Backmerge tag 'v5.17-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds...
authorDave Airlie <airlied@redhat.com>
Mon, 14 Feb 2022 00:52:27 +0000 (10:52 +1000)
committerDave Airlie <airlied@redhat.com>
Mon, 14 Feb 2022 00:52:27 +0000 (10:52 +1000)
Daniel asked for this for some intel deps, so let's do it now.

Signed-off-by: Dave Airlie <airlied@redhat.com>
14 files changed:
1  2 
Documentation/gpu/todo.rst
MAINTAINERS
drivers/gpu/drm/bridge/nwl-dsi.c
drivers/gpu/drm/drm_privacy_screen.c
drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
drivers/gpu/drm/i915/i915_gpu_error.c
drivers/gpu/drm/panel/panel-simple.c
drivers/gpu/drm/vc4/vc4_hdmi.c
drivers/gpu/drm/vc4/vc4_hdmi.h
drivers/misc/fastrpc.c
drivers/platform/x86/thinkpad_acpi.c
drivers/video/fbdev/core/fbmem.c
include/linux/fb.h

@@@ -222,7 -222,7 +222,7 @@@ Convert drivers to use drm_fbdev_generi
  Most drivers can use drm_fbdev_generic_setup(). Driver have to implement
  atomic modesetting and GEM vmap support. Historically, generic fbdev emulation
  expected the framebuffer in system memory or system-like memory. By employing
 -struct dma_buf_map, drivers with frambuffers in I/O memory can be supported
 +struct iosys_map, drivers with frambuffers in I/O memory can be supported
  as well.
  
  Contact: Maintainer of the driver you plan to convert
@@@ -234,7 -234,7 +234,7 @@@ Reimplement functions in drm_fbdev_fb_o
  
  A number of callback functions in drm_fbdev_fb_ops could benefit from
  being rewritten without dependencies on the fbdev module. Some of the
 -helpers could further benefit from using struct dma_buf_map instead of
 +helpers could further benefit from using struct iosys_map instead of
  raw pointers.
  
  Contact: Thomas Zimmermann <tzimmermann@suse.de>, Daniel Vetter
@@@ -300,30 -300,6 +300,6 @@@ Contact: Daniel Vetter, Noralf Tronne
  
  Level: Advanced
  
- Garbage collect fbdev scrolling acceleration
- --------------------------------------------
- Scroll acceleration has been disabled in fbcon. Now it works as the old
- SCROLL_REDRAW mode. A ton of code was removed in fbcon.c and the hook bmove was
- removed from fbcon_ops.
- Remaining tasks:
- - a bunch of the hooks in fbcon_ops could be removed or simplified by calling
-   directly instead of the function table (with a switch on p->rotate)
- - fb_copyarea is unused after this, and can be deleted from all drivers
- - after that, fb_copyarea can be deleted from fb_ops in include/linux/fb.h as
-   well as cfb_copyarea
- Note that not all acceleration code can be deleted, since clearing and cursor
- support is still accelerated, which might be good candidates for further
- deletion projects.
- Contact: Daniel Vetter
- Level: Intermediate
  idr_init_base()
  ---------------
  
@@@ -434,19 -410,19 +410,19 @@@ Contact: Emil Velikov, respective drive
  
  Level: Intermediate
  
 -Use struct dma_buf_map throughout codebase
 -------------------------------------------
 +Use struct iosys_map throughout codebase
 +----------------------------------------
  
 -Pointers to shared device memory are stored in struct dma_buf_map. Each
 +Pointers to shared device memory are stored in struct iosys_map. Each
  instance knows whether it refers to system or I/O memory. Most of the DRM-wide
 -interface have been converted to use struct dma_buf_map, but implementations
 +interface have been converted to use struct iosys_map, but implementations
  often still use raw pointers.
  
 -The task is to use struct dma_buf_map where it makes sense.
 +The task is to use struct iosys_map where it makes sense.
  
 -* Memory managers should use struct dma_buf_map for dma-buf-imported buffers.
 -* TTM might benefit from using struct dma_buf_map internally.
 -* Framebuffer copying and blitting helpers should operate on struct dma_buf_map.
 +* Memory managers should use struct iosys_map for dma-buf-imported buffers.
 +* TTM might benefit from using struct iosys_map internally.
 +* Framebuffer copying and blitting helpers should operate on struct iosys_map.
  
  Contact: Thomas Zimmermann <tzimmermann@suse.de>, Christian König, Daniel Vetter
  
@@@ -467,21 -443,6 +443,21 @@@ Contact: Thomas Zimmermann <tzimmermann
  
  Level: Intermediate
  
 +Request memory regions in all drivers
 +-------------------------------------
 +
 +Go through all drivers and add code to request the memory regions that the
 +driver uses. This requires adding calls to request_mem_region(),
 +pci_request_region() or similar functions. Use helpers for managed cleanup
 +where possible.
 +
 +Drivers are pretty bad at doing this and there used to be conflicts among
 +DRM and fbdev drivers. Still, it's the correct thing to do.
 +
 +Contact: Thomas Zimmermann <tzimmermann@suse.de>
 +
 +Level: Starter
 +
  
  Core refactorings
  =================
diff --combined MAINTAINERS
@@@ -1620,6 -1620,7 +1620,7 @@@ M:      Olof Johansson <olof@lixom.net
  M:    soc@kernel.org
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  S:    Maintained
+ C:    irc://irc.libera.chat/armlinux
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git
  F:    arch/arm/boot/dts/Makefile
  F:    arch/arm64/boot/dts/Makefile
  ARM SUB-ARCHITECTURES
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  S:    Maintained
+ C:    irc://irc.libera.chat/armlinux
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git
  F:    arch/arm/mach-*/
  F:    arch/arm/plat-*/
@@@ -1780,6 -1782,7 +1782,7 @@@ F:      drivers/irqchip/irq-apple-aic.
  F:    drivers/mailbox/apple-mailbox.c
  F:    drivers/pinctrl/pinctrl-apple-gpio.c
  F:    drivers/soc/apple/*
+ F:    drivers/watchdog/apple_wdt.c
  F:    include/dt-bindings/interrupt-controller/apple-aic.h
  F:    include/dt-bindings/pinctrl/apple.h
  F:    include/linux/apple-mailbox.h
@@@ -2570,10 -2573,13 +2573,13 @@@ N:   rockchi
  
  ARM/SAMSUNG S3C, S5P AND EXYNOS ARM ARCHITECTURES
  M:    Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+ R:    Alim Akhtar <alim.akhtar@samsung.com>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  L:    linux-samsung-soc@vger.kernel.org
  S:    Maintained
+ C:    irc://irc.libera.chat/linux-exynos
  Q:    https://patchwork.kernel.org/project/linux-samsung-soc/list/
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git
  F:    Documentation/arm/samsung/
  F:    Documentation/devicetree/bindings/arm/samsung/
  F:    Documentation/devicetree/bindings/power/pd-samsung.yaml
@@@ -4157,9 -4163,8 +4163,8 @@@ N:      csk
  K:    csky
  
  CA8210 IEEE-802.15.4 RADIO DRIVER
- M:    Harry Morris <h.morris@cascoda.com>
  L:    linux-wpan@vger.kernel.org
- S:    Maintained
+ S:    Orphan
  W:    https://github.com/Cascoda/ca8210-linux.git
  F:    Documentation/devicetree/bindings/net/ieee802154/ca8210.txt
  F:    drivers/net/ieee802154/ca8210.c
@@@ -5734,7 -5739,7 +5739,7 @@@ T:      git git://anongit.freedesktop.org/dr
  F:    Documentation/driver-api/dma-buf.rst
  F:    drivers/dma-buf/
  F:    include/linux/*fence.h
 -F:    include/linux/dma-buf*
 +F:    include/linux/dma-buf.h
  F:    include/linux/dma-resv.h
  K:    \bdma_(?:buf|fence|resv)\b
  
@@@ -5773,7 -5778,7 +5778,7 @@@ F:      tools/testing/selftests/dma
  
  DMA-BUF HEAPS FRAMEWORK
  M:    Sumit Semwal <sumit.semwal@linaro.org>
- R:    Benjamin Gaignard <benjamin.gaignard@linaro.org>
+ R:    Benjamin Gaignard <benjamin.gaignard@collabora.com>
  R:    Liam Mark <lmark@codeaurora.org>
  R:    Laura Abbott <labbott@redhat.com>
  R:    Brian Starkey <Brian.Starkey@arm.com>
@@@ -6503,7 -6508,7 +6508,7 @@@ F:      Documentation/devicetree/bindings/di
  F:    drivers/gpu/drm/rockchip/
  
  DRM DRIVERS FOR STI
- M:    Benjamin Gaignard <benjamin.gaignard@linaro.org>
+ M:    Alain Volmat <alain.volmat@foss.st.com>
  L:    dri-devel@lists.freedesktop.org
  S:    Maintained
  T:    git git://anongit.freedesktop.org/drm/drm-misc
@@@ -6512,8 -6517,8 +6517,8 @@@ F:      drivers/gpu/drm/st
  
  DRM DRIVERS FOR STM
  M:    Yannick Fertre <yannick.fertre@foss.st.com>
+ M:    Raphael Gallais-Pou <raphael.gallais-pou@foss.st.com>
  M:    Philippe Cornu <philippe.cornu@foss.st.com>
- M:    Benjamin Gaignard <benjamin.gaignard@linaro.org>
  L:    dri-devel@lists.freedesktop.org
  S:    Maintained
  T:    git git://anongit.freedesktop.org/drm/drm-misc
@@@ -7576,6 -7581,12 +7581,12 @@@ S:    Maintaine
  W:    http://floatingpoint.sourceforge.net/emulator/index.html
  F:    arch/x86/math-emu/
  
+ FRAMEBUFFER CORE
+ M:    Daniel Vetter <daniel@ffwll.ch>
+ F:    drivers/video/fbdev/core/
+ S:    Odd Fixes
+ T:    git git://anongit.freedesktop.org/drm/drm-misc
  FRAMEBUFFER LAYER
  M:    Helge Deller <deller@gmx.de>
  L:    linux-fbdev@vger.kernel.org
@@@ -10050,13 -10061,6 +10061,13 @@@ F: include/linux/iova.
  F:    include/linux/of_iommu.h
  F:    include/uapi/linux/iommu.h
  
 +IOSYS-MAP HELPERS
 +M:    Thomas Zimmermann <tzimmermann@suse.de>
 +L:    dri-devel@lists.freedesktop.org
 +S:    Maintained
 +T:    git git://anongit.freedesktop.org/drm/drm-misc
 +F:    include/linux/iosys-map.h
 +
  IO_URING
  M:    Jens Axboe <axboe@kernel.dk>
  R:    Pavel Begunkov <asml.silence@gmail.com>
@@@ -10887,6 -10891,12 +10898,12 @@@ T: git git://git.kernel.org/pub/scm/lin
  F:    drivers/ata/pata_arasan_cf.c
  F:    include/linux/pata_arasan_cf_data.h
  
+ LIBATA PATA DRIVERS
+ R:    Sergey Shtylyov <s.shtylyov@omp.ru>
+ L:    linux-ide@vger.kernel.org
+ F:    drivers/ata/ata_*.c
+ F:    drivers/ata/pata_*.c
  LIBATA PATA FARADAY FTIDE010 AND GEMINI SATA BRIDGE DRIVERS
  M:    Linus Walleij <linus.walleij@linaro.org>
  L:    linux-ide@vger.kernel.org
@@@ -12407,7 -12417,7 +12424,7 @@@ F:   include/uapi/linux/membarrier.
  F:    kernel/sched/membarrier.c
  
  MEMBLOCK
- M:    Mike Rapoport <rppt@linux.ibm.com>
+ M:    Mike Rapoport <rppt@kernel.org>
  L:    linux-mm@kvack.org
  S:    Maintained
  F:    Documentation/core-api/boot-time-mm.rst
@@@ -13305,8 -13315,8 +13322,8 @@@ W:   http://www.iptables.org
  W:    http://www.nftables.org/
  Q:    http://patchwork.ozlabs.org/project/netfilter-devel/list/
  C:    irc://irc.libera.chat/netfilter
- T:    git git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git
- T:    git git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf.git
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next.git
  F:    include/linux/netfilter*
  F:    include/linux/netfilter/
  F:    include/net/netfilter/
@@@ -13573,7 -13583,7 +13590,7 @@@ F:   tools/testing/selftests/nci
  
  NFS, SUNRPC, AND LOCKD CLIENTS
  M:    Trond Myklebust <trond.myklebust@hammerspace.com>
- M:    Anna Schumaker <anna.schumaker@netapp.com>
+ M:    Anna Schumaker <anna@kernel.org>
  L:    linux-nfs@vger.kernel.org
  S:    Maintained
  W:    http://client.linux-nfs.org
@@@ -14391,6 -14401,7 +14408,7 @@@ M:   Rob Herring <robh+dt@kernel.org
  M:    Frank Rowand <frowand.list@gmail.com>
  L:    devicetree@vger.kernel.org
  S:    Maintained
+ C:    irc://irc.libera.chat/devicetree
  W:    http://www.devicetree.org/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git
  F:    Documentation/ABI/testing/sysfs-firmware-ofw
@@@ -14402,6 -14413,7 +14420,7 @@@ OPEN FIRMWARE AND FLATTENED DEVICE TRE
  M:    Rob Herring <robh+dt@kernel.org>
  L:    devicetree@vger.kernel.org
  S:    Maintained
+ C:    irc://irc.libera.chat/devicetree
  Q:    http://patchwork.ozlabs.org/project/devicetree-bindings/list/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git
  F:    Documentation/devicetree/
@@@ -15292,9 -15304,11 +15311,11 @@@ PIN CONTROLLER - SAMSUN
  M:    Tomasz Figa <tomasz.figa@gmail.com>
  M:    Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
  M:    Sylwester Nawrocki <s.nawrocki@samsung.com>
+ R:    Alim Akhtar <alim.akhtar@samsung.com>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  L:    linux-samsung-soc@vger.kernel.org
  S:    Maintained
+ C:    irc://irc.libera.chat/linux-exynos
  Q:    https://patchwork.kernel.org/project/linux-samsung-soc/list/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung.git
  F:    Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
@@@ -16476,6 -16490,14 +16497,14 @@@ F: Documentation/devicetree/bindings/i2
  F:    drivers/i2c/busses/i2c-rcar.c
  F:    drivers/i2c/busses/i2c-sh_mobile.c
  
+ RENESAS R-CAR SATA DRIVER
+ R:    Sergey Shtylyov <s.shtylyov@omp.ru>
+ S:    Supported
+ L:    linux-ide@vger.kernel.org
+ L:    linux-renesas-soc@vger.kernel.org
+ F:    Documentation/devicetree/bindings/ata/renesas,rcar-sata.yaml
+ F:    drivers/ata/sata_rcar.c
  RENESAS R-CAR THERMAL DRIVERS
  M:    Niklas Söderlund <niklas.soderlund@ragnatech.se>
  L:    linux-renesas-soc@vger.kernel.org
@@@ -16811,8 -16833,8 +16840,8 @@@ F:   drivers/video/fbdev/savage
  S390
  M:    Heiko Carstens <hca@linux.ibm.com>
  M:    Vasily Gorbik <gor@linux.ibm.com>
- M:    Christian Borntraeger <borntraeger@linux.ibm.com>
- R:    Alexander Gordeev <agordeev@linux.ibm.com>
+ M:    Alexander Gordeev <agordeev@linux.ibm.com>
+ R:    Christian Borntraeger <borntraeger@linux.ibm.com>
  R:    Sven Schnelle <svens@linux.ibm.com>
  L:    linux-s390@vger.kernel.org
  S:    Supported
@@@ -17083,6 -17105,7 +17112,7 @@@ SAMSUNG SOC CLOCK DRIVER
  M:    Sylwester Nawrocki <s.nawrocki@samsung.com>
  M:    Tomasz Figa <tomasz.figa@gmail.com>
  M:    Chanwoo Choi <cw00.choi@samsung.com>
+ R:    Alim Akhtar <alim.akhtar@samsung.com>
  L:    linux-samsung-soc@vger.kernel.org
  S:    Supported
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/snawrocki/clk.git
@@@ -17719,6 -17742,21 +17749,21 @@@ S: Maintaine
  W:    http://www.winischhofer.at/linuxsisusbvga.shtml
  F:    drivers/usb/misc/sisusbvga/
  
+ SL28 CPLD MFD DRIVER
+ M:    Michael Walle <michael@walle.cc>
+ S:    Maintained
+ F:    Documentation/devicetree/bindings/gpio/kontron,sl28cpld-gpio.yaml
+ F:    Documentation/devicetree/bindings/hwmon/kontron,sl28cpld-hwmon.yaml
+ F:    Documentation/devicetree/bindings/interrupt-controller/kontron,sl28cpld-intc.yaml
+ F:    Documentation/devicetree/bindings/mfd/kontron,sl28cpld.yaml
+ F:    Documentation/devicetree/bindings/pwm/kontron,sl28cpld-pwm.yaml
+ F:    Documentation/devicetree/bindings/watchdog/kontron,sl28cpld-wdt.yaml
+ F:    drivers/gpio/gpio-sl28cpld.c
+ F:    drivers/hwmon/sl28cpld-hwmon.c
+ F:    drivers/irqchip/irq-sl28cpld.c
+ F:    drivers/pwm/pwm-sl28cpld.c
+ F:    drivers/watchdog/sl28cpld_wdt.c
  SLAB ALLOCATOR
  M:    Christoph Lameter <cl@linux.com>
  M:    Pekka Enberg <penberg@kernel.org>
@@@ -18435,7 -18473,7 +18480,7 @@@ F:   Documentation/devicetree/bindings/so
  F:    sound/soc/sti/
  
  STI CEC DRIVER
- M:    Benjamin Gaignard <benjamin.gaignard@linaro.org>
+ M:    Alain Volmat <alain.volmat@foss.st.com>
  S:    Maintained
  F:    Documentation/devicetree/bindings/media/stih-cec.txt
  F:    drivers/media/cec/platform/sti/
@@@ -19589,6 -19627,14 +19634,14 @@@ F: Documentation/trace/timerlat-tracer.
  F:    Documentation/trace/hwlat_detector.rst
  F:    arch/*/kernel/trace.c
  
+ Real-time Linux Analysis (RTLA) tools
+ M:    Daniel Bristot de Oliveira <bristot@kernel.org>
+ M:    Steven Rostedt <rostedt@goodmis.org>
+ L:    linux-trace-devel@vger.kernel.org
+ S:    Maintained
+ F:    Documentation/tools/rtla/
+ F:    tools/tracing/rtla/
  TRADITIONAL CHINESE DOCUMENTATION
  M:    Hu Haowen <src.res@email.cn>
  L:    linux-doc-tw-discuss@lists.sourceforge.net
@@@ -7,6 -7,7 +7,7 @@@
   */
  
  #include <linux/bitfield.h>
+ #include <linux/bits.h>
  #include <linux/clk.h>
  #include <linux/irq.h>
  #include <linux/math64.h>
@@@ -65,6 -66,7 +66,6 @@@ struct nwl_dsi_transfer 
  struct nwl_dsi {
        struct drm_bridge bridge;
        struct mipi_dsi_host dsi_host;
 -      struct drm_bridge *panel_bridge;
        struct device *dev;
        struct phy *phy;
        union phy_configure_opts phy_cfg;
@@@ -195,12 -197,9 +196,9 @@@ static u32 ps2bc(struct nwl_dsi *dsi, u
  /*
   * ui2bc - UI time periods to byte clock cycles
   */
- static u32 ui2bc(struct nwl_dsi *dsi, unsigned long long ui)
+ static u32 ui2bc(unsigned int ui)
  {
-       u32 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
-       return DIV64_U64_ROUND_UP(ui * dsi->lanes,
-                                 dsi->mode.clock * 1000 * bpp);
+       return DIV_ROUND_UP(ui, BITS_PER_BYTE);
  }
  
  /*
@@@ -231,12 -230,12 +229,12 @@@ static int nwl_dsi_config_host(struct n
        }
  
        /* values in byte clock cycles */
-       cycles = ui2bc(dsi, cfg->clk_pre);
+       cycles = ui2bc(cfg->clk_pre);
        DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_pre: 0x%x\n", cycles);
        nwl_dsi_write(dsi, NWL_DSI_CFG_T_PRE, cycles);
        cycles = ps2bc(dsi, cfg->lpx + cfg->clk_prepare + cfg->clk_zero);
        DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_tx_gap (pre): 0x%x\n", cycles);
-       cycles += ui2bc(dsi, cfg->clk_pre);
+       cycles += ui2bc(cfg->clk_pre);
        DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_post: 0x%x\n", cycles);
        nwl_dsi_write(dsi, NWL_DSI_CFG_T_POST, cycles);
        cycles = ps2bc(dsi, cfg->hs_exit);
@@@ -923,11 -922,13 +921,11 @@@ static int nwl_dsi_bridge_attach(struc
                if (IS_ERR(panel_bridge))
                        return PTR_ERR(panel_bridge);
        }
 -      dsi->panel_bridge = panel_bridge;
  
 -      if (!dsi->panel_bridge)
 +      if (!panel_bridge)
                return -EPROBE_DEFER;
  
 -      return drm_bridge_attach(bridge->encoder, dsi->panel_bridge, bridge,
 -                               flags);
 +      return drm_bridge_attach(bridge->encoder, panel_bridge, bridge, flags);
  }
  
  static void nwl_dsi_bridge_detach(struct drm_bridge *bridge)
@@@ -1203,7 -1204,6 +1201,7 @@@ static int nwl_dsi_probe(struct platfor
  
        ret = nwl_dsi_select_input(dsi);
        if (ret < 0) {
 +              pm_runtime_disable(dev);
                mipi_dsi_host_unregister(&dsi->dsi_host);
                return ret;
        }
@@@ -269,7 -269,7 +269,7 @@@ EXPORT_SYMBOL(drm_privacy_screen_get_st
   *
   * The notifier is called with no locks held. The new hw_state and sw_state
   * can be retrieved using the drm_privacy_screen_get_state() function.
-  * A pointer to the drm_privacy_screen's struct is passed as the void *data
+  * A pointer to the drm_privacy_screen's struct is passed as the ``void *data``
   * argument of the notifier_block's notifier_call.
   *
   * The notifier will NOT be called when changes are made through
@@@ -387,8 -387,7 +387,8 @@@ static void drm_privacy_screen_device_r
   * * An ERR_PTR(errno) on failure.
   */
  struct drm_privacy_screen *drm_privacy_screen_register(
 -      struct device *parent, const struct drm_privacy_screen_ops *ops)
 +      struct device *parent, const struct drm_privacy_screen_ops *ops,
 +      void *data)
  {
        struct drm_privacy_screen *priv;
        int ret;
        priv->dev.parent = parent;
        priv->dev.release = drm_privacy_screen_device_release;
        dev_set_name(&priv->dev, "privacy_screen-%s", dev_name(parent));
 +      priv->drvdata = data;
        priv->ops = ops;
  
        priv->ops->get_hw_state(priv);
@@@ -441,7 -439,6 +441,7 @@@ void drm_privacy_screen_unregister(stru
        mutex_unlock(&drm_privacy_screen_devs_lock);
  
        mutex_lock(&priv->lock);
 +      priv->drvdata = NULL;
        priv->ops = NULL;
        mutex_unlock(&priv->lock);
  
  
  #include "pxp/intel_pxp.h"
  
 +#include "i915_cmd_parser.h"
  #include "i915_drv.h"
  #include "i915_gem_clflush.h"
  #include "i915_gem_context.h"
 +#include "i915_gem_evict.h"
  #include "i915_gem_ioctls.h"
  #include "i915_trace.h"
  #include "i915_user_extensions.h"
@@@ -2507,9 -2505,14 +2507,14 @@@ static int eb_pin_timeline(struct i915_
                                      timeout) < 0) {
                        i915_request_put(rq);
  
-                       tl = intel_context_timeline_lock(ce);
+                       /*
+                        * Error path, cannot use intel_context_timeline_lock as
+                        * that is user interruptable and this clean up step
+                        * must be done.
+                        */
+                       mutex_lock(&ce->timeline->mutex);
                        intel_context_exit(ce);
-                       intel_context_timeline_unlock(tl);
+                       mutex_unlock(&ce->timeline->mutex);
  
                        if (nonblock)
                                return -EWOULDBLOCK;
@@@ -9,15 -9,13 +9,15 @@@
  #include "gt/gen8_engine_cs.h"
  #include "gt/intel_breadcrumbs.h"
  #include "gt/intel_context.h"
 -#include "gt/intel_engine_pm.h"
  #include "gt/intel_engine_heartbeat.h"
 +#include "gt/intel_engine_pm.h"
 +#include "gt/intel_engine_regs.h"
  #include "gt/intel_gpu_commands.h"
  #include "gt/intel_gt.h"
  #include "gt/intel_gt_clock_utils.h"
  #include "gt/intel_gt_irq.h"
  #include "gt/intel_gt_pm.h"
 +#include "gt/intel_gt_regs.h"
  #include "gt/intel_gt_requests.h"
  #include "gt/intel_lrc.h"
  #include "gt/intel_lrc_reg.h"
@@@ -1115,6 -1113,19 +1115,19 @@@ __extend_last_switch(struct intel_guc *
        if (new_start == lower_32_bits(*prev_start))
                return;
  
+       /*
+        * When gt is unparked, we update the gt timestamp and start the ping
+        * worker that updates the gt_stamp every POLL_TIME_CLKS. As long as gt
+        * is unparked, all switched in contexts will have a start time that is
+        * within +/- POLL_TIME_CLKS of the most recent gt_stamp.
+        *
+        * If neither gt_stamp nor new_start has rolled over, then the
+        * gt_stamp_hi does not need to be adjusted, however if one of them has
+        * rolled over, we need to adjust gt_stamp_hi accordingly.
+        *
+        * The below conditions address the cases of new_start rollover and
+        * gt_stamp_last rollover respectively.
+        */
        if (new_start < gt_stamp_last &&
            (new_start - gt_stamp_last) <= POLL_TIME_CLKS)
                gt_stamp_hi++;
        *prev_start = ((u64)gt_stamp_hi << 32) | new_start;
  }
  
- static void guc_update_engine_gt_clks(struct intel_engine_cs *engine)
+ /*
+  * GuC updates shared memory and KMD reads it. Since this is not synchronized,
+  * we run into a race where the value read is inconsistent. Sometimes the
+  * inconsistency is in reading the upper MSB bytes of the last_in value when
+  * this race occurs. 2 types of cases are seen - upper 8 bits are zero and upper
+  * 24 bits are zero. Since these are non-zero values, it is non-trivial to
+  * determine validity of these values. Instead we read the values multiple times
+  * until they are consistent. In test runs, 3 attempts results in consistent
+  * values. The upper bound is set to 6 attempts and may need to be tuned as per
+  * any new occurences.
+  */
+ static void __get_engine_usage_record(struct intel_engine_cs *engine,
+                                     u32 *last_in, u32 *id, u32 *total)
  {
        struct guc_engine_usage_record *rec = intel_guc_engine_usage(engine);
+       int i = 0;
+       do {
+               *last_in = READ_ONCE(rec->last_switch_in_stamp);
+               *id = READ_ONCE(rec->current_context_index);
+               *total = READ_ONCE(rec->total_runtime);
+               if (READ_ONCE(rec->last_switch_in_stamp) == *last_in &&
+                   READ_ONCE(rec->current_context_index) == *id &&
+                   READ_ONCE(rec->total_runtime) == *total)
+                       break;
+       } while (++i < 6);
+ }
+ static void guc_update_engine_gt_clks(struct intel_engine_cs *engine)
+ {
        struct intel_engine_guc_stats *stats = &engine->stats.guc;
        struct intel_guc *guc = &engine->gt->uc.guc;
-       u32 last_switch = rec->last_switch_in_stamp;
-       u32 ctx_id = rec->current_context_index;
-       u32 total = rec->total_runtime;
+       u32 last_switch, ctx_id, total;
  
        lockdep_assert_held(&guc->timestamp.lock);
  
+       __get_engine_usage_record(engine, &last_switch, &ctx_id, &total);
        stats->running = ctx_id != ~0U && last_switch;
        if (stats->running)
                __extend_last_switch(guc, &stats->start_gt_clk, last_switch);
        }
  }
  
- static void guc_update_pm_timestamp(struct intel_guc *guc,
-                                   struct intel_engine_cs *engine,
-                                   ktime_t *now)
+ static u32 gpm_timestamp_shift(struct intel_gt *gt)
+ {
+       intel_wakeref_t wakeref;
+       u32 reg, shift;
+       with_intel_runtime_pm(gt->uncore->rpm, wakeref)
+               reg = intel_uncore_read(gt->uncore, RPM_CONFIG0);
+       shift = (reg & GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_MASK) >>
+               GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_SHIFT;
+       return 3 - shift;
+ }
+ static u64 gpm_timestamp(struct intel_gt *gt)
+ {
+       u32 lo, hi, old_hi, loop = 0;
+       hi = intel_uncore_read(gt->uncore, MISC_STATUS1);
+       do {
+               lo = intel_uncore_read(gt->uncore, MISC_STATUS0);
+               old_hi = hi;
+               hi = intel_uncore_read(gt->uncore, MISC_STATUS1);
+       } while (old_hi != hi && loop++ < 2);
+       return ((u64)hi << 32) | lo;
+ }
+ static void guc_update_pm_timestamp(struct intel_guc *guc, ktime_t *now)
  {
-       u32 gt_stamp_now, gt_stamp_hi;
+       struct intel_gt *gt = guc_to_gt(guc);
+       u32 gt_stamp_lo, gt_stamp_hi;
+       u64 gpm_ts;
  
        lockdep_assert_held(&guc->timestamp.lock);
  
        gt_stamp_hi = upper_32_bits(guc->timestamp.gt_stamp);
-       gt_stamp_now = intel_uncore_read(engine->uncore,
-                                        RING_TIMESTAMP(engine->mmio_base));
+       gpm_ts = gpm_timestamp(gt) >> guc->timestamp.shift;
+       gt_stamp_lo = lower_32_bits(gpm_ts);
        *now = ktime_get();
  
-       if (gt_stamp_now < lower_32_bits(guc->timestamp.gt_stamp))
+       if (gt_stamp_lo < lower_32_bits(guc->timestamp.gt_stamp))
                gt_stamp_hi++;
  
-       guc->timestamp.gt_stamp = ((u64)gt_stamp_hi << 32) | gt_stamp_now;
+       guc->timestamp.gt_stamp = ((u64)gt_stamp_hi << 32) | gt_stamp_lo;
  }
  
  /*
@@@ -1210,8 -1277,12 +1279,12 @@@ static ktime_t guc_engine_busyness(stru
        if (!in_reset && intel_gt_pm_get_if_awake(gt)) {
                stats_saved = *stats;
                gt_stamp_saved = guc->timestamp.gt_stamp;
+               /*
+                * Update gt_clks, then gt timestamp to simplify the 'gt_stamp -
+                * start_gt_clk' calculation below for active engines.
+                */
                guc_update_engine_gt_clks(engine);
-               guc_update_pm_timestamp(guc, engine, now);
+               guc_update_pm_timestamp(guc, now);
                intel_gt_pm_put_async(gt);
                if (i915_reset_count(gpu_error) != reset_count) {
                        *stats = stats_saved;
@@@ -1243,8 -1314,8 +1316,8 @@@ static void __reset_guc_busyness_stats(
  
        spin_lock_irqsave(&guc->timestamp.lock, flags);
  
+       guc_update_pm_timestamp(guc, &unused);
        for_each_engine(engine, gt, id) {
-               guc_update_pm_timestamp(guc, engine, &unused);
                guc_update_engine_gt_clks(engine);
                engine->stats.guc.prev_total = 0;
        }
@@@ -1261,10 -1332,11 +1334,11 @@@ static void __update_guc_busyness_stats
        ktime_t unused;
  
        spin_lock_irqsave(&guc->timestamp.lock, flags);
-       for_each_engine(engine, gt, id) {
-               guc_update_pm_timestamp(guc, engine, &unused);
+       guc_update_pm_timestamp(guc, &unused);
+       for_each_engine(engine, gt, id)
                guc_update_engine_gt_clks(engine);
-       }
        spin_unlock_irqrestore(&guc->timestamp.lock, flags);
  }
  
@@@ -1337,10 -1409,15 +1411,15 @@@ void intel_guc_busyness_park(struct int
  void intel_guc_busyness_unpark(struct intel_gt *gt)
  {
        struct intel_guc *guc = &gt->uc.guc;
+       unsigned long flags;
+       ktime_t unused;
  
        if (!guc_submission_initialized(guc))
                return;
  
+       spin_lock_irqsave(&guc->timestamp.lock, flags);
+       guc_update_pm_timestamp(guc, &unused);
+       spin_unlock_irqrestore(&guc->timestamp.lock, flags);
        mod_delayed_work(system_highpri_wq, &guc->timestamp.work,
                         guc->timestamp.ping_delay);
  }
@@@ -1785,6 -1862,7 +1864,7 @@@ int intel_guc_submission_init(struct in
        spin_lock_init(&guc->timestamp.lock);
        INIT_DELAYED_WORK(&guc->timestamp.work, guc_timestamp_ping);
        guc->timestamp.ping_delay = (POLL_TIME_CLKS / gt->clock_frequency + 1) * HZ;
+       guc->timestamp.shift = gpm_timestamp_shift(gt);
  
        return 0;
  }
  
  #include "gem/i915_gem_context.h"
  #include "gem/i915_gem_lmem.h"
 +#include "gt/intel_engine_regs.h"
  #include "gt/intel_gt.h"
  #include "gt/intel_gt_pm.h"
 +#include "gt/intel_gt_regs.h"
  
  #include "i915_drv.h"
  #include "i915_gpu_error.h"
@@@ -1524,7 -1522,7 +1524,7 @@@ capture_engine(struct intel_engine_cs *
        struct i915_request *rq = NULL;
        unsigned long flags;
  
-       ee = intel_engine_coredump_alloc(engine, GFP_KERNEL);
+       ee = intel_engine_coredump_alloc(engine, ALLOW_FAIL);
        if (!ee)
                return NULL;
  
@@@ -588,6 -588,7 +588,7 @@@ static int panel_simple_probe(struct de
                err = panel_dpi_probe(dev, panel);
                if (err)
                        goto free_ddc;
+               desc = panel->desc;
        } else {
                if (!of_get_display_timing(dev->of_node, "panel-timing", &dt))
                        panel_simple_parse_panel_timing_node(dev, panel, &dt);
@@@ -2525,36 -2526,6 +2526,36 @@@ static const struct panel_desc mitsubis
        .bus_flags = DRM_BUS_FLAG_DE_HIGH,
  };
  
 +static const struct display_timing multi_inno_mi0700s4t_6_timing = {
 +      .pixelclock = { 29000000, 33000000, 38000000 },
 +      .hactive = { 800, 800, 800 },
 +      .hfront_porch = { 180, 210, 240 },
 +      .hback_porch = { 16, 16, 16 },
 +      .hsync_len = { 30, 30, 30 },
 +      .vactive = { 480, 480, 480 },
 +      .vfront_porch = { 12, 22, 32 },
 +      .vback_porch = { 10, 10, 10 },
 +      .vsync_len = { 13, 13, 13 },
 +      .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW |
 +               DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE |
 +               DISPLAY_FLAGS_SYNC_POSEDGE,
 +};
 +
 +static const struct panel_desc multi_inno_mi0700s4t_6 = {
 +      .timings = &multi_inno_mi0700s4t_6_timing,
 +      .num_timings = 1,
 +      .bpc = 8,
 +      .size = {
 +              .width = 154,
 +              .height = 86,
 +      },
 +      .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
 +      .bus_flags = DRM_BUS_FLAG_DE_HIGH |
 +                   DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE |
 +                   DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE,
 +      .connector_type = DRM_MODE_CONNECTOR_DPI,
 +};
 +
  static const struct display_timing multi_inno_mi1010ait_1cp_timing = {
        .pixelclock = { 68900000, 70000000, 73400000 },
        .hactive = { 1280, 1280, 1280 },
@@@ -3901,9 -3872,6 +3902,9 @@@ static const struct of_device_id platfo
        }, {
                .compatible = "mitsubishi,aa070mc01-ca1",
                .data = &mitsubishi_aa070mc01,
 +      }, {
 +              .compatible = "multi-inno,mi0700s4t-6",
 +              .data = &multi_inno_mi0700s4t_6,
        }, {
                .compatible = "multi-inno,mi1010ait-1cp",
                .data = &multi_inno_mi1010ait_1cp,
@@@ -104,15 -104,6 +104,15 @@@ static bool vc4_hdmi_mode_needs_scrambl
        return (mode->clock * 1000) > HDMI_14_MAX_TMDS_CLK;
  }
  
 +static bool vc4_hdmi_is_full_range_rgb(struct vc4_hdmi *vc4_hdmi,
 +                                     const struct drm_display_mode *mode)
 +{
 +      struct vc4_hdmi_encoder *vc4_encoder = &vc4_hdmi->encoder;
 +
 +      return !vc4_encoder->hdmi_monitor ||
 +              drm_default_rgb_quant_range(mode) == HDMI_QUANTIZATION_RANGE_FULL;
 +}
 +
  static int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused)
  {
        struct drm_info_node *node = (struct drm_info_node *)m->private;
@@@ -205,14 -196,8 +205,8 @@@ vc4_hdmi_connector_detect(struct drm_co
                if (gpiod_get_value_cansleep(vc4_hdmi->hpd_gpio))
                        connected = true;
        } else {
-               unsigned long flags;
-               u32 hotplug;
-               spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
-               hotplug = HDMI_READ(HDMI_HOTPLUG);
-               spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
-               if (hotplug & VC4_HDMI_HOTPLUG_CONNECTED)
+               if (vc4_hdmi->variant->hp_detect &&
+                   vc4_hdmi->variant->hp_detect(vc4_hdmi))
                        connected = true;
        }
  
@@@ -490,6 -475,7 +484,6 @@@ static void vc4_hdmi_write_infoframe(st
  static void vc4_hdmi_set_avi_infoframe(struct drm_encoder *encoder)
  {
        struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
 -      struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
        struct drm_connector *connector = &vc4_hdmi->connector;
        struct drm_connector_state *cstate = connector->state;
        const struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode;
  
        drm_hdmi_avi_infoframe_quant_range(&frame.avi,
                                           connector, mode,
 -                                         vc4_encoder->limited_rgb_range ?
 -                                         HDMI_QUANTIZATION_RANGE_LIMITED :
 -                                         HDMI_QUANTIZATION_RANGE_FULL);
 -      drm_hdmi_avi_infoframe_colorspace(&frame.avi, cstate);
 +                                         vc4_hdmi_is_full_range_rgb(vc4_hdmi, mode) ?
 +                                         HDMI_QUANTIZATION_RANGE_FULL :
 +                                         HDMI_QUANTIZATION_RANGE_LIMITED);
 +      drm_hdmi_avi_infoframe_colorimetry(&frame.avi, cstate);
        drm_hdmi_avi_infoframe_bars(&frame.avi, cstate);
  
        vc4_hdmi_write_infoframe(encoder, &frame);
@@@ -734,9 -720,7 +728,9 @@@ static void vc4_hdmi_encoder_disable(st
        mutex_unlock(&vc4_hdmi->mutex);
  }
  
 -static void vc4_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, bool enable)
 +static void vc4_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi,
 +                             struct drm_connector_state *state,
 +                             const struct drm_display_mode *mode)
  {
        unsigned long flags;
        u32 csc_ctl;
        csc_ctl = VC4_SET_FIELD(VC4_HD_CSC_CTL_ORDER_BGR,
                                VC4_HD_CSC_CTL_ORDER);
  
 -      if (enable) {
 +      if (!vc4_hdmi_is_full_range_rgb(vc4_hdmi, mode)) {
                /* CEA VICs other than #1 requre limited range RGB
                 * output unless overridden by an AVI infoframe.
                 * Apply a colorspace conversion to squash 0-255 down
        spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
  }
  
 -static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, bool enable)
 +/*
 + * If we need to output Full Range RGB, then use the unity matrix
 + *
 + * [ 1      0      0      0]
 + * [ 0      1      0      0]
 + * [ 0      0      1      0]
 + *
 + * Matrix is signed 2p13 fixed point, with signed 9p6 offsets
 + */
 +static const u16 vc5_hdmi_csc_full_rgb_unity[3][4] = {
 +      { 0x2000, 0x0000, 0x0000, 0x0000 },
 +      { 0x0000, 0x2000, 0x0000, 0x0000 },
 +      { 0x0000, 0x0000, 0x2000, 0x0000 },
 +};
 +
 +/*
 + * CEA VICs other than #1 require limited range RGB output unless
 + * overridden by an AVI infoframe. Apply a colorspace conversion to
 + * squash 0-255 down to 16-235. The matrix here is:
 + *
 + * [ 0.8594 0      0      16]
 + * [ 0      0.8594 0      16]
 + * [ 0      0      0.8594 16]
 + *
 + * Matrix is signed 2p13 fixed point, with signed 9p6 offsets
 + */
 +static const u16 vc5_hdmi_csc_full_rgb_to_limited_rgb[3][4] = {
 +      { 0x1b80, 0x0000, 0x0000, 0x0400 },
 +      { 0x0000, 0x1b80, 0x0000, 0x0400 },
 +      { 0x0000, 0x0000, 0x1b80, 0x0400 },
 +};
 +
 +static void vc5_hdmi_set_csc_coeffs(struct vc4_hdmi *vc4_hdmi,
 +                                  const u16 coeffs[3][4])
 +{
 +      lockdep_assert_held(&vc4_hdmi->hw_lock);
 +
 +      HDMI_WRITE(HDMI_CSC_12_11, (coeffs[0][1] << 16) | coeffs[0][0]);
 +      HDMI_WRITE(HDMI_CSC_14_13, (coeffs[0][3] << 16) | coeffs[0][2]);
 +      HDMI_WRITE(HDMI_CSC_22_21, (coeffs[1][1] << 16) | coeffs[1][0]);
 +      HDMI_WRITE(HDMI_CSC_24_23, (coeffs[1][3] << 16) | coeffs[1][2]);
 +      HDMI_WRITE(HDMI_CSC_32_31, (coeffs[2][1] << 16) | coeffs[2][0]);
 +      HDMI_WRITE(HDMI_CSC_34_33, (coeffs[2][3] << 16) | coeffs[2][2]);
 +}
 +
 +static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi,
 +                             struct drm_connector_state *state,
 +                             const struct drm_display_mode *mode)
  {
        unsigned long flags;
 -      u32 csc_ctl;
 -
 -      csc_ctl = 0x07; /* RGB_CONVERT_MODE = custom matrix, || USE_RGB_TO_YCBCR */
 +      u32 csc_ctl = VC5_MT_CP_CSC_CTL_ENABLE | VC4_SET_FIELD(VC4_HD_CSC_CTL_MODE_CUSTOM,
 +                                                             VC5_MT_CP_CSC_CTL_MODE);
  
        spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
  
 -      if (enable) {
 -              /* CEA VICs other than #1 requre limited range RGB
 -               * output unless overridden by an AVI infoframe.
 -               * Apply a colorspace conversion to squash 0-255 down
 -               * to 16-235.  The matrix here is:
 -               *
 -               * [ 0.8594 0      0      16]
 -               * [ 0      0.8594 0      16]
 -               * [ 0      0      0.8594 16]
 -               * [ 0      0      0       1]
 -               * Matrix is signed 2p13 fixed point, with signed 9p6 offsets
 -               */
 -              HDMI_WRITE(HDMI_CSC_12_11, (0x0000 << 16) | 0x1b80);
 -              HDMI_WRITE(HDMI_CSC_14_13, (0x0400 << 16) | 0x0000);
 -              HDMI_WRITE(HDMI_CSC_22_21, (0x1b80 << 16) | 0x0000);
 -              HDMI_WRITE(HDMI_CSC_24_23, (0x0400 << 16) | 0x0000);
 -              HDMI_WRITE(HDMI_CSC_32_31, (0x0000 << 16) | 0x0000);
 -              HDMI_WRITE(HDMI_CSC_34_33, (0x0400 << 16) | 0x1b80);
 -      } else {
 -              /* Still use the matrix for full range, but make it unity.
 -               * Matrix is signed 2p13 fixed point, with signed 9p6 offsets
 -               */
 -              HDMI_WRITE(HDMI_CSC_12_11, (0x0000 << 16) | 0x2000);
 -              HDMI_WRITE(HDMI_CSC_14_13, (0x0000 << 16) | 0x0000);
 -              HDMI_WRITE(HDMI_CSC_22_21, (0x2000 << 16) | 0x0000);
 -              HDMI_WRITE(HDMI_CSC_24_23, (0x0000 << 16) | 0x0000);
 -              HDMI_WRITE(HDMI_CSC_32_31, (0x0000 << 16) | 0x0000);
 -              HDMI_WRITE(HDMI_CSC_34_33, (0x0000 << 16) | 0x2000);
 -      }
 +      HDMI_WRITE(HDMI_VEC_INTERFACE_XBAR, 0x354021);
 +
 +      if (!vc4_hdmi_is_full_range_rgb(vc4_hdmi, mode))
 +              vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_to_limited_rgb);
 +      else
 +              vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_unity);
  
        HDMI_WRITE(HDMI_CSC_CTL, csc_ctl);
  
@@@ -922,6 -883,7 +916,6 @@@ static void vc5_hdmi_set_timings(struc
  
        spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
  
 -      HDMI_WRITE(HDMI_VEC_INTERFACE_XBAR, 0x354021);
        HDMI_WRITE(HDMI_HORZA,
                   (vsync_pos ? VC5_HDMI_HORZA_VPOS : 0) |
                   (hsync_pos ? VC5_HDMI_HORZA_HPOS : 0) |
@@@ -1145,16 -1107,24 +1139,16 @@@ static void vc4_hdmi_encoder_pre_crtc_e
                                             struct drm_atomic_state *state)
  {
        struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
 +      struct drm_connector *connector = &vc4_hdmi->connector;
        struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode;
 -      struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
 +      struct drm_connector_state *conn_state =
 +              drm_atomic_get_new_connector_state(state, connector);
        unsigned long flags;
  
        mutex_lock(&vc4_hdmi->mutex);
  
 -      if (vc4_encoder->hdmi_monitor &&
 -          drm_default_rgb_quant_range(mode) == HDMI_QUANTIZATION_RANGE_LIMITED) {
 -              if (vc4_hdmi->variant->csc_setup)
 -                      vc4_hdmi->variant->csc_setup(vc4_hdmi, true);
 -
 -              vc4_encoder->limited_rgb_range = true;
 -      } else {
 -              if (vc4_hdmi->variant->csc_setup)
 -                      vc4_hdmi->variant->csc_setup(vc4_hdmi, false);
 -
 -              vc4_encoder->limited_rgb_range = false;
 -      }
 +      if (vc4_hdmi->variant->csc_setup)
 +              vc4_hdmi->variant->csc_setup(vc4_hdmi, conn_state, mode);
  
        spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
        HDMI_WRITE(HDMI_FIFO_CTL, VC4_HDMI_FIFO_CTL_MASTER_SLAVE_N);
@@@ -1275,6 -1245,7 +1269,7 @@@ static int vc4_hdmi_encoder_atomic_chec
        unsigned long long tmds_rate;
  
        if (vc4_hdmi->variant->unsupported_odd_h_timings &&
+           !(mode->flags & DRM_MODE_FLAG_DBLCLK) &&
            ((mode->hdisplay % 2) || (mode->hsync_start % 2) ||
             (mode->hsync_end % 2) || (mode->htotal % 2)))
                return -EINVAL;
@@@ -1322,6 -1293,7 +1317,7 @@@ vc4_hdmi_encoder_mode_valid(struct drm_
        struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
  
        if (vc4_hdmi->variant->unsupported_odd_h_timings &&
+           !(mode->flags & DRM_MODE_FLAG_DBLCLK) &&
            ((mode->hdisplay % 2) || (mode->hsync_start % 2) ||
             (mode->hsync_end % 2) || (mode->htotal % 2)))
                return MODE_H_ILLEGAL;
@@@ -1367,6 -1339,18 +1363,18 @@@ static u32 vc5_hdmi_channel_map(struct 
        return channel_map;
  }
  
+ static bool vc5_hdmi_hp_detect(struct vc4_hdmi *vc4_hdmi)
+ {
+       unsigned long flags;
+       u32 hotplug;
+       spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
+       hotplug = HDMI_READ(HDMI_HOTPLUG);
+       spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
+       return !!(hotplug & VC4_HDMI_HOTPLUG_CONNECTED);
+ }
  /* HDMI audio codec callbacks */
  static void vc4_hdmi_audio_set_mai_clock(struct vc4_hdmi *vc4_hdmi,
                                         unsigned int samplerate)
@@@ -2528,7 -2512,8 +2536,8 @@@ static int vc4_hdmi_bind(struct device 
         * vc4_hdmi_disable_scrambling() will thus run at boot, make
         * sure it's disabled, and avoid any inconsistency.
         */
-       vc4_hdmi->scdc_enabled = true;
+       if (variant->max_pixel_clock > HDMI_14_MAX_TMDS_CLK)
+               vc4_hdmi->scdc_enabled = true;
  
        ret = variant->init_resources(vc4_hdmi);
        if (ret)
@@@ -2747,6 -2732,7 +2756,7 @@@ static const struct vc4_hdmi_variant bc
        .phy_rng_disable        = vc5_hdmi_phy_rng_disable,
        .channel_map            = vc5_hdmi_channel_map,
        .supports_hdr           = true,
+       .hp_detect              = vc5_hdmi_hp_detect,
  };
  
  static const struct vc4_hdmi_variant bcm2711_hdmi1_variant = {
        .phy_rng_disable        = vc5_hdmi_phy_rng_disable,
        .channel_map            = vc5_hdmi_channel_map,
        .supports_hdr           = true,
+       .hp_detect              = vc5_hdmi_hp_detect,
  };
  
  static const struct of_device_id vc4_hdmi_dt_match[] = {
@@@ -12,6 -12,7 +12,6 @@@
  struct vc4_hdmi_encoder {
        struct vc4_encoder base;
        bool hdmi_monitor;
 -      bool limited_rgb_range;
  };
  
  static inline struct vc4_hdmi_encoder *
@@@ -76,9 -77,7 +76,9 @@@ struct vc4_hdmi_variant 
        void (*reset)(struct vc4_hdmi *vc4_hdmi);
  
        /* Callback to enable / disable the CSC */
 -      void (*csc_setup)(struct vc4_hdmi *vc4_hdmi, bool enable);
 +      void (*csc_setup)(struct vc4_hdmi *vc4_hdmi,
 +                        struct drm_connector_state *state,
 +                        const struct drm_display_mode *mode);
  
        /* Callback to configure the video timings in the HDMI block */
        void (*set_timings)(struct vc4_hdmi *vc4_hdmi,
  
        /* Enables HDR metadata */
        bool supports_hdr;
+       /* Callback for hardware specific hotplug detect */
+       bool (*hp_detect)(struct vc4_hdmi *vc4_hdmi);
  };
  
  /* HDMI audio information */
diff --combined drivers/misc/fastrpc.c
@@@ -587,11 -587,11 +587,11 @@@ static void fastrpc_dma_buf_detatch(str
        kfree(a);
  }
  
 -static int fastrpc_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map)
 +static int fastrpc_vmap(struct dma_buf *dmabuf, struct iosys_map *map)
  {
        struct fastrpc_buf *buf = dmabuf->priv;
  
 -      dma_buf_map_set_vaddr(map, buf->virt);
 +      iosys_map_set_vaddr(map, buf->virt);
  
        return 0;
  }
@@@ -1288,7 -1288,14 +1288,14 @@@ static int fastrpc_dmabuf_alloc(struct 
        }
  
        if (copy_to_user(argp, &bp, sizeof(bp))) {
-               dma_buf_put(buf->dmabuf);
+               /*
+                * The usercopy failed, but we can't do much about it, as
+                * dma_buf_fd() already called fd_install() and made the
+                * file descriptor accessible for the current process. It
+                * might already be closed and dmabuf no longer valid when
+                * we reach this point. Therefore "leak" the fd and rely on
+                * the process exit path to do any required cleanup.
+                */
                return -EFAULT;
        }
  
@@@ -8679,9 -8679,10 +8679,10 @@@ static const struct attribute_group fan
        .attrs = fan_driver_attributes,
  };
  
- #define TPACPI_FAN_Q1 0x0001          /* Unitialized HFSP */
- #define TPACPI_FAN_2FAN       0x0002          /* EC 0x31 bit 0 selects fan2 */
- #define TPACPI_FAN_2CTL       0x0004          /* selects fan2 control */
+ #define TPACPI_FAN_Q1         0x0001          /* Uninitialized HFSP */
+ #define TPACPI_FAN_2FAN               0x0002          /* EC 0x31 bit 0 selects fan2 */
+ #define TPACPI_FAN_2CTL               0x0004          /* selects fan2 control */
+ #define TPACPI_FAN_NOFAN      0x0008          /* no fan available */
  
  static const struct tpacpi_quirk fan_quirk_table[] __initconst = {
        TPACPI_QEC_IBM('1', 'Y', TPACPI_FAN_Q1),
        TPACPI_Q_LNV3('N', '4', '0', TPACPI_FAN_2CTL),  /* P1 / X1 Extreme (4nd gen) */
        TPACPI_Q_LNV3('N', '3', '0', TPACPI_FAN_2CTL),  /* P15 (1st gen) / P15v (1st gen) */
        TPACPI_Q_LNV3('N', '3', '2', TPACPI_FAN_2CTL),  /* X1 Carbon (9th gen) */
+       TPACPI_Q_LNV3('N', '1', 'O', TPACPI_FAN_NOFAN), /* X1 Tablet (2nd gen) */
  };
  
  static int __init fan_init(struct ibm_init_struct *iibm)
        quirks = tpacpi_check_quirks(fan_quirk_table,
                                     ARRAY_SIZE(fan_quirk_table));
  
+       if (quirks & TPACPI_FAN_NOFAN) {
+               pr_info("No integrated ThinkPad fan available\n");
+               return -ENODEV;
+       }
        if (gfan_handle) {
                /* 570, 600e/x, 770e, 770x */
                fan_status_access_mode = TPACPI_FAN_RD_ACPI_GFAN;
@@@ -9869,7 -9876,7 +9876,7 @@@ static int tpacpi_lcdshadow_init(struc
                return 0;
  
        lcdshadow_dev = drm_privacy_screen_register(&tpacpi_pdev->dev,
 -                                                  &lcdshadow_ops);
 +                                                  &lcdshadow_ops, NULL);
        if (IS_ERR(lcdshadow_dev))
                return PTR_ERR(lcdshadow_dev);
  
@@@ -10112,6 -10119,9 +10119,9 @@@ static struct ibm_struct proxsensor_dri
  #define DYTC_CMD_MMC_GET      8 /* To get current MMC function and mode */
  #define DYTC_CMD_RESET    0x1ff /* To reset back to default */
  
+ #define DYTC_CMD_FUNC_CAP     3 /* To get DYTC capabilities */
+ #define DYTC_FC_MMC           27 /* MMC Mode supported */
  #define DYTC_GET_FUNCTION_BIT 8  /* Bits  8-11 - function setting */
  #define DYTC_GET_MODE_BIT     12 /* Bits 12-15 - mode setting */
  
@@@ -10324,6 -10334,15 +10334,15 @@@ static int tpacpi_dytc_profile_init(str
        if (dytc_version < 5)
                return -ENODEV;
  
+       /* Check what capabilities are supported. Currently MMC is needed */
+       err = dytc_command(DYTC_CMD_FUNC_CAP, &output);
+       if (err)
+               return err;
+       if (!(output & BIT(DYTC_FC_MMC))) {
+               dbg_printk(TPACPI_DBG_INIT, " DYTC MMC mode not supported\n");
+               return -ENODEV;
+       }
        dbg_printk(TPACPI_DBG_INIT,
                        "DYTC version %d: thermal mode available\n", dytc_version);
        /*
@@@ -25,7 -25,6 +25,7 @@@
  #include <linux/init.h>
  #include <linux/linux_logo.h>
  #include <linux/proc_fs.h>
 +#include <linux/platform_device.h>
  #include <linux/seq_file.h>
  #include <linux/console.h>
  #include <linux/kmod.h>
@@@ -1161,6 -1160,8 +1161,8 @@@ static long do_fb_ioctl(struct fb_info 
                ret = fbcon_set_con2fb_map_ioctl(argp);
                break;
        case FBIOBLANK:
+               if (arg > FB_BLANK_POWERDOWN)
+                       return -EINVAL;
                console_lock();
                lock_fb_info(info);
                ret = fb_blank(info, arg);
@@@ -1558,36 -1559,18 +1560,36 @@@ static void do_remove_conflicting_frame
        /* check all firmware fbs and kick off if the base addr overlaps */
        for_each_registered_fb(i) {
                struct apertures_struct *gen_aper;
 +              struct device *device;
  
                if (!(registered_fb[i]->flags & FBINFO_MISC_FIRMWARE))
                        continue;
  
                gen_aper = registered_fb[i]->apertures;
 +              device = registered_fb[i]->device;
                if (fb_do_apertures_overlap(gen_aper, a) ||
                        (primary && gen_aper && gen_aper->count &&
                         gen_aper->ranges[0].base == VGA_FB_PHYS)) {
  
                        printk(KERN_INFO "fb%d: switching to %s from %s\n",
                               i, name, registered_fb[i]->fix.id);
 -                      do_unregister_framebuffer(registered_fb[i]);
 +
 +                      /*
 +                       * If we kick-out a firmware driver, we also want to remove
 +                       * the underlying platform device, such as simple-framebuffer,
 +                       * VESA, EFI, etc. A native driver will then be able to
 +                       * allocate the memory range.
 +                       *
 +                       * If it's not a platform device, at least print a warning. A
 +                       * fix would add code to remove the device from the system.
 +                       */
 +                      if (dev_is_platform(device)) {
 +                              registered_fb[i]->forced_out = true;
 +                              platform_device_unregister(to_platform_device(device));
 +                      } else {
 +                              pr_warn("fb%d: cannot remove device\n", i);
 +                              do_unregister_framebuffer(registered_fb[i]);
 +                      }
                }
        }
  }
@@@ -1917,13 -1900,9 +1919,13 @@@ EXPORT_SYMBOL(register_framebuffer)
  void
  unregister_framebuffer(struct fb_info *fb_info)
  {
 -      mutex_lock(&registration_lock);
 +      bool forced_out = fb_info->forced_out;
 +
 +      if (!forced_out)
 +              mutex_lock(&registration_lock);
        do_unregister_framebuffer(fb_info);
 -      mutex_unlock(&registration_lock);
 +      if (!forced_out)
 +              mutex_unlock(&registration_lock);
  }
  EXPORT_SYMBOL(unregister_framebuffer);
  
diff --combined include/linux/fb.h
@@@ -262,7 -262,7 +262,7 @@@ struct fb_ops 
  
        /* Draws a rectangle */
        void (*fb_fillrect) (struct fb_info *info, const struct fb_fillrect *rect);
-       /* Copy data from area to another. Obsolete. */
+       /* Copy data from area to another */
        void (*fb_copyarea) (struct fb_info *info, const struct fb_copyarea *region);
        /* Draws a image to the display */
        void (*fb_imageblit) (struct fb_info *info, const struct fb_image *image);
@@@ -502,7 -502,6 +502,7 @@@ struct fb_info 
        } *apertures;
  
        bool skip_vt_switch; /* no VT switch on suspend/resume required */
 +      bool forced_out; /* set when being removed by another driver */
  };
  
  static inline struct apertures_struct *alloc_apertures(unsigned int max_num) {