Merge tag 'media/v3.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 11 Dec 2014 19:49:23 +0000 (11:49 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 11 Dec 2014 19:49:23 +0000 (11:49 -0800)
Pull media updates from Mauro Carvalho Chehab:
 - Two new dvb frontend drivers: mn88472 and mn88473
 - A new driver for some PCIe DVBSky cards
 - A new remote controller driver: meson-ir
 - One LIRC staging driver got rewritten and promoted to mainstream:
   igorplugusb
 - A new tuner driver (m88rs6000t)
 - The old omap2 media driver got removed from staging.  This driver
   uses an old DMA API and it is likely broken on recent kernels.
   Nobody cared enough to fix it
 - Media bus format moved to a separate header, as DRM will also use the
   definitions there
 - mem2mem_testdev were renamed to vim2m, in order to use the same
   naming convention taken by the other virtual test driver (vivid)
 - Added a new driver for coda SoC (coda-jpeg)
 - The cx88 driver got converted to use videobuf2 core
 - Make DMABUF export buffer to work with DMA Scatter/Gather and Vmalloc
   cores
 - Lots of other fixes, improvements and cleanups on the drivers.

* tag 'media/v3.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (384 commits)
  [media] mn88473: One function call less in mn88473_init() after error
  [media] mn88473: Remove uneeded check before release_firmware()
  [media] lirc_zilog: Deletion of unnecessary checks before vfree()
  [media] MAINTAINERS: Add myself as img-ir maintainer
  [media] img-ir: Don't set driver's module owner
  [media] img-ir: Depend on METAG or MIPS or COMPILE_TEST
  [media] img-ir/hw: Drop [un]register_decoder declarations
  [media] img-ir/hw: Fix potential deadlock stopping timer
  [media] img-ir/hw: Always read data to clear buffer
  [media] redrat3: ensure dma is setup properly
  [media] ddbridge: remove unneeded check before dvb_unregister_device()
  [media] si2157: One function call less in si2157_init() after error
  [media] tuners: remove uneeded checks before release_firmware()
  [media] arm: omap2: rx51-peripherals: fix build warning
  [media] stv090x: add an extra protetion against buffer overflow
  [media] stv090x: Remove an unreachable code
  [media] stv090x: Some whitespace cleanups
  [media] em28xx: checkpatch cleanup: whitespaces/new lines cleanups
  [media] si2168: add support for firmware files in new format
  [media] si2168: debug printout for firmware version
  ...

15 files changed:
1  2 
MAINTAINERS
arch/arm/boot/dts/meson.dtsi
arch/arm/mach-omap2/board-rx51-peripherals.c
arch/arm/mach-omap2/devices.c
arch/arm/mach-shmobile/board-mackerel.c
drivers/media/i2c/smiapp/smiapp-core.c
drivers/media/pci/cx23885/cx23885-core.c
drivers/media/platform/coda/coda-common.c
drivers/media/platform/exynos4-is/fimc-core.c
drivers/media/platform/exynos4-is/fimc-lite.c
drivers/media/platform/exynos4-is/mipi-csis.c
drivers/media/platform/s5p-jpeg/jpeg-core.c
drivers/media/platform/s5p-mfc/s5p_mfc.c
drivers/media/usb/s2255/s2255drv.c
include/uapi/linux/Kbuild

diff --combined MAINTAINERS
@@@ -850,6 -850,7 +850,7 @@@ ARM/Amlogic MesonX SoC suppor
  M:    Carlo Caione <carlo@caione.org>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  S:    Maintained
+ F:    drivers/media/rc/meson-ir.c
  N:    meson[x68]
  
  ARM/ATMEL AT91RM9200 AND AT91SAM ARM ARCHITECTURES
@@@ -861,7 -862,6 +862,7 @@@ W: http://maxim.org.za/at91_26.htm
  W:    http://www.linux4sam.org
  S:    Supported
  F:    arch/arm/mach-at91/
 +F:    include/soc/at91/
  F:    arch/arm/boot/dts/at91*.dts
  F:    arch/arm/boot/dts/at91*.dtsi
  F:    arch/arm/boot/dts/sama*.dts
@@@ -1309,22 -1309,30 +1310,22 @@@ F:   drivers/*/*rockchip
  F:    drivers/*/*/*rockchip*
  F:    sound/soc/rockchip/
  
 -ARM/SAMSUNG ARM ARCHITECTURES
 -M:    Ben Dooks <ben-linux@fluff.org>
 -M:    Kukjin Kim <kgene.kim@samsung.com>
 +ARM/SAMSUNG EXYNOS ARM ARCHITECTURES
 +M:    Kukjin Kim <kgene@kernel.org>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  L:    linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
 -W:    http://www.fluff.org/ben/linux/
  S:    Maintained
  F:    arch/arm/boot/dts/s3c*
  F:    arch/arm/boot/dts/exynos*
  F:    arch/arm/plat-samsung/
  F:    arch/arm/mach-s3c24*/
  F:    arch/arm/mach-s3c64xx/
 +F:    arch/arm/mach-s5p*/
 +F:    arch/arm/mach-exynos*/
  F:    drivers/*/*s3c2410*
  F:    drivers/*/*/*s3c2410*
  F:    drivers/spi/spi-s3c*
  F:    sound/soc/samsung/*
 -
 -ARM/S5P EXYNOS ARM ARCHITECTURES
 -M:    Kukjin Kim <kgene.kim@samsung.com>
 -L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 -L:    linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
 -S:    Maintained
 -F:    arch/arm/mach-s5p*/
 -F:    arch/arm/mach-exynos*/
  N:    exynos
  
  ARM/SAMSUNG MOBILE MACHINE SUPPORT
@@@ -1374,12 -1382,12 +1375,12 @@@ F:   arch/arm/boot/dts/sh
  F:    arch/arm/configs/ape6evm_defconfig
  F:    arch/arm/configs/armadillo800eva_defconfig
  F:    arch/arm/configs/bockw_defconfig
 -F:    arch/arm/configs/koelsch_defconfig
  F:    arch/arm/configs/kzm9g_defconfig
  F:    arch/arm/configs/lager_defconfig
  F:    arch/arm/configs/mackerel_defconfig
  F:    arch/arm/configs/marzen_defconfig
  F:    arch/arm/configs/shmobile_defconfig
 +F:    arch/arm/include/debug/renesas-scif.S
  F:    arch/arm/mach-shmobile/
  F:    drivers/sh/
  
@@@ -1423,7 -1431,6 +1424,7 @@@ F:      drivers/tty/serial/st-asc.
  F:    drivers/usb/dwc3/dwc3-st.c
  F:    drivers/usb/host/ehci-st.c
  F:    drivers/usb/host/ohci-st.c
 +F:    drivers/ata/ahci_st.c
  
  ARM/TECHNOLOGIC SYSTEMS TS7250 MACHINE SUPPORT
  M:    Lennert Buytenhek <kernel@wantstofly.org>
@@@ -1497,19 -1504,6 +1498,19 @@@ S:    Maintaine
  F:    drivers/clk/ux500/
  F:    include/linux/platform_data/clk-ux500.h
  
 +ARM/VERSATILE EXPRESS PLATFORM
 +M:    Liviu Dudau <liviu.dudau@arm.com>
 +M:    Sudeep Holla <sudeep.holla@arm.com>
 +M:    Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
 +L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 +S:    Maintained
 +F:    arch/arm/boot/dts/vexpress*
 +F:    arch/arm/mach-vexpress/
 +F:    */*/vexpress*
 +F:    */*/*/vexpress*
 +F:    drivers/clk/versatile/clk-vexpress-osc.c
 +F:    drivers/clocksource/versatile.c
 +
  ARM/VFP SUPPORT
  M:    Russell King <linux@arm.linux.org.uk>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@@ -1835,7 -1829,7 +1836,7 @@@ F:      include/net/ax25.
  F:    net/ax25/
  
  AZ6007 DVB DRIVER
 -M:    Mauro Carvalho Chehab <m.chehab@samsung.com>
 +M:    Mauro Carvalho Chehab <mchehab@osg.samsung.com>
  L:    linux-media@vger.kernel.org
  W:    http://linuxtv.org
  T:    git git://linuxtv.org/media_tree.git
@@@ -1869,6 -1863,7 +1870,6 @@@ F:      drivers/net/wireless/b43legacy
  
  BACKLIGHT CLASS/SUBSYSTEM
  M:    Jingoo Han <jg1.han@samsung.com>
 -M:    Bryan Wu <cooloney@gmail.com>
  M:    Lee Jones <lee.jones@linaro.org>
  S:    Maintained
  F:    drivers/video/backlight/
@@@ -2103,13 -2098,10 +2104,13 @@@ F:   arch/arm/include/debug/bcm63xx.
  BROADCOM BCM7XXX ARM ARCHITECTURE
  M:    Marc Carino <marc.ceeeee@gmail.com>
  M:    Brian Norris <computersforpeace@gmail.com>
 +M:    Gregory Fong <gregory.0xf0@gmail.com>
 +M:    Florian Fainelli <f.fainelli@gmail.com>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  S:    Maintained
  F:    arch/arm/mach-bcm/*brcmstb*
  F:    arch/arm/boot/dts/bcm7*.dts*
 +F:    drivers/bus/brcmstb_gisb.c
  
  BROADCOM TG3 GIGABIT ETHERNET DRIVER
  M:    Prashant Sreedharan <prashant@broadcom.com>
@@@ -2140,20 -2132,6 +2141,20 @@@ L:    linux-scsi@vger.kernel.or
  S:    Supported
  F:    drivers/scsi/bnx2i/
  
 +BROADCOM CYGNUS/IPROC ARM ARCHITECTURE
 +M:    Ray Jui <rjui@broadcom.com>
 +M:    Scott Branden <sbranden@broadcom.com>
 +L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 +L:    bcm-kernel-feedback-list@broadcom.com
 +T:    git git://git.github.com/brcm/linux.git
 +S:    Maintained
 +N:    iproc
 +N:    cygnus
 +N:    bcm9113*
 +N:    bcm9583*
 +N:    bcm583*
 +N:    bcm113*
 +
  BROADCOM KONA GPIO DRIVER
  M:    Ray Jui <rjui@broadcom.com>
  L:    bcm-kernel-feedback-list@broadcom.com
@@@ -2221,7 -2199,7 +2222,7 @@@ F:      Documentation/filesystems/btrfs.tx
  F:    fs/btrfs/
  
  BTTV VIDEO4LINUX DRIVER
 -M:    Mauro Carvalho Chehab <m.chehab@samsung.com>
 +M:    Mauro Carvalho Chehab <mchehab@osg.samsung.com>
  L:    linux-media@vger.kernel.org
  W:    http://linuxtv.org
  T:    git git://linuxtv.org/media_tree.git
@@@ -2512,6 -2490,13 +2513,13 @@@ F:    fs/coda
  F:    include/linux/coda*.h
  F:    include/uapi/linux/coda*.h
  
+ CODA V4L2 MEM2MEM DRIVER
+ M:    Philipp Zabel <p.zabel@pengutronix.de>
+ L:    linux-media@vger.kernel.org
+ S:    Maintained
+ F:    Documentation/devicetree/bindings/media/coda.txt
+ F:    drivers/media/platform/coda/
  COMMON CLK FRAMEWORK
  M:    Mike Turquette <mturquette@linaro.org>
  L:    linux-kernel@vger.kernel.org
@@@ -2527,7 -2512,8 +2535,7 @@@ M:      Steve French <sfrench@samba.org
  L:    linux-cifs@vger.kernel.org
  L:    samba-technical@lists.samba.org (moderated for non-subscribers)
  W:    http://linux-cifs.samba.org/
 -Q:    http://patchwork.ozlabs.org/project/linux-cifs-client/list/
 -T:    git git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6.git
 +T:    git git://git.samba.org/sfrench/cifs-2.6.git
  S:    Supported
  F:    Documentation/filesystems/cifs/
  F:    fs/cifs/
@@@ -2604,7 -2590,7 +2612,7 @@@ L:      cgroups@vger.kernel.or
  L:    linux-mm@kvack.org
  S:    Maintained
  F:    mm/memcontrol.c
 -F:    mm/page_cgroup.c
 +F:    mm/swap_cgroup.c
  
  CORETEMP HARDWARE MONITORING DRIVER
  M:    Fenghua Yu <fenghua.yu@intel.com>
@@@ -2654,16 -2640,6 +2662,16 @@@ T:    git git://git.kernel.org/pub/scm/lin
  S:    Maintained
  F:    drivers/cpuidle/cpuidle-big_little.c
  
 +CPUIDLE DRIVER - ARM EXYNOS
 +M:    Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
 +M:    Daniel Lezcano <daniel.lezcano@linaro.org>
 +M:    Kukjin Kim <kgene@kernel.org>
 +L:    linux-pm@vger.kernel.org
 +L:    linux-samsung-soc@vger.kernel.org
 +S:    Supported
 +F:    drivers/cpuidle/cpuidle-exynos.c
 +F:    arch/arm/mach-exynos/pm.c
 +
  CPUIDLE DRIVERS
  M:    Rafael J. Wysocki <rjw@rjwysocki.net>
  M:    Daniel Lezcano <daniel.lezcano@linaro.org>
@@@ -2731,7 -2707,7 +2739,7 @@@ F:      drivers/net/wireless/cw1200
  
  CX18 VIDEO4LINUX DRIVER
  M:    Andy Walls <awalls@md.metrocast.net>
 -L:    ivtv-devel@ivtvdriver.org (moderated for non-subscribers)
 +L:    ivtv-devel@ivtvdriver.org (subscribers-only)
  L:    linux-media@vger.kernel.org
  T:    git git://linuxtv.org/media_tree.git
  W:    http://linuxtv.org
@@@ -2751,7 -2727,7 +2759,7 @@@ F:      drivers/media/common/cx2341x
  F:    include/media/cx2341x*
  
  CX88 VIDEO4LINUX DRIVER
 -M:    Mauro Carvalho Chehab <m.chehab@samsung.com>
 +M:    Mauro Carvalho Chehab <mchehab@osg.samsung.com>
  L:    linux-media@vger.kernel.org
  W:    http://linuxtv.org
  T:    git git://linuxtv.org/media_tree.git
@@@ -2776,13 -2752,6 +2784,13 @@@ W:    http://www.chelsio.co
  S:    Supported
  F:    drivers/net/ethernet/chelsio/cxgb3/
  
 +CXGB3 ISCSI DRIVER (CXGB3I)
 +M:      Karen Xie <kxie@chelsio.com>
 +L:      linux-scsi@vger.kernel.org
 +W:      http://www.chelsio.com
 +S:      Supported
 +F:      drivers/scsi/cxgbi/cxgb3i
 +
  CXGB3 IWARP RNIC DRIVER (IW_CXGB3)
  M:    Steve Wise <swise@chelsio.com>
  L:    linux-rdma@vger.kernel.org
@@@ -2797,13 -2766,6 +2805,13 @@@ W:    http://www.chelsio.co
  S:    Supported
  F:    drivers/net/ethernet/chelsio/cxgb4/
  
 +CXGB4 ISCSI DRIVER (CXGB4I)
 +M:      Karen Xie <kxie@chelsio.com>
 +L:      linux-scsi@vger.kernel.org
 +W:      http://www.chelsio.com
 +S:      Supported
 +F:      drivers/scsi/cxgbi/cxgb4i
 +
  CXGB4 IWARP RNIC DRIVER (IW_CXGB4)
  M:    Steve Wise <swise@chelsio.com>
  L:    linux-rdma@vger.kernel.org
@@@ -2894,10 -2856,11 +2902,10 @@@ F:   Documentation/networking/dmfe.tx
  F:    drivers/net/ethernet/dec/tulip/dmfe.c
  
  DC390/AM53C974 SCSI driver
 -M:    Kurt Garloff <garloff@suse.de>
 -W:    http://www.garloff.de/kurt/linux/dc390/
 -M:    Guennadi Liakhovetski <g.liakhovetski@gmx.de>
 +M:    Hannes Reinecke <hare@suse.de>
 +L:    linux-scsi@vger.kernel.org
  S:    Maintained
 -F:    drivers/scsi/tmscsim.*
 +F:    drivers/scsi/am53c974.c
  
  DC395x SCSI driver
  M:    Oliver Neukum <oliver@neukum.org>
@@@ -3433,7 -3396,7 +3441,7 @@@ F:      fs/ecryptfs
  EDAC-CORE
  M:    Doug Thompson <dougthompson@xmission.com>
  M:    Borislav Petkov <bp@alien8.de>
 -M:    Mauro Carvalho Chehab <m.chehab@samsung.com>
 +M:    Mauro Carvalho Chehab <mchehab@osg.samsung.com>
  L:    linux-edac@vger.kernel.org
  W:    bluesmoke.sourceforge.net
  S:    Supported
@@@ -3482,7 -3445,7 +3490,7 @@@ S:      Maintaine
  F:    drivers/edac/e7xxx_edac.c
  
  EDAC-GHES
 -M:    Mauro Carvalho Chehab <m.chehab@samsung.com>
 +M:    Mauro Carvalho Chehab <mchehab@osg.samsung.com>
  L:    linux-edac@vger.kernel.org
  W:    bluesmoke.sourceforge.net
  S:    Maintained
@@@ -3510,21 -3473,21 +3518,21 @@@ S:   Maintaine
  F:    drivers/edac/i5000_edac.c
  
  EDAC-I5400
 -M:    Mauro Carvalho Chehab <m.chehab@samsung.com>
 +M:    Mauro Carvalho Chehab <mchehab@osg.samsung.com>
  L:    linux-edac@vger.kernel.org
  W:    bluesmoke.sourceforge.net
  S:    Maintained
  F:    drivers/edac/i5400_edac.c
  
  EDAC-I7300
 -M:    Mauro Carvalho Chehab <m.chehab@samsung.com>
 +M:    Mauro Carvalho Chehab <mchehab@osg.samsung.com>
  L:    linux-edac@vger.kernel.org
  W:    bluesmoke.sourceforge.net
  S:    Maintained
  F:    drivers/edac/i7300_edac.c
  
  EDAC-I7CORE
 -M:    Mauro Carvalho Chehab <m.chehab@samsung.com>
 +M:    Mauro Carvalho Chehab <mchehab@osg.samsung.com>
  L:    linux-edac@vger.kernel.org
  W:    bluesmoke.sourceforge.net
  S:    Maintained
@@@ -3567,7 -3530,7 +3575,7 @@@ S:      Maintaine
  F:    drivers/edac/r82600_edac.c
  
  EDAC-SBRIDGE
 -M:    Mauro Carvalho Chehab <m.chehab@samsung.com>
 +M:    Mauro Carvalho Chehab <mchehab@osg.samsung.com>
  L:    linux-edac@vger.kernel.org
  W:    bluesmoke.sourceforge.net
  S:    Maintained
@@@ -3627,7 -3590,7 +3635,7 @@@ S:      Maintaine
  F:    drivers/net/ethernet/ibm/ehea/
  
  EM28XX VIDEO4LINUX DRIVER
 -M:    Mauro Carvalho Chehab <m.chehab@samsung.com>
 +M:    Mauro Carvalho Chehab <mchehab@osg.samsung.com>
  L:    linux-media@vger.kernel.org
  W:    http://linuxtv.org
  T:    git git://linuxtv.org/media_tree.git
@@@ -4746,6 -4709,12 +4754,12 @@@ F:    net/mac802154
  F:    drivers/net/ieee802154/
  F:    Documentation/networking/ieee802154.txt
  
+ IGORPLUG-USB IR RECEIVER
+ M:    Sean Young <sean@mess.org>
+ L:    linux-media@vger.kernel.org
+ S:    Maintained
+ F:    drivers/media/rc/igorplugusb.c
  IGUANAWORKS USB IR TRANSCEIVER
  M:    Sean Young <sean@mess.org>
  L:    linux-media@vger.kernel.org
@@@ -4761,7 -4730,6 +4775,7 @@@ L:      linux-iio@vger.kernel.or
  S:    Maintained
  F:    drivers/iio/
  F:    drivers/staging/iio/
 +F:    include/linux/iio/
  
  IKANOS/ADI EAGLE ADSL USB DRIVER
  M:    Matthieu Castet <castet.matthieu@free.fr>
@@@ -4803,6 -4771,11 +4817,11 @@@ L:    linux-security-module@vger.kernel.or
  S:    Supported
  F:    security/integrity/ima/
  
+ IMGTEC IR DECODER DRIVER
+ M:    James Hogan <james.hogan@imgtec.com>
+ S:    Maintained
+ F:    drivers/media/rc/img-ir/
  IMS TWINTURBO FRAMEBUFFER DRIVER
  L:    linux-fbdev@vger.kernel.org
  S:    Orphan
@@@ -5217,7 -5190,7 +5236,7 @@@ F:      drivers/media/tuners/it913x
  
  IVTV VIDEO4LINUX DRIVER
  M:    Andy Walls <awalls@md.metrocast.net>
 -L:    ivtv-devel@ivtvdriver.org (moderated for non-subscribers)
 +L:    ivtv-devel@ivtvdriver.org (subscribers-only)
  L:    linux-media@vger.kernel.org
  T:    git git://linuxtv.org/media_tree.git
  W:    http://www.ivtvdriver.org
@@@ -5993,7 -5966,7 +6012,7 @@@ S:      Maintaine
  F:    drivers/media/radio/radio-maxiradio*
  
  MEDIA INPUT INFRASTRUCTURE (V4L/DVB)
 -M:    Mauro Carvalho Chehab <m.chehab@samsung.com>
 +M:    Mauro Carvalho Chehab <mchehab@osg.samsung.com>
  P:    LinuxTV.org Project
  L:    linux-media@vger.kernel.org
  W:    http://linuxtv.org
@@@ -6022,13 -5995,10 +6041,13 @@@ W:   http://linuxtv.or
  S:    Odd Fixes
  F:    drivers/media/parport/pms*
  
 -MEGARAID SCSI DRIVERS
 -M:    Neela Syam Kolli <megaraidlinux@lsi.com>
 +MEGARAID SCSI/SAS DRIVERS
 +M:    Kashyap Desai <kashyap.desai@avagotech.com>
 +M:    Sumit Saxena <sumit.saxena@avagotech.com>
 +M:    Uday Lingala <uday.lingala@avagotech.com>
 +L:    megaraidlinux.pdl@avagotech.com
  L:    linux-scsi@vger.kernel.org
 -W:    http://megaraid.lsilogic.com
 +W:    http://www.lsi.com
  S:    Maintained
  F:    Documentation/scsi/megaraid.txt
  F:    drivers/scsi/megaraid.*
@@@ -6151,6 -6121,28 +6170,28 @@@ S:    Supporte
  F:    include/linux/mlx5/
  F:    drivers/infiniband/hw/mlx5/
  
+ MN88472 MEDIA DRIVER
+ M:    Antti Palosaari <crope@iki.fi>
+ L:    linux-media@vger.kernel.org
+ W:    http://linuxtv.org/
+ W:    http://palosaari.fi/linux/
+ Q:    http://patchwork.linuxtv.org/project/linux-media/list/
+ T:    git git://linuxtv.org/anttip/media_tree.git
+ S:    Maintained
+ F:    drivers/staging/media/mn88472/
+ F:    drivers/media/dvb-frontends/mn88472.h
+ MN88473 MEDIA DRIVER
+ M:    Antti Palosaari <crope@iki.fi>
+ L:    linux-media@vger.kernel.org
+ W:    http://linuxtv.org/
+ W:    http://palosaari.fi/linux/
+ Q:    http://patchwork.linuxtv.org/project/linux-media/list/
+ T:    git git://linuxtv.org/anttip/media_tree.git
+ S:    Maintained
+ F:    drivers/staging/media/mn88473/
+ F:    drivers/media/dvb-frontends/mn88473.h
  MODULE SUPPORT
  M:    Rusty Russell <rusty@rustcorp.com.au>
  S:    Maintained
@@@ -6339,6 -6331,7 +6380,6 @@@ F:      drivers/scsi/g_NCR5380.
  F:    drivers/scsi/g_NCR5380_mmio.c
  F:    drivers/scsi/mac_scsi.*
  F:    drivers/scsi/pas16.*
 -F:    drivers/scsi/sun3_NCR5380.c
  F:    drivers/scsi/sun3_scsi.*
  F:    drivers/scsi/sun3_scsi_vme.c
  F:    drivers/scsi/t128.*
@@@ -6594,13 -6587,6 +6635,13 @@@ S:    Maintaine
  F:    Documentation/scsi/NinjaSCSI.txt
  F:    drivers/scsi/nsp32*
  
 +NIOS2 ARCHITECTURE
 +M:    Ley Foon Tan <lftan@altera.com>
 +L:    nios2-dev@lists.rocketboards.org (moderated for non-subscribers)
 +T:    git git://git.rocketboards.org/linux-socfpga.git
 +S:    Maintained
 +F:    arch/nios2/
 +
  NTB DRIVER
  M:    Jon Mason <jdmason@kudzu.us>
  M:    Dave Jiang <dave.jiang@intel.com>
@@@ -6651,23 -6637,6 +6692,23 @@@ T:    git git://git.kernel.org/pub/scm/lin
  S:    Maintained
  F:    arch/arm/*omap*/
  F:    drivers/i2c/busses/i2c-omap.c
 +F:    drivers/irqchip/irq-omap-intc.c
 +F:    drivers/mfd/*omap*.c
 +F:    drivers/mfd/menelaus.c
 +F:    drivers/mfd/palmas.c
 +F:    drivers/mfd/tps65217.c
 +F:    drivers/mfd/tps65218.c
 +F:    drivers/mfd/tps65910.c
 +F:    drivers/mfd/twl-core.[ch]
 +F:    drivers/mfd/twl4030*.c
 +F:    drivers/mfd/twl6030*.c
 +F:    drivers/mfd/twl6040*.c
 +F:    drivers/regulator/palmas-regulator*.c
 +F:    drivers/regulator/pbias-regulator.c
 +F:    drivers/regulator/tps65217-regulator.c
 +F:    drivers/regulator/tps65218-regulator.c
 +F:    drivers/regulator/tps65910-regulator.c
 +F:    drivers/regulator/twl-regulator.c
  F:    include/linux/i2c-omap.h
  
  OMAP DEVICE TREE SUPPORT
@@@ -6678,9 -6647,6 +6719,9 @@@ L:      devicetree@vger.kernel.or
  S:    Maintained
  F:    arch/arm/boot/dts/*omap*
  F:    arch/arm/boot/dts/*am3*
 +F:    arch/arm/boot/dts/*am4*
 +F:    arch/arm/boot/dts/*am5*
 +F:    arch/arm/boot/dts/*dra7*
  
  OMAP CLOCK FRAMEWORK SUPPORT
  M:    Paul Walmsley <paul@pwsan.com>
@@@ -6710,14 -6676,6 +6751,14 @@@ L:    linux-omap@vger.kernel.or
  S:    Maintained
  F:    sound/soc/omap/
  
 +OMAP GENERAL PURPOSE MEMORY CONTROLLER SUPPORT
 +M:    Roger Quadros <rogerq@ti.com>
 +M:    Tony Lindgren <tony@atomide.com>
 +L:    linux-omap@vger.kernel.org
 +S:    Maintained
 +F:    drivers/memory/omap-gpmc.c
 +F:    arch/arm/mach-omap2/*gpmc*
 +
  OMAP FRAMEBUFFER SUPPORT
  M:    Tomi Valkeinen <tomi.valkeinen@ti.com>
  L:    linux-fbdev@vger.kernel.org
@@@ -6936,12 -6894,11 +6977,12 @@@ F:   drivers/scsi/osd
  F:    include/scsi/osd_*
  F:    fs/exofs/
  
 -OVERLAYFS FILESYSTEM
 +OVERLAY FILESYSTEM
  M:    Miklos Szeredi <miklos@szeredi.hu>
 -L:    linux-fsdevel@vger.kernel.org
 +L:    linux-unionfs@vger.kernel.org
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs.git
  S:    Supported
 -F:    fs/overlayfs/*
 +F:    fs/overlayfs/
  F:    Documentation/filesystems/overlayfs.txt
  
  P54 WIRELESS DRIVER
@@@ -7095,16 -7052,6 +7136,16 @@@ S:    Maintaine
  F:    Documentation/devicetree/bindings/pci/xgene-pci.txt
  F:    drivers/pci/host/pci-xgene.c
  
 +PCI DRIVER FOR FREESCALE LAYERSCAPE
 +M:    Minghuan Lian <minghuan.Lian@freescale.com>
 +M:    Mingkai Hu <mingkai.hu@freescale.com>
 +M:    Roy Zang <tie-fei.zang@freescale.com>
 +L:    linuxppc-dev@lists.ozlabs.org
 +L:    linux-pci@vger.kernel.org
 +L:    linux-arm-kernel@lists.infradead.org
 +S:    Maintained
 +F:    drivers/pci/host/*layerscape*
 +
  PCI DRIVER FOR IMX6
  M:    Richard Zhu <r65037@freescale.com>
  M:    Lucas Stach <l.stach@pengutronix.de>
@@@ -7284,13 -7231,7 +7325,13 @@@ PIN CONTROLLER - ATMEL AT9
  M:    Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  S:    Maintained
 -F:    drivers/pinctrl/pinctrl-at91.c
 +F:    drivers/pinctrl/pinctrl-at91.*
 +
 +PIN CONTROLLER - INTEL
 +M:    Mika Westerberg <mika.westerberg@linux.intel.com>
 +M:    Heikki Krogerus <heikki.krogerus@linux.intel.com>
 +S:    Maintained
 +F:    drivers/pinctrl/intel/
  
  PIN CONTROLLER - RENESAS
  M:    Laurent Pinchart <laurent.pinchart@ideasonboard.com>
@@@ -8077,7 -8018,7 +8118,7 @@@ S:      Odd Fixe
  F:    drivers/media/i2c/saa6588*
  
  SAA7134 VIDEO4LINUX DRIVER
 -M:    Mauro Carvalho Chehab <m.chehab@samsung.com>
 +M:    Mauro Carvalho Chehab <mchehab@osg.samsung.com>
  L:    linux-media@vger.kernel.org
  W:    http://linuxtv.org
  T:    git git://linuxtv.org/media_tree.git
@@@ -8535,7 -8476,7 +8576,7 @@@ S:      Maintaine
  F:    drivers/media/radio/si4713/radio-usb-si4713.c
  
  SIANO DVB DRIVER
 -M:    Mauro Carvalho Chehab <m.chehab@samsung.com>
 +M:    Mauro Carvalho Chehab <mchehab@osg.samsung.com>
  L:    linux-media@vger.kernel.org
  W:    http://linuxtv.org
  T:    git git://linuxtv.org/media_tree.git
@@@ -8746,9 -8687,7 +8787,9 @@@ S:      Maintaine
  F:    drivers/leds/leds-net48xx.c
  
  SOFTLOGIC 6x10 MPEG CODEC
 -M:    Ismael Luceno <ismael.luceno@corp.bluecherry.net>
 +M:    Bluecherry Maintainers <maintainers@bluecherrydvr.com>
 +M:    Andrey Utkin <andrey.utkin@corp.bluecherry.net>
 +M:    Andrey Utkin <andrey.krieger.utkin@gmail.com>
  L:    linux-media@vger.kernel.org
  S:    Supported
  F:    drivers/media/pci/solo6x10/
@@@ -9222,7 -9161,7 +9263,7 @@@ S:      Maintaine
  F:    drivers/media/i2c/tda9840*
  
  TEA5761 TUNER DRIVER
 -M:    Mauro Carvalho Chehab <m.chehab@samsung.com>
 +M:    Mauro Carvalho Chehab <mchehab@osg.samsung.com>
  L:    linux-media@vger.kernel.org
  W:    http://linuxtv.org
  T:    git git://linuxtv.org/media_tree.git
@@@ -9230,7 -9169,7 +9271,7 @@@ S:      Odd fixe
  F:    drivers/media/tuners/tea5761.*
  
  TEA5767 TUNER DRIVER
 -M:    Mauro Carvalho Chehab <m.chehab@samsung.com>
 +M:    Mauro Carvalho Chehab <mchehab@osg.samsung.com>
  L:    linux-media@vger.kernel.org
  W:    http://linuxtv.org
  T:    git git://linuxtv.org/media_tree.git
@@@ -9542,7 -9481,7 +9583,7 @@@ F:      include/linux/shmem_fs.
  F:    mm/shmem.c
  
  TM6000 VIDEO4LINUX DRIVER
 -M:    Mauro Carvalho Chehab <m.chehab@samsung.com>
 +M:    Mauro Carvalho Chehab <mchehab@osg.samsung.com>
  L:    linux-media@vger.kernel.org
  W:    http://linuxtv.org
  T:    git git://linuxtv.org/media_tree.git
@@@ -10363,7 -10302,7 +10404,7 @@@ S:   Maintaine
  F:    arch/x86/kernel/cpu/mcheck/*
  
  XC2028/3028 TUNER DRIVER
 -M:    Mauro Carvalho Chehab <m.chehab@samsung.com>
 +M:    Mauro Carvalho Chehab <mchehab@osg.samsung.com>
  L:    linux-media@vger.kernel.org
  W:    http://linuxtv.org
  T:    git git://linuxtv.org/media_tree.git
  / {
        interrupt-parent = <&gic>;
  
 +      L2: l2-cache-controller@c4200000 {
 +              compatible = "arm,pl310-cache";
 +              reg = <0xc4200000 0x1000>;
 +              cache-unified;
 +              cache-level = <2>;
 +      };
 +
        gic: interrupt-controller@c4301000 {
                compatible = "arm,cortex-a9-gic";
                reg = <0xc4301000 0x1000>,
                        status = "disabled";
                };
  
 +              i2c_AO: i2c@c8100500 {
 +                      compatible = "amlogic,meson6-i2c";
 +                      reg = <0xc8100500 0x20>;
 +                      interrupts = <0 92 1>;
 +                      clocks = <&clk81>;
 +                      #address-cells = <1>;
 +                      #size-cells = <0>;
 +                      status = "disabled";
 +              };
 +
 +              i2c_A: i2c@c1108500 {
 +                      compatible = "amlogic,meson6-i2c";
 +                      reg = <0xc1108500 0x20>;
 +                      interrupts = <0 21 1>;
 +                      clocks = <&clk81>;
 +                      #address-cells = <1>;
 +                      #size-cells = <0>;
 +                      status = "disabled";
 +              };
 +
 +              i2c_B: i2c@c11087c0 {
 +                      compatible = "amlogic,meson6-i2c";
 +                      reg = <0xc11087c0 0x20>;
 +                      interrupts = <0 128 1>;
 +                      clocks = <&clk81>;
 +                      #address-cells = <1>;
 +                      #size-cells = <0>;
 +                      status = "disabled";
 +              };
++
+               ir_receiver: ir-receiver@c8100480 {
+                       compatible= "amlogic,meson6-ir";
+                       reg = <0xc8100480 0x20>;
+                       interrupts = <0 15 1>;
+                       status = "disabled";
+               };
        };
  }; /* end of / */
@@@ -23,7 -23,7 +23,8 @@@
  #include <linux/regulator/machine.h>
  #include <linux/gpio.h>
  #include <linux/gpio_keys.h>
+ #include <linux/gpio/machine.h>
 +#include <linux/omap-gpmc.h>
  #include <linux/mmc/host.h>
  #include <linux/power/isp1704_charger.h>
  #include <linux/platform_data/spi-omap2-mcspi.h>
  
  #include "common.h"
  #include <linux/omap-dma.h>
 -#include "gpmc-smc91x.h"
  
  #include "board-rx51.h"
  
  #include <sound/tlv320aic3x.h>
  #include <sound/tpa6130a2-plat.h>
- #include <media/radio-si4713.h>
  #include <media/si4713.h>
  #include <linux/platform_data/leds-lp55xx.h>
  
@@@ -55,6 -55,8 +55,6 @@@
  #include "omap-pm.h"
  #include "hsmmc.h"
  #include "common-board-devices.h"
 -#include "gpmc.h"
 -#include "gpmc-onenand.h"
  #include "soc.h"
  #include "omap-secure.h"
  
@@@ -482,7 -484,7 +482,7 @@@ static struct omap_mux_partition *parti
   * Current flows to eMMC when eMMC is off and the data lines are pulled up,
   * so pull them down. N.B. we pull 8 lines because we are using 8 lines.
   */
 -static void rx51_mmc2_remux(struct device *dev, int slot, int power_on)
 +static void rx51_mmc2_remux(struct device *dev, int power_on)
  {
        if (power_on)
                omap_mux_write_array(partition, rx51_mmc2_on_mux);
@@@ -498,6 -500,7 +498,6 @@@ static struct omap2_hsmmc_info mmc[] __
                .cover_only     = true,
                .gpio_cd        = 160,
                .gpio_wp        = -EINVAL,
 -              .power_saving   = true,
        },
        {
                .name           = "internal",
                .gpio_cd        = -EINVAL,
                .gpio_wp        = -EINVAL,
                .nonremovable   = true,
 -              .power_saving   = true,
                .remux          = rx51_mmc2_remux,
        },
        {}      /* Terminator */
@@@ -756,46 -760,17 +756,17 @@@ static struct regulator_init_data rx51_
        },
  };
  
- static const char * const si4713_supply_names[] = {
-       "vio",
-       "vdd",
- };
- static struct si4713_platform_data rx51_si4713_i2c_data __initdata_or_module = {
-       .supplies       = ARRAY_SIZE(si4713_supply_names),
-       .supply_names   = si4713_supply_names,
-       .gpio_reset     = RX51_FMTX_RESET_GPIO,
- };
- static struct i2c_board_info rx51_si4713_board_info __initdata_or_module = {
-       I2C_BOARD_INFO("si4713", SI4713_I2C_ADDR_BUSEN_HIGH),
-       .platform_data  = &rx51_si4713_i2c_data,
- };
- static struct radio_si4713_platform_data rx51_si4713_data __initdata_or_module = {
-       .i2c_bus        = 2,
-       .subdev_board_info = &rx51_si4713_board_info,
- };
- static struct platform_device rx51_si4713_dev __initdata_or_module = {
-       .name   = "radio-si4713",
-       .id     = -1,
-       .dev    = {
-               .platform_data  = &rx51_si4713_data,
+ static struct gpiod_lookup_table rx51_fmtx_gpios_table = {
+       .dev_id = "2-0063",
+       .table = {
+               GPIO_LOOKUP("gpio.6", 3, "reset", GPIO_ACTIVE_HIGH), /* 163 */
+               { },
        },
  };
  
- static __init void rx51_init_si4713(void)
+ static __init void rx51_gpio_init(void)
  {
-       int err;
-       err = gpio_request_one(RX51_FMTX_IRQ, GPIOF_DIR_IN, "si4713 irq");
-       if (err) {
-               printk(KERN_ERR "Cannot request si4713 irq gpio. %d\n", err);
-               return;
-       }
-       rx51_si4713_board_info.irq = gpio_to_irq(RX51_FMTX_IRQ);
-       platform_device_register(&rx51_si4713_dev);
+       gpiod_add_lookup_table(&rx51_fmtx_gpios_table);
  }
  
  static int rx51_twlgpio_setup(struct device *dev, unsigned gpio, unsigned n)
@@@ -1025,7 -1000,19 +996,19 @@@ static struct aic3x_pdata rx51_aic3x_da
        .gpio_reset = 60,
  };
  
+ #if IS_ENABLED(CONFIG_I2C_SI4713) && IS_ENABLED(CONFIG_PLATFORM_SI4713)
+ static struct si4713_platform_data rx51_si4713_platform_data = {
+       .is_platform_device = true
+ };
+ #endif
  static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_2[] = {
+ #if IS_ENABLED(CONFIG_I2C_SI4713) && IS_ENABLED(CONFIG_PLATFORM_SI4713)
+       {
+               I2C_BOARD_INFO("si4713", 0x63),
+               .platform_data = &rx51_si4713_platform_data,
+       },
+ #endif
        {
                I2C_BOARD_INFO("tlv320aic3x", 0x18),
                .platform_data = &rx51_aic3x_data,
@@@ -1066,6 -1053,10 +1049,10 @@@ static struct i2c_board_info __initdat
  
  static int __init rx51_i2c_init(void)
  {
+ #if IS_ENABLED(CONFIG_I2C_SI4713) && IS_ENABLED(CONFIG_PLATFORM_SI4713)
+       int err;
+ #endif
        if ((system_rev >= SYSTEM_REV_S_USES_VAUX3 && system_rev < 0x100) ||
            system_rev >= SYSTEM_REV_B_USES_VAUX3) {
                rx51_twldata.vaux3 = &rx51_vaux3_mmc;
        rx51_twldata.vdac->constraints.name = "VDAC";
  
        omap_pmic_init(1, 2200, "twl5030", 7 + OMAP_INTC_START, &rx51_twldata);
+ #if IS_ENABLED(CONFIG_I2C_SI4713) && IS_ENABLED(CONFIG_PLATFORM_SI4713)
+       err = gpio_request_one(RX51_FMTX_IRQ, GPIOF_DIR_IN, "si4713 irq");
+       if (err) {
+               printk(KERN_ERR "Cannot request si4713 irq gpio. %d\n", err);
+               return err;
+       }
+       rx51_peripherals_i2c_board_info_2[0].irq = gpio_to_irq(RX51_FMTX_IRQ);
+ #endif
        omap_register_i2c_bus(2, 100, rx51_peripherals_i2c_board_info_2,
                              ARRAY_SIZE(rx51_peripherals_i2c_board_info_2));
  #if defined(CONFIG_SENSORS_LIS3_I2C) || defined(CONFIG_SENSORS_LIS3_I2C_MODULE)
@@@ -1142,6 -1141,33 +1137,6 @@@ static struct omap_onenand_platform_dat
  };
  #endif
  
 -#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
 -
 -static struct omap_smc91x_platform_data board_smc91x_data = {
 -      .cs             = 1,
 -      .gpio_irq       = 54,
 -      .gpio_pwrdwn    = 86,
 -      .gpio_reset     = 164,
 -      .flags          = GPMC_TIMINGS_SMC91C96 | IORESOURCE_IRQ_HIGHLEVEL,
 -};
 -
 -static void __init board_smc91x_init(void)
 -{
 -      omap_mux_init_gpio(54, OMAP_PIN_INPUT_PULLDOWN);
 -      omap_mux_init_gpio(86, OMAP_PIN_OUTPUT);
 -      omap_mux_init_gpio(164, OMAP_PIN_OUTPUT);
 -
 -      gpmc_smc91x_init(&board_smc91x_data);
 -}
 -
 -#else
 -
 -static inline void board_smc91x_init(void)
 -{
 -}
 -
 -#endif
 -
  static struct gpio rx51_wl1251_gpios[] __initdata = {
        { RX51_WL1251_IRQ_GPIO,   GPIOF_IN,             "wl1251 irq"    },
  };
@@@ -1269,13 -1295,14 +1264,13 @@@ static void __init rx51_init_omap3_rom_
  
  void __init rx51_peripherals_init(void)
  {
+       rx51_gpio_init();
        rx51_i2c_init();
        regulator_has_full_constraints();
        gpmc_onenand_init(board_onenand_data);
 -      board_smc91x_init();
        rx51_add_gpio_keys();
        rx51_init_wl1251();
        rx51_init_tsc2005();
-       rx51_init_si4713();
        rx51_init_lirc();
        spi_register_board_info(rx51_peripherals_spi_board_info,
                                ARRAY_SIZE(rx51_peripherals_spi_board_info));
@@@ -49,7 -49,7 +49,7 @@@ static int __init omap3_l3_init(void
         * To avoid code running on other OMAPs in
         * multi-omap builds
         */
 -      if (!(cpu_is_omap34xx()))
 +      if (!(cpu_is_omap34xx()) || of_have_populated_dt())
                return -ENODEV;
  
        snprintf(oh_name, L3_MODULES_MAX_LEN, "l3_main");
  }
  omap_postcore_initcall(omap3_l3_init);
  
- #if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE)
 -static int __init omap4_l3_init(void)
 -{
 -      int i;
 -      struct omap_hwmod *oh[3];
 -      struct platform_device *pdev;
 -      char oh_name[L3_MODULES_MAX_LEN];
--
- static struct resource omap2cam_resources[] = {
-       {
-               .start          = OMAP24XX_CAMERA_BASE,
-               .end            = OMAP24XX_CAMERA_BASE + 0xfff,
-               .flags          = IORESOURCE_MEM,
-       },
-       {
-               .start          = 24 + OMAP_INTC_START,
-               .flags          = IORESOURCE_IRQ,
 -      /* If dtb is there, the devices will be created dynamically */
 -      if (of_have_populated_dt())
 -              return -ENODEV;
 -
 -      /*
 -       * To avoid code running on other OMAPs in
 -       * multi-omap builds
 -       */
 -      if (!cpu_is_omap44xx() && !soc_is_omap54xx())
 -              return -ENODEV;
 -
 -      for (i = 0; i < L3_MODULES; i++) {
 -              snprintf(oh_name, L3_MODULES_MAX_LEN, "l3_main_%d", i+1);
 -
 -              oh[i] = omap_hwmod_lookup(oh_name);
 -              if (!(oh[i]))
 -                      pr_err("could not look up %s\n", oh_name);
--      }
- };
--
- static struct platform_device omap2cam_device = {
-       .name           = "omap24xxcam",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(omap2cam_resources),
-       .resource       = omap2cam_resources,
- };
- #endif
 -      pdev = omap_device_build_ss("omap_l3_noc", 0, oh, 3, NULL, 0);
 -
 -      WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name);
 -
 -      return PTR_RET(pdev);
 -}
 -omap_postcore_initcall(omap4_l3_init);
--
  #if defined(CONFIG_IOMMU_API)
  
  #include <linux/platform_data/iommu-omap.h>
@@@ -211,14 -223,6 +189,6 @@@ int omap3_init_camera(struct isp_platfo
  
  #endif
  
- static inline void omap_init_camera(void)
- {
- #if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE)
-       if (cpu_is_omap24xx())
-               platform_device_register(&omap2cam_device);
- #endif
- }
  #if defined(CONFIG_OMAP2PLUS_MBOX) || defined(CONFIG_OMAP2PLUS_MBOX_MODULE)
  static inline void __init omap_init_mbox(void)
  {
@@@ -397,7 -401,6 +367,6 @@@ static int __init omap2_init_devices(vo
         * in alphabetical order so they're easier to sort through.
         */
        omap_init_audio();
-       omap_init_camera();
        /* If dtb is there, the devices will be created dynamically */
        if (!of_have_populated_dt()) {
                omap_init_mbox();
        return 0;
  }
  omap_arch_initcall(omap2_init_devices);
 +
 +static int __init omap_gpmc_init(void)
 +{
 +      struct omap_hwmod *oh;
 +      struct platform_device *pdev;
 +      char *oh_name = "gpmc";
 +
 +      /*
 +       * if the board boots up with a populated DT, do not
 +       * manually add the device from this initcall
 +       */
 +      if (of_have_populated_dt())
 +              return -ENODEV;
 +
 +      oh = omap_hwmod_lookup(oh_name);
 +      if (!oh) {
 +              pr_err("Could not look up %s\n", oh_name);
 +              return -ENODEV;
 +      }
 +
 +      pdev = omap_device_build("omap-gpmc", -1, oh, NULL, 0);
 +      WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name);
 +
 +      return PTR_RET(pdev);
 +}
 +omap_postcore_initcall(omap_gpmc_init);
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program; if not, write to the Free Software
 - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
   */
  #include <linux/delay.h>
  #include <linux/kernel.h>
@@@ -1149,7 -1153,7 +1149,7 @@@ static struct soc_camera_platform_info 
        .format_name = "UYVY",
        .format_depth = 16,
        .format = {
-               .code = V4L2_MBUS_FMT_UYVY8_2X8,
+               .code = MEDIA_BUS_FMT_UYVY8_2X8,
                .colorspace = V4L2_COLORSPACE_SMPTE170M,
                .field = V4L2_FIELD_NONE,
                .width = 640,
@@@ -205,12 -205,12 +205,12 @@@ static int smiapp_pll_configure(struct 
        int rval;
  
        rval = smiapp_write(
-               sensor, SMIAPP_REG_U16_VT_PIX_CLK_DIV, pll->vt_pix_clk_div);
+               sensor, SMIAPP_REG_U16_VT_PIX_CLK_DIV, pll->vt.pix_clk_div);
        if (rval < 0)
                return rval;
  
        rval = smiapp_write(
-               sensor, SMIAPP_REG_U16_VT_SYS_CLK_DIV, pll->vt_sys_clk_div);
+               sensor, SMIAPP_REG_U16_VT_SYS_CLK_DIV, pll->vt.sys_clk_div);
        if (rval < 0)
                return rval;
  
        /* Lane op clock ratio does not apply here. */
        rval = smiapp_write(
                sensor, SMIAPP_REG_U32_REQUESTED_LINK_BIT_RATE_MBPS,
-               DIV_ROUND_UP(pll->op_sys_clk_freq_hz, 1000000 / 256 / 256));
+               DIV_ROUND_UP(pll->op.sys_clk_freq_hz, 1000000 / 256 / 256));
        if (rval < 0 || sensor->minfo.smiapp_profile == SMIAPP_PROFILE_0)
                return rval;
  
        rval = smiapp_write(
-               sensor, SMIAPP_REG_U16_OP_PIX_CLK_DIV, pll->op_pix_clk_div);
+               sensor, SMIAPP_REG_U16_OP_PIX_CLK_DIV, pll->op.pix_clk_div);
        if (rval < 0)
                return rval;
  
        return smiapp_write(
-               sensor, SMIAPP_REG_U16_OP_SYS_CLK_DIV, pll->op_sys_clk_div);
+               sensor, SMIAPP_REG_U16_OP_SYS_CLK_DIV, pll->op.sys_clk_div);
  }
  
- static int smiapp_pll_update(struct smiapp_sensor *sensor)
+ static int smiapp_pll_try(struct smiapp_sensor *sensor,
+                         struct smiapp_pll *pll)
  {
        struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
        struct smiapp_pll_limits lim = {
                .min_line_length_pck_bin = sensor->limits[SMIAPP_LIMIT_MIN_LINE_LENGTH_PCK_BIN],
                .min_line_length_pck = sensor->limits[SMIAPP_LIMIT_MIN_LINE_LENGTH_PCK],
        };
+       return smiapp_pll_calculate(&client->dev, &lim, pll);
+ }
+ static int smiapp_pll_update(struct smiapp_sensor *sensor)
+ {
        struct smiapp_pll *pll = &sensor->pll;
        int rval;
  
-       if (sensor->minfo.smiapp_profile == SMIAPP_PROFILE_0) {
-               /*
-                * Fill in operational clock divisors limits from the
-                * video timing ones. On profile 0 sensors the
-                * requirements regarding them are essentially the
-                * same as on VT ones.
-                */
-               lim.op = lim.vt;
-       }
        pll->binning_horizontal = sensor->binning_horizontal;
        pll->binning_vertical = sensor->binning_vertical;
        pll->link_freq =
        pll->scale_m = sensor->scale_m;
        pll->bits_per_pixel = sensor->csi_format->compressed;
  
-       rval = smiapp_pll_calculate(&client->dev, &lim, pll);
+       rval = smiapp_pll_try(sensor, pll);
        if (rval < 0)
                return rval;
  
        __v4l2_ctrl_s_ctrl_int64(sensor->pixel_rate_parray,
-                                pll->vt_pix_clk_freq_hz);
+                                pll->pixel_rate_pixel_array);
        __v4l2_ctrl_s_ctrl_int64(sensor->pixel_rate_csi, pll->pixel_rate_csi);
  
        return 0;
@@@ -333,22 -330,22 +330,22 @@@ static void __smiapp_update_exposure_li
   *    orders must be defined.
   */
  static const struct smiapp_csi_data_format smiapp_csi_data_formats[] = {
-       { V4L2_MBUS_FMT_SGRBG12_1X12, 12, 12, SMIAPP_PIXEL_ORDER_GRBG, },
-       { V4L2_MBUS_FMT_SRGGB12_1X12, 12, 12, SMIAPP_PIXEL_ORDER_RGGB, },
-       { V4L2_MBUS_FMT_SBGGR12_1X12, 12, 12, SMIAPP_PIXEL_ORDER_BGGR, },
-       { V4L2_MBUS_FMT_SGBRG12_1X12, 12, 12, SMIAPP_PIXEL_ORDER_GBRG, },
-       { V4L2_MBUS_FMT_SGRBG10_1X10, 10, 10, SMIAPP_PIXEL_ORDER_GRBG, },
-       { V4L2_MBUS_FMT_SRGGB10_1X10, 10, 10, SMIAPP_PIXEL_ORDER_RGGB, },
-       { V4L2_MBUS_FMT_SBGGR10_1X10, 10, 10, SMIAPP_PIXEL_ORDER_BGGR, },
-       { V4L2_MBUS_FMT_SGBRG10_1X10, 10, 10, SMIAPP_PIXEL_ORDER_GBRG, },
-       { V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, 10, 8, SMIAPP_PIXEL_ORDER_GRBG, },
-       { V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8, 10, 8, SMIAPP_PIXEL_ORDER_RGGB, },
-       { V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8, 10, 8, SMIAPP_PIXEL_ORDER_BGGR, },
-       { V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8, 10, 8, SMIAPP_PIXEL_ORDER_GBRG, },
-       { V4L2_MBUS_FMT_SGRBG8_1X8, 8, 8, SMIAPP_PIXEL_ORDER_GRBG, },
-       { V4L2_MBUS_FMT_SRGGB8_1X8, 8, 8, SMIAPP_PIXEL_ORDER_RGGB, },
-       { V4L2_MBUS_FMT_SBGGR8_1X8, 8, 8, SMIAPP_PIXEL_ORDER_BGGR, },
-       { V4L2_MBUS_FMT_SGBRG8_1X8, 8, 8, SMIAPP_PIXEL_ORDER_GBRG, },
+       { MEDIA_BUS_FMT_SGRBG12_1X12, 12, 12, SMIAPP_PIXEL_ORDER_GRBG, },
+       { MEDIA_BUS_FMT_SRGGB12_1X12, 12, 12, SMIAPP_PIXEL_ORDER_RGGB, },
+       { MEDIA_BUS_FMT_SBGGR12_1X12, 12, 12, SMIAPP_PIXEL_ORDER_BGGR, },
+       { MEDIA_BUS_FMT_SGBRG12_1X12, 12, 12, SMIAPP_PIXEL_ORDER_GBRG, },
+       { MEDIA_BUS_FMT_SGRBG10_1X10, 10, 10, SMIAPP_PIXEL_ORDER_GRBG, },
+       { MEDIA_BUS_FMT_SRGGB10_1X10, 10, 10, SMIAPP_PIXEL_ORDER_RGGB, },
+       { MEDIA_BUS_FMT_SBGGR10_1X10, 10, 10, SMIAPP_PIXEL_ORDER_BGGR, },
+       { MEDIA_BUS_FMT_SGBRG10_1X10, 10, 10, SMIAPP_PIXEL_ORDER_GBRG, },
+       { MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, 10, 8, SMIAPP_PIXEL_ORDER_GRBG, },
+       { MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8, 10, 8, SMIAPP_PIXEL_ORDER_RGGB, },
+       { MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8, 10, 8, SMIAPP_PIXEL_ORDER_BGGR, },
+       { MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8, 10, 8, SMIAPP_PIXEL_ORDER_GBRG, },
+       { MEDIA_BUS_FMT_SGRBG8_1X8, 8, 8, SMIAPP_PIXEL_ORDER_GRBG, },
+       { MEDIA_BUS_FMT_SRGGB8_1X8, 8, 8, SMIAPP_PIXEL_ORDER_RGGB, },
+       { MEDIA_BUS_FMT_SBGGR8_1X8, 8, 8, SMIAPP_PIXEL_ORDER_BGGR, },
+       { MEDIA_BUS_FMT_SGBRG8_1X8, 8, 8, SMIAPP_PIXEL_ORDER_GBRG, },
  };
  
  const char *pixel_order_str[] = { "GRBG", "RGGB", "BGGR", "GBRG" };
@@@ -526,6 -523,8 +523,8 @@@ static const struct v4l2_ctrl_ops smiap
  static int smiapp_init_controls(struct smiapp_sensor *sensor)
  {
        struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
+       unsigned long *valid_link_freqs = &sensor->valid_link_freqs[
+               sensor->csi_format->compressed - SMIAPP_COMPRESSED_BASE];
        unsigned int max, i;
        int rval;
  
  
        sensor->link_freq = v4l2_ctrl_new_int_menu(
                &sensor->src->ctrl_handler, &smiapp_ctrl_ops,
-               V4L2_CID_LINK_FREQ, max, 0,
-               sensor->platform_data->op_sys_clock);
+               V4L2_CID_LINK_FREQ, __fls(*valid_link_freqs),
+               __ffs(*valid_link_freqs), sensor->platform_data->op_sys_clock);
  
        sensor->pixel_rate_csi = v4l2_ctrl_new_std(
                &sensor->src->ctrl_handler, &smiapp_ctrl_ops,
@@@ -745,6 -744,7 +744,7 @@@ static int smiapp_get_limits_binning(st
  static int smiapp_get_mbus_formats(struct smiapp_sensor *sensor)
  {
        struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
+       struct smiapp_pll *pll = &sensor->pll;
        unsigned int type, n;
        unsigned int i, pixel_order;
        int rval;
                        dev_dbg(&client->dev, "jolly good! %d\n", j);
  
                        sensor->default_mbus_frame_fmts |= 1 << j;
-                       if (!sensor->csi_format
-                           || f->width > sensor->csi_format->width
-                           || (f->width == sensor->csi_format->width
-                               && f->compressed
-                               > sensor->csi_format->compressed)) {
-                               sensor->csi_format = f;
-                               sensor->internal_csi_format = f;
-                       }
+               }
+       }
+       /* Figure out which BPP values can be used with which formats. */
+       pll->binning_horizontal = 1;
+       pll->binning_vertical = 1;
+       pll->scale_m = sensor->scale_m;
+       for (i = 0; i < ARRAY_SIZE(smiapp_csi_data_formats); i++) {
+               const struct smiapp_csi_data_format *f =
+                       &smiapp_csi_data_formats[i];
+               unsigned long *valid_link_freqs =
+                       &sensor->valid_link_freqs[
+                               f->compressed - SMIAPP_COMPRESSED_BASE];
+               unsigned int j;
+               BUG_ON(f->compressed < SMIAPP_COMPRESSED_BASE);
+               BUG_ON(f->compressed > SMIAPP_COMPRESSED_MAX);
+               if (!(sensor->default_mbus_frame_fmts & 1 << i))
+                       continue;
+               pll->bits_per_pixel = f->compressed;
+               for (j = 0; sensor->platform_data->op_sys_clock[j]; j++) {
+                       pll->link_freq = sensor->platform_data->op_sys_clock[j];
+                       rval = smiapp_pll_try(sensor, pll);
+                       dev_dbg(&client->dev, "link freq %u Hz, bpp %u %s\n",
+                               pll->link_freq, pll->bits_per_pixel,
+                               rval ? "not ok" : "ok");
+                       if (rval)
+                               continue;
+                       set_bit(j, valid_link_freqs);
+               }
+               if (!*valid_link_freqs) {
+                       dev_info(&client->dev,
+                                "no valid link frequencies for %u bpp\n",
+                                f->compressed);
+                       sensor->default_mbus_frame_fmts &= ~BIT(i);
+                       continue;
+               }
+               if (!sensor->csi_format
+                   || f->width > sensor->csi_format->width
+                   || (f->width == sensor->csi_format->width
+                       && f->compressed > sensor->csi_format->compressed)) {
+                       sensor->csi_format = f;
+                       sensor->internal_csi_format = f;
                }
        }
  
@@@ -904,7 -947,7 +947,7 @@@ static int smiapp_update_mode(struct sm
        dev_dbg(&client->dev, "hblank\t\t%d\n", sensor->hblank->val);
  
        dev_dbg(&client->dev, "real timeperframe\t100/%d\n",
-               sensor->pll.vt_pix_clk_freq_hz /
+               sensor->pll.pixel_rate_pixel_array /
                ((sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].width
                  + sensor->hblank->val) *
                 (sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height
@@@ -1687,51 -1730,77 +1730,77 @@@ static const struct smiapp_csi_data_for
        return csi_format;
  }
  
- static int smiapp_set_format(struct v4l2_subdev *subdev,
-                            struct v4l2_subdev_fh *fh,
-                            struct v4l2_subdev_format *fmt)
+ static int smiapp_set_format_source(struct v4l2_subdev *subdev,
+                                   struct v4l2_subdev_fh *fh,
+                                   struct v4l2_subdev_format *fmt)
  {
        struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
-       struct smiapp_subdev *ssd = to_smiapp_subdev(subdev);
-       struct v4l2_rect *crops[SMIAPP_PADS];
+       const struct smiapp_csi_data_format *csi_format,
+               *old_csi_format = sensor->csi_format;
+       unsigned long *valid_link_freqs;
+       u32 code = fmt->format.code;
+       unsigned int i;
+       int rval;
  
-       mutex_lock(&sensor->mutex);
+       rval = __smiapp_get_format(subdev, fh, fmt);
+       if (rval)
+               return rval;
  
        /*
         * Media bus code is changeable on src subdev's source pad. On
         * other source pads we just get format here.
         */
-       if (fmt->pad == ssd->source_pad) {
-               u32 code = fmt->format.code;
-               int rval = __smiapp_get_format(subdev, fh, fmt);
-               bool range_changed = false;
-               unsigned int i;
+       if (subdev != &sensor->src->sd)
+               return 0;
  
-               if (!rval && subdev == &sensor->src->sd) {
-                       const struct smiapp_csi_data_format *csi_format =
-                               smiapp_validate_csi_data_format(sensor, code);
+       csi_format = smiapp_validate_csi_data_format(sensor, code);
  
-                       if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
-                               if (csi_format->width !=
-                                   sensor->csi_format->width)
-                                       range_changed = true;
+       fmt->format.code = csi_format->code;
  
-                               sensor->csi_format = csi_format;
-                       }
-                       fmt->format.code = csi_format->code;
-               }
+       if (fmt->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+               return 0;
  
-               mutex_unlock(&sensor->mutex);
-               if (rval || !range_changed)
-                       return rval;
+       sensor->csi_format = csi_format;
  
+       if (csi_format->width != old_csi_format->width)
                for (i = 0; i < ARRAY_SIZE(sensor->test_data); i++)
-                       v4l2_ctrl_modify_range(
-                               sensor->test_data[i],
-                               0, (1 << sensor->csi_format->width) - 1, 1, 0);
+                       __v4l2_ctrl_modify_range(
+                               sensor->test_data[i], 0,
+                               (1 << csi_format->width) - 1, 1, 0);
  
+       if (csi_format->compressed == old_csi_format->compressed)
                return 0;
+       valid_link_freqs = 
+               &sensor->valid_link_freqs[sensor->csi_format->compressed
+                                         - SMIAPP_COMPRESSED_BASE];
+       __v4l2_ctrl_modify_range(
+               sensor->link_freq, 0,
+               __fls(*valid_link_freqs), ~*valid_link_freqs,
+               __ffs(*valid_link_freqs));
+       return smiapp_pll_update(sensor);
+ }
+ static int smiapp_set_format(struct v4l2_subdev *subdev,
+                            struct v4l2_subdev_fh *fh,
+                            struct v4l2_subdev_format *fmt)
+ {
+       struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
+       struct smiapp_subdev *ssd = to_smiapp_subdev(subdev);
+       struct v4l2_rect *crops[SMIAPP_PADS];
+       mutex_lock(&sensor->mutex);
+       if (fmt->pad == ssd->source_pad) {
+               int rval;
+               rval = smiapp_set_format_source(subdev, fh, fmt);
+               mutex_unlock(&sensor->mutex);
+               return rval;
        }
  
        /* Sink pad. Width and height are changeable here. */
@@@ -2023,6 -2092,11 +2092,11 @@@ static int __smiapp_sel_supported(struc
                    == SMIAPP_DIGITAL_CROP_CAPABILITY_INPUT_CROP)
                        return 0;
                return -EINVAL;
+       case V4L2_SEL_TGT_NATIVE_SIZE:
+               if (ssd == sensor->pixel_array
+                   && sel->pad == SMIAPP_PA_PAD_SRC)
+                       return 0;
+               return -EINVAL;
        case V4L2_SEL_TGT_COMPOSE:
        case V4L2_SEL_TGT_COMPOSE_BOUNDS:
                if (sel->pad == ssd->source_pad)
@@@ -2121,7 -2195,9 +2195,9 @@@ static int __smiapp_get_selection(struc
  
        switch (sel->target) {
        case V4L2_SEL_TGT_CROP_BOUNDS:
+       case V4L2_SEL_TGT_NATIVE_SIZE:
                if (ssd == sensor->pixel_array) {
+                       sel->r.left = sel->r.top = 0;
                        sel->r.width =
                                sensor->limits[SMIAPP_LIMIT_X_ADDR_MAX] + 1;
                        sel->r.height =
@@@ -2190,7 -2266,7 +2266,7 @@@ static int smiapp_set_selection(struct 
                ret = smiapp_set_compose(subdev, fh, sel);
                break;
        default:
 -              BUG();
 +              ret = -EINVAL;
        }
  
        mutex_unlock(&sensor->mutex);
@@@ -2482,12 -2558,6 +2558,6 @@@ static int smiapp_registered(struct v4l
                goto out_power_off;
        }
  
-       rval = smiapp_get_mbus_formats(sensor);
-       if (rval) {
-               rval = -ENODEV;
-               goto out_power_off;
-       }
        if (sensor->limits[SMIAPP_LIMIT_BINNING_CAPABILITY]) {
                u32 val;
  
  
        sensor->scale_m = sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN];
  
+       /* prepare PLL configuration input values */
+       pll->bus_type = SMIAPP_PLL_BUS_TYPE_CSI2;
+       pll->csi2.lanes = sensor->platform_data->lanes;
+       pll->ext_clk_freq_hz = sensor->platform_data->ext_clk;
+       pll->flags = smiapp_call_quirk(sensor, pll_flags);
+       pll->scale_n = sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN];
+       /* Profile 0 sensors have no separate OP clock branch. */
+       if (sensor->minfo.smiapp_profile == SMIAPP_PROFILE_0)
+               pll->flags |= SMIAPP_PLL_FLAG_NO_OP_CLOCKS;
+       rval = smiapp_get_mbus_formats(sensor);
+       if (rval) {
+               rval = -ENODEV;
+               goto out_nvm_release;
+       }
        for (i = 0; i < SMIAPP_SUBDEVS; i++) {
                struct {
                        struct smiapp_subdev *ssd;
        if (rval < 0)
                goto out_nvm_release;
  
-       /* prepare PLL configuration input values */
-       pll->bus_type = SMIAPP_PLL_BUS_TYPE_CSI2;
-       pll->csi2.lanes = sensor->platform_data->lanes;
-       pll->ext_clk_freq_hz = sensor->platform_data->ext_clk;
-       pll->flags = smiapp_call_quirk(sensor, pll_flags);
-       /* Profile 0 sensors have no separate OP clock branch. */
-       if (sensor->minfo.smiapp_profile == SMIAPP_PROFILE_0)
-               pll->flags |= SMIAPP_PLL_FLAG_NO_OP_CLOCKS;
-       pll->scale_n = sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN];
+       mutex_lock(&sensor->mutex);
        rval = smiapp_update_mode(sensor);
+       mutex_unlock(&sensor->mutex);
        if (rval) {
                dev_err(&client->dev, "update mode failed\n");
                goto out_nvm_release;
@@@ -1078,7 -1078,7 +1078,7 @@@ static __le32 *cx23885_risc_field(__le3
        for (line = 0; line < lines; line++) {
                while (offset && offset >= sg_dma_len(sg)) {
                        offset -= sg_dma_len(sg);
 -                      sg++;
 +                      sg = sg_next(sg);
                }
  
                if (lpi && line > 0 && !(line % lpi))
                        *(rp++) = cpu_to_le32(0); /* bits 63-32 */
                        todo -= (sg_dma_len(sg)-offset);
                        offset = 0;
 -                      sg++;
 +                      sg = sg_next(sg);
                        while (todo > sg_dma_len(sg)) {
                                *(rp++) = cpu_to_le32(RISC_WRITE|
                                                    sg_dma_len(sg));
                                *(rp++) = cpu_to_le32(sg_dma_address(sg));
                                *(rp++) = cpu_to_le32(0); /* bits 63-32 */
                                todo -= sg_dma_len(sg);
 -                              sg++;
 +                              sg = sg_next(sg);
                        }
                        *(rp++) = cpu_to_le32(RISC_WRITE|RISC_EOL|todo);
                        *(rp++) = cpu_to_le32(sg_dma_address(sg));
@@@ -1453,17 -1453,12 +1453,12 @@@ int cx23885_buf_prepare(struct cx23885_
        struct cx23885_dev *dev = port->dev;
        int size = port->ts_packet_size * port->ts_packet_count;
        struct sg_table *sgt = vb2_dma_sg_plane_desc(&buf->vb, 0);
-       int rc;
  
        dprintk(1, "%s: %p\n", __func__, buf);
        if (vb2_plane_size(&buf->vb, 0) < size)
                return -EINVAL;
        vb2_set_plane_payload(&buf->vb, 0, size);
  
-       rc = dma_map_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE);
-       if (!rc)
-               return -EIO;
        cx23885_risc_databuffer(dev->pci, &buf->risc,
                                sgt->sgl,
                                port->ts_packet_size, port->ts_packet_count, 0);
@@@ -1997,9 -1992,14 +1992,14 @@@ static int cx23885_initdev(struct pci_d
        if (!pci_dma_supported(pci_dev, 0xffffffff)) {
                printk("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name);
                err = -EIO;
-               goto fail_irq;
+               goto fail_context;
        }
  
+       dev->alloc_ctx = vb2_dma_sg_init_ctx(&pci_dev->dev);
+       if (IS_ERR(dev->alloc_ctx)) {
+               err = PTR_ERR(dev->alloc_ctx);
+               goto fail_context;
+       }
        err = request_irq(pci_dev->irq, cx23885_irq,
                          IRQF_SHARED, dev->name, dev);
        if (err < 0) {
        return 0;
  
  fail_irq:
+       vb2_dma_sg_cleanup_ctx(dev->alloc_ctx);
+ fail_context:
        cx23885_dev_unregister(dev);
  fail_ctrl:
        v4l2_ctrl_handler_free(hdl);
@@@ -2053,6 -2055,7 +2055,7 @@@ static void cx23885_finidev(struct pci_
        free_irq(pci_dev->irq, dev);
  
        cx23885_dev_unregister(dev);
+       vb2_dma_sg_cleanup_ctx(dev->alloc_ctx);
        v4l2_ctrl_handler_free(&dev->ctrl_handler);
        v4l2_device_unregister(v4l2_dev);
        kfree(dev);
@@@ -43,6 -43,7 +43,7 @@@
  #define CODA_NAME             "coda"
  
  #define CODADX6_MAX_INSTANCES 4
+ #define CODA_MAX_FORMATS      4
  
  #define CODA_PARA_BUF_SIZE    (10 * 1024)
  #define CODA_ISRAM_SIZE       (2048 * 2)
@@@ -82,6 -83,34 +83,34 @@@ unsigned int coda_read(struct coda_dev 
        return data;
  }
  
+ void coda_write_base(struct coda_ctx *ctx, struct coda_q_data *q_data,
+                    struct vb2_buffer *buf, unsigned int reg_y)
+ {
+       u32 base_y = vb2_dma_contig_plane_dma_addr(buf, 0);
+       u32 base_cb, base_cr;
+       switch (q_data->fourcc) {
+       case V4L2_PIX_FMT_YVU420:
+               /* Switch Cb and Cr for YVU420 format */
+               base_cr = base_y + q_data->bytesperline * q_data->height;
+               base_cb = base_cr + q_data->bytesperline * q_data->height / 4;
+               break;
+       case V4L2_PIX_FMT_YUV420:
+       case V4L2_PIX_FMT_NV12:
+       default:
+               base_cb = base_y + q_data->bytesperline * q_data->height;
+               base_cr = base_cb + q_data->bytesperline * q_data->height / 4;
+               break;
+       case V4L2_PIX_FMT_YUV422P:
+               base_cb = base_y + q_data->bytesperline * q_data->height;
+               base_cr = base_cb + q_data->bytesperline * q_data->height / 2;
+       }
+       coda_write(ctx->dev, base_y, reg_y);
+       coda_write(ctx->dev, base_cb, reg_y + 4);
+       coda_write(ctx->dev, base_cr, reg_y + 8);
+ }
  /*
   * Array of all formats supported by any version of Coda:
   */
@@@ -94,6 -123,14 +123,14 @@@ static const struct coda_fmt coda_forma
                .name = "YUV 4:2:0 Planar, YCrCb",
                .fourcc = V4L2_PIX_FMT_YVU420,
        },
+       {
+               .name = "YUV 4:2:0 Partial interleaved Y/CbCr",
+               .fourcc = V4L2_PIX_FMT_NV12,
+       },
+       {
+               .name = "YUV 4:2:2 Planar, YCbCr",
+               .fourcc = V4L2_PIX_FMT_YUV422P,
+       },
        {
                .name = "H264 Encoded Stream",
                .fourcc = V4L2_PIX_FMT_H264,
                .name = "MPEG4 Encoded Stream",
                .fourcc = V4L2_PIX_FMT_MPEG4,
        },
+       {
+               .name = "JPEG Encoded Images",
+               .fourcc = V4L2_PIX_FMT_JPEG,
+       },
  };
  
  #define CODA_CODEC(mode, src_fourcc, dst_fourcc, max_w, max_h) \
@@@ -122,8 -163,10 +163,10 @@@ static const struct coda_codec codadx6_
  static const struct coda_codec coda7_codecs[] = {
        CODA_CODEC(CODA7_MODE_ENCODE_H264, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_H264,   1280, 720),
        CODA_CODEC(CODA7_MODE_ENCODE_MP4,  V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_MPEG4,  1280, 720),
+       CODA_CODEC(CODA7_MODE_ENCODE_MJPG, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_JPEG,   8192, 8192),
        CODA_CODEC(CODA7_MODE_DECODE_H264, V4L2_PIX_FMT_H264,   V4L2_PIX_FMT_YUV420, 1920, 1088),
        CODA_CODEC(CODA7_MODE_DECODE_MP4,  V4L2_PIX_FMT_MPEG4,  V4L2_PIX_FMT_YUV420, 1920, 1088),
+       CODA_CODEC(CODA7_MODE_DECODE_MJPG, V4L2_PIX_FMT_JPEG,   V4L2_PIX_FMT_YUV420, 8192, 8192),
  };
  
  static const struct coda_codec coda9_codecs[] = {
        CODA_CODEC(CODA9_MODE_DECODE_MP4,  V4L2_PIX_FMT_MPEG4,  V4L2_PIX_FMT_YUV420, 1920, 1088),
  };
  
+ struct coda_video_device {
+       const char *name;
+       enum coda_inst_type type;
+       const struct coda_context_ops *ops;
+       u32 src_formats[CODA_MAX_FORMATS];
+       u32 dst_formats[CODA_MAX_FORMATS];
+ };
+ static const struct coda_video_device coda_bit_encoder = {
+       .name = "coda-encoder",
+       .type = CODA_INST_ENCODER,
+       .ops = &coda_bit_encode_ops,
+       .src_formats = {
+               V4L2_PIX_FMT_YUV420,
+               V4L2_PIX_FMT_YVU420,
+               V4L2_PIX_FMT_NV12,
+       },
+       .dst_formats = {
+               V4L2_PIX_FMT_H264,
+               V4L2_PIX_FMT_MPEG4,
+       },
+ };
+ static const struct coda_video_device coda_bit_jpeg_encoder = {
+       .name = "coda-jpeg-encoder",
+       .type = CODA_INST_ENCODER,
+       .ops = &coda_bit_encode_ops,
+       .src_formats = {
+               V4L2_PIX_FMT_YUV420,
+               V4L2_PIX_FMT_YVU420,
+               V4L2_PIX_FMT_NV12,
+               V4L2_PIX_FMT_YUV422P,
+       },
+       .dst_formats = {
+               V4L2_PIX_FMT_JPEG,
+       },
+ };
+ static const struct coda_video_device coda_bit_decoder = {
+       .name = "coda-decoder",
+       .type = CODA_INST_DECODER,
+       .ops = &coda_bit_decode_ops,
+       .src_formats = {
+               V4L2_PIX_FMT_H264,
+               V4L2_PIX_FMT_MPEG4,
+       },
+       .dst_formats = {
+               V4L2_PIX_FMT_YUV420,
+               V4L2_PIX_FMT_YVU420,
+               V4L2_PIX_FMT_NV12,
+       },
+ };
+ static const struct coda_video_device coda_bit_jpeg_decoder = {
+       .name = "coda-jpeg-decoder",
+       .type = CODA_INST_DECODER,
+       .ops = &coda_bit_decode_ops,
+       .src_formats = {
+               V4L2_PIX_FMT_JPEG,
+       },
+       .dst_formats = {
+               V4L2_PIX_FMT_YUV420,
+               V4L2_PIX_FMT_YVU420,
+               V4L2_PIX_FMT_NV12,
+               V4L2_PIX_FMT_YUV422P,
+       },
+ };
+ static const struct coda_video_device *codadx6_video_devices[] = {
+       &coda_bit_encoder,
+ };
+ static const struct coda_video_device *coda7_video_devices[] = {
+       &coda_bit_jpeg_encoder,
+       &coda_bit_jpeg_decoder,
+       &coda_bit_encoder,
+       &coda_bit_decoder,
+ };
+ static const struct coda_video_device *coda9_video_devices[] = {
+       &coda_bit_encoder,
+       &coda_bit_decoder,
+ };
  static bool coda_format_is_yuv(u32 fourcc)
  {
        switch (fourcc) {
        case V4L2_PIX_FMT_YUV420:
        case V4L2_PIX_FMT_YVU420:
+       case V4L2_PIX_FMT_NV12:
+       case V4L2_PIX_FMT_YUV422P:
                return true;
        default:
                return false;
        }
  }
  
+ static const char *coda_format_name(u32 fourcc)
+ {
+       int i;
+       for (i = 0; i < ARRAY_SIZE(coda_formats); i++) {
+               if (coda_formats[i].fourcc == fourcc)
+                       return coda_formats[i].name;
+       }
+       return NULL;
+ }
  /*
   * Normalize all supported YUV 4:2:0 formats to the value used in the codec
   * tables.
@@@ -202,6 -343,17 +343,17 @@@ static void coda_get_max_dimensions(str
                *max_h = h;
  }
  
+ const struct coda_video_device *to_coda_video_device(struct video_device *vdev)
+ {
+       struct coda_dev *dev = video_get_drvdata(vdev);
+       unsigned int i = vdev - dev->vfd;
+       if (i >= dev->devtype->num_vdevs)
+               return NULL;
+       return dev->devtype->vdevs[i];
+ }
  const char *coda_product_name(int product)
  {
        static char buf[9];
@@@ -240,58 -392,28 +392,28 @@@ static int coda_querycap(struct file *f
  static int coda_enum_fmt(struct file *file, void *priv,
                         struct v4l2_fmtdesc *f)
  {
-       struct coda_ctx *ctx = fh_to_ctx(priv);
-       const struct coda_codec *codecs = ctx->dev->devtype->codecs;
-       const struct coda_fmt *formats = coda_formats;
-       const struct coda_fmt *fmt;
-       int num_codecs = ctx->dev->devtype->num_codecs;
-       int num_formats = ARRAY_SIZE(coda_formats);
-       int i, k, num = 0;
-       bool yuv;
-       if (ctx->inst_type == CODA_INST_ENCODER)
-               yuv = (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT);
+       struct video_device *vdev = video_devdata(file);
+       const struct coda_video_device *cvd = to_coda_video_device(vdev);
+       const u32 *formats;
+       const char *name;
+       if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
+               formats = cvd->src_formats;
+       else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               formats = cvd->dst_formats;
        else
-               yuv = (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE);
-       for (i = 0; i < num_formats; i++) {
-               /* Skip either raw or compressed formats */
-               if (yuv != coda_format_is_yuv(formats[i].fourcc))
-                       continue;
-               /* All uncompressed formats are always supported */
-               if (yuv) {
-                       if (num == f->index)
-                               break;
-                       ++num;
-                       continue;
-               }
-               /* Compressed formats may be supported, check the codec list */
-               for (k = 0; k < num_codecs; k++) {
-                       if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
-                           formats[i].fourcc == codecs[k].dst_fourcc)
-                               break;
-                       if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
-                           formats[i].fourcc == codecs[k].src_fourcc)
-                               break;
-               }
-               if (k < num_codecs) {
-                       if (num == f->index)
-                               break;
-                       ++num;
-               }
-       }
+               return -EINVAL;
  
-       if (i < num_formats) {
-               fmt = &formats[i];
-               strlcpy(f->description, fmt->name, sizeof(f->description));
-               f->pixelformat = fmt->fourcc;
-               if (!yuv)
-                       f->flags |= V4L2_FMT_FLAG_COMPRESSED;
-               return 0;
-       }
+       if (f->index >= CODA_MAX_FORMATS || formats[f->index] == 0)
+               return -EINVAL;
+       name = coda_format_name(formats[f->index]);
+       strlcpy(f->description, name, sizeof(f->description));
+       f->pixelformat = formats[f->index];
+       if (!coda_format_is_yuv(formats[f->index]))
+               f->flags |= V4L2_FMT_FLAG_COMPRESSED;
  
-       /* Format not found */
-       return -EINVAL;
+       return 0;
  }
  
  static int coda_g_fmt(struct file *file, void *priv,
        f->fmt.pix.bytesperline = q_data->bytesperline;
  
        f->fmt.pix.sizeimage    = q_data->sizeimage;
-       f->fmt.pix.colorspace   = ctx->colorspace;
+       if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_JPEG)
+               f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
+       else
+               f->fmt.pix.colorspace = ctx->colorspace;
+       return 0;
+ }
+ static int coda_try_pixelformat(struct coda_ctx *ctx, struct v4l2_format *f)
+ {
+       struct coda_q_data *q_data;
+       const u32 *formats;
+       int i;
+       if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
+               formats = ctx->cvd->src_formats;
+       else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               formats = ctx->cvd->dst_formats;
+       else
+               return -EINVAL;
+       for (i = 0; i < CODA_MAX_FORMATS; i++) {
+               if (formats[i] == f->fmt.pix.pixelformat) {
+                       f->fmt.pix.pixelformat = formats[i];
+                       return 0;
+               }
+       }
+       /* Fall back to currently set pixelformat */
+       q_data = get_q_data(ctx, f->type);
+       f->fmt.pix.pixelformat = q_data->fourcc;
  
        return 0;
  }
@@@ -320,7 -472,6 +472,6 @@@ static int coda_try_fmt(struct coda_ct
                        struct v4l2_format *f)
  {
        struct coda_dev *dev = ctx->dev;
-       struct coda_q_data *q_data;
        unsigned int max_w, max_h;
        enum v4l2_field field;
  
        switch (f->fmt.pix.pixelformat) {
        case V4L2_PIX_FMT_YUV420:
        case V4L2_PIX_FMT_YVU420:
-       case V4L2_PIX_FMT_H264:
-       case V4L2_PIX_FMT_MPEG4:
-       case V4L2_PIX_FMT_JPEG:
-               break;
-       default:
-               q_data = get_q_data(ctx, f->type);
-               if (!q_data)
-                       return -EINVAL;
-               f->fmt.pix.pixelformat = q_data->fourcc;
-       }
-       switch (f->fmt.pix.pixelformat) {
-       case V4L2_PIX_FMT_YUV420:
-       case V4L2_PIX_FMT_YVU420:
-               /* Frame stride must be multiple of 8, but 16 for h.264 */
+       case V4L2_PIX_FMT_NV12:
+               /*
+                * Frame stride must be at least multiple of 8,
+                * but multiple of 16 for h.264 or JPEG 4:2:x
+                */
                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;
                break;
+       case V4L2_PIX_FMT_YUV422P:
+               f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 16);
+               f->fmt.pix.sizeimage = f->fmt.pix.bytesperline *
+                                       f->fmt.pix.height * 2;
+               break;
+       case V4L2_PIX_FMT_JPEG:
+               f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
+               /* fallthrough */
        case V4L2_PIX_FMT_H264:
        case V4L2_PIX_FMT_MPEG4:
-       case V4L2_PIX_FMT_JPEG:
                f->fmt.pix.bytesperline = 0;
-               f->fmt.pix.sizeimage = CODA_MAX_FRAME_SIZE;
+               /*
+                * This is a rough estimate for sensible compressed buffer
+                * sizes (between 1 and 16 bits per pixel). This could be
+                * improved by better format specific worst case estimates.
+                */
+               f->fmt.pix.sizeimage = round_up(clamp(f->fmt.pix.sizeimage,
+                               f->fmt.pix.width * f->fmt.pix.height / 8,
+                               f->fmt.pix.width * f->fmt.pix.height * 2),
+                               PAGE_SIZE);
                break;
        default:
                BUG();
@@@ -378,34 -534,35 +534,35 @@@ static int coda_try_fmt_vid_cap(struct 
                                struct v4l2_format *f)
  {
        struct coda_ctx *ctx = fh_to_ctx(priv);
-       const struct coda_codec *codec = NULL;
+       const struct coda_q_data *q_data_src;
+       const struct coda_codec *codec;
        struct vb2_queue *src_vq;
        int ret;
  
+       ret = coda_try_pixelformat(ctx, f);
+       if (ret < 0)
+               return ret;
+       q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
        /*
-        * If the source format is already fixed, try to find a codec that
-        * converts to the given destination format
+        * If the source format is already fixed, only allow the same output
+        * resolution
         */
        src_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
        if (vb2_is_streaming(src_vq)) {
-               struct coda_q_data *q_data_src;
-               q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
-               codec = coda_find_codec(ctx->dev, q_data_src->fourcc,
-                                       f->fmt.pix.pixelformat);
-               if (!codec)
-                       return -EINVAL;
                f->fmt.pix.width = q_data_src->width;
                f->fmt.pix.height = q_data_src->height;
-       } else {
-               /* Otherwise determine codec by encoded format, if possible */
-               codec = coda_find_codec(ctx->dev, V4L2_PIX_FMT_YUV420,
-                                       f->fmt.pix.pixelformat);
        }
  
        f->fmt.pix.colorspace = ctx->colorspace;
  
+       q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+       codec = coda_find_codec(ctx->dev, q_data_src->fourcc,
+                               f->fmt.pix.pixelformat);
+       if (!codec)
+               return -EINVAL;
        ret = coda_try_fmt(ctx, codec, f);
        if (ret < 0)
                return ret;
@@@ -426,21 -583,24 +583,24 @@@ static int coda_try_fmt_vid_out(struct 
                                struct v4l2_format *f)
  {
        struct coda_ctx *ctx = fh_to_ctx(priv);
-       const struct coda_codec *codec = NULL;
+       struct coda_dev *dev = ctx->dev;
+       const struct coda_q_data *q_data_dst;
+       const struct coda_codec *codec;
+       int ret;
  
-       /* Determine codec by encoded format, returns NULL if raw or invalid */
-       if (ctx->inst_type == CODA_INST_DECODER) {
-               codec = coda_find_codec(ctx->dev, f->fmt.pix.pixelformat,
-                                       V4L2_PIX_FMT_YUV420);
-               if (!codec)
-                       codec = coda_find_codec(ctx->dev, V4L2_PIX_FMT_H264,
-                                               V4L2_PIX_FMT_YUV420);
-               if (!codec)
-                       return -EINVAL;
+       ret = coda_try_pixelformat(ctx, f);
+       if (ret < 0)
+               return ret;
+       if (!f->fmt.pix.colorspace) {
+               if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_JPEG)
+                       f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
+               else
+                       f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709;
        }
  
-       if (!f->fmt.pix.colorspace)
-               f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709;
+       q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+       codec = coda_find_codec(dev, f->fmt.pix.pixelformat, q_data_dst->fourcc);
  
        return coda_try_fmt(ctx, codec, f);
  }
@@@ -781,6 -941,7 +941,7 @@@ static int coda_job_ready(void *m2m_pri
  
        if (ctx->hold ||
            ((ctx->inst_type == CODA_INST_DECODER) &&
+            !v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) &&
             (coda_get_bitstream_payload(ctx) < 512) &&
             !(ctx->bit_stream_param & CODA_BIT_STREAM_END_FLAG))) {
                v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
@@@ -862,25 -1023,17 +1023,17 @@@ static void coda_set_tiled_map_type(str
  
  static void set_default_params(struct coda_ctx *ctx)
  {
-       u32 src_fourcc, dst_fourcc;
-       int max_w;
-       int max_h;
+       unsigned int max_w, max_h, size;
  
-       if (ctx->inst_type == CODA_INST_ENCODER) {
-               src_fourcc = V4L2_PIX_FMT_YUV420;
-               dst_fourcc = V4L2_PIX_FMT_H264;
-       } else {
-               src_fourcc = V4L2_PIX_FMT_H264;
-               dst_fourcc = V4L2_PIX_FMT_YUV420;
-       }
-       ctx->codec = coda_find_codec(ctx->dev, src_fourcc, dst_fourcc);
-       max_w = ctx->codec->max_w;
-       max_h = ctx->codec->max_h;
+       ctx->codec = coda_find_codec(ctx->dev, ctx->cvd->src_formats[0],
+                                    ctx->cvd->dst_formats[0]);
+       max_w = min(ctx->codec->max_w, 1920U);
+       max_h = min(ctx->codec->max_h, 1088U);
+       size = max_w * max_h * 3 / 2;
  
        ctx->params.codec_mode = ctx->codec->mode;
        ctx->colorspace = V4L2_COLORSPACE_REC709;
        ctx->params.framerate = 30;
-       ctx->aborting = 0;
  
        /* Default formats for output and input queues */
        ctx->q_data[V4L2_M2M_SRC].fourcc = ctx->codec->src_fourcc;
        ctx->q_data[V4L2_M2M_DST].height = max_h;
        if (ctx->codec->src_fourcc == V4L2_PIX_FMT_YUV420) {
                ctx->q_data[V4L2_M2M_SRC].bytesperline = max_w;
-               ctx->q_data[V4L2_M2M_SRC].sizeimage = (max_w * max_h * 3) / 2;
+               ctx->q_data[V4L2_M2M_SRC].sizeimage = size;
                ctx->q_data[V4L2_M2M_DST].bytesperline = 0;
-               ctx->q_data[V4L2_M2M_DST].sizeimage = CODA_MAX_FRAME_SIZE;
+               ctx->q_data[V4L2_M2M_DST].sizeimage = round_up(size, PAGE_SIZE);
        } else {
                ctx->q_data[V4L2_M2M_SRC].bytesperline = 0;
-               ctx->q_data[V4L2_M2M_SRC].sizeimage = CODA_MAX_FRAME_SIZE;
+               ctx->q_data[V4L2_M2M_SRC].sizeimage = round_up(size, PAGE_SIZE);
                ctx->q_data[V4L2_M2M_DST].bytesperline = max_w;
-               ctx->q_data[V4L2_M2M_DST].sizeimage = (max_w * max_h * 3) / 2;
+               ctx->q_data[V4L2_M2M_DST].sizeimage = size;
        }
        ctx->q_data[V4L2_M2M_SRC].rect.width = max_w;
        ctx->q_data[V4L2_M2M_SRC].rect.height = max_h;
@@@ -964,7 -1117,7 +1117,7 @@@ static void coda_buf_queue(struct vb2_b
         * In the decoder case, immediately try to copy the buffer into the
         * bitstream ringbuffer and mark it as ready to be dequeued.
         */
-       if (q_data->fourcc == V4L2_PIX_FMT_H264 &&
+       if (ctx->inst_type == CODA_INST_DECODER &&
            vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
                /*
                 * For backwards compatibility, queuing an empty buffer marks
@@@ -1027,12 -1180,13 +1180,13 @@@ static int coda_start_streaming(struct 
        struct v4l2_device *v4l2_dev = &ctx->dev->v4l2_dev;
        struct coda_q_data *q_data_src, *q_data_dst;
        struct vb2_buffer *buf;
-       u32 dst_fourcc;
        int ret = 0;
  
        q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
        if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
-               if (q_data_src->fourcc == V4L2_PIX_FMT_H264) {
+               if (q_data_src->fourcc == V4L2_PIX_FMT_H264 ||
+                   (q_data_src->fourcc == V4L2_PIX_FMT_JPEG &&
+                    ctx->dev->devtype->product == CODA_7541)) {
                        /* copy the buffers that where queued before streamon */
                        mutex_lock(&ctx->bitstream_mutex);
                        coda_fill_bitstream(ctx);
        if (!(ctx->streamon_out & ctx->streamon_cap))
                return 0;
  
-       /* Allow decoder device_run with no new buffers queued */
+       /* Allow BIT decoder device_run with no new buffers queued */
        if (ctx->inst_type == CODA_INST_DECODER)
                v4l2_m2m_set_src_buffered(ctx->fh.m2m_ctx, true);
  
        ctx->gopcounter = ctx->params.gop_size - 1;
        q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
-       dst_fourcc = q_data_dst->fourcc;
  
        ctx->codec = coda_find_codec(ctx->dev, q_data_src->fourcc,
                                     q_data_dst->fourcc);
                goto err;
        }
  
+       if (q_data_dst->fourcc == V4L2_PIX_FMT_JPEG)
+               ctx->params.gop_size = 1;
+       ctx->gopcounter = ctx->params.gop_size - 1;
        ret = ctx->ops->start_streaming(ctx);
        if (ctx->inst_type == CODA_INST_DECODER) {
                if (ret == -EAGAIN)
  err:
        if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
                while ((buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx)))
-                       v4l2_m2m_buf_done(buf, VB2_BUF_STATE_DEQUEUED);
+                       v4l2_m2m_buf_done(buf, VB2_BUF_STATE_QUEUED);
        } else {
                while ((buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx)))
-                       v4l2_m2m_buf_done(buf, VB2_BUF_STATE_DEQUEUED);
+                       v4l2_m2m_buf_done(buf, VB2_BUF_STATE_QUEUED);
        }
        return ret;
  }
@@@ -1131,19 -1288,20 +1288,20 @@@ static void coda_stop_streaming(struct 
        }
  
        if (!ctx->streamon_out && !ctx->streamon_cap) {
-               struct coda_timestamp *ts;
+               struct coda_buffer_meta *meta;
  
                mutex_lock(&ctx->bitstream_mutex);
-               while (!list_empty(&ctx->timestamp_list)) {
-                       ts = list_first_entry(&ctx->timestamp_list,
-                                             struct coda_timestamp, list);
-                       list_del(&ts->list);
-                       kfree(ts);
+               while (!list_empty(&ctx->buffer_meta_list)) {
+                       meta = list_first_entry(&ctx->buffer_meta_list,
+                                               struct coda_buffer_meta, list);
+                       list_del(&meta->list);
+                       kfree(meta);
                }
                mutex_unlock(&ctx->bitstream_mutex);
                kfifo_init(&ctx->bitstream_fifo,
                        ctx->bitstream.vaddr, ctx->bitstream.size);
                ctx->runcounter = 0;
+               ctx->aborting = 0;
        }
  }
  
@@@ -1226,6 -1384,12 +1384,12 @@@ static int coda_s_ctrl(struct v4l2_ctr
        case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB:
                ctx->params.intra_refresh = ctrl->val;
                break;
+       case V4L2_CID_JPEG_COMPRESSION_QUALITY:
+               coda_set_jpeg_compression_quality(ctx, ctrl->val);
+               break;
+       case V4L2_CID_JPEG_RESTART_INTERVAL:
+               ctx->params.jpeg_restart_interval = ctrl->val;
+               break;
        default:
                v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
                        "Invalid control, id=%d, val=%d\n",
@@@ -1240,14 -1404,8 +1404,8 @@@ static const struct v4l2_ctrl_ops coda_
        .s_ctrl = coda_s_ctrl,
  };
  
- static int coda_ctrls_setup(struct coda_ctx *ctx)
+ static void coda_encode_ctrls(struct coda_ctx *ctx)
  {
-       v4l2_ctrl_handler_init(&ctx->ctrls, 9);
-       v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
-               V4L2_CID_HFLIP, 0, 1, 1, 0);
-       v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
-               V4L2_CID_VFLIP, 0, 1, 1, 0);
        v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
                V4L2_CID_MPEG_VIDEO_BITRATE, 0, 32767000, 1, 0);
        v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
        v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
                V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB, 0,
                1920 * 1088 / 256, 1, 0);
+ }
+ static void coda_jpeg_encode_ctrls(struct coda_ctx *ctx)
+ {
+       v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
+               V4L2_CID_JPEG_COMPRESSION_QUALITY, 5, 100, 1, 50);
+       v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
+               V4L2_CID_JPEG_RESTART_INTERVAL, 0, 100, 1, 0);
+ }
+ static int coda_ctrls_setup(struct coda_ctx *ctx)
+ {
+       v4l2_ctrl_handler_init(&ctx->ctrls, 2);
+       v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
+               V4L2_CID_HFLIP, 0, 1, 1, 0);
+       v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
+               V4L2_CID_VFLIP, 0, 1, 1, 0);
+       if (ctx->inst_type == CODA_INST_ENCODER) {
+               if (ctx->cvd->dst_formats[0] == V4L2_PIX_FMT_JPEG)
+                       coda_jpeg_encode_ctrls(ctx);
+               else
+                       coda_encode_ctrls(ctx);
+       }
  
        if (ctx->ctrls.error) {
                v4l2_err(&ctx->dev->v4l2_dev,
@@@ -1364,10 -1546,14 +1546,14 @@@ static int coda_next_free_instance(stru
        return idx;
  }
  
- static int coda_open(struct file *file, enum coda_inst_type inst_type,
-                    const struct coda_context_ops *ctx_ops)
+ /*
+  * File operations
+  */
+ static int coda_open(struct file *file)
  {
-       struct coda_dev *dev = video_drvdata(file);
+       struct video_device *vdev = video_devdata(file);
+       struct coda_dev *dev = video_get_drvdata(vdev);
        struct coda_ctx *ctx = NULL;
        char *name;
        int ret;
        ctx->debugfs_entry = debugfs_create_dir(name, dev->debugfs_root);
        kfree(name);
  
-       ctx->inst_type = inst_type;
-       ctx->ops = ctx_ops;
+       ctx->cvd = to_coda_video_device(vdev);
+       ctx->inst_type = ctx->cvd->type;
+       ctx->ops = ctx->cvd->ops;
        init_completion(&ctx->completion);
        INIT_WORK(&ctx->pic_run_work, coda_pic_run_work);
        INIT_WORK(&ctx->seq_end_work, ctx->ops->seq_end_work);
        ctx->dev = dev;
        ctx->idx = idx;
        switch (dev->devtype->product) {
-       case CODA_7541:
        case CODA_960:
+               ctx->frame_mem_ctrl = 1 << 12;
+               /* fallthrough */
+       case CODA_7541:
                ctx->reg_idx = 0;
                break;
        default:
  
        ctx->fh.ctrl_handler = &ctx->ctrls;
  
-       ret = coda_alloc_context_buf(ctx, &ctx->parabuf, CODA_PARA_BUF_SIZE,
-                                    "parabuf");
+       ret = coda_alloc_context_buf(ctx, &ctx->parabuf,
+                                    CODA_PARA_BUF_SIZE, "parabuf");
        if (ret < 0) {
                v4l2_err(&dev->v4l2_dev, "failed to allocate parabuf");
                goto err_dma_alloc;
        }
  
        ctx->bitstream.size = CODA_MAX_FRAME_SIZE;
-       ctx->bitstream.vaddr = dma_alloc_writecombine(&dev->plat_dev->dev,
-                       ctx->bitstream.size, &ctx->bitstream.paddr, GFP_KERNEL);
+       ctx->bitstream.vaddr = dma_alloc_writecombine(
+                       &dev->plat_dev->dev, ctx->bitstream.size,
+                       &ctx->bitstream.paddr, GFP_KERNEL);
        if (!ctx->bitstream.vaddr) {
                v4l2_err(&dev->v4l2_dev,
                         "failed to allocate bitstream ringbuffer");
                ctx->bitstream.vaddr, ctx->bitstream.size);
        mutex_init(&ctx->bitstream_mutex);
        mutex_init(&ctx->buffer_mutex);
-       INIT_LIST_HEAD(&ctx->timestamp_list);
+       INIT_LIST_HEAD(&ctx->buffer_meta_list);
  
        coda_lock(ctx);
        list_add(&ctx->list, &dev->instances);
@@@ -1495,16 -1685,6 +1685,6 @@@ err_coda_max
        return ret;
  }
  
- static int coda_encoder_open(struct file *file)
- {
-       return coda_open(file, CODA_INST_ENCODER, &coda_bit_encode_ops);
- }
- static int coda_decoder_open(struct file *file)
- {
-       return coda_open(file, CODA_INST_DECODER, &coda_bit_decode_ops);
- }
  static int coda_release(struct file *file)
  {
        struct coda_dev *dev = video_drvdata(file);
  
        debugfs_remove_recursive(ctx->debugfs_entry);
  
+       if (ctx->inst_type == CODA_INST_DECODER)
+               coda_bit_stream_end_flag(ctx);
        /* If this instance is running, call .job_abort and wait for it to end */
        v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
  
        list_del(&ctx->list);
        coda_unlock(ctx);
  
-       dma_free_writecombine(&dev->plat_dev->dev, ctx->bitstream.size,
-               ctx->bitstream.vaddr, ctx->bitstream.paddr);
+       if (ctx->bitstream.vaddr) {
+               dma_free_writecombine(&dev->plat_dev->dev, ctx->bitstream.size,
+                       ctx->bitstream.vaddr, ctx->bitstream.paddr);
+       }
        if (ctx->dev->devtype->product == CODA_DX6)
                coda_free_aux_buf(dev, &ctx->workbuf);
  
        return 0;
  }
  
- static const struct v4l2_file_operations coda_encoder_fops = {
-       .owner          = THIS_MODULE,
-       .open           = coda_encoder_open,
-       .release        = coda_release,
-       .poll           = v4l2_m2m_fop_poll,
-       .unlocked_ioctl = video_ioctl2,
-       .mmap           = v4l2_m2m_fop_mmap,
- };
- static const struct v4l2_file_operations coda_decoder_fops = {
+ static const struct v4l2_file_operations coda_fops = {
        .owner          = THIS_MODULE,
-       .open           = coda_decoder_open,
+       .open           = coda_open,
        .release        = coda_release,
        .poll           = v4l2_m2m_fop_poll,
        .unlocked_ioctl = video_ioctl2,
@@@ -1664,8 -1840,16 +1840,16 @@@ err_clk_per
        return ret;
  }
  
- static int coda_register_device(struct coda_dev *dev, struct video_device *vfd)
+ static int coda_register_device(struct coda_dev *dev, int i)
  {
+       struct video_device *vfd = &dev->vfd[i];
+       if (i > ARRAY_SIZE(dev->vfd))
+               return -EINVAL;
+       snprintf(vfd->name, sizeof(vfd->name), dev->devtype->vdevs[i]->name);
+       vfd->fops       = &coda_fops;
+       vfd->ioctl_ops  = &coda_ioctl_ops;
        vfd->release    = video_device_release_empty,
        vfd->lock       = &dev->dev_mutex;
        vfd->v4l2_dev   = &dev->v4l2_dev;
@@@ -1684,7 -1868,7 +1868,7 @@@ static void coda_fw_callback(const stru
  {
        struct coda_dev *dev = context;
        struct platform_device *pdev = dev->plat_dev;
-       int ret;
+       int i, ret;
  
        if (!fw) {
                v4l2_err(&dev->v4l2_dev, "firmware request failed\n");
                goto rel_ctx;
        }
  
-       dev->vfd[0].fops      = &coda_encoder_fops,
-       dev->vfd[0].ioctl_ops = &coda_ioctl_ops;
-       snprintf(dev->vfd[0].name, sizeof(dev->vfd[0].name), "coda-encoder");
-       ret = coda_register_device(dev, &dev->vfd[0]);
-       if (ret) {
-               v4l2_err(&dev->v4l2_dev,
-                        "Failed to register encoder video device\n");
-               goto rel_m2m;
-       }
-       dev->vfd[1].fops      = &coda_decoder_fops,
-       dev->vfd[1].ioctl_ops = &coda_ioctl_ops;
-       snprintf(dev->vfd[1].name, sizeof(dev->vfd[1].name), "coda-decoder");
-       ret = coda_register_device(dev, &dev->vfd[1]);
-       if (ret) {
-               v4l2_err(&dev->v4l2_dev,
-                        "Failed to register decoder video device\n");
-               goto rel_m2m;
+       for (i = 0; i < dev->devtype->num_vdevs; i++) {
+               ret = coda_register_device(dev, i);
+               if (ret) {
+                       v4l2_err(&dev->v4l2_dev,
+                                "Failed to register %s video device: %d\n",
+                                dev->devtype->vdevs[i]->name, ret);
+                       goto rel_vfd;
+               }
        }
  
        v4l2_info(&dev->v4l2_dev, "codec registered as /dev/video[%d-%d]\n",
-                 dev->vfd[0].num, dev->vfd[1].num);
+                 dev->vfd[0].num, dev->vfd[i - 1].num);
  
        pm_runtime_put_sync(&pdev->dev);
        return;
  
- rel_m2m:
+ rel_vfd:
+       while (--i >= 0)
+               video_unregister_device(&dev->vfd[i]);
        v4l2_m2m_release(dev->m2m_dev);
  rel_ctx:
        vb2_dma_contig_cleanup_ctx(dev->alloc_ctx);
@@@ -1783,6 -1959,8 +1959,8 @@@ static const struct coda_devtype coda_d
                .product      = CODA_DX6,
                .codecs       = codadx6_codecs,
                .num_codecs   = ARRAY_SIZE(codadx6_codecs),
+               .vdevs        = codadx6_video_devices,
+               .num_vdevs    = ARRAY_SIZE(codadx6_video_devices),
                .workbuf_size = 288 * 1024 + FMO_SLICE_SAVE_BUF_SIZE * 8 * 1024,
                .iram_size    = 0xb000,
        },
                .product      = CODA_7541,
                .codecs       = coda7_codecs,
                .num_codecs   = ARRAY_SIZE(coda7_codecs),
+               .vdevs        = coda7_video_devices,
+               .num_vdevs    = ARRAY_SIZE(coda7_video_devices),
                .workbuf_size = 128 * 1024,
                .tempbuf_size = 304 * 1024,
                .iram_size    = 0x14000,
                .product      = CODA_960,
                .codecs       = coda9_codecs,
                .num_codecs   = ARRAY_SIZE(coda9_codecs),
+               .vdevs        = coda9_video_devices,
+               .num_vdevs    = ARRAY_SIZE(coda9_video_devices),
                .workbuf_size = 80 * 1024,
                .tempbuf_size = 204 * 1024,
                .iram_size    = 0x21000,
                .product      = CODA_960,
                .codecs       = coda9_codecs,
                .num_codecs   = ARRAY_SIZE(coda9_codecs),
+               .vdevs        = coda9_video_devices,
+               .num_vdevs    = ARRAY_SIZE(coda9_video_devices),
                .workbuf_size = 80 * 1024,
                .tempbuf_size = 204 * 1024,
                .iram_size    = 0x20000,
@@@ -1846,10 -2030,18 +2030,18 @@@ static int coda_probe(struct platform_d
        int ret, irq;
  
        dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
-       if (!dev) {
-               dev_err(&pdev->dev, "Not enough memory for %s\n",
-                       CODA_NAME);
+       if (!dev)
                return -ENOMEM;
+       pdev_id = of_id ? of_id->data : platform_get_device_id(pdev);
+       if (of_id) {
+               dev->devtype = of_id->data;
+       } else if (pdev_id) {
+               dev->devtype = &coda_devdata[pdev_id->driver_data];
+       } else {
+               ret = -EINVAL;
+               goto err_v4l2_register;
        }
  
        spin_lock_init(&dev->irqlock);
        mutex_init(&dev->dev_mutex);
        mutex_init(&dev->coda_mutex);
  
-       pdev_id = of_id ? of_id->data : platform_get_device_id(pdev);
-       if (of_id) {
-               dev->devtype = of_id->data;
-       } else if (pdev_id) {
-               dev->devtype = &coda_devdata[pdev_id->driver_data];
-       } else {
-               v4l2_device_unregister(&dev->v4l2_dev);
-               return -EINVAL;
-       }
        dev->debugfs_root = debugfs_create_dir("coda", NULL);
        if (!dev->debugfs_root)
                dev_warn(&pdev->dev, "failed to create debugfs root\n");
                                         dev->debugfs_root);
                if (ret < 0) {
                        dev_err(&pdev->dev, "failed to allocate work buffer\n");
-                       v4l2_device_unregister(&dev->v4l2_dev);
-                       return ret;
+                       goto err_v4l2_register;
                }
        }
  
                                         dev->debugfs_root);
                if (ret < 0) {
                        dev_err(&pdev->dev, "failed to allocate temp buffer\n");
-                       v4l2_device_unregister(&dev->v4l2_dev);
-                       return ret;
+                       goto err_v4l2_register;
                }
        }
  
        dev->workqueue = alloc_workqueue("coda", WQ_UNBOUND | WQ_MEM_RECLAIM, 1);
        if (!dev->workqueue) {
                dev_err(&pdev->dev, "unable to alloc workqueue\n");
-               return -ENOMEM;
+               ret = -ENOMEM;
+               goto err_v4l2_register;
        }
  
        platform_set_drvdata(pdev, dev);
  
        /*
         * Start activated so we can directly call coda_hw_init in
 -       * coda_fw_callback regardless of whether CONFIG_PM_RUNTIME is
 +       * coda_fw_callback regardless of whether CONFIG_PM is
         * enabled or whether the device is associated with a PM domain.
         */
        pm_runtime_get_noresume(&pdev->dev);
        pm_runtime_enable(&pdev->dev);
  
        return coda_firmware_request(dev);
+ err_v4l2_register:
+       v4l2_device_unregister(&dev->v4l2_dev);
+       return ret;
  }
  
  static int coda_remove(struct platform_device *pdev)
  {
        struct coda_dev *dev = platform_get_drvdata(pdev);
+       int i;
  
-       video_unregister_device(&dev->vfd[0]);
-       video_unregister_device(&dev->vfd[1]);
+       for (i = 0; i < ARRAY_SIZE(dev->vfd); i++) {
+               if (video_get_drvdata(&dev->vfd[i]))
+                       video_unregister_device(&dev->vfd[i]);
+       }
        if (dev->m2m_dev)
                v4l2_m2m_release(dev->m2m_dev);
        pm_runtime_disable(&pdev->dev);
        return 0;
  }
  
 -#ifdef CONFIG_PM_RUNTIME
 +#ifdef CONFIG_PM
  static int coda_runtime_resume(struct device *dev)
  {
        struct coda_dev *cdev = dev_get_drvdata(dev);
@@@ -81,7 -81,7 +81,7 @@@ static struct fimc_fmt fimc_formats[] 
                .flags          = FMT_FLAGS_M2M_OUT | FMT_HAS_ALPHA,
        }, {
                .name           = "YUV 4:4:4",
-               .mbus_code      = V4L2_MBUS_FMT_YUV10_1X30,
+               .mbus_code      = MEDIA_BUS_FMT_YUV10_1X30,
                .flags          = FMT_FLAGS_WRITEBACK,
        }, {
                .name           = "YUV 4:2:2 packed, YCbYCr",
@@@ -90,7 -90,7 +90,7 @@@
                .color          = FIMC_FMT_YCBYCR422,
                .memplanes      = 1,
                .colplanes      = 1,
-               .mbus_code      = V4L2_MBUS_FMT_YUYV8_2X8,
+               .mbus_code      = MEDIA_BUS_FMT_YUYV8_2X8,
                .flags          = FMT_FLAGS_M2M | FMT_FLAGS_CAM,
        }, {
                .name           = "YUV 4:2:2 packed, CbYCrY",
@@@ -99,7 -99,7 +99,7 @@@
                .color          = FIMC_FMT_CBYCRY422,
                .memplanes      = 1,
                .colplanes      = 1,
-               .mbus_code      = V4L2_MBUS_FMT_UYVY8_2X8,
+               .mbus_code      = MEDIA_BUS_FMT_UYVY8_2X8,
                .flags          = FMT_FLAGS_M2M | FMT_FLAGS_CAM,
        }, {
                .name           = "YUV 4:2:2 packed, CrYCbY",
                .color          = FIMC_FMT_CRYCBY422,
                .memplanes      = 1,
                .colplanes      = 1,
-               .mbus_code      = V4L2_MBUS_FMT_VYUY8_2X8,
+               .mbus_code      = MEDIA_BUS_FMT_VYUY8_2X8,
                .flags          = FMT_FLAGS_M2M | FMT_FLAGS_CAM,
        }, {
                .name           = "YUV 4:2:2 packed, YCrYCb",
                .color          = FIMC_FMT_YCRYCB422,
                .memplanes      = 1,
                .colplanes      = 1,
-               .mbus_code      = V4L2_MBUS_FMT_YVYU8_2X8,
+               .mbus_code      = MEDIA_BUS_FMT_YVYU8_2X8,
                .flags          = FMT_FLAGS_M2M | FMT_FLAGS_CAM,
        }, {
                .name           = "YUV 4:2:2 planar, Y/Cb/Cr",
                .depth          = { 8 },
                .memplanes      = 1,
                .colplanes      = 1,
-               .mbus_code      = V4L2_MBUS_FMT_JPEG_1X8,
+               .mbus_code      = MEDIA_BUS_FMT_JPEG_1X8,
                .flags          = FMT_FLAGS_CAM | FMT_FLAGS_COMPRESSED,
        }, {
                .name           = "S5C73MX interleaved UYVY/JPEG",
                .memplanes      = 2,
                .colplanes      = 1,
                .mdataplanes    = 0x2, /* plane 1 holds frame meta data */
-               .mbus_code      = V4L2_MBUS_FMT_S5C_UYVY_JPEG_1X8,
+               .mbus_code      = MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8,
                .flags          = FMT_FLAGS_CAM | FMT_FLAGS_COMPRESSED,
        },
  };
@@@ -832,7 -832,7 +832,7 @@@ err
        return -ENXIO;
  }
  
 -#if defined(CONFIG_PM_RUNTIME) || defined(CONFIG_PM_SLEEP)
 +#ifdef CONFIG_PM
  static int fimc_m2m_suspend(struct fimc_dev *fimc)
  {
        unsigned long flags;
@@@ -871,7 -871,7 +871,7 @@@ static int fimc_m2m_resume(struct fimc_
  
        return 0;
  }
 -#endif /* CONFIG_PM_RUNTIME || CONFIG_PM_SLEEP */
 +#endif /* CONFIG_PM */
  
  static const struct of_device_id fimc_of_match[];
  
@@@ -1039,7 -1039,7 +1039,7 @@@ err_sclk
        return ret;
  }
  
 -#ifdef CONFIG_PM_RUNTIME
 +#ifdef CONFIG_PM
  static int fimc_runtime_resume(struct device *dev)
  {
        struct fimc_dev *fimc = dev_get_drvdata(dev);
@@@ -48,7 -48,7 +48,7 @@@ static const struct fimc_fmt fimc_lite_
                .depth          = { 16 },
                .color          = FIMC_FMT_YCBYCR422,
                .memplanes      = 1,
-               .mbus_code      = V4L2_MBUS_FMT_YUYV8_2X8,
+               .mbus_code      = MEDIA_BUS_FMT_YUYV8_2X8,
                .flags          = FMT_FLAGS_YUV,
        }, {
                .name           = "YUV 4:2:2 packed, CbYCrY",
@@@ -57,7 -57,7 +57,7 @@@
                .depth          = { 16 },
                .color          = FIMC_FMT_CBYCRY422,
                .memplanes      = 1,
-               .mbus_code      = V4L2_MBUS_FMT_UYVY8_2X8,
+               .mbus_code      = MEDIA_BUS_FMT_UYVY8_2X8,
                .flags          = FMT_FLAGS_YUV,
        }, {
                .name           = "YUV 4:2:2 packed, CrYCbY",
@@@ -66,7 -66,7 +66,7 @@@
                .depth          = { 16 },
                .color          = FIMC_FMT_CRYCBY422,
                .memplanes      = 1,
-               .mbus_code      = V4L2_MBUS_FMT_VYUY8_2X8,
+               .mbus_code      = MEDIA_BUS_FMT_VYUY8_2X8,
                .flags          = FMT_FLAGS_YUV,
        }, {
                .name           = "YUV 4:2:2 packed, YCrYCb",
@@@ -75,7 -75,7 +75,7 @@@
                .depth          = { 16 },
                .color          = FIMC_FMT_YCRYCB422,
                .memplanes      = 1,
-               .mbus_code      = V4L2_MBUS_FMT_YVYU8_2X8,
+               .mbus_code      = MEDIA_BUS_FMT_YVYU8_2X8,
                .flags          = FMT_FLAGS_YUV,
        }, {
                .name           = "RAW8 (GRBG)",
@@@ -84,7 -84,7 +84,7 @@@
                .depth          = { 8 },
                .color          = FIMC_FMT_RAW8,
                .memplanes      = 1,
-               .mbus_code      = V4L2_MBUS_FMT_SGRBG8_1X8,
+               .mbus_code      = MEDIA_BUS_FMT_SGRBG8_1X8,
                .flags          = FMT_FLAGS_RAW_BAYER,
        }, {
                .name           = "RAW10 (GRBG)",
@@@ -93,7 -93,7 +93,7 @@@
                .depth          = { 16 },
                .color          = FIMC_FMT_RAW10,
                .memplanes      = 1,
-               .mbus_code      = V4L2_MBUS_FMT_SGRBG10_1X10,
+               .mbus_code      = MEDIA_BUS_FMT_SGRBG10_1X10,
                .flags          = FMT_FLAGS_RAW_BAYER,
        }, {
                .name           = "RAW12 (GRBG)",
                .depth          = { 16 },
                .color          = FIMC_FMT_RAW12,
                .memplanes      = 1,
-               .mbus_code      = V4L2_MBUS_FMT_SGRBG12_1X12,
+               .mbus_code      = MEDIA_BUS_FMT_SGRBG12_1X12,
                .flags          = FMT_FLAGS_RAW_BAYER,
        },
  };
@@@ -1588,7 -1588,7 +1588,7 @@@ err_clk_put
        return ret;
  }
  
 -#ifdef CONFIG_PM_RUNTIME
 +#ifdef CONFIG_PM
  static int fimc_lite_runtime_resume(struct device *dev)
  {
        struct fimc_lite *fimc = dev_get_drvdata(dev);
@@@ -238,34 -238,34 +238,34 @@@ struct csis_state 
   */
  struct csis_pix_format {
        unsigned int pix_width_alignment;
-       enum v4l2_mbus_pixelcode code;
+       u32 code;
        u32 fmt_reg;
        u8 data_alignment;
  };
  
  static const struct csis_pix_format s5pcsis_formats[] = {
        {
-               .code = V4L2_MBUS_FMT_VYUY8_2X8,
+               .code = MEDIA_BUS_FMT_VYUY8_2X8,
                .fmt_reg = S5PCSIS_CFG_FMT_YCBCR422_8BIT,
                .data_alignment = 32,
        }, {
-               .code = V4L2_MBUS_FMT_JPEG_1X8,
+               .code = MEDIA_BUS_FMT_JPEG_1X8,
                .fmt_reg = S5PCSIS_CFG_FMT_USER(1),
                .data_alignment = 32,
        }, {
-               .code = V4L2_MBUS_FMT_S5C_UYVY_JPEG_1X8,
+               .code = MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8,
                .fmt_reg = S5PCSIS_CFG_FMT_USER(1),
                .data_alignment = 32,
        }, {
-               .code = V4L2_MBUS_FMT_SGRBG8_1X8,
+               .code = MEDIA_BUS_FMT_SGRBG8_1X8,
                .fmt_reg = S5PCSIS_CFG_FMT_RAW8,
                .data_alignment = 24,
        }, {
-               .code = V4L2_MBUS_FMT_SGRBG10_1X10,
+               .code = MEDIA_BUS_FMT_SGRBG10_1X10,
                .fmt_reg = S5PCSIS_CFG_FMT_RAW10,
                .data_alignment = 24,
        }, {
-               .code = V4L2_MBUS_FMT_SGRBG12_1X12,
+               .code = MEDIA_BUS_FMT_SGRBG12_1X12,
                .fmt_reg = S5PCSIS_CFG_FMT_RAW12,
                .data_alignment = 24,
        }
@@@ -978,7 -978,7 +978,7 @@@ static int s5pcsis_resume(struct devic
  }
  #endif
  
 -#ifdef CONFIG_PM_RUNTIME
 +#ifdef CONFIG_PM
  static int s5pcsis_runtime_suspend(struct device *dev)
  {
        return s5pcsis_pm_suspend(dev, true);
@@@ -1001,13 -1001,8 +1001,8 @@@ static int s5p_jpeg_querycap(struct fil
                        sizeof(cap->card));
        }
        cap->bus_info[0] = 0;
-       /*
-        * This is only a mem-to-mem video device. The capture and output
-        * device capability flags are left only for backward compatibility
-        * and are scheduled for removal.
-        */
-       cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M |
-                           V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT;
+       cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M;
+       cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
        return 0;
  }
  
@@@ -2632,7 -2627,7 +2627,7 @@@ static int s5p_jpeg_remove(struct platf
        return 0;
  }
  
 -#if defined(CONFIG_PM_RUNTIME) || defined(CONFIG_PM_SLEEP)
 +#ifdef CONFIG_PM
  static int s5p_jpeg_runtime_suspend(struct device *dev)
  {
        struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
@@@ -2682,7 -2677,7 +2677,7 @@@ static int s5p_jpeg_runtime_resume(stru
  
        return 0;
  }
 -#endif /* CONFIG_PM_RUNTIME || CONFIG_PM_SLEEP */
 +#endif /* CONFIG_PM */
  
  #ifdef CONFIG_PM_SLEEP
  static int s5p_jpeg_suspend(struct device *dev)
@@@ -159,6 -159,10 +159,10 @@@ static void s5p_mfc_watchdog_worker(str
        }
        clear_bit(0, &dev->hw_lock);
        spin_unlock_irqrestore(&dev->irqlock, flags);
+       /* De-init MFC */
+       s5p_mfc_deinit_hw(dev);
        /* Double check if there is at least one instance running.
         * If no instance is in memory than no firmware should be present */
        if (dev->num_inst > 0) {
@@@ -220,11 -224,14 +224,14 @@@ static void s5p_mfc_handle_frame_copy_t
        size_t dec_y_addr;
        unsigned int frame_type;
  
-       dec_y_addr = s5p_mfc_hw_call(dev->mfc_ops, get_dec_y_adr, dev);
+       /* Make sure we actually have a new frame before continuing. */
        frame_type = s5p_mfc_hw_call(dev->mfc_ops, get_dec_frame_type, dev);
+       if (frame_type == S5P_FIMV_DECODE_FRAME_SKIPPED)
+               return;
+       dec_y_addr = s5p_mfc_hw_call(dev->mfc_ops, get_dec_y_adr, dev);
  
        /* Copy timestamp / timecode from decoded src to dst and set
-          appropriate flags */
+          appropriate flags. */
        src_buf = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
        list_for_each_entry(dst_buf, &ctx->dst_queue, list) {
                if (vb2_dma_contig_plane_dma_addr(dst_buf->b, 0) == dec_y_addr) {
                                dst_buf->b->v4l2_buf.flags |=
                                                V4L2_BUF_FLAG_BFRAME;
                                break;
+                       default:
+                               /* Don't know how to handle
+                                  S5P_FIMV_DECODE_FRAME_OTHER_FRAME. */
+                               mfc_debug(2, "Unexpected frame type: %d\n",
+                                               frame_type);
                        }
                        break;
                }
@@@ -334,8 -346,7 +346,7 @@@ static void s5p_mfc_handle_frame(struc
                ctx->state = MFCINST_RES_CHANGE_INIT;
                s5p_mfc_hw_call_void(dev->mfc_ops, clear_int_flags, dev);
                wake_up_ctx(ctx, reason, err);
-               if (test_and_clear_bit(0, &dev->hw_lock) == 0)
-                       BUG();
+               WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0);
                s5p_mfc_clock_off();
                s5p_mfc_hw_call_void(dev->mfc_ops, try_run, dev);
                return;
@@@ -407,8 -418,7 +418,7 @@@ leave_handle_frame
                clear_work_bit(ctx);
        s5p_mfc_hw_call_void(dev->mfc_ops, clear_int_flags, dev);
        wake_up_ctx(ctx, reason, err);
-       if (test_and_clear_bit(0, &dev->hw_lock) == 0)
-               BUG();
+       WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0);
        s5p_mfc_clock_off();
        /* if suspending, wake up device and do not try_run again*/
        if (test_bit(0, &dev->enter_suspend))
@@@ -455,8 -465,7 +465,7 @@@ static void s5p_mfc_handle_error(struc
                        break;
                }
        }
-       if (test_and_clear_bit(0, &dev->hw_lock) == 0)
-               BUG();
+       WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0);
        s5p_mfc_hw_call_void(dev->mfc_ops, clear_int_flags, dev);
        s5p_mfc_clock_off();
        wake_up_dev(dev, reason, err);
@@@ -510,8 -519,7 +519,7 @@@ static void s5p_mfc_handle_seq_done(str
        }
        s5p_mfc_hw_call_void(dev->mfc_ops, clear_int_flags, dev);
        clear_work_bit(ctx);
-       if (test_and_clear_bit(0, &dev->hw_lock) == 0)
-               BUG();
+       WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0);
        s5p_mfc_clock_off();
        s5p_mfc_hw_call_void(dev->mfc_ops, try_run, dev);
        wake_up_ctx(ctx, reason, err);
@@@ -549,16 -557,14 +557,14 @@@ static void s5p_mfc_handle_init_buffers
                } else {
                        ctx->dpb_flush_flag = 0;
                }
-               if (test_and_clear_bit(0, &dev->hw_lock) == 0)
-                       BUG();
+               WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0);
  
                s5p_mfc_clock_off();
  
                wake_up(&ctx->queue);
                s5p_mfc_hw_call_void(dev->mfc_ops, try_run, dev);
        } else {
-               if (test_and_clear_bit(0, &dev->hw_lock) == 0)
-                       BUG();
+               WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0);
  
                s5p_mfc_clock_off();
  
@@@ -635,8 -641,7 +641,7 @@@ static irqreturn_t s5p_mfc_irq(int irq
                                mfc_err("post_frame_start() failed\n");
                        s5p_mfc_hw_call_void(dev->mfc_ops, clear_int_flags, dev);
                        wake_up_ctx(ctx, reason, err);
-                       if (test_and_clear_bit(0, &dev->hw_lock) == 0)
-                               BUG();
+                       WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0);
                        s5p_mfc_clock_off();
                        s5p_mfc_hw_call_void(dev->mfc_ops, try_run, dev);
                } else {
@@@ -815,7 -820,7 +820,7 @@@ static int s5p_mfc_open(struct file *fi
                ret = -ENOENT;
                goto err_queue_init;
        }
-       q->mem_ops = (struct vb2_mem_ops *)&vb2_dma_contig_memops;
+       q->mem_ops = &vb2_dma_contig_memops;
        q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
        ret = vb2_queue_init(q);
        if (ret) {
                ret = -ENOENT;
                goto err_queue_init;
        }
-       q->mem_ops = (struct vb2_mem_ops *)&vb2_dma_contig_memops;
+       q->mem_ops = &vb2_dma_contig_memops;
        q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
        ret = vb2_queue_init(q);
        if (ret) {
@@@ -1284,11 -1289,17 +1289,17 @@@ static int s5p_mfc_suspend(struct devic
                        m_dev->int_cond, msecs_to_jiffies(MFC_INT_TIMEOUT));
                if (ret == 0) {
                        mfc_err("Waiting for hardware to finish timed out\n");
+                       clear_bit(0, &m_dev->enter_suspend);
                        return -EIO;
                }
        }
  
-       return s5p_mfc_sleep(m_dev);
+       ret = s5p_mfc_sleep(m_dev);
+       if (ret) {
+               clear_bit(0, &m_dev->enter_suspend);
+               clear_bit(0, &m_dev->hw_lock);
+       }
+       return ret;
  }
  
  static int s5p_mfc_resume(struct device *dev)
  }
  #endif
  
 -#ifdef CONFIG_PM_RUNTIME
 +#ifdef CONFIG_PM
  static int s5p_mfc_runtime_suspend(struct device *dev)
  {
        struct platform_device *pdev = to_platform_device(dev);
@@@ -558,27 -558,30 +558,30 @@@ static void s2255_fwchunk_complete(stru
  
  }
  
- static int s2255_got_frame(struct s2255_vc *vc, int jpgsize)
+ static void s2255_got_frame(struct s2255_vc *vc, int jpgsize)
  {
        struct s2255_buffer *buf;
        struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
        unsigned long flags = 0;
-       int rc = 0;
        spin_lock_irqsave(&vc->qlock, flags);
        if (list_empty(&vc->buf_list)) {
                dprintk(dev, 1, "No active queue to serve\n");
-               rc = -1;
-               goto unlock;
+               spin_unlock_irqrestore(&vc->qlock, flags);
+               return;
        }
        buf = list_entry(vc->buf_list.next,
                         struct s2255_buffer, list);
        list_del(&buf->list);
        v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
+       buf->vb.v4l2_buf.field = vc->field;
+       buf->vb.v4l2_buf.sequence = vc->frame_count;
+       spin_unlock_irqrestore(&vc->qlock, flags);
        s2255_fillbuff(vc, buf, jpgsize);
+       /* tell v4l buffer was filled */
+       vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE);
        dprintk(dev, 2, "%s: [buf] [%p]\n", __func__, buf);
- unlock:
-       spin_unlock_irqrestore(&vc->qlock, flags);
-       return rc;
  }
  
  static const struct s2255_fmt *format_by_fourcc(int fourcc)
@@@ -632,7 -635,7 +635,7 @@@ static void s2255_fillbuff(struct s2255
                        break;
                case V4L2_PIX_FMT_JPEG:
                case V4L2_PIX_FMT_MJPEG:
 -                      buf->vb.v4l2_buf.length = jpgsize;
 +                      vb2_set_plane_payload(&buf->vb, 0, jpgsize);
                        memcpy(vbuf, tmpbuf, jpgsize);
                        break;
                case V4L2_PIX_FMT_YUV422P:
        }
        dprintk(dev, 2, "s2255fill at : Buffer 0x%08lx size= %d\n",
                (unsigned long)vbuf, pos);
-       /* tell v4l buffer was filled */
-       buf->vb.v4l2_buf.field = vc->field;
-       buf->vb.v4l2_buf.sequence = vc->frame_count;
-       v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
-       vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE);
  }
  
  
@@@ -1976,8 -1974,7 +1974,7 @@@ static int s2255_release_sys_buffers(st
  {
        unsigned long i;
        for (i = 0; i < SYS_FRAMES; i++) {
-               if (vc->buffer.frame[i].lpvbits)
-                       vfree(vc->buffer.frame[i].lpvbits);
+               vfree(vc->buffer.frame[i].lpvbits);
                vc->buffer.frame[i].lpvbits = NULL;
        }
        return 0;
@@@ -125,7 -125,6 +125,7 @@@ header-y += filter.
  header-y += firewire-cdev.h
  header-y += firewire-constants.h
  header-y += flat.h
 +header-y += fou.h
  header-y += fs.h
  header-y += fsl_hypervisor.h
  header-y += fuse.h
@@@ -142,7 -141,6 +142,7 @@@ header-y += hid.
  header-y += hiddev.h
  header-y += hidraw.h
  header-y += hpet.h
 +header-y += hsr_netlink.h
  header-y += hyperv.h
  header-y += hysdn_if.h
  header-y += i2c-dev.h
@@@ -243,6 -241,7 +243,7 @@@ header-y += map_to_7segment.
  header-y += matroxfb.h
  header-y += mdio.h
  header-y += media.h
+ header-y += media-bus-format.h
  header-y += mei.h
  header-y += memfd.h
  header-y += mempolicy.h
@@@ -253,7 -252,6 +254,7 @@@ header-y += mii.
  header-y += minix_fs.h
  header-y += mman.h
  header-y += mmtimer.h
 +header-y += mpls.h
  header-y += mqueue.h
  header-y += mroute.h
  header-y += mroute6.h
@@@ -427,7 -425,6 +428,7 @@@ header-y += virtio_net.
  header-y += virtio_pci.h
  header-y += virtio_ring.h
  header-y += virtio_rng.h
 +header-y += vm_sockets.h
  header-y += vt.h
  header-y += wait.h
  header-y += wanrouter.h