]> Git Repo - linux.git/commitdiff
Merge drm/drm-next into drm-misc-next
authorThomas Zimmermann <[email protected]>
Thu, 18 Nov 2021 08:36:39 +0000 (09:36 +0100)
committerThomas Zimmermann <[email protected]>
Thu, 18 Nov 2021 08:36:39 +0000 (09:36 +0100)
Backmerging from drm/drm-next for v5.16-rc1.

Signed-off-by: Thomas Zimmermann <[email protected]>
33 files changed:
1  2 
Documentation/devicetree/bindings/vendor-prefixes.yaml
MAINTAINERS
drivers/dma-buf/dma-buf.c
drivers/gpu/drm/Kconfig
drivers/gpu/drm/amd/amdgpu/amdgpu.h
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
drivers/gpu/drm/drm_fb_helper.c
drivers/gpu/drm/drm_gem_shmem_helper.c
drivers/gpu/drm/hyperv/hyperv_drm_modeset.c
drivers/gpu/drm/i915/display/intel_dp.c
drivers/gpu/drm/kmb/kmb_drv.c
drivers/gpu/drm/msm/dsi/dsi.c
drivers/gpu/drm/msm/dsi/dsi.h
drivers/gpu/drm/msm/dsi/dsi_host.c
drivers/gpu/drm/msm/dsi/dsi_manager.c
drivers/gpu/drm/msm/msm_drv.h
drivers/gpu/drm/msm/msm_gem.c
drivers/gpu/drm/nouveau/dispnv50/crc.c
drivers/gpu/drm/nouveau/dispnv50/disp.c
drivers/gpu/drm/nouveau/dispnv50/head.c
drivers/gpu/drm/panel/Kconfig
drivers/gpu/drm/panel/panel-abt-y030xx067a.c
drivers/gpu/drm/panel/panel-ilitek-ili9881c.c
drivers/gpu/drm/rockchip/rockchip_drm_vop.c
drivers/gpu/drm/ttm/ttm_bo.c
drivers/gpu/drm/vc4/vc4_hdmi.c
drivers/platform/x86/Kconfig
drivers/platform/x86/thinkpad_acpi.c
drivers/pwm/core.c
include/linux/dma-buf.h
include/linux/pwm.h

index 2e848852f9794c46242d60f151b003e49c5188aa,66d6432fd7812276120b9baf31e5bbc8a57f0241..7463870d0922ca174edce5e0f459c8b41ec8ed3c
@@@ -131,6 -131,8 +131,8 @@@ patternProperties
      description: Asahi Kasei Corp.
    "^asc,.*":
      description: All Sensors Corporation
+   "^asix,.*":
+     description: ASIX Electronics Corporation
    "^aspeed,.*":
      description: ASPEED Technology Inc.
    "^asus,.*":
      description: B&R Industrial Automation GmbH
    "^bticino,.*":
      description: Bticino International
+   "^calamp,.*":
+     description: CalAmp Corp.
    "^calaosystems,.*":
      description: CALAO Systems SAS
    "^calxeda,.*":
      description: EBV Elektronik
    "^eckelmann,.*":
      description: Eckelmann AG
+   "^edimax,.*":
+     description: EDIMAX Technology Co., Ltd
    "^edt,.*":
      description: Emerging Display Technologies
    "^eeti,.*":
      description: Shenzhen Elida Technology Co., Ltd.
    "^elimo,.*":
      description: Elimo Engineering Ltd.
+   "^elpida,.*":
+     description: Elpida Memory, Inc.
    "^embest,.*":
      description: Shenzhen Embest Technology Co., Ltd.
    "^emlid,.*":
      description: Exar Corporation
    "^excito,.*":
      description: Excito
+   "^exegin,.*":
+     description: Exegin Technologies Limited
    "^ezchip,.*":
      description: EZchip Semiconductor
    "^facebook,.*":
      description: Hycon Technology Corp.
    "^hydis,.*":
      description: Hydis Technologies
+   "^hynix,.*":
+     description: SK Hynix Inc.
    "^hyundai,.*":
      description: Hyundai Technology
    "^i2se,.*":
      description: JEDEC Solid State Technology Association
    "^jesurun,.*":
      description: Shenzhen Jesurun Electronics Business Dept.
+   "^jethome,.*":
+     description: JetHome (IP Sokolov P.A.)
    "^jianda,.*":
      description: Jiandangjing Technology Co., Ltd.
    "^kam,.*":
      description: Linux-specific binding
    "^linx,.*":
      description: Linx Technologies
+   "^liteon,.*":
+     description: LITE-ON Technology Corp.
    "^litex,.*":
      description: LiteX SoC builder
    "^lltc,.*":
      description: Shenzhen SEI Robotics Co., Ltd
    "^semtech,.*":
      description: Semtech Corporation
+   "^senseair,.*":
+     description: Senseair AB
    "^sensirion,.*":
      description: Sensirion AG
    "^sensortek,.*":
      description: Spansion Inc.
    "^sparkfun,.*":
      description: SparkFun Electronics
+   "^spinalhdl,.*":
+     description: SpinalHDL
    "^sprd,.*":
      description: Spreadtrum Communications Inc.
+   "^ssi,.*":
+     description: SSI Computer Corp
    "^sst,.*":
      description: Silicon Storage Technology, Inc.
    "^sstar,.*":
      description: Wondermedia Technologies, Inc.
    "^wobo,.*":
      description: Wobo
 +  "^wanchanglong,.*":
 +    description: Wanchanglong Electronics Technology(SHENZHEN)Co.,Ltd.
    "^x-powers,.*":
      description: X-Powers
    "^xes,.*":
diff --combined MAINTAINERS
index 270dc9c0a42713989503fa1d0008b8dddd797c9c,7a2345ce85213cd03ef4aca3735a26cc1677d018..ba6fa65df8bb159832e9e9777497c22939d2f9a8
@@@ -334,7 -334,7 +334,7 @@@ F: drivers/platform/x86/acer-wmi.
  
  ACPI
  M:    "Rafael J. Wysocki" <[email protected]>
M:    Len Brown <[email protected]>
R:    Len Brown <[email protected]>
  L:    [email protected]
  S:    Supported
  W:    https://01.org/linux-acpi
@@@ -355,7 -355,7 +355,7 @@@ F: tools/power/acpi
  
  ACPI APEI
  M:    "Rafael J. Wysocki" <[email protected]>
M:    Len Brown <[email protected]>
R:    Len Brown <[email protected]>
  R:    James Morse <[email protected]>
  R:    Tony Luck <[email protected]>
  R:    Borislav Petkov <[email protected]>
@@@ -378,14 -378,6 +378,6 @@@ F:        drivers/acpi/acpica
  F:    include/acpi/
  F:    tools/power/acpi/
  
- ACPI FAN DRIVER
- M:    Zhang Rui <[email protected]>
- L:    [email protected]
- S:    Supported
- W:    https://01.org/linux-acpi
- B:    https://bugzilla.kernel.org
- F:    drivers/acpi/fan.c
  ACPI FOR ARM64 (ACPI/arm64)
  M:    Lorenzo Pieralisi <[email protected]>
  M:    Hanjun Guo <[email protected]>
@@@ -401,6 -393,12 +393,12 @@@ L:       [email protected]
  S:    Maintained
  F:    drivers/platform/x86/i2c-multi-instantiate.c
  
+ ACPI PCC(Platform Communication Channel) MAILBOX DRIVER
+ M:    Sudeep Holla <[email protected]>
+ L:    [email protected]
+ S:    Supported
+ F:    drivers/mailbox/pcc.c
  ACPI PMIC DRIVERS
  M:    "Rafael J. Wysocki" <[email protected]>
  M:    Len Brown <[email protected]>
@@@ -414,21 -412,14 +412,14 @@@ T:      git git://git.kernel.org/pub/scm/lin
  F:    drivers/acpi/pmic/
  
  ACPI THERMAL DRIVER
- M:    Zhang Rui <[email protected]>
+ M:    Rafael J. Wysocki <[email protected]>
+ R:    Zhang Rui <[email protected]>
  L:    [email protected]
  S:    Supported
  W:    https://01.org/linux-acpi
  B:    https://bugzilla.kernel.org
  F:    drivers/acpi/*thermal*
  
- ACPI VIDEO DRIVER
- M:    Zhang Rui <[email protected]>
- L:    [email protected]
- S:    Supported
- W:    https://01.org/linux-acpi
- B:    https://bugzilla.kernel.org
- F:    drivers/acpi/acpi_video.c
  ACPI VIOT DRIVER
  M:    Jean-Philippe Brucker <[email protected]>
  L:    [email protected]
@@@ -590,6 -581,12 +581,12 @@@ L:       [email protected]
  S:    Maintained
  F:    drivers/platform/x86/adv_swbutton.c
  
+ ADXL313 THREE-AXIS DIGITAL ACCELEROMETER DRIVER
+ M:    Lucas Stankus <[email protected]>
+ S:    Supported
+ F:    Documentation/devicetree/bindings/iio/accel/adi,adxl313.yaml
+ F:    drivers/iio/accel/adxl313*
  ADXL34X THREE-AXIS DIGITAL ACCELEROMETER DRIVER (ADXL345/ADXL346)
  M:    Michael Hennerich <[email protected]>
  S:    Supported
@@@ -598,6 -595,16 +595,16 @@@ W:       http://ez.analog.com/community/linux
  F:    Documentation/devicetree/bindings/iio/accel/adi,adxl345.yaml
  F:    drivers/input/misc/adxl34x.c
  
+ ADXL355 THREE-AXIS DIGITAL ACCELEROMETER DRIVER
+ M:    Puranjay Mohan <[email protected]>
+ L:    [email protected]
+ S:    Supported
+ F:    Documentation/devicetree/bindings/iio/accel/adi,adxl355.yaml
+ F:    drivers/iio/accel/adxl355.h
+ F:    drivers/iio/accel/adxl355_core.c
+ F:    drivers/iio/accel/adxl355_i2c.c
+ F:    drivers/iio/accel/adxl355_spi.c
  ADXL372 THREE-AXIS DIGITAL ACCELEROMETER DRIVER
  M:    Michael Hennerich <[email protected]>
  S:    Supported
@@@ -760,7 -767,7 +767,7 @@@ F: drivers/crypto/allwinner
  ALLWINNER HARDWARE SPINLOCK SUPPORT
  M:    Wilken Gottwalt <[email protected]>
  S:    Maintained
- F:    Documentation/devicetree/bindings/hwlock/allwinner,sun6i-hwspinlock.yaml
+ F:    Documentation/devicetree/bindings/hwlock/allwinner,sun6i-a31-hwspinlock.yaml
  F:    drivers/hwspinlock/sun6i_hwspinlock.c
  
  ALLWINNER THERMAL DRIVER
@@@ -797,7 -804,7 +804,7 @@@ F: Documentation/devicetree/bindings/i2
  F:    drivers/i2c/busses/i2c-altera.c
  
  ALTERA MAILBOX DRIVER
- M:    Joyce Ooi <joyce.ooi@intel.com>
+ M:    Mun Yew Tham <mun.yew.tham@intel.com>
  S:    Maintained
  F:    drivers/mailbox/mailbox-altera.c
  
@@@ -810,7 -817,7 +817,7 @@@ F: Documentation/devicetree/bindings/dm
  F:    drivers/dma/altera-msgdma.c
  
  ALTERA PIO DRIVER
- M:    Joyce Ooi <joyce.ooi@intel.com>
+ M:    Mun Yew Tham <mun.yew.tham@intel.com>
  L:    [email protected]
  S:    Maintained
  F:    drivers/gpio/gpio-altera.c
@@@ -865,9 -872,10 +872,10 @@@ F:       Documentation/devicetree/bindings/th
  F:    drivers/thermal/thermal_mmio.c
  
  AMAZON ETHERNET DRIVERS
- M:    Netanel Belgazal <netanel@amazon.com>
+ M:    Shay Agroskin <shayagr@amazon.com>
  M:    Arthur Kiyanovski <[email protected]>
- R:    Guy Tzalik <[email protected]>
+ R:    David Arinzon <[email protected]>
+ R:    Noam Dagan <[email protected]>
  R:    Saeed Bishara <[email protected]>
  L:    [email protected]
  S:    Supported
@@@ -902,6 -910,7 +910,7 @@@ F: include/uapi/linux/psp-sev.
  AMD DISPLAY CORE
  M:    Harry Wentland <[email protected]>
  M:    Leo Li <[email protected]>
+ M:    Rodrigo Siqueira <[email protected]>
  L:    [email protected]
  S:    Supported
  T:    git https://gitlab.freedesktop.org/agd5f/linux.git
@@@ -1019,6 -1028,14 +1028,14 @@@ S:    Maintaine
  F:    Documentation/devicetree/bindings/iio/light/ams,as73211.yaml
  F:    drivers/iio/light/as73211.c
  
+ AMT (Automatic Multicast Tunneling)
+ M:    Taehee Yoo <[email protected]>
+ L:    [email protected]
+ S:    Maintained
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git
+ F:    drivers/net/amt.c
  ANALOG DEVICES INC AD7192 DRIVER
  M:    Alexandru Tachici <[email protected]>
  L:    [email protected]
@@@ -1275,11 -1292,19 +1292,19 @@@ F:   drivers/input/mouse/bcm5974.
  
  APPLE DART IOMMU DRIVER
  M:    Sven Peter <[email protected]>
+ R:    Alyssa Rosenzweig <[email protected]>
  L:    [email protected]
  S:    Maintained
  F:    Documentation/devicetree/bindings/iommu/apple,dart.yaml
  F:    drivers/iommu/apple-dart.c
  
+ APPLE PCIE CONTROLLER DRIVER
+ M:    Alyssa Rosenzweig <[email protected]>
+ M:    Marc Zyngier <[email protected]>
+ L:    [email protected]
+ S:    Maintained
+ F:    drivers/pci/controller/pcie-apple.c
  APPLE SMC DRIVER
  M:    Henrik Rydberg <[email protected]>
  L:    [email protected]
@@@ -1411,7 -1436,7 +1436,7 @@@ F:      Documentation/devicetree/bindings/au
  F:    Documentation/devicetree/bindings/clock/arm,syscon-icst.yaml
  F:    Documentation/devicetree/bindings/i2c/i2c-versatile.txt
  F:    Documentation/devicetree/bindings/interrupt-controller/arm,versatile-fpga-irq.txt
- F:    Documentation/devicetree/bindings/mtd/arm-versatile.txt
+ F:    Documentation/devicetree/bindings/mtd/mtd-physmap.yaml
  F:    arch/arm/boot/dts/arm-realview-*
  F:    arch/arm/boot/dts/integrator*
  F:    arch/arm/boot/dts/versatile*
@@@ -1550,7 -1575,7 +1575,7 @@@ ARM PRIMECELL VIC PL190/PL192 DRIVE
  M:    Linus Walleij <[email protected]>
  L:    [email protected] (moderated for non-subscribers)
  S:    Maintained
- F:    Documentation/devicetree/bindings/interrupt-controller/arm,vic.txt
+ F:    Documentation/devicetree/bindings/interrupt-controller/arm,vic.yaml
  F:    drivers/irqchip/irq-vic.c
  
  ARM SMC WATCHDOG DRIVER
@@@ -1711,6 -1736,8 +1736,8 @@@ F:      drivers/*/*alpine
  
  ARM/APPLE MACHINE SUPPORT
  M:    Hector Martin <[email protected]>
+ M:    Sven Peter <[email protected]>
+ R:    Alyssa Rosenzweig <[email protected]>
  L:    [email protected] (moderated for non-subscribers)
  S:    Maintained
  W:    https://asahilinux.org
@@@ -1718,12 -1745,20 +1745,20 @@@ B:   https://github.com/AsahiLinux/linux/
  C:    irc://irc.oftc.net/asahi-dev
  T:    git https://github.com/AsahiLinux/linux.git
  F:    Documentation/devicetree/bindings/arm/apple.yaml
+ F:    Documentation/devicetree/bindings/i2c/apple,i2c.yaml
  F:    Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml
+ F:    Documentation/devicetree/bindings/mailbox/apple,mailbox.yaml
+ F:    Documentation/devicetree/bindings/pci/apple,pcie.yaml
  F:    Documentation/devicetree/bindings/pinctrl/apple,pinctrl.yaml
  F:    arch/arm64/boot/dts/apple/
+ F:    drivers/i2c/busses/i2c-pasemi-core.c
+ F:    drivers/i2c/busses/i2c-pasemi-platform.c
  F:    drivers/irqchip/irq-apple-aic.c
+ F:    drivers/mailbox/apple-mailbox.c
+ F:    drivers/pinctrl/pinctrl-apple-gpio.c
  F:    include/dt-bindings/interrupt-controller/apple-aic.h
  F:    include/dt-bindings/pinctrl/apple.h
+ F:    include/linux/apple-mailbox.h
  
  ARM/ARTPEC MACHINE SUPPORT
  M:    Jesper Nilsson <[email protected]>
@@@ -1745,7 -1780,7 +1780,7 @@@ R:      Joel Stanley <[email protected]
  L:    [email protected]
  L:    [email protected] (moderated for non-subscribers)
  S:    Maintained
- F:    Documentation/devicetree/bindings/i2c/i2c-aspeed.txt
+ F:    Documentation/devicetree/bindings/i2c/aspeed,i2c.yaml
  F:    Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2400-i2c-ic.txt
  F:    drivers/i2c/busses/i2c-aspeed.c
  F:    drivers/irqchip/irq-aspeed-i2c-ic.c
@@@ -1872,10 -1907,10 +1907,10 @@@ M:   Linus Walleij <linus.walleij@linaro.
  L:    [email protected] (moderated for non-subscribers)
  S:    Maintained
  T:    git git://github.com/ulli-kroll/linux.git
- F:    Documentation/devicetree/bindings/arm/gemini.txt
+ F:    Documentation/devicetree/bindings/arm/gemini.yaml
  F:    Documentation/devicetree/bindings/net/cortina,gemini-ethernet.txt
  F:    Documentation/devicetree/bindings/pinctrl/cortina,gemini-pinctrl.txt
- F:    Documentation/devicetree/bindings/rtc/faraday,ftrtc010.txt
+ F:    Documentation/devicetree/bindings/rtc/faraday,ftrtc010.yaml
  F:    arch/arm/boot/dts/gemini*
  F:    arch/arm/mach-gemini/
  F:    drivers/crypto/gemini/
@@@ -2236,6 -2271,7 +2271,7 @@@ F:      arch/arm/mach-pxa/mioa701.
  
  ARM/MStar/Sigmastar Armv7 SoC support
  M:    Daniel Palmer <[email protected]>
+ M:    Romain Perier <[email protected]>
  L:    [email protected] (moderated for non-subscribers)
  S:    Maintained
  W:    http://linux-chenxing.org/
@@@ -2247,6 -2283,7 +2283,7 @@@ F:      arch/arm/boot/dts/mstar-
  F:    arch/arm/mach-mstar/
  F:    drivers/clk/mstar/
  F:    drivers/gpio/gpio-msc313.c
+ F:    drivers/rtc/rtc-msc313.c
  F:    drivers/watchdog/msc313e_wdt.c
  F:    include/dt-bindings/clock/mstar-*
  F:    include/dt-bindings/gpio/msc313-gpio.h
@@@ -2307,6 -2344,14 +2344,14 @@@ F:    arch/arm/boot/dts/nuvoton-wpcm450
  F:    arch/arm/mach-npcm/wpcm450.c
  F:    drivers/*/*wpcm*
  
+ ARM/NXP S32G ARCHITECTURE
+ M:    Chester Lin <[email protected]>
+ R:    Andreas Färber <[email protected]>
+ R:    Matthias Brugger <[email protected]>
+ L:    [email protected] (moderated for non-subscribers)
+ S:    Maintained
+ F:    arch/arm64/boot/dts/freescale/s32g*.dts*
  ARM/OPENMOKO NEO FREERUNNER (GTA02) MACHINE SUPPORT
  L:    [email protected] (subscribers-only)
  S:    Orphan
@@@ -2712,6 -2757,7 +2757,7 @@@ F:      drivers/power/reset/keystone-reset.
  
  ARM/TEXAS INSTRUMENTS K3 ARCHITECTURE
  M:    Nishanth Menon <[email protected]>
+ M:    Vignesh Raghavendra <[email protected]>
  M:    Tero Kristo <[email protected]>
  L:    [email protected] (moderated for non-subscribers)
  S:    Supported
@@@ -2739,7 -2785,7 +2785,7 @@@ F:      Documentation/devicetree/bindings/ar
  F:    Documentation/devicetree/bindings/net/toshiba,visconti-dwmac.yaml
  F:    Documentation/devicetree/bindings/gpio/toshiba,gpio-visconti.yaml
  F:    Documentation/devicetree/bindings/pci/toshiba,visconti-pcie.yaml
- F:    Documentation/devicetree/bindings/pinctrl/toshiba,tmpv7700-pinctrl.yaml
+ F:    Documentation/devicetree/bindings/pinctrl/toshiba,visconti-pinctrl.yaml
  F:    Documentation/devicetree/bindings/watchdog/toshiba,visconti-wdt.yaml
  F:    arch/arm64/boot/dts/toshiba/
  F:    drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c
@@@ -2804,9 -2850,8 +2850,8 @@@ F:      arch/arm/mach-pxa/include/mach/vpac2
  F:    arch/arm/mach-pxa/vpac270.c
  
  ARM/VT8500 ARM ARCHITECTURE
- M:    Tony Prisk <[email protected]>
  L:    [email protected] (moderated for non-subscribers)
- S:    Maintained
+ S:    Orphan
  F:    Documentation/devicetree/bindings/i2c/i2c-wmt.txt
  F:    arch/arm/mach-vt8500/
  F:    drivers/clocksource/timer-vt8500.c
@@@ -2894,6 -2939,12 +2939,12 @@@ S:    Maintaine
  F:    Documentation/hwmon/asc7621.rst
  F:    drivers/hwmon/asc7621.c
  
+ ASIX AX88796C SPI ETHERNET ADAPTER
+ M:    Łukasz Stelmach <[email protected]>
+ S:    Maintained
+ F:    Documentation/devicetree/bindings/net/asix,ax88796c.yaml
+ F:    drivers/net/ethernet/asix/ax88796c_*
  ASPEED PINCTRL DRIVERS
  M:    Andrew Jeffery <[email protected]>
  L:    [email protected] (moderated for non-subscribers)
@@@ -2962,7 -3013,7 +3013,7 @@@ F:      crypto/async_tx
  F:    include/linux/async_tx.h
  
  AT24 EEPROM DRIVER
- M:    Bartosz Golaszewski <b[email protected]>
+ M:    Bartosz Golaszewski <b[email protected]>
  L:    [email protected]
  S:    Maintained
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git
@@@ -3113,6 -3164,7 +3164,7 @@@ W:      https://github.com/linux-audi
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit.git
  F:    include/asm-generic/audit_*.h
  F:    include/linux/audit.h
+ F:    include/linux/audit_arch.h
  F:    include/uapi/linux/audit.h
  F:    kernel/audit*
  F:    lib/*audit.c
  AUXILIARY DISPLAY DRIVERS
  M:    Miguel Ojeda <[email protected]>
  S:    Maintained
+ F:    Documentation/devicetree/bindings/auxdisplay/
  F:    drivers/auxdisplay/
  F:    include/linux/cfag12864b.h
  
@@@ -3215,6 -3268,12 +3268,12 @@@ F:    drivers/video/backlight
  F:    include/linux/backlight.h
  F:    include/linux/pwm_backlight.h
  
+ BARCO P50 GPIO DRIVER
+ M:    Santosh Kumar Yadav <[email protected]>
+ M:    Peter Korsgaard <[email protected]>
+ S:    Maintained
+ F:    drivers/platform/x86/barco-p50-gpio.c
  BATMAN ADVANCED
  M:    Marek Lindner <[email protected]>
  M:    Simon Wunderlich <[email protected]>
@@@ -3385,9 -3444,11 +3444,11 @@@ F:    Documentation/networking/filter.rs
  F:    Documentation/userspace-api/ebpf/
  F:    arch/*/net/*
  F:    include/linux/bpf*
+ F:    include/linux/btf*
  F:    include/linux/filter.h
  F:    include/trace/events/xdp.h
  F:    include/uapi/linux/bpf*
+ F:    include/uapi/linux/btf*
  F:    include/uapi/linux/filter.h
  F:    kernel/bpf/
  F:    kernel/trace/bpf_trace.c
@@@ -3421,6 -3482,7 +3482,7 @@@ S:      Supporte
  F:    arch/arm64/net/
  
  BPF JIT for MIPS (32-BIT AND 64-BIT)
+ M:    Johan Almbladh <[email protected]>
  M:    Paul Burton <[email protected]>
  L:    [email protected]
  L:    [email protected]
@@@ -3609,6 -3671,8 +3671,8 @@@ F:      arch/arm/mm/cache-b15-rac.
  F:    drivers/bus/brcmstb_gisb.c
  F:    drivers/pci/controller/pcie-brcmstb.c
  N:    brcmstb
+ N:    bcm7038
+ N:    bcm7120
  
  BROADCOM BDC DRIVER
  M:    Al Cooper <[email protected]>
@@@ -3756,7 -3820,7 +3820,7 @@@ L:      [email protected]
  L:    [email protected]
  S:    Supported
  F:    Documentation/devicetree/bindings/net/brcm,bcmgenet.txt
- F:    Documentation/devicetree/bindings/net/brcm,unimac-mdio.txt
+ F:    Documentation/devicetree/bindings/net/brcm,unimac-mdio.yaml
  F:    drivers/net/ethernet/broadcom/genet/
  F:    drivers/net/ethernet/broadcom/unimac.h
  F:    drivers/net/mdio/mdio-bcm-unimac.c
@@@ -3821,7 -3885,6 +3885,6 @@@ F:      drivers/scsi/mpi3mr
  
  BROADCOM NETXTREME-E ROCE DRIVER
  M:    Selvin Xavier <[email protected]>
- M:    Naresh Kumar PBS <[email protected]>
  L:    [email protected]
  S:    Supported
  W:    http://www.broadcom.com
@@@ -4396,7 -4459,7 +4459,7 @@@ CHIPONE ICN8318 I2C TOUCHSCREEN DRIVE
  M:    Hans de Goede <[email protected]>
  L:    [email protected]
  S:    Maintained
- F:    Documentation/devicetree/bindings/input/touchscreen/chipone_icn8318.txt
+ F:    Documentation/devicetree/bindings/input/touchscreen/chipone,icn8318.yaml
  F:    drivers/input/touchscreen/chipone_icn8318.c
  
  CHIPONE ICN8505 I2C TOUCHSCREEN DRIVER
@@@ -4407,14 -4470,12 +4470,12 @@@ F:   drivers/input/touchscreen/chipone_ic
  
  CHROME HARDWARE PLATFORM SUPPORT
  M:    Benson Leung <[email protected]>
- M:    Enric Balletbo i Serra <[email protected]>
  S:    Maintained
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux.git
  F:    drivers/platform/chrome/
  
  CHROMEOS EC CODEC DRIVER
  M:    Cheng-Yi Chiang <[email protected]>
- R:    Enric Balletbo i Serra <[email protected]>
  R:    Guenter Roeck <[email protected]>
  S:    Maintained
  F:    Documentation/devicetree/bindings/sound/google,cros-ec-codec.yaml
@@@ -4422,15 -4483,25 +4483,25 @@@ F:   sound/soc/codecs/cros_ec_codec.
  
  CHROMEOS EC SUBDRIVERS
  M:    Benson Leung <[email protected]>
- M:    Enric Balletbo i Serra <[email protected]>
  R:    Guenter Roeck <[email protected]>
  S:    Maintained
  F:    drivers/power/supply/cros_usbpd-charger.c
  N:    cros_ec
  N:    cros-ec
  
+ CHROMEOS EC USB TYPE-C DRIVER
+ M:    Prashant Malani <[email protected]>
+ S:    Maintained
+ F:    drivers/platform/chrome/cros_ec_typec.c
+ CHROMEOS EC USB PD NOTIFY DRIVER
+ M:    Prashant Malani <[email protected]>
+ S:    Maintained
+ F:    drivers/platform/chrome/cros_usbpd_notify.c
+ F:    include/linux/platform_data/cros_usbpd_notify.h
  CHRONTEL CH7322 CEC DRIVER
- M:    Jeff Chase <jnchase@google.com>
+ M:    Joe Tessler <jrt@google.com>
  L:    [email protected]
  S:    Maintained
  T:    git git://linuxtv.org/media_tree.git
  S:    Maintained
  F:    sound/soc/codecs/cs*
  
+ CIRRUS LOGIC DSP FIRMWARE DRIVER
+ M:    Simon Trimmer <[email protected]>
+ M:    Charles Keepax <[email protected]>
+ M:    Richard Fitzgerald <[email protected]>
+ L:    [email protected]
+ S:    Supported
+ W:    https://github.com/CirrusLogic/linux-drivers/wiki
+ T:    git https://github.com/CirrusLogic/linux-drivers.git
+ F:    drivers/firmware/cirrus/*
+ F:    include/linux/firmware/cirrus/*
  CIRRUS LOGIC EP93XX ETHERNET DRIVER
  M:    Hartley Sweeten <[email protected]>
  L:    [email protected]
@@@ -4594,11 -4676,10 +4676,10 @@@ COCCINELLE/Semantic Patches (SmPL
  M:    Julia Lawall <[email protected]>
  M:    Gilles Muller <[email protected]>
  M:    Nicolas Palix <[email protected]>
- M:    Michal Marek <[email protected]>
- L:    [email protected] (moderated for non-subscribers)
+ L:    [email protected] (moderated for non-subscribers)
  S:    Supported
- W:    http://coccinelle.lip6.fr/
- T:    git git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild.git misc
+ W:    https://coccinelle.gitlabpages.inria.fr/website/
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/jlawall/linux.git
  F:    Documentation/dev-tools/coccinelle.rst
  F:    scripts/coccicheck
  F:    scripts/coccinelle/
@@@ -4656,7 -4737,7 +4737,7 @@@ W:      http://linux-cifs.samba.org
  T:    git git://git.samba.org/sfrench/cifs-2.6.git
  F:    Documentation/admin-guide/cifs/
  F:    fs/cifs/
- F:    fs/cifs_common/
+ F:    fs/smbfs_common/
  
  COMPACTPCI HOTPLUG CORE
  M:    Scott Murray <[email protected]>
@@@ -4804,7 -4885,8 +4885,8 @@@ F:      Documentation/ABI/testing/sysfs-bus-
  F:    Documentation/driver-api/generic-counter.rst
  F:    drivers/counter/
  F:    include/linux/counter.h
- F:    include/linux/counter_enum.h
+ F:    include/uapi/linux/counter.h
+ F:    tools/counter/
  
  CP2615 I2C DRIVER
  M:    Bence Csókás <[email protected]>
  S:    Maintained
  F:    drivers/input/touchscreen/cy8ctma140.c
  
+ CYPRESS STREETFIGHTER TOUCHKEYS DRIVER
+ M:    Yassine Oudjana <[email protected]>
+ L:    [email protected]
+ S:    Maintained
+ F:    Documentation/devicetree/bindings/input/cypress-sf.yaml
+ F:    drivers/input/keyboard/cypress-sf.c
  CYTTSP TOUCHSCREEN DRIVER
  M:    Linus Walleij <[email protected]>
  L:    [email protected]
@@@ -5155,7 -5244,7 +5244,7 @@@ F:      net/ax25/ax25_timer.
  F:    net/ax25/sysctl_net_ax25.c
  
  DATA ACCESS MONITOR
- M:    SeongJae Park <sj[email protected]>
+ M:    SeongJae Park <sj@kernel.org>
  L:    [email protected]
  S:    Maintained
  F:    Documentation/admin-guide/mm/damon/
@@@ -5452,6 -5541,19 +5541,19 @@@ F:    include/net/devlink.
  F:    include/uapi/linux/devlink.h
  F:    net/core/devlink.c
  
+ DH ELECTRONICS IMX6 DHCOM BOARD SUPPORT
+ M:    Christoph Niedermaier <[email protected]>
+ L:    [email protected]
+ S:    Maintained
+ F:    arch/arm/boot/dts/imx6*-dhcom-*
+ DH ELECTRONICS STM32MP1 DHCOM/DHCOR BOARD SUPPORT
+ M:    Marek Vasut <[email protected]>
+ L:    [email protected]
+ S:    Maintained
+ F:    arch/arm/boot/dts/stm32mp1*-dhcom-*
+ F:    arch/arm/boot/dts/stm32mp1*-dhcor-*
  DIALOG SEMICONDUCTOR DRIVERS
  M:    Support Opensource <[email protected]>
  S:    Supported
@@@ -5961,17 -6063,10 +6063,17 @@@ F:   drivers/gpu/drm/panel/panel-novatek-
  
  DRM DRIVER FOR NVIDIA GEFORCE/QUADRO GPUS
  M:    Ben Skeggs <[email protected]>
 +M:    Karol Herbst <[email protected]>
 +M:    Lyude Paul <[email protected]>
  L:    [email protected]
  L:    [email protected]
  S:    Supported
 -T:    git git://github.com/skeggsb/linux
 +W:    https://nouveau.freedesktop.org/
 +Q:    https://patchwork.freedesktop.org/project/nouveau/
 +Q:    https://gitlab.freedesktop.org/drm/nouveau/-/merge_requests
 +B:    https://gitlab.freedesktop.org/drm/nouveau/-/issues
 +C:    irc://irc.oftc.net/nouveau
 +T:    git https://gitlab.freedesktop.org/drm/nouveau.git
  F:    drivers/gpu/drm/nouveau/
  F:    include/uapi/drm/nouveau_drm.h
  
@@@ -6154,8 -6249,7 +6256,7 @@@ T:      git git://anongit.freedesktop.org/dr
  F:    Documentation/devicetree/bindings/display/
  F:    Documentation/devicetree/bindings/gpu/
  F:    Documentation/gpu/
- F:    drivers/gpu/drm/
- F:    drivers/gpu/vga/
+ F:    drivers/gpu/
  F:    include/drm/
  F:    include/linux/vga*
  F:    include/uapi/drm/
@@@ -6299,6 -6393,7 +6400,7 @@@ L:      [email protected]
  S:    Supported
  T:    git git://anongit.freedesktop.org/tegra/linux.git
  F:    Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
+ F:    Documentation/devicetree/bindings/gpu/host1x/
  F:    drivers/gpu/drm/tegra/
  F:    drivers/gpu/host1x/
  F:    include/linux/host1x.h
@@@ -6429,14 -6524,6 +6531,14 @@@ F:    drivers/gpu/drm/drm_panel.
  F:    drivers/gpu/drm/panel/
  F:    include/drm/drm_panel.h
  
 +DRM PRIVACY-SCREEN CLASS
 +M:    Hans de Goede <[email protected]>
 +L:    [email protected]
 +S:    Maintained
 +T:    git git://anongit.freedesktop.org/drm/drm-misc
 +F:    drivers/gpu/drm/drm_privacy_screen*
 +F:    include/drm/drm_privacy_screen*
 +
  DRM TTM SUBSYSTEM
  M:    Christian Koenig <[email protected]>
  M:    Huang Rui <[email protected]>
@@@ -6712,7 -6799,7 +6814,7 @@@ S:      Supporte
  F:    drivers/edac/dmc520_edac.c
  
  EDAC-E752X
- M:    Mark Gross <mark[email protected]>
+ M:    Mark Gross <mark[email protected]>
  L:    [email protected]
  S:    Maintained
  F:    drivers/edac/e752x_edac.c
@@@ -7035,7 -7122,6 +7137,6 @@@ F:      drivers/net/mdio/fwnode_mdio.
  F:    drivers/net/mdio/of_mdio.c
  F:    drivers/net/pcs/
  F:    drivers/net/phy/
- F:    drivers/of/of_net.c
  F:    include/dt-bindings/net/qca-ar803x.h
  F:    include/linux/*mdio*.h
  F:    include/linux/mdio/*.h
@@@ -7047,6 -7133,21 +7148,21 @@@ F:    include/linux/platform_data/mdio-gpi
  F:    include/trace/events/mdio.h
  F:    include/uapi/linux/mdio.h
  F:    include/uapi/linux/mii.h
+ F:    net/core/of_net.c
+ EXEC & BINFMT API
+ R:    Eric Biederman <[email protected]>
+ R:    Kees Cook <[email protected]>
+ F:    arch/alpha/kernel/binfmt_loader.c
+ F:    arch/x86/ia32/ia32_aout.c
+ F:    fs/*binfmt_*.c
+ F:    fs/exec.c
+ F:    include/linux/binfmts.h
+ F:    include/linux/elf.h
+ F:    include/uapi/linux/binfmts.h
+ F:    tools/testing/selftests/exec/
+ N:    asm/elf.h
+ N:    binfmt
  
  EXFAT FILE SYSTEM
  M:    Namjae Jeon <[email protected]>
  S:    Maintained
  F:    drivers/net/ethernet/nvidia/*
  
+ FORTIFY_SOURCE
+ M:    Kees Cook <[email protected]>
+ L:    [email protected]
+ S:    Supported
+ F:    include/linux/fortify-string.h
+ F:    lib/test_fortify/*
+ F:    scripts/test_fortify.sh
+ K:    \b__NO_FORTIFY\b
  FPGA DFL DRIVERS
  M:    Wu Hao <[email protected]>
  R:    Tom Rix <[email protected]>
@@@ -7366,10 -7476,11 +7491,11 @@@ F:   include/uapi/linux/fpga-dfl.
  
  FPGA MANAGER FRAMEWORK
  M:    Moritz Fischer <[email protected]>
+ M:    Wu Hao <[email protected]>
+ M:    Xu Yilun <[email protected]>
  R:    Tom Rix <[email protected]>
  L:    [email protected]
  S:    Maintained
- W:    http://www.rocketboards.org
  Q:    http://patchwork.kernel.org/project/linux-fpga/list/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/mdf/linux-fpga.git
  F:    Documentation/devicetree/bindings/fpga/
@@@ -7463,7 -7574,7 +7589,7 @@@ FREESCALE IMX / MXC FEC DRIVE
  M:    Joakim Zhang <[email protected]>
  L:    [email protected]
  S:    Maintained
- F:    Documentation/devicetree/bindings/net/fsl-fec.txt
+ F:    Documentation/devicetree/bindings/net/fsl,fec.yaml
  F:    drivers/net/ethernet/freescale/fec.h
  F:    drivers/net/ethernet/freescale/fec_main.c
  F:    drivers/net/ethernet/freescale/fec_ptp.c
@@@ -7747,6 -7858,7 +7873,7 @@@ M:      Ingo Molnar <[email protected]
  R:    Peter Zijlstra <[email protected]>
  R:    Darren Hart <[email protected]>
  R:    Davidlohr Bueso <[email protected]>
+ R:    André Almeida <[email protected]>
  L:    [email protected]
  S:    Maintained
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git locking/core
@@@ -7754,7 -7866,7 +7881,7 @@@ F:      Documentation/locking/*futex
  F:    include/asm-generic/futex.h
  F:    include/linux/futex.h
  F:    include/uapi/linux/futex.h
- F:    kernel/futex.c
+ F:    kernel/futex/*
  F:    tools/perf/bench/futex*
  F:    tools/testing/selftests/futex/
  
@@@ -7957,9 -8069,10 +8084,10 @@@ F:    drivers/media/usb/go7007
  
  GOODIX TOUCHSCREEN
  M:    Bastien Nocera <[email protected]>
+ M:    Hans de Goede <[email protected]>
  L:    [email protected]
  S:    Maintained
- F:    drivers/input/touchscreen/goodix.c
+ F:    drivers/input/touchscreen/goodix*
  
  GOOGLE ETHERNET DRIVERS
  M:    Jeroen de Borst <[email protected]>
@@@ -8015,7 -8128,7 +8143,7 @@@ F:      include/linux/gpio/regmap.
  
  GPIO SUBSYSTEM
  M:    Linus Walleij <[email protected]>
- M:    Bartosz Golaszewski <b[email protected]>
+ M:    Bartosz Golaszewski <b[email protected]>
  L:    [email protected]
  S:    Maintained
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git
@@@ -8220,7 -8333,7 +8348,7 @@@ T:      git git://linuxtv.org/anttip/media_t
  F:    drivers/media/usb/hackrf/
  
  HANTRO VPU CODEC DRIVER
- M:    Ezequiel Garcia <ezequiel@collabora.com>
+ M:    Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
  M:    Philipp Zabel <[email protected]>
  L:    [email protected]
  L:    [email protected]
@@@ -8243,6 -8356,7 +8371,7 @@@ L:      [email protected]
  S:    Maintained
  W:    http://hwmon.wiki.kernel.org/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git
+ F:    Documentation/ABI/testing/sysfs-class-hwmon
  F:    Documentation/devicetree/bindings/hwmon/
  F:    Documentation/hwmon/
  F:    drivers/hwmon/
@@@ -8479,7 -8593,6 +8608,6 @@@ M:      John Stultz <[email protected]
  L:    [email protected]
  S:    Maintained
  F:    drivers/misc/hisi_hikey_usb.c
- F:    Documentation/devicetree/bindings/misc/hisilicon-hikey-usb.yaml
  
  HISILICON PMU DRIVER
  M:    Shaokun Zhang <[email protected]>
@@@ -8637,9 -8750,8 +8765,8 @@@ F:      Documentation/devicetree/bindings/ii
  F:    drivers/iio/humidity/hts221*
  
  HUAWEI ETHERNET DRIVER
- M:    Bin Luo <[email protected]>
  L:    [email protected]
- S:    Supported
+ S:    Orphan
  F:    Documentation/networking/device_drivers/ethernet/huawei/hinic.rst
  F:    drivers/net/ethernet/huawei/hinic/
  
@@@ -8689,6 -8801,12 +8816,12 @@@ S:    Maintaine
  T:    git git://linuxtv.org/media_tree.git
  F:    drivers/media/i2c/hi556.c
  
+ HYNIX HI846 SENSOR DRIVER
+ M:    Martin Kepplinger <[email protected]>
+ L:    [email protected]
+ S:    Maintained
+ F:    drivers/media/i2c/hi846.c
  Hyper-V/Azure CORE AND DRIVERS
  M:    "K. Y. Srinivasan" <[email protected]>
  M:    Haiyang Zhang <[email protected]>
@@@ -8736,8 -8854,7 +8869,7 @@@ S:      Supporte
  Q:    http://patchwork.ozlabs.org/project/linux-mtd/list/
  C:    irc://irc.oftc.net/mtd
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git cfi/next
- F:    Documentation/devicetree/bindings/mtd/cypress,hyperflash.txt
- F:    Documentation/devicetree/bindings/mtd/ti,am654-hbmc.txt
+ F:    Documentation/devicetree/bindings/mtd/ti,am654-hbmc.yaml
  F:    drivers/mtd/hyperbus/
  F:    include/linux/mtd/hyperbus.h
  
@@@ -9331,7 -9448,7 +9463,7 @@@ S:      Maintaine
  F:    drivers/platform/x86/intel/atomisp2/led.c
  
  INTEL BIOS SAR INT1092 DRIVER
- M:    Shravan S <[email protected]>
+ M:    Shravan Sudhakar <[email protected]>
  M:    Intel Corporation <[email protected]>
  L:    [email protected]
  S:    Maintained
  S:    Maintained
  F:    drivers/crypto/ixp4xx_crypto.c
  
+ INTEL ISHTP ECLITE DRIVER
+ M:    Sumesh K Naduvalath <[email protected]>
+ L:    [email protected]
+ S:    Supported
+ F:    drivers/platform/x86/intel/ishtp_eclite.c
  INTEL IXP4XX QMGR, NPE, ETHERNET and HSS SUPPORT
  M:    Krzysztof Halasa <[email protected]>
  S:    Maintained
@@@ -9521,14 -9644,14 +9659,14 @@@ F:   include/linux/soc/ixp4xx/qmgr.
  INTEL IXP4XX RANDOM NUMBER GENERATOR SUPPORT
  M:    Deepak Saxena <[email protected]>
  S:    Maintained
- F:    Documentation/devicetree/bindings/display/intel,ixp46x-rng.yaml
+ F:    Documentation/devicetree/bindings/rng/intel,ixp46x-rng.yaml
  F:    drivers/char/hw_random/ixp4xx-rng.c
  
  INTEL KEEM BAY DRM DRIVER
  M:    Anitha Chrisanthus <[email protected]>
  M:    Edmund Dea <[email protected]>
  S:    Maintained
- F:    Documentation/devicetree/bindings/display/intel,kmb_display.yaml
+ F:    Documentation/devicetree/bindings/display/intel,keembay-display.yaml
  F:    drivers/gpu/drm/kmb/
  
  INTEL KEEM BAY OCS AES/SM4 CRYPTO DRIVER
@@@ -9541,6 -9664,17 +9679,17 @@@ F:    drivers/crypto/keembay/keembay-ocs-a
  F:    drivers/crypto/keembay/ocs-aes.c
  F:    drivers/crypto/keembay/ocs-aes.h
  
+ INTEL KEEM BAY OCS ECC CRYPTO DRIVER
+ M:    Daniele Alessandrelli <[email protected]>
+ M:    Prabhjot Khurana <[email protected]>
+ M:    Mark Gross <[email protected]>
+ S:    Maintained
+ F:    Documentation/devicetree/bindings/crypto/intel,keembay-ocs-ecc.yaml
+ F:    drivers/crypto/keembay/Kconfig
+ F:    drivers/crypto/keembay/Makefile
+ F:    drivers/crypto/keembay/keembay-ocs-ecc.c
+ F:    drivers/crypto/keembay/ocs-ecc-curve-defs.h
  INTEL KEEM BAY OCS HCU CRYPTO DRIVER
  M:    Daniele Alessandrelli <[email protected]>
  M:    Declan Murphy <[email protected]>
@@@ -9653,7 -9787,7 +9802,7 @@@ F:      include/uapi/linux/isst_if.
  F:    tools/power/x86/intel-speed-select/
  
  INTEL STRATIX10 FIRMWARE DRIVERS
- M:    Richard Gong <[email protected]>
+ M:    Dinh Nguyen <[email protected]>
  L:    [email protected]
  S:    Maintained
  F:    Documentation/ABI/testing/sysfs-devices-platform-stratix10-rsu
@@@ -10024,6 -10158,7 +10173,7 @@@ JC42.4 TEMPERATURE SENSOR DRIVE
  M:    Guenter Roeck <[email protected]>
  L:    [email protected]
  S:    Maintained
+ F:    Documentation/devicetree/bindings/hwmon/jedec,jc42.yaml
  F:    Documentation/hwmon/jc42.rst
  F:    drivers/hwmon/jc42.c
  
@@@ -10063,6 -10198,7 +10213,7 @@@ F:   include/linux/jbd2.
  JPU V4L2 MEM2MEM DRIVER FOR RENESAS
  M:    Mikhail Ulyanov <[email protected]>
  L:    [email protected]
+ L:    [email protected]
  S:    Maintained
  F:    drivers/media/platform/rcar_jpu.c
  
@@@ -10223,8 -10359,8 +10374,8 @@@ M:   Hyunchul Lee <[email protected]
  L:    [email protected]
  S:    Maintained
  T:    git git://git.samba.org/ksmbd.git
- F:    fs/cifs_common/
  F:    fs/ksmbd/
+ F:    fs/smbfs_common/
  
  KERNEL UNIT TESTING FRAMEWORK (KUnit)
  M:    Brendan Higgins <[email protected]>
@@@ -10289,21 -10425,29 +10440,29 @@@ F:        arch/mips/include/uapi/asm/kvm
  F:    arch/mips/kvm/
  
  KERNEL VIRTUAL MACHINE FOR POWERPC (KVM/powerpc)
- M:    Paul Mackerras <[email protected]>
- L:    [email protected]
- S:    Supported
- W:    http://www.linux-kvm.org/
- T:    git git://github.com/agraf/linux-2.6.git
+ L:    [email protected]
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git topic/ppc-kvm
  F:    arch/powerpc/include/asm/kvm*
  F:    arch/powerpc/include/uapi/asm/kvm*
  F:    arch/powerpc/kernel/kvm*
  F:    arch/powerpc/kvm/
  
+ KERNEL VIRTUAL MACHINE FOR RISC-V (KVM/riscv)
+ M:    Anup Patel <[email protected]>
+ R:    Atish Patra <[email protected]>
+ L:    [email protected]
+ L:    [email protected]
+ L:    [email protected]
+ S:    Maintained
+ T:    git git://github.com/kvm-riscv/linux.git
+ F:    arch/riscv/include/asm/kvm*
+ F:    arch/riscv/include/uapi/asm/kvm*
+ F:    arch/riscv/kvm/
  KERNEL VIRTUAL MACHINE for s390 (KVM/s390)
  M:    Christian Borntraeger <[email protected]>
  M:    Janosch Frank <[email protected]>
  R:    David Hildenbrand <[email protected]>
- R:    Cornelia Huck <[email protected]>
  R:    Claudio Imbrenda <[email protected]>
  L:    [email protected]
  S:    Supported
@@@ -10467,10 -10611,13 +10626,13 @@@ M:        Anil S Keshavamurthy <anil.s.keshava
  M:    "David S. Miller" <[email protected]>
  M:    Masami Hiramatsu <[email protected]>
  S:    Maintained
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace.git
  F:    Documentation/trace/kprobes.rst
  F:    include/asm-generic/kprobes.h
  F:    include/linux/kprobes.h
  F:    kernel/kprobes.c
+ F:    lib/test_kprobes.c
+ F:    samples/kprobes
  
  KS0108 LCD CONTROLLER DRIVER
  M:    Miguel Ojeda <[email protected]>
@@@ -10660,11 -10807,6 +10822,6 @@@ F:  drivers/ata
  F:    include/linux/ata.h
  F:    include/linux/libata.h
  
- LIBLOCKDEP
- M:    Sasha Levin <[email protected]>
- S:    Maintained
- F:    tools/lib/lockdep/
  LIBNVDIMM BLK: MMIO-APERTURE DRIVER
  M:    Dan Williams <[email protected]>
  M:    Vishal Verma <[email protected]>
@@@ -10918,7 -11060,7 +11075,7 @@@ LM90 HARDWARE MONITOR DRIVE
  M:    Jean Delvare <[email protected]>
  L:    [email protected]
  S:    Maintained
- F:    Documentation/devicetree/bindings/hwmon/lm90.txt
+ F:    Documentation/devicetree/bindings/hwmon/national,lm90.yaml
  F:    Documentation/hwmon/lm90.rst
  F:    drivers/hwmon/lm90.c
  F:    include/dt-bindings/thermal/lm90.h
@@@ -11177,6 -11319,7 +11334,7 @@@ S:   Maintaine
  F:    Documentation/devicetree/bindings/net/dsa/marvell.txt
  F:    Documentation/networking/devlink/mv88e6xxx.rst
  F:    drivers/net/dsa/mv88e6xxx/
+ F:    include/linux/dsa/mv88e6xxx.h
  F:    include/linux/platform_data/mv88e6xxx.h
  
  MARVELL ARMADA 3700 PHY DRIVERS
@@@ -11301,7 -11444,6 +11459,6 @@@ F:   Documentation/networking/device_driv
  F:    drivers/net/ethernet/marvell/octeontx2/af/
  
  MARVELL PRESTERA ETHERNET SWITCH DRIVER
- M:    Vadym Kochan <[email protected]>
  M:    Taras Chornyi <[email protected]>
  S:    Supported
  W:    https://github.com/Marvell-switching/switchdev-prestera
@@@ -11395,8 -11537,29 +11552,29 @@@ S: Maintaine
  F:    Documentation/devicetree/bindings/iio/proximity/maxbotix,mb1232.yaml
  F:    drivers/iio/proximity/mb1232.c
  
+ MAXIM MAX17040 FAMILY FUEL GAUGE DRIVERS
+ R:    Iskren Chernev <[email protected]>
+ R:    Krzysztof Kozlowski <[email protected]>
+ R:    Marek Szyprowski <[email protected]>
+ R:    Matheus Castello <[email protected]>
+ L:    [email protected]
+ S:    Maintained
+ F:    Documentation/devicetree/bindings/power/supply/maxim,max17040.yaml
+ F:    drivers/power/supply/max17040_battery.c
+ MAXIM MAX17042 FAMILY FUEL GAUGE DRIVERS
+ R:    Hans de Goede <[email protected]>
+ R:    Krzysztof Kozlowski <[email protected]>
+ R:    Marek Szyprowski <[email protected]>
+ R:    Sebastian Krzyszkowiak <[email protected]>
+ R:    Purism Kernel Team <[email protected]>
+ L:    [email protected]
+ S:    Maintained
+ F:    Documentation/devicetree/bindings/power/supply/maxim,max17042.yaml
+ F:    drivers/power/supply/max17042_battery.c
  MAXIM MAX77650 PMIC MFD DRIVER
- M:    Bartosz Golaszewski <b[email protected]>
+ M:    Bartosz Golaszewski <b[email protected]>
  L:    [email protected]
  S:    Maintained
  F:    Documentation/devicetree/bindings/*/*max77650.yaml
@@@ -11702,6 -11865,7 +11880,7 @@@ T:   git git://linuxtv.org/media_tree.gi
  F:    Documentation/devicetree/bindings/media/renesas,csi2.yaml
  F:    Documentation/devicetree/bindings/media/renesas,isp.yaml
  F:    Documentation/devicetree/bindings/media/renesas,vin.yaml
+ F:    drivers/media/platform/rcar-isp.c
  F:    drivers/media/platform/rcar-vin/
  
  MEDIA DRIVERS FOR RENESAS - VSP1
@@@ -11847,7 -12011,9 +12026,9 @@@ F:   drivers/mmc/host/mtk-sd.
  MEDIATEK MT76 WIRELESS LAN DRIVER
  M:    Felix Fietkau <[email protected]>
  M:    Lorenzo Bianconi <[email protected]>
- R:    Ryder Lee <[email protected]>
+ M:    Ryder Lee <[email protected]>
+ R:    Shayne Chen <[email protected]>
+ R:    Sean Wang <[email protected]>
  L:    [email protected]
  S:    Maintained
  F:    drivers/net/wireless/mediatek/mt76/
@@@ -11871,6 -12037,12 +12052,12 @@@ S: Maintaine
  F:    Documentation/devicetree/bindings/i2c/i2c-mt7621.txt
  F:    drivers/i2c/busses/i2c-mt7621.c
  
+ MEDIATEK MT7621 PCIE CONTROLLER DRIVER
+ M:    Sergio Paracuellos <[email protected]>
+ S:    Maintained
+ F:    Documentation/devicetree/bindings/pci/mediatek,mt7621-pcie.yaml
+ F:    drivers/pci/controller/pcie-mt7621.c
  MEDIATEK MT7621 PHY PCI DRIVER
  M:    Sergio Paracuellos <[email protected]>
  S:    Maintained
  S:    Maintained
  F:    drivers/char/hw_random/mtk-rng.c
  
+ MEDIATEK SMI DRIVER
+ M:    Yong Wu <[email protected]>
+ L:    [email protected] (moderated for non-subscribers)
+ S:    Supported
+ F:    Documentation/devicetree/bindings/memory-controllers/mediatek,smi*
+ F:    drivers/memory/mtk-smi.c
+ F:    include/soc/mediatek/smi.h
  MEDIATEK SWITCH DRIVER
  M:    Sean Wang <[email protected]>
  M:    Landen Chao <[email protected]>
@@@ -12008,7 -12188,7 +12203,7 @@@ F:   drivers/net/ethernet/mellanox/mlxfw
  
  MELLANOX HARDWARE PLATFORM SUPPORT
  M:    Hans de Goede <[email protected]>
- M:    Mark Gross <m[email protected]>
+ M:    Mark Gross <m[email protected]>
  M:    Vadim Pasternak <[email protected]>
  L:    [email protected]
  S:    Supported
@@@ -12220,7 -12400,8 +12415,8 @@@ F:   arch/arm64/boot/dts/marvell/armada-3
  
  MHI BUS
  M:    Manivannan Sadhasivam <[email protected]>
- M:    Hemant Kumar <[email protected]>
+ R:    Hemant Kumar <[email protected]>
+ L:    [email protected]
  L:    [email protected]
  S:    Maintained
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/mani/mhi.git
  S:    Maintained
  F:    drivers/crypto/atmel-ecc.*
  
+ MICROCHIP EIC DRIVER
+ M:    Claudiu Beznea <[email protected]>
+ L:    [email protected] (moderated for non-subscribers)
+ S:    Supported
+ F:    drivers/irqchip/irq-mchp-eic.c
  MICROCHIP I2C DRIVER
  M:    Codrin Ciubotariu <[email protected]>
  L:    [email protected]
@@@ -12460,7 -12647,7 +12662,7 @@@ F:   drivers/platform/surface/surface_gpe
  
  MICROSOFT SURFACE HARDWARE PLATFORM SUPPORT
  M:    Hans de Goede <[email protected]>
- M:    Mark Gross <m[email protected]>
+ M:    Mark Gross <m[email protected]>
  M:    Maximilian Luz <[email protected]>
  L:    [email protected]
  S:    Maintained
@@@ -12777,6 -12964,7 +12979,7 @@@ M:   Laurent Pinchart <laurent.pinchart@i
  L:    [email protected]
  S:    Maintained
  T:    git git://linuxtv.org/media_tree.git
+ F:    Documentation/devicetree/bindings/media/i2c/aptina,mt9p031.yaml
  F:    drivers/media/i2c/mt9p031.c
  F:    include/media/i2c/mt9p031.h
  
@@@ -13071,6 -13259,7 +13274,7 @@@ F:   include/linux/dsa
  F:    include/linux/platform_data/dsa.h
  F:    include/net/dsa.h
  F:    net/dsa/
+ F:    tools/testing/selftests/drivers/net/dsa/
  
  NETWORKING [GENERAL]
  M:    "David S. Miller" <[email protected]>
@@@ -13283,10 -13472,16 +13487,16 @@@ W:        http://www.netlab.is.tsukuba.ac.jp/~
  F:    Documentation/scsi/NinjaSCSI.rst
  F:    drivers/scsi/nsp32*
  
+ NINTENDO HID DRIVER
+ M:    Daniel J. Ogorchock <[email protected]>
+ L:    [email protected]
+ S:    Maintained
+ F:    drivers/hid/hid-nintendo*
  NIOS2 ARCHITECTURE
- M:    Ley Foon Tan <[email protected]>
+ M:    Dinh Nguyen <[email protected]>
  S:    Maintained
- T:    git git://git.kernel.org/pub/scm/linux/kernel/git/lftan/nios2.git
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/dinguyen/linux.git
  F:    arch/nios2/
  
  NITRO ENCLAVES (NE)
@@@ -13412,6 -13607,12 +13622,12 @@@ S: Maintaine
  F:    drivers/video/fbdev/nvidia/
  F:    drivers/video/fbdev/riva/
  
+ NVIDIA WMI EC BACKLIGHT DRIVER
+ M:    Daniel Dadap <[email protected]>
+ L:    [email protected]
+ S:    Supported
+ F:    drivers/platform/x86/nvidia-wmi-ec-backlight.c
  NVM EXPRESS DRIVER
  M:    Keith Busch <[email protected]>
  M:    Jens Axboe <[email protected]>
@@@ -13466,7 -13667,7 +13682,7 @@@ M:   Ashish Kumar <[email protected]
  R:    Yogesh Gaur <[email protected]>
  L:    [email protected]
  S:    Maintained
- F:    Documentation/devicetree/bindings/spi/spi-nxp-fspi.txt
+ F:    Documentation/devicetree/bindings/spi/spi-nxp-fspi.yaml
  F:    drivers/spi/spi-nxp-fspi.c
  
  NXP FXAS21002C DRIVER
@@@ -13494,6 -13695,13 +13710,13 @@@ S: Maintaine
  F:    Documentation/devicetree/bindings/display/imx/nxp,imx8mq-dcss.yaml
  F:    drivers/gpu/drm/imx/dcss/
  
+ NXP i.MX 8QXP ADC DRIVER
+ M:    Cai Huoqing <[email protected]>
+ L:    [email protected]
+ S:    Supported
+ F:    Documentation/devicetree/bindings/iio/adc/nxp,imx8qxp-adc.yaml
+ F:    drivers/iio/adc/imx8qxp-adc.c
  NXP PF8100/PF8121A/PF8200 PMIC REGULATOR DEVICE DRIVER
  M:    Jagan Teki <[email protected]>
  S:    Maintained
@@@ -13549,6 -13757,7 +13772,7 @@@ NXP-NCI NFC DRIVE
  R:    Charles Gorand <[email protected]>
  L:    [email protected] (subscribers-only)
  S:    Supported
+ F:    Documentation/devicetree/bindings/net/nfc/nxp,nci.yaml
  F:    drivers/nfc/nxp-nci
  
  NXP i.MX 8QXP/8QM JPEG V4L2 DRIVER
@@@ -13556,7 -13765,7 +13780,7 @@@ M:   Mirela Rabulea <[email protected]
  R:    NXP Linux Team <[email protected]>
  L:    [email protected]
  S:    Maintained
- F:    Documentation/devicetree/bindings/media/imx8-jpeg.yaml
+ F:    Documentation/devicetree/bindings/media/nxp,imx8-jpeg.yaml
  F:    drivers/media/platform/imx-jpeg
  
  NZXT-KRAKEN2 HARDWARE MONITORING DRIVER
@@@ -13829,6 -14038,13 +14053,13 @@@ S: Maintaine
  T:    git git://linuxtv.org/media_tree.git
  F:    drivers/media/i2c/ov13858.c
  
+ OMNIVISION OV13B10 SENSOR DRIVER
+ M:    Arec Kao <[email protected]>
+ L:    [email protected]
+ S:    Maintained
+ T:    git git://linuxtv.org/media_tree.git
+ F:    drivers/media/i2c/ov13b10.c
  OMNIVISION OV2680 SENSOR DRIVER
  M:    Rui Miguel Silva <[email protected]>
  L:    [email protected]
@@@ -14196,7 -14412,9 +14427,9 @@@ M:   Juergen Gross <[email protected]
  M:    Deep Shah <[email protected]>
  M:    "VMware, Inc." <[email protected]>
  L:    [email protected]
+ L:    [email protected]
  S:    Supported
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86/core
  F:    Documentation/virt/paravirt_ops.rst
  F:    arch/*/include/asm/paravirt*.h
  F:    arch/*/kernel/paravirt*
@@@ -14469,9 -14687,12 +14702,12 @@@ M: Lorenzo Pieralisi <lorenzo.pieralisi
  R:    Krzysztof Wilczyński <[email protected]>
  L:    [email protected]
  S:    Supported
+ Q:    https://patchwork.kernel.org/project/linux-pci/list/
+ B:    https://bugzilla.kernel.org
+ C:    irc://irc.oftc.net/linux-pci
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/pci.git
  F:    Documentation/PCI/endpoint/*
  F:    Documentation/misc-devices/pci-endpoint-test.rst
- T:    git git://git.kernel.org/pub/scm/linux/kernel/git/kishon/pci-endpoint.git
  F:    drivers/misc/pci_endpoint_test.c
  F:    drivers/pci/endpoint/
  F:    tools/pci/
@@@ -14517,15 -14738,21 +14753,21 @@@ R:        Rob Herring <[email protected]
  R:    Krzysztof Wilczyński <[email protected]>
  L:    [email protected]
  S:    Supported
- Q:    http://patchwork.ozlabs.org/project/linux-pci/list/
- T:    git git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/pci.git/
+ Q:    https://patchwork.kernel.org/project/linux-pci/list/
+ B:    https://bugzilla.kernel.org
+ C:    irc://irc.oftc.net/linux-pci
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/pci.git
  F:    drivers/pci/controller/
+ F:    drivers/pci/pci-bridge-emul.c
+ F:    drivers/pci/pci-bridge-emul.h
  
  PCI SUBSYSTEM
  M:    Bjorn Helgaas <[email protected]>
  L:    [email protected]
  S:    Supported
- Q:    http://patchwork.ozlabs.org/project/linux-pci/list/
+ Q:    https://patchwork.kernel.org/project/linux-pci/list/
+ B:    https://bugzilla.kernel.org
+ C:    irc://irc.oftc.net/linux-pci
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git
  F:    Documentation/PCI/
  F:    Documentation/devicetree/bindings/pci/
@@@ -14625,7 -14852,15 +14867,15 @@@ M: Stanimir Varbanov <svarbanov@mm-sol.
  L:    [email protected]
  L:    [email protected]
  S:    Maintained
- F:    drivers/pci/controller/dwc/*qcom*
+ F:    drivers/pci/controller/dwc/pcie-qcom.c
+ PCIE ENDPOINT DRIVER FOR QUALCOMM
+ M:    Manivannan Sadhasivam <[email protected]>
+ L:    [email protected]
+ L:    [email protected]
+ S:    Maintained
+ F:    Documentation/devicetree/bindings/pci/qcom,pcie-ep.yaml
+ F:    drivers/pci/controller/dwc/pcie-qcom-ep.c
  
  PCIE DRIVER FOR ROCKCHIP
  M:    Shawn Lin <[email protected]>
  S:    Maintained
  F:    drivers/pinctrl/pinctrl-single.c
  
- PIN CONTROLLER - ST SPEAR
- M:    Viresh Kumar <[email protected]>
- L:    [email protected] (moderated for non-subscribers)
- S:    Maintained
- W:    http://www.st.com/spear
- F:    drivers/pinctrl/spear/
  PKTCDVD DRIVER
  M:    [email protected]
  S:    Orphan
@@@ -14937,7 -15165,6 +15180,6 @@@ S:   Maintaine
  W:    http://hwmon.wiki.kernel.org/
  W:    http://www.roeck-us.net/linux/drivers/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git
- F:    Documentation/devicetree/bindings/hwmon/ibm,cffps1.txt
  F:    Documentation/devicetree/bindings/hwmon/ltc2978.txt
  F:    Documentation/devicetree/bindings/hwmon/max31785.txt
  F:    Documentation/hwmon/adm1275.rst
@@@ -15176,7 -15403,7 +15418,7 @@@ S:   Maintaine
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/pstore
  F:    Documentation/admin-guide/ramoops.rst
  F:    Documentation/admin-guide/pstore-blk.rst
- F:    Documentation/devicetree/bindings/reserved-memory/ramoops.txt
+ F:    Documentation/devicetree/bindings/reserved-memory/ramoops.yaml
  F:    drivers/acpi/apei/erst.c
  F:    drivers/firmware/efi/efi-pstore.c
  F:    fs/pstore/
  L:    [email protected]
  S:    Supported
  W:    https://wireless.wiki.kernel.org/en/users/Drivers/ath9k
+ F:    Documentation/devicetree/bindings/net/wireless/qca,ath9k.yaml
  F:    drivers/net/wireless/ath/ath9k/
  
  QUALCOMM CAMERA SUBSYSTEM DRIVER
@@@ -15602,6 -15830,14 +15845,14 @@@ S: Maintaine
  F:    Documentation/devicetree/bindings/regulator/vqmmc-ipq4019-regulator.yaml
  F:    drivers/regulator/vqmmc-ipq4019-regulator.c
  
+ QUALCOMM NAND CONTROLLER DRIVER
+ M:    Manivannan Sadhasivam <[email protected]>
+ L:    [email protected]
+ L:    [email protected]
+ S:    Maintained
+ F:    Documentation/devicetree/bindings/mtd/qcom,nandc.yaml
+ F:    drivers/mtd/nand/raw/qcom_nandc.c
  QUALCOMM RMNET DRIVER
  M:    Subash Abhinov Kasiviswanathan <[email protected]>
  M:    Sean Tranchetti <[email protected]>
  S:    Maintained
  F:    drivers/net/wireless/realtek/rtw88/
  
+ REALTEK WIRELESS DRIVER (rtw89)
+ M:    Ping-Ke Shih <[email protected]>
+ L:    [email protected]
+ S:    Maintained
+ F:    drivers/net/wireless/realtek/rtw89/
  REDPINE WIRELESS DRIVER
  M:    Amitkumar Karwar <[email protected]>
  M:    Siva Rebbagondla <[email protected]>
@@@ -15934,7 -16176,7 +16191,7 @@@ M:   Bjorn Andersson <bjorn.andersson@lin
  M:    Mathieu Poirier <[email protected]>
  L:    [email protected]
  S:    Maintained
- T:    git git://git.kernel.org/pub/scm/linux/kernel/git/andersson/remoteproc.git rproc-next
+ T:    git https://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux.git rproc-next
  F:    Documentation/ABI/testing/sysfs-class-remoteproc
  F:    Documentation/devicetree/bindings/remoteproc/
  F:    Documentation/staging/remoteproc.rst
@@@ -15948,7 -16190,7 +16205,7 @@@ M:   Bjorn Andersson <bjorn.andersson@lin
  M:    Mathieu Poirier <[email protected]>
  L:    [email protected]
  S:    Maintained
- T:    git git://git.kernel.org/pub/scm/linux/kernel/git/andersson/remoteproc.git rpmsg-next
+ T:    git https://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux.git rpmsg-next
  F:    Documentation/ABI/testing/sysfs-bus-rpmsg
  F:    Documentation/staging/rpmsg.rst
  F:    drivers/rpmsg/
@@@ -16127,6 -16369,13 +16384,13 @@@ F: Documentation/ABI/*/sysfs-driver-hid
  F:    drivers/hid/hid-roccat*
  F:    include/linux/hid-roccat*
  
+ ROCKCHIP I2S TDM DRIVER
+ M:    Nicolas Frattaroli <[email protected]>
+ L:    [email protected]
+ S:    Maintained
+ F:    Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml
+ F:    sound/soc/rockchip/rockchip_i2s_tdm.*
  ROCKCHIP ISP V1 DRIVER
  M:    Helen Koike <[email protected]>
  M:    Dafna Hirschfeld <[email protected]>
@@@ -16141,7 -16390,7 +16405,7 @@@ F:   include/uapi/linux/rkisp1-config.
  
  ROCKCHIP RASTER 2D GRAPHIC ACCELERATION UNIT DRIVER
  M:    Jacob Chen <[email protected]>
- M:    Ezequiel Garcia <ezequiel@collabora.com>
+ M:    Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
  L:    [email protected]
  L:    [email protected]
  S:    Maintained
@@@ -16149,7 -16398,7 +16413,7 @@@ F:   Documentation/devicetree/bindings/me
  F:    drivers/media/platform/rockchip/rga/
  
  ROCKCHIP VIDEO DECODER DRIVER
- M:    Ezequiel Garcia <ezequiel@collabora.com>
+ M:    Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
  L:    [email protected]
  L:    [email protected]
  S:    Maintained
  M:    Heiko Carstens <[email protected]>
  M:    Vasily Gorbik <[email protected]>
  M:    Christian Borntraeger <[email protected]>
+ R:    Alexander Gordeev <[email protected]>
  L:    [email protected]
  S:    Supported
  W:    http://www.ibm.com/developerworks/linux/linux390/
@@@ -16403,7 -16653,6 +16668,6 @@@ F:   drivers/s390/crypto/vfio_ap_ops.
  F:    drivers/s390/crypto/vfio_ap_private.h
  
  S390 VFIO-CCW DRIVER
- M:    Cornelia Huck <[email protected]>
  M:    Eric Farman <[email protected]>
  M:    Matthew Rosato <[email protected]>
  R:    Halil Pasic <[email protected]>
@@@ -16532,10 -16781,11 +16796,11 @@@ M:        Bartlomiej Zolnierkiewicz <b.zolnier
  L:    [email protected]
  L:    [email protected]
  S:    Supported
- F:    Documentation/devicetree/bindings/clock/samsung,s2mps11.txt
- F:    Documentation/devicetree/bindings/mfd/samsung,sec-core.txt
- F:    Documentation/devicetree/bindings/regulator/samsung,s2m*.txt
- F:    Documentation/devicetree/bindings/regulator/samsung,s5m*.txt
+ F:    Documentation/devicetree/bindings/clock/samsung,s2mps11.yaml
+ F:    Documentation/devicetree/bindings/mfd/samsung,s2m*.yaml
+ F:    Documentation/devicetree/bindings/mfd/samsung,s5m*.yaml
+ F:    Documentation/devicetree/bindings/regulator/samsung,s2m*.yaml
+ F:    Documentation/devicetree/bindings/regulator/samsung,s5m*.yaml
  F:    drivers/clk/clk-s2mps11.c
  F:    drivers/mfd/sec*.c
  F:    drivers/regulator/s2m*.c
@@@ -16680,13 -16930,6 +16945,6 @@@ M:  Lubomir Rintel <[email protected]
  S:    Supported
  F:    drivers/char/pcmcia/scr24x_cs.c
  
- SCSI CDROM DRIVER
- M:    Jens Axboe <[email protected]>
- L:    [email protected]
- S:    Maintained
- W:    http://www.kernel.dk
- F:    drivers/scsi/sr*
  SCSI RDMA PROTOCOL (SRP) INITIATOR
  M:    Bart Van Assche <[email protected]>
  L:    [email protected]
@@@ -16826,7 -17069,6 +17084,6 @@@ M:   Adrian Hunter <[email protected]
  L:    [email protected]
  S:    Maintained
  F:    drivers/mmc/host/sdhci*
- F:    include/linux/mmc/sdhci*
  
  SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) MICROCHIP DRIVER
  M:    Eugen Hristev <[email protected]>
@@@ -16901,6 -17143,13 +17158,13 @@@ S: Maintaine
  F:    drivers/misc/phantom.c
  F:    include/uapi/linux/phantom.h
  
+ SENSEAIR SUNRISE 006-0-0007
+ M:    Jacopo Mondi <[email protected]>
+ S:    Maintained
+ F:    Documentation/ABI/testing/sysfs-bus-iio-chemical-sunrise-co2
+ F:    Documentation/devicetree/bindings/iio/chemical/senseair,sunrise.yaml
+ F:    drivers/iio/chemical/sunrise_co2.c
  SENSIRION SCD30 CARBON DIOXIDE SENSOR DRIVER
  M:    Tomasz Duszynski <[email protected]>
  S:    Maintained
@@@ -16910,6 -17159,12 +17174,12 @@@ F: drivers/iio/chemical/scd30_core.
  F:    drivers/iio/chemical/scd30_i2c.c
  F:    drivers/iio/chemical/scd30_serial.c
  
+ SENSIRION SCD4X CARBON DIOXIDE SENSOR DRIVER
+ M:    Roan van Dijk <[email protected]>
+ S:    Maintained
+ F:    Documentation/devicetree/bindings/iio/chemical/sensirion,scd4x.yaml
+ F:    drivers/iio/chemical/scd4x.c
  SENSIRION SGP40 GAS SENSOR DRIVER
  M:    Andreas Klinger <[email protected]>
  S:    Maintained
@@@ -16985,7 -17240,6 +17255,6 @@@ F:   drivers/misc/sgi-xp
  
  SHARED MEMORY COMMUNICATIONS (SMC) SOCKETS
  M:    Karsten Graul <[email protected]>
- M:    Guvenc Gulce <[email protected]>
  L:    [email protected]
  S:    Supported
  W:    http://www.ibm.com/developerworks/linux/linux390/
@@@ -17662,21 -17916,17 +17931,17 @@@ W:        https://github.com/linux-speakup/spe
  B:    https://github.com/linux-speakup/speakup/issues
  F:    drivers/accessibility/speakup/
  
- SPEAR CLOCK FRAMEWORK SUPPORT
- M:    Viresh Kumar <[email protected]>
- L:    [email protected] (moderated for non-subscribers)
- S:    Maintained
- W:    http://www.st.com/spear
- F:    drivers/clk/spear/
- SPEAR PLATFORM SUPPORT
+ SPEAR PLATFORM/CLOCK/PINCTRL SUPPORT
  M:    Viresh Kumar <[email protected]>
  M:    Shiraz Hashim <[email protected]>
+ M:    [email protected]
  L:    [email protected] (moderated for non-subscribers)
  S:    Maintained
  W:    http://www.st.com/spear
  F:    arch/arm/boot/dts/spear*
  F:    arch/arm/mach-spear/
+ F:    drivers/clk/spear/
+ F:    drivers/pinctrl/spear/
  
  SPI NOR SUBSYSTEM
  M:    Tudor Ambarus <[email protected]>
@@@ -17688,6 -17938,7 +17953,7 @@@ W:   http://www.linux-mtd.infradead.org
  Q:    http://patchwork.ozlabs.org/project/linux-mtd/list/
  C:    irc://irc.oftc.net/mtd
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git spi-nor/next
+ F:    Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml
  F:    drivers/mtd/spi-nor/
  F:    include/linux/mtd/spi-nor.h
  
@@@ -17830,7 -18081,6 +18096,6 @@@ F:   drivers/staging/nvec
  
  STAGING - OLPC SECONDARY DISPLAY CONTROLLER (DCON)
  M:    Jens Frederich <[email protected]>
- M:    Daniel Drake <[email protected]>
  M:    Jon Nettleton <[email protected]>
  S:    Maintained
  W:    http://wiki.laptop.org/go/DCON
@@@ -17921,7 -18171,8 +18186,8 @@@ M:   Olivier Moysan <olivier.moysan@foss.
  M:    Arnaud Pouliquen <[email protected]>
  L:    [email protected] (moderated for non-subscribers)
  S:    Maintained
- F:    Documentation/devicetree/bindings/iio/adc/st,stm32-*.yaml
+ F:    Documentation/devicetree/bindings/iio/adc/st,stm32-dfsdm-adc.yaml
+ F:    Documentation/devicetree/bindings/sound/st,stm32-*.yaml
  F:    sound/soc/stm/
  
  STM32 TIMER/LPTIMER DRIVERS
@@@ -17998,10 -18249,11 +18264,11 @@@ F:        Documentation/admin-guide/svga.rs
  F:    arch/x86/boot/video*
  
  SWIOTLB SUBSYSTEM
- M:    Konrad Rzeszutek Wilk <[email protected]>
+ M:    Christoph Hellwig <[email protected]>
  L:    [email protected]
  S:    Supported
- T:    git git://git.kernel.org/pub/scm/linux/kernel/git/konrad/swiotlb.git
+ W:    http://git.infradead.org/users/hch/dma-mapping.git
+ T:    git git://git.infradead.org/users/hch/dma-mapping.git
  F:    arch/*/kernel/pci-swiotlb.c
  F:    include/linux/swiotlb.h
  F:    kernel/dma/swiotlb.c
@@@ -18017,7 -18269,7 +18284,7 @@@ F:   net/switchdev
  SY8106A REGULATOR DRIVER
  M:    Icenowy Zheng <[email protected]>
  S:    Maintained
- F:    Documentation/devicetree/bindings/regulator/sy8106a-regulator.txt
+ F:    Documentation/devicetree/bindings/regulator/silergy,sy8106a.yaml
  F:    drivers/regulator/sy8106a-regulator.c
  
  SYNC FILE FRAMEWORK
@@@ -18489,7 -18741,7 +18756,7 @@@ S:   Supporte
  F:    drivers/net/ethernet/tehuti/*
  
  TELECOM CLOCK DRIVER FOR MCPL0010
- M:    Mark Gross <mark[email protected]>
+ M:    Mark Gross <mark[email protected]>
  S:    Supported
  F:    drivers/char/tlclk.c
  
@@@ -18542,7 -18794,7 +18809,7 @@@ M:   Santosh Shilimkar <[email protected]
  L:    [email protected] (moderated for non-subscribers)
  S:    Maintained
  F:    Documentation/devicetree/bindings/arm/keystone/ti,k3-sci-common.yaml
- F:    Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
+ F:    Documentation/devicetree/bindings/arm/keystone/ti,sci.yaml
  F:    Documentation/devicetree/bindings/clock/ti,sci-clk.yaml
  F:    Documentation/devicetree/bindings/interrupt-controller/ti,sci-inta.yaml
  F:    Documentation/devicetree/bindings/interrupt-controller/ti,sci-intr.yaml
@@@ -18584,14 -18836,17 +18851,17 @@@ T:        git git://linuxtv.org/media_tree.gi
  F:    drivers/media/radio/radio-raremono.c
  
  THERMAL
- M:    Zhang Rui <[email protected]>
+ M:    Rafael J. Wysocki <[email protected]>
  M:    Daniel Lezcano <[email protected]>
  R:    Amit Kucheria <[email protected]>
+ R:    Zhang Rui <[email protected]>
  L:    [email protected]
  S:    Supported
  Q:    https://patchwork.kernel.org/project/linux-pm/list/
- T:    git git://git.kernel.org/pub/scm/linux/kernel/git/thermal/linux.git
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git thermal
+ F:    Documentation/ABI/testing/sysfs-class-thermal
  F:    Documentation/devicetree/bindings/thermal/
+ F:    Documentation/driver-api/thermal/
  F:    drivers/thermal/
  F:    include/linux/cpu_cooling.h
  F:    include/linux/thermal.h
@@@ -18719,7 -18974,7 +18989,7 @@@ F:   include/linux/clk/ti.
  
  TI DAVINCI MACHINE SUPPORT
  M:    Sekhar Nori <[email protected]>
- R:    Bartosz Golaszewski <b[email protected]>
+ R:    Bartosz Golaszewski <b[email protected]>
  L:    [email protected] (moderated for non-subscribers)
  S:    Supported
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/nsekhar/linux-davinci.git
@@@ -18809,7 -19064,7 +19079,7 @@@ M:   Mark Greer <[email protected]
  L:    [email protected]
  L:    [email protected] (subscribers-only)
  S:    Supported
- F:    Documentation/devicetree/bindings/net/nfc/trf7970a.txt
+ F:    Documentation/devicetree/bindings/net/nfc/ti,trf7970a.yaml
  F:    drivers/nfc/trf7970a.c
  
  TI TSC2046 ADC DRIVER
@@@ -19004,7 -19259,7 +19274,7 @@@ TRACIN
  M:    Steven Rostedt <[email protected]>
  M:    Ingo Molnar <[email protected]>
  S:    Maintained
- T:    git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git perf/core
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace.git
  F:    Documentation/trace/ftrace.rst
  F:    arch/*/*/*/ftrace.h
  F:    arch/*/kernel/ftrace.c
@@@ -19318,13 -19573,12 +19588,12 @@@ S:        Maintaine
  F:    drivers/usb/misc/chaoskey.c
  
  USB CYPRESS C67X00 DRIVER
- M:    Peter Korsgaard <[email protected]>
  L:    [email protected]
- S:    Maintained
+ S:    Orphan
  F:    drivers/usb/c67x00/
  
  USB DAVICOM DM9601 DRIVER
- M:    Peter Korsgaard <[email protected]>
+ M:    Peter Korsgaard <[email protected]>
  L:    [email protected]
  S:    Maintained
  W:    http://www.linux-usb.org/usbnet
@@@ -19913,8 -20167,6 +20182,8 @@@ F:   include/uapi/linux/virtio_gpio.
  VIRTIO GPU DRIVER
  M:    David Airlie <[email protected]>
  M:    Gerd Hoffmann <[email protected]>
 +R:    Gurchetan Singh <[email protected]>
 +R:    Chia-I Wu <[email protected]>
  L:    [email protected]
  L:    [email protected]
  S:    Maintained
@@@ -19965,7 -20217,7 +20234,7 @@@ F:   include/uapi/linux/virtio_snd.
  F:    sound/virtio/*
  
  VIRTIO I2C DRIVER
- M:    Jie Deng <jie.deng@intel.com>
+ M:    Conghui Chen <conghui.chen@intel.com>
  M:    Viresh Kumar <[email protected]>
  L:    [email protected]
  L:    [email protected]
@@@ -19973,6 -20225,13 +20242,13 @@@ S: Maintaine
  F:    drivers/i2c/busses/i2c-virtio.c
  F:    include/uapi/linux/virtio_i2c.h
  
+ VIRTIO PMEM DRIVER
+ M:    Pankaj Gupta <[email protected]>
+ L:    [email protected]
+ S:    Maintained
+ F:    drivers/nvdimm/virtio_pmem.c
+ F:    drivers/nvdimm/nd_virtio.c
  VIRTUAL BOX GUEST DEVICE DRIVER
  M:    Hans de Goede <[email protected]>
  M:    Arnd Bergmann <[email protected]>
@@@ -20368,6 -20627,7 +20644,7 @@@ X86 ARCHITECTURE (32-BIT AND 64-BIT
  M:    Thomas Gleixner <[email protected]>
  M:    Ingo Molnar <[email protected]>
  M:    Borislav Petkov <[email protected]>
+ M:    Dave Hansen <[email protected]>
  M:    [email protected]
  R:    "H. Peter Anvin" <[email protected]>
  L:    [email protected]
@@@ -20389,6 -20649,8 +20666,8 @@@ M:   Tony Luck <[email protected]
  M:    Borislav Petkov <[email protected]>
  L:    [email protected]
  S:    Maintained
+ F:    Documentation/ABI/testing/sysfs-mce
+ F:    Documentation/x86/x86_64/machinecheck.rst
  F:    arch/x86/kernel/cpu/mce/*
  
  X86 MICROCODE UPDATE SUPPORT
@@@ -20407,7 -20669,7 +20686,7 @@@ F:   arch/x86/mm
  
  X86 PLATFORM DRIVERS
  M:    Hans de Goede <[email protected]>
- M:    Mark Gross <m[email protected]>
+ M:    Mark Gross <m[email protected]>
  L:    [email protected]
  S:    Maintained
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86.git
@@@ -20506,7 -20768,6 +20785,6 @@@ F:   samples/bpf/xdpsock
  F:    tools/lib/bpf/xsk*
  
  XEN BLOCK SUBSYSTEM
- M:    Konrad Rzeszutek Wilk <[email protected]>
  M:    Roger Pau Monné <[email protected]>
  L:    [email protected] (moderated for non-subscribers)
  S:    Supported
@@@ -20554,7 -20815,7 +20832,7 @@@ S:   Supporte
  F:    drivers/net/xen-netback/*
  
  XEN PCI SUBSYSTEM
- M:    Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+ M:    Juergen Gross <jgross@suse.com>
  L:    [email protected] (moderated for non-subscribers)
  S:    Supported
  F:    arch/x86/pci/*xen*
@@@ -20577,7 -20838,8 +20855,8 @@@ S:   Supporte
  F:    sound/xen/*
  
  XEN SWIOTLB SUBSYSTEM
- M:    Konrad Rzeszutek Wilk <[email protected]>
+ M:    Juergen Gross <[email protected]>
+ M:    Stefano Stabellini <[email protected]>
  L:    [email protected] (moderated for non-subscribers)
  L:    [email protected]
  S:    Supported
@@@ -20736,7 -20998,6 +21015,6 @@@ S:   Maintaine
  F:    mm/zbud.c
  
  ZD1211RW WIRELESS DRIVER
- M:    Daniel Drake <[email protected]>
  M:    Ulrich Kunitz <[email protected]>
  L:    [email protected]
  L:    [email protected] (subscribers-only)
@@@ -20819,6 -21080,18 +21097,18 @@@ F: Documentation/vm/zsmalloc.rs
  F:    include/linux/zsmalloc.h
  F:    mm/zsmalloc.c
  
+ ZSTD
+ M:    Nick Terrell <[email protected]>
+ S:    Maintained
+ B:    https://github.com/facebook/zstd/issues
+ T:    git git://github.com/terrelln/linux.git
+ F:    include/linux/zstd*
+ F:    lib/zstd/
+ F:    lib/decompress_unzstd.c
+ F:    crypto/zstd.c
+ N:    zstd
+ K:    zstd
  ZSWAP COMPRESSED SWAP CACHING
  M:    Seth Jennings <[email protected]>
  M:    Dan Streetman <[email protected]>
index 385cd037325ef34749149e85f95f090647780b39,6437b2e978fb9fa376aaaf2d802dae79e8f01b09..602b12d7470d2d6cca23e7aca1356110cbdea917
@@@ -67,12 -67,9 +67,9 @@@ static void dma_buf_release(struct dent
        BUG_ON(dmabuf->vmapping_counter);
  
        /*
-        * Any fences that a dma-buf poll can wait on should be signaled
-        * before releasing dma-buf. This is the responsibility of each
-        * driver that uses the reservation objects.
-        *
-        * If you hit this BUG() it means someone dropped their ref to the
-        * dma-buf while still having pending operation to the buffer.
+        * If you hit this BUG() it could mean:
+        * * There's a file reference imbalance in dma_buf_poll / dma_buf_poll_cb or somewhere else
+        * * dmabuf->cb_in/out.active are non-0 despite no pending fence callback
         */
        BUG_ON(dmabuf->cb_in.active || dmabuf->cb_out.active);
  
@@@ -200,6 -197,7 +197,7 @@@ static loff_t dma_buf_llseek(struct fil
  static void dma_buf_poll_cb(struct dma_fence *fence, struct dma_fence_cb *cb)
  {
        struct dma_buf_poll_cb_t *dcb = (struct dma_buf_poll_cb_t *)cb;
+       struct dma_buf *dmabuf = container_of(dcb->poll, struct dma_buf, poll);
        unsigned long flags;
  
        spin_lock_irqsave(&dcb->poll->lock, flags);
        dcb->active = 0;
        spin_unlock_irqrestore(&dcb->poll->lock, flags);
        dma_fence_put(fence);
+       /* Paired with get_file in dma_buf_poll */
+       fput(dmabuf->file);
  }
  
  static bool dma_buf_poll_add_cb(struct dma_resv *resv, bool write,
@@@ -259,6 -259,9 +259,9 @@@ static __poll_t dma_buf_poll(struct fil
                spin_unlock_irq(&dmabuf->poll.lock);
  
                if (events & EPOLLOUT) {
+                       /* Paired with fput in dma_buf_poll_cb */
+                       get_file(dmabuf->file);
                        if (!dma_buf_poll_add_cb(resv, true, dcb))
                                /* No callback queued, wake up any other waiters */
                                dma_buf_poll_cb(NULL, &dcb->cb);
                spin_unlock_irq(&dmabuf->poll.lock);
  
                if (events & EPOLLIN) {
+                       /* Paired with fput in dma_buf_poll_cb */
+                       get_file(dmabuf->file);
                        if (!dma_buf_poll_add_cb(resv, false, dcb))
                                /* No callback queued, wake up any other waiters */
                                dma_buf_poll_cb(NULL, &dcb->cb);
  
  /**
   * dma_buf_set_name - Set a name to a specific dma_buf to track the usage.
 - * The name of the dma-buf buffer can only be set when the dma-buf is not
 - * attached to any devices. It could theoritically support changing the
 - * name of the dma-buf if the same piece of memory is used for multiple
 - * purpose between different devices.
 + * It could support changing the name of the dma-buf if the same
 + * piece of memory is used for multiple purpose between different devices.
   *
   * @dmabuf: [in]     dmabuf buffer that will be renamed.
   * @buf:    [in]     A piece of userspace memory that contains the name of
  static long dma_buf_set_name(struct dma_buf *dmabuf, const char __user *buf)
  {
        char *name = strndup_user(buf, DMA_BUF_NAME_LEN);
 -      long ret = 0;
  
        if (IS_ERR(name))
                return PTR_ERR(name);
  
 -      dma_resv_lock(dmabuf->resv, NULL);
 -      if (!list_empty(&dmabuf->attachments)) {
 -              ret = -EBUSY;
 -              kfree(name);
 -              goto out_unlock;
 -      }
        spin_lock(&dmabuf->name_lock);
        kfree(dmabuf->name);
        dmabuf->name = name;
        spin_unlock(&dmabuf->name_lock);
  
 -out_unlock:
 -      dma_resv_unlock(dmabuf->resv);
 -      return ret;
 +      return 0;
  }
  
  static long dma_buf_ioctl(struct file *file,
@@@ -564,7 -581,7 +570,7 @@@ err_module
        module_put(exp_info->owner);
        return ERR_PTR(ret);
  }
- EXPORT_SYMBOL_GPL(dma_buf_export);
+ EXPORT_SYMBOL_NS_GPL(dma_buf_export, DMA_BUF);
  
  /**
   * dma_buf_fd - returns a file descriptor for the given struct dma_buf
@@@ -588,7 -605,7 +594,7 @@@ int dma_buf_fd(struct dma_buf *dmabuf, 
  
        return fd;
  }
- EXPORT_SYMBOL_GPL(dma_buf_fd);
+ EXPORT_SYMBOL_NS_GPL(dma_buf_fd, DMA_BUF);
  
  /**
   * dma_buf_get - returns the struct dma_buf related to an fd
@@@ -614,7 -631,7 +620,7 @@@ struct dma_buf *dma_buf_get(int fd
  
        return file->private_data;
  }
- EXPORT_SYMBOL_GPL(dma_buf_get);
+ EXPORT_SYMBOL_NS_GPL(dma_buf_get, DMA_BUF);
  
  /**
   * dma_buf_put - decreases refcount of the buffer
@@@ -633,7 -650,7 +639,7 @@@ void dma_buf_put(struct dma_buf *dmabuf
  
        fput(dmabuf->file);
  }
- EXPORT_SYMBOL_GPL(dma_buf_put);
+ EXPORT_SYMBOL_NS_GPL(dma_buf_put, DMA_BUF);
  
  static void mangle_sg_table(struct sg_table *sg_table)
  {
@@@ -764,7 -781,7 +770,7 @@@ err_unlock
        dma_buf_detach(dmabuf, attach);
        return ERR_PTR(ret);
  }
- EXPORT_SYMBOL_GPL(dma_buf_dynamic_attach);
+ EXPORT_SYMBOL_NS_GPL(dma_buf_dynamic_attach, DMA_BUF);
  
  /**
   * dma_buf_attach - Wrapper for dma_buf_dynamic_attach
@@@ -779,7 -796,7 +785,7 @@@ struct dma_buf_attachment *dma_buf_atta
  {
        return dma_buf_dynamic_attach(dmabuf, dev, NULL, NULL);
  }
- EXPORT_SYMBOL_GPL(dma_buf_attach);
+ EXPORT_SYMBOL_NS_GPL(dma_buf_attach, DMA_BUF);
  
  static void __unmap_dma_buf(struct dma_buf_attachment *attach,
                            struct sg_table *sg_table,
@@@ -825,7 -842,7 +831,7 @@@ void dma_buf_detach(struct dma_buf *dma
  
        kfree(attach);
  }
- EXPORT_SYMBOL_GPL(dma_buf_detach);
+ EXPORT_SYMBOL_NS_GPL(dma_buf_detach, DMA_BUF);
  
  /**
   * dma_buf_pin - Lock down the DMA-buf
@@@ -855,7 -872,7 +861,7 @@@ int dma_buf_pin(struct dma_buf_attachme
  
        return ret;
  }
- EXPORT_SYMBOL_GPL(dma_buf_pin);
+ EXPORT_SYMBOL_NS_GPL(dma_buf_pin, DMA_BUF);
  
  /**
   * dma_buf_unpin - Unpin a DMA-buf
@@@ -876,7 -893,7 +882,7 @@@ void dma_buf_unpin(struct dma_buf_attac
        if (dmabuf->ops->unpin)
                dmabuf->ops->unpin(attach);
  }
- EXPORT_SYMBOL_GPL(dma_buf_unpin);
+ EXPORT_SYMBOL_NS_GPL(dma_buf_unpin, DMA_BUF);
  
  /**
   * dma_buf_map_attachment - Returns the scatterlist table of the attachment;
@@@ -966,7 -983,7 +972,7 @@@ struct sg_table *dma_buf_map_attachment
  #endif /* CONFIG_DMA_API_DEBUG */
        return sg_table;
  }
- EXPORT_SYMBOL_GPL(dma_buf_map_attachment);
+ EXPORT_SYMBOL_NS_GPL(dma_buf_map_attachment, DMA_BUF);
  
  /**
   * dma_buf_unmap_attachment - unmaps and decreases usecount of the buffer;might
@@@ -1002,7 -1019,7 +1008,7 @@@ void dma_buf_unmap_attachment(struct dm
            !IS_ENABLED(CONFIG_DMABUF_MOVE_NOTIFY))
                dma_buf_unpin(attach);
  }
- EXPORT_SYMBOL_GPL(dma_buf_unmap_attachment);
+ EXPORT_SYMBOL_NS_GPL(dma_buf_unmap_attachment, DMA_BUF);
  
  /**
   * dma_buf_move_notify - notify attachments that DMA-buf is moving
@@@ -1022,7 -1039,7 +1028,7 @@@ void dma_buf_move_notify(struct dma_bu
                if (attach->importer_ops)
                        attach->importer_ops->move_notify(attach);
  }
- EXPORT_SYMBOL_GPL(dma_buf_move_notify);
+ EXPORT_SYMBOL_NS_GPL(dma_buf_move_notify, DMA_BUF);
  
  /**
   * DOC: cpu access
   *
   *   Interfaces::
   *
 - *      void \*dma_buf_vmap(struct dma_buf \*dmabuf)
 - *      void dma_buf_vunmap(struct dma_buf \*dmabuf, void \*vaddr)
 + *      void \*dma_buf_vmap(struct dma_buf \*dmabuf, struct dma_buf_map \*map)
 + *      void dma_buf_vunmap(struct dma_buf \*dmabuf, struct dma_buf_map \*map)
   *
   *   The vmap call can fail if there is no vmap support in the exporter, or if
   *   it runs out of vmalloc space. Note that the dma-buf layer keeps a reference
@@@ -1166,7 -1183,7 +1172,7 @@@ int dma_buf_begin_cpu_access(struct dma
  
        return ret;
  }
- EXPORT_SYMBOL_GPL(dma_buf_begin_cpu_access);
+ EXPORT_SYMBOL_NS_GPL(dma_buf_begin_cpu_access, DMA_BUF);
  
  /**
   * dma_buf_end_cpu_access - Must be called after accessing a dma_buf from the
@@@ -1194,7 -1211,7 +1200,7 @@@ int dma_buf_end_cpu_access(struct dma_b
  
        return ret;
  }
- EXPORT_SYMBOL_GPL(dma_buf_end_cpu_access);
+ EXPORT_SYMBOL_NS_GPL(dma_buf_end_cpu_access, DMA_BUF);
  
  
  /**
@@@ -1236,7 -1253,7 +1242,7 @@@ int dma_buf_mmap(struct dma_buf *dmabuf
  
        return dmabuf->ops->mmap(dmabuf, vma);
  }
- EXPORT_SYMBOL_GPL(dma_buf_mmap);
+ EXPORT_SYMBOL_NS_GPL(dma_buf_mmap, DMA_BUF);
  
  /**
   * dma_buf_vmap - Create virtual mapping for the buffer object into kernel
@@@ -1290,7 -1307,7 +1296,7 @@@ out_unlock
        mutex_unlock(&dmabuf->lock);
        return ret;
  }
- EXPORT_SYMBOL_GPL(dma_buf_vmap);
+ EXPORT_SYMBOL_NS_GPL(dma_buf_vmap, DMA_BUF);
  
  /**
   * dma_buf_vunmap - Unmap a vmap obtained by dma_buf_vmap.
@@@ -1314,13 -1331,15 +1320,13 @@@ void dma_buf_vunmap(struct dma_buf *dma
        }
        mutex_unlock(&dmabuf->lock);
  }
- EXPORT_SYMBOL_GPL(dma_buf_vunmap);
+ EXPORT_SYMBOL_NS_GPL(dma_buf_vunmap, DMA_BUF);
  
  #ifdef CONFIG_DEBUG_FS
  static int dma_buf_debug_show(struct seq_file *s, void *unused)
  {
        struct dma_buf *buf_obj;
        struct dma_buf_attachment *attach_obj;
 -      struct dma_resv_iter cursor;
 -      struct dma_fence *fence;
        int count = 0, attach_count;
        size_t size = 0;
        int ret;
                if (ret)
                        goto error_unlock;
  
+               spin_lock(&buf_obj->name_lock);
                seq_printf(s, "%08zu\t%08x\t%08x\t%08ld\t%s\t%08lu\t%s\n",
                                buf_obj->size,
                                buf_obj->file->f_flags, buf_obj->file->f_mode,
                                buf_obj->exp_name,
                                file_inode(buf_obj->file)->i_ino,
                                buf_obj->name ?: "");
+               spin_unlock(&buf_obj->name_lock);
  
 -              dma_resv_for_each_fence(&cursor, buf_obj->resv, true, fence) {
 -                      seq_printf(s, "\t%s fence: %s %s %ssignalled\n",
 -                                 dma_resv_iter_is_exclusive(&cursor) ?
 -                                      "Exclusive" : "Shared",
 -                                 fence->ops->get_driver_name(fence),
 -                                 fence->ops->get_timeline_name(fence),
 -                                 dma_fence_is_signaled(fence) ? "" : "un");
 -              }
 +              dma_resv_describe(buf_obj->resv, s);
  
                seq_puts(s, "\tAttached Devices:\n");
                attach_count = 0;
diff --combined drivers/gpu/drm/Kconfig
index fb144617055b46f261daf32636a213b344fc6581,0039df26854ba058d5f30fe0e1ecd66f212098bb..9bb456b49b5906cdc9f0fdf1c75b374bb00b1f50
@@@ -117,9 -117,8 +117,8 @@@ config DRM_DEBUG_MODESET_LOC
  
  config DRM_FBDEV_EMULATION
        bool "Enable legacy fbdev support for your modesetting driver"
-       depends on DRM
-       depends on FB=y || FB=DRM
-       select DRM_KMS_HELPER
+       depends on DRM_KMS_HELPER
+       depends on FB=y || FB=DRM_KMS_HELPER
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
@@@ -212,7 -211,7 +211,7 @@@ config DRM_TTM_HELPE
          Helpers for ttm-based gem objects
  
  config DRM_GEM_CMA_HELPER
 -      bool
 +      tristate
        depends on DRM
        help
          Choose this if you need the GEM CMA helper functions
@@@ -225,7 -224,7 +224,7 @@@ config DRM_KMS_CMA_HELPE
          Choose this if you need the KMS CMA helper functions
  
  config DRM_GEM_SHMEM_HELPER
 -      bool
 +      tristate
        depends on DRM && MMU
        help
          Choose this if you need the GEM shmem helper functions
@@@ -496,7 -495,3 +495,7 @@@ config DRM_PANEL_ORIENTATION_QUIRK
  config DRM_LIB_RANDOM
        bool
        default n
 +
 +config DRM_PRIVACY_SCREEN
 +      bool
 +      default n
index 4da7eb65e744783ed715aeba925740730c9aea49,b85b67a88a3d3f0089ba5f9b8026aa53fcc67461..9f017663ac5065d031ba9598215e4925e52e30c9
@@@ -205,6 -205,7 +205,7 @@@ extern struct amdgpu_mgpu_info mgpu_inf
  extern int amdgpu_ras_enable;
  extern uint amdgpu_ras_mask;
  extern int amdgpu_bad_page_threshold;
+ extern bool amdgpu_ignore_bad_page_threshold;
  extern struct amdgpu_watchdog_timer amdgpu_watchdog_timer;
  extern int amdgpu_async_gfx_ring;
  extern int amdgpu_mcbp;
@@@ -457,6 -458,7 +458,6 @@@ struct amdgpu_flip_work 
        uint64_t                        base;
        struct drm_pending_vblank_event *event;
        struct amdgpu_bo                *old_abo;
 -      struct dma_fence                *excl;
        unsigned                        shared_count;
        struct dma_fence                **shared;
        struct dma_fence_cb             cb;
index 30b7dde496fc644a3fceeda4488164ee32424052,c875f1cdd2af7fe17b2caaf99410b15f069180d2..eab4380f28e54b87475132bbb8aa1257292feb7e
@@@ -41,6 -41,7 +41,7 @@@
  #include <linux/swiotlb.h>
  #include <linux/dma-buf.h>
  #include <linux/sizes.h>
+ #include <linux/module.h>
  
  #include <drm/ttm/ttm_bo_api.h>
  #include <drm/ttm/ttm_bo_driver.h>
@@@ -59,6 -60,8 +60,8 @@@
  #include "amdgpu_res_cursor.h"
  #include "bif/bif_4_1_d.h"
  
+ MODULE_IMPORT_NS(DMA_BUF);
  #define AMDGPU_TTM_VRAM_MAX_DW_READ   (size_t)128
  
  static int amdgpu_ttm_backend_bind(struct ttm_device *bdev,
@@@ -696,6 -699,9 +699,9 @@@ int amdgpu_ttm_tt_get_user_pages(struc
                                       true, NULL);
  out_unlock:
        mmap_read_unlock(mm);
+       if (r)
+               pr_debug("failed %d to get user pages 0x%lx\n", r, start);
        mmput(mm);
  
        return r;
@@@ -1235,7 -1241,7 +1241,7 @@@ struct mm_struct *amdgpu_ttm_tt_get_use
   *
   */
  bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start,
-                                 unsigned long end)
+                                 unsigned long end, unsigned long *userptr)
  {
        struct amdgpu_ttm_tt *gtt = (void *)ttm;
        unsigned long size;
        if (gtt->userptr > end || gtt->userptr + size <= start)
                return false;
  
+       if (userptr)
+               *userptr = gtt->userptr;
        return true;
  }
  
@@@ -1345,9 -1353,10 +1353,9 @@@ static bool amdgpu_ttm_bo_eviction_valu
                                            const struct ttm_place *place)
  {
        unsigned long num_pages = bo->resource->num_pages;
 +      struct dma_resv_iter resv_cursor;
        struct amdgpu_res_cursor cursor;
 -      struct dma_resv_list *flist;
        struct dma_fence *f;
 -      int i;
  
        /* Swapout? */
        if (bo->resource->mem_type == TTM_PL_SYSTEM)
         * If true, then return false as any KFD process needs all its BOs to
         * be resident to run successfully
         */
 -      flist = dma_resv_shared_list(bo->base.resv);
 -      if (flist) {
 -              for (i = 0; i < flist->shared_count; ++i) {
 -                      f = rcu_dereference_protected(flist->shared[i],
 -                              dma_resv_held(bo->base.resv));
 -                      if (amdkfd_fence_check_mm(f, current->mm))
 -                              return false;
 -              }
 +      dma_resv_for_each_fence(&resv_cursor, bo->base.resv, true, f) {
 +              if (amdkfd_fence_check_mm(f, current->mm))
 +                      return false;
        }
  
        switch (bo->resource->mem_type) {
index c42b7f50beb8994baa37c9600b8d83554ad26fa7,c911b30de6588e707611095c61975d7241652589..4130082c58731f338e612bd8c7ee119853f91408
@@@ -217,6 -217,7 +217,7 @@@ static const struct drm_format_info 
  amd_get_format_info(const struct drm_mode_fb_cmd2 *cmd);
  
  static void handle_hpd_irq_helper(struct amdgpu_dm_connector *aconnector);
+ static void handle_hpd_rx_irq(void *param);
  
  static bool
  is_timing_unchanged_for_freesync(struct drm_crtc_state *old_crtc_state,
@@@ -619,7 -620,7 +620,7 @@@ static void dm_dcn_vertical_interrupt0_
  
        amdgpu_dm_crtc_handle_crc_window_irq(&acrtc->base);
  }
- #endif
+ #endif /* CONFIG_DRM_AMD_SECURE_DISPLAY */
  
  /**
   * dmub_aux_setconfig_reply_callback - Callback for AUX or SET_CONFIG command.
@@@ -669,10 -670,7 +670,7 @@@ void dmub_hpd_callback(struct amdgpu_de
                return;
        }
  
-       drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
        link_index = notify->link_index;
        link = adev->dm.dc->links[link_index];
  
        drm_connector_list_iter_begin(dev, &iter);
                }
        }
        drm_connector_list_iter_end(&iter);
-       drm_modeset_unlock(&dev->mode_config.connection_mutex);
  
-       if (hpd_aconnector)
-               handle_hpd_irq_helper(hpd_aconnector);
+       if (hpd_aconnector) {
+               if (notify->type == DMUB_NOTIFICATION_HPD)
+                       handle_hpd_irq_helper(hpd_aconnector);
+               else if (notify->type == DMUB_NOTIFICATION_HPD_IRQ)
+                       handle_hpd_rx_irq(hpd_aconnector);
+       }
  }
  
  /**
@@@ -730,6 -731,8 +731,8 @@@ static void dm_handle_hpd_work(struct w
                dmub_hpd_wrk->adev->dm.dmub_callback[dmub_hpd_wrk->dmub_notify->type](dmub_hpd_wrk->adev,
                dmub_hpd_wrk->dmub_notify);
        }
+       kfree(dmub_hpd_wrk->dmub_notify);
        kfree(dmub_hpd_wrk);
  
  }
@@@ -755,12 -758,6 +758,6 @@@ static void dm_dmub_outbox1_low_irq(voi
  
        if (dc_enable_dmub_notifications(adev->dm.dc) &&
                irq_params->irq_src == DC_IRQ_SOURCE_DMCUB_OUTBOX) {
-               dmub_hpd_wrk = kzalloc(sizeof(*dmub_hpd_wrk), GFP_ATOMIC);
-               if (!dmub_hpd_wrk) {
-                       DRM_ERROR("Failed to allocate dmub_hpd_wrk");
-                       return;
-               }
-               INIT_WORK(&dmub_hpd_wrk->handle_hpd_work, dm_handle_hpd_work);
  
                do {
                        dc_stat_get_dmub_notification(adev->dm.dc, &notify);
                                DRM_ERROR("DM: notify type %d invalid!", notify.type);
                                continue;
                        }
+                       if (!dm->dmub_callback[notify.type]) {
+                               DRM_DEBUG_DRIVER("DMUB notification skipped, no handler: type=%d\n", notify.type);
+                               continue;
+                       }
                        if (dm->dmub_thread_offload[notify.type] == true) {
-                               dmub_hpd_wrk->dmub_notify = &notify;
+                               dmub_hpd_wrk = kzalloc(sizeof(*dmub_hpd_wrk), GFP_ATOMIC);
+                               if (!dmub_hpd_wrk) {
+                                       DRM_ERROR("Failed to allocate dmub_hpd_wrk");
+                                       return;
+                               }
+                               dmub_hpd_wrk->dmub_notify = kzalloc(sizeof(struct dmub_notification), GFP_ATOMIC);
+                               if (!dmub_hpd_wrk->dmub_notify) {
+                                       kfree(dmub_hpd_wrk);
+                                       DRM_ERROR("Failed to allocate dmub_hpd_wrk->dmub_notify");
+                                       return;
+                               }
+                               INIT_WORK(&dmub_hpd_wrk->handle_hpd_work, dm_handle_hpd_work);
+                               if (dmub_hpd_wrk->dmub_notify)
+                                       memcpy(dmub_hpd_wrk->dmub_notify, &notify, sizeof(struct dmub_notification));
                                dmub_hpd_wrk->adev = adev;
                                if (notify.type == DMUB_NOTIFICATION_HPD) {
                                        plink = adev->dm.dc->links[notify.link_index];
        if (count > DMUB_TRACE_MAX_READ)
                DRM_DEBUG_DRIVER("Warning : count > DMUB_TRACE_MAX_READ");
  }
- #endif
+ #endif /* CONFIG_DRM_AMD_DC_DCN */
  
  static int dm_set_clockgating_state(void *handle,
                  enum amd_clockgating_state state)
@@@ -1008,6 -1022,7 +1022,7 @@@ static int dm_dmub_hw_init(struct amdgp
        const unsigned char *fw_inst_const, *fw_bss_data;
        uint32_t i, fw_inst_const_size, fw_bss_data_size;
        bool has_hw_support;
+       struct dc *dc = adev->dm.dc;
  
        if (!dmub_srv)
                /* DMUB isn't supported on the ASIC. */
        for (i = 0; i < fb_info->num_fb; ++i)
                hw_params.fb[i] = &fb_info->fb[i];
  
+       switch (adev->asic_type) {
+       case CHIP_YELLOW_CARP:
+               if (dc->ctx->asic_id.hw_internal_rev != YELLOW_CARP_A0) {
+                       hw_params.dpia_supported = true;
+ #if defined(CONFIG_DRM_AMD_DC_DCN)
+                       hw_params.disable_dpia = dc->debug.dpia_debug.bits.disable_dpia;
+ #endif
+               }
+               break;
+       default:
+               break;
+       }
        status = dmub_srv_hw_init(dmub_srv, &hw_params);
        if (status != DMUB_STATUS_OK) {
                DRM_ERROR("Error initializing DMUB HW: %d\n", status);
@@@ -1295,6 -1323,37 +1323,37 @@@ static struct hpd_rx_irq_offload_work_q
        return hpd_rx_offload_wq;
  }
  
+ struct amdgpu_stutter_quirk {
+       u16 chip_vendor;
+       u16 chip_device;
+       u16 subsys_vendor;
+       u16 subsys_device;
+       u8 revision;
+ };
+ static const struct amdgpu_stutter_quirk amdgpu_stutter_quirk_list[] = {
+       /* https://bugzilla.kernel.org/show_bug.cgi?id=214417 */
+       { 0x1002, 0x15dd, 0x1002, 0x15dd, 0xc8 },
+       { 0, 0, 0, 0, 0 },
+ };
+ static bool dm_should_disable_stutter(struct pci_dev *pdev)
+ {
+       const struct amdgpu_stutter_quirk *p = amdgpu_stutter_quirk_list;
+       while (p && p->chip_device != 0) {
+               if (pdev->vendor == p->chip_vendor &&
+                   pdev->device == p->chip_device &&
+                   pdev->subsystem_vendor == p->subsys_vendor &&
+                   pdev->subsystem_device == p->subsys_device &&
+                   pdev->revision == p->revision) {
+                       return true;
+               }
+               ++p;
+       }
+       return false;
+ }
  static int amdgpu_dm_init(struct amdgpu_device *adev)
  {
        struct dc_init_data init_data;
                switch (adev->ip_versions[DCE_HWIP][0]) {
                case IP_VERSION(2, 1, 0):
                        init_data.flags.gpu_vm_support = true;
-                       if (ASICREV_IS_GREEN_SARDINE(adev->external_rev_id))
+                       switch (adev->dm.dmcub_fw_version) {
+                       case 0: /* development */
+                       case 0x1: /* linux-firmware.git hash 6d9f399 */
+                       case 0x01000000: /* linux-firmware.git hash 9a0b0f4 */
+                               init_data.flags.disable_dmcu = false;
+                               break;
+                       default:
                                init_data.flags.disable_dmcu = true;
+                       }
                        break;
                case IP_VERSION(1, 0, 0):
                case IP_VERSION(1, 0, 1):
  
        if (adev->asic_type != CHIP_CARRIZO && adev->asic_type != CHIP_STONEY)
                adev->dm.dc->debug.disable_stutter = amdgpu_pp_feature_mask & PP_STUTTER_MODE ? false : true;
+       if (dm_should_disable_stutter(adev->pdev))
+               adev->dm.dc->debug.disable_stutter = true;
  
        if (amdgpu_dc_debug_mask & DC_DISABLE_STUTTER)
                adev->dm.dc->debug.disable_stutter = true;
                        DRM_ERROR("amdgpu: fail to register dmub hpd callback");
                        goto error;
                }
- #endif
+               if (!register_dmub_notify_callback(adev, DMUB_NOTIFICATION_HPD_IRQ, dmub_hpd_callback, true)) {
+                       DRM_ERROR("amdgpu: fail to register dmub hpd callback");
+                       goto error;
+               }
+ #endif /* CONFIG_DRM_AMD_DC_DCN */
        }
  
        if (amdgpu_dm_initialize_drm_device(adev)) {
@@@ -1793,7 -1865,7 +1865,7 @@@ static int dm_dmub_sw_init(struct amdgp
                break;
        case IP_VERSION(3, 1, 2):
        case IP_VERSION(3, 1, 3):
-               dmub_asic = DMUB_ASIC_DCN31;
+               dmub_asic = (adev->external_rev_id == YELLOW_CARP_B0) ? DMUB_ASIC_DCN31B : DMUB_ASIC_DCN31;
                fw_name_dmub = FIRMWARE_YELLOW_CARP_DMUB;
                break;
  
@@@ -2940,7 -3012,7 +3012,7 @@@ static void handle_hpd_irq_helper(struc
                drm_modeset_unlock_all(dev);
  
                if (aconnector->base.force == DRM_FORCE_UNSPECIFIED)
 -                      drm_kms_helper_hotplug_event(dev);
 +                      drm_kms_helper_connector_hotplug_event(connector);
  
        } else if (dc_link_detect(aconnector->dc_link, DETECT_REASON_HPD)) {
                if (new_connection_type == dc_connection_none &&
                drm_modeset_unlock_all(dev);
  
                if (aconnector->base.force == DRM_FORCE_UNSPECIFIED)
 -                      drm_kms_helper_hotplug_event(dev);
 +                      drm_kms_helper_connector_hotplug_event(connector);
        }
        mutex_unlock(&aconnector->hpd_lock);
  
@@@ -3149,7 -3221,7 +3221,7 @@@ out
                        dm_restore_drm_connector_state(dev, connector);
                        drm_modeset_unlock_all(dev);
  
 -                      drm_kms_helper_hotplug_event(dev);
 +                      drm_kms_helper_connector_hotplug_event(connector);
                } else if (dc_link_detect(dc_link, DETECT_REASON_HPDRX)) {
  
                        if (aconnector->fake_enable)
                        dm_restore_drm_connector_state(dev, connector);
                        drm_modeset_unlock_all(dev);
  
 -                      drm_kms_helper_hotplug_event(dev);
 +                      drm_kms_helper_connector_hotplug_event(connector);
                }
        }
  #ifdef CONFIG_DRM_AMD_DC_HDCP
@@@ -4031,6 -4103,7 +4103,7 @@@ static int amdgpu_dm_initialize_drm_dev
        int32_t primary_planes;
        enum dc_connection_type new_connection_type = dc_connection_none;
        const struct dc_plane_cap *plane;
+       bool psr_feature_enabled = false;
  
        dm->display_indexes_num = dm->dc->caps.max_streams;
        /* Update the actual used number of crtc */
                DRM_DEBUG_KMS("Unsupported DCN IP version for outbox: 0x%X\n",
                              adev->ip_versions[DCE_HWIP][0]);
        }
+       /* Determine whether to enable PSR support by default. */
+       if (!(amdgpu_dc_debug_mask & DC_DISABLE_PSR)) {
+               switch (adev->ip_versions[DCE_HWIP][0]) {
+               case IP_VERSION(3, 1, 2):
+               case IP_VERSION(3, 1, 3):
+                       psr_feature_enabled = true;
+                       break;
+               default:
+                       psr_feature_enabled = amdgpu_dc_feature_mask & DC_PSR_MASK;
+                       break;
+               }
+       }
  #endif
  
        /* loops over all connectors on the board */
                } else if (dc_link_detect(link, DETECT_REASON_BOOT)) {
                        amdgpu_dm_update_connector_after_detect(aconnector);
                        register_backlight_device(dm, link);
-                       if (amdgpu_dc_feature_mask & DC_PSR_MASK)
+                       if (psr_feature_enabled)
                                amdgpu_dm_set_psr_caps(link);
                }
  
@@@ -4495,7 -4582,8 +4582,8 @@@ static void get_min_max_dc_plane_scalin
  }
  
  
- static int fill_dc_scaling_info(const struct drm_plane_state *state,
+ static int fill_dc_scaling_info(struct amdgpu_device *adev,
+                               const struct drm_plane_state *state,
                                struct dc_scaling_info *scaling_info)
  {
        int scale_w, scale_h, min_downscale, max_upscale;
        /*
         * For reasons we don't (yet) fully understand a non-zero
         * src_y coordinate into an NV12 buffer can cause a
-        * system hang. To avoid hangs (and maybe be overly cautious)
+        * system hang on DCN1x.
+        * To avoid hangs (and maybe be overly cautious)
         * let's reject both non-zero src_x and src_y.
         *
         * We currently know of only one use-case to reproduce a
         * is to gesture the YouTube Android app into full screen
         * on ChromeOS.
         */
-       if (state->fb &&
-           state->fb->format->format == DRM_FORMAT_NV12 &&
-           (scaling_info->src_rect.x != 0 ||
-            scaling_info->src_rect.y != 0))
+       if (((adev->ip_versions[DCE_HWIP][0] == IP_VERSION(1, 0, 0)) ||
+           (adev->ip_versions[DCE_HWIP][0] == IP_VERSION(1, 0, 1))) &&
+           (state->fb && state->fb->format->format == DRM_FORMAT_NV12 &&
+           (scaling_info->src_rect.x != 0 || scaling_info->src_rect.y != 0)))
                return -EINVAL;
  
        scaling_info->src_rect.width = state->src_w >> 16;
@@@ -5426,7 -5515,7 +5515,7 @@@ static int fill_dc_plane_attributes(str
        int ret;
        bool force_disable_dcc = false;
  
-       ret = fill_dc_scaling_info(plane_state, &scaling_info);
+       ret = fill_dc_scaling_info(adev, plane_state, &scaling_info);
        if (ret)
                return ret;
  
@@@ -6000,7 -6089,7 +6089,7 @@@ static void apply_dsc_policy_for_stream
        if (stream->timing.flags.DSC && aconnector->dsc_settings.dsc_bits_per_pixel)
                stream->timing.dsc_cfg.bits_per_pixel = aconnector->dsc_settings.dsc_bits_per_pixel;
  }
- #endif
+ #endif /* CONFIG_DRM_AMD_DC_DCN */
  
  /**
   * DOC: FreeSync Video
@@@ -7171,8 -7260,8 +7260,8 @@@ static int dm_update_mst_vcpi_slots_for
        struct drm_connector_state *new_con_state;
        struct amdgpu_dm_connector *aconnector;
        struct dm_connector_state *dm_conn_state;
-       int i, j, clock;
-       int vcpi, pbn_div, pbn = 0;
+       int i, j;
+       int vcpi, pbn_div, pbn, slot_num = 0;
  
        for_each_new_connector_in_state(state, connector, new_con_state, i) {
  
                if (!stream)
                        continue;
  
-               if (stream->timing.flags.DSC != 1) {
-                       drm_dp_mst_atomic_enable_dsc(state,
-                                                    aconnector->port,
-                                                    dm_conn_state->pbn,
-                                                    0,
-                                                    false);
-                       continue;
-               }
                pbn_div = dm_mst_get_pbn_divider(stream->link);
-               clock = stream->timing.pix_clk_100hz / 10;
                /* pbn is calculated by compute_mst_dsc_configs_for_state*/
                for (j = 0; j < dc_state->stream_count; j++) {
                        if (vars[j].aconnector == aconnector) {
                        }
                }
  
+               if (j == dc_state->stream_count)
+                       continue;
+               slot_num = DIV_ROUND_UP(pbn, pbn_div);
+               if (stream->timing.flags.DSC != 1) {
+                       dm_conn_state->pbn = pbn;
+                       dm_conn_state->vcpi_slots = slot_num;
+                       drm_dp_mst_atomic_enable_dsc(state,
+                                                    aconnector->port,
+                                                    dm_conn_state->pbn,
+                                                    0,
+                                                    false);
+                       continue;
+               }
                vcpi = drm_dp_mst_atomic_enable_dsc(state,
                                                    aconnector->port,
                                                    pbn, pbn_div,
@@@ -7482,7 -7578,7 +7578,7 @@@ static int dm_plane_atomic_check(struc
        if (ret)
                return ret;
  
-       ret = fill_dc_scaling_info(new_plane_state, &scaling_info);
+       ret = fill_dc_scaling_info(adev, new_plane_state, &scaling_info);
        if (ret)
                return ret;
  
@@@ -8930,7 -9026,7 +9026,7 @@@ static void amdgpu_dm_commit_planes(str
                        bundle->surface_updates[planes_count].gamut_remap_matrix = &dc_plane->gamut_remap_matrix;
                }
  
-               fill_dc_scaling_info(new_plane_state,
+               fill_dc_scaling_info(dm->adev, new_plane_state,
                                     &bundle->scaling_infos[planes_count]);
  
                bundle->surface_updates[planes_count].scaling_info =
@@@ -10535,18 -10631,18 +10631,18 @@@ static int dm_check_crtc_cursor(struct 
                                struct drm_crtc *crtc,
                                struct drm_crtc_state *new_crtc_state)
  {
-       struct drm_plane_state *new_cursor_state, *new_primary_state;
-       int cursor_scale_w, cursor_scale_h, primary_scale_w, primary_scale_h;
+       struct drm_plane *cursor = crtc->cursor, *underlying;
+       struct drm_plane_state *new_cursor_state, *new_underlying_state;
+       int i;
+       int cursor_scale_w, cursor_scale_h, underlying_scale_w, underlying_scale_h;
  
        /* On DCE and DCN there is no dedicated hardware cursor plane. We get a
         * cursor per pipe but it's going to inherit the scaling and
         * positioning from the underlying pipe. Check the cursor plane's
-        * blending properties match the primary plane's. */
+        * blending properties match the underlying planes'. */
  
-       new_cursor_state = drm_atomic_get_new_plane_state(state, crtc->cursor);
-       new_primary_state = drm_atomic_get_new_plane_state(state, crtc->primary);
-       if (!new_cursor_state || !new_primary_state ||
-           !new_cursor_state->fb || !new_primary_state->fb) {
+       new_cursor_state = drm_atomic_get_new_plane_state(state, cursor);
+       if (!new_cursor_state || !new_cursor_state->fb) {
                return 0;
        }
  
        cursor_scale_h = new_cursor_state->crtc_h * 1000 /
                         (new_cursor_state->src_h >> 16);
  
-       primary_scale_w = new_primary_state->crtc_w * 1000 /
-                        (new_primary_state->src_w >> 16);
-       primary_scale_h = new_primary_state->crtc_h * 1000 /
-                        (new_primary_state->src_h >> 16);
+       for_each_new_plane_in_state_reverse(state, underlying, new_underlying_state, i) {
+               /* Narrow down to non-cursor planes on the same CRTC as the cursor */
+               if (new_underlying_state->crtc != crtc || underlying == crtc->cursor)
+                       continue;
  
-       if (cursor_scale_w != primary_scale_w ||
-           cursor_scale_h != primary_scale_h) {
-               drm_dbg_atomic(crtc->dev, "Cursor plane scaling doesn't match primary plane\n");
-               return -EINVAL;
+               /* Ignore disabled planes */
+               if (!new_underlying_state->fb)
+                       continue;
+               underlying_scale_w = new_underlying_state->crtc_w * 1000 /
+                                    (new_underlying_state->src_w >> 16);
+               underlying_scale_h = new_underlying_state->crtc_h * 1000 /
+                                    (new_underlying_state->src_h >> 16);
+               if (cursor_scale_w != underlying_scale_w ||
+                   cursor_scale_h != underlying_scale_h) {
+                       drm_dbg_atomic(crtc->dev,
+                                      "Cursor [PLANE:%d:%s] scaling doesn't match underlying [PLANE:%d:%s]\n",
+                                      cursor->base.id, cursor->name, underlying->base.id, underlying->name);
+                       return -EINVAL;
+               }
+               /* If this plane covers the whole CRTC, no need to check planes underneath */
+               if (new_underlying_state->crtc_x <= 0 &&
+                   new_underlying_state->crtc_y <= 0 &&
+                   new_underlying_state->crtc_x + new_underlying_state->crtc_w >= new_crtc_state->mode.hdisplay &&
+                   new_underlying_state->crtc_y + new_underlying_state->crtc_h >= new_crtc_state->mode.vdisplay)
+                       break;
        }
  
        return 0;
@@@ -10594,53 -10709,6 +10709,6 @@@ static int add_affected_mst_dsc_crtcs(s
  }
  #endif
  
- static int validate_overlay(struct drm_atomic_state *state)
- {
-       int i;
-       struct drm_plane *plane;
-       struct drm_plane_state *new_plane_state;
-       struct drm_plane_state *primary_state, *overlay_state = NULL;
-       /* Check if primary plane is contained inside overlay */
-       for_each_new_plane_in_state_reverse(state, plane, new_plane_state, i) {
-               if (plane->type == DRM_PLANE_TYPE_OVERLAY) {
-                       if (drm_atomic_plane_disabling(plane->state, new_plane_state))
-                               return 0;
-                       overlay_state = new_plane_state;
-                       continue;
-               }
-       }
-       /* check if we're making changes to the overlay plane */
-       if (!overlay_state)
-               return 0;
-       /* check if overlay plane is enabled */
-       if (!overlay_state->crtc)
-               return 0;
-       /* find the primary plane for the CRTC that the overlay is enabled on */
-       primary_state = drm_atomic_get_plane_state(state, overlay_state->crtc->primary);
-       if (IS_ERR(primary_state))
-               return PTR_ERR(primary_state);
-       /* check if primary plane is enabled */
-       if (!primary_state->crtc)
-               return 0;
-       /* Perform the bounds check to ensure the overlay plane covers the primary */
-       if (primary_state->crtc_x < overlay_state->crtc_x ||
-           primary_state->crtc_y < overlay_state->crtc_y ||
-           primary_state->crtc_x + primary_state->crtc_w > overlay_state->crtc_x + overlay_state->crtc_w ||
-           primary_state->crtc_y + primary_state->crtc_h > overlay_state->crtc_y + overlay_state->crtc_h) {
-               DRM_DEBUG_ATOMIC("Overlay plane is enabled with hardware cursor but does not fully cover primary plane\n");
-               return -EINVAL;
-       }
-       return 0;
- }
  /**
   * amdgpu_dm_atomic_check() - Atomic check implementation for AMDgpu DM.
   * @dev: The DRM device
@@@ -10683,6 -10751,8 +10751,8 @@@ static int amdgpu_dm_atomic_check(struc
        struct dm_crtc_state *dm_old_crtc_state;
  #if defined(CONFIG_DRM_AMD_DC_DCN)
        struct dsc_mst_fairness_vars vars[MAX_PIPES];
+       struct drm_dp_mst_topology_state *mst_state;
+       struct drm_dp_mst_topology_mgr *mgr;
  #endif
  
        trace_amdgpu_dm_atomic_check_begin(state);
  
                ret = drm_atomic_add_affected_connectors(state, crtc);
                if (ret)
-                       return ret;
+                       goto fail;
  
                ret = drm_atomic_add_affected_planes(state, crtc);
                if (ret)
                        goto fail;
        }
  
-       ret = validate_overlay(state);
-       if (ret)
-               goto fail;
        /* Add new/modified planes */
        for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) {
                ret = dm_update_plane_state(dc, state, plane,
                lock_and_validation_needed = true;
        }
  
+ #if defined(CONFIG_DRM_AMD_DC_DCN)
+       /* set the slot info for each mst_state based on the link encoding format */
+       for_each_new_mst_mgr_in_state(state, mgr, mst_state, i) {
+               struct amdgpu_dm_connector *aconnector;
+               struct drm_connector *connector;
+               struct drm_connector_list_iter iter;
+               u8 link_coding_cap;
+               if (!mgr->mst_state )
+                       continue;
+               drm_connector_list_iter_begin(dev, &iter);
+               drm_for_each_connector_iter(connector, &iter) {
+                       int id = connector->index;
+                       if (id == mst_state->mgr->conn_base_id) {
+                               aconnector = to_amdgpu_dm_connector(connector);
+                               link_coding_cap = dc_link_dp_mst_decide_link_encoding_format(aconnector->dc_link);
+                               drm_dp_mst_update_slots(mst_state, link_coding_cap);
+                               break;
+                       }
+               }
+               drm_connector_list_iter_end(&iter);
+       }
+ #endif
        /**
         * Streams and planes are reset when there are changes that affect
         * bandwidth. Anything that affects bandwidth needs to go through
index f8c8122e15ed23e8a8a2fb7dfb3134ff7a1e0f9e,9d43ecb1f692dd7a6a5018512d34914adfbabc7c..0277685864c53889cf7a7db2a56137a11dbe9c46
@@@ -78,12 -78,10 +78,10 @@@ static int parse_write_buffer_into_para
  
        wr_buf_ptr = wr_buf;
  
-       r = copy_from_user(wr_buf_ptr, buf, wr_buf_size);
-               /* r is bytes not be copied */
-       if (r >= wr_buf_size) {
-               DRM_DEBUG_DRIVER("user data not be read\n");
-               return -EINVAL;
+       /* r is bytes not be copied */
+       if (copy_from_user(wr_buf_ptr, buf, wr_buf_size)) {
+               DRM_DEBUG_DRIVER("user data could not be read successfully\n");
+               return -EFAULT;
        }
  
        /* check number of parameters. isspace could not differ space and \n */
@@@ -264,7 -262,7 +262,7 @@@ static ssize_t dp_link_settings_write(s
        if (!wr_buf)
                return -ENOSPC;
  
-       if (parse_write_buffer_into_params(wr_buf, size,
+       if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
                                           (long *)param, buf,
                                           max_param_num,
                                           &param_nums)) {
        case LINK_RATE_RBR2:
        case LINK_RATE_HIGH2:
        case LINK_RATE_HIGH3:
+ #if defined(CONFIG_DRM_AMD_DC_DCN)
+       case LINK_RATE_UHBR10:
+ #endif
                break;
        default:
                valid_input = false;
@@@ -488,7 -489,7 +489,7 @@@ static ssize_t dp_phy_settings_write(st
        if (!wr_buf)
                return -ENOSPC;
  
-       if (parse_write_buffer_into_params(wr_buf, size,
+       if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
                                           (long *)param, buf,
                                           max_param_num,
                                           &param_nums)) {
@@@ -640,7 -641,7 +641,7 @@@ static ssize_t dp_phy_test_pattern_debu
        if (!wr_buf)
                return -ENOSPC;
  
-       if (parse_write_buffer_into_params(wr_buf, size,
+       if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
                                           (long *)param, buf,
                                           max_param_num,
                                           &param_nums)) {
@@@ -915,7 -916,7 +916,7 @@@ static ssize_t dp_dsc_passthrough_set(s
                return -ENOSPC;
        }
  
-       if (parse_write_buffer_into_params(wr_buf, size,
+       if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
                                           &param, buf,
                                           max_param_num,
                                           &param_nums)) {
@@@ -1212,7 -1213,7 +1213,7 @@@ static ssize_t trigger_hotplug(struct f
                return -ENOSPC;
        }
  
-       if (parse_write_buffer_into_params(wr_buf, size,
+       if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
                                                (long *)param, buf,
                                                max_param_num,
                                                &param_nums)) {
                dm_restore_drm_connector_state(dev, connector);
                drm_modeset_unlock_all(dev);
  
 -              drm_kms_helper_hotplug_event(dev);
 +              drm_kms_helper_connector_hotplug_event(connector);
        } else if (param[0] == 0) {
                if (!aconnector->dc_link)
                        goto unlock;
                dm_restore_drm_connector_state(dev, connector);
                drm_modeset_unlock_all(dev);
  
 -              drm_kms_helper_hotplug_event(dev);
 +              drm_kms_helper_connector_hotplug_event(connector);
        }
  
  unlock:
@@@ -1397,7 -1398,7 +1398,7 @@@ static ssize_t dp_dsc_clock_en_write(st
                return -ENOSPC;
        }
  
-       if (parse_write_buffer_into_params(wr_buf, size,
+       if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
                                            (long *)param, buf,
                                            max_param_num,
                                            &param_nums)) {
@@@ -1582,7 -1583,7 +1583,7 @@@ static ssize_t dp_dsc_slice_width_write
                return -ENOSPC;
        }
  
-       if (parse_write_buffer_into_params(wr_buf, size,
+       if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
                                            (long *)param, buf,
                                            max_param_num,
                                            &param_nums)) {
@@@ -1767,7 -1768,7 +1768,7 @@@ static ssize_t dp_dsc_slice_height_writ
                return -ENOSPC;
        }
  
-       if (parse_write_buffer_into_params(wr_buf, size,
+       if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
                                            (long *)param, buf,
                                            max_param_num,
                                            &param_nums)) {
@@@ -1945,7 -1946,7 +1946,7 @@@ static ssize_t dp_dsc_bits_per_pixel_wr
                return -ENOSPC;
        }
  
-       if (parse_write_buffer_into_params(wr_buf, size,
+       if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
                                            (long *)param, buf,
                                            max_param_num,
                                            &param_nums)) {
@@@ -2383,7 -2384,7 +2384,7 @@@ static ssize_t dp_max_bpc_write(struct 
                return -ENOSPC;
        }
  
-       if (parse_write_buffer_into_params(wr_buf, size,
+       if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
                                           (long *)param, buf,
                                           max_param_num,
                                           &param_nums)) {
index 442db735416fe21c9545fdc1d9cf1f51f64aec1d,8e7a124d6c5a3ae27f18c268af7d02e4fa952b77..9727a59d35fd6e8e994d9f93a51e89c7e1561bad
@@@ -1506,6 -1506,7 +1506,7 @@@ static int drm_fb_helper_single_fb_prob
  {
        struct drm_client_dev *client = &fb_helper->client;
        struct drm_device *dev = fb_helper->dev;
+       struct drm_mode_config *config = &dev->mode_config;
        int ret = 0;
        int crtc_count = 0;
        struct drm_connector_list_iter conn_iter;
        /* Handle our overallocation */
        sizes.surface_height *= drm_fbdev_overalloc;
        sizes.surface_height /= 100;
+       if (sizes.surface_height > config->max_height) {
+               drm_dbg_kms(dev, "Fbdev over-allocation too large; clamping height to %d\n",
+                           config->max_height);
+               sizes.surface_height = config->max_height;
+       }
  
        /* push down into drivers */
        ret = (*fb_helper->funcs->fb_probe)(fb_helper, &sizes);
@@@ -2332,7 -2338,7 +2338,7 @@@ static int drm_fb_helper_generic_probe(
                return PTR_ERR(fbi);
  
        fbi->fbops = &drm_fbdev_fb_ops;
 -      fbi->screen_size = fb->height * fb->pitches[0];
 +      fbi->screen_size = sizes->surface_height * fb->pitches[0];
        fbi->fix.smem_len = fbi->screen_size;
  
        drm_fb_helper_fill_info(fbi, fb_helper, sizes);
index dfff073bf1e8e5996f84072f7ff8b8094032305f,7b9f69f21f1eda7491f230a3be176aacce3d34e9..0eeda1012364b33c89d0ac81ca82c51d0ee98fc2
@@@ -5,7 -5,6 +5,7 @@@
  
  #include <linux/dma-buf.h>
  #include <linux/export.h>
 +#include <linux/module.h>
  #include <linux/mutex.h>
  #include <linux/shmem_fs.h>
  #include <linux/slab.h>
  #include <drm/drm_prime.h>
  #include <drm/drm_print.h>
  
+ MODULE_IMPORT_NS(DMA_BUF);
  /**
   * DOC: overview
   *
   * This library provides helpers for GEM objects backed by shmem buffers
   * allocated using anonymous pageable memory.
 + *
 + * Functions that operate on the GEM object receive struct &drm_gem_shmem_object.
 + * For GEM callback helpers in struct &drm_gem_object functions, see likewise
 + * named functions with an _object_ infix (e.g., drm_gem_shmem_object_vmap() wraps
 + * drm_gem_shmem_vmap()). These helpers perform the necessary type conversion.
   */
  
  static const struct drm_gem_object_funcs drm_gem_shmem_funcs = {
 -      .free = drm_gem_shmem_free_object,
 -      .print_info = drm_gem_shmem_print_info,
 -      .pin = drm_gem_shmem_pin,
 -      .unpin = drm_gem_shmem_unpin,
 -      .get_sg_table = drm_gem_shmem_get_sg_table,
 -      .vmap = drm_gem_shmem_vmap,
 -      .vunmap = drm_gem_shmem_vunmap,
 -      .mmap = drm_gem_shmem_mmap,
 +      .free = drm_gem_shmem_object_free,
 +      .print_info = drm_gem_shmem_object_print_info,
 +      .pin = drm_gem_shmem_object_pin,
 +      .unpin = drm_gem_shmem_object_unpin,
 +      .get_sg_table = drm_gem_shmem_object_get_sg_table,
 +      .vmap = drm_gem_shmem_object_vmap,
 +      .vunmap = drm_gem_shmem_object_vunmap,
 +      .mmap = drm_gem_shmem_object_mmap,
  };
  
  static struct drm_gem_shmem_object *
@@@ -122,15 -118,16 +124,15 @@@ struct drm_gem_shmem_object *drm_gem_sh
  EXPORT_SYMBOL_GPL(drm_gem_shmem_create);
  
  /**
 - * drm_gem_shmem_free_object - Free resources associated with a shmem GEM object
 - * @obj: GEM object to free
 + * drm_gem_shmem_free - Free resources associated with a shmem GEM object
 + * @shmem: shmem GEM object to free
   *
   * This function cleans up the GEM object state and frees the memory used to
 - * store the object itself. It should be used to implement
 - * &drm_gem_object_funcs.free.
 + * store the object itself.
   */
 -void drm_gem_shmem_free_object(struct drm_gem_object *obj)
 +void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem)
  {
 -      struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
 +      struct drm_gem_object *obj = &shmem->base;
  
        WARN_ON(shmem->vmap_use_count);
  
        mutex_destroy(&shmem->vmap_lock);
        kfree(shmem);
  }
 -EXPORT_SYMBOL_GPL(drm_gem_shmem_free_object);
 +EXPORT_SYMBOL_GPL(drm_gem_shmem_free);
  
  static int drm_gem_shmem_get_pages_locked(struct drm_gem_shmem_object *shmem)
  {
@@@ -249,16 -246,19 +251,16 @@@ EXPORT_SYMBOL(drm_gem_shmem_put_pages)
  
  /**
   * drm_gem_shmem_pin - Pin backing pages for a shmem GEM object
 - * @obj: GEM object
 + * @shmem: shmem GEM object
   *
   * This function makes sure the backing pages are pinned in memory while the
 - * buffer is exported. It should only be used to implement
 - * &drm_gem_object_funcs.pin.
 + * buffer is exported.
   *
   * Returns:
   * 0 on success or a negative error code on failure.
   */
 -int drm_gem_shmem_pin(struct drm_gem_object *obj)
 +int drm_gem_shmem_pin(struct drm_gem_shmem_object *shmem)
  {
 -      struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
 -
        WARN_ON(shmem->base.import_attach);
  
        return drm_gem_shmem_get_pages(shmem);
@@@ -267,13 -267,15 +269,13 @@@ EXPORT_SYMBOL(drm_gem_shmem_pin)
  
  /**
   * drm_gem_shmem_unpin - Unpin backing pages for a shmem GEM object
 - * @obj: GEM object
 + * @shmem: shmem GEM object
   *
   * This function removes the requirement that the backing pages are pinned in
 - * memory. It should only be used to implement &drm_gem_object_funcs.unpin.
 + * memory.
   */
 -void drm_gem_shmem_unpin(struct drm_gem_object *obj)
 +void drm_gem_shmem_unpin(struct drm_gem_shmem_object *shmem)
  {
 -      struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
 -
        WARN_ON(shmem->base.import_attach);
  
        drm_gem_shmem_put_pages(shmem);
@@@ -339,16 -341,20 +341,16 @@@ err_zero_use
   *       store.
   *
   * This function makes sure that a contiguous kernel virtual address mapping
 - * exists for the buffer backing the shmem GEM object.
 - *
 - * This function can be used to implement &drm_gem_object_funcs.vmap. But it can
 - * also be called by drivers directly, in which case it will hide the
 - * differences between dma-buf imported and natively allocated objects.
 + * exists for the buffer backing the shmem GEM object. It hides the differences
 + * between dma-buf imported and natively allocated objects.
   *
   * Acquired mappings should be cleaned up by calling drm_gem_shmem_vunmap().
   *
   * Returns:
   * 0 on success or a negative error code on failure.
   */
 -int drm_gem_shmem_vmap(struct drm_gem_object *obj, struct dma_buf_map *map)
 +int drm_gem_shmem_vmap(struct drm_gem_shmem_object *shmem, struct dma_buf_map *map)
  {
 -      struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
        int ret;
  
        ret = mutex_lock_interruptible(&shmem->vmap_lock);
@@@ -391,18 -397,21 +393,18 @@@ static void drm_gem_shmem_vunmap_locked
   * drm_gem_shmem_vmap(). The mapping is only removed when the use count drops to
   * zero.
   *
 - * This function can be used to implement &drm_gem_object_funcs.vmap. But it can
 - * also be called by drivers directly, in which case it will hide the
 - * differences between dma-buf imported and natively allocated objects.
 + * This function hides the differences between dma-buf imported and natively
 + * allocated objects.
   */
 -void drm_gem_shmem_vunmap(struct drm_gem_object *obj, struct dma_buf_map *map)
 +void drm_gem_shmem_vunmap(struct drm_gem_shmem_object *shmem, struct dma_buf_map *map)
  {
 -      struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
 -
        mutex_lock(&shmem->vmap_lock);
        drm_gem_shmem_vunmap_locked(shmem, map);
        mutex_unlock(&shmem->vmap_lock);
  }
  EXPORT_SYMBOL(drm_gem_shmem_vunmap);
  
 -struct drm_gem_shmem_object *
 +static struct drm_gem_shmem_object *
  drm_gem_shmem_create_with_handle(struct drm_file *file_priv,
                                 struct drm_device *dev, size_t size,
                                 uint32_t *handle)
  
        return shmem;
  }
 -EXPORT_SYMBOL(drm_gem_shmem_create_with_handle);
  
  /* Update madvise status, returns true if not purged, else
   * false or -errno.
   */
 -int drm_gem_shmem_madvise(struct drm_gem_object *obj, int madv)
 +int drm_gem_shmem_madvise(struct drm_gem_shmem_object *shmem, int madv)
  {
 -      struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
 -
        mutex_lock(&shmem->pages_lock);
  
        if (shmem->madv >= 0)
  }
  EXPORT_SYMBOL(drm_gem_shmem_madvise);
  
 -void drm_gem_shmem_purge_locked(struct drm_gem_object *obj)
 +void drm_gem_shmem_purge_locked(struct drm_gem_shmem_object *shmem)
  {
 +      struct drm_gem_object *obj = &shmem->base;
        struct drm_device *dev = obj->dev;
 -      struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
  
        WARN_ON(!drm_gem_shmem_is_purgeable(shmem));
  
 -      dma_unmap_sgtable(obj->dev->dev, shmem->sgt, DMA_BIDIRECTIONAL, 0);
 +      dma_unmap_sgtable(dev->dev, shmem->sgt, DMA_BIDIRECTIONAL, 0);
        sg_free_table(shmem->sgt);
        kfree(shmem->sgt);
        shmem->sgt = NULL;
         */
        shmem_truncate_range(file_inode(obj->filp), 0, (loff_t)-1);
  
 -      invalidate_mapping_pages(file_inode(obj->filp)->i_mapping,
 -                      0, (loff_t)-1);
 +      invalidate_mapping_pages(file_inode(obj->filp)->i_mapping, 0, (loff_t)-1);
  }
  EXPORT_SYMBOL(drm_gem_shmem_purge_locked);
  
 -bool drm_gem_shmem_purge(struct drm_gem_object *obj)
 +bool drm_gem_shmem_purge(struct drm_gem_shmem_object *shmem)
  {
 -      struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
 -
        if (!mutex_trylock(&shmem->pages_lock))
                return false;
 -      drm_gem_shmem_purge_locked(obj);
 +      drm_gem_shmem_purge_locked(shmem);
        mutex_unlock(&shmem->pages_lock);
  
        return true;
@@@ -587,18 -602,19 +589,18 @@@ static const struct vm_operations_struc
  
  /**
   * drm_gem_shmem_mmap - Memory-map a shmem GEM object
 - * @obj: gem object
 + * @shmem: shmem GEM object
   * @vma: VMA for the area to be mapped
   *
   * This function implements an augmented version of the GEM DRM file mmap
 - * operation for shmem objects. Drivers which employ the shmem helpers should
 - * use this function as their &drm_gem_object_funcs.mmap handler.
 + * operation for shmem objects.
   *
   * Returns:
   * 0 on success or a negative error code on failure.
   */
 -int drm_gem_shmem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
 +int drm_gem_shmem_mmap(struct drm_gem_shmem_object *shmem, struct vm_area_struct *vma)
  {
 -      struct drm_gem_shmem_object *shmem;
 +      struct drm_gem_object *obj = &shmem->base;
        int ret;
  
        if (obj->import_attach) {
                return dma_buf_mmap(obj->dma_buf, vma, 0);
        }
  
 -      shmem = to_drm_gem_shmem_obj(obj);
 -
        ret = drm_gem_shmem_get_pages(shmem);
        if (ret) {
                drm_gem_vm_close(vma);
@@@ -627,13 -645,17 +629,13 @@@ EXPORT_SYMBOL_GPL(drm_gem_shmem_mmap)
  
  /**
   * drm_gem_shmem_print_info() - Print &drm_gem_shmem_object info for debugfs
 + * @shmem: shmem GEM object
   * @p: DRM printer
   * @indent: Tab indentation level
 - * @obj: GEM object
 - *
 - * This implements the &drm_gem_object_funcs.info callback.
   */
 -void drm_gem_shmem_print_info(struct drm_printer *p, unsigned int indent,
 -                            const struct drm_gem_object *obj)
 +void drm_gem_shmem_print_info(const struct drm_gem_shmem_object *shmem,
 +                            struct drm_printer *p, unsigned int indent)
  {
 -      const struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
 -
        drm_printf_indent(p, indent, "pages_use_count=%u\n", shmem->pages_use_count);
        drm_printf_indent(p, indent, "vmap_use_count=%u\n", shmem->vmap_use_count);
        drm_printf_indent(p, indent, "vaddr=%p\n", shmem->vaddr);
@@@ -643,10 -665,12 +645,10 @@@ EXPORT_SYMBOL(drm_gem_shmem_print_info)
  /**
   * drm_gem_shmem_get_sg_table - Provide a scatter/gather table of pinned
   *                              pages for a shmem GEM object
 - * @obj: GEM object
 + * @shmem: shmem GEM object
   *
   * This function exports a scatter/gather table suitable for PRIME usage by
 - * calling the standard DMA mapping API. Drivers should not call this function
 - * directly, instead it should only be used as an implementation for
 - * &drm_gem_object_funcs.get_sg_table.
 + * calling the standard DMA mapping API.
   *
   * Drivers who need to acquire an scatter/gather table for objects need to call
   * drm_gem_shmem_get_pages_sgt() instead.
   * Returns:
   * A pointer to the scatter/gather table of pinned pages or NULL on failure.
   */
 -struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_object *obj)
 +struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_shmem_object *shmem)
  {
 -      struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
 +      struct drm_gem_object *obj = &shmem->base;
  
        WARN_ON(shmem->base.import_attach);
  
@@@ -667,7 -691,7 +669,7 @@@ EXPORT_SYMBOL_GPL(drm_gem_shmem_get_sg_
  /**
   * drm_gem_shmem_get_pages_sgt - Pin pages, dma map them, and return a
   *                             scatter/gather table for a shmem GEM object.
 - * @obj: GEM object
 + * @shmem: shmem GEM object
   *
   * This function returns a scatter/gather table suitable for driver usage. If
   * the sg table doesn't exist, the pages are pinned, dma-mapped, and a sg
   * Returns:
   * A pointer to the scatter/gather table of pinned pages or errno on failure.
   */
 -struct sg_table *drm_gem_shmem_get_pages_sgt(struct drm_gem_object *obj)
 +struct sg_table *drm_gem_shmem_get_pages_sgt(struct drm_gem_shmem_object *shmem)
  {
 +      struct drm_gem_object *obj = &shmem->base;
        int ret;
 -      struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
        struct sg_table *sgt;
  
        if (shmem->sgt)
        if (ret)
                return ERR_PTR(ret);
  
 -      sgt = drm_gem_shmem_get_sg_table(&shmem->base);
 +      sgt = drm_gem_shmem_get_sg_table(shmem);
        if (IS_ERR(sgt)) {
                ret = PTR_ERR(sgt);
                goto err_put_pages;
@@@ -752,7 -776,3 +754,7 @@@ drm_gem_shmem_prime_import_sg_table(str
        return &shmem->base;
  }
  EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_sg_table);
 +
 +MODULE_DESCRIPTION("DRM SHMEM memory-management helpers");
 +MODULE_IMPORT_NS(DMA_BUF);
 +MODULE_LICENSE("GPL v2");
index b490c3d2286ec29b72e40c7f0e06495787823b86,8c97a20dfe2310505110a4e125b3983490b41385..93f51e70a95180bfc4ae4ebf32ecb6201b61b487
@@@ -23,16 -23,13 +23,16 @@@ static int hyperv_blit_to_vram_rect(str
                                    struct drm_rect *rect)
  {
        struct hyperv_drm_device *hv = to_hv(fb->dev);
 +      void __iomem *dst = hv->vram;
        void *vmap = map->vaddr; /* TODO: Use mapping abstraction properly */
        int idx;
  
        if (!drm_dev_enter(&hv->dev, &idx))
                return -ENODEV;
  
 -      drm_fb_memcpy_dstclip(hv->vram, fb->pitches[0], vmap, fb, rect);
 +      dst += drm_fb_clip_offset(fb->pitches[0], fb->format, rect);
 +      drm_fb_memcpy_toio(dst, fb->pitches[0], vmap, fb, rect);
 +
        drm_dev_exit(idx);
  
        return 0;
@@@ -104,6 -101,7 +104,7 @@@ static void hyperv_pipe_enable(struct d
        struct hyperv_drm_device *hv = to_hv(pipe->crtc.dev);
        struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
  
+       hyperv_hide_hw_ptr(hv->hdev);
        hyperv_update_situation(hv->hdev, 1,  hv->screen_depth,
                                crtc_state->mode.hdisplay,
                                crtc_state->mode.vdisplay,
index 7732573e325868f13008a46067a4b5c15ec09273,be883469d2fcc30299a211dafddc2f5c6c489c84..8195452b2d4c46d237dd9ba513bdc91e32b2f735
@@@ -120,6 -120,12 +120,12 @@@ bool intel_dp_is_uhbr(const struct inte
        return crtc_state->port_clock >= 1000000;
  }
  
+ static void intel_dp_set_default_sink_rates(struct intel_dp *intel_dp)
+ {
+       intel_dp->sink_rates[0] = 162000;
+       intel_dp->num_sink_rates = 1;
+ }
  /* update sink rates from dpcd */
  static void intel_dp_set_sink_rates(struct intel_dp *intel_dp)
  {
@@@ -281,7 -287,7 +287,7 @@@ intel_dp_max_data_rate(int max_link_rat
                 */
                int max_link_rate_kbps = max_link_rate * 10;
  
-               max_link_rate_kbps = DIV_ROUND_CLOSEST_ULL(max_link_rate_kbps * 9671, 10000);
+               max_link_rate_kbps = DIV_ROUND_CLOSEST_ULL(mul_u32_u32(max_link_rate_kbps, 9671), 10000);
                max_link_rate = max_link_rate_kbps / 8;
        }
  
@@@ -1858,6 -1864,12 +1864,12 @@@ void intel_dp_set_link_params(struct in
        intel_dp->lane_count = lane_count;
  }
  
+ static void intel_dp_reset_max_link_params(struct intel_dp *intel_dp)
+ {
+       intel_dp->max_link_lane_count = intel_dp_max_common_lane_count(intel_dp);
+       intel_dp->max_link_rate = intel_dp_max_common_rate(intel_dp);
+ }
  /* Enable backlight PWM and backlight PP control. */
  void intel_edp_backlight_on(const struct intel_crtc_state *crtc_state,
                            const struct drm_connector_state *conn_state)
@@@ -2007,6 -2019,9 +2019,9 @@@ void intel_dp_sync_state(struct intel_e
  {
        struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
  
+       if (!crtc_state)
+               return;
        /*
         * Don't clobber DPCD if it's been already read out during output
         * setup (eDP) or detect.
        if (intel_dp->dpcd[DP_DPCD_REV] == 0)
                intel_dp_get_dpcd(intel_dp);
  
-       intel_dp->max_link_lane_count = intel_dp_max_common_lane_count(intel_dp);
-       intel_dp->max_link_rate = intel_dp_max_common_rate(intel_dp);
+       intel_dp_reset_max_link_params(intel_dp);
  }
  
  bool intel_dp_initial_fastset_check(struct intel_encoder *encoder,
@@@ -2553,6 -2567,9 +2567,9 @@@ intel_edp_init_dpcd(struct intel_dp *in
         */
        intel_psr_init_dpcd(intel_dp);
  
+       /* Clear the default sink rates */
+       intel_dp->num_sink_rates = 0;
        /* Read the eDP 1.4+ supported link rates. */
        if (intel_dp->edp_dpcd[0] >= DP_EDP_14) {
                __le16 sink_rates[DP_MAX_SUPPORTED_RATES];
                intel_dp_set_sink_rates(intel_dp);
  
        intel_dp_set_common_rates(intel_dp);
+       intel_dp_reset_max_link_params(intel_dp);
  
        /* Read the eDP DSC DPCD registers */
        if (DISPLAY_VER(dev_priv) >= 10)
@@@ -4329,12 -4347,7 +4347,7 @@@ intel_dp_detect(struct drm_connector *c
         * supports link training fallback params.
         */
        if (intel_dp->reset_link_params || intel_dp->is_mst) {
-               /* Initial max link lane count */
-               intel_dp->max_link_lane_count = intel_dp_max_common_lane_count(intel_dp);
-               /* Initial max link rate */
-               intel_dp->max_link_rate = intel_dp_max_common_rate(intel_dp);
+               intel_dp_reset_max_link_params(intel_dp);
                intel_dp->reset_link_params = false;
        }
  
@@@ -4947,7 -4960,7 +4960,7 @@@ static void intel_dp_modeset_retry_work
                                               DRM_MODE_LINK_STATUS_BAD);
        mutex_unlock(&connector->dev->mode_config.mutex);
        /* Send Hotplug uevent so userspace can reprobe */
 -      drm_kms_helper_hotplug_event(connector->dev);
 +      drm_kms_helper_connector_hotplug_event(connector);
  }
  
  bool
@@@ -5000,6 -5013,9 +5013,9 @@@ intel_dp_init_connector(struct intel_di
        }
  
        intel_dp_set_source_rates(intel_dp);
+       intel_dp_set_default_sink_rates(intel_dp);
+       intel_dp_set_common_rates(intel_dp);
+       intel_dp_reset_max_link_params(intel_dp);
  
        if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
                intel_dp->pps.active_pipe = vlv_active_pipe(intel_dp);
index 7e1fda9f9a3d45e0fa712825f529d1bc2ef1d97c,961ac6fb5fcf746e658e6f3fc4a839fe6b15f4e6..ed242435077314fb03d891b582fdd1aa16f85245
@@@ -15,7 -15,6 +15,7 @@@
  
  #include <drm/drm_atomic_helper.h>
  #include <drm/drm_drv.h>
 +#include <drm/drm_fb_helper.h>
  #include <drm/drm_gem_cma_helper.h>
  #include <drm/drm_gem_framebuffer_helper.h>
  #include <drm/drm_probe_helper.h>
@@@ -173,11 -172,10 +173,11 @@@ static int kmb_setup_mode_config(struc
        ret = drmm_mode_config_init(drm);
        if (ret)
                return ret;
-       drm->mode_config.min_width = KMB_MIN_WIDTH;
-       drm->mode_config.min_height = KMB_MIN_HEIGHT;
-       drm->mode_config.max_width = KMB_MAX_WIDTH;
-       drm->mode_config.max_height = KMB_MAX_HEIGHT;
+       drm->mode_config.min_width = KMB_FB_MIN_WIDTH;
+       drm->mode_config.min_height = KMB_FB_MIN_HEIGHT;
+       drm->mode_config.max_width = KMB_FB_MAX_WIDTH;
+       drm->mode_config.max_height = KMB_FB_MAX_HEIGHT;
 +      drm->mode_config.preferred_depth = 24;
        drm->mode_config.funcs = &kmb_mode_config_funcs;
  
        ret = kmb_setup_crtc(drm);
@@@ -382,7 -380,7 +382,7 @@@ static irqreturn_t handle_lcd_irq(struc
                if (val & LAYER3_DMA_FIFO_UNDERFLOW)
                        drm_dbg(&kmb->drm,
                                "LAYER3:GL1 DMA UNDERFLOW val = 0x%lx", val);
-               if (val & LAYER3_DMA_FIFO_UNDERFLOW)
+               if (val & LAYER3_DMA_FIFO_OVERFLOW)
                        drm_dbg(&kmb->drm,
                                "LAYER3:GL1 DMA OVERFLOW val = 0x%lx", val);
        }
@@@ -561,8 -559,6 +561,8 @@@ static int kmb_probe(struct platform_de
        if (ret)
                goto err_register;
  
 +      drm_fbdev_generic_setup(&kmb->drm, 0);
 +
        return 0;
  
   err_register:
index ad73ebb84b2dd259f23cba7e422d7c67e2b9195f,75ae3008b68f4a2bb81f2cb4a439a42174c8d199..5cd230a5d5d3e7ef65e5948ca87de65811dc46f7
@@@ -112,7 -112,18 +112,7 @@@ static int dsi_bind(struct device *dev
  {
        struct drm_device *drm = dev_get_drvdata(master);
        struct msm_drm_private *priv = drm->dev_private;
 -      struct platform_device *pdev = to_platform_device(dev);
 -      struct msm_dsi *msm_dsi;
 -
 -      DBG("");
 -      msm_dsi = dsi_init(pdev);
 -      if (IS_ERR(msm_dsi)) {
 -              /* Don't fail the bind if the dsi port is not connected */
 -              if (PTR_ERR(msm_dsi) == -ENODEV)
 -                      return 0;
 -              else
 -                      return PTR_ERR(msm_dsi);
 -      }
 +      struct msm_dsi *msm_dsi = dev_get_drvdata(dev);
  
        priv->dsi[msm_dsi->id] = msm_dsi;
  
@@@ -125,8 -136,12 +125,8 @@@ static void dsi_unbind(struct device *d
        struct drm_device *drm = dev_get_drvdata(master);
        struct msm_drm_private *priv = drm->dev_private;
        struct msm_dsi *msm_dsi = dev_get_drvdata(dev);
 -      int id = msm_dsi->id;
  
 -      if (priv->dsi[id]) {
 -              dsi_destroy(msm_dsi);
 -              priv->dsi[id] = NULL;
 -      }
 +      priv->dsi[msm_dsi->id] = NULL;
  }
  
  static const struct component_ops dsi_ops = {
        .unbind = dsi_unbind,
  };
  
 -static int dsi_dev_probe(struct platform_device *pdev)
 +int dsi_dev_attach(struct platform_device *pdev)
  {
        return component_add(&pdev->dev, &dsi_ops);
  }
  
 +void dsi_dev_detach(struct platform_device *pdev)
 +{
 +      component_del(&pdev->dev, &dsi_ops);
 +}
 +
 +static int dsi_dev_probe(struct platform_device *pdev)
 +{
 +      struct msm_dsi *msm_dsi;
 +
 +      DBG("");
 +      msm_dsi = dsi_init(pdev);
 +      if (IS_ERR(msm_dsi)) {
 +              /* Don't fail the bind if the dsi port is not connected */
 +              if (PTR_ERR(msm_dsi) == -ENODEV)
 +                      return 0;
 +              else
 +                      return PTR_ERR(msm_dsi);
 +      }
 +
 +      return 0;
 +}
 +
  static int dsi_dev_remove(struct platform_device *pdev)
  {
 +      struct msm_dsi *msm_dsi = platform_get_drvdata(pdev);
 +
        DBG("");
 -      component_del(&pdev->dev, &dsi_ops);
 +      dsi_destroy(msm_dsi);
 +
        return 0;
  }
  
@@@ -225,8 -215,10 +225,10 @@@ int msm_dsi_modeset_init(struct msm_ds
                goto fail;
        }
  
-       if (!msm_dsi_manager_validate_current_config(msm_dsi->id))
+       if (!msm_dsi_manager_validate_current_config(msm_dsi->id)) {
+               ret = -EINVAL;
                goto fail;
+       }
  
        msm_dsi->encoder = encoder;
  
index 83787cbee41938f921e067ce393b89a24c9bb3ee,569c8ff062ba484ab74e16b0dfef23d8613b00bc..bb39e7ca802de719c69f08aef4179c022be9caba
@@@ -107,6 -107,8 +107,8 @@@ void msm_dsi_host_cmd_xfer_commit(struc
                                        u32 dma_base, u32 len);
  int msm_dsi_host_enable(struct mipi_dsi_host *host);
  int msm_dsi_host_disable(struct mipi_dsi_host *host);
+ void msm_dsi_host_enable_irq(struct mipi_dsi_host *host);
+ void msm_dsi_host_disable_irq(struct mipi_dsi_host *host);
  int msm_dsi_host_power_on(struct mipi_dsi_host *host,
                        struct msm_dsi_phy_shared_timings *phy_shared_timings,
                        bool is_bonded_dsi, struct msm_dsi_phy *phy);
@@@ -116,7 -118,7 +118,7 @@@ int msm_dsi_host_set_display_mode(struc
  struct drm_panel *msm_dsi_host_get_panel(struct mipi_dsi_host *host);
  unsigned long msm_dsi_host_get_mode_flags(struct mipi_dsi_host *host);
  struct drm_bridge *msm_dsi_host_get_bridge(struct mipi_dsi_host *host);
 -int msm_dsi_host_register(struct mipi_dsi_host *host, bool check_defer);
 +int msm_dsi_host_register(struct mipi_dsi_host *host);
  void msm_dsi_host_unregister(struct mipi_dsi_host *host);
  int msm_dsi_host_set_src_pll(struct mipi_dsi_host *host,
                        struct msm_dsi_phy *src_phy);
index f741494b1bf62738f54c914634b6f4b1dde03aa6,f69a125f955958ae41d89cf9214c1cb963df30d6..4c7b6944fc0dcdcca71b45e816f973eb734f5c6d
@@@ -106,7 -106,8 +106,8 @@@ struct msm_dsi_host 
        phys_addr_t ctrl_size;
        struct regulator_bulk_data supplies[DSI_DEV_REGULATOR_MAX];
  
-       struct clk *bus_clks[DSI_BUS_CLK_MAX];
+       int num_bus_clks;
+       struct clk_bulk_data bus_clks[DSI_BUS_CLK_MAX];
  
        struct clk *byte_clk;
        struct clk *esc_clk;
        struct clk *pixel_clk_src;
        struct clk *byte_intf_clk;
  
-       u32 byte_clk_rate;
-       u32 pixel_clk_rate;
-       u32 esc_clk_rate;
+       unsigned long byte_clk_rate;
+       unsigned long pixel_clk_rate;
+       unsigned long esc_clk_rate;
  
        /* DSI v2 specific clocks */
        struct clk *src_clk;
        struct clk *esc_clk_src;
        struct clk *dsi_clk_src;
  
-       u32 src_clk_rate;
+       unsigned long src_clk_rate;
  
        struct gpio_desc *disp_en_gpio;
        struct gpio_desc *te_gpio;
@@@ -374,15 -375,14 +375,14 @@@ static int dsi_clk_init(struct msm_dsi_
        int i, ret = 0;
  
        /* get bus clocks */
-       for (i = 0; i < cfg->num_bus_clks; i++) {
-               msm_host->bus_clks[i] = msm_clk_get(pdev,
-                                               cfg->bus_clk_names[i]);
-               if (IS_ERR(msm_host->bus_clks[i])) {
-                       ret = PTR_ERR(msm_host->bus_clks[i]);
-                       pr_err("%s: Unable to get %s clock, ret = %d\n",
-                               __func__, cfg->bus_clk_names[i], ret);
-                       goto exit;
-               }
+       for (i = 0; i < cfg->num_bus_clks; i++)
+               msm_host->bus_clks[i].id = cfg->bus_clk_names[i];
+       msm_host->num_bus_clks = cfg->num_bus_clks;
+       ret = devm_clk_bulk_get(&pdev->dev, msm_host->num_bus_clks, msm_host->bus_clks);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "Unable to get clocks, ret = %d\n", ret);
+               goto exit;
        }
  
        /* get link and source clocks */
@@@ -433,41 -433,6 +433,6 @@@ exit
        return ret;
  }
  
- static int dsi_bus_clk_enable(struct msm_dsi_host *msm_host)
- {
-       const struct msm_dsi_config *cfg = msm_host->cfg_hnd->cfg;
-       int i, ret;
-       DBG("id=%d", msm_host->id);
-       for (i = 0; i < cfg->num_bus_clks; i++) {
-               ret = clk_prepare_enable(msm_host->bus_clks[i]);
-               if (ret) {
-                       pr_err("%s: failed to enable bus clock %d ret %d\n",
-                               __func__, i, ret);
-                       goto err;
-               }
-       }
-       return 0;
- err:
-       for (; i > 0; i--)
-               clk_disable_unprepare(msm_host->bus_clks[i]);
-       return ret;
- }
- static void dsi_bus_clk_disable(struct msm_dsi_host *msm_host)
- {
-       const struct msm_dsi_config *cfg = msm_host->cfg_hnd->cfg;
-       int i;
-       DBG("");
-       for (i = cfg->num_bus_clks - 1; i >= 0; i--)
-               clk_disable_unprepare(msm_host->bus_clks[i]);
- }
  int msm_dsi_runtime_suspend(struct device *dev)
  {
        struct platform_device *pdev = to_platform_device(dev);
        if (!msm_host->cfg_hnd)
                return 0;
  
-       dsi_bus_clk_disable(msm_host);
+       clk_bulk_disable_unprepare(msm_host->num_bus_clks, msm_host->bus_clks);
  
        return 0;
  }
@@@ -493,15 -458,15 +458,15 @@@ int msm_dsi_runtime_resume(struct devic
        if (!msm_host->cfg_hnd)
                return 0;
  
-       return dsi_bus_clk_enable(msm_host);
+       return clk_bulk_prepare_enable(msm_host->num_bus_clks, msm_host->bus_clks);
  }
  
  int dsi_link_clk_set_rate_6g(struct msm_dsi_host *msm_host)
  {
-       u32 byte_intf_rate;
+       unsigned long byte_intf_rate;
        int ret;
  
-       DBG("Set clk rates: pclk=%d, byteclk=%d",
+       DBG("Set clk rates: pclk=%d, byteclk=%lu",
                msm_host->mode->clock, msm_host->byte_clk_rate);
  
        ret = dev_pm_opp_set_rate(&msm_host->pdev->dev,
@@@ -558,13 -523,11 +523,11 @@@ int dsi_link_clk_enable_6g(struct msm_d
                goto pixel_clk_err;
        }
  
-       if (msm_host->byte_intf_clk) {
-               ret = clk_prepare_enable(msm_host->byte_intf_clk);
-               if (ret) {
-                       pr_err("%s: Failed to enable byte intf clk\n",
-                              __func__);
-                       goto byte_intf_clk_err;
-               }
+       ret = clk_prepare_enable(msm_host->byte_intf_clk);
+       if (ret) {
+               pr_err("%s: Failed to enable byte intf clk\n",
+                          __func__);
+               goto byte_intf_clk_err;
        }
  
        return 0;
@@@ -583,7 -546,7 +546,7 @@@ int dsi_link_clk_set_rate_v2(struct msm
  {
        int ret;
  
-       DBG("Set clk rates: pclk=%d, byteclk=%d, esc_clk=%d, dsi_src_clk=%d",
+       DBG("Set clk rates: pclk=%d, byteclk=%lu, esc_clk=%lu, dsi_src_clk=%lu",
                msm_host->mode->clock, msm_host->byte_clk_rate,
                msm_host->esc_clk_rate, msm_host->src_clk_rate);
  
@@@ -660,8 -623,7 +623,7 @@@ void dsi_link_clk_disable_6g(struct msm
        dev_pm_opp_set_rate(&msm_host->pdev->dev, 0);
        clk_disable_unprepare(msm_host->esc_clk);
        clk_disable_unprepare(msm_host->pixel_clk);
-       if (msm_host->byte_intf_clk)
-               clk_disable_unprepare(msm_host->byte_intf_clk);
+       clk_disable_unprepare(msm_host->byte_intf_clk);
        clk_disable_unprepare(msm_host->byte_clk);
  }
  
@@@ -673,10 -635,10 +635,10 @@@ void dsi_link_clk_disable_v2(struct msm
        clk_disable_unprepare(msm_host->byte_clk);
  }
  
- static u32 dsi_get_pclk_rate(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
+ static unsigned long dsi_get_pclk_rate(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
  {
        struct drm_display_mode *mode = msm_host->mode;
-       u32 pclk_rate;
+       unsigned long pclk_rate;
  
        pclk_rate = mode->clock * 1000;
  
@@@ -696,7 -658,7 +658,7 @@@ static void dsi_calc_pclk(struct msm_ds
  {
        u8 lanes = msm_host->lanes;
        u32 bpp = dsi_get_bpp(msm_host->format);
-       u32 pclk_rate = dsi_get_pclk_rate(msm_host, is_bonded_dsi);
+       unsigned long pclk_rate = dsi_get_pclk_rate(msm_host, is_bonded_dsi);
        u64 pclk_bpp = (u64)pclk_rate * bpp;
  
        if (lanes == 0) {
        msm_host->pixel_clk_rate = pclk_rate;
        msm_host->byte_clk_rate = pclk_bpp;
  
-       DBG("pclk=%d, bclk=%d", msm_host->pixel_clk_rate,
+       DBG("pclk=%lu, bclk=%lu", msm_host->pixel_clk_rate,
                                msm_host->byte_clk_rate);
  
  }
@@@ -772,7 -734,7 +734,7 @@@ int dsi_calc_clk_rate_v2(struct msm_dsi
  
        msm_host->esc_clk_rate = msm_host->byte_clk_rate / esc_div;
  
-       DBG("esc=%d, src=%d", msm_host->esc_clk_rate,
+       DBG("esc=%lu, src=%lu", msm_host->esc_clk_rate,
                msm_host->src_clk_rate);
  
        return 0;
@@@ -1624,10 -1586,6 +1586,10 @@@ static int dsi_host_attach(struct mipi_
        if (ret)
                return ret;
  
 +      ret = dsi_dev_attach(msm_host->pdev);
 +      if (ret)
 +              return ret;
 +
        DBG("id=%d", msm_host->id);
        if (msm_host->dev)
                queue_work(msm_host->workqueue, &msm_host->hpd_work);
@@@ -1640,8 -1598,6 +1602,8 @@@ static int dsi_host_detach(struct mipi_
  {
        struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
  
 +      dsi_dev_detach(msm_host->pdev);
 +
        msm_host->device_node = NULL;
  
        DBG("id=%d", msm_host->id);
@@@ -1904,6 -1860,23 +1866,23 @@@ int msm_dsi_host_init(struct msm_dsi *m
                return ret;
        }
  
+       msm_host->irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
+       if (msm_host->irq < 0) {
+               ret = msm_host->irq;
+               dev_err(&pdev->dev, "failed to get irq: %d\n", ret);
+               return ret;
+       }
+       /* do not autoenable, will be enabled later */
+       ret = devm_request_irq(&pdev->dev, msm_host->irq, dsi_host_irq,
+                       IRQF_TRIGGER_HIGH | IRQF_ONESHOT | IRQF_NO_AUTOEN,
+                       "dsi_isr", msm_host);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "failed to request IRQ%u: %d\n",
+                               msm_host->irq, ret);
+               return ret;
+       }
        init_completion(&msm_host->dma_comp);
        init_completion(&msm_host->video_comp);
        mutex_init(&msm_host->dev_mutex);
@@@ -1931,7 -1904,6 +1910,6 @@@ void msm_dsi_host_destroy(struct mipi_d
        DBG("");
        dsi_tx_buf_free(msm_host);
        if (msm_host->workqueue) {
-               flush_workqueue(msm_host->workqueue);
                destroy_workqueue(msm_host->workqueue);
                msm_host->workqueue = NULL;
        }
@@@ -1947,25 -1919,8 +1925,8 @@@ int msm_dsi_host_modeset_init(struct mi
  {
        struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
        const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
-       struct platform_device *pdev = msm_host->pdev;
        int ret;
  
-       msm_host->irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
-       if (msm_host->irq < 0) {
-               ret = msm_host->irq;
-               DRM_DEV_ERROR(dev->dev, "failed to get irq: %d\n", ret);
-               return ret;
-       }
-       ret = devm_request_irq(&pdev->dev, msm_host->irq,
-                       dsi_host_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
-                       "dsi_isr", msm_host);
-       if (ret < 0) {
-               DRM_DEV_ERROR(&pdev->dev, "failed to request IRQ%u: %d\n",
-                               msm_host->irq, ret);
-               return ret;
-       }
        msm_host->dev = dev;
        ret = cfg_hnd->ops->tx_buf_alloc(msm_host, SZ_4K);
        if (ret) {
        return 0;
  }
  
 -int msm_dsi_host_register(struct mipi_dsi_host *host, bool check_defer)
 +int msm_dsi_host_register(struct mipi_dsi_host *host)
  {
        struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
        int ret;
                        return ret;
  
                msm_host->registered = true;
 -
 -              /* If the panel driver has not been probed after host register,
 -               * we should defer the host's probe.
 -               * It makes sure panel is connected when fbcon detects
 -               * connector status and gets the proper display mode to
 -               * create framebuffer.
 -               * Don't try to defer if there is nothing connected to the dsi
 -               * output
 -               */
 -              if (check_defer && msm_host->device_node) {
 -                      if (IS_ERR(of_drm_find_panel(msm_host->device_node)))
 -                              if (!of_drm_find_bridge(msm_host->device_node))
 -                                      return -EPROBE_DEFER;
 -              }
        }
  
        return 0;
@@@ -2307,6 -2276,20 +2268,20 @@@ void msm_dsi_host_get_phy_clk_req(struc
        clk_req->escclk_rate = msm_host->esc_clk_rate;
  }
  
+ void msm_dsi_host_enable_irq(struct mipi_dsi_host *host)
+ {
+       struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+       enable_irq(msm_host->irq);
+ }
+ void msm_dsi_host_disable_irq(struct mipi_dsi_host *host)
+ {
+       struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+       disable_irq(msm_host->irq);
+ }
  int msm_dsi_host_enable(struct mipi_dsi_host *host)
  {
        struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
index fc949a84cef60efea22353685097e32140001cf5,20c4d650fd80c40cbc7e9e80cd18e8313f46bf83..01bf8d907933394e0a4784c9efea6a1a41575c8c
@@@ -3,6 -3,8 +3,8 @@@
   * Copyright (c) 2015, The Linux Foundation. All rights reserved.
   */
  
+ #include "drm/drm_bridge_connector.h"
  #include "msm_kms.h"
  #include "dsi.h"
  
@@@ -72,7 -74,7 +74,7 @@@ static int dsi_mgr_setup_components(in
        int ret;
  
        if (!IS_BONDED_DSI()) {
 -              ret = msm_dsi_host_register(msm_dsi->host, true);
 +              ret = msm_dsi_host_register(msm_dsi->host);
                if (ret)
                        return ret;
  
                 * because only master DSI device adds the panel to global
                 * panel list. The panel's device is the master DSI device.
                 */
 -              ret = msm_dsi_host_register(slave_link_dsi->host, false);
 +              ret = msm_dsi_host_register(slave_link_dsi->host);
                if (ret)
                        return ret;
 -              ret = msm_dsi_host_register(master_link_dsi->host, true);
 +              ret = msm_dsi_host_register(master_link_dsi->host);
                if (ret)
                        return ret;
  
@@@ -377,6 -379,14 +379,14 @@@ static void dsi_mgr_bridge_pre_enable(s
                }
        }
  
+       /*
+        * Enable before preparing the panel, disable after unpreparing, so
+        * that the panel can communicate over the DSI link.
+        */
+       msm_dsi_host_enable_irq(host);
+       if (is_bonded_dsi && msm_dsi1)
+               msm_dsi_host_enable_irq(msm_dsi1->host);
        /* Always call panel functions once, because even for dual panels,
         * there is only one drm_panel instance.
         */
@@@ -411,6 -421,10 +421,10 @@@ host_en_fail
        if (panel)
                drm_panel_unprepare(panel);
  panel_prep_fail:
+       msm_dsi_host_disable_irq(host);
+       if (is_bonded_dsi && msm_dsi1)
+               msm_dsi_host_disable_irq(msm_dsi1->host);
        if (is_bonded_dsi && msm_dsi1)
                msm_dsi_host_power_off(msm_dsi1->host);
  host1_on_fail:
@@@ -523,6 -537,10 +537,10 @@@ static void dsi_mgr_bridge_post_disable
                                                                id, ret);
        }
  
+       msm_dsi_host_disable_irq(host);
+       if (is_bonded_dsi && msm_dsi1)
+               msm_dsi_host_disable_irq(msm_dsi1->host);
        /* Save PHY status if it is a clock source */
        msm_dsi_phy_pll_save_state(msm_dsi->phy);
  
@@@ -688,10 -706,10 +706,10 @@@ struct drm_connector *msm_dsi_manager_e
  {
        struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
        struct drm_device *dev = msm_dsi->dev;
+       struct drm_connector *connector;
        struct drm_encoder *encoder;
        struct drm_bridge *int_bridge, *ext_bridge;
-       struct drm_connector *connector;
-       struct list_head *connector_list;
+       int ret;
  
        int_bridge = msm_dsi->bridge;
        ext_bridge = msm_dsi->external_bridge =
  
        encoder = msm_dsi->encoder;
  
-       /* link the internal dsi bridge to the external bridge */
-       drm_bridge_attach(encoder, ext_bridge, int_bridge, 0);
        /*
-        * we need the drm_connector created by the external bridge
-        * driver (or someone else) to feed it to our driver's
-        * priv->connector[] list, mainly for msm_fbdev_init()
+        * Try first to create the bridge without it creating its own
+        * connector.. currently some bridges support this, and others
+        * do not (and some support both modes)
         */
-       connector_list = &dev->mode_config.connector_list;
+       ret = drm_bridge_attach(encoder, ext_bridge, int_bridge,
+                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+       if (ret == -EINVAL) {
+               struct drm_connector *connector;
+               struct list_head *connector_list;
+               /* link the internal dsi bridge to the external bridge */
+               drm_bridge_attach(encoder, ext_bridge, int_bridge, 0);
+               /*
+                * we need the drm_connector created by the external bridge
+                * driver (or someone else) to feed it to our driver's
+                * priv->connector[] list, mainly for msm_fbdev_init()
+                */
+               connector_list = &dev->mode_config.connector_list;
+               list_for_each_entry(connector, connector_list, head) {
+                       if (drm_connector_has_possible_encoder(connector, encoder))
+                               return connector;
+               }
+               return ERR_PTR(-ENODEV);
+       }
  
-       list_for_each_entry(connector, connector_list, head) {
-               if (drm_connector_has_possible_encoder(connector, encoder))
-                       return connector;
+       connector = drm_bridge_connector_init(dev, encoder);
+       if (IS_ERR(connector)) {
+               DRM_ERROR("Unable to create bridge connector\n");
+               return ERR_CAST(connector);
        }
  
-       return ERR_PTR(-ENODEV);
+       drm_connector_attach_encoder(connector, encoder);
+       return connector;
  }
  
  void msm_dsi_manager_bridge_destroy(struct drm_bridge *bridge)
index 31d50e98a723d1fe06246022cabeb2860a572551,69952b2393843b464d0a6f47edca68758dd8f092..eb984d925f4d5839ca1807b4fcc0c92c81dd05de
@@@ -53,14 -53,6 +53,6 @@@ struct msm_disp_state
  
  #define FRAC_16_16(mult, div)    (((mult) << 16) / (div))
  
- struct msm_file_private {
-       rwlock_t queuelock;
-       struct list_head submitqueues;
-       int queueid;
-       struct msm_gem_address_space *aspace;
-       struct kref ref;
- };
  enum msm_mdp_plane_property {
        PLANE_PROP_ZPOS,
        PLANE_PROP_ALPHA,
        PLANE_PROP_MAX_NUM
  };
  
+ enum msm_dp_controller {
+       MSM_DP_CONTROLLER_0,
+       MSM_DP_CONTROLLER_1,
+       MSM_DP_CONTROLLER_2,
+       MSM_DP_CONTROLLER_COUNT,
+ };
  #define MSM_GPU_MAX_RINGS 4
  #define MAX_H_TILES_PER_DISPLAY 2
  
@@@ -161,7 -160,7 +160,7 @@@ struct msm_drm_private 
        /* DSI is shared by mdp4 and mdp5 */
        struct msm_dsi *dsi[2];
  
-       struct msm_dp *dp;
+       struct msm_dp *dp[MSM_DP_CONTROLLER_COUNT];
  
        /* when we have more than one 'msm_gpu' these need to be an array: */
        struct msm_gpu *gpu;
@@@ -344,8 -343,6 +343,8 @@@ int msm_edp_modeset_init(struct msm_ed
  
  struct msm_dsi;
  #ifdef CONFIG_DRM_MSM_DSI
 +int dsi_dev_attach(struct platform_device *pdev);
 +void dsi_dev_detach(struct platform_device *pdev);
  void __init msm_dsi_register(void);
  void __exit msm_dsi_unregister(void);
  int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev,
@@@ -490,40 -487,27 +489,27 @@@ void msm_writel(u32 data, void __iomem 
  u32 msm_readl(const void __iomem *addr);
  void msm_rmw(void __iomem *addr, u32 mask, u32 or);
  
- struct msm_gpu_submitqueue;
- int msm_submitqueue_init(struct drm_device *drm, struct msm_file_private *ctx);
- struct msm_gpu_submitqueue *msm_submitqueue_get(struct msm_file_private *ctx,
-               u32 id);
- int msm_submitqueue_create(struct drm_device *drm,
-               struct msm_file_private *ctx,
-               u32 prio, u32 flags, u32 *id);
- int msm_submitqueue_query(struct drm_device *drm, struct msm_file_private *ctx,
-               struct drm_msm_submitqueue_query *args);
- int msm_submitqueue_remove(struct msm_file_private *ctx, u32 id);
- void msm_submitqueue_close(struct msm_file_private *ctx);
- void msm_submitqueue_destroy(struct kref *kref);
- static inline void __msm_file_private_destroy(struct kref *kref)
- {
-       struct msm_file_private *ctx = container_of(kref,
-               struct msm_file_private, ref);
-       msm_gem_address_space_put(ctx->aspace);
-       kfree(ctx);
- }
- static inline void msm_file_private_put(struct msm_file_private *ctx)
- {
-       kref_put(&ctx->ref, __msm_file_private_destroy);
- }
+ /**
+  * struct msm_hrtimer_work - a helper to combine an hrtimer with kthread_work
+  *
+  * @timer: hrtimer to control when the kthread work is triggered
+  * @work:  the kthread work
+  * @worker: the kthread worker the work will be scheduled on
+  */
+ struct msm_hrtimer_work {
+       struct hrtimer timer;
+       struct kthread_work work;
+       struct kthread_worker *worker;
+ };
  
- static inline struct msm_file_private *msm_file_private_get(
-       struct msm_file_private *ctx)
- {
-       kref_get(&ctx->ref);
-       return ctx;
- }
+ void msm_hrtimer_queue_work(struct msm_hrtimer_work *work,
+                           ktime_t wakeup_time,
+                           enum hrtimer_mode mode);
+ void msm_hrtimer_work_init(struct msm_hrtimer_work *work,
+                          struct kthread_worker *worker,
+                          kthread_work_func_t fn,
+                          clockid_t clock_id,
+                          enum hrtimer_mode mode);
  
  #define DBG(fmt, ...) DRM_DEBUG_DRIVER(fmt"\n", ##__VA_ARGS__)
  #define VERB(fmt, ...) if (0) DRM_DEBUG_DRIVER(fmt"\n", ##__VA_ARGS__)
@@@ -549,7 -533,7 +535,7 @@@ static inline int align_pitch(int width
  static inline unsigned long timeout_to_jiffies(const ktime_t *timeout)
  {
        ktime_t now = ktime_get();
-       unsigned long remaining_jiffies;
+       s64 remaining_jiffies;
  
        if (ktime_compare(*timeout, now) < 0) {
                remaining_jiffies = 0;
                remaining_jiffies = ktime_divns(rem, NSEC_PER_SEC / HZ);
        }
  
-       return remaining_jiffies;
+       return clamp(remaining_jiffies, 0LL, (s64)INT_MAX);
  }
  
  #endif /* __MSM_DRV_H__ */
index 3878b8dc2d59c21cc6524bdd1efaa2cfb9b1c59e,104fdfc140278863c62a1dc1225c253d863e727a..2916480d9115c518b9eaddf71c205c8c6de6b55e
@@@ -5,6 -5,7 +5,7 @@@
   */
  
  #include <linux/dma-map-ops.h>
+ #include <linux/vmalloc.h>
  #include <linux/spinlock.h>
  #include <linux/shmem_fs.h>
  #include <linux/dma-buf.h>
@@@ -865,11 -866,23 +866,11 @@@ int msm_gem_cpu_fini(struct drm_gem_obj
  }
  
  #ifdef CONFIG_DEBUG_FS
 -static void describe_fence(struct dma_fence *fence, const char *type,
 -              struct seq_file *m)
 -{
 -      if (!dma_fence_is_signaled(fence))
 -              seq_printf(m, "\t%9s: %s %s seq %llu\n", type,
 -                              fence->ops->get_driver_name(fence),
 -                              fence->ops->get_timeline_name(fence),
 -                              fence->seqno);
 -}
 -
  void msm_gem_describe(struct drm_gem_object *obj, struct seq_file *m,
                struct msm_gem_stats *stats)
  {
        struct msm_gem_object *msm_obj = to_msm_bo(obj);
        struct dma_resv *robj = obj->resv;
 -      struct dma_resv_list *fobj;
 -      struct dma_fence *fence;
        struct msm_gem_vma *vma;
        uint64_t off = drm_vma_node_start(&obj->vma_node);
        const char *madv;
                seq_puts(m, "\n");
        }
  
 -      rcu_read_lock();
 -      fobj = dma_resv_shared_list(robj);
 -      if (fobj) {
 -              unsigned int i, shared_count = fobj->shared_count;
 -
 -              for (i = 0; i < shared_count; i++) {
 -                      fence = rcu_dereference(fobj->shared[i]);
 -                      describe_fence(fence, "Shared", m);
 -              }
 -      }
 -
 -      fence = dma_resv_excl_fence(robj);
 -      if (fence)
 -              describe_fence(fence, "Exclusive", m);
 -      rcu_read_unlock();
 -
 +      dma_resv_describe(robj, m);
        msm_gem_unlock(obj);
  }
  
@@@ -1105,6 -1133,7 +1106,7 @@@ static int msm_gem_new_impl(struct drm_
        msm_obj->flags = flags;
        msm_obj->madv = MSM_MADV_WILLNEED;
  
+       INIT_LIST_HEAD(&msm_obj->node);
        INIT_LIST_HEAD(&msm_obj->vmas);
  
        *obj = &msm_obj->base;
@@@ -1139,7 -1168,7 +1141,7 @@@ struct drm_gem_object *msm_gem_new(stru
  
        ret = msm_gem_new_impl(dev, size, flags, &obj);
        if (ret)
-               goto fail;
+               return ERR_PTR(ret);
  
        msm_obj = to_msm_bo(obj);
  
@@@ -1223,7 -1252,7 +1225,7 @@@ struct drm_gem_object *msm_gem_import(s
  
        ret = msm_gem_new_impl(dev, size, MSM_BO_WC, &obj);
        if (ret)
-               goto fail;
+               return ERR_PTR(ret);
  
        drm_gem_private_object_init(dev, obj, size);
  
index 49eb8e9fef2267e94323f4f00f7ca83bdd322e96,66f32d965c7239496f38f783ddebf2ca0f5b0e33..29428e770f1460407d02194fbe3dc91ed303c1e3
@@@ -84,10 -84,7 +84,10 @@@ static void nv50_crc_ctx_flip_work(stru
        struct nv50_crc *crc = container_of(work, struct nv50_crc, flip_work);
        struct nv50_head *head = container_of(crc, struct nv50_head, crc);
        struct drm_crtc *crtc = &head->base.base;
 -      struct nv50_disp *disp = nv50_disp(crtc->dev);
 +      struct drm_device *dev = crtc->dev;
 +      struct nv50_disp *disp = nv50_disp(dev);
 +      const uint64_t start_vbl = drm_crtc_vblank_count(crtc);
 +      uint64_t end_vbl;
        u8 new_idx = crc->ctx_idx ^ 1;
  
        /*
         * try again for the next vblank if we don't grab the lock
         */
        if (!mutex_trylock(&disp->mutex)) {
 -              DRM_DEV_DEBUG_KMS(crtc->dev->dev,
 -                                "Lock contended, delaying CRC ctx flip for head-%d\n",
 -                                head->base.index);
 -              drm_vblank_work_schedule(work,
 -                                       drm_crtc_vblank_count(crtc) + 1,
 -                                       true);
 +              drm_dbg_kms(dev, "Lock contended, delaying CRC ctx flip for %s\n", crtc->name);
 +              drm_vblank_work_schedule(work, start_vbl + 1, true);
                return;
        }
  
 -      DRM_DEV_DEBUG_KMS(crtc->dev->dev,
 -                        "Flipping notifier ctx for head %d (%d -> %d)\n",
 -                        drm_crtc_index(crtc), crc->ctx_idx, new_idx);
 +      drm_dbg_kms(dev, "Flipping notifier ctx for %s (%d -> %d)\n",
 +                  crtc->name, crc->ctx_idx, new_idx);
  
        nv50_crc_program_ctx(head, NULL);
        nv50_crc_program_ctx(head, &crc->ctx[new_idx]);
        mutex_unlock(&disp->mutex);
  
 +      end_vbl = drm_crtc_vblank_count(crtc);
 +      if (unlikely(end_vbl != start_vbl))
 +              NV_ERROR(nouveau_drm(dev),
 +                       "Failed to flip CRC context on %s on time (%llu > %llu)\n",
 +                       crtc->name, end_vbl, start_vbl);
 +
        spin_lock_irq(&crc->lock);
        crc->ctx_changed = true;
        spin_unlock_irq(&crc->lock);
@@@ -193,9 -189,9 +193,9 @@@ void nv50_crc_handle_vblank(struct nv50
                 * updates back-to-back without waiting, we'll just be
                 * optimistic and assume we always miss exactly one frame.
                 */
 -              DRM_DEV_DEBUG_KMS(head->base.base.dev->dev,
 -                                "Notifier ctx flip for head-%d finished, lost CRC for frame %llu\n",
 -                                head->base.index, crc->frame);
 +              drm_dbg_kms(head->base.base.dev,
 +                          "Notifier ctx flip for head-%d finished, lost CRC for frame %llu\n",
 +                          head->base.index, crc->frame);
                crc->frame++;
  
                nv50_crc_reset_ctx(ctx);
@@@ -351,6 -347,8 +351,6 @@@ int nv50_crc_atomic_check_head(struct n
                               struct nv50_head_atom *armh)
  {
        struct nv50_atom *atom = nv50_atom(asyh->state.state);
 -      struct drm_device *dev = head->base.base.dev;
 -      struct nv50_disp *disp = nv50_disp(dev);
        bool changed = armh->crc.src != asyh->crc.src;
  
        if (!armh->crc.src && !asyh->crc.src) {
                return 0;
        }
  
 -      /* While we don't care about entry tags, Volta+ hw always needs the
 -       * controlling wndw channel programmed to a wndw that's owned by our
 -       * head
 -       */
 -      if (asyh->crc.src && disp->disp->object.oclass >= GV100_DISP &&
 -          !(BIT(asyh->crc.wndw) & asyh->wndw.owned)) {
 -              if (!asyh->wndw.owned) {
 -                      /* TODO: once we support flexible channel ownership,
 -                       * we should write some code here to handle attempting
 -                       * to "steal" a plane: e.g. take a plane that is
 -                       * currently not-visible and owned by another head,
 -                       * and reassign it to this head. If we fail to do so,
 -                       * we shuld reject the mode outright as CRC capture
 -                       * then becomes impossible.
 -                       */
 -                      NV_ATOMIC(nouveau_drm(dev),
 -                                "No available wndws for CRC readback\n");
 -                      return -EINVAL;
 -              }
 -              asyh->crc.wndw = ffs(asyh->wndw.owned) - 1;
 -      }
 -
 -      if (drm_atomic_crtc_needs_modeset(&asyh->state) || changed ||
 -          armh->crc.wndw != asyh->crc.wndw) {
 +      if (drm_atomic_crtc_needs_modeset(&asyh->state) || changed) {
                asyh->clr.crc = armh->crc.src && armh->state.active;
                asyh->set.crc = asyh->crc.src && asyh->state.active;
                if (changed)
@@@ -446,8 -467,9 +446,8 @@@ void nv50_crc_atomic_set(struct nv50_he
        struct nouveau_encoder *outp =
                nv50_real_outp(nv50_head_atom_get_encoder(asyh));
  
 -      func->set_src(head, outp->or,
 -                    nv50_crc_source_type(outp, asyh->crc.src),
 -                    &crc->ctx[crc->ctx_idx], asyh->crc.wndw);
 +      func->set_src(head, outp->or, nv50_crc_source_type(outp, asyh->crc.src),
 +                    &crc->ctx[crc->ctx_idx]);
  }
  
  void nv50_crc_atomic_clr(struct nv50_head *head)
        const struct nv50_crc_func *func =
                nv50_disp(head->base.base.dev)->core->func->crc;
  
 -      func->set_src(head, 0, NV50_CRC_SOURCE_TYPE_NONE, NULL, 0);
 +      func->set_src(head, 0, NV50_CRC_SOURCE_TYPE_NONE, NULL);
  }
  
  static inline int
@@@ -682,6 -704,7 +682,7 @@@ static const struct file_operations nv5
        .open = nv50_crc_debugfs_flip_threshold_open,
        .read = seq_read,
        .write = nv50_crc_debugfs_flip_threshold_set,
+       .release = single_release,
  };
  
  int nv50_head_crc_late_register(struct nv50_head *head)
index 23fa9ecc22967b250203a8a0c273fbe09b3faf49,8e28403ea9b14283c64eae0c15e8058cd7aaad34..ae1f4120552091c9c1f0645cef9d964494c06b4b
@@@ -852,9 -852,6 +852,9 @@@ nv50_hdmi_enable(struct drm_encoder *en
        ret = drm_hdmi_avi_infoframe_from_display_mode(&avi_frame.avi,
                                                       &nv_connector->base, mode);
        if (!ret) {
 +              drm_hdmi_avi_infoframe_quant_range(&avi_frame.avi,
 +                                                 &nv_connector->base, mode,
 +                                                 HDMI_QUANTIZATION_RANGE_FULL);
                /* We have an AVI InfoFrame, populate it to the display */
                args.pwr.avi_infoframe_length
                        = hdmi_infoframe_pack(&avi_frame, args.infoframes, 17);
@@@ -1390,11 -1387,12 +1390,11 @@@ nv50_mstm_cleanup(struct nv50_mstm *mst
  {
        struct nouveau_drm *drm = nouveau_drm(mstm->outp->base.base.dev);
        struct drm_encoder *encoder;
 -      int ret;
  
        NV_ATOMIC(drm, "%s: mstm cleanup\n", mstm->outp->base.base.name);
 -      ret = drm_dp_check_act_status(&mstm->mgr);
 +      drm_dp_check_act_status(&mstm->mgr);
  
 -      ret = drm_dp_update_payload_part2(&mstm->mgr);
 +      drm_dp_update_payload_part2(&mstm->mgr);
  
        drm_for_each_encoder(encoder, mstm->outp->base.base.dev) {
                if (encoder->encoder_type == DRM_MODE_ENCODER_DPMST) {
@@@ -1413,9 -1411,10 +1413,9 @@@ nv50_mstm_prepare(struct nv50_mstm *mst
  {
        struct nouveau_drm *drm = nouveau_drm(mstm->outp->base.base.dev);
        struct drm_encoder *encoder;
 -      int ret;
  
        NV_ATOMIC(drm, "%s: mstm prepare\n", mstm->outp->base.base.name);
-       drm_dp_update_payload_part1(&mstm->mgr);
 -      ret = drm_dp_update_payload_part1(&mstm->mgr, 1);
++      drm_dp_update_payload_part1(&mstm->mgr, 1);
  
        drm_for_each_encoder(encoder, mstm->outp->base.base.dev) {
                if (encoder->encoder_type == DRM_MODE_ENCODER_DPMST) {
index f8438a886b646f2aba1406b2fb12fe9d10462bfd,72099d1e4816902f50a623107af7c64edc6f29aa..c3c57be54e1ce24ac220cfa07229a5af1033ea49
@@@ -52,6 -52,7 +52,7 @@@ nv50_head_flush_clr(struct nv50_head *h
  void
  nv50_head_flush_set_wndw(struct nv50_head *head, struct nv50_head_atom *asyh)
  {
+       if (asyh->set.curs   ) head->func->curs_set(head, asyh);
        if (asyh->set.olut   ) {
                asyh->olut.offset = nv50_lut_load(&head->olut,
                                                  asyh->olut.buffer,
@@@ -67,7 -68,6 +68,6 @@@ nv50_head_flush_set(struct nv50_head *h
        if (asyh->set.view   ) head->func->view    (head, asyh);
        if (asyh->set.mode   ) head->func->mode    (head, asyh);
        if (asyh->set.core   ) head->func->core_set(head, asyh);
-       if (asyh->set.curs   ) head->func->curs_set(head, asyh);
        if (asyh->set.base   ) head->func->base    (head, asyh);
        if (asyh->set.ovly   ) head->func->ovly    (head, asyh);
        if (asyh->set.dither ) head->func->dither  (head, asyh);
@@@ -226,24 -226,10 +226,24 @@@ static in
  nv50_head_atomic_check_lut(struct nv50_head *head,
                           struct nv50_head_atom *asyh)
  {
 -      struct nv50_disp *disp = nv50_disp(head->base.base.dev);
 -      struct drm_property_blob *olut = asyh->state.gamma_lut;
 +      struct drm_device *dev = head->base.base.dev;
 +      struct drm_crtc *crtc = &head->base.base;
 +      struct nv50_disp *disp = nv50_disp(dev);
 +      struct nouveau_drm *drm = nouveau_drm(dev);
 +      struct drm_property_blob *olut = asyh->state.gamma_lut,
 +                               *ilut = asyh->state.degamma_lut;
        int size;
  
 +      /* Ensure that the ilut is valid */
 +      if (ilut) {
 +              size = drm_color_lut_size(ilut);
 +              if (!head->func->ilut_check(size)) {
 +                      NV_ATOMIC(drm, "Invalid size %d for degamma on [CRTC:%d:%s]\n",
 +                                size, crtc->base.id, crtc->name);
 +                      return -EINVAL;
 +              }
 +      }
 +
        /* Determine whether core output LUT should be enabled. */
        if (olut) {
                /* Check if any window(s) have stolen the core output LUT
        }
  
        if (!head->func->olut(head, asyh, size)) {
 -              DRM_DEBUG_KMS("Invalid olut\n");
 +              NV_ATOMIC(drm, "Invalid size %d for gamma on [CRTC:%d:%s]\n",
 +                        size, crtc->base.id, crtc->name);
                return -EINVAL;
        }
        asyh->olut.handle = disp->core->chan.vram.handle;
@@@ -345,17 -330,8 +345,17 @@@ nv50_head_atomic_check(struct drm_crtc 
        struct drm_connector_state *conns;
        struct drm_connector *conn;
        int i, ret;
 +      bool check_lut = asyh->state.color_mgmt_changed ||
 +                       memcmp(&armh->wndw, &asyh->wndw, sizeof(asyh->wndw));
  
        NV_ATOMIC(drm, "%s atomic_check %d\n", crtc->name, asyh->state.active);
 +
 +      if (check_lut) {
 +              ret = nv50_head_atomic_check_lut(head, asyh);
 +              if (ret)
 +                      return ret;
 +      }
 +
        if (asyh->state.active) {
                for_each_new_connector_in_state(asyh->state.state, conn, conns, i) {
                        if (conns->crtc == crtc) {
                if (asyh->state.mode_changed || asyh->state.connectors_changed)
                        nv50_head_atomic_check_mode(head, asyh);
  
 -              if (asyh->state.color_mgmt_changed ||
 -                  memcmp(&armh->wndw, &asyh->wndw, sizeof(asyh->wndw))) {
 -                      int ret = nv50_head_atomic_check_lut(head, asyh);
 -                      if (ret)
 -                              return ret;
 -
 +              if (check_lut)
                        asyh->olut.visible = asyh->olut.handle != 0;
 -              }
  
                if (asyc) {
                        if (asyc->set.scaler)
index c64670707abf9af88d2df86707d7818ddfa7be19,cfc8d644cedfd2518b9ad8a250b988e7fceb7d20..7770b18022916b04b84e3695791f5bd6762fe698
@@@ -37,17 -37,6 +37,17 @@@ config DRM_PANEL_ASUS_Z00T_TM5P5_NT3559
          NT35596 1080x1920 video mode panel as found in some Asus
          Zenfone 2 Laser Z00T devices.
  
 +config DRM_PANEL_BOE_BF060Y8M_AJ0
 +      tristate "Boe BF060Y8M-AJ0 panel"
 +      depends on OF
 +      depends on DRM_MIPI_DSI
 +      depends on BACKLIGHT_CLASS_DEVICE
 +      help
 +        Say Y here if you want to enable support for Boe BF060Y8M-AJ0
 +        5.99" AMOLED modules. The panel has a 1080x2160 resolution and
 +        uses 24 bit RGB per pixel. It provides a MIPI DSI interface to
 +        the host and backlight is controlled through DSI commands.
 +
  config DRM_PANEL_BOE_HIMAX8279D
        tristate "Boe Himax8279d panel"
        depends on OF
@@@ -200,15 -189,6 +200,15 @@@ config DRM_PANEL_JDI_LT070ME0500
          The panel has a 1200(RGB)×1920 (WUXGA) resolution and uses
          24 bit per pixel.
  
 +config DRM_PANEL_JDI_R63452
 +      tristate "JDI R63452 Full HD DSI panel"
 +      depends on OF
 +      depends on DRM_MIPI_DSI
 +      depends on BACKLIGHT_CLASS_DEVICE
 +      help
 +        Say Y here if you want to enable support for the JDI R63452
 +        DSI command mode panel as found in Xiaomi Mi 5 Devices.
 +
  config DRM_PANEL_KHADAS_TS050
        tristate "Khadas TS050 panel"
        depends on OF
@@@ -292,17 -272,6 +292,17 @@@ config DRM_PANEL_NOVATEK_NT3551
          around the Novatek NT35510 display controller, such as some
          Hydis panels.
  
 +config DRM_PANEL_NOVATEK_NT35950
 +      tristate "Novatek NT35950 DSI panel"
 +      depends on OF
 +      depends on DRM_MIPI_DSI
 +      depends on BACKLIGHT_CLASS_DEVICE
 +      help
 +        Say Y here if you want to enable support for the panels built
 +        around the Novatek NT35950 display controller, such as some
 +        Sharp panels used in Sony Xperia Z5 Premium and XZ Premium
 +        mobile phones.
 +
  config DRM_PANEL_NOVATEK_NT36672A
        tristate "Novatek NT36672A DSI panel"
        depends on OF
@@@ -338,6 -307,7 +338,7 @@@ config DRM_PANEL_OLIMEX_LCD_OLINUXIN
        depends on OF
        depends on I2C
        depends on BACKLIGHT_CLASS_DEVICE
+       select CRC32
        help
          The panel is used with different sizes LCDs, from 480x272 to
          1280x800, and 24 bit per pixel.
@@@ -610,16 -580,6 +611,16 @@@ config DRM_PANEL_SONY_ACX565AK
          Say Y here if you want to enable support for the Sony ACX565AKM
          800x600 3.5" panel (found on the Nokia N900).
  
 +config DRM_PANEL_SONY_TULIP_TRULY_NT35521
 +      tristate "Sony Tulip Truly NT35521 panel"
 +      depends on GPIOLIB && OF
 +      depends on DRM_MIPI_DSI
 +      depends on BACKLIGHT_CLASS_DEVICE
 +      help
 +        Say Y here if you want to enable support for the Sony Tulip
 +        NT35521 1280x720 video mode panel as found on Sony Xperia M4
 +        Aqua phone.
 +
  config DRM_PANEL_TDO_TL070WSH30
        tristate "TDO TL070WSH30 DSI panel"
        depends on OF
index 1b5d8f755b1257052bc11588f489ac54ff82398a,3d8a9ab47cae2face971d4deb8ed6863afc9ee71..f043b484055b2da39632c7b02d172289c845f1a0
@@@ -146,8 -146,8 +146,8 @@@ static const struct reg_sequence y030xx
        { 0x09, REG09_SUB_BRIGHT_R(0x20) },
        { 0x0a, REG0A_SUB_BRIGHT_B(0x20) },
        { 0x0b, REG0B_HD_FREERUN | REG0B_VD_FREERUN },
-       { 0x0c, REG0C_CONTRAST_R(0x10) },
-       { 0x0d, REG0D_CONTRAST_G(0x10) },
+       { 0x0c, REG0C_CONTRAST_R(0x00) },
+       { 0x0d, REG0D_CONTRAST_G(0x00) },
        { 0x0e, REG0E_CONTRAST_B(0x10) },
        { 0x0f, 0 },
        { 0x10, REG10_BRIGHT(0x7f) },
@@@ -272,14 -272,16 +272,14 @@@ static int y030xx067a_probe(struct spi_
                return -EINVAL;
  
        priv->supply = devm_regulator_get(dev, "power");
 -      if (IS_ERR(priv->supply)) {
 -              dev_err(dev, "Failed to get power supply\n");
 -              return PTR_ERR(priv->supply);
 -      }
 +      if (IS_ERR(priv->supply))
 +              return dev_err_probe(dev, PTR_ERR(priv->supply),
 +                                   "Failed to get power supply\n");
  
        priv->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
 -      if (IS_ERR(priv->reset_gpio)) {
 -              dev_err(dev, "Failed to get reset GPIO\n");
 -              return PTR_ERR(priv->reset_gpio);
 -      }
 +      if (IS_ERR(priv->reset_gpio))
 +              return dev_err_probe(dev, PTR_ERR(priv->reset_gpio),
 +                                   "Failed to get reset GPIO\n");
  
        drm_panel_init(&priv->panel, dev, &y030xx067a_funcs,
                       DRM_MODE_CONNECTOR_DPI);
index 754a0c775801ebd933cce59f0745cd022a950176,534dd7414d428cddead1d2ddfb23cba2c30cb504..ba30d11547adefec90732fd1b4e6b0146c89e10f
@@@ -42,7 -42,6 +42,7 @@@ struct ili9881c_desc 
        const struct ili9881c_instr *init;
        const size_t init_length;
        const struct drm_display_mode *mode;
 +      const unsigned long mode_flags;
  };
  
  struct ili9881c {
@@@ -52,8 -51,6 +52,8 @@@
  
        struct regulator        *power;
        struct gpio_desc        *reset;
 +
 +      enum drm_panel_orientation      orientation;
  };
  
  #define ILI9881C_SWITCH_PAGE_INSTR(_page)     \
@@@ -456,213 -453,6 +456,213 @@@ static const struct ili9881c_instr k101
        ILI9881C_COMMAND_INSTR(0xD3, 0x3F), /* VN0 */
  };
  
 +static const struct ili9881c_instr w552946ab_init[] = {
 +      ILI9881C_SWITCH_PAGE_INSTR(3),
 +      ILI9881C_COMMAND_INSTR(0x01, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x02, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x03, 0x53),
 +      ILI9881C_COMMAND_INSTR(0x04, 0x53),
 +      ILI9881C_COMMAND_INSTR(0x05, 0x13),
 +      ILI9881C_COMMAND_INSTR(0x06, 0x04),
 +      ILI9881C_COMMAND_INSTR(0x07, 0x02),
 +      ILI9881C_COMMAND_INSTR(0x08, 0x02),
 +      ILI9881C_COMMAND_INSTR(0x09, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x0A, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x0B, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x0C, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x0D, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x0E, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x0F, 0x00),
 +
 +      ILI9881C_COMMAND_INSTR(0x10, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x11, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x12, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x13, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x14, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x15, 0x08),
 +      ILI9881C_COMMAND_INSTR(0x16, 0x10),
 +      ILI9881C_COMMAND_INSTR(0x17, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x18, 0x08),
 +      ILI9881C_COMMAND_INSTR(0x19, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x1A, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x1B, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x1C, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x1D, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x1E, 0xC0),
 +      ILI9881C_COMMAND_INSTR(0x1F, 0x80),
 +
 +      ILI9881C_COMMAND_INSTR(0x20, 0x02),
 +      ILI9881C_COMMAND_INSTR(0x21, 0x09),
 +      ILI9881C_COMMAND_INSTR(0x22, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x23, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x24, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x25, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x26, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x27, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x28, 0x55),
 +      ILI9881C_COMMAND_INSTR(0x29, 0x03),
 +      ILI9881C_COMMAND_INSTR(0x2A, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x2B, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x2C, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x2D, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x2E, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x2F, 0x00),
 +
 +      ILI9881C_COMMAND_INSTR(0x30, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x31, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x32, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x33, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x34, 0x04),
 +      ILI9881C_COMMAND_INSTR(0x35, 0x05),
 +      ILI9881C_COMMAND_INSTR(0x36, 0x05),
 +      ILI9881C_COMMAND_INSTR(0x37, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x38, 0x3C),
 +      ILI9881C_COMMAND_INSTR(0x39, 0x35),
 +      ILI9881C_COMMAND_INSTR(0x3A, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x3B, 0x40),
 +      ILI9881C_COMMAND_INSTR(0x3C, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x3D, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x3E, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x3F, 0x00),
 +
 +      ILI9881C_COMMAND_INSTR(0x40, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x41, 0x88),
 +      ILI9881C_COMMAND_INSTR(0x42, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x43, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x44, 0x1F),
 +
 +      ILI9881C_COMMAND_INSTR(0x50, 0x01),
 +      ILI9881C_COMMAND_INSTR(0x51, 0x23),
 +      ILI9881C_COMMAND_INSTR(0x52, 0x45),
 +      ILI9881C_COMMAND_INSTR(0x53, 0x67),
 +      ILI9881C_COMMAND_INSTR(0x54, 0x89),
 +      ILI9881C_COMMAND_INSTR(0x55, 0xaB),
 +      ILI9881C_COMMAND_INSTR(0x56, 0x01),
 +      ILI9881C_COMMAND_INSTR(0x57, 0x23),
 +      ILI9881C_COMMAND_INSTR(0x58, 0x45),
 +      ILI9881C_COMMAND_INSTR(0x59, 0x67),
 +      ILI9881C_COMMAND_INSTR(0x5A, 0x89),
 +      ILI9881C_COMMAND_INSTR(0x5B, 0xAB),
 +      ILI9881C_COMMAND_INSTR(0x5C, 0xCD),
 +      ILI9881C_COMMAND_INSTR(0x5D, 0xEF),
 +      ILI9881C_COMMAND_INSTR(0x5E, 0x03),
 +      ILI9881C_COMMAND_INSTR(0x5F, 0x14),
 +
 +      ILI9881C_COMMAND_INSTR(0x60, 0x15),
 +      ILI9881C_COMMAND_INSTR(0x61, 0x0C),
 +      ILI9881C_COMMAND_INSTR(0x62, 0x0D),
 +      ILI9881C_COMMAND_INSTR(0x63, 0x0E),
 +      ILI9881C_COMMAND_INSTR(0x64, 0x0F),
 +      ILI9881C_COMMAND_INSTR(0x65, 0x10),
 +      ILI9881C_COMMAND_INSTR(0x66, 0x11),
 +      ILI9881C_COMMAND_INSTR(0x67, 0x08),
 +      ILI9881C_COMMAND_INSTR(0x68, 0x02),
 +      ILI9881C_COMMAND_INSTR(0x69, 0x0A),
 +      ILI9881C_COMMAND_INSTR(0x6A, 0x02),
 +      ILI9881C_COMMAND_INSTR(0x6B, 0x02),
 +      ILI9881C_COMMAND_INSTR(0x6C, 0x02),
 +      ILI9881C_COMMAND_INSTR(0x6D, 0x02),
 +      ILI9881C_COMMAND_INSTR(0x6E, 0x02),
 +      ILI9881C_COMMAND_INSTR(0x6F, 0x02),
 +
 +      ILI9881C_COMMAND_INSTR(0x70, 0x02),
 +      ILI9881C_COMMAND_INSTR(0x71, 0x02),
 +      ILI9881C_COMMAND_INSTR(0x72, 0x06),
 +      ILI9881C_COMMAND_INSTR(0x73, 0x02),
 +      ILI9881C_COMMAND_INSTR(0x74, 0x02),
 +      ILI9881C_COMMAND_INSTR(0x75, 0x14),
 +      ILI9881C_COMMAND_INSTR(0x76, 0x15),
 +      ILI9881C_COMMAND_INSTR(0x77, 0x0F),
 +      ILI9881C_COMMAND_INSTR(0x78, 0x0E),
 +      ILI9881C_COMMAND_INSTR(0x79, 0x0D),
 +      ILI9881C_COMMAND_INSTR(0x7A, 0x0C),
 +      ILI9881C_COMMAND_INSTR(0x7B, 0x11),
 +      ILI9881C_COMMAND_INSTR(0x7C, 0x10),
 +      ILI9881C_COMMAND_INSTR(0x7D, 0x06),
 +      ILI9881C_COMMAND_INSTR(0x7E, 0x02),
 +      ILI9881C_COMMAND_INSTR(0x7F, 0x0A),
 +
 +      ILI9881C_COMMAND_INSTR(0x80, 0x02),
 +      ILI9881C_COMMAND_INSTR(0x81, 0x02),
 +      ILI9881C_COMMAND_INSTR(0x82, 0x02),
 +      ILI9881C_COMMAND_INSTR(0x83, 0x02),
 +      ILI9881C_COMMAND_INSTR(0x84, 0x02),
 +      ILI9881C_COMMAND_INSTR(0x85, 0x02),
 +      ILI9881C_COMMAND_INSTR(0x86, 0x02),
 +      ILI9881C_COMMAND_INSTR(0x87, 0x02),
 +      ILI9881C_COMMAND_INSTR(0x88, 0x08),
 +      ILI9881C_COMMAND_INSTR(0x89, 0x02),
 +      ILI9881C_COMMAND_INSTR(0x8A, 0x02),
 +
 +      ILI9881C_SWITCH_PAGE_INSTR(4),
 +      ILI9881C_COMMAND_INSTR(0x00, 0x80),
 +      ILI9881C_COMMAND_INSTR(0x70, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x71, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x66, 0xFE),
 +      ILI9881C_COMMAND_INSTR(0x82, 0x15),
 +      ILI9881C_COMMAND_INSTR(0x84, 0x15),
 +      ILI9881C_COMMAND_INSTR(0x85, 0x15),
 +      ILI9881C_COMMAND_INSTR(0x3a, 0x24),
 +      ILI9881C_COMMAND_INSTR(0x32, 0xAC),
 +      ILI9881C_COMMAND_INSTR(0x8C, 0x80),
 +      ILI9881C_COMMAND_INSTR(0x3C, 0xF5),
 +      ILI9881C_COMMAND_INSTR(0x88, 0x33),
 +
 +      ILI9881C_SWITCH_PAGE_INSTR(1),
 +      ILI9881C_COMMAND_INSTR(0x22, 0x0A),
 +      ILI9881C_COMMAND_INSTR(0x31, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x53, 0x78),
 +      ILI9881C_COMMAND_INSTR(0x50, 0x5B),
 +      ILI9881C_COMMAND_INSTR(0x51, 0x5B),
 +      ILI9881C_COMMAND_INSTR(0x60, 0x20),
 +      ILI9881C_COMMAND_INSTR(0x61, 0x00),
 +      ILI9881C_COMMAND_INSTR(0x62, 0x0D),
 +      ILI9881C_COMMAND_INSTR(0x63, 0x00),
 +
 +      ILI9881C_COMMAND_INSTR(0xA0, 0x00),
 +      ILI9881C_COMMAND_INSTR(0xA1, 0x10),
 +      ILI9881C_COMMAND_INSTR(0xA2, 0x1C),
 +      ILI9881C_COMMAND_INSTR(0xA3, 0x13),
 +      ILI9881C_COMMAND_INSTR(0xA4, 0x15),
 +      ILI9881C_COMMAND_INSTR(0xA5, 0x26),
 +      ILI9881C_COMMAND_INSTR(0xA6, 0x1A),
 +      ILI9881C_COMMAND_INSTR(0xA7, 0x1D),
 +      ILI9881C_COMMAND_INSTR(0xA8, 0x67),
 +      ILI9881C_COMMAND_INSTR(0xA9, 0x1C),
 +      ILI9881C_COMMAND_INSTR(0xAA, 0x29),
 +      ILI9881C_COMMAND_INSTR(0xAB, 0x5B),
 +      ILI9881C_COMMAND_INSTR(0xAC, 0x26),
 +      ILI9881C_COMMAND_INSTR(0xAD, 0x28),
 +      ILI9881C_COMMAND_INSTR(0xAE, 0x5C),
 +      ILI9881C_COMMAND_INSTR(0xAF, 0x30),
 +      ILI9881C_COMMAND_INSTR(0xB0, 0x31),
 +      ILI9881C_COMMAND_INSTR(0xB1, 0x2E),
 +      ILI9881C_COMMAND_INSTR(0xB2, 0x32),
 +      ILI9881C_COMMAND_INSTR(0xB3, 0x00),
 +
 +      ILI9881C_COMMAND_INSTR(0xC0, 0x00),
 +      ILI9881C_COMMAND_INSTR(0xC1, 0x10),
 +      ILI9881C_COMMAND_INSTR(0xC2, 0x1C),
 +      ILI9881C_COMMAND_INSTR(0xC3, 0x13),
 +      ILI9881C_COMMAND_INSTR(0xC4, 0x15),
 +      ILI9881C_COMMAND_INSTR(0xC5, 0x26),
 +      ILI9881C_COMMAND_INSTR(0xC6, 0x1A),
 +      ILI9881C_COMMAND_INSTR(0xC7, 0x1D),
 +      ILI9881C_COMMAND_INSTR(0xC8, 0x67),
 +      ILI9881C_COMMAND_INSTR(0xC9, 0x1C),
 +      ILI9881C_COMMAND_INSTR(0xCA, 0x29),
 +      ILI9881C_COMMAND_INSTR(0xCB, 0x5B),
 +      ILI9881C_COMMAND_INSTR(0xCC, 0x26),
 +      ILI9881C_COMMAND_INSTR(0xCD, 0x28),
 +      ILI9881C_COMMAND_INSTR(0xCE, 0x5C),
 +      ILI9881C_COMMAND_INSTR(0xCF, 0x30),
 +      ILI9881C_COMMAND_INSTR(0xD0, 0x31),
 +      ILI9881C_COMMAND_INSTR(0xD1, 0x2E),
 +      ILI9881C_COMMAND_INSTR(0xD2, 0x32),
 +      ILI9881C_COMMAND_INSTR(0xD3, 0x00),
 +      ILI9881C_SWITCH_PAGE_INSTR(0),
 +};
 +
  static inline struct ili9881c *panel_to_ili9881c(struct drm_panel *panel)
  {
        return container_of(panel, struct ili9881c, panel);
@@@ -800,36 -590,19 +800,36 @@@ static const struct drm_display_mode k1
        .clock          = 69700,
  
        .hdisplay       = 800,
-       .hsync_start    = 800 + 6,
-       .hsync_end      = 800 + 6 + 15,
-       .htotal         = 800 + 6 + 15 + 16,
+       .hsync_start    = 800 + 52,
+       .hsync_end      = 800 + 52 + 8,
+       .htotal         = 800 + 52 + 8 + 48,
  
        .vdisplay       = 1280,
-       .vsync_start    = 1280 + 8,
-       .vsync_end      = 1280 + 8 + 48,
-       .vtotal         = 1280 + 8 + 48 + 52,
+       .vsync_start    = 1280 + 16,
+       .vsync_end      = 1280 + 16 + 6,
+       .vtotal         = 1280 + 16 + 6 + 15,
  
        .width_mm       = 135,
        .height_mm      = 217,
  };
  
 +static const struct drm_display_mode w552946aba_default_mode = {
 +      .clock          = 64000,
 +
 +      .hdisplay       = 720,
 +      .hsync_start    = 720 + 40,
 +      .hsync_end      = 720 + 40 + 10,
 +      .htotal         = 720 + 40 + 10 + 40,
 +
 +      .vdisplay       = 1280,
 +      .vsync_start    = 1280 + 22,
 +      .vsync_end      = 1280 + 22 + 4,
 +      .vtotal         = 1280 + 22 + 4 + 11,
 +
 +      .width_mm       = 68,
 +      .height_mm      = 121,
 +};
 +
  static int ili9881c_get_modes(struct drm_panel *panel,
                              struct drm_connector *connector)
  {
        connector->display_info.width_mm = mode->width_mm;
        connector->display_info.height_mm = mode->height_mm;
  
 +      drm_connector_set_panel_orientation(connector, ctx->orientation);
 +
        return 1;
  }
  
@@@ -882,20 -653,15 +882,20 @@@ static int ili9881c_dsi_probe(struct mi
                       DRM_MODE_CONNECTOR_DSI);
  
        ctx->power = devm_regulator_get(&dsi->dev, "power");
 -      if (IS_ERR(ctx->power)) {
 -              dev_err(&dsi->dev, "Couldn't get our power regulator\n");
 -              return PTR_ERR(ctx->power);
 -      }
 -
 -      ctx->reset = devm_gpiod_get(&dsi->dev, "reset", GPIOD_OUT_LOW);
 -      if (IS_ERR(ctx->reset)) {
 -              dev_err(&dsi->dev, "Couldn't get our reset GPIO\n");
 -              return PTR_ERR(ctx->reset);
 +      if (IS_ERR(ctx->power))
 +              return dev_err_probe(&dsi->dev, PTR_ERR(ctx->power),
 +                                   "Couldn't get our power regulator\n");
 +
 +      ctx->reset = devm_gpiod_get_optional(&dsi->dev, "reset", GPIOD_OUT_LOW);
 +      if (IS_ERR(ctx->reset))
 +              return dev_err_probe(&dsi->dev, PTR_ERR(ctx->reset),
 +                                   "Couldn't get our reset GPIO\n");
 +
 +      ret = of_drm_get_panel_orientation(dsi->dev.of_node, &ctx->orientation);
 +      if (ret) {
 +              dev_err(&dsi->dev, "%pOF: failed to get orientation: %d\n",
 +                      dsi->dev.of_node, ret);
 +              return ret;
        }
  
        ret = drm_panel_of_backlight(&ctx->panel);
  
        drm_panel_add(&ctx->panel);
  
 -      dsi->mode_flags = MIPI_DSI_MODE_VIDEO_SYNC_PULSE;
 +      dsi->mode_flags = ctx->desc->mode_flags;
        dsi->format = MIPI_DSI_FMT_RGB888;
        dsi->lanes = 4;
  
@@@ -925,28 -691,17 +925,28 @@@ static const struct ili9881c_desc lhr05
        .init = lhr050h41_init,
        .init_length = ARRAY_SIZE(lhr050h41_init),
        .mode = &lhr050h41_default_mode,
 +      .mode_flags = MIPI_DSI_MODE_VIDEO_SYNC_PULSE,
  };
  
  static const struct ili9881c_desc k101_im2byl02_desc = {
        .init = k101_im2byl02_init,
        .init_length = ARRAY_SIZE(k101_im2byl02_init),
        .mode = &k101_im2byl02_default_mode,
 +      .mode_flags = MIPI_DSI_MODE_VIDEO_SYNC_PULSE,
 +};
 +
 +static const struct ili9881c_desc w552946aba_desc = {
 +      .init = w552946ab_init,
 +      .init_length = ARRAY_SIZE(w552946ab_init),
 +      .mode = &w552946aba_default_mode,
 +      .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
 +                    MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_NO_EOT_PACKET,
  };
  
  static const struct of_device_id ili9881c_of_match[] = {
        { .compatible = "bananapi,lhr050h41", .data = &lhr050h41_desc },
        { .compatible = "feixin,k101-im2byl02", .data = &k101_im2byl02_desc },
 +      { .compatible = "wanchanglong,w552946aba", .data = &w552946aba_desc },
        { }
  };
  MODULE_DEVICE_TABLE(of, ili9881c_of_match);
index b28ea5d6a3e26b7aeb07e02d8fb3bb0f6ed856c4,a25b98b7f5bd7875c8be067b5b58e95f8d9a820f..3e8d9e2d1b675c5f3eb56e99a7f3c0997f7d0fb9
@@@ -726,9 -726,7 +726,9 @@@ static void vop_crtc_atomic_disable(str
  
        spin_unlock(&vop->reg_lock);
  
 -      wait_for_completion(&vop->dsp_hold_completion);
 +      if (!wait_for_completion_timeout(&vop->dsp_hold_completion,
 +                                       msecs_to_jiffies(200)))
 +              WARN(1, "%s: timed out waiting for DSP hold", crtc->name);
  
        vop_dsp_hold_valid_irq_disable(vop);
  
@@@ -1176,26 -1174,24 +1176,24 @@@ static bool vop_crtc_mode_fixup(struct 
         *
         * Action plan:
         *
-        * 1. When DRM gives us a mode, we should add 999 Hz to it.  That way
-        *    if the clock we need is 60000001 Hz (~60 MHz) and DRM tells us to
-        *    make 60000 kHz then the clock framework will actually give us
-        *    the right clock.
+        * 1. Try to set the exact rate first, and confirm the clock framework
+        *    can provide it.
         *
-        *    NOTE: if the PLL (maybe through a divider) could actually make
-        *    a clock rate 999 Hz higher instead of the one we want then this
-        *    could be a problem.  Unfortunately there's not much we can do
-        *    since it's baked into DRM to use kHz.  It shouldn't matter in
-        *    practice since Rockchip PLLs are controlled by tables and
-        *    even if there is a divider in the middle I wouldn't expect PLL
-        *    rates in the table that are just a few kHz different.
+        * 2. If the clock framework cannot provide the exact rate, we should
+        *    add 999 Hz to the requested rate.  That way if the clock we need
+        *    is 60000001 Hz (~60 MHz) and DRM tells us to make 60000 kHz then
+        *    the clock framework will actually give us the right clock.
         *
-        * 2. Get the clock framework to round the rate for us to tell us
+        * 3. Get the clock framework to round the rate for us to tell us
         *    what it will actually make.
         *
-        * 3. Store the rounded up rate so that we don't need to worry about
+        * 4. Store the rounded up rate so that we don't need to worry about
         *    this in the actual clk_set_rate().
         */
-       rate = clk_round_rate(vop->dclk, adjusted_mode->clock * 1000 + 999);
+       rate = clk_round_rate(vop->dclk, adjusted_mode->clock * 1000);
+       if (rate / 1000 != adjusted_mode->clock)
+               rate = clk_round_rate(vop->dclk,
+                                     adjusted_mode->clock * 1000 + 999);
        adjusted_mode->clock = DIV_ROUND_UP(rate, 1000);
  
        return true;
index f349ec8b91a187b51bba6197ddf00af973a2894e,739f11c0109cbea1972cbe92f9bfcb93f2271e0c..e4a20a3a5d16607bba2b8d93c82f5386a924edef
@@@ -619,7 -619,8 +619,8 @@@ static bool ttm_bo_evict_swapout_allowa
                        *busy = !ret;
        }
  
-       if (ret && place && !bo->bdev->funcs->eviction_valuable(bo, place)) {
+       if (ret && place && (bo->resource->mem_type != place->mem_type ||
+               !bo->bdev->funcs->eviction_valuable(bo, place))) {
                ret = false;
                if (*locked) {
                        dma_resv_unlock(bo->base.resv);
@@@ -726,8 -727,6 +727,8 @@@ int ttm_mem_evict_first(struct ttm_devi
        ret = ttm_bo_evict(bo, ctx);
        if (locked)
                ttm_bo_unreserve(bo);
 +      else
 +              ttm_bo_move_to_lru_tail_unlocked(bo);
  
        ttm_bo_put(bo);
        return ret;
index fab9b93e1b84961d2334bafa0e138d45c695a0ee,b284623e28634465bf7d0dc01b06b425716b1ce5..053fbaf765ca6f69ce9d9c5efde88a5c9febcc2f
@@@ -94,7 -94,6 +94,7 @@@
  # define VC4_HD_M_SW_RST                      BIT(2)
  # define VC4_HD_M_ENABLE                      BIT(0)
  
 +#define HSM_MIN_CLOCK_FREQ    120000000
  #define CEC_CLOCK_FREQ 40000
  
  #define HDMI_14_MAX_TMDS_CLK   (340 * 1000 * 1000)
@@@ -118,10 -117,6 +118,10 @@@ static int vc4_hdmi_debugfs_regs(struc
  
  static void vc4_hdmi_reset(struct vc4_hdmi *vc4_hdmi)
  {
 +      unsigned long flags;
 +
 +      spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
 +
        HDMI_WRITE(HDMI_M_CTL, VC4_HD_M_SW_RST);
        udelay(1);
        HDMI_WRITE(HDMI_M_CTL, 0);
                   VC4_HDMI_SW_RESET_FORMAT_DETECT);
  
        HDMI_WRITE(HDMI_SW_RESET_CONTROL, 0);
 +
 +      spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
  }
  
  static void vc5_hdmi_reset(struct vc4_hdmi *vc4_hdmi)
  {
 +      unsigned long flags;
 +
        reset_control_reset(vc4_hdmi->reset);
  
 +      spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
 +
        HDMI_WRITE(HDMI_DVP_CTL, 0);
  
        HDMI_WRITE(HDMI_CLOCK_STOP,
                   HDMI_READ(HDMI_CLOCK_STOP) | VC4_DVP_HT_CLOCK_STOP_PIXEL);
 +
 +      spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
  }
  
  #ifdef CONFIG_DRM_VC4_HDMI_CEC
  static void vc4_hdmi_cec_update_clk_div(struct vc4_hdmi *vc4_hdmi)
  {
 +      unsigned long cec_rate = clk_get_rate(vc4_hdmi->cec_clock);
 +      unsigned long flags;
        u16 clk_cnt;
        u32 value;
  
 +      spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
 +
        value = HDMI_READ(HDMI_CEC_CNTRL_1);
        value &= ~VC4_HDMI_CEC_DIV_CLK_CNT_MASK;
  
         * Set the clock divider: the hsm_clock rate and this divider
         * setting will give a 40 kHz CEC clock.
         */
 -      clk_cnt = clk_get_rate(vc4_hdmi->cec_clock) / CEC_CLOCK_FREQ;
 +      clk_cnt = cec_rate / CEC_CLOCK_FREQ;
        value |= clk_cnt << VC4_HDMI_CEC_DIV_CLK_CNT_SHIFT;
        HDMI_WRITE(HDMI_CEC_CNTRL_1, value);
 +
 +      spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
  }
  #else
  static void vc4_hdmi_cec_update_clk_div(struct vc4_hdmi *vc4_hdmi) {}
  #endif
  
 +static void vc4_hdmi_enable_scrambling(struct drm_encoder *encoder);
 +
  static enum drm_connector_status
  vc4_hdmi_connector_detect(struct drm_connector *connector, bool force)
  {
        struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
        bool connected = false;
  
 -      if (vc4_hdmi->hpd_gpio &&
 -          gpiod_get_value_cansleep(vc4_hdmi->hpd_gpio)) {
 -              connected = true;
 -      } else if (drm_probe_ddc(vc4_hdmi->ddc)) {
 -              connected = true;
 -      } else if (HDMI_READ(HDMI_HOTPLUG) & VC4_HDMI_HOTPLUG_CONNECTED) {
 -              connected = true;
 +      mutex_lock(&vc4_hdmi->mutex);
 +
 +      WARN_ON(pm_runtime_resume_and_get(&vc4_hdmi->pdev->dev));
 +
 +      if (vc4_hdmi->hpd_gpio) {
 +              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)
 +                      connected = true;
        }
  
        if (connected) {
                        }
                }
  
 +              vc4_hdmi_enable_scrambling(&vc4_hdmi->encoder.base.base);
 +              pm_runtime_put(&vc4_hdmi->pdev->dev);
 +              mutex_unlock(&vc4_hdmi->mutex);
                return connector_status_connected;
        }
  
        cec_phys_addr_invalidate(vc4_hdmi->cec_adap);
 +      pm_runtime_put(&vc4_hdmi->pdev->dev);
 +      mutex_unlock(&vc4_hdmi->mutex);
        return connector_status_disconnected;
  }
  
@@@ -243,14 -207,10 +243,14 @@@ static int vc4_hdmi_connector_get_modes
        int ret = 0;
        struct edid *edid;
  
 +      mutex_lock(&vc4_hdmi->mutex);
 +
        edid = drm_get_edid(connector, vc4_hdmi->ddc);
        cec_s_phys_addr_from_edid(vc4_hdmi->cec_adap, edid);
 -      if (!edid)
 -              return -ENODEV;
 +      if (!edid) {
 +              ret = -ENODEV;
 +              goto out;
 +      }
  
        vc4_encoder->hdmi_monitor = drm_detect_hdmi_monitor(edid);
  
                }
        }
  
 +out:
 +      mutex_unlock(&vc4_hdmi->mutex);
 +
        return ret;
  }
  
@@@ -407,12 -364,9 +407,12 @@@ static int vc4_hdmi_stop_packet(struct 
  {
        struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
        u32 packet_id = type - 0x80;
 +      unsigned long flags;
  
 +      spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
        HDMI_WRITE(HDMI_RAM_PACKET_CONFIG,
                   HDMI_READ(HDMI_RAM_PACKET_CONFIG) & ~BIT(packet_id));
 +      spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
  
        if (!poll)
                return 0;
@@@ -432,7 -386,6 +432,7 @@@ static void vc4_hdmi_write_infoframe(st
        void __iomem *base = __vc4_hdmi_get_field_base(vc4_hdmi,
                                                       ram_packet_start->reg);
        uint8_t buffer[VC4_HDMI_PACKET_STRIDE];
 +      unsigned long flags;
        ssize_t len, i;
        int ret;
  
                return;
        }
  
 +      spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
 +
        for (i = 0; i < len; i += 7) {
                writel(buffer[i + 0] << 0 |
                       buffer[i + 1] << 8 |
  
        HDMI_WRITE(HDMI_RAM_PACKET_CONFIG,
                   HDMI_READ(HDMI_RAM_PACKET_CONFIG) | BIT(packet_id));
 +
 +      spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
 +
        ret = wait_for((HDMI_READ(HDMI_RAM_PACKET_STATUS) &
                        BIT(packet_id)), 100);
        if (ret)
@@@ -484,12 -432,11 +484,12 @@@ static void vc4_hdmi_set_avi_infoframe(
        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;
 -      struct drm_crtc *crtc = encoder->crtc;
 -      const struct drm_display_mode *mode = &crtc->state->adjusted_mode;
 +      const struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode;
        union hdmi_infoframe frame;
        int ret;
  
 +      lockdep_assert_held(&vc4_hdmi->mutex);
 +
        ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
                                                       connector, mode);
        if (ret < 0) {
@@@ -541,8 -488,6 +541,8 @@@ static void vc4_hdmi_set_hdr_infoframe(
        struct drm_connector_state *conn_state = connector->state;
        union hdmi_infoframe frame;
  
 +      lockdep_assert_held(&vc4_hdmi->mutex);
 +
        if (!vc4_hdmi->variant->supports_hdr)
                return;
  
@@@ -559,8 -504,6 +559,8 @@@ static void vc4_hdmi_set_infoframes(str
  {
        struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
  
 +      lockdep_assert_held(&vc4_hdmi->mutex);
 +
        vc4_hdmi_set_avi_infoframe(encoder);
        vc4_hdmi_set_spd_infoframe(encoder);
        /*
@@@ -580,8 -523,6 +580,8 @@@ static bool vc4_hdmi_supports_scramblin
        struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
        struct drm_display_info *display = &vc4_hdmi->connector.display_info;
  
 +      lockdep_assert_held(&vc4_hdmi->mutex);
 +
        if (!vc4_encoder->hdmi_monitor)
                return false;
  
  
  static void vc4_hdmi_enable_scrambling(struct drm_encoder *encoder)
  {
 -      struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
        struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
 +      struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode;
 +      unsigned long flags;
 +
 +      lockdep_assert_held(&vc4_hdmi->mutex);
  
        if (!vc4_hdmi_supports_scrambling(encoder, mode))
                return;
        drm_scdc_set_high_tmds_clock_ratio(vc4_hdmi->ddc, true);
        drm_scdc_set_scrambling(vc4_hdmi->ddc, true);
  
 +      spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
        HDMI_WRITE(HDMI_SCRAMBLER_CTL, HDMI_READ(HDMI_SCRAMBLER_CTL) |
                   VC5_HDMI_SCRAMBLER_CTL_ENABLE);
 +      spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
 +
 +      vc4_hdmi->scdc_enabled = true;
  
        queue_delayed_work(system_wq, &vc4_hdmi->scrambling_work,
                           msecs_to_jiffies(SCRAMBLING_POLLING_DELAY_MS));
  static void vc4_hdmi_disable_scrambling(struct drm_encoder *encoder)
  {
        struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
 -      struct drm_crtc *crtc = encoder->crtc;
 +      unsigned long flags;
  
 -      /*
 -       * At boot, encoder->crtc will be NULL. Since we don't know the
 -       * state of the scrambler and in order to avoid any
 -       * inconsistency, let's disable it all the time.
 -       */
 -      if (crtc && !vc4_hdmi_supports_scrambling(encoder, &crtc->mode))
 -              return;
 +      lockdep_assert_held(&vc4_hdmi->mutex);
  
 -      if (crtc && !vc4_hdmi_mode_needs_scrambling(&crtc->mode))
 +      if (!vc4_hdmi->scdc_enabled)
                return;
  
 +      vc4_hdmi->scdc_enabled = false;
 +
        if (delayed_work_pending(&vc4_hdmi->scrambling_work))
                cancel_delayed_work_sync(&vc4_hdmi->scrambling_work);
  
 +      spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
        HDMI_WRITE(HDMI_SCRAMBLER_CTL, HDMI_READ(HDMI_SCRAMBLER_CTL) &
                   ~VC5_HDMI_SCRAMBLER_CTL_ENABLE);
 +      spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
  
        drm_scdc_set_scrambling(vc4_hdmi->ddc, false);
        drm_scdc_set_high_tmds_clock_ratio(vc4_hdmi->ddc, false);
@@@ -666,73 -602,47 +666,73 @@@ static void vc4_hdmi_encoder_post_crtc_
                                               struct drm_atomic_state *state)
  {
        struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
 +      unsigned long flags;
 +
 +      mutex_lock(&vc4_hdmi->mutex);
 +
 +      spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
  
        HDMI_WRITE(HDMI_RAM_PACKET_CONFIG, 0);
  
        HDMI_WRITE(HDMI_VID_CTL, HDMI_READ(HDMI_VID_CTL) | VC4_HD_VID_CTL_CLRRGB);
  
 +      spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
 +
        mdelay(1);
  
 +      spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
        HDMI_WRITE(HDMI_VID_CTL,
                   HDMI_READ(HDMI_VID_CTL) & ~VC4_HD_VID_CTL_ENABLE);
 +      spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
 +
        vc4_hdmi_disable_scrambling(encoder);
 +
 +      mutex_unlock(&vc4_hdmi->mutex);
  }
  
  static void vc4_hdmi_encoder_post_crtc_powerdown(struct drm_encoder *encoder,
                                                 struct drm_atomic_state *state)
  {
        struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
 +      unsigned long flags;
        int ret;
  
 +      mutex_lock(&vc4_hdmi->mutex);
 +
 +      spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
        HDMI_WRITE(HDMI_VID_CTL,
                   HDMI_READ(HDMI_VID_CTL) | VC4_HD_VID_CTL_BLANKPIX);
 +      spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
  
        if (vc4_hdmi->variant->phy_disable)
                vc4_hdmi->variant->phy_disable(vc4_hdmi);
  
        clk_disable_unprepare(vc4_hdmi->pixel_bvb_clock);
 -      clk_disable_unprepare(vc4_hdmi->hsm_clock);
        clk_disable_unprepare(vc4_hdmi->pixel_clock);
  
        ret = pm_runtime_put(&vc4_hdmi->pdev->dev);
        if (ret < 0)
                DRM_ERROR("Failed to release power domain: %d\n", ret);
 +
 +      mutex_unlock(&vc4_hdmi->mutex);
  }
  
  static void vc4_hdmi_encoder_disable(struct drm_encoder *encoder)
  {
 +      struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
 +
 +      mutex_lock(&vc4_hdmi->mutex);
 +      vc4_hdmi->output_enabled = false;
 +      mutex_unlock(&vc4_hdmi->mutex);
  }
  
  static void vc4_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, bool enable)
  {
 +      unsigned long flags;
        u32 csc_ctl;
  
 +      spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
 +
        csc_ctl = VC4_SET_FIELD(VC4_HD_CSC_CTL_ORDER_BGR,
                                VC4_HD_CSC_CTL_ORDER);
  
  
        /* The RGB order applies even when CSC is disabled. */
        HDMI_WRITE(HDMI_CSC_CTL, csc_ctl);
 +
 +      spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
  }
  
  static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, bool enable)
  {
 +      unsigned long flags;
        u32 csc_ctl;
  
        csc_ctl = 0x07; /* RGB_CONVERT_MODE = custom matrix, || USE_RGB_TO_YCBCR */
  
 +      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.
        }
  
        HDMI_WRITE(HDMI_CSC_CTL, csc_ctl);
 +
 +      spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
  }
  
  static void vc4_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
                                        mode->crtc_vsync_end -
                                        interlaced,
                                        VC4_HDMI_VERTB_VBP));
 +      unsigned long flags;
 +
 +      spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
  
        HDMI_WRITE(HDMI_HORZA,
                   (vsync_pos ? VC4_HDMI_HORZA_VPOS : 0) |
  
        HDMI_WRITE(HDMI_VERTB0, vertb_even);
        HDMI_WRITE(HDMI_VERTB1, vertb);
 +
 +      spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
  }
  
  static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
                                        mode->crtc_vsync_end -
                                        interlaced,
                                        VC4_HDMI_VERTB_VBP));
 +      unsigned long flags;
        unsigned char gcp;
        bool gcp_en;
        u32 reg;
  
 +      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) |
        HDMI_WRITE(HDMI_GCP_CONFIG, reg);
  
        HDMI_WRITE(HDMI_CLOCK_STOP, 0);
 +
 +      spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
  }
  
  static void vc4_hdmi_recenter_fifo(struct vc4_hdmi *vc4_hdmi)
  {
 +      unsigned long flags;
        u32 drift;
        int ret;
  
 +      spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
 +
        drift = HDMI_READ(HDMI_FIFO_CTL);
        drift &= VC4_HDMI_FIFO_VALID_WRITE_MASK;
  
                   drift & ~VC4_HDMI_FIFO_CTL_RECENTER);
        HDMI_WRITE(HDMI_FIFO_CTL,
                   drift | VC4_HDMI_FIFO_CTL_RECENTER);
 +
 +      spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
 +
        usleep_range(1000, 1100);
 +
 +      spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
 +
        HDMI_WRITE(HDMI_FIFO_CTL,
                   drift & ~VC4_HDMI_FIFO_CTL_RECENTER);
        HDMI_WRITE(HDMI_FIFO_CTL,
                   drift | VC4_HDMI_FIFO_CTL_RECENTER);
  
 +      spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
 +
        ret = wait_for(HDMI_READ(HDMI_FIFO_CTL) &
                       VC4_HDMI_FIFO_CTL_RECENTER_DONE, 1);
        WARN_ONCE(ret, "Timeout waiting for "
@@@ -1009,14 -891,29 +1009,14 @@@ static void vc4_hdmi_encoder_pre_crtc_c
                vc4_hdmi_encoder_get_connector_state(encoder, state);
        struct vc4_hdmi_connector_state *vc4_conn_state =
                conn_state_to_vc4_hdmi_conn_state(conn_state);
 -      struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
        struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
 -      unsigned long bvb_rate, pixel_rate, hsm_rate;
 +      struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode;
 +      unsigned long pixel_rate = vc4_conn_state->pixel_rate;
 +      unsigned long bvb_rate, hsm_rate;
 +      unsigned long flags;
        int ret;
  
 -      ret = pm_runtime_resume_and_get(&vc4_hdmi->pdev->dev);
 -      if (ret < 0) {
 -              DRM_ERROR("Failed to retain power domain: %d\n", ret);
 -              return;
 -      }
 -
 -      pixel_rate = vc4_conn_state->pixel_rate;
 -      ret = clk_set_rate(vc4_hdmi->pixel_clock, pixel_rate);
 -      if (ret) {
 -              DRM_ERROR("Failed to set pixel clock rate: %d\n", ret);
 -              return;
 -      }
 -
 -      ret = clk_prepare_enable(vc4_hdmi->pixel_clock);
 -      if (ret) {
 -              DRM_ERROR("Failed to turn on pixel clock: %d\n", ret);
 -              return;
 -      }
 +      mutex_lock(&vc4_hdmi->mutex);
  
        /*
         * As stated in RPi's vc4 firmware "HDMI state machine (HSM) clock must
        ret = clk_set_min_rate(vc4_hdmi->hsm_clock, hsm_rate);
        if (ret) {
                DRM_ERROR("Failed to set HSM clock rate: %d\n", ret);
 -              return;
 +              goto out;
        }
  
 -      ret = clk_prepare_enable(vc4_hdmi->hsm_clock);
 +      ret = pm_runtime_resume_and_get(&vc4_hdmi->pdev->dev);
 +      if (ret < 0) {
 +              DRM_ERROR("Failed to retain power domain: %d\n", ret);
 +              goto out;
 +      }
 +
 +      ret = clk_set_rate(vc4_hdmi->pixel_clock, pixel_rate);
        if (ret) {
 -              DRM_ERROR("Failed to turn on HSM clock: %d\n", ret);
 -              clk_disable_unprepare(vc4_hdmi->pixel_clock);
 -              return;
 +              DRM_ERROR("Failed to set pixel clock rate: %d\n", ret);
 +              goto err_put_runtime_pm;
        }
  
 +      ret = clk_prepare_enable(vc4_hdmi->pixel_clock);
 +      if (ret) {
 +              DRM_ERROR("Failed to turn on pixel clock: %d\n", ret);
 +              goto err_put_runtime_pm;
 +      }
 +
 +
        vc4_hdmi_cec_update_clk_div(vc4_hdmi);
  
        if (pixel_rate > 297000000)
        ret = clk_set_min_rate(vc4_hdmi->pixel_bvb_clock, bvb_rate);
        if (ret) {
                DRM_ERROR("Failed to set pixel bvb clock rate: %d\n", ret);
 -              clk_disable_unprepare(vc4_hdmi->hsm_clock);
 -              clk_disable_unprepare(vc4_hdmi->pixel_clock);
 -              return;
 +              goto err_disable_pixel_clock;
        }
  
        ret = clk_prepare_enable(vc4_hdmi->pixel_bvb_clock);
        if (ret) {
                DRM_ERROR("Failed to turn on pixel bvb clock: %d\n", ret);
 -              clk_disable_unprepare(vc4_hdmi->hsm_clock);
 -              clk_disable_unprepare(vc4_hdmi->pixel_clock);
 -              return;
 +              goto err_disable_pixel_clock;
        }
  
        if (vc4_hdmi->variant->phy_init)
                vc4_hdmi->variant->phy_init(vc4_hdmi, vc4_conn_state);
  
 +      spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
 +
        HDMI_WRITE(HDMI_SCHEDULER_CONTROL,
                   HDMI_READ(HDMI_SCHEDULER_CONTROL) |
                   VC4_HDMI_SCHEDULER_CONTROL_MANUAL_FORMAT |
                   VC4_HDMI_SCHEDULER_CONTROL_IGNORE_VSYNC_PREDICTS);
  
 +      spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
 +
        if (vc4_hdmi->variant->set_timings)
                vc4_hdmi->variant->set_timings(vc4_hdmi, conn_state, mode);
 +
 +      mutex_unlock(&vc4_hdmi->mutex);
 +
 +      return;
 +
 +err_disable_pixel_clock:
 +      clk_disable_unprepare(vc4_hdmi->pixel_clock);
 +err_put_runtime_pm:
 +      pm_runtime_put(&vc4_hdmi->pdev->dev);
 +out:
 +      mutex_unlock(&vc4_hdmi->mutex);
 +      return;
  }
  
  static void vc4_hdmi_encoder_pre_crtc_enable(struct drm_encoder *encoder,
                                             struct drm_atomic_state *state)
  {
 -      struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
 -      struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
        struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
 +      struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode;
 +      struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
 +      unsigned long flags;
 +
 +      mutex_lock(&vc4_hdmi->mutex);
  
        if (vc4_encoder->hdmi_monitor &&
            drm_default_rgb_quant_range(mode) == HDMI_QUANTIZATION_RANGE_LIMITED) {
                vc4_encoder->limited_rgb_range = false;
        }
  
 +      spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
        HDMI_WRITE(HDMI_FIFO_CTL, VC4_HDMI_FIFO_CTL_MASTER_SLAVE_N);
 +      spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
 +
 +      mutex_unlock(&vc4_hdmi->mutex);
  }
  
  static void vc4_hdmi_encoder_post_crtc_enable(struct drm_encoder *encoder,
                                              struct drm_atomic_state *state)
  {
 -      struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
        struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
 +      struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode;
        struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
        bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC;
        bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC;
 +      unsigned long flags;
        int ret;
  
 +      mutex_lock(&vc4_hdmi->mutex);
 +
 +      spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
 +
        HDMI_WRITE(HDMI_VID_CTL,
                   VC4_HD_VID_CTL_ENABLE |
                   VC4_HD_VID_CTL_CLRRGB |
                           HDMI_READ(HDMI_SCHEDULER_CONTROL) |
                           VC4_HDMI_SCHEDULER_CONTROL_MODE_HDMI);
  
 +              spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
 +
                ret = wait_for(HDMI_READ(HDMI_SCHEDULER_CONTROL) &
                               VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE, 1000);
                WARN_ONCE(ret, "Timeout waiting for "
                           HDMI_READ(HDMI_SCHEDULER_CONTROL) &
                           ~VC4_HDMI_SCHEDULER_CONTROL_MODE_HDMI);
  
 +              spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
 +
                ret = wait_for(!(HDMI_READ(HDMI_SCHEDULER_CONTROL) &
                                 VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE), 1000);
                WARN_ONCE(ret, "Timeout waiting for "
        }
  
        if (vc4_encoder->hdmi_monitor) {
 +              spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
 +
                WARN_ON(!(HDMI_READ(HDMI_SCHEDULER_CONTROL) &
                          VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE));
                HDMI_WRITE(HDMI_SCHEDULER_CONTROL,
                HDMI_WRITE(HDMI_RAM_PACKET_CONFIG,
                           VC4_HDMI_RAM_PACKET_ENABLE);
  
 +              spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
 +
                vc4_hdmi_set_infoframes(encoder);
        }
  
        vc4_hdmi_recenter_fifo(vc4_hdmi);
        vc4_hdmi_enable_scrambling(encoder);
 +
 +      mutex_unlock(&vc4_hdmi->mutex);
  }
  
  static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
  {
 +      struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
 +
 +      mutex_lock(&vc4_hdmi->mutex);
 +      vc4_hdmi->output_enabled = true;
 +      mutex_unlock(&vc4_hdmi->mutex);
 +}
 +
 +static void vc4_hdmi_encoder_atomic_mode_set(struct drm_encoder *encoder,
 +                                           struct drm_crtc_state *crtc_state,
 +                                           struct drm_connector_state *conn_state)
 +{
 +      struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
 +
 +      mutex_lock(&vc4_hdmi->mutex);
 +      memcpy(&vc4_hdmi->saved_adjusted_mode,
 +             &crtc_state->adjusted_mode,
 +             sizeof(vc4_hdmi->saved_adjusted_mode));
 +      mutex_unlock(&vc4_hdmi->mutex);
  }
  
  #define WIFI_2_4GHz_CH1_MIN_FREQ      2400000000ULL
@@@ -1313,7 -1146,6 +1313,7 @@@ vc4_hdmi_encoder_mode_valid(struct drm_
  
  static const struct drm_encoder_helper_funcs vc4_hdmi_encoder_helper_funcs = {
        .atomic_check = vc4_hdmi_encoder_atomic_check,
 +      .atomic_mode_set = vc4_hdmi_encoder_atomic_mode_set,
        .mode_valid = vc4_hdmi_encoder_mode_valid,
        .disable = vc4_hdmi_encoder_disable,
        .enable = vc4_hdmi_encoder_enable,
@@@ -1348,7 -1180,6 +1348,7 @@@ static void vc4_hdmi_audio_set_mai_cloc
                                         unsigned int samplerate)
  {
        u32 hsm_clock = clk_get_rate(vc4_hdmi->audio_clock);
 +      unsigned long flags;
        unsigned long n, m;
  
        rational_best_approximation(hsm_clock, samplerate,
                                     VC4_HD_MAI_SMP_M_SHIFT) + 1,
                                    &n, &m);
  
 +      spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
        HDMI_WRITE(HDMI_MAI_SMP,
                   VC4_SET_FIELD(n, VC4_HD_MAI_SMP_N) |
                   VC4_SET_FIELD(m - 1, VC4_HD_MAI_SMP_M));
 +      spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
  }
  
  static void vc4_hdmi_set_n_cts(struct vc4_hdmi *vc4_hdmi, unsigned int samplerate)
  {
 -      struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
 -      struct drm_crtc *crtc = encoder->crtc;
 -      const struct drm_display_mode *mode = &crtc->state->adjusted_mode;
 +      const struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode;
        u32 n, cts;
        u64 tmp;
  
 +      lockdep_assert_held(&vc4_hdmi->mutex);
 +      lockdep_assert_held(&vc4_hdmi->hw_lock);
 +
        n = 128 * samplerate / 1000;
        tmp = (u64)(mode->clock * 1000) * n;
        do_div(tmp, 128 * samplerate);
@@@ -1399,54 -1227,31 +1399,54 @@@ static inline struct vc4_hdmi *dai_to_h
        return snd_soc_card_get_drvdata(card);
  }
  
 -static int vc4_hdmi_audio_startup(struct device *dev, void *data)
 +static bool vc4_hdmi_audio_can_stream(struct vc4_hdmi *vc4_hdmi)
  {
 -      struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
 -      struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
 +      lockdep_assert_held(&vc4_hdmi->mutex);
 +
 +      /*
 +       * If the controller is disabled, prevent any ALSA output.
 +       */
 +      if (!vc4_hdmi->output_enabled)
 +              return false;
  
        /*
 -       * If the HDMI encoder hasn't probed, or the encoder is
 -       * currently in DVI mode, treat the codec dai as missing.
 +       * If the encoder is currently in DVI mode, treat the codec DAI
 +       * as missing.
         */
 -      if (!encoder->crtc || !(HDMI_READ(HDMI_RAM_PACKET_CONFIG) &
 -                              VC4_HDMI_RAM_PACKET_ENABLE))
 +      if (!(HDMI_READ(HDMI_RAM_PACKET_CONFIG) & VC4_HDMI_RAM_PACKET_ENABLE))
 +              return false;
 +
 +      return true;
 +}
 +
 +static int vc4_hdmi_audio_startup(struct device *dev, void *data)
 +{
 +      struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
 +      unsigned long flags;
 +
 +      mutex_lock(&vc4_hdmi->mutex);
 +
 +      if (!vc4_hdmi_audio_can_stream(vc4_hdmi)) {
 +              mutex_unlock(&vc4_hdmi->mutex);
                return -ENODEV;
 +      }
  
        vc4_hdmi->audio.streaming = true;
  
 +      spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
        HDMI_WRITE(HDMI_MAI_CTL,
                   VC4_HD_MAI_CTL_RESET |
                   VC4_HD_MAI_CTL_FLUSH |
                   VC4_HD_MAI_CTL_DLATE |
                   VC4_HD_MAI_CTL_ERRORE |
                   VC4_HD_MAI_CTL_ERRORF);
 +      spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
  
        if (vc4_hdmi->variant->phy_rng_enable)
                vc4_hdmi->variant->phy_rng_enable(vc4_hdmi);
  
 +      mutex_unlock(&vc4_hdmi->mutex);
 +
        return 0;
  }
  
@@@ -1454,48 -1259,32 +1454,48 @@@ static void vc4_hdmi_audio_reset(struc
  {
        struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
        struct device *dev = &vc4_hdmi->pdev->dev;
 +      unsigned long flags;
        int ret;
  
 +      lockdep_assert_held(&vc4_hdmi->mutex);
 +
        vc4_hdmi->audio.streaming = false;
        ret = vc4_hdmi_stop_packet(encoder, HDMI_INFOFRAME_TYPE_AUDIO, false);
        if (ret)
                dev_err(dev, "Failed to stop audio infoframe: %d\n", ret);
  
 +      spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
 +
        HDMI_WRITE(HDMI_MAI_CTL, VC4_HD_MAI_CTL_RESET);
        HDMI_WRITE(HDMI_MAI_CTL, VC4_HD_MAI_CTL_ERRORF);
        HDMI_WRITE(HDMI_MAI_CTL, VC4_HD_MAI_CTL_FLUSH);
 +
 +      spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
  }
  
  static void vc4_hdmi_audio_shutdown(struct device *dev, void *data)
  {
        struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
 +      unsigned long flags;
 +
 +      mutex_lock(&vc4_hdmi->mutex);
 +
 +      spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
  
        HDMI_WRITE(HDMI_MAI_CTL,
                   VC4_HD_MAI_CTL_DLATE |
                   VC4_HD_MAI_CTL_ERRORE |
                   VC4_HD_MAI_CTL_ERRORF);
  
 +      spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
 +
        if (vc4_hdmi->variant->phy_rng_disable)
                vc4_hdmi->variant->phy_rng_disable(vc4_hdmi);
  
        vc4_hdmi->audio.streaming = false;
        vc4_hdmi_audio_reset(vc4_hdmi);
 +
 +      mutex_unlock(&vc4_hdmi->mutex);
  }
  
  static int sample_rate_to_mai_fmt(int samplerate)
@@@ -1545,7 -1334,6 +1545,7 @@@ static int vc4_hdmi_audio_prepare(struc
        struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
        unsigned int sample_rate = params->sample_rate;
        unsigned int channels = params->channels;
 +      unsigned long flags;
        u32 audio_packet_config, channel_mask;
        u32 channel_map;
        u32 mai_audio_format;
        dev_dbg(dev, "%s: %u Hz, %d bit, %d channels\n", __func__,
                sample_rate, params->sample_width, channels);
  
 +      mutex_lock(&vc4_hdmi->mutex);
 +
 +      if (!vc4_hdmi_audio_can_stream(vc4_hdmi)) {
 +              mutex_unlock(&vc4_hdmi->mutex);
 +              return -EINVAL;
 +      }
 +
 +      vc4_hdmi_audio_set_mai_clock(vc4_hdmi, sample_rate);
 +
 +      spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
        HDMI_WRITE(HDMI_MAI_CTL,
                   VC4_SET_FIELD(channels, VC4_HD_MAI_CTL_CHNUM) |
                   VC4_HD_MAI_CTL_WHOLSMP |
                   VC4_HD_MAI_CTL_CHALIGN |
                   VC4_HD_MAI_CTL_ENABLE);
  
 -      vc4_hdmi_audio_set_mai_clock(vc4_hdmi, sample_rate);
 -
        mai_sample_rate = sample_rate_to_mai_fmt(sample_rate);
        if (params->iec.status[0] & IEC958_AES0_NONAUDIO &&
            params->channels == 8)
        channel_map = vc4_hdmi->variant->channel_map(vc4_hdmi, channel_mask);
        HDMI_WRITE(HDMI_MAI_CHANNEL_MAP, channel_map);
        HDMI_WRITE(HDMI_AUDIO_PACKET_CONFIG, audio_packet_config);
 +
        vc4_hdmi_set_n_cts(vc4_hdmi, sample_rate);
  
 +      spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
 +
        memcpy(&vc4_hdmi->audio.infoframe, &params->cea, sizeof(params->cea));
        vc4_hdmi_set_audio_infoframe(encoder);
  
 +      mutex_unlock(&vc4_hdmi->mutex);
 +
        return 0;
  }
  
- static const struct snd_soc_dapm_widget vc4_hdmi_audio_widgets[] = {
-       SND_SOC_DAPM_OUTPUT("TX"),
- };
- static const struct snd_soc_dapm_route vc4_hdmi_audio_routes[] = {
-       { "TX", NULL, "Playback" },
- };
  static const struct snd_soc_component_driver vc4_hdmi_audio_cpu_dai_comp = {
        .name = "vc4-hdmi-cpu-dai-component",
  };
@@@ -1667,9 -1434,7 +1659,9 @@@ static int vc4_hdmi_audio_get_eld(struc
        struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
        struct drm_connector *connector = &vc4_hdmi->connector;
  
 +      mutex_lock(&vc4_hdmi->mutex);
        memcpy(buf, connector->eld, min(sizeof(connector->eld), len));
 +      mutex_unlock(&vc4_hdmi->mutex);
  
        return 0;
  }
@@@ -1891,8 -1656,6 +1883,8 @@@ static void vc4_cec_read_msg(struct vc4
        struct cec_msg *msg = &vc4_hdmi->cec_rx_msg;
        unsigned int i;
  
 +      lockdep_assert_held(&vc4_hdmi->hw_lock);
 +
        msg->len = 1 + ((cntrl1 & VC4_HDMI_CEC_REC_WRD_CNT_MASK) >>
                                        VC4_HDMI_CEC_REC_WRD_CNT_SHIFT);
  
        }
  }
  
 -static irqreturn_t vc4_cec_irq_handler_tx_bare(int irq, void *priv)
 +static irqreturn_t vc4_cec_irq_handler_tx_bare_locked(struct vc4_hdmi *vc4_hdmi)
  {
 -      struct vc4_hdmi *vc4_hdmi = priv;
        u32 cntrl1;
  
 +      lockdep_assert_held(&vc4_hdmi->hw_lock);
 +
        cntrl1 = HDMI_READ(HDMI_CEC_CNTRL_1);
        vc4_hdmi->cec_tx_ok = cntrl1 & VC4_HDMI_CEC_TX_STATUS_GOOD;
        cntrl1 &= ~VC4_HDMI_CEC_START_XMIT_BEGIN;
        return IRQ_WAKE_THREAD;
  }
  
 -static irqreturn_t vc4_cec_irq_handler_rx_bare(int irq, void *priv)
 +static irqreturn_t vc4_cec_irq_handler_tx_bare(int irq, void *priv)
  {
        struct vc4_hdmi *vc4_hdmi = priv;
 +      irqreturn_t ret;
 +
 +      spin_lock(&vc4_hdmi->hw_lock);
 +      ret = vc4_cec_irq_handler_tx_bare_locked(vc4_hdmi);
 +      spin_unlock(&vc4_hdmi->hw_lock);
 +
 +      return ret;
 +}
 +
 +static irqreturn_t vc4_cec_irq_handler_rx_bare_locked(struct vc4_hdmi *vc4_hdmi)
 +{
        u32 cntrl1;
  
 +      lockdep_assert_held(&vc4_hdmi->hw_lock);
 +
        vc4_hdmi->cec_rx_msg.len = 0;
        cntrl1 = HDMI_READ(HDMI_CEC_CNTRL_1);
        vc4_cec_read_msg(vc4_hdmi, cntrl1);
        return IRQ_WAKE_THREAD;
  }
  
 +static irqreturn_t vc4_cec_irq_handler_rx_bare(int irq, void *priv)
 +{
 +      struct vc4_hdmi *vc4_hdmi = priv;
 +      irqreturn_t ret;
 +
 +      spin_lock(&vc4_hdmi->hw_lock);
 +      ret = vc4_cec_irq_handler_rx_bare_locked(vc4_hdmi);
 +      spin_unlock(&vc4_hdmi->hw_lock);
 +
 +      return ret;
 +}
 +
  static irqreturn_t vc4_cec_irq_handler(int irq, void *priv)
  {
        struct vc4_hdmi *vc4_hdmi = priv;
        if (!(stat & VC4_HDMI_CPU_CEC))
                return IRQ_NONE;
  
 +      spin_lock(&vc4_hdmi->hw_lock);
        cntrl5 = HDMI_READ(HDMI_CEC_CNTRL_5);
        vc4_hdmi->cec_irq_was_rx = cntrl5 & VC4_HDMI_CEC_RX_CEC_INT;
        if (vc4_hdmi->cec_irq_was_rx)
 -              ret = vc4_cec_irq_handler_rx_bare(irq, priv);
 +              ret = vc4_cec_irq_handler_rx_bare_locked(vc4_hdmi);
        else
 -              ret = vc4_cec_irq_handler_tx_bare(irq, priv);
 +              ret = vc4_cec_irq_handler_tx_bare_locked(vc4_hdmi);
  
        HDMI_WRITE(HDMI_CEC_CPU_CLEAR, VC4_HDMI_CPU_CEC);
 +      spin_unlock(&vc4_hdmi->hw_lock);
 +
        return ret;
  }
  
 -static int vc4_hdmi_cec_adap_enable(struct cec_adapter *adap, bool enable)
 +static int vc4_hdmi_cec_enable(struct cec_adapter *adap)
  {
        struct vc4_hdmi *vc4_hdmi = cec_get_drvdata(adap);
        /* clock period in microseconds */
        const u32 usecs = 1000000 / CEC_CLOCK_FREQ;
 -      u32 val = HDMI_READ(HDMI_CEC_CNTRL_5);
 +      unsigned long flags;
 +      u32 val;
 +      int ret;
 +
 +      /*
 +       * NOTE: This function should really take vc4_hdmi->mutex, but doing so
 +       * results in a reentrancy since cec_s_phys_addr_from_edid() called in
 +       * .detect or .get_modes might call .adap_enable, which leads to this
 +       * function being called with that mutex held.
 +       *
 +       * Concurrency is not an issue for the moment since we don't share any
 +       * state with KMS, so we can ignore the lock for now, but we need to
 +       * keep it in mind if we were to change that assumption.
 +       */
  
 +      ret = pm_runtime_resume_and_get(&vc4_hdmi->pdev->dev);
 +      if (ret)
 +              return ret;
 +
 +      spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
 +
 +      val = HDMI_READ(HDMI_CEC_CNTRL_5);
        val &= ~(VC4_HDMI_CEC_TX_SW_RESET | VC4_HDMI_CEC_RX_SW_RESET |
                 VC4_HDMI_CEC_CNT_TO_4700_US_MASK |
                 VC4_HDMI_CEC_CNT_TO_4500_US_MASK);
        val |= ((4700 / usecs) << VC4_HDMI_CEC_CNT_TO_4700_US_SHIFT) |
               ((4500 / usecs) << VC4_HDMI_CEC_CNT_TO_4500_US_SHIFT);
  
 -      if (enable) {
 -              HDMI_WRITE(HDMI_CEC_CNTRL_5, val |
 -                         VC4_HDMI_CEC_TX_SW_RESET | VC4_HDMI_CEC_RX_SW_RESET);
 -              HDMI_WRITE(HDMI_CEC_CNTRL_5, val);
 -              HDMI_WRITE(HDMI_CEC_CNTRL_2,
 -                         ((1500 / usecs) << VC4_HDMI_CEC_CNT_TO_1500_US_SHIFT) |
 -                         ((1300 / usecs) << VC4_HDMI_CEC_CNT_TO_1300_US_SHIFT) |
 -                         ((800 / usecs) << VC4_HDMI_CEC_CNT_TO_800_US_SHIFT) |
 -                         ((600 / usecs) << VC4_HDMI_CEC_CNT_TO_600_US_SHIFT) |
 -                         ((400 / usecs) << VC4_HDMI_CEC_CNT_TO_400_US_SHIFT));
 -              HDMI_WRITE(HDMI_CEC_CNTRL_3,
 -                         ((2750 / usecs) << VC4_HDMI_CEC_CNT_TO_2750_US_SHIFT) |
 -                         ((2400 / usecs) << VC4_HDMI_CEC_CNT_TO_2400_US_SHIFT) |
 -                         ((2050 / usecs) << VC4_HDMI_CEC_CNT_TO_2050_US_SHIFT) |
 -                         ((1700 / usecs) << VC4_HDMI_CEC_CNT_TO_1700_US_SHIFT));
 -              HDMI_WRITE(HDMI_CEC_CNTRL_4,
 -                         ((4300 / usecs) << VC4_HDMI_CEC_CNT_TO_4300_US_SHIFT) |
 -                         ((3900 / usecs) << VC4_HDMI_CEC_CNT_TO_3900_US_SHIFT) |
 -                         ((3600 / usecs) << VC4_HDMI_CEC_CNT_TO_3600_US_SHIFT) |
 -                         ((3500 / usecs) << VC4_HDMI_CEC_CNT_TO_3500_US_SHIFT));
 -
 -              if (!vc4_hdmi->variant->external_irq_controller)
 -                      HDMI_WRITE(HDMI_CEC_CPU_MASK_CLEAR, VC4_HDMI_CPU_CEC);
 -      } else {
 -              if (!vc4_hdmi->variant->external_irq_controller)
 -                      HDMI_WRITE(HDMI_CEC_CPU_MASK_SET, VC4_HDMI_CPU_CEC);
 -              HDMI_WRITE(HDMI_CEC_CNTRL_5, val |
 -                         VC4_HDMI_CEC_TX_SW_RESET | VC4_HDMI_CEC_RX_SW_RESET);
 -      }
 +      HDMI_WRITE(HDMI_CEC_CNTRL_5, val |
 +                 VC4_HDMI_CEC_TX_SW_RESET | VC4_HDMI_CEC_RX_SW_RESET);
 +      HDMI_WRITE(HDMI_CEC_CNTRL_5, val);
 +      HDMI_WRITE(HDMI_CEC_CNTRL_2,
 +                 ((1500 / usecs) << VC4_HDMI_CEC_CNT_TO_1500_US_SHIFT) |
 +                 ((1300 / usecs) << VC4_HDMI_CEC_CNT_TO_1300_US_SHIFT) |
 +                 ((800 / usecs) << VC4_HDMI_CEC_CNT_TO_800_US_SHIFT) |
 +                 ((600 / usecs) << VC4_HDMI_CEC_CNT_TO_600_US_SHIFT) |
 +                 ((400 / usecs) << VC4_HDMI_CEC_CNT_TO_400_US_SHIFT));
 +      HDMI_WRITE(HDMI_CEC_CNTRL_3,
 +                 ((2750 / usecs) << VC4_HDMI_CEC_CNT_TO_2750_US_SHIFT) |
 +                 ((2400 / usecs) << VC4_HDMI_CEC_CNT_TO_2400_US_SHIFT) |
 +                 ((2050 / usecs) << VC4_HDMI_CEC_CNT_TO_2050_US_SHIFT) |
 +                 ((1700 / usecs) << VC4_HDMI_CEC_CNT_TO_1700_US_SHIFT));
 +      HDMI_WRITE(HDMI_CEC_CNTRL_4,
 +                 ((4300 / usecs) << VC4_HDMI_CEC_CNT_TO_4300_US_SHIFT) |
 +                 ((3900 / usecs) << VC4_HDMI_CEC_CNT_TO_3900_US_SHIFT) |
 +                 ((3600 / usecs) << VC4_HDMI_CEC_CNT_TO_3600_US_SHIFT) |
 +                 ((3500 / usecs) << VC4_HDMI_CEC_CNT_TO_3500_US_SHIFT));
 +
 +      if (!vc4_hdmi->variant->external_irq_controller)
 +              HDMI_WRITE(HDMI_CEC_CPU_MASK_CLEAR, VC4_HDMI_CPU_CEC);
 +
 +      spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
 +
        return 0;
  }
  
 +static int vc4_hdmi_cec_disable(struct cec_adapter *adap)
 +{
 +      struct vc4_hdmi *vc4_hdmi = cec_get_drvdata(adap);
 +      unsigned long flags;
 +
 +      /*
 +       * NOTE: This function should really take vc4_hdmi->mutex, but doing so
 +       * results in a reentrancy since cec_s_phys_addr_from_edid() called in
 +       * .detect or .get_modes might call .adap_enable, which leads to this
 +       * function being called with that mutex held.
 +       *
 +       * Concurrency is not an issue for the moment since we don't share any
 +       * state with KMS, so we can ignore the lock for now, but we need to
 +       * keep it in mind if we were to change that assumption.
 +       */
 +
 +      spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
 +
 +      if (!vc4_hdmi->variant->external_irq_controller)
 +              HDMI_WRITE(HDMI_CEC_CPU_MASK_SET, VC4_HDMI_CPU_CEC);
 +
 +      HDMI_WRITE(HDMI_CEC_CNTRL_5, HDMI_READ(HDMI_CEC_CNTRL_5) |
 +                 VC4_HDMI_CEC_TX_SW_RESET | VC4_HDMI_CEC_RX_SW_RESET);
 +
 +      spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
 +
 +      pm_runtime_put(&vc4_hdmi->pdev->dev);
 +
 +      return 0;
 +}
 +
 +static int vc4_hdmi_cec_adap_enable(struct cec_adapter *adap, bool enable)
 +{
 +      if (enable)
 +              return vc4_hdmi_cec_enable(adap);
 +      else
 +              return vc4_hdmi_cec_disable(adap);
 +}
 +
  static int vc4_hdmi_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr)
  {
        struct vc4_hdmi *vc4_hdmi = cec_get_drvdata(adap);
 +      unsigned long flags;
 +
 +      /*
 +       * NOTE: This function should really take vc4_hdmi->mutex, but doing so
 +       * results in a reentrancy since cec_s_phys_addr_from_edid() called in
 +       * .detect or .get_modes might call .adap_enable, which leads to this
 +       * function being called with that mutex held.
 +       *
 +       * Concurrency is not an issue for the moment since we don't share any
 +       * state with KMS, so we can ignore the lock for now, but we need to
 +       * keep it in mind if we were to change that assumption.
 +       */
  
 +      spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
        HDMI_WRITE(HDMI_CEC_CNTRL_1,
                   (HDMI_READ(HDMI_CEC_CNTRL_1) & ~VC4_HDMI_CEC_ADDR_MASK) |
                   (log_addr & 0xf) << VC4_HDMI_CEC_ADDR_SHIFT);
 +      spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
 +
        return 0;
  }
  
@@@ -2121,28 -1785,14 +2113,28 @@@ static int vc4_hdmi_cec_adap_transmit(s
  {
        struct vc4_hdmi *vc4_hdmi = cec_get_drvdata(adap);
        struct drm_device *dev = vc4_hdmi->connector.dev;
 +      unsigned long flags;
        u32 val;
        unsigned int i;
  
 +      /*
 +       * NOTE: This function should really take vc4_hdmi->mutex, but doing so
 +       * results in a reentrancy since cec_s_phys_addr_from_edid() called in
 +       * .detect or .get_modes might call .adap_enable, which leads to this
 +       * function being called with that mutex held.
 +       *
 +       * Concurrency is not an issue for the moment since we don't share any
 +       * state with KMS, so we can ignore the lock for now, but we need to
 +       * keep it in mind if we were to change that assumption.
 +       */
 +
        if (msg->len > 16) {
                drm_err(dev, "Attempting to transmit too much data (%d)\n", msg->len);
                return -ENOMEM;
        }
  
 +      spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
 +
        for (i = 0; i < msg->len; i += 4)
                HDMI_WRITE(HDMI_CEC_TX_DATA_1 + (i >> 2),
                           (msg->msg[i]) |
        val |= VC4_HDMI_CEC_START_XMIT_BEGIN;
  
        HDMI_WRITE(HDMI_CEC_CNTRL_1, val);
 +
 +      spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
 +
        return 0;
  }
  
@@@ -2175,7 -1822,6 +2167,7 @@@ static int vc4_hdmi_cec_init(struct vc4
        struct cec_connector_info conn_info;
        struct platform_device *pdev = vc4_hdmi->pdev;
        struct device *dev = &pdev->dev;
 +      unsigned long flags;
        u32 value;
        int ret;
  
        cec_fill_conn_info_from_drm(&conn_info, &vc4_hdmi->connector);
        cec_s_conn_info(vc4_hdmi->cec_adap, &conn_info);
  
 +      spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
        value = HDMI_READ(HDMI_CEC_CNTRL_1);
        /* Set the logical address to Unregistered */
        value |= VC4_HDMI_CEC_ADDR_MASK;
        HDMI_WRITE(HDMI_CEC_CNTRL_1, value);
 +      spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
  
        vc4_hdmi_cec_update_clk_div(vc4_hdmi);
  
                if (ret)
                        goto err_remove_cec_rx_handler;
        } else {
 +              spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
                HDMI_WRITE(HDMI_CEC_CPU_MASK_SET, 0xffffffff);
 +              spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
  
                ret = request_threaded_irq(platform_get_irq(pdev, 0),
                                           vc4_cec_irq_handler,
@@@ -2457,27 -2099,6 +2449,27 @@@ static int vc5_hdmi_init_resources(stru
        return 0;
  }
  
 +static int __maybe_unused vc4_hdmi_runtime_suspend(struct device *dev)
 +{
 +      struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
 +
 +      clk_disable_unprepare(vc4_hdmi->hsm_clock);
 +
 +      return 0;
 +}
 +
 +static int vc4_hdmi_runtime_resume(struct device *dev)
 +{
 +      struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
 +      int ret;
 +
 +      ret = clk_prepare_enable(vc4_hdmi->hsm_clock);
 +      if (ret)
 +              return ret;
 +
 +      return 0;
 +}
 +
  static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
  {
        const struct vc4_hdmi_variant *variant = of_device_get_match_data(dev);
        vc4_hdmi = devm_kzalloc(dev, sizeof(*vc4_hdmi), GFP_KERNEL);
        if (!vc4_hdmi)
                return -ENOMEM;
 +      mutex_init(&vc4_hdmi->mutex);
 +      spin_lock_init(&vc4_hdmi->hw_lock);
        INIT_DELAYED_WORK(&vc4_hdmi->scrambling_work, vc4_hdmi_scrambling_wq);
  
        dev_set_drvdata(dev, vc4_hdmi);
        vc4_hdmi->pdev = pdev;
        vc4_hdmi->variant = variant;
  
 +      /*
 +       * Since we don't know the state of the controller and its
 +       * display (if any), let's assume it's always enabled.
 +       * vc4_hdmi_disable_scrambling() will thus run at boot, make
 +       * sure it's disabled, and avoid any inconsistency.
 +       */
 +      vc4_hdmi->scdc_enabled = true;
 +
        ret = variant->init_resources(vc4_hdmi);
        if (ret)
                return ret;
                        vc4_hdmi->disable_4kp60 = true;
        }
  
 +      /*
 +       * If we boot without any cable connected to the HDMI connector,
 +       * the firmware will skip the HSM initialization and leave it
 +       * with a rate of 0, resulting in a bus lockup when we're
 +       * accessing the registers even if it's enabled.
 +       *
 +       * Let's put a sensible default at runtime_resume so that we
 +       * don't end up in this situation.
 +       */
 +      ret = clk_set_min_rate(vc4_hdmi->hsm_clock, HSM_MIN_CLOCK_FREQ);
 +      if (ret)
 +              goto err_put_ddc;
 +
 +      /*
 +       * We need to have the device powered up at this point to call
 +       * our reset hook and for the CEC init.
 +       */
 +      ret = vc4_hdmi_runtime_resume(dev);
 +      if (ret)
 +              goto err_put_ddc;
 +
 +      pm_runtime_get_noresume(dev);
 +      pm_runtime_set_active(dev);
 +      pm_runtime_enable(dev);
 +
        if (vc4_hdmi->variant->reset)
                vc4_hdmi->variant->reset(vc4_hdmi);
  
                clk_prepare_enable(vc4_hdmi->pixel_bvb_clock);
        }
  
 -      pm_runtime_enable(dev);
 -
        drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);
        drm_encoder_helper_add(encoder, &vc4_hdmi_encoder_helper_funcs);
  
                             vc4_hdmi_debugfs_regs,
                             vc4_hdmi);
  
 +      pm_runtime_put_sync(dev);
 +
        return 0;
  
  err_free_cec:
@@@ -2622,7 -2208,6 +2614,7 @@@ err_destroy_conn
        vc4_hdmi_connector_destroy(&vc4_hdmi->connector);
  err_destroy_encoder:
        drm_encoder_cleanup(encoder);
 +      pm_runtime_put_sync(dev);
        pm_runtime_disable(dev);
  err_put_ddc:
        put_device(&vc4_hdmi->ddc->dev);
@@@ -2709,7 -2294,7 +2701,7 @@@ static const struct vc4_hdmi_variant bc
        .encoder_type           = VC4_ENCODER_TYPE_HDMI0,
        .debugfs_name           = "hdmi0_regs",
        .card_name              = "vc4-hdmi-0",
 -      .max_pixel_clock        = HDMI_14_MAX_TMDS_CLK,
 +      .max_pixel_clock        = 600000000,
        .registers              = vc5_hdmi_hdmi0_fields,
        .num_registers          = ARRAY_SIZE(vc5_hdmi_hdmi0_fields),
        .phy_lane_mapping       = {
@@@ -2768,18 -2353,11 +2760,18 @@@ static const struct of_device_id vc4_hd
        {}
  };
  
 +static const struct dev_pm_ops vc4_hdmi_pm_ops = {
 +      SET_RUNTIME_PM_OPS(vc4_hdmi_runtime_suspend,
 +                         vc4_hdmi_runtime_resume,
 +                         NULL)
 +};
 +
  struct platform_driver vc4_hdmi_driver = {
        .probe = vc4_hdmi_dev_probe,
        .remove = vc4_hdmi_dev_remove,
        .driver = {
                .name = "vc4_hdmi",
                .of_match_table = vc4_hdmi_dt_match,
 +              .pm = &vc4_hdmi_pm_ops,
        },
  };
index 20208207e36671fbaf7333d06cba9b05c5e10b8b,d4c079f4afc63d9e052518e278b9dc377016d143..b110a2e6b8f332cf538a2c53685fccf16712f5c7
@@@ -91,6 -91,21 +91,21 @@@ config PEAQ_WM
        help
         Say Y here if you want to support WMI-based hotkeys on PEAQ 2-in-1s.
  
+ config NVIDIA_WMI_EC_BACKLIGHT
+       tristate "EC Backlight Driver for Hybrid Graphics Notebook Systems"
+       depends on ACPI_WMI
+       depends on BACKLIGHT_CLASS_DEVICE
+       help
+         This driver provides a sysfs backlight interface for notebook systems
+         which are equipped with NVIDIA hybrid graphics and drive LCD backlight
+         levels through the Embedded Controller (EC).
+         Say Y or M here if you want to control the backlight on a notebook
+         system with an EC-driven backlight.
+         If you choose to compile this driver as a module the module will be
+         called nvidia-wmi-ec-backlight.
  config XIAOMI_WMI
        tristate "Xiaomi WMI key driver"
        depends on ACPI_WMI
@@@ -426,6 -441,7 +441,7 @@@ config HP_WM
        depends on RFKILL || RFKILL = n
        select INPUT_SPARSEKMAP
        select ACPI_PLATFORM_PROFILE
+       select HWMON
        help
         Say Y here if you want to support WMI-based hotkeys on HP laptops and
         to read data from WMI such as docking or ambient light sensor state.
@@@ -501,9 -517,7 +517,9 @@@ config THINKPAD_ACP
        depends on ACPI_VIDEO || ACPI_VIDEO = n
        depends on BACKLIGHT_CLASS_DEVICE
        depends on I2C
 +      depends on DRM
        select ACPI_PLATFORM_PROFILE
 +      select DRM_PRIVACY_SCREEN
        select HWMON
        select NVRAM
        select NEW_LEDS
@@@ -715,6 -729,16 +731,16 @@@ config PCENGINES_APU
          To compile this driver as a module, choose M here: the module
          will be called pcengines-apuv2.
  
+ config BARCO_P50_GPIO
+       tristate "Barco P50 GPIO driver for identify LED/button"
+       depends on GPIOLIB
+       help
+         This driver provides access to the GPIOs for the identify button
+         and led present on Barco P50 board.
+         To compile this driver as a module, choose M here: the module
+         will be called barco-p50-gpio.
  config SAMSUNG_LAPTOP
        tristate "Samsung Laptop driver"
        depends on RFKILL || RFKILL = n
@@@ -907,6 -931,9 +933,9 @@@ config SONYPI_COMPA
  config SYSTEM76_ACPI
        tristate "System76 ACPI Driver"
        depends on ACPI
+       depends on ACPI_BATTERY
+       depends on HWMON
+       depends on INPUT
        select NEW_LEDS
        select LEDS_CLASS
        select LEDS_TRIGGERS
index 291cd18c9c8fc321e579dfdee5f297fb3592be3e,9c632df734bbf45a7039a8a636138722847f0f32..b39dbc2fe45b2c745cbec2918cbcd4ea0d812847
@@@ -73,7 -73,6 +73,7 @@@
  #include <linux/uaccess.h>
  #include <acpi/battery.h>
  #include <acpi/video.h>
 +#include <drm/drm_privacy_screen_driver.h>
  #include "dual_accel_detect.h"
  
  /* ThinkPad CMOS commands */
@@@ -158,7 -157,6 +158,7 @@@ enum tpacpi_hkey_event_t 
        TP_HKEY_EV_VOL_UP               = 0x1015, /* Volume up or unmute */
        TP_HKEY_EV_VOL_DOWN             = 0x1016, /* Volume down or unmute */
        TP_HKEY_EV_VOL_MUTE             = 0x1017, /* Mixer output mute */
 +      TP_HKEY_EV_PRIVACYGUARD_TOGGLE  = 0x130f, /* Toggle priv.guard on/off */
  
        /* Reasons for waking up from S3/S4 */
        TP_HKEY_EV_WKUP_S3_UNDOCK       = 0x2304, /* undock requested, S3 */
@@@ -1003,79 -1001,6 +1003,6 @@@ static struct platform_driver tpacpi_hw
   * sysfs support helpers
   */
  
- struct attribute_set {
-       unsigned int members, max_members;
-       struct attribute_group group;
- };
- struct attribute_set_obj {
-       struct attribute_set s;
-       struct attribute *a;
- } __attribute__((packed));
- static struct attribute_set *create_attr_set(unsigned int max_members,
-                                               const char *name)
- {
-       struct attribute_set_obj *sobj;
-       if (max_members == 0)
-               return NULL;
-       /* Allocates space for implicit NULL at the end too */
-       sobj = kzalloc(sizeof(struct attribute_set_obj) +
-                   max_members * sizeof(struct attribute *),
-                   GFP_KERNEL);
-       if (!sobj)
-               return NULL;
-       sobj->s.max_members = max_members;
-       sobj->s.group.attrs = &sobj->a;
-       sobj->s.group.name = name;
-       return &sobj->s;
- }
- #define destroy_attr_set(_set) \
-       kfree(_set)
- /* not multi-threaded safe, use it in a single thread per set */
- static int add_to_attr_set(struct attribute_set *s, struct attribute *attr)
- {
-       if (!s || !attr)
-               return -EINVAL;
-       if (s->members >= s->max_members)
-               return -ENOMEM;
-       s->group.attrs[s->members] = attr;
-       s->members++;
-       return 0;
- }
- static int add_many_to_attr_set(struct attribute_set *s,
-                       struct attribute **attr,
-                       unsigned int count)
- {
-       int i, res;
-       for (i = 0; i < count; i++) {
-               res = add_to_attr_set(s, attr[i]);
-               if (res)
-                       return res;
-       }
-       return 0;
- }
- static void delete_attr_set(struct attribute_set *s, struct kobject *kobj)
- {
-       sysfs_remove_group(kobj, &s->group);
-       destroy_attr_set(s);
- }
- #define register_attr_set_with_sysfs(_attr_set, _kobj) \
-       sysfs_create_group(_kobj, &_attr_set->group)
  static int parse_strtoul(const char *buf,
                unsigned long max, unsigned long *value)
  {
@@@ -1350,7 -1275,7 +1277,7 @@@ static ssize_t tpacpi_rfk_sysfs_enable_
                        return status;
        }
  
-       return snprintf(buf, PAGE_SIZE, "%d\n",
+       return sysfs_emit(buf, "%d\n",
                        (status == TPACPI_RFK_RADIO_ON) ? 1 : 0);
  }
  
@@@ -1443,14 -1368,14 +1370,14 @@@ static int tpacpi_rfk_procfs_write(cons
  /* interface_version --------------------------------------------------- */
  static ssize_t interface_version_show(struct device_driver *drv, char *buf)
  {
-       return snprintf(buf, PAGE_SIZE, "0x%08x\n", TPACPI_SYSFS_VERSION);
+       return sysfs_emit(buf, "0x%08x\n", TPACPI_SYSFS_VERSION);
  }
  static DRIVER_ATTR_RO(interface_version);
  
  /* debug_level --------------------------------------------------------- */
  static ssize_t debug_level_show(struct device_driver *drv, char *buf)
  {
-       return snprintf(buf, PAGE_SIZE, "0x%04x\n", dbg_level);
+       return sysfs_emit(buf, "0x%04x\n", dbg_level);
  }
  
  static ssize_t debug_level_store(struct device_driver *drv, const char *buf,
@@@ -1470,7 -1395,7 +1397,7 @@@ static DRIVER_ATTR_RW(debug_level)
  /* version ------------------------------------------------------------- */
  static ssize_t version_show(struct device_driver *drv, char *buf)
  {
-       return snprintf(buf, PAGE_SIZE, "%s v%s\n",
+       return sysfs_emit(buf, "%s v%s\n",
                        TPACPI_DESC, TPACPI_VERSION);
  }
  static DRIVER_ATTR_RO(version);
  /* wlsw_emulstate ------------------------------------------------------ */
  static ssize_t wlsw_emulstate_show(struct device_driver *drv, char *buf)
  {
-       return snprintf(buf, PAGE_SIZE, "%d\n", !!tpacpi_wlsw_emulstate);
+       return sysfs_emit(buf, "%d\n", !!tpacpi_wlsw_emulstate);
  }
  
  static ssize_t wlsw_emulstate_store(struct device_driver *drv, const char *buf,
@@@ -1505,7 -1430,7 +1432,7 @@@ static DRIVER_ATTR_RW(wlsw_emulstate)
  /* bluetooth_emulstate ------------------------------------------------- */
  static ssize_t bluetooth_emulstate_show(struct device_driver *drv, char *buf)
  {
-       return snprintf(buf, PAGE_SIZE, "%d\n", !!tpacpi_bluetooth_emulstate);
+       return sysfs_emit(buf, "%d\n", !!tpacpi_bluetooth_emulstate);
  }
  
  static ssize_t bluetooth_emulstate_store(struct device_driver *drv,
@@@ -1525,7 -1450,7 +1452,7 @@@ static DRIVER_ATTR_RW(bluetooth_emulsta
  /* wwan_emulstate ------------------------------------------------- */
  static ssize_t wwan_emulstate_show(struct device_driver *drv, char *buf)
  {
-       return snprintf(buf, PAGE_SIZE, "%d\n", !!tpacpi_wwan_emulstate);
+       return sysfs_emit(buf, "%d\n", !!tpacpi_wwan_emulstate);
  }
  
  static ssize_t wwan_emulstate_store(struct device_driver *drv, const char *buf,
@@@ -1545,7 -1470,7 +1472,7 @@@ static DRIVER_ATTR_RW(wwan_emulstate)
  /* uwb_emulstate ------------------------------------------------- */
  static ssize_t uwb_emulstate_show(struct device_driver *drv, char *buf)
  {
-       return snprintf(buf, PAGE_SIZE, "%d\n", !!tpacpi_uwb_emulstate);
+       return sysfs_emit(buf, "%d\n", !!tpacpi_uwb_emulstate);
  }
  
  static ssize_t uwb_emulstate_store(struct device_driver *drv, const char *buf,
@@@ -2044,8 -1969,6 +1971,6 @@@ static u32 hotkey_acpi_mask;            /* event
  
  static u16 *hotkey_keycode_map;
  
- static struct attribute_set *hotkey_dev_attributes;
  static void tpacpi_driver_event(const unsigned int hkey_event);
  static void hotkey_driver_event(const unsigned int scancode);
  static void hotkey_poll_setup(const bool may_warn);
@@@ -2755,7 -2678,7 +2680,7 @@@ static ssize_t hotkey_enable_show(struc
        if (res)
                return res;
  
-       return snprintf(buf, PAGE_SIZE, "%d\n", status);
+       return sysfs_emit(buf, "%d\n", status);
  }
  
  static ssize_t hotkey_enable_store(struct device *dev,
@@@ -2783,7 -2706,7 +2708,7 @@@ static ssize_t hotkey_mask_show(struct 
                           struct device_attribute *attr,
                           char *buf)
  {
-       return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_user_mask);
+       return sysfs_emit(buf, "0x%08x\n", hotkey_user_mask);
  }
  
  static ssize_t hotkey_mask_store(struct device *dev,
@@@ -2831,7 -2754,7 +2756,7 @@@ static ssize_t hotkey_bios_mask_show(st
  {
        printk_deprecated_attribute("hotkey_bios_mask",
                        "This attribute is useless.");
-       return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_orig_mask);
+       return sysfs_emit(buf, "0x%08x\n", hotkey_orig_mask);
  }
  
  static DEVICE_ATTR_RO(hotkey_bios_mask);
@@@ -2841,7 -2764,7 +2766,7 @@@ static ssize_t hotkey_all_mask_show(str
                           struct device_attribute *attr,
                           char *buf)
  {
-       return snprintf(buf, PAGE_SIZE, "0x%08x\n",
+       return sysfs_emit(buf, "0x%08x\n",
                                hotkey_all_mask | hotkey_source_mask);
  }
  
@@@ -2852,7 -2775,7 +2777,7 @@@ static ssize_t hotkey_adaptive_all_mask
                           struct device_attribute *attr,
                           char *buf)
  {
-       return snprintf(buf, PAGE_SIZE, "0x%08x\n",
+       return sysfs_emit(buf, "0x%08x\n",
                        hotkey_adaptive_all_mask | hotkey_source_mask);
  }
  
@@@ -2863,7 -2786,7 +2788,7 @@@ static ssize_t hotkey_recommended_mask_
                                            struct device_attribute *attr,
                                            char *buf)
  {
-       return snprintf(buf, PAGE_SIZE, "0x%08x\n",
+       return sysfs_emit(buf, "0x%08x\n",
                        (hotkey_all_mask | hotkey_source_mask)
                        & ~hotkey_reserved_mask);
  }
@@@ -2877,7 -2800,7 +2802,7 @@@ static ssize_t hotkey_source_mask_show(
                           struct device_attribute *attr,
                           char *buf)
  {
-       return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_source_mask);
+       return sysfs_emit(buf, "0x%08x\n", hotkey_source_mask);
  }
  
  static ssize_t hotkey_source_mask_store(struct device *dev,
@@@ -2928,7 -2851,7 +2853,7 @@@ static ssize_t hotkey_poll_freq_show(st
                           struct device_attribute *attr,
                           char *buf)
  {
-       return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_poll_freq);
+       return sysfs_emit(buf, "%d\n", hotkey_poll_freq);
  }
  
  static ssize_t hotkey_poll_freq_store(struct device *dev,
@@@ -2970,7 -2893,7 +2895,7 @@@ static ssize_t hotkey_radio_sw_show(str
        /* Opportunistic update */
        tpacpi_rfk_update_hwblock_state((res == TPACPI_RFK_RADIO_OFF));
  
-       return snprintf(buf, PAGE_SIZE, "%d\n",
+       return sysfs_emit(buf, "%d\n",
                        (res == TPACPI_RFK_RADIO_OFF) ? 0 : 1);
  }
  
@@@ -2993,7 -2916,7 +2918,7 @@@ static ssize_t hotkey_tablet_mode_show(
        if (res < 0)
                return res;
  
-       return snprintf(buf, PAGE_SIZE, "%d\n", !!s);
+       return sysfs_emit(buf, "%d\n", !!s);
  }
  
  static DEVICE_ATTR_RO(hotkey_tablet_mode);
@@@ -3010,7 -2933,7 +2935,7 @@@ static ssize_t hotkey_wakeup_reason_sho
                           struct device_attribute *attr,
                           char *buf)
  {
-       return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_wakeup_reason);
+       return sysfs_emit(buf, "%d\n", hotkey_wakeup_reason);
  }
  
  static DEVICE_ATTR(wakeup_reason, S_IRUGO, hotkey_wakeup_reason_show, NULL);
@@@ -3026,7 -2949,7 +2951,7 @@@ static ssize_t hotkey_wakeup_hotunplug_
                           struct device_attribute *attr,
                           char *buf)
  {
-       return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_autosleep_ack);
+       return sysfs_emit(buf, "%d\n", hotkey_autosleep_ack);
  }
  
  static DEVICE_ATTR(wakeup_hotunplug_complete, S_IRUGO,
@@@ -3061,7 -2984,7 +2986,7 @@@ static ssize_t adaptive_kbd_mode_show(s
        if (current_mode < 0)
                return current_mode;
  
-       return snprintf(buf, PAGE_SIZE, "%d\n", current_mode);
+       return sysfs_emit(buf, "%d\n", current_mode);
  }
  
  static ssize_t adaptive_kbd_mode_store(struct device *dev,
@@@ -3091,7 -3014,7 +3016,7 @@@ static const struct attribute_group ada
  
  /* --------------------------------------------------------------------- */
  
- static struct attribute *hotkey_attributes[] __initdata = {
+ static struct attribute *hotkey_attributes[] = {
        &dev_attr_hotkey_enable.attr,
        &dev_attr_hotkey_bios_enabled.attr,
        &dev_attr_hotkey_bios_mask.attr,
        &dev_attr_hotkey_source_mask.attr,
        &dev_attr_hotkey_poll_freq.attr,
  #endif
+       NULL
+ };
+ static umode_t hotkey_attr_is_visible(struct kobject *kobj,
+                                     struct attribute *attr, int n)
+ {
+       if (attr == &dev_attr_hotkey_tablet_mode.attr) {
+               if (!tp_features.hotkey_tablet)
+                       return 0;
+       } else if (attr == &dev_attr_hotkey_radio_sw.attr) {
+               if (!tp_features.hotkey_wlsw)
+                       return 0;
+       }
+       return attr->mode;
+ }
+ static const struct attribute_group hotkey_attr_group = {
+       .is_visible = hotkey_attr_is_visible,
+       .attrs = hotkey_attributes,
  };
  
  /*
@@@ -3163,9 -3106,7 +3108,7 @@@ static void hotkey_exit(void
        hotkey_poll_stop_sync();
        mutex_unlock(&hotkey_mutex);
  #endif
-       if (hotkey_dev_attributes)
-               delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj);
+       sysfs_remove_group(&tpacpi_pdev->dev.kobj, &hotkey_attr_group);
  
        dbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_HKEY,
                   "restoring original HKEY status and mask\n");
@@@ -3251,11 -3192,6 +3194,6 @@@ static int hotkey_init_tablet_mode(void
        pr_info("Tablet mode switch found (type: %s), currently in %s mode\n",
                type, in_tablet_mode ? "tablet" : "laptop");
  
-       res = add_to_attr_set(hotkey_dev_attributes,
-                             &dev_attr_hotkey_tablet_mode.attr);
-       if (res)
-               return -1;
        return in_tablet_mode;
  }
  
@@@ -3517,19 -3453,6 +3455,6 @@@ static int __init hotkey_init(struct ib
  
        tpacpi_disable_brightness_delay();
  
-       /* MUST have enough space for all attributes to be added to
-        * hotkey_dev_attributes */
-       hotkey_dev_attributes = create_attr_set(
-                                       ARRAY_SIZE(hotkey_attributes) + 2,
-                                       NULL);
-       if (!hotkey_dev_attributes)
-               return -ENOMEM;
-       res = add_many_to_attr_set(hotkey_dev_attributes,
-                       hotkey_attributes,
-                       ARRAY_SIZE(hotkey_attributes));
-       if (res)
-               goto err_exit;
        /* mask not supported on 600e/x, 770e, 770x, A21e, A2xm/p,
           A30, R30, R31, T20-22, X20-21, X22-24.  Detected by checking
           for HKEY interface version 0x100 */
                pr_info("radio switch found; radios are %s\n",
                        enabled(status, 0));
        }
-       if (tp_features.hotkey_wlsw)
-               res = add_to_attr_set(hotkey_dev_attributes,
-                               &dev_attr_hotkey_radio_sw.attr);
-       res = hotkey_init_tablet_mode();
-       if (res < 0)
-               goto err_exit;
  
-       tabletsw_state = res;
-       res = register_attr_set_with_sysfs(hotkey_dev_attributes,
-                                          &tpacpi_pdev->dev.kobj);
+       tabletsw_state = hotkey_init_tablet_mode();
+       res = sysfs_create_group(&tpacpi_pdev->dev.kobj, &hotkey_attr_group);
        if (res)
                goto err_exit;
  
        return 0;
  
  err_exit:
-       delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj);
-       sysfs_remove_group(&tpacpi_pdev->dev.kobj,
-                       &adaptive_kbd_attr_group);
-       hotkey_dev_attributes = NULL;
+       sysfs_remove_group(&tpacpi_pdev->dev.kobj, &hotkey_attr_group);
+       sysfs_remove_group(&tpacpi_pdev->dev.kobj, &adaptive_kbd_attr_group);
  
        return (res < 0) ? res : 1;
  }
@@@ -3887,30 -3798,6 +3800,30 @@@ static bool adaptive_keyboard_hotkey_no
        }
  }
  
 +static bool hotkey_notify_extended_hotkey(const u32 hkey)
 +{
 +      unsigned int scancode;
 +
 +      switch (hkey) {
 +      case TP_HKEY_EV_PRIVACYGUARD_TOGGLE:
 +              tpacpi_driver_event(hkey);
 +              return true;
 +      }
 +
 +      /* Extended keycodes start at 0x300 and our offset into the map
 +       * TP_ACPI_HOTKEYSCAN_EXTENDED_START. The calculated scancode
 +       * will be positive, but might not be in the correct range.
 +       */
 +      scancode = (hkey & 0xfff) - (0x300 - TP_ACPI_HOTKEYSCAN_EXTENDED_START);
 +      if (scancode >= TP_ACPI_HOTKEYSCAN_EXTENDED_START &&
 +          scancode < TPACPI_HOTKEY_MAP_LEN) {
 +              tpacpi_input_send_key(scancode);
 +              return true;
 +      }
 +
 +      return false;
 +}
 +
  static bool hotkey_notify_hotkey(const u32 hkey,
                                 bool *send_acpi_ev,
                                 bool *ignore_acpi_ev)
                return adaptive_keyboard_hotkey_notify_hotkey(scancode);
  
        case 3:
 -              /* Extended keycodes start at 0x300 and our offset into the map
 -               * TP_ACPI_HOTKEYSCAN_EXTENDED_START. The calculated scancode
 -               * will be positive, but might not be in the correct range.
 -               */
 -              scancode -= (0x300 - TP_ACPI_HOTKEYSCAN_EXTENDED_START);
 -              if (scancode >= TP_ACPI_HOTKEYSCAN_EXTENDED_START &&
 -                  scancode < TPACPI_HOTKEY_MAP_LEN) {
 -                      tpacpi_input_send_key(scancode);
 -                      return true;
 -              }
 -              break;
 +              return hotkey_notify_extended_hotkey(hkey);
        }
  
        return false;
@@@ -6437,7 -6334,7 +6350,7 @@@ static ssize_t thermal_temp_input_show(
        if (value == TPACPI_THERMAL_SENSOR_NA)
                return -ENXIO;
  
-       return snprintf(buf, PAGE_SIZE, "%d\n", value);
+       return sysfs_emit(buf, "%d\n", value);
  }
  
  #define THERMAL_SENSOR_ATTR_TEMP(_idxA, _idxB) \
@@@ -8670,7 -8567,7 +8583,7 @@@ static ssize_t fan_pwm1_enable_show(str
        } else
                mode = 1;
  
-       return snprintf(buf, PAGE_SIZE, "%d\n", mode);
+       return sysfs_emit(buf, "%d\n", mode);
  }
  
  static ssize_t fan_pwm1_enable_store(struct device *dev,
@@@ -8736,7 -8633,7 +8649,7 @@@ static ssize_t fan_pwm1_show(struct dev
        if (status > 7)
                status = 7;
  
-       return snprintf(buf, PAGE_SIZE, "%u\n", (status * 255) / 7);
+       return sysfs_emit(buf, "%u\n", (status * 255) / 7);
  }
  
  static ssize_t fan_pwm1_store(struct device *dev,
@@@ -8789,7 -8686,7 +8702,7 @@@ static ssize_t fan_fan1_input_show(stru
        if (res < 0)
                return res;
  
-       return snprintf(buf, PAGE_SIZE, "%u\n", speed);
+       return sysfs_emit(buf, "%u\n", speed);
  }
  
  static DEVICE_ATTR(fan1_input, S_IRUGO, fan_fan1_input_show, NULL);
@@@ -8806,7 -8703,7 +8719,7 @@@ static ssize_t fan_fan2_input_show(stru
        if (res < 0)
                return res;
  
-       return snprintf(buf, PAGE_SIZE, "%u\n", speed);
+       return sysfs_emit(buf, "%u\n", speed);
  }
  
  static DEVICE_ATTR(fan2_input, S_IRUGO, fan_fan2_input_show, NULL);
  /* sysfs fan fan_watchdog (hwmon driver) ------------------------------- */
  static ssize_t fan_watchdog_show(struct device_driver *drv, char *buf)
  {
-       return snprintf(buf, PAGE_SIZE, "%u\n", fan_watchdog_maxinterval);
+       return sysfs_emit(buf, "%u\n", fan_watchdog_maxinterval);
  }
  
  static ssize_t fan_watchdog_store(struct device_driver *drv, const char *buf,
@@@ -9161,7 -9058,7 +9074,7 @@@ static int fan_write_cmd_level(const ch
  
        if (strlencmp(cmd, "level auto") == 0)
                level = TP_EC_FAN_AUTO;
-       else if ((strlencmp(cmd, "level disengaged") == 0) |
+       else if ((strlencmp(cmd, "level disengaged") == 0) ||
                        (strlencmp(cmd, "level full-speed") == 0))
                level = TP_EC_FAN_FULLSPEED;
        else if (sscanf(cmd, "level %d", &level) != 1)
@@@ -9827,85 -9724,69 +9740,85 @@@ static struct ibm_struct battery_driver
   * LCD Shadow subdriver, for the Lenovo PrivacyGuard feature
   */
  
 -static int lcdshadow_state;
 +static struct drm_privacy_screen *lcdshadow_dev;
 +static acpi_handle lcdshadow_get_handle;
 +static acpi_handle lcdshadow_set_handle;
  
 -static int lcdshadow_on_off(bool state)
 +static int lcdshadow_set_sw_state(struct drm_privacy_screen *priv,
 +                                enum drm_privacy_screen_status state)
  {
 -      acpi_handle set_shadow_handle;
        int output;
  
 -      if (ACPI_FAILURE(acpi_get_handle(hkey_handle, "SSSS", &set_shadow_handle))) {
 -              pr_warn("Thinkpad ACPI has no %s interface.\n", "SSSS");
 +      if (WARN_ON(!mutex_is_locked(&priv->lock)))
                return -EIO;
 -      }
  
 -      if (!acpi_evalf(set_shadow_handle, &output, NULL, "dd", (int)state))
 +      if (!acpi_evalf(lcdshadow_set_handle, &output, NULL, "dd", (int)state))
                return -EIO;
  
 -      lcdshadow_state = state;
 +      priv->hw_state = priv->sw_state = state;
        return 0;
  }
  
 -static int lcdshadow_set(bool on)
 +static void lcdshadow_get_hw_state(struct drm_privacy_screen *priv)
  {
 -      if (lcdshadow_state < 0)
 -              return lcdshadow_state;
 -      if (lcdshadow_state == on)
 -              return 0;
 -      return lcdshadow_on_off(on);
 +      int output;
 +
 +      if (!acpi_evalf(lcdshadow_get_handle, &output, NULL, "dd", 0))
 +              return;
 +
 +      priv->hw_state = priv->sw_state = output & 0x1;
  }
  
 +static const struct drm_privacy_screen_ops lcdshadow_ops = {
 +      .set_sw_state = lcdshadow_set_sw_state,
 +      .get_hw_state = lcdshadow_get_hw_state,
 +};
 +
  static int tpacpi_lcdshadow_init(struct ibm_init_struct *iibm)
  {
 -      acpi_handle get_shadow_handle;
 +      acpi_status status1, status2;
        int output;
  
 -      if (ACPI_FAILURE(acpi_get_handle(hkey_handle, "GSSS", &get_shadow_handle))) {
 -              lcdshadow_state = -ENODEV;
 +      status1 = acpi_get_handle(hkey_handle, "GSSS", &lcdshadow_get_handle);
 +      status2 = acpi_get_handle(hkey_handle, "SSSS", &lcdshadow_set_handle);
 +      if (ACPI_FAILURE(status1) || ACPI_FAILURE(status2))
                return 0;
 -      }
  
 -      if (!acpi_evalf(get_shadow_handle, &output, NULL, "dd", 0)) {
 -              lcdshadow_state = -EIO;
 +      if (!acpi_evalf(lcdshadow_get_handle, &output, NULL, "dd", 0))
                return -EIO;
 -      }
 -      if (!(output & 0x10000)) {
 -              lcdshadow_state = -ENODEV;
 +
 +      if (!(output & 0x10000))
                return 0;
 -      }
 -      lcdshadow_state = output & 0x1;
 +
 +      lcdshadow_dev = drm_privacy_screen_register(&tpacpi_pdev->dev,
 +                                                  &lcdshadow_ops);
 +      if (IS_ERR(lcdshadow_dev))
 +              return PTR_ERR(lcdshadow_dev);
  
        return 0;
  }
  
 +static void lcdshadow_exit(void)
 +{
 +      drm_privacy_screen_unregister(lcdshadow_dev);
 +}
 +
  static void lcdshadow_resume(void)
  {
 -      if (lcdshadow_state >= 0)
 -              lcdshadow_on_off(lcdshadow_state);
 +      if (!lcdshadow_dev)
 +              return;
 +
 +      mutex_lock(&lcdshadow_dev->lock);
 +      lcdshadow_set_sw_state(lcdshadow_dev, lcdshadow_dev->sw_state);
 +      mutex_unlock(&lcdshadow_dev->lock);
  }
  
  static int lcdshadow_read(struct seq_file *m)
  {
 -      if (lcdshadow_state < 0) {
 +      if (!lcdshadow_dev) {
                seq_puts(m, "status:\t\tnot supported\n");
        } else {
 -              seq_printf(m, "status:\t\t%d\n", lcdshadow_state);
 +              seq_printf(m, "status:\t\t%d\n", lcdshadow_dev->hw_state);
                seq_puts(m, "commands:\t0, 1\n");
        }
  
@@@ -9917,7 -9798,7 +9830,7 @@@ static int lcdshadow_write(char *buf
        char *cmd;
        int res, state = -EINVAL;
  
 -      if (lcdshadow_state < 0)
 +      if (!lcdshadow_dev)
                return -ENODEV;
  
        while ((cmd = strsep(&buf, ","))) {
        if (state >= 2 || state < 0)
                return -EINVAL;
  
 -      return lcdshadow_set(state);
 +      mutex_lock(&lcdshadow_dev->lock);
 +      res = lcdshadow_set_sw_state(lcdshadow_dev, state);
 +      mutex_unlock(&lcdshadow_dev->lock);
 +
 +      drm_privacy_screen_call_notifier_chain(lcdshadow_dev);
 +
 +      return res;
  }
  
  static struct ibm_struct lcdshadow_driver_data = {
        .name = "lcdshadow",
 +      .exit = lcdshadow_exit,
        .resume = lcdshadow_resume,
        .read = lcdshadow_read,
        .write = lcdshadow_write,
@@@ -10750,20 -10624,6 +10663,20 @@@ static void tpacpi_driver_event(const u
                if (!atomic_add_unless(&dytc_ignore_event, -1, 0))
                        dytc_profile_refresh();
        }
 +
 +      if (lcdshadow_dev && hkey_event == TP_HKEY_EV_PRIVACYGUARD_TOGGLE) {
 +              enum drm_privacy_screen_status old_hw_state;
 +              bool changed;
 +
 +              mutex_lock(&lcdshadow_dev->lock);
 +              old_hw_state = lcdshadow_dev->hw_state;
 +              lcdshadow_get_hw_state(lcdshadow_dev);
 +              changed = lcdshadow_dev->hw_state != old_hw_state;
 +              mutex_unlock(&lcdshadow_dev->lock);
 +
 +              if (changed)
 +                      drm_privacy_screen_call_notifier_chain(lcdshadow_dev);
 +      }
  }
  
  static void hotkey_driver_event(const unsigned int scancode)
diff --combined drivers/pwm/core.c
index 2c6b155002a2f59f1abfc13d9c3c9fbad7101f3c,fb04a439462c74bcd7db62f271dcb6b5f9f07234..93772ab8d7e3e3f1bad619d97f0527961ddd9813
@@@ -152,32 -152,6 +152,32 @@@ of_pwm_xlate_with_flags(struct pwm_chi
  }
  EXPORT_SYMBOL_GPL(of_pwm_xlate_with_flags);
  
 +struct pwm_device *
 +of_pwm_single_xlate(struct pwm_chip *pc, const struct of_phandle_args *args)
 +{
 +      struct pwm_device *pwm;
 +
 +      if (pc->of_pwm_n_cells < 1)
 +              return ERR_PTR(-EINVAL);
 +
 +      /* validate that one cell is specified, optionally with flags */
 +      if (args->args_count != 1 && args->args_count != 2)
 +              return ERR_PTR(-EINVAL);
 +
 +      pwm = pwm_request_from_chip(pc, 0, NULL);
 +      if (IS_ERR(pwm))
 +              return pwm;
 +
 +      pwm->args.period = args->args[0];
 +      pwm->args.polarity = PWM_POLARITY_NORMAL;
 +
 +      if (args->args_count == 2 && args->args[2] & PWM_POLARITY_INVERTED)
 +              pwm->args.polarity = PWM_POLARITY_INVERSED;
 +
 +      return pwm;
 +}
 +EXPORT_SYMBOL_GPL(of_pwm_single_xlate);
 +
  static void of_pwmchip_add(struct pwm_chip *chip)
  {
        if (!chip->dev || !chip->dev->of_node)
@@@ -558,6 -532,15 +558,15 @@@ int pwm_apply_state(struct pwm_device *
        struct pwm_chip *chip;
        int err;
  
+       /*
+        * Some lowlevel driver's implementations of .apply() make use of
+        * mutexes, also with some drivers only returning when the new
+        * configuration is active calling pwm_apply_state() from atomic context
+        * is a bad idea. So make it explicit that calling this function might
+        * sleep.
+        */
+       might_sleep();
        if (!pwm || !state || !state->period ||
            state->duty_cycle > state->period)
                return -EINVAL;
diff --combined include/linux/dma-buf.h
index 9807aef33685c2fd04c5a279fba1ddb98de1db7f,42a323a73c618b9d94d35fa214bc33948362f1bc..7ab50076e7a604010c06bfc9bc895f522f60e8c1
@@@ -86,8 -86,8 +86,8 @@@ struct dma_buf_ops 
         * @pin:
         *
         * This is called by dma_buf_pin() and lets the exporter know that the
-        * DMA-buf can't be moved any more. The exporter should pin the buffer
-        * into system memory to make sure it is generally accessible by other
+        * DMA-buf can't be moved any more. Ideally, the exporter should
+        * pin the buffer so that it is generally accessible by all
         * devices.
         *
         * This is called with the &dmabuf.resv object locked and is mutual
@@@ -433,8 -433,8 +433,8 @@@ struct dma_buf 
        /** @poll: for userspace poll support */
        wait_queue_head_t poll;
  
 -      /** @cb_excl: for userspace poll support */
 -      /** @cb_shared: for userspace poll support */
 +      /** @cb_in: for userspace poll support */
 +      /** @cb_out: for userspace poll support */
        struct dma_buf_poll_cb_t {
                struct dma_fence_cb cb;
                wait_queue_head_t *poll;
diff --combined include/linux/pwm.h
index dd51d4931fdc00937e40debdd652975677a9f463,e6dac95e4960923c51c46bfb142b515c1e055ad6..9771a0761a40e016c0f8a7696489091c0ebc9d97
@@@ -414,8 -414,6 +414,8 @@@ struct pwm_device *pwm_request_from_chi
  
  struct pwm_device *of_pwm_xlate_with_flags(struct pwm_chip *pc,
                const struct of_phandle_args *args);
 +struct pwm_device *of_pwm_single_xlate(struct pwm_chip *pc,
 +                                     const struct of_phandle_args *args);
  
  struct pwm_device *pwm_get(struct device *dev, const char *con_id);
  struct pwm_device *of_pwm_get(struct device *dev, struct device_node *np,
@@@ -431,16 -429,19 +431,19 @@@ struct pwm_device *devm_fwnode_pwm_get(
  #else
  static inline struct pwm_device *pwm_request(int pwm_id, const char *label)
  {
+       might_sleep();
        return ERR_PTR(-ENODEV);
  }
  
  static inline void pwm_free(struct pwm_device *pwm)
  {
+       might_sleep();
  }
  
  static inline int pwm_apply_state(struct pwm_device *pwm,
                                  const struct pwm_state *state)
  {
+       might_sleep();
        return -ENOTSUPP;
  }
  
@@@ -452,6 -453,7 +455,7 @@@ static inline int pwm_adjust_config(str
  static inline int pwm_config(struct pwm_device *pwm, int duty_ns,
                             int period_ns)
  {
+       might_sleep();
        return -EINVAL;
  }
  
@@@ -464,11 -466,13 +468,13 @@@ static inline int pwm_capture(struct pw
  
  static inline int pwm_enable(struct pwm_device *pwm)
  {
+       might_sleep();
        return -EINVAL;
  }
  
  static inline void pwm_disable(struct pwm_device *pwm)
  {
+       might_sleep();
  }
  
  static inline int pwm_set_chip_data(struct pwm_device *pwm, void *data)
@@@ -495,12 -499,14 +501,14 @@@ static inline struct pwm_device *pwm_re
                                                       unsigned int index,
                                                       const char *label)
  {
+       might_sleep();
        return ERR_PTR(-ENODEV);
  }
  
  static inline struct pwm_device *pwm_get(struct device *dev,
                                         const char *consumer)
  {
+       might_sleep();
        return ERR_PTR(-ENODEV);
  }
  
@@@ -508,16 -514,19 +516,19 @@@ static inline struct pwm_device *of_pwm
                                            struct device_node *np,
                                            const char *con_id)
  {
+       might_sleep();
        return ERR_PTR(-ENODEV);
  }
  
  static inline void pwm_put(struct pwm_device *pwm)
  {
+       might_sleep();
  }
  
  static inline struct pwm_device *devm_pwm_get(struct device *dev,
                                              const char *consumer)
  {
+       might_sleep();
        return ERR_PTR(-ENODEV);
  }
  
@@@ -525,6 -534,7 +536,7 @@@ static inline struct pwm_device *devm_o
                                                 struct device_node *np,
                                                 const char *con_id)
  {
+       might_sleep();
        return ERR_PTR(-ENODEV);
  }
  
@@@ -532,6 -542,7 +544,7 @@@ static inline struct pwm_device 
  devm_fwnode_pwm_get(struct device *dev, struct fwnode_handle *fwnode,
                    const char *con_id)
  {
+       might_sleep();
        return ERR_PTR(-ENODEV);
  }
  #endif
This page took 0.441812 seconds and 4 git commands to generate.