summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pagano <mpagano@gentoo.org>2021-05-12 08:30:11 -0400
committerMike Pagano <mpagano@gentoo.org>2021-05-12 08:30:11 -0400
commitc9d5ee0d0a4467cf833043032dceaf8d526cef79 (patch)
tree795164808aaabbd3d6e90ddfc6d766209974d80f
parentLinux patch 5.12.2 (diff)
downloadlinux-patches-c9d5ee0d0a4467cf833043032dceaf8d526cef79.tar.gz
linux-patches-c9d5ee0d0a4467cf833043032dceaf8d526cef79.tar.bz2
linux-patches-c9d5ee0d0a4467cf833043032dceaf8d526cef79.zip
Linux patch 5.12.35.12-4
Signed-off-by: Mike Pagano <mpagano@gentoo.org>
-rw-r--r--0000_README4
-rw-r--r--1002_linux-5.12.3.patch16867
2 files changed, 16871 insertions, 0 deletions
diff --git a/0000_README b/0000_README
index d1c77caf..00f2c30b 100644
--- a/0000_README
+++ b/0000_README
@@ -51,6 +51,10 @@ Patch: 1001_linux-5.12.2.patch
From: http://www.kernel.org
Desc: Linux 5.12.2
+Patch: 1002_linux-5.12.3.patch
+From: http://www.kernel.org
+Desc: Linux 5.12.3
+
Patch: 1500_XATTR_USER_PREFIX.patch
From: https://bugs.gentoo.org/show_bug.cgi?id=470644
Desc: Support for namespace user.pax.* on tmpfs.
diff --git a/1002_linux-5.12.3.patch b/1002_linux-5.12.3.patch
new file mode 100644
index 00000000..4a0a0399
--- /dev/null
+++ b/1002_linux-5.12.3.patch
@@ -0,0 +1,16867 @@
+diff --git a/Makefile b/Makefile
+index 5077411a1874b..53a4b1cb7bb06 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 5
+ PATCHLEVEL = 12
+-SUBLEVEL = 2
++SUBLEVEL = 3
+ EXTRAVERSION =
+ NAME = Frozen Wasteland
+
+@@ -775,16 +775,16 @@ KBUILD_CFLAGS += -Wno-gnu
+ KBUILD_CFLAGS += -mno-global-merge
+ else
+
+-# These warnings generated too much noise in a regular build.
+-# Use make W=1 to enable them (see scripts/Makefile.extrawarn)
+-KBUILD_CFLAGS += -Wno-unused-but-set-variable
+-
+ # Warn about unmarked fall-throughs in switch statement.
+ # Disabled for clang while comment to attribute conversion happens and
+ # https://github.com/ClangBuiltLinux/linux/issues/636 is discussed.
+ KBUILD_CFLAGS += $(call cc-option,-Wimplicit-fallthrough,)
+ endif
+
++# These warnings generated too much noise in a regular build.
++# Use make W=1 to enable them (see scripts/Makefile.extrawarn)
++KBUILD_CFLAGS += $(call cc-disable-warning, unused-but-set-variable)
++
+ KBUILD_CFLAGS += $(call cc-disable-warning, unused-const-variable)
+ ifdef CONFIG_FRAME_POINTER
+ KBUILD_CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls
+diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
+index fd94e27ba4fa3..c1f8047686219 100644
+--- a/arch/arm/boot/compressed/Makefile
++++ b/arch/arm/boot/compressed/Makefile
+@@ -118,8 +118,8 @@ asflags-y := -DZIMAGE
+
+ # Supply kernel BSS size to the decompressor via a linker symbol.
+ KBSS_SZ = $(shell echo $$(($$($(NM) $(obj)/../../../../vmlinux | \
+- sed -n -e 's/^\([^ ]*\) [AB] __bss_start$$/-0x\1/p' \
+- -e 's/^\([^ ]*\) [AB] __bss_stop$$/+0x\1/p') )) )
++ sed -n -e 's/^\([^ ]*\) [ABD] __bss_start$$/-0x\1/p' \
++ -e 's/^\([^ ]*\) [ABD] __bss_stop$$/+0x\1/p') )) )
+ LDFLAGS_vmlinux = --defsym _kernel_bss_size=$(KBSS_SZ)
+ # Supply ZRELADDR to the decompressor via a linker symbol.
+ ifneq ($(CONFIG_AUTO_ZRELADDR),y)
+diff --git a/arch/arm/boot/dts/at91-sam9x60ek.dts b/arch/arm/boot/dts/at91-sam9x60ek.dts
+index 775ceb3acb6c0..edca66c232c15 100644
+--- a/arch/arm/boot/dts/at91-sam9x60ek.dts
++++ b/arch/arm/boot/dts/at91-sam9x60ek.dts
+@@ -8,6 +8,7 @@
+ */
+ /dts-v1/;
+ #include "sam9x60.dtsi"
++#include <dt-bindings/input/input.h>
+
+ / {
+ model = "Microchip SAM9X60-EK";
+@@ -84,7 +85,7 @@
+ sw1 {
+ label = "SW1";
+ gpios = <&pioD 18 GPIO_ACTIVE_LOW>;
+- linux,code=<0x104>;
++ linux,code=<KEY_PROG1>;
+ wakeup-source;
+ };
+ };
+diff --git a/arch/arm/boot/dts/at91-sama5d27_som1_ek.dts b/arch/arm/boot/dts/at91-sama5d27_som1_ek.dts
+index 84e1180f3e89d..a9e6fee55a2a8 100644
+--- a/arch/arm/boot/dts/at91-sama5d27_som1_ek.dts
++++ b/arch/arm/boot/dts/at91-sama5d27_som1_ek.dts
+@@ -11,6 +11,7 @@
+ #include "at91-sama5d27_som1.dtsi"
+ #include <dt-bindings/mfd/atmel-flexcom.h>
+ #include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/input/input.h>
+
+ / {
+ model = "Atmel SAMA5D27 SOM1 EK";
+@@ -466,7 +467,7 @@
+ pb4 {
+ label = "USER";
+ gpios = <&pioA PIN_PA29 GPIO_ACTIVE_LOW>;
+- linux,code = <0x104>;
++ linux,code = <KEY_PROG1>;
+ wakeup-source;
+ };
+ };
+diff --git a/arch/arm/boot/dts/at91-sama5d27_wlsom1_ek.dts b/arch/arm/boot/dts/at91-sama5d27_wlsom1_ek.dts
+index 180a08765cb85..ff83967fd0082 100644
+--- a/arch/arm/boot/dts/at91-sama5d27_wlsom1_ek.dts
++++ b/arch/arm/boot/dts/at91-sama5d27_wlsom1_ek.dts
+@@ -8,6 +8,7 @@
+ */
+ /dts-v1/;
+ #include "at91-sama5d27_wlsom1.dtsi"
++#include <dt-bindings/input/input.h>
+
+ / {
+ model = "Microchip SAMA5D27 WLSOM1 EK";
+@@ -35,7 +36,7 @@
+ sw4 {
+ label = "USER BUTTON";
+ gpios = <&pioA PIN_PB2 GPIO_ACTIVE_LOW>;
+- linux,code = <0x104>;
++ linux,code = <KEY_PROG1>;
+ wakeup-source;
+ };
+ };
+diff --git a/arch/arm/boot/dts/at91-sama5d2_icp.dts b/arch/arm/boot/dts/at91-sama5d2_icp.dts
+index 46722a163184e..bd64721fa23ca 100644
+--- a/arch/arm/boot/dts/at91-sama5d2_icp.dts
++++ b/arch/arm/boot/dts/at91-sama5d2_icp.dts
+@@ -12,6 +12,7 @@
+ #include "sama5d2.dtsi"
+ #include "sama5d2-pinfunc.h"
+ #include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/input/input.h>
+ #include <dt-bindings/mfd/atmel-flexcom.h>
+
+ / {
+@@ -51,7 +52,7 @@
+ sw4 {
+ label = "USER_PB1";
+ gpios = <&pioA PIN_PD0 GPIO_ACTIVE_LOW>;
+- linux,code = <0x104>;
++ linux,code = <KEY_PROG1>;
+ wakeup-source;
+ };
+ };
+diff --git a/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts b/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts
+index 8de57d164acd3..dfd150eb0fd86 100644
+--- a/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts
++++ b/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts
+@@ -11,6 +11,7 @@
+ #include "sama5d2-pinfunc.h"
+ #include <dt-bindings/mfd/atmel-flexcom.h>
+ #include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/input/input.h>
+ #include <dt-bindings/pinctrl/at91.h>
+
+ / {
+@@ -402,7 +403,7 @@
+ bp1 {
+ label = "PB_USER";
+ gpios = <&pioA PIN_PA10 GPIO_ACTIVE_LOW>;
+- linux,code = <0x104>;
++ linux,code = <KEY_PROG1>;
+ wakeup-source;
+ };
+ };
+diff --git a/arch/arm/boot/dts/at91-sama5d2_xplained.dts b/arch/arm/boot/dts/at91-sama5d2_xplained.dts
+index 4e7cf21f124c0..509c732a0d8b4 100644
+--- a/arch/arm/boot/dts/at91-sama5d2_xplained.dts
++++ b/arch/arm/boot/dts/at91-sama5d2_xplained.dts
+@@ -10,6 +10,7 @@
+ #include "sama5d2-pinfunc.h"
+ #include <dt-bindings/mfd/atmel-flexcom.h>
+ #include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/input/input.h>
+ #include <dt-bindings/regulator/active-semi,8945a-regulator.h>
+
+ / {
+@@ -712,7 +713,7 @@
+ bp1 {
+ label = "PB_USER";
+ gpios = <&pioA PIN_PB9 GPIO_ACTIVE_LOW>;
+- linux,code = <0x104>;
++ linux,code = <KEY_PROG1>;
+ wakeup-source;
+ };
+ };
+diff --git a/arch/arm/boot/dts/at91-sama5d3_xplained.dts b/arch/arm/boot/dts/at91-sama5d3_xplained.dts
+index 5179258f92470..9c55a921263bd 100644
+--- a/arch/arm/boot/dts/at91-sama5d3_xplained.dts
++++ b/arch/arm/boot/dts/at91-sama5d3_xplained.dts
+@@ -7,6 +7,7 @@
+ */
+ /dts-v1/;
+ #include "sama5d36.dtsi"
++#include <dt-bindings/input/input.h>
+
+ / {
+ model = "SAMA5D3 Xplained";
+@@ -354,7 +355,7 @@
+ bp3 {
+ label = "PB_USER";
+ gpios = <&pioE 29 GPIO_ACTIVE_LOW>;
+- linux,code = <0x104>;
++ linux,code = <KEY_PROG1>;
+ wakeup-source;
+ };
+ };
+diff --git a/arch/arm/boot/dts/at91sam9260ek.dts b/arch/arm/boot/dts/at91sam9260ek.dts
+index d3446e42b5983..ce96345d28a39 100644
+--- a/arch/arm/boot/dts/at91sam9260ek.dts
++++ b/arch/arm/boot/dts/at91sam9260ek.dts
+@@ -7,6 +7,7 @@
+ */
+ /dts-v1/;
+ #include "at91sam9260.dtsi"
++#include <dt-bindings/input/input.h>
+
+ / {
+ model = "Atmel at91sam9260ek";
+@@ -156,7 +157,7 @@
+ btn4 {
+ label = "Button 4";
+ gpios = <&pioA 31 GPIO_ACTIVE_LOW>;
+- linux,code = <0x104>;
++ linux,code = <KEY_PROG1>;
+ wakeup-source;
+ };
+ };
+diff --git a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
+index 6e6e672c0b86d..87bb39060e8be 100644
+--- a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
++++ b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
+@@ -5,6 +5,7 @@
+ * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ */
+ #include "at91sam9g20.dtsi"
++#include <dt-bindings/input/input.h>
+
+ / {
+
+@@ -234,7 +235,7 @@
+ btn4 {
+ label = "Button 4";
+ gpios = <&pioA 31 GPIO_ACTIVE_LOW>;
+- linux,code = <0x104>;
++ linux,code = <KEY_PROG1>;
+ wakeup-source;
+ };
+ };
+diff --git a/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts b/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts
+index 6a96655d86260..8ed403767540e 100644
+--- a/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts
++++ b/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts
+@@ -21,8 +21,8 @@
+
+ memory@0 {
+ device_type = "memory";
+- reg = <0x00000000 0x08000000
+- 0x88000000 0x08000000>;
++ reg = <0x00000000 0x08000000>,
++ <0x88000000 0x08000000>;
+ };
+
+ leds {
+diff --git a/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts b/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts
+index 3b0029e61b4c6..667b118ba4ee1 100644
+--- a/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts
++++ b/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts
+@@ -21,8 +21,8 @@
+
+ memory@0 {
+ device_type = "memory";
+- reg = <0x00000000 0x08000000
+- 0x88000000 0x08000000>;
++ reg = <0x00000000 0x08000000>,
++ <0x88000000 0x08000000>;
+ };
+
+ leds {
+diff --git a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
+index 90f57bad6b243..ff31ce45831a7 100644
+--- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
++++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
+@@ -21,8 +21,8 @@
+
+ memory@0 {
+ device_type = "memory";
+- reg = <0x00000000 0x08000000
+- 0x88000000 0x18000000>;
++ reg = <0x00000000 0x08000000>,
++ <0x88000000 0x18000000>;
+ };
+
+ spi {
+diff --git a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
+index fed75e6ab58ca..61c7b137607e5 100644
+--- a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
++++ b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
+@@ -22,8 +22,8 @@
+
+ memory {
+ device_type = "memory";
+- reg = <0x00000000 0x08000000
+- 0x88000000 0x08000000>;
++ reg = <0x00000000 0x08000000>,
++ <0x88000000 0x08000000>;
+ };
+
+ leds {
+diff --git a/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts b/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
+index 79542e18915c5..4c60eda296d97 100644
+--- a/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
++++ b/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
+@@ -21,8 +21,8 @@
+
+ memory@0 {
+ device_type = "memory";
+- reg = <0x00000000 0x08000000
+- 0x88000000 0x08000000>;
++ reg = <0x00000000 0x08000000>,
++ <0x88000000 0x08000000>;
+ };
+
+ leds {
+diff --git a/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts b/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
+index 51c64f0b25603..9ca6d1b2590d4 100644
+--- a/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
++++ b/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
+@@ -21,8 +21,8 @@
+
+ memory@0 {
+ device_type = "memory";
+- reg = <0x00000000 0x08000000
+- 0x88000000 0x08000000>;
++ reg = <0x00000000 0x08000000>,
++ <0x88000000 0x08000000>;
+ };
+
+ leds {
+diff --git a/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts b/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
+index c29950b43a953..0e273c598732f 100644
+--- a/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
++++ b/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
+@@ -21,8 +21,8 @@
+
+ memory@0 {
+ device_type = "memory";
+- reg = <0x00000000 0x08000000
+- 0x88000000 0x08000000>;
++ reg = <0x00000000 0x08000000>,
++ <0x88000000 0x08000000>;
+ };
+
+ leds {
+diff --git a/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts b/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
+index 2f2d2b0a6893c..d857751ec5076 100644
+--- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
++++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
+@@ -21,8 +21,8 @@
+
+ memory@0 {
+ device_type = "memory";
+- reg = <0x00000000 0x08000000
+- 0x88000000 0x08000000>;
++ reg = <0x00000000 0x08000000>,
++ <0x88000000 0x08000000>;
+ };
+
+ spi {
+diff --git a/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts b/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
+index 0e349e39f6081..8b1a05a0f1a11 100644
+--- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
++++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
+@@ -21,8 +21,8 @@
+
+ memory@0 {
+ device_type = "memory";
+- reg = <0x00000000 0x08000000
+- 0x88000000 0x08000000>;
++ reg = <0x00000000 0x08000000>,
++ <0x88000000 0x08000000>;
+ };
+
+ spi {
+diff --git a/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts b/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
+index 8f1e565c3db45..6c6bb7b17d27a 100644
+--- a/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
++++ b/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
+@@ -21,8 +21,8 @@
+
+ memory {
+ device_type = "memory";
+- reg = <0x00000000 0x08000000
+- 0x88000000 0x08000000>;
++ reg = <0x00000000 0x08000000>,
++ <0x88000000 0x08000000>;
+ };
+
+ leds {
+diff --git a/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts b/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
+index ce888b1835d1f..d29e7f80ea6aa 100644
+--- a/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
++++ b/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
+@@ -21,8 +21,8 @@
+
+ memory {
+ device_type = "memory";
+- reg = <0x00000000 0x08000000
+- 0x88000000 0x18000000>;
++ reg = <0x00000000 0x08000000>,
++ <0x88000000 0x18000000>;
+ };
+
+ leds {
+diff --git a/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts b/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts
+index ed8619b54d692..38fbefdf2e4e4 100644
+--- a/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts
++++ b/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts
+@@ -18,8 +18,8 @@
+
+ memory {
+ device_type = "memory";
+- reg = <0x00000000 0x08000000
+- 0x88000000 0x08000000>;
++ reg = <0x00000000 0x08000000>,
++ <0x88000000 0x08000000>;
+ };
+
+ gpio-keys {
+diff --git a/arch/arm/boot/dts/bcm4709-netgear-r7000.dts b/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
+index 1f87993eae1d1..7989a53597d4f 100644
+--- a/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
++++ b/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
+@@ -21,8 +21,8 @@
+
+ memory {
+ device_type = "memory";
+- reg = <0x00000000 0x08000000
+- 0x88000000 0x08000000>;
++ reg = <0x00000000 0x08000000>,
++ <0x88000000 0x08000000>;
+ };
+
+ leds {
+diff --git a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
+index 6c6199a53d091..87b655be674c5 100644
+--- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
++++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
+@@ -32,8 +32,8 @@
+
+ memory {
+ device_type = "memory";
+- reg = <0x00000000 0x08000000
+- 0x88000000 0x08000000>;
++ reg = <0x00000000 0x08000000>,
++ <0x88000000 0x08000000>;
+ };
+
+ leds {
+diff --git a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
+index 911c65fbf2510..e635a15041dd8 100644
+--- a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
++++ b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
+@@ -21,8 +21,8 @@
+
+ memory@0 {
+ device_type = "memory";
+- reg = <0x00000000 0x08000000
+- 0x88000000 0x08000000>;
++ reg = <0x00000000 0x08000000>,
++ <0x88000000 0x08000000>;
+ };
+
+ nand: nand@18028000 {
+diff --git a/arch/arm/boot/dts/bcm47094-linksys-panamera.dts b/arch/arm/boot/dts/bcm47094-linksys-panamera.dts
+index 3725f2b0d60bd..4b24b25389b5f 100644
+--- a/arch/arm/boot/dts/bcm47094-linksys-panamera.dts
++++ b/arch/arm/boot/dts/bcm47094-linksys-panamera.dts
+@@ -18,8 +18,8 @@
+
+ memory@0 {
+ device_type = "memory";
+- reg = <0x00000000 0x08000000
+- 0x88000000 0x08000000>;
++ reg = <0x00000000 0x08000000>,
++ <0x88000000 0x08000000>;
+ };
+
+ gpio-keys {
+diff --git a/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts b/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
+index 50f7cd08cfbbc..a6dc99955e191 100644
+--- a/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
++++ b/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
+@@ -18,8 +18,8 @@
+
+ memory@0 {
+ device_type = "memory";
+- reg = <0x00000000 0x08000000
+- 0x88000000 0x18000000>;
++ reg = <0x00000000 0x08000000>,
++ <0x88000000 0x18000000>;
+ };
+
+ leds {
+diff --git a/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts b/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
+index bcc420f85b566..ff98837bc0db0 100644
+--- a/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
++++ b/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
+@@ -18,8 +18,8 @@
+
+ memory@0 {
+ device_type = "memory";
+- reg = <0x00000000 0x08000000
+- 0x88000000 0x18000000>;
++ reg = <0x00000000 0x08000000>,
++ <0x88000000 0x18000000>;
+ };
+
+ leds {
+diff --git a/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts b/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
+index 4f8d777ae18de..452b8d0ab180e 100644
+--- a/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
++++ b/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
+@@ -18,8 +18,8 @@
+
+ memory {
+ device_type = "memory";
+- reg = <0x00000000 0x08000000
+- 0x88000000 0x18000000>;
++ reg = <0x00000000 0x08000000>,
++ <0x88000000 0x18000000>;
+ };
+
+ leds {
+diff --git a/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts b/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
+index e17e9a17fb008..b76bfe6efcd4a 100644
+--- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
++++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
+@@ -18,8 +18,8 @@
+
+ memory@0 {
+ device_type = "memory";
+- reg = <0x00000000 0x08000000
+- 0x88000000 0x08000000>;
++ reg = <0x00000000 0x08000000>,
++ <0x88000000 0x08000000>;
+ };
+
+ leds {
+diff --git a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
+index 60cc87ecc7ece..32d5a50578ec1 100644
+--- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
++++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
+@@ -18,8 +18,8 @@
+
+ memory@0 {
+ device_type = "memory";
+- reg = <0x00000000 0x08000000
+- 0x88000000 0x18000000>;
++ reg = <0x00000000 0x08000000>,
++ <0x88000000 0x18000000>;
+ };
+
+ leds {
+diff --git a/arch/arm/boot/dts/bcm47094-netgear-r8500.dts b/arch/arm/boot/dts/bcm47094-netgear-r8500.dts
+index f42a1703f4ab1..42097a4c2659f 100644
+--- a/arch/arm/boot/dts/bcm47094-netgear-r8500.dts
++++ b/arch/arm/boot/dts/bcm47094-netgear-r8500.dts
+@@ -18,8 +18,8 @@
+
+ memory@0 {
+ device_type = "memory";
+- reg = <0x00000000 0x08000000
+- 0x88000000 0x18000000>;
++ reg = <0x00000000 0x08000000>,
++ <0x88000000 0x18000000>;
+ };
+
+ leds {
+diff --git a/arch/arm/boot/dts/bcm47094-phicomm-k3.dts b/arch/arm/boot/dts/bcm47094-phicomm-k3.dts
+index ac3a4483dcb3f..a2566ad4619c4 100644
+--- a/arch/arm/boot/dts/bcm47094-phicomm-k3.dts
++++ b/arch/arm/boot/dts/bcm47094-phicomm-k3.dts
+@@ -15,8 +15,8 @@
+
+ memory@0 {
+ device_type = "memory";
+- reg = <0x00000000 0x08000000
+- 0x88000000 0x18000000>;
++ reg = <0x00000000 0x08000000>,
++ <0x88000000 0x18000000>;
+ };
+
+ gpio-keys {
+diff --git a/arch/arm/boot/dts/ste-href-tvk1281618-r3.dtsi b/arch/arm/boot/dts/ste-href-tvk1281618-r3.dtsi
+index cb3677f0a1cbb..b580397ede833 100644
+--- a/arch/arm/boot/dts/ste-href-tvk1281618-r3.dtsi
++++ b/arch/arm/boot/dts/ste-href-tvk1281618-r3.dtsi
+@@ -8,37 +8,43 @@
+ / {
+ soc {
+ i2c@80128000 {
+- /* Marked:
+- * 129
+- * M35
+- * L3GD20
+- */
+- l3gd20@6a {
+- /* Gyroscope */
+- compatible = "st,l3gd20";
+- status = "disabled";
++ accelerometer@19 {
++ compatible = "st,lsm303dlhc-accel";
+ st,drdy-int-pin = <1>;
+- drive-open-drain;
+- reg = <0x6a>; // 0x6a or 0x6b
++ reg = <0x19>;
+ vdd-supply = <&ab8500_ldo_aux1_reg>;
+ vddio-supply = <&db8500_vsmps2_reg>;
++ interrupt-parent = <&gpio2>;
++ interrupts = <18 IRQ_TYPE_EDGE_RISING>,
++ <19 IRQ_TYPE_EDGE_RISING>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&accel_tvk_mode>;
+ };
+- /*
+- * Marked:
+- * 2122
+- * C3H
+- * DQEEE
+- * LIS3DH?
+- */
+- lis3dh@18 {
+- /* Accelerometer */
+- compatible = "st,lis3dh-accel";
++ magnetometer@1e {
++ compatible = "st,lsm303dlm-magn";
+ st,drdy-int-pin = <1>;
+- reg = <0x18>;
++ reg = <0x1e>;
+ vdd-supply = <&ab8500_ldo_aux1_reg>;
+ vddio-supply = <&db8500_vsmps2_reg>;
++ // This interrupt is not properly working with the driver
++ // interrupt-parent = <&gpio1>;
++ // interrupts = <0 IRQ_TYPE_EDGE_RISING>;
+ pinctrl-names = "default";
+- pinctrl-0 = <&accel_tvk_mode>;
++ pinctrl-0 = <&magn_tvk_mode>;
++ };
++ gyroscope@68 {
++ /* Gyroscope */
++ compatible = "st,l3g4200d-gyro";
++ reg = <0x68>;
++ vdd-supply = <&ab8500_ldo_aux1_reg>;
++ vddio-supply = <&db8500_vsmps2_reg>;
++ };
++ pressure@5c {
++ /* Barometer/pressure sensor */
++ compatible = "st,lps001wp-press";
++ reg = <0x5c>;
++ vdd-supply = <&ab8500_ldo_aux1_reg>;
++ vddio-supply = <&db8500_vsmps2_reg>;
+ };
+ };
+
+@@ -54,5 +60,26 @@
+ };
+ };
+ };
++
++ pinctrl {
++ accelerometer {
++ accel_tvk_mode: accel_tvk {
++ /* Accelerometer interrupt lines 1 & 2 */
++ tvk_cfg {
++ pins = "GPIO82_C1", "GPIO83_D3";
++ ste,config = <&gpio_in_pd>;
++ };
++ };
++ };
++ magnetometer {
++ magn_tvk_mode: magn_tvk {
++ /* GPIO 32 used for DRDY, pull this down */
++ tvk_cfg {
++ pins = "GPIO32_V2";
++ ste,config = <&gpio_in_pd>;
++ };
++ };
++ };
++ };
+ };
+ };
+diff --git a/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts b/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts
+index d3b99535d755e..f9c0f6884cc1e 100644
+--- a/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts
++++ b/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts
+@@ -448,7 +448,7 @@
+
+ reset-gpios = <&gpio TEGRA_GPIO(Q, 7) GPIO_ACTIVE_LOW>;
+
+- avdd-supply = <&vdd_3v3_sys>;
++ vdda-supply = <&vdd_3v3_sys>;
+ vdd-supply = <&vdd_3v3_sys>;
+ };
+
+diff --git a/arch/arm/crypto/curve25519-core.S b/arch/arm/crypto/curve25519-core.S
+index be18af52e7dc9..b697fa5d059a2 100644
+--- a/arch/arm/crypto/curve25519-core.S
++++ b/arch/arm/crypto/curve25519-core.S
+@@ -10,8 +10,8 @@
+ #include <linux/linkage.h>
+
+ .text
+-.fpu neon
+ .arch armv7-a
++.fpu neon
+ .align 4
+
+ ENTRY(curve25519_neon)
+diff --git a/arch/arm64/boot/dts/freescale/imx8mq-librem5-r3.dts b/arch/arm64/boot/dts/freescale/imx8mq-librem5-r3.dts
+index 0d38327043f88..cd3c3edd48fa3 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mq-librem5-r3.dts
++++ b/arch/arm64/boot/dts/freescale/imx8mq-librem5-r3.dts
+@@ -28,6 +28,10 @@
+ ti,termination-current = <144000>; /* uA */
+ };
+
++&buck3_reg {
++ regulator-always-on;
++};
++
+ &proximity {
+ proximity-near-level = <25>;
+ };
+diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
+index 7a2df148c6a31..456dcd4a7793f 100644
+--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
++++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
+@@ -156,7 +156,8 @@
+ };
+
+ nb_periph_clk: nb-periph-clk@13000 {
+- compatible = "marvell,armada-3700-periph-clock-nb";
++ compatible = "marvell,armada-3700-periph-clock-nb",
++ "syscon";
+ reg = <0x13000 0x100>;
+ clocks = <&tbg 0>, <&tbg 1>, <&tbg 2>,
+ <&tbg 3>, <&xtalclk>;
+diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+index 7fa870e4386a3..ecb37a7e68705 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+@@ -1235,7 +1235,7 @@
+ <&mmsys CLK_MM_DSI1_DIGITAL>,
+ <&mipi_tx1>;
+ clock-names = "engine", "digital", "hs";
+- phy = <&mipi_tx1>;
++ phys = <&mipi_tx1>;
+ phy-names = "dphy";
+ status = "disabled";
+ };
+diff --git a/arch/arm64/kernel/vdso/vdso.lds.S b/arch/arm64/kernel/vdso/vdso.lds.S
+index 61dbb4c838ef7..a5e61e09ea927 100644
+--- a/arch/arm64/kernel/vdso/vdso.lds.S
++++ b/arch/arm64/kernel/vdso/vdso.lds.S
+@@ -31,6 +31,13 @@ SECTIONS
+ .gnu.version_d : { *(.gnu.version_d) }
+ .gnu.version_r : { *(.gnu.version_r) }
+
++ /*
++ * Discard .note.gnu.property sections which are unused and have
++ * different alignment requirement from vDSO note sections.
++ */
++ /DISCARD/ : {
++ *(.note.GNU-stack .note.gnu.property)
++ }
+ .note : { *(.note.*) } :text :note
+
+ . = ALIGN(16);
+@@ -48,7 +55,6 @@ SECTIONS
+ PROVIDE(end = .);
+
+ /DISCARD/ : {
+- *(.note.GNU-stack)
+ *(.data .data.* .gnu.linkonce.d.* .sdata*)
+ *(.bss .sbss .dynbss .dynsbss)
+ *(.eh_frame .eh_frame_hdr)
+diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h
+index 652ce85f9410a..4bc45d3ed8b0e 100644
+--- a/arch/powerpc/include/asm/mmu_context.h
++++ b/arch/powerpc/include/asm/mmu_context.h
+@@ -263,7 +263,7 @@ extern void arch_exit_mmap(struct mm_struct *mm);
+ static inline void arch_unmap(struct mm_struct *mm,
+ unsigned long start, unsigned long end)
+ {
+- unsigned long vdso_base = (unsigned long)mm->context.vdso - PAGE_SIZE;
++ unsigned long vdso_base = (unsigned long)mm->context.vdso;
+
+ if (start <= vdso_base && vdso_base < end)
+ mm->context.vdso = NULL;
+diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
+index da103e92c1126..37d0b8c76a59d 100644
+--- a/arch/powerpc/include/asm/reg.h
++++ b/arch/powerpc/include/asm/reg.h
+@@ -441,6 +441,7 @@
+ #define LPCR_VRMA_LP1 ASM_CONST(0x0000800000000000)
+ #define LPCR_RMLS 0x1C000000 /* Implementation dependent RMO limit sel */
+ #define LPCR_RMLS_SH 26
++#define LPCR_HAIL ASM_CONST(0x0000000004000000) /* HV AIL (ISAv3.1) */
+ #define LPCR_ILE ASM_CONST(0x0000000002000000) /* !HV irqs set MSR:LE */
+ #define LPCR_AIL ASM_CONST(0x0000000001800000) /* Alternate interrupt location */
+ #define LPCR_AIL_0 ASM_CONST(0x0000000000000000) /* MMU off exception offset 0x0 */
+diff --git a/arch/powerpc/include/uapi/asm/errno.h b/arch/powerpc/include/uapi/asm/errno.h
+index cc79856896a19..4ba87de32be00 100644
+--- a/arch/powerpc/include/uapi/asm/errno.h
++++ b/arch/powerpc/include/uapi/asm/errno.h
+@@ -2,6 +2,7 @@
+ #ifndef _ASM_POWERPC_ERRNO_H
+ #define _ASM_POWERPC_ERRNO_H
+
++#undef EDEADLOCK
+ #include <asm-generic/errno.h>
+
+ #undef EDEADLOCK
+diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c
+index cd60bc1c87011..7040e430a1249 100644
+--- a/arch/powerpc/kernel/eeh.c
++++ b/arch/powerpc/kernel/eeh.c
+@@ -362,14 +362,11 @@ static inline unsigned long eeh_token_to_phys(unsigned long token)
+ pa = pte_pfn(*ptep);
+
+ /* On radix we can do hugepage mappings for io, so handle that */
+- if (hugepage_shift) {
+- pa <<= hugepage_shift;
+- pa |= token & ((1ul << hugepage_shift) - 1);
+- } else {
+- pa <<= PAGE_SHIFT;
+- pa |= token & (PAGE_SIZE - 1);
+- }
++ if (!hugepage_shift)
++ hugepage_shift = PAGE_SHIFT;
+
++ pa <<= PAGE_SHIFT;
++ pa |= token & ((1ul << hugepage_shift) - 1);
+ return pa;
+ }
+
+diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
+index 560ed8b975e77..830fee91b2d99 100644
+--- a/arch/powerpc/kernel/setup_64.c
++++ b/arch/powerpc/kernel/setup_64.c
+@@ -232,10 +232,23 @@ static void cpu_ready_for_interrupts(void)
+ * If we are not in hypervisor mode the job is done once for
+ * the whole partition in configure_exceptions().
+ */
+- if (cpu_has_feature(CPU_FTR_HVMODE) &&
+- cpu_has_feature(CPU_FTR_ARCH_207S)) {
++ if (cpu_has_feature(CPU_FTR_HVMODE)) {
+ unsigned long lpcr = mfspr(SPRN_LPCR);
+- mtspr(SPRN_LPCR, lpcr | LPCR_AIL_3);
++ unsigned long new_lpcr = lpcr;
++
++ if (cpu_has_feature(CPU_FTR_ARCH_31)) {
++ /* P10 DD1 does not have HAIL */
++ if (pvr_version_is(PVR_POWER10) &&
++ (mfspr(SPRN_PVR) & 0xf00) == 0x100)
++ new_lpcr |= LPCR_AIL_3;
++ else
++ new_lpcr |= LPCR_HAIL;
++ } else if (cpu_has_feature(CPU_FTR_ARCH_207S)) {
++ new_lpcr |= LPCR_AIL_3;
++ }
++
++ if (new_lpcr != lpcr)
++ mtspr(SPRN_LPCR, new_lpcr);
+ }
+
+ /*
+diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
+index e839a906fdf23..b14907209822e 100644
+--- a/arch/powerpc/kernel/vdso.c
++++ b/arch/powerpc/kernel/vdso.c
+@@ -55,10 +55,10 @@ static int vdso_mremap(const struct vm_special_mapping *sm, struct vm_area_struc
+ {
+ unsigned long new_size = new_vma->vm_end - new_vma->vm_start;
+
+- if (new_size != text_size + PAGE_SIZE)
++ if (new_size != text_size)
+ return -EINVAL;
+
+- current->mm->context.vdso = (void __user *)new_vma->vm_start + PAGE_SIZE;
++ current->mm->context.vdso = (void __user *)new_vma->vm_start;
+
+ return 0;
+ }
+@@ -73,6 +73,10 @@ static int vdso64_mremap(const struct vm_special_mapping *sm, struct vm_area_str
+ return vdso_mremap(sm, new_vma, &vdso64_end - &vdso64_start);
+ }
+
++static struct vm_special_mapping vvar_spec __ro_after_init = {
++ .name = "[vvar]",
++};
++
+ static struct vm_special_mapping vdso32_spec __ro_after_init = {
+ .name = "[vdso]",
+ .mremap = vdso32_mremap,
+@@ -89,11 +93,11 @@ static struct vm_special_mapping vdso64_spec __ro_after_init = {
+ */
+ static int __arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+ {
+- struct mm_struct *mm = current->mm;
++ unsigned long vdso_size, vdso_base, mappings_size;
+ struct vm_special_mapping *vdso_spec;
++ unsigned long vvar_size = PAGE_SIZE;
++ struct mm_struct *mm = current->mm;
+ struct vm_area_struct *vma;
+- unsigned long vdso_size;
+- unsigned long vdso_base;
+
+ if (is_32bit_task()) {
+ vdso_spec = &vdso32_spec;
+@@ -110,8 +114,8 @@ static int __arch_setup_additional_pages(struct linux_binprm *bprm, int uses_int
+ vdso_base = 0;
+ }
+
+- /* Add a page to the vdso size for the data page */
+- vdso_size += PAGE_SIZE;
++ mappings_size = vdso_size + vvar_size;
++ mappings_size += (VDSO_ALIGNMENT - 1) & PAGE_MASK;
+
+ /*
+ * pick a base address for the vDSO in process space. We try to put it
+@@ -119,9 +123,7 @@ static int __arch_setup_additional_pages(struct linux_binprm *bprm, int uses_int
+ * and end up putting it elsewhere.
+ * Add enough to the size so that the result can be aligned.
+ */
+- vdso_base = get_unmapped_area(NULL, vdso_base,
+- vdso_size + ((VDSO_ALIGNMENT - 1) & PAGE_MASK),
+- 0, 0);
++ vdso_base = get_unmapped_area(NULL, vdso_base, mappings_size, 0, 0);
+ if (IS_ERR_VALUE(vdso_base))
+ return vdso_base;
+
+@@ -133,7 +135,13 @@ static int __arch_setup_additional_pages(struct linux_binprm *bprm, int uses_int
+ * install_special_mapping or the perf counter mmap tracking code
+ * will fail to recognise it as a vDSO.
+ */
+- mm->context.vdso = (void __user *)vdso_base + PAGE_SIZE;
++ mm->context.vdso = (void __user *)vdso_base + vvar_size;
++
++ vma = _install_special_mapping(mm, vdso_base, vvar_size,
++ VM_READ | VM_MAYREAD | VM_IO |
++ VM_DONTDUMP | VM_PFNMAP, &vvar_spec);
++ if (IS_ERR(vma))
++ return PTR_ERR(vma);
+
+ /*
+ * our vma flags don't have VM_WRITE so by default, the process isn't
+@@ -145,9 +153,12 @@ static int __arch_setup_additional_pages(struct linux_binprm *bprm, int uses_int
+ * It's fine to use that for setting breakpoints in the vDSO code
+ * pages though.
+ */
+- vma = _install_special_mapping(mm, vdso_base, vdso_size,
++ vma = _install_special_mapping(mm, vdso_base + vvar_size, vdso_size,
+ VM_READ | VM_EXEC | VM_MAYREAD |
+ VM_MAYWRITE | VM_MAYEXEC, vdso_spec);
++ if (IS_ERR(vma))
++ do_munmap(mm, vdso_base, vvar_size, NULL);
++
+ return PTR_ERR_OR_ZERO(vma);
+ }
+
+@@ -249,11 +260,22 @@ static struct page ** __init vdso_setup_pages(void *start, void *end)
+ if (!pagelist)
+ panic("%s: Cannot allocate page list for VDSO", __func__);
+
+- pagelist[0] = virt_to_page(vdso_data);
+-
+ for (i = 0; i < pages; i++)
+- pagelist[i + 1] = virt_to_page(start + i * PAGE_SIZE);
++ pagelist[i] = virt_to_page(start + i * PAGE_SIZE);
++
++ return pagelist;
++}
++
++static struct page ** __init vvar_setup_pages(void)
++{
++ struct page **pagelist;
+
++ /* .pages is NULL-terminated */
++ pagelist = kcalloc(2, sizeof(struct page *), GFP_KERNEL);
++ if (!pagelist)
++ panic("%s: Cannot allocate page list for VVAR", __func__);
++
++ pagelist[0] = virt_to_page(vdso_data);
+ return pagelist;
+ }
+
+@@ -295,6 +317,8 @@ static int __init vdso_init(void)
+ if (IS_ENABLED(CONFIG_PPC64))
+ vdso64_spec.pages = vdso_setup_pages(&vdso64_start, &vdso64_end);
+
++ vvar_spec.pages = vvar_setup_pages();
++
+ smp_wmb();
+
+ return 0;
+diff --git a/arch/powerpc/kexec/file_load_64.c b/arch/powerpc/kexec/file_load_64.c
+index 02b9e4d0dc40b..a8a7cb71086b3 100644
+--- a/arch/powerpc/kexec/file_load_64.c
++++ b/arch/powerpc/kexec/file_load_64.c
+@@ -960,6 +960,93 @@ unsigned int kexec_fdt_totalsize_ppc64(struct kimage *image)
+ return fdt_size;
+ }
+
++/**
++ * add_node_props - Reads node properties from device node structure and add
++ * them to fdt.
++ * @fdt: Flattened device tree of the kernel
++ * @node_offset: offset of the node to add a property at
++ * @dn: device node pointer
++ *
++ * Returns 0 on success, negative errno on error.
++ */
++static int add_node_props(void *fdt, int node_offset, const struct device_node *dn)
++{
++ int ret = 0;
++ struct property *pp;
++
++ if (!dn)
++ return -EINVAL;
++
++ for_each_property_of_node(dn, pp) {
++ ret = fdt_setprop(fdt, node_offset, pp->name, pp->value, pp->length);
++ if (ret < 0) {
++ pr_err("Unable to add %s property: %s\n", pp->name, fdt_strerror(ret));
++ return ret;
++ }
++ }
++ return ret;
++}
++
++/**
++ * update_cpus_node - Update cpus node of flattened device tree using of_root
++ * device node.
++ * @fdt: Flattened device tree of the kernel.
++ *
++ * Returns 0 on success, negative errno on error.
++ */
++static int update_cpus_node(void *fdt)
++{
++ struct device_node *cpus_node, *dn;
++ int cpus_offset, cpus_subnode_offset, ret = 0;
++
++ cpus_offset = fdt_path_offset(fdt, "/cpus");
++ if (cpus_offset < 0 && cpus_offset != -FDT_ERR_NOTFOUND) {
++ pr_err("Malformed device tree: error reading /cpus node: %s\n",
++ fdt_strerror(cpus_offset));
++ return cpus_offset;
++ }
++
++ if (cpus_offset > 0) {
++ ret = fdt_del_node(fdt, cpus_offset);
++ if (ret < 0) {
++ pr_err("Error deleting /cpus node: %s\n", fdt_strerror(ret));
++ return -EINVAL;
++ }
++ }
++
++ /* Add cpus node to fdt */
++ cpus_offset = fdt_add_subnode(fdt, fdt_path_offset(fdt, "/"), "cpus");
++ if (cpus_offset < 0) {
++ pr_err("Error creating /cpus node: %s\n", fdt_strerror(cpus_offset));
++ return -EINVAL;
++ }
++
++ /* Add cpus node properties */
++ cpus_node = of_find_node_by_path("/cpus");
++ ret = add_node_props(fdt, cpus_offset, cpus_node);
++ of_node_put(cpus_node);
++ if (ret < 0)
++ return ret;
++
++ /* Loop through all subnodes of cpus and add them to fdt */
++ for_each_node_by_type(dn, "cpu") {
++ cpus_subnode_offset = fdt_add_subnode(fdt, cpus_offset, dn->full_name);
++ if (cpus_subnode_offset < 0) {
++ pr_err("Unable to add %s subnode: %s\n", dn->full_name,
++ fdt_strerror(cpus_subnode_offset));
++ ret = cpus_subnode_offset;
++ goto out;
++ }
++
++ ret = add_node_props(fdt, cpus_subnode_offset, dn);
++ if (ret < 0)
++ goto out;
++ }
++out:
++ of_node_put(dn);
++ return ret;
++}
++
+ /**
+ * setup_new_fdt_ppc64 - Update the flattend device-tree of the kernel
+ * being loaded.
+@@ -1020,6 +1107,11 @@ int setup_new_fdt_ppc64(const struct kimage *image, void *fdt,
+ }
+ }
+
++ /* Update cpus nodes information to account hotplug CPUs. */
++ ret = update_cpus_node(fdt);
++ if (ret < 0)
++ goto out;
++
+ /* Update memory reserve map */
+ ret = get_reserved_memory_ranges(&rmem);
+ if (ret)
+diff --git a/arch/powerpc/kvm/book3s_64_mmu_host.c b/arch/powerpc/kvm/book3s_64_mmu_host.c
+index e452158a18d77..c3e31fef0be1c 100644
+--- a/arch/powerpc/kvm/book3s_64_mmu_host.c
++++ b/arch/powerpc/kvm/book3s_64_mmu_host.c
+@@ -8,6 +8,7 @@
+ */
+
+ #include <linux/kvm_host.h>
++#include <linux/pkeys.h>
+
+ #include <asm/kvm_ppc.h>
+ #include <asm/kvm_book3s.h>
+@@ -133,6 +134,7 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte,
+ else
+ kvmppc_mmu_flush_icache(pfn);
+
++ rflags |= pte_to_hpte_pkey_bits(0, HPTE_USE_KERNEL_KEY);
+ rflags = (rflags & ~HPTE_R_WIMG) | orig_pte->wimg;
+
+ /*
+diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
+index d4efc182662a8..248f7c9e36fce 100644
+--- a/arch/powerpc/lib/Makefile
++++ b/arch/powerpc/lib/Makefile
+@@ -5,6 +5,9 @@
+
+ ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC)
+
++CFLAGS_code-patching.o += -fno-stack-protector
++CFLAGS_feature-fixups.o += -fno-stack-protector
++
+ CFLAGS_REMOVE_code-patching.o = $(CC_FLAGS_FTRACE)
+ CFLAGS_REMOVE_feature-fixups.o = $(CC_FLAGS_FTRACE)
+
+diff --git a/arch/riscv/kernel/probes/kprobes.c b/arch/riscv/kernel/probes/kprobes.c
+index 7e2c78e2ca6b0..d71f7c49a721a 100644
+--- a/arch/riscv/kernel/probes/kprobes.c
++++ b/arch/riscv/kernel/probes/kprobes.c
+@@ -260,8 +260,10 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, unsigned int trapnr)
+
+ if (kcb->kprobe_status == KPROBE_REENTER)
+ restore_previous_kprobe(kcb);
+- else
++ else {
++ kprobes_restore_local_irqflag(kcb, regs);
+ reset_current_kprobe();
++ }
+
+ break;
+ case KPROBE_HIT_ACTIVE:
+diff --git a/arch/s390/crypto/arch_random.c b/arch/s390/crypto/arch_random.c
+index 7b947728d57ef..56007c763902a 100644
+--- a/arch/s390/crypto/arch_random.c
++++ b/arch/s390/crypto/arch_random.c
+@@ -54,6 +54,10 @@ static DECLARE_DELAYED_WORK(arch_rng_work, arch_rng_refill_buffer);
+
+ bool s390_arch_random_generate(u8 *buf, unsigned int nbytes)
+ {
++ /* max hunk is ARCH_RNG_BUF_SIZE */
++ if (nbytes > ARCH_RNG_BUF_SIZE)
++ return false;
++
+ /* lock rng buffer */
+ if (!spin_trylock(&arch_rng_lock))
+ return false;
+diff --git a/arch/s390/include/asm/qdio.h b/arch/s390/include/asm/qdio.h
+index d9215c7106f0d..8fc52679543d6 100644
+--- a/arch/s390/include/asm/qdio.h
++++ b/arch/s390/include/asm/qdio.h
+@@ -246,21 +246,8 @@ struct slsb {
+ u8 val[QDIO_MAX_BUFFERS_PER_Q];
+ } __attribute__ ((packed, aligned(256)));
+
+-/**
+- * struct qdio_outbuf_state - SBAL related asynchronous operation information
+- * (for communication with upper layer programs)
+- * (only required for use with completion queues)
+- * @user: pointer to upper layer program's state information related to SBAL
+- * (stored in user1 data of QAOB)
+- */
+-struct qdio_outbuf_state {
+- void *user;
+-};
+-
+-#define CHSC_AC1_INITIATE_INPUTQ 0x80
+-
+-
+ /* qdio adapter-characteristics-1 flag */
++#define CHSC_AC1_INITIATE_INPUTQ 0x80
+ #define AC1_SIGA_INPUT_NEEDED 0x40 /* process input queues */
+ #define AC1_SIGA_OUTPUT_NEEDED 0x20 /* process output queues */
+ #define AC1_SIGA_SYNC_NEEDED 0x10 /* ask hypervisor to sync */
+@@ -338,7 +325,6 @@ typedef void qdio_handler_t(struct ccw_device *, unsigned int, int,
+ * @int_parm: interruption parameter
+ * @input_sbal_addr_array: per-queue array, each element points to 128 SBALs
+ * @output_sbal_addr_array: per-queue array, each element points to 128 SBALs
+- * @output_sbal_state_array: no_output_qs * 128 state info (for CQ or NULL)
+ */
+ struct qdio_initialize {
+ unsigned char q_format;
+@@ -357,7 +343,6 @@ struct qdio_initialize {
+ unsigned long int_parm;
+ struct qdio_buffer ***input_sbal_addr_array;
+ struct qdio_buffer ***output_sbal_addr_array;
+- struct qdio_outbuf_state *output_sbal_state_array;
+ };
+
+ #define QDIO_STATE_INACTIVE 0x00000002 /* after qdio_cleanup */
+@@ -378,9 +363,10 @@ extern int qdio_allocate(struct ccw_device *cdev, unsigned int no_input_qs,
+ extern int qdio_establish(struct ccw_device *cdev,
+ struct qdio_initialize *init_data);
+ extern int qdio_activate(struct ccw_device *);
++extern struct qaob *qdio_allocate_aob(void);
+ extern void qdio_release_aob(struct qaob *);
+-extern int do_QDIO(struct ccw_device *, unsigned int, int, unsigned int,
+- unsigned int);
++extern int do_QDIO(struct ccw_device *cdev, unsigned int callflags, int q_nr,
++ unsigned int bufnr, unsigned int count, struct qaob *aob);
+ extern int qdio_start_irq(struct ccw_device *cdev);
+ extern int qdio_stop_irq(struct ccw_device *cdev);
+ extern int qdio_get_next_buffers(struct ccw_device *, int, int *, int *);
+diff --git a/arch/s390/kernel/dis.c b/arch/s390/kernel/dis.c
+index a7eab7be4db05..5412efe328f80 100644
+--- a/arch/s390/kernel/dis.c
++++ b/arch/s390/kernel/dis.c
+@@ -563,7 +563,7 @@ void show_code(struct pt_regs *regs)
+
+ void print_fn_code(unsigned char *code, unsigned long len)
+ {
+- char buffer[64], *ptr;
++ char buffer[128], *ptr;
+ int opsize, i;
+
+ while (len) {
+diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
+index 2792879d398ee..268b7d5c98354 100644
+--- a/arch/x86/Kconfig
++++ b/arch/x86/Kconfig
+@@ -1406,7 +1406,7 @@ config HIGHMEM4G
+
+ config HIGHMEM64G
+ bool "64GB"
+- depends on !M486 && !M586 && !M586TSC && !M586MMX && !MGEODE_LX && !MGEODEGX1 && !MCYRIXIII && !MELAN && !MWINCHIPC6 && !WINCHIP3D && !MK6
++ depends on !M486SX && !M486 && !M586 && !M586TSC && !M586MMX && !MGEODE_LX && !MGEODEGX1 && !MCYRIXIII && !MELAN && !MWINCHIPC6 && !WINCHIP3D && !MK6
+ select X86_PAE
+ help
+ Select this if you have a 32-bit processor and more than 4
+diff --git a/arch/x86/Makefile b/arch/x86/Makefile
+index 9a85eae37b173..78faf9c7e3aed 100644
+--- a/arch/x86/Makefile
++++ b/arch/x86/Makefile
+@@ -33,6 +33,7 @@ REALMODE_CFLAGS += -ffreestanding
+ REALMODE_CFLAGS += -fno-stack-protector
+ REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), -Wno-address-of-packed-member)
+ REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), $(cc_stack_align4))
++REALMODE_CFLAGS += $(CLANG_FLAGS)
+ export REALMODE_CFLAGS
+
+ # BITS is used as extension for files which are available in a 32 bit
+diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
+index e0bc3988c3faa..6e5522aebbbd4 100644
+--- a/arch/x86/boot/compressed/Makefile
++++ b/arch/x86/boot/compressed/Makefile
+@@ -46,6 +46,7 @@ KBUILD_CFLAGS += -D__DISABLE_EXPORTS
+ # Disable relocation relaxation in case the link is not PIE.
+ KBUILD_CFLAGS += $(call as-option,-Wa$(comma)-mrelax-relocations=no)
+ KBUILD_CFLAGS += -include $(srctree)/include/linux/hidden.h
++KBUILD_CFLAGS += $(CLANG_FLAGS)
+
+ # sev-es.c indirectly inludes inat-table.h which is generated during
+ # compilation and stored in $(objtree). Add the directory to the includes so
+diff --git a/arch/x86/boot/compressed/mem_encrypt.S b/arch/x86/boot/compressed/mem_encrypt.S
+index aa561795efd16..a6dea4e8a082f 100644
+--- a/arch/x86/boot/compressed/mem_encrypt.S
++++ b/arch/x86/boot/compressed/mem_encrypt.S
+@@ -23,12 +23,6 @@ SYM_FUNC_START(get_sev_encryption_bit)
+ push %ecx
+ push %edx
+
+- /* Check if running under a hypervisor */
+- movl $1, %eax
+- cpuid
+- bt $31, %ecx /* Check the hypervisor bit */
+- jnc .Lno_sev
+-
+ movl $0x80000000, %eax /* CPUID to check the highest leaf */
+ cpuid
+ cmpl $0x8000001f, %eax /* See if 0x8000001f is available */
+diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
+index ab640abe26b68..1e576cc831c15 100644
+--- a/arch/x86/kernel/cpu/common.c
++++ b/arch/x86/kernel/cpu/common.c
+@@ -1850,7 +1850,7 @@ static inline void setup_getcpu(int cpu)
+ unsigned long cpudata = vdso_encode_cpunode(cpu, early_cpu_to_node(cpu));
+ struct desc_struct d = { };
+
+- if (boot_cpu_has(X86_FEATURE_RDTSCP))
++ if (boot_cpu_has(X86_FEATURE_RDTSCP) || boot_cpu_has(X86_FEATURE_RDPID))
+ write_rdtscp_aux(cpudata);
+
+ /* Store CPU and node number in limit. */
+diff --git a/arch/x86/kernel/sev-es-shared.c b/arch/x86/kernel/sev-es-shared.c
+index cdc04d0912423..387b716698187 100644
+--- a/arch/x86/kernel/sev-es-shared.c
++++ b/arch/x86/kernel/sev-es-shared.c
+@@ -186,7 +186,6 @@ void __init do_vc_no_ghcb(struct pt_regs *regs, unsigned long exit_code)
+ * make it accessible to the hypervisor.
+ *
+ * In particular, check for:
+- * - Hypervisor CPUID bit
+ * - Availability of CPUID leaf 0x8000001f
+ * - SEV CPUID bit.
+ *
+@@ -194,10 +193,7 @@ void __init do_vc_no_ghcb(struct pt_regs *regs, unsigned long exit_code)
+ * can't be checked here.
+ */
+
+- if ((fn == 1 && !(regs->cx & BIT(31))))
+- /* Hypervisor bit */
+- goto fail;
+- else if (fn == 0x80000000 && (regs->ax < 0x8000001f))
++ if (fn == 0x80000000 && (regs->ax < 0x8000001f))
+ /* SEV leaf check */
+ goto fail;
+ else if ((fn == 0x8000001f && !(regs->ax & BIT(1))))
+diff --git a/arch/x86/mm/mem_encrypt_identity.c b/arch/x86/mm/mem_encrypt_identity.c
+index 6c5eb6f3f14f4..a19374d261013 100644
+--- a/arch/x86/mm/mem_encrypt_identity.c
++++ b/arch/x86/mm/mem_encrypt_identity.c
+@@ -503,14 +503,10 @@ void __init sme_enable(struct boot_params *bp)
+
+ #define AMD_SME_BIT BIT(0)
+ #define AMD_SEV_BIT BIT(1)
+- /*
+- * Set the feature mask (SME or SEV) based on whether we are
+- * running under a hypervisor.
+- */
+- eax = 1;
+- ecx = 0;
+- native_cpuid(&eax, &ebx, &ecx, &edx);
+- feature_mask = (ecx & BIT(31)) ? AMD_SEV_BIT : AMD_SME_BIT;
++
++ /* Check the SEV MSR whether SEV or SME is enabled */
++ sev_status = __rdmsr(MSR_AMD64_SEV);
++ feature_mask = (sev_status & MSR_AMD64_SEV_ENABLED) ? AMD_SEV_BIT : AMD_SME_BIT;
+
+ /*
+ * Check for the SME/SEV feature:
+@@ -530,19 +526,26 @@ void __init sme_enable(struct boot_params *bp)
+
+ /* Check if memory encryption is enabled */
+ if (feature_mask == AMD_SME_BIT) {
++ /*
++ * No SME if Hypervisor bit is set. This check is here to
++ * prevent a guest from trying to enable SME. For running as a
++ * KVM guest the MSR_K8_SYSCFG will be sufficient, but there
++ * might be other hypervisors which emulate that MSR as non-zero
++ * or even pass it through to the guest.
++ * A malicious hypervisor can still trick a guest into this
++ * path, but there is no way to protect against that.
++ */
++ eax = 1;
++ ecx = 0;
++ native_cpuid(&eax, &ebx, &ecx, &edx);
++ if (ecx & BIT(31))
++ return;
++
+ /* For SME, check the SYSCFG MSR */
+ msr = __rdmsr(MSR_K8_SYSCFG);
+ if (!(msr & MSR_K8_SYSCFG_MEM_ENCRYPT))
+ return;
+ } else {
+- /* For SEV, check the SEV MSR */
+- msr = __rdmsr(MSR_AMD64_SEV);
+- if (!(msr & MSR_AMD64_SEV_ENABLED))
+- return;
+-
+- /* Save SEV_STATUS to avoid reading MSR again */
+- sev_status = msr;
+-
+ /* SEV state cannot be controlled by a command line option */
+ sme_me_mask = me_mask;
+ sev_enabled = true;
+diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
+index 95586137194ee..20ba5db0f61cd 100644
+--- a/block/bfq-iosched.c
++++ b/block/bfq-iosched.c
+@@ -1012,7 +1012,7 @@ static void
+ bfq_bfqq_resume_state(struct bfq_queue *bfqq, struct bfq_data *bfqd,
+ struct bfq_io_cq *bic, bool bfq_already_existing)
+ {
+- unsigned int old_wr_coeff = bfqq->wr_coeff;
++ unsigned int old_wr_coeff = 1;
+ bool busy = bfq_already_existing && bfq_bfqq_busy(bfqq);
+
+ if (bic->saved_has_short_ttime)
+@@ -1033,7 +1033,13 @@ bfq_bfqq_resume_state(struct bfq_queue *bfqq, struct bfq_data *bfqd,
+ bfqq->ttime = bic->saved_ttime;
+ bfqq->io_start_time = bic->saved_io_start_time;
+ bfqq->tot_idle_time = bic->saved_tot_idle_time;
+- bfqq->wr_coeff = bic->saved_wr_coeff;
++ /*
++ * Restore weight coefficient only if low_latency is on
++ */
++ if (bfqd->low_latency) {
++ old_wr_coeff = bfqq->wr_coeff;
++ bfqq->wr_coeff = bic->saved_wr_coeff;
++ }
+ bfqq->service_from_wr = bic->saved_service_from_wr;
+ bfqq->wr_start_at_switch_to_srt = bic->saved_wr_start_at_switch_to_srt;
+ bfqq->last_wr_start_finish = bic->saved_last_wr_start_finish;
+diff --git a/crypto/api.c b/crypto/api.c
+index ed08cbd5b9d3f..c4eda56cff891 100644
+--- a/crypto/api.c
++++ b/crypto/api.c
+@@ -562,7 +562,7 @@ void crypto_destroy_tfm(void *mem, struct crypto_tfm *tfm)
+ {
+ struct crypto_alg *alg;
+
+- if (unlikely(!mem))
++ if (IS_ERR_OR_NULL(mem))
+ return;
+
+ alg = tfm->__crt_alg;
+diff --git a/crypto/rng.c b/crypto/rng.c
+index a888d84b524a4..fea082b25fe4b 100644
+--- a/crypto/rng.c
++++ b/crypto/rng.c
+@@ -34,22 +34,18 @@ int crypto_rng_reset(struct crypto_rng *tfm, const u8 *seed, unsigned int slen)
+ u8 *buf = NULL;
+ int err;
+
+- crypto_stats_get(alg);
+ if (!seed && slen) {
+ buf = kmalloc(slen, GFP_KERNEL);
+- if (!buf) {
+- crypto_alg_put(alg);
++ if (!buf)
+ return -ENOMEM;
+- }
+
+ err = get_random_bytes_wait(buf, slen);
+- if (err) {
+- crypto_alg_put(alg);
++ if (err)
+ goto out;
+- }
+ seed = buf;
+ }
+
++ crypto_stats_get(alg);
+ err = crypto_rng_alg(tfm)->seed(tfm, seed, slen);
+ crypto_stats_rng_seed(alg, err);
+ out:
+diff --git a/drivers/acpi/arm64/gtdt.c b/drivers/acpi/arm64/gtdt.c
+index f2d0e5915dab5..0a0a982f9c28d 100644
+--- a/drivers/acpi/arm64/gtdt.c
++++ b/drivers/acpi/arm64/gtdt.c
+@@ -329,7 +329,7 @@ static int __init gtdt_import_sbsa_gwdt(struct acpi_gtdt_watchdog *wd,
+ int index)
+ {
+ struct platform_device *pdev;
+- int irq = map_gt_gsi(wd->timer_interrupt, wd->timer_flags);
++ int irq;
+
+ /*
+ * According to SBSA specification the size of refresh and control
+@@ -338,7 +338,7 @@ static int __init gtdt_import_sbsa_gwdt(struct acpi_gtdt_watchdog *wd,
+ struct resource res[] = {
+ DEFINE_RES_MEM(wd->control_frame_address, SZ_4K),
+ DEFINE_RES_MEM(wd->refresh_frame_address, SZ_4K),
+- DEFINE_RES_IRQ(irq),
++ {},
+ };
+ int nr_res = ARRAY_SIZE(res);
+
+@@ -348,10 +348,11 @@ static int __init gtdt_import_sbsa_gwdt(struct acpi_gtdt_watchdog *wd,
+
+ if (!(wd->refresh_frame_address && wd->control_frame_address)) {
+ pr_err(FW_BUG "failed to get the Watchdog base address.\n");
+- acpi_unregister_gsi(wd->timer_interrupt);
+ return -EINVAL;
+ }
+
++ irq = map_gt_gsi(wd->timer_interrupt, wd->timer_flags);
++ res[2] = (struct resource)DEFINE_RES_IRQ(irq);
+ if (irq <= 0) {
+ pr_warn("failed to map the Watchdog interrupt.\n");
+ nr_res--;
+@@ -364,7 +365,8 @@ static int __init gtdt_import_sbsa_gwdt(struct acpi_gtdt_watchdog *wd,
+ */
+ pdev = platform_device_register_simple("sbsa-gwdt", index, res, nr_res);
+ if (IS_ERR(pdev)) {
+- acpi_unregister_gsi(wd->timer_interrupt);
++ if (irq > 0)
++ acpi_unregister_gsi(wd->timer_interrupt);
+ return PTR_ERR(pdev);
+ }
+
+diff --git a/drivers/acpi/custom_method.c b/drivers/acpi/custom_method.c
+index 7b54dc95d36b3..4058e02410917 100644
+--- a/drivers/acpi/custom_method.c
++++ b/drivers/acpi/custom_method.c
+@@ -42,6 +42,8 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf,
+ sizeof(struct acpi_table_header)))
+ return -EFAULT;
+ uncopied_bytes = max_size = table.length;
++ /* make sure the buf is not allocated */
++ kfree(buf);
+ buf = kzalloc(max_size, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+@@ -55,6 +57,7 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf,
+ (*ppos + count < count) ||
+ (count > uncopied_bytes)) {
+ kfree(buf);
++ buf = NULL;
+ return -EINVAL;
+ }
+
+@@ -76,7 +79,6 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf,
+ add_taint(TAINT_OVERRIDDEN_ACPI_TABLE, LOCKDEP_NOW_UNRELIABLE);
+ }
+
+- kfree(buf);
+ return count;
+ }
+
+diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
+index 00ba8e5a1ccc0..33192a8f687d6 100644
+--- a/drivers/ata/ahci.c
++++ b/drivers/ata/ahci.c
+@@ -1772,6 +1772,11 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+ hpriv->flags |= AHCI_HFLAG_NO_DEVSLP;
+
+ #ifdef CONFIG_ARM64
++ if (pdev->vendor == PCI_VENDOR_ID_HUAWEI &&
++ pdev->device == 0xa235 &&
++ pdev->revision < 0x30)
++ hpriv->flags |= AHCI_HFLAG_NO_SXS;
++
+ if (pdev->vendor == 0x177d && pdev->device == 0xa01c)
+ hpriv->irq_handler = ahci_thunderx_irq_handler;
+ #endif
+diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
+index 98b8baa47dc5e..d1f284f0c83d9 100644
+--- a/drivers/ata/ahci.h
++++ b/drivers/ata/ahci.h
+@@ -242,6 +242,7 @@ enum {
+ suspend/resume */
+ AHCI_HFLAG_IGN_NOTSUPP_POWER_ON = (1 << 27), /* ignore -EOPNOTSUPP
+ from phy_power_on() */
++ AHCI_HFLAG_NO_SXS = (1 << 28), /* SXS not supported */
+
+ /* ap->flags bits */
+
+diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
+index ea5bf5f4cbed5..fec2e9754aed2 100644
+--- a/drivers/ata/libahci.c
++++ b/drivers/ata/libahci.c
+@@ -493,6 +493,11 @@ void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv)
+ cap |= HOST_CAP_ALPM;
+ }
+
++ if ((cap & HOST_CAP_SXS) && (hpriv->flags & AHCI_HFLAG_NO_SXS)) {
++ dev_info(dev, "controller does not support SXS, disabling CAP_SXS\n");
++ cap &= ~HOST_CAP_SXS;
++ }
++
+ if (hpriv->force_port_map && port_map != hpriv->force_port_map) {
+ dev_info(dev, "forcing port_map 0x%x -> 0x%x\n",
+ port_map, hpriv->force_port_map);
+diff --git a/drivers/block/rnbd/rnbd-clt-sysfs.c b/drivers/block/rnbd/rnbd-clt-sysfs.c
+index d4aa6bfc95557..526c77cd7a506 100644
+--- a/drivers/block/rnbd/rnbd-clt-sysfs.c
++++ b/drivers/block/rnbd/rnbd-clt-sysfs.c
+@@ -432,10 +432,14 @@ void rnbd_clt_remove_dev_symlink(struct rnbd_clt_dev *dev)
+ * i.e. rnbd_clt_unmap_dev_store() leading to a sysfs warning because
+ * of sysfs link already was removed already.
+ */
+- if (dev->blk_symlink_name && try_module_get(THIS_MODULE)) {
+- sysfs_remove_link(rnbd_devs_kobj, dev->blk_symlink_name);
++ if (dev->blk_symlink_name) {
++ if (try_module_get(THIS_MODULE)) {
++ sysfs_remove_link(rnbd_devs_kobj, dev->blk_symlink_name);
++ module_put(THIS_MODULE);
++ }
++ /* It should be freed always. */
+ kfree(dev->blk_symlink_name);
+- module_put(THIS_MODULE);
++ dev->blk_symlink_name = NULL;
+ }
+ }
+
+diff --git a/drivers/block/rnbd/rnbd-srv.c b/drivers/block/rnbd/rnbd-srv.c
+index a6a68d44f517c..677770f32843f 100644
+--- a/drivers/block/rnbd/rnbd-srv.c
++++ b/drivers/block/rnbd/rnbd-srv.c
+@@ -341,7 +341,9 @@ void rnbd_srv_sess_dev_force_close(struct rnbd_srv_sess_dev *sess_dev)
+ struct rnbd_srv_session *sess = sess_dev->sess;
+
+ sess_dev->keep_id = true;
+- mutex_lock(&sess->lock);
++ /* It is already started to close by client's close message. */
++ if (!mutex_trylock(&sess->lock))
++ return;
+ rnbd_srv_destroy_dev_session_sysfs(sess_dev);
+ mutex_unlock(&sess->lock);
+ }
+diff --git a/drivers/bus/mhi/core/init.c b/drivers/bus/mhi/core/init.c
+index be4eebb0971bc..08b7f4a06bfcc 100644
+--- a/drivers/bus/mhi/core/init.c
++++ b/drivers/bus/mhi/core/init.c
+@@ -508,8 +508,6 @@ int mhi_init_mmio(struct mhi_controller *mhi_cntrl)
+
+ /* Setup wake db */
+ mhi_cntrl->wake_db = base + val + (8 * MHI_DEV_WAKE_DB);
+- mhi_write_reg(mhi_cntrl, mhi_cntrl->wake_db, 4, 0);
+- mhi_write_reg(mhi_cntrl, mhi_cntrl->wake_db, 0, 0);
+ mhi_cntrl->wake_set = false;
+
+ /* Setup channel db address for each channel in tre_ring */
+@@ -552,6 +550,7 @@ void mhi_deinit_chan_ctxt(struct mhi_controller *mhi_cntrl,
+ struct mhi_ring *buf_ring;
+ struct mhi_ring *tre_ring;
+ struct mhi_chan_ctxt *chan_ctxt;
++ u32 tmp;
+
+ buf_ring = &mhi_chan->buf_ring;
+ tre_ring = &mhi_chan->tre_ring;
+@@ -565,7 +564,19 @@ void mhi_deinit_chan_ctxt(struct mhi_controller *mhi_cntrl,
+ vfree(buf_ring->base);
+
+ buf_ring->base = tre_ring->base = NULL;
++ tre_ring->ctxt_wp = NULL;
+ chan_ctxt->rbase = 0;
++ chan_ctxt->rlen = 0;
++ chan_ctxt->rp = 0;
++ chan_ctxt->wp = 0;
++
++ tmp = chan_ctxt->chcfg;
++ tmp &= ~CHAN_CTX_CHSTATE_MASK;
++ tmp |= (MHI_CH_STATE_DISABLED << CHAN_CTX_CHSTATE_SHIFT);
++ chan_ctxt->chcfg = tmp;
++
++ /* Update to all cores */
++ smp_wmb();
+ }
+
+ int mhi_init_chan_ctxt(struct mhi_controller *mhi_cntrl,
+@@ -863,12 +874,10 @@ int mhi_register_controller(struct mhi_controller *mhi_cntrl,
+ u32 soc_info;
+ int ret, i;
+
+- if (!mhi_cntrl)
+- return -EINVAL;
+-
+- if (!mhi_cntrl->runtime_get || !mhi_cntrl->runtime_put ||
++ if (!mhi_cntrl || !mhi_cntrl->cntrl_dev || !mhi_cntrl->regs ||
++ !mhi_cntrl->runtime_get || !mhi_cntrl->runtime_put ||
+ !mhi_cntrl->status_cb || !mhi_cntrl->read_reg ||
+- !mhi_cntrl->write_reg || !mhi_cntrl->nr_irqs)
++ !mhi_cntrl->write_reg || !mhi_cntrl->nr_irqs || !mhi_cntrl->irq)
+ return -EINVAL;
+
+ ret = parse_config(mhi_cntrl, config);
+@@ -890,8 +899,7 @@ int mhi_register_controller(struct mhi_controller *mhi_cntrl,
+ INIT_WORK(&mhi_cntrl->st_worker, mhi_pm_st_worker);
+ init_waitqueue_head(&mhi_cntrl->state_event);
+
+- mhi_cntrl->hiprio_wq = alloc_ordered_workqueue
+- ("mhi_hiprio_wq", WQ_MEM_RECLAIM | WQ_HIGHPRI);
++ mhi_cntrl->hiprio_wq = alloc_ordered_workqueue("mhi_hiprio_wq", WQ_HIGHPRI);
+ if (!mhi_cntrl->hiprio_wq) {
+ dev_err(mhi_cntrl->cntrl_dev, "Failed to allocate workqueue\n");
+ ret = -ENOMEM;
+@@ -1296,7 +1304,8 @@ static int mhi_driver_remove(struct device *dev)
+
+ mutex_lock(&mhi_chan->mutex);
+
+- if (ch_state[dir] == MHI_CH_STATE_ENABLED &&
++ if ((ch_state[dir] == MHI_CH_STATE_ENABLED ||
++ ch_state[dir] == MHI_CH_STATE_STOP) &&
+ !mhi_chan->offload_ch)
+ mhi_deinit_chan_ctxt(mhi_cntrl, mhi_chan);
+
+diff --git a/drivers/bus/mhi/core/main.c b/drivers/bus/mhi/core/main.c
+index 4e0131b94056b..61c37b23dd718 100644
+--- a/drivers/bus/mhi/core/main.c
++++ b/drivers/bus/mhi/core/main.c
+@@ -242,10 +242,17 @@ static void mhi_del_ring_element(struct mhi_controller *mhi_cntrl,
+ smp_wmb();
+ }
+
++static bool is_valid_ring_ptr(struct mhi_ring *ring, dma_addr_t addr)
++{
++ return addr >= ring->iommu_base && addr < ring->iommu_base + ring->len;
++}
++
+ int mhi_destroy_device(struct device *dev, void *data)
+ {
++ struct mhi_chan *ul_chan, *dl_chan;
+ struct mhi_device *mhi_dev;
+ struct mhi_controller *mhi_cntrl;
++ enum mhi_ee_type ee = MHI_EE_MAX;
+
+ if (dev->bus != &mhi_bus_type)
+ return 0;
+@@ -257,6 +264,17 @@ int mhi_destroy_device(struct device *dev, void *data)
+ if (mhi_dev->dev_type == MHI_DEVICE_CONTROLLER)
+ return 0;
+
++ ul_chan = mhi_dev->ul_chan;
++ dl_chan = mhi_dev->dl_chan;
++
++ /*
++ * If execution environment is specified, remove only those devices that
++ * started in them based on ee_mask for the channels as we move on to a
++ * different execution environment
++ */
++ if (data)
++ ee = *(enum mhi_ee_type *)data;
++
+ /*
+ * For the suspend and resume case, this function will get called
+ * without mhi_unregister_controller(). Hence, we need to drop the
+@@ -264,11 +282,19 @@ int mhi_destroy_device(struct device *dev, void *data)
+ * be sure that there will be no instances of mhi_dev left after
+ * this.
+ */
+- if (mhi_dev->ul_chan)
+- put_device(&mhi_dev->ul_chan->mhi_dev->dev);
++ if (ul_chan) {
++ if (ee != MHI_EE_MAX && !(ul_chan->ee_mask & BIT(ee)))
++ return 0;
+
+- if (mhi_dev->dl_chan)
+- put_device(&mhi_dev->dl_chan->mhi_dev->dev);
++ put_device(&ul_chan->mhi_dev->dev);
++ }
++
++ if (dl_chan) {
++ if (ee != MHI_EE_MAX && !(dl_chan->ee_mask & BIT(ee)))
++ return 0;
++
++ put_device(&dl_chan->mhi_dev->dev);
++ }
+
+ dev_dbg(&mhi_cntrl->mhi_dev->dev, "destroy device for chan:%s\n",
+ mhi_dev->name);
+@@ -383,7 +409,16 @@ irqreturn_t mhi_irq_handler(int irq_number, void *dev)
+ struct mhi_event_ctxt *er_ctxt =
+ &mhi_cntrl->mhi_ctxt->er_ctxt[mhi_event->er_index];
+ struct mhi_ring *ev_ring = &mhi_event->ring;
+- void *dev_rp = mhi_to_virtual(ev_ring, er_ctxt->rp);
++ dma_addr_t ptr = er_ctxt->rp;
++ void *dev_rp;
++
++ if (!is_valid_ring_ptr(ev_ring, ptr)) {
++ dev_err(&mhi_cntrl->mhi_dev->dev,
++ "Event ring rp points outside of the event ring\n");
++ return IRQ_HANDLED;
++ }
++
++ dev_rp = mhi_to_virtual(ev_ring, ptr);
+
+ /* Only proceed if event ring has pending events */
+ if (ev_ring->rp == dev_rp)
+@@ -409,7 +444,7 @@ irqreturn_t mhi_intvec_threaded_handler(int irq_number, void *priv)
+ struct device *dev = &mhi_cntrl->mhi_dev->dev;
+ enum mhi_state state = MHI_STATE_MAX;
+ enum mhi_pm_state pm_state = 0;
+- enum mhi_ee_type ee = 0;
++ enum mhi_ee_type ee = MHI_EE_MAX;
+
+ write_lock_irq(&mhi_cntrl->pm_lock);
+ if (!MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) {
+@@ -418,8 +453,7 @@ irqreturn_t mhi_intvec_threaded_handler(int irq_number, void *priv)
+ }
+
+ state = mhi_get_mhi_state(mhi_cntrl);
+- ee = mhi_cntrl->ee;
+- mhi_cntrl->ee = mhi_get_exec_env(mhi_cntrl);
++ ee = mhi_get_exec_env(mhi_cntrl);
+ dev_dbg(dev, "local ee:%s device ee:%s dev_state:%s\n",
+ TO_MHI_EXEC_STR(mhi_cntrl->ee), TO_MHI_EXEC_STR(ee),
+ TO_MHI_STATE_STR(state));
+@@ -431,27 +465,30 @@ irqreturn_t mhi_intvec_threaded_handler(int irq_number, void *priv)
+ }
+ write_unlock_irq(&mhi_cntrl->pm_lock);
+
+- /* If device supports RDDM don't bother processing SYS error */
+- if (mhi_cntrl->rddm_image) {
+- /* host may be performing a device power down already */
+- if (!mhi_is_active(mhi_cntrl))
+- goto exit_intvec;
++ if (pm_state != MHI_PM_SYS_ERR_DETECT || ee == mhi_cntrl->ee)
++ goto exit_intvec;
+
+- if (mhi_cntrl->ee == MHI_EE_RDDM && mhi_cntrl->ee != ee) {
++ switch (ee) {
++ case MHI_EE_RDDM:
++ /* proceed if power down is not already in progress */
++ if (mhi_cntrl->rddm_image && mhi_is_active(mhi_cntrl)) {
+ mhi_cntrl->status_cb(mhi_cntrl, MHI_CB_EE_RDDM);
++ mhi_cntrl->ee = ee;
+ wake_up_all(&mhi_cntrl->state_event);
+ }
+- goto exit_intvec;
+- }
+-
+- if (pm_state == MHI_PM_SYS_ERR_DETECT) {
++ break;
++ case MHI_EE_PBL:
++ case MHI_EE_EDL:
++ case MHI_EE_PTHRU:
++ mhi_cntrl->status_cb(mhi_cntrl, MHI_CB_FATAL_ERROR);
++ mhi_cntrl->ee = ee;
+ wake_up_all(&mhi_cntrl->state_event);
+-
+- /* For fatal errors, we let controller decide next step */
+- if (MHI_IN_PBL(ee))
+- mhi_cntrl->status_cb(mhi_cntrl, MHI_CB_FATAL_ERROR);
+- else
+- mhi_pm_sys_err_handler(mhi_cntrl);
++ mhi_pm_sys_err_handler(mhi_cntrl);
++ break;
++ default:
++ wake_up_all(&mhi_cntrl->state_event);
++ mhi_pm_sys_err_handler(mhi_cntrl);
++ break;
+ }
+
+ exit_intvec:
+@@ -536,6 +573,11 @@ static int parse_xfer_event(struct mhi_controller *mhi_cntrl,
+ struct mhi_buf_info *buf_info;
+ u16 xfer_len;
+
++ if (!is_valid_ring_ptr(tre_ring, ptr)) {
++ dev_err(&mhi_cntrl->mhi_dev->dev,
++ "Event element points outside of the tre ring\n");
++ break;
++ }
+ /* Get the TRB this event points to */
+ ev_tre = mhi_to_virtual(tre_ring, ptr);
+
+@@ -570,8 +612,11 @@ static int parse_xfer_event(struct mhi_controller *mhi_cntrl,
+ /* notify client */
+ mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result);
+
+- if (mhi_chan->dir == DMA_TO_DEVICE)
++ if (mhi_chan->dir == DMA_TO_DEVICE) {
+ atomic_dec(&mhi_cntrl->pending_pkts);
++ /* Release the reference got from mhi_queue() */
++ mhi_cntrl->runtime_put(mhi_cntrl);
++ }
+
+ /*
+ * Recycle the buffer if buffer is pre-allocated,
+@@ -695,6 +740,12 @@ static void mhi_process_cmd_completion(struct mhi_controller *mhi_cntrl,
+ struct mhi_chan *mhi_chan;
+ u32 chan;
+
++ if (!is_valid_ring_ptr(mhi_ring, ptr)) {
++ dev_err(&mhi_cntrl->mhi_dev->dev,
++ "Event element points outside of the cmd ring\n");
++ return;
++ }
++
+ cmd_pkt = mhi_to_virtual(mhi_ring, ptr);
+
+ chan = MHI_TRE_GET_CMD_CHID(cmd_pkt);
+@@ -719,6 +770,7 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi_cntrl,
+ struct device *dev = &mhi_cntrl->mhi_dev->dev;
+ u32 chan;
+ int count = 0;
++ dma_addr_t ptr = er_ctxt->rp;
+
+ /*
+ * This is a quick check to avoid unnecessary event processing
+@@ -728,7 +780,13 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi_cntrl,
+ if (unlikely(MHI_EVENT_ACCESS_INVALID(mhi_cntrl->pm_state)))
+ return -EIO;
+
+- dev_rp = mhi_to_virtual(ev_ring, er_ctxt->rp);
++ if (!is_valid_ring_ptr(ev_ring, ptr)) {
++ dev_err(&mhi_cntrl->mhi_dev->dev,
++ "Event ring rp points outside of the event ring\n");
++ return -EIO;
++ }
++
++ dev_rp = mhi_to_virtual(ev_ring, ptr);
+ local_rp = ev_ring->rp;
+
+ while (dev_rp != local_rp) {
+@@ -834,6 +892,8 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi_cntrl,
+ */
+ if (chan < mhi_cntrl->max_chan) {
+ mhi_chan = &mhi_cntrl->mhi_chan[chan];
++ if (!mhi_chan->configured)
++ break;
+ parse_xfer_event(mhi_cntrl, local_rp, mhi_chan);
+ event_quota--;
+ }
+@@ -845,7 +905,15 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi_cntrl,
+
+ mhi_recycle_ev_ring_element(mhi_cntrl, ev_ring);
+ local_rp = ev_ring->rp;
+- dev_rp = mhi_to_virtual(ev_ring, er_ctxt->rp);
++
++ ptr = er_ctxt->rp;
++ if (!is_valid_ring_ptr(ev_ring, ptr)) {
++ dev_err(&mhi_cntrl->mhi_dev->dev,
++ "Event ring rp points outside of the event ring\n");
++ return -EIO;
++ }
++
++ dev_rp = mhi_to_virtual(ev_ring, ptr);
+ count++;
+ }
+
+@@ -868,11 +936,18 @@ int mhi_process_data_event_ring(struct mhi_controller *mhi_cntrl,
+ int count = 0;
+ u32 chan;
+ struct mhi_chan *mhi_chan;
++ dma_addr_t ptr = er_ctxt->rp;
+
+ if (unlikely(MHI_EVENT_ACCESS_INVALID(mhi_cntrl->pm_state)))
+ return -EIO;
+
+- dev_rp = mhi_to_virtual(ev_ring, er_ctxt->rp);
++ if (!is_valid_ring_ptr(ev_ring, ptr)) {
++ dev_err(&mhi_cntrl->mhi_dev->dev,
++ "Event ring rp points outside of the event ring\n");
++ return -EIO;
++ }
++
++ dev_rp = mhi_to_virtual(ev_ring, ptr);
+ local_rp = ev_ring->rp;
+
+ while (dev_rp != local_rp && event_quota > 0) {
+@@ -886,7 +961,8 @@ int mhi_process_data_event_ring(struct mhi_controller *mhi_cntrl,
+ * Only process the event ring elements whose channel
+ * ID is within the maximum supported range.
+ */
+- if (chan < mhi_cntrl->max_chan) {
++ if (chan < mhi_cntrl->max_chan &&
++ mhi_cntrl->mhi_chan[chan].configured) {
+ mhi_chan = &mhi_cntrl->mhi_chan[chan];
+
+ if (likely(type == MHI_PKT_TYPE_TX_EVENT)) {
+@@ -900,7 +976,15 @@ int mhi_process_data_event_ring(struct mhi_controller *mhi_cntrl,
+
+ mhi_recycle_ev_ring_element(mhi_cntrl, ev_ring);
+ local_rp = ev_ring->rp;
+- dev_rp = mhi_to_virtual(ev_ring, er_ctxt->rp);
++
++ ptr = er_ctxt->rp;
++ if (!is_valid_ring_ptr(ev_ring, ptr)) {
++ dev_err(&mhi_cntrl->mhi_dev->dev,
++ "Event ring rp points outside of the event ring\n");
++ return -EIO;
++ }
++
++ dev_rp = mhi_to_virtual(ev_ring, ptr);
+ count++;
+ }
+ read_lock_bh(&mhi_cntrl->pm_lock);
+@@ -1004,9 +1088,11 @@ static int mhi_queue(struct mhi_device *mhi_dev, struct mhi_buf_info *buf_info,
+ if (unlikely(ret))
+ goto exit_unlock;
+
+- /* trigger M3 exit if necessary */
+- if (MHI_PM_IN_SUSPEND_STATE(mhi_cntrl->pm_state))
+- mhi_trigger_resume(mhi_cntrl);
++ /* Packet is queued, take a usage ref to exit M3 if necessary
++ * for host->device buffer, balanced put is done on buffer completion
++ * for device->host buffer, balanced put is after ringing the DB
++ */
++ mhi_cntrl->runtime_get(mhi_cntrl);
+
+ /* Assert dev_wake (to exit/prevent M1/M2)*/
+ mhi_cntrl->wake_toggle(mhi_cntrl);
+@@ -1014,12 +1100,11 @@ static int mhi_queue(struct mhi_device *mhi_dev, struct mhi_buf_info *buf_info,
+ if (mhi_chan->dir == DMA_TO_DEVICE)
+ atomic_inc(&mhi_cntrl->pending_pkts);
+
+- if (unlikely(!MHI_DB_ACCESS_VALID(mhi_cntrl))) {
+- ret = -EIO;
+- goto exit_unlock;
+- }
++ if (likely(MHI_DB_ACCESS_VALID(mhi_cntrl)))
++ mhi_ring_chan_db(mhi_cntrl, mhi_chan);
+
+- mhi_ring_chan_db(mhi_cntrl, mhi_chan);
++ if (dir == DMA_FROM_DEVICE)
++ mhi_cntrl->runtime_put(mhi_cntrl);
+
+ exit_unlock:
+ read_unlock_irqrestore(&mhi_cntrl->pm_lock, flags);
+@@ -1365,6 +1450,7 @@ static void mhi_mark_stale_events(struct mhi_controller *mhi_cntrl,
+ struct mhi_ring *ev_ring;
+ struct device *dev = &mhi_cntrl->mhi_dev->dev;
+ unsigned long flags;
++ dma_addr_t ptr;
+
+ dev_dbg(dev, "Marking all events for chan: %d as stale\n", chan);
+
+@@ -1372,7 +1458,15 @@ static void mhi_mark_stale_events(struct mhi_controller *mhi_cntrl,
+
+ /* mark all stale events related to channel as STALE event */
+ spin_lock_irqsave(&mhi_event->lock, flags);
+- dev_rp = mhi_to_virtual(ev_ring, er_ctxt->rp);
++
++ ptr = er_ctxt->rp;
++ if (!is_valid_ring_ptr(ev_ring, ptr)) {
++ dev_err(&mhi_cntrl->mhi_dev->dev,
++ "Event ring rp points outside of the event ring\n");
++ dev_rp = ev_ring->rp;
++ } else {
++ dev_rp = mhi_to_virtual(ev_ring, ptr);
++ }
+
+ local_rp = ev_ring->rp;
+ while (dev_rp != local_rp) {
+@@ -1403,8 +1497,11 @@ static void mhi_reset_data_chan(struct mhi_controller *mhi_cntrl,
+ while (tre_ring->rp != tre_ring->wp) {
+ struct mhi_buf_info *buf_info = buf_ring->rp;
+
+- if (mhi_chan->dir == DMA_TO_DEVICE)
++ if (mhi_chan->dir == DMA_TO_DEVICE) {
+ atomic_dec(&mhi_cntrl->pending_pkts);
++ /* Release the reference got from mhi_queue() */
++ mhi_cntrl->runtime_put(mhi_cntrl);
++ }
+
+ if (!buf_info->pre_mapped)
+ mhi_cntrl->unmap_single(mhi_cntrl, buf_info);
+diff --git a/drivers/bus/mhi/core/pm.c b/drivers/bus/mhi/core/pm.c
+index 681960c72d2a8..277704af7eb6f 100644
+--- a/drivers/bus/mhi/core/pm.c
++++ b/drivers/bus/mhi/core/pm.c
+@@ -377,24 +377,28 @@ static int mhi_pm_mission_mode_transition(struct mhi_controller *mhi_cntrl)
+ {
+ struct mhi_event *mhi_event;
+ struct device *dev = &mhi_cntrl->mhi_dev->dev;
++ enum mhi_ee_type ee = MHI_EE_MAX, current_ee = mhi_cntrl->ee;
+ int i, ret;
+
+ dev_dbg(dev, "Processing Mission Mode transition\n");
+
+ write_lock_irq(&mhi_cntrl->pm_lock);
+ if (MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state))
+- mhi_cntrl->ee = mhi_get_exec_env(mhi_cntrl);
++ ee = mhi_get_exec_env(mhi_cntrl);
+
+- if (!MHI_IN_MISSION_MODE(mhi_cntrl->ee)) {
++ if (!MHI_IN_MISSION_MODE(ee)) {
+ mhi_cntrl->pm_state = MHI_PM_LD_ERR_FATAL_DETECT;
+ write_unlock_irq(&mhi_cntrl->pm_lock);
+ wake_up_all(&mhi_cntrl->state_event);
+ return -EIO;
+ }
++ mhi_cntrl->ee = ee;
+ write_unlock_irq(&mhi_cntrl->pm_lock);
+
+ wake_up_all(&mhi_cntrl->state_event);
+
++ device_for_each_child(&mhi_cntrl->mhi_dev->dev, &current_ee,
++ mhi_destroy_device);
+ mhi_cntrl->status_cb(mhi_cntrl, MHI_CB_EE_MISSION_MODE);
+
+ /* Force MHI to be in M0 state before continuing */
+@@ -1092,7 +1096,7 @@ int mhi_async_power_up(struct mhi_controller *mhi_cntrl)
+ &val) ||
+ !val,
+ msecs_to_jiffies(mhi_cntrl->timeout_ms));
+- if (ret) {
++ if (!ret) {
+ ret = -EIO;
+ dev_info(dev, "Failed to reset MHI due to syserr state\n");
+ goto error_bhi_offset;
+diff --git a/drivers/bus/mhi/pci_generic.c b/drivers/bus/mhi/pci_generic.c
+index 20673a4b4a3c6..ef549c695b55c 100644
+--- a/drivers/bus/mhi/pci_generic.c
++++ b/drivers/bus/mhi/pci_generic.c
+@@ -230,6 +230,21 @@ static void mhi_pci_status_cb(struct mhi_controller *mhi_cntrl,
+ }
+ }
+
++static void mhi_pci_wake_get_nop(struct mhi_controller *mhi_cntrl, bool force)
++{
++ /* no-op */
++}
++
++static void mhi_pci_wake_put_nop(struct mhi_controller *mhi_cntrl, bool override)
++{
++ /* no-op */
++}
++
++static void mhi_pci_wake_toggle_nop(struct mhi_controller *mhi_cntrl)
++{
++ /* no-op */
++}
++
+ static bool mhi_pci_is_alive(struct mhi_controller *mhi_cntrl)
+ {
+ struct pci_dev *pdev = to_pci_dev(mhi_cntrl->cntrl_dev);
+@@ -433,6 +448,9 @@ static int mhi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ mhi_cntrl->status_cb = mhi_pci_status_cb;
+ mhi_cntrl->runtime_get = mhi_pci_runtime_get;
+ mhi_cntrl->runtime_put = mhi_pci_runtime_put;
++ mhi_cntrl->wake_get = mhi_pci_wake_get_nop;
++ mhi_cntrl->wake_put = mhi_pci_wake_put_nop;
++ mhi_cntrl->wake_toggle = mhi_pci_wake_toggle_nop;
+
+ err = mhi_pci_claim(mhi_cntrl, info->bar_num, DMA_BIT_MASK(info->dma_data_width));
+ if (err)
+@@ -498,6 +516,12 @@ static void mhi_pci_remove(struct pci_dev *pdev)
+ mhi_unregister_controller(mhi_cntrl);
+ }
+
++static void mhi_pci_shutdown(struct pci_dev *pdev)
++{
++ mhi_pci_remove(pdev);
++ pci_set_power_state(pdev, PCI_D3hot);
++}
++
+ static void mhi_pci_reset_prepare(struct pci_dev *pdev)
+ {
+ struct mhi_pci_device *mhi_pdev = pci_get_drvdata(pdev);
+@@ -668,6 +692,7 @@ static struct pci_driver mhi_pci_driver = {
+ .id_table = mhi_pci_id_table,
+ .probe = mhi_pci_probe,
+ .remove = mhi_pci_remove,
++ .shutdown = mhi_pci_shutdown,
+ .err_handler = &mhi_pci_err_handler,
+ .driver.pm = &mhi_pci_pm_ops
+ };
+diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c
+index 3d74f237f005b..9e535336689fd 100644
+--- a/drivers/bus/ti-sysc.c
++++ b/drivers/bus/ti-sysc.c
+@@ -635,6 +635,51 @@ static int sysc_parse_and_check_child_range(struct sysc *ddata)
+ return 0;
+ }
+
++/* Interconnect instances to probe before l4_per instances */
++static struct resource early_bus_ranges[] = {
++ /* am3/4 l4_wkup */
++ { .start = 0x44c00000, .end = 0x44c00000 + 0x300000, },
++ /* omap4/5 and dra7 l4_cfg */
++ { .start = 0x4a000000, .end = 0x4a000000 + 0x300000, },
++ /* omap4 l4_wkup */
++ { .start = 0x4a300000, .end = 0x4a300000 + 0x30000, },
++ /* omap5 and dra7 l4_wkup without dra7 dcan segment */
++ { .start = 0x4ae00000, .end = 0x4ae00000 + 0x30000, },
++};
++
++static atomic_t sysc_defer = ATOMIC_INIT(10);
++
++/**
++ * sysc_defer_non_critical - defer non_critical interconnect probing
++ * @ddata: device driver data
++ *
++ * We want to probe l4_cfg and l4_wkup interconnect instances before any
++ * l4_per instances as l4_per instances depend on resources on l4_cfg and
++ * l4_wkup interconnects.
++ */
++static int sysc_defer_non_critical(struct sysc *ddata)
++{
++ struct resource *res;
++ int i;
++
++ if (!atomic_read(&sysc_defer))
++ return 0;
++
++ for (i = 0; i < ARRAY_SIZE(early_bus_ranges); i++) {
++ res = &early_bus_ranges[i];
++ if (ddata->module_pa >= res->start &&
++ ddata->module_pa <= res->end) {
++ atomic_set(&sysc_defer, 0);
++
++ return 0;
++ }
++ }
++
++ atomic_dec_if_positive(&sysc_defer);
++
++ return -EPROBE_DEFER;
++}
++
+ static struct device_node *stdout_path;
+
+ static void sysc_init_stdout_path(struct sysc *ddata)
+@@ -863,6 +908,10 @@ static int sysc_map_and_check_registers(struct sysc *ddata)
+ if (error)
+ return error;
+
++ error = sysc_defer_non_critical(ddata);
++ if (error)
++ return error;
++
+ sysc_check_children(ddata);
+
+ error = sysc_parse_registers(ddata);
+diff --git a/drivers/char/random.c b/drivers/char/random.c
+index 0fe9e200e4c84..5d6acfecd919b 100644
+--- a/drivers/char/random.c
++++ b/drivers/char/random.c
+@@ -819,7 +819,7 @@ static bool __init crng_init_try_arch_early(struct crng_state *crng)
+
+ static void __maybe_unused crng_initialize_secondary(struct crng_state *crng)
+ {
+- memcpy(&crng->state[0], "expand 32-byte k", 16);
++ chacha_init_consts(crng->state);
+ _get_random_bytes(&crng->state[4], sizeof(__u32) * 12);
+ crng_init_try_arch(crng);
+ crng->init_time = jiffies - CRNG_RESEED_INTERVAL - 1;
+@@ -827,7 +827,7 @@ static void __maybe_unused crng_initialize_secondary(struct crng_state *crng)
+
+ static void __init crng_initialize_primary(struct crng_state *crng)
+ {
+- memcpy(&crng->state[0], "expand 32-byte k", 16);
++ chacha_init_consts(crng->state);
+ _extract_entropy(&input_pool, &crng->state[4], sizeof(__u32) * 12, 0);
+ if (crng_init_try_arch_early(crng) && trust_cpu) {
+ invalidate_batched_entropy();
+diff --git a/drivers/char/tpm/eventlog/acpi.c b/drivers/char/tpm/eventlog/acpi.c
+index 3633ed70f48fa..1b18ce5ebab1e 100644
+--- a/drivers/char/tpm/eventlog/acpi.c
++++ b/drivers/char/tpm/eventlog/acpi.c
+@@ -41,6 +41,27 @@ struct acpi_tcpa {
+ };
+ };
+
++/* Check that the given log is indeed a TPM2 log. */
++static bool tpm_is_tpm2_log(void *bios_event_log, u64 len)
++{
++ struct tcg_efi_specid_event_head *efispecid;
++ struct tcg_pcr_event *event_header;
++ int n;
++
++ if (len < sizeof(*event_header))
++ return false;
++ len -= sizeof(*event_header);
++ event_header = bios_event_log;
++
++ if (len < sizeof(*efispecid))
++ return false;
++ efispecid = (struct tcg_efi_specid_event_head *)event_header->event;
++
++ n = memcmp(efispecid->signature, TCG_SPECID_SIG,
++ sizeof(TCG_SPECID_SIG));
++ return n == 0;
++}
++
+ /* read binary bios log */
+ int tpm_read_log_acpi(struct tpm_chip *chip)
+ {
+@@ -52,6 +73,7 @@ int tpm_read_log_acpi(struct tpm_chip *chip)
+ struct acpi_table_tpm2 *tbl;
+ struct acpi_tpm2_phy *tpm2_phy;
+ int format;
++ int ret;
+
+ log = &chip->log;
+
+@@ -112,6 +134,7 @@ int tpm_read_log_acpi(struct tpm_chip *chip)
+
+ log->bios_event_log_end = log->bios_event_log + len;
+
++ ret = -EIO;
+ virt = acpi_os_map_iomem(start, len);
+ if (!virt)
+ goto err;
+@@ -119,11 +142,19 @@ int tpm_read_log_acpi(struct tpm_chip *chip)
+ memcpy_fromio(log->bios_event_log, virt, len);
+
+ acpi_os_unmap_iomem(virt, len);
++
++ if (chip->flags & TPM_CHIP_FLAG_TPM2 &&
++ !tpm_is_tpm2_log(log->bios_event_log, len)) {
++ /* try EFI log next */
++ ret = -ENODEV;
++ goto err;
++ }
++
+ return format;
+
+ err:
+ kfree(log->bios_event_log);
+ log->bios_event_log = NULL;
+- return -EIO;
++ return ret;
+
+ }
+diff --git a/drivers/char/tpm/eventlog/common.c b/drivers/char/tpm/eventlog/common.c
+index 7460f230bae4c..8512ec76d5260 100644
+--- a/drivers/char/tpm/eventlog/common.c
++++ b/drivers/char/tpm/eventlog/common.c
+@@ -107,6 +107,9 @@ void tpm_bios_log_setup(struct tpm_chip *chip)
+ int log_version;
+ int rc = 0;
+
++ if (chip->flags & TPM_CHIP_FLAG_VIRTUAL)
++ return;
++
+ rc = tpm_read_log(chip);
+ if (rc < 0)
+ return;
+diff --git a/drivers/char/tpm/eventlog/efi.c b/drivers/char/tpm/eventlog/efi.c
+index 35229e5143cac..e6cb9d525e30c 100644
+--- a/drivers/char/tpm/eventlog/efi.c
++++ b/drivers/char/tpm/eventlog/efi.c
+@@ -17,6 +17,7 @@ int tpm_read_log_efi(struct tpm_chip *chip)
+ {
+
+ struct efi_tcg2_final_events_table *final_tbl = NULL;
++ int final_events_log_size = efi_tpm_final_log_size;
+ struct linux_efi_tpm_eventlog *log_tbl;
+ struct tpm_bios_log *log;
+ u32 log_size;
+@@ -66,12 +67,12 @@ int tpm_read_log_efi(struct tpm_chip *chip)
+ ret = tpm_log_version;
+
+ if (efi.tpm_final_log == EFI_INVALID_TABLE_ADDR ||
+- efi_tpm_final_log_size == 0 ||
++ final_events_log_size == 0 ||
+ tpm_log_version != EFI_TCG2_EVENT_LOG_FORMAT_TCG_2)
+ goto out;
+
+ final_tbl = memremap(efi.tpm_final_log,
+- sizeof(*final_tbl) + efi_tpm_final_log_size,
++ sizeof(*final_tbl) + final_events_log_size,
+ MEMREMAP_WB);
+ if (!final_tbl) {
+ pr_err("Could not map UEFI TPM final log\n");
+@@ -80,10 +81,18 @@ int tpm_read_log_efi(struct tpm_chip *chip)
+ goto out;
+ }
+
+- efi_tpm_final_log_size -= log_tbl->final_events_preboot_size;
++ /*
++ * The 'final events log' size excludes the 'final events preboot log'
++ * at its beginning.
++ */
++ final_events_log_size -= log_tbl->final_events_preboot_size;
+
++ /*
++ * Allocate memory for the 'combined log' where we will append the
++ * 'final events log' to.
++ */
+ tmp = krealloc(log->bios_event_log,
+- log_size + efi_tpm_final_log_size,
++ log_size + final_events_log_size,
+ GFP_KERNEL);
+ if (!tmp) {
+ kfree(log->bios_event_log);
+@@ -94,15 +103,19 @@ int tpm_read_log_efi(struct tpm_chip *chip)
+ log->bios_event_log = tmp;
+
+ /*
+- * Copy any of the final events log that didn't also end up in the
+- * main log. Events can be logged in both if events are generated
++ * Append any of the 'final events log' that didn't also end up in the
++ * 'main log'. Events can be logged in both if events are generated
+ * between GetEventLog() and ExitBootServices().
+ */
+ memcpy((void *)log->bios_event_log + log_size,
+ final_tbl->events + log_tbl->final_events_preboot_size,
+- efi_tpm_final_log_size);
++ final_events_log_size);
++ /*
++ * The size of the 'combined log' is the size of the 'main log' plus
++ * the size of the 'final events log'.
++ */
+ log->bios_event_log_end = log->bios_event_log +
+- log_size + efi_tpm_final_log_size;
++ log_size + final_events_log_size;
+
+ out:
+ memunmap(final_tbl);
+diff --git a/drivers/clk/socfpga/clk-gate-a10.c b/drivers/clk/socfpga/clk-gate-a10.c
+index cd5df91036142..d62778884208c 100644
+--- a/drivers/clk/socfpga/clk-gate-a10.c
++++ b/drivers/clk/socfpga/clk-gate-a10.c
+@@ -146,6 +146,7 @@ static void __init __socfpga_gate_init(struct device_node *node,
+ if (IS_ERR(socfpga_clk->sys_mgr_base_addr)) {
+ pr_err("%s: failed to find altr,sys-mgr regmap!\n",
+ __func__);
++ kfree(socfpga_clk);
+ return;
+ }
+ }
+diff --git a/drivers/clocksource/dw_apb_timer_of.c b/drivers/clocksource/dw_apb_timer_of.c
+index 42e7e43b8fcd9..b1e2b697b21bd 100644
+--- a/drivers/clocksource/dw_apb_timer_of.c
++++ b/drivers/clocksource/dw_apb_timer_of.c
+@@ -52,18 +52,34 @@ static int __init timer_get_base_and_rate(struct device_node *np,
+ return 0;
+
+ timer_clk = of_clk_get_by_name(np, "timer");
+- if (IS_ERR(timer_clk))
+- return PTR_ERR(timer_clk);
++ if (IS_ERR(timer_clk)) {
++ ret = PTR_ERR(timer_clk);
++ goto out_pclk_disable;
++ }
+
+ ret = clk_prepare_enable(timer_clk);
+ if (ret)
+- return ret;
++ goto out_timer_clk_put;
+
+ *rate = clk_get_rate(timer_clk);
+- if (!(*rate))
+- return -EINVAL;
++ if (!(*rate)) {
++ ret = -EINVAL;
++ goto out_timer_clk_disable;
++ }
+
+ return 0;
++
++out_timer_clk_disable:
++ clk_disable_unprepare(timer_clk);
++out_timer_clk_put:
++ clk_put(timer_clk);
++out_pclk_disable:
++ if (!IS_ERR(pclk)) {
++ clk_disable_unprepare(pclk);
++ clk_put(pclk);
++ }
++ iounmap(*base);
++ return ret;
+ }
+
+ static int __init add_clockevent(struct device_node *event_timer)
+diff --git a/drivers/cpuidle/cpuidle-tegra.c b/drivers/cpuidle/cpuidle-tegra.c
+index 191966dc8d023..29c5e83500d33 100644
+--- a/drivers/cpuidle/cpuidle-tegra.c
++++ b/drivers/cpuidle/cpuidle-tegra.c
+@@ -135,13 +135,13 @@ static int tegra_cpuidle_c7_enter(void)
+ {
+ int err;
+
+- if (tegra_cpuidle_using_firmware()) {
+- err = call_firmware_op(prepare_idle, TF_PM_MODE_LP2_NOFLUSH_L2);
+- if (err)
+- return err;
++ err = call_firmware_op(prepare_idle, TF_PM_MODE_LP2_NOFLUSH_L2);
++ if (err && err != -ENOSYS)
++ return err;
+
+- return call_firmware_op(do_idle, 0);
+- }
++ err = call_firmware_op(do_idle, 0);
++ if (err != -ENOSYS)
++ return err;
+
+ return cpu_suspend(0, tegra30_pm_secondary_cpu_suspend);
+ }
+diff --git a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c
+index c2e6f5ed1d797..dec79fa3ebafb 100644
+--- a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c
++++ b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c
+@@ -561,7 +561,7 @@ int sun4i_ss_cipher_init(struct crypto_tfm *tfm)
+ sizeof(struct sun4i_cipher_req_ctx) +
+ crypto_skcipher_reqsize(op->fallback_tfm));
+
+- err = pm_runtime_get_sync(op->ss->dev);
++ err = pm_runtime_resume_and_get(op->ss->dev);
+ if (err < 0)
+ goto error_pm;
+
+diff --git a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-core.c b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-core.c
+index 709905ec46806..02a2d34845f24 100644
+--- a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-core.c
++++ b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-core.c
+@@ -459,7 +459,7 @@ static int sun4i_ss_probe(struct platform_device *pdev)
+ * this info could be useful
+ */
+
+- err = pm_runtime_get_sync(ss->dev);
++ err = pm_runtime_resume_and_get(ss->dev);
+ if (err < 0)
+ goto error_pm;
+
+diff --git a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-hash.c b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-hash.c
+index c1b4585e9bbc7..d28292762b324 100644
+--- a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-hash.c
++++ b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-hash.c
+@@ -27,7 +27,7 @@ int sun4i_hash_crainit(struct crypto_tfm *tfm)
+ algt = container_of(alg, struct sun4i_ss_alg_template, alg.hash);
+ op->ss = algt->ss;
+
+- err = pm_runtime_get_sync(op->ss->dev);
++ err = pm_runtime_resume_and_get(op->ss->dev);
+ if (err < 0)
+ return err;
+
+diff --git a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-prng.c b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-prng.c
+index 443160a114bb0..491fcb7b81b40 100644
+--- a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-prng.c
++++ b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-prng.c
+@@ -29,7 +29,7 @@ int sun4i_ss_prng_generate(struct crypto_rng *tfm, const u8 *src,
+ algt = container_of(alg, struct sun4i_ss_alg_template, alg.rng);
+ ss = algt->ss;
+
+- err = pm_runtime_get_sync(ss->dev);
++ err = pm_runtime_resume_and_get(ss->dev);
+ if (err < 0)
+ return err;
+
+diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c
+index 158422ff5695c..00194d1d9ae69 100644
+--- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c
++++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c
+@@ -932,7 +932,7 @@ static int sun8i_ce_probe(struct platform_device *pdev)
+ if (err)
+ goto error_alg;
+
+- err = pm_runtime_get_sync(ce->dev);
++ err = pm_runtime_resume_and_get(ce->dev);
+ if (err < 0)
+ goto error_alg;
+
+diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c
+index ed2a69f82e1c1..7c355bc2fb066 100644
+--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c
++++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c
+@@ -351,7 +351,7 @@ int sun8i_ss_cipher_init(struct crypto_tfm *tfm)
+ op->enginectx.op.prepare_request = NULL;
+ op->enginectx.op.unprepare_request = NULL;
+
+- err = pm_runtime_get_sync(op->ss->dev);
++ err = pm_runtime_resume_and_get(op->ss->dev);
+ if (err < 0) {
+ dev_err(op->ss->dev, "pm error %d\n", err);
+ goto error_pm;
+diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c
+index e0ddc684798dc..80e89066dbd1a 100644
+--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c
++++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c
+@@ -753,7 +753,7 @@ static int sun8i_ss_probe(struct platform_device *pdev)
+ if (err)
+ goto error_alg;
+
+- err = pm_runtime_get_sync(ss->dev);
++ err = pm_runtime_resume_and_get(ss->dev);
+ if (err < 0)
+ goto error_alg;
+
+diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.c b/drivers/crypto/hisilicon/sec2/sec_crypto.c
+index 2eaa516b32311..8adcbb3271267 100644
+--- a/drivers/crypto/hisilicon/sec2/sec_crypto.c
++++ b/drivers/crypto/hisilicon/sec2/sec_crypto.c
+@@ -546,7 +546,7 @@ static int sec_skcipher_init(struct crypto_skcipher *tfm)
+ crypto_skcipher_set_reqsize(tfm, sizeof(struct sec_req));
+ ctx->c_ctx.ivsize = crypto_skcipher_ivsize(tfm);
+ if (ctx->c_ctx.ivsize > SEC_IV_SIZE) {
+- dev_err(SEC_CTX_DEV(ctx), "get error skcipher iv size!\n");
++ pr_err("get error skcipher iv size!\n");
+ return -EINVAL;
+ }
+
+diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
+index a45bdcf3026df..0dd4c6b157de9 100644
+--- a/drivers/crypto/omap-aes.c
++++ b/drivers/crypto/omap-aes.c
+@@ -103,9 +103,8 @@ static int omap_aes_hw_init(struct omap_aes_dev *dd)
+ dd->err = 0;
+ }
+
+- err = pm_runtime_get_sync(dd->dev);
++ err = pm_runtime_resume_and_get(dd->dev);
+ if (err < 0) {
+- pm_runtime_put_noidle(dd->dev);
+ dev_err(dd->dev, "failed to get sync: %d\n", err);
+ return err;
+ }
+@@ -1134,7 +1133,7 @@ static int omap_aes_probe(struct platform_device *pdev)
+ pm_runtime_set_autosuspend_delay(dev, DEFAULT_AUTOSUSPEND_DELAY);
+
+ pm_runtime_enable(dev);
+- err = pm_runtime_get_sync(dev);
++ err = pm_runtime_resume_and_get(dev);
+ if (err < 0) {
+ dev_err(dev, "%s: failed to get_sync(%d)\n",
+ __func__, err);
+@@ -1303,7 +1302,7 @@ static int omap_aes_suspend(struct device *dev)
+
+ static int omap_aes_resume(struct device *dev)
+ {
+- pm_runtime_get_sync(dev);
++ pm_runtime_resume_and_get(dev);
+ return 0;
+ }
+ #endif
+diff --git a/drivers/crypto/qat/qat_common/qat_algs.c b/drivers/crypto/qat/qat_common/qat_algs.c
+index ff78c73c47e38..ea1c6899290d7 100644
+--- a/drivers/crypto/qat/qat_common/qat_algs.c
++++ b/drivers/crypto/qat/qat_common/qat_algs.c
+@@ -719,7 +719,7 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst,
+ struct qat_alg_buf_list *bufl;
+ struct qat_alg_buf_list *buflout = NULL;
+ dma_addr_t blp;
+- dma_addr_t bloutp = 0;
++ dma_addr_t bloutp;
+ struct scatterlist *sg;
+ size_t sz_out, sz = struct_size(bufl, bufers, n + 1);
+
+@@ -731,6 +731,9 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst,
+ if (unlikely(!bufl))
+ return -ENOMEM;
+
++ for_each_sg(sgl, sg, n, i)
++ bufl->bufers[i].addr = DMA_MAPPING_ERROR;
++
+ blp = dma_map_single(dev, bufl, sz, DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(dev, blp)))
+ goto err_in;
+@@ -764,10 +767,14 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst,
+ dev_to_node(&GET_DEV(inst->accel_dev)));
+ if (unlikely(!buflout))
+ goto err_in;
++
++ bufers = buflout->bufers;
++ for_each_sg(sglout, sg, n, i)
++ bufers[i].addr = DMA_MAPPING_ERROR;
++
+ bloutp = dma_map_single(dev, buflout, sz_out, DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(dev, bloutp)))
+ goto err_out;
+- bufers = buflout->bufers;
+ for_each_sg(sglout, sg, n, i) {
+ int y = sg_nctr;
+
+diff --git a/drivers/crypto/sa2ul.c b/drivers/crypto/sa2ul.c
+index f300b0a5958a5..d7b1628fb4848 100644
+--- a/drivers/crypto/sa2ul.c
++++ b/drivers/crypto/sa2ul.c
+@@ -2350,7 +2350,7 @@ static int sa_ul_probe(struct platform_device *pdev)
+ dev_set_drvdata(sa_k3_dev, dev_data);
+
+ pm_runtime_enable(dev);
+- ret = pm_runtime_get_sync(dev);
++ ret = pm_runtime_resume_and_get(dev);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "%s: failed to get sync: %d\n", __func__,
+ ret);
+diff --git a/drivers/crypto/stm32/stm32-cryp.c b/drivers/crypto/stm32/stm32-cryp.c
+index 2a4793176c713..7389a0536ff02 100644
+--- a/drivers/crypto/stm32/stm32-cryp.c
++++ b/drivers/crypto/stm32/stm32-cryp.c
+@@ -542,7 +542,7 @@ static int stm32_cryp_hw_init(struct stm32_cryp *cryp)
+ int ret;
+ u32 cfg, hw_mode;
+
+- pm_runtime_get_sync(cryp->dev);
++ pm_runtime_resume_and_get(cryp->dev);
+
+ /* Disable interrupt */
+ stm32_cryp_write(cryp, CRYP_IMSCR, 0);
+@@ -2043,7 +2043,7 @@ static int stm32_cryp_remove(struct platform_device *pdev)
+ if (!cryp)
+ return -ENODEV;
+
+- ret = pm_runtime_get_sync(cryp->dev);
++ ret = pm_runtime_resume_and_get(cryp->dev);
+ if (ret < 0)
+ return ret;
+
+diff --git a/drivers/crypto/stm32/stm32-hash.c b/drivers/crypto/stm32/stm32-hash.c
+index 7ac0573ef6630..389de9e3302d5 100644
+--- a/drivers/crypto/stm32/stm32-hash.c
++++ b/drivers/crypto/stm32/stm32-hash.c
+@@ -813,7 +813,7 @@ static void stm32_hash_finish_req(struct ahash_request *req, int err)
+ static int stm32_hash_hw_init(struct stm32_hash_dev *hdev,
+ struct stm32_hash_request_ctx *rctx)
+ {
+- pm_runtime_get_sync(hdev->dev);
++ pm_runtime_resume_and_get(hdev->dev);
+
+ if (!(HASH_FLAGS_INIT & hdev->flags)) {
+ stm32_hash_write(hdev, HASH_CR, HASH_CR_INIT);
+@@ -962,7 +962,7 @@ static int stm32_hash_export(struct ahash_request *req, void *out)
+ u32 *preg;
+ unsigned int i;
+
+- pm_runtime_get_sync(hdev->dev);
++ pm_runtime_resume_and_get(hdev->dev);
+
+ while ((stm32_hash_read(hdev, HASH_SR) & HASH_SR_BUSY))
+ cpu_relax();
+@@ -1000,7 +1000,7 @@ static int stm32_hash_import(struct ahash_request *req, const void *in)
+
+ preg = rctx->hw_context;
+
+- pm_runtime_get_sync(hdev->dev);
++ pm_runtime_resume_and_get(hdev->dev);
+
+ stm32_hash_write(hdev, HASH_IMR, *preg++);
+ stm32_hash_write(hdev, HASH_STR, *preg++);
+@@ -1566,7 +1566,7 @@ static int stm32_hash_remove(struct platform_device *pdev)
+ if (!hdev)
+ return -ENODEV;
+
+- ret = pm_runtime_get_sync(hdev->dev);
++ ret = pm_runtime_resume_and_get(hdev->dev);
+ if (ret < 0)
+ return ret;
+
+diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c
+index aae82db542a5e..76aacbac5869d 100644
+--- a/drivers/extcon/extcon-arizona.c
++++ b/drivers/extcon/extcon-arizona.c
+@@ -601,7 +601,7 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data)
+ struct arizona *arizona = info->arizona;
+ int id_gpio = arizona->pdata.hpdet_id_gpio;
+ unsigned int report = EXTCON_JACK_HEADPHONE;
+- int ret, reading;
++ int ret, reading, state;
+ bool mic = false;
+
+ mutex_lock(&info->lock);
+@@ -614,12 +614,11 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data)
+ }
+
+ /* If the cable was removed while measuring ignore the result */
+- ret = extcon_get_state(info->edev, EXTCON_MECHANICAL);
+- if (ret < 0) {
+- dev_err(arizona->dev, "Failed to check cable state: %d\n",
+- ret);
++ state = extcon_get_state(info->edev, EXTCON_MECHANICAL);
++ if (state < 0) {
++ dev_err(arizona->dev, "Failed to check cable state: %d\n", state);
+ goto out;
+- } else if (!ret) {
++ } else if (!state) {
+ dev_dbg(arizona->dev, "Ignoring HPDET for removed cable\n");
+ goto done;
+ }
+@@ -667,7 +666,7 @@ done:
+ gpio_set_value_cansleep(id_gpio, 0);
+
+ /* If we have a mic then reenable MICDET */
+- if (mic || info->mic)
++ if (state && (mic || info->mic))
+ arizona_start_mic(info);
+
+ if (info->hpdet_active) {
+@@ -675,7 +674,9 @@ done:
+ info->hpdet_active = false;
+ }
+
+- info->hpdet_done = true;
++ /* Do not set hp_det done when the cable has been unplugged */
++ if (state)
++ info->hpdet_done = true;
+
+ out:
+ mutex_unlock(&info->lock);
+@@ -1759,25 +1760,6 @@ static int arizona_extcon_remove(struct platform_device *pdev)
+ bool change;
+ int ret;
+
+- ret = regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1,
+- ARIZONA_MICD_ENA, 0,
+- &change);
+- if (ret < 0) {
+- dev_err(&pdev->dev, "Failed to disable micd on remove: %d\n",
+- ret);
+- } else if (change) {
+- regulator_disable(info->micvdd);
+- pm_runtime_put(info->dev);
+- }
+-
+- gpiod_put(info->micd_pol_gpio);
+-
+- pm_runtime_disable(&pdev->dev);
+-
+- regmap_update_bits(arizona->regmap,
+- ARIZONA_MICD_CLAMP_CONTROL,
+- ARIZONA_MICD_CLAMP_MODE_MASK, 0);
+-
+ if (info->micd_clamp) {
+ jack_irq_rise = ARIZONA_IRQ_MICD_CLAMP_RISE;
+ jack_irq_fall = ARIZONA_IRQ_MICD_CLAMP_FALL;
+@@ -1793,10 +1775,31 @@ static int arizona_extcon_remove(struct platform_device *pdev)
+ arizona_free_irq(arizona, jack_irq_rise, info);
+ arizona_free_irq(arizona, jack_irq_fall, info);
+ cancel_delayed_work_sync(&info->hpdet_work);
++ cancel_delayed_work_sync(&info->micd_detect_work);
++ cancel_delayed_work_sync(&info->micd_timeout_work);
++
++ ret = regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1,
++ ARIZONA_MICD_ENA, 0,
++ &change);
++ if (ret < 0) {
++ dev_err(&pdev->dev, "Failed to disable micd on remove: %d\n",
++ ret);
++ } else if (change) {
++ regulator_disable(info->micvdd);
++ pm_runtime_put(info->dev);
++ }
++
++ regmap_update_bits(arizona->regmap,
++ ARIZONA_MICD_CLAMP_CONTROL,
++ ARIZONA_MICD_CLAMP_MODE_MASK, 0);
+ regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE,
+ ARIZONA_JD1_ENA, 0);
+ arizona_clk32k_disable(arizona);
+
++ gpiod_put(info->micd_pol_gpio);
++
++ pm_runtime_disable(&pdev->dev);
++
+ return 0;
+ }
+
+diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
+index c23466e05e60d..d0537573501e9 100644
+--- a/drivers/firmware/efi/libstub/Makefile
++++ b/drivers/firmware/efi/libstub/Makefile
+@@ -13,7 +13,8 @@ cflags-$(CONFIG_X86) += -m$(BITS) -D__KERNEL__ \
+ -Wno-pointer-sign \
+ $(call cc-disable-warning, address-of-packed-member) \
+ $(call cc-disable-warning, gnu) \
+- -fno-asynchronous-unwind-tables
++ -fno-asynchronous-unwind-tables \
++ $(CLANG_FLAGS)
+
+ # arm64 uses the full KBUILD_CFLAGS so it's necessary to explicitly
+ # disable the stackleak plugin
+diff --git a/drivers/fpga/dfl-pci.c b/drivers/fpga/dfl-pci.c
+index 04e47e266f26d..b44523ea8c91a 100644
+--- a/drivers/fpga/dfl-pci.c
++++ b/drivers/fpga/dfl-pci.c
+@@ -69,14 +69,16 @@ static void cci_pci_free_irq(struct pci_dev *pcidev)
+ }
+
+ /* PCI Device ID */
+-#define PCIE_DEVICE_ID_PF_INT_5_X 0xBCBD
+-#define PCIE_DEVICE_ID_PF_INT_6_X 0xBCC0
+-#define PCIE_DEVICE_ID_PF_DSC_1_X 0x09C4
+-#define PCIE_DEVICE_ID_INTEL_PAC_N3000 0x0B30
++#define PCIE_DEVICE_ID_PF_INT_5_X 0xBCBD
++#define PCIE_DEVICE_ID_PF_INT_6_X 0xBCC0
++#define PCIE_DEVICE_ID_PF_DSC_1_X 0x09C4
++#define PCIE_DEVICE_ID_INTEL_PAC_N3000 0x0B30
++#define PCIE_DEVICE_ID_INTEL_PAC_D5005 0x0B2B
+ /* VF Device */
+-#define PCIE_DEVICE_ID_VF_INT_5_X 0xBCBF
+-#define PCIE_DEVICE_ID_VF_INT_6_X 0xBCC1
+-#define PCIE_DEVICE_ID_VF_DSC_1_X 0x09C5
++#define PCIE_DEVICE_ID_VF_INT_5_X 0xBCBF
++#define PCIE_DEVICE_ID_VF_INT_6_X 0xBCC1
++#define PCIE_DEVICE_ID_VF_DSC_1_X 0x09C5
++#define PCIE_DEVICE_ID_INTEL_PAC_D5005_VF 0x0B2C
+
+ static struct pci_device_id cci_pcie_id_tbl[] = {
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_INT_5_X),},
+@@ -86,6 +88,8 @@ static struct pci_device_id cci_pcie_id_tbl[] = {
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_DSC_1_X),},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_DSC_1_X),},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_PAC_N3000),},
++ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_PAC_D5005),},
++ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_PAC_D5005_VF),},
+ {0,}
+ };
+ MODULE_DEVICE_TABLE(pci, cci_pcie_id_tbl);
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+index 8a5a8ff5d3629..5eee251e3335b 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+@@ -3613,6 +3613,7 @@ void amdgpu_device_fini(struct amdgpu_device *adev)
+ {
+ dev_info(adev->dev, "amdgpu: finishing device.\n");
+ flush_delayed_work(&adev->delayed_init_work);
++ ttm_bo_lock_delayed_workqueue(&adev->mman.bdev);
+ adev->shutdown = true;
+
+ kfree(adev->pci_state);
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
+index d56f4023ebb31..7e8e46c39dbd3 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
+@@ -533,6 +533,8 @@ void amdgpu_fence_driver_fini(struct amdgpu_device *adev)
+
+ if (!ring || !ring->fence_drv.initialized)
+ continue;
++ if (!ring->no_scheduler)
++ drm_sched_fini(&ring->sched);
+ r = amdgpu_fence_wait_empty(ring);
+ if (r) {
+ /* no need to trigger GPU reset as we are unloading */
+@@ -541,8 +543,7 @@ void amdgpu_fence_driver_fini(struct amdgpu_device *adev)
+ if (ring->fence_drv.irq_src)
+ amdgpu_irq_put(adev, ring->fence_drv.irq_src,
+ ring->fence_drv.irq_type);
+- if (!ring->no_scheduler)
+- drm_sched_fini(&ring->sched);
++
+ del_timer_sync(&ring->fence_drv.fallback_timer);
+ for (j = 0; j <= ring->fence_drv.num_fences_mask; ++j)
+ dma_fence_put(ring->fence_drv.fences[j]);
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
+index afbbec82a289c..9be945d8e72f8 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
+@@ -535,7 +535,7 @@ void amdgpu_irq_gpu_reset_resume_helper(struct amdgpu_device *adev)
+ for (j = 0; j < AMDGPU_MAX_IRQ_SRC_ID; ++j) {
+ struct amdgpu_irq_src *src = adev->irq.client[i].sources[j];
+
+- if (!src)
++ if (!src || !src->funcs || !src->funcs->set)
+ continue;
+ for (k = 0; k < src->num_types; k++)
+ amdgpu_irq_update(adev, src, k);
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+index 5efa331e3ee82..383c178cf0746 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+@@ -942,7 +942,7 @@ static void amdgpu_ttm_tt_unpin_userptr(struct ttm_bo_device *bdev,
+ DMA_BIDIRECTIONAL : DMA_TO_DEVICE;
+
+ /* double check that we don't free the table twice */
+- if (!ttm->sg->sgl)
++ if (!ttm->sg || !ttm->sg->sgl)
+ return;
+
+ /* unmap the pages mapped to the device */
+@@ -1162,13 +1162,13 @@ static void amdgpu_ttm_backend_unbind(struct ttm_bo_device *bdev,
+ struct amdgpu_ttm_tt *gtt = (void *)ttm;
+ int r;
+
+- if (!gtt->bound)
+- return;
+-
+ /* if the pages have userptr pinning then clear that first */
+ if (gtt->userptr)
+ amdgpu_ttm_tt_unpin_userptr(bdev, ttm);
+
++ if (!gtt->bound)
++ return;
++
+ if (gtt->offset == AMDGPU_BO_INVALID_OFFSET)
+ return;
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
+index e2ed4689118a9..c6dbc08016045 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
+@@ -259,7 +259,7 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev)
+ if ((adev->asic_type == CHIP_POLARIS10 ||
+ adev->asic_type == CHIP_POLARIS11) &&
+ (adev->uvd.fw_version < FW_1_66_16))
+- DRM_ERROR("POLARIS10/11 UVD firmware version %hu.%hu is too old.\n",
++ DRM_ERROR("POLARIS10/11 UVD firmware version %u.%u is too old.\n",
+ version_major, version_minor);
+ } else {
+ unsigned int enc_major, enc_minor, dec_minor;
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c
+index 659b385b27b5a..4d3a24fdeb9ca 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c
+@@ -468,15 +468,22 @@ int amdgpu_xgmi_update_topology(struct amdgpu_hive_info *hive, struct amdgpu_dev
+ }
+
+
++/*
++ * NOTE psp_xgmi_node_info.num_hops layout is as follows:
++ * num_hops[7:6] = link type (0 = xGMI2, 1 = xGMI3, 2/3 = reserved)
++ * num_hops[5:3] = reserved
++ * num_hops[2:0] = number of hops
++ */
+ int amdgpu_xgmi_get_hops_count(struct amdgpu_device *adev,
+ struct amdgpu_device *peer_adev)
+ {
+ struct psp_xgmi_topology_info *top = &adev->psp.xgmi_context.top_info;
++ uint8_t num_hops_mask = 0x7;
+ int i;
+
+ for (i = 0 ; i < top->num_nodes; ++i)
+ if (top->nodes[i].node_id == peer_adev->gmc.xgmi.node_id)
+- return top->nodes[i].num_hops;
++ return top->nodes[i].num_hops & num_hops_mask;
+ return -EINVAL;
+ }
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
+index 88626d83e07be..ca8efa5c6978d 100644
+--- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
++++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
+@@ -220,10 +220,8 @@ static int vega10_ih_enable_ring(struct amdgpu_device *adev,
+ tmp = vega10_ih_rb_cntl(ih, tmp);
+ if (ih == &adev->irq.ih)
+ tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RPTR_REARM, !!adev->irq.msi_enabled);
+- if (ih == &adev->irq.ih1) {
+- tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_ENABLE, 0);
++ if (ih == &adev->irq.ih1)
+ tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RB_FULL_DRAIN_ENABLE, 1);
+- }
+ if (amdgpu_sriov_vf(adev)) {
+ if (psp_reg_program(&adev->psp, ih_regs->psp_reg_id, tmp)) {
+ dev_err(adev->dev, "PSP program IH_RB_CNTL failed!\n");
+@@ -265,7 +263,6 @@ static int vega10_ih_irq_init(struct amdgpu_device *adev)
+ u32 ih_chicken;
+ int ret;
+ int i;
+- u32 tmp;
+
+ /* disable irqs */
+ ret = vega10_ih_toggle_interrupts(adev, false);
+@@ -291,15 +288,6 @@ static int vega10_ih_irq_init(struct amdgpu_device *adev)
+ }
+ }
+
+- tmp = RREG32_SOC15(OSSSYS, 0, mmIH_STORM_CLIENT_LIST_CNTL);
+- tmp = REG_SET_FIELD(tmp, IH_STORM_CLIENT_LIST_CNTL,
+- CLIENT18_IS_STORM_CLIENT, 1);
+- WREG32_SOC15(OSSSYS, 0, mmIH_STORM_CLIENT_LIST_CNTL, tmp);
+-
+- tmp = RREG32_SOC15(OSSSYS, 0, mmIH_INT_FLOOD_CNTL);
+- tmp = REG_SET_FIELD(tmp, IH_INT_FLOOD_CNTL, FLOOD_CNTL_ENABLE, 1);
+- WREG32_SOC15(OSSSYS, 0, mmIH_INT_FLOOD_CNTL, tmp);
+-
+ pci_set_master(adev->pdev);
+
+ /* enable interrupts */
+@@ -345,11 +333,17 @@ static u32 vega10_ih_get_wptr(struct amdgpu_device *adev,
+ u32 wptr, tmp;
+ struct amdgpu_ih_regs *ih_regs;
+
+- wptr = le32_to_cpu(*ih->wptr_cpu);
+- ih_regs = &ih->ih_regs;
++ if (ih == &adev->irq.ih) {
++ /* Only ring0 supports writeback. On other rings fall back
++ * to register-based code with overflow checking below.
++ */
++ wptr = le32_to_cpu(*ih->wptr_cpu);
+
+- if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW))
+- goto out;
++ if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW))
++ goto out;
++ }
++
++ ih_regs = &ih->ih_regs;
+
+ /* Double check that the overflow wasn't already cleared. */
+ wptr = RREG32_NO_KIQ(ih_regs->ih_rb_wptr);
+@@ -440,15 +434,11 @@ static int vega10_ih_self_irq(struct amdgpu_device *adev,
+ struct amdgpu_irq_src *source,
+ struct amdgpu_iv_entry *entry)
+ {
+- uint32_t wptr = cpu_to_le32(entry->src_data[0]);
+-
+ switch (entry->ring_id) {
+ case 1:
+- *adev->irq.ih1.wptr_cpu = wptr;
+ schedule_work(&adev->irq.ih1_work);
+ break;
+ case 2:
+- *adev->irq.ih2.wptr_cpu = wptr;
+ schedule_work(&adev->irq.ih2_work);
+ break;
+ default: break;
+diff --git a/drivers/gpu/drm/amd/amdgpu/vega20_ih.c b/drivers/gpu/drm/amd/amdgpu/vega20_ih.c
+index 5a3c867d58811..86dcf448e0c22 100644
+--- a/drivers/gpu/drm/amd/amdgpu/vega20_ih.c
++++ b/drivers/gpu/drm/amd/amdgpu/vega20_ih.c
+@@ -104,6 +104,8 @@ static int vega20_ih_toggle_ring_interrupts(struct amdgpu_device *adev,
+
+ tmp = RREG32(ih_regs->ih_rb_cntl);
+ tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RB_ENABLE, (enable ? 1 : 0));
++ tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RB_GPU_TS_ENABLE, 1);
++
+ /* enable_intr field is only valid in ring0 */
+ if (ih == &adev->irq.ih)
+ tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, ENABLE_INTR, (enable ? 1 : 0));
+@@ -220,10 +222,8 @@ static int vega20_ih_enable_ring(struct amdgpu_device *adev,
+ tmp = vega20_ih_rb_cntl(ih, tmp);
+ if (ih == &adev->irq.ih)
+ tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RPTR_REARM, !!adev->irq.msi_enabled);
+- if (ih == &adev->irq.ih1) {
+- tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_ENABLE, 0);
++ if (ih == &adev->irq.ih1)
+ tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RB_FULL_DRAIN_ENABLE, 1);
+- }
+ if (amdgpu_sriov_vf(adev)) {
+ if (psp_reg_program(&adev->psp, ih_regs->psp_reg_id, tmp)) {
+ dev_err(adev->dev, "PSP program IH_RB_CNTL failed!\n");
+@@ -297,7 +297,6 @@ static int vega20_ih_irq_init(struct amdgpu_device *adev)
+ u32 ih_chicken;
+ int ret;
+ int i;
+- u32 tmp;
+
+ /* disable irqs */
+ ret = vega20_ih_toggle_interrupts(adev, false);
+@@ -326,15 +325,6 @@ static int vega20_ih_irq_init(struct amdgpu_device *adev)
+ }
+ }
+
+- tmp = RREG32_SOC15(OSSSYS, 0, mmIH_STORM_CLIENT_LIST_CNTL);
+- tmp = REG_SET_FIELD(tmp, IH_STORM_CLIENT_LIST_CNTL,
+- CLIENT18_IS_STORM_CLIENT, 1);
+- WREG32_SOC15(OSSSYS, 0, mmIH_STORM_CLIENT_LIST_CNTL, tmp);
+-
+- tmp = RREG32_SOC15(OSSSYS, 0, mmIH_INT_FLOOD_CNTL);
+- tmp = REG_SET_FIELD(tmp, IH_INT_FLOOD_CNTL, FLOOD_CNTL_ENABLE, 1);
+- WREG32_SOC15(OSSSYS, 0, mmIH_INT_FLOOD_CNTL, tmp);
+-
+ pci_set_master(adev->pdev);
+
+ /* enable interrupts */
+@@ -380,11 +370,17 @@ static u32 vega20_ih_get_wptr(struct amdgpu_device *adev,
+ u32 wptr, tmp;
+ struct amdgpu_ih_regs *ih_regs;
+
+- wptr = le32_to_cpu(*ih->wptr_cpu);
+- ih_regs = &ih->ih_regs;
++ if (ih == &adev->irq.ih) {
++ /* Only ring0 supports writeback. On other rings fall back
++ * to register-based code with overflow checking below.
++ */
++ wptr = le32_to_cpu(*ih->wptr_cpu);
+
+- if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW))
+- goto out;
++ if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW))
++ goto out;
++ }
++
++ ih_regs = &ih->ih_regs;
+
+ /* Double check that the overflow wasn't already cleared. */
+ wptr = RREG32_NO_KIQ(ih_regs->ih_rb_wptr);
+@@ -476,15 +472,11 @@ static int vega20_ih_self_irq(struct amdgpu_device *adev,
+ struct amdgpu_irq_src *source,
+ struct amdgpu_iv_entry *entry)
+ {
+- uint32_t wptr = cpu_to_le32(entry->src_data[0]);
+-
+ switch (entry->ring_id) {
+ case 1:
+- *adev->irq.ih1.wptr_cpu = wptr;
+ schedule_work(&adev->irq.ih1_work);
+ break;
+ case 2:
+- *adev->irq.ih2.wptr_cpu = wptr;
+ schedule_work(&adev->irq.ih2_work);
+ break;
+ default: break;
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c b/drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c
+index 511712c2e382d..673d5e34f213c 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c
+@@ -33,6 +33,11 @@ static int kfd_debugfs_open(struct inode *inode, struct file *file)
+
+ return single_open(file, show, NULL);
+ }
++static int kfd_debugfs_hang_hws_read(struct seq_file *m, void *data)
++{
++ seq_printf(m, "echo gpu_id > hang_hws\n");
++ return 0;
++}
+
+ static ssize_t kfd_debugfs_hang_hws_write(struct file *file,
+ const char __user *user_buf, size_t size, loff_t *ppos)
+@@ -94,7 +99,7 @@ void kfd_debugfs_init(void)
+ debugfs_create_file("rls", S_IFREG | 0444, debugfs_root,
+ kfd_debugfs_rls_by_device, &kfd_debugfs_fops);
+ debugfs_create_file("hang_hws", S_IFREG | 0200, debugfs_root,
+- NULL, &kfd_debugfs_hang_hws_fops);
++ kfd_debugfs_hang_hws_read, &kfd_debugfs_hang_hws_fops);
+ }
+
+ void kfd_debugfs_fini(void)
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+index 4598a9a581251..a4266c4bca135 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+@@ -1128,6 +1128,9 @@ static int set_sched_resources(struct device_queue_manager *dqm)
+
+ static int initialize_cpsch(struct device_queue_manager *dqm)
+ {
++ uint64_t num_sdma_queues;
++ uint64_t num_xgmi_sdma_queues;
++
+ pr_debug("num of pipes: %d\n", get_pipes_per_mec(dqm));
+
+ mutex_init(&dqm->lock_hidden);
+@@ -1136,8 +1139,18 @@ static int initialize_cpsch(struct device_queue_manager *dqm)
+ dqm->active_cp_queue_count = 0;
+ dqm->gws_queue_count = 0;
+ dqm->active_runlist = false;
+- dqm->sdma_bitmap = ~0ULL >> (64 - get_num_sdma_queues(dqm));
+- dqm->xgmi_sdma_bitmap = ~0ULL >> (64 - get_num_xgmi_sdma_queues(dqm));
++
++ num_sdma_queues = get_num_sdma_queues(dqm);
++ if (num_sdma_queues >= BITS_PER_TYPE(dqm->sdma_bitmap))
++ dqm->sdma_bitmap = ULLONG_MAX;
++ else
++ dqm->sdma_bitmap = (BIT_ULL(num_sdma_queues) - 1);
++
++ num_xgmi_sdma_queues = get_num_xgmi_sdma_queues(dqm);
++ if (num_xgmi_sdma_queues >= BITS_PER_TYPE(dqm->xgmi_sdma_bitmap))
++ dqm->xgmi_sdma_bitmap = ULLONG_MAX;
++ else
++ dqm->xgmi_sdma_bitmap = (BIT_ULL(num_xgmi_sdma_queues) - 1);
+
+ INIT_WORK(&dqm->hw_exception_work, kfd_process_hw_exception);
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index d699a5cf6c118..29ca1708458c1 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -1191,6 +1191,15 @@ static void amdgpu_dm_fini(struct amdgpu_device *adev)
+ if (adev->dm.dc)
+ dc_deinit_callbacks(adev->dm.dc);
+ #endif
++
++#if defined(CONFIG_DRM_AMD_DC_DCN)
++ if (adev->dm.vblank_workqueue) {
++ adev->dm.vblank_workqueue->dm = NULL;
++ kfree(adev->dm.vblank_workqueue);
++ adev->dm.vblank_workqueue = NULL;
++ }
++#endif
++
+ if (adev->dm.dc->ctx->dmub_srv) {
+ dc_dmub_srv_destroy(&adev->dm.dc->ctx->dmub_srv);
+ adev->dm.dc->ctx->dmub_srv = NULL;
+@@ -5863,6 +5872,15 @@ create_validate_stream_for_sink(struct amdgpu_dm_connector *aconnector,
+
+ } while (stream == NULL && requested_bpc >= 6);
+
++ if (dc_result == DC_FAIL_ENC_VALIDATE && !aconnector->force_yuv420_output) {
++ DRM_DEBUG_KMS("Retry forcing YCbCr420 encoding\n");
++
++ aconnector->force_yuv420_output = true;
++ stream = create_validate_stream_for_sink(aconnector, drm_mode,
++ dm_state, old_stream);
++ aconnector->force_yuv420_output = false;
++ }
++
+ return stream;
+ }
+
+@@ -7417,10 +7435,6 @@ static int get_cursor_position(struct drm_plane *plane, struct drm_crtc *crtc,
+ int x, y;
+ int xorigin = 0, yorigin = 0;
+
+- position->enable = false;
+- position->x = 0;
+- position->y = 0;
+-
+ if (!crtc || !plane->state->fb)
+ return 0;
+
+@@ -7467,7 +7481,7 @@ static void handle_cursor_update(struct drm_plane *plane,
+ struct dm_crtc_state *crtc_state = crtc ? to_dm_crtc_state(crtc->state) : NULL;
+ struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
+ uint64_t address = afb ? afb->address : 0;
+- struct dc_cursor_position position;
++ struct dc_cursor_position position = {0};
+ struct dc_cursor_attributes attributes;
+ int ret;
+
+@@ -9383,7 +9397,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
+ }
+
+ #if defined(CONFIG_DRM_AMD_DC_DCN)
+- if (adev->asic_type >= CHIP_NAVI10) {
++ if (dc_resource_is_dsc_encoding_supported(dc)) {
+ for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
+ if (drm_atomic_crtc_needs_modeset(new_crtc_state)) {
+ ret = add_affected_mst_dsc_crtcs(state, crtc);
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+index 8bfe901cf2374..52cc817052802 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+@@ -68,18 +68,6 @@ struct common_irq_params {
+ enum dc_irq_source irq_src;
+ };
+
+-/**
+- * struct irq_list_head - Linked-list for low context IRQ handlers.
+- *
+- * @head: The list_head within &struct handler_data
+- * @work: A work_struct containing the deferred handler work
+- */
+-struct irq_list_head {
+- struct list_head head;
+- /* In case this interrupt needs post-processing, 'work' will be queued*/
+- struct work_struct work;
+-};
+-
+ /**
+ * struct dm_compressor_info - Buffer info used by frame buffer compression
+ * @cpu_addr: MMIO cpu addr
+@@ -293,7 +281,7 @@ struct amdgpu_display_manager {
+ * Note that handlers are called in the same order as they were
+ * registered (FIFO).
+ */
+- struct irq_list_head irq_handler_list_low_tab[DAL_IRQ_SOURCES_NUMBER];
++ struct list_head irq_handler_list_low_tab[DAL_IRQ_SOURCES_NUMBER];
+
+ /**
+ * @irq_handler_list_high_tab:
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+index 360952129b6d5..29139b34dbe2b 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+@@ -150,7 +150,7 @@ static int parse_write_buffer_into_params(char *wr_buf, uint32_t wr_buf_size,
+ *
+ * --- to get dp configuration
+ *
+- * cat link_settings
++ * cat /sys/kernel/debug/dri/0/DP-x/link_settings
+ *
+ * It will list current, verified, reported, preferred dp configuration.
+ * current -- for current video mode
+@@ -163,7 +163,7 @@ static int parse_write_buffer_into_params(char *wr_buf, uint32_t wr_buf_size,
+ * echo <lane_count> <link_rate> > link_settings
+ *
+ * for example, to force to 2 lane, 2.7GHz,
+- * echo 4 0xa > link_settings
++ * echo 4 0xa > /sys/kernel/debug/dri/0/DP-x/link_settings
+ *
+ * spread_spectrum could not be changed dynamically.
+ *
+@@ -171,7 +171,7 @@ static int parse_write_buffer_into_params(char *wr_buf, uint32_t wr_buf_size,
+ * done. please check link settings after force operation to see if HW get
+ * programming.
+ *
+- * cat link_settings
++ * cat /sys/kernel/debug/dri/0/DP-x/link_settings
+ *
+ * check current and preferred settings.
+ *
+@@ -255,7 +255,7 @@ static ssize_t dp_link_settings_write(struct file *f, const char __user *buf,
+ int max_param_num = 2;
+ uint8_t param_nums = 0;
+ long param[2];
+- bool valid_input = false;
++ bool valid_input = true;
+
+ if (size == 0)
+ return -EINVAL;
+@@ -282,9 +282,9 @@ static ssize_t dp_link_settings_write(struct file *f, const char __user *buf,
+ case LANE_COUNT_ONE:
+ case LANE_COUNT_TWO:
+ case LANE_COUNT_FOUR:
+- valid_input = true;
+ break;
+ default:
++ valid_input = false;
+ break;
+ }
+
+@@ -294,9 +294,9 @@ static ssize_t dp_link_settings_write(struct file *f, const char __user *buf,
+ case LINK_RATE_RBR2:
+ case LINK_RATE_HIGH2:
+ case LINK_RATE_HIGH3:
+- valid_input = true;
+ break;
+ default:
++ valid_input = false;
+ break;
+ }
+
+@@ -310,10 +310,11 @@ static ssize_t dp_link_settings_write(struct file *f, const char __user *buf,
+ * spread spectrum will not be changed
+ */
+ prefer_link_settings.link_spread = link->cur_link_settings.link_spread;
++ prefer_link_settings.use_link_rate_set = false;
+ prefer_link_settings.lane_count = param[0];
+ prefer_link_settings.link_rate = param[1];
+
+- dc_link_set_preferred_link_settings(dc, &prefer_link_settings, link);
++ dc_link_set_preferred_training_settings(dc, &prefer_link_settings, NULL, link, true);
+
+ kfree(wr_buf);
+ return size;
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c
+index e0000c180ed1f..8ce10d0973c5b 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c
+@@ -82,6 +82,7 @@ struct amdgpu_dm_irq_handler_data {
+ struct amdgpu_display_manager *dm;
+ /* DAL irq source which registered for this interrupt. */
+ enum dc_irq_source irq_source;
++ struct work_struct work;
+ };
+
+ #define DM_IRQ_TABLE_LOCK(adev, flags) \
+@@ -111,20 +112,10 @@ static void init_handler_common_data(struct amdgpu_dm_irq_handler_data *hcd,
+ */
+ static void dm_irq_work_func(struct work_struct *work)
+ {
+- struct irq_list_head *irq_list_head =
+- container_of(work, struct irq_list_head, work);
+- struct list_head *handler_list = &irq_list_head->head;
+- struct amdgpu_dm_irq_handler_data *handler_data;
+-
+- list_for_each_entry(handler_data, handler_list, list) {
+- DRM_DEBUG_KMS("DM_IRQ: work_func: for dal_src=%d\n",
+- handler_data->irq_source);
++ struct amdgpu_dm_irq_handler_data *handler_data =
++ container_of(work, struct amdgpu_dm_irq_handler_data, work);
+
+- DRM_DEBUG_KMS("DM_IRQ: schedule_work: for dal_src=%d\n",
+- handler_data->irq_source);
+-
+- handler_data->handler(handler_data->handler_arg);
+- }
++ handler_data->handler(handler_data->handler_arg);
+
+ /* Call a DAL subcomponent which registered for interrupt notification
+ * at INTERRUPT_LOW_IRQ_CONTEXT.
+@@ -156,7 +147,7 @@ static struct list_head *remove_irq_handler(struct amdgpu_device *adev,
+ break;
+ case INTERRUPT_LOW_IRQ_CONTEXT:
+ default:
+- hnd_list = &adev->dm.irq_handler_list_low_tab[irq_source].head;
++ hnd_list = &adev->dm.irq_handler_list_low_tab[irq_source];
+ break;
+ }
+
+@@ -290,7 +281,8 @@ void *amdgpu_dm_irq_register_interrupt(struct amdgpu_device *adev,
+ break;
+ case INTERRUPT_LOW_IRQ_CONTEXT:
+ default:
+- hnd_list = &adev->dm.irq_handler_list_low_tab[irq_source].head;
++ hnd_list = &adev->dm.irq_handler_list_low_tab[irq_source];
++ INIT_WORK(&handler_data->work, dm_irq_work_func);
+ break;
+ }
+
+@@ -372,7 +364,7 @@ void amdgpu_dm_irq_unregister_interrupt(struct amdgpu_device *adev,
+ int amdgpu_dm_irq_init(struct amdgpu_device *adev)
+ {
+ int src;
+- struct irq_list_head *lh;
++ struct list_head *lh;
+
+ DRM_DEBUG_KMS("DM_IRQ\n");
+
+@@ -381,9 +373,7 @@ int amdgpu_dm_irq_init(struct amdgpu_device *adev)
+ for (src = 0; src < DAL_IRQ_SOURCES_NUMBER; src++) {
+ /* low context handler list init */
+ lh = &adev->dm.irq_handler_list_low_tab[src];
+- INIT_LIST_HEAD(&lh->head);
+- INIT_WORK(&lh->work, dm_irq_work_func);
+-
++ INIT_LIST_HEAD(lh);
+ /* high context handler init */
+ INIT_LIST_HEAD(&adev->dm.irq_handler_list_high_tab[src]);
+ }
+@@ -400,8 +390,11 @@ int amdgpu_dm_irq_init(struct amdgpu_device *adev)
+ void amdgpu_dm_irq_fini(struct amdgpu_device *adev)
+ {
+ int src;
+- struct irq_list_head *lh;
++ struct list_head *lh;
++ struct list_head *entry, *tmp;
++ struct amdgpu_dm_irq_handler_data *handler;
+ unsigned long irq_table_flags;
++
+ DRM_DEBUG_KMS("DM_IRQ: releasing resources.\n");
+ for (src = 0; src < DAL_IRQ_SOURCES_NUMBER; src++) {
+ DM_IRQ_TABLE_LOCK(adev, irq_table_flags);
+@@ -410,7 +403,16 @@ void amdgpu_dm_irq_fini(struct amdgpu_device *adev)
+ * (because no code can schedule a new one). */
+ lh = &adev->dm.irq_handler_list_low_tab[src];
+ DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags);
+- flush_work(&lh->work);
++
++ if (!list_empty(lh)) {
++ list_for_each_safe(entry, tmp, lh) {
++ handler = list_entry(
++ entry,
++ struct amdgpu_dm_irq_handler_data,
++ list);
++ flush_work(&handler->work);
++ }
++ }
+ }
+ }
+
+@@ -420,6 +422,8 @@ int amdgpu_dm_irq_suspend(struct amdgpu_device *adev)
+ struct list_head *hnd_list_h;
+ struct list_head *hnd_list_l;
+ unsigned long irq_table_flags;
++ struct list_head *entry, *tmp;
++ struct amdgpu_dm_irq_handler_data *handler;
+
+ DM_IRQ_TABLE_LOCK(adev, irq_table_flags);
+
+@@ -430,14 +434,22 @@ int amdgpu_dm_irq_suspend(struct amdgpu_device *adev)
+ * will be disabled from manage_dm_interrupts on disable CRTC.
+ */
+ for (src = DC_IRQ_SOURCE_HPD1; src <= DC_IRQ_SOURCE_HPD6RX; src++) {
+- hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head;
++ hnd_list_l = &adev->dm.irq_handler_list_low_tab[src];
+ hnd_list_h = &adev->dm.irq_handler_list_high_tab[src];
+ if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h))
+ dc_interrupt_set(adev->dm.dc, src, false);
+
+ DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags);
+- flush_work(&adev->dm.irq_handler_list_low_tab[src].work);
+
++ if (!list_empty(hnd_list_l)) {
++ list_for_each_safe (entry, tmp, hnd_list_l) {
++ handler = list_entry(
++ entry,
++ struct amdgpu_dm_irq_handler_data,
++ list);
++ flush_work(&handler->work);
++ }
++ }
+ DM_IRQ_TABLE_LOCK(adev, irq_table_flags);
+ }
+
+@@ -457,7 +469,7 @@ int amdgpu_dm_irq_resume_early(struct amdgpu_device *adev)
+
+ /* re-enable short pulse interrupts HW interrupt */
+ for (src = DC_IRQ_SOURCE_HPD1RX; src <= DC_IRQ_SOURCE_HPD6RX; src++) {
+- hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head;
++ hnd_list_l = &adev->dm.irq_handler_list_low_tab[src];
+ hnd_list_h = &adev->dm.irq_handler_list_high_tab[src];
+ if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h))
+ dc_interrupt_set(adev->dm.dc, src, true);
+@@ -483,7 +495,7 @@ int amdgpu_dm_irq_resume_late(struct amdgpu_device *adev)
+ * will be enabled from manage_dm_interrupts on enable CRTC.
+ */
+ for (src = DC_IRQ_SOURCE_HPD1; src <= DC_IRQ_SOURCE_HPD6; src++) {
+- hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head;
++ hnd_list_l = &adev->dm.irq_handler_list_low_tab[src];
+ hnd_list_h = &adev->dm.irq_handler_list_high_tab[src];
+ if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h))
+ dc_interrupt_set(adev->dm.dc, src, true);
+@@ -500,22 +512,53 @@ int amdgpu_dm_irq_resume_late(struct amdgpu_device *adev)
+ static void amdgpu_dm_irq_schedule_work(struct amdgpu_device *adev,
+ enum dc_irq_source irq_source)
+ {
+- unsigned long irq_table_flags;
+- struct work_struct *work = NULL;
++ struct list_head *handler_list = &adev->dm.irq_handler_list_low_tab[irq_source];
++ struct amdgpu_dm_irq_handler_data *handler_data;
++ bool work_queued = false;
+
+- DM_IRQ_TABLE_LOCK(adev, irq_table_flags);
++ if (list_empty(handler_list))
++ return;
++
++ list_for_each_entry (handler_data, handler_list, list) {
++ if (!queue_work(system_highpri_wq, &handler_data->work)) {
++ continue;
++ } else {
++ work_queued = true;
++ break;
++ }
++ }
+
+- if (!list_empty(&adev->dm.irq_handler_list_low_tab[irq_source].head))
+- work = &adev->dm.irq_handler_list_low_tab[irq_source].work;
++ if (!work_queued) {
++ struct amdgpu_dm_irq_handler_data *handler_data_add;
++ /*get the amdgpu_dm_irq_handler_data of first item pointed by handler_list*/
++ handler_data = container_of(handler_list->next, struct amdgpu_dm_irq_handler_data, list);
+
+- DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags);
++ /*allocate a new amdgpu_dm_irq_handler_data*/
++ handler_data_add = kzalloc(sizeof(*handler_data), GFP_KERNEL);
++ if (!handler_data_add) {
++ DRM_ERROR("DM_IRQ: failed to allocate irq handler!\n");
++ return;
++ }
+
+- if (work) {
+- if (!schedule_work(work))
+- DRM_INFO("amdgpu_dm_irq_schedule_work FAILED src %d\n",
+- irq_source);
+- }
++ /*copy new amdgpu_dm_irq_handler_data members from handler_data*/
++ handler_data_add->handler = handler_data->handler;
++ handler_data_add->handler_arg = handler_data->handler_arg;
++ handler_data_add->dm = handler_data->dm;
++ handler_data_add->irq_source = irq_source;
+
++ list_add_tail(&handler_data_add->list, handler_list);
++
++ INIT_WORK(&handler_data_add->work, dm_irq_work_func);
++
++ if (queue_work(system_highpri_wq, &handler_data_add->work))
++ DRM_DEBUG("Queued work for handling interrupt from "
++ "display for IRQ source %d\n",
++ irq_source);
++ else
++ DRM_ERROR("Failed to queue work for handling interrupt "
++ "from display for IRQ source %d\n",
++ irq_source);
++ }
+ }
+
+ /*
+diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
+index 995ffbbf64e7c..1ee27f2f28f1d 100644
+--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
++++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
+@@ -217,6 +217,9 @@ void dc_destroy_clk_mgr(struct clk_mgr *clk_mgr_base)
+ if (ASICREV_IS_SIENNA_CICHLID_P(clk_mgr_base->ctx->asic_id.hw_internal_rev)) {
+ dcn3_clk_mgr_destroy(clk_mgr);
+ }
++ if (ASICREV_IS_DIMGREY_CAVEFISH_P(clk_mgr_base->ctx->asic_id.hw_internal_rev)) {
++ dcn3_clk_mgr_destroy(clk_mgr);
++ }
+ break;
+
+ case FAMILY_VGH:
+diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c
+index c7e5a64e06afb..81ea5d3a1947b 100644
+--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c
++++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c
+@@ -252,6 +252,7 @@ static void dcn3_update_clocks(struct clk_mgr *clk_mgr_base,
+ bool force_reset = false;
+ bool update_uclk = false;
+ bool p_state_change_support;
++ int total_plane_count;
+
+ if (dc->work_arounds.skip_clock_update || !clk_mgr->smu_present)
+ return;
+@@ -292,7 +293,8 @@ static void dcn3_update_clocks(struct clk_mgr *clk_mgr_base,
+ clk_mgr_base->clks.socclk_khz = new_clocks->socclk_khz;
+
+ clk_mgr_base->clks.prev_p_state_change_support = clk_mgr_base->clks.p_state_change_support;
+- p_state_change_support = new_clocks->p_state_change_support || (display_count == 0);
++ total_plane_count = clk_mgr_helper_get_active_plane_cnt(dc, context);
++ p_state_change_support = new_clocks->p_state_change_support || (total_plane_count == 0);
+ if (should_update_pstate_support(safe_to_lower, p_state_change_support, clk_mgr_base->clks.p_state_change_support)) {
+ clk_mgr_base->clks.p_state_change_support = p_state_change_support;
+
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
+index 8f8a13c7cf73d..c0b827d162684 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
+@@ -2398,7 +2398,8 @@ static void commit_planes_do_stream_update(struct dc *dc,
+ if (pipe_ctx->stream_res.audio && !dc->debug.az_endpoint_mute_only)
+ pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio);
+
+- dc->hwss.optimize_bandwidth(dc, dc->current_state);
++ dc->optimized_required = true;
++
+ } else {
+ if (dc->optimize_seamless_boot_streams == 0)
+ dc->hwss.prepare_bandwidth(dc, dc->current_state);
+diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.h b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.h
+index 277484cf853e4..d4be5954d7aa3 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.h
++++ b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.h
+@@ -99,7 +99,6 @@ struct dce110_aux_registers {
+ AUX_SF(AUX_SW_CONTROL, AUX_SW_GO, mask_sh),\
+ AUX_SF(AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\
+ AUX_SF(AUX_SW_DATA, AUX_SW_DATA_RW, mask_sh),\
+- AUX_SF(AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\
+ AUX_SF(AUX_SW_DATA, AUX_SW_INDEX, mask_sh),\
+ AUX_SF(AUX_SW_DATA, AUX_SW_DATA, mask_sh),\
+ AUX_SF(AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT, mask_sh),\
+diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
+index 69e34bef274c1..febccb35ddade 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
++++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
+@@ -81,13 +81,18 @@ static void dmub_psr_get_state(struct dmub_psr *dmub, enum dc_psr_state *state)
+ {
+ struct dmub_srv *srv = dmub->ctx->dmub_srv->dmub;
+ uint32_t raw_state;
++ enum dmub_status status = DMUB_STATUS_INVALID;
+
+ // Send gpint command and wait for ack
+- dmub_srv_send_gpint_command(srv, DMUB_GPINT__GET_PSR_STATE, 0, 30);
+-
+- dmub_srv_get_gpint_response(srv, &raw_state);
+-
+- *state = convert_psr_state(raw_state);
++ status = dmub_srv_send_gpint_command(srv, DMUB_GPINT__GET_PSR_STATE, 0, 30);
++
++ if (status == DMUB_STATUS_OK) {
++ // GPINT was executed, get response
++ dmub_srv_get_gpint_response(srv, &raw_state);
++ *state = convert_psr_state(raw_state);
++ } else
++ // Return invalid state when GPINT times out
++ *state = 0xFF;
+ }
+
+ /*
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
+index 06dc1e2e8383a..07c8d2e2c09c2 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
+@@ -848,7 +848,7 @@ bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable)
+
+ cmd.mall.cursor_copy_src.quad_part = cursor_attr.address.quad_part;
+ cmd.mall.cursor_copy_dst.quad_part =
+- plane->address.grph.cursor_cache_addr.quad_part;
++ (plane->address.grph.cursor_cache_addr.quad_part + 2047) & ~2047;
+ cmd.mall.cursor_width = cursor_attr.width;
+ cmd.mall.cursor_height = cursor_attr.height;
+ cmd.mall.cursor_pitch = cursor_attr.pitch;
+@@ -858,8 +858,7 @@ bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable)
+ dc_dmub_srv_wait_idle(dc->ctx->dmub_srv);
+
+ /* Use copied cursor, and it's okay to not switch back */
+- cursor_attr.address.quad_part =
+- plane->address.grph.cursor_cache_addr.quad_part;
++ cursor_attr.address.quad_part = cmd.mall.cursor_copy_dst.quad_part;
+ dc_stream_set_cursor_attributes(stream, &cursor_attr);
+ }
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c
+index 3e6f76096119c..a7598356f37d2 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c
+@@ -143,16 +143,18 @@ static void mpc3_power_on_ogam_lut(
+ {
+ struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
+
+- if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) {
+- // Force power on
+- REG_UPDATE(MPCC_MEM_PWR_CTRL[mpcc_id], MPCC_OGAM_MEM_PWR_DIS, power_on == true ? 1:0);
+- // Wait for confirmation when powering on
+- if (power_on)
+- REG_WAIT(MPCC_MEM_PWR_CTRL[mpcc_id], MPCC_OGAM_MEM_PWR_STATE, 0, 10, 10);
+- } else {
+- REG_SET(MPCC_MEM_PWR_CTRL[mpcc_id], 0,
+- MPCC_OGAM_MEM_PWR_FORCE, power_on == true ? 0 : 1);
+- }
++ /*
++ * Powering on: force memory active so the LUT can be updated.
++ * Powering off: allow entering memory low power mode
++ *
++ * Memory low power mode is controlled during MPC OGAM LUT init.
++ */
++ REG_UPDATE(MPCC_MEM_PWR_CTRL[mpcc_id],
++ MPCC_OGAM_MEM_PWR_DIS, power_on != 0);
++
++ /* Wait for memory to be powered on - we won't be able to write to it otherwise. */
++ if (power_on)
++ REG_WAIT(MPCC_MEM_PWR_CTRL[mpcc_id], MPCC_OGAM_MEM_PWR_STATE, 0, 10, 10);
+ }
+
+ static void mpc3_configure_ogam_lut(
+@@ -1427,7 +1429,7 @@ const struct mpc_funcs dcn30_mpc_funcs = {
+ .acquire_rmu = mpcc3_acquire_rmu,
+ .program_3dlut = mpc3_program_3dlut,
+ .release_rmu = mpcc3_release_rmu,
+- .power_on_mpc_mem_pwr = mpc20_power_on_ogam_lut,
++ .power_on_mpc_mem_pwr = mpc3_power_on_ogam_lut,
+ .get_mpc_out_mux = mpc1_get_mpc_out_mux,
+
+ };
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
+index fb7f1dea3c467..71e2d5e025710 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
+@@ -181,7 +181,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_0_soc = {
+ },
+ .min_dcfclk = 500.0, /* TODO: set this to actual min DCFCLK */
+ .num_states = 1,
+- .sr_exit_time_us = 12,
++ .sr_exit_time_us = 15.5,
+ .sr_enter_plus_exit_time_us = 20,
+ .urgent_latency_us = 4.0,
+ .urgent_latency_pixel_data_only_us = 4.0,
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c b/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c
+index 4b659b63f75b3..d03b1975e4178 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c
+@@ -164,7 +164,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_02_soc = {
+
+ .min_dcfclk = 500.0, /* TODO: set this to actual min DCFCLK */
+ .num_states = 1,
+- .sr_exit_time_us = 12,
++ .sr_exit_time_us = 15.5,
+ .sr_enter_plus_exit_time_us = 20,
+ .urgent_latency_us = 4.0,
+ .urgent_latency_pixel_data_only_us = 4.0,
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c
+index 0f3f510fd83b8..9729cf292e849 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c
+@@ -3437,6 +3437,7 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
+ mode_lib->vba.DCCEnabledInAnyPlane = true;
+ }
+ }
++ mode_lib->vba.UrgentLatency = mode_lib->vba.UrgentLatencyPixelDataOnly;
+ for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
+ locals->FabricAndDRAMBandwidthPerState[i] = dml_min(
+ mode_lib->vba.DRAMSpeedPerState[i] * mode_lib->vba.NumberOfChannels
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c
+index 210c96cd5b03b..51098c2c98548 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c
+@@ -3544,6 +3544,7 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
+ mode_lib->vba.DCCEnabledInAnyPlane = true;
+ }
+ }
++ mode_lib->vba.UrgentLatency = mode_lib->vba.UrgentLatencyPixelDataOnly;
+ for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
+ locals->FabricAndDRAMBandwidthPerState[i] = dml_min(
+ mode_lib->vba.DRAMSpeedPerState[i] * mode_lib->vba.NumberOfChannels
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
+index 72423dc425dc0..799bae229e679 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
+@@ -293,13 +293,31 @@ static void handle_det_buf_split(struct display_mode_lib *mode_lib,
+ if (surf_linear) {
+ log2_swath_height_l = 0;
+ log2_swath_height_c = 0;
+- } else if (!surf_vert) {
+- log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_height) - req128_l;
+- log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_height) - req128_c;
+ } else {
+- log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_width) - req128_l;
+- log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_width) - req128_c;
++ unsigned int swath_height_l;
++ unsigned int swath_height_c;
++
++ if (!surf_vert) {
++ swath_height_l = rq_param->misc.rq_l.blk256_height;
++ swath_height_c = rq_param->misc.rq_c.blk256_height;
++ } else {
++ swath_height_l = rq_param->misc.rq_l.blk256_width;
++ swath_height_c = rq_param->misc.rq_c.blk256_width;
++ }
++
++ if (swath_height_l > 0)
++ log2_swath_height_l = dml_log2(swath_height_l);
++
++ if (req128_l && log2_swath_height_l > 0)
++ log2_swath_height_l -= 1;
++
++ if (swath_height_c > 0)
++ log2_swath_height_c = dml_log2(swath_height_c);
++
++ if (req128_c && log2_swath_height_c > 0)
++ log2_swath_height_c -= 1;
+ }
++
+ rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l;
+ rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c;
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c
+index 9c78446c3a9d8..6a6d5970d1d58 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c
+@@ -293,13 +293,31 @@ static void handle_det_buf_split(struct display_mode_lib *mode_lib,
+ if (surf_linear) {
+ log2_swath_height_l = 0;
+ log2_swath_height_c = 0;
+- } else if (!surf_vert) {
+- log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_height) - req128_l;
+- log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_height) - req128_c;
+ } else {
+- log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_width) - req128_l;
+- log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_width) - req128_c;
++ unsigned int swath_height_l;
++ unsigned int swath_height_c;
++
++ if (!surf_vert) {
++ swath_height_l = rq_param->misc.rq_l.blk256_height;
++ swath_height_c = rq_param->misc.rq_c.blk256_height;
++ } else {
++ swath_height_l = rq_param->misc.rq_l.blk256_width;
++ swath_height_c = rq_param->misc.rq_c.blk256_width;
++ }
++
++ if (swath_height_l > 0)
++ log2_swath_height_l = dml_log2(swath_height_l);
++
++ if (req128_l && log2_swath_height_l > 0)
++ log2_swath_height_l -= 1;
++
++ if (swath_height_c > 0)
++ log2_swath_height_c = dml_log2(swath_height_c);
++
++ if (req128_c && log2_swath_height_c > 0)
++ log2_swath_height_c -= 1;
+ }
++
+ rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l;
+ rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c;
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c
+index edd41d3582910..dc1c81a6e3771 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c
+@@ -277,13 +277,31 @@ static void handle_det_buf_split(
+ if (surf_linear) {
+ log2_swath_height_l = 0;
+ log2_swath_height_c = 0;
+- } else if (!surf_vert) {
+- log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_height) - req128_l;
+- log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_height) - req128_c;
+ } else {
+- log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_width) - req128_l;
+- log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_width) - req128_c;
++ unsigned int swath_height_l;
++ unsigned int swath_height_c;
++
++ if (!surf_vert) {
++ swath_height_l = rq_param->misc.rq_l.blk256_height;
++ swath_height_c = rq_param->misc.rq_c.blk256_height;
++ } else {
++ swath_height_l = rq_param->misc.rq_l.blk256_width;
++ swath_height_c = rq_param->misc.rq_c.blk256_width;
++ }
++
++ if (swath_height_l > 0)
++ log2_swath_height_l = dml_log2(swath_height_l);
++
++ if (req128_l && log2_swath_height_l > 0)
++ log2_swath_height_l -= 1;
++
++ if (swath_height_c > 0)
++ log2_swath_height_c = dml_log2(swath_height_c);
++
++ if (req128_c && log2_swath_height_c > 0)
++ log2_swath_height_c -= 1;
+ }
++
+ rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l;
+ rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c;
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c
+index 0f14f205ebe59..04601a767a8f1 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c
+@@ -237,13 +237,31 @@ static void handle_det_buf_split(struct display_mode_lib *mode_lib,
+ if (surf_linear) {
+ log2_swath_height_l = 0;
+ log2_swath_height_c = 0;
+- } else if (!surf_vert) {
+- log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_height) - req128_l;
+- log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_height) - req128_c;
+ } else {
+- log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_width) - req128_l;
+- log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_width) - req128_c;
++ unsigned int swath_height_l;
++ unsigned int swath_height_c;
++
++ if (!surf_vert) {
++ swath_height_l = rq_param->misc.rq_l.blk256_height;
++ swath_height_c = rq_param->misc.rq_c.blk256_height;
++ } else {
++ swath_height_l = rq_param->misc.rq_l.blk256_width;
++ swath_height_c = rq_param->misc.rq_c.blk256_width;
++ }
++
++ if (swath_height_l > 0)
++ log2_swath_height_l = dml_log2(swath_height_l);
++
++ if (req128_l && log2_swath_height_l > 0)
++ log2_swath_height_l -= 1;
++
++ if (swath_height_c > 0)
++ log2_swath_height_c = dml_log2(swath_height_c);
++
++ if (req128_c && log2_swath_height_c > 0)
++ log2_swath_height_c -= 1;
+ }
++
+ rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l;
+ rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c;
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c
+index 4c3e9cc301679..414da64f57340 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c
+@@ -344,13 +344,31 @@ static void handle_det_buf_split(
+ if (surf_linear) {
+ log2_swath_height_l = 0;
+ log2_swath_height_c = 0;
+- } else if (!surf_vert) {
+- log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_height) - req128_l;
+- log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_height) - req128_c;
+ } else {
+- log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_width) - req128_l;
+- log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_width) - req128_c;
++ unsigned int swath_height_l;
++ unsigned int swath_height_c;
++
++ if (!surf_vert) {
++ swath_height_l = rq_param->misc.rq_l.blk256_height;
++ swath_height_c = rq_param->misc.rq_c.blk256_height;
++ } else {
++ swath_height_l = rq_param->misc.rq_l.blk256_width;
++ swath_height_c = rq_param->misc.rq_c.blk256_width;
++ }
++
++ if (swath_height_l > 0)
++ log2_swath_height_l = dml_log2(swath_height_l);
++
++ if (req128_l && log2_swath_height_l > 0)
++ log2_swath_height_l -= 1;
++
++ if (swath_height_c > 0)
++ log2_swath_height_c = dml_log2(swath_height_c);
++
++ if (req128_c && log2_swath_height_c > 0)
++ log2_swath_height_c -= 1;
+ }
++
+ rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l;
+ rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c;
+
+diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c
+index ed05a30d1139d..e2a56a7f3d7a0 100644
+--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c
++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c
+@@ -1526,20 +1526,6 @@ static int smu10_set_fine_grain_clk_vol(struct pp_hwmgr *hwmgr,
+
+ smu10_data->gfx_actual_soft_min_freq = min_freq;
+ smu10_data->gfx_actual_soft_max_freq = max_freq;
+-
+- ret = smum_send_msg_to_smc_with_parameter(hwmgr,
+- PPSMC_MSG_SetHardMinGfxClk,
+- min_freq,
+- NULL);
+- if (ret)
+- return ret;
+-
+- ret = smum_send_msg_to_smc_with_parameter(hwmgr,
+- PPSMC_MSG_SetSoftMaxGfxClk,
+- max_freq,
+- NULL);
+- if (ret)
+- return ret;
+ } else if (type == PP_OD_COMMIT_DPM_TABLE) {
+ if (size != 0) {
+ pr_err("Input parameter number not correct\n");
+diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c
+index 599ec97266018..959143eff6510 100644
+--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c
++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c
+@@ -5160,7 +5160,7 @@ static int vega10_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, ui
+
+ out:
+ smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetWorkloadMask,
+- 1 << power_profile_mode,
++ (!power_profile_mode) ? 0 : 1 << (power_profile_mode - 1),
+ NULL);
+ hwmgr->power_profile_mode = power_profile_mode;
+
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
+index cd905e41080e5..42c4dbe3e3624 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
+@@ -279,35 +279,25 @@ static void smu_set_user_clk_dependencies(struct smu_context *smu, enum smu_clk_
+ if (smu->adev->in_suspend)
+ return;
+
+- /*
+- * mclk, fclk and socclk are interdependent
+- * on each other
+- */
+ if (clk == SMU_MCLK) {
+- /* reset clock dependency */
+ smu->user_dpm_profile.clk_dependency = 0;
+- /* set mclk dependent clocks(fclk and socclk) */
+ smu->user_dpm_profile.clk_dependency = BIT(SMU_FCLK) | BIT(SMU_SOCCLK);
+ } else if (clk == SMU_FCLK) {
+- /* give priority to mclk, if mclk dependent clocks are set */
++ /* MCLK takes precedence over FCLK */
+ if (smu->user_dpm_profile.clk_dependency == (BIT(SMU_FCLK) | BIT(SMU_SOCCLK)))
+ return;
+
+- /* reset clock dependency */
+ smu->user_dpm_profile.clk_dependency = 0;
+- /* set fclk dependent clocks(mclk and socclk) */
+ smu->user_dpm_profile.clk_dependency = BIT(SMU_MCLK) | BIT(SMU_SOCCLK);
+ } else if (clk == SMU_SOCCLK) {
+- /* give priority to mclk, if mclk dependent clocks are set */
++ /* MCLK takes precedence over SOCCLK */
+ if (smu->user_dpm_profile.clk_dependency == (BIT(SMU_FCLK) | BIT(SMU_SOCCLK)))
+ return;
+
+- /* reset clock dependency */
+ smu->user_dpm_profile.clk_dependency = 0;
+- /* set socclk dependent clocks(mclk and fclk) */
+ smu->user_dpm_profile.clk_dependency = BIT(SMU_MCLK) | BIT(SMU_FCLK);
+ } else
+- /* add clk dependencies here, if any */
++ /* Add clk dependencies here, if any */
+ return;
+ }
+
+@@ -331,7 +321,7 @@ static void smu_restore_dpm_user_profile(struct smu_context *smu)
+ return;
+
+ /* Enable restore flag */
+- smu->user_dpm_profile.flags = SMU_DPM_USER_PROFILE_RESTORE;
++ smu->user_dpm_profile.flags |= SMU_DPM_USER_PROFILE_RESTORE;
+
+ /* set the user dpm power limit */
+ if (smu->user_dpm_profile.power_limit) {
+@@ -354,8 +344,8 @@ static void smu_restore_dpm_user_profile(struct smu_context *smu)
+ ret = smu_force_clk_levels(smu, clk_type,
+ smu->user_dpm_profile.clk_mask[clk_type]);
+ if (ret)
+- dev_err(smu->adev->dev, "Failed to set clock type = %d\n",
+- clk_type);
++ dev_err(smu->adev->dev,
++ "Failed to set clock type = %d\n", clk_type);
+ }
+ }
+ }
+@@ -1777,7 +1767,7 @@ int smu_force_clk_levels(struct smu_context *smu,
+
+ if (smu->ppt_funcs && smu->ppt_funcs->force_clk_levels) {
+ ret = smu->ppt_funcs->force_clk_levels(smu, clk_type, mask);
+- if (!ret && smu->user_dpm_profile.flags != SMU_DPM_USER_PROFILE_RESTORE) {
++ if (!ret && !(smu->user_dpm_profile.flags & SMU_DPM_USER_PROFILE_RESTORE)) {
+ smu->user_dpm_profile.clk_mask[clk_type] = mask;
+ smu_set_user_clk_dependencies(smu, clk_type);
+ }
+@@ -2034,7 +2024,7 @@ int smu_set_fan_speed_rpm(struct smu_context *smu, uint32_t speed)
+ if (smu->ppt_funcs->set_fan_speed_percent) {
+ percent = speed * 100 / smu->fan_max_rpm;
+ ret = smu->ppt_funcs->set_fan_speed_percent(smu, percent);
+- if (!ret && smu->user_dpm_profile.flags != SMU_DPM_USER_PROFILE_RESTORE)
++ if (!ret && !(smu->user_dpm_profile.flags & SMU_DPM_USER_PROFILE_RESTORE))
+ smu->user_dpm_profile.fan_speed_percent = percent;
+ }
+
+@@ -2104,7 +2094,7 @@ int smu_set_power_limit(struct smu_context *smu, uint32_t limit)
+
+ if (smu->ppt_funcs->set_power_limit) {
+ ret = smu->ppt_funcs->set_power_limit(smu, limit);
+- if (!ret && smu->user_dpm_profile.flags != SMU_DPM_USER_PROFILE_RESTORE)
++ if (!ret && !(smu->user_dpm_profile.flags & SMU_DPM_USER_PROFILE_RESTORE))
+ smu->user_dpm_profile.power_limit = limit;
+ }
+
+@@ -2285,7 +2275,7 @@ int smu_set_fan_control_mode(struct smu_context *smu, int value)
+
+ if (smu->ppt_funcs->set_fan_control_mode) {
+ ret = smu->ppt_funcs->set_fan_control_mode(smu, value);
+- if (!ret && smu->user_dpm_profile.flags != SMU_DPM_USER_PROFILE_RESTORE)
++ if (!ret && !(smu->user_dpm_profile.flags & SMU_DPM_USER_PROFILE_RESTORE))
+ smu->user_dpm_profile.fan_mode = value;
+ }
+
+@@ -2293,7 +2283,7 @@ int smu_set_fan_control_mode(struct smu_context *smu, int value)
+
+ /* reset user dpm fan speed */
+ if (!ret && value != AMD_FAN_CTRL_MANUAL &&
+- smu->user_dpm_profile.flags != SMU_DPM_USER_PROFILE_RESTORE)
++ !(smu->user_dpm_profile.flags & SMU_DPM_USER_PROFILE_RESTORE))
+ smu->user_dpm_profile.fan_speed_percent = 0;
+
+ return ret;
+@@ -2335,7 +2325,7 @@ int smu_set_fan_speed_percent(struct smu_context *smu, uint32_t speed)
+ if (speed > 100)
+ speed = 100;
+ ret = smu->ppt_funcs->set_fan_speed_percent(smu, speed);
+- if (!ret && smu->user_dpm_profile.flags != SMU_DPM_USER_PROFILE_RESTORE)
++ if (!ret && !(smu->user_dpm_profile.flags & SMU_DPM_USER_PROFILE_RESTORE))
+ smu->user_dpm_profile.fan_speed_percent = speed;
+ }
+
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c
+index 101eaa20db9bd..a80f551771b93 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c
+@@ -1462,7 +1462,6 @@ static int vangogh_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TAB
+ long input[], uint32_t size)
+ {
+ int ret = 0;
+- int i;
+ struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
+
+ if (!(smu_dpm_ctx->dpm_level == AMD_DPM_FORCED_LEVEL_MANUAL)) {
+@@ -1535,43 +1534,6 @@ static int vangogh_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TAB
+ smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
+ smu->cpu_actual_soft_min_freq = smu->cpu_default_soft_min_freq;
+ smu->cpu_actual_soft_max_freq = smu->cpu_default_soft_max_freq;
+-
+- ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinGfxClk,
+- smu->gfx_actual_hard_min_freq, NULL);
+- if (ret) {
+- dev_err(smu->adev->dev, "Restore the default hard min sclk failed!");
+- return ret;
+- }
+-
+- ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxGfxClk,
+- smu->gfx_actual_soft_max_freq, NULL);
+- if (ret) {
+- dev_err(smu->adev->dev, "Restore the default soft max sclk failed!");
+- return ret;
+- }
+-
+- if (smu->adev->pm.fw_version < 0x43f1b00) {
+- dev_warn(smu->adev->dev, "CPUSoftMax/CPUSoftMin are not supported, please update SBIOS!\n");
+- break;
+- }
+-
+- for (i = 0; i < smu->cpu_core_num; i++) {
+- ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMinCclk,
+- (i << 20) | smu->cpu_actual_soft_min_freq,
+- NULL);
+- if (ret) {
+- dev_err(smu->adev->dev, "Set hard min cclk failed!");
+- return ret;
+- }
+-
+- ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxCclk,
+- (i << 20) | smu->cpu_actual_soft_max_freq,
+- NULL);
+- if (ret) {
+- dev_err(smu->adev->dev, "Set soft max cclk failed!");
+- return ret;
+- }
+- }
+ }
+ break;
+ case PP_OD_COMMIT_DPM_TABLE:
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c
+index 5493388fcb10c..dbe6d0caddb78 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c
+@@ -389,24 +389,6 @@ static int renoir_od_edit_dpm_table(struct smu_context *smu,
+ }
+ smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq;
+ smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
+-
+- ret = smu_cmn_send_smc_msg_with_param(smu,
+- SMU_MSG_SetHardMinGfxClk,
+- smu->gfx_actual_hard_min_freq,
+- NULL);
+- if (ret) {
+- dev_err(smu->adev->dev, "Restore the default hard min sclk failed!");
+- return ret;
+- }
+-
+- ret = smu_cmn_send_smc_msg_with_param(smu,
+- SMU_MSG_SetSoftMaxGfxClk,
+- smu->gfx_actual_soft_max_freq,
+- NULL);
+- if (ret) {
+- dev_err(smu->adev->dev, "Restore the default soft max sclk failed!");
+- return ret;
+- }
+ break;
+ case PP_OD_COMMIT_DPM_TABLE:
+ if (size != 0) {
+diff --git a/drivers/gpu/drm/arm/display/include/malidp_utils.h b/drivers/gpu/drm/arm/display/include/malidp_utils.h
+index 3bc383d5bf73d..49a1d7f3539c2 100644
+--- a/drivers/gpu/drm/arm/display/include/malidp_utils.h
++++ b/drivers/gpu/drm/arm/display/include/malidp_utils.h
+@@ -13,9 +13,6 @@
+ #define has_bit(nr, mask) (BIT(nr) & (mask))
+ #define has_bits(bits, mask) (((bits) & (mask)) == (bits))
+
+-#define dp_for_each_set_bit(bit, mask) \
+- for_each_set_bit((bit), ((unsigned long *)&(mask)), sizeof(mask) * 8)
+-
+ #define dp_wait_cond(__cond, __tries, __min_range, __max_range) \
+ ({ \
+ int num_tries = __tries; \
+diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c
+index 719a79728e24f..06c595378dda2 100644
+--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c
++++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c
+@@ -46,8 +46,9 @@ void komeda_pipeline_destroy(struct komeda_dev *mdev,
+ {
+ struct komeda_component *c;
+ int i;
++ unsigned long avail_comps = pipe->avail_comps;
+
+- dp_for_each_set_bit(i, pipe->avail_comps) {
++ for_each_set_bit(i, &avail_comps, 32) {
+ c = komeda_pipeline_get_component(pipe, i);
+ komeda_component_destroy(mdev, c);
+ }
+@@ -247,6 +248,7 @@ static void komeda_pipeline_dump(struct komeda_pipeline *pipe)
+ {
+ struct komeda_component *c;
+ int id;
++ unsigned long avail_comps = pipe->avail_comps;
+
+ DRM_INFO("Pipeline-%d: n_layers: %d, n_scalers: %d, output: %s.\n",
+ pipe->id, pipe->n_layers, pipe->n_scalers,
+@@ -258,7 +260,7 @@ static void komeda_pipeline_dump(struct komeda_pipeline *pipe)
+ pipe->of_output_links[1] ?
+ pipe->of_output_links[1]->full_name : "none");
+
+- dp_for_each_set_bit(id, pipe->avail_comps) {
++ for_each_set_bit(id, &avail_comps, 32) {
+ c = komeda_pipeline_get_component(pipe, id);
+
+ komeda_component_dump(c);
+@@ -270,8 +272,9 @@ static void komeda_component_verify_inputs(struct komeda_component *c)
+ struct komeda_pipeline *pipe = c->pipeline;
+ struct komeda_component *input;
+ int id;
++ unsigned long supported_inputs = c->supported_inputs;
+
+- dp_for_each_set_bit(id, c->supported_inputs) {
++ for_each_set_bit(id, &supported_inputs, 32) {
+ input = komeda_pipeline_get_component(pipe, id);
+ if (!input) {
+ c->supported_inputs &= ~(BIT(id));
+@@ -302,8 +305,9 @@ static void komeda_pipeline_assemble(struct komeda_pipeline *pipe)
+ struct komeda_component *c;
+ struct komeda_layer *layer;
+ int i, id;
++ unsigned long avail_comps = pipe->avail_comps;
+
+- dp_for_each_set_bit(id, pipe->avail_comps) {
++ for_each_set_bit(id, &avail_comps, 32) {
+ c = komeda_pipeline_get_component(pipe, id);
+ komeda_component_verify_inputs(c);
+ }
+@@ -355,13 +359,15 @@ void komeda_pipeline_dump_register(struct komeda_pipeline *pipe,
+ {
+ struct komeda_component *c;
+ u32 id;
++ unsigned long avail_comps;
+
+ seq_printf(sf, "\n======== Pipeline-%d ==========\n", pipe->id);
+
+ if (pipe->funcs && pipe->funcs->dump_register)
+ pipe->funcs->dump_register(pipe, sf);
+
+- dp_for_each_set_bit(id, pipe->avail_comps) {
++ avail_comps = pipe->avail_comps;
++ for_each_set_bit(id, &avail_comps, 32) {
+ c = komeda_pipeline_get_component(pipe, id);
+
+ seq_printf(sf, "\n------%s------\n", c->name);
+diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+index 5c085116de3f8..e672b9cffee3c 100644
+--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
++++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+@@ -1231,14 +1231,15 @@ komeda_pipeline_unbound_components(struct komeda_pipeline *pipe,
+ struct komeda_pipeline_state *old = priv_to_pipe_st(pipe->obj.state);
+ struct komeda_component_state *c_st;
+ struct komeda_component *c;
+- u32 disabling_comps, id;
++ u32 id;
++ unsigned long disabling_comps;
+
+ WARN_ON(!old);
+
+ disabling_comps = (~new->active_comps) & old->active_comps;
+
+ /* unbound all disabling component */
+- dp_for_each_set_bit(id, disabling_comps) {
++ for_each_set_bit(id, &disabling_comps, 32) {
+ c = komeda_pipeline_get_component(pipe, id);
+ c_st = komeda_component_get_state_and_set_user(c,
+ drm_st, NULL, new->crtc);
+@@ -1286,7 +1287,8 @@ bool komeda_pipeline_disable(struct komeda_pipeline *pipe,
+ struct komeda_pipeline_state *old;
+ struct komeda_component *c;
+ struct komeda_component_state *c_st;
+- u32 id, disabling_comps = 0;
++ u32 id;
++ unsigned long disabling_comps;
+
+ old = komeda_pipeline_get_old_state(pipe, old_state);
+
+@@ -1296,10 +1298,10 @@ bool komeda_pipeline_disable(struct komeda_pipeline *pipe,
+ disabling_comps = old->active_comps &
+ pipe->standalone_disabled_comps;
+
+- DRM_DEBUG_ATOMIC("PIPE%d: active_comps: 0x%x, disabling_comps: 0x%x.\n",
++ DRM_DEBUG_ATOMIC("PIPE%d: active_comps: 0x%x, disabling_comps: 0x%lx.\n",
+ pipe->id, old->active_comps, disabling_comps);
+
+- dp_for_each_set_bit(id, disabling_comps) {
++ for_each_set_bit(id, &disabling_comps, 32) {
+ c = komeda_pipeline_get_component(pipe, id);
+ c_st = priv_to_comp_st(c->obj.state);
+
+@@ -1330,16 +1332,17 @@ void komeda_pipeline_update(struct komeda_pipeline *pipe,
+ struct komeda_pipeline_state *new = priv_to_pipe_st(pipe->obj.state);
+ struct komeda_pipeline_state *old;
+ struct komeda_component *c;
+- u32 id, changed_comps = 0;
++ u32 id;
++ unsigned long changed_comps;
+
+ old = komeda_pipeline_get_old_state(pipe, old_state);
+
+ changed_comps = new->active_comps | old->active_comps;
+
+- DRM_DEBUG_ATOMIC("PIPE%d: active_comps: 0x%x, changed: 0x%x.\n",
++ DRM_DEBUG_ATOMIC("PIPE%d: active_comps: 0x%x, changed: 0x%lx.\n",
+ pipe->id, new->active_comps, changed_comps);
+
+- dp_for_each_set_bit(id, changed_comps) {
++ for_each_set_bit(id, &changed_comps, 32) {
+ c = komeda_pipeline_get_component(pipe, id);
+
+ if (new->active_comps & BIT(c->id))
+diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c
+index ea8164e7a6dc6..01837bea18c25 100644
+--- a/drivers/gpu/drm/ast/ast_drv.c
++++ b/drivers/gpu/drm/ast/ast_drv.c
+@@ -30,6 +30,7 @@
+ #include <linux/module.h>
+ #include <linux/pci.h>
+
++#include <drm/drm_atomic_helper.h>
+ #include <drm/drm_crtc_helper.h>
+ #include <drm/drm_drv.h>
+ #include <drm/drm_fb_helper.h>
+@@ -138,6 +139,7 @@ static void ast_pci_remove(struct pci_dev *pdev)
+ struct drm_device *dev = pci_get_drvdata(pdev);
+
+ drm_dev_unregister(dev);
++ drm_atomic_helper_shutdown(dev);
+ }
+
+ static int ast_drm_freeze(struct drm_device *dev)
+diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
+index 988b270fea5eb..758c69aa7232c 100644
+--- a/drivers/gpu/drm/ast/ast_mode.c
++++ b/drivers/gpu/drm/ast/ast_mode.c
+@@ -688,7 +688,7 @@ ast_cursor_plane_helper_atomic_update(struct drm_plane *plane,
+ unsigned int offset_x, offset_y;
+
+ offset_x = AST_MAX_HWC_WIDTH - fb->width;
+- offset_y = AST_MAX_HWC_WIDTH - fb->height;
++ offset_y = AST_MAX_HWC_HEIGHT - fb->height;
+
+ if (state->fb != old_state->fb) {
+ /* A new cursor image was installed. */
+diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c
+index 58f5dc2f6dd52..f6bdec7fa9253 100644
+--- a/drivers/gpu/drm/drm_panel_orientation_quirks.c
++++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c
+@@ -84,6 +84,13 @@ static const struct drm_dmi_panel_orientation_data itworks_tw891 = {
+ .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
+ };
+
++static const struct drm_dmi_panel_orientation_data onegx1_pro = {
++ .width = 1200,
++ .height = 1920,
++ .bios_dates = (const char * const []){ "12/17/2020", NULL },
++ .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
++};
++
+ static const struct drm_dmi_panel_orientation_data lcd720x1280_rightside_up = {
+ .width = 720,
+ .height = 1280,
+@@ -211,6 +218,13 @@ static const struct dmi_system_id orientation_data[] = {
+ DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad D330-10IGM"),
+ },
+ .driver_data = (void *)&lcd1200x1920_rightside_up,
++ }, { /* OneGX1 Pro */
++ .matches = {
++ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "SYSTEM_MANUFACTURER"),
++ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SYSTEM_PRODUCT_NAME"),
++ DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Default string"),
++ },
++ .driver_data = (void *)&onegx1_pro,
+ }, { /* VIOS LTH17 */
+ .matches = {
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "VIOS"),
+diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
+index 4b4d8d034782f..4ba20f959a71a 100644
+--- a/drivers/gpu/drm/i915/intel_pm.c
++++ b/drivers/gpu/drm/i915/intel_pm.c
+@@ -2993,7 +2993,7 @@ int ilk_wm_max_level(const struct drm_i915_private *dev_priv)
+
+ static void intel_print_wm_latency(struct drm_i915_private *dev_priv,
+ const char *name,
+- const u16 wm[8])
++ const u16 wm[])
+ {
+ int level, max_level = ilk_wm_max_level(dev_priv);
+
+diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+index 91cf46f840257..3d55e153fa9c3 100644
+--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
++++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+@@ -246,7 +246,7 @@ static int a6xx_gmu_hfi_start(struct a6xx_gmu *gmu)
+ }
+
+ struct a6xx_gmu_oob_bits {
+- int set, ack, set_new, ack_new;
++ int set, ack, set_new, ack_new, clear, clear_new;
+ const char *name;
+ };
+
+@@ -260,6 +260,8 @@ static const struct a6xx_gmu_oob_bits a6xx_gmu_oob_bits[] = {
+ .ack = 24,
+ .set_new = 30,
+ .ack_new = 31,
++ .clear = 24,
++ .clear_new = 31,
+ },
+
+ [GMU_OOB_PERFCOUNTER_SET] = {
+@@ -268,18 +270,22 @@ static const struct a6xx_gmu_oob_bits a6xx_gmu_oob_bits[] = {
+ .ack = 25,
+ .set_new = 28,
+ .ack_new = 30,
++ .clear = 25,
++ .clear_new = 29,
+ },
+
+ [GMU_OOB_BOOT_SLUMBER] = {
+ .name = "BOOT_SLUMBER",
+ .set = 22,
+ .ack = 30,
++ .clear = 30,
+ },
+
+ [GMU_OOB_DCVS_SET] = {
+ .name = "GPU_DCVS",
+ .set = 23,
+ .ack = 31,
++ .clear = 31,
+ },
+ };
+
+@@ -335,9 +341,9 @@ void a6xx_gmu_clear_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state)
+ return;
+
+ if (gmu->legacy)
+- bit = a6xx_gmu_oob_bits[state].ack;
++ bit = a6xx_gmu_oob_bits[state].clear;
+ else
+- bit = a6xx_gmu_oob_bits[state].ack_new;
++ bit = a6xx_gmu_oob_bits[state].clear_new;
+
+ gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET, 1 << bit);
+ }
+diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c
+index ff2c1d583c792..0392d4dfe270a 100644
+--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c
++++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c
+@@ -20,7 +20,7 @@ static int pingpong_tearcheck_setup(struct drm_encoder *encoder,
+ {
+ struct mdp5_kms *mdp5_kms = get_kms(encoder);
+ struct device *dev = encoder->dev->dev;
+- u32 total_lines_x100, vclks_line, cfg;
++ u32 total_lines, vclks_line, cfg;
+ long vsync_clk_speed;
+ struct mdp5_hw_mixer *mixer = mdp5_crtc_get_mixer(encoder->crtc);
+ int pp_id = mixer->pp;
+@@ -30,8 +30,8 @@ static int pingpong_tearcheck_setup(struct drm_encoder *encoder,
+ return -EINVAL;
+ }
+
+- total_lines_x100 = mode->vtotal * drm_mode_vrefresh(mode);
+- if (!total_lines_x100) {
++ total_lines = mode->vtotal * drm_mode_vrefresh(mode);
++ if (!total_lines) {
+ DRM_DEV_ERROR(dev, "%s: vtotal(%d) or vrefresh(%d) is 0\n",
+ __func__, mode->vtotal, drm_mode_vrefresh(mode));
+ return -EINVAL;
+@@ -43,15 +43,23 @@ static int pingpong_tearcheck_setup(struct drm_encoder *encoder,
+ vsync_clk_speed);
+ return -EINVAL;
+ }
+- vclks_line = vsync_clk_speed * 100 / total_lines_x100;
++ vclks_line = vsync_clk_speed / total_lines;
+
+ cfg = MDP5_PP_SYNC_CONFIG_VSYNC_COUNTER_EN
+ | MDP5_PP_SYNC_CONFIG_VSYNC_IN_EN;
+ cfg |= MDP5_PP_SYNC_CONFIG_VSYNC_COUNT(vclks_line);
+
++ /*
++ * Tearcheck emits a blanking signal every vclks_line * vtotal * 2 ticks on
++ * the vsync_clk equating to roughly half the desired panel refresh rate.
++ * This is only necessary as stability fallback if interrupts from the
++ * panel arrive too late or not at all, but is currently used by default
++ * because these panel interrupts are not wired up yet.
++ */
+ mdp5_write(mdp5_kms, REG_MDP5_PP_SYNC_CONFIG_VSYNC(pp_id), cfg);
+ mdp5_write(mdp5_kms,
+- REG_MDP5_PP_SYNC_CONFIG_HEIGHT(pp_id), 0xfff0);
++ REG_MDP5_PP_SYNC_CONFIG_HEIGHT(pp_id), (2 * mode->vtotal));
++
+ mdp5_write(mdp5_kms,
+ REG_MDP5_PP_VSYNC_INIT_VAL(pp_id), mode->vdisplay);
+ mdp5_write(mdp5_kms, REG_MDP5_PP_RD_PTR_IRQ(pp_id), mode->vdisplay + 1);
+diff --git a/drivers/gpu/drm/msm/dp/dp_hpd.c b/drivers/gpu/drm/msm/dp/dp_hpd.c
+index 5b8fe32022b5f..e1c90fa47411f 100644
+--- a/drivers/gpu/drm/msm/dp/dp_hpd.c
++++ b/drivers/gpu/drm/msm/dp/dp_hpd.c
+@@ -34,8 +34,8 @@ int dp_hpd_connect(struct dp_usbpd *dp_usbpd, bool hpd)
+
+ dp_usbpd->hpd_high = hpd;
+
+- if (!hpd_priv->dp_cb && !hpd_priv->dp_cb->configure
+- && !hpd_priv->dp_cb->disconnect) {
++ if (!hpd_priv->dp_cb || !hpd_priv->dp_cb->configure
++ || !hpd_priv->dp_cb->disconnect) {
+ pr_err("hpd dp_cb not initialized\n");
+ return -EINVAL;
+ }
+diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c
+index 10738e04c09b8..56e0c6c625e9a 100644
+--- a/drivers/gpu/drm/qxl/qxl_display.c
++++ b/drivers/gpu/drm/qxl/qxl_display.c
+@@ -1228,6 +1228,10 @@ int qxl_modeset_init(struct qxl_device *qdev)
+
+ void qxl_modeset_fini(struct qxl_device *qdev)
+ {
++ if (qdev->dumb_shadow_bo) {
++ drm_gem_object_put(&qdev->dumb_shadow_bo->tbo.base);
++ qdev->dumb_shadow_bo = NULL;
++ }
+ qxl_destroy_monitors_object(qdev);
+ drm_mode_config_cleanup(&qdev->ddev);
+ }
+diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c
+index 1864467f10639..1b09bbe980551 100644
+--- a/drivers/gpu/drm/qxl/qxl_drv.c
++++ b/drivers/gpu/drm/qxl/qxl_drv.c
+@@ -144,6 +144,8 @@ static void qxl_drm_release(struct drm_device *dev)
+ * reordering qxl_modeset_fini() + qxl_device_fini() calls is
+ * non-trivial though.
+ */
++ if (!dev->registered)
++ return;
+ qxl_modeset_fini(qdev);
+ qxl_device_fini(qdev);
+ }
+diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c
+index 9b81786782de7..499ce55e34ccf 100644
+--- a/drivers/gpu/drm/radeon/radeon_object.c
++++ b/drivers/gpu/drm/radeon/radeon_object.c
+@@ -384,6 +384,8 @@ int radeon_bo_evict_vram(struct radeon_device *rdev)
+ }
+ #endif
+ man = ttm_manager_type(bdev, TTM_PL_VRAM);
++ if (!man)
++ return 0;
+ return ttm_resource_manager_evict_all(bdev, man);
+ }
+
+diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
+index 78893bea85aed..c0258d213a72f 100644
+--- a/drivers/gpu/drm/radeon/radeon_ttm.c
++++ b/drivers/gpu/drm/radeon/radeon_ttm.c
+@@ -485,13 +485,14 @@ static void radeon_ttm_backend_unbind(struct ttm_bo_device *bdev, struct ttm_tt
+ struct radeon_ttm_tt *gtt = (void *)ttm;
+ struct radeon_device *rdev = radeon_get_rdev(bdev);
+
++ if (gtt->userptr)
++ radeon_ttm_tt_unpin_userptr(bdev, ttm);
++
+ if (!gtt->bound)
+ return;
+
+ radeon_gart_unbind(rdev, gtt->offset, ttm->num_pages);
+
+- if (gtt->userptr)
+- radeon_ttm_tt_unpin_userptr(bdev, ttm);
+ gtt->bound = false;
+ }
+
+diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+index 23eb6d772e405..669f2ee395154 100644
+--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
++++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+@@ -174,7 +174,7 @@ static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data,
+ if (!sync_file) {
+ dma_fence_put(&out_fence->f);
+ ret = -ENOMEM;
+- goto out_memdup;
++ goto out_unresv;
+ }
+
+ exbuf->fence_fd = out_fence_fd;
+diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c
+index d69a5b6da5532..4ff1ec28e630d 100644
+--- a/drivers/gpu/drm/virtio/virtgpu_object.c
++++ b/drivers/gpu/drm/virtio/virtgpu_object.c
+@@ -248,6 +248,7 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev,
+
+ ret = virtio_gpu_object_shmem_init(vgdev, bo, &ents, &nents);
+ if (ret != 0) {
++ virtio_gpu_array_put_free(objs);
+ virtio_gpu_free_object(&shmem_obj->base);
+ return ret;
+ }
+diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c
+index 0443b7deeaef6..758d8a98d96b3 100644
+--- a/drivers/gpu/drm/vkms/vkms_crtc.c
++++ b/drivers/gpu/drm/vkms/vkms_crtc.c
+@@ -18,7 +18,8 @@ static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer)
+
+ ret_overrun = hrtimer_forward_now(&output->vblank_hrtimer,
+ output->period_ns);
+- WARN_ON(ret_overrun != 1);
++ if (ret_overrun != 1)
++ pr_warn("%s: vblank timer overrun\n", __func__);
+
+ spin_lock(&output->lock);
+ ret = drm_crtc_handle_vblank(crtc);
+diff --git a/drivers/hwtracing/intel_th/gth.c b/drivers/hwtracing/intel_th/gth.c
+index f72803a023910..28509b02a0b56 100644
+--- a/drivers/hwtracing/intel_th/gth.c
++++ b/drivers/hwtracing/intel_th/gth.c
+@@ -543,7 +543,7 @@ static void intel_th_gth_disable(struct intel_th_device *thdev,
+ output->active = false;
+
+ for_each_set_bit(master, gth->output[output->port].master,
+- TH_CONFIGURABLE_MASTERS) {
++ TH_CONFIGURABLE_MASTERS + 1) {
+ gth_master_set(gth, master, -1);
+ }
+ spin_unlock(&gth->gth_lock);
+@@ -697,7 +697,7 @@ static void intel_th_gth_unassign(struct intel_th_device *thdev,
+ othdev->output.port = -1;
+ othdev->output.active = false;
+ gth->output[port].output = NULL;
+- for (master = 0; master <= TH_CONFIGURABLE_MASTERS; master++)
++ for (master = 0; master < TH_CONFIGURABLE_MASTERS + 1; master++)
+ if (gth->master[master] == port)
+ gth->master[master] = -1;
+ spin_unlock(&gth->gth_lock);
+diff --git a/drivers/hwtracing/intel_th/pci.c b/drivers/hwtracing/intel_th/pci.c
+index 251e75c9ba9d0..817cdb29bbd89 100644
+--- a/drivers/hwtracing/intel_th/pci.c
++++ b/drivers/hwtracing/intel_th/pci.c
+@@ -273,11 +273,21 @@ static const struct pci_device_id intel_th_pci_id_table[] = {
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x51a6),
+ .driver_data = (kernel_ulong_t)&intel_th_2x,
+ },
++ {
++ /* Alder Lake-M */
++ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x54a6),
++ .driver_data = (kernel_ulong_t)&intel_th_2x,
++ },
+ {
+ /* Alder Lake CPU */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x466f),
+ .driver_data = (kernel_ulong_t)&intel_th_2x,
+ },
++ {
++ /* Rocket Lake CPU */
++ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4c19),
++ .driver_data = (kernel_ulong_t)&intel_th_2x,
++ },
+ { 0 },
+ };
+
+diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c
+index d8fccf048bf44..30576a5f2f045 100644
+--- a/drivers/input/touchscreen/ili210x.c
++++ b/drivers/input/touchscreen/ili210x.c
+@@ -87,7 +87,7 @@ static bool ili210x_touchdata_to_coords(const u8 *touchdata,
+ unsigned int *x, unsigned int *y,
+ unsigned int *z)
+ {
+- if (touchdata[0] & BIT(finger))
++ if (!(touchdata[0] & BIT(finger)))
+ return false;
+
+ *x = get_unaligned_be16(touchdata + 1 + (finger * 4) + 0);
+diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
+index ee0932307d646..881c9f2a5c7d9 100644
+--- a/drivers/iommu/intel/iommu.c
++++ b/drivers/iommu/intel/iommu.c
+@@ -2289,6 +2289,41 @@ static inline int hardware_largepage_caps(struct dmar_domain *domain,
+ return level;
+ }
+
++/*
++ * Ensure that old small page tables are removed to make room for superpage(s).
++ * We're going to add new large pages, so make sure we don't remove their parent
++ * tables. The IOTLB/devTLBs should be flushed if any PDE/PTEs are cleared.
++ */
++static void switch_to_super_page(struct dmar_domain *domain,
++ unsigned long start_pfn,
++ unsigned long end_pfn, int level)
++{
++ unsigned long lvl_pages = lvl_to_nr_pages(level);
++ struct dma_pte *pte = NULL;
++ int i;
++
++ while (start_pfn <= end_pfn) {
++ if (!pte)
++ pte = pfn_to_dma_pte(domain, start_pfn, &level);
++
++ if (dma_pte_present(pte)) {
++ dma_pte_free_pagetable(domain, start_pfn,
++ start_pfn + lvl_pages - 1,
++ level + 1);
++
++ for_each_domain_iommu(i, domain)
++ iommu_flush_iotlb_psi(g_iommus[i], domain,
++ start_pfn, lvl_pages,
++ 0, 0);
++ }
++
++ pte++;
++ start_pfn += lvl_pages;
++ if (first_pte_in_page(pte))
++ pte = NULL;
++ }
++}
++
+ static int
+ __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
+ unsigned long phys_pfn, unsigned long nr_pages, int prot)
+@@ -2329,22 +2364,11 @@ __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
+ return -ENOMEM;
+ /* It is large page*/
+ if (largepage_lvl > 1) {
+- unsigned long nr_superpages, end_pfn;
++ unsigned long end_pfn;
+
+ pteval |= DMA_PTE_LARGE_PAGE;
+- lvl_pages = lvl_to_nr_pages(largepage_lvl);
+-
+- nr_superpages = nr_pages / lvl_pages;
+- end_pfn = iov_pfn + nr_superpages * lvl_pages - 1;
+-
+- /*
+- * Ensure that old small page tables are
+- * removed to make room for superpage(s).
+- * We're adding new large pages, so make sure
+- * we don't remove their parent tables.
+- */
+- dma_pte_free_pagetable(domain, iov_pfn, end_pfn,
+- largepage_lvl + 1);
++ end_pfn = ((iov_pfn + nr_pages) & level_mask(largepage_lvl)) - 1;
++ switch_to_super_page(domain, iov_pfn, end_pfn, largepage_lvl);
+ } else {
+ pteval &= ~(uint64_t)DMA_PTE_LARGE_PAGE;
+ }
+diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
+index eb0ee356a6294..00404024d7cd5 100644
+--- a/drivers/irqchip/irq-gic-v3.c
++++ b/drivers/irqchip/irq-gic-v3.c
+@@ -648,6 +648,10 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs
+
+ irqnr = gic_read_iar();
+
++ /* Check for special IDs first */
++ if ((irqnr >= 1020 && irqnr <= 1023))
++ return;
++
+ if (gic_supports_nmi() &&
+ unlikely(gic_read_rpr() == GICD_INT_NMI_PRI)) {
+ gic_handle_nmi(irqnr, regs);
+@@ -659,10 +663,6 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs
+ gic_arch_enable_irqs();
+ }
+
+- /* Check for special IDs first */
+- if ((irqnr >= 1020 && irqnr <= 1023))
+- return;
+-
+ if (static_branch_likely(&supports_deactivate_key))
+ gic_write_eoir(irqnr);
+ else
+diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c
+index 46b5d542b8fe6..362c887d33b3d 100644
+--- a/drivers/md/dm-integrity.c
++++ b/drivers/md/dm-integrity.c
+@@ -4039,6 +4039,7 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned argc, char **argv)
+ if (val >= (uint64_t)UINT_MAX * 1000 / HZ) {
+ r = -EINVAL;
+ ti->error = "Invalid bitmap_flush_interval argument";
++ goto bad;
+ }
+ ic->bitmap_flush_interval = msecs_to_jiffies(val);
+ } else if (!strncmp(opt_string, "internal_hash:", strlen("internal_hash:"))) {
+diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
+index cab12b2251bac..91461b6904c1d 100644
+--- a/drivers/md/dm-raid.c
++++ b/drivers/md/dm-raid.c
+@@ -1868,6 +1868,14 @@ static bool rs_takeover_requested(struct raid_set *rs)
+ return rs->md.new_level != rs->md.level;
+ }
+
++/* True if layout is set to reshape. */
++static bool rs_is_layout_change(struct raid_set *rs, bool use_mddev)
++{
++ return (use_mddev ? rs->md.delta_disks : rs->delta_disks) ||
++ rs->md.new_layout != rs->md.layout ||
++ rs->md.new_chunk_sectors != rs->md.chunk_sectors;
++}
++
+ /* True if @rs is requested to reshape by ctr */
+ static bool rs_reshape_requested(struct raid_set *rs)
+ {
+@@ -1880,9 +1888,7 @@ static bool rs_reshape_requested(struct raid_set *rs)
+ if (rs_is_raid0(rs))
+ return false;
+
+- change = mddev->new_layout != mddev->layout ||
+- mddev->new_chunk_sectors != mddev->chunk_sectors ||
+- rs->delta_disks;
++ change = rs_is_layout_change(rs, false);
+
+ /* Historical case to support raid1 reshape without delta disks */
+ if (rs_is_raid1(rs)) {
+@@ -2817,7 +2823,7 @@ static sector_t _get_reshape_sectors(struct raid_set *rs)
+ }
+
+ /*
+- *
++ * Reshape:
+ * - change raid layout
+ * - change chunk size
+ * - add disks
+@@ -2926,6 +2932,20 @@ static int rs_setup_reshape(struct raid_set *rs)
+ return r;
+ }
+
++/*
++ * If the md resync thread has updated superblock with max reshape position
++ * at the end of a reshape but not (yet) reset the layout configuration
++ * changes -> reset the latter.
++ */
++static void rs_reset_inconclusive_reshape(struct raid_set *rs)
++{
++ if (!rs_is_reshaping(rs) && rs_is_layout_change(rs, true)) {
++ rs_set_cur(rs);
++ rs->md.delta_disks = 0;
++ rs->md.reshape_backwards = 0;
++ }
++}
++
+ /*
+ * Enable/disable discard support on RAID set depending on
+ * RAID level and discard properties of underlying RAID members.
+@@ -3212,11 +3232,14 @@ size_check:
+ if (r)
+ goto bad;
+
++ /* Catch any inconclusive reshape superblock content. */
++ rs_reset_inconclusive_reshape(rs);
++
+ /* Start raid set read-only and assumed clean to change in raid_resume() */
+ rs->md.ro = 1;
+ rs->md.in_sync = 1;
+
+- /* Keep array frozen */
++ /* Keep array frozen until resume. */
+ set_bit(MD_RECOVERY_FROZEN, &rs->md.recovery);
+
+ /* Has to be held on running the array */
+@@ -3230,7 +3253,6 @@ size_check:
+ }
+
+ r = md_start(&rs->md);
+-
+ if (r) {
+ ti->error = "Failed to start raid array";
+ mddev_unlock(&rs->md);
+diff --git a/drivers/md/dm-rq.c b/drivers/md/dm-rq.c
+index 13b4385f4d5a9..9c3bc3711b335 100644
+--- a/drivers/md/dm-rq.c
++++ b/drivers/md/dm-rq.c
+@@ -569,6 +569,7 @@ out_tag_set:
+ blk_mq_free_tag_set(md->tag_set);
+ out_kfree_tag_set:
+ kfree(md->tag_set);
++ md->tag_set = NULL;
+
+ return err;
+ }
+@@ -578,6 +579,7 @@ void dm_mq_cleanup_mapped_device(struct mapped_device *md)
+ if (md->tag_set) {
+ blk_mq_free_tag_set(md->tag_set);
+ kfree(md->tag_set);
++ md->tag_set = NULL;
+ }
+ }
+
+diff --git a/drivers/md/persistent-data/dm-btree-internal.h b/drivers/md/persistent-data/dm-btree-internal.h
+index fe073d92f01e6..70cfdea27efdf 100644
+--- a/drivers/md/persistent-data/dm-btree-internal.h
++++ b/drivers/md/persistent-data/dm-btree-internal.h
+@@ -34,12 +34,12 @@ struct node_header {
+ __le32 max_entries;
+ __le32 value_size;
+ __le32 padding;
+-} __packed;
++} __attribute__((packed, aligned(8)));
+
+ struct btree_node {
+ struct node_header header;
+ __le64 keys[];
+-} __packed;
++} __attribute__((packed, aligned(8)));
+
+
+ /*
+diff --git a/drivers/md/persistent-data/dm-space-map-common.c b/drivers/md/persistent-data/dm-space-map-common.c
+index d8b4125e338ca..a213bf11738fb 100644
+--- a/drivers/md/persistent-data/dm-space-map-common.c
++++ b/drivers/md/persistent-data/dm-space-map-common.c
+@@ -339,6 +339,8 @@ int sm_ll_find_free_block(struct ll_disk *ll, dm_block_t begin,
+ */
+ begin = do_div(index_begin, ll->entries_per_block);
+ end = do_div(end, ll->entries_per_block);
++ if (end == 0)
++ end = ll->entries_per_block;
+
+ for (i = index_begin; i < index_end; i++, begin = 0) {
+ struct dm_block *blk;
+diff --git a/drivers/md/persistent-data/dm-space-map-common.h b/drivers/md/persistent-data/dm-space-map-common.h
+index 8de63ce39bdd5..87e17909ef521 100644
+--- a/drivers/md/persistent-data/dm-space-map-common.h
++++ b/drivers/md/persistent-data/dm-space-map-common.h
+@@ -33,7 +33,7 @@ struct disk_index_entry {
+ __le64 blocknr;
+ __le32 nr_free;
+ __le32 none_free_before;
+-} __packed;
++} __attribute__ ((packed, aligned(8)));
+
+
+ #define MAX_METADATA_BITMAPS 255
+@@ -43,7 +43,7 @@ struct disk_metadata_index {
+ __le64 blocknr;
+
+ struct disk_index_entry index[MAX_METADATA_BITMAPS];
+-} __packed;
++} __attribute__ ((packed, aligned(8)));
+
+ struct ll_disk;
+
+@@ -86,7 +86,7 @@ struct disk_sm_root {
+ __le64 nr_allocated;
+ __le64 bitmap_root;
+ __le64 ref_count_root;
+-} __packed;
++} __attribute__ ((packed, aligned(8)));
+
+ #define ENTRIES_PER_BYTE 4
+
+@@ -94,7 +94,7 @@ struct disk_bitmap_header {
+ __le32 csum;
+ __le32 not_used;
+ __le64 blocknr;
+-} __packed;
++} __attribute__ ((packed, aligned(8)));
+
+ enum allocation_event {
+ SM_NONE,
+diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
+index d2378765dc154..ced076ba560e1 100644
+--- a/drivers/md/raid1.c
++++ b/drivers/md/raid1.c
+@@ -478,6 +478,8 @@ static void raid1_end_write_request(struct bio *bio)
+ if (!test_bit(Faulty, &rdev->flags))
+ set_bit(R1BIO_WriteError, &r1_bio->state);
+ else {
++ /* Fail the request */
++ set_bit(R1BIO_Degraded, &r1_bio->state);
+ /* Finished with this branch */
+ r1_bio->bios[mirror] = NULL;
+ to_put = bio;
+diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c
+index 5ff7bedee2477..3862ddc86ec48 100644
+--- a/drivers/media/dvb-core/dvbdev.c
++++ b/drivers/media/dvb-core/dvbdev.c
+@@ -241,6 +241,7 @@ static void dvb_media_device_free(struct dvb_device *dvbdev)
+
+ if (dvbdev->adapter->conn) {
+ media_device_unregister_entity(dvbdev->adapter->conn);
++ kfree(dvbdev->adapter->conn);
+ dvbdev->adapter->conn = NULL;
+ kfree(dvbdev->adapter->conn_pads);
+ dvbdev->adapter->conn_pads = NULL;
+diff --git a/drivers/media/i2c/adv7511-v4l2.c b/drivers/media/i2c/adv7511-v4l2.c
+index a3161d7090153..ab7883cff8b22 100644
+--- a/drivers/media/i2c/adv7511-v4l2.c
++++ b/drivers/media/i2c/adv7511-v4l2.c
+@@ -1964,7 +1964,7 @@ static int adv7511_remove(struct i2c_client *client)
+
+ adv7511_set_isr(sd, false);
+ adv7511_init_setup(sd);
+- cancel_delayed_work(&state->edid_handler);
++ cancel_delayed_work_sync(&state->edid_handler);
+ i2c_unregister_device(state->i2c_edid);
+ i2c_unregister_device(state->i2c_cec);
+ i2c_unregister_device(state->i2c_pktmem);
+diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
+index 09004d928d11f..d1f58795794fd 100644
+--- a/drivers/media/i2c/adv7604.c
++++ b/drivers/media/i2c/adv7604.c
+@@ -3616,7 +3616,7 @@ static int adv76xx_remove(struct i2c_client *client)
+ io_write(sd, 0x6e, 0);
+ io_write(sd, 0x73, 0);
+
+- cancel_delayed_work(&state->delayed_work_enable_hotplug);
++ cancel_delayed_work_sync(&state->delayed_work_enable_hotplug);
+ v4l2_async_unregister_subdev(sd);
+ media_entity_cleanup(&sd->entity);
+ adv76xx_unregister_clients(to_state(sd));
+diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c
+index 0855f648416d1..f7d2b6cd3008b 100644
+--- a/drivers/media/i2c/adv7842.c
++++ b/drivers/media/i2c/adv7842.c
+@@ -3586,7 +3586,7 @@ static int adv7842_remove(struct i2c_client *client)
+ struct adv7842_state *state = to_state(sd);
+
+ adv7842_irq_enable(sd, false);
+- cancel_delayed_work(&state->delayed_work_enable_hotplug);
++ cancel_delayed_work_sync(&state->delayed_work_enable_hotplug);
+ v4l2_device_unregister_subdev(sd);
+ media_entity_cleanup(&sd->entity);
+ adv7842_unregister_clients(sd);
+diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
+index 831b5b54fd78c..1b309bb743c7b 100644
+--- a/drivers/media/i2c/tc358743.c
++++ b/drivers/media/i2c/tc358743.c
+@@ -2193,7 +2193,7 @@ static int tc358743_remove(struct i2c_client *client)
+ del_timer_sync(&state->timer);
+ flush_work(&state->work_i2c_poll);
+ }
+- cancel_delayed_work(&state->delayed_work_enable_hotplug);
++ cancel_delayed_work_sync(&state->delayed_work_enable_hotplug);
+ cec_unregister_adapter(state->cec_adap);
+ v4l2_async_unregister_subdev(sd);
+ v4l2_device_unregister_subdev(sd);
+diff --git a/drivers/media/i2c/tda1997x.c b/drivers/media/i2c/tda1997x.c
+index a09bf0a39d058..89bb7e6dc7a42 100644
+--- a/drivers/media/i2c/tda1997x.c
++++ b/drivers/media/i2c/tda1997x.c
+@@ -2804,7 +2804,7 @@ static int tda1997x_remove(struct i2c_client *client)
+ media_entity_cleanup(&sd->entity);
+ v4l2_ctrl_handler_free(&state->hdl);
+ regulator_bulk_disable(TDA1997X_NUM_SUPPLIES, state->supplies);
+- cancel_delayed_work(&state->delayed_work_enable_hpd);
++ cancel_delayed_work_sync(&state->delayed_work_enable_hpd);
+ mutex_destroy(&state->page_lock);
+ mutex_destroy(&state->lock);
+
+diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c
+index 22f55a7840a62..d0ca260ecf700 100644
+--- a/drivers/media/pci/cx23885/cx23885-core.c
++++ b/drivers/media/pci/cx23885/cx23885-core.c
+@@ -2077,6 +2077,15 @@ static struct {
+ * 0x1423 is the PCI ID for the IOMMU found on Kaveri
+ */
+ { PCI_VENDOR_ID_AMD, 0x1423 },
++ /* 0x1481 is the PCI ID for the IOMMU found on Starship/Matisse
++ */
++ { PCI_VENDOR_ID_AMD, 0x1481 },
++ /* 0x1419 is the PCI ID for the IOMMU found on 15h (Models 10h-1fh) family
++ */
++ { PCI_VENDOR_ID_AMD, 0x1419 },
++ /* 0x5a23 is the PCI ID for the IOMMU found on RD890S/RD990
++ */
++ { PCI_VENDOR_ID_ATI, 0x5a23 },
+ };
+
+ static bool cx23885_does_need_dma_reset(void)
+diff --git a/drivers/media/pci/saa7164/saa7164-encoder.c b/drivers/media/pci/saa7164/saa7164-encoder.c
+index 11e1eb6a6809e..1d1d32e043f16 100644
+--- a/drivers/media/pci/saa7164/saa7164-encoder.c
++++ b/drivers/media/pci/saa7164/saa7164-encoder.c
+@@ -1008,7 +1008,7 @@ int saa7164_encoder_register(struct saa7164_port *port)
+ printk(KERN_ERR "%s() failed (errno = %d), NO PCI configuration\n",
+ __func__, result);
+ result = -ENOMEM;
+- goto failed;
++ goto fail_pci;
+ }
+
+ /* Establish encoder defaults here */
+@@ -1062,7 +1062,7 @@ int saa7164_encoder_register(struct saa7164_port *port)
+ 100000, ENCODER_DEF_BITRATE);
+ if (hdl->error) {
+ result = hdl->error;
+- goto failed;
++ goto fail_hdl;
+ }
+
+ port->std = V4L2_STD_NTSC_M;
+@@ -1080,7 +1080,7 @@ int saa7164_encoder_register(struct saa7164_port *port)
+ printk(KERN_INFO "%s: can't allocate mpeg device\n",
+ dev->name);
+ result = -ENOMEM;
+- goto failed;
++ goto fail_hdl;
+ }
+
+ port->v4l_device->ctrl_handler = hdl;
+@@ -1091,10 +1091,7 @@ int saa7164_encoder_register(struct saa7164_port *port)
+ if (result < 0) {
+ printk(KERN_INFO "%s: can't register mpeg device\n",
+ dev->name);
+- /* TODO: We're going to leak here if we don't dealloc
+- The buffers above. The unreg function can't deal wit it.
+- */
+- goto failed;
++ goto fail_reg;
+ }
+
+ printk(KERN_INFO "%s: registered device video%d [mpeg]\n",
+@@ -1116,9 +1113,14 @@ int saa7164_encoder_register(struct saa7164_port *port)
+
+ saa7164_api_set_encoder(port);
+ saa7164_api_get_encoder(port);
++ return 0;
+
+- result = 0;
+-failed:
++fail_reg:
++ video_device_release(port->v4l_device);
++ port->v4l_device = NULL;
++fail_hdl:
++ v4l2_ctrl_handler_free(hdl);
++fail_pci:
+ return result;
+ }
+
+diff --git a/drivers/media/pci/sta2x11/Kconfig b/drivers/media/pci/sta2x11/Kconfig
+index 4dd98f94a91ed..27bb785136319 100644
+--- a/drivers/media/pci/sta2x11/Kconfig
++++ b/drivers/media/pci/sta2x11/Kconfig
+@@ -3,6 +3,7 @@ config STA2X11_VIP
+ tristate "STA2X11 VIP Video For Linux"
+ depends on PCI && VIDEO_V4L2 && VIRT_TO_BUS && I2C
+ depends on STA2X11 || COMPILE_TEST
++ select GPIOLIB if MEDIA_SUBDRV_AUTOSELECT
+ select VIDEO_ADV7180 if MEDIA_SUBDRV_AUTOSELECT
+ select VIDEOBUF2_DMA_CONTIG
+ select MEDIA_CONTROLLER
+diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c
+index 995e95272e511..e600764dce968 100644
+--- a/drivers/media/platform/coda/coda-common.c
++++ b/drivers/media/platform/coda/coda-common.c
+@@ -2062,7 +2062,9 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
+ if (q_data_dst->fourcc == V4L2_PIX_FMT_JPEG)
+ ctx->params.gop_size = 1;
+ ctx->gopcounter = ctx->params.gop_size - 1;
+- v4l2_ctrl_s_ctrl(ctx->mb_err_cnt_ctrl, 0);
++ /* Only decoders have this control */
++ if (ctx->mb_err_cnt_ctrl)
++ v4l2_ctrl_s_ctrl(ctx->mb_err_cnt_ctrl, 0);
+
+ ret = ctx->ops->start_streaming(ctx);
+ if (ctx->inst_type == CODA_INST_DECODER) {
+diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c
+index f9896c121fd89..d2842f496b474 100644
+--- a/drivers/media/platform/qcom/venus/core.c
++++ b/drivers/media/platform/qcom/venus/core.c
+@@ -218,7 +218,6 @@ static int venus_probe(struct platform_device *pdev)
+ return -ENOMEM;
+
+ core->dev = dev;
+- platform_set_drvdata(pdev, core);
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ core->base = devm_ioremap_resource(dev, r);
+@@ -248,7 +247,7 @@ static int venus_probe(struct platform_device *pdev)
+ return -ENODEV;
+
+ if (core->pm_ops->core_get) {
+- ret = core->pm_ops->core_get(dev);
++ ret = core->pm_ops->core_get(core);
+ if (ret)
+ return ret;
+ }
+@@ -273,6 +272,12 @@ static int venus_probe(struct platform_device *pdev)
+ if (ret)
+ goto err_core_put;
+
++ ret = v4l2_device_register(dev, &core->v4l2_dev);
++ if (ret)
++ goto err_core_deinit;
++
++ platform_set_drvdata(pdev, core);
++
+ pm_runtime_enable(dev);
+
+ ret = pm_runtime_get_sync(dev);
+@@ -307,10 +312,6 @@ static int venus_probe(struct platform_device *pdev)
+ if (ret)
+ goto err_venus_shutdown;
+
+- ret = v4l2_device_register(dev, &core->v4l2_dev);
+- if (ret)
+- goto err_core_deinit;
+-
+ ret = pm_runtime_put_sync(dev);
+ if (ret) {
+ pm_runtime_get_noresume(dev);
+@@ -323,8 +324,6 @@ static int venus_probe(struct platform_device *pdev)
+
+ err_dev_unregister:
+ v4l2_device_unregister(&core->v4l2_dev);
+-err_core_deinit:
+- hfi_core_deinit(core, false);
+ err_venus_shutdown:
+ venus_shutdown(core);
+ err_runtime_disable:
+@@ -332,9 +331,11 @@ err_runtime_disable:
+ pm_runtime_set_suspended(dev);
+ pm_runtime_disable(dev);
+ hfi_destroy(core);
++err_core_deinit:
++ hfi_core_deinit(core, false);
+ err_core_put:
+ if (core->pm_ops->core_put)
+- core->pm_ops->core_put(dev);
++ core->pm_ops->core_put(core);
+ return ret;
+ }
+
+@@ -360,7 +361,9 @@ static int venus_remove(struct platform_device *pdev)
+ pm_runtime_disable(dev);
+
+ if (pm_ops->core_put)
+- pm_ops->core_put(dev);
++ pm_ops->core_put(core);
++
++ v4l2_device_unregister(&core->v4l2_dev);
+
+ hfi_destroy(core);
+
+@@ -368,6 +371,7 @@ static int venus_remove(struct platform_device *pdev)
+ icc_put(core->cpucfg_path);
+
+ v4l2_device_unregister(&core->v4l2_dev);
++
+ mutex_destroy(&core->pm_lock);
+ mutex_destroy(&core->lock);
+ venus_dbgfs_deinit(core);
+@@ -396,7 +400,7 @@ static __maybe_unused int venus_runtime_suspend(struct device *dev)
+ return ret;
+
+ if (pm_ops->core_power) {
+- ret = pm_ops->core_power(dev, POWER_OFF);
++ ret = pm_ops->core_power(core, POWER_OFF);
+ if (ret)
+ return ret;
+ }
+@@ -414,7 +418,7 @@ static __maybe_unused int venus_runtime_suspend(struct device *dev)
+ err_video_path:
+ icc_set_bw(core->cpucfg_path, kbps_to_icc(1000), 0);
+ err_cpucfg_path:
+- pm_ops->core_power(dev, POWER_ON);
++ pm_ops->core_power(core, POWER_ON);
+
+ return ret;
+ }
+@@ -434,7 +438,7 @@ static __maybe_unused int venus_runtime_resume(struct device *dev)
+ return ret;
+
+ if (pm_ops->core_power) {
+- ret = pm_ops->core_power(dev, POWER_ON);
++ ret = pm_ops->core_power(core, POWER_ON);
+ if (ret)
+ return ret;
+ }
+diff --git a/drivers/media/platform/qcom/venus/hfi_cmds.c b/drivers/media/platform/qcom/venus/hfi_cmds.c
+index 4f75658344690..558510a8dfc82 100644
+--- a/drivers/media/platform/qcom/venus/hfi_cmds.c
++++ b/drivers/media/platform/qcom/venus/hfi_cmds.c
+@@ -1039,6 +1039,18 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
+ pkt->shdr.hdr.size += sizeof(u32) + sizeof(*hierp);
+ break;
+ }
++ case HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_INFO: {
++ struct hfi_uncompressed_plane_actual_info *in = pdata;
++ struct hfi_uncompressed_plane_actual_info *info = prop_data;
++
++ info->buffer_type = in->buffer_type;
++ info->num_planes = in->num_planes;
++ info->plane_format[0] = in->plane_format[0];
++ if (in->num_planes > 1)
++ info->plane_format[1] = in->plane_format[1];
++ pkt->shdr.hdr.size += sizeof(u32) + sizeof(*info);
++ break;
++ }
+
+ /* FOLLOWING PROPERTIES ARE NOT IMPLEMENTED IN CORE YET */
+ case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS:
+@@ -1205,18 +1217,6 @@ pkt_session_set_property_4xx(struct hfi_session_set_property_pkt *pkt,
+ pkt->shdr.hdr.size += sizeof(u32) + sizeof(*cu);
+ break;
+ }
+- case HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_INFO: {
+- struct hfi_uncompressed_plane_actual_info *in = pdata;
+- struct hfi_uncompressed_plane_actual_info *info = prop_data;
+-
+- info->buffer_type = in->buffer_type;
+- info->num_planes = in->num_planes;
+- info->plane_format[0] = in->plane_format[0];
+- if (in->num_planes > 1)
+- info->plane_format[1] = in->plane_format[1];
+- pkt->shdr.hdr.size += sizeof(u32) + sizeof(*info);
+- break;
+- }
+ case HFI_PROPERTY_CONFIG_VENC_MAX_BITRATE:
+ case HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER:
+ case HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE:
+diff --git a/drivers/media/platform/qcom/venus/hfi_parser.c b/drivers/media/platform/qcom/venus/hfi_parser.c
+index 7263c0c326954..5b8389b982993 100644
+--- a/drivers/media/platform/qcom/venus/hfi_parser.c
++++ b/drivers/media/platform/qcom/venus/hfi_parser.c
+@@ -235,13 +235,13 @@ static int hfi_platform_parser(struct venus_core *core, struct venus_inst *inst)
+ u32 enc_codecs, dec_codecs, count = 0;
+ unsigned int entries;
+
+- if (inst)
+- return 0;
+-
+ plat = hfi_platform_get(core->res->hfi_version);
+ if (!plat)
+ return -EINVAL;
+
++ if (inst)
++ return 0;
++
+ if (plat->codecs)
+ plat->codecs(&enc_codecs, &dec_codecs, &count);
+
+@@ -277,8 +277,10 @@ u32 hfi_parser(struct venus_core *core, struct venus_inst *inst, void *buf,
+
+ parser_init(inst, &codecs, &domain);
+
+- core->codecs_count = 0;
+- memset(core->caps, 0, sizeof(core->caps));
++ if (core->res->hfi_version > HFI_VERSION_1XX) {
++ core->codecs_count = 0;
++ memset(core->caps, 0, sizeof(core->caps));
++ }
+
+ while (words_count) {
+ data = word + 1;
+diff --git a/drivers/media/platform/qcom/venus/pm_helpers.c b/drivers/media/platform/qcom/venus/pm_helpers.c
+index 43c4e3d9e2818..95b4d40ff6a5e 100644
+--- a/drivers/media/platform/qcom/venus/pm_helpers.c
++++ b/drivers/media/platform/qcom/venus/pm_helpers.c
+@@ -277,16 +277,28 @@ set_freq:
+ return 0;
+ }
+
+-static int core_get_v1(struct device *dev)
++static int core_get_v1(struct venus_core *core)
+ {
+- struct venus_core *core = dev_get_drvdata(dev);
++ int ret;
++
++ ret = core_clks_get(core);
++ if (ret)
++ return ret;
+
+- return core_clks_get(core);
++ core->opp_table = dev_pm_opp_set_clkname(core->dev, "core");
++ if (IS_ERR(core->opp_table))
++ return PTR_ERR(core->opp_table);
++
++ return 0;
+ }
+
+-static int core_power_v1(struct device *dev, int on)
++static void core_put_v1(struct venus_core *core)
++{
++ dev_pm_opp_put_clkname(core->opp_table);
++}
++
++static int core_power_v1(struct venus_core *core, int on)
+ {
+- struct venus_core *core = dev_get_drvdata(dev);
+ int ret = 0;
+
+ if (on == POWER_ON)
+@@ -299,6 +311,7 @@ static int core_power_v1(struct device *dev, int on)
+
+ static const struct venus_pm_ops pm_ops_v1 = {
+ .core_get = core_get_v1,
++ .core_put = core_put_v1,
+ .core_power = core_power_v1,
+ .load_scale = load_scale_v1,
+ };
+@@ -371,6 +384,7 @@ static int venc_power_v3(struct device *dev, int on)
+
+ static const struct venus_pm_ops pm_ops_v3 = {
+ .core_get = core_get_v1,
++ .core_put = core_put_v1,
+ .core_power = core_power_v1,
+ .vdec_get = vdec_get_v3,
+ .vdec_power = vdec_power_v3,
+@@ -753,12 +767,12 @@ static int venc_power_v4(struct device *dev, int on)
+ return ret;
+ }
+
+-static int vcodec_domains_get(struct device *dev)
++static int vcodec_domains_get(struct venus_core *core)
+ {
+ int ret;
+ struct opp_table *opp_table;
+ struct device **opp_virt_dev;
+- struct venus_core *core = dev_get_drvdata(dev);
++ struct device *dev = core->dev;
+ const struct venus_resources *res = core->res;
+ struct device *pd;
+ unsigned int i;
+@@ -809,9 +823,8 @@ opp_attach_err:
+ return ret;
+ }
+
+-static void vcodec_domains_put(struct device *dev)
++static void vcodec_domains_put(struct venus_core *core)
+ {
+- struct venus_core *core = dev_get_drvdata(dev);
+ const struct venus_resources *res = core->res;
+ unsigned int i;
+
+@@ -834,9 +847,9 @@ skip_pmdomains:
+ dev_pm_opp_detach_genpd(core->opp_table);
+ }
+
+-static int core_get_v4(struct device *dev)
++static int core_get_v4(struct venus_core *core)
+ {
+- struct venus_core *core = dev_get_drvdata(dev);
++ struct device *dev = core->dev;
+ const struct venus_resources *res = core->res;
+ int ret;
+
+@@ -875,7 +888,7 @@ static int core_get_v4(struct device *dev)
+ }
+ }
+
+- ret = vcodec_domains_get(dev);
++ ret = vcodec_domains_get(core);
+ if (ret) {
+ if (core->has_opp_table)
+ dev_pm_opp_of_remove_table(dev);
+@@ -886,14 +899,14 @@ static int core_get_v4(struct device *dev)
+ return 0;
+ }
+
+-static void core_put_v4(struct device *dev)
++static void core_put_v4(struct venus_core *core)
+ {
+- struct venus_core *core = dev_get_drvdata(dev);
++ struct device *dev = core->dev;
+
+ if (legacy_binding)
+ return;
+
+- vcodec_domains_put(dev);
++ vcodec_domains_put(core);
+
+ if (core->has_opp_table)
+ dev_pm_opp_of_remove_table(dev);
+@@ -901,9 +914,9 @@ static void core_put_v4(struct device *dev)
+
+ }
+
+-static int core_power_v4(struct device *dev, int on)
++static int core_power_v4(struct venus_core *core, int on)
+ {
+- struct venus_core *core = dev_get_drvdata(dev);
++ struct device *dev = core->dev;
+ struct device *pmctrl = core->pmdomains[0];
+ int ret = 0;
+
+diff --git a/drivers/media/platform/qcom/venus/pm_helpers.h b/drivers/media/platform/qcom/venus/pm_helpers.h
+index aa2f6afa23544..a492c50c5543c 100644
+--- a/drivers/media/platform/qcom/venus/pm_helpers.h
++++ b/drivers/media/platform/qcom/venus/pm_helpers.h
+@@ -4,14 +4,15 @@
+ #define __VENUS_PM_HELPERS_H__
+
+ struct device;
++struct venus_core;
+
+ #define POWER_ON 1
+ #define POWER_OFF 0
+
+ struct venus_pm_ops {
+- int (*core_get)(struct device *dev);
+- void (*core_put)(struct device *dev);
+- int (*core_power)(struct device *dev, int on);
++ int (*core_get)(struct venus_core *core);
++ void (*core_put)(struct venus_core *core);
++ int (*core_power)(struct venus_core *core, int on);
+
+ int (*vdec_get)(struct device *dev);
+ void (*vdec_put)(struct device *dev);
+diff --git a/drivers/media/platform/qcom/venus/venc_ctrls.c b/drivers/media/platform/qcom/venus/venc_ctrls.c
+index a52b800551737..abef0037bf55b 100644
+--- a/drivers/media/platform/qcom/venus/venc_ctrls.c
++++ b/drivers/media/platform/qcom/venus/venc_ctrls.c
+@@ -359,7 +359,7 @@ int venc_ctrl_init(struct venus_inst *inst)
+ V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME,
+ ~((1 << V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE) |
+ (1 << V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME)),
+- V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE);
++ V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME);
+
+ v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE,
+diff --git a/drivers/media/platform/sti/bdisp/bdisp-debug.c b/drivers/media/platform/sti/bdisp/bdisp-debug.c
+index 2b270093009c7..a27f638df11c6 100644
+--- a/drivers/media/platform/sti/bdisp/bdisp-debug.c
++++ b/drivers/media/platform/sti/bdisp/bdisp-debug.c
+@@ -480,7 +480,7 @@ static int regs_show(struct seq_file *s, void *data)
+ int ret;
+ unsigned int i;
+
+- ret = pm_runtime_get_sync(bdisp->dev);
++ ret = pm_runtime_resume_and_get(bdisp->dev);
+ if (ret < 0) {
+ seq_puts(s, "Cannot wake up IP\n");
+ return 0;
+diff --git a/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c b/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c
+index ed863bf5ea804..671e4a928993d 100644
+--- a/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c
++++ b/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c
+@@ -589,7 +589,7 @@ static int deinterlace_start_streaming(struct vb2_queue *vq, unsigned int count)
+ int ret;
+
+ if (V4L2_TYPE_IS_OUTPUT(vq->type)) {
+- ret = pm_runtime_get_sync(dev);
++ ret = pm_runtime_resume_and_get(dev);
+ if (ret < 0) {
+ dev_err(dev, "Failed to enable module\n");
+
+diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c
+index 0c6229592e132..e5c4a6941d26b 100644
+--- a/drivers/media/rc/ite-cir.c
++++ b/drivers/media/rc/ite-cir.c
+@@ -276,8 +276,14 @@ static irqreturn_t ite_cir_isr(int irq, void *data)
+ /* read the interrupt flags */
+ iflags = dev->params.get_irq_causes(dev);
+
++ /* Check for RX overflow */
++ if (iflags & ITE_IRQ_RX_FIFO_OVERRUN) {
++ dev_warn(&dev->rdev->dev, "receive overflow\n");
++ ir_raw_event_reset(dev->rdev);
++ }
++
+ /* check for the receive interrupt */
+- if (iflags & (ITE_IRQ_RX_FIFO | ITE_IRQ_RX_FIFO_OVERRUN)) {
++ if (iflags & ITE_IRQ_RX_FIFO) {
+ /* read the FIFO bytes */
+ rx_bytes =
+ dev->params.get_rx_bytes(dev, rx_buf,
+diff --git a/drivers/media/test-drivers/vivid/vivid-core.c b/drivers/media/test-drivers/vivid/vivid-core.c
+index 0dc65ef3aa14d..ca0ebf6ad9ccf 100644
+--- a/drivers/media/test-drivers/vivid/vivid-core.c
++++ b/drivers/media/test-drivers/vivid/vivid-core.c
+@@ -205,13 +205,13 @@ static const u8 vivid_hdmi_edid[256] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x7b,
+
+- 0x02, 0x03, 0x3f, 0xf0, 0x51, 0x61, 0x60, 0x5f,
++ 0x02, 0x03, 0x3f, 0xf1, 0x51, 0x61, 0x60, 0x5f,
+ 0x5e, 0x5d, 0x10, 0x1f, 0x04, 0x13, 0x22, 0x21,
+ 0x20, 0x05, 0x14, 0x02, 0x11, 0x01, 0x23, 0x09,
+ 0x07, 0x07, 0x83, 0x01, 0x00, 0x00, 0x6d, 0x03,
+ 0x0c, 0x00, 0x10, 0x00, 0x00, 0x3c, 0x21, 0x00,
+ 0x60, 0x01, 0x02, 0x03, 0x67, 0xd8, 0x5d, 0xc4,
+- 0x01, 0x78, 0x00, 0x00, 0xe2, 0x00, 0xea, 0xe3,
++ 0x01, 0x78, 0x00, 0x00, 0xe2, 0x00, 0xca, 0xe3,
+ 0x05, 0x00, 0x00, 0xe3, 0x06, 0x01, 0x00, 0x4d,
+ 0xd0, 0x00, 0xa0, 0xf0, 0x70, 0x3e, 0x80, 0x30,
+ 0x20, 0x35, 0x00, 0xc0, 0x1c, 0x32, 0x00, 0x00,
+@@ -220,7 +220,7 @@ static const u8 vivid_hdmi_edid[256] = {
+ 0x00, 0x00, 0x1a, 0x1a, 0x1d, 0x00, 0x80, 0x51,
+ 0xd0, 0x1c, 0x20, 0x40, 0x80, 0x35, 0x00, 0xc0,
+ 0x1c, 0x32, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,
+- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63,
++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82,
+ };
+
+ static int vidioc_querycap(struct file *file, void *priv,
+diff --git a/drivers/media/usb/dvb-usb/dvb-usb-init.c b/drivers/media/usb/dvb-usb/dvb-usb-init.c
+index c1a7634e27b43..28e1fd64dd3c2 100644
+--- a/drivers/media/usb/dvb-usb/dvb-usb-init.c
++++ b/drivers/media/usb/dvb-usb/dvb-usb-init.c
+@@ -79,11 +79,17 @@ static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs)
+ }
+ }
+
+- if ((ret = dvb_usb_adapter_stream_init(adap)) ||
+- (ret = dvb_usb_adapter_dvb_init(adap, adapter_nrs)) ||
+- (ret = dvb_usb_adapter_frontend_init(adap))) {
++ ret = dvb_usb_adapter_stream_init(adap);
++ if (ret)
+ return ret;
+- }
++
++ ret = dvb_usb_adapter_dvb_init(adap, adapter_nrs);
++ if (ret)
++ goto dvb_init_err;
++
++ ret = dvb_usb_adapter_frontend_init(adap);
++ if (ret)
++ goto frontend_init_err;
+
+ /* use exclusive FE lock if there is multiple shared FEs */
+ if (adap->fe_adap[1].fe)
+@@ -103,6 +109,12 @@ static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs)
+ }
+
+ return 0;
++
++frontend_init_err:
++ dvb_usb_adapter_dvb_exit(adap);
++dvb_init_err:
++ dvb_usb_adapter_stream_exit(adap);
++ return ret;
+ }
+
+ static int dvb_usb_adapter_exit(struct dvb_usb_device *d)
+@@ -158,22 +170,20 @@ static int dvb_usb_init(struct dvb_usb_device *d, short *adapter_nums)
+
+ if (d->props.priv_init != NULL) {
+ ret = d->props.priv_init(d);
+- if (ret != 0) {
+- kfree(d->priv);
+- d->priv = NULL;
+- return ret;
+- }
++ if (ret != 0)
++ goto err_priv_init;
+ }
+ }
+
+ /* check the capabilities and set appropriate variables */
+ dvb_usb_device_power_ctrl(d, 1);
+
+- if ((ret = dvb_usb_i2c_init(d)) ||
+- (ret = dvb_usb_adapter_init(d, adapter_nums))) {
+- dvb_usb_exit(d);
+- return ret;
+- }
++ ret = dvb_usb_i2c_init(d);
++ if (ret)
++ goto err_i2c_init;
++ ret = dvb_usb_adapter_init(d, adapter_nums);
++ if (ret)
++ goto err_adapter_init;
+
+ if ((ret = dvb_usb_remote_init(d)))
+ err("could not initialize remote control.");
+@@ -181,6 +191,17 @@ static int dvb_usb_init(struct dvb_usb_device *d, short *adapter_nums)
+ dvb_usb_device_power_ctrl(d, 0);
+
+ return 0;
++
++err_adapter_init:
++ dvb_usb_adapter_exit(d);
++err_i2c_init:
++ dvb_usb_i2c_exit(d);
++ if (d->priv && d->props.priv_destroy)
++ d->props.priv_destroy(d);
++err_priv_init:
++ kfree(d->priv);
++ d->priv = NULL;
++ return ret;
+ }
+
+ /* determine the name and the state of the just found USB device */
+@@ -255,41 +276,50 @@ int dvb_usb_device_init(struct usb_interface *intf,
+ if (du != NULL)
+ *du = NULL;
+
+- if ((desc = dvb_usb_find_device(udev, props, &cold)) == NULL) {
++ d = kzalloc(sizeof(*d), GFP_KERNEL);
++ if (!d) {
++ err("no memory for 'struct dvb_usb_device'");
++ return -ENOMEM;
++ }
++
++ memcpy(&d->props, props, sizeof(struct dvb_usb_device_properties));
++
++ desc = dvb_usb_find_device(udev, &d->props, &cold);
++ if (!desc) {
+ deb_err("something went very wrong, device was not found in current device list - let's see what comes next.\n");
+- return -ENODEV;
++ ret = -ENODEV;
++ goto error;
+ }
+
+ if (cold) {
+ info("found a '%s' in cold state, will try to load a firmware", desc->name);
+ ret = dvb_usb_download_firmware(udev, props);
+ if (!props->no_reconnect || ret != 0)
+- return ret;
++ goto error;
+ }
+
+ info("found a '%s' in warm state.", desc->name);
+- d = kzalloc(sizeof(struct dvb_usb_device), GFP_KERNEL);
+- if (d == NULL) {
+- err("no memory for 'struct dvb_usb_device'");
+- return -ENOMEM;
+- }
+-
+ d->udev = udev;
+- memcpy(&d->props, props, sizeof(struct dvb_usb_device_properties));
+ d->desc = desc;
+ d->owner = owner;
+
+ usb_set_intfdata(intf, d);
+
+- if (du != NULL)
++ ret = dvb_usb_init(d, adapter_nums);
++ if (ret) {
++ info("%s error while loading driver (%d)", desc->name, ret);
++ goto error;
++ }
++
++ if (du)
+ *du = d;
+
+- ret = dvb_usb_init(d, adapter_nums);
++ info("%s successfully initialized and connected.", desc->name);
++ return 0;
+
+- if (ret == 0)
+- info("%s successfully initialized and connected.", desc->name);
+- else
+- info("%s error while loading driver (%d)", desc->name, ret);
++ error:
++ usb_set_intfdata(intf, NULL);
++ kfree(d);
+ return ret;
+ }
+ EXPORT_SYMBOL(dvb_usb_device_init);
+diff --git a/drivers/media/usb/dvb-usb/dvb-usb.h b/drivers/media/usb/dvb-usb/dvb-usb.h
+index 741be0e694471..2b8ad2bde8a48 100644
+--- a/drivers/media/usb/dvb-usb/dvb-usb.h
++++ b/drivers/media/usb/dvb-usb/dvb-usb.h
+@@ -487,7 +487,7 @@ extern int __must_check
+ dvb_usb_generic_write(struct dvb_usb_device *, u8 *, u16);
+
+ /* commonly used remote control parsing */
+-extern int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *, u8[], u32 *, int *);
++extern int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *, u8[5], u32 *, int *);
+
+ /* commonly used firmware download types and function */
+ struct hexline {
+diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c
+index 5264242796370..471bd74667e3c 100644
+--- a/drivers/media/usb/em28xx/em28xx-dvb.c
++++ b/drivers/media/usb/em28xx/em28xx-dvb.c
+@@ -2010,6 +2010,7 @@ ret:
+ return result;
+
+ out_free:
++ em28xx_uninit_usb_xfer(dev, EM28XX_DIGITAL_MODE);
+ kfree(dvb);
+ dev->dvb = NULL;
+ goto ret;
+diff --git a/drivers/media/usb/gspca/gspca.c b/drivers/media/usb/gspca/gspca.c
+index 158c8e28ed2cc..47d8f28bfdfc2 100644
+--- a/drivers/media/usb/gspca/gspca.c
++++ b/drivers/media/usb/gspca/gspca.c
+@@ -1576,6 +1576,8 @@ out:
+ #endif
+ v4l2_ctrl_handler_free(gspca_dev->vdev.ctrl_handler);
+ v4l2_device_unregister(&gspca_dev->v4l2_dev);
++ if (sd_desc->probe_error)
++ sd_desc->probe_error(gspca_dev);
+ kfree(gspca_dev->usb_buf);
+ kfree(gspca_dev);
+ return ret;
+diff --git a/drivers/media/usb/gspca/gspca.h b/drivers/media/usb/gspca/gspca.h
+index b0ced2e140064..a6554d5e9e1a5 100644
+--- a/drivers/media/usb/gspca/gspca.h
++++ b/drivers/media/usb/gspca/gspca.h
+@@ -105,6 +105,7 @@ struct sd_desc {
+ cam_cf_op config; /* called on probe */
+ cam_op init; /* called on probe and resume */
+ cam_op init_controls; /* called on probe */
++ cam_v_op probe_error; /* called if probe failed, do cleanup here */
+ cam_op start; /* called on stream on after URBs creation */
+ cam_pkt_op pkt_scan;
+ /* optional operations */
+diff --git a/drivers/media/usb/gspca/sq905.c b/drivers/media/usb/gspca/sq905.c
+index 97799cfb832e3..9491110709718 100644
+--- a/drivers/media/usb/gspca/sq905.c
++++ b/drivers/media/usb/gspca/sq905.c
+@@ -158,7 +158,7 @@ static int
+ sq905_read_data(struct gspca_dev *gspca_dev, u8 *data, int size, int need_lock)
+ {
+ int ret;
+- int act_len;
++ int act_len = 0;
+
+ gspca_dev->usb_buf[0] = '\0';
+ if (need_lock)
+diff --git a/drivers/media/usb/gspca/stv06xx/stv06xx.c b/drivers/media/usb/gspca/stv06xx/stv06xx.c
+index 95673fc0a99c5..d9bc2aacc8851 100644
+--- a/drivers/media/usb/gspca/stv06xx/stv06xx.c
++++ b/drivers/media/usb/gspca/stv06xx/stv06xx.c
+@@ -529,12 +529,21 @@ static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
+ static int stv06xx_config(struct gspca_dev *gspca_dev,
+ const struct usb_device_id *id);
+
++static void stv06xx_probe_error(struct gspca_dev *gspca_dev)
++{
++ struct sd *sd = (struct sd *)gspca_dev;
++
++ kfree(sd->sensor_priv);
++ sd->sensor_priv = NULL;
++}
++
+ /* sub-driver description */
+ static const struct sd_desc sd_desc = {
+ .name = MODULE_NAME,
+ .config = stv06xx_config,
+ .init = stv06xx_init,
+ .init_controls = stv06xx_init_controls,
++ .probe_error = stv06xx_probe_error,
+ .start = stv06xx_start,
+ .stopN = stv06xx_stopN,
+ .pkt_scan = stv06xx_pkt_scan,
+diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
+index 30ef2a3110f72..9a791d8ef200d 100644
+--- a/drivers/media/usb/uvc/uvc_driver.c
++++ b/drivers/media/usb/uvc/uvc_driver.c
+@@ -1712,10 +1712,35 @@ static int uvc_scan_chain_forward(struct uvc_video_chain *chain,
+ if (forward->bNrInPins != 1) {
+ uvc_dbg(chain->dev, DESCR,
+ "Extension unit %d has more than 1 input pin\n",
+- entity->id);
++ forward->id);
+ return -EINVAL;
+ }
+
++ /*
++ * Some devices reference an output terminal as the
++ * source of extension units. This is incorrect, as
++ * output terminals only have an input pin, and thus
++ * can't be connected to any entity in the forward
++ * direction. The resulting topology would cause issues
++ * when registering the media controller graph. To
++ * avoid this problem, connect the extension unit to
++ * the source of the output terminal instead.
++ */
++ if (UVC_ENTITY_IS_OTERM(entity)) {
++ struct uvc_entity *source;
++
++ source = uvc_entity_by_id(chain->dev,
++ entity->baSourceID[0]);
++ if (!source) {
++ uvc_dbg(chain->dev, DESCR,
++ "Can't connect extension unit %u in chain\n",
++ forward->id);
++ break;
++ }
++
++ forward->baSourceID[0] = source->id;
++ }
++
+ list_add_tail(&forward->chain, &chain->entities);
+ if (!found)
+ uvc_dbg_cont(PROBE, " (->");
+@@ -1735,6 +1760,13 @@ static int uvc_scan_chain_forward(struct uvc_video_chain *chain,
+ return -EINVAL;
+ }
+
++ if (UVC_ENTITY_IS_OTERM(entity)) {
++ uvc_dbg(chain->dev, DESCR,
++ "Unsupported connection between output terminals %u and %u\n",
++ entity->id, forward->id);
++ break;
++ }
++
+ list_add_tail(&forward->chain, &chain->entities);
+ if (!found)
+ uvc_dbg_cont(PROBE, " (->");
+diff --git a/drivers/media/usb/zr364xx/zr364xx.c b/drivers/media/usb/zr364xx/zr364xx.c
+index d29b861367ea7..1ef611e083237 100644
+--- a/drivers/media/usb/zr364xx/zr364xx.c
++++ b/drivers/media/usb/zr364xx/zr364xx.c
+@@ -1430,7 +1430,7 @@ static int zr364xx_probe(struct usb_interface *intf,
+ if (hdl->error) {
+ err = hdl->error;
+ dev_err(&udev->dev, "couldn't register control\n");
+- goto unregister;
++ goto free_hdlr_and_unreg_dev;
+ }
+ /* save the init method used by this camera */
+ cam->method = id->driver_info;
+@@ -1503,7 +1503,7 @@ static int zr364xx_probe(struct usb_interface *intf,
+ if (!cam->read_endpoint) {
+ err = -ENOMEM;
+ dev_err(&intf->dev, "Could not find bulk-in endpoint\n");
+- goto unregister;
++ goto free_hdlr_and_unreg_dev;
+ }
+
+ /* v4l */
+@@ -1515,7 +1515,7 @@ static int zr364xx_probe(struct usb_interface *intf,
+ /* load zr364xx board specific */
+ err = zr364xx_board_init(cam);
+ if (err)
+- goto unregister;
++ goto free_hdlr_and_unreg_dev;
+ err = v4l2_ctrl_handler_setup(hdl);
+ if (err)
+ goto board_uninit;
+@@ -1533,7 +1533,7 @@ static int zr364xx_probe(struct usb_interface *intf,
+ err = video_register_device(&cam->vdev, VFL_TYPE_VIDEO, -1);
+ if (err) {
+ dev_err(&udev->dev, "video_register_device failed\n");
+- goto free_handler;
++ goto board_uninit;
+ }
+ cam->v4l2_dev.release = zr364xx_release;
+
+@@ -1541,11 +1541,10 @@ static int zr364xx_probe(struct usb_interface *intf,
+ video_device_node_name(&cam->vdev));
+ return 0;
+
+-free_handler:
+- v4l2_ctrl_handler_free(hdl);
+ board_uninit:
+ zr364xx_board_uninit(cam);
+-unregister:
++free_hdlr_and_unreg_dev:
++ v4l2_ctrl_handler_free(hdl);
+ v4l2_device_unregister(&cam->v4l2_dev);
+ free_cam:
+ kfree(cam);
+diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
+index 016cf6204cbb8..4f0209695f132 100644
+--- a/drivers/media/v4l2-core/v4l2-ctrls.c
++++ b/drivers/media/v4l2-core/v4l2-ctrls.c
+@@ -1675,6 +1675,8 @@ static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx,
+ p_fwht_params->version = V4L2_FWHT_VERSION;
+ p_fwht_params->width = 1280;
+ p_fwht_params->height = 720;
++ p_fwht_params->flags = V4L2_FWHT_FL_PIXENC_YUV |
++ (2 << V4L2_FWHT_FL_COMPONENTS_NUM_OFFSET);
+ break;
+ }
+ }
+@@ -2395,7 +2397,16 @@ static void new_to_req(struct v4l2_ctrl_ref *ref)
+ if (!ref)
+ return;
+ ptr_to_ptr(ref->ctrl, ref->ctrl->p_new, ref->p_req);
+- ref->req = ref;
++ ref->valid_p_req = true;
++}
++
++/* Copy the current value to the request value */
++static void cur_to_req(struct v4l2_ctrl_ref *ref)
++{
++ if (!ref)
++ return;
++ ptr_to_ptr(ref->ctrl, ref->ctrl->p_cur, ref->p_req);
++ ref->valid_p_req = true;
+ }
+
+ /* Copy the request value to the new value */
+@@ -2403,8 +2414,8 @@ static void req_to_new(struct v4l2_ctrl_ref *ref)
+ {
+ if (!ref)
+ return;
+- if (ref->req)
+- ptr_to_ptr(ref->ctrl, ref->req->p_req, ref->ctrl->p_new);
++ if (ref->valid_p_req)
++ ptr_to_ptr(ref->ctrl, ref->p_req, ref->ctrl->p_new);
+ else
+ ptr_to_ptr(ref->ctrl, ref->ctrl->p_cur, ref->ctrl->p_new);
+ }
+@@ -3571,39 +3582,8 @@ static void v4l2_ctrl_request_queue(struct media_request_object *obj)
+ struct v4l2_ctrl_handler *hdl =
+ container_of(obj, struct v4l2_ctrl_handler, req_obj);
+ struct v4l2_ctrl_handler *main_hdl = obj->priv;
+- struct v4l2_ctrl_handler *prev_hdl = NULL;
+- struct v4l2_ctrl_ref *ref_ctrl, *ref_ctrl_prev = NULL;
+
+ mutex_lock(main_hdl->lock);
+- if (list_empty(&main_hdl->requests_queued))
+- goto queue;
+-
+- prev_hdl = list_last_entry(&main_hdl->requests_queued,
+- struct v4l2_ctrl_handler, requests_queued);
+- /*
+- * Note: prev_hdl and hdl must contain the same list of control
+- * references, so if any differences are detected then that is a
+- * driver bug and the WARN_ON is triggered.
+- */
+- mutex_lock(prev_hdl->lock);
+- ref_ctrl_prev = list_first_entry(&prev_hdl->ctrl_refs,
+- struct v4l2_ctrl_ref, node);
+- list_for_each_entry(ref_ctrl, &hdl->ctrl_refs, node) {
+- if (ref_ctrl->req)
+- continue;
+- while (ref_ctrl_prev->ctrl->id < ref_ctrl->ctrl->id) {
+- /* Should never happen, but just in case... */
+- if (list_is_last(&ref_ctrl_prev->node,
+- &prev_hdl->ctrl_refs))
+- break;
+- ref_ctrl_prev = list_next_entry(ref_ctrl_prev, node);
+- }
+- if (WARN_ON(ref_ctrl_prev->ctrl->id != ref_ctrl->ctrl->id))
+- break;
+- ref_ctrl->req = ref_ctrl_prev->req;
+- }
+- mutex_unlock(prev_hdl->lock);
+-queue:
+ list_add_tail(&hdl->requests_queued, &main_hdl->requests_queued);
+ hdl->request_is_queued = true;
+ mutex_unlock(main_hdl->lock);
+@@ -3660,7 +3640,7 @@ v4l2_ctrl_request_hdl_ctrl_find(struct v4l2_ctrl_handler *hdl, u32 id)
+ {
+ struct v4l2_ctrl_ref *ref = find_ref_lock(hdl, id);
+
+- return (ref && ref->req == ref) ? ref->ctrl : NULL;
++ return (ref && ref->valid_p_req) ? ref->ctrl : NULL;
+ }
+ EXPORT_SYMBOL_GPL(v4l2_ctrl_request_hdl_ctrl_find);
+
+@@ -3846,7 +3826,13 @@ static int class_check(struct v4l2_ctrl_handler *hdl, u32 which)
+ return find_ref_lock(hdl, which | 1) ? 0 : -EINVAL;
+ }
+
+-/* Get extended controls. Allocates the helpers array if needed. */
++/*
++ * Get extended controls. Allocates the helpers array if needed.
++ *
++ * Note that v4l2_g_ext_ctrls_common() with 'which' set to
++ * V4L2_CTRL_WHICH_REQUEST_VAL is only called if the request was
++ * completed, and in that case valid_p_req is true for all controls.
++ */
+ static int v4l2_g_ext_ctrls_common(struct v4l2_ctrl_handler *hdl,
+ struct v4l2_ext_controls *cs,
+ struct video_device *vdev)
+@@ -3855,9 +3841,10 @@ static int v4l2_g_ext_ctrls_common(struct v4l2_ctrl_handler *hdl,
+ struct v4l2_ctrl_helper *helpers = helper;
+ int ret;
+ int i, j;
+- bool def_value;
++ bool is_default, is_request;
+
+- def_value = (cs->which == V4L2_CTRL_WHICH_DEF_VAL);
++ is_default = (cs->which == V4L2_CTRL_WHICH_DEF_VAL);
++ is_request = (cs->which == V4L2_CTRL_WHICH_REQUEST_VAL);
+
+ cs->error_idx = cs->count;
+ cs->which = V4L2_CTRL_ID2WHICH(cs->which);
+@@ -3883,11 +3870,9 @@ static int v4l2_g_ext_ctrls_common(struct v4l2_ctrl_handler *hdl,
+ ret = -EACCES;
+
+ for (i = 0; !ret && i < cs->count; i++) {
+- int (*ctrl_to_user)(struct v4l2_ext_control *c,
+- struct v4l2_ctrl *ctrl);
+ struct v4l2_ctrl *master;
+-
+- ctrl_to_user = def_value ? def_to_user : cur_to_user;
++ bool is_volatile = false;
++ u32 idx = i;
+
+ if (helpers[i].mref == NULL)
+ continue;
+@@ -3897,31 +3882,48 @@ static int v4l2_g_ext_ctrls_common(struct v4l2_ctrl_handler *hdl,
+
+ v4l2_ctrl_lock(master);
+
+- /* g_volatile_ctrl will update the new control values */
+- if (!def_value &&
++ /*
++ * g_volatile_ctrl will update the new control values.
++ * This makes no sense for V4L2_CTRL_WHICH_DEF_VAL and
++ * V4L2_CTRL_WHICH_REQUEST_VAL. In the case of requests
++ * it is v4l2_ctrl_request_complete() that copies the
++ * volatile controls at the time of request completion
++ * to the request, so you don't want to do that again.
++ */
++ if (!is_default && !is_request &&
+ ((master->flags & V4L2_CTRL_FLAG_VOLATILE) ||
+ (master->has_volatiles && !is_cur_manual(master)))) {
+ for (j = 0; j < master->ncontrols; j++)
+ cur_to_new(master->cluster[j]);
+ ret = call_op(master, g_volatile_ctrl);
+- ctrl_to_user = new_to_user;
++ is_volatile = true;
+ }
+- /* If OK, then copy the current (for non-volatile controls)
+- or the new (for volatile controls) control values to the
+- caller */
+- if (!ret) {
+- u32 idx = i;
+
+- do {
+- if (helpers[idx].ref->req)
+- ret = req_to_user(cs->controls + idx,
+- helpers[idx].ref->req);
+- else
+- ret = ctrl_to_user(cs->controls + idx,
+- helpers[idx].ref->ctrl);
+- idx = helpers[idx].next;
+- } while (!ret && idx);
++ if (ret) {
++ v4l2_ctrl_unlock(master);
++ break;
+ }
++
++ /*
++ * Copy the default value (if is_default is true), the
++ * request value (if is_request is true and p_req is valid),
++ * the new volatile value (if is_volatile is true) or the
++ * current value.
++ */
++ do {
++ struct v4l2_ctrl_ref *ref = helpers[idx].ref;
++
++ if (is_default)
++ ret = def_to_user(cs->controls + idx, ref->ctrl);
++ else if (is_request && ref->valid_p_req)
++ ret = req_to_user(cs->controls + idx, ref);
++ else if (is_volatile)
++ ret = new_to_user(cs->controls + idx, ref->ctrl);
++ else
++ ret = cur_to_user(cs->controls + idx, ref->ctrl);
++ idx = helpers[idx].next;
++ } while (!ret && idx);
++
+ v4l2_ctrl_unlock(master);
+ }
+
+@@ -4564,8 +4566,6 @@ void v4l2_ctrl_request_complete(struct media_request *req,
+ unsigned int i;
+
+ if (ctrl->flags & V4L2_CTRL_FLAG_VOLATILE) {
+- ref->req = ref;
+-
+ v4l2_ctrl_lock(master);
+ /* g_volatile_ctrl will update the current control values */
+ for (i = 0; i < master->ncontrols; i++)
+@@ -4575,21 +4575,12 @@ void v4l2_ctrl_request_complete(struct media_request *req,
+ v4l2_ctrl_unlock(master);
+ continue;
+ }
+- if (ref->req == ref)
++ if (ref->valid_p_req)
+ continue;
+
++ /* Copy the current control value into the request */
+ v4l2_ctrl_lock(ctrl);
+- if (ref->req) {
+- ptr_to_ptr(ctrl, ref->req->p_req, ref->p_req);
+- } else {
+- ptr_to_ptr(ctrl, ctrl->p_cur, ref->p_req);
+- /*
+- * Set ref->req to ensure that when userspace wants to
+- * obtain the controls of this request it will take
+- * this value and not the current value of the control.
+- */
+- ref->req = ref;
+- }
++ cur_to_req(ref);
+ v4l2_ctrl_unlock(ctrl);
+ }
+
+@@ -4653,7 +4644,7 @@ int v4l2_ctrl_request_setup(struct media_request *req,
+ struct v4l2_ctrl_ref *r =
+ find_ref(hdl, master->cluster[i]->id);
+
+- if (r->req && r == r->req) {
++ if (r->valid_p_req) {
+ have_new_data = true;
+ break;
+ }
+diff --git a/drivers/mfd/arizona-irq.c b/drivers/mfd/arizona-irq.c
+index 077d9ab112b71..d919ae9691e23 100644
+--- a/drivers/mfd/arizona-irq.c
++++ b/drivers/mfd/arizona-irq.c
+@@ -100,7 +100,7 @@ static irqreturn_t arizona_irq_thread(int irq, void *data)
+ unsigned int val;
+ int ret;
+
+- ret = pm_runtime_get_sync(arizona->dev);
++ ret = pm_runtime_resume_and_get(arizona->dev);
+ if (ret < 0) {
+ dev_err(arizona->dev, "Failed to resume device: %d\n", ret);
+ return IRQ_NONE;
+diff --git a/drivers/mfd/da9063-i2c.c b/drivers/mfd/da9063-i2c.c
+index 3781d0bb77865..783a14af18e26 100644
+--- a/drivers/mfd/da9063-i2c.c
++++ b/drivers/mfd/da9063-i2c.c
+@@ -442,6 +442,16 @@ static int da9063_i2c_probe(struct i2c_client *i2c,
+ return ret;
+ }
+
++ /* If SMBus is not available and only I2C is possible, enter I2C mode */
++ if (i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C)) {
++ ret = regmap_clear_bits(da9063->regmap, DA9063_REG_CONFIG_J,
++ DA9063_TWOWIRE_TO);
++ if (ret < 0) {
++ dev_err(da9063->dev, "Failed to set Two-Wire Bus Mode.\n");
++ return -EIO;
++ }
++ }
++
+ return da9063_device_init(da9063, i2c->irq);
+ }
+
+diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
+index d666e24fbe0e0..a4c06ef673943 100644
+--- a/drivers/mmc/core/block.c
++++ b/drivers/mmc/core/block.c
+@@ -572,6 +572,18 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md,
+ main_md->part_curr = value & EXT_CSD_PART_CONFIG_ACC_MASK;
+ }
+
++ /*
++ * Make sure to update CACHE_CTRL in case it was changed. The cache
++ * will get turned back on if the card is re-initialized, e.g.
++ * suspend/resume or hw reset in recovery.
++ */
++ if ((MMC_EXTRACT_INDEX_FROM_ARG(cmd.arg) == EXT_CSD_CACHE_CTRL) &&
++ (cmd.opcode == MMC_SWITCH)) {
++ u8 value = MMC_EXTRACT_VALUE_FROM_ARG(cmd.arg) & 1;
++
++ card->ext_csd.cache_ctrl = value;
++ }
++
+ /*
+ * According to the SD specs, some commands require a delay after
+ * issuing the command.
+@@ -2224,6 +2236,10 @@ enum mmc_issued mmc_blk_mq_issue_rq(struct mmc_queue *mq, struct request *req)
+ case MMC_ISSUE_ASYNC:
+ switch (req_op(req)) {
+ case REQ_OP_FLUSH:
++ if (!mmc_cache_enabled(host)) {
++ blk_mq_end_request(req, BLK_STS_OK);
++ return MMC_REQ_FINISHED;
++ }
+ ret = mmc_blk_cqe_issue_flush(mq, req);
+ break;
+ case REQ_OP_READ:
+diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
+index 1136b859ddd86..e30c4e88e4043 100644
+--- a/drivers/mmc/core/core.c
++++ b/drivers/mmc/core/core.c
+@@ -1207,7 +1207,7 @@ int mmc_set_uhs_voltage(struct mmc_host *host, u32 ocr)
+
+ err = mmc_wait_for_cmd(host, &cmd, 0);
+ if (err)
+- return err;
++ goto power_cycle;
+
+ if (!mmc_host_is_spi(host) && (cmd.resp[0] & R1_ERROR))
+ return -EIO;
+@@ -2369,80 +2369,6 @@ void mmc_stop_host(struct mmc_host *host)
+ mmc_release_host(host);
+ }
+
+-#ifdef CONFIG_PM_SLEEP
+-/* Do the card removal on suspend if card is assumed removeable
+- * Do that in pm notifier while userspace isn't yet frozen, so we will be able
+- to sync the card.
+-*/
+-static int mmc_pm_notify(struct notifier_block *notify_block,
+- unsigned long mode, void *unused)
+-{
+- struct mmc_host *host = container_of(
+- notify_block, struct mmc_host, pm_notify);
+- unsigned long flags;
+- int err = 0;
+-
+- switch (mode) {
+- case PM_HIBERNATION_PREPARE:
+- case PM_SUSPEND_PREPARE:
+- case PM_RESTORE_PREPARE:
+- spin_lock_irqsave(&host->lock, flags);
+- host->rescan_disable = 1;
+- spin_unlock_irqrestore(&host->lock, flags);
+- cancel_delayed_work_sync(&host->detect);
+-
+- if (!host->bus_ops)
+- break;
+-
+- /* Validate prerequisites for suspend */
+- if (host->bus_ops->pre_suspend)
+- err = host->bus_ops->pre_suspend(host);
+- if (!err)
+- break;
+-
+- if (!mmc_card_is_removable(host)) {
+- dev_warn(mmc_dev(host),
+- "pre_suspend failed for non-removable host: "
+- "%d\n", err);
+- /* Avoid removing non-removable hosts */
+- break;
+- }
+-
+- /* Calling bus_ops->remove() with a claimed host can deadlock */
+- host->bus_ops->remove(host);
+- mmc_claim_host(host);
+- mmc_detach_bus(host);
+- mmc_power_off(host);
+- mmc_release_host(host);
+- host->pm_flags = 0;
+- break;
+-
+- case PM_POST_SUSPEND:
+- case PM_POST_HIBERNATION:
+- case PM_POST_RESTORE:
+-
+- spin_lock_irqsave(&host->lock, flags);
+- host->rescan_disable = 0;
+- spin_unlock_irqrestore(&host->lock, flags);
+- _mmc_detect_change(host, 0, false);
+-
+- }
+-
+- return 0;
+-}
+-
+-void mmc_register_pm_notifier(struct mmc_host *host)
+-{
+- host->pm_notify.notifier_call = mmc_pm_notify;
+- register_pm_notifier(&host->pm_notify);
+-}
+-
+-void mmc_unregister_pm_notifier(struct mmc_host *host)
+-{
+- unregister_pm_notifier(&host->pm_notify);
+-}
+-#endif
+-
+ static int __init mmc_init(void)
+ {
+ int ret;
+diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
+index 575ac0257af2f..db3c9c68875d8 100644
+--- a/drivers/mmc/core/core.h
++++ b/drivers/mmc/core/core.h
+@@ -29,6 +29,7 @@ struct mmc_bus_ops {
+ int (*shutdown)(struct mmc_host *);
+ int (*hw_reset)(struct mmc_host *);
+ int (*sw_reset)(struct mmc_host *);
++ bool (*cache_enabled)(struct mmc_host *);
+ };
+
+ void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops);
+@@ -93,14 +94,6 @@ int mmc_execute_tuning(struct mmc_card *card);
+ int mmc_hs200_to_hs400(struct mmc_card *card);
+ int mmc_hs400_to_hs200(struct mmc_card *card);
+
+-#ifdef CONFIG_PM_SLEEP
+-void mmc_register_pm_notifier(struct mmc_host *host);
+-void mmc_unregister_pm_notifier(struct mmc_host *host);
+-#else
+-static inline void mmc_register_pm_notifier(struct mmc_host *host) { }
+-static inline void mmc_unregister_pm_notifier(struct mmc_host *host) { }
+-#endif
+-
+ void mmc_wait_for_req_done(struct mmc_host *host, struct mmc_request *mrq);
+ bool mmc_is_req_done(struct mmc_host *host, struct mmc_request *mrq);
+
+@@ -171,4 +164,12 @@ static inline void mmc_post_req(struct mmc_host *host, struct mmc_request *mrq,
+ host->ops->post_req(host, mrq, err);
+ }
+
++static inline bool mmc_cache_enabled(struct mmc_host *host)
++{
++ if (host->bus_ops->cache_enabled)
++ return host->bus_ops->cache_enabled(host);
++
++ return false;
++}
++
+ #endif
+diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
+index 9b89a91b6b476..fe05b3645fe98 100644
+--- a/drivers/mmc/core/host.c
++++ b/drivers/mmc/core/host.c
+@@ -35,6 +35,42 @@
+
+ static DEFINE_IDA(mmc_host_ida);
+
++#ifdef CONFIG_PM_SLEEP
++static int mmc_host_class_prepare(struct device *dev)
++{
++ struct mmc_host *host = cls_dev_to_mmc_host(dev);
++
++ /*
++ * It's safe to access the bus_ops pointer, as both userspace and the
++ * workqueue for detecting cards are frozen at this point.
++ */
++ if (!host->bus_ops)
++ return 0;
++
++ /* Validate conditions for system suspend. */
++ if (host->bus_ops->pre_suspend)
++ return host->bus_ops->pre_suspend(host);
++
++ return 0;
++}
++
++static void mmc_host_class_complete(struct device *dev)
++{
++ struct mmc_host *host = cls_dev_to_mmc_host(dev);
++
++ _mmc_detect_change(host, 0, false);
++}
++
++static const struct dev_pm_ops mmc_host_class_dev_pm_ops = {
++ .prepare = mmc_host_class_prepare,
++ .complete = mmc_host_class_complete,
++};
++
++#define MMC_HOST_CLASS_DEV_PM_OPS (&mmc_host_class_dev_pm_ops)
++#else
++#define MMC_HOST_CLASS_DEV_PM_OPS NULL
++#endif
++
+ static void mmc_host_classdev_release(struct device *dev)
+ {
+ struct mmc_host *host = cls_dev_to_mmc_host(dev);
+@@ -46,6 +82,7 @@ static void mmc_host_classdev_release(struct device *dev)
+ static struct class mmc_host_class = {
+ .name = "mmc_host",
+ .dev_release = mmc_host_classdev_release,
++ .pm = MMC_HOST_CLASS_DEV_PM_OPS,
+ };
+
+ int mmc_register_host_class(void)
+@@ -538,8 +575,6 @@ int mmc_add_host(struct mmc_host *host)
+ #endif
+
+ mmc_start_host(host);
+- mmc_register_pm_notifier(host);
+-
+ return 0;
+ }
+
+@@ -555,7 +590,6 @@ EXPORT_SYMBOL(mmc_add_host);
+ */
+ void mmc_remove_host(struct mmc_host *host)
+ {
+- mmc_unregister_pm_notifier(host);
+ mmc_stop_host(host);
+
+ #ifdef CONFIG_DEBUG_FS
+diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
+index 8741271d39712..4d2b4b0da93cd 100644
+--- a/drivers/mmc/core/mmc.c
++++ b/drivers/mmc/core/mmc.c
+@@ -2029,6 +2029,12 @@ static void mmc_detect(struct mmc_host *host)
+ }
+ }
+
++static bool _mmc_cache_enabled(struct mmc_host *host)
++{
++ return host->card->ext_csd.cache_size > 0 &&
++ host->card->ext_csd.cache_ctrl & 1;
++}
++
+ static int _mmc_suspend(struct mmc_host *host, bool is_suspend)
+ {
+ int err = 0;
+@@ -2208,6 +2214,7 @@ static const struct mmc_bus_ops mmc_ops = {
+ .alive = mmc_alive,
+ .shutdown = mmc_shutdown,
+ .hw_reset = _mmc_hw_reset,
++ .cache_enabled = _mmc_cache_enabled,
+ };
+
+ /*
+diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
+index 265d95ec82ce1..c458f6b626a2f 100644
+--- a/drivers/mmc/core/mmc_ops.c
++++ b/drivers/mmc/core/mmc_ops.c
+@@ -988,9 +988,7 @@ int mmc_flush_cache(struct mmc_card *card)
+ {
+ int err = 0;
+
+- if (mmc_card_mmc(card) &&
+- (card->ext_csd.cache_size > 0) &&
+- (card->ext_csd.cache_ctrl & 1)) {
++ if (mmc_cache_enabled(card->host)) {
+ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+ EXT_CSD_FLUSH_CACHE, 1,
+ MMC_CACHE_FLUSH_TIMEOUT_MS);
+diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
+index 6fa51a6ed0585..2c48d65041013 100644
+--- a/drivers/mmc/core/sd.c
++++ b/drivers/mmc/core/sd.c
+@@ -135,6 +135,9 @@ static int mmc_decode_csd(struct mmc_card *card)
+ csd->erase_size = UNSTUFF_BITS(resp, 39, 7) + 1;
+ csd->erase_size <<= csd->write_blkbits - 9;
+ }
++
++ if (UNSTUFF_BITS(resp, 13, 1))
++ mmc_card_set_readonly(card);
+ break;
+ case 1:
+ /*
+@@ -169,6 +172,9 @@ static int mmc_decode_csd(struct mmc_card *card)
+ csd->write_blkbits = 9;
+ csd->write_partial = 0;
+ csd->erase_size = 1;
++
++ if (UNSTUFF_BITS(resp, 13, 1))
++ mmc_card_set_readonly(card);
+ break;
+ default:
+ pr_err("%s: unrecognised CSD structure version %d\n",
+diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
+index 0fda7784cab20..3eb94ac2712e7 100644
+--- a/drivers/mmc/core/sdio.c
++++ b/drivers/mmc/core/sdio.c
+@@ -985,21 +985,37 @@ out:
+ */
+ static int mmc_sdio_pre_suspend(struct mmc_host *host)
+ {
+- int i, err = 0;
++ int i;
+
+ for (i = 0; i < host->card->sdio_funcs; i++) {
+ struct sdio_func *func = host->card->sdio_func[i];
+ if (func && sdio_func_present(func) && func->dev.driver) {
+ const struct dev_pm_ops *pmops = func->dev.driver->pm;
+- if (!pmops || !pmops->suspend || !pmops->resume) {
++ if (!pmops || !pmops->suspend || !pmops->resume)
+ /* force removal of entire card in that case */
+- err = -ENOSYS;
+- break;
+- }
++ goto remove;
+ }
+ }
+
+- return err;
++ return 0;
++
++remove:
++ if (!mmc_card_is_removable(host)) {
++ dev_warn(mmc_dev(host),
++ "missing suspend/resume ops for non-removable SDIO card\n");
++ /* Don't remove a non-removable card - we can't re-detect it. */
++ return 0;
++ }
++
++ /* Remove the SDIO card and let it be re-detected later on. */
++ mmc_sdio_remove(host);
++ mmc_claim_host(host);
++ mmc_detach_bus(host);
++ mmc_power_off(host);
++ mmc_release_host(host);
++ host->pm_flags = 0;
++
++ return 0;
+ }
+
+ /*
+diff --git a/drivers/mmc/host/sdhci-brcmstb.c b/drivers/mmc/host/sdhci-brcmstb.c
+index f9780c65ebe98..f24623aac2dbe 100644
+--- a/drivers/mmc/host/sdhci-brcmstb.c
++++ b/drivers/mmc/host/sdhci-brcmstb.c
+@@ -199,7 +199,6 @@ static int sdhci_brcmstb_add_host(struct sdhci_host *host,
+ if (dma64) {
+ dev_dbg(mmc_dev(host->mmc), "Using 64 bit DMA\n");
+ cq_host->caps |= CQHCI_TASK_DESC_SZ_128;
+- cq_host->quirks |= CQHCI_QUIRK_SHORT_TXFR_DESC_SZ;
+ }
+
+ ret = cqhci_init(cq_host, host->mmc, dma64);
+diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
+index a20459744d213..94327988da914 100644
+--- a/drivers/mmc/host/sdhci-esdhc-imx.c
++++ b/drivers/mmc/host/sdhci-esdhc-imx.c
+@@ -1488,7 +1488,7 @@ sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,
+
+ mmc_of_parse_voltage(np, &host->ocr_mask);
+
+- if (esdhc_is_usdhc(imx_data)) {
++ if (esdhc_is_usdhc(imx_data) && !IS_ERR(imx_data->pinctrl)) {
+ imx_data->pins_100mhz = pinctrl_lookup_state(imx_data->pinctrl,
+ ESDHC_PINCTRL_STATE_100MHZ);
+ imx_data->pins_200mhz = pinctrl_lookup_state(imx_data->pinctrl,
+diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c
+index 9552708846ca3..bf04a08eeba13 100644
+--- a/drivers/mmc/host/sdhci-pci-core.c
++++ b/drivers/mmc/host/sdhci-pci-core.c
+@@ -516,6 +516,7 @@ struct intel_host {
+ int drv_strength;
+ bool d3_retune;
+ bool rpm_retune_ok;
++ bool needs_pwr_off;
+ u32 glk_rx_ctrl1;
+ u32 glk_tun_val;
+ u32 active_ltr;
+@@ -643,9 +644,25 @@ out:
+ static void sdhci_intel_set_power(struct sdhci_host *host, unsigned char mode,
+ unsigned short vdd)
+ {
++ struct sdhci_pci_slot *slot = sdhci_priv(host);
++ struct intel_host *intel_host = sdhci_pci_priv(slot);
+ int cntr;
+ u8 reg;
+
++ /*
++ * Bus power may control card power, but a full reset still may not
++ * reset the power, whereas a direct write to SDHCI_POWER_CONTROL can.
++ * That might be needed to initialize correctly, if the card was left
++ * powered on previously.
++ */
++ if (intel_host->needs_pwr_off) {
++ intel_host->needs_pwr_off = false;
++ if (mode != MMC_POWER_OFF) {
++ sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
++ usleep_range(10000, 12500);
++ }
++ }
++
+ sdhci_set_power(host, mode, vdd);
+
+ if (mode == MMC_POWER_OFF)
+@@ -1135,6 +1152,14 @@ static int byt_sdio_probe_slot(struct sdhci_pci_slot *slot)
+ return 0;
+ }
+
++static void byt_needs_pwr_off(struct sdhci_pci_slot *slot)
++{
++ struct intel_host *intel_host = sdhci_pci_priv(slot);
++ u8 reg = sdhci_readb(slot->host, SDHCI_POWER_CONTROL);
++
++ intel_host->needs_pwr_off = reg & SDHCI_POWER_ON;
++}
++
+ static int byt_sd_probe_slot(struct sdhci_pci_slot *slot)
+ {
+ byt_probe_slot(slot);
+@@ -1152,6 +1177,8 @@ static int byt_sd_probe_slot(struct sdhci_pci_slot *slot)
+ slot->chip->pdev->subsystem_device == PCI_SUBDEVICE_ID_NI_78E3)
+ slot->host->mmc->caps2 |= MMC_CAP2_AVOID_3_3V;
+
++ byt_needs_pwr_off(slot);
++
+ return 0;
+ }
+
+@@ -1903,6 +1930,8 @@ static const struct pci_device_id pci_ids[] = {
+ SDHCI_PCI_DEVICE(INTEL, CMLH_SD, intel_byt_sd),
+ SDHCI_PCI_DEVICE(INTEL, JSL_EMMC, intel_glk_emmc),
+ SDHCI_PCI_DEVICE(INTEL, JSL_SD, intel_byt_sd),
++ SDHCI_PCI_DEVICE(INTEL, LKF_EMMC, intel_glk_emmc),
++ SDHCI_PCI_DEVICE(INTEL, LKF_SD, intel_byt_sd),
+ SDHCI_PCI_DEVICE(O2, 8120, o2),
+ SDHCI_PCI_DEVICE(O2, 8220, o2),
+ SDHCI_PCI_DEVICE(O2, 8221, o2),
+diff --git a/drivers/mmc/host/sdhci-pci.h b/drivers/mmc/host/sdhci-pci.h
+index d0ed232af0eb8..8f90c4163bb5c 100644
+--- a/drivers/mmc/host/sdhci-pci.h
++++ b/drivers/mmc/host/sdhci-pci.h
+@@ -57,6 +57,8 @@
+ #define PCI_DEVICE_ID_INTEL_CMLH_SD 0x06f5
+ #define PCI_DEVICE_ID_INTEL_JSL_EMMC 0x4dc4
+ #define PCI_DEVICE_ID_INTEL_JSL_SD 0x4df8
++#define PCI_DEVICE_ID_INTEL_LKF_EMMC 0x98c4
++#define PCI_DEVICE_ID_INTEL_LKF_SD 0x98f8
+
+ #define PCI_DEVICE_ID_SYSKONNECT_8000 0x8000
+ #define PCI_DEVICE_ID_VIA_95D0 0x95d0
+diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
+index 41d193fa77bbf..8ea9132ebca4e 100644
+--- a/drivers/mmc/host/sdhci-tegra.c
++++ b/drivers/mmc/host/sdhci-tegra.c
+@@ -119,6 +119,10 @@
+ /* SDMMC CQE Base Address for Tegra Host Ver 4.1 and Higher */
+ #define SDHCI_TEGRA_CQE_BASE_ADDR 0xF000
+
++#define SDHCI_TEGRA_CQE_TRNS_MODE (SDHCI_TRNS_MULTI | \
++ SDHCI_TRNS_BLK_CNT_EN | \
++ SDHCI_TRNS_DMA)
++
+ struct sdhci_tegra_soc_data {
+ const struct sdhci_pltfm_data *pdata;
+ u64 dma_mask;
+@@ -1156,6 +1160,7 @@ static void tegra_sdhci_voltage_switch(struct sdhci_host *host)
+ static void tegra_cqhci_writel(struct cqhci_host *cq_host, u32 val, int reg)
+ {
+ struct mmc_host *mmc = cq_host->mmc;
++ struct sdhci_host *host = mmc_priv(mmc);
+ u8 ctrl;
+ ktime_t timeout;
+ bool timed_out;
+@@ -1170,6 +1175,7 @@ static void tegra_cqhci_writel(struct cqhci_host *cq_host, u32 val, int reg)
+ */
+ if (reg == CQHCI_CTL && !(val & CQHCI_HALT) &&
+ cqhci_readl(cq_host, CQHCI_CTL) & CQHCI_HALT) {
++ sdhci_writew(host, SDHCI_TEGRA_CQE_TRNS_MODE, SDHCI_TRANSFER_MODE);
+ sdhci_cqe_enable(mmc);
+ writel(val, cq_host->mmio + reg);
+ timeout = ktime_add_us(ktime_get(), 50);
+@@ -1205,6 +1211,7 @@ static void sdhci_tegra_update_dcmd_desc(struct mmc_host *mmc,
+ static void sdhci_tegra_cqe_enable(struct mmc_host *mmc)
+ {
+ struct cqhci_host *cq_host = mmc->cqe_private;
++ struct sdhci_host *host = mmc_priv(mmc);
+ u32 val;
+
+ /*
+@@ -1218,6 +1225,7 @@ static void sdhci_tegra_cqe_enable(struct mmc_host *mmc)
+ if (val & CQHCI_ENABLE)
+ cqhci_writel(cq_host, (val & ~CQHCI_ENABLE),
+ CQHCI_CFG);
++ sdhci_writew(host, SDHCI_TEGRA_CQE_TRNS_MODE, SDHCI_TRANSFER_MODE);
+ sdhci_cqe_enable(mmc);
+ if (val & CQHCI_ENABLE)
+ cqhci_writel(cq_host, val, CQHCI_CFG);
+@@ -1281,12 +1289,36 @@ static void tegra_sdhci_set_timeout(struct sdhci_host *host,
+ __sdhci_set_timeout(host, cmd);
+ }
+
++static void sdhci_tegra_cqe_pre_enable(struct mmc_host *mmc)
++{
++ struct cqhci_host *cq_host = mmc->cqe_private;
++ u32 reg;
++
++ reg = cqhci_readl(cq_host, CQHCI_CFG);
++ reg |= CQHCI_ENABLE;
++ cqhci_writel(cq_host, reg, CQHCI_CFG);
++}
++
++static void sdhci_tegra_cqe_post_disable(struct mmc_host *mmc)
++{
++ struct cqhci_host *cq_host = mmc->cqe_private;
++ struct sdhci_host *host = mmc_priv(mmc);
++ u32 reg;
++
++ reg = cqhci_readl(cq_host, CQHCI_CFG);
++ reg &= ~CQHCI_ENABLE;
++ cqhci_writel(cq_host, reg, CQHCI_CFG);
++ sdhci_writew(host, 0x0, SDHCI_TRANSFER_MODE);
++}
++
+ static const struct cqhci_host_ops sdhci_tegra_cqhci_ops = {
+ .write_l = tegra_cqhci_writel,
+ .enable = sdhci_tegra_cqe_enable,
+ .disable = sdhci_cqe_disable,
+ .dumpregs = sdhci_tegra_dumpregs,
+ .update_dcmd_desc = sdhci_tegra_update_dcmd_desc,
++ .pre_enable = sdhci_tegra_cqe_pre_enable,
++ .post_disable = sdhci_tegra_cqe_post_disable,
+ };
+
+ static int tegra_sdhci_set_dma_mask(struct sdhci_host *host)
+diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
+index 2d73407ee52ec..a9e20818ff3a3 100644
+--- a/drivers/mmc/host/sdhci.c
++++ b/drivers/mmc/host/sdhci.c
+@@ -2996,6 +2996,37 @@ static bool sdhci_request_done(struct sdhci_host *host)
+ return true;
+ }
+
++ /*
++ * The controller needs a reset of internal state machines
++ * upon error conditions.
++ */
++ if (sdhci_needs_reset(host, mrq)) {
++ /*
++ * Do not finish until command and data lines are available for
++ * reset. Note there can only be one other mrq, so it cannot
++ * also be in mrqs_done, otherwise host->cmd and host->data_cmd
++ * would both be null.
++ */
++ if (host->cmd || host->data_cmd) {
++ spin_unlock_irqrestore(&host->lock, flags);
++ return true;
++ }
++
++ /* Some controllers need this kick or reset won't work here */
++ if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET)
++ /* This is to force an update */
++ host->ops->set_clock(host, host->clock);
++
++ /*
++ * Spec says we should do both at the same time, but Ricoh
++ * controllers do not like that.
++ */
++ sdhci_do_reset(host, SDHCI_RESET_CMD);
++ sdhci_do_reset(host, SDHCI_RESET_DATA);
++
++ host->pending_reset = false;
++ }
++
+ /*
+ * Always unmap the data buffers if they were mapped by
+ * sdhci_prepare_data() whenever we finish with a request.
+@@ -3059,35 +3090,6 @@ static bool sdhci_request_done(struct sdhci_host *host)
+ }
+ }
+
+- /*
+- * The controller needs a reset of internal state machines
+- * upon error conditions.
+- */
+- if (sdhci_needs_reset(host, mrq)) {
+- /*
+- * Do not finish until command and data lines are available for
+- * reset. Note there can only be one other mrq, so it cannot
+- * also be in mrqs_done, otherwise host->cmd and host->data_cmd
+- * would both be null.
+- */
+- if (host->cmd || host->data_cmd) {
+- spin_unlock_irqrestore(&host->lock, flags);
+- return true;
+- }
+-
+- /* Some controllers need this kick or reset won't work here */
+- if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET)
+- /* This is to force an update */
+- host->ops->set_clock(host, host->clock);
+-
+- /* Spec says we should do both at the same time, but Ricoh
+- controllers do not like that. */
+- sdhci_do_reset(host, SDHCI_RESET_CMD);
+- sdhci_do_reset(host, SDHCI_RESET_DATA);
+-
+- host->pending_reset = false;
+- }
+-
+ host->mrqs_done[i] = NULL;
+
+ spin_unlock_irqrestore(&host->lock, flags);
+diff --git a/drivers/mmc/host/uniphier-sd.c b/drivers/mmc/host/uniphier-sd.c
+index 2413b6750cec3..ccbf9885a52be 100644
+--- a/drivers/mmc/host/uniphier-sd.c
++++ b/drivers/mmc/host/uniphier-sd.c
+@@ -635,7 +635,7 @@ static int uniphier_sd_probe(struct platform_device *pdev)
+
+ ret = tmio_mmc_host_probe(host);
+ if (ret)
+- goto free_host;
++ goto disable_clk;
+
+ ret = devm_request_irq(dev, irq, tmio_mmc_irq, IRQF_SHARED,
+ dev_name(dev), host);
+@@ -646,6 +646,8 @@ static int uniphier_sd_probe(struct platform_device *pdev)
+
+ remove_host:
+ tmio_mmc_host_remove(host);
++disable_clk:
++ uniphier_sd_clk_disable(host);
+ free_host:
+ tmio_mmc_host_free(host);
+
+@@ -658,6 +660,7 @@ static int uniphier_sd_remove(struct platform_device *pdev)
+
+ tmio_mmc_host_remove(host);
+ uniphier_sd_clk_disable(host);
++ tmio_mmc_host_free(host);
+
+ return 0;
+ }
+diff --git a/drivers/mtd/maps/physmap-bt1-rom.c b/drivers/mtd/maps/physmap-bt1-rom.c
+index a35450002284c..58782cfaf71cf 100644
+--- a/drivers/mtd/maps/physmap-bt1-rom.c
++++ b/drivers/mtd/maps/physmap-bt1-rom.c
+@@ -79,7 +79,7 @@ static void __xipram bt1_rom_map_copy_from(struct map_info *map,
+ if (shift) {
+ chunk = min_t(ssize_t, 4 - shift, len);
+ data = readl_relaxed(src - shift);
+- memcpy(to, &data + shift, chunk);
++ memcpy(to, (char *)&data + shift, chunk);
+ src += chunk;
+ to += chunk;
+ len -= chunk;
+diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c
+index e6ceec8f50dce..8aab1017b4600 100644
+--- a/drivers/mtd/nand/raw/atmel/nand-controller.c
++++ b/drivers/mtd/nand/raw/atmel/nand-controller.c
+@@ -883,10 +883,12 @@ static int atmel_nand_pmecc_correct_data(struct nand_chip *chip, void *buf,
+ NULL, 0,
+ chip->ecc.strength);
+
+- if (ret >= 0)
++ if (ret >= 0) {
++ mtd->ecc_stats.corrected += ret;
+ max_bitflips = max(ret, max_bitflips);
+- else
++ } else {
+ mtd->ecc_stats.failed++;
++ }
+
+ databuf += chip->ecc.size;
+ eccbuf += chip->ecc.bytes;
+diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
+index 61d932c1b7180..17f63f95f4a28 100644
+--- a/drivers/mtd/nand/spi/core.c
++++ b/drivers/mtd/nand/spi/core.c
+@@ -1263,12 +1263,14 @@ static const struct spi_device_id spinand_ids[] = {
+ { .name = "spi-nand" },
+ { /* sentinel */ },
+ };
++MODULE_DEVICE_TABLE(spi, spinand_ids);
+
+ #ifdef CONFIG_OF
+ static const struct of_device_id spinand_of_ids[] = {
+ { .compatible = "spi-nand" },
+ { /* sentinel */ },
+ };
++MODULE_DEVICE_TABLE(of, spinand_of_ids);
+ #endif
+
+ static struct spi_mem_driver spinand_drv = {
+diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
+index 0522304f52fad..72bc1342c3ff8 100644
+--- a/drivers/mtd/spi-nor/core.c
++++ b/drivers/mtd/spi-nor/core.c
+@@ -3301,6 +3301,37 @@ static void spi_nor_resume(struct mtd_info *mtd)
+ dev_err(dev, "resume() failed\n");
+ }
+
++static int spi_nor_get_device(struct mtd_info *mtd)
++{
++ struct mtd_info *master = mtd_get_master(mtd);
++ struct spi_nor *nor = mtd_to_spi_nor(master);
++ struct device *dev;
++
++ if (nor->spimem)
++ dev = nor->spimem->spi->controller->dev.parent;
++ else
++ dev = nor->dev;
++
++ if (!try_module_get(dev->driver->owner))
++ return -ENODEV;
++
++ return 0;
++}
++
++static void spi_nor_put_device(struct mtd_info *mtd)
++{
++ struct mtd_info *master = mtd_get_master(mtd);
++ struct spi_nor *nor = mtd_to_spi_nor(master);
++ struct device *dev;
++
++ if (nor->spimem)
++ dev = nor->spimem->spi->controller->dev.parent;
++ else
++ dev = nor->dev;
++
++ module_put(dev->driver->owner);
++}
++
+ void spi_nor_restore(struct spi_nor *nor)
+ {
+ /* restore the addressing mode */
+@@ -3495,6 +3526,8 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
+ mtd->_read = spi_nor_read;
+ mtd->_suspend = spi_nor_suspend;
+ mtd->_resume = spi_nor_resume;
++ mtd->_get_device = spi_nor_get_device;
++ mtd->_put_device = spi_nor_put_device;
+
+ if (nor->params->locking_ops) {
+ mtd->_lock = spi_nor_lock;
+diff --git a/drivers/mtd/spi-nor/macronix.c b/drivers/mtd/spi-nor/macronix.c
+index 9203abaac2297..662b212787d4d 100644
+--- a/drivers/mtd/spi-nor/macronix.c
++++ b/drivers/mtd/spi-nor/macronix.c
+@@ -73,9 +73,6 @@ static const struct flash_info macronix_parts[] = {
+ SECT_4K | SPI_NOR_DUAL_READ |
+ SPI_NOR_QUAD_READ) },
+ { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
+- { "mx25l51245g", INFO(0xc2201a, 0, 64 * 1024, 1024,
+- SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
+- SPI_NOR_4B_OPCODES) },
+ { "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024,
+ SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
+ SPI_NOR_4B_OPCODES) },
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c
+index 7846a21555ef8..1f6bc0c7e91dd 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c
+@@ -535,6 +535,16 @@ mlxsw_sp_mr_route_evif_resolve(struct mlxsw_sp_mr_table *mr_table,
+ u16 erif_index = 0;
+ int err;
+
++ /* Add the eRIF */
++ if (mlxsw_sp_mr_vif_valid(rve->mr_vif)) {
++ erif_index = mlxsw_sp_rif_index(rve->mr_vif->rif);
++ err = mr->mr_ops->route_erif_add(mlxsw_sp,
++ rve->mr_route->route_priv,
++ erif_index);
++ if (err)
++ return err;
++ }
++
+ /* Update the route action, as the new eVIF can be a tunnel or a pimreg
+ * device which will require updating the action.
+ */
+@@ -544,17 +554,7 @@ mlxsw_sp_mr_route_evif_resolve(struct mlxsw_sp_mr_table *mr_table,
+ rve->mr_route->route_priv,
+ route_action);
+ if (err)
+- return err;
+- }
+-
+- /* Add the eRIF */
+- if (mlxsw_sp_mr_vif_valid(rve->mr_vif)) {
+- erif_index = mlxsw_sp_rif_index(rve->mr_vif->rif);
+- err = mr->mr_ops->route_erif_add(mlxsw_sp,
+- rve->mr_route->route_priv,
+- erif_index);
+- if (err)
+- goto err_route_erif_add;
++ goto err_route_action_update;
+ }
+
+ /* Update the minimum MTU */
+@@ -572,14 +572,14 @@ mlxsw_sp_mr_route_evif_resolve(struct mlxsw_sp_mr_table *mr_table,
+ return 0;
+
+ err_route_min_mtu_update:
+- if (mlxsw_sp_mr_vif_valid(rve->mr_vif))
+- mr->mr_ops->route_erif_del(mlxsw_sp, rve->mr_route->route_priv,
+- erif_index);
+-err_route_erif_add:
+ if (route_action != rve->mr_route->route_action)
+ mr->mr_ops->route_action_update(mlxsw_sp,
+ rve->mr_route->route_priv,
+ rve->mr_route->route_action);
++err_route_action_update:
++ if (mlxsw_sp_mr_vif_valid(rve->mr_vif))
++ mr->mr_ops->route_erif_del(mlxsw_sp, rve->mr_route->route_priv,
++ erif_index);
+ return err;
+ }
+
+diff --git a/drivers/net/ethernet/sfc/efx_channels.c b/drivers/net/ethernet/sfc/efx_channels.c
+index 1bfeee283ea90..a3ca406a35611 100644
+--- a/drivers/net/ethernet/sfc/efx_channels.c
++++ b/drivers/net/ethernet/sfc/efx_channels.c
+@@ -914,6 +914,8 @@ int efx_set_channels(struct efx_nic *efx)
+ }
+ }
+ }
++ if (xdp_queue_number)
++ efx->xdp_tx_queue_count = xdp_queue_number;
+
+ rc = netif_set_real_num_tx_queues(efx->net_dev, efx->n_tx_channels);
+ if (rc)
+diff --git a/drivers/net/ethernet/sfc/farch.c b/drivers/net/ethernet/sfc/farch.c
+index d75cf5ff5686a..49df02ecee912 100644
+--- a/drivers/net/ethernet/sfc/farch.c
++++ b/drivers/net/ethernet/sfc/farch.c
+@@ -835,14 +835,14 @@ efx_farch_handle_tx_event(struct efx_channel *channel, efx_qword_t *event)
+ /* Transmit completion */
+ tx_ev_desc_ptr = EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_DESC_PTR);
+ tx_ev_q_label = EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_Q_LABEL);
+- tx_queue = efx_channel_get_tx_queue(
+- channel, tx_ev_q_label % EFX_MAX_TXQ_PER_CHANNEL);
++ tx_queue = channel->tx_queue +
++ (tx_ev_q_label % EFX_MAX_TXQ_PER_CHANNEL);
+ efx_xmit_done(tx_queue, tx_ev_desc_ptr);
+ } else if (EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_WQ_FF_FULL)) {
+ /* Rewrite the FIFO write pointer */
+ tx_ev_q_label = EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_Q_LABEL);
+- tx_queue = efx_channel_get_tx_queue(
+- channel, tx_ev_q_label % EFX_MAX_TXQ_PER_CHANNEL);
++ tx_queue = channel->tx_queue +
++ (tx_ev_q_label % EFX_MAX_TXQ_PER_CHANNEL);
+
+ netif_tx_lock(efx->net_dev);
+ efx_farch_notify_tx_desc(tx_queue);
+@@ -1081,16 +1081,16 @@ static void
+ efx_farch_handle_tx_flush_done(struct efx_nic *efx, efx_qword_t *event)
+ {
+ struct efx_tx_queue *tx_queue;
++ struct efx_channel *channel;
+ int qid;
+
+ qid = EFX_QWORD_FIELD(*event, FSF_AZ_DRIVER_EV_SUBDATA);
+ if (qid < EFX_MAX_TXQ_PER_CHANNEL * (efx->n_tx_channels + efx->n_extra_tx_channels)) {
+- tx_queue = efx_get_tx_queue(efx, qid / EFX_MAX_TXQ_PER_CHANNEL,
+- qid % EFX_MAX_TXQ_PER_CHANNEL);
+- if (atomic_cmpxchg(&tx_queue->flush_outstanding, 1, 0)) {
++ channel = efx_get_tx_channel(efx, qid / EFX_MAX_TXQ_PER_CHANNEL);
++ tx_queue = channel->tx_queue + (qid % EFX_MAX_TXQ_PER_CHANNEL);
++ if (atomic_cmpxchg(&tx_queue->flush_outstanding, 1, 0))
+ efx_farch_magic_event(tx_queue->channel,
+ EFX_CHANNEL_MAGIC_TX_DRAIN(tx_queue));
+- }
+ }
+ }
+
+diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio.c b/drivers/net/wireless/rsi/rsi_91x_sdio.c
+index fe0287b22a254..e0c502bc42707 100644
+--- a/drivers/net/wireless/rsi/rsi_91x_sdio.c
++++ b/drivers/net/wireless/rsi/rsi_91x_sdio.c
+@@ -1513,7 +1513,7 @@ static int rsi_restore(struct device *dev)
+ }
+ static const struct dev_pm_ops rsi_pm_ops = {
+ .suspend = rsi_suspend,
+- .resume = rsi_resume,
++ .resume_noirq = rsi_resume,
+ .freeze = rsi_freeze,
+ .thaw = rsi_thaw,
+ .restore = rsi_restore,
+diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c
+index fe6b8aa90b534..81224447605b9 100644
+--- a/drivers/nvme/target/admin-cmd.c
++++ b/drivers/nvme/target/admin-cmd.c
+@@ -919,15 +919,21 @@ void nvmet_execute_async_event(struct nvmet_req *req)
+ void nvmet_execute_keep_alive(struct nvmet_req *req)
+ {
+ struct nvmet_ctrl *ctrl = req->sq->ctrl;
++ u16 status = 0;
+
+ if (!nvmet_check_transfer_len(req, 0))
+ return;
+
++ if (!ctrl->kato) {
++ status = NVME_SC_KA_TIMEOUT_INVALID;
++ goto out;
++ }
++
+ pr_debug("ctrl %d update keep-alive timer for %d secs\n",
+ ctrl->cntlid, ctrl->kato);
+-
+ mod_delayed_work(system_wq, &ctrl->ka_work, ctrl->kato * HZ);
+- nvmet_req_complete(req, 0);
++out:
++ nvmet_req_complete(req, status);
+ }
+
+ u16 nvmet_parse_admin_cmd(struct nvmet_req *req)
+diff --git a/drivers/nvme/target/discovery.c b/drivers/nvme/target/discovery.c
+index 682854e0e079d..4845d12e374ac 100644
+--- a/drivers/nvme/target/discovery.c
++++ b/drivers/nvme/target/discovery.c
+@@ -178,12 +178,14 @@ static void nvmet_execute_disc_get_log_page(struct nvmet_req *req)
+ if (req->cmd->get_log_page.lid != NVME_LOG_DISC) {
+ req->error_loc =
+ offsetof(struct nvme_get_log_page_command, lid);
+- status = NVME_SC_INVALID_OPCODE | NVME_SC_DNR;
++ status = NVME_SC_INVALID_FIELD | NVME_SC_DNR;
+ goto out;
+ }
+
+ /* Spec requires dword aligned offsets */
+ if (offset & 0x3) {
++ req->error_loc =
++ offsetof(struct nvme_get_log_page_command, lpo);
+ status = NVME_SC_INVALID_FIELD | NVME_SC_DNR;
+ goto out;
+ }
+@@ -250,7 +252,7 @@ static void nvmet_execute_disc_identify(struct nvmet_req *req)
+
+ if (req->cmd->identify.cns != NVME_ID_CNS_CTRL) {
+ req->error_loc = offsetof(struct nvme_identify, cns);
+- status = NVME_SC_INVALID_OPCODE | NVME_SC_DNR;
++ status = NVME_SC_INVALID_FIELD | NVME_SC_DNR;
+ goto out;
+ }
+
+diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
+index 1c25d83371510..8d028a88b375b 100644
+--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
++++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
+@@ -705,6 +705,8 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
+ }
+ }
+
++ dw_pcie_iatu_detect(pci);
++
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space");
+ if (!res)
+ return -EINVAL;
+diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
+index 7e55b2b661821..24192b40e3a2a 100644
+--- a/drivers/pci/controller/dwc/pcie-designware-host.c
++++ b/drivers/pci/controller/dwc/pcie-designware-host.c
+@@ -398,6 +398,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
+ if (ret)
+ goto err_free_msi;
+ }
++ dw_pcie_iatu_detect(pci);
+
+ dw_pcie_setup_rc(pp);
+ dw_pcie_msi_init(pp);
+diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
+index 004cb860e2667..a945f0c0e73dc 100644
+--- a/drivers/pci/controller/dwc/pcie-designware.c
++++ b/drivers/pci/controller/dwc/pcie-designware.c
+@@ -660,11 +660,9 @@ static void dw_pcie_iatu_detect_regions(struct dw_pcie *pci)
+ pci->num_ob_windows = ob;
+ }
+
+-void dw_pcie_setup(struct dw_pcie *pci)
++void dw_pcie_iatu_detect(struct dw_pcie *pci)
+ {
+- u32 val;
+ struct device *dev = pci->dev;
+- struct device_node *np = dev->of_node;
+ struct platform_device *pdev = to_platform_device(dev);
+
+ if (pci->version >= 0x480A || (!pci->version &&
+@@ -693,6 +691,13 @@ void dw_pcie_setup(struct dw_pcie *pci)
+
+ dev_info(pci->dev, "Detected iATU regions: %u outbound, %u inbound",
+ pci->num_ob_windows, pci->num_ib_windows);
++}
++
++void dw_pcie_setup(struct dw_pcie *pci)
++{
++ u32 val;
++ struct device *dev = pci->dev;
++ struct device_node *np = dev->of_node;
+
+ if (pci->link_gen > 0)
+ dw_pcie_link_set_max_speed(pci, pci->link_gen);
+diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
+index 7247c8b01f048..7d6e9b7576be5 100644
+--- a/drivers/pci/controller/dwc/pcie-designware.h
++++ b/drivers/pci/controller/dwc/pcie-designware.h
+@@ -306,6 +306,7 @@ int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
+ void dw_pcie_disable_atu(struct dw_pcie *pci, int index,
+ enum dw_pcie_region_type type);
+ void dw_pcie_setup(struct dw_pcie *pci);
++void dw_pcie_iatu_detect(struct dw_pcie *pci);
+
+ static inline void dw_pcie_writel_dbi(struct dw_pcie *pci, u32 reg, u32 val)
+ {
+diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
+index 16a17215f633d..e4d4e399004b4 100644
+--- a/drivers/pci/pci.c
++++ b/drivers/pci/pci.c
+@@ -1870,20 +1870,10 @@ static int pci_enable_device_flags(struct pci_dev *dev, unsigned long flags)
+ int err;
+ int i, bars = 0;
+
+- /*
+- * Power state could be unknown at this point, either due to a fresh
+- * boot or a device removal call. So get the current power state
+- * so that things like MSI message writing will behave as expected
+- * (e.g. if the device really is in D0 at enable time).
+- */
+- if (dev->pm_cap) {
+- u16 pmcsr;
+- pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
+- dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK);
+- }
+-
+- if (atomic_inc_return(&dev->enable_cnt) > 1)
++ if (atomic_inc_return(&dev->enable_cnt) > 1) {
++ pci_update_current_state(dev, dev->current_state);
+ return 0; /* already enabled */
++ }
+
+ bridge = pci_upstream_bridge(dev);
+ if (bridge)
+diff --git a/drivers/perf/arm_pmu_platform.c b/drivers/perf/arm_pmu_platform.c
+index 933bd8410fc2a..ef9676418c9f4 100644
+--- a/drivers/perf/arm_pmu_platform.c
++++ b/drivers/perf/arm_pmu_platform.c
+@@ -6,6 +6,7 @@
+ * Copyright (C) 2010 ARM Ltd., Will Deacon <will.deacon@arm.com>
+ */
+ #define pr_fmt(fmt) "hw perfevents: " fmt
++#define dev_fmt pr_fmt
+
+ #include <linux/bug.h>
+ #include <linux/cpumask.h>
+@@ -100,10 +101,8 @@ static int pmu_parse_irqs(struct arm_pmu *pmu)
+ struct pmu_hw_events __percpu *hw_events = pmu->hw_events;
+
+ num_irqs = platform_irq_count(pdev);
+- if (num_irqs < 0) {
+- pr_err("unable to count PMU IRQs\n");
+- return num_irqs;
+- }
++ if (num_irqs < 0)
++ return dev_err_probe(&pdev->dev, num_irqs, "unable to count PMU IRQs\n");
+
+ /*
+ * In this case we have no idea which CPUs are covered by the PMU.
+@@ -236,7 +235,7 @@ int arm_pmu_device_probe(struct platform_device *pdev,
+
+ ret = armpmu_register(pmu);
+ if (ret)
+- goto out_free;
++ goto out_free_irqs;
+
+ return 0;
+
+diff --git a/drivers/phy/ti/phy-twl4030-usb.c b/drivers/phy/ti/phy-twl4030-usb.c
+index 9887f908f5401..812e5409d3595 100644
+--- a/drivers/phy/ti/phy-twl4030-usb.c
++++ b/drivers/phy/ti/phy-twl4030-usb.c
+@@ -779,7 +779,7 @@ static int twl4030_usb_remove(struct platform_device *pdev)
+
+ usb_remove_phy(&twl->phy);
+ pm_runtime_get_sync(twl->dev);
+- cancel_delayed_work(&twl->id_workaround_work);
++ cancel_delayed_work_sync(&twl->id_workaround_work);
+ device_remove_file(twl->dev, &dev_attr_vbus);
+
+ /* set transceiver mode to power on defaults */
+diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c
+index f2746125b0777..3de0f767b7d17 100644
+--- a/drivers/pinctrl/pinctrl-ingenic.c
++++ b/drivers/pinctrl/pinctrl-ingenic.c
+@@ -667,7 +667,9 @@ static int jz4770_pwm_pwm7_pins[] = { 0x6b, };
+ static int jz4770_mac_rmii_pins[] = {
+ 0xa9, 0xab, 0xaa, 0xac, 0xa5, 0xa4, 0xad, 0xae, 0xa6, 0xa8,
+ };
+-static int jz4770_mac_mii_pins[] = { 0xa7, 0xaf, };
++static int jz4770_mac_mii_pins[] = {
++ 0x7b, 0x7a, 0x7d, 0x7c, 0xa7, 0x24, 0xaf,
++};
+
+ static const struct group_desc jz4770_groups[] = {
+ INGENIC_PIN_GROUP("uart0-data", jz4770_uart0_data, 0),
+@@ -2107,26 +2109,48 @@ static int ingenic_pinconf_get(struct pinctrl_dev *pctldev,
+ enum pin_config_param param = pinconf_to_config_param(*config);
+ unsigned int idx = pin % PINS_PER_GPIO_CHIP;
+ unsigned int offt = pin / PINS_PER_GPIO_CHIP;
+- bool pull;
++ unsigned int bias;
++ bool pull, pullup, pulldown;
+
+- if (jzpc->info->version >= ID_JZ4770)
+- pull = !ingenic_get_pin_config(jzpc, pin, JZ4770_GPIO_PEN);
+- else
+- pull = !ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_PULL_DIS);
++ if (jzpc->info->version >= ID_X1830) {
++ unsigned int half = PINS_PER_GPIO_CHIP / 2;
++ unsigned int idxh = (pin % half) * 2;
++
++ if (idx < half)
++ regmap_read(jzpc->map, offt * jzpc->info->reg_offset +
++ X1830_GPIO_PEL, &bias);
++ else
++ regmap_read(jzpc->map, offt * jzpc->info->reg_offset +
++ X1830_GPIO_PEH, &bias);
++
++ bias = (bias >> idxh) & (GPIO_PULL_UP | GPIO_PULL_DOWN);
++
++ pullup = (bias == GPIO_PULL_UP) && (jzpc->info->pull_ups[offt] & BIT(idx));
++ pulldown = (bias == GPIO_PULL_DOWN) && (jzpc->info->pull_downs[offt] & BIT(idx));
++
++ } else {
++ if (jzpc->info->version >= ID_JZ4770)
++ pull = !ingenic_get_pin_config(jzpc, pin, JZ4770_GPIO_PEN);
++ else
++ pull = !ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_PULL_DIS);
++
++ pullup = pull && (jzpc->info->pull_ups[offt] & BIT(idx));
++ pulldown = pull && (jzpc->info->pull_downs[offt] & BIT(idx));
++ }
+
+ switch (param) {
+ case PIN_CONFIG_BIAS_DISABLE:
+- if (pull)
++ if (pullup || pulldown)
+ return -EINVAL;
+ break;
+
+ case PIN_CONFIG_BIAS_PULL_UP:
+- if (!pull || !(jzpc->info->pull_ups[offt] & BIT(idx)))
++ if (!pullup)
+ return -EINVAL;
+ break;
+
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+- if (!pull || !(jzpc->info->pull_downs[offt] & BIT(idx)))
++ if (!pulldown)
+ return -EINVAL;
+ break;
+
+@@ -2144,7 +2168,7 @@ static void ingenic_set_bias(struct ingenic_pinctrl *jzpc,
+ if (jzpc->info->version >= ID_X1830) {
+ unsigned int idx = pin % PINS_PER_GPIO_CHIP;
+ unsigned int half = PINS_PER_GPIO_CHIP / 2;
+- unsigned int idxh = pin % half * 2;
++ unsigned int idxh = (pin % half) * 2;
+ unsigned int offt = pin / PINS_PER_GPIO_CHIP;
+
+ if (idx < half) {
+diff --git a/drivers/platform/x86/intel_pmc_core.c b/drivers/platform/x86/intel_pmc_core.c
+index b5888aeb4bcff..260d49dca1ad1 100644
+--- a/drivers/platform/x86/intel_pmc_core.c
++++ b/drivers/platform/x86/intel_pmc_core.c
+@@ -1186,9 +1186,15 @@ static const struct pci_device_id pmc_pci_ids[] = {
+ * the platform BIOS enforces 24Mhz crystal to shutdown
+ * before PMC can assert SLP_S0#.
+ */
++static bool xtal_ignore;
+ static int quirk_xtal_ignore(const struct dmi_system_id *id)
+ {
+- struct pmc_dev *pmcdev = &pmc;
++ xtal_ignore = true;
++ return 0;
++}
++
++static void pmc_core_xtal_ignore(struct pmc_dev *pmcdev)
++{
+ u32 value;
+
+ value = pmc_core_reg_read(pmcdev, pmcdev->map->pm_vric1_offset);
+@@ -1197,7 +1203,6 @@ static int quirk_xtal_ignore(const struct dmi_system_id *id)
+ /* Low Voltage Mode Enable */
+ value &= ~SPT_PMC_VRIC1_SLPS0LVEN;
+ pmc_core_reg_write(pmcdev, pmcdev->map->pm_vric1_offset, value);
+- return 0;
+ }
+
+ static const struct dmi_system_id pmc_core_dmi_table[] = {
+@@ -1212,6 +1217,14 @@ static const struct dmi_system_id pmc_core_dmi_table[] = {
+ {}
+ };
+
++static void pmc_core_do_dmi_quirks(struct pmc_dev *pmcdev)
++{
++ dmi_check_system(pmc_core_dmi_table);
++
++ if (xtal_ignore)
++ pmc_core_xtal_ignore(pmcdev);
++}
++
+ static int pmc_core_probe(struct platform_device *pdev)
+ {
+ static bool device_initialized;
+@@ -1253,7 +1266,7 @@ static int pmc_core_probe(struct platform_device *pdev)
+ mutex_init(&pmcdev->lock);
+ platform_set_drvdata(pdev, pmcdev);
+ pmcdev->pmc_xram_read_bit = pmc_core_check_read_lock_bit();
+- dmi_check_system(pmc_core_dmi_table);
++ pmc_core_do_dmi_quirks(pmcdev);
+
+ /*
+ * On TGL, due to a hardware limitation, the GBE LTR blocks PC10 when
+diff --git a/drivers/platform/x86/intel_speed_select_if/isst_if_mbox_pci.c b/drivers/platform/x86/intel_speed_select_if/isst_if_mbox_pci.c
+index a2a2d923e60cb..df1fc6c719f32 100644
+--- a/drivers/platform/x86/intel_speed_select_if/isst_if_mbox_pci.c
++++ b/drivers/platform/x86/intel_speed_select_if/isst_if_mbox_pci.c
+@@ -21,12 +21,16 @@
+ #define PUNIT_MAILBOX_BUSY_BIT 31
+
+ /*
+- * The average time to complete some commands is about 40us. The current
+- * count is enough to satisfy 40us. But when the firmware is very busy, this
+- * causes timeout occasionally. So increase to deal with some worst case
+- * scenarios. Most of the command still complete in few us.
++ * The average time to complete mailbox commands is less than 40us. Most of
++ * the commands complete in few micro seconds. But the same firmware handles
++ * requests from all power management features.
++ * We can create a scenario where we flood the firmware with requests then
++ * the mailbox response can be delayed for 100s of micro seconds. So define
++ * two timeouts. One for average case and one for long.
++ * If the firmware is taking more than average, just call cond_resched().
+ */
+-#define OS_MAILBOX_RETRY_COUNT 100
++#define OS_MAILBOX_TIMEOUT_AVG_US 40
++#define OS_MAILBOX_TIMEOUT_MAX_US 1000
+
+ struct isst_if_device {
+ struct mutex mutex;
+@@ -35,11 +39,13 @@ struct isst_if_device {
+ static int isst_if_mbox_cmd(struct pci_dev *pdev,
+ struct isst_if_mbox_cmd *mbox_cmd)
+ {
+- u32 retries, data;
++ s64 tm_delta = 0;
++ ktime_t tm;
++ u32 data;
+ int ret;
+
+ /* Poll for rb bit == 0 */
+- retries = OS_MAILBOX_RETRY_COUNT;
++ tm = ktime_get();
+ do {
+ ret = pci_read_config_dword(pdev, PUNIT_MAILBOX_INTERFACE,
+ &data);
+@@ -48,11 +54,14 @@ static int isst_if_mbox_cmd(struct pci_dev *pdev,
+
+ if (data & BIT_ULL(PUNIT_MAILBOX_BUSY_BIT)) {
+ ret = -EBUSY;
++ tm_delta = ktime_us_delta(ktime_get(), tm);
++ if (tm_delta > OS_MAILBOX_TIMEOUT_AVG_US)
++ cond_resched();
+ continue;
+ }
+ ret = 0;
+ break;
+- } while (--retries);
++ } while (tm_delta < OS_MAILBOX_TIMEOUT_MAX_US);
+
+ if (ret)
+ return ret;
+@@ -74,7 +83,8 @@ static int isst_if_mbox_cmd(struct pci_dev *pdev,
+ return ret;
+
+ /* Poll for rb bit == 0 */
+- retries = OS_MAILBOX_RETRY_COUNT;
++ tm_delta = 0;
++ tm = ktime_get();
+ do {
+ ret = pci_read_config_dword(pdev, PUNIT_MAILBOX_INTERFACE,
+ &data);
+@@ -83,6 +93,9 @@ static int isst_if_mbox_cmd(struct pci_dev *pdev,
+
+ if (data & BIT_ULL(PUNIT_MAILBOX_BUSY_BIT)) {
+ ret = -EBUSY;
++ tm_delta = ktime_us_delta(ktime_get(), tm);
++ if (tm_delta > OS_MAILBOX_TIMEOUT_AVG_US)
++ cond_resched();
+ continue;
+ }
+
+@@ -96,7 +109,7 @@ static int isst_if_mbox_cmd(struct pci_dev *pdev,
+ mbox_cmd->resp_data = data;
+ ret = 0;
+ break;
+- } while (--retries);
++ } while (tm_delta < OS_MAILBOX_TIMEOUT_MAX_US);
+
+ return ret;
+ }
+diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
+index 4c4a7b1c64c57..0262109ac285e 100644
+--- a/drivers/power/supply/bq27xxx_battery.c
++++ b/drivers/power/supply/bq27xxx_battery.c
+@@ -1661,27 +1661,6 @@ static int bq27xxx_battery_read_time(struct bq27xxx_device_info *di, u8 reg)
+ return tval * 60;
+ }
+
+-/*
+- * Read an average power register.
+- * Return < 0 if something fails.
+- */
+-static int bq27xxx_battery_read_pwr_avg(struct bq27xxx_device_info *di)
+-{
+- int tval;
+-
+- tval = bq27xxx_read(di, BQ27XXX_REG_AP, false);
+- if (tval < 0) {
+- dev_err(di->dev, "error reading average power register %02x: %d\n",
+- BQ27XXX_REG_AP, tval);
+- return tval;
+- }
+-
+- if (di->opts & BQ27XXX_O_ZERO)
+- return (tval * BQ27XXX_POWER_CONSTANT) / BQ27XXX_RS;
+- else
+- return tval;
+-}
+-
+ /*
+ * Returns true if a battery over temperature condition is detected
+ */
+@@ -1769,8 +1748,6 @@ void bq27xxx_battery_update(struct bq27xxx_device_info *di)
+ }
+ if (di->regs[BQ27XXX_REG_CYCT] != INVALID_REG_ADDR)
+ cache.cycle_count = bq27xxx_battery_read_cyct(di);
+- if (di->regs[BQ27XXX_REG_AP] != INVALID_REG_ADDR)
+- cache.power_avg = bq27xxx_battery_read_pwr_avg(di);
+
+ /* We only have to read charge design full once */
+ if (di->charge_design_full <= 0)
+@@ -1833,6 +1810,32 @@ static int bq27xxx_battery_current(struct bq27xxx_device_info *di,
+ return 0;
+ }
+
++/*
++ * Get the average power in µW
++ * Return < 0 if something fails.
++ */
++static int bq27xxx_battery_pwr_avg(struct bq27xxx_device_info *di,
++ union power_supply_propval *val)
++{
++ int power;
++
++ power = bq27xxx_read(di, BQ27XXX_REG_AP, false);
++ if (power < 0) {
++ dev_err(di->dev,
++ "error reading average power register %02x: %d\n",
++ BQ27XXX_REG_AP, power);
++ return power;
++ }
++
++ if (di->opts & BQ27XXX_O_ZERO)
++ val->intval = (power * BQ27XXX_POWER_CONSTANT) / BQ27XXX_RS;
++ else
++ /* Other gauges return a signed value in units of 10mW */
++ val->intval = (int)((s16)power) * 10000;
++
++ return 0;
++}
++
+ static int bq27xxx_battery_status(struct bq27xxx_device_info *di,
+ union power_supply_propval *val)
+ {
+@@ -2020,7 +2023,7 @@ static int bq27xxx_battery_get_property(struct power_supply *psy,
+ ret = bq27xxx_simple_value(di->cache.energy, val);
+ break;
+ case POWER_SUPPLY_PROP_POWER_AVG:
+- ret = bq27xxx_simple_value(di->cache.power_avg, val);
++ ret = bq27xxx_battery_pwr_avg(di, val);
+ break;
+ case POWER_SUPPLY_PROP_HEALTH:
+ ret = bq27xxx_simple_value(di->cache.health, val);
+diff --git a/drivers/power/supply/cpcap-battery.c b/drivers/power/supply/cpcap-battery.c
+index 6d5bcdb9f45d6..a3fc0084cda00 100644
+--- a/drivers/power/supply/cpcap-battery.c
++++ b/drivers/power/supply/cpcap-battery.c
+@@ -786,7 +786,7 @@ static irqreturn_t cpcap_battery_irq_thread(int irq, void *data)
+ break;
+ }
+
+- if (!d)
++ if (list_entry_is_head(d, &ddata->irq_list, node))
+ return IRQ_NONE;
+
+ latest = cpcap_battery_latest(ddata);
+diff --git a/drivers/power/supply/cpcap-charger.c b/drivers/power/supply/cpcap-charger.c
+index 641dcad1133f7..2a8915c3e73ef 100644
+--- a/drivers/power/supply/cpcap-charger.c
++++ b/drivers/power/supply/cpcap-charger.c
+@@ -318,7 +318,7 @@ static int cpcap_charger_current_to_regval(int microamp)
+ return CPCAP_REG_CRM_ICHRG(0x0);
+ if (miliamp < 177)
+ return CPCAP_REG_CRM_ICHRG(0x1);
+- if (miliamp > 1596)
++ if (miliamp >= 1596)
+ return CPCAP_REG_CRM_ICHRG(0xe);
+
+ res = microamp / 88666;
+@@ -668,6 +668,9 @@ static void cpcap_usb_detect(struct work_struct *work)
+ return;
+ }
+
++ /* Delay for 80ms to avoid vbus bouncing when usb cable is plugged in */
++ usleep_range(80000, 120000);
++
+ /* Throttle chrgcurr2 interrupt for charger done and retry */
+ switch (ddata->status) {
+ case POWER_SUPPLY_STATUS_CHARGING:
+diff --git a/drivers/power/supply/generic-adc-battery.c b/drivers/power/supply/generic-adc-battery.c
+index 0032069fbc2bb..66039c665dd1e 100644
+--- a/drivers/power/supply/generic-adc-battery.c
++++ b/drivers/power/supply/generic-adc-battery.c
+@@ -373,7 +373,7 @@ static int gab_remove(struct platform_device *pdev)
+ }
+
+ kfree(adc_bat->psy_desc.properties);
+- cancel_delayed_work(&adc_bat->bat_work);
++ cancel_delayed_work_sync(&adc_bat->bat_work);
+ return 0;
+ }
+
+diff --git a/drivers/power/supply/lp8788-charger.c b/drivers/power/supply/lp8788-charger.c
+index e7931ffb7151d..397e5a03b7d9a 100644
+--- a/drivers/power/supply/lp8788-charger.c
++++ b/drivers/power/supply/lp8788-charger.c
+@@ -501,7 +501,7 @@ static int lp8788_set_irqs(struct platform_device *pdev,
+
+ ret = request_threaded_irq(virq, NULL,
+ lp8788_charger_irq_thread,
+- 0, name, pchg);
++ IRQF_ONESHOT, name, pchg);
+ if (ret)
+ break;
+ }
+diff --git a/drivers/power/supply/pm2301_charger.c b/drivers/power/supply/pm2301_charger.c
+index ac06ecf7fc9ca..a3bfb9612b174 100644
+--- a/drivers/power/supply/pm2301_charger.c
++++ b/drivers/power/supply/pm2301_charger.c
+@@ -1089,7 +1089,7 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client,
+ ret = request_threaded_irq(gpio_to_irq(pm2->pdata->gpio_irq_number),
+ NULL,
+ pm2xxx_charger_irq[0].isr,
+- pm2->pdata->irq_type,
++ pm2->pdata->irq_type | IRQF_ONESHOT,
+ pm2xxx_charger_irq[0].name, pm2);
+
+ if (ret != 0) {
+diff --git a/drivers/power/supply/s3c_adc_battery.c b/drivers/power/supply/s3c_adc_battery.c
+index a2addc24ee8b8..3e3a598f114d1 100644
+--- a/drivers/power/supply/s3c_adc_battery.c
++++ b/drivers/power/supply/s3c_adc_battery.c
+@@ -395,7 +395,7 @@ static int s3c_adc_bat_remove(struct platform_device *pdev)
+ if (main_bat.charge_finished)
+ free_irq(gpiod_to_irq(main_bat.charge_finished), NULL);
+
+- cancel_delayed_work(&bat_work);
++ cancel_delayed_work_sync(&bat_work);
+
+ if (pdata->exit)
+ pdata->exit();
+diff --git a/drivers/power/supply/tps65090-charger.c b/drivers/power/supply/tps65090-charger.c
+index 6b0098e5a88b5..0990b2fa6cd8d 100644
+--- a/drivers/power/supply/tps65090-charger.c
++++ b/drivers/power/supply/tps65090-charger.c
+@@ -301,7 +301,7 @@ static int tps65090_charger_probe(struct platform_device *pdev)
+
+ if (irq != -ENXIO) {
+ ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
+- tps65090_charger_isr, 0, "tps65090-charger", cdata);
++ tps65090_charger_isr, IRQF_ONESHOT, "tps65090-charger", cdata);
+ if (ret) {
+ dev_err(cdata->dev,
+ "Unable to register irq %d err %d\n", irq,
+diff --git a/drivers/power/supply/tps65217_charger.c b/drivers/power/supply/tps65217_charger.c
+index 814c2b81fdfec..ba33d1617e0b6 100644
+--- a/drivers/power/supply/tps65217_charger.c
++++ b/drivers/power/supply/tps65217_charger.c
+@@ -238,7 +238,7 @@ static int tps65217_charger_probe(struct platform_device *pdev)
+ for (i = 0; i < NUM_CHARGER_IRQS; i++) {
+ ret = devm_request_threaded_irq(&pdev->dev, irq[i], NULL,
+ tps65217_charger_irq,
+- 0, "tps65217-charger",
++ IRQF_ONESHOT, "tps65217-charger",
+ charger);
+ if (ret) {
+ dev_err(charger->dev,
+diff --git a/drivers/regulator/da9121-regulator.c b/drivers/regulator/da9121-regulator.c
+index a2ede7d7897eb..08cbf688e14d3 100644
+--- a/drivers/regulator/da9121-regulator.c
++++ b/drivers/regulator/da9121-regulator.c
+@@ -40,6 +40,7 @@ struct da9121 {
+ unsigned int passive_delay;
+ int chip_irq;
+ int variant_id;
++ int subvariant_id;
+ };
+
+ /* Define ranges for different variants, enabling translation to/from
+@@ -812,7 +813,6 @@ static struct regmap_config da9121_2ch_regmap_config = {
+ static int da9121_check_device_type(struct i2c_client *i2c, struct da9121 *chip)
+ {
+ u32 device_id;
+- u8 chip_id = chip->variant_id;
+ u32 variant_id;
+ u8 variant_mrc, variant_vrc;
+ char *type;
+@@ -839,22 +839,34 @@ static int da9121_check_device_type(struct i2c_client *i2c, struct da9121 *chip)
+
+ variant_vrc = variant_id & DA9121_MASK_OTP_VARIANT_ID_VRC;
+
+- switch (variant_vrc) {
+- case DA9121_VARIANT_VRC:
+- type = "DA9121/DA9130";
+- config_match = (chip_id == DA9121_TYPE_DA9121_DA9130);
++ switch (chip->subvariant_id) {
++ case DA9121_SUBTYPE_DA9121:
++ type = "DA9121";
++ config_match = (variant_vrc == DA9121_VARIANT_VRC);
+ break;
+- case DA9220_VARIANT_VRC:
+- type = "DA9220/DA9132";
+- config_match = (chip_id == DA9121_TYPE_DA9220_DA9132);
++ case DA9121_SUBTYPE_DA9130:
++ type = "DA9130";
++ config_match = (variant_vrc == DA9130_VARIANT_VRC);
+ break;
+- case DA9122_VARIANT_VRC:
+- type = "DA9122/DA9131";
+- config_match = (chip_id == DA9121_TYPE_DA9122_DA9131);
++ case DA9121_SUBTYPE_DA9220:
++ type = "DA9220";
++ config_match = (variant_vrc == DA9220_VARIANT_VRC);
+ break;
+- case DA9217_VARIANT_VRC:
++ case DA9121_SUBTYPE_DA9132:
++ type = "DA9132";
++ config_match = (variant_vrc == DA9132_VARIANT_VRC);
++ break;
++ case DA9121_SUBTYPE_DA9122:
++ type = "DA9122";
++ config_match = (variant_vrc == DA9122_VARIANT_VRC);
++ break;
++ case DA9121_SUBTYPE_DA9131:
++ type = "DA9131";
++ config_match = (variant_vrc == DA9131_VARIANT_VRC);
++ break;
++ case DA9121_SUBTYPE_DA9217:
+ type = "DA9217";
+- config_match = (chip_id == DA9121_TYPE_DA9217);
++ config_match = (variant_vrc == DA9217_VARIANT_VRC);
+ break;
+ default:
+ type = "Unknown";
+@@ -892,15 +904,27 @@ static int da9121_assign_chip_model(struct i2c_client *i2c,
+
+ chip->dev = &i2c->dev;
+
+- switch (chip->variant_id) {
+- case DA9121_TYPE_DA9121_DA9130:
+- fallthrough;
+- case DA9121_TYPE_DA9217:
++ /* Use configured subtype to select the regulator descriptor index and
++ * register map, common to both consumer and automotive grade variants
++ */
++ switch (chip->subvariant_id) {
++ case DA9121_SUBTYPE_DA9121:
++ case DA9121_SUBTYPE_DA9130:
++ chip->variant_id = DA9121_TYPE_DA9121_DA9130;
+ regmap = &da9121_1ch_regmap_config;
+ break;
+- case DA9121_TYPE_DA9122_DA9131:
+- fallthrough;
+- case DA9121_TYPE_DA9220_DA9132:
++ case DA9121_SUBTYPE_DA9217:
++ chip->variant_id = DA9121_TYPE_DA9217;
++ regmap = &da9121_1ch_regmap_config;
++ break;
++ case DA9121_SUBTYPE_DA9122:
++ case DA9121_SUBTYPE_DA9131:
++ chip->variant_id = DA9121_TYPE_DA9122_DA9131;
++ regmap = &da9121_2ch_regmap_config;
++ break;
++ case DA9121_SUBTYPE_DA9220:
++ case DA9121_SUBTYPE_DA9132:
++ chip->variant_id = DA9121_TYPE_DA9220_DA9132;
+ regmap = &da9121_2ch_regmap_config;
+ break;
+ }
+@@ -975,13 +999,13 @@ regmap_error:
+ }
+
+ static const struct of_device_id da9121_dt_ids[] = {
+- { .compatible = "dlg,da9121", .data = (void *) DA9121_TYPE_DA9121_DA9130 },
+- { .compatible = "dlg,da9130", .data = (void *) DA9121_TYPE_DA9121_DA9130 },
+- { .compatible = "dlg,da9217", .data = (void *) DA9121_TYPE_DA9217 },
+- { .compatible = "dlg,da9122", .data = (void *) DA9121_TYPE_DA9122_DA9131 },
+- { .compatible = "dlg,da9131", .data = (void *) DA9121_TYPE_DA9122_DA9131 },
+- { .compatible = "dlg,da9220", .data = (void *) DA9121_TYPE_DA9220_DA9132 },
+- { .compatible = "dlg,da9132", .data = (void *) DA9121_TYPE_DA9220_DA9132 },
++ { .compatible = "dlg,da9121", .data = (void *) DA9121_SUBTYPE_DA9121 },
++ { .compatible = "dlg,da9130", .data = (void *) DA9121_SUBTYPE_DA9130 },
++ { .compatible = "dlg,da9217", .data = (void *) DA9121_SUBTYPE_DA9217 },
++ { .compatible = "dlg,da9122", .data = (void *) DA9121_SUBTYPE_DA9122 },
++ { .compatible = "dlg,da9131", .data = (void *) DA9121_SUBTYPE_DA9131 },
++ { .compatible = "dlg,da9220", .data = (void *) DA9121_SUBTYPE_DA9220 },
++ { .compatible = "dlg,da9132", .data = (void *) DA9121_SUBTYPE_DA9132 },
+ { }
+ };
+ MODULE_DEVICE_TABLE(of, da9121_dt_ids);
+@@ -1011,7 +1035,7 @@ static int da9121_i2c_probe(struct i2c_client *i2c,
+ }
+
+ chip->pdata = i2c->dev.platform_data;
+- chip->variant_id = da9121_of_get_id(&i2c->dev);
++ chip->subvariant_id = da9121_of_get_id(&i2c->dev);
+
+ ret = da9121_assign_chip_model(i2c, chip);
+ if (ret < 0)
+diff --git a/drivers/regulator/da9121-regulator.h b/drivers/regulator/da9121-regulator.h
+index 3c34cb889ca87..357f416e17c1d 100644
+--- a/drivers/regulator/da9121-regulator.h
++++ b/drivers/regulator/da9121-regulator.h
+@@ -29,6 +29,16 @@ enum da9121_variant {
+ DA9121_TYPE_DA9217
+ };
+
++enum da9121_subvariant {
++ DA9121_SUBTYPE_DA9121,
++ DA9121_SUBTYPE_DA9130,
++ DA9121_SUBTYPE_DA9220,
++ DA9121_SUBTYPE_DA9132,
++ DA9121_SUBTYPE_DA9122,
++ DA9121_SUBTYPE_DA9131,
++ DA9121_SUBTYPE_DA9217
++};
++
+ /* Minimum, maximum and default polling millisecond periods are provided
+ * here as an example. It is expected that any final implementation will
+ * include a modification of these settings to match the required
+@@ -279,6 +289,9 @@ enum da9121_variant {
+ #define DA9220_VARIANT_VRC 0x0
+ #define DA9122_VARIANT_VRC 0x2
+ #define DA9217_VARIANT_VRC 0x7
++#define DA9130_VARIANT_VRC 0x0
++#define DA9131_VARIANT_VRC 0x1
++#define DA9132_VARIANT_VRC 0x2
+
+ /* DA9121_REG_OTP_CUSTOMER_ID */
+
+diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
+index 3f026021e95e4..84f659cafe766 100644
+--- a/drivers/s390/cio/device.c
++++ b/drivers/s390/cio/device.c
+@@ -1532,8 +1532,7 @@ static int io_subchannel_sch_event(struct subchannel *sch, int process)
+ switch (action) {
+ case IO_SCH_ORPH_UNREG:
+ case IO_SCH_UNREG:
+- if (!cdev)
+- css_sch_device_unregister(sch);
++ css_sch_device_unregister(sch);
+ break;
+ case IO_SCH_ORPH_ATTACH:
+ case IO_SCH_UNREG_ATTACH:
+diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
+index 34bf2f197c714..0e0044d708440 100644
+--- a/drivers/s390/cio/qdio.h
++++ b/drivers/s390/cio/qdio.h
+@@ -181,12 +181,6 @@ struct qdio_input_q {
+ struct qdio_output_q {
+ /* PCIs are enabled for the queue */
+ int pci_out_enabled;
+- /* cq: use asynchronous output buffers */
+- int use_cq;
+- /* cq: aobs used for particual SBAL */
+- struct qaob **aobs;
+- /* cq: sbal state related to asynchronous operation */
+- struct qdio_outbuf_state *sbal_state;
+ /* timer to check for more outbound work */
+ struct timer_list timer;
+ /* tasklet to check for completions */
+@@ -379,12 +373,8 @@ int qdio_setup_irq(struct qdio_irq *irq_ptr, struct qdio_initialize *init_data);
+ void qdio_shutdown_irq(struct qdio_irq *irq);
+ void qdio_print_subchannel_info(struct qdio_irq *irq_ptr);
+ void qdio_free_queues(struct qdio_irq *irq_ptr);
+-void qdio_free_async_data(struct qdio_irq *irq_ptr);
+ int qdio_setup_init(void);
+ void qdio_setup_exit(void);
+-int qdio_enable_async_operation(struct qdio_output_q *q);
+-void qdio_disable_async_operation(struct qdio_output_q *q);
+-struct qaob *qdio_allocate_aob(void);
+
+ int debug_get_buf_state(struct qdio_q *q, unsigned int bufnr,
+ unsigned char *state);
+diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
+index 03a0116199089..307ce7ff5ca44 100644
+--- a/drivers/s390/cio/qdio_main.c
++++ b/drivers/s390/cio/qdio_main.c
+@@ -517,24 +517,6 @@ static inline int qdio_inbound_q_done(struct qdio_q *q, unsigned int start)
+ return 1;
+ }
+
+-static inline unsigned long qdio_aob_for_buffer(struct qdio_output_q *q,
+- int bufnr)
+-{
+- unsigned long phys_aob = 0;
+-
+- if (!q->aobs[bufnr]) {
+- struct qaob *aob = qdio_allocate_aob();
+- q->aobs[bufnr] = aob;
+- }
+- if (q->aobs[bufnr]) {
+- q->aobs[bufnr]->user1 = (u64) q->sbal_state[bufnr].user;
+- phys_aob = virt_to_phys(q->aobs[bufnr]);
+- WARN_ON_ONCE(phys_aob & 0xFF);
+- }
+-
+- return phys_aob;
+-}
+-
+ static inline int qdio_tasklet_schedule(struct qdio_q *q)
+ {
+ if (likely(q->irq_ptr->state == QDIO_IRQ_STATE_ACTIVE)) {
+@@ -548,7 +530,6 @@ static int get_outbound_buffer_frontier(struct qdio_q *q, unsigned int start,
+ unsigned int *error)
+ {
+ unsigned char state = 0;
+- unsigned int i;
+ int count;
+
+ q->timestamp = get_tod_clock_fast();
+@@ -570,10 +551,6 @@ static int get_outbound_buffer_frontier(struct qdio_q *q, unsigned int start,
+
+ switch (state) {
+ case SLSB_P_OUTPUT_PENDING:
+- /* detach the utilized QAOBs: */
+- for (i = 0; i < count; i++)
+- q->u.out.aobs[QDIO_BUFNR(start + i)] = NULL;
+-
+ *error = QDIO_ERROR_SLSB_PENDING;
+ fallthrough;
+ case SLSB_P_OUTPUT_EMPTY:
+@@ -999,7 +976,6 @@ int qdio_free(struct ccw_device *cdev)
+ cdev->private->qdio_data = NULL;
+ mutex_unlock(&irq_ptr->setup_mutex);
+
+- qdio_free_async_data(irq_ptr);
+ qdio_free_queues(irq_ptr);
+ free_page((unsigned long) irq_ptr->qdr);
+ free_page(irq_ptr->chsc_page);
+@@ -1075,28 +1051,6 @@ err_dbf:
+ }
+ EXPORT_SYMBOL_GPL(qdio_allocate);
+
+-static void qdio_detect_hsicq(struct qdio_irq *irq_ptr)
+-{
+- struct qdio_q *q = irq_ptr->input_qs[0];
+- int i, use_cq = 0;
+-
+- if (irq_ptr->nr_input_qs > 1 && queue_type(q) == QDIO_IQDIO_QFMT)
+- use_cq = 1;
+-
+- for_each_output_queue(irq_ptr, q, i) {
+- if (use_cq) {
+- if (multicast_outbound(q))
+- continue;
+- if (qdio_enable_async_operation(&q->u.out) < 0) {
+- use_cq = 0;
+- continue;
+- }
+- } else
+- qdio_disable_async_operation(&q->u.out);
+- }
+- DBF_EVENT("use_cq:%d", use_cq);
+-}
+-
+ static void qdio_trace_init_data(struct qdio_irq *irq,
+ struct qdio_initialize *data)
+ {
+@@ -1191,8 +1145,6 @@ int qdio_establish(struct ccw_device *cdev,
+
+ qdio_setup_ssqd_info(irq_ptr);
+
+- qdio_detect_hsicq(irq_ptr);
+-
+ /* qebsm is now setup if available, initialize buffer states */
+ qdio_init_buf_states(irq_ptr);
+
+@@ -1297,9 +1249,11 @@ static int handle_inbound(struct qdio_q *q, unsigned int callflags,
+ * @callflags: flags
+ * @bufnr: first buffer to process
+ * @count: how many buffers are filled
++ * @aob: asynchronous operation block
+ */
+ static int handle_outbound(struct qdio_q *q, unsigned int callflags,
+- unsigned int bufnr, unsigned int count)
++ unsigned int bufnr, unsigned int count,
++ struct qaob *aob)
+ {
+ const unsigned int scan_threshold = q->irq_ptr->scan_threshold;
+ unsigned char state = 0;
+@@ -1320,11 +1274,9 @@ static int handle_outbound(struct qdio_q *q, unsigned int callflags,
+ q->u.out.pci_out_enabled = 0;
+
+ if (queue_type(q) == QDIO_IQDIO_QFMT) {
+- unsigned long phys_aob = 0;
+-
+- if (q->u.out.use_cq && count == 1)
+- phys_aob = qdio_aob_for_buffer(&q->u.out, bufnr);
++ unsigned long phys_aob = aob ? virt_to_phys(aob) : 0;
+
++ WARN_ON_ONCE(!IS_ALIGNED(phys_aob, 256));
+ rc = qdio_kick_outbound_q(q, count, phys_aob);
+ } else if (need_siga_sync(q)) {
+ rc = qdio_siga_sync_q(q);
+@@ -1359,9 +1311,10 @@ static int handle_outbound(struct qdio_q *q, unsigned int callflags,
+ * @q_nr: queue number
+ * @bufnr: buffer number
+ * @count: how many buffers to process
++ * @aob: asynchronous operation block (outbound only)
+ */
+ int do_QDIO(struct ccw_device *cdev, unsigned int callflags,
+- int q_nr, unsigned int bufnr, unsigned int count)
++ int q_nr, unsigned int bufnr, unsigned int count, struct qaob *aob)
+ {
+ struct qdio_irq *irq_ptr = cdev->private->qdio_data;
+
+@@ -1383,7 +1336,7 @@ int do_QDIO(struct ccw_device *cdev, unsigned int callflags,
+ callflags, bufnr, count);
+ else if (callflags & QDIO_FLAG_SYNC_OUTPUT)
+ return handle_outbound(irq_ptr->output_qs[q_nr],
+- callflags, bufnr, count);
++ callflags, bufnr, count, aob);
+ return -EINVAL;
+ }
+ EXPORT_SYMBOL_GPL(do_QDIO);
+diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c
+index c8b9620bc6883..da67e49794023 100644
+--- a/drivers/s390/cio/qdio_setup.c
++++ b/drivers/s390/cio/qdio_setup.c
+@@ -30,6 +30,7 @@ struct qaob *qdio_allocate_aob(void)
+ {
+ return kmem_cache_zalloc(qdio_aob_cache, GFP_ATOMIC);
+ }
++EXPORT_SYMBOL_GPL(qdio_allocate_aob);
+
+ void qdio_release_aob(struct qaob *aob)
+ {
+@@ -247,8 +248,6 @@ static void setup_queues(struct qdio_irq *irq_ptr,
+ struct qdio_initialize *qdio_init)
+ {
+ struct qdio_q *q;
+- struct qdio_outbuf_state *output_sbal_state_array =
+- qdio_init->output_sbal_state_array;
+ int i;
+
+ for_each_input_queue(irq_ptr, q, i) {
+@@ -265,9 +264,6 @@ static void setup_queues(struct qdio_irq *irq_ptr,
+ DBF_EVENT("outq:%1d", i);
+ setup_queues_misc(q, irq_ptr, qdio_init->output_handler, i);
+
+- q->u.out.sbal_state = output_sbal_state_array;
+- output_sbal_state_array += QDIO_MAX_BUFFERS_PER_Q;
+-
+ q->is_input_q = 0;
+ setup_storage_lists(q, irq_ptr,
+ qdio_init->output_sbal_addr_array[i], i);
+@@ -372,30 +368,6 @@ void qdio_setup_ssqd_info(struct qdio_irq *irq_ptr)
+ DBF_EVENT("3:%4x qib:%4x", irq_ptr->ssqd_desc.qdioac3, irq_ptr->qib.ac);
+ }
+
+-void qdio_free_async_data(struct qdio_irq *irq_ptr)
+-{
+- struct qdio_q *q;
+- int i;
+-
+- for (i = 0; i < irq_ptr->max_output_qs; i++) {
+- q = irq_ptr->output_qs[i];
+- if (q->u.out.use_cq) {
+- unsigned int n;
+-
+- for (n = 0; n < QDIO_MAX_BUFFERS_PER_Q; n++) {
+- struct qaob *aob = q->u.out.aobs[n];
+-
+- if (aob) {
+- qdio_release_aob(aob);
+- q->u.out.aobs[n] = NULL;
+- }
+- }
+-
+- qdio_disable_async_operation(&q->u.out);
+- }
+- }
+-}
+-
+ static void qdio_fill_qdr_desc(struct qdesfmt0 *desc, struct qdio_q *queue)
+ {
+ desc->sliba = virt_to_phys(queue->slib);
+@@ -545,25 +517,6 @@ void qdio_print_subchannel_info(struct qdio_irq *irq_ptr)
+ printk(KERN_INFO "%s", s);
+ }
+
+-int qdio_enable_async_operation(struct qdio_output_q *outq)
+-{
+- outq->aobs = kcalloc(QDIO_MAX_BUFFERS_PER_Q, sizeof(struct qaob *),
+- GFP_KERNEL);
+- if (!outq->aobs) {
+- outq->use_cq = 0;
+- return -ENOMEM;
+- }
+- outq->use_cq = 1;
+- return 0;
+-}
+-
+-void qdio_disable_async_operation(struct qdio_output_q *q)
+-{
+- kfree(q->aobs);
+- q->aobs = NULL;
+- q->use_cq = 0;
+-}
+-
+ int __init qdio_setup_init(void)
+ {
+ int rc;
+diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
+index 1ffdd411201cd..6946a7e26eff7 100644
+--- a/drivers/s390/crypto/vfio_ap_ops.c
++++ b/drivers/s390/crypto/vfio_ap_ops.c
+@@ -294,6 +294,19 @@ static int handle_pqap(struct kvm_vcpu *vcpu)
+ matrix_mdev = container_of(vcpu->kvm->arch.crypto.pqap_hook,
+ struct ap_matrix_mdev, pqap_hook);
+
++ /*
++ * If the KVM pointer is in the process of being set, wait until the
++ * process has completed.
++ */
++ wait_event_cmd(matrix_mdev->wait_for_kvm,
++ !matrix_mdev->kvm_busy,
++ mutex_unlock(&matrix_dev->lock),
++ mutex_lock(&matrix_dev->lock));
++
++ /* If the there is no guest using the mdev, there is nothing to do */
++ if (!matrix_mdev->kvm)
++ goto out_unlock;
++
+ q = vfio_ap_get_queue(matrix_mdev, apqn);
+ if (!q)
+ goto out_unlock;
+@@ -337,6 +350,7 @@ static int vfio_ap_mdev_create(struct kobject *kobj, struct mdev_device *mdev)
+
+ matrix_mdev->mdev = mdev;
+ vfio_ap_matrix_init(&matrix_dev->info, &matrix_mdev->matrix);
++ init_waitqueue_head(&matrix_mdev->wait_for_kvm);
+ mdev_set_drvdata(mdev, matrix_mdev);
+ matrix_mdev->pqap_hook.hook = handle_pqap;
+ matrix_mdev->pqap_hook.owner = THIS_MODULE;
+@@ -351,17 +365,23 @@ static int vfio_ap_mdev_remove(struct mdev_device *mdev)
+ {
+ struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev);
+
+- if (matrix_mdev->kvm)
++ mutex_lock(&matrix_dev->lock);
++
++ /*
++ * If the KVM pointer is in flux or the guest is running, disallow
++ * un-assignment of control domain.
++ */
++ if (matrix_mdev->kvm_busy || matrix_mdev->kvm) {
++ mutex_unlock(&matrix_dev->lock);
+ return -EBUSY;
++ }
+
+- mutex_lock(&matrix_dev->lock);
+ vfio_ap_mdev_reset_queues(mdev);
+ list_del(&matrix_mdev->node);
+- mutex_unlock(&matrix_dev->lock);
+-
+ kfree(matrix_mdev);
+ mdev_set_drvdata(mdev, NULL);
+ atomic_inc(&matrix_dev->available_instances);
++ mutex_unlock(&matrix_dev->lock);
+
+ return 0;
+ }
+@@ -606,24 +626,31 @@ static ssize_t assign_adapter_store(struct device *dev,
+ struct mdev_device *mdev = mdev_from_dev(dev);
+ struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev);
+
+- /* If the guest is running, disallow assignment of adapter */
+- if (matrix_mdev->kvm)
+- return -EBUSY;
++ mutex_lock(&matrix_dev->lock);
++
++ /*
++ * If the KVM pointer is in flux or the guest is running, disallow
++ * un-assignment of adapter
++ */
++ if (matrix_mdev->kvm_busy || matrix_mdev->kvm) {
++ ret = -EBUSY;
++ goto done;
++ }
+
+ ret = kstrtoul(buf, 0, &apid);
+ if (ret)
+- return ret;
++ goto done;
+
+- if (apid > matrix_mdev->matrix.apm_max)
+- return -ENODEV;
++ if (apid > matrix_mdev->matrix.apm_max) {
++ ret = -ENODEV;
++ goto done;
++ }
+
+ /*
+ * Set the bit in the AP mask (APM) corresponding to the AP adapter
+ * number (APID). The bits in the mask, from most significant to least
+ * significant bit, correspond to APIDs 0-255.
+ */
+- mutex_lock(&matrix_dev->lock);
+-
+ ret = vfio_ap_mdev_verify_queues_reserved_for_apid(matrix_mdev, apid);
+ if (ret)
+ goto done;
+@@ -672,22 +699,31 @@ static ssize_t unassign_adapter_store(struct device *dev,
+ struct mdev_device *mdev = mdev_from_dev(dev);
+ struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev);
+
+- /* If the guest is running, disallow un-assignment of adapter */
+- if (matrix_mdev->kvm)
+- return -EBUSY;
++ mutex_lock(&matrix_dev->lock);
++
++ /*
++ * If the KVM pointer is in flux or the guest is running, disallow
++ * un-assignment of adapter
++ */
++ if (matrix_mdev->kvm_busy || matrix_mdev->kvm) {
++ ret = -EBUSY;
++ goto done;
++ }
+
+ ret = kstrtoul(buf, 0, &apid);
+ if (ret)
+- return ret;
++ goto done;
+
+- if (apid > matrix_mdev->matrix.apm_max)
+- return -ENODEV;
++ if (apid > matrix_mdev->matrix.apm_max) {
++ ret = -ENODEV;
++ goto done;
++ }
+
+- mutex_lock(&matrix_dev->lock);
+ clear_bit_inv((unsigned long)apid, matrix_mdev->matrix.apm);
++ ret = count;
++done:
+ mutex_unlock(&matrix_dev->lock);
+-
+- return count;
++ return ret;
+ }
+ static DEVICE_ATTR_WO(unassign_adapter);
+
+@@ -753,17 +789,24 @@ static ssize_t assign_domain_store(struct device *dev,
+ struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev);
+ unsigned long max_apqi = matrix_mdev->matrix.aqm_max;
+
+- /* If the guest is running, disallow assignment of domain */
+- if (matrix_mdev->kvm)
+- return -EBUSY;
++ mutex_lock(&matrix_dev->lock);
++
++ /*
++ * If the KVM pointer is in flux or the guest is running, disallow
++ * assignment of domain
++ */
++ if (matrix_mdev->kvm_busy || matrix_mdev->kvm) {
++ ret = -EBUSY;
++ goto done;
++ }
+
+ ret = kstrtoul(buf, 0, &apqi);
+ if (ret)
+- return ret;
+- if (apqi > max_apqi)
+- return -ENODEV;
+-
+- mutex_lock(&matrix_dev->lock);
++ goto done;
++ if (apqi > max_apqi) {
++ ret = -ENODEV;
++ goto done;
++ }
+
+ ret = vfio_ap_mdev_verify_queues_reserved_for_apqi(matrix_mdev, apqi);
+ if (ret)
+@@ -814,22 +857,32 @@ static ssize_t unassign_domain_store(struct device *dev,
+ struct mdev_device *mdev = mdev_from_dev(dev);
+ struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev);
+
+- /* If the guest is running, disallow un-assignment of domain */
+- if (matrix_mdev->kvm)
+- return -EBUSY;
++ mutex_lock(&matrix_dev->lock);
++
++ /*
++ * If the KVM pointer is in flux or the guest is running, disallow
++ * un-assignment of domain
++ */
++ if (matrix_mdev->kvm_busy || matrix_mdev->kvm) {
++ ret = -EBUSY;
++ goto done;
++ }
+
+ ret = kstrtoul(buf, 0, &apqi);
+ if (ret)
+- return ret;
++ goto done;
+
+- if (apqi > matrix_mdev->matrix.aqm_max)
+- return -ENODEV;
++ if (apqi > matrix_mdev->matrix.aqm_max) {
++ ret = -ENODEV;
++ goto done;
++ }
+
+- mutex_lock(&matrix_dev->lock);
+ clear_bit_inv((unsigned long)apqi, matrix_mdev->matrix.aqm);
+- mutex_unlock(&matrix_dev->lock);
++ ret = count;
+
+- return count;
++done:
++ mutex_unlock(&matrix_dev->lock);
++ return ret;
+ }
+ static DEVICE_ATTR_WO(unassign_domain);
+
+@@ -858,27 +911,36 @@ static ssize_t assign_control_domain_store(struct device *dev,
+ struct mdev_device *mdev = mdev_from_dev(dev);
+ struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev);
+
+- /* If the guest is running, disallow assignment of control domain */
+- if (matrix_mdev->kvm)
+- return -EBUSY;
++ mutex_lock(&matrix_dev->lock);
++
++ /*
++ * If the KVM pointer is in flux or the guest is running, disallow
++ * assignment of control domain.
++ */
++ if (matrix_mdev->kvm_busy || matrix_mdev->kvm) {
++ ret = -EBUSY;
++ goto done;
++ }
+
+ ret = kstrtoul(buf, 0, &id);
+ if (ret)
+- return ret;
++ goto done;
+
+- if (id > matrix_mdev->matrix.adm_max)
+- return -ENODEV;
++ if (id > matrix_mdev->matrix.adm_max) {
++ ret = -ENODEV;
++ goto done;
++ }
+
+ /* Set the bit in the ADM (bitmask) corresponding to the AP control
+ * domain number (id). The bits in the mask, from most significant to
+ * least significant, correspond to IDs 0 up to the one less than the
+ * number of control domains that can be assigned.
+ */
+- mutex_lock(&matrix_dev->lock);
+ set_bit_inv(id, matrix_mdev->matrix.adm);
++ ret = count;
++done:
+ mutex_unlock(&matrix_dev->lock);
+-
+- return count;
++ return ret;
+ }
+ static DEVICE_ATTR_WO(assign_control_domain);
+
+@@ -908,21 +970,30 @@ static ssize_t unassign_control_domain_store(struct device *dev,
+ struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev);
+ unsigned long max_domid = matrix_mdev->matrix.adm_max;
+
+- /* If the guest is running, disallow un-assignment of control domain */
+- if (matrix_mdev->kvm)
+- return -EBUSY;
++ mutex_lock(&matrix_dev->lock);
++
++ /*
++ * If the KVM pointer is in flux or the guest is running, disallow
++ * un-assignment of control domain.
++ */
++ if (matrix_mdev->kvm_busy || matrix_mdev->kvm) {
++ ret = -EBUSY;
++ goto done;
++ }
+
+ ret = kstrtoul(buf, 0, &domid);
+ if (ret)
+- return ret;
+- if (domid > max_domid)
+- return -ENODEV;
++ goto done;
++ if (domid > max_domid) {
++ ret = -ENODEV;
++ goto done;
++ }
+
+- mutex_lock(&matrix_dev->lock);
+ clear_bit_inv(domid, matrix_mdev->matrix.adm);
++ ret = count;
++done:
+ mutex_unlock(&matrix_dev->lock);
+-
+- return count;
++ return ret;
+ }
+ static DEVICE_ATTR_WO(unassign_control_domain);
+
+@@ -1027,8 +1098,15 @@ static const struct attribute_group *vfio_ap_mdev_attr_groups[] = {
+ * @matrix_mdev: a mediated matrix device
+ * @kvm: reference to KVM instance
+ *
+- * Verifies no other mediated matrix device has @kvm and sets a reference to
+- * it in @matrix_mdev->kvm.
++ * Sets all data for @matrix_mdev that are needed to manage AP resources
++ * for the guest whose state is represented by @kvm.
++ *
++ * Note: The matrix_dev->lock must be taken prior to calling
++ * this function; however, the lock will be temporarily released while the
++ * guest's AP configuration is set to avoid a potential lockdep splat.
++ * The kvm->lock is taken to set the guest's AP configuration which, under
++ * certain circumstances, will result in a circular lock dependency if this is
++ * done under the @matrix_mdev->lock.
+ *
+ * Return 0 if no other mediated matrix device has a reference to @kvm;
+ * otherwise, returns an -EPERM.
+@@ -1038,14 +1116,25 @@ static int vfio_ap_mdev_set_kvm(struct ap_matrix_mdev *matrix_mdev,
+ {
+ struct ap_matrix_mdev *m;
+
+- list_for_each_entry(m, &matrix_dev->mdev_list, node) {
+- if ((m != matrix_mdev) && (m->kvm == kvm))
+- return -EPERM;
+- }
++ if (kvm->arch.crypto.crycbd) {
++ list_for_each_entry(m, &matrix_dev->mdev_list, node) {
++ if (m != matrix_mdev && m->kvm == kvm)
++ return -EPERM;
++ }
+
+- matrix_mdev->kvm = kvm;
+- kvm_get_kvm(kvm);
+- kvm->arch.crypto.pqap_hook = &matrix_mdev->pqap_hook;
++ kvm_get_kvm(kvm);
++ matrix_mdev->kvm_busy = true;
++ mutex_unlock(&matrix_dev->lock);
++ kvm_arch_crypto_set_masks(kvm,
++ matrix_mdev->matrix.apm,
++ matrix_mdev->matrix.aqm,
++ matrix_mdev->matrix.adm);
++ mutex_lock(&matrix_dev->lock);
++ kvm->arch.crypto.pqap_hook = &matrix_mdev->pqap_hook;
++ matrix_mdev->kvm = kvm;
++ matrix_mdev->kvm_busy = false;
++ wake_up_all(&matrix_mdev->wait_for_kvm);
++ }
+
+ return 0;
+ }
+@@ -1079,51 +1168,65 @@ static int vfio_ap_mdev_iommu_notifier(struct notifier_block *nb,
+ return NOTIFY_DONE;
+ }
+
++/**
++ * vfio_ap_mdev_unset_kvm
++ *
++ * @matrix_mdev: a matrix mediated device
++ *
++ * Performs clean-up of resources no longer needed by @matrix_mdev.
++ *
++ * Note: The matrix_dev->lock must be taken prior to calling
++ * this function; however, the lock will be temporarily released while the
++ * guest's AP configuration is cleared to avoid a potential lockdep splat.
++ * The kvm->lock is taken to clear the guest's AP configuration which, under
++ * certain circumstances, will result in a circular lock dependency if this is
++ * done under the @matrix_mdev->lock.
++ *
++ */
+ static void vfio_ap_mdev_unset_kvm(struct ap_matrix_mdev *matrix_mdev)
+ {
+- kvm_arch_crypto_clear_masks(matrix_mdev->kvm);
+- matrix_mdev->kvm->arch.crypto.pqap_hook = NULL;
+- vfio_ap_mdev_reset_queues(matrix_mdev->mdev);
+- kvm_put_kvm(matrix_mdev->kvm);
+- matrix_mdev->kvm = NULL;
++ /*
++ * If the KVM pointer is in the process of being set, wait until the
++ * process has completed.
++ */
++ wait_event_cmd(matrix_mdev->wait_for_kvm,
++ !matrix_mdev->kvm_busy,
++ mutex_unlock(&matrix_dev->lock),
++ mutex_lock(&matrix_dev->lock));
++
++ if (matrix_mdev->kvm) {
++ matrix_mdev->kvm_busy = true;
++ mutex_unlock(&matrix_dev->lock);
++ kvm_arch_crypto_clear_masks(matrix_mdev->kvm);
++ mutex_lock(&matrix_dev->lock);
++ vfio_ap_mdev_reset_queues(matrix_mdev->mdev);
++ matrix_mdev->kvm->arch.crypto.pqap_hook = NULL;
++ kvm_put_kvm(matrix_mdev->kvm);
++ matrix_mdev->kvm = NULL;
++ matrix_mdev->kvm_busy = false;
++ wake_up_all(&matrix_mdev->wait_for_kvm);
++ }
+ }
+
+ static int vfio_ap_mdev_group_notifier(struct notifier_block *nb,
+ unsigned long action, void *data)
+ {
+- int ret, notify_rc = NOTIFY_OK;
++ int notify_rc = NOTIFY_OK;
+ struct ap_matrix_mdev *matrix_mdev;
+
+ if (action != VFIO_GROUP_NOTIFY_SET_KVM)
+ return NOTIFY_OK;
+
+- matrix_mdev = container_of(nb, struct ap_matrix_mdev, group_notifier);
+ mutex_lock(&matrix_dev->lock);
++ matrix_mdev = container_of(nb, struct ap_matrix_mdev, group_notifier);
+
+- if (!data) {
+- if (matrix_mdev->kvm)
+- vfio_ap_mdev_unset_kvm(matrix_mdev);
+- goto notify_done;
+- }
+-
+- ret = vfio_ap_mdev_set_kvm(matrix_mdev, data);
+- if (ret) {
+- notify_rc = NOTIFY_DONE;
+- goto notify_done;
+- }
+-
+- /* If there is no CRYCB pointer, then we can't copy the masks */
+- if (!matrix_mdev->kvm->arch.crypto.crycbd) {
++ if (!data)
++ vfio_ap_mdev_unset_kvm(matrix_mdev);
++ else if (vfio_ap_mdev_set_kvm(matrix_mdev, data))
+ notify_rc = NOTIFY_DONE;
+- goto notify_done;
+- }
+-
+- kvm_arch_crypto_set_masks(matrix_mdev->kvm, matrix_mdev->matrix.apm,
+- matrix_mdev->matrix.aqm,
+- matrix_mdev->matrix.adm);
+
+-notify_done:
+ mutex_unlock(&matrix_dev->lock);
++
+ return notify_rc;
+ }
+
+@@ -1258,8 +1361,7 @@ static void vfio_ap_mdev_release(struct mdev_device *mdev)
+ struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev);
+
+ mutex_lock(&matrix_dev->lock);
+- if (matrix_mdev->kvm)
+- vfio_ap_mdev_unset_kvm(matrix_mdev);
++ vfio_ap_mdev_unset_kvm(matrix_mdev);
+ mutex_unlock(&matrix_dev->lock);
+
+ vfio_unregister_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY,
+@@ -1293,6 +1395,7 @@ static ssize_t vfio_ap_mdev_ioctl(struct mdev_device *mdev,
+ unsigned int cmd, unsigned long arg)
+ {
+ int ret;
++ struct ap_matrix_mdev *matrix_mdev;
+
+ mutex_lock(&matrix_dev->lock);
+ switch (cmd) {
+@@ -1300,6 +1403,21 @@ static ssize_t vfio_ap_mdev_ioctl(struct mdev_device *mdev,
+ ret = vfio_ap_mdev_get_device_info(arg);
+ break;
+ case VFIO_DEVICE_RESET:
++ matrix_mdev = mdev_get_drvdata(mdev);
++ if (WARN(!matrix_mdev, "Driver data missing from mdev!!")) {
++ ret = -EINVAL;
++ break;
++ }
++
++ /*
++ * If the KVM pointer is in the process of being set, wait until
++ * the process has completed.
++ */
++ wait_event_cmd(matrix_mdev->wait_for_kvm,
++ !matrix_mdev->kvm_busy,
++ mutex_unlock(&matrix_dev->lock),
++ mutex_lock(&matrix_dev->lock));
++
+ ret = vfio_ap_mdev_reset_queues(mdev);
+ break;
+ default:
+diff --git a/drivers/s390/crypto/vfio_ap_private.h b/drivers/s390/crypto/vfio_ap_private.h
+index 28e9d99897682..f82a6396acae7 100644
+--- a/drivers/s390/crypto/vfio_ap_private.h
++++ b/drivers/s390/crypto/vfio_ap_private.h
+@@ -83,6 +83,8 @@ struct ap_matrix_mdev {
+ struct ap_matrix matrix;
+ struct notifier_block group_notifier;
+ struct notifier_block iommu_notifier;
++ bool kvm_busy;
++ wait_queue_head_t wait_for_kvm;
+ struct kvm *kvm;
+ struct kvm_s390_module_hook pqap_hook;
+ struct mdev_device *mdev;
+diff --git a/drivers/s390/crypto/zcrypt_card.c b/drivers/s390/crypto/zcrypt_card.c
+index 33b23884b133f..09fe6bb8880bc 100644
+--- a/drivers/s390/crypto/zcrypt_card.c
++++ b/drivers/s390/crypto/zcrypt_card.c
+@@ -192,5 +192,6 @@ void zcrypt_card_unregister(struct zcrypt_card *zc)
+ spin_unlock(&zcrypt_list_lock);
+ sysfs_remove_group(&zc->card->ap_dev.device.kobj,
+ &zcrypt_card_attr_group);
++ zcrypt_card_put(zc);
+ }
+ EXPORT_SYMBOL(zcrypt_card_unregister);
+diff --git a/drivers/s390/crypto/zcrypt_queue.c b/drivers/s390/crypto/zcrypt_queue.c
+index 5062eae73d4aa..c3ffbd26b73ff 100644
+--- a/drivers/s390/crypto/zcrypt_queue.c
++++ b/drivers/s390/crypto/zcrypt_queue.c
+@@ -223,5 +223,6 @@ void zcrypt_queue_unregister(struct zcrypt_queue *zq)
+ sysfs_remove_group(&zq->queue->ap_dev.device.kobj,
+ &zcrypt_queue_attr_group);
+ zcrypt_card_put(zc);
++ zcrypt_queue_put(zq);
+ }
+ EXPORT_SYMBOL(zcrypt_queue_unregister);
+diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
+index 91acff493612a..fd9b869d278ed 100644
+--- a/drivers/s390/net/qeth_core.h
++++ b/drivers/s390/net/qeth_core.h
+@@ -437,6 +437,7 @@ struct qeth_qdio_out_buffer {
+
+ struct qeth_qdio_out_q *q;
+ struct list_head list_entry;
++ struct qaob *aob;
+ };
+
+ struct qeth_card;
+@@ -499,7 +500,6 @@ struct qeth_out_q_stats {
+ struct qeth_qdio_out_q {
+ struct qdio_buffer *qdio_bufs[QDIO_MAX_BUFFERS_PER_Q];
+ struct qeth_qdio_out_buffer *bufs[QDIO_MAX_BUFFERS_PER_Q];
+- struct qdio_outbuf_state *bufstates; /* convenience pointer */
+ struct list_head pending_bufs;
+ struct qeth_out_q_stats stats;
+ spinlock_t lock;
+@@ -563,7 +563,6 @@ struct qeth_qdio_info {
+ /* output */
+ unsigned int no_out_queues;
+ struct qeth_qdio_out_q *out_qs[QETH_MAX_OUT_QUEUES];
+- struct qdio_outbuf_state *out_bufstates;
+
+ /* priority queueing */
+ int do_prio_queueing;
+diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
+index a814698387bc3..175b82b98f369 100644
+--- a/drivers/s390/net/qeth_core_main.c
++++ b/drivers/s390/net/qeth_core_main.c
+@@ -369,8 +369,7 @@ static int qeth_cq_init(struct qeth_card *card)
+ QDIO_MAX_BUFFERS_PER_Q);
+ card->qdio.c_q->next_buf_to_init = 127;
+ rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT,
+- card->qdio.no_in_queues - 1, 0,
+- 127);
++ card->qdio.no_in_queues - 1, 0, 127, NULL);
+ if (rc) {
+ QETH_CARD_TEXT_(card, 2, "1err%d", rc);
+ goto out;
+@@ -383,48 +382,22 @@ out:
+
+ static int qeth_alloc_cq(struct qeth_card *card)
+ {
+- int rc;
+-
+ if (card->options.cq == QETH_CQ_ENABLED) {
+- int i;
+- struct qdio_outbuf_state *outbuf_states;
+-
+ QETH_CARD_TEXT(card, 2, "cqon");
+ card->qdio.c_q = qeth_alloc_qdio_queue();
+ if (!card->qdio.c_q) {
+- rc = -1;
+- goto kmsg_out;
++ dev_err(&card->gdev->dev, "Failed to create completion queue\n");
++ return -ENOMEM;
+ }
++
+ card->qdio.no_in_queues = 2;
+- card->qdio.out_bufstates =
+- kcalloc(card->qdio.no_out_queues *
+- QDIO_MAX_BUFFERS_PER_Q,
+- sizeof(struct qdio_outbuf_state),
+- GFP_KERNEL);
+- outbuf_states = card->qdio.out_bufstates;
+- if (outbuf_states == NULL) {
+- rc = -1;
+- goto free_cq_out;
+- }
+- for (i = 0; i < card->qdio.no_out_queues; ++i) {
+- card->qdio.out_qs[i]->bufstates = outbuf_states;
+- outbuf_states += QDIO_MAX_BUFFERS_PER_Q;
+- }
+ } else {
+ QETH_CARD_TEXT(card, 2, "nocq");
+ card->qdio.c_q = NULL;
+ card->qdio.no_in_queues = 1;
+ }
+ QETH_CARD_TEXT_(card, 2, "iqc%d", card->qdio.no_in_queues);
+- rc = 0;
+-out:
+- return rc;
+-free_cq_out:
+- qeth_free_qdio_queue(card->qdio.c_q);
+- card->qdio.c_q = NULL;
+-kmsg_out:
+- dev_err(&card->gdev->dev, "Failed to create completion queue\n");
+- goto out;
++ return 0;
+ }
+
+ static void qeth_free_cq(struct qeth_card *card)
+@@ -434,8 +407,6 @@ static void qeth_free_cq(struct qeth_card *card)
+ qeth_free_qdio_queue(card->qdio.c_q);
+ card->qdio.c_q = NULL;
+ }
+- kfree(card->qdio.out_bufstates);
+- card->qdio.out_bufstates = NULL;
+ }
+
+ static enum iucv_tx_notify qeth_compute_cq_notification(int sbalf15,
+@@ -487,12 +458,12 @@ static void qeth_qdio_handle_aob(struct qeth_card *card,
+ switch (atomic_xchg(&buffer->state, new_state)) {
+ case QETH_QDIO_BUF_PRIMED:
+ /* Faster than TX completion code, let it handle the async
+- * completion for us.
++ * completion for us. It will also recycle the QAOB.
+ */
+ break;
+ case QETH_QDIO_BUF_PENDING:
+ /* TX completion code is active and will handle the async
+- * completion for us.
++ * completion for us. It will also recycle the QAOB.
+ */
+ break;
+ case QETH_QDIO_BUF_NEED_QAOB:
+@@ -501,7 +472,7 @@ static void qeth_qdio_handle_aob(struct qeth_card *card,
+ qeth_notify_skbs(buffer->q, buffer, notification);
+
+ /* Free dangling allocations. The attached skbs are handled by
+- * qeth_tx_complete_pending_bufs().
++ * qeth_tx_complete_pending_bufs(), and so is the QAOB.
+ */
+ for (i = 0;
+ i < aob->sb_count && i < QETH_MAX_BUFFER_ELEMENTS(card);
+@@ -520,8 +491,6 @@ static void qeth_qdio_handle_aob(struct qeth_card *card,
+ default:
+ WARN_ON_ONCE(1);
+ }
+-
+- qdio_release_aob(aob);
+ }
+
+ static void qeth_setup_ccw(struct ccw1 *ccw, u8 cmd_code, u8 flags, u32 len,
+@@ -1451,6 +1420,13 @@ static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
+ atomic_set(&buf->state, QETH_QDIO_BUF_EMPTY);
+ }
+
++static void qeth_free_out_buf(struct qeth_qdio_out_buffer *buf)
++{
++ if (buf->aob)
++ qdio_release_aob(buf->aob);
++ kmem_cache_free(qeth_qdio_outbuf_cache, buf);
++}
++
+ static void qeth_tx_complete_pending_bufs(struct qeth_card *card,
+ struct qeth_qdio_out_q *queue,
+ bool drain)
+@@ -1468,7 +1444,7 @@ static void qeth_tx_complete_pending_bufs(struct qeth_card *card,
+ qeth_tx_complete_buf(buf, drain, 0);
+
+ list_del(&buf->list_entry);
+- kmem_cache_free(qeth_qdio_outbuf_cache, buf);
++ qeth_free_out_buf(buf);
+ }
+ }
+ }
+@@ -1485,7 +1461,7 @@ static void qeth_drain_output_queue(struct qeth_qdio_out_q *q, bool free)
+
+ qeth_clear_output_buffer(q, q->bufs[j], true, 0);
+ if (free) {
+- kmem_cache_free(qeth_qdio_outbuf_cache, q->bufs[j]);
++ qeth_free_out_buf(q->bufs[j]);
+ q->bufs[j] = NULL;
+ }
+ }
+@@ -2637,7 +2613,7 @@ static struct qeth_qdio_out_q *qeth_alloc_output_queue(void)
+
+ err_out_bufs:
+ while (i > 0)
+- kmem_cache_free(qeth_qdio_outbuf_cache, q->bufs[--i]);
++ qeth_free_out_buf(q->bufs[--i]);
+ qdio_free_buffers(q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q);
+ err_qdio_bufs:
+ kfree(q);
+@@ -3024,7 +3000,8 @@ static int qeth_init_qdio_queues(struct qeth_card *card)
+ }
+
+ card->qdio.in_q->next_buf_to_init = QDIO_BUFNR(rx_bufs);
+- rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, 0, 0, rx_bufs);
++ rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, 0, 0, rx_bufs,
++ NULL);
+ if (rc) {
+ QETH_CARD_TEXT_(card, 2, "1err%d", rc);
+ return rc;
+@@ -3516,7 +3493,7 @@ static unsigned int qeth_rx_refill_queue(struct qeth_card *card,
+ }
+
+ rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, 0,
+- queue->next_buf_to_init, count);
++ queue->next_buf_to_init, count, NULL);
+ if (rc) {
+ QETH_CARD_TEXT(card, 2, "qinberr");
+ }
+@@ -3625,6 +3602,7 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index,
+ struct qeth_qdio_out_buffer *buf = queue->bufs[index];
+ unsigned int qdio_flags = QDIO_FLAG_SYNC_OUTPUT;
+ struct qeth_card *card = queue->card;
++ struct qaob *aob = NULL;
+ int rc;
+ int i;
+
+@@ -3637,16 +3615,24 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index,
+ SBAL_EFLAGS_LAST_ENTRY;
+ queue->coalesced_frames += buf->frames;
+
+- if (queue->bufstates)
+- queue->bufstates[bidx].user = buf;
+-
+ if (IS_IQD(card)) {
+ skb_queue_walk(&buf->skb_list, skb)
+ skb_tx_timestamp(skb);
+ }
+ }
+
+- if (!IS_IQD(card)) {
++ if (IS_IQD(card)) {
++ if (card->options.cq == QETH_CQ_ENABLED &&
++ !qeth_iqd_is_mcast_queue(card, queue) &&
++ count == 1) {
++ if (!buf->aob)
++ buf->aob = qdio_allocate_aob();
++ if (buf->aob) {
++ aob = buf->aob;
++ aob->user1 = (u64) buf;
++ }
++ }
++ } else {
+ if (!queue->do_pack) {
+ if ((atomic_read(&queue->used_buffers) >=
+ (QETH_HIGH_WATERMARK_PACK -
+@@ -3677,8 +3663,8 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index,
+ }
+
+ QETH_TXQ_STAT_INC(queue, doorbell);
+- rc = do_QDIO(CARD_DDEV(queue->card), qdio_flags,
+- queue->queue_no, index, count);
++ rc = do_QDIO(CARD_DDEV(card), qdio_flags, queue->queue_no, index, count,
++ aob);
+
+ switch (rc) {
+ case 0:
+@@ -3814,8 +3800,7 @@ static void qeth_qdio_cq_handler(struct qeth_card *card, unsigned int qdio_err,
+ qeth_scrub_qdio_buffer(buffer, QDIO_MAX_ELEMENTS_PER_BUFFER);
+ }
+ rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, queue,
+- card->qdio.c_q->next_buf_to_init,
+- count);
++ cq->next_buf_to_init, count, NULL);
+ if (rc) {
+ dev_warn(&card->gdev->dev,
+ "QDIO reported an error, rc=%i\n", rc);
+@@ -5270,7 +5255,6 @@ static int qeth_qdio_establish(struct qeth_card *card)
+ init_data.int_parm = (unsigned long) card;
+ init_data.input_sbal_addr_array = in_sbal_ptrs;
+ init_data.output_sbal_addr_array = out_sbal_ptrs;
+- init_data.output_sbal_state_array = card->qdio.out_bufstates;
+ init_data.scan_threshold = IS_IQD(card) ? 0 : 32;
+
+ if (atomic_cmpxchg(&card->qdio.state, QETH_QDIO_ALLOCATED,
+@@ -6069,7 +6053,15 @@ static void qeth_iqd_tx_complete(struct qeth_qdio_out_q *queue,
+ bool error = !!qdio_error;
+
+ if (qdio_error == QDIO_ERROR_SLSB_PENDING) {
+- WARN_ON_ONCE(card->options.cq != QETH_CQ_ENABLED);
++ struct qaob *aob = buffer->aob;
++
++ if (!aob) {
++ netdev_WARN_ONCE(card->dev,
++ "Pending TX buffer %#x without QAOB on TX queue %u\n",
++ bidx, queue->queue_no);
++ qeth_schedule_recovery(card);
++ return;
++ }
+
+ QETH_CARD_TEXT_(card, 5, "pel%u", bidx);
+
+@@ -6125,6 +6117,8 @@ static void qeth_iqd_tx_complete(struct qeth_qdio_out_q *queue,
+ default:
+ WARN_ON_ONCE(1);
+ }
++
++ memset(aob, 0, sizeof(*aob));
+ } else if (card->options.cq == QETH_CQ_ENABLED) {
+ qeth_notify_skbs(queue, buffer,
+ qeth_compute_cq_notification(sflags, 0));
+diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
+index 23ab16d65f2a4..049596cbfb5de 100644
+--- a/drivers/s390/scsi/zfcp_qdio.c
++++ b/drivers/s390/scsi/zfcp_qdio.c
+@@ -128,7 +128,7 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err,
+ /*
+ * put SBALs back to response queue
+ */
+- if (do_QDIO(cdev, QDIO_FLAG_SYNC_INPUT, 0, idx, count))
++ if (do_QDIO(cdev, QDIO_FLAG_SYNC_INPUT, 0, idx, count, NULL))
+ zfcp_erp_adapter_reopen(qdio->adapter, 0, "qdires2");
+ }
+
+@@ -298,7 +298,7 @@ int zfcp_qdio_send(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req)
+ atomic_sub(sbal_number, &qdio->req_q_free);
+
+ retval = do_QDIO(qdio->adapter->ccw_device, QDIO_FLAG_SYNC_OUTPUT, 0,
+- q_req->sbal_first, sbal_number);
++ q_req->sbal_first, sbal_number, NULL);
+
+ if (unlikely(retval)) {
+ /* Failed to submit the IO, roll back our modifications. */
+@@ -463,7 +463,8 @@ int zfcp_qdio_open(struct zfcp_qdio *qdio)
+ sbale->addr = 0;
+ }
+
+- if (do_QDIO(cdev, QDIO_FLAG_SYNC_INPUT, 0, 0, QDIO_MAX_BUFFERS_PER_Q))
++ if (do_QDIO(cdev, QDIO_FLAG_SYNC_INPUT, 0, 0, QDIO_MAX_BUFFERS_PER_Q,
++ NULL))
+ goto failed_qdio;
+
+ /* set index of first available SBALS / number of available SBALS */
+diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c
+index ea436a14087f1..5eff3368143d3 100644
+--- a/drivers/scsi/device_handler/scsi_dh_alua.c
++++ b/drivers/scsi/device_handler/scsi_dh_alua.c
+@@ -573,10 +573,11 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_port_group *pg)
+ * even though it shouldn't according to T10.
+ * The retry without rtpg_ext_hdr_req set
+ * handles this.
++ * Note: some arrays return a sense key of ILLEGAL_REQUEST
++ * with ASC 00h if they don't support the extended header.
+ */
+ if (!(pg->flags & ALUA_RTPG_EXT_HDR_UNSUPP) &&
+- sense_hdr.sense_key == ILLEGAL_REQUEST &&
+- sense_hdr.asc == 0x24 && sense_hdr.ascq == 0) {
++ sense_hdr.sense_key == ILLEGAL_REQUEST) {
+ pg->flags |= ALUA_RTPG_EXT_HDR_UNSUPP;
+ goto retry;
+ }
+diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
+index 22826544da7e7..9989669beec3c 100644
+--- a/drivers/scsi/libfc/fc_lport.c
++++ b/drivers/scsi/libfc/fc_lport.c
+@@ -1731,7 +1731,7 @@ void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
+
+ if (mfs < FC_SP_MIN_MAX_PAYLOAD || mfs > FC_SP_MAX_MAX_PAYLOAD) {
+ FC_LPORT_DBG(lport, "FLOGI bad mfs:%hu response, "
+- "lport->mfs:%hu\n", mfs, lport->mfs);
++ "lport->mfs:%u\n", mfs, lport->mfs);
+ fc_lport_error(lport, fp);
+ goto out;
+ }
+diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
+index bdd9a29f4201c..0496a60735ef1 100644
+--- a/drivers/scsi/lpfc/lpfc_attr.c
++++ b/drivers/scsi/lpfc/lpfc_attr.c
+@@ -1687,8 +1687,7 @@ lpfc_set_trunking(struct lpfc_hba *phba, char *buff_out)
+ lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
+ "0071 Set trunk mode failed with status: %d",
+ rc);
+- if (rc != MBX_TIMEOUT)
+- mempool_free(mbox, phba->mbox_mem_pool);
++ mempool_free(mbox, phba->mbox_mem_pool);
+
+ return 0;
+ }
+@@ -6793,15 +6792,19 @@ lpfc_get_stats(struct Scsi_Host *shost)
+ pmboxq->ctx_buf = NULL;
+ pmboxq->vport = vport;
+
+- if (vport->fc_flag & FC_OFFLINE_MODE)
++ if (vport->fc_flag & FC_OFFLINE_MODE) {
+ rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
+- else
+- rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
+-
+- if (rc != MBX_SUCCESS) {
+- if (rc != MBX_TIMEOUT)
++ if (rc != MBX_SUCCESS) {
+ mempool_free(pmboxq, phba->mbox_mem_pool);
+- return NULL;
++ return NULL;
++ }
++ } else {
++ rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
++ if (rc != MBX_SUCCESS) {
++ if (rc != MBX_TIMEOUT)
++ mempool_free(pmboxq, phba->mbox_mem_pool);
++ return NULL;
++ }
+ }
+
+ memset(hs, 0, sizeof (struct fc_host_statistics));
+@@ -6825,15 +6828,19 @@ lpfc_get_stats(struct Scsi_Host *shost)
+ pmboxq->ctx_buf = NULL;
+ pmboxq->vport = vport;
+
+- if (vport->fc_flag & FC_OFFLINE_MODE)
++ if (vport->fc_flag & FC_OFFLINE_MODE) {
+ rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
+- else
+- rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
+-
+- if (rc != MBX_SUCCESS) {
+- if (rc != MBX_TIMEOUT)
++ if (rc != MBX_SUCCESS) {
+ mempool_free(pmboxq, phba->mbox_mem_pool);
+- return NULL;
++ return NULL;
++ }
++ } else {
++ rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
++ if (rc != MBX_SUCCESS) {
++ if (rc != MBX_TIMEOUT)
++ mempool_free(pmboxq, phba->mbox_mem_pool);
++ return NULL;
++ }
+ }
+
+ hs->link_failure_count = pmb->un.varRdLnk.linkFailureCnt;
+@@ -6906,15 +6913,19 @@ lpfc_reset_stats(struct Scsi_Host *shost)
+ pmboxq->vport = vport;
+
+ if ((vport->fc_flag & FC_OFFLINE_MODE) ||
+- (!(psli->sli_flag & LPFC_SLI_ACTIVE)))
++ (!(psli->sli_flag & LPFC_SLI_ACTIVE))) {
+ rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
+- else
+- rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
+-
+- if (rc != MBX_SUCCESS) {
+- if (rc != MBX_TIMEOUT)
++ if (rc != MBX_SUCCESS) {
+ mempool_free(pmboxq, phba->mbox_mem_pool);
+- return;
++ return;
++ }
++ } else {
++ rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
++ if (rc != MBX_SUCCESS) {
++ if (rc != MBX_TIMEOUT)
++ mempool_free(pmboxq, phba->mbox_mem_pool);
++ return;
++ }
+ }
+
+ memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t));
+@@ -6924,15 +6935,19 @@ lpfc_reset_stats(struct Scsi_Host *shost)
+ pmboxq->vport = vport;
+
+ if ((vport->fc_flag & FC_OFFLINE_MODE) ||
+- (!(psli->sli_flag & LPFC_SLI_ACTIVE)))
++ (!(psli->sli_flag & LPFC_SLI_ACTIVE))) {
+ rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
+- else
++ if (rc != MBX_SUCCESS) {
++ mempool_free(pmboxq, phba->mbox_mem_pool);
++ return;
++ }
++ } else {
+ rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
+-
+- if (rc != MBX_SUCCESS) {
+- if (rc != MBX_TIMEOUT)
+- mempool_free( pmboxq, phba->mbox_mem_pool);
+- return;
++ if (rc != MBX_SUCCESS) {
++ if (rc != MBX_TIMEOUT)
++ mempool_free(pmboxq, phba->mbox_mem_pool);
++ return;
++ }
+ }
+
+ lso->link_failure_count = pmb->un.varRdLnk.linkFailureCnt;
+diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
+index a0aad4896a459..763b1eeb0ca80 100644
+--- a/drivers/scsi/lpfc/lpfc_crtn.h
++++ b/drivers/scsi/lpfc/lpfc_crtn.h
+@@ -55,9 +55,6 @@ void lpfc_register_new_vport(struct lpfc_hba *, struct lpfc_vport *,
+ void lpfc_unreg_vpi(struct lpfc_hba *, uint16_t, LPFC_MBOXQ_t *);
+ void lpfc_init_link(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t);
+ void lpfc_request_features(struct lpfc_hba *, struct lpfcMboxq *);
+-void lpfc_supported_pages(struct lpfcMboxq *);
+-void lpfc_pc_sli4_params(struct lpfcMboxq *);
+-int lpfc_pc_sli4_params_get(struct lpfc_hba *, LPFC_MBOXQ_t *);
+ int lpfc_sli4_mbox_rsrc_extent(struct lpfc_hba *, struct lpfcMboxq *,
+ uint16_t, uint16_t, bool);
+ int lpfc_get_sli4_parameters(struct lpfc_hba *, LPFC_MBOXQ_t *);
+@@ -351,8 +348,8 @@ int lpfc_sli_hbq_size(void);
+ int lpfc_sli_issue_abort_iotag(struct lpfc_hba *, struct lpfc_sli_ring *,
+ struct lpfc_iocbq *, void *);
+ int lpfc_sli_sum_iocb(struct lpfc_vport *, uint16_t, uint64_t, lpfc_ctx_cmd);
+-int lpfc_sli_abort_iocb(struct lpfc_vport *, struct lpfc_sli_ring *, uint16_t,
+- uint64_t, lpfc_ctx_cmd);
++int lpfc_sli_abort_iocb(struct lpfc_vport *vport, u16 tgt_id, u64 lun_id,
++ lpfc_ctx_cmd abort_cmd);
+ int
+ lpfc_sli_abort_taskmgmt(struct lpfc_vport *, struct lpfc_sli_ring *,
+ uint16_t, uint64_t, lpfc_ctx_cmd);
+diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
+index f0a758138ae88..fd18ac2acc135 100644
+--- a/drivers/scsi/lpfc/lpfc_els.c
++++ b/drivers/scsi/lpfc/lpfc_els.c
+@@ -1600,7 +1600,7 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
+ struct lpfc_nodelist *new_ndlp;
+ struct serv_parm *sp;
+ uint8_t name[sizeof(struct lpfc_name)];
+- uint32_t rc, keepDID = 0, keep_nlp_flag = 0;
++ uint32_t keepDID = 0, keep_nlp_flag = 0;
+ uint32_t keep_new_nlp_flag = 0;
+ uint16_t keep_nlp_state;
+ u32 keep_nlp_fc4_type = 0;
+@@ -1622,7 +1622,7 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
+ new_ndlp = lpfc_findnode_wwpn(vport, &sp->portName);
+
+ /* return immediately if the WWPN matches ndlp */
+- if (new_ndlp == ndlp)
++ if (!new_ndlp || (new_ndlp == ndlp))
+ return ndlp;
+
+ if (phba->sli_rev == LPFC_SLI_REV4) {
+@@ -1641,30 +1641,11 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
+ (new_ndlp ? new_ndlp->nlp_flag : 0),
+ (new_ndlp ? new_ndlp->nlp_fc4_type : 0));
+
+- if (!new_ndlp) {
+- rc = memcmp(&ndlp->nlp_portname, name,
+- sizeof(struct lpfc_name));
+- if (!rc) {
+- if (active_rrqs_xri_bitmap)
+- mempool_free(active_rrqs_xri_bitmap,
+- phba->active_rrq_pool);
+- return ndlp;
+- }
+- new_ndlp = lpfc_nlp_init(vport, ndlp->nlp_DID);
+- if (!new_ndlp) {
+- if (active_rrqs_xri_bitmap)
+- mempool_free(active_rrqs_xri_bitmap,
+- phba->active_rrq_pool);
+- return ndlp;
+- }
+- } else {
+- keepDID = new_ndlp->nlp_DID;
+- if (phba->sli_rev == LPFC_SLI_REV4 &&
+- active_rrqs_xri_bitmap)
+- memcpy(active_rrqs_xri_bitmap,
+- new_ndlp->active_rrqs_xri_bitmap,
+- phba->cfg_rrq_xri_bitmap_sz);
+- }
++ keepDID = new_ndlp->nlp_DID;
++
++ if (phba->sli_rev == LPFC_SLI_REV4 && active_rrqs_xri_bitmap)
++ memcpy(active_rrqs_xri_bitmap, new_ndlp->active_rrqs_xri_bitmap,
++ phba->cfg_rrq_xri_bitmap_sz);
+
+ /* At this point in this routine, we know new_ndlp will be
+ * returned. however, any previous GID_FTs that were done
+@@ -3829,7 +3810,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+ did = irsp->un.elsreq64.remoteID;
+ ndlp = lpfc_findnode_did(vport, did);
+ if (!ndlp && (cmd != ELS_CMD_PLOGI))
+- return 1;
++ return 0;
+ }
+
+ lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
+@@ -4473,10 +4454,7 @@ lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
+ * nlp_flag bitmap in the ndlp data structure, if the mbox command reference
+ * field in the command IOCB is not NULL, the referred mailbox command will
+ * be send out, and then invokes the lpfc_els_free_iocb() routine to release
+- * the IOCB. Under error conditions, such as when a LS_RJT is returned or a
+- * link down event occurred during the discovery, the lpfc_nlp_not_used()
+- * routine shall be invoked trying to release the ndlp if no other threads
+- * are currently referring it.
++ * the IOCB.
+ **/
+ static void
+ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+@@ -4486,10 +4464,8 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+ struct lpfc_vport *vport = ndlp ? ndlp->vport : NULL;
+ struct Scsi_Host *shost = vport ? lpfc_shost_from_vport(vport) : NULL;
+ IOCB_t *irsp;
+- uint8_t *pcmd;
+ LPFC_MBOXQ_t *mbox = NULL;
+ struct lpfc_dmabuf *mp = NULL;
+- uint32_t ls_rjt = 0;
+
+ irsp = &rspiocb->iocb;
+
+@@ -4501,18 +4477,6 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+ if (cmdiocb->context_un.mbox)
+ mbox = cmdiocb->context_un.mbox;
+
+- /* First determine if this is a LS_RJT cmpl. Note, this callback
+- * function can have cmdiocb->contest1 (ndlp) field set to NULL.
+- */
+- pcmd = (uint8_t *) (((struct lpfc_dmabuf *) cmdiocb->context2)->virt);
+- if (ndlp && (*((uint32_t *) (pcmd)) == ELS_CMD_LS_RJT)) {
+- /* A LS_RJT associated with Default RPI cleanup has its own
+- * separate code path.
+- */
+- if (!(ndlp->nlp_flag & NLP_RM_DFLT_RPI))
+- ls_rjt = 1;
+- }
+-
+ /* Check to see if link went down during discovery */
+ if (!ndlp || lpfc_els_chk_latt(vport)) {
+ if (mbox) {
+@@ -4523,15 +4487,6 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+ }
+ mempool_free(mbox, phba->mbox_mem_pool);
+ }
+- if (ndlp && (ndlp->nlp_flag & NLP_RM_DFLT_RPI))
+- if (lpfc_nlp_not_used(ndlp)) {
+- ndlp = NULL;
+- /* Indicate the node has already released,
+- * should not reference to it from within
+- * the routine lpfc_els_free_iocb.
+- */
+- cmdiocb->context1 = NULL;
+- }
+ goto out;
+ }
+
+@@ -4609,29 +4564,6 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+ "Data: x%x x%x x%x\n",
+ ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
+ ndlp->nlp_rpi);
+-
+- if (lpfc_nlp_not_used(ndlp)) {
+- ndlp = NULL;
+- /* Indicate node has already been released,
+- * should not reference to it from within
+- * the routine lpfc_els_free_iocb.
+- */
+- cmdiocb->context1 = NULL;
+- }
+- } else {
+- /* Do not drop node for lpfc_els_abort'ed ELS cmds */
+- if (!lpfc_error_lost_link(irsp) &&
+- ndlp->nlp_flag & NLP_ACC_REGLOGIN) {
+- if (lpfc_nlp_not_used(ndlp)) {
+- ndlp = NULL;
+- /* Indicate node has already been
+- * released, should not reference
+- * to it from within the routine
+- * lpfc_els_free_iocb.
+- */
+- cmdiocb->context1 = NULL;
+- }
+- }
+ }
+ mp = (struct lpfc_dmabuf *)mbox->ctx_buf;
+ if (mp) {
+@@ -4647,19 +4579,6 @@ out:
+ ndlp->nlp_flag &= ~NLP_ACC_REGLOGIN;
+ ndlp->nlp_flag &= ~NLP_RM_DFLT_RPI;
+ spin_unlock_irq(&ndlp->lock);
+-
+- /* If the node is not being used by another discovery thread,
+- * and we are sending a reject, we are done with it.
+- * Release driver reference count here and free associated
+- * resources.
+- */
+- if (ls_rjt)
+- if (lpfc_nlp_not_used(ndlp))
+- /* Indicate node has already been released,
+- * should not reference to it from within
+- * the routine lpfc_els_free_iocb.
+- */
+- cmdiocb->context1 = NULL;
+ }
+
+ /* Release the originating I/O reference. */
+diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
+index 48ca4a612f801..c5176f4063864 100644
+--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
++++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
+@@ -140,11 +140,8 @@ lpfc_terminate_rport_io(struct fc_rport *rport)
+ "rport terminate: sid:x%x did:x%x flg:x%x",
+ ndlp->nlp_sid, ndlp->nlp_DID, ndlp->nlp_flag);
+
+- if (ndlp->nlp_sid != NLP_NO_SID) {
+- lpfc_sli_abort_iocb(vport,
+- &vport->phba->sli.sli3_ring[LPFC_FCP_RING],
+- ndlp->nlp_sid, 0, LPFC_CTX_TGT);
+- }
++ if (ndlp->nlp_sid != NLP_NO_SID)
++ lpfc_sli_abort_iocb(vport, ndlp->nlp_sid, 0, LPFC_CTX_TGT);
+ }
+
+ /*
+@@ -299,8 +296,7 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
+
+ if (ndlp->nlp_sid != NLP_NO_SID) {
+ warn_on = 1;
+- lpfc_sli_abort_iocb(vport, &phba->sli.sli3_ring[LPFC_FCP_RING],
+- ndlp->nlp_sid, 0, LPFC_CTX_TGT);
++ lpfc_sli_abort_iocb(vport, ndlp->nlp_sid, 0, LPFC_CTX_TGT);
+ }
+
+ if (warn_on) {
+diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
+index 541b9aef6bfec..f5bc2c32a8179 100644
+--- a/drivers/scsi/lpfc/lpfc_hw4.h
++++ b/drivers/scsi/lpfc/lpfc_hw4.h
+@@ -124,6 +124,7 @@ struct lpfc_sli_intf {
+ /* Define SLI4 Alignment requirements. */
+ #define LPFC_ALIGN_16_BYTE 16
+ #define LPFC_ALIGN_64_BYTE 64
++#define SLI4_PAGE_SIZE 4096
+
+ /* Define SLI4 specific definitions. */
+ #define LPFC_MQ_CQE_BYTE_OFFSET 256
+@@ -2976,62 +2977,6 @@ struct lpfc_mbx_request_features {
+ #define lpfc_mbx_rq_ftr_rsp_mrqp_WORD word3
+ };
+
+-struct lpfc_mbx_supp_pages {
+- uint32_t word1;
+-#define qs_SHIFT 0
+-#define qs_MASK 0x00000001
+-#define qs_WORD word1
+-#define wr_SHIFT 1
+-#define wr_MASK 0x00000001
+-#define wr_WORD word1
+-#define pf_SHIFT 8
+-#define pf_MASK 0x000000ff
+-#define pf_WORD word1
+-#define cpn_SHIFT 16
+-#define cpn_MASK 0x000000ff
+-#define cpn_WORD word1
+- uint32_t word2;
+-#define list_offset_SHIFT 0
+-#define list_offset_MASK 0x000000ff
+-#define list_offset_WORD word2
+-#define next_offset_SHIFT 8
+-#define next_offset_MASK 0x000000ff
+-#define next_offset_WORD word2
+-#define elem_cnt_SHIFT 16
+-#define elem_cnt_MASK 0x000000ff
+-#define elem_cnt_WORD word2
+- uint32_t word3;
+-#define pn_0_SHIFT 24
+-#define pn_0_MASK 0x000000ff
+-#define pn_0_WORD word3
+-#define pn_1_SHIFT 16
+-#define pn_1_MASK 0x000000ff
+-#define pn_1_WORD word3
+-#define pn_2_SHIFT 8
+-#define pn_2_MASK 0x000000ff
+-#define pn_2_WORD word3
+-#define pn_3_SHIFT 0
+-#define pn_3_MASK 0x000000ff
+-#define pn_3_WORD word3
+- uint32_t word4;
+-#define pn_4_SHIFT 24
+-#define pn_4_MASK 0x000000ff
+-#define pn_4_WORD word4
+-#define pn_5_SHIFT 16
+-#define pn_5_MASK 0x000000ff
+-#define pn_5_WORD word4
+-#define pn_6_SHIFT 8
+-#define pn_6_MASK 0x000000ff
+-#define pn_6_WORD word4
+-#define pn_7_SHIFT 0
+-#define pn_7_MASK 0x000000ff
+-#define pn_7_WORD word4
+- uint32_t rsvd[27];
+-#define LPFC_SUPP_PAGES 0
+-#define LPFC_BLOCK_GUARD_PROFILES 1
+-#define LPFC_SLI4_PARAMETERS 2
+-};
+-
+ struct lpfc_mbx_memory_dump_type3 {
+ uint32_t word1;
+ #define lpfc_mbx_memory_dump_type3_type_SHIFT 0
+@@ -3248,121 +3193,6 @@ struct user_eeprom {
+ uint8_t reserved191[57];
+ };
+
+-struct lpfc_mbx_pc_sli4_params {
+- uint32_t word1;
+-#define qs_SHIFT 0
+-#define qs_MASK 0x00000001
+-#define qs_WORD word1
+-#define wr_SHIFT 1
+-#define wr_MASK 0x00000001
+-#define wr_WORD word1
+-#define pf_SHIFT 8
+-#define pf_MASK 0x000000ff
+-#define pf_WORD word1
+-#define cpn_SHIFT 16
+-#define cpn_MASK 0x000000ff
+-#define cpn_WORD word1
+- uint32_t word2;
+-#define if_type_SHIFT 0
+-#define if_type_MASK 0x00000007
+-#define if_type_WORD word2
+-#define sli_rev_SHIFT 4
+-#define sli_rev_MASK 0x0000000f
+-#define sli_rev_WORD word2
+-#define sli_family_SHIFT 8
+-#define sli_family_MASK 0x000000ff
+-#define sli_family_WORD word2
+-#define featurelevel_1_SHIFT 16
+-#define featurelevel_1_MASK 0x000000ff
+-#define featurelevel_1_WORD word2
+-#define featurelevel_2_SHIFT 24
+-#define featurelevel_2_MASK 0x0000001f
+-#define featurelevel_2_WORD word2
+- uint32_t word3;
+-#define fcoe_SHIFT 0
+-#define fcoe_MASK 0x00000001
+-#define fcoe_WORD word3
+-#define fc_SHIFT 1
+-#define fc_MASK 0x00000001
+-#define fc_WORD word3
+-#define nic_SHIFT 2
+-#define nic_MASK 0x00000001
+-#define nic_WORD word3
+-#define iscsi_SHIFT 3
+-#define iscsi_MASK 0x00000001
+-#define iscsi_WORD word3
+-#define rdma_SHIFT 4
+-#define rdma_MASK 0x00000001
+-#define rdma_WORD word3
+- uint32_t sge_supp_len;
+-#define SLI4_PAGE_SIZE 4096
+- uint32_t word5;
+-#define if_page_sz_SHIFT 0
+-#define if_page_sz_MASK 0x0000ffff
+-#define if_page_sz_WORD word5
+-#define loopbk_scope_SHIFT 24
+-#define loopbk_scope_MASK 0x0000000f
+-#define loopbk_scope_WORD word5
+-#define rq_db_window_SHIFT 28
+-#define rq_db_window_MASK 0x0000000f
+-#define rq_db_window_WORD word5
+- uint32_t word6;
+-#define eq_pages_SHIFT 0
+-#define eq_pages_MASK 0x0000000f
+-#define eq_pages_WORD word6
+-#define eqe_size_SHIFT 8
+-#define eqe_size_MASK 0x000000ff
+-#define eqe_size_WORD word6
+- uint32_t word7;
+-#define cq_pages_SHIFT 0
+-#define cq_pages_MASK 0x0000000f
+-#define cq_pages_WORD word7
+-#define cqe_size_SHIFT 8
+-#define cqe_size_MASK 0x000000ff
+-#define cqe_size_WORD word7
+- uint32_t word8;
+-#define mq_pages_SHIFT 0
+-#define mq_pages_MASK 0x0000000f
+-#define mq_pages_WORD word8
+-#define mqe_size_SHIFT 8
+-#define mqe_size_MASK 0x000000ff
+-#define mqe_size_WORD word8
+-#define mq_elem_cnt_SHIFT 16
+-#define mq_elem_cnt_MASK 0x000000ff
+-#define mq_elem_cnt_WORD word8
+- uint32_t word9;
+-#define wq_pages_SHIFT 0
+-#define wq_pages_MASK 0x0000ffff
+-#define wq_pages_WORD word9
+-#define wqe_size_SHIFT 8
+-#define wqe_size_MASK 0x000000ff
+-#define wqe_size_WORD word9
+- uint32_t word10;
+-#define rq_pages_SHIFT 0
+-#define rq_pages_MASK 0x0000ffff
+-#define rq_pages_WORD word10
+-#define rqe_size_SHIFT 8
+-#define rqe_size_MASK 0x000000ff
+-#define rqe_size_WORD word10
+- uint32_t word11;
+-#define hdr_pages_SHIFT 0
+-#define hdr_pages_MASK 0x0000000f
+-#define hdr_pages_WORD word11
+-#define hdr_size_SHIFT 8
+-#define hdr_size_MASK 0x0000000f
+-#define hdr_size_WORD word11
+-#define hdr_pp_align_SHIFT 16
+-#define hdr_pp_align_MASK 0x0000ffff
+-#define hdr_pp_align_WORD word11
+- uint32_t word12;
+-#define sgl_pages_SHIFT 0
+-#define sgl_pages_MASK 0x0000000f
+-#define sgl_pages_WORD word12
+-#define sgl_pp_align_SHIFT 16
+-#define sgl_pp_align_MASK 0x0000ffff
+-#define sgl_pp_align_WORD word12
+- uint32_t rsvd_13_63[51];
+-};
+ #define SLI4_PAGE_ALIGN(addr) (((addr)+((SLI4_PAGE_SIZE)-1)) \
+ &(~((SLI4_PAGE_SIZE)-1)))
+
+@@ -3994,8 +3824,6 @@ struct lpfc_mqe {
+ struct lpfc_mbx_post_hdr_tmpl hdr_tmpl;
+ struct lpfc_mbx_query_fw_config query_fw_cfg;
+ struct lpfc_mbx_set_beacon_config beacon_config;
+- struct lpfc_mbx_supp_pages supp_pages;
+- struct lpfc_mbx_pc_sli4_params sli4_params;
+ struct lpfc_mbx_get_sli4_parameters get_sli4_parameters;
+ struct lpfc_mbx_set_link_diag_state link_diag_state;
+ struct lpfc_mbx_set_link_diag_loopback link_diag_loopback;
+diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
+index 71f340dd4fbdc..a67051ba3f127 100644
+--- a/drivers/scsi/lpfc/lpfc_init.c
++++ b/drivers/scsi/lpfc/lpfc_init.c
+@@ -6573,8 +6573,6 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
+ LPFC_MBOXQ_t *mboxq;
+ MAILBOX_t *mb;
+ int rc, i, max_buf_size;
+- uint8_t pn_page[LPFC_MAX_SUPPORTED_PAGES] = {0};
+- struct lpfc_mqe *mqe;
+ int longs;
+ int extra;
+ uint64_t wwn;
+@@ -6808,32 +6806,6 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
+
+ lpfc_nvme_mod_param_dep(phba);
+
+- /* Get the Supported Pages if PORT_CAPABILITIES is supported by port. */
+- lpfc_supported_pages(mboxq);
+- rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
+- if (!rc) {
+- mqe = &mboxq->u.mqe;
+- memcpy(&pn_page[0], ((uint8_t *)&mqe->un.supp_pages.word3),
+- LPFC_MAX_SUPPORTED_PAGES);
+- for (i = 0; i < LPFC_MAX_SUPPORTED_PAGES; i++) {
+- switch (pn_page[i]) {
+- case LPFC_SLI4_PARAMETERS:
+- phba->sli4_hba.pc_sli4_params.supported = 1;
+- break;
+- default:
+- break;
+- }
+- }
+- /* Read the port's SLI4 Parameters capabilities if supported. */
+- if (phba->sli4_hba.pc_sli4_params.supported)
+- rc = lpfc_pc_sli4_params_get(phba, mboxq);
+- if (rc) {
+- mempool_free(mboxq, phba->mbox_mem_pool);
+- rc = -EIO;
+- goto out_free_bsmbx;
+- }
+- }
+-
+ /*
+ * Get sli4 parameters that override parameters from Port capabilities.
+ * If this call fails, it isn't critical unless the SLI4 parameters come
+@@ -9660,8 +9632,7 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba)
+ "3250 QUERY_FW_CFG mailbox failed with status "
+ "x%x add_status x%x, mbx status x%x\n",
+ shdr_status, shdr_add_status, rc);
+- if (rc != MBX_TIMEOUT)
+- mempool_free(mboxq, phba->mbox_mem_pool);
++ mempool_free(mboxq, phba->mbox_mem_pool);
+ rc = -ENXIO;
+ goto out_error;
+ }
+@@ -9677,8 +9648,7 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba)
+ "ulp1_mode:x%x\n", phba->sli4_hba.fw_func_mode,
+ phba->sli4_hba.ulp0_mode, phba->sli4_hba.ulp1_mode);
+
+- if (rc != MBX_TIMEOUT)
+- mempool_free(mboxq, phba->mbox_mem_pool);
++ mempool_free(mboxq, phba->mbox_mem_pool);
+
+ /*
+ * Set up HBA Event Queues (EQs)
+@@ -10276,8 +10246,7 @@ lpfc_pci_function_reset(struct lpfc_hba *phba)
+ shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
+ shdr_add_status = bf_get(lpfc_mbox_hdr_add_status,
+ &shdr->response);
+- if (rc != MBX_TIMEOUT)
+- mempool_free(mboxq, phba->mbox_mem_pool);
++ mempool_free(mboxq, phba->mbox_mem_pool);
+ if (shdr_status || shdr_add_status || rc) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
+ "0495 SLI_FUNCTION_RESET mailbox "
+@@ -12075,78 +12044,6 @@ lpfc_sli4_hba_unset(struct lpfc_hba *phba)
+ phba->pport->work_port_events = 0;
+ }
+
+- /**
+- * lpfc_pc_sli4_params_get - Get the SLI4_PARAMS port capabilities.
+- * @phba: Pointer to HBA context object.
+- * @mboxq: Pointer to the mailboxq memory for the mailbox command response.
+- *
+- * This function is called in the SLI4 code path to read the port's
+- * sli4 capabilities.
+- *
+- * This function may be be called from any context that can block-wait
+- * for the completion. The expectation is that this routine is called
+- * typically from probe_one or from the online routine.
+- **/
+-int
+-lpfc_pc_sli4_params_get(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
+-{
+- int rc;
+- struct lpfc_mqe *mqe;
+- struct lpfc_pc_sli4_params *sli4_params;
+- uint32_t mbox_tmo;
+-
+- rc = 0;
+- mqe = &mboxq->u.mqe;
+-
+- /* Read the port's SLI4 Parameters port capabilities */
+- lpfc_pc_sli4_params(mboxq);
+- if (!phba->sli4_hba.intr_enable)
+- rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
+- else {
+- mbox_tmo = lpfc_mbox_tmo_val(phba, mboxq);
+- rc = lpfc_sli_issue_mbox_wait(phba, mboxq, mbox_tmo);
+- }
+-
+- if (unlikely(rc))
+- return 1;
+-
+- sli4_params = &phba->sli4_hba.pc_sli4_params;
+- sli4_params->if_type = bf_get(if_type, &mqe->un.sli4_params);
+- sli4_params->sli_rev = bf_get(sli_rev, &mqe->un.sli4_params);
+- sli4_params->sli_family = bf_get(sli_family, &mqe->un.sli4_params);
+- sli4_params->featurelevel_1 = bf_get(featurelevel_1,
+- &mqe->un.sli4_params);
+- sli4_params->featurelevel_2 = bf_get(featurelevel_2,
+- &mqe->un.sli4_params);
+- sli4_params->proto_types = mqe->un.sli4_params.word3;
+- sli4_params->sge_supp_len = mqe->un.sli4_params.sge_supp_len;
+- sli4_params->if_page_sz = bf_get(if_page_sz, &mqe->un.sli4_params);
+- sli4_params->rq_db_window = bf_get(rq_db_window, &mqe->un.sli4_params);
+- sli4_params->loopbk_scope = bf_get(loopbk_scope, &mqe->un.sli4_params);
+- sli4_params->eq_pages_max = bf_get(eq_pages, &mqe->un.sli4_params);
+- sli4_params->eqe_size = bf_get(eqe_size, &mqe->un.sli4_params);
+- sli4_params->cq_pages_max = bf_get(cq_pages, &mqe->un.sli4_params);
+- sli4_params->cqe_size = bf_get(cqe_size, &mqe->un.sli4_params);
+- sli4_params->mq_pages_max = bf_get(mq_pages, &mqe->un.sli4_params);
+- sli4_params->mqe_size = bf_get(mqe_size, &mqe->un.sli4_params);
+- sli4_params->mq_elem_cnt = bf_get(mq_elem_cnt, &mqe->un.sli4_params);
+- sli4_params->wq_pages_max = bf_get(wq_pages, &mqe->un.sli4_params);
+- sli4_params->wqe_size = bf_get(wqe_size, &mqe->un.sli4_params);
+- sli4_params->rq_pages_max = bf_get(rq_pages, &mqe->un.sli4_params);
+- sli4_params->rqe_size = bf_get(rqe_size, &mqe->un.sli4_params);
+- sli4_params->hdr_pages_max = bf_get(hdr_pages, &mqe->un.sli4_params);
+- sli4_params->hdr_size = bf_get(hdr_size, &mqe->un.sli4_params);
+- sli4_params->hdr_pp_align = bf_get(hdr_pp_align, &mqe->un.sli4_params);
+- sli4_params->sgl_pages_max = bf_get(sgl_pages, &mqe->un.sli4_params);
+- sli4_params->sgl_pp_align = bf_get(sgl_pp_align, &mqe->un.sli4_params);
+-
+- /* Make sure that sge_supp_len can be handled by the driver */
+- if (sli4_params->sge_supp_len > LPFC_MAX_SGE_SIZE)
+- sli4_params->sge_supp_len = LPFC_MAX_SGE_SIZE;
+-
+- return rc;
+-}
+-
+ /**
+ * lpfc_get_sli4_parameters - Get the SLI4 Config PARAMETERS.
+ * @phba: Pointer to HBA context object.
+@@ -12205,7 +12102,8 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
+ else
+ phba->sli3_options &= ~LPFC_SLI4_PHWQ_ENABLED;
+ sli4_params->sge_supp_len = mbx_sli4_parameters->sge_supp_len;
+- sli4_params->loopbk_scope = bf_get(loopbk_scope, mbx_sli4_parameters);
++ sli4_params->loopbk_scope = bf_get(cfg_loopbk_scope,
++ mbx_sli4_parameters);
+ sli4_params->oas_supported = bf_get(cfg_oas, mbx_sli4_parameters);
+ sli4_params->cqv = bf_get(cfg_cqv, mbx_sli4_parameters);
+ sli4_params->mqv = bf_get(cfg_mqv, mbx_sli4_parameters);
+diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c
+index c03a7f12dd65b..72dd22ad5dccf 100644
+--- a/drivers/scsi/lpfc/lpfc_mbox.c
++++ b/drivers/scsi/lpfc/lpfc_mbox.c
+@@ -2624,39 +2624,3 @@ lpfc_resume_rpi(struct lpfcMboxq *mbox, struct lpfc_nodelist *ndlp)
+ resume_rpi->event_tag = ndlp->phba->fc_eventTag;
+ }
+
+-/**
+- * lpfc_supported_pages - Initialize the PORT_CAPABILITIES supported pages
+- * mailbox command.
+- * @mbox: pointer to lpfc mbox command to initialize.
+- *
+- * The PORT_CAPABILITIES supported pages mailbox command is issued to
+- * retrieve the particular feature pages supported by the port.
+- **/
+-void
+-lpfc_supported_pages(struct lpfcMboxq *mbox)
+-{
+- struct lpfc_mbx_supp_pages *supp_pages;
+-
+- memset(mbox, 0, sizeof(*mbox));
+- supp_pages = &mbox->u.mqe.un.supp_pages;
+- bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_PORT_CAPABILITIES);
+- bf_set(cpn, supp_pages, LPFC_SUPP_PAGES);
+-}
+-
+-/**
+- * lpfc_pc_sli4_params - Initialize the PORT_CAPABILITIES SLI4 Params mbox cmd.
+- * @mbox: pointer to lpfc mbox command to initialize.
+- *
+- * The PORT_CAPABILITIES SLI4 parameters mailbox command is issued to
+- * retrieve the particular SLI4 features supported by the port.
+- **/
+-void
+-lpfc_pc_sli4_params(struct lpfcMboxq *mbox)
+-{
+- struct lpfc_mbx_pc_sli4_params *sli4_params;
+-
+- memset(mbox, 0, sizeof(*mbox));
+- sli4_params = &mbox->u.mqe.un.sli4_params;
+- bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_PORT_CAPABILITIES);
+- bf_set(cpn, sli4_params, LPFC_SLI4_PARAMETERS);
+-}
+diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
+index 135d8e8a42ba2..9f05f5e329c6b 100644
+--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
++++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
+@@ -279,106 +279,43 @@ lpfc_els_abort(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
+ lpfc_cancel_retry_delay_tmo(phba->pport, ndlp);
+ }
+
+-/* lpfc_defer_pt2pt_acc - Complete SLI3 pt2pt processing on link up
++/* lpfc_defer_plogi_acc - Issue PLOGI ACC after reg_login completes
+ * @phba: pointer to lpfc hba data structure.
+- * @link_mbox: pointer to CONFIG_LINK mailbox object
++ * @login_mbox: pointer to REG_RPI mailbox object
+ *
+- * This routine is only called if we are SLI3, direct connect pt2pt
+- * mode and the remote NPort issues the PLOGI after link up.
++ * The ACC for a rcv'ed PLOGI is deferred until AFTER the REG_RPI completes
+ */
+ static void
+-lpfc_defer_pt2pt_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *link_mbox)
++lpfc_defer_plogi_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *login_mbox)
+ {
+- LPFC_MBOXQ_t *login_mbox;
+- MAILBOX_t *mb = &link_mbox->u.mb;
+ struct lpfc_iocbq *save_iocb;
+ struct lpfc_nodelist *ndlp;
++ MAILBOX_t *mb = &login_mbox->u.mb;
++
+ int rc;
+
+- ndlp = link_mbox->ctx_ndlp;
+- login_mbox = link_mbox->context3;
++ ndlp = login_mbox->ctx_ndlp;
+ save_iocb = login_mbox->context3;
+- link_mbox->context3 = NULL;
+- login_mbox->context3 = NULL;
+-
+- /* Check for CONFIG_LINK error */
+- if (mb->mbxStatus) {
+- lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
+- "4575 CONFIG_LINK fails pt2pt discovery: %x\n",
+- mb->mbxStatus);
+- mempool_free(login_mbox, phba->mbox_mem_pool);
+- mempool_free(link_mbox, phba->mbox_mem_pool);
+- kfree(save_iocb);
+- return;
+- }
+
+- /* Now that CONFIG_LINK completed, and our SID is configured,
+- * we can now proceed with sending the PLOGI ACC.
+- */
+- rc = lpfc_els_rsp_acc(link_mbox->vport, ELS_CMD_PLOGI,
+- save_iocb, ndlp, login_mbox);
+- if (rc) {
+- lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
+- "4576 PLOGI ACC fails pt2pt discovery: %x\n",
+- rc);
+- mempool_free(login_mbox, phba->mbox_mem_pool);
++ if (mb->mbxStatus == MBX_SUCCESS) {
++ /* Now that REG_RPI completed successfully,
++ * we can now proceed with sending the PLOGI ACC.
++ */
++ rc = lpfc_els_rsp_acc(login_mbox->vport, ELS_CMD_PLOGI,
++ save_iocb, ndlp, NULL);
++ if (rc) {
++ lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
++ "4576 PLOGI ACC fails pt2pt discovery: "
++ "DID %x Data: %x\n", ndlp->nlp_DID, rc);
++ }
+ }
+
+- mempool_free(link_mbox, phba->mbox_mem_pool);
++ /* Now process the REG_RPI cmpl */
++ lpfc_mbx_cmpl_reg_login(phba, login_mbox);
++ ndlp->nlp_flag &= ~NLP_ACC_REGLOGIN;
+ kfree(save_iocb);
+ }
+
+-/**
+- * lpfc_defer_tgt_acc - Progress SLI4 target rcv PLOGI handler
+- * @phba: Pointer to HBA context object.
+- * @pmb: Pointer to mailbox object.
+- *
+- * This function provides the unreg rpi mailbox completion handler for a tgt.
+- * The routine frees the memory resources associated with the completed
+- * mailbox command and transmits the ELS ACC.
+- *
+- * This routine is only called if we are SLI4, acting in target
+- * mode and the remote NPort issues the PLOGI after link up.
+- **/
+-static void
+-lpfc_defer_acc_rsp(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
+-{
+- struct lpfc_vport *vport = pmb->vport;
+- struct lpfc_nodelist *ndlp = pmb->ctx_ndlp;
+- LPFC_MBOXQ_t *mbox = pmb->context3;
+- struct lpfc_iocbq *piocb = NULL;
+- int rc;
+-
+- if (mbox) {
+- pmb->context3 = NULL;
+- piocb = mbox->context3;
+- mbox->context3 = NULL;
+- }
+-
+- /*
+- * Complete the unreg rpi mbx request, and update flags.
+- * This will also restart any deferred events.
+- */
+- lpfc_sli4_unreg_rpi_cmpl_clr(phba, pmb);
+-
+- if (!piocb) {
+- lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
+- "4578 PLOGI ACC fail\n");
+- if (mbox)
+- mempool_free(mbox, phba->mbox_mem_pool);
+- return;
+- }
+-
+- rc = lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, piocb, ndlp, mbox);
+- if (rc) {
+- lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
+- "4579 PLOGI ACC fail %x\n", rc);
+- if (mbox)
+- mempool_free(mbox, phba->mbox_mem_pool);
+- }
+- kfree(piocb);
+-}
+-
+ static int
+ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+ struct lpfc_iocbq *cmdiocb)
+@@ -395,8 +332,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+ struct lpfc_iocbq *save_iocb;
+ struct ls_rjt stat;
+ uint32_t vid, flag;
+- u16 rpi;
+- int rc, defer_acc;
++ int rc;
+
+ memset(&stat, 0, sizeof (struct ls_rjt));
+ pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
+@@ -445,7 +381,6 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+ else
+ ndlp->nlp_fcp_info |= CLASS3;
+
+- defer_acc = 0;
+ ndlp->nlp_class_sup = 0;
+ if (sp->cls1.classValid)
+ ndlp->nlp_class_sup |= FC_COS_CLASS1;
+@@ -539,27 +474,26 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+
+ memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm));
+
+- /* Issue config_link / reg_vfi to account for updated TOV's */
+-
++ /* Issue CONFIG_LINK for SLI3 or REG_VFI for SLI4,
++ * to account for updated TOV's / parameters
++ */
+ if (phba->sli_rev == LPFC_SLI_REV4)
+ lpfc_issue_reg_vfi(vport);
+ else {
+- defer_acc = 1;
+ link_mbox = mempool_alloc(phba->mbox_mem_pool,
+ GFP_KERNEL);
+ if (!link_mbox)
+ goto out;
+ lpfc_config_link(phba, link_mbox);
+- link_mbox->mbox_cmpl = lpfc_defer_pt2pt_acc;
++ link_mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
+ link_mbox->vport = vport;
+ link_mbox->ctx_ndlp = ndlp;
+
+- save_iocb = kzalloc(sizeof(*save_iocb), GFP_KERNEL);
+- if (!save_iocb)
++ rc = lpfc_sli_issue_mbox(phba, link_mbox, MBX_NOWAIT);
++ if (rc == MBX_NOT_FINISHED) {
++ mempool_free(link_mbox, phba->mbox_mem_pool);
+ goto out;
+- /* Save info from cmd IOCB used in rsp */
+- memcpy((uint8_t *)save_iocb, (uint8_t *)cmdiocb,
+- sizeof(struct lpfc_iocbq));
++ }
+ }
+
+ lpfc_can_disctmo(vport);
+@@ -578,59 +512,28 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+ if (!login_mbox)
+ goto out;
+
+- /* Registering an existing RPI behaves differently for SLI3 vs SLI4 */
+- if (phba->nvmet_support && !defer_acc) {
+- link_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+- if (!link_mbox)
+- goto out;
+-
+- /* As unique identifiers such as iotag would be overwritten
+- * with those from the cmdiocb, allocate separate temporary
+- * storage for the copy.
+- */
+- save_iocb = kzalloc(sizeof(*save_iocb), GFP_KERNEL);
+- if (!save_iocb)
+- goto out;
+-
+- /* Unreg RPI is required for SLI4. */
+- rpi = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];
+- lpfc_unreg_login(phba, vport->vpi, rpi, link_mbox);
+- link_mbox->vport = vport;
+- link_mbox->ctx_ndlp = lpfc_nlp_get(ndlp);
+- if (!link_mbox->ctx_ndlp)
+- goto out;
+-
+- link_mbox->mbox_cmpl = lpfc_defer_acc_rsp;
+-
+- if (((ndlp->nlp_DID & Fabric_DID_MASK) != Fabric_DID_MASK) &&
+- (!(vport->fc_flag & FC_OFFLINE_MODE)))
+- ndlp->nlp_flag |= NLP_UNREG_INP;
++ save_iocb = kzalloc(sizeof(*save_iocb), GFP_KERNEL);
++ if (!save_iocb)
++ goto out;
+
+- /* Save info from cmd IOCB used in rsp */
+- memcpy(save_iocb, cmdiocb, sizeof(*save_iocb));
++ /* Save info from cmd IOCB to be used in rsp after all mbox completes */
++ memcpy((uint8_t *)save_iocb, (uint8_t *)cmdiocb,
++ sizeof(struct lpfc_iocbq));
+
+- /* Delay sending ACC till unreg RPI completes. */
+- defer_acc = 1;
+- } else if (phba->sli_rev == LPFC_SLI_REV4)
++ /* Registering an existing RPI behaves differently for SLI3 vs SLI4 */
++ if (phba->sli_rev == LPFC_SLI_REV4)
+ lpfc_unreg_rpi(vport, ndlp);
+
++ /* Issue REG_LOGIN first, before ACCing the PLOGI, thus we will
++ * always be deferring the ACC.
++ */
+ rc = lpfc_reg_rpi(phba, vport->vpi, icmd->un.rcvels.remoteID,
+ (uint8_t *)sp, login_mbox, ndlp->nlp_rpi);
+ if (rc)
+ goto out;
+
+- /* ACC PLOGI rsp command needs to execute first,
+- * queue this login_mbox command to be processed later.
+- */
+ login_mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login;
+- /*
+- * login_mbox->ctx_ndlp = lpfc_nlp_get(ndlp) deferred until mailbox
+- * command issued in lpfc_cmpl_els_acc().
+- */
+ login_mbox->vport = vport;
+- spin_lock_irq(&ndlp->lock);
+- ndlp->nlp_flag |= (NLP_ACC_REGLOGIN | NLP_RCV_PLOGI);
+- spin_unlock_irq(&ndlp->lock);
+
+ /*
+ * If there is an outstanding PLOGI issued, abort it before
+@@ -660,7 +563,8 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+ * to register, then unregister the RPI.
+ */
+ spin_lock_irq(&ndlp->lock);
+- ndlp->nlp_flag |= NLP_RM_DFLT_RPI;
++ ndlp->nlp_flag |= (NLP_RM_DFLT_RPI | NLP_ACC_REGLOGIN |
++ NLP_RCV_PLOGI);
+ spin_unlock_irq(&ndlp->lock);
+ stat.un.b.lsRjtRsnCode = LSRJT_INVALID_CMD;
+ stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
+@@ -670,42 +574,39 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+ mempool_free(login_mbox, phba->mbox_mem_pool);
+ return 1;
+ }
+- if (defer_acc) {
+- /* So the order here should be:
+- * SLI3 pt2pt
+- * Issue CONFIG_LINK mbox
+- * CONFIG_LINK cmpl
+- * SLI4 tgt
+- * Issue UNREG RPI mbx
+- * UNREG RPI cmpl
+- * Issue PLOGI ACC
+- * PLOGI ACC cmpl
+- * Issue REG_LOGIN mbox
+- */
+
+- /* Save the REG_LOGIN mbox for and rcv IOCB copy later */
+- link_mbox->context3 = login_mbox;
+- login_mbox->context3 = save_iocb;
++ /* So the order here should be:
++ * SLI3 pt2pt
++ * Issue CONFIG_LINK mbox
++ * CONFIG_LINK cmpl
++ * SLI4 pt2pt
++ * Issue REG_VFI mbox
++ * REG_VFI cmpl
++ * SLI4
++ * Issue UNREG RPI mbx
++ * UNREG RPI cmpl
++ * Issue REG_RPI mbox
++ * REG RPI cmpl
++ * Issue PLOGI ACC
++ * PLOGI ACC cmpl
++ */
++ login_mbox->mbox_cmpl = lpfc_defer_plogi_acc;
++ login_mbox->ctx_ndlp = lpfc_nlp_get(ndlp);
++ login_mbox->context3 = save_iocb; /* For PLOGI ACC */
+
+- /* Start the ball rolling by issuing CONFIG_LINK here */
+- rc = lpfc_sli_issue_mbox(phba, link_mbox, MBX_NOWAIT);
+- if (rc == MBX_NOT_FINISHED)
+- goto out;
+- return 1;
+- }
++ spin_lock_irq(&ndlp->lock);
++ ndlp->nlp_flag |= (NLP_ACC_REGLOGIN | NLP_RCV_PLOGI);
++ spin_unlock_irq(&ndlp->lock);
++
++ /* Start the ball rolling by issuing REG_LOGIN here */
++ rc = lpfc_sli_issue_mbox(phba, login_mbox, MBX_NOWAIT);
++ if (rc == MBX_NOT_FINISHED)
++ goto out;
++ lpfc_nlp_set_state(vport, ndlp, NLP_STE_REG_LOGIN_ISSUE);
+
+- rc = lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, login_mbox);
+- if (rc)
+- mempool_free(login_mbox, phba->mbox_mem_pool);
+ return 1;
+ out:
+- if (defer_acc)
+- lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
+- "4577 discovery failure: %p %p %p\n",
+- save_iocb, link_mbox, login_mbox);
+ kfree(save_iocb);
+- if (link_mbox)
+- mempool_free(link_mbox, phba->mbox_mem_pool);
+ if (login_mbox)
+ mempool_free(login_mbox, phba->mbox_mem_pool);
+
+@@ -913,9 +814,14 @@ lpfc_rcv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+ }
+ } else if ((!(ndlp->nlp_type & NLP_FABRIC) &&
+ ((ndlp->nlp_type & NLP_FCP_TARGET) ||
+- !(ndlp->nlp_type & NLP_FCP_INITIATOR))) ||
++ (ndlp->nlp_type & NLP_NVME_TARGET) ||
++ (vport->fc_flag & FC_PT2PT))) ||
+ (ndlp->nlp_state == NLP_STE_ADISC_ISSUE)) {
+- /* Only try to re-login if this is NOT a Fabric Node */
++ /* Only try to re-login if this is NOT a Fabric Node
++ * AND the remote NPORT is a FCP/NVME Target or we
++ * are in pt2pt mode. NLP_STE_ADISC_ISSUE is a special
++ * case for LOGO as a response to ADISC behavior.
++ */
+ mod_timer(&ndlp->nlp_delayfunc,
+ jiffies + msecs_to_jiffies(1000 * 1));
+ spin_lock_irq(&ndlp->lock);
+@@ -1985,8 +1891,6 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_vport *vport,
+ ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;
+
+ lpfc_issue_els_logo(vport, ndlp, 0);
+- ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
+- lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
+ return ndlp->nlp_state;
+ }
+
+@@ -2633,12 +2537,10 @@ static uint32_t
+ lpfc_rcv_prlo_mapped_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+ void *arg, uint32_t evt)
+ {
+- struct lpfc_hba *phba = vport->phba;
+ struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
+
+ /* flush the target */
+- lpfc_sli_abort_iocb(vport, &phba->sli.sli3_ring[LPFC_FCP_RING],
+- ndlp->nlp_sid, 0, LPFC_CTX_TGT);
++ lpfc_sli_abort_iocb(vport, ndlp->nlp_sid, 0, LPFC_CTX_TGT);
+
+ /* Treat like rcv logo */
+ lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_PRLO);
+diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c
+index bb2a4a0d12959..a3fd959f7431c 100644
+--- a/drivers/scsi/lpfc/lpfc_nvmet.c
++++ b/drivers/scsi/lpfc/lpfc_nvmet.c
+@@ -3304,7 +3304,6 @@ lpfc_nvmet_unsol_issue_abort(struct lpfc_hba *phba,
+ bf_set(wqe_rcvoxid, &wqe_abts->xmit_sequence.wqe_com, xri);
+
+ /* Word 10 */
+- bf_set(wqe_dbde, &wqe_abts->xmit_sequence.wqe_com, 1);
+ bf_set(wqe_iod, &wqe_abts->xmit_sequence.wqe_com, LPFC_WQE_IOD_WRITE);
+ bf_set(wqe_lenloc, &wqe_abts->xmit_sequence.wqe_com,
+ LPFC_WQE_LENLOC_WORD12);
+diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
+index fa1a714a78f09..bd31feb3d5e18 100644
+--- a/drivers/scsi/lpfc/lpfc_sli.c
++++ b/drivers/scsi/lpfc/lpfc_sli.c
+@@ -5683,12 +5683,10 @@ lpfc_sli4_get_ctl_attr(struct lpfc_hba *phba)
+ phba->sli4_hba.lnk_info.lnk_no,
+ phba->BIOSVersion);
+ out_free_mboxq:
+- if (rc != MBX_TIMEOUT) {
+- if (bf_get(lpfc_mqe_command, &mboxq->u.mqe) == MBX_SLI4_CONFIG)
+- lpfc_sli4_mbox_cmd_free(phba, mboxq);
+- else
+- mempool_free(mboxq, phba->mbox_mem_pool);
+- }
++ if (bf_get(lpfc_mqe_command, &mboxq->u.mqe) == MBX_SLI4_CONFIG)
++ lpfc_sli4_mbox_cmd_free(phba, mboxq);
++ else
++ mempool_free(mboxq, phba->mbox_mem_pool);
+ return rc;
+ }
+
+@@ -5789,12 +5787,10 @@ retrieve_ppname:
+ }
+
+ out_free_mboxq:
+- if (rc != MBX_TIMEOUT) {
+- if (bf_get(lpfc_mqe_command, &mboxq->u.mqe) == MBX_SLI4_CONFIG)
+- lpfc_sli4_mbox_cmd_free(phba, mboxq);
+- else
+- mempool_free(mboxq, phba->mbox_mem_pool);
+- }
++ if (bf_get(lpfc_mqe_command, &mboxq->u.mqe) == MBX_SLI4_CONFIG)
++ lpfc_sli4_mbox_cmd_free(phba, mboxq);
++ else
++ mempool_free(mboxq, phba->mbox_mem_pool);
+ return rc;
+ }
+
+@@ -11647,7 +11643,7 @@ lpfc_sli_issue_abort_iotag(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
+ icmd = &cmdiocb->iocb;
+ if (icmd->ulpCommand == CMD_ABORT_XRI_CN ||
+ icmd->ulpCommand == CMD_CLOSE_XRI_CN ||
+- (cmdiocb->iocb_flag & LPFC_DRIVER_ABORTED) != 0)
++ cmdiocb->iocb_flag & LPFC_DRIVER_ABORTED)
+ return IOCB_ABORTING;
+
+ if (!pring) {
+@@ -11945,7 +11941,6 @@ lpfc_sli_abort_fcp_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+ /**
+ * lpfc_sli_abort_iocb - issue abort for all commands on a host/target/LUN
+ * @vport: Pointer to virtual port.
+- * @pring: Pointer to driver SLI ring object.
+ * @tgt_id: SCSI ID of the target.
+ * @lun_id: LUN ID of the scsi device.
+ * @abort_cmd: LPFC_CTX_LUN/LPFC_CTX_TGT/LPFC_CTX_HOST.
+@@ -11960,18 +11955,22 @@ lpfc_sli_abort_fcp_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+ * FCP iocbs associated with SCSI target specified by tgt_id parameter.
+ * When abort_cmd == LPFC_CTX_HOST, the function sends abort to all
+ * FCP iocbs associated with virtual port.
++ * The pring used for SLI3 is sli3_ring[LPFC_FCP_RING], for SLI4
++ * lpfc_sli4_calc_ring is used.
+ * This function returns number of iocbs it failed to abort.
+ * This function is called with no locks held.
+ **/
+ int
+-lpfc_sli_abort_iocb(struct lpfc_vport *vport, struct lpfc_sli_ring *pring,
+- uint16_t tgt_id, uint64_t lun_id, lpfc_ctx_cmd abort_cmd)
++lpfc_sli_abort_iocb(struct lpfc_vport *vport, u16 tgt_id, u64 lun_id,
++ lpfc_ctx_cmd abort_cmd)
+ {
+ struct lpfc_hba *phba = vport->phba;
++ struct lpfc_sli_ring *pring = NULL;
+ struct lpfc_iocbq *iocbq;
+ int errcnt = 0, ret_val = 0;
+ unsigned long iflags;
+ int i;
++ void *fcp_cmpl = NULL;
+
+ /* all I/Os are in process of being flushed */
+ if (phba->hba_flag & HBA_IOQ_FLUSH)
+@@ -11985,8 +11984,15 @@ lpfc_sli_abort_iocb(struct lpfc_vport *vport, struct lpfc_sli_ring *pring,
+ continue;
+
+ spin_lock_irqsave(&phba->hbalock, iflags);
++ if (phba->sli_rev == LPFC_SLI_REV3) {
++ pring = &phba->sli.sli3_ring[LPFC_FCP_RING];
++ fcp_cmpl = lpfc_sli_abort_fcp_cmpl;
++ } else if (phba->sli_rev == LPFC_SLI_REV4) {
++ pring = lpfc_sli4_calc_ring(phba, iocbq);
++ fcp_cmpl = lpfc_sli4_abort_fcp_cmpl;
++ }
+ ret_val = lpfc_sli_issue_abort_iotag(phba, pring, iocbq,
+- lpfc_sli_abort_fcp_cmpl);
++ fcp_cmpl);
+ spin_unlock_irqrestore(&phba->hbalock, iflags);
+ if (ret_val != IOCB_SUCCESS)
+ errcnt++;
+@@ -17072,8 +17078,7 @@ lpfc_rq_destroy(struct lpfc_hba *phba, struct lpfc_queue *hrq,
+ "2509 RQ_DESTROY mailbox failed with "
+ "status x%x add_status x%x, mbx status x%x\n",
+ shdr_status, shdr_add_status, rc);
+- if (rc != MBX_TIMEOUT)
+- mempool_free(mbox, hrq->phba->mbox_mem_pool);
++ mempool_free(mbox, hrq->phba->mbox_mem_pool);
+ return -ENXIO;
+ }
+ bf_set(lpfc_mbx_rq_destroy_q_id, &mbox->u.mqe.un.rq_destroy.u.request,
+@@ -17170,7 +17175,9 @@ lpfc_sli4_post_sgl(struct lpfc_hba *phba,
+ shdr = (union lpfc_sli4_cfg_shdr *) &post_sgl_pages->header.cfg_shdr;
+ shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
+ shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response);
+- if (rc != MBX_TIMEOUT)
++ if (!phba->sli4_hba.intr_enable)
++ mempool_free(mbox, phba->mbox_mem_pool);
++ else if (rc != MBX_TIMEOUT)
+ mempool_free(mbox, phba->mbox_mem_pool);
+ if (shdr_status || shdr_add_status || rc) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
+@@ -17367,7 +17374,9 @@ lpfc_sli4_post_sgl_list(struct lpfc_hba *phba,
+ shdr = (union lpfc_sli4_cfg_shdr *) &sgl->cfg_shdr;
+ shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
+ shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response);
+- if (rc != MBX_TIMEOUT)
++ if (!phba->sli4_hba.intr_enable)
++ lpfc_sli4_mbox_cmd_free(phba, mbox);
++ else if (rc != MBX_TIMEOUT)
+ lpfc_sli4_mbox_cmd_free(phba, mbox);
+ if (shdr_status || shdr_add_status || rc) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
+@@ -17480,7 +17489,9 @@ lpfc_sli4_post_io_sgl_block(struct lpfc_hba *phba, struct list_head *nblist,
+ shdr = (union lpfc_sli4_cfg_shdr *)&sgl->cfg_shdr;
+ shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
+ shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response);
+- if (rc != MBX_TIMEOUT)
++ if (!phba->sli4_hba.intr_enable)
++ lpfc_sli4_mbox_cmd_free(phba, mbox);
++ else if (rc != MBX_TIMEOUT)
+ lpfc_sli4_mbox_cmd_free(phba, mbox);
+ if (shdr_status || shdr_add_status || rc) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
+@@ -18064,7 +18075,6 @@ lpfc_sli4_seq_abort_rsp_cmpl(struct lpfc_hba *phba,
+ if (cmd_iocbq) {
+ ndlp = (struct lpfc_nodelist *)cmd_iocbq->context1;
+ lpfc_nlp_put(ndlp);
+- lpfc_nlp_not_used(ndlp);
+ lpfc_sli_release_iocbq(phba, cmd_iocbq);
+ }
+
+@@ -18831,8 +18841,7 @@ lpfc_sli4_post_rpi_hdr(struct lpfc_hba *phba, struct lpfc_rpi_hdr *rpi_page)
+ shdr = (union lpfc_sli4_cfg_shdr *) &hdr_tmpl->header.cfg_shdr;
+ shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
+ shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response);
+- if (rc != MBX_TIMEOUT)
+- mempool_free(mboxq, phba->mbox_mem_pool);
++ mempool_free(mboxq, phba->mbox_mem_pool);
+ if (shdr_status || shdr_add_status || rc) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
+ "2514 POST_RPI_HDR mailbox failed with "
+@@ -20076,7 +20085,9 @@ lpfc_wr_object(struct lpfc_hba *phba, struct list_head *dmabuf_list,
+ break;
+ }
+ }
+- if (rc != MBX_TIMEOUT)
++ if (!phba->sli4_hba.intr_enable)
++ mempool_free(mbox, phba->mbox_mem_pool);
++ else if (rc != MBX_TIMEOUT)
+ mempool_free(mbox, phba->mbox_mem_pool);
+ if (shdr_status || shdr_add_status || rc) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
+diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c
+index ac0eef975f179..b6beacfd0f628 100644
+--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
++++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
+@@ -7252,6 +7252,8 @@ _base_diag_reset(struct MPT3SAS_ADAPTER *ioc)
+
+ ioc_info(ioc, "sending diag reset !!\n");
+
++ pci_cfg_access_lock(ioc->pdev);
++
+ drsprintk(ioc, ioc_info(ioc, "clear interrupts\n"));
+
+ count = 0;
+@@ -7342,10 +7344,12 @@ _base_diag_reset(struct MPT3SAS_ADAPTER *ioc)
+ goto out;
+ }
+
++ pci_cfg_access_unlock(ioc->pdev);
+ ioc_info(ioc, "diag reset: SUCCESS\n");
+ return 0;
+
+ out:
++ pci_cfg_access_unlock(ioc->pdev);
+ ioc_err(ioc, "diag reset: FAILED\n");
+ return -EFAULT;
+ }
+diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
+index 44f9a05db94e1..2ec11be62a827 100644
+--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c
++++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
+@@ -2507,7 +2507,7 @@ _ctl_addnl_diag_query(struct MPT3SAS_ADAPTER *ioc, void __user *arg)
+ __func__, karg.unique_id);
+ return -EPERM;
+ }
+- memset(&karg.buffer_rel_condition, 0, sizeof(struct htb_rel_query));
++ memset(&karg.rel_query, 0, sizeof(karg.rel_query));
+ if ((ioc->diag_buffer_status[buffer_type] &
+ MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) {
+ ioc_info(ioc, "%s: buffer_type(0x%02x) is not registered\n",
+@@ -2520,8 +2520,7 @@ _ctl_addnl_diag_query(struct MPT3SAS_ADAPTER *ioc, void __user *arg)
+ __func__, buffer_type);
+ return -EPERM;
+ }
+- memcpy(&karg.buffer_rel_condition, &ioc->htb_rel,
+- sizeof(struct htb_rel_query));
++ memcpy(&karg.rel_query, &ioc->htb_rel, sizeof(karg.rel_query));
+ out:
+ if (copy_to_user(arg, &karg, sizeof(struct mpt3_addnl_diag_query))) {
+ ioc_err(ioc, "%s: unable to write mpt3_addnl_diag_query data @ %p\n",
+diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.h b/drivers/scsi/mpt3sas/mpt3sas_ctl.h
+index d2ccdafb8df2a..8f6ffb40261c9 100644
+--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.h
++++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.h
+@@ -50,6 +50,8 @@
+ #include <linux/miscdevice.h>
+ #endif
+
++#include "mpt3sas_base.h"
++
+ #ifndef MPT2SAS_MINOR
+ #define MPT2SAS_MINOR (MPT_MINOR + 1)
+ #endif
+@@ -436,19 +438,13 @@ struct mpt3_diag_read_buffer {
+ * struct mpt3_addnl_diag_query - diagnostic buffer release reason
+ * @hdr - generic header
+ * @unique_id - unique id associated with this buffer.
+- * @buffer_rel_condition - Release condition ioctl/sysfs/reset
+- * @reserved1
+- * @trigger_type - Master/Event/scsi/MPI
+- * @trigger_info_dwords - Data Correspondig to trigger type
++ * @rel_query - release query.
+ * @reserved2
+ */
+ struct mpt3_addnl_diag_query {
+ struct mpt3_ioctl_header hdr;
+ uint32_t unique_id;
+- uint16_t buffer_rel_condition;
+- uint16_t reserved1;
+- uint32_t trigger_type;
+- uint32_t trigger_info_dwords[2];
++ struct htb_rel_query rel_query;
+ uint32_t reserved2[2];
+ };
+
+diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+index 6aa6de7291876..ae1973878cc7d 100644
+--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
++++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+@@ -6483,6 +6483,9 @@ _scsih_alloc_vphy(struct MPT3SAS_ADAPTER *ioc, u8 port_id, u8 phy_num)
+ if (!vphy)
+ return NULL;
+
++ if (!port->vphys_mask)
++ INIT_LIST_HEAD(&port->vphys_list);
++
+ /*
+ * Enable bit corresponding to HBA phy number on its
+ * parent hba_port object's vphys_mask field.
+@@ -6490,7 +6493,6 @@ _scsih_alloc_vphy(struct MPT3SAS_ADAPTER *ioc, u8 port_id, u8 phy_num)
+ port->vphys_mask |= (1 << phy_num);
+ vphy->phy_mask |= (1 << phy_num);
+
+- INIT_LIST_HEAD(&port->vphys_list);
+ list_add_tail(&vphy->list, &port->vphys_list);
+
+ ioc_info(ioc,
+diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
+index 63391c9be05dd..3aa9869f6fae2 100644
+--- a/drivers/scsi/qla2xxx/qla_attr.c
++++ b/drivers/scsi/qla2xxx/qla_attr.c
+@@ -2864,6 +2864,8 @@ qla2x00_reset_host_stats(struct Scsi_Host *shost)
+ vha->qla_stats.jiffies_at_last_reset = get_jiffies_64();
+
+ if (IS_FWI2_CAPABLE(ha)) {
++ int rval;
++
+ stats = dma_alloc_coherent(&ha->pdev->dev,
+ sizeof(*stats), &stats_dma, GFP_KERNEL);
+ if (!stats) {
+@@ -2873,7 +2875,11 @@ qla2x00_reset_host_stats(struct Scsi_Host *shost)
+ }
+
+ /* reset firmware statistics */
+- qla24xx_get_isp_stats(base_vha, stats, stats_dma, BIT_0);
++ rval = qla24xx_get_isp_stats(base_vha, stats, stats_dma, BIT_0);
++ if (rval != QLA_SUCCESS)
++ ql_log(ql_log_warn, vha, 0x70de,
++ "Resetting ISP statistics failed: rval = %d\n",
++ rval);
+
+ dma_free_coherent(&ha->pdev->dev, sizeof(*stats),
+ stats, stats_dma);
+diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
+index bee8cf9f8123c..d021e51344f57 100644
+--- a/drivers/scsi/qla2xxx/qla_bsg.c
++++ b/drivers/scsi/qla2xxx/qla_bsg.c
+@@ -25,10 +25,11 @@ void qla2x00_bsg_job_done(srb_t *sp, int res)
+ struct bsg_job *bsg_job = sp->u.bsg_job;
+ struct fc_bsg_reply *bsg_reply = bsg_job->reply;
+
++ sp->free(sp);
++
+ bsg_reply->result = res;
+ bsg_job_done(bsg_job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
+- sp->free(sp);
+ }
+
+ void qla2x00_bsg_sp_free(srb_t *sp)
+diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
+index 5e188375c8713..af4831c9edf9a 100644
+--- a/drivers/scsi/qla2xxx/qla_isr.c
++++ b/drivers/scsi/qla2xxx/qla_isr.c
+@@ -4005,11 +4005,11 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp)
+ if (USER_CTRL_IRQ(ha) || !ha->mqiobase) {
+ /* user wants to control IRQ setting for target mode */
+ ret = pci_alloc_irq_vectors(ha->pdev, min_vecs,
+- min((u16)ha->msix_count, (u16)num_online_cpus()),
++ min((u16)ha->msix_count, (u16)(num_online_cpus() + min_vecs)),
+ PCI_IRQ_MSIX);
+ } else
+ ret = pci_alloc_irq_vectors_affinity(ha->pdev, min_vecs,
+- min((u16)ha->msix_count, (u16)num_online_cpus()),
++ min((u16)ha->msix_count, (u16)(num_online_cpus() + min_vecs)),
+ PCI_IRQ_MSIX | PCI_IRQ_AFFINITY,
+ &desc);
+
+diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
+index 074392560f3d1..0e07b98dfae8e 100644
+--- a/drivers/scsi/qla2xxx/qla_os.c
++++ b/drivers/scsi/qla2xxx/qla_os.c
+@@ -1013,8 +1013,6 @@ qla2xxx_mqueuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd,
+ if (rval != QLA_SUCCESS) {
+ ql_dbg(ql_dbg_io + ql_dbg_verbose, vha, 0x3078,
+ "Start scsi failed rval=%d for cmd=%p.\n", rval, cmd);
+- if (rval == QLA_INTERFACE_ERROR)
+- goto qc24_free_sp_fail_command;
+ goto qc24_host_busy_free_sp;
+ }
+
+@@ -1026,11 +1024,6 @@ qc24_host_busy_free_sp:
+ qc24_target_busy:
+ return SCSI_MLQUEUE_TARGET_BUSY;
+
+-qc24_free_sp_fail_command:
+- sp->free(sp);
+- CMD_SP(cmd) = NULL;
+- qla2xxx_rel_qpair_sp(sp->qpair, sp);
+-
+ qc24_fail_command:
+ cmd->scsi_done(cmd);
+
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index a1dacb6e993e7..c30f6047410fc 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -5488,6 +5488,8 @@ static void pqi_fail_io_queued_for_device(struct pqi_ctrl_info *ctrl_info,
+
+ list_del(&io_request->request_list_entry);
+ set_host_byte(scmd, DID_RESET);
++ pqi_free_io_request(io_request);
++ scsi_dma_unmap(scmd);
+ pqi_scsi_done(scmd);
+ }
+
+@@ -5524,6 +5526,8 @@ static void pqi_fail_io_queued_for_all_devices(struct pqi_ctrl_info *ctrl_info)
+
+ list_del(&io_request->request_list_entry);
+ set_host_byte(scmd, DID_RESET);
++ pqi_free_io_request(io_request);
++ scsi_dma_unmap(scmd);
+ pqi_scsi_done(scmd);
+ }
+
+@@ -6598,6 +6602,7 @@ static int pqi_register_scsi(struct pqi_ctrl_info *ctrl_info)
+ shost->irq = pci_irq_vector(ctrl_info->pci_dev, 0);
+ shost->unique_id = shost->irq;
+ shost->nr_hw_queues = ctrl_info->num_queue_groups;
++ shost->host_tagset = 1;
+ shost->hostdata[0] = (unsigned long)ctrl_info;
+
+ rc = scsi_add_host(shost, &ctrl_info->pci_dev->dev);
+@@ -8216,6 +8221,10 @@ static const struct pci_device_id pqi_pci_id_table[] = {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 0x152d, 0x8a37)
+ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ 0x193d, 0x8460)
++ },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 0x193d, 0x1104)
+@@ -8288,6 +8297,22 @@ static const struct pci_device_id pqi_pci_id_table[] = {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 0x1bd4, 0x004f)
+ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ 0x1bd4, 0x0051)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ 0x1bd4, 0x0052)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ 0x1bd4, 0x0053)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ 0x1bd4, 0x0054)
++ },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 0x19e5, 0xd227)
+@@ -8448,6 +8473,122 @@ static const struct pci_device_id pqi_pci_id_table[] = {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ PCI_VENDOR_ID_ADAPTEC2, 0x1380)
+ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ PCI_VENDOR_ID_ADAPTEC2, 0x1400)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ PCI_VENDOR_ID_ADAPTEC2, 0x1402)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ PCI_VENDOR_ID_ADAPTEC2, 0x1410)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ PCI_VENDOR_ID_ADAPTEC2, 0x1411)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ PCI_VENDOR_ID_ADAPTEC2, 0x1412)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ PCI_VENDOR_ID_ADAPTEC2, 0x1420)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ PCI_VENDOR_ID_ADAPTEC2, 0x1430)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ PCI_VENDOR_ID_ADAPTEC2, 0x1440)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ PCI_VENDOR_ID_ADAPTEC2, 0x1441)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ PCI_VENDOR_ID_ADAPTEC2, 0x1450)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ PCI_VENDOR_ID_ADAPTEC2, 0x1452)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ PCI_VENDOR_ID_ADAPTEC2, 0x1460)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ PCI_VENDOR_ID_ADAPTEC2, 0x1461)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ PCI_VENDOR_ID_ADAPTEC2, 0x1462)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ PCI_VENDOR_ID_ADAPTEC2, 0x1470)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ PCI_VENDOR_ID_ADAPTEC2, 0x1471)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ PCI_VENDOR_ID_ADAPTEC2, 0x1472)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ PCI_VENDOR_ID_ADAPTEC2, 0x1480)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ PCI_VENDOR_ID_ADAPTEC2, 0x1490)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ PCI_VENDOR_ID_ADAPTEC2, 0x1491)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ PCI_VENDOR_ID_ADAPTEC2, 0x14a0)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ PCI_VENDOR_ID_ADAPTEC2, 0x14a1)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ PCI_VENDOR_ID_ADAPTEC2, 0x14b0)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ PCI_VENDOR_ID_ADAPTEC2, 0x14b1)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ PCI_VENDOR_ID_ADAPTEC2, 0x14c0)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ PCI_VENDOR_ID_ADAPTEC2, 0x14c1)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ PCI_VENDOR_ID_ADAPTEC2, 0x14d0)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ PCI_VENDOR_ID_ADAPTEC2, 0x14e0)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ PCI_VENDOR_ID_ADAPTEC2, 0x14f0)
++ },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ PCI_VENDOR_ID_ADVANTECH, 0x8312)
+@@ -8512,6 +8653,10 @@ static const struct pci_device_id pqi_pci_id_table[] = {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ PCI_VENDOR_ID_HP, 0x1001)
+ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ PCI_VENDOR_ID_HP, 0x1002)
++ },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ PCI_VENDOR_ID_HP, 0x1100)
+@@ -8520,6 +8665,22 @@ static const struct pci_device_id pqi_pci_id_table[] = {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ PCI_VENDOR_ID_HP, 0x1101)
+ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ 0x1590, 0x0294)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ 0x1590, 0x02db)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ 0x1590, 0x02dc)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ 0x1590, 0x032e)
++ },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 0x1d8d, 0x0800)
+diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
+index df9a5ca8c99c4..0118bd986f902 100644
+--- a/drivers/soc/tegra/pmc.c
++++ b/drivers/soc/tegra/pmc.c
+@@ -317,6 +317,8 @@ struct tegra_pmc_soc {
+ bool invert);
+ int (*irq_set_wake)(struct irq_data *data, unsigned int on);
+ int (*irq_set_type)(struct irq_data *data, unsigned int type);
++ int (*powergate_set)(struct tegra_pmc *pmc, unsigned int id,
++ bool new_state);
+
+ const char * const *reset_sources;
+ unsigned int num_reset_sources;
+@@ -517,6 +519,63 @@ static int tegra_powergate_lookup(struct tegra_pmc *pmc, const char *name)
+ return -ENODEV;
+ }
+
++static int tegra20_powergate_set(struct tegra_pmc *pmc, unsigned int id,
++ bool new_state)
++{
++ unsigned int retries = 100;
++ bool status;
++ int ret;
++
++ /*
++ * As per TRM documentation, the toggle command will be dropped by PMC
++ * if there is contention with a HW-initiated toggling (i.e. CPU core
++ * power-gated), the command should be retried in that case.
++ */
++ do {
++ tegra_pmc_writel(pmc, PWRGATE_TOGGLE_START | id, PWRGATE_TOGGLE);
++
++ /* wait for PMC to execute the command */
++ ret = readx_poll_timeout(tegra_powergate_state, id, status,
++ status == new_state, 1, 10);
++ } while (ret == -ETIMEDOUT && retries--);
++
++ return ret;
++}
++
++static inline bool tegra_powergate_toggle_ready(struct tegra_pmc *pmc)
++{
++ return !(tegra_pmc_readl(pmc, PWRGATE_TOGGLE) & PWRGATE_TOGGLE_START);
++}
++
++static int tegra114_powergate_set(struct tegra_pmc *pmc, unsigned int id,
++ bool new_state)
++{
++ bool status;
++ int err;
++
++ /* wait while PMC power gating is contended */
++ err = readx_poll_timeout(tegra_powergate_toggle_ready, pmc, status,
++ status == true, 1, 100);
++ if (err)
++ return err;
++
++ tegra_pmc_writel(pmc, PWRGATE_TOGGLE_START | id, PWRGATE_TOGGLE);
++
++ /* wait for PMC to accept the command */
++ err = readx_poll_timeout(tegra_powergate_toggle_ready, pmc, status,
++ status == true, 1, 100);
++ if (err)
++ return err;
++
++ /* wait for PMC to execute the command */
++ err = readx_poll_timeout(tegra_powergate_state, id, status,
++ status == new_state, 10, 100000);
++ if (err)
++ return err;
++
++ return 0;
++}
++
+ /**
+ * tegra_powergate_set() - set the state of a partition
+ * @pmc: power management controller
+@@ -526,7 +585,6 @@ static int tegra_powergate_lookup(struct tegra_pmc *pmc, const char *name)
+ static int tegra_powergate_set(struct tegra_pmc *pmc, unsigned int id,
+ bool new_state)
+ {
+- bool status;
+ int err;
+
+ if (id == TEGRA_POWERGATE_3D && pmc->soc->has_gpu_clamps)
+@@ -539,10 +597,7 @@ static int tegra_powergate_set(struct tegra_pmc *pmc, unsigned int id,
+ return 0;
+ }
+
+- tegra_pmc_writel(pmc, PWRGATE_TOGGLE_START | id, PWRGATE_TOGGLE);
+-
+- err = readx_poll_timeout(tegra_powergate_state, id, status,
+- status == new_state, 10, 100000);
++ err = pmc->soc->powergate_set(pmc, id, new_state);
+
+ mutex_unlock(&pmc->powergates_lock);
+
+@@ -2699,6 +2754,7 @@ static const struct tegra_pmc_soc tegra20_pmc_soc = {
+ .regs = &tegra20_pmc_regs,
+ .init = tegra20_pmc_init,
+ .setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
++ .powergate_set = tegra20_powergate_set,
+ .reset_sources = NULL,
+ .num_reset_sources = 0,
+ .reset_levels = NULL,
+@@ -2757,6 +2813,7 @@ static const struct tegra_pmc_soc tegra30_pmc_soc = {
+ .regs = &tegra20_pmc_regs,
+ .init = tegra20_pmc_init,
+ .setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
++ .powergate_set = tegra20_powergate_set,
+ .reset_sources = tegra30_reset_sources,
+ .num_reset_sources = ARRAY_SIZE(tegra30_reset_sources),
+ .reset_levels = NULL,
+@@ -2811,6 +2868,7 @@ static const struct tegra_pmc_soc tegra114_pmc_soc = {
+ .regs = &tegra20_pmc_regs,
+ .init = tegra20_pmc_init,
+ .setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
++ .powergate_set = tegra114_powergate_set,
+ .reset_sources = tegra30_reset_sources,
+ .num_reset_sources = ARRAY_SIZE(tegra30_reset_sources),
+ .reset_levels = NULL,
+@@ -2925,6 +2983,7 @@ static const struct tegra_pmc_soc tegra124_pmc_soc = {
+ .regs = &tegra20_pmc_regs,
+ .init = tegra20_pmc_init,
+ .setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
++ .powergate_set = tegra114_powergate_set,
+ .reset_sources = tegra30_reset_sources,
+ .num_reset_sources = ARRAY_SIZE(tegra30_reset_sources),
+ .reset_levels = NULL,
+@@ -3048,6 +3107,7 @@ static const struct tegra_pmc_soc tegra210_pmc_soc = {
+ .regs = &tegra20_pmc_regs,
+ .init = tegra20_pmc_init,
+ .setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
++ .powergate_set = tegra114_powergate_set,
+ .irq_set_wake = tegra210_pmc_irq_set_wake,
+ .irq_set_type = tegra210_pmc_irq_set_type,
+ .reset_sources = tegra210_reset_sources,
+diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
+index d05442e646a38..57c59a33ce616 100644
+--- a/drivers/soundwire/cadence_master.c
++++ b/drivers/soundwire/cadence_master.c
+@@ -1450,10 +1450,12 @@ int sdw_cdns_clock_stop(struct sdw_cdns *cdns, bool block_wake)
+ }
+
+ /* Prepare slaves for clock stop */
+- ret = sdw_bus_prep_clk_stop(&cdns->bus);
+- if (ret < 0) {
+- dev_err(cdns->dev, "prepare clock stop failed %d", ret);
+- return ret;
++ if (slave_present) {
++ ret = sdw_bus_prep_clk_stop(&cdns->bus);
++ if (ret < 0 && ret != -ENODATA) {
++ dev_err(cdns->dev, "prepare clock stop failed %d\n", ret);
++ return ret;
++ }
+ }
+
+ /*
+diff --git a/drivers/spi/spi-ath79.c b/drivers/spi/spi-ath79.c
+index eb9a243e95265..98ace748cd986 100644
+--- a/drivers/spi/spi-ath79.c
++++ b/drivers/spi/spi-ath79.c
+@@ -156,8 +156,7 @@ static int ath79_spi_probe(struct platform_device *pdev)
+
+ master->use_gpio_descriptors = true;
+ master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
+- master->setup = spi_bitbang_setup;
+- master->cleanup = spi_bitbang_cleanup;
++ master->flags = SPI_MASTER_GPIO_SS;
+ if (pdata) {
+ master->bus_num = pdata->bus_num;
+ master->num_chipselect = pdata->num_chipselect;
+diff --git a/drivers/spi/spi-dln2.c b/drivers/spi/spi-dln2.c
+index 75b33d7d14b04..9a4d942fafcf5 100644
+--- a/drivers/spi/spi-dln2.c
++++ b/drivers/spi/spi-dln2.c
+@@ -780,7 +780,7 @@ exit_free_master:
+
+ static int dln2_spi_remove(struct platform_device *pdev)
+ {
+- struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
++ struct spi_master *master = platform_get_drvdata(pdev);
+ struct dln2_spi *dln2 = spi_master_get_devdata(master);
+
+ pm_runtime_disable(&pdev->dev);
+diff --git a/drivers/spi/spi-omap-100k.c b/drivers/spi/spi-omap-100k.c
+index 36a4922a134a1..ccd817ee4917b 100644
+--- a/drivers/spi/spi-omap-100k.c
++++ b/drivers/spi/spi-omap-100k.c
+@@ -424,7 +424,7 @@ err:
+
+ static int omap1_spi100k_remove(struct platform_device *pdev)
+ {
+- struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
++ struct spi_master *master = platform_get_drvdata(pdev);
+ struct omap1_spi100k *spi100k = spi_master_get_devdata(master);
+
+ pm_runtime_disable(&pdev->dev);
+@@ -438,7 +438,7 @@ static int omap1_spi100k_remove(struct platform_device *pdev)
+ #ifdef CONFIG_PM
+ static int omap1_spi100k_runtime_suspend(struct device *dev)
+ {
+- struct spi_master *master = spi_master_get(dev_get_drvdata(dev));
++ struct spi_master *master = dev_get_drvdata(dev);
+ struct omap1_spi100k *spi100k = spi_master_get_devdata(master);
+
+ clk_disable_unprepare(spi100k->ick);
+@@ -449,7 +449,7 @@ static int omap1_spi100k_runtime_suspend(struct device *dev)
+
+ static int omap1_spi100k_runtime_resume(struct device *dev)
+ {
+- struct spi_master *master = spi_master_get(dev_get_drvdata(dev));
++ struct spi_master *master = dev_get_drvdata(dev);
+ struct omap1_spi100k *spi100k = spi_master_get_devdata(master);
+ int ret;
+
+diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c
+index 8dcb2e70735c9..d39dec6d1c91e 100644
+--- a/drivers/spi/spi-qup.c
++++ b/drivers/spi/spi-qup.c
+@@ -1263,7 +1263,7 @@ static int spi_qup_remove(struct platform_device *pdev)
+ struct spi_qup *controller = spi_master_get_devdata(master);
+ int ret;
+
+- ret = pm_runtime_get_sync(&pdev->dev);
++ ret = pm_runtime_resume_and_get(&pdev->dev);
+ if (ret < 0)
+ return ret;
+
+diff --git a/drivers/spi/spi-stm32-qspi.c b/drivers/spi/spi-stm32-qspi.c
+index 947e6b9dc9f4d..2786470a52011 100644
+--- a/drivers/spi/spi-stm32-qspi.c
++++ b/drivers/spi/spi-stm32-qspi.c
+@@ -727,21 +727,31 @@ static int __maybe_unused stm32_qspi_suspend(struct device *dev)
+ {
+ pinctrl_pm_select_sleep_state(dev);
+
+- return 0;
++ return pm_runtime_force_suspend(dev);
+ }
+
+ static int __maybe_unused stm32_qspi_resume(struct device *dev)
+ {
+ struct stm32_qspi *qspi = dev_get_drvdata(dev);
++ int ret;
++
++ ret = pm_runtime_force_resume(dev);
++ if (ret < 0)
++ return ret;
+
+ pinctrl_pm_select_default_state(dev);
+- clk_prepare_enable(qspi->clk);
++
++ ret = pm_runtime_get_sync(dev);
++ if (ret < 0) {
++ pm_runtime_put_noidle(dev);
++ return ret;
++ }
+
+ writel_relaxed(qspi->cr_reg, qspi->io_base + QSPI_CR);
+ writel_relaxed(qspi->dcr_reg, qspi->io_base + QSPI_DCR);
+
+- pm_runtime_mark_last_busy(qspi->dev);
+- pm_runtime_put_autosuspend(qspi->dev);
++ pm_runtime_mark_last_busy(dev);
++ pm_runtime_put_autosuspend(dev);
+
+ return 0;
+ }
+diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c
+index 9417385c09217..e06aafe169e0c 100644
+--- a/drivers/spi/spi-ti-qspi.c
++++ b/drivers/spi/spi-ti-qspi.c
+@@ -733,6 +733,17 @@ static int ti_qspi_runtime_resume(struct device *dev)
+ return 0;
+ }
+
++static void ti_qspi_dma_cleanup(struct ti_qspi *qspi)
++{
++ if (qspi->rx_bb_addr)
++ dma_free_coherent(qspi->dev, QSPI_DMA_BUFFER_SIZE,
++ qspi->rx_bb_addr,
++ qspi->rx_bb_dma_addr);
++
++ if (qspi->rx_chan)
++ dma_release_channel(qspi->rx_chan);
++}
++
+ static const struct of_device_id ti_qspi_match[] = {
+ {.compatible = "ti,dra7xxx-qspi" },
+ {.compatible = "ti,am4372-qspi" },
+@@ -886,6 +897,8 @@ no_dma:
+ if (!ret)
+ return 0;
+
++ ti_qspi_dma_cleanup(qspi);
++
+ pm_runtime_disable(&pdev->dev);
+ free_master:
+ spi_master_put(master);
+@@ -904,12 +917,7 @@ static int ti_qspi_remove(struct platform_device *pdev)
+ pm_runtime_put_sync(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+
+- if (qspi->rx_bb_addr)
+- dma_free_coherent(qspi->dev, QSPI_DMA_BUFFER_SIZE,
+- qspi->rx_bb_addr,
+- qspi->rx_bb_dma_addr);
+- if (qspi->rx_chan)
+- dma_release_channel(qspi->rx_chan);
++ ti_qspi_dma_cleanup(qspi);
+
+ return 0;
+ }
+diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
+index b08efe88ccd6c..927c2a28011f6 100644
+--- a/drivers/spi/spi.c
++++ b/drivers/spi/spi.c
+@@ -795,7 +795,7 @@ int spi_register_board_info(struct spi_board_info const *info, unsigned n)
+
+ /*-------------------------------------------------------------------------*/
+
+-static void spi_set_cs(struct spi_device *spi, bool enable)
++static void spi_set_cs(struct spi_device *spi, bool enable, bool force)
+ {
+ bool enable1 = enable;
+
+@@ -803,7 +803,7 @@ static void spi_set_cs(struct spi_device *spi, bool enable)
+ * Avoid calling into the driver (or doing delays) if the chip select
+ * isn't actually changing from the last time this was called.
+ */
+- if ((spi->controller->last_cs_enable == enable) &&
++ if (!force && (spi->controller->last_cs_enable == enable) &&
+ (spi->controller->last_cs_mode_high == (spi->mode & SPI_CS_HIGH)))
+ return;
+
+@@ -1253,7 +1253,7 @@ static int spi_transfer_one_message(struct spi_controller *ctlr,
+ struct spi_statistics *statm = &ctlr->statistics;
+ struct spi_statistics *stats = &msg->spi->statistics;
+
+- spi_set_cs(msg->spi, true);
++ spi_set_cs(msg->spi, true, false);
+
+ SPI_STATISTICS_INCREMENT_FIELD(statm, messages);
+ SPI_STATISTICS_INCREMENT_FIELD(stats, messages);
+@@ -1321,9 +1321,9 @@ fallback_pio:
+ &msg->transfers)) {
+ keep_cs = true;
+ } else {
+- spi_set_cs(msg->spi, false);
++ spi_set_cs(msg->spi, false, false);
+ _spi_transfer_cs_change_delay(msg, xfer);
+- spi_set_cs(msg->spi, true);
++ spi_set_cs(msg->spi, true, false);
+ }
+ }
+
+@@ -1332,7 +1332,7 @@ fallback_pio:
+
+ out:
+ if (ret != 0 || !keep_cs)
+- spi_set_cs(msg->spi, false);
++ spi_set_cs(msg->spi, false, false);
+
+ if (msg->status == -EINPROGRESS)
+ msg->status = ret;
+@@ -3423,11 +3423,11 @@ int spi_setup(struct spi_device *spi)
+ */
+ status = 0;
+
+- spi_set_cs(spi, false);
++ spi_set_cs(spi, false, true);
+ pm_runtime_mark_last_busy(spi->controller->dev.parent);
+ pm_runtime_put_autosuspend(spi->controller->dev.parent);
+ } else {
+- spi_set_cs(spi, false);
++ spi_set_cs(spi, false, true);
+ }
+
+ mutex_unlock(&spi->controller->io_mutex);
+diff --git a/drivers/staging/media/atomisp/pci/atomisp_fops.c b/drivers/staging/media/atomisp/pci/atomisp_fops.c
+index 453bb69135505..f1e6b25978534 100644
+--- a/drivers/staging/media/atomisp/pci/atomisp_fops.c
++++ b/drivers/staging/media/atomisp/pci/atomisp_fops.c
+@@ -221,6 +221,9 @@ int atomisp_q_video_buffers_to_css(struct atomisp_sub_device *asd,
+ unsigned long irqflags;
+ int err = 0;
+
++ if (WARN_ON(css_pipe_id >= IA_CSS_PIPE_ID_NUM))
++ return -EINVAL;
++
+ while (pipe->buffers_in_css < ATOMISP_CSS_Q_DEPTH) {
+ struct videobuf_buffer *vb;
+
+diff --git a/drivers/staging/media/imx/imx-media-capture.c b/drivers/staging/media/imx/imx-media-capture.c
+index e10ce103a5b4f..94a0467d673b8 100644
+--- a/drivers/staging/media/imx/imx-media-capture.c
++++ b/drivers/staging/media/imx/imx-media-capture.c
+@@ -557,7 +557,7 @@ static int capture_validate_fmt(struct capture_priv *priv)
+ priv->vdev.fmt.fmt.pix.height != f.fmt.pix.height ||
+ priv->vdev.cc->cs != cc->cs ||
+ priv->vdev.compose.width != compose.width ||
+- priv->vdev.compose.height != compose.height) ? -EINVAL : 0;
++ priv->vdev.compose.height != compose.height) ? -EPIPE : 0;
+ }
+
+ static int capture_start_streaming(struct vb2_queue *vq, unsigned int count)
+diff --git a/drivers/staging/media/ipu3/ipu3-v4l2.c b/drivers/staging/media/ipu3/ipu3-v4l2.c
+index 60aa02eb7d2a9..6d9c49b395314 100644
+--- a/drivers/staging/media/ipu3/ipu3-v4l2.c
++++ b/drivers/staging/media/ipu3/ipu3-v4l2.c
+@@ -686,6 +686,7 @@ static int imgu_fmt(struct imgu_device *imgu, unsigned int pipe, int node,
+
+ dev_dbg(dev, "IPU3 pipe %u pipe_id = %u", pipe, css_pipe->pipe_id);
+
++ css_q = imgu_node_to_queue(node);
+ for (i = 0; i < IPU3_CSS_QUEUES; i++) {
+ unsigned int inode = imgu_map_node(imgu, i);
+
+@@ -693,6 +694,18 @@ static int imgu_fmt(struct imgu_device *imgu, unsigned int pipe, int node,
+ if (inode == IMGU_NODE_STAT_3A || inode == IMGU_NODE_PARAMS)
+ continue;
+
++ /* CSS expects some format on OUT queue */
++ if (i != IPU3_CSS_QUEUE_OUT &&
++ !imgu_pipe->nodes[inode].enabled) {
++ fmts[i] = NULL;
++ continue;
++ }
++
++ if (i == css_q) {
++ fmts[i] = &f->fmt.pix_mp;
++ continue;
++ }
++
+ if (try) {
+ fmts[i] = kmemdup(&imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp,
+ sizeof(struct v4l2_pix_format_mplane),
+@@ -705,10 +718,6 @@ static int imgu_fmt(struct imgu_device *imgu, unsigned int pipe, int node,
+ fmts[i] = &imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp;
+ }
+
+- /* CSS expects some format on OUT queue */
+- if (i != IPU3_CSS_QUEUE_OUT &&
+- !imgu_pipe->nodes[inode].enabled)
+- fmts[i] = NULL;
+ }
+
+ if (!try) {
+@@ -725,16 +734,10 @@ static int imgu_fmt(struct imgu_device *imgu, unsigned int pipe, int node,
+ rects[IPU3_CSS_RECT_GDC]->height = pad_fmt.height;
+ }
+
+- /*
+- * imgu doesn't set the node to the value given by user
+- * before we return success from this function, so set it here.
+- */
+- css_q = imgu_node_to_queue(node);
+ if (!fmts[css_q]) {
+ ret = -EINVAL;
+ goto out;
+ }
+- *fmts[css_q] = f->fmt.pix_mp;
+
+ if (try)
+ ret = imgu_css_fmt_try(&imgu->css, fmts, rects, pipe);
+@@ -745,15 +748,18 @@ static int imgu_fmt(struct imgu_device *imgu, unsigned int pipe, int node,
+ if (ret < 0)
+ goto out;
+
+- if (try)
+- f->fmt.pix_mp = *fmts[css_q];
+- else
+- f->fmt = imgu_pipe->nodes[node].vdev_fmt.fmt;
++ /*
++ * imgu doesn't set the node to the value given by user
++ * before we return success from this function, so set it here.
++ */
++ if (!try)
++ imgu_pipe->nodes[node].vdev_fmt.fmt.pix_mp = f->fmt.pix_mp;
+
+ out:
+ if (try) {
+ for (i = 0; i < IPU3_CSS_QUEUES; i++)
+- kfree(fmts[i]);
++ if (i != css_q)
++ kfree(fmts[i]);
+ }
+
+ return ret;
+diff --git a/drivers/staging/wimax/i2400m/op-rfkill.c b/drivers/staging/wimax/i2400m/op-rfkill.c
+index fbddf2e18c142..44698a1aae87a 100644
+--- a/drivers/staging/wimax/i2400m/op-rfkill.c
++++ b/drivers/staging/wimax/i2400m/op-rfkill.c
+@@ -86,7 +86,7 @@ int i2400m_op_rfkill_sw_toggle(struct wimax_dev *wimax_dev,
+ if (cmd == NULL)
+ goto error_alloc;
+ cmd->hdr.type = cpu_to_le16(I2400M_MT_CMD_RF_CONTROL);
+- cmd->hdr.length = sizeof(cmd->sw_rf);
++ cmd->hdr.length = cpu_to_le16(sizeof(cmd->sw_rf));
+ cmd->hdr.version = cpu_to_le16(I2400M_L3L4_VERSION);
+ cmd->sw_rf.hdr.type = cpu_to_le16(I2400M_TLV_RF_OPERATION);
+ cmd->sw_rf.hdr.length = cpu_to_le16(sizeof(cmd->sw_rf.status));
+diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c
+index 9ee797b8cb7ea..508b49b0eaf51 100644
+--- a/drivers/target/target_core_pscsi.c
++++ b/drivers/target/target_core_pscsi.c
+@@ -620,8 +620,9 @@ static void pscsi_complete_cmd(struct se_cmd *cmd, u8 scsi_status,
+ unsigned char *buf;
+
+ buf = transport_kmap_data_sg(cmd);
+- if (!buf)
++ if (!buf) {
+ ; /* XXX: TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE */
++ }
+
+ if (cdb[0] == MODE_SENSE_10) {
+ if (!(buf[3] & 0x80))
+diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c
+index 319a1e701163b..ddb8f9ecf3078 100644
+--- a/drivers/tee/optee/core.c
++++ b/drivers/tee/optee/core.c
+@@ -79,16 +79,6 @@ int optee_from_msg_param(struct tee_param *params, size_t num_params,
+ return rc;
+ p->u.memref.shm_offs = mp->u.tmem.buf_ptr - pa;
+ p->u.memref.shm = shm;
+-
+- /* Check that the memref is covered by the shm object */
+- if (p->u.memref.size) {
+- size_t o = p->u.memref.shm_offs +
+- p->u.memref.size - 1;
+-
+- rc = tee_shm_get_pa(shm, o, NULL);
+- if (rc)
+- return rc;
+- }
+ break;
+ case OPTEE_MSG_ATTR_TYPE_RMEM_INPUT:
+ case OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT:
+diff --git a/drivers/thermal/cpufreq_cooling.c b/drivers/thermal/cpufreq_cooling.c
+index 10af3341e5eaa..6956581ed7a4f 100644
+--- a/drivers/thermal/cpufreq_cooling.c
++++ b/drivers/thermal/cpufreq_cooling.c
+@@ -125,7 +125,7 @@ static u32 cpu_power_to_freq(struct cpufreq_cooling_device *cpufreq_cdev,
+ {
+ int i;
+
+- for (i = cpufreq_cdev->max_level; i >= 0; i--) {
++ for (i = cpufreq_cdev->max_level; i > 0; i--) {
+ if (power >= cpufreq_cdev->em->table[i].power)
+ break;
+ }
+diff --git a/drivers/thermal/gov_fair_share.c b/drivers/thermal/gov_fair_share.c
+index aaa07180ab482..645432ce63659 100644
+--- a/drivers/thermal/gov_fair_share.c
++++ b/drivers/thermal/gov_fair_share.c
+@@ -82,6 +82,8 @@ static int fair_share_throttle(struct thermal_zone_device *tz, int trip)
+ int total_instance = 0;
+ int cur_trip_level = get_trip_level(tz);
+
++ mutex_lock(&tz->lock);
++
+ list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
+ if (instance->trip != trip)
+ continue;
+@@ -110,6 +112,8 @@ static int fair_share_throttle(struct thermal_zone_device *tz, int trip)
+ mutex_unlock(&instance->cdev->lock);
+ thermal_cdev_update(cdev);
+ }
++
++ mutex_unlock(&tz->lock);
+ return 0;
+ }
+
+diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
+index 51dafc06f5414..2406653d38b78 100644
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -2384,8 +2384,18 @@ static int gsmld_attach_gsm(struct tty_struct *tty, struct gsm_mux *gsm)
+ /* Don't register device 0 - this is the control channel and not
+ a usable tty interface */
+ base = mux_num_to_base(gsm); /* Base for this MUX */
+- for (i = 1; i < NUM_DLCI; i++)
+- tty_register_device(gsm_tty_driver, base + i, NULL);
++ for (i = 1; i < NUM_DLCI; i++) {
++ struct device *dev;
++
++ dev = tty_register_device(gsm_tty_driver,
++ base + i, NULL);
++ if (IS_ERR(dev)) {
++ for (i--; i >= 1; i--)
++ tty_unregister_device(gsm_tty_driver,
++ base + i);
++ return PTR_ERR(dev);
++ }
++ }
+ }
+ return ret;
+ }
+diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
+index 284b07224c555..0cc360da5426a 100644
+--- a/drivers/tty/vt/vt.c
++++ b/drivers/tty/vt/vt.c
+@@ -1381,6 +1381,7 @@ struct vc_data *vc_deallocate(unsigned int currcons)
+ atomic_notifier_call_chain(&vt_notifier_list, VT_DEALLOCATE, &param);
+ vcs_remove_sysfs(currcons);
+ visual_deinit(vc);
++ con_free_unimap(vc);
+ put_pid(vc->vt_pid);
+ vc_uniscr_set(vc, NULL);
+ kfree(vc->vc_screenbuf);
+diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
+index 7f71218cc1e54..404507d1b76f1 100644
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -3556,7 +3556,7 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg)
+ u16 portchange, portstatus;
+
+ if (!test_and_set_bit(port1, hub->child_usage_bits)) {
+- status = pm_runtime_get_sync(&port_dev->dev);
++ status = pm_runtime_resume_and_get(&port_dev->dev);
+ if (status < 0) {
+ dev_dbg(&udev->dev, "can't resume usb port, status %d\n",
+ status);
+diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c
+index 55f1d14fc4148..800c8b6c55ff1 100644
+--- a/drivers/usb/dwc2/core_intr.c
++++ b/drivers/usb/dwc2/core_intr.c
+@@ -307,6 +307,7 @@ static void dwc2_handle_conn_id_status_change_intr(struct dwc2_hsotg *hsotg)
+ static void dwc2_handle_session_req_intr(struct dwc2_hsotg *hsotg)
+ {
+ int ret;
++ u32 hprt0;
+
+ /* Clear interrupt */
+ dwc2_writel(hsotg, GINTSTS_SESSREQINT, GINTSTS);
+@@ -327,6 +328,13 @@ static void dwc2_handle_session_req_intr(struct dwc2_hsotg *hsotg)
+ * established
+ */
+ dwc2_hsotg_disconnect(hsotg);
++ } else {
++ /* Turn on the port power bit. */
++ hprt0 = dwc2_read_hprt0(hsotg);
++ hprt0 |= HPRT0_PWR;
++ dwc2_writel(hsotg, hprt0, HPRT0);
++ /* Connect hcd after port power is set. */
++ dwc2_hcd_connect(hsotg);
+ }
+ }
+
+diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
+index f2448d0a9d393..126f0e10b3ef4 100644
+--- a/drivers/usb/dwc3/core.c
++++ b/drivers/usb/dwc3/core.c
+@@ -114,6 +114,8 @@ void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode)
+ dwc->current_dr_role = mode;
+ }
+
++static int dwc3_core_soft_reset(struct dwc3 *dwc);
++
+ static void __dwc3_set_mode(struct work_struct *work)
+ {
+ struct dwc3 *dwc = work_to_dwc(work);
+@@ -121,6 +123,8 @@ static void __dwc3_set_mode(struct work_struct *work)
+ int ret;
+ u32 reg;
+
++ mutex_lock(&dwc->mutex);
++
+ pm_runtime_get_sync(dwc->dev);
+
+ if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_OTG)
+@@ -154,6 +158,25 @@ static void __dwc3_set_mode(struct work_struct *work)
+ break;
+ }
+
++ /* For DRD host or device mode only */
++ if (dwc->desired_dr_role != DWC3_GCTL_PRTCAP_OTG) {
++ reg = dwc3_readl(dwc->regs, DWC3_GCTL);
++ reg |= DWC3_GCTL_CORESOFTRESET;
++ dwc3_writel(dwc->regs, DWC3_GCTL, reg);
++
++ /*
++ * Wait for internal clocks to synchronized. DWC_usb31 and
++ * DWC_usb32 may need at least 50ms (less for DWC_usb3). To
++ * keep it consistent across different IPs, let's wait up to
++ * 100ms before clearing GCTL.CORESOFTRESET.
++ */
++ msleep(100);
++
++ reg = dwc3_readl(dwc->regs, DWC3_GCTL);
++ reg &= ~DWC3_GCTL_CORESOFTRESET;
++ dwc3_writel(dwc->regs, DWC3_GCTL, reg);
++ }
++
+ spin_lock_irqsave(&dwc->lock, flags);
+
+ dwc3_set_prtcap(dwc, dwc->desired_dr_role);
+@@ -178,6 +201,8 @@ static void __dwc3_set_mode(struct work_struct *work)
+ }
+ break;
+ case DWC3_GCTL_PRTCAP_DEVICE:
++ dwc3_core_soft_reset(dwc);
++
+ dwc3_event_buffers_setup(dwc);
+
+ if (dwc->usb2_phy)
+@@ -200,6 +225,7 @@ static void __dwc3_set_mode(struct work_struct *work)
+ out:
+ pm_runtime_mark_last_busy(dwc->dev);
+ pm_runtime_put_autosuspend(dwc->dev);
++ mutex_unlock(&dwc->mutex);
+ }
+
+ void dwc3_set_mode(struct dwc3 *dwc, u32 mode)
+@@ -1277,6 +1303,8 @@ static void dwc3_get_properties(struct dwc3 *dwc)
+ "snps,usb3_lpm_capable");
+ dwc->usb2_lpm_disable = device_property_read_bool(dev,
+ "snps,usb2-lpm-disable");
++ dwc->usb2_gadget_lpm_disable = device_property_read_bool(dev,
++ "snps,usb2-gadget-lpm-disable");
+ device_property_read_u8(dev, "snps,rx-thr-num-pkt-prd",
+ &rx_thr_num_pkt_prd);
+ device_property_read_u8(dev, "snps,rx-max-burst-prd",
+@@ -1543,6 +1571,7 @@ static int dwc3_probe(struct platform_device *pdev)
+ dwc3_cache_hwparams(dwc);
+
+ spin_lock_init(&dwc->lock);
++ mutex_init(&dwc->mutex);
+
+ pm_runtime_set_active(dev);
+ pm_runtime_use_autosuspend(dev);
+diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
+index 052b20d526510..453cfebd4d044 100644
+--- a/drivers/usb/dwc3/core.h
++++ b/drivers/usb/dwc3/core.h
+@@ -13,6 +13,7 @@
+
+ #include <linux/device.h>
+ #include <linux/spinlock.h>
++#include <linux/mutex.h>
+ #include <linux/ioport.h>
+ #include <linux/list.h>
+ #include <linux/bitops.h>
+@@ -946,6 +947,7 @@ struct dwc3_scratchpad_array {
+ * @scratch_addr: dma address of scratchbuf
+ * @ep0_in_setup: one control transfer is completed and enter setup phase
+ * @lock: for synchronizing
++ * @mutex: for mode switching
+ * @dev: pointer to our struct device
+ * @sysdev: pointer to the DMA-capable device
+ * @xhci: pointer to our xHCI child
+@@ -1034,7 +1036,8 @@ struct dwc3_scratchpad_array {
+ * @dis_start_transfer_quirk: set if start_transfer failure SW workaround is
+ * not needed for DWC_usb31 version 1.70a-ea06 and below
+ * @usb3_lpm_capable: set if hadrware supports Link Power Management
+- * @usb2_lpm_disable: set to disable usb2 lpm
++ * @usb2_lpm_disable: set to disable usb2 lpm for host
++ * @usb2_gadget_lpm_disable: set to disable usb2 lpm for gadget
+ * @disable_scramble_quirk: set if we enable the disable scramble quirk
+ * @u2exit_lfps_quirk: set if we enable u2exit lfps quirk
+ * @u2ss_inp3_quirk: set if we enable P3 OK for U2/SS Inactive quirk
+@@ -1085,6 +1088,9 @@ struct dwc3 {
+ /* device lock */
+ spinlock_t lock;
+
++ /* mode switching lock */
++ struct mutex mutex;
++
+ struct device *dev;
+ struct device *sysdev;
+
+@@ -1238,6 +1244,7 @@ struct dwc3 {
+ unsigned dis_start_transfer_quirk:1;
+ unsigned usb3_lpm_capable:1;
+ unsigned usb2_lpm_disable:1;
++ unsigned usb2_gadget_lpm_disable:1;
+
+ unsigned disable_scramble_quirk:1;
+ unsigned u2exit_lfps_quirk:1;
+diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
+index 4c5c6972124a4..95f954a1d7be9 100644
+--- a/drivers/usb/dwc3/dwc3-pci.c
++++ b/drivers/usb/dwc3/dwc3-pci.c
+@@ -41,6 +41,7 @@
+ #define PCI_DEVICE_ID_INTEL_TGPH 0x43ee
+ #define PCI_DEVICE_ID_INTEL_JSP 0x4dee
+ #define PCI_DEVICE_ID_INTEL_ADLP 0x51ee
++#define PCI_DEVICE_ID_INTEL_ADLM 0x54ee
+ #define PCI_DEVICE_ID_INTEL_ADLS 0x7ae1
+ #define PCI_DEVICE_ID_INTEL_TGL 0x9a15
+
+@@ -388,6 +389,9 @@ static const struct pci_device_id dwc3_pci_id_table[] = {
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ADLP),
+ (kernel_ulong_t) &dwc3_pci_intel_swnode, },
+
++ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ADLM),
++ (kernel_ulong_t) &dwc3_pci_intel_swnode, },
++
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ADLS),
+ (kernel_ulong_t) &dwc3_pci_intel_swnode, },
+
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
+index c7ef218e7a8cf..f85eda6bc988e 100644
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -308,13 +308,12 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned int cmd,
+ }
+
+ if (DWC3_DEPCMD_CMD(cmd) == DWC3_DEPCMD_STARTTRANSFER) {
+- int needs_wakeup;
++ int link_state;
+
+- needs_wakeup = (dwc->link_state == DWC3_LINK_STATE_U1 ||
+- dwc->link_state == DWC3_LINK_STATE_U2 ||
+- dwc->link_state == DWC3_LINK_STATE_U3);
+-
+- if (unlikely(needs_wakeup)) {
++ link_state = dwc3_gadget_get_link_state(dwc);
++ if (link_state == DWC3_LINK_STATE_U1 ||
++ link_state == DWC3_LINK_STATE_U2 ||
++ link_state == DWC3_LINK_STATE_U3) {
+ ret = __dwc3_gadget_wakeup(dwc);
+ dev_WARN_ONCE(dwc->dev, ret, "wakeup failed --> %d\n",
+ ret);
+@@ -608,12 +607,14 @@ static int dwc3_gadget_set_ep_config(struct dwc3_ep *dep, unsigned int action)
+ u8 bInterval_m1;
+
+ /*
+- * Valid range for DEPCFG.bInterval_m1 is from 0 to 13, and it
+- * must be set to 0 when the controller operates in full-speed.
++ * Valid range for DEPCFG.bInterval_m1 is from 0 to 13.
++ *
++ * NOTE: The programming guide incorrectly stated bInterval_m1
++ * must be set to 0 when operating in fullspeed. Internally the
++ * controller does not have this limitation. See DWC_usb3x
++ * programming guide section 3.2.2.1.
+ */
+ bInterval_m1 = min_t(u8, desc->bInterval - 1, 13);
+- if (dwc->gadget->speed == USB_SPEED_FULL)
+- bInterval_m1 = 0;
+
+ if (usb_endpoint_type(desc) == USB_ENDPOINT_XFER_INT &&
+ dwc->gadget->speed == USB_SPEED_FULL)
+@@ -1973,6 +1974,8 @@ static int __dwc3_gadget_wakeup(struct dwc3 *dwc)
+ case DWC3_LINK_STATE_RESET:
+ case DWC3_LINK_STATE_RX_DET: /* in HS, means Early Suspend */
+ case DWC3_LINK_STATE_U3: /* in HS, means SUSPEND */
++ case DWC3_LINK_STATE_U2: /* in HS, means Sleep (L1) */
++ case DWC3_LINK_STATE_U1:
+ case DWC3_LINK_STATE_RESUME:
+ break;
+ default:
+@@ -3322,6 +3325,15 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc)
+ {
+ u32 reg;
+
++ /*
++ * Ideally, dwc3_reset_gadget() would trigger the function
++ * drivers to stop any active transfers through ep disable.
++ * However, for functions which defer ep disable, such as mass
++ * storage, we will need to rely on the call to stop active
++ * transfers here, and avoid allowing of request queuing.
++ */
++ dwc->connected = false;
++
+ /*
+ * WORKAROUND: DWC3 revisions <1.88a have an issue which
+ * would cause a missing Disconnect Event if there's a
+@@ -3460,6 +3472,7 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
+ /* Enable USB2 LPM Capability */
+
+ if (!DWC3_VER_IS_WITHIN(DWC3, ANY, 194A) &&
++ !dwc->usb2_gadget_lpm_disable &&
+ (speed != DWC3_DSTS_SUPERSPEED) &&
+ (speed != DWC3_DSTS_SUPERSPEED_PLUS)) {
+ reg = dwc3_readl(dwc->regs, DWC3_DCFG);
+@@ -3486,6 +3499,12 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
+
+ dwc3_gadget_dctl_write_safe(dwc, reg);
+ } else {
++ if (dwc->usb2_gadget_lpm_disable) {
++ reg = dwc3_readl(dwc->regs, DWC3_DCFG);
++ reg &= ~DWC3_DCFG_LPM_CAP;
++ dwc3_writel(dwc->regs, DWC3_DCFG, reg);
++ }
++
+ reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg &= ~DWC3_DCTL_HIRD_THRES_MASK;
+ dwc3_gadget_dctl_write_safe(dwc, reg);
+@@ -3934,7 +3953,7 @@ int dwc3_gadget_init(struct dwc3 *dwc)
+ dwc->gadget->ssp_rate = USB_SSP_GEN_UNKNOWN;
+ dwc->gadget->sg_supported = true;
+ dwc->gadget->name = "dwc3-gadget";
+- dwc->gadget->lpm_capable = true;
++ dwc->gadget->lpm_capable = !dwc->usb2_gadget_lpm_disable;
+
+ /*
+ * FIXME We might be setting max_speed to <SUPER, however versions
+diff --git a/drivers/usb/gadget/config.c b/drivers/usb/gadget/config.c
+index 2d115353424c2..8bb25773b61e9 100644
+--- a/drivers/usb/gadget/config.c
++++ b/drivers/usb/gadget/config.c
+@@ -194,9 +194,13 @@ EXPORT_SYMBOL_GPL(usb_assign_descriptors);
+ void usb_free_all_descriptors(struct usb_function *f)
+ {
+ usb_free_descriptors(f->fs_descriptors);
++ f->fs_descriptors = NULL;
+ usb_free_descriptors(f->hs_descriptors);
++ f->hs_descriptors = NULL;
+ usb_free_descriptors(f->ss_descriptors);
++ f->ss_descriptors = NULL;
+ usb_free_descriptors(f->ssp_descriptors);
++ f->ssp_descriptors = NULL;
+ }
+ EXPORT_SYMBOL_GPL(usb_free_all_descriptors);
+
+diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
+index 801a8b668a35a..10a5d9f0f2b90 100644
+--- a/drivers/usb/gadget/function/f_fs.c
++++ b/drivers/usb/gadget/function/f_fs.c
+@@ -2640,6 +2640,7 @@ static int __ffs_data_got_strings(struct ffs_data *ffs,
+
+ do { /* lang_count > 0 so we can use do-while */
+ unsigned needed = needed_count;
++ u32 str_per_lang = str_count;
+
+ if (len < 3)
+ goto error_free;
+@@ -2675,7 +2676,7 @@ static int __ffs_data_got_strings(struct ffs_data *ffs,
+
+ data += length + 1;
+ len -= length + 1;
+- } while (--str_count);
++ } while (--str_per_lang);
+
+ s->id = 0; /* terminator */
+ s->s = NULL;
+diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c
+index 560382e0a8f38..e65f474ad7b3b 100644
+--- a/drivers/usb/gadget/function/f_uac1.c
++++ b/drivers/usb/gadget/function/f_uac1.c
+@@ -19,6 +19,9 @@
+ #include "u_audio.h"
+ #include "u_uac1.h"
+
++/* UAC1 spec: 3.7.2.3 Audio Channel Cluster Format */
++#define UAC1_CHANNEL_MASK 0x0FFF
++
+ struct f_uac1 {
+ struct g_audio g_audio;
+ u8 ac_intf, as_in_intf, as_out_intf;
+@@ -30,6 +33,11 @@ static inline struct f_uac1 *func_to_uac1(struct usb_function *f)
+ return container_of(f, struct f_uac1, g_audio.func);
+ }
+
++static inline struct f_uac1_opts *g_audio_to_uac1_opts(struct g_audio *audio)
++{
++ return container_of(audio->func.fi, struct f_uac1_opts, func_inst);
++}
++
+ /*
+ * DESCRIPTORS ... most are static, but strings and full
+ * configuration descriptors are built on demand.
+@@ -505,11 +513,42 @@ static void f_audio_disable(struct usb_function *f)
+
+ /*-------------------------------------------------------------------------*/
+
++static int f_audio_validate_opts(struct g_audio *audio, struct device *dev)
++{
++ struct f_uac1_opts *opts = g_audio_to_uac1_opts(audio);
++
++ if (!opts->p_chmask && !opts->c_chmask) {
++ dev_err(dev, "Error: no playback and capture channels\n");
++ return -EINVAL;
++ } else if (opts->p_chmask & ~UAC1_CHANNEL_MASK) {
++ dev_err(dev, "Error: unsupported playback channels mask\n");
++ return -EINVAL;
++ } else if (opts->c_chmask & ~UAC1_CHANNEL_MASK) {
++ dev_err(dev, "Error: unsupported capture channels mask\n");
++ return -EINVAL;
++ } else if ((opts->p_ssize < 1) || (opts->p_ssize > 4)) {
++ dev_err(dev, "Error: incorrect playback sample size\n");
++ return -EINVAL;
++ } else if ((opts->c_ssize < 1) || (opts->c_ssize > 4)) {
++ dev_err(dev, "Error: incorrect capture sample size\n");
++ return -EINVAL;
++ } else if (!opts->p_srate) {
++ dev_err(dev, "Error: incorrect playback sampling rate\n");
++ return -EINVAL;
++ } else if (!opts->c_srate) {
++ dev_err(dev, "Error: incorrect capture sampling rate\n");
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
+ /* audio function driver setup/binding */
+ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f)
+ {
+ struct usb_composite_dev *cdev = c->cdev;
+ struct usb_gadget *gadget = cdev->gadget;
++ struct device *dev = &gadget->dev;
+ struct f_uac1 *uac1 = func_to_uac1(f);
+ struct g_audio *audio = func_to_g_audio(f);
+ struct f_uac1_opts *audio_opts;
+@@ -519,6 +558,10 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f)
+ int rate;
+ int status;
+
++ status = f_audio_validate_opts(audio, dev);
++ if (status)
++ return status;
++
+ audio_opts = container_of(f->fi, struct f_uac1_opts, func_inst);
+
+ us = usb_gstrings_attach(cdev, uac1_strings, ARRAY_SIZE(strings_uac1));
+diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c
+index 6f03e944e0e31..dd960cea642f3 100644
+--- a/drivers/usb/gadget/function/f_uac2.c
++++ b/drivers/usb/gadget/function/f_uac2.c
+@@ -14,6 +14,9 @@
+ #include "u_audio.h"
+ #include "u_uac2.h"
+
++/* UAC2 spec: 4.1 Audio Channel Cluster Descriptor */
++#define UAC2_CHANNEL_MASK 0x07FFFFFF
++
+ /*
+ * The driver implements a simple UAC_2 topology.
+ * USB-OUT -> IT_1 -> OT_3 -> ALSA_Capture
+@@ -604,6 +607,36 @@ static void setup_descriptor(struct f_uac2_opts *opts)
+ hs_audio_desc[i] = NULL;
+ }
+
++static int afunc_validate_opts(struct g_audio *agdev, struct device *dev)
++{
++ struct f_uac2_opts *opts = g_audio_to_uac2_opts(agdev);
++
++ if (!opts->p_chmask && !opts->c_chmask) {
++ dev_err(dev, "Error: no playback and capture channels\n");
++ return -EINVAL;
++ } else if (opts->p_chmask & ~UAC2_CHANNEL_MASK) {
++ dev_err(dev, "Error: unsupported playback channels mask\n");
++ return -EINVAL;
++ } else if (opts->c_chmask & ~UAC2_CHANNEL_MASK) {
++ dev_err(dev, "Error: unsupported capture channels mask\n");
++ return -EINVAL;
++ } else if ((opts->p_ssize < 1) || (opts->p_ssize > 4)) {
++ dev_err(dev, "Error: incorrect playback sample size\n");
++ return -EINVAL;
++ } else if ((opts->c_ssize < 1) || (opts->c_ssize > 4)) {
++ dev_err(dev, "Error: incorrect capture sample size\n");
++ return -EINVAL;
++ } else if (!opts->p_srate) {
++ dev_err(dev, "Error: incorrect playback sampling rate\n");
++ return -EINVAL;
++ } else if (!opts->c_srate) {
++ dev_err(dev, "Error: incorrect capture sampling rate\n");
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
+ static int
+ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
+ {
+@@ -612,11 +645,13 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
+ struct usb_composite_dev *cdev = cfg->cdev;
+ struct usb_gadget *gadget = cdev->gadget;
+ struct device *dev = &gadget->dev;
+- struct f_uac2_opts *uac2_opts;
++ struct f_uac2_opts *uac2_opts = g_audio_to_uac2_opts(agdev);
+ struct usb_string *us;
+ int ret;
+
+- uac2_opts = container_of(fn->fi, struct f_uac2_opts, func_inst);
++ ret = afunc_validate_opts(agdev, dev);
++ if (ret)
++ return ret;
+
+ us = usb_gstrings_attach(cdev, fn_strings, ARRAY_SIZE(strings_fn));
+ if (IS_ERR(us))
+diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c
+index 44b4352a26765..f48a00e497945 100644
+--- a/drivers/usb/gadget/function/f_uvc.c
++++ b/drivers/usb/gadget/function/f_uvc.c
+@@ -633,7 +633,12 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
+
+ uvc_hs_streaming_ep.wMaxPacketSize =
+ cpu_to_le16(max_packet_size | ((max_packet_mult - 1) << 11));
+- uvc_hs_streaming_ep.bInterval = opts->streaming_interval;
++
++ /* A high-bandwidth endpoint must specify a bInterval value of 1 */
++ if (max_packet_mult > 1)
++ uvc_hs_streaming_ep.bInterval = 1;
++ else
++ uvc_hs_streaming_ep.bInterval = opts->streaming_interval;
+
+ uvc_ss_streaming_ep.wMaxPacketSize = cpu_to_le16(max_packet_size);
+ uvc_ss_streaming_ep.bInterval = opts->streaming_interval;
+@@ -817,6 +822,7 @@ static struct usb_function_instance *uvc_alloc_inst(void)
+ pd->bmControls[0] = 1;
+ pd->bmControls[1] = 0;
+ pd->iProcessing = 0;
++ pd->bmVideoStandards = 0;
+
+ od = &opts->uvc_output_terminal;
+ od->bLength = UVC_DT_OUTPUT_TERMINAL_SIZE;
+diff --git a/drivers/usb/gadget/legacy/webcam.c b/drivers/usb/gadget/legacy/webcam.c
+index a9f8eb8e1c767..2c9eab2b863d2 100644
+--- a/drivers/usb/gadget/legacy/webcam.c
++++ b/drivers/usb/gadget/legacy/webcam.c
+@@ -125,6 +125,7 @@ static const struct uvc_processing_unit_descriptor uvc_processing = {
+ .bmControls[0] = 1,
+ .bmControls[1] = 0,
+ .iProcessing = 0,
++ .bmVideoStandards = 0,
+ };
+
+ static const struct uvc_output_terminal_descriptor uvc_output_terminal = {
+diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c
+index 57067763b1005..5f474ffe2be1e 100644
+--- a/drivers/usb/gadget/udc/dummy_hcd.c
++++ b/drivers/usb/gadget/udc/dummy_hcd.c
+@@ -903,6 +903,21 @@ static int dummy_pullup(struct usb_gadget *_gadget, int value)
+ spin_lock_irqsave(&dum->lock, flags);
+ dum->pullup = (value != 0);
+ set_link_state(dum_hcd);
++ if (value == 0) {
++ /*
++ * Emulate synchronize_irq(): wait for callbacks to finish.
++ * This seems to be the best place to emulate the call to
++ * synchronize_irq() that's in usb_gadget_remove_driver().
++ * Doing it in dummy_udc_stop() would be too late since it
++ * is called after the unbind callback and unbind shouldn't
++ * be invoked until all the other callbacks are finished.
++ */
++ while (dum->callback_usage > 0) {
++ spin_unlock_irqrestore(&dum->lock, flags);
++ usleep_range(1000, 2000);
++ spin_lock_irqsave(&dum->lock, flags);
++ }
++ }
+ spin_unlock_irqrestore(&dum->lock, flags);
+
+ usb_hcd_poll_rh_status(dummy_hcd_to_hcd(dum_hcd));
+@@ -1004,14 +1019,6 @@ static int dummy_udc_stop(struct usb_gadget *g)
+ spin_lock_irq(&dum->lock);
+ dum->ints_enabled = 0;
+ stop_activity(dum);
+-
+- /* emulate synchronize_irq(): wait for callbacks to finish */
+- while (dum->callback_usage > 0) {
+- spin_unlock_irq(&dum->lock);
+- usleep_range(1000, 2000);
+- spin_lock_irq(&dum->lock);
+- }
+-
+ dum->driver = NULL;
+ spin_unlock_irq(&dum->lock);
+
+diff --git a/drivers/usb/gadget/udc/tegra-xudc.c b/drivers/usb/gadget/udc/tegra-xudc.c
+index 580bef8eb4cbc..2319c9737c2bd 100644
+--- a/drivers/usb/gadget/udc/tegra-xudc.c
++++ b/drivers/usb/gadget/udc/tegra-xudc.c
+@@ -3883,7 +3883,7 @@ static int tegra_xudc_remove(struct platform_device *pdev)
+
+ pm_runtime_get_sync(xudc->dev);
+
+- cancel_delayed_work(&xudc->plc_reset_work);
++ cancel_delayed_work_sync(&xudc->plc_reset_work);
+ cancel_work_sync(&xudc->usb_role_sw_work);
+
+ usb_del_gadget_udc(&xudc->gadget);
+diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
+index f2c4ee7c4786e..717c122f94490 100644
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -2129,6 +2129,15 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports,
+
+ if (major_revision == 0x03) {
+ rhub = &xhci->usb3_rhub;
++ /*
++ * Some hosts incorrectly use sub-minor version for minor
++ * version (i.e. 0x02 instead of 0x20 for bcdUSB 0x320 and 0x01
++ * for bcdUSB 0x310). Since there is no USB release with sub
++ * minor version 0x301 to 0x309, we can assume that they are
++ * incorrect and fix it here.
++ */
++ if (minor_revision > 0x00 && minor_revision < 0x10)
++ minor_revision <<= 4;
+ } else if (major_revision <= 0x02) {
+ rhub = &xhci->usb2_rhub;
+ } else {
+@@ -2240,6 +2249,9 @@ static void xhci_create_rhub_port_array(struct xhci_hcd *xhci,
+ return;
+ rhub->ports = kcalloc_node(rhub->num_ports, sizeof(*rhub->ports),
+ flags, dev_to_node(dev));
++ if (!rhub->ports)
++ return;
++
+ for (i = 0; i < HCS_MAX_PORTS(xhci->hcs_params1); i++) {
+ if (xhci->hw_ports[i].rhub != rhub ||
+ xhci->hw_ports[i].hcd_portnum == DUPLICATE_ENTRY)
+diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
+index 2f27dc0d9c6bd..1c331577fca92 100644
+--- a/drivers/usb/host/xhci-mtk.c
++++ b/drivers/usb/host/xhci-mtk.c
+@@ -397,6 +397,8 @@ static void xhci_mtk_quirks(struct device *dev, struct xhci_hcd *xhci)
+ xhci->quirks |= XHCI_SPURIOUS_SUCCESS;
+ if (mtk->lpm_support)
+ xhci->quirks |= XHCI_LPM_SUPPORT;
++ if (mtk->u2_lpm_disable)
++ xhci->quirks |= XHCI_HW_LPM_DISABLE;
+
+ /*
+ * MTK xHCI 0.96: PSA is 1 by default even if doesn't support stream,
+@@ -469,6 +471,7 @@ static int xhci_mtk_probe(struct platform_device *pdev)
+ return ret;
+
+ mtk->lpm_support = of_property_read_bool(node, "usb3-lpm-capable");
++ mtk->u2_lpm_disable = of_property_read_bool(node, "usb2-lpm-disable");
+ /* optional property, ignore the error if it does not exist */
+ of_property_read_u32(node, "mediatek,u3p-dis-msk",
+ &mtk->u3p_dis_msk);
+diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h
+index cbb09dfea62e0..080109012b9ac 100644
+--- a/drivers/usb/host/xhci-mtk.h
++++ b/drivers/usb/host/xhci-mtk.h
+@@ -150,6 +150,7 @@ struct xhci_hcd_mtk {
+ struct phy **phys;
+ int num_phys;
+ bool lpm_support;
++ bool u2_lpm_disable;
+ /* usb remote wakeup */
+ bool uwk_en;
+ struct regmap *uwk;
+diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
+index ce38076901e25..59d41d2c200df 100644
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -2129,16 +2129,13 @@ int xhci_is_vendor_info_code(struct xhci_hcd *xhci, unsigned int trb_comp_code)
+ return 0;
+ }
+
+-static int finish_td(struct xhci_hcd *xhci, struct xhci_td *td,
+- struct xhci_transfer_event *event, struct xhci_virt_ep *ep)
++static int finish_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep,
++ struct xhci_ring *ep_ring, struct xhci_td *td,
++ u32 trb_comp_code)
+ {
+ struct xhci_ep_ctx *ep_ctx;
+- struct xhci_ring *ep_ring;
+- u32 trb_comp_code;
+
+- ep_ring = xhci_dma_to_transfer_ring(ep, le64_to_cpu(event->buffer));
+ ep_ctx = xhci_get_ep_ctx(xhci, ep->vdev->out_ctx, ep->ep_index);
+- trb_comp_code = GET_COMP_CODE(le32_to_cpu(event->transfer_len));
+
+ switch (trb_comp_code) {
+ case COMP_STOPPED_LENGTH_INVALID:
+@@ -2234,9 +2231,9 @@ static int sum_trb_lengths(struct xhci_hcd *xhci, struct xhci_ring *ring,
+ /*
+ * Process control tds, update urb status and actual_length.
+ */
+-static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td,
+- union xhci_trb *ep_trb, struct xhci_transfer_event *event,
+- struct xhci_virt_ep *ep)
++static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep,
++ struct xhci_ring *ep_ring, struct xhci_td *td,
++ union xhci_trb *ep_trb, struct xhci_transfer_event *event)
+ {
+ struct xhci_ep_ctx *ep_ctx;
+ u32 trb_comp_code;
+@@ -2324,15 +2321,15 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td,
+ td->urb->actual_length = requested;
+
+ finish_td:
+- return finish_td(xhci, td, event, ep);
++ return finish_td(xhci, ep, ep_ring, td, trb_comp_code);
+ }
+
+ /*
+ * Process isochronous tds, update urb packet status and actual_length.
+ */
+-static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
+- union xhci_trb *ep_trb, struct xhci_transfer_event *event,
+- struct xhci_virt_ep *ep)
++static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep,
++ struct xhci_ring *ep_ring, struct xhci_td *td,
++ union xhci_trb *ep_trb, struct xhci_transfer_event *event)
+ {
+ struct urb_priv *urb_priv;
+ int idx;
+@@ -2409,7 +2406,7 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
+
+ td->urb->actual_length += frame->actual_length;
+
+- return finish_td(xhci, td, event, ep);
++ return finish_td(xhci, ep, ep_ring, td, trb_comp_code);
+ }
+
+ static int skip_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
+@@ -2441,17 +2438,15 @@ static int skip_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
+ /*
+ * Process bulk and interrupt tds, update urb status and actual_length.
+ */
+-static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td,
+- union xhci_trb *ep_trb, struct xhci_transfer_event *event,
+- struct xhci_virt_ep *ep)
++static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep,
++ struct xhci_ring *ep_ring, struct xhci_td *td,
++ union xhci_trb *ep_trb, struct xhci_transfer_event *event)
+ {
+ struct xhci_slot_ctx *slot_ctx;
+- struct xhci_ring *ep_ring;
+ u32 trb_comp_code;
+ u32 remaining, requested, ep_trb_len;
+
+ slot_ctx = xhci_get_slot_ctx(xhci, ep->vdev->out_ctx);
+- ep_ring = xhci_dma_to_transfer_ring(ep, le64_to_cpu(event->buffer));
+ trb_comp_code = GET_COMP_CODE(le32_to_cpu(event->transfer_len));
+ remaining = EVENT_TRB_LEN(le32_to_cpu(event->transfer_len));
+ ep_trb_len = TRB_LEN(le32_to_cpu(ep_trb->generic.field[2]));
+@@ -2511,7 +2506,8 @@ finish_td:
+ remaining);
+ td->urb->actual_length = 0;
+ }
+- return finish_td(xhci, td, event, ep);
++
++ return finish_td(xhci, ep, ep_ring, td, trb_comp_code);
+ }
+
+ /*
+@@ -2854,11 +2850,11 @@ static int handle_tx_event(struct xhci_hcd *xhci,
+
+ /* update the urb's actual_length and give back to the core */
+ if (usb_endpoint_xfer_control(&td->urb->ep->desc))
+- process_ctrl_td(xhci, td, ep_trb, event, ep);
++ process_ctrl_td(xhci, ep, ep_ring, td, ep_trb, event);
+ else if (usb_endpoint_xfer_isoc(&td->urb->ep->desc))
+- process_isoc_td(xhci, td, ep_trb, event, ep);
++ process_isoc_td(xhci, ep, ep_ring, td, ep_trb, event);
+ else
+- process_bulk_intr_td(xhci, td, ep_trb, event, ep);
++ process_bulk_intr_td(xhci, ep, ep_ring, td, ep_trb, event);
+ cleanup:
+ handling_skipped_tds = ep->skip &&
+ trb_comp_code != COMP_MISSED_SERVICE_ERROR &&
+diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
+index 1975016f46bff..6672c2f403034 100644
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -228,6 +228,7 @@ static void xhci_zero_64b_regs(struct xhci_hcd *xhci)
+ struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
+ int err, i;
+ u64 val;
++ u32 intrs;
+
+ /*
+ * Some Renesas controllers get into a weird state if they are
+@@ -266,7 +267,10 @@ static void xhci_zero_64b_regs(struct xhci_hcd *xhci)
+ if (upper_32_bits(val))
+ xhci_write_64(xhci, 0, &xhci->op_regs->cmd_ring);
+
+- for (i = 0; i < HCS_MAX_INTRS(xhci->hcs_params1); i++) {
++ intrs = min_t(u32, HCS_MAX_INTRS(xhci->hcs_params1),
++ ARRAY_SIZE(xhci->run_regs->ir_set));
++
++ for (i = 0; i < intrs; i++) {
+ struct xhci_intr_reg __iomem *ir;
+
+ ir = &xhci->run_regs->ir_set[i];
+@@ -3269,6 +3273,14 @@ static void xhci_endpoint_reset(struct usb_hcd *hcd,
+
+ /* config ep command clears toggle if add and drop ep flags are set */
+ ctrl_ctx = xhci_get_input_control_ctx(cfg_cmd->in_ctx);
++ if (!ctrl_ctx) {
++ spin_unlock_irqrestore(&xhci->lock, flags);
++ xhci_free_command(xhci, cfg_cmd);
++ xhci_warn(xhci, "%s: Could not get input context, bad type.\n",
++ __func__);
++ goto cleanup;
++ }
++
+ xhci_setup_input_ctx_for_config_ep(xhci, cfg_cmd->in_ctx, vdev->out_ctx,
+ ctrl_ctx, ep_flag, ep_flag);
+ xhci_endpoint_copy(xhci, cfg_cmd->in_ctx, vdev->out_ctx, ep_index);
+diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
+index fc0457db62e1a..8f09a387b7738 100644
+--- a/drivers/usb/musb/musb_core.c
++++ b/drivers/usb/musb/musb_core.c
+@@ -2070,7 +2070,7 @@ static void musb_irq_work(struct work_struct *data)
+ struct musb *musb = container_of(data, struct musb, irq_work.work);
+ int error;
+
+- error = pm_runtime_get_sync(musb->controller);
++ error = pm_runtime_resume_and_get(musb->controller);
+ if (error < 0) {
+ dev_err(musb->controller, "Could not enable: %i\n", error);
+
+diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
+index bfa4c6ef554e5..c79d2f2387aaa 100644
+--- a/drivers/vhost/vdpa.c
++++ b/drivers/vhost/vdpa.c
+@@ -993,6 +993,7 @@ static int vhost_vdpa_mmap(struct file *file, struct vm_area_struct *vma)
+ if (vma->vm_end - vma->vm_start != notify.size)
+ return -ENOTSUPP;
+
++ vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP;
+ vma->vm_ops = &vhost_vdpa_vm_ops;
+ return 0;
+ }
+diff --git a/drivers/video/backlight/qcom-wled.c b/drivers/video/backlight/qcom-wled.c
+index 091f07e7c1451..e9fbe24838440 100644
+--- a/drivers/video/backlight/qcom-wled.c
++++ b/drivers/video/backlight/qcom-wled.c
+@@ -336,19 +336,19 @@ static int wled3_sync_toggle(struct wled *wled)
+ unsigned int mask = GENMASK(wled->max_string_count - 1, 0);
+
+ rc = regmap_update_bits(wled->regmap,
+- wled->ctrl_addr + WLED3_SINK_REG_SYNC,
++ wled->sink_addr + WLED3_SINK_REG_SYNC,
+ mask, mask);
+ if (rc < 0)
+ return rc;
+
+ rc = regmap_update_bits(wled->regmap,
+- wled->ctrl_addr + WLED3_SINK_REG_SYNC,
++ wled->sink_addr + WLED3_SINK_REG_SYNC,
+ mask, WLED3_SINK_REG_SYNC_CLEAR);
+
+ return rc;
+ }
+
+-static int wled5_sync_toggle(struct wled *wled)
++static int wled5_mod_sync_toggle(struct wled *wled)
+ {
+ int rc;
+ u8 val;
+@@ -445,10 +445,23 @@ static int wled_update_status(struct backlight_device *bl)
+ goto unlock_mutex;
+ }
+
+- rc = wled->wled_sync_toggle(wled);
+- if (rc < 0) {
+- dev_err(wled->dev, "wled sync failed rc:%d\n", rc);
+- goto unlock_mutex;
++ if (wled->version < 5) {
++ rc = wled->wled_sync_toggle(wled);
++ if (rc < 0) {
++ dev_err(wled->dev, "wled sync failed rc:%d\n", rc);
++ goto unlock_mutex;
++ }
++ } else {
++ /*
++ * For WLED5 toggling the MOD_SYNC_BIT updates the
++ * brightness
++ */
++ rc = wled5_mod_sync_toggle(wled);
++ if (rc < 0) {
++ dev_err(wled->dev, "wled mod sync failed rc:%d\n",
++ rc);
++ goto unlock_mutex;
++ }
+ }
+ }
+
+@@ -1459,7 +1472,7 @@ static int wled_configure(struct wled *wled)
+ size = ARRAY_SIZE(wled5_opts);
+ *cfg = wled5_config_defaults;
+ wled->wled_set_brightness = wled5_set_brightness;
+- wled->wled_sync_toggle = wled5_sync_toggle;
++ wled->wled_sync_toggle = wled3_sync_toggle;
+ wled->wled_cabc_config = wled5_cabc_config;
+ wled->wled_ovp_delay = wled5_ovp_delay;
+ wled->wled_auto_detection_required =
+diff --git a/drivers/video/fbdev/core/fbcmap.c b/drivers/video/fbdev/core/fbcmap.c
+index 757d5c3f620b7..ff09e57f3c380 100644
+--- a/drivers/video/fbdev/core/fbcmap.c
++++ b/drivers/video/fbdev/core/fbcmap.c
+@@ -101,17 +101,17 @@ int fb_alloc_cmap_gfp(struct fb_cmap *cmap, int len, int transp, gfp_t flags)
+ if (!len)
+ return 0;
+
+- cmap->red = kmalloc(size, flags);
++ cmap->red = kzalloc(size, flags);
+ if (!cmap->red)
+ goto fail;
+- cmap->green = kmalloc(size, flags);
++ cmap->green = kzalloc(size, flags);
+ if (!cmap->green)
+ goto fail;
+- cmap->blue = kmalloc(size, flags);
++ cmap->blue = kzalloc(size, flags);
+ if (!cmap->blue)
+ goto fail;
+ if (transp) {
+- cmap->transp = kmalloc(size, flags);
++ cmap->transp = kzalloc(size, flags);
+ if (!cmap->transp)
+ goto fail;
+ } else {
+diff --git a/drivers/virt/nitro_enclaves/ne_misc_dev.c b/drivers/virt/nitro_enclaves/ne_misc_dev.c
+index f1964ea4b8269..e21e1e86ad15f 100644
+--- a/drivers/virt/nitro_enclaves/ne_misc_dev.c
++++ b/drivers/virt/nitro_enclaves/ne_misc_dev.c
+@@ -1524,7 +1524,8 @@ static const struct file_operations ne_enclave_fops = {
+ * enclave file descriptor to be further used for enclave
+ * resources handling e.g. memory regions and CPUs.
+ * @ne_pci_dev : Private data associated with the PCI device.
+- * @slot_uid: Generated unique slot id associated with an enclave.
++ * @slot_uid: User pointer to store the generated unique slot id
++ * associated with an enclave to.
+ *
+ * Context: Process context. This function is called with the ne_pci_dev enclave
+ * mutex held.
+@@ -1532,7 +1533,7 @@ static const struct file_operations ne_enclave_fops = {
+ * * Enclave fd on success.
+ * * Negative return value on failure.
+ */
+-static int ne_create_vm_ioctl(struct ne_pci_dev *ne_pci_dev, u64 *slot_uid)
++static int ne_create_vm_ioctl(struct ne_pci_dev *ne_pci_dev, u64 __user *slot_uid)
+ {
+ struct ne_pci_dev_cmd_reply cmd_reply = {};
+ int enclave_fd = -1;
+@@ -1634,7 +1635,18 @@ static int ne_create_vm_ioctl(struct ne_pci_dev *ne_pci_dev, u64 *slot_uid)
+
+ list_add(&ne_enclave->enclave_list_entry, &ne_pci_dev->enclaves_list);
+
+- *slot_uid = ne_enclave->slot_uid;
++ if (copy_to_user(slot_uid, &ne_enclave->slot_uid, sizeof(ne_enclave->slot_uid))) {
++ /*
++ * As we're holding the only reference to 'enclave_file', fput()
++ * will call ne_enclave_release() which will do a proper cleanup
++ * of all so far allocated resources, leaving only the unused fd
++ * for us to free.
++ */
++ fput(enclave_file);
++ put_unused_fd(enclave_fd);
++
++ return -EFAULT;
++ }
+
+ fd_install(enclave_fd, enclave_file);
+
+@@ -1671,34 +1683,13 @@ static long ne_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+ switch (cmd) {
+ case NE_CREATE_VM: {
+ int enclave_fd = -1;
+- struct file *enclave_file = NULL;
+ struct ne_pci_dev *ne_pci_dev = ne_devs.ne_pci_dev;
+- int rc = -EINVAL;
+- u64 slot_uid = 0;
++ u64 __user *slot_uid = (void __user *)arg;
+
+ mutex_lock(&ne_pci_dev->enclaves_list_mutex);
+-
+- enclave_fd = ne_create_vm_ioctl(ne_pci_dev, &slot_uid);
+- if (enclave_fd < 0) {
+- rc = enclave_fd;
+-
+- mutex_unlock(&ne_pci_dev->enclaves_list_mutex);
+-
+- return rc;
+- }
+-
++ enclave_fd = ne_create_vm_ioctl(ne_pci_dev, slot_uid);
+ mutex_unlock(&ne_pci_dev->enclaves_list_mutex);
+
+- if (copy_to_user((void __user *)arg, &slot_uid, sizeof(slot_uid))) {
+- enclave_file = fget(enclave_fd);
+- /* Decrement file refs to have release() called. */
+- fput(enclave_file);
+- fput(enclave_file);
+- put_unused_fd(enclave_fd);
+-
+- return -EFAULT;
+- }
+-
+ return enclave_fd;
+ }
+
+diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c
+index 744b99ddc28ca..a7d9e147dee62 100644
+--- a/fs/btrfs/block-group.c
++++ b/fs/btrfs/block-group.c
+@@ -3269,6 +3269,7 @@ static u64 get_profile_num_devs(struct btrfs_fs_info *fs_info, u64 type)
+ */
+ void check_system_chunk(struct btrfs_trans_handle *trans, u64 type)
+ {
++ struct btrfs_transaction *cur_trans = trans->transaction;
+ struct btrfs_fs_info *fs_info = trans->fs_info;
+ struct btrfs_space_info *info;
+ u64 left;
+@@ -3283,6 +3284,7 @@ void check_system_chunk(struct btrfs_trans_handle *trans, u64 type)
+ lockdep_assert_held(&fs_info->chunk_mutex);
+
+ info = btrfs_find_space_info(fs_info, BTRFS_BLOCK_GROUP_SYSTEM);
++again:
+ spin_lock(&info->lock);
+ left = info->total_bytes - btrfs_space_info_used(info, true);
+ spin_unlock(&info->lock);
+@@ -3301,6 +3303,58 @@ void check_system_chunk(struct btrfs_trans_handle *trans, u64 type)
+
+ if (left < thresh) {
+ u64 flags = btrfs_system_alloc_profile(fs_info);
++ u64 reserved = atomic64_read(&cur_trans->chunk_bytes_reserved);
++
++ /*
++ * If there's not available space for the chunk tree (system
++ * space) and there are other tasks that reserved space for
++ * creating a new system block group, wait for them to complete
++ * the creation of their system block group and release excess
++ * reserved space. We do this because:
++ *
++ * *) We can end up allocating more system chunks than necessary
++ * when there are multiple tasks that are concurrently
++ * allocating block groups, which can lead to exhaustion of
++ * the system array in the superblock;
++ *
++ * *) If we allocate extra and unnecessary system block groups,
++ * despite being empty for a long time, and possibly forever,
++ * they end not being added to the list of unused block groups
++ * because that typically happens only when deallocating the
++ * last extent from a block group - which never happens since
++ * we never allocate from them in the first place. The few
++ * exceptions are when mounting a filesystem or running scrub,
++ * which add unused block groups to the list of unused block
++ * groups, to be deleted by the cleaner kthread.
++ * And even when they are added to the list of unused block
++ * groups, it can take a long time until they get deleted,
++ * since the cleaner kthread might be sleeping or busy with
++ * other work (deleting subvolumes, running delayed iputs,
++ * defrag scheduling, etc);
++ *
++ * This is rare in practice, but can happen when too many tasks
++ * are allocating blocks groups in parallel (via fallocate())
++ * and before the one that reserved space for a new system block
++ * group finishes the block group creation and releases the space
++ * reserved in excess (at btrfs_create_pending_block_groups()),
++ * other tasks end up here and see free system space temporarily
++ * not enough for updating the chunk tree.
++ *
++ * We unlock the chunk mutex before waiting for such tasks and
++ * lock it again after the wait, otherwise we would deadlock.
++ * It is safe to do so because allocating a system chunk is the
++ * first thing done while allocating a new block group.
++ */
++ if (reserved > trans->chunk_bytes_reserved) {
++ const u64 min_needed = reserved - thresh;
++
++ mutex_unlock(&fs_info->chunk_mutex);
++ wait_event(cur_trans->chunk_reserve_wait,
++ atomic64_read(&cur_trans->chunk_bytes_reserved) <=
++ min_needed);
++ mutex_lock(&fs_info->chunk_mutex);
++ goto again;
++ }
+
+ /*
+ * Ignore failure to create system chunk. We might end up not
+@@ -3315,8 +3369,10 @@ void check_system_chunk(struct btrfs_trans_handle *trans, u64 type)
+ ret = btrfs_block_rsv_add(fs_info->chunk_root,
+ &fs_info->chunk_block_rsv,
+ thresh, BTRFS_RESERVE_NO_FLUSH);
+- if (!ret)
++ if (!ret) {
++ atomic64_add(thresh, &cur_trans->chunk_bytes_reserved);
+ trans->chunk_bytes_reserved += thresh;
++ }
+ }
+ }
+
+diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h
+index 28e202e89660f..4189036049362 100644
+--- a/fs/btrfs/btrfs_inode.h
++++ b/fs/btrfs/btrfs_inode.h
+@@ -299,6 +299,21 @@ static inline void btrfs_mod_outstanding_extents(struct btrfs_inode *inode,
+ mod);
+ }
+
++/*
++ * Called every time after doing a buffered, direct IO or memory mapped write.
++ *
++ * This is to ensure that if we write to a file that was previously fsynced in
++ * the current transaction, then try to fsync it again in the same transaction,
++ * we will know that there were changes in the file and that it needs to be
++ * logged.
++ */
++static inline void btrfs_set_inode_last_sub_trans(struct btrfs_inode *inode)
++{
++ spin_lock(&inode->lock);
++ inode->last_sub_trans = inode->root->log_transid;
++ spin_unlock(&inode->lock);
++}
++
+ static inline int btrfs_inode_in_log(struct btrfs_inode *inode, u64 generation)
+ {
+ int ret = 0;
+diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
+index 3f4c832abfed6..81387cdf334da 100644
+--- a/fs/btrfs/compression.c
++++ b/fs/btrfs/compression.c
+@@ -80,10 +80,15 @@ static int compression_compress_pages(int type, struct list_head *ws,
+ case BTRFS_COMPRESS_NONE:
+ default:
+ /*
+- * This can't happen, the type is validated several times
+- * before we get here. As a sane fallback, return what the
+- * callers will understand as 'no compression happened'.
++ * This can happen when compression races with remount setting
++ * it to 'no compress', while caller doesn't call
++ * inode_need_compress() to check if we really need to
++ * compress.
++ *
++ * Not a big deal, just need to inform caller that we
++ * haven't allocated any pages yet.
+ */
++ *out_pages = 0;
+ return -E2BIG;
+ }
+ }
+diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
+index 34b929bd5c1af..f43ce82a6aedc 100644
+--- a/fs/btrfs/ctree.c
++++ b/fs/btrfs/ctree.c
+@@ -1365,10 +1365,30 @@ get_old_root(struct btrfs_root *root, u64 time_seq)
+ "failed to read tree block %llu from get_old_root",
+ logical);
+ } else {
++ struct tree_mod_elem *tm2;
++
+ btrfs_tree_read_lock(old);
+ eb = btrfs_clone_extent_buffer(old);
++ /*
++ * After the lookup for the most recent tree mod operation
++ * above and before we locked and cloned the extent buffer
++ * 'old', a new tree mod log operation may have been added.
++ * So lookup for a more recent one to make sure the number
++ * of mod log operations we replay is consistent with the
++ * number of items we have in the cloned extent buffer,
++ * otherwise we can hit a BUG_ON when rewinding the extent
++ * buffer.
++ */
++ tm2 = tree_mod_log_search(fs_info, logical, time_seq);
+ btrfs_tree_read_unlock(old);
+ free_extent_buffer(old);
++ ASSERT(tm2);
++ ASSERT(tm2 == tm || tm2->seq > tm->seq);
++ if (!tm2 || tm2->seq < tm->seq) {
++ free_extent_buffer(eb);
++ return NULL;
++ }
++ tm = tm2;
+ }
+ } else if (old_root) {
+ eb_root_owner = btrfs_header_owner(eb_root);
+diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c
+index bf25401c97681..c1d2b67861292 100644
+--- a/fs/btrfs/delayed-inode.c
++++ b/fs/btrfs/delayed-inode.c
+@@ -1589,8 +1589,8 @@ bool btrfs_readdir_get_delayed_items(struct inode *inode,
+ * We can only do one readdir with delayed items at a time because of
+ * item->readdir_list.
+ */
+- inode_unlock_shared(inode);
+- inode_lock(inode);
++ btrfs_inode_unlock(inode, BTRFS_ILOCK_SHARED);
++ btrfs_inode_lock(inode, 0);
+
+ mutex_lock(&delayed_node->mutex);
+ item = __btrfs_first_delayed_insertion_item(delayed_node);
+diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
+index 0e155f0138391..6eb72c9b15a7d 100644
+--- a/fs/btrfs/file.c
++++ b/fs/btrfs/file.c
+@@ -2014,14 +2014,8 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb,
+ else
+ num_written = btrfs_buffered_write(iocb, from);
+
+- /*
+- * We also have to set last_sub_trans to the current log transid,
+- * otherwise subsequent syncs to a file that's been synced in this
+- * transaction will appear to have already occurred.
+- */
+- spin_lock(&inode->lock);
+- inode->last_sub_trans = inode->root->log_transid;
+- spin_unlock(&inode->lock);
++ btrfs_set_inode_last_sub_trans(inode);
++
+ if (num_written > 0)
+ num_written = generic_write_sync(iocb, num_written);
+
+@@ -2122,7 +2116,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
+ if (ret)
+ goto out;
+
+- inode_lock(inode);
++ btrfs_inode_lock(inode, 0);
+
+ atomic_inc(&root->log_batch);
+
+@@ -2154,7 +2148,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
+ */
+ ret = start_ordered_ops(inode, start, end);
+ if (ret) {
+- inode_unlock(inode);
++ btrfs_inode_unlock(inode, 0);
+ goto out;
+ }
+
+@@ -2255,7 +2249,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
+ * file again, but that will end up using the synchronization
+ * inside btrfs_sync_log to keep things safe.
+ */
+- inode_unlock(inode);
++ btrfs_inode_unlock(inode, 0);
+
+ if (ret != BTRFS_NO_LOG_SYNC) {
+ if (!ret) {
+@@ -2285,7 +2279,7 @@ out:
+
+ out_release_extents:
+ btrfs_release_log_ctx_extents(&ctx);
+- inode_unlock(inode);
++ btrfs_inode_unlock(inode, 0);
+ goto out;
+ }
+
+@@ -2735,8 +2729,6 @@ int btrfs_replace_file_extents(struct inode *inode, struct btrfs_path *path,
+ extent_info->file_offset += replace_len;
+ }
+
+- cur_offset = drop_args.drop_end;
+-
+ ret = btrfs_update_inode(trans, root, BTRFS_I(inode));
+ if (ret)
+ break;
+@@ -2756,7 +2748,9 @@ int btrfs_replace_file_extents(struct inode *inode, struct btrfs_path *path,
+ BUG_ON(ret); /* shouldn't happen */
+ trans->block_rsv = rsv;
+
+- if (!extent_info) {
++ cur_offset = drop_args.drop_end;
++ len = end - cur_offset;
++ if (!extent_info && len) {
+ ret = find_first_non_hole(BTRFS_I(inode), &cur_offset,
+ &len);
+ if (unlikely(ret < 0))
+@@ -2868,7 +2862,7 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len)
+ if (ret)
+ return ret;
+
+- inode_lock(inode);
++ btrfs_inode_lock(inode, 0);
+ ino_size = round_up(inode->i_size, fs_info->sectorsize);
+ ret = find_first_non_hole(BTRFS_I(inode), &offset, &len);
+ if (ret < 0)
+@@ -2908,7 +2902,7 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len)
+ truncated_block = true;
+ ret = btrfs_truncate_block(BTRFS_I(inode), offset, 0, 0);
+ if (ret) {
+- inode_unlock(inode);
++ btrfs_inode_unlock(inode, 0);
+ return ret;
+ }
+ }
+@@ -3009,7 +3003,7 @@ out_only_mutex:
+ ret = ret2;
+ }
+ }
+- inode_unlock(inode);
++ btrfs_inode_unlock(inode, 0);
+ return ret;
+ }
+
+@@ -3377,7 +3371,7 @@ static long btrfs_fallocate(struct file *file, int mode,
+
+ if (mode & FALLOC_FL_ZERO_RANGE) {
+ ret = btrfs_zero_range(inode, offset, len, mode);
+- inode_unlock(inode);
++ btrfs_inode_unlock(inode, 0);
+ return ret;
+ }
+
+@@ -3487,7 +3481,7 @@ out_unlock:
+ unlock_extent_cached(&BTRFS_I(inode)->io_tree, alloc_start, locked_end,
+ &cached_state);
+ out:
+- inode_unlock(inode);
++ btrfs_inode_unlock(inode, 0);
+ /* Let go of our reservation. */
+ if (ret != 0 && !(mode & FALLOC_FL_ZERO_RANGE))
+ btrfs_free_reserved_data_space(BTRFS_I(inode), data_reserved,
+diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
+index a520775949a07..a922c3bcb65e1 100644
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -8619,9 +8619,7 @@ again:
+ set_page_dirty(page);
+ SetPageUptodate(page);
+
+- BTRFS_I(inode)->last_trans = fs_info->generation;
+- BTRFS_I(inode)->last_sub_trans = BTRFS_I(inode)->root->log_transid;
+- BTRFS_I(inode)->last_log_commit = BTRFS_I(inode)->root->last_log_commit;
++ btrfs_set_inode_last_sub_trans(BTRFS_I(inode));
+
+ unlock_extent_cached(io_tree, page_start, page_end, &cached_state);
+
+diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
+index e8d53fea4c61a..5efd6c7fe6206 100644
+--- a/fs/btrfs/ioctl.c
++++ b/fs/btrfs/ioctl.c
+@@ -226,7 +226,7 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
+ if (ret)
+ return ret;
+
+- inode_lock(inode);
++ btrfs_inode_lock(inode, 0);
+ fsflags = btrfs_mask_fsflags_for_type(inode, fsflags);
+ old_fsflags = btrfs_inode_flags_to_fsflags(binode->flags);
+
+@@ -353,7 +353,7 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
+ out_end_trans:
+ btrfs_end_transaction(trans);
+ out_unlock:
+- inode_unlock(inode);
++ btrfs_inode_unlock(inode, 0);
+ mnt_drop_write_file(file);
+ return ret;
+ }
+@@ -449,7 +449,7 @@ static int btrfs_ioctl_fssetxattr(struct file *file, void __user *arg)
+ if (ret)
+ return ret;
+
+- inode_lock(inode);
++ btrfs_inode_lock(inode, 0);
+
+ old_flags = binode->flags;
+ old_i_flags = inode->i_flags;
+@@ -501,7 +501,7 @@ out_unlock:
+ inode->i_flags = old_i_flags;
+ }
+
+- inode_unlock(inode);
++ btrfs_inode_unlock(inode, 0);
+ mnt_drop_write_file(file);
+
+ return ret;
+@@ -697,8 +697,6 @@ static noinline int create_subvol(struct inode *dir,
+ btrfs_set_root_otransid(root_item, trans->transid);
+
+ btrfs_tree_unlock(leaf);
+- free_extent_buffer(leaf);
+- leaf = NULL;
+
+ btrfs_set_root_dirid(root_item, BTRFS_FIRST_FREE_OBJECTID);
+
+@@ -707,8 +705,22 @@ static noinline int create_subvol(struct inode *dir,
+ key.type = BTRFS_ROOT_ITEM_KEY;
+ ret = btrfs_insert_root(trans, fs_info->tree_root, &key,
+ root_item);
+- if (ret)
++ if (ret) {
++ /*
++ * Since we don't abort the transaction in this case, free the
++ * tree block so that we don't leak space and leave the
++ * filesystem in an inconsistent state (an extent item in the
++ * extent tree without backreferences). Also no need to have
++ * the tree block locked since it is not in any tree at this
++ * point, so no other task can find it and use it.
++ */
++ btrfs_free_tree_block(trans, root, leaf, 0, 1);
++ free_extent_buffer(leaf);
+ goto fail;
++ }
++
++ free_extent_buffer(leaf);
++ leaf = NULL;
+
+ key.offset = (u64)-1;
+ new_root = btrfs_get_new_fs_root(fs_info, objectid, anon_dev);
+@@ -1014,7 +1026,7 @@ out_up_read:
+ out_dput:
+ dput(dentry);
+ out_unlock:
+- inode_unlock(dir);
++ btrfs_inode_unlock(dir, 0);
+ return error;
+ }
+
+@@ -1612,7 +1624,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
+ ra_index += cluster;
+ }
+
+- inode_lock(inode);
++ btrfs_inode_lock(inode, 0);
+ if (IS_SWAPFILE(inode)) {
+ ret = -ETXTBSY;
+ } else {
+@@ -1621,13 +1633,13 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
+ ret = cluster_pages_for_defrag(inode, pages, i, cluster);
+ }
+ if (ret < 0) {
+- inode_unlock(inode);
++ btrfs_inode_unlock(inode, 0);
+ goto out_ra;
+ }
+
+ defrag_count += ret;
+ balance_dirty_pages_ratelimited(inode->i_mapping);
+- inode_unlock(inode);
++ btrfs_inode_unlock(inode, 0);
+
+ if (newer_than) {
+ if (newer_off == (u64)-1)
+@@ -1675,9 +1687,9 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
+
+ out_ra:
+ if (do_compress) {
+- inode_lock(inode);
++ btrfs_inode_lock(inode, 0);
+ BTRFS_I(inode)->defrag_compress = BTRFS_COMPRESS_NONE;
+- inode_unlock(inode);
++ btrfs_inode_unlock(inode, 0);
+ }
+ if (!file)
+ kfree(ra);
+@@ -3112,9 +3124,9 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,
+ goto out_dput;
+ }
+
+- inode_lock(inode);
++ btrfs_inode_lock(inode, 0);
+ err = btrfs_delete_subvolume(dir, dentry);
+- inode_unlock(inode);
++ btrfs_inode_unlock(inode, 0);
+ if (!err) {
+ fsnotify_rmdir(dir, dentry);
+ d_delete(dentry);
+@@ -3123,7 +3135,7 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,
+ out_dput:
+ dput(dentry);
+ out_unlock_dir:
+- inode_unlock(dir);
++ btrfs_inode_unlock(dir, 0);
+ free_subvol_name:
+ kfree(subvol_name_ptr);
+ free_parent:
+diff --git a/fs/btrfs/reflink.c b/fs/btrfs/reflink.c
+index 762881b777b3b..0abbf050580d1 100644
+--- a/fs/btrfs/reflink.c
++++ b/fs/btrfs/reflink.c
+@@ -833,7 +833,7 @@ loff_t btrfs_remap_file_range(struct file *src_file, loff_t off,
+ return -EINVAL;
+
+ if (same_inode)
+- inode_lock(src_inode);
++ btrfs_inode_lock(src_inode, 0);
+ else
+ lock_two_nondirectories(src_inode, dst_inode);
+
+@@ -849,7 +849,7 @@ loff_t btrfs_remap_file_range(struct file *src_file, loff_t off,
+
+ out_unlock:
+ if (same_inode)
+- inode_unlock(src_inode);
++ btrfs_inode_unlock(src_inode, 0);
+ else
+ unlock_two_nondirectories(src_inode, dst_inode);
+
+diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
+index 232d5da7b7bef..829dc8dcc1514 100644
+--- a/fs/btrfs/relocation.c
++++ b/fs/btrfs/relocation.c
+@@ -733,10 +733,12 @@ static struct btrfs_root *create_reloc_root(struct btrfs_trans_handle *trans,
+ struct extent_buffer *eb;
+ struct btrfs_root_item *root_item;
+ struct btrfs_key root_key;
+- int ret;
++ int ret = 0;
++ bool must_abort = false;
+
+ root_item = kmalloc(sizeof(*root_item), GFP_NOFS);
+- BUG_ON(!root_item);
++ if (!root_item)
++ return ERR_PTR(-ENOMEM);
+
+ root_key.objectid = BTRFS_TREE_RELOC_OBJECTID;
+ root_key.type = BTRFS_ROOT_ITEM_KEY;
+@@ -748,7 +750,9 @@ static struct btrfs_root *create_reloc_root(struct btrfs_trans_handle *trans,
+ /* called by btrfs_init_reloc_root */
+ ret = btrfs_copy_root(trans, root, root->commit_root, &eb,
+ BTRFS_TREE_RELOC_OBJECTID);
+- BUG_ON(ret);
++ if (ret)
++ goto fail;
++
+ /*
+ * Set the last_snapshot field to the generation of the commit
+ * root - like this ctree.c:btrfs_block_can_be_shared() behaves
+@@ -769,9 +773,16 @@ static struct btrfs_root *create_reloc_root(struct btrfs_trans_handle *trans,
+ */
+ ret = btrfs_copy_root(trans, root, root->node, &eb,
+ BTRFS_TREE_RELOC_OBJECTID);
+- BUG_ON(ret);
++ if (ret)
++ goto fail;
+ }
+
++ /*
++ * We have changed references at this point, we must abort the
++ * transaction if anything fails.
++ */
++ must_abort = true;
++
+ memcpy(root_item, &root->root_item, sizeof(*root_item));
+ btrfs_set_root_bytenr(root_item, eb->start);
+ btrfs_set_root_level(root_item, btrfs_header_level(eb));
+@@ -789,14 +800,25 @@ static struct btrfs_root *create_reloc_root(struct btrfs_trans_handle *trans,
+
+ ret = btrfs_insert_root(trans, fs_info->tree_root,
+ &root_key, root_item);
+- BUG_ON(ret);
++ if (ret)
++ goto fail;
++
+ kfree(root_item);
+
+ reloc_root = btrfs_read_tree_root(fs_info->tree_root, &root_key);
+- BUG_ON(IS_ERR(reloc_root));
++ if (IS_ERR(reloc_root)) {
++ ret = PTR_ERR(reloc_root);
++ goto abort;
++ }
+ set_bit(BTRFS_ROOT_SHAREABLE, &reloc_root->state);
+ reloc_root->last_trans = trans->transid;
+ return reloc_root;
++fail:
++ kfree(root_item);
++abort:
++ if (must_abort)
++ btrfs_abort_transaction(trans, ret);
++ return ERR_PTR(ret);
+ }
+
+ /*
+@@ -875,7 +897,7 @@ int btrfs_update_reloc_root(struct btrfs_trans_handle *trans,
+ int ret;
+
+ if (!have_reloc_root(root))
+- goto out;
++ return 0;
+
+ reloc_root = root->reloc_root;
+ root_item = &reloc_root->root_item;
+@@ -908,10 +930,8 @@ int btrfs_update_reloc_root(struct btrfs_trans_handle *trans,
+
+ ret = btrfs_update_root(trans, fs_info->tree_root,
+ &reloc_root->root_key, root_item);
+- BUG_ON(ret);
+ btrfs_put_root(reloc_root);
+-out:
+- return 0;
++ return ret;
+ }
+
+ /*
+@@ -1185,8 +1205,8 @@ int replace_path(struct btrfs_trans_handle *trans, struct reloc_control *rc,
+ int ret;
+ int slot;
+
+- BUG_ON(src->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID);
+- BUG_ON(dest->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID);
++ ASSERT(src->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID);
++ ASSERT(dest->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID);
+
+ last_snapshot = btrfs_root_last_snapshot(&src->root_item);
+ again:
+@@ -1217,7 +1237,7 @@ again:
+ parent = eb;
+ while (1) {
+ level = btrfs_header_level(parent);
+- BUG_ON(level < lowest_level);
++ ASSERT(level >= lowest_level);
+
+ ret = btrfs_bin_search(parent, &key, &slot);
+ if (ret < 0)
+@@ -2578,7 +2598,7 @@ static noinline_for_stack int prealloc_file_extent_cluster(
+ return btrfs_end_transaction(trans);
+ }
+
+- inode_lock(&inode->vfs_inode);
++ btrfs_inode_lock(&inode->vfs_inode, 0);
+ for (nr = 0; nr < cluster->nr; nr++) {
+ start = cluster->boundary[nr] - offset;
+ if (nr + 1 < cluster->nr)
+@@ -2596,7 +2616,7 @@ static noinline_for_stack int prealloc_file_extent_cluster(
+ if (ret)
+ break;
+ }
+- inode_unlock(&inode->vfs_inode);
++ btrfs_inode_unlock(&inode->vfs_inode, 0);
+
+ if (cur_offset < prealloc_end)
+ btrfs_free_reserved_data_space_noquota(inode->root->fs_info,
+diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
+index 3d9088eab2fca..b9202a1f1af10 100644
+--- a/fs/btrfs/scrub.c
++++ b/fs/btrfs/scrub.c
+@@ -3682,8 +3682,8 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx,
+ spin_lock(&cache->lock);
+ if (!cache->to_copy) {
+ spin_unlock(&cache->lock);
+- ro_set = 0;
+- goto done;
++ btrfs_put_block_group(cache);
++ goto skip;
+ }
+ spin_unlock(&cache->lock);
+ }
+@@ -3841,7 +3841,6 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx,
+ cache, found_key.offset))
+ ro_set = 0;
+
+-done:
+ down_write(&dev_replace->rwsem);
+ dev_replace->cursor_left = dev_replace->cursor_right;
+ dev_replace->item_needs_writeback = 1;
+diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
+index acff6bb49a97b..d56d3e7ca3240 100644
+--- a/fs/btrfs/transaction.c
++++ b/fs/btrfs/transaction.c
+@@ -260,6 +260,7 @@ static inline int extwriter_counter_read(struct btrfs_transaction *trans)
+ void btrfs_trans_release_chunk_metadata(struct btrfs_trans_handle *trans)
+ {
+ struct btrfs_fs_info *fs_info = trans->fs_info;
++ struct btrfs_transaction *cur_trans = trans->transaction;
+
+ if (!trans->chunk_bytes_reserved)
+ return;
+@@ -268,6 +269,8 @@ void btrfs_trans_release_chunk_metadata(struct btrfs_trans_handle *trans)
+
+ btrfs_block_rsv_release(fs_info, &fs_info->chunk_block_rsv,
+ trans->chunk_bytes_reserved, NULL);
++ atomic64_sub(trans->chunk_bytes_reserved, &cur_trans->chunk_bytes_reserved);
++ cond_wake_up(&cur_trans->chunk_reserve_wait);
+ trans->chunk_bytes_reserved = 0;
+ }
+
+@@ -383,6 +386,8 @@ loop:
+ spin_lock_init(&cur_trans->dropped_roots_lock);
+ INIT_LIST_HEAD(&cur_trans->releasing_ebs);
+ spin_lock_init(&cur_trans->releasing_ebs_lock);
++ atomic64_set(&cur_trans->chunk_bytes_reserved, 0);
++ init_waitqueue_head(&cur_trans->chunk_reserve_wait);
+ list_add_tail(&cur_trans->list, &fs_info->trans_list);
+ extent_io_tree_init(fs_info, &cur_trans->dirty_pages,
+ IO_TREE_TRANS_DIRTY_PAGES, fs_info->btree_inode);
+@@ -1961,7 +1966,6 @@ static void cleanup_transaction(struct btrfs_trans_handle *trans, int err)
+ */
+ BUG_ON(list_empty(&cur_trans->list));
+
+- list_del_init(&cur_trans->list);
+ if (cur_trans == fs_info->running_transaction) {
+ cur_trans->state = TRANS_STATE_COMMIT_DOING;
+ spin_unlock(&fs_info->trans_lock);
+@@ -1970,6 +1974,17 @@ static void cleanup_transaction(struct btrfs_trans_handle *trans, int err)
+
+ spin_lock(&fs_info->trans_lock);
+ }
++
++ /*
++ * Now that we know no one else is still using the transaction we can
++ * remove the transaction from the list of transactions. This avoids
++ * the transaction kthread from cleaning up the transaction while some
++ * other task is still using it, which could result in a use-after-free
++ * on things like log trees, as it forces the transaction kthread to
++ * wait for this transaction to be cleaned up by us.
++ */
++ list_del_init(&cur_trans->list);
++
+ spin_unlock(&fs_info->trans_lock);
+
+ btrfs_cleanup_one_transaction(trans->transaction, fs_info);
+diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h
+index 6335716e513ff..364cfbb4c5c59 100644
+--- a/fs/btrfs/transaction.h
++++ b/fs/btrfs/transaction.h
+@@ -96,6 +96,13 @@ struct btrfs_transaction {
+
+ spinlock_t releasing_ebs_lock;
+ struct list_head releasing_ebs;
++
++ /*
++ * The number of bytes currently reserved, by all transaction handles
++ * attached to this transaction, for metadata extents of the chunk tree.
++ */
++ atomic64_t chunk_bytes_reserved;
++ wait_queue_head_t chunk_reserve_wait;
+ };
+
+ #define __TRANS_FREEZABLE (1U << 0)
+@@ -175,7 +182,7 @@ static inline void btrfs_set_inode_last_trans(struct btrfs_trans_handle *trans,
+ spin_lock(&inode->lock);
+ inode->last_trans = trans->transaction->transid;
+ inode->last_sub_trans = inode->root->log_transid;
+- inode->last_log_commit = inode->root->last_log_commit;
++ inode->last_log_commit = inode->last_sub_trans - 1;
+ spin_unlock(&inode->lock);
+ }
+
+diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c
+index eeb3ebe11d7ae..70b23a0d03b10 100644
+--- a/fs/btrfs/zoned.c
++++ b/fs/btrfs/zoned.c
+@@ -342,6 +342,13 @@ int btrfs_get_dev_zone_info(struct btrfs_device *device)
+ if (!IS_ALIGNED(nr_sectors, zone_sectors))
+ zone_info->nr_zones++;
+
++ if (bdev_is_zoned(bdev) && zone_info->max_zone_append_size == 0) {
++ btrfs_err(fs_info, "zoned: device %pg does not support zone append",
++ bdev);
++ ret = -EINVAL;
++ goto out;
++ }
++
+ zone_info->seq_zones = bitmap_zalloc(zone_info->nr_zones, GFP_KERNEL);
+ if (!zone_info->seq_zones) {
+ ret = -ENOMEM;
+diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
+index 5ddd20b62484d..fa896a1c8b075 100644
+--- a/fs/cifs/cifsfs.c
++++ b/fs/cifs/cifsfs.c
+@@ -834,7 +834,7 @@ cifs_smb3_do_mount(struct file_system_type *fs_type,
+ goto out;
+ }
+
+- rc = cifs_setup_volume_info(cifs_sb->ctx, NULL, old_ctx->UNC);
++ rc = cifs_setup_volume_info(cifs_sb->ctx, NULL, NULL);
+ if (rc) {
+ root = ERR_PTR(rc);
+ goto out;
+diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
+index 24668eb006c63..3d62d52d730b5 100644
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -488,6 +488,7 @@ server_unresponsive(struct TCP_Server_Info *server)
+ */
+ if ((server->tcpStatus == CifsGood ||
+ server->tcpStatus == CifsNeedNegotiate) &&
++ (!server->ops->can_echo || server->ops->can_echo(server)) &&
+ time_after(jiffies, server->lstrp + 3 * server->echo_interval)) {
+ cifs_server_dbg(VFS, "has not responded in %lu seconds. Reconnecting...\n",
+ (3 * server->echo_interval) / HZ);
+@@ -3175,17 +3176,29 @@ out:
+ int
+ cifs_setup_volume_info(struct smb3_fs_context *ctx, const char *mntopts, const char *devname)
+ {
+- int rc = 0;
++ int rc;
+
+- smb3_parse_devname(devname, ctx);
++ if (devname) {
++ cifs_dbg(FYI, "%s: devname=%s\n", __func__, devname);
++ rc = smb3_parse_devname(devname, ctx);
++ if (rc) {
++ cifs_dbg(VFS, "%s: failed to parse %s: %d\n", __func__, devname, rc);
++ return rc;
++ }
++ }
+
+ if (mntopts) {
+ char *ip;
+
+- cifs_dbg(FYI, "%s: mntopts=%s\n", __func__, mntopts);
+ rc = smb3_parse_opt(mntopts, "ip", &ip);
+- if (!rc && !cifs_convert_address((struct sockaddr *)&ctx->dstaddr, ip,
+- strlen(ip))) {
++ if (rc) {
++ cifs_dbg(VFS, "%s: failed to parse ip options: %d\n", __func__, rc);
++ return rc;
++ }
++
++ rc = cifs_convert_address((struct sockaddr *)&ctx->dstaddr, ip, strlen(ip));
++ kfree(ip);
++ if (!rc) {
+ cifs_dbg(VFS, "%s: failed to convert ip address\n", __func__);
+ return -EINVAL;
+ }
+@@ -3205,7 +3218,7 @@ cifs_setup_volume_info(struct smb3_fs_context *ctx, const char *mntopts, const c
+ return -EINVAL;
+ }
+
+- return rc;
++ return 0;
+ }
+
+ static int
+diff --git a/fs/cifs/fs_context.c b/fs/cifs/fs_context.c
+index 78889024a7ed0..a7253eb2e9559 100644
+--- a/fs/cifs/fs_context.c
++++ b/fs/cifs/fs_context.c
+@@ -475,6 +475,7 @@ smb3_parse_devname(const char *devname, struct smb3_fs_context *ctx)
+
+ /* move "pos" up to delimiter or NULL */
+ pos += len;
++ kfree(ctx->UNC);
+ ctx->UNC = kstrndup(devname, pos - devname, GFP_KERNEL);
+ if (!ctx->UNC)
+ return -ENOMEM;
+@@ -485,6 +486,9 @@ smb3_parse_devname(const char *devname, struct smb3_fs_context *ctx)
+ if (*pos == '/' || *pos == '\\')
+ pos++;
+
++ kfree(ctx->prepath);
++ ctx->prepath = NULL;
++
+ /* If pos is NULL then no prepath */
+ if (!*pos)
+ return 0;
+@@ -995,6 +999,9 @@ static int smb3_fs_context_parse_param(struct fs_context *fc,
+ goto cifs_parse_mount_err;
+ }
+ ctx->max_channels = result.uint_32;
++ /* If more than one channel requested ... they want multichan */
++ if (result.uint_32 > 1)
++ ctx->multichannel = true;
+ break;
+ case Opt_handletimeout:
+ ctx->handle_timeout = result.uint_32;
+diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
+index 63d517b9f2ffe..a92a1fb7cb526 100644
+--- a/fs/cifs/sess.c
++++ b/fs/cifs/sess.c
+@@ -97,6 +97,12 @@ int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses)
+ return 0;
+ }
+
++ if (!(ses->server->capabilities & SMB2_GLOBAL_CAP_MULTI_CHANNEL)) {
++ cifs_dbg(VFS, "server %s does not support multichannel\n", ses->server->hostname);
++ ses->chan_max = 1;
++ return 0;
++ }
++
+ /*
+ * Make a copy of the iface list at the time and use that
+ * instead so as to not hold the iface spinlock for opening
+diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
+index f703204fb185d..5df6daacc230b 100644
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -1763,18 +1763,14 @@ smb2_ioctl_query_info(const unsigned int xid,
+ }
+
+ iqinf_exit:
+- kfree(vars);
+- kfree(buffer);
+- SMB2_open_free(&rqst[0]);
+- if (qi.flags & PASSTHRU_FSCTL)
+- SMB2_ioctl_free(&rqst[1]);
+- else
+- SMB2_query_info_free(&rqst[1]);
+-
+- SMB2_close_free(&rqst[2]);
++ cifs_small_buf_release(rqst[0].rq_iov[0].iov_base);
++ cifs_small_buf_release(rqst[1].rq_iov[0].iov_base);
++ cifs_small_buf_release(rqst[2].rq_iov[0].iov_base);
+ free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base);
+ free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
+ free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base);
++ kfree(vars);
++ kfree(buffer);
+ return rc;
+
+ e_fault:
+@@ -2232,7 +2228,7 @@ smb3_notify(const unsigned int xid, struct file *pfile,
+
+ cifs_sb = CIFS_SB(inode->i_sb);
+
+- utf16_path = cifs_convert_path_to_utf16(path + 1, cifs_sb);
++ utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
+ if (utf16_path == NULL) {
+ rc = -ENOMEM;
+ goto notify_exit;
+@@ -4178,7 +4174,7 @@ smb2_get_enc_key(struct TCP_Server_Info *server, __u64 ses_id, int enc, u8 *key)
+ }
+ spin_unlock(&cifs_tcp_ses_lock);
+
+- return 1;
++ return -EAGAIN;
+ }
+ /*
+ * Encrypt or decrypt @rqst message. @rqst[0] has the following format:
+diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
+index 2199a9bfae8f7..29272d99102c5 100644
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -841,6 +841,8 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses)
+ req->SecurityMode = 0;
+
+ req->Capabilities = cpu_to_le32(server->vals->req_capabilities);
++ if (ses->chan_max > 1)
++ req->Capabilities |= cpu_to_le32(SMB2_GLOBAL_CAP_MULTI_CHANNEL);
+
+ /* ClientGUID must be zero for SMB2.02 dialect */
+ if (server->vals->protocol_id == SMB20_PROT_ID)
+@@ -1032,6 +1034,9 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon)
+
+ pneg_inbuf->Capabilities =
+ cpu_to_le32(server->vals->req_capabilities);
++ if (tcon->ses->chan_max > 1)
++ pneg_inbuf->Capabilities |= cpu_to_le32(SMB2_GLOBAL_CAP_MULTI_CHANNEL);
++
+ memcpy(pneg_inbuf->Guid, server->client_guid,
+ SMB2_CLIENT_GUID_SIZE);
+
+diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
+index cdf40a54a35d8..cf772c72ab2b8 100644
+--- a/fs/ecryptfs/main.c
++++ b/fs/ecryptfs/main.c
+@@ -492,6 +492,12 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags
+ goto out;
+ }
+
++ if (!dev_name) {
++ rc = -EINVAL;
++ err = "Device name cannot be null";
++ goto out;
++ }
++
+ rc = ecryptfs_parse_options(sbi, raw_data, &check_ruid);
+ if (rc) {
+ err = "Error parsing options";
+diff --git a/fs/erofs/erofs_fs.h b/fs/erofs/erofs_fs.h
+index 9ad1615f44743..e8d04d808fa62 100644
+--- a/fs/erofs/erofs_fs.h
++++ b/fs/erofs/erofs_fs.h
+@@ -75,6 +75,9 @@ static inline bool erofs_inode_is_data_compressed(unsigned int datamode)
+ #define EROFS_I_VERSION_BIT 0
+ #define EROFS_I_DATALAYOUT_BIT 1
+
++#define EROFS_I_ALL \
++ ((1 << (EROFS_I_DATALAYOUT_BIT + EROFS_I_DATALAYOUT_BITS)) - 1)
++
+ /* 32-byte reduced form of an ondisk inode */
+ struct erofs_inode_compact {
+ __le16 i_format; /* inode format hints */
+diff --git a/fs/erofs/inode.c b/fs/erofs/inode.c
+index 119fdce1b5207..7ed2d73916928 100644
+--- a/fs/erofs/inode.c
++++ b/fs/erofs/inode.c
+@@ -44,6 +44,13 @@ static struct page *erofs_read_inode(struct inode *inode,
+ dic = page_address(page) + *ofs;
+ ifmt = le16_to_cpu(dic->i_format);
+
++ if (ifmt & ~EROFS_I_ALL) {
++ erofs_err(inode->i_sb, "unsupported i_format %u of nid %llu",
++ ifmt, vi->nid);
++ err = -EOPNOTSUPP;
++ goto err_out;
++ }
++
+ vi->datalayout = erofs_inode_datalayout(ifmt);
+ if (vi->datalayout >= EROFS_INODE_DATALAYOUT_MAX) {
+ erofs_err(inode->i_sb, "unsupported datalayout %u of nid %llu",
+diff --git a/fs/eventpoll.c b/fs/eventpoll.c
+index 3196474cbe24c..e42477fcbfa05 100644
+--- a/fs/eventpoll.c
++++ b/fs/eventpoll.c
+@@ -657,6 +657,12 @@ static void ep_done_scan(struct eventpoll *ep,
+ */
+ list_splice(txlist, &ep->rdllist);
+ __pm_relax(ep->ws);
++
++ if (!list_empty(&ep->rdllist)) {
++ if (waitqueue_active(&ep->wq))
++ wake_up(&ep->wq);
++ }
++
+ write_unlock_irq(&ep->lock);
+ }
+
+diff --git a/fs/exfat/balloc.c b/fs/exfat/balloc.c
+index 761c79c3a4ba2..411fb0a8da10d 100644
+--- a/fs/exfat/balloc.c
++++ b/fs/exfat/balloc.c
+@@ -141,10 +141,6 @@ void exfat_free_bitmap(struct exfat_sb_info *sbi)
+ kfree(sbi->vol_amap);
+ }
+
+-/*
+- * If the value of "clu" is 0, it means cluster 2 which is the first cluster of
+- * the cluster heap.
+- */
+ int exfat_set_bitmap(struct inode *inode, unsigned int clu)
+ {
+ int i, b;
+@@ -162,10 +158,6 @@ int exfat_set_bitmap(struct inode *inode, unsigned int clu)
+ return 0;
+ }
+
+-/*
+- * If the value of "clu" is 0, it means cluster 2 which is the first cluster of
+- * the cluster heap.
+- */
+ void exfat_clear_bitmap(struct inode *inode, unsigned int clu, bool sync)
+ {
+ int i, b;
+@@ -186,8 +178,7 @@ void exfat_clear_bitmap(struct inode *inode, unsigned int clu, bool sync)
+ int ret_discard;
+
+ ret_discard = sb_issue_discard(sb,
+- exfat_cluster_to_sector(sbi, clu +
+- EXFAT_RESERVED_CLUSTERS),
++ exfat_cluster_to_sector(sbi, clu),
+ (1 << sbi->sect_per_clus_bits), GFP_NOFS, 0);
+
+ if (ret_discard == -EOPNOTSUPP) {
+diff --git a/fs/ext4/fast_commit.c b/fs/ext4/fast_commit.c
+index 7541d0b5d7069..312273ed8a9fe 100644
+--- a/fs/ext4/fast_commit.c
++++ b/fs/ext4/fast_commit.c
+@@ -1088,8 +1088,10 @@ static int ext4_fc_perform_commit(journal_t *journal)
+ head.fc_tid = cpu_to_le32(
+ sbi->s_journal->j_running_transaction->t_tid);
+ if (!ext4_fc_add_tlv(sb, EXT4_FC_TAG_HEAD, sizeof(head),
+- (u8 *)&head, &crc))
++ (u8 *)&head, &crc)) {
++ ret = -ENOSPC;
+ goto out;
++ }
+ }
+
+ spin_lock(&sbi->s_fc_lock);
+diff --git a/fs/ext4/file.c b/fs/ext4/file.c
+index 194f5d00fa326..7924634ab0bfe 100644
+--- a/fs/ext4/file.c
++++ b/fs/ext4/file.c
+@@ -371,15 +371,32 @@ truncate:
+ static int ext4_dio_write_end_io(struct kiocb *iocb, ssize_t size,
+ int error, unsigned int flags)
+ {
+- loff_t offset = iocb->ki_pos;
++ loff_t pos = iocb->ki_pos;
+ struct inode *inode = file_inode(iocb->ki_filp);
+
+ if (error)
+ return error;
+
+- if (size && flags & IOMAP_DIO_UNWRITTEN)
+- return ext4_convert_unwritten_extents(NULL, inode,
+- offset, size);
++ if (size && flags & IOMAP_DIO_UNWRITTEN) {
++ error = ext4_convert_unwritten_extents(NULL, inode, pos, size);
++ if (error < 0)
++ return error;
++ }
++ /*
++ * If we are extending the file, we have to update i_size here before
++ * page cache gets invalidated in iomap_dio_rw(). Otherwise racing
++ * buffered reads could zero out too much from page cache pages. Update
++ * of on-disk size will happen later in ext4_dio_write_iter() where
++ * we have enough information to also perform orphan list handling etc.
++ * Note that we perform all extending writes synchronously under
++ * i_rwsem held exclusively so i_size update is safe here in that case.
++ * If the write was not extending, we cannot see pos > i_size here
++ * because operations reducing i_size like truncate wait for all
++ * outstanding DIO before updating i_size.
++ */
++ pos += size;
++ if (pos > i_size_read(inode))
++ i_size_write(inode, pos);
+
+ return 0;
+ }
+diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
+index 633ae7becd61f..71d321b3b9844 100644
+--- a/fs/ext4/ialloc.c
++++ b/fs/ext4/ialloc.c
+@@ -1292,7 +1292,8 @@ got:
+
+ ei->i_extra_isize = sbi->s_want_extra_isize;
+ ei->i_inline_off = 0;
+- if (ext4_has_feature_inline_data(sb))
++ if (ext4_has_feature_inline_data(sb) &&
++ (!(ei->i_flags & EXT4_DAX_FL) || S_ISDIR(mode)))
+ ext4_set_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA);
+ ret = inode;
+ err = dquot_alloc_inode(inode);
+@@ -1513,6 +1514,7 @@ int ext4_init_inode_table(struct super_block *sb, ext4_group_t group,
+ handle_t *handle;
+ ext4_fsblk_t blk;
+ int num, ret = 0, used_blks = 0;
++ unsigned long used_inos = 0;
+
+ /* This should not happen, but just to be sure check this */
+ if (sb_rdonly(sb)) {
+@@ -1543,22 +1545,37 @@ int ext4_init_inode_table(struct super_block *sb, ext4_group_t group,
+ * used inodes so we need to skip blocks with used inodes in
+ * inode table.
+ */
+- if (!(gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)))
+- used_blks = DIV_ROUND_UP((EXT4_INODES_PER_GROUP(sb) -
+- ext4_itable_unused_count(sb, gdp)),
+- sbi->s_inodes_per_block);
+-
+- if ((used_blks < 0) || (used_blks > sbi->s_itb_per_group) ||
+- ((group == 0) && ((EXT4_INODES_PER_GROUP(sb) -
+- ext4_itable_unused_count(sb, gdp)) <
+- EXT4_FIRST_INO(sb)))) {
+- ext4_error(sb, "Something is wrong with group %u: "
+- "used itable blocks: %d; "
+- "itable unused count: %u",
+- group, used_blks,
+- ext4_itable_unused_count(sb, gdp));
+- ret = 1;
+- goto err_out;
++ if (!(gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT))) {
++ used_inos = EXT4_INODES_PER_GROUP(sb) -
++ ext4_itable_unused_count(sb, gdp);
++ used_blks = DIV_ROUND_UP(used_inos, sbi->s_inodes_per_block);
++
++ /* Bogus inode unused count? */
++ if (used_blks < 0 || used_blks > sbi->s_itb_per_group) {
++ ext4_error(sb, "Something is wrong with group %u: "
++ "used itable blocks: %d; "
++ "itable unused count: %u",
++ group, used_blks,
++ ext4_itable_unused_count(sb, gdp));
++ ret = 1;
++ goto err_out;
++ }
++
++ used_inos += group * EXT4_INODES_PER_GROUP(sb);
++ /*
++ * Are there some uninitialized inodes in the inode table
++ * before the first normal inode?
++ */
++ if ((used_blks != sbi->s_itb_per_group) &&
++ (used_inos < EXT4_FIRST_INO(sb))) {
++ ext4_error(sb, "Something is wrong with group %u: "
++ "itable unused count: %u; "
++ "itables initialized count: %ld",
++ group, ext4_itable_unused_count(sb, gdp),
++ used_inos);
++ ret = 1;
++ goto err_out;
++ }
+ }
+
+ blk = ext4_inode_table(sb, gdp) + used_blks;
+diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
+index a2cf35066f46b..0796bfa72829c 100644
+--- a/fs/ext4/ioctl.c
++++ b/fs/ext4/ioctl.c
+@@ -315,6 +315,12 @@ static void ext4_dax_dontcache(struct inode *inode, unsigned int flags)
+ static bool dax_compatible(struct inode *inode, unsigned int oldflags,
+ unsigned int flags)
+ {
++ /* Allow the DAX flag to be changed on inline directories */
++ if (S_ISDIR(inode->i_mode)) {
++ flags &= ~EXT4_INLINE_DATA_FL;
++ oldflags &= ~EXT4_INLINE_DATA_FL;
++ }
++
+ if (flags & EXT4_DAX_FL) {
+ if ((oldflags & EXT4_DAX_MUT_EXCL) ||
+ ext4_test_inode_state(inode,
+diff --git a/fs/ext4/mmp.c b/fs/ext4/mmp.c
+index 795c3ff2907c2..68fbeedd627bc 100644
+--- a/fs/ext4/mmp.c
++++ b/fs/ext4/mmp.c
+@@ -56,7 +56,7 @@ static int write_mmp_block(struct super_block *sb, struct buffer_head *bh)
+ wait_on_buffer(bh);
+ sb_end_write(sb);
+ if (unlikely(!buffer_uptodate(bh)))
+- return 1;
++ return -EIO;
+
+ return 0;
+ }
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index b9693680463aa..77c1cb2582623 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -667,9 +667,6 @@ static void ext4_handle_error(struct super_block *sb, bool force_ro, int error,
+ ext4_commit_super(sb);
+ }
+
+- if (sb_rdonly(sb) || continue_fs)
+- return;
+-
+ /*
+ * We force ERRORS_RO behavior when system is rebooting. Otherwise we
+ * could panic during 'reboot -f' as the underlying device got already
+@@ -679,6 +676,10 @@ static void ext4_handle_error(struct super_block *sb, bool force_ro, int error,
+ panic("EXT4-fs (device %s): panic forced after error\n",
+ sb->s_id);
+ }
++
++ if (sb_rdonly(sb) || continue_fs)
++ return;
++
+ ext4_msg(sb, KERN_CRIT, "Remounting filesystem read-only");
+ /*
+ * Make sure updated value of ->s_mount_flags will be visible before
+@@ -3023,9 +3024,6 @@ static void ext4_orphan_cleanup(struct super_block *sb,
+ sb->s_flags &= ~SB_RDONLY;
+ }
+ #ifdef CONFIG_QUOTA
+- /* Needed for iput() to work correctly and not trash data */
+- sb->s_flags |= SB_ACTIVE;
+-
+ /*
+ * Turn on quotas which were not enabled for read-only mounts if
+ * filesystem has quota feature, so that they are updated correctly.
+@@ -5561,8 +5559,10 @@ static int ext4_commit_super(struct super_block *sb)
+ struct buffer_head *sbh = EXT4_SB(sb)->s_sbh;
+ int error = 0;
+
+- if (!sbh || block_device_ejected(sb))
+- return error;
++ if (!sbh)
++ return -EINVAL;
++ if (block_device_ejected(sb))
++ return -ENODEV;
+
+ ext4_update_super(sb);
+
+diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
+index 4b0e2e3c2c886..45c8cf1afe666 100644
+--- a/fs/f2fs/node.c
++++ b/fs/f2fs/node.c
+@@ -2785,6 +2785,9 @@ static void remove_nats_in_journal(struct f2fs_sb_info *sbi)
+ struct f2fs_nat_entry raw_ne;
+ nid_t nid = le32_to_cpu(nid_in_journal(journal, i));
+
++ if (f2fs_check_nid_range(sbi, nid))
++ continue;
++
+ raw_ne = nat_in_journal(journal, i);
+
+ ne = __lookup_nat_cache(nm_i, nid);
+diff --git a/fs/f2fs/verity.c b/fs/f2fs/verity.c
+index 054ec852b5ea4..15ba36926fad7 100644
+--- a/fs/f2fs/verity.c
++++ b/fs/f2fs/verity.c
+@@ -152,40 +152,73 @@ static int f2fs_end_enable_verity(struct file *filp, const void *desc,
+ size_t desc_size, u64 merkle_tree_size)
+ {
+ struct inode *inode = file_inode(filp);
++ struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+ u64 desc_pos = f2fs_verity_metadata_pos(inode) + merkle_tree_size;
+ struct fsverity_descriptor_location dloc = {
+ .version = cpu_to_le32(F2FS_VERIFY_VER),
+ .size = cpu_to_le32(desc_size),
+ .pos = cpu_to_le64(desc_pos),
+ };
+- int err = 0;
++ int err = 0, err2 = 0;
+
+- if (desc != NULL) {
+- /* Succeeded; write the verity descriptor. */
+- err = pagecache_write(inode, desc, desc_size, desc_pos);
++ /*
++ * If an error already occurred (which fs/verity/ signals by passing
++ * desc == NULL), then only clean-up is needed.
++ */
++ if (desc == NULL)
++ goto cleanup;
+
+- /* Write all pages before clearing FI_VERITY_IN_PROGRESS. */
+- if (!err)
+- err = filemap_write_and_wait(inode->i_mapping);
+- }
++ /* Append the verity descriptor. */
++ err = pagecache_write(inode, desc, desc_size, desc_pos);
++ if (err)
++ goto cleanup;
++
++ /*
++ * Write all pages (both data and verity metadata). Note that this must
++ * happen before clearing FI_VERITY_IN_PROGRESS; otherwise pages beyond
++ * i_size won't be written properly. For crash consistency, this also
++ * must happen before the verity inode flag gets persisted.
++ */
++ err = filemap_write_and_wait(inode->i_mapping);
++ if (err)
++ goto cleanup;
++
++ /* Set the verity xattr. */
++ err = f2fs_setxattr(inode, F2FS_XATTR_INDEX_VERITY,
++ F2FS_XATTR_NAME_VERITY, &dloc, sizeof(dloc),
++ NULL, XATTR_CREATE);
++ if (err)
++ goto cleanup;
+
+- /* If we failed, truncate anything we wrote past i_size. */
+- if (desc == NULL || err)
+- f2fs_truncate(inode);
++ /* Finally, set the verity inode flag. */
++ file_set_verity(inode);
++ f2fs_set_inode_flags(inode);
++ f2fs_mark_inode_dirty_sync(inode, true);
+
+ clear_inode_flag(inode, FI_VERITY_IN_PROGRESS);
++ return 0;
+
+- if (desc != NULL && !err) {
+- err = f2fs_setxattr(inode, F2FS_XATTR_INDEX_VERITY,
+- F2FS_XATTR_NAME_VERITY, &dloc, sizeof(dloc),
+- NULL, XATTR_CREATE);
+- if (!err) {
+- file_set_verity(inode);
+- f2fs_set_inode_flags(inode);
+- f2fs_mark_inode_dirty_sync(inode, true);
+- }
++cleanup:
++ /*
++ * Verity failed to be enabled, so clean up by truncating any verity
++ * metadata that was written beyond i_size (both from cache and from
++ * disk) and clearing FI_VERITY_IN_PROGRESS.
++ *
++ * Taking i_gc_rwsem[WRITE] is needed to stop f2fs garbage collection
++ * from re-instantiating cached pages we are truncating (since unlike
++ * normal file accesses, garbage collection isn't limited by i_size).
++ */
++ down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
++ truncate_inode_pages(inode->i_mapping, inode->i_size);
++ err2 = f2fs_truncate(inode);
++ if (err2) {
++ f2fs_err(sbi, "Truncating verity metadata failed (errno=%d)",
++ err2);
++ set_sbi_flag(sbi, SBI_NEED_FSCK);
+ }
+- return err;
++ up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
++ clear_inode_flag(inode, FI_VERITY_IN_PROGRESS);
++ return err ?: err2;
+ }
+
+ static int f2fs_get_verity_descriptor(struct inode *inode, void *buf,
+diff --git a/fs/fuse/file.c b/fs/fuse/file.c
+index 8cccecb55fb80..eff4abaa87da0 100644
+--- a/fs/fuse/file.c
++++ b/fs/fuse/file.c
+@@ -1099,6 +1099,7 @@ static ssize_t fuse_send_write_pages(struct fuse_io_args *ia,
+ struct fuse_file *ff = file->private_data;
+ struct fuse_mount *fm = ff->fm;
+ unsigned int offset, i;
++ bool short_write;
+ int err;
+
+ for (i = 0; i < ap->num_pages; i++)
+@@ -1113,32 +1114,38 @@ static ssize_t fuse_send_write_pages(struct fuse_io_args *ia,
+ if (!err && ia->write.out.size > count)
+ err = -EIO;
+
++ short_write = ia->write.out.size < count;
+ offset = ap->descs[0].offset;
+ count = ia->write.out.size;
+ for (i = 0; i < ap->num_pages; i++) {
+ struct page *page = ap->pages[i];
+
+- if (!err && !offset && count >= PAGE_SIZE)
+- SetPageUptodate(page);
+-
+- if (count > PAGE_SIZE - offset)
+- count -= PAGE_SIZE - offset;
+- else
+- count = 0;
+- offset = 0;
+-
+- unlock_page(page);
++ if (err) {
++ ClearPageUptodate(page);
++ } else {
++ if (count >= PAGE_SIZE - offset)
++ count -= PAGE_SIZE - offset;
++ else {
++ if (short_write)
++ ClearPageUptodate(page);
++ count = 0;
++ }
++ offset = 0;
++ }
++ if (ia->write.page_locked && (i == ap->num_pages - 1))
++ unlock_page(page);
+ put_page(page);
+ }
+
+ return err;
+ }
+
+-static ssize_t fuse_fill_write_pages(struct fuse_args_pages *ap,
++static ssize_t fuse_fill_write_pages(struct fuse_io_args *ia,
+ struct address_space *mapping,
+ struct iov_iter *ii, loff_t pos,
+ unsigned int max_pages)
+ {
++ struct fuse_args_pages *ap = &ia->ap;
+ struct fuse_conn *fc = get_fuse_conn(mapping->host);
+ unsigned offset = pos & (PAGE_SIZE - 1);
+ size_t count = 0;
+@@ -1191,6 +1198,16 @@ static ssize_t fuse_fill_write_pages(struct fuse_args_pages *ap,
+ if (offset == PAGE_SIZE)
+ offset = 0;
+
++ /* If we copied full page, mark it uptodate */
++ if (tmp == PAGE_SIZE)
++ SetPageUptodate(page);
++
++ if (PageUptodate(page)) {
++ unlock_page(page);
++ } else {
++ ia->write.page_locked = true;
++ break;
++ }
+ if (!fc->big_writes)
+ break;
+ } while (iov_iter_count(ii) && count < fc->max_write &&
+@@ -1234,7 +1251,7 @@ static ssize_t fuse_perform_write(struct kiocb *iocb,
+ break;
+ }
+
+- count = fuse_fill_write_pages(ap, mapping, ii, pos, nr_pages);
++ count = fuse_fill_write_pages(&ia, mapping, ii, pos, nr_pages);
+ if (count <= 0) {
+ err = count;
+ } else {
+diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
+index 63d97a15ffde9..74d888c78fa4e 100644
+--- a/fs/fuse/fuse_i.h
++++ b/fs/fuse/fuse_i.h
+@@ -912,6 +912,7 @@ struct fuse_io_args {
+ struct {
+ struct fuse_write_in in;
+ struct fuse_write_out out;
++ bool page_locked;
+ } write;
+ };
+ struct fuse_args_pages ap;
+diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c
+index 4ee6f734ba838..1e5affed158e9 100644
+--- a/fs/fuse/virtio_fs.c
++++ b/fs/fuse/virtio_fs.c
+@@ -896,6 +896,7 @@ static int virtio_fs_probe(struct virtio_device *vdev)
+ out_vqs:
+ vdev->config->reset(vdev);
+ virtio_fs_cleanup_vqs(vdev, fs);
++ kfree(fs->vqs);
+
+ out:
+ vdev->priv = NULL;
+diff --git a/fs/io_uring.c b/fs/io_uring.c
+index dff34975d86bc..0b5fbbd969cbd 100644
+--- a/fs/io_uring.c
++++ b/fs/io_uring.c
+@@ -1008,7 +1008,7 @@ static void io_uring_del_task_file(unsigned long index);
+ static void io_uring_try_cancel_requests(struct io_ring_ctx *ctx,
+ struct task_struct *task,
+ struct files_struct *files);
+-static void io_uring_cancel_sqpoll(struct io_ring_ctx *ctx);
++static void io_uring_cancel_sqpoll(struct io_sq_data *sqd);
+ static void destroy_fixed_rsrc_ref_node(struct fixed_rsrc_ref_node *ref_node);
+ static struct fixed_rsrc_ref_node *alloc_fixed_rsrc_ref_node(
+ struct io_ring_ctx *ctx);
+@@ -6710,6 +6710,10 @@ static int __io_sq_thread(struct io_ring_ctx *ctx, bool cap_entries)
+ if (!list_empty(&ctx->iopoll_list))
+ io_do_iopoll(ctx, &nr_events, 0);
+
++ /*
++ * Don't submit if refs are dying, good for io_uring_register(),
++ * but also it is relied upon by io_ring_exit_work()
++ */
+ if (to_submit && likely(!percpu_ref_is_dying(&ctx->refs)) &&
+ !(ctx->flags & IORING_SETUP_R_DISABLED))
+ ret = io_submit_sqes(ctx, to_submit);
+@@ -6832,15 +6836,14 @@ static int io_sq_thread(void *data)
+ timeout = jiffies + sqd->sq_thread_idle;
+ }
+
+- list_for_each_entry(ctx, &sqd->ctx_list, sqd_list)
+- io_uring_cancel_sqpoll(ctx);
++ io_uring_cancel_sqpoll(sqd);
+ sqd->thread = NULL;
+ list_for_each_entry(ctx, &sqd->ctx_list, sqd_list)
+ io_ring_set_wakeup_flag(ctx);
+- mutex_unlock(&sqd->lock);
+-
+ io_run_task_work();
+ io_run_task_work_head(&sqd->park_task_work);
++ mutex_unlock(&sqd->lock);
++
+ complete(&sqd->exited);
+ do_exit(0);
+ }
+@@ -7200,8 +7203,6 @@ static void io_sq_thread_finish(struct io_ring_ctx *ctx)
+
+ io_put_sq_data(sqd);
+ ctx->sq_data = NULL;
+- if (ctx->sq_creds)
+- put_cred(ctx->sq_creds);
+ }
+ }
+
+@@ -8469,6 +8470,8 @@ static void io_ring_ctx_free(struct io_ring_ctx *ctx)
+ mutex_unlock(&ctx->uring_lock);
+ io_eventfd_unregister(ctx);
+ io_destroy_buffers(ctx);
++ if (ctx->sq_creds)
++ put_cred(ctx->sq_creds);
+
+ #if defined(CONFIG_UNIX)
+ if (ctx->ring_sock) {
+@@ -8568,6 +8571,13 @@ static void io_tctx_exit_cb(struct callback_head *cb)
+ complete(&work->completion);
+ }
+
++static bool io_cancel_ctx_cb(struct io_wq_work *work, void *data)
++{
++ struct io_kiocb *req = container_of(work, struct io_kiocb, work);
++
++ return req->ctx == data;
++}
++
+ static void io_ring_exit_work(struct work_struct *work)
+ {
+ struct io_ring_ctx *ctx = container_of(work, struct io_ring_ctx, exit_work);
+@@ -8576,14 +8586,6 @@ static void io_ring_exit_work(struct work_struct *work)
+ struct io_tctx_node *node;
+ int ret;
+
+- /* prevent SQPOLL from submitting new requests */
+- if (ctx->sq_data) {
+- io_sq_thread_park(ctx->sq_data);
+- list_del_init(&ctx->sqd_list);
+- io_sqd_update_thread_idle(ctx->sq_data);
+- io_sq_thread_unpark(ctx->sq_data);
+- }
+-
+ /*
+ * If we're doing polled IO and end up having requests being
+ * submitted async (out-of-line), then completions can come in while
+@@ -8592,6 +8594,17 @@ static void io_ring_exit_work(struct work_struct *work)
+ */
+ do {
+ io_uring_try_cancel_requests(ctx, NULL, NULL);
++ if (ctx->sq_data) {
++ struct io_sq_data *sqd = ctx->sq_data;
++ struct task_struct *tsk;
++
++ io_sq_thread_park(sqd);
++ tsk = sqd->thread;
++ if (tsk && tsk->io_uring && tsk->io_uring->io_wq)
++ io_wq_cancel_cb(tsk->io_uring->io_wq,
++ io_cancel_ctx_cb, ctx, true);
++ io_sq_thread_unpark(sqd);
++ }
+
+ WARN_ON_ONCE(time_after(jiffies, timeout));
+ } while (!wait_for_completion_timeout(&ctx->ref_comp, HZ/20));
+@@ -8736,13 +8749,6 @@ static bool io_cancel_defer_files(struct io_ring_ctx *ctx,
+ return true;
+ }
+
+-static bool io_cancel_ctx_cb(struct io_wq_work *work, void *data)
+-{
+- struct io_kiocb *req = container_of(work, struct io_kiocb, work);
+-
+- return req->ctx == data;
+-}
+-
+ static bool io_uring_try_cancel_iowq(struct io_ring_ctx *ctx)
+ {
+ struct io_tctx_node *node;
+@@ -8935,11 +8941,11 @@ static s64 tctx_inflight(struct io_uring_task *tctx)
+ static void io_sqpoll_cancel_cb(struct callback_head *cb)
+ {
+ struct io_tctx_exit *work = container_of(cb, struct io_tctx_exit, task_work);
+- struct io_ring_ctx *ctx = work->ctx;
+- struct io_sq_data *sqd = ctx->sq_data;
++ struct io_sq_data *sqd = work->ctx->sq_data;
+
+ if (sqd->thread)
+- io_uring_cancel_sqpoll(ctx);
++ io_uring_cancel_sqpoll(sqd);
++ list_del_init(&work->ctx->sqd_list);
+ complete(&work->completion);
+ }
+
+@@ -8950,7 +8956,6 @@ static void io_sqpoll_cancel_sync(struct io_ring_ctx *ctx)
+ struct task_struct *task;
+
+ io_sq_thread_park(sqd);
+- list_del_init(&ctx->sqd_list);
+ io_sqd_update_thread_idle(sqd);
+ task = sqd->thread;
+ if (task) {
+@@ -8958,6 +8963,8 @@ static void io_sqpoll_cancel_sync(struct io_ring_ctx *ctx)
+ init_task_work(&work.task_work, io_sqpoll_cancel_cb);
+ io_task_work_add_head(&sqd->park_task_work, &work.task_work);
+ wake_up_process(task);
++ } else {
++ list_del_init(&ctx->sqd_list);
+ }
+ io_sq_thread_unpark(sqd);
+
+@@ -8991,14 +8998,16 @@ void __io_uring_files_cancel(struct files_struct *files)
+ }
+
+ /* should only be called by SQPOLL task */
+-static void io_uring_cancel_sqpoll(struct io_ring_ctx *ctx)
++static void io_uring_cancel_sqpoll(struct io_sq_data *sqd)
+ {
+- struct io_sq_data *sqd = ctx->sq_data;
+ struct io_uring_task *tctx = current->io_uring;
++ struct io_ring_ctx *ctx;
+ s64 inflight;
+ DEFINE_WAIT(wait);
+
+- WARN_ON_ONCE(!sqd || ctx->sq_data->thread != current);
++ if (!current->io_uring)
++ return;
++ WARN_ON_ONCE(!sqd || sqd->thread != current);
+
+ atomic_inc(&tctx->in_idle);
+ do {
+@@ -9006,7 +9015,8 @@ static void io_uring_cancel_sqpoll(struct io_ring_ctx *ctx)
+ inflight = tctx_inflight(tctx);
+ if (!inflight)
+ break;
+- io_uring_try_cancel_requests(ctx, current, NULL);
++ list_for_each_entry(ctx, &sqd->ctx_list, sqd_list)
++ io_uring_try_cancel_requests(ctx, current, NULL);
+
+ prepare_to_wait(&tctx->wait, &wait, TASK_UNINTERRUPTIBLE);
+ /*
+diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
+index 9396666b73145..e8fc45fd751fb 100644
+--- a/fs/jbd2/transaction.c
++++ b/fs/jbd2/transaction.c
+@@ -349,7 +349,12 @@ static int start_this_handle(journal_t *journal, handle_t *handle,
+ }
+
+ alloc_transaction:
+- if (!journal->j_running_transaction) {
++ /*
++ * This check is racy but it is just an optimization of allocating new
++ * transaction early if there are high chances we'll need it. If we
++ * guess wrong, we'll retry or free unused transaction.
++ */
++ if (!data_race(journal->j_running_transaction)) {
+ /*
+ * If __GFP_FS is not present, then we may be being called from
+ * inside the fs writeback layer, so we MUST NOT fail.
+@@ -1474,8 +1479,8 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh)
+ * crucial to catch bugs so let's do a reliable check until the
+ * lockless handling is fully proven.
+ */
+- if (jh->b_transaction != transaction &&
+- jh->b_next_transaction != transaction) {
++ if (data_race(jh->b_transaction != transaction &&
++ jh->b_next_transaction != transaction)) {
+ spin_lock(&jh->b_state_lock);
+ J_ASSERT_JH(jh, jh->b_transaction == transaction ||
+ jh->b_next_transaction == transaction);
+@@ -1483,8 +1488,8 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh)
+ }
+ if (jh->b_modified == 1) {
+ /* If it's in our transaction it must be in BJ_Metadata list. */
+- if (jh->b_transaction == transaction &&
+- jh->b_jlist != BJ_Metadata) {
++ if (data_race(jh->b_transaction == transaction &&
++ jh->b_jlist != BJ_Metadata)) {
+ spin_lock(&jh->b_state_lock);
+ if (jh->b_transaction == transaction &&
+ jh->b_jlist != BJ_Metadata)
+diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c
+index f8fb89b10227c..4fc8cd698d1a4 100644
+--- a/fs/jffs2/file.c
++++ b/fs/jffs2/file.c
+@@ -57,6 +57,7 @@ const struct file_operations jffs2_file_operations =
+ .mmap = generic_file_readonly_mmap,
+ .fsync = jffs2_fsync,
+ .splice_read = generic_file_splice_read,
++ .splice_write = iter_file_splice_write,
+ };
+
+ /* jffs2_file_inode_operations */
+diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c
+index db72a9d2d0afb..b676056826beb 100644
+--- a/fs/jffs2/scan.c
++++ b/fs/jffs2/scan.c
+@@ -1079,7 +1079,7 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo
+ memcpy(&fd->name, rd->name, checkedlen);
+ fd->name[checkedlen] = 0;
+
+- crc = crc32(0, fd->name, rd->nsize);
++ crc = crc32(0, fd->name, checkedlen);
+ if (crc != je32_to_cpu(rd->name_crc)) {
+ pr_notice("%s(): Name CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
+ __func__, ofs, je32_to_cpu(rd->name_crc), crc);
+diff --git a/fs/nfs/fs_context.c b/fs/nfs/fs_context.c
+index 971a9251c1d97..902db1262d2bf 100644
+--- a/fs/nfs/fs_context.c
++++ b/fs/nfs/fs_context.c
+@@ -973,6 +973,15 @@ static int nfs23_parse_monolithic(struct fs_context *fc,
+ memset(mntfh->data + mntfh->size, 0,
+ sizeof(mntfh->data) - mntfh->size);
+
++ /*
++ * for proto == XPRT_TRANSPORT_UDP, which is what uses
++ * to_exponential, implying shift: limit the shift value
++ * to BITS_PER_LONG (majortimeo is unsigned long)
++ */
++ if (!(data->flags & NFS_MOUNT_TCP)) /* this will be UDP */
++ if (data->retrans >= 64) /* shift value is too large */
++ goto out_invalid_data;
++
+ /*
+ * Translate to nfs_fs_context, which nfs_fill_super
+ * can deal with.
+@@ -1073,6 +1082,9 @@ out_no_address:
+
+ out_invalid_fh:
+ return nfs_invalf(fc, "NFS: invalid root filehandle");
++
++out_invalid_data:
++ return nfs_invalf(fc, "NFS: invalid binary mount data");
+ }
+
+ #if IS_ENABLED(CONFIG_NFS_V4)
+diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
+index 102b66e0bdeff..f726f8b12b7e8 100644
+--- a/fs/nfs/pnfs.c
++++ b/fs/nfs/pnfs.c
+@@ -1344,7 +1344,7 @@ _pnfs_return_layout(struct inode *ino)
+ }
+ valid_layout = pnfs_layout_is_valid(lo);
+ pnfs_clear_layoutcommit(ino, &tmp_list);
+- pnfs_mark_matching_lsegs_invalid(lo, &tmp_list, NULL, 0);
++ pnfs_mark_matching_lsegs_return(lo, &tmp_list, NULL, 0);
+
+ if (NFS_SERVER(ino)->pnfs_curr_ld->return_range) {
+ struct pnfs_layout_range range = {
+@@ -2468,6 +2468,9 @@ pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo,
+
+ assert_spin_locked(&lo->plh_inode->i_lock);
+
++ if (test_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags))
++ tmp_list = &lo->plh_return_segs;
++
+ list_for_each_entry_safe(lseg, next, &lo->plh_segs, pls_list)
+ if (pnfs_match_lseg_recall(lseg, return_range, seq)) {
+ dprintk("%s: marking lseg %p iomode %d "
+@@ -2475,6 +2478,8 @@ pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo,
+ lseg, lseg->pls_range.iomode,
+ lseg->pls_range.offset,
+ lseg->pls_range.length);
++ if (test_bit(NFS_LSEG_LAYOUTRETURN, &lseg->pls_flags))
++ tmp_list = &lo->plh_return_segs;
+ if (mark_lseg_invalid(lseg, tmp_list))
+ continue;
+ remaining++;
+diff --git a/fs/stat.c b/fs/stat.c
+index fbc171d038aa5..1fa38bdec1a68 100644
+--- a/fs/stat.c
++++ b/fs/stat.c
+@@ -86,12 +86,20 @@ int vfs_getattr_nosec(const struct path *path, struct kstat *stat,
+ /* SB_NOATIME means filesystem supplies dummy atime value */
+ if (inode->i_sb->s_flags & SB_NOATIME)
+ stat->result_mask &= ~STATX_ATIME;
++
++ /*
++ * Note: If you add another clause to set an attribute flag, please
++ * update attributes_mask below.
++ */
+ if (IS_AUTOMOUNT(inode))
+ stat->attributes |= STATX_ATTR_AUTOMOUNT;
+
+ if (IS_DAX(inode))
+ stat->attributes |= STATX_ATTR_DAX;
+
++ stat->attributes_mask |= (STATX_ATTR_AUTOMOUNT |
++ STATX_ATTR_DAX);
++
+ mnt_userns = mnt_user_ns(path->mnt);
+ if (inode->i_op->getattr)
+ return inode->i_op->getattr(mnt_userns, path, stat,
+diff --git a/fs/ubifs/replay.c b/fs/ubifs/replay.c
+index 0f8a6a16421b4..1929ec63a0cb6 100644
+--- a/fs/ubifs/replay.c
++++ b/fs/ubifs/replay.c
+@@ -223,7 +223,8 @@ static bool inode_still_linked(struct ubifs_info *c, struct replay_entry *rino)
+ */
+ list_for_each_entry_reverse(r, &c->replay_list, list) {
+ ubifs_assert(c, r->sqnum >= rino->sqnum);
+- if (key_inum(c, &r->key) == key_inum(c, &rino->key))
++ if (key_inum(c, &r->key) == key_inum(c, &rino->key) &&
++ key_type(c, &r->key) == UBIFS_INO_KEY)
+ return r->deletion == 0;
+
+ }
+diff --git a/include/crypto/acompress.h b/include/crypto/acompress.h
+index fcde59c65a81b..cb3d6b1c655de 100644
+--- a/include/crypto/acompress.h
++++ b/include/crypto/acompress.h
+@@ -165,6 +165,8 @@ static inline struct crypto_acomp *crypto_acomp_reqtfm(struct acomp_req *req)
+ * crypto_free_acomp() -- free ACOMPRESS tfm handle
+ *
+ * @tfm: ACOMPRESS tfm handle allocated with crypto_alloc_acomp()
++ *
++ * If @tfm is a NULL or error pointer, this function does nothing.
+ */
+ static inline void crypto_free_acomp(struct crypto_acomp *tfm)
+ {
+diff --git a/include/crypto/aead.h b/include/crypto/aead.h
+index fcc12c593ef8b..e728469c4cccb 100644
+--- a/include/crypto/aead.h
++++ b/include/crypto/aead.h
+@@ -185,6 +185,8 @@ static inline struct crypto_tfm *crypto_aead_tfm(struct crypto_aead *tfm)
+ /**
+ * crypto_free_aead() - zeroize and free aead handle
+ * @tfm: cipher handle to be freed
++ *
++ * If @tfm is a NULL or error pointer, this function does nothing.
+ */
+ static inline void crypto_free_aead(struct crypto_aead *tfm)
+ {
+diff --git a/include/crypto/akcipher.h b/include/crypto/akcipher.h
+index 1d3aa252cabaf..5764b46bd1ec1 100644
+--- a/include/crypto/akcipher.h
++++ b/include/crypto/akcipher.h
+@@ -174,6 +174,8 @@ static inline struct crypto_akcipher *crypto_akcipher_reqtfm(
+ * crypto_free_akcipher() - free AKCIPHER tfm handle
+ *
+ * @tfm: AKCIPHER tfm handle allocated with crypto_alloc_akcipher()
++ *
++ * If @tfm is a NULL or error pointer, this function does nothing.
+ */
+ static inline void crypto_free_akcipher(struct crypto_akcipher *tfm)
+ {
+diff --git a/include/crypto/chacha.h b/include/crypto/chacha.h
+index 3a1c72fdb7cf5..dabaee6987186 100644
+--- a/include/crypto/chacha.h
++++ b/include/crypto/chacha.h
+@@ -47,13 +47,18 @@ static inline void hchacha_block(const u32 *state, u32 *out, int nrounds)
+ hchacha_block_generic(state, out, nrounds);
+ }
+
+-void chacha_init_arch(u32 *state, const u32 *key, const u8 *iv);
+-static inline void chacha_init_generic(u32 *state, const u32 *key, const u8 *iv)
++static inline void chacha_init_consts(u32 *state)
+ {
+ state[0] = 0x61707865; /* "expa" */
+ state[1] = 0x3320646e; /* "nd 3" */
+ state[2] = 0x79622d32; /* "2-by" */
+ state[3] = 0x6b206574; /* "te k" */
++}
++
++void chacha_init_arch(u32 *state, const u32 *key, const u8 *iv);
++static inline void chacha_init_generic(u32 *state, const u32 *key, const u8 *iv)
++{
++ chacha_init_consts(state);
+ state[4] = key[0];
+ state[5] = key[1];
+ state[6] = key[2];
+diff --git a/include/crypto/hash.h b/include/crypto/hash.h
+index 13f8a6a54ca87..b2bc1e46e86a7 100644
+--- a/include/crypto/hash.h
++++ b/include/crypto/hash.h
+@@ -281,6 +281,8 @@ static inline struct crypto_tfm *crypto_ahash_tfm(struct crypto_ahash *tfm)
+ /**
+ * crypto_free_ahash() - zeroize and free the ahash handle
+ * @tfm: cipher handle to be freed
++ *
++ * If @tfm is a NULL or error pointer, this function does nothing.
+ */
+ static inline void crypto_free_ahash(struct crypto_ahash *tfm)
+ {
+@@ -724,6 +726,8 @@ static inline struct crypto_tfm *crypto_shash_tfm(struct crypto_shash *tfm)
+ /**
+ * crypto_free_shash() - zeroize and free the message digest handle
+ * @tfm: cipher handle to be freed
++ *
++ * If @tfm is a NULL or error pointer, this function does nothing.
+ */
+ static inline void crypto_free_shash(struct crypto_shash *tfm)
+ {
+diff --git a/include/crypto/kpp.h b/include/crypto/kpp.h
+index 88b591215d5c8..cccceadc164b9 100644
+--- a/include/crypto/kpp.h
++++ b/include/crypto/kpp.h
+@@ -154,6 +154,8 @@ static inline void crypto_kpp_set_flags(struct crypto_kpp *tfm, u32 flags)
+ * crypto_free_kpp() - free KPP tfm handle
+ *
+ * @tfm: KPP tfm handle allocated with crypto_alloc_kpp()
++ *
++ * If @tfm is a NULL or error pointer, this function does nothing.
+ */
+ static inline void crypto_free_kpp(struct crypto_kpp *tfm)
+ {
+diff --git a/include/crypto/rng.h b/include/crypto/rng.h
+index 8b4b844b4eef8..17bb3673d3c17 100644
+--- a/include/crypto/rng.h
++++ b/include/crypto/rng.h
+@@ -111,6 +111,8 @@ static inline struct rng_alg *crypto_rng_alg(struct crypto_rng *tfm)
+ /**
+ * crypto_free_rng() - zeroize and free RNG handle
+ * @tfm: cipher handle to be freed
++ *
++ * If @tfm is a NULL or error pointer, this function does nothing.
+ */
+ static inline void crypto_free_rng(struct crypto_rng *tfm)
+ {
+diff --git a/include/crypto/skcipher.h b/include/crypto/skcipher.h
+index 6a733b171a5d0..ef0fc9ed4342e 100644
+--- a/include/crypto/skcipher.h
++++ b/include/crypto/skcipher.h
+@@ -196,6 +196,8 @@ static inline struct crypto_tfm *crypto_skcipher_tfm(
+ /**
+ * crypto_free_skcipher() - zeroize and free cipher handle
+ * @tfm: cipher handle to be freed
++ *
++ * If @tfm is a NULL or error pointer, this function does nothing.
+ */
+ static inline void crypto_free_skcipher(struct crypto_skcipher *tfm)
+ {
+diff --git a/include/linux/ioport.h b/include/linux/ioport.h
+index 55de385c839cf..647744d8514e0 100644
+--- a/include/linux/ioport.h
++++ b/include/linux/ioport.h
+@@ -331,7 +331,7 @@ static inline void irqresource_disabled(struct resource *res, u32 irq)
+ {
+ res->start = irq;
+ res->end = irq;
+- res->flags = IORESOURCE_IRQ | IORESOURCE_DISABLED | IORESOURCE_UNSET;
++ res->flags |= IORESOURCE_IRQ | IORESOURCE_DISABLED | IORESOURCE_UNSET;
+ }
+
+ extern struct address_space *iomem_get_mapping(void);
+diff --git a/include/linux/mfd/da9063/registers.h b/include/linux/mfd/da9063/registers.h
+index 1dbabf1b3cb81..6e0f66a2e7279 100644
+--- a/include/linux/mfd/da9063/registers.h
++++ b/include/linux/mfd/da9063/registers.h
+@@ -1037,6 +1037,9 @@
+ #define DA9063_NONKEY_PIN_AUTODOWN 0x02
+ #define DA9063_NONKEY_PIN_AUTOFLPRT 0x03
+
++/* DA9063_REG_CONFIG_J (addr=0x10F) */
++#define DA9063_TWOWIRE_TO 0x40
++
+ /* DA9063_REG_MON_REG_5 (addr=0x116) */
+ #define DA9063_MON_A8_IDX_MASK 0x07
+ #define DA9063_MON_A8_IDX_NONE 0x00
+diff --git a/include/linux/mfd/intel-m10-bmc.h b/include/linux/mfd/intel-m10-bmc.h
+index 74d4e193966a9..9b54ca13eac3c 100644
+--- a/include/linux/mfd/intel-m10-bmc.h
++++ b/include/linux/mfd/intel-m10-bmc.h
+@@ -11,7 +11,7 @@
+
+ #define M10BMC_LEGACY_SYS_BASE 0x300400
+ #define M10BMC_SYS_BASE 0x300800
+-#define M10BMC_MEM_END 0x200000fc
++#define M10BMC_MEM_END 0x1fffffff
+
+ /* Register offset of system registers */
+ #define NIOS2_FW_VERSION 0x0
+diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
+index 26a3c7bc29ae5..a3a4e374f8028 100644
+--- a/include/linux/mmc/host.h
++++ b/include/linux/mmc/host.h
+@@ -302,9 +302,6 @@ struct mmc_host {
+ u32 ocr_avail_sdio; /* SDIO-specific OCR */
+ u32 ocr_avail_sd; /* SD-specific OCR */
+ u32 ocr_avail_mmc; /* MMC-specific OCR */
+-#ifdef CONFIG_PM_SLEEP
+- struct notifier_block pm_notify;
+-#endif
+ struct wakeup_source *ws; /* Enable consume of uevents */
+ u32 max_current_330;
+ u32 max_current_300;
+diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
+index 3f7f89ea5e512..3d478abf411cd 100644
+--- a/include/linux/perf_event.h
++++ b/include/linux/perf_event.h
+@@ -607,6 +607,7 @@ struct swevent_hlist {
+ #define PERF_ATTACH_TASK_DATA 0x08
+ #define PERF_ATTACH_ITRACE 0x10
+ #define PERF_ATTACH_SCHED_CB 0x20
++#define PERF_ATTACH_CHILD 0x40
+
+ struct perf_cgroup;
+ struct perf_buffer;
+diff --git a/include/linux/power/bq27xxx_battery.h b/include/linux/power/bq27xxx_battery.h
+index 111a40d0d3d50..8d5f4f40fb418 100644
+--- a/include/linux/power/bq27xxx_battery.h
++++ b/include/linux/power/bq27xxx_battery.h
+@@ -53,7 +53,6 @@ struct bq27xxx_reg_cache {
+ int capacity;
+ int energy;
+ int flags;
+- int power_avg;
+ int health;
+ };
+
+diff --git a/include/linux/reset.h b/include/linux/reset.h
+index b9109efa2a5cd..9700124affa34 100644
+--- a/include/linux/reset.h
++++ b/include/linux/reset.h
+@@ -47,6 +47,11 @@ static inline int reset_control_reset(struct reset_control *rstc)
+ return 0;
+ }
+
++static inline int reset_control_rearm(struct reset_control *rstc)
++{
++ return 0;
++}
++
+ static inline int reset_control_assert(struct reset_control *rstc)
+ {
+ return 0;
+diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
+index 167ca8c8424f6..2fe4019b749f6 100644
+--- a/include/media/v4l2-ctrls.h
++++ b/include/media/v4l2-ctrls.h
+@@ -301,12 +301,14 @@ struct v4l2_ctrl {
+ * the control has been applied. This prevents applying controls
+ * from a cluster with multiple controls twice (when the first
+ * control of a cluster is applied, they all are).
+- * @req: If set, this refers to another request that sets this control.
++ * @valid_p_req: If set, then p_req contains the control value for the request.
+ * @p_req: If the control handler containing this control reference
+ * is bound to a media request, then this points to the
+- * value of the control that should be applied when the request
++ * value of the control that must be applied when the request
+ * is executed, or to the value of the control at the time
+- * that the request was completed.
++ * that the request was completed. If @valid_p_req is false,
++ * then this control was never set for this request and the
++ * control will not be updated when this request is applied.
+ *
+ * Each control handler has a list of these refs. The list_head is used to
+ * keep a sorted-by-control-ID list of all controls, while the next pointer
+@@ -319,7 +321,7 @@ struct v4l2_ctrl_ref {
+ struct v4l2_ctrl_helper *helper;
+ bool from_other_dev;
+ bool req_done;
+- struct v4l2_ctrl_ref *req;
++ bool valid_p_req;
+ union v4l2_ctrl_ptr p_req;
+ };
+
+@@ -346,7 +348,7 @@ struct v4l2_ctrl_ref {
+ * @error: The error code of the first failed control addition.
+ * @request_is_queued: True if the request was queued.
+ * @requests: List to keep track of open control handler request objects.
+- * For the parent control handler (@req_obj.req == NULL) this
++ * For the parent control handler (@req_obj.ops == NULL) this
+ * is the list header. When the parent control handler is
+ * removed, it has to unbind and put all these requests since
+ * they refer to the parent.
+diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h
+index 2568cb0627ec0..fac8e89aed81d 100644
+--- a/include/scsi/libfcoe.h
++++ b/include/scsi/libfcoe.h
+@@ -249,7 +249,7 @@ int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *, struct fc_lport *,
+ struct fc_frame *);
+
+ /* libfcoe funcs */
+-u64 fcoe_wwn_from_mac(unsigned char mac[], unsigned int, unsigned int);
++u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN], unsigned int, unsigned int);
+ int fcoe_libfc_config(struct fc_lport *, struct fcoe_ctlr *,
+ const struct libfc_function_template *, int init_fcp);
+ u32 fcoe_fc_crc(struct fc_frame *fp);
+diff --git a/include/uapi/linux/usb/video.h b/include/uapi/linux/usb/video.h
+index d854cb19c42c3..bfdae12cdacf8 100644
+--- a/include/uapi/linux/usb/video.h
++++ b/include/uapi/linux/usb/video.h
+@@ -302,9 +302,10 @@ struct uvc_processing_unit_descriptor {
+ __u8 bControlSize;
+ __u8 bmControls[2];
+ __u8 iProcessing;
++ __u8 bmVideoStandards;
+ } __attribute__((__packed__));
+
+-#define UVC_DT_PROCESSING_UNIT_SIZE(n) (9+(n))
++#define UVC_DT_PROCESSING_UNIT_SIZE(n) (10+(n))
+
+ /* 3.7.2.6. Extension Unit Descriptor */
+ struct uvc_extension_unit_descriptor {
+diff --git a/kernel/.gitignore b/kernel/.gitignore
+index 78701ea37c973..5518835ac35c7 100644
+--- a/kernel/.gitignore
++++ b/kernel/.gitignore
+@@ -1,4 +1,5 @@
+ # SPDX-License-Identifier: GPL-2.0-only
++/config_data
+ kheaders.md5
+ timeconst.h
+ hz.bc
+diff --git a/kernel/Makefile b/kernel/Makefile
+index 320f1f3941b79..605ec3e70cb78 100644
+--- a/kernel/Makefile
++++ b/kernel/Makefile
+@@ -138,10 +138,15 @@ obj-$(CONFIG_SCF_TORTURE_TEST) += scftorture.o
+
+ $(obj)/configs.o: $(obj)/config_data.gz
+
+-targets += config_data.gz
+-$(obj)/config_data.gz: $(KCONFIG_CONFIG) FORCE
++targets += config_data config_data.gz
++$(obj)/config_data.gz: $(obj)/config_data FORCE
+ $(call if_changed,gzip)
+
++filechk_cat = cat $<
++
++$(obj)/config_data: $(KCONFIG_CONFIG) FORCE
++ $(call filechk,cat)
++
+ $(obj)/kheaders.o: $(obj)/kheaders_data.tar.xz
+
+ quiet_cmd_genikh = CHK $(obj)/kheaders_data.tar.xz
+diff --git a/kernel/events/core.c b/kernel/events/core.c
+index 43ceb8dae2644..c24ea952e7ae4 100644
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -2204,6 +2204,26 @@ out:
+ perf_event__header_size(leader);
+ }
+
++static void sync_child_event(struct perf_event *child_event);
++
++static void perf_child_detach(struct perf_event *event)
++{
++ struct perf_event *parent_event = event->parent;
++
++ if (!(event->attach_state & PERF_ATTACH_CHILD))
++ return;
++
++ event->attach_state &= ~PERF_ATTACH_CHILD;
++
++ if (WARN_ON_ONCE(!parent_event))
++ return;
++
++ lockdep_assert_held(&parent_event->child_mutex);
++
++ sync_child_event(event);
++ list_del_init(&event->child_list);
++}
++
+ static bool is_orphaned_event(struct perf_event *event)
+ {
+ return event->state == PERF_EVENT_STATE_DEAD;
+@@ -2311,6 +2331,7 @@ group_sched_out(struct perf_event *group_event,
+ }
+
+ #define DETACH_GROUP 0x01UL
++#define DETACH_CHILD 0x02UL
+
+ /*
+ * Cross CPU call to remove a performance event
+@@ -2334,6 +2355,8 @@ __perf_remove_from_context(struct perf_event *event,
+ event_sched_out(event, cpuctx, ctx);
+ if (flags & DETACH_GROUP)
+ perf_group_detach(event);
++ if (flags & DETACH_CHILD)
++ perf_child_detach(event);
+ list_del_event(event, ctx);
+
+ if (!ctx->nr_events && ctx->is_active) {
+@@ -2362,25 +2385,21 @@ static void perf_remove_from_context(struct perf_event *event, unsigned long fla
+
+ lockdep_assert_held(&ctx->mutex);
+
+- event_function_call(event, __perf_remove_from_context, (void *)flags);
+-
+ /*
+- * The above event_function_call() can NO-OP when it hits
+- * TASK_TOMBSTONE. In that case we must already have been detached
+- * from the context (by perf_event_exit_event()) but the grouping
+- * might still be in-tact.
++ * Because of perf_event_exit_task(), perf_remove_from_context() ought
++ * to work in the face of TASK_TOMBSTONE, unlike every other
++ * event_function_call() user.
+ */
+- WARN_ON_ONCE(event->attach_state & PERF_ATTACH_CONTEXT);
+- if ((flags & DETACH_GROUP) &&
+- (event->attach_state & PERF_ATTACH_GROUP)) {
+- /*
+- * Since in that case we cannot possibly be scheduled, simply
+- * detach now.
+- */
+- raw_spin_lock_irq(&ctx->lock);
+- perf_group_detach(event);
++ raw_spin_lock_irq(&ctx->lock);
++ if (!ctx->is_active) {
++ __perf_remove_from_context(event, __get_cpu_context(ctx),
++ ctx, (void *)flags);
+ raw_spin_unlock_irq(&ctx->lock);
++ return;
+ }
++ raw_spin_unlock_irq(&ctx->lock);
++
++ event_function_call(event, __perf_remove_from_context, (void *)flags);
+ }
+
+ /*
+@@ -12373,14 +12392,17 @@ void perf_pmu_migrate_context(struct pmu *pmu, int src_cpu, int dst_cpu)
+ }
+ EXPORT_SYMBOL_GPL(perf_pmu_migrate_context);
+
+-static void sync_child_event(struct perf_event *child_event,
+- struct task_struct *child)
++static void sync_child_event(struct perf_event *child_event)
+ {
+ struct perf_event *parent_event = child_event->parent;
+ u64 child_val;
+
+- if (child_event->attr.inherit_stat)
+- perf_event_read_event(child_event, child);
++ if (child_event->attr.inherit_stat) {
++ struct task_struct *task = child_event->ctx->task;
++
++ if (task && task != TASK_TOMBSTONE)
++ perf_event_read_event(child_event, task);
++ }
+
+ child_val = perf_event_count(child_event);
+
+@@ -12395,60 +12417,53 @@ static void sync_child_event(struct perf_event *child_event,
+ }
+
+ static void
+-perf_event_exit_event(struct perf_event *child_event,
+- struct perf_event_context *child_ctx,
+- struct task_struct *child)
++perf_event_exit_event(struct perf_event *event, struct perf_event_context *ctx)
+ {
+- struct perf_event *parent_event = child_event->parent;
++ struct perf_event *parent_event = event->parent;
++ unsigned long detach_flags = 0;
+
+- /*
+- * Do not destroy the 'original' grouping; because of the context
+- * switch optimization the original events could've ended up in a
+- * random child task.
+- *
+- * If we were to destroy the original group, all group related
+- * operations would cease to function properly after this random
+- * child dies.
+- *
+- * Do destroy all inherited groups, we don't care about those
+- * and being thorough is better.
+- */
+- raw_spin_lock_irq(&child_ctx->lock);
+- WARN_ON_ONCE(child_ctx->is_active);
++ if (parent_event) {
++ /*
++ * Do not destroy the 'original' grouping; because of the
++ * context switch optimization the original events could've
++ * ended up in a random child task.
++ *
++ * If we were to destroy the original group, all group related
++ * operations would cease to function properly after this
++ * random child dies.
++ *
++ * Do destroy all inherited groups, we don't care about those
++ * and being thorough is better.
++ */
++ detach_flags = DETACH_GROUP | DETACH_CHILD;
++ mutex_lock(&parent_event->child_mutex);
++ }
+
+- if (parent_event)
+- perf_group_detach(child_event);
+- list_del_event(child_event, child_ctx);
+- perf_event_set_state(child_event, PERF_EVENT_STATE_EXIT); /* is_event_hup() */
+- raw_spin_unlock_irq(&child_ctx->lock);
++ perf_remove_from_context(event, detach_flags);
++
++ raw_spin_lock_irq(&ctx->lock);
++ if (event->state > PERF_EVENT_STATE_EXIT)
++ perf_event_set_state(event, PERF_EVENT_STATE_EXIT);
++ raw_spin_unlock_irq(&ctx->lock);
+
+ /*
+- * Parent events are governed by their filedesc, retain them.
++ * Child events can be freed.
+ */
+- if (!parent_event) {
+- perf_event_wakeup(child_event);
++ if (parent_event) {
++ mutex_unlock(&parent_event->child_mutex);
++ /*
++ * Kick perf_poll() for is_event_hup();
++ */
++ perf_event_wakeup(parent_event);
++ free_event(event);
++ put_event(parent_event);
+ return;
+ }
+- /*
+- * Child events can be cleaned up.
+- */
+-
+- sync_child_event(child_event, child);
+
+ /*
+- * Remove this event from the parent's list
+- */
+- WARN_ON_ONCE(parent_event->ctx->parent_ctx);
+- mutex_lock(&parent_event->child_mutex);
+- list_del_init(&child_event->child_list);
+- mutex_unlock(&parent_event->child_mutex);
+-
+- /*
+- * Kick perf_poll() for is_event_hup().
++ * Parent events are governed by their filedesc, retain them.
+ */
+- perf_event_wakeup(parent_event);
+- free_event(child_event);
+- put_event(parent_event);
++ perf_event_wakeup(event);
+ }
+
+ static void perf_event_exit_task_context(struct task_struct *child, int ctxn)
+@@ -12505,7 +12520,7 @@ static void perf_event_exit_task_context(struct task_struct *child, int ctxn)
+ perf_event_task(child, child_ctx, 0);
+
+ list_for_each_entry_safe(child_event, next, &child_ctx->event_list, event_entry)
+- perf_event_exit_event(child_event, child_ctx, child);
++ perf_event_exit_event(child_event, child_ctx);
+
+ mutex_unlock(&child_ctx->mutex);
+
+@@ -12765,6 +12780,7 @@ inherit_event(struct perf_event *parent_event,
+ */
+ raw_spin_lock_irqsave(&child_ctx->lock, flags);
+ add_event_to_ctx(child_event, child_ctx);
++ child_event->attach_state |= PERF_ATTACH_CHILD;
+ raw_spin_unlock_irqrestore(&child_ctx->lock, flags);
+
+ /*
+diff --git a/kernel/futex.c b/kernel/futex.c
+index 00febd6dea9cc..a8629b695d38e 100644
+--- a/kernel/futex.c
++++ b/kernel/futex.c
+@@ -3711,8 +3711,7 @@ long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout,
+
+ if (op & FUTEX_CLOCK_REALTIME) {
+ flags |= FLAGS_CLOCKRT;
+- if (cmd != FUTEX_WAIT && cmd != FUTEX_WAIT_BITSET && \
+- cmd != FUTEX_WAIT_REQUEUE_PI)
++ if (cmd != FUTEX_WAIT_BITSET && cmd != FUTEX_WAIT_REQUEUE_PI)
+ return -ENOSYS;
+ }
+
+@@ -3782,7 +3781,7 @@ SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, u32, val,
+ t = timespec64_to_ktime(ts);
+ if (cmd == FUTEX_WAIT)
+ t = ktime_add_safe(ktime_get(), t);
+- else if (!(op & FUTEX_CLOCK_REALTIME))
++ else if (cmd != FUTEX_LOCK_PI && !(op & FUTEX_CLOCK_REALTIME))
+ t = timens_ktime_to_host(CLOCK_MONOTONIC, t);
+ tp = &t;
+ }
+@@ -3976,7 +3975,7 @@ SYSCALL_DEFINE6(futex_time32, u32 __user *, uaddr, int, op, u32, val,
+ t = timespec64_to_ktime(ts);
+ if (cmd == FUTEX_WAIT)
+ t = ktime_add_safe(ktime_get(), t);
+- else if (!(op & FUTEX_CLOCK_REALTIME))
++ else if (cmd != FUTEX_LOCK_PI && !(op & FUTEX_CLOCK_REALTIME))
+ t = timens_ktime_to_host(CLOCK_MONOTONIC, t);
+ tp = &t;
+ }
+diff --git a/kernel/irq/matrix.c b/kernel/irq/matrix.c
+index 651a4ad6d711f..8e586858bcf41 100644
+--- a/kernel/irq/matrix.c
++++ b/kernel/irq/matrix.c
+@@ -423,7 +423,9 @@ void irq_matrix_free(struct irq_matrix *m, unsigned int cpu,
+ if (WARN_ON_ONCE(bit < m->alloc_start || bit >= m->alloc_end))
+ return;
+
+- clear_bit(bit, cm->alloc_map);
++ if (WARN_ON_ONCE(!test_and_clear_bit(bit, cm->alloc_map)))
++ return;
++
+ cm->allocated--;
+ if(managed)
+ cm->managed_allocated--;
+diff --git a/kernel/kcsan/core.c b/kernel/kcsan/core.c
+index 3bf98db9c702d..23e7acb5c6679 100644
+--- a/kernel/kcsan/core.c
++++ b/kernel/kcsan/core.c
+@@ -639,8 +639,6 @@ void __init kcsan_init(void)
+
+ BUG_ON(!in_task());
+
+- kcsan_debugfs_init();
+-
+ for_each_possible_cpu(cpu)
+ per_cpu(kcsan_rand_state, cpu) = (u32)get_cycles();
+
+diff --git a/kernel/kcsan/debugfs.c b/kernel/kcsan/debugfs.c
+index 3c8093a371b1c..209ad8dcfcecf 100644
+--- a/kernel/kcsan/debugfs.c
++++ b/kernel/kcsan/debugfs.c
+@@ -261,7 +261,9 @@ static const struct file_operations debugfs_ops =
+ .release = single_release
+ };
+
+-void __init kcsan_debugfs_init(void)
++static void __init kcsan_debugfs_init(void)
+ {
+ debugfs_create_file("kcsan", 0644, NULL, NULL, &debugfs_ops);
+ }
++
++late_initcall(kcsan_debugfs_init);
+diff --git a/kernel/kcsan/kcsan.h b/kernel/kcsan/kcsan.h
+index 8d4bf3431b3cc..87ccdb3b051fd 100644
+--- a/kernel/kcsan/kcsan.h
++++ b/kernel/kcsan/kcsan.h
+@@ -30,11 +30,6 @@ extern bool kcsan_enabled;
+ void kcsan_save_irqtrace(struct task_struct *task);
+ void kcsan_restore_irqtrace(struct task_struct *task);
+
+-/*
+- * Initialize debugfs file.
+- */
+-void kcsan_debugfs_init(void);
+-
+ /*
+ * Statistics counters displayed via debugfs; should only be modified in
+ * slow-paths.
+diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
+index da6f5213fb74c..2a739c5fcca5a 100644
+--- a/kernel/rcu/tree.c
++++ b/kernel/rcu/tree.c
+@@ -3464,7 +3464,7 @@ static void fill_page_cache_func(struct work_struct *work)
+
+ for (i = 0; i < rcu_min_cached_objs; i++) {
+ bnode = (struct kvfree_rcu_bulk_data *)
+- __get_free_page(GFP_KERNEL | __GFP_NOWARN);
++ __get_free_page(GFP_KERNEL | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN);
+
+ if (bnode) {
+ raw_spin_lock_irqsave(&krcp->lock, flags);
+diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h
+index 2d603771c7dce..0796a75b6e0e8 100644
+--- a/kernel/rcu/tree_plugin.h
++++ b/kernel/rcu/tree_plugin.h
+@@ -1646,7 +1646,11 @@ static bool wake_nocb_gp(struct rcu_data *rdp, bool force,
+ rcu_nocb_unlock_irqrestore(rdp, flags);
+ return false;
+ }
+- del_timer(&rdp->nocb_timer);
++
++ if (READ_ONCE(rdp->nocb_defer_wakeup) > RCU_NOCB_WAKE_NOT) {
++ WRITE_ONCE(rdp->nocb_defer_wakeup, RCU_NOCB_WAKE_NOT);
++ del_timer(&rdp->nocb_timer);
++ }
+ rcu_nocb_unlock_irqrestore(rdp, flags);
+ raw_spin_lock_irqsave(&rdp_gp->nocb_gp_lock, flags);
+ if (force || READ_ONCE(rdp_gp->nocb_gp_sleep)) {
+@@ -2265,7 +2269,6 @@ static bool do_nocb_deferred_wakeup_common(struct rcu_data *rdp)
+ return false;
+ }
+ ndw = READ_ONCE(rdp->nocb_defer_wakeup);
+- WRITE_ONCE(rdp->nocb_defer_wakeup, RCU_NOCB_WAKE_NOT);
+ ret = wake_nocb_gp(rdp, ndw == RCU_NOCB_WAKE_FORCE, flags);
+ trace_rcu_nocb_wake(rcu_state.name, rdp->cpu, TPS("DeferredWake"));
+
+diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
+index 794c2cb945f8b..0eeeeeb66f33a 100644
+--- a/kernel/sched/fair.c
++++ b/kernel/sched/fair.c
+@@ -682,7 +682,13 @@ static u64 __sched_period(unsigned long nr_running)
+ */
+ static u64 sched_slice(struct cfs_rq *cfs_rq, struct sched_entity *se)
+ {
+- u64 slice = __sched_period(cfs_rq->nr_running + !se->on_rq);
++ unsigned int nr_running = cfs_rq->nr_running;
++ u64 slice;
++
++ if (sched_feat(ALT_PERIOD))
++ nr_running = rq_of(cfs_rq)->cfs.h_nr_running;
++
++ slice = __sched_period(nr_running + !se->on_rq);
+
+ for_each_sched_entity(se) {
+ struct load_weight *load;
+@@ -699,6 +705,10 @@ static u64 sched_slice(struct cfs_rq *cfs_rq, struct sched_entity *se)
+ }
+ slice = __calc_delta(slice, se->load.weight, load);
+ }
++
++ if (sched_feat(BASE_SLICE))
++ slice = max(slice, (u64)sysctl_sched_min_granularity);
++
+ return slice;
+ }
+
+@@ -3941,6 +3951,8 @@ static inline void util_est_dequeue(struct cfs_rq *cfs_rq,
+ trace_sched_util_est_cfs_tp(cfs_rq);
+ }
+
++#define UTIL_EST_MARGIN (SCHED_CAPACITY_SCALE / 100)
++
+ /*
+ * Check if a (signed) value is within a specified (unsigned) margin,
+ * based on the observation that:
+@@ -3958,7 +3970,7 @@ static inline void util_est_update(struct cfs_rq *cfs_rq,
+ struct task_struct *p,
+ bool task_sleep)
+ {
+- long last_ewma_diff;
++ long last_ewma_diff, last_enqueued_diff;
+ struct util_est ue;
+
+ if (!sched_feat(UTIL_EST))
+@@ -3979,6 +3991,8 @@ static inline void util_est_update(struct cfs_rq *cfs_rq,
+ if (ue.enqueued & UTIL_AVG_UNCHANGED)
+ return;
+
++ last_enqueued_diff = ue.enqueued;
++
+ /*
+ * Reset EWMA on utilization increases, the moving average is used only
+ * to smooth utilization decreases.
+@@ -3992,12 +4006,17 @@ static inline void util_est_update(struct cfs_rq *cfs_rq,
+ }
+
+ /*
+- * Skip update of task's estimated utilization when its EWMA is
++ * Skip update of task's estimated utilization when its members are
+ * already ~1% close to its last activation value.
+ */
+ last_ewma_diff = ue.enqueued - ue.ewma;
+- if (within_margin(last_ewma_diff, (SCHED_CAPACITY_SCALE / 100)))
++ last_enqueued_diff -= ue.enqueued;
++ if (within_margin(last_ewma_diff, UTIL_EST_MARGIN)) {
++ if (!within_margin(last_enqueued_diff, UTIL_EST_MARGIN))
++ goto done;
++
+ return;
++ }
+
+ /*
+ * To avoid overestimation of actual task utilization, skip updates if
+@@ -6098,6 +6117,24 @@ static int select_idle_core(struct task_struct *p, int core, struct cpumask *cpu
+ return -1;
+ }
+
++/*
++ * Scan the local SMT mask for idle CPUs.
++ */
++static int select_idle_smt(struct task_struct *p, struct sched_domain *sd, int target)
++{
++ int cpu;
++
++ for_each_cpu(cpu, cpu_smt_mask(target)) {
++ if (!cpumask_test_cpu(cpu, p->cpus_ptr) ||
++ !cpumask_test_cpu(cpu, sched_domain_span(sd)))
++ continue;
++ if (available_idle_cpu(cpu) || sched_idle_cpu(cpu))
++ return cpu;
++ }
++
++ return -1;
++}
++
+ #else /* CONFIG_SCHED_SMT */
+
+ static inline void set_idle_cores(int cpu, int val)
+@@ -6114,6 +6151,11 @@ static inline int select_idle_core(struct task_struct *p, int core, struct cpuma
+ return __select_idle_cpu(core);
+ }
+
++static inline int select_idle_smt(struct task_struct *p, struct sched_domain *sd, int target)
++{
++ return -1;
++}
++
+ #endif /* CONFIG_SCHED_SMT */
+
+ /*
+@@ -6121,11 +6163,10 @@ static inline int select_idle_core(struct task_struct *p, int core, struct cpuma
+ * comparing the average scan cost (tracked in sd->avg_scan_cost) against the
+ * average idle time for this rq (as found in rq->avg_idle).
+ */
+-static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, int target)
++static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, bool has_idle_core, int target)
+ {
+ struct cpumask *cpus = this_cpu_cpumask_var_ptr(select_idle_mask);
+ int i, cpu, idle_cpu = -1, nr = INT_MAX;
+- bool smt = test_idle_cores(target, false);
+ int this = smp_processor_id();
+ struct sched_domain *this_sd;
+ u64 time;
+@@ -6136,7 +6177,7 @@ static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, int t
+
+ cpumask_and(cpus, sched_domain_span(sd), p->cpus_ptr);
+
+- if (sched_feat(SIS_PROP) && !smt) {
++ if (sched_feat(SIS_PROP) && !has_idle_core) {
+ u64 avg_cost, avg_idle, span_avg;
+
+ /*
+@@ -6156,7 +6197,7 @@ static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, int t
+ }
+
+ for_each_cpu_wrap(cpu, cpus, target) {
+- if (smt) {
++ if (has_idle_core) {
+ i = select_idle_core(p, cpu, cpus, &idle_cpu);
+ if ((unsigned int)i < nr_cpumask_bits)
+ return i;
+@@ -6170,10 +6211,10 @@ static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, int t
+ }
+ }
+
+- if (smt)
++ if (has_idle_core)
+ set_idle_cores(this, false);
+
+- if (sched_feat(SIS_PROP) && !smt) {
++ if (sched_feat(SIS_PROP) && !has_idle_core) {
+ time = cpu_clock(this) - time;
+ update_avg(&this_sd->avg_scan_cost, time);
+ }
+@@ -6228,6 +6269,7 @@ static inline bool asym_fits_capacity(int task_util, int cpu)
+ */
+ static int select_idle_sibling(struct task_struct *p, int prev, int target)
+ {
++ bool has_idle_core = false;
+ struct sched_domain *sd;
+ unsigned long task_util;
+ int i, recent_used_cpu;
+@@ -6307,7 +6349,17 @@ static int select_idle_sibling(struct task_struct *p, int prev, int target)
+ if (!sd)
+ return target;
+
+- i = select_idle_cpu(p, sd, target);
++ if (sched_smt_active()) {
++ has_idle_core = test_idle_cores(target, false);
++
++ if (!has_idle_core && cpus_share_cache(prev, target)) {
++ i = select_idle_smt(p, sd, prev);
++ if ((unsigned int)i < nr_cpumask_bits)
++ return i;
++ }
++ }
++
++ i = select_idle_cpu(p, sd, has_idle_core, target);
+ if ((unsigned)i < nr_cpumask_bits)
+ return i;
+
+@@ -6518,8 +6570,24 @@ compute_energy(struct task_struct *p, int dst_cpu, struct perf_domain *pd)
+ * its pd list and will not be accounted by compute_energy().
+ */
+ for_each_cpu_and(cpu, pd_mask, cpu_online_mask) {
+- unsigned long cpu_util, util_cfs = cpu_util_next(cpu, p, dst_cpu);
+- struct task_struct *tsk = cpu == dst_cpu ? p : NULL;
++ unsigned long util_freq = cpu_util_next(cpu, p, dst_cpu);
++ unsigned long cpu_util, util_running = util_freq;
++ struct task_struct *tsk = NULL;
++
++ /*
++ * When @p is placed on @cpu:
++ *
++ * util_running = max(cpu_util, cpu_util_est) +
++ * max(task_util, _task_util_est)
++ *
++ * while cpu_util_next is: max(cpu_util + task_util,
++ * cpu_util_est + _task_util_est)
++ */
++ if (cpu == dst_cpu) {
++ tsk = p;
++ util_running =
++ cpu_util_next(cpu, p, -1) + task_util_est(p);
++ }
+
+ /*
+ * Busy time computation: utilization clamping is not
+@@ -6527,7 +6595,7 @@ compute_energy(struct task_struct *p, int dst_cpu, struct perf_domain *pd)
+ * is already enough to scale the EM reported power
+ * consumption at the (eventually clamped) cpu_capacity.
+ */
+- sum_util += effective_cpu_util(cpu, util_cfs, cpu_cap,
++ sum_util += effective_cpu_util(cpu, util_running, cpu_cap,
+ ENERGY_UTIL, NULL);
+
+ /*
+@@ -6537,7 +6605,7 @@ compute_energy(struct task_struct *p, int dst_cpu, struct perf_domain *pd)
+ * NOTE: in case RT tasks are running, by default the
+ * FREQUENCY_UTIL's utilization can be max OPP.
+ */
+- cpu_util = effective_cpu_util(cpu, util_cfs, cpu_cap,
++ cpu_util = effective_cpu_util(cpu, util_freq, cpu_cap,
+ FREQUENCY_UTIL, tsk);
+ max_util = max(max_util, cpu_util);
+ }
+@@ -7539,6 +7607,10 @@ int can_migrate_task(struct task_struct *p, struct lb_env *env)
+ if (throttled_lb_pair(task_group(p), env->src_cpu, env->dst_cpu))
+ return 0;
+
++ /* Disregard pcpu kthreads; they are where they need to be. */
++ if ((p->flags & PF_KTHREAD) && kthread_is_per_cpu(p))
++ return 0;
++
+ if (!cpumask_test_cpu(env->dst_cpu, p->cpus_ptr)) {
+ int cpu;
+
+diff --git a/kernel/sched/features.h b/kernel/sched/features.h
+index 1bc2b158fc515..e911111df83a7 100644
+--- a/kernel/sched/features.h
++++ b/kernel/sched/features.h
+@@ -90,3 +90,6 @@ SCHED_FEAT(WA_BIAS, true)
+ */
+ SCHED_FEAT(UTIL_EST, true)
+ SCHED_FEAT(UTIL_EST_FASTUP, true)
++
++SCHED_FEAT(ALT_PERIOD, true)
++SCHED_FEAT(BASE_SLICE, true)
+diff --git a/kernel/sched/psi.c b/kernel/sched/psi.c
+index 967732c0766c5..651218ded9817 100644
+--- a/kernel/sched/psi.c
++++ b/kernel/sched/psi.c
+@@ -711,14 +711,15 @@ static void psi_group_change(struct psi_group *group, int cpu,
+ for (t = 0, m = clear; m; m &= ~(1 << t), t++) {
+ if (!(m & (1 << t)))
+ continue;
+- if (groupc->tasks[t] == 0 && !psi_bug) {
++ if (groupc->tasks[t]) {
++ groupc->tasks[t]--;
++ } else if (!psi_bug) {
+ printk_deferred(KERN_ERR "psi: task underflow! cpu=%d t=%d tasks=[%u %u %u %u] clear=%x set=%x\n",
+ cpu, t, groupc->tasks[0],
+ groupc->tasks[1], groupc->tasks[2],
+ groupc->tasks[3], clear, set);
+ psi_bug = 1;
+ }
+- groupc->tasks[t]--;
+ }
+
+ for (t = 0; set; set &= ~(1 << t), t++)
+diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c
+index 09d35044bd889..12f80587e127c 100644
+--- a/kernel/sched/topology.c
++++ b/kernel/sched/topology.c
+@@ -723,35 +723,6 @@ cpu_attach_domain(struct sched_domain *sd, struct root_domain *rd, int cpu)
+ for (tmp = sd; tmp; tmp = tmp->parent)
+ numa_distance += !!(tmp->flags & SD_NUMA);
+
+- /*
+- * FIXME: Diameter >=3 is misrepresented.
+- *
+- * Smallest diameter=3 topology is:
+- *
+- * node 0 1 2 3
+- * 0: 10 20 30 40
+- * 1: 20 10 20 30
+- * 2: 30 20 10 20
+- * 3: 40 30 20 10
+- *
+- * 0 --- 1 --- 2 --- 3
+- *
+- * NUMA-3 0-3 N/A N/A 0-3
+- * groups: {0-2},{1-3} {1-3},{0-2}
+- *
+- * NUMA-2 0-2 0-3 0-3 1-3
+- * groups: {0-1},{1-3} {0-2},{2-3} {1-3},{0-1} {2-3},{0-2}
+- *
+- * NUMA-1 0-1 0-2 1-3 2-3
+- * groups: {0},{1} {1},{2},{0} {2},{3},{1} {3},{2}
+- *
+- * NUMA-0 0 1 2 3
+- *
+- * The NUMA-2 groups for nodes 0 and 3 are obviously buggered, as the
+- * group span isn't a subset of the domain span.
+- */
+- WARN_ONCE(numa_distance > 2, "Shortest NUMA path spans too many nodes\n");
+-
+ sched_domain_debug(sd, cpu);
+
+ rq_attach_root(rq, rd);
+@@ -982,6 +953,31 @@ static void init_overlap_sched_group(struct sched_domain *sd,
+ sg->sgc->max_capacity = SCHED_CAPACITY_SCALE;
+ }
+
++static struct sched_domain *
++find_descended_sibling(struct sched_domain *sd, struct sched_domain *sibling)
++{
++ /*
++ * The proper descendant would be the one whose child won't span out
++ * of sd
++ */
++ while (sibling->child &&
++ !cpumask_subset(sched_domain_span(sibling->child),
++ sched_domain_span(sd)))
++ sibling = sibling->child;
++
++ /*
++ * As we are referencing sgc across different topology level, we need
++ * to go down to skip those sched_domains which don't contribute to
++ * scheduling because they will be degenerated in cpu_attach_domain
++ */
++ while (sibling->child &&
++ cpumask_equal(sched_domain_span(sibling->child),
++ sched_domain_span(sibling)))
++ sibling = sibling->child;
++
++ return sibling;
++}
++
+ static int
+ build_overlap_sched_groups(struct sched_domain *sd, int cpu)
+ {
+@@ -1015,6 +1011,41 @@ build_overlap_sched_groups(struct sched_domain *sd, int cpu)
+ if (!cpumask_test_cpu(i, sched_domain_span(sibling)))
+ continue;
+
++ /*
++ * Usually we build sched_group by sibling's child sched_domain
++ * But for machines whose NUMA diameter are 3 or above, we move
++ * to build sched_group by sibling's proper descendant's child
++ * domain because sibling's child sched_domain will span out of
++ * the sched_domain being built as below.
++ *
++ * Smallest diameter=3 topology is:
++ *
++ * node 0 1 2 3
++ * 0: 10 20 30 40
++ * 1: 20 10 20 30
++ * 2: 30 20 10 20
++ * 3: 40 30 20 10
++ *
++ * 0 --- 1 --- 2 --- 3
++ *
++ * NUMA-3 0-3 N/A N/A 0-3
++ * groups: {0-2},{1-3} {1-3},{0-2}
++ *
++ * NUMA-2 0-2 0-3 0-3 1-3
++ * groups: {0-1},{1-3} {0-2},{2-3} {1-3},{0-1} {2-3},{0-2}
++ *
++ * NUMA-1 0-1 0-2 1-3 2-3
++ * groups: {0},{1} {1},{2},{0} {2},{3},{1} {3},{2}
++ *
++ * NUMA-0 0 1 2 3
++ *
++ * The NUMA-2 groups for nodes 0 and 3 are obviously buggered, as the
++ * group span isn't a subset of the domain span.
++ */
++ if (sibling->child &&
++ !cpumask_subset(sched_domain_span(sibling->child), span))
++ sibling = find_descended_sibling(sd, sibling);
++
+ sg = build_group_from_child_sched_domain(sibling, cpu);
+ if (!sg)
+ goto fail;
+@@ -1022,7 +1053,7 @@ build_overlap_sched_groups(struct sched_domain *sd, int cpu)
+ sg_span = sched_group_span(sg);
+ cpumask_or(covered, covered, sg_span);
+
+- init_overlap_sched_group(sd, sg);
++ init_overlap_sched_group(sibling, sg);
+
+ if (!first)
+ first = sg;
+diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
+index bf540f5a4115a..dd5697d7347b1 100644
+--- a/kernel/time/posix-timers.c
++++ b/kernel/time/posix-timers.c
+@@ -1191,8 +1191,8 @@ SYSCALL_DEFINE2(clock_adjtime32, clockid_t, which_clock,
+
+ err = do_clock_adjtime(which_clock, &ktx);
+
+- if (err >= 0)
+- err = put_old_timex32(utp, &ktx);
++ if (err >= 0 && put_old_timex32(utp, &ktx))
++ return -EFAULT;
+
+ return err;
+ }
+diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
+index 3ba52d4e13142..826b88b727a62 100644
+--- a/kernel/trace/ftrace.c
++++ b/kernel/trace/ftrace.c
+@@ -5631,7 +5631,10 @@ int ftrace_regex_release(struct inode *inode, struct file *file)
+
+ parser = &iter->parser;
+ if (trace_parser_loaded(parser)) {
+- ftrace_match_records(iter->hash, parser->buffer, parser->idx);
++ int enable = !(iter->flags & FTRACE_ITER_NOTRACE);
++
++ ftrace_process_regex(iter, parser->buffer,
++ parser->idx, enable);
+ }
+
+ trace_parser_put(parser);
+diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
+index c0c9aa5cd8e2c..67c01dc5cdeb7 100644
+--- a/kernel/trace/trace.c
++++ b/kernel/trace/trace.c
+@@ -2390,14 +2390,13 @@ static void tracing_stop_tr(struct trace_array *tr)
+
+ static int trace_save_cmdline(struct task_struct *tsk)
+ {
+- unsigned pid, idx;
++ unsigned tpid, idx;
+
+ /* treat recording of idle task as a success */
+ if (!tsk->pid)
+ return 1;
+
+- if (unlikely(tsk->pid > PID_MAX_DEFAULT))
+- return 0;
++ tpid = tsk->pid & (PID_MAX_DEFAULT - 1);
+
+ /*
+ * It's not the end of the world if we don't get
+@@ -2408,26 +2407,15 @@ static int trace_save_cmdline(struct task_struct *tsk)
+ if (!arch_spin_trylock(&trace_cmdline_lock))
+ return 0;
+
+- idx = savedcmd->map_pid_to_cmdline[tsk->pid];
++ idx = savedcmd->map_pid_to_cmdline[tpid];
+ if (idx == NO_CMDLINE_MAP) {
+ idx = (savedcmd->cmdline_idx + 1) % savedcmd->cmdline_num;
+
+- /*
+- * Check whether the cmdline buffer at idx has a pid
+- * mapped. We are going to overwrite that entry so we
+- * need to clear the map_pid_to_cmdline. Otherwise we
+- * would read the new comm for the old pid.
+- */
+- pid = savedcmd->map_cmdline_to_pid[idx];
+- if (pid != NO_CMDLINE_MAP)
+- savedcmd->map_pid_to_cmdline[pid] = NO_CMDLINE_MAP;
+-
+- savedcmd->map_cmdline_to_pid[idx] = tsk->pid;
+- savedcmd->map_pid_to_cmdline[tsk->pid] = idx;
+-
++ savedcmd->map_pid_to_cmdline[tpid] = idx;
+ savedcmd->cmdline_idx = idx;
+ }
+
++ savedcmd->map_cmdline_to_pid[idx] = tsk->pid;
+ set_cmdline(idx, tsk->comm);
+
+ arch_spin_unlock(&trace_cmdline_lock);
+@@ -2438,6 +2426,7 @@ static int trace_save_cmdline(struct task_struct *tsk)
+ static void __trace_find_cmdline(int pid, char comm[])
+ {
+ unsigned map;
++ int tpid;
+
+ if (!pid) {
+ strcpy(comm, "<idle>");
+@@ -2449,16 +2438,16 @@ static void __trace_find_cmdline(int pid, char comm[])
+ return;
+ }
+
+- if (pid > PID_MAX_DEFAULT) {
+- strcpy(comm, "<...>");
+- return;
++ tpid = pid & (PID_MAX_DEFAULT - 1);
++ map = savedcmd->map_pid_to_cmdline[tpid];
++ if (map != NO_CMDLINE_MAP) {
++ tpid = savedcmd->map_cmdline_to_pid[map];
++ if (tpid == pid) {
++ strlcpy(comm, get_saved_cmdlines(map), TASK_COMM_LEN);
++ return;
++ }
+ }
+-
+- map = savedcmd->map_pid_to_cmdline[pid];
+- if (map != NO_CMDLINE_MAP)
+- strlcpy(comm, get_saved_cmdlines(map), TASK_COMM_LEN);
+- else
+- strcpy(comm, "<...>");
++ strcpy(comm, "<...>");
+ }
+
+ void trace_find_cmdline(int pid, char comm[])
+diff --git a/kernel/trace/trace_clock.c b/kernel/trace/trace_clock.c
+index aaf6793ededaa..c1637f90c8a38 100644
+--- a/kernel/trace/trace_clock.c
++++ b/kernel/trace/trace_clock.c
+@@ -95,33 +95,49 @@ u64 notrace trace_clock_global(void)
+ {
+ unsigned long flags;
+ int this_cpu;
+- u64 now;
++ u64 now, prev_time;
+
+ raw_local_irq_save(flags);
+
+ this_cpu = raw_smp_processor_id();
+- now = sched_clock_cpu(this_cpu);
++
+ /*
+- * If in an NMI context then dont risk lockups and return the
+- * cpu_clock() time:
++ * The global clock "guarantees" that the events are ordered
++ * between CPUs. But if two events on two different CPUS call
++ * trace_clock_global at roughly the same time, it really does
++ * not matter which one gets the earlier time. Just make sure
++ * that the same CPU will always show a monotonic clock.
++ *
++ * Use a read memory barrier to get the latest written
++ * time that was recorded.
+ */
+- if (unlikely(in_nmi()))
+- goto out;
++ smp_rmb();
++ prev_time = READ_ONCE(trace_clock_struct.prev_time);
++ now = sched_clock_cpu(this_cpu);
+
+- arch_spin_lock(&trace_clock_struct.lock);
++ /* Make sure that now is always greater than prev_time */
++ if ((s64)(now - prev_time) < 0)
++ now = prev_time + 1;
+
+ /*
+- * TODO: if this happens often then maybe we should reset
+- * my_scd->clock to prev_time+1, to make sure
+- * we start ticking with the local clock from now on?
++ * If in an NMI context then dont risk lockups and simply return
++ * the current time.
+ */
+- if ((s64)(now - trace_clock_struct.prev_time) < 0)
+- now = trace_clock_struct.prev_time + 1;
++ if (unlikely(in_nmi()))
++ goto out;
+
+- trace_clock_struct.prev_time = now;
++ /* Tracing can cause strange recursion, always use a try lock */
++ if (arch_spin_trylock(&trace_clock_struct.lock)) {
++ /* Reread prev_time in case it was already updated */
++ prev_time = READ_ONCE(trace_clock_struct.prev_time);
++ if ((s64)(now - prev_time) < 0)
++ now = prev_time + 1;
+
+- arch_spin_unlock(&trace_clock_struct.lock);
++ trace_clock_struct.prev_time = now;
+
++ /* The unlock acts as the wmb for the above rmb */
++ arch_spin_unlock(&trace_clock_struct.lock);
++ }
+ out:
+ raw_local_irq_restore(flags);
+
+diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
+index c70d6347afa2b..921d0a654243c 100644
+--- a/lib/dynamic_debug.c
++++ b/lib/dynamic_debug.c
+@@ -396,7 +396,7 @@ static int ddebug_parse_query(char *words[], int nwords,
+ /* tail :$info is function or line-range */
+ fline = strchr(query->filename, ':');
+ if (!fline)
+- break;
++ continue;
+ *fline++ = '\0';
+ if (isalpha(*fline) || *fline == '*' || *fline == '?') {
+ /* take as function name */
+diff --git a/lib/vsprintf.c b/lib/vsprintf.c
+index 41ddc353ebb82..39ef2e314da5e 100644
+--- a/lib/vsprintf.c
++++ b/lib/vsprintf.c
+@@ -3135,8 +3135,6 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
+ switch (*fmt) {
+ case 'S':
+ case 's':
+- case 'F':
+- case 'f':
+ case 'x':
+ case 'K':
+ case 'e':
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c
+index cfc72873961d9..4bb3cdfc47f87 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -764,32 +764,36 @@ static inline void clear_page_guard(struct zone *zone, struct page *page,
+ */
+ void init_mem_debugging_and_hardening(void)
+ {
++ bool page_poisoning_requested = false;
++
++#ifdef CONFIG_PAGE_POISONING
++ /*
++ * Page poisoning is debug page alloc for some arches. If
++ * either of those options are enabled, enable poisoning.
++ */
++ if (page_poisoning_enabled() ||
++ (!IS_ENABLED(CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC) &&
++ debug_pagealloc_enabled())) {
++ static_branch_enable(&_page_poisoning_enabled);
++ page_poisoning_requested = true;
++ }
++#endif
++
+ if (_init_on_alloc_enabled_early) {
+- if (page_poisoning_enabled())
++ if (page_poisoning_requested)
+ pr_info("mem auto-init: CONFIG_PAGE_POISONING is on, "
+ "will take precedence over init_on_alloc\n");
+ else
+ static_branch_enable(&init_on_alloc);
+ }
+ if (_init_on_free_enabled_early) {
+- if (page_poisoning_enabled())
++ if (page_poisoning_requested)
+ pr_info("mem auto-init: CONFIG_PAGE_POISONING is on, "
+ "will take precedence over init_on_free\n");
+ else
+ static_branch_enable(&init_on_free);
+ }
+
+-#ifdef CONFIG_PAGE_POISONING
+- /*
+- * Page poisoning is debug page alloc for some arches. If
+- * either of those options are enabled, enable poisoning.
+- */
+- if (page_poisoning_enabled() ||
+- (!IS_ENABLED(CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC) &&
+- debug_pagealloc_enabled()))
+- static_branch_enable(&_page_poisoning_enabled);
+-#endif
+-
+ #ifdef CONFIG_DEBUG_PAGEALLOC
+ if (!debug_pagealloc_enabled())
+ return;
+diff --git a/net/bluetooth/ecdh_helper.h b/net/bluetooth/ecdh_helper.h
+index a6f8d03d4aaf6..830723971cf83 100644
+--- a/net/bluetooth/ecdh_helper.h
++++ b/net/bluetooth/ecdh_helper.h
+@@ -25,6 +25,6 @@
+
+ int compute_ecdh_secret(struct crypto_kpp *tfm, const u8 pair_public_key[64],
+ u8 secret[32]);
+-int set_ecdh_privkey(struct crypto_kpp *tfm, const u8 *private_key);
++int set_ecdh_privkey(struct crypto_kpp *tfm, const u8 private_key[32]);
+ int generate_ecdh_public_key(struct crypto_kpp *tfm, u8 public_key[64]);
+ int generate_ecdh_keys(struct crypto_kpp *tfm, u8 public_key[64]);
+diff --git a/net/ceph/auth_x.c b/net/ceph/auth_x.c
+index ca44c327baced..79641c4afee93 100644
+--- a/net/ceph/auth_x.c
++++ b/net/ceph/auth_x.c
+@@ -526,7 +526,7 @@ static int ceph_x_build_request(struct ceph_auth_client *ac,
+ if (ret < 0)
+ return ret;
+
+- auth->struct_v = 2; /* nautilus+ */
++ auth->struct_v = 3; /* nautilus+ */
+ auth->key = 0;
+ for (u = (u64 *)enc_buf; u + 1 <= (u64 *)(enc_buf + ret); u++)
+ auth->key ^= *(__le64 *)u;
+diff --git a/net/ceph/decode.c b/net/ceph/decode.c
+index b44f7651be04b..bc109a1a4616f 100644
+--- a/net/ceph/decode.c
++++ b/net/ceph/decode.c
+@@ -4,6 +4,7 @@
+ #include <linux/inet.h>
+
+ #include <linux/ceph/decode.h>
++#include <linux/ceph/messenger.h> /* for ceph_pr_addr() */
+
+ static int
+ ceph_decode_entity_addr_versioned(void **p, void *end,
+@@ -110,6 +111,7 @@ int ceph_decode_entity_addrvec(void **p, void *end, bool msgr2,
+ }
+
+ ceph_decode_32_safe(p, end, addr_cnt, e_inval);
++ dout("%s addr_cnt %d\n", __func__, addr_cnt);
+
+ found = false;
+ for (i = 0; i < addr_cnt; i++) {
+@@ -117,6 +119,7 @@ int ceph_decode_entity_addrvec(void **p, void *end, bool msgr2,
+ if (ret)
+ return ret;
+
++ dout("%s i %d addr %s\n", __func__, i, ceph_pr_addr(&tmp_addr));
+ if (tmp_addr.type == my_type) {
+ if (found) {
+ pr_err("another match of type %d in addrvec\n",
+@@ -128,13 +131,18 @@ int ceph_decode_entity_addrvec(void **p, void *end, bool msgr2,
+ found = true;
+ }
+ }
+- if (!found && addr_cnt != 0) {
+- pr_err("no match of type %d in addrvec\n",
+- le32_to_cpu(my_type));
+- return -ENOENT;
+- }
+
+- return 0;
++ if (found)
++ return 0;
++
++ if (!addr_cnt)
++ return 0; /* normal -- e.g. unused OSD id/slot */
++
++ if (addr_cnt == 1 && !memchr_inv(&tmp_addr, 0, sizeof(tmp_addr)))
++ return 0; /* weird but effectively the same as !addr_cnt */
++
++ pr_err("no match of type %d in addrvec\n", le32_to_cpu(my_type));
++ return -ENOENT;
+
+ e_inval:
+ return -EINVAL;
+diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
+index 92a0b67b27282..77d924ab8cdb9 100644
+--- a/net/openvswitch/actions.c
++++ b/net/openvswitch/actions.c
+@@ -827,17 +827,17 @@ static void ovs_fragment(struct net *net, struct vport *vport,
+ }
+
+ if (key->eth.type == htons(ETH_P_IP)) {
+- struct dst_entry ovs_dst;
++ struct rtable ovs_rt = { 0 };
+ unsigned long orig_dst;
+
+ prepare_frag(vport, skb, orig_network_offset,
+ ovs_key_mac_proto(key));
+- dst_init(&ovs_dst, &ovs_dst_ops, NULL, 1,
++ dst_init(&ovs_rt.dst, &ovs_dst_ops, NULL, 1,
+ DST_OBSOLETE_NONE, DST_NOCOUNT);
+- ovs_dst.dev = vport->dev;
++ ovs_rt.dst.dev = vport->dev;
+
+ orig_dst = skb->_skb_refdst;
+- skb_dst_set_noref(skb, &ovs_dst);
++ skb_dst_set_noref(skb, &ovs_rt.dst);
+ IPCB(skb)->frag_max_size = mru;
+
+ ip_do_fragment(net, skb->sk, skb, ovs_vport_output);
+diff --git a/net/sched/sch_frag.c b/net/sched/sch_frag.c
+index e1e77d3fb6c02..8c06381391d6f 100644
+--- a/net/sched/sch_frag.c
++++ b/net/sched/sch_frag.c
+@@ -90,16 +90,16 @@ static int sch_fragment(struct net *net, struct sk_buff *skb,
+ }
+
+ if (skb_protocol(skb, true) == htons(ETH_P_IP)) {
+- struct dst_entry sch_frag_dst;
++ struct rtable sch_frag_rt = { 0 };
+ unsigned long orig_dst;
+
+ sch_frag_prepare_frag(skb, xmit);
+- dst_init(&sch_frag_dst, &sch_frag_dst_ops, NULL, 1,
++ dst_init(&sch_frag_rt.dst, &sch_frag_dst_ops, NULL, 1,
+ DST_OBSOLETE_NONE, DST_NOCOUNT);
+- sch_frag_dst.dev = skb->dev;
++ sch_frag_rt.dst.dev = skb->dev;
+
+ orig_dst = skb->_skb_refdst;
+- skb_dst_set_noref(skb, &sch_frag_dst);
++ skb_dst_set_noref(skb, &sch_frag_rt.dst);
+ IPCB(skb)->frag_max_size = mru;
+
+ ret = ip_do_fragment(net, skb->sk, skb, sch_frag_xmit);
+diff --git a/security/commoncap.c b/security/commoncap.c
+index 1c519c8752176..5cdeb73ca8fa9 100644
+--- a/security/commoncap.c
++++ b/security/commoncap.c
+@@ -400,7 +400,7 @@ int cap_inode_getsecurity(struct user_namespace *mnt_userns,
+ &tmpbuf, size, GFP_NOFS);
+ dput(dentry);
+
+- if (ret < 0)
++ if (ret < 0 || !tmpbuf)
+ return ret;
+
+ fs_ns = inode->i_sb->s_user_ns;
+diff --git a/sound/isa/sb/emu8000.c b/sound/isa/sb/emu8000.c
+index 0aa545ac6e60c..1c90421a88dcd 100644
+--- a/sound/isa/sb/emu8000.c
++++ b/sound/isa/sb/emu8000.c
+@@ -1029,8 +1029,10 @@ snd_emu8000_create_mixer(struct snd_card *card, struct snd_emu8000 *emu)
+
+ memset(emu->controls, 0, sizeof(emu->controls));
+ for (i = 0; i < EMU8000_NUM_CONTROLS; i++) {
+- if ((err = snd_ctl_add(card, emu->controls[i] = snd_ctl_new1(mixer_defs[i], emu))) < 0)
++ if ((err = snd_ctl_add(card, emu->controls[i] = snd_ctl_new1(mixer_defs[i], emu))) < 0) {
++ emu->controls[i] = NULL;
+ goto __error;
++ }
+ }
+ return 0;
+
+diff --git a/sound/isa/sb/sb16_csp.c b/sound/isa/sb/sb16_csp.c
+index 8635a2b6b36b2..4789345a8fdde 100644
+--- a/sound/isa/sb/sb16_csp.c
++++ b/sound/isa/sb/sb16_csp.c
+@@ -1045,10 +1045,14 @@ static int snd_sb_qsound_build(struct snd_sb_csp * p)
+
+ spin_lock_init(&p->q_lock);
+
+- if ((err = snd_ctl_add(card, p->qsound_switch = snd_ctl_new1(&snd_sb_qsound_switch, p))) < 0)
++ if ((err = snd_ctl_add(card, p->qsound_switch = snd_ctl_new1(&snd_sb_qsound_switch, p))) < 0) {
++ p->qsound_switch = NULL;
+ goto __error;
+- if ((err = snd_ctl_add(card, p->qsound_space = snd_ctl_new1(&snd_sb_qsound_space, p))) < 0)
++ }
++ if ((err = snd_ctl_add(card, p->qsound_space = snd_ctl_new1(&snd_sb_qsound_space, p))) < 0) {
++ p->qsound_space = NULL;
+ goto __error;
++ }
+
+ return 0;
+
+diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
+index dfef9c17e1404..d111258c6f458 100644
+--- a/sound/pci/hda/patch_conexant.c
++++ b/sound/pci/hda/patch_conexant.c
+@@ -930,18 +930,18 @@ static const struct snd_pci_quirk cxt5066_fixups[] = {
+ SND_PCI_QUIRK(0x103c, 0x8079, "HP EliteBook 840 G3", CXT_FIXUP_HP_DOCK),
+ SND_PCI_QUIRK(0x103c, 0x807C, "HP EliteBook 820 G3", CXT_FIXUP_HP_DOCK),
+ SND_PCI_QUIRK(0x103c, 0x80FD, "HP ProBook 640 G2", CXT_FIXUP_HP_DOCK),
+- SND_PCI_QUIRK(0x103c, 0x828c, "HP EliteBook 840 G4", CXT_FIXUP_HP_DOCK),
+- SND_PCI_QUIRK(0x103c, 0x83b2, "HP EliteBook 840 G5", CXT_FIXUP_HP_DOCK),
+- SND_PCI_QUIRK(0x103c, 0x83b3, "HP EliteBook 830 G5", CXT_FIXUP_HP_DOCK),
+- SND_PCI_QUIRK(0x103c, 0x83d3, "HP ProBook 640 G4", CXT_FIXUP_HP_DOCK),
+- SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE),
+ SND_PCI_QUIRK(0x103c, 0x8115, "HP Z1 Gen3", CXT_FIXUP_HP_GATE_MIC),
+ SND_PCI_QUIRK(0x103c, 0x814f, "HP ZBook 15u G3", CXT_FIXUP_MUTE_LED_GPIO),
++ SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE),
+ SND_PCI_QUIRK(0x103c, 0x822e, "HP ProBook 440 G4", CXT_FIXUP_MUTE_LED_GPIO),
+- SND_PCI_QUIRK(0x103c, 0x836e, "HP ProBook 455 G5", CXT_FIXUP_MUTE_LED_GPIO),
+- SND_PCI_QUIRK(0x103c, 0x837f, "HP ProBook 470 G5", CXT_FIXUP_MUTE_LED_GPIO),
++ SND_PCI_QUIRK(0x103c, 0x828c, "HP EliteBook 840 G4", CXT_FIXUP_HP_DOCK),
+ SND_PCI_QUIRK(0x103c, 0x8299, "HP 800 G3 SFF", CXT_FIXUP_HP_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x103c, 0x829a, "HP 800 G3 DM", CXT_FIXUP_HP_MIC_NO_PRESENCE),
++ SND_PCI_QUIRK(0x103c, 0x836e, "HP ProBook 455 G5", CXT_FIXUP_MUTE_LED_GPIO),
++ SND_PCI_QUIRK(0x103c, 0x837f, "HP ProBook 470 G5", CXT_FIXUP_MUTE_LED_GPIO),
++ SND_PCI_QUIRK(0x103c, 0x83b2, "HP EliteBook 840 G5", CXT_FIXUP_HP_DOCK),
++ SND_PCI_QUIRK(0x103c, 0x83b3, "HP EliteBook 830 G5", CXT_FIXUP_HP_DOCK),
++ SND_PCI_QUIRK(0x103c, 0x83d3, "HP ProBook 640 G4", CXT_FIXUP_HP_DOCK),
+ SND_PCI_QUIRK(0x103c, 0x8402, "HP ProBook 645 G4", CXT_FIXUP_MUTE_LED_GPIO),
+ SND_PCI_QUIRK(0x103c, 0x8427, "HP ZBook Studio G5", CXT_FIXUP_HP_ZBOOK_MUTE_LED),
+ SND_PCI_QUIRK(0x103c, 0x844f, "HP ZBook Studio G5", CXT_FIXUP_HP_ZBOOK_MUTE_LED),
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index a7544b77d3f7c..d05d16ddbdf2c 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -2552,8 +2552,10 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x1558, 0x65d1, "Clevo PB51[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
+ SND_PCI_QUIRK(0x1558, 0x65d2, "Clevo PB51R[CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
+ SND_PCI_QUIRK(0x1558, 0x65e1, "Clevo PB51[ED][DF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
++ SND_PCI_QUIRK(0x1558, 0x65e5, "Clevo PC50D[PRS](?:-D|-G)?", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
+ SND_PCI_QUIRK(0x1558, 0x67d1, "Clevo PB71[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
+ SND_PCI_QUIRK(0x1558, 0x67e1, "Clevo PB71[DE][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
++ SND_PCI_QUIRK(0x1558, 0x67e5, "Clevo PC70D[PRS](?:-D|-G)?", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
+ SND_PCI_QUIRK(0x1558, 0x70d1, "Clevo PC70[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
+ SND_PCI_QUIRK(0x1558, 0x7714, "Clevo X170", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
+ SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
+@@ -4438,6 +4440,25 @@ static void alc236_fixup_hp_mute_led(struct hda_codec *codec,
+ alc236_fixup_hp_coef_micmute_led(codec, fix, action);
+ }
+
++static void alc236_fixup_hp_micmute_led_vref(struct hda_codec *codec,
++ const struct hda_fixup *fix, int action)
++{
++ struct alc_spec *spec = codec->spec;
++
++ if (action == HDA_FIXUP_ACT_PRE_PROBE) {
++ spec->cap_mute_led_nid = 0x1a;
++ snd_hda_gen_add_micmute_led_cdev(codec, vref_micmute_led_set);
++ codec->power_filter = led_power_filter;
++ }
++}
++
++static void alc236_fixup_hp_mute_led_micmute_vref(struct hda_codec *codec,
++ const struct hda_fixup *fix, int action)
++{
++ alc236_fixup_hp_mute_led_coefbit(codec, fix, action);
++ alc236_fixup_hp_micmute_led_vref(codec, fix, action);
++}
++
+ #if IS_REACHABLE(CONFIG_INPUT)
+ static void gpio2_mic_hotkey_event(struct hda_codec *codec,
+ struct hda_jack_callback *event)
+@@ -6400,6 +6421,7 @@ enum {
+ ALC285_FIXUP_HP_MUTE_LED,
+ ALC236_FIXUP_HP_GPIO_LED,
+ ALC236_FIXUP_HP_MUTE_LED,
++ ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF,
+ ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET,
+ ALC295_FIXUP_ASUS_MIC_NO_PRESENCE,
+ ALC269VC_FIXUP_ACER_VCOPPERBOX_PINS,
+@@ -6415,6 +6437,8 @@ enum {
+ ALC269_FIXUP_LEMOTE_A1802,
+ ALC269_FIXUP_LEMOTE_A190X,
+ ALC256_FIXUP_INTEL_NUC8_RUGGED,
++ ALC233_FIXUP_INTEL_NUC8_DMIC,
++ ALC233_FIXUP_INTEL_NUC8_BOOST,
+ ALC256_FIXUP_INTEL_NUC10,
+ ALC255_FIXUP_XIAOMI_HEADSET_MIC,
+ ALC274_FIXUP_HP_MIC,
+@@ -7136,6 +7160,16 @@ static const struct hda_fixup alc269_fixups[] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = alc233_fixup_lenovo_line2_mic_hotkey,
+ },
++ [ALC233_FIXUP_INTEL_NUC8_DMIC] = {
++ .type = HDA_FIXUP_FUNC,
++ .v.func = alc_fixup_inv_dmic,
++ .chained = true,
++ .chain_id = ALC233_FIXUP_INTEL_NUC8_BOOST,
++ },
++ [ALC233_FIXUP_INTEL_NUC8_BOOST] = {
++ .type = HDA_FIXUP_FUNC,
++ .v.func = alc269_fixup_limit_int_mic_boost
++ },
+ [ALC255_FIXUP_DELL_SPK_NOISE] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = alc_fixup_disable_aamix,
+@@ -7646,6 +7680,10 @@ static const struct hda_fixup alc269_fixups[] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = alc236_fixup_hp_mute_led,
+ },
++ [ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF] = {
++ .type = HDA_FIXUP_FUNC,
++ .v.func = alc236_fixup_hp_mute_led_micmute_vref,
++ },
+ [ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET] = {
+ .type = HDA_FIXUP_VERBS,
+ .v.verbs = (const struct hda_verb[]) {
+@@ -8051,6 +8089,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x103c, 0x221c, "HP EliteBook 755 G2", ALC280_FIXUP_HP_HEADSET_MIC),
+ SND_PCI_QUIRK(0x103c, 0x802e, "HP Z240 SFF", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x103c, 0x802f, "HP Z240", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
++ SND_PCI_QUIRK(0x103c, 0x8077, "HP", ALC256_FIXUP_HP_HEADSET_MIC),
++ SND_PCI_QUIRK(0x103c, 0x8158, "HP", ALC256_FIXUP_HP_HEADSET_MIC),
+ SND_PCI_QUIRK(0x103c, 0x820d, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3),
+ SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC),
+ SND_PCI_QUIRK(0x103c, 0x827e, "HP x360", ALC295_FIXUP_HP_X360),
+@@ -8063,6 +8103,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x103c, 0x869d, "HP", ALC236_FIXUP_HP_MUTE_LED),
+ SND_PCI_QUIRK(0x103c, 0x8724, "HP EliteBook 850 G7", ALC285_FIXUP_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x8729, "HP", ALC285_FIXUP_HP_GPIO_LED),
++ SND_PCI_QUIRK(0x103c, 0x8730, "HP ProBook 445 G7", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
+ SND_PCI_QUIRK(0x103c, 0x8736, "HP", ALC285_FIXUP_HP_GPIO_AMP_INIT),
+ SND_PCI_QUIRK(0x103c, 0x8760, "HP", ALC285_FIXUP_HP_MUTE_LED),
+ SND_PCI_QUIRK(0x103c, 0x877a, "HP", ALC285_FIXUP_HP_MUTE_LED),
+@@ -8113,6 +8154,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC),
+ SND_PCI_QUIRK(0x1043, 0x1d4e, "ASUS TM420", ALC256_FIXUP_ASUS_HPE),
+ SND_PCI_QUIRK(0x1043, 0x1e11, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA502),
++ SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401),
+ SND_PCI_QUIRK(0x1043, 0x1f11, "ASUS Zephyrus G14", ALC289_FIXUP_ASUS_GA401),
+ SND_PCI_QUIRK(0x1043, 0x1881, "ASUS Zephyrus S/M", ALC294_FIXUP_ASUS_GX502_PINS),
+ SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2),
+@@ -8279,6 +8321,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x10ec, 0x118c, "Medion EE4254 MD62100", ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE),
+ SND_PCI_QUIRK(0x1c06, 0x2013, "Lemote A1802", ALC269_FIXUP_LEMOTE_A1802),
+ SND_PCI_QUIRK(0x1c06, 0x2015, "Lemote A190X", ALC269_FIXUP_LEMOTE_A190X),
++ SND_PCI_QUIRK(0x8086, 0x2074, "Intel NUC 8", ALC233_FIXUP_INTEL_NUC8_DMIC),
+ SND_PCI_QUIRK(0x8086, 0x2080, "Intel NUC 8 Rugged", ALC256_FIXUP_INTEL_NUC8_RUGGED),
+ SND_PCI_QUIRK(0x8086, 0x2081, "Intel NUC 10", ALC256_FIXUP_INTEL_NUC10),
+
+@@ -8733,12 +8776,7 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
+ {0x12, 0x90a60130},
+ {0x19, 0x03a11020},
+ {0x21, 0x0321101f}),
+- SND_HDA_PIN_QUIRK(0x10ec0285, 0x17aa, "Lenovo", ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK,
+- {0x14, 0x90170110},
+- {0x19, 0x04a11040},
+- {0x21, 0x04211020}),
+ SND_HDA_PIN_QUIRK(0x10ec0285, 0x17aa, "Lenovo", ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE,
+- {0x12, 0x90a60130},
+ {0x14, 0x90170110},
+ {0x19, 0x04a11040},
+ {0x21, 0x04211020}),
+@@ -8909,6 +8947,10 @@ static const struct snd_hda_pin_quirk alc269_fallback_pin_fixup_tbl[] = {
+ SND_HDA_PIN_QUIRK(0x10ec0274, 0x1028, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
+ {0x19, 0x40000000},
+ {0x1a, 0x40000000}),
++ SND_HDA_PIN_QUIRK(0x10ec0285, 0x17aa, "Lenovo", ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK,
++ {0x14, 0x90170110},
++ {0x19, 0x04a11040},
++ {0x21, 0x04211020}),
+ {}
+ };
+
+diff --git a/sound/usb/clock.c b/sound/usb/clock.c
+index a746802d0ac3b..17bbde73d4d15 100644
+--- a/sound/usb/clock.c
++++ b/sound/usb/clock.c
+@@ -296,7 +296,7 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
+
+ selector = snd_usb_find_clock_selector(chip->ctrl_intf, entity_id);
+ if (selector) {
+- int ret, i, cur;
++ int ret, i, cur, err;
+
+ if (selector->bNrInPins == 1) {
+ ret = 1;
+@@ -324,13 +324,17 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
+ ret = __uac_clock_find_source(chip, fmt,
+ selector->baCSourceID[ret - 1],
+ visited, validate);
++ if (ret > 0) {
++ err = uac_clock_selector_set_val(chip, entity_id, cur);
++ if (err < 0)
++ return err;
++ }
++
+ if (!validate || ret > 0 || !chip->autoclock)
+ return ret;
+
+ /* The current clock source is invalid, try others. */
+ for (i = 1; i <= selector->bNrInPins; i++) {
+- int err;
+-
+ if (i == cur)
+ continue;
+
+@@ -396,7 +400,7 @@ static int __uac3_clock_find_source(struct snd_usb_audio *chip,
+
+ selector = snd_usb_find_clock_selector_v3(chip->ctrl_intf, entity_id);
+ if (selector) {
+- int ret, i, cur;
++ int ret, i, cur, err;
+
+ /* the entity ID we are looking for is a selector.
+ * find out what it currently selects */
+@@ -418,6 +422,12 @@ static int __uac3_clock_find_source(struct snd_usb_audio *chip,
+ ret = __uac3_clock_find_source(chip, fmt,
+ selector->baCSourceID[ret - 1],
+ visited, validate);
++ if (ret > 0) {
++ err = uac_clock_selector_set_val(chip, entity_id, cur);
++ if (err < 0)
++ return err;
++ }
++
+ if (!validate || ret > 0 || !chip->autoclock)
+ return ret;
+
+diff --git a/sound/usb/mixer_maps.c b/sound/usb/mixer_maps.c
+index 646deb6244b15..c5794e83fd800 100644
+--- a/sound/usb/mixer_maps.c
++++ b/sound/usb/mixer_maps.c
+@@ -337,6 +337,13 @@ static const struct usbmix_name_map bose_companion5_map[] = {
+ { 0 } /* terminator */
+ };
+
++/* Sennheiser Communications Headset [PC 8], the dB value is reported as -6 negative maximum */
++static const struct usbmix_dB_map sennheiser_pc8_dB = {-9500, 0};
++static const struct usbmix_name_map sennheiser_pc8_map[] = {
++ { 9, NULL, .dB = &sennheiser_pc8_dB },
++ { 0 } /* terminator */
++};
++
+ /*
+ * Dell usb dock with ALC4020 codec had a firmware problem where it got
+ * screwed up when zero volume is passed; just skip it as a workaround
+@@ -593,6 +600,11 @@ static const struct usbmix_ctl_map usbmix_ctl_maps[] = {
+ .id = USB_ID(0x17aa, 0x1046),
+ .map = lenovo_p620_rear_map,
+ },
++ {
++ /* Sennheiser Communications Headset [PC 8] */
++ .id = USB_ID(0x1395, 0x0025),
++ .map = sennheiser_pc8_map,
++ },
+ { 0 } /* terminator */
+ };
+
+diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c
+index 8e54ce47648e2..3bf1820c0da11 100644
+--- a/tools/power/x86/intel-speed-select/isst-display.c
++++ b/tools/power/x86/intel-speed-select/isst-display.c
+@@ -25,10 +25,14 @@ static void printcpulist(int str_len, char *str, int mask_size,
+ index = snprintf(&str[curr_index],
+ str_len - curr_index, ",");
+ curr_index += index;
++ if (curr_index >= str_len)
++ break;
+ }
+ index = snprintf(&str[curr_index], str_len - curr_index, "%d",
+ i);
+ curr_index += index;
++ if (curr_index >= str_len)
++ break;
+ first = 0;
+ }
+ }
+@@ -64,10 +68,14 @@ static void printcpumask(int str_len, char *str, int mask_size,
+ index = snprintf(&str[curr_index], str_len - curr_index, "%08x",
+ mask[i]);
+ curr_index += index;
++ if (curr_index >= str_len)
++ break;
+ if (i) {
+ strncat(&str[curr_index], ",", str_len - curr_index);
+ curr_index++;
+ }
++ if (curr_index >= str_len)
++ break;
+ }
+
+ free(mask);
+@@ -185,7 +193,7 @@ static void _isst_pbf_display_information(int cpu, FILE *outf, int level,
+ int disp_level)
+ {
+ char header[256];
+- char value[256];
++ char value[512];
+
+ snprintf(header, sizeof(header), "speed-select-base-freq-properties");
+ format_and_print(outf, disp_level, header, NULL);
+@@ -349,7 +357,7 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level,
+ struct isst_pkg_ctdp *pkg_dev)
+ {
+ char header[256];
+- char value[256];
++ char value[512];
+ static int level;
+ int i;
+
+diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
+index a7c4f0772e534..490c9a496fe28 100644
+--- a/tools/power/x86/turbostat/turbostat.c
++++ b/tools/power/x86/turbostat/turbostat.c
+@@ -291,13 +291,16 @@ struct msr_sum_array {
+ /* The percpu MSR sum array.*/
+ struct msr_sum_array *per_cpu_msr_sum;
+
+-int idx_to_offset(int idx)
++off_t idx_to_offset(int idx)
+ {
+- int offset;
++ off_t offset;
+
+ switch (idx) {
+ case IDX_PKG_ENERGY:
+- offset = MSR_PKG_ENERGY_STATUS;
++ if (do_rapl & RAPL_AMD_F17H)
++ offset = MSR_PKG_ENERGY_STAT;
++ else
++ offset = MSR_PKG_ENERGY_STATUS;
+ break;
+ case IDX_DRAM_ENERGY:
+ offset = MSR_DRAM_ENERGY_STATUS;
+@@ -320,12 +323,13 @@ int idx_to_offset(int idx)
+ return offset;
+ }
+
+-int offset_to_idx(int offset)
++int offset_to_idx(off_t offset)
+ {
+ int idx;
+
+ switch (offset) {
+ case MSR_PKG_ENERGY_STATUS:
++ case MSR_PKG_ENERGY_STAT:
+ idx = IDX_PKG_ENERGY;
+ break;
+ case MSR_DRAM_ENERGY_STATUS:
+@@ -353,7 +357,7 @@ int idx_valid(int idx)
+ {
+ switch (idx) {
+ case IDX_PKG_ENERGY:
+- return do_rapl & RAPL_PKG;
++ return do_rapl & (RAPL_PKG | RAPL_AMD_F17H);
+ case IDX_DRAM_ENERGY:
+ return do_rapl & RAPL_DRAM;
+ case IDX_PP0_ENERGY:
+@@ -3272,7 +3276,7 @@ static int update_msr_sum(struct thread_data *t, struct core_data *c, struct pkg
+
+ for (i = IDX_PKG_ENERGY; i < IDX_COUNT; i++) {
+ unsigned long long msr_cur, msr_last;
+- int offset;
++ off_t offset;
+
+ if (!idx_valid(i))
+ continue;
+@@ -3281,7 +3285,8 @@ static int update_msr_sum(struct thread_data *t, struct core_data *c, struct pkg
+ continue;
+ ret = get_msr(cpu, offset, &msr_cur);
+ if (ret) {
+- fprintf(outf, "Can not update msr(0x%x)\n", offset);
++ fprintf(outf, "Can not update msr(0x%llx)\n",
++ (unsigned long long)offset);
+ continue;
+ }
+
+diff --git a/tools/testing/selftests/arm64/mte/Makefile b/tools/testing/selftests/arm64/mte/Makefile
+index 0b3af552632a6..df15d44aeb8d4 100644
+--- a/tools/testing/selftests/arm64/mte/Makefile
++++ b/tools/testing/selftests/arm64/mte/Makefile
+@@ -6,9 +6,7 @@ SRCS := $(filter-out mte_common_util.c,$(wildcard *.c))
+ PROGS := $(patsubst %.c,%,$(SRCS))
+
+ #Add mte compiler option
+-ifneq ($(shell $(CC) --version 2>&1 | head -n 1 | grep gcc),)
+ CFLAGS += -march=armv8.5-a+memtag
+-endif
+
+ #check if the compiler works well
+ mte_cc_support := $(shell if ($(CC) $(CFLAGS) -E -x c /dev/null -o /dev/null 2>&1) then echo "1"; fi)
+diff --git a/tools/testing/selftests/arm64/mte/mte_common_util.c b/tools/testing/selftests/arm64/mte/mte_common_util.c
+index 39f8908988eab..70665ba88cbb1 100644
+--- a/tools/testing/selftests/arm64/mte/mte_common_util.c
++++ b/tools/testing/selftests/arm64/mte/mte_common_util.c
+@@ -278,22 +278,13 @@ int mte_switch_mode(int mte_option, unsigned long incl_mask)
+ return 0;
+ }
+
+-#define ID_AA64PFR1_MTE_SHIFT 8
+-#define ID_AA64PFR1_MTE 2
+-
+ int mte_default_setup(void)
+ {
+- unsigned long hwcaps = getauxval(AT_HWCAP);
++ unsigned long hwcaps2 = getauxval(AT_HWCAP2);
+ unsigned long en = 0;
+ int ret;
+
+- if (!(hwcaps & HWCAP_CPUID)) {
+- ksft_print_msg("FAIL: CPUID registers unavailable\n");
+- return KSFT_FAIL;
+- }
+- /* Read ID_AA64PFR1_EL1 register */
+- asm volatile("mrs %0, id_aa64pfr1_el1" : "=r"(hwcaps) : : "memory");
+- if (((hwcaps >> ID_AA64PFR1_MTE_SHIFT) & MT_TAG_MASK) != ID_AA64PFR1_MTE) {
++ if (!(hwcaps2 & HWCAP2_MTE)) {
+ ksft_print_msg("FAIL: MTE features unavailable\n");
+ return KSFT_SKIP;
+ }
+diff --git a/tools/testing/selftests/resctrl/Makefile b/tools/testing/selftests/resctrl/Makefile
+index d585cc1948cc7..6bcee2ec91a9c 100644
+--- a/tools/testing/selftests/resctrl/Makefile
++++ b/tools/testing/selftests/resctrl/Makefile
+@@ -1,5 +1,5 @@
+ CC = $(CROSS_COMPILE)gcc
+-CFLAGS = -g -Wall
++CFLAGS = -g -Wall -O2 -D_FORTIFY_SOURCE=2
+ SRCS=$(wildcard *.c)
+ OBJS=$(SRCS:.c=.o)
+
+diff --git a/tools/testing/selftests/resctrl/cache.c b/tools/testing/selftests/resctrl/cache.c
+index 38dbf4962e333..5922cc1b03867 100644
+--- a/tools/testing/selftests/resctrl/cache.c
++++ b/tools/testing/selftests/resctrl/cache.c
+@@ -182,7 +182,7 @@ int measure_cache_vals(struct resctrl_val_param *param, int bm_pid)
+ /*
+ * Measure cache miss from perf.
+ */
+- if (!strcmp(param->resctrl_val, "cat")) {
++ if (!strncmp(param->resctrl_val, CAT_STR, sizeof(CAT_STR))) {
+ ret = get_llc_perf(&llc_perf_miss);
+ if (ret < 0)
+ return ret;
+@@ -192,7 +192,7 @@ int measure_cache_vals(struct resctrl_val_param *param, int bm_pid)
+ /*
+ * Measure llc occupancy from resctrl.
+ */
+- if (!strcmp(param->resctrl_val, "cqm")) {
++ if (!strncmp(param->resctrl_val, CQM_STR, sizeof(CQM_STR))) {
+ ret = get_llc_occu_resctrl(&llc_occu_resc);
+ if (ret < 0)
+ return ret;
+@@ -234,7 +234,7 @@ int cat_val(struct resctrl_val_param *param)
+ if (ret)
+ return ret;
+
+- if ((strcmp(resctrl_val, "cat") == 0)) {
++ if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR))) {
+ ret = initialize_llc_perf();
+ if (ret)
+ return ret;
+@@ -242,7 +242,7 @@ int cat_val(struct resctrl_val_param *param)
+
+ /* Test runs until the callback setup() tells the test to stop. */
+ while (1) {
+- if (strcmp(resctrl_val, "cat") == 0) {
++ if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR))) {
+ ret = param->setup(1, param);
+ if (ret) {
+ ret = 0;
+diff --git a/tools/testing/selftests/resctrl/cat_test.c b/tools/testing/selftests/resctrl/cat_test.c
+index 5da43767b9731..20823725daca5 100644
+--- a/tools/testing/selftests/resctrl/cat_test.c
++++ b/tools/testing/selftests/resctrl/cat_test.c
+@@ -17,10 +17,10 @@
+ #define MAX_DIFF_PERCENT 4
+ #define MAX_DIFF 1000000
+
+-int count_of_bits;
+-char cbm_mask[256];
+-unsigned long long_mask;
+-unsigned long cache_size;
++static int count_of_bits;
++static char cbm_mask[256];
++static unsigned long long_mask;
++static unsigned long cache_size;
+
+ /*
+ * Change schemata. Write schemata to specified
+@@ -136,7 +136,7 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type)
+ return -1;
+
+ /* Get default cbm mask for L3/L2 cache */
+- ret = get_cbm_mask(cache_type);
++ ret = get_cbm_mask(cache_type, cbm_mask);
+ if (ret)
+ return ret;
+
+@@ -164,7 +164,7 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type)
+ return -1;
+
+ struct resctrl_val_param param = {
+- .resctrl_val = "cat",
++ .resctrl_val = CAT_STR,
+ .cpu_no = cpu_no,
+ .mum_resctrlfs = 0,
+ .setup = cat_setup,
+diff --git a/tools/testing/selftests/resctrl/cqm_test.c b/tools/testing/selftests/resctrl/cqm_test.c
+index c8756152bd615..271752e9ef5be 100644
+--- a/tools/testing/selftests/resctrl/cqm_test.c
++++ b/tools/testing/selftests/resctrl/cqm_test.c
+@@ -16,10 +16,10 @@
+ #define MAX_DIFF 2000000
+ #define MAX_DIFF_PERCENT 15
+
+-int count_of_bits;
+-char cbm_mask[256];
+-unsigned long long_mask;
+-unsigned long cache_size;
++static int count_of_bits;
++static char cbm_mask[256];
++static unsigned long long_mask;
++static unsigned long cache_size;
+
+ static int cqm_setup(int num, ...)
+ {
+@@ -86,7 +86,7 @@ static int check_results(struct resctrl_val_param *param, int no_of_bits)
+ return errno;
+ }
+
+- while (fgets(temp, 1024, fp)) {
++ while (fgets(temp, sizeof(temp), fp)) {
+ char *token = strtok(temp, ":\t");
+ int fields = 0;
+
+@@ -125,7 +125,7 @@ int cqm_resctrl_val(int cpu_no, int n, char **benchmark_cmd)
+ if (!validate_resctrl_feature_request("cqm"))
+ return -1;
+
+- ret = get_cbm_mask("L3");
++ ret = get_cbm_mask("L3", cbm_mask);
+ if (ret)
+ return ret;
+
+@@ -145,7 +145,7 @@ int cqm_resctrl_val(int cpu_no, int n, char **benchmark_cmd)
+ }
+
+ struct resctrl_val_param param = {
+- .resctrl_val = "cqm",
++ .resctrl_val = CQM_STR,
+ .ctrlgrp = "c1",
+ .mongrp = "m1",
+ .cpu_no = cpu_no,
+diff --git a/tools/testing/selftests/resctrl/fill_buf.c b/tools/testing/selftests/resctrl/fill_buf.c
+index 79c611c99a3dd..51e5cf22632f7 100644
+--- a/tools/testing/selftests/resctrl/fill_buf.c
++++ b/tools/testing/selftests/resctrl/fill_buf.c
+@@ -115,7 +115,7 @@ static int fill_cache_read(unsigned char *start_ptr, unsigned char *end_ptr,
+
+ while (1) {
+ ret = fill_one_span_read(start_ptr, end_ptr);
+- if (!strcmp(resctrl_val, "cat"))
++ if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR)))
+ break;
+ }
+
+@@ -134,7 +134,7 @@ static int fill_cache_write(unsigned char *start_ptr, unsigned char *end_ptr,
+ {
+ while (1) {
+ fill_one_span_write(start_ptr, end_ptr);
+- if (!strcmp(resctrl_val, "cat"))
++ if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR)))
+ break;
+ }
+
+diff --git a/tools/testing/selftests/resctrl/mba_test.c b/tools/testing/selftests/resctrl/mba_test.c
+index 7bf8eaa6204bf..6449fbd96096a 100644
+--- a/tools/testing/selftests/resctrl/mba_test.c
++++ b/tools/testing/selftests/resctrl/mba_test.c
+@@ -141,7 +141,7 @@ void mba_test_cleanup(void)
+ int mba_schemata_change(int cpu_no, char *bw_report, char **benchmark_cmd)
+ {
+ struct resctrl_val_param param = {
+- .resctrl_val = "mba",
++ .resctrl_val = MBA_STR,
+ .ctrlgrp = "c1",
+ .mongrp = "m1",
+ .cpu_no = cpu_no,
+diff --git a/tools/testing/selftests/resctrl/mbm_test.c b/tools/testing/selftests/resctrl/mbm_test.c
+index 4700f7453f811..ec6cfe01c9c26 100644
+--- a/tools/testing/selftests/resctrl/mbm_test.c
++++ b/tools/testing/selftests/resctrl/mbm_test.c
+@@ -114,7 +114,7 @@ void mbm_test_cleanup(void)
+ int mbm_bw_change(int span, int cpu_no, char *bw_report, char **benchmark_cmd)
+ {
+ struct resctrl_val_param param = {
+- .resctrl_val = "mbm",
++ .resctrl_val = MBM_STR,
+ .ctrlgrp = "c1",
+ .mongrp = "m1",
+ .span = span,
+diff --git a/tools/testing/selftests/resctrl/resctrl.h b/tools/testing/selftests/resctrl/resctrl.h
+index 39bf59c6b9c56..9dcc96e1ad3d7 100644
+--- a/tools/testing/selftests/resctrl/resctrl.h
++++ b/tools/testing/selftests/resctrl/resctrl.h
+@@ -28,6 +28,10 @@
+ #define RESCTRL_PATH "/sys/fs/resctrl"
+ #define PHYS_ID_PATH "/sys/devices/system/cpu/cpu"
+ #define CBM_MASK_PATH "/sys/fs/resctrl/info"
++#define L3_PATH "/sys/fs/resctrl/info/L3"
++#define MB_PATH "/sys/fs/resctrl/info/MB"
++#define L3_MON_PATH "/sys/fs/resctrl/info/L3_MON"
++#define L3_MON_FEATURES_PATH "/sys/fs/resctrl/info/L3_MON/mon_features"
+
+ #define PARENT_EXIT(err_msg) \
+ do { \
+@@ -62,11 +66,16 @@ struct resctrl_val_param {
+ int (*setup)(int num, ...);
+ };
+
+-pid_t bm_pid, ppid;
+-int tests_run;
++#define MBM_STR "mbm"
++#define MBA_STR "mba"
++#define CQM_STR "cqm"
++#define CAT_STR "cat"
+
+-char llc_occup_path[1024];
+-bool is_amd;
++extern pid_t bm_pid, ppid;
++extern int tests_run;
++
++extern char llc_occup_path[1024];
++extern bool is_amd;
+
+ bool check_resctrlfs_support(void);
+ int filter_dmesg(void);
+@@ -74,7 +83,7 @@ int remount_resctrlfs(bool mum_resctrlfs);
+ int get_resource_id(int cpu_no, int *resource_id);
+ int umount_resctrlfs(void);
+ int validate_bw_report_request(char *bw_report);
+-bool validate_resctrl_feature_request(char *resctrl_val);
++bool validate_resctrl_feature_request(const char *resctrl_val);
+ char *fgrep(FILE *inf, const char *str);
+ int taskset_benchmark(pid_t bm_pid, int cpu_no);
+ void run_benchmark(int signum, siginfo_t *info, void *ucontext);
+@@ -92,7 +101,7 @@ void tests_cleanup(void);
+ void mbm_test_cleanup(void);
+ int mba_schemata_change(int cpu_no, char *bw_report, char **benchmark_cmd);
+ void mba_test_cleanup(void);
+-int get_cbm_mask(char *cache_type);
++int get_cbm_mask(char *cache_type, char *cbm_mask);
+ int get_cache_size(int cpu_no, char *cache_type, unsigned long *cache_size);
+ void ctrlc_handler(int signum, siginfo_t *info, void *ptr);
+ int cat_val(struct resctrl_val_param *param);
+diff --git a/tools/testing/selftests/resctrl/resctrl_tests.c b/tools/testing/selftests/resctrl/resctrl_tests.c
+index 425cc85ac8836..ac2269610aa9d 100644
+--- a/tools/testing/selftests/resctrl/resctrl_tests.c
++++ b/tools/testing/selftests/resctrl/resctrl_tests.c
+@@ -73,7 +73,7 @@ int main(int argc, char **argv)
+ }
+ }
+
+- while ((c = getopt(argc_new, argv, "ht:b:")) != -1) {
++ while ((c = getopt(argc_new, argv, "ht:b:n:p:")) != -1) {
+ char *token;
+
+ switch (c) {
+@@ -85,13 +85,13 @@ int main(int argc, char **argv)
+ cqm_test = false;
+ cat_test = false;
+ while (token) {
+- if (!strcmp(token, "mbm")) {
++ if (!strncmp(token, MBM_STR, sizeof(MBM_STR))) {
+ mbm_test = true;
+- } else if (!strcmp(token, "mba")) {
++ } else if (!strncmp(token, MBA_STR, sizeof(MBA_STR))) {
+ mba_test = true;
+- } else if (!strcmp(token, "cqm")) {
++ } else if (!strncmp(token, CQM_STR, sizeof(CQM_STR))) {
+ cqm_test = true;
+- } else if (!strcmp(token, "cat")) {
++ } else if (!strncmp(token, CAT_STR, sizeof(CAT_STR))) {
+ cat_test = true;
+ } else {
+ printf("invalid argument\n");
+@@ -161,7 +161,7 @@ int main(int argc, char **argv)
+ if (!is_amd && mbm_test) {
+ printf("# Starting MBM BW change ...\n");
+ if (!has_ben)
+- sprintf(benchmark_cmd[5], "%s", "mba");
++ sprintf(benchmark_cmd[5], "%s", MBA_STR);
+ res = mbm_bw_change(span, cpu_no, bw_report, benchmark_cmd);
+ printf("%sok MBM: bw change\n", res ? "not " : "");
+ mbm_test_cleanup();
+@@ -181,7 +181,7 @@ int main(int argc, char **argv)
+ if (cqm_test) {
+ printf("# Starting CQM test ...\n");
+ if (!has_ben)
+- sprintf(benchmark_cmd[5], "%s", "cqm");
++ sprintf(benchmark_cmd[5], "%s", CQM_STR);
+ res = cqm_resctrl_val(cpu_no, no_of_bits, benchmark_cmd);
+ printf("%sok CQM: test\n", res ? "not " : "");
+ cqm_test_cleanup();
+diff --git a/tools/testing/selftests/resctrl/resctrl_val.c b/tools/testing/selftests/resctrl/resctrl_val.c
+index 520fea3606d17..8df557894059a 100644
+--- a/tools/testing/selftests/resctrl/resctrl_val.c
++++ b/tools/testing/selftests/resctrl/resctrl_val.c
+@@ -221,8 +221,8 @@ static int read_from_imc_dir(char *imc_dir, int count)
+ */
+ static int num_of_imcs(void)
+ {
++ char imc_dir[512], *temp;
+ unsigned int count = 0;
+- char imc_dir[512];
+ struct dirent *ep;
+ int ret;
+ DIR *dp;
+@@ -230,7 +230,25 @@ static int num_of_imcs(void)
+ dp = opendir(DYN_PMU_PATH);
+ if (dp) {
+ while ((ep = readdir(dp))) {
+- if (strstr(ep->d_name, UNCORE_IMC)) {
++ temp = strstr(ep->d_name, UNCORE_IMC);
++ if (!temp)
++ continue;
++
++ /*
++ * imc counters are named as "uncore_imc_<n>", hence
++ * increment the pointer to point to <n>. Note that
++ * sizeof(UNCORE_IMC) would count for null character as
++ * well and hence the last underscore character in
++ * uncore_imc'_' need not be counted.
++ */
++ temp = temp + sizeof(UNCORE_IMC);
++
++ /*
++ * Some directories under "DYN_PMU_PATH" could have
++ * names like "uncore_imc_free_running", hence, check if
++ * first character is a numerical digit or not.
++ */
++ if (temp[0] >= '0' && temp[0] <= '9') {
+ sprintf(imc_dir, "%s/%s/", DYN_PMU_PATH,
+ ep->d_name);
+ ret = read_from_imc_dir(imc_dir, count);
+@@ -282,9 +300,9 @@ static int initialize_mem_bw_imc(void)
+ * Memory B/W utilized by a process on a socket can be calculated using
+ * iMC counters. Perf events are used to read these counters.
+ *
+- * Return: >= 0 on success. < 0 on failure.
++ * Return: = 0 on success. < 0 on failure.
+ */
+-static float get_mem_bw_imc(int cpu_no, char *bw_report)
++static int get_mem_bw_imc(int cpu_no, char *bw_report, float *bw_imc)
+ {
+ float reads, writes, of_mul_read, of_mul_write;
+ int imc, j, ret;
+@@ -355,13 +373,18 @@ static float get_mem_bw_imc(int cpu_no, char *bw_report)
+ close(imc_counters_config[imc][WRITE].fd);
+ }
+
+- if (strcmp(bw_report, "reads") == 0)
+- return reads;
++ if (strcmp(bw_report, "reads") == 0) {
++ *bw_imc = reads;
++ return 0;
++ }
+
+- if (strcmp(bw_report, "writes") == 0)
+- return writes;
++ if (strcmp(bw_report, "writes") == 0) {
++ *bw_imc = writes;
++ return 0;
++ }
+
+- return (reads + writes);
++ *bw_imc = reads + writes;
++ return 0;
+ }
+
+ void set_mbm_path(const char *ctrlgrp, const char *mongrp, int resource_id)
+@@ -397,10 +420,10 @@ static void initialize_mem_bw_resctrl(const char *ctrlgrp, const char *mongrp,
+ return;
+ }
+
+- if (strcmp(resctrl_val, "mbm") == 0)
++ if (!strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR)))
+ set_mbm_path(ctrlgrp, mongrp, resource_id);
+
+- if ((strcmp(resctrl_val, "mba") == 0)) {
++ if (!strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR))) {
+ if (ctrlgrp)
+ sprintf(mbm_total_path, CON_MBM_LOCAL_BYTES_PATH,
+ RESCTRL_PATH, ctrlgrp, resource_id);
+@@ -420,9 +443,8 @@ static void initialize_mem_bw_resctrl(const char *ctrlgrp, const char *mongrp,
+ * 1. If con_mon grp is given, then read from it
+ * 2. If con_mon grp is not given, then read from root con_mon grp
+ */
+-static unsigned long get_mem_bw_resctrl(void)
++static int get_mem_bw_resctrl(unsigned long *mbm_total)
+ {
+- unsigned long mbm_total = 0;
+ FILE *fp;
+
+ fp = fopen(mbm_total_path, "r");
+@@ -431,7 +453,7 @@ static unsigned long get_mem_bw_resctrl(void)
+
+ return -1;
+ }
+- if (fscanf(fp, "%lu", &mbm_total) <= 0) {
++ if (fscanf(fp, "%lu", mbm_total) <= 0) {
+ perror("Could not get mbm local bytes");
+ fclose(fp);
+
+@@ -439,7 +461,7 @@ static unsigned long get_mem_bw_resctrl(void)
+ }
+ fclose(fp);
+
+- return mbm_total;
++ return 0;
+ }
+
+ pid_t bm_pid, ppid;
+@@ -524,14 +546,15 @@ static void initialize_llc_occu_resctrl(const char *ctrlgrp, const char *mongrp,
+ return;
+ }
+
+- if (strcmp(resctrl_val, "cqm") == 0)
++ if (!strncmp(resctrl_val, CQM_STR, sizeof(CQM_STR)))
+ set_cqm_path(ctrlgrp, mongrp, resource_id);
+ }
+
+ static int
+ measure_vals(struct resctrl_val_param *param, unsigned long *bw_resc_start)
+ {
+- unsigned long bw_imc, bw_resc, bw_resc_end;
++ unsigned long bw_resc, bw_resc_end;
++ float bw_imc;
+ int ret;
+
+ /*
+@@ -541,13 +564,13 @@ measure_vals(struct resctrl_val_param *param, unsigned long *bw_resc_start)
+ * Compare the two values to validate resctrl value.
+ * It takes 1sec to measure the data.
+ */
+- bw_imc = get_mem_bw_imc(param->cpu_no, param->bw_report);
+- if (bw_imc <= 0)
+- return bw_imc;
++ ret = get_mem_bw_imc(param->cpu_no, param->bw_report, &bw_imc);
++ if (ret < 0)
++ return ret;
+
+- bw_resc_end = get_mem_bw_resctrl();
+- if (bw_resc_end <= 0)
+- return bw_resc_end;
++ ret = get_mem_bw_resctrl(&bw_resc_end);
++ if (ret < 0)
++ return ret;
+
+ bw_resc = (bw_resc_end - *bw_resc_start) / MB;
+ ret = print_results_bw(param->filename, bm_pid, bw_imc, bw_resc);
+@@ -579,8 +602,8 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param)
+ if (strcmp(param->filename, "") == 0)
+ sprintf(param->filename, "stdio");
+
+- if ((strcmp(resctrl_val, "mba")) == 0 ||
+- (strcmp(resctrl_val, "mbm")) == 0) {
++ if (!strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR)) ||
++ !strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR))) {
+ ret = validate_bw_report_request(param->bw_report);
+ if (ret)
+ return ret;
+@@ -674,15 +697,15 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param)
+ if (ret)
+ goto out;
+
+- if ((strcmp(resctrl_val, "mbm") == 0) ||
+- (strcmp(resctrl_val, "mba") == 0)) {
++ if (!strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR)) ||
++ !strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR))) {
+ ret = initialize_mem_bw_imc();
+ if (ret)
+ goto out;
+
+ initialize_mem_bw_resctrl(param->ctrlgrp, param->mongrp,
+ param->cpu_no, resctrl_val);
+- } else if (strcmp(resctrl_val, "cqm") == 0)
++ } else if (!strncmp(resctrl_val, CQM_STR, sizeof(CQM_STR)))
+ initialize_llc_occu_resctrl(param->ctrlgrp, param->mongrp,
+ param->cpu_no, resctrl_val);
+
+@@ -710,8 +733,8 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param)
+
+ /* Test runs until the callback setup() tells the test to stop. */
+ while (1) {
+- if ((strcmp(resctrl_val, "mbm") == 0) ||
+- (strcmp(resctrl_val, "mba") == 0)) {
++ if (!strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR)) ||
++ !strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR))) {
+ ret = param->setup(1, param);
+ if (ret) {
+ ret = 0;
+@@ -721,7 +744,7 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param)
+ ret = measure_vals(param, &bw_resc_start);
+ if (ret)
+ break;
+- } else if (strcmp(resctrl_val, "cqm") == 0) {
++ } else if (!strncmp(resctrl_val, CQM_STR, sizeof(CQM_STR))) {
+ ret = param->setup(1, param);
+ if (ret) {
+ ret = 0;
+diff --git a/tools/testing/selftests/resctrl/resctrlfs.c b/tools/testing/selftests/resctrl/resctrlfs.c
+index 19c0ec4045a40..b57170f53861d 100644
+--- a/tools/testing/selftests/resctrl/resctrlfs.c
++++ b/tools/testing/selftests/resctrl/resctrlfs.c
+@@ -49,8 +49,6 @@ static int find_resctrl_mount(char *buffer)
+ return -ENOENT;
+ }
+
+-char cbm_mask[256];
+-
+ /*
+ * remount_resctrlfs - Remount resctrl FS at /sys/fs/resctrl
+ * @mum_resctrlfs: Should the resctrl FS be remounted?
+@@ -205,16 +203,18 @@ int get_cache_size(int cpu_no, char *cache_type, unsigned long *cache_size)
+ /*
+ * get_cbm_mask - Get cbm mask for given cache
+ * @cache_type: Cache level L2/L3
+- *
+- * Mask is stored in cbm_mask which is global variable.
++ * @cbm_mask: cbm_mask returned as a string
+ *
+ * Return: = 0 on success, < 0 on failure.
+ */
+-int get_cbm_mask(char *cache_type)
++int get_cbm_mask(char *cache_type, char *cbm_mask)
+ {
+ char cbm_mask_path[1024];
+ FILE *fp;
+
++ if (!cbm_mask)
++ return -1;
++
+ sprintf(cbm_mask_path, "%s/%s/cbm_mask", CBM_MASK_PATH, cache_type);
+
+ fp = fopen(cbm_mask_path, "r");
+@@ -334,7 +334,7 @@ void run_benchmark(int signum, siginfo_t *info, void *ucontext)
+ operation = atoi(benchmark_cmd[4]);
+ sprintf(resctrl_val, "%s", benchmark_cmd[5]);
+
+- if (strcmp(resctrl_val, "cqm") != 0)
++ if (strncmp(resctrl_val, CQM_STR, sizeof(CQM_STR)))
+ buffer_span = span * MB;
+ else
+ buffer_span = span;
+@@ -459,8 +459,8 @@ int write_bm_pid_to_resctrl(pid_t bm_pid, char *ctrlgrp, char *mongrp,
+ goto out;
+
+ /* Create mon grp and write pid into it for "mbm" and "cqm" test */
+- if ((strcmp(resctrl_val, "cqm") == 0) ||
+- (strcmp(resctrl_val, "mbm") == 0)) {
++ if (!strncmp(resctrl_val, CQM_STR, sizeof(CQM_STR)) ||
++ !strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR))) {
+ if (strlen(mongrp)) {
+ sprintf(monitorgroup_p, "%s/mon_groups", controlgroup);
+ sprintf(monitorgroup, "%s/%s", monitorgroup_p, mongrp);
+@@ -505,9 +505,9 @@ int write_schemata(char *ctrlgrp, char *schemata, int cpu_no, char *resctrl_val)
+ int resource_id, ret = 0;
+ FILE *fp;
+
+- if ((strcmp(resctrl_val, "mba") != 0) &&
+- (strcmp(resctrl_val, "cat") != 0) &&
+- (strcmp(resctrl_val, "cqm") != 0))
++ if (strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR)) &&
++ strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR)) &&
++ strncmp(resctrl_val, CQM_STR, sizeof(CQM_STR)))
+ return -ENOENT;
+
+ if (!schemata) {
+@@ -528,9 +528,10 @@ int write_schemata(char *ctrlgrp, char *schemata, int cpu_no, char *resctrl_val)
+ else
+ sprintf(controlgroup, "%s/schemata", RESCTRL_PATH);
+
+- if (!strcmp(resctrl_val, "cat") || !strcmp(resctrl_val, "cqm"))
++ if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR)) ||
++ !strncmp(resctrl_val, CQM_STR, sizeof(CQM_STR)))
+ sprintf(schema, "%s%d%c%s", "L3:", resource_id, '=', schemata);
+- if (strcmp(resctrl_val, "mba") == 0)
++ if (!strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR)))
+ sprintf(schema, "%s%d%c%s", "MB:", resource_id, '=', schemata);
+
+ fp = fopen(controlgroup, "w");
+@@ -615,26 +616,56 @@ char *fgrep(FILE *inf, const char *str)
+ * validate_resctrl_feature_request - Check if requested feature is valid.
+ * @resctrl_val: Requested feature
+ *
+- * Return: 0 on success, non-zero on failure
++ * Return: True if the feature is supported, else false
+ */
+-bool validate_resctrl_feature_request(char *resctrl_val)
++bool validate_resctrl_feature_request(const char *resctrl_val)
+ {
+- FILE *inf = fopen("/proc/cpuinfo", "r");
++ struct stat statbuf;
+ bool found = false;
+ char *res;
++ FILE *inf;
+
+- if (!inf)
++ if (!resctrl_val)
+ return false;
+
+- res = fgrep(inf, "flags");
+-
+- if (res) {
+- char *s = strchr(res, ':');
++ if (remount_resctrlfs(false))
++ return false;
+
+- found = s && !strstr(s, resctrl_val);
+- free(res);
++ if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR))) {
++ if (!stat(L3_PATH, &statbuf))
++ return true;
++ } else if (!strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR))) {
++ if (!stat(MB_PATH, &statbuf))
++ return true;
++ } else if (!strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR)) ||
++ !strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR))) {
++ if (!stat(L3_MON_PATH, &statbuf)) {
++ inf = fopen(L3_MON_FEATURES_PATH, "r");
++ if (!inf)
++ return false;
++
++ if (!strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR))) {
++ res = fgrep(inf, "llc_occupancy");
++ if (res) {
++ found = true;
++ free(res);
++ }
++ }
++
++ if (!strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR))) {
++ res = fgrep(inf, "mbm_total_bytes");
++ if (res) {
++ free(res);
++ res = fgrep(inf, "mbm_local_bytes");
++ if (res) {
++ found = true;
++ free(res);
++ }
++ }
++ }
++ fclose(inf);
++ }
+ }
+- fclose(inf);
+
+ return found;
+ }