summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pagano <mpagano@gentoo.org>2023-05-11 10:48:39 -0400
committerMike Pagano <mpagano@gentoo.org>2023-05-11 10:48:39 -0400
commiteee10f955c1d2689f8bd7ec36ef5d1d76f6d355f (patch)
tree4c3acec03e24d34437eb3239c8ff26d9f5bfb692
parentnetfilter: nf_tables: deactivate anonymous set from preparation phase (diff)
downloadlinux-patches-eee10f955c1d2689f8bd7ec36ef5d1d76f6d355f.tar.gz
linux-patches-eee10f955c1d2689f8bd7ec36ef5d1d76f6d355f.tar.bz2
linux-patches-eee10f955c1d2689f8bd7ec36ef5d1d76f6d355f.zip
Linux patch 6.2.15
Signed-off-by: Mike Pagano <mpagano@gentoo.org>
-rw-r--r--0000_README4
-rw-r--r--1014_linux-6.2.15.patch38097
2 files changed, 38101 insertions, 0 deletions
diff --git a/0000_README b/0000_README
index a1325df7..025f8570 100644
--- a/0000_README
+++ b/0000_README
@@ -99,6 +99,10 @@ Patch: 1013_linux-6.2.14.patch
From: https://www.kernel.org
Desc: Linux 6.2.14
+Patch: 1014_linux-6.2.15.patch
+From: https://www.kernel.org
+Desc: Linux 6.2.15
+
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/1014_linux-6.2.15.patch b/1014_linux-6.2.15.patch
new file mode 100644
index 00000000..030da015
--- /dev/null
+++ b/1014_linux-6.2.15.patch
@@ -0,0 +1,38097 @@
+diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml b/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml
+index 79c6f8da1319c..b0b95689d78b8 100644
+--- a/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml
++++ b/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml
+@@ -30,6 +30,7 @@ properties:
+ const: 0
+
+ clocks:
++ minItems: 3
+ maxItems: 5
+
+ clock-names:
+diff --git a/Makefile b/Makefile
+index 031d40ad0bd9d..9f535df81b033 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 2
+-SUBLEVEL = 14
++SUBLEVEL = 15
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+
+diff --git a/arch/arm/boot/dts/omap3-gta04.dtsi b/arch/arm/boot/dts/omap3-gta04.dtsi
+index 87e0ab1bbe957..e0be0fb23f80f 100644
+--- a/arch/arm/boot/dts/omap3-gta04.dtsi
++++ b/arch/arm/boot/dts/omap3-gta04.dtsi
+@@ -612,6 +612,22 @@
+ clock-frequency = <100000>;
+ };
+
++&mcspi1 {
++ status = "disabled";
++};
++
++&mcspi2 {
++ status = "disabled";
++};
++
++&mcspi3 {
++ status = "disabled";
++};
++
++&mcspi4 {
++ status = "disabled";
++};
++
+ &usb_otg_hs {
+ interface-type = <0>;
+ usb-phy = <&usb2_phy>;
+diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi
+index 0da9623ea0849..4133321edad88 100644
+--- a/arch/arm/boot/dts/qcom-apq8064.dtsi
++++ b/arch/arm/boot/dts/qcom-apq8064.dtsi
+@@ -1261,7 +1261,7 @@
+ gpu_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+- opp-320000000 {
++ opp-450000000 {
+ opp-hz = /bits/ 64 <450000000>;
+ };
+
+diff --git a/arch/arm/boot/dts/qcom-ipq4019.dtsi b/arch/arm/boot/dts/qcom-ipq4019.dtsi
+index acb08dcf94428..a89a17278a118 100644
+--- a/arch/arm/boot/dts/qcom-ipq4019.dtsi
++++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi
+@@ -426,8 +426,8 @@
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+- ranges = <0x81000000 0 0x40200000 0x40200000 0 0x00100000>,
+- <0x82000000 0 0x40300000 0x40300000 0 0x00d00000>;
++ ranges = <0x81000000 0x0 0x00000000 0x40200000 0x0 0x00100000>,
++ <0x82000000 0x0 0x40300000 0x40300000 0x0 0x00d00000>;
+
+ interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi";
+diff --git a/arch/arm/boot/dts/qcom-ipq8064.dtsi b/arch/arm/boot/dts/qcom-ipq8064.dtsi
+index 7e784b0995da2..1e6eb6773a0b0 100644
+--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
++++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
+@@ -1082,8 +1082,8 @@
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+- ranges = <0x81000000 0 0x0fe00000 0x0fe00000 0 0x00010000 /* downstream I/O */
+- 0x82000000 0 0x08000000 0x08000000 0 0x07e00000>; /* non-prefetchable memory */
++ ranges = <0x81000000 0x0 0x00000000 0x0fe00000 0x0 0x00010000 /* I/O */
++ 0x82000000 0x0 0x08000000 0x08000000 0x0 0x07e00000>; /* MEM */
+
+ interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi";
+@@ -1133,8 +1133,8 @@
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+- ranges = <0x81000000 0 0x31e00000 0x31e00000 0 0x00010000 /* downstream I/O */
+- 0x82000000 0 0x2e000000 0x2e000000 0 0x03e00000>; /* non-prefetchable memory */
++ ranges = <0x81000000 0x0 0x00000000 0x31e00000 0x0 0x00010000 /* I/O */
++ 0x82000000 0x0 0x2e000000 0x2e000000 0x0 0x03e00000>; /* MEM */
+
+ interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi";
+@@ -1184,8 +1184,8 @@
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+- ranges = <0x81000000 0 0x35e00000 0x35e00000 0 0x00010000 /* downstream I/O */
+- 0x82000000 0 0x32000000 0x32000000 0 0x03e00000>; /* non-prefetchable memory */
++ ranges = <0x81000000 0x0 0x00000000 0x35e00000 0x0 0x00010000 /* I/O */
++ 0x82000000 0x0 0x32000000 0x32000000 0x0 0x03e00000>; /* MEM */
+
+ interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi";
+diff --git a/arch/arm/boot/dts/qcom-sdx55.dtsi b/arch/arm/boot/dts/qcom-sdx55.dtsi
+index 93d71aff3fab7..e84ca795cae65 100644
+--- a/arch/arm/boot/dts/qcom-sdx55.dtsi
++++ b/arch/arm/boot/dts/qcom-sdx55.dtsi
+@@ -303,6 +303,45 @@
+ status = "disabled";
+ };
+
++ pcie_ep: pcie-ep@1c00000 {
++ compatible = "qcom,sdx55-pcie-ep";
++ reg = <0x01c00000 0x3000>,
++ <0x40000000 0xf1d>,
++ <0x40000f20 0xc8>,
++ <0x40001000 0x1000>,
++ <0x40200000 0x100000>,
++ <0x01c03000 0x3000>;
++ reg-names = "parf", "dbi", "elbi", "atu", "addr_space",
++ "mmio";
++
++ qcom,perst-regs = <&tcsr 0xb258 0xb270>;
++
++ clocks = <&gcc GCC_PCIE_AUX_CLK>,
++ <&gcc GCC_PCIE_CFG_AHB_CLK>,
++ <&gcc GCC_PCIE_MSTR_AXI_CLK>,
++ <&gcc GCC_PCIE_SLV_AXI_CLK>,
++ <&gcc GCC_PCIE_SLV_Q2A_AXI_CLK>,
++ <&gcc GCC_PCIE_SLEEP_CLK>,
++ <&gcc GCC_PCIE_0_CLKREF_CLK>;
++ clock-names = "aux", "cfg", "bus_master", "bus_slave",
++ "slave_q2a", "sleep", "ref";
++
++ interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-names = "global", "doorbell";
++ reset-gpios = <&tlmm 57 GPIO_ACTIVE_LOW>;
++ wake-gpios = <&tlmm 53 GPIO_ACTIVE_LOW>;
++ resets = <&gcc GCC_PCIE_BCR>;
++ reset-names = "core";
++ power-domains = <&gcc PCIE_GDSC>;
++ phys = <&pcie0_lane>;
++ phy-names = "pciephy";
++ max-link-speed = <3>;
++ num-lanes = <2>;
++
++ status = "disabled";
++ };
++
+ pcie0_phy: phy@1c07000 {
+ compatible = "qcom,sdx55-qmp-pcie-phy";
+ reg = <0x01c07000 0x1c4>;
+@@ -400,45 +439,6 @@
+ status = "disabled";
+ };
+
+- pcie_ep: pcie-ep@40000000 {
+- compatible = "qcom,sdx55-pcie-ep";
+- reg = <0x01c00000 0x3000>,
+- <0x40000000 0xf1d>,
+- <0x40000f20 0xc8>,
+- <0x40001000 0x1000>,
+- <0x40200000 0x100000>,
+- <0x01c03000 0x3000>;
+- reg-names = "parf", "dbi", "elbi", "atu", "addr_space",
+- "mmio";
+-
+- qcom,perst-regs = <&tcsr 0xb258 0xb270>;
+-
+- clocks = <&gcc GCC_PCIE_AUX_CLK>,
+- <&gcc GCC_PCIE_CFG_AHB_CLK>,
+- <&gcc GCC_PCIE_MSTR_AXI_CLK>,
+- <&gcc GCC_PCIE_SLV_AXI_CLK>,
+- <&gcc GCC_PCIE_SLV_Q2A_AXI_CLK>,
+- <&gcc GCC_PCIE_SLEEP_CLK>,
+- <&gcc GCC_PCIE_0_CLKREF_CLK>;
+- clock-names = "aux", "cfg", "bus_master", "bus_slave",
+- "slave_q2a", "sleep", "ref";
+-
+- interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
+- interrupt-names = "global", "doorbell";
+- reset-gpios = <&tlmm 57 GPIO_ACTIVE_LOW>;
+- wake-gpios = <&tlmm 53 GPIO_ACTIVE_LOW>;
+- resets = <&gcc GCC_PCIE_BCR>;
+- reset-names = "core";
+- power-domains = <&gcc PCIE_GDSC>;
+- phys = <&pcie0_lane>;
+- phy-names = "pciephy";
+- max-link-speed = <3>;
+- num-lanes = <2>;
+-
+- status = "disabled";
+- };
+-
+ remoteproc_mpss: remoteproc@4080000 {
+ compatible = "qcom,sdx55-mpss-pas";
+ reg = <0x04080000 0x4040>;
+diff --git a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi
+index a9d2bec990141..e15a3b2a9b399 100644
+--- a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi
++++ b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi
+@@ -1880,6 +1880,21 @@
+ };
+ };
+
++ spi1_pins_b: spi1-1 {
++ pins1 {
++ pinmux = <STM32_PINMUX('A', 5, AF5)>, /* SPI1_SCK */
++ <STM32_PINMUX('B', 5, AF5)>; /* SPI1_MOSI */
++ bias-disable;
++ drive-push-pull;
++ slew-rate = <1>;
++ };
++
++ pins2 {
++ pinmux = <STM32_PINMUX('A', 6, AF5)>; /* SPI1_MISO */
++ bias-disable;
++ };
++ };
++
+ spi2_pins_a: spi2-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('B', 10, AF5)>, /* SPI2_SCK */
+@@ -2448,19 +2463,4 @@
+ bias-disable;
+ };
+ };
+-
+- spi1_pins_b: spi1-1 {
+- pins1 {
+- pinmux = <STM32_PINMUX('A', 5, AF5)>, /* SPI1_SCK */
+- <STM32_PINMUX('B', 5, AF5)>; /* SPI1_MOSI */
+- bias-disable;
+- drive-push-pull;
+- slew-rate = <1>;
+- };
+-
+- pins2 {
+- pinmux = <STM32_PINMUX('A', 6, AF5)>; /* SPI1_MISO */
+- bias-disable;
+- };
+- };
+ };
+diff --git a/arch/arm64/boot/dts/apple/t8103-j274.dts b/arch/arm64/boot/dts/apple/t8103-j274.dts
+index b52ddc4098939..1c3e37f86d46d 100644
+--- a/arch/arm64/boot/dts/apple/t8103-j274.dts
++++ b/arch/arm64/boot/dts/apple/t8103-j274.dts
+@@ -37,10 +37,12 @@
+
+ &port01 {
+ bus-range = <2 2>;
++ status = "okay";
+ };
+
+ &port02 {
+ bus-range = <3 3>;
++ status = "okay";
+ ethernet0: ethernet@0,0 {
+ reg = <0x30000 0x0 0x0 0x0 0x0>;
+ /* To be filled by the loader */
+@@ -48,6 +50,14 @@
+ };
+ };
+
++&pcie0_dart_1 {
++ status = "okay";
++};
++
++&pcie0_dart_2 {
++ status = "okay";
++};
++
+ &i2c2 {
+ status = "okay";
+ };
+diff --git a/arch/arm64/boot/dts/apple/t8103-j293.dts b/arch/arm64/boot/dts/apple/t8103-j293.dts
+index 151074109a114..c363dfef80709 100644
+--- a/arch/arm64/boot/dts/apple/t8103-j293.dts
++++ b/arch/arm64/boot/dts/apple/t8103-j293.dts
+@@ -25,21 +25,6 @@
+ brcm,board-type = "apple,honshu";
+ };
+
+-/*
+- * Remove unused PCIe ports and disable the associated DARTs.
+- */
+-
+-&pcie0_dart_1 {
+- status = "disabled";
+-};
+-
+-&pcie0_dart_2 {
+- status = "disabled";
+-};
+-
+-/delete-node/ &port01;
+-/delete-node/ &port02;
+-
+ &i2c2 {
+ status = "okay";
+ };
+diff --git a/arch/arm64/boot/dts/apple/t8103-j313.dts b/arch/arm64/boot/dts/apple/t8103-j313.dts
+index bc1f865aa7909..08409be1cf357 100644
+--- a/arch/arm64/boot/dts/apple/t8103-j313.dts
++++ b/arch/arm64/boot/dts/apple/t8103-j313.dts
+@@ -24,18 +24,3 @@
+ &wifi0 {
+ brcm,board-type = "apple,shikoku";
+ };
+-
+-/*
+- * Remove unused PCIe ports and disable the associated DARTs.
+- */
+-
+-&pcie0_dart_1 {
+- status = "disabled";
+-};
+-
+-&pcie0_dart_2 {
+- status = "disabled";
+-};
+-
+-/delete-node/ &port01;
+-/delete-node/ &port02;
+diff --git a/arch/arm64/boot/dts/apple/t8103-j456.dts b/arch/arm64/boot/dts/apple/t8103-j456.dts
+index 2db425ceb30f6..58c8e43789b48 100644
+--- a/arch/arm64/boot/dts/apple/t8103-j456.dts
++++ b/arch/arm64/boot/dts/apple/t8103-j456.dts
+@@ -55,13 +55,23 @@
+
+ &port01 {
+ bus-range = <2 2>;
++ status = "okay";
+ };
+
+ &port02 {
+ bus-range = <3 3>;
++ status = "okay";
+ ethernet0: ethernet@0,0 {
+ reg = <0x30000 0x0 0x0 0x0 0x0>;
+ /* To be filled by the loader */
+ local-mac-address = [00 10 18 00 00 00];
+ };
+ };
++
++&pcie0_dart_1 {
++ status = "okay";
++};
++
++&pcie0_dart_2 {
++ status = "okay";
++};
+diff --git a/arch/arm64/boot/dts/apple/t8103-j457.dts b/arch/arm64/boot/dts/apple/t8103-j457.dts
+index 3821ff146c56b..152f95fd49a21 100644
+--- a/arch/arm64/boot/dts/apple/t8103-j457.dts
++++ b/arch/arm64/boot/dts/apple/t8103-j457.dts
+@@ -37,6 +37,7 @@
+
+ &port02 {
+ bus-range = <3 3>;
++ status = "okay";
+ ethernet0: ethernet@0,0 {
+ reg = <0x30000 0x0 0x0 0x0 0x0>;
+ /* To be filled by the loader */
+@@ -44,12 +45,6 @@
+ };
+ };
+
+-/*
+- * Remove unused PCIe port and disable the associated DART.
+- */
+-
+-&pcie0_dart_1 {
+- status = "disabled";
++&pcie0_dart_2 {
++ status = "okay";
+ };
+-
+-/delete-node/ &port01;
+diff --git a/arch/arm64/boot/dts/apple/t8103.dtsi b/arch/arm64/boot/dts/apple/t8103.dtsi
+index 9859219699f45..87a9c1ba6d0f4 100644
+--- a/arch/arm64/boot/dts/apple/t8103.dtsi
++++ b/arch/arm64/boot/dts/apple/t8103.dtsi
+@@ -724,6 +724,7 @@
+ interrupt-parent = <&aic>;
+ interrupts = <AIC_IRQ 699 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&ps_apcie_gp>;
++ status = "disabled";
+ };
+
+ pcie0_dart_2: iommu@683008000 {
+@@ -733,6 +734,7 @@
+ interrupt-parent = <&aic>;
+ interrupts = <AIC_IRQ 702 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&ps_apcie_gp>;
++ status = "disabled";
+ };
+
+ pcie0: pcie@690000000 {
+@@ -807,6 +809,7 @@
+ <0 0 0 2 &port01 0 0 0 1>,
+ <0 0 0 3 &port01 0 0 0 2>,
+ <0 0 0 4 &port01 0 0 0 3>;
++ status = "disabled";
+ };
+
+ port02: pci@2,0 {
+@@ -826,6 +829,7 @@
+ <0 0 0 2 &port02 0 0 0 1>,
+ <0 0 0 3 &port02 0 0 0 2>,
+ <0 0 0 4 &port02 0 0 0 3>;
++ status = "disabled";
+ };
+ };
+ };
+diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908-asus-gt-ac5300.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908-asus-gt-ac5300.dts
+index 839ca33178b01..d94a53d68320b 100644
+--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908-asus-gt-ac5300.dts
++++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908-asus-gt-ac5300.dts
+@@ -120,7 +120,7 @@
+ };
+
+ &leds {
+- led-power@11 {
++ led@11 {
+ reg = <0x11>;
+ function = LED_FUNCTION_POWER;
+ color = <LED_COLOR_ID_WHITE>;
+@@ -130,7 +130,7 @@
+ pinctrl-0 = <&pins_led_17_a>;
+ };
+
+- led-wan-red@12 {
++ led@12 {
+ reg = <0x12>;
+ function = LED_FUNCTION_WAN;
+ color = <LED_COLOR_ID_RED>;
+@@ -139,7 +139,7 @@
+ pinctrl-0 = <&pins_led_18_a>;
+ };
+
+- led-wps@14 {
++ led@14 {
+ reg = <0x14>;
+ function = LED_FUNCTION_WPS;
+ color = <LED_COLOR_ID_WHITE>;
+@@ -148,7 +148,7 @@
+ pinctrl-0 = <&pins_led_20_a>;
+ };
+
+- led-wan-white@15 {
++ led@15 {
+ reg = <0x15>;
+ function = LED_FUNCTION_WAN;
+ color = <LED_COLOR_ID_WHITE>;
+@@ -157,7 +157,7 @@
+ pinctrl-0 = <&pins_led_21_a>;
+ };
+
+- led-lan@19 {
++ led@19 {
+ reg = <0x19>;
+ function = LED_FUNCTION_LAN;
+ color = <LED_COLOR_ID_WHITE>;
+diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
+index eb2a78f4e0332..343b320cbd746 100644
+--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
++++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
+@@ -254,7 +254,7 @@
+ };
+ };
+
+- procmon: syscon@280000 {
++ procmon: bus@280000 {
+ compatible = "simple-bus";
+ reg = <0x280000 0x1000>;
+ ranges;
+@@ -538,7 +538,7 @@
+ reg = <0x1800 0x600>, <0x2000 0x10>;
+ reg-names = "nand", "nand-int-base";
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+- interrupt-names = "nand";
++ interrupt-names = "nand_ctlrdy";
+ status = "okay";
+
+ nandcs: nand@0 {
+diff --git a/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi b/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi
+index 4b314435f8fd6..50367da93cd79 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi
+@@ -935,7 +935,7 @@
+ regulator-compatible = "vbuck1";
+ regulator-name = "Vgpu";
+ regulator-min-microvolt = <606250>;
+- regulator-max-microvolt = <1193750>;
++ regulator-max-microvolt = <800000>;
+ regulator-enable-ramp-delay = <256>;
+ regulator-allowed-modes = <0 1 2>;
+ };
+diff --git a/arch/arm64/boot/dts/qcom/apq8096-db820c.dts b/arch/arm64/boot/dts/qcom/apq8096-db820c.dts
+index fe6c415e82297..5251dbcab4d90 100644
+--- a/arch/arm64/boot/dts/qcom/apq8096-db820c.dts
++++ b/arch/arm64/boot/dts/qcom/apq8096-db820c.dts
+@@ -706,8 +706,7 @@
+ &pmi8994_spmi_regulators {
+ vdd_s2-supply = <&vph_pwr>;
+
+- vdd_gfx: s2@1700 {
+- reg = <0x1700 0x100>;
++ vdd_gfx: s2 {
+ regulator-name = "VDD_GFX";
+ regulator-min-microvolt = <980000>;
+ regulator-max-microvolt = <980000>;
+diff --git a/arch/arm64/boot/dts/qcom/ipq6018.dtsi b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
+index 5d453f11acd98..4663e23cd94f4 100644
+--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi
++++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
+@@ -96,26 +96,31 @@
+ opp-microvolt = <725000>;
+ clock-latency-ns = <200000>;
+ };
++
+ opp-1056000000 {
+ opp-hz = /bits/ 64 <1056000000>;
+ opp-microvolt = <787500>;
+ clock-latency-ns = <200000>;
+ };
++
+ opp-1320000000 {
+ opp-hz = /bits/ 64 <1320000000>;
+ opp-microvolt = <862500>;
+ clock-latency-ns = <200000>;
+ };
++
+ opp-1440000000 {
+ opp-hz = /bits/ 64 <1440000000>;
+ opp-microvolt = <925000>;
+ clock-latency-ns = <200000>;
+ };
++
+ opp-1608000000 {
+ opp-hz = /bits/ 64 <1608000000>;
+ opp-microvolt = <987500>;
+ clock-latency-ns = <200000>;
+ };
++
+ opp-1800000000 {
+ opp-hz = /bits/ 64 <1800000000>;
+ opp-microvolt = <1062500>;
+@@ -131,8 +136,7 @@
+
+ pmuv8: pmu {
+ compatible = "arm,cortex-a53-pmu";
+- interrupts = <GIC_PPI 7 (GIC_CPU_MASK_SIMPLE(4) |
+- IRQ_TYPE_LEVEL_HIGH)>;
++ interrupts = <GIC_PPI 7 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
+ psci: psci {
+@@ -437,24 +441,18 @@
+ phys = <&pcie_phy0>;
+ phy-names = "pciephy";
+
+- ranges = <0x81000000 0 0x20200000 0 0x20200000
+- 0 0x10000>, /* downstream I/O */
+- <0x82000000 0 0x20220000 0 0x20220000
+- 0 0xfde0000>; /* non-prefetchable memory */
++ ranges = <0x81000000 0x0 0x00000000 0x0 0x20200000 0x0 0x10000>,
++ <0x82000000 0x0 0x20220000 0x0 0x20220000 0x0 0xfde0000>;
+
+ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi";
+
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0x7>;
+- interrupt-map = <0 0 0 1 &intc 0 75
+- IRQ_TYPE_LEVEL_HIGH>, /* int_a */
+- <0 0 0 2 &intc 0 78
+- IRQ_TYPE_LEVEL_HIGH>, /* int_b */
+- <0 0 0 3 &intc 0 79
+- IRQ_TYPE_LEVEL_HIGH>, /* int_c */
+- <0 0 0 4 &intc 0 83
+- IRQ_TYPE_LEVEL_HIGH>; /* int_d */
++ interrupt-map = <0 0 0 1 &intc 0 75 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
++ <0 0 0 2 &intc 0 78 IRQ_TYPE_LEVEL_HIGH>, /* int_b */
++ <0 0 0 3 &intc 0 79 IRQ_TYPE_LEVEL_HIGH>, /* int_c */
++ <0 0 0 4 &intc 0 83 IRQ_TYPE_LEVEL_HIGH>; /* int_d */
+
+ clocks = <&gcc GCC_SYS_NOC_PCIE0_AXI_CLK>,
+ <&gcc GCC_PCIE0_AXI_M_CLK>,
+diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+index 4294beeb494fd..ffb50e5ea2efd 100644
+--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
++++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+@@ -772,10 +772,8 @@
+ phys = <&pcie_phy1>;
+ phy-names = "pciephy";
+
+- ranges = <0x81000000 0 0x10200000 0x10200000
+- 0 0x10000>, /* downstream I/O */
+- <0x82000000 0 0x10220000 0x10220000
+- 0 0xfde0000>; /* non-prefetchable memory */
++ ranges = <0x81000000 0x0 0x00000000 0x10200000 0x0 0x10000>, /* I/O */
++ <0x82000000 0x0 0x10220000 0x10220000 0x0 0xfde0000>; /* MEM */
+
+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi";
+@@ -836,10 +834,8 @@
+ phys = <&pcie_phy0>;
+ phy-names = "pciephy";
+
+- ranges = <0x81000000 0 0x20200000 0x20200000
+- 0 0x10000>, /* downstream I/O */
+- <0x82000000 0 0x20220000 0x20220000
+- 0 0xfde0000>; /* non-prefetchable memory */
++ ranges = <0x81000000 0x0 0x00000000 0x20200000 0x0 0x10000>, /* I/O */
++ <0x82000000 0x0 0x20220000 0x20220000 0x0 0xfde0000>; /* MEM */
+
+ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi";
+diff --git a/arch/arm64/boot/dts/qcom/msm8956-sony-xperia-loire.dtsi b/arch/arm64/boot/dts/qcom/msm8956-sony-xperia-loire.dtsi
+index 67baced639c91..085d79542e1bb 100644
+--- a/arch/arm64/boot/dts/qcom/msm8956-sony-xperia-loire.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8956-sony-xperia-loire.dtsi
+@@ -280,3 +280,7 @@
+ vdda3p3-supply = <&pm8950_l13>;
+ status = "okay";
+ };
++
++&xo_board {
++ clock-frequency = <19200000>;
++};
+diff --git a/arch/arm64/boot/dts/qcom/msm8976.dtsi b/arch/arm64/boot/dts/qcom/msm8976.dtsi
+index 05dcb30b07795..c125ebcdd1e47 100644
+--- a/arch/arm64/boot/dts/qcom/msm8976.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8976.dtsi
+@@ -20,6 +20,13 @@
+
+ chosen { };
+
++ clocks {
++ xo_board: xo-board {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ };
++ };
++
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+@@ -351,6 +358,8 @@
+
+ rpmcc: clock-controller {
+ compatible = "qcom,rpmcc-msm8976", "qcom,rpmcc";
++ clocks = <&xo_board>;
++ clock-names = "xo";
+ #clock-cells = <1>;
+ };
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8992-lg-bullhead.dtsi b/arch/arm64/boot/dts/qcom/msm8992-lg-bullhead.dtsi
+index cd77dcb558722..b8f2a01bcb96c 100644
+--- a/arch/arm64/boot/dts/qcom/msm8992-lg-bullhead.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8992-lg-bullhead.dtsi
+@@ -60,11 +60,6 @@
+ reg = <0x0 0x05000000 0x0 0x1a00000>;
+ no-map;
+ };
+-
+- reserved@6c00000 {
+- reg = <0x0 0x06c00000 0x0 0x400000>;
+- no-map;
+- };
+ };
+ };
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8994-huawei-angler-rev-101.dts b/arch/arm64/boot/dts/qcom/msm8994-huawei-angler-rev-101.dts
+index 7b0f62144c3ee..29e79ae0849d8 100644
+--- a/arch/arm64/boot/dts/qcom/msm8994-huawei-angler-rev-101.dts
++++ b/arch/arm64/boot/dts/qcom/msm8994-huawei-angler-rev-101.dts
+@@ -2,7 +2,7 @@
+ /*
+ * Copyright (c) 2015, Huawei Inc. All rights reserved.
+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+- * Copyright (c) 2021-2022, Petr Vorel <petr.vorel@gmail.com>
++ * Copyright (c) 2021-2023, Petr Vorel <petr.vorel@gmail.com>
+ */
+
+ /dts-v1/;
+@@ -31,13 +31,18 @@
+ #size-cells = <2>;
+ ranges;
+
++ cont_splash_mem: memory@3401000 {
++ reg = <0 0x03401000 0 0x1000000>;
++ no-map;
++ };
++
+ tzapp_mem: tzapp@4800000 {
+ reg = <0 0x04800000 0 0x1900000>;
+ no-map;
+ };
+
+- removed_region: reserved@6300000 {
+- reg = <0 0x06300000 0 0xD00000>;
++ reserved@6300000 {
++ reg = <0 0x06300000 0 0x700000>;
+ no-map;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/qcom/msm8994-msft-lumia-octagon.dtsi b/arch/arm64/boot/dts/qcom/msm8994-msft-lumia-octagon.dtsi
+index 9b67f0d3820cd..63dda2ab06241 100644
+--- a/arch/arm64/boot/dts/qcom/msm8994-msft-lumia-octagon.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8994-msft-lumia-octagon.dtsi
+@@ -542,8 +542,7 @@
+ };
+
+ &pmi8994_spmi_regulators {
+- vdd_gfx: s2@1700 {
+- reg = <0x1700 0x100>;
++ vdd_gfx: s2 {
+ regulator-min-microvolt = <980000>;
+ regulator-max-microvolt = <980000>;
+ };
+diff --git a/arch/arm64/boot/dts/qcom/msm8994-sony-xperia-kitakami.dtsi b/arch/arm64/boot/dts/qcom/msm8994-sony-xperia-kitakami.dtsi
+index f3d153c349188..db2282c9f68bf 100644
+--- a/arch/arm64/boot/dts/qcom/msm8994-sony-xperia-kitakami.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8994-sony-xperia-kitakami.dtsi
+@@ -173,8 +173,7 @@
+ * power domain.. which still isn't enough and forces us to bind
+ * OXILI_CX and OXILI_GX together!
+ */
+- vdd_gfx: s2@1700 {
+- reg = <0x1700 0x100>;
++ vdd_gfx: s2 {
+ regulator-name = "VDD_GFX";
+ regulator-min-microvolt = <980000>;
+ regulator-max-microvolt = <980000>;
+diff --git a/arch/arm64/boot/dts/qcom/msm8994.dtsi b/arch/arm64/boot/dts/qcom/msm8994.dtsi
+index 9ff9d35496d21..24c3fced8df71 100644
+--- a/arch/arm64/boot/dts/qcom/msm8994.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8994.dtsi
+@@ -228,6 +228,11 @@
+ reg = <0 0xc9400000 0 0x3f00000>;
+ no-map;
+ };
++
++ reserved@6c00000 {
++ reg = <0 0x06c00000 0 0x400000>;
++ no-map;
++ };
+ };
+
+ smd {
+diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
+index 71678749d66f6..25d97cc2d08ff 100644
+--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
+@@ -1841,8 +1841,8 @@
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+- ranges = <0x01000000 0x0 0x0c200000 0x0c200000 0x0 0x100000>,
+- <0x02000000 0x0 0x0c300000 0x0c300000 0x0 0xd00000>;
++ ranges = <0x01000000 0x0 0x00000000 0x0c200000 0x0 0x100000>,
++ <0x02000000 0x0 0x0c300000 0x0c300000 0x0 0xd00000>;
+
+ device_type = "pci";
+
+@@ -1895,8 +1895,8 @@
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+- ranges = <0x01000000 0x0 0x0d200000 0x0d200000 0x0 0x100000>,
+- <0x02000000 0x0 0x0d300000 0x0d300000 0x0 0xd00000>;
++ ranges = <0x01000000 0x0 0x00000000 0x0d200000 0x0 0x100000>,
++ <0x02000000 0x0 0x0d300000 0x0d300000 0x0 0xd00000>;
+
+ device_type = "pci";
+
+@@ -1946,8 +1946,8 @@
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+- ranges = <0x01000000 0x0 0x0e200000 0x0e200000 0x0 0x100000>,
+- <0x02000000 0x0 0x0e300000 0x0e300000 0x0 0x1d00000>;
++ ranges = <0x01000000 0x0 0x00000000 0x0e200000 0x0 0x100000>,
++ <0x02000000 0x0 0x0e300000 0x0e300000 0x0 0x1d00000>;
+
+ device_type = "pci";
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8998-oneplus-cheeseburger.dts b/arch/arm64/boot/dts/qcom/msm8998-oneplus-cheeseburger.dts
+index 9fb1fb9b85298..794e9f2ab77ab 100644
+--- a/arch/arm64/boot/dts/qcom/msm8998-oneplus-cheeseburger.dts
++++ b/arch/arm64/boot/dts/qcom/msm8998-oneplus-cheeseburger.dts
+@@ -34,7 +34,7 @@
+ &pmi8998_gpio {
+ button_backlight_default: button-backlight-state {
+ pins = "gpio5";
+- function = "gpio";
++ function = "normal";
+ bias-pull-down;
+ qcom,drive-strength = <PMIC_GPIO_STRENGTH_NO>;
+ };
+diff --git a/arch/arm64/boot/dts/qcom/msm8998.dtsi b/arch/arm64/boot/dts/qcom/msm8998.dtsi
+index 539382dab0ada..c8c76338ae18b 100644
+--- a/arch/arm64/boot/dts/qcom/msm8998.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8998.dtsi
+@@ -916,7 +916,7 @@
+ phy-names = "pciephy";
+ status = "disabled";
+
+- ranges = <0x01000000 0x0 0x1b200000 0x1b200000 0x0 0x100000>,
++ ranges = <0x01000000 0x0 0x00000000 0x1b200000 0x0 0x100000>,
+ <0x02000000 0x0 0x1b300000 0x1b300000 0x0 0xd00000>;
+
+ #interrupt-cells = <1>;
+@@ -1514,7 +1514,7 @@
+ compatible = "arm,coresight-stm", "arm,primecell";
+ reg = <0x06002000 0x1000>,
+ <0x16280000 0x180000>;
+- reg-names = "stm-base", "stm-data-base";
++ reg-names = "stm-base", "stm-stimulus-base";
+ status = "disabled";
+
+ clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
+diff --git a/arch/arm64/boot/dts/qcom/pmi8994.dtsi b/arch/arm64/boot/dts/qcom/pmi8994.dtsi
+index a0af91698d497..0192968f4d9b3 100644
+--- a/arch/arm64/boot/dts/qcom/pmi8994.dtsi
++++ b/arch/arm64/boot/dts/qcom/pmi8994.dtsi
+@@ -49,8 +49,6 @@
+
+ pmi8994_spmi_regulators: regulators {
+ compatible = "qcom,pmi8994-regulators";
+- #address-cells = <1>;
+- #size-cells = <1>;
+ };
+
+ pmi8994_wled: wled@d800 {
+diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-nots-r4.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-nots-r4.dts
+index 850776c5323d1..70d5a7aa88735 100644
+--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-nots-r4.dts
++++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-nots-r4.dts
+@@ -26,7 +26,7 @@
+ interrupt-parent = <&tlmm>;
+ interrupts = <58 IRQ_TYPE_EDGE_FALLING>;
+
+- vcc-supply = <&pp3300_fp_tp>;
++ vdd-supply = <&pp3300_fp_tp>;
+ hid-descr-addr = <0x20>;
+
+ wakeup-source;
+diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel.dtsi
+index d06cc4ea33756..8823edbb4d6e2 100644
+--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel.dtsi
+@@ -39,7 +39,7 @@
+ interrupt-parent = <&tlmm>;
+ interrupts = <0 IRQ_TYPE_EDGE_FALLING>;
+
+- vcc-supply = <&pp3300_fp_tp>;
++ vdd-supply = <&pp3300_fp_tp>;
+ post-power-on-delay-ms = <100>;
+ hid-descr-addr = <0x0001>;
+
+diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi
+index e45726be81c82..4e7d93ff75c47 100644
+--- a/arch/arm64/boot/dts/qcom/sc7180.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi
+@@ -1512,7 +1512,7 @@
+ function = "qspi_data";
+ };
+
+- qspi_data12: qspi-data12-state {
++ qspi_data23: qspi-data23-state {
+ pins = "gpio66", "gpio67";
+ function = "qspi_data";
+ };
+diff --git a/arch/arm64/boot/dts/qcom/sc7280-herobrine-villager.dtsi b/arch/arm64/boot/dts/qcom/sc7280-herobrine-villager.dtsi
+index 17553e0fd6fd9..43d76ea8869fb 100644
+--- a/arch/arm64/boot/dts/qcom/sc7280-herobrine-villager.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc7280-herobrine-villager.dtsi
+@@ -33,7 +33,7 @@ ap_tp_i2c: &i2c0 {
+ interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
+
+ hid-descr-addr = <0x20>;
+- vcc-supply = <&pp3300_z1>;
++ vdd-supply = <&pp3300_z1>;
+
+ wakeup-source;
+ };
+diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi
+index a407cd2579719..286d59d11f2e9 100644
+--- a/arch/arm64/boot/dts/qcom/sc7280.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi
+@@ -2068,7 +2068,7 @@
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+- ranges = <0x01000000 0x0 0x40200000 0x0 0x40200000 0x0 0x100000>,
++ ranges = <0x01000000 0x0 0x00000000 0x0 0x40200000 0x0 0x100000>,
+ <0x02000000 0x0 0x40300000 0x0 0x40300000 0x0 0x1fd00000>;
+
+ interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>;
+@@ -3592,12 +3592,17 @@
+ <0 0x88e2000 0 0x1000>;
+ interrupts-extended = <&pdc 11 IRQ_TYPE_LEVEL_HIGH>;
+ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
+ port@0 {
++ reg = <0>;
+ eud_ep: endpoint {
+ remote-endpoint = <&usb2_role_switch>;
+ };
+ };
+ port@1 {
++ reg = <1>;
+ eud_con: endpoint {
+ remote-endpoint = <&con_eud>;
+ };
+@@ -3608,7 +3613,11 @@
+ eud_typec: connector {
+ compatible = "usb-c-connector";
+ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
+ port@0 {
++ reg = <0>;
+ con_eud: endpoint {
+ remote-endpoint = <&eud_con>;
+ };
+@@ -4340,7 +4349,7 @@
+ function = "qspi_data";
+ };
+
+- qspi_data12: qspi-data12-state {
++ qspi_data23: qspi-data23-state {
+ pins = "gpio16", "gpio17";
+ function = "qspi_data";
+ };
+diff --git a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
+index 8363e82369854..966dca906bf07 100644
+--- a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
+@@ -902,7 +902,7 @@
+ reg-names = "parf", "dbi", "elbi", "atu", "config";
+ #address-cells = <3>;
+ #size-cells = <2>;
+- ranges = <0x01000000 0x0 0x30200000 0x0 0x30200000 0x0 0x100000>,
++ ranges = <0x01000000 0x0 0x00000000 0x0 0x30200000 0x0 0x100000>,
+ <0x02000000 0x0 0x30300000 0x0 0x30300000 0x0 0x1d00000>;
+ bus-range = <0x00 0xff>;
+
+@@ -1001,7 +1001,7 @@
+ reg-names = "parf", "dbi", "elbi", "atu", "config";
+ #address-cells = <3>;
+ #size-cells = <2>;
+- ranges = <0x01000000 0x0 0x32200000 0x0 0x32200000 0x0 0x100000>,
++ ranges = <0x01000000 0x0 0x00000000 0x0 0x32200000 0x0 0x100000>,
+ <0x02000000 0x0 0x32300000 0x0 0x32300000 0x0 0x1d00000>;
+ bus-range = <0x00 0xff>;
+
+@@ -1098,7 +1098,7 @@
+ reg-names = "parf", "dbi", "elbi", "atu", "config";
+ #address-cells = <3>;
+ #size-cells = <2>;
+- ranges = <0x01000000 0x0 0x34200000 0x0 0x34200000 0x0 0x100000>,
++ ranges = <0x01000000 0x0 0x00000000 0x0 0x34200000 0x0 0x100000>,
+ <0x02000000 0x0 0x34300000 0x0 0x34300000 0x0 0x1d00000>;
+ bus-range = <0x00 0xff>;
+
+@@ -1198,7 +1198,7 @@
+ reg-names = "parf", "dbi", "elbi", "atu", "config";
+ #address-cells = <3>;
+ #size-cells = <2>;
+- ranges = <0x01000000 0x0 0x38200000 0x0 0x38200000 0x0 0x100000>,
++ ranges = <0x01000000 0x0 0x00000000 0x0 0x38200000 0x0 0x100000>,
+ <0x02000000 0x0 0x38300000 0x0 0x38300000 0x0 0x1d00000>;
+ bus-range = <0x00 0xff>;
+
+@@ -1295,7 +1295,7 @@
+ reg-names = "parf", "dbi", "elbi", "atu", "config";
+ #address-cells = <3>;
+ #size-cells = <2>;
+- ranges = <0x01000000 0x0 0x3c200000 0x0 0x3c200000 0x0 0x100000>,
++ ranges = <0x01000000 0x0 0x00000000 0x0 0x3c200000 0x0 0x100000>,
+ <0x02000000 0x0 0x3c300000 0x0 0x3c300000 0x0 0x1d00000>;
+ bus-range = <0x00 0xff>;
+
+diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
+index f36c23e7a2248..c8b54e401eb98 100644
+--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
++++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
+@@ -198,7 +198,7 @@
+ reg = <0x0 0x0>;
+ enable-method = "psci";
+ capacity-dmips-mhz = <611>;
+- dynamic-power-coefficient = <290>;
++ dynamic-power-coefficient = <154>;
+ qcom,freq-domain = <&cpufreq_hw 0>;
+ operating-points-v2 = <&cpu0_opp_table>;
+ interconnects = <&gladiator_noc MASTER_APPSS_PROC 3 &mem_noc SLAVE_EBI1 3>,
+@@ -222,7 +222,7 @@
+ reg = <0x0 0x100>;
+ enable-method = "psci";
+ capacity-dmips-mhz = <611>;
+- dynamic-power-coefficient = <290>;
++ dynamic-power-coefficient = <154>;
+ qcom,freq-domain = <&cpufreq_hw 0>;
+ operating-points-v2 = <&cpu0_opp_table>;
+ interconnects = <&gladiator_noc MASTER_APPSS_PROC 3 &mem_noc SLAVE_EBI1 3>,
+@@ -243,7 +243,7 @@
+ reg = <0x0 0x200>;
+ enable-method = "psci";
+ capacity-dmips-mhz = <611>;
+- dynamic-power-coefficient = <290>;
++ dynamic-power-coefficient = <154>;
+ qcom,freq-domain = <&cpufreq_hw 0>;
+ operating-points-v2 = <&cpu0_opp_table>;
+ interconnects = <&gladiator_noc MASTER_APPSS_PROC 3 &mem_noc SLAVE_EBI1 3>,
+@@ -264,7 +264,7 @@
+ reg = <0x0 0x300>;
+ enable-method = "psci";
+ capacity-dmips-mhz = <611>;
+- dynamic-power-coefficient = <290>;
++ dynamic-power-coefficient = <154>;
+ qcom,freq-domain = <&cpufreq_hw 0>;
+ operating-points-v2 = <&cpu0_opp_table>;
+ interconnects = <&gladiator_noc MASTER_APPSS_PROC 3 &mem_noc SLAVE_EBI1 3>,
+@@ -2226,8 +2226,8 @@
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+- ranges = <0x01000000 0x0 0x60200000 0 0x60200000 0x0 0x100000>,
+- <0x02000000 0x0 0x60300000 0 0x60300000 0x0 0xd00000>;
++ ranges = <0x01000000 0x0 0x00000000 0x0 0x60200000 0x0 0x100000>,
++ <0x02000000 0x0 0x60300000 0x0 0x60300000 0x0 0xd00000>;
+
+ interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi";
+@@ -2331,7 +2331,7 @@
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+- ranges = <0x01000000 0x0 0x40200000 0x0 0x40200000 0x0 0x100000>,
++ ranges = <0x01000000 0x0 0x00000000 0x0 0x40200000 0x0 0x100000>,
+ <0x02000000 0x0 0x40300000 0x0 0x40300000 0x0 0x1fd00000>;
+
+ interrupts = <GIC_SPI 307 IRQ_TYPE_EDGE_RISING>;
+@@ -2705,7 +2705,7 @@
+ };
+ };
+
+- qspi_data12: qspi-data12 {
++ qspi_data23: qspi-data23 {
+ pinmux-data {
+ pins = "gpio93", "gpio94";
+ function = "qspi_data";
+diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi
+index f790223ed8f5a..d338a987e8868 100644
+--- a/arch/arm64/boot/dts/qcom/sm8150.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi
+@@ -1783,8 +1783,8 @@
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+- ranges = <0x01000000 0x0 0x60200000 0 0x60200000 0x0 0x100000>,
+- <0x02000000 0x0 0x60300000 0 0x60300000 0x0 0x3d00000>;
++ ranges = <0x01000000 0x0 0x00000000 0x0 0x60200000 0x0 0x100000>,
++ <0x02000000 0x0 0x60300000 0x0 0x60300000 0x0 0x3d00000>;
+
+ interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi";
+@@ -1879,7 +1879,7 @@
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+- ranges = <0x01000000 0x0 0x40200000 0x0 0x40200000 0x0 0x100000>,
++ ranges = <0x01000000 0x0 0x00000000 0x0 0x40200000 0x0 0x100000>,
+ <0x02000000 0x0 0x40300000 0x0 0x40300000 0x0 0x1fd00000>;
+
+ interrupts = <GIC_SPI 307 IRQ_TYPE_EDGE_RISING>;
+diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi
+index 927032863e2f1..d3f2f617047f1 100644
+--- a/arch/arm64/boot/dts/qcom/sm8250.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi
+@@ -1807,8 +1807,8 @@
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+- ranges = <0x01000000 0x0 0x60200000 0 0x60200000 0x0 0x100000>,
+- <0x02000000 0x0 0x60300000 0 0x60300000 0x0 0x3d00000>;
++ ranges = <0x01000000 0x0 0x00000000 0x0 0x60200000 0x0 0x100000>,
++ <0x02000000 0x0 0x60300000 0x0 0x60300000 0x0 0x3d00000>;
+
+ interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+@@ -1916,7 +1916,7 @@
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+- ranges = <0x01000000 0x0 0x40200000 0x0 0x40200000 0x0 0x100000>,
++ ranges = <0x01000000 0x0 0x00000000 0x0 0x40200000 0x0 0x100000>,
+ <0x02000000 0x0 0x40300000 0x0 0x40300000 0x0 0x1fd00000>;
+
+ interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>;
+@@ -2024,7 +2024,7 @@
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+- ranges = <0x01000000 0x0 0x64200000 0x0 0x64200000 0x0 0x100000>,
++ ranges = <0x01000000 0x0 0x00000000 0x0 0x64200000 0x0 0x100000>,
+ <0x02000000 0x0 0x64300000 0x0 0x64300000 0x0 0x3d00000>;
+
+ interrupts = <GIC_SPI 243 IRQ_TYPE_LEVEL_HIGH>;
+diff --git a/arch/arm64/boot/dts/qcom/sm8350-microsoft-surface-duo2.dts b/arch/arm64/boot/dts/qcom/sm8350-microsoft-surface-duo2.dts
+index 9c4cfd995ff29..e87514d8fd84e 100644
+--- a/arch/arm64/boot/dts/qcom/sm8350-microsoft-surface-duo2.dts
++++ b/arch/arm64/boot/dts/qcom/sm8350-microsoft-surface-duo2.dts
+@@ -341,6 +341,9 @@
+
+ &usb_1 {
+ status = "okay";
++};
++
++&usb_1_dwc3 {
+ dr_mode = "peripheral";
+ };
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8450.dtsi b/arch/arm64/boot/dts/qcom/sm8450.dtsi
+index 16a73288c1b37..d86ee3dd2270a 100644
+--- a/arch/arm64/boot/dts/qcom/sm8450.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8450.dtsi
+@@ -1726,8 +1726,8 @@
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+- ranges = <0x01000000 0x0 0x60200000 0 0x60200000 0x0 0x100000>,
+- <0x02000000 0x0 0x60300000 0 0x60300000 0x0 0x3d00000>;
++ ranges = <0x01000000 0x0 0x00000000 0x0 0x60200000 0x0 0x100000>,
++ <0x02000000 0x0 0x60300000 0x0 0x60300000 0x0 0x3d00000>;
+
+ interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi";
+@@ -1835,8 +1835,8 @@
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+- ranges = <0x01000000 0x0 0x40200000 0 0x40200000 0x0 0x100000>,
+- <0x02000000 0x0 0x40300000 0 0x40300000 0x0 0x1fd00000>;
++ ranges = <0x01000000 0x0 0x00000000 0x0 0x40200000 0x0 0x100000>,
++ <0x02000000 0x0 0x40300000 0x0 0x40300000 0x0 0x1fd00000>;
+
+ interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi";
+@@ -1883,8 +1883,8 @@
+ phys = <&pcie1_lane>;
+ phy-names = "pciephy";
+
+- perst-gpio = <&tlmm 97 GPIO_ACTIVE_LOW>;
+- enable-gpio = <&tlmm 99 GPIO_ACTIVE_HIGH>;
++ perst-gpios = <&tlmm 97 GPIO_ACTIVE_LOW>;
++ wake-gpios = <&tlmm 99 GPIO_ACTIVE_HIGH>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie1_default_state>;
+diff --git a/arch/arm64/boot/dts/renesas/r8a774c0.dtsi b/arch/arm64/boot/dts/renesas/r8a774c0.dtsi
+index 151e32ac03683..ec7c7851519f4 100644
+--- a/arch/arm64/boot/dts/renesas/r8a774c0.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a774c0.dtsi
+@@ -49,17 +49,14 @@
+ opp-shared;
+ opp-800000000 {
+ opp-hz = /bits/ 64 <800000000>;
+- opp-microvolt = <820000>;
+ clock-latency-ns = <300000>;
+ };
+ opp-1000000000 {
+ opp-hz = /bits/ 64 <1000000000>;
+- opp-microvolt = <820000>;
+ clock-latency-ns = <300000>;
+ };
+ opp-1200000000 {
+ opp-hz = /bits/ 64 <1200000000>;
+- opp-microvolt = <820000>;
+ clock-latency-ns = <300000>;
+ opp-suspend;
+ };
+diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
+index 3053b4b214978..3ed31ffd73a28 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
+@@ -49,17 +49,14 @@
+ opp-shared;
+ opp-800000000 {
+ opp-hz = /bits/ 64 <800000000>;
+- opp-microvolt = <820000>;
+ clock-latency-ns = <300000>;
+ };
+ opp-1000000000 {
+ opp-hz = /bits/ 64 <1000000000>;
+- opp-microvolt = <820000>;
+ clock-latency-ns = <300000>;
+ };
+ opp-1200000000 {
+ opp-hz = /bits/ 64 <1200000000>;
+- opp-microvolt = <820000>;
+ clock-latency-ns = <300000>;
+ opp-suspend;
+ };
+diff --git a/arch/arm64/boot/dts/renesas/r9a07g043.dtsi b/arch/arm64/boot/dts/renesas/r9a07g043.dtsi
+index 3f7d451b11995..95817679b3884 100644
+--- a/arch/arm64/boot/dts/renesas/r9a07g043.dtsi
++++ b/arch/arm64/boot/dts/renesas/r9a07g043.dtsi
+@@ -80,9 +80,8 @@
+ reg = <0 0x10049c00 0 0x400>;
+ interrupts = <SOC_PERIPHERAL_IRQ(326) IRQ_TYPE_LEVEL_HIGH>,
+ <SOC_PERIPHERAL_IRQ(327) IRQ_TYPE_EDGE_RISING>,
+- <SOC_PERIPHERAL_IRQ(328) IRQ_TYPE_EDGE_RISING>,
+- <SOC_PERIPHERAL_IRQ(329) IRQ_TYPE_EDGE_RISING>;
+- interrupt-names = "int_req", "dma_rx", "dma_tx", "dma_rt";
++ <SOC_PERIPHERAL_IRQ(328) IRQ_TYPE_EDGE_RISING>;
++ interrupt-names = "int_req", "dma_rx", "dma_tx";
+ clocks = <&cpg CPG_MOD R9A07G043_SSI0_PCLK2>,
+ <&cpg CPG_MOD R9A07G043_SSI0_PCLK_SFR>,
+ <&audio_clk1>, <&audio_clk2>;
+@@ -101,9 +100,8 @@
+ reg = <0 0x1004a000 0 0x400>;
+ interrupts = <SOC_PERIPHERAL_IRQ(330) IRQ_TYPE_LEVEL_HIGH>,
+ <SOC_PERIPHERAL_IRQ(331) IRQ_TYPE_EDGE_RISING>,
+- <SOC_PERIPHERAL_IRQ(332) IRQ_TYPE_EDGE_RISING>,
+- <SOC_PERIPHERAL_IRQ(333) IRQ_TYPE_EDGE_RISING>;
+- interrupt-names = "int_req", "dma_rx", "dma_tx", "dma_rt";
++ <SOC_PERIPHERAL_IRQ(332) IRQ_TYPE_EDGE_RISING>;
++ interrupt-names = "int_req", "dma_rx", "dma_tx";
+ clocks = <&cpg CPG_MOD R9A07G043_SSI1_PCLK2>,
+ <&cpg CPG_MOD R9A07G043_SSI1_PCLK_SFR>,
+ <&audio_clk1>, <&audio_clk2>;
+@@ -121,10 +119,8 @@
+ "renesas,rz-ssi";
+ reg = <0 0x1004a400 0 0x400>;
+ interrupts = <SOC_PERIPHERAL_IRQ(334) IRQ_TYPE_LEVEL_HIGH>,
+- <SOC_PERIPHERAL_IRQ(335) IRQ_TYPE_EDGE_RISING>,
+- <SOC_PERIPHERAL_IRQ(336) IRQ_TYPE_EDGE_RISING>,
+ <SOC_PERIPHERAL_IRQ(337) IRQ_TYPE_EDGE_RISING>;
+- interrupt-names = "int_req", "dma_rx", "dma_tx", "dma_rt";
++ interrupt-names = "int_req", "dma_rt";
+ clocks = <&cpg CPG_MOD R9A07G043_SSI2_PCLK2>,
+ <&cpg CPG_MOD R9A07G043_SSI2_PCLK_SFR>,
+ <&audio_clk1>, <&audio_clk2>;
+@@ -143,9 +139,8 @@
+ reg = <0 0x1004a800 0 0x400>;
+ interrupts = <SOC_PERIPHERAL_IRQ(338) IRQ_TYPE_LEVEL_HIGH>,
+ <SOC_PERIPHERAL_IRQ(339) IRQ_TYPE_EDGE_RISING>,
+- <SOC_PERIPHERAL_IRQ(340) IRQ_TYPE_EDGE_RISING>,
+- <SOC_PERIPHERAL_IRQ(341) IRQ_TYPE_EDGE_RISING>;
+- interrupt-names = "int_req", "dma_rx", "dma_tx", "dma_rt";
++ <SOC_PERIPHERAL_IRQ(340) IRQ_TYPE_EDGE_RISING>;
++ interrupt-names = "int_req", "dma_rx", "dma_tx";
+ clocks = <&cpg CPG_MOD R9A07G043_SSI3_PCLK2>,
+ <&cpg CPG_MOD R9A07G043_SSI3_PCLK_SFR>,
+ <&audio_clk1>, <&audio_clk2>;
+diff --git a/arch/arm64/boot/dts/renesas/r9a07g044.dtsi b/arch/arm64/boot/dts/renesas/r9a07g044.dtsi
+index 487536696d900..6a42df15440cf 100644
+--- a/arch/arm64/boot/dts/renesas/r9a07g044.dtsi
++++ b/arch/arm64/boot/dts/renesas/r9a07g044.dtsi
+@@ -175,9 +175,8 @@
+ reg = <0 0x10049c00 0 0x400>;
+ interrupts = <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 327 IRQ_TYPE_EDGE_RISING>,
+- <GIC_SPI 328 IRQ_TYPE_EDGE_RISING>,
+- <GIC_SPI 329 IRQ_TYPE_EDGE_RISING>;
+- interrupt-names = "int_req", "dma_rx", "dma_tx", "dma_rt";
++ <GIC_SPI 328 IRQ_TYPE_EDGE_RISING>;
++ interrupt-names = "int_req", "dma_rx", "dma_tx";
+ clocks = <&cpg CPG_MOD R9A07G044_SSI0_PCLK2>,
+ <&cpg CPG_MOD R9A07G044_SSI0_PCLK_SFR>,
+ <&audio_clk1>, <&audio_clk2>;
+@@ -196,9 +195,8 @@
+ reg = <0 0x1004a000 0 0x400>;
+ interrupts = <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 331 IRQ_TYPE_EDGE_RISING>,
+- <GIC_SPI 332 IRQ_TYPE_EDGE_RISING>,
+- <GIC_SPI 333 IRQ_TYPE_EDGE_RISING>;
+- interrupt-names = "int_req", "dma_rx", "dma_tx", "dma_rt";
++ <GIC_SPI 332 IRQ_TYPE_EDGE_RISING>;
++ interrupt-names = "int_req", "dma_rx", "dma_tx";
+ clocks = <&cpg CPG_MOD R9A07G044_SSI1_PCLK2>,
+ <&cpg CPG_MOD R9A07G044_SSI1_PCLK_SFR>,
+ <&audio_clk1>, <&audio_clk2>;
+@@ -216,10 +214,8 @@
+ "renesas,rz-ssi";
+ reg = <0 0x1004a400 0 0x400>;
+ interrupts = <GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 335 IRQ_TYPE_EDGE_RISING>,
+- <GIC_SPI 336 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 337 IRQ_TYPE_EDGE_RISING>;
+- interrupt-names = "int_req", "dma_rx", "dma_tx", "dma_rt";
++ interrupt-names = "int_req", "dma_rt";
+ clocks = <&cpg CPG_MOD R9A07G044_SSI2_PCLK2>,
+ <&cpg CPG_MOD R9A07G044_SSI2_PCLK_SFR>,
+ <&audio_clk1>, <&audio_clk2>;
+@@ -238,9 +234,8 @@
+ reg = <0 0x1004a800 0 0x400>;
+ interrupts = <GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 339 IRQ_TYPE_EDGE_RISING>,
+- <GIC_SPI 340 IRQ_TYPE_EDGE_RISING>,
+- <GIC_SPI 341 IRQ_TYPE_EDGE_RISING>;
+- interrupt-names = "int_req", "dma_rx", "dma_tx", "dma_rt";
++ <GIC_SPI 340 IRQ_TYPE_EDGE_RISING>;
++ interrupt-names = "int_req", "dma_rx", "dma_tx";
+ clocks = <&cpg CPG_MOD R9A07G044_SSI3_PCLK2>,
+ <&cpg CPG_MOD R9A07G044_SSI3_PCLK_SFR>,
+ <&audio_clk1>, <&audio_clk2>;
+diff --git a/arch/arm64/boot/dts/renesas/r9a07g054.dtsi b/arch/arm64/boot/dts/renesas/r9a07g054.dtsi
+index 304ade54425bf..fea537d9fce66 100644
+--- a/arch/arm64/boot/dts/renesas/r9a07g054.dtsi
++++ b/arch/arm64/boot/dts/renesas/r9a07g054.dtsi
+@@ -175,9 +175,8 @@
+ reg = <0 0x10049c00 0 0x400>;
+ interrupts = <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 327 IRQ_TYPE_EDGE_RISING>,
+- <GIC_SPI 328 IRQ_TYPE_EDGE_RISING>,
+- <GIC_SPI 329 IRQ_TYPE_EDGE_RISING>;
+- interrupt-names = "int_req", "dma_rx", "dma_tx", "dma_rt";
++ <GIC_SPI 328 IRQ_TYPE_EDGE_RISING>;
++ interrupt-names = "int_req", "dma_rx", "dma_tx";
+ clocks = <&cpg CPG_MOD R9A07G054_SSI0_PCLK2>,
+ <&cpg CPG_MOD R9A07G054_SSI0_PCLK_SFR>,
+ <&audio_clk1>, <&audio_clk2>;
+@@ -196,9 +195,8 @@
+ reg = <0 0x1004a000 0 0x400>;
+ interrupts = <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 331 IRQ_TYPE_EDGE_RISING>,
+- <GIC_SPI 332 IRQ_TYPE_EDGE_RISING>,
+- <GIC_SPI 333 IRQ_TYPE_EDGE_RISING>;
+- interrupt-names = "int_req", "dma_rx", "dma_tx", "dma_rt";
++ <GIC_SPI 332 IRQ_TYPE_EDGE_RISING>;
++ interrupt-names = "int_req", "dma_rx", "dma_tx";
+ clocks = <&cpg CPG_MOD R9A07G054_SSI1_PCLK2>,
+ <&cpg CPG_MOD R9A07G054_SSI1_PCLK_SFR>,
+ <&audio_clk1>, <&audio_clk2>;
+@@ -216,10 +214,8 @@
+ "renesas,rz-ssi";
+ reg = <0 0x1004a400 0 0x400>;
+ interrupts = <GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 335 IRQ_TYPE_EDGE_RISING>,
+- <GIC_SPI 336 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 337 IRQ_TYPE_EDGE_RISING>;
+- interrupt-names = "int_req", "dma_rx", "dma_tx", "dma_rt";
++ interrupt-names = "int_req", "dma_rt";
+ clocks = <&cpg CPG_MOD R9A07G054_SSI2_PCLK2>,
+ <&cpg CPG_MOD R9A07G054_SSI2_PCLK_SFR>,
+ <&audio_clk1>, <&audio_clk2>;
+@@ -238,9 +234,8 @@
+ reg = <0 0x1004a800 0 0x400>;
+ interrupts = <GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 339 IRQ_TYPE_EDGE_RISING>,
+- <GIC_SPI 340 IRQ_TYPE_EDGE_RISING>,
+- <GIC_SPI 341 IRQ_TYPE_EDGE_RISING>;
+- interrupt-names = "int_req", "dma_rx", "dma_tx", "dma_rt";
++ <GIC_SPI 340 IRQ_TYPE_EDGE_RISING>;
++ interrupt-names = "int_req", "dma_rx", "dma_tx";
+ clocks = <&cpg CPG_MOD R9A07G054_SSI3_PCLK2>,
+ <&cpg CPG_MOD R9A07G054_SSI3_PCLK_SFR>,
+ <&audio_clk1>, <&audio_clk2>;
+diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
+index ae1ec58117c35..0bdc16b0d08f2 100644
+--- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
++++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
+@@ -461,7 +461,7 @@
+ <193>, <194>, <195>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+- ti,ngpio = <87>;
++ ti,ngpio = <92>;
+ ti,davinci-gpio-unbanked = <0>;
+ power-domains = <&k3_pds 77 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 77 0>;
+@@ -478,7 +478,7 @@
+ <183>, <184>, <185>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+- ti,ngpio = <88>;
++ ti,ngpio = <52>;
+ ti,davinci-gpio-unbanked = <0>;
+ power-domains = <&k3_pds 78 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 78 0>;
+diff --git a/arch/arm64/boot/dts/ti/k3-am625.dtsi b/arch/arm64/boot/dts/ti/k3-am625.dtsi
+index cea2cc7de5dd3..26d78562ceba7 100644
+--- a/arch/arm64/boot/dts/ti/k3-am625.dtsi
++++ b/arch/arm64/boot/dts/ti/k3-am625.dtsi
+@@ -147,7 +147,7 @@
+ L2_0: l2-cache0 {
+ compatible = "cache";
+ cache-level = <2>;
+- cache-size = <0x40000>;
++ cache-size = <0x80000>;
+ cache-line-size = <64>;
+ cache-sets = <512>;
+ };
+diff --git a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
+index 576dbce80ad83..b08a083d722d4 100644
+--- a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
++++ b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
+@@ -26,8 +26,9 @@
+
+ memory@80000000 {
+ device_type = "memory";
+- /* 2G RAM */
+- reg = <0x00000000 0x80000000 0x00000000 0x80000000>;
++ /* 4G RAM */
++ reg = <0x00000000 0x80000000 0x00000000 0x80000000>,
++ <0x00000008 0x80000000 0x00000000 0x80000000>;
+ };
+
+ reserved-memory {
+diff --git a/arch/arm64/boot/dts/ti/k3-am62a7.dtsi b/arch/arm64/boot/dts/ti/k3-am62a7.dtsi
+index 331d89fda29d0..f1ebaec404fbc 100644
+--- a/arch/arm64/boot/dts/ti/k3-am62a7.dtsi
++++ b/arch/arm64/boot/dts/ti/k3-am62a7.dtsi
+@@ -96,7 +96,7 @@
+ L2_0: l2-cache0 {
+ compatible = "cache";
+ cache-level = <2>;
+- cache-size = <0x40000>;
++ cache-size = <0x80000>;
+ cache-line-size = <64>;
+ cache-sets = <512>;
+ };
+diff --git a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
+index c935622f01028..bfa296dce3a31 100644
+--- a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
++++ b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
+@@ -1180,7 +1180,6 @@
+ ti,itap-del-sel-mmc-hs = <0xa>;
+ ti,itap-del-sel-ddr52 = <0x3>;
+ ti,trm-icp = <0x8>;
+- ti,strobe-sel = <0x77>;
+ dma-coherent;
+ };
+
+diff --git a/arch/arm64/crypto/aes-neonbs-core.S b/arch/arm64/crypto/aes-neonbs-core.S
+index 7278a37c2d5cd..baf450717b24b 100644
+--- a/arch/arm64/crypto/aes-neonbs-core.S
++++ b/arch/arm64/crypto/aes-neonbs-core.S
+@@ -15,6 +15,7 @@
+ */
+
+ #include <linux/linkage.h>
++#include <linux/cfi_types.h>
+ #include <asm/assembler.h>
+
+ .text
+@@ -620,12 +621,12 @@ SYM_FUNC_END(aesbs_decrypt8)
+ .endm
+
+ .align 4
+-SYM_FUNC_START(aesbs_ecb_encrypt)
++SYM_TYPED_FUNC_START(aesbs_ecb_encrypt)
+ __ecb_crypt aesbs_encrypt8, v0, v1, v4, v6, v3, v7, v2, v5
+ SYM_FUNC_END(aesbs_ecb_encrypt)
+
+ .align 4
+-SYM_FUNC_START(aesbs_ecb_decrypt)
++SYM_TYPED_FUNC_START(aesbs_ecb_decrypt)
+ __ecb_crypt aesbs_decrypt8, v0, v1, v6, v4, v2, v7, v3, v5
+ SYM_FUNC_END(aesbs_ecb_decrypt)
+
+@@ -799,11 +800,11 @@ SYM_FUNC_END(__xts_crypt8)
+ ret
+ .endm
+
+-SYM_FUNC_START(aesbs_xts_encrypt)
++SYM_TYPED_FUNC_START(aesbs_xts_encrypt)
+ __xts_crypt aesbs_encrypt8, v0, v1, v4, v6, v3, v7, v2, v5
+ SYM_FUNC_END(aesbs_xts_encrypt)
+
+-SYM_FUNC_START(aesbs_xts_decrypt)
++SYM_TYPED_FUNC_START(aesbs_xts_decrypt)
+ __xts_crypt aesbs_decrypt8, v0, v1, v6, v4, v2, v7, v3, v5
+ SYM_FUNC_END(aesbs_xts_decrypt)
+
+diff --git a/arch/arm64/include/asm/debug-monitors.h b/arch/arm64/include/asm/debug-monitors.h
+index 7b7e05c02691c..13d437bcbf58c 100644
+--- a/arch/arm64/include/asm/debug-monitors.h
++++ b/arch/arm64/include/asm/debug-monitors.h
+@@ -104,6 +104,7 @@ void user_regs_reset_single_step(struct user_pt_regs *regs,
+ void kernel_enable_single_step(struct pt_regs *regs);
+ void kernel_disable_single_step(void);
+ int kernel_active_single_step(void);
++void kernel_rewind_single_step(struct pt_regs *regs);
+
+ #ifdef CONFIG_HAVE_HW_BREAKPOINT
+ int reinstall_suspended_bps(struct pt_regs *regs);
+diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
+index 307a840b78865..f134c300cdcf1 100644
+--- a/arch/arm64/include/asm/kvm_host.h
++++ b/arch/arm64/include/asm/kvm_host.h
+@@ -191,6 +191,9 @@ struct kvm_arch {
+ /* Mandated version of PSCI */
+ u32 psci_version;
+
++ /* Protects VM-scoped configuration data */
++ struct mutex config_lock;
++
+ /*
+ * If we encounter a data abort without valid instruction syndrome
+ * information, report this to user space. User space can (and
+@@ -482,6 +485,7 @@ struct kvm_vcpu_arch {
+
+ /* vcpu power state */
+ struct kvm_mp_state mp_state;
++ spinlock_t mp_state_lock;
+
+ /* Cache some mmu pages needed inside spinlock regions */
+ struct kvm_mmu_memory_cache mmu_page_cache;
+diff --git a/arch/arm64/include/asm/scs.h b/arch/arm64/include/asm/scs.h
+index ff7da1268a52a..13df982a08080 100644
+--- a/arch/arm64/include/asm/scs.h
++++ b/arch/arm64/include/asm/scs.h
+@@ -10,15 +10,16 @@
+ #ifdef CONFIG_SHADOW_CALL_STACK
+ scs_sp .req x18
+
+- .macro scs_load tsk
+- ldr scs_sp, [\tsk, #TSK_TI_SCS_SP]
++ .macro scs_load_current
++ get_current_task scs_sp
++ ldr scs_sp, [scs_sp, #TSK_TI_SCS_SP]
+ .endm
+
+ .macro scs_save tsk
+ str scs_sp, [\tsk, #TSK_TI_SCS_SP]
+ .endm
+ #else
+- .macro scs_load tsk
++ .macro scs_load_current
+ .endm
+
+ .macro scs_save tsk
+diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c
+index 3da09778267ec..64f2ecbdfe5c2 100644
+--- a/arch/arm64/kernel/debug-monitors.c
++++ b/arch/arm64/kernel/debug-monitors.c
+@@ -438,6 +438,11 @@ int kernel_active_single_step(void)
+ }
+ NOKPROBE_SYMBOL(kernel_active_single_step);
+
++void kernel_rewind_single_step(struct pt_regs *regs)
++{
++ set_regs_spsr_ss(regs);
++}
++
+ /* ptrace API */
+ void user_enable_single_step(struct task_struct *task)
+ {
+diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
+index 11cb99c4d2987..80d763e165fc5 100644
+--- a/arch/arm64/kernel/entry.S
++++ b/arch/arm64/kernel/entry.S
+@@ -275,7 +275,7 @@ alternative_if ARM64_HAS_ADDRESS_AUTH
+ alternative_else_nop_endif
+ 1:
+
+- scs_load tsk
++ scs_load_current
+ .else
+ add x21, sp, #PT_REGS_SIZE
+ get_current_task tsk
+@@ -848,7 +848,7 @@ SYM_FUNC_START(cpu_switch_to)
+ msr sp_el0, x1
+ ptrauth_keys_install_kernel x1, x8, x9, x10
+ scs_save x0
+- scs_load x1
++ scs_load_current
+ ret
+ SYM_FUNC_END(cpu_switch_to)
+ NOKPROBE(cpu_switch_to)
+@@ -876,19 +876,19 @@ NOKPROBE(ret_from_fork)
+ */
+ SYM_FUNC_START(call_on_irq_stack)
+ #ifdef CONFIG_SHADOW_CALL_STACK
+- stp scs_sp, xzr, [sp, #-16]!
++ get_current_task x16
++ scs_save x16
+ ldr_this_cpu scs_sp, irq_shadow_call_stack_ptr, x17
+ #endif
++
+ /* Create a frame record to save our LR and SP (implicit in FP) */
+ stp x29, x30, [sp, #-16]!
+ mov x29, sp
+
+ ldr_this_cpu x16, irq_stack_ptr, x17
+- mov x15, #IRQ_STACK_SIZE
+- add x16, x16, x15
+
+ /* Move to the new stack and call the function there */
+- mov sp, x16
++ add sp, x16, #IRQ_STACK_SIZE
+ blr x1
+
+ /*
+@@ -897,9 +897,7 @@ SYM_FUNC_START(call_on_irq_stack)
+ */
+ mov sp, x29
+ ldp x29, x30, [sp], #16
+-#ifdef CONFIG_SHADOW_CALL_STACK
+- ldp scs_sp, xzr, [sp], #16
+-#endif
++ scs_load_current
+ ret
+ SYM_FUNC_END(call_on_irq_stack)
+ NOKPROBE(call_on_irq_stack)
+diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
+index 952e17bd1c0b4..b9c1a506798ea 100644
+--- a/arch/arm64/kernel/head.S
++++ b/arch/arm64/kernel/head.S
+@@ -404,7 +404,7 @@ SYM_FUNC_END(create_kernel_mapping)
+ stp xzr, xzr, [sp, #S_STACKFRAME]
+ add x29, sp, #S_STACKFRAME
+
+- scs_load \tsk
++ scs_load_current
+
+ adr_l \tmp1, __per_cpu_offset
+ ldr w\tmp2, [\tsk, #TSK_TI_CPU]
+diff --git a/arch/arm64/kernel/kgdb.c b/arch/arm64/kernel/kgdb.c
+index cda9c1e9864f7..4e1f983df3d1c 100644
+--- a/arch/arm64/kernel/kgdb.c
++++ b/arch/arm64/kernel/kgdb.c
+@@ -224,6 +224,8 @@ int kgdb_arch_handle_exception(int exception_vector, int signo,
+ */
+ if (!kernel_active_single_step())
+ kernel_enable_single_step(linux_regs);
++ else
++ kernel_rewind_single_step(linux_regs);
+ err = 0;
+ break;
+ default:
+diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
+index e57f8ae093875..f092c3672afcd 100644
+--- a/arch/arm64/kvm/arm.c
++++ b/arch/arm64/kvm/arm.c
+@@ -138,6 +138,16 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
+ {
+ int ret;
+
++ mutex_init(&kvm->arch.config_lock);
++
++#ifdef CONFIG_LOCKDEP
++ /* Clue in lockdep that the config_lock must be taken inside kvm->lock */
++ mutex_lock(&kvm->lock);
++ mutex_lock(&kvm->arch.config_lock);
++ mutex_unlock(&kvm->arch.config_lock);
++ mutex_unlock(&kvm->lock);
++#endif
++
+ ret = kvm_share_hyp(kvm, kvm + 1);
+ if (ret)
+ return ret;
+@@ -336,6 +346,16 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
+ {
+ int err;
+
++ spin_lock_init(&vcpu->arch.mp_state_lock);
++
++#ifdef CONFIG_LOCKDEP
++ /* Inform lockdep that the config_lock is acquired after vcpu->mutex */
++ mutex_lock(&vcpu->mutex);
++ mutex_lock(&vcpu->kvm->arch.config_lock);
++ mutex_unlock(&vcpu->kvm->arch.config_lock);
++ mutex_unlock(&vcpu->mutex);
++#endif
++
+ /* Force users to call KVM_ARM_VCPU_INIT */
+ vcpu->arch.target = -1;
+ bitmap_zero(vcpu->arch.features, KVM_VCPU_MAX_FEATURES);
+@@ -453,34 +473,41 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
+ vcpu->cpu = -1;
+ }
+
+-void kvm_arm_vcpu_power_off(struct kvm_vcpu *vcpu)
++static void __kvm_arm_vcpu_power_off(struct kvm_vcpu *vcpu)
+ {
+- vcpu->arch.mp_state.mp_state = KVM_MP_STATE_STOPPED;
++ WRITE_ONCE(vcpu->arch.mp_state.mp_state, KVM_MP_STATE_STOPPED);
+ kvm_make_request(KVM_REQ_SLEEP, vcpu);
+ kvm_vcpu_kick(vcpu);
+ }
+
++void kvm_arm_vcpu_power_off(struct kvm_vcpu *vcpu)
++{
++ spin_lock(&vcpu->arch.mp_state_lock);
++ __kvm_arm_vcpu_power_off(vcpu);
++ spin_unlock(&vcpu->arch.mp_state_lock);
++}
++
+ bool kvm_arm_vcpu_stopped(struct kvm_vcpu *vcpu)
+ {
+- return vcpu->arch.mp_state.mp_state == KVM_MP_STATE_STOPPED;
++ return READ_ONCE(vcpu->arch.mp_state.mp_state) == KVM_MP_STATE_STOPPED;
+ }
+
+ static void kvm_arm_vcpu_suspend(struct kvm_vcpu *vcpu)
+ {
+- vcpu->arch.mp_state.mp_state = KVM_MP_STATE_SUSPENDED;
++ WRITE_ONCE(vcpu->arch.mp_state.mp_state, KVM_MP_STATE_SUSPENDED);
+ kvm_make_request(KVM_REQ_SUSPEND, vcpu);
+ kvm_vcpu_kick(vcpu);
+ }
+
+ static bool kvm_arm_vcpu_suspended(struct kvm_vcpu *vcpu)
+ {
+- return vcpu->arch.mp_state.mp_state == KVM_MP_STATE_SUSPENDED;
++ return READ_ONCE(vcpu->arch.mp_state.mp_state) == KVM_MP_STATE_SUSPENDED;
+ }
+
+ int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
+ struct kvm_mp_state *mp_state)
+ {
+- *mp_state = vcpu->arch.mp_state;
++ *mp_state = READ_ONCE(vcpu->arch.mp_state);
+
+ return 0;
+ }
+@@ -490,12 +517,14 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
+ {
+ int ret = 0;
+
++ spin_lock(&vcpu->arch.mp_state_lock);
++
+ switch (mp_state->mp_state) {
+ case KVM_MP_STATE_RUNNABLE:
+- vcpu->arch.mp_state = *mp_state;
++ WRITE_ONCE(vcpu->arch.mp_state, *mp_state);
+ break;
+ case KVM_MP_STATE_STOPPED:
+- kvm_arm_vcpu_power_off(vcpu);
++ __kvm_arm_vcpu_power_off(vcpu);
+ break;
+ case KVM_MP_STATE_SUSPENDED:
+ kvm_arm_vcpu_suspend(vcpu);
+@@ -504,6 +533,8 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
+ ret = -EINVAL;
+ }
+
++ spin_unlock(&vcpu->arch.mp_state_lock);
++
+ return ret;
+ }
+
+@@ -603,9 +634,9 @@ int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)
+ if (kvm_vm_is_protected(kvm))
+ kvm_call_hyp_nvhe(__pkvm_vcpu_init_traps, vcpu);
+
+- mutex_lock(&kvm->lock);
++ mutex_lock(&kvm->arch.config_lock);
+ set_bit(KVM_ARCH_FLAG_HAS_RAN_ONCE, &kvm->arch.flags);
+- mutex_unlock(&kvm->lock);
++ mutex_unlock(&kvm->arch.config_lock);
+
+ return ret;
+ }
+@@ -1223,7 +1254,7 @@ static int kvm_arch_vcpu_ioctl_vcpu_init(struct kvm_vcpu *vcpu,
+ if (test_bit(KVM_ARM_VCPU_POWER_OFF, vcpu->arch.features))
+ kvm_arm_vcpu_power_off(vcpu);
+ else
+- vcpu->arch.mp_state.mp_state = KVM_MP_STATE_RUNNABLE;
++ WRITE_ONCE(vcpu->arch.mp_state.mp_state, KVM_MP_STATE_RUNNABLE);
+
+ return 0;
+ }
+diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
+index cf4c495a43213..a8fe8e1bbaddf 100644
+--- a/arch/arm64/kvm/guest.c
++++ b/arch/arm64/kvm/guest.c
+@@ -951,7 +951,9 @@ int kvm_arm_vcpu_arch_set_attr(struct kvm_vcpu *vcpu,
+
+ switch (attr->group) {
+ case KVM_ARM_VCPU_PMU_V3_CTRL:
++ mutex_lock(&vcpu->kvm->arch.config_lock);
+ ret = kvm_arm_pmu_v3_set_attr(vcpu, attr);
++ mutex_unlock(&vcpu->kvm->arch.config_lock);
+ break;
+ case KVM_ARM_VCPU_TIMER_CTRL:
+ ret = kvm_arm_timer_set_attr(vcpu, attr);
+diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c
+index 950e35b993d2b..1f5beebf62174 100644
+--- a/arch/arm64/kvm/hypercalls.c
++++ b/arch/arm64/kvm/hypercalls.c
+@@ -377,7 +377,7 @@ static int kvm_arm_set_fw_reg_bmap(struct kvm_vcpu *vcpu, u64 reg_id, u64 val)
+ if (val & ~fw_reg_features)
+ return -EINVAL;
+
+- mutex_lock(&kvm->lock);
++ mutex_lock(&kvm->arch.config_lock);
+
+ if (test_bit(KVM_ARCH_FLAG_HAS_RAN_ONCE, &kvm->arch.flags) &&
+ val != *fw_reg_bmap) {
+@@ -387,7 +387,7 @@ static int kvm_arm_set_fw_reg_bmap(struct kvm_vcpu *vcpu, u64 reg_id, u64 val)
+
+ WRITE_ONCE(*fw_reg_bmap, val);
+ out:
+- mutex_unlock(&kvm->lock);
++ mutex_unlock(&kvm->arch.config_lock);
+ return ret;
+ }
+
+diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
+index 5eca0cdd961df..99e990a472a57 100644
+--- a/arch/arm64/kvm/pmu-emul.c
++++ b/arch/arm64/kvm/pmu-emul.c
+@@ -876,7 +876,7 @@ static int kvm_arm_pmu_v3_set_pmu(struct kvm_vcpu *vcpu, int pmu_id)
+ struct arm_pmu *arm_pmu;
+ int ret = -ENXIO;
+
+- mutex_lock(&kvm->lock);
++ lockdep_assert_held(&kvm->arch.config_lock);
+ mutex_lock(&arm_pmus_lock);
+
+ list_for_each_entry(entry, &arm_pmus, entry) {
+@@ -896,7 +896,6 @@ static int kvm_arm_pmu_v3_set_pmu(struct kvm_vcpu *vcpu, int pmu_id)
+ }
+
+ mutex_unlock(&arm_pmus_lock);
+- mutex_unlock(&kvm->lock);
+ return ret;
+ }
+
+@@ -904,22 +903,20 @@ int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
+ {
+ struct kvm *kvm = vcpu->kvm;
+
++ lockdep_assert_held(&kvm->arch.config_lock);
++
+ if (!kvm_vcpu_has_pmu(vcpu))
+ return -ENODEV;
+
+ if (vcpu->arch.pmu.created)
+ return -EBUSY;
+
+- mutex_lock(&kvm->lock);
+ if (!kvm->arch.arm_pmu) {
+ /* No PMU set, get the default one */
+ kvm->arch.arm_pmu = kvm_pmu_probe_armpmu();
+- if (!kvm->arch.arm_pmu) {
+- mutex_unlock(&kvm->lock);
++ if (!kvm->arch.arm_pmu)
+ return -ENODEV;
+- }
+ }
+- mutex_unlock(&kvm->lock);
+
+ switch (attr->attr) {
+ case KVM_ARM_VCPU_PMU_V3_IRQ: {
+@@ -963,19 +960,13 @@ int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
+ filter.action != KVM_PMU_EVENT_DENY))
+ return -EINVAL;
+
+- mutex_lock(&kvm->lock);
+-
+- if (test_bit(KVM_ARCH_FLAG_HAS_RAN_ONCE, &kvm->arch.flags)) {
+- mutex_unlock(&kvm->lock);
++ if (test_bit(KVM_ARCH_FLAG_HAS_RAN_ONCE, &kvm->arch.flags))
+ return -EBUSY;
+- }
+
+ if (!kvm->arch.pmu_filter) {
+ kvm->arch.pmu_filter = bitmap_alloc(nr_events, GFP_KERNEL_ACCOUNT);
+- if (!kvm->arch.pmu_filter) {
+- mutex_unlock(&kvm->lock);
++ if (!kvm->arch.pmu_filter)
+ return -ENOMEM;
+- }
+
+ /*
+ * The default depends on the first applied filter.
+@@ -994,8 +985,6 @@ int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
+ else
+ bitmap_clear(kvm->arch.pmu_filter, filter.base_event, filter.nevents);
+
+- mutex_unlock(&kvm->lock);
+-
+ return 0;
+ }
+ case KVM_ARM_VCPU_PMU_V3_SET_PMU: {
+diff --git a/arch/arm64/kvm/psci.c b/arch/arm64/kvm/psci.c
+index 7fbc4c1b9df04..5767e6baa61a2 100644
+--- a/arch/arm64/kvm/psci.c
++++ b/arch/arm64/kvm/psci.c
+@@ -62,6 +62,7 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
+ struct vcpu_reset_state *reset_state;
+ struct kvm *kvm = source_vcpu->kvm;
+ struct kvm_vcpu *vcpu = NULL;
++ int ret = PSCI_RET_SUCCESS;
+ unsigned long cpu_id;
+
+ cpu_id = smccc_get_arg1(source_vcpu);
+@@ -76,11 +77,15 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
+ */
+ if (!vcpu)
+ return PSCI_RET_INVALID_PARAMS;
++
++ spin_lock(&vcpu->arch.mp_state_lock);
+ if (!kvm_arm_vcpu_stopped(vcpu)) {
+ if (kvm_psci_version(source_vcpu) != KVM_ARM_PSCI_0_1)
+- return PSCI_RET_ALREADY_ON;
++ ret = PSCI_RET_ALREADY_ON;
+ else
+- return PSCI_RET_INVALID_PARAMS;
++ ret = PSCI_RET_INVALID_PARAMS;
++
++ goto out_unlock;
+ }
+
+ reset_state = &vcpu->arch.reset_state;
+@@ -96,7 +101,7 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
+ */
+ reset_state->r0 = smccc_get_arg3(source_vcpu);
+
+- WRITE_ONCE(reset_state->reset, true);
++ reset_state->reset = true;
+ kvm_make_request(KVM_REQ_VCPU_RESET, vcpu);
+
+ /*
+@@ -108,7 +113,9 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
+ vcpu->arch.mp_state.mp_state = KVM_MP_STATE_RUNNABLE;
+ kvm_vcpu_wake_up(vcpu);
+
+- return PSCI_RET_SUCCESS;
++out_unlock:
++ spin_unlock(&vcpu->arch.mp_state_lock);
++ return ret;
+ }
+
+ static unsigned long kvm_psci_vcpu_affinity_info(struct kvm_vcpu *vcpu)
+@@ -168,8 +175,11 @@ static void kvm_prepare_system_event(struct kvm_vcpu *vcpu, u32 type, u64 flags)
+ * after this call is handled and before the VCPUs have been
+ * re-initialized.
+ */
+- kvm_for_each_vcpu(i, tmp, vcpu->kvm)
+- tmp->arch.mp_state.mp_state = KVM_MP_STATE_STOPPED;
++ kvm_for_each_vcpu(i, tmp, vcpu->kvm) {
++ spin_lock(&tmp->arch.mp_state_lock);
++ WRITE_ONCE(tmp->arch.mp_state.mp_state, KVM_MP_STATE_STOPPED);
++ spin_unlock(&tmp->arch.mp_state_lock);
++ }
+ kvm_make_all_cpus_request(vcpu->kvm, KVM_REQ_SLEEP);
+
+ memset(&vcpu->run->system_event, 0, sizeof(vcpu->run->system_event));
+@@ -229,7 +239,6 @@ static unsigned long kvm_psci_check_allowed_function(struct kvm_vcpu *vcpu, u32
+
+ static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
+ {
+- struct kvm *kvm = vcpu->kvm;
+ u32 psci_fn = smccc_get_function(vcpu);
+ unsigned long val;
+ int ret = 1;
+@@ -254,9 +263,7 @@ static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
+ kvm_psci_narrow_to_32bit(vcpu);
+ fallthrough;
+ case PSCI_0_2_FN64_CPU_ON:
+- mutex_lock(&kvm->lock);
+ val = kvm_psci_vcpu_on(vcpu);
+- mutex_unlock(&kvm->lock);
+ break;
+ case PSCI_0_2_FN_AFFINITY_INFO:
+ kvm_psci_narrow_to_32bit(vcpu);
+@@ -395,7 +402,6 @@ static int kvm_psci_1_x_call(struct kvm_vcpu *vcpu, u32 minor)
+
+ static int kvm_psci_0_1_call(struct kvm_vcpu *vcpu)
+ {
+- struct kvm *kvm = vcpu->kvm;
+ u32 psci_fn = smccc_get_function(vcpu);
+ unsigned long val;
+
+@@ -405,9 +411,7 @@ static int kvm_psci_0_1_call(struct kvm_vcpu *vcpu)
+ val = PSCI_RET_SUCCESS;
+ break;
+ case KVM_PSCI_FN_CPU_ON:
+- mutex_lock(&kvm->lock);
+ val = kvm_psci_vcpu_on(vcpu);
+- mutex_unlock(&kvm->lock);
+ break;
+ default:
+ val = PSCI_RET_NOT_SUPPORTED;
+diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
+index e0267f672b8ab..8c346b3e41e0a 100644
+--- a/arch/arm64/kvm/reset.c
++++ b/arch/arm64/kvm/reset.c
+@@ -200,7 +200,7 @@ static int kvm_set_vm_width(struct kvm_vcpu *vcpu)
+
+ is32bit = vcpu_has_feature(vcpu, KVM_ARM_VCPU_EL1_32BIT);
+
+- lockdep_assert_held(&kvm->lock);
++ lockdep_assert_held(&kvm->arch.config_lock);
+
+ if (test_bit(KVM_ARCH_FLAG_REG_WIDTH_CONFIGURED, &kvm->arch.flags)) {
+ /*
+@@ -253,17 +253,18 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
+ bool loaded;
+ u32 pstate;
+
+- mutex_lock(&vcpu->kvm->lock);
++ mutex_lock(&vcpu->kvm->arch.config_lock);
+ ret = kvm_set_vm_width(vcpu);
+- if (!ret) {
+- reset_state = vcpu->arch.reset_state;
+- WRITE_ONCE(vcpu->arch.reset_state.reset, false);
+- }
+- mutex_unlock(&vcpu->kvm->lock);
++ mutex_unlock(&vcpu->kvm->arch.config_lock);
+
+ if (ret)
+ return ret;
+
++ spin_lock(&vcpu->arch.mp_state_lock);
++ reset_state = vcpu->arch.reset_state;
++ vcpu->arch.reset_state.reset = false;
++ spin_unlock(&vcpu->arch.mp_state_lock);
++
+ /* Reset PMU outside of the non-preemptible section */
+ kvm_pmu_vcpu_reset(vcpu);
+
+diff --git a/arch/arm64/kvm/vgic/vgic-debug.c b/arch/arm64/kvm/vgic/vgic-debug.c
+index 78cde687383ca..07aa0437125a6 100644
+--- a/arch/arm64/kvm/vgic/vgic-debug.c
++++ b/arch/arm64/kvm/vgic/vgic-debug.c
+@@ -85,7 +85,7 @@ static void *vgic_debug_start(struct seq_file *s, loff_t *pos)
+ struct kvm *kvm = s->private;
+ struct vgic_state_iter *iter;
+
+- mutex_lock(&kvm->lock);
++ mutex_lock(&kvm->arch.config_lock);
+ iter = kvm->arch.vgic.iter;
+ if (iter) {
+ iter = ERR_PTR(-EBUSY);
+@@ -104,7 +104,7 @@ static void *vgic_debug_start(struct seq_file *s, loff_t *pos)
+ if (end_of_vgic(iter))
+ iter = NULL;
+ out:
+- mutex_unlock(&kvm->lock);
++ mutex_unlock(&kvm->arch.config_lock);
+ return iter;
+ }
+
+@@ -132,12 +132,12 @@ static void vgic_debug_stop(struct seq_file *s, void *v)
+ if (IS_ERR(v))
+ return;
+
+- mutex_lock(&kvm->lock);
++ mutex_lock(&kvm->arch.config_lock);
+ iter = kvm->arch.vgic.iter;
+ kfree(iter->lpi_array);
+ kfree(iter);
+ kvm->arch.vgic.iter = NULL;
+- mutex_unlock(&kvm->lock);
++ mutex_unlock(&kvm->arch.config_lock);
+ }
+
+ static void print_dist_state(struct seq_file *s, struct vgic_dist *dist)
+diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c
+index f6d4f4052555c..8c1d2d7128db6 100644
+--- a/arch/arm64/kvm/vgic/vgic-init.c
++++ b/arch/arm64/kvm/vgic/vgic-init.c
+@@ -74,9 +74,6 @@ int kvm_vgic_create(struct kvm *kvm, u32 type)
+ unsigned long i;
+ int ret;
+
+- if (irqchip_in_kernel(kvm))
+- return -EEXIST;
+-
+ /*
+ * This function is also called by the KVM_CREATE_IRQCHIP handler,
+ * which had no chance yet to check the availability of the GICv2
+@@ -87,10 +84,20 @@ int kvm_vgic_create(struct kvm *kvm, u32 type)
+ !kvm_vgic_global_state.can_emulate_gicv2)
+ return -ENODEV;
+
++ /* Must be held to avoid race with vCPU creation */
++ lockdep_assert_held(&kvm->lock);
++
+ ret = -EBUSY;
+ if (!lock_all_vcpus(kvm))
+ return ret;
+
++ mutex_lock(&kvm->arch.config_lock);
++
++ if (irqchip_in_kernel(kvm)) {
++ ret = -EEXIST;
++ goto out_unlock;
++ }
++
+ kvm_for_each_vcpu(i, vcpu, kvm) {
+ if (vcpu_has_run_once(vcpu))
+ goto out_unlock;
+@@ -118,6 +125,7 @@ int kvm_vgic_create(struct kvm *kvm, u32 type)
+ INIT_LIST_HEAD(&kvm->arch.vgic.rd_regions);
+
+ out_unlock:
++ mutex_unlock(&kvm->arch.config_lock);
+ unlock_all_vcpus(kvm);
+ return ret;
+ }
+@@ -227,9 +235,9 @@ int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu)
+ * KVM io device for the redistributor that belongs to this VCPU.
+ */
+ if (dist->vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3) {
+- mutex_lock(&vcpu->kvm->lock);
++ mutex_lock(&vcpu->kvm->arch.config_lock);
+ ret = vgic_register_redist_iodev(vcpu);
+- mutex_unlock(&vcpu->kvm->lock);
++ mutex_unlock(&vcpu->kvm->arch.config_lock);
+ }
+ return ret;
+ }
+@@ -250,7 +258,6 @@ static void kvm_vgic_vcpu_enable(struct kvm_vcpu *vcpu)
+ * The function is generally called when nr_spis has been explicitly set
+ * by the guest through the KVM DEVICE API. If not nr_spis is set to 256.
+ * vgic_initialized() returns true when this function has succeeded.
+- * Must be called with kvm->lock held!
+ */
+ int vgic_init(struct kvm *kvm)
+ {
+@@ -259,6 +266,8 @@ int vgic_init(struct kvm *kvm)
+ int ret = 0, i;
+ unsigned long idx;
+
++ lockdep_assert_held(&kvm->arch.config_lock);
++
+ if (vgic_initialized(kvm))
+ return 0;
+
+@@ -373,12 +382,13 @@ void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu)
+ vgic_cpu->rd_iodev.base_addr = VGIC_ADDR_UNDEF;
+ }
+
+-/* To be called with kvm->lock held */
+ static void __kvm_vgic_destroy(struct kvm *kvm)
+ {
+ struct kvm_vcpu *vcpu;
+ unsigned long i;
+
++ lockdep_assert_held(&kvm->arch.config_lock);
++
+ vgic_debug_destroy(kvm);
+
+ kvm_for_each_vcpu(i, vcpu, kvm)
+@@ -389,9 +399,9 @@ static void __kvm_vgic_destroy(struct kvm *kvm)
+
+ void kvm_vgic_destroy(struct kvm *kvm)
+ {
+- mutex_lock(&kvm->lock);
++ mutex_lock(&kvm->arch.config_lock);
+ __kvm_vgic_destroy(kvm);
+- mutex_unlock(&kvm->lock);
++ mutex_unlock(&kvm->arch.config_lock);
+ }
+
+ /**
+@@ -414,9 +424,9 @@ int vgic_lazy_init(struct kvm *kvm)
+ if (kvm->arch.vgic.vgic_model != KVM_DEV_TYPE_ARM_VGIC_V2)
+ return -EBUSY;
+
+- mutex_lock(&kvm->lock);
++ mutex_lock(&kvm->arch.config_lock);
+ ret = vgic_init(kvm);
+- mutex_unlock(&kvm->lock);
++ mutex_unlock(&kvm->arch.config_lock);
+ }
+
+ return ret;
+@@ -441,7 +451,7 @@ int kvm_vgic_map_resources(struct kvm *kvm)
+ if (likely(vgic_ready(kvm)))
+ return 0;
+
+- mutex_lock(&kvm->lock);
++ mutex_lock(&kvm->arch.config_lock);
+ if (vgic_ready(kvm))
+ goto out;
+
+@@ -459,7 +469,7 @@ int kvm_vgic_map_resources(struct kvm *kvm)
+ dist->ready = true;
+
+ out:
+- mutex_unlock(&kvm->lock);
++ mutex_unlock(&kvm->arch.config_lock);
+ return ret;
+ }
+
+diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c
+index 2642e9ce28199..750e51e3779a3 100644
+--- a/arch/arm64/kvm/vgic/vgic-its.c
++++ b/arch/arm64/kvm/vgic/vgic-its.c
+@@ -1958,6 +1958,16 @@ static int vgic_its_create(struct kvm_device *dev, u32 type)
+ mutex_init(&its->its_lock);
+ mutex_init(&its->cmd_lock);
+
++ /* Yep, even more trickery for lock ordering... */
++#ifdef CONFIG_LOCKDEP
++ mutex_lock(&dev->kvm->arch.config_lock);
++ mutex_lock(&its->cmd_lock);
++ mutex_lock(&its->its_lock);
++ mutex_unlock(&its->its_lock);
++ mutex_unlock(&its->cmd_lock);
++ mutex_unlock(&dev->kvm->arch.config_lock);
++#endif
++
+ its->vgic_its_base = VGIC_ADDR_UNDEF;
+
+ INIT_LIST_HEAD(&its->device_list);
+@@ -2045,6 +2055,13 @@ static int vgic_its_attr_regs_access(struct kvm_device *dev,
+
+ mutex_lock(&dev->kvm->lock);
+
++ if (!lock_all_vcpus(dev->kvm)) {
++ mutex_unlock(&dev->kvm->lock);
++ return -EBUSY;
++ }
++
++ mutex_lock(&dev->kvm->arch.config_lock);
++
+ if (IS_VGIC_ADDR_UNDEF(its->vgic_its_base)) {
+ ret = -ENXIO;
+ goto out;
+@@ -2058,11 +2075,6 @@ static int vgic_its_attr_regs_access(struct kvm_device *dev,
+ goto out;
+ }
+
+- if (!lock_all_vcpus(dev->kvm)) {
+- ret = -EBUSY;
+- goto out;
+- }
+-
+ addr = its->vgic_its_base + offset;
+
+ len = region->access_flags & VGIC_ACCESS_64bit ? 8 : 4;
+@@ -2076,8 +2088,9 @@ static int vgic_its_attr_regs_access(struct kvm_device *dev,
+ } else {
+ *reg = region->its_read(dev->kvm, its, addr, len);
+ }
+- unlock_all_vcpus(dev->kvm);
+ out:
++ mutex_unlock(&dev->kvm->arch.config_lock);
++ unlock_all_vcpus(dev->kvm);
+ mutex_unlock(&dev->kvm->lock);
+ return ret;
+ }
+@@ -2749,14 +2762,15 @@ static int vgic_its_ctrl(struct kvm *kvm, struct vgic_its *its, u64 attr)
+ return 0;
+
+ mutex_lock(&kvm->lock);
+- mutex_lock(&its->its_lock);
+
+ if (!lock_all_vcpus(kvm)) {
+- mutex_unlock(&its->its_lock);
+ mutex_unlock(&kvm->lock);
+ return -EBUSY;
+ }
+
++ mutex_lock(&kvm->arch.config_lock);
++ mutex_lock(&its->its_lock);
++
+ switch (attr) {
+ case KVM_DEV_ARM_ITS_CTRL_RESET:
+ vgic_its_reset(kvm, its);
+@@ -2769,8 +2783,9 @@ static int vgic_its_ctrl(struct kvm *kvm, struct vgic_its *its, u64 attr)
+ break;
+ }
+
+- unlock_all_vcpus(kvm);
+ mutex_unlock(&its->its_lock);
++ mutex_unlock(&kvm->arch.config_lock);
++ unlock_all_vcpus(kvm);
+ mutex_unlock(&kvm->lock);
+ return ret;
+ }
+diff --git a/arch/arm64/kvm/vgic/vgic-kvm-device.c b/arch/arm64/kvm/vgic/vgic-kvm-device.c
+index edeac2380591f..07e727023deb7 100644
+--- a/arch/arm64/kvm/vgic/vgic-kvm-device.c
++++ b/arch/arm64/kvm/vgic/vgic-kvm-device.c
+@@ -46,7 +46,7 @@ int kvm_set_legacy_vgic_v2_addr(struct kvm *kvm, struct kvm_arm_device_addr *dev
+ struct vgic_dist *vgic = &kvm->arch.vgic;
+ int r;
+
+- mutex_lock(&kvm->lock);
++ mutex_lock(&kvm->arch.config_lock);
+ switch (FIELD_GET(KVM_ARM_DEVICE_TYPE_MASK, dev_addr->id)) {
+ case KVM_VGIC_V2_ADDR_TYPE_DIST:
+ r = vgic_check_type(kvm, KVM_DEV_TYPE_ARM_VGIC_V2);
+@@ -68,7 +68,7 @@ int kvm_set_legacy_vgic_v2_addr(struct kvm *kvm, struct kvm_arm_device_addr *dev
+ r = -ENODEV;
+ }
+
+- mutex_unlock(&kvm->lock);
++ mutex_unlock(&kvm->arch.config_lock);
+
+ return r;
+ }
+@@ -102,7 +102,7 @@ static int kvm_vgic_addr(struct kvm *kvm, struct kvm_device_attr *attr, bool wri
+ if (get_user(addr, uaddr))
+ return -EFAULT;
+
+- mutex_lock(&kvm->lock);
++ mutex_lock(&kvm->arch.config_lock);
+ switch (attr->attr) {
+ case KVM_VGIC_V2_ADDR_TYPE_DIST:
+ r = vgic_check_type(kvm, KVM_DEV_TYPE_ARM_VGIC_V2);
+@@ -191,7 +191,7 @@ static int kvm_vgic_addr(struct kvm *kvm, struct kvm_device_attr *attr, bool wri
+ }
+
+ out:
+- mutex_unlock(&kvm->lock);
++ mutex_unlock(&kvm->arch.config_lock);
+
+ if (!r && !write)
+ r = put_user(addr, uaddr);
+@@ -227,7 +227,7 @@ static int vgic_set_common_attr(struct kvm_device *dev,
+ (val & 31))
+ return -EINVAL;
+
+- mutex_lock(&dev->kvm->lock);
++ mutex_lock(&dev->kvm->arch.config_lock);
+
+ if (vgic_ready(dev->kvm) || dev->kvm->arch.vgic.nr_spis)
+ ret = -EBUSY;
+@@ -235,16 +235,16 @@ static int vgic_set_common_attr(struct kvm_device *dev,
+ dev->kvm->arch.vgic.nr_spis =
+ val - VGIC_NR_PRIVATE_IRQS;
+
+- mutex_unlock(&dev->kvm->lock);
++ mutex_unlock(&dev->kvm->arch.config_lock);
+
+ return ret;
+ }
+ case KVM_DEV_ARM_VGIC_GRP_CTRL: {
+ switch (attr->attr) {
+ case KVM_DEV_ARM_VGIC_CTRL_INIT:
+- mutex_lock(&dev->kvm->lock);
++ mutex_lock(&dev->kvm->arch.config_lock);
+ r = vgic_init(dev->kvm);
+- mutex_unlock(&dev->kvm->lock);
++ mutex_unlock(&dev->kvm->arch.config_lock);
+ return r;
+ case KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES:
+ /*
+@@ -260,7 +260,10 @@ static int vgic_set_common_attr(struct kvm_device *dev,
+ mutex_unlock(&dev->kvm->lock);
+ return -EBUSY;
+ }
++
++ mutex_lock(&dev->kvm->arch.config_lock);
+ r = vgic_v3_save_pending_tables(dev->kvm);
++ mutex_unlock(&dev->kvm->arch.config_lock);
+ unlock_all_vcpus(dev->kvm);
+ mutex_unlock(&dev->kvm->lock);
+ return r;
+@@ -411,15 +414,17 @@ static int vgic_v2_attr_regs_access(struct kvm_device *dev,
+
+ mutex_lock(&dev->kvm->lock);
+
++ if (!lock_all_vcpus(dev->kvm)) {
++ mutex_unlock(&dev->kvm->lock);
++ return -EBUSY;
++ }
++
++ mutex_lock(&dev->kvm->arch.config_lock);
++
+ ret = vgic_init(dev->kvm);
+ if (ret)
+ goto out;
+
+- if (!lock_all_vcpus(dev->kvm)) {
+- ret = -EBUSY;
+- goto out;
+- }
+-
+ switch (attr->group) {
+ case KVM_DEV_ARM_VGIC_GRP_CPU_REGS:
+ ret = vgic_v2_cpuif_uaccess(vcpu, is_write, addr, &val);
+@@ -432,8 +437,9 @@ static int vgic_v2_attr_regs_access(struct kvm_device *dev,
+ break;
+ }
+
+- unlock_all_vcpus(dev->kvm);
+ out:
++ mutex_unlock(&dev->kvm->arch.config_lock);
++ unlock_all_vcpus(dev->kvm);
+ mutex_unlock(&dev->kvm->lock);
+
+ if (!ret && !is_write)
+@@ -569,12 +575,14 @@ static int vgic_v3_attr_regs_access(struct kvm_device *dev,
+
+ mutex_lock(&dev->kvm->lock);
+
+- if (unlikely(!vgic_initialized(dev->kvm))) {
+- ret = -EBUSY;
+- goto out;
++ if (!lock_all_vcpus(dev->kvm)) {
++ mutex_unlock(&dev->kvm->lock);
++ return -EBUSY;
+ }
+
+- if (!lock_all_vcpus(dev->kvm)) {
++ mutex_lock(&dev->kvm->arch.config_lock);
++
++ if (unlikely(!vgic_initialized(dev->kvm))) {
+ ret = -EBUSY;
+ goto out;
+ }
+@@ -609,8 +617,9 @@ static int vgic_v3_attr_regs_access(struct kvm_device *dev,
+ break;
+ }
+
+- unlock_all_vcpus(dev->kvm);
+ out:
++ mutex_unlock(&dev->kvm->arch.config_lock);
++ unlock_all_vcpus(dev->kvm);
+ mutex_unlock(&dev->kvm->lock);
+
+ if (!ret && uaccess && !is_write) {
+diff --git a/arch/arm64/kvm/vgic/vgic-mmio-v3.c b/arch/arm64/kvm/vgic/vgic-mmio-v3.c
+index 91201f7430339..472b18ac92a24 100644
+--- a/arch/arm64/kvm/vgic/vgic-mmio-v3.c
++++ b/arch/arm64/kvm/vgic/vgic-mmio-v3.c
+@@ -111,7 +111,7 @@ static void vgic_mmio_write_v3_misc(struct kvm_vcpu *vcpu,
+ case GICD_CTLR: {
+ bool was_enabled, is_hwsgi;
+
+- mutex_lock(&vcpu->kvm->lock);
++ mutex_lock(&vcpu->kvm->arch.config_lock);
+
+ was_enabled = dist->enabled;
+ is_hwsgi = dist->nassgireq;
+@@ -139,7 +139,7 @@ static void vgic_mmio_write_v3_misc(struct kvm_vcpu *vcpu,
+ else if (!was_enabled && dist->enabled)
+ vgic_kick_vcpus(vcpu->kvm);
+
+- mutex_unlock(&vcpu->kvm->lock);
++ mutex_unlock(&vcpu->kvm->arch.config_lock);
+ break;
+ }
+ case GICD_TYPER:
+diff --git a/arch/arm64/kvm/vgic/vgic-mmio.c b/arch/arm64/kvm/vgic/vgic-mmio.c
+index b32d434c1d4a4..a95f99b93dd68 100644
+--- a/arch/arm64/kvm/vgic/vgic-mmio.c
++++ b/arch/arm64/kvm/vgic/vgic-mmio.c
+@@ -527,13 +527,13 @@ unsigned long vgic_mmio_read_active(struct kvm_vcpu *vcpu,
+ u32 intid = VGIC_ADDR_TO_INTID(addr, 1);
+ u32 val;
+
+- mutex_lock(&vcpu->kvm->lock);
++ mutex_lock(&vcpu->kvm->arch.config_lock);
+ vgic_access_active_prepare(vcpu, intid);
+
+ val = __vgic_mmio_read_active(vcpu, addr, len);
+
+ vgic_access_active_finish(vcpu, intid);
+- mutex_unlock(&vcpu->kvm->lock);
++ mutex_unlock(&vcpu->kvm->arch.config_lock);
+
+ return val;
+ }
+@@ -622,13 +622,13 @@ void vgic_mmio_write_cactive(struct kvm_vcpu *vcpu,
+ {
+ u32 intid = VGIC_ADDR_TO_INTID(addr, 1);
+
+- mutex_lock(&vcpu->kvm->lock);
++ mutex_lock(&vcpu->kvm->arch.config_lock);
+ vgic_access_active_prepare(vcpu, intid);
+
+ __vgic_mmio_write_cactive(vcpu, addr, len, val);
+
+ vgic_access_active_finish(vcpu, intid);
+- mutex_unlock(&vcpu->kvm->lock);
++ mutex_unlock(&vcpu->kvm->arch.config_lock);
+ }
+
+ int vgic_mmio_uaccess_write_cactive(struct kvm_vcpu *vcpu,
+@@ -659,13 +659,13 @@ void vgic_mmio_write_sactive(struct kvm_vcpu *vcpu,
+ {
+ u32 intid = VGIC_ADDR_TO_INTID(addr, 1);
+
+- mutex_lock(&vcpu->kvm->lock);
++ mutex_lock(&vcpu->kvm->arch.config_lock);
+ vgic_access_active_prepare(vcpu, intid);
+
+ __vgic_mmio_write_sactive(vcpu, addr, len, val);
+
+ vgic_access_active_finish(vcpu, intid);
+- mutex_unlock(&vcpu->kvm->lock);
++ mutex_unlock(&vcpu->kvm->arch.config_lock);
+ }
+
+ int vgic_mmio_uaccess_write_sactive(struct kvm_vcpu *vcpu,
+diff --git a/arch/arm64/kvm/vgic/vgic-v4.c b/arch/arm64/kvm/vgic/vgic-v4.c
+index a413718be92b8..3bb0034780605 100644
+--- a/arch/arm64/kvm/vgic/vgic-v4.c
++++ b/arch/arm64/kvm/vgic/vgic-v4.c
+@@ -232,9 +232,8 @@ int vgic_v4_request_vpe_irq(struct kvm_vcpu *vcpu, int irq)
+ * @kvm: Pointer to the VM being initialized
+ *
+ * We may be called each time a vITS is created, or when the
+- * vgic is initialized. This relies on kvm->lock to be
+- * held. In both cases, the number of vcpus should now be
+- * fixed.
++ * vgic is initialized. In both cases, the number of vcpus
++ * should now be fixed.
+ */
+ int vgic_v4_init(struct kvm *kvm)
+ {
+@@ -243,6 +242,8 @@ int vgic_v4_init(struct kvm *kvm)
+ int nr_vcpus, ret;
+ unsigned long i;
+
++ lockdep_assert_held(&kvm->arch.config_lock);
++
+ if (!kvm_vgic_global_state.has_gicv4)
+ return 0; /* Nothing to see here... move along. */
+
+@@ -309,14 +310,14 @@ int vgic_v4_init(struct kvm *kvm)
+ /**
+ * vgic_v4_teardown - Free the GICv4 data structures
+ * @kvm: Pointer to the VM being destroyed
+- *
+- * Relies on kvm->lock to be held.
+ */
+ void vgic_v4_teardown(struct kvm *kvm)
+ {
+ struct its_vm *its_vm = &kvm->arch.vgic.its_vm;
+ int i;
+
++ lockdep_assert_held(&kvm->arch.config_lock);
++
+ if (!its_vm->vpes)
+ return;
+
+diff --git a/arch/arm64/kvm/vgic/vgic.c b/arch/arm64/kvm/vgic/vgic.c
+index d97e6080b4217..0a005da83ae64 100644
+--- a/arch/arm64/kvm/vgic/vgic.c
++++ b/arch/arm64/kvm/vgic/vgic.c
+@@ -24,11 +24,13 @@ struct vgic_global kvm_vgic_global_state __ro_after_init = {
+ /*
+ * Locking order is always:
+ * kvm->lock (mutex)
+- * its->cmd_lock (mutex)
+- * its->its_lock (mutex)
+- * vgic_cpu->ap_list_lock must be taken with IRQs disabled
+- * kvm->lpi_list_lock must be taken with IRQs disabled
+- * vgic_irq->irq_lock must be taken with IRQs disabled
++ * vcpu->mutex (mutex)
++ * kvm->arch.config_lock (mutex)
++ * its->cmd_lock (mutex)
++ * its->its_lock (mutex)
++ * vgic_cpu->ap_list_lock must be taken with IRQs disabled
++ * kvm->lpi_list_lock must be taken with IRQs disabled
++ * vgic_irq->irq_lock must be taken with IRQs disabled
+ *
+ * As the ap_list_lock might be taken from the timer interrupt handler,
+ * we have to disable IRQs before taking this lock and everything lower
+diff --git a/arch/ia64/kernel/salinfo.c b/arch/ia64/kernel/salinfo.c
+index bd3ba276e69c3..03b632c568995 100644
+--- a/arch/ia64/kernel/salinfo.c
++++ b/arch/ia64/kernel/salinfo.c
+@@ -581,7 +581,7 @@ static int salinfo_cpu_pre_down(unsigned int cpu)
+ * 'data' contains an integer that corresponds to the feature we're
+ * testing
+ */
+-static int proc_salinfo_show(struct seq_file *m, void *v)
++static int __maybe_unused proc_salinfo_show(struct seq_file *m, void *v)
+ {
+ unsigned long data = (unsigned long)v;
+ seq_puts(m, (sal_platform_features & data) ? "1\n" : "0\n");
+diff --git a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c
+index 24901d8093015..1e9eaa107eb73 100644
+--- a/arch/ia64/mm/contig.c
++++ b/arch/ia64/mm/contig.c
+@@ -77,7 +77,7 @@ skip:
+ return __per_cpu_start + __per_cpu_offset[smp_processor_id()];
+ }
+
+-static inline void
++static inline __init void
+ alloc_per_cpu_data(void)
+ {
+ size_t size = PERCPU_PAGE_SIZE * num_possible_cpus();
+diff --git a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c
+index 380d2f3966c98..9e8960e499622 100644
+--- a/arch/ia64/mm/hugetlbpage.c
++++ b/arch/ia64/mm/hugetlbpage.c
+@@ -58,7 +58,7 @@ huge_pte_offset (struct mm_struct *mm, unsigned long addr, unsigned long sz)
+
+ pgd = pgd_offset(mm, taddr);
+ if (pgd_present(*pgd)) {
+- p4d = p4d_offset(pgd, addr);
++ p4d = p4d_offset(pgd, taddr);
+ if (p4d_present(*p4d)) {
+ pud = pud_offset(p4d, taddr);
+ if (pud_present(*pud)) {
+diff --git a/arch/mips/fw/lib/cmdline.c b/arch/mips/fw/lib/cmdline.c
+index f24cbb4a39b50..892765b742bbc 100644
+--- a/arch/mips/fw/lib/cmdline.c
++++ b/arch/mips/fw/lib/cmdline.c
+@@ -53,7 +53,7 @@ char *fw_getenv(char *envname)
+ {
+ char *result = NULL;
+
+- if (_fw_envp != NULL) {
++ if (_fw_envp != NULL && fw_envp(0) != NULL) {
+ /*
+ * Return a pointer to the given environment variable.
+ * YAMON uses "name", "value" pairs, while U-Boot uses
+diff --git a/arch/openrisc/kernel/entry.S b/arch/openrisc/kernel/entry.S
+index 54a87bba35caa..a130c4dac48d3 100644
+--- a/arch/openrisc/kernel/entry.S
++++ b/arch/openrisc/kernel/entry.S
+@@ -173,7 +173,6 @@ handler: ;\
+ l.sw PT_GPR28(r1),r28 ;\
+ l.sw PT_GPR29(r1),r29 ;\
+ /* r30 already save */ ;\
+-/* l.sw PT_GPR30(r1),r30*/ ;\
+ l.sw PT_GPR31(r1),r31 ;\
+ TRACE_IRQS_OFF_ENTRY ;\
+ /* Store -1 in orig_gpr11 for non-syscall exceptions */ ;\
+@@ -211,9 +210,8 @@ handler: ;\
+ l.sw PT_GPR27(r1),r27 ;\
+ l.sw PT_GPR28(r1),r28 ;\
+ l.sw PT_GPR29(r1),r29 ;\
+- /* r31 already saved */ ;\
+- l.sw PT_GPR30(r1),r30 ;\
+-/* l.sw PT_GPR31(r1),r31 */ ;\
++ /* r30 already saved */ ;\
++ l.sw PT_GPR31(r1),r31 ;\
+ /* Store -1 in orig_gpr11 for non-syscall exceptions */ ;\
+ l.addi r30,r0,-1 ;\
+ l.sw PT_ORIG_GPR11(r1),r30 ;\
+diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S
+index 9a0018f1f42cb..541370d145594 100644
+--- a/arch/parisc/kernel/pacache.S
++++ b/arch/parisc/kernel/pacache.S
+@@ -889,6 +889,7 @@ ENDPROC_CFI(flush_icache_page_asm)
+ ENTRY_CFI(flush_kernel_dcache_page_asm)
+ 88: ldil L%dcache_stride, %r1
+ ldw R%dcache_stride(%r1), %r23
++ depi_safe 0, 31,PAGE_SHIFT, %r26 /* Clear any offset bits */
+
+ #ifdef CONFIG_64BIT
+ depdi,z 1, 63-PAGE_SHIFT,1, %r25
+@@ -925,6 +926,7 @@ ENDPROC_CFI(flush_kernel_dcache_page_asm)
+ ENTRY_CFI(purge_kernel_dcache_page_asm)
+ 88: ldil L%dcache_stride, %r1
+ ldw R%dcache_stride(%r1), %r23
++ depi_safe 0, 31,PAGE_SHIFT, %r26 /* Clear any offset bits */
+
+ #ifdef CONFIG_64BIT
+ depdi,z 1, 63-PAGE_SHIFT,1, %r25
+diff --git a/arch/parisc/kernel/real2.S b/arch/parisc/kernel/real2.S
+index 4dc12c4c09809..509d18b8e0e65 100644
+--- a/arch/parisc/kernel/real2.S
++++ b/arch/parisc/kernel/real2.S
+@@ -235,9 +235,6 @@ ENTRY_CFI(real64_call_asm)
+ /* save fn */
+ copy %arg2, %r31
+
+- /* set up the new ap */
+- ldo 64(%arg1), %r29
+-
+ /* load up the arg registers from the saved arg area */
+ /* 32-bit calling convention passes first 4 args in registers */
+ ldd 0*REG_SZ(%arg1), %arg0 /* note overwriting arg0 */
+@@ -249,7 +246,9 @@ ENTRY_CFI(real64_call_asm)
+ ldd 7*REG_SZ(%arg1), %r19
+ ldd 1*REG_SZ(%arg1), %arg1 /* do this one last! */
+
++ /* set up real-mode stack and real-mode ap */
+ tophys_r1 %sp
++ ldo -16(%sp), %r29 /* Reference param save area */
+
+ b,l rfi_virt2real,%r2
+ nop
+diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
+index 295f76df13b55..13fad4f0a6d8f 100644
+--- a/arch/powerpc/boot/Makefile
++++ b/arch/powerpc/boot/Makefile
+@@ -34,6 +34,8 @@ endif
+
+ BOOTCFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
+ -fno-strict-aliasing -O2 -msoft-float -mno-altivec -mno-vsx \
++ $(call cc-option,-mno-prefixed) $(call cc-option,-mno-pcrel) \
++ $(call cc-option,-mno-mma) \
+ $(call cc-option,-mno-spe) $(call cc-option,-mspe=no) \
+ -pipe -fomit-frame-pointer -fno-builtin -fPIC -nostdinc \
+ $(LINUXINCLUDE)
+diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
+index 1e8b2e04e626a..8fda87af2fa5e 100644
+--- a/arch/powerpc/include/asm/reg.h
++++ b/arch/powerpc/include/asm/reg.h
+@@ -1310,6 +1310,11 @@
+ #define PVR_VER_E500MC 0x8023
+ #define PVR_VER_E5500 0x8024
+ #define PVR_VER_E6500 0x8040
++#define PVR_VER_7450 0x8000
++#define PVR_VER_7455 0x8001
++#define PVR_VER_7447 0x8002
++#define PVR_VER_7447A 0x8003
++#define PVR_VER_7448 0x8004
+
+ /*
+ * For the 8xx processors, all of them report the same PVR family for
+diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
+index deded51a79784..333a239a30d62 100644
+--- a/arch/powerpc/kernel/rtas.c
++++ b/arch/powerpc/kernel/rtas.c
+@@ -425,7 +425,7 @@ static char *__fetch_rtas_last_error(char *altbuf)
+ buf = kmalloc(RTAS_ERROR_LOG_MAX, GFP_ATOMIC);
+ }
+ if (buf)
+- memcpy(buf, rtas_err_buf, RTAS_ERROR_LOG_MAX);
++ memmove(buf, rtas_err_buf, RTAS_ERROR_LOG_MAX);
+ }
+
+ return buf;
+diff --git a/arch/powerpc/perf/mpc7450-pmu.c b/arch/powerpc/perf/mpc7450-pmu.c
+index 552d51a925d37..db451b9aac35e 100644
+--- a/arch/powerpc/perf/mpc7450-pmu.c
++++ b/arch/powerpc/perf/mpc7450-pmu.c
+@@ -417,9 +417,9 @@ struct power_pmu mpc7450_pmu = {
+
+ static int __init init_mpc7450_pmu(void)
+ {
+- unsigned int pvr = mfspr(SPRN_PVR);
+-
+- if (PVR_VER(pvr) != PVR_7450)
++ if (!pvr_version_is(PVR_VER_7450) && !pvr_version_is(PVR_VER_7455) &&
++ !pvr_version_is(PVR_VER_7447) && !pvr_version_is(PVR_VER_7447A) &&
++ !pvr_version_is(PVR_VER_7448))
+ return -ENODEV;
+
+ return register_power_pmu(&mpc7450_pmu);
+diff --git a/arch/powerpc/platforms/512x/clock-commonclk.c b/arch/powerpc/platforms/512x/clock-commonclk.c
+index 42abeba4f6983..079cb3627eacd 100644
+--- a/arch/powerpc/platforms/512x/clock-commonclk.c
++++ b/arch/powerpc/platforms/512x/clock-commonclk.c
+@@ -986,7 +986,7 @@ static void __init mpc5121_clk_provide_migration_support(void)
+
+ #define NODE_PREP do { \
+ of_address_to_resource(np, 0, &res); \
+- snprintf(devname, sizeof(devname), "%08x.%s", res.start, np->name); \
++ snprintf(devname, sizeof(devname), "%pa.%s", &res.start, np->name); \
+ } while (0)
+
+ #define NODE_CHK(clkname, clkitem, regnode, regflag) do { \
+diff --git a/arch/powerpc/platforms/embedded6xx/flipper-pic.c b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
+index 609bda2ad5dd2..4d9200bdba78c 100644
+--- a/arch/powerpc/platforms/embedded6xx/flipper-pic.c
++++ b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
+@@ -145,7 +145,7 @@ static struct irq_domain * __init flipper_pic_init(struct device_node *np)
+ }
+ io_base = ioremap(res.start, resource_size(&res));
+
+- pr_info("controller at 0x%08x mapped to 0x%p\n", res.start, io_base);
++ pr_info("controller at 0x%pa mapped to 0x%p\n", &res.start, io_base);
+
+ __flipper_quiesce(io_base);
+
+diff --git a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
+index 380b4285cce47..4d2d92de30afd 100644
+--- a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
++++ b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
+@@ -171,7 +171,7 @@ static struct irq_domain *__init hlwd_pic_init(struct device_node *np)
+ return NULL;
+ }
+
+- pr_info("controller at 0x%08x mapped to 0x%p\n", res.start, io_base);
++ pr_info("controller at 0x%pa mapped to 0x%p\n", &res.start, io_base);
+
+ __hlwd_quiesce(io_base);
+
+diff --git a/arch/powerpc/platforms/embedded6xx/wii.c b/arch/powerpc/platforms/embedded6xx/wii.c
+index f4e654a9d4ff6..219659f2ede06 100644
+--- a/arch/powerpc/platforms/embedded6xx/wii.c
++++ b/arch/powerpc/platforms/embedded6xx/wii.c
+@@ -74,8 +74,8 @@ static void __iomem *__init wii_ioremap_hw_regs(char *name, char *compatible)
+
+ hw_regs = ioremap(res.start, resource_size(&res));
+ if (hw_regs) {
+- pr_info("%s at 0x%08x mapped to 0x%p\n", name,
+- res.start, hw_regs);
++ pr_info("%s at 0x%pa mapped to 0x%p\n", name,
++ &res.start, hw_regs);
+ }
+
+ out_put:
+diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c
+index 5af4c35ff5842..0e42f7bad7db1 100644
+--- a/arch/powerpc/sysdev/tsi108_pci.c
++++ b/arch/powerpc/sysdev/tsi108_pci.c
+@@ -217,9 +217,8 @@ int __init tsi108_setup_pci(struct device_node *dev, u32 cfg_phys, int primary)
+
+ (hose)->ops = &tsi108_direct_pci_ops;
+
+- printk(KERN_INFO "Found tsi108 PCI host bridge at 0x%08x. "
+- "Firmware bus number: %d->%d\n",
+- rsrc.start, hose->first_busno, hose->last_busno);
++ pr_info("Found tsi108 PCI host bridge at 0x%pa. Firmware bus number: %d->%d\n",
++ &rsrc.start, hose->first_busno, hose->last_busno);
+
+ /* Interpret the "ranges" property */
+ /* This also maps the I/O region and sets isa_io/mem_base */
+diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
+index 4ca7fbacff424..8cb7c579aa21d 100644
+--- a/arch/riscv/include/asm/sbi.h
++++ b/arch/riscv/include/asm/sbi.h
+@@ -293,7 +293,7 @@ int sbi_remote_hfence_vvma_asid(const struct cpumask *cpu_mask,
+ unsigned long start,
+ unsigned long size,
+ unsigned long asid);
+-int sbi_probe_extension(int ext);
++long sbi_probe_extension(int ext);
+
+ /* Check if current SBI specification version is 0.1 or not */
+ static inline int sbi_spec_is_0_1(void)
+diff --git a/arch/riscv/kernel/cpu_ops.c b/arch/riscv/kernel/cpu_ops.c
+index 8275f237a59df..eb479a88a954e 100644
+--- a/arch/riscv/kernel/cpu_ops.c
++++ b/arch/riscv/kernel/cpu_ops.c
+@@ -27,7 +27,7 @@ const struct cpu_operations cpu_ops_spinwait = {
+ void __init cpu_set_ops(int cpuid)
+ {
+ #if IS_ENABLED(CONFIG_RISCV_SBI)
+- if (sbi_probe_extension(SBI_EXT_HSM) > 0) {
++ if (sbi_probe_extension(SBI_EXT_HSM)) {
+ if (!cpuid)
+ pr_info("SBI HSM extension detected\n");
+ cpu_ops[cpuid] = &cpu_ops_sbi;
+diff --git a/arch/riscv/kernel/sbi.c b/arch/riscv/kernel/sbi.c
+index 5c87db8fdff2d..015ce8eef2de2 100644
+--- a/arch/riscv/kernel/sbi.c
++++ b/arch/riscv/kernel/sbi.c
+@@ -581,19 +581,18 @@ static void sbi_srst_power_off(void)
+ * sbi_probe_extension() - Check if an SBI extension ID is supported or not.
+ * @extid: The extension ID to be probed.
+ *
+- * Return: Extension specific nonzero value f yes, -ENOTSUPP otherwise.
++ * Return: 1 or an extension specific nonzero value if yes, 0 otherwise.
+ */
+-int sbi_probe_extension(int extid)
++long sbi_probe_extension(int extid)
+ {
+ struct sbiret ret;
+
+ ret = sbi_ecall(SBI_EXT_BASE, SBI_EXT_BASE_PROBE_EXT, extid,
+ 0, 0, 0, 0, 0);
+ if (!ret.error)
+- if (ret.value)
+- return ret.value;
++ return ret.value;
+
+- return -ENOTSUPP;
++ return 0;
+ }
+ EXPORT_SYMBOL(sbi_probe_extension);
+
+@@ -665,26 +664,26 @@ void __init sbi_init(void)
+ if (!sbi_spec_is_0_1()) {
+ pr_info("SBI implementation ID=0x%lx Version=0x%lx\n",
+ sbi_get_firmware_id(), sbi_get_firmware_version());
+- if (sbi_probe_extension(SBI_EXT_TIME) > 0) {
++ if (sbi_probe_extension(SBI_EXT_TIME)) {
+ __sbi_set_timer = __sbi_set_timer_v02;
+ pr_info("SBI TIME extension detected\n");
+ } else {
+ __sbi_set_timer = __sbi_set_timer_v01;
+ }
+- if (sbi_probe_extension(SBI_EXT_IPI) > 0) {
++ if (sbi_probe_extension(SBI_EXT_IPI)) {
+ __sbi_send_ipi = __sbi_send_ipi_v02;
+ pr_info("SBI IPI extension detected\n");
+ } else {
+ __sbi_send_ipi = __sbi_send_ipi_v01;
+ }
+- if (sbi_probe_extension(SBI_EXT_RFENCE) > 0) {
++ if (sbi_probe_extension(SBI_EXT_RFENCE)) {
+ __sbi_rfence = __sbi_rfence_v02;
+ pr_info("SBI RFENCE extension detected\n");
+ } else {
+ __sbi_rfence = __sbi_rfence_v01;
+ }
+ if ((sbi_spec_version >= sbi_mk_version(0, 3)) &&
+- (sbi_probe_extension(SBI_EXT_SRST) > 0)) {
++ sbi_probe_extension(SBI_EXT_SRST)) {
+ pr_info("SBI SRST extension detected\n");
+ pm_power_off = sbi_srst_power_off;
+ sbi_srst_reboot_nb.notifier_call = sbi_srst_reboot;
+diff --git a/arch/riscv/kvm/main.c b/arch/riscv/kvm/main.c
+index 58c5489d3031a..2e9b1e89c6972 100644
+--- a/arch/riscv/kvm/main.c
++++ b/arch/riscv/kvm/main.c
+@@ -84,7 +84,7 @@ int kvm_arch_init(void *opaque)
+ return -ENODEV;
+ }
+
+- if (sbi_probe_extension(SBI_EXT_RFENCE) <= 0) {
++ if (!sbi_probe_extension(SBI_EXT_RFENCE)) {
+ kvm_info("require SBI RFENCE extension\n");
+ return -ENODEV;
+ }
+diff --git a/arch/riscv/kvm/mmu.c b/arch/riscv/kvm/mmu.c
+index 34b57e0be2ef0..d1ae0df7411ea 100644
+--- a/arch/riscv/kvm/mmu.c
++++ b/arch/riscv/kvm/mmu.c
+@@ -628,6 +628,13 @@ int kvm_riscv_gstage_map(struct kvm_vcpu *vcpu,
+ !(memslot->flags & KVM_MEM_READONLY)) ? true : false;
+ unsigned long vma_pagesize, mmu_seq;
+
++ /* We need minimum second+third level pages */
++ ret = kvm_mmu_topup_memory_cache(pcache, gstage_pgd_levels);
++ if (ret) {
++ kvm_err("Failed to topup G-stage cache\n");
++ return ret;
++ }
++
+ mmap_read_lock(current->mm);
+
+ vma = vma_lookup(current->mm, hva);
+@@ -648,6 +655,15 @@ int kvm_riscv_gstage_map(struct kvm_vcpu *vcpu,
+ if (vma_pagesize == PMD_SIZE || vma_pagesize == PGDIR_SIZE)
+ gfn = (gpa & huge_page_mask(hstate_vma(vma))) >> PAGE_SHIFT;
+
++ /*
++ * Read mmu_invalidate_seq so that KVM can detect if the results of
++ * vma_lookup() or gfn_to_pfn_prot() become stale priort to acquiring
++ * kvm->mmu_lock.
++ *
++ * Rely on mmap_read_unlock() for an implicit smp_rmb(), which pairs
++ * with the smp_wmb() in kvm_mmu_invalidate_end().
++ */
++ mmu_seq = kvm->mmu_invalidate_seq;
+ mmap_read_unlock(current->mm);
+
+ if (vma_pagesize != PGDIR_SIZE &&
+@@ -657,15 +673,6 @@ int kvm_riscv_gstage_map(struct kvm_vcpu *vcpu,
+ return -EFAULT;
+ }
+
+- /* We need minimum second+third level pages */
+- ret = kvm_mmu_topup_memory_cache(pcache, gstage_pgd_levels);
+- if (ret) {
+- kvm_err("Failed to topup G-stage cache\n");
+- return ret;
+- }
+-
+- mmu_seq = kvm->mmu_invalidate_seq;
+-
+ hfn = gfn_to_pfn_prot(kvm, gfn, is_write, &writable);
+ if (hfn == KVM_PFN_ERR_HWPOISON) {
+ send_sig_mceerr(BUS_MCEERR_AR, (void __user *)hva,
+diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
+index 0f14f4a8d179a..6ebb75a9a6b9f 100644
+--- a/arch/riscv/mm/init.c
++++ b/arch/riscv/mm/init.c
+@@ -843,8 +843,7 @@ static void __init create_kernel_page_table(pgd_t *pgdir, bool early)
+ * this means 2 PMD entries whereas for 32-bit kernel, this is only 1 PGDIR
+ * entry.
+ */
+-static void __init create_fdt_early_page_table(pgd_t *pgdir,
+- uintptr_t fix_fdt_va,
++static void __init create_fdt_early_page_table(uintptr_t fix_fdt_va,
+ uintptr_t dtb_pa)
+ {
+ uintptr_t pa = dtb_pa & ~(PMD_SIZE - 1);
+@@ -1034,8 +1033,7 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
+ create_kernel_page_table(early_pg_dir, true);
+
+ /* Setup early mapping for FDT early scan */
+- create_fdt_early_page_table(early_pg_dir,
+- __fix_to_virt(FIX_FDT), dtb_pa);
++ create_fdt_early_page_table(__fix_to_virt(FIX_FDT), dtb_pa);
+
+ /*
+ * Bootime fixmap only can handle PMD_SIZE mapping. Thus, boot-ioremap
+diff --git a/arch/riscv/mm/ptdump.c b/arch/riscv/mm/ptdump.c
+index 830e7de65e3a3..20a9f991a6d74 100644
+--- a/arch/riscv/mm/ptdump.c
++++ b/arch/riscv/mm/ptdump.c
+@@ -59,10 +59,6 @@ struct ptd_mm_info {
+ };
+
+ enum address_markers_idx {
+-#ifdef CONFIG_KASAN
+- KASAN_SHADOW_START_NR,
+- KASAN_SHADOW_END_NR,
+-#endif
+ FIXMAP_START_NR,
+ FIXMAP_END_NR,
+ PCI_IO_START_NR,
+@@ -74,6 +70,10 @@ enum address_markers_idx {
+ VMALLOC_START_NR,
+ VMALLOC_END_NR,
+ PAGE_OFFSET_NR,
++#ifdef CONFIG_KASAN
++ KASAN_SHADOW_START_NR,
++ KASAN_SHADOW_END_NR,
++#endif
+ #ifdef CONFIG_64BIT
+ MODULES_MAPPING_NR,
+ KERNEL_MAPPING_NR,
+@@ -82,10 +82,6 @@ enum address_markers_idx {
+ };
+
+ static struct addr_marker address_markers[] = {
+-#ifdef CONFIG_KASAN
+- {0, "Kasan shadow start"},
+- {0, "Kasan shadow end"},
+-#endif
+ {0, "Fixmap start"},
+ {0, "Fixmap end"},
+ {0, "PCI I/O start"},
+@@ -97,6 +93,10 @@ static struct addr_marker address_markers[] = {
+ {0, "vmalloc() area"},
+ {0, "vmalloc() end"},
+ {0, "Linear mapping"},
++#ifdef CONFIG_KASAN
++ {0, "Kasan shadow start"},
++ {0, "Kasan shadow end"},
++#endif
+ #ifdef CONFIG_64BIT
+ {0, "Modules/BPF mapping"},
+ {0, "Kernel mapping"},
+@@ -362,10 +362,6 @@ static int __init ptdump_init(void)
+ {
+ unsigned int i, j;
+
+-#ifdef CONFIG_KASAN
+- address_markers[KASAN_SHADOW_START_NR].start_address = KASAN_SHADOW_START;
+- address_markers[KASAN_SHADOW_END_NR].start_address = KASAN_SHADOW_END;
+-#endif
+ address_markers[FIXMAP_START_NR].start_address = FIXADDR_START;
+ address_markers[FIXMAP_END_NR].start_address = FIXADDR_TOP;
+ address_markers[PCI_IO_START_NR].start_address = PCI_IO_START;
+@@ -377,6 +373,10 @@ static int __init ptdump_init(void)
+ address_markers[VMALLOC_START_NR].start_address = VMALLOC_START;
+ address_markers[VMALLOC_END_NR].start_address = VMALLOC_END;
+ address_markers[PAGE_OFFSET_NR].start_address = PAGE_OFFSET;
++#ifdef CONFIG_KASAN
++ address_markers[KASAN_SHADOW_START_NR].start_address = KASAN_SHADOW_START;
++ address_markers[KASAN_SHADOW_END_NR].start_address = KASAN_SHADOW_END;
++#endif
+ #ifdef CONFIG_64BIT
+ address_markers[MODULES_MAPPING_NR].start_address = MODULES_VADDR;
+ address_markers[KERNEL_MAPPING_NR].start_address = kernel_map.virt_addr;
+diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
+index 7fd08755a1f9e..854a6581d2f90 100644
+--- a/arch/s390/Kconfig
++++ b/arch/s390/Kconfig
+@@ -26,10 +26,6 @@ config GENERIC_BUG
+ config GENERIC_BUG_RELATIVE_POINTERS
+ def_bool y
+
+-config GENERIC_CSUM
+- bool
+- default y if KASAN
+-
+ config GENERIC_LOCKBREAK
+ def_bool y if PREEMPTION
+
+diff --git a/arch/s390/include/asm/checksum.h b/arch/s390/include/asm/checksum.h
+index d977a3a2f6190..1b6b992cf18ed 100644
+--- a/arch/s390/include/asm/checksum.h
++++ b/arch/s390/include/asm/checksum.h
+@@ -12,12 +12,7 @@
+ #ifndef _S390_CHECKSUM_H
+ #define _S390_CHECKSUM_H
+
+-#ifdef CONFIG_GENERIC_CSUM
+-
+-#include <asm-generic/checksum.h>
+-
+-#else /* CONFIG_GENERIC_CSUM */
+-
++#include <linux/kasan-checks.h>
+ #include <linux/uaccess.h>
+ #include <linux/in6.h>
+
+@@ -40,6 +35,7 @@ static inline __wsum csum_partial(const void *buff, int len, __wsum sum)
+ .odd = (unsigned long) len,
+ };
+
++ kasan_check_read(buff, len);
+ asm volatile(
+ "0: cksm %[sum],%[rp]\n"
+ " jo 0b\n"
+@@ -135,5 +131,4 @@ static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
+ return csum_fold((__force __wsum)(sum >> 32));
+ }
+
+-#endif /* CONFIG_GENERIC_CSUM */
+ #endif /* _S390_CHECKSUM_H */
+diff --git a/arch/sh/kernel/cpu/sh4/sq.c b/arch/sh/kernel/cpu/sh4/sq.c
+index a76b94e41e913..8ddfe9989f5fc 100644
+--- a/arch/sh/kernel/cpu/sh4/sq.c
++++ b/arch/sh/kernel/cpu/sh4/sq.c
+@@ -382,7 +382,7 @@ static int __init sq_api_init(void)
+ if (unlikely(!sq_cache))
+ return ret;
+
+- sq_bitmap = kzalloc(size, GFP_KERNEL);
++ sq_bitmap = kcalloc(size, sizeof(long), GFP_KERNEL);
+ if (unlikely(!sq_bitmap))
+ goto out;
+
+diff --git a/arch/x86/include/asm/intel-family.h b/arch/x86/include/asm/intel-family.h
+index cbaf174d8efd9..b3af2d45bbbb5 100644
+--- a/arch/x86/include/asm/intel-family.h
++++ b/arch/x86/include/asm/intel-family.h
+@@ -125,6 +125,8 @@
+
+ #define INTEL_FAM6_LUNARLAKE_M 0xBD
+
++#define INTEL_FAM6_ARROWLAKE 0xC6
++
+ /* "Small Core" Processors (Atom/E-Core) */
+
+ #define INTEL_FAM6_ATOM_BONNELL 0x1C /* Diamondville, Pineview */
+diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
+index 20d9a604da7c4..7705571100518 100644
+--- a/arch/x86/kernel/apic/apic.c
++++ b/arch/x86/kernel/apic/apic.c
+@@ -422,10 +422,9 @@ static unsigned int reserve_eilvt_offset(int offset, unsigned int new)
+ if (vector && !eilvt_entry_is_changeable(vector, new))
+ /* may not change if vectors are different */
+ return rsvd;
+- rsvd = atomic_cmpxchg(&eilvt_offsets[offset], rsvd, new);
+- } while (rsvd != new);
++ } while (!atomic_try_cmpxchg(&eilvt_offsets[offset], &rsvd, new));
+
+- rsvd &= ~APIC_EILVT_MASKED;
++ rsvd = new & ~APIC_EILVT_MASKED;
+ if (rsvd && rsvd != vector)
+ pr_info("LVT offset %d assigned for vector 0x%02x\n",
+ offset, rsvd);
+diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
+index a868b76cd3d42..efa87b6bb1cde 100644
+--- a/arch/x86/kernel/apic/io_apic.c
++++ b/arch/x86/kernel/apic/io_apic.c
+@@ -2480,17 +2480,21 @@ static int io_apic_get_redir_entries(int ioapic)
+
+ unsigned int arch_dynirq_lower_bound(unsigned int from)
+ {
++ unsigned int ret;
++
+ /*
+ * dmar_alloc_hwirq() may be called before setup_IO_APIC(), so use
+ * gsi_top if ioapic_dynirq_base hasn't been initialized yet.
+ */
+- if (!ioapic_initialized)
+- return gsi_top;
++ ret = ioapic_dynirq_base ? : gsi_top;
++
+ /*
+- * For DT enabled machines ioapic_dynirq_base is irrelevant and not
+- * updated. So simply return @from if ioapic_dynirq_base == 0.
++ * For DT enabled machines ioapic_dynirq_base is irrelevant and
++ * always 0. gsi_top can be 0 if there is no IO/APIC registered.
++ * 0 is an invalid interrupt number for dynamic allocations. Return
++ * @from instead.
+ */
+- return ioapic_dynirq_base ? : from;
++ return ret ? : from;
+ }
+
+ #ifdef CONFIG_X86_32
+diff --git a/arch/x86/kernel/cpu/mce/amd.c b/arch/x86/kernel/cpu/mce/amd.c
+index 10fb5b5c9efa4..5518272061bfb 100644
+--- a/arch/x86/kernel/cpu/mce/amd.c
++++ b/arch/x86/kernel/cpu/mce/amd.c
+@@ -235,10 +235,10 @@ static DEFINE_PER_CPU(struct threshold_bank **, threshold_banks);
+ * A list of the banks enabled on each logical CPU. Controls which respective
+ * descriptors to initialize later in mce_threshold_create_device().
+ */
+-static DEFINE_PER_CPU(unsigned int, bank_map);
++static DEFINE_PER_CPU(u64, bank_map);
+
+ /* Map of banks that have more than MCA_MISC0 available. */
+-static DEFINE_PER_CPU(u32, smca_misc_banks_map);
++static DEFINE_PER_CPU(u64, smca_misc_banks_map);
+
+ static void amd_threshold_interrupt(void);
+ static void amd_deferred_error_interrupt(void);
+@@ -267,7 +267,7 @@ static void smca_set_misc_banks_map(unsigned int bank, unsigned int cpu)
+ return;
+
+ if (low & MASK_BLKPTR_LO)
+- per_cpu(smca_misc_banks_map, cpu) |= BIT(bank);
++ per_cpu(smca_misc_banks_map, cpu) |= BIT_ULL(bank);
+
+ }
+
+@@ -528,7 +528,7 @@ static u32 smca_get_block_address(unsigned int bank, unsigned int block,
+ if (!block)
+ return MSR_AMD64_SMCA_MCx_MISC(bank);
+
+- if (!(per_cpu(smca_misc_banks_map, cpu) & BIT(bank)))
++ if (!(per_cpu(smca_misc_banks_map, cpu) & BIT_ULL(bank)))
+ return 0;
+
+ return MSR_AMD64_SMCA_MCx_MISCy(bank, block - 1);
+@@ -572,7 +572,7 @@ prepare_threshold_block(unsigned int bank, unsigned int block, u32 addr,
+ int new;
+
+ if (!block)
+- per_cpu(bank_map, cpu) |= (1 << bank);
++ per_cpu(bank_map, cpu) |= BIT_ULL(bank);
+
+ memset(&b, 0, sizeof(b));
+ b.cpu = cpu;
+@@ -884,7 +884,7 @@ static void amd_threshold_interrupt(void)
+ return;
+
+ for (bank = 0; bank < this_cpu_read(mce_num_banks); ++bank) {
+- if (!(per_cpu(bank_map, cpu) & (1 << bank)))
++ if (!(per_cpu(bank_map, cpu) & BIT_ULL(bank)))
+ continue;
+
+ first_block = bp[bank]->blocks;
+@@ -1362,7 +1362,7 @@ int mce_threshold_create_device(unsigned int cpu)
+ return -ENOMEM;
+
+ for (bank = 0; bank < numbanks; ++bank) {
+- if (!(this_cpu_read(bank_map) & (1 << bank)))
++ if (!(this_cpu_read(bank_map) & BIT_ULL(bank)))
+ continue;
+ err = threshold_create_bank(bp, cpu, bank);
+ if (err) {
+diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
+index 46668e2554210..1ce228dc267ae 100644
+--- a/arch/x86/kernel/cpu/mshyperv.c
++++ b/arch/x86/kernel/cpu/mshyperv.c
+@@ -291,12 +291,16 @@ static void __init ms_hyperv_init_platform(void)
+ * To mirror what Windows does we should extract CPU management
+ * features and use the ReservedIdentityBit to detect if Linux is the
+ * root partition. But that requires negotiating CPU management
+- * interface (a process to be finalized).
++ * interface (a process to be finalized). For now, use the privilege
++ * flag as the indicator for running as root.
+ *
+- * For now, use the privilege flag as the indicator for running as
+- * root.
++ * Hyper-V should never specify running as root and as a Confidential
++ * VM. But to protect against a compromised/malicious Hyper-V trying
++ * to exploit root behavior to expose Confidential VM memory, ignore
++ * the root partition setting if also a Confidential VM.
+ */
+- if (cpuid_ebx(HYPERV_CPUID_FEATURES) & HV_CPU_MANAGEMENT) {
++ if ((ms_hyperv.priv_high & HV_CPU_MANAGEMENT) &&
++ !(ms_hyperv.priv_high & HV_ISOLATION)) {
+ hv_root_partition = true;
+ pr_info("Hyper-V: running as root partition\n");
+ }
+diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
+index cb547a0833812..53034045cb6e6 100644
+--- a/arch/x86/kvm/vmx/vmx.c
++++ b/arch/x86/kvm/vmx/vmx.c
+@@ -7749,9 +7749,11 @@ static u64 vmx_get_perf_capabilities(void)
+ if (boot_cpu_has(X86_FEATURE_PDCM))
+ rdmsrl(MSR_IA32_PERF_CAPABILITIES, host_perf_cap);
+
+- x86_perf_get_lbr(&lbr);
+- if (lbr.nr)
+- perf_cap |= host_perf_cap & PMU_CAP_LBR_FMT;
++ if (!cpu_feature_enabled(X86_FEATURE_ARCH_LBR)) {
++ x86_perf_get_lbr(&lbr);
++ if (lbr.nr)
++ perf_cap |= host_perf_cap & PMU_CAP_LBR_FMT;
++ }
+
+ if (vmx_pebs_supported()) {
+ perf_cap |= host_perf_cap & PERF_CAP_PEBS_MASK;
+@@ -7891,6 +7893,21 @@ static int vmx_check_intercept(struct kvm_vcpu *vcpu,
+ /* FIXME: produce nested vmexit and return X86EMUL_INTERCEPTED. */
+ break;
+
++ case x86_intercept_pause:
++ /*
++ * PAUSE is a single-byte NOP with a REPE prefix, i.e. collides
++ * with vanilla NOPs in the emulator. Apply the interception
++ * check only to actual PAUSE instructions. Don't check
++ * PAUSE-loop-exiting, software can't expect a given PAUSE to
++ * exit, i.e. KVM is within its rights to allow L2 to execute
++ * the PAUSE.
++ */
++ if ((info->rep_prefix != REPE_PREFIX) ||
++ !nested_cpu_has2(vmcs12, CPU_BASED_PAUSE_EXITING))
++ return X86EMUL_CONTINUE;
++
++ break;
++
+ /* TODO: check more intercepts... */
+ default:
+ break;
+diff --git a/block/blk-crypto-internal.h b/block/blk-crypto-internal.h
+index a8cdaf26851e1..4f1de2495f0c3 100644
+--- a/block/blk-crypto-internal.h
++++ b/block/blk-crypto-internal.h
+@@ -65,6 +65,11 @@ static inline bool blk_crypto_rq_is_encrypted(struct request *rq)
+ return rq->crypt_ctx;
+ }
+
++static inline bool blk_crypto_rq_has_keyslot(struct request *rq)
++{
++ return rq->crypt_keyslot;
++}
++
+ blk_status_t blk_crypto_get_keyslot(struct blk_crypto_profile *profile,
+ const struct blk_crypto_key *key,
+ struct blk_crypto_keyslot **slot_ptr);
+@@ -119,6 +124,11 @@ static inline bool blk_crypto_rq_is_encrypted(struct request *rq)
+ return false;
+ }
+
++static inline bool blk_crypto_rq_has_keyslot(struct request *rq)
++{
++ return false;
++}
++
+ #endif /* CONFIG_BLK_INLINE_ENCRYPTION */
+
+ void __bio_crypt_advance(struct bio *bio, unsigned int bytes);
+@@ -153,14 +163,21 @@ static inline bool blk_crypto_bio_prep(struct bio **bio_ptr)
+ return true;
+ }
+
+-blk_status_t __blk_crypto_init_request(struct request *rq);
+-static inline blk_status_t blk_crypto_init_request(struct request *rq)
++blk_status_t __blk_crypto_rq_get_keyslot(struct request *rq);
++static inline blk_status_t blk_crypto_rq_get_keyslot(struct request *rq)
+ {
+ if (blk_crypto_rq_is_encrypted(rq))
+- return __blk_crypto_init_request(rq);
++ return __blk_crypto_rq_get_keyslot(rq);
+ return BLK_STS_OK;
+ }
+
++void __blk_crypto_rq_put_keyslot(struct request *rq);
++static inline void blk_crypto_rq_put_keyslot(struct request *rq)
++{
++ if (blk_crypto_rq_has_keyslot(rq))
++ __blk_crypto_rq_put_keyslot(rq);
++}
++
+ void __blk_crypto_free_request(struct request *rq);
+ static inline void blk_crypto_free_request(struct request *rq)
+ {
+@@ -199,7 +216,7 @@ static inline blk_status_t blk_crypto_insert_cloned_request(struct request *rq)
+ {
+
+ if (blk_crypto_rq_is_encrypted(rq))
+- return blk_crypto_init_request(rq);
++ return blk_crypto_rq_get_keyslot(rq);
+ return BLK_STS_OK;
+ }
+
+diff --git a/block/blk-crypto-profile.c b/block/blk-crypto-profile.c
+index 0307fb0d95d34..3290c03c9918d 100644
+--- a/block/blk-crypto-profile.c
++++ b/block/blk-crypto-profile.c
+@@ -354,28 +354,16 @@ bool __blk_crypto_cfg_supported(struct blk_crypto_profile *profile,
+ return true;
+ }
+
+-/**
+- * __blk_crypto_evict_key() - Evict a key from a device.
+- * @profile: the crypto profile of the device
+- * @key: the key to evict. It must not still be used in any I/O.
+- *
+- * If the device has keyslots, this finds the keyslot (if any) that contains the
+- * specified key and calls the driver's keyslot_evict function to evict it.
+- *
+- * Otherwise, this just calls the driver's keyslot_evict function if it is
+- * implemented, passing just the key (without any particular keyslot). This
+- * allows layered devices to evict the key from their underlying devices.
+- *
+- * Context: Process context. Takes and releases profile->lock.
+- * Return: 0 on success or if there's no keyslot with the specified key, -EBUSY
+- * if the keyslot is still in use, or another -errno value on other
+- * error.
++/*
++ * This is an internal function that evicts a key from an inline encryption
++ * device that can be either a real device or the blk-crypto-fallback "device".
++ * It is used only by blk_crypto_evict_key(); see that function for details.
+ */
+ int __blk_crypto_evict_key(struct blk_crypto_profile *profile,
+ const struct blk_crypto_key *key)
+ {
+ struct blk_crypto_keyslot *slot;
+- int err = 0;
++ int err;
+
+ if (profile->num_slots == 0) {
+ if (profile->ll_ops.keyslot_evict) {
+@@ -389,22 +377,30 @@ int __blk_crypto_evict_key(struct blk_crypto_profile *profile,
+
+ blk_crypto_hw_enter(profile);
+ slot = blk_crypto_find_keyslot(profile, key);
+- if (!slot)
+- goto out_unlock;
++ if (!slot) {
++ /*
++ * Not an error, since a key not in use by I/O is not guaranteed
++ * to be in a keyslot. There can be more keys than keyslots.
++ */
++ err = 0;
++ goto out;
++ }
+
+ if (WARN_ON_ONCE(atomic_read(&slot->slot_refs) != 0)) {
++ /* BUG: key is still in use by I/O */
+ err = -EBUSY;
+- goto out_unlock;
++ goto out_remove;
+ }
+ err = profile->ll_ops.keyslot_evict(profile, key,
+ blk_crypto_keyslot_index(slot));
+- if (err)
+- goto out_unlock;
+-
++out_remove:
++ /*
++ * Callers free the key even on error, so unlink the key from the hash
++ * table and clear slot->key even on error.
++ */
+ hlist_del(&slot->hash_node);
+ slot->key = NULL;
+- err = 0;
+-out_unlock:
++out:
+ blk_crypto_hw_exit(profile);
+ return err;
+ }
+diff --git a/block/blk-crypto.c b/block/blk-crypto.c
+index 45378586151f7..4d760b092deb9 100644
+--- a/block/blk-crypto.c
++++ b/block/blk-crypto.c
+@@ -13,6 +13,7 @@
+ #include <linux/blkdev.h>
+ #include <linux/blk-crypto-profile.h>
+ #include <linux/module.h>
++#include <linux/ratelimit.h>
+ #include <linux/slab.h>
+
+ #include "blk-crypto-internal.h"
+@@ -224,27 +225,27 @@ static bool bio_crypt_check_alignment(struct bio *bio)
+ return true;
+ }
+
+-blk_status_t __blk_crypto_init_request(struct request *rq)
++blk_status_t __blk_crypto_rq_get_keyslot(struct request *rq)
+ {
+ return blk_crypto_get_keyslot(rq->q->crypto_profile,
+ rq->crypt_ctx->bc_key,
+ &rq->crypt_keyslot);
+ }
+
+-/**
+- * __blk_crypto_free_request - Uninitialize the crypto fields of a request.
+- *
+- * @rq: The request whose crypto fields to uninitialize.
+- *
+- * Completely uninitializes the crypto fields of a request. If a keyslot has
+- * been programmed into some inline encryption hardware, that keyslot is
+- * released. The rq->crypt_ctx is also freed.
+- */
+-void __blk_crypto_free_request(struct request *rq)
++void __blk_crypto_rq_put_keyslot(struct request *rq)
+ {
+ blk_crypto_put_keyslot(rq->crypt_keyslot);
++ rq->crypt_keyslot = NULL;
++}
++
++void __blk_crypto_free_request(struct request *rq)
++{
++ /* The keyslot, if one was needed, should have been released earlier. */
++ if (WARN_ON_ONCE(rq->crypt_keyslot))
++ __blk_crypto_rq_put_keyslot(rq);
++
+ mempool_free(rq->crypt_ctx, bio_crypt_ctx_pool);
+- blk_crypto_rq_set_defaults(rq);
++ rq->crypt_ctx = NULL;
+ }
+
+ /**
+@@ -399,30 +400,39 @@ int blk_crypto_start_using_key(struct block_device *bdev,
+ }
+
+ /**
+- * blk_crypto_evict_key() - Evict a key from any inline encryption hardware
+- * it may have been programmed into
+- * @bdev: The block_device who's associated inline encryption hardware this key
+- * might have been programmed into
+- * @key: The key to evict
++ * blk_crypto_evict_key() - Evict a blk_crypto_key from a block_device
++ * @bdev: a block_device on which I/O using the key may have been done
++ * @key: the key to evict
++ *
++ * For a given block_device, this function removes the given blk_crypto_key from
++ * the keyslot management structures and evicts it from any underlying hardware
++ * keyslot(s) or blk-crypto-fallback keyslot it may have been programmed into.
+ *
+- * Upper layers (filesystems) must call this function to ensure that a key is
+- * evicted from any hardware that it might have been programmed into. The key
+- * must not be in use by any in-flight IO when this function is called.
++ * Upper layers must call this before freeing the blk_crypto_key. It must be
++ * called for every block_device the key may have been used on. The key must no
++ * longer be in use by any I/O when this function is called.
+ *
+- * Return: 0 on success or if the key wasn't in any keyslot; -errno on error.
++ * Context: May sleep.
+ */
+-int blk_crypto_evict_key(struct block_device *bdev,
+- const struct blk_crypto_key *key)
++void blk_crypto_evict_key(struct block_device *bdev,
++ const struct blk_crypto_key *key)
+ {
+ struct request_queue *q = bdev_get_queue(bdev);
++ int err;
+
+ if (blk_crypto_config_supported_natively(bdev, &key->crypto_cfg))
+- return __blk_crypto_evict_key(q->crypto_profile, key);
+-
++ err = __blk_crypto_evict_key(q->crypto_profile, key);
++ else
++ err = blk_crypto_fallback_evict_key(key);
+ /*
+- * If the block_device didn't support the key, then blk-crypto-fallback
+- * may have been used, so try to evict the key from blk-crypto-fallback.
++ * An error can only occur here if the key failed to be evicted from a
++ * keyslot (due to a hardware or driver issue) or is allegedly still in
++ * use by I/O (due to a kernel bug). Even in these cases, the key is
++ * still unlinked from the keyslot management structures, and the caller
++ * is allowed and expected to free it right away. There's nothing
++ * callers can do to handle errors, so just log them and return void.
+ */
+- return blk_crypto_fallback_evict_key(key);
++ if (err)
++ pr_warn_ratelimited("%pg: error %d evicting key\n", bdev, err);
+ }
+ EXPORT_SYMBOL_GPL(blk_crypto_evict_key);
+diff --git a/block/blk-iocost.c b/block/blk-iocost.c
+index ec7219caea165..5c265791decbd 100644
+--- a/block/blk-iocost.c
++++ b/block/blk-iocost.c
+@@ -258,6 +258,11 @@ enum {
+ VRATE_MIN = VTIME_PER_USEC * VRATE_MIN_PPM / MILLION,
+ VRATE_CLAMP_ADJ_PCT = 4,
+
++ /* switch iff the conditions are met for longer than this */
++ AUTOP_CYCLE_NSEC = 10LLU * NSEC_PER_SEC,
++};
++
++enum {
+ /* if IOs end up waiting for requests, issue less */
+ RQ_WAIT_BUSY_PCT = 5,
+
+@@ -296,9 +301,6 @@ enum {
+ /* don't let cmds which take a very long time pin lagging for too long */
+ MAX_LAGGING_PERIODS = 10,
+
+- /* switch iff the conditions are met for longer than this */
+- AUTOP_CYCLE_NSEC = 10LLU * NSEC_PER_SEC,
+-
+ /*
+ * Count IO size in 4k pages. The 12bit shift helps keeping
+ * size-proportional components of cost calculation in closer
+diff --git a/block/blk-merge.c b/block/blk-merge.c
+index 808b58129d3e4..efe5504902a32 100644
+--- a/block/blk-merge.c
++++ b/block/blk-merge.c
+@@ -873,6 +873,8 @@ static struct request *attempt_merge(struct request_queue *q,
+ if (!blk_discard_mergable(req))
+ elv_merge_requests(q, req, next);
+
++ blk_crypto_rq_put_keyslot(next);
++
+ /*
+ * 'next' is going away, so update stats accordingly
+ */
+diff --git a/block/blk-mq.c b/block/blk-mq.c
+index 86425167594cf..9f1bafb62973d 100644
+--- a/block/blk-mq.c
++++ b/block/blk-mq.c
+@@ -840,6 +840,12 @@ static void blk_complete_request(struct request *req)
+ req->q->integrity.profile->complete_fn(req, total_bytes);
+ #endif
+
++ /*
++ * Upper layers may call blk_crypto_evict_key() anytime after the last
++ * bio_endio(). Therefore, the keyslot must be released before that.
++ */
++ blk_crypto_rq_put_keyslot(req);
++
+ blk_account_io_completion(req, total_bytes);
+
+ do {
+@@ -905,6 +911,13 @@ bool blk_update_request(struct request *req, blk_status_t error,
+ req->q->integrity.profile->complete_fn(req, nr_bytes);
+ #endif
+
++ /*
++ * Upper layers may call blk_crypto_evict_key() anytime after the last
++ * bio_endio(). Therefore, the keyslot must be released before that.
++ */
++ if (blk_crypto_rq_has_keyslot(req) && nr_bytes >= blk_rq_bytes(req))
++ __blk_crypto_rq_put_keyslot(req);
++
+ if (unlikely(error && !blk_rq_is_passthrough(req) &&
+ !(req->rq_flags & RQF_QUIET)) &&
+ !test_bit(GD_DEAD, &req->q->disk->state)) {
+@@ -1332,7 +1345,7 @@ void blk_execute_rq_nowait(struct request *rq, bool at_head)
+ * device, directly accessing the plug instead of using blk_mq_plug()
+ * should not have any consequences.
+ */
+- if (current->plug)
++ if (current->plug && !at_head)
+ blk_add_rq_to_plug(current->plug, rq);
+ else
+ blk_mq_sched_insert_request(rq, at_head, true, false);
+@@ -2987,7 +3000,7 @@ void blk_mq_submit_bio(struct bio *bio)
+
+ blk_mq_bio_to_request(rq, bio, nr_segs);
+
+- ret = blk_crypto_init_request(rq);
++ ret = blk_crypto_rq_get_keyslot(rq);
+ if (ret != BLK_STS_OK) {
+ bio->bi_status = ret;
+ bio_endio(bio);
+diff --git a/block/blk-stat.c b/block/blk-stat.c
+index 2ea01b5c1aca0..da9407b7d4abf 100644
+--- a/block/blk-stat.c
++++ b/block/blk-stat.c
+@@ -189,7 +189,7 @@ void blk_stat_disable_accounting(struct request_queue *q)
+ unsigned long flags;
+
+ spin_lock_irqsave(&q->stats->lock, flags);
+- if (!--q->stats->accounting)
++ if (!--q->stats->accounting && list_empty(&q->stats->callbacks))
+ blk_queue_flag_clear(QUEUE_FLAG_STATS, q);
+ spin_unlock_irqrestore(&q->stats->lock, flags);
+ }
+@@ -200,7 +200,7 @@ void blk_stat_enable_accounting(struct request_queue *q)
+ unsigned long flags;
+
+ spin_lock_irqsave(&q->stats->lock, flags);
+- if (!q->stats->accounting++)
++ if (!q->stats->accounting++ && list_empty(&q->stats->callbacks))
+ blk_queue_flag_set(QUEUE_FLAG_STATS, q);
+ spin_unlock_irqrestore(&q->stats->lock, flags);
+ }
+diff --git a/crypto/algapi.c b/crypto/algapi.c
+index d08f864f08bee..9de0677b3643d 100644
+--- a/crypto/algapi.c
++++ b/crypto/algapi.c
+@@ -493,7 +493,9 @@ void crypto_unregister_alg(struct crypto_alg *alg)
+ if (WARN(ret, "Algorithm %s is not registered", alg->cra_driver_name))
+ return;
+
+- BUG_ON(refcount_read(&alg->cra_refcnt) != 1);
++ if (WARN_ON(refcount_read(&alg->cra_refcnt) != 1))
++ return;
++
+ if (alg->cra_destroy)
+ alg->cra_destroy(alg);
+
+diff --git a/crypto/drbg.c b/crypto/drbg.c
+index 982d4ca4526d8..ff4ebbc68efab 100644
+--- a/crypto/drbg.c
++++ b/crypto/drbg.c
+@@ -1546,7 +1546,7 @@ static int drbg_prepare_hrng(struct drbg_state *drbg)
+ const int err = PTR_ERR(drbg->jent);
+
+ drbg->jent = NULL;
+- if (fips_enabled || err != -ENOENT)
++ if (fips_enabled)
+ return err;
+ pr_info("DRBG: Continuing without Jitter RNG\n");
+ }
+diff --git a/crypto/testmgr.c b/crypto/testmgr.c
+index 4476ac97baa5e..abd91fadd34f7 100644
+--- a/crypto/testmgr.c
++++ b/crypto/testmgr.c
+@@ -852,12 +852,50 @@ static int prepare_keybuf(const u8 *key, unsigned int ksize,
+
+ #ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS
+
++/*
++ * The fuzz tests use prandom instead of the normal Linux RNG since they don't
++ * need cryptographically secure random numbers. This greatly improves the
++ * performance of these tests, especially if they are run before the Linux RNG
++ * has been initialized or if they are run on a lockdep-enabled kernel.
++ */
++
++static inline void init_rnd_state(struct rnd_state *rng)
++{
++ prandom_seed_state(rng, get_random_u64());
++}
++
++static inline u8 prandom_u8(struct rnd_state *rng)
++{
++ return prandom_u32_state(rng);
++}
++
++static inline u32 prandom_u32_below(struct rnd_state *rng, u32 ceil)
++{
++ /*
++ * This is slightly biased for non-power-of-2 values of 'ceil', but this
++ * isn't important here.
++ */
++ return prandom_u32_state(rng) % ceil;
++}
++
++static inline bool prandom_bool(struct rnd_state *rng)
++{
++ return prandom_u32_below(rng, 2);
++}
++
++static inline u32 prandom_u32_inclusive(struct rnd_state *rng,
++ u32 floor, u32 ceil)
++{
++ return floor + prandom_u32_below(rng, ceil - floor + 1);
++}
++
+ /* Generate a random length in range [0, max_len], but prefer smaller values */
+-static unsigned int generate_random_length(unsigned int max_len)
++static unsigned int generate_random_length(struct rnd_state *rng,
++ unsigned int max_len)
+ {
+- unsigned int len = get_random_u32_below(max_len + 1);
++ unsigned int len = prandom_u32_below(rng, max_len + 1);
+
+- switch (get_random_u32_below(4)) {
++ switch (prandom_u32_below(rng, 4)) {
+ case 0:
+ return len % 64;
+ case 1:
+@@ -870,43 +908,44 @@ static unsigned int generate_random_length(unsigned int max_len)
+ }
+
+ /* Flip a random bit in the given nonempty data buffer */
+-static void flip_random_bit(u8 *buf, size_t size)
++static void flip_random_bit(struct rnd_state *rng, u8 *buf, size_t size)
+ {
+ size_t bitpos;
+
+- bitpos = get_random_u32_below(size * 8);
++ bitpos = prandom_u32_below(rng, size * 8);
+ buf[bitpos / 8] ^= 1 << (bitpos % 8);
+ }
+
+ /* Flip a random byte in the given nonempty data buffer */
+-static void flip_random_byte(u8 *buf, size_t size)
++static void flip_random_byte(struct rnd_state *rng, u8 *buf, size_t size)
+ {
+- buf[get_random_u32_below(size)] ^= 0xff;
++ buf[prandom_u32_below(rng, size)] ^= 0xff;
+ }
+
+ /* Sometimes make some random changes to the given nonempty data buffer */
+-static void mutate_buffer(u8 *buf, size_t size)
++static void mutate_buffer(struct rnd_state *rng, u8 *buf, size_t size)
+ {
+ size_t num_flips;
+ size_t i;
+
+ /* Sometimes flip some bits */
+- if (get_random_u32_below(4) == 0) {
+- num_flips = min_t(size_t, 1 << get_random_u32_below(8), size * 8);
++ if (prandom_u32_below(rng, 4) == 0) {
++ num_flips = min_t(size_t, 1 << prandom_u32_below(rng, 8),
++ size * 8);
+ for (i = 0; i < num_flips; i++)
+- flip_random_bit(buf, size);
++ flip_random_bit(rng, buf, size);
+ }
+
+ /* Sometimes flip some bytes */
+- if (get_random_u32_below(4) == 0) {
+- num_flips = min_t(size_t, 1 << get_random_u32_below(8), size);
++ if (prandom_u32_below(rng, 4) == 0) {
++ num_flips = min_t(size_t, 1 << prandom_u32_below(rng, 8), size);
+ for (i = 0; i < num_flips; i++)
+- flip_random_byte(buf, size);
++ flip_random_byte(rng, buf, size);
+ }
+ }
+
+ /* Randomly generate 'count' bytes, but sometimes make them "interesting" */
+-static void generate_random_bytes(u8 *buf, size_t count)
++static void generate_random_bytes(struct rnd_state *rng, u8 *buf, size_t count)
+ {
+ u8 b;
+ u8 increment;
+@@ -915,11 +954,11 @@ static void generate_random_bytes(u8 *buf, size_t count)
+ if (count == 0)
+ return;
+
+- switch (get_random_u32_below(8)) { /* Choose a generation strategy */
++ switch (prandom_u32_below(rng, 8)) { /* Choose a generation strategy */
+ case 0:
+ case 1:
+ /* All the same byte, plus optional mutations */
+- switch (get_random_u32_below(4)) {
++ switch (prandom_u32_below(rng, 4)) {
+ case 0:
+ b = 0x00;
+ break;
+@@ -927,28 +966,28 @@ static void generate_random_bytes(u8 *buf, size_t count)
+ b = 0xff;
+ break;
+ default:
+- b = get_random_u8();
++ b = prandom_u8(rng);
+ break;
+ }
+ memset(buf, b, count);
+- mutate_buffer(buf, count);
++ mutate_buffer(rng, buf, count);
+ break;
+ case 2:
+ /* Ascending or descending bytes, plus optional mutations */
+- increment = get_random_u8();
+- b = get_random_u8();
++ increment = prandom_u8(rng);
++ b = prandom_u8(rng);
+ for (i = 0; i < count; i++, b += increment)
+ buf[i] = b;
+- mutate_buffer(buf, count);
++ mutate_buffer(rng, buf, count);
+ break;
+ default:
+ /* Fully random bytes */
+- for (i = 0; i < count; i++)
+- buf[i] = get_random_u8();
++ prandom_bytes_state(rng, buf, count);
+ }
+ }
+
+-static char *generate_random_sgl_divisions(struct test_sg_division *divs,
++static char *generate_random_sgl_divisions(struct rnd_state *rng,
++ struct test_sg_division *divs,
+ size_t max_divs, char *p, char *end,
+ bool gen_flushes, u32 req_flags)
+ {
+@@ -959,24 +998,26 @@ static char *generate_random_sgl_divisions(struct test_sg_division *divs,
+ unsigned int this_len;
+ const char *flushtype_str;
+
+- if (div == &divs[max_divs - 1] || get_random_u32_below(2) == 0)
++ if (div == &divs[max_divs - 1] || prandom_bool(rng))
+ this_len = remaining;
+ else
+- this_len = get_random_u32_inclusive(1, remaining);
++ this_len = prandom_u32_inclusive(rng, 1, remaining);
+ div->proportion_of_total = this_len;
+
+- if (get_random_u32_below(4) == 0)
+- div->offset = get_random_u32_inclusive(PAGE_SIZE - 128, PAGE_SIZE - 1);
+- else if (get_random_u32_below(2) == 0)
+- div->offset = get_random_u32_below(32);
++ if (prandom_u32_below(rng, 4) == 0)
++ div->offset = prandom_u32_inclusive(rng,
++ PAGE_SIZE - 128,
++ PAGE_SIZE - 1);
++ else if (prandom_bool(rng))
++ div->offset = prandom_u32_below(rng, 32);
+ else
+- div->offset = get_random_u32_below(PAGE_SIZE);
+- if (get_random_u32_below(8) == 0)
++ div->offset = prandom_u32_below(rng, PAGE_SIZE);
++ if (prandom_u32_below(rng, 8) == 0)
+ div->offset_relative_to_alignmask = true;
+
+ div->flush_type = FLUSH_TYPE_NONE;
+ if (gen_flushes) {
+- switch (get_random_u32_below(4)) {
++ switch (prandom_u32_below(rng, 4)) {
+ case 0:
+ div->flush_type = FLUSH_TYPE_REIMPORT;
+ break;
+@@ -988,7 +1029,7 @@ static char *generate_random_sgl_divisions(struct test_sg_division *divs,
+
+ if (div->flush_type != FLUSH_TYPE_NONE &&
+ !(req_flags & CRYPTO_TFM_REQ_MAY_SLEEP) &&
+- get_random_u32_below(2) == 0)
++ prandom_bool(rng))
+ div->nosimd = true;
+
+ switch (div->flush_type) {
+@@ -1023,7 +1064,8 @@ static char *generate_random_sgl_divisions(struct test_sg_division *divs,
+ }
+
+ /* Generate a random testvec_config for fuzz testing */
+-static void generate_random_testvec_config(struct testvec_config *cfg,
++static void generate_random_testvec_config(struct rnd_state *rng,
++ struct testvec_config *cfg,
+ char *name, size_t max_namelen)
+ {
+ char *p = name;
+@@ -1035,7 +1077,7 @@ static void generate_random_testvec_config(struct testvec_config *cfg,
+
+ p += scnprintf(p, end - p, "random:");
+
+- switch (get_random_u32_below(4)) {
++ switch (prandom_u32_below(rng, 4)) {
+ case 0:
+ case 1:
+ cfg->inplace_mode = OUT_OF_PLACE;
+@@ -1050,12 +1092,12 @@ static void generate_random_testvec_config(struct testvec_config *cfg,
+ break;
+ }
+
+- if (get_random_u32_below(2) == 0) {
++ if (prandom_bool(rng)) {
+ cfg->req_flags |= CRYPTO_TFM_REQ_MAY_SLEEP;
+ p += scnprintf(p, end - p, " may_sleep");
+ }
+
+- switch (get_random_u32_below(4)) {
++ switch (prandom_u32_below(rng, 4)) {
+ case 0:
+ cfg->finalization_type = FINALIZATION_TYPE_FINAL;
+ p += scnprintf(p, end - p, " use_final");
+@@ -1070,36 +1112,37 @@ static void generate_random_testvec_config(struct testvec_config *cfg,
+ break;
+ }
+
+- if (!(cfg->req_flags & CRYPTO_TFM_REQ_MAY_SLEEP) &&
+- get_random_u32_below(2) == 0) {
++ if (!(cfg->req_flags & CRYPTO_TFM_REQ_MAY_SLEEP) && prandom_bool(rng)) {
+ cfg->nosimd = true;
+ p += scnprintf(p, end - p, " nosimd");
+ }
+
+ p += scnprintf(p, end - p, " src_divs=[");
+- p = generate_random_sgl_divisions(cfg->src_divs,
++ p = generate_random_sgl_divisions(rng, cfg->src_divs,
+ ARRAY_SIZE(cfg->src_divs), p, end,
+ (cfg->finalization_type !=
+ FINALIZATION_TYPE_DIGEST),
+ cfg->req_flags);
+ p += scnprintf(p, end - p, "]");
+
+- if (cfg->inplace_mode == OUT_OF_PLACE && get_random_u32_below(2) == 0) {
++ if (cfg->inplace_mode == OUT_OF_PLACE && prandom_bool(rng)) {
+ p += scnprintf(p, end - p, " dst_divs=[");
+- p = generate_random_sgl_divisions(cfg->dst_divs,
++ p = generate_random_sgl_divisions(rng, cfg->dst_divs,
+ ARRAY_SIZE(cfg->dst_divs),
+ p, end, false,
+ cfg->req_flags);
+ p += scnprintf(p, end - p, "]");
+ }
+
+- if (get_random_u32_below(2) == 0) {
+- cfg->iv_offset = get_random_u32_inclusive(1, MAX_ALGAPI_ALIGNMASK);
++ if (prandom_bool(rng)) {
++ cfg->iv_offset = prandom_u32_inclusive(rng, 1,
++ MAX_ALGAPI_ALIGNMASK);
+ p += scnprintf(p, end - p, " iv_offset=%u", cfg->iv_offset);
+ }
+
+- if (get_random_u32_below(2) == 0) {
+- cfg->key_offset = get_random_u32_inclusive(1, MAX_ALGAPI_ALIGNMASK);
++ if (prandom_bool(rng)) {
++ cfg->key_offset = prandom_u32_inclusive(rng, 1,
++ MAX_ALGAPI_ALIGNMASK);
+ p += scnprintf(p, end - p, " key_offset=%u", cfg->key_offset);
+ }
+
+@@ -1612,11 +1655,14 @@ static int test_hash_vec(const struct hash_testvec *vec, unsigned int vec_num,
+
+ #ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS
+ if (!noextratests) {
++ struct rnd_state rng;
+ struct testvec_config cfg;
+ char cfgname[TESTVEC_CONFIG_NAMELEN];
+
++ init_rnd_state(&rng);
++
+ for (i = 0; i < fuzz_iterations; i++) {
+- generate_random_testvec_config(&cfg, cfgname,
++ generate_random_testvec_config(&rng, &cfg, cfgname,
+ sizeof(cfgname));
+ err = test_hash_vec_cfg(vec, vec_name, &cfg,
+ req, desc, tsgl, hashstate);
+@@ -1634,15 +1680,16 @@ static int test_hash_vec(const struct hash_testvec *vec, unsigned int vec_num,
+ * Generate a hash test vector from the given implementation.
+ * Assumes the buffers in 'vec' were already allocated.
+ */
+-static void generate_random_hash_testvec(struct shash_desc *desc,
++static void generate_random_hash_testvec(struct rnd_state *rng,
++ struct shash_desc *desc,
+ struct hash_testvec *vec,
+ unsigned int maxkeysize,
+ unsigned int maxdatasize,
+ char *name, size_t max_namelen)
+ {
+ /* Data */
+- vec->psize = generate_random_length(maxdatasize);
+- generate_random_bytes((u8 *)vec->plaintext, vec->psize);
++ vec->psize = generate_random_length(rng, maxdatasize);
++ generate_random_bytes(rng, (u8 *)vec->plaintext, vec->psize);
+
+ /*
+ * Key: length in range [1, maxkeysize], but usually choose maxkeysize.
+@@ -1652,9 +1699,9 @@ static void generate_random_hash_testvec(struct shash_desc *desc,
+ vec->ksize = 0;
+ if (maxkeysize) {
+ vec->ksize = maxkeysize;
+- if (get_random_u32_below(4) == 0)
+- vec->ksize = get_random_u32_inclusive(1, maxkeysize);
+- generate_random_bytes((u8 *)vec->key, vec->ksize);
++ if (prandom_u32_below(rng, 4) == 0)
++ vec->ksize = prandom_u32_inclusive(rng, 1, maxkeysize);
++ generate_random_bytes(rng, (u8 *)vec->key, vec->ksize);
+
+ vec->setkey_error = crypto_shash_setkey(desc->tfm, vec->key,
+ vec->ksize);
+@@ -1688,6 +1735,7 @@ static int test_hash_vs_generic_impl(const char *generic_driver,
+ const unsigned int maxdatasize = (2 * PAGE_SIZE) - TESTMGR_POISON_LEN;
+ const char *algname = crypto_hash_alg_common(tfm)->base.cra_name;
+ const char *driver = crypto_ahash_driver_name(tfm);
++ struct rnd_state rng;
+ char _generic_driver[CRYPTO_MAX_ALG_NAME];
+ struct crypto_shash *generic_tfm = NULL;
+ struct shash_desc *generic_desc = NULL;
+@@ -1701,6 +1749,8 @@ static int test_hash_vs_generic_impl(const char *generic_driver,
+ if (noextratests)
+ return 0;
+
++ init_rnd_state(&rng);
++
+ if (!generic_driver) { /* Use default naming convention? */
+ err = build_generic_driver_name(algname, _generic_driver);
+ if (err)
+@@ -1769,10 +1819,11 @@ static int test_hash_vs_generic_impl(const char *generic_driver,
+ }
+
+ for (i = 0; i < fuzz_iterations * 8; i++) {
+- generate_random_hash_testvec(generic_desc, &vec,
++ generate_random_hash_testvec(&rng, generic_desc, &vec,
+ maxkeysize, maxdatasize,
+ vec_name, sizeof(vec_name));
+- generate_random_testvec_config(cfg, cfgname, sizeof(cfgname));
++ generate_random_testvec_config(&rng, cfg, cfgname,
++ sizeof(cfgname));
+
+ err = test_hash_vec_cfg(&vec, vec_name, cfg,
+ req, desc, tsgl, hashstate);
+@@ -2174,11 +2225,14 @@ static int test_aead_vec(int enc, const struct aead_testvec *vec,
+
+ #ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS
+ if (!noextratests) {
++ struct rnd_state rng;
+ struct testvec_config cfg;
+ char cfgname[TESTVEC_CONFIG_NAMELEN];
+
++ init_rnd_state(&rng);
++
+ for (i = 0; i < fuzz_iterations; i++) {
+- generate_random_testvec_config(&cfg, cfgname,
++ generate_random_testvec_config(&rng, &cfg, cfgname,
+ sizeof(cfgname));
+ err = test_aead_vec_cfg(enc, vec, vec_name,
+ &cfg, req, tsgls);
+@@ -2194,6 +2248,7 @@ static int test_aead_vec(int enc, const struct aead_testvec *vec,
+ #ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS
+
+ struct aead_extra_tests_ctx {
++ struct rnd_state rng;
+ struct aead_request *req;
+ struct crypto_aead *tfm;
+ const struct alg_test_desc *test_desc;
+@@ -2212,24 +2267,26 @@ struct aead_extra_tests_ctx {
+ * here means the full ciphertext including the authentication tag. The
+ * authentication tag (and hence also the ciphertext) is assumed to be nonempty.
+ */
+-static void mutate_aead_message(struct aead_testvec *vec, bool aad_iv,
++static void mutate_aead_message(struct rnd_state *rng,
++ struct aead_testvec *vec, bool aad_iv,
+ unsigned int ivsize)
+ {
+ const unsigned int aad_tail_size = aad_iv ? ivsize : 0;
+ const unsigned int authsize = vec->clen - vec->plen;
+
+- if (get_random_u32_below(2) == 0 && vec->alen > aad_tail_size) {
++ if (prandom_bool(rng) && vec->alen > aad_tail_size) {
+ /* Mutate the AAD */
+- flip_random_bit((u8 *)vec->assoc, vec->alen - aad_tail_size);
+- if (get_random_u32_below(2) == 0)
++ flip_random_bit(rng, (u8 *)vec->assoc,
++ vec->alen - aad_tail_size);
++ if (prandom_bool(rng))
+ return;
+ }
+- if (get_random_u32_below(2) == 0) {
++ if (prandom_bool(rng)) {
+ /* Mutate auth tag (assuming it's at the end of ciphertext) */
+- flip_random_bit((u8 *)vec->ctext + vec->plen, authsize);
++ flip_random_bit(rng, (u8 *)vec->ctext + vec->plen, authsize);
+ } else {
+ /* Mutate any part of the ciphertext */
+- flip_random_bit((u8 *)vec->ctext, vec->clen);
++ flip_random_bit(rng, (u8 *)vec->ctext, vec->clen);
+ }
+ }
+
+@@ -2240,7 +2297,8 @@ static void mutate_aead_message(struct aead_testvec *vec, bool aad_iv,
+ */
+ #define MIN_COLLISION_FREE_AUTHSIZE 8
+
+-static void generate_aead_message(struct aead_request *req,
++static void generate_aead_message(struct rnd_state *rng,
++ struct aead_request *req,
+ const struct aead_test_suite *suite,
+ struct aead_testvec *vec,
+ bool prefer_inauthentic)
+@@ -2249,17 +2307,18 @@ static void generate_aead_message(struct aead_request *req,
+ const unsigned int ivsize = crypto_aead_ivsize(tfm);
+ const unsigned int authsize = vec->clen - vec->plen;
+ const bool inauthentic = (authsize >= MIN_COLLISION_FREE_AUTHSIZE) &&
+- (prefer_inauthentic || get_random_u32_below(4) == 0);
++ (prefer_inauthentic ||
++ prandom_u32_below(rng, 4) == 0);
+
+ /* Generate the AAD. */
+- generate_random_bytes((u8 *)vec->assoc, vec->alen);
++ generate_random_bytes(rng, (u8 *)vec->assoc, vec->alen);
+ if (suite->aad_iv && vec->alen >= ivsize)
+ /* Avoid implementation-defined behavior. */
+ memcpy((u8 *)vec->assoc + vec->alen - ivsize, vec->iv, ivsize);
+
+- if (inauthentic && get_random_u32_below(2) == 0) {
++ if (inauthentic && prandom_bool(rng)) {
+ /* Generate a random ciphertext. */
+- generate_random_bytes((u8 *)vec->ctext, vec->clen);
++ generate_random_bytes(rng, (u8 *)vec->ctext, vec->clen);
+ } else {
+ int i = 0;
+ struct scatterlist src[2], dst;
+@@ -2271,7 +2330,7 @@ static void generate_aead_message(struct aead_request *req,
+ if (vec->alen)
+ sg_set_buf(&src[i++], vec->assoc, vec->alen);
+ if (vec->plen) {
+- generate_random_bytes((u8 *)vec->ptext, vec->plen);
++ generate_random_bytes(rng, (u8 *)vec->ptext, vec->plen);
+ sg_set_buf(&src[i++], vec->ptext, vec->plen);
+ }
+ sg_init_one(&dst, vec->ctext, vec->alen + vec->clen);
+@@ -2291,7 +2350,7 @@ static void generate_aead_message(struct aead_request *req,
+ * Mutate the authentic (ciphertext, AAD) pair to get an
+ * inauthentic one.
+ */
+- mutate_aead_message(vec, suite->aad_iv, ivsize);
++ mutate_aead_message(rng, vec, suite->aad_iv, ivsize);
+ }
+ vec->novrfy = 1;
+ if (suite->einval_allowed)
+@@ -2305,7 +2364,8 @@ static void generate_aead_message(struct aead_request *req,
+ * If 'prefer_inauthentic' is true, then this function will generate inauthentic
+ * test vectors (i.e. vectors with 'vec->novrfy=1') more often.
+ */
+-static void generate_random_aead_testvec(struct aead_request *req,
++static void generate_random_aead_testvec(struct rnd_state *rng,
++ struct aead_request *req,
+ struct aead_testvec *vec,
+ const struct aead_test_suite *suite,
+ unsigned int maxkeysize,
+@@ -2321,18 +2381,18 @@ static void generate_random_aead_testvec(struct aead_request *req,
+
+ /* Key: length in [0, maxkeysize], but usually choose maxkeysize */
+ vec->klen = maxkeysize;
+- if (get_random_u32_below(4) == 0)
+- vec->klen = get_random_u32_below(maxkeysize + 1);
+- generate_random_bytes((u8 *)vec->key, vec->klen);
++ if (prandom_u32_below(rng, 4) == 0)
++ vec->klen = prandom_u32_below(rng, maxkeysize + 1);
++ generate_random_bytes(rng, (u8 *)vec->key, vec->klen);
+ vec->setkey_error = crypto_aead_setkey(tfm, vec->key, vec->klen);
+
+ /* IV */
+- generate_random_bytes((u8 *)vec->iv, ivsize);
++ generate_random_bytes(rng, (u8 *)vec->iv, ivsize);
+
+ /* Tag length: in [0, maxauthsize], but usually choose maxauthsize */
+ authsize = maxauthsize;
+- if (get_random_u32_below(4) == 0)
+- authsize = get_random_u32_below(maxauthsize + 1);
++ if (prandom_u32_below(rng, 4) == 0)
++ authsize = prandom_u32_below(rng, maxauthsize + 1);
+ if (prefer_inauthentic && authsize < MIN_COLLISION_FREE_AUTHSIZE)
+ authsize = MIN_COLLISION_FREE_AUTHSIZE;
+ if (WARN_ON(authsize > maxdatasize))
+@@ -2341,11 +2401,11 @@ static void generate_random_aead_testvec(struct aead_request *req,
+ vec->setauthsize_error = crypto_aead_setauthsize(tfm, authsize);
+
+ /* AAD, plaintext, and ciphertext lengths */
+- total_len = generate_random_length(maxdatasize);
+- if (get_random_u32_below(4) == 0)
++ total_len = generate_random_length(rng, maxdatasize);
++ if (prandom_u32_below(rng, 4) == 0)
+ vec->alen = 0;
+ else
+- vec->alen = generate_random_length(total_len);
++ vec->alen = generate_random_length(rng, total_len);
+ vec->plen = total_len - vec->alen;
+ vec->clen = vec->plen + authsize;
+
+@@ -2356,7 +2416,7 @@ static void generate_random_aead_testvec(struct aead_request *req,
+ vec->novrfy = 0;
+ vec->crypt_error = 0;
+ if (vec->setkey_error == 0 && vec->setauthsize_error == 0)
+- generate_aead_message(req, suite, vec, prefer_inauthentic);
++ generate_aead_message(rng, req, suite, vec, prefer_inauthentic);
+ snprintf(name, max_namelen,
+ "\"random: alen=%u plen=%u authsize=%u klen=%u novrfy=%d\"",
+ vec->alen, vec->plen, authsize, vec->klen, vec->novrfy);
+@@ -2368,7 +2428,7 @@ static void try_to_generate_inauthentic_testvec(
+ int i;
+
+ for (i = 0; i < 10; i++) {
+- generate_random_aead_testvec(ctx->req, &ctx->vec,
++ generate_random_aead_testvec(&ctx->rng, ctx->req, &ctx->vec,
+ &ctx->test_desc->suite.aead,
+ ctx->maxkeysize, ctx->maxdatasize,
+ ctx->vec_name,
+@@ -2399,7 +2459,8 @@ static int test_aead_inauthentic_inputs(struct aead_extra_tests_ctx *ctx)
+ */
+ try_to_generate_inauthentic_testvec(ctx);
+ if (ctx->vec.novrfy) {
+- generate_random_testvec_config(&ctx->cfg, ctx->cfgname,
++ generate_random_testvec_config(&ctx->rng, &ctx->cfg,
++ ctx->cfgname,
+ sizeof(ctx->cfgname));
+ err = test_aead_vec_cfg(DECRYPT, &ctx->vec,
+ ctx->vec_name, &ctx->cfg,
+@@ -2489,12 +2550,13 @@ static int test_aead_vs_generic_impl(struct aead_extra_tests_ctx *ctx)
+ * the other implementation against them.
+ */
+ for (i = 0; i < fuzz_iterations * 8; i++) {
+- generate_random_aead_testvec(generic_req, &ctx->vec,
++ generate_random_aead_testvec(&ctx->rng, generic_req, &ctx->vec,
+ &ctx->test_desc->suite.aead,
+ ctx->maxkeysize, ctx->maxdatasize,
+ ctx->vec_name,
+ sizeof(ctx->vec_name), false);
+- generate_random_testvec_config(&ctx->cfg, ctx->cfgname,
++ generate_random_testvec_config(&ctx->rng, &ctx->cfg,
++ ctx->cfgname,
+ sizeof(ctx->cfgname));
+ if (!ctx->vec.novrfy) {
+ err = test_aead_vec_cfg(ENCRYPT, &ctx->vec,
+@@ -2533,6 +2595,7 @@ static int test_aead_extra(const struct alg_test_desc *test_desc,
+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
++ init_rnd_state(&ctx->rng);
+ ctx->req = req;
+ ctx->tfm = crypto_aead_reqtfm(req);
+ ctx->test_desc = test_desc;
+@@ -2922,11 +2985,14 @@ static int test_skcipher_vec(int enc, const struct cipher_testvec *vec,
+
+ #ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS
+ if (!noextratests) {
++ struct rnd_state rng;
+ struct testvec_config cfg;
+ char cfgname[TESTVEC_CONFIG_NAMELEN];
+
++ init_rnd_state(&rng);
++
+ for (i = 0; i < fuzz_iterations; i++) {
+- generate_random_testvec_config(&cfg, cfgname,
++ generate_random_testvec_config(&rng, &cfg, cfgname,
+ sizeof(cfgname));
+ err = test_skcipher_vec_cfg(enc, vec, vec_name,
+ &cfg, req, tsgls);
+@@ -2944,7 +3010,8 @@ static int test_skcipher_vec(int enc, const struct cipher_testvec *vec,
+ * Generate a symmetric cipher test vector from the given implementation.
+ * Assumes the buffers in 'vec' were already allocated.
+ */
+-static void generate_random_cipher_testvec(struct skcipher_request *req,
++static void generate_random_cipher_testvec(struct rnd_state *rng,
++ struct skcipher_request *req,
+ struct cipher_testvec *vec,
+ unsigned int maxdatasize,
+ char *name, size_t max_namelen)
+@@ -2958,17 +3025,17 @@ static void generate_random_cipher_testvec(struct skcipher_request *req,
+
+ /* Key: length in [0, maxkeysize], but usually choose maxkeysize */
+ vec->klen = maxkeysize;
+- if (get_random_u32_below(4) == 0)
+- vec->klen = get_random_u32_below(maxkeysize + 1);
+- generate_random_bytes((u8 *)vec->key, vec->klen);
++ if (prandom_u32_below(rng, 4) == 0)
++ vec->klen = prandom_u32_below(rng, maxkeysize + 1);
++ generate_random_bytes(rng, (u8 *)vec->key, vec->klen);
+ vec->setkey_error = crypto_skcipher_setkey(tfm, vec->key, vec->klen);
+
+ /* IV */
+- generate_random_bytes((u8 *)vec->iv, ivsize);
++ generate_random_bytes(rng, (u8 *)vec->iv, ivsize);
+
+ /* Plaintext */
+- vec->len = generate_random_length(maxdatasize);
+- generate_random_bytes((u8 *)vec->ptext, vec->len);
++ vec->len = generate_random_length(rng, maxdatasize);
++ generate_random_bytes(rng, (u8 *)vec->ptext, vec->len);
+
+ /* If the key couldn't be set, no need to continue to encrypt. */
+ if (vec->setkey_error)
+@@ -3010,6 +3077,7 @@ static int test_skcipher_vs_generic_impl(const char *generic_driver,
+ const unsigned int maxdatasize = (2 * PAGE_SIZE) - TESTMGR_POISON_LEN;
+ const char *algname = crypto_skcipher_alg(tfm)->base.cra_name;
+ const char *driver = crypto_skcipher_driver_name(tfm);
++ struct rnd_state rng;
+ char _generic_driver[CRYPTO_MAX_ALG_NAME];
+ struct crypto_skcipher *generic_tfm = NULL;
+ struct skcipher_request *generic_req = NULL;
+@@ -3027,6 +3095,8 @@ static int test_skcipher_vs_generic_impl(const char *generic_driver,
+ if (strncmp(algname, "kw(", 3) == 0)
+ return 0;
+
++ init_rnd_state(&rng);
++
+ if (!generic_driver) { /* Use default naming convention? */
+ err = build_generic_driver_name(algname, _generic_driver);
+ if (err)
+@@ -3111,9 +3181,11 @@ static int test_skcipher_vs_generic_impl(const char *generic_driver,
+ }
+
+ for (i = 0; i < fuzz_iterations * 8; i++) {
+- generate_random_cipher_testvec(generic_req, &vec, maxdatasize,
++ generate_random_cipher_testvec(&rng, generic_req, &vec,
++ maxdatasize,
+ vec_name, sizeof(vec_name));
+- generate_random_testvec_config(cfg, cfgname, sizeof(cfgname));
++ generate_random_testvec_config(&rng, cfg, cfgname,
++ sizeof(cfgname));
+
+ err = test_skcipher_vec_cfg(ENCRYPT, &vec, vec_name,
+ cfg, req, tsgls);
+diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
+index 7c16bc15e7a14..837cd86d0316b 100644
+--- a/drivers/acpi/bus.c
++++ b/drivers/acpi/bus.c
+@@ -589,6 +589,7 @@ static void acpi_device_remove_notify_handler(struct acpi_device *device,
+ acpi_remove_notify_handler(device->handle, type,
+ acpi_notify_device);
+ }
++ acpi_os_wait_events_complete();
+ }
+
+ /* Handle events targeting \_SB device (at present only graceful shutdown) */
+diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
+index 23507d29f0006..c2c70139c4f1d 100644
+--- a/drivers/acpi/power.c
++++ b/drivers/acpi/power.c
+@@ -23,6 +23,7 @@
+
+ #define pr_fmt(fmt) "ACPI: PM: " fmt
+
++#include <linux/dmi.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
+@@ -1022,6 +1023,21 @@ void acpi_resume_power_resources(void)
+ }
+ #endif
+
++static const struct dmi_system_id dmi_leave_unused_power_resources_on[] = {
++ {
++ /*
++ * The Toshiba Click Mini has a CPR3 power-resource which must
++ * be on for the touchscreen to work, but which is not in any
++ * _PR? lists. The other 2 affected power-resources are no-ops.
++ */
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE Click Mini L9W-B"),
++ },
++ },
++ {}
++};
++
+ /**
+ * acpi_turn_off_unused_power_resources - Turn off power resources not in use.
+ */
+@@ -1029,6 +1045,9 @@ void acpi_turn_off_unused_power_resources(void)
+ {
+ struct acpi_power_resource *resource;
+
++ if (dmi_check_system(dmi_leave_unused_power_resources_on))
++ return;
++
+ mutex_lock(&power_resource_list_lock);
+
+ list_for_each_entry_reverse(resource, &acpi_power_resource_list, list_node) {
+diff --git a/drivers/acpi/processor_pdc.c b/drivers/acpi/processor_pdc.c
+index 8c3f82c9fff35..18fb04523f93b 100644
+--- a/drivers/acpi/processor_pdc.c
++++ b/drivers/acpi/processor_pdc.c
+@@ -14,6 +14,8 @@
+ #include <linux/acpi.h>
+ #include <acpi/processor.h>
+
++#include <xen/xen.h>
++
+ #include "internal.h"
+
+ static bool __init processor_physically_present(acpi_handle handle)
+@@ -47,6 +49,15 @@ static bool __init processor_physically_present(acpi_handle handle)
+ return false;
+ }
+
++ if (xen_initial_domain())
++ /*
++ * When running as a Xen dom0 the number of processors Linux
++ * sees can be different from the real number of processors on
++ * the system, and we still need to execute _PDC for all of
++ * them.
++ */
++ return xen_processor_present(acpi_id);
++
+ type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0;
+ cpuid = acpi_get_cpuid(handle, type, acpi_id);
+
+diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
+index e85729fc481fd..295744fe7c920 100644
+--- a/drivers/acpi/video_detect.c
++++ b/drivers/acpi/video_detect.c
+@@ -299,20 +299,6 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
+ },
+ },
+
+- /*
+- * Older models with nvidia GPU which need acpi_video backlight
+- * control and where the old nvidia binary driver series does not
+- * call acpi_video_register_backlight().
+- */
+- {
+- .callback = video_detect_force_video,
+- /* ThinkPad W530 */
+- .matches = {
+- DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+- DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad W530"),
+- },
+- },
+-
+ /*
+ * These models have a working acpi_video backlight control, and using
+ * native backlight causes a regression where backlight does not work
+diff --git a/drivers/acpi/viot.c b/drivers/acpi/viot.c
+index ed752cbbe6362..c8025921c129b 100644
+--- a/drivers/acpi/viot.c
++++ b/drivers/acpi/viot.c
+@@ -328,6 +328,7 @@ static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
+ {
+ u32 epid;
+ struct viot_endpoint *ep;
++ struct device *aliased_dev = data;
+ u32 domain_nr = pci_domain_nr(pdev->bus);
+
+ list_for_each_entry(ep, &viot_pci_ranges, list) {
+@@ -338,7 +339,7 @@ static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
+ epid = ((domain_nr - ep->segment_start) << 16) +
+ dev_id - ep->bdf_start + ep->endpoint_id;
+
+- return viot_dev_iommu_init(&pdev->dev, ep->viommu,
++ return viot_dev_iommu_init(aliased_dev, ep->viommu,
+ epid);
+ }
+ }
+@@ -372,7 +373,7 @@ int viot_iommu_configure(struct device *dev)
+ {
+ if (dev_is_pci(dev))
+ return pci_for_each_dma_alias(to_pci_dev(dev),
+- viot_pci_dev_iommu_init, NULL);
++ viot_pci_dev_iommu_init, dev);
+ else if (dev_is_platform(dev))
+ return viot_mmio_dev_iommu_init(to_platform_device(dev));
+ return -ENODEV;
+diff --git a/drivers/base/cacheinfo.c b/drivers/base/cacheinfo.c
+index f05acf3c16c6b..88205a240fb2e 100644
+--- a/drivers/base/cacheinfo.c
++++ b/drivers/base/cacheinfo.c
+@@ -38,11 +38,10 @@ static inline bool cache_leaves_are_shared(struct cacheinfo *this_leaf,
+ {
+ /*
+ * For non DT/ACPI systems, assume unique level 1 caches,
+- * system-wide shared caches for all other levels. This will be used
+- * only if arch specific code has not populated shared_cpu_map
++ * system-wide shared caches for all other levels.
+ */
+ if (!(IS_ENABLED(CONFIG_OF) || IS_ENABLED(CONFIG_ACPI)))
+- return !(this_leaf->level == 1);
++ return (this_leaf->level != 1) && (sib_leaf->level != 1);
+
+ if ((sib_leaf->attributes & CACHE_ID) &&
+ (this_leaf->attributes & CACHE_ID))
+diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
+index 4c98849577d4e..7af8e33735a36 100644
+--- a/drivers/base/cpu.c
++++ b/drivers/base/cpu.c
+@@ -487,7 +487,8 @@ static const struct attribute_group *cpu_root_attr_groups[] = {
+ bool cpu_is_hotpluggable(unsigned int cpu)
+ {
+ struct device *dev = get_cpu_device(cpu);
+- return dev && container_of(dev, struct cpu, dev)->hotpluggable;
++ return dev && container_of(dev, struct cpu, dev)->hotpluggable
++ && tick_nohz_cpu_hotpluggable(cpu);
+ }
+ EXPORT_SYMBOL_GPL(cpu_is_hotpluggable);
+
+diff --git a/drivers/base/platform.c b/drivers/base/platform.c
+index 968f3d71eeab2..a4938d1c8fe1d 100644
+--- a/drivers/base/platform.c
++++ b/drivers/base/platform.c
+@@ -1416,7 +1416,9 @@ static void platform_remove(struct device *_dev)
+ struct platform_driver *drv = to_platform_driver(_dev->driver);
+ struct platform_device *dev = to_platform_device(_dev);
+
+- if (drv->remove) {
++ if (drv->remove_new) {
++ drv->remove_new(dev);
++ } else if (drv->remove) {
+ int ret = drv->remove(dev);
+
+ if (ret)
+diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
+index 757f4692b5bd8..1fc815be12d01 100644
+--- a/drivers/block/drbd/drbd_receiver.c
++++ b/drivers/block/drbd/drbd_receiver.c
+@@ -1283,7 +1283,7 @@ static void one_flush_endio(struct bio *bio)
+ static void submit_one_flush(struct drbd_device *device, struct issue_flush_context *ctx)
+ {
+ struct bio *bio = bio_alloc(device->ldev->backing_bdev, 0,
+- REQ_OP_FLUSH | REQ_PREFLUSH, GFP_NOIO);
++ REQ_OP_WRITE | REQ_PREFLUSH, GFP_NOIO);
+ struct one_flush_context *octx = kmalloc(sizeof(*octx), GFP_NOIO);
+
+ if (!octx) {
+diff --git a/drivers/bluetooth/btsdio.c b/drivers/bluetooth/btsdio.c
+index 02893600db390..795be33f2892d 100644
+--- a/drivers/bluetooth/btsdio.c
++++ b/drivers/bluetooth/btsdio.c
+@@ -354,7 +354,6 @@ static void btsdio_remove(struct sdio_func *func)
+
+ BT_DBG("func %p", func);
+
+- cancel_work_sync(&data->work);
+ if (!data)
+ return;
+
+diff --git a/drivers/bus/mhi/host/boot.c b/drivers/bus/mhi/host/boot.c
+index 1c69feee17030..d2a19b07ccb88 100644
+--- a/drivers/bus/mhi/host/boot.c
++++ b/drivers/bus/mhi/host/boot.c
+@@ -391,6 +391,7 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl)
+ {
+ const struct firmware *firmware = NULL;
+ struct device *dev = &mhi_cntrl->mhi_dev->dev;
++ enum mhi_pm_state new_state;
+ const char *fw_name;
+ void *buf;
+ dma_addr_t dma_addr;
+@@ -508,14 +509,18 @@ error_ready_state:
+ }
+
+ error_fw_load:
+- mhi_cntrl->pm_state = MHI_PM_FW_DL_ERR;
+- wake_up_all(&mhi_cntrl->state_event);
++ write_lock_irq(&mhi_cntrl->pm_lock);
++ new_state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_FW_DL_ERR);
++ write_unlock_irq(&mhi_cntrl->pm_lock);
++ if (new_state == MHI_PM_FW_DL_ERR)
++ wake_up_all(&mhi_cntrl->state_event);
+ }
+
+ int mhi_download_amss_image(struct mhi_controller *mhi_cntrl)
+ {
+ struct image_info *image_info = mhi_cntrl->fbc_image;
+ struct device *dev = &mhi_cntrl->mhi_dev->dev;
++ enum mhi_pm_state new_state;
+ int ret;
+
+ if (!image_info)
+@@ -526,8 +531,11 @@ int mhi_download_amss_image(struct mhi_controller *mhi_cntrl)
+ &image_info->mhi_buf[image_info->entries - 1]);
+ if (ret) {
+ dev_err(dev, "MHI did not load AMSS, ret:%d\n", ret);
+- mhi_cntrl->pm_state = MHI_PM_FW_DL_ERR;
+- wake_up_all(&mhi_cntrl->state_event);
++ write_lock_irq(&mhi_cntrl->pm_lock);
++ new_state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_FW_DL_ERR);
++ write_unlock_irq(&mhi_cntrl->pm_lock);
++ if (new_state == MHI_PM_FW_DL_ERR)
++ wake_up_all(&mhi_cntrl->state_event);
+ }
+
+ return ret;
+diff --git a/drivers/bus/mhi/host/init.c b/drivers/bus/mhi/host/init.c
+index bf672de351315..04fbccff65ac2 100644
+--- a/drivers/bus/mhi/host/init.c
++++ b/drivers/bus/mhi/host/init.c
+@@ -516,6 +516,12 @@ int mhi_init_mmio(struct mhi_controller *mhi_cntrl)
+ return -EIO;
+ }
+
++ if (val >= mhi_cntrl->reg_len - (8 * MHI_DEV_WAKE_DB)) {
++ dev_err(dev, "CHDB offset: 0x%x is out of range: 0x%zx\n",
++ val, mhi_cntrl->reg_len - (8 * MHI_DEV_WAKE_DB));
++ return -ERANGE;
++ }
++
+ /* Setup wake db */
+ mhi_cntrl->wake_db = base + val + (8 * MHI_DEV_WAKE_DB);
+ mhi_cntrl->wake_set = false;
+@@ -532,6 +538,12 @@ int mhi_init_mmio(struct mhi_controller *mhi_cntrl)
+ return -EIO;
+ }
+
++ if (val >= mhi_cntrl->reg_len - (8 * mhi_cntrl->total_ev_rings)) {
++ dev_err(dev, "ERDB offset: 0x%x is out of range: 0x%zx\n",
++ val, mhi_cntrl->reg_len - (8 * mhi_cntrl->total_ev_rings));
++ return -ERANGE;
++ }
++
+ /* Setup event db address for each ev_ring */
+ mhi_event = mhi_cntrl->mhi_event;
+ for (i = 0; i < mhi_cntrl->total_ev_rings; i++, val += 8, mhi_event++) {
+diff --git a/drivers/bus/mhi/host/main.c b/drivers/bus/mhi/host/main.c
+index df0fbfee7b78b..0c3a009ed9bb0 100644
+--- a/drivers/bus/mhi/host/main.c
++++ b/drivers/bus/mhi/host/main.c
+@@ -503,7 +503,7 @@ irqreturn_t mhi_intvec_threaded_handler(int irq_number, void *priv)
+ }
+ write_unlock_irq(&mhi_cntrl->pm_lock);
+
+- if (pm_state != MHI_PM_SYS_ERR_DETECT || ee == mhi_cntrl->ee)
++ if (pm_state != MHI_PM_SYS_ERR_DETECT)
+ goto exit_intvec;
+
+ switch (ee) {
+diff --git a/drivers/bus/mhi/host/pci_generic.c b/drivers/bus/mhi/host/pci_generic.c
+index f39657f71483c..cb5c067e78be1 100644
+--- a/drivers/bus/mhi/host/pci_generic.c
++++ b/drivers/bus/mhi/host/pci_generic.c
+@@ -344,8 +344,6 @@ static const struct mhi_channel_config mhi_foxconn_sdx55_channels[] = {
+ MHI_CHANNEL_CONFIG_DL(13, "MBIM", 32, 0),
+ MHI_CHANNEL_CONFIG_UL(32, "DUN", 32, 0),
+ MHI_CHANNEL_CONFIG_DL(33, "DUN", 32, 0),
+- MHI_CHANNEL_CONFIG_UL(92, "DUN2", 32, 1),
+- MHI_CHANNEL_CONFIG_DL(93, "DUN2", 32, 1),
+ MHI_CHANNEL_CONFIG_HW_UL(100, "IP_HW0_MBIM", 128, 2),
+ MHI_CHANNEL_CONFIG_HW_DL(101, "IP_HW0_MBIM", 128, 3),
+ };
+diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig
+index b6c0d35fc1a5f..f4adc6feb3b22 100644
+--- a/drivers/char/ipmi/Kconfig
++++ b/drivers/char/ipmi/Kconfig
+@@ -162,7 +162,8 @@ config IPMI_KCS_BMC_SERIO
+
+ config ASPEED_BT_IPMI_BMC
+ depends on ARCH_ASPEED || COMPILE_TEST
+- depends on REGMAP && REGMAP_MMIO && MFD_SYSCON
++ depends on MFD_SYSCON
++ select REGMAP_MMIO
+ tristate "BT IPMI bmc driver"
+ help
+ Provides a driver for the BT (Block Transfer) IPMI interface
+diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c
+index f49d2c2ef3cfd..273ad74d0b4cf 100644
+--- a/drivers/char/ipmi/ipmi_ssif.c
++++ b/drivers/char/ipmi/ipmi_ssif.c
+@@ -564,8 +564,10 @@ static void retry_timeout(struct timer_list *t)
+
+ if (waiting)
+ start_get(ssif_info);
+- if (resend)
++ if (resend) {
+ start_resend(ssif_info);
++ ssif_inc_stat(ssif_info, send_retries);
++ }
+ }
+
+ static void watch_timeout(struct timer_list *t)
+@@ -792,9 +794,9 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result,
+ } else if (data[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2
+ || data[1] != IPMI_GET_MSG_FLAGS_CMD) {
+ /*
+- * Don't abort here, maybe it was a queued
+- * response to a previous command.
++ * Recv error response, give up.
+ */
++ ssif_info->ssif_state = SSIF_IDLE;
+ ipmi_ssif_unlock_cond(ssif_info, flags);
+ dev_warn(&ssif_info->client->dev,
+ "Invalid response getting flags: %x %x\n",
+diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
+index c467eeae99733..bd6ebc66a55a9 100644
+--- a/drivers/char/tpm/tpm-chip.c
++++ b/drivers/char/tpm/tpm-chip.c
+@@ -683,7 +683,8 @@ EXPORT_SYMBOL_GPL(tpm_chip_register);
+ void tpm_chip_unregister(struct tpm_chip *chip)
+ {
+ tpm_del_legacy_sysfs(chip);
+- if (IS_ENABLED(CONFIG_HW_RANDOM_TPM) && !tpm_is_firmware_upgrade(chip))
++ if (IS_ENABLED(CONFIG_HW_RANDOM_TPM) && !tpm_is_firmware_upgrade(chip) &&
++ !tpm_amd_is_rng_defective(chip))
+ hwrng_unregister(&chip->hwrng);
+ tpm_bios_log_teardown(chip);
+ if (chip->flags & TPM_CHIP_FLAG_TPM2 && !tpm_is_firmware_upgrade(chip))
+diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
+index 3f98e587b3e84..eecfbd7e97867 100644
+--- a/drivers/char/tpm/tpm_tis_core.c
++++ b/drivers/char/tpm/tpm_tis_core.c
+@@ -136,16 +136,27 @@ static bool check_locality(struct tpm_chip *chip, int l)
+ return false;
+ }
+
+-static int release_locality(struct tpm_chip *chip, int l)
++static int __tpm_tis_relinquish_locality(struct tpm_tis_data *priv, int l)
++{
++ tpm_tis_write8(priv, TPM_ACCESS(l), TPM_ACCESS_ACTIVE_LOCALITY);
++
++ return 0;
++}
++
++static int tpm_tis_relinquish_locality(struct tpm_chip *chip, int l)
+ {
+ struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
+
+- tpm_tis_write8(priv, TPM_ACCESS(l), TPM_ACCESS_ACTIVE_LOCALITY);
++ mutex_lock(&priv->locality_count_mutex);
++ priv->locality_count--;
++ if (priv->locality_count == 0)
++ __tpm_tis_relinquish_locality(priv, l);
++ mutex_unlock(&priv->locality_count_mutex);
+
+ return 0;
+ }
+
+-static int request_locality(struct tpm_chip *chip, int l)
++static int __tpm_tis_request_locality(struct tpm_chip *chip, int l)
+ {
+ struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
+ unsigned long stop, timeout;
+@@ -186,6 +197,20 @@ again:
+ return -1;
+ }
+
++static int tpm_tis_request_locality(struct tpm_chip *chip, int l)
++{
++ struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
++ int ret = 0;
++
++ mutex_lock(&priv->locality_count_mutex);
++ if (priv->locality_count == 0)
++ ret = __tpm_tis_request_locality(chip, l);
++ if (!ret)
++ priv->locality_count++;
++ mutex_unlock(&priv->locality_count_mutex);
++ return ret;
++}
++
+ static u8 tpm_tis_status(struct tpm_chip *chip)
+ {
+ struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
+@@ -652,7 +677,7 @@ static int probe_itpm(struct tpm_chip *chip)
+ if (vendor != TPM_VID_INTEL)
+ return 0;
+
+- if (request_locality(chip, 0) != 0)
++ if (tpm_tis_request_locality(chip, 0) != 0)
+ return -EBUSY;
+
+ rc = tpm_tis_send_data(chip, cmd_getticks, len);
+@@ -673,7 +698,7 @@ static int probe_itpm(struct tpm_chip *chip)
+
+ out:
+ tpm_tis_ready(chip);
+- release_locality(chip, priv->locality);
++ tpm_tis_relinquish_locality(chip, priv->locality);
+
+ return rc;
+ }
+@@ -732,25 +757,17 @@ static irqreturn_t tis_int_handler(int dummy, void *dev_id)
+ return IRQ_HANDLED;
+ }
+
+-static int tpm_tis_gen_interrupt(struct tpm_chip *chip)
++static void tpm_tis_gen_interrupt(struct tpm_chip *chip)
+ {
+ const char *desc = "attempting to generate an interrupt";
+ u32 cap2;
+ cap_t cap;
+ int ret;
+
+- ret = request_locality(chip, 0);
+- if (ret < 0)
+- return ret;
+-
+ if (chip->flags & TPM_CHIP_FLAG_TPM2)
+ ret = tpm2_get_tpm_pt(chip, 0x100, &cap2, desc);
+ else
+ ret = tpm1_getcap(chip, TPM_CAP_PROP_TIS_TIMEOUT, &cap, desc, 0);
+-
+- release_locality(chip, 0);
+-
+- return ret;
+ }
+
+ /* Register the IRQ and issue a command that will cause an interrupt. If an
+@@ -773,52 +790,55 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask,
+ }
+ priv->irq = irq;
+
++ rc = tpm_tis_request_locality(chip, 0);
++ if (rc < 0)
++ return rc;
++
+ rc = tpm_tis_read8(priv, TPM_INT_VECTOR(priv->locality),
+ &original_int_vec);
+- if (rc < 0)
++ if (rc < 0) {
++ tpm_tis_relinquish_locality(chip, priv->locality);
+ return rc;
++ }
+
+ rc = tpm_tis_write8(priv, TPM_INT_VECTOR(priv->locality), irq);
+ if (rc < 0)
+- return rc;
++ goto restore_irqs;
+
+ rc = tpm_tis_read32(priv, TPM_INT_STATUS(priv->locality), &int_status);
+ if (rc < 0)
+- return rc;
++ goto restore_irqs;
+
+ /* Clear all existing */
+ rc = tpm_tis_write32(priv, TPM_INT_STATUS(priv->locality), int_status);
+ if (rc < 0)
+- return rc;
+-
++ goto restore_irqs;
+ /* Turn on */
+ rc = tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality),
+ intmask | TPM_GLOBAL_INT_ENABLE);
+ if (rc < 0)
+- return rc;
++ goto restore_irqs;
+
+ priv->irq_tested = false;
+
+ /* Generate an interrupt by having the core call through to
+ * tpm_tis_send
+ */
+- rc = tpm_tis_gen_interrupt(chip);
+- if (rc < 0)
+- return rc;
++ tpm_tis_gen_interrupt(chip);
+
++restore_irqs:
+ /* tpm_tis_send will either confirm the interrupt is working or it
+ * will call disable_irq which undoes all of the above.
+ */
+ if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) {
+- rc = tpm_tis_write8(priv, original_int_vec,
+- TPM_INT_VECTOR(priv->locality));
+- if (rc < 0)
+- return rc;
+-
+- return 1;
++ tpm_tis_write8(priv, original_int_vec,
++ TPM_INT_VECTOR(priv->locality));
++ rc = -1;
+ }
+
+- return 0;
++ tpm_tis_relinquish_locality(chip, priv->locality);
++
++ return rc;
+ }
+
+ /* Try to find the IRQ the TPM is using. This is for legacy x86 systems that
+@@ -932,8 +952,8 @@ static const struct tpm_class_ops tpm_tis = {
+ .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
+ .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
+ .req_canceled = tpm_tis_req_canceled,
+- .request_locality = request_locality,
+- .relinquish_locality = release_locality,
++ .request_locality = tpm_tis_request_locality,
++ .relinquish_locality = tpm_tis_relinquish_locality,
+ .clk_enable = tpm_tis_clkrun_enable,
+ };
+
+@@ -967,6 +987,8 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
+ priv->timeout_min = TPM_TIMEOUT_USECS_MIN;
+ priv->timeout_max = TPM_TIMEOUT_USECS_MAX;
+ priv->phy_ops = phy_ops;
++ priv->locality_count = 0;
++ mutex_init(&priv->locality_count_mutex);
+
+ dev_set_drvdata(&chip->dev, priv);
+
+@@ -1013,14 +1035,14 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
+ TPM_INTF_DATA_AVAIL_INT | TPM_INTF_STS_VALID_INT;
+ intmask &= ~TPM_GLOBAL_INT_ENABLE;
+
+- rc = request_locality(chip, 0);
++ rc = tpm_tis_request_locality(chip, 0);
+ if (rc < 0) {
+ rc = -ENODEV;
+ goto out_err;
+ }
+
+ tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
+- release_locality(chip, 0);
++ tpm_tis_relinquish_locality(chip, 0);
+
+ rc = tpm_chip_start(chip);
+ if (rc)
+@@ -1080,13 +1102,13 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
+ * proper timeouts for the driver.
+ */
+
+- rc = request_locality(chip, 0);
++ rc = tpm_tis_request_locality(chip, 0);
+ if (rc < 0)
+ goto out_err;
+
+ rc = tpm_get_timeouts(chip);
+
+- release_locality(chip, 0);
++ tpm_tis_relinquish_locality(chip, 0);
+
+ if (rc) {
+ dev_err(dev, "Could not get TPM timeouts and durations\n");
+@@ -1094,17 +1116,21 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
+ goto out_err;
+ }
+
+- if (irq) {
++ if (irq)
+ tpm_tis_probe_irq_single(chip, intmask, IRQF_SHARED,
+ irq);
+- if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) {
+- dev_err(&chip->dev, FW_BUG
++ else
++ tpm_tis_probe_irq(chip, intmask);
++
++ if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) {
++ dev_err(&chip->dev, FW_BUG
+ "TPM interrupt not working, polling instead\n");
+
+- disable_interrupts(chip);
+- }
+- } else {
+- tpm_tis_probe_irq(chip, intmask);
++ rc = tpm_tis_request_locality(chip, 0);
++ if (rc < 0)
++ goto out_err;
++ disable_interrupts(chip);
++ tpm_tis_relinquish_locality(chip, 0);
+ }
+ }
+
+@@ -1165,28 +1191,27 @@ int tpm_tis_resume(struct device *dev)
+ struct tpm_chip *chip = dev_get_drvdata(dev);
+ int ret;
+
++ ret = tpm_tis_request_locality(chip, 0);
++ if (ret < 0)
++ return ret;
++
+ if (chip->flags & TPM_CHIP_FLAG_IRQ)
+ tpm_tis_reenable_interrupts(chip);
+
+ ret = tpm_pm_resume(dev);
+ if (ret)
+- return ret;
++ goto out;
+
+ /*
+ * TPM 1.2 requires self-test on resume. This function actually returns
+ * an error code but for unknown reason it isn't handled.
+ */
+- if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) {
+- ret = request_locality(chip, 0);
+- if (ret < 0)
+- return ret;
+-
++ if (!(chip->flags & TPM_CHIP_FLAG_TPM2))
+ tpm1_do_selftest(chip);
++out:
++ tpm_tis_relinquish_locality(chip, 0);
+
+- release_locality(chip, 0);
+- }
+-
+- return 0;
++ return ret;
+ }
+ EXPORT_SYMBOL_GPL(tpm_tis_resume);
+ #endif
+diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h
+index b68479e0de10f..1d51d5168fb6e 100644
+--- a/drivers/char/tpm/tpm_tis_core.h
++++ b/drivers/char/tpm/tpm_tis_core.h
+@@ -91,6 +91,8 @@ enum tpm_tis_flags {
+
+ struct tpm_tis_data {
+ u16 manufacturer_id;
++ struct mutex locality_count_mutex;
++ unsigned int locality_count;
+ int locality;
+ int irq;
+ bool irq_tested;
+diff --git a/drivers/clk/at91/clk-sam9x60-pll.c b/drivers/clk/at91/clk-sam9x60-pll.c
+index d757003004cbb..0882ed01d5c27 100644
+--- a/drivers/clk/at91/clk-sam9x60-pll.c
++++ b/drivers/clk/at91/clk-sam9x60-pll.c
+@@ -668,7 +668,7 @@ sam9x60_clk_register_frac_pll(struct regmap *regmap, spinlock_t *lock,
+
+ ret = sam9x60_frac_pll_compute_mul_frac(&frac->core, FCORE_MIN,
+ parent_rate, true);
+- if (ret <= 0) {
++ if (ret < 0) {
+ hw = ERR_PTR(ret);
+ goto free;
+ }
+diff --git a/drivers/clk/clk-conf.c b/drivers/clk/clk-conf.c
+index 2ef819606c417..1a4e6340f95ce 100644
+--- a/drivers/clk/clk-conf.c
++++ b/drivers/clk/clk-conf.c
+@@ -33,9 +33,12 @@ static int __set_clk_parents(struct device_node *node, bool clk_supplier)
+ else
+ return rc;
+ }
+- if (clkspec.np == node && !clk_supplier)
++ if (clkspec.np == node && !clk_supplier) {
++ of_node_put(clkspec.np);
+ return 0;
++ }
+ pclk = of_clk_get_from_provider(&clkspec);
++ of_node_put(clkspec.np);
+ if (IS_ERR(pclk)) {
+ if (PTR_ERR(pclk) != -EPROBE_DEFER)
+ pr_warn("clk: couldn't get parent clock %d for %pOF\n",
+@@ -48,10 +51,12 @@ static int __set_clk_parents(struct device_node *node, bool clk_supplier)
+ if (rc < 0)
+ goto err;
+ if (clkspec.np == node && !clk_supplier) {
++ of_node_put(clkspec.np);
+ rc = 0;
+ goto err;
+ }
+ clk = of_clk_get_from_provider(&clkspec);
++ of_node_put(clkspec.np);
+ if (IS_ERR(clk)) {
+ if (PTR_ERR(clk) != -EPROBE_DEFER)
+ pr_warn("clk: couldn't get assigned clock %d for %pOF\n",
+@@ -93,10 +98,13 @@ static int __set_clk_rates(struct device_node *node, bool clk_supplier)
+ else
+ return rc;
+ }
+- if (clkspec.np == node && !clk_supplier)
++ if (clkspec.np == node && !clk_supplier) {
++ of_node_put(clkspec.np);
+ return 0;
++ }
+
+ clk = of_clk_get_from_provider(&clkspec);
++ of_node_put(clkspec.np);
+ if (IS_ERR(clk)) {
+ if (PTR_ERR(clk) != -EPROBE_DEFER)
+ pr_warn("clk: couldn't get clock %d for %pOF\n",
+diff --git a/drivers/clk/imx/clk-fracn-gppll.c b/drivers/clk/imx/clk-fracn-gppll.c
+index a2aaa14fc1aef..f6674110a88e0 100644
+--- a/drivers/clk/imx/clk-fracn-gppll.c
++++ b/drivers/clk/imx/clk-fracn-gppll.c
+@@ -15,6 +15,7 @@
+ #include "clk.h"
+
+ #define PLL_CTRL 0x0
++#define HW_CTRL_SEL BIT(16)
+ #define CLKMUX_BYPASS BIT(2)
+ #define CLKMUX_EN BIT(1)
+ #define POWERUP_MASK BIT(0)
+@@ -60,18 +61,20 @@ struct clk_fracn_gppll {
+ };
+
+ /*
+- * Fvco = Fref * (MFI + MFN / MFD)
+- * Fout = Fvco / (rdiv * odiv)
++ * Fvco = (Fref / rdiv) * (MFI + MFN / MFD)
++ * Fout = Fvco / odiv
++ * The (Fref / rdiv) should be in range 20MHz to 40MHz
++ * The Fvco should be in range 2.5Ghz to 5Ghz
+ */
+ static const struct imx_fracn_gppll_rate_table fracn_tbl[] = {
+- PLL_FRACN_GP(650000000U, 81, 0, 1, 0, 3),
++ PLL_FRACN_GP(650000000U, 162, 50, 100, 0, 6),
+ PLL_FRACN_GP(594000000U, 198, 0, 1, 0, 8),
+- PLL_FRACN_GP(560000000U, 70, 0, 1, 0, 3),
+- PLL_FRACN_GP(498000000U, 83, 0, 1, 0, 4),
++ PLL_FRACN_GP(560000000U, 140, 0, 1, 0, 6),
++ PLL_FRACN_GP(498000000U, 166, 0, 1, 0, 8),
+ PLL_FRACN_GP(484000000U, 121, 0, 1, 0, 6),
+ PLL_FRACN_GP(445333333U, 167, 0, 1, 0, 9),
+- PLL_FRACN_GP(400000000U, 50, 0, 1, 0, 3),
+- PLL_FRACN_GP(393216000U, 81, 92, 100, 0, 5)
++ PLL_FRACN_GP(400000000U, 200, 0, 1, 0, 12),
++ PLL_FRACN_GP(393216000U, 163, 84, 100, 0, 10)
+ };
+
+ struct imx_fracn_gppll_clk imx_fracn_gppll = {
+@@ -191,6 +194,11 @@ static int clk_fracn_gppll_set_rate(struct clk_hw *hw, unsigned long drate,
+
+ rate = imx_get_pll_settings(pll, drate);
+
++ /* Hardware control select disable. PLL is control by register */
++ tmp = readl_relaxed(pll->base + PLL_CTRL);
++ tmp &= ~HW_CTRL_SEL;
++ writel_relaxed(tmp, pll->base + PLL_CTRL);
++
+ /* Disable output */
+ tmp = readl_relaxed(pll->base + PLL_CTRL);
+ tmp &= ~CLKMUX_EN;
+diff --git a/drivers/clk/imx/clk-imx8ulp.c b/drivers/clk/imx/clk-imx8ulp.c
+index 8eb1af2d64298..ca0e4a3aa454e 100644
+--- a/drivers/clk/imx/clk-imx8ulp.c
++++ b/drivers/clk/imx/clk-imx8ulp.c
+@@ -200,8 +200,8 @@ static int imx8ulp_clk_cgc1_init(struct platform_device *pdev)
+ clks[IMX8ULP_CLK_NIC_AD_DIVPLAT] = imx_clk_hw_divider_flags("nic_ad_divplat", "nic_sel", base + 0x34, 21, 6, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
+ clks[IMX8ULP_CLK_NIC_PER_DIVPLAT] = imx_clk_hw_divider_flags("nic_per_divplat", "nic_ad_divplat", base + 0x34, 14, 6, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
+ clks[IMX8ULP_CLK_XBAR_AD_DIVPLAT] = imx_clk_hw_divider_flags("xbar_ad_divplat", "nic_ad_divplat", base + 0x38, 14, 6, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
+- clks[IMX8ULP_CLK_XBAR_DIVBUS] = imx_clk_hw_divider_flags("xbar_divbus", "nic_ad_divplat", base + 0x38, 7, 6, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
+- clks[IMX8ULP_CLK_XBAR_AD_SLOW] = imx_clk_hw_divider_flags("xbar_ad_slow", "nic_ad_divplat", base + 0x38, 0, 6, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
++ clks[IMX8ULP_CLK_XBAR_DIVBUS] = imx_clk_hw_divider_flags("xbar_divbus", "xbar_ad_divplat", base + 0x38, 7, 6, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
++ clks[IMX8ULP_CLK_XBAR_AD_SLOW] = imx_clk_hw_divider_flags("xbar_ad_slow", "xbar_divbus", base + 0x38, 0, 6, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
+
+ clks[IMX8ULP_CLK_SOSC_DIV1_GATE] = imx_clk_hw_gate_dis("sosc_div1_gate", "sosc", base + 0x108, 7);
+ clks[IMX8ULP_CLK_SOSC_DIV2_GATE] = imx_clk_hw_gate_dis("sosc_div2_gate", "sosc", base + 0x108, 15);
+diff --git a/drivers/clk/mediatek/clk-mt2701-aud.c b/drivers/clk/mediatek/clk-mt2701-aud.c
+index 6ba398eb7df91..4287bd3f545ee 100644
+--- a/drivers/clk/mediatek/clk-mt2701-aud.c
++++ b/drivers/clk/mediatek/clk-mt2701-aud.c
+@@ -15,41 +15,17 @@
+
+ #include <dt-bindings/clock/mt2701-clk.h>
+
+-#define GATE_AUDIO0(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &audio0_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr, \
+- }
++#define GATE_AUDIO0(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &audio0_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr)
+
+-#define GATE_AUDIO1(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &audio1_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr, \
+- }
++#define GATE_AUDIO1(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &audio1_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr)
+
+-#define GATE_AUDIO2(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &audio2_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr, \
+- }
++#define GATE_AUDIO2(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &audio2_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr)
+
+-#define GATE_AUDIO3(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &audio3_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr, \
+- }
++#define GATE_AUDIO3(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &audio3_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr)
+
+ static const struct mtk_gate_regs audio0_cg_regs = {
+ .set_ofs = 0x0,
+diff --git a/drivers/clk/mediatek/clk-mt2701-bdp.c b/drivers/clk/mediatek/clk-mt2701-bdp.c
+index 435ed4819d563..b0f0572079452 100644
+--- a/drivers/clk/mediatek/clk-mt2701-bdp.c
++++ b/drivers/clk/mediatek/clk-mt2701-bdp.c
+@@ -24,23 +24,11 @@ static const struct mtk_gate_regs bdp1_cg_regs = {
+ .sta_ofs = 0x0110,
+ };
+
+-#define GATE_BDP0(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &bdp0_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr_inv, \
+- }
++#define GATE_BDP0(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &bdp0_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
+
+-#define GATE_BDP1(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &bdp1_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr_inv, \
+- }
++#define GATE_BDP1(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &bdp1_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
+
+ static const struct mtk_gate bdp_clks[] = {
+ GATE_BDP0(CLK_BDP_BRG_BA, "brg_baclk", "mm_sel", 0),
+diff --git a/drivers/clk/mediatek/clk-mt2701-eth.c b/drivers/clk/mediatek/clk-mt2701-eth.c
+index edf1e2ed2b596..601358748750e 100644
+--- a/drivers/clk/mediatek/clk-mt2701-eth.c
++++ b/drivers/clk/mediatek/clk-mt2701-eth.c
+@@ -16,14 +16,8 @@ static const struct mtk_gate_regs eth_cg_regs = {
+ .sta_ofs = 0x0030,
+ };
+
+-#define GATE_ETH(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &eth_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr_inv, \
+- }
++#define GATE_ETH(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &eth_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
+
+ static const struct mtk_gate eth_clks[] = {
+ GATE_ETH(CLK_ETHSYS_HSDMA, "hsdma_clk", "ethif_sel", 5),
+diff --git a/drivers/clk/mediatek/clk-mt2701-g3d.c b/drivers/clk/mediatek/clk-mt2701-g3d.c
+index 1458109d99d94..8d1fc8e3336eb 100644
+--- a/drivers/clk/mediatek/clk-mt2701-g3d.c
++++ b/drivers/clk/mediatek/clk-mt2701-g3d.c
+@@ -16,14 +16,8 @@
+
+ #include <dt-bindings/clock/mt2701-clk.h>
+
+-#define GATE_G3D(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &g3d_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
++#define GATE_G3D(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &g3d_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+ static const struct mtk_gate_regs g3d_cg_regs = {
+ .sta_ofs = 0x0,
+diff --git a/drivers/clk/mediatek/clk-mt2701-hif.c b/drivers/clk/mediatek/clk-mt2701-hif.c
+index 434cbbe8c0371..edeeb033a2350 100644
+--- a/drivers/clk/mediatek/clk-mt2701-hif.c
++++ b/drivers/clk/mediatek/clk-mt2701-hif.c
+@@ -16,14 +16,8 @@ static const struct mtk_gate_regs hif_cg_regs = {
+ .sta_ofs = 0x0030,
+ };
+
+-#define GATE_HIF(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &hif_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr_inv, \
+- }
++#define GATE_HIF(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &hif_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
+
+ static const struct mtk_gate hif_clks[] = {
+ GATE_HIF(CLK_HIFSYS_USB0PHY, "usb0_phy_clk", "ethpll_500m_ck", 21),
+diff --git a/drivers/clk/mediatek/clk-mt2701-img.c b/drivers/clk/mediatek/clk-mt2701-img.c
+index 7e53deb7f9905..eb172473f0755 100644
+--- a/drivers/clk/mediatek/clk-mt2701-img.c
++++ b/drivers/clk/mediatek/clk-mt2701-img.c
+@@ -18,14 +18,8 @@ static const struct mtk_gate_regs img_cg_regs = {
+ .sta_ofs = 0x0000,
+ };
+
+-#define GATE_IMG(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &img_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
++#define GATE_IMG(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &img_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+ static const struct mtk_gate img_clks[] = {
+ GATE_IMG(CLK_IMG_SMI_COMM, "img_smi_comm", "mm_sel", 0),
+diff --git a/drivers/clk/mediatek/clk-mt2701-mm.c b/drivers/clk/mediatek/clk-mt2701-mm.c
+index 9ea7abad99d23..eb069f3bc9a2b 100644
+--- a/drivers/clk/mediatek/clk-mt2701-mm.c
++++ b/drivers/clk/mediatek/clk-mt2701-mm.c
+@@ -24,23 +24,11 @@ static const struct mtk_gate_regs disp1_cg_regs = {
+ .sta_ofs = 0x0110,
+ };
+
+-#define GATE_DISP0(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &disp0_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
++#define GATE_DISP0(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &disp0_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+-#define GATE_DISP1(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &disp1_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
++#define GATE_DISP1(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &disp1_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+ static const struct mtk_gate mm_clks[] = {
+ GATE_DISP0(CLK_MM_SMI_COMMON, "mm_smi_comm", "mm_sel", 0),
+diff --git a/drivers/clk/mediatek/clk-mt2701-vdec.c b/drivers/clk/mediatek/clk-mt2701-vdec.c
+index d3089da0ab62e..0f07c5d731df6 100644
+--- a/drivers/clk/mediatek/clk-mt2701-vdec.c
++++ b/drivers/clk/mediatek/clk-mt2701-vdec.c
+@@ -24,23 +24,11 @@ static const struct mtk_gate_regs vdec1_cg_regs = {
+ .sta_ofs = 0x0008,
+ };
+
+-#define GATE_VDEC0(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &vdec0_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr_inv, \
+- }
++#define GATE_VDEC0(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &vdec0_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
+
+-#define GATE_VDEC1(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &vdec1_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr_inv, \
+- }
++#define GATE_VDEC1(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &vdec1_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
+
+ static const struct mtk_gate vdec_clks[] = {
+ GATE_VDEC0(CLK_VDEC_CKGEN, "vdec_cken", "vdec_sel", 0),
+diff --git a/drivers/clk/mediatek/clk-mt2701.c b/drivers/clk/mediatek/clk-mt2701.c
+index 9b442af37e672..1c3a93143dc5e 100644
+--- a/drivers/clk/mediatek/clk-mt2701.c
++++ b/drivers/clk/mediatek/clk-mt2701.c
+@@ -636,14 +636,8 @@ static const struct mtk_gate_regs top_aud_cg_regs = {
+ .sta_ofs = 0x012C,
+ };
+
+-#define GATE_TOP_AUD(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &top_aud_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr, \
+- }
++#define GATE_TOP_AUD(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &top_aud_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr)
+
+ static const struct mtk_gate top_clks[] = {
+ GATE_TOP_AUD(CLK_TOP_AUD_48K_TIMING, "a1sys_hp_ck", "aud_mux1_div",
+@@ -701,14 +695,8 @@ static const struct mtk_gate_regs infra_cg_regs = {
+ .sta_ofs = 0x0048,
+ };
+
+-#define GATE_ICG(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &infra_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
++#define GATE_ICG(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &infra_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+ static const struct mtk_gate infra_clks[] = {
+ GATE_ICG(CLK_INFRA_DBG, "dbgclk", "axi_sel", 0),
+@@ -822,23 +810,11 @@ static const struct mtk_gate_regs peri1_cg_regs = {
+ .sta_ofs = 0x001c,
+ };
+
+-#define GATE_PERI0(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &peri0_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
++#define GATE_PERI0(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &peri0_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+-#define GATE_PERI1(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &peri1_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
++#define GATE_PERI1(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &peri1_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+ static const struct mtk_gate peri_clks[] = {
+ GATE_PERI0(CLK_PERI_USB0_MCU, "usb0_mcu_ck", "axi_sel", 31),
+diff --git a/drivers/clk/mediatek/clk-mt2712-bdp.c b/drivers/clk/mediatek/clk-mt2712-bdp.c
+index 684d03e9f6de1..5e668651dd901 100644
+--- a/drivers/clk/mediatek/clk-mt2712-bdp.c
++++ b/drivers/clk/mediatek/clk-mt2712-bdp.c
+@@ -18,14 +18,8 @@ static const struct mtk_gate_regs bdp_cg_regs = {
+ .sta_ofs = 0x100,
+ };
+
+-#define GATE_BDP(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &bdp_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr, \
+- }
++#define GATE_BDP(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &bdp_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr)
+
+ static const struct mtk_gate bdp_clks[] = {
+ GATE_BDP(CLK_BDP_BRIDGE_B, "bdp_bridge_b", "mm_sel", 0),
+diff --git a/drivers/clk/mediatek/clk-mt2712-img.c b/drivers/clk/mediatek/clk-mt2712-img.c
+index 335049cdc856c..3ffa51384e6b2 100644
+--- a/drivers/clk/mediatek/clk-mt2712-img.c
++++ b/drivers/clk/mediatek/clk-mt2712-img.c
+@@ -18,14 +18,8 @@ static const struct mtk_gate_regs img_cg_regs = {
+ .sta_ofs = 0x0,
+ };
+
+-#define GATE_IMG(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &img_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr, \
+- }
++#define GATE_IMG(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &img_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr)
+
+ static const struct mtk_gate img_clks[] = {
+ GATE_IMG(CLK_IMG_SMI_LARB2, "img_smi_larb2", "mm_sel", 0),
+diff --git a/drivers/clk/mediatek/clk-mt2712-jpgdec.c b/drivers/clk/mediatek/clk-mt2712-jpgdec.c
+index 07ba7c5e80aff..8c768d5ce24d5 100644
+--- a/drivers/clk/mediatek/clk-mt2712-jpgdec.c
++++ b/drivers/clk/mediatek/clk-mt2712-jpgdec.c
+@@ -18,14 +18,8 @@ static const struct mtk_gate_regs jpgdec_cg_regs = {
+ .sta_ofs = 0x0,
+ };
+
+-#define GATE_JPGDEC(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &jpgdec_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr_inv, \
+- }
++#define GATE_JPGDEC(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &jpgdec_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
+
+ static const struct mtk_gate jpgdec_clks[] = {
+ GATE_JPGDEC(CLK_JPGDEC_JPGDEC1, "jpgdec_jpgdec1", "jpgdec_sel", 0),
+diff --git a/drivers/clk/mediatek/clk-mt2712-mfg.c b/drivers/clk/mediatek/clk-mt2712-mfg.c
+index 42f8cf3ecf4cb..8949315c2dd20 100644
+--- a/drivers/clk/mediatek/clk-mt2712-mfg.c
++++ b/drivers/clk/mediatek/clk-mt2712-mfg.c
+@@ -18,14 +18,8 @@ static const struct mtk_gate_regs mfg_cg_regs = {
+ .sta_ofs = 0x0,
+ };
+
+-#define GATE_MFG(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &mfg_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
++#define GATE_MFG(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &mfg_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+ static const struct mtk_gate mfg_clks[] = {
+ GATE_MFG(CLK_MFG_BG3D, "mfg_bg3d", "mfg_sel", 0),
+diff --git a/drivers/clk/mediatek/clk-mt2712-mm.c b/drivers/clk/mediatek/clk-mt2712-mm.c
+index 7d44b09b8a0a7..ad6daa8f28a83 100644
+--- a/drivers/clk/mediatek/clk-mt2712-mm.c
++++ b/drivers/clk/mediatek/clk-mt2712-mm.c
+@@ -30,32 +30,14 @@ static const struct mtk_gate_regs mm2_cg_regs = {
+ .sta_ofs = 0x220,
+ };
+
+-#define GATE_MM0(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &mm0_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
+-
+-#define GATE_MM1(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &mm1_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
+-
+-#define GATE_MM2(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &mm2_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
++#define GATE_MM0(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &mm0_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
++
++#define GATE_MM1(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &mm1_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
++
++#define GATE_MM2(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &mm2_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+ static const struct mtk_gate mm_clks[] = {
+ /* MM0 */
+diff --git a/drivers/clk/mediatek/clk-mt2712-vdec.c b/drivers/clk/mediatek/clk-mt2712-vdec.c
+index 6296ed5c5b555..572290dd43c87 100644
+--- a/drivers/clk/mediatek/clk-mt2712-vdec.c
++++ b/drivers/clk/mediatek/clk-mt2712-vdec.c
+@@ -24,23 +24,11 @@ static const struct mtk_gate_regs vdec1_cg_regs = {
+ .sta_ofs = 0x8,
+ };
+
+-#define GATE_VDEC0(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &vdec0_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr_inv, \
+- }
++#define GATE_VDEC0(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &vdec0_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
+
+-#define GATE_VDEC1(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &vdec1_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr_inv, \
+- }
++#define GATE_VDEC1(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &vdec1_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
+
+ static const struct mtk_gate vdec_clks[] = {
+ /* VDEC0 */
+diff --git a/drivers/clk/mediatek/clk-mt2712-venc.c b/drivers/clk/mediatek/clk-mt2712-venc.c
+index b9bfc35de629c..9588eb03016eb 100644
+--- a/drivers/clk/mediatek/clk-mt2712-venc.c
++++ b/drivers/clk/mediatek/clk-mt2712-venc.c
+@@ -18,14 +18,8 @@ static const struct mtk_gate_regs venc_cg_regs = {
+ .sta_ofs = 0x0,
+ };
+
+-#define GATE_VENC(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &venc_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr_inv, \
+- }
++#define GATE_VENC(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &venc_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
+
+ static const struct mtk_gate venc_clks[] = {
+ GATE_VENC(CLK_VENC_SMI_COMMON_CON, "venc_smi", "mm_sel", 0),
+diff --git a/drivers/clk/mediatek/clk-mt2712.c b/drivers/clk/mediatek/clk-mt2712.c
+index 56980dd6c2eaf..d6c2cc183b1a1 100644
+--- a/drivers/clk/mediatek/clk-mt2712.c
++++ b/drivers/clk/mediatek/clk-mt2712.c
+@@ -958,23 +958,11 @@ static const struct mtk_gate_regs top1_cg_regs = {
+ .sta_ofs = 0x424,
+ };
+
+-#define GATE_TOP0(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &top0_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr, \
+- }
++#define GATE_TOP0(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &top0_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr)
+
+-#define GATE_TOP1(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &top1_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr_inv, \
+- }
++#define GATE_TOP1(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &top1_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
+
+ static const struct mtk_gate top_clks[] = {
+ /* TOP0 */
+@@ -998,14 +986,8 @@ static const struct mtk_gate_regs infra_cg_regs = {
+ .sta_ofs = 0x48,
+ };
+
+-#define GATE_INFRA(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &infra_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
++#define GATE_INFRA(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &infra_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+ static const struct mtk_gate infra_clks[] = {
+ GATE_INFRA(CLK_INFRA_DBGCLK, "infra_dbgclk", "axi_sel", 0),
+@@ -1035,32 +1017,14 @@ static const struct mtk_gate_regs peri2_cg_regs = {
+ .sta_ofs = 0x42c,
+ };
+
+-#define GATE_PERI0(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &peri0_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
++#define GATE_PERI0(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &peri0_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+-#define GATE_PERI1(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &peri1_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
++#define GATE_PERI1(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &peri1_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+-#define GATE_PERI2(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &peri2_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr_inv, \
+- }
++#define GATE_PERI2(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &peri2_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
+
+ static const struct mtk_gate peri_clks[] = {
+ /* PERI0 */
+@@ -1283,15 +1247,25 @@ static int clk_mt2712_apmixed_probe(struct platform_device *pdev)
+ struct device_node *node = pdev->dev.of_node;
+
+ clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK);
++ if (!clk_data)
++ return -ENOMEM;
+
+- mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
++ r = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
++ if (r)
++ goto free_clk_data;
+
+ r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
++ if (r) {
++ dev_err(&pdev->dev, "Cannot register clock provider: %d\n", r);
++ goto unregister_plls;
++ }
+
+- if (r != 0)
+- pr_err("%s(): could not register clock provider: %d\n",
+- __func__, r);
++ return 0;
+
++unregister_plls:
++ mtk_clk_unregister_plls(plls, ARRAY_SIZE(plls), clk_data);
++free_clk_data:
++ mtk_free_clk_data(clk_data);
+ return r;
+ }
+
+diff --git a/drivers/clk/mediatek/clk-mt6765-audio.c b/drivers/clk/mediatek/clk-mt6765-audio.c
+index 0aa6c0d352ca5..5682e0302eee2 100644
+--- a/drivers/clk/mediatek/clk-mt6765-audio.c
++++ b/drivers/clk/mediatek/clk-mt6765-audio.c
+@@ -24,23 +24,11 @@ static const struct mtk_gate_regs audio1_cg_regs = {
+ .sta_ofs = 0x4,
+ };
+
+-#define GATE_AUDIO0(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &audio0_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr, \
+- }
++#define GATE_AUDIO0(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &audio0_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr)
+
+-#define GATE_AUDIO1(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &audio1_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr, \
+- }
++#define GATE_AUDIO1(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &audio1_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr)
+
+ static const struct mtk_gate audio_clks[] = {
+ /* AUDIO0 */
+diff --git a/drivers/clk/mediatek/clk-mt6765-cam.c b/drivers/clk/mediatek/clk-mt6765-cam.c
+index 25f2bef38126e..6e7d192c19cb0 100644
+--- a/drivers/clk/mediatek/clk-mt6765-cam.c
++++ b/drivers/clk/mediatek/clk-mt6765-cam.c
+@@ -18,14 +18,8 @@ static const struct mtk_gate_regs cam_cg_regs = {
+ .sta_ofs = 0x0,
+ };
+
+-#define GATE_CAM(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &cam_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
++#define GATE_CAM(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &cam_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+ static const struct mtk_gate cam_clks[] = {
+ GATE_CAM(CLK_CAM_LARB3, "cam_larb3", "mm_ck", 0),
+diff --git a/drivers/clk/mediatek/clk-mt6765-img.c b/drivers/clk/mediatek/clk-mt6765-img.c
+index a62303ef4f41d..cfbc907988aff 100644
+--- a/drivers/clk/mediatek/clk-mt6765-img.c
++++ b/drivers/clk/mediatek/clk-mt6765-img.c
+@@ -18,14 +18,8 @@ static const struct mtk_gate_regs img_cg_regs = {
+ .sta_ofs = 0x0,
+ };
+
+-#define GATE_IMG(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &img_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
++#define GATE_IMG(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &img_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+ static const struct mtk_gate img_clks[] = {
+ GATE_IMG(CLK_IMG_LARB2, "img_larb2", "mm_ck", 0),
+diff --git a/drivers/clk/mediatek/clk-mt6765-mipi0a.c b/drivers/clk/mediatek/clk-mt6765-mipi0a.c
+index 25c829fc38661..f2b9dc8084801 100644
+--- a/drivers/clk/mediatek/clk-mt6765-mipi0a.c
++++ b/drivers/clk/mediatek/clk-mt6765-mipi0a.c
+@@ -18,14 +18,8 @@ static const struct mtk_gate_regs mipi0a_cg_regs = {
+ .sta_ofs = 0x80,
+ };
+
+-#define GATE_MIPI0A(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &mipi0a_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr_inv, \
+- }
++#define GATE_MIPI0A(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &mipi0a_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
+
+ static const struct mtk_gate mipi0a_clks[] = {
+ GATE_MIPI0A(CLK_MIPI0A_CSR_CSI_EN_0A,
+diff --git a/drivers/clk/mediatek/clk-mt6765-mm.c b/drivers/clk/mediatek/clk-mt6765-mm.c
+index bda774668a361..a4570c9dbefa5 100644
+--- a/drivers/clk/mediatek/clk-mt6765-mm.c
++++ b/drivers/clk/mediatek/clk-mt6765-mm.c
+@@ -18,14 +18,8 @@ static const struct mtk_gate_regs mm_cg_regs = {
+ .sta_ofs = 0x100,
+ };
+
+-#define GATE_MM(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &mm_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
++#define GATE_MM(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &mm_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+ static const struct mtk_gate mm_clks[] = {
+ /* MM */
+diff --git a/drivers/clk/mediatek/clk-mt6765-vcodec.c b/drivers/clk/mediatek/clk-mt6765-vcodec.c
+index 2bc1fbde87da9..75d72b9b4032c 100644
+--- a/drivers/clk/mediatek/clk-mt6765-vcodec.c
++++ b/drivers/clk/mediatek/clk-mt6765-vcodec.c
+@@ -18,14 +18,8 @@ static const struct mtk_gate_regs venc_cg_regs = {
+ .sta_ofs = 0x0,
+ };
+
+-#define GATE_VENC(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &venc_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr_inv, \
+- }
++#define GATE_VENC(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &venc_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
+
+ static const struct mtk_gate venc_clks[] = {
+ GATE_VENC(CLK_VENC_SET0_LARB, "venc_set0_larb", "mm_ck", 0),
+diff --git a/drivers/clk/mediatek/clk-mt6765.c b/drivers/clk/mediatek/clk-mt6765.c
+index e9b9e67297335..665981fc411f5 100644
+--- a/drivers/clk/mediatek/clk-mt6765.c
++++ b/drivers/clk/mediatek/clk-mt6765.c
+@@ -483,32 +483,14 @@ static const struct mtk_gate_regs top2_cg_regs = {
+ .sta_ofs = 0x320,
+ };
+
+-#define GATE_TOP0(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &top0_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr, \
+- }
++#define GATE_TOP0(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &top0_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr)
+
+-#define GATE_TOP1(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &top1_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr_inv, \
+- }
++#define GATE_TOP1(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &top1_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
+
+-#define GATE_TOP2(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &top2_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr, \
+- }
++#define GATE_TOP2(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &top2_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr)
+
+ static const struct mtk_gate top_clks[] = {
+ /* TOP0 */
+@@ -559,41 +541,17 @@ static const struct mtk_gate_regs ifr5_cg_regs = {
+ .sta_ofs = 0xc8,
+ };
+
+-#define GATE_IFR2(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &ifr2_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
++#define GATE_IFR2(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &ifr2_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+-#define GATE_IFR3(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &ifr3_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
++#define GATE_IFR3(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &ifr3_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+-#define GATE_IFR4(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &ifr4_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
++#define GATE_IFR4(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &ifr4_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+-#define GATE_IFR5(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &ifr5_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
++#define GATE_IFR5(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &ifr5_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+ static const struct mtk_gate ifr_clks[] = {
+ /* INFRA_TOPAXI */
+@@ -674,14 +632,8 @@ static const struct mtk_gate_regs apmixed_cg_regs = {
+ .sta_ofs = 0x14,
+ };
+
+-#define GATE_APMIXED(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &apmixed_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr_inv, \
+- }
++#define GATE_APMIXED(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &apmixed_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
+
+ static const struct mtk_gate apmixed_clks[] = {
+ /* AUDIO0 */
+diff --git a/drivers/clk/mediatek/clk-mt6797-img.c b/drivers/clk/mediatek/clk-mt6797-img.c
+index 7c6a53fbb8be6..06441393478f6 100644
+--- a/drivers/clk/mediatek/clk-mt6797-img.c
++++ b/drivers/clk/mediatek/clk-mt6797-img.c
+@@ -16,14 +16,8 @@ static const struct mtk_gate_regs img_cg_regs = {
+ .sta_ofs = 0x0000,
+ };
+
+-#define GATE_IMG(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &img_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
++#define GATE_IMG(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &img_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+ static const struct mtk_gate img_clks[] = {
+ GATE_IMG(CLK_IMG_FDVT, "img_fdvt", "mm_sel", 11),
+diff --git a/drivers/clk/mediatek/clk-mt6797-mm.c b/drivers/clk/mediatek/clk-mt6797-mm.c
+index 0846011fc8943..99a63f46642fa 100644
+--- a/drivers/clk/mediatek/clk-mt6797-mm.c
++++ b/drivers/clk/mediatek/clk-mt6797-mm.c
+@@ -23,23 +23,11 @@ static const struct mtk_gate_regs mm1_cg_regs = {
+ .sta_ofs = 0x0110,
+ };
+
+-#define GATE_MM0(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &mm0_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+-}
++#define GATE_MM0(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &mm0_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+-#define GATE_MM1(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &mm1_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+-}
++#define GATE_MM1(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &mm1_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+ static const struct mtk_gate mm_clks[] = {
+ GATE_MM0(CLK_MM_SMI_COMMON, "mm_smi_common", "mm_sel", 0),
+diff --git a/drivers/clk/mediatek/clk-mt6797-vdec.c b/drivers/clk/mediatek/clk-mt6797-vdec.c
+index 6120fccc859f1..8622ddd87a5bb 100644
+--- a/drivers/clk/mediatek/clk-mt6797-vdec.c
++++ b/drivers/clk/mediatek/clk-mt6797-vdec.c
+@@ -24,23 +24,11 @@ static const struct mtk_gate_regs vdec1_cg_regs = {
+ .sta_ofs = 0x0008,
+ };
+
+-#define GATE_VDEC0(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &vdec0_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr_inv, \
+-}
++#define GATE_VDEC0(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &vdec0_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
+
+-#define GATE_VDEC1(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &vdec1_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr_inv, \
+-}
++#define GATE_VDEC1(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &vdec1_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
+
+ static const struct mtk_gate vdec_clks[] = {
+ GATE_VDEC0(CLK_VDEC_CKEN_ENG, "vdec_cken_eng", "vdec_sel", 8),
+diff --git a/drivers/clk/mediatek/clk-mt6797-venc.c b/drivers/clk/mediatek/clk-mt6797-venc.c
+index 834d3834d2bbc..928d611a476e4 100644
+--- a/drivers/clk/mediatek/clk-mt6797-venc.c
++++ b/drivers/clk/mediatek/clk-mt6797-venc.c
+@@ -18,14 +18,8 @@ static const struct mtk_gate_regs venc_cg_regs = {
+ .sta_ofs = 0x0000,
+ };
+
+-#define GATE_VENC(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &venc_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr_inv, \
+- }
++#define GATE_VENC(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &venc_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
+
+ static const struct mtk_gate venc_clks[] = {
+ GATE_VENC(CLK_VENC_0, "venc_0", "mm_sel", 0),
+diff --git a/drivers/clk/mediatek/clk-mt6797.c b/drivers/clk/mediatek/clk-mt6797.c
+index b89f325a4b9b8..78339cb35beb0 100644
+--- a/drivers/clk/mediatek/clk-mt6797.c
++++ b/drivers/clk/mediatek/clk-mt6797.c
+@@ -420,40 +420,22 @@ static const struct mtk_gate_regs infra2_cg_regs = {
+ .sta_ofs = 0x00b0,
+ };
+
+-#define GATE_ICG0(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &infra0_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+-}
++#define GATE_ICG0(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &infra0_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+-#define GATE_ICG1(_id, _name, _parent, _shift) \
+- GATE_ICG1_FLAGS(_id, _name, _parent, _shift, 0)
++#define GATE_ICG1(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &infra1_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+-#define GATE_ICG1_FLAGS(_id, _name, _parent, _shift, _flags) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &infra1_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- .flags = _flags, \
+-}
++#define GATE_ICG1_FLAGS(_id, _name, _parent, _shift, _flags) \
++ GATE_MTK_FLAGS(_id, _name, _parent, &infra1_cg_regs, _shift, \
++ &mtk_clk_gate_ops_setclr, _flags)
+
+-#define GATE_ICG2(_id, _name, _parent, _shift) \
+- GATE_ICG2_FLAGS(_id, _name, _parent, _shift, 0)
++#define GATE_ICG2(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &infra2_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+-#define GATE_ICG2_FLAGS(_id, _name, _parent, _shift, _flags) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &infra2_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- .flags = _flags, \
+-}
++#define GATE_ICG2_FLAGS(_id, _name, _parent, _shift, _flags) \
++ GATE_MTK_FLAGS(_id, _name, _parent, &infra2_cg_regs, _shift, \
++ &mtk_clk_gate_ops_setclr, _flags)
+
+ /*
+ * Clock gates dramc and dramc_b are needed by the DRAM controller.
+diff --git a/drivers/clk/mediatek/clk-mt7622-aud.c b/drivers/clk/mediatek/clk-mt7622-aud.c
+index 9f2e5aa7b5d9b..b17731fa11445 100644
+--- a/drivers/clk/mediatek/clk-mt7622-aud.c
++++ b/drivers/clk/mediatek/clk-mt7622-aud.c
+@@ -16,41 +16,17 @@
+
+ #include <dt-bindings/clock/mt7622-clk.h>
+
+-#define GATE_AUDIO0(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &audio0_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr, \
+- }
++#define GATE_AUDIO0(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &audio0_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr)
+
+-#define GATE_AUDIO1(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &audio1_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr, \
+- }
++#define GATE_AUDIO1(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &audio1_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr)
+
+-#define GATE_AUDIO2(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &audio2_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr, \
+- }
++#define GATE_AUDIO2(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &audio2_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr)
+
+-#define GATE_AUDIO3(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &audio3_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr, \
+- }
++#define GATE_AUDIO3(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &audio3_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr)
+
+ static const struct mtk_gate_regs audio0_cg_regs = {
+ .set_ofs = 0x0,
+diff --git a/drivers/clk/mediatek/clk-mt7622-eth.c b/drivers/clk/mediatek/clk-mt7622-eth.c
+index 43de0477d5d99..a60190e834186 100644
+--- a/drivers/clk/mediatek/clk-mt7622-eth.c
++++ b/drivers/clk/mediatek/clk-mt7622-eth.c
+@@ -16,14 +16,8 @@
+
+ #include <dt-bindings/clock/mt7622-clk.h>
+
+-#define GATE_ETH(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &eth_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr_inv, \
+- }
++#define GATE_ETH(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &eth_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
+
+ static const struct mtk_gate_regs eth_cg_regs = {
+ .set_ofs = 0x30,
+@@ -45,14 +39,8 @@ static const struct mtk_gate_regs sgmii_cg_regs = {
+ .sta_ofs = 0xE4,
+ };
+
+-#define GATE_SGMII(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &sgmii_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr_inv, \
+- }
++#define GATE_SGMII(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &sgmii_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
+
+ static const struct mtk_gate sgmii_clks[] = {
+ GATE_SGMII(CLK_SGMII_TX250M_EN, "sgmii_tx250m_en",
+diff --git a/drivers/clk/mediatek/clk-mt7622-hif.c b/drivers/clk/mediatek/clk-mt7622-hif.c
+index 67e96231dd25b..55baa6d06a205 100644
+--- a/drivers/clk/mediatek/clk-mt7622-hif.c
++++ b/drivers/clk/mediatek/clk-mt7622-hif.c
+@@ -16,23 +16,11 @@
+
+ #include <dt-bindings/clock/mt7622-clk.h>
+
+-#define GATE_PCIE(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &pcie_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr_inv, \
+- }
++#define GATE_PCIE(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &pcie_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
+
+-#define GATE_SSUSB(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &ssusb_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr_inv, \
+- }
++#define GATE_SSUSB(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &ssusb_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
+
+ static const struct mtk_gate_regs pcie_cg_regs = {
+ .set_ofs = 0x30,
+diff --git a/drivers/clk/mediatek/clk-mt7622.c b/drivers/clk/mediatek/clk-mt7622.c
+index 3b55f8641fae0..eebbb87906930 100644
+--- a/drivers/clk/mediatek/clk-mt7622.c
++++ b/drivers/clk/mediatek/clk-mt7622.c
+@@ -50,59 +50,28 @@
+ _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift, \
+ NULL, "clkxtal")
+
+-#define GATE_APMIXED(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &apmixed_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr_inv, \
+- }
++#define GATE_APMIXED_AO(_id, _name, _parent, _shift) \
++ GATE_MTK_FLAGS(_id, _name, _parent, &apmixed_cg_regs, _shift, \
++ &mtk_clk_gate_ops_no_setclr_inv, CLK_IS_CRITICAL)
+
+-#define GATE_INFRA(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &infra_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
++#define GATE_INFRA(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &infra_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+-#define GATE_TOP0(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &top0_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr, \
+- }
++#define GATE_TOP0(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &top0_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr)
+
+-#define GATE_TOP1(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &top1_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr, \
+- }
++#define GATE_TOP1(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &top1_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr)
+
+-#define GATE_PERI0(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &peri0_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
++#define GATE_PERI0(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &peri0_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+-#define GATE_PERI1(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &peri1_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
++#define GATE_PERI0_AO(_id, _name, _parent, _shift) \
++ GATE_MTK_FLAGS(_id, _name, _parent, &peri0_cg_regs, _shift, \
++ &mtk_clk_gate_ops_setclr, CLK_IS_CRITICAL)
++
++#define GATE_PERI1(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &peri1_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+ static DEFINE_SPINLOCK(mt7622_clk_lock);
+
+@@ -350,7 +319,7 @@ static const struct mtk_pll_data plls[] = {
+ };
+
+ static const struct mtk_gate apmixed_clks[] = {
+- GATE_APMIXED(CLK_APMIXED_MAIN_CORE_EN, "main_core_en", "mainpll", 5),
++ GATE_APMIXED_AO(CLK_APMIXED_MAIN_CORE_EN, "main_core_en", "mainpll", 5),
+ };
+
+ static const struct mtk_gate infra_clks[] = {
+@@ -485,7 +454,7 @@ static const struct mtk_gate peri_clks[] = {
+ GATE_PERI0(CLK_PERI_AP_DMA_PD, "peri_ap_dma_pd", "axi_sel", 12),
+ GATE_PERI0(CLK_PERI_MSDC30_0_PD, "peri_msdc30_0", "msdc30_0_sel", 13),
+ GATE_PERI0(CLK_PERI_MSDC30_1_PD, "peri_msdc30_1", "msdc30_1_sel", 14),
+- GATE_PERI0(CLK_PERI_UART0_PD, "peri_uart0_pd", "axi_sel", 17),
++ GATE_PERI0_AO(CLK_PERI_UART0_PD, "peri_uart0_pd", "axi_sel", 17),
+ GATE_PERI0(CLK_PERI_UART1_PD, "peri_uart1_pd", "axi_sel", 18),
+ GATE_PERI0(CLK_PERI_UART2_PD, "peri_uart2_pd", "axi_sel", 19),
+ GATE_PERI0(CLK_PERI_UART3_PD, "peri_uart3_pd", "axi_sel", 20),
+@@ -513,12 +482,12 @@ static struct mtk_composite infra_muxes[] = {
+
+ static struct mtk_composite top_muxes[] = {
+ /* CLK_CFG_0 */
+- MUX_GATE(CLK_TOP_AXI_SEL, "axi_sel", axi_parents,
+- 0x040, 0, 3, 7),
+- MUX_GATE(CLK_TOP_MEM_SEL, "mem_sel", mem_parents,
+- 0x040, 8, 1, 15),
+- MUX_GATE(CLK_TOP_DDRPHYCFG_SEL, "ddrphycfg_sel", ddrphycfg_parents,
+- 0x040, 16, 1, 23),
++ MUX_GATE_FLAGS(CLK_TOP_AXI_SEL, "axi_sel", axi_parents,
++ 0x040, 0, 3, 7, CLK_IS_CRITICAL),
++ MUX_GATE_FLAGS(CLK_TOP_MEM_SEL, "mem_sel", mem_parents,
++ 0x040, 8, 1, 15, CLK_IS_CRITICAL),
++ MUX_GATE_FLAGS(CLK_TOP_DDRPHYCFG_SEL, "ddrphycfg_sel", ddrphycfg_parents,
++ 0x040, 16, 1, 23, CLK_IS_CRITICAL),
+ MUX_GATE(CLK_TOP_ETH_SEL, "eth_sel", eth_parents,
+ 0x040, 24, 3, 31),
+
+@@ -655,10 +624,6 @@ static int mtk_topckgen_init(struct platform_device *pdev)
+ mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks),
+ clk_data);
+
+- clk_prepare_enable(clk_data->hws[CLK_TOP_AXI_SEL]->clk);
+- clk_prepare_enable(clk_data->hws[CLK_TOP_MEM_SEL]->clk);
+- clk_prepare_enable(clk_data->hws[CLK_TOP_DDRPHYCFG_SEL]->clk);
+-
+ return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+ }
+
+@@ -701,9 +666,6 @@ static int mtk_apmixedsys_init(struct platform_device *pdev)
+ mtk_clk_register_gates(node, apmixed_clks,
+ ARRAY_SIZE(apmixed_clks), clk_data);
+
+- clk_prepare_enable(clk_data->hws[CLK_APMIXED_ARMPLL]->clk);
+- clk_prepare_enable(clk_data->hws[CLK_APMIXED_MAIN_CORE_EN]->clk);
+-
+ return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+ }
+
+@@ -730,8 +692,6 @@ static int mtk_pericfg_init(struct platform_device *pdev)
+ if (r)
+ return r;
+
+- clk_prepare_enable(clk_data->hws[CLK_PERI_UART0_PD]->clk);
+-
+ mtk_register_reset_controller_with_dev(&pdev->dev, &clk_rst_desc[1]);
+
+ return 0;
+diff --git a/drivers/clk/mediatek/clk-mt7629-eth.c b/drivers/clk/mediatek/clk-mt7629-eth.c
+index 282dd65594654..b0c8fa3b8bbec 100644
+--- a/drivers/clk/mediatek/clk-mt7629-eth.c
++++ b/drivers/clk/mediatek/clk-mt7629-eth.c
+@@ -16,14 +16,8 @@
+
+ #include <dt-bindings/clock/mt7629-clk.h>
+
+-#define GATE_ETH(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &eth_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr_inv, \
+- }
++#define GATE_ETH(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &eth_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
+
+ static const struct mtk_gate_regs eth_cg_regs = {
+ .set_ofs = 0x30,
+@@ -45,14 +39,8 @@ static const struct mtk_gate_regs sgmii_cg_regs = {
+ .sta_ofs = 0xE4,
+ };
+
+-#define GATE_SGMII(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &sgmii_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr_inv, \
+- }
++#define GATE_SGMII(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &sgmii_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
+
+ static const struct mtk_gate sgmii_clks[2][4] = {
+ {
+diff --git a/drivers/clk/mediatek/clk-mt7629-hif.c b/drivers/clk/mediatek/clk-mt7629-hif.c
+index 0c8b9e1397890..3628811a2f57f 100644
+--- a/drivers/clk/mediatek/clk-mt7629-hif.c
++++ b/drivers/clk/mediatek/clk-mt7629-hif.c
+@@ -16,23 +16,11 @@
+
+ #include <dt-bindings/clock/mt7629-clk.h>
+
+-#define GATE_PCIE(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &pcie_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr_inv, \
+- }
++#define GATE_PCIE(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &pcie_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
+
+-#define GATE_SSUSB(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &ssusb_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr_inv, \
+- }
++#define GATE_SSUSB(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &ssusb_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
+
+ static const struct mtk_gate_regs pcie_cg_regs = {
+ .set_ofs = 0x30,
+diff --git a/drivers/clk/mediatek/clk-mt7629.c b/drivers/clk/mediatek/clk-mt7629.c
+index e4a08c811adc2..0bc88b7d171b5 100644
+--- a/drivers/clk/mediatek/clk-mt7629.c
++++ b/drivers/clk/mediatek/clk-mt7629.c
+@@ -50,41 +50,17 @@
+ _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift, \
+ NULL, "clk20m")
+
+-#define GATE_APMIXED(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &apmixed_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr_inv, \
+- }
++#define GATE_APMIXED(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &apmixed_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
+
+-#define GATE_INFRA(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &infra_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
++#define GATE_INFRA(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &infra_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+-#define GATE_PERI0(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &peri0_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
++#define GATE_PERI0(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &peri0_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+-#define GATE_PERI1(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &peri1_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
++#define GATE_PERI1(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &peri1_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+ static DEFINE_SPINLOCK(mt7629_clk_lock);
+
+diff --git a/drivers/clk/mediatek/clk-mt7986-eth.c b/drivers/clk/mediatek/clk-mt7986-eth.c
+index 7868c0728e962..c21e1d672384a 100644
+--- a/drivers/clk/mediatek/clk-mt7986-eth.c
++++ b/drivers/clk/mediatek/clk-mt7986-eth.c
+@@ -22,12 +22,8 @@ static const struct mtk_gate_regs sgmii0_cg_regs = {
+ .sta_ofs = 0xe4,
+ };
+
+-#define GATE_SGMII0(_id, _name, _parent, _shift) \
+- { \
+- .id = _id, .name = _name, .parent_name = _parent, \
+- .regs = &sgmii0_cg_regs, .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr_inv, \
+- }
++#define GATE_SGMII0(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &sgmii0_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
+
+ static const struct mtk_gate sgmii0_clks[] __initconst = {
+ GATE_SGMII0(CLK_SGMII0_TX250M_EN, "sgmii0_tx250m_en", "top_xtal", 2),
+@@ -42,12 +38,8 @@ static const struct mtk_gate_regs sgmii1_cg_regs = {
+ .sta_ofs = 0xe4,
+ };
+
+-#define GATE_SGMII1(_id, _name, _parent, _shift) \
+- { \
+- .id = _id, .name = _name, .parent_name = _parent, \
+- .regs = &sgmii1_cg_regs, .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr_inv, \
+- }
++#define GATE_SGMII1(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &sgmii1_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
+
+ static const struct mtk_gate sgmii1_clks[] __initconst = {
+ GATE_SGMII1(CLK_SGMII1_TX250M_EN, "sgmii1_tx250m_en", "top_xtal", 2),
+@@ -62,12 +54,8 @@ static const struct mtk_gate_regs eth_cg_regs = {
+ .sta_ofs = 0x30,
+ };
+
+-#define GATE_ETH(_id, _name, _parent, _shift) \
+- { \
+- .id = _id, .name = _name, .parent_name = _parent, \
+- .regs = &eth_cg_regs, .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr_inv, \
+- }
++#define GATE_ETH(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &eth_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
+
+ static const struct mtk_gate eth_clks[] __initconst = {
+ GATE_ETH(CLK_ETH_FE_EN, "eth_fe_en", "netsys_2x_sel", 6),
+diff --git a/drivers/clk/mediatek/clk-mt7986-infracfg.c b/drivers/clk/mediatek/clk-mt7986-infracfg.c
+index 49666047bf0ed..74e68a7197301 100644
+--- a/drivers/clk/mediatek/clk-mt7986-infracfg.c
++++ b/drivers/clk/mediatek/clk-mt7986-infracfg.c
+@@ -87,26 +87,14 @@ static const struct mtk_gate_regs infra2_cg_regs = {
+ .sta_ofs = 0x68,
+ };
+
+-#define GATE_INFRA0(_id, _name, _parent, _shift) \
+- { \
+- .id = _id, .name = _name, .parent_name = _parent, \
+- .regs = &infra0_cg_regs, .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
++#define GATE_INFRA0(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &infra0_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+-#define GATE_INFRA1(_id, _name, _parent, _shift) \
+- { \
+- .id = _id, .name = _name, .parent_name = _parent, \
+- .regs = &infra1_cg_regs, .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
++#define GATE_INFRA1(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &infra1_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+-#define GATE_INFRA2(_id, _name, _parent, _shift) \
+- { \
+- .id = _id, .name = _name, .parent_name = _parent, \
+- .regs = &infra2_cg_regs, .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
++#define GATE_INFRA2(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &infra2_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+ static const struct mtk_gate infra_clks[] = {
+ /* INFRA0 */
+diff --git a/drivers/clk/mediatek/clk-mt8135.c b/drivers/clk/mediatek/clk-mt8135.c
+index b68888a034c40..3ea06d2ec2f11 100644
+--- a/drivers/clk/mediatek/clk-mt8135.c
++++ b/drivers/clk/mediatek/clk-mt8135.c
+@@ -2,6 +2,8 @@
+ /*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Author: James Liao <jamesjj.liao@mediatek.com>
++ * Copyright (c) 2023 Collabora, Ltd.
++ * AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+ */
+
+ #include <linux/clk.h>
+@@ -390,7 +392,7 @@ static const struct mtk_composite top_muxes[] __initconst = {
+ MUX_GATE(CLK_TOP_GCPU_SEL, "gcpu_sel", gcpu_parents, 0x0164, 24, 3, 31),
+ /* CLK_CFG_9 */
+ MUX_GATE(CLK_TOP_DPI1_SEL, "dpi1_sel", dpi1_parents, 0x0168, 0, 2, 7),
+- MUX_GATE(CLK_TOP_CCI_SEL, "cci_sel", cci_parents, 0x0168, 8, 3, 15),
++ MUX_GATE_FLAGS(CLK_TOP_CCI_SEL, "cci_sel", cci_parents, 0x0168, 8, 3, 15, CLK_IS_CRITICAL),
+ MUX_GATE(CLK_TOP_APLL_SEL, "apll_sel", apll_parents, 0x0168, 16, 3, 23),
+ MUX_GATE(CLK_TOP_HDMIPLL_SEL, "hdmipll_sel", hdmipll_parents, 0x0168, 24, 2, 31),
+ };
+@@ -401,14 +403,12 @@ static const struct mtk_gate_regs infra_cg_regs = {
+ .sta_ofs = 0x0048,
+ };
+
+-#define GATE_ICG(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &infra_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
++#define GATE_ICG(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &infra_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
++
++#define GATE_ICG_AO(_id, _name, _parent, _shift) \
++ GATE_MTK_FLAGS(_id, _name, _parent, &infra_cg_regs, _shift, \
++ &mtk_clk_gate_ops_setclr, CLK_IS_CRITICAL)
+
+ static const struct mtk_gate infra_clks[] __initconst = {
+ GATE_ICG(CLK_INFRA_PMIC_WRAP, "pmic_wrap_ck", "axi_sel", 23),
+@@ -417,7 +417,7 @@ static const struct mtk_gate infra_clks[] __initconst = {
+ GATE_ICG(CLK_INFRA_CCIF0_AP_CTRL, "ccif0_ap_ctrl", "axi_sel", 20),
+ GATE_ICG(CLK_INFRA_KP, "kp_ck", "axi_sel", 16),
+ GATE_ICG(CLK_INFRA_CPUM, "cpum_ck", "cpum_tck_in", 15),
+- GATE_ICG(CLK_INFRA_M4U, "m4u_ck", "mem_sel", 8),
++ GATE_ICG_AO(CLK_INFRA_M4U, "m4u_ck", "mem_sel", 8),
+ GATE_ICG(CLK_INFRA_MFGAXI, "mfgaxi_ck", "axi_sel", 7),
+ GATE_ICG(CLK_INFRA_DEVAPC, "devapc_ck", "axi_sel", 6),
+ GATE_ICG(CLK_INFRA_AUDIO, "audio_ck", "aud_intbus_sel", 5),
+@@ -438,23 +438,11 @@ static const struct mtk_gate_regs peri1_cg_regs = {
+ .sta_ofs = 0x001c,
+ };
+
+-#define GATE_PERI0(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &peri0_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
++#define GATE_PERI0(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &peri0_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+-#define GATE_PERI1(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &peri1_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
++#define GATE_PERI1(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &peri1_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+ static const struct mtk_gate peri_gates[] __initconst = {
+ /* PERI0 */
+@@ -551,8 +539,6 @@ static void __init mtk_topckgen_init(struct device_node *node)
+ mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base,
+ &mt8135_clk_lock, clk_data);
+
+- clk_prepare_enable(clk_data->hws[CLK_TOP_CCI_SEL]->clk);
+-
+ r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+ if (r)
+ pr_err("%s(): could not register clock provider: %d\n",
+@@ -570,8 +556,6 @@ static void __init mtk_infrasys_init(struct device_node *node)
+ mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
+ clk_data);
+
+- clk_prepare_enable(clk_data->hws[CLK_INFRA_M4U]->clk);
+-
+ r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+ if (r)
+ pr_err("%s(): could not register clock provider: %d\n",
+diff --git a/drivers/clk/mediatek/clk-mt8167-aud.c b/drivers/clk/mediatek/clk-mt8167-aud.c
+index ce1ae8d243c33..b5ac196cd9454 100644
+--- a/drivers/clk/mediatek/clk-mt8167-aud.c
++++ b/drivers/clk/mediatek/clk-mt8167-aud.c
+@@ -23,14 +23,9 @@ static const struct mtk_gate_regs aud_cg_regs = {
+ .sta_ofs = 0x0,
+ };
+
+-#define GATE_AUD(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &aud_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr, \
+- }
++#define GATE_AUD(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &aud_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr)
++
+
+ static const struct mtk_gate aud_clks[] __initconst = {
+ GATE_AUD(CLK_AUD_AFE, "aud_afe", "clk26m_ck", 2),
+diff --git a/drivers/clk/mediatek/clk-mt8167-img.c b/drivers/clk/mediatek/clk-mt8167-img.c
+index e359e563d2b79..4e7c0772b4f99 100644
+--- a/drivers/clk/mediatek/clk-mt8167-img.c
++++ b/drivers/clk/mediatek/clk-mt8167-img.c
+@@ -23,14 +23,8 @@ static const struct mtk_gate_regs img_cg_regs = {
+ .sta_ofs = 0x0,
+ };
+
+-#define GATE_IMG(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &img_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
++#define GATE_IMG(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &img_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+ static const struct mtk_gate img_clks[] __initconst = {
+ GATE_IMG(CLK_IMG_LARB1_SMI, "img_larb1_smi", "smi_mm", 0),
+diff --git a/drivers/clk/mediatek/clk-mt8167-mfgcfg.c b/drivers/clk/mediatek/clk-mt8167-mfgcfg.c
+index 4fd82fe87d6e5..192714498b2ec 100644
+--- a/drivers/clk/mediatek/clk-mt8167-mfgcfg.c
++++ b/drivers/clk/mediatek/clk-mt8167-mfgcfg.c
+@@ -23,14 +23,8 @@ static const struct mtk_gate_regs mfg_cg_regs = {
+ .sta_ofs = 0x0,
+ };
+
+-#define GATE_MFG(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &mfg_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
++#define GATE_MFG(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &mfg_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+ static const struct mtk_gate mfg_clks[] __initconst = {
+ GATE_MFG(CLK_MFG_BAXI, "mfg_baxi", "ahb_infra_sel", 0),
+diff --git a/drivers/clk/mediatek/clk-mt8167-mm.c b/drivers/clk/mediatek/clk-mt8167-mm.c
+index 73910060577f6..a94961b7b8cc6 100644
+--- a/drivers/clk/mediatek/clk-mt8167-mm.c
++++ b/drivers/clk/mediatek/clk-mt8167-mm.c
+@@ -29,23 +29,11 @@ static const struct mtk_gate_regs mm1_cg_regs = {
+ .sta_ofs = 0x110,
+ };
+
+-#define GATE_MM0(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &mm0_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
+-
+-#define GATE_MM1(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &mm1_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
++#define GATE_MM0(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &mm0_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
++
++#define GATE_MM1(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &mm1_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+ static const struct mtk_gate mm_clks[] = {
+ /* MM0 */
+diff --git a/drivers/clk/mediatek/clk-mt8167-vdec.c b/drivers/clk/mediatek/clk-mt8167-vdec.c
+index ee4fffb6859da..38f0ba357d599 100644
+--- a/drivers/clk/mediatek/clk-mt8167-vdec.c
++++ b/drivers/clk/mediatek/clk-mt8167-vdec.c
+@@ -29,23 +29,11 @@ static const struct mtk_gate_regs vdec1_cg_regs = {
+ .sta_ofs = 0x8,
+ };
+
+-#define GATE_VDEC0_I(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &vdec0_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr_inv, \
+- }
++#define GATE_VDEC0_I(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &vdec0_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
+
+-#define GATE_VDEC1_I(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &vdec1_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr_inv, \
+- }
++#define GATE_VDEC1_I(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &vdec1_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
+
+ static const struct mtk_gate vdec_clks[] __initconst = {
+ /* VDEC0 */
+diff --git a/drivers/clk/mediatek/clk-mt8173-mm.c b/drivers/clk/mediatek/clk-mt8173-mm.c
+index 8abf42c2030c6..5826eabdc9c77 100644
+--- a/drivers/clk/mediatek/clk-mt8173-mm.c
++++ b/drivers/clk/mediatek/clk-mt8173-mm.c
+@@ -25,23 +25,11 @@ static const struct mtk_gate_regs mm1_cg_regs = {
+ .sta_ofs = 0x0110,
+ };
+
+-#define GATE_MM0(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &mm0_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
+-
+-#define GATE_MM1(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &mm1_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
++#define GATE_MM0(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &mm0_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
++
++#define GATE_MM1(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &mm1_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+ static const struct mtk_gate mt8173_mm_clks[] = {
+ /* MM0 */
+diff --git a/drivers/clk/mediatek/clk-mt8516-aud.c b/drivers/clk/mediatek/clk-mt8516-aud.c
+index 90f48068a8de7..a3dafc719799c 100644
+--- a/drivers/clk/mediatek/clk-mt8516-aud.c
++++ b/drivers/clk/mediatek/clk-mt8516-aud.c
+@@ -22,14 +22,8 @@ static const struct mtk_gate_regs aud_cg_regs = {
+ .sta_ofs = 0x0,
+ };
+
+-#define GATE_AUD(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &aud_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr, \
+- }
++#define GATE_AUD(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &aud_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr)
+
+ static const struct mtk_gate aud_clks[] __initconst = {
+ GATE_AUD(CLK_AUD_AFE, "aud_afe", "clk26m_ck", 2),
+diff --git a/drivers/clk/mediatek/clk-mt8516.c b/drivers/clk/mediatek/clk-mt8516.c
+index b96db88893e23..056953d594c66 100644
+--- a/drivers/clk/mediatek/clk-mt8516.c
++++ b/drivers/clk/mediatek/clk-mt8516.c
+@@ -525,59 +525,23 @@ static const struct mtk_gate_regs top5_cg_regs = {
+ .sta_ofs = 0x44,
+ };
+
+-#define GATE_TOP1(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &top1_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
++#define GATE_TOP1(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &top1_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+-#define GATE_TOP2(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &top2_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
++#define GATE_TOP2(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &top2_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+-#define GATE_TOP2_I(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &top2_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr_inv, \
+- }
++#define GATE_TOP2_I(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &top2_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
+
+-#define GATE_TOP3(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &top3_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr, \
+- }
++#define GATE_TOP3(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &top3_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+-#define GATE_TOP4_I(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &top4_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_setclr_inv, \
+- }
++#define GATE_TOP4_I(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &top4_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
+
+-#define GATE_TOP5(_id, _name, _parent, _shift) { \
+- .id = _id, \
+- .name = _name, \
+- .parent_name = _parent, \
+- .regs = &top5_cg_regs, \
+- .shift = _shift, \
+- .ops = &mtk_clk_gate_ops_no_setclr, \
+- }
++#define GATE_TOP5(_id, _name, _parent, _shift) \
++ GATE_MTK(_id, _name, _parent, &top5_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+ static const struct mtk_gate top_clks[] __initconst = {
+ /* TOP1 */
+diff --git a/drivers/clk/mediatek/clk-pllfh.c b/drivers/clk/mediatek/clk-pllfh.c
+index f48780bec5077..f135b32c6dbed 100644
+--- a/drivers/clk/mediatek/clk-pllfh.c
++++ b/drivers/clk/mediatek/clk-pllfh.c
+@@ -75,13 +75,13 @@ void fhctl_parse_dt(const u8 *compatible_node, struct mtk_pllfh_data *pllfhs,
+ base = of_iomap(node, 0);
+ if (!base) {
+ pr_err("%s(): ioremap failed\n", __func__);
+- return;
++ goto out_node_put;
+ }
+
+ num_clocks = of_clk_get_parent_count(node);
+ if (!num_clocks) {
+ pr_err("%s(): failed to get clocks property\n", __func__);
+- return;
++ goto err;
+ }
+
+ for (i = 0; i < num_clocks; i++) {
+@@ -102,6 +102,13 @@ void fhctl_parse_dt(const u8 *compatible_node, struct mtk_pllfh_data *pllfhs,
+ pllfh->state.ssc_rate = ssc_rate;
+ pllfh->state.base = base;
+ }
++
++out_node_put:
++ of_node_put(node);
++ return;
++err:
++ iounmap(base);
++ goto out_node_put;
+ }
+
+ static void pllfh_init(struct mtk_fh *fh, struct mtk_pllfh_data *pllfh_data)
+diff --git a/drivers/clk/microchip/clk-mpfs.c b/drivers/clk/microchip/clk-mpfs.c
+index 4f0a19db7ed74..cc5d7dee59f06 100644
+--- a/drivers/clk/microchip/clk-mpfs.c
++++ b/drivers/clk/microchip/clk-mpfs.c
+@@ -374,14 +374,13 @@ static void mpfs_reset_unregister_adev(void *_adev)
+ struct auxiliary_device *adev = _adev;
+
+ auxiliary_device_delete(adev);
++ auxiliary_device_uninit(adev);
+ }
+
+ static void mpfs_reset_adev_release(struct device *dev)
+ {
+ struct auxiliary_device *adev = to_auxiliary_dev(dev);
+
+- auxiliary_device_uninit(adev);
+-
+ kfree(adev);
+ }
+
+diff --git a/drivers/clk/qcom/dispcc-qcm2290.c b/drivers/clk/qcom/dispcc-qcm2290.c
+index 96b149365912a..24755dc841f9d 100644
+--- a/drivers/clk/qcom/dispcc-qcm2290.c
++++ b/drivers/clk/qcom/dispcc-qcm2290.c
+@@ -26,7 +26,6 @@ enum {
+ P_DISP_CC_PLL0_OUT_MAIN,
+ P_DSI0_PHY_PLL_OUT_BYTECLK,
+ P_DSI0_PHY_PLL_OUT_DSICLK,
+- P_DSI1_PHY_PLL_OUT_DSICLK,
+ P_GPLL0_OUT_MAIN,
+ P_SLEEP_CLK,
+ };
+@@ -71,7 +70,6 @@ static const struct parent_map disp_cc_parent_map_0[] = {
+ static const struct clk_parent_data disp_cc_parent_data_0[] = {
+ { .fw_name = "bi_tcxo" },
+ { .fw_name = "dsi0_phy_pll_out_byteclk" },
+- { .fw_name = "core_bi_pll_test_se" },
+ };
+
+ static const struct parent_map disp_cc_parent_map_1[] = {
+@@ -80,7 +78,6 @@ static const struct parent_map disp_cc_parent_map_1[] = {
+
+ static const struct clk_parent_data disp_cc_parent_data_1[] = {
+ { .fw_name = "bi_tcxo" },
+- { .fw_name = "core_bi_pll_test_se" },
+ };
+
+ static const struct parent_map disp_cc_parent_map_2[] = {
+@@ -91,7 +88,6 @@ static const struct parent_map disp_cc_parent_map_2[] = {
+ static const struct clk_parent_data disp_cc_parent_data_2[] = {
+ { .fw_name = "bi_tcxo_ao" },
+ { .fw_name = "gcc_disp_gpll0_div_clk_src" },
+- { .fw_name = "core_bi_pll_test_se" },
+ };
+
+ static const struct parent_map disp_cc_parent_map_3[] = {
+@@ -104,20 +100,16 @@ static const struct clk_parent_data disp_cc_parent_data_3[] = {
+ { .fw_name = "bi_tcxo" },
+ { .hw = &disp_cc_pll0.clkr.hw },
+ { .fw_name = "gcc_disp_gpll0_clk_src" },
+- { .fw_name = "core_bi_pll_test_se" },
+ };
+
+ static const struct parent_map disp_cc_parent_map_4[] = {
+ { P_BI_TCXO, 0 },
+ { P_DSI0_PHY_PLL_OUT_DSICLK, 1 },
+- { P_DSI1_PHY_PLL_OUT_DSICLK, 2 },
+ };
+
+ static const struct clk_parent_data disp_cc_parent_data_4[] = {
+ { .fw_name = "bi_tcxo" },
+ { .fw_name = "dsi0_phy_pll_out_dsiclk" },
+- { .fw_name = "dsi1_phy_pll_out_dsiclk" },
+- { .fw_name = "core_bi_pll_test_se" },
+ };
+
+ static const struct parent_map disp_cc_parent_map_5[] = {
+@@ -126,7 +118,6 @@ static const struct parent_map disp_cc_parent_map_5[] = {
+
+ static const struct clk_parent_data disp_cc_parent_data_5[] = {
+ { .fw_name = "sleep_clk" },
+- { .fw_name = "core_bi_pll_test_se" },
+ };
+
+ static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = {
+diff --git a/drivers/clk/qcom/gcc-qcm2290.c b/drivers/clk/qcom/gcc-qcm2290.c
+index 7792b8f237047..096deff2ba257 100644
+--- a/drivers/clk/qcom/gcc-qcm2290.c
++++ b/drivers/clk/qcom/gcc-qcm2290.c
+@@ -1243,7 +1243,8 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = {
+ .name = "gcc_sdcc2_apps_clk_src",
+ .parent_data = gcc_parents_12,
+ .num_parents = ARRAY_SIZE(gcc_parents_12),
+- .ops = &clk_rcg2_ops,
++ .ops = &clk_rcg2_floor_ops,
++ .flags = CLK_OPS_PARENT_ENABLE,
+ },
+ };
+
+diff --git a/drivers/clk/qcom/gcc-sm6115.c b/drivers/clk/qcom/gcc-sm6115.c
+index 565f9912039fe..631419caf695a 100644
+--- a/drivers/clk/qcom/gcc-sm6115.c
++++ b/drivers/clk/qcom/gcc-sm6115.c
+@@ -694,7 +694,7 @@ static struct clk_rcg2 gcc_camss_axi_clk_src = {
+ .parent_data = gcc_parents_7,
+ .num_parents = ARRAY_SIZE(gcc_parents_7),
+ .flags = CLK_SET_RATE_PARENT,
+- .ops = &clk_rcg2_ops,
++ .ops = &clk_rcg2_shared_ops,
+ },
+ };
+
+@@ -715,7 +715,7 @@ static struct clk_rcg2 gcc_camss_cci_clk_src = {
+ .parent_data = gcc_parents_9,
+ .num_parents = ARRAY_SIZE(gcc_parents_9),
+ .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
+- .ops = &clk_rcg2_ops,
++ .ops = &clk_rcg2_shared_ops,
+ },
+ };
+
+@@ -738,7 +738,7 @@ static struct clk_rcg2 gcc_camss_csi0phytimer_clk_src = {
+ .parent_data = gcc_parents_4,
+ .num_parents = ARRAY_SIZE(gcc_parents_4),
+ .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
+- .ops = &clk_rcg2_ops,
++ .ops = &clk_rcg2_shared_ops,
+ },
+ };
+
+@@ -753,7 +753,7 @@ static struct clk_rcg2 gcc_camss_csi1phytimer_clk_src = {
+ .parent_data = gcc_parents_4,
+ .num_parents = ARRAY_SIZE(gcc_parents_4),
+ .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
+- .ops = &clk_rcg2_ops,
++ .ops = &clk_rcg2_shared_ops,
+ },
+ };
+
+@@ -768,7 +768,7 @@ static struct clk_rcg2 gcc_camss_csi2phytimer_clk_src = {
+ .parent_data = gcc_parents_4,
+ .num_parents = ARRAY_SIZE(gcc_parents_4),
+ .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
+- .ops = &clk_rcg2_ops,
++ .ops = &clk_rcg2_shared_ops,
+ },
+ };
+
+@@ -790,7 +790,7 @@ static struct clk_rcg2 gcc_camss_mclk0_clk_src = {
+ .parent_data = gcc_parents_3,
+ .num_parents = ARRAY_SIZE(gcc_parents_3),
+ .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
+- .ops = &clk_rcg2_ops,
++ .ops = &clk_rcg2_shared_ops,
+ },
+ };
+
+@@ -805,7 +805,7 @@ static struct clk_rcg2 gcc_camss_mclk1_clk_src = {
+ .parent_data = gcc_parents_3,
+ .num_parents = ARRAY_SIZE(gcc_parents_3),
+ .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
+- .ops = &clk_rcg2_ops,
++ .ops = &clk_rcg2_shared_ops,
+ },
+ };
+
+@@ -820,7 +820,7 @@ static struct clk_rcg2 gcc_camss_mclk2_clk_src = {
+ .parent_data = gcc_parents_3,
+ .num_parents = ARRAY_SIZE(gcc_parents_3),
+ .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
+- .ops = &clk_rcg2_ops,
++ .ops = &clk_rcg2_shared_ops,
+ },
+ };
+
+@@ -835,7 +835,7 @@ static struct clk_rcg2 gcc_camss_mclk3_clk_src = {
+ .parent_data = gcc_parents_3,
+ .num_parents = ARRAY_SIZE(gcc_parents_3),
+ .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
+- .ops = &clk_rcg2_ops,
++ .ops = &clk_rcg2_shared_ops,
+ },
+ };
+
+@@ -857,7 +857,7 @@ static struct clk_rcg2 gcc_camss_ope_ahb_clk_src = {
+ .parent_data = gcc_parents_8,
+ .num_parents = ARRAY_SIZE(gcc_parents_8),
+ .flags = CLK_SET_RATE_PARENT,
+- .ops = &clk_rcg2_ops,
++ .ops = &clk_rcg2_shared_ops,
+ },
+ };
+
+@@ -881,7 +881,7 @@ static struct clk_rcg2 gcc_camss_ope_clk_src = {
+ .parent_data = gcc_parents_8,
+ .num_parents = ARRAY_SIZE(gcc_parents_8),
+ .flags = CLK_SET_RATE_PARENT,
+- .ops = &clk_rcg2_ops,
++ .ops = &clk_rcg2_shared_ops,
+ },
+ };
+
+@@ -916,7 +916,7 @@ static struct clk_rcg2 gcc_camss_tfe_0_clk_src = {
+ .parent_data = gcc_parents_5,
+ .num_parents = ARRAY_SIZE(gcc_parents_5),
+ .flags = CLK_SET_RATE_PARENT,
+- .ops = &clk_rcg2_ops,
++ .ops = &clk_rcg2_shared_ops,
+ },
+ };
+
+@@ -941,7 +941,7 @@ static struct clk_rcg2 gcc_camss_tfe_0_csid_clk_src = {
+ .parent_data = gcc_parents_6,
+ .num_parents = ARRAY_SIZE(gcc_parents_6),
+ .flags = CLK_SET_RATE_PARENT,
+- .ops = &clk_rcg2_ops,
++ .ops = &clk_rcg2_shared_ops,
+ },
+ };
+
+@@ -956,7 +956,7 @@ static struct clk_rcg2 gcc_camss_tfe_1_clk_src = {
+ .parent_data = gcc_parents_5,
+ .num_parents = ARRAY_SIZE(gcc_parents_5),
+ .flags = CLK_SET_RATE_PARENT,
+- .ops = &clk_rcg2_ops,
++ .ops = &clk_rcg2_shared_ops,
+ },
+ };
+
+@@ -971,7 +971,7 @@ static struct clk_rcg2 gcc_camss_tfe_1_csid_clk_src = {
+ .parent_data = gcc_parents_6,
+ .num_parents = ARRAY_SIZE(gcc_parents_6),
+ .flags = CLK_SET_RATE_PARENT,
+- .ops = &clk_rcg2_ops,
++ .ops = &clk_rcg2_shared_ops,
+ },
+ };
+
+@@ -986,7 +986,7 @@ static struct clk_rcg2 gcc_camss_tfe_2_clk_src = {
+ .parent_data = gcc_parents_5,
+ .num_parents = ARRAY_SIZE(gcc_parents_5),
+ .flags = CLK_SET_RATE_PARENT,
+- .ops = &clk_rcg2_ops,
++ .ops = &clk_rcg2_shared_ops,
+ },
+ };
+
+@@ -1001,7 +1001,7 @@ static struct clk_rcg2 gcc_camss_tfe_2_csid_clk_src = {
+ .parent_data = gcc_parents_6,
+ .num_parents = ARRAY_SIZE(gcc_parents_6),
+ .flags = CLK_SET_RATE_PARENT,
+- .ops = &clk_rcg2_ops,
++ .ops = &clk_rcg2_shared_ops,
+ },
+ };
+
+@@ -1024,7 +1024,7 @@ static struct clk_rcg2 gcc_camss_tfe_cphy_rx_clk_src = {
+ .parent_data = gcc_parents_10,
+ .num_parents = ARRAY_SIZE(gcc_parents_10),
+ .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
+- .ops = &clk_rcg2_ops,
++ .ops = &clk_rcg2_shared_ops,
+ },
+ };
+
+@@ -1046,7 +1046,7 @@ static struct clk_rcg2 gcc_camss_top_ahb_clk_src = {
+ .parent_data = gcc_parents_7,
+ .num_parents = ARRAY_SIZE(gcc_parents_7),
+ .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
+- .ops = &clk_rcg2_ops,
++ .ops = &clk_rcg2_shared_ops,
+ },
+ };
+
+@@ -1116,7 +1116,7 @@ static struct clk_rcg2 gcc_pdm2_clk_src = {
+ .name = "gcc_pdm2_clk_src",
+ .parent_data = gcc_parents_0,
+ .num_parents = ARRAY_SIZE(gcc_parents_0),
+- .ops = &clk_rcg2_ops,
++ .ops = &clk_rcg2_shared_ops,
+ },
+ };
+
+@@ -1329,7 +1329,7 @@ static struct clk_rcg2 gcc_ufs_phy_axi_clk_src = {
+ .name = "gcc_ufs_phy_axi_clk_src",
+ .parent_data = gcc_parents_0,
+ .num_parents = ARRAY_SIZE(gcc_parents_0),
+- .ops = &clk_rcg2_ops,
++ .ops = &clk_rcg2_shared_ops,
+ },
+ };
+
+@@ -1351,7 +1351,7 @@ static struct clk_rcg2 gcc_ufs_phy_ice_core_clk_src = {
+ .name = "gcc_ufs_phy_ice_core_clk_src",
+ .parent_data = gcc_parents_0,
+ .num_parents = ARRAY_SIZE(gcc_parents_0),
+- .ops = &clk_rcg2_ops,
++ .ops = &clk_rcg2_shared_ops,
+ },
+ };
+
+@@ -1392,7 +1392,7 @@ static struct clk_rcg2 gcc_ufs_phy_unipro_core_clk_src = {
+ .name = "gcc_ufs_phy_unipro_core_clk_src",
+ .parent_data = gcc_parents_0,
+ .num_parents = ARRAY_SIZE(gcc_parents_0),
+- .ops = &clk_rcg2_ops,
++ .ops = &clk_rcg2_shared_ops,
+ },
+ };
+
+@@ -1414,7 +1414,7 @@ static struct clk_rcg2 gcc_usb30_prim_master_clk_src = {
+ .name = "gcc_usb30_prim_master_clk_src",
+ .parent_data = gcc_parents_0,
+ .num_parents = ARRAY_SIZE(gcc_parents_0),
+- .ops = &clk_rcg2_ops,
++ .ops = &clk_rcg2_shared_ops,
+ },
+ };
+
+@@ -1483,7 +1483,7 @@ static struct clk_rcg2 gcc_video_venus_clk_src = {
+ .parent_data = gcc_parents_13,
+ .num_parents = ARRAY_SIZE(gcc_parents_13),
+ .flags = CLK_SET_RATE_PARENT,
+- .ops = &clk_rcg2_ops,
++ .ops = &clk_rcg2_shared_ops,
+ },
+ };
+
+diff --git a/drivers/clk/qcom/gcc-sm8350.c b/drivers/clk/qcom/gcc-sm8350.c
+index c3731f96c8e6b..430ef407a8341 100644
+--- a/drivers/clk/qcom/gcc-sm8350.c
++++ b/drivers/clk/qcom/gcc-sm8350.c
+@@ -17,6 +17,7 @@
+ #include "clk-regmap.h"
+ #include "clk-regmap-divider.h"
+ #include "clk-regmap-mux.h"
++#include "clk-regmap-phy-mux.h"
+ #include "gdsc.h"
+ #include "reset.h"
+
+@@ -167,26 +168,6 @@ static const struct clk_parent_data gcc_parent_data_3[] = {
+ { .fw_name = "core_bi_pll_test_se" },
+ };
+
+-static const struct parent_map gcc_parent_map_4[] = {
+- { P_PCIE_0_PIPE_CLK, 0 },
+- { P_BI_TCXO, 2 },
+-};
+-
+-static const struct clk_parent_data gcc_parent_data_4[] = {
+- { .fw_name = "pcie_0_pipe_clk", },
+- { .fw_name = "bi_tcxo" },
+-};
+-
+-static const struct parent_map gcc_parent_map_5[] = {
+- { P_PCIE_1_PIPE_CLK, 0 },
+- { P_BI_TCXO, 2 },
+-};
+-
+-static const struct clk_parent_data gcc_parent_data_5[] = {
+- { .fw_name = "pcie_1_pipe_clk" },
+- { .fw_name = "bi_tcxo" },
+-};
+-
+ static const struct parent_map gcc_parent_map_6[] = {
+ { P_BI_TCXO, 0 },
+ { P_GCC_GPLL0_OUT_MAIN, 1 },
+@@ -289,32 +270,30 @@ static const struct clk_parent_data gcc_parent_data_14[] = {
+ { .fw_name = "bi_tcxo" },
+ };
+
+-static struct clk_regmap_mux gcc_pcie_0_pipe_clk_src = {
++static struct clk_regmap_phy_mux gcc_pcie_0_pipe_clk_src = {
+ .reg = 0x6b054,
+- .shift = 0,
+- .width = 2,
+- .parent_map = gcc_parent_map_4,
+ .clkr = {
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_pcie_0_pipe_clk_src",
+- .parent_data = gcc_parent_data_4,
+- .num_parents = ARRAY_SIZE(gcc_parent_data_4),
+- .ops = &clk_regmap_mux_closest_ops,
++ .parent_data = &(const struct clk_parent_data){
++ .fw_name = "pcie_0_pipe_clk",
++ },
++ .num_parents = 1,
++ .ops = &clk_regmap_phy_mux_ops,
+ },
+ },
+ };
+
+-static struct clk_regmap_mux gcc_pcie_1_pipe_clk_src = {
++static struct clk_regmap_phy_mux gcc_pcie_1_pipe_clk_src = {
+ .reg = 0x8d054,
+- .shift = 0,
+- .width = 2,
+- .parent_map = gcc_parent_map_5,
+ .clkr = {
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_pcie_1_pipe_clk_src",
+- .parent_data = gcc_parent_data_5,
+- .num_parents = ARRAY_SIZE(gcc_parent_data_5),
+- .ops = &clk_regmap_mux_closest_ops,
++ .parent_data = &(const struct clk_parent_data){
++ .fw_name = "pcie_1_pipe_clk",
++ },
++ .num_parents = 1,
++ .ops = &clk_regmap_phy_mux_ops,
+ },
+ },
+ };
+diff --git a/drivers/clk/qcom/lpassaudiocc-sc7280.c b/drivers/clk/qcom/lpassaudiocc-sc7280.c
+index 1339f9211a149..134eb1529ede2 100644
+--- a/drivers/clk/qcom/lpassaudiocc-sc7280.c
++++ b/drivers/clk/qcom/lpassaudiocc-sc7280.c
+@@ -696,6 +696,8 @@ static const struct qcom_cc_desc lpass_cc_sc7280_desc = {
+ .config = &lpass_audio_cc_sc7280_regmap_config,
+ .clks = lpass_cc_sc7280_clocks,
+ .num_clks = ARRAY_SIZE(lpass_cc_sc7280_clocks),
++ .gdscs = lpass_aon_cc_sc7280_gdscs,
++ .num_gdscs = ARRAY_SIZE(lpass_aon_cc_sc7280_gdscs),
+ };
+
+ static const struct qcom_cc_desc lpass_audio_cc_sc7280_desc = {
+diff --git a/drivers/clk/qcom/lpasscc-sc7280.c b/drivers/clk/qcom/lpasscc-sc7280.c
+index 5c1e17bd0d763..8486d7135ab10 100644
+--- a/drivers/clk/qcom/lpasscc-sc7280.c
++++ b/drivers/clk/qcom/lpasscc-sc7280.c
+@@ -118,14 +118,18 @@ static int lpass_cc_sc7280_probe(struct platform_device *pdev)
+ goto destroy_pm_clk;
+ }
+
+- lpass_regmap_config.name = "qdsp6ss";
+- desc = &lpass_qdsp6ss_sc7280_desc;
+-
+- ret = qcom_cc_probe_by_index(pdev, 0, desc);
+- if (ret)
+- goto destroy_pm_clk;
++ if (!of_property_read_bool(pdev->dev.of_node, "qcom,adsp-pil-mode")) {
++ lpass_regmap_config.name = "qdsp6ss";
++ lpass_regmap_config.max_register = 0x3f;
++ desc = &lpass_qdsp6ss_sc7280_desc;
++
++ ret = qcom_cc_probe_by_index(pdev, 0, desc);
++ if (ret)
++ goto destroy_pm_clk;
++ }
+
+ lpass_regmap_config.name = "top_cc";
++ lpass_regmap_config.max_register = 0x4;
+ desc = &lpass_cc_top_sc7280_desc;
+
+ ret = qcom_cc_probe_by_index(pdev, 1, desc);
+diff --git a/drivers/clk/rockchip/clk-rk3399.c b/drivers/clk/rockchip/clk-rk3399.c
+index 306910a3a0d38..9ebd6c451b3db 100644
+--- a/drivers/clk/rockchip/clk-rk3399.c
++++ b/drivers/clk/rockchip/clk-rk3399.c
+@@ -1263,7 +1263,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
+ RK3399_CLKSEL_CON(56), 6, 2, MFLAGS,
+ RK3399_CLKGATE_CON(10), 7, GFLAGS),
+
+- COMPOSITE_NOGATE(SCLK_CIF_OUT, "clk_cifout", mux_clk_cif_p, 0,
++ COMPOSITE_NOGATE(SCLK_CIF_OUT, "clk_cifout", mux_clk_cif_p, CLK_SET_RATE_PARENT,
+ RK3399_CLKSEL_CON(56), 5, 1, MFLAGS, 0, 5, DFLAGS),
+
+ /* gic */
+diff --git a/drivers/clocksource/timer-davinci.c b/drivers/clocksource/timer-davinci.c
+index 9996c05425200..b1c248498be46 100644
+--- a/drivers/clocksource/timer-davinci.c
++++ b/drivers/clocksource/timer-davinci.c
+@@ -257,21 +257,25 @@ int __init davinci_timer_register(struct clk *clk,
+ resource_size(&timer_cfg->reg),
+ "davinci-timer")) {
+ pr_err("Unable to request memory region\n");
+- return -EBUSY;
++ rv = -EBUSY;
++ goto exit_clk_disable;
+ }
+
+ base = ioremap(timer_cfg->reg.start, resource_size(&timer_cfg->reg));
+ if (!base) {
+ pr_err("Unable to map the register range\n");
+- return -ENOMEM;
++ rv = -ENOMEM;
++ goto exit_mem_region;
+ }
+
+ davinci_timer_init(base);
+ tick_rate = clk_get_rate(clk);
+
+ clockevent = kzalloc(sizeof(*clockevent), GFP_KERNEL);
+- if (!clockevent)
+- return -ENOMEM;
++ if (!clockevent) {
++ rv = -ENOMEM;
++ goto exit_iounmap_base;
++ }
+
+ clockevent->dev.name = "tim12";
+ clockevent->dev.features = CLOCK_EVT_FEAT_ONESHOT;
+@@ -296,7 +300,7 @@ int __init davinci_timer_register(struct clk *clk,
+ "clockevent/tim12", clockevent);
+ if (rv) {
+ pr_err("Unable to request the clockevent interrupt\n");
+- return rv;
++ goto exit_free_clockevent;
+ }
+
+ davinci_clocksource.dev.rating = 300;
+@@ -323,13 +327,27 @@ int __init davinci_timer_register(struct clk *clk,
+ rv = clocksource_register_hz(&davinci_clocksource.dev, tick_rate);
+ if (rv) {
+ pr_err("Unable to register clocksource\n");
+- return rv;
++ goto exit_free_irq;
+ }
+
+ sched_clock_register(davinci_timer_read_sched_clock,
+ DAVINCI_TIMER_CLKSRC_BITS, tick_rate);
+
+ return 0;
++
++exit_free_irq:
++ free_irq(timer_cfg->irq[DAVINCI_TIMER_CLOCKEVENT_IRQ].start,
++ clockevent);
++exit_free_clockevent:
++ kfree(clockevent);
++exit_iounmap_base:
++ iounmap(base);
++exit_mem_region:
++ release_mem_region(timer_cfg->reg.start,
++ resource_size(&timer_cfg->reg));
++exit_clk_disable:
++ clk_disable_unprepare(clk);
++ return rv;
+ }
+
+ static int __init of_davinci_timer_register(struct device_node *np)
+diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
+index 7e56a42750ea5..285ba51b31f60 100644
+--- a/drivers/cpufreq/cpufreq.c
++++ b/drivers/cpufreq/cpufreq.c
+@@ -1727,7 +1727,7 @@ static unsigned int cpufreq_verify_current_freq(struct cpufreq_policy *policy, b
+ * MHz. In such cases it is better to avoid getting into
+ * unnecessary frequency updates.
+ */
+- if (abs(policy->cur - new_freq) < HZ_PER_MHZ)
++ if (abs(policy->cur - new_freq) < KHZ_PER_MHZ)
+ return policy->cur;
+
+ cpufreq_out_of_sync(policy, new_freq);
+diff --git a/drivers/cpufreq/mediatek-cpufreq.c b/drivers/cpufreq/mediatek-cpufreq.c
+index 7f2680bc9a0f4..9a39a7ccfae96 100644
+--- a/drivers/cpufreq/mediatek-cpufreq.c
++++ b/drivers/cpufreq/mediatek-cpufreq.c
+@@ -373,13 +373,13 @@ static struct device *of_get_cci(struct device *cpu_dev)
+ struct platform_device *pdev;
+
+ np = of_parse_phandle(cpu_dev->of_node, "mediatek,cci", 0);
+- if (IS_ERR_OR_NULL(np))
+- return NULL;
++ if (!np)
++ return ERR_PTR(-ENODEV);
+
+ pdev = of_find_device_by_node(np);
+ of_node_put(np);
+- if (IS_ERR_OR_NULL(pdev))
+- return NULL;
++ if (!pdev)
++ return ERR_PTR(-ENODEV);
+
+ return &pdev->dev;
+ }
+@@ -401,7 +401,7 @@ static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu)
+ info->ccifreq_bound = false;
+ if (info->soc_data->ccifreq_supported) {
+ info->cci_dev = of_get_cci(info->cpu_dev);
+- if (IS_ERR_OR_NULL(info->cci_dev)) {
++ if (IS_ERR(info->cci_dev)) {
+ ret = PTR_ERR(info->cci_dev);
+ dev_err(cpu_dev, "cpu%d: failed to get cci device\n", cpu);
+ return -ENODEV;
+@@ -420,7 +420,7 @@ static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu)
+ ret = PTR_ERR(info->inter_clk);
+ dev_err_probe(cpu_dev, ret,
+ "cpu%d: failed to get intermediate clk\n", cpu);
+- goto out_free_resources;
++ goto out_free_mux_clock;
+ }
+
+ info->proc_reg = regulator_get_optional(cpu_dev, "proc");
+@@ -428,13 +428,13 @@ static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu)
+ ret = PTR_ERR(info->proc_reg);
+ dev_err_probe(cpu_dev, ret,
+ "cpu%d: failed to get proc regulator\n", cpu);
+- goto out_free_resources;
++ goto out_free_inter_clock;
+ }
+
+ ret = regulator_enable(info->proc_reg);
+ if (ret) {
+ dev_warn(cpu_dev, "cpu%d: failed to enable vproc\n", cpu);
+- goto out_free_resources;
++ goto out_free_proc_reg;
+ }
+
+ /* Both presence and absence of sram regulator are valid cases. */
+@@ -442,14 +442,14 @@ static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu)
+ if (IS_ERR(info->sram_reg)) {
+ ret = PTR_ERR(info->sram_reg);
+ if (ret == -EPROBE_DEFER)
+- goto out_free_resources;
++ goto out_disable_proc_reg;
+
+ info->sram_reg = NULL;
+ } else {
+ ret = regulator_enable(info->sram_reg);
+ if (ret) {
+ dev_warn(cpu_dev, "cpu%d: failed to enable vsram\n", cpu);
+- goto out_free_resources;
++ goto out_free_sram_reg;
+ }
+ }
+
+@@ -458,13 +458,13 @@ static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu)
+ if (ret) {
+ dev_err(cpu_dev,
+ "cpu%d: failed to get OPP-sharing information\n", cpu);
+- goto out_free_resources;
++ goto out_disable_sram_reg;
+ }
+
+ ret = dev_pm_opp_of_cpumask_add_table(&info->cpus);
+ if (ret) {
+ dev_warn(cpu_dev, "cpu%d: no OPP table\n", cpu);
+- goto out_free_resources;
++ goto out_disable_sram_reg;
+ }
+
+ ret = clk_prepare_enable(info->cpu_clk);
+@@ -533,43 +533,41 @@ out_disable_mux_clock:
+ out_free_opp_table:
+ dev_pm_opp_of_cpumask_remove_table(&info->cpus);
+
+-out_free_resources:
+- if (regulator_is_enabled(info->proc_reg))
+- regulator_disable(info->proc_reg);
+- if (info->sram_reg && regulator_is_enabled(info->sram_reg))
++out_disable_sram_reg:
++ if (info->sram_reg)
+ regulator_disable(info->sram_reg);
+
+- if (!IS_ERR(info->proc_reg))
+- regulator_put(info->proc_reg);
+- if (!IS_ERR(info->sram_reg))
++out_free_sram_reg:
++ if (info->sram_reg)
+ regulator_put(info->sram_reg);
+- if (!IS_ERR(info->cpu_clk))
+- clk_put(info->cpu_clk);
+- if (!IS_ERR(info->inter_clk))
+- clk_put(info->inter_clk);
++
++out_disable_proc_reg:
++ regulator_disable(info->proc_reg);
++
++out_free_proc_reg:
++ regulator_put(info->proc_reg);
++
++out_free_inter_clock:
++ clk_put(info->inter_clk);
++
++out_free_mux_clock:
++ clk_put(info->cpu_clk);
+
+ return ret;
+ }
+
+ static void mtk_cpu_dvfs_info_release(struct mtk_cpu_dvfs_info *info)
+ {
+- if (!IS_ERR(info->proc_reg)) {
+- regulator_disable(info->proc_reg);
+- regulator_put(info->proc_reg);
+- }
+- if (!IS_ERR(info->sram_reg)) {
++ regulator_disable(info->proc_reg);
++ regulator_put(info->proc_reg);
++ if (info->sram_reg) {
+ regulator_disable(info->sram_reg);
+ regulator_put(info->sram_reg);
+ }
+- if (!IS_ERR(info->cpu_clk)) {
+- clk_disable_unprepare(info->cpu_clk);
+- clk_put(info->cpu_clk);
+- }
+- if (!IS_ERR(info->inter_clk)) {
+- clk_disable_unprepare(info->inter_clk);
+- clk_put(info->inter_clk);
+- }
+-
++ clk_disable_unprepare(info->cpu_clk);
++ clk_put(info->cpu_clk);
++ clk_disable_unprepare(info->inter_clk);
++ clk_put(info->inter_clk);
+ dev_pm_opp_of_cpumask_remove_table(&info->cpus);
+ dev_pm_opp_unregister_notifier(info->cpu_dev, &info->opp_nb);
+ }
+@@ -695,6 +693,15 @@ static const struct mtk_cpufreq_platform_data mt2701_platform_data = {
+ .ccifreq_supported = false,
+ };
+
++static const struct mtk_cpufreq_platform_data mt7622_platform_data = {
++ .min_volt_shift = 100000,
++ .max_volt_shift = 200000,
++ .proc_max_volt = 1360000,
++ .sram_min_volt = 0,
++ .sram_max_volt = 1360000,
++ .ccifreq_supported = false,
++};
++
+ static const struct mtk_cpufreq_platform_data mt8183_platform_data = {
+ .min_volt_shift = 100000,
+ .max_volt_shift = 200000,
+@@ -713,20 +720,29 @@ static const struct mtk_cpufreq_platform_data mt8186_platform_data = {
+ .ccifreq_supported = true,
+ };
+
++static const struct mtk_cpufreq_platform_data mt8516_platform_data = {
++ .min_volt_shift = 100000,
++ .max_volt_shift = 200000,
++ .proc_max_volt = 1310000,
++ .sram_min_volt = 0,
++ .sram_max_volt = 1310000,
++ .ccifreq_supported = false,
++};
++
+ /* List of machines supported by this driver */
+ static const struct of_device_id mtk_cpufreq_machines[] __initconst = {
+ { .compatible = "mediatek,mt2701", .data = &mt2701_platform_data },
+ { .compatible = "mediatek,mt2712", .data = &mt2701_platform_data },
+- { .compatible = "mediatek,mt7622", .data = &mt2701_platform_data },
+- { .compatible = "mediatek,mt7623", .data = &mt2701_platform_data },
+- { .compatible = "mediatek,mt8167", .data = &mt2701_platform_data },
++ { .compatible = "mediatek,mt7622", .data = &mt7622_platform_data },
++ { .compatible = "mediatek,mt7623", .data = &mt7622_platform_data },
++ { .compatible = "mediatek,mt8167", .data = &mt8516_platform_data },
+ { .compatible = "mediatek,mt817x", .data = &mt2701_platform_data },
+ { .compatible = "mediatek,mt8173", .data = &mt2701_platform_data },
+ { .compatible = "mediatek,mt8176", .data = &mt2701_platform_data },
+ { .compatible = "mediatek,mt8183", .data = &mt8183_platform_data },
+ { .compatible = "mediatek,mt8186", .data = &mt8186_platform_data },
+ { .compatible = "mediatek,mt8365", .data = &mt2701_platform_data },
+- { .compatible = "mediatek,mt8516", .data = &mt2701_platform_data },
++ { .compatible = "mediatek,mt8516", .data = &mt8516_platform_data },
+ { }
+ };
+ MODULE_DEVICE_TABLE(of, mtk_cpufreq_machines);
+diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c
+index d3f55ca06ed34..64a50777d88b8 100644
+--- a/drivers/cpufreq/qcom-cpufreq-hw.c
++++ b/drivers/cpufreq/qcom-cpufreq-hw.c
+@@ -14,7 +14,6 @@
+ #include <linux/of_address.h>
+ #include <linux/of_platform.h>
+ #include <linux/pm_opp.h>
+-#include <linux/pm_qos.h>
+ #include <linux/slab.h>
+ #include <linux/spinlock.h>
+ #include <linux/units.h>
+@@ -43,7 +42,6 @@ struct qcom_cpufreq_soc_data {
+
+ struct qcom_cpufreq_data {
+ void __iomem *base;
+- struct resource *res;
+
+ /*
+ * Mutex to synchronize between de-init sequence and re-starting LMh
+@@ -58,8 +56,6 @@ struct qcom_cpufreq_data {
+ struct clk_hw cpu_clk;
+
+ bool per_core_dcvs;
+-
+- struct freq_qos_request throttle_freq_req;
+ };
+
+ static struct {
+@@ -349,8 +345,6 @@ static void qcom_lmh_dcvs_notify(struct qcom_cpufreq_data *data)
+
+ throttled_freq = freq_hz / HZ_PER_KHZ;
+
+- freq_qos_update_request(&data->throttle_freq_req, throttled_freq);
+-
+ /* Update thermal pressure (the boost frequencies are accepted) */
+ arch_update_thermal_pressure(policy->related_cpus, throttled_freq);
+
+@@ -443,14 +437,6 @@ static int qcom_cpufreq_hw_lmh_init(struct cpufreq_policy *policy, int index)
+ if (data->throttle_irq < 0)
+ return data->throttle_irq;
+
+- ret = freq_qos_add_request(&policy->constraints,
+- &data->throttle_freq_req, FREQ_QOS_MAX,
+- FREQ_QOS_MAX_DEFAULT_VALUE);
+- if (ret < 0) {
+- dev_err(&pdev->dev, "Failed to add freq constraint (%d)\n", ret);
+- return ret;
+- }
+-
+ data->cancel_throttle = false;
+ data->policy = policy;
+
+@@ -517,7 +503,6 @@ static void qcom_cpufreq_hw_lmh_exit(struct qcom_cpufreq_data *data)
+ if (data->throttle_irq <= 0)
+ return;
+
+- freq_qos_remove_request(&data->throttle_freq_req);
+ free_irq(data->throttle_irq, data);
+ }
+
+@@ -590,16 +575,12 @@ static int qcom_cpufreq_hw_cpu_exit(struct cpufreq_policy *policy)
+ {
+ struct device *cpu_dev = get_cpu_device(policy->cpu);
+ struct qcom_cpufreq_data *data = policy->driver_data;
+- struct resource *res = data->res;
+- void __iomem *base = data->base;
+
+ dev_pm_opp_remove_all_dynamic(cpu_dev);
+ dev_pm_opp_of_cpumask_remove_table(policy->related_cpus);
+ qcom_cpufreq_hw_lmh_exit(data);
+ kfree(policy->freq_table);
+ kfree(data);
+- iounmap(base);
+- release_mem_region(res->start, resource_size(res));
+
+ return 0;
+ }
+@@ -718,17 +699,15 @@ static int qcom_cpufreq_hw_driver_probe(struct platform_device *pdev)
+ for (i = 0; i < num_domains; i++) {
+ struct qcom_cpufreq_data *data = &qcom_cpufreq.data[i];
+ struct clk_init_data clk_init = {};
+- struct resource *res;
+ void __iomem *base;
+
+- base = devm_platform_get_and_ioremap_resource(pdev, i, &res);
++ base = devm_platform_ioremap_resource(pdev, i);
+ if (IS_ERR(base)) {
+- dev_err(dev, "Failed to map resource %pR\n", res);
++ dev_err(dev, "Failed to map resource index %d\n", i);
+ return PTR_ERR(base);
+ }
+
+ data->base = base;
+- data->res = res;
+
+ /* Register CPU clock for each frequency domain */
+ clk_init.name = kasprintf(GFP_KERNEL, "qcom_cpufreq%d", i);
+diff --git a/drivers/cpuidle/cpuidle-riscv-sbi.c b/drivers/cpuidle/cpuidle-riscv-sbi.c
+index 05fe2902df9a7..af7320a768d27 100644
+--- a/drivers/cpuidle/cpuidle-riscv-sbi.c
++++ b/drivers/cpuidle/cpuidle-riscv-sbi.c
+@@ -612,7 +612,7 @@ static int __init sbi_cpuidle_init(void)
+ * 2) SBI HSM extension is available
+ */
+ if ((sbi_spec_version < sbi_mk_version(0, 3)) ||
+- sbi_probe_extension(SBI_EXT_HSM) <= 0) {
++ !sbi_probe_extension(SBI_EXT_HSM)) {
+ pr_info("HSM suspend not available\n");
+ return 0;
+ }
+diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
+index dfb103f81a64b..8d06bc30eadeb 100644
+--- a/drivers/crypto/Kconfig
++++ b/drivers/crypto/Kconfig
+@@ -820,6 +820,7 @@ config CRYPTO_DEV_SA2UL
+ select CRYPTO_AES
+ select CRYPTO_ALGAPI
+ select CRYPTO_AUTHENC
++ select CRYPTO_DES
+ select CRYPTO_SHA1
+ select CRYPTO_SHA256
+ select CRYPTO_SHA512
+diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c
+index 32253a064d0fe..3b79e0d83d40a 100644
+--- a/drivers/crypto/caam/ctrl.c
++++ b/drivers/crypto/caam/ctrl.c
+@@ -284,6 +284,10 @@ static int instantiate_rng(struct device *ctrldev, int state_handle_mask,
+ const u32 rdsta_if = RDSTA_IF0 << sh_idx;
+ const u32 rdsta_pr = RDSTA_PR0 << sh_idx;
+ const u32 rdsta_mask = rdsta_if | rdsta_pr;
++
++ /* Clear the contents before using the descriptor */
++ memset(desc, 0x00, CAAM_CMD_SZ * 7);
++
+ /*
+ * If the corresponding bit is set, this state handle
+ * was initialized by somebody else, so it's left alone.
+@@ -327,8 +331,6 @@ static int instantiate_rng(struct device *ctrldev, int state_handle_mask,
+ }
+
+ dev_info(ctrldev, "Instantiated RNG4 SH%d\n", sh_idx);
+- /* Clear the contents before recreating the descriptor */
+- memset(desc, 0x00, CAAM_CMD_SZ * 7);
+ }
+
+ kfree(desc);
+diff --git a/drivers/crypto/ccp/sp-pci.c b/drivers/crypto/ccp/sp-pci.c
+index 084d052fddccb..55411b494d69a 100644
+--- a/drivers/crypto/ccp/sp-pci.c
++++ b/drivers/crypto/ccp/sp-pci.c
+@@ -451,9 +451,9 @@ static const struct pci_device_id sp_pci_table[] = {
+ { PCI_VDEVICE(AMD, 0x1468), (kernel_ulong_t)&dev_vdata[2] },
+ { PCI_VDEVICE(AMD, 0x1486), (kernel_ulong_t)&dev_vdata[3] },
+ { PCI_VDEVICE(AMD, 0x15DF), (kernel_ulong_t)&dev_vdata[4] },
+- { PCI_VDEVICE(AMD, 0x1649), (kernel_ulong_t)&dev_vdata[4] },
+ { PCI_VDEVICE(AMD, 0x14CA), (kernel_ulong_t)&dev_vdata[5] },
+ { PCI_VDEVICE(AMD, 0x15C7), (kernel_ulong_t)&dev_vdata[6] },
++ { PCI_VDEVICE(AMD, 0x1649), (kernel_ulong_t)&dev_vdata[6] },
+ /* Last entry must be zero */
+ { 0, }
+ };
+diff --git a/drivers/crypto/inside-secure/safexcel.c b/drivers/crypto/inside-secure/safexcel.c
+index ae6110376e21c..eec44ea32a180 100644
+--- a/drivers/crypto/inside-secure/safexcel.c
++++ b/drivers/crypto/inside-secure/safexcel.c
+@@ -1639,19 +1639,23 @@ static int safexcel_probe_generic(void *pdev,
+ &priv->ring[i].rdr);
+ if (ret) {
+ dev_err(dev, "Failed to initialize rings\n");
+- return ret;
++ goto err_cleanup_rings;
+ }
+
+ priv->ring[i].rdr_req = devm_kcalloc(dev,
+ EIP197_DEFAULT_RING_SIZE,
+ sizeof(*priv->ring[i].rdr_req),
+ GFP_KERNEL);
+- if (!priv->ring[i].rdr_req)
+- return -ENOMEM;
++ if (!priv->ring[i].rdr_req) {
++ ret = -ENOMEM;
++ goto err_cleanup_rings;
++ }
+
+ ring_irq = devm_kzalloc(dev, sizeof(*ring_irq), GFP_KERNEL);
+- if (!ring_irq)
+- return -ENOMEM;
++ if (!ring_irq) {
++ ret = -ENOMEM;
++ goto err_cleanup_rings;
++ }
+
+ ring_irq->priv = priv;
+ ring_irq->ring = i;
+@@ -1665,7 +1669,8 @@ static int safexcel_probe_generic(void *pdev,
+ ring_irq);
+ if (irq < 0) {
+ dev_err(dev, "Failed to get IRQ ID for ring %d\n", i);
+- return irq;
++ ret = irq;
++ goto err_cleanup_rings;
+ }
+
+ priv->ring[i].irq = irq;
+@@ -1677,8 +1682,10 @@ static int safexcel_probe_generic(void *pdev,
+ snprintf(wq_name, 9, "wq_ring%d", i);
+ priv->ring[i].workqueue =
+ create_singlethread_workqueue(wq_name);
+- if (!priv->ring[i].workqueue)
+- return -ENOMEM;
++ if (!priv->ring[i].workqueue) {
++ ret = -ENOMEM;
++ goto err_cleanup_rings;
++ }
+
+ priv->ring[i].requests = 0;
+ priv->ring[i].busy = false;
+@@ -1695,16 +1702,26 @@ static int safexcel_probe_generic(void *pdev,
+ ret = safexcel_hw_init(priv);
+ if (ret) {
+ dev_err(dev, "HW init failed (%d)\n", ret);
+- return ret;
++ goto err_cleanup_rings;
+ }
+
+ ret = safexcel_register_algorithms(priv);
+ if (ret) {
+ dev_err(dev, "Failed to register algorithms (%d)\n", ret);
+- return ret;
++ goto err_cleanup_rings;
+ }
+
+ return 0;
++
++err_cleanup_rings:
++ for (i = 0; i < priv->config.rings; i++) {
++ if (priv->ring[i].irq)
++ irq_set_affinity_hint(priv->ring[i].irq, NULL);
++ if (priv->ring[i].workqueue)
++ destroy_workqueue(priv->ring[i].workqueue);
++ }
++
++ return ret;
+ }
+
+ static void safexcel_hw_reset_rings(struct safexcel_crypto_priv *priv)
+diff --git a/drivers/crypto/qat/qat_common/adf_accel_devices.h b/drivers/crypto/qat/qat_common/adf_accel_devices.h
+index 284f5aad3ee0b..7be933d6f0ffa 100644
+--- a/drivers/crypto/qat/qat_common/adf_accel_devices.h
++++ b/drivers/crypto/qat/qat_common/adf_accel_devices.h
+@@ -310,6 +310,7 @@ struct adf_accel_dev {
+ u8 pf_compat_ver;
+ } vf;
+ };
++ struct mutex state_lock; /* protect state of the device */
+ bool is_vf;
+ u32 accel_id;
+ };
+diff --git a/drivers/crypto/qat/qat_common/adf_common_drv.h b/drivers/crypto/qat/qat_common/adf_common_drv.h
+index 7189265573c08..4bf1fceb7052b 100644
+--- a/drivers/crypto/qat/qat_common/adf_common_drv.h
++++ b/drivers/crypto/qat/qat_common/adf_common_drv.h
+@@ -58,6 +58,9 @@ void adf_dev_stop(struct adf_accel_dev *accel_dev);
+ void adf_dev_shutdown(struct adf_accel_dev *accel_dev);
+ int adf_dev_shutdown_cache_cfg(struct adf_accel_dev *accel_dev);
+
++int adf_dev_up(struct adf_accel_dev *accel_dev, bool init_config);
++int adf_dev_down(struct adf_accel_dev *accel_dev, bool cache_config);
++
+ void adf_devmgr_update_class_index(struct adf_hw_device_data *hw_data);
+ void adf_clean_vf_map(bool);
+
+diff --git a/drivers/crypto/qat/qat_common/adf_dev_mgr.c b/drivers/crypto/qat/qat_common/adf_dev_mgr.c
+index 4c752eed10fea..86ee36feefad3 100644
+--- a/drivers/crypto/qat/qat_common/adf_dev_mgr.c
++++ b/drivers/crypto/qat/qat_common/adf_dev_mgr.c
+@@ -223,6 +223,7 @@ int adf_devmgr_add_dev(struct adf_accel_dev *accel_dev,
+ map->attached = true;
+ list_add_tail(&map->list, &vfs_table);
+ }
++ mutex_init(&accel_dev->state_lock);
+ unlock:
+ mutex_unlock(&table_lock);
+ return ret;
+@@ -269,6 +270,7 @@ void adf_devmgr_rm_dev(struct adf_accel_dev *accel_dev,
+ }
+ }
+ unlock:
++ mutex_destroy(&accel_dev->state_lock);
+ list_del(&accel_dev->list);
+ mutex_unlock(&table_lock);
+ }
+diff --git a/drivers/crypto/qat/qat_common/adf_init.c b/drivers/crypto/qat/qat_common/adf_init.c
+index cef7bb8ec0073..988cffd0b8338 100644
+--- a/drivers/crypto/qat/qat_common/adf_init.c
++++ b/drivers/crypto/qat/qat_common/adf_init.c
+@@ -400,3 +400,67 @@ int adf_dev_shutdown_cache_cfg(struct adf_accel_dev *accel_dev)
+
+ return 0;
+ }
++
++int adf_dev_down(struct adf_accel_dev *accel_dev, bool reconfig)
++{
++ int ret = 0;
++
++ if (!accel_dev)
++ return -EINVAL;
++
++ mutex_lock(&accel_dev->state_lock);
++
++ if (!adf_dev_started(accel_dev)) {
++ dev_info(&GET_DEV(accel_dev), "Device qat_dev%d already down\n",
++ accel_dev->accel_id);
++ ret = -EINVAL;
++ goto out;
++ }
++
++ if (reconfig) {
++ ret = adf_dev_shutdown_cache_cfg(accel_dev);
++ goto out;
++ }
++
++ adf_dev_stop(accel_dev);
++ adf_dev_shutdown(accel_dev);
++
++out:
++ mutex_unlock(&accel_dev->state_lock);
++ return ret;
++}
++EXPORT_SYMBOL_GPL(adf_dev_down);
++
++int adf_dev_up(struct adf_accel_dev *accel_dev, bool config)
++{
++ int ret = 0;
++
++ if (!accel_dev)
++ return -EINVAL;
++
++ mutex_lock(&accel_dev->state_lock);
++
++ if (adf_dev_started(accel_dev)) {
++ dev_info(&GET_DEV(accel_dev), "Device qat_dev%d already up\n",
++ accel_dev->accel_id);
++ ret = -EALREADY;
++ goto out;
++ }
++
++ if (config && GET_HW_DATA(accel_dev)->dev_config) {
++ ret = GET_HW_DATA(accel_dev)->dev_config(accel_dev);
++ if (unlikely(ret))
++ goto out;
++ }
++
++ ret = adf_dev_init(accel_dev);
++ if (unlikely(ret))
++ goto out;
++
++ ret = adf_dev_start(accel_dev);
++
++out:
++ mutex_unlock(&accel_dev->state_lock);
++ return ret;
++}
++EXPORT_SYMBOL_GPL(adf_dev_up);
+diff --git a/drivers/crypto/qat/qat_common/adf_sysfs.c b/drivers/crypto/qat/qat_common/adf_sysfs.c
+index e8b078e719c20..3eb6611ab1b11 100644
+--- a/drivers/crypto/qat/qat_common/adf_sysfs.c
++++ b/drivers/crypto/qat/qat_common/adf_sysfs.c
+@@ -50,38 +50,21 @@ static ssize_t state_store(struct device *dev, struct device_attribute *attr,
+
+ switch (ret) {
+ case DEV_DOWN:
+- if (!adf_dev_started(accel_dev)) {
+- dev_info(dev, "Device qat_dev%d already down\n",
+- accel_id);
+- return -EINVAL;
+- }
+-
+ dev_info(dev, "Stopping device qat_dev%d\n", accel_id);
+
+- ret = adf_dev_shutdown_cache_cfg(accel_dev);
++ ret = adf_dev_down(accel_dev, true);
+ if (ret < 0)
+ return -EINVAL;
+
+ break;
+ case DEV_UP:
+- if (adf_dev_started(accel_dev)) {
+- dev_info(dev, "Device qat_dev%d already up\n",
+- accel_id);
+- return -EINVAL;
+- }
+-
+ dev_info(dev, "Starting device qat_dev%d\n", accel_id);
+
+- ret = GET_HW_DATA(accel_dev)->dev_config(accel_dev);
+- if (!ret)
+- ret = adf_dev_init(accel_dev);
+- if (!ret)
+- ret = adf_dev_start(accel_dev);
+-
++ ret = adf_dev_up(accel_dev, true);
+ if (ret < 0) {
+ dev_err(dev, "Failed to start device qat_dev%d\n",
+ accel_id);
+- adf_dev_shutdown_cache_cfg(accel_dev);
++ adf_dev_down(accel_dev, true);
+ return ret;
+ }
+ break;
+diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c
+index dcc16d7cb8f37..c6a244d54ff68 100644
+--- a/drivers/cxl/core/hdm.c
++++ b/drivers/cxl/core/hdm.c
+@@ -219,8 +219,11 @@ static int __cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
+
+ lockdep_assert_held_write(&cxl_dpa_rwsem);
+
+- if (!len)
+- goto success;
++ if (!len) {
++ dev_warn(dev, "decoder%d.%d: empty reservation attempted\n",
++ port->id, cxled->cxld.id);
++ return -EINVAL;
++ }
+
+ if (cxled->dpa_res) {
+ dev_dbg(dev, "decoder%d.%d: existing allocation %pr assigned\n",
+@@ -273,7 +276,6 @@ static int __cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
+ cxled->mode = CXL_DECODER_MIXED;
+ }
+
+-success:
+ port->hdm_end++;
+ get_device(&cxled->cxld.dev);
+ return 0;
+@@ -732,6 +734,13 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
+ port->id, cxld->id);
+ return -ENXIO;
+ }
++
++ if (size == 0) {
++ dev_warn(&port->dev,
++ "decoder%d.%d: Committed with zero size\n",
++ port->id, cxld->id);
++ return -ENXIO;
++ }
+ port->commit_end = cxld->id;
+ } else {
+ /* unless / until type-2 drivers arrive, assume type-3 */
+diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c
+index d6c9781cd46af..bfc8ae2143957 100644
+--- a/drivers/dma/at_xdmac.c
++++ b/drivers/dma/at_xdmac.c
+@@ -243,6 +243,7 @@ struct at_xdmac {
+ int irq;
+ struct clk *clk;
+ u32 save_gim;
++ u32 save_gs;
+ struct dma_pool *at_xdmac_desc_pool;
+ const struct at_xdmac_layout *layout;
+ struct at_xdmac_chan chan[];
+@@ -1988,6 +1989,7 @@ static int __maybe_unused atmel_xdmac_suspend(struct device *dev)
+ }
+ }
+ atxdmac->save_gim = at_xdmac_read(atxdmac, AT_XDMAC_GIM);
++ atxdmac->save_gs = at_xdmac_read(atxdmac, AT_XDMAC_GS);
+
+ at_xdmac_off(atxdmac);
+ clk_disable_unprepare(atxdmac->clk);
+@@ -2027,7 +2029,8 @@ static int __maybe_unused atmel_xdmac_resume(struct device *dev)
+ at_xdmac_chan_write(atchan, AT_XDMAC_CNDC, atchan->save_cndc);
+ at_xdmac_chan_write(atchan, AT_XDMAC_CIE, atchan->save_cim);
+ wmb();
+- at_xdmac_write(atxdmac, AT_XDMAC_GE, atchan->mask);
++ if (atxdmac->save_gs & atchan->mask)
++ at_xdmac_write(atxdmac, AT_XDMAC_GE, atchan->mask);
+ }
+ }
+ return 0;
+diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c
+index 52bdf04aff511..ef4cdcf6beba0 100644
+--- a/drivers/dma/dw-edma/dw-edma-core.c
++++ b/drivers/dma/dw-edma/dw-edma-core.c
+@@ -170,7 +170,7 @@ static void vchan_free_desc(struct virt_dma_desc *vdesc)
+ dw_edma_free_desc(vd2dw_edma_desc(vdesc));
+ }
+
+-static void dw_edma_start_transfer(struct dw_edma_chan *chan)
++static int dw_edma_start_transfer(struct dw_edma_chan *chan)
+ {
+ struct dw_edma_chunk *child;
+ struct dw_edma_desc *desc;
+@@ -178,16 +178,16 @@ static void dw_edma_start_transfer(struct dw_edma_chan *chan)
+
+ vd = vchan_next_desc(&chan->vc);
+ if (!vd)
+- return;
++ return 0;
+
+ desc = vd2dw_edma_desc(vd);
+ if (!desc)
+- return;
++ return 0;
+
+ child = list_first_entry_or_null(&desc->chunk->list,
+ struct dw_edma_chunk, list);
+ if (!child)
+- return;
++ return 0;
+
+ dw_edma_v0_core_start(child, !desc->xfer_sz);
+ desc->xfer_sz += child->ll_region.sz;
+@@ -195,6 +195,8 @@ static void dw_edma_start_transfer(struct dw_edma_chan *chan)
+ list_del(&child->list);
+ kfree(child);
+ desc->chunks_alloc--;
++
++ return 1;
+ }
+
+ static int dw_edma_device_config(struct dma_chan *dchan,
+@@ -277,9 +279,12 @@ static void dw_edma_device_issue_pending(struct dma_chan *dchan)
+ struct dw_edma_chan *chan = dchan2dw_edma_chan(dchan);
+ unsigned long flags;
+
++ if (!chan->configured)
++ return;
++
+ spin_lock_irqsave(&chan->vc.lock, flags);
+- if (chan->configured && chan->request == EDMA_REQ_NONE &&
+- chan->status == EDMA_ST_IDLE && vchan_issue_pending(&chan->vc)) {
++ if (vchan_issue_pending(&chan->vc) && chan->request == EDMA_REQ_NONE &&
++ chan->status == EDMA_ST_IDLE) {
+ chan->status = EDMA_ST_BUSY;
+ dw_edma_start_transfer(chan);
+ }
+@@ -572,14 +577,14 @@ static void dw_edma_done_interrupt(struct dw_edma_chan *chan)
+ switch (chan->request) {
+ case EDMA_REQ_NONE:
+ desc = vd2dw_edma_desc(vd);
+- if (desc->chunks_alloc) {
+- chan->status = EDMA_ST_BUSY;
+- dw_edma_start_transfer(chan);
+- } else {
++ if (!desc->chunks_alloc) {
+ list_del(&vd->node);
+ vchan_cookie_complete(vd);
+- chan->status = EDMA_ST_IDLE;
+ }
++
++ /* Continue transferring if there are remaining chunks or issued requests.
++ */
++ chan->status = dw_edma_start_transfer(chan) ? EDMA_ST_BUSY : EDMA_ST_IDLE;
+ break;
+
+ case EDMA_REQ_STOP:
+diff --git a/drivers/dma/mv_xor_v2.c b/drivers/dma/mv_xor_v2.c
+index 113834e1167b6..d086ff1824f82 100644
+--- a/drivers/dma/mv_xor_v2.c
++++ b/drivers/dma/mv_xor_v2.c
+@@ -755,7 +755,7 @@ static int mv_xor_v2_probe(struct platform_device *pdev)
+
+ xor_dev->clk = devm_clk_get(&pdev->dev, NULL);
+ if (PTR_ERR(xor_dev->clk) == -EPROBE_DEFER) {
+- ret = EPROBE_DEFER;
++ ret = -EPROBE_DEFER;
+ goto disable_reg_clk;
+ }
+ if (!IS_ERR(xor_dev->clk)) {
+diff --git a/drivers/dma/qcom/gpi.c b/drivers/dma/qcom/gpi.c
+index 59a36cbf9b5f7..932628b319c81 100644
+--- a/drivers/dma/qcom/gpi.c
++++ b/drivers/dma/qcom/gpi.c
+@@ -1966,7 +1966,6 @@ error_alloc_ev_ring:
+ error_config_int:
+ gpi_free_ring(&gpii->ev_ring, gpii);
+ exit_gpi_init:
+- mutex_unlock(&gpii->ctrl_lock);
+ return ret;
+ }
+
+diff --git a/drivers/edac/skx_base.c b/drivers/edac/skx_base.c
+index 9397abb42c498..0a862336a7ce8 100644
+--- a/drivers/edac/skx_base.c
++++ b/drivers/edac/skx_base.c
+@@ -510,7 +510,7 @@ rir_found:
+ }
+
+ static u8 skx_close_row[] = {
+- 15, 16, 17, 18, 20, 21, 22, 28, 10, 11, 12, 13, 29, 30, 31, 32, 33
++ 15, 16, 17, 18, 20, 21, 22, 28, 10, 11, 12, 13, 29, 30, 31, 32, 33, 34
+ };
+
+ static u8 skx_close_column[] = {
+@@ -518,7 +518,7 @@ static u8 skx_close_column[] = {
+ };
+
+ static u8 skx_open_row[] = {
+- 14, 15, 16, 20, 28, 21, 22, 23, 24, 25, 26, 27, 29, 30, 31, 32, 33
++ 14, 15, 16, 20, 28, 21, 22, 23, 24, 25, 26, 27, 29, 30, 31, 32, 33, 34
+ };
+
+ static u8 skx_open_column[] = {
+diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
+index ffdad59ec81fc..fe06dc1936896 100644
+--- a/drivers/firmware/arm_scmi/driver.c
++++ b/drivers/firmware/arm_scmi/driver.c
+@@ -1981,7 +1981,7 @@ static int scmi_xfer_info_init(struct scmi_info *sinfo)
+ return ret;
+
+ ret = __scmi_xfer_info_init(sinfo, &sinfo->tx_minfo);
+- if (!ret && idr_find(&sinfo->rx_idr, SCMI_PROTOCOL_BASE))
++ if (!ret && !idr_is_empty(&sinfo->rx_idr))
+ ret = __scmi_xfer_info_init(sinfo, &sinfo->rx_minfo);
+
+ return ret;
+diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c
+index cdbfe54c81467..51eb85354c058 100644
+--- a/drivers/firmware/qcom_scm.c
++++ b/drivers/firmware/qcom_scm.c
+@@ -1418,8 +1418,7 @@ static int qcom_scm_probe(struct platform_device *pdev)
+ static void qcom_scm_shutdown(struct platform_device *pdev)
+ {
+ /* Clean shutdown, disable download mode to allow normal restart */
+- if (download_mode)
+- qcom_scm_set_download_mode(false);
++ qcom_scm_set_download_mode(false);
+ }
+
+ static const struct of_device_id qcom_scm_dt_match[] = {
+diff --git a/drivers/firmware/stratix10-svc.c b/drivers/firmware/stratix10-svc.c
+index bde1f543f5298..80f4e2d14e046 100644
+--- a/drivers/firmware/stratix10-svc.c
++++ b/drivers/firmware/stratix10-svc.c
+@@ -1133,8 +1133,8 @@ static int stratix10_svc_drv_probe(struct platform_device *pdev)
+ return ret;
+
+ genpool = svc_create_memory_pool(pdev, sh_memory);
+- if (!genpool)
+- return -ENOMEM;
++ if (IS_ERR(genpool))
++ return PTR_ERR(genpool);
+
+ /* allocate service controller and supporting channel */
+ controller = devm_kzalloc(dev, sizeof(*controller), GFP_KERNEL);
+diff --git a/drivers/fpga/fpga-bridge.c b/drivers/fpga/fpga-bridge.c
+index 13918c8c839ea..833ce13ff6f86 100644
+--- a/drivers/fpga/fpga-bridge.c
++++ b/drivers/fpga/fpga-bridge.c
+@@ -115,7 +115,7 @@ static int fpga_bridge_dev_match(struct device *dev, const void *data)
+ /**
+ * fpga_bridge_get - get an exclusive reference to an fpga bridge
+ * @dev: parent device that fpga bridge was registered with
+- * @info: fpga manager info
++ * @info: fpga image specific information
+ *
+ * Given a device, get an exclusive reference to an fpga bridge.
+ *
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+index 3dac1e139c5f3..533263d442657 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+@@ -35,6 +35,7 @@
+ #include <linux/devcoredump.h>
+ #include <generated/utsrelease.h>
+ #include <linux/pci-p2pdma.h>
++#include <linux/apple-gmux.h>
+
+ #include <drm/drm_aperture.h>
+ #include <drm/drm_atomic_helper.h>
+@@ -3952,12 +3953,15 @@ fence_driver_init:
+ if ((adev->pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA)
+ vga_client_register(adev->pdev, amdgpu_device_vga_set_decode);
+
+- if (amdgpu_device_supports_px(ddev)) {
+- px = true;
++ px = amdgpu_device_supports_px(ddev);
++
++ if (px || (!pci_is_thunderbolt_attached(adev->pdev) &&
++ apple_gmux_detect(NULL, NULL)))
+ vga_switcheroo_register_client(adev->pdev,
+ &amdgpu_switcheroo_ops, px);
++
++ if (px)
+ vga_switcheroo_init_domain_pm_ops(adev->dev, &adev->vga_pm_domain);
+- }
+
+ if (adev->gmc.xgmi.pending_reset)
+ queue_delayed_work(system_wq, &mgpu_info.delayed_reset_work,
+@@ -4063,6 +4067,7 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev)
+ void amdgpu_device_fini_sw(struct amdgpu_device *adev)
+ {
+ int idx;
++ bool px;
+
+ amdgpu_fence_driver_sw_fini(adev);
+ amdgpu_device_ip_fini(adev);
+@@ -4082,10 +4087,16 @@ void amdgpu_device_fini_sw(struct amdgpu_device *adev)
+
+ kfree(adev->bios);
+ adev->bios = NULL;
+- if (amdgpu_device_supports_px(adev_to_drm(adev))) {
++
++ px = amdgpu_device_supports_px(adev_to_drm(adev));
++
++ if (px || (!pci_is_thunderbolt_attached(adev->pdev) &&
++ apple_gmux_detect(NULL, NULL)))
+ vga_switcheroo_unregister_client(adev->pdev);
++
++ if (px)
+ vga_switcheroo_fini_domain_pm_ops(adev->dev);
+- }
++
+ if ((adev->pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA)
+ vga_client_unregister(adev->pdev);
+
+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 7fa1728384bfd..422909d1f352b 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -1771,7 +1771,8 @@ static void amdgpu_dm_fini(struct amdgpu_device *adev)
+ dc_deinit_callbacks(adev->dm.dc);
+ #endif
+
+- dc_dmub_srv_destroy(&adev->dm.dc->ctx->dmub_srv);
++ if (adev->dm.dc)
++ dc_dmub_srv_destroy(&adev->dm.dc->ctx->dmub_srv);
+
+ if (dc_enable_dmub_notifications(adev->dm.dc)) {
+ kfree(adev->dm.dmub_notify);
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
+index 26291db0a3cf6..872d06fe14364 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
+@@ -122,6 +122,9 @@ bool amdgpu_dm_link_setup_psr(struct dc_stream_state *stream)
+ psr_config.allow_multi_disp_optimizations =
+ (amdgpu_dc_feature_mask & DC_PSR_ALLOW_MULTI_DISP_OPT);
+
++ if (!psr_su_set_y_granularity(dc, link, stream, &psr_config))
++ return false;
++
+ ret = dc_link_setup_psr(link, stream, &psr_config, &psr_context);
+
+ }
+diff --git a/drivers/gpu/drm/amd/display/dc/dce60/Makefile b/drivers/gpu/drm/amd/display/dc/dce60/Makefile
+index dda596fa1cd76..fee331accc0e7 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce60/Makefile
++++ b/drivers/gpu/drm/amd/display/dc/dce60/Makefile
+@@ -23,7 +23,7 @@
+ # Makefile for the 'controller' sub-component of DAL.
+ # It provides the control and status of HW CRTC block.
+
+-CFLAGS_AMDDALPATH)/dc/dce60/dce60_resource.o = $(call cc-disable-warning, override-init)
++CFLAGS_$(AMDDALPATH)/dc/dce60/dce60_resource.o = $(call cc-disable-warning, override-init)
+
+ DCE60 = dce60_timing_generator.o dce60_hw_sequencer.o \
+ dce60_resource.o
+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 c18c52a60100e..c4e206aedf731 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
+@@ -1648,7 +1648,8 @@ noinline bool dcn30_internal_validate_bw(
+ display_e2e_pipe_params_st *pipes,
+ int *pipe_cnt_out,
+ int *vlevel_out,
+- bool fast_validate)
++ bool fast_validate,
++ bool allow_self_refresh_only)
+ {
+ bool out = false;
+ bool repopulate_pipes = false;
+@@ -1675,7 +1676,7 @@ noinline bool dcn30_internal_validate_bw(
+
+ dml_log_pipe_params(&context->bw_ctx.dml, pipes, pipe_cnt);
+
+- if (!fast_validate) {
++ if (!fast_validate || !allow_self_refresh_only) {
+ /*
+ * DML favors voltage over p-state, but we're more interested in
+ * supporting p-state over voltage. We can't support p-state in
+@@ -1688,11 +1689,12 @@ noinline bool dcn30_internal_validate_bw(
+ if (vlevel < context->bw_ctx.dml.soc.num_states)
+ vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, vlevel, split, merge);
+ }
+- if (fast_validate || vlevel == context->bw_ctx.dml.soc.num_states ||
+- vba->DRAMClockChangeSupport[vlevel][vba->maxMpcComb] == dm_dram_clock_change_unsupported) {
++ if (allow_self_refresh_only &&
++ (fast_validate || vlevel == context->bw_ctx.dml.soc.num_states ||
++ vba->DRAMClockChangeSupport[vlevel][vba->maxMpcComb] == dm_dram_clock_change_unsupported)) {
+ /*
+- * If mode is unsupported or there's still no p-state support then
+- * fall back to favoring voltage.
++ * If mode is unsupported or there's still no p-state support
++ * then fall back to favoring voltage.
+ *
+ * We don't actually support prefetch mode 2, so require that we
+ * at least support prefetch mode 1.
+@@ -2063,7 +2065,7 @@ bool dcn30_validate_bandwidth(struct dc *dc,
+ BW_VAL_TRACE_COUNT();
+
+ DC_FP_START();
+- out = dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate);
++ out = dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate, true);
+ DC_FP_END();
+
+ if (pipe_cnt == 0)
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.h b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.h
+index 7d063c7d6a4bf..8e6b8b7368fdb 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.h
++++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.h
+@@ -64,7 +64,8 @@ bool dcn30_internal_validate_bw(
+ display_e2e_pipe_params_st *pipes,
+ int *pipe_cnt_out,
+ int *vlevel_out,
+- bool fast_validate);
++ bool fast_validate,
++ bool allow_self_refresh_only);
+ void dcn30_calculate_wm_and_dlg(
+ struct dc *dc, struct dc_state *context,
+ display_e2e_pipe_params_st *pipes,
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
+index 3ca517dcc82dc..d3918a10773a3 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
+@@ -1795,7 +1795,7 @@ bool dcn31_validate_bandwidth(struct dc *dc,
+ BW_VAL_TRACE_COUNT();
+
+ DC_FP_START();
+- out = dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate);
++ out = dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate, true);
+ DC_FP_END();
+
+ // Disable fast_validate to set min dcfclk in alculate_wm_and_dlg
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c
+index 73f519dbdb531..9ffba4c6fe550 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c
+@@ -1697,6 +1697,81 @@ static void dcn314_get_panel_config_defaults(struct dc_panel_config *panel_confi
+ *panel_config = panel_config_defaults;
+ }
+
++static bool filter_modes_for_single_channel_workaround(struct dc *dc,
++ struct dc_state *context)
++{
++ // Filter 2K@240Hz+8K@24fps above combination timing if memory only has single dimm LPDDR
++ if (dc->clk_mgr->bw_params->vram_type == 34 && dc->clk_mgr->bw_params->num_channels < 2) {
++ int total_phy_pix_clk = 0;
++
++ for (int i = 0; i < context->stream_count; i++)
++ if (context->res_ctx.pipe_ctx[i].stream)
++ total_phy_pix_clk += context->res_ctx.pipe_ctx[i].stream->phy_pix_clk;
++
++ if (total_phy_pix_clk >= (1148928+826260)) //2K@240Hz+8K@24fps
++ return true;
++ }
++ return false;
++}
++
++bool dcn314_validate_bandwidth(struct dc *dc,
++ struct dc_state *context,
++ bool fast_validate)
++{
++ bool out = false;
++
++ BW_VAL_TRACE_SETUP();
++
++ int vlevel = 0;
++ int pipe_cnt = 0;
++ display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_KERNEL);
++ DC_LOGGER_INIT(dc->ctx->logger);
++
++ BW_VAL_TRACE_COUNT();
++
++ if (filter_modes_for_single_channel_workaround(dc, context))
++ goto validate_fail;
++
++ DC_FP_START();
++ // do not support self refresh only
++ out = dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate, false);
++ DC_FP_END();
++
++ // Disable fast_validate to set min dcfclk in calculate_wm_and_dlg
++ if (pipe_cnt == 0)
++ fast_validate = false;
++
++ if (!out)
++ goto validate_fail;
++
++ BW_VAL_TRACE_END_VOLTAGE_LEVEL();
++
++ if (fast_validate) {
++ BW_VAL_TRACE_SKIP(fast);
++ goto validate_out;
++ }
++
++ dc->res_pool->funcs->calculate_wm_and_dlg(dc, context, pipes, pipe_cnt, vlevel);
++
++ BW_VAL_TRACE_END_WATERMARKS();
++
++ goto validate_out;
++
++validate_fail:
++ DC_LOG_WARNING("Mode Validation Warning: %s failed validation.\n",
++ dml_get_status_message(context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states]));
++
++ BW_VAL_TRACE_SKIP(fail);
++ out = false;
++
++validate_out:
++ kfree(pipes);
++
++ BW_VAL_TRACE_FINISH();
++
++ return out;
++}
++
+ static struct resource_funcs dcn314_res_pool_funcs = {
+ .destroy = dcn314_destroy_resource_pool,
+ .link_enc_create = dcn31_link_encoder_create,
+@@ -1704,7 +1779,7 @@ static struct resource_funcs dcn314_res_pool_funcs = {
+ .link_encs_assign = link_enc_cfg_link_encs_assign,
+ .link_enc_unassign = link_enc_cfg_link_enc_unassign,
+ .panel_cntl_create = dcn31_panel_cntl_create,
+- .validate_bandwidth = dcn31_validate_bandwidth,
++ .validate_bandwidth = dcn314_validate_bandwidth,
+ .calculate_wm_and_dlg = dcn31_calculate_wm_and_dlg,
+ .update_soc_for_wm_a = dcn31_update_soc_for_wm_a,
+ .populate_dml_pipes = dcn314_populate_dml_pipes_from_context,
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.h b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.h
+index 0dd3153aa5c17..49ffe71018dfb 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.h
++++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.h
+@@ -39,6 +39,10 @@ struct dcn314_resource_pool {
+ struct resource_pool base;
+ };
+
++bool dcn314_validate_bandwidth(struct dc *dc,
++ struct dc_state *context,
++ bool fast_validate);
++
+ struct resource_pool *dcn314_create_resource_pool(
+ const struct dc_init_data *init_data,
+ struct dc *dc);
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.c
+index d4c0f9cdac8e2..4fa6363647937 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.c
+@@ -634,7 +634,7 @@ int dcn30_find_dummy_latency_index_for_fw_based_mclk_switch(struct dc *dc,
+ while (dummy_latency_index < max_latency_table_entries) {
+ context->bw_ctx.dml.soc.dram_clock_change_latency_us =
+ dc->clk_mgr->bw_params->dummy_pstate_table[dummy_latency_index].dummy_pstate_latency_us;
+- dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, false);
++ dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, false, true);
+
+ if (context->bw_ctx.dml.soc.allow_dram_self_refresh_or_dram_clock_change_in_vblank ==
+ dm_allow_self_refresh_and_mclk_switch)
+diff --git a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c
+index 9b5d9b2c9a6a7..e75b443ee95dc 100644
+--- a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c
++++ b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c
+@@ -916,3 +916,38 @@ bool mod_power_only_edp(const struct dc_state *context, const struct dc_stream_s
+ {
+ return context && context->stream_count == 1 && dc_is_embedded_signal(stream->signal);
+ }
++
++bool psr_su_set_y_granularity(struct dc *dc, struct dc_link *link,
++ struct dc_stream_state *stream,
++ struct psr_config *config)
++{
++ uint16_t pic_height;
++ uint8_t slice_height;
++
++ if ((link->connector_signal & SIGNAL_TYPE_EDP) &&
++ (!dc->caps.edp_dsc_support ||
++ link->panel_config.dsc.disable_dsc_edp ||
++ !link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT ||
++ !stream->timing.dsc_cfg.num_slices_v))
++ return true;
++
++ pic_height = stream->timing.v_addressable +
++ stream->timing.v_border_top + stream->timing.v_border_bottom;
++
++ if (stream->timing.dsc_cfg.num_slices_v == 0)
++ return false;
++
++ slice_height = pic_height / stream->timing.dsc_cfg.num_slices_v;
++
++ if (slice_height) {
++ if (config->su_y_granularity &&
++ (slice_height % config->su_y_granularity)) {
++ ASSERT(0);
++ return false;
++ }
++
++ config->su_y_granularity = slice_height;
++ }
++
++ return true;
++}
+diff --git a/drivers/gpu/drm/amd/display/modules/power/power_helpers.h b/drivers/gpu/drm/amd/display/modules/power/power_helpers.h
+index 316452e9dbc91..bb16b37b83da7 100644
+--- a/drivers/gpu/drm/amd/display/modules/power/power_helpers.h
++++ b/drivers/gpu/drm/amd/display/modules/power/power_helpers.h
+@@ -59,4 +59,7 @@ void mod_power_calc_psr_configs(struct psr_config *psr_config,
+ const struct dc_stream_state *stream);
+ bool mod_power_only_edp(const struct dc_state *context,
+ const struct dc_stream_state *stream);
++bool psr_su_set_y_granularity(struct dc *dc, struct dc_link *link,
++ struct dc_stream_state *stream,
++ struct psr_config *config);
+ #endif /* MODULES_POWER_POWER_HELPERS_H_ */
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
+index 6ab1550235926..516e07c367f00 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
+@@ -161,10 +161,15 @@ int smu_get_dpm_freq_range(struct smu_context *smu,
+
+ int smu_set_gfx_power_up_by_imu(struct smu_context *smu)
+ {
+- if (!smu->ppt_funcs || !smu->ppt_funcs->set_gfx_power_up_by_imu)
+- return -EOPNOTSUPP;
++ int ret = 0;
++ struct amdgpu_device *adev = smu->adev;
+
+- return smu->ppt_funcs->set_gfx_power_up_by_imu(smu);
++ if (smu->ppt_funcs->set_gfx_power_up_by_imu) {
++ ret = smu->ppt_funcs->set_gfx_power_up_by_imu(smu);
++ if (ret)
++ dev_err(adev->dev, "Failed to enable gfx imu!\n");
++ }
++ return ret;
+ }
+
+ static u32 smu_get_mclk(void *handle, bool low)
+@@ -195,6 +200,19 @@ static u32 smu_get_sclk(void *handle, bool low)
+ return clk_freq * 100;
+ }
+
++static int smu_set_gfx_imu_enable(struct smu_context *smu)
++{
++ struct amdgpu_device *adev = smu->adev;
++
++ if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP)
++ return 0;
++
++ if (amdgpu_in_reset(smu->adev) || adev->in_s0ix)
++ return 0;
++
++ return smu_set_gfx_power_up_by_imu(smu);
++}
++
+ static int smu_dpm_set_vcn_enable(struct smu_context *smu,
+ bool enable)
+ {
+@@ -1386,15 +1404,9 @@ static int smu_hw_init(void *handle)
+ }
+
+ if (smu->is_apu) {
+- if ((smu->ppt_funcs->set_gfx_power_up_by_imu) &&
+- likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) {
+- ret = smu->ppt_funcs->set_gfx_power_up_by_imu(smu);
+- if (ret) {
+- dev_err(adev->dev, "Failed to Enable gfx imu!\n");
+- return ret;
+- }
+- }
+-
++ ret = smu_set_gfx_imu_enable(smu);
++ if (ret)
++ return ret;
+ smu_dpm_set_vcn_enable(smu, true);
+ smu_dpm_set_jpeg_enable(smu, true);
+ smu_set_gfx_cgpg(smu, true);
+@@ -1671,6 +1683,10 @@ static int smu_resume(void *handle)
+ return ret;
+ }
+
++ ret = smu_set_gfx_imu_enable(smu);
++ if (ret)
++ return ret;
++
+ smu_set_gfx_cgpg(smu, true);
+
+ smu->disable_uclk_switch = 0;
+diff --git a/drivers/gpu/drm/bridge/adv7511/adv7533.c b/drivers/gpu/drm/bridge/adv7511/adv7533.c
+index fdfeadcefe805..7e3e56441aedc 100644
+--- a/drivers/gpu/drm/bridge/adv7511/adv7533.c
++++ b/drivers/gpu/drm/bridge/adv7511/adv7533.c
+@@ -103,22 +103,19 @@ void adv7533_dsi_power_off(struct adv7511 *adv)
+ enum drm_mode_status adv7533_mode_valid(struct adv7511 *adv,
+ const struct drm_display_mode *mode)
+ {
+- int lanes;
++ unsigned long max_lane_freq;
+ struct mipi_dsi_device *dsi = adv->dsi;
++ u8 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
+
+- if (mode->clock > 80000)
+- lanes = 4;
+- else
+- lanes = 3;
+-
+- /*
+- * TODO: add support for dynamic switching of lanes
+- * by using the bridge pre_enable() op . Till then filter
+- * out the modes which shall need different number of lanes
+- * than what was configured in the device tree.
+- */
+- if (lanes != dsi->lanes)
+- return MODE_BAD;
++ /* Check max clock for either 7533 or 7535 */
++ if (mode->clock > (adv->type == ADV7533 ? 80000 : 148500))
++ return MODE_CLOCK_HIGH;
++
++ /* Check max clock for each lane */
++ max_lane_freq = (adv->type == ADV7533 ? 800000 : 891000);
++
++ if (mode->clock * bpp > max_lane_freq * adv->num_dsi_lanes)
++ return MODE_CLOCK_HIGH;
+
+ return MODE_OK;
+ }
+diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
+index bcd9611dabfd9..1a672747c83b8 100644
+--- a/drivers/gpu/drm/drm_probe_helper.c
++++ b/drivers/gpu/drm/drm_probe_helper.c
+@@ -556,8 +556,9 @@ retry:
+ */
+ dev->mode_config.delayed_event = true;
+ if (dev->mode_config.poll_enabled)
+- schedule_delayed_work(&dev->mode_config.output_poll_work,
+- 0);
++ mod_delayed_work(system_wq,
++ &dev->mode_config.output_poll_work,
++ 0);
+ }
+
+ /* Re-enable polling in case the global poll config changed. */
+diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
+index 2d46dcf820a23..80eb4f92167cc 100644
+--- a/drivers/gpu/drm/i915/display/intel_display.c
++++ b/drivers/gpu/drm/i915/display/intel_display.c
+@@ -1090,7 +1090,7 @@ intel_get_crtc_new_encoder(const struct intel_atomic_state *state,
+ num_encoders++;
+ }
+
+- drm_WARN(encoder->base.dev, num_encoders != 1,
++ drm_WARN(state->base.dev, num_encoders != 1,
+ "%d encoders for pipe %c\n",
+ num_encoders, pipe_name(master_crtc->pipe));
+
+diff --git a/drivers/gpu/drm/lima/lima_drv.c b/drivers/gpu/drm/lima/lima_drv.c
+index 7b8d7178d09aa..39cab4a55f572 100644
+--- a/drivers/gpu/drm/lima/lima_drv.c
++++ b/drivers/gpu/drm/lima/lima_drv.c
+@@ -392,8 +392,10 @@ static int lima_pdev_probe(struct platform_device *pdev)
+
+ /* Allocate and initialize the DRM device. */
+ ddev = drm_dev_alloc(&lima_drm_driver, &pdev->dev);
+- if (IS_ERR(ddev))
+- return PTR_ERR(ddev);
++ if (IS_ERR(ddev)) {
++ err = PTR_ERR(ddev);
++ goto err_out0;
++ }
+
+ ddev->dev_private = ldev;
+ ldev->ddev = ddev;
+diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
+index 9d085c05c49c3..007af69e5026f 100644
+--- a/drivers/gpu/drm/mediatek/mtk_dp.c
++++ b/drivers/gpu/drm/mediatek/mtk_dp.c
+@@ -806,10 +806,9 @@ static int mtk_dp_aux_wait_for_completion(struct mtk_dp *mtk_dp, bool is_read)
+ }
+
+ static int mtk_dp_aux_do_transfer(struct mtk_dp *mtk_dp, bool is_read, u8 cmd,
+- u32 addr, u8 *buf, size_t length)
++ u32 addr, u8 *buf, size_t length, u8 *reply_cmd)
+ {
+ int ret;
+- u32 reply_cmd;
+
+ if (is_read && (length > DP_AUX_MAX_PAYLOAD_BYTES ||
+ (cmd == DP_AUX_NATIVE_READ && !length)))
+@@ -841,10 +840,10 @@ static int mtk_dp_aux_do_transfer(struct mtk_dp *mtk_dp, bool is_read, u8 cmd,
+ /* Wait for feedback from sink device. */
+ ret = mtk_dp_aux_wait_for_completion(mtk_dp, is_read);
+
+- reply_cmd = mtk_dp_read(mtk_dp, MTK_DP_AUX_P0_3624) &
+- AUX_RX_REPLY_COMMAND_AUX_TX_P0_MASK;
++ *reply_cmd = mtk_dp_read(mtk_dp, MTK_DP_AUX_P0_3624) &
++ AUX_RX_REPLY_COMMAND_AUX_TX_P0_MASK;
+
+- if (ret || reply_cmd) {
++ if (ret) {
+ u32 phy_status = mtk_dp_read(mtk_dp, MTK_DP_AUX_P0_3628) &
+ AUX_RX_PHY_STATE_AUX_TX_P0_MASK;
+ if (phy_status != AUX_RX_PHY_STATE_AUX_TX_P0_RX_IDLE) {
+@@ -1823,7 +1822,8 @@ static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
+ spin_unlock_irqrestore(&mtk_dp->irq_thread_lock, flags);
+
+ if (status & MTK_DP_THREAD_CABLE_STATE_CHG) {
+- drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
++ if (mtk_dp->bridge.dev)
++ drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
+
+ if (!mtk_dp->train_info.cable_plugged_in) {
+ mtk_dp_disable_sdp_aui(mtk_dp);
+@@ -2070,7 +2070,7 @@ static ssize_t mtk_dp_aux_transfer(struct drm_dp_aux *mtk_aux,
+ ret = mtk_dp_aux_do_transfer(mtk_dp, is_read, request,
+ msg->address + accessed_bytes,
+ msg->buffer + accessed_bytes,
+- to_access);
++ to_access, &msg->reply);
+
+ if (ret) {
+ drm_info(mtk_dp->drm_dev,
+@@ -2080,7 +2080,6 @@ static ssize_t mtk_dp_aux_transfer(struct drm_dp_aux *mtk_aux,
+ accessed_bytes += to_access;
+ } while (accessed_bytes < msg->size);
+
+- msg->reply = DP_AUX_NATIVE_REPLY_ACK | DP_AUX_I2C_REPLY_ACK;
+ return msg->size;
+ err:
+ msg->reply = DP_AUX_NATIVE_REPLY_NACK | DP_AUX_I2C_REPLY_NACK;
+diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+index 047c5e8c87ff4..f21f1bb7f886d 100644
+--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
++++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+@@ -1743,6 +1743,7 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev)
+ struct a5xx_gpu *a5xx_gpu = NULL;
+ struct adreno_gpu *adreno_gpu;
+ struct msm_gpu *gpu;
++ unsigned int nr_rings;
+ int ret;
+
+ if (!pdev) {
+@@ -1763,7 +1764,12 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev)
+
+ check_speed_bin(&pdev->dev);
+
+- ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 4);
++ nr_rings = 4;
++
++ if (adreno_is_a510(adreno_gpu))
++ nr_rings = 1;
++
++ ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, nr_rings);
+ if (ret) {
+ a5xx_destroy(&(a5xx_gpu->base.base));
+ return ERR_PTR(ret);
+diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c
+index c5c4c93b3689c..cd009d56d35d5 100644
+--- a/drivers/gpu/drm/msm/adreno/adreno_device.c
++++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
+@@ -438,9 +438,6 @@ struct msm_gpu *adreno_load_gpu(struct drm_device *dev)
+ */
+ pm_runtime_enable(&pdev->dev);
+
+- /* Make sure pm runtime is active and reset any previous errors */
+- pm_runtime_set_active(&pdev->dev);
+-
+ ret = pm_runtime_get_sync(&pdev->dev);
+ if (ret < 0) {
+ pm_runtime_put_sync(&pdev->dev);
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+index 9c6817b5a1943..547f9f2b9fcb5 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+@@ -654,7 +654,7 @@ static int dpu_encoder_virt_atomic_check(
+ if (drm_atomic_crtc_needs_modeset(crtc_state)) {
+ dpu_rm_release(global_state, drm_enc);
+
+- if (!crtc_state->active_changed || crtc_state->active)
++ if (!crtc_state->active_changed || crtc_state->enable)
+ ret = dpu_rm_reserve(&dpu_kms->rm, global_state,
+ drm_enc, crtc_state, topology);
+ }
+diff --git a/drivers/gpu/drm/panel/panel-novatek-nt35950.c b/drivers/gpu/drm/panel/panel-novatek-nt35950.c
+index 3a844917da075..5d04957b1144f 100644
+--- a/drivers/gpu/drm/panel/panel-novatek-nt35950.c
++++ b/drivers/gpu/drm/panel/panel-novatek-nt35950.c
+@@ -593,8 +593,12 @@ static int nt35950_probe(struct mipi_dsi_device *dsi)
+ DRM_MODE_CONNECTOR_DSI);
+
+ ret = drm_panel_of_backlight(&nt->panel);
+- if (ret)
++ if (ret) {
++ if (num_dsis == 2)
++ mipi_dsi_device_unregister(nt->dsi[1]);
++
+ return dev_err_probe(dev, ret, "Failed to get backlight\n");
++ }
+
+ drm_panel_add(&nt->panel);
+
+@@ -610,6 +614,10 @@ static int nt35950_probe(struct mipi_dsi_device *dsi)
+
+ ret = mipi_dsi_attach(nt->dsi[i]);
+ if (ret < 0) {
++ /* If we fail to attach to either host, we're done */
++ if (num_dsis == 2)
++ mipi_dsi_device_unregister(nt->dsi[1]);
++
+ return dev_err_probe(dev, ret,
+ "Cannot attach to DSI%d host.\n", i);
+ }
+diff --git a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
+index b1787be31e92c..7ecec7b04a8d0 100644
+--- a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
++++ b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
+@@ -109,8 +109,8 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu,
+ renc = drmm_encoder_alloc(&rcdu->ddev, struct rcar_du_encoder, base,
+ &rcar_du_encoder_funcs, DRM_MODE_ENCODER_NONE,
+ NULL);
+- if (!renc)
+- return -ENOMEM;
++ if (IS_ERR(renc))
++ return PTR_ERR(renc);
+
+ renc->output = output;
+
+diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+index 6edb7c52cb3dc..19b46c00dcbfd 100644
+--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
++++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+@@ -262,9 +262,6 @@ static int rockchip_drm_gem_object_mmap(struct drm_gem_object *obj,
+ else
+ ret = rockchip_drm_gem_object_mmap_dma(obj, vma);
+
+- if (ret)
+- drm_gem_vm_close(vma);
+-
+ return ret;
+ }
+
+diff --git a/drivers/gpu/drm/ttm/ttm_pool.c b/drivers/gpu/drm/ttm/ttm_pool.c
+index 9f6764bf3b15d..86affe987a1cb 100644
+--- a/drivers/gpu/drm/ttm/ttm_pool.c
++++ b/drivers/gpu/drm/ttm/ttm_pool.c
+@@ -366,6 +366,43 @@ static int ttm_pool_page_allocated(struct ttm_pool *pool, unsigned int order,
+ return 0;
+ }
+
++/**
++ * ttm_pool_free_range() - Free a range of TTM pages
++ * @pool: The pool used for allocating.
++ * @tt: The struct ttm_tt holding the page pointers.
++ * @caching: The page caching mode used by the range.
++ * @start_page: index for first page to free.
++ * @end_page: index for last page to free + 1.
++ *
++ * During allocation the ttm_tt page-vector may be populated with ranges of
++ * pages with different attributes if allocation hit an error without being
++ * able to completely fulfill the allocation. This function can be used
++ * to free these individual ranges.
++ */
++static void ttm_pool_free_range(struct ttm_pool *pool, struct ttm_tt *tt,
++ enum ttm_caching caching,
++ pgoff_t start_page, pgoff_t end_page)
++{
++ struct page **pages = tt->pages;
++ unsigned int order;
++ pgoff_t i, nr;
++
++ for (i = start_page; i < end_page; i += nr, pages += nr) {
++ struct ttm_pool_type *pt = NULL;
++
++ order = ttm_pool_page_order(pool, *pages);
++ nr = (1UL << order);
++ if (tt->dma_address)
++ ttm_pool_unmap(pool, tt->dma_address[i], nr);
++
++ pt = ttm_pool_select_type(pool, caching, order);
++ if (pt)
++ ttm_pool_type_give(pt, *pages);
++ else
++ ttm_pool_free_page(pool, caching, order, *pages);
++ }
++}
++
+ /**
+ * ttm_pool_alloc - Fill a ttm_tt object
+ *
+@@ -381,12 +418,14 @@ static int ttm_pool_page_allocated(struct ttm_pool *pool, unsigned int order,
+ int ttm_pool_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
+ struct ttm_operation_ctx *ctx)
+ {
+- unsigned long num_pages = tt->num_pages;
++ pgoff_t num_pages = tt->num_pages;
+ dma_addr_t *dma_addr = tt->dma_address;
+ struct page **caching = tt->pages;
+ struct page **pages = tt->pages;
++ enum ttm_caching page_caching;
+ gfp_t gfp_flags = GFP_USER;
+- unsigned int i, order;
++ pgoff_t caching_divide;
++ unsigned int order;
+ struct page *p;
+ int r;
+
+@@ -409,6 +448,7 @@ int ttm_pool_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
+ order = min_t(unsigned int, order, __fls(num_pages))) {
+ struct ttm_pool_type *pt;
+
++ page_caching = tt->caching;
+ pt = ttm_pool_select_type(pool, tt->caching, order);
+ p = pt ? ttm_pool_type_take(pt) : NULL;
+ if (p) {
+@@ -417,6 +457,7 @@ int ttm_pool_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
+ if (r)
+ goto error_free_page;
+
++ caching = pages;
+ do {
+ r = ttm_pool_page_allocated(pool, order, p,
+ &dma_addr,
+@@ -425,14 +466,15 @@ int ttm_pool_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
+ if (r)
+ goto error_free_page;
+
++ caching = pages;
+ if (num_pages < (1 << order))
+ break;
+
+ p = ttm_pool_type_take(pt);
+ } while (p);
+- caching = pages;
+ }
+
++ page_caching = ttm_cached;
+ while (num_pages >= (1 << order) &&
+ (p = ttm_pool_alloc_page(pool, gfp_flags, order))) {
+
+@@ -441,6 +483,7 @@ int ttm_pool_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
+ tt->caching);
+ if (r)
+ goto error_free_page;
++ caching = pages;
+ }
+ r = ttm_pool_page_allocated(pool, order, p, &dma_addr,
+ &num_pages, &pages);
+@@ -467,15 +510,13 @@ int ttm_pool_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
+ return 0;
+
+ error_free_page:
+- ttm_pool_free_page(pool, tt->caching, order, p);
++ ttm_pool_free_page(pool, page_caching, order, p);
+
+ error_free_all:
+ num_pages = tt->num_pages - num_pages;
+- for (i = 0; i < num_pages; ) {
+- order = ttm_pool_page_order(pool, tt->pages[i]);
+- ttm_pool_free_page(pool, tt->caching, order, tt->pages[i]);
+- i += 1 << order;
+- }
++ caching_divide = caching - tt->pages;
++ ttm_pool_free_range(pool, tt, tt->caching, 0, caching_divide);
++ ttm_pool_free_range(pool, tt, ttm_cached, caching_divide, num_pages);
+
+ return r;
+ }
+@@ -491,27 +532,7 @@ EXPORT_SYMBOL(ttm_pool_alloc);
+ */
+ void ttm_pool_free(struct ttm_pool *pool, struct ttm_tt *tt)
+ {
+- unsigned int i;
+-
+- for (i = 0; i < tt->num_pages; ) {
+- struct page *p = tt->pages[i];
+- unsigned int order, num_pages;
+- struct ttm_pool_type *pt;
+-
+- order = ttm_pool_page_order(pool, p);
+- num_pages = 1ULL << order;
+- if (tt->dma_address)
+- ttm_pool_unmap(pool, tt->dma_address[i], num_pages);
+-
+- pt = ttm_pool_select_type(pool, tt->caching, order);
+- if (pt)
+- ttm_pool_type_give(pt, tt->pages[i]);
+- else
+- ttm_pool_free_page(pool, tt->caching, order,
+- tt->pages[i]);
+-
+- i += num_pages;
+- }
++ ttm_pool_free_range(pool, tt, tt->caching, 0, tt->num_pages);
+
+ while (atomic_long_read(&allocated_pages) > page_pool_size)
+ ttm_pool_shrink();
+diff --git a/drivers/gpu/drm/vgem/vgem_fence.c b/drivers/gpu/drm/vgem/vgem_fence.c
+index c2a879734d407..e157541783959 100644
+--- a/drivers/gpu/drm/vgem/vgem_fence.c
++++ b/drivers/gpu/drm/vgem/vgem_fence.c
+@@ -249,4 +249,5 @@ void vgem_fence_close(struct vgem_file *vfile)
+ {
+ idr_for_each(&vfile->fence_idr, __vgem_fence_idr_fini, vfile);
+ idr_destroy(&vfile->fence_idr);
++ mutex_destroy(&vfile->fence_mutex);
+ }
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+index 445d619e1fdc8..9fec194cdbf16 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+@@ -1420,70 +1420,10 @@ static void vmw_framebuffer_bo_destroy(struct drm_framebuffer *framebuffer)
+ kfree(vfbd);
+ }
+
+-static int vmw_framebuffer_bo_dirty(struct drm_framebuffer *framebuffer,
+- struct drm_file *file_priv,
+- unsigned int flags, unsigned int color,
+- struct drm_clip_rect *clips,
+- unsigned int num_clips)
+-{
+- struct vmw_private *dev_priv = vmw_priv(framebuffer->dev);
+- struct vmw_framebuffer_bo *vfbd =
+- vmw_framebuffer_to_vfbd(framebuffer);
+- struct drm_clip_rect norect;
+- int ret, increment = 1;
+-
+- drm_modeset_lock_all(&dev_priv->drm);
+-
+- if (!num_clips) {
+- num_clips = 1;
+- clips = &norect;
+- norect.x1 = norect.y1 = 0;
+- norect.x2 = framebuffer->width;
+- norect.y2 = framebuffer->height;
+- } else if (flags & DRM_MODE_FB_DIRTY_ANNOTATE_COPY) {
+- num_clips /= 2;
+- increment = 2;
+- }
+-
+- switch (dev_priv->active_display_unit) {
+- case vmw_du_legacy:
+- ret = vmw_kms_ldu_do_bo_dirty(dev_priv, &vfbd->base, 0, 0,
+- clips, num_clips, increment);
+- break;
+- default:
+- ret = -EINVAL;
+- WARN_ONCE(true, "Dirty called with invalid display system.\n");
+- break;
+- }
+-
+- vmw_cmd_flush(dev_priv, false);
+-
+- drm_modeset_unlock_all(&dev_priv->drm);
+-
+- return ret;
+-}
+-
+-static int vmw_framebuffer_bo_dirty_ext(struct drm_framebuffer *framebuffer,
+- struct drm_file *file_priv,
+- unsigned int flags, unsigned int color,
+- struct drm_clip_rect *clips,
+- unsigned int num_clips)
+-{
+- struct vmw_private *dev_priv = vmw_priv(framebuffer->dev);
+-
+- if (dev_priv->active_display_unit == vmw_du_legacy &&
+- vmw_cmd_supported(dev_priv))
+- return vmw_framebuffer_bo_dirty(framebuffer, file_priv, flags,
+- color, clips, num_clips);
+-
+- return drm_atomic_helper_dirtyfb(framebuffer, file_priv, flags, color,
+- clips, num_clips);
+-}
+-
+ static const struct drm_framebuffer_funcs vmw_framebuffer_bo_funcs = {
+ .create_handle = vmw_framebuffer_bo_create_handle,
+ .destroy = vmw_framebuffer_bo_destroy,
+- .dirty = vmw_framebuffer_bo_dirty_ext,
++ .dirty = drm_atomic_helper_dirtyfb,
+ };
+
+ /*
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
+index 4d6e7b555db79..83595325cc186 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
+@@ -512,11 +512,6 @@ void vmw_du_connector_destroy_state(struct drm_connector *connector,
+ */
+ int vmw_kms_ldu_init_display(struct vmw_private *dev_priv);
+ int vmw_kms_ldu_close_display(struct vmw_private *dev_priv);
+-int vmw_kms_ldu_do_bo_dirty(struct vmw_private *dev_priv,
+- struct vmw_framebuffer *framebuffer,
+- unsigned int flags, unsigned int color,
+- struct drm_clip_rect *clips,
+- unsigned int num_clips, int increment);
+ int vmw_kms_update_proxy(struct vmw_resource *res,
+ const struct drm_clip_rect *clips,
+ unsigned num_clips,
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
+index a56e5d0ca3c65..ac72c20715f32 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
+@@ -234,6 +234,7 @@ static const struct drm_crtc_funcs vmw_legacy_crtc_funcs = {
+ .atomic_duplicate_state = vmw_du_crtc_duplicate_state,
+ .atomic_destroy_state = vmw_du_crtc_destroy_state,
+ .set_config = drm_atomic_helper_set_config,
++ .page_flip = drm_atomic_helper_page_flip,
+ };
+
+
+@@ -273,6 +274,12 @@ static const struct
+ drm_connector_helper_funcs vmw_ldu_connector_helper_funcs = {
+ };
+
++static int vmw_kms_ldu_do_bo_dirty(struct vmw_private *dev_priv,
++ struct vmw_framebuffer *framebuffer,
++ unsigned int flags, unsigned int color,
++ struct drm_mode_rect *clips,
++ unsigned int num_clips);
++
+ /*
+ * Legacy Display Plane Functions
+ */
+@@ -291,7 +298,6 @@ vmw_ldu_primary_plane_atomic_update(struct drm_plane *plane,
+ struct drm_framebuffer *fb;
+ struct drm_crtc *crtc = new_state->crtc ?: old_state->crtc;
+
+-
+ ldu = vmw_crtc_to_ldu(crtc);
+ dev_priv = vmw_priv(plane->dev);
+ fb = new_state->fb;
+@@ -304,8 +310,31 @@ vmw_ldu_primary_plane_atomic_update(struct drm_plane *plane,
+ vmw_ldu_del_active(dev_priv, ldu);
+
+ vmw_ldu_commit_list(dev_priv);
+-}
+
++ if (vfb && vmw_cmd_supported(dev_priv)) {
++ struct drm_mode_rect fb_rect = {
++ .x1 = 0,
++ .y1 = 0,
++ .x2 = vfb->base.width,
++ .y2 = vfb->base.height
++ };
++ struct drm_mode_rect *damage_rects = drm_plane_get_damage_clips(new_state);
++ u32 rect_count = drm_plane_get_damage_clips_count(new_state);
++ int ret;
++
++ if (!damage_rects) {
++ damage_rects = &fb_rect;
++ rect_count = 1;
++ }
++
++ ret = vmw_kms_ldu_do_bo_dirty(dev_priv, vfb, 0, 0, damage_rects, rect_count);
++
++ drm_WARN_ONCE(plane->dev, ret,
++ "vmw_kms_ldu_do_bo_dirty failed with: ret=%d\n", ret);
++
++ vmw_cmd_flush(dev_priv, false);
++ }
++}
+
+ static const struct drm_plane_funcs vmw_ldu_plane_funcs = {
+ .update_plane = drm_atomic_helper_update_plane,
+@@ -536,11 +565,11 @@ int vmw_kms_ldu_close_display(struct vmw_private *dev_priv)
+ }
+
+
+-int vmw_kms_ldu_do_bo_dirty(struct vmw_private *dev_priv,
+- struct vmw_framebuffer *framebuffer,
+- unsigned int flags, unsigned int color,
+- struct drm_clip_rect *clips,
+- unsigned int num_clips, int increment)
++static int vmw_kms_ldu_do_bo_dirty(struct vmw_private *dev_priv,
++ struct vmw_framebuffer *framebuffer,
++ unsigned int flags, unsigned int color,
++ struct drm_mode_rect *clips,
++ unsigned int num_clips)
+ {
+ size_t fifo_size;
+ int i;
+@@ -556,7 +585,7 @@ int vmw_kms_ldu_do_bo_dirty(struct vmw_private *dev_priv,
+ return -ENOMEM;
+
+ memset(cmd, 0, fifo_size);
+- for (i = 0; i < num_clips; i++, clips += increment) {
++ for (i = 0; i < num_clips; i++, clips++) {
+ cmd[i].header = SVGA_CMD_UPDATE;
+ cmd[i].body.x = clips->x1;
+ cmd[i].body.y = clips->y1;
+diff --git a/drivers/gpu/host1x/context.c b/drivers/gpu/host1x/context.c
+index c8e7994c2c9cd..84b23d36bcef4 100644
+--- a/drivers/gpu/host1x/context.c
++++ b/drivers/gpu/host1x/context.c
+@@ -13,6 +13,11 @@
+ #include "context.h"
+ #include "dev.h"
+
++static void host1x_memory_context_release(struct device *dev)
++{
++ /* context device is freed in host1x_memory_context_list_free() */
++}
++
+ int host1x_memory_context_list_init(struct host1x *host1x)
+ {
+ struct host1x_memory_context_list *cdl = &host1x->context_list;
+@@ -53,28 +58,30 @@ int host1x_memory_context_list_init(struct host1x *host1x)
+ dev_set_name(&ctx->dev, "host1x-ctx.%d", i);
+ ctx->dev.bus = &host1x_context_device_bus_type;
+ ctx->dev.parent = host1x->dev;
++ ctx->dev.release = host1x_memory_context_release;
+
+ dma_set_max_seg_size(&ctx->dev, UINT_MAX);
+
+ err = device_add(&ctx->dev);
+ if (err) {
+ dev_err(host1x->dev, "could not add context device %d: %d\n", i, err);
+- goto del_devices;
++ put_device(&ctx->dev);
++ goto unreg_devices;
+ }
+
+ err = of_dma_configure_id(&ctx->dev, node, true, &i);
+ if (err) {
+ dev_err(host1x->dev, "IOMMU configuration failed for context device %d: %d\n",
+ i, err);
+- device_del(&ctx->dev);
+- goto del_devices;
++ device_unregister(&ctx->dev);
++ goto unreg_devices;
+ }
+
+ fwspec = dev_iommu_fwspec_get(&ctx->dev);
+ if (!fwspec || !device_iommu_mapped(&ctx->dev)) {
+ dev_err(host1x->dev, "Context device %d has no IOMMU!\n", i);
+- device_del(&ctx->dev);
+- goto del_devices;
++ device_unregister(&ctx->dev);
++ goto unreg_devices;
+ }
+
+ ctx->stream_id = fwspec->ids[0] & 0xffff;
+@@ -82,11 +89,12 @@ int host1x_memory_context_list_init(struct host1x *host1x)
+
+ return 0;
+
+-del_devices:
++unreg_devices:
+ while (i--)
+- device_del(&cdl->devs[i].dev);
++ device_unregister(&cdl->devs[i].dev);
+
+ kfree(cdl->devs);
++ cdl->devs = NULL;
+ cdl->len = 0;
+
+ return err;
+@@ -97,7 +105,7 @@ void host1x_memory_context_list_free(struct host1x_memory_context_list *cdl)
+ unsigned int i;
+
+ for (i = 0; i < cdl->len; i++)
+- device_del(&cdl->devs[i].dev);
++ device_unregister(&cdl->devs[i].dev);
+
+ kfree(cdl->devs);
+ cdl->len = 0;
+diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
+index 47774b9ab3de0..c936d6a51c0cd 100644
+--- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
++++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
+@@ -367,6 +367,14 @@ init_done:
+ return devm_add_action_or_reset(&pdev->dev, privdata->mp2_ops->remove, privdata);
+ }
+
++static void amd_sfh_shutdown(struct pci_dev *pdev)
++{
++ struct amd_mp2_dev *mp2 = pci_get_drvdata(pdev);
++
++ if (mp2 && mp2->mp2_ops)
++ mp2->mp2_ops->stop_all(mp2);
++}
++
+ static int __maybe_unused amd_mp2_pci_resume(struct device *dev)
+ {
+ struct amd_mp2_dev *mp2 = dev_get_drvdata(dev);
+@@ -401,6 +409,7 @@ static struct pci_driver amd_mp2_pci_driver = {
+ .id_table = amd_mp2_pci_tbl,
+ .probe = amd_mp2_pci_probe,
+ .driver.pm = &amd_mp2_pm_ops,
++ .shutdown = amd_sfh_shutdown,
+ };
+ module_pci_driver(amd_mp2_pci_driver);
+
+diff --git a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c
+index 0609fea581c96..6f0d332ccf51c 100644
+--- a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c
++++ b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c
+@@ -218,7 +218,7 @@ static u8 get_input_rep(u8 current_index, int sensor_idx, int report_id,
+ OFFSET_SENSOR_DATA_DEFAULT;
+ memcpy_fromio(&als_data, sensoraddr, sizeof(struct sfh_als_data));
+ get_common_inputs(&als_input.common_property, report_id);
+- als_input.illuminance_value = als_data.lux;
++ als_input.illuminance_value = float_to_int(als_data.lux);
+ report_size = sizeof(als_input);
+ memcpy(input_report, &als_input, sizeof(als_input));
+ break;
+diff --git a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c
+index a1d6e08fab7d4..bb8bd7892b674 100644
+--- a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c
++++ b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c
+@@ -112,6 +112,7 @@ static int amd_sfh1_1_hid_client_init(struct amd_mp2_dev *privdata)
+ cl_data->num_hid_devices = amd_sfh_get_sensor_num(privdata, &cl_data->sensor_idx[0]);
+ if (cl_data->num_hid_devices == 0)
+ return -ENODEV;
++ cl_data->is_any_sensor_enabled = false;
+
+ INIT_DELAYED_WORK(&cl_data->work, amd_sfh_work);
+ INIT_DELAYED_WORK(&cl_data->work_buffer, amd_sfh_work_buffer);
+@@ -170,6 +171,7 @@ static int amd_sfh1_1_hid_client_init(struct amd_mp2_dev *privdata)
+ status = (status == 0) ? SENSOR_ENABLED : SENSOR_DISABLED;
+
+ if (status == SENSOR_ENABLED) {
++ cl_data->is_any_sensor_enabled = true;
+ cl_data->sensor_sts[i] = SENSOR_ENABLED;
+ rc = amdtp_hid_probe(i, cl_data);
+ if (rc) {
+@@ -186,12 +188,21 @@ static int amd_sfh1_1_hid_client_init(struct amd_mp2_dev *privdata)
+ cl_data->sensor_sts[i]);
+ goto cleanup;
+ }
++ } else {
++ cl_data->sensor_sts[i] = SENSOR_DISABLED;
+ }
+ dev_dbg(dev, "sid 0x%x (%s) status 0x%x\n",
+ cl_data->sensor_idx[i], get_sensor_name(cl_data->sensor_idx[i]),
+ cl_data->sensor_sts[i]);
+ }
+
++ if (!cl_data->is_any_sensor_enabled) {
++ dev_warn(dev, "Failed to discover, sensors not enabled is %d\n",
++ cl_data->is_any_sensor_enabled);
++ rc = -EOPNOTSUPP;
++ goto cleanup;
++ }
++
+ schedule_delayed_work(&cl_data->work_buffer, msecs_to_jiffies(AMD_SFH_IDLE_LOOP));
+ return 0;
+
+diff --git a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c
+index c6df959ec7252..4f81ef2d4f56e 100644
+--- a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c
++++ b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c
+@@ -16,11 +16,11 @@ static int amd_sfh_wait_response(struct amd_mp2_dev *mp2, u8 sid, u32 cmd_id)
+ {
+ struct sfh_cmd_response cmd_resp;
+
+- /* Get response with status within a max of 1600 ms timeout */
++ /* Get response with status within a max of 10000 ms timeout */
+ if (!readl_poll_timeout(mp2->mmio + AMD_P2C_MSG(0), cmd_resp.resp,
+ (cmd_resp.response.response == 0 &&
+ cmd_resp.response.cmd_id == cmd_id && (sid == 0xff ||
+- cmd_resp.response.sensor_id == sid)), 500, 1600000))
++ cmd_resp.response.sensor_id == sid)), 500, 10000000))
+ return cmd_resp.response.response;
+
+ return -1;
+@@ -33,6 +33,7 @@ static void amd_start_sensor(struct amd_mp2_dev *privdata, struct amd_mp2_sensor
+ cmd_base.ul = 0;
+ cmd_base.cmd.cmd_id = ENABLE_SENSOR;
+ cmd_base.cmd.intr_disable = 0;
++ cmd_base.cmd.sub_cmd_value = 1;
+ cmd_base.cmd.sensor_id = info.sensor_idx;
+
+ writel(cmd_base.ul, privdata->mmio + AMD_C2P_MSG(0));
+@@ -45,6 +46,7 @@ static void amd_stop_sensor(struct amd_mp2_dev *privdata, u16 sensor_idx)
+ cmd_base.ul = 0;
+ cmd_base.cmd.cmd_id = DISABLE_SENSOR;
+ cmd_base.cmd.intr_disable = 0;
++ cmd_base.cmd.sub_cmd_value = 1;
+ cmd_base.cmd.sensor_id = sensor_idx;
+
+ writeq(0x0, privdata->mmio + AMD_C2P_MSG(1));
+@@ -56,8 +58,10 @@ static void amd_stop_all_sensor(struct amd_mp2_dev *privdata)
+ struct sfh_cmd_base cmd_base;
+
+ cmd_base.ul = 0;
+- cmd_base.cmd.cmd_id = STOP_ALL_SENSORS;
++ cmd_base.cmd.cmd_id = DISABLE_SENSOR;
+ cmd_base.cmd.intr_disable = 0;
++ /* 0xf indicates all sensors */
++ cmd_base.cmd.sensor_id = 0xf;
+
+ writel(cmd_base.ul, privdata->mmio + AMD_C2P_MSG(0));
+ }
+diff --git a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.h b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.h
+index ae47a369dc05a..9d31d5b510eb4 100644
+--- a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.h
++++ b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.h
+@@ -33,9 +33,9 @@ struct sfh_cmd_base {
+ struct {
+ u32 sensor_id : 4;
+ u32 cmd_id : 4;
+- u32 sub_cmd_id : 6;
+- u32 length : 12;
+- u32 rsvd : 5;
++ u32 sub_cmd_id : 8;
++ u32 sub_cmd_value : 12;
++ u32 rsvd : 3;
+ u32 intr_disable : 1;
+ } cmd;
+ };
+@@ -133,7 +133,7 @@ struct sfh_mag_data {
+
+ struct sfh_als_data {
+ struct sfh_common_data commondata;
+- u16 lux;
++ u32 lux;
+ };
+
+ struct hpd_status {
+diff --git a/drivers/hte/hte-tegra194-test.c b/drivers/hte/hte-tegra194-test.c
+index 5d776a185bd62..ce8c44e792213 100644
+--- a/drivers/hte/hte-tegra194-test.c
++++ b/drivers/hte/hte-tegra194-test.c
+@@ -6,6 +6,7 @@
+ */
+
+ #include <linux/err.h>
++#include <linux/mod_devicetable.h>
+ #include <linux/module.h>
+ #include <linux/moduleparam.h>
+ #include <linux/interrupt.h>
+diff --git a/drivers/hte/hte-tegra194.c b/drivers/hte/hte-tegra194.c
+index 49a27af22742b..d1b579c822797 100644
+--- a/drivers/hte/hte-tegra194.c
++++ b/drivers/hte/hte-tegra194.c
+@@ -251,7 +251,7 @@ static int tegra_hte_map_to_line_id(u32 eid,
+ {
+
+ if (m) {
+- if (eid > map_sz)
++ if (eid >= map_sz)
+ return -EINVAL;
+ if (m[eid].slice == NV_AON_SLICE_INVALID)
+ return -EINVAL;
+diff --git a/drivers/hwmon/adt7475.c b/drivers/hwmon/adt7475.c
+index 6e4c92b500b8e..6a6ebcc896b1d 100644
+--- a/drivers/hwmon/adt7475.c
++++ b/drivers/hwmon/adt7475.c
+@@ -1604,9 +1604,9 @@ static int adt7475_set_pwm_polarity(struct i2c_client *client)
+ int ret, i;
+ u8 val;
+
+- ret = of_property_read_u32_array(client->dev.of_node,
+- "adi,pwm-active-state", states,
+- ARRAY_SIZE(states));
++ ret = device_property_read_u32_array(&client->dev,
++ "adi,pwm-active-state", states,
++ ARRAY_SIZE(states));
+ if (ret)
+ return ret;
+
+diff --git a/drivers/hwmon/k10temp.c b/drivers/hwmon/k10temp.c
+index 5a9d47a229e40..be8bbb1c3a02d 100644
+--- a/drivers/hwmon/k10temp.c
++++ b/drivers/hwmon/k10temp.c
+@@ -75,6 +75,7 @@ static DEFINE_MUTEX(nb_smu_ind_mutex);
+
+ #define ZEN_CUR_TEMP_SHIFT 21
+ #define ZEN_CUR_TEMP_RANGE_SEL_MASK BIT(19)
++#define ZEN_CUR_TEMP_TJ_SEL_MASK GENMASK(17, 16)
+
+ struct k10temp_data {
+ struct pci_dev *pdev;
+@@ -155,7 +156,8 @@ static long get_raw_temp(struct k10temp_data *data)
+
+ data->read_tempreg(data->pdev, &regval);
+ temp = (regval >> ZEN_CUR_TEMP_SHIFT) * 125;
+- if (regval & data->temp_adjust_mask)
++ if ((regval & data->temp_adjust_mask) ||
++ (regval & ZEN_CUR_TEMP_TJ_SEL_MASK) == ZEN_CUR_TEMP_TJ_SEL_MASK)
+ temp -= 49000;
+ return temp;
+ }
+diff --git a/drivers/hwmon/pmbus/fsp-3y.c b/drivers/hwmon/pmbus/fsp-3y.c
+index aec294cc72d1f..c7469d2cdedcf 100644
+--- a/drivers/hwmon/pmbus/fsp-3y.c
++++ b/drivers/hwmon/pmbus/fsp-3y.c
+@@ -180,7 +180,6 @@ static struct pmbus_driver_info fsp3y_info[] = {
+ PMBUS_HAVE_FAN12,
+ .func[YM2151_PAGE_5VSB_LOG] =
+ PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT,
+- PMBUS_HAVE_IIN,
+ .read_word_data = fsp3y_read_word_data,
+ .read_byte_data = fsp3y_read_byte_data,
+ },
+diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
+index 43bbd5dc3d3b1..f9a0ee49d8e80 100644
+--- a/drivers/hwtracing/coresight/coresight-etm-perf.c
++++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
+@@ -870,6 +870,7 @@ int __init etm_perf_init(void)
+ etm_pmu.addr_filters_sync = etm_addr_filters_sync;
+ etm_pmu.addr_filters_validate = etm_addr_filters_validate;
+ etm_pmu.nr_addr_filters = ETM_ADDR_CMP_MAX;
++ etm_pmu.module = THIS_MODULE;
+
+ ret = perf_pmu_register(&etm_pmu, CORESIGHT_ETM_PMU_NAME, -1);
+ if (ret == 0)
+diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c
+index f58943cb13414..8a5fdb150c446 100644
+--- a/drivers/i2c/busses/i2c-cadence.c
++++ b/drivers/i2c/busses/i2c-cadence.c
+@@ -833,8 +833,10 @@ static int cdns_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
+ #if IS_ENABLED(CONFIG_I2C_SLAVE)
+ /* Check i2c operating mode and switch if possible */
+ if (id->dev_mode == CDNS_I2C_MODE_SLAVE) {
+- if (id->slave_state != CDNS_I2C_SLAVE_STATE_IDLE)
+- return -EAGAIN;
++ if (id->slave_state != CDNS_I2C_SLAVE_STATE_IDLE) {
++ ret = -EAGAIN;
++ goto out;
++ }
+
+ /* Set mode to master */
+ cdns_i2c_set_mode(CDNS_I2C_MODE_MASTER, id);
+diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
+index f9ae520aed228..7ec2521997061 100644
+--- a/drivers/i2c/busses/i2c-omap.c
++++ b/drivers/i2c/busses/i2c-omap.c
+@@ -1058,7 +1058,7 @@ omap_i2c_isr(int irq, void *dev_id)
+ u16 stat;
+
+ stat = omap_i2c_read_reg(omap, OMAP_I2C_STAT_REG);
+- mask = omap_i2c_read_reg(omap, OMAP_I2C_IE_REG);
++ mask = omap_i2c_read_reg(omap, OMAP_I2C_IE_REG) & ~OMAP_I2C_STAT_NACK;
+
+ if (stat & mask)
+ ret = IRQ_WAKE_THREAD;
+diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c
+index bee5a2ef1f229..2bf3713b1969d 100644
+--- a/drivers/i2c/busses/i2c-xiic.c
++++ b/drivers/i2c/busses/i2c-xiic.c
+@@ -704,7 +704,7 @@ static int xiic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+ err = xiic_start_xfer(i2c, msgs, num);
+ if (err < 0) {
+ dev_err(adap->dev.parent, "Error xiic_start_xfer\n");
+- return err;
++ goto out;
+ }
+
+ err = wait_for_completion_timeout(&i2c->completion, XIIC_XFER_TIMEOUT);
+@@ -722,6 +722,8 @@ static int xiic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+ err = (i2c->state == STATE_DONE) ? num : -EIO;
+ }
+ mutex_unlock(&i2c->lock);
++
++out:
+ pm_runtime_mark_last_busy(i2c->dev);
+ pm_runtime_put_autosuspend(i2c->dev);
+ return err;
+diff --git a/drivers/iio/adc/palmas_gpadc.c b/drivers/iio/adc/palmas_gpadc.c
+index fd000345ec5cf..849a697a467e5 100644
+--- a/drivers/iio/adc/palmas_gpadc.c
++++ b/drivers/iio/adc/palmas_gpadc.c
+@@ -639,7 +639,7 @@ out:
+
+ static int palmas_gpadc_remove(struct platform_device *pdev)
+ {
+- struct iio_dev *indio_dev = dev_to_iio_dev(&pdev->dev);
++ struct iio_dev *indio_dev = dev_get_drvdata(&pdev->dev);
+ struct palmas_gpadc *adc = iio_priv(indio_dev);
+
+ if (adc->wakeup1_enable || adc->wakeup2_enable)
+diff --git a/drivers/iio/addac/stx104.c b/drivers/iio/addac/stx104.c
+index 48a91a95e597b..b658a75d4e3a8 100644
+--- a/drivers/iio/addac/stx104.c
++++ b/drivers/iio/addac/stx104.c
+@@ -15,6 +15,7 @@
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/moduleparam.h>
++#include <linux/mutex.h>
+ #include <linux/spinlock.h>
+ #include <linux/types.h>
+
+@@ -69,10 +70,12 @@ struct stx104_reg {
+
+ /**
+ * struct stx104_iio - IIO device private data structure
++ * @lock: synchronization lock to prevent I/O race conditions
+ * @chan_out_states: channels' output states
+ * @reg: I/O address offset for the device registers
+ */
+ struct stx104_iio {
++ struct mutex lock;
+ unsigned int chan_out_states[STX104_NUM_OUT_CHAN];
+ struct stx104_reg __iomem *reg;
+ };
+@@ -114,6 +117,8 @@ static int stx104_read_raw(struct iio_dev *indio_dev,
+ return IIO_VAL_INT;
+ }
+
++ mutex_lock(&priv->lock);
++
+ /* select ADC channel */
+ iowrite8(chan->channel | (chan->channel << 4), &reg->achan);
+
+@@ -124,6 +129,8 @@ static int stx104_read_raw(struct iio_dev *indio_dev,
+ while (ioread8(&reg->cir_asr) & BIT(7));
+
+ *val = ioread16(&reg->ssr_ad);
++
++ mutex_unlock(&priv->lock);
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_OFFSET:
+ /* get ADC bipolar/unipolar configuration */
+@@ -178,9 +185,12 @@ static int stx104_write_raw(struct iio_dev *indio_dev,
+ if ((unsigned int)val > 65535)
+ return -EINVAL;
+
++ mutex_lock(&priv->lock);
++
+ priv->chan_out_states[chan->channel] = val;
+ iowrite16(val, &priv->reg->dac[chan->channel]);
+
++ mutex_unlock(&priv->lock);
+ return 0;
+ }
+ return -EINVAL;
+@@ -351,6 +361,8 @@ static int stx104_probe(struct device *dev, unsigned int id)
+
+ indio_dev->name = dev_name(dev);
+
++ mutex_init(&priv->lock);
++
+ /* configure device for software trigger operation */
+ iowrite8(0, &priv->reg->acr);
+
+diff --git a/drivers/iio/light/max44009.c b/drivers/iio/light/max44009.c
+index 801e5a0ad496b..f3648f20ef2c0 100644
+--- a/drivers/iio/light/max44009.c
++++ b/drivers/iio/light/max44009.c
+@@ -528,6 +528,12 @@ static int max44009_probe(struct i2c_client *client,
+ return devm_iio_device_register(&client->dev, indio_dev);
+ }
+
++static const struct of_device_id max44009_of_match[] = {
++ { .compatible = "maxim,max44009" },
++ { }
++};
++MODULE_DEVICE_TABLE(of, max44009_of_match);
++
+ static const struct i2c_device_id max44009_id[] = {
+ { "max44009", 0 },
+ { }
+@@ -537,18 +543,13 @@ MODULE_DEVICE_TABLE(i2c, max44009_id);
+ static struct i2c_driver max44009_driver = {
+ .driver = {
+ .name = MAX44009_DRV_NAME,
++ .of_match_table = max44009_of_match,
+ },
+ .probe = max44009_probe,
+ .id_table = max44009_id,
+ };
+ module_i2c_driver(max44009_driver);
+
+-static const struct of_device_id max44009_of_match[] = {
+- { .compatible = "maxim,max44009" },
+- { }
+-};
+-MODULE_DEVICE_TABLE(of, max44009_of_match);
+-
+ MODULE_AUTHOR("Robert Eshleman <bobbyeshleman@gmail.com>");
+ MODULE_LICENSE("GPL v2");
+ MODULE_DESCRIPTION("MAX44009 ambient light sensor driver");
+diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
+index 603c0aecc3614..ff58058aeadca 100644
+--- a/drivers/infiniband/core/cm.c
++++ b/drivers/infiniband/core/cm.c
+@@ -2912,6 +2912,8 @@ static int cm_send_rej_locked(struct cm_id_private *cm_id_priv,
+ (ari && ari_length > IB_CM_REJ_ARI_LENGTH))
+ return -EINVAL;
+
++ trace_icm_send_rej(&cm_id_priv->id, reason);
++
+ switch (state) {
+ case IB_CM_REQ_SENT:
+ case IB_CM_MRA_REQ_RCVD:
+@@ -2942,7 +2944,6 @@ static int cm_send_rej_locked(struct cm_id_private *cm_id_priv,
+ return -EINVAL;
+ }
+
+- trace_icm_send_rej(&cm_id_priv->id, reason);
+ ret = ib_post_send_mad(msg, NULL);
+ if (ret) {
+ cm_free_msg(msg);
+diff --git a/drivers/infiniband/hw/erdma/erdma_hw.h b/drivers/infiniband/hw/erdma/erdma_hw.h
+index 8a8d4539a006b..51ab2058b03f1 100644
+--- a/drivers/infiniband/hw/erdma/erdma_hw.h
++++ b/drivers/infiniband/hw/erdma/erdma_hw.h
+@@ -112,6 +112,10 @@
+
+ #define ERDMA_PAGE_SIZE_SUPPORT 0x7FFFF000
+
++/* Hardware page size definition */
++#define ERDMA_HW_PAGE_SHIFT 12
++#define ERDMA_HW_PAGE_SIZE 4096
++
+ /* WQE related. */
+ #define EQE_SIZE 16
+ #define EQE_SHIFT 4
+diff --git a/drivers/infiniband/hw/erdma/erdma_verbs.c b/drivers/infiniband/hw/erdma/erdma_verbs.c
+index 9c30d78730aa1..83e1b0d559771 100644
+--- a/drivers/infiniband/hw/erdma/erdma_verbs.c
++++ b/drivers/infiniband/hw/erdma/erdma_verbs.c
+@@ -38,7 +38,7 @@ static int create_qp_cmd(struct erdma_dev *dev, struct erdma_qp *qp)
+ FIELD_PREP(ERDMA_CMD_CREATE_QP_PD_MASK, pd->pdn);
+
+ if (rdma_is_kernel_res(&qp->ibqp.res)) {
+- u32 pgsz_range = ilog2(SZ_1M) - PAGE_SHIFT;
++ u32 pgsz_range = ilog2(SZ_1M) - ERDMA_HW_PAGE_SHIFT;
+
+ req.sq_cqn_mtt_cfg =
+ FIELD_PREP(ERDMA_CMD_CREATE_QP_PAGE_SIZE_MASK,
+@@ -66,13 +66,13 @@ static int create_qp_cmd(struct erdma_dev *dev, struct erdma_qp *qp)
+ user_qp = &qp->user_qp;
+ req.sq_cqn_mtt_cfg = FIELD_PREP(
+ ERDMA_CMD_CREATE_QP_PAGE_SIZE_MASK,
+- ilog2(user_qp->sq_mtt.page_size) - PAGE_SHIFT);
++ ilog2(user_qp->sq_mtt.page_size) - ERDMA_HW_PAGE_SHIFT);
+ req.sq_cqn_mtt_cfg |=
+ FIELD_PREP(ERDMA_CMD_CREATE_QP_CQN_MASK, qp->scq->cqn);
+
+ req.rq_cqn_mtt_cfg = FIELD_PREP(
+ ERDMA_CMD_CREATE_QP_PAGE_SIZE_MASK,
+- ilog2(user_qp->rq_mtt.page_size) - PAGE_SHIFT);
++ ilog2(user_qp->rq_mtt.page_size) - ERDMA_HW_PAGE_SHIFT);
+ req.rq_cqn_mtt_cfg |=
+ FIELD_PREP(ERDMA_CMD_CREATE_QP_CQN_MASK, qp->rcq->cqn);
+
+@@ -162,7 +162,7 @@ static int create_cq_cmd(struct erdma_dev *dev, struct erdma_cq *cq)
+ if (rdma_is_kernel_res(&cq->ibcq.res)) {
+ page_size = SZ_32M;
+ req.cfg0 |= FIELD_PREP(ERDMA_CMD_CREATE_CQ_PAGESIZE_MASK,
+- ilog2(page_size) - PAGE_SHIFT);
++ ilog2(page_size) - ERDMA_HW_PAGE_SHIFT);
+ req.qbuf_addr_l = lower_32_bits(cq->kern_cq.qbuf_dma_addr);
+ req.qbuf_addr_h = upper_32_bits(cq->kern_cq.qbuf_dma_addr);
+
+@@ -175,8 +175,9 @@ static int create_cq_cmd(struct erdma_dev *dev, struct erdma_cq *cq)
+ cq->kern_cq.qbuf_dma_addr + (cq->depth << CQE_SHIFT);
+ } else {
+ mtt = &cq->user_cq.qbuf_mtt;
+- req.cfg0 |= FIELD_PREP(ERDMA_CMD_CREATE_CQ_PAGESIZE_MASK,
+- ilog2(mtt->page_size) - PAGE_SHIFT);
++ req.cfg0 |=
++ FIELD_PREP(ERDMA_CMD_CREATE_CQ_PAGESIZE_MASK,
++ ilog2(mtt->page_size) - ERDMA_HW_PAGE_SHIFT);
+ if (mtt->mtt_nents == 1) {
+ req.qbuf_addr_l = lower_32_bits(*(u64 *)mtt->mtt_buf);
+ req.qbuf_addr_h = upper_32_bits(*(u64 *)mtt->mtt_buf);
+@@ -636,7 +637,7 @@ static int init_user_qp(struct erdma_qp *qp, struct erdma_ucontext *uctx,
+ u32 rq_offset;
+ int ret;
+
+- if (len < (PAGE_ALIGN(qp->attrs.sq_size * SQEBB_SIZE) +
++ if (len < (ALIGN(qp->attrs.sq_size * SQEBB_SIZE, ERDMA_HW_PAGE_SIZE) +
+ qp->attrs.rq_size * RQE_SIZE))
+ return -EINVAL;
+
+@@ -646,7 +647,7 @@ static int init_user_qp(struct erdma_qp *qp, struct erdma_ucontext *uctx,
+ if (ret)
+ return ret;
+
+- rq_offset = PAGE_ALIGN(qp->attrs.sq_size << SQEBB_SHIFT);
++ rq_offset = ALIGN(qp->attrs.sq_size << SQEBB_SHIFT, ERDMA_HW_PAGE_SIZE);
+ qp->user_qp.rq_offset = rq_offset;
+
+ ret = get_mtt_entries(qp->dev, &qp->user_qp.rq_mtt, va + rq_offset,
+diff --git a/drivers/infiniband/hw/hfi1/ipoib_tx.c b/drivers/infiniband/hw/hfi1/ipoib_tx.c
+index 5d9a7b09ca37e..8973a081d641e 100644
+--- a/drivers/infiniband/hw/hfi1/ipoib_tx.c
++++ b/drivers/infiniband/hw/hfi1/ipoib_tx.c
+@@ -215,6 +215,7 @@ static int hfi1_ipoib_build_ulp_payload(struct ipoib_txreq *tx,
+ const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+
+ ret = sdma_txadd_page(dd,
++ NULL,
+ txreq,
+ skb_frag_page(frag),
+ frag->bv_offset,
+@@ -737,10 +738,13 @@ int hfi1_ipoib_txreq_init(struct hfi1_ipoib_dev_priv *priv)
+ txq->tx_ring.shift = ilog2(tx_item_size);
+ txq->tx_ring.avail = hfi1_ipoib_ring_hwat(txq);
+ tx_ring = &txq->tx_ring;
+- for (j = 0; j < tx_ring_size; j++)
++ for (j = 0; j < tx_ring_size; j++) {
+ hfi1_txreq_from_idx(tx_ring, j)->sdma_hdr =
+ kzalloc_node(sizeof(*tx->sdma_hdr),
+ GFP_KERNEL, priv->dd->node);
++ if (!hfi1_txreq_from_idx(tx_ring, j)->sdma_hdr)
++ goto free_txqs;
++ }
+
+ netif_napi_add_tx(dev, &txq->napi, hfi1_ipoib_poll_tx_ring);
+ }
+diff --git a/drivers/infiniband/hw/hfi1/mmu_rb.c b/drivers/infiniband/hw/hfi1/mmu_rb.c
+index 7333646021bb8..71b9ac0188875 100644
+--- a/drivers/infiniband/hw/hfi1/mmu_rb.c
++++ b/drivers/infiniband/hw/hfi1/mmu_rb.c
+@@ -126,11 +126,11 @@ int hfi1_mmu_rb_insert(struct mmu_rb_handler *handler,
+ spin_lock_irqsave(&handler->lock, flags);
+ node = __mmu_rb_search(handler, mnode->addr, mnode->len);
+ if (node) {
+- ret = -EINVAL;
++ ret = -EEXIST;
+ goto unlock;
+ }
+ __mmu_int_rb_insert(mnode, &handler->root);
+- list_add(&mnode->list, &handler->lru_list);
++ list_add_tail(&mnode->list, &handler->lru_list);
+
+ ret = handler->ops->insert(handler->ops_arg, mnode);
+ if (ret) {
+@@ -143,6 +143,19 @@ unlock:
+ return ret;
+ }
+
++/* Caller must hold handler lock */
++struct mmu_rb_node *hfi1_mmu_rb_get_first(struct mmu_rb_handler *handler,
++ unsigned long addr, unsigned long len)
++{
++ struct mmu_rb_node *node;
++
++ trace_hfi1_mmu_rb_search(addr, len);
++ node = __mmu_int_rb_iter_first(&handler->root, addr, (addr + len) - 1);
++ if (node)
++ list_move_tail(&node->list, &handler->lru_list);
++ return node;
++}
++
+ /* Caller must hold handler lock */
+ static struct mmu_rb_node *__mmu_rb_search(struct mmu_rb_handler *handler,
+ unsigned long addr,
+@@ -167,32 +180,6 @@ static struct mmu_rb_node *__mmu_rb_search(struct mmu_rb_handler *handler,
+ return node;
+ }
+
+-bool hfi1_mmu_rb_remove_unless_exact(struct mmu_rb_handler *handler,
+- unsigned long addr, unsigned long len,
+- struct mmu_rb_node **rb_node)
+-{
+- struct mmu_rb_node *node;
+- unsigned long flags;
+- bool ret = false;
+-
+- if (current->mm != handler->mn.mm)
+- return ret;
+-
+- spin_lock_irqsave(&handler->lock, flags);
+- node = __mmu_rb_search(handler, addr, len);
+- if (node) {
+- if (node->addr == addr && node->len == len)
+- goto unlock;
+- __mmu_int_rb_remove(node, &handler->root);
+- list_del(&node->list); /* remove from LRU list */
+- ret = true;
+- }
+-unlock:
+- spin_unlock_irqrestore(&handler->lock, flags);
+- *rb_node = node;
+- return ret;
+-}
+-
+ void hfi1_mmu_rb_evict(struct mmu_rb_handler *handler, void *evict_arg)
+ {
+ struct mmu_rb_node *rbnode, *ptr;
+@@ -206,8 +193,7 @@ void hfi1_mmu_rb_evict(struct mmu_rb_handler *handler, void *evict_arg)
+ INIT_LIST_HEAD(&del_list);
+
+ spin_lock_irqsave(&handler->lock, flags);
+- list_for_each_entry_safe_reverse(rbnode, ptr, &handler->lru_list,
+- list) {
++ list_for_each_entry_safe(rbnode, ptr, &handler->lru_list, list) {
+ if (handler->ops->evict(handler->ops_arg, rbnode, evict_arg,
+ &stop)) {
+ __mmu_int_rb_remove(rbnode, &handler->root);
+@@ -219,36 +205,11 @@ void hfi1_mmu_rb_evict(struct mmu_rb_handler *handler, void *evict_arg)
+ }
+ spin_unlock_irqrestore(&handler->lock, flags);
+
+- while (!list_empty(&del_list)) {
+- rbnode = list_first_entry(&del_list, struct mmu_rb_node, list);
+- list_del(&rbnode->list);
++ list_for_each_entry_safe(rbnode, ptr, &del_list, list) {
+ handler->ops->remove(handler->ops_arg, rbnode);
+ }
+ }
+
+-/*
+- * It is up to the caller to ensure that this function does not race with the
+- * mmu invalidate notifier which may be calling the users remove callback on
+- * 'node'.
+- */
+-void hfi1_mmu_rb_remove(struct mmu_rb_handler *handler,
+- struct mmu_rb_node *node)
+-{
+- unsigned long flags;
+-
+- if (current->mm != handler->mn.mm)
+- return;
+-
+- /* Validity of handler and node pointers has been checked by caller. */
+- trace_hfi1_mmu_rb_remove(node->addr, node->len);
+- spin_lock_irqsave(&handler->lock, flags);
+- __mmu_int_rb_remove(node, &handler->root);
+- list_del(&node->list); /* remove from LRU list */
+- spin_unlock_irqrestore(&handler->lock, flags);
+-
+- handler->ops->remove(handler->ops_arg, node);
+-}
+-
+ static int mmu_notifier_range_start(struct mmu_notifier *mn,
+ const struct mmu_notifier_range *range)
+ {
+diff --git a/drivers/infiniband/hw/hfi1/mmu_rb.h b/drivers/infiniband/hw/hfi1/mmu_rb.h
+index 7417be2b9dc8a..ed75acdb7b839 100644
+--- a/drivers/infiniband/hw/hfi1/mmu_rb.h
++++ b/drivers/infiniband/hw/hfi1/mmu_rb.h
+@@ -52,10 +52,8 @@ void hfi1_mmu_rb_unregister(struct mmu_rb_handler *handler);
+ int hfi1_mmu_rb_insert(struct mmu_rb_handler *handler,
+ struct mmu_rb_node *mnode);
+ void hfi1_mmu_rb_evict(struct mmu_rb_handler *handler, void *evict_arg);
+-void hfi1_mmu_rb_remove(struct mmu_rb_handler *handler,
+- struct mmu_rb_node *mnode);
+-bool hfi1_mmu_rb_remove_unless_exact(struct mmu_rb_handler *handler,
+- unsigned long addr, unsigned long len,
+- struct mmu_rb_node **rb_node);
++struct mmu_rb_node *hfi1_mmu_rb_get_first(struct mmu_rb_handler *handler,
++ unsigned long addr,
++ unsigned long len);
+
+ #endif /* _HFI1_MMU_RB_H */
+diff --git a/drivers/infiniband/hw/hfi1/sdma.c b/drivers/infiniband/hw/hfi1/sdma.c
+index 8ed20392e9f0d..bb2552dd29c1e 100644
+--- a/drivers/infiniband/hw/hfi1/sdma.c
++++ b/drivers/infiniband/hw/hfi1/sdma.c
+@@ -1593,22 +1593,7 @@ static inline void sdma_unmap_desc(
+ struct hfi1_devdata *dd,
+ struct sdma_desc *descp)
+ {
+- switch (sdma_mapping_type(descp)) {
+- case SDMA_MAP_SINGLE:
+- dma_unmap_single(
+- &dd->pcidev->dev,
+- sdma_mapping_addr(descp),
+- sdma_mapping_len(descp),
+- DMA_TO_DEVICE);
+- break;
+- case SDMA_MAP_PAGE:
+- dma_unmap_page(
+- &dd->pcidev->dev,
+- sdma_mapping_addr(descp),
+- sdma_mapping_len(descp),
+- DMA_TO_DEVICE);
+- break;
+- }
++ system_descriptor_complete(dd, descp);
+ }
+
+ /*
+@@ -3128,7 +3113,7 @@ int ext_coal_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx,
+
+ /* Add descriptor for coalesce buffer */
+ tx->desc_limit = MAX_DESC;
+- return _sdma_txadd_daddr(dd, SDMA_MAP_SINGLE, tx,
++ return _sdma_txadd_daddr(dd, SDMA_MAP_SINGLE, NULL, tx,
+ addr, tx->tlen);
+ }
+
+@@ -3167,10 +3152,12 @@ int _pad_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx)
+ return rval;
+ }
+ }
++
+ /* finish the one just added */
+ make_tx_sdma_desc(
+ tx,
+ SDMA_MAP_NONE,
++ NULL,
+ dd->sdma_pad_phys,
+ sizeof(u32) - (tx->packet_len & (sizeof(u32) - 1)));
+ tx->num_desc++;
+diff --git a/drivers/infiniband/hw/hfi1/sdma.h b/drivers/infiniband/hw/hfi1/sdma.h
+index b023fc461bd51..95aaec14c6c28 100644
+--- a/drivers/infiniband/hw/hfi1/sdma.h
++++ b/drivers/infiniband/hw/hfi1/sdma.h
+@@ -594,6 +594,7 @@ static inline dma_addr_t sdma_mapping_addr(struct sdma_desc *d)
+ static inline void make_tx_sdma_desc(
+ struct sdma_txreq *tx,
+ int type,
++ void *pinning_ctx,
+ dma_addr_t addr,
+ size_t len)
+ {
+@@ -612,6 +613,7 @@ static inline void make_tx_sdma_desc(
+ << SDMA_DESC0_PHY_ADDR_SHIFT) |
+ (((u64)len & SDMA_DESC0_BYTE_COUNT_MASK)
+ << SDMA_DESC0_BYTE_COUNT_SHIFT);
++ desc->pinning_ctx = pinning_ctx;
+ }
+
+ /* helper to extend txreq */
+@@ -643,6 +645,7 @@ static inline void _sdma_close_tx(struct hfi1_devdata *dd,
+ static inline int _sdma_txadd_daddr(
+ struct hfi1_devdata *dd,
+ int type,
++ void *pinning_ctx,
+ struct sdma_txreq *tx,
+ dma_addr_t addr,
+ u16 len)
+@@ -652,6 +655,7 @@ static inline int _sdma_txadd_daddr(
+ make_tx_sdma_desc(
+ tx,
+ type,
++ pinning_ctx,
+ addr, len);
+ WARN_ON(len > tx->tlen);
+ tx->num_desc++;
+@@ -672,6 +676,7 @@ static inline int _sdma_txadd_daddr(
+ /**
+ * sdma_txadd_page() - add a page to the sdma_txreq
+ * @dd: the device to use for mapping
++ * @pinning_ctx: context to be released at descriptor retirement
+ * @tx: tx request to which the page is added
+ * @page: page to map
+ * @offset: offset within the page
+@@ -687,6 +692,7 @@ static inline int _sdma_txadd_daddr(
+ */
+ static inline int sdma_txadd_page(
+ struct hfi1_devdata *dd,
++ void *pinning_ctx,
+ struct sdma_txreq *tx,
+ struct page *page,
+ unsigned long offset,
+@@ -714,8 +720,7 @@ static inline int sdma_txadd_page(
+ return -ENOSPC;
+ }
+
+- return _sdma_txadd_daddr(
+- dd, SDMA_MAP_PAGE, tx, addr, len);
++ return _sdma_txadd_daddr(dd, SDMA_MAP_PAGE, pinning_ctx, tx, addr, len);
+ }
+
+ /**
+@@ -749,7 +754,8 @@ static inline int sdma_txadd_daddr(
+ return rval;
+ }
+
+- return _sdma_txadd_daddr(dd, SDMA_MAP_NONE, tx, addr, len);
++ return _sdma_txadd_daddr(dd, SDMA_MAP_NONE, NULL, tx,
++ addr, len);
+ }
+
+ /**
+@@ -795,8 +801,7 @@ static inline int sdma_txadd_kvaddr(
+ return -ENOSPC;
+ }
+
+- return _sdma_txadd_daddr(
+- dd, SDMA_MAP_SINGLE, tx, addr, len);
++ return _sdma_txadd_daddr(dd, SDMA_MAP_SINGLE, NULL, tx, addr, len);
+ }
+
+ struct iowait_work;
+@@ -1030,4 +1035,5 @@ extern uint mod_num_sdma;
+
+ void sdma_update_lmc(struct hfi1_devdata *dd, u64 mask, u32 lid);
+
++void system_descriptor_complete(struct hfi1_devdata *dd, struct sdma_desc *descp);
+ #endif
+diff --git a/drivers/infiniband/hw/hfi1/sdma_txreq.h b/drivers/infiniband/hw/hfi1/sdma_txreq.h
+index e262fb5c5ec61..fad946cb5e0d8 100644
+--- a/drivers/infiniband/hw/hfi1/sdma_txreq.h
++++ b/drivers/infiniband/hw/hfi1/sdma_txreq.h
+@@ -19,6 +19,7 @@
+ struct sdma_desc {
+ /* private: don't use directly */
+ u64 qw[2];
++ void *pinning_ctx;
+ };
+
+ /**
+diff --git a/drivers/infiniband/hw/hfi1/trace_mmu.h b/drivers/infiniband/hw/hfi1/trace_mmu.h
+index 187e9244fe5ed..57900ebb7702e 100644
+--- a/drivers/infiniband/hw/hfi1/trace_mmu.h
++++ b/drivers/infiniband/hw/hfi1/trace_mmu.h
+@@ -37,10 +37,6 @@ DEFINE_EVENT(hfi1_mmu_rb_template, hfi1_mmu_rb_search,
+ TP_PROTO(unsigned long addr, unsigned long len),
+ TP_ARGS(addr, len));
+
+-DEFINE_EVENT(hfi1_mmu_rb_template, hfi1_mmu_rb_remove,
+- TP_PROTO(unsigned long addr, unsigned long len),
+- TP_ARGS(addr, len));
+-
+ DEFINE_EVENT(hfi1_mmu_rb_template, hfi1_mmu_mem_invalidate,
+ TP_PROTO(unsigned long addr, unsigned long len),
+ TP_ARGS(addr, len));
+diff --git a/drivers/infiniband/hw/hfi1/user_sdma.c b/drivers/infiniband/hw/hfi1/user_sdma.c
+index a71c5a36cebab..ae58b48afe074 100644
+--- a/drivers/infiniband/hw/hfi1/user_sdma.c
++++ b/drivers/infiniband/hw/hfi1/user_sdma.c
+@@ -24,7 +24,6 @@
+
+ #include "hfi.h"
+ #include "sdma.h"
+-#include "mmu_rb.h"
+ #include "user_sdma.h"
+ #include "verbs.h" /* for the headers */
+ #include "common.h" /* for struct hfi1_tid_info */
+@@ -39,11 +38,7 @@ static unsigned initial_pkt_count = 8;
+ static int user_sdma_send_pkts(struct user_sdma_request *req, u16 maxpkts);
+ static void user_sdma_txreq_cb(struct sdma_txreq *txreq, int status);
+ static inline void pq_update(struct hfi1_user_sdma_pkt_q *pq);
+-static void user_sdma_free_request(struct user_sdma_request *req, bool unpin);
+-static int pin_vector_pages(struct user_sdma_request *req,
+- struct user_sdma_iovec *iovec);
+-static void unpin_vector_pages(struct mm_struct *mm, struct page **pages,
+- unsigned start, unsigned npages);
++static void user_sdma_free_request(struct user_sdma_request *req);
+ static int check_header_template(struct user_sdma_request *req,
+ struct hfi1_pkt_header *hdr, u32 lrhlen,
+ u32 datalen);
+@@ -81,6 +76,11 @@ static struct mmu_rb_ops sdma_rb_ops = {
+ .invalidate = sdma_rb_invalidate
+ };
+
++static int add_system_pages_to_sdma_packet(struct user_sdma_request *req,
++ struct user_sdma_txreq *tx,
++ struct user_sdma_iovec *iovec,
++ u32 *pkt_remaining);
++
+ static int defer_packet_queue(
+ struct sdma_engine *sde,
+ struct iowait_work *wait,
+@@ -410,6 +410,7 @@ int hfi1_user_sdma_process_request(struct hfi1_filedata *fd,
+ ret = -EINVAL;
+ goto free_req;
+ }
++
+ /* Copy the header from the user buffer */
+ ret = copy_from_user(&req->hdr, iovec[idx].iov_base + sizeof(info),
+ sizeof(req->hdr));
+@@ -484,9 +485,8 @@ int hfi1_user_sdma_process_request(struct hfi1_filedata *fd,
+ memcpy(&req->iovs[i].iov,
+ iovec + idx++,
+ sizeof(req->iovs[i].iov));
+- ret = pin_vector_pages(req, &req->iovs[i]);
+- if (ret) {
+- req->data_iovs = i;
++ if (req->iovs[i].iov.iov_len == 0) {
++ ret = -EINVAL;
+ goto free_req;
+ }
+ req->data_len += req->iovs[i].iov.iov_len;
+@@ -584,7 +584,7 @@ free_req:
+ if (req->seqsubmitted)
+ wait_event(pq->busy.wait_dma,
+ (req->seqcomp == req->seqsubmitted - 1));
+- user_sdma_free_request(req, true);
++ user_sdma_free_request(req);
+ pq_update(pq);
+ set_comp_state(pq, cq, info.comp_idx, ERROR, ret);
+ }
+@@ -696,48 +696,6 @@ static int user_sdma_txadd_ahg(struct user_sdma_request *req,
+ return ret;
+ }
+
+-static int user_sdma_txadd(struct user_sdma_request *req,
+- struct user_sdma_txreq *tx,
+- struct user_sdma_iovec *iovec, u32 datalen,
+- u32 *queued_ptr, u32 *data_sent_ptr,
+- u64 *iov_offset_ptr)
+-{
+- int ret;
+- unsigned int pageidx, len;
+- unsigned long base, offset;
+- u64 iov_offset = *iov_offset_ptr;
+- u32 queued = *queued_ptr, data_sent = *data_sent_ptr;
+- struct hfi1_user_sdma_pkt_q *pq = req->pq;
+-
+- base = (unsigned long)iovec->iov.iov_base;
+- offset = offset_in_page(base + iovec->offset + iov_offset);
+- pageidx = (((iovec->offset + iov_offset + base) - (base & PAGE_MASK)) >>
+- PAGE_SHIFT);
+- len = offset + req->info.fragsize > PAGE_SIZE ?
+- PAGE_SIZE - offset : req->info.fragsize;
+- len = min((datalen - queued), len);
+- ret = sdma_txadd_page(pq->dd, &tx->txreq, iovec->pages[pageidx],
+- offset, len);
+- if (ret) {
+- SDMA_DBG(req, "SDMA txreq add page failed %d\n", ret);
+- return ret;
+- }
+- iov_offset += len;
+- queued += len;
+- data_sent += len;
+- if (unlikely(queued < datalen && pageidx == iovec->npages &&
+- req->iov_idx < req->data_iovs - 1)) {
+- iovec->offset += iov_offset;
+- iovec = &req->iovs[++req->iov_idx];
+- iov_offset = 0;
+- }
+-
+- *queued_ptr = queued;
+- *data_sent_ptr = data_sent;
+- *iov_offset_ptr = iov_offset;
+- return ret;
+-}
+-
+ static int user_sdma_send_pkts(struct user_sdma_request *req, u16 maxpkts)
+ {
+ int ret = 0;
+@@ -769,8 +727,7 @@ static int user_sdma_send_pkts(struct user_sdma_request *req, u16 maxpkts)
+ maxpkts = req->info.npkts - req->seqnum;
+
+ while (npkts < maxpkts) {
+- u32 datalen = 0, queued = 0, data_sent = 0;
+- u64 iov_offset = 0;
++ u32 datalen = 0;
+
+ /*
+ * Check whether any of the completions have come back
+@@ -863,27 +820,17 @@ static int user_sdma_send_pkts(struct user_sdma_request *req, u16 maxpkts)
+ goto free_txreq;
+ }
+
+- /*
+- * If the request contains any data vectors, add up to
+- * fragsize bytes to the descriptor.
+- */
+- while (queued < datalen &&
+- (req->sent + data_sent) < req->data_len) {
+- ret = user_sdma_txadd(req, tx, iovec, datalen,
+- &queued, &data_sent, &iov_offset);
+- if (ret)
+- goto free_txreq;
+- }
+- /*
+- * The txreq was submitted successfully so we can update
+- * the counters.
+- */
+ req->koffset += datalen;
+ if (req_opcode(req->info.ctrl) == EXPECTED)
+ req->tidoffset += datalen;
+- req->sent += data_sent;
+- if (req->data_len)
+- iovec->offset += iov_offset;
++ req->sent += datalen;
++ while (datalen) {
++ ret = add_system_pages_to_sdma_packet(req, tx, iovec,
++ &datalen);
++ if (ret)
++ goto free_txreq;
++ iovec = &req->iovs[req->iov_idx];
++ }
+ list_add_tail(&tx->txreq.list, &req->txps);
+ /*
+ * It is important to increment this here as it is used to
+@@ -920,133 +867,14 @@ free_tx:
+ static u32 sdma_cache_evict(struct hfi1_user_sdma_pkt_q *pq, u32 npages)
+ {
+ struct evict_data evict_data;
++ struct mmu_rb_handler *handler = pq->handler;
+
+ evict_data.cleared = 0;
+ evict_data.target = npages;
+- hfi1_mmu_rb_evict(pq->handler, &evict_data);
++ hfi1_mmu_rb_evict(handler, &evict_data);
+ return evict_data.cleared;
+ }
+
+-static int pin_sdma_pages(struct user_sdma_request *req,
+- struct user_sdma_iovec *iovec,
+- struct sdma_mmu_node *node,
+- int npages)
+-{
+- int pinned, cleared;
+- struct page **pages;
+- struct hfi1_user_sdma_pkt_q *pq = req->pq;
+-
+- pages = kcalloc(npages, sizeof(*pages), GFP_KERNEL);
+- if (!pages)
+- return -ENOMEM;
+- memcpy(pages, node->pages, node->npages * sizeof(*pages));
+-
+- npages -= node->npages;
+-retry:
+- if (!hfi1_can_pin_pages(pq->dd, current->mm,
+- atomic_read(&pq->n_locked), npages)) {
+- cleared = sdma_cache_evict(pq, npages);
+- if (cleared >= npages)
+- goto retry;
+- }
+- pinned = hfi1_acquire_user_pages(current->mm,
+- ((unsigned long)iovec->iov.iov_base +
+- (node->npages * PAGE_SIZE)), npages, 0,
+- pages + node->npages);
+- if (pinned < 0) {
+- kfree(pages);
+- return pinned;
+- }
+- if (pinned != npages) {
+- unpin_vector_pages(current->mm, pages, node->npages, pinned);
+- return -EFAULT;
+- }
+- kfree(node->pages);
+- node->rb.len = iovec->iov.iov_len;
+- node->pages = pages;
+- atomic_add(pinned, &pq->n_locked);
+- return pinned;
+-}
+-
+-static void unpin_sdma_pages(struct sdma_mmu_node *node)
+-{
+- if (node->npages) {
+- unpin_vector_pages(mm_from_sdma_node(node), node->pages, 0,
+- node->npages);
+- atomic_sub(node->npages, &node->pq->n_locked);
+- }
+-}
+-
+-static int pin_vector_pages(struct user_sdma_request *req,
+- struct user_sdma_iovec *iovec)
+-{
+- int ret = 0, pinned, npages;
+- struct hfi1_user_sdma_pkt_q *pq = req->pq;
+- struct sdma_mmu_node *node = NULL;
+- struct mmu_rb_node *rb_node;
+- struct iovec *iov;
+- bool extracted;
+-
+- extracted =
+- hfi1_mmu_rb_remove_unless_exact(pq->handler,
+- (unsigned long)
+- iovec->iov.iov_base,
+- iovec->iov.iov_len, &rb_node);
+- if (rb_node) {
+- node = container_of(rb_node, struct sdma_mmu_node, rb);
+- if (!extracted) {
+- atomic_inc(&node->refcount);
+- iovec->pages = node->pages;
+- iovec->npages = node->npages;
+- iovec->node = node;
+- return 0;
+- }
+- }
+-
+- if (!node) {
+- node = kzalloc(sizeof(*node), GFP_KERNEL);
+- if (!node)
+- return -ENOMEM;
+-
+- node->rb.addr = (unsigned long)iovec->iov.iov_base;
+- node->pq = pq;
+- atomic_set(&node->refcount, 0);
+- }
+-
+- iov = &iovec->iov;
+- npages = num_user_pages((unsigned long)iov->iov_base, iov->iov_len);
+- if (node->npages < npages) {
+- pinned = pin_sdma_pages(req, iovec, node, npages);
+- if (pinned < 0) {
+- ret = pinned;
+- goto bail;
+- }
+- node->npages += pinned;
+- npages = node->npages;
+- }
+- iovec->pages = node->pages;
+- iovec->npages = npages;
+- iovec->node = node;
+-
+- ret = hfi1_mmu_rb_insert(req->pq->handler, &node->rb);
+- if (ret) {
+- iovec->node = NULL;
+- goto bail;
+- }
+- return 0;
+-bail:
+- unpin_sdma_pages(node);
+- kfree(node);
+- return ret;
+-}
+-
+-static void unpin_vector_pages(struct mm_struct *mm, struct page **pages,
+- unsigned start, unsigned npages)
+-{
+- hfi1_release_user_pages(mm, pages + start, npages, false);
+- kfree(pages);
+-}
+-
+ static int check_header_template(struct user_sdma_request *req,
+ struct hfi1_pkt_header *hdr, u32 lrhlen,
+ u32 datalen)
+@@ -1388,7 +1216,7 @@ static void user_sdma_txreq_cb(struct sdma_txreq *txreq, int status)
+ if (req->seqcomp != req->info.npkts - 1)
+ return;
+
+- user_sdma_free_request(req, false);
++ user_sdma_free_request(req);
+ set_comp_state(pq, cq, req->info.comp_idx, state, status);
+ pq_update(pq);
+ }
+@@ -1399,10 +1227,8 @@ static inline void pq_update(struct hfi1_user_sdma_pkt_q *pq)
+ wake_up(&pq->wait);
+ }
+
+-static void user_sdma_free_request(struct user_sdma_request *req, bool unpin)
++static void user_sdma_free_request(struct user_sdma_request *req)
+ {
+- int i;
+-
+ if (!list_empty(&req->txps)) {
+ struct sdma_txreq *t, *p;
+
+@@ -1415,21 +1241,6 @@ static void user_sdma_free_request(struct user_sdma_request *req, bool unpin)
+ }
+ }
+
+- for (i = 0; i < req->data_iovs; i++) {
+- struct sdma_mmu_node *node = req->iovs[i].node;
+-
+- if (!node)
+- continue;
+-
+- req->iovs[i].node = NULL;
+-
+- if (unpin)
+- hfi1_mmu_rb_remove(req->pq->handler,
+- &node->rb);
+- else
+- atomic_dec(&node->refcount);
+- }
+-
+ kfree(req->tids);
+ clear_bit(req->info.comp_idx, req->pq->req_in_use);
+ }
+@@ -1447,6 +1258,368 @@ static inline void set_comp_state(struct hfi1_user_sdma_pkt_q *pq,
+ idx, state, ret);
+ }
+
++static void unpin_vector_pages(struct mm_struct *mm, struct page **pages,
++ unsigned int start, unsigned int npages)
++{
++ hfi1_release_user_pages(mm, pages + start, npages, false);
++ kfree(pages);
++}
++
++static void free_system_node(struct sdma_mmu_node *node)
++{
++ if (node->npages) {
++ unpin_vector_pages(mm_from_sdma_node(node), node->pages, 0,
++ node->npages);
++ atomic_sub(node->npages, &node->pq->n_locked);
++ }
++ kfree(node);
++}
++
++static inline void acquire_node(struct sdma_mmu_node *node)
++{
++ atomic_inc(&node->refcount);
++ WARN_ON(atomic_read(&node->refcount) < 0);
++}
++
++static inline void release_node(struct mmu_rb_handler *handler,
++ struct sdma_mmu_node *node)
++{
++ atomic_dec(&node->refcount);
++ WARN_ON(atomic_read(&node->refcount) < 0);
++}
++
++static struct sdma_mmu_node *find_system_node(struct mmu_rb_handler *handler,
++ unsigned long start,
++ unsigned long end)
++{
++ struct mmu_rb_node *rb_node;
++ struct sdma_mmu_node *node;
++ unsigned long flags;
++
++ spin_lock_irqsave(&handler->lock, flags);
++ rb_node = hfi1_mmu_rb_get_first(handler, start, (end - start));
++ if (!rb_node) {
++ spin_unlock_irqrestore(&handler->lock, flags);
++ return NULL;
++ }
++ node = container_of(rb_node, struct sdma_mmu_node, rb);
++ acquire_node(node);
++ spin_unlock_irqrestore(&handler->lock, flags);
++
++ return node;
++}
++
++static int pin_system_pages(struct user_sdma_request *req,
++ uintptr_t start_address, size_t length,
++ struct sdma_mmu_node *node, int npages)
++{
++ struct hfi1_user_sdma_pkt_q *pq = req->pq;
++ int pinned, cleared;
++ struct page **pages;
++
++ pages = kcalloc(npages, sizeof(*pages), GFP_KERNEL);
++ if (!pages)
++ return -ENOMEM;
++
++retry:
++ if (!hfi1_can_pin_pages(pq->dd, current->mm, atomic_read(&pq->n_locked),
++ npages)) {
++ SDMA_DBG(req, "Evicting: nlocked %u npages %u",
++ atomic_read(&pq->n_locked), npages);
++ cleared = sdma_cache_evict(pq, npages);
++ if (cleared >= npages)
++ goto retry;
++ }
++
++ SDMA_DBG(req, "Acquire user pages start_address %lx node->npages %u npages %u",
++ start_address, node->npages, npages);
++ pinned = hfi1_acquire_user_pages(current->mm, start_address, npages, 0,
++ pages);
++
++ if (pinned < 0) {
++ kfree(pages);
++ SDMA_DBG(req, "pinned %d", pinned);
++ return pinned;
++ }
++ if (pinned != npages) {
++ unpin_vector_pages(current->mm, pages, node->npages, pinned);
++ SDMA_DBG(req, "npages %u pinned %d", npages, pinned);
++ return -EFAULT;
++ }
++ node->rb.addr = start_address;
++ node->rb.len = length;
++ node->pages = pages;
++ node->npages = npages;
++ atomic_add(pinned, &pq->n_locked);
++ SDMA_DBG(req, "done. pinned %d", pinned);
++ return 0;
++}
++
++static int add_system_pinning(struct user_sdma_request *req,
++ struct sdma_mmu_node **node_p,
++ unsigned long start, unsigned long len)
++
++{
++ struct hfi1_user_sdma_pkt_q *pq = req->pq;
++ struct sdma_mmu_node *node;
++ int ret;
++
++ node = kzalloc(sizeof(*node), GFP_KERNEL);
++ if (!node)
++ return -ENOMEM;
++
++ node->pq = pq;
++ ret = pin_system_pages(req, start, len, node, PFN_DOWN(len));
++ if (ret == 0) {
++ ret = hfi1_mmu_rb_insert(pq->handler, &node->rb);
++ if (ret)
++ free_system_node(node);
++ else
++ *node_p = node;
++
++ return ret;
++ }
++
++ kfree(node);
++ return ret;
++}
++
++static int get_system_cache_entry(struct user_sdma_request *req,
++ struct sdma_mmu_node **node_p,
++ size_t req_start, size_t req_len)
++{
++ struct hfi1_user_sdma_pkt_q *pq = req->pq;
++ u64 start = ALIGN_DOWN(req_start, PAGE_SIZE);
++ u64 end = PFN_ALIGN(req_start + req_len);
++ struct mmu_rb_handler *handler = pq->handler;
++ int ret;
++
++ if ((end - start) == 0) {
++ SDMA_DBG(req,
++ "Request for empty cache entry req_start %lx req_len %lx start %llx end %llx",
++ req_start, req_len, start, end);
++ return -EINVAL;
++ }
++
++ SDMA_DBG(req, "req_start %lx req_len %lu", req_start, req_len);
++
++ while (1) {
++ struct sdma_mmu_node *node =
++ find_system_node(handler, start, end);
++ u64 prepend_len = 0;
++
++ SDMA_DBG(req, "node %p start %llx end %llu", node, start, end);
++ if (!node) {
++ ret = add_system_pinning(req, node_p, start,
++ end - start);
++ if (ret == -EEXIST) {
++ /*
++ * Another execution context has inserted a
++ * conficting entry first.
++ */
++ continue;
++ }
++ return ret;
++ }
++
++ if (node->rb.addr <= start) {
++ /*
++ * This entry covers at least part of the region. If it doesn't extend
++ * to the end, then this will be called again for the next segment.
++ */
++ *node_p = node;
++ return 0;
++ }
++
++ SDMA_DBG(req, "prepend: node->rb.addr %lx, node->refcount %d",
++ node->rb.addr, atomic_read(&node->refcount));
++ prepend_len = node->rb.addr - start;
++
++ /*
++ * This node will not be returned, instead a new node
++ * will be. So release the reference.
++ */
++ release_node(handler, node);
++
++ /* Prepend a node to cover the beginning of the allocation */
++ ret = add_system_pinning(req, node_p, start, prepend_len);
++ if (ret == -EEXIST) {
++ /* Another execution context has inserted a conficting entry first. */
++ continue;
++ }
++ return ret;
++ }
++}
++
++static int add_mapping_to_sdma_packet(struct user_sdma_request *req,
++ struct user_sdma_txreq *tx,
++ struct sdma_mmu_node *cache_entry,
++ size_t start,
++ size_t from_this_cache_entry)
++{
++ struct hfi1_user_sdma_pkt_q *pq = req->pq;
++ unsigned int page_offset;
++ unsigned int from_this_page;
++ size_t page_index;
++ void *ctx;
++ int ret;
++
++ /*
++ * Because the cache may be more fragmented than the memory that is being accessed,
++ * it's not strictly necessary to have a descriptor per cache entry.
++ */
++
++ while (from_this_cache_entry) {
++ page_index = PFN_DOWN(start - cache_entry->rb.addr);
++
++ if (page_index >= cache_entry->npages) {
++ SDMA_DBG(req,
++ "Request for page_index %zu >= cache_entry->npages %u",
++ page_index, cache_entry->npages);
++ return -EINVAL;
++ }
++
++ page_offset = start - ALIGN_DOWN(start, PAGE_SIZE);
++ from_this_page = PAGE_SIZE - page_offset;
++
++ if (from_this_page < from_this_cache_entry) {
++ ctx = NULL;
++ } else {
++ /*
++ * In the case they are equal the next line has no practical effect,
++ * but it's better to do a register to register copy than a conditional
++ * branch.
++ */
++ from_this_page = from_this_cache_entry;
++ ctx = cache_entry;
++ }
++
++ ret = sdma_txadd_page(pq->dd, ctx, &tx->txreq,
++ cache_entry->pages[page_index],
++ page_offset, from_this_page);
++ if (ret) {
++ /*
++ * When there's a failure, the entire request is freed by
++ * user_sdma_send_pkts().
++ */
++ SDMA_DBG(req,
++ "sdma_txadd_page failed %d page_index %lu page_offset %u from_this_page %u",
++ ret, page_index, page_offset, from_this_page);
++ return ret;
++ }
++ start += from_this_page;
++ from_this_cache_entry -= from_this_page;
++ }
++ return 0;
++}
++
++static int add_system_iovec_to_sdma_packet(struct user_sdma_request *req,
++ struct user_sdma_txreq *tx,
++ struct user_sdma_iovec *iovec,
++ size_t from_this_iovec)
++{
++ struct mmu_rb_handler *handler = req->pq->handler;
++
++ while (from_this_iovec > 0) {
++ struct sdma_mmu_node *cache_entry;
++ size_t from_this_cache_entry;
++ size_t start;
++ int ret;
++
++ start = (uintptr_t)iovec->iov.iov_base + iovec->offset;
++ ret = get_system_cache_entry(req, &cache_entry, start,
++ from_this_iovec);
++ if (ret) {
++ SDMA_DBG(req, "pin system segment failed %d", ret);
++ return ret;
++ }
++
++ from_this_cache_entry = cache_entry->rb.len - (start - cache_entry->rb.addr);
++ if (from_this_cache_entry > from_this_iovec)
++ from_this_cache_entry = from_this_iovec;
++
++ ret = add_mapping_to_sdma_packet(req, tx, cache_entry, start,
++ from_this_cache_entry);
++ if (ret) {
++ /*
++ * We're guaranteed that there will be no descriptor
++ * completion callback that releases this node
++ * because only the last descriptor referencing it
++ * has a context attached, and a failure means the
++ * last descriptor was never added.
++ */
++ release_node(handler, cache_entry);
++ SDMA_DBG(req, "add system segment failed %d", ret);
++ return ret;
++ }
++
++ iovec->offset += from_this_cache_entry;
++ from_this_iovec -= from_this_cache_entry;
++ }
++
++ return 0;
++}
++
++static int add_system_pages_to_sdma_packet(struct user_sdma_request *req,
++ struct user_sdma_txreq *tx,
++ struct user_sdma_iovec *iovec,
++ u32 *pkt_data_remaining)
++{
++ size_t remaining_to_add = *pkt_data_remaining;
++ /*
++ * Walk through iovec entries, ensure the associated pages
++ * are pinned and mapped, add data to the packet until no more
++ * data remains to be added.
++ */
++ while (remaining_to_add > 0) {
++ struct user_sdma_iovec *cur_iovec;
++ size_t from_this_iovec;
++ int ret;
++
++ cur_iovec = iovec;
++ from_this_iovec = iovec->iov.iov_len - iovec->offset;
++
++ if (from_this_iovec > remaining_to_add) {
++ from_this_iovec = remaining_to_add;
++ } else {
++ /* The current iovec entry will be consumed by this pass. */
++ req->iov_idx++;
++ iovec++;
++ }
++
++ ret = add_system_iovec_to_sdma_packet(req, tx, cur_iovec,
++ from_this_iovec);
++ if (ret)
++ return ret;
++
++ remaining_to_add -= from_this_iovec;
++ }
++ *pkt_data_remaining = remaining_to_add;
++
++ return 0;
++}
++
++void system_descriptor_complete(struct hfi1_devdata *dd,
++ struct sdma_desc *descp)
++{
++ switch (sdma_mapping_type(descp)) {
++ case SDMA_MAP_SINGLE:
++ dma_unmap_single(&dd->pcidev->dev, sdma_mapping_addr(descp),
++ sdma_mapping_len(descp), DMA_TO_DEVICE);
++ break;
++ case SDMA_MAP_PAGE:
++ dma_unmap_page(&dd->pcidev->dev, sdma_mapping_addr(descp),
++ sdma_mapping_len(descp), DMA_TO_DEVICE);
++ break;
++ }
++
++ if (descp->pinning_ctx) {
++ struct sdma_mmu_node *node = descp->pinning_ctx;
++
++ release_node(node->rb.handler, node);
++ }
++}
++
+ static bool sdma_rb_filter(struct mmu_rb_node *node, unsigned long addr,
+ unsigned long len)
+ {
+@@ -1493,8 +1666,7 @@ static void sdma_rb_remove(void *arg, struct mmu_rb_node *mnode)
+ struct sdma_mmu_node *node =
+ container_of(mnode, struct sdma_mmu_node, rb);
+
+- unpin_sdma_pages(node);
+- kfree(node);
++ free_system_node(node);
+ }
+
+ static int sdma_rb_invalidate(void *arg, struct mmu_rb_node *mnode)
+diff --git a/drivers/infiniband/hw/hfi1/user_sdma.h b/drivers/infiniband/hw/hfi1/user_sdma.h
+index ea56eb57e6568..a241836371dc1 100644
+--- a/drivers/infiniband/hw/hfi1/user_sdma.h
++++ b/drivers/infiniband/hw/hfi1/user_sdma.h
+@@ -112,16 +112,11 @@ struct sdma_mmu_node {
+ struct user_sdma_iovec {
+ struct list_head list;
+ struct iovec iov;
+- /* number of pages in this vector */
+- unsigned int npages;
+- /* array of pinned pages for this vector */
+- struct page **pages;
+ /*
+ * offset into the virtual address space of the vector at
+ * which we last left off.
+ */
+ u64 offset;
+- struct sdma_mmu_node *node;
+ };
+
+ /* evict operation argument */
+diff --git a/drivers/infiniband/hw/hfi1/verbs.c b/drivers/infiniband/hw/hfi1/verbs.c
+index e6e17984553c0..39ca32d9ae6a5 100644
+--- a/drivers/infiniband/hw/hfi1/verbs.c
++++ b/drivers/infiniband/hw/hfi1/verbs.c
+@@ -778,8 +778,8 @@ static int build_verbs_tx_desc(
+
+ /* add icrc, lt byte, and padding to flit */
+ if (extra_bytes)
+- ret = sdma_txadd_daddr(sde->dd, &tx->txreq,
+- sde->dd->sdma_pad_phys, extra_bytes);
++ ret = sdma_txadd_daddr(sde->dd, &tx->txreq, sde->dd->sdma_pad_phys,
++ extra_bytes);
+
+ bail_txadd:
+ return ret;
+diff --git a/drivers/infiniband/hw/hfi1/vnic_sdma.c b/drivers/infiniband/hw/hfi1/vnic_sdma.c
+index c3f0f8d877c37..727eedfba332a 100644
+--- a/drivers/infiniband/hw/hfi1/vnic_sdma.c
++++ b/drivers/infiniband/hw/hfi1/vnic_sdma.c
+@@ -64,6 +64,7 @@ static noinline int build_vnic_ulp_payload(struct sdma_engine *sde,
+
+ /* combine physically continuous fragments later? */
+ ret = sdma_txadd_page(sde->dd,
++ NULL,
+ &tx->txreq,
+ skb_frag_page(frag),
+ skb_frag_off(frag),
+diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
+index b17d6ebc5b705..488c906c0432c 100644
+--- a/drivers/infiniband/hw/mlx4/qp.c
++++ b/drivers/infiniband/hw/mlx4/qp.c
+@@ -412,9 +412,13 @@ static int set_user_sq_size(struct mlx4_ib_dev *dev,
+ struct mlx4_ib_qp *qp,
+ struct mlx4_ib_create_qp *ucmd)
+ {
++ u32 cnt;
++
+ /* Sanity check SQ size before proceeding */
+- if ((1 << ucmd->log_sq_bb_count) > dev->dev->caps.max_wqes ||
+- ucmd->log_sq_stride >
++ if (check_shl_overflow(1, ucmd->log_sq_bb_count, &cnt) ||
++ cnt > dev->dev->caps.max_wqes)
++ return -EINVAL;
++ if (ucmd->log_sq_stride >
+ ilog2(roundup_pow_of_two(dev->dev->caps.max_sq_desc_sz)) ||
+ ucmd->log_sq_stride < MLX4_IB_MIN_SQ_STRIDE)
+ return -EINVAL;
+diff --git a/drivers/infiniband/hw/mlx5/devx.c b/drivers/infiniband/hw/mlx5/devx.c
+index 2211a0be16f36..f8e2baed27a5c 100644
+--- a/drivers/infiniband/hw/mlx5/devx.c
++++ b/drivers/infiniband/hw/mlx5/devx.c
+@@ -666,7 +666,21 @@ static bool devx_is_valid_obj_id(struct uverbs_attr_bundle *attrs,
+ obj_id;
+
+ case MLX5_IB_OBJECT_DEVX_OBJ:
+- return ((struct devx_obj *)uobj->object)->obj_id == obj_id;
++ {
++ u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode);
++ struct devx_obj *devx_uobj = uobj->object;
++
++ if (opcode == MLX5_CMD_OP_QUERY_FLOW_COUNTER &&
++ devx_uobj->flow_counter_bulk_size) {
++ u64 end;
++
++ end = devx_uobj->obj_id +
++ devx_uobj->flow_counter_bulk_size;
++ return devx_uobj->obj_id <= obj_id && end > obj_id;
++ }
++
++ return devx_uobj->obj_id == obj_id;
++ }
+
+ default:
+ return false;
+@@ -1517,10 +1531,17 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_CREATE)(
+ goto obj_free;
+
+ if (opcode == MLX5_CMD_OP_ALLOC_FLOW_COUNTER) {
+- u8 bulk = MLX5_GET(alloc_flow_counter_in,
+- cmd_in,
+- flow_counter_bulk);
+- obj->flow_counter_bulk_size = 128UL * bulk;
++ u32 bulk = MLX5_GET(alloc_flow_counter_in,
++ cmd_in,
++ flow_counter_bulk_log_size);
++
++ if (bulk)
++ bulk = 1 << bulk;
++ else
++ bulk = 128UL * MLX5_GET(alloc_flow_counter_in,
++ cmd_in,
++ flow_counter_bulk);
++ obj->flow_counter_bulk_size = bulk;
+ }
+
+ uobj->object = obj;
+diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
+index cf953d23d18da..f7d3643b08f50 100644
+--- a/drivers/infiniband/hw/mlx5/qp.c
++++ b/drivers/infiniband/hw/mlx5/qp.c
+@@ -4408,7 +4408,7 @@ static int mlx5_ib_modify_dct(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+ return -EINVAL;
+
+ if (attr->port_num == 0 ||
+- attr->port_num > MLX5_CAP_GEN(dev->mdev, num_ports)) {
++ attr->port_num > dev->num_ports) {
+ mlx5_ib_dbg(dev, "invalid port number %d. number of ports is %d\n",
+ attr->port_num, dev->num_ports);
+ return -EINVAL;
+diff --git a/drivers/infiniband/hw/mlx5/umr.c b/drivers/infiniband/hw/mlx5/umr.c
+index 029e9536ec28f..8b674514818a1 100644
+--- a/drivers/infiniband/hw/mlx5/umr.c
++++ b/drivers/infiniband/hw/mlx5/umr.c
+@@ -380,6 +380,9 @@ static void mlx5r_umr_set_access_flags(struct mlx5_ib_dev *dev,
+ struct mlx5_mkey_seg *seg,
+ unsigned int access_flags)
+ {
++ bool ro_read = (access_flags & IB_ACCESS_RELAXED_ORDERING) &&
++ pcie_relaxed_ordering_enabled(dev->mdev->pdev);
++
+ MLX5_SET(mkc, seg, a, !!(access_flags & IB_ACCESS_REMOTE_ATOMIC));
+ MLX5_SET(mkc, seg, rw, !!(access_flags & IB_ACCESS_REMOTE_WRITE));
+ MLX5_SET(mkc, seg, rr, !!(access_flags & IB_ACCESS_REMOTE_READ));
+@@ -387,8 +390,7 @@ static void mlx5r_umr_set_access_flags(struct mlx5_ib_dev *dev,
+ MLX5_SET(mkc, seg, lr, 1);
+ MLX5_SET(mkc, seg, relaxed_ordering_write,
+ !!(access_flags & IB_ACCESS_RELAXED_ORDERING));
+- MLX5_SET(mkc, seg, relaxed_ordering_read,
+- !!(access_flags & IB_ACCESS_RELAXED_ORDERING));
++ MLX5_SET(mkc, seg, relaxed_ordering_read, ro_read);
+ }
+
+ int mlx5r_umr_rereg_pd_access(struct mlx5_ib_mr *mr, struct ib_pd *pd,
+diff --git a/drivers/infiniband/sw/rdmavt/qp.c b/drivers/infiniband/sw/rdmavt/qp.c
+index 3acab569fbb94..2bdc4486c3daa 100644
+--- a/drivers/infiniband/sw/rdmavt/qp.c
++++ b/drivers/infiniband/sw/rdmavt/qp.c
+@@ -464,8 +464,6 @@ void rvt_qp_exit(struct rvt_dev_info *rdi)
+ if (qps_inuse)
+ rvt_pr_err(rdi, "QP memory leak! %u still in use\n",
+ qps_inuse);
+- if (!rdi->qp_dev)
+- return;
+
+ kfree(rdi->qp_dev->qp_table);
+ free_qpn_table(&rdi->qp_dev->qpn_table);
+diff --git a/drivers/infiniband/sw/rxe/rxe.c b/drivers/infiniband/sw/rxe/rxe.c
+index 136c2efe34660..a3f05fdd9fac2 100644
+--- a/drivers/infiniband/sw/rxe/rxe.c
++++ b/drivers/infiniband/sw/rxe/rxe.c
+@@ -175,7 +175,7 @@ int rxe_add(struct rxe_dev *rxe, unsigned int mtu, const char *ibdev_name)
+
+ static int rxe_newlink(const char *ibdev_name, struct net_device *ndev)
+ {
+- struct rxe_dev *exists;
++ struct rxe_dev *rxe;
+ int err = 0;
+
+ if (is_vlan_dev(ndev)) {
+@@ -184,17 +184,17 @@ static int rxe_newlink(const char *ibdev_name, struct net_device *ndev)
+ goto err;
+ }
+
+- exists = rxe_get_dev_from_net(ndev);
+- if (exists) {
+- ib_device_put(&exists->ib_dev);
+- rxe_dbg(exists, "already configured on %s\n", ndev->name);
++ rxe = rxe_get_dev_from_net(ndev);
++ if (rxe) {
++ ib_device_put(&rxe->ib_dev);
++ rxe_dbg(rxe, "already configured on %s\n", ndev->name);
+ err = -EEXIST;
+ goto err;
+ }
+
+ err = rxe_net_add(ibdev_name, ndev);
+ if (err) {
+- rxe_dbg(exists, "failed to add %s\n", ndev->name);
++ pr_debug("failed to add %s\n", ndev->name);
+ goto err;
+ }
+ err:
+diff --git a/drivers/infiniband/sw/rxe/rxe_comp.c b/drivers/infiniband/sw/rxe/rxe_comp.c
+index 20737fec392bf..9a9d3ec2bf2fd 100644
+--- a/drivers/infiniband/sw/rxe/rxe_comp.c
++++ b/drivers/infiniband/sw/rxe/rxe_comp.c
+@@ -571,9 +571,8 @@ static void free_pkt(struct rxe_pkt_info *pkt)
+ ib_device_put(dev);
+ }
+
+-int rxe_completer(void *arg)
++int rxe_completer(struct rxe_qp *qp)
+ {
+- struct rxe_qp *qp = (struct rxe_qp *)arg;
+ struct rxe_dev *rxe = to_rdev(qp->ibqp.device);
+ struct rxe_send_wqe *wqe = NULL;
+ struct sk_buff *skb = NULL;
+diff --git a/drivers/infiniband/sw/rxe/rxe_cq.c b/drivers/infiniband/sw/rxe/rxe_cq.c
+index 1df186534639a..faf49c50bbaba 100644
+--- a/drivers/infiniband/sw/rxe/rxe_cq.c
++++ b/drivers/infiniband/sw/rxe/rxe_cq.c
+@@ -39,21 +39,6 @@ err1:
+ return -EINVAL;
+ }
+
+-static void rxe_send_complete(struct tasklet_struct *t)
+-{
+- struct rxe_cq *cq = from_tasklet(cq, t, comp_task);
+- unsigned long flags;
+-
+- spin_lock_irqsave(&cq->cq_lock, flags);
+- if (cq->is_dying) {
+- spin_unlock_irqrestore(&cq->cq_lock, flags);
+- return;
+- }
+- spin_unlock_irqrestore(&cq->cq_lock, flags);
+-
+- cq->ibcq.comp_handler(&cq->ibcq, cq->ibcq.cq_context);
+-}
+-
+ int rxe_cq_from_init(struct rxe_dev *rxe, struct rxe_cq *cq, int cqe,
+ int comp_vector, struct ib_udata *udata,
+ struct rxe_create_cq_resp __user *uresp)
+@@ -79,10 +64,6 @@ int rxe_cq_from_init(struct rxe_dev *rxe, struct rxe_cq *cq, int cqe,
+
+ cq->is_user = uresp;
+
+- cq->is_dying = false;
+-
+- tasklet_setup(&cq->comp_task, rxe_send_complete);
+-
+ spin_lock_init(&cq->cq_lock);
+ cq->ibcq.cqe = cqe;
+ return 0;
+@@ -103,6 +84,7 @@ int rxe_cq_resize_queue(struct rxe_cq *cq, int cqe,
+ return err;
+ }
+
++/* caller holds reference to cq */
+ int rxe_cq_post(struct rxe_cq *cq, struct rxe_cqe *cqe, int solicited)
+ {
+ struct ib_event ev;
+@@ -135,21 +117,13 @@ int rxe_cq_post(struct rxe_cq *cq, struct rxe_cqe *cqe, int solicited)
+ if ((cq->notify == IB_CQ_NEXT_COMP) ||
+ (cq->notify == IB_CQ_SOLICITED && solicited)) {
+ cq->notify = 0;
+- tasklet_schedule(&cq->comp_task);
++
++ cq->ibcq.comp_handler(&cq->ibcq, cq->ibcq.cq_context);
+ }
+
+ return 0;
+ }
+
+-void rxe_cq_disable(struct rxe_cq *cq)
+-{
+- unsigned long flags;
+-
+- spin_lock_irqsave(&cq->cq_lock, flags);
+- cq->is_dying = true;
+- spin_unlock_irqrestore(&cq->cq_lock, flags);
+-}
+-
+ void rxe_cq_cleanup(struct rxe_pool_elem *elem)
+ {
+ struct rxe_cq *cq = container_of(elem, typeof(*cq), elem);
+diff --git a/drivers/infiniband/sw/rxe/rxe_loc.h b/drivers/infiniband/sw/rxe/rxe_loc.h
+index 1bb0cb479eb12..d131aaa94d059 100644
+--- a/drivers/infiniband/sw/rxe/rxe_loc.h
++++ b/drivers/infiniband/sw/rxe/rxe_loc.h
+@@ -171,9 +171,9 @@ void rxe_srq_cleanup(struct rxe_pool_elem *elem);
+
+ void rxe_dealloc(struct ib_device *ib_dev);
+
+-int rxe_completer(void *arg);
+-int rxe_requester(void *arg);
+-int rxe_responder(void *arg);
++int rxe_completer(struct rxe_qp *qp);
++int rxe_requester(struct rxe_qp *qp);
++int rxe_responder(struct rxe_qp *qp);
+
+ /* rxe_icrc.c */
+ int rxe_icrc_init(struct rxe_dev *rxe);
+diff --git a/drivers/infiniband/sw/rxe/rxe_qp.c b/drivers/infiniband/sw/rxe/rxe_qp.c
+index ab72db68b58f6..13283ec06f95e 100644
+--- a/drivers/infiniband/sw/rxe/rxe_qp.c
++++ b/drivers/infiniband/sw/rxe/rxe_qp.c
+@@ -473,29 +473,23 @@ static void rxe_qp_reset(struct rxe_qp *qp)
+ {
+ /* stop tasks from running */
+ rxe_disable_task(&qp->resp.task);
+-
+- /* stop request/comp */
+- if (qp->sq.queue) {
+- if (qp_type(qp) == IB_QPT_RC)
+- rxe_disable_task(&qp->comp.task);
+- rxe_disable_task(&qp->req.task);
+- }
++ rxe_disable_task(&qp->comp.task);
++ rxe_disable_task(&qp->req.task);
+
+ /* move qp to the reset state */
+ qp->req.state = QP_STATE_RESET;
+ qp->comp.state = QP_STATE_RESET;
+ qp->resp.state = QP_STATE_RESET;
+
+- /* let state machines reset themselves drain work and packet queues
+- * etc.
+- */
+- __rxe_do_task(&qp->resp.task);
++ /* drain work and packet queuesc */
++ rxe_requester(qp);
++ rxe_completer(qp);
++ rxe_responder(qp);
+
+- if (qp->sq.queue) {
+- __rxe_do_task(&qp->comp.task);
+- __rxe_do_task(&qp->req.task);
++ if (qp->rq.queue)
++ rxe_queue_reset(qp->rq.queue);
++ if (qp->sq.queue)
+ rxe_queue_reset(qp->sq.queue);
+- }
+
+ /* cleanup attributes */
+ atomic_set(&qp->ssn, 0);
+@@ -518,13 +512,8 @@ static void rxe_qp_reset(struct rxe_qp *qp)
+
+ /* reenable tasks */
+ rxe_enable_task(&qp->resp.task);
+-
+- if (qp->sq.queue) {
+- if (qp_type(qp) == IB_QPT_RC)
+- rxe_enable_task(&qp->comp.task);
+-
+- rxe_enable_task(&qp->req.task);
+- }
++ rxe_enable_task(&qp->comp.task);
++ rxe_enable_task(&qp->req.task);
+ }
+
+ /* drain the send queue */
+@@ -533,10 +522,7 @@ static void rxe_qp_drain(struct rxe_qp *qp)
+ if (qp->sq.queue) {
+ if (qp->req.state != QP_STATE_DRAINED) {
+ qp->req.state = QP_STATE_DRAIN;
+- if (qp_type(qp) == IB_QPT_RC)
+- rxe_sched_task(&qp->comp.task);
+- else
+- __rxe_do_task(&qp->comp.task);
++ rxe_sched_task(&qp->comp.task);
+ rxe_sched_task(&qp->req.task);
+ }
+ }
+@@ -552,11 +538,7 @@ void rxe_qp_error(struct rxe_qp *qp)
+
+ /* drain work and packet queues */
+ rxe_sched_task(&qp->resp.task);
+-
+- if (qp_type(qp) == IB_QPT_RC)
+- rxe_sched_task(&qp->comp.task);
+- else
+- __rxe_do_task(&qp->comp.task);
++ rxe_sched_task(&qp->comp.task);
+ rxe_sched_task(&qp->req.task);
+ }
+
+@@ -773,24 +755,25 @@ static void rxe_qp_do_cleanup(struct work_struct *work)
+
+ qp->valid = 0;
+ qp->qp_timeout_jiffies = 0;
+- rxe_cleanup_task(&qp->resp.task);
+
+ if (qp_type(qp) == IB_QPT_RC) {
+ del_timer_sync(&qp->retrans_timer);
+ del_timer_sync(&qp->rnr_nak_timer);
+ }
+
+- rxe_cleanup_task(&qp->req.task);
+- rxe_cleanup_task(&qp->comp.task);
++ if (qp->resp.task.func)
++ rxe_cleanup_task(&qp->resp.task);
+
+- /* flush out any receive wr's or pending requests */
+ if (qp->req.task.func)
+- __rxe_do_task(&qp->req.task);
++ rxe_cleanup_task(&qp->req.task);
+
+- if (qp->sq.queue) {
+- __rxe_do_task(&qp->comp.task);
+- __rxe_do_task(&qp->req.task);
+- }
++ if (qp->comp.task.func)
++ rxe_cleanup_task(&qp->comp.task);
++
++ /* flush out any receive wr's or pending requests */
++ rxe_requester(qp);
++ rxe_completer(qp);
++ rxe_responder(qp);
+
+ if (qp->sq.queue)
+ rxe_queue_cleanup(qp->sq.queue);
+diff --git a/drivers/infiniband/sw/rxe/rxe_req.c b/drivers/infiniband/sw/rxe/rxe_req.c
+index 899c8779f8001..f2dc2d191e16f 100644
+--- a/drivers/infiniband/sw/rxe/rxe_req.c
++++ b/drivers/infiniband/sw/rxe/rxe_req.c
+@@ -635,9 +635,8 @@ static int rxe_do_local_ops(struct rxe_qp *qp, struct rxe_send_wqe *wqe)
+ return 0;
+ }
+
+-int rxe_requester(void *arg)
++int rxe_requester(struct rxe_qp *qp)
+ {
+- struct rxe_qp *qp = (struct rxe_qp *)arg;
+ struct rxe_dev *rxe = to_rdev(qp->ibqp.device);
+ struct rxe_pkt_info pkt;
+ struct sk_buff *skb;
+diff --git a/drivers/infiniband/sw/rxe/rxe_resp.c b/drivers/infiniband/sw/rxe/rxe_resp.c
+index 0cc1ba91d48cc..8c68340502769 100644
+--- a/drivers/infiniband/sw/rxe/rxe_resp.c
++++ b/drivers/infiniband/sw/rxe/rxe_resp.c
+@@ -1439,9 +1439,8 @@ static void rxe_drain_req_pkts(struct rxe_qp *qp, bool notify)
+ queue_advance_consumer(q, q->type);
+ }
+
+-int rxe_responder(void *arg)
++int rxe_responder(struct rxe_qp *qp)
+ {
+- struct rxe_qp *qp = (struct rxe_qp *)arg;
+ struct rxe_dev *rxe = to_rdev(qp->ibqp.device);
+ enum resp_states state;
+ struct rxe_pkt_info *pkt = NULL;
+diff --git a/drivers/infiniband/sw/rxe/rxe_task.c b/drivers/infiniband/sw/rxe/rxe_task.c
+index 60b90e33a8849..a67f485454436 100644
+--- a/drivers/infiniband/sw/rxe/rxe_task.c
++++ b/drivers/infiniband/sw/rxe/rxe_task.c
+@@ -6,19 +6,6 @@
+
+ #include "rxe.h"
+
+-int __rxe_do_task(struct rxe_task *task)
+-
+-{
+- int ret;
+-
+- while ((ret = task->func(task->arg)) == 0)
+- ;
+-
+- task->ret = ret;
+-
+- return ret;
+-}
+-
+ /*
+ * this locking is due to a potential race where
+ * a second caller finds the task already running
+@@ -29,7 +16,7 @@ static void do_task(struct tasklet_struct *t)
+ int cont;
+ int ret;
+ struct rxe_task *task = from_tasklet(task, t, tasklet);
+- struct rxe_qp *qp = (struct rxe_qp *)task->arg;
++ struct rxe_qp *qp = (struct rxe_qp *)task->qp;
+ unsigned int iterations = RXE_MAX_ITERATIONS;
+
+ spin_lock_bh(&task->lock);
+@@ -54,7 +41,7 @@ static void do_task(struct tasklet_struct *t)
+
+ do {
+ cont = 0;
+- ret = task->func(task->arg);
++ ret = task->func(task->qp);
+
+ spin_lock_bh(&task->lock);
+ switch (task->state) {
+@@ -91,9 +78,10 @@ static void do_task(struct tasklet_struct *t)
+ task->ret = ret;
+ }
+
+-int rxe_init_task(struct rxe_task *task, void *arg, int (*func)(void *))
++int rxe_init_task(struct rxe_task *task, struct rxe_qp *qp,
++ int (*func)(struct rxe_qp *))
+ {
+- task->arg = arg;
++ task->qp = qp;
+ task->func = func;
+ task->destroyed = false;
+
+diff --git a/drivers/infiniband/sw/rxe/rxe_task.h b/drivers/infiniband/sw/rxe/rxe_task.h
+index 7b88129702ac6..99585e40cef92 100644
+--- a/drivers/infiniband/sw/rxe/rxe_task.h
++++ b/drivers/infiniband/sw/rxe/rxe_task.h
+@@ -22,28 +22,23 @@ struct rxe_task {
+ struct tasklet_struct tasklet;
+ int state;
+ spinlock_t lock;
+- void *arg;
+- int (*func)(void *arg);
++ struct rxe_qp *qp;
++ int (*func)(struct rxe_qp *qp);
+ int ret;
+ bool destroyed;
+ };
+
+ /*
+ * init rxe_task structure
+- * arg => parameter to pass to fcn
++ * qp => parameter to pass to func
+ * func => function to call until it returns != 0
+ */
+-int rxe_init_task(struct rxe_task *task, void *arg, int (*func)(void *));
++int rxe_init_task(struct rxe_task *task, struct rxe_qp *qp,
++ int (*func)(struct rxe_qp *));
+
+ /* cleanup task */
+ void rxe_cleanup_task(struct rxe_task *task);
+
+-/*
+- * raw call to func in loop without any checking
+- * can call when tasklets are disabled
+- */
+-int __rxe_do_task(struct rxe_task *task);
+-
+ void rxe_run_task(struct rxe_task *task);
+
+ void rxe_sched_task(struct rxe_task *task);
+diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.c b/drivers/infiniband/sw/rxe/rxe_verbs.c
+index a3aee247aa157..9ae7cf93365c7 100644
+--- a/drivers/infiniband/sw/rxe/rxe_verbs.c
++++ b/drivers/infiniband/sw/rxe/rxe_verbs.c
+@@ -786,8 +786,6 @@ static int rxe_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
+ if (atomic_read(&cq->num_wq))
+ return -EINVAL;
+
+- rxe_cq_disable(cq);
+-
+ rxe_cleanup(cq);
+ return 0;
+ }
+diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.h b/drivers/infiniband/sw/rxe/rxe_verbs.h
+index c269ae2a32243..d812093a39166 100644
+--- a/drivers/infiniband/sw/rxe/rxe_verbs.h
++++ b/drivers/infiniband/sw/rxe/rxe_verbs.h
+@@ -63,9 +63,7 @@ struct rxe_cq {
+ struct rxe_queue *queue;
+ spinlock_t cq_lock;
+ u8 notify;
+- bool is_dying;
+ bool is_user;
+- struct tasklet_struct comp_task;
+ atomic_t num_wq;
+ };
+
+diff --git a/drivers/infiniband/sw/siw/siw_main.c b/drivers/infiniband/sw/siw/siw_main.c
+index dacc174604bf2..65b5cda5457ba 100644
+--- a/drivers/infiniband/sw/siw/siw_main.c
++++ b/drivers/infiniband/sw/siw/siw_main.c
+@@ -437,9 +437,6 @@ static int siw_netdev_event(struct notifier_block *nb, unsigned long event,
+
+ dev_dbg(&netdev->dev, "siw: event %lu\n", event);
+
+- if (dev_net(netdev) != &init_net)
+- return NOTIFY_OK;
+-
+ base_dev = ib_device_get_by_netdev(netdev, RDMA_DRIVER_SIW);
+ if (!base_dev)
+ return NOTIFY_OK;
+diff --git a/drivers/infiniband/sw/siw/siw_qp_tx.c b/drivers/infiniband/sw/siw/siw_qp_tx.c
+index 05052b49107f2..6bb9e9e81ff4c 100644
+--- a/drivers/infiniband/sw/siw/siw_qp_tx.c
++++ b/drivers/infiniband/sw/siw/siw_qp_tx.c
+@@ -558,7 +558,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx, struct socket *s)
+ data_len -= plen;
+ fp_off = 0;
+
+- if (++seg > (int)MAX_ARRAY) {
++ if (++seg >= (int)MAX_ARRAY) {
+ siw_dbg_qp(tx_qp(c_tx), "to many fragments\n");
+ siw_unmap_pages(iov, kmap_mask, seg-1);
+ wqe->processed -= c_tx->bytes_unsent;
+diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c
+index 75404885cf981..f290cd49698ea 100644
+--- a/drivers/infiniband/ulp/isert/ib_isert.c
++++ b/drivers/infiniband/ulp/isert/ib_isert.c
+@@ -2506,8 +2506,8 @@ isert_wait4cmds(struct iscsit_conn *conn)
+ isert_info("iscsit_conn %p\n", conn);
+
+ if (conn->sess) {
+- target_stop_session(conn->sess->se_sess);
+- target_wait_for_sess_cmds(conn->sess->se_sess);
++ target_stop_cmd_counter(conn->cmd_cnt);
++ target_wait_for_cmds(conn->cmd_cnt);
+ }
+ }
+
+diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c
+index 3c3fae738c3ed..25e799dba999e 100644
+--- a/drivers/infiniband/ulp/srpt/ib_srpt.c
++++ b/drivers/infiniband/ulp/srpt/ib_srpt.c
+@@ -549,6 +549,7 @@ static int srpt_format_guid(char *buf, unsigned int size, const __be64 *guid)
+ */
+ static int srpt_refresh_port(struct srpt_port *sport)
+ {
++ struct ib_mad_agent *mad_agent;
+ struct ib_mad_reg_req reg_req;
+ struct ib_port_modify port_modify;
+ struct ib_port_attr port_attr;
+@@ -593,24 +594,26 @@ static int srpt_refresh_port(struct srpt_port *sport)
+ set_bit(IB_MGMT_METHOD_GET, reg_req.method_mask);
+ set_bit(IB_MGMT_METHOD_SET, reg_req.method_mask);
+
+- sport->mad_agent = ib_register_mad_agent(sport->sdev->device,
+- sport->port,
+- IB_QPT_GSI,
+- &reg_req, 0,
+- srpt_mad_send_handler,
+- srpt_mad_recv_handler,
+- sport, 0);
+- if (IS_ERR(sport->mad_agent)) {
++ mad_agent = ib_register_mad_agent(sport->sdev->device,
++ sport->port,
++ IB_QPT_GSI,
++ &reg_req, 0,
++ srpt_mad_send_handler,
++ srpt_mad_recv_handler,
++ sport, 0);
++ if (IS_ERR(mad_agent)) {
+ pr_err("%s-%d: MAD agent registration failed (%ld). Note: this is expected if SR-IOV is enabled.\n",
+ dev_name(&sport->sdev->device->dev), sport->port,
+- PTR_ERR(sport->mad_agent));
++ PTR_ERR(mad_agent));
+ sport->mad_agent = NULL;
+ memset(&port_modify, 0, sizeof(port_modify));
+ port_modify.clr_port_cap_mask = IB_PORT_DEVICE_MGMT_SUP;
+ ib_modify_port(sport->sdev->device, sport->port, 0,
+ &port_modify);
+-
++ return 0;
+ }
++
++ sport->mad_agent = mad_agent;
+ }
+
+ return 0;
+diff --git a/drivers/input/touchscreen/raspberrypi-ts.c b/drivers/input/touchscreen/raspberrypi-ts.c
+index 5000f5fd9ec38..45c575df994e0 100644
+--- a/drivers/input/touchscreen/raspberrypi-ts.c
++++ b/drivers/input/touchscreen/raspberrypi-ts.c
+@@ -134,7 +134,7 @@ static int rpi_ts_probe(struct platform_device *pdev)
+ return -ENOENT;
+ }
+
+- fw = rpi_firmware_get(fw_node);
++ fw = devm_rpi_firmware_get(&pdev->dev, fw_node);
+ of_node_put(fw_node);
+ if (!fw)
+ return -EPROBE_DEFER;
+@@ -160,7 +160,6 @@ static int rpi_ts_probe(struct platform_device *pdev)
+ touchbuf = (u32)ts->fw_regs_phys;
+ error = rpi_firmware_property(fw, RPI_FIRMWARE_FRAMEBUFFER_SET_TOUCHBUF,
+ &touchbuf, sizeof(touchbuf));
+- rpi_firmware_put(fw);
+ if (error || touchbuf != 0) {
+ dev_warn(dev, "Failed to set touchbuf, %d\n", error);
+ return error;
+diff --git a/drivers/interconnect/qcom/icc-rpm.c b/drivers/interconnect/qcom/icc-rpm.c
+index 4180a06681b2b..c80819557923e 100644
+--- a/drivers/interconnect/qcom/icc-rpm.c
++++ b/drivers/interconnect/qcom/icc-rpm.c
+@@ -11,7 +11,6 @@
+ #include <linux/of_device.h>
+ #include <linux/of_platform.h>
+ #include <linux/platform_device.h>
+-#include <linux/pm_domain.h>
+ #include <linux/regmap.h>
+ #include <linux/slab.h>
+
+@@ -496,12 +495,6 @@ regmap_done:
+ if (ret)
+ return ret;
+
+- if (desc->has_bus_pd) {
+- ret = dev_pm_domain_attach(dev, true);
+- if (ret)
+- return ret;
+- }
+-
+ provider = &qp->provider;
+ provider->dev = dev;
+ provider->set = qcom_icc_set;
+diff --git a/drivers/interconnect/qcom/icc-rpm.h b/drivers/interconnect/qcom/icc-rpm.h
+index a49af844ab13e..02257b0d3d5c6 100644
+--- a/drivers/interconnect/qcom/icc-rpm.h
++++ b/drivers/interconnect/qcom/icc-rpm.h
+@@ -91,7 +91,6 @@ struct qcom_icc_desc {
+ size_t num_nodes;
+ const char * const *clocks;
+ size_t num_clocks;
+- bool has_bus_pd;
+ enum qcom_icc_type type;
+ const struct regmap_config *regmap_cfg;
+ unsigned int qos_offset;
+diff --git a/drivers/interconnect/qcom/msm8996.c b/drivers/interconnect/qcom/msm8996.c
+index 25a1a32bc611f..14efd2761b7ab 100644
+--- a/drivers/interconnect/qcom/msm8996.c
++++ b/drivers/interconnect/qcom/msm8996.c
+@@ -1823,7 +1823,6 @@ static const struct qcom_icc_desc msm8996_a0noc = {
+ .num_nodes = ARRAY_SIZE(a0noc_nodes),
+ .clocks = bus_a0noc_clocks,
+ .num_clocks = ARRAY_SIZE(bus_a0noc_clocks),
+- .has_bus_pd = true,
+ .regmap_cfg = &msm8996_a0noc_regmap_config
+ };
+
+diff --git a/drivers/interconnect/qcom/osm-l3.c b/drivers/interconnect/qcom/osm-l3.c
+index 1bafb54f14329..a1f4f918b9116 100644
+--- a/drivers/interconnect/qcom/osm-l3.c
++++ b/drivers/interconnect/qcom/osm-l3.c
+@@ -14,13 +14,6 @@
+
+ #include <dt-bindings/interconnect/qcom,osm-l3.h>
+
+-#include "sc7180.h"
+-#include "sc7280.h"
+-#include "sc8180x.h"
+-#include "sdm845.h"
+-#include "sm8150.h"
+-#include "sm8250.h"
+-
+ #define LUT_MAX_ENTRIES 40U
+ #define LUT_SRC GENMASK(31, 30)
+ #define LUT_L_VAL GENMASK(7, 0)
+diff --git a/drivers/interconnect/qcom/sc7180.h b/drivers/interconnect/qcom/sc7180.h
+index c6212a10c2f61..c2d8388bb8809 100644
+--- a/drivers/interconnect/qcom/sc7180.h
++++ b/drivers/interconnect/qcom/sc7180.h
+@@ -145,7 +145,5 @@
+ #define SC7180_SLAVE_SERVICE_SNOC 134
+ #define SC7180_SLAVE_QDSS_STM 135
+ #define SC7180_SLAVE_TCU 136
+-#define SC7180_MASTER_OSM_L3_APPS 137
+-#define SC7180_SLAVE_OSM_L3 138
+
+ #endif
+diff --git a/drivers/interconnect/qcom/sc7280.h b/drivers/interconnect/qcom/sc7280.h
+index 1fb9839b2c14b..175e400305c51 100644
+--- a/drivers/interconnect/qcom/sc7280.h
++++ b/drivers/interconnect/qcom/sc7280.h
+@@ -150,7 +150,5 @@
+ #define SC7280_SLAVE_PCIE_1 139
+ #define SC7280_SLAVE_QDSS_STM 140
+ #define SC7280_SLAVE_TCU 141
+-#define SC7280_MASTER_EPSS_L3_APPS 142
+-#define SC7280_SLAVE_EPSS_L3 143
+
+ #endif
+diff --git a/drivers/interconnect/qcom/sc8180x.h b/drivers/interconnect/qcom/sc8180x.h
+index 2eafd35543c78..ce32295af8f3a 100644
+--- a/drivers/interconnect/qcom/sc8180x.h
++++ b/drivers/interconnect/qcom/sc8180x.h
+@@ -168,8 +168,6 @@
+ #define SC8180X_SLAVE_EBI_CH0_DISPLAY 158
+ #define SC8180X_SLAVE_MNOC_SF_MEM_NOC_DISPLAY 159
+ #define SC8180X_SLAVE_MNOC_HF_MEM_NOC_DISPLAY 160
+-#define SC8180X_MASTER_OSM_L3_APPS 161
+-#define SC8180X_SLAVE_OSM_L3 162
+
+ #define SC8180X_MASTER_QUP_CORE_0 163
+ #define SC8180X_MASTER_QUP_CORE_1 164
+diff --git a/drivers/interconnect/qcom/sdm845.h b/drivers/interconnect/qcom/sdm845.h
+index 776e9c2acb278..bc7e425ce9852 100644
+--- a/drivers/interconnect/qcom/sdm845.h
++++ b/drivers/interconnect/qcom/sdm845.h
+@@ -136,7 +136,5 @@
+ #define SDM845_SLAVE_SERVICE_SNOC 128
+ #define SDM845_SLAVE_QDSS_STM 129
+ #define SDM845_SLAVE_TCU 130
+-#define SDM845_MASTER_OSM_L3_APPS 131
+-#define SDM845_SLAVE_OSM_L3 132
+
+ #endif /* __DRIVERS_INTERCONNECT_QCOM_SDM845_H__ */
+diff --git a/drivers/interconnect/qcom/sm8150.h b/drivers/interconnect/qcom/sm8150.h
+index 97996f64d799c..3e01ac76ae1db 100644
+--- a/drivers/interconnect/qcom/sm8150.h
++++ b/drivers/interconnect/qcom/sm8150.h
+@@ -148,7 +148,5 @@
+ #define SM8150_SLAVE_VSENSE_CTRL_CFG 137
+ #define SM8150_SNOC_CNOC_MAS 138
+ #define SM8150_SNOC_CNOC_SLV 139
+-#define SM8150_MASTER_OSM_L3_APPS 140
+-#define SM8150_SLAVE_OSM_L3 141
+
+ #endif
+diff --git a/drivers/interconnect/qcom/sm8250.h b/drivers/interconnect/qcom/sm8250.h
+index b31fb431a20fc..7eb6c709c30d1 100644
+--- a/drivers/interconnect/qcom/sm8250.h
++++ b/drivers/interconnect/qcom/sm8250.h
+@@ -158,7 +158,5 @@
+ #define SM8250_SLAVE_VSENSE_CTRL_CFG 147
+ #define SM8250_SNOC_CNOC_MAS 148
+ #define SM8250_SNOC_CNOC_SLV 149
+-#define SM8250_MASTER_EPSS_L3_APPS 150
+-#define SM8250_SLAVE_EPSS_L3 151
+
+ #endif
+diff --git a/drivers/iommu/amd/amd_iommu_types.h b/drivers/iommu/amd/amd_iommu_types.h
+index 3d684190b4d53..f7cb1ce0f9bbc 100644
+--- a/drivers/iommu/amd/amd_iommu_types.h
++++ b/drivers/iommu/amd/amd_iommu_types.h
+@@ -1001,8 +1001,8 @@ struct amd_ir_data {
+ */
+ struct irq_cfg *cfg;
+ int ga_vector;
+- int ga_root_ptr;
+- int ga_tag;
++ u64 ga_root_ptr;
++ u32 ga_tag;
+ };
+
+ struct amd_irte_ops {
+diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
+index ff4f3d4da3402..e108280fdaa0e 100644
+--- a/drivers/iommu/amd/iommu.c
++++ b/drivers/iommu/amd/iommu.c
+@@ -1656,10 +1656,6 @@ static void do_attach(struct iommu_dev_data *dev_data,
+ domain->dev_iommu[iommu->index] += 1;
+ domain->dev_cnt += 1;
+
+- /* Override supported page sizes */
+- if (domain->flags & PD_GIOV_MASK)
+- domain->domain.pgsize_bitmap = AMD_IOMMU_PGSIZES_V2;
+-
+ /* Update device table */
+ set_dte_entry(iommu, dev_data->devid, domain,
+ ats, dev_data->iommu_v2);
+@@ -2038,6 +2034,8 @@ static int protection_domain_init_v2(struct protection_domain *domain)
+
+ domain->flags |= PD_GIOV_MASK;
+
++ domain->domain.pgsize_bitmap = AMD_IOMMU_PGSIZES_V2;
++
+ if (domain_enable_v2(domain, 1)) {
+ domain_id_free(domain->id);
+ return -ENOMEM;
+diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
+index f8100067502fb..e6f2a0bc9f0be 100644
+--- a/drivers/iommu/iommu.c
++++ b/drivers/iommu/iommu.c
+@@ -1940,8 +1940,13 @@ static struct iommu_domain *__iommu_domain_alloc(struct bus_type *bus,
+ return NULL;
+
+ domain->type = type;
+- /* Assume all sizes by default; the driver may override this later */
+- domain->pgsize_bitmap = bus->iommu_ops->pgsize_bitmap;
++ /*
++ * If not already set, assume all sizes by default; the driver
++ * may override this later
++ */
++ if (!domain->pgsize_bitmap)
++ domain->pgsize_bitmap = bus->iommu_ops->pgsize_bitmap;
++
+ if (!domain->ops)
+ domain->ops = bus->iommu_ops->default_domain_ops;
+
+diff --git a/drivers/iommu/iommufd/selftest.c b/drivers/iommu/iommufd/selftest.c
+index cfb5fe9a5e0ee..76c46847dc494 100644
+--- a/drivers/iommu/iommufd/selftest.c
++++ b/drivers/iommu/iommufd/selftest.c
+@@ -339,10 +339,12 @@ static int iommufd_test_md_check_pa(struct iommufd_ucmd *ucmd,
+ {
+ struct iommufd_hw_pagetable *hwpt;
+ struct mock_iommu_domain *mock;
++ uintptr_t end;
+ int rc;
+
+ if (iova % MOCK_IO_PAGE_SIZE || length % MOCK_IO_PAGE_SIZE ||
+- (uintptr_t)uptr % MOCK_IO_PAGE_SIZE)
++ (uintptr_t)uptr % MOCK_IO_PAGE_SIZE ||
++ check_add_overflow((uintptr_t)uptr, (uintptr_t)length, &end))
+ return -EINVAL;
+
+ hwpt = get_md_pagetable(ucmd, mockpt_id, &mock);
+@@ -390,7 +392,10 @@ static int iommufd_test_md_check_refs(struct iommufd_ucmd *ucmd,
+ void __user *uptr, size_t length,
+ unsigned int refs)
+ {
+- if (length % PAGE_SIZE || (uintptr_t)uptr % PAGE_SIZE)
++ uintptr_t end;
++
++ if (length % PAGE_SIZE || (uintptr_t)uptr % PAGE_SIZE ||
++ check_add_overflow((uintptr_t)uptr, (uintptr_t)length, &end))
+ return -EINVAL;
+
+ for (; length; length -= PAGE_SIZE) {
+diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
+index 2badd6acfb23d..4ef71afb9525a 100644
+--- a/drivers/iommu/mtk_iommu.c
++++ b/drivers/iommu/mtk_iommu.c
+@@ -1267,6 +1267,14 @@ static int mtk_iommu_probe(struct platform_device *pdev)
+ return PTR_ERR(data->bclk);
+ }
+
++ if (MTK_IOMMU_HAS_FLAG(data->plat_data, PGTABLE_PA_35_EN)) {
++ ret = dma_set_mask(dev, DMA_BIT_MASK(35));
++ if (ret) {
++ dev_err(dev, "Failed to set dma_mask 35.\n");
++ return ret;
++ }
++ }
++
+ pm_runtime_enable(dev);
+
+ if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) {
+diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
+index 499d0f215a8bf..2378cfb7443e4 100644
+--- a/drivers/leds/Kconfig
++++ b/drivers/leds/Kconfig
+@@ -814,7 +814,7 @@ config LEDS_SPI_BYTE
+ config LEDS_TI_LMU_COMMON
+ tristate "LED driver for TI LMU"
+ depends on LEDS_CLASS
+- depends on REGMAP
++ select REGMAP
+ help
+ Say Y to enable the LED driver for TI LMU devices.
+ This supports common features between the TI LM3532, LM3631, LM3632,
+diff --git a/drivers/leds/leds-tca6507.c b/drivers/leds/leds-tca6507.c
+index 161bef65c6b7b..62a968613cc37 100644
+--- a/drivers/leds/leds-tca6507.c
++++ b/drivers/leds/leds-tca6507.c
+@@ -691,8 +691,9 @@ tca6507_led_dt_init(struct device *dev)
+ if (fwnode_property_read_string(child, "label", &led.name))
+ led.name = fwnode_get_name(child);
+
+- fwnode_property_read_string(child, "linux,default-trigger",
+- &led.default_trigger);
++ if (fwnode_property_read_string(child, "linux,default-trigger",
++ &led.default_trigger))
++ led.default_trigger = NULL;
+
+ led.flags = 0;
+ if (fwnode_property_match_string(child, "compatible",
+diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig
+index 539a2ed4e13dc..a0e717a986dcb 100644
+--- a/drivers/macintosh/Kconfig
++++ b/drivers/macintosh/Kconfig
+@@ -86,6 +86,7 @@ config ADB_PMU_LED
+
+ config ADB_PMU_LED_DISK
+ bool "Use front LED as DISK LED by default"
++ depends on ATA
+ depends on ADB_PMU_LED
+ depends on LEDS_CLASS
+ select LEDS_TRIGGERS
+diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c
+index ebc4256a9e4a0..089f2743a070d 100644
+--- a/drivers/macintosh/windfarm_smu_sat.c
++++ b/drivers/macintosh/windfarm_smu_sat.c
+@@ -171,6 +171,7 @@ static void wf_sat_release(struct kref *ref)
+
+ if (sat->nr >= 0)
+ sats[sat->nr] = NULL;
++ of_node_put(sat->node);
+ kfree(sat);
+ }
+
+diff --git a/drivers/mailbox/mailbox-mpfs.c b/drivers/mailbox/mailbox-mpfs.c
+index 853901acaeec2..08aa840cccaca 100644
+--- a/drivers/mailbox/mailbox-mpfs.c
++++ b/drivers/mailbox/mailbox-mpfs.c
+@@ -79,6 +79,13 @@ static bool mpfs_mbox_busy(struct mpfs_mbox *mbox)
+ return status & SCB_STATUS_BUSY_MASK;
+ }
+
++static bool mpfs_mbox_last_tx_done(struct mbox_chan *chan)
++{
++ struct mpfs_mbox *mbox = (struct mpfs_mbox *)chan->con_priv;
++
++ return !mpfs_mbox_busy(mbox);
++}
++
+ static int mpfs_mbox_send_data(struct mbox_chan *chan, void *data)
+ {
+ struct mpfs_mbox *mbox = (struct mpfs_mbox *)chan->con_priv;
+@@ -182,7 +189,6 @@ static irqreturn_t mpfs_mbox_inbox_isr(int irq, void *data)
+
+ mpfs_mbox_rx_data(chan);
+
+- mbox_chan_txdone(chan, 0);
+ return IRQ_HANDLED;
+ }
+
+@@ -212,6 +218,7 @@ static const struct mbox_chan_ops mpfs_mbox_ops = {
+ .send_data = mpfs_mbox_send_data,
+ .startup = mpfs_mbox_startup,
+ .shutdown = mpfs_mbox_shutdown,
++ .last_tx_done = mpfs_mbox_last_tx_done,
+ };
+
+ static int mpfs_mbox_probe(struct platform_device *pdev)
+@@ -247,7 +254,8 @@ static int mpfs_mbox_probe(struct platform_device *pdev)
+ mbox->controller.num_chans = 1;
+ mbox->controller.chans = mbox->chans;
+ mbox->controller.ops = &mpfs_mbox_ops;
+- mbox->controller.txdone_irq = true;
++ mbox->controller.txdone_poll = true;
++ mbox->controller.txpoll_period = 10u;
+
+ ret = devm_mbox_controller_register(&pdev->dev, &mbox->controller);
+ if (ret) {
+diff --git a/drivers/mailbox/zynqmp-ipi-mailbox.c b/drivers/mailbox/zynqmp-ipi-mailbox.c
+index 12e004ff1a147..e02a4a18e8c29 100644
+--- a/drivers/mailbox/zynqmp-ipi-mailbox.c
++++ b/drivers/mailbox/zynqmp-ipi-mailbox.c
+@@ -152,7 +152,7 @@ static irqreturn_t zynqmp_ipi_interrupt(int irq, void *data)
+ struct zynqmp_ipi_message *msg;
+ u64 arg0, arg3;
+ struct arm_smccc_res res;
+- int ret, i;
++ int ret, i, status = IRQ_NONE;
+
+ (void)irq;
+ arg0 = SMC_IPI_MAILBOX_STATUS_ENQUIRY;
+@@ -170,11 +170,11 @@ static irqreturn_t zynqmp_ipi_interrupt(int irq, void *data)
+ memcpy_fromio(msg->data, mchan->req_buf,
+ msg->len);
+ mbox_chan_received_data(chan, (void *)msg);
+- return IRQ_HANDLED;
++ status = IRQ_HANDLED;
+ }
+ }
+ }
+- return IRQ_NONE;
++ return status;
+ }
+
+ /**
+diff --git a/drivers/md/dm-clone-target.c b/drivers/md/dm-clone-target.c
+index 29e0b85eeaf09..e088081b7a8ad 100644
+--- a/drivers/md/dm-clone-target.c
++++ b/drivers/md/dm-clone-target.c
+@@ -2205,6 +2205,7 @@ static int __init dm_clone_init(void)
+ r = dm_register_target(&clone_target);
+ if (r < 0) {
+ DMERR("Failed to register clone target");
++ kmem_cache_destroy(_hydration_cache);
+ return r;
+ }
+
+diff --git a/drivers/md/dm-flakey.c b/drivers/md/dm-flakey.c
+index 7efbdb42cf3b4..3b34270ce607e 100644
+--- a/drivers/md/dm-flakey.c
++++ b/drivers/md/dm-flakey.c
+@@ -124,9 +124,9 @@ static int parse_features(struct dm_arg_set *as, struct flakey_c *fc,
+ * Direction r or w?
+ */
+ arg_name = dm_shift_arg(as);
+- if (!strcasecmp(arg_name, "w"))
++ if (arg_name && !strcasecmp(arg_name, "w"))
+ fc->corrupt_bio_rw = WRITE;
+- else if (!strcasecmp(arg_name, "r"))
++ else if (arg_name && !strcasecmp(arg_name, "r"))
+ fc->corrupt_bio_rw = READ;
+ else {
+ ti->error = "Invalid corrupt bio direction (r or w)";
+diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c
+index 53f9f765df9fd..a2b8f8781a99f 100644
+--- a/drivers/md/dm-integrity.c
++++ b/drivers/md/dm-integrity.c
+@@ -4646,11 +4646,13 @@ static int __init dm_integrity_init(void)
+ }
+
+ r = dm_register_target(&integrity_target);
+-
+- if (r < 0)
++ if (r < 0) {
+ DMERR("register failed %d", r);
++ kmem_cache_destroy(journal_io_cache);
++ return r;
++ }
+
+- return r;
++ return 0;
+ }
+
+ static void __exit dm_integrity_exit(void)
+diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
+index 37f5ea7337cc2..bd63fc94f1dd9 100644
+--- a/drivers/md/dm-ioctl.c
++++ b/drivers/md/dm-ioctl.c
+@@ -1151,10 +1151,13 @@ static int do_resume(struct dm_ioctl *param)
+ /* Do we need to load a new map ? */
+ if (new_map) {
+ sector_t old_size, new_size;
++ int srcu_idx;
+
+ /* Suspend if it isn't already suspended */
+- if (param->flags & DM_SKIP_LOCKFS_FLAG)
++ old_map = dm_get_live_table(md, &srcu_idx);
++ if ((param->flags & DM_SKIP_LOCKFS_FLAG) || !old_map)
+ suspend_flags &= ~DM_SUSPEND_LOCKFS_FLAG;
++ dm_put_live_table(md, srcu_idx);
+ if (param->flags & DM_NOFLUSH_FLAG)
+ suspend_flags |= DM_SUSPEND_NOFLUSH_FLAG;
+ if (!dm_suspended_md(md))
+@@ -1539,11 +1542,12 @@ static int table_clear(struct file *filp, struct dm_ioctl *param, size_t param_s
+ has_new_map = true;
+ }
+
+- param->flags &= ~DM_INACTIVE_PRESENT_FLAG;
+-
+- __dev_status(hc->md, param);
+ md = hc->md;
+ up_write(&_hash_lock);
++
++ param->flags &= ~DM_INACTIVE_PRESENT_FLAG;
++ __dev_status(md, param);
++
+ if (old_map) {
+ dm_sync_table(md);
+ dm_table_destroy(old_map);
+diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
+index c571f2385b57f..3acded2f976db 100644
+--- a/drivers/md/dm-table.c
++++ b/drivers/md/dm-table.c
+@@ -1203,21 +1203,12 @@ struct dm_crypto_profile {
+ struct mapped_device *md;
+ };
+
+-struct dm_keyslot_evict_args {
+- const struct blk_crypto_key *key;
+- int err;
+-};
+-
+ static int dm_keyslot_evict_callback(struct dm_target *ti, struct dm_dev *dev,
+ sector_t start, sector_t len, void *data)
+ {
+- struct dm_keyslot_evict_args *args = data;
+- int err;
++ const struct blk_crypto_key *key = data;
+
+- err = blk_crypto_evict_key(dev->bdev, args->key);
+- if (!args->err)
+- args->err = err;
+- /* Always try to evict the key from all devices. */
++ blk_crypto_evict_key(dev->bdev, key);
+ return 0;
+ }
+
+@@ -1230,7 +1221,6 @@ static int dm_keyslot_evict(struct blk_crypto_profile *profile,
+ {
+ struct mapped_device *md =
+ container_of(profile, struct dm_crypto_profile, profile)->md;
+- struct dm_keyslot_evict_args args = { key };
+ struct dm_table *t;
+ int srcu_idx;
+
+@@ -1243,11 +1233,12 @@ static int dm_keyslot_evict(struct blk_crypto_profile *profile,
+
+ if (!ti->type->iterate_devices)
+ continue;
+- ti->type->iterate_devices(ti, dm_keyslot_evict_callback, &args);
++ ti->type->iterate_devices(ti, dm_keyslot_evict_callback,
++ (void *)key);
+ }
+
+ dm_put_live_table(md, srcu_idx);
+- return args.err;
++ return 0;
+ }
+
+ static int
+diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c
+index 64e8ac429984d..14a9988ec30ba 100644
+--- a/drivers/md/dm-verity-target.c
++++ b/drivers/md/dm-verity-target.c
+@@ -523,7 +523,7 @@ static int verity_verify_io(struct dm_verity_io *io)
+ sector_t cur_block = io->block + b;
+ struct ahash_request *req = verity_io_hash_req(v, io);
+
+- if (v->validated_blocks &&
++ if (v->validated_blocks && bio->bi_status == BLK_STS_OK &&
+ likely(test_bit(cur_block, v->validated_blocks))) {
+ verity_bv_skip_block(v, io, iter);
+ continue;
+diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
+index 6c66357f92f55..ea6967aeaa02a 100644
+--- a/drivers/md/raid10.c
++++ b/drivers/md/raid10.c
+@@ -995,11 +995,15 @@ static bool stop_waiting_barrier(struct r10conf *conf)
+ (!bio_list_empty(&bio_list[0]) || !bio_list_empty(&bio_list[1])))
+ return true;
+
+- /* move on if recovery thread is blocked by us */
+- if (conf->mddev->thread->tsk == current &&
+- test_bit(MD_RECOVERY_RUNNING, &conf->mddev->recovery) &&
+- conf->nr_queued > 0)
++ /*
++ * move on if io is issued from raid10d(), nr_pending is not released
++ * from original io(see handle_read_error()). All raise barrier is
++ * blocked until this io is done.
++ */
++ if (conf->mddev->thread->tsk == current) {
++ WARN_ON_ONCE(atomic_read(&conf->nr_pending) == 0);
+ return true;
++ }
+
+ return false;
+ }
+@@ -1244,7 +1248,8 @@ static void raid10_read_request(struct mddev *mddev, struct bio *bio,
+ }
+ slot = r10_bio->read_slot;
+
+- if (blk_queue_io_stat(bio->bi_bdev->bd_disk->queue))
++ if (!r10_bio->start_time &&
++ blk_queue_io_stat(bio->bi_bdev->bd_disk->queue))
+ r10_bio->start_time = bio_start_io_acct(bio);
+ read_bio = bio_alloc_clone(rdev->bdev, bio, gfp, &mddev->bio_set);
+
+@@ -1574,6 +1579,7 @@ static void __make_request(struct mddev *mddev, struct bio *bio, int sectors)
+ r10_bio->sector = bio->bi_iter.bi_sector;
+ r10_bio->state = 0;
+ r10_bio->read_slot = -1;
++ r10_bio->start_time = 0;
+ memset(r10_bio->devs, 0, sizeof(r10_bio->devs[0]) *
+ conf->geo.raid_disks);
+
+@@ -2609,11 +2615,22 @@ static void recovery_request_write(struct mddev *mddev, struct r10bio *r10_bio)
+ {
+ struct r10conf *conf = mddev->private;
+ int d;
+- struct bio *wbio, *wbio2;
++ struct bio *wbio = r10_bio->devs[1].bio;
++ struct bio *wbio2 = r10_bio->devs[1].repl_bio;
++
++ /* Need to test wbio2->bi_end_io before we call
++ * submit_bio_noacct as if the former is NULL,
++ * the latter is free to free wbio2.
++ */
++ if (wbio2 && !wbio2->bi_end_io)
++ wbio2 = NULL;
+
+ if (!test_bit(R10BIO_Uptodate, &r10_bio->state)) {
+ fix_recovery_read_error(r10_bio);
+- end_sync_request(r10_bio);
++ if (wbio->bi_end_io)
++ end_sync_request(r10_bio);
++ if (wbio2)
++ end_sync_request(r10_bio);
+ return;
+ }
+
+@@ -2622,14 +2639,6 @@ static void recovery_request_write(struct mddev *mddev, struct r10bio *r10_bio)
+ * and submit the write request
+ */
+ d = r10_bio->devs[1].devnum;
+- wbio = r10_bio->devs[1].bio;
+- wbio2 = r10_bio->devs[1].repl_bio;
+- /* Need to test wbio2->bi_end_io before we call
+- * submit_bio_noacct as if the former is NULL,
+- * the latter is free to free wbio2.
+- */
+- if (wbio2 && !wbio2->bi_end_io)
+- wbio2 = NULL;
+ if (wbio->bi_end_io) {
+ atomic_inc(&conf->mirrors[d].rdev->nr_pending);
+ md_sync_acct(conf->mirrors[d].rdev->bdev, bio_sectors(wbio));
+@@ -2978,9 +2987,13 @@ static void handle_read_error(struct mddev *mddev, struct r10bio *r10_bio)
+ md_error(mddev, rdev);
+
+ rdev_dec_pending(rdev, mddev);
+- allow_barrier(conf);
+ r10_bio->state = 0;
+ raid10_read_request(mddev, r10_bio->master_bio, r10_bio);
++ /*
++ * allow_barrier after re-submit to ensure no sync io
++ * can be issued while regular io pending.
++ */
++ allow_barrier(conf);
+ }
+
+ static void handle_write_completed(struct r10conf *conf, struct r10bio *r10_bio)
+@@ -3289,10 +3302,6 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
+ sector_t chunk_mask = conf->geo.chunk_mask;
+ int page_idx = 0;
+
+- if (!mempool_initialized(&conf->r10buf_pool))
+- if (init_resync(conf))
+- return 0;
+-
+ /*
+ * Allow skipping a full rebuild for incremental assembly
+ * of a clean array, like RAID1 does.
+@@ -3308,6 +3317,10 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
+ return mddev->dev_sectors - sector_nr;
+ }
+
++ if (!mempool_initialized(&conf->r10buf_pool))
++ if (init_resync(conf))
++ return 0;
++
+ skipped:
+ max_sector = mddev->dev_sectors;
+ if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) ||
+@@ -4004,6 +4017,20 @@ static int setup_geo(struct geom *geo, struct mddev *mddev, enum geo_type new)
+ return nc*fc;
+ }
+
++static void raid10_free_conf(struct r10conf *conf)
++{
++ if (!conf)
++ return;
++
++ mempool_exit(&conf->r10bio_pool);
++ kfree(conf->mirrors);
++ kfree(conf->mirrors_old);
++ kfree(conf->mirrors_new);
++ safe_put_page(conf->tmppage);
++ bioset_exit(&conf->bio_split);
++ kfree(conf);
++}
++
+ static struct r10conf *setup_conf(struct mddev *mddev)
+ {
+ struct r10conf *conf = NULL;
+@@ -4086,13 +4113,7 @@ static struct r10conf *setup_conf(struct mddev *mddev)
+ return conf;
+
+ out:
+- if (conf) {
+- mempool_exit(&conf->r10bio_pool);
+- kfree(conf->mirrors);
+- safe_put_page(conf->tmppage);
+- bioset_exit(&conf->bio_split);
+- kfree(conf);
+- }
++ raid10_free_conf(conf);
+ return ERR_PTR(err);
+ }
+
+@@ -4129,6 +4150,9 @@ static int raid10_run(struct mddev *mddev)
+ if (!conf)
+ goto out;
+
++ mddev->thread = conf->thread;
++ conf->thread = NULL;
++
+ if (mddev_is_clustered(conf->mddev)) {
+ int fc, fo;
+
+@@ -4141,9 +4165,6 @@ static int raid10_run(struct mddev *mddev)
+ }
+ }
+
+- mddev->thread = conf->thread;
+- conf->thread = NULL;
+-
+ if (mddev->queue) {
+ blk_queue_max_write_zeroes_sectors(mddev->queue, 0);
+ blk_queue_io_min(mddev->queue, mddev->chunk_sectors << 9);
+@@ -4283,10 +4304,7 @@ static int raid10_run(struct mddev *mddev)
+
+ out_free_conf:
+ md_unregister_thread(&mddev->thread);
+- mempool_exit(&conf->r10bio_pool);
+- safe_put_page(conf->tmppage);
+- kfree(conf->mirrors);
+- kfree(conf);
++ raid10_free_conf(conf);
+ mddev->private = NULL;
+ out:
+ return -EIO;
+@@ -4294,15 +4312,7 @@ out:
+
+ static void raid10_free(struct mddev *mddev, void *priv)
+ {
+- struct r10conf *conf = priv;
+-
+- mempool_exit(&conf->r10bio_pool);
+- safe_put_page(conf->tmppage);
+- kfree(conf->mirrors);
+- kfree(conf->mirrors_old);
+- kfree(conf->mirrors_new);
+- bioset_exit(&conf->bio_split);
+- kfree(conf);
++ raid10_free_conf(priv);
+ }
+
+ static void raid10_quiesce(struct mddev *mddev, int quiesce)
+diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
+index 7b820b81d8c2b..f787c9e5b10e7 100644
+--- a/drivers/md/raid5.c
++++ b/drivers/md/raid5.c
+@@ -6079,6 +6079,38 @@ out_release:
+ return ret;
+ }
+
++/*
++ * If the bio covers multiple data disks, find sector within the bio that has
++ * the lowest chunk offset in the first chunk.
++ */
++static sector_t raid5_bio_lowest_chunk_sector(struct r5conf *conf,
++ struct bio *bi)
++{
++ int sectors_per_chunk = conf->chunk_sectors;
++ int raid_disks = conf->raid_disks;
++ int dd_idx;
++ struct stripe_head sh;
++ unsigned int chunk_offset;
++ sector_t r_sector = bi->bi_iter.bi_sector & ~((sector_t)RAID5_STRIPE_SECTORS(conf)-1);
++ sector_t sector;
++
++ /* We pass in fake stripe_head to get back parity disk numbers */
++ sector = raid5_compute_sector(conf, r_sector, 0, &dd_idx, &sh);
++ chunk_offset = sector_div(sector, sectors_per_chunk);
++ if (sectors_per_chunk - chunk_offset >= bio_sectors(bi))
++ return r_sector;
++ /*
++ * Bio crosses to the next data disk. Check whether it's in the same
++ * chunk.
++ */
++ dd_idx++;
++ while (dd_idx == sh.pd_idx || dd_idx == sh.qd_idx)
++ dd_idx++;
++ if (dd_idx >= raid_disks)
++ return r_sector;
++ return r_sector + sectors_per_chunk - chunk_offset;
++}
++
+ static bool raid5_make_request(struct mddev *mddev, struct bio * bi)
+ {
+ DEFINE_WAIT_FUNC(wait, woken_wake_function);
+@@ -6150,6 +6182,17 @@ static bool raid5_make_request(struct mddev *mddev, struct bio * bi)
+ }
+ md_account_bio(mddev, &bi);
+
++ /*
++ * Lets start with the stripe with the lowest chunk offset in the first
++ * chunk. That has the best chances of creating IOs adjacent to
++ * previous IOs in case of sequential IO and thus creates the most
++ * sequential IO pattern. We don't bother with the optimization when
++ * reshaping as the performance benefit is not worth the complexity.
++ */
++ if (likely(conf->reshape_progress == MaxSector))
++ logical_sector = raid5_bio_lowest_chunk_sector(conf, bi);
++ s = (logical_sector - ctx.first_sector) >> RAID5_STRIPE_SHIFT(conf);
++
+ add_wait_queue(&conf->wait_for_overlap, &wait);
+ while (1) {
+ res = make_stripe_request(mddev, conf, &ctx, logical_sector,
+@@ -6178,7 +6221,7 @@ static bool raid5_make_request(struct mddev *mddev, struct bio * bi)
+ continue;
+ }
+
+- s = find_first_bit(ctx.sectors_to_do, stripe_cnt);
++ s = find_next_bit_wrap(ctx.sectors_to_do, stripe_cnt, s);
+ if (s == stripe_cnt)
+ break;
+
+diff --git a/drivers/media/i2c/hi846.c b/drivers/media/i2c/hi846.c
+index 7c61873b71981..306dc35e925fd 100644
+--- a/drivers/media/i2c/hi846.c
++++ b/drivers/media/i2c/hi846.c
+@@ -1472,21 +1472,26 @@ static int hi846_init_controls(struct hi846 *hi846)
+ if (ctrl_hdlr->error) {
+ dev_err(&client->dev, "v4l ctrl handler error: %d\n",
+ ctrl_hdlr->error);
+- return ctrl_hdlr->error;
++ ret = ctrl_hdlr->error;
++ goto error;
+ }
+
+ ret = v4l2_fwnode_device_parse(&client->dev, &props);
+ if (ret)
+- return ret;
++ goto error;
+
+ ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &hi846_ctrl_ops,
+ &props);
+ if (ret)
+- return ret;
++ goto error;
+
+ hi846->sd.ctrl_handler = ctrl_hdlr;
+
+ return 0;
++
++error:
++ v4l2_ctrl_handler_free(ctrl_hdlr);
++ return ret;
+ }
+
+ static int hi846_set_video_mode(struct hi846 *hi846, int fps)
+diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
+index d034a67042e35..892cd97b7cab7 100644
+--- a/drivers/media/i2c/max9286.c
++++ b/drivers/media/i2c/max9286.c
+@@ -941,6 +941,7 @@ err_async:
+ static void max9286_v4l2_unregister(struct max9286_priv *priv)
+ {
+ fwnode_handle_put(priv->sd.fwnode);
++ v4l2_ctrl_handler_free(&priv->ctrls);
+ v4l2_async_unregister_subdev(&priv->sd);
+ max9286_v4l2_notifier_unregister(priv);
+ }
+diff --git a/drivers/media/i2c/ov8856.c b/drivers/media/i2c/ov8856.c
+index cf8384e09413b..b5c7881383ca7 100644
+--- a/drivers/media/i2c/ov8856.c
++++ b/drivers/media/i2c/ov8856.c
+@@ -1709,46 +1709,6 @@ static int ov8856_identify_module(struct ov8856 *ov8856)
+ return -ENXIO;
+ }
+
+- ret = ov8856_write_reg(ov8856, OV8856_REG_MODE_SELECT,
+- OV8856_REG_VALUE_08BIT, OV8856_MODE_STREAMING);
+- if (ret)
+- return ret;
+-
+- ret = ov8856_write_reg(ov8856, OV8856_OTP_MODE_CTRL,
+- OV8856_REG_VALUE_08BIT, OV8856_OTP_MODE_AUTO);
+- if (ret) {
+- dev_err(&client->dev, "failed to set otp mode");
+- return ret;
+- }
+-
+- ret = ov8856_write_reg(ov8856, OV8856_OTP_LOAD_CTRL,
+- OV8856_REG_VALUE_08BIT,
+- OV8856_OTP_LOAD_CTRL_ENABLE);
+- if (ret) {
+- dev_err(&client->dev, "failed to enable load control");
+- return ret;
+- }
+-
+- ret = ov8856_read_reg(ov8856, OV8856_MODULE_REVISION,
+- OV8856_REG_VALUE_08BIT, &val);
+- if (ret) {
+- dev_err(&client->dev, "failed to read module revision");
+- return ret;
+- }
+-
+- dev_info(&client->dev, "OV8856 revision %x (%s) at address 0x%02x\n",
+- val,
+- val == OV8856_2A_MODULE ? "2A" :
+- val == OV8856_1B_MODULE ? "1B" : "unknown revision",
+- client->addr);
+-
+- ret = ov8856_write_reg(ov8856, OV8856_REG_MODE_SELECT,
+- OV8856_REG_VALUE_08BIT, OV8856_MODE_STANDBY);
+- if (ret) {
+- dev_err(&client->dev, "failed to exit streaming mode");
+- return ret;
+- }
+-
+ ov8856->identified = true;
+
+ return 0;
+diff --git a/drivers/media/pci/dm1105/dm1105.c b/drivers/media/pci/dm1105/dm1105.c
+index 4ac645a56c14e..9e9c7c071accc 100644
+--- a/drivers/media/pci/dm1105/dm1105.c
++++ b/drivers/media/pci/dm1105/dm1105.c
+@@ -1176,6 +1176,7 @@ static void dm1105_remove(struct pci_dev *pdev)
+ struct dvb_demux *dvbdemux = &dev->demux;
+ struct dmx_demux *dmx = &dvbdemux->dmx;
+
++ cancel_work_sync(&dev->ir.work);
+ dm1105_ir_exit(dev);
+ dmx->close(dmx);
+ dvb_net_release(&dev->dvbnet);
+diff --git a/drivers/media/pci/saa7134/saa7134-ts.c b/drivers/media/pci/saa7134/saa7134-ts.c
+index 6a5053126237f..437dbe5e75e29 100644
+--- a/drivers/media/pci/saa7134/saa7134-ts.c
++++ b/drivers/media/pci/saa7134/saa7134-ts.c
+@@ -300,6 +300,7 @@ int saa7134_ts_start(struct saa7134_dev *dev)
+
+ int saa7134_ts_fini(struct saa7134_dev *dev)
+ {
++ del_timer_sync(&dev->ts_q.timeout);
+ saa7134_pgtable_free(dev->pci, &dev->ts_q.pt);
+ return 0;
+ }
+diff --git a/drivers/media/pci/saa7134/saa7134-vbi.c b/drivers/media/pci/saa7134/saa7134-vbi.c
+index 3f0b0933eed69..3e773690468bd 100644
+--- a/drivers/media/pci/saa7134/saa7134-vbi.c
++++ b/drivers/media/pci/saa7134/saa7134-vbi.c
+@@ -185,6 +185,7 @@ int saa7134_vbi_init1(struct saa7134_dev *dev)
+ int saa7134_vbi_fini(struct saa7134_dev *dev)
+ {
+ /* nothing */
++ del_timer_sync(&dev->vbi_q.timeout);
+ return 0;
+ }
+
+diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c
+index 4d8974c9fcc98..29124756a62bc 100644
+--- a/drivers/media/pci/saa7134/saa7134-video.c
++++ b/drivers/media/pci/saa7134/saa7134-video.c
+@@ -2146,6 +2146,7 @@ int saa7134_video_init1(struct saa7134_dev *dev)
+
+ void saa7134_video_fini(struct saa7134_dev *dev)
+ {
++ del_timer_sync(&dev->video_q.timeout);
+ /* free stuff */
+ saa7134_pgtable_free(dev->pci, &dev->video_q.pt);
+ saa7134_pgtable_free(dev->pci, &dev->vbi_q.pt);
+diff --git a/drivers/media/platform/amphion/vdec.c b/drivers/media/platform/amphion/vdec.c
+index 87f9f8e90ab13..70633530d23a1 100644
+--- a/drivers/media/platform/amphion/vdec.c
++++ b/drivers/media/platform/amphion/vdec.c
+@@ -168,7 +168,31 @@ static const struct vpu_format vdec_formats[] = {
+ {0, 0, 0, 0},
+ };
+
++static int vdec_op_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct vpu_inst *inst = ctrl_to_inst(ctrl);
++ struct vdec_t *vdec = inst->priv;
++ int ret = 0;
++
++ vpu_inst_lock(inst);
++ switch (ctrl->id) {
++ case V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY_ENABLE:
++ vdec->params.display_delay_enable = ctrl->val;
++ break;
++ case V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY:
++ vdec->params.display_delay = ctrl->val;
++ break;
++ default:
++ ret = -EINVAL;
++ break;
++ }
++ vpu_inst_unlock(inst);
++
++ return ret;
++}
++
+ static const struct v4l2_ctrl_ops vdec_ctrl_ops = {
++ .s_ctrl = vdec_op_s_ctrl,
+ .g_volatile_ctrl = vpu_helper_g_volatile_ctrl,
+ };
+
+@@ -181,6 +205,14 @@ static int vdec_ctrl_init(struct vpu_inst *inst)
+ if (ret)
+ return ret;
+
++ v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops,
++ V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY,
++ 0, 0, 1, 0);
++
++ v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops,
++ V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY_ENABLE,
++ 0, 1, 1, 0);
++
+ ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops,
+ V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 2);
+ if (ctrl)
+diff --git a/drivers/media/platform/amphion/vpu_codec.h b/drivers/media/platform/amphion/vpu_codec.h
+index 528a93f08ecd4..bac6d0d94f8a5 100644
+--- a/drivers/media/platform/amphion/vpu_codec.h
++++ b/drivers/media/platform/amphion/vpu_codec.h
+@@ -55,7 +55,8 @@ struct vpu_encode_params {
+ struct vpu_decode_params {
+ u32 codec_format;
+ u32 output_format;
+- u32 b_dis_reorder;
++ u32 display_delay_enable;
++ u32 display_delay;
+ u32 b_non_frame;
+ u32 frame_count;
+ u32 end_flag;
+diff --git a/drivers/media/platform/amphion/vpu_malone.c b/drivers/media/platform/amphion/vpu_malone.c
+index 2c9bfc6a5a72e..feb5c25e31044 100644
+--- a/drivers/media/platform/amphion/vpu_malone.c
++++ b/drivers/media/platform/amphion/vpu_malone.c
+@@ -641,7 +641,9 @@ static int vpu_malone_set_params(struct vpu_shared_addr *shared,
+ hc->jpg[instance].jpg_mjpeg_interlaced = 0;
+ }
+
+- hc->codec_param[instance].disp_imm = params->b_dis_reorder ? 1 : 0;
++ hc->codec_param[instance].disp_imm = params->display_delay_enable ? 1 : 0;
++ if (malone_format != MALONE_FMT_AVC)
++ hc->codec_param[instance].disp_imm = 0;
+ hc->codec_param[instance].dbglog_enable = 0;
+ iface->dbglog_desc.level = 0;
+
+diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
+index 969516a940ba7..d9584fe5033eb 100644
+--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
++++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
+@@ -1025,9 +1025,6 @@ retry_select:
+ if (!dst_buf)
+ goto getbuf_fail;
+
+- v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+- v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
+-
+ v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, true);
+
+ mtk_jpegenc_set_hw_param(ctx, hw_id, src_buf, dst_buf);
+@@ -1045,6 +1042,9 @@ retry_select:
+ goto enc_end;
+ }
+
++ v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
++ v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
++
+ schedule_delayed_work(&comp_jpeg[hw_id]->job_timeout_work,
+ msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC));
+
+@@ -1220,9 +1220,6 @@ retry_select:
+ if (!dst_buf)
+ goto getbuf_fail;
+
+- v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+- v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
+-
+ v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, true);
+ jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(&src_buf->vb2_buf);
+ jpeg_dst_buf = mtk_jpeg_vb2_to_srcbuf(&dst_buf->vb2_buf);
+@@ -1231,7 +1228,7 @@ retry_select:
+ &jpeg_src_buf->dec_param)) {
+ mtk_jpeg_queue_src_chg_event(ctx);
+ ctx->state = MTK_JPEG_SOURCE_CHANGE;
+- goto dec_end;
++ goto getbuf_fail;
+ }
+
+ jpeg_src_buf->curr_ctx = ctx;
+@@ -1254,6 +1251,9 @@ retry_select:
+ goto clk_end;
+ }
+
++ v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
++ v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
++
+ schedule_delayed_work(&comp_jpeg[hw_id]->job_timeout_work,
+ msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC));
+
+@@ -1692,7 +1692,7 @@ static int mtk_jpeg_probe(struct platform_device *pdev)
+ return -EINVAL;
+ }
+
+- if (list_empty(&pdev->dev.devres_head)) {
++ if (!jpeg->variant->multi_core) {
+ INIT_DELAYED_WORK(&jpeg->job_timeout_work,
+ mtk_jpeg_job_timeout_work);
+
+@@ -1874,6 +1874,7 @@ static const struct mtk_jpeg_variant mtk_jpeg_drvdata = {
+ .ioctl_ops = &mtk_jpeg_enc_ioctl_ops,
+ .out_q_default_fourcc = V4L2_PIX_FMT_YUYV,
+ .cap_q_default_fourcc = V4L2_PIX_FMT_JPEG,
++ .multi_core = false,
+ };
+
+ static struct mtk_jpeg_variant mtk8195_jpegenc_drvdata = {
+@@ -1885,6 +1886,7 @@ static struct mtk_jpeg_variant mtk8195_jpegenc_drvdata = {
+ .ioctl_ops = &mtk_jpeg_enc_ioctl_ops,
+ .out_q_default_fourcc = V4L2_PIX_FMT_YUYV,
+ .cap_q_default_fourcc = V4L2_PIX_FMT_JPEG,
++ .multi_core = true,
+ };
+
+ static const struct mtk_jpeg_variant mtk8195_jpegdec_drvdata = {
+@@ -1896,6 +1898,7 @@ static const struct mtk_jpeg_variant mtk8195_jpegdec_drvdata = {
+ .ioctl_ops = &mtk_jpeg_dec_ioctl_ops,
+ .out_q_default_fourcc = V4L2_PIX_FMT_JPEG,
+ .cap_q_default_fourcc = V4L2_PIX_FMT_YUV420M,
++ .multi_core = true,
+ };
+
+ #if defined(CONFIG_OF)
+diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h
+index b9126476be8fa..f87358cc9f47f 100644
+--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h
++++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h
+@@ -60,6 +60,7 @@ enum mtk_jpeg_ctx_state {
+ * @ioctl_ops: the callback of jpeg v4l2_ioctl_ops
+ * @out_q_default_fourcc: output queue default fourcc
+ * @cap_q_default_fourcc: capture queue default fourcc
++ * @multi_core: mark jpeg hw is multi_core or not
+ */
+ struct mtk_jpeg_variant {
+ struct clk_bulk_data *clks;
+@@ -74,6 +75,7 @@ struct mtk_jpeg_variant {
+ const struct v4l2_ioctl_ops *ioctl_ops;
+ u32 out_q_default_fourcc;
+ u32 cap_q_default_fourcc;
++ bool multi_core;
+ };
+
+ struct mtk_jpeg_src_buf {
+diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c
+index 1bbb712d78d0e..867f4c1a09fa6 100644
+--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c
++++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c
+@@ -286,10 +286,6 @@ static irqreturn_t mtk_jpegenc_hw_irq_handler(int irq, void *priv)
+ mtk_jpegenc_put_buf(jpeg);
+ pm_runtime_put(ctx->jpeg->dev);
+ clk_disable_unprepare(jpeg->venc_clk.clks->clk);
+- if (!list_empty(&ctx->fh.m2m_ctx->out_q_ctx.rdy_queue) ||
+- !list_empty(&ctx->fh.m2m_ctx->cap_q_ctx.rdy_queue)) {
+- queue_work(master_jpeg->workqueue, &ctx->jpeg_work);
+- }
+
+ jpeg->hw_state = MTK_JPEG_HW_IDLE;
+ wake_up(&master_jpeg->enc_hw_wq);
+diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-m2m.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-m2m.c
+index 5f74ea3b7a524..8612a48bde10f 100644
+--- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-m2m.c
++++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-m2m.c
+@@ -566,7 +566,11 @@ static int mdp_m2m_open(struct file *file)
+ goto err_free_ctx;
+ }
+
+- ctx->id = ida_alloc(&mdp->mdp_ida, GFP_KERNEL);
++ ret = ida_alloc(&mdp->mdp_ida, GFP_KERNEL);
++ if (ret < 0)
++ goto err_unlock_mutex;
++ ctx->id = ret;
++
+ ctx->mdp_dev = mdp;
+
+ v4l2_fh_init(&ctx->fh, vdev);
+@@ -617,6 +621,8 @@ err_release_handler:
+ v4l2_fh_del(&ctx->fh);
+ err_exit_fh:
+ v4l2_fh_exit(&ctx->fh);
++ ida_free(&mdp->mdp_ida, ctx->id);
++err_unlock_mutex:
+ mutex_unlock(&mdp->m2m_lock);
+ err_free_ctx:
+ kfree(ctx);
+diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-regs.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-regs.c
+index 4e84a37ecdfc1..36336d169bd91 100644
+--- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-regs.c
++++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-regs.c
+@@ -4,6 +4,7 @@
+ * Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
+ */
+
++#include <linux/math64.h>
+ #include <media/v4l2-common.h>
+ #include <media/videobuf2-v4l2.h>
+ #include <media/videobuf2-dma-contig.h>
+@@ -428,14 +429,15 @@ const struct mdp_format *mdp_try_fmt_mplane(struct v4l2_format *f,
+ u32 bpl = pix_mp->plane_fmt[i].bytesperline;
+ u32 min_si, max_si;
+ u32 si = pix_mp->plane_fmt[i].sizeimage;
++ u64 di;
+
+ bpl = clamp(bpl, min_bpl, max_bpl);
+ pix_mp->plane_fmt[i].bytesperline = bpl;
+
+- min_si = (bpl * pix_mp->height * fmt->depth[i]) /
+- fmt->row_depth[i];
+- max_si = (bpl * s.max_height * fmt->depth[i]) /
+- fmt->row_depth[i];
++ di = (u64)bpl * pix_mp->height * fmt->depth[i];
++ min_si = (u32)div_u64(di, fmt->row_depth[i]);
++ di = (u64)bpl * s.max_height * fmt->depth[i];
++ max_si = (u32)div_u64(di, fmt->row_depth[i]);
+
+ si = clamp(si, min_si, max_si);
+ pix_mp->plane_fmt[i].sizeimage = si;
+diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c
+index 641f533c417fd..c99705681a03e 100644
+--- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c
++++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c
+@@ -39,10 +39,9 @@ static bool mtk_vdec_get_cap_fmt(struct mtk_vcodec_ctx *ctx, int format_index)
+ {
+ const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
+ const struct mtk_video_fmt *fmt;
+- struct mtk_q_data *q_data;
+ int num_frame_count = 0, i;
+- bool ret = true;
+
++ fmt = &dec_pdata->vdec_formats[format_index];
+ for (i = 0; i < *dec_pdata->num_formats; i++) {
+ if (dec_pdata->vdec_formats[i].type != MTK_FMT_FRAME)
+ continue;
+@@ -50,27 +49,10 @@ static bool mtk_vdec_get_cap_fmt(struct mtk_vcodec_ctx *ctx, int format_index)
+ num_frame_count++;
+ }
+
+- if (num_frame_count == 1)
++ if (num_frame_count == 1 || fmt->fourcc == V4L2_PIX_FMT_MM21)
+ return true;
+
+- fmt = &dec_pdata->vdec_formats[format_index];
+- q_data = &ctx->q_data[MTK_Q_DATA_SRC];
+- switch (q_data->fmt->fourcc) {
+- case V4L2_PIX_FMT_VP8_FRAME:
+- if (fmt->fourcc == V4L2_PIX_FMT_MM21)
+- ret = true;
+- break;
+- case V4L2_PIX_FMT_H264_SLICE:
+- case V4L2_PIX_FMT_VP9_FRAME:
+- if (fmt->fourcc == V4L2_PIX_FMT_MM21)
+- ret = false;
+- break;
+- default:
+- ret = true;
+- break;
+- }
+-
+- return ret;
++ return false;
+ }
+
+ static struct mtk_q_data *mtk_vdec_get_q_data(struct mtk_vcodec_ctx *ctx,
+diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c
+index 174a6eec2f549..42df901e8beb4 100644
+--- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c
++++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c
+@@ -451,7 +451,8 @@ err_core_workq:
+ if (IS_VDEC_LAT_ARCH(dev->vdec_pdata->hw_arch))
+ destroy_workqueue(dev->core_workqueue);
+ err_res:
+- pm_runtime_disable(dev->pm.dev);
++ if (!dev->vdec_pdata->is_subdev_supported)
++ pm_runtime_disable(dev->pm.dev);
+ err_dec_pm:
+ mtk_vcodec_fw_release(dev->fw_handler);
+ return ret;
+diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_hw.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_hw.c
+index 376db0e433d75..b753bf54ebd90 100644
+--- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_hw.c
++++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_hw.c
+@@ -193,8 +193,16 @@ err:
+ return ret;
+ }
+
++static int mtk_vdec_hw_remove(struct platform_device *pdev)
++{
++ pm_runtime_disable(&pdev->dev);
++
++ return 0;
++}
++
+ static struct platform_driver mtk_vdec_driver = {
+ .probe = mtk_vdec_hw_probe,
++ .remove = mtk_vdec_hw_remove,
+ .driver = {
+ .name = "mtk-vdec-comp",
+ .of_match_table = mtk_vdec_hw_match,
+diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateful.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateful.c
+index 035c86e7809fd..29991551cf614 100644
+--- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateful.c
++++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateful.c
+@@ -11,7 +11,7 @@
+ #include "mtk_vcodec_dec_pm.h"
+ #include "vdec_drv_if.h"
+
+-static const struct mtk_video_fmt mtk_video_formats[] = {
++static struct mtk_video_fmt mtk_video_formats[] = {
+ {
+ .fourcc = V4L2_PIX_FMT_H264,
+ .type = MTK_FMT_DEC,
+@@ -580,6 +580,16 @@ static int mtk_vcodec_dec_ctrls_setup(struct mtk_vcodec_ctx *ctx)
+
+ static void mtk_init_vdec_params(struct mtk_vcodec_ctx *ctx)
+ {
++ unsigned int i;
++
++ if (!(ctx->dev->dec_capability & VCODEC_CAPABILITY_4K_DISABLED)) {
++ for (i = 0; i < num_supported_formats; i++) {
++ mtk_video_formats[i].frmsize.max_width =
++ VCODEC_DEC_4K_CODED_WIDTH;
++ mtk_video_formats[i].frmsize.max_height =
++ VCODEC_DEC_4K_CODED_HEIGHT;
++ }
++ }
+ }
+
+ static struct vb2_ops mtk_vdec_frame_vb2_ops = {
+diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c
+index ffbcee04dc26f..3000db975e5f5 100644
+--- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c
++++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c
+@@ -258,8 +258,10 @@ static void mtk_vdec_worker(struct work_struct *work)
+ if (src_buf_req)
+ v4l2_ctrl_request_complete(src_buf_req, &ctx->ctrl_hdl);
+ } else {
+- v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
+- v4l2_m2m_buf_done(vb2_v4l2_src, state);
++ if (ret != -EAGAIN) {
++ v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
++ v4l2_m2m_buf_done(vb2_v4l2_src, state);
++ }
+ v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
+ }
+ }
+@@ -390,14 +392,14 @@ static void mtk_vcodec_get_supported_formats(struct mtk_vcodec_ctx *ctx)
+ if (num_formats)
+ return;
+
+- if (ctx->dev->dec_capability & MTK_VDEC_FORMAT_MM21) {
+- mtk_vcodec_add_formats(V4L2_PIX_FMT_MM21, ctx);
+- cap_format_count++;
+- }
+ if (ctx->dev->dec_capability & MTK_VDEC_FORMAT_MT21C) {
+ mtk_vcodec_add_formats(V4L2_PIX_FMT_MT21C, ctx);
+ cap_format_count++;
+ }
++ if (ctx->dev->dec_capability & MTK_VDEC_FORMAT_MM21) {
++ mtk_vcodec_add_formats(V4L2_PIX_FMT_MM21, ctx);
++ cap_format_count++;
++ }
+ if (ctx->dev->dec_capability & MTK_VDEC_FORMAT_H264_SLICE) {
+ mtk_vcodec_add_formats(V4L2_PIX_FMT_H264_SLICE, ctx);
+ out_format_count++;
+diff --git a/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_multi_if.c b/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_multi_if.c
+index 955b2d0c8f53f..999ce7ee5fdc2 100644
+--- a/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_multi_if.c
++++ b/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_multi_if.c
+@@ -597,7 +597,7 @@ static int vdec_h264_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
+ lat_buf = vdec_msg_queue_dqbuf(&inst->ctx->msg_queue.lat_ctx);
+ if (!lat_buf) {
+ mtk_vcodec_err(inst, "failed to get lat buffer");
+- return -EINVAL;
++ return -EAGAIN;
+ }
+ share_info = lat_buf->private_data;
+ src_buf_info = container_of(bs, struct mtk_video_dec_buf, bs_buffer);
+diff --git a/drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_req_lat_if.c b/drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_req_lat_if.c
+index cbb6728b8a40b..cf16cf2807f07 100644
+--- a/drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_req_lat_if.c
++++ b/drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_req_lat_if.c
+@@ -2070,7 +2070,7 @@ static int vdec_vp9_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
+ lat_buf = vdec_msg_queue_dqbuf(&instance->ctx->msg_queue.lat_ctx);
+ if (!lat_buf) {
+ mtk_vcodec_err(instance, "Failed to get VP9 lat buf\n");
+- return -EBUSY;
++ return -EAGAIN;
+ }
+ pfc = (struct vdec_vp9_slice_pfc *)lat_buf->private_data;
+ if (!pfc) {
+diff --git a/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c b/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c
+index dc2004790a472..f3073d1e7f420 100644
+--- a/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c
++++ b/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c
+@@ -52,9 +52,26 @@ static struct list_head *vdec_get_buf_list(int hardware_index, struct vdec_lat_b
+ }
+ }
+
++static void vdec_msg_queue_inc(struct vdec_msg_queue *msg_queue, int hardware_index)
++{
++ if (hardware_index == MTK_VDEC_CORE)
++ atomic_inc(&msg_queue->core_list_cnt);
++ else
++ atomic_inc(&msg_queue->lat_list_cnt);
++}
++
++static void vdec_msg_queue_dec(struct vdec_msg_queue *msg_queue, int hardware_index)
++{
++ if (hardware_index == MTK_VDEC_CORE)
++ atomic_dec(&msg_queue->core_list_cnt);
++ else
++ atomic_dec(&msg_queue->lat_list_cnt);
++}
++
+ int vdec_msg_queue_qbuf(struct vdec_msg_queue_ctx *msg_ctx, struct vdec_lat_buf *buf)
+ {
+ struct list_head *head;
++ int status;
+
+ head = vdec_get_buf_list(msg_ctx->hardware_index, buf);
+ if (!head) {
+@@ -66,11 +83,18 @@ int vdec_msg_queue_qbuf(struct vdec_msg_queue_ctx *msg_ctx, struct vdec_lat_buf
+ list_add_tail(head, &msg_ctx->ready_queue);
+ msg_ctx->ready_num++;
+
+- if (msg_ctx->hardware_index != MTK_VDEC_CORE)
++ vdec_msg_queue_inc(&buf->ctx->msg_queue, msg_ctx->hardware_index);
++ if (msg_ctx->hardware_index != MTK_VDEC_CORE) {
+ wake_up_all(&msg_ctx->ready_to_use);
+- else
+- queue_work(buf->ctx->dev->core_workqueue,
+- &buf->ctx->msg_queue.core_work);
++ } else {
++ if (buf->ctx->msg_queue.core_work_cnt <
++ atomic_read(&buf->ctx->msg_queue.core_list_cnt)) {
++ status = queue_work(buf->ctx->dev->core_workqueue,
++ &buf->ctx->msg_queue.core_work);
++ if (status)
++ buf->ctx->msg_queue.core_work_cnt++;
++ }
++ }
+
+ mtk_v4l2_debug(3, "enqueue buf type: %d addr: 0x%p num: %d",
+ msg_ctx->hardware_index, buf, msg_ctx->ready_num);
+@@ -127,6 +151,7 @@ struct vdec_lat_buf *vdec_msg_queue_dqbuf(struct vdec_msg_queue_ctx *msg_ctx)
+ return NULL;
+ }
+ list_del(head);
++ vdec_msg_queue_dec(&buf->ctx->msg_queue, msg_ctx->hardware_index);
+
+ msg_ctx->ready_num--;
+ mtk_v4l2_debug(3, "dqueue buf type:%d addr: 0x%p num: %d",
+@@ -156,11 +181,29 @@ void vdec_msg_queue_update_ube_wptr(struct vdec_msg_queue *msg_queue, uint64_t u
+
+ bool vdec_msg_queue_wait_lat_buf_full(struct vdec_msg_queue *msg_queue)
+ {
++ struct vdec_lat_buf *buf, *tmp;
++ struct list_head *list_core[3];
++ struct vdec_msg_queue_ctx *core_ctx;
++ int ret, i, in_core_count = 0, count = 0;
+ long timeout_jiff;
+- int ret;
++
++ core_ctx = &msg_queue->ctx->dev->msg_queue_core_ctx;
++ spin_lock(&core_ctx->ready_lock);
++ list_for_each_entry_safe(buf, tmp, &core_ctx->ready_queue, core_list) {
++ if (buf && buf->ctx == msg_queue->ctx) {
++ list_core[in_core_count++] = &buf->core_list;
++ list_del(&buf->core_list);
++ }
++ }
++
++ for (i = 0; i < in_core_count; i++) {
++ list_add(list_core[in_core_count - (1 + i)], &core_ctx->ready_queue);
++ queue_work(msg_queue->ctx->dev->core_workqueue, &msg_queue->core_work);
++ }
++ spin_unlock(&core_ctx->ready_lock);
+
+ timeout_jiff = msecs_to_jiffies(1000 * (NUM_BUFFER_COUNT + 2));
+- ret = wait_event_timeout(msg_queue->lat_ctx.ready_to_use,
++ ret = wait_event_timeout(msg_queue->ctx->msg_queue.core_dec_done,
+ msg_queue->lat_ctx.ready_num == NUM_BUFFER_COUNT,
+ timeout_jiff);
+ if (ret) {
+@@ -168,8 +211,20 @@ bool vdec_msg_queue_wait_lat_buf_full(struct vdec_msg_queue *msg_queue)
+ msg_queue->lat_ctx.ready_num);
+ return true;
+ }
+- mtk_v4l2_err("failed with lat buf isn't full: %d",
+- msg_queue->lat_ctx.ready_num);
++
++ spin_lock(&core_ctx->ready_lock);
++ list_for_each_entry_safe(buf, tmp, &core_ctx->ready_queue, core_list) {
++ if (buf && buf->ctx == msg_queue->ctx) {
++ count++;
++ list_del(&buf->core_list);
++ }
++ }
++ spin_unlock(&core_ctx->ready_lock);
++
++ mtk_v4l2_err("failed with lat buf isn't full: list(%d %d) count:%d",
++ atomic_read(&msg_queue->lat_list_cnt),
++ atomic_read(&msg_queue->core_list_cnt), count);
++
+ return false;
+ }
+
+@@ -206,6 +261,7 @@ static void vdec_msg_queue_core_work(struct work_struct *work)
+ container_of(msg_queue, struct mtk_vcodec_ctx, msg_queue);
+ struct mtk_vcodec_dev *dev = ctx->dev;
+ struct vdec_lat_buf *lat_buf;
++ int status;
+
+ lat_buf = vdec_msg_queue_dqbuf(&dev->msg_queue_core_ctx);
+ if (!lat_buf)
+@@ -221,11 +277,18 @@ static void vdec_msg_queue_core_work(struct work_struct *work)
+ mtk_vcodec_dec_disable_hardware(ctx, MTK_VDEC_CORE);
+ vdec_msg_queue_qbuf(&ctx->msg_queue.lat_ctx, lat_buf);
+
+- if (!list_empty(&dev->msg_queue_core_ctx.ready_queue)) {
+- mtk_v4l2_debug(3, "re-schedule to decode for core: %d",
+- dev->msg_queue_core_ctx.ready_num);
+- queue_work(dev->core_workqueue, &msg_queue->core_work);
++ wake_up_all(&ctx->msg_queue.core_dec_done);
++ spin_lock(&dev->msg_queue_core_ctx.ready_lock);
++ lat_buf->ctx->msg_queue.core_work_cnt--;
++
++ if (lat_buf->ctx->msg_queue.core_work_cnt <
++ atomic_read(&lat_buf->ctx->msg_queue.core_list_cnt)) {
++ status = queue_work(lat_buf->ctx->dev->core_workqueue,
++ &lat_buf->ctx->msg_queue.core_work);
++ if (status)
++ lat_buf->ctx->msg_queue.core_work_cnt++;
+ }
++ spin_unlock(&dev->msg_queue_core_ctx.ready_lock);
+ }
+
+ int vdec_msg_queue_init(struct vdec_msg_queue *msg_queue,
+@@ -239,12 +302,18 @@ int vdec_msg_queue_init(struct vdec_msg_queue *msg_queue,
+ if (msg_queue->wdma_addr.size)
+ return 0;
+
++ msg_queue->ctx = ctx;
++ msg_queue->core_work_cnt = 0;
+ vdec_msg_queue_init_ctx(&msg_queue->lat_ctx, MTK_VDEC_LAT0);
+ INIT_WORK(&msg_queue->core_work, vdec_msg_queue_core_work);
++
++ atomic_set(&msg_queue->lat_list_cnt, 0);
++ atomic_set(&msg_queue->core_list_cnt, 0);
++ init_waitqueue_head(&msg_queue->core_dec_done);
++
+ msg_queue->wdma_addr.size =
+ vde_msg_queue_get_trans_size(ctx->picinfo.buf_w,
+ ctx->picinfo.buf_h);
+-
+ err = mtk_vcodec_mem_alloc(ctx, &msg_queue->wdma_addr);
+ if (err) {
+ mtk_v4l2_err("failed to allocate wdma_addr buf");
+diff --git a/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.h b/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.h
+index c43d427f5f544..a5d44bc97c16b 100644
+--- a/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.h
++++ b/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.h
+@@ -72,6 +72,12 @@ struct vdec_lat_buf {
+ * @wdma_wptr_addr: ube write point
+ * @core_work: core hardware work
+ * @lat_ctx: used to store lat buffer list
++ * @ctx: point to mtk_vcodec_ctx
++ *
++ * @lat_list_cnt: used to record each instance lat list count
++ * @core_list_cnt: used to record each instance core list count
++ * @core_dec_done: core work queue decode done event
++ * @core_work_cnt: the number of core work in work queue
+ */
+ struct vdec_msg_queue {
+ struct vdec_lat_buf lat_buf[NUM_BUFFER_COUNT];
+@@ -82,6 +88,12 @@ struct vdec_msg_queue {
+
+ struct work_struct core_work;
+ struct vdec_msg_queue_ctx lat_ctx;
++ struct mtk_vcodec_ctx *ctx;
++
++ atomic_t lat_list_cnt;
++ atomic_t core_list_cnt;
++ wait_queue_head_t core_dec_done;
++ int core_work_cnt;
+ };
+
+ /**
+diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c
+index 4ceaba37e2e57..1a52c2ea2da5b 100644
+--- a/drivers/media/platform/qcom/venus/vdec.c
++++ b/drivers/media/platform/qcom/venus/vdec.c
+@@ -31,15 +31,15 @@
+ */
+ static const struct venus_format vdec_formats[] = {
+ {
+- .pixfmt = V4L2_PIX_FMT_QC08C,
++ .pixfmt = V4L2_PIX_FMT_NV12,
+ .num_planes = 1,
+ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+ }, {
+- .pixfmt = V4L2_PIX_FMT_QC10C,
++ .pixfmt = V4L2_PIX_FMT_QC08C,
+ .num_planes = 1,
+ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+- },{
+- .pixfmt = V4L2_PIX_FMT_NV12,
++ }, {
++ .pixfmt = V4L2_PIX_FMT_QC10C,
+ .num_planes = 1,
+ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+ }, {
+@@ -526,6 +526,7 @@ static int
+ vdec_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *cmd)
+ {
+ struct venus_inst *inst = to_inst(file);
++ struct vb2_queue *dst_vq;
+ struct hfi_frame_data fdata = {0};
+ int ret;
+
+@@ -556,6 +557,13 @@ vdec_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *cmd)
+ inst->codec_state = VENUS_DEC_STATE_DRAIN;
+ inst->drain_active = true;
+ }
++ } else if (cmd->cmd == V4L2_DEC_CMD_START &&
++ inst->codec_state == VENUS_DEC_STATE_STOPPED) {
++ dst_vq = v4l2_m2m_get_vq(inst->fh.m2m_ctx,
++ V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
++ vb2_clear_last_buffer_dequeued(dst_vq);
++
++ inst->codec_state = VENUS_DEC_STATE_DECODING;
+ }
+
+ unlock:
+diff --git a/drivers/media/platform/renesas/rcar_fdp1.c b/drivers/media/platform/renesas/rcar_fdp1.c
+index 37ecf489d112e..c548cb01957b0 100644
+--- a/drivers/media/platform/renesas/rcar_fdp1.c
++++ b/drivers/media/platform/renesas/rcar_fdp1.c
+@@ -2313,8 +2313,10 @@ static int fdp1_probe(struct platform_device *pdev)
+
+ /* Determine our clock rate */
+ clk = clk_get(&pdev->dev, NULL);
+- if (IS_ERR(clk))
+- return PTR_ERR(clk);
++ if (IS_ERR(clk)) {
++ ret = PTR_ERR(clk);
++ goto put_dev;
++ }
+
+ fdp1->clk_rate = clk_get_rate(clk);
+ clk_put(clk);
+@@ -2323,7 +2325,7 @@ static int fdp1_probe(struct platform_device *pdev)
+ ret = v4l2_device_register(&pdev->dev, &fdp1->v4l2_dev);
+ if (ret) {
+ v4l2_err(&fdp1->v4l2_dev, "Failed to register video device\n");
+- return ret;
++ goto put_dev;
+ }
+
+ /* M2M registration */
+@@ -2393,10 +2395,12 @@ release_m2m:
+ unreg_dev:
+ v4l2_device_unregister(&fdp1->v4l2_dev);
+
++put_dev:
++ rcar_fcp_put(fdp1->fcp);
+ return ret;
+ }
+
+-static int fdp1_remove(struct platform_device *pdev)
++static void fdp1_remove(struct platform_device *pdev)
+ {
+ struct fdp1_dev *fdp1 = platform_get_drvdata(pdev);
+
+@@ -2404,8 +2408,7 @@ static int fdp1_remove(struct platform_device *pdev)
+ video_unregister_device(&fdp1->vfd);
+ v4l2_device_unregister(&fdp1->v4l2_dev);
+ pm_runtime_disable(&pdev->dev);
+-
+- return 0;
++ rcar_fcp_put(fdp1->fcp);
+ }
+
+ static int __maybe_unused fdp1_pm_runtime_suspend(struct device *dev)
+@@ -2441,7 +2444,7 @@ MODULE_DEVICE_TABLE(of, fdp1_dt_ids);
+
+ static struct platform_driver fdp1_pdrv = {
+ .probe = fdp1_probe,
+- .remove = fdp1_remove,
++ .remove_new = fdp1_remove,
+ .driver = {
+ .name = DRIVER_NAME,
+ .of_match_table = fdp1_dt_ids,
+diff --git a/drivers/media/platform/renesas/vsp1/vsp1_video.c b/drivers/media/platform/renesas/vsp1/vsp1_video.c
+index 9d24647c8f324..0cea5e5acf82b 100644
+--- a/drivers/media/platform/renesas/vsp1/vsp1_video.c
++++ b/drivers/media/platform/renesas/vsp1/vsp1_video.c
+@@ -776,7 +776,7 @@ static void vsp1_video_buffer_queue(struct vb2_buffer *vb)
+ video->rwpf->mem = buf->mem;
+ pipe->buffers_ready |= 1 << video->pipe_index;
+
+- if (vb2_is_streaming(&video->queue) &&
++ if (vb2_start_streaming_called(&video->queue) &&
+ vsp1_pipeline_ready(pipe))
+ vsp1_video_pipeline_run(pipe);
+
+diff --git a/drivers/media/platform/st/sti/bdisp/bdisp-v4l2.c b/drivers/media/platform/st/sti/bdisp/bdisp-v4l2.c
+index dd74cc43920d3..080da254b9109 100644
+--- a/drivers/media/platform/st/sti/bdisp/bdisp-v4l2.c
++++ b/drivers/media/platform/st/sti/bdisp/bdisp-v4l2.c
+@@ -1309,6 +1309,8 @@ static int bdisp_probe(struct platform_device *pdev)
+ init_waitqueue_head(&bdisp->irq_queue);
+ INIT_DELAYED_WORK(&bdisp->timeout_work, bdisp_irq_timeout);
+ bdisp->work_queue = create_workqueue(BDISP_NAME);
++ if (!bdisp->work_queue)
++ return -ENOMEM;
+
+ spin_lock_init(&bdisp->slock);
+ mutex_init(&bdisp->lock);
+diff --git a/drivers/media/rc/gpio-ir-recv.c b/drivers/media/rc/gpio-ir-recv.c
+index 8dbe780dae4e7..41ef8cdba28c4 100644
+--- a/drivers/media/rc/gpio-ir-recv.c
++++ b/drivers/media/rc/gpio-ir-recv.c
+@@ -103,6 +103,8 @@ static int gpio_ir_recv_probe(struct platform_device *pdev)
+ rcdev->map_name = RC_MAP_EMPTY;
+
+ gpio_dev->rcdev = rcdev;
++ if (of_property_read_bool(np, "wakeup-source"))
++ device_init_wakeup(dev, true);
+
+ rc = devm_rc_register_device(dev, rcdev);
+ if (rc < 0) {
+diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
+index 2f1b718a91893..008a2a3e312e0 100644
+--- a/drivers/media/v4l2-core/v4l2-async.c
++++ b/drivers/media/v4l2-core/v4l2-async.c
+@@ -414,7 +414,8 @@ static void v4l2_async_cleanup(struct v4l2_subdev *sd)
+
+ /* Unbind all sub-devices in the notifier tree. */
+ static void
+-v4l2_async_nf_unbind_all_subdevs(struct v4l2_async_notifier *notifier)
++v4l2_async_nf_unbind_all_subdevs(struct v4l2_async_notifier *notifier,
++ bool readd)
+ {
+ struct v4l2_subdev *sd, *tmp;
+
+@@ -423,9 +424,11 @@ v4l2_async_nf_unbind_all_subdevs(struct v4l2_async_notifier *notifier)
+ v4l2_async_find_subdev_notifier(sd);
+
+ if (subdev_notifier)
+- v4l2_async_nf_unbind_all_subdevs(subdev_notifier);
++ v4l2_async_nf_unbind_all_subdevs(subdev_notifier, true);
+
+ v4l2_async_nf_call_unbind(notifier, sd, sd->asd);
++ if (readd)
++ list_add_tail(&sd->asd->list, &notifier->waiting);
+ v4l2_async_cleanup(sd);
+
+ list_move(&sd->async_list, &subdev_list);
+@@ -557,7 +560,7 @@ err_unbind:
+ /*
+ * On failure, unbind all sub-devices registered through this notifier.
+ */
+- v4l2_async_nf_unbind_all_subdevs(notifier);
++ v4l2_async_nf_unbind_all_subdevs(notifier, false);
+
+ err_unlock:
+ mutex_unlock(&list_lock);
+@@ -607,7 +610,7 @@ __v4l2_async_nf_unregister(struct v4l2_async_notifier *notifier)
+ if (!notifier || (!notifier->v4l2_dev && !notifier->sd))
+ return;
+
+- v4l2_async_nf_unbind_all_subdevs(notifier);
++ v4l2_async_nf_unbind_all_subdevs(notifier, false);
+
+ notifier->sd = NULL;
+ notifier->v4l2_dev = NULL;
+@@ -805,7 +808,7 @@ err_unbind:
+ */
+ subdev_notifier = v4l2_async_find_subdev_notifier(sd);
+ if (subdev_notifier)
+- v4l2_async_nf_unbind_all_subdevs(subdev_notifier);
++ v4l2_async_nf_unbind_all_subdevs(subdev_notifier, false);
+
+ if (sd->asd)
+ v4l2_async_nf_call_unbind(notifier, sd, sd->asd);
+diff --git a/drivers/mfd/arizona-spi.c b/drivers/mfd/arizona-spi.c
+index da05b966d48c6..02cf4f3e91d76 100644
+--- a/drivers/mfd/arizona-spi.c
++++ b/drivers/mfd/arizona-spi.c
+@@ -277,6 +277,7 @@ static const struct of_device_id arizona_spi_of_match[] = {
+ { .compatible = "cirrus,cs47l24", .data = (void *)CS47L24 },
+ {},
+ };
++MODULE_DEVICE_TABLE(of, arizona_spi_of_match);
+ #endif
+
+ static struct spi_driver arizona_spi_driver = {
+diff --git a/drivers/mfd/ocelot-spi.c b/drivers/mfd/ocelot-spi.c
+index 2ecd271de2fb9..85021f94e5874 100644
+--- a/drivers/mfd/ocelot-spi.c
++++ b/drivers/mfd/ocelot-spi.c
+@@ -130,6 +130,7 @@ static const struct regmap_config ocelot_spi_regmap_config = {
+
+ .write_flag_mask = 0x80,
+
++ .use_single_read = true,
+ .use_single_write = true,
+ .can_multi_write = false,
+
+diff --git a/drivers/mfd/tqmx86.c b/drivers/mfd/tqmx86.c
+index 7ae906ff8e353..fac02875fe7d9 100644
+--- a/drivers/mfd/tqmx86.c
++++ b/drivers/mfd/tqmx86.c
+@@ -16,8 +16,8 @@
+ #include <linux/platform_data/i2c-ocores.h>
+ #include <linux/platform_device.h>
+
+-#define TQMX86_IOBASE 0x160
+-#define TQMX86_IOSIZE 0x3f
++#define TQMX86_IOBASE 0x180
++#define TQMX86_IOSIZE 0x20
+ #define TQMX86_IOBASE_I2C 0x1a0
+ #define TQMX86_IOSIZE_I2C 0xa
+ #define TQMX86_IOBASE_WATCHDOG 0x18b
+@@ -25,14 +25,14 @@
+ #define TQMX86_IOBASE_GPIO 0x18d
+ #define TQMX86_IOSIZE_GPIO 0x4
+
+-#define TQMX86_REG_BOARD_ID 0x20
++#define TQMX86_REG_BOARD_ID 0x00
+ #define TQMX86_REG_BOARD_ID_E38M 1
+ #define TQMX86_REG_BOARD_ID_50UC 2
+ #define TQMX86_REG_BOARD_ID_E38C 3
+ #define TQMX86_REG_BOARD_ID_60EB 4
+-#define TQMX86_REG_BOARD_ID_E39M 5
+-#define TQMX86_REG_BOARD_ID_E39C 6
+-#define TQMX86_REG_BOARD_ID_E39x 7
++#define TQMX86_REG_BOARD_ID_E39MS 5
++#define TQMX86_REG_BOARD_ID_E39C1 6
++#define TQMX86_REG_BOARD_ID_E39C2 7
+ #define TQMX86_REG_BOARD_ID_70EB 8
+ #define TQMX86_REG_BOARD_ID_80UC 9
+ #define TQMX86_REG_BOARD_ID_110EB 11
+@@ -40,18 +40,18 @@
+ #define TQMX86_REG_BOARD_ID_E40S 13
+ #define TQMX86_REG_BOARD_ID_E40C1 14
+ #define TQMX86_REG_BOARD_ID_E40C2 15
+-#define TQMX86_REG_BOARD_REV 0x21
+-#define TQMX86_REG_IO_EXT_INT 0x26
++#define TQMX86_REG_BOARD_REV 0x01
++#define TQMX86_REG_IO_EXT_INT 0x06
+ #define TQMX86_REG_IO_EXT_INT_NONE 0
+ #define TQMX86_REG_IO_EXT_INT_7 1
+ #define TQMX86_REG_IO_EXT_INT_9 2
+ #define TQMX86_REG_IO_EXT_INT_12 3
+ #define TQMX86_REG_IO_EXT_INT_MASK 0x3
+ #define TQMX86_REG_IO_EXT_INT_GPIO_SHIFT 4
++#define TQMX86_REG_SAUC 0x17
+
+-#define TQMX86_REG_I2C_DETECT 0x47
++#define TQMX86_REG_I2C_DETECT 0x1a7
+ #define TQMX86_REG_I2C_DETECT_SOFT 0xa5
+-#define TQMX86_REG_I2C_INT_EN 0x49
+
+ static uint gpio_irq;
+ module_param(gpio_irq, uint, 0);
+@@ -111,7 +111,7 @@ static const struct mfd_cell tqmx86_devs[] = {
+ },
+ };
+
+-static const char *tqmx86_board_id_to_name(u8 board_id)
++static const char *tqmx86_board_id_to_name(u8 board_id, u8 sauc)
+ {
+ switch (board_id) {
+ case TQMX86_REG_BOARD_ID_E38M:
+@@ -122,12 +122,12 @@ static const char *tqmx86_board_id_to_name(u8 board_id)
+ return "TQMxE38C";
+ case TQMX86_REG_BOARD_ID_60EB:
+ return "TQMx60EB";
+- case TQMX86_REG_BOARD_ID_E39M:
+- return "TQMxE39M";
+- case TQMX86_REG_BOARD_ID_E39C:
+- return "TQMxE39C";
+- case TQMX86_REG_BOARD_ID_E39x:
+- return "TQMxE39x";
++ case TQMX86_REG_BOARD_ID_E39MS:
++ return (sauc == 0xff) ? "TQMxE39M" : "TQMxE39S";
++ case TQMX86_REG_BOARD_ID_E39C1:
++ return "TQMxE39C1";
++ case TQMX86_REG_BOARD_ID_E39C2:
++ return "TQMxE39C2";
+ case TQMX86_REG_BOARD_ID_70EB:
+ return "TQMx70EB";
+ case TQMX86_REG_BOARD_ID_80UC:
+@@ -160,9 +160,9 @@ static int tqmx86_board_id_to_clk_rate(struct device *dev, u8 board_id)
+ case TQMX86_REG_BOARD_ID_E40C1:
+ case TQMX86_REG_BOARD_ID_E40C2:
+ return 24000;
+- case TQMX86_REG_BOARD_ID_E39M:
+- case TQMX86_REG_BOARD_ID_E39C:
+- case TQMX86_REG_BOARD_ID_E39x:
++ case TQMX86_REG_BOARD_ID_E39MS:
++ case TQMX86_REG_BOARD_ID_E39C1:
++ case TQMX86_REG_BOARD_ID_E39C2:
+ return 25000;
+ case TQMX86_REG_BOARD_ID_E38M:
+ case TQMX86_REG_BOARD_ID_E38C:
+@@ -176,7 +176,7 @@ static int tqmx86_board_id_to_clk_rate(struct device *dev, u8 board_id)
+
+ static int tqmx86_probe(struct platform_device *pdev)
+ {
+- u8 board_id, rev, i2c_det, io_ext_int_val;
++ u8 board_id, sauc, rev, i2c_det, io_ext_int_val;
+ struct device *dev = &pdev->dev;
+ u8 gpio_irq_cfg, readback;
+ const char *board_name;
+@@ -206,14 +206,20 @@ static int tqmx86_probe(struct platform_device *pdev)
+ return -ENOMEM;
+
+ board_id = ioread8(io_base + TQMX86_REG_BOARD_ID);
+- board_name = tqmx86_board_id_to_name(board_id);
++ sauc = ioread8(io_base + TQMX86_REG_SAUC);
++ board_name = tqmx86_board_id_to_name(board_id, sauc);
+ rev = ioread8(io_base + TQMX86_REG_BOARD_REV);
+
+ dev_info(dev,
+ "Found %s - Board ID %d, PCB Revision %d, PLD Revision %d\n",
+ board_name, board_id, rev >> 4, rev & 0xf);
+
+- i2c_det = ioread8(io_base + TQMX86_REG_I2C_DETECT);
++ /*
++ * The I2C_DETECT register is in the range assigned to the I2C driver
++ * later, so we don't extend TQMX86_IOSIZE. Use inb() for this one-off
++ * access instead of ioport_map + unmap.
++ */
++ i2c_det = inb(TQMX86_REG_I2C_DETECT);
+
+ if (gpio_irq_cfg) {
+ io_ext_int_val =
+diff --git a/drivers/misc/vmw_vmci/vmci_host.c b/drivers/misc/vmw_vmci/vmci_host.c
+index 857b9851402a6..abe79f6fd2a79 100644
+--- a/drivers/misc/vmw_vmci/vmci_host.c
++++ b/drivers/misc/vmw_vmci/vmci_host.c
+@@ -165,10 +165,16 @@ static int vmci_host_close(struct inode *inode, struct file *filp)
+ static __poll_t vmci_host_poll(struct file *filp, poll_table *wait)
+ {
+ struct vmci_host_dev *vmci_host_dev = filp->private_data;
+- struct vmci_ctx *context = vmci_host_dev->context;
++ struct vmci_ctx *context;
+ __poll_t mask = 0;
+
+ if (vmci_host_dev->ct_type == VMCIOBJ_CONTEXT) {
++ /*
++ * Read context only if ct_type == VMCIOBJ_CONTEXT to make
++ * sure that context is initialized
++ */
++ context = vmci_host_dev->context;
++
+ /* Check for VMCI calls to this VM context. */
+ if (wait)
+ poll_wait(filp, &context->host_context.wait_queue,
+diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
+index 4712adac7f7c0..48ca1cf15b199 100644
+--- a/drivers/mmc/host/sdhci-of-esdhc.c
++++ b/drivers/mmc/host/sdhci-of-esdhc.c
+@@ -133,6 +133,7 @@ static u32 esdhc_readl_fixup(struct sdhci_host *host,
+ return ret;
+ }
+ }
++
+ /*
+ * The DAT[3:0] line signal levels and the CMD line signal level are
+ * not compatible with standard SDHC register. The line signal levels
+@@ -144,6 +145,16 @@ static u32 esdhc_readl_fixup(struct sdhci_host *host,
+ ret = value & 0x000fffff;
+ ret |= (value >> 4) & SDHCI_DATA_LVL_MASK;
+ ret |= (value << 1) & SDHCI_CMD_LVL;
++
++ /*
++ * Some controllers have unreliable Data Line Active
++ * bit for commands with busy signal. This affects
++ * Command Inhibit (data) bit. Just ignore it since
++ * MMC core driver has already polled card status
++ * with CMD13 after any command with busy siganl.
++ */
++ if (esdhc->quirk_ignore_data_inhibit)
++ ret &= ~SDHCI_DATA_INHIBIT;
+ return ret;
+ }
+
+@@ -158,19 +169,6 @@ static u32 esdhc_readl_fixup(struct sdhci_host *host,
+ return ret;
+ }
+
+- /*
+- * Some controllers have unreliable Data Line Active
+- * bit for commands with busy signal. This affects
+- * Command Inhibit (data) bit. Just ignore it since
+- * MMC core driver has already polled card status
+- * with CMD13 after any command with busy siganl.
+- */
+- if ((spec_reg == SDHCI_PRESENT_STATE) &&
+- (esdhc->quirk_ignore_data_inhibit == true)) {
+- ret = value & ~SDHCI_DATA_INHIBIT;
+- return ret;
+- }
+-
+ ret = value;
+ return ret;
+ }
+diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
+index 0feacb9fbdac5..0bc9676fe0299 100644
+--- a/drivers/mtd/mtdcore.c
++++ b/drivers/mtd/mtdcore.c
+@@ -888,8 +888,8 @@ static struct nvmem_device *mtd_otp_nvmem_register(struct mtd_info *mtd,
+
+ /* OTP nvmem will be registered on the physical device */
+ config.dev = mtd->dev.parent;
+- config.name = kasprintf(GFP_KERNEL, "%s-%s", dev_name(&mtd->dev), compatible);
+- config.id = NVMEM_DEVID_NONE;
++ config.name = compatible;
++ config.id = NVMEM_DEVID_AUTO;
+ config.owner = THIS_MODULE;
+ config.type = NVMEM_TYPE_OTP;
+ config.root_only = true;
+@@ -905,7 +905,6 @@ static struct nvmem_device *mtd_otp_nvmem_register(struct mtd_info *mtd,
+ nvmem = NULL;
+
+ of_node_put(np);
+- kfree(config.name);
+
+ return nvmem;
+ }
+@@ -940,6 +939,7 @@ static int mtd_nvmem_fact_otp_reg_read(void *priv, unsigned int offset,
+
+ static int mtd_otp_nvmem_add(struct mtd_info *mtd)
+ {
++ struct device *dev = mtd->dev.parent;
+ struct nvmem_device *nvmem;
+ ssize_t size;
+ int err;
+@@ -953,7 +953,7 @@ static int mtd_otp_nvmem_add(struct mtd_info *mtd)
+ nvmem = mtd_otp_nvmem_register(mtd, "user-otp", size,
+ mtd_nvmem_user_otp_reg_read);
+ if (IS_ERR(nvmem)) {
+- dev_err(&mtd->dev, "Failed to register OTP NVMEM device\n");
++ dev_err(dev, "Failed to register OTP NVMEM device\n");
+ return PTR_ERR(nvmem);
+ }
+ mtd->otp_user_nvmem = nvmem;
+@@ -971,7 +971,7 @@ static int mtd_otp_nvmem_add(struct mtd_info *mtd)
+ nvmem = mtd_otp_nvmem_register(mtd, "factory-otp", size,
+ mtd_nvmem_fact_otp_reg_read);
+ if (IS_ERR(nvmem)) {
+- dev_err(&mtd->dev, "Failed to register OTP NVMEM device\n");
++ dev_err(dev, "Failed to register OTP NVMEM device\n");
+ err = PTR_ERR(nvmem);
+ goto err;
+ }
+@@ -1023,10 +1023,14 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
+
+ mtd_set_dev_defaults(mtd);
+
++ ret = mtd_otp_nvmem_add(mtd);
++ if (ret)
++ goto out;
++
+ if (IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER)) {
+ ret = add_mtd_device(mtd);
+ if (ret)
+- return ret;
++ goto out;
+ }
+
+ /* Prefer parsed partitions over driver-provided fallback */
+@@ -1061,9 +1065,12 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
+ register_reboot_notifier(&mtd->reboot_notifier);
+ }
+
+- ret = mtd_otp_nvmem_add(mtd);
+-
+ out:
++ if (ret) {
++ nvmem_unregister(mtd->otp_user_nvmem);
++ nvmem_unregister(mtd->otp_factory_nvmem);
++ }
++
+ if (ret && device_is_registered(&mtd->dev))
+ del_mtd_device(mtd);
+
+diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
+index 4244c6fd98111..bf50a35db711e 100644
+--- a/drivers/mtd/spi-nor/core.c
++++ b/drivers/mtd/spi-nor/core.c
+@@ -2733,6 +2733,7 @@ static int spi_nor_quad_enable(struct spi_nor *nor)
+
+ static int spi_nor_init(struct spi_nor *nor)
+ {
++ struct spi_nor_flash_parameter *params = nor->params;
+ int err;
+
+ err = spi_nor_octal_dtr_enable(nor, true);
+@@ -2774,9 +2775,10 @@ static int spi_nor_init(struct spi_nor *nor)
+ */
+ WARN_ONCE(nor->flags & SNOR_F_BROKEN_RESET,
+ "enabling reset hack; may not recover from unexpected reboots\n");
+- err = nor->params->set_4byte_addr_mode(nor, true);
++ err = params->set_4byte_addr_mode(nor, true);
+ if (err && err != -ENOTSUPP)
+ return err;
++ params->addr_mode_nbytes = 4;
+ }
+
+ return 0;
+diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c
+index 09c408c45a621..4e1d80746b04b 100644
+--- a/drivers/mtd/ubi/eba.c
++++ b/drivers/mtd/ubi/eba.c
+@@ -946,7 +946,7 @@ static int try_write_vid_and_data(struct ubi_volume *vol, int lnum,
+ int offset, int len)
+ {
+ struct ubi_device *ubi = vol->ubi;
+- int pnum, opnum, err, vol_id = vol->vol_id;
++ int pnum, opnum, err, err2, vol_id = vol->vol_id;
+
+ pnum = ubi_wl_get_peb(ubi);
+ if (pnum < 0) {
+@@ -981,10 +981,19 @@ static int try_write_vid_and_data(struct ubi_volume *vol, int lnum,
+ out_put:
+ up_read(&ubi->fm_eba_sem);
+
+- if (err && pnum >= 0)
+- err = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1);
+- else if (!err && opnum >= 0)
+- err = ubi_wl_put_peb(ubi, vol_id, lnum, opnum, 0);
++ if (err && pnum >= 0) {
++ err2 = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1);
++ if (err2) {
++ ubi_warn(ubi, "failed to return physical eraseblock %d, error %d",
++ pnum, err2);
++ }
++ } else if (!err && opnum >= 0) {
++ err2 = ubi_wl_put_peb(ubi, vol_id, lnum, opnum, 0);
++ if (err2) {
++ ubi_warn(ubi, "failed to return physical eraseblock %d, error %d",
++ opnum, err2);
++ }
++ }
+
+ return err;
+ }
+diff --git a/drivers/net/dsa/qca/qca8k-8xxx.c b/drivers/net/dsa/qca/qca8k-8xxx.c
+index 2f224b166bbb3..f7944fe2e0ba7 100644
+--- a/drivers/net/dsa/qca/qca8k-8xxx.c
++++ b/drivers/net/dsa/qca/qca8k-8xxx.c
+@@ -1427,7 +1427,6 @@ static void qca8k_pcs_get_state(struct phylink_pcs *pcs,
+
+ state->link = !!(reg & QCA8K_PORT_STATUS_LINK_UP);
+ state->an_complete = state->link;
+- state->an_enabled = !!(reg & QCA8K_PORT_STATUS_LINK_AUTO);
+ state->duplex = (reg & QCA8K_PORT_STATUS_DUPLEX) ? DUPLEX_FULL :
+ DUPLEX_HALF;
+
+diff --git a/drivers/net/ethernet/amd/nmclan_cs.c b/drivers/net/ethernet/amd/nmclan_cs.c
+index 823a329a921f4..0dd391c84c138 100644
+--- a/drivers/net/ethernet/amd/nmclan_cs.c
++++ b/drivers/net/ethernet/amd/nmclan_cs.c
+@@ -651,7 +651,7 @@ static int nmclan_config(struct pcmcia_device *link)
+ } else {
+ pr_notice("mace id not found: %x %x should be 0x40 0x?9\n",
+ sig[0], sig[1]);
+- return -ENODEV;
++ goto failed;
+ }
+ }
+
+diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+index 027fff9f7db07..48ec323e0a920 100644
+--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
++++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+@@ -295,7 +295,8 @@ static int dpaa_stop(struct net_device *net_dev)
+ {
+ struct mac_device *mac_dev;
+ struct dpaa_priv *priv;
+- int i, err, error;
++ int i, error;
++ int err = 0;
+
+ priv = netdev_priv(net_dev);
+ mac_dev = priv->mac_dev;
+diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h
+index 60e351665c707..e789729a9cfba 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e.h
++++ b/drivers/net/ethernet/intel/i40e/i40e.h
+@@ -1287,9 +1287,9 @@ void i40e_ptp_stop(struct i40e_pf *pf);
+ int i40e_ptp_alloc_pins(struct i40e_pf *pf);
+ int i40e_update_adq_vsi_queues(struct i40e_vsi *vsi, int vsi_offset);
+ int i40e_is_vsi_uplink_mode_veb(struct i40e_vsi *vsi);
+-i40e_status i40e_get_partition_bw_setting(struct i40e_pf *pf);
+-i40e_status i40e_set_partition_bw_setting(struct i40e_pf *pf);
+-i40e_status i40e_commit_partition_bw_setting(struct i40e_pf *pf);
++int i40e_get_partition_bw_setting(struct i40e_pf *pf);
++int i40e_set_partition_bw_setting(struct i40e_pf *pf);
++int i40e_commit_partition_bw_setting(struct i40e_pf *pf);
+ void i40e_print_link_message(struct i40e_vsi *vsi, bool isup);
+
+ void i40e_set_fec_in_flags(u8 fec_cfg, u32 *flags);
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq.c b/drivers/net/ethernet/intel/i40e/i40e_adminq.c
+index 42439f725aa43..86fac8f959bb0 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_adminq.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_adminq.c
+@@ -47,9 +47,9 @@ static void i40e_adminq_init_regs(struct i40e_hw *hw)
+ * i40e_alloc_adminq_asq_ring - Allocate Admin Queue send rings
+ * @hw: pointer to the hardware structure
+ **/
+-static i40e_status i40e_alloc_adminq_asq_ring(struct i40e_hw *hw)
++static int i40e_alloc_adminq_asq_ring(struct i40e_hw *hw)
+ {
+- i40e_status ret_code;
++ int ret_code;
+
+ ret_code = i40e_allocate_dma_mem(hw, &hw->aq.asq.desc_buf,
+ i40e_mem_atq_ring,
+@@ -74,9 +74,9 @@ static i40e_status i40e_alloc_adminq_asq_ring(struct i40e_hw *hw)
+ * i40e_alloc_adminq_arq_ring - Allocate Admin Queue receive rings
+ * @hw: pointer to the hardware structure
+ **/
+-static i40e_status i40e_alloc_adminq_arq_ring(struct i40e_hw *hw)
++static int i40e_alloc_adminq_arq_ring(struct i40e_hw *hw)
+ {
+- i40e_status ret_code;
++ int ret_code;
+
+ ret_code = i40e_allocate_dma_mem(hw, &hw->aq.arq.desc_buf,
+ i40e_mem_arq_ring,
+@@ -115,11 +115,11 @@ static void i40e_free_adminq_arq(struct i40e_hw *hw)
+ * i40e_alloc_arq_bufs - Allocate pre-posted buffers for the receive queue
+ * @hw: pointer to the hardware structure
+ **/
+-static i40e_status i40e_alloc_arq_bufs(struct i40e_hw *hw)
++static int i40e_alloc_arq_bufs(struct i40e_hw *hw)
+ {
+- i40e_status ret_code;
+ struct i40e_aq_desc *desc;
+ struct i40e_dma_mem *bi;
++ int ret_code;
+ int i;
+
+ /* We'll be allocating the buffer info memory first, then we can
+@@ -182,10 +182,10 @@ unwind_alloc_arq_bufs:
+ * i40e_alloc_asq_bufs - Allocate empty buffer structs for the send queue
+ * @hw: pointer to the hardware structure
+ **/
+-static i40e_status i40e_alloc_asq_bufs(struct i40e_hw *hw)
++static int i40e_alloc_asq_bufs(struct i40e_hw *hw)
+ {
+- i40e_status ret_code;
+ struct i40e_dma_mem *bi;
++ int ret_code;
+ int i;
+
+ /* No mapped memory needed yet, just the buffer info structures */
+@@ -266,9 +266,9 @@ static void i40e_free_asq_bufs(struct i40e_hw *hw)
+ *
+ * Configure base address and length registers for the transmit queue
+ **/
+-static i40e_status i40e_config_asq_regs(struct i40e_hw *hw)
++static int i40e_config_asq_regs(struct i40e_hw *hw)
+ {
+- i40e_status ret_code = 0;
++ int ret_code = 0;
+ u32 reg = 0;
+
+ /* Clear Head and Tail */
+@@ -295,9 +295,9 @@ static i40e_status i40e_config_asq_regs(struct i40e_hw *hw)
+ *
+ * Configure base address and length registers for the receive (event queue)
+ **/
+-static i40e_status i40e_config_arq_regs(struct i40e_hw *hw)
++static int i40e_config_arq_regs(struct i40e_hw *hw)
+ {
+- i40e_status ret_code = 0;
++ int ret_code = 0;
+ u32 reg = 0;
+
+ /* Clear Head and Tail */
+@@ -334,9 +334,9 @@ static i40e_status i40e_config_arq_regs(struct i40e_hw *hw)
+ * Do *NOT* hold the lock when calling this as the memory allocation routines
+ * called are not going to be atomic context safe
+ **/
+-static i40e_status i40e_init_asq(struct i40e_hw *hw)
++static int i40e_init_asq(struct i40e_hw *hw)
+ {
+- i40e_status ret_code = 0;
++ int ret_code = 0;
+
+ if (hw->aq.asq.count > 0) {
+ /* queue already initialized */
+@@ -393,9 +393,9 @@ init_adminq_exit:
+ * Do *NOT* hold the lock when calling this as the memory allocation routines
+ * called are not going to be atomic context safe
+ **/
+-static i40e_status i40e_init_arq(struct i40e_hw *hw)
++static int i40e_init_arq(struct i40e_hw *hw)
+ {
+- i40e_status ret_code = 0;
++ int ret_code = 0;
+
+ if (hw->aq.arq.count > 0) {
+ /* queue already initialized */
+@@ -445,9 +445,9 @@ init_adminq_exit:
+ *
+ * The main shutdown routine for the Admin Send Queue
+ **/
+-static i40e_status i40e_shutdown_asq(struct i40e_hw *hw)
++static int i40e_shutdown_asq(struct i40e_hw *hw)
+ {
+- i40e_status ret_code = 0;
++ int ret_code = 0;
+
+ mutex_lock(&hw->aq.asq_mutex);
+
+@@ -479,9 +479,9 @@ shutdown_asq_out:
+ *
+ * The main shutdown routine for the Admin Receive Queue
+ **/
+-static i40e_status i40e_shutdown_arq(struct i40e_hw *hw)
++static int i40e_shutdown_arq(struct i40e_hw *hw)
+ {
+- i40e_status ret_code = 0;
++ int ret_code = 0;
+
+ mutex_lock(&hw->aq.arq_mutex);
+
+@@ -582,12 +582,12 @@ static void i40e_set_hw_flags(struct i40e_hw *hw)
+ * - hw->aq.arq_buf_size
+ * - hw->aq.asq_buf_size
+ **/
+-i40e_status i40e_init_adminq(struct i40e_hw *hw)
++int i40e_init_adminq(struct i40e_hw *hw)
+ {
+ u16 cfg_ptr, oem_hi, oem_lo;
+ u16 eetrack_lo, eetrack_hi;
+- i40e_status ret_code;
+ int retry = 0;
++ int ret_code;
+
+ /* verify input for valid configuration */
+ if ((hw->aq.num_arq_entries == 0) ||
+@@ -780,7 +780,7 @@ static bool i40e_asq_done(struct i40e_hw *hw)
+ * This is the main send command driver routine for the Admin Queue send
+ * queue. It runs the queue, cleans the queue, etc
+ **/
+-static i40e_status
++static int
+ i40e_asq_send_command_atomic_exec(struct i40e_hw *hw,
+ struct i40e_aq_desc *desc,
+ void *buff, /* can be NULL */
+@@ -788,12 +788,12 @@ i40e_asq_send_command_atomic_exec(struct i40e_hw *hw,
+ struct i40e_asq_cmd_details *cmd_details,
+ bool is_atomic_context)
+ {
+- i40e_status status = 0;
+ struct i40e_dma_mem *dma_buff = NULL;
+ struct i40e_asq_cmd_details *details;
+ struct i40e_aq_desc *desc_on_ring;
+ bool cmd_completed = false;
+ u16 retval = 0;
++ int status = 0;
+ u32 val = 0;
+
+ if (hw->aq.asq.count == 0) {
+@@ -984,7 +984,7 @@ asq_send_command_error:
+ * Acquires the lock and calls the main send command execution
+ * routine.
+ **/
+-i40e_status
++int
+ i40e_asq_send_command_atomic(struct i40e_hw *hw,
+ struct i40e_aq_desc *desc,
+ void *buff, /* can be NULL */
+@@ -992,7 +992,7 @@ i40e_asq_send_command_atomic(struct i40e_hw *hw,
+ struct i40e_asq_cmd_details *cmd_details,
+ bool is_atomic_context)
+ {
+- i40e_status status;
++ int status;
+
+ mutex_lock(&hw->aq.asq_mutex);
+ status = i40e_asq_send_command_atomic_exec(hw, desc, buff, buff_size,
+@@ -1003,7 +1003,7 @@ i40e_asq_send_command_atomic(struct i40e_hw *hw,
+ return status;
+ }
+
+-i40e_status
++int
+ i40e_asq_send_command(struct i40e_hw *hw, struct i40e_aq_desc *desc,
+ void *buff, /* can be NULL */ u16 buff_size,
+ struct i40e_asq_cmd_details *cmd_details)
+@@ -1026,7 +1026,7 @@ i40e_asq_send_command(struct i40e_hw *hw, struct i40e_aq_desc *desc,
+ * routine. Returns the last Admin Queue status in aq_status
+ * to avoid race conditions in access to hw->aq.asq_last_status.
+ **/
+-i40e_status
++int
+ i40e_asq_send_command_atomic_v2(struct i40e_hw *hw,
+ struct i40e_aq_desc *desc,
+ void *buff, /* can be NULL */
+@@ -1035,7 +1035,7 @@ i40e_asq_send_command_atomic_v2(struct i40e_hw *hw,
+ bool is_atomic_context,
+ enum i40e_admin_queue_err *aq_status)
+ {
+- i40e_status status;
++ int status;
+
+ mutex_lock(&hw->aq.asq_mutex);
+ status = i40e_asq_send_command_atomic_exec(hw, desc, buff,
+@@ -1048,7 +1048,7 @@ i40e_asq_send_command_atomic_v2(struct i40e_hw *hw,
+ return status;
+ }
+
+-i40e_status
++int
+ i40e_asq_send_command_v2(struct i40e_hw *hw, struct i40e_aq_desc *desc,
+ void *buff, /* can be NULL */ u16 buff_size,
+ struct i40e_asq_cmd_details *cmd_details,
+@@ -1084,14 +1084,14 @@ void i40e_fill_default_direct_cmd_desc(struct i40e_aq_desc *desc,
+ * the contents through e. It can also return how many events are
+ * left to process through 'pending'
+ **/
+-i40e_status i40e_clean_arq_element(struct i40e_hw *hw,
+- struct i40e_arq_event_info *e,
+- u16 *pending)
++int i40e_clean_arq_element(struct i40e_hw *hw,
++ struct i40e_arq_event_info *e,
++ u16 *pending)
+ {
+- i40e_status ret_code = 0;
+ u16 ntc = hw->aq.arq.next_to_clean;
+ struct i40e_aq_desc *desc;
+ struct i40e_dma_mem *bi;
++ int ret_code = 0;
+ u16 desc_idx;
+ u16 datalen;
+ u16 flags;
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_alloc.h b/drivers/net/ethernet/intel/i40e/i40e_alloc.h
+index cb8689222c8b7..a6c9a9e343d11 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_alloc.h
++++ b/drivers/net/ethernet/intel/i40e/i40e_alloc.h
+@@ -20,16 +20,16 @@ enum i40e_memory_type {
+ };
+
+ /* prototype for functions used for dynamic memory allocation */
+-i40e_status i40e_allocate_dma_mem(struct i40e_hw *hw,
+- struct i40e_dma_mem *mem,
+- enum i40e_memory_type type,
+- u64 size, u32 alignment);
+-i40e_status i40e_free_dma_mem(struct i40e_hw *hw,
+- struct i40e_dma_mem *mem);
+-i40e_status i40e_allocate_virt_mem(struct i40e_hw *hw,
+- struct i40e_virt_mem *mem,
+- u32 size);
+-i40e_status i40e_free_virt_mem(struct i40e_hw *hw,
+- struct i40e_virt_mem *mem);
++int i40e_allocate_dma_mem(struct i40e_hw *hw,
++ struct i40e_dma_mem *mem,
++ enum i40e_memory_type type,
++ u64 size, u32 alignment);
++int i40e_free_dma_mem(struct i40e_hw *hw,
++ struct i40e_dma_mem *mem);
++int i40e_allocate_virt_mem(struct i40e_hw *hw,
++ struct i40e_virt_mem *mem,
++ u32 size);
++int i40e_free_virt_mem(struct i40e_hw *hw,
++ struct i40e_virt_mem *mem);
+
+ #endif /* _I40E_ALLOC_H_ */
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_client.c b/drivers/net/ethernet/intel/i40e/i40e_client.c
+index 10d7a982a5b9b..8bcb98b85e3d9 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_client.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_client.c
+@@ -541,7 +541,7 @@ static int i40e_client_virtchnl_send(struct i40e_info *ldev,
+ {
+ struct i40e_pf *pf = ldev->pf;
+ struct i40e_hw *hw = &pf->hw;
+- i40e_status err;
++ int err;
+
+ err = i40e_aq_send_msg_to_vf(hw, vf_id, VIRTCHNL_OP_IWARP,
+ 0, msg, len, NULL);
+@@ -674,7 +674,7 @@ static int i40e_client_update_vsi_ctxt(struct i40e_info *ldev,
+ struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
+ struct i40e_vsi_context ctxt;
+ bool update = true;
+- i40e_status err;
++ int err;
+
+ /* TODO: for now do not allow setting VF's VSI setting */
+ if (is_vf)
+@@ -686,8 +686,8 @@ static int i40e_client_update_vsi_ctxt(struct i40e_info *ldev,
+ ctxt.flags = I40E_AQ_VSI_TYPE_PF;
+ if (err) {
+ dev_info(&pf->pdev->dev,
+- "couldn't get PF vsi config, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, err),
++ "couldn't get PF vsi config, err %d aq_err %s\n",
++ err,
+ i40e_aq_str(&pf->hw,
+ pf->hw.aq.asq_last_status));
+ return -ENOENT;
+@@ -714,8 +714,8 @@ static int i40e_client_update_vsi_ctxt(struct i40e_info *ldev,
+ err = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL);
+ if (err) {
+ dev_info(&pf->pdev->dev,
+- "update VSI ctxt for PE failed, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, err),
++ "update VSI ctxt for PE failed, err %d aq_err %s\n",
++ err,
+ i40e_aq_str(&pf->hw,
+ pf->hw.aq.asq_last_status));
+ }
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c
+index 8f764ff5c990f..ed88e38d488b2 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_common.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_common.c
+@@ -14,9 +14,9 @@
+ * This function sets the mac type of the adapter based on the
+ * vendor ID and device ID stored in the hw structure.
+ **/
+-i40e_status i40e_set_mac_type(struct i40e_hw *hw)
++int i40e_set_mac_type(struct i40e_hw *hw)
+ {
+- i40e_status status = 0;
++ int status = 0;
+
+ if (hw->vendor_id == PCI_VENDOR_ID_INTEL) {
+ switch (hw->device_id) {
+@@ -124,154 +124,6 @@ const char *i40e_aq_str(struct i40e_hw *hw, enum i40e_admin_queue_err aq_err)
+ return hw->err_str;
+ }
+
+-/**
+- * i40e_stat_str - convert status err code to a string
+- * @hw: pointer to the HW structure
+- * @stat_err: the status error code to convert
+- **/
+-const char *i40e_stat_str(struct i40e_hw *hw, i40e_status stat_err)
+-{
+- switch (stat_err) {
+- case 0:
+- return "OK";
+- case I40E_ERR_NVM:
+- return "I40E_ERR_NVM";
+- case I40E_ERR_NVM_CHECKSUM:
+- return "I40E_ERR_NVM_CHECKSUM";
+- case I40E_ERR_PHY:
+- return "I40E_ERR_PHY";
+- case I40E_ERR_CONFIG:
+- return "I40E_ERR_CONFIG";
+- case I40E_ERR_PARAM:
+- return "I40E_ERR_PARAM";
+- case I40E_ERR_MAC_TYPE:
+- return "I40E_ERR_MAC_TYPE";
+- case I40E_ERR_UNKNOWN_PHY:
+- return "I40E_ERR_UNKNOWN_PHY";
+- case I40E_ERR_LINK_SETUP:
+- return "I40E_ERR_LINK_SETUP";
+- case I40E_ERR_ADAPTER_STOPPED:
+- return "I40E_ERR_ADAPTER_STOPPED";
+- case I40E_ERR_INVALID_MAC_ADDR:
+- return "I40E_ERR_INVALID_MAC_ADDR";
+- case I40E_ERR_DEVICE_NOT_SUPPORTED:
+- return "I40E_ERR_DEVICE_NOT_SUPPORTED";
+- case I40E_ERR_PRIMARY_REQUESTS_PENDING:
+- return "I40E_ERR_PRIMARY_REQUESTS_PENDING";
+- case I40E_ERR_INVALID_LINK_SETTINGS:
+- return "I40E_ERR_INVALID_LINK_SETTINGS";
+- case I40E_ERR_AUTONEG_NOT_COMPLETE:
+- return "I40E_ERR_AUTONEG_NOT_COMPLETE";
+- case I40E_ERR_RESET_FAILED:
+- return "I40E_ERR_RESET_FAILED";
+- case I40E_ERR_SWFW_SYNC:
+- return "I40E_ERR_SWFW_SYNC";
+- case I40E_ERR_NO_AVAILABLE_VSI:
+- return "I40E_ERR_NO_AVAILABLE_VSI";
+- case I40E_ERR_NO_MEMORY:
+- return "I40E_ERR_NO_MEMORY";
+- case I40E_ERR_BAD_PTR:
+- return "I40E_ERR_BAD_PTR";
+- case I40E_ERR_RING_FULL:
+- return "I40E_ERR_RING_FULL";
+- case I40E_ERR_INVALID_PD_ID:
+- return "I40E_ERR_INVALID_PD_ID";
+- case I40E_ERR_INVALID_QP_ID:
+- return "I40E_ERR_INVALID_QP_ID";
+- case I40E_ERR_INVALID_CQ_ID:
+- return "I40E_ERR_INVALID_CQ_ID";
+- case I40E_ERR_INVALID_CEQ_ID:
+- return "I40E_ERR_INVALID_CEQ_ID";
+- case I40E_ERR_INVALID_AEQ_ID:
+- return "I40E_ERR_INVALID_AEQ_ID";
+- case I40E_ERR_INVALID_SIZE:
+- return "I40E_ERR_INVALID_SIZE";
+- case I40E_ERR_INVALID_ARP_INDEX:
+- return "I40E_ERR_INVALID_ARP_INDEX";
+- case I40E_ERR_INVALID_FPM_FUNC_ID:
+- return "I40E_ERR_INVALID_FPM_FUNC_ID";
+- case I40E_ERR_QP_INVALID_MSG_SIZE:
+- return "I40E_ERR_QP_INVALID_MSG_SIZE";
+- case I40E_ERR_QP_TOOMANY_WRS_POSTED:
+- return "I40E_ERR_QP_TOOMANY_WRS_POSTED";
+- case I40E_ERR_INVALID_FRAG_COUNT:
+- return "I40E_ERR_INVALID_FRAG_COUNT";
+- case I40E_ERR_QUEUE_EMPTY:
+- return "I40E_ERR_QUEUE_EMPTY";
+- case I40E_ERR_INVALID_ALIGNMENT:
+- return "I40E_ERR_INVALID_ALIGNMENT";
+- case I40E_ERR_FLUSHED_QUEUE:
+- return "I40E_ERR_FLUSHED_QUEUE";
+- case I40E_ERR_INVALID_PUSH_PAGE_INDEX:
+- return "I40E_ERR_INVALID_PUSH_PAGE_INDEX";
+- case I40E_ERR_INVALID_IMM_DATA_SIZE:
+- return "I40E_ERR_INVALID_IMM_DATA_SIZE";
+- case I40E_ERR_TIMEOUT:
+- return "I40E_ERR_TIMEOUT";
+- case I40E_ERR_OPCODE_MISMATCH:
+- return "I40E_ERR_OPCODE_MISMATCH";
+- case I40E_ERR_CQP_COMPL_ERROR:
+- return "I40E_ERR_CQP_COMPL_ERROR";
+- case I40E_ERR_INVALID_VF_ID:
+- return "I40E_ERR_INVALID_VF_ID";
+- case I40E_ERR_INVALID_HMCFN_ID:
+- return "I40E_ERR_INVALID_HMCFN_ID";
+- case I40E_ERR_BACKING_PAGE_ERROR:
+- return "I40E_ERR_BACKING_PAGE_ERROR";
+- case I40E_ERR_NO_PBLCHUNKS_AVAILABLE:
+- return "I40E_ERR_NO_PBLCHUNKS_AVAILABLE";
+- case I40E_ERR_INVALID_PBLE_INDEX:
+- return "I40E_ERR_INVALID_PBLE_INDEX";
+- case I40E_ERR_INVALID_SD_INDEX:
+- return "I40E_ERR_INVALID_SD_INDEX";
+- case I40E_ERR_INVALID_PAGE_DESC_INDEX:
+- return "I40E_ERR_INVALID_PAGE_DESC_INDEX";
+- case I40E_ERR_INVALID_SD_TYPE:
+- return "I40E_ERR_INVALID_SD_TYPE";
+- case I40E_ERR_MEMCPY_FAILED:
+- return "I40E_ERR_MEMCPY_FAILED";
+- case I40E_ERR_INVALID_HMC_OBJ_INDEX:
+- return "I40E_ERR_INVALID_HMC_OBJ_INDEX";
+- case I40E_ERR_INVALID_HMC_OBJ_COUNT:
+- return "I40E_ERR_INVALID_HMC_OBJ_COUNT";
+- case I40E_ERR_INVALID_SRQ_ARM_LIMIT:
+- return "I40E_ERR_INVALID_SRQ_ARM_LIMIT";
+- case I40E_ERR_SRQ_ENABLED:
+- return "I40E_ERR_SRQ_ENABLED";
+- case I40E_ERR_ADMIN_QUEUE_ERROR:
+- return "I40E_ERR_ADMIN_QUEUE_ERROR";
+- case I40E_ERR_ADMIN_QUEUE_TIMEOUT:
+- return "I40E_ERR_ADMIN_QUEUE_TIMEOUT";
+- case I40E_ERR_BUF_TOO_SHORT:
+- return "I40E_ERR_BUF_TOO_SHORT";
+- case I40E_ERR_ADMIN_QUEUE_FULL:
+- return "I40E_ERR_ADMIN_QUEUE_FULL";
+- case I40E_ERR_ADMIN_QUEUE_NO_WORK:
+- return "I40E_ERR_ADMIN_QUEUE_NO_WORK";
+- case I40E_ERR_BAD_IWARP_CQE:
+- return "I40E_ERR_BAD_IWARP_CQE";
+- case I40E_ERR_NVM_BLANK_MODE:
+- return "I40E_ERR_NVM_BLANK_MODE";
+- case I40E_ERR_NOT_IMPLEMENTED:
+- return "I40E_ERR_NOT_IMPLEMENTED";
+- case I40E_ERR_PE_DOORBELL_NOT_ENABLED:
+- return "I40E_ERR_PE_DOORBELL_NOT_ENABLED";
+- case I40E_ERR_DIAG_TEST_FAILED:
+- return "I40E_ERR_DIAG_TEST_FAILED";
+- case I40E_ERR_NOT_READY:
+- return "I40E_ERR_NOT_READY";
+- case I40E_NOT_SUPPORTED:
+- return "I40E_NOT_SUPPORTED";
+- case I40E_ERR_FIRMWARE_API_VERSION:
+- return "I40E_ERR_FIRMWARE_API_VERSION";
+- case I40E_ERR_ADMIN_QUEUE_CRITICAL_ERROR:
+- return "I40E_ERR_ADMIN_QUEUE_CRITICAL_ERROR";
+- }
+-
+- snprintf(hw->err_str, sizeof(hw->err_str), "%d", stat_err);
+- return hw->err_str;
+-}
+-
+ /**
+ * i40e_debug_aq
+ * @hw: debug mask related to admin queue
+@@ -355,13 +207,13 @@ bool i40e_check_asq_alive(struct i40e_hw *hw)
+ * Tell the Firmware that we're shutting down the AdminQ and whether
+ * or not the driver is unloading as well.
+ **/
+-i40e_status i40e_aq_queue_shutdown(struct i40e_hw *hw,
+- bool unloading)
++int i40e_aq_queue_shutdown(struct i40e_hw *hw,
++ bool unloading)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_queue_shutdown *cmd =
+ (struct i40e_aqc_queue_shutdown *)&desc.params.raw;
+- i40e_status status;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_queue_shutdown);
+@@ -384,15 +236,15 @@ i40e_status i40e_aq_queue_shutdown(struct i40e_hw *hw,
+ *
+ * Internal function to get or set RSS look up table
+ **/
+-static i40e_status i40e_aq_get_set_rss_lut(struct i40e_hw *hw,
+- u16 vsi_id, bool pf_lut,
+- u8 *lut, u16 lut_size,
+- bool set)
++static int i40e_aq_get_set_rss_lut(struct i40e_hw *hw,
++ u16 vsi_id, bool pf_lut,
++ u8 *lut, u16 lut_size,
++ bool set)
+ {
+- i40e_status status;
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_get_set_rss_lut *cmd_resp =
+ (struct i40e_aqc_get_set_rss_lut *)&desc.params.raw;
++ int status;
+
+ if (set)
+ i40e_fill_default_direct_cmd_desc(&desc,
+@@ -437,8 +289,8 @@ static i40e_status i40e_aq_get_set_rss_lut(struct i40e_hw *hw,
+ *
+ * get the RSS lookup table, PF or VSI type
+ **/
+-i40e_status i40e_aq_get_rss_lut(struct i40e_hw *hw, u16 vsi_id,
+- bool pf_lut, u8 *lut, u16 lut_size)
++int i40e_aq_get_rss_lut(struct i40e_hw *hw, u16 vsi_id,
++ bool pf_lut, u8 *lut, u16 lut_size)
+ {
+ return i40e_aq_get_set_rss_lut(hw, vsi_id, pf_lut, lut, lut_size,
+ false);
+@@ -454,8 +306,8 @@ i40e_status i40e_aq_get_rss_lut(struct i40e_hw *hw, u16 vsi_id,
+ *
+ * set the RSS lookup table, PF or VSI type
+ **/
+-i40e_status i40e_aq_set_rss_lut(struct i40e_hw *hw, u16 vsi_id,
+- bool pf_lut, u8 *lut, u16 lut_size)
++int i40e_aq_set_rss_lut(struct i40e_hw *hw, u16 vsi_id,
++ bool pf_lut, u8 *lut, u16 lut_size)
+ {
+ return i40e_aq_get_set_rss_lut(hw, vsi_id, pf_lut, lut, lut_size, true);
+ }
+@@ -469,16 +321,16 @@ i40e_status i40e_aq_set_rss_lut(struct i40e_hw *hw, u16 vsi_id,
+ *
+ * get the RSS key per VSI
+ **/
+-static i40e_status i40e_aq_get_set_rss_key(struct i40e_hw *hw,
+- u16 vsi_id,
+- struct i40e_aqc_get_set_rss_key_data *key,
+- bool set)
++static int i40e_aq_get_set_rss_key(struct i40e_hw *hw,
++ u16 vsi_id,
++ struct i40e_aqc_get_set_rss_key_data *key,
++ bool set)
+ {
+- i40e_status status;
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_get_set_rss_key *cmd_resp =
+ (struct i40e_aqc_get_set_rss_key *)&desc.params.raw;
+ u16 key_size = sizeof(struct i40e_aqc_get_set_rss_key_data);
++ int status;
+
+ if (set)
+ i40e_fill_default_direct_cmd_desc(&desc,
+@@ -509,9 +361,9 @@ static i40e_status i40e_aq_get_set_rss_key(struct i40e_hw *hw,
+ * @key: pointer to key info struct
+ *
+ **/
+-i40e_status i40e_aq_get_rss_key(struct i40e_hw *hw,
+- u16 vsi_id,
+- struct i40e_aqc_get_set_rss_key_data *key)
++int i40e_aq_get_rss_key(struct i40e_hw *hw,
++ u16 vsi_id,
++ struct i40e_aqc_get_set_rss_key_data *key)
+ {
+ return i40e_aq_get_set_rss_key(hw, vsi_id, key, false);
+ }
+@@ -524,9 +376,9 @@ i40e_status i40e_aq_get_rss_key(struct i40e_hw *hw,
+ *
+ * set the RSS key per VSI
+ **/
+-i40e_status i40e_aq_set_rss_key(struct i40e_hw *hw,
+- u16 vsi_id,
+- struct i40e_aqc_get_set_rss_key_data *key)
++int i40e_aq_set_rss_key(struct i40e_hw *hw,
++ u16 vsi_id,
++ struct i40e_aqc_get_set_rss_key_data *key)
+ {
+ return i40e_aq_get_set_rss_key(hw, vsi_id, key, true);
+ }
+@@ -796,10 +648,10 @@ struct i40e_rx_ptype_decoded i40e_ptype_lookup[BIT(8)] = {
+ * hw_addr, back, device_id, vendor_id, subsystem_device_id,
+ * subsystem_vendor_id, and revision_id
+ **/
+-i40e_status i40e_init_shared_code(struct i40e_hw *hw)
++int i40e_init_shared_code(struct i40e_hw *hw)
+ {
+- i40e_status status = 0;
+ u32 port, ari, func_rid;
++ int status = 0;
+
+ i40e_set_mac_type(hw);
+
+@@ -836,15 +688,16 @@ i40e_status i40e_init_shared_code(struct i40e_hw *hw)
+ * @addrs: the requestor's mac addr store
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+-static i40e_status i40e_aq_mac_address_read(struct i40e_hw *hw,
+- u16 *flags,
+- struct i40e_aqc_mac_address_read_data *addrs,
+- struct i40e_asq_cmd_details *cmd_details)
++static int
++i40e_aq_mac_address_read(struct i40e_hw *hw,
++ u16 *flags,
++ struct i40e_aqc_mac_address_read_data *addrs,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_mac_address_read *cmd_data =
+ (struct i40e_aqc_mac_address_read *)&desc.params.raw;
+- i40e_status status;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_mac_address_read);
+ desc.flags |= cpu_to_le16(I40E_AQ_FLAG_BUF);
+@@ -863,14 +716,14 @@ static i40e_status i40e_aq_mac_address_read(struct i40e_hw *hw,
+ * @mac_addr: address to write
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+-i40e_status i40e_aq_mac_address_write(struct i40e_hw *hw,
+- u16 flags, u8 *mac_addr,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_mac_address_write(struct i40e_hw *hw,
++ u16 flags, u8 *mac_addr,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_mac_address_write *cmd_data =
+ (struct i40e_aqc_mac_address_write *)&desc.params.raw;
+- i40e_status status;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_mac_address_write);
+@@ -893,11 +746,11 @@ i40e_status i40e_aq_mac_address_write(struct i40e_hw *hw,
+ *
+ * Reads the adapter's MAC address from register
+ **/
+-i40e_status i40e_get_mac_addr(struct i40e_hw *hw, u8 *mac_addr)
++int i40e_get_mac_addr(struct i40e_hw *hw, u8 *mac_addr)
+ {
+ struct i40e_aqc_mac_address_read_data addrs;
+- i40e_status status;
+ u16 flags = 0;
++ int status;
+
+ status = i40e_aq_mac_address_read(hw, &flags, &addrs, NULL);
+
+@@ -914,11 +767,11 @@ i40e_status i40e_get_mac_addr(struct i40e_hw *hw, u8 *mac_addr)
+ *
+ * Reads the adapter's Port MAC address
+ **/
+-i40e_status i40e_get_port_mac_addr(struct i40e_hw *hw, u8 *mac_addr)
++int i40e_get_port_mac_addr(struct i40e_hw *hw, u8 *mac_addr)
+ {
+ struct i40e_aqc_mac_address_read_data addrs;
+- i40e_status status;
+ u16 flags = 0;
++ int status;
+
+ status = i40e_aq_mac_address_read(hw, &flags, &addrs, NULL);
+ if (status)
+@@ -972,13 +825,13 @@ void i40e_pre_tx_queue_cfg(struct i40e_hw *hw, u32 queue, bool enable)
+ *
+ * Reads the part number string from the EEPROM.
+ **/
+-i40e_status i40e_read_pba_string(struct i40e_hw *hw, u8 *pba_num,
+- u32 pba_num_size)
++int i40e_read_pba_string(struct i40e_hw *hw, u8 *pba_num,
++ u32 pba_num_size)
+ {
+- i40e_status status = 0;
+ u16 pba_word = 0;
+ u16 pba_size = 0;
+ u16 pba_ptr = 0;
++ int status = 0;
+ u16 i = 0;
+
+ status = i40e_read_nvm_word(hw, I40E_SR_PBA_FLAGS, &pba_word);
+@@ -1087,8 +940,8 @@ static enum i40e_media_type i40e_get_media_type(struct i40e_hw *hw)
+ * @hw: pointer to the hardware structure
+ * @retry_limit: how many times to retry before failure
+ **/
+-static i40e_status i40e_poll_globr(struct i40e_hw *hw,
+- u32 retry_limit)
++static int i40e_poll_globr(struct i40e_hw *hw,
++ u32 retry_limit)
+ {
+ u32 cnt, reg = 0;
+
+@@ -1114,7 +967,7 @@ static i40e_status i40e_poll_globr(struct i40e_hw *hw,
+ * Assuming someone else has triggered a global reset,
+ * assure the global reset is complete and then reset the PF
+ **/
+-i40e_status i40e_pf_reset(struct i40e_hw *hw)
++int i40e_pf_reset(struct i40e_hw *hw)
+ {
+ u32 cnt = 0;
+ u32 cnt1 = 0;
+@@ -1453,15 +1306,16 @@ void i40e_led_set(struct i40e_hw *hw, u32 mode, bool blink)
+ *
+ * Returns the various PHY abilities supported on the Port.
+ **/
+-i40e_status i40e_aq_get_phy_capabilities(struct i40e_hw *hw,
+- bool qualified_modules, bool report_init,
+- struct i40e_aq_get_phy_abilities_resp *abilities,
+- struct i40e_asq_cmd_details *cmd_details)
++int
++i40e_aq_get_phy_capabilities(struct i40e_hw *hw,
++ bool qualified_modules, bool report_init,
++ struct i40e_aq_get_phy_abilities_resp *abilities,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+- struct i40e_aq_desc desc;
+- i40e_status status;
+ u16 abilities_size = sizeof(struct i40e_aq_get_phy_abilities_resp);
+ u16 max_delay = I40E_MAX_PHY_TIMEOUT, total_delay = 0;
++ struct i40e_aq_desc desc;
++ int status;
+
+ if (!abilities)
+ return I40E_ERR_PARAM;
+@@ -1532,14 +1386,14 @@ i40e_status i40e_aq_get_phy_capabilities(struct i40e_hw *hw,
+ * of the PHY Config parameters. This status will be indicated by the
+ * command response.
+ **/
+-enum i40e_status_code i40e_aq_set_phy_config(struct i40e_hw *hw,
+- struct i40e_aq_set_phy_config *config,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_set_phy_config(struct i40e_hw *hw,
++ struct i40e_aq_set_phy_config *config,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aq_set_phy_config *cmd =
+ (struct i40e_aq_set_phy_config *)&desc.params.raw;
+- enum i40e_status_code status;
++ int status;
+
+ if (!config)
+ return I40E_ERR_PARAM;
+@@ -1554,7 +1408,7 @@ enum i40e_status_code i40e_aq_set_phy_config(struct i40e_hw *hw,
+ return status;
+ }
+
+-static noinline_for_stack enum i40e_status_code
++static noinline_for_stack int
+ i40e_set_fc_status(struct i40e_hw *hw,
+ struct i40e_aq_get_phy_abilities_resp *abilities,
+ bool atomic_restart)
+@@ -1612,11 +1466,11 @@ i40e_set_fc_status(struct i40e_hw *hw,
+ *
+ * Set the requested flow control mode using set_phy_config.
+ **/
+-enum i40e_status_code i40e_set_fc(struct i40e_hw *hw, u8 *aq_failures,
+- bool atomic_restart)
++int i40e_set_fc(struct i40e_hw *hw, u8 *aq_failures,
++ bool atomic_restart)
+ {
+ struct i40e_aq_get_phy_abilities_resp abilities;
+- enum i40e_status_code status;
++ int status;
+
+ *aq_failures = 0x0;
+
+@@ -1655,13 +1509,13 @@ enum i40e_status_code i40e_set_fc(struct i40e_hw *hw, u8 *aq_failures,
+ *
+ * Tell the firmware that the driver is taking over from PXE
+ **/
+-i40e_status i40e_aq_clear_pxe_mode(struct i40e_hw *hw,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_clear_pxe_mode(struct i40e_hw *hw,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+- i40e_status status;
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_clear_pxe *cmd =
+ (struct i40e_aqc_clear_pxe *)&desc.params.raw;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_clear_pxe_mode);
+@@ -1683,14 +1537,14 @@ i40e_status i40e_aq_clear_pxe_mode(struct i40e_hw *hw,
+ *
+ * Sets up the link and restarts the Auto-Negotiation over the link.
+ **/
+-i40e_status i40e_aq_set_link_restart_an(struct i40e_hw *hw,
+- bool enable_link,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_set_link_restart_an(struct i40e_hw *hw,
++ bool enable_link,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_set_link_restart_an *cmd =
+ (struct i40e_aqc_set_link_restart_an *)&desc.params.raw;
+- i40e_status status;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_set_link_restart_an);
+@@ -1715,17 +1569,17 @@ i40e_status i40e_aq_set_link_restart_an(struct i40e_hw *hw,
+ *
+ * Returns the link status of the adapter.
+ **/
+-i40e_status i40e_aq_get_link_info(struct i40e_hw *hw,
+- bool enable_lse, struct i40e_link_status *link,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_get_link_info(struct i40e_hw *hw,
++ bool enable_lse, struct i40e_link_status *link,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_get_link_status *resp =
+ (struct i40e_aqc_get_link_status *)&desc.params.raw;
+ struct i40e_link_status *hw_link_info = &hw->phy.link_info;
+- i40e_status status;
+ bool tx_pause, rx_pause;
+ u16 command_flags;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_get_link_status);
+
+@@ -1811,14 +1665,14 @@ aq_get_link_info_exit:
+ *
+ * Set link interrupt mask.
+ **/
+-i40e_status i40e_aq_set_phy_int_mask(struct i40e_hw *hw,
+- u16 mask,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_set_phy_int_mask(struct i40e_hw *hw,
++ u16 mask,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_set_phy_int_mask *cmd =
+ (struct i40e_aqc_set_phy_int_mask *)&desc.params.raw;
+- i40e_status status;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_set_phy_int_mask);
+@@ -1838,8 +1692,8 @@ i40e_status i40e_aq_set_phy_int_mask(struct i40e_hw *hw,
+ *
+ * Enable/disable loopback on a given port
+ */
+-i40e_status i40e_aq_set_mac_loopback(struct i40e_hw *hw, bool ena_lpbk,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_set_mac_loopback(struct i40e_hw *hw, bool ena_lpbk,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_set_lb_mode *cmd =
+@@ -1864,13 +1718,13 @@ i40e_status i40e_aq_set_mac_loopback(struct i40e_hw *hw, bool ena_lpbk,
+ *
+ * Reset the external PHY.
+ **/
+-i40e_status i40e_aq_set_phy_debug(struct i40e_hw *hw, u8 cmd_flags,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_set_phy_debug(struct i40e_hw *hw, u8 cmd_flags,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_set_phy_debug *cmd =
+ (struct i40e_aqc_set_phy_debug *)&desc.params.raw;
+- i40e_status status;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_set_phy_debug);
+@@ -1905,9 +1759,9 @@ static bool i40e_is_aq_api_ver_ge(struct i40e_adminq_info *aq, u16 maj,
+ *
+ * Add a VSI context to the hardware.
+ **/
+-i40e_status i40e_aq_add_vsi(struct i40e_hw *hw,
+- struct i40e_vsi_context *vsi_ctx,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_add_vsi(struct i40e_hw *hw,
++ struct i40e_vsi_context *vsi_ctx,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_add_get_update_vsi *cmd =
+@@ -1915,7 +1769,7 @@ i40e_status i40e_aq_add_vsi(struct i40e_hw *hw,
+ struct i40e_aqc_add_get_update_vsi_completion *resp =
+ (struct i40e_aqc_add_get_update_vsi_completion *)
+ &desc.params.raw;
+- i40e_status status;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_add_vsi);
+@@ -1949,15 +1803,15 @@ aq_add_vsi_exit:
+ * @seid: vsi number
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+-i40e_status i40e_aq_set_default_vsi(struct i40e_hw *hw,
+- u16 seid,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_set_default_vsi(struct i40e_hw *hw,
++ u16 seid,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
+ (struct i40e_aqc_set_vsi_promiscuous_modes *)
+ &desc.params.raw;
+- i40e_status status;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_set_vsi_promiscuous_modes);
+@@ -1977,15 +1831,15 @@ i40e_status i40e_aq_set_default_vsi(struct i40e_hw *hw,
+ * @seid: vsi number
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+-i40e_status i40e_aq_clear_default_vsi(struct i40e_hw *hw,
+- u16 seid,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_clear_default_vsi(struct i40e_hw *hw,
++ u16 seid,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
+ (struct i40e_aqc_set_vsi_promiscuous_modes *)
+ &desc.params.raw;
+- i40e_status status;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_set_vsi_promiscuous_modes);
+@@ -2007,16 +1861,16 @@ i40e_status i40e_aq_clear_default_vsi(struct i40e_hw *hw,
+ * @cmd_details: pointer to command details structure or NULL
+ * @rx_only_promisc: flag to decide if egress traffic gets mirrored in promisc
+ **/
+-i40e_status i40e_aq_set_vsi_unicast_promiscuous(struct i40e_hw *hw,
+- u16 seid, bool set,
+- struct i40e_asq_cmd_details *cmd_details,
+- bool rx_only_promisc)
++int i40e_aq_set_vsi_unicast_promiscuous(struct i40e_hw *hw,
++ u16 seid, bool set,
++ struct i40e_asq_cmd_details *cmd_details,
++ bool rx_only_promisc)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
+ (struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
+- i40e_status status;
+ u16 flags = 0;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_set_vsi_promiscuous_modes);
+@@ -2047,14 +1901,15 @@ i40e_status i40e_aq_set_vsi_unicast_promiscuous(struct i40e_hw *hw,
+ * @set: set multicast promiscuous enable/disable
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+-i40e_status i40e_aq_set_vsi_multicast_promiscuous(struct i40e_hw *hw,
+- u16 seid, bool set, struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_set_vsi_multicast_promiscuous(struct i40e_hw *hw,
++ u16 seid, bool set,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
+ (struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
+- i40e_status status;
+ u16 flags = 0;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_set_vsi_promiscuous_modes);
+@@ -2080,16 +1935,16 @@ i40e_status i40e_aq_set_vsi_multicast_promiscuous(struct i40e_hw *hw,
+ * @vid: The VLAN tag filter - capture any multicast packet with this VLAN tag
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+-enum i40e_status_code i40e_aq_set_vsi_mc_promisc_on_vlan(struct i40e_hw *hw,
+- u16 seid, bool enable,
+- u16 vid,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_set_vsi_mc_promisc_on_vlan(struct i40e_hw *hw,
++ u16 seid, bool enable,
++ u16 vid,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
+ (struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
+- enum i40e_status_code status;
+ u16 flags = 0;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_set_vsi_promiscuous_modes);
+@@ -2116,16 +1971,16 @@ enum i40e_status_code i40e_aq_set_vsi_mc_promisc_on_vlan(struct i40e_hw *hw,
+ * @vid: The VLAN tag filter - capture any unicast packet with this VLAN tag
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+-enum i40e_status_code i40e_aq_set_vsi_uc_promisc_on_vlan(struct i40e_hw *hw,
+- u16 seid, bool enable,
+- u16 vid,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_set_vsi_uc_promisc_on_vlan(struct i40e_hw *hw,
++ u16 seid, bool enable,
++ u16 vid,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
+ (struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
+- enum i40e_status_code status;
+ u16 flags = 0;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_set_vsi_promiscuous_modes);
+@@ -2158,15 +2013,15 @@ enum i40e_status_code i40e_aq_set_vsi_uc_promisc_on_vlan(struct i40e_hw *hw,
+ * @vid: The VLAN tag filter - capture any broadcast packet with this VLAN tag
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+-i40e_status i40e_aq_set_vsi_bc_promisc_on_vlan(struct i40e_hw *hw,
+- u16 seid, bool enable, u16 vid,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_set_vsi_bc_promisc_on_vlan(struct i40e_hw *hw,
++ u16 seid, bool enable, u16 vid,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
+ (struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
+- i40e_status status;
+ u16 flags = 0;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_set_vsi_promiscuous_modes);
+@@ -2193,14 +2048,14 @@ i40e_status i40e_aq_set_vsi_bc_promisc_on_vlan(struct i40e_hw *hw,
+ *
+ * Set or clear the broadcast promiscuous flag (filter) for a given VSI.
+ **/
+-i40e_status i40e_aq_set_vsi_broadcast(struct i40e_hw *hw,
+- u16 seid, bool set_filter,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_set_vsi_broadcast(struct i40e_hw *hw,
++ u16 seid, bool set_filter,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
+ (struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
+- i40e_status status;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_set_vsi_promiscuous_modes);
+@@ -2226,15 +2081,15 @@ i40e_status i40e_aq_set_vsi_broadcast(struct i40e_hw *hw,
+ * @enable: set MAC L2 layer unicast promiscuous enable/disable for a given VLAN
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+-i40e_status i40e_aq_set_vsi_vlan_promisc(struct i40e_hw *hw,
+- u16 seid, bool enable,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_set_vsi_vlan_promisc(struct i40e_hw *hw,
++ u16 seid, bool enable,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
+ (struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
+- i40e_status status;
+ u16 flags = 0;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_set_vsi_promiscuous_modes);
+@@ -2256,9 +2111,9 @@ i40e_status i40e_aq_set_vsi_vlan_promisc(struct i40e_hw *hw,
+ * @vsi_ctx: pointer to a vsi context struct
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+-i40e_status i40e_aq_get_vsi_params(struct i40e_hw *hw,
+- struct i40e_vsi_context *vsi_ctx,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_get_vsi_params(struct i40e_hw *hw,
++ struct i40e_vsi_context *vsi_ctx,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_add_get_update_vsi *cmd =
+@@ -2266,7 +2121,7 @@ i40e_status i40e_aq_get_vsi_params(struct i40e_hw *hw,
+ struct i40e_aqc_add_get_update_vsi_completion *resp =
+ (struct i40e_aqc_add_get_update_vsi_completion *)
+ &desc.params.raw;
+- i40e_status status;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_get_vsi_parameters);
+@@ -2298,9 +2153,9 @@ aq_get_vsi_params_exit:
+ *
+ * Update a VSI context.
+ **/
+-i40e_status i40e_aq_update_vsi_params(struct i40e_hw *hw,
+- struct i40e_vsi_context *vsi_ctx,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_update_vsi_params(struct i40e_hw *hw,
++ struct i40e_vsi_context *vsi_ctx,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_add_get_update_vsi *cmd =
+@@ -2308,7 +2163,7 @@ i40e_status i40e_aq_update_vsi_params(struct i40e_hw *hw,
+ struct i40e_aqc_add_get_update_vsi_completion *resp =
+ (struct i40e_aqc_add_get_update_vsi_completion *)
+ &desc.params.raw;
+- i40e_status status;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_update_vsi_parameters);
+@@ -2336,15 +2191,15 @@ i40e_status i40e_aq_update_vsi_params(struct i40e_hw *hw,
+ *
+ * Fill the buf with switch configuration returned from AdminQ command
+ **/
+-i40e_status i40e_aq_get_switch_config(struct i40e_hw *hw,
+- struct i40e_aqc_get_switch_config_resp *buf,
+- u16 buf_size, u16 *start_seid,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_get_switch_config(struct i40e_hw *hw,
++ struct i40e_aqc_get_switch_config_resp *buf,
++ u16 buf_size, u16 *start_seid,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_switch_seid *scfg =
+ (struct i40e_aqc_switch_seid *)&desc.params.raw;
+- i40e_status status;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_get_switch_config);
+@@ -2370,15 +2225,15 @@ i40e_status i40e_aq_get_switch_config(struct i40e_hw *hw,
+ *
+ * Set switch configuration bits
+ **/
+-enum i40e_status_code i40e_aq_set_switch_config(struct i40e_hw *hw,
+- u16 flags,
+- u16 valid_flags, u8 mode,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_set_switch_config(struct i40e_hw *hw,
++ u16 flags,
++ u16 valid_flags, u8 mode,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_set_switch_config *scfg =
+ (struct i40e_aqc_set_switch_config *)&desc.params.raw;
+- enum i40e_status_code status;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_set_switch_config);
+@@ -2407,16 +2262,16 @@ enum i40e_status_code i40e_aq_set_switch_config(struct i40e_hw *hw,
+ *
+ * Get the firmware version from the admin queue commands
+ **/
+-i40e_status i40e_aq_get_firmware_version(struct i40e_hw *hw,
+- u16 *fw_major_version, u16 *fw_minor_version,
+- u32 *fw_build,
+- u16 *api_major_version, u16 *api_minor_version,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_get_firmware_version(struct i40e_hw *hw,
++ u16 *fw_major_version, u16 *fw_minor_version,
++ u32 *fw_build,
++ u16 *api_major_version, u16 *api_minor_version,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_get_version *resp =
+ (struct i40e_aqc_get_version *)&desc.params.raw;
+- i40e_status status;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_get_version);
+
+@@ -2446,14 +2301,14 @@ i40e_status i40e_aq_get_firmware_version(struct i40e_hw *hw,
+ *
+ * Send the driver version to the firmware
+ **/
+-i40e_status i40e_aq_send_driver_version(struct i40e_hw *hw,
++int i40e_aq_send_driver_version(struct i40e_hw *hw,
+ struct i40e_driver_version *dv,
+ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_driver_version *cmd =
+ (struct i40e_aqc_driver_version *)&desc.params.raw;
+- i40e_status status;
++ int status;
+ u16 len;
+
+ if (dv == NULL)
+@@ -2488,9 +2343,9 @@ i40e_status i40e_aq_send_driver_version(struct i40e_hw *hw,
+ *
+ * Side effect: LinkStatusEvent reporting becomes enabled
+ **/
+-i40e_status i40e_get_link_status(struct i40e_hw *hw, bool *link_up)
++int i40e_get_link_status(struct i40e_hw *hw, bool *link_up)
+ {
+- i40e_status status = 0;
++ int status = 0;
+
+ if (hw->phy.get_link_info) {
+ status = i40e_update_link_info(hw);
+@@ -2509,10 +2364,10 @@ i40e_status i40e_get_link_status(struct i40e_hw *hw, bool *link_up)
+ * i40e_update_link_info - update status of the HW network link
+ * @hw: pointer to the hw struct
+ **/
+-noinline_for_stack i40e_status i40e_update_link_info(struct i40e_hw *hw)
++noinline_for_stack int i40e_update_link_info(struct i40e_hw *hw)
+ {
+ struct i40e_aq_get_phy_abilities_resp abilities;
+- i40e_status status = 0;
++ int status = 0;
+
+ status = i40e_aq_get_link_info(hw, true, NULL, NULL);
+ if (status)
+@@ -2559,19 +2414,19 @@ noinline_for_stack i40e_status i40e_update_link_info(struct i40e_hw *hw)
+ * This asks the FW to add a VEB between the uplink and downlink
+ * elements. If the uplink SEID is 0, this will be a floating VEB.
+ **/
+-i40e_status i40e_aq_add_veb(struct i40e_hw *hw, u16 uplink_seid,
+- u16 downlink_seid, u8 enabled_tc,
+- bool default_port, u16 *veb_seid,
+- bool enable_stats,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_add_veb(struct i40e_hw *hw, u16 uplink_seid,
++ u16 downlink_seid, u8 enabled_tc,
++ bool default_port, u16 *veb_seid,
++ bool enable_stats,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_add_veb *cmd =
+ (struct i40e_aqc_add_veb *)&desc.params.raw;
+ struct i40e_aqc_add_veb_completion *resp =
+ (struct i40e_aqc_add_veb_completion *)&desc.params.raw;
+- i40e_status status;
+ u16 veb_flags = 0;
++ int status;
+
+ /* SEIDs need to either both be set or both be 0 for floating VEB */
+ if (!!uplink_seid != !!downlink_seid)
+@@ -2617,17 +2472,17 @@ i40e_status i40e_aq_add_veb(struct i40e_hw *hw, u16 uplink_seid,
+ * This retrieves the parameters for a particular VEB, specified by
+ * uplink_seid, and returns them to the caller.
+ **/
+-i40e_status i40e_aq_get_veb_parameters(struct i40e_hw *hw,
+- u16 veb_seid, u16 *switch_id,
+- bool *floating, u16 *statistic_index,
+- u16 *vebs_used, u16 *vebs_free,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_get_veb_parameters(struct i40e_hw *hw,
++ u16 veb_seid, u16 *switch_id,
++ bool *floating, u16 *statistic_index,
++ u16 *vebs_used, u16 *vebs_free,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_get_veb_parameters_completion *cmd_resp =
+ (struct i40e_aqc_get_veb_parameters_completion *)
+ &desc.params.raw;
+- i40e_status status;
++ int status;
+
+ if (veb_seid == 0)
+ return I40E_ERR_PARAM;
+@@ -2711,7 +2566,7 @@ i40e_prepare_add_macvlan(struct i40e_aqc_add_macvlan_element_data *mv_list,
+ *
+ * Add MAC/VLAN addresses to the HW filtering
+ **/
+-i40e_status
++int
+ i40e_aq_add_macvlan(struct i40e_hw *hw, u16 seid,
+ struct i40e_aqc_add_macvlan_element_data *mv_list,
+ u16 count, struct i40e_asq_cmd_details *cmd_details)
+@@ -2743,7 +2598,7 @@ i40e_aq_add_macvlan(struct i40e_hw *hw, u16 seid,
+ * It also calls _v2 versions of asq_send_command functions to
+ * get the aq_status on the stack.
+ **/
+-i40e_status
++int
+ i40e_aq_add_macvlan_v2(struct i40e_hw *hw, u16 seid,
+ struct i40e_aqc_add_macvlan_element_data *mv_list,
+ u16 count, struct i40e_asq_cmd_details *cmd_details,
+@@ -2771,15 +2626,16 @@ i40e_aq_add_macvlan_v2(struct i40e_hw *hw, u16 seid,
+ *
+ * Remove MAC/VLAN addresses from the HW filtering
+ **/
+-i40e_status i40e_aq_remove_macvlan(struct i40e_hw *hw, u16 seid,
+- struct i40e_aqc_remove_macvlan_element_data *mv_list,
+- u16 count, struct i40e_asq_cmd_details *cmd_details)
++int
++i40e_aq_remove_macvlan(struct i40e_hw *hw, u16 seid,
++ struct i40e_aqc_remove_macvlan_element_data *mv_list,
++ u16 count, struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_macvlan *cmd =
+ (struct i40e_aqc_macvlan *)&desc.params.raw;
+- i40e_status status;
+ u16 buf_size;
++ int status;
+
+ if (count == 0 || !mv_list || !hw)
+ return I40E_ERR_PARAM;
+@@ -2818,7 +2674,7 @@ i40e_status i40e_aq_remove_macvlan(struct i40e_hw *hw, u16 seid,
+ * It also calls _v2 versions of asq_send_command functions to
+ * get the aq_status on the stack.
+ **/
+-i40e_status
++int
+ i40e_aq_remove_macvlan_v2(struct i40e_hw *hw, u16 seid,
+ struct i40e_aqc_remove_macvlan_element_data *mv_list,
+ u16 count, struct i40e_asq_cmd_details *cmd_details,
+@@ -2866,19 +2722,19 @@ i40e_aq_remove_macvlan_v2(struct i40e_hw *hw, u16 seid,
+ * Add/Delete a mirror rule to a specific switch. Mirror rules are supported for
+ * VEBs/VEPA elements only
+ **/
+-static i40e_status i40e_mirrorrule_op(struct i40e_hw *hw,
+- u16 opcode, u16 sw_seid, u16 rule_type, u16 id,
+- u16 count, __le16 *mr_list,
+- struct i40e_asq_cmd_details *cmd_details,
+- u16 *rule_id, u16 *rules_used, u16 *rules_free)
++static int i40e_mirrorrule_op(struct i40e_hw *hw,
++ u16 opcode, u16 sw_seid, u16 rule_type, u16 id,
++ u16 count, __le16 *mr_list,
++ struct i40e_asq_cmd_details *cmd_details,
++ u16 *rule_id, u16 *rules_used, u16 *rules_free)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_add_delete_mirror_rule *cmd =
+ (struct i40e_aqc_add_delete_mirror_rule *)&desc.params.raw;
+ struct i40e_aqc_add_delete_mirror_rule_completion *resp =
+ (struct i40e_aqc_add_delete_mirror_rule_completion *)&desc.params.raw;
+- i40e_status status;
+ u16 buf_size;
++ int status;
+
+ buf_size = count * sizeof(*mr_list);
+
+@@ -2926,10 +2782,11 @@ static i40e_status i40e_mirrorrule_op(struct i40e_hw *hw,
+ *
+ * Add mirror rule. Mirror rules are supported for VEBs or VEPA elements only
+ **/
+-i40e_status i40e_aq_add_mirrorrule(struct i40e_hw *hw, u16 sw_seid,
+- u16 rule_type, u16 dest_vsi, u16 count, __le16 *mr_list,
+- struct i40e_asq_cmd_details *cmd_details,
+- u16 *rule_id, u16 *rules_used, u16 *rules_free)
++int i40e_aq_add_mirrorrule(struct i40e_hw *hw, u16 sw_seid,
++ u16 rule_type, u16 dest_vsi, u16 count,
++ __le16 *mr_list,
++ struct i40e_asq_cmd_details *cmd_details,
++ u16 *rule_id, u16 *rules_used, u16 *rules_free)
+ {
+ if (!(rule_type == I40E_AQC_MIRROR_RULE_TYPE_ALL_INGRESS ||
+ rule_type == I40E_AQC_MIRROR_RULE_TYPE_ALL_EGRESS)) {
+@@ -2957,10 +2814,11 @@ i40e_status i40e_aq_add_mirrorrule(struct i40e_hw *hw, u16 sw_seid,
+ *
+ * Delete a mirror rule. Mirror rules are supported for VEBs/VEPA elements only
+ **/
+-i40e_status i40e_aq_delete_mirrorrule(struct i40e_hw *hw, u16 sw_seid,
+- u16 rule_type, u16 rule_id, u16 count, __le16 *mr_list,
+- struct i40e_asq_cmd_details *cmd_details,
+- u16 *rules_used, u16 *rules_free)
++int i40e_aq_delete_mirrorrule(struct i40e_hw *hw, u16 sw_seid,
++ u16 rule_type, u16 rule_id, u16 count,
++ __le16 *mr_list,
++ struct i40e_asq_cmd_details *cmd_details,
++ u16 *rules_used, u16 *rules_free)
+ {
+ /* Rule ID has to be valid except rule_type: INGRESS VLAN mirroring */
+ if (rule_type == I40E_AQC_MIRROR_RULE_TYPE_VLAN) {
+@@ -2989,14 +2847,14 @@ i40e_status i40e_aq_delete_mirrorrule(struct i40e_hw *hw, u16 sw_seid,
+ *
+ * send msg to vf
+ **/
+-i40e_status i40e_aq_send_msg_to_vf(struct i40e_hw *hw, u16 vfid,
+- u32 v_opcode, u32 v_retval, u8 *msg, u16 msglen,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_send_msg_to_vf(struct i40e_hw *hw, u16 vfid,
++ u32 v_opcode, u32 v_retval, u8 *msg, u16 msglen,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_pf_vf_message *cmd =
+ (struct i40e_aqc_pf_vf_message *)&desc.params.raw;
+- i40e_status status;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_send_msg_to_vf);
+ cmd->id = cpu_to_le32(vfid);
+@@ -3024,14 +2882,14 @@ i40e_status i40e_aq_send_msg_to_vf(struct i40e_hw *hw, u16 vfid,
+ *
+ * Read the register using the admin queue commands
+ **/
+-i40e_status i40e_aq_debug_read_register(struct i40e_hw *hw,
++int i40e_aq_debug_read_register(struct i40e_hw *hw,
+ u32 reg_addr, u64 *reg_val,
+ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_debug_reg_read_write *cmd_resp =
+ (struct i40e_aqc_debug_reg_read_write *)&desc.params.raw;
+- i40e_status status;
++ int status;
+
+ if (reg_val == NULL)
+ return I40E_ERR_PARAM;
+@@ -3059,14 +2917,14 @@ i40e_status i40e_aq_debug_read_register(struct i40e_hw *hw,
+ *
+ * Write to a register using the admin queue commands
+ **/
+-i40e_status i40e_aq_debug_write_register(struct i40e_hw *hw,
+- u32 reg_addr, u64 reg_val,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_debug_write_register(struct i40e_hw *hw,
++ u32 reg_addr, u64 reg_val,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_debug_reg_read_write *cmd =
+ (struct i40e_aqc_debug_reg_read_write *)&desc.params.raw;
+- i40e_status status;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_debug_write_reg);
+
+@@ -3090,16 +2948,16 @@ i40e_status i40e_aq_debug_write_register(struct i40e_hw *hw,
+ *
+ * requests common resource using the admin queue commands
+ **/
+-i40e_status i40e_aq_request_resource(struct i40e_hw *hw,
+- enum i40e_aq_resources_ids resource,
+- enum i40e_aq_resource_access_type access,
+- u8 sdp_number, u64 *timeout,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_request_resource(struct i40e_hw *hw,
++ enum i40e_aq_resources_ids resource,
++ enum i40e_aq_resource_access_type access,
++ u8 sdp_number, u64 *timeout,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_request_resource *cmd_resp =
+ (struct i40e_aqc_request_resource *)&desc.params.raw;
+- i40e_status status;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_request_resource);
+
+@@ -3129,15 +2987,15 @@ i40e_status i40e_aq_request_resource(struct i40e_hw *hw,
+ *
+ * release common resource using the admin queue commands
+ **/
+-i40e_status i40e_aq_release_resource(struct i40e_hw *hw,
+- enum i40e_aq_resources_ids resource,
+- u8 sdp_number,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_release_resource(struct i40e_hw *hw,
++ enum i40e_aq_resources_ids resource,
++ u8 sdp_number,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_request_resource *cmd =
+ (struct i40e_aqc_request_resource *)&desc.params.raw;
+- i40e_status status;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_release_resource);
+
+@@ -3161,15 +3019,15 @@ i40e_status i40e_aq_release_resource(struct i40e_hw *hw,
+ *
+ * Read the NVM using the admin queue commands
+ **/
+-i40e_status i40e_aq_read_nvm(struct i40e_hw *hw, u8 module_pointer,
+- u32 offset, u16 length, void *data,
+- bool last_command,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_read_nvm(struct i40e_hw *hw, u8 module_pointer,
++ u32 offset, u16 length, void *data,
++ bool last_command,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_nvm_update *cmd =
+ (struct i40e_aqc_nvm_update *)&desc.params.raw;
+- i40e_status status;
++ int status;
+
+ /* In offset the highest byte must be zeroed. */
+ if (offset & 0xFF000000) {
+@@ -3207,14 +3065,14 @@ i40e_aq_read_nvm_exit:
+ *
+ * Erase the NVM sector using the admin queue commands
+ **/
+-i40e_status i40e_aq_erase_nvm(struct i40e_hw *hw, u8 module_pointer,
+- u32 offset, u16 length, bool last_command,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_erase_nvm(struct i40e_hw *hw, u8 module_pointer,
++ u32 offset, u16 length, bool last_command,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_nvm_update *cmd =
+ (struct i40e_aqc_nvm_update *)&desc.params.raw;
+- i40e_status status;
++ int status;
+
+ /* In offset the highest byte must be zeroed. */
+ if (offset & 0xFF000000) {
+@@ -3255,8 +3113,8 @@ static void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff,
+ u32 number, logical_id, phys_id;
+ struct i40e_hw_capabilities *p;
+ u16 id, ocp_cfg_word0;
+- i40e_status status;
+ u8 major_rev;
++ int status;
+ u32 i = 0;
+
+ cap = (struct i40e_aqc_list_capabilities_element_resp *) buff;
+@@ -3497,14 +3355,14 @@ static void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff,
+ *
+ * Get the device capabilities descriptions from the firmware
+ **/
+-i40e_status i40e_aq_discover_capabilities(struct i40e_hw *hw,
+- void *buff, u16 buff_size, u16 *data_size,
+- enum i40e_admin_queue_opc list_type_opc,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_discover_capabilities(struct i40e_hw *hw,
++ void *buff, u16 buff_size, u16 *data_size,
++ enum i40e_admin_queue_opc list_type_opc,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aqc_list_capabilites *cmd;
+ struct i40e_aq_desc desc;
+- i40e_status status = 0;
++ int status = 0;
+
+ cmd = (struct i40e_aqc_list_capabilites *)&desc.params.raw;
+
+@@ -3546,15 +3404,15 @@ exit:
+ *
+ * Update the NVM using the admin queue commands
+ **/
+-i40e_status i40e_aq_update_nvm(struct i40e_hw *hw, u8 module_pointer,
+- u32 offset, u16 length, void *data,
+- bool last_command, u8 preservation_flags,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_update_nvm(struct i40e_hw *hw, u8 module_pointer,
++ u32 offset, u16 length, void *data,
++ bool last_command, u8 preservation_flags,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_nvm_update *cmd =
+ (struct i40e_aqc_nvm_update *)&desc.params.raw;
+- i40e_status status;
++ int status;
+
+ /* In offset the highest byte must be zeroed. */
+ if (offset & 0xFF000000) {
+@@ -3599,13 +3457,13 @@ i40e_aq_update_nvm_exit:
+ *
+ * Rearrange NVM structure, available only for transition FW
+ **/
+-i40e_status i40e_aq_rearrange_nvm(struct i40e_hw *hw,
+- u8 rearrange_nvm,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_rearrange_nvm(struct i40e_hw *hw,
++ u8 rearrange_nvm,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aqc_nvm_update *cmd;
+- i40e_status status;
+ struct i40e_aq_desc desc;
++ int status;
+
+ cmd = (struct i40e_aqc_nvm_update *)&desc.params.raw;
+
+@@ -3639,17 +3497,17 @@ i40e_aq_rearrange_nvm_exit:
+ *
+ * Requests the complete LLDP MIB (entire packet).
+ **/
+-i40e_status i40e_aq_get_lldp_mib(struct i40e_hw *hw, u8 bridge_type,
+- u8 mib_type, void *buff, u16 buff_size,
+- u16 *local_len, u16 *remote_len,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_get_lldp_mib(struct i40e_hw *hw, u8 bridge_type,
++ u8 mib_type, void *buff, u16 buff_size,
++ u16 *local_len, u16 *remote_len,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_lldp_get_mib *cmd =
+ (struct i40e_aqc_lldp_get_mib *)&desc.params.raw;
+ struct i40e_aqc_lldp_get_mib *resp =
+ (struct i40e_aqc_lldp_get_mib *)&desc.params.raw;
+- i40e_status status;
++ int status;
+
+ if (buff_size == 0 || !buff)
+ return I40E_ERR_PARAM;
+@@ -3689,14 +3547,14 @@ i40e_status i40e_aq_get_lldp_mib(struct i40e_hw *hw, u8 bridge_type,
+ *
+ * Set the LLDP MIB.
+ **/
+-enum i40e_status_code
++int
+ i40e_aq_set_lldp_mib(struct i40e_hw *hw,
+ u8 mib_type, void *buff, u16 buff_size,
+ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aqc_lldp_set_local_mib *cmd;
+- enum i40e_status_code status;
+ struct i40e_aq_desc desc;
++ int status;
+
+ cmd = (struct i40e_aqc_lldp_set_local_mib *)&desc.params.raw;
+ if (buff_size == 0 || !buff)
+@@ -3728,14 +3586,14 @@ i40e_aq_set_lldp_mib(struct i40e_hw *hw,
+ * Enable or Disable posting of an event on ARQ when LLDP MIB
+ * associated with the interface changes
+ **/
+-i40e_status i40e_aq_cfg_lldp_mib_change_event(struct i40e_hw *hw,
+- bool enable_update,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_cfg_lldp_mib_change_event(struct i40e_hw *hw,
++ bool enable_update,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_lldp_update_mib *cmd =
+ (struct i40e_aqc_lldp_update_mib *)&desc.params.raw;
+- i40e_status status;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_update_mib);
+
+@@ -3757,14 +3615,14 @@ i40e_status i40e_aq_cfg_lldp_mib_change_event(struct i40e_hw *hw,
+ * Restore LLDP Agent factory settings if @restore set to True. In other case
+ * only returns factory setting in AQ response.
+ **/
+-enum i40e_status_code
++int
+ i40e_aq_restore_lldp(struct i40e_hw *hw, u8 *setting, bool restore,
+ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_lldp_restore *cmd =
+ (struct i40e_aqc_lldp_restore *)&desc.params.raw;
+- i40e_status status;
++ int status;
+
+ if (!(hw->flags & I40E_HW_FLAG_FW_LLDP_PERSISTENT)) {
+ i40e_debug(hw, I40E_DEBUG_ALL,
+@@ -3794,14 +3652,14 @@ i40e_aq_restore_lldp(struct i40e_hw *hw, u8 *setting, bool restore,
+ *
+ * Stop or Shutdown the embedded LLDP Agent
+ **/
+-i40e_status i40e_aq_stop_lldp(struct i40e_hw *hw, bool shutdown_agent,
+- bool persist,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_stop_lldp(struct i40e_hw *hw, bool shutdown_agent,
++ bool persist,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_lldp_stop *cmd =
+ (struct i40e_aqc_lldp_stop *)&desc.params.raw;
+- i40e_status status;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_stop);
+
+@@ -3829,13 +3687,13 @@ i40e_status i40e_aq_stop_lldp(struct i40e_hw *hw, bool shutdown_agent,
+ *
+ * Start the embedded LLDP Agent on all ports.
+ **/
+-i40e_status i40e_aq_start_lldp(struct i40e_hw *hw, bool persist,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_start_lldp(struct i40e_hw *hw, bool persist,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_lldp_start *cmd =
+ (struct i40e_aqc_lldp_start *)&desc.params.raw;
+- i40e_status status;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_start);
+
+@@ -3861,14 +3719,14 @@ i40e_status i40e_aq_start_lldp(struct i40e_hw *hw, bool persist,
+ * @dcb_enable: True if DCB configuration needs to be applied
+ *
+ **/
+-enum i40e_status_code
++int
+ i40e_aq_set_dcb_parameters(struct i40e_hw *hw, bool dcb_enable,
+ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_set_dcb_parameters *cmd =
+ (struct i40e_aqc_set_dcb_parameters *)&desc.params.raw;
+- i40e_status status;
++ int status;
+
+ if (!(hw->flags & I40E_HW_FLAG_FW_LLDP_STOPPABLE))
+ return I40E_ERR_DEVICE_NOT_SUPPORTED;
+@@ -3894,12 +3752,12 @@ i40e_aq_set_dcb_parameters(struct i40e_hw *hw, bool dcb_enable,
+ *
+ * Get CEE DCBX mode operational configuration from firmware
+ **/
+-i40e_status i40e_aq_get_cee_dcb_config(struct i40e_hw *hw,
+- void *buff, u16 buff_size,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_get_cee_dcb_config(struct i40e_hw *hw,
++ void *buff, u16 buff_size,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+- i40e_status status;
++ int status;
+
+ if (buff_size == 0 || !buff)
+ return I40E_ERR_PARAM;
+@@ -3925,17 +3783,17 @@ i40e_status i40e_aq_get_cee_dcb_config(struct i40e_hw *hw,
+ * and this function will call cpu_to_le16 to convert from Host byte order to
+ * Little Endian order.
+ **/
+-i40e_status i40e_aq_add_udp_tunnel(struct i40e_hw *hw,
+- u16 udp_port, u8 protocol_index,
+- u8 *filter_index,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_add_udp_tunnel(struct i40e_hw *hw,
++ u16 udp_port, u8 protocol_index,
++ u8 *filter_index,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_add_udp_tunnel *cmd =
+ (struct i40e_aqc_add_udp_tunnel *)&desc.params.raw;
+ struct i40e_aqc_del_udp_tunnel_completion *resp =
+ (struct i40e_aqc_del_udp_tunnel_completion *)&desc.params.raw;
+- i40e_status status;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_udp_tunnel);
+
+@@ -3956,13 +3814,13 @@ i40e_status i40e_aq_add_udp_tunnel(struct i40e_hw *hw,
+ * @index: filter index
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+-i40e_status i40e_aq_del_udp_tunnel(struct i40e_hw *hw, u8 index,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_del_udp_tunnel(struct i40e_hw *hw, u8 index,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_remove_udp_tunnel *cmd =
+ (struct i40e_aqc_remove_udp_tunnel *)&desc.params.raw;
+- i40e_status status;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_del_udp_tunnel);
+
+@@ -3981,13 +3839,13 @@ i40e_status i40e_aq_del_udp_tunnel(struct i40e_hw *hw, u8 index,
+ *
+ * This deletes a switch element from the switch.
+ **/
+-i40e_status i40e_aq_delete_element(struct i40e_hw *hw, u16 seid,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_delete_element(struct i40e_hw *hw, u16 seid,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_switch_seid *cmd =
+ (struct i40e_aqc_switch_seid *)&desc.params.raw;
+- i40e_status status;
++ int status;
+
+ if (seid == 0)
+ return I40E_ERR_PARAM;
+@@ -4011,11 +3869,11 @@ i40e_status i40e_aq_delete_element(struct i40e_hw *hw, u16 seid,
+ * recomputed and modified. The retval field in the descriptor
+ * will be set to 0 when RPB is modified.
+ **/
+-i40e_status i40e_aq_dcb_updated(struct i40e_hw *hw,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_dcb_updated(struct i40e_hw *hw,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+- i40e_status status;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_dcb_updated);
+
+@@ -4035,15 +3893,15 @@ i40e_status i40e_aq_dcb_updated(struct i40e_hw *hw,
+ *
+ * Generic command handler for Tx scheduler AQ commands
+ **/
+-static i40e_status i40e_aq_tx_sched_cmd(struct i40e_hw *hw, u16 seid,
++static int i40e_aq_tx_sched_cmd(struct i40e_hw *hw, u16 seid,
+ void *buff, u16 buff_size,
+- enum i40e_admin_queue_opc opcode,
++ enum i40e_admin_queue_opc opcode,
+ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_tx_sched_ind *cmd =
+ (struct i40e_aqc_tx_sched_ind *)&desc.params.raw;
+- i40e_status status;
++ int status;
+ bool cmd_param_flag = false;
+
+ switch (opcode) {
+@@ -4093,14 +3951,14 @@ static i40e_status i40e_aq_tx_sched_cmd(struct i40e_hw *hw, u16 seid,
+ * @max_credit: Max BW limit credits
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+-i40e_status i40e_aq_config_vsi_bw_limit(struct i40e_hw *hw,
++int i40e_aq_config_vsi_bw_limit(struct i40e_hw *hw,
+ u16 seid, u16 credit, u8 max_credit,
+ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_configure_vsi_bw_limit *cmd =
+ (struct i40e_aqc_configure_vsi_bw_limit *)&desc.params.raw;
+- i40e_status status;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_configure_vsi_bw_limit);
+@@ -4121,10 +3979,10 @@ i40e_status i40e_aq_config_vsi_bw_limit(struct i40e_hw *hw,
+ * @bw_data: Buffer holding enabled TCs, relative TC BW limit/credits
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+-i40e_status i40e_aq_config_vsi_tc_bw(struct i40e_hw *hw,
+- u16 seid,
+- struct i40e_aqc_configure_vsi_tc_bw_data *bw_data,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_config_vsi_tc_bw(struct i40e_hw *hw,
++ u16 seid,
++ struct i40e_aqc_configure_vsi_tc_bw_data *bw_data,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
+ i40e_aqc_opc_configure_vsi_tc_bw,
+@@ -4139,11 +3997,12 @@ i40e_status i40e_aq_config_vsi_tc_bw(struct i40e_hw *hw,
+ * @opcode: Tx scheduler AQ command opcode
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+-i40e_status i40e_aq_config_switch_comp_ets(struct i40e_hw *hw,
+- u16 seid,
+- struct i40e_aqc_configure_switching_comp_ets_data *ets_data,
+- enum i40e_admin_queue_opc opcode,
+- struct i40e_asq_cmd_details *cmd_details)
++int
++i40e_aq_config_switch_comp_ets(struct i40e_hw *hw,
++ u16 seid,
++ struct i40e_aqc_configure_switching_comp_ets_data *ets_data,
++ enum i40e_admin_queue_opc opcode,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ return i40e_aq_tx_sched_cmd(hw, seid, (void *)ets_data,
+ sizeof(*ets_data), opcode, cmd_details);
+@@ -4156,7 +4015,8 @@ i40e_status i40e_aq_config_switch_comp_ets(struct i40e_hw *hw,
+ * @bw_data: Buffer holding enabled TCs, relative/absolute TC BW limit/credits
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+-i40e_status i40e_aq_config_switch_comp_bw_config(struct i40e_hw *hw,
++int
++i40e_aq_config_switch_comp_bw_config(struct i40e_hw *hw,
+ u16 seid,
+ struct i40e_aqc_configure_switching_comp_bw_config_data *bw_data,
+ struct i40e_asq_cmd_details *cmd_details)
+@@ -4173,10 +4033,11 @@ i40e_status i40e_aq_config_switch_comp_bw_config(struct i40e_hw *hw,
+ * @bw_data: Buffer to hold VSI BW configuration
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+-i40e_status i40e_aq_query_vsi_bw_config(struct i40e_hw *hw,
+- u16 seid,
+- struct i40e_aqc_query_vsi_bw_config_resp *bw_data,
+- struct i40e_asq_cmd_details *cmd_details)
++int
++i40e_aq_query_vsi_bw_config(struct i40e_hw *hw,
++ u16 seid,
++ struct i40e_aqc_query_vsi_bw_config_resp *bw_data,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
+ i40e_aqc_opc_query_vsi_bw_config,
+@@ -4190,10 +4051,11 @@ i40e_status i40e_aq_query_vsi_bw_config(struct i40e_hw *hw,
+ * @bw_data: Buffer to hold VSI BW configuration per TC
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+-i40e_status i40e_aq_query_vsi_ets_sla_config(struct i40e_hw *hw,
+- u16 seid,
+- struct i40e_aqc_query_vsi_ets_sla_config_resp *bw_data,
+- struct i40e_asq_cmd_details *cmd_details)
++int
++i40e_aq_query_vsi_ets_sla_config(struct i40e_hw *hw,
++ u16 seid,
++ struct i40e_aqc_query_vsi_ets_sla_config_resp *bw_data,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
+ i40e_aqc_opc_query_vsi_ets_sla_config,
+@@ -4207,10 +4069,11 @@ i40e_status i40e_aq_query_vsi_ets_sla_config(struct i40e_hw *hw,
+ * @bw_data: Buffer to hold switching component's per TC BW config
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+-i40e_status i40e_aq_query_switch_comp_ets_config(struct i40e_hw *hw,
+- u16 seid,
+- struct i40e_aqc_query_switching_comp_ets_config_resp *bw_data,
+- struct i40e_asq_cmd_details *cmd_details)
++int
++i40e_aq_query_switch_comp_ets_config(struct i40e_hw *hw,
++ u16 seid,
++ struct i40e_aqc_query_switching_comp_ets_config_resp *bw_data,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
+ i40e_aqc_opc_query_switching_comp_ets_config,
+@@ -4224,10 +4087,11 @@ i40e_status i40e_aq_query_switch_comp_ets_config(struct i40e_hw *hw,
+ * @bw_data: Buffer to hold current ETS configuration for the Physical Port
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+-i40e_status i40e_aq_query_port_ets_config(struct i40e_hw *hw,
+- u16 seid,
+- struct i40e_aqc_query_port_ets_config_resp *bw_data,
+- struct i40e_asq_cmd_details *cmd_details)
++int
++i40e_aq_query_port_ets_config(struct i40e_hw *hw,
++ u16 seid,
++ struct i40e_aqc_query_port_ets_config_resp *bw_data,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
+ i40e_aqc_opc_query_port_ets_config,
+@@ -4241,10 +4105,11 @@ i40e_status i40e_aq_query_port_ets_config(struct i40e_hw *hw,
+ * @bw_data: Buffer to hold switching component's BW configuration
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+-i40e_status i40e_aq_query_switch_comp_bw_config(struct i40e_hw *hw,
+- u16 seid,
+- struct i40e_aqc_query_switching_comp_bw_config_resp *bw_data,
+- struct i40e_asq_cmd_details *cmd_details)
++int
++i40e_aq_query_switch_comp_bw_config(struct i40e_hw *hw,
++ u16 seid,
++ struct i40e_aqc_query_switching_comp_bw_config_resp *bw_data,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
+ i40e_aqc_opc_query_switching_comp_bw_config,
+@@ -4263,8 +4128,9 @@ i40e_status i40e_aq_query_switch_comp_bw_config(struct i40e_hw *hw,
+ * Returns 0 if the values passed are valid and within
+ * range else returns an error.
+ **/
+-static i40e_status i40e_validate_filter_settings(struct i40e_hw *hw,
+- struct i40e_filter_control_settings *settings)
++static int
++i40e_validate_filter_settings(struct i40e_hw *hw,
++ struct i40e_filter_control_settings *settings)
+ {
+ u32 fcoe_cntx_size, fcoe_filt_size;
+ u32 fcoe_fmax;
+@@ -4350,11 +4216,11 @@ static i40e_status i40e_validate_filter_settings(struct i40e_hw *hw,
+ * for a single PF. It is expected that these settings are programmed
+ * at the driver initialization time.
+ **/
+-i40e_status i40e_set_filter_control(struct i40e_hw *hw,
+- struct i40e_filter_control_settings *settings)
++int i40e_set_filter_control(struct i40e_hw *hw,
++ struct i40e_filter_control_settings *settings)
+ {
+- i40e_status ret = 0;
+ u32 hash_lut_size = 0;
++ int ret = 0;
+ u32 val;
+
+ if (!settings)
+@@ -4424,11 +4290,11 @@ i40e_status i40e_set_filter_control(struct i40e_hw *hw,
+ * In return it will update the total number of perfect filter count in
+ * the stats member.
+ **/
+-i40e_status i40e_aq_add_rem_control_packet_filter(struct i40e_hw *hw,
+- u8 *mac_addr, u16 ethtype, u16 flags,
+- u16 vsi_seid, u16 queue, bool is_add,
+- struct i40e_control_filter_stats *stats,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_add_rem_control_packet_filter(struct i40e_hw *hw,
++ u8 *mac_addr, u16 ethtype, u16 flags,
++ u16 vsi_seid, u16 queue, bool is_add,
++ struct i40e_control_filter_stats *stats,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_add_remove_control_packet_filter *cmd =
+@@ -4437,7 +4303,7 @@ i40e_status i40e_aq_add_rem_control_packet_filter(struct i40e_hw *hw,
+ struct i40e_aqc_add_remove_control_packet_filter_completion *resp =
+ (struct i40e_aqc_add_remove_control_packet_filter_completion *)
+ &desc.params.raw;
+- i40e_status status;
++ int status;
+
+ if (vsi_seid == 0)
+ return I40E_ERR_PARAM;
+@@ -4483,7 +4349,7 @@ void i40e_add_filter_to_drop_tx_flow_control_frames(struct i40e_hw *hw,
+ I40E_AQC_ADD_CONTROL_PACKET_FLAGS_DROP |
+ I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TX;
+ u16 ethtype = I40E_FLOW_CONTROL_ETHTYPE;
+- i40e_status status;
++ int status;
+
+ status = i40e_aq_add_rem_control_packet_filter(hw, NULL, ethtype, flag,
+ seid, 0, true, NULL,
+@@ -4505,14 +4371,14 @@ void i40e_add_filter_to_drop_tx_flow_control_frames(struct i40e_hw *hw,
+ * is not passed then only register at 'reg_addr0' is read.
+ *
+ **/
+-static i40e_status i40e_aq_alternate_read(struct i40e_hw *hw,
+- u32 reg_addr0, u32 *reg_val0,
+- u32 reg_addr1, u32 *reg_val1)
++static int i40e_aq_alternate_read(struct i40e_hw *hw,
++ u32 reg_addr0, u32 *reg_val0,
++ u32 reg_addr1, u32 *reg_val1)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_alternate_write *cmd_resp =
+ (struct i40e_aqc_alternate_write *)&desc.params.raw;
+- i40e_status status;
++ int status;
+
+ if (!reg_val0)
+ return I40E_ERR_PARAM;
+@@ -4541,12 +4407,12 @@ static i40e_status i40e_aq_alternate_read(struct i40e_hw *hw,
+ *
+ * Suspend port's Tx traffic
+ **/
+-i40e_status i40e_aq_suspend_port_tx(struct i40e_hw *hw, u16 seid,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_suspend_port_tx(struct i40e_hw *hw, u16 seid,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aqc_tx_sched_ind *cmd;
+ struct i40e_aq_desc desc;
+- i40e_status status;
++ int status;
+
+ cmd = (struct i40e_aqc_tx_sched_ind *)&desc.params.raw;
+ i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_suspend_port_tx);
+@@ -4563,11 +4429,11 @@ i40e_status i40e_aq_suspend_port_tx(struct i40e_hw *hw, u16 seid,
+ *
+ * Resume port's Tx traffic
+ **/
+-i40e_status i40e_aq_resume_port_tx(struct i40e_hw *hw,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_resume_port_tx(struct i40e_hw *hw,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+- i40e_status status;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_resume_port_tx);
+
+@@ -4637,18 +4503,18 @@ void i40e_set_pci_config_data(struct i40e_hw *hw, u16 link_status)
+ * Dump internal FW/HW data for debug purposes.
+ *
+ **/
+-i40e_status i40e_aq_debug_dump(struct i40e_hw *hw, u8 cluster_id,
+- u8 table_id, u32 start_index, u16 buff_size,
+- void *buff, u16 *ret_buff_size,
+- u8 *ret_next_table, u32 *ret_next_index,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_debug_dump(struct i40e_hw *hw, u8 cluster_id,
++ u8 table_id, u32 start_index, u16 buff_size,
++ void *buff, u16 *ret_buff_size,
++ u8 *ret_next_table, u32 *ret_next_index,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_debug_dump_internals *cmd =
+ (struct i40e_aqc_debug_dump_internals *)&desc.params.raw;
+ struct i40e_aqc_debug_dump_internals *resp =
+ (struct i40e_aqc_debug_dump_internals *)&desc.params.raw;
+- i40e_status status;
++ int status;
+
+ if (buff_size == 0 || !buff)
+ return I40E_ERR_PARAM;
+@@ -4689,12 +4555,12 @@ i40e_status i40e_aq_debug_dump(struct i40e_hw *hw, u8 cluster_id,
+ *
+ * Read bw from the alternate ram for the given pf
+ **/
+-i40e_status i40e_read_bw_from_alt_ram(struct i40e_hw *hw,
+- u32 *max_bw, u32 *min_bw,
+- bool *min_valid, bool *max_valid)
++int i40e_read_bw_from_alt_ram(struct i40e_hw *hw,
++ u32 *max_bw, u32 *min_bw,
++ bool *min_valid, bool *max_valid)
+ {
+- i40e_status status;
+ u32 max_bw_addr, min_bw_addr;
++ int status;
+
+ /* Calculate the address of the min/max bw registers */
+ max_bw_addr = I40E_ALT_STRUCT_FIRST_PF_OFFSET +
+@@ -4729,13 +4595,14 @@ i40e_status i40e_read_bw_from_alt_ram(struct i40e_hw *hw,
+ *
+ * Configure partitions guaranteed/max bw
+ **/
+-i40e_status i40e_aq_configure_partition_bw(struct i40e_hw *hw,
+- struct i40e_aqc_configure_partition_bw_data *bw_data,
+- struct i40e_asq_cmd_details *cmd_details)
++int
++i40e_aq_configure_partition_bw(struct i40e_hw *hw,
++ struct i40e_aqc_configure_partition_bw_data *bw_data,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+- i40e_status status;
+- struct i40e_aq_desc desc;
+ u16 bwd_size = sizeof(*bw_data);
++ struct i40e_aq_desc desc;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_configure_partition_bw);
+@@ -4764,11 +4631,11 @@ i40e_status i40e_aq_configure_partition_bw(struct i40e_hw *hw,
+ *
+ * Reads specified PHY register value
+ **/
+-i40e_status i40e_read_phy_register_clause22(struct i40e_hw *hw,
+- u16 reg, u8 phy_addr, u16 *value)
++int i40e_read_phy_register_clause22(struct i40e_hw *hw,
++ u16 reg, u8 phy_addr, u16 *value)
+ {
+- i40e_status status = I40E_ERR_TIMEOUT;
+ u8 port_num = (u8)hw->func_caps.mdio_port_num;
++ int status = I40E_ERR_TIMEOUT;
+ u32 command = 0;
+ u16 retry = 1000;
+
+@@ -4809,11 +4676,11 @@ i40e_status i40e_read_phy_register_clause22(struct i40e_hw *hw,
+ *
+ * Writes specified PHY register value
+ **/
+-i40e_status i40e_write_phy_register_clause22(struct i40e_hw *hw,
+- u16 reg, u8 phy_addr, u16 value)
++int i40e_write_phy_register_clause22(struct i40e_hw *hw,
++ u16 reg, u8 phy_addr, u16 value)
+ {
+- i40e_status status = I40E_ERR_TIMEOUT;
+ u8 port_num = (u8)hw->func_caps.mdio_port_num;
++ int status = I40E_ERR_TIMEOUT;
+ u32 command = 0;
+ u16 retry = 1000;
+
+@@ -4850,13 +4717,13 @@ i40e_status i40e_write_phy_register_clause22(struct i40e_hw *hw,
+ *
+ * Reads specified PHY register value
+ **/
+-i40e_status i40e_read_phy_register_clause45(struct i40e_hw *hw,
+- u8 page, u16 reg, u8 phy_addr, u16 *value)
++int i40e_read_phy_register_clause45(struct i40e_hw *hw,
++ u8 page, u16 reg, u8 phy_addr, u16 *value)
+ {
+- i40e_status status = I40E_ERR_TIMEOUT;
++ u8 port_num = hw->func_caps.mdio_port_num;
++ int status = I40E_ERR_TIMEOUT;
+ u32 command = 0;
+ u16 retry = 1000;
+- u8 port_num = hw->func_caps.mdio_port_num;
+
+ command = (reg << I40E_GLGEN_MSCA_MDIADD_SHIFT) |
+ (page << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
+@@ -4924,13 +4791,13 @@ phy_read_end:
+ *
+ * Writes value to specified PHY register
+ **/
+-i40e_status i40e_write_phy_register_clause45(struct i40e_hw *hw,
+- u8 page, u16 reg, u8 phy_addr, u16 value)
++int i40e_write_phy_register_clause45(struct i40e_hw *hw,
++ u8 page, u16 reg, u8 phy_addr, u16 value)
+ {
+- i40e_status status = I40E_ERR_TIMEOUT;
+- u32 command = 0;
+- u16 retry = 1000;
+ u8 port_num = hw->func_caps.mdio_port_num;
++ int status = I40E_ERR_TIMEOUT;
++ u16 retry = 1000;
++ u32 command = 0;
+
+ command = (reg << I40E_GLGEN_MSCA_MDIADD_SHIFT) |
+ (page << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
+@@ -4991,10 +4858,10 @@ phy_write_end:
+ *
+ * Writes value to specified PHY register
+ **/
+-i40e_status i40e_write_phy_register(struct i40e_hw *hw,
+- u8 page, u16 reg, u8 phy_addr, u16 value)
++int i40e_write_phy_register(struct i40e_hw *hw,
++ u8 page, u16 reg, u8 phy_addr, u16 value)
+ {
+- i40e_status status;
++ int status;
+
+ switch (hw->device_id) {
+ case I40E_DEV_ID_1G_BASE_T_X722:
+@@ -5030,10 +4897,10 @@ i40e_status i40e_write_phy_register(struct i40e_hw *hw,
+ *
+ * Reads specified PHY register value
+ **/
+-i40e_status i40e_read_phy_register(struct i40e_hw *hw,
+- u8 page, u16 reg, u8 phy_addr, u16 *value)
++int i40e_read_phy_register(struct i40e_hw *hw,
++ u8 page, u16 reg, u8 phy_addr, u16 *value)
+ {
+- i40e_status status;
++ int status;
+
+ switch (hw->device_id) {
+ case I40E_DEV_ID_1G_BASE_T_X722:
+@@ -5082,17 +4949,17 @@ u8 i40e_get_phy_address(struct i40e_hw *hw, u8 dev_num)
+ *
+ * Blinks PHY link LED
+ **/
+-i40e_status i40e_blink_phy_link_led(struct i40e_hw *hw,
+- u32 time, u32 interval)
++int i40e_blink_phy_link_led(struct i40e_hw *hw,
++ u32 time, u32 interval)
+ {
+- i40e_status status = 0;
+- u32 i;
+- u16 led_ctl;
+- u16 gpio_led_port;
+- u16 led_reg;
+ u16 led_addr = I40E_PHY_LED_PROV_REG_1;
++ u16 gpio_led_port;
+ u8 phy_addr = 0;
++ int status = 0;
++ u16 led_ctl;
+ u8 port_num;
++ u16 led_reg;
++ u32 i;
+
+ i = rd32(hw, I40E_PFGEN_PORTNUM);
+ port_num = (u8)(i & I40E_PFGEN_PORTNUM_PORT_NUM_MASK);
+@@ -5154,12 +5021,12 @@ phy_blinking_end:
+ * @led_addr: LED register address
+ * @reg_val: read register value
+ **/
+-static enum i40e_status_code i40e_led_get_reg(struct i40e_hw *hw, u16 led_addr,
+- u32 *reg_val)
++static int i40e_led_get_reg(struct i40e_hw *hw, u16 led_addr,
++ u32 *reg_val)
+ {
+- enum i40e_status_code status;
+ u8 phy_addr = 0;
+ u8 port_num;
++ int status;
+ u32 i;
+
+ *reg_val = 0;
+@@ -5188,12 +5055,12 @@ static enum i40e_status_code i40e_led_get_reg(struct i40e_hw *hw, u16 led_addr,
+ * @led_addr: LED register address
+ * @reg_val: register value to write
+ **/
+-static enum i40e_status_code i40e_led_set_reg(struct i40e_hw *hw, u16 led_addr,
+- u32 reg_val)
++static int i40e_led_set_reg(struct i40e_hw *hw, u16 led_addr,
++ u32 reg_val)
+ {
+- enum i40e_status_code status;
+ u8 phy_addr = 0;
+ u8 port_num;
++ int status;
+ u32 i;
+
+ if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE) {
+@@ -5223,17 +5090,17 @@ static enum i40e_status_code i40e_led_set_reg(struct i40e_hw *hw, u16 led_addr,
+ * @val: original value of register to use
+ *
+ **/
+-i40e_status i40e_led_get_phy(struct i40e_hw *hw, u16 *led_addr,
+- u16 *val)
++int i40e_led_get_phy(struct i40e_hw *hw, u16 *led_addr,
++ u16 *val)
+ {
+- i40e_status status = 0;
+ u16 gpio_led_port;
+ u8 phy_addr = 0;
+- u16 reg_val;
++ u32 reg_val_aq;
++ int status = 0;
+ u16 temp_addr;
++ u16 reg_val;
+ u8 port_num;
+ u32 i;
+- u32 reg_val_aq;
+
+ if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE) {
+ status =
+@@ -5278,12 +5145,12 @@ i40e_status i40e_led_get_phy(struct i40e_hw *hw, u16 *led_addr,
+ * Set led's on or off when controlled by the PHY
+ *
+ **/
+-i40e_status i40e_led_set_phy(struct i40e_hw *hw, bool on,
+- u16 led_addr, u32 mode)
++int i40e_led_set_phy(struct i40e_hw *hw, bool on,
++ u16 led_addr, u32 mode)
+ {
+- i40e_status status = 0;
+ u32 led_ctl = 0;
+ u32 led_reg = 0;
++ int status = 0;
+
+ status = i40e_led_get_reg(hw, led_addr, &led_reg);
+ if (status)
+@@ -5327,14 +5194,14 @@ restore_config:
+ * Use the firmware to read the Rx control register,
+ * especially useful if the Rx unit is under heavy pressure
+ **/
+-i40e_status i40e_aq_rx_ctl_read_register(struct i40e_hw *hw,
+- u32 reg_addr, u32 *reg_val,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_rx_ctl_read_register(struct i40e_hw *hw,
++ u32 reg_addr, u32 *reg_val,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_rx_ctl_reg_read_write *cmd_resp =
+ (struct i40e_aqc_rx_ctl_reg_read_write *)&desc.params.raw;
+- i40e_status status;
++ int status;
+
+ if (!reg_val)
+ return I40E_ERR_PARAM;
+@@ -5358,8 +5225,8 @@ i40e_status i40e_aq_rx_ctl_read_register(struct i40e_hw *hw,
+ **/
+ u32 i40e_read_rx_ctl(struct i40e_hw *hw, u32 reg_addr)
+ {
+- i40e_status status = 0;
+ bool use_register;
++ int status = 0;
+ int retry = 5;
+ u32 val = 0;
+
+@@ -5393,14 +5260,14 @@ do_retry:
+ * Use the firmware to write to an Rx control register,
+ * especially useful if the Rx unit is under heavy pressure
+ **/
+-i40e_status i40e_aq_rx_ctl_write_register(struct i40e_hw *hw,
+- u32 reg_addr, u32 reg_val,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_rx_ctl_write_register(struct i40e_hw *hw,
++ u32 reg_addr, u32 reg_val,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_rx_ctl_reg_read_write *cmd =
+ (struct i40e_aqc_rx_ctl_reg_read_write *)&desc.params.raw;
+- i40e_status status;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_rx_ctl_reg_write);
+
+@@ -5420,8 +5287,8 @@ i40e_status i40e_aq_rx_ctl_write_register(struct i40e_hw *hw,
+ **/
+ void i40e_write_rx_ctl(struct i40e_hw *hw, u32 reg_addr, u32 reg_val)
+ {
+- i40e_status status = 0;
+ bool use_register;
++ int status = 0;
+ int retry = 5;
+
+ use_register = (((hw->aq.api_maj_ver == 1) &&
+@@ -5483,16 +5350,16 @@ static void i40e_mdio_if_number_selection(struct i40e_hw *hw, bool set_mdio,
+ * NOTE: In common cases MDIO I/F number should not be changed, thats why you
+ * may use simple wrapper i40e_aq_set_phy_register.
+ **/
+-enum i40e_status_code i40e_aq_set_phy_register_ext(struct i40e_hw *hw,
+- u8 phy_select, u8 dev_addr, bool page_change,
+- bool set_mdio, u8 mdio_num,
+- u32 reg_addr, u32 reg_val,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_set_phy_register_ext(struct i40e_hw *hw,
++ u8 phy_select, u8 dev_addr, bool page_change,
++ bool set_mdio, u8 mdio_num,
++ u32 reg_addr, u32 reg_val,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_phy_register_access *cmd =
+ (struct i40e_aqc_phy_register_access *)&desc.params.raw;
+- i40e_status status;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_set_phy_register);
+@@ -5528,16 +5395,16 @@ enum i40e_status_code i40e_aq_set_phy_register_ext(struct i40e_hw *hw,
+ * NOTE: In common cases MDIO I/F number should not be changed, thats why you
+ * may use simple wrapper i40e_aq_get_phy_register.
+ **/
+-enum i40e_status_code i40e_aq_get_phy_register_ext(struct i40e_hw *hw,
+- u8 phy_select, u8 dev_addr, bool page_change,
+- bool set_mdio, u8 mdio_num,
+- u32 reg_addr, u32 *reg_val,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_get_phy_register_ext(struct i40e_hw *hw,
++ u8 phy_select, u8 dev_addr, bool page_change,
++ bool set_mdio, u8 mdio_num,
++ u32 reg_addr, u32 *reg_val,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_phy_register_access *cmd =
+ (struct i40e_aqc_phy_register_access *)&desc.params.raw;
+- i40e_status status;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_get_phy_register);
+@@ -5568,18 +5435,17 @@ enum i40e_status_code i40e_aq_get_phy_register_ext(struct i40e_hw *hw,
+ * @error_info: returns error information
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+-enum
+-i40e_status_code i40e_aq_write_ddp(struct i40e_hw *hw, void *buff,
+- u16 buff_size, u32 track_id,
+- u32 *error_offset, u32 *error_info,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_write_ddp(struct i40e_hw *hw, void *buff,
++ u16 buff_size, u32 track_id,
++ u32 *error_offset, u32 *error_info,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_write_personalization_profile *cmd =
+ (struct i40e_aqc_write_personalization_profile *)
+ &desc.params.raw;
+ struct i40e_aqc_write_ddp_resp *resp;
+- i40e_status status;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_write_personalization_profile);
+@@ -5612,15 +5478,14 @@ i40e_status_code i40e_aq_write_ddp(struct i40e_hw *hw, void *buff,
+ * @flags: AdminQ command flags
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+-enum
+-i40e_status_code i40e_aq_get_ddp_list(struct i40e_hw *hw, void *buff,
+- u16 buff_size, u8 flags,
+- struct i40e_asq_cmd_details *cmd_details)
++int i40e_aq_get_ddp_list(struct i40e_hw *hw, void *buff,
++ u16 buff_size, u8 flags,
++ struct i40e_asq_cmd_details *cmd_details)
+ {
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_get_applied_profiles *cmd =
+ (struct i40e_aqc_get_applied_profiles *)&desc.params.raw;
+- i40e_status status;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_get_personalization_profile_list);
+@@ -5719,14 +5584,13 @@ i40e_find_section_in_profile(u32 section_type,
+ * @hw: pointer to the hw struct
+ * @aq: command buffer containing all data to execute AQ
+ **/
+-static enum
+-i40e_status_code i40e_ddp_exec_aq_section(struct i40e_hw *hw,
+- struct i40e_profile_aq_section *aq)
++static int i40e_ddp_exec_aq_section(struct i40e_hw *hw,
++ struct i40e_profile_aq_section *aq)
+ {
+- i40e_status status;
+ struct i40e_aq_desc desc;
+ u8 *msg = NULL;
+ u16 msglen;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc, aq->opcode);
+ desc.flags |= cpu_to_le16(aq->flags);
+@@ -5766,14 +5630,14 @@ i40e_status_code i40e_ddp_exec_aq_section(struct i40e_hw *hw,
+ *
+ * Validates supported devices and profile's sections.
+ */
+-static enum i40e_status_code
++static int
+ i40e_validate_profile(struct i40e_hw *hw, struct i40e_profile_segment *profile,
+ u32 track_id, bool rollback)
+ {
+ struct i40e_profile_section_header *sec = NULL;
+- i40e_status status = 0;
+ struct i40e_section_table *sec_tbl;
+ u32 vendor_dev_id;
++ int status = 0;
+ u32 dev_cnt;
+ u32 sec_off;
+ u32 i;
+@@ -5831,16 +5695,16 @@ i40e_validate_profile(struct i40e_hw *hw, struct i40e_profile_segment *profile,
+ *
+ * Handles the download of a complete package.
+ */
+-enum i40e_status_code
++int
+ i40e_write_profile(struct i40e_hw *hw, struct i40e_profile_segment *profile,
+ u32 track_id)
+ {
+- i40e_status status = 0;
+- struct i40e_section_table *sec_tbl;
+ struct i40e_profile_section_header *sec = NULL;
+ struct i40e_profile_aq_section *ddp_aq;
+- u32 section_size = 0;
++ struct i40e_section_table *sec_tbl;
+ u32 offset = 0, info = 0;
++ u32 section_size = 0;
++ int status = 0;
+ u32 sec_off;
+ u32 i;
+
+@@ -5894,15 +5758,15 @@ i40e_write_profile(struct i40e_hw *hw, struct i40e_profile_segment *profile,
+ *
+ * Rolls back previously loaded package.
+ */
+-enum i40e_status_code
++int
+ i40e_rollback_profile(struct i40e_hw *hw, struct i40e_profile_segment *profile,
+ u32 track_id)
+ {
+ struct i40e_profile_section_header *sec = NULL;
+- i40e_status status = 0;
+ struct i40e_section_table *sec_tbl;
+ u32 offset = 0, info = 0;
+ u32 section_size = 0;
++ int status = 0;
+ u32 sec_off;
+ int i;
+
+@@ -5946,15 +5810,15 @@ i40e_rollback_profile(struct i40e_hw *hw, struct i40e_profile_segment *profile,
+ *
+ * Register a profile to the list of loaded profiles.
+ */
+-enum i40e_status_code
++int
+ i40e_add_pinfo_to_list(struct i40e_hw *hw,
+ struct i40e_profile_segment *profile,
+ u8 *profile_info_sec, u32 track_id)
+ {
+- i40e_status status = 0;
+ struct i40e_profile_section_header *sec = NULL;
+ struct i40e_profile_info *pinfo;
+ u32 offset = 0, info = 0;
++ int status = 0;
+
+ sec = (struct i40e_profile_section_header *)profile_info_sec;
+ sec->tbl_size = 1;
+@@ -5988,7 +5852,7 @@ i40e_add_pinfo_to_list(struct i40e_hw *hw,
+ * of the function.
+ *
+ **/
+-enum i40e_status_code
++int
+ i40e_aq_add_cloud_filters(struct i40e_hw *hw, u16 seid,
+ struct i40e_aqc_cloud_filters_element_data *filters,
+ u8 filter_count)
+@@ -5996,8 +5860,8 @@ i40e_aq_add_cloud_filters(struct i40e_hw *hw, u16 seid,
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_add_remove_cloud_filters *cmd =
+ (struct i40e_aqc_add_remove_cloud_filters *)&desc.params.raw;
+- enum i40e_status_code status;
+ u16 buff_len;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_add_cloud_filters);
+@@ -6025,7 +5889,7 @@ i40e_aq_add_cloud_filters(struct i40e_hw *hw, u16 seid,
+ * function.
+ *
+ **/
+-enum i40e_status_code
++int
+ i40e_aq_add_cloud_filters_bb(struct i40e_hw *hw, u16 seid,
+ struct i40e_aqc_cloud_filters_element_bb *filters,
+ u8 filter_count)
+@@ -6033,8 +5897,8 @@ i40e_aq_add_cloud_filters_bb(struct i40e_hw *hw, u16 seid,
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_add_remove_cloud_filters *cmd =
+ (struct i40e_aqc_add_remove_cloud_filters *)&desc.params.raw;
+- i40e_status status;
+ u16 buff_len;
++ int status;
+ int i;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+@@ -6082,7 +5946,7 @@ i40e_aq_add_cloud_filters_bb(struct i40e_hw *hw, u16 seid,
+ * of the function.
+ *
+ **/
+-enum i40e_status_code
++int
+ i40e_aq_rem_cloud_filters(struct i40e_hw *hw, u16 seid,
+ struct i40e_aqc_cloud_filters_element_data *filters,
+ u8 filter_count)
+@@ -6090,8 +5954,8 @@ i40e_aq_rem_cloud_filters(struct i40e_hw *hw, u16 seid,
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_add_remove_cloud_filters *cmd =
+ (struct i40e_aqc_add_remove_cloud_filters *)&desc.params.raw;
+- enum i40e_status_code status;
+ u16 buff_len;
++ int status;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_remove_cloud_filters);
+@@ -6119,7 +5983,7 @@ i40e_aq_rem_cloud_filters(struct i40e_hw *hw, u16 seid,
+ * function.
+ *
+ **/
+-enum i40e_status_code
++int
+ i40e_aq_rem_cloud_filters_bb(struct i40e_hw *hw, u16 seid,
+ struct i40e_aqc_cloud_filters_element_bb *filters,
+ u8 filter_count)
+@@ -6127,8 +5991,8 @@ i40e_aq_rem_cloud_filters_bb(struct i40e_hw *hw, u16 seid,
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_add_remove_cloud_filters *cmd =
+ (struct i40e_aqc_add_remove_cloud_filters *)&desc.params.raw;
+- i40e_status status;
+ u16 buff_len;
++ int status;
+ int i;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_dcb.c b/drivers/net/ethernet/intel/i40e/i40e_dcb.c
+index 673f341f4c0c1..90638b67f8dc8 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_dcb.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_dcb.c
+@@ -12,7 +12,7 @@
+ *
+ * Get the DCBX status from the Firmware
+ **/
+-i40e_status i40e_get_dcbx_status(struct i40e_hw *hw, u16 *status)
++int i40e_get_dcbx_status(struct i40e_hw *hw, u16 *status)
+ {
+ u32 reg;
+
+@@ -497,15 +497,15 @@ static void i40e_parse_org_tlv(struct i40e_lldp_org_tlv *tlv,
+ *
+ * Parse DCB configuration from the LLDPDU
+ **/
+-i40e_status i40e_lldp_to_dcb_config(u8 *lldpmib,
+- struct i40e_dcbx_config *dcbcfg)
++int i40e_lldp_to_dcb_config(u8 *lldpmib,
++ struct i40e_dcbx_config *dcbcfg)
+ {
+- i40e_status ret = 0;
+ struct i40e_lldp_org_tlv *tlv;
+- u16 type;
+- u16 length;
+ u16 typelength;
+ u16 offset = 0;
++ int ret = 0;
++ u16 length;
++ u16 type;
+
+ if (!lldpmib || !dcbcfg)
+ return I40E_ERR_PARAM;
+@@ -551,12 +551,12 @@ i40e_status i40e_lldp_to_dcb_config(u8 *lldpmib,
+ *
+ * Query DCB configuration from the Firmware
+ **/
+-i40e_status i40e_aq_get_dcb_config(struct i40e_hw *hw, u8 mib_type,
+- u8 bridgetype,
+- struct i40e_dcbx_config *dcbcfg)
++int i40e_aq_get_dcb_config(struct i40e_hw *hw, u8 mib_type,
++ u8 bridgetype,
++ struct i40e_dcbx_config *dcbcfg)
+ {
+- i40e_status ret = 0;
+ struct i40e_virt_mem mem;
++ int ret = 0;
+ u8 *lldpmib;
+
+ /* Allocate the LLDPDU */
+@@ -767,9 +767,9 @@ static void i40e_cee_to_dcb_config(
+ *
+ * Get IEEE mode DCB configuration from the Firmware
+ **/
+-static i40e_status i40e_get_ieee_dcb_config(struct i40e_hw *hw)
++static int i40e_get_ieee_dcb_config(struct i40e_hw *hw)
+ {
+- i40e_status ret = 0;
++ int ret = 0;
+
+ /* IEEE mode */
+ hw->local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_IEEE;
+@@ -797,11 +797,11 @@ out:
+ *
+ * Get DCB configuration from the Firmware
+ **/
+-i40e_status i40e_get_dcb_config(struct i40e_hw *hw)
++int i40e_get_dcb_config(struct i40e_hw *hw)
+ {
+- i40e_status ret = 0;
+- struct i40e_aqc_get_cee_dcb_cfg_resp cee_cfg;
+ struct i40e_aqc_get_cee_dcb_cfg_v1_resp cee_v1_cfg;
++ struct i40e_aqc_get_cee_dcb_cfg_resp cee_cfg;
++ int ret = 0;
+
+ /* If Firmware version < v4.33 on X710/XL710, IEEE only */
+ if ((hw->mac.type == I40E_MAC_XL710) &&
+@@ -867,11 +867,11 @@ out:
+ *
+ * Update DCB configuration from the Firmware
+ **/
+-i40e_status i40e_init_dcb(struct i40e_hw *hw, bool enable_mib_change)
++int i40e_init_dcb(struct i40e_hw *hw, bool enable_mib_change)
+ {
+- i40e_status ret = 0;
+ struct i40e_lldp_variables lldp_cfg;
+ u8 adminstatus = 0;
++ int ret = 0;
+
+ if (!hw->func_caps.dcb)
+ return I40E_NOT_SUPPORTED;
+@@ -940,13 +940,13 @@ i40e_status i40e_init_dcb(struct i40e_hw *hw, bool enable_mib_change)
+ * Get status of FW Link Layer Discovery Protocol (LLDP) Agent.
+ * Status of agent is reported via @lldp_status parameter.
+ **/
+-enum i40e_status_code
++int
+ i40e_get_fw_lldp_status(struct i40e_hw *hw,
+ enum i40e_get_fw_lldp_status_resp *lldp_status)
+ {
+ struct i40e_virt_mem mem;
+- i40e_status ret;
+ u8 *lldpmib;
++ int ret;
+
+ if (!lldp_status)
+ return I40E_ERR_PARAM;
+@@ -1238,13 +1238,13 @@ static void i40e_add_dcb_tlv(struct i40e_lldp_org_tlv *tlv,
+ *
+ * Set DCB configuration to the Firmware
+ **/
+-i40e_status i40e_set_dcb_config(struct i40e_hw *hw)
++int i40e_set_dcb_config(struct i40e_hw *hw)
+ {
+ struct i40e_dcbx_config *dcbcfg;
+ struct i40e_virt_mem mem;
+ u8 mib_type, *lldpmib;
+- i40e_status ret;
+ u16 miblen;
++ int ret;
+
+ /* update the hw local config */
+ dcbcfg = &hw->local_dcbx_config;
+@@ -1274,8 +1274,8 @@ i40e_status i40e_set_dcb_config(struct i40e_hw *hw)
+ *
+ * send DCB configuration to FW
+ **/
+-i40e_status i40e_dcb_config_to_lldp(u8 *lldpmib, u16 *miblen,
+- struct i40e_dcbx_config *dcbcfg)
++int i40e_dcb_config_to_lldp(u8 *lldpmib, u16 *miblen,
++ struct i40e_dcbx_config *dcbcfg)
+ {
+ u16 length, offset = 0, tlvid, typelength;
+ struct i40e_lldp_org_tlv *tlv;
+@@ -1888,13 +1888,13 @@ void i40e_dcb_hw_rx_pb_config(struct i40e_hw *hw,
+ *
+ * Reads the LLDP configuration data from NVM using passed addresses
+ **/
+-static i40e_status _i40e_read_lldp_cfg(struct i40e_hw *hw,
+- struct i40e_lldp_variables *lldp_cfg,
+- u8 module, u32 word_offset)
++static int _i40e_read_lldp_cfg(struct i40e_hw *hw,
++ struct i40e_lldp_variables *lldp_cfg,
++ u8 module, u32 word_offset)
+ {
+ u32 address, offset = (2 * word_offset);
+- i40e_status ret;
+ __le16 raw_mem;
++ int ret;
+ u16 mem;
+
+ ret = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
+@@ -1950,10 +1950,10 @@ err_lldp_cfg:
+ *
+ * Reads the LLDP configuration data from NVM
+ **/
+-i40e_status i40e_read_lldp_cfg(struct i40e_hw *hw,
+- struct i40e_lldp_variables *lldp_cfg)
++int i40e_read_lldp_cfg(struct i40e_hw *hw,
++ struct i40e_lldp_variables *lldp_cfg)
+ {
+- i40e_status ret = 0;
++ int ret = 0;
+ u32 mem;
+
+ if (!lldp_cfg)
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_dcb.h b/drivers/net/ethernet/intel/i40e/i40e_dcb.h
+index 2370ceecb0612..6b60dc9b77361 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_dcb.h
++++ b/drivers/net/ethernet/intel/i40e/i40e_dcb.h
+@@ -264,20 +264,20 @@ void i40e_dcb_hw_calculate_pool_sizes(struct i40e_hw *hw,
+ void i40e_dcb_hw_rx_pb_config(struct i40e_hw *hw,
+ struct i40e_rx_pb_config *old_pb_cfg,
+ struct i40e_rx_pb_config *new_pb_cfg);
+-i40e_status i40e_get_dcbx_status(struct i40e_hw *hw,
+- u16 *status);
+-i40e_status i40e_lldp_to_dcb_config(u8 *lldpmib,
+- struct i40e_dcbx_config *dcbcfg);
+-i40e_status i40e_aq_get_dcb_config(struct i40e_hw *hw, u8 mib_type,
+- u8 bridgetype,
+- struct i40e_dcbx_config *dcbcfg);
+-i40e_status i40e_get_dcb_config(struct i40e_hw *hw);
+-i40e_status i40e_init_dcb(struct i40e_hw *hw,
+- bool enable_mib_change);
+-enum i40e_status_code
++int i40e_get_dcbx_status(struct i40e_hw *hw,
++ u16 *status);
++int i40e_lldp_to_dcb_config(u8 *lldpmib,
++ struct i40e_dcbx_config *dcbcfg);
++int i40e_aq_get_dcb_config(struct i40e_hw *hw, u8 mib_type,
++ u8 bridgetype,
++ struct i40e_dcbx_config *dcbcfg);
++int i40e_get_dcb_config(struct i40e_hw *hw);
++int i40e_init_dcb(struct i40e_hw *hw,
++ bool enable_mib_change);
++int
+ i40e_get_fw_lldp_status(struct i40e_hw *hw,
+ enum i40e_get_fw_lldp_status_resp *lldp_status);
+-i40e_status i40e_set_dcb_config(struct i40e_hw *hw);
+-i40e_status i40e_dcb_config_to_lldp(u8 *lldpmib, u16 *miblen,
+- struct i40e_dcbx_config *dcbcfg);
++int i40e_set_dcb_config(struct i40e_hw *hw);
++int i40e_dcb_config_to_lldp(u8 *lldpmib, u16 *miblen,
++ struct i40e_dcbx_config *dcbcfg);
+ #endif /* _I40E_DCB_H_ */
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_dcb_nl.c b/drivers/net/ethernet/intel/i40e/i40e_dcb_nl.c
+index e32c61909b310..bba70bd5703bf 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_dcb_nl.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_dcb_nl.c
+@@ -135,8 +135,8 @@ static int i40e_dcbnl_ieee_setets(struct net_device *netdev,
+ ret = i40e_hw_dcb_config(pf, &pf->tmp_cfg);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "Failed setting DCB ETS configuration err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "Failed setting DCB ETS configuration err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
+ return -EINVAL;
+ }
+@@ -174,8 +174,8 @@ static int i40e_dcbnl_ieee_setpfc(struct net_device *netdev,
+ ret = i40e_hw_dcb_config(pf, &pf->tmp_cfg);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "Failed setting DCB PFC configuration err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "Failed setting DCB PFC configuration err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
+ return -EINVAL;
+ }
+@@ -225,8 +225,8 @@ static int i40e_dcbnl_ieee_setapp(struct net_device *netdev,
+ ret = i40e_hw_dcb_config(pf, &pf->tmp_cfg);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "Failed setting DCB configuration err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "Failed setting DCB configuration err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
+ return -EINVAL;
+ }
+@@ -290,8 +290,8 @@ static int i40e_dcbnl_ieee_delapp(struct net_device *netdev,
+ ret = i40e_hw_dcb_config(pf, &pf->tmp_cfg);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "Failed setting DCB configuration err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "Failed setting DCB configuration err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
+ return -EINVAL;
+ }
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_ddp.c b/drivers/net/ethernet/intel/i40e/i40e_ddp.c
+index e1069ae658ad3..7e8183762fd95 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_ddp.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_ddp.c
+@@ -36,7 +36,7 @@ static int i40e_ddp_does_profile_exist(struct i40e_hw *hw,
+ {
+ struct i40e_ddp_profile_list *profile_list;
+ u8 buff[I40E_PROFILE_LIST_SIZE];
+- i40e_status status;
++ int status;
+ int i;
+
+ status = i40e_aq_get_ddp_list(hw, buff, I40E_PROFILE_LIST_SIZE, 0,
+@@ -91,7 +91,7 @@ static int i40e_ddp_does_profile_overlap(struct i40e_hw *hw,
+ {
+ struct i40e_ddp_profile_list *profile_list;
+ u8 buff[I40E_PROFILE_LIST_SIZE];
+- i40e_status status;
++ int status;
+ int i;
+
+ status = i40e_aq_get_ddp_list(hw, buff, I40E_PROFILE_LIST_SIZE, 0,
+@@ -117,14 +117,14 @@ static int i40e_ddp_does_profile_overlap(struct i40e_hw *hw,
+ *
+ * Register a profile to the list of loaded profiles.
+ */
+-static enum i40e_status_code
++static int
+ i40e_add_pinfo(struct i40e_hw *hw, struct i40e_profile_segment *profile,
+ u8 *profile_info_sec, u32 track_id)
+ {
+ struct i40e_profile_section_header *sec;
+ struct i40e_profile_info *pinfo;
+- i40e_status status;
+ u32 offset = 0, info = 0;
++ int status;
+
+ sec = (struct i40e_profile_section_header *)profile_info_sec;
+ sec->tbl_size = 1;
+@@ -157,14 +157,14 @@ i40e_add_pinfo(struct i40e_hw *hw, struct i40e_profile_segment *profile,
+ *
+ * Removes DDP profile from the NIC.
+ **/
+-static enum i40e_status_code
++static int
+ i40e_del_pinfo(struct i40e_hw *hw, struct i40e_profile_segment *profile,
+ u8 *profile_info_sec, u32 track_id)
+ {
+ struct i40e_profile_section_header *sec;
+ struct i40e_profile_info *pinfo;
+- i40e_status status;
+ u32 offset = 0, info = 0;
++ int status;
+
+ sec = (struct i40e_profile_section_header *)profile_info_sec;
+ sec->tbl_size = 1;
+@@ -270,12 +270,12 @@ int i40e_ddp_load(struct net_device *netdev, const u8 *data, size_t size,
+ struct i40e_profile_segment *profile_hdr;
+ struct i40e_profile_info pinfo;
+ struct i40e_package_header *pkg_hdr;
+- i40e_status status;
+ struct i40e_netdev_priv *np = netdev_priv(netdev);
+ struct i40e_vsi *vsi = np->vsi;
+ struct i40e_pf *pf = vsi->back;
+ u32 track_id;
+ int istatus;
++ int status;
+
+ pkg_hdr = (struct i40e_package_header *)data;
+ if (!i40e_ddp_is_pkg_hdr_valid(netdev, pkg_hdr, size))
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c
+index c9dcd6d92c832..9954493cd4489 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c
+@@ -918,9 +918,9 @@ static ssize_t i40e_dbg_command_write(struct file *filp,
+ dev_info(&pf->pdev->dev, "deleting relay %d\n", veb_seid);
+ i40e_veb_release(pf->veb[i]);
+ } else if (strncmp(cmd_buf, "add pvid", 8) == 0) {
+- i40e_status ret;
+- u16 vid;
+ unsigned int v;
++ int ret;
++ u16 vid;
+
+ cnt = sscanf(&cmd_buf[8], "%i %u", &vsi_seid, &v);
+ if (cnt != 2) {
+@@ -1284,7 +1284,7 @@ static ssize_t i40e_dbg_command_write(struct file *filp,
+ }
+ } else if (strncmp(cmd_buf, "send aq_cmd", 11) == 0) {
+ struct i40e_aq_desc *desc;
+- i40e_status ret;
++ int ret;
+
+ desc = kzalloc(sizeof(struct i40e_aq_desc), GFP_KERNEL);
+ if (!desc)
+@@ -1330,9 +1330,9 @@ static ssize_t i40e_dbg_command_write(struct file *filp,
+ desc = NULL;
+ } else if (strncmp(cmd_buf, "send indirect aq_cmd", 20) == 0) {
+ struct i40e_aq_desc *desc;
+- i40e_status ret;
+ u16 buffer_len;
+ u8 *buff;
++ int ret;
+
+ desc = kzalloc(sizeof(struct i40e_aq_desc), GFP_KERNEL);
+ if (!desc)
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_diag.c b/drivers/net/ethernet/intel/i40e/i40e_diag.c
+index ca229b0efeb65..97fe1787a8f4a 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_diag.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_diag.c
+@@ -10,8 +10,8 @@
+ * @reg: reg to be tested
+ * @mask: bits to be touched
+ **/
+-static i40e_status i40e_diag_reg_pattern_test(struct i40e_hw *hw,
+- u32 reg, u32 mask)
++static int i40e_diag_reg_pattern_test(struct i40e_hw *hw,
++ u32 reg, u32 mask)
+ {
+ static const u32 patterns[] = {
+ 0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF
+@@ -74,9 +74,9 @@ const struct i40e_diag_reg_test_info i40e_reg_list[] = {
+ *
+ * Perform registers diagnostic test
+ **/
+-i40e_status i40e_diag_reg_test(struct i40e_hw *hw)
++int i40e_diag_reg_test(struct i40e_hw *hw)
+ {
+- i40e_status ret_code = 0;
++ int ret_code = 0;
+ u32 reg, mask;
+ u32 elements;
+ u32 i, j;
+@@ -115,9 +115,9 @@ i40e_status i40e_diag_reg_test(struct i40e_hw *hw)
+ *
+ * Perform EEPROM diagnostic test
+ **/
+-i40e_status i40e_diag_eeprom_test(struct i40e_hw *hw)
++int i40e_diag_eeprom_test(struct i40e_hw *hw)
+ {
+- i40e_status ret_code;
++ int ret_code;
+ u16 reg_val;
+
+ /* read NVM control word and if NVM valid, validate EEPROM checksum*/
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_diag.h b/drivers/net/ethernet/intel/i40e/i40e_diag.h
+index 1db7c6d572311..c3ce5f35211f0 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_diag.h
++++ b/drivers/net/ethernet/intel/i40e/i40e_diag.h
+@@ -22,7 +22,7 @@ struct i40e_diag_reg_test_info {
+
+ extern const struct i40e_diag_reg_test_info i40e_reg_list[];
+
+-i40e_status i40e_diag_reg_test(struct i40e_hw *hw);
+-i40e_status i40e_diag_eeprom_test(struct i40e_hw *hw);
++int i40e_diag_reg_test(struct i40e_hw *hw);
++int i40e_diag_eeprom_test(struct i40e_hw *hw);
+
+ #endif /* _I40E_DIAG_H_ */
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+index 887a735fe2a7b..04cbc217c569b 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+@@ -1226,8 +1226,8 @@ static int i40e_set_link_ksettings(struct net_device *netdev,
+ struct i40e_vsi *vsi = np->vsi;
+ struct i40e_hw *hw = &pf->hw;
+ bool autoneg_changed = false;
+- i40e_status status = 0;
+ int timeout = 50;
++ int status = 0;
+ int err = 0;
+ __u32 speed;
+ u8 autoneg;
+@@ -1455,8 +1455,8 @@ static int i40e_set_link_ksettings(struct net_device *netdev,
+ status = i40e_aq_set_phy_config(hw, &config, NULL);
+ if (status) {
+ netdev_info(netdev,
+- "Set phy config failed, err %s aq_err %s\n",
+- i40e_stat_str(hw, status),
++ "Set phy config failed, err %d aq_err %s\n",
++ status,
+ i40e_aq_str(hw, hw->aq.asq_last_status));
+ err = -EAGAIN;
+ goto done;
+@@ -1465,8 +1465,8 @@ static int i40e_set_link_ksettings(struct net_device *netdev,
+ status = i40e_update_link_info(hw);
+ if (status)
+ netdev_dbg(netdev,
+- "Updating link info failed with err %s aq_err %s\n",
+- i40e_stat_str(hw, status),
++ "Updating link info failed with err %d aq_err %s\n",
++ status,
+ i40e_aq_str(hw, hw->aq.asq_last_status));
+
+ } else {
+@@ -1485,7 +1485,7 @@ static int i40e_set_fec_cfg(struct net_device *netdev, u8 fec_cfg)
+ struct i40e_aq_get_phy_abilities_resp abilities;
+ struct i40e_pf *pf = np->vsi->back;
+ struct i40e_hw *hw = &pf->hw;
+- i40e_status status = 0;
++ int status = 0;
+ u32 flags = 0;
+ int err = 0;
+
+@@ -1517,8 +1517,8 @@ static int i40e_set_fec_cfg(struct net_device *netdev, u8 fec_cfg)
+ status = i40e_aq_set_phy_config(hw, &config, NULL);
+ if (status) {
+ netdev_info(netdev,
+- "Set phy config failed, err %s aq_err %s\n",
+- i40e_stat_str(hw, status),
++ "Set phy config failed, err %d aq_err %s\n",
++ status,
+ i40e_aq_str(hw, hw->aq.asq_last_status));
+ err = -EAGAIN;
+ goto done;
+@@ -1531,8 +1531,8 @@ static int i40e_set_fec_cfg(struct net_device *netdev, u8 fec_cfg)
+ * (e.g. no physical connection etc.)
+ */
+ netdev_dbg(netdev,
+- "Updating link info failed with err %s aq_err %s\n",
+- i40e_stat_str(hw, status),
++ "Updating link info failed with err %d aq_err %s\n",
++ status,
+ i40e_aq_str(hw, hw->aq.asq_last_status));
+ }
+
+@@ -1547,7 +1547,7 @@ static int i40e_get_fec_param(struct net_device *netdev,
+ struct i40e_aq_get_phy_abilities_resp abilities;
+ struct i40e_pf *pf = np->vsi->back;
+ struct i40e_hw *hw = &pf->hw;
+- i40e_status status = 0;
++ int status = 0;
+ int err = 0;
+ u8 fec_cfg;
+
+@@ -1634,12 +1634,12 @@ static int i40e_nway_reset(struct net_device *netdev)
+ struct i40e_pf *pf = np->vsi->back;
+ struct i40e_hw *hw = &pf->hw;
+ bool link_up = hw->phy.link_info.link_info & I40E_AQ_LINK_UP;
+- i40e_status ret = 0;
++ int ret = 0;
+
+ ret = i40e_aq_set_link_restart_an(hw, link_up, NULL);
+ if (ret) {
+- netdev_info(netdev, "link restart failed, err %s aq_err %s\n",
+- i40e_stat_str(hw, ret),
++ netdev_info(netdev, "link restart failed, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(hw, hw->aq.asq_last_status));
+ return -EIO;
+ }
+@@ -1699,9 +1699,9 @@ static int i40e_set_pauseparam(struct net_device *netdev,
+ struct i40e_link_status *hw_link_info = &hw->phy.link_info;
+ struct i40e_dcbx_config *dcbx_cfg = &hw->local_dcbx_config;
+ bool link_up = hw_link_info->link_info & I40E_AQ_LINK_UP;
+- i40e_status status;
+ u8 aq_failures;
+ int err = 0;
++ int status;
+ u32 is_an;
+
+ /* Changing the port's flow control is not supported if this isn't the
+@@ -1755,20 +1755,20 @@ static int i40e_set_pauseparam(struct net_device *netdev,
+ status = i40e_set_fc(hw, &aq_failures, link_up);
+
+ if (aq_failures & I40E_SET_FC_AQ_FAIL_GET) {
+- netdev_info(netdev, "Set fc failed on the get_phy_capabilities call with err %s aq_err %s\n",
+- i40e_stat_str(hw, status),
++ netdev_info(netdev, "Set fc failed on the get_phy_capabilities call with err %d aq_err %s\n",
++ status,
+ i40e_aq_str(hw, hw->aq.asq_last_status));
+ err = -EAGAIN;
+ }
+ if (aq_failures & I40E_SET_FC_AQ_FAIL_SET) {
+- netdev_info(netdev, "Set fc failed on the set_phy_config call with err %s aq_err %s\n",
+- i40e_stat_str(hw, status),
++ netdev_info(netdev, "Set fc failed on the set_phy_config call with err %d aq_err %s\n",
++ status,
+ i40e_aq_str(hw, hw->aq.asq_last_status));
+ err = -EAGAIN;
+ }
+ if (aq_failures & I40E_SET_FC_AQ_FAIL_UPDATE) {
+- netdev_info(netdev, "Set fc failed on the get_link_info call with err %s aq_err %s\n",
+- i40e_stat_str(hw, status),
++ netdev_info(netdev, "Set fc failed on the get_link_info call with err %d aq_err %s\n",
++ status,
+ i40e_aq_str(hw, hw->aq.asq_last_status));
+ err = -EAGAIN;
+ }
+@@ -2583,8 +2583,8 @@ static u64 i40e_link_test(struct net_device *netdev, u64 *data)
+ {
+ struct i40e_netdev_priv *np = netdev_priv(netdev);
+ struct i40e_pf *pf = np->vsi->back;
+- i40e_status status;
+ bool link_up = false;
++ int status;
+
+ netif_info(pf, hw, netdev, "link test\n");
+ status = i40e_get_link_status(&pf->hw, &link_up);
+@@ -2807,11 +2807,11 @@ static int i40e_set_phys_id(struct net_device *netdev,
+ enum ethtool_phys_id_state state)
+ {
+ struct i40e_netdev_priv *np = netdev_priv(netdev);
+- i40e_status ret = 0;
+ struct i40e_pf *pf = np->vsi->back;
+ struct i40e_hw *hw = &pf->hw;
+ int blink_freq = 2;
+ u16 temp_status;
++ int ret = 0;
+
+ switch (state) {
+ case ETHTOOL_ID_ACTIVE:
+@@ -5247,7 +5247,7 @@ static int i40e_set_priv_flags(struct net_device *dev, u32 flags)
+ struct i40e_vsi *vsi = np->vsi;
+ struct i40e_pf *pf = vsi->back;
+ u32 reset_needed = 0;
+- i40e_status status;
++ int status;
+ u32 i, j;
+
+ orig_flags = READ_ONCE(pf->flags);
+@@ -5362,8 +5362,8 @@ flags_complete:
+ 0, NULL);
+ if (ret && pf->hw.aq.asq_last_status != I40E_AQ_RC_ESRCH) {
+ dev_info(&pf->pdev->dev,
+- "couldn't set switch config bits, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "couldn't set switch config bits, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw,
+ pf->hw.aq.asq_last_status));
+ /* not a fatal problem, just keep going */
+@@ -5435,9 +5435,8 @@ flags_complete:
+ return -EBUSY;
+ default:
+ dev_warn(&pf->pdev->dev,
+- "Starting FW LLDP agent failed: error: %s, %s\n",
+- i40e_stat_str(&pf->hw,
+- status),
++ "Starting FW LLDP agent failed: error: %d, %s\n",
++ status,
+ i40e_aq_str(&pf->hw,
+ adq_err));
+ return -EINVAL;
+@@ -5477,8 +5476,8 @@ static int i40e_get_module_info(struct net_device *netdev,
+ u32 sff8472_comp = 0;
+ u32 sff8472_swap = 0;
+ u32 sff8636_rev = 0;
+- i40e_status status;
+ u32 type = 0;
++ int status;
+
+ /* Check if firmware supports reading module EEPROM. */
+ if (!(hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE)) {
+@@ -5582,8 +5581,8 @@ static int i40e_get_module_eeprom(struct net_device *netdev,
+ struct i40e_pf *pf = vsi->back;
+ struct i40e_hw *hw = &pf->hw;
+ bool is_sfp = false;
+- i40e_status status;
+ u32 value = 0;
++ int status;
+ int i;
+
+ if (!ee || !ee->len || !data)
+@@ -5624,10 +5623,10 @@ static int i40e_get_eee(struct net_device *netdev, struct ethtool_eee *edata)
+ {
+ struct i40e_netdev_priv *np = netdev_priv(netdev);
+ struct i40e_aq_get_phy_abilities_resp phy_cfg;
+- enum i40e_status_code status = 0;
+ struct i40e_vsi *vsi = np->vsi;
+ struct i40e_pf *pf = vsi->back;
+ struct i40e_hw *hw = &pf->hw;
++ int status = 0;
+
+ /* Get initial PHY capabilities */
+ status = i40e_aq_get_phy_capabilities(hw, false, true, &phy_cfg, NULL);
+@@ -5689,11 +5688,11 @@ static int i40e_set_eee(struct net_device *netdev, struct ethtool_eee *edata)
+ {
+ struct i40e_netdev_priv *np = netdev_priv(netdev);
+ struct i40e_aq_get_phy_abilities_resp abilities;
+- enum i40e_status_code status = I40E_SUCCESS;
+ struct i40e_aq_set_phy_config config;
+ struct i40e_vsi *vsi = np->vsi;
+ struct i40e_pf *pf = vsi->back;
+ struct i40e_hw *hw = &pf->hw;
++ int status = I40E_SUCCESS;
+ __le16 eee_capability;
+
+ /* Deny parameters we don't support */
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_hmc.c b/drivers/net/ethernet/intel/i40e/i40e_hmc.c
+index 163ee8c6311cc..46f7950a0049a 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_hmc.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_hmc.c
+@@ -17,17 +17,17 @@
+ * @type: what type of segment descriptor we're manipulating
+ * @direct_mode_sz: size to alloc in direct mode
+ **/
+-i40e_status i40e_add_sd_table_entry(struct i40e_hw *hw,
+- struct i40e_hmc_info *hmc_info,
+- u32 sd_index,
+- enum i40e_sd_entry_type type,
+- u64 direct_mode_sz)
++int i40e_add_sd_table_entry(struct i40e_hw *hw,
++ struct i40e_hmc_info *hmc_info,
++ u32 sd_index,
++ enum i40e_sd_entry_type type,
++ u64 direct_mode_sz)
+ {
+ enum i40e_memory_type mem_type __attribute__((unused));
+ struct i40e_hmc_sd_entry *sd_entry;
+ bool dma_mem_alloc_done = false;
++ int ret_code = I40E_SUCCESS;
+ struct i40e_dma_mem mem;
+- i40e_status ret_code = I40E_SUCCESS;
+ u64 alloc_len;
+
+ if (NULL == hmc_info->sd_table.sd_entry) {
+@@ -106,19 +106,19 @@ exit:
+ * aligned on 4K boundary and zeroed memory.
+ * 2. It should be 4K in size.
+ **/
+-i40e_status i40e_add_pd_table_entry(struct i40e_hw *hw,
+- struct i40e_hmc_info *hmc_info,
+- u32 pd_index,
+- struct i40e_dma_mem *rsrc_pg)
++int i40e_add_pd_table_entry(struct i40e_hw *hw,
++ struct i40e_hmc_info *hmc_info,
++ u32 pd_index,
++ struct i40e_dma_mem *rsrc_pg)
+ {
+- i40e_status ret_code = 0;
+ struct i40e_hmc_pd_table *pd_table;
+ struct i40e_hmc_pd_entry *pd_entry;
+ struct i40e_dma_mem mem;
+ struct i40e_dma_mem *page = &mem;
+ u32 sd_idx, rel_pd_idx;
+- u64 *pd_addr;
++ int ret_code = 0;
+ u64 page_desc;
++ u64 *pd_addr;
+
+ if (pd_index / I40E_HMC_PD_CNT_IN_SD >= hmc_info->sd_table.sd_cnt) {
+ ret_code = I40E_ERR_INVALID_PAGE_DESC_INDEX;
+@@ -185,15 +185,15 @@ exit:
+ * 1. Caller can deallocate the memory used by backing storage after this
+ * function returns.
+ **/
+-i40e_status i40e_remove_pd_bp(struct i40e_hw *hw,
+- struct i40e_hmc_info *hmc_info,
+- u32 idx)
++int i40e_remove_pd_bp(struct i40e_hw *hw,
++ struct i40e_hmc_info *hmc_info,
++ u32 idx)
+ {
+- i40e_status ret_code = 0;
+ struct i40e_hmc_pd_entry *pd_entry;
+ struct i40e_hmc_pd_table *pd_table;
+ struct i40e_hmc_sd_entry *sd_entry;
+ u32 sd_idx, rel_pd_idx;
++ int ret_code = 0;
+ u64 *pd_addr;
+
+ /* calculate index */
+@@ -241,11 +241,11 @@ exit:
+ * @hmc_info: pointer to the HMC configuration information structure
+ * @idx: the page index
+ **/
+-i40e_status i40e_prep_remove_sd_bp(struct i40e_hmc_info *hmc_info,
+- u32 idx)
++int i40e_prep_remove_sd_bp(struct i40e_hmc_info *hmc_info,
++ u32 idx)
+ {
+- i40e_status ret_code = 0;
+ struct i40e_hmc_sd_entry *sd_entry;
++ int ret_code = 0;
+
+ /* get the entry and decrease its ref counter */
+ sd_entry = &hmc_info->sd_table.sd_entry[idx];
+@@ -269,9 +269,9 @@ exit:
+ * @idx: the page index
+ * @is_pf: used to distinguish between VF and PF
+ **/
+-i40e_status i40e_remove_sd_bp_new(struct i40e_hw *hw,
+- struct i40e_hmc_info *hmc_info,
+- u32 idx, bool is_pf)
++int i40e_remove_sd_bp_new(struct i40e_hw *hw,
++ struct i40e_hmc_info *hmc_info,
++ u32 idx, bool is_pf)
+ {
+ struct i40e_hmc_sd_entry *sd_entry;
+
+@@ -290,11 +290,11 @@ i40e_status i40e_remove_sd_bp_new(struct i40e_hw *hw,
+ * @hmc_info: pointer to the HMC configuration information structure
+ * @idx: segment descriptor index to find the relevant page descriptor
+ **/
+-i40e_status i40e_prep_remove_pd_page(struct i40e_hmc_info *hmc_info,
+- u32 idx)
++int i40e_prep_remove_pd_page(struct i40e_hmc_info *hmc_info,
++ u32 idx)
+ {
+- i40e_status ret_code = 0;
+ struct i40e_hmc_sd_entry *sd_entry;
++ int ret_code = 0;
+
+ sd_entry = &hmc_info->sd_table.sd_entry[idx];
+
+@@ -318,9 +318,9 @@ exit:
+ * @idx: segment descriptor index to find the relevant page descriptor
+ * @is_pf: used to distinguish between VF and PF
+ **/
+-i40e_status i40e_remove_pd_page_new(struct i40e_hw *hw,
+- struct i40e_hmc_info *hmc_info,
+- u32 idx, bool is_pf)
++int i40e_remove_pd_page_new(struct i40e_hw *hw,
++ struct i40e_hmc_info *hmc_info,
++ u32 idx, bool is_pf)
+ {
+ struct i40e_hmc_sd_entry *sd_entry;
+
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_hmc.h b/drivers/net/ethernet/intel/i40e/i40e_hmc.h
+index 3113792afaffa..9960da07a5732 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_hmc.h
++++ b/drivers/net/ethernet/intel/i40e/i40e_hmc.h
+@@ -187,28 +187,28 @@ struct i40e_hmc_info {
+ /* add one more to the limit to correct our range */ \
+ *(pd_limit) += 1; \
+ }
+-i40e_status i40e_add_sd_table_entry(struct i40e_hw *hw,
+- struct i40e_hmc_info *hmc_info,
+- u32 sd_index,
+- enum i40e_sd_entry_type type,
+- u64 direct_mode_sz);
+-
+-i40e_status i40e_add_pd_table_entry(struct i40e_hw *hw,
+- struct i40e_hmc_info *hmc_info,
+- u32 pd_index,
+- struct i40e_dma_mem *rsrc_pg);
+-i40e_status i40e_remove_pd_bp(struct i40e_hw *hw,
+- struct i40e_hmc_info *hmc_info,
+- u32 idx);
+-i40e_status i40e_prep_remove_sd_bp(struct i40e_hmc_info *hmc_info,
+- u32 idx);
+-i40e_status i40e_remove_sd_bp_new(struct i40e_hw *hw,
+- struct i40e_hmc_info *hmc_info,
+- u32 idx, bool is_pf);
+-i40e_status i40e_prep_remove_pd_page(struct i40e_hmc_info *hmc_info,
+- u32 idx);
+-i40e_status i40e_remove_pd_page_new(struct i40e_hw *hw,
+- struct i40e_hmc_info *hmc_info,
+- u32 idx, bool is_pf);
++
++int i40e_add_sd_table_entry(struct i40e_hw *hw,
++ struct i40e_hmc_info *hmc_info,
++ u32 sd_index,
++ enum i40e_sd_entry_type type,
++ u64 direct_mode_sz);
++int i40e_add_pd_table_entry(struct i40e_hw *hw,
++ struct i40e_hmc_info *hmc_info,
++ u32 pd_index,
++ struct i40e_dma_mem *rsrc_pg);
++int i40e_remove_pd_bp(struct i40e_hw *hw,
++ struct i40e_hmc_info *hmc_info,
++ u32 idx);
++int i40e_prep_remove_sd_bp(struct i40e_hmc_info *hmc_info,
++ u32 idx);
++int i40e_remove_sd_bp_new(struct i40e_hw *hw,
++ struct i40e_hmc_info *hmc_info,
++ u32 idx, bool is_pf);
++int i40e_prep_remove_pd_page(struct i40e_hmc_info *hmc_info,
++ u32 idx);
++int i40e_remove_pd_page_new(struct i40e_hw *hw,
++ struct i40e_hmc_info *hmc_info,
++ u32 idx, bool is_pf);
+
+ #endif /* _I40E_HMC_H_ */
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_lan_hmc.c b/drivers/net/ethernet/intel/i40e/i40e_lan_hmc.c
+index d6e92ecddfbd8..40c101f286d19 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_lan_hmc.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_lan_hmc.c
+@@ -74,12 +74,12 @@ static u64 i40e_calculate_l2fpm_size(u32 txq_num, u32 rxq_num,
+ * Assumptions:
+ * - HMC Resource Profile has been selected before calling this function.
+ **/
+-i40e_status i40e_init_lan_hmc(struct i40e_hw *hw, u32 txq_num,
+- u32 rxq_num, u32 fcoe_cntx_num,
+- u32 fcoe_filt_num)
++int i40e_init_lan_hmc(struct i40e_hw *hw, u32 txq_num,
++ u32 rxq_num, u32 fcoe_cntx_num,
++ u32 fcoe_filt_num)
+ {
+ struct i40e_hmc_obj_info *obj, *full_obj;
+- i40e_status ret_code = 0;
++ int ret_code = 0;
+ u64 l2fpm_size;
+ u32 size_exp;
+
+@@ -229,11 +229,11 @@ init_lan_hmc_out:
+ * 1. caller can deallocate the memory used by pd after this function
+ * returns.
+ **/
+-static i40e_status i40e_remove_pd_page(struct i40e_hw *hw,
+- struct i40e_hmc_info *hmc_info,
+- u32 idx)
++static int i40e_remove_pd_page(struct i40e_hw *hw,
++ struct i40e_hmc_info *hmc_info,
++ u32 idx)
+ {
+- i40e_status ret_code = 0;
++ int ret_code = 0;
+
+ if (!i40e_prep_remove_pd_page(hmc_info, idx))
+ ret_code = i40e_remove_pd_page_new(hw, hmc_info, idx, true);
+@@ -256,11 +256,11 @@ static i40e_status i40e_remove_pd_page(struct i40e_hw *hw,
+ * 1. caller can deallocate the memory used by backing storage after this
+ * function returns.
+ **/
+-static i40e_status i40e_remove_sd_bp(struct i40e_hw *hw,
+- struct i40e_hmc_info *hmc_info,
+- u32 idx)
++static int i40e_remove_sd_bp(struct i40e_hw *hw,
++ struct i40e_hmc_info *hmc_info,
++ u32 idx)
+ {
+- i40e_status ret_code = 0;
++ int ret_code = 0;
+
+ if (!i40e_prep_remove_sd_bp(hmc_info, idx))
+ ret_code = i40e_remove_sd_bp_new(hw, hmc_info, idx, true);
+@@ -276,15 +276,15 @@ static i40e_status i40e_remove_sd_bp(struct i40e_hw *hw,
+ * This will allocate memory for PDs and backing pages and populate
+ * the sd and pd entries.
+ **/
+-static i40e_status i40e_create_lan_hmc_object(struct i40e_hw *hw,
+- struct i40e_hmc_lan_create_obj_info *info)
++static int i40e_create_lan_hmc_object(struct i40e_hw *hw,
++ struct i40e_hmc_lan_create_obj_info *info)
+ {
+- i40e_status ret_code = 0;
+ struct i40e_hmc_sd_entry *sd_entry;
+ u32 pd_idx1 = 0, pd_lmt1 = 0;
+ u32 pd_idx = 0, pd_lmt = 0;
+ bool pd_error = false;
+ u32 sd_idx, sd_lmt;
++ int ret_code = 0;
+ u64 sd_size;
+ u32 i, j;
+
+@@ -435,13 +435,13 @@ exit:
+ * - This function will be called after i40e_init_lan_hmc() and before
+ * any LAN/FCoE HMC objects can be created.
+ **/
+-i40e_status i40e_configure_lan_hmc(struct i40e_hw *hw,
+- enum i40e_hmc_model model)
++int i40e_configure_lan_hmc(struct i40e_hw *hw,
++ enum i40e_hmc_model model)
+ {
+ struct i40e_hmc_lan_create_obj_info info;
+- i40e_status ret_code = 0;
+ u8 hmc_fn_id = hw->hmc.hmc_fn_id;
+ struct i40e_hmc_obj_info *obj;
++ int ret_code = 0;
+
+ /* Initialize part of the create object info struct */
+ info.hmc_info = &hw->hmc;
+@@ -520,13 +520,13 @@ configure_lan_hmc_out:
+ * caller should deallocate memory allocated previously for
+ * book-keeping information about PDs and backing storage.
+ **/
+-static i40e_status i40e_delete_lan_hmc_object(struct i40e_hw *hw,
+- struct i40e_hmc_lan_delete_obj_info *info)
++static int i40e_delete_lan_hmc_object(struct i40e_hw *hw,
++ struct i40e_hmc_lan_delete_obj_info *info)
+ {
+- i40e_status ret_code = 0;
+ struct i40e_hmc_pd_table *pd_table;
+ u32 pd_idx, pd_lmt, rel_pd_idx;
+ u32 sd_idx, sd_lmt;
++ int ret_code = 0;
+ u32 i, j;
+
+ if (NULL == info) {
+@@ -632,10 +632,10 @@ exit:
+ * This must be called by drivers as they are shutting down and being
+ * removed from the OS.
+ **/
+-i40e_status i40e_shutdown_lan_hmc(struct i40e_hw *hw)
++int i40e_shutdown_lan_hmc(struct i40e_hw *hw)
+ {
+ struct i40e_hmc_lan_delete_obj_info info;
+- i40e_status ret_code;
++ int ret_code;
+
+ info.hmc_info = &hw->hmc;
+ info.rsrc_type = I40E_HMC_LAN_FULL;
+@@ -915,9 +915,9 @@ static void i40e_write_qword(u8 *hmc_bits,
+ * @context_bytes: pointer to the context bit array (DMA memory)
+ * @hmc_type: the type of HMC resource
+ **/
+-static i40e_status i40e_clear_hmc_context(struct i40e_hw *hw,
+- u8 *context_bytes,
+- enum i40e_hmc_lan_rsrc_type hmc_type)
++static int i40e_clear_hmc_context(struct i40e_hw *hw,
++ u8 *context_bytes,
++ enum i40e_hmc_lan_rsrc_type hmc_type)
+ {
+ /* clean the bit array */
+ memset(context_bytes, 0, (u32)hw->hmc.hmc_obj[hmc_type].size);
+@@ -931,9 +931,9 @@ static i40e_status i40e_clear_hmc_context(struct i40e_hw *hw,
+ * @ce_info: a description of the struct to be filled
+ * @dest: the struct to be filled
+ **/
+-static i40e_status i40e_set_hmc_context(u8 *context_bytes,
+- struct i40e_context_ele *ce_info,
+- u8 *dest)
++static int i40e_set_hmc_context(u8 *context_bytes,
++ struct i40e_context_ele *ce_info,
++ u8 *dest)
+ {
+ int f;
+
+@@ -973,18 +973,18 @@ static i40e_status i40e_set_hmc_context(u8 *context_bytes,
+ * base pointer. This function is used for LAN Queue contexts.
+ **/
+ static
+-i40e_status i40e_hmc_get_object_va(struct i40e_hw *hw, u8 **object_base,
+- enum i40e_hmc_lan_rsrc_type rsrc_type,
+- u32 obj_idx)
++int i40e_hmc_get_object_va(struct i40e_hw *hw, u8 **object_base,
++ enum i40e_hmc_lan_rsrc_type rsrc_type,
++ u32 obj_idx)
+ {
+ struct i40e_hmc_info *hmc_info = &hw->hmc;
+ u32 obj_offset_in_sd, obj_offset_in_pd;
+ struct i40e_hmc_sd_entry *sd_entry;
+ struct i40e_hmc_pd_entry *pd_entry;
+ u32 pd_idx, pd_lmt, rel_pd_idx;
+- i40e_status ret_code = 0;
+ u64 obj_offset_in_fpm;
+ u32 sd_idx, sd_lmt;
++ int ret_code = 0;
+
+ if (NULL == hmc_info) {
+ ret_code = I40E_ERR_BAD_PTR;
+@@ -1042,11 +1042,11 @@ exit:
+ * @hw: the hardware struct
+ * @queue: the queue we care about
+ **/
+-i40e_status i40e_clear_lan_tx_queue_context(struct i40e_hw *hw,
+- u16 queue)
++int i40e_clear_lan_tx_queue_context(struct i40e_hw *hw,
++ u16 queue)
+ {
+- i40e_status err;
+ u8 *context_bytes;
++ int err;
+
+ err = i40e_hmc_get_object_va(hw, &context_bytes,
+ I40E_HMC_LAN_TX, queue);
+@@ -1062,12 +1062,12 @@ i40e_status i40e_clear_lan_tx_queue_context(struct i40e_hw *hw,
+ * @queue: the queue we care about
+ * @s: the struct to be filled
+ **/
+-i40e_status i40e_set_lan_tx_queue_context(struct i40e_hw *hw,
+- u16 queue,
+- struct i40e_hmc_obj_txq *s)
++int i40e_set_lan_tx_queue_context(struct i40e_hw *hw,
++ u16 queue,
++ struct i40e_hmc_obj_txq *s)
+ {
+- i40e_status err;
+ u8 *context_bytes;
++ int err;
+
+ err = i40e_hmc_get_object_va(hw, &context_bytes,
+ I40E_HMC_LAN_TX, queue);
+@@ -1083,11 +1083,11 @@ i40e_status i40e_set_lan_tx_queue_context(struct i40e_hw *hw,
+ * @hw: the hardware struct
+ * @queue: the queue we care about
+ **/
+-i40e_status i40e_clear_lan_rx_queue_context(struct i40e_hw *hw,
+- u16 queue)
++int i40e_clear_lan_rx_queue_context(struct i40e_hw *hw,
++ u16 queue)
+ {
+- i40e_status err;
+ u8 *context_bytes;
++ int err;
+
+ err = i40e_hmc_get_object_va(hw, &context_bytes,
+ I40E_HMC_LAN_RX, queue);
+@@ -1103,12 +1103,12 @@ i40e_status i40e_clear_lan_rx_queue_context(struct i40e_hw *hw,
+ * @queue: the queue we care about
+ * @s: the struct to be filled
+ **/
+-i40e_status i40e_set_lan_rx_queue_context(struct i40e_hw *hw,
+- u16 queue,
+- struct i40e_hmc_obj_rxq *s)
++int i40e_set_lan_rx_queue_context(struct i40e_hw *hw,
++ u16 queue,
++ struct i40e_hmc_obj_rxq *s)
+ {
+- i40e_status err;
+ u8 *context_bytes;
++ int err;
+
+ err = i40e_hmc_get_object_va(hw, &context_bytes,
+ I40E_HMC_LAN_RX, queue);
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_lan_hmc.h b/drivers/net/ethernet/intel/i40e/i40e_lan_hmc.h
+index c46a2c449e60e..9f960404c2b37 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_lan_hmc.h
++++ b/drivers/net/ethernet/intel/i40e/i40e_lan_hmc.h
+@@ -137,22 +137,22 @@ struct i40e_hmc_lan_delete_obj_info {
+ u32 count;
+ };
+
+-i40e_status i40e_init_lan_hmc(struct i40e_hw *hw, u32 txq_num,
+- u32 rxq_num, u32 fcoe_cntx_num,
+- u32 fcoe_filt_num);
+-i40e_status i40e_configure_lan_hmc(struct i40e_hw *hw,
+- enum i40e_hmc_model model);
+-i40e_status i40e_shutdown_lan_hmc(struct i40e_hw *hw);
+-
+-i40e_status i40e_clear_lan_tx_queue_context(struct i40e_hw *hw,
+- u16 queue);
+-i40e_status i40e_set_lan_tx_queue_context(struct i40e_hw *hw,
+- u16 queue,
+- struct i40e_hmc_obj_txq *s);
+-i40e_status i40e_clear_lan_rx_queue_context(struct i40e_hw *hw,
+- u16 queue);
+-i40e_status i40e_set_lan_rx_queue_context(struct i40e_hw *hw,
+- u16 queue,
+- struct i40e_hmc_obj_rxq *s);
++int i40e_init_lan_hmc(struct i40e_hw *hw, u32 txq_num,
++ u32 rxq_num, u32 fcoe_cntx_num,
++ u32 fcoe_filt_num);
++int i40e_configure_lan_hmc(struct i40e_hw *hw,
++ enum i40e_hmc_model model);
++int i40e_shutdown_lan_hmc(struct i40e_hw *hw);
++
++int i40e_clear_lan_tx_queue_context(struct i40e_hw *hw,
++ u16 queue);
++int i40e_set_lan_tx_queue_context(struct i40e_hw *hw,
++ u16 queue,
++ struct i40e_hmc_obj_txq *s);
++int i40e_clear_lan_rx_queue_context(struct i40e_hw *hw,
++ u16 queue);
++int i40e_set_lan_rx_queue_context(struct i40e_hw *hw,
++ u16 queue,
++ struct i40e_hmc_obj_rxq *s);
+
+ #endif /* _I40E_LAN_HMC_H_ */
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
+index 3ac7234a85bbb..49ba9f1be952d 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
+@@ -1817,13 +1817,13 @@ static int i40e_set_mac(struct net_device *netdev, void *p)
+ spin_unlock_bh(&vsi->mac_filter_hash_lock);
+
+ if (vsi->type == I40E_VSI_MAIN) {
+- i40e_status ret;
++ int ret;
+
+ ret = i40e_aq_mac_address_write(hw, I40E_AQC_WRITE_TYPE_LAA_WOL,
+ addr->sa_data, NULL);
+ if (ret)
+- netdev_info(netdev, "Ignoring error from firmware on LAA update, status %s, AQ ret %s\n",
+- i40e_stat_str(hw, ret),
++ netdev_info(netdev, "Ignoring error from firmware on LAA update, status %d, AQ ret %s\n",
++ ret,
+ i40e_aq_str(hw, hw->aq.asq_last_status));
+ }
+
+@@ -1854,8 +1854,8 @@ static int i40e_config_rss_aq(struct i40e_vsi *vsi, const u8 *seed,
+ ret = i40e_aq_set_rss_key(hw, vsi->id, seed_dw);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "Cannot set RSS key, err %s aq_err %s\n",
+- i40e_stat_str(hw, ret),
++ "Cannot set RSS key, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(hw, hw->aq.asq_last_status));
+ return ret;
+ }
+@@ -1866,8 +1866,8 @@ static int i40e_config_rss_aq(struct i40e_vsi *vsi, const u8 *seed,
+ ret = i40e_aq_set_rss_lut(hw, vsi->id, pf_lut, lut, lut_size);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "Cannot set RSS lut, err %s aq_err %s\n",
+- i40e_stat_str(hw, ret),
++ "Cannot set RSS lut, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(hw, hw->aq.asq_last_status));
+ return ret;
+ }
+@@ -2349,7 +2349,7 @@ void i40e_aqc_del_filters(struct i40e_vsi *vsi, const char *vsi_name,
+ {
+ struct i40e_hw *hw = &vsi->back->hw;
+ enum i40e_admin_queue_err aq_status;
+- i40e_status aq_ret;
++ int aq_ret;
+
+ aq_ret = i40e_aq_remove_macvlan_v2(hw, vsi->seid, list, num_del, NULL,
+ &aq_status);
+@@ -2358,8 +2358,8 @@ void i40e_aqc_del_filters(struct i40e_vsi *vsi, const char *vsi_name,
+ if (aq_ret && !(aq_status == I40E_AQ_RC_ENOENT)) {
+ *retval = -EIO;
+ dev_info(&vsi->back->pdev->dev,
+- "ignoring delete macvlan error on %s, err %s, aq_err %s\n",
+- vsi_name, i40e_stat_str(hw, aq_ret),
++ "ignoring delete macvlan error on %s, err %d, aq_err %s\n",
++ vsi_name, aq_ret,
+ i40e_aq_str(hw, aq_status));
+ }
+ }
+@@ -2423,13 +2423,13 @@ void i40e_aqc_add_filters(struct i40e_vsi *vsi, const char *vsi_name,
+ *
+ * Returns status indicating success or failure;
+ **/
+-static i40e_status
++static int
+ i40e_aqc_broadcast_filter(struct i40e_vsi *vsi, const char *vsi_name,
+ struct i40e_mac_filter *f)
+ {
+ bool enable = f->state == I40E_FILTER_NEW;
+ struct i40e_hw *hw = &vsi->back->hw;
+- i40e_status aq_ret;
++ int aq_ret;
+
+ if (f->vlan == I40E_VLAN_ANY) {
+ aq_ret = i40e_aq_set_vsi_broadcast(hw,
+@@ -2468,7 +2468,7 @@ static int i40e_set_promiscuous(struct i40e_pf *pf, bool promisc)
+ {
+ struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
+ struct i40e_hw *hw = &pf->hw;
+- i40e_status aq_ret;
++ int aq_ret;
+
+ if (vsi->type == I40E_VSI_MAIN &&
+ pf->lan_veb != I40E_NO_VEB &&
+@@ -2488,8 +2488,8 @@ static int i40e_set_promiscuous(struct i40e_pf *pf, bool promisc)
+ NULL);
+ if (aq_ret) {
+ dev_info(&pf->pdev->dev,
+- "Set default VSI failed, err %s, aq_err %s\n",
+- i40e_stat_str(hw, aq_ret),
++ "Set default VSI failed, err %d, aq_err %s\n",
++ aq_ret,
+ i40e_aq_str(hw, hw->aq.asq_last_status));
+ }
+ } else {
+@@ -2500,8 +2500,8 @@ static int i40e_set_promiscuous(struct i40e_pf *pf, bool promisc)
+ true);
+ if (aq_ret) {
+ dev_info(&pf->pdev->dev,
+- "set unicast promisc failed, err %s, aq_err %s\n",
+- i40e_stat_str(hw, aq_ret),
++ "set unicast promisc failed, err %d, aq_err %s\n",
++ aq_ret,
+ i40e_aq_str(hw, hw->aq.asq_last_status));
+ }
+ aq_ret = i40e_aq_set_vsi_multicast_promiscuous(
+@@ -2510,8 +2510,8 @@ static int i40e_set_promiscuous(struct i40e_pf *pf, bool promisc)
+ promisc, NULL);
+ if (aq_ret) {
+ dev_info(&pf->pdev->dev,
+- "set multicast promisc failed, err %s, aq_err %s\n",
+- i40e_stat_str(hw, aq_ret),
++ "set multicast promisc failed, err %d, aq_err %s\n",
++ aq_ret,
+ i40e_aq_str(hw, hw->aq.asq_last_status));
+ }
+ }
+@@ -2541,12 +2541,12 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
+ unsigned int vlan_filters = 0;
+ char vsi_name[16] = "PF";
+ int filter_list_len = 0;
+- i40e_status aq_ret = 0;
+ u32 changed_flags = 0;
+ struct hlist_node *h;
+ struct i40e_pf *pf;
+ int num_add = 0;
+ int num_del = 0;
++ int aq_ret = 0;
+ int retval = 0;
+ u16 cmd_flags;
+ int list_size;
+@@ -2814,9 +2814,9 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
+ retval = i40e_aq_rc_to_posix(aq_ret,
+ hw->aq.asq_last_status);
+ dev_info(&pf->pdev->dev,
+- "set multi promisc failed on %s, err %s aq_err %s\n",
++ "set multi promisc failed on %s, err %d aq_err %s\n",
+ vsi_name,
+- i40e_stat_str(hw, aq_ret),
++ aq_ret,
+ i40e_aq_str(hw, hw->aq.asq_last_status));
+ } else {
+ dev_info(&pf->pdev->dev, "%s allmulti mode.\n",
+@@ -2834,10 +2834,10 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
+ retval = i40e_aq_rc_to_posix(aq_ret,
+ hw->aq.asq_last_status);
+ dev_info(&pf->pdev->dev,
+- "Setting promiscuous %s failed on %s, err %s aq_err %s\n",
++ "Setting promiscuous %s failed on %s, err %d aq_err %s\n",
+ cur_promisc ? "on" : "off",
+ vsi_name,
+- i40e_stat_str(hw, aq_ret),
++ aq_ret,
+ i40e_aq_str(hw, hw->aq.asq_last_status));
+ }
+ }
+@@ -2965,7 +2965,7 @@ int i40e_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+ void i40e_vlan_stripping_enable(struct i40e_vsi *vsi)
+ {
+ struct i40e_vsi_context ctxt;
+- i40e_status ret;
++ int ret;
+
+ /* Don't modify stripping options if a port VLAN is active */
+ if (vsi->info.pvid)
+@@ -2985,8 +2985,8 @@ void i40e_vlan_stripping_enable(struct i40e_vsi *vsi)
+ ret = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL);
+ if (ret) {
+ dev_info(&vsi->back->pdev->dev,
+- "update vlan stripping failed, err %s aq_err %s\n",
+- i40e_stat_str(&vsi->back->hw, ret),
++ "update vlan stripping failed, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&vsi->back->hw,
+ vsi->back->hw.aq.asq_last_status));
+ }
+@@ -2999,7 +2999,7 @@ void i40e_vlan_stripping_enable(struct i40e_vsi *vsi)
+ void i40e_vlan_stripping_disable(struct i40e_vsi *vsi)
+ {
+ struct i40e_vsi_context ctxt;
+- i40e_status ret;
++ int ret;
+
+ /* Don't modify stripping options if a port VLAN is active */
+ if (vsi->info.pvid)
+@@ -3020,8 +3020,8 @@ void i40e_vlan_stripping_disable(struct i40e_vsi *vsi)
+ ret = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL);
+ if (ret) {
+ dev_info(&vsi->back->pdev->dev,
+- "update vlan stripping failed, err %s aq_err %s\n",
+- i40e_stat_str(&vsi->back->hw, ret),
++ "update vlan stripping failed, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&vsi->back->hw,
+ vsi->back->hw.aq.asq_last_status));
+ }
+@@ -3252,7 +3252,7 @@ static void i40e_restore_vlan(struct i40e_vsi *vsi)
+ int i40e_vsi_add_pvid(struct i40e_vsi *vsi, u16 vid)
+ {
+ struct i40e_vsi_context ctxt;
+- i40e_status ret;
++ int ret;
+
+ vsi->info.valid_sections = cpu_to_le16(I40E_AQ_VSI_PROP_VLAN_VALID);
+ vsi->info.pvid = cpu_to_le16(vid);
+@@ -3265,8 +3265,8 @@ int i40e_vsi_add_pvid(struct i40e_vsi *vsi, u16 vid)
+ ret = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL);
+ if (ret) {
+ dev_info(&vsi->back->pdev->dev,
+- "add pvid failed, err %s aq_err %s\n",
+- i40e_stat_str(&vsi->back->hw, ret),
++ "add pvid failed, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&vsi->back->hw,
+ vsi->back->hw.aq.asq_last_status));
+ return -ENOENT;
+@@ -3429,8 +3429,8 @@ static int i40e_configure_tx_ring(struct i40e_ring *ring)
+ u16 pf_q = vsi->base_queue + ring->queue_index;
+ struct i40e_hw *hw = &vsi->back->hw;
+ struct i40e_hmc_obj_txq tx_ctx;
+- i40e_status err = 0;
+ u32 qtx_ctl = 0;
++ int err = 0;
+
+ if (ring_is_xdp(ring))
+ ring->xsk_pool = i40e_xsk_pool(ring);
+@@ -3554,7 +3554,7 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring)
+ u16 pf_q = vsi->base_queue + ring->queue_index;
+ struct i40e_hw *hw = &vsi->back->hw;
+ struct i40e_hmc_obj_rxq rx_ctx;
+- i40e_status err = 0;
++ int err = 0;
+ bool ok;
+ int ret;
+
+@@ -5525,16 +5525,16 @@ static int i40e_vsi_get_bw_info(struct i40e_vsi *vsi)
+ struct i40e_aqc_query_vsi_bw_config_resp bw_config = {0};
+ struct i40e_pf *pf = vsi->back;
+ struct i40e_hw *hw = &pf->hw;
+- i40e_status ret;
+ u32 tc_bw_max;
++ int ret;
+ int i;
+
+ /* Get the VSI level BW configuration */
+ ret = i40e_aq_query_vsi_bw_config(hw, vsi->seid, &bw_config, NULL);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "couldn't get PF vsi bw config, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "couldn't get PF vsi bw config, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
+ return -EINVAL;
+ }
+@@ -5544,8 +5544,8 @@ static int i40e_vsi_get_bw_info(struct i40e_vsi *vsi)
+ NULL);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "couldn't get PF vsi ets bw config, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "couldn't get PF vsi ets bw config, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
+ return -EINVAL;
+ }
+@@ -5586,7 +5586,7 @@ static int i40e_vsi_configure_bw_alloc(struct i40e_vsi *vsi, u8 enabled_tc,
+ {
+ struct i40e_aqc_configure_vsi_tc_bw_data bw_data;
+ struct i40e_pf *pf = vsi->back;
+- i40e_status ret;
++ int ret;
+ int i;
+
+ /* There is no need to reset BW when mqprio mode is on. */
+@@ -5734,8 +5734,8 @@ int i40e_update_adq_vsi_queues(struct i40e_vsi *vsi, int vsi_offset)
+
+ ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL);
+ if (ret) {
+- dev_info(&pf->pdev->dev, "Update vsi config failed, err %s aq_err %s\n",
+- i40e_stat_str(hw, ret),
++ dev_info(&pf->pdev->dev, "Update vsi config failed, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(hw, hw->aq.asq_last_status));
+ return ret;
+ }
+@@ -5790,8 +5790,8 @@ static int i40e_vsi_config_tc(struct i40e_vsi *vsi, u8 enabled_tc)
+ &bw_config, NULL);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "Failed querying vsi bw info, err %s aq_err %s\n",
+- i40e_stat_str(hw, ret),
++ "Failed querying vsi bw info, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(hw, hw->aq.asq_last_status));
+ goto out;
+ }
+@@ -5857,8 +5857,8 @@ static int i40e_vsi_config_tc(struct i40e_vsi *vsi, u8 enabled_tc)
+ ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "Update vsi tc config failed, err %s aq_err %s\n",
+- i40e_stat_str(hw, ret),
++ "Update vsi tc config failed, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(hw, hw->aq.asq_last_status));
+ goto out;
+ }
+@@ -5870,8 +5870,8 @@ static int i40e_vsi_config_tc(struct i40e_vsi *vsi, u8 enabled_tc)
+ ret = i40e_vsi_get_bw_info(vsi);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "Failed updating vsi bw info, err %s aq_err %s\n",
+- i40e_stat_str(hw, ret),
++ "Failed updating vsi bw info, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(hw, hw->aq.asq_last_status));
+ goto out;
+ }
+@@ -5962,8 +5962,8 @@ int i40e_set_bw_limit(struct i40e_vsi *vsi, u16 seid, u64 max_tx_rate)
+ I40E_MAX_BW_INACTIVE_ACCUM, NULL);
+ if (ret)
+ dev_err(&pf->pdev->dev,
+- "Failed set tx rate (%llu Mbps) for vsi->seid %u, err %s aq_err %s\n",
+- max_tx_rate, seid, i40e_stat_str(&pf->hw, ret),
++ "Failed set tx rate (%llu Mbps) for vsi->seid %u, err %d aq_err %s\n",
++ max_tx_rate, seid, ret,
+ i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
+ return ret;
+ }
+@@ -6038,8 +6038,8 @@ static void i40e_remove_queue_channels(struct i40e_vsi *vsi)
+ last_aq_status = pf->hw.aq.asq_last_status;
+ if (ret)
+ dev_info(&pf->pdev->dev,
+- "Failed to delete cloud filter, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "Failed to delete cloud filter, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw, last_aq_status));
+ kfree(cfilter);
+ }
+@@ -6173,8 +6173,8 @@ static int i40e_vsi_reconfig_rss(struct i40e_vsi *vsi, u16 rss_size)
+ ret = i40e_config_rss(vsi, seed, lut, vsi->rss_table_size);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "Cannot set RSS lut, err %s aq_err %s\n",
+- i40e_stat_str(hw, ret),
++ "Cannot set RSS lut, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(hw, hw->aq.asq_last_status));
+ kfree(lut);
+ return ret;
+@@ -6272,8 +6272,8 @@ static int i40e_add_channel(struct i40e_pf *pf, u16 uplink_seid,
+ ret = i40e_aq_add_vsi(hw, &ctxt, NULL);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "add new vsi failed, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "add new vsi failed, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw,
+ pf->hw.aq.asq_last_status));
+ return -ENOENT;
+@@ -6304,7 +6304,7 @@ static int i40e_channel_config_bw(struct i40e_vsi *vsi, struct i40e_channel *ch,
+ u8 *bw_share)
+ {
+ struct i40e_aqc_configure_vsi_tc_bw_data bw_data;
+- i40e_status ret;
++ int ret;
+ int i;
+
+ memset(&bw_data, 0, sizeof(bw_data));
+@@ -6340,9 +6340,9 @@ static int i40e_channel_config_tx_ring(struct i40e_pf *pf,
+ struct i40e_vsi *vsi,
+ struct i40e_channel *ch)
+ {
+- i40e_status ret;
+- int i;
+ u8 bw_share[I40E_MAX_TRAFFIC_CLASS] = {0};
++ int ret;
++ int i;
+
+ /* Enable ETS TCs with equal BW Share for now across all VSIs */
+ for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
+@@ -6518,8 +6518,8 @@ static int i40e_validate_and_set_switch_mode(struct i40e_vsi *vsi)
+ mode, NULL);
+ if (ret && hw->aq.asq_last_status != I40E_AQ_RC_ESRCH)
+ dev_err(&pf->pdev->dev,
+- "couldn't set switch config bits, err %s aq_err %s\n",
+- i40e_stat_str(hw, ret),
++ "couldn't set switch config bits, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(hw,
+ hw->aq.asq_last_status));
+
+@@ -6719,8 +6719,8 @@ int i40e_veb_config_tc(struct i40e_veb *veb, u8 enabled_tc)
+ &bw_data, NULL);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "VEB bw config failed, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "VEB bw config failed, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
+ goto out;
+ }
+@@ -6729,8 +6729,8 @@ int i40e_veb_config_tc(struct i40e_veb *veb, u8 enabled_tc)
+ ret = i40e_veb_get_bw_info(veb);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "Failed getting veb bw config, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "Failed getting veb bw config, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
+ }
+
+@@ -6813,8 +6813,8 @@ static int i40e_resume_port_tx(struct i40e_pf *pf)
+ ret = i40e_aq_resume_port_tx(hw, NULL);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "Resume Port Tx failed, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "Resume Port Tx failed, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
+ /* Schedule PF reset to recover */
+ set_bit(__I40E_PF_RESET_REQUESTED, pf->state);
+@@ -6838,8 +6838,8 @@ static int i40e_suspend_port_tx(struct i40e_pf *pf)
+ ret = i40e_aq_suspend_port_tx(hw, pf->mac_seid, NULL);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "Suspend Port Tx failed, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "Suspend Port Tx failed, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
+ /* Schedule PF reset to recover */
+ set_bit(__I40E_PF_RESET_REQUESTED, pf->state);
+@@ -6878,8 +6878,8 @@ static int i40e_hw_set_dcb_config(struct i40e_pf *pf,
+ ret = i40e_set_dcb_config(&pf->hw);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "Set DCB Config failed, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "Set DCB Config failed, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
+ goto out;
+ }
+@@ -6995,8 +6995,8 @@ int i40e_hw_dcb_config(struct i40e_pf *pf, struct i40e_dcbx_config *new_cfg)
+ i40e_aqc_opc_modify_switching_comp_ets, NULL);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "Modify Port ETS failed, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "Modify Port ETS failed, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
+ goto out;
+ }
+@@ -7033,8 +7033,8 @@ int i40e_hw_dcb_config(struct i40e_pf *pf, struct i40e_dcbx_config *new_cfg)
+ ret = i40e_aq_dcb_updated(&pf->hw, NULL);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "DCB Updated failed, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "DCB Updated failed, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
+ goto out;
+ }
+@@ -7117,8 +7117,8 @@ int i40e_dcb_sw_default_config(struct i40e_pf *pf)
+ i40e_aqc_opc_enable_switching_comp_ets, NULL);
+ if (err) {
+ dev_info(&pf->pdev->dev,
+- "Enable Port ETS failed, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, err),
++ "Enable Port ETS failed, err %d aq_err %s\n",
++ err,
+ i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
+ err = -ENOENT;
+ goto out;
+@@ -7197,8 +7197,8 @@ static int i40e_init_pf_dcb(struct i40e_pf *pf)
+ pf->flags |= I40E_FLAG_DISABLE_FW_LLDP;
+ } else {
+ dev_info(&pf->pdev->dev,
+- "Query for DCB configuration failed, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, err),
++ "Query for DCB configuration failed, err %d aq_err %s\n",
++ err,
+ i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
+ }
+
+@@ -7416,15 +7416,15 @@ static void i40e_vsi_reinit_locked(struct i40e_vsi *vsi)
+ * @pf: board private structure
+ * @is_up: whether the link state should be forced up or down
+ **/
+-static i40e_status i40e_force_link_state(struct i40e_pf *pf, bool is_up)
++static int i40e_force_link_state(struct i40e_pf *pf, bool is_up)
+ {
+ struct i40e_aq_get_phy_abilities_resp abilities;
+ struct i40e_aq_set_phy_config config = {0};
+ bool non_zero_phy_type = is_up;
+ struct i40e_hw *hw = &pf->hw;
+- i40e_status err;
+ u64 mask;
+ u8 speed;
++ int err;
+
+ /* Card might've been put in an unstable state by other drivers
+ * and applications, which causes incorrect speed values being
+@@ -7436,8 +7436,8 @@ static i40e_status i40e_force_link_state(struct i40e_pf *pf, bool is_up)
+ NULL);
+ if (err) {
+ dev_err(&pf->pdev->dev,
+- "failed to get phy cap., ret = %s last_status = %s\n",
+- i40e_stat_str(hw, err),
++ "failed to get phy cap., ret = %d last_status = %s\n",
++ err,
+ i40e_aq_str(hw, hw->aq.asq_last_status));
+ return err;
+ }
+@@ -7448,8 +7448,8 @@ static i40e_status i40e_force_link_state(struct i40e_pf *pf, bool is_up)
+ NULL);
+ if (err) {
+ dev_err(&pf->pdev->dev,
+- "failed to get phy cap., ret = %s last_status = %s\n",
+- i40e_stat_str(hw, err),
++ "failed to get phy cap., ret = %d last_status = %s\n",
++ err,
+ i40e_aq_str(hw, hw->aq.asq_last_status));
+ return err;
+ }
+@@ -7493,8 +7493,8 @@ static i40e_status i40e_force_link_state(struct i40e_pf *pf, bool is_up)
+
+ if (err) {
+ dev_err(&pf->pdev->dev,
+- "set phy config ret = %s last_status = %s\n",
+- i40e_stat_str(&pf->hw, err),
++ "set phy config ret = %d last_status = %s\n",
++ err,
+ i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
+ return err;
+ }
+@@ -7657,11 +7657,11 @@ static void i40e_vsi_set_default_tc_config(struct i40e_vsi *vsi)
+ * This function deletes a mac filter on the channel VSI which serves as the
+ * macvlan. Returns 0 on success.
+ **/
+-static i40e_status i40e_del_macvlan_filter(struct i40e_hw *hw, u16 seid,
+- const u8 *macaddr, int *aq_err)
++static int i40e_del_macvlan_filter(struct i40e_hw *hw, u16 seid,
++ const u8 *macaddr, int *aq_err)
+ {
+ struct i40e_aqc_remove_macvlan_element_data element;
+- i40e_status status;
++ int status;
+
+ memset(&element, 0, sizeof(element));
+ ether_addr_copy(element.mac_addr, macaddr);
+@@ -7683,12 +7683,12 @@ static i40e_status i40e_del_macvlan_filter(struct i40e_hw *hw, u16 seid,
+ * This function adds a mac filter on the channel VSI which serves as the
+ * macvlan. Returns 0 on success.
+ **/
+-static i40e_status i40e_add_macvlan_filter(struct i40e_hw *hw, u16 seid,
+- const u8 *macaddr, int *aq_err)
++static int i40e_add_macvlan_filter(struct i40e_hw *hw, u16 seid,
++ const u8 *macaddr, int *aq_err)
+ {
+ struct i40e_aqc_add_macvlan_element_data element;
+- i40e_status status;
+ u16 cmd_flags = 0;
++ int status;
+
+ ether_addr_copy(element.mac_addr, macaddr);
+ element.vlan_tag = 0;
+@@ -7834,8 +7834,8 @@ static int i40e_fwd_ring_up(struct i40e_vsi *vsi, struct net_device *vdev,
+ rx_ring->netdev = NULL;
+ }
+ dev_info(&pf->pdev->dev,
+- "Error adding mac filter on macvlan err %s, aq_err %s\n",
+- i40e_stat_str(hw, ret),
++ "Error adding mac filter on macvlan err %d, aq_err %s\n",
++ ret,
+ i40e_aq_str(hw, aq_err));
+ netdev_err(vdev, "L2fwd offload disabled to L2 filter error\n");
+ }
+@@ -7907,8 +7907,8 @@ static int i40e_setup_macvlans(struct i40e_vsi *vsi, u16 macvlan_cnt, u16 qcnt,
+ ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "Update vsi tc config failed, err %s aq_err %s\n",
+- i40e_stat_str(hw, ret),
++ "Update vsi tc config failed, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(hw, hw->aq.asq_last_status));
+ return ret;
+ }
+@@ -8123,8 +8123,8 @@ static void i40e_fwd_del(struct net_device *netdev, void *vdev)
+ ch->fwd = NULL;
+ } else {
+ dev_info(&pf->pdev->dev,
+- "Error deleting mac filter on macvlan err %s, aq_err %s\n",
+- i40e_stat_str(hw, ret),
++ "Error deleting mac filter on macvlan err %d, aq_err %s\n",
++ ret,
+ i40e_aq_str(hw, aq_err));
+ }
+ break;
+@@ -8875,8 +8875,7 @@ static int i40e_delete_clsflower(struct i40e_vsi *vsi,
+ kfree(filter);
+ if (err) {
+ dev_err(&pf->pdev->dev,
+- "Failed to delete cloud filter, err %s\n",
+- i40e_stat_str(&pf->hw, err));
++ "Failed to delete cloud filter, err %d\n", err);
+ return i40e_aq_rc_to_posix(err, pf->hw.aq.asq_last_status);
+ }
+
+@@ -9438,8 +9437,8 @@ static int i40e_handle_lldp_event(struct i40e_pf *pf,
+ pf->flags &= ~I40E_FLAG_DCB_CAPABLE;
+ } else {
+ dev_info(&pf->pdev->dev,
+- "Failed querying DCB configuration data from firmware, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "Failed querying DCB configuration data from firmware, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw,
+ pf->hw.aq.asq_last_status));
+ }
+@@ -9887,8 +9886,8 @@ static void i40e_link_event(struct i40e_pf *pf)
+ {
+ struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
+ u8 new_link_speed, old_link_speed;
+- i40e_status status;
+ bool new_link, old_link;
++ int status;
+ #ifdef CONFIG_I40E_DCB
+ int err;
+ #endif /* CONFIG_I40E_DCB */
+@@ -10099,9 +10098,9 @@ static void i40e_clean_adminq_subtask(struct i40e_pf *pf)
+ struct i40e_arq_event_info event;
+ struct i40e_hw *hw = &pf->hw;
+ u16 pending, i = 0;
+- i40e_status ret;
+ u16 opcode;
+ u32 oldval;
++ int ret;
+ u32 val;
+
+ /* Do not run clean AQ when PF reset fails */
+@@ -10265,8 +10264,8 @@ static void i40e_enable_pf_switch_lb(struct i40e_pf *pf)
+ ret = i40e_aq_get_vsi_params(&pf->hw, &ctxt, NULL);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "couldn't get PF vsi config, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "couldn't get PF vsi config, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
+ return;
+ }
+@@ -10277,8 +10276,8 @@ static void i40e_enable_pf_switch_lb(struct i40e_pf *pf)
+ ret = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "update vsi switch failed, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "update vsi switch failed, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
+ }
+ }
+@@ -10301,8 +10300,8 @@ static void i40e_disable_pf_switch_lb(struct i40e_pf *pf)
+ ret = i40e_aq_get_vsi_params(&pf->hw, &ctxt, NULL);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "couldn't get PF vsi config, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "couldn't get PF vsi config, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
+ return;
+ }
+@@ -10313,8 +10312,8 @@ static void i40e_disable_pf_switch_lb(struct i40e_pf *pf)
+ ret = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "update vsi switch failed, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "update vsi switch failed, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
+ }
+ }
+@@ -10458,8 +10457,8 @@ static int i40e_get_capabilities(struct i40e_pf *pf,
+ buf_len = data_size;
+ } else if (pf->hw.aq.asq_last_status != I40E_AQ_RC_OK || err) {
+ dev_info(&pf->pdev->dev,
+- "capability discovery failed, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, err),
++ "capability discovery failed, err %d aq_err %s\n",
++ err,
+ i40e_aq_str(&pf->hw,
+ pf->hw.aq.asq_last_status));
+ return -ENODEV;
+@@ -10580,7 +10579,7 @@ static int i40e_rebuild_cloud_filters(struct i40e_vsi *vsi, u16 seid)
+ struct i40e_cloud_filter *cfilter;
+ struct i40e_pf *pf = vsi->back;
+ struct hlist_node *node;
+- i40e_status ret;
++ int ret;
+
+ /* Add cloud filters back if they exist */
+ hlist_for_each_entry_safe(cfilter, node, &pf->cloud_filter_list,
+@@ -10596,8 +10595,8 @@ static int i40e_rebuild_cloud_filters(struct i40e_vsi *vsi, u16 seid)
+
+ if (ret) {
+ dev_dbg(&pf->pdev->dev,
+- "Failed to rebuild cloud filter, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "Failed to rebuild cloud filter, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw,
+ pf->hw.aq.asq_last_status));
+ return ret;
+@@ -10615,7 +10614,7 @@ static int i40e_rebuild_cloud_filters(struct i40e_vsi *vsi, u16 seid)
+ static int i40e_rebuild_channels(struct i40e_vsi *vsi)
+ {
+ struct i40e_channel *ch, *ch_tmp;
+- i40e_status ret;
++ int ret;
+
+ if (list_empty(&vsi->ch_list))
+ return 0;
+@@ -10691,7 +10690,7 @@ static void i40e_clean_xps_state(struct i40e_vsi *vsi)
+ static void i40e_prep_for_reset(struct i40e_pf *pf)
+ {
+ struct i40e_hw *hw = &pf->hw;
+- i40e_status ret = 0;
++ int ret = 0;
+ u32 v;
+
+ clear_bit(__I40E_RESET_INTR_RECEIVED, pf->state);
+@@ -10796,7 +10795,7 @@ static void i40e_get_oem_version(struct i40e_hw *hw)
+ static int i40e_reset(struct i40e_pf *pf)
+ {
+ struct i40e_hw *hw = &pf->hw;
+- i40e_status ret;
++ int ret;
+
+ ret = i40e_pf_reset(hw);
+ if (ret) {
+@@ -10821,7 +10820,7 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)
+ const bool is_recovery_mode_reported = i40e_check_recovery_mode(pf);
+ struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
+ struct i40e_hw *hw = &pf->hw;
+- i40e_status ret;
++ int ret;
+ u32 val;
+ int v;
+
+@@ -10837,8 +10836,8 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)
+ /* rebuild the basics for the AdminQ, HMC, and initial HW switch */
+ ret = i40e_init_adminq(&pf->hw);
+ if (ret) {
+- dev_info(&pf->pdev->dev, "Rebuild AdminQ failed, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ dev_info(&pf->pdev->dev, "Rebuild AdminQ failed, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
+ goto clear_recovery;
+ }
+@@ -10949,8 +10948,8 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)
+ I40E_AQ_EVENT_MEDIA_NA |
+ I40E_AQ_EVENT_MODULE_QUAL_FAIL), NULL);
+ if (ret)
+- dev_info(&pf->pdev->dev, "set phy mask fail, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ dev_info(&pf->pdev->dev, "set phy mask fail, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
+
+ /* Rebuild the VSIs and VEBs that existed before reset.
+@@ -11053,8 +11052,8 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)
+ msleep(75);
+ ret = i40e_aq_set_link_restart_an(&pf->hw, true, NULL);
+ if (ret)
+- dev_info(&pf->pdev->dev, "link restart failed, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ dev_info(&pf->pdev->dev, "link restart failed, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw,
+ pf->hw.aq.asq_last_status));
+ }
+@@ -11085,9 +11084,9 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)
+ ret = i40e_set_promiscuous(pf, pf->cur_promisc);
+ if (ret)
+ dev_warn(&pf->pdev->dev,
+- "Failed to restore promiscuous setting: %s, err %s aq_err %s\n",
++ "Failed to restore promiscuous setting: %s, err %d aq_err %s\n",
+ pf->cur_promisc ? "on" : "off",
+- i40e_stat_str(&pf->hw, ret),
++ ret,
+ i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
+
+ i40e_reset_all_vfs(pf, true);
+@@ -12221,8 +12220,8 @@ static int i40e_get_rss_aq(struct i40e_vsi *vsi, const u8 *seed,
+ (struct i40e_aqc_get_set_rss_key_data *)seed);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "Cannot get RSS key, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "Cannot get RSS key, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw,
+ pf->hw.aq.asq_last_status));
+ return ret;
+@@ -12235,8 +12234,8 @@ static int i40e_get_rss_aq(struct i40e_vsi *vsi, const u8 *seed,
+ ret = i40e_aq_get_rss_lut(hw, vsi->id, pf_lut, lut, lut_size);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "Cannot get RSS lut, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "Cannot get RSS lut, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw,
+ pf->hw.aq.asq_last_status));
+ return ret;
+@@ -12511,11 +12510,11 @@ int i40e_reconfig_rss_queues(struct i40e_pf *pf, int queue_count)
+ * i40e_get_partition_bw_setting - Retrieve BW settings for this PF partition
+ * @pf: board private structure
+ **/
+-i40e_status i40e_get_partition_bw_setting(struct i40e_pf *pf)
++int i40e_get_partition_bw_setting(struct i40e_pf *pf)
+ {
+- i40e_status status;
+ bool min_valid, max_valid;
+ u32 max_bw, min_bw;
++ int status;
+
+ status = i40e_read_bw_from_alt_ram(&pf->hw, &max_bw, &min_bw,
+ &min_valid, &max_valid);
+@@ -12534,10 +12533,10 @@ i40e_status i40e_get_partition_bw_setting(struct i40e_pf *pf)
+ * i40e_set_partition_bw_setting - Set BW settings for this PF partition
+ * @pf: board private structure
+ **/
+-i40e_status i40e_set_partition_bw_setting(struct i40e_pf *pf)
++int i40e_set_partition_bw_setting(struct i40e_pf *pf)
+ {
+ struct i40e_aqc_configure_partition_bw_data bw_data;
+- i40e_status status;
++ int status;
+
+ memset(&bw_data, 0, sizeof(bw_data));
+
+@@ -12556,12 +12555,12 @@ i40e_status i40e_set_partition_bw_setting(struct i40e_pf *pf)
+ * i40e_commit_partition_bw_setting - Commit BW settings for this PF partition
+ * @pf: board private structure
+ **/
+-i40e_status i40e_commit_partition_bw_setting(struct i40e_pf *pf)
++int i40e_commit_partition_bw_setting(struct i40e_pf *pf)
+ {
+ /* Commit temporary BW setting to permanent NVM image */
+ enum i40e_admin_queue_err last_aq_status;
+- i40e_status ret;
+ u16 nvm_word;
++ int ret;
+
+ if (pf->hw.partition_id != 1) {
+ dev_info(&pf->pdev->dev,
+@@ -12576,8 +12575,8 @@ i40e_status i40e_commit_partition_bw_setting(struct i40e_pf *pf)
+ last_aq_status = pf->hw.aq.asq_last_status;
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "Cannot acquire NVM for read access, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "Cannot acquire NVM for read access, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw, last_aq_status));
+ goto bw_commit_out;
+ }
+@@ -12593,8 +12592,8 @@ i40e_status i40e_commit_partition_bw_setting(struct i40e_pf *pf)
+ last_aq_status = pf->hw.aq.asq_last_status;
+ i40e_release_nvm(&pf->hw);
+ if (ret) {
+- dev_info(&pf->pdev->dev, "NVM read error, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ dev_info(&pf->pdev->dev, "NVM read error, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw, last_aq_status));
+ goto bw_commit_out;
+ }
+@@ -12607,8 +12606,8 @@ i40e_status i40e_commit_partition_bw_setting(struct i40e_pf *pf)
+ last_aq_status = pf->hw.aq.asq_last_status;
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "Cannot acquire NVM for write access, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "Cannot acquire NVM for write access, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw, last_aq_status));
+ goto bw_commit_out;
+ }
+@@ -12627,8 +12626,8 @@ i40e_status i40e_commit_partition_bw_setting(struct i40e_pf *pf)
+ i40e_release_nvm(&pf->hw);
+ if (ret)
+ dev_info(&pf->pdev->dev,
+- "BW settings NOT SAVED, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "BW settings NOT SAVED, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw, last_aq_status));
+ bw_commit_out:
+
+@@ -12649,7 +12648,7 @@ static bool i40e_is_total_port_shutdown_enabled(struct i40e_pf *pf)
+ #define I40E_LINK_BEHAVIOR_WORD_LENGTH 0x1
+ #define I40E_LINK_BEHAVIOR_OS_FORCED_ENABLED BIT(0)
+ #define I40E_LINK_BEHAVIOR_PORT_BIT_LENGTH 4
+- i40e_status read_status = I40E_SUCCESS;
++ int read_status = I40E_SUCCESS;
+ u16 sr_emp_sr_settings_ptr = 0;
+ u16 features_enable = 0;
+ u16 link_behavior = 0;
+@@ -12682,8 +12681,8 @@ static bool i40e_is_total_port_shutdown_enabled(struct i40e_pf *pf)
+
+ err_nvm:
+ dev_warn(&pf->pdev->dev,
+- "total-port-shutdown feature is off due to read nvm error: %s\n",
+- i40e_stat_str(&pf->hw, read_status));
++ "total-port-shutdown feature is off due to read nvm error: %d\n",
++ read_status);
+ return ret;
+ }
+
+@@ -13028,7 +13027,7 @@ static int i40e_udp_tunnel_set_port(struct net_device *netdev,
+ struct i40e_netdev_priv *np = netdev_priv(netdev);
+ struct i40e_hw *hw = &np->vsi->back->hw;
+ u8 type, filter_index;
+- i40e_status ret;
++ int ret;
+
+ type = ti->type == UDP_TUNNEL_TYPE_VXLAN ? I40E_AQC_TUNNEL_TYPE_VXLAN :
+ I40E_AQC_TUNNEL_TYPE_NGE;
+@@ -13036,8 +13035,8 @@ static int i40e_udp_tunnel_set_port(struct net_device *netdev,
+ ret = i40e_aq_add_udp_tunnel(hw, ntohs(ti->port), type, &filter_index,
+ NULL);
+ if (ret) {
+- netdev_info(netdev, "add UDP port failed, err %s aq_err %s\n",
+- i40e_stat_str(hw, ret),
++ netdev_info(netdev, "add UDP port failed, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(hw, hw->aq.asq_last_status));
+ return -EIO;
+ }
+@@ -13052,12 +13051,12 @@ static int i40e_udp_tunnel_unset_port(struct net_device *netdev,
+ {
+ struct i40e_netdev_priv *np = netdev_priv(netdev);
+ struct i40e_hw *hw = &np->vsi->back->hw;
+- i40e_status ret;
++ int ret;
+
+ ret = i40e_aq_del_udp_tunnel(hw, ti->hw_priv, NULL);
+ if (ret) {
+- netdev_info(netdev, "delete UDP port failed, err %s aq_err %s\n",
+- i40e_stat_str(hw, ret),
++ netdev_info(netdev, "delete UDP port failed, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(hw, hw->aq.asq_last_status));
+ return -EIO;
+ }
+@@ -13946,8 +13945,8 @@ static int i40e_add_vsi(struct i40e_vsi *vsi)
+ ctxt.flags = I40E_AQ_VSI_TYPE_PF;
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "couldn't get PF vsi config, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "couldn't get PF vsi config, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw,
+ pf->hw.aq.asq_last_status));
+ return -ENOENT;
+@@ -13976,8 +13975,8 @@ static int i40e_add_vsi(struct i40e_vsi *vsi)
+ ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "update vsi failed, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "update vsi failed, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw,
+ pf->hw.aq.asq_last_status));
+ ret = -ENOENT;
+@@ -13996,8 +13995,8 @@ static int i40e_add_vsi(struct i40e_vsi *vsi)
+ ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "update vsi failed, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "update vsi failed, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw,
+ pf->hw.aq.asq_last_status));
+ ret = -ENOENT;
+@@ -14019,9 +14018,9 @@ static int i40e_add_vsi(struct i40e_vsi *vsi)
+ * message and continue
+ */
+ dev_info(&pf->pdev->dev,
+- "failed to configure TCs for main VSI tc_map 0x%08x, err %s aq_err %s\n",
++ "failed to configure TCs for main VSI tc_map 0x%08x, err %d aq_err %s\n",
+ enabled_tc,
+- i40e_stat_str(&pf->hw, ret),
++ ret,
+ i40e_aq_str(&pf->hw,
+ pf->hw.aq.asq_last_status));
+ }
+@@ -14115,8 +14114,8 @@ static int i40e_add_vsi(struct i40e_vsi *vsi)
+ ret = i40e_aq_add_vsi(hw, &ctxt, NULL);
+ if (ret) {
+ dev_info(&vsi->back->pdev->dev,
+- "add vsi failed, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "add vsi failed, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw,
+ pf->hw.aq.asq_last_status));
+ ret = -ENOENT;
+@@ -14147,8 +14146,8 @@ static int i40e_add_vsi(struct i40e_vsi *vsi)
+ ret = i40e_vsi_get_bw_info(vsi);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "couldn't get vsi bw info, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "couldn't get vsi bw info, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
+ /* VSI is already added so not tearing that up */
+ ret = 0;
+@@ -14594,8 +14593,8 @@ static int i40e_veb_get_bw_info(struct i40e_veb *veb)
+ &bw_data, NULL);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "query veb bw config failed, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "query veb bw config failed, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw, hw->aq.asq_last_status));
+ goto out;
+ }
+@@ -14604,8 +14603,8 @@ static int i40e_veb_get_bw_info(struct i40e_veb *veb)
+ &ets_data, NULL);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "query veb bw ets config failed, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "query veb bw ets config failed, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw, hw->aq.asq_last_status));
+ goto out;
+ }
+@@ -14801,8 +14800,8 @@ static int i40e_add_veb(struct i40e_veb *veb, struct i40e_vsi *vsi)
+ /* get a VEB from the hardware */
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "couldn't add VEB, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "couldn't add VEB, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
+ return -EPERM;
+ }
+@@ -14812,16 +14811,16 @@ static int i40e_add_veb(struct i40e_veb *veb, struct i40e_vsi *vsi)
+ &veb->stats_idx, NULL, NULL, NULL);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "couldn't get VEB statistics idx, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "couldn't get VEB statistics idx, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
+ return -EPERM;
+ }
+ ret = i40e_veb_get_bw_info(veb);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "couldn't get VEB bw info, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "couldn't get VEB bw info, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
+ i40e_aq_delete_element(&pf->hw, veb->seid, NULL);
+ return -ENOENT;
+@@ -15031,8 +15030,8 @@ int i40e_fetch_switch_configuration(struct i40e_pf *pf, bool printconfig)
+ &next_seid, NULL);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "get switch config failed err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "get switch config failed err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw,
+ pf->hw.aq.asq_last_status));
+ kfree(aq_buf);
+@@ -15077,8 +15076,8 @@ static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit, bool lock_acqui
+ ret = i40e_fetch_switch_configuration(pf, false);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+- "couldn't fetch switch config, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "couldn't fetch switch config, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
+ return ret;
+ }
+@@ -15104,8 +15103,8 @@ static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit, bool lock_acqui
+ NULL);
+ if (ret && pf->hw.aq.asq_last_status != I40E_AQ_RC_ESRCH) {
+ dev_info(&pf->pdev->dev,
+- "couldn't set switch config bits, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, ret),
++ "couldn't set switch config bits, err %d aq_err %s\n",
++ ret,
+ i40e_aq_str(&pf->hw,
+ pf->hw.aq.asq_last_status));
+ /* not a fatal problem, just keep going */
+@@ -15442,13 +15441,12 @@ static bool i40e_check_recovery_mode(struct i40e_pf *pf)
+ *
+ * Return 0 on success, negative on failure.
+ **/
+-static i40e_status i40e_pf_loop_reset(struct i40e_pf *pf)
++static int i40e_pf_loop_reset(struct i40e_pf *pf)
+ {
+ /* wait max 10 seconds for PF reset to succeed */
+ const unsigned long time_end = jiffies + 10 * HZ;
+-
+ struct i40e_hw *hw = &pf->hw;
+- i40e_status ret;
++ int ret;
+
+ ret = i40e_pf_reset(hw);
+ while (ret != I40E_SUCCESS && time_before(jiffies, time_end)) {
+@@ -15494,9 +15492,9 @@ static bool i40e_check_fw_empr(struct i40e_pf *pf)
+ * Return 0 if NIC is healthy or negative value when there are issues
+ * with resets
+ **/
+-static i40e_status i40e_handle_resets(struct i40e_pf *pf)
++static int i40e_handle_resets(struct i40e_pf *pf)
+ {
+- const i40e_status pfr = i40e_pf_loop_reset(pf);
++ const int pfr = i40e_pf_loop_reset(pf);
+ const bool is_empr = i40e_check_fw_empr(pf);
+
+ if (is_empr || pfr != I40E_SUCCESS)
+@@ -15635,13 +15633,15 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ struct i40e_aq_get_phy_abilities_resp abilities;
+ #ifdef CONFIG_I40E_DCB
+ enum i40e_get_fw_lldp_status_resp lldp_status;
+- i40e_status status;
+ #endif /* CONFIG_I40E_DCB */
+ struct i40e_pf *pf;
+ struct i40e_hw *hw;
+ static u16 pfs_found;
+ u16 wol_nvm_bits;
+ u16 link_status;
++#ifdef CONFIG_I40E_DCB
++ int status;
++#endif /* CONFIG_I40E_DCB */
+ int err;
+ u32 val;
+ u32 i;
+@@ -16010,8 +16010,8 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ I40E_AQ_EVENT_MEDIA_NA |
+ I40E_AQ_EVENT_MODULE_QUAL_FAIL), NULL);
+ if (err)
+- dev_info(&pf->pdev->dev, "set phy mask fail, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, err),
++ dev_info(&pf->pdev->dev, "set phy mask fail, err %d aq_err %s\n",
++ err,
+ i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
+
+ /* Reconfigure hardware for allowing smaller MSS in the case
+@@ -16029,8 +16029,8 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ msleep(75);
+ err = i40e_aq_set_link_restart_an(&pf->hw, true, NULL);
+ if (err)
+- dev_info(&pf->pdev->dev, "link restart failed, err %s aq_err %s\n",
+- i40e_stat_str(&pf->hw, err),
++ dev_info(&pf->pdev->dev, "link restart failed, err %d aq_err %s\n",
++ err,
+ i40e_aq_str(&pf->hw,
+ pf->hw.aq.asq_last_status));
+ }
+@@ -16162,8 +16162,8 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ /* get the requested speeds from the fw */
+ err = i40e_aq_get_phy_capabilities(hw, false, false, &abilities, NULL);
+ if (err)
+- dev_dbg(&pf->pdev->dev, "get requested speeds ret = %s last_status = %s\n",
+- i40e_stat_str(&pf->hw, err),
++ dev_dbg(&pf->pdev->dev, "get requested speeds ret = %d last_status = %s\n",
++ err,
+ i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
+ pf->hw.phy.link_info.requested_speeds = abilities.link_speed;
+
+@@ -16173,8 +16173,8 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ /* get the supported phy types from the fw */
+ err = i40e_aq_get_phy_capabilities(hw, false, true, &abilities, NULL);
+ if (err)
+- dev_dbg(&pf->pdev->dev, "get supported phy types ret = %s last_status = %s\n",
+- i40e_stat_str(&pf->hw, err),
++ dev_dbg(&pf->pdev->dev, "get supported phy types ret = %d last_status = %s\n",
++ err,
+ i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
+
+ /* make sure the MFS hasn't been set lower than the default */
+@@ -16245,7 +16245,7 @@ static void i40e_remove(struct pci_dev *pdev)
+ {
+ struct i40e_pf *pf = pci_get_drvdata(pdev);
+ struct i40e_hw *hw = &pf->hw;
+- i40e_status ret_code;
++ int ret_code;
+ int i;
+
+ i40e_dbg_pf_exit(pf);
+@@ -16493,9 +16493,9 @@ static void i40e_pci_error_resume(struct pci_dev *pdev)
+ static void i40e_enable_mc_magic_wake(struct i40e_pf *pf)
+ {
+ struct i40e_hw *hw = &pf->hw;
+- i40e_status ret;
+ u8 mac_addr[6];
+ u16 flags = 0;
++ int ret;
+
+ /* Get current MAC address in case it's an LAA */
+ if (pf->vsi[pf->lan_vsi] && pf->vsi[pf->lan_vsi]->netdev) {
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_nvm.c b/drivers/net/ethernet/intel/i40e/i40e_nvm.c
+index 3a38bf8bcde7e..17e3f26eee4a4 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_nvm.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_nvm.c
+@@ -13,10 +13,10 @@
+ * in this file) as an equivalent of the FLASH part mapped into the SR.
+ * We are accessing FLASH always thru the Shadow RAM.
+ **/
+-i40e_status i40e_init_nvm(struct i40e_hw *hw)
++int i40e_init_nvm(struct i40e_hw *hw)
+ {
+ struct i40e_nvm_info *nvm = &hw->nvm;
+- i40e_status ret_code = 0;
++ int ret_code = 0;
+ u32 fla, gens;
+ u8 sr_size;
+
+@@ -52,12 +52,12 @@ i40e_status i40e_init_nvm(struct i40e_hw *hw)
+ * This function will request NVM ownership for reading
+ * via the proper Admin Command.
+ **/
+-i40e_status i40e_acquire_nvm(struct i40e_hw *hw,
+- enum i40e_aq_resource_access_type access)
++int i40e_acquire_nvm(struct i40e_hw *hw,
++ enum i40e_aq_resource_access_type access)
+ {
+- i40e_status ret_code = 0;
+ u64 gtime, timeout;
+ u64 time_left = 0;
++ int ret_code = 0;
+
+ if (hw->nvm.blank_nvm_mode)
+ goto i40e_i40e_acquire_nvm_exit;
+@@ -111,7 +111,7 @@ i40e_i40e_acquire_nvm_exit:
+ **/
+ void i40e_release_nvm(struct i40e_hw *hw)
+ {
+- i40e_status ret_code = I40E_SUCCESS;
++ int ret_code = I40E_SUCCESS;
+ u32 total_delay = 0;
+
+ if (hw->nvm.blank_nvm_mode)
+@@ -138,9 +138,9 @@ void i40e_release_nvm(struct i40e_hw *hw)
+ *
+ * Polls the SRCTL Shadow RAM register done bit.
+ **/
+-static i40e_status i40e_poll_sr_srctl_done_bit(struct i40e_hw *hw)
++static int i40e_poll_sr_srctl_done_bit(struct i40e_hw *hw)
+ {
+- i40e_status ret_code = I40E_ERR_TIMEOUT;
++ int ret_code = I40E_ERR_TIMEOUT;
+ u32 srctl, wait_cnt;
+
+ /* Poll the I40E_GLNVM_SRCTL until the done bit is set */
+@@ -165,10 +165,10 @@ static i40e_status i40e_poll_sr_srctl_done_bit(struct i40e_hw *hw)
+ *
+ * Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register.
+ **/
+-static i40e_status i40e_read_nvm_word_srctl(struct i40e_hw *hw, u16 offset,
+- u16 *data)
++static int i40e_read_nvm_word_srctl(struct i40e_hw *hw, u16 offset,
++ u16 *data)
+ {
+- i40e_status ret_code = I40E_ERR_TIMEOUT;
++ int ret_code = I40E_ERR_TIMEOUT;
+ u32 sr_reg;
+
+ if (offset >= hw->nvm.sr_size) {
+@@ -216,13 +216,13 @@ read_nvm_exit:
+ *
+ * Writes a 16 bit words buffer to the Shadow RAM using the admin command.
+ **/
+-static i40e_status i40e_read_nvm_aq(struct i40e_hw *hw,
+- u8 module_pointer, u32 offset,
+- u16 words, void *data,
+- bool last_command)
++static int i40e_read_nvm_aq(struct i40e_hw *hw,
++ u8 module_pointer, u32 offset,
++ u16 words, void *data,
++ bool last_command)
+ {
+- i40e_status ret_code = I40E_ERR_NVM;
+ struct i40e_asq_cmd_details cmd_details;
++ int ret_code = I40E_ERR_NVM;
+
+ memset(&cmd_details, 0, sizeof(cmd_details));
+ cmd_details.wb_desc = &hw->nvm_wb_desc;
+@@ -264,10 +264,10 @@ static i40e_status i40e_read_nvm_aq(struct i40e_hw *hw,
+ *
+ * Reads one 16 bit word from the Shadow RAM using the AdminQ
+ **/
+-static i40e_status i40e_read_nvm_word_aq(struct i40e_hw *hw, u16 offset,
+- u16 *data)
++static int i40e_read_nvm_word_aq(struct i40e_hw *hw, u16 offset,
++ u16 *data)
+ {
+- i40e_status ret_code = I40E_ERR_TIMEOUT;
++ int ret_code = I40E_ERR_TIMEOUT;
+
+ ret_code = i40e_read_nvm_aq(hw, 0x0, offset, 1, data, true);
+ *data = le16_to_cpu(*(__le16 *)data);
+@@ -286,8 +286,8 @@ static i40e_status i40e_read_nvm_word_aq(struct i40e_hw *hw, u16 offset,
+ * Do not use this function except in cases where the nvm lock is already
+ * taken via i40e_acquire_nvm().
+ **/
+-static i40e_status __i40e_read_nvm_word(struct i40e_hw *hw,
+- u16 offset, u16 *data)
++static int __i40e_read_nvm_word(struct i40e_hw *hw,
++ u16 offset, u16 *data)
+ {
+ if (hw->flags & I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE)
+ return i40e_read_nvm_word_aq(hw, offset, data);
+@@ -303,10 +303,10 @@ static i40e_status __i40e_read_nvm_word(struct i40e_hw *hw,
+ *
+ * Reads one 16 bit word from the Shadow RAM.
+ **/
+-i40e_status i40e_read_nvm_word(struct i40e_hw *hw, u16 offset,
+- u16 *data)
++int i40e_read_nvm_word(struct i40e_hw *hw, u16 offset,
++ u16 *data)
+ {
+- i40e_status ret_code = 0;
++ int ret_code = 0;
+
+ if (hw->flags & I40E_HW_FLAG_NVM_READ_REQUIRES_LOCK)
+ ret_code = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
+@@ -330,17 +330,17 @@ i40e_status i40e_read_nvm_word(struct i40e_hw *hw, u16 offset,
+ * @words_data_size: Words to read from NVM
+ * @data_ptr: Pointer to memory location where resulting buffer will be stored
+ **/
+-enum i40e_status_code i40e_read_nvm_module_data(struct i40e_hw *hw,
+- u8 module_ptr,
+- u16 module_offset,
+- u16 data_offset,
+- u16 words_data_size,
+- u16 *data_ptr)
++int i40e_read_nvm_module_data(struct i40e_hw *hw,
++ u8 module_ptr,
++ u16 module_offset,
++ u16 data_offset,
++ u16 words_data_size,
++ u16 *data_ptr)
+ {
+- i40e_status status;
+ u16 specific_ptr = 0;
+ u16 ptr_value = 0;
+ u32 offset = 0;
++ int status;
+
+ if (module_ptr != 0) {
+ status = i40e_read_nvm_word(hw, module_ptr, &ptr_value);
+@@ -406,10 +406,10 @@ enum i40e_status_code i40e_read_nvm_module_data(struct i40e_hw *hw,
+ * method. The buffer read is preceded by the NVM ownership take
+ * and followed by the release.
+ **/
+-static i40e_status i40e_read_nvm_buffer_srctl(struct i40e_hw *hw, u16 offset,
+- u16 *words, u16 *data)
++static int i40e_read_nvm_buffer_srctl(struct i40e_hw *hw, u16 offset,
++ u16 *words, u16 *data)
+ {
+- i40e_status ret_code = 0;
++ int ret_code = 0;
+ u16 index, word;
+
+ /* Loop thru the selected region */
+@@ -437,13 +437,13 @@ static i40e_status i40e_read_nvm_buffer_srctl(struct i40e_hw *hw, u16 offset,
+ * method. The buffer read is preceded by the NVM ownership take
+ * and followed by the release.
+ **/
+-static i40e_status i40e_read_nvm_buffer_aq(struct i40e_hw *hw, u16 offset,
+- u16 *words, u16 *data)
++static int i40e_read_nvm_buffer_aq(struct i40e_hw *hw, u16 offset,
++ u16 *words, u16 *data)
+ {
+- i40e_status ret_code;
+- u16 read_size;
+ bool last_cmd = false;
+ u16 words_read = 0;
++ u16 read_size;
++ int ret_code;
+ u16 i = 0;
+
+ do {
+@@ -493,9 +493,9 @@ read_nvm_buffer_aq_exit:
+ * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_srrd()
+ * method.
+ **/
+-static i40e_status __i40e_read_nvm_buffer(struct i40e_hw *hw,
+- u16 offset, u16 *words,
+- u16 *data)
++static int __i40e_read_nvm_buffer(struct i40e_hw *hw,
++ u16 offset, u16 *words,
++ u16 *data)
+ {
+ if (hw->flags & I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE)
+ return i40e_read_nvm_buffer_aq(hw, offset, words, data);
+@@ -514,10 +514,10 @@ static i40e_status __i40e_read_nvm_buffer(struct i40e_hw *hw,
+ * method. The buffer read is preceded by the NVM ownership take
+ * and followed by the release.
+ **/
+-i40e_status i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset,
+- u16 *words, u16 *data)
++int i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset,
++ u16 *words, u16 *data)
+ {
+- i40e_status ret_code = 0;
++ int ret_code = 0;
+
+ if (hw->flags & I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE) {
+ ret_code = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
+@@ -544,12 +544,12 @@ i40e_status i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset,
+ *
+ * Writes a 16 bit words buffer to the Shadow RAM using the admin command.
+ **/
+-static i40e_status i40e_write_nvm_aq(struct i40e_hw *hw, u8 module_pointer,
+- u32 offset, u16 words, void *data,
+- bool last_command)
++static int i40e_write_nvm_aq(struct i40e_hw *hw, u8 module_pointer,
++ u32 offset, u16 words, void *data,
++ bool last_command)
+ {
+- i40e_status ret_code = I40E_ERR_NVM;
+ struct i40e_asq_cmd_details cmd_details;
++ int ret_code = I40E_ERR_NVM;
+
+ memset(&cmd_details, 0, sizeof(cmd_details));
+ cmd_details.wb_desc = &hw->nvm_wb_desc;
+@@ -594,14 +594,14 @@ static i40e_status i40e_write_nvm_aq(struct i40e_hw *hw, u8 module_pointer,
+ * is customer specific and unknown. Therefore, this function skips all maximum
+ * possible size of VPD (1kB).
+ **/
+-static i40e_status i40e_calc_nvm_checksum(struct i40e_hw *hw,
+- u16 *checksum)
++static int i40e_calc_nvm_checksum(struct i40e_hw *hw,
++ u16 *checksum)
+ {
+- i40e_status ret_code;
+ struct i40e_virt_mem vmem;
+ u16 pcie_alt_module = 0;
+ u16 checksum_local = 0;
+ u16 vpd_module = 0;
++ int ret_code;
+ u16 *data;
+ u16 i = 0;
+
+@@ -675,11 +675,11 @@ i40e_calc_nvm_checksum_exit:
+ * on ARQ completion event reception by caller.
+ * This function will commit SR to NVM.
+ **/
+-i40e_status i40e_update_nvm_checksum(struct i40e_hw *hw)
++int i40e_update_nvm_checksum(struct i40e_hw *hw)
+ {
+- i40e_status ret_code;
+- u16 checksum;
+ __le16 le_sum;
++ int ret_code;
++ u16 checksum;
+
+ ret_code = i40e_calc_nvm_checksum(hw, &checksum);
+ if (!ret_code) {
+@@ -699,12 +699,12 @@ i40e_status i40e_update_nvm_checksum(struct i40e_hw *hw)
+ * Performs checksum calculation and validates the NVM SW checksum. If the
+ * caller does not need checksum, the value can be NULL.
+ **/
+-i40e_status i40e_validate_nvm_checksum(struct i40e_hw *hw,
+- u16 *checksum)
++int i40e_validate_nvm_checksum(struct i40e_hw *hw,
++ u16 *checksum)
+ {
+- i40e_status ret_code = 0;
+- u16 checksum_sr = 0;
+ u16 checksum_local = 0;
++ u16 checksum_sr = 0;
++ int ret_code = 0;
+
+ /* We must acquire the NVM lock in order to correctly synchronize the
+ * NVM accesses across multiple PFs. Without doing so it is possible
+@@ -733,36 +733,36 @@ i40e_status i40e_validate_nvm_checksum(struct i40e_hw *hw,
+ return ret_code;
+ }
+
+-static i40e_status i40e_nvmupd_state_init(struct i40e_hw *hw,
+- struct i40e_nvm_access *cmd,
+- u8 *bytes, int *perrno);
+-static i40e_status i40e_nvmupd_state_reading(struct i40e_hw *hw,
+- struct i40e_nvm_access *cmd,
+- u8 *bytes, int *perrno);
+-static i40e_status i40e_nvmupd_state_writing(struct i40e_hw *hw,
+- struct i40e_nvm_access *cmd,
+- u8 *bytes, int *errno);
++static int i40e_nvmupd_state_init(struct i40e_hw *hw,
++ struct i40e_nvm_access *cmd,
++ u8 *bytes, int *perrno);
++static int i40e_nvmupd_state_reading(struct i40e_hw *hw,
++ struct i40e_nvm_access *cmd,
++ u8 *bytes, int *perrno);
++static int i40e_nvmupd_state_writing(struct i40e_hw *hw,
++ struct i40e_nvm_access *cmd,
++ u8 *bytes, int *errno);
+ static enum i40e_nvmupd_cmd i40e_nvmupd_validate_command(struct i40e_hw *hw,
+ struct i40e_nvm_access *cmd,
+ int *perrno);
+-static i40e_status i40e_nvmupd_nvm_erase(struct i40e_hw *hw,
+- struct i40e_nvm_access *cmd,
+- int *perrno);
+-static i40e_status i40e_nvmupd_nvm_write(struct i40e_hw *hw,
+- struct i40e_nvm_access *cmd,
+- u8 *bytes, int *perrno);
+-static i40e_status i40e_nvmupd_nvm_read(struct i40e_hw *hw,
+- struct i40e_nvm_access *cmd,
+- u8 *bytes, int *perrno);
+-static i40e_status i40e_nvmupd_exec_aq(struct i40e_hw *hw,
+- struct i40e_nvm_access *cmd,
+- u8 *bytes, int *perrno);
+-static i40e_status i40e_nvmupd_get_aq_result(struct i40e_hw *hw,
+- struct i40e_nvm_access *cmd,
+- u8 *bytes, int *perrno);
+-static i40e_status i40e_nvmupd_get_aq_event(struct i40e_hw *hw,
+- struct i40e_nvm_access *cmd,
+- u8 *bytes, int *perrno);
++static int i40e_nvmupd_nvm_erase(struct i40e_hw *hw,
++ struct i40e_nvm_access *cmd,
++ int *perrno);
++static int i40e_nvmupd_nvm_write(struct i40e_hw *hw,
++ struct i40e_nvm_access *cmd,
++ u8 *bytes, int *perrno);
++static int i40e_nvmupd_nvm_read(struct i40e_hw *hw,
++ struct i40e_nvm_access *cmd,
++ u8 *bytes, int *perrno);
++static int i40e_nvmupd_exec_aq(struct i40e_hw *hw,
++ struct i40e_nvm_access *cmd,
++ u8 *bytes, int *perrno);
++static int i40e_nvmupd_get_aq_result(struct i40e_hw *hw,
++ struct i40e_nvm_access *cmd,
++ u8 *bytes, int *perrno);
++static int i40e_nvmupd_get_aq_event(struct i40e_hw *hw,
++ struct i40e_nvm_access *cmd,
++ u8 *bytes, int *perrno);
+ static inline u8 i40e_nvmupd_get_module(u32 val)
+ {
+ return (u8)(val & I40E_NVM_MOD_PNT_MASK);
+@@ -807,12 +807,12 @@ static const char * const i40e_nvm_update_state_str[] = {
+ *
+ * Dispatches command depending on what update state is current
+ **/
+-i40e_status i40e_nvmupd_command(struct i40e_hw *hw,
+- struct i40e_nvm_access *cmd,
+- u8 *bytes, int *perrno)
++int i40e_nvmupd_command(struct i40e_hw *hw,
++ struct i40e_nvm_access *cmd,
++ u8 *bytes, int *perrno)
+ {
+- i40e_status status;
+ enum i40e_nvmupd_cmd upd_cmd;
++ int status;
+
+ /* assume success */
+ *perrno = 0;
+@@ -923,12 +923,12 @@ i40e_status i40e_nvmupd_command(struct i40e_hw *hw,
+ * Process legitimate commands of the Init state and conditionally set next
+ * state. Reject all other commands.
+ **/
+-static i40e_status i40e_nvmupd_state_init(struct i40e_hw *hw,
+- struct i40e_nvm_access *cmd,
+- u8 *bytes, int *perrno)
++static int i40e_nvmupd_state_init(struct i40e_hw *hw,
++ struct i40e_nvm_access *cmd,
++ u8 *bytes, int *perrno)
+ {
+- i40e_status status = 0;
+ enum i40e_nvmupd_cmd upd_cmd;
++ int status = 0;
+
+ upd_cmd = i40e_nvmupd_validate_command(hw, cmd, perrno);
+
+@@ -1062,12 +1062,12 @@ static i40e_status i40e_nvmupd_state_init(struct i40e_hw *hw,
+ * NVM ownership is already held. Process legitimate commands and set any
+ * change in state; reject all other commands.
+ **/
+-static i40e_status i40e_nvmupd_state_reading(struct i40e_hw *hw,
+- struct i40e_nvm_access *cmd,
+- u8 *bytes, int *perrno)
++static int i40e_nvmupd_state_reading(struct i40e_hw *hw,
++ struct i40e_nvm_access *cmd,
++ u8 *bytes, int *perrno)
+ {
+- i40e_status status = 0;
+ enum i40e_nvmupd_cmd upd_cmd;
++ int status = 0;
+
+ upd_cmd = i40e_nvmupd_validate_command(hw, cmd, perrno);
+
+@@ -1104,13 +1104,13 @@ static i40e_status i40e_nvmupd_state_reading(struct i40e_hw *hw,
+ * NVM ownership is already held. Process legitimate commands and set any
+ * change in state; reject all other commands
+ **/
+-static i40e_status i40e_nvmupd_state_writing(struct i40e_hw *hw,
+- struct i40e_nvm_access *cmd,
+- u8 *bytes, int *perrno)
++static int i40e_nvmupd_state_writing(struct i40e_hw *hw,
++ struct i40e_nvm_access *cmd,
++ u8 *bytes, int *perrno)
+ {
+- i40e_status status = 0;
+ enum i40e_nvmupd_cmd upd_cmd;
+ bool retry_attempt = false;
++ int status = 0;
+
+ upd_cmd = i40e_nvmupd_validate_command(hw, cmd, perrno);
+
+@@ -1187,8 +1187,8 @@ retry:
+ */
+ if (status && (hw->aq.asq_last_status == I40E_AQ_RC_EBUSY) &&
+ !retry_attempt) {
+- i40e_status old_status = status;
+ u32 old_asq_status = hw->aq.asq_last_status;
++ int old_status = status;
+ u32 gtime;
+
+ gtime = rd32(hw, I40E_GLVFGEN_TIMER);
+@@ -1370,17 +1370,17 @@ static enum i40e_nvmupd_cmd i40e_nvmupd_validate_command(struct i40e_hw *hw,
+ *
+ * cmd structure contains identifiers and data buffer
+ **/
+-static i40e_status i40e_nvmupd_exec_aq(struct i40e_hw *hw,
+- struct i40e_nvm_access *cmd,
+- u8 *bytes, int *perrno)
++static int i40e_nvmupd_exec_aq(struct i40e_hw *hw,
++ struct i40e_nvm_access *cmd,
++ u8 *bytes, int *perrno)
+ {
+ struct i40e_asq_cmd_details cmd_details;
+- i40e_status status;
+ struct i40e_aq_desc *aq_desc;
+ u32 buff_size = 0;
+ u8 *buff = NULL;
+ u32 aq_desc_len;
+ u32 aq_data_len;
++ int status;
+
+ i40e_debug(hw, I40E_DEBUG_NVM, "NVMUPD: %s\n", __func__);
+ if (cmd->offset == 0xffff)
+@@ -1429,8 +1429,8 @@ static i40e_status i40e_nvmupd_exec_aq(struct i40e_hw *hw,
+ buff_size, &cmd_details);
+ if (status) {
+ i40e_debug(hw, I40E_DEBUG_NVM,
+- "i40e_nvmupd_exec_aq err %s aq_err %s\n",
+- i40e_stat_str(hw, status),
++ "%s err %d aq_err %s\n",
++ __func__, status,
+ i40e_aq_str(hw, hw->aq.asq_last_status));
+ *perrno = i40e_aq_rc_to_posix(status, hw->aq.asq_last_status);
+ return status;
+@@ -1454,9 +1454,9 @@ static i40e_status i40e_nvmupd_exec_aq(struct i40e_hw *hw,
+ *
+ * cmd structure contains identifiers and data buffer
+ **/
+-static i40e_status i40e_nvmupd_get_aq_result(struct i40e_hw *hw,
+- struct i40e_nvm_access *cmd,
+- u8 *bytes, int *perrno)
++static int i40e_nvmupd_get_aq_result(struct i40e_hw *hw,
++ struct i40e_nvm_access *cmd,
++ u8 *bytes, int *perrno)
+ {
+ u32 aq_total_len;
+ u32 aq_desc_len;
+@@ -1523,9 +1523,9 @@ static i40e_status i40e_nvmupd_get_aq_result(struct i40e_hw *hw,
+ *
+ * cmd structure contains identifiers and data buffer
+ **/
+-static i40e_status i40e_nvmupd_get_aq_event(struct i40e_hw *hw,
+- struct i40e_nvm_access *cmd,
+- u8 *bytes, int *perrno)
++static int i40e_nvmupd_get_aq_event(struct i40e_hw *hw,
++ struct i40e_nvm_access *cmd,
++ u8 *bytes, int *perrno)
+ {
+ u32 aq_total_len;
+ u32 aq_desc_len;
+@@ -1557,13 +1557,13 @@ static i40e_status i40e_nvmupd_get_aq_event(struct i40e_hw *hw,
+ *
+ * cmd structure contains identifiers and data buffer
+ **/
+-static i40e_status i40e_nvmupd_nvm_read(struct i40e_hw *hw,
+- struct i40e_nvm_access *cmd,
+- u8 *bytes, int *perrno)
++static int i40e_nvmupd_nvm_read(struct i40e_hw *hw,
++ struct i40e_nvm_access *cmd,
++ u8 *bytes, int *perrno)
+ {
+ struct i40e_asq_cmd_details cmd_details;
+- i40e_status status;
+ u8 module, transaction;
++ int status;
+ bool last;
+
+ transaction = i40e_nvmupd_get_transaction(cmd->config);
+@@ -1596,13 +1596,13 @@ static i40e_status i40e_nvmupd_nvm_read(struct i40e_hw *hw,
+ *
+ * module, offset, data_size and data are in cmd structure
+ **/
+-static i40e_status i40e_nvmupd_nvm_erase(struct i40e_hw *hw,
+- struct i40e_nvm_access *cmd,
+- int *perrno)
++static int i40e_nvmupd_nvm_erase(struct i40e_hw *hw,
++ struct i40e_nvm_access *cmd,
++ int *perrno)
+ {
+- i40e_status status = 0;
+ struct i40e_asq_cmd_details cmd_details;
+ u8 module, transaction;
++ int status = 0;
+ bool last;
+
+ transaction = i40e_nvmupd_get_transaction(cmd->config);
+@@ -1636,14 +1636,14 @@ static i40e_status i40e_nvmupd_nvm_erase(struct i40e_hw *hw,
+ *
+ * module, offset, data_size and data are in cmd structure
+ **/
+-static i40e_status i40e_nvmupd_nvm_write(struct i40e_hw *hw,
+- struct i40e_nvm_access *cmd,
+- u8 *bytes, int *perrno)
++static int i40e_nvmupd_nvm_write(struct i40e_hw *hw,
++ struct i40e_nvm_access *cmd,
++ u8 *bytes, int *perrno)
+ {
+- i40e_status status = 0;
+ struct i40e_asq_cmd_details cmd_details;
+ u8 module, transaction;
+ u8 preservation_flags;
++ int status = 0;
+ bool last;
+
+ transaction = i40e_nvmupd_get_transaction(cmd->config);
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_osdep.h b/drivers/net/ethernet/intel/i40e/i40e_osdep.h
+index 2f6815b2f8df8..2bd4de03dafa2 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_osdep.h
++++ b/drivers/net/ethernet/intel/i40e/i40e_osdep.h
+@@ -56,5 +56,4 @@ do { \
+ (h)->bus.func, ##__VA_ARGS__); \
+ } while (0)
+
+-typedef enum i40e_status_code i40e_status;
+ #endif /* _I40E_OSDEP_H_ */
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_prototype.h b/drivers/net/ethernet/intel/i40e/i40e_prototype.h
+index 9a71121420c3b..fe845987d99a5 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_prototype.h
++++ b/drivers/net/ethernet/intel/i40e/i40e_prototype.h
+@@ -16,29 +16,29 @@
+ */
+
+ /* adminq functions */
+-i40e_status i40e_init_adminq(struct i40e_hw *hw);
++int i40e_init_adminq(struct i40e_hw *hw);
+ void i40e_shutdown_adminq(struct i40e_hw *hw);
+ void i40e_adminq_init_ring_data(struct i40e_hw *hw);
+-i40e_status i40e_clean_arq_element(struct i40e_hw *hw,
+- struct i40e_arq_event_info *e,
+- u16 *events_pending);
+-i40e_status
++int i40e_clean_arq_element(struct i40e_hw *hw,
++ struct i40e_arq_event_info *e,
++ u16 *events_pending);
++int
+ i40e_asq_send_command(struct i40e_hw *hw, struct i40e_aq_desc *desc,
+ void *buff, /* can be NULL */ u16 buff_size,
+ struct i40e_asq_cmd_details *cmd_details);
+-i40e_status
++int
+ i40e_asq_send_command_v2(struct i40e_hw *hw,
+ struct i40e_aq_desc *desc,
+ void *buff, /* can be NULL */
+ u16 buff_size,
+ struct i40e_asq_cmd_details *cmd_details,
+ enum i40e_admin_queue_err *aq_status);
+-i40e_status
++int
+ i40e_asq_send_command_atomic(struct i40e_hw *hw, struct i40e_aq_desc *desc,
+ void *buff, /* can be NULL */ u16 buff_size,
+ struct i40e_asq_cmd_details *cmd_details,
+ bool is_atomic_context);
+-i40e_status
++int
+ i40e_asq_send_command_atomic_v2(struct i40e_hw *hw,
+ struct i40e_aq_desc *desc,
+ void *buff, /* can be NULL */
+@@ -53,327 +53,332 @@ void i40e_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask,
+
+ void i40e_idle_aq(struct i40e_hw *hw);
+ bool i40e_check_asq_alive(struct i40e_hw *hw);
+-i40e_status i40e_aq_queue_shutdown(struct i40e_hw *hw, bool unloading);
++int i40e_aq_queue_shutdown(struct i40e_hw *hw, bool unloading);
+ const char *i40e_aq_str(struct i40e_hw *hw, enum i40e_admin_queue_err aq_err);
+-const char *i40e_stat_str(struct i40e_hw *hw, i40e_status stat_err);
+
+-i40e_status i40e_aq_get_rss_lut(struct i40e_hw *hw, u16 seid,
+- bool pf_lut, u8 *lut, u16 lut_size);
+-i40e_status i40e_aq_set_rss_lut(struct i40e_hw *hw, u16 seid,
+- bool pf_lut, u8 *lut, u16 lut_size);
+-i40e_status i40e_aq_get_rss_key(struct i40e_hw *hw,
+- u16 seid,
+- struct i40e_aqc_get_set_rss_key_data *key);
+-i40e_status i40e_aq_set_rss_key(struct i40e_hw *hw,
+- u16 seid,
+- struct i40e_aqc_get_set_rss_key_data *key);
++int i40e_aq_get_rss_lut(struct i40e_hw *hw, u16 seid,
++ bool pf_lut, u8 *lut, u16 lut_size);
++int i40e_aq_set_rss_lut(struct i40e_hw *hw, u16 seid,
++ bool pf_lut, u8 *lut, u16 lut_size);
++int i40e_aq_get_rss_key(struct i40e_hw *hw,
++ u16 seid,
++ struct i40e_aqc_get_set_rss_key_data *key);
++int i40e_aq_set_rss_key(struct i40e_hw *hw,
++ u16 seid,
++ struct i40e_aqc_get_set_rss_key_data *key);
+
+ u32 i40e_led_get(struct i40e_hw *hw);
+ void i40e_led_set(struct i40e_hw *hw, u32 mode, bool blink);
+-i40e_status i40e_led_set_phy(struct i40e_hw *hw, bool on,
+- u16 led_addr, u32 mode);
+-i40e_status i40e_led_get_phy(struct i40e_hw *hw, u16 *led_addr,
+- u16 *val);
+-i40e_status i40e_blink_phy_link_led(struct i40e_hw *hw,
+- u32 time, u32 interval);
++int i40e_led_set_phy(struct i40e_hw *hw, bool on,
++ u16 led_addr, u32 mode);
++int i40e_led_get_phy(struct i40e_hw *hw, u16 *led_addr,
++ u16 *val);
++int i40e_blink_phy_link_led(struct i40e_hw *hw,
++ u32 time, u32 interval);
+
+ /* admin send queue commands */
+
+-i40e_status i40e_aq_get_firmware_version(struct i40e_hw *hw,
+- u16 *fw_major_version, u16 *fw_minor_version,
+- u32 *fw_build,
+- u16 *api_major_version, u16 *api_minor_version,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_debug_write_register(struct i40e_hw *hw,
+- u32 reg_addr, u64 reg_val,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_debug_read_register(struct i40e_hw *hw,
++int i40e_aq_get_firmware_version(struct i40e_hw *hw,
++ u16 *fw_major_version, u16 *fw_minor_version,
++ u32 *fw_build,
++ u16 *api_major_version, u16 *api_minor_version,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_debug_write_register(struct i40e_hw *hw,
++ u32 reg_addr, u64 reg_val,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_debug_read_register(struct i40e_hw *hw,
+ u32 reg_addr, u64 *reg_val,
+ struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_set_phy_debug(struct i40e_hw *hw, u8 cmd_flags,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_set_default_vsi(struct i40e_hw *hw, u16 vsi_id,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_clear_default_vsi(struct i40e_hw *hw, u16 vsi_id,
+- struct i40e_asq_cmd_details *cmd_details);
+-enum i40e_status_code i40e_aq_get_phy_capabilities(struct i40e_hw *hw,
+- bool qualified_modules, bool report_init,
+- struct i40e_aq_get_phy_abilities_resp *abilities,
+- struct i40e_asq_cmd_details *cmd_details);
+-enum i40e_status_code i40e_aq_set_phy_config(struct i40e_hw *hw,
+- struct i40e_aq_set_phy_config *config,
+- struct i40e_asq_cmd_details *cmd_details);
+-enum i40e_status_code i40e_set_fc(struct i40e_hw *hw, u8 *aq_failures,
+- bool atomic_reset);
+-i40e_status i40e_aq_set_mac_loopback(struct i40e_hw *hw,
+- bool ena_lpbk,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_set_phy_int_mask(struct i40e_hw *hw, u16 mask,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_clear_pxe_mode(struct i40e_hw *hw,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_set_link_restart_an(struct i40e_hw *hw,
+- bool enable_link,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_get_link_info(struct i40e_hw *hw,
+- bool enable_lse, struct i40e_link_status *link,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_set_local_advt_reg(struct i40e_hw *hw,
+- u64 advt_reg,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_send_driver_version(struct i40e_hw *hw,
++int i40e_aq_set_phy_debug(struct i40e_hw *hw, u8 cmd_flags,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_set_default_vsi(struct i40e_hw *hw, u16 vsi_id,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_clear_default_vsi(struct i40e_hw *hw, u16 vsi_id,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_get_phy_capabilities(struct i40e_hw *hw,
++ bool qualified_modules, bool report_init,
++ struct i40e_aq_get_phy_abilities_resp *abilities,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_set_phy_config(struct i40e_hw *hw,
++ struct i40e_aq_set_phy_config *config,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_set_fc(struct i40e_hw *hw, u8 *aq_failures,
++ bool atomic_reset);
++int i40e_aq_set_mac_loopback(struct i40e_hw *hw,
++ bool ena_lpbk,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_set_phy_int_mask(struct i40e_hw *hw, u16 mask,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_clear_pxe_mode(struct i40e_hw *hw,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_set_link_restart_an(struct i40e_hw *hw,
++ bool enable_link,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_get_link_info(struct i40e_hw *hw,
++ bool enable_lse, struct i40e_link_status *link,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_set_local_advt_reg(struct i40e_hw *hw,
++ u64 advt_reg,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_send_driver_version(struct i40e_hw *hw,
+ struct i40e_driver_version *dv,
+ struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_add_vsi(struct i40e_hw *hw,
+- struct i40e_vsi_context *vsi_ctx,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_set_vsi_broadcast(struct i40e_hw *hw,
+- u16 vsi_id, bool set_filter,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_set_vsi_unicast_promiscuous(struct i40e_hw *hw,
+- u16 vsi_id, bool set, struct i40e_asq_cmd_details *cmd_details,
+- bool rx_only_promisc);
+-i40e_status i40e_aq_set_vsi_multicast_promiscuous(struct i40e_hw *hw,
+- u16 vsi_id, bool set, struct i40e_asq_cmd_details *cmd_details);
+-enum i40e_status_code i40e_aq_set_vsi_mc_promisc_on_vlan(struct i40e_hw *hw,
+- u16 seid, bool enable,
+- u16 vid,
+- struct i40e_asq_cmd_details *cmd_details);
+-enum i40e_status_code i40e_aq_set_vsi_uc_promisc_on_vlan(struct i40e_hw *hw,
+- u16 seid, bool enable,
+- u16 vid,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_set_vsi_bc_promisc_on_vlan(struct i40e_hw *hw,
+- u16 seid, bool enable, u16 vid,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_set_vsi_vlan_promisc(struct i40e_hw *hw,
+- u16 seid, bool enable,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_get_vsi_params(struct i40e_hw *hw,
+- struct i40e_vsi_context *vsi_ctx,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_update_vsi_params(struct i40e_hw *hw,
+- struct i40e_vsi_context *vsi_ctx,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_add_veb(struct i40e_hw *hw, u16 uplink_seid,
+- u16 downlink_seid, u8 enabled_tc,
+- bool default_port, u16 *pveb_seid,
+- bool enable_stats,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_get_veb_parameters(struct i40e_hw *hw,
+- u16 veb_seid, u16 *switch_id, bool *floating,
+- u16 *statistic_index, u16 *vebs_used,
+- u16 *vebs_free,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_add_macvlan(struct i40e_hw *hw, u16 vsi_id,
++int i40e_aq_add_vsi(struct i40e_hw *hw,
++ struct i40e_vsi_context *vsi_ctx,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_set_vsi_broadcast(struct i40e_hw *hw,
++ u16 vsi_id, bool set_filter,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_set_vsi_unicast_promiscuous(struct i40e_hw *hw, u16 vsi_id, bool set,
++ struct i40e_asq_cmd_details *cmd_details,
++ bool rx_only_promisc);
++int i40e_aq_set_vsi_multicast_promiscuous(struct i40e_hw *hw, u16 vsi_id, bool set,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_set_vsi_mc_promisc_on_vlan(struct i40e_hw *hw,
++ u16 seid, bool enable,
++ u16 vid,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_set_vsi_uc_promisc_on_vlan(struct i40e_hw *hw,
++ u16 seid, bool enable,
++ u16 vid,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_set_vsi_bc_promisc_on_vlan(struct i40e_hw *hw,
++ u16 seid, bool enable, u16 vid,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_set_vsi_vlan_promisc(struct i40e_hw *hw,
++ u16 seid, bool enable,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_get_vsi_params(struct i40e_hw *hw,
++ struct i40e_vsi_context *vsi_ctx,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_update_vsi_params(struct i40e_hw *hw,
++ struct i40e_vsi_context *vsi_ctx,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_add_veb(struct i40e_hw *hw, u16 uplink_seid,
++ u16 downlink_seid, u8 enabled_tc,
++ bool default_port, u16 *pveb_seid,
++ bool enable_stats,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_get_veb_parameters(struct i40e_hw *hw,
++ u16 veb_seid, u16 *switch_id, bool *floating,
++ u16 *statistic_index, u16 *vebs_used,
++ u16 *vebs_free,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_add_macvlan(struct i40e_hw *hw, u16 vsi_id,
+ struct i40e_aqc_add_macvlan_element_data *mv_list,
+ u16 count, struct i40e_asq_cmd_details *cmd_details);
+-i40e_status
++int
+ i40e_aq_add_macvlan_v2(struct i40e_hw *hw, u16 seid,
+ struct i40e_aqc_add_macvlan_element_data *mv_list,
+ u16 count, struct i40e_asq_cmd_details *cmd_details,
+ enum i40e_admin_queue_err *aq_status);
+-i40e_status i40e_aq_remove_macvlan(struct i40e_hw *hw, u16 vsi_id,
+- struct i40e_aqc_remove_macvlan_element_data *mv_list,
+- u16 count, struct i40e_asq_cmd_details *cmd_details);
+-i40e_status
++int i40e_aq_remove_macvlan(struct i40e_hw *hw, u16 vsi_id,
++ struct i40e_aqc_remove_macvlan_element_data *mv_list,
++ u16 count, struct i40e_asq_cmd_details *cmd_details);
++int
+ i40e_aq_remove_macvlan_v2(struct i40e_hw *hw, u16 seid,
+ struct i40e_aqc_remove_macvlan_element_data *mv_list,
+ u16 count, struct i40e_asq_cmd_details *cmd_details,
+ enum i40e_admin_queue_err *aq_status);
+-i40e_status i40e_aq_add_mirrorrule(struct i40e_hw *hw, u16 sw_seid,
+- u16 rule_type, u16 dest_vsi, u16 count, __le16 *mr_list,
+- struct i40e_asq_cmd_details *cmd_details,
+- u16 *rule_id, u16 *rules_used, u16 *rules_free);
+-i40e_status i40e_aq_delete_mirrorrule(struct i40e_hw *hw, u16 sw_seid,
+- u16 rule_type, u16 rule_id, u16 count, __le16 *mr_list,
+- struct i40e_asq_cmd_details *cmd_details,
+- u16 *rules_used, u16 *rules_free);
++int i40e_aq_add_mirrorrule(struct i40e_hw *hw, u16 sw_seid,
++ u16 rule_type, u16 dest_vsi, u16 count, __le16 *mr_list,
++ struct i40e_asq_cmd_details *cmd_details,
++ u16 *rule_id, u16 *rules_used, u16 *rules_free);
++int i40e_aq_delete_mirrorrule(struct i40e_hw *hw, u16 sw_seid,
++ u16 rule_type, u16 rule_id, u16 count, __le16 *mr_list,
++ struct i40e_asq_cmd_details *cmd_details,
++ u16 *rules_used, u16 *rules_free);
+
+-i40e_status i40e_aq_send_msg_to_vf(struct i40e_hw *hw, u16 vfid,
+- u32 v_opcode, u32 v_retval, u8 *msg, u16 msglen,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_get_switch_config(struct i40e_hw *hw,
+- struct i40e_aqc_get_switch_config_resp *buf,
+- u16 buf_size, u16 *start_seid,
+- struct i40e_asq_cmd_details *cmd_details);
+-enum i40e_status_code i40e_aq_set_switch_config(struct i40e_hw *hw,
+- u16 flags,
+- u16 valid_flags, u8 mode,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_request_resource(struct i40e_hw *hw,
+- enum i40e_aq_resources_ids resource,
+- enum i40e_aq_resource_access_type access,
+- u8 sdp_number, u64 *timeout,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_release_resource(struct i40e_hw *hw,
+- enum i40e_aq_resources_ids resource,
+- u8 sdp_number,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_read_nvm(struct i40e_hw *hw, u8 module_pointer,
+- u32 offset, u16 length, void *data,
+- bool last_command,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_erase_nvm(struct i40e_hw *hw, u8 module_pointer,
+- u32 offset, u16 length, bool last_command,
++int i40e_aq_send_msg_to_vf(struct i40e_hw *hw, u16 vfid,
++ u32 v_opcode, u32 v_retval, u8 *msg, u16 msglen,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_get_switch_config(struct i40e_hw *hw,
++ struct i40e_aqc_get_switch_config_resp *buf,
++ u16 buf_size, u16 *start_seid,
+ struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_discover_capabilities(struct i40e_hw *hw,
+- void *buff, u16 buff_size, u16 *data_size,
+- enum i40e_admin_queue_opc list_type_opc,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_update_nvm(struct i40e_hw *hw, u8 module_pointer,
+- u32 offset, u16 length, void *data,
+- bool last_command, u8 preservation_flags,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_rearrange_nvm(struct i40e_hw *hw,
+- u8 rearrange_nvm,
++int i40e_aq_set_switch_config(struct i40e_hw *hw,
++ u16 flags,
++ u16 valid_flags, u8 mode,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_request_resource(struct i40e_hw *hw,
++ enum i40e_aq_resources_ids resource,
++ enum i40e_aq_resource_access_type access,
++ u8 sdp_number, u64 *timeout,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_release_resource(struct i40e_hw *hw,
++ enum i40e_aq_resources_ids resource,
++ u8 sdp_number,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_read_nvm(struct i40e_hw *hw, u8 module_pointer,
++ u32 offset, u16 length, void *data,
++ bool last_command,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_erase_nvm(struct i40e_hw *hw, u8 module_pointer,
++ u32 offset, u16 length, bool last_command,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_discover_capabilities(struct i40e_hw *hw,
++ void *buff, u16 buff_size, u16 *data_size,
++ enum i40e_admin_queue_opc list_type_opc,
+ struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_get_lldp_mib(struct i40e_hw *hw, u8 bridge_type,
+- u8 mib_type, void *buff, u16 buff_size,
+- u16 *local_len, u16 *remote_len,
+- struct i40e_asq_cmd_details *cmd_details);
+-enum i40e_status_code
++int i40e_aq_update_nvm(struct i40e_hw *hw, u8 module_pointer,
++ u32 offset, u16 length, void *data,
++ bool last_command, u8 preservation_flags,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_rearrange_nvm(struct i40e_hw *hw,
++ u8 rearrange_nvm,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_get_lldp_mib(struct i40e_hw *hw, u8 bridge_type,
++ u8 mib_type, void *buff, u16 buff_size,
++ u16 *local_len, u16 *remote_len,
++ struct i40e_asq_cmd_details *cmd_details);
++int
+ i40e_aq_set_lldp_mib(struct i40e_hw *hw,
+ u8 mib_type, void *buff, u16 buff_size,
+ struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_cfg_lldp_mib_change_event(struct i40e_hw *hw,
+- bool enable_update,
+- struct i40e_asq_cmd_details *cmd_details);
+-enum i40e_status_code
++int i40e_aq_cfg_lldp_mib_change_event(struct i40e_hw *hw,
++ bool enable_update,
++ struct i40e_asq_cmd_details *cmd_details);
++int
+ i40e_aq_restore_lldp(struct i40e_hw *hw, u8 *setting, bool restore,
+ struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_stop_lldp(struct i40e_hw *hw, bool shutdown_agent,
+- bool persist,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_set_dcb_parameters(struct i40e_hw *hw,
+- bool dcb_enable,
+- struct i40e_asq_cmd_details
+- *cmd_details);
+-i40e_status i40e_aq_start_lldp(struct i40e_hw *hw, bool persist,
++int i40e_aq_stop_lldp(struct i40e_hw *hw, bool shutdown_agent,
++ bool persist,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_set_dcb_parameters(struct i40e_hw *hw,
++ bool dcb_enable,
++ struct i40e_asq_cmd_details
++ *cmd_details);
++int i40e_aq_start_lldp(struct i40e_hw *hw, bool persist,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_get_cee_dcb_config(struct i40e_hw *hw,
++ void *buff, u16 buff_size,
+ struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_get_cee_dcb_config(struct i40e_hw *hw,
+- void *buff, u16 buff_size,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_add_udp_tunnel(struct i40e_hw *hw,
+- u16 udp_port, u8 protocol_index,
+- u8 *filter_index,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_del_udp_tunnel(struct i40e_hw *hw, u8 index,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_delete_element(struct i40e_hw *hw, u16 seid,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_mac_address_write(struct i40e_hw *hw,
+- u16 flags, u8 *mac_addr,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_config_vsi_bw_limit(struct i40e_hw *hw,
++int i40e_aq_add_udp_tunnel(struct i40e_hw *hw,
++ u16 udp_port, u8 protocol_index,
++ u8 *filter_index,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_del_udp_tunnel(struct i40e_hw *hw, u8 index,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_delete_element(struct i40e_hw *hw, u16 seid,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_mac_address_write(struct i40e_hw *hw,
++ u16 flags, u8 *mac_addr,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_config_vsi_bw_limit(struct i40e_hw *hw,
+ u16 seid, u16 credit, u8 max_credit,
+ struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_dcb_updated(struct i40e_hw *hw,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_config_switch_comp_bw_limit(struct i40e_hw *hw,
+- u16 seid, u16 credit, u8 max_bw,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_config_vsi_tc_bw(struct i40e_hw *hw, u16 seid,
+- struct i40e_aqc_configure_vsi_tc_bw_data *bw_data,
++int i40e_aq_dcb_updated(struct i40e_hw *hw,
+ struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_config_switch_comp_ets(struct i40e_hw *hw,
+- u16 seid,
+- struct i40e_aqc_configure_switching_comp_ets_data *ets_data,
+- enum i40e_admin_queue_opc opcode,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_config_switch_comp_bw_config(struct i40e_hw *hw,
++int i40e_aq_config_switch_comp_bw_limit(struct i40e_hw *hw,
++ u16 seid, u16 credit, u8 max_bw,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_config_vsi_tc_bw(struct i40e_hw *hw, u16 seid,
++ struct i40e_aqc_configure_vsi_tc_bw_data *bw_data,
++ struct i40e_asq_cmd_details *cmd_details);
++int
++i40e_aq_config_switch_comp_ets(struct i40e_hw *hw,
++ u16 seid,
++ struct i40e_aqc_configure_switching_comp_ets_data *ets_data,
++ enum i40e_admin_queue_opc opcode,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_config_switch_comp_bw_config(struct i40e_hw *hw,
+ u16 seid,
+ struct i40e_aqc_configure_switching_comp_bw_config_data *bw_data,
+ struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_query_vsi_bw_config(struct i40e_hw *hw,
+- u16 seid,
+- struct i40e_aqc_query_vsi_bw_config_resp *bw_data,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_query_vsi_ets_sla_config(struct i40e_hw *hw,
+- u16 seid,
+- struct i40e_aqc_query_vsi_ets_sla_config_resp *bw_data,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_query_switch_comp_ets_config(struct i40e_hw *hw,
+- u16 seid,
+- struct i40e_aqc_query_switching_comp_ets_config_resp *bw_data,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_query_port_ets_config(struct i40e_hw *hw,
+- u16 seid,
+- struct i40e_aqc_query_port_ets_config_resp *bw_data,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_query_switch_comp_bw_config(struct i40e_hw *hw,
+- u16 seid,
+- struct i40e_aqc_query_switching_comp_bw_config_resp *bw_data,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_resume_port_tx(struct i40e_hw *hw,
+- struct i40e_asq_cmd_details *cmd_details);
+-enum i40e_status_code
++int i40e_aq_query_vsi_bw_config(struct i40e_hw *hw,
++ u16 seid,
++ struct i40e_aqc_query_vsi_bw_config_resp *bw_data,
++ struct i40e_asq_cmd_details *cmd_details);
++int
++i40e_aq_query_vsi_ets_sla_config(struct i40e_hw *hw,
++ u16 seid,
++ struct i40e_aqc_query_vsi_ets_sla_config_resp *bw_data,
++ struct i40e_asq_cmd_details *cmd_details);
++int
++i40e_aq_query_switch_comp_ets_config(struct i40e_hw *hw,
++ u16 seid,
++ struct i40e_aqc_query_switching_comp_ets_config_resp *bw_data,
++ struct i40e_asq_cmd_details *cmd_details);
++int
++i40e_aq_query_port_ets_config(struct i40e_hw *hw,
++ u16 seid,
++ struct i40e_aqc_query_port_ets_config_resp *bw_data,
++ struct i40e_asq_cmd_details *cmd_details);
++int
++i40e_aq_query_switch_comp_bw_config(struct i40e_hw *hw,
++ u16 seid,
++ struct i40e_aqc_query_switching_comp_bw_config_resp *bw_data,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_resume_port_tx(struct i40e_hw *hw,
++ struct i40e_asq_cmd_details *cmd_details);
++int
+ i40e_aq_add_cloud_filters_bb(struct i40e_hw *hw, u16 seid,
+ struct i40e_aqc_cloud_filters_element_bb *filters,
+ u8 filter_count);
+-enum i40e_status_code
++int
+ i40e_aq_add_cloud_filters(struct i40e_hw *hw, u16 vsi,
+ struct i40e_aqc_cloud_filters_element_data *filters,
+ u8 filter_count);
+-enum i40e_status_code
++int
+ i40e_aq_rem_cloud_filters(struct i40e_hw *hw, u16 vsi,
+ struct i40e_aqc_cloud_filters_element_data *filters,
+ u8 filter_count);
+-enum i40e_status_code
++int
+ i40e_aq_rem_cloud_filters_bb(struct i40e_hw *hw, u16 seid,
+ struct i40e_aqc_cloud_filters_element_bb *filters,
+ u8 filter_count);
+-i40e_status i40e_read_lldp_cfg(struct i40e_hw *hw,
+- struct i40e_lldp_variables *lldp_cfg);
+-enum i40e_status_code
++int i40e_read_lldp_cfg(struct i40e_hw *hw,
++ struct i40e_lldp_variables *lldp_cfg);
++int
+ i40e_aq_suspend_port_tx(struct i40e_hw *hw, u16 seid,
+ struct i40e_asq_cmd_details *cmd_details);
+ /* i40e_common */
+-i40e_status i40e_init_shared_code(struct i40e_hw *hw);
+-i40e_status i40e_pf_reset(struct i40e_hw *hw);
++int i40e_init_shared_code(struct i40e_hw *hw);
++int i40e_pf_reset(struct i40e_hw *hw);
+ void i40e_clear_hw(struct i40e_hw *hw);
+ void i40e_clear_pxe_mode(struct i40e_hw *hw);
+-i40e_status i40e_get_link_status(struct i40e_hw *hw, bool *link_up);
+-i40e_status i40e_update_link_info(struct i40e_hw *hw);
+-i40e_status i40e_get_mac_addr(struct i40e_hw *hw, u8 *mac_addr);
+-i40e_status i40e_read_bw_from_alt_ram(struct i40e_hw *hw,
+- u32 *max_bw, u32 *min_bw, bool *min_valid,
+- bool *max_valid);
+-i40e_status i40e_aq_configure_partition_bw(struct i40e_hw *hw,
+- struct i40e_aqc_configure_partition_bw_data *bw_data,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_get_port_mac_addr(struct i40e_hw *hw, u8 *mac_addr);
+-i40e_status i40e_read_pba_string(struct i40e_hw *hw, u8 *pba_num,
+- u32 pba_num_size);
+-i40e_status i40e_validate_mac_addr(u8 *mac_addr);
++int i40e_get_link_status(struct i40e_hw *hw, bool *link_up);
++int i40e_update_link_info(struct i40e_hw *hw);
++int i40e_get_mac_addr(struct i40e_hw *hw, u8 *mac_addr);
++int i40e_read_bw_from_alt_ram(struct i40e_hw *hw,
++ u32 *max_bw, u32 *min_bw, bool *min_valid,
++ bool *max_valid);
++int
++i40e_aq_configure_partition_bw(struct i40e_hw *hw,
++ struct i40e_aqc_configure_partition_bw_data *bw_data,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_get_port_mac_addr(struct i40e_hw *hw, u8 *mac_addr);
++int i40e_read_pba_string(struct i40e_hw *hw, u8 *pba_num,
++ u32 pba_num_size);
++int i40e_validate_mac_addr(u8 *mac_addr);
+ void i40e_pre_tx_queue_cfg(struct i40e_hw *hw, u32 queue, bool enable);
+ /* prototype for functions used for NVM access */
+-i40e_status i40e_init_nvm(struct i40e_hw *hw);
+-i40e_status i40e_acquire_nvm(struct i40e_hw *hw,
+- enum i40e_aq_resource_access_type access);
++int i40e_init_nvm(struct i40e_hw *hw);
++int i40e_acquire_nvm(struct i40e_hw *hw,
++ enum i40e_aq_resource_access_type access);
+ void i40e_release_nvm(struct i40e_hw *hw);
+-i40e_status i40e_read_nvm_word(struct i40e_hw *hw, u16 offset,
+- u16 *data);
+-enum i40e_status_code i40e_read_nvm_module_data(struct i40e_hw *hw,
+- u8 module_ptr,
+- u16 module_offset,
+- u16 data_offset,
+- u16 words_data_size,
+- u16 *data_ptr);
+-i40e_status i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset,
+- u16 *words, u16 *data);
+-i40e_status i40e_update_nvm_checksum(struct i40e_hw *hw);
+-i40e_status i40e_validate_nvm_checksum(struct i40e_hw *hw,
+- u16 *checksum);
+-i40e_status i40e_nvmupd_command(struct i40e_hw *hw,
+- struct i40e_nvm_access *cmd,
+- u8 *bytes, int *);
++int i40e_read_nvm_word(struct i40e_hw *hw, u16 offset,
++ u16 *data);
++int i40e_read_nvm_module_data(struct i40e_hw *hw,
++ u8 module_ptr,
++ u16 module_offset,
++ u16 data_offset,
++ u16 words_data_size,
++ u16 *data_ptr);
++int i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset,
++ u16 *words, u16 *data);
++int i40e_update_nvm_checksum(struct i40e_hw *hw);
++int i40e_validate_nvm_checksum(struct i40e_hw *hw,
++ u16 *checksum);
++int i40e_nvmupd_command(struct i40e_hw *hw,
++ struct i40e_nvm_access *cmd,
++ u8 *bytes, int *errno);
+ void i40e_nvmupd_check_wait_event(struct i40e_hw *hw, u16 opcode,
+ struct i40e_aq_desc *desc);
+ void i40e_nvmupd_clear_wait_state(struct i40e_hw *hw);
+ void i40e_set_pci_config_data(struct i40e_hw *hw, u16 link_status);
+
+-i40e_status i40e_set_mac_type(struct i40e_hw *hw);
++int i40e_set_mac_type(struct i40e_hw *hw);
+
+ extern struct i40e_rx_ptype_decoded i40e_ptype_lookup[];
+
+@@ -422,41 +427,41 @@ i40e_virtchnl_link_speed(enum i40e_aq_link_speed link_speed)
+ /* i40e_common for VF drivers*/
+ void i40e_vf_parse_hw_config(struct i40e_hw *hw,
+ struct virtchnl_vf_resource *msg);
+-i40e_status i40e_vf_reset(struct i40e_hw *hw);
+-i40e_status i40e_aq_send_msg_to_pf(struct i40e_hw *hw,
+- enum virtchnl_ops v_opcode,
+- i40e_status v_retval,
+- u8 *msg, u16 msglen,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_set_filter_control(struct i40e_hw *hw,
+- struct i40e_filter_control_settings *settings);
+-i40e_status i40e_aq_add_rem_control_packet_filter(struct i40e_hw *hw,
+- u8 *mac_addr, u16 ethtype, u16 flags,
+- u16 vsi_seid, u16 queue, bool is_add,
+- struct i40e_control_filter_stats *stats,
+- struct i40e_asq_cmd_details *cmd_details);
+-i40e_status i40e_aq_debug_dump(struct i40e_hw *hw, u8 cluster_id,
+- u8 table_id, u32 start_index, u16 buff_size,
+- void *buff, u16 *ret_buff_size,
+- u8 *ret_next_table, u32 *ret_next_index,
+- struct i40e_asq_cmd_details *cmd_details);
++int i40e_vf_reset(struct i40e_hw *hw);
++int i40e_aq_send_msg_to_pf(struct i40e_hw *hw,
++ enum virtchnl_ops v_opcode,
++ int v_retval,
++ u8 *msg, u16 msglen,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_set_filter_control(struct i40e_hw *hw,
++ struct i40e_filter_control_settings *settings);
++int i40e_aq_add_rem_control_packet_filter(struct i40e_hw *hw,
++ u8 *mac_addr, u16 ethtype, u16 flags,
++ u16 vsi_seid, u16 queue, bool is_add,
++ struct i40e_control_filter_stats *stats,
++ struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_debug_dump(struct i40e_hw *hw, u8 cluster_id,
++ u8 table_id, u32 start_index, u16 buff_size,
++ void *buff, u16 *ret_buff_size,
++ u8 *ret_next_table, u32 *ret_next_index,
++ struct i40e_asq_cmd_details *cmd_details);
+ void i40e_add_filter_to_drop_tx_flow_control_frames(struct i40e_hw *hw,
+ u16 vsi_seid);
+-i40e_status i40e_aq_rx_ctl_read_register(struct i40e_hw *hw,
+- u32 reg_addr, u32 *reg_val,
+- struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_rx_ctl_read_register(struct i40e_hw *hw,
++ u32 reg_addr, u32 *reg_val,
++ struct i40e_asq_cmd_details *cmd_details);
+ u32 i40e_read_rx_ctl(struct i40e_hw *hw, u32 reg_addr);
+-i40e_status i40e_aq_rx_ctl_write_register(struct i40e_hw *hw,
+- u32 reg_addr, u32 reg_val,
+- struct i40e_asq_cmd_details *cmd_details);
++int i40e_aq_rx_ctl_write_register(struct i40e_hw *hw,
++ u32 reg_addr, u32 reg_val,
++ struct i40e_asq_cmd_details *cmd_details);
+ void i40e_write_rx_ctl(struct i40e_hw *hw, u32 reg_addr, u32 reg_val);
+-enum i40e_status_code
++int
+ i40e_aq_set_phy_register_ext(struct i40e_hw *hw,
+ u8 phy_select, u8 dev_addr, bool page_change,
+ bool set_mdio, u8 mdio_num,
+ u32 reg_addr, u32 reg_val,
+ struct i40e_asq_cmd_details *cmd_details);
+-enum i40e_status_code
++int
+ i40e_aq_get_phy_register_ext(struct i40e_hw *hw,
+ u8 phy_select, u8 dev_addr, bool page_change,
+ bool set_mdio, u8 mdio_num,
+@@ -469,43 +474,43 @@ i40e_aq_get_phy_register_ext(struct i40e_hw *hw,
+ #define i40e_aq_get_phy_register(hw, ps, da, pc, ra, rv, cd) \
+ i40e_aq_get_phy_register_ext(hw, ps, da, pc, false, 0, ra, rv, cd)
+
+-i40e_status i40e_read_phy_register_clause22(struct i40e_hw *hw,
+- u16 reg, u8 phy_addr, u16 *value);
+-i40e_status i40e_write_phy_register_clause22(struct i40e_hw *hw,
+- u16 reg, u8 phy_addr, u16 value);
+-i40e_status i40e_read_phy_register_clause45(struct i40e_hw *hw,
+- u8 page, u16 reg, u8 phy_addr, u16 *value);
+-i40e_status i40e_write_phy_register_clause45(struct i40e_hw *hw,
+- u8 page, u16 reg, u8 phy_addr, u16 value);
+-i40e_status i40e_read_phy_register(struct i40e_hw *hw, u8 page, u16 reg,
+- u8 phy_addr, u16 *value);
+-i40e_status i40e_write_phy_register(struct i40e_hw *hw, u8 page, u16 reg,
+- u8 phy_addr, u16 value);
++int i40e_read_phy_register_clause22(struct i40e_hw *hw,
++ u16 reg, u8 phy_addr, u16 *value);
++int i40e_write_phy_register_clause22(struct i40e_hw *hw,
++ u16 reg, u8 phy_addr, u16 value);
++int i40e_read_phy_register_clause45(struct i40e_hw *hw,
++ u8 page, u16 reg, u8 phy_addr, u16 *value);
++int i40e_write_phy_register_clause45(struct i40e_hw *hw,
++ u8 page, u16 reg, u8 phy_addr, u16 value);
++int i40e_read_phy_register(struct i40e_hw *hw, u8 page, u16 reg,
++ u8 phy_addr, u16 *value);
++int i40e_write_phy_register(struct i40e_hw *hw, u8 page, u16 reg,
++ u8 phy_addr, u16 value);
+ u8 i40e_get_phy_address(struct i40e_hw *hw, u8 dev_num);
+-i40e_status i40e_blink_phy_link_led(struct i40e_hw *hw,
+- u32 time, u32 interval);
+-i40e_status i40e_aq_write_ddp(struct i40e_hw *hw, void *buff,
+- u16 buff_size, u32 track_id,
+- u32 *error_offset, u32 *error_info,
+- struct i40e_asq_cmd_details *
+- cmd_details);
+-i40e_status i40e_aq_get_ddp_list(struct i40e_hw *hw, void *buff,
+- u16 buff_size, u8 flags,
+- struct i40e_asq_cmd_details *
+- cmd_details);
++int i40e_blink_phy_link_led(struct i40e_hw *hw,
++ u32 time, u32 interval);
++int i40e_aq_write_ddp(struct i40e_hw *hw, void *buff,
++ u16 buff_size, u32 track_id,
++ u32 *error_offset, u32 *error_info,
++ struct i40e_asq_cmd_details *
++ cmd_details);
++int i40e_aq_get_ddp_list(struct i40e_hw *hw, void *buff,
++ u16 buff_size, u8 flags,
++ struct i40e_asq_cmd_details *
++ cmd_details);
+ struct i40e_generic_seg_header *
+ i40e_find_segment_in_package(u32 segment_type,
+ struct i40e_package_header *pkg_header);
+ struct i40e_profile_section_header *
+ i40e_find_section_in_profile(u32 section_type,
+ struct i40e_profile_segment *profile);
+-enum i40e_status_code
++int
+ i40e_write_profile(struct i40e_hw *hw, struct i40e_profile_segment *i40e_seg,
+ u32 track_id);
+-enum i40e_status_code
++int
+ i40e_rollback_profile(struct i40e_hw *hw, struct i40e_profile_segment *i40e_seg,
+ u32 track_id);
+-enum i40e_status_code
++int
+ i40e_add_pinfo_to_list(struct i40e_hw *hw,
+ struct i40e_profile_segment *profile,
+ u8 *profile_info_sec, u32 track_id);
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_status.h b/drivers/net/ethernet/intel/i40e/i40e_status.h
+index db3714a65dc71..4d2782e76038b 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_status.h
++++ b/drivers/net/ethernet/intel/i40e/i40e_status.h
+@@ -9,65 +9,30 @@ enum i40e_status_code {
+ I40E_SUCCESS = 0,
+ I40E_ERR_NVM = -1,
+ I40E_ERR_NVM_CHECKSUM = -2,
+- I40E_ERR_PHY = -3,
+ I40E_ERR_CONFIG = -4,
+ I40E_ERR_PARAM = -5,
+- I40E_ERR_MAC_TYPE = -6,
+ I40E_ERR_UNKNOWN_PHY = -7,
+- I40E_ERR_LINK_SETUP = -8,
+- I40E_ERR_ADAPTER_STOPPED = -9,
+ I40E_ERR_INVALID_MAC_ADDR = -10,
+ I40E_ERR_DEVICE_NOT_SUPPORTED = -11,
+- I40E_ERR_PRIMARY_REQUESTS_PENDING = -12,
+- I40E_ERR_INVALID_LINK_SETTINGS = -13,
+- I40E_ERR_AUTONEG_NOT_COMPLETE = -14,
+ I40E_ERR_RESET_FAILED = -15,
+- I40E_ERR_SWFW_SYNC = -16,
+ I40E_ERR_NO_AVAILABLE_VSI = -17,
+ I40E_ERR_NO_MEMORY = -18,
+ I40E_ERR_BAD_PTR = -19,
+- I40E_ERR_RING_FULL = -20,
+- I40E_ERR_INVALID_PD_ID = -21,
+- I40E_ERR_INVALID_QP_ID = -22,
+- I40E_ERR_INVALID_CQ_ID = -23,
+- I40E_ERR_INVALID_CEQ_ID = -24,
+- I40E_ERR_INVALID_AEQ_ID = -25,
+ I40E_ERR_INVALID_SIZE = -26,
+- I40E_ERR_INVALID_ARP_INDEX = -27,
+- I40E_ERR_INVALID_FPM_FUNC_ID = -28,
+- I40E_ERR_QP_INVALID_MSG_SIZE = -29,
+- I40E_ERR_QP_TOOMANY_WRS_POSTED = -30,
+- I40E_ERR_INVALID_FRAG_COUNT = -31,
+ I40E_ERR_QUEUE_EMPTY = -32,
+- I40E_ERR_INVALID_ALIGNMENT = -33,
+- I40E_ERR_FLUSHED_QUEUE = -34,
+- I40E_ERR_INVALID_PUSH_PAGE_INDEX = -35,
+- I40E_ERR_INVALID_IMM_DATA_SIZE = -36,
+ I40E_ERR_TIMEOUT = -37,
+- I40E_ERR_OPCODE_MISMATCH = -38,
+- I40E_ERR_CQP_COMPL_ERROR = -39,
+- I40E_ERR_INVALID_VF_ID = -40,
+- I40E_ERR_INVALID_HMCFN_ID = -41,
+- I40E_ERR_BACKING_PAGE_ERROR = -42,
+- I40E_ERR_NO_PBLCHUNKS_AVAILABLE = -43,
+- I40E_ERR_INVALID_PBLE_INDEX = -44,
+ I40E_ERR_INVALID_SD_INDEX = -45,
+ I40E_ERR_INVALID_PAGE_DESC_INDEX = -46,
+ I40E_ERR_INVALID_SD_TYPE = -47,
+- I40E_ERR_MEMCPY_FAILED = -48,
+ I40E_ERR_INVALID_HMC_OBJ_INDEX = -49,
+ I40E_ERR_INVALID_HMC_OBJ_COUNT = -50,
+- I40E_ERR_INVALID_SRQ_ARM_LIMIT = -51,
+- I40E_ERR_SRQ_ENABLED = -52,
+ I40E_ERR_ADMIN_QUEUE_ERROR = -53,
+ I40E_ERR_ADMIN_QUEUE_TIMEOUT = -54,
+ I40E_ERR_BUF_TOO_SHORT = -55,
+ I40E_ERR_ADMIN_QUEUE_FULL = -56,
+ I40E_ERR_ADMIN_QUEUE_NO_WORK = -57,
+- I40E_ERR_BAD_IWARP_CQE = -58,
+ I40E_ERR_NVM_BLANK_MODE = -59,
+ I40E_ERR_NOT_IMPLEMENTED = -60,
+- I40E_ERR_PE_DOORBELL_NOT_ENABLED = -61,
+ I40E_ERR_DIAG_TEST_FAILED = -62,
+ I40E_ERR_NOT_READY = -63,
+ I40E_NOT_SUPPORTED = -64,
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+index 635f93d603186..cb7cf672f6971 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+@@ -17,7 +17,7 @@
+ **/
+ static void i40e_vc_vf_broadcast(struct i40e_pf *pf,
+ enum virtchnl_ops v_opcode,
+- i40e_status v_retval, u8 *msg,
++ int v_retval, u8 *msg,
+ u16 msglen)
+ {
+ struct i40e_hw *hw = &pf->hw;
+@@ -1246,13 +1246,13 @@ err:
+ * @vl: List of VLANs - apply filter for given VLANs
+ * @num_vlans: Number of elements in @vl
+ **/
+-static i40e_status
++static int
+ i40e_set_vsi_promisc(struct i40e_vf *vf, u16 seid, bool multi_enable,
+ bool unicast_enable, s16 *vl, u16 num_vlans)
+ {
+- i40e_status aq_ret, aq_tmp = 0;
+ struct i40e_pf *pf = vf->pf;
+ struct i40e_hw *hw = &pf->hw;
++ int aq_ret, aq_tmp = 0;
+ int i;
+
+ /* No VLAN to set promisc on, set on VSI */
+@@ -1264,9 +1264,9 @@ i40e_set_vsi_promisc(struct i40e_vf *vf, u16 seid, bool multi_enable,
+ int aq_err = pf->hw.aq.asq_last_status;
+
+ dev_err(&pf->pdev->dev,
+- "VF %d failed to set multicast promiscuous mode err %s aq_err %s\n",
++ "VF %d failed to set multicast promiscuous mode err %d aq_err %s\n",
+ vf->vf_id,
+- i40e_stat_str(&pf->hw, aq_ret),
++ aq_ret,
+ i40e_aq_str(&pf->hw, aq_err));
+
+ return aq_ret;
+@@ -1280,9 +1280,9 @@ i40e_set_vsi_promisc(struct i40e_vf *vf, u16 seid, bool multi_enable,
+ int aq_err = pf->hw.aq.asq_last_status;
+
+ dev_err(&pf->pdev->dev,
+- "VF %d failed to set unicast promiscuous mode err %s aq_err %s\n",
++ "VF %d failed to set unicast promiscuous mode err %d aq_err %s\n",
+ vf->vf_id,
+- i40e_stat_str(&pf->hw, aq_ret),
++ aq_ret,
+ i40e_aq_str(&pf->hw, aq_err));
+ }
+
+@@ -1297,9 +1297,9 @@ i40e_set_vsi_promisc(struct i40e_vf *vf, u16 seid, bool multi_enable,
+ int aq_err = pf->hw.aq.asq_last_status;
+
+ dev_err(&pf->pdev->dev,
+- "VF %d failed to set multicast promiscuous mode err %s aq_err %s\n",
++ "VF %d failed to set multicast promiscuous mode err %d aq_err %s\n",
+ vf->vf_id,
+- i40e_stat_str(&pf->hw, aq_ret),
++ aq_ret,
+ i40e_aq_str(&pf->hw, aq_err));
+
+ if (!aq_tmp)
+@@ -1313,9 +1313,9 @@ i40e_set_vsi_promisc(struct i40e_vf *vf, u16 seid, bool multi_enable,
+ int aq_err = pf->hw.aq.asq_last_status;
+
+ dev_err(&pf->pdev->dev,
+- "VF %d failed to set unicast promiscuous mode err %s aq_err %s\n",
++ "VF %d failed to set unicast promiscuous mode err %d aq_err %s\n",
+ vf->vf_id,
+- i40e_stat_str(&pf->hw, aq_ret),
++ aq_ret,
+ i40e_aq_str(&pf->hw, aq_err));
+
+ if (!aq_tmp)
+@@ -1339,13 +1339,13 @@ i40e_set_vsi_promisc(struct i40e_vf *vf, u16 seid, bool multi_enable,
+ * Called from the VF to configure the promiscuous mode of
+ * VF vsis and from the VF reset path to reset promiscuous mode.
+ **/
+-static i40e_status i40e_config_vf_promiscuous_mode(struct i40e_vf *vf,
+- u16 vsi_id,
+- bool allmulti,
+- bool alluni)
++static int i40e_config_vf_promiscuous_mode(struct i40e_vf *vf,
++ u16 vsi_id,
++ bool allmulti,
++ bool alluni)
+ {
+- i40e_status aq_ret = I40E_SUCCESS;
+ struct i40e_pf *pf = vf->pf;
++ int aq_ret = I40E_SUCCESS;
+ struct i40e_vsi *vsi;
+ u16 num_vlans;
+ s16 *vl;
+@@ -1955,7 +1955,7 @@ static int i40e_vc_send_msg_to_vf(struct i40e_vf *vf, u32 v_opcode,
+ struct i40e_pf *pf;
+ struct i40e_hw *hw;
+ int abs_vf_id;
+- i40e_status aq_ret;
++ int aq_ret;
+
+ /* validate the request */
+ if (!vf || vf->vf_id >= vf->pf->num_alloc_vfs)
+@@ -1987,7 +1987,7 @@ static int i40e_vc_send_msg_to_vf(struct i40e_vf *vf, u32 v_opcode,
+ **/
+ static int i40e_vc_send_resp_to_vf(struct i40e_vf *vf,
+ enum virtchnl_ops opcode,
+- i40e_status retval)
++ int retval)
+ {
+ return i40e_vc_send_msg_to_vf(vf, opcode, retval, NULL, 0);
+ }
+@@ -2091,9 +2091,9 @@ static int i40e_vc_get_vf_resources_msg(struct i40e_vf *vf, u8 *msg)
+ {
+ struct virtchnl_vf_resource *vfres = NULL;
+ struct i40e_pf *pf = vf->pf;
+- i40e_status aq_ret = 0;
+ struct i40e_vsi *vsi;
+ int num_vsis = 1;
++ int aq_ret = 0;
+ size_t len = 0;
+ int ret;
+
+@@ -2221,9 +2221,9 @@ static int i40e_vc_config_promiscuous_mode_msg(struct i40e_vf *vf, u8 *msg)
+ struct virtchnl_promisc_info *info =
+ (struct virtchnl_promisc_info *)msg;
+ struct i40e_pf *pf = vf->pf;
+- i40e_status aq_ret = 0;
+ bool allmulti = false;
+ bool alluni = false;
++ int aq_ret = 0;
+
+ if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) {
+ aq_ret = I40E_ERR_PARAM;
+@@ -2308,10 +2308,10 @@ static int i40e_vc_config_queues_msg(struct i40e_vf *vf, u8 *msg)
+ struct virtchnl_queue_pair_info *qpi;
+ u16 vsi_id, vsi_queue_id = 0;
+ struct i40e_pf *pf = vf->pf;
+- i40e_status aq_ret = 0;
+ int i, j = 0, idx = 0;
+ struct i40e_vsi *vsi;
+ u16 num_qps_all = 0;
++ int aq_ret = 0;
+
+ if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) {
+ aq_ret = I40E_ERR_PARAM;
+@@ -2458,8 +2458,8 @@ static int i40e_vc_config_irq_map_msg(struct i40e_vf *vf, u8 *msg)
+ struct virtchnl_irq_map_info *irqmap_info =
+ (struct virtchnl_irq_map_info *)msg;
+ struct virtchnl_vector_map *map;
++ int aq_ret = 0;
+ u16 vsi_id;
+- i40e_status aq_ret = 0;
+ int i;
+
+ if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) {
+@@ -2574,7 +2574,7 @@ static int i40e_vc_enable_queues_msg(struct i40e_vf *vf, u8 *msg)
+ struct virtchnl_queue_select *vqs =
+ (struct virtchnl_queue_select *)msg;
+ struct i40e_pf *pf = vf->pf;
+- i40e_status aq_ret = 0;
++ int aq_ret = 0;
+ int i;
+
+ if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) {
+@@ -2632,7 +2632,7 @@ static int i40e_vc_disable_queues_msg(struct i40e_vf *vf, u8 *msg)
+ struct virtchnl_queue_select *vqs =
+ (struct virtchnl_queue_select *)msg;
+ struct i40e_pf *pf = vf->pf;
+- i40e_status aq_ret = 0;
++ int aq_ret = 0;
+
+ if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) {
+ aq_ret = I40E_ERR_PARAM;
+@@ -2783,7 +2783,7 @@ static int i40e_vc_get_stats_msg(struct i40e_vf *vf, u8 *msg)
+ (struct virtchnl_queue_select *)msg;
+ struct i40e_pf *pf = vf->pf;
+ struct i40e_eth_stats stats;
+- i40e_status aq_ret = 0;
++ int aq_ret = 0;
+ struct i40e_vsi *vsi;
+
+ memset(&stats, 0, sizeof(struct i40e_eth_stats));
+@@ -2926,7 +2926,7 @@ static int i40e_vc_add_mac_addr_msg(struct i40e_vf *vf, u8 *msg)
+ (struct virtchnl_ether_addr_list *)msg;
+ struct i40e_pf *pf = vf->pf;
+ struct i40e_vsi *vsi = NULL;
+- i40e_status ret = 0;
++ int ret = 0;
+ int i;
+
+ if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE) ||
+@@ -2998,7 +2998,7 @@ static int i40e_vc_del_mac_addr_msg(struct i40e_vf *vf, u8 *msg)
+ bool was_unimac_deleted = false;
+ struct i40e_pf *pf = vf->pf;
+ struct i40e_vsi *vsi = NULL;
+- i40e_status ret = 0;
++ int ret = 0;
+ int i;
+
+ if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE) ||
+@@ -3071,7 +3071,7 @@ static int i40e_vc_add_vlan_msg(struct i40e_vf *vf, u8 *msg)
+ (struct virtchnl_vlan_filter_list *)msg;
+ struct i40e_pf *pf = vf->pf;
+ struct i40e_vsi *vsi = NULL;
+- i40e_status aq_ret = 0;
++ int aq_ret = 0;
+ int i;
+
+ if ((vf->num_vlan >= I40E_VC_MAX_VLAN_PER_VF) &&
+@@ -3142,7 +3142,7 @@ static int i40e_vc_remove_vlan_msg(struct i40e_vf *vf, u8 *msg)
+ (struct virtchnl_vlan_filter_list *)msg;
+ struct i40e_pf *pf = vf->pf;
+ struct i40e_vsi *vsi = NULL;
+- i40e_status aq_ret = 0;
++ int aq_ret = 0;
+ int i;
+
+ if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE) ||
+@@ -3198,7 +3198,7 @@ static int i40e_vc_iwarp_msg(struct i40e_vf *vf, u8 *msg, u16 msglen)
+ {
+ struct i40e_pf *pf = vf->pf;
+ int abs_vf_id = vf->vf_id + pf->hw.func_caps.vf_base_id;
+- i40e_status aq_ret = 0;
++ int aq_ret = 0;
+
+ if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states) ||
+ !test_bit(I40E_VF_STATE_IWARPENA, &vf->vf_states)) {
+@@ -3227,7 +3227,7 @@ static int i40e_vc_iwarp_qvmap_msg(struct i40e_vf *vf, u8 *msg, bool config)
+ {
+ struct virtchnl_iwarp_qvlist_info *qvlist_info =
+ (struct virtchnl_iwarp_qvlist_info *)msg;
+- i40e_status aq_ret = 0;
++ int aq_ret = 0;
+
+ if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states) ||
+ !test_bit(I40E_VF_STATE_IWARPENA, &vf->vf_states)) {
+@@ -3263,7 +3263,7 @@ static int i40e_vc_config_rss_key(struct i40e_vf *vf, u8 *msg)
+ (struct virtchnl_rss_key *)msg;
+ struct i40e_pf *pf = vf->pf;
+ struct i40e_vsi *vsi = NULL;
+- i40e_status aq_ret = 0;
++ int aq_ret = 0;
+
+ if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE) ||
+ !i40e_vc_isvalid_vsi_id(vf, vrk->vsi_id) ||
+@@ -3293,7 +3293,7 @@ static int i40e_vc_config_rss_lut(struct i40e_vf *vf, u8 *msg)
+ (struct virtchnl_rss_lut *)msg;
+ struct i40e_pf *pf = vf->pf;
+ struct i40e_vsi *vsi = NULL;
+- i40e_status aq_ret = 0;
++ int aq_ret = 0;
+ u16 i;
+
+ if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE) ||
+@@ -3328,7 +3328,7 @@ static int i40e_vc_get_rss_hena(struct i40e_vf *vf, u8 *msg)
+ {
+ struct virtchnl_rss_hena *vrh = NULL;
+ struct i40e_pf *pf = vf->pf;
+- i40e_status aq_ret = 0;
++ int aq_ret = 0;
+ int len = 0;
+
+ if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) {
+@@ -3365,7 +3365,7 @@ static int i40e_vc_set_rss_hena(struct i40e_vf *vf, u8 *msg)
+ (struct virtchnl_rss_hena *)msg;
+ struct i40e_pf *pf = vf->pf;
+ struct i40e_hw *hw = &pf->hw;
+- i40e_status aq_ret = 0;
++ int aq_ret = 0;
+
+ if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) {
+ aq_ret = I40E_ERR_PARAM;
+@@ -3389,8 +3389,8 @@ err:
+ **/
+ static int i40e_vc_enable_vlan_stripping(struct i40e_vf *vf, u8 *msg)
+ {
+- i40e_status aq_ret = 0;
+ struct i40e_vsi *vsi;
++ int aq_ret = 0;
+
+ if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) {
+ aq_ret = I40E_ERR_PARAM;
+@@ -3415,8 +3415,8 @@ err:
+ **/
+ static int i40e_vc_disable_vlan_stripping(struct i40e_vf *vf, u8 *msg)
+ {
+- i40e_status aq_ret = 0;
+ struct i40e_vsi *vsi;
++ int aq_ret = 0;
+
+ if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) {
+ aq_ret = I40E_ERR_PARAM;
+@@ -3615,8 +3615,8 @@ static void i40e_del_all_cloud_filters(struct i40e_vf *vf)
+ ret = i40e_add_del_cloud_filter(vsi, cfilter, false);
+ if (ret)
+ dev_err(&pf->pdev->dev,
+- "VF %d: Failed to delete cloud filter, err %s aq_err %s\n",
+- vf->vf_id, i40e_stat_str(&pf->hw, ret),
++ "VF %d: Failed to delete cloud filter, err %d aq_err %s\n",
++ vf->vf_id, ret,
+ i40e_aq_str(&pf->hw,
+ pf->hw.aq.asq_last_status));
+
+@@ -3642,7 +3642,7 @@ static int i40e_vc_del_cloud_filter(struct i40e_vf *vf, u8 *msg)
+ struct i40e_pf *pf = vf->pf;
+ struct i40e_vsi *vsi = NULL;
+ struct hlist_node *node;
+- i40e_status aq_ret = 0;
++ int aq_ret = 0;
+ int i, ret;
+
+ if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) {
+@@ -3718,8 +3718,8 @@ static int i40e_vc_del_cloud_filter(struct i40e_vf *vf, u8 *msg)
+ ret = i40e_add_del_cloud_filter(vsi, &cfilter, false);
+ if (ret) {
+ dev_err(&pf->pdev->dev,
+- "VF %d: Failed to delete cloud filter, err %s aq_err %s\n",
+- vf->vf_id, i40e_stat_str(&pf->hw, ret),
++ "VF %d: Failed to delete cloud filter, err %d aq_err %s\n",
++ vf->vf_id, ret,
+ i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
+ goto err;
+ }
+@@ -3773,7 +3773,7 @@ static int i40e_vc_add_cloud_filter(struct i40e_vf *vf, u8 *msg)
+ struct i40e_cloud_filter *cfilter = NULL;
+ struct i40e_pf *pf = vf->pf;
+ struct i40e_vsi *vsi = NULL;
+- i40e_status aq_ret = 0;
++ int aq_ret = 0;
+ int i, ret;
+
+ if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) {
+@@ -3852,8 +3852,8 @@ static int i40e_vc_add_cloud_filter(struct i40e_vf *vf, u8 *msg)
+ ret = i40e_add_del_cloud_filter(vsi, cfilter, true);
+ if (ret) {
+ dev_err(&pf->pdev->dev,
+- "VF %d: Failed to add cloud filter, err %s aq_err %s\n",
+- vf->vf_id, i40e_stat_str(&pf->hw, ret),
++ "VF %d: Failed to add cloud filter, err %d aq_err %s\n",
++ vf->vf_id, ret,
+ i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
+ goto err_free;
+ }
+@@ -3882,7 +3882,7 @@ static int i40e_vc_add_qch_msg(struct i40e_vf *vf, u8 *msg)
+ struct i40e_pf *pf = vf->pf;
+ struct i40e_link_status *ls = &pf->hw.phy.link_info;
+ int i, adq_request_qps = 0;
+- i40e_status aq_ret = 0;
++ int aq_ret = 0;
+ u64 speed = 0;
+
+ if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) {
+@@ -3994,7 +3994,7 @@ err:
+ static int i40e_vc_del_qch_msg(struct i40e_vf *vf, u8 *msg)
+ {
+ struct i40e_pf *pf = vf->pf;
+- i40e_status aq_ret = 0;
++ int aq_ret = 0;
+
+ if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) {
+ aq_ret = I40E_ERR_PARAM;
+diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
+index 6cfc9dc165378..0bbad4a5cc2f5 100644
+--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
+@@ -2665,6 +2665,14 @@ static int ixgbe_get_rss_hash_opts(struct ixgbe_adapter *adapter,
+ return 0;
+ }
+
++static int ixgbe_rss_indir_tbl_max(struct ixgbe_adapter *adapter)
++{
++ if (adapter->hw.mac.type < ixgbe_mac_X550)
++ return 16;
++ else
++ return 64;
++}
++
+ static int ixgbe_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
+ u32 *rule_locs)
+ {
+@@ -2673,7 +2681,8 @@ static int ixgbe_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
+
+ switch (cmd->cmd) {
+ case ETHTOOL_GRXRINGS:
+- cmd->data = adapter->num_rx_queues;
++ cmd->data = min_t(int, adapter->num_rx_queues,
++ ixgbe_rss_indir_tbl_max(adapter));
+ ret = 0;
+ break;
+ case ETHTOOL_GRXCLSRLCNT:
+@@ -3075,14 +3084,6 @@ static int ixgbe_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
+ return ret;
+ }
+
+-static int ixgbe_rss_indir_tbl_max(struct ixgbe_adapter *adapter)
+-{
+- if (adapter->hw.mac.type < ixgbe_mac_X550)
+- return 16;
+- else
+- return 64;
+-}
+-
+ static u32 ixgbe_get_rxfh_key_size(struct net_device *netdev)
+ {
+ return IXGBE_RSS_KEY_SIZE;
+@@ -3131,8 +3132,8 @@ static int ixgbe_set_rxfh(struct net_device *netdev, const u32 *indir,
+ int i;
+ u32 reta_entries = ixgbe_rss_indir_tbl_entries(adapter);
+
+- if (hfunc)
+- return -EINVAL;
++ if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
++ return -EOPNOTSUPP;
+
+ /* Fill out the redirection table */
+ if (indir) {
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/dev.c b/drivers/net/ethernet/mellanox/mlx5/core/dev.c
+index 0571e40c6ee5f..02bb9d43ff9c4 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/dev.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/dev.c
+@@ -396,7 +396,7 @@ int mlx5_attach_device(struct mlx5_core_dev *dev)
+ return ret;
+ }
+
+-void mlx5_detach_device(struct mlx5_core_dev *dev)
++void mlx5_detach_device(struct mlx5_core_dev *dev, bool suspend)
+ {
+ struct mlx5_priv *priv = &dev->priv;
+ struct auxiliary_device *adev;
+@@ -426,7 +426,7 @@ void mlx5_detach_device(struct mlx5_core_dev *dev)
+
+ adrv = to_auxiliary_drv(adev->dev.driver);
+
+- if (adrv->suspend) {
++ if (adrv->suspend && suspend) {
+ adrv->suspend(adev, pm);
+ continue;
+ }
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+index 5bd83c0275f82..2370e9ad52ea9 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+@@ -104,7 +104,7 @@ static int mlx5_devlink_reload_fw_activate(struct devlink *devlink, struct netli
+ if (err)
+ return err;
+
+- mlx5_unload_one_devl_locked(dev);
++ mlx5_unload_one_devl_locked(dev, true);
+ err = mlx5_health_wait_pci_up(dev);
+ if (err)
+ NL_SET_ERR_MSG_MOD(extack, "FW activate aborted, PCI reads fail after reset");
+@@ -162,7 +162,7 @@ static int mlx5_devlink_reload_down(struct devlink *devlink, bool netns_change,
+
+ switch (action) {
+ case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
+- mlx5_unload_one_devl_locked(dev);
++ mlx5_unload_one_devl_locked(dev, false);
+ break;
+ case DEVLINK_RELOAD_ACTION_FW_ACTIVATE:
+ if (limit == DEVLINK_RELOAD_LIMIT_NO_RESET)
+@@ -196,7 +196,7 @@ static int mlx5_devlink_reload_up(struct devlink *devlink, enum devlink_reload_a
+ break;
+ /* On fw_activate action, also driver is reloaded and reinit performed */
+ *actions_performed |= BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT);
+- ret = mlx5_load_one_devl_locked(dev, false);
++ ret = mlx5_load_one_devl_locked(dev, true);
+ break;
+ default:
+ /* Unsupported action should not get to this function */
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/post_act.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/post_act.c
+index 4e48946c4c2ac..0290e0dea5390 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/post_act.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/post_act.c
+@@ -106,22 +106,17 @@ err_rule:
+ }
+
+ struct mlx5e_post_act_handle *
+-mlx5e_tc_post_act_add(struct mlx5e_post_act *post_act, struct mlx5_flow_attr *attr)
++mlx5e_tc_post_act_add(struct mlx5e_post_act *post_act, struct mlx5_flow_attr *post_attr)
+ {
+- u32 attr_sz = ns_to_attr_sz(post_act->ns_type);
+ struct mlx5e_post_act_handle *handle;
+- struct mlx5_flow_attr *post_attr;
+ int err;
+
+ handle = kzalloc(sizeof(*handle), GFP_KERNEL);
+- post_attr = mlx5_alloc_flow_attr(post_act->ns_type);
+- if (!handle || !post_attr) {
+- kfree(post_attr);
++ if (!handle) {
+ kfree(handle);
+ return ERR_PTR(-ENOMEM);
+ }
+
+- memcpy(post_attr, attr, attr_sz);
+ post_attr->chain = 0;
+ post_attr->prio = 0;
+ post_attr->ft = post_act->ft;
+@@ -145,7 +140,6 @@ mlx5e_tc_post_act_add(struct mlx5e_post_act *post_act, struct mlx5_flow_attr *at
+ return handle;
+
+ err_xarray:
+- kfree(post_attr);
+ kfree(handle);
+ return ERR_PTR(err);
+ }
+@@ -164,7 +158,6 @@ mlx5e_tc_post_act_del(struct mlx5e_post_act *post_act, struct mlx5e_post_act_han
+ if (!IS_ERR_OR_NULL(handle->rule))
+ mlx5e_tc_post_act_unoffload(post_act, handle);
+ xa_erase(&post_act->ids, handle->id);
+- kfree(handle->attr);
+ kfree(handle);
+ }
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/post_act.h b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/post_act.h
+index f476774c0b75d..40b8df184af51 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/post_act.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/post_act.h
+@@ -19,7 +19,7 @@ void
+ mlx5e_tc_post_act_destroy(struct mlx5e_post_act *post_act);
+
+ struct mlx5e_post_act_handle *
+-mlx5e_tc_post_act_add(struct mlx5e_post_act *post_act, struct mlx5_flow_attr *attr);
++mlx5e_tc_post_act_add(struct mlx5e_post_act *post_act, struct mlx5_flow_attr *post_attr);
+
+ void
+ mlx5e_tc_post_act_del(struct mlx5e_post_act *post_act, struct mlx5e_post_act_handle *handle);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/sample.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/sample.c
+index f2c2c752bd1c3..c57b097275241 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/sample.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/sample.c
+@@ -14,10 +14,10 @@
+
+ #define MLX5_ESW_VPORT_TBL_SIZE_SAMPLE (64 * 1024)
+
+-static const struct esw_vport_tbl_namespace mlx5_esw_vport_tbl_sample_ns = {
++static struct esw_vport_tbl_namespace mlx5_esw_vport_tbl_sample_ns = {
+ .max_fte = MLX5_ESW_VPORT_TBL_SIZE_SAMPLE,
+ .max_num_groups = 0, /* default num of groups */
+- .flags = MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT | MLX5_FLOW_TABLE_TUNNEL_EN_DECAP,
++ .flags = 0,
+ };
+
+ struct mlx5e_tc_psample {
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c b/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
+index 7cd36f4ac3efc..eba601487eb79 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
+@@ -776,6 +776,7 @@ static int mlx5e_create_promisc_table(struct mlx5e_flow_steering *fs)
+ ft->t = mlx5_create_auto_grouped_flow_table(fs->ns, &ft_attr);
+ if (IS_ERR(ft->t)) {
+ err = PTR_ERR(ft->t);
++ ft->t = NULL;
+ fs_err(fs, "fail to create promisc table err=%d\n", err);
+ return err;
+ }
+@@ -803,7 +804,7 @@ static void mlx5e_del_promisc_rule(struct mlx5e_flow_steering *fs)
+
+ static void mlx5e_destroy_promisc_table(struct mlx5e_flow_steering *fs)
+ {
+- if (WARN(!fs->promisc.ft.t, "Trying to remove non-existing promiscuous table"))
++ if (!fs->promisc.ft.t)
+ return;
+ mlx5e_del_promisc_rule(fs);
+ mlx5_destroy_flow_table(fs->promisc.ft.t);
+@@ -1471,6 +1472,8 @@ err:
+
+ void mlx5e_fs_cleanup(struct mlx5e_flow_steering *fs)
+ {
++ if (!fs)
++ return;
+ mlx5e_fs_ethtool_free(fs);
+ mlx5e_fs_tc_free(fs);
+ mlx5e_fs_vlan_free(fs);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index 1f4233b2842f7..53eba076c53fc 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -5208,6 +5208,7 @@ static void mlx5e_nic_cleanup(struct mlx5e_priv *priv)
+ mlx5e_health_destroy_reporters(priv);
+ mlx5e_ktls_cleanup(priv);
+ mlx5e_fs_cleanup(priv->fs);
++ priv->fs = NULL;
+ }
+
+ static int mlx5e_init_nic_rx(struct mlx5e_priv *priv)
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
+index 301a734b7c6a7..21426decc4bde 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
+@@ -822,6 +822,7 @@ static int mlx5e_init_ul_rep(struct mlx5_core_dev *mdev,
+ static void mlx5e_cleanup_rep(struct mlx5e_priv *priv)
+ {
+ mlx5e_fs_cleanup(priv->fs);
++ priv->fs = NULL;
+ }
+
+ static int mlx5e_create_rep_ttc_table(struct mlx5e_priv *priv)
+@@ -988,6 +989,7 @@ err_close_drop_rq:
+ priv->rx_res = NULL;
+ err_free_fs:
+ mlx5e_fs_cleanup(priv->fs);
++ priv->fs = NULL;
+ return err;
+ }
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/vporttbl.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/vporttbl.c
+index 9e72118f2e4c0..749c3957a1280 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/vporttbl.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/vporttbl.c
+@@ -11,7 +11,7 @@ struct mlx5_vport_key {
+ u16 prio;
+ u16 vport;
+ u16 vhca_id;
+- const struct esw_vport_tbl_namespace *vport_ns;
++ struct esw_vport_tbl_namespace *vport_ns;
+ } __packed;
+
+ struct mlx5_vport_table {
+@@ -21,6 +21,14 @@ struct mlx5_vport_table {
+ struct mlx5_vport_key key;
+ };
+
++static void
++esw_vport_tbl_init(struct mlx5_eswitch *esw, struct esw_vport_tbl_namespace *ns)
++{
++ if (esw->offloads.encap != DEVLINK_ESWITCH_ENCAP_MODE_NONE)
++ ns->flags |= (MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT |
++ MLX5_FLOW_TABLE_TUNNEL_EN_DECAP);
++}
++
+ static struct mlx5_flow_table *
+ esw_vport_tbl_create(struct mlx5_eswitch *esw, struct mlx5_flow_namespace *ns,
+ const struct esw_vport_tbl_namespace *vport_ns)
+@@ -80,6 +88,7 @@ mlx5_esw_vporttbl_get(struct mlx5_eswitch *esw, struct mlx5_vport_tbl_attr *attr
+ u32 hkey;
+
+ mutex_lock(&esw->fdb_table.offloads.vports.lock);
++ esw_vport_tbl_init(esw, attr->vport_ns);
+ hkey = flow_attr_to_vport_key(esw, attr, &skey);
+ e = esw_vport_tbl_lookup(esw, &skey, hkey);
+ if (e) {
+@@ -127,6 +136,7 @@ mlx5_esw_vporttbl_put(struct mlx5_eswitch *esw, struct mlx5_vport_tbl_attr *attr
+ u32 hkey;
+
+ mutex_lock(&esw->fdb_table.offloads.vports.lock);
++ esw_vport_tbl_init(esw, attr->vport_ns);
+ hkey = flow_attr_to_vport_key(esw, attr, &key);
+ e = esw_vport_tbl_lookup(esw, &key, hkey);
+ if (!e || --e->num_rules)
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
+index 92644fbb50816..ceb6722c84e2c 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
+@@ -677,7 +677,7 @@ struct mlx5_vport_tbl_attr {
+ u32 chain;
+ u16 prio;
+ u16 vport;
+- const struct esw_vport_tbl_namespace *vport_ns;
++ struct esw_vport_tbl_namespace *vport_ns;
+ };
+
+ struct mlx5_flow_table *
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+index 0facc709f0e74..6561b6b505568 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+@@ -73,7 +73,7 @@
+
+ #define MLX5_ESW_FT_OFFLOADS_DROP_RULE (1)
+
+-static const struct esw_vport_tbl_namespace mlx5_esw_vport_tbl_mirror_ns = {
++static struct esw_vport_tbl_namespace mlx5_esw_vport_tbl_mirror_ns = {
+ .max_fte = MLX5_ESW_VPORT_TBL_SIZE,
+ .max_num_groups = MLX5_ESW_VPORT_TBL_NUM_GROUPS,
+ .flags = 0,
+@@ -763,7 +763,6 @@ mlx5_eswitch_add_fwd_rule(struct mlx5_eswitch *esw,
+ kfree(dest);
+ return rule;
+ err_chain_src_rewrite:
+- esw_put_dest_tables_loop(esw, attr, 0, i);
+ mlx5_esw_vporttbl_put(esw, &fwd_attr);
+ err_get_fwd:
+ mlx5_chains_put_table(chains, attr->chain, attr->prio, 0);
+@@ -806,7 +805,6 @@ __mlx5_eswitch_del_rule(struct mlx5_eswitch *esw,
+ if (fwd_rule) {
+ mlx5_esw_vporttbl_put(esw, &fwd_attr);
+ mlx5_chains_put_table(chains, attr->chain, attr->prio, 0);
+- esw_put_dest_tables_loop(esw, attr, 0, esw_attr->split_count);
+ } else {
+ if (split)
+ mlx5_esw_vporttbl_put(esw, &fwd_attr);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c
+index 3a9a6bb9158de..edd9102583144 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c
+@@ -210,18 +210,6 @@ static bool mlx5_eswitch_offload_is_uplink_port(const struct mlx5_eswitch *esw,
+ return (port_mask & port_value) == MLX5_VPORT_UPLINK;
+ }
+
+-static bool
+-mlx5_eswitch_is_push_vlan_no_cap(struct mlx5_eswitch *esw,
+- struct mlx5_flow_act *flow_act)
+-{
+- if (flow_act->action & MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH &&
+- !(mlx5_fs_get_capabilities(esw->dev, MLX5_FLOW_NAMESPACE_FDB) &
+- MLX5_FLOW_STEERING_CAP_VLAN_PUSH_ON_RX))
+- return true;
+-
+- return false;
+-}
+-
+ bool
+ mlx5_eswitch_termtbl_required(struct mlx5_eswitch *esw,
+ struct mlx5_flow_attr *attr,
+@@ -237,7 +225,10 @@ mlx5_eswitch_termtbl_required(struct mlx5_eswitch *esw,
+ (!mlx5_eswitch_offload_is_uplink_port(esw, spec) && !esw_attr->int_port))
+ return false;
+
+- if (mlx5_eswitch_is_push_vlan_no_cap(esw, flow_act))
++ /* push vlan on RX */
++ if (flow_act->action & MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH &&
++ !(mlx5_fs_get_capabilities(esw->dev, MLX5_FLOW_NAMESPACE_FDB) &
++ MLX5_FLOW_STEERING_CAP_VLAN_PUSH_ON_RX))
+ return true;
+
+ /* hairpin */
+@@ -261,31 +252,19 @@ mlx5_eswitch_add_termtbl_rule(struct mlx5_eswitch *esw,
+ struct mlx5_flow_act term_tbl_act = {};
+ struct mlx5_flow_handle *rule = NULL;
+ bool term_table_created = false;
+- bool is_push_vlan_on_rx;
+ int num_vport_dests = 0;
+ int i, curr_dest;
+
+- is_push_vlan_on_rx = mlx5_eswitch_is_push_vlan_no_cap(esw, flow_act);
+ mlx5_eswitch_termtbl_actions_move(flow_act, &term_tbl_act);
+ term_tbl_act.action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
+
+ for (i = 0; i < num_dest; i++) {
+ struct mlx5_termtbl_handle *tt;
+- bool hairpin = false;
+
+ /* only vport destinations can be terminated */
+ if (dest[i].type != MLX5_FLOW_DESTINATION_TYPE_VPORT)
+ continue;
+
+- if (attr->dests[num_vport_dests].rep &&
+- attr->dests[num_vport_dests].rep->vport == MLX5_VPORT_UPLINK)
+- hairpin = true;
+-
+- if (!is_push_vlan_on_rx && !hairpin) {
+- num_vport_dests++;
+- continue;
+- }
+-
+ if (attr->dests[num_vport_dests].flags & MLX5_ESW_DEST_ENCAP) {
+ term_tbl_act.action |= MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT;
+ term_tbl_act.pkt_reformat = attr->dests[num_vport_dests].pkt_reformat;
+@@ -333,9 +312,6 @@ revert_changes:
+ for (curr_dest = 0; curr_dest < num_vport_dests; curr_dest++) {
+ struct mlx5_termtbl_handle *tt = attr->dests[curr_dest].termtbl;
+
+- if (!tt)
+- continue;
+-
+ attr->dests[curr_dest].termtbl = NULL;
+
+ /* search for the destination associated with the
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+index 1e46f9afa40e0..d219f8417d93a 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+@@ -150,11 +150,11 @@ static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev)
+ if (test_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags)) {
+ complete(&fw_reset->done);
+ } else {
+- mlx5_unload_one(dev);
++ mlx5_unload_one(dev, false);
+ if (mlx5_health_wait_pci_up(dev))
+ mlx5_core_err(dev, "reset reload flow aborted, PCI reads still not working\n");
+ else
+- mlx5_load_one(dev, false);
++ mlx5_load_one(dev, true);
+ devlink_remote_reload_actions_performed(priv_to_devlink(dev), 0,
+ BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) |
+ BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE));
+@@ -484,8 +484,8 @@ int mlx5_fw_reset_wait_reset_done(struct mlx5_core_dev *dev)
+ }
+ err = fw_reset->ret;
+ if (test_and_clear_bit(MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED, &fw_reset->reset_flags)) {
+- mlx5_unload_one_devl_locked(dev);
+- mlx5_load_one_devl_locked(dev, false);
++ mlx5_unload_one_devl_locked(dev, false);
++ mlx5_load_one_devl_locked(dev, true);
+ }
+ out:
+ clear_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/health.c b/drivers/net/ethernet/mellanox/mlx5/core/health.c
+index 879555ba847dd..e42e4ac231c64 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/health.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/health.c
+@@ -699,7 +699,7 @@ static void mlx5_fw_fatal_reporter_err_work(struct work_struct *work)
+ * requests from the kernel.
+ */
+ mlx5_core_err(dev, "Driver is in error state. Unloading\n");
+- mlx5_unload_one(dev);
++ mlx5_unload_one(dev, false);
+ }
+ }
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+index f4e0431da55b4..0bb010d00a659 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+@@ -1502,12 +1502,12 @@ int mlx5_load_one(struct mlx5_core_dev *dev, bool recovery)
+ return ret;
+ }
+
+-void mlx5_unload_one_devl_locked(struct mlx5_core_dev *dev)
++void mlx5_unload_one_devl_locked(struct mlx5_core_dev *dev, bool suspend)
+ {
+ devl_assert_locked(priv_to_devlink(dev));
+ mutex_lock(&dev->intf_state_mutex);
+
+- mlx5_detach_device(dev);
++ mlx5_detach_device(dev, suspend);
+
+ if (!test_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state)) {
+ mlx5_core_warn(dev, "%s: interface is down, NOP\n",
+@@ -1522,12 +1522,12 @@ out:
+ mutex_unlock(&dev->intf_state_mutex);
+ }
+
+-void mlx5_unload_one(struct mlx5_core_dev *dev)
++void mlx5_unload_one(struct mlx5_core_dev *dev, bool suspend)
+ {
+ struct devlink *devlink = priv_to_devlink(dev);
+
+ devl_lock(devlink);
+- mlx5_unload_one_devl_locked(dev);
++ mlx5_unload_one_devl_locked(dev, suspend);
+ devl_unlock(devlink);
+ }
+
+@@ -1809,7 +1809,7 @@ static pci_ers_result_t mlx5_pci_err_detected(struct pci_dev *pdev,
+
+ mlx5_enter_error_state(dev, false);
+ mlx5_error_sw_reset(dev);
+- mlx5_unload_one(dev);
++ mlx5_unload_one(dev, true);
+ mlx5_drain_health_wq(dev);
+ mlx5_pci_disable_device(dev);
+
+@@ -1966,7 +1966,7 @@ static void shutdown(struct pci_dev *pdev)
+ set_bit(MLX5_BREAK_FW_WAIT, &dev->intf_state);
+ err = mlx5_try_fast_unload(dev);
+ if (err)
+- mlx5_unload_one(dev);
++ mlx5_unload_one(dev, false);
+ mlx5_pci_disable_device(dev);
+ }
+
+@@ -1974,7 +1974,7 @@ static int mlx5_suspend(struct pci_dev *pdev, pm_message_t state)
+ {
+ struct mlx5_core_dev *dev = pci_get_drvdata(pdev);
+
+- mlx5_unload_one(dev);
++ mlx5_unload_one(dev, true);
+
+ return 0;
+ }
+@@ -2017,7 +2017,7 @@ MODULE_DEVICE_TABLE(pci, mlx5_core_pci_table);
+ void mlx5_disable_device(struct mlx5_core_dev *dev)
+ {
+ mlx5_error_sw_reset(dev);
+- mlx5_unload_one_devl_locked(dev);
++ mlx5_unload_one_devl_locked(dev, false);
+ }
+
+ int mlx5_recover_device(struct mlx5_core_dev *dev)
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
+index 029305a8b80a8..a3c5c2dab5fd7 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
+@@ -236,7 +236,7 @@ void mlx5_adev_cleanup(struct mlx5_core_dev *dev);
+ int mlx5_adev_init(struct mlx5_core_dev *dev);
+
+ int mlx5_attach_device(struct mlx5_core_dev *dev);
+-void mlx5_detach_device(struct mlx5_core_dev *dev);
++void mlx5_detach_device(struct mlx5_core_dev *dev, bool suspend);
+ int mlx5_register_device(struct mlx5_core_dev *dev);
+ void mlx5_unregister_device(struct mlx5_core_dev *dev);
+ struct mlx5_core_dev *mlx5_get_next_phys_dev_lag(struct mlx5_core_dev *dev);
+@@ -319,8 +319,8 @@ int mlx5_mdev_init(struct mlx5_core_dev *dev, int profile_idx);
+ void mlx5_mdev_uninit(struct mlx5_core_dev *dev);
+ int mlx5_init_one(struct mlx5_core_dev *dev);
+ void mlx5_uninit_one(struct mlx5_core_dev *dev);
+-void mlx5_unload_one(struct mlx5_core_dev *dev);
+-void mlx5_unload_one_devl_locked(struct mlx5_core_dev *dev);
++void mlx5_unload_one(struct mlx5_core_dev *dev, bool suspend);
++void mlx5_unload_one_devl_locked(struct mlx5_core_dev *dev, bool suspend);
+ int mlx5_load_one(struct mlx5_core_dev *dev, bool recovery);
+ int mlx5_load_one_devl_locked(struct mlx5_core_dev *dev, bool recovery);
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/driver.c b/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/driver.c
+index 7b4783ce213e2..a7377619ba6f2 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/driver.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/driver.c
+@@ -74,7 +74,7 @@ static void mlx5_sf_dev_shutdown(struct auxiliary_device *adev)
+ {
+ struct mlx5_sf_dev *sf_dev = container_of(adev, struct mlx5_sf_dev, adev);
+
+- mlx5_unload_one(sf_dev->mdev);
++ mlx5_unload_one(sf_dev->mdev, false);
+ }
+
+ static const struct auxiliary_device_id mlx5_sf_dev_id_table[] = {
+diff --git a/drivers/net/ethernet/netronome/nfp/crypto/ipsec.c b/drivers/net/ethernet/netronome/nfp/crypto/ipsec.c
+index 063cd371033a8..b7cf18fcb9461 100644
+--- a/drivers/net/ethernet/netronome/nfp/crypto/ipsec.c
++++ b/drivers/net/ethernet/netronome/nfp/crypto/ipsec.c
+@@ -267,7 +267,7 @@ static void set_sha2_512hmac(struct nfp_ipsec_cfg_add_sa *cfg, int *trunc_len)
+
+ static int nfp_net_xfrm_add_state(struct xfrm_state *x)
+ {
+- struct net_device *netdev = x->xso.dev;
++ struct net_device *netdev = x->xso.real_dev;
+ struct nfp_ipsec_cfg_mssg msg = {};
+ int i, key_len, trunc_len, err = 0;
+ struct nfp_ipsec_cfg_add_sa *cfg;
+@@ -503,7 +503,7 @@ static void nfp_net_xfrm_del_state(struct xfrm_state *x)
+ .cmd = NFP_IPSEC_CFG_MSSG_INV_SA,
+ .sa_idx = x->xso.offload_handle - 1,
+ };
+- struct net_device *netdev = x->xso.dev;
++ struct net_device *netdev = x->xso.real_dev;
+ struct nfp_net *nn;
+ int err;
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+index 6656d76b6766b..cf682a9e3fff2 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+@@ -39,6 +39,24 @@ struct rk_gmac_ops {
+ u32 regs[];
+ };
+
++static const char * const rk_clocks[] = {
++ "aclk_mac", "pclk_mac", "mac_clk_tx", "clk_mac_speed",
++};
++
++static const char * const rk_rmii_clocks[] = {
++ "mac_clk_rx", "clk_mac_ref", "clk_mac_refout",
++};
++
++enum rk_clocks_index {
++ RK_ACLK_MAC = 0,
++ RK_PCLK_MAC,
++ RK_MAC_CLK_TX,
++ RK_CLK_MAC_SPEED,
++ RK_MAC_CLK_RX,
++ RK_CLK_MAC_REF,
++ RK_CLK_MAC_REFOUT,
++};
++
+ struct rk_priv_data {
+ struct platform_device *pdev;
+ phy_interface_t phy_iface;
+@@ -51,15 +69,9 @@ struct rk_priv_data {
+ bool clock_input;
+ bool integrated_phy;
+
++ struct clk_bulk_data *clks;
++ int num_clks;
+ struct clk *clk_mac;
+- struct clk *gmac_clkin;
+- struct clk *mac_clk_rx;
+- struct clk *mac_clk_tx;
+- struct clk *clk_mac_ref;
+- struct clk *clk_mac_refout;
+- struct clk *clk_mac_speed;
+- struct clk *aclk_mac;
+- struct clk *pclk_mac;
+ struct clk *clk_phy;
+
+ struct reset_control *phy_reset;
+@@ -104,10 +116,11 @@ static void px30_set_to_rmii(struct rk_priv_data *bsp_priv)
+
+ static void px30_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
+ {
++ struct clk *clk_mac_speed = bsp_priv->clks[RK_CLK_MAC_SPEED].clk;
+ struct device *dev = &bsp_priv->pdev->dev;
+ int ret;
+
+- if (IS_ERR(bsp_priv->clk_mac_speed)) {
++ if (!clk_mac_speed) {
+ dev_err(dev, "%s: Missing clk_mac_speed clock\n", __func__);
+ return;
+ }
+@@ -116,7 +129,7 @@ static void px30_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
+ regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1,
+ PX30_GMAC_SPEED_10M);
+
+- ret = clk_set_rate(bsp_priv->clk_mac_speed, 2500000);
++ ret = clk_set_rate(clk_mac_speed, 2500000);
+ if (ret)
+ dev_err(dev, "%s: set clk_mac_speed rate 2500000 failed: %d\n",
+ __func__, ret);
+@@ -124,7 +137,7 @@ static void px30_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
+ regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1,
+ PX30_GMAC_SPEED_100M);
+
+- ret = clk_set_rate(bsp_priv->clk_mac_speed, 25000000);
++ ret = clk_set_rate(clk_mac_speed, 25000000);
+ if (ret)
+ dev_err(dev, "%s: set clk_mac_speed rate 25000000 failed: %d\n",
+ __func__, ret);
+@@ -1066,6 +1079,7 @@ static void rk3568_set_to_rmii(struct rk_priv_data *bsp_priv)
+
+ static void rk3568_set_gmac_speed(struct rk_priv_data *bsp_priv, int speed)
+ {
++ struct clk *clk_mac_speed = bsp_priv->clks[RK_CLK_MAC_SPEED].clk;
+ struct device *dev = &bsp_priv->pdev->dev;
+ unsigned long rate;
+ int ret;
+@@ -1085,7 +1099,7 @@ static void rk3568_set_gmac_speed(struct rk_priv_data *bsp_priv, int speed)
+ return;
+ }
+
+- ret = clk_set_rate(bsp_priv->clk_mac_speed, rate);
++ ret = clk_set_rate(clk_mac_speed, rate);
+ if (ret)
+ dev_err(dev, "%s: set clk_mac_speed rate %ld failed %d\n",
+ __func__, rate, ret);
+@@ -1371,6 +1385,7 @@ static void rv1126_set_to_rmii(struct rk_priv_data *bsp_priv)
+
+ static void rv1126_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
+ {
++ struct clk *clk_mac_speed = bsp_priv->clks[RK_CLK_MAC_SPEED].clk;
+ struct device *dev = &bsp_priv->pdev->dev;
+ unsigned long rate;
+ int ret;
+@@ -1390,7 +1405,7 @@ static void rv1126_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
+ return;
+ }
+
+- ret = clk_set_rate(bsp_priv->clk_mac_speed, rate);
++ ret = clk_set_rate(clk_mac_speed, rate);
+ if (ret)
+ dev_err(dev, "%s: set clk_mac_speed rate %ld failed %d\n",
+ __func__, rate, ret);
+@@ -1398,6 +1413,7 @@ static void rv1126_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
+
+ static void rv1126_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
+ {
++ struct clk *clk_mac_speed = bsp_priv->clks[RK_CLK_MAC_SPEED].clk;
+ struct device *dev = &bsp_priv->pdev->dev;
+ unsigned long rate;
+ int ret;
+@@ -1414,7 +1430,7 @@ static void rv1126_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
+ return;
+ }
+
+- ret = clk_set_rate(bsp_priv->clk_mac_speed, rate);
++ ret = clk_set_rate(clk_mac_speed, rate);
+ if (ret)
+ dev_err(dev, "%s: set clk_mac_speed rate %ld failed %d\n",
+ __func__, rate, ret);
+@@ -1475,68 +1491,50 @@ static int rk_gmac_clk_init(struct plat_stmmacenet_data *plat)
+ {
+ struct rk_priv_data *bsp_priv = plat->bsp_priv;
+ struct device *dev = &bsp_priv->pdev->dev;
+- int ret;
++ int phy_iface = bsp_priv->phy_iface;
++ int i, j, ret;
+
+ bsp_priv->clk_enabled = false;
+
+- bsp_priv->mac_clk_rx = devm_clk_get(dev, "mac_clk_rx");
+- if (IS_ERR(bsp_priv->mac_clk_rx))
+- dev_err(dev, "cannot get clock %s\n",
+- "mac_clk_rx");
++ bsp_priv->num_clks = ARRAY_SIZE(rk_clocks);
++ if (phy_iface == PHY_INTERFACE_MODE_RMII)
++ bsp_priv->num_clks += ARRAY_SIZE(rk_rmii_clocks);
+
+- bsp_priv->mac_clk_tx = devm_clk_get(dev, "mac_clk_tx");
+- if (IS_ERR(bsp_priv->mac_clk_tx))
+- dev_err(dev, "cannot get clock %s\n",
+- "mac_clk_tx");
++ bsp_priv->clks = devm_kcalloc(dev, bsp_priv->num_clks,
++ sizeof(*bsp_priv->clks), GFP_KERNEL);
++ if (!bsp_priv->clks)
++ return -ENOMEM;
+
+- bsp_priv->aclk_mac = devm_clk_get(dev, "aclk_mac");
+- if (IS_ERR(bsp_priv->aclk_mac))
+- dev_err(dev, "cannot get clock %s\n",
+- "aclk_mac");
++ for (i = 0; i < ARRAY_SIZE(rk_clocks); i++)
++ bsp_priv->clks[i].id = rk_clocks[i];
+
+- bsp_priv->pclk_mac = devm_clk_get(dev, "pclk_mac");
+- if (IS_ERR(bsp_priv->pclk_mac))
+- dev_err(dev, "cannot get clock %s\n",
+- "pclk_mac");
+-
+- bsp_priv->clk_mac = devm_clk_get(dev, "stmmaceth");
+- if (IS_ERR(bsp_priv->clk_mac))
+- dev_err(dev, "cannot get clock %s\n",
+- "stmmaceth");
+-
+- if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) {
+- bsp_priv->clk_mac_ref = devm_clk_get(dev, "clk_mac_ref");
+- if (IS_ERR(bsp_priv->clk_mac_ref))
+- dev_err(dev, "cannot get clock %s\n",
+- "clk_mac_ref");
+-
+- if (!bsp_priv->clock_input) {
+- bsp_priv->clk_mac_refout =
+- devm_clk_get(dev, "clk_mac_refout");
+- if (IS_ERR(bsp_priv->clk_mac_refout))
+- dev_err(dev, "cannot get clock %s\n",
+- "clk_mac_refout");
+- }
++ if (phy_iface == PHY_INTERFACE_MODE_RMII) {
++ for (j = 0; j < ARRAY_SIZE(rk_rmii_clocks); j++)
++ bsp_priv->clks[i++].id = rk_rmii_clocks[j];
+ }
+
+- bsp_priv->clk_mac_speed = devm_clk_get(dev, "clk_mac_speed");
+- if (IS_ERR(bsp_priv->clk_mac_speed))
+- dev_err(dev, "cannot get clock %s\n", "clk_mac_speed");
++ ret = devm_clk_bulk_get_optional(dev, bsp_priv->num_clks,
++ bsp_priv->clks);
++ if (ret)
++ return dev_err_probe(dev, ret, "Failed to get clocks\n");
++
++ /* "stmmaceth" will be enabled by the core */
++ bsp_priv->clk_mac = devm_clk_get(dev, "stmmaceth");
++ ret = PTR_ERR_OR_ZERO(bsp_priv->clk_mac);
++ if (ret)
++ return dev_err_probe(dev, ret, "Cannot get stmmaceth clock\n");
+
+ if (bsp_priv->clock_input) {
+ dev_info(dev, "clock input from PHY\n");
+- } else {
+- if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII)
+- clk_set_rate(bsp_priv->clk_mac, 50000000);
++ } else if (phy_iface == PHY_INTERFACE_MODE_RMII) {
++ clk_set_rate(bsp_priv->clk_mac, 50000000);
+ }
+
+ if (plat->phy_node && bsp_priv->integrated_phy) {
+ bsp_priv->clk_phy = of_clk_get(plat->phy_node, 0);
+- if (IS_ERR(bsp_priv->clk_phy)) {
+- ret = PTR_ERR(bsp_priv->clk_phy);
+- dev_err(dev, "Cannot get PHY clock: %d\n", ret);
+- return -EINVAL;
+- }
++ ret = PTR_ERR_OR_ZERO(bsp_priv->clk_phy);
++ if (ret)
++ return dev_err_probe(dev, ret, "Cannot get PHY clock\n");
+ clk_set_rate(bsp_priv->clk_phy, 50000000);
+ }
+
+@@ -1545,77 +1543,36 @@ static int rk_gmac_clk_init(struct plat_stmmacenet_data *plat)
+
+ static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable)
+ {
+- int phy_iface = bsp_priv->phy_iface;
++ int ret;
+
+ if (enable) {
+ if (!bsp_priv->clk_enabled) {
+- if (phy_iface == PHY_INTERFACE_MODE_RMII) {
+- if (!IS_ERR(bsp_priv->mac_clk_rx))
+- clk_prepare_enable(
+- bsp_priv->mac_clk_rx);
+-
+- if (!IS_ERR(bsp_priv->clk_mac_ref))
+- clk_prepare_enable(
+- bsp_priv->clk_mac_ref);
+-
+- if (!IS_ERR(bsp_priv->clk_mac_refout))
+- clk_prepare_enable(
+- bsp_priv->clk_mac_refout);
+- }
+-
+- if (!IS_ERR(bsp_priv->clk_phy))
+- clk_prepare_enable(bsp_priv->clk_phy);
++ ret = clk_bulk_prepare_enable(bsp_priv->num_clks,
++ bsp_priv->clks);
++ if (ret)
++ return ret;
+
+- if (!IS_ERR(bsp_priv->aclk_mac))
+- clk_prepare_enable(bsp_priv->aclk_mac);
+-
+- if (!IS_ERR(bsp_priv->pclk_mac))
+- clk_prepare_enable(bsp_priv->pclk_mac);
+-
+- if (!IS_ERR(bsp_priv->mac_clk_tx))
+- clk_prepare_enable(bsp_priv->mac_clk_tx);
+-
+- if (!IS_ERR(bsp_priv->clk_mac_speed))
+- clk_prepare_enable(bsp_priv->clk_mac_speed);
++ ret = clk_prepare_enable(bsp_priv->clk_phy);
++ if (ret)
++ return ret;
+
+ if (bsp_priv->ops && bsp_priv->ops->set_clock_selection)
+ bsp_priv->ops->set_clock_selection(bsp_priv,
+ bsp_priv->clock_input, true);
+
+- /**
+- * if (!IS_ERR(bsp_priv->clk_mac))
+- * clk_prepare_enable(bsp_priv->clk_mac);
+- */
+ mdelay(5);
+ bsp_priv->clk_enabled = true;
+ }
+ } else {
+ if (bsp_priv->clk_enabled) {
+- if (phy_iface == PHY_INTERFACE_MODE_RMII) {
+- clk_disable_unprepare(bsp_priv->mac_clk_rx);
+-
+- clk_disable_unprepare(bsp_priv->clk_mac_ref);
+-
+- clk_disable_unprepare(bsp_priv->clk_mac_refout);
+- }
+-
++ clk_bulk_disable_unprepare(bsp_priv->num_clks,
++ bsp_priv->clks);
+ clk_disable_unprepare(bsp_priv->clk_phy);
+
+- clk_disable_unprepare(bsp_priv->aclk_mac);
+-
+- clk_disable_unprepare(bsp_priv->pclk_mac);
+-
+- clk_disable_unprepare(bsp_priv->mac_clk_tx);
+-
+- clk_disable_unprepare(bsp_priv->clk_mac_speed);
+-
+ if (bsp_priv->ops && bsp_priv->ops->set_clock_selection)
+ bsp_priv->ops->set_clock_selection(bsp_priv,
+ bsp_priv->clock_input, false);
+- /**
+- * if (!IS_ERR(bsp_priv->clk_mac))
+- * clk_disable_unprepare(bsp_priv->clk_mac);
+- */
++
+ bsp_priv->clk_enabled = false;
+ }
+ }
+@@ -1629,9 +1586,6 @@ static int phy_power_on(struct rk_priv_data *bsp_priv, bool enable)
+ int ret;
+ struct device *dev = &bsp_priv->pdev->dev;
+
+- if (!ldo)
+- return 0;
+-
+ if (enable) {
+ ret = regulator_enable(ldo);
+ if (ret)
+@@ -1679,14 +1633,11 @@ static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev,
+ }
+ }
+
+- bsp_priv->regulator = devm_regulator_get_optional(dev, "phy");
++ bsp_priv->regulator = devm_regulator_get(dev, "phy");
+ if (IS_ERR(bsp_priv->regulator)) {
+- if (PTR_ERR(bsp_priv->regulator) == -EPROBE_DEFER) {
+- dev_err(dev, "phy regulator is not available yet, deferred probing\n");
+- return ERR_PTR(-EPROBE_DEFER);
+- }
+- dev_err(dev, "no regulator found\n");
+- bsp_priv->regulator = NULL;
++ ret = PTR_ERR(bsp_priv->regulator);
++ dev_err_probe(dev, ret, "failed to get phy regulator\n");
++ return ERR_PTR(ret);
+ }
+
+ ret = of_property_read_string(dev->of_node, "clock_in_out", &strings);
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index 014ce97f96b15..d0e64c1ab9a55 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -6348,6 +6348,10 @@ static int stmmac_vlan_rx_add_vid(struct net_device *ndev, __be16 proto, u16 vid
+ bool is_double = false;
+ int ret;
+
++ ret = pm_runtime_resume_and_get(priv->device);
++ if (ret < 0)
++ return ret;
++
+ if (be16_to_cpu(proto) == ETH_P_8021AD)
+ is_double = true;
+
+@@ -6355,16 +6359,18 @@ static int stmmac_vlan_rx_add_vid(struct net_device *ndev, __be16 proto, u16 vid
+ ret = stmmac_vlan_update(priv, is_double);
+ if (ret) {
+ clear_bit(vid, priv->active_vlans);
+- return ret;
++ goto err_pm_put;
+ }
+
+ if (priv->hw->num_vlan) {
+ ret = stmmac_add_hw_vlan_rx_fltr(priv, ndev, priv->hw, proto, vid);
+ if (ret)
+- return ret;
++ goto err_pm_put;
+ }
++err_pm_put:
++ pm_runtime_put(priv->device);
+
+- return 0;
++ return ret;
+ }
+
+ static int stmmac_vlan_rx_kill_vid(struct net_device *ndev, __be16 proto, u16 vid)
+diff --git a/drivers/net/ethernet/sun/sunhme.c b/drivers/net/ethernet/sun/sunhme.c
+index b0c7ab74a82ed..7cf8210ebbec3 100644
+--- a/drivers/net/ethernet/sun/sunhme.c
++++ b/drivers/net/ethernet/sun/sunhme.c
+@@ -2834,7 +2834,7 @@ static int happy_meal_pci_probe(struct pci_dev *pdev,
+ int i, qfe_slot = -1;
+ char prom_name[64];
+ u8 addr[ETH_ALEN];
+- int err;
++ int err = -ENODEV;
+
+ /* Now make sure pci_dev cookie is there. */
+ #ifdef CONFIG_SPARC
+diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c
+index f6a038a1d51e4..c70b27c4c1d5e 100644
+--- a/drivers/net/pcs/pcs-xpcs.c
++++ b/drivers/net/pcs/pcs-xpcs.c
+@@ -323,7 +323,7 @@ static int xpcs_read_fault_c73(struct dw_xpcs *xpcs,
+ return 0;
+ }
+
+-static int xpcs_read_link_c73(struct dw_xpcs *xpcs, bool an)
++static int xpcs_read_link_c73(struct dw_xpcs *xpcs)
+ {
+ bool link = true;
+ int ret;
+@@ -335,15 +335,6 @@ static int xpcs_read_link_c73(struct dw_xpcs *xpcs, bool an)
+ if (!(ret & MDIO_STAT1_LSTATUS))
+ link = false;
+
+- if (an) {
+- ret = xpcs_read(xpcs, MDIO_MMD_AN, MDIO_STAT1);
+- if (ret < 0)
+- return ret;
+-
+- if (!(ret & MDIO_STAT1_LSTATUS))
+- link = false;
+- }
+-
+ return link;
+ }
+
+@@ -937,7 +928,7 @@ static int xpcs_get_state_c73(struct dw_xpcs *xpcs,
+ int ret;
+
+ /* Link needs to be read first ... */
+- state->link = xpcs_read_link_c73(xpcs, state->an_enabled) > 0 ? 1 : 0;
++ state->link = xpcs_read_link_c73(xpcs) > 0 ? 1 : 0;
+
+ /* ... and then we check the faults. */
+ ret = xpcs_read_fault_c73(xpcs, state);
+diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c
+index b224800d7db0b..10e66c89ca0fe 100644
+--- a/drivers/net/phy/sfp.c
++++ b/drivers/net/phy/sfp.c
+@@ -395,6 +395,10 @@ static const struct sfp_quirk sfp_quirks[] = {
+
+ SFP_QUIRK_F("HALNy", "HL-GSFP", sfp_fixup_halny_gsfp),
+
++ // HG MXPD-483II-F 2.5G supports 2500Base-X, but incorrectly reports
++ // 2600MBd in their EERPOM
++ SFP_QUIRK_M("HG GENUINE", "MXPD-483II", sfp_quirk_2500basex),
++
+ // Huawei MA5671A can operate at 2500base-X, but report 1.2GBd NRZ in
+ // their EEPROM
+ SFP_QUIRK("HUAWEI", "MA5671A", sfp_quirk_2500basex,
+diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c
+index d34a4d6325b2b..76f275ca53e9c 100644
+--- a/drivers/net/wireless/ath/ath11k/ahb.c
++++ b/drivers/net/wireless/ath/ath11k/ahb.c
+@@ -859,11 +859,11 @@ static int ath11k_ahb_setup_msi_resources(struct ath11k_base *ab)
+ ab->pci.msi.ep_base_data = int_prop + 32;
+
+ for (i = 0; i < ab->pci.msi.config->total_vectors; i++) {
+- res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
+- if (!res)
+- return -ENODEV;
++ ret = platform_get_irq(pdev, i);
++ if (ret < 0)
++ return ret;
+
+- ab->pci.msi.irqs[i] = res->start;
++ ab->pci.msi.irqs[i] = ret;
+ }
+
+ set_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags);
+@@ -1063,6 +1063,12 @@ static int ath11k_ahb_fw_resource_deinit(struct ath11k_base *ab)
+ struct iommu_domain *iommu;
+ size_t unmapped_size;
+
++ /* Chipsets not requiring MSA would have not initialized
++ * MSA resources, return success in such cases.
++ */
++ if (!ab->hw_params.fixed_fw_mem)
++ return 0;
++
+ if (ab_ahb->fw.use_tz)
+ return 0;
+
+diff --git a/drivers/net/wireless/ath/ath11k/dbring.c b/drivers/net/wireless/ath/ath11k/dbring.c
+index 2107ec05d14fd..5536e86423312 100644
+--- a/drivers/net/wireless/ath/ath11k/dbring.c
++++ b/drivers/net/wireless/ath/ath11k/dbring.c
+@@ -26,13 +26,13 @@ int ath11k_dbring_validate_buffer(struct ath11k *ar, void *buffer, u32 size)
+ static void ath11k_dbring_fill_magic_value(struct ath11k *ar,
+ void *buffer, u32 size)
+ {
+- u32 *temp;
+- int idx;
+-
+- size = size >> 2;
++ /* memset32 function fills buffer payload with the ATH11K_DB_MAGIC_VALUE
++ * and the variable size is expected to be the number of u32 values
++ * to be stored, not the number of bytes.
++ */
++ size = size / sizeof(u32);
+
+- for (idx = 0, temp = buffer; idx < size; idx++, temp++)
+- *temp++ = ATH11K_DB_MAGIC_VALUE;
++ memset32(buffer, ATH11K_DB_MAGIC_VALUE, size);
+ }
+
+ static int ath11k_dbring_bufs_replenish(struct ath11k *ar,
+diff --git a/drivers/net/wireless/ath/ath11k/mhi.c b/drivers/net/wireless/ath/ath11k/mhi.c
+index 86995e8dc9135..a62ee05c54097 100644
+--- a/drivers/net/wireless/ath/ath11k/mhi.c
++++ b/drivers/net/wireless/ath/ath11k/mhi.c
+@@ -16,7 +16,7 @@
+ #include "pci.h"
+ #include "pcic.h"
+
+-#define MHI_TIMEOUT_DEFAULT_MS 90000
++#define MHI_TIMEOUT_DEFAULT_MS 20000
+ #define RDDM_DUMP_SIZE 0x420000
+
+ static struct mhi_channel_config ath11k_mhi_channels_qca6390[] = {
+diff --git a/drivers/net/wireless/ath/ath11k/peer.c b/drivers/net/wireless/ath/ath11k/peer.c
+index 1ae7af02c364e..1380811827a84 100644
+--- a/drivers/net/wireless/ath/ath11k/peer.c
++++ b/drivers/net/wireless/ath/ath11k/peer.c
+@@ -382,22 +382,23 @@ int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif,
+ return -ENOBUFS;
+ }
+
++ mutex_lock(&ar->ab->tbl_mtx_lock);
+ spin_lock_bh(&ar->ab->base_lock);
+ peer = ath11k_peer_find_by_addr(ar->ab, param->peer_addr);
+ if (peer) {
+ if (peer->vdev_id == param->vdev_id) {
+ spin_unlock_bh(&ar->ab->base_lock);
++ mutex_unlock(&ar->ab->tbl_mtx_lock);
+ return -EINVAL;
+ }
+
+ /* Assume sta is transitioning to another band.
+ * Remove here the peer from rhash.
+ */
+- mutex_lock(&ar->ab->tbl_mtx_lock);
+ ath11k_peer_rhash_delete(ar->ab, peer);
+- mutex_unlock(&ar->ab->tbl_mtx_lock);
+ }
+ spin_unlock_bh(&ar->ab->base_lock);
++ mutex_unlock(&ar->ab->tbl_mtx_lock);
+
+ ret = ath11k_wmi_send_peer_create_cmd(ar, param);
+ if (ret) {
+diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c
+index 2c9cec8b53d9e..28a1e5eff204e 100644
+--- a/drivers/net/wireless/ath/ath5k/ahb.c
++++ b/drivers/net/wireless/ath/ath5k/ahb.c
+@@ -113,15 +113,13 @@ static int ath_ahb_probe(struct platform_device *pdev)
+ goto err_out;
+ }
+
+- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+- if (res == NULL) {
+- dev_err(&pdev->dev, "no IRQ resource found\n");
+- ret = -ENXIO;
++ irq = platform_get_irq(pdev, 0);
++ if (irq < 0) {
++ dev_err(&pdev->dev, "no IRQ resource found: %d\n", irq);
++ ret = irq;
+ goto err_iounmap;
+ }
+
+- irq = res->start;
+-
+ hw = ieee80211_alloc_hw(sizeof(struct ath5k_hw), &ath5k_hw_ops);
+ if (hw == NULL) {
+ dev_err(&pdev->dev, "no memory for ieee80211_hw\n");
+diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c
+index d444b3d70ba2e..58d3e86f6256d 100644
+--- a/drivers/net/wireless/ath/ath5k/eeprom.c
++++ b/drivers/net/wireless/ath/ath5k/eeprom.c
+@@ -529,7 +529,7 @@ ath5k_eeprom_read_freq_list(struct ath5k_hw *ah, int *offset, int max,
+ ee->ee_n_piers[mode]++;
+
+ freq2 = (val >> 8) & 0xff;
+- if (!freq2)
++ if (!freq2 || i >= max)
+ break;
+
+ pc[i++].freq = ath5k_eeprom_bin2freq(ee,
+diff --git a/drivers/net/wireless/ath/ath6kl/bmi.c b/drivers/net/wireless/ath/ath6kl/bmi.c
+index bde5a10d470c8..af98e871199d3 100644
+--- a/drivers/net/wireless/ath/ath6kl/bmi.c
++++ b/drivers/net/wireless/ath/ath6kl/bmi.c
+@@ -246,7 +246,7 @@ int ath6kl_bmi_execute(struct ath6kl *ar, u32 addr, u32 *param)
+ return -EACCES;
+ }
+
+- size = sizeof(cid) + sizeof(addr) + sizeof(param);
++ size = sizeof(cid) + sizeof(addr) + sizeof(*param);
+ if (size > ar->bmi.max_cmd_size) {
+ WARN_ON(1);
+ return -EINVAL;
+diff --git a/drivers/net/wireless/ath/ath6kl/htc_pipe.c b/drivers/net/wireless/ath/ath6kl/htc_pipe.c
+index c68848819a52d..9b88d96bfe96c 100644
+--- a/drivers/net/wireless/ath/ath6kl/htc_pipe.c
++++ b/drivers/net/wireless/ath/ath6kl/htc_pipe.c
+@@ -960,8 +960,8 @@ static int ath6kl_htc_pipe_rx_complete(struct ath6kl *ar, struct sk_buff *skb,
+ * Thus the possibility of ar->htc_target being NULL
+ * via ath6kl_recv_complete -> ath6kl_usb_io_comp_work.
+ */
+- if (WARN_ON_ONCE(!target)) {
+- ath6kl_err("Target not yet initialized\n");
++ if (!target) {
++ ath6kl_dbg(ATH6KL_DBG_HTC, "Target not yet initialized\n");
+ status = -EINVAL;
+ goto free_skb;
+ }
+diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
+index f521dfa2f1945..e0130beb304df 100644
+--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
++++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
+@@ -534,6 +534,24 @@ static struct ath9k_htc_hif hif_usb = {
+ .send = hif_usb_send,
+ };
+
++/* Need to free remain_skb allocated in ath9k_hif_usb_rx_stream
++ * in case ath9k_hif_usb_rx_stream wasn't called next time to
++ * process the buffer and subsequently free it.
++ */
++static void ath9k_hif_usb_free_rx_remain_skb(struct hif_device_usb *hif_dev)
++{
++ unsigned long flags;
++
++ spin_lock_irqsave(&hif_dev->rx_lock, flags);
++ if (hif_dev->remain_skb) {
++ dev_kfree_skb_any(hif_dev->remain_skb);
++ hif_dev->remain_skb = NULL;
++ hif_dev->rx_remain_len = 0;
++ RX_STAT_INC(hif_dev, skb_dropped);
++ }
++ spin_unlock_irqrestore(&hif_dev->rx_lock, flags);
++}
++
+ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
+ struct sk_buff *skb)
+ {
+@@ -868,6 +886,7 @@ err:
+ static void ath9k_hif_usb_dealloc_rx_urbs(struct hif_device_usb *hif_dev)
+ {
+ usb_kill_anchored_urbs(&hif_dev->rx_submitted);
++ ath9k_hif_usb_free_rx_remain_skb(hif_dev);
+ }
+
+ static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev)
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+index b8c99bfce963a..d17bb22422f48 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+@@ -6494,18 +6494,20 @@ static s32 brcmf_notify_rssi(struct brcmf_if *ifp,
+ {
+ struct brcmf_cfg80211_vif *vif = ifp->vif;
+ struct brcmf_rssi_be *info = data;
+- s32 rssi, snr, noise;
++ s32 rssi, snr = 0, noise = 0;
+ s32 low, high, last;
+
+- if (e->datalen < sizeof(*info)) {
++ if (e->datalen >= sizeof(*info)) {
++ rssi = be32_to_cpu(info->rssi);
++ snr = be32_to_cpu(info->snr);
++ noise = be32_to_cpu(info->noise);
++ } else if (e->datalen >= sizeof(rssi)) {
++ rssi = be32_to_cpu(*(__be32 *)data);
++ } else {
+ brcmf_err("insufficient RSSI event data\n");
+ return 0;
+ }
+
+- rssi = be32_to_cpu(info->rssi);
+- snr = be32_to_cpu(info->snr);
+- noise = be32_to_cpu(info->noise);
+-
+ low = vif->cqm_rssi_low;
+ high = vif->cqm_rssi_high;
+ last = vif->cqm_rssi_last;
+diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+index abf49022edbe4..027360e63b926 100644
+--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
++++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+@@ -1038,7 +1038,7 @@ iwl_dump_ini_prph_mac_iter(struct iwl_fw_runtime *fwrt,
+ range->range_data_size = reg->dev_addr.size;
+ for (i = 0; i < le32_to_cpu(reg->dev_addr.size); i += 4) {
+ prph_val = iwl_read_prph(fwrt->trans, addr + i);
+- if (prph_val == 0x5a5a5a5a)
++ if ((prph_val & ~0xf) == 0xa5a5a5a0)
+ return -EBUSY;
+ *val++ = cpu_to_le32(prph_val);
+ }
+@@ -1388,13 +1388,13 @@ static void iwl_ini_get_rxf_data(struct iwl_fw_runtime *fwrt,
+ if (!data)
+ return;
+
++ memset(data, 0, sizeof(*data));
++
+ /* make sure only one bit is set in only one fid */
+ if (WARN_ONCE(hweight_long(fid1) + hweight_long(fid2) != 1,
+ "fid1=%x, fid2=%x\n", fid1, fid2))
+ return;
+
+- memset(data, 0, sizeof(*data));
+-
+ if (fid1) {
+ fifo_idx = ffs(fid1) - 1;
+ if (WARN_ONCE(fifo_idx >= MAX_NUM_LMAC, "fifo_idx=%d\n",
+@@ -1562,7 +1562,7 @@ iwl_dump_ini_dbgi_sram_iter(struct iwl_fw_runtime *fwrt,
+ prph_data = iwl_read_prph_no_grab(fwrt->trans, (i % 2) ?
+ DBGI_SRAM_TARGET_ACCESS_RDATA_MSB :
+ DBGI_SRAM_TARGET_ACCESS_RDATA_LSB);
+- if (prph_data == 0x5a5a5a5a) {
++ if ((prph_data & ~0xf) == 0xa5a5a5a0) {
+ iwl_trans_release_nic_access(fwrt->trans);
+ return -EBUSY;
+ }
+diff --git a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c
+index 43e997283db0f..607e07ed2477c 100644
+--- a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c
++++ b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c
+@@ -317,8 +317,10 @@ static void *iwl_dbgfs_fw_info_seq_next(struct seq_file *seq,
+ const struct iwl_fw *fw = priv->fwrt->fw;
+
+ *pos = ++state->pos;
+- if (*pos >= fw->ucode_capa.n_cmd_versions)
++ if (*pos >= fw->ucode_capa.n_cmd_versions) {
++ kfree(state);
+ return NULL;
++ }
+
+ return state;
+ }
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
+index 48e7376a5fea7..7ed4991f8dab9 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
+@@ -138,6 +138,12 @@ static int iwl_dbg_tlv_alloc_buf_alloc(struct iwl_trans *trans,
+ alloc_id != IWL_FW_INI_ALLOCATION_ID_DBGC1)
+ goto err;
+
++ if (buf_location == IWL_FW_INI_LOCATION_DRAM_PATH &&
++ alloc->req_size == 0) {
++ IWL_ERR(trans, "WRT: Invalid DRAM buffer allocation requested size (0)\n");
++ return -EINVAL;
++ }
++
+ trans->dbg.fw_mon_cfg[alloc_id] = *alloc;
+
+ return 0;
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-debug.c b/drivers/net/wireless/intel/iwlwifi/iwl-debug.c
+index ae4c2a3d63d5b..3a3c13a41fc61 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-debug.c
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-debug.c
+@@ -1,6 +1,6 @@
+ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+ /*
+- * Copyright (C) 2005-2011, 2021 Intel Corporation
++ * Copyright (C) 2005-2011, 2021-2022 Intel Corporation
+ */
+ #include <linux/device.h>
+ #include <linux/interrupt.h>
+@@ -57,6 +57,7 @@ void __iwl_err(struct device *dev, enum iwl_err_mode mode, const char *fmt, ...)
+ default:
+ break;
+ }
++ vaf.va = &args;
+ trace_iwlwifi_err(&vaf);
+ va_end(args);
+ }
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+index c5ad34b063df6..29f75948ab00c 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+@@ -563,6 +563,7 @@ static void iwl_mvm_wowlan_get_tkip_data(struct ieee80211_hw *hw,
+ }
+
+ for (i = 0; i < IWL_NUM_RSC; i++) {
++ ieee80211_get_key_rx_seq(key, i, &seq);
+ /* wrapping isn't allowed, AP must rekey */
+ if (seq.tkip.iv32 > cur_rx_iv32)
+ cur_rx_iv32 = seq.tkip.iv32;
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
+index 1ce9450e5add2..4071827d44757 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
+@@ -1745,6 +1745,11 @@ static ssize_t iwl_dbgfs_mem_read(struct file *file, char __user *user_buf,
+ if (ret < 0)
+ return ret;
+
++ if (iwl_rx_packet_payload_len(hcmd.resp_pkt) < sizeof(*rsp)) {
++ ret = -EIO;
++ goto out;
++ }
++
+ rsp = (void *)hcmd.resp_pkt->data;
+ if (le32_to_cpu(rsp->status) != DEBUG_MEM_STATUS_SUCCESS) {
+ ret = -ENXIO;
+@@ -1821,6 +1826,11 @@ static ssize_t iwl_dbgfs_mem_write(struct file *file,
+ if (ret < 0)
+ return ret;
+
++ if (iwl_rx_packet_payload_len(hcmd.resp_pkt) < sizeof(*rsp)) {
++ ret = -EIO;
++ goto out;
++ }
++
+ rsp = (void *)hcmd.resp_pkt->data;
+ if (rsp->status != DEBUG_MEM_STATUS_SUCCESS) {
+ ret = -ENXIO;
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+index 1d46a2b345eb3..a29e685aac4ff 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+@@ -5518,7 +5518,10 @@ static bool iwl_mvm_mac_can_aggregate(struct ieee80211_hw *hw,
+ {
+ struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
+
+- if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ)
++ if (mvm->trans->trans_cfg->device_family > IWL_DEVICE_FAMILY_BZ ||
++ (mvm->trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_BZ &&
++ !(CSR_HW_REV_TYPE(mvm->trans->hw_rev) == IWL_CFG_MAC_TYPE_GL &&
++ mvm->trans->hw_rev_step == SILICON_A_STEP)))
+ return iwl_mvm_tx_csum_bz(mvm, head, true) ==
+ iwl_mvm_tx_csum_bz(mvm, skb, true);
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c
+index 49ca1e168fc5b..eee98cebbb46a 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c
+@@ -384,9 +384,10 @@ void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi,
+ * Don't even try to decrypt a MCAST frame that was received
+ * before the managed vif is authorized, we'd fail anyway.
+ */
+- if (vif->type == NL80211_IFTYPE_STATION &&
++ if (is_multicast_ether_addr(hdr->addr1) &&
++ vif->type == NL80211_IFTYPE_STATION &&
+ !mvmvif->authorized &&
+- is_multicast_ether_addr(hdr->addr1)) {
++ ieee80211_has_protected(hdr->frame_control)) {
+ IWL_DEBUG_DROP(mvm, "MCAST before the vif is authorized\n");
+ kfree_skb(skb);
+ rcu_read_unlock();
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+index 97b67270f3847..a5356c0d91953 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+@@ -193,8 +193,7 @@ static int iwl_mvm_create_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
+ * Starting from Bz hardware, it calculates starting directly after
+ * the MAC header, so that matches mac80211's expectation.
+ */
+- if (skb->ip_summed == CHECKSUM_COMPLETE &&
+- mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_BZ) {
++ if (skb->ip_summed == CHECKSUM_COMPLETE) {
+ struct {
+ u8 hdr[6];
+ __be16 type;
+@@ -209,7 +208,7 @@ static int iwl_mvm_create_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
+ shdr->type != htons(ETH_P_PAE) &&
+ shdr->type != htons(ETH_P_TDLS))))
+ skb->ip_summed = CHECKSUM_NONE;
+- else
++ else if (mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_BZ)
+ /* mac80211 assumes full CSUM including SNAP header */
+ skb_postpush_rcsum(skb, shdr, sizeof(*shdr));
+ }
+diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+index 99768d6a60322..a0bf19b18635c 100644
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+@@ -565,7 +565,6 @@ static const struct iwl_dev_info iwl_dev_info_table[] = {
+ IWL_DEV_INFO(0x43F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0, iwl_ax201_killer_1650i_name),
+ IWL_DEV_INFO(0x43F0, 0x2074, iwl_ax201_cfg_qu_hr, NULL),
+ IWL_DEV_INFO(0x43F0, 0x4070, iwl_ax201_cfg_qu_hr, NULL),
+- IWL_DEV_INFO(0x43F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0, iwl_ax201_killer_1650s_name),
+ IWL_DEV_INFO(0xA0F0, 0x0070, iwl_ax201_cfg_qu_hr, NULL),
+ IWL_DEV_INFO(0xA0F0, 0x0074, iwl_ax201_cfg_qu_hr, NULL),
+ IWL_DEV_INFO(0xA0F0, 0x0078, iwl_ax201_cfg_qu_hr, NULL),
+diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+index 0a9af1ad1f206..171b6bf4a65a0 100644
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+@@ -599,7 +599,6 @@ static int iwl_pcie_set_hw_ready(struct iwl_trans *trans)
+ int iwl_pcie_prepare_card_hw(struct iwl_trans *trans)
+ {
+ int ret;
+- int t = 0;
+ int iter;
+
+ IWL_DEBUG_INFO(trans, "iwl_trans_prepare_card_hw enter\n");
+@@ -616,6 +615,8 @@ int iwl_pcie_prepare_card_hw(struct iwl_trans *trans)
+ usleep_range(1000, 2000);
+
+ for (iter = 0; iter < 10; iter++) {
++ int t = 0;
++
+ /* If HW is not ready, prepare the conditions to check again */
+ iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
+ CSR_HW_IF_CONFIG_REG_PREPARE);
+@@ -1522,19 +1523,16 @@ static int iwl_pcie_d3_handshake(struct iwl_trans *trans, bool suspend)
+ struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+ int ret;
+
+- if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_AX210) {
++ if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_AX210)
+ iwl_write_umac_prph(trans, UREG_DOORBELL_TO_ISR6,
+ suspend ? UREG_DOORBELL_TO_ISR6_SUSPEND :
+ UREG_DOORBELL_TO_ISR6_RESUME);
+- } else if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) {
++ else if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ)
+ iwl_write32(trans, CSR_IPC_SLEEP_CONTROL,
+ suspend ? CSR_IPC_SLEEP_CONTROL_SUSPEND :
+ CSR_IPC_SLEEP_CONTROL_RESUME);
+- iwl_write_umac_prph(trans, UREG_DOORBELL_TO_ISR6,
+- UREG_DOORBELL_TO_ISR6_SLEEP_CTRL);
+- } else {
++ else
+ return 0;
+- }
+
+ ret = wait_event_timeout(trans_pcie->sx_waitq,
+ trans_pcie->sx_complete, 2 * HZ);
+diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c
+index d147dc698c9db..4b6cb3aee8487 100644
+--- a/drivers/net/wireless/mediatek/mt76/dma.c
++++ b/drivers/net/wireless/mediatek/mt76/dma.c
+@@ -577,7 +577,9 @@ free:
+ free_skb:
+ status.skb = tx_info.skb;
+ hw = mt76_tx_status_get_hw(dev, tx_info.skb);
++ spin_lock_bh(&dev->rx_lock);
+ ieee80211_tx_status_ext(hw, &status);
++ spin_unlock_bh(&dev->rx_lock);
+
+ return ret;
+ }
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
+index d8216243b0224..1fc2fe61ef773 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76.h
++++ b/drivers/net/wireless/mediatek/mt76/mt76.h
+@@ -908,10 +908,11 @@ bool __mt76_poll(struct mt76_dev *dev, u32 offset, u32 mask, u32 val,
+
+ #define mt76_poll(dev, ...) __mt76_poll(&((dev)->mt76), __VA_ARGS__)
+
+-bool __mt76_poll_msec(struct mt76_dev *dev, u32 offset, u32 mask, u32 val,
+- int timeout);
+-
+-#define mt76_poll_msec(dev, ...) __mt76_poll_msec(&((dev)->mt76), __VA_ARGS__)
++bool ____mt76_poll_msec(struct mt76_dev *dev, u32 offset, u32 mask, u32 val,
++ int timeout, int kick);
++#define __mt76_poll_msec(...) ____mt76_poll_msec(__VA_ARGS__, 10)
++#define mt76_poll_msec(dev, ...) ____mt76_poll_msec(&((dev)->mt76), __VA_ARGS__, 10)
++#define mt76_poll_msec_tick(dev, ...) ____mt76_poll_msec(&((dev)->mt76), __VA_ARGS__)
+
+ void mt76_mmio_init(struct mt76_dev *dev, void __iomem *regs);
+ void mt76_pci_disable_aspm(struct pci_dev *pdev);
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
+index 70a7f84af0282..12e0af52082a6 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
+@@ -1279,8 +1279,11 @@ void mt7603_mac_add_txs(struct mt7603_dev *dev, void *data)
+ if (wcidx >= MT7603_WTBL_STA || !sta)
+ goto out;
+
+- if (mt7603_fill_txs(dev, msta, &info, txs_data))
++ if (mt7603_fill_txs(dev, msta, &info, txs_data)) {
++ spin_lock_bh(&dev->mt76.rx_lock);
+ ieee80211_tx_status_noskb(mt76_hw(dev), sta, &info);
++ spin_unlock_bh(&dev->mt76.rx_lock);
++ }
+
+ out:
+ rcu_read_unlock();
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
+index 51a968a6afdc9..eafa0f204c1f8 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
+@@ -1530,8 +1530,11 @@ static void mt7615_mac_add_txs(struct mt7615_dev *dev, void *data)
+ if (wcid->phy_idx && dev->mt76.phys[MT_BAND1])
+ mphy = dev->mt76.phys[MT_BAND1];
+
+- if (mt7615_fill_txs(dev, msta, &info, txs_data))
++ if (mt7615_fill_txs(dev, msta, &info, txs_data)) {
++ spin_lock_bh(&dev->mt76.rx_lock);
+ ieee80211_tx_status_noskb(mphy->hw, sta, &info);
++ spin_unlock_bh(&dev->mt76.rx_lock);
++ }
+
+ out:
+ rcu_read_unlock();
+@@ -2352,7 +2355,7 @@ void mt7615_coredump_work(struct work_struct *work)
+ break;
+
+ skb_pull(skb, sizeof(struct mt7615_mcu_rxd));
+- if (data + skb->len - dump > MT76_CONNAC_COREDUMP_SZ) {
++ if (!dump || data + skb->len - dump > MT76_CONNAC_COREDUMP_SZ) {
+ dev_kfree_skb(skb);
+ continue;
+ }
+@@ -2362,6 +2365,8 @@ void mt7615_coredump_work(struct work_struct *work)
+
+ dev_kfree_skb(skb);
+ }
+- dev_coredumpv(dev->mt76.dev, dump, MT76_CONNAC_COREDUMP_SZ,
+- GFP_KERNEL);
++
++ if (dump)
++ dev_coredumpv(dev->mt76.dev, dump, MT76_CONNAC_COREDUMP_SZ,
++ GFP_KERNEL);
+ }
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
+index aed4ee95fb2ec..82aac0a04655f 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
+@@ -537,7 +537,8 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi,
+ if (txwi[2] & cpu_to_le32(MT_TXD2_FIX_RATE)) {
+ /* Fixed rata is available just for 802.11 txd */
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+- bool multicast = is_multicast_ether_addr(hdr->addr1);
++ bool multicast = ieee80211_is_data(hdr->frame_control) &&
++ is_multicast_ether_addr(hdr->addr1);
+ u16 rate = mt76_connac2_mac_tx_rate_val(mphy, vif, beacon,
+ multicast);
+ u32 val = MT_TXD6_FIXED_BW;
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
+index d106cbfc387c8..b678820ba6327 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
+@@ -1632,8 +1632,16 @@ int mt76_connac_mcu_hw_scan(struct mt76_phy *phy, struct ieee80211_vif *vif,
+ req->channel_min_dwell_time = cpu_to_le16(duration);
+ req->channel_dwell_time = cpu_to_le16(duration);
+
+- req->channels_num = min_t(u8, sreq->n_channels, 32);
+- req->ext_channels_num = min_t(u8, ext_channels_num, 32);
++ if (sreq->n_channels == 0 || sreq->n_channels > 64) {
++ req->channel_type = 0;
++ req->channels_num = 0;
++ req->ext_channels_num = 0;
++ } else {
++ req->channel_type = 4;
++ req->channels_num = min_t(u8, sreq->n_channels, 32);
++ req->ext_channels_num = min_t(u8, ext_channels_num, 32);
++ }
++
+ for (i = 0; i < req->channels_num + req->ext_channels_num; i++) {
+ if (i >= 32)
+ chan = &req->ext_channels[i - 32];
+@@ -1653,7 +1661,6 @@ int mt76_connac_mcu_hw_scan(struct mt76_phy *phy, struct ieee80211_vif *vif,
+ }
+ chan->channel_num = scan_list[i]->hw_value;
+ }
+- req->channel_type = sreq->n_channels ? 4 : 0;
+
+ if (sreq->ie_len > 0) {
+ memcpy(req->ies, sreq->ie, sreq->ie_len);
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
+index 82fdf6d794bcf..3c7c369d997ad 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
++++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
+@@ -962,9 +962,6 @@ enum {
+ DEV_INFO_MAX_NUM
+ };
+
+-#define MCU_UNI_CMD_EVENT BIT(1)
+-#define MCU_UNI_CMD_UNSOLICITED_EVENT BIT(2)
+-
+ /* event table */
+ enum {
+ MCU_EVENT_TARGET_ADDRESS_LEN = 0x01,
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+index d3f74473e6fb0..3e41d809ade39 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+@@ -631,8 +631,11 @@ void mt76x02_send_tx_status(struct mt76x02_dev *dev,
+
+ mt76_tx_status_unlock(mdev, &list);
+
+- if (!status.skb)
++ if (!status.skb) {
++ spin_lock_bh(&dev->mt76.rx_lock);
+ ieee80211_tx_status_ext(mt76_hw(dev), &status);
++ spin_unlock_bh(&dev->mt76.rx_lock);
++ }
+
+ if (!len)
+ goto out;
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
+index a80ae31e7abff..0d8bc7b06a46b 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
+@@ -90,6 +90,7 @@ static ssize_t mt7915_thermal_temp_store(struct device *dev,
+ val < phy->throttle_temp[MT7915_CRIT_TEMP_IDX])) {
+ dev_err(phy->dev->mt76.dev,
+ "temp1_max shall be greater than temp1_crit.");
++ mutex_unlock(&phy->dev->mt76.mutex);
+ return -EINVAL;
+ }
+
+@@ -145,8 +146,11 @@ mt7915_thermal_set_cur_throttle_state(struct thermal_cooling_device *cdev,
+ u8 throttling = MT7915_THERMAL_THROTTLE_MAX - state;
+ int ret;
+
+- if (state > MT7915_CDEV_THROTTLE_MAX)
++ if (state > MT7915_CDEV_THROTTLE_MAX) {
++ dev_err(phy->dev->mt76.dev,
++ "please specify a valid throttling state\n");
+ return -EINVAL;
++ }
+
+ if (state == phy->cdev_state)
+ return 0;
+@@ -175,7 +179,7 @@ static void mt7915_unregister_thermal(struct mt7915_phy *phy)
+ struct wiphy *wiphy = phy->mt76->hw->wiphy;
+
+ if (!phy->cdev)
+- return;
++ return;
+
+ sysfs_remove_link(&wiphy->dev.kobj, "cooling_device");
+ thermal_cooling_device_unregister(phy->cdev);
+@@ -200,6 +204,10 @@ static int mt7915_thermal_init(struct mt7915_phy *phy)
+ phy->cdev = cdev;
+ }
+
++ /* initialize critical/maximum high temperature */
++ phy->throttle_temp[MT7915_CRIT_TEMP_IDX] = MT7915_CRIT_TEMP;
++ phy->throttle_temp[MT7915_MAX_TEMP_IDX] = MT7915_MAX_TEMP;
++
+ if (!IS_REACHABLE(CONFIG_HWMON))
+ return 0;
+
+@@ -208,10 +216,6 @@ static int mt7915_thermal_init(struct mt7915_phy *phy)
+ if (IS_ERR(hwmon))
+ return PTR_ERR(hwmon);
+
+- /* initialize critical/maximum high temperature */
+- phy->throttle_temp[MT7915_CRIT_TEMP_IDX] = 110;
+- phy->throttle_temp[MT7915_MAX_TEMP_IDX] = 120;
+-
+ return 0;
+ }
+
+@@ -1111,7 +1115,6 @@ static void mt7915_stop_hardware(struct mt7915_dev *dev)
+ mt7986_wmac_disable(dev);
+ }
+
+-
+ int mt7915_register_device(struct mt7915_dev *dev)
+ {
+ struct ieee80211_hw *hw = mt76_hw(dev);
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+index e58650bbbd14a..942d70c538254 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+@@ -72,6 +72,8 @@
+
+ #define MT7915_CRIT_TEMP_IDX 0
+ #define MT7915_MAX_TEMP_IDX 1
++#define MT7915_CRIT_TEMP 110
++#define MT7915_MAX_TEMP 120
+
+ struct mt7915_vif;
+ struct mt7915_sta;
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/soc.c b/drivers/net/wireless/mediatek/mt76/mt7915/soc.c
+index 686c9bbd59293..7303b690a64dc 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/soc.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/soc.c
+@@ -1237,6 +1237,8 @@ static const struct of_device_id mt7986_wmac_of_match[] = {
+ {},
+ };
+
++MODULE_DEVICE_TABLE(of, mt7986_wmac_of_match);
++
+ struct platform_driver mt7986_wmac_driver = {
+ .driver = {
+ .name = "mt7986-wmac",
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c
+index d1f10f6d9adc3..fd57c87a29ae3 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c
+@@ -66,6 +66,24 @@ static void mt7921_dma_prefetch(struct mt7921_dev *dev)
+
+ static int mt7921_dma_disable(struct mt7921_dev *dev, bool force)
+ {
++ /* disable WFDMA0 */
++ mt76_clear(dev, MT_WFDMA0_GLO_CFG,
++ MT_WFDMA0_GLO_CFG_TX_DMA_EN | MT_WFDMA0_GLO_CFG_RX_DMA_EN |
++ MT_WFDMA0_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN |
++ MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
++ MT_WFDMA0_GLO_CFG_OMIT_RX_INFO |
++ MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
++
++ if (!mt76_poll_msec_tick(dev, MT_WFDMA0_GLO_CFG,
++ MT_WFDMA0_GLO_CFG_TX_DMA_BUSY |
++ MT_WFDMA0_GLO_CFG_RX_DMA_BUSY, 0, 100, 1))
++ return -ETIMEDOUT;
++
++ /* disable dmashdl */
++ mt76_clear(dev, MT_WFDMA0_GLO_CFG_EXT0,
++ MT_WFDMA0_CSR_TX_DMASHDL_ENABLE);
++ mt76_set(dev, MT_DMASHDL_SW_CONTROL, MT_DMASHDL_DMASHDL_BYPASS);
++
+ if (force) {
+ /* reset */
+ mt76_clear(dev, MT_WFDMA0_RST,
+@@ -77,24 +95,6 @@ static int mt7921_dma_disable(struct mt7921_dev *dev, bool force)
+ MT_WFDMA0_RST_LOGIC_RST);
+ }
+
+- /* disable dmashdl */
+- mt76_clear(dev, MT_WFDMA0_GLO_CFG_EXT0,
+- MT_WFDMA0_CSR_TX_DMASHDL_ENABLE);
+- mt76_set(dev, MT_DMASHDL_SW_CONTROL, MT_DMASHDL_DMASHDL_BYPASS);
+-
+- /* disable WFDMA0 */
+- mt76_clear(dev, MT_WFDMA0_GLO_CFG,
+- MT_WFDMA0_GLO_CFG_TX_DMA_EN | MT_WFDMA0_GLO_CFG_RX_DMA_EN |
+- MT_WFDMA0_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN |
+- MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
+- MT_WFDMA0_GLO_CFG_OMIT_RX_INFO |
+- MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
+-
+- if (!mt76_poll(dev, MT_WFDMA0_GLO_CFG,
+- MT_WFDMA0_GLO_CFG_TX_DMA_BUSY |
+- MT_WFDMA0_GLO_CFG_RX_DMA_BUSY, 0, 1000))
+- return -ETIMEDOUT;
+-
+ return 0;
+ }
+
+@@ -301,6 +301,10 @@ void mt7921_dma_cleanup(struct mt7921_dev *dev)
+ MT_WFDMA0_GLO_CFG_OMIT_RX_INFO |
+ MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
+
++ mt76_poll_msec_tick(dev, MT_WFDMA0_GLO_CFG,
++ MT_WFDMA0_GLO_CFG_TX_DMA_BUSY |
++ MT_WFDMA0_GLO_CFG_RX_DMA_BUSY, 0, 100, 1);
++
+ /* reset */
+ mt76_clear(dev, MT_WFDMA0_RST,
+ MT_WFDMA0_RST_DMASHDL_ALL_RST |
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/init.c b/drivers/net/wireless/mediatek/mt76/mt7921/init.c
+index d4b681d7e1d22..f2c6ec4d8e2ee 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/init.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/init.c
+@@ -162,12 +162,12 @@ mt7921_mac_init_band(struct mt7921_dev *dev, u8 band)
+
+ u8 mt7921_check_offload_capability(struct device *dev, const char *fw_wm)
+ {
+- struct mt7921_fw_features *features = NULL;
+ const struct mt76_connac2_fw_trailer *hdr;
+ struct mt7921_realease_info *rel_info;
+ const struct firmware *fw;
+ int ret, i, offset = 0;
+ const u8 *data, *end;
++ u8 offload_caps = 0;
+
+ ret = request_firmware(&fw, fw_wm, dev);
+ if (ret)
+@@ -199,7 +199,10 @@ u8 mt7921_check_offload_capability(struct device *dev, const char *fw_wm)
+ data += sizeof(*rel_info);
+
+ if (rel_info->tag == MT7921_FW_TAG_FEATURE) {
++ struct mt7921_fw_features *features;
++
+ features = (struct mt7921_fw_features *)data;
++ offload_caps = features->data;
+ break;
+ }
+
+@@ -209,7 +212,7 @@ u8 mt7921_check_offload_capability(struct device *dev, const char *fw_wm)
+ out:
+ release_firmware(fw);
+
+- return features ? features->data : 0;
++ return offload_caps;
+ }
+ EXPORT_SYMBOL_GPL(mt7921_check_offload_capability);
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
+index 744382be36f8b..b2366efd74ea5 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
+@@ -1705,7 +1705,7 @@ static void mt7921_ctx_iter(void *priv, u8 *mac,
+ if (ctx != mvif->ctx)
+ return;
+
+- if (vif->type & NL80211_IFTYPE_MONITOR)
++ if (vif->type == NL80211_IFTYPE_MONITOR)
+ mt7921_mcu_config_sniffer(mvif, ctx);
+ else
+ mt76_connac_mcu_uni_set_chctx(mvif->phy->mt76, &mvif->mt76, ctx);
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
+index 7253ce90234ef..087a5dc2593db 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
+@@ -16,24 +16,6 @@ static bool mt7921_disable_clc;
+ module_param_named(disable_clc, mt7921_disable_clc, bool, 0644);
+ MODULE_PARM_DESC(disable_clc, "disable CLC support");
+
+-static int
+-mt7921_mcu_parse_eeprom(struct mt76_dev *dev, struct sk_buff *skb)
+-{
+- struct mt7921_mcu_eeprom_info *res;
+- u8 *buf;
+-
+- if (!skb)
+- return -EINVAL;
+-
+- skb_pull(skb, sizeof(struct mt76_connac2_mcu_rxd));
+-
+- res = (struct mt7921_mcu_eeprom_info *)skb->data;
+- buf = dev->eeprom.data + le32_to_cpu(res->addr);
+- memcpy(buf, res->data, 16);
+-
+- return 0;
+-}
+-
+ int mt7921_mcu_parse_response(struct mt76_dev *mdev, int cmd,
+ struct sk_buff *skb, int seq)
+ {
+@@ -60,8 +42,6 @@ int mt7921_mcu_parse_response(struct mt76_dev *mdev, int cmd,
+ } else if (cmd == MCU_EXT_CMD(THERMAL_CTRL)) {
+ skb_pull(skb, sizeof(*rxd) + 4);
+ ret = le32_to_cpu(*(__le32 *)skb->data);
+- } else if (cmd == MCU_EXT_CMD(EFUSE_ACCESS)) {
+- ret = mt7921_mcu_parse_eeprom(mdev, skb);
+ } else if (cmd == MCU_UNI_CMD(DEV_INFO_UPDATE) ||
+ cmd == MCU_UNI_CMD(BSS_INFO_UPDATE) ||
+ cmd == MCU_UNI_CMD(STA_REC_UPDATE) ||
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
+index 5c23c827abe47..aa4ecf008a3c9 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
+@@ -115,9 +115,10 @@ static void mt7921e_unregister_device(struct mt7921_dev *dev)
+ napi_disable(&dev->mt76.napi[i]);
+ cancel_delayed_work_sync(&pm->ps_work);
+ cancel_work_sync(&pm->wake_work);
++ cancel_work_sync(&dev->reset_work);
+
+ mt7921_tx_token_put(dev);
+- mt7921_mcu_drv_pmctrl(dev);
++ __mt7921_mcu_drv_pmctrl(dev);
+ mt7921_dma_cleanup(dev);
+ mt7921_wfsys_reset(dev);
+ skb_queue_purge(&dev->mt76.mcu.res_q);
+@@ -263,6 +264,7 @@ static int mt7921_pci_probe(struct pci_dev *pdev,
+ struct mt76_dev *mdev;
+ u8 features;
+ int ret;
++ u16 cmd;
+
+ ret = pcim_enable_device(pdev);
+ if (ret)
+@@ -272,6 +274,11 @@ static int mt7921_pci_probe(struct pci_dev *pdev,
+ if (ret)
+ return ret;
+
++ pci_read_config_word(pdev, PCI_COMMAND, &cmd);
++ if (!(cmd & PCI_COMMAND_MEMORY)) {
++ cmd |= PCI_COMMAND_MEMORY;
++ pci_write_config_word(pdev, PCI_COMMAND, cmd);
++ }
+ pci_set_master(pdev);
+
+ ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
+@@ -509,17 +516,7 @@ failed:
+
+ static void mt7921_pci_shutdown(struct pci_dev *pdev)
+ {
+- struct mt76_dev *mdev = pci_get_drvdata(pdev);
+- struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76);
+- struct mt76_connac_pm *pm = &dev->pm;
+-
+- cancel_delayed_work_sync(&pm->ps_work);
+- cancel_work_sync(&pm->wake_work);
+-
+- /* chip cleanup before reboot */
+- mt7921_mcu_drv_pmctrl(dev);
+- mt7921_dma_cleanup(dev);
+- mt7921_wfsys_reset(dev);
++ mt7921_pci_remove(pdev);
+ }
+
+ static DEFINE_SIMPLE_DEV_PM_OPS(mt7921_pm_ops, mt7921_pci_suspend, mt7921_pci_resume);
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/usb.c b/drivers/net/wireless/mediatek/mt76/mt7921/usb.c
+index 5321d20dcdcbf..363a170efdda9 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/usb.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/usb.c
+@@ -270,7 +270,7 @@ static int mt7921u_probe(struct usb_interface *usb_intf,
+
+ ret = mt7921u_dma_init(dev, false);
+ if (ret)
+- return ret;
++ goto error;
+
+ hw = mt76_hw(dev);
+ /* check hw sg support in order to enable AMSDU */
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/eeprom.h b/drivers/net/wireless/mediatek/mt76/mt7996/eeprom.h
+index 8da599e0abeac..cfc48698539b3 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7996/eeprom.h
++++ b/drivers/net/wireless/mediatek/mt76/mt7996/eeprom.h
+@@ -31,11 +31,11 @@ enum mt7996_eeprom_field {
+ #define MT_EE_WIFI_CONF2_BAND_SEL GENMASK(2, 0)
+
+ #define MT_EE_WIFI_CONF1_TX_PATH_BAND0 GENMASK(5, 3)
+-#define MT_EE_WIFI_CONF2_TX_PATH_BAND1 GENMASK(5, 3)
+-#define MT_EE_WIFI_CONF2_TX_PATH_BAND2 GENMASK(2, 0)
++#define MT_EE_WIFI_CONF2_TX_PATH_BAND1 GENMASK(2, 0)
++#define MT_EE_WIFI_CONF2_TX_PATH_BAND2 GENMASK(5, 3)
+ #define MT_EE_WIFI_CONF4_STREAM_NUM_BAND0 GENMASK(5, 3)
+-#define MT_EE_WIFI_CONF5_STREAM_NUM_BAND1 GENMASK(5, 3)
+-#define MT_EE_WIFI_CONF5_STREAM_NUM_BAND2 GENMASK(2, 0)
++#define MT_EE_WIFI_CONF5_STREAM_NUM_BAND1 GENMASK(2, 0)
++#define MT_EE_WIFI_CONF5_STREAM_NUM_BAND2 GENMASK(5, 3)
+
+ #define MT_EE_RATE_DELTA_MASK GENMASK(5, 0)
+ #define MT_EE_RATE_DELTA_SIGN BIT(6)
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
+index 0eb9e4d73f2c1..e643a27048f93 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
+@@ -253,12 +253,9 @@ mt7996_mac_decode_he_radiotap_ru(struct mt76_rx_status *status,
+ struct ieee80211_radiotap_he *he,
+ __le32 *rxv)
+ {
+- u32 ru_h, ru_l;
+- u8 ru, offs = 0;
++ u32 ru, offs = 0;
+
+- ru_l = le32_get_bits(rxv[0], MT_PRXV_HE_RU_ALLOC_L);
+- ru_h = le32_get_bits(rxv[1], MT_PRXV_HE_RU_ALLOC_H);
+- ru = (u8)(ru_l | ru_h << 4);
++ ru = le32_get_bits(rxv[0], MT_PRXV_HE_RU_ALLOC);
+
+ status->bw = RATE_INFO_BW_HE_RU;
+
+@@ -323,18 +320,23 @@ mt7996_mac_decode_he_mu_radiotap(struct sk_buff *skb, __le32 *rxv)
+
+ he_mu->flags2 |= MU_PREP(FLAGS2_BW_FROM_SIG_A_BW, status->bw) |
+ MU_PREP(FLAGS2_SIG_B_SYMS_USERS,
+- le32_get_bits(rxv[2], MT_CRXV_HE_NUM_USER));
++ le32_get_bits(rxv[4], MT_CRXV_HE_NUM_USER));
+
+- he_mu->ru_ch1[0] = le32_get_bits(rxv[3], MT_CRXV_HE_RU0);
++ he_mu->ru_ch1[0] = le32_get_bits(rxv[16], MT_CRXV_HE_RU0) & 0xff;
+
+ if (status->bw >= RATE_INFO_BW_40) {
+ he_mu->flags1 |= HE_BITS(MU_FLAGS1_CH2_RU_KNOWN);
+- he_mu->ru_ch2[0] = le32_get_bits(rxv[3], MT_CRXV_HE_RU1);
++ he_mu->ru_ch2[0] = le32_get_bits(rxv[16], MT_CRXV_HE_RU1) & 0xff;
+ }
+
+ if (status->bw >= RATE_INFO_BW_80) {
+- he_mu->ru_ch1[1] = le32_get_bits(rxv[3], MT_CRXV_HE_RU2);
+- he_mu->ru_ch2[1] = le32_get_bits(rxv[3], MT_CRXV_HE_RU3);
++ u32 ru_h, ru_l;
++
++ he_mu->ru_ch1[1] = le32_get_bits(rxv[16], MT_CRXV_HE_RU2) & 0xff;
++
++ ru_l = le32_get_bits(rxv[16], MT_CRXV_HE_RU3_L);
++ ru_h = le32_get_bits(rxv[17], MT_CRXV_HE_RU3_H) & 0x7;
++ he_mu->ru_ch2[1] = (u8)(ru_l | ru_h << 4);
+ }
+ }
+
+@@ -357,23 +359,23 @@ mt7996_mac_decode_he_radiotap(struct sk_buff *skb, __le32 *rxv, u8 mode)
+ HE_BITS(DATA2_TXOP_KNOWN),
+ };
+ struct ieee80211_radiotap_he *he = NULL;
+- u32 ltf_size = le32_get_bits(rxv[2], MT_CRXV_HE_LTF_SIZE) + 1;
++ u32 ltf_size = le32_get_bits(rxv[4], MT_CRXV_HE_LTF_SIZE) + 1;
+
+ status->flag |= RX_FLAG_RADIOTAP_HE;
+
+ he = skb_push(skb, sizeof(known));
+ memcpy(he, &known, sizeof(known));
+
+- he->data3 = HE_PREP(DATA3_BSS_COLOR, BSS_COLOR, rxv[14]) |
+- HE_PREP(DATA3_LDPC_XSYMSEG, LDPC_EXT_SYM, rxv[2]);
+- he->data4 = HE_PREP(DATA4_SU_MU_SPTL_REUSE, SR_MASK, rxv[11]);
+- he->data5 = HE_PREP(DATA5_PE_DISAMBIG, PE_DISAMBIG, rxv[2]) |
++ he->data3 = HE_PREP(DATA3_BSS_COLOR, BSS_COLOR, rxv[9]) |
++ HE_PREP(DATA3_LDPC_XSYMSEG, LDPC_EXT_SYM, rxv[4]);
++ he->data4 = HE_PREP(DATA4_SU_MU_SPTL_REUSE, SR_MASK, rxv[13]);
++ he->data5 = HE_PREP(DATA5_PE_DISAMBIG, PE_DISAMBIG, rxv[5]) |
+ le16_encode_bits(ltf_size,
+ IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE);
+ if (le32_to_cpu(rxv[0]) & MT_PRXV_TXBF)
+ he->data5 |= HE_BITS(DATA5_TXBF);
+- he->data6 = HE_PREP(DATA6_TXOP, TXOP_DUR, rxv[14]) |
+- HE_PREP(DATA6_DOPPLER, DOPPLER, rxv[14]);
++ he->data6 = HE_PREP(DATA6_TXOP, TXOP_DUR, rxv[9]) |
++ HE_PREP(DATA6_DOPPLER, DOPPLER, rxv[9]);
+
+ switch (mode) {
+ case MT_PHY_TYPE_HE_SU:
+@@ -382,22 +384,22 @@ mt7996_mac_decode_he_radiotap(struct sk_buff *skb, __le32 *rxv, u8 mode)
+ HE_BITS(DATA1_BEAM_CHANGE_KNOWN) |
+ HE_BITS(DATA1_BW_RU_ALLOC_KNOWN);
+
+- he->data3 |= HE_PREP(DATA3_BEAM_CHANGE, BEAM_CHNG, rxv[14]) |
+- HE_PREP(DATA3_UL_DL, UPLINK, rxv[2]);
++ he->data3 |= HE_PREP(DATA3_BEAM_CHANGE, BEAM_CHNG, rxv[8]) |
++ HE_PREP(DATA3_UL_DL, UPLINK, rxv[5]);
+ break;
+ case MT_PHY_TYPE_HE_EXT_SU:
+ he->data1 |= HE_BITS(DATA1_FORMAT_EXT_SU) |
+ HE_BITS(DATA1_UL_DL_KNOWN) |
+ HE_BITS(DATA1_BW_RU_ALLOC_KNOWN);
+
+- he->data3 |= HE_PREP(DATA3_UL_DL, UPLINK, rxv[2]);
++ he->data3 |= HE_PREP(DATA3_UL_DL, UPLINK, rxv[5]);
+ break;
+ case MT_PHY_TYPE_HE_MU:
+ he->data1 |= HE_BITS(DATA1_FORMAT_MU) |
+ HE_BITS(DATA1_UL_DL_KNOWN);
+
+- he->data3 |= HE_PREP(DATA3_UL_DL, UPLINK, rxv[2]);
+- he->data4 |= HE_PREP(DATA4_MU_STA_ID, MU_AID, rxv[7]);
++ he->data3 |= HE_PREP(DATA3_UL_DL, UPLINK, rxv[5]);
++ he->data4 |= HE_PREP(DATA4_MU_STA_ID, MU_AID, rxv[8]);
+
+ mt7996_mac_decode_he_radiotap_ru(status, he, rxv);
+ mt7996_mac_decode_he_mu_radiotap(skb, rxv);
+@@ -408,10 +410,10 @@ mt7996_mac_decode_he_radiotap(struct sk_buff *skb, __le32 *rxv, u8 mode)
+ HE_BITS(DATA1_SPTL_REUSE3_KNOWN) |
+ HE_BITS(DATA1_SPTL_REUSE4_KNOWN);
+
+- he->data4 |= HE_PREP(DATA4_TB_SPTL_REUSE1, SR_MASK, rxv[11]) |
+- HE_PREP(DATA4_TB_SPTL_REUSE2, SR1_MASK, rxv[11]) |
+- HE_PREP(DATA4_TB_SPTL_REUSE3, SR2_MASK, rxv[11]) |
+- HE_PREP(DATA4_TB_SPTL_REUSE4, SR3_MASK, rxv[11]);
++ he->data4 |= HE_PREP(DATA4_TB_SPTL_REUSE1, SR_MASK, rxv[13]) |
++ HE_PREP(DATA4_TB_SPTL_REUSE2, SR1_MASK, rxv[13]) |
++ HE_PREP(DATA4_TB_SPTL_REUSE3, SR2_MASK, rxv[13]) |
++ HE_PREP(DATA4_TB_SPTL_REUSE4, SR3_MASK, rxv[13]);
+
+ mt7996_mac_decode_he_radiotap_ru(status, he, rxv);
+ break;
+@@ -960,8 +962,9 @@ mt7996_mac_write_txwi_80211(struct mt7996_dev *dev, __le32 *txwi,
+ }
+
+ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
+- struct sk_buff *skb, struct mt76_wcid *wcid, int pid,
+- struct ieee80211_key_conf *key, u32 changed)
++ struct sk_buff *skb, struct mt76_wcid *wcid,
++ struct ieee80211_key_conf *key, int pid,
++ enum mt76_txq_id qid, u32 changed)
+ {
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_vif *vif = info->control.vif;
+@@ -992,7 +995,7 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
+ } else if (beacon) {
+ p_fmt = MT_TX_TYPE_FW;
+ q_idx = MT_LMAC_BCN0;
+- } else if (skb_get_queue_mapping(skb) >= MT_TXQ_PSD) {
++ } else if (qid >= MT_TXQ_PSD) {
+ p_fmt = MT_TX_TYPE_CT;
+ q_idx = MT_LMAC_ALTX0;
+ } else {
+@@ -1069,8 +1072,8 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_info->skb);
+ struct ieee80211_key_conf *key = info->control.hw_key;
+ struct ieee80211_vif *vif = info->control.vif;
++ struct mt76_connac_txp_common *txp;
+ struct mt76_txwi_cache *t;
+- struct mt7996_txp *txp;
+ int id, i, pid, nbuf = tx_info->nbuf - 1;
+ bool is_8023 = info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP;
+ u8 *txwi = (u8 *)txwi_ptr;
+@@ -1098,41 +1101,36 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
+ return id;
+
+ pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);
+- memset(txwi_ptr, 0, MT_TXD_SIZE);
+- /* Transmit non qos data by 802.11 header and need to fill txd by host*/
+- if (!is_8023 || pid >= MT_PACKET_ID_FIRST)
+- mt7996_mac_write_txwi(dev, txwi_ptr, tx_info->skb, wcid, pid,
+- key, 0);
++ mt7996_mac_write_txwi(dev, txwi_ptr, tx_info->skb, wcid, key,
++ pid, qid, 0);
+
+- txp = (struct mt7996_txp *)(txwi + MT_TXD_SIZE);
++ txp = (struct mt76_connac_txp_common *)(txwi + MT_TXD_SIZE);
+ for (i = 0; i < nbuf; i++) {
+- txp->buf[i] = cpu_to_le32(tx_info->buf[i + 1].addr);
+- txp->len[i] = cpu_to_le16(tx_info->buf[i + 1].len);
++ txp->fw.buf[i] = cpu_to_le32(tx_info->buf[i + 1].addr);
++ txp->fw.len[i] = cpu_to_le16(tx_info->buf[i + 1].len);
+ }
+- txp->nbuf = nbuf;
+-
+- txp->flags = cpu_to_le16(MT_CT_INFO_FROM_HOST);
++ txp->fw.nbuf = nbuf;
+
+- if (!is_8023 || pid >= MT_PACKET_ID_FIRST)
+- txp->flags |= cpu_to_le16(MT_CT_INFO_APPLY_TXD);
++ txp->fw.flags =
++ cpu_to_le16(MT_CT_INFO_FROM_HOST | MT_CT_INFO_APPLY_TXD);
+
+ if (!key)
+- txp->flags |= cpu_to_le16(MT_CT_INFO_NONE_CIPHER_FRAME);
++ txp->fw.flags |= cpu_to_le16(MT_CT_INFO_NONE_CIPHER_FRAME);
+
+ if (!is_8023 && ieee80211_is_mgmt(hdr->frame_control))
+- txp->flags |= cpu_to_le16(MT_CT_INFO_MGMT_FRAME);
++ txp->fw.flags |= cpu_to_le16(MT_CT_INFO_MGMT_FRAME);
+
+ if (vif) {
+ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
+
+- txp->bss_idx = mvif->mt76.idx;
++ txp->fw.bss_idx = mvif->mt76.idx;
+ }
+
+- txp->token = cpu_to_le16(id);
++ txp->fw.token = cpu_to_le16(id);
+ if (test_bit(MT_WCID_FLAG_4ADDR, &wcid->flags))
+- txp->rept_wds_wcid = cpu_to_le16(wcid->idx);
++ txp->fw.rept_wds_wcid = cpu_to_le16(wcid->idx);
+ else
+- txp->rept_wds_wcid = cpu_to_le16(0xfff);
++ txp->fw.rept_wds_wcid = cpu_to_le16(0xfff);
+ tx_info->skb = DMA_DUMMY_DATA;
+
+ /* pass partial skb header to fw */
+@@ -1171,13 +1169,13 @@ mt7996_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi)
+ static void
+ mt7996_txp_skb_unmap(struct mt76_dev *dev, struct mt76_txwi_cache *t)
+ {
+- struct mt7996_txp *txp;
++ struct mt76_connac_txp_common *txp;
+ int i;
+
+ txp = mt7996_txwi_to_txp(dev, t);
+- for (i = 0; i < txp->nbuf; i++)
+- dma_unmap_single(dev->dev, le32_to_cpu(txp->buf[i]),
+- le16_to_cpu(txp->len[i]), DMA_TO_DEVICE);
++ for (i = 0; i < txp->fw.nbuf; i++)
++ dma_unmap_single(dev->dev, le32_to_cpu(txp->fw.buf[i]),
++ le16_to_cpu(txp->fw.len[i]), DMA_TO_DEVICE);
+ }
+
+ static void
+@@ -1554,11 +1552,11 @@ void mt7996_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue_entry *e)
+
+ /* error path */
+ if (e->skb == DMA_DUMMY_DATA) {
++ struct mt76_connac_txp_common *txp;
+ struct mt76_txwi_cache *t;
+- struct mt7996_txp *txp;
+
+ txp = mt7996_txwi_to_txp(mdev, e->txwi);
+- t = mt76_token_put(mdev, le16_to_cpu(txp->token));
++ t = mt76_token_put(mdev, le16_to_cpu(txp->fw.token));
+ e->skb = t ? t->skb : NULL;
+ }
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.h b/drivers/net/wireless/mediatek/mt76/mt7996/mac.h
+index 9f68852012b9e..1404ded52104a 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.h
++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.h
+@@ -102,8 +102,7 @@ enum rx_pkt_type {
+ #define MT_PRXV_NSTS GENMASK(10, 7)
+ #define MT_PRXV_TXBF BIT(11)
+ #define MT_PRXV_HT_AD_CODE BIT(12)
+-#define MT_PRXV_HE_RU_ALLOC_L GENMASK(31, 28)
+-#define MT_PRXV_HE_RU_ALLOC_H GENMASK(3, 0)
++#define MT_PRXV_HE_RU_ALLOC GENMASK(30, 22)
+ #define MT_PRXV_RCPI3 GENMASK(31, 24)
+ #define MT_PRXV_RCPI2 GENMASK(23, 16)
+ #define MT_PRXV_RCPI1 GENMASK(15, 8)
+@@ -113,34 +112,32 @@ enum rx_pkt_type {
+ #define MT_PRXV_TX_MODE GENMASK(14, 11)
+ #define MT_PRXV_FRAME_MODE GENMASK(2, 0)
+ #define MT_PRXV_DCM BIT(5)
+-#define MT_PRXV_NUM_RX BIT(8, 6)
+
+ /* C-RXV */
+-#define MT_CRXV_HT_STBC GENMASK(1, 0)
+-#define MT_CRXV_TX_MODE GENMASK(7, 4)
+-#define MT_CRXV_FRAME_MODE GENMASK(10, 8)
+-#define MT_CRXV_HT_SHORT_GI GENMASK(14, 13)
+-#define MT_CRXV_HE_LTF_SIZE GENMASK(18, 17)
+-#define MT_CRXV_HE_LDPC_EXT_SYM BIT(20)
+-#define MT_CRXV_HE_PE_DISAMBIG BIT(23)
+-#define MT_CRXV_HE_NUM_USER GENMASK(30, 24)
+-#define MT_CRXV_HE_UPLINK BIT(31)
+-#define MT_CRXV_HE_RU0 GENMASK(7, 0)
+-#define MT_CRXV_HE_RU1 GENMASK(15, 8)
+-#define MT_CRXV_HE_RU2 GENMASK(23, 16)
+-#define MT_CRXV_HE_RU3 GENMASK(31, 24)
+-
+-#define MT_CRXV_HE_MU_AID GENMASK(30, 20)
++#define MT_CRXV_HE_NUM_USER GENMASK(26, 20)
++#define MT_CRXV_HE_LTF_SIZE GENMASK(28, 27)
++#define MT_CRXV_HE_LDPC_EXT_SYM BIT(30)
++
++#define MT_CRXV_HE_PE_DISAMBIG BIT(1)
++#define MT_CRXV_HE_UPLINK BIT(2)
++
++#define MT_CRXV_HE_MU_AID GENMASK(27, 17)
++#define MT_CRXV_HE_BEAM_CHNG BIT(29)
++
++#define MT_CRXV_HE_DOPPLER BIT(0)
++#define MT_CRXV_HE_BSS_COLOR GENMASK(15, 10)
++#define MT_CRXV_HE_TXOP_DUR GENMASK(19, 17)
+
+ #define MT_CRXV_HE_SR_MASK GENMASK(11, 8)
+ #define MT_CRXV_HE_SR1_MASK GENMASK(16, 12)
+ #define MT_CRXV_HE_SR2_MASK GENMASK(20, 17)
+ #define MT_CRXV_HE_SR3_MASK GENMASK(24, 21)
+
+-#define MT_CRXV_HE_BSS_COLOR GENMASK(5, 0)
+-#define MT_CRXV_HE_TXOP_DUR GENMASK(12, 6)
+-#define MT_CRXV_HE_BEAM_CHNG BIT(13)
+-#define MT_CRXV_HE_DOPPLER BIT(16)
++#define MT_CRXV_HE_RU0 GENMASK(8, 0)
++#define MT_CRXV_HE_RU1 GENMASK(17, 9)
++#define MT_CRXV_HE_RU2 GENMASK(26, 18)
++#define MT_CRXV_HE_RU3_L GENMASK(31, 27)
++#define MT_CRXV_HE_RU3_H GENMASK(3, 0)
+
+ enum tx_header_format {
+ MT_HDR_FORMAT_802_3,
+@@ -268,17 +265,6 @@ enum tx_mgnt_type {
+ /* VHT/HE only use bits 0-3 */
+ #define MT_TX_RATE_IDX GENMASK(5, 0)
+
+-struct mt7996_txp {
+- __le16 flags;
+- __le16 token;
+- u8 bss_idx;
+- __le16 rept_wds_wcid;
+- u8 nbuf;
+-#define MT_TXP_MAX_BUF_NUM 6
+- __le32 buf[MT_TXP_MAX_BUF_NUM];
+- __le16 len[MT_TXP_MAX_BUF_NUM];
+-} __packed __aligned(4);
+-
+ #define MT_TXFREE0_PKT_TYPE GENMASK(31, 27)
+ #define MT_TXFREE0_MSDU_CNT GENMASK(25, 16)
+ #define MT_TXFREE0_RX_BYTE GENMASK(15, 0)
+@@ -382,7 +368,7 @@ struct mt7996_dfs_radar_spec {
+ struct mt7996_dfs_pattern radar_pattern[16];
+ };
+
+-static inline struct mt7996_txp *
++static inline struct mt76_connac_txp_common *
+ mt7996_txwi_to_txp(struct mt76_dev *dev, struct mt76_txwi_cache *t)
+ {
+ u8 *txwi;
+@@ -392,7 +378,7 @@ mt7996_txwi_to_txp(struct mt76_dev *dev, struct mt76_txwi_cache *t)
+
+ txwi = mt76_get_txwi_ptr(dev, t);
+
+- return (struct mt7996_txp *)(txwi + MT_TXD_SIZE);
++ return (struct mt76_connac_txp_common *)(txwi + MT_TXD_SIZE);
+ }
+
+ #endif
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
+index d593ed9e3f73c..c8c332ed8a402 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
+@@ -421,7 +421,8 @@ mt7996_mcu_ie_countdown(struct mt7996_dev *dev, struct sk_buff *skb)
+ if (hdr->band && dev->mt76.phys[hdr->band])
+ mphy = dev->mt76.phys[hdr->band];
+
+- tail = skb->data + le16_to_cpu(rxd->len);
++ tail = skb->data + skb->len;
++ data += sizeof(struct header);
+ while (data + sizeof(struct tlv) < tail && le16_to_cpu(tlv->len)) {
+ switch (le16_to_cpu(tlv->tag)) {
+ case UNI_EVENT_IE_COUNTDOWN_CSA:
+@@ -1804,8 +1805,9 @@ mt7996_mcu_beacon_cont(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+ }
+
+ buf = (u8 *)bcn + sizeof(*bcn) - MAX_BEACON_SIZE;
+- mt7996_mac_write_txwi(dev, (__le32 *)buf, skb, wcid, 0, NULL,
++ mt7996_mac_write_txwi(dev, (__le32 *)buf, skb, wcid, NULL, 0, 0,
+ BSS_CHANGED_BEACON);
++
+ memcpy(buf + MT_TXD_SIZE, skb->data, skb->len);
+ }
+
+@@ -1995,8 +1997,7 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev,
+
+ buf = (u8 *)tlv + sizeof(*discov) - MAX_INBAND_FRAME_SIZE;
+
+- mt7996_mac_write_txwi(dev, (__le32 *)buf, skb, wcid, 0, NULL,
+- changed);
++ mt7996_mac_write_txwi(dev, (__le32 *)buf, skb, wcid, NULL, 0, 0, changed);
+
+ memcpy(buf + MT_TXD_SIZE, skb->data, skb->len);
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mmio.c b/drivers/net/wireless/mediatek/mt76/mt7996/mmio.c
+index d8a2c1a744b25..2237f50adbc71 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7996/mmio.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mmio.c
+@@ -318,7 +318,7 @@ struct mt7996_dev *mt7996_mmio_probe(struct device *pdev,
+ {
+ static const struct mt76_driver_ops drv_ops = {
+ /* txwi_size = txd size + txp size */
+- .txwi_size = MT_TXD_SIZE + sizeof(struct mt7996_txp),
++ .txwi_size = MT_TXD_SIZE + sizeof(struct mt76_connac_fw_txp),
+ .drv_flags = MT_DRV_TXWI_NO_FREE |
+ MT_DRV_HW_MGMT_TXQ,
+ .survey_flags = SURVEY_INFO_TIME_TX |
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
+index 725344791b4cd..e8eedae78479f 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
+@@ -472,8 +472,9 @@ void mt7996_mac_enable_nf(struct mt7996_dev *dev, u8 band);
+ void mt7996_mac_enable_rtscts(struct mt7996_dev *dev,
+ struct ieee80211_vif *vif, bool enable);
+ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
+- struct sk_buff *skb, struct mt76_wcid *wcid, int pid,
+- struct ieee80211_key_conf *key, u32 changed);
++ struct sk_buff *skb, struct mt76_wcid *wcid,
++ struct ieee80211_key_conf *key, int pid,
++ enum mt76_txq_id qid, u32 changed);
+ void mt7996_mac_set_timing(struct mt7996_phy *phy);
+ int mt7996_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta);
+diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c
+index 1f309d05380ad..b435aed6aff7d 100644
+--- a/drivers/net/wireless/mediatek/mt76/tx.c
++++ b/drivers/net/wireless/mediatek/mt76/tx.c
+@@ -77,7 +77,9 @@ mt76_tx_status_unlock(struct mt76_dev *dev, struct sk_buff_head *list)
+ }
+
+ hw = mt76_tx_status_get_hw(dev, skb);
++ spin_lock_bh(&dev->rx_lock);
+ ieee80211_tx_status_ext(hw, &status);
++ spin_unlock_bh(&dev->rx_lock);
+ }
+ rcu_read_unlock();
+ }
+@@ -263,7 +265,9 @@ void __mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid_idx, struct sk_buff *
+ if (cb->pktid < MT_PACKET_ID_FIRST) {
+ hw = mt76_tx_status_get_hw(dev, skb);
+ status.sta = wcid_to_sta(wcid);
++ spin_lock_bh(&dev->rx_lock);
+ ieee80211_tx_status_ext(hw, &status);
++ spin_unlock_bh(&dev->rx_lock);
+ goto out;
+ }
+
+diff --git a/drivers/net/wireless/mediatek/mt76/util.c b/drivers/net/wireless/mediatek/mt76/util.c
+index 581964425468f..fc76c66ff1a5a 100644
+--- a/drivers/net/wireless/mediatek/mt76/util.c
++++ b/drivers/net/wireless/mediatek/mt76/util.c
+@@ -24,23 +24,23 @@ bool __mt76_poll(struct mt76_dev *dev, u32 offset, u32 mask, u32 val,
+ }
+ EXPORT_SYMBOL_GPL(__mt76_poll);
+
+-bool __mt76_poll_msec(struct mt76_dev *dev, u32 offset, u32 mask, u32 val,
+- int timeout)
++bool ____mt76_poll_msec(struct mt76_dev *dev, u32 offset, u32 mask, u32 val,
++ int timeout, int tick)
+ {
+ u32 cur;
+
+- timeout /= 10;
++ timeout /= tick;
+ do {
+ cur = __mt76_rr(dev, offset) & mask;
+ if (cur == val)
+ return true;
+
+- usleep_range(10000, 20000);
++ usleep_range(1000 * tick, 2000 * tick);
+ } while (timeout-- > 0);
+
+ return false;
+ }
+-EXPORT_SYMBOL_GPL(__mt76_poll_msec);
++EXPORT_SYMBOL_GPL(____mt76_poll_msec);
+
+ int mt76_wcid_alloc(u32 *mask, int size)
+ {
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+index 3a035afcf7f99..9a9cfd0ce402d 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+@@ -1091,6 +1091,7 @@ static void rt2x00lib_remove_hw(struct rt2x00_dev *rt2x00dev)
+ }
+
+ kfree(rt2x00dev->spec.channels_info);
++ kfree(rt2x00dev->chan_survey);
+ }
+
+ static const struct ieee80211_tpt_blink rt2x00_tpt_blink[] = {
+diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c
+index 9d0ed6760cb61..a0c61a39a969d 100644
+--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c
++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c
+@@ -1801,6 +1801,7 @@ struct rtl8xxxu_fileops rtl8192eu_fops = {
+ .rx_desc_size = sizeof(struct rtl8xxxu_rxdesc24),
+ .has_s0s1 = 0,
+ .gen2_thermal_meter = 1,
++ .needs_full_init = 1,
+ .adda_1t_init = 0x0fc01616,
+ .adda_1t_path_on = 0x0fc01616,
+ .adda_2t_path_on_a = 0x0fc01616,
+diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
+index d22990464dad6..846bd268ffd94 100644
+--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
+@@ -1574,11 +1574,7 @@ rtl8xxxu_set_spec_sifs(struct rtl8xxxu_priv *priv, u16 cck, u16 ofdm)
+ static void rtl8xxxu_print_chipinfo(struct rtl8xxxu_priv *priv)
+ {
+ struct device *dev = &priv->udev->dev;
+- char cut = '?';
+-
+- /* Currently always true: chip_cut is 4 bits. */
+- if (priv->chip_cut <= 15)
+- cut = 'A' + priv->chip_cut;
++ char cut = 'A' + priv->chip_cut;
+
+ dev_info(dev,
+ "RTL%s rev %c (%s) %iT%iR, TX queues %i, WiFi=%i, BT=%i, GPS=%i, HI PA=%i\n",
+diff --git a/drivers/net/wireless/realtek/rtlwifi/debug.c b/drivers/net/wireless/realtek/rtlwifi/debug.c
+index 0b1bc04cb6adb..9eb26dfe4ca92 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/debug.c
++++ b/drivers/net/wireless/realtek/rtlwifi/debug.c
+@@ -278,8 +278,8 @@ static ssize_t rtl_debugfs_set_write_reg(struct file *filp,
+
+ tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count);
+
+- if (!buffer || copy_from_user(tmp, buffer, tmp_len))
+- return count;
++ if (copy_from_user(tmp, buffer, tmp_len))
++ return -EFAULT;
+
+ tmp[tmp_len] = '\0';
+
+@@ -287,7 +287,7 @@ static ssize_t rtl_debugfs_set_write_reg(struct file *filp,
+ num = sscanf(tmp, "%x %x %x", &addr, &val, &len);
+
+ if (num != 3)
+- return count;
++ return -EINVAL;
+
+ switch (len) {
+ case 1:
+@@ -375,8 +375,8 @@ static ssize_t rtl_debugfs_set_write_rfreg(struct file *filp,
+
+ tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count);
+
+- if (!buffer || copy_from_user(tmp, buffer, tmp_len))
+- return count;
++ if (copy_from_user(tmp, buffer, tmp_len))
++ return -EFAULT;
+
+ tmp[tmp_len] = '\0';
+
+@@ -386,7 +386,7 @@ static ssize_t rtl_debugfs_set_write_rfreg(struct file *filp,
+ if (num != 4) {
+ rtl_dbg(rtlpriv, COMP_ERR, DBG_DMESG,
+ "Format is <path> <addr> <mask> <data>\n");
+- return count;
++ return -EINVAL;
+ }
+
+ rtl_set_rfreg(hw, path, addr, bitmask, data);
+diff --git a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/realtek/rtw88/mac.c
+index aa7c5901ef260..8625a0a1430ac 100644
+--- a/drivers/net/wireless/realtek/rtw88/mac.c
++++ b/drivers/net/wireless/realtek/rtw88/mac.c
+@@ -233,7 +233,7 @@ static int rtw_pwr_seq_parser(struct rtw_dev *rtwdev,
+
+ ret = rtw_sub_pwr_seq_parser(rtwdev, intf_mask, cut_mask, cmd);
+ if (ret)
+- return -EBUSY;
++ return ret;
+
+ idx++;
+ } while (1);
+@@ -247,6 +247,7 @@ static int rtw_mac_power_switch(struct rtw_dev *rtwdev, bool pwr_on)
+ const struct rtw_pwr_seq_cmd **pwr_seq;
+ u8 rpwm;
+ bool cur_pwr;
++ int ret;
+
+ if (rtw_chip_wcpu_11ac(rtwdev)) {
+ rpwm = rtw_read8(rtwdev, rtwdev->hci.rpwm_addr);
+@@ -270,8 +271,9 @@ static int rtw_mac_power_switch(struct rtw_dev *rtwdev, bool pwr_on)
+ return -EALREADY;
+
+ pwr_seq = pwr_on ? chip->pwr_on_seq : chip->pwr_off_seq;
+- if (rtw_pwr_seq_parser(rtwdev, pwr_seq))
+- return -EINVAL;
++ ret = rtw_pwr_seq_parser(rtwdev, pwr_seq);
++ if (ret)
++ return ret;
+
+ if (pwr_on)
+ set_bit(RTW_FLAG_POWERON, rtwdev->flags);
+diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c
+index 17f800f6efbd0..67efa58dd78ee 100644
+--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c
++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c
+@@ -47,7 +47,7 @@ static int rtw8821c_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
+
+ map = (struct rtw8821c_efuse *)log_map;
+
+- efuse->rfe_option = map->rfe_option;
++ efuse->rfe_option = map->rfe_option & 0x1f;
+ efuse->rf_board_option = map->rf_board_option;
+ efuse->crystal_cap = map->xtal_k;
+ efuse->pa_type_2g = map->pa_type;
+@@ -1537,7 +1537,6 @@ static const struct rtw_rfe_def rtw8821c_rfe_defs[] = {
+ [2] = RTW_DEF_RFE_EXT(8821c, 0, 0, 2),
+ [4] = RTW_DEF_RFE_EXT(8821c, 0, 0, 2),
+ [6] = RTW_DEF_RFE(8821c, 0, 0),
+- [34] = RTW_DEF_RFE(8821c, 0, 0),
+ };
+
+ static struct rtw_hw_reg rtw8821c_dig[] = {
+diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c
+index 2a8336b1847a5..a10d6fef4ffaf 100644
+--- a/drivers/net/wireless/realtek/rtw88/usb.c
++++ b/drivers/net/wireless/realtek/rtw88/usb.c
+@@ -118,6 +118,22 @@ static void rtw_usb_write32(struct rtw_dev *rtwdev, u32 addr, u32 val)
+ rtw_usb_write(rtwdev, addr, val, 4);
+ }
+
++static int dma_mapping_to_ep(enum rtw_dma_mapping dma_mapping)
++{
++ switch (dma_mapping) {
++ case RTW_DMA_MAPPING_HIGH:
++ return 0;
++ case RTW_DMA_MAPPING_NORMAL:
++ return 1;
++ case RTW_DMA_MAPPING_LOW:
++ return 2;
++ case RTW_DMA_MAPPING_EXTRA:
++ return 3;
++ default:
++ return -EINVAL;
++ }
++}
++
+ static int rtw_usb_parse(struct rtw_dev *rtwdev,
+ struct usb_interface *interface)
+ {
+@@ -129,6 +145,8 @@ static int rtw_usb_parse(struct rtw_dev *rtwdev,
+ int num_out_pipes = 0;
+ int i;
+ u8 num;
++ const struct rtw_chip_info *chip = rtwdev->chip;
++ const struct rtw_rqpn *rqpn;
+
+ for (i = 0; i < interface_desc->bNumEndpoints; i++) {
+ endpoint = &host_interface->endpoint[i].desc;
+@@ -183,31 +201,34 @@ static int rtw_usb_parse(struct rtw_dev *rtwdev,
+
+ rtwdev->hci.bulkout_num = num_out_pipes;
+
+- switch (num_out_pipes) {
+- case 4:
+- case 3:
+- rtwusb->qsel_to_ep[TX_DESC_QSEL_TID0] = 2;
+- rtwusb->qsel_to_ep[TX_DESC_QSEL_TID1] = 2;
+- rtwusb->qsel_to_ep[TX_DESC_QSEL_TID2] = 2;
+- rtwusb->qsel_to_ep[TX_DESC_QSEL_TID3] = 2;
+- rtwusb->qsel_to_ep[TX_DESC_QSEL_TID4] = 1;
+- rtwusb->qsel_to_ep[TX_DESC_QSEL_TID5] = 1;
+- rtwusb->qsel_to_ep[TX_DESC_QSEL_TID6] = 0;
+- rtwusb->qsel_to_ep[TX_DESC_QSEL_TID7] = 0;
+- break;
+- case 2:
+- rtwusb->qsel_to_ep[TX_DESC_QSEL_TID0] = 1;
+- rtwusb->qsel_to_ep[TX_DESC_QSEL_TID1] = 1;
+- rtwusb->qsel_to_ep[TX_DESC_QSEL_TID2] = 1;
+- rtwusb->qsel_to_ep[TX_DESC_QSEL_TID3] = 1;
+- break;
+- case 1:
+- break;
+- default:
+- rtw_err(rtwdev, "failed to get out_pipes(%d)\n", num_out_pipes);
++ if (num_out_pipes < 1 || num_out_pipes > 4) {
++ rtw_err(rtwdev, "invalid number of endpoints %d\n", num_out_pipes);
+ return -EINVAL;
+ }
+
++ rqpn = &chip->rqpn_table[num_out_pipes];
++
++ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID0] = dma_mapping_to_ep(rqpn->dma_map_be);
++ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID1] = dma_mapping_to_ep(rqpn->dma_map_bk);
++ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID2] = dma_mapping_to_ep(rqpn->dma_map_bk);
++ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID3] = dma_mapping_to_ep(rqpn->dma_map_be);
++ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID4] = dma_mapping_to_ep(rqpn->dma_map_vi);
++ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID5] = dma_mapping_to_ep(rqpn->dma_map_vi);
++ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID6] = dma_mapping_to_ep(rqpn->dma_map_vo);
++ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID7] = dma_mapping_to_ep(rqpn->dma_map_vo);
++ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID8] = -EINVAL;
++ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID9] = -EINVAL;
++ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID10] = -EINVAL;
++ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID11] = -EINVAL;
++ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID12] = -EINVAL;
++ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID13] = -EINVAL;
++ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID14] = -EINVAL;
++ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID15] = -EINVAL;
++ rtwusb->qsel_to_ep[TX_DESC_QSEL_BEACON] = dma_mapping_to_ep(rqpn->dma_map_hi);
++ rtwusb->qsel_to_ep[TX_DESC_QSEL_HIGH] = dma_mapping_to_ep(rqpn->dma_map_hi);
++ rtwusb->qsel_to_ep[TX_DESC_QSEL_MGMT] = dma_mapping_to_ep(rqpn->dma_map_mg);
++ rtwusb->qsel_to_ep[TX_DESC_QSEL_H2C] = dma_mapping_to_ep(rqpn->dma_map_hi);
++
+ return 0;
+ }
+
+@@ -250,7 +271,7 @@ static void rtw_usb_write_port_tx_complete(struct urb *urb)
+ static int qsel_to_ep(struct rtw_usb *rtwusb, unsigned int qsel)
+ {
+ if (qsel >= ARRAY_SIZE(rtwusb->qsel_to_ep))
+- return 0;
++ return -EINVAL;
+
+ return rtwusb->qsel_to_ep[qsel];
+ }
+@@ -265,6 +286,9 @@ static int rtw_usb_write_port(struct rtw_dev *rtwdev, u8 qsel, struct sk_buff *s
+ int ret;
+ int ep = qsel_to_ep(rtwusb, qsel);
+
++ if (ep < 0)
++ return ep;
++
+ pipe = usb_sndbulkpipe(usbd, rtwusb->out_ep[ep]);
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+ if (!urb)
+diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
+index e99eccf11c762..08c6d1a8c712d 100644
+--- a/drivers/net/wireless/realtek/rtw89/core.c
++++ b/drivers/net/wireless/realtek/rtw89/core.c
+@@ -3374,18 +3374,22 @@ static int rtw89_core_register_hw(struct rtw89_dev *rtwdev)
+ ret = ieee80211_register_hw(hw);
+ if (ret) {
+ rtw89_err(rtwdev, "failed to register hw\n");
+- goto err;
++ goto err_free_supported_band;
+ }
+
+ ret = rtw89_regd_init(rtwdev, rtw89_regd_notifier);
+ if (ret) {
+ rtw89_err(rtwdev, "failed to init regd\n");
+- goto err;
++ goto err_unregister_hw;
+ }
+
+ return 0;
+
+-err:
++err_unregister_hw:
++ ieee80211_unregister_hw(hw);
++err_free_supported_band:
++ rtw89_core_clr_supported_band(rtwdev);
++
+ return ret;
+ }
+
+diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c
+index 0ea734c81b4f0..e3129ba1ea200 100644
+--- a/drivers/net/wireless/realtek/rtw89/pci.c
++++ b/drivers/net/wireless/realtek/rtw89/pci.c
+@@ -3874,25 +3874,26 @@ int rtw89_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ rtw89_pci_link_cfg(rtwdev);
+ rtw89_pci_l1ss_cfg(rtwdev);
+
+- ret = rtw89_core_register(rtwdev);
+- if (ret) {
+- rtw89_err(rtwdev, "failed to register core\n");
+- goto err_clear_resource;
+- }
+-
+ rtw89_core_napi_init(rtwdev);
+
+ ret = rtw89_pci_request_irq(rtwdev, pdev);
+ if (ret) {
+ rtw89_err(rtwdev, "failed to request pci irq\n");
+- goto err_unregister;
++ goto err_deinit_napi;
++ }
++
++ ret = rtw89_core_register(rtwdev);
++ if (ret) {
++ rtw89_err(rtwdev, "failed to register core\n");
++ goto err_free_irq;
+ }
+
+ return 0;
+
+-err_unregister:
++err_free_irq:
++ rtw89_pci_free_irq(rtwdev, pdev);
++err_deinit_napi:
+ rtw89_core_napi_deinit(rtwdev);
+- rtw89_core_unregister(rtwdev);
+ err_clear_resource:
+ rtw89_pci_clear_resource(rtwdev, pdev);
+ err_declaim_pci:
+diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c
+index b635ac1d1ca2f..81b348631519d 100644
+--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c
++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c
+@@ -1284,7 +1284,7 @@ static void rtw8852b_ctrl_cck_en(struct rtw89_dev *rtwdev, bool cck_en)
+ static void rtw8852b_5m_mask(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan,
+ enum rtw89_phy_idx phy_idx)
+ {
+- u8 pri_ch = chan->primary_channel;
++ u8 pri_ch = chan->pri_ch_idx;
+ bool mask_5m_low;
+ bool mask_5m_en;
+
+@@ -1292,12 +1292,13 @@ static void rtw8852b_5m_mask(struct rtw89_dev *rtwdev, const struct rtw89_chan *
+ case RTW89_CHANNEL_WIDTH_40:
+ /* Prich=1: Mask 5M High, Prich=2: Mask 5M Low */
+ mask_5m_en = true;
+- mask_5m_low = pri_ch == 2;
++ mask_5m_low = pri_ch == RTW89_SC_20_LOWER;
+ break;
+ case RTW89_CHANNEL_WIDTH_80:
+ /* Prich=3: Mask 5M High, Prich=4: Mask 5M Low, Else: Disable */
+- mask_5m_en = pri_ch == 3 || pri_ch == 4;
+- mask_5m_low = pri_ch == 4;
++ mask_5m_en = pri_ch == RTW89_SC_20_UPMOST ||
++ pri_ch == RTW89_SC_20_LOWEST;
++ mask_5m_low = pri_ch == RTW89_SC_20_LOWEST;
+ break;
+ default:
+ mask_5m_en = false;
+diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
+index a87482cc25f58..4f57d76ba26f7 100644
+--- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c
++++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
+@@ -1445,18 +1445,19 @@ static void rtw8852c_5m_mask(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan,
+ enum rtw89_phy_idx phy_idx)
+ {
+- u8 pri_ch = chan->primary_channel;
++ u8 pri_ch = chan->pri_ch_idx;
+ bool mask_5m_low;
+ bool mask_5m_en;
+
+ switch (chan->band_width) {
+ case RTW89_CHANNEL_WIDTH_40:
+ mask_5m_en = true;
+- mask_5m_low = pri_ch == 2;
++ mask_5m_low = pri_ch == RTW89_SC_20_LOWER;
+ break;
+ case RTW89_CHANNEL_WIDTH_80:
+- mask_5m_en = ((pri_ch == 3) || (pri_ch == 4));
+- mask_5m_low = pri_ch == 4;
++ mask_5m_en = pri_ch == RTW89_SC_20_UPMOST ||
++ pri_ch == RTW89_SC_20_LOWEST;
++ mask_5m_low = pri_ch == RTW89_SC_20_LOWEST;
+ break;
+ default:
+ mask_5m_en = false;
+diff --git a/drivers/net/wwan/t7xx/Makefile b/drivers/net/wwan/t7xx/Makefile
+index 268ff9e87e5b3..2652cd00504e6 100644
+--- a/drivers/net/wwan/t7xx/Makefile
++++ b/drivers/net/wwan/t7xx/Makefile
+@@ -1,7 +1,5 @@
+ # SPDX-License-Identifier: GPL-2.0-only
+
+-ccflags-y += -Werror
+-
+ obj-${CONFIG_MTK_T7XX} := mtk_t7xx.o
+ mtk_t7xx-y:= t7xx_pci.o \
+ t7xx_pcie_mac.o \
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index c0429f9f50920..d567762545b05 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -4808,8 +4808,6 @@ static bool nvme_handle_aen_notice(struct nvme_ctrl *ctrl, u32 result)
+ u32 aer_notice_type = nvme_aer_subtype(result);
+ bool requeue = true;
+
+- trace_nvme_async_event(ctrl, aer_notice_type);
+-
+ switch (aer_notice_type) {
+ case NVME_AER_NOTICE_NS_CHANGED:
+ set_bit(NVME_AER_NOTICE_NS_CHANGED, &ctrl->events);
+@@ -4845,7 +4843,6 @@ static bool nvme_handle_aen_notice(struct nvme_ctrl *ctrl, u32 result)
+
+ static void nvme_handle_aer_persistent_error(struct nvme_ctrl *ctrl)
+ {
+- trace_nvme_async_event(ctrl, NVME_AER_ERROR);
+ dev_warn(ctrl->device, "resetting controller due to AER\n");
+ nvme_reset_ctrl(ctrl);
+ }
+@@ -4861,6 +4858,7 @@ void nvme_complete_async_event(struct nvme_ctrl *ctrl, __le16 status,
+ if (le16_to_cpu(status) >> 1 != NVME_SC_SUCCESS)
+ return;
+
++ trace_nvme_async_event(ctrl, result);
+ switch (aer_type) {
+ case NVME_AER_NOTICE:
+ requeue = nvme_handle_aen_notice(ctrl, result);
+@@ -4878,7 +4876,6 @@ void nvme_complete_async_event(struct nvme_ctrl *ctrl, __le16 status,
+ case NVME_AER_SMART:
+ case NVME_AER_CSS:
+ case NVME_AER_VS:
+- trace_nvme_async_event(ctrl, aer_type);
+ ctrl->aen_result = result;
+ break;
+ default:
+diff --git a/drivers/nvme/host/trace.h b/drivers/nvme/host/trace.h
+index 6f0eaf6a15282..4fb5922ffdac5 100644
+--- a/drivers/nvme/host/trace.h
++++ b/drivers/nvme/host/trace.h
+@@ -127,15 +127,12 @@ TRACE_EVENT(nvme_async_event,
+ ),
+ TP_printk("nvme%d: NVME_AEN=%#08x [%s]",
+ __entry->ctrl_id, __entry->result,
+- __print_symbolic(__entry->result,
+- aer_name(NVME_AER_NOTICE_NS_CHANGED),
+- aer_name(NVME_AER_NOTICE_ANA),
+- aer_name(NVME_AER_NOTICE_FW_ACT_STARTING),
+- aer_name(NVME_AER_NOTICE_DISC_CHANGED),
+- aer_name(NVME_AER_ERROR),
+- aer_name(NVME_AER_SMART),
+- aer_name(NVME_AER_CSS),
+- aer_name(NVME_AER_VS))
++ __print_symbolic(__entry->result & 0x7,
++ aer_name(NVME_AER_ERROR),
++ aer_name(NVME_AER_SMART),
++ aer_name(NVME_AER_NOTICE),
++ aer_name(NVME_AER_CSS),
++ aer_name(NVME_AER_VS))
+ )
+ );
+
+diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c
+index 6a54ed6fb1214..29b73e6581d73 100644
+--- a/drivers/nvme/target/admin-cmd.c
++++ b/drivers/nvme/target/admin-cmd.c
+@@ -685,6 +685,13 @@ static bool nvmet_handle_identify_desclist(struct nvmet_req *req)
+ }
+ }
+
++static void nvmet_execute_identify_ctrl_nvm(struct nvmet_req *req)
++{
++ /* Not supported: return zeroes */
++ nvmet_req_complete(req,
++ nvmet_zero_sgl(req, 0, sizeof(struct nvme_id_ctrl_nvm)));
++}
++
+ static void nvmet_execute_identify(struct nvmet_req *req)
+ {
+ if (!nvmet_check_transfer_len(req, NVME_IDENTIFY_DATA_SIZE))
+@@ -692,13 +699,8 @@ static void nvmet_execute_identify(struct nvmet_req *req)
+
+ switch (req->cmd->identify.cns) {
+ case NVME_ID_CNS_NS:
+- switch (req->cmd->identify.csi) {
+- case NVME_CSI_NVM:
+- return nvmet_execute_identify_ns(req);
+- default:
+- break;
+- }
+- break;
++ nvmet_execute_identify_ns(req);
++ return;
+ case NVME_ID_CNS_CS_NS:
+ if (IS_ENABLED(CONFIG_BLK_DEV_ZONED)) {
+ switch (req->cmd->identify.csi) {
+@@ -710,29 +712,24 @@ static void nvmet_execute_identify(struct nvmet_req *req)
+ }
+ break;
+ case NVME_ID_CNS_CTRL:
+- switch (req->cmd->identify.csi) {
+- case NVME_CSI_NVM:
+- return nvmet_execute_identify_ctrl(req);
+- }
+- break;
++ nvmet_execute_identify_ctrl(req);
++ return;
+ case NVME_ID_CNS_CS_CTRL:
+- if (IS_ENABLED(CONFIG_BLK_DEV_ZONED)) {
+- switch (req->cmd->identify.csi) {
+- case NVME_CSI_ZNS:
+- return nvmet_execute_identify_cns_cs_ctrl(req);
+- default:
+- break;
+- }
+- }
+- break;
+- case NVME_ID_CNS_NS_ACTIVE_LIST:
+ switch (req->cmd->identify.csi) {
+ case NVME_CSI_NVM:
+- return nvmet_execute_identify_nslist(req);
+- default:
++ nvmet_execute_identify_ctrl_nvm(req);
++ return;
++ case NVME_CSI_ZNS:
++ if (IS_ENABLED(CONFIG_BLK_DEV_ZONED)) {
++ nvmet_execute_identify_ctrl_zns(req);
++ return;
++ }
+ break;
+ }
+ break;
++ case NVME_ID_CNS_NS_ACTIVE_LIST:
++ nvmet_execute_identify_nslist(req);
++ return;
+ case NVME_ID_CNS_NS_DESC_LIST:
+ if (nvmet_handle_identify_desclist(req) == true)
+ return;
+diff --git a/drivers/nvme/target/fcloop.c b/drivers/nvme/target/fcloop.c
+index 5c16372f3b533..c780af36c1d4a 100644
+--- a/drivers/nvme/target/fcloop.c
++++ b/drivers/nvme/target/fcloop.c
+@@ -614,10 +614,11 @@ fcloop_fcp_recv_work(struct work_struct *work)
+ struct fcloop_fcpreq *tfcp_req =
+ container_of(work, struct fcloop_fcpreq, fcp_rcv_work);
+ struct nvmefc_fcp_req *fcpreq = tfcp_req->fcpreq;
++ unsigned long flags;
+ int ret = 0;
+ bool aborted = false;
+
+- spin_lock_irq(&tfcp_req->reqlock);
++ spin_lock_irqsave(&tfcp_req->reqlock, flags);
+ switch (tfcp_req->inistate) {
+ case INI_IO_START:
+ tfcp_req->inistate = INI_IO_ACTIVE;
+@@ -626,11 +627,11 @@ fcloop_fcp_recv_work(struct work_struct *work)
+ aborted = true;
+ break;
+ default:
+- spin_unlock_irq(&tfcp_req->reqlock);
++ spin_unlock_irqrestore(&tfcp_req->reqlock, flags);
+ WARN_ON(1);
+ return;
+ }
+- spin_unlock_irq(&tfcp_req->reqlock);
++ spin_unlock_irqrestore(&tfcp_req->reqlock, flags);
+
+ if (unlikely(aborted))
+ ret = -ECANCELED;
+@@ -655,8 +656,9 @@ fcloop_fcp_abort_recv_work(struct work_struct *work)
+ container_of(work, struct fcloop_fcpreq, abort_rcv_work);
+ struct nvmefc_fcp_req *fcpreq;
+ bool completed = false;
++ unsigned long flags;
+
+- spin_lock_irq(&tfcp_req->reqlock);
++ spin_lock_irqsave(&tfcp_req->reqlock, flags);
+ fcpreq = tfcp_req->fcpreq;
+ switch (tfcp_req->inistate) {
+ case INI_IO_ABORTED:
+@@ -665,11 +667,11 @@ fcloop_fcp_abort_recv_work(struct work_struct *work)
+ completed = true;
+ break;
+ default:
+- spin_unlock_irq(&tfcp_req->reqlock);
++ spin_unlock_irqrestore(&tfcp_req->reqlock, flags);
+ WARN_ON(1);
+ return;
+ }
+- spin_unlock_irq(&tfcp_req->reqlock);
++ spin_unlock_irqrestore(&tfcp_req->reqlock, flags);
+
+ if (unlikely(completed)) {
+ /* remove reference taken in original abort downcall */
+@@ -681,9 +683,9 @@ fcloop_fcp_abort_recv_work(struct work_struct *work)
+ nvmet_fc_rcv_fcp_abort(tfcp_req->tport->targetport,
+ &tfcp_req->tgt_fcp_req);
+
+- spin_lock_irq(&tfcp_req->reqlock);
++ spin_lock_irqsave(&tfcp_req->reqlock, flags);
+ tfcp_req->fcpreq = NULL;
+- spin_unlock_irq(&tfcp_req->reqlock);
++ spin_unlock_irqrestore(&tfcp_req->reqlock, flags);
+
+ fcloop_call_host_done(fcpreq, tfcp_req, -ECANCELED);
+ /* call_host_done releases reference for abort downcall */
+@@ -699,11 +701,12 @@ fcloop_tgt_fcprqst_done_work(struct work_struct *work)
+ struct fcloop_fcpreq *tfcp_req =
+ container_of(work, struct fcloop_fcpreq, tio_done_work);
+ struct nvmefc_fcp_req *fcpreq;
++ unsigned long flags;
+
+- spin_lock_irq(&tfcp_req->reqlock);
++ spin_lock_irqsave(&tfcp_req->reqlock, flags);
+ fcpreq = tfcp_req->fcpreq;
+ tfcp_req->inistate = INI_IO_COMPLETED;
+- spin_unlock_irq(&tfcp_req->reqlock);
++ spin_unlock_irqrestore(&tfcp_req->reqlock, flags);
+
+ fcloop_call_host_done(fcpreq, tfcp_req, tfcp_req->status);
+ }
+@@ -807,13 +810,14 @@ fcloop_fcp_op(struct nvmet_fc_target_port *tgtport,
+ u32 rsplen = 0, xfrlen = 0;
+ int fcp_err = 0, active, aborted;
+ u8 op = tgt_fcpreq->op;
++ unsigned long flags;
+
+- spin_lock_irq(&tfcp_req->reqlock);
++ spin_lock_irqsave(&tfcp_req->reqlock, flags);
+ fcpreq = tfcp_req->fcpreq;
+ active = tfcp_req->active;
+ aborted = tfcp_req->aborted;
+ tfcp_req->active = true;
+- spin_unlock_irq(&tfcp_req->reqlock);
++ spin_unlock_irqrestore(&tfcp_req->reqlock, flags);
+
+ if (unlikely(active))
+ /* illegal - call while i/o active */
+@@ -821,9 +825,9 @@ fcloop_fcp_op(struct nvmet_fc_target_port *tgtport,
+
+ if (unlikely(aborted)) {
+ /* target transport has aborted i/o prior */
+- spin_lock_irq(&tfcp_req->reqlock);
++ spin_lock_irqsave(&tfcp_req->reqlock, flags);
+ tfcp_req->active = false;
+- spin_unlock_irq(&tfcp_req->reqlock);
++ spin_unlock_irqrestore(&tfcp_req->reqlock, flags);
+ tgt_fcpreq->transferred_length = 0;
+ tgt_fcpreq->fcp_error = -ECANCELED;
+ tgt_fcpreq->done(tgt_fcpreq);
+@@ -880,9 +884,9 @@ fcloop_fcp_op(struct nvmet_fc_target_port *tgtport,
+ break;
+ }
+
+- spin_lock_irq(&tfcp_req->reqlock);
++ spin_lock_irqsave(&tfcp_req->reqlock, flags);
+ tfcp_req->active = false;
+- spin_unlock_irq(&tfcp_req->reqlock);
++ spin_unlock_irqrestore(&tfcp_req->reqlock, flags);
+
+ tgt_fcpreq->transferred_length = xfrlen;
+ tgt_fcpreq->fcp_error = fcp_err;
+@@ -896,15 +900,16 @@ fcloop_tgt_fcp_abort(struct nvmet_fc_target_port *tgtport,
+ struct nvmefc_tgt_fcp_req *tgt_fcpreq)
+ {
+ struct fcloop_fcpreq *tfcp_req = tgt_fcp_req_to_fcpreq(tgt_fcpreq);
++ unsigned long flags;
+
+ /*
+ * mark aborted only in case there were 2 threads in transport
+ * (one doing io, other doing abort) and only kills ops posted
+ * after the abort request
+ */
+- spin_lock_irq(&tfcp_req->reqlock);
++ spin_lock_irqsave(&tfcp_req->reqlock, flags);
+ tfcp_req->aborted = true;
+- spin_unlock_irq(&tfcp_req->reqlock);
++ spin_unlock_irqrestore(&tfcp_req->reqlock, flags);
+
+ tfcp_req->status = NVME_SC_INTERNAL;
+
+@@ -946,6 +951,7 @@ fcloop_fcp_abort(struct nvme_fc_local_port *localport,
+ struct fcloop_ini_fcpreq *inireq = fcpreq->private;
+ struct fcloop_fcpreq *tfcp_req;
+ bool abortio = true;
++ unsigned long flags;
+
+ spin_lock(&inireq->inilock);
+ tfcp_req = inireq->tfcp_req;
+@@ -958,7 +964,7 @@ fcloop_fcp_abort(struct nvme_fc_local_port *localport,
+ return;
+
+ /* break initiator/target relationship for io */
+- spin_lock_irq(&tfcp_req->reqlock);
++ spin_lock_irqsave(&tfcp_req->reqlock, flags);
+ switch (tfcp_req->inistate) {
+ case INI_IO_START:
+ case INI_IO_ACTIVE:
+@@ -968,11 +974,11 @@ fcloop_fcp_abort(struct nvme_fc_local_port *localport,
+ abortio = false;
+ break;
+ default:
+- spin_unlock_irq(&tfcp_req->reqlock);
++ spin_unlock_irqrestore(&tfcp_req->reqlock, flags);
+ WARN_ON(1);
+ return;
+ }
+- spin_unlock_irq(&tfcp_req->reqlock);
++ spin_unlock_irqrestore(&tfcp_req->reqlock, flags);
+
+ if (abortio)
+ /* leave the reference while the work item is scheduled */
+diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
+index 89bedfcd974c4..ed3786140965f 100644
+--- a/drivers/nvme/target/nvmet.h
++++ b/drivers/nvme/target/nvmet.h
+@@ -581,7 +581,7 @@ bool nvmet_ns_revalidate(struct nvmet_ns *ns);
+ u16 blk_to_nvme_status(struct nvmet_req *req, blk_status_t blk_sts);
+
+ bool nvmet_bdev_zns_enable(struct nvmet_ns *ns);
+-void nvmet_execute_identify_cns_cs_ctrl(struct nvmet_req *req);
++void nvmet_execute_identify_ctrl_zns(struct nvmet_req *req);
+ void nvmet_execute_identify_cns_cs_ns(struct nvmet_req *req);
+ void nvmet_bdev_execute_zone_mgmt_recv(struct nvmet_req *req);
+ void nvmet_bdev_execute_zone_mgmt_send(struct nvmet_req *req);
+diff --git a/drivers/nvme/target/zns.c b/drivers/nvme/target/zns.c
+index 1254cf57e008d..d93ee4ae19454 100644
+--- a/drivers/nvme/target/zns.c
++++ b/drivers/nvme/target/zns.c
+@@ -70,7 +70,7 @@ bool nvmet_bdev_zns_enable(struct nvmet_ns *ns)
+ return true;
+ }
+
+-void nvmet_execute_identify_cns_cs_ctrl(struct nvmet_req *req)
++void nvmet_execute_identify_ctrl_zns(struct nvmet_req *req)
+ {
+ u8 zasl = req->sq->ctrl->subsys->zasl;
+ struct nvmet_ctrl *ctrl = req->sq->ctrl;
+@@ -97,7 +97,7 @@ out:
+
+ void nvmet_execute_identify_cns_cs_ns(struct nvmet_req *req)
+ {
+- struct nvme_id_ns_zns *id_zns;
++ struct nvme_id_ns_zns *id_zns = NULL;
+ u64 zsze;
+ u16 status;
+ u32 mar, mor;
+@@ -118,16 +118,18 @@ void nvmet_execute_identify_cns_cs_ns(struct nvmet_req *req)
+ if (status)
+ goto done;
+
+- if (!bdev_is_zoned(req->ns->bdev)) {
+- req->error_loc = offsetof(struct nvme_identify, nsid);
+- goto done;
+- }
+-
+ if (nvmet_ns_revalidate(req->ns)) {
+ mutex_lock(&req->ns->subsys->lock);
+ nvmet_ns_changed(req->ns->subsys, req->ns->nsid);
+ mutex_unlock(&req->ns->subsys->lock);
+ }
++
++ if (!bdev_is_zoned(req->ns->bdev)) {
++ status = NVME_SC_INVALID_FIELD | NVME_SC_DNR;
++ req->error_loc = offsetof(struct nvme_identify, nsid);
++ goto out;
++ }
++
+ zsze = (bdev_zone_sectors(req->ns->bdev) << 9) >>
+ req->ns->blksize_shift;
+ id_zns->lbafe[0].zsze = cpu_to_le64(zsze);
+@@ -148,8 +150,8 @@ void nvmet_execute_identify_cns_cs_ns(struct nvmet_req *req)
+
+ done:
+ status = nvmet_copy_to_sgl(req, 0, id_zns, sizeof(*id_zns));
+- kfree(id_zns);
+ out:
++ kfree(id_zns);
+ nvmet_req_complete(req, status);
+ }
+
+diff --git a/drivers/of/device.c b/drivers/of/device.c
+index c674a13c30558..877f50379fab5 100644
+--- a/drivers/of/device.c
++++ b/drivers/of/device.c
+@@ -297,12 +297,15 @@ int of_device_request_module(struct device *dev)
+ if (size < 0)
+ return size;
+
+- str = kmalloc(size + 1, GFP_KERNEL);
++ /* Reserve an additional byte for the trailing '\0' */
++ size++;
++
++ str = kmalloc(size, GFP_KERNEL);
+ if (!str)
+ return -ENOMEM;
+
+ of_device_get_modalias(dev, str, size);
+- str[size] = '\0';
++ str[size - 1] = '\0';
+ ret = request_module(str);
+ kfree(str);
+
+diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig
+index 99ec91e2a5cfa..4681eef508899 100644
+--- a/drivers/pci/controller/dwc/Kconfig
++++ b/drivers/pci/controller/dwc/Kconfig
+@@ -286,6 +286,7 @@ config PCIE_KIRIN
+ tristate "HiSilicon Kirin series SoCs PCIe controllers"
+ depends on PCI_MSI
+ select PCIE_DW_HOST
++ select REGMAP_MMIO
+ help
+ Say Y here if you want PCIe controller support
+ on HiSilicon Kirin series SoCs.
+diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
+index 1dde5c579edc8..47db2d20568ef 100644
+--- a/drivers/pci/controller/dwc/pci-imx6.c
++++ b/drivers/pci/controller/dwc/pci-imx6.c
+@@ -1402,6 +1402,13 @@ DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_SYNOPSYS, 0xabcd,
+ static int __init imx6_pcie_init(void)
+ {
+ #ifdef CONFIG_ARM
++ struct device_node *np;
++
++ np = of_find_matching_node(NULL, imx6_pcie_of_match);
++ if (!np)
++ return -ENODEV;
++ of_node_put(np);
++
+ /*
+ * Since probe() can be deferred we need to make sure that
+ * hook_fault_code is not called after __init memory is freed
+diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
+index 7e23c74fb4230..face42e843968 100644
+--- a/drivers/pci/controller/dwc/pcie-qcom.c
++++ b/drivers/pci/controller/dwc/pcie-qcom.c
+@@ -1279,11 +1279,9 @@ static int qcom_pcie_init_2_7_0(struct qcom_pcie *pcie)
+ val &= ~REQ_NOT_ENTR_L1;
+ writel(val, pcie->parf + PCIE20_PARF_PM_CTRL);
+
+- if (IS_ENABLED(CONFIG_PCI_MSI)) {
+- val = readl(pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT);
+- val |= BIT(31);
+- writel(val, pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT);
+- }
++ val = readl(pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2);
++ val |= BIT(31);
++ writel(val, pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2);
+
+ return 0;
+ err_disable_clocks:
+diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c
+index d17f3bf36f709..ad12515a4a121 100644
+--- a/drivers/pci/hotplug/pciehp_pci.c
++++ b/drivers/pci/hotplug/pciehp_pci.c
+@@ -63,7 +63,14 @@ int pciehp_configure_device(struct controller *ctrl)
+
+ pci_assign_unassigned_bridge_resources(bridge);
+ pcie_bus_configure_settings(parent);
++
++ /*
++ * Release reset_lock during driver binding
++ * to avoid AB-BA deadlock with device_lock.
++ */
++ up_read(&ctrl->reset_lock);
+ pci_bus_add_devices(parent);
++ down_read_nested(&ctrl->reset_lock, ctrl->depth);
+
+ out:
+ pci_unlock_rescan_remove();
+@@ -104,7 +111,15 @@ void pciehp_unconfigure_device(struct controller *ctrl, bool presence)
+ list_for_each_entry_safe_reverse(dev, temp, &parent->devices,
+ bus_list) {
+ pci_dev_get(dev);
++
++ /*
++ * Release reset_lock during driver unbinding
++ * to avoid AB-BA deadlock with device_lock.
++ */
++ up_read(&ctrl->reset_lock);
+ pci_stop_and_remove_bus_device(dev);
++ down_read_nested(&ctrl->reset_lock, ctrl->depth);
++
+ /*
+ * Ensure that no new Requests will be generated from
+ * the device.
+diff --git a/drivers/pci/pcie/edr.c b/drivers/pci/pcie/edr.c
+index a6b9b479b97ad..87734e4c3c204 100644
+--- a/drivers/pci/pcie/edr.c
++++ b/drivers/pci/pcie/edr.c
+@@ -193,6 +193,7 @@ send_ost:
+ */
+ if (estate == PCI_ERS_RESULT_RECOVERED) {
+ pci_dbg(edev, "DPC port successfully recovered\n");
++ pcie_clear_device_status(edev);
+ acpi_send_edr_status(pdev, edev, EDR_OST_SUCCESS);
+ } else {
+ pci_dbg(edev, "DPC port recovery failed\n");
+diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
+index 494fa46f57671..8d32a3834688f 100644
+--- a/drivers/pci/quirks.c
++++ b/drivers/pci/quirks.c
+@@ -1939,6 +1939,19 @@ static void quirk_radeon_pm(struct pci_dev *dev)
+ }
+ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x6741, quirk_radeon_pm);
+
++/*
++ * NVIDIA Ampere-based HDA controllers can wedge the whole device if a bus
++ * reset is performed too soon after transition to D0, extend d3hot_delay
++ * to previous effective default for all NVIDIA HDA controllers.
++ */
++static void quirk_nvidia_hda_pm(struct pci_dev *dev)
++{
++ quirk_d3hot_delay(dev, 20);
++}
++DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
++ PCI_CLASS_MULTIMEDIA_HD_AUDIO, 8,
++ quirk_nvidia_hda_pm);
++
+ /*
+ * Ryzen5/7 XHCI controllers fail upon resume from runtime suspend or s2idle.
+ * https://bugzilla.kernel.org/show_bug.cgi?id=205587
+diff --git a/drivers/perf/amlogic/meson_ddr_pmu_core.c b/drivers/perf/amlogic/meson_ddr_pmu_core.c
+index b84346dbac2ce..0b24dee1ed3cf 100644
+--- a/drivers/perf/amlogic/meson_ddr_pmu_core.c
++++ b/drivers/perf/amlogic/meson_ddr_pmu_core.c
+@@ -156,10 +156,14 @@ static int meson_ddr_perf_event_add(struct perf_event *event, int flags)
+ u64 config2 = event->attr.config2;
+ int i;
+
+- for_each_set_bit(i, (const unsigned long *)&config1, sizeof(config1))
++ for_each_set_bit(i,
++ (const unsigned long *)&config1,
++ BITS_PER_TYPE(config1))
+ meson_ddr_set_axi_filter(event, i);
+
+- for_each_set_bit(i, (const unsigned long *)&config2, sizeof(config2))
++ for_each_set_bit(i,
++ (const unsigned long *)&config2,
++ BITS_PER_TYPE(config2))
+ meson_ddr_set_axi_filter(event, i + 64);
+
+ if (flags & PERF_EF_START)
+diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
+index 1deb61b22bc76..ff86075edca48 100644
+--- a/drivers/perf/arm-cmn.c
++++ b/drivers/perf/arm-cmn.c
+@@ -57,14 +57,12 @@
+ #define CMN_INFO_REQ_VC_NUM GENMASK_ULL(1, 0)
+
+ /* XPs also have some local topology info which has uses too */
+-#define CMN_MXP__CONNECT_INFO_P0 0x0008
+-#define CMN_MXP__CONNECT_INFO_P1 0x0010
+-#define CMN_MXP__CONNECT_INFO_P2 0x0028
+-#define CMN_MXP__CONNECT_INFO_P3 0x0030
+-#define CMN_MXP__CONNECT_INFO_P4 0x0038
+-#define CMN_MXP__CONNECT_INFO_P5 0x0040
++#define CMN_MXP__CONNECT_INFO(p) (0x0008 + 8 * (p))
+ #define CMN__CONNECT_INFO_DEVICE_TYPE GENMASK_ULL(4, 0)
+
++#define CMN_MAX_PORTS 6
++#define CI700_CONNECT_INFO_P2_5_OFFSET 0x10
++
+ /* PMU registers occupy the 3rd 4KB page of each node's region */
+ #define CMN_PMU_OFFSET 0x2000
+
+@@ -166,7 +164,7 @@
+ #define CMN_EVENT_BYNODEID(event) FIELD_GET(CMN_CONFIG_BYNODEID, (event)->attr.config)
+ #define CMN_EVENT_NODEID(event) FIELD_GET(CMN_CONFIG_NODEID, (event)->attr.config)
+
+-#define CMN_CONFIG_WP_COMBINE GENMASK_ULL(27, 24)
++#define CMN_CONFIG_WP_COMBINE GENMASK_ULL(30, 27)
+ #define CMN_CONFIG_WP_DEV_SEL GENMASK_ULL(50, 48)
+ #define CMN_CONFIG_WP_CHN_SEL GENMASK_ULL(55, 51)
+ /* Note that we don't yet support the tertiary match group on newer IPs */
+@@ -396,6 +394,25 @@ static struct arm_cmn_node *arm_cmn_node(const struct arm_cmn *cmn,
+ return NULL;
+ }
+
++static u32 arm_cmn_device_connect_info(const struct arm_cmn *cmn,
++ const struct arm_cmn_node *xp, int port)
++{
++ int offset = CMN_MXP__CONNECT_INFO(port);
++
++ if (port >= 2) {
++ if (cmn->model & (CMN600 | CMN650))
++ return 0;
++ /*
++ * CI-700 may have extra ports, but still has the
++ * mesh_port_connect_info registers in the way.
++ */
++ if (cmn->model == CI700)
++ offset += CI700_CONNECT_INFO_P2_5_OFFSET;
++ }
++
++ return readl_relaxed(xp->pmu_base - CMN_PMU_OFFSET + offset);
++}
++
+ static struct dentry *arm_cmn_debugfs;
+
+ #ifdef CONFIG_DEBUG_FS
+@@ -469,7 +486,7 @@ static int arm_cmn_map_show(struct seq_file *s, void *data)
+ y = cmn->mesh_y;
+ while (y--) {
+ int xp_base = cmn->mesh_x * y;
+- u8 port[6][CMN_MAX_DIMENSION];
++ u8 port[CMN_MAX_PORTS][CMN_MAX_DIMENSION];
+
+ for (x = 0; x < cmn->mesh_x; x++)
+ seq_puts(s, "--------+");
+@@ -477,14 +494,9 @@ static int arm_cmn_map_show(struct seq_file *s, void *data)
+ seq_printf(s, "\n%d |", y);
+ for (x = 0; x < cmn->mesh_x; x++) {
+ struct arm_cmn_node *xp = cmn->xps + xp_base + x;
+- void __iomem *base = xp->pmu_base - CMN_PMU_OFFSET;
+-
+- port[0][x] = readl_relaxed(base + CMN_MXP__CONNECT_INFO_P0);
+- port[1][x] = readl_relaxed(base + CMN_MXP__CONNECT_INFO_P1);
+- port[2][x] = readl_relaxed(base + CMN_MXP__CONNECT_INFO_P2);
+- port[3][x] = readl_relaxed(base + CMN_MXP__CONNECT_INFO_P3);
+- port[4][x] = readl_relaxed(base + CMN_MXP__CONNECT_INFO_P4);
+- port[5][x] = readl_relaxed(base + CMN_MXP__CONNECT_INFO_P5);
++
++ for (p = 0; p < CMN_MAX_PORTS; p++)
++ port[p][x] = arm_cmn_device_connect_info(cmn, xp, p);
+ seq_printf(s, " XP #%-2d |", xp_base + x);
+ }
+
+@@ -2082,18 +2094,9 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
+ * from this, since in that case we will see at least one XP
+ * with port 2 connected, for the HN-D.
+ */
+- if (readq_relaxed(xp_region + CMN_MXP__CONNECT_INFO_P0))
+- xp_ports |= BIT(0);
+- if (readq_relaxed(xp_region + CMN_MXP__CONNECT_INFO_P1))
+- xp_ports |= BIT(1);
+- if (readq_relaxed(xp_region + CMN_MXP__CONNECT_INFO_P2))
+- xp_ports |= BIT(2);
+- if (readq_relaxed(xp_region + CMN_MXP__CONNECT_INFO_P3))
+- xp_ports |= BIT(3);
+- if (readq_relaxed(xp_region + CMN_MXP__CONNECT_INFO_P4))
+- xp_ports |= BIT(4);
+- if (readq_relaxed(xp_region + CMN_MXP__CONNECT_INFO_P5))
+- xp_ports |= BIT(5);
++ for (int p = 0; p < CMN_MAX_PORTS; p++)
++ if (arm_cmn_device_connect_info(cmn, xp, p))
++ xp_ports |= BIT(p);
+
+ if (cmn->multi_dtm && (xp_ports & 0xc))
+ arm_cmn_init_dtm(dtm++, xp, 1);
+diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
+index f6507efe2a584..6f9ca2c42ffe1 100644
+--- a/drivers/perf/riscv_pmu_sbi.c
++++ b/drivers/perf/riscv_pmu_sbi.c
+@@ -883,7 +883,7 @@ static int __init pmu_sbi_devinit(void)
+ struct platform_device *pdev;
+
+ if (sbi_spec_version < sbi_mk_version(0, 3) ||
+- sbi_probe_extension(SBI_EXT_PMU) <= 0) {
++ !sbi_probe_extension(SBI_EXT_PMU)) {
+ return 0;
+ }
+
+diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+index 1b136a87053f8..390380313f760 100644
+--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
++++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+@@ -1854,7 +1854,7 @@ static const struct qmp_phy_cfg msm8998_pciephy_cfg = {
+ };
+
+ static const struct qmp_phy_cfg sc8180x_pciephy_cfg = {
+- .lanes = 1,
++ .lanes = 2,
+
+ .tbls = {
+ .serdes = sc8180x_qmp_pcie_serdes_tbl,
+diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c
+index ff4b930879f3c..58eeda573b677 100644
+--- a/drivers/phy/tegra/xusb.c
++++ b/drivers/phy/tegra/xusb.c
+@@ -782,6 +782,7 @@ static int tegra_xusb_add_usb2_port(struct tegra_xusb_padctl *padctl,
+ usb2->base.lane = usb2->base.ops->map(&usb2->base);
+ if (IS_ERR(usb2->base.lane)) {
+ err = PTR_ERR(usb2->base.lane);
++ tegra_xusb_port_unregister(&usb2->base);
+ goto out;
+ }
+
+@@ -848,6 +849,7 @@ static int tegra_xusb_add_ulpi_port(struct tegra_xusb_padctl *padctl,
+ ulpi->base.lane = ulpi->base.ops->map(&ulpi->base);
+ if (IS_ERR(ulpi->base.lane)) {
+ err = PTR_ERR(ulpi->base.lane);
++ tegra_xusb_port_unregister(&ulpi->base);
+ goto out;
+ }
+
+diff --git a/drivers/phy/ti/phy-j721e-wiz.c b/drivers/phy/ti/phy-j721e-wiz.c
+index ddce5ef7711c6..c21b193fb5498 100644
+--- a/drivers/phy/ti/phy-j721e-wiz.c
++++ b/drivers/phy/ti/phy-j721e-wiz.c
+@@ -430,18 +430,17 @@ static int wiz_mode_select(struct wiz *wiz)
+ int i;
+
+ for (i = 0; i < num_lanes; i++) {
+- if (wiz->lane_phy_type[i] == PHY_TYPE_DP)
++ if (wiz->lane_phy_type[i] == PHY_TYPE_DP) {
+ mode = LANE_MODE_GEN1;
+- else if (wiz->lane_phy_type[i] == PHY_TYPE_QSGMII)
++ } else if (wiz->lane_phy_type[i] == PHY_TYPE_QSGMII) {
+ mode = LANE_MODE_GEN2;
+- else
+- continue;
+-
+- if (wiz->lane_phy_type[i] == PHY_TYPE_USXGMII) {
++ } else if (wiz->lane_phy_type[i] == PHY_TYPE_USXGMII) {
+ ret = regmap_field_write(wiz->p0_mac_src_sel[i], 0x3);
+ ret = regmap_field_write(wiz->p0_rxfclk_sel[i], 0x3);
+ ret = regmap_field_write(wiz->p0_refclk_sel[i], 0x3);
+ mode = LANE_MODE_GEN1;
++ } else {
++ continue;
+ }
+
+ ret = regmap_field_write(wiz->p_standard_mode[i], mode);
+diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
+index c7cdccdb4332a..0f1ab0829ffe6 100644
+--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c
++++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
+@@ -90,6 +90,8 @@ struct bcm2835_pinctrl {
+ struct pinctrl_gpio_range gpio_range;
+
+ raw_spinlock_t irq_lock[BCM2835_NUM_BANKS];
++ /* Protect FSEL registers */
++ spinlock_t fsel_lock;
+ };
+
+ /* pins are just named GPIO0..GPIO53 */
+@@ -284,14 +286,19 @@ static inline void bcm2835_pinctrl_fsel_set(
+ struct bcm2835_pinctrl *pc, unsigned pin,
+ enum bcm2835_fsel fsel)
+ {
+- u32 val = bcm2835_gpio_rd(pc, FSEL_REG(pin));
+- enum bcm2835_fsel cur = (val >> FSEL_SHIFT(pin)) & BCM2835_FSEL_MASK;
++ u32 val;
++ enum bcm2835_fsel cur;
++ unsigned long flags;
++
++ spin_lock_irqsave(&pc->fsel_lock, flags);
++ val = bcm2835_gpio_rd(pc, FSEL_REG(pin));
++ cur = (val >> FSEL_SHIFT(pin)) & BCM2835_FSEL_MASK;
+
+ dev_dbg(pc->dev, "read %08x (%u => %s)\n", val, pin,
+- bcm2835_functions[cur]);
++ bcm2835_functions[cur]);
+
+ if (cur == fsel)
+- return;
++ goto unlock;
+
+ if (cur != BCM2835_FSEL_GPIO_IN && fsel != BCM2835_FSEL_GPIO_IN) {
+ /* always transition through GPIO_IN */
+@@ -309,6 +316,9 @@ static inline void bcm2835_pinctrl_fsel_set(
+ dev_dbg(pc->dev, "write %08x (%u <= %s)\n", val, pin,
+ bcm2835_functions[fsel]);
+ bcm2835_gpio_wr(pc, FSEL_REG(pin), val);
++
++unlock:
++ spin_unlock_irqrestore(&pc->fsel_lock, flags);
+ }
+
+ static int bcm2835_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+@@ -1248,6 +1258,7 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
+ pc->gpio_chip = *pdata->gpio_chip;
+ pc->gpio_chip.parent = dev;
+
++ spin_lock_init(&pc->fsel_lock);
+ for (i = 0; i < BCM2835_NUM_BANKS; i++) {
+ unsigned long events;
+ unsigned offset;
+diff --git a/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c b/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c
+index 3dc670faa59ec..2ee5294c21d8e 100644
+--- a/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c
++++ b/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c
+@@ -221,6 +221,15 @@ static int lpi_config_set(struct pinctrl_dev *pctldev, unsigned int group,
+ }
+ }
+
++ /*
++ * As per Hardware Programming Guide, when configuring pin as output,
++ * set the pin value before setting output-enable (OE).
++ */
++ if (output_enabled) {
++ val = u32_encode_bits(value ? 1 : 0, LPI_GPIO_VALUE_OUT_MASK);
++ lpi_gpio_write(pctrl, group, LPI_GPIO_VALUE_REG, val);
++ }
++
+ val = lpi_gpio_read(pctrl, group, LPI_GPIO_CFG_REG);
+
+ u32p_replace_bits(&val, pullup, LPI_GPIO_PULL_MASK);
+@@ -230,11 +239,6 @@ static int lpi_config_set(struct pinctrl_dev *pctldev, unsigned int group,
+
+ lpi_gpio_write(pctrl, group, LPI_GPIO_CFG_REG, val);
+
+- if (output_enabled) {
+- val = u32_encode_bits(value ? 1 : 0, LPI_GPIO_VALUE_OUT_MASK);
+- lpi_gpio_write(pctrl, group, LPI_GPIO_VALUE_REG, val);
+- }
+-
+ return 0;
+ }
+
+diff --git a/drivers/pinctrl/ralink/pinctrl-mt7620.c b/drivers/pinctrl/ralink/pinctrl-mt7620.c
+index 22ff16eff02ff..929a1ace56aeb 100644
+--- a/drivers/pinctrl/ralink/pinctrl-mt7620.c
++++ b/drivers/pinctrl/ralink/pinctrl-mt7620.c
+@@ -372,6 +372,7 @@ static int mt7620_pinctrl_probe(struct platform_device *pdev)
+
+ static const struct of_device_id mt7620_pinctrl_match[] = {
+ { .compatible = "ralink,mt7620-pinctrl" },
++ { .compatible = "ralink,rt2880-pinmux" },
+ {}
+ };
+ MODULE_DEVICE_TABLE(of, mt7620_pinctrl_match);
+diff --git a/drivers/pinctrl/ralink/pinctrl-mt7621.c b/drivers/pinctrl/ralink/pinctrl-mt7621.c
+index b47968f40e0c2..0297cf455b3a0 100644
+--- a/drivers/pinctrl/ralink/pinctrl-mt7621.c
++++ b/drivers/pinctrl/ralink/pinctrl-mt7621.c
+@@ -97,6 +97,7 @@ static int mt7621_pinctrl_probe(struct platform_device *pdev)
+
+ static const struct of_device_id mt7621_pinctrl_match[] = {
+ { .compatible = "ralink,mt7621-pinctrl" },
++ { .compatible = "ralink,rt2880-pinmux" },
+ {}
+ };
+ MODULE_DEVICE_TABLE(of, mt7621_pinctrl_match);
+diff --git a/drivers/pinctrl/ralink/pinctrl-rt2880.c b/drivers/pinctrl/ralink/pinctrl-rt2880.c
+index 811e12df11331..fd9af7c2ffd0e 100644
+--- a/drivers/pinctrl/ralink/pinctrl-rt2880.c
++++ b/drivers/pinctrl/ralink/pinctrl-rt2880.c
+@@ -41,6 +41,7 @@ static int rt2880_pinctrl_probe(struct platform_device *pdev)
+
+ static const struct of_device_id rt2880_pinctrl_match[] = {
+ { .compatible = "ralink,rt2880-pinctrl" },
++ { .compatible = "ralink,rt2880-pinmux" },
+ {}
+ };
+ MODULE_DEVICE_TABLE(of, rt2880_pinctrl_match);
+diff --git a/drivers/pinctrl/ralink/pinctrl-rt305x.c b/drivers/pinctrl/ralink/pinctrl-rt305x.c
+index 5b204b7ca1f3c..13a012a65d1d8 100644
+--- a/drivers/pinctrl/ralink/pinctrl-rt305x.c
++++ b/drivers/pinctrl/ralink/pinctrl-rt305x.c
+@@ -118,6 +118,7 @@ static int rt305x_pinctrl_probe(struct platform_device *pdev)
+
+ static const struct of_device_id rt305x_pinctrl_match[] = {
+ { .compatible = "ralink,rt305x-pinctrl" },
++ { .compatible = "ralink,rt2880-pinmux" },
+ {}
+ };
+ MODULE_DEVICE_TABLE(of, rt305x_pinctrl_match);
+diff --git a/drivers/pinctrl/ralink/pinctrl-rt3883.c b/drivers/pinctrl/ralink/pinctrl-rt3883.c
+index 44a66c3d2d2a1..b263764011e76 100644
+--- a/drivers/pinctrl/ralink/pinctrl-rt3883.c
++++ b/drivers/pinctrl/ralink/pinctrl-rt3883.c
+@@ -88,6 +88,7 @@ static int rt3883_pinctrl_probe(struct platform_device *pdev)
+
+ static const struct of_device_id rt3883_pinctrl_match[] = {
+ { .compatible = "ralink,rt3883-pinctrl" },
++ { .compatible = "ralink,rt2880-pinmux" },
+ {}
+ };
+ MODULE_DEVICE_TABLE(of, rt3883_pinctrl_match);
+diff --git a/drivers/pinctrl/renesas/pfc-r8a779a0.c b/drivers/pinctrl/renesas/pfc-r8a779a0.c
+index 760c83a8740bd..6069869353bb4 100644
+--- a/drivers/pinctrl/renesas/pfc-r8a779a0.c
++++ b/drivers/pinctrl/renesas/pfc-r8a779a0.c
+@@ -696,16 +696,8 @@ static const u16 pinmux_data[] = {
+ PINMUX_SINGLE(PCIE0_CLKREQ_N),
+
+ PINMUX_SINGLE(AVB0_PHY_INT),
+- PINMUX_SINGLE(AVB0_MAGIC),
+- PINMUX_SINGLE(AVB0_MDC),
+- PINMUX_SINGLE(AVB0_MDIO),
+- PINMUX_SINGLE(AVB0_TXCREFCLK),
+
+ PINMUX_SINGLE(AVB1_PHY_INT),
+- PINMUX_SINGLE(AVB1_MAGIC),
+- PINMUX_SINGLE(AVB1_MDC),
+- PINMUX_SINGLE(AVB1_MDIO),
+- PINMUX_SINGLE(AVB1_TXCREFCLK),
+
+ PINMUX_SINGLE(AVB2_AVTP_PPS),
+ PINMUX_SINGLE(AVB2_AVTP_CAPTURE),
+diff --git a/drivers/pinctrl/renesas/pfc-r8a779f0.c b/drivers/pinctrl/renesas/pfc-r8a779f0.c
+index 417c357f16b19..65c141ce909ac 100644
+--- a/drivers/pinctrl/renesas/pfc-r8a779f0.c
++++ b/drivers/pinctrl/renesas/pfc-r8a779f0.c
+@@ -1213,7 +1213,7 @@ static const unsigned int tsn1_avtp_pps_pins[] = {
+ RCAR_GP_PIN(3, 13),
+ };
+ static const unsigned int tsn1_avtp_pps_mux[] = {
+- TSN0_AVTP_PPS_MARK,
++ TSN1_AVTP_PPS_MARK,
+ };
+ static const unsigned int tsn1_avtp_capture_a_pins[] = {
+ /* TSN1_AVTP_CAPTURE_A */
+diff --git a/drivers/pinctrl/renesas/pfc-r8a779g0.c b/drivers/pinctrl/renesas/pfc-r8a779g0.c
+index 5dd1c2c7708a8..43a63a21a6fb5 100644
+--- a/drivers/pinctrl/renesas/pfc-r8a779g0.c
++++ b/drivers/pinctrl/renesas/pfc-r8a779g0.c
+@@ -156,54 +156,54 @@
+ #define GPSR3_0 F_(MMC_SD_D1, IP0SR3_3_0)
+
+ /* GPSR4 */
+-#define GPSR4_24 FM(AVS1)
+-#define GPSR4_23 FM(AVS0)
+-#define GPSR4_22 FM(PCIE1_CLKREQ_N)
+-#define GPSR4_21 FM(PCIE0_CLKREQ_N)
+-#define GPSR4_20 FM(TSN0_TXCREFCLK)
+-#define GPSR4_19 FM(TSN0_TD2)
+-#define GPSR4_18 FM(TSN0_TD3)
+-#define GPSR4_17 FM(TSN0_RD2)
+-#define GPSR4_16 FM(TSN0_RD3)
+-#define GPSR4_15 FM(TSN0_TD0)
+-#define GPSR4_14 FM(TSN0_TD1)
+-#define GPSR4_13 FM(TSN0_RD1)
+-#define GPSR4_12 FM(TSN0_TXC)
+-#define GPSR4_11 FM(TSN0_RXC)
+-#define GPSR4_10 FM(TSN0_RD0)
+-#define GPSR4_9 FM(TSN0_TX_CTL)
+-#define GPSR4_8 FM(TSN0_AVTP_PPS0)
+-#define GPSR4_7 FM(TSN0_RX_CTL)
+-#define GPSR4_6 FM(TSN0_AVTP_CAPTURE)
+-#define GPSR4_5 FM(TSN0_AVTP_MATCH)
+-#define GPSR4_4 FM(TSN0_LINK)
+-#define GPSR4_3 FM(TSN0_PHY_INT)
+-#define GPSR4_2 FM(TSN0_AVTP_PPS1)
+-#define GPSR4_1 FM(TSN0_MDC)
+-#define GPSR4_0 FM(TSN0_MDIO)
++#define GPSR4_24 F_(AVS1, IP3SR4_3_0)
++#define GPSR4_23 F_(AVS0, IP2SR4_31_28)
++#define GPSR4_22 F_(PCIE1_CLKREQ_N, IP2SR4_27_24)
++#define GPSR4_21 F_(PCIE0_CLKREQ_N, IP2SR4_23_20)
++#define GPSR4_20 F_(TSN0_TXCREFCLK, IP2SR4_19_16)
++#define GPSR4_19 F_(TSN0_TD2, IP2SR4_15_12)
++#define GPSR4_18 F_(TSN0_TD3, IP2SR4_11_8)
++#define GPSR4_17 F_(TSN0_RD2, IP2SR4_7_4)
++#define GPSR4_16 F_(TSN0_RD3, IP2SR4_3_0)
++#define GPSR4_15 F_(TSN0_TD0, IP1SR4_31_28)
++#define GPSR4_14 F_(TSN0_TD1, IP1SR4_27_24)
++#define GPSR4_13 F_(TSN0_RD1, IP1SR4_23_20)
++#define GPSR4_12 F_(TSN0_TXC, IP1SR4_19_16)
++#define GPSR4_11 F_(TSN0_RXC, IP1SR4_15_12)
++#define GPSR4_10 F_(TSN0_RD0, IP1SR4_11_8)
++#define GPSR4_9 F_(TSN0_TX_CTL, IP1SR4_7_4)
++#define GPSR4_8 F_(TSN0_AVTP_PPS0, IP1SR4_3_0)
++#define GPSR4_7 F_(TSN0_RX_CTL, IP0SR4_31_28)
++#define GPSR4_6 F_(TSN0_AVTP_CAPTURE, IP0SR4_27_24)
++#define GPSR4_5 F_(TSN0_AVTP_MATCH, IP0SR4_23_20)
++#define GPSR4_4 F_(TSN0_LINK, IP0SR4_19_16)
++#define GPSR4_3 F_(TSN0_PHY_INT, IP0SR4_15_12)
++#define GPSR4_2 F_(TSN0_AVTP_PPS1, IP0SR4_11_8)
++#define GPSR4_1 F_(TSN0_MDC, IP0SR4_7_4)
++#define GPSR4_0 F_(TSN0_MDIO, IP0SR4_3_0)
+
+ /* GPSR 5 */
+-#define GPSR5_20 FM(AVB2_RX_CTL)
+-#define GPSR5_19 FM(AVB2_TX_CTL)
+-#define GPSR5_18 FM(AVB2_RXC)
+-#define GPSR5_17 FM(AVB2_RD0)
+-#define GPSR5_16 FM(AVB2_TXC)
+-#define GPSR5_15 FM(AVB2_TD0)
+-#define GPSR5_14 FM(AVB2_RD1)
+-#define GPSR5_13 FM(AVB2_RD2)
+-#define GPSR5_12 FM(AVB2_TD1)
+-#define GPSR5_11 FM(AVB2_TD2)
+-#define GPSR5_10 FM(AVB2_MDIO)
+-#define GPSR5_9 FM(AVB2_RD3)
+-#define GPSR5_8 FM(AVB2_TD3)
+-#define GPSR5_7 FM(AVB2_TXCREFCLK)
+-#define GPSR5_6 FM(AVB2_MDC)
+-#define GPSR5_5 FM(AVB2_MAGIC)
+-#define GPSR5_4 FM(AVB2_PHY_INT)
+-#define GPSR5_3 FM(AVB2_LINK)
+-#define GPSR5_2 FM(AVB2_AVTP_MATCH)
+-#define GPSR5_1 FM(AVB2_AVTP_CAPTURE)
+-#define GPSR5_0 FM(AVB2_AVTP_PPS)
++#define GPSR5_20 F_(AVB2_RX_CTL, IP2SR5_19_16)
++#define GPSR5_19 F_(AVB2_TX_CTL, IP2SR5_15_12)
++#define GPSR5_18 F_(AVB2_RXC, IP2SR5_11_8)
++#define GPSR5_17 F_(AVB2_RD0, IP2SR5_7_4)
++#define GPSR5_16 F_(AVB2_TXC, IP2SR5_3_0)
++#define GPSR5_15 F_(AVB2_TD0, IP1SR5_31_28)
++#define GPSR5_14 F_(AVB2_RD1, IP1SR5_27_24)
++#define GPSR5_13 F_(AVB2_RD2, IP1SR5_23_20)
++#define GPSR5_12 F_(AVB2_TD1, IP1SR5_19_16)
++#define GPSR5_11 F_(AVB2_TD2, IP1SR5_15_12)
++#define GPSR5_10 F_(AVB2_MDIO, IP1SR5_11_8)
++#define GPSR5_9 F_(AVB2_RD3, IP1SR5_7_4)
++#define GPSR5_8 F_(AVB2_TD3, IP1SR5_3_0)
++#define GPSR5_7 F_(AVB2_TXCREFCLK, IP0SR5_31_28)
++#define GPSR5_6 F_(AVB2_MDC, IP0SR5_27_24)
++#define GPSR5_5 F_(AVB2_MAGIC, IP0SR5_23_20)
++#define GPSR5_4 F_(AVB2_PHY_INT, IP0SR5_19_16)
++#define GPSR5_3 F_(AVB2_LINK, IP0SR5_15_12)
++#define GPSR5_2 F_(AVB2_AVTP_MATCH, IP0SR5_11_8)
++#define GPSR5_1 F_(AVB2_AVTP_CAPTURE, IP0SR5_7_4)
++#define GPSR5_0 F_(AVB2_AVTP_PPS, IP0SR5_3_0)
+
+ /* GPSR 6 */
+ #define GPSR6_20 F_(AVB1_TXCREFCLK, IP2SR6_19_16)
+@@ -268,209 +268,271 @@
+ #define GPSR8_0 F_(SCL0, IP0SR8_3_0)
+
+ /* SR0 */
+-/* IP0SR0 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
+-#define IP0SR0_3_0 F_(0, 0) FM(ERROROUTC_B) FM(TCLK2_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR0_7_4 F_(0, 0) FM(MSIOF3_SS1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR0_11_8 F_(0, 0) FM(MSIOF3_SS2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR0_15_12 FM(IRQ3) FM(MSIOF3_SCK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR0_19_16 FM(IRQ2) FM(MSIOF3_TXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR0_23_20 FM(IRQ1) FM(MSIOF3_RXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR0_27_24 FM(IRQ0) FM(MSIOF3_SYNC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR0_31_28 FM(MSIOF5_SS2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-
+-/* IP1SR0 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
+-#define IP1SR0_3_0 FM(MSIOF5_SS1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR0_7_4 FM(MSIOF5_SYNC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR0_11_8 FM(MSIOF5_TXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR0_15_12 FM(MSIOF5_SCK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR0_19_16 FM(MSIOF5_RXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR0_23_20 FM(MSIOF2_SS2) FM(TCLK1) FM(IRQ2_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR0_27_24 FM(MSIOF2_SS1) FM(HTX1) FM(TX1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR0_31_28 FM(MSIOF2_SYNC) FM(HRX1) FM(RX1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-
+-/* IP2SR0 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
+-#define IP2SR0_3_0 FM(MSIOF2_TXD) FM(HCTS1_N) FM(CTS1_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP2SR0_7_4 FM(MSIOF2_SCK) FM(HRTS1_N) FM(RTS1_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP2SR0_11_8 FM(MSIOF2_RXD) FM(HSCK1) FM(SCK1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++/* IP0SR0 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
++#define IP0SR0_3_0 F_(0, 0) FM(ERROROUTC_N_B) FM(TCLK2_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR0_7_4 F_(0, 0) FM(MSIOF3_SS1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR0_11_8 F_(0, 0) FM(MSIOF3_SS2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR0_15_12 FM(IRQ3) FM(MSIOF3_SCK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR0_19_16 FM(IRQ2) FM(MSIOF3_TXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR0_23_20 FM(IRQ1) FM(MSIOF3_RXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR0_27_24 FM(IRQ0) FM(MSIOF3_SYNC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR0_31_28 FM(MSIOF5_SS2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++
++/* IP1SR0 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
++#define IP1SR0_3_0 FM(MSIOF5_SS1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR0_7_4 FM(MSIOF5_SYNC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR0_11_8 FM(MSIOF5_TXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR0_15_12 FM(MSIOF5_SCK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR0_19_16 FM(MSIOF5_RXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR0_23_20 FM(MSIOF2_SS2) FM(TCLK1) FM(IRQ2_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR0_27_24 FM(MSIOF2_SS1) FM(HTX1) FM(TX1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR0_31_28 FM(MSIOF2_SYNC) FM(HRX1) FM(RX1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++
++/* IP2SR0 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
++#define IP2SR0_3_0 FM(MSIOF2_TXD) FM(HCTS1_N) FM(CTS1_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2SR0_7_4 FM(MSIOF2_SCK) FM(HRTS1_N) FM(RTS1_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2SR0_11_8 FM(MSIOF2_RXD) FM(HSCK1) FM(SCK1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+
+ /* SR1 */
+-/* IP0SR1 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
+-#define IP0SR1_3_0 FM(MSIOF1_SS2) FM(HTX3_A) FM(TX3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR1_7_4 FM(MSIOF1_SS1) FM(HCTS3_N_A) FM(RX3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR1_11_8 FM(MSIOF1_SYNC) FM(HRTS3_N_A) FM(RTS3_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR1_15_12 FM(MSIOF1_SCK) FM(HSCK3_A) FM(CTS3_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR1_19_16 FM(MSIOF1_TXD) FM(HRX3_A) FM(SCK3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR1_23_20 FM(MSIOF1_RXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR1_27_24 FM(MSIOF0_SS2) FM(HTX1_X) FM(TX1_X) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR1_31_28 FM(MSIOF0_SS1) FM(HRX1_X) FM(RX1_X) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-
+-/* IP1SR1 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
+-#define IP1SR1_3_0 FM(MSIOF0_SYNC) FM(HCTS1_N_X) FM(CTS1_N_X) FM(CANFD5_TX_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR1_7_4 FM(MSIOF0_TXD) FM(HRTS1_N_X) FM(RTS1_N_X) FM(CANFD5_RX_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR1_11_8 FM(MSIOF0_SCK) FM(HSCK1_X) FM(SCK1_X) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR1_15_12 FM(MSIOF0_RXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR1_19_16 FM(HTX0) FM(TX0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR1_23_20 FM(HCTS0_N) FM(CTS0_N) FM(PWM8_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR1_27_24 FM(HRTS0_N) FM(RTS0_N) FM(PWM9_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR1_31_28 FM(HSCK0) FM(SCK0) FM(PWM0_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-
+-/* IP2SR1 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
+-#define IP2SR1_3_0 FM(HRX0) FM(RX0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP2SR1_7_4 FM(SCIF_CLK) FM(IRQ4_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP2SR1_11_8 FM(SSI_SCK) FM(TCLK3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP2SR1_15_12 FM(SSI_WS) FM(TCLK4) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP2SR1_19_16 FM(SSI_SD) FM(IRQ0_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP2SR1_23_20 FM(AUDIO_CLKOUT) FM(IRQ1_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP2SR1_27_24 FM(AUDIO_CLKIN) FM(PWM3_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP2SR1_31_28 F_(0, 0) FM(TCLK2) FM(MSIOF4_SS1) FM(IRQ3_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-
+-/* IP3SR1 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
+-#define IP3SR1_3_0 FM(HRX3) FM(SCK3_A) FM(MSIOF4_SS2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP3SR1_7_4 FM(HSCK3) FM(CTS3_N_A) FM(MSIOF4_SCK) FM(TPU0TO0_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP3SR1_11_8 FM(HRTS3_N) FM(RTS3_N_A) FM(MSIOF4_TXD) FM(TPU0TO1_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP3SR1_15_12 FM(HCTS3_N) FM(RX3_A) FM(MSIOF4_RXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP3SR1_19_16 FM(HTX3) FM(TX3_A) FM(MSIOF4_SYNC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++/* IP0SR1 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
++#define IP0SR1_3_0 FM(MSIOF1_SS2) FM(HTX3_A) FM(TX3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR1_7_4 FM(MSIOF1_SS1) FM(HCTS3_N_A) FM(RX3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR1_11_8 FM(MSIOF1_SYNC) FM(HRTS3_N_A) FM(RTS3_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR1_15_12 FM(MSIOF1_SCK) FM(HSCK3_A) FM(CTS3_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR1_19_16 FM(MSIOF1_TXD) FM(HRX3_A) FM(SCK3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR1_23_20 FM(MSIOF1_RXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR1_27_24 FM(MSIOF0_SS2) FM(HTX1_X) FM(TX1_X) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR1_31_28 FM(MSIOF0_SS1) FM(HRX1_X) FM(RX1_X) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++
++/* IP1SR1 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
++#define IP1SR1_3_0 FM(MSIOF0_SYNC) FM(HCTS1_N_X) FM(CTS1_N_X) FM(CANFD5_TX_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR1_7_4 FM(MSIOF0_TXD) FM(HRTS1_N_X) FM(RTS1_N_X) FM(CANFD5_RX_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR1_11_8 FM(MSIOF0_SCK) FM(HSCK1_X) FM(SCK1_X) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR1_15_12 FM(MSIOF0_RXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR1_19_16 FM(HTX0) FM(TX0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR1_23_20 FM(HCTS0_N) FM(CTS0_N) FM(PWM8_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR1_27_24 FM(HRTS0_N) FM(RTS0_N) FM(PWM9_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR1_31_28 FM(HSCK0) FM(SCK0) FM(PWM0_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++
++/* IP2SR1 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
++#define IP2SR1_3_0 FM(HRX0) FM(RX0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2SR1_7_4 FM(SCIF_CLK) FM(IRQ4_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2SR1_11_8 FM(SSI_SCK) FM(TCLK3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2SR1_15_12 FM(SSI_WS) FM(TCLK4) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2SR1_19_16 FM(SSI_SD) FM(IRQ0_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2SR1_23_20 FM(AUDIO_CLKOUT) FM(IRQ1_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2SR1_27_24 FM(AUDIO_CLKIN) FM(PWM3_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2SR1_31_28 F_(0, 0) FM(TCLK2) FM(MSIOF4_SS1) FM(IRQ3_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++
++/* IP3SR1 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
++#define IP3SR1_3_0 FM(HRX3) FM(SCK3_A) FM(MSIOF4_SS2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP3SR1_7_4 FM(HSCK3) FM(CTS3_N_A) FM(MSIOF4_SCK) FM(TPU0TO0_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP3SR1_11_8 FM(HRTS3_N) FM(RTS3_N_A) FM(MSIOF4_TXD) FM(TPU0TO1_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP3SR1_15_12 FM(HCTS3_N) FM(RX3_A) FM(MSIOF4_RXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP3SR1_19_16 FM(HTX3) FM(TX3_A) FM(MSIOF4_SYNC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+
+ /* SR2 */
+-/* IP0SR2 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
+-#define IP0SR2_3_0 FM(FXR_TXDA) FM(CANFD1_TX) FM(TPU0TO2_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR2_7_4 FM(FXR_TXENA_N) FM(CANFD1_RX) FM(TPU0TO3_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR2_11_8 FM(RXDA_EXTFXR) FM(CANFD5_TX) FM(IRQ5) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR2_15_12 FM(CLK_EXTFXR) FM(CANFD5_RX) FM(IRQ4_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR2_19_16 FM(RXDB_EXTFXR) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR2_23_20 FM(FXR_TXENB_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR2_27_24 FM(FXR_TXDB) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR2_31_28 FM(TPU0TO1) FM(CANFD6_TX) F_(0, 0) FM(TCLK2_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-
+-/* IP1SR2 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
+-#define IP1SR2_3_0 FM(TPU0TO0) FM(CANFD6_RX) F_(0, 0) FM(TCLK1_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR2_7_4 FM(CAN_CLK) FM(FXR_TXENA_N_X) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR2_11_8 FM(CANFD0_TX) FM(FXR_TXENB_N_X) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR2_15_12 FM(CANFD0_RX) FM(STPWT_EXTFXR) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR2_19_16 FM(CANFD2_TX) FM(TPU0TO2) F_(0, 0) FM(TCLK3_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR2_23_20 FM(CANFD2_RX) FM(TPU0TO3) FM(PWM1_B) FM(TCLK4_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR2_27_24 FM(CANFD3_TX) F_(0, 0) FM(PWM2_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR2_31_28 FM(CANFD3_RX) F_(0, 0) FM(PWM3_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-
+-/* IP2SR2 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
+-#define IP2SR2_3_0 FM(CANFD4_TX) F_(0, 0) FM(PWM4) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP2SR2_7_4 FM(CANFD4_RX) F_(0, 0) FM(PWM5) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP2SR2_11_8 FM(CANFD7_TX) F_(0, 0) FM(PWM6) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP2SR2_15_12 FM(CANFD7_RX) F_(0, 0) FM(PWM7) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++/* IP0SR2 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
++#define IP0SR2_3_0 FM(FXR_TXDA) FM(CANFD1_TX) FM(TPU0TO2_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR2_7_4 FM(FXR_TXENA_N) FM(CANFD1_RX) FM(TPU0TO3_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR2_11_8 FM(RXDA_EXTFXR) FM(CANFD5_TX) FM(IRQ5) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR2_15_12 FM(CLK_EXTFXR) FM(CANFD5_RX) FM(IRQ4_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR2_19_16 FM(RXDB_EXTFXR) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR2_23_20 FM(FXR_TXENB_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR2_27_24 FM(FXR_TXDB) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR2_31_28 FM(TPU0TO1) FM(CANFD6_TX) F_(0, 0) FM(TCLK2_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++
++/* IP1SR2 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
++#define IP1SR2_3_0 FM(TPU0TO0) FM(CANFD6_RX) F_(0, 0) FM(TCLK1_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR2_7_4 FM(CAN_CLK) FM(FXR_TXENA_N_X) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR2_11_8 FM(CANFD0_TX) FM(FXR_TXENB_N_X) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR2_15_12 FM(CANFD0_RX) FM(STPWT_EXTFXR) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR2_19_16 FM(CANFD2_TX) FM(TPU0TO2) F_(0, 0) FM(TCLK3_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR2_23_20 FM(CANFD2_RX) FM(TPU0TO3) FM(PWM1_B) FM(TCLK4_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR2_27_24 FM(CANFD3_TX) F_(0, 0) FM(PWM2_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR2_31_28 FM(CANFD3_RX) F_(0, 0) FM(PWM3_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++
++/* IP2SR2 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
++#define IP2SR2_3_0 FM(CANFD4_TX) F_(0, 0) FM(PWM4) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2SR2_7_4 FM(CANFD4_RX) F_(0, 0) FM(PWM5) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2SR2_11_8 FM(CANFD7_TX) F_(0, 0) FM(PWM6) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2SR2_15_12 FM(CANFD7_RX) F_(0, 0) FM(PWM7) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+
+ /* SR3 */
+-/* IP0SR3 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
+-#define IP0SR3_3_0 FM(MMC_SD_D1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR3_7_4 FM(MMC_SD_D0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR3_11_8 FM(MMC_SD_D2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR3_15_12 FM(MMC_SD_CLK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR3_19_16 FM(MMC_DS) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR3_23_20 FM(MMC_SD_D3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR3_27_24 FM(MMC_D5) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR3_31_28 FM(MMC_D4) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-
+-/* IP1SR3 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
+-#define IP1SR3_3_0 FM(MMC_D7) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR3_7_4 FM(MMC_D6) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR3_11_8 FM(MMC_SD_CMD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR3_15_12 FM(SD_CD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR3_19_16 FM(SD_WP) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR3_23_20 FM(IPC_CLKIN) FM(IPC_CLKEN_IN) FM(PWM1_A) FM(TCLK3_X) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR3_27_24 FM(IPC_CLKOUT) FM(IPC_CLKEN_OUT) FM(ERROROUTC_A) FM(TCLK4_X) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR3_31_28 FM(QSPI0_SSL) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-
+-/* IP2SR3 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
+-#define IP2SR3_3_0 FM(QSPI0_IO3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP2SR3_7_4 FM(QSPI0_IO2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP2SR3_11_8 FM(QSPI0_MISO_IO1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP2SR3_15_12 FM(QSPI0_MOSI_IO0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP2SR3_19_16 FM(QSPI0_SPCLK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP2SR3_23_20 FM(QSPI1_MOSI_IO0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP2SR3_27_24 FM(QSPI1_SPCLK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP2SR3_31_28 FM(QSPI1_MISO_IO1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-
+-/* IP3SR3 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
+-#define IP3SR3_3_0 FM(QSPI1_IO2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP3SR3_7_4 FM(QSPI1_SSL) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP3SR3_11_8 FM(QSPI1_IO3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP3SR3_15_12 FM(RPC_RESET_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP3SR3_19_16 FM(RPC_WP_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP3SR3_23_20 FM(RPC_INT_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++/* IP0SR3 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
++#define IP0SR3_3_0 FM(MMC_SD_D1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR3_7_4 FM(MMC_SD_D0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR3_11_8 FM(MMC_SD_D2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR3_15_12 FM(MMC_SD_CLK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR3_19_16 FM(MMC_DS) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR3_23_20 FM(MMC_SD_D3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR3_27_24 FM(MMC_D5) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR3_31_28 FM(MMC_D4) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++
++/* IP1SR3 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
++#define IP1SR3_3_0 FM(MMC_D7) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR3_7_4 FM(MMC_D6) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR3_11_8 FM(MMC_SD_CMD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR3_15_12 FM(SD_CD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR3_19_16 FM(SD_WP) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR3_23_20 FM(IPC_CLKIN) FM(IPC_CLKEN_IN) FM(PWM1_A) FM(TCLK3_X) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR3_27_24 FM(IPC_CLKOUT) FM(IPC_CLKEN_OUT) FM(ERROROUTC_N_A) FM(TCLK4_X) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR3_31_28 FM(QSPI0_SSL) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++
++/* IP2SR3 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
++#define IP2SR3_3_0 FM(QSPI0_IO3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2SR3_7_4 FM(QSPI0_IO2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2SR3_11_8 FM(QSPI0_MISO_IO1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2SR3_15_12 FM(QSPI0_MOSI_IO0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2SR3_19_16 FM(QSPI0_SPCLK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2SR3_23_20 FM(QSPI1_MOSI_IO0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2SR3_27_24 FM(QSPI1_SPCLK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2SR3_31_28 FM(QSPI1_MISO_IO1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++
++/* IP3SR3 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
++#define IP3SR3_3_0 FM(QSPI1_IO2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP3SR3_7_4 FM(QSPI1_SSL) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP3SR3_11_8 FM(QSPI1_IO3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP3SR3_15_12 FM(RPC_RESET_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP3SR3_19_16 FM(RPC_WP_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP3SR3_23_20 FM(RPC_INT_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++
++/* SR4 */
++/* IP0SR4 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
++#define IP0SR4_3_0 FM(TSN0_MDIO) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR4_7_4 FM(TSN0_MDC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR4_11_8 FM(TSN0_AVTP_PPS1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR4_15_12 FM(TSN0_PHY_INT) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR4_19_16 FM(TSN0_LINK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR4_23_20 FM(TSN0_AVTP_MATCH) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR4_27_24 FM(TSN0_AVTP_CAPTURE) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR4_31_28 FM(TSN0_RX_CTL) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++
++/* IP1SR4 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
++#define IP1SR4_3_0 FM(TSN0_AVTP_PPS0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR4_7_4 FM(TSN0_TX_CTL) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR4_11_8 FM(TSN0_RD0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR4_15_12 FM(TSN0_RXC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR4_19_16 FM(TSN0_TXC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR4_23_20 FM(TSN0_RD1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR4_27_24 FM(TSN0_TD1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR4_31_28 FM(TSN0_TD0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++
++/* IP2SR4 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
++#define IP2SR4_3_0 FM(TSN0_RD3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2SR4_7_4 FM(TSN0_RD2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2SR4_11_8 FM(TSN0_TD3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2SR4_15_12 FM(TSN0_TD2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2SR4_19_16 FM(TSN0_TXCREFCLK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2SR4_23_20 FM(PCIE0_CLKREQ_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2SR4_27_24 FM(PCIE1_CLKREQ_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2SR4_31_28 FM(AVS0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++
++/* IP3SR4 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
++#define IP3SR4_3_0 FM(AVS1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++
++/* SR5 */
++/* IP0SR5 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
++#define IP0SR5_3_0 FM(AVB2_AVTP_PPS) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR5_7_4 FM(AVB2_AVTP_CAPTURE) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR5_11_8 FM(AVB2_AVTP_MATCH) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR5_15_12 FM(AVB2_LINK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR5_19_16 FM(AVB2_PHY_INT) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR5_23_20 FM(AVB2_MAGIC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR5_27_24 FM(AVB2_MDC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR5_31_28 FM(AVB2_TXCREFCLK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++
++/* IP1SR5 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
++#define IP1SR5_3_0 FM(AVB2_TD3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR5_7_4 FM(AVB2_RD3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR5_11_8 FM(AVB2_MDIO) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR5_15_12 FM(AVB2_TD2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR5_19_16 FM(AVB2_TD1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR5_23_20 FM(AVB2_RD2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR5_27_24 FM(AVB2_RD1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR5_31_28 FM(AVB2_TD0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++
++/* IP2SR5 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
++#define IP2SR5_3_0 FM(AVB2_TXC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2SR5_7_4 FM(AVB2_RD0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2SR5_11_8 FM(AVB2_RXC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2SR5_15_12 FM(AVB2_TX_CTL) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2SR5_19_16 FM(AVB2_RX_CTL) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+
+ /* SR6 */
+-/* IP0SR6 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
+-#define IP0SR6_3_0 FM(AVB1_MDIO) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR6_7_4 FM(AVB1_MAGIC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR6_11_8 FM(AVB1_MDC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR6_15_12 FM(AVB1_PHY_INT) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR6_19_16 FM(AVB1_LINK) FM(AVB1_MII_TX_ER) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR6_23_20 FM(AVB1_AVTP_MATCH) FM(AVB1_MII_RX_ER) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR6_27_24 FM(AVB1_TXC) FM(AVB1_MII_TXC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR6_31_28 FM(AVB1_TX_CTL) FM(AVB1_MII_TX_EN) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-
+-/* IP1SR6 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
+-#define IP1SR6_3_0 FM(AVB1_RXC) FM(AVB1_MII_RXC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR6_7_4 FM(AVB1_RX_CTL) FM(AVB1_MII_RX_DV) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR6_11_8 FM(AVB1_AVTP_PPS) FM(AVB1_MII_COL) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR6_15_12 FM(AVB1_AVTP_CAPTURE) FM(AVB1_MII_CRS) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR6_19_16 FM(AVB1_TD1) FM(AVB1_MII_TD1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR6_23_20 FM(AVB1_TD0) FM(AVB1_MII_TD0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR6_27_24 FM(AVB1_RD1) FM(AVB1_MII_RD1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR6_31_28 FM(AVB1_RD0) FM(AVB1_MII_RD0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-
+-/* IP2SR6 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
+-#define IP2SR6_3_0 FM(AVB1_TD2) FM(AVB1_MII_TD2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP2SR6_7_4 FM(AVB1_RD2) FM(AVB1_MII_RD2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP2SR6_11_8 FM(AVB1_TD3) FM(AVB1_MII_TD3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP2SR6_15_12 FM(AVB1_RD3) FM(AVB1_MII_RD3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP2SR6_19_16 FM(AVB1_TXCREFCLK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++/* IP0SR6 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
++#define IP0SR6_3_0 FM(AVB1_MDIO) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR6_7_4 FM(AVB1_MAGIC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR6_11_8 FM(AVB1_MDC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR6_15_12 FM(AVB1_PHY_INT) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR6_19_16 FM(AVB1_LINK) FM(AVB1_MII_TX_ER) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR6_23_20 FM(AVB1_AVTP_MATCH) FM(AVB1_MII_RX_ER) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR6_27_24 FM(AVB1_TXC) FM(AVB1_MII_TXC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR6_31_28 FM(AVB1_TX_CTL) FM(AVB1_MII_TX_EN) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++
++/* IP1SR6 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
++#define IP1SR6_3_0 FM(AVB1_RXC) FM(AVB1_MII_RXC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR6_7_4 FM(AVB1_RX_CTL) FM(AVB1_MII_RX_DV) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR6_11_8 FM(AVB1_AVTP_PPS) FM(AVB1_MII_COL) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR6_15_12 FM(AVB1_AVTP_CAPTURE) FM(AVB1_MII_CRS) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR6_19_16 FM(AVB1_TD1) FM(AVB1_MII_TD1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR6_23_20 FM(AVB1_TD0) FM(AVB1_MII_TD0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR6_27_24 FM(AVB1_RD1) FM(AVB1_MII_RD1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR6_31_28 FM(AVB1_RD0) FM(AVB1_MII_RD0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++
++/* IP2SR6 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
++#define IP2SR6_3_0 FM(AVB1_TD2) FM(AVB1_MII_TD2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2SR6_7_4 FM(AVB1_RD2) FM(AVB1_MII_RD2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2SR6_11_8 FM(AVB1_TD3) FM(AVB1_MII_TD3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2SR6_15_12 FM(AVB1_RD3) FM(AVB1_MII_RD3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2SR6_19_16 FM(AVB1_TXCREFCLK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+
+ /* SR7 */
+-/* IP0SR7 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
+-#define IP0SR7_3_0 FM(AVB0_AVTP_PPS) FM(AVB0_MII_COL) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR7_7_4 FM(AVB0_AVTP_CAPTURE) FM(AVB0_MII_CRS) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR7_11_8 FM(AVB0_AVTP_MATCH) FM(AVB0_MII_RX_ER) FM(CC5_OSCOUT) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR7_15_12 FM(AVB0_TD3) FM(AVB0_MII_TD3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR7_19_16 FM(AVB0_LINK) FM(AVB0_MII_TX_ER) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR7_23_20 FM(AVB0_PHY_INT) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR7_27_24 FM(AVB0_TD2) FM(AVB0_MII_TD2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR7_31_28 FM(AVB0_TD1) FM(AVB0_MII_TD1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-
+-/* IP1SR7 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
+-#define IP1SR7_3_0 FM(AVB0_RD3) FM(AVB0_MII_RD3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR7_7_4 FM(AVB0_TXCREFCLK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR7_11_8 FM(AVB0_MAGIC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR7_15_12 FM(AVB0_TD0) FM(AVB0_MII_TD0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR7_19_16 FM(AVB0_RD2) FM(AVB0_MII_RD2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR7_23_20 FM(AVB0_MDC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR7_27_24 FM(AVB0_MDIO) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR7_31_28 FM(AVB0_TXC) FM(AVB0_MII_TXC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-
+-/* IP2SR7 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
+-#define IP2SR7_3_0 FM(AVB0_TX_CTL) FM(AVB0_MII_TX_EN) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP2SR7_7_4 FM(AVB0_RD1) FM(AVB0_MII_RD1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP2SR7_11_8 FM(AVB0_RD0) FM(AVB0_MII_RD0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP2SR7_15_12 FM(AVB0_RXC) FM(AVB0_MII_RXC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP2SR7_19_16 FM(AVB0_RX_CTL) FM(AVB0_MII_RX_DV) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++/* IP0SR7 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
++#define IP0SR7_3_0 FM(AVB0_AVTP_PPS) FM(AVB0_MII_COL) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR7_7_4 FM(AVB0_AVTP_CAPTURE) FM(AVB0_MII_CRS) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR7_11_8 FM(AVB0_AVTP_MATCH) FM(AVB0_MII_RX_ER) FM(CC5_OSCOUT) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR7_15_12 FM(AVB0_TD3) FM(AVB0_MII_TD3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR7_19_16 FM(AVB0_LINK) FM(AVB0_MII_TX_ER) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR7_23_20 FM(AVB0_PHY_INT) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR7_27_24 FM(AVB0_TD2) FM(AVB0_MII_TD2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR7_31_28 FM(AVB0_TD1) FM(AVB0_MII_TD1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++
++/* IP1SR7 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
++#define IP1SR7_3_0 FM(AVB0_RD3) FM(AVB0_MII_RD3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR7_7_4 FM(AVB0_TXCREFCLK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR7_11_8 FM(AVB0_MAGIC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR7_15_12 FM(AVB0_TD0) FM(AVB0_MII_TD0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR7_19_16 FM(AVB0_RD2) FM(AVB0_MII_RD2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR7_23_20 FM(AVB0_MDC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR7_27_24 FM(AVB0_MDIO) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR7_31_28 FM(AVB0_TXC) FM(AVB0_MII_TXC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++
++/* IP2SR7 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
++#define IP2SR7_3_0 FM(AVB0_TX_CTL) FM(AVB0_MII_TX_EN) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2SR7_7_4 FM(AVB0_RD1) FM(AVB0_MII_RD1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2SR7_11_8 FM(AVB0_RD0) FM(AVB0_MII_RD0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2SR7_15_12 FM(AVB0_RXC) FM(AVB0_MII_RXC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2SR7_19_16 FM(AVB0_RX_CTL) FM(AVB0_MII_RX_DV) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+
+ /* SR8 */
+-/* IP0SR8 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
+-#define IP0SR8_3_0 FM(SCL0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR8_7_4 FM(SDA0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR8_11_8 FM(SCL1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR8_15_12 FM(SDA1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR8_19_16 FM(SCL2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR8_23_20 FM(SDA2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR8_27_24 FM(SCL3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP0SR8_31_28 FM(SDA3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-
+-/* IP1SR8 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
+-#define IP1SR8_3_0 FM(SCL4) FM(HRX2) FM(SCK4) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR8_7_4 FM(SDA4) FM(HTX2) FM(CTS4_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR8_11_8 FM(SCL5) FM(HRTS2_N) FM(RTS4_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR8_15_12 FM(SDA5) FM(SCIF_CLK2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR8_19_16 F_(0, 0) FM(HCTS2_N) FM(TX4) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+-#define IP1SR8_23_20 F_(0, 0) FM(HSCK2) FM(RX4) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++/* IP0SR8 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
++#define IP0SR8_3_0 FM(SCL0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR8_7_4 FM(SDA0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR8_11_8 FM(SCL1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR8_15_12 FM(SDA1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR8_19_16 FM(SCL2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR8_23_20 FM(SDA2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR8_27_24 FM(SCL3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0SR8_31_28 FM(SDA3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++
++/* IP1SR8 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */
++#define IP1SR8_3_0 FM(SCL4) FM(HRX2) FM(SCK4) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR8_7_4 FM(SDA4) FM(HTX2) FM(CTS4_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR8_11_8 FM(SCL5) FM(HRTS2_N) FM(RTS4_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR8_15_12 FM(SDA5) FM(SCIF_CLK2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR8_19_16 F_(0, 0) FM(HCTS2_N) FM(TX4) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1SR8_23_20 F_(0, 0) FM(HSCK2) FM(RX4) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+
+ #define PINMUX_GPSR \
+ GPSR3_29 \
+@@ -542,6 +604,24 @@ FM(IP0SR3_23_20) IP0SR3_23_20 FM(IP1SR3_23_20) IP1SR3_23_20 FM(IP2SR3_23_20) IP2
+ FM(IP0SR3_27_24) IP0SR3_27_24 FM(IP1SR3_27_24) IP1SR3_27_24 FM(IP2SR3_27_24) IP2SR3_27_24 \
+ FM(IP0SR3_31_28) IP0SR3_31_28 FM(IP1SR3_31_28) IP1SR3_31_28 FM(IP2SR3_31_28) IP2SR3_31_28 \
+ \
++FM(IP0SR4_3_0) IP0SR4_3_0 FM(IP1SR4_3_0) IP1SR4_3_0 FM(IP2SR4_3_0) IP2SR4_3_0 FM(IP3SR4_3_0) IP3SR4_3_0 \
++FM(IP0SR4_7_4) IP0SR4_7_4 FM(IP1SR4_7_4) IP1SR4_7_4 FM(IP2SR4_7_4) IP2SR4_7_4 \
++FM(IP0SR4_11_8) IP0SR4_11_8 FM(IP1SR4_11_8) IP1SR4_11_8 FM(IP2SR4_11_8) IP2SR4_11_8 \
++FM(IP0SR4_15_12) IP0SR4_15_12 FM(IP1SR4_15_12) IP1SR4_15_12 FM(IP2SR4_15_12) IP2SR4_15_12 \
++FM(IP0SR4_19_16) IP0SR4_19_16 FM(IP1SR4_19_16) IP1SR4_19_16 FM(IP2SR4_19_16) IP2SR4_19_16 \
++FM(IP0SR4_23_20) IP0SR4_23_20 FM(IP1SR4_23_20) IP1SR4_23_20 FM(IP2SR4_23_20) IP2SR4_23_20 \
++FM(IP0SR4_27_24) IP0SR4_27_24 FM(IP1SR4_27_24) IP1SR4_27_24 FM(IP2SR4_27_24) IP2SR4_27_24 \
++FM(IP0SR4_31_28) IP0SR4_31_28 FM(IP1SR4_31_28) IP1SR4_31_28 FM(IP2SR4_31_28) IP2SR4_31_28 \
++\
++FM(IP0SR5_3_0) IP0SR5_3_0 FM(IP1SR5_3_0) IP1SR5_3_0 FM(IP2SR5_3_0) IP2SR5_3_0 \
++FM(IP0SR5_7_4) IP0SR5_7_4 FM(IP1SR5_7_4) IP1SR5_7_4 FM(IP2SR5_7_4) IP2SR5_7_4 \
++FM(IP0SR5_11_8) IP0SR5_11_8 FM(IP1SR5_11_8) IP1SR5_11_8 FM(IP2SR5_11_8) IP2SR5_11_8 \
++FM(IP0SR5_15_12) IP0SR5_15_12 FM(IP1SR5_15_12) IP1SR5_15_12 FM(IP2SR5_15_12) IP2SR5_15_12 \
++FM(IP0SR5_19_16) IP0SR5_19_16 FM(IP1SR5_19_16) IP1SR5_19_16 FM(IP2SR5_19_16) IP2SR5_19_16 \
++FM(IP0SR5_23_20) IP0SR5_23_20 FM(IP1SR5_23_20) IP1SR5_23_20 \
++FM(IP0SR5_27_24) IP0SR5_27_24 FM(IP1SR5_27_24) IP1SR5_27_24 \
++FM(IP0SR5_31_28) IP0SR5_31_28 FM(IP1SR5_31_28) IP1SR5_31_28 \
++\
+ FM(IP0SR6_3_0) IP0SR6_3_0 FM(IP1SR6_3_0) IP1SR6_3_0 FM(IP2SR6_3_0) IP2SR6_3_0 \
+ FM(IP0SR6_7_4) IP0SR6_7_4 FM(IP1SR6_7_4) IP1SR6_7_4 FM(IP2SR6_7_4) IP2SR6_7_4 \
+ FM(IP0SR6_11_8) IP0SR6_11_8 FM(IP1SR6_11_8) IP1SR6_11_8 FM(IP2SR6_11_8) IP2SR6_11_8 \
+@@ -569,54 +649,6 @@ FM(IP0SR8_23_20) IP0SR8_23_20 FM(IP1SR8_23_20) IP1SR8_23_20 \
+ FM(IP0SR8_27_24) IP0SR8_27_24 \
+ FM(IP0SR8_31_28) IP0SR8_31_28
+
+-/* MOD_SEL4 */ /* 0 */ /* 1 */
+-#define MOD_SEL4_19 FM(SEL_TSN0_TD2_0) FM(SEL_TSN0_TD2_1)
+-#define MOD_SEL4_18 FM(SEL_TSN0_TD3_0) FM(SEL_TSN0_TD3_1)
+-#define MOD_SEL4_15 FM(SEL_TSN0_TD0_0) FM(SEL_TSN0_TD0_1)
+-#define MOD_SEL4_14 FM(SEL_TSN0_TD1_0) FM(SEL_TSN0_TD1_1)
+-#define MOD_SEL4_12 FM(SEL_TSN0_TXC_0) FM(SEL_TSN0_TXC_1)
+-#define MOD_SEL4_9 FM(SEL_TSN0_TX_CTL_0) FM(SEL_TSN0_TX_CTL_1)
+-#define MOD_SEL4_8 FM(SEL_TSN0_AVTP_PPS0_0) FM(SEL_TSN0_AVTP_PPS0_1)
+-#define MOD_SEL4_5 FM(SEL_TSN0_AVTP_MATCH_0) FM(SEL_TSN0_AVTP_MATCH_1)
+-#define MOD_SEL4_2 FM(SEL_TSN0_AVTP_PPS1_0) FM(SEL_TSN0_AVTP_PPS1_1)
+-#define MOD_SEL4_1 FM(SEL_TSN0_MDC_0) FM(SEL_TSN0_MDC_1)
+-
+-/* MOD_SEL5 */ /* 0 */ /* 1 */
+-#define MOD_SEL5_19 FM(SEL_AVB2_TX_CTL_0) FM(SEL_AVB2_TX_CTL_1)
+-#define MOD_SEL5_16 FM(SEL_AVB2_TXC_0) FM(SEL_AVB2_TXC_1)
+-#define MOD_SEL5_15 FM(SEL_AVB2_TD0_0) FM(SEL_AVB2_TD0_1)
+-#define MOD_SEL5_12 FM(SEL_AVB2_TD1_0) FM(SEL_AVB2_TD1_1)
+-#define MOD_SEL5_11 FM(SEL_AVB2_TD2_0) FM(SEL_AVB2_TD2_1)
+-#define MOD_SEL5_8 FM(SEL_AVB2_TD3_0) FM(SEL_AVB2_TD3_1)
+-#define MOD_SEL5_6 FM(SEL_AVB2_MDC_0) FM(SEL_AVB2_MDC_1)
+-#define MOD_SEL5_5 FM(SEL_AVB2_MAGIC_0) FM(SEL_AVB2_MAGIC_1)
+-#define MOD_SEL5_2 FM(SEL_AVB2_AVTP_MATCH_0) FM(SEL_AVB2_AVTP_MATCH_1)
+-#define MOD_SEL5_0 FM(SEL_AVB2_AVTP_PPS_0) FM(SEL_AVB2_AVTP_PPS_1)
+-
+-/* MOD_SEL6 */ /* 0 */ /* 1 */
+-#define MOD_SEL6_18 FM(SEL_AVB1_TD3_0) FM(SEL_AVB1_TD3_1)
+-#define MOD_SEL6_16 FM(SEL_AVB1_TD2_0) FM(SEL_AVB1_TD2_1)
+-#define MOD_SEL6_13 FM(SEL_AVB1_TD0_0) FM(SEL_AVB1_TD0_1)
+-#define MOD_SEL6_12 FM(SEL_AVB1_TD1_0) FM(SEL_AVB1_TD1_1)
+-#define MOD_SEL6_10 FM(SEL_AVB1_AVTP_PPS_0) FM(SEL_AVB1_AVTP_PPS_1)
+-#define MOD_SEL6_7 FM(SEL_AVB1_TX_CTL_0) FM(SEL_AVB1_TX_CTL_1)
+-#define MOD_SEL6_6 FM(SEL_AVB1_TXC_0) FM(SEL_AVB1_TXC_1)
+-#define MOD_SEL6_5 FM(SEL_AVB1_AVTP_MATCH_0) FM(SEL_AVB1_AVTP_MATCH_1)
+-#define MOD_SEL6_2 FM(SEL_AVB1_MDC_0) FM(SEL_AVB1_MDC_1)
+-#define MOD_SEL6_1 FM(SEL_AVB1_MAGIC_0) FM(SEL_AVB1_MAGIC_1)
+-
+-/* MOD_SEL7 */ /* 0 */ /* 1 */
+-#define MOD_SEL7_16 FM(SEL_AVB0_TX_CTL_0) FM(SEL_AVB0_TX_CTL_1)
+-#define MOD_SEL7_15 FM(SEL_AVB0_TXC_0) FM(SEL_AVB0_TXC_1)
+-#define MOD_SEL7_13 FM(SEL_AVB0_MDC_0) FM(SEL_AVB0_MDC_1)
+-#define MOD_SEL7_11 FM(SEL_AVB0_TD0_0) FM(SEL_AVB0_TD0_1)
+-#define MOD_SEL7_10 FM(SEL_AVB0_MAGIC_0) FM(SEL_AVB0_MAGIC_1)
+-#define MOD_SEL7_7 FM(SEL_AVB0_TD1_0) FM(SEL_AVB0_TD1_1)
+-#define MOD_SEL7_6 FM(SEL_AVB0_TD2_0) FM(SEL_AVB0_TD2_1)
+-#define MOD_SEL7_3 FM(SEL_AVB0_TD3_0) FM(SEL_AVB0_TD3_1)
+-#define MOD_SEL7_2 FM(SEL_AVB0_AVTP_MATCH_0) FM(SEL_AVB0_AVTP_MATCH_1)
+-#define MOD_SEL7_0 FM(SEL_AVB0_AVTP_PPS_0) FM(SEL_AVB0_AVTP_PPS_1)
+-
+ /* MOD_SEL8 */ /* 0 */ /* 1 */
+ #define MOD_SEL8_11 FM(SEL_SDA5_0) FM(SEL_SDA5_1)
+ #define MOD_SEL8_10 FM(SEL_SCL5_0) FM(SEL_SCL5_1)
+@@ -633,26 +665,18 @@ FM(IP0SR8_31_28) IP0SR8_31_28
+
+ #define PINMUX_MOD_SELS \
+ \
+-MOD_SEL4_19 MOD_SEL5_19 \
+-MOD_SEL4_18 MOD_SEL6_18 \
+- \
+- MOD_SEL5_16 MOD_SEL6_16 MOD_SEL7_16 \
+-MOD_SEL4_15 MOD_SEL5_15 MOD_SEL7_15 \
+-MOD_SEL4_14 \
+- MOD_SEL6_13 MOD_SEL7_13 \
+-MOD_SEL4_12 MOD_SEL5_12 MOD_SEL6_12 \
+- MOD_SEL5_11 MOD_SEL7_11 MOD_SEL8_11 \
+- MOD_SEL6_10 MOD_SEL7_10 MOD_SEL8_10 \
+-MOD_SEL4_9 MOD_SEL8_9 \
+-MOD_SEL4_8 MOD_SEL5_8 MOD_SEL8_8 \
+- MOD_SEL6_7 MOD_SEL7_7 MOD_SEL8_7 \
+- MOD_SEL5_6 MOD_SEL6_6 MOD_SEL7_6 MOD_SEL8_6 \
+-MOD_SEL4_5 MOD_SEL5_5 MOD_SEL6_5 MOD_SEL8_5 \
+- MOD_SEL8_4 \
+- MOD_SEL7_3 MOD_SEL8_3 \
+-MOD_SEL4_2 MOD_SEL5_2 MOD_SEL6_2 MOD_SEL7_2 MOD_SEL8_2 \
+-MOD_SEL4_1 MOD_SEL6_1 MOD_SEL8_1 \
+- MOD_SEL5_0 MOD_SEL7_0 MOD_SEL8_0
++MOD_SEL8_11 \
++MOD_SEL8_10 \
++MOD_SEL8_9 \
++MOD_SEL8_8 \
++MOD_SEL8_7 \
++MOD_SEL8_6 \
++MOD_SEL8_5 \
++MOD_SEL8_4 \
++MOD_SEL8_3 \
++MOD_SEL8_2 \
++MOD_SEL8_1 \
++MOD_SEL8_0
+
+ enum {
+ PINMUX_RESERVED = 0,
+@@ -686,61 +710,8 @@ enum {
+ static const u16 pinmux_data[] = {
+ PINMUX_DATA_GP_ALL(),
+
+- PINMUX_SINGLE(AVS1),
+- PINMUX_SINGLE(AVS0),
+- PINMUX_SINGLE(PCIE1_CLKREQ_N),
+- PINMUX_SINGLE(PCIE0_CLKREQ_N),
+-
+- /* TSN0 without MODSEL4 */
+- PINMUX_SINGLE(TSN0_TXCREFCLK),
+- PINMUX_SINGLE(TSN0_RD2),
+- PINMUX_SINGLE(TSN0_RD3),
+- PINMUX_SINGLE(TSN0_RD1),
+- PINMUX_SINGLE(TSN0_RXC),
+- PINMUX_SINGLE(TSN0_RD0),
+- PINMUX_SINGLE(TSN0_RX_CTL),
+- PINMUX_SINGLE(TSN0_AVTP_CAPTURE),
+- PINMUX_SINGLE(TSN0_LINK),
+- PINMUX_SINGLE(TSN0_PHY_INT),
+- PINMUX_SINGLE(TSN0_MDIO),
+- /* TSN0 with MODSEL4 */
+- PINMUX_IPSR_NOGM(0, TSN0_TD2, SEL_TSN0_TD2_1),
+- PINMUX_IPSR_NOGM(0, TSN0_TD3, SEL_TSN0_TD3_1),
+- PINMUX_IPSR_NOGM(0, TSN0_TD0, SEL_TSN0_TD0_1),
+- PINMUX_IPSR_NOGM(0, TSN0_TD1, SEL_TSN0_TD1_1),
+- PINMUX_IPSR_NOGM(0, TSN0_TXC, SEL_TSN0_TXC_1),
+- PINMUX_IPSR_NOGM(0, TSN0_TX_CTL, SEL_TSN0_TX_CTL_1),
+- PINMUX_IPSR_NOGM(0, TSN0_AVTP_PPS0, SEL_TSN0_AVTP_PPS0_1),
+- PINMUX_IPSR_NOGM(0, TSN0_AVTP_MATCH, SEL_TSN0_AVTP_MATCH_1),
+- PINMUX_IPSR_NOGM(0, TSN0_AVTP_PPS1, SEL_TSN0_AVTP_PPS1_1),
+- PINMUX_IPSR_NOGM(0, TSN0_MDC, SEL_TSN0_MDC_1),
+-
+- /* TSN0 without MODSEL5 */
+- PINMUX_SINGLE(AVB2_RX_CTL),
+- PINMUX_SINGLE(AVB2_RXC),
+- PINMUX_SINGLE(AVB2_RD0),
+- PINMUX_SINGLE(AVB2_RD1),
+- PINMUX_SINGLE(AVB2_RD2),
+- PINMUX_SINGLE(AVB2_MDIO),
+- PINMUX_SINGLE(AVB2_RD3),
+- PINMUX_SINGLE(AVB2_TXCREFCLK),
+- PINMUX_SINGLE(AVB2_PHY_INT),
+- PINMUX_SINGLE(AVB2_LINK),
+- PINMUX_SINGLE(AVB2_AVTP_CAPTURE),
+- /* TSN0 with MODSEL5 */
+- PINMUX_IPSR_NOGM(0, AVB2_TX_CTL, SEL_AVB2_TX_CTL_1),
+- PINMUX_IPSR_NOGM(0, AVB2_TXC, SEL_AVB2_TXC_1),
+- PINMUX_IPSR_NOGM(0, AVB2_TD0, SEL_AVB2_TD0_1),
+- PINMUX_IPSR_NOGM(0, AVB2_TD1, SEL_AVB2_TD1_1),
+- PINMUX_IPSR_NOGM(0, AVB2_TD2, SEL_AVB2_TD2_1),
+- PINMUX_IPSR_NOGM(0, AVB2_TD3, SEL_AVB2_TD3_1),
+- PINMUX_IPSR_NOGM(0, AVB2_MDC, SEL_AVB2_MDC_1),
+- PINMUX_IPSR_NOGM(0, AVB2_MAGIC, SEL_AVB2_MAGIC_1),
+- PINMUX_IPSR_NOGM(0, AVB2_AVTP_MATCH, SEL_AVB2_AVTP_MATCH_1),
+- PINMUX_IPSR_NOGM(0, AVB2_AVTP_PPS, SEL_AVB2_AVTP_PPS_1),
+-
+ /* IP0SR0 */
+- PINMUX_IPSR_GPSR(IP0SR0_3_0, ERROROUTC_B),
++ PINMUX_IPSR_GPSR(IP0SR0_3_0, ERROROUTC_N_B),
+ PINMUX_IPSR_GPSR(IP0SR0_3_0, TCLK2_A),
+
+ PINMUX_IPSR_GPSR(IP0SR0_7_4, MSIOF3_SS1),
+@@ -1006,7 +977,7 @@ static const u16 pinmux_data[] = {
+
+ PINMUX_IPSR_GPSR(IP1SR3_27_24, IPC_CLKOUT),
+ PINMUX_IPSR_GPSR(IP1SR3_27_24, IPC_CLKEN_OUT),
+- PINMUX_IPSR_GPSR(IP1SR3_27_24, ERROROUTC_A),
++ PINMUX_IPSR_GPSR(IP1SR3_27_24, ERROROUTC_N_A),
+ PINMUX_IPSR_GPSR(IP1SR3_27_24, TCLK4_X),
+
+ PINMUX_IPSR_GPSR(IP1SR3_31_28, QSPI0_SSL),
+@@ -1029,26 +1000,86 @@ static const u16 pinmux_data[] = {
+ PINMUX_IPSR_GPSR(IP3SR3_19_16, RPC_WP_N),
+ PINMUX_IPSR_GPSR(IP3SR3_23_20, RPC_INT_N),
+
++ /* IP0SR4 */
++ PINMUX_IPSR_GPSR(IP0SR4_3_0, TSN0_MDIO),
++ PINMUX_IPSR_GPSR(IP0SR4_7_4, TSN0_MDC),
++ PINMUX_IPSR_GPSR(IP0SR4_11_8, TSN0_AVTP_PPS1),
++ PINMUX_IPSR_GPSR(IP0SR4_15_12, TSN0_PHY_INT),
++ PINMUX_IPSR_GPSR(IP0SR4_19_16, TSN0_LINK),
++ PINMUX_IPSR_GPSR(IP0SR4_23_20, TSN0_AVTP_MATCH),
++ PINMUX_IPSR_GPSR(IP0SR4_27_24, TSN0_AVTP_CAPTURE),
++ PINMUX_IPSR_GPSR(IP0SR4_31_28, TSN0_RX_CTL),
++
++ /* IP1SR4 */
++ PINMUX_IPSR_GPSR(IP1SR4_3_0, TSN0_AVTP_PPS0),
++ PINMUX_IPSR_GPSR(IP1SR4_7_4, TSN0_TX_CTL),
++ PINMUX_IPSR_GPSR(IP1SR4_11_8, TSN0_RD0),
++ PINMUX_IPSR_GPSR(IP1SR4_15_12, TSN0_RXC),
++ PINMUX_IPSR_GPSR(IP1SR4_19_16, TSN0_TXC),
++ PINMUX_IPSR_GPSR(IP1SR4_23_20, TSN0_RD1),
++ PINMUX_IPSR_GPSR(IP1SR4_27_24, TSN0_TD1),
++ PINMUX_IPSR_GPSR(IP1SR4_31_28, TSN0_TD0),
++
++ /* IP2SR4 */
++ PINMUX_IPSR_GPSR(IP2SR4_3_0, TSN0_RD3),
++ PINMUX_IPSR_GPSR(IP2SR4_7_4, TSN0_RD2),
++ PINMUX_IPSR_GPSR(IP2SR4_11_8, TSN0_TD3),
++ PINMUX_IPSR_GPSR(IP2SR4_15_12, TSN0_TD2),
++ PINMUX_IPSR_GPSR(IP2SR4_19_16, TSN0_TXCREFCLK),
++ PINMUX_IPSR_GPSR(IP2SR4_23_20, PCIE0_CLKREQ_N),
++ PINMUX_IPSR_GPSR(IP2SR4_27_24, PCIE1_CLKREQ_N),
++ PINMUX_IPSR_GPSR(IP2SR4_31_28, AVS0),
++
++ /* IP3SR4 */
++ PINMUX_IPSR_GPSR(IP3SR4_3_0, AVS1),
++
++ /* IP0SR5 */
++ PINMUX_IPSR_GPSR(IP0SR5_3_0, AVB2_AVTP_PPS),
++ PINMUX_IPSR_GPSR(IP0SR5_7_4, AVB2_AVTP_CAPTURE),
++ PINMUX_IPSR_GPSR(IP0SR5_11_8, AVB2_AVTP_MATCH),
++ PINMUX_IPSR_GPSR(IP0SR5_15_12, AVB2_LINK),
++ PINMUX_IPSR_GPSR(IP0SR5_19_16, AVB2_PHY_INT),
++ PINMUX_IPSR_GPSR(IP0SR5_23_20, AVB2_MAGIC),
++ PINMUX_IPSR_GPSR(IP0SR5_27_24, AVB2_MDC),
++ PINMUX_IPSR_GPSR(IP0SR5_31_28, AVB2_TXCREFCLK),
++
++ /* IP1SR5 */
++ PINMUX_IPSR_GPSR(IP1SR5_3_0, AVB2_TD3),
++ PINMUX_IPSR_GPSR(IP1SR5_7_4, AVB2_RD3),
++ PINMUX_IPSR_GPSR(IP1SR5_11_8, AVB2_MDIO),
++ PINMUX_IPSR_GPSR(IP1SR5_15_12, AVB2_TD2),
++ PINMUX_IPSR_GPSR(IP1SR5_19_16, AVB2_TD1),
++ PINMUX_IPSR_GPSR(IP1SR5_23_20, AVB2_RD2),
++ PINMUX_IPSR_GPSR(IP1SR5_27_24, AVB2_RD1),
++ PINMUX_IPSR_GPSR(IP1SR5_31_28, AVB2_TD0),
++
++ /* IP2SR5 */
++ PINMUX_IPSR_GPSR(IP2SR5_3_0, AVB2_TXC),
++ PINMUX_IPSR_GPSR(IP2SR5_7_4, AVB2_RD0),
++ PINMUX_IPSR_GPSR(IP2SR5_11_8, AVB2_RXC),
++ PINMUX_IPSR_GPSR(IP2SR5_15_12, AVB2_TX_CTL),
++ PINMUX_IPSR_GPSR(IP2SR5_19_16, AVB2_RX_CTL),
++
+ /* IP0SR6 */
+ PINMUX_IPSR_GPSR(IP0SR6_3_0, AVB1_MDIO),
+
+- PINMUX_IPSR_MSEL(IP0SR6_7_4, AVB1_MAGIC, SEL_AVB1_MAGIC_1),
++ PINMUX_IPSR_GPSR(IP0SR6_7_4, AVB1_MAGIC),
+
+- PINMUX_IPSR_MSEL(IP0SR6_11_8, AVB1_MDC, SEL_AVB1_MDC_1),
++ PINMUX_IPSR_GPSR(IP0SR6_11_8, AVB1_MDC),
+
+ PINMUX_IPSR_GPSR(IP0SR6_15_12, AVB1_PHY_INT),
+
+ PINMUX_IPSR_GPSR(IP0SR6_19_16, AVB1_LINK),
+ PINMUX_IPSR_GPSR(IP0SR6_19_16, AVB1_MII_TX_ER),
+
+- PINMUX_IPSR_MSEL(IP0SR6_23_20, AVB1_AVTP_MATCH, SEL_AVB1_AVTP_MATCH_1),
+- PINMUX_IPSR_MSEL(IP0SR6_23_20, AVB1_MII_RX_ER, SEL_AVB1_AVTP_MATCH_0),
++ PINMUX_IPSR_GPSR(IP0SR6_23_20, AVB1_AVTP_MATCH),
++ PINMUX_IPSR_GPSR(IP0SR6_23_20, AVB1_MII_RX_ER),
+
+- PINMUX_IPSR_MSEL(IP0SR6_27_24, AVB1_TXC, SEL_AVB1_TXC_1),
+- PINMUX_IPSR_MSEL(IP0SR6_27_24, AVB1_MII_TXC, SEL_AVB1_TXC_0),
++ PINMUX_IPSR_GPSR(IP0SR6_27_24, AVB1_TXC),
++ PINMUX_IPSR_GPSR(IP0SR6_27_24, AVB1_MII_TXC),
+
+- PINMUX_IPSR_MSEL(IP0SR6_31_28, AVB1_TX_CTL, SEL_AVB1_TX_CTL_1),
+- PINMUX_IPSR_MSEL(IP0SR6_31_28, AVB1_MII_TX_EN, SEL_AVB1_TX_CTL_0),
++ PINMUX_IPSR_GPSR(IP0SR6_31_28, AVB1_TX_CTL),
++ PINMUX_IPSR_GPSR(IP0SR6_31_28, AVB1_MII_TX_EN),
+
+ /* IP1SR6 */
+ PINMUX_IPSR_GPSR(IP1SR6_3_0, AVB1_RXC),
+@@ -1057,17 +1088,17 @@ static const u16 pinmux_data[] = {
+ PINMUX_IPSR_GPSR(IP1SR6_7_4, AVB1_RX_CTL),
+ PINMUX_IPSR_GPSR(IP1SR6_7_4, AVB1_MII_RX_DV),
+
+- PINMUX_IPSR_MSEL(IP1SR6_11_8, AVB1_AVTP_PPS, SEL_AVB1_AVTP_PPS_1),
+- PINMUX_IPSR_MSEL(IP1SR6_11_8, AVB1_MII_COL, SEL_AVB1_AVTP_PPS_0),
++ PINMUX_IPSR_GPSR(IP1SR6_11_8, AVB1_AVTP_PPS),
++ PINMUX_IPSR_GPSR(IP1SR6_11_8, AVB1_MII_COL),
+
+ PINMUX_IPSR_GPSR(IP1SR6_15_12, AVB1_AVTP_CAPTURE),
+ PINMUX_IPSR_GPSR(IP1SR6_15_12, AVB1_MII_CRS),
+
+- PINMUX_IPSR_MSEL(IP1SR6_19_16, AVB1_TD1, SEL_AVB1_TD1_1),
+- PINMUX_IPSR_MSEL(IP1SR6_19_16, AVB1_MII_TD1, SEL_AVB1_TD1_0),
++ PINMUX_IPSR_GPSR(IP1SR6_19_16, AVB1_TD1),
++ PINMUX_IPSR_GPSR(IP1SR6_19_16, AVB1_MII_TD1),
+
+- PINMUX_IPSR_MSEL(IP1SR6_23_20, AVB1_TD0, SEL_AVB1_TD0_1),
+- PINMUX_IPSR_MSEL(IP1SR6_23_20, AVB1_MII_TD0, SEL_AVB1_TD0_0),
++ PINMUX_IPSR_GPSR(IP1SR6_23_20, AVB1_TD0),
++ PINMUX_IPSR_GPSR(IP1SR6_23_20, AVB1_MII_TD0),
+
+ PINMUX_IPSR_GPSR(IP1SR6_27_24, AVB1_RD1),
+ PINMUX_IPSR_GPSR(IP1SR6_27_24, AVB1_MII_RD1),
+@@ -1076,14 +1107,14 @@ static const u16 pinmux_data[] = {
+ PINMUX_IPSR_GPSR(IP1SR6_31_28, AVB1_MII_RD0),
+
+ /* IP2SR6 */
+- PINMUX_IPSR_MSEL(IP2SR6_3_0, AVB1_TD2, SEL_AVB1_TD2_1),
+- PINMUX_IPSR_MSEL(IP2SR6_3_0, AVB1_MII_TD2, SEL_AVB1_TD2_0),
++ PINMUX_IPSR_GPSR(IP2SR6_3_0, AVB1_TD2),
++ PINMUX_IPSR_GPSR(IP2SR6_3_0, AVB1_MII_TD2),
+
+ PINMUX_IPSR_GPSR(IP2SR6_7_4, AVB1_RD2),
+ PINMUX_IPSR_GPSR(IP2SR6_7_4, AVB1_MII_RD2),
+
+- PINMUX_IPSR_MSEL(IP2SR6_11_8, AVB1_TD3, SEL_AVB1_TD3_1),
+- PINMUX_IPSR_MSEL(IP2SR6_11_8, AVB1_MII_TD3, SEL_AVB1_TD3_0),
++ PINMUX_IPSR_GPSR(IP2SR6_11_8, AVB1_TD3),
++ PINMUX_IPSR_GPSR(IP2SR6_11_8, AVB1_MII_TD3),
+
+ PINMUX_IPSR_GPSR(IP2SR6_15_12, AVB1_RD3),
+ PINMUX_IPSR_GPSR(IP2SR6_15_12, AVB1_MII_RD3),
+@@ -1091,29 +1122,29 @@ static const u16 pinmux_data[] = {
+ PINMUX_IPSR_GPSR(IP2SR6_19_16, AVB1_TXCREFCLK),
+
+ /* IP0SR7 */
+- PINMUX_IPSR_MSEL(IP0SR7_3_0, AVB0_AVTP_PPS, SEL_AVB0_AVTP_PPS_1),
+- PINMUX_IPSR_MSEL(IP0SR7_3_0, AVB0_MII_COL, SEL_AVB0_AVTP_PPS_0),
++ PINMUX_IPSR_GPSR(IP0SR7_3_0, AVB0_AVTP_PPS),
++ PINMUX_IPSR_GPSR(IP0SR7_3_0, AVB0_MII_COL),
+
+ PINMUX_IPSR_GPSR(IP0SR7_7_4, AVB0_AVTP_CAPTURE),
+ PINMUX_IPSR_GPSR(IP0SR7_7_4, AVB0_MII_CRS),
+
+- PINMUX_IPSR_MSEL(IP0SR7_11_8, AVB0_AVTP_MATCH, SEL_AVB0_AVTP_MATCH_1),
+- PINMUX_IPSR_MSEL(IP0SR7_11_8, AVB0_MII_RX_ER, SEL_AVB0_AVTP_MATCH_0),
+- PINMUX_IPSR_MSEL(IP0SR7_11_8, CC5_OSCOUT, SEL_AVB0_AVTP_MATCH_0),
++ PINMUX_IPSR_GPSR(IP0SR7_11_8, AVB0_AVTP_MATCH),
++ PINMUX_IPSR_GPSR(IP0SR7_11_8, AVB0_MII_RX_ER),
++ PINMUX_IPSR_GPSR(IP0SR7_11_8, CC5_OSCOUT),
+
+- PINMUX_IPSR_MSEL(IP0SR7_15_12, AVB0_TD3, SEL_AVB0_TD3_1),
+- PINMUX_IPSR_MSEL(IP0SR7_15_12, AVB0_MII_TD3, SEL_AVB0_TD3_0),
++ PINMUX_IPSR_GPSR(IP0SR7_15_12, AVB0_TD3),
++ PINMUX_IPSR_GPSR(IP0SR7_15_12, AVB0_MII_TD3),
+
+ PINMUX_IPSR_GPSR(IP0SR7_19_16, AVB0_LINK),
+ PINMUX_IPSR_GPSR(IP0SR7_19_16, AVB0_MII_TX_ER),
+
+ PINMUX_IPSR_GPSR(IP0SR7_23_20, AVB0_PHY_INT),
+
+- PINMUX_IPSR_MSEL(IP0SR7_27_24, AVB0_TD2, SEL_AVB0_TD2_1),
+- PINMUX_IPSR_MSEL(IP0SR7_27_24, AVB0_MII_TD2, SEL_AVB0_TD2_0),
++ PINMUX_IPSR_GPSR(IP0SR7_27_24, AVB0_TD2),
++ PINMUX_IPSR_GPSR(IP0SR7_27_24, AVB0_MII_TD2),
+
+- PINMUX_IPSR_MSEL(IP0SR7_31_28, AVB0_TD1, SEL_AVB0_TD1_1),
+- PINMUX_IPSR_MSEL(IP0SR7_31_28, AVB0_MII_TD1, SEL_AVB0_TD1_0),
++ PINMUX_IPSR_GPSR(IP0SR7_31_28, AVB0_TD1),
++ PINMUX_IPSR_GPSR(IP0SR7_31_28, AVB0_MII_TD1),
+
+ /* IP1SR7 */
+ PINMUX_IPSR_GPSR(IP1SR7_3_0, AVB0_RD3),
+@@ -1121,24 +1152,24 @@ static const u16 pinmux_data[] = {
+
+ PINMUX_IPSR_GPSR(IP1SR7_7_4, AVB0_TXCREFCLK),
+
+- PINMUX_IPSR_MSEL(IP1SR7_11_8, AVB0_MAGIC, SEL_AVB0_MAGIC_1),
++ PINMUX_IPSR_GPSR(IP1SR7_11_8, AVB0_MAGIC),
+
+- PINMUX_IPSR_MSEL(IP1SR7_15_12, AVB0_TD0, SEL_AVB0_TD0_1),
+- PINMUX_IPSR_MSEL(IP1SR7_15_12, AVB0_MII_TD0, SEL_AVB0_TD0_0),
++ PINMUX_IPSR_GPSR(IP1SR7_15_12, AVB0_TD0),
++ PINMUX_IPSR_GPSR(IP1SR7_15_12, AVB0_MII_TD0),
+
+ PINMUX_IPSR_GPSR(IP1SR7_19_16, AVB0_RD2),
+ PINMUX_IPSR_GPSR(IP1SR7_19_16, AVB0_MII_RD2),
+
+- PINMUX_IPSR_MSEL(IP1SR7_23_20, AVB0_MDC, SEL_AVB0_MDC_1),
++ PINMUX_IPSR_GPSR(IP1SR7_23_20, AVB0_MDC),
+
+ PINMUX_IPSR_GPSR(IP1SR7_27_24, AVB0_MDIO),
+
+- PINMUX_IPSR_MSEL(IP1SR7_31_28, AVB0_TXC, SEL_AVB0_TXC_1),
+- PINMUX_IPSR_MSEL(IP1SR7_31_28, AVB0_MII_TXC, SEL_AVB0_TXC_0),
++ PINMUX_IPSR_GPSR(IP1SR7_31_28, AVB0_TXC),
++ PINMUX_IPSR_GPSR(IP1SR7_31_28, AVB0_MII_TXC),
+
+ /* IP2SR7 */
+- PINMUX_IPSR_MSEL(IP2SR7_3_0, AVB0_TX_CTL, SEL_AVB0_TX_CTL_1),
+- PINMUX_IPSR_MSEL(IP2SR7_3_0, AVB0_MII_TX_EN, SEL_AVB0_TX_CTL_0),
++ PINMUX_IPSR_GPSR(IP2SR7_3_0, AVB0_TX_CTL),
++ PINMUX_IPSR_GPSR(IP2SR7_3_0, AVB0_MII_TX_EN),
+
+ PINMUX_IPSR_GPSR(IP2SR7_7_4, AVB0_RD1),
+ PINMUX_IPSR_GPSR(IP2SR7_7_4, AVB0_MII_RD1),
+@@ -3419,6 +3450,82 @@ static const struct pinmux_cfg_reg pinmux_config_regs[] = {
+ IP3SR3_7_4
+ IP3SR3_3_0))
+ },
++ { PINMUX_CFG_REG_VAR("IP0SR4", 0xE6060060, 32,
++ GROUP(4, 4, 4, 4, 4, 4, 4, 4),
++ GROUP(
++ IP0SR4_31_28
++ IP0SR4_27_24
++ IP0SR4_23_20
++ IP0SR4_19_16
++ IP0SR4_15_12
++ IP0SR4_11_8
++ IP0SR4_7_4
++ IP0SR4_3_0))
++ },
++ { PINMUX_CFG_REG_VAR("IP1SR4", 0xE6060064, 32,
++ GROUP(4, 4, 4, 4, 4, 4, 4, 4),
++ GROUP(
++ IP1SR4_31_28
++ IP1SR4_27_24
++ IP1SR4_23_20
++ IP1SR4_19_16
++ IP1SR4_15_12
++ IP1SR4_11_8
++ IP1SR4_7_4
++ IP1SR4_3_0))
++ },
++ { PINMUX_CFG_REG_VAR("IP2SR4", 0xE6060068, 32,
++ GROUP(4, 4, 4, 4, 4, 4, 4, 4),
++ GROUP(
++ IP2SR4_31_28
++ IP2SR4_27_24
++ IP2SR4_23_20
++ IP2SR4_19_16
++ IP2SR4_15_12
++ IP2SR4_11_8
++ IP2SR4_7_4
++ IP2SR4_3_0))
++ },
++ { PINMUX_CFG_REG_VAR("IP3SR4", 0xE606006C, 32,
++ GROUP(-28, 4),
++ GROUP(
++ /* IP3SR4_31_4 RESERVED */
++ IP3SR4_3_0))
++ },
++ { PINMUX_CFG_REG_VAR("IP0SR5", 0xE6060860, 32,
++ GROUP(4, 4, 4, 4, 4, 4, 4, 4),
++ GROUP(
++ IP0SR5_31_28
++ IP0SR5_27_24
++ IP0SR5_23_20
++ IP0SR5_19_16
++ IP0SR5_15_12
++ IP0SR5_11_8
++ IP0SR5_7_4
++ IP0SR5_3_0))
++ },
++ { PINMUX_CFG_REG_VAR("IP1SR5", 0xE6060864, 32,
++ GROUP(4, 4, 4, 4, 4, 4, 4, 4),
++ GROUP(
++ IP1SR5_31_28
++ IP1SR5_27_24
++ IP1SR5_23_20
++ IP1SR5_19_16
++ IP1SR5_15_12
++ IP1SR5_11_8
++ IP1SR5_7_4
++ IP1SR5_3_0))
++ },
++ { PINMUX_CFG_REG_VAR("IP2SR5", 0xE6060868, 32,
++ GROUP(-12, 4, 4, 4, 4, 4),
++ GROUP(
++ /* IP2SR5_31_20 RESERVED */
++ IP2SR5_19_16
++ IP2SR5_15_12
++ IP2SR5_11_8
++ IP2SR5_7_4
++ IP2SR5_3_0))
++ },
+ { PINMUX_CFG_REG("IP0SR6", 0xE6061060, 32, 4, GROUP(
+ IP0SR6_31_28
+ IP0SR6_27_24
+@@ -3505,95 +3612,6 @@ static const struct pinmux_cfg_reg pinmux_config_regs[] = {
+
+ #define F_(x, y) x,
+ #define FM(x) FN_##x,
+- { PINMUX_CFG_REG_VAR("MOD_SEL4", 0xE6060100, 32,
+- GROUP(-12, 1, 1, -2, 1, 1, -1, 1, -2, 1, 1, -2, 1,
+- -2, 1, 1, -1),
+- GROUP(
+- /* RESERVED 31-20 */
+- MOD_SEL4_19
+- MOD_SEL4_18
+- /* RESERVED 17-16 */
+- MOD_SEL4_15
+- MOD_SEL4_14
+- /* RESERVED 13 */
+- MOD_SEL4_12
+- /* RESERVED 11-10 */
+- MOD_SEL4_9
+- MOD_SEL4_8
+- /* RESERVED 7-6 */
+- MOD_SEL4_5
+- /* RESERVED 4-3 */
+- MOD_SEL4_2
+- MOD_SEL4_1
+- /* RESERVED 0 */
+- ))
+- },
+- { PINMUX_CFG_REG_VAR("MOD_SEL5", 0xE6060900, 32,
+- GROUP(-12, 1, -2, 1, 1, -2, 1, 1, -2, 1, -1,
+- 1, 1, -2, 1, -1, 1),
+- GROUP(
+- /* RESERVED 31-20 */
+- MOD_SEL5_19
+- /* RESERVED 18-17 */
+- MOD_SEL5_16
+- MOD_SEL5_15
+- /* RESERVED 14-13 */
+- MOD_SEL5_12
+- MOD_SEL5_11
+- /* RESERVED 10-9 */
+- MOD_SEL5_8
+- /* RESERVED 7 */
+- MOD_SEL5_6
+- MOD_SEL5_5
+- /* RESERVED 4-3 */
+- MOD_SEL5_2
+- /* RESERVED 1 */
+- MOD_SEL5_0))
+- },
+- { PINMUX_CFG_REG_VAR("MOD_SEL6", 0xE6061100, 32,
+- GROUP(-13, 1, -1, 1, -2, 1, 1,
+- -1, 1, -2, 1, 1, 1, -2, 1, 1, -1),
+- GROUP(
+- /* RESERVED 31-19 */
+- MOD_SEL6_18
+- /* RESERVED 17 */
+- MOD_SEL6_16
+- /* RESERVED 15-14 */
+- MOD_SEL6_13
+- MOD_SEL6_12
+- /* RESERVED 11 */
+- MOD_SEL6_10
+- /* RESERVED 9-8 */
+- MOD_SEL6_7
+- MOD_SEL6_6
+- MOD_SEL6_5
+- /* RESERVED 4-3 */
+- MOD_SEL6_2
+- MOD_SEL6_1
+- /* RESERVED 0 */
+- ))
+- },
+- { PINMUX_CFG_REG_VAR("MOD_SEL7", 0xE6061900, 32,
+- GROUP(-15, 1, 1, -1, 1, -1, 1, 1, -2, 1, 1,
+- -2, 1, 1, -1, 1),
+- GROUP(
+- /* RESERVED 31-17 */
+- MOD_SEL7_16
+- MOD_SEL7_15
+- /* RESERVED 14 */
+- MOD_SEL7_13
+- /* RESERVED 12 */
+- MOD_SEL7_11
+- MOD_SEL7_10
+- /* RESERVED 9-8 */
+- MOD_SEL7_7
+- MOD_SEL7_6
+- /* RESERVED 5-4 */
+- MOD_SEL7_3
+- MOD_SEL7_2
+- /* RESERVED 1 */
+- MOD_SEL7_0))
+- },
+ { PINMUX_CFG_REG_VAR("MOD_SEL8", 0xE6068100, 32,
+ GROUP(-20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
+ GROUP(
+diff --git a/drivers/platform/chrome/cros_typec_switch.c b/drivers/platform/chrome/cros_typec_switch.c
+index a26219e97c931..26af51952f7f1 100644
+--- a/drivers/platform/chrome/cros_typec_switch.c
++++ b/drivers/platform/chrome/cros_typec_switch.c
+@@ -268,6 +268,7 @@ static int cros_typec_register_switches(struct cros_typec_switch_data *sdata)
+
+ return 0;
+ err_switch:
++ fwnode_handle_put(fwnode);
+ cros_typec_unregister_switches(sdata);
+ return ret;
+ }
+diff --git a/drivers/platform/x86/amd/Kconfig b/drivers/platform/x86/amd/Kconfig
+index 2ce8cb2170dfc..d9685aef0887d 100644
+--- a/drivers/platform/x86/amd/Kconfig
++++ b/drivers/platform/x86/amd/Kconfig
+@@ -7,7 +7,7 @@ source "drivers/platform/x86/amd/pmf/Kconfig"
+
+ config AMD_PMC
+ tristate "AMD SoC PMC driver"
+- depends on ACPI && PCI && RTC_CLASS
++ depends on ACPI && PCI && RTC_CLASS && AMD_NB
+ select SERIO
+ help
+ The driver provides support for AMD Power Management Controller
+diff --git a/drivers/platform/x86/amd/pmc.c b/drivers/platform/x86/amd/pmc.c
+index 3cbb01ec10e32..45b0050dfbf7b 100644
+--- a/drivers/platform/x86/amd/pmc.c
++++ b/drivers/platform/x86/amd/pmc.c
+@@ -10,6 +10,7 @@
+
+ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
++#include <asm/amd_nb.h>
+ #include <linux/acpi.h>
+ #include <linux/bitfield.h>
+ #include <linux/bits.h>
+@@ -37,8 +38,6 @@
+ #define AMD_PMC_SCRATCH_REG_YC 0xD14
+
+ /* STB Registers */
+-#define AMD_PMC_STB_INDEX_ADDRESS 0xF8
+-#define AMD_PMC_STB_INDEX_DATA 0xFC
+ #define AMD_PMC_STB_PMI_0 0x03E30600
+ #define AMD_PMC_STB_S2IDLE_PREPARE 0xC6000001
+ #define AMD_PMC_STB_S2IDLE_RESTORE 0xC6000002
+@@ -55,8 +54,6 @@
+ #define S2D_TELEMETRY_DRAMBYTES_MAX 0x1000000
+
+ /* Base address of SMU for mapping physical address to virtual address */
+-#define AMD_PMC_SMU_INDEX_ADDRESS 0xB8
+-#define AMD_PMC_SMU_INDEX_DATA 0xBC
+ #define AMD_PMC_MAPPING_SIZE 0x01000
+ #define AMD_PMC_BASE_ADDR_OFFSET 0x10000
+ #define AMD_PMC_BASE_ADDR_LO 0x13B102E8
+@@ -314,33 +311,6 @@ static int amd_pmc_setup_smu_logging(struct amd_pmc_dev *dev)
+ return 0;
+ }
+
+-static int amd_pmc_idlemask_read(struct amd_pmc_dev *pdev, struct device *dev,
+- struct seq_file *s)
+-{
+- u32 val;
+-
+- switch (pdev->cpu_id) {
+- case AMD_CPU_ID_CZN:
+- val = amd_pmc_reg_read(pdev, AMD_PMC_SCRATCH_REG_CZN);
+- break;
+- case AMD_CPU_ID_YC:
+- case AMD_CPU_ID_CB:
+- case AMD_CPU_ID_PS:
+- val = amd_pmc_reg_read(pdev, AMD_PMC_SCRATCH_REG_YC);
+- break;
+- default:
+- return -EINVAL;
+- }
+-
+- if (dev)
+- dev_dbg(pdev->dev, "SMU idlemask s0i3: 0x%x\n", val);
+-
+- if (s)
+- seq_printf(s, "SMU idlemask : 0x%x\n", val);
+-
+- return 0;
+-}
+-
+ static int get_metrics_table(struct amd_pmc_dev *pdev, struct smu_metrics *table)
+ {
+ if (!pdev->smu_virt_addr) {
+@@ -377,6 +347,9 @@ static int amd_pmc_get_smu_version(struct amd_pmc_dev *dev)
+ int rc;
+ u32 val;
+
++ if (dev->cpu_id == AMD_CPU_ID_PCO)
++ return -ENODEV;
++
+ rc = amd_pmc_send_cmd(dev, 0, &val, SMU_MSG_GETSMUVERSION, 1);
+ if (rc)
+ return rc;
+@@ -423,12 +396,31 @@ static ssize_t smu_program_show(struct device *d, struct device_attribute *attr,
+ static DEVICE_ATTR_RO(smu_fw_version);
+ static DEVICE_ATTR_RO(smu_program);
+
++static umode_t pmc_attr_is_visible(struct kobject *kobj, struct attribute *attr, int idx)
++{
++ struct device *dev = kobj_to_dev(kobj);
++ struct amd_pmc_dev *pdev = dev_get_drvdata(dev);
++
++ if (pdev->cpu_id == AMD_CPU_ID_PCO)
++ return 0;
++ return 0444;
++}
++
+ static struct attribute *pmc_attrs[] = {
+ &dev_attr_smu_fw_version.attr,
+ &dev_attr_smu_program.attr,
+ NULL,
+ };
+-ATTRIBUTE_GROUPS(pmc);
++
++static struct attribute_group pmc_attr_group = {
++ .attrs = pmc_attrs,
++ .is_visible = pmc_attr_is_visible,
++};
++
++static const struct attribute_group *pmc_groups[] = {
++ &pmc_attr_group,
++ NULL,
++};
+
+ static int smu_fw_info_show(struct seq_file *s, void *unused)
+ {
+@@ -495,28 +487,47 @@ static int s0ix_stats_show(struct seq_file *s, void *unused)
+ }
+ DEFINE_SHOW_ATTRIBUTE(s0ix_stats);
+
+-static int amd_pmc_idlemask_show(struct seq_file *s, void *unused)
++static int amd_pmc_idlemask_read(struct amd_pmc_dev *pdev, struct device *dev,
++ struct seq_file *s)
+ {
+- struct amd_pmc_dev *dev = s->private;
++ u32 val;
+ int rc;
+
+- /* we haven't yet read SMU version */
+- if (!dev->major) {
+- rc = amd_pmc_get_smu_version(dev);
+- if (rc)
+- return rc;
++ switch (pdev->cpu_id) {
++ case AMD_CPU_ID_CZN:
++ /* we haven't yet read SMU version */
++ if (!pdev->major) {
++ rc = amd_pmc_get_smu_version(pdev);
++ if (rc)
++ return rc;
++ }
++ if (pdev->major > 56 || (pdev->major >= 55 && pdev->minor >= 37))
++ val = amd_pmc_reg_read(pdev, AMD_PMC_SCRATCH_REG_CZN);
++ else
++ return -EINVAL;
++ break;
++ case AMD_CPU_ID_YC:
++ case AMD_CPU_ID_CB:
++ case AMD_CPU_ID_PS:
++ val = amd_pmc_reg_read(pdev, AMD_PMC_SCRATCH_REG_YC);
++ break;
++ default:
++ return -EINVAL;
+ }
+
+- if (dev->major > 56 || (dev->major >= 55 && dev->minor >= 37)) {
+- rc = amd_pmc_idlemask_read(dev, NULL, s);
+- if (rc)
+- return rc;
+- } else {
+- seq_puts(s, "Unsupported SMU version for Idlemask\n");
+- }
++ if (dev)
++ dev_dbg(pdev->dev, "SMU idlemask s0i3: 0x%x\n", val);
++
++ if (s)
++ seq_printf(s, "SMU idlemask : 0x%x\n", val);
+
+ return 0;
+ }
++
++static int amd_pmc_idlemask_show(struct seq_file *s, void *unused)
++{
++ return amd_pmc_idlemask_read(s->private, NULL, s);
++}
+ DEFINE_SHOW_ATTRIBUTE(amd_pmc_idlemask);
+
+ static void amd_pmc_dbgfs_unregister(struct amd_pmc_dev *dev)
+@@ -787,6 +798,14 @@ static void amd_pmc_s2idle_check(void)
+ dev_err(pdev->dev, "error writing to STB: %d\n", rc);
+ }
+
++static int amd_pmc_dump_data(struct amd_pmc_dev *pdev)
++{
++ if (pdev->cpu_id == AMD_CPU_ID_PCO)
++ return -ENODEV;
++
++ return amd_pmc_send_cmd(pdev, 0, NULL, SMU_MSG_LOG_DUMP_DATA, 0);
++}
++
+ static void amd_pmc_s2idle_restore(void)
+ {
+ struct amd_pmc_dev *pdev = &pmc;
+@@ -799,7 +818,7 @@ static void amd_pmc_s2idle_restore(void)
+ dev_err(pdev->dev, "resume failed: %d\n", rc);
+
+ /* Let SMU know that we are looking for stats */
+- amd_pmc_send_cmd(pdev, 0, NULL, SMU_MSG_LOG_DUMP_DATA, 0);
++ amd_pmc_dump_data(pdev);
+
+ rc = amd_pmc_write_stb(pdev, AMD_PMC_STB_S2IDLE_RESTORE);
+ if (rc)
+@@ -880,17 +899,9 @@ static int amd_pmc_write_stb(struct amd_pmc_dev *dev, u32 data)
+ {
+ int err;
+
+- err = pci_write_config_dword(dev->rdev, AMD_PMC_STB_INDEX_ADDRESS, AMD_PMC_STB_PMI_0);
++ err = amd_smn_write(0, AMD_PMC_STB_PMI_0, data);
+ if (err) {
+- dev_err(dev->dev, "failed to write addr in stb: 0x%X\n",
+- AMD_PMC_STB_INDEX_ADDRESS);
+- return pcibios_err_to_errno(err);
+- }
+-
+- err = pci_write_config_dword(dev->rdev, AMD_PMC_STB_INDEX_DATA, data);
+- if (err) {
+- dev_err(dev->dev, "failed to write data in stb: 0x%X\n",
+- AMD_PMC_STB_INDEX_DATA);
++ dev_err(dev->dev, "failed to write data in stb: 0x%X\n", AMD_PMC_STB_PMI_0);
+ return pcibios_err_to_errno(err);
+ }
+
+@@ -902,18 +913,10 @@ static int amd_pmc_read_stb(struct amd_pmc_dev *dev, u32 *buf)
+ {
+ int i, err;
+
+- err = pci_write_config_dword(dev->rdev, AMD_PMC_STB_INDEX_ADDRESS, AMD_PMC_STB_PMI_0);
+- if (err) {
+- dev_err(dev->dev, "error writing addr to stb: 0x%X\n",
+- AMD_PMC_STB_INDEX_ADDRESS);
+- return pcibios_err_to_errno(err);
+- }
+-
+ for (i = 0; i < FIFO_SIZE; i++) {
+- err = pci_read_config_dword(dev->rdev, AMD_PMC_STB_INDEX_DATA, buf++);
++ err = amd_smn_read(0, AMD_PMC_STB_PMI_0, buf++);
+ if (err) {
+- dev_err(dev->dev, "error reading data from stb: 0x%X\n",
+- AMD_PMC_STB_INDEX_DATA);
++ dev_err(dev->dev, "error reading data from stb: 0x%X\n", AMD_PMC_STB_PMI_0);
+ return pcibios_err_to_errno(err);
+ }
+ }
+@@ -940,30 +943,18 @@ static int amd_pmc_probe(struct platform_device *pdev)
+
+ dev->cpu_id = rdev->device;
+ dev->rdev = rdev;
+- err = pci_write_config_dword(rdev, AMD_PMC_SMU_INDEX_ADDRESS, AMD_PMC_BASE_ADDR_LO);
+- if (err) {
+- dev_err(dev->dev, "error writing to 0x%x\n", AMD_PMC_SMU_INDEX_ADDRESS);
+- err = pcibios_err_to_errno(err);
+- goto err_pci_dev_put;
+- }
+-
+- err = pci_read_config_dword(rdev, AMD_PMC_SMU_INDEX_DATA, &val);
++ err = amd_smn_read(0, AMD_PMC_BASE_ADDR_LO, &val);
+ if (err) {
++ dev_err(dev->dev, "error reading 0x%x\n", AMD_PMC_BASE_ADDR_LO);
+ err = pcibios_err_to_errno(err);
+ goto err_pci_dev_put;
+ }
+
+ base_addr_lo = val & AMD_PMC_BASE_ADDR_HI_MASK;
+
+- err = pci_write_config_dword(rdev, AMD_PMC_SMU_INDEX_ADDRESS, AMD_PMC_BASE_ADDR_HI);
+- if (err) {
+- dev_err(dev->dev, "error writing to 0x%x\n", AMD_PMC_SMU_INDEX_ADDRESS);
+- err = pcibios_err_to_errno(err);
+- goto err_pci_dev_put;
+- }
+-
+- err = pci_read_config_dword(rdev, AMD_PMC_SMU_INDEX_DATA, &val);
++ err = amd_smn_read(0, AMD_PMC_BASE_ADDR_HI, &val);
+ if (err) {
++ dev_err(dev->dev, "error reading 0x%x\n", AMD_PMC_BASE_ADDR_HI);
+ err = pcibios_err_to_errno(err);
+ goto err_pci_dev_put;
+ }
+diff --git a/drivers/platform/x86/amd/pmf/Kconfig b/drivers/platform/x86/amd/pmf/Kconfig
+index 6d89528c31779..d87986adf91e1 100644
+--- a/drivers/platform/x86/amd/pmf/Kconfig
++++ b/drivers/platform/x86/amd/pmf/Kconfig
+@@ -7,6 +7,7 @@ config AMD_PMF
+ tristate "AMD Platform Management Framework"
+ depends on ACPI && PCI
+ depends on POWER_SUPPLY
++ depends on AMD_NB
+ select ACPI_PLATFORM_PROFILE
+ help
+ This driver provides support for the AMD Platform Management Framework.
+diff --git a/drivers/platform/x86/amd/pmf/core.c b/drivers/platform/x86/amd/pmf/core.c
+index da23639071d79..0acc0b6221290 100644
+--- a/drivers/platform/x86/amd/pmf/core.c
++++ b/drivers/platform/x86/amd/pmf/core.c
+@@ -8,6 +8,7 @@
+ * Author: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
+ */
+
++#include <asm/amd_nb.h>
+ #include <linux/debugfs.h>
+ #include <linux/iopoll.h>
+ #include <linux/module.h>
+@@ -22,8 +23,6 @@
+ #define AMD_PMF_REGISTER_ARGUMENT 0xA58
+
+ /* Base address of SMU for mapping physical address to virtual address */
+-#define AMD_PMF_SMU_INDEX_ADDRESS 0xB8
+-#define AMD_PMF_SMU_INDEX_DATA 0xBC
+ #define AMD_PMF_MAPPING_SIZE 0x01000
+ #define AMD_PMF_BASE_ADDR_OFFSET 0x10000
+ #define AMD_PMF_BASE_ADDR_LO 0x13B102E8
+@@ -348,30 +347,19 @@ static int amd_pmf_probe(struct platform_device *pdev)
+ }
+
+ dev->cpu_id = rdev->device;
+- err = pci_write_config_dword(rdev, AMD_PMF_SMU_INDEX_ADDRESS, AMD_PMF_BASE_ADDR_LO);
+- if (err) {
+- dev_err(dev->dev, "error writing to 0x%x\n", AMD_PMF_SMU_INDEX_ADDRESS);
+- pci_dev_put(rdev);
+- return pcibios_err_to_errno(err);
+- }
+
+- err = pci_read_config_dword(rdev, AMD_PMF_SMU_INDEX_DATA, &val);
++ err = amd_smn_read(0, AMD_PMF_BASE_ADDR_LO, &val);
+ if (err) {
++ dev_err(dev->dev, "error in reading from 0x%x\n", AMD_PMF_BASE_ADDR_LO);
+ pci_dev_put(rdev);
+ return pcibios_err_to_errno(err);
+ }
+
+ base_addr_lo = val & AMD_PMF_BASE_ADDR_HI_MASK;
+
+- err = pci_write_config_dword(rdev, AMD_PMF_SMU_INDEX_ADDRESS, AMD_PMF_BASE_ADDR_HI);
+- if (err) {
+- dev_err(dev->dev, "error writing to 0x%x\n", AMD_PMF_SMU_INDEX_ADDRESS);
+- pci_dev_put(rdev);
+- return pcibios_err_to_errno(err);
+- }
+-
+- err = pci_read_config_dword(rdev, AMD_PMF_SMU_INDEX_DATA, &val);
++ err = amd_smn_read(0, AMD_PMF_BASE_ADDR_HI, &val);
+ if (err) {
++ dev_err(dev->dev, "error in reading from 0x%x\n", AMD_PMF_BASE_ADDR_HI);
+ pci_dev_put(rdev);
+ return pcibios_err_to_errno(err);
+ }
+diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
+index 32c10457399e4..7191ff2625b1e 100644
+--- a/drivers/platform/x86/thinkpad_acpi.c
++++ b/drivers/platform/x86/thinkpad_acpi.c
+@@ -4478,6 +4478,14 @@ static const struct dmi_system_id fwbug_list[] __initconst = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "20UH"),
+ }
+ },
++ {
++ .ident = "T14s Gen1 AMD",
++ .driver_data = &quirk_s2idle_bug,
++ .matches = {
++ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "20UJ"),
++ }
++ },
+ {
+ .ident = "P14s Gen1 AMD",
+ .driver_data = &quirk_s2idle_bug,
+diff --git a/drivers/power/supply/generic-adc-battery.c b/drivers/power/supply/generic-adc-battery.c
+index 66039c665dd1e..0af536f4932f1 100644
+--- a/drivers/power/supply/generic-adc-battery.c
++++ b/drivers/power/supply/generic-adc-battery.c
+@@ -135,6 +135,9 @@ static int read_channel(struct gab *adc_bat, enum power_supply_property psp,
+ result);
+ if (ret < 0)
+ pr_err("read channel error\n");
++ else
++ *result *= 1000;
++
+ return ret;
+ }
+
+diff --git a/drivers/power/supply/rk817_charger.c b/drivers/power/supply/rk817_charger.c
+index 36f807b5ec442..f1b431aa0e4f2 100644
+--- a/drivers/power/supply/rk817_charger.c
++++ b/drivers/power/supply/rk817_charger.c
+@@ -335,6 +335,20 @@ static int rk817_bat_calib_cap(struct rk817_charger *charger)
+ charger->fcc_mah * 1000);
+ }
+
++ /*
++ * Set the SOC to 0 if we are below the minimum system voltage.
++ */
++ if (volt_avg <= charger->bat_voltage_min_design_uv) {
++ charger->soc = 0;
++ charge_now_adc = CHARGE_TO_ADC(0, charger->res_div);
++ put_unaligned_be32(charge_now_adc, bulk_reg);
++ regmap_bulk_write(rk808->regmap,
++ RK817_GAS_GAUGE_Q_INIT_H3, bulk_reg, 4);
++ dev_warn(charger->dev,
++ "Battery voltage %d below minimum voltage %d\n",
++ volt_avg, charger->bat_voltage_min_design_uv);
++ }
++
+ rk817_record_battery_nvram_values(charger);
+
+ return 0;
+@@ -710,9 +724,10 @@ static int rk817_read_battery_nvram_values(struct rk817_charger *charger)
+
+ /*
+ * Read the nvram for state of charge. Sanity check for values greater
+- * than 100 (10000). If the value is off it should get corrected
+- * automatically when the voltage drops to the min (soc is 0) or when
+- * the battery is full (soc is 100).
++ * than 100 (10000) or less than 0, because other things (BSP kernels,
++ * U-Boot, or even i2cset) can write to this register. If the value is
++ * off it should get corrected automatically when the voltage drops to
++ * the min (soc is 0) or when the battery is full (soc is 100).
+ */
+ ret = regmap_bulk_read(charger->rk808->regmap,
+ RK817_GAS_GAUGE_BAT_R1, bulk_reg, 3);
+@@ -721,6 +736,8 @@ static int rk817_read_battery_nvram_values(struct rk817_charger *charger)
+ charger->soc = get_unaligned_le24(bulk_reg);
+ if (charger->soc > 10000)
+ charger->soc = 10000;
++ if (charger->soc < 0)
++ charger->soc = 0;
+
+ return 0;
+ }
+@@ -731,8 +748,8 @@ rk817_read_or_set_full_charge_on_boot(struct rk817_charger *charger,
+ {
+ struct rk808 *rk808 = charger->rk808;
+ u8 bulk_reg[4];
+- u32 boot_voltage, boot_charge_mah, tmp;
+- int ret, reg, off_time;
++ u32 boot_voltage, boot_charge_mah;
++ int ret, reg, off_time, tmp;
+ bool first_boot;
+
+ /*
+@@ -785,10 +802,12 @@ rk817_read_or_set_full_charge_on_boot(struct rk817_charger *charger,
+ regmap_bulk_read(rk808->regmap, RK817_GAS_GAUGE_Q_PRES_H3,
+ bulk_reg, 4);
+ tmp = get_unaligned_be32(bulk_reg);
++ if (tmp < 0)
++ tmp = 0;
+ boot_charge_mah = ADC_TO_CHARGE_UAH(tmp,
+ charger->res_div) / 1000;
+ /*
+- * Check if the columb counter has been off for more than 300
++ * Check if the columb counter has been off for more than 30
+ * minutes as it tends to drift downward. If so, re-init soc
+ * with the boot voltage instead. Note the unit values for the
+ * OFF_CNT register appear to be in decaminutes and stops
+@@ -799,7 +818,7 @@ rk817_read_or_set_full_charge_on_boot(struct rk817_charger *charger,
+ * than 0 on a reboot anyway.
+ */
+ regmap_read(rk808->regmap, RK817_GAS_GAUGE_OFF_CNT, &off_time);
+- if (off_time >= 30) {
++ if (off_time >= 3) {
+ regmap_bulk_read(rk808->regmap,
+ RK817_GAS_GAUGE_PWRON_VOL_H,
+ bulk_reg, 2);
+diff --git a/drivers/pwm/pwm-meson.c b/drivers/pwm/pwm-meson.c
+index 5cd7b90872c62..5732300eb0046 100644
+--- a/drivers/pwm/pwm-meson.c
++++ b/drivers/pwm/pwm-meson.c
+@@ -418,7 +418,7 @@ static const struct meson_pwm_data pwm_axg_ee_data = {
+ };
+
+ static const char * const pwm_axg_ao_parent_names[] = {
+- "aoclk81", "xtal", "fclk_div4", "fclk_div5"
++ "xtal", "axg_ao_clk81", "fclk_div4", "fclk_div5"
+ };
+
+ static const struct meson_pwm_data pwm_axg_ao_data = {
+@@ -427,7 +427,7 @@ static const struct meson_pwm_data pwm_axg_ao_data = {
+ };
+
+ static const char * const pwm_g12a_ao_ab_parent_names[] = {
+- "xtal", "aoclk81", "fclk_div4", "fclk_div5"
++ "xtal", "g12a_ao_clk81", "fclk_div4", "fclk_div5"
+ };
+
+ static const struct meson_pwm_data pwm_g12a_ao_ab_data = {
+@@ -436,7 +436,7 @@ static const struct meson_pwm_data pwm_g12a_ao_ab_data = {
+ };
+
+ static const char * const pwm_g12a_ao_cd_parent_names[] = {
+- "xtal", "aoclk81",
++ "xtal", "g12a_ao_clk81",
+ };
+
+ static const struct meson_pwm_data pwm_g12a_ao_cd_data = {
+diff --git a/drivers/pwm/pwm-mtk-disp.c b/drivers/pwm/pwm-mtk-disp.c
+index 692a06121b286..fe9593f968eeb 100644
+--- a/drivers/pwm/pwm-mtk-disp.c
++++ b/drivers/pwm/pwm-mtk-disp.c
+@@ -138,6 +138,19 @@ static int mtk_disp_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+ high_width = mul_u64_u64_div_u64(state->duty_cycle, rate, div);
+ value = period | (high_width << PWM_HIGH_WIDTH_SHIFT);
+
++ if (mdp->data->bls_debug && !mdp->data->has_commit) {
++ /*
++ * For MT2701, disable double buffer before writing register
++ * and select manual mode and use PWM_PERIOD/PWM_HIGH_WIDTH.
++ */
++ mtk_disp_pwm_update_bits(mdp, mdp->data->bls_debug,
++ mdp->data->bls_debug_mask,
++ mdp->data->bls_debug_mask);
++ mtk_disp_pwm_update_bits(mdp, mdp->data->con0,
++ mdp->data->con0_sel,
++ mdp->data->con0_sel);
++ }
++
+ mtk_disp_pwm_update_bits(mdp, mdp->data->con0,
+ PWM_CLKDIV_MASK,
+ clk_div << PWM_CLKDIV_SHIFT);
+@@ -152,17 +165,6 @@ static int mtk_disp_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+ mtk_disp_pwm_update_bits(mdp, mdp->data->commit,
+ mdp->data->commit_mask,
+ 0x0);
+- } else {
+- /*
+- * For MT2701, disable double buffer before writing register
+- * and select manual mode and use PWM_PERIOD/PWM_HIGH_WIDTH.
+- */
+- mtk_disp_pwm_update_bits(mdp, mdp->data->bls_debug,
+- mdp->data->bls_debug_mask,
+- mdp->data->bls_debug_mask);
+- mtk_disp_pwm_update_bits(mdp, mdp->data->con0,
+- mdp->data->con0_sel,
+- mdp->data->con0_sel);
+ }
+
+ mtk_disp_pwm_update_bits(mdp, DISP_PWM_EN, mdp->data->enable_mask,
+@@ -194,6 +196,16 @@ static int mtk_disp_pwm_get_state(struct pwm_chip *chip,
+ return err;
+ }
+
++ /*
++ * Apply DISP_PWM_DEBUG settings to choose whether to enable or disable
++ * registers double buffer and manual commit to working register before
++ * performing any read/write operation
++ */
++ if (mdp->data->bls_debug)
++ mtk_disp_pwm_update_bits(mdp, mdp->data->bls_debug,
++ mdp->data->bls_debug_mask,
++ mdp->data->bls_debug_mask);
++
+ rate = clk_get_rate(mdp->clk_main);
+ con0 = readl(mdp->base + mdp->data->con0);
+ con1 = readl(mdp->base + mdp->data->con1);
+diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
+index 4fcd36055b025..08726bc0da9d7 100644
+--- a/drivers/regulator/core.c
++++ b/drivers/regulator/core.c
+@@ -207,6 +207,78 @@ static void regulator_unlock(struct regulator_dev *rdev)
+ mutex_unlock(&regulator_nesting_mutex);
+ }
+
++/**
++ * regulator_lock_two - lock two regulators
++ * @rdev1: first regulator
++ * @rdev2: second regulator
++ * @ww_ctx: w/w mutex acquire context
++ *
++ * Locks both rdevs using the regulator_ww_class.
++ */
++static void regulator_lock_two(struct regulator_dev *rdev1,
++ struct regulator_dev *rdev2,
++ struct ww_acquire_ctx *ww_ctx)
++{
++ struct regulator_dev *tmp;
++ int ret;
++
++ ww_acquire_init(ww_ctx, &regulator_ww_class);
++
++ /* Try to just grab both of them */
++ ret = regulator_lock_nested(rdev1, ww_ctx);
++ WARN_ON(ret);
++ ret = regulator_lock_nested(rdev2, ww_ctx);
++ if (ret != -EDEADLOCK) {
++ WARN_ON(ret);
++ goto exit;
++ }
++
++ while (true) {
++ /*
++ * Start of loop: rdev1 was locked and rdev2 was contended.
++ * Need to unlock rdev1, slowly lock rdev2, then try rdev1
++ * again.
++ */
++ regulator_unlock(rdev1);
++
++ ww_mutex_lock_slow(&rdev2->mutex, ww_ctx);
++ rdev2->ref_cnt++;
++ rdev2->mutex_owner = current;
++ ret = regulator_lock_nested(rdev1, ww_ctx);
++
++ if (ret == -EDEADLOCK) {
++ /* More contention; swap which needs to be slow */
++ tmp = rdev1;
++ rdev1 = rdev2;
++ rdev2 = tmp;
++ } else {
++ WARN_ON(ret);
++ break;
++ }
++ }
++
++exit:
++ ww_acquire_done(ww_ctx);
++}
++
++/**
++ * regulator_unlock_two - unlock two regulators
++ * @rdev1: first regulator
++ * @rdev2: second regulator
++ * @ww_ctx: w/w mutex acquire context
++ *
++ * The inverse of regulator_lock_two().
++ */
++
++static void regulator_unlock_two(struct regulator_dev *rdev1,
++ struct regulator_dev *rdev2,
++ struct ww_acquire_ctx *ww_ctx)
++{
++ regulator_unlock(rdev2);
++ regulator_unlock(rdev1);
++ ww_acquire_fini(ww_ctx);
++}
++
+ static bool regulator_supply_is_couple(struct regulator_dev *rdev)
+ {
+ struct regulator_dev *c_rdev;
+@@ -334,6 +406,7 @@ static void regulator_lock_dependent(struct regulator_dev *rdev,
+ ww_mutex_lock_slow(&new_contended_rdev->mutex, ww_ctx);
+ old_contended_rdev = new_contended_rdev;
+ old_contended_rdev->ref_cnt++;
++ old_contended_rdev->mutex_owner = current;
+ }
+
+ err = regulator_lock_recursive(rdev,
+@@ -1583,9 +1656,6 @@ static int set_machine_constraints(struct regulator_dev *rdev)
+ rdev->constraints->always_on = true;
+ }
+
+- if (rdev->desc->off_on_delay)
+- rdev->last_off = ktime_get_boottime();
+-
+ /* If the constraints say the regulator should be on at this point
+ * and we have control then make sure it is enabled.
+ */
+@@ -1619,6 +1689,8 @@ static int set_machine_constraints(struct regulator_dev *rdev)
+
+ if (rdev->constraints->always_on)
+ rdev->use_count++;
++ } else if (rdev->desc->off_on_delay) {
++ rdev->last_off = ktime_get();
+ }
+
+ print_constraints(rdev);
+@@ -1627,8 +1699,8 @@ static int set_machine_constraints(struct regulator_dev *rdev)
+
+ /**
+ * set_supply - set regulator supply regulator
+- * @rdev: regulator name
+- * @supply_rdev: supply regulator name
++ * @rdev: regulator (locked)
++ * @supply_rdev: supply regulator (locked))
+ *
+ * Called by platform initialisation code to set the supply regulator for this
+ * regulator. This ensures that a regulators supply will also be enabled by the
+@@ -1800,6 +1872,8 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
+ struct regulator *regulator;
+ int err = 0;
+
++ lockdep_assert_held_once(&rdev->mutex.base);
++
+ if (dev) {
+ char buf[REG_STR_SIZE];
+ int size;
+@@ -1827,9 +1901,7 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
+ regulator->rdev = rdev;
+ regulator->supply_name = supply_name;
+
+- regulator_lock(rdev);
+ list_add(&regulator->list, &rdev->consumer_list);
+- regulator_unlock(rdev);
+
+ if (dev) {
+ regulator->dev = dev;
+@@ -1995,6 +2067,7 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
+ {
+ struct regulator_dev *r;
+ struct device *dev = rdev->dev.parent;
++ struct ww_acquire_ctx ww_ctx;
+ int ret = 0;
+
+ /* No supply to resolve? */
+@@ -2061,23 +2134,23 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
+ * between rdev->supply null check and setting rdev->supply in
+ * set_supply() from concurrent tasks.
+ */
+- regulator_lock(rdev);
++ regulator_lock_two(rdev, r, &ww_ctx);
+
+ /* Supply just resolved by a concurrent task? */
+ if (rdev->supply) {
+- regulator_unlock(rdev);
++ regulator_unlock_two(rdev, r, &ww_ctx);
+ put_device(&r->dev);
+ goto out;
+ }
+
+ ret = set_supply(rdev, r);
+ if (ret < 0) {
+- regulator_unlock(rdev);
++ regulator_unlock_two(rdev, r, &ww_ctx);
+ put_device(&r->dev);
+ goto out;
+ }
+
+- regulator_unlock(rdev);
++ regulator_unlock_two(rdev, r, &ww_ctx);
+
+ /*
+ * In set_machine_constraints() we may have turned this regulator on
+@@ -2190,7 +2263,9 @@ struct regulator *_regulator_get(struct device *dev, const char *id,
+ return regulator;
+ }
+
++ regulator_lock(rdev);
+ regulator = create_regulator(rdev, dev, id);
++ regulator_unlock(rdev);
+ if (regulator == NULL) {
+ regulator = ERR_PTR(-ENOMEM);
+ module_put(rdev->owner);
+@@ -2668,7 +2743,7 @@ static int _regulator_do_enable(struct regulator_dev *rdev)
+
+ trace_regulator_enable(rdev_get_name(rdev));
+
+- if (rdev->desc->off_on_delay && rdev->last_off) {
++ if (rdev->desc->off_on_delay) {
+ /* if needed, keep a distance of off_on_delay from last time
+ * this regulator was disabled.
+ */
+@@ -6049,6 +6124,7 @@ static void regulator_summary_lock(struct ww_acquire_ctx *ww_ctx)
+ ww_mutex_lock_slow(&new_contended_rdev->mutex, ww_ctx);
+ old_contended_rdev = new_contended_rdev;
+ old_contended_rdev->ref_cnt++;
++ old_contended_rdev->mutex_owner = current;
+ }
+
+ err = regulator_summary_lock_all(ww_ctx,
+diff --git a/drivers/regulator/stm32-pwr.c b/drivers/regulator/stm32-pwr.c
+index 2a42acb7c24e9..e5dd4db6403b2 100644
+--- a/drivers/regulator/stm32-pwr.c
++++ b/drivers/regulator/stm32-pwr.c
+@@ -129,17 +129,16 @@ static const struct regulator_desc stm32_pwr_desc[] = {
+
+ static int stm32_pwr_regulator_probe(struct platform_device *pdev)
+ {
+- struct device_node *np = pdev->dev.of_node;
+ struct stm32_pwr_reg *priv;
+ void __iomem *base;
+ struct regulator_dev *rdev;
+ struct regulator_config config = { };
+ int i, ret = 0;
+
+- base = of_iomap(np, 0);
+- if (!base) {
++ base = devm_platform_ioremap_resource(pdev, 0);
++ if (IS_ERR(base)) {
+ dev_err(&pdev->dev, "Unable to map IO memory\n");
+- return -ENOMEM;
++ return PTR_ERR(base);
+ }
+
+ config.dev = &pdev->dev;
+diff --git a/drivers/remoteproc/xlnx_r5_remoteproc.c b/drivers/remoteproc/xlnx_r5_remoteproc.c
+index 2db57d3941555..5dd007622603d 100644
+--- a/drivers/remoteproc/xlnx_r5_remoteproc.c
++++ b/drivers/remoteproc/xlnx_r5_remoteproc.c
+@@ -61,8 +61,6 @@ static const struct mem_bank_data zynqmp_tcm_banks[] = {
+ * @np: device node of RPU instance
+ * @tcm_bank_count: number TCM banks accessible to this RPU
+ * @tcm_banks: array of each TCM bank data
+- * @rmem_count: Number of reserved mem regions
+- * @rmem: reserved memory region nodes from device tree
+ * @rproc: rproc handle
+ * @pm_domain_id: RPU CPU power domain id
+ */
+@@ -71,8 +69,6 @@ struct zynqmp_r5_core {
+ struct device_node *np;
+ int tcm_bank_count;
+ struct mem_bank_data **tcm_banks;
+- int rmem_count;
+- struct reserved_mem **rmem;
+ struct rproc *rproc;
+ u32 pm_domain_id;
+ };
+@@ -239,21 +235,29 @@ static int add_mem_regions_carveout(struct rproc *rproc)
+ {
+ struct rproc_mem_entry *rproc_mem;
+ struct zynqmp_r5_core *r5_core;
++ struct of_phandle_iterator it;
+ struct reserved_mem *rmem;
+- int i, num_mem_regions;
++ int i = 0;
+
+ r5_core = (struct zynqmp_r5_core *)rproc->priv;
+- num_mem_regions = r5_core->rmem_count;
+
+- for (i = 0; i < num_mem_regions; i++) {
+- rmem = r5_core->rmem[i];
++ /* Register associated reserved memory regions */
++ of_phandle_iterator_init(&it, r5_core->np, "memory-region", NULL, 0);
+
+- if (!strncmp(rmem->name, "vdev0buffer", strlen("vdev0buffer"))) {
++ while (of_phandle_iterator_next(&it) == 0) {
++ rmem = of_reserved_mem_lookup(it.node);
++ if (!rmem) {
++ of_node_put(it.node);
++ dev_err(&rproc->dev, "unable to acquire memory-region\n");
++ return -EINVAL;
++ }
++
++ if (!strcmp(it.node->name, "vdev0buffer")) {
+ /* Init reserved memory for vdev buffer */
+ rproc_mem = rproc_of_resm_mem_entry_init(&rproc->dev, i,
+ rmem->size,
+ rmem->base,
+- rmem->name);
++ it.node->name);
+ } else {
+ /* Register associated reserved memory regions */
+ rproc_mem = rproc_mem_entry_init(&rproc->dev, NULL,
+@@ -261,16 +265,19 @@ static int add_mem_regions_carveout(struct rproc *rproc)
+ rmem->size, rmem->base,
+ zynqmp_r5_mem_region_map,
+ zynqmp_r5_mem_region_unmap,
+- rmem->name);
++ it.node->name);
+ }
+
+- if (!rproc_mem)
++ if (!rproc_mem) {
++ of_node_put(it.node);
+ return -ENOMEM;
++ }
+
+ rproc_add_carveout(rproc, rproc_mem);
+
+ dev_dbg(&rproc->dev, "reserved mem carveout %s addr=%llx, size=0x%llx",
+- rmem->name, rmem->base, rmem->size);
++ it.node->name, rmem->base, rmem->size);
++ i++;
+ }
+
+ return 0;
+@@ -726,59 +733,6 @@ static int zynqmp_r5_get_tcm_node(struct zynqmp_r5_cluster *cluster)
+ return 0;
+ }
+
+-/**
+- * zynqmp_r5_get_mem_region_node()
+- * parse memory-region property and get reserved mem regions
+- *
+- * @r5_core: pointer to zynqmp_r5_core type object
+- *
+- * Return: 0 for success and error code for failure.
+- */
+-static int zynqmp_r5_get_mem_region_node(struct zynqmp_r5_core *r5_core)
+-{
+- struct device_node *np, *rmem_np;
+- struct reserved_mem **rmem;
+- int res_mem_count, i;
+- struct device *dev;
+-
+- dev = r5_core->dev;
+- np = r5_core->np;
+-
+- res_mem_count = of_property_count_elems_of_size(np, "memory-region",
+- sizeof(phandle));
+- if (res_mem_count <= 0) {
+- dev_warn(dev, "failed to get memory-region property %d\n",
+- res_mem_count);
+- return 0;
+- }
+-
+- rmem = devm_kcalloc(dev, res_mem_count,
+- sizeof(struct reserved_mem *), GFP_KERNEL);
+- if (!rmem)
+- return -ENOMEM;
+-
+- for (i = 0; i < res_mem_count; i++) {
+- rmem_np = of_parse_phandle(np, "memory-region", i);
+- if (!rmem_np)
+- goto release_rmem;
+-
+- rmem[i] = of_reserved_mem_lookup(rmem_np);
+- if (!rmem[i]) {
+- of_node_put(rmem_np);
+- goto release_rmem;
+- }
+-
+- of_node_put(rmem_np);
+- }
+-
+- r5_core->rmem_count = res_mem_count;
+- r5_core->rmem = rmem;
+- return 0;
+-
+-release_rmem:
+- return -EINVAL;
+-}
+-
+ /*
+ * zynqmp_r5_core_init()
+ * Create and initialize zynqmp_r5_core type object
+@@ -806,10 +760,6 @@ static int zynqmp_r5_core_init(struct zynqmp_r5_cluster *cluster,
+ for (i = 0; i < cluster->core_count; i++) {
+ r5_core = cluster->r5_cores[i];
+
+- ret = zynqmp_r5_get_mem_region_node(r5_core);
+- if (ret)
+- dev_warn(dev, "memory-region prop failed %d\n", ret);
+-
+ /* Initialize r5 cores with power-domains parsed from dts */
+ ret = of_property_read_u32_index(r5_core->np, "power-domains",
+ 1, &r5_core->pm_domain_id);
+diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c
+index 35df1b0a515bf..67e7664efb0dc 100644
+--- a/drivers/rpmsg/qcom_glink_native.c
++++ b/drivers/rpmsg/qcom_glink_native.c
+@@ -1348,8 +1348,9 @@ static int __qcom_glink_send(struct glink_channel *channel,
+ ret = qcom_glink_tx(glink, &req, sizeof(req), data, chunk_size, wait);
+
+ /* Mark intent available if we failed */
+- if (ret && intent) {
+- intent->in_use = false;
++ if (ret) {
++ if (intent)
++ intent->in_use = false;
+ return ret;
+ }
+
+@@ -1370,8 +1371,9 @@ static int __qcom_glink_send(struct glink_channel *channel,
+ chunk_size, wait);
+
+ /* Mark intent available if we failed */
+- if (ret && intent) {
+- intent->in_use = false;
++ if (ret) {
++ if (intent)
++ intent->in_use = false;
+ break;
+ }
+ }
+diff --git a/drivers/rtc/rtc-meson-vrtc.c b/drivers/rtc/rtc-meson-vrtc.c
+index 1463c86215615..648fa362ec447 100644
+--- a/drivers/rtc/rtc-meson-vrtc.c
++++ b/drivers/rtc/rtc-meson-vrtc.c
+@@ -23,7 +23,7 @@ static int meson_vrtc_read_time(struct device *dev, struct rtc_time *tm)
+ struct timespec64 time;
+
+ dev_dbg(dev, "%s\n", __func__);
+- ktime_get_raw_ts64(&time);
++ ktime_get_real_ts64(&time);
+ rtc_time64_to_tm(time.tv_sec, tm);
+
+ return 0;
+@@ -96,7 +96,7 @@ static int __maybe_unused meson_vrtc_suspend(struct device *dev)
+ long alarm_secs;
+ struct timespec64 time;
+
+- ktime_get_raw_ts64(&time);
++ ktime_get_real_ts64(&time);
+ local_time = time.tv_sec;
+
+ dev_dbg(dev, "alarm_time = %lus, local_time=%lus\n",
+diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
+index 4d4f3b1a73093..73634a3ccfd3b 100644
+--- a/drivers/rtc/rtc-omap.c
++++ b/drivers/rtc/rtc-omap.c
+@@ -25,6 +25,7 @@
+ #include <linux/platform_device.h>
+ #include <linux/pm_runtime.h>
+ #include <linux/rtc.h>
++#include <linux/rtc/rtc-omap.h>
+
+ /*
+ * The OMAP RTC is a year/month/day/hours/minutes/seconds BCD clock
+diff --git a/drivers/rtc/rtc-ti-k3.c b/drivers/rtc/rtc-ti-k3.c
+index ba23163cc0428..0d90fe9233550 100644
+--- a/drivers/rtc/rtc-ti-k3.c
++++ b/drivers/rtc/rtc-ti-k3.c
+@@ -632,7 +632,8 @@ static int __maybe_unused ti_k3_rtc_suspend(struct device *dev)
+ struct ti_k3_rtc *priv = dev_get_drvdata(dev);
+
+ if (device_may_wakeup(dev))
+- enable_irq_wake(priv->irq);
++ return enable_irq_wake(priv->irq);
++
+ return 0;
+ }
+
+diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
+index 5a6d9c15395f7..bce3422d85640 100644
+--- a/drivers/s390/block/dasd.c
++++ b/drivers/s390/block/dasd.c
+@@ -2941,7 +2941,7 @@ static int _dasd_requeue_request(struct dasd_ccw_req *cqr)
+ return 0;
+ spin_lock_irq(&cqr->dq->lock);
+ req = (struct request *) cqr->callback_data;
+- blk_mq_requeue_request(req, false);
++ blk_mq_requeue_request(req, true);
+ spin_unlock_irq(&cqr->dq->lock);
+
+ return 0;
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+index d643c5a49aa94..70c24377c6a19 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+@@ -1258,7 +1258,11 @@ static void slot_complete_v1_hw(struct hisi_hba *hisi_hba,
+
+ slot_err_v1_hw(hisi_hba, task, slot);
+ if (unlikely(slot->abort)) {
+- sas_task_abort(task);
++ if (dev_is_sata(device) && task->ata_task.use_ncq)
++ sas_ata_device_link_abort(device, true);
++ else
++ sas_task_abort(task);
++
+ return;
+ }
+ goto out;
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+index cded42f4ca445..02575d81afca2 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -2404,7 +2404,11 @@ static void slot_complete_v2_hw(struct hisi_hba *hisi_hba,
+ error_info[2], error_info[3]);
+
+ if (unlikely(slot->abort)) {
+- sas_task_abort(task);
++ if (dev_is_sata(device) && task->ata_task.use_ncq)
++ sas_ata_device_link_abort(device, true);
++ else
++ sas_task_abort(task);
++
+ return;
+ }
+ goto out;
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index a63279f55d096..9afc23e3a80fc 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -2320,7 +2320,11 @@ static void slot_complete_v3_hw(struct hisi_hba *hisi_hba,
+ error_info[0], error_info[1],
+ error_info[2], error_info[3]);
+ if (unlikely(slot->abort)) {
+- sas_task_abort(task);
++ if (dev_is_sata(device) && task->ata_task.use_ncq)
++ sas_ata_device_link_abort(device, true);
++ else
++ sas_task_abort(task);
++
+ return;
+ }
+ goto out;
+diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
+index eeb73da754d0d..99d2694fe00a0 100644
+--- a/drivers/scsi/lpfc/lpfc_init.c
++++ b/drivers/scsi/lpfc/lpfc_init.c
+@@ -11970,7 +11970,7 @@ lpfc_sli4_pci_mem_setup(struct lpfc_hba *phba)
+ goto out_iounmap_all;
+ } else {
+ error = -ENOMEM;
+- goto out_iounmap_all;
++ goto out_iounmap_ctrl;
+ }
+ }
+
+@@ -11988,7 +11988,7 @@ lpfc_sli4_pci_mem_setup(struct lpfc_hba *phba)
+ dev_err(&pdev->dev,
+ "ioremap failed for SLI4 HBA dpp registers.\n");
+ error = -ENOMEM;
+- goto out_iounmap_ctrl;
++ goto out_iounmap_all;
+ }
+ phba->pci_bar4_memmap_p = phba->sli4_hba.dpp_regs_memmap_p;
+ }
+@@ -12013,9 +12013,11 @@ lpfc_sli4_pci_mem_setup(struct lpfc_hba *phba)
+ return 0;
+
+ out_iounmap_all:
+- iounmap(phba->sli4_hba.drbl_regs_memmap_p);
++ if (phba->sli4_hba.drbl_regs_memmap_p)
++ iounmap(phba->sli4_hba.drbl_regs_memmap_p);
+ out_iounmap_ctrl:
+- iounmap(phba->sli4_hba.ctrl_regs_memmap_p);
++ if (phba->sli4_hba.ctrl_regs_memmap_p)
++ iounmap(phba->sli4_hba.ctrl_regs_memmap_p);
+ out_iounmap_conf:
+ iounmap(phba->sli4_hba.conf_regs_memmap_p);
+
+diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
+index bf491af9f0d65..16e2cf848c6ef 100644
+--- a/drivers/scsi/megaraid.c
++++ b/drivers/scsi/megaraid.c
+@@ -1441,6 +1441,7 @@ mega_cmd_done(adapter_t *adapter, u8 completed[], int nstatus, int status)
+ */
+ if (cmdid == CMDID_INT_CMDS) {
+ scb = &adapter->int_scb;
++ cmd = scb->cmd;
+
+ list_del_init(&scb->list);
+ scb->state = SCB_FREE;
+diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c
+index a565817aa56d4..d109a4ceb72b1 100644
+--- a/drivers/scsi/mpi3mr/mpi3mr_fw.c
++++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c
+@@ -2526,7 +2526,7 @@ static void mpi3mr_watchdog_work(struct work_struct *work)
+ mrioc->unrecoverable = 1;
+ goto schedule_work;
+ case MPI3_SYSIF_FAULT_CODE_SOFT_RESET_IN_PROGRESS:
+- return;
++ goto schedule_work;
+ case MPI3_SYSIF_FAULT_CODE_CI_ACTIVATION_RESET:
+ reset_reason = MPI3MR_RESET_FROM_CIACTIV_FAULT;
+ break;
+diff --git a/drivers/soc/bcm/brcmstb/biuctrl.c b/drivers/soc/bcm/brcmstb/biuctrl.c
+index e1d7b45432485..364ddbe365c24 100644
+--- a/drivers/soc/bcm/brcmstb/biuctrl.c
++++ b/drivers/soc/bcm/brcmstb/biuctrl.c
+@@ -288,6 +288,10 @@ static int __init setup_hifcpubiuctrl_regs(struct device_node *np)
+ if (BRCM_ID(family_id) == 0x7260 && BRCM_REV(family_id) == 0)
+ cpubiuctrl_regs = b53_cpubiuctrl_no_wb_regs;
+ out:
++ if (ret && cpubiuctrl_base) {
++ iounmap(cpubiuctrl_base);
++ cpubiuctrl_base = NULL;
++ }
+ return ret;
+ }
+
+diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c
+index 0f8b2249f8894..f93544f6d7961 100644
+--- a/drivers/soc/qcom/rpmh-rsc.c
++++ b/drivers/soc/qcom/rpmh-rsc.c
+@@ -1073,7 +1073,7 @@ static int rpmh_rsc_probe(struct platform_device *pdev)
+ drv->ver.minor = rsc_id & (MINOR_VER_MASK << MINOR_VER_SHIFT);
+ drv->ver.minor >>= MINOR_VER_SHIFT;
+
+- if (drv->ver.major == 3 && drv->ver.minor == 0)
++ if (drv->ver.major == 3 && drv->ver.minor >= 0)
+ drv->regs = rpmh_rsc_reg_offset_ver_3_0;
+ else
+ drv->regs = rpmh_rsc_reg_offset_ver_2_7;
+diff --git a/drivers/soc/renesas/renesas-soc.c b/drivers/soc/renesas/renesas-soc.c
+index 468ebce1ea88b..51191d1a6dd1d 100644
+--- a/drivers/soc/renesas/renesas-soc.c
++++ b/drivers/soc/renesas/renesas-soc.c
+@@ -471,8 +471,11 @@ static int __init renesas_soc_init(void)
+ }
+
+ soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
+- if (!soc_dev_attr)
++ if (!soc_dev_attr) {
++ if (chipid)
++ iounmap(chipid);
+ return -ENOMEM;
++ }
+
+ np = of_find_node_by_path("/");
+ of_property_read_string(np, "model", &soc_dev_attr->machine);
+diff --git a/drivers/soc/ti/k3-ringacc.c b/drivers/soc/ti/k3-ringacc.c
+index e01e4d815230a..8f131368a7586 100644
+--- a/drivers/soc/ti/k3-ringacc.c
++++ b/drivers/soc/ti/k3-ringacc.c
+@@ -406,6 +406,11 @@ static int k3_dmaring_request_dual_ring(struct k3_ringacc *ringacc, int fwd_id,
+
+ mutex_lock(&ringacc->req_lock);
+
++ if (!try_module_get(ringacc->dev->driver->owner)) {
++ ret = -EINVAL;
++ goto err_module_get;
++ }
++
+ if (test_bit(fwd_id, ringacc->rings_inuse)) {
+ ret = -EBUSY;
+ goto error;
+@@ -421,6 +426,8 @@ static int k3_dmaring_request_dual_ring(struct k3_ringacc *ringacc, int fwd_id,
+ return 0;
+
+ error:
++ module_put(ringacc->dev->driver->owner);
++err_module_get:
+ mutex_unlock(&ringacc->req_lock);
+ return ret;
+ }
+diff --git a/drivers/soc/ti/pm33xx.c b/drivers/soc/ti/pm33xx.c
+index ce09c42eaed25..f04c21157904b 100644
+--- a/drivers/soc/ti/pm33xx.c
++++ b/drivers/soc/ti/pm33xx.c
+@@ -527,7 +527,7 @@ static int am33xx_pm_probe(struct platform_device *pdev)
+
+ ret = am33xx_pm_alloc_sram();
+ if (ret)
+- return ret;
++ goto err_wkup_m3_ipc_put;
+
+ ret = am33xx_pm_rtc_setup();
+ if (ret)
+@@ -572,13 +572,14 @@ err_pm_runtime_put:
+ pm_runtime_put_sync(dev);
+ err_pm_runtime_disable:
+ pm_runtime_disable(dev);
+- wkup_m3_ipc_put(m3_ipc);
+ err_unsetup_rtc:
+ iounmap(rtc_base_virt);
+ clk_put(rtc_fck);
+ err_free_sram:
+ am33xx_pm_free_sram();
+ pm33xx_dev = NULL;
++err_wkup_m3_ipc_put:
++ wkup_m3_ipc_put(m3_ipc);
+ return ret;
+ }
+
+diff --git a/drivers/soundwire/cadence_master.h b/drivers/soundwire/cadence_master.h
+index e0a64b28c6b9c..4393607c7e4ad 100644
+--- a/drivers/soundwire/cadence_master.h
++++ b/drivers/soundwire/cadence_master.h
+@@ -84,7 +84,6 @@ struct sdw_cdns_stream_config {
+ * @bus: Bus handle
+ * @stream_type: Stream type
+ * @link_id: Master link id
+- * @hw_params: hw_params to be applied in .prepare step
+ * @suspended: status set when suspended, to be used in .prepare
+ * @paused: status set in .trigger, to be used in suspend
+ * @direction: stream direction
+@@ -96,7 +95,6 @@ struct sdw_cdns_dai_runtime {
+ struct sdw_bus *bus;
+ enum sdw_stream_type stream_type;
+ int link_id;
+- struct snd_pcm_hw_params *hw_params;
+ bool suspended;
+ bool paused;
+ int direction;
+diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
+index bc9c50bacc494..c852745989167 100644
+--- a/drivers/soundwire/intel.c
++++ b/drivers/soundwire/intel.c
+@@ -833,7 +833,6 @@ static int intel_hw_params(struct snd_pcm_substream *substream,
+ dai_runtime->paused = false;
+ dai_runtime->suspended = false;
+ dai_runtime->pdi = pdi;
+- dai_runtime->hw_params = params;
+
+ /* Inform DSP about PDI stream number */
+ ret = intel_params_stream(sdw, substream->stream, dai, params,
+@@ -886,6 +885,11 @@ static int intel_prepare(struct snd_pcm_substream *substream,
+ }
+
+ if (dai_runtime->suspended) {
++ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
++ struct snd_pcm_hw_params *hw_params;
++
++ hw_params = &rtd->dpcm[substream->stream].hw_params;
++
+ dai_runtime->suspended = false;
+
+ /*
+@@ -897,7 +901,7 @@ static int intel_prepare(struct snd_pcm_substream *substream,
+ */
+
+ /* configure stream */
+- ch = params_channels(dai_runtime->hw_params);
++ ch = params_channels(hw_params);
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+ dir = SDW_DATA_DIR_RX;
+ else
+@@ -909,7 +913,7 @@ static int intel_prepare(struct snd_pcm_substream *substream,
+
+ /* Inform DSP about PDI stream number */
+ ret = intel_params_stream(sdw, substream->stream, dai,
+- dai_runtime->hw_params,
++ hw_params,
+ sdw->instance,
+ dai_runtime->pdi->intel_alh_id);
+ }
+@@ -948,7 +952,6 @@ intel_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
+ return ret;
+ }
+
+- dai_runtime->hw_params = NULL;
+ dai_runtime->pdi = NULL;
+
+ return 0;
+diff --git a/drivers/soundwire/qcom.c b/drivers/soundwire/qcom.c
+index 3354248702900..ba502129150d5 100644
+--- a/drivers/soundwire/qcom.c
++++ b/drivers/soundwire/qcom.c
+@@ -704,7 +704,7 @@ static int qcom_swrm_init(struct qcom_swrm_ctrl *ctrl)
+ }
+
+ /* Configure number of retries of a read/write cmd */
+- if (ctrl->version > 0x01050001) {
++ if (ctrl->version >= 0x01050001) {
+ /* Only for versions >= 1.5.1 */
+ ctrl->reg_write(ctrl, SWRM_CMD_FIFO_CFG_ADDR,
+ SWRM_RD_WR_CMD_RETRIES |
+diff --git a/drivers/spi/atmel-quadspi.c b/drivers/spi/atmel-quadspi.c
+index 70637e46290a4..e8971ec74f82e 100644
+--- a/drivers/spi/atmel-quadspi.c
++++ b/drivers/spi/atmel-quadspi.c
+@@ -706,18 +706,28 @@ static int atmel_qspi_remove(struct platform_device *pdev)
+ struct atmel_qspi *aq = spi_controller_get_devdata(ctrl);
+ int ret;
+
+- ret = pm_runtime_resume_and_get(&pdev->dev);
+- if (ret < 0)
+- return ret;
+-
+ spi_unregister_controller(ctrl);
+- atmel_qspi_write(QSPI_CR_QSPIDIS, aq, QSPI_CR);
++
++ ret = pm_runtime_get_sync(&pdev->dev);
++ if (ret >= 0) {
++ atmel_qspi_write(QSPI_CR_QSPIDIS, aq, QSPI_CR);
++ clk_disable(aq->qspick);
++ clk_disable(aq->pclk);
++ } else {
++ /*
++ * atmel_qspi_runtime_{suspend,resume} just disable and enable
++ * the two clks respectively. So after resume failed these are
++ * off, and we skip hardware access and disabling these clks again.
++ */
++ dev_warn(&pdev->dev, "Failed to resume device on remove\n");
++ }
++
++ clk_unprepare(aq->qspick);
++ clk_unprepare(aq->pclk);
+
+ pm_runtime_disable(&pdev->dev);
+ pm_runtime_put_noidle(&pdev->dev);
+
+- clk_disable_unprepare(aq->qspick);
+- clk_disable_unprepare(aq->pclk);
+ return 0;
+ }
+
+@@ -786,7 +796,11 @@ static int __maybe_unused atmel_qspi_runtime_resume(struct device *dev)
+ if (ret)
+ return ret;
+
+- return clk_enable(aq->qspick);
++ ret = clk_enable(aq->qspick);
++ if (ret)
++ clk_disable(aq->pclk);
++
++ return ret;
+ }
+
+ static const struct dev_pm_ops __maybe_unused atmel_qspi_pm_ops = {
+diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c
+index 676313e1bdad1..fa11610ab40b0 100644
+--- a/drivers/spi/spi-cadence-quadspi.c
++++ b/drivers/spi/spi-cadence-quadspi.c
+@@ -1768,32 +1768,36 @@ static int cqspi_remove(struct platform_device *pdev)
+ return 0;
+ }
+
+-#ifdef CONFIG_PM_SLEEP
+ static int cqspi_suspend(struct device *dev)
+ {
+ struct cqspi_st *cqspi = dev_get_drvdata(dev);
++ struct spi_master *master = dev_get_drvdata(dev);
++ int ret;
+
++ ret = spi_master_suspend(master);
+ cqspi_controller_enable(cqspi, 0);
+- return 0;
++
++ clk_disable_unprepare(cqspi->clk);
++
++ return ret;
+ }
+
+ static int cqspi_resume(struct device *dev)
+ {
+ struct cqspi_st *cqspi = dev_get_drvdata(dev);
++ struct spi_master *master = dev_get_drvdata(dev);
+
+- cqspi_controller_enable(cqspi, 1);
+- return 0;
+-}
++ clk_prepare_enable(cqspi->clk);
++ cqspi_wait_idle(cqspi);
++ cqspi_controller_init(cqspi);
+
+-static const struct dev_pm_ops cqspi__dev_pm_ops = {
+- .suspend = cqspi_suspend,
+- .resume = cqspi_resume,
+-};
++ cqspi->current_cs = -1;
++ cqspi->sclk = 0;
++
++ return spi_master_resume(master);
++}
+
+-#define CQSPI_DEV_PM_OPS (&cqspi__dev_pm_ops)
+-#else
+-#define CQSPI_DEV_PM_OPS NULL
+-#endif
++static DEFINE_SIMPLE_DEV_PM_OPS(cqspi_dev_pm_ops, cqspi_suspend, cqspi_resume);
+
+ static const struct cqspi_driver_platdata cdns_qspi = {
+ .quirks = CQSPI_DISABLE_DAC_MODE,
+@@ -1860,7 +1864,7 @@ static struct platform_driver cqspi_platform_driver = {
+ .remove = cqspi_remove,
+ .driver = {
+ .name = CQSPI_NAME,
+- .pm = CQSPI_DEV_PM_OPS,
++ .pm = &cqspi_dev_pm_ops,
+ .of_match_table = cqspi_dt_ids,
+ },
+ };
+diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c
+index 93152144fd2ec..5602f052b2b50 100644
+--- a/drivers/spi/spi-fsl-spi.c
++++ b/drivers/spi/spi-fsl-spi.c
+@@ -181,8 +181,8 @@ static int mspi_apply_qe_mode_quirks(struct spi_mpc8xxx_cs *cs,
+ struct spi_device *spi,
+ int bits_per_word)
+ {
+- /* QE uses Little Endian for words > 8
+- * so transform all words > 8 into 8 bits
++ /* CPM/QE uses Little Endian for words > 8
++ * so transform 16 and 32 bits words into 8 bits
+ * Unfortnatly that doesn't work for LSB so
+ * reject these for now */
+ /* Note: 32 bits word, LSB works iff
+@@ -190,9 +190,11 @@ static int mspi_apply_qe_mode_quirks(struct spi_mpc8xxx_cs *cs,
+ if (spi->mode & SPI_LSB_FIRST &&
+ bits_per_word > 8)
+ return -EINVAL;
+- if (bits_per_word > 8)
++ if (bits_per_word <= 8)
++ return bits_per_word;
++ if (bits_per_word == 16 || bits_per_word == 32)
+ return 8; /* pretend its 8 bits */
+- return bits_per_word;
++ return -EINVAL;
+ }
+
+ static int fsl_spi_setup_transfer(struct spi_device *spi,
+@@ -222,7 +224,7 @@ static int fsl_spi_setup_transfer(struct spi_device *spi,
+ bits_per_word = mspi_apply_cpu_mode_quirks(cs, spi,
+ mpc8xxx_spi,
+ bits_per_word);
+- else if (mpc8xxx_spi->flags & SPI_QE)
++ else
+ bits_per_word = mspi_apply_qe_mode_quirks(cs, spi,
+ bits_per_word);
+
+diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
+index e4ccd0c329d06..6c9c87cd14cae 100644
+--- a/drivers/spi/spi-imx.c
++++ b/drivers/spi/spi-imx.c
+@@ -1856,13 +1856,11 @@ static int spi_imx_remove(struct platform_device *pdev)
+
+ spi_unregister_controller(controller);
+
+- ret = pm_runtime_resume_and_get(spi_imx->dev);
+- if (ret < 0) {
+- dev_err(spi_imx->dev, "failed to enable clock\n");
+- return ret;
+- }
+-
+- writel(0, spi_imx->base + MXC_CSPICTRL);
++ ret = pm_runtime_get_sync(spi_imx->dev);
++ if (ret >= 0)
++ writel(0, spi_imx->base + MXC_CSPICTRL);
++ else
++ dev_warn(spi_imx->dev, "failed to enable clock, skip hw disable\n");
+
+ pm_runtime_dont_use_autosuspend(spi_imx->dev);
+ pm_runtime_put_sync(spi_imx->dev);
+diff --git a/drivers/spi/spi-pci1xxxx.c b/drivers/spi/spi-pci1xxxx.c
+index a31c3b612a430..13efbfeff92ce 100644
+--- a/drivers/spi/spi-pci1xxxx.c
++++ b/drivers/spi/spi-pci1xxxx.c
+@@ -58,7 +58,7 @@
+ #define VENDOR_ID_MCHP 0x1055
+
+ #define SPI_SUSPEND_CONFIG 0x101
+-#define SPI_RESUME_CONFIG 0x303
++#define SPI_RESUME_CONFIG 0x203
+
+ struct pci1xxxx_spi_internal {
+ u8 hw_inst;
+@@ -199,8 +199,9 @@ static int pci1xxxx_spi_transfer_one(struct spi_controller *spi_ctlr,
+ else
+ regval &= ~SPI_MST_CTL_MODE_SEL;
+
+- regval |= ((clkdiv << 5) | SPI_FORCE_CE | (len << 8));
++ regval |= ((clkdiv << 5) | SPI_FORCE_CE);
+ regval &= ~SPI_MST_CTL_CMD_LEN_MASK;
++ regval |= (len << 8);
+ writel(regval, par->reg_base +
+ SPI_MST_CTL_REG_OFFSET(p->hw_inst));
+ regval = readl(par->reg_base +
+diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c
+index 678dc51ef0174..205e54f157b4a 100644
+--- a/drivers/spi/spi-qup.c
++++ b/drivers/spi/spi-qup.c
+@@ -1277,18 +1277,22 @@ static int spi_qup_remove(struct platform_device *pdev)
+ struct spi_qup *controller = spi_master_get_devdata(master);
+ int ret;
+
+- ret = pm_runtime_resume_and_get(&pdev->dev);
+- if (ret < 0)
+- return ret;
++ ret = pm_runtime_get_sync(&pdev->dev);
+
+- ret = spi_qup_set_state(controller, QUP_STATE_RESET);
+- if (ret)
+- return ret;
++ if (ret >= 0) {
++ ret = spi_qup_set_state(controller, QUP_STATE_RESET);
++ if (ret)
++ dev_warn(&pdev->dev, "failed to reset controller (%pe)\n",
++ ERR_PTR(ret));
+
+- spi_qup_release_dma(master);
++ clk_disable_unprepare(controller->cclk);
++ clk_disable_unprepare(controller->iclk);
++ } else {
++ dev_warn(&pdev->dev, "failed to resume, skip hw disable (%pe)\n",
++ ERR_PTR(ret));
++ }
+
+- clk_disable_unprepare(controller->cclk);
+- clk_disable_unprepare(controller->iclk);
++ spi_qup_release_dma(master);
+
+ pm_runtime_put_noidle(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+diff --git a/drivers/spi/spi-sn-f-ospi.c b/drivers/spi/spi-sn-f-ospi.c
+index 333b22dfd8dba..0aedade8908c4 100644
+--- a/drivers/spi/spi-sn-f-ospi.c
++++ b/drivers/spi/spi-sn-f-ospi.c
+@@ -561,7 +561,7 @@ static bool f_ospi_supports_op(struct spi_mem *mem,
+ if (!f_ospi_supports_op_width(mem, op))
+ return false;
+
+- return true;
++ return spi_mem_default_supports_op(mem, op);
+ }
+
+ static int f_ospi_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
+diff --git a/drivers/spmi/spmi.c b/drivers/spmi/spmi.c
+index 55381592bb5a6..e73d3017863cb 100644
+--- a/drivers/spmi/spmi.c
++++ b/drivers/spmi/spmi.c
+@@ -350,7 +350,8 @@ static void spmi_drv_remove(struct device *dev)
+ const struct spmi_driver *sdrv = to_spmi_driver(dev->driver);
+
+ pm_runtime_get_sync(dev);
+- sdrv->remove(to_spmi_device(dev));
++ if (sdrv->remove)
++ sdrv->remove(to_spmi_device(dev));
+ pm_runtime_put_noidle(dev);
+
+ pm_runtime_disable(dev);
+diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
+index e4cf42438487d..636c45b128438 100644
+--- a/drivers/staging/iio/resolver/ad2s1210.c
++++ b/drivers/staging/iio/resolver/ad2s1210.c
+@@ -101,7 +101,7 @@ struct ad2s1210_state {
+ static const int ad2s1210_mode_vals[4][2] = {
+ [MOD_POS] = { 0, 0 },
+ [MOD_VEL] = { 0, 1 },
+- [MOD_CONFIG] = { 1, 0 },
++ [MOD_CONFIG] = { 1, 1 },
+ };
+
+ static inline void ad2s1210_set_mode(enum ad2s1210_mode mode,
+diff --git a/drivers/staging/media/deprecated/saa7146/av7110/av7110_av.c b/drivers/staging/media/deprecated/saa7146/av7110/av7110_av.c
+index 0bf513c26b6b5..a5c5bebad3061 100644
+--- a/drivers/staging/media/deprecated/saa7146/av7110/av7110_av.c
++++ b/drivers/staging/media/deprecated/saa7146/av7110/av7110_av.c
+@@ -823,10 +823,10 @@ static int write_ts_to_decoder(struct av7110 *av7110, int type, const u8 *buf, s
+ av7110_ipack_flush(ipack);
+
+ if (buf[3] & ADAPT_FIELD) {
++ if (buf[4] > len - 1 - 4)
++ return 0;
+ len -= buf[4] + 1;
+ buf += buf[4] + 1;
+- if (!len)
+- return 0;
+ }
+
+ av7110_ipack_instant_repack(buf + 4, len - 4, ipack);
+diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c
+index 7bab7586918c1..82806f198074a 100644
+--- a/drivers/staging/media/rkvdec/rkvdec.c
++++ b/drivers/staging/media/rkvdec/rkvdec.c
+@@ -1066,6 +1066,8 @@ static int rkvdec_remove(struct platform_device *pdev)
+ {
+ struct rkvdec_dev *rkvdec = platform_get_drvdata(pdev);
+
++ cancel_delayed_work_sync(&rkvdec->watchdog_work);
++
+ rkvdec_v4l2_cleanup(rkvdec);
+ pm_runtime_disable(&pdev->dev);
+ pm_runtime_dont_use_autosuspend(&pdev->dev);
+diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c
+index a43d5ff667163..a50a4d0a8f715 100644
+--- a/drivers/staging/media/sunxi/cedrus/cedrus.c
++++ b/drivers/staging/media/sunxi/cedrus/cedrus.c
+@@ -547,6 +547,7 @@ static int cedrus_remove(struct platform_device *pdev)
+ {
+ struct cedrus_dev *dev = platform_get_drvdata(pdev);
+
++ cancel_delayed_work_sync(&dev->watchdog_work);
+ if (media_devnode_is_registered(dev->mdev.devnode)) {
+ media_device_unregister(&dev->mdev);
+ v4l2_m2m_unregister_media_controller(dev->m2m_dev);
+diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c
+index f8fbe78ccad9f..699ee7754428c 100644
+--- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c
++++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c
+@@ -716,6 +716,7 @@ static int _rtl92e_sta_up(struct net_device *dev, bool is_silent_reset)
+ else
+ netif_wake_queue(dev);
+
++ priv->bfirst_after_down = false;
+ return 0;
+ }
+
+diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme.c b/drivers/staging/rtl8723bs/core/rtw_mlme.c
+index c6fd6cf741ef6..091842d70d486 100644
+--- a/drivers/staging/rtl8723bs/core/rtw_mlme.c
++++ b/drivers/staging/rtl8723bs/core/rtw_mlme.c
+@@ -1549,7 +1549,7 @@ void _rtw_join_timeout_handler(struct timer_list *t)
+ if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
+ return;
+
+- spin_lock_irq(&pmlmepriv->lock);
++ spin_lock_bh(&pmlmepriv->lock);
+
+ if (rtw_to_roam(adapter) > 0) { /* join timeout caused by roaming */
+ while (1) {
+@@ -1577,7 +1577,7 @@ void _rtw_join_timeout_handler(struct timer_list *t)
+
+ }
+
+- spin_unlock_irq(&pmlmepriv->lock);
++ spin_unlock_bh(&pmlmepriv->lock);
+ }
+
+ /*
+@@ -1590,11 +1590,11 @@ void rtw_scan_timeout_handler(struct timer_list *t)
+ mlmepriv.scan_to_timer);
+ struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+
+- spin_lock_irq(&pmlmepriv->lock);
++ spin_lock_bh(&pmlmepriv->lock);
+
+ _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
+
+- spin_unlock_irq(&pmlmepriv->lock);
++ spin_unlock_bh(&pmlmepriv->lock);
+
+ rtw_indicate_scan_done(adapter, true);
+ }
+diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
+index baf4da7bb3b4e..3f7a9f7f5f4e3 100644
+--- a/drivers/target/iscsi/iscsi_target.c
++++ b/drivers/target/iscsi/iscsi_target.c
+@@ -1190,9 +1190,10 @@ int iscsit_setup_scsi_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
+ * Initialize struct se_cmd descriptor from target_core_mod infrastructure
+ */
+ __target_init_cmd(&cmd->se_cmd, &iscsi_ops,
+- conn->sess->se_sess, be32_to_cpu(hdr->data_length),
+- cmd->data_direction, sam_task_attr,
+- cmd->sense_buffer + 2, scsilun_to_int(&hdr->lun));
++ conn->sess->se_sess, be32_to_cpu(hdr->data_length),
++ cmd->data_direction, sam_task_attr,
++ cmd->sense_buffer + 2, scsilun_to_int(&hdr->lun),
++ conn->cmd_cnt);
+
+ pr_debug("Got SCSI Command, ITT: 0x%08x, CmdSN: 0x%08x,"
+ " ExpXferLen: %u, Length: %u, CID: %hu\n", hdr->itt,
+@@ -2055,7 +2056,8 @@ iscsit_handle_task_mgt_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
+ __target_init_cmd(&cmd->se_cmd, &iscsi_ops,
+ conn->sess->se_sess, 0, DMA_NONE,
+ TCM_SIMPLE_TAG, cmd->sense_buffer + 2,
+- scsilun_to_int(&hdr->lun));
++ scsilun_to_int(&hdr->lun),
++ conn->cmd_cnt);
+
+ target_get_sess_cmd(&cmd->se_cmd, true);
+
+@@ -4218,9 +4220,12 @@ static void iscsit_release_commands_from_conn(struct iscsit_conn *conn)
+ list_for_each_entry_safe(cmd, cmd_tmp, &tmp_list, i_conn_node) {
+ struct se_cmd *se_cmd = &cmd->se_cmd;
+
+- if (se_cmd->se_tfo != NULL) {
+- spin_lock_irq(&se_cmd->t_state_lock);
+- if (se_cmd->transport_state & CMD_T_ABORTED) {
++ if (!se_cmd->se_tfo)
++ continue;
++
++ spin_lock_irq(&se_cmd->t_state_lock);
++ if (se_cmd->transport_state & CMD_T_ABORTED) {
++ if (!(se_cmd->transport_state & CMD_T_TAS))
+ /*
+ * LIO's abort path owns the cleanup for this,
+ * so put it back on the list and let
+@@ -4228,11 +4233,10 @@ static void iscsit_release_commands_from_conn(struct iscsit_conn *conn)
+ */
+ list_move_tail(&cmd->i_conn_node,
+ &conn->conn_cmd_list);
+- } else {
+- se_cmd->transport_state |= CMD_T_FABRIC_STOP;
+- }
+- spin_unlock_irq(&se_cmd->t_state_lock);
++ } else {
++ se_cmd->transport_state |= CMD_T_FABRIC_STOP;
+ }
++ spin_unlock_irq(&se_cmd->t_state_lock);
+ }
+ spin_unlock_bh(&conn->cmd_lock);
+
+@@ -4243,6 +4247,16 @@ static void iscsit_release_commands_from_conn(struct iscsit_conn *conn)
+ iscsit_free_cmd(cmd, true);
+
+ }
++
++ /*
++ * Wait on commands that were cleaned up via the aborted_task path.
++ * LLDs that implement iscsit_wait_conn will already have waited for
++ * commands.
++ */
++ if (!conn->conn_transport->iscsit_wait_conn) {
++ target_stop_cmd_counter(conn->cmd_cnt);
++ target_wait_for_cmds(conn->cmd_cnt);
++ }
+ }
+
+ static void iscsit_stop_timers_for_cmds(
+diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c
+index 27e448c2d066c..274bdd7845ca9 100644
+--- a/drivers/target/iscsi/iscsi_target_login.c
++++ b/drivers/target/iscsi/iscsi_target_login.c
+@@ -1147,8 +1147,14 @@ static struct iscsit_conn *iscsit_alloc_conn(struct iscsi_np *np)
+ goto free_conn_cpumask;
+ }
+
++ conn->cmd_cnt = target_alloc_cmd_counter();
++ if (!conn->cmd_cnt)
++ goto free_conn_allowed_cpumask;
++
+ return conn;
+
++free_conn_allowed_cpumask:
++ free_cpumask_var(conn->allowed_cpumask);
+ free_conn_cpumask:
+ free_cpumask_var(conn->conn_cpumask);
+ free_conn_ops:
+@@ -1162,6 +1168,7 @@ free_conn:
+
+ void iscsit_free_conn(struct iscsit_conn *conn)
+ {
++ target_free_cmd_counter(conn->cmd_cnt);
+ free_cpumask_var(conn->allowed_cpumask);
+ free_cpumask_var(conn->conn_cpumask);
+ kfree(conn->conn_ops);
+diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
+index f6e58410ec3f9..aeb03136773d5 100644
+--- a/drivers/target/target_core_device.c
++++ b/drivers/target/target_core_device.c
+@@ -782,6 +782,7 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name)
+ spin_lock_init(&dev->t10_alua.lba_map_lock);
+
+ INIT_WORK(&dev->delayed_cmd_work, target_do_delayed_work);
++ mutex_init(&dev->lun_reset_mutex);
+
+ dev->t10_wwn.t10_dev = dev;
+ /*
+diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h
+index 38a6d08f75b34..85e35cf582e50 100644
+--- a/drivers/target/target_core_internal.h
++++ b/drivers/target/target_core_internal.h
+@@ -138,7 +138,6 @@ int init_se_kmem_caches(void);
+ void release_se_kmem_caches(void);
+ u32 scsi_get_new_index(scsi_index_t);
+ void transport_subsystem_check_init(void);
+-void transport_uninit_session(struct se_session *);
+ unsigned char *transport_dump_cmd_direction(struct se_cmd *);
+ void transport_dump_dev_state(struct se_device *, char *, int *);
+ void transport_dump_dev_info(struct se_device *, struct se_lun *,
+diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c
+index 2b95b4550a637..4718db628222b 100644
+--- a/drivers/target/target_core_tmr.c
++++ b/drivers/target/target_core_tmr.c
+@@ -188,14 +188,23 @@ static void core_tmr_drain_tmr_list(
+ * LUN_RESET tmr..
+ */
+ spin_lock_irqsave(&dev->se_tmr_lock, flags);
+- if (tmr)
+- list_del_init(&tmr->tmr_list);
+ list_for_each_entry_safe(tmr_p, tmr_pp, &dev->dev_tmr_list, tmr_list) {
++ if (tmr_p == tmr)
++ continue;
++
+ cmd = tmr_p->task_cmd;
+ if (!cmd) {
+ pr_err("Unable to locate struct se_cmd for TMR\n");
+ continue;
+ }
++
++ /*
++ * We only execute one LUN_RESET at a time so we can't wait
++ * on them below.
++ */
++ if (tmr_p->function == TMR_LUN_RESET)
++ continue;
++
+ /*
+ * If this function was called with a valid pr_res_key
+ * parameter (eg: for PROUT PREEMPT_AND_ABORT service action
+@@ -379,14 +388,25 @@ int core_tmr_lun_reset(
+ tmr_nacl->initiatorname);
+ }
+ }
++
++
++ /*
++ * We only allow one reset or preempt and abort to execute at a time
++ * to prevent one call from claiming all the cmds causing a second
++ * call from returning while cmds it should have waited on are still
++ * running.
++ */
++ mutex_lock(&dev->lun_reset_mutex);
++
+ pr_debug("LUN_RESET: %s starting for [%s], tas: %d\n",
+ (preempt_and_abort_list) ? "Preempt" : "TMR",
+ dev->transport->name, tas);
+-
+ core_tmr_drain_tmr_list(dev, tmr, preempt_and_abort_list);
+ core_tmr_drain_state_list(dev, prout_cmd, tmr_sess, tas,
+ preempt_and_abort_list);
+
++ mutex_unlock(&dev->lun_reset_mutex);
++
+ /*
+ * Clear any legacy SPC-2 reservation when called during
+ * LOGICAL UNIT RESET
+diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c
+index 736847c933e5c..8ebccdbd94f0e 100644
+--- a/drivers/target/target_core_tpg.c
++++ b/drivers/target/target_core_tpg.c
+@@ -328,7 +328,7 @@ static void target_shutdown_sessions(struct se_node_acl *acl)
+ restart:
+ spin_lock_irqsave(&acl->nacl_sess_lock, flags);
+ list_for_each_entry(sess, &acl->acl_sess_list, sess_acl_list) {
+- if (atomic_read(&sess->stopped))
++ if (sess->cmd_cnt && atomic_read(&sess->cmd_cnt->stopped))
+ continue;
+
+ list_del_init(&sess->sess_acl_list);
+diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
+index 5926316252eb9..86adff2a86edd 100644
+--- a/drivers/target/target_core_transport.c
++++ b/drivers/target/target_core_transport.c
+@@ -220,12 +220,52 @@ void transport_subsystem_check_init(void)
+ sub_api_initialized = 1;
+ }
+
+-static void target_release_sess_cmd_refcnt(struct percpu_ref *ref)
++static void target_release_cmd_refcnt(struct percpu_ref *ref)
+ {
+- struct se_session *sess = container_of(ref, typeof(*sess), cmd_count);
++ struct target_cmd_counter *cmd_cnt = container_of(ref,
++ typeof(*cmd_cnt),
++ refcnt);
++ wake_up(&cmd_cnt->refcnt_wq);
++}
++
++struct target_cmd_counter *target_alloc_cmd_counter(void)
++{
++ struct target_cmd_counter *cmd_cnt;
++ int rc;
++
++ cmd_cnt = kzalloc(sizeof(*cmd_cnt), GFP_KERNEL);
++ if (!cmd_cnt)
++ return NULL;
++
++ init_completion(&cmd_cnt->stop_done);
++ init_waitqueue_head(&cmd_cnt->refcnt_wq);
++ atomic_set(&cmd_cnt->stopped, 0);
+
+- wake_up(&sess->cmd_count_wq);
++ rc = percpu_ref_init(&cmd_cnt->refcnt, target_release_cmd_refcnt, 0,
++ GFP_KERNEL);
++ if (rc)
++ goto free_cmd_cnt;
++
++ return cmd_cnt;
++
++free_cmd_cnt:
++ kfree(cmd_cnt);
++ return NULL;
+ }
++EXPORT_SYMBOL_GPL(target_alloc_cmd_counter);
++
++void target_free_cmd_counter(struct target_cmd_counter *cmd_cnt)
++{
++ /*
++ * Drivers like loop do not call target_stop_session during session
++ * shutdown so we have to drop the ref taken at init time here.
++ */
++ if (!atomic_read(&cmd_cnt->stopped))
++ percpu_ref_put(&cmd_cnt->refcnt);
++
++ percpu_ref_exit(&cmd_cnt->refcnt);
++}
++EXPORT_SYMBOL_GPL(target_free_cmd_counter);
+
+ /**
+ * transport_init_session - initialize a session object
+@@ -233,32 +273,14 @@ static void target_release_sess_cmd_refcnt(struct percpu_ref *ref)
+ *
+ * The caller must have zero-initialized @se_sess before calling this function.
+ */
+-int transport_init_session(struct se_session *se_sess)
++void transport_init_session(struct se_session *se_sess)
+ {
+ INIT_LIST_HEAD(&se_sess->sess_list);
+ INIT_LIST_HEAD(&se_sess->sess_acl_list);
+ spin_lock_init(&se_sess->sess_cmd_lock);
+- init_waitqueue_head(&se_sess->cmd_count_wq);
+- init_completion(&se_sess->stop_done);
+- atomic_set(&se_sess->stopped, 0);
+- return percpu_ref_init(&se_sess->cmd_count,
+- target_release_sess_cmd_refcnt, 0, GFP_KERNEL);
+ }
+ EXPORT_SYMBOL(transport_init_session);
+
+-void transport_uninit_session(struct se_session *se_sess)
+-{
+- /*
+- * Drivers like iscsi and loop do not call target_stop_session
+- * during session shutdown so we have to drop the ref taken at init
+- * time here.
+- */
+- if (!atomic_read(&se_sess->stopped))
+- percpu_ref_put(&se_sess->cmd_count);
+-
+- percpu_ref_exit(&se_sess->cmd_count);
+-}
+-
+ /**
+ * transport_alloc_session - allocate a session object and initialize it
+ * @sup_prot_ops: bitmask that defines which T10-PI modes are supported.
+@@ -266,7 +288,6 @@ void transport_uninit_session(struct se_session *se_sess)
+ struct se_session *transport_alloc_session(enum target_prot_op sup_prot_ops)
+ {
+ struct se_session *se_sess;
+- int ret;
+
+ se_sess = kmem_cache_zalloc(se_sess_cache, GFP_KERNEL);
+ if (!se_sess) {
+@@ -274,11 +295,7 @@ struct se_session *transport_alloc_session(enum target_prot_op sup_prot_ops)
+ " se_sess_cache\n");
+ return ERR_PTR(-ENOMEM);
+ }
+- ret = transport_init_session(se_sess);
+- if (ret < 0) {
+- kmem_cache_free(se_sess_cache, se_sess);
+- return ERR_PTR(ret);
+- }
++ transport_init_session(se_sess);
+ se_sess->sup_prot_ops = sup_prot_ops;
+
+ return se_sess;
+@@ -444,8 +461,13 @@ target_setup_session(struct se_portal_group *tpg,
+ int (*callback)(struct se_portal_group *,
+ struct se_session *, void *))
+ {
++ struct target_cmd_counter *cmd_cnt;
+ struct se_session *sess;
++ int rc;
+
++ cmd_cnt = target_alloc_cmd_counter();
++ if (!cmd_cnt)
++ return ERR_PTR(-ENOMEM);
+ /*
+ * If the fabric driver is using percpu-ida based pre allocation
+ * of I/O descriptor tags, go ahead and perform that setup now..
+@@ -455,29 +477,36 @@ target_setup_session(struct se_portal_group *tpg,
+ else
+ sess = transport_alloc_session(prot_op);
+
+- if (IS_ERR(sess))
+- return sess;
++ if (IS_ERR(sess)) {
++ rc = PTR_ERR(sess);
++ goto free_cnt;
++ }
++ sess->cmd_cnt = cmd_cnt;
+
+ sess->se_node_acl = core_tpg_check_initiator_node_acl(tpg,
+ (unsigned char *)initiatorname);
+ if (!sess->se_node_acl) {
+- transport_free_session(sess);
+- return ERR_PTR(-EACCES);
++ rc = -EACCES;
++ goto free_sess;
+ }
+ /*
+ * Go ahead and perform any remaining fabric setup that is
+ * required before transport_register_session().
+ */
+ if (callback != NULL) {
+- int rc = callback(tpg, sess, private);
+- if (rc) {
+- transport_free_session(sess);
+- return ERR_PTR(rc);
+- }
++ rc = callback(tpg, sess, private);
++ if (rc)
++ goto free_sess;
+ }
+
+ transport_register_session(tpg, sess->se_node_acl, sess, private);
+ return sess;
++
++free_sess:
++ transport_free_session(sess);
++free_cnt:
++ target_free_cmd_counter(cmd_cnt);
++ return ERR_PTR(rc);
+ }
+ EXPORT_SYMBOL(target_setup_session);
+
+@@ -602,7 +631,8 @@ void transport_free_session(struct se_session *se_sess)
+ sbitmap_queue_free(&se_sess->sess_tag_pool);
+ kvfree(se_sess->sess_cmd_map);
+ }
+- transport_uninit_session(se_sess);
++ if (se_sess->cmd_cnt)
++ target_free_cmd_counter(se_sess->cmd_cnt);
+ kmem_cache_free(se_sess_cache, se_sess);
+ }
+ EXPORT_SYMBOL(transport_free_session);
+@@ -1412,14 +1442,12 @@ target_cmd_size_check(struct se_cmd *cmd, unsigned int size)
+ *
+ * Preserves the value of @cmd->tag.
+ */
+-void __target_init_cmd(
+- struct se_cmd *cmd,
+- const struct target_core_fabric_ops *tfo,
+- struct se_session *se_sess,
+- u32 data_length,
+- int data_direction,
+- int task_attr,
+- unsigned char *sense_buffer, u64 unpacked_lun)
++void __target_init_cmd(struct se_cmd *cmd,
++ const struct target_core_fabric_ops *tfo,
++ struct se_session *se_sess, u32 data_length,
++ int data_direction, int task_attr,
++ unsigned char *sense_buffer, u64 unpacked_lun,
++ struct target_cmd_counter *cmd_cnt)
+ {
+ INIT_LIST_HEAD(&cmd->se_delayed_node);
+ INIT_LIST_HEAD(&cmd->se_qf_node);
+@@ -1439,6 +1467,7 @@ void __target_init_cmd(
+ cmd->sam_task_attr = task_attr;
+ cmd->sense_buffer = sense_buffer;
+ cmd->orig_fe_lun = unpacked_lun;
++ cmd->cmd_cnt = cmd_cnt;
+
+ if (!(cmd->se_cmd_flags & SCF_USE_CPUID))
+ cmd->cpuid = raw_smp_processor_id();
+@@ -1658,7 +1687,8 @@ int target_init_cmd(struct se_cmd *se_cmd, struct se_session *se_sess,
+ * target_core_fabric_ops->queue_status() callback
+ */
+ __target_init_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess, data_length,
+- data_dir, task_attr, sense, unpacked_lun);
++ data_dir, task_attr, sense, unpacked_lun,
++ se_sess->cmd_cnt);
+
+ /*
+ * Obtain struct se_cmd->cmd_kref reference. A second kref_get here is
+@@ -1953,7 +1983,8 @@ int target_submit_tmr(struct se_cmd *se_cmd, struct se_session *se_sess,
+ BUG_ON(!se_tpg);
+
+ __target_init_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess,
+- 0, DMA_NONE, TCM_SIMPLE_TAG, sense, unpacked_lun);
++ 0, DMA_NONE, TCM_SIMPLE_TAG, sense, unpacked_lun,
++ se_sess->cmd_cnt);
+ /*
+ * FIXME: Currently expect caller to handle se_cmd->se_tmr_req
+ * allocation failure.
+@@ -2957,7 +2988,6 @@ EXPORT_SYMBOL(transport_generic_free_cmd);
+ */
+ int target_get_sess_cmd(struct se_cmd *se_cmd, bool ack_kref)
+ {
+- struct se_session *se_sess = se_cmd->se_sess;
+ int ret = 0;
+
+ /*
+@@ -2970,9 +3000,14 @@ int target_get_sess_cmd(struct se_cmd *se_cmd, bool ack_kref)
+ se_cmd->se_cmd_flags |= SCF_ACK_KREF;
+ }
+
+- if (!percpu_ref_tryget_live(&se_sess->cmd_count))
+- ret = -ESHUTDOWN;
+-
++ /*
++ * Users like xcopy do not use counters since they never do a stop
++ * and wait.
++ */
++ if (se_cmd->cmd_cnt) {
++ if (!percpu_ref_tryget_live(&se_cmd->cmd_cnt->refcnt))
++ ret = -ESHUTDOWN;
++ }
+ if (ret && ack_kref)
+ target_put_sess_cmd(se_cmd);
+
+@@ -2993,7 +3028,7 @@ static void target_free_cmd_mem(struct se_cmd *cmd)
+ static void target_release_cmd_kref(struct kref *kref)
+ {
+ struct se_cmd *se_cmd = container_of(kref, struct se_cmd, cmd_kref);
+- struct se_session *se_sess = se_cmd->se_sess;
++ struct target_cmd_counter *cmd_cnt = se_cmd->cmd_cnt;
+ struct completion *free_compl = se_cmd->free_compl;
+ struct completion *abrt_compl = se_cmd->abrt_compl;
+
+@@ -3004,7 +3039,8 @@ static void target_release_cmd_kref(struct kref *kref)
+ if (abrt_compl)
+ complete(abrt_compl);
+
+- percpu_ref_put(&se_sess->cmd_count);
++ if (cmd_cnt)
++ percpu_ref_put(&cmd_cnt->refcnt);
+ }
+
+ /**
+@@ -3123,46 +3159,67 @@ void target_show_cmd(const char *pfx, struct se_cmd *cmd)
+ }
+ EXPORT_SYMBOL(target_show_cmd);
+
+-static void target_stop_session_confirm(struct percpu_ref *ref)
++static void target_stop_cmd_counter_confirm(struct percpu_ref *ref)
++{
++ struct target_cmd_counter *cmd_cnt = container_of(ref,
++ struct target_cmd_counter,
++ refcnt);
++ complete_all(&cmd_cnt->stop_done);
++}
++
++/**
++ * target_stop_cmd_counter - Stop new IO from being added to the counter.
++ * @cmd_cnt: counter to stop
++ */
++void target_stop_cmd_counter(struct target_cmd_counter *cmd_cnt)
+ {
+- struct se_session *se_sess = container_of(ref, struct se_session,
+- cmd_count);
+- complete_all(&se_sess->stop_done);
++ pr_debug("Stopping command counter.\n");
++ if (!atomic_cmpxchg(&cmd_cnt->stopped, 0, 1))
++ percpu_ref_kill_and_confirm(&cmd_cnt->refcnt,
++ target_stop_cmd_counter_confirm);
+ }
++EXPORT_SYMBOL_GPL(target_stop_cmd_counter);
+
+ /**
+ * target_stop_session - Stop new IO from being queued on the session.
+- * @se_sess: session to stop
++ * @se_sess: session to stop
+ */
+ void target_stop_session(struct se_session *se_sess)
+ {
+- pr_debug("Stopping session queue.\n");
+- if (atomic_cmpxchg(&se_sess->stopped, 0, 1) == 0)
+- percpu_ref_kill_and_confirm(&se_sess->cmd_count,
+- target_stop_session_confirm);
++ target_stop_cmd_counter(se_sess->cmd_cnt);
+ }
+ EXPORT_SYMBOL(target_stop_session);
+
+ /**
+- * target_wait_for_sess_cmds - Wait for outstanding commands
+- * @se_sess: session to wait for active I/O
++ * target_wait_for_cmds - Wait for outstanding cmds.
++ * @cmd_cnt: counter to wait for active I/O for.
+ */
+-void target_wait_for_sess_cmds(struct se_session *se_sess)
++void target_wait_for_cmds(struct target_cmd_counter *cmd_cnt)
+ {
+ int ret;
+
+- WARN_ON_ONCE(!atomic_read(&se_sess->stopped));
++ WARN_ON_ONCE(!atomic_read(&cmd_cnt->stopped));
+
+ do {
+ pr_debug("Waiting for running cmds to complete.\n");
+- ret = wait_event_timeout(se_sess->cmd_count_wq,
+- percpu_ref_is_zero(&se_sess->cmd_count),
+- 180 * HZ);
++ ret = wait_event_timeout(cmd_cnt->refcnt_wq,
++ percpu_ref_is_zero(&cmd_cnt->refcnt),
++ 180 * HZ);
+ } while (ret <= 0);
+
+- wait_for_completion(&se_sess->stop_done);
++ wait_for_completion(&cmd_cnt->stop_done);
+ pr_debug("Waiting for cmds done.\n");
+ }
++EXPORT_SYMBOL_GPL(target_wait_for_cmds);
++
++/**
++ * target_wait_for_sess_cmds - Wait for outstanding commands
++ * @se_sess: session to wait for active I/O
++ */
++void target_wait_for_sess_cmds(struct se_session *se_sess)
++{
++ target_wait_for_cmds(se_sess->cmd_cnt);
++}
+ EXPORT_SYMBOL(target_wait_for_sess_cmds);
+
+ /*
+diff --git a/drivers/target/target_core_xcopy.c b/drivers/target/target_core_xcopy.c
+index 49eaee022ef1d..91ed015b588c6 100644
+--- a/drivers/target/target_core_xcopy.c
++++ b/drivers/target/target_core_xcopy.c
+@@ -461,8 +461,6 @@ static const struct target_core_fabric_ops xcopy_pt_tfo = {
+
+ int target_xcopy_setup_pt(void)
+ {
+- int ret;
+-
+ xcopy_wq = alloc_workqueue("xcopy_wq", WQ_MEM_RECLAIM, 0);
+ if (!xcopy_wq) {
+ pr_err("Unable to allocate xcopy_wq\n");
+@@ -479,9 +477,7 @@ int target_xcopy_setup_pt(void)
+ INIT_LIST_HEAD(&xcopy_pt_nacl.acl_list);
+ INIT_LIST_HEAD(&xcopy_pt_nacl.acl_sess_list);
+ memset(&xcopy_pt_sess, 0, sizeof(struct se_session));
+- ret = transport_init_session(&xcopy_pt_sess);
+- if (ret < 0)
+- goto destroy_wq;
++ transport_init_session(&xcopy_pt_sess);
+
+ xcopy_pt_nacl.se_tpg = &xcopy_pt_tpg;
+ xcopy_pt_nacl.nacl_sess = &xcopy_pt_sess;
+@@ -490,19 +486,12 @@ int target_xcopy_setup_pt(void)
+ xcopy_pt_sess.se_node_acl = &xcopy_pt_nacl;
+
+ return 0;
+-
+-destroy_wq:
+- destroy_workqueue(xcopy_wq);
+- xcopy_wq = NULL;
+- return ret;
+ }
+
+ void target_xcopy_release_pt(void)
+ {
+- if (xcopy_wq) {
++ if (xcopy_wq)
+ destroy_workqueue(xcopy_wq);
+- transport_uninit_session(&xcopy_pt_sess);
+- }
+ }
+
+ /*
+@@ -602,8 +591,8 @@ static int target_xcopy_read_source(
+ (unsigned long long)src_lba, transfer_length_block, src_bytes);
+
+ __target_init_cmd(se_cmd, &xcopy_pt_tfo, &xcopy_pt_sess, src_bytes,
+- DMA_FROM_DEVICE, 0, &xpt_cmd.sense_buffer[0], 0);
+-
++ DMA_FROM_DEVICE, 0, &xpt_cmd.sense_buffer[0], 0,
++ NULL);
+ rc = target_xcopy_setup_pt_cmd(&xpt_cmd, xop, src_dev, &cdb[0],
+ remote_port);
+ if (rc < 0) {
+@@ -647,8 +636,8 @@ static int target_xcopy_write_destination(
+ (unsigned long long)dst_lba, transfer_length_block, dst_bytes);
+
+ __target_init_cmd(se_cmd, &xcopy_pt_tfo, &xcopy_pt_sess, dst_bytes,
+- DMA_TO_DEVICE, 0, &xpt_cmd.sense_buffer[0], 0);
+-
++ DMA_TO_DEVICE, 0, &xpt_cmd.sense_buffer[0], 0,
++ NULL);
+ rc = target_xcopy_setup_pt_cmd(&xpt_cmd, xop, dst_dev, &cdb[0],
+ remote_port);
+ if (rc < 0) {
+diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c
+index 8440692e3890d..62f1e691659e3 100644
+--- a/drivers/thermal/mtk_thermal.c
++++ b/drivers/thermal/mtk_thermal.c
+@@ -1028,7 +1028,12 @@ static int mtk_thermal_probe(struct platform_device *pdev)
+ return -ENODEV;
+ }
+
+- auxadc_base = of_iomap(auxadc, 0);
++ auxadc_base = devm_of_iomap(&pdev->dev, auxadc, 0, NULL);
++ if (IS_ERR(auxadc_base)) {
++ of_node_put(auxadc);
++ return PTR_ERR(auxadc_base);
++ }
++
+ auxadc_phys_base = of_get_phys_base(auxadc);
+
+ of_node_put(auxadc);
+@@ -1044,7 +1049,12 @@ static int mtk_thermal_probe(struct platform_device *pdev)
+ return -ENODEV;
+ }
+
+- apmixed_base = of_iomap(apmixedsys, 0);
++ apmixed_base = devm_of_iomap(&pdev->dev, apmixedsys, 0, NULL);
++ if (IS_ERR(apmixed_base)) {
++ of_node_put(apmixedsys);
++ return PTR_ERR(apmixed_base);
++ }
++
+ apmixed_phys_base = of_get_phys_base(apmixedsys);
+
+ of_node_put(apmixedsys);
+diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h
+index f034723b1b40e..f79cae48a8eab 100644
+--- a/drivers/thunderbolt/tb.h
++++ b/drivers/thunderbolt/tb.h
+@@ -1058,7 +1058,7 @@ void tb_port_lane_bonding_disable(struct tb_port *port);
+ int tb_port_wait_for_link_width(struct tb_port *port, int width,
+ int timeout_msec);
+ int tb_port_update_credits(struct tb_port *port);
+-bool tb_port_is_clx_enabled(struct tb_port *port, enum tb_clx clx);
++bool tb_port_is_clx_enabled(struct tb_port *port, unsigned int clx);
+
+ int tb_switch_find_vse_cap(struct tb_switch *sw, enum tb_switch_vse_cap vsec);
+ int tb_switch_find_cap(struct tb_switch *sw, enum tb_switch_cap cap);
+diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h
+index 287153d325365..1e8fe44a7099f 100644
+--- a/drivers/tty/serial/8250/8250.h
++++ b/drivers/tty/serial/8250/8250.h
+@@ -365,6 +365,13 @@ static inline void serial8250_do_prepare_rx_dma(struct uart_8250_port *p)
+ if (dma->prepare_rx_dma)
+ dma->prepare_rx_dma(p);
+ }
++
++static inline bool serial8250_tx_dma_running(struct uart_8250_port *p)
++{
++ struct uart_8250_dma *dma = p->dma;
++
++ return dma && dma->tx_running;
++}
+ #else
+ static inline int serial8250_tx_dma(struct uart_8250_port *p)
+ {
+@@ -380,6 +387,11 @@ static inline int serial8250_request_dma(struct uart_8250_port *p)
+ return -1;
+ }
+ static inline void serial8250_release_dma(struct uart_8250_port *p) { }
++
++static inline bool serial8250_tx_dma_running(struct uart_8250_port *p)
++{
++ return false;
++}
+ #endif
+
+ static inline int ns16550a_goto_highspeed(struct uart_8250_port *up)
+diff --git a/drivers/tty/serial/8250/8250_bcm7271.c b/drivers/tty/serial/8250/8250_bcm7271.c
+index ed5a947476920..f801b1f5b46c0 100644
+--- a/drivers/tty/serial/8250/8250_bcm7271.c
++++ b/drivers/tty/serial/8250/8250_bcm7271.c
+@@ -1014,14 +1014,16 @@ static int brcmuart_probe(struct platform_device *pdev)
+ /* See if a Baud clock has been specified */
+ baud_mux_clk = of_clk_get_by_name(np, "sw_baud");
+ if (IS_ERR(baud_mux_clk)) {
+- if (PTR_ERR(baud_mux_clk) == -EPROBE_DEFER)
+- return -EPROBE_DEFER;
++ if (PTR_ERR(baud_mux_clk) == -EPROBE_DEFER) {
++ ret = -EPROBE_DEFER;
++ goto release_dma;
++ }
+ dev_dbg(dev, "BAUD MUX clock not specified\n");
+ } else {
+ dev_dbg(dev, "BAUD MUX clock found\n");
+ ret = clk_prepare_enable(baud_mux_clk);
+ if (ret)
+- return ret;
++ goto release_dma;
+ priv->baud_mux_clk = baud_mux_clk;
+ init_real_clk_rates(dev, priv);
+ clk_rate = priv->default_mux_rate;
+@@ -1029,7 +1031,8 @@ static int brcmuart_probe(struct platform_device *pdev)
+
+ if (clk_rate == 0) {
+ dev_err(dev, "clock-frequency or clk not defined\n");
+- return -EINVAL;
++ ret = -EINVAL;
++ goto release_dma;
+ }
+
+ dev_dbg(dev, "DMA is %senabled\n", priv->dma_enabled ? "" : "not ");
+@@ -1116,7 +1119,9 @@ err1:
+ serial8250_unregister_port(priv->line);
+ err:
+ brcmuart_free_bufs(dev, priv);
+- brcmuart_arbitration(priv, 0);
++release_dma:
++ if (priv->dma_enabled)
++ brcmuart_arbitration(priv, 0);
+ return ret;
+ }
+
+@@ -1128,7 +1133,8 @@ static int brcmuart_remove(struct platform_device *pdev)
+ hrtimer_cancel(&priv->hrt);
+ serial8250_unregister_port(priv->line);
+ brcmuart_free_bufs(&pdev->dev, priv);
+- brcmuart_arbitration(priv, 0);
++ if (priv->dma_enabled)
++ brcmuart_arbitration(priv, 0);
+ return 0;
+ }
+
+diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
+index d006467ec7843..fa220620511e5 100644
+--- a/drivers/tty/serial/8250/8250_port.c
++++ b/drivers/tty/serial/8250/8250_port.c
+@@ -15,6 +15,7 @@
+ #include <linux/moduleparam.h>
+ #include <linux/ioport.h>
+ #include <linux/init.h>
++#include <linux/irq.h>
+ #include <linux/console.h>
+ #include <linux/gpio/consumer.h>
+ #include <linux/sysrq.h>
+@@ -1925,6 +1926,7 @@ static bool handle_rx_dma(struct uart_8250_port *up, unsigned int iir)
+ int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
+ {
+ struct uart_8250_port *up = up_to_u8250p(port);
++ struct tty_port *tport = &port->state->port;
+ bool skip_rx = false;
+ unsigned long flags;
+ u16 status;
+@@ -1950,6 +1952,8 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
+ skip_rx = true;
+
+ if (status & (UART_LSR_DR | UART_LSR_BI) && !skip_rx) {
++ if (irqd_is_wakeup_set(irq_get_irq_data(port->irq)))
++ pm_wakeup_event(tport->tty->dev, 0);
+ if (!up->dma || handle_rx_dma(up, iir))
+ status = serial8250_rx_chars(up, status);
+ }
+@@ -2009,18 +2013,19 @@ static int serial8250_tx_threshold_handle_irq(struct uart_port *port)
+ static unsigned int serial8250_tx_empty(struct uart_port *port)
+ {
+ struct uart_8250_port *up = up_to_u8250p(port);
++ unsigned int result = 0;
+ unsigned long flags;
+- u16 lsr;
+
+ serial8250_rpm_get(up);
+
+ spin_lock_irqsave(&port->lock, flags);
+- lsr = serial_lsr_in(up);
++ if (!serial8250_tx_dma_running(up) && uart_lsr_tx_empty(serial_lsr_in(up)))
++ result = TIOCSER_TEMT;
+ spin_unlock_irqrestore(&port->lock, flags);
+
+ serial8250_rpm_put(up);
+
+- return uart_lsr_tx_empty(lsr) ? TIOCSER_TEMT : 0;
++ return result;
+ }
+
+ unsigned int serial8250_do_get_mctrl(struct uart_port *port)
+diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
+index 59c10bceebbef..29b50a0792dcf 100644
+--- a/drivers/tty/serial/fsl_lpuart.c
++++ b/drivers/tty/serial/fsl_lpuart.c
+@@ -1270,7 +1270,7 @@ static inline int lpuart_start_rx_dma(struct lpuart_port *sport)
+ * 10ms at any baud rate.
+ */
+ sport->rx_dma_rng_buf_len = (DMA_RX_TIMEOUT * baud / bits / 1000) * 2;
+- sport->rx_dma_rng_buf_len = (1 << (fls(sport->rx_dma_rng_buf_len) - 1));
++ sport->rx_dma_rng_buf_len = (1 << fls(sport->rx_dma_rng_buf_len));
+ if (sport->rx_dma_rng_buf_len < 16)
+ sport->rx_dma_rng_buf_len = 16;
+
+diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c
+index 4eb24e3407f80..9ec39edf56b81 100644
+--- a/drivers/tty/serial/max310x.c
++++ b/drivers/tty/serial/max310x.c
+@@ -525,6 +525,11 @@ static bool max310x_reg_precious(struct device *dev, unsigned int reg)
+ return false;
+ }
+
++static bool max310x_reg_noinc(struct device *dev, unsigned int reg)
++{
++ return reg == MAX310X_RHR_REG;
++}
++
+ static int max310x_set_baud(struct uart_port *port, int baud)
+ {
+ unsigned int mode = 0, div = 0, frac = 0, c = 0, F = 0;
+@@ -651,14 +656,14 @@ static void max310x_batch_write(struct uart_port *port, u8 *txbuf, unsigned int
+ {
+ struct max310x_one *one = to_max310x_port(port);
+
+- regmap_raw_write(one->regmap, MAX310X_THR_REG, txbuf, len);
++ regmap_noinc_write(one->regmap, MAX310X_THR_REG, txbuf, len);
+ }
+
+ static void max310x_batch_read(struct uart_port *port, u8 *rxbuf, unsigned int len)
+ {
+ struct max310x_one *one = to_max310x_port(port);
+
+- regmap_raw_read(one->regmap, MAX310X_RHR_REG, rxbuf, len);
++ regmap_noinc_read(one->regmap, MAX310X_RHR_REG, rxbuf, len);
+ }
+
+ static void max310x_handle_rx(struct uart_port *port, unsigned int rxlen)
+@@ -1469,6 +1474,10 @@ static struct regmap_config regcfg = {
+ .writeable_reg = max310x_reg_writeable,
+ .volatile_reg = max310x_reg_volatile,
+ .precious_reg = max310x_reg_precious,
++ .writeable_noinc_reg = max310x_reg_noinc,
++ .readable_noinc_reg = max310x_reg_noinc,
++ .max_raw_read = MAX310X_FIFO_SIZE,
++ .max_raw_write = MAX310X_FIFO_SIZE,
+ };
+
+ #ifdef CONFIG_SPI_MASTER
+@@ -1554,6 +1563,10 @@ static struct regmap_config regcfg_i2c = {
+ .volatile_reg = max310x_reg_volatile,
+ .precious_reg = max310x_reg_precious,
+ .max_register = MAX310X_I2C_REVID_EXTREG,
++ .writeable_noinc_reg = max310x_reg_noinc,
++ .readable_noinc_reg = max310x_reg_noinc,
++ .max_raw_read = MAX310X_FIFO_SIZE,
++ .max_raw_write = MAX310X_FIFO_SIZE,
+ };
+
+ static const struct max310x_if_cfg max310x_i2c_if_cfg = {
+diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
+index ec874f3a567ca..eea526d34fdda 100644
+--- a/drivers/tty/serial/serial_core.c
++++ b/drivers/tty/serial/serial_core.c
+@@ -1552,7 +1552,7 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg)
+ goto out;
+
+ /* rs485_config requires more locking than others */
+- if (cmd == TIOCGRS485)
++ if (cmd == TIOCSRS485)
+ down_write(&tty->termios_rwsem);
+
+ mutex_lock(&port->mutex);
+@@ -1595,7 +1595,7 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg)
+ }
+ out_up:
+ mutex_unlock(&port->mutex);
+- if (cmd == TIOCGRS485)
++ if (cmd == TIOCSRS485)
+ up_write(&tty->termios_rwsem);
+ out:
+ return ret;
+diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
+index 409e91d6829a5..81a53cc41dcb8 100644
+--- a/drivers/tty/serial/stm32-usart.c
++++ b/drivers/tty/serial/stm32-usart.c
+@@ -689,8 +689,9 @@ static void stm32_usart_transmit_chars(struct uart_port *port)
+ int ret;
+
+ if (!stm32_port->hw_flow_control &&
+- port->rs485.flags & SER_RS485_ENABLED) {
+- stm32_port->txdone = false;
++ port->rs485.flags & SER_RS485_ENABLED &&
++ (port->x_char ||
++ !(uart_circ_empty(xmit) || uart_tx_stopped(port)))) {
+ stm32_usart_tc_interrupt_disable(port);
+ stm32_usart_rs485_rts_enable(port);
+ }
+diff --git a/drivers/tty/tty.h b/drivers/tty/tty.h
+index f45cd683c02ea..1e0d80e98d263 100644
+--- a/drivers/tty/tty.h
++++ b/drivers/tty/tty.h
+@@ -62,6 +62,8 @@ int __tty_check_change(struct tty_struct *tty, int sig);
+ int tty_check_change(struct tty_struct *tty);
+ void __stop_tty(struct tty_struct *tty);
+ void __start_tty(struct tty_struct *tty);
++void tty_write_unlock(struct tty_struct *tty);
++int tty_write_lock(struct tty_struct *tty, int ndelay);
+ void tty_vhangup_session(struct tty_struct *tty);
+ void tty_open_proc_set_tty(struct file *filp, struct tty_struct *tty);
+ int tty_signal_session_leader(struct tty_struct *tty, int exit_session);
+diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
+index 36fb945fdad48..8e3de07f103da 100644
+--- a/drivers/tty/tty_io.c
++++ b/drivers/tty/tty_io.c
+@@ -933,13 +933,13 @@ static ssize_t tty_read(struct kiocb *iocb, struct iov_iter *to)
+ return i;
+ }
+
+-static void tty_write_unlock(struct tty_struct *tty)
++void tty_write_unlock(struct tty_struct *tty)
+ {
+ mutex_unlock(&tty->atomic_write_lock);
+ wake_up_interruptible_poll(&tty->write_wait, EPOLLOUT);
+ }
+
+-static int tty_write_lock(struct tty_struct *tty, int ndelay)
++int tty_write_lock(struct tty_struct *tty, int ndelay)
+ {
+ if (!mutex_trylock(&tty->atomic_write_lock)) {
+ if (ndelay)
+diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c
+index ce511557b98b1..ad1cf51ecd11d 100644
+--- a/drivers/tty/tty_ioctl.c
++++ b/drivers/tty/tty_ioctl.c
+@@ -500,21 +500,42 @@ static int set_termios(struct tty_struct *tty, void __user *arg, int opt)
+ tmp_termios.c_ispeed = tty_termios_input_baud_rate(&tmp_termios);
+ tmp_termios.c_ospeed = tty_termios_baud_rate(&tmp_termios);
+
+- ld = tty_ldisc_ref(tty);
++ if (opt & (TERMIOS_FLUSH|TERMIOS_WAIT)) {
++retry_write_wait:
++ retval = wait_event_interruptible(tty->write_wait, !tty_chars_in_buffer(tty));
++ if (retval < 0)
++ return retval;
+
+- if (ld != NULL) {
+- if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer)
+- ld->ops->flush_buffer(tty);
+- tty_ldisc_deref(ld);
+- }
++ if (tty_write_lock(tty, 0) < 0)
++ goto retry_write_wait;
+
+- if (opt & TERMIOS_WAIT) {
+- tty_wait_until_sent(tty, 0);
+- if (signal_pending(current))
+- return -ERESTARTSYS;
+- }
++ /* Racing writer? */
++ if (tty_chars_in_buffer(tty)) {
++ tty_write_unlock(tty);
++ goto retry_write_wait;
++ }
+
+- tty_set_termios(tty, &tmp_termios);
++ ld = tty_ldisc_ref(tty);
++ if (ld != NULL) {
++ if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer)
++ ld->ops->flush_buffer(tty);
++ tty_ldisc_deref(ld);
++ }
++
++ if ((opt & TERMIOS_WAIT) && tty->ops->wait_until_sent) {
++ tty->ops->wait_until_sent(tty, 0);
++ if (signal_pending(current)) {
++ tty_write_unlock(tty);
++ return -ERESTARTSYS;
++ }
++ }
++
++ tty_set_termios(tty, &tmp_termios);
++
++ tty_write_unlock(tty);
++ } else {
++ tty_set_termios(tty, &tmp_termios);
++ }
+
+ /* FIXME: Arguably if tmp_termios == tty->termios AND the
+ actual requested termios was not tmp_termios then we may
+diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
+index 281fc51720cea..25084ce7c297b 100644
+--- a/drivers/usb/chipidea/core.c
++++ b/drivers/usb/chipidea/core.c
+@@ -1108,7 +1108,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
+ ret = ci_usb_phy_init(ci);
+ if (ret) {
+ dev_err(dev, "unable to init phy: %d\n", ret);
+- return ret;
++ goto ulpi_exit;
+ }
+
+ ci->hw_bank.phys = res->start;
+diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
+index 476b636185116..9f8c988c25cb1 100644
+--- a/drivers/usb/dwc3/core.c
++++ b/drivers/usb/dwc3/core.c
+@@ -1883,13 +1883,11 @@ static int dwc3_probe(struct platform_device *pdev)
+ spin_lock_init(&dwc->lock);
+ mutex_init(&dwc->mutex);
+
++ pm_runtime_get_noresume(dev);
+ pm_runtime_set_active(dev);
+ pm_runtime_use_autosuspend(dev);
+ pm_runtime_set_autosuspend_delay(dev, DWC3_DEFAULT_AUTOSUSPEND_DELAY);
+ pm_runtime_enable(dev);
+- ret = pm_runtime_get_sync(dev);
+- if (ret < 0)
+- goto err1;
+
+ pm_runtime_forbid(dev);
+
+@@ -1954,12 +1952,10 @@ err3:
+ dwc3_free_event_buffers(dwc);
+
+ err2:
+- pm_runtime_allow(&pdev->dev);
+-
+-err1:
+- pm_runtime_put_sync(&pdev->dev);
+- pm_runtime_disable(&pdev->dev);
+-
++ pm_runtime_allow(dev);
++ pm_runtime_disable(dev);
++ pm_runtime_set_suspended(dev);
++ pm_runtime_put_noidle(dev);
+ disable_clks:
+ dwc3_clk_disable(dwc);
+ assert_reset:
+@@ -1983,6 +1979,7 @@ static int dwc3_remove(struct platform_device *pdev)
+ dwc3_core_exit(dwc);
+ dwc3_ulpi_exit(dwc);
+
++ pm_runtime_allow(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+ pm_runtime_put_noidle(&pdev->dev);
+ pm_runtime_set_suspended(&pdev->dev);
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
+index cf5b4f49c3ed8..3faac3244c7db 100644
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -2532,29 +2532,17 @@ static int __dwc3_gadget_start(struct dwc3 *dwc);
+ static int dwc3_gadget_soft_disconnect(struct dwc3 *dwc)
+ {
+ unsigned long flags;
++ int ret;
+
+ spin_lock_irqsave(&dwc->lock, flags);
+ dwc->connected = false;
+
+ /*
+- * Per databook, when we want to stop the gadget, if a control transfer
+- * is still in process, complete it and get the core into setup phase.
++ * Attempt to end pending SETUP status phase, and not wait for the
++ * function to do so.
+ */
+- if (dwc->ep0state != EP0_SETUP_PHASE) {
+- int ret;
+-
+- if (dwc->delayed_status)
+- dwc3_ep0_send_delayed_status(dwc);
+-
+- reinit_completion(&dwc->ep0_in_setup);
+-
+- spin_unlock_irqrestore(&dwc->lock, flags);
+- ret = wait_for_completion_timeout(&dwc->ep0_in_setup,
+- msecs_to_jiffies(DWC3_PULL_UP_TIMEOUT));
+- spin_lock_irqsave(&dwc->lock, flags);
+- if (ret == 0)
+- dev_warn(dwc->dev, "timed out waiting for SETUP phase\n");
+- }
++ if (dwc->delayed_status)
++ dwc3_ep0_send_delayed_status(dwc);
+
+ /*
+ * In the Synopsys DesignWare Cores USB3 Databook Rev. 3.30a
+@@ -2567,6 +2555,33 @@ static int dwc3_gadget_soft_disconnect(struct dwc3 *dwc)
+ __dwc3_gadget_stop(dwc);
+ spin_unlock_irqrestore(&dwc->lock, flags);
+
++ /*
++ * Per databook, when we want to stop the gadget, if a control transfer
++ * is still in process, complete it and get the core into setup phase.
++ * In case the host is unresponsive to a SETUP transaction, forcefully
++ * stall the transfer, and move back to the SETUP phase, so that any
++ * pending endxfers can be executed.
++ */
++ if (dwc->ep0state != EP0_SETUP_PHASE) {
++ reinit_completion(&dwc->ep0_in_setup);
++
++ ret = wait_for_completion_timeout(&dwc->ep0_in_setup,
++ msecs_to_jiffies(DWC3_PULL_UP_TIMEOUT));
++ if (ret == 0) {
++ unsigned int dir;
++
++ dev_warn(dwc->dev, "wait for SETUP phase timed out\n");
++ spin_lock_irqsave(&dwc->lock, flags);
++ dir = !!dwc->ep0_expect_in;
++ if (dwc->ep0state == EP0_DATA_PHASE)
++ dwc3_ep0_end_control_data(dwc, dwc->eps[dir]);
++ else
++ dwc3_ep0_end_control_data(dwc, dwc->eps[!dir]);
++ dwc3_ep0_stall_and_restart(dwc);
++ spin_unlock_irqrestore(&dwc->lock, flags);
++ }
++ }
++
+ /*
+ * Note: if the GEVNTCOUNT indicates events in the event buffer, the
+ * driver needs to acknowledge them before the controller can halt.
+@@ -4247,15 +4262,8 @@ static void dwc3_gadget_interrupt(struct dwc3 *dwc,
+ break;
+ case DWC3_DEVICE_EVENT_SUSPEND:
+ /* It changed to be suspend event for version 2.30a and above */
+- if (!DWC3_VER_IS_PRIOR(DWC3, 230A)) {
+- /*
+- * Ignore suspend event until the gadget enters into
+- * USB_STATE_CONFIGURED state.
+- */
+- if (dwc->gadget->state >= USB_STATE_CONFIGURED)
+- dwc3_gadget_suspend_interrupt(dwc,
+- event->event_info);
+- }
++ if (!DWC3_VER_IS_PRIOR(DWC3, 230A))
++ dwc3_gadget_suspend_interrupt(dwc, event->event_info);
+ break;
+ case DWC3_DEVICE_EVENT_SOF:
+ case DWC3_DEVICE_EVENT_ERRATIC_ERROR:
+diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c
+index 658e2e21fdd0d..c21acebe8aae5 100644
+--- a/drivers/usb/gadget/function/f_tcm.c
++++ b/drivers/usb/gadget/function/f_tcm.c
+@@ -1054,7 +1054,7 @@ static void usbg_cmd_work(struct work_struct *work)
+ tv_nexus->tvn_se_sess->se_tpg->se_tpg_tfo,
+ tv_nexus->tvn_se_sess, cmd->data_len, DMA_NONE,
+ cmd->prio_attr, cmd->sense_iu.sense,
+- cmd->unpacked_lun);
++ cmd->unpacked_lun, NULL);
+ goto out;
+ }
+
+@@ -1183,7 +1183,7 @@ static void bot_cmd_work(struct work_struct *work)
+ tv_nexus->tvn_se_sess->se_tpg->se_tpg_tfo,
+ tv_nexus->tvn_se_sess, cmd->data_len, DMA_NONE,
+ cmd->prio_attr, cmd->sense_iu.sense,
+- cmd->unpacked_lun);
++ cmd->unpacked_lun, NULL);
+ goto out;
+ }
+
+diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c
+index 23b0629a87743..b14cbd0a6d013 100644
+--- a/drivers/usb/gadget/udc/core.c
++++ b/drivers/usb/gadget/udc/core.c
+@@ -37,6 +37,10 @@ static struct bus_type gadget_bus_type;
+ * @vbus: for udcs who care about vbus status, this value is real vbus status;
+ * for udcs who do not care about vbus status, this value is always true
+ * @started: the UDC's started state. True if the UDC had started.
++ * @connect_lock: protects udc->vbus, udc->started, gadget->connect, gadget->deactivate related
++ * functions. usb_gadget_connect_locked, usb_gadget_disconnect_locked,
++ * usb_udc_connect_control_locked, usb_gadget_udc_start_locked, usb_gadget_udc_stop_locked are
++ * called with this lock held.
+ *
+ * This represents the internal data structure which is used by the UDC-class
+ * to hold information about udc driver and gadget together.
+@@ -48,6 +52,7 @@ struct usb_udc {
+ struct list_head list;
+ bool vbus;
+ bool started;
++ struct mutex connect_lock;
+ };
+
+ static struct class *udc_class;
+@@ -660,17 +665,9 @@ out:
+ }
+ EXPORT_SYMBOL_GPL(usb_gadget_vbus_disconnect);
+
+-/**
+- * usb_gadget_connect - software-controlled connect to USB host
+- * @gadget:the peripheral being connected
+- *
+- * Enables the D+ (or potentially D-) pullup. The host will start
+- * enumerating this gadget when the pullup is active and a VBUS session
+- * is active (the link is powered).
+- *
+- * Returns zero on success, else negative errno.
+- */
+-int usb_gadget_connect(struct usb_gadget *gadget)
++/* Internal version of usb_gadget_connect needs to be called with connect_lock held. */
++static int usb_gadget_connect_locked(struct usb_gadget *gadget)
++ __must_hold(&gadget->udc->connect_lock)
+ {
+ int ret = 0;
+
+@@ -679,10 +676,15 @@ int usb_gadget_connect(struct usb_gadget *gadget)
+ goto out;
+ }
+
+- if (gadget->deactivated) {
++ if (gadget->connected)
++ goto out;
++
++ if (gadget->deactivated || !gadget->udc->started) {
+ /*
+ * If gadget is deactivated we only save new state.
+ * Gadget will be connected automatically after activation.
++ *
++ * udc first needs to be started before gadget can be pulled up.
+ */
+ gadget->connected = true;
+ goto out;
+@@ -697,22 +699,32 @@ out:
+
+ return ret;
+ }
+-EXPORT_SYMBOL_GPL(usb_gadget_connect);
+
+ /**
+- * usb_gadget_disconnect - software-controlled disconnect from USB host
+- * @gadget:the peripheral being disconnected
+- *
+- * Disables the D+ (or potentially D-) pullup, which the host may see
+- * as a disconnect (when a VBUS session is active). Not all systems
+- * support software pullup controls.
++ * usb_gadget_connect - software-controlled connect to USB host
++ * @gadget:the peripheral being connected
+ *
+- * Following a successful disconnect, invoke the ->disconnect() callback
+- * for the current gadget driver so that UDC drivers don't need to.
++ * Enables the D+ (or potentially D-) pullup. The host will start
++ * enumerating this gadget when the pullup is active and a VBUS session
++ * is active (the link is powered).
+ *
+ * Returns zero on success, else negative errno.
+ */
+-int usb_gadget_disconnect(struct usb_gadget *gadget)
++int usb_gadget_connect(struct usb_gadget *gadget)
++{
++ int ret;
++
++ mutex_lock(&gadget->udc->connect_lock);
++ ret = usb_gadget_connect_locked(gadget);
++ mutex_unlock(&gadget->udc->connect_lock);
++
++ return ret;
++}
++EXPORT_SYMBOL_GPL(usb_gadget_connect);
++
++/* Internal version of usb_gadget_disconnect needs to be called with connect_lock held. */
++static int usb_gadget_disconnect_locked(struct usb_gadget *gadget)
++ __must_hold(&gadget->udc->connect_lock)
+ {
+ int ret = 0;
+
+@@ -724,10 +736,12 @@ int usb_gadget_disconnect(struct usb_gadget *gadget)
+ if (!gadget->connected)
+ goto out;
+
+- if (gadget->deactivated) {
++ if (gadget->deactivated || !gadget->udc->started) {
+ /*
+ * If gadget is deactivated we only save new state.
+ * Gadget will stay disconnected after activation.
++ *
++ * udc should have been started before gadget being pulled down.
+ */
+ gadget->connected = false;
+ goto out;
+@@ -747,6 +761,30 @@ out:
+
+ return ret;
+ }
++
++/**
++ * usb_gadget_disconnect - software-controlled disconnect from USB host
++ * @gadget:the peripheral being disconnected
++ *
++ * Disables the D+ (or potentially D-) pullup, which the host may see
++ * as a disconnect (when a VBUS session is active). Not all systems
++ * support software pullup controls.
++ *
++ * Following a successful disconnect, invoke the ->disconnect() callback
++ * for the current gadget driver so that UDC drivers don't need to.
++ *
++ * Returns zero on success, else negative errno.
++ */
++int usb_gadget_disconnect(struct usb_gadget *gadget)
++{
++ int ret;
++
++ mutex_lock(&gadget->udc->connect_lock);
++ ret = usb_gadget_disconnect_locked(gadget);
++ mutex_unlock(&gadget->udc->connect_lock);
++
++ return ret;
++}
+ EXPORT_SYMBOL_GPL(usb_gadget_disconnect);
+
+ /**
+@@ -767,10 +805,11 @@ int usb_gadget_deactivate(struct usb_gadget *gadget)
+ if (gadget->deactivated)
+ goto out;
+
++ mutex_lock(&gadget->udc->connect_lock);
+ if (gadget->connected) {
+- ret = usb_gadget_disconnect(gadget);
++ ret = usb_gadget_disconnect_locked(gadget);
+ if (ret)
+- goto out;
++ goto unlock;
+
+ /*
+ * If gadget was being connected before deactivation, we want
+@@ -780,6 +819,8 @@ int usb_gadget_deactivate(struct usb_gadget *gadget)
+ }
+ gadget->deactivated = true;
+
++unlock:
++ mutex_unlock(&gadget->udc->connect_lock);
+ out:
+ trace_usb_gadget_deactivate(gadget, ret);
+
+@@ -803,6 +844,7 @@ int usb_gadget_activate(struct usb_gadget *gadget)
+ if (!gadget->deactivated)
+ goto out;
+
++ mutex_lock(&gadget->udc->connect_lock);
+ gadget->deactivated = false;
+
+ /*
+@@ -810,7 +852,8 @@ int usb_gadget_activate(struct usb_gadget *gadget)
+ * while it was being deactivated, we call usb_gadget_connect().
+ */
+ if (gadget->connected)
+- ret = usb_gadget_connect(gadget);
++ ret = usb_gadget_connect_locked(gadget);
++ mutex_unlock(&gadget->udc->connect_lock);
+
+ out:
+ trace_usb_gadget_activate(gadget, ret);
+@@ -1051,12 +1094,13 @@ EXPORT_SYMBOL_GPL(usb_gadget_set_state);
+
+ /* ------------------------------------------------------------------------- */
+
+-static void usb_udc_connect_control(struct usb_udc *udc)
++/* Acquire connect_lock before calling this function. */
++static void usb_udc_connect_control_locked(struct usb_udc *udc) __must_hold(&udc->connect_lock)
+ {
+- if (udc->vbus)
+- usb_gadget_connect(udc->gadget);
++ if (udc->vbus && udc->started)
++ usb_gadget_connect_locked(udc->gadget);
+ else
+- usb_gadget_disconnect(udc->gadget);
++ usb_gadget_disconnect_locked(udc->gadget);
+ }
+
+ /**
+@@ -1072,10 +1116,12 @@ void usb_udc_vbus_handler(struct usb_gadget *gadget, bool status)
+ {
+ struct usb_udc *udc = gadget->udc;
+
++ mutex_lock(&udc->connect_lock);
+ if (udc) {
+ udc->vbus = status;
+- usb_udc_connect_control(udc);
++ usb_udc_connect_control_locked(udc);
+ }
++ mutex_unlock(&udc->connect_lock);
+ }
+ EXPORT_SYMBOL_GPL(usb_udc_vbus_handler);
+
+@@ -1097,7 +1143,7 @@ void usb_gadget_udc_reset(struct usb_gadget *gadget,
+ EXPORT_SYMBOL_GPL(usb_gadget_udc_reset);
+
+ /**
+- * usb_gadget_udc_start - tells usb device controller to start up
++ * usb_gadget_udc_start_locked - tells usb device controller to start up
+ * @udc: The UDC to be started
+ *
+ * This call is issued by the UDC Class driver when it's about
+@@ -1108,8 +1154,11 @@ EXPORT_SYMBOL_GPL(usb_gadget_udc_reset);
+ * necessary to have it powered on.
+ *
+ * Returns zero on success, else negative errno.
++ *
++ * Caller should acquire connect_lock before invoking this function.
+ */
+-static inline int usb_gadget_udc_start(struct usb_udc *udc)
++static inline int usb_gadget_udc_start_locked(struct usb_udc *udc)
++ __must_hold(&udc->connect_lock)
+ {
+ int ret;
+
+@@ -1126,7 +1175,7 @@ static inline int usb_gadget_udc_start(struct usb_udc *udc)
+ }
+
+ /**
+- * usb_gadget_udc_stop - tells usb device controller we don't need it anymore
++ * usb_gadget_udc_stop_locked - tells usb device controller we don't need it anymore
+ * @udc: The UDC to be stopped
+ *
+ * This call is issued by the UDC Class driver after calling
+@@ -1135,8 +1184,11 @@ static inline int usb_gadget_udc_start(struct usb_udc *udc)
+ * The details are implementation specific, but it can go as
+ * far as powering off UDC completely and disable its data
+ * line pullups.
++ *
++ * Caller should acquire connect lock before invoking this function.
+ */
+-static inline void usb_gadget_udc_stop(struct usb_udc *udc)
++static inline void usb_gadget_udc_stop_locked(struct usb_udc *udc)
++ __must_hold(&udc->connect_lock)
+ {
+ if (!udc->started) {
+ dev_err(&udc->dev, "UDC had already stopped\n");
+@@ -1295,6 +1347,7 @@ int usb_add_gadget(struct usb_gadget *gadget)
+
+ udc->gadget = gadget;
+ gadget->udc = udc;
++ mutex_init(&udc->connect_lock);
+
+ udc->started = false;
+
+@@ -1496,11 +1549,15 @@ static int gadget_bind_driver(struct device *dev)
+ if (ret)
+ goto err_bind;
+
+- ret = usb_gadget_udc_start(udc);
+- if (ret)
++ mutex_lock(&udc->connect_lock);
++ ret = usb_gadget_udc_start_locked(udc);
++ if (ret) {
++ mutex_unlock(&udc->connect_lock);
+ goto err_start;
++ }
+ usb_gadget_enable_async_callbacks(udc);
+- usb_udc_connect_control(udc);
++ usb_udc_connect_control_locked(udc);
++ mutex_unlock(&udc->connect_lock);
+
+ kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE);
+ return 0;
+@@ -1531,12 +1588,14 @@ static void gadget_unbind_driver(struct device *dev)
+
+ kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE);
+
+- usb_gadget_disconnect(gadget);
++ mutex_lock(&udc->connect_lock);
++ usb_gadget_disconnect_locked(gadget);
+ usb_gadget_disable_async_callbacks(udc);
+ if (gadget->irq)
+ synchronize_irq(gadget->irq);
+ udc->driver->unbind(gadget);
+- usb_gadget_udc_stop(udc);
++ usb_gadget_udc_stop_locked(udc);
++ mutex_unlock(&udc->connect_lock);
+
+ mutex_lock(&udc_lock);
+ driver->is_bound = false;
+@@ -1622,11 +1681,15 @@ static ssize_t soft_connect_store(struct device *dev,
+ }
+
+ if (sysfs_streq(buf, "connect")) {
+- usb_gadget_udc_start(udc);
+- usb_gadget_connect(udc->gadget);
++ mutex_lock(&udc->connect_lock);
++ usb_gadget_udc_start_locked(udc);
++ usb_gadget_connect_locked(udc->gadget);
++ mutex_unlock(&udc->connect_lock);
+ } else if (sysfs_streq(buf, "disconnect")) {
+- usb_gadget_disconnect(udc->gadget);
+- usb_gadget_udc_stop(udc);
++ mutex_lock(&udc->connect_lock);
++ usb_gadget_disconnect_locked(udc->gadget);
++ usb_gadget_udc_stop_locked(udc);
++ mutex_unlock(&udc->connect_lock);
+ } else {
+ dev_err(dev, "unsupported command '%s'\n", buf);
+ ret = -EINVAL;
+diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c
+index 615ba0a6fbee1..32c9e369216c9 100644
+--- a/drivers/usb/gadget/udc/renesas_usb3.c
++++ b/drivers/usb/gadget/udc/renesas_usb3.c
+@@ -2596,6 +2596,7 @@ static int renesas_usb3_remove(struct platform_device *pdev)
+ debugfs_remove_recursive(usb3->dentry);
+ device_remove_file(&pdev->dev, &dev_attr_role);
+
++ cancel_work_sync(&usb3->role_work);
+ usb_role_switch_unregister(usb3->role_sw);
+
+ usb_del_gadget_udc(&usb3->gadget);
+diff --git a/drivers/usb/gadget/udc/tegra-xudc.c b/drivers/usb/gadget/udc/tegra-xudc.c
+index 76919d7570d23..3c7ffb35c35cd 100644
+--- a/drivers/usb/gadget/udc/tegra-xudc.c
++++ b/drivers/usb/gadget/udc/tegra-xudc.c
+@@ -2160,7 +2160,7 @@ static int tegra_xudc_gadget_vbus_draw(struct usb_gadget *gadget,
+
+ dev_dbg(xudc->dev, "%s: %u mA\n", __func__, m_a);
+
+- if (xudc->curr_usbphy->chg_type == SDP_TYPE)
++ if (xudc->curr_usbphy && xudc->curr_usbphy->chg_type == SDP_TYPE)
+ ret = usb_phy_set_power(xudc->curr_usbphy, m_a);
+
+ return ret;
+diff --git a/drivers/usb/host/xhci-debugfs.c b/drivers/usb/host/xhci-debugfs.c
+index dc832ddf7033f..bd40caeeb21c6 100644
+--- a/drivers/usb/host/xhci-debugfs.c
++++ b/drivers/usb/host/xhci-debugfs.c
+@@ -133,6 +133,7 @@ static void xhci_debugfs_regset(struct xhci_hcd *xhci, u32 base,
+ regset->regs = regs;
+ regset->nregs = nregs;
+ regset->base = hcd->regs + base;
++ regset->dev = hcd->self.controller;
+
+ debugfs_create_regset32((const char *)rgs->name, 0444, parent, regset);
+ }
+diff --git a/drivers/usb/host/xhci-rcar.c b/drivers/usb/host/xhci-rcar.c
+index aef0258a7160d..98525704be9d4 100644
+--- a/drivers/usb/host/xhci-rcar.c
++++ b/drivers/usb/host/xhci-rcar.c
+@@ -75,7 +75,6 @@ MODULE_FIRMWARE(XHCI_RCAR_FIRMWARE_NAME_V3);
+
+ /* For soc_device_attribute */
+ #define RCAR_XHCI_FIRMWARE_V2 BIT(0) /* FIRMWARE V2 */
+-#define RCAR_XHCI_FIRMWARE_V3 BIT(1) /* FIRMWARE V3 */
+
+ static const struct soc_device_attribute rcar_quirks_match[] = {
+ {
+@@ -147,8 +146,6 @@ static int xhci_rcar_download_firmware(struct usb_hcd *hcd)
+
+ if (quirks & RCAR_XHCI_FIRMWARE_V2)
+ firmware_name = XHCI_RCAR_FIRMWARE_NAME_V2;
+- else if (quirks & RCAR_XHCI_FIRMWARE_V3)
+- firmware_name = XHCI_RCAR_FIRMWARE_NAME_V3;
+ else
+ firmware_name = priv->firmware_name;
+
+diff --git a/drivers/usb/mtu3/mtu3_qmu.c b/drivers/usb/mtu3/mtu3_qmu.c
+index 2ea3157ddb6e2..e65586147965d 100644
+--- a/drivers/usb/mtu3/mtu3_qmu.c
++++ b/drivers/usb/mtu3/mtu3_qmu.c
+@@ -210,6 +210,7 @@ static struct qmu_gpd *advance_enq_gpd(struct mtu3_gpd_ring *ring)
+ return ring->enqueue;
+ }
+
++/* @dequeue may be NULL if ring is unallocated or freed */
+ static struct qmu_gpd *advance_deq_gpd(struct mtu3_gpd_ring *ring)
+ {
+ if (ring->dequeue < ring->end)
+@@ -484,7 +485,7 @@ static void qmu_done_tx(struct mtu3 *mtu, u8 epnum)
+ dev_dbg(mtu->dev, "%s EP%d, last=%p, current=%p, enq=%p\n",
+ __func__, epnum, gpd, gpd_current, ring->enqueue);
+
+- while (gpd != gpd_current && !GET_GPD_HWO(gpd)) {
++ while (gpd && gpd != gpd_current && !GET_GPD_HWO(gpd)) {
+
+ mreq = next_request(mep);
+
+@@ -523,7 +524,7 @@ static void qmu_done_rx(struct mtu3 *mtu, u8 epnum)
+ dev_dbg(mtu->dev, "%s EP%d, last=%p, current=%p, enq=%p\n",
+ __func__, epnum, gpd, gpd_current, ring->enqueue);
+
+- while (gpd != gpd_current && !GET_GPD_HWO(gpd)) {
++ while (gpd && gpd != gpd_current && !GET_GPD_HWO(gpd)) {
+
+ mreq = next_request(mep);
+
+diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
+index b7657984dd8df..6f532da59e08a 100644
+--- a/drivers/vhost/vdpa.c
++++ b/drivers/vhost/vdpa.c
+@@ -819,11 +819,7 @@ static void vhost_vdpa_unmap(struct vhost_vdpa *v,
+ if (!v->in_batch)
+ ops->set_map(vdpa, asid, iotlb);
+ }
+- /* If we are in the middle of batch processing, delay the free
+- * of AS until BATCH_END.
+- */
+- if (!v->in_batch && !iotlb->nmaps)
+- vhost_vdpa_remove_as(v, asid);
++
+ }
+
+ static int vhost_vdpa_va_map(struct vhost_vdpa *v,
+@@ -1080,8 +1076,6 @@ static int vhost_vdpa_process_iotlb_msg(struct vhost_dev *dev, u32 asid,
+ if (v->in_batch && ops->set_map)
+ ops->set_map(vdpa, asid, iotlb);
+ v->in_batch = false;
+- if (!iotlb->nmaps)
+- vhost_vdpa_remove_as(v, asid);
+ break;
+ default:
+ r = -EINVAL;
+diff --git a/drivers/video/fbdev/mmp/hw/mmp_ctrl.c b/drivers/video/fbdev/mmp/hw/mmp_ctrl.c
+index a9df8ee798102..51fbf02a03430 100644
+--- a/drivers/video/fbdev/mmp/hw/mmp_ctrl.c
++++ b/drivers/video/fbdev/mmp/hw/mmp_ctrl.c
+@@ -514,9 +514,9 @@ static int mmphw_probe(struct platform_device *pdev)
+ /* get clock */
+ ctrl->clk = devm_clk_get(ctrl->dev, mi->clk_name);
+ if (IS_ERR(ctrl->clk)) {
++ ret = PTR_ERR(ctrl->clk);
+ dev_err_probe(ctrl->dev, ret,
+ "unable to get clk %s\n", mi->clk_name);
+- ret = -ENOENT;
+ goto failed;
+ }
+ clk_prepare_enable(ctrl->clk);
+diff --git a/drivers/virt/coco/sev-guest/sev-guest.c b/drivers/virt/coco/sev-guest/sev-guest.c
+index 46f1a8d558b0b..0c7b47acba2a8 100644
+--- a/drivers/virt/coco/sev-guest/sev-guest.c
++++ b/drivers/virt/coco/sev-guest/sev-guest.c
+@@ -46,7 +46,15 @@ struct snp_guest_dev {
+
+ void *certs_data;
+ struct snp_guest_crypto *crypto;
++ /* request and response are in unencrypted memory */
+ struct snp_guest_msg *request, *response;
++
++ /*
++ * Avoid information leakage by double-buffering shared messages
++ * in fields that are in regular encrypted memory.
++ */
++ struct snp_guest_msg secret_request, secret_response;
++
+ struct snp_secrets_page_layout *layout;
+ struct snp_req_data input;
+ u32 *os_area_msg_seqno;
+@@ -266,14 +274,17 @@ static int dec_payload(struct snp_guest_dev *snp_dev, struct snp_guest_msg *msg,
+ static int verify_and_dec_payload(struct snp_guest_dev *snp_dev, void *payload, u32 sz)
+ {
+ struct snp_guest_crypto *crypto = snp_dev->crypto;
+- struct snp_guest_msg *resp = snp_dev->response;
+- struct snp_guest_msg *req = snp_dev->request;
++ struct snp_guest_msg *resp = &snp_dev->secret_response;
++ struct snp_guest_msg *req = &snp_dev->secret_request;
+ struct snp_guest_msg_hdr *req_hdr = &req->hdr;
+ struct snp_guest_msg_hdr *resp_hdr = &resp->hdr;
+
+ dev_dbg(snp_dev->dev, "response [seqno %lld type %d version %d sz %d]\n",
+ resp_hdr->msg_seqno, resp_hdr->msg_type, resp_hdr->msg_version, resp_hdr->msg_sz);
+
++ /* Copy response from shared memory to encrypted memory. */
++ memcpy(resp, snp_dev->response, sizeof(*resp));
++
+ /* Verify that the sequence counter is incremented by 1 */
+ if (unlikely(resp_hdr->msg_seqno != (req_hdr->msg_seqno + 1)))
+ return -EBADMSG;
+@@ -297,7 +308,7 @@ static int verify_and_dec_payload(struct snp_guest_dev *snp_dev, void *payload,
+ static int enc_payload(struct snp_guest_dev *snp_dev, u64 seqno, int version, u8 type,
+ void *payload, size_t sz)
+ {
+- struct snp_guest_msg *req = snp_dev->request;
++ struct snp_guest_msg *req = &snp_dev->secret_request;
+ struct snp_guest_msg_hdr *hdr = &req->hdr;
+
+ memset(req, 0, sizeof(*req));
+@@ -417,13 +428,21 @@ static int handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, in
+ if (!seqno)
+ return -EIO;
+
++ /* Clear shared memory's response for the host to populate. */
+ memset(snp_dev->response, 0, sizeof(struct snp_guest_msg));
+
+- /* Encrypt the userspace provided payload */
++ /* Encrypt the userspace provided payload in snp_dev->secret_request. */
+ rc = enc_payload(snp_dev, seqno, msg_ver, type, req_buf, req_sz);
+ if (rc)
+ return rc;
+
++ /*
++ * Write the fully encrypted request to the shared unencrypted
++ * request page.
++ */
++ memcpy(snp_dev->request, &snp_dev->secret_request,
++ sizeof(snp_dev->secret_request));
++
+ rc = __handle_guest_request(snp_dev, exit_code, fw_err);
+ if (rc) {
+ if (rc == -EIO && *fw_err == SNP_GUEST_REQ_INVALID_LEN)
+diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
+index 723c4e29e1d3b..5bee2ab62111b 100644
+--- a/drivers/virtio/virtio_ring.c
++++ b/drivers/virtio/virtio_ring.c
+@@ -848,6 +848,14 @@ static void virtqueue_disable_cb_split(struct virtqueue *_vq)
+
+ if (!(vq->split.avail_flags_shadow & VRING_AVAIL_F_NO_INTERRUPT)) {
+ vq->split.avail_flags_shadow |= VRING_AVAIL_F_NO_INTERRUPT;
++
++ /*
++ * If device triggered an event already it won't trigger one again:
++ * no need to disable.
++ */
++ if (vq->event_triggered)
++ return;
++
+ if (vq->event)
+ /* TODO: this is a hack. Figure out a cleaner value to write. */
+ vring_used_event(&vq->split.vring) = 0x0;
+@@ -1687,6 +1695,14 @@ static void virtqueue_disable_cb_packed(struct virtqueue *_vq)
+
+ if (vq->packed.event_flags_shadow != VRING_PACKED_EVENT_FLAG_DISABLE) {
+ vq->packed.event_flags_shadow = VRING_PACKED_EVENT_FLAG_DISABLE;
++
++ /*
++ * If device triggered an event already it won't trigger one again:
++ * no need to disable.
++ */
++ if (vq->event_triggered)
++ return;
++
+ vq->packed.vring.driver->flags =
+ cpu_to_le16(vq->packed.event_flags_shadow);
+ }
+@@ -2309,12 +2325,6 @@ void virtqueue_disable_cb(struct virtqueue *_vq)
+ {
+ struct vring_virtqueue *vq = to_vvq(_vq);
+
+- /* If device triggered an event already it won't trigger one again:
+- * no need to disable.
+- */
+- if (vq->event_triggered)
+- return;
+-
+ if (vq->packed_ring)
+ virtqueue_disable_cb_packed(_vq);
+ else
+diff --git a/drivers/xen/pcpu.c b/drivers/xen/pcpu.c
+index fd3a644b08559..b3e3d1bb37f3e 100644
+--- a/drivers/xen/pcpu.c
++++ b/drivers/xen/pcpu.c
+@@ -58,6 +58,7 @@ struct pcpu {
+ struct list_head list;
+ struct device dev;
+ uint32_t cpu_id;
++ uint32_t acpi_id;
+ uint32_t flags;
+ };
+
+@@ -249,6 +250,7 @@ static struct pcpu *create_and_register_pcpu(struct xenpf_pcpuinfo *info)
+
+ INIT_LIST_HEAD(&pcpu->list);
+ pcpu->cpu_id = info->xen_cpuid;
++ pcpu->acpi_id = info->acpi_id;
+ pcpu->flags = info->flags;
+
+ /* Need hold on xen_pcpu_lock before pcpu list manipulations */
+@@ -381,3 +383,21 @@ err1:
+ return ret;
+ }
+ arch_initcall(xen_pcpu_init);
++
++#ifdef CONFIG_ACPI
++bool __init xen_processor_present(uint32_t acpi_id)
++{
++ const struct pcpu *pcpu;
++ bool online = false;
++
++ mutex_lock(&xen_pcpu_lock);
++ list_for_each_entry(pcpu, &xen_pcpus, list)
++ if (pcpu->acpi_id == acpi_id) {
++ online = pcpu->flags & XEN_PCPU_FLAGS_ONLINE;
++ break;
++ }
++ mutex_unlock(&xen_pcpu_lock);
++
++ return online;
++}
++#endif
+diff --git a/fs/Makefile b/fs/Makefile
+index 4dea17840761a..80ab0154419ec 100644
+--- a/fs/Makefile
++++ b/fs/Makefile
+@@ -6,7 +6,6 @@
+ # Rewritten to use lists instead of if-statements.
+ #
+
+-obj-$(CONFIG_SYSCTL) += sysctls.o
+
+ obj-y := open.o read_write.o file_table.o super.o \
+ char_dev.o stat.o exec.o pipe.o namei.o fcntl.o \
+@@ -49,7 +48,7 @@ obj-$(CONFIG_FS_MBCACHE) += mbcache.o
+ obj-$(CONFIG_FS_POSIX_ACL) += posix_acl.o
+ obj-$(CONFIG_NFS_COMMON) += nfs_common/
+ obj-$(CONFIG_COREDUMP) += coredump.o
+-obj-$(CONFIG_SYSCTL) += drop_caches.o
++obj-$(CONFIG_SYSCTL) += drop_caches.o sysctls.o
+
+ obj-$(CONFIG_FHANDLE) += fhandle.o
+ obj-y += iomap/
+diff --git a/fs/afs/dir.c b/fs/afs/dir.c
+index b7c1f8c84b38a..be8f8da5b6b02 100644
+--- a/fs/afs/dir.c
++++ b/fs/afs/dir.c
+@@ -275,6 +275,7 @@ static struct afs_read *afs_read_dir(struct afs_vnode *dvnode, struct key *key)
+ loff_t i_size;
+ int nr_pages, i;
+ int ret;
++ loff_t remote_size = 0;
+
+ _enter("");
+
+@@ -289,6 +290,8 @@ static struct afs_read *afs_read_dir(struct afs_vnode *dvnode, struct key *key)
+
+ expand:
+ i_size = i_size_read(&dvnode->netfs.inode);
++ if (i_size < remote_size)
++ i_size = remote_size;
+ if (i_size < 2048) {
+ ret = afs_bad(dvnode, afs_file_error_dir_small);
+ goto error;
+@@ -364,6 +367,7 @@ expand:
+ * buffer.
+ */
+ up_write(&dvnode->validate_lock);
++ remote_size = req->file_size;
+ goto expand;
+ }
+
+diff --git a/fs/afs/inode.c b/fs/afs/inode.c
+index 6d3a3dbe49286..5921dd3687e39 100644
+--- a/fs/afs/inode.c
++++ b/fs/afs/inode.c
+@@ -230,6 +230,7 @@ static void afs_apply_status(struct afs_operation *op,
+ set_bit(AFS_VNODE_ZAP_DATA, &vnode->flags);
+ }
+ change_size = true;
++ data_changed = true;
+ } else if (vnode->status.type == AFS_FTYPE_DIR) {
+ /* Expected directory change is handled elsewhere so
+ * that we can locally edit the directory and save on a
+@@ -449,7 +450,7 @@ static void afs_get_inode_cache(struct afs_vnode *vnode)
+ 0 : FSCACHE_ADV_SINGLE_CHUNK,
+ &key, sizeof(key),
+ &aux, sizeof(aux),
+- vnode->status.size));
++ i_size_read(&vnode->netfs.inode)));
+ #endif
+ }
+
+@@ -765,6 +766,13 @@ int afs_getattr(struct user_namespace *mnt_userns, const struct path *path,
+ if (test_bit(AFS_VNODE_SILLY_DELETED, &vnode->flags) &&
+ stat->nlink > 0)
+ stat->nlink -= 1;
++
++ /* Lie about the size of directories. We maintain a locally
++ * edited copy and may make different allocation decisions on
++ * it, but we need to give userspace the server's size.
++ */
++ if (S_ISDIR(inode->i_mode))
++ stat->size = vnode->netfs.remote_i_size;
+ } while (need_seqretry(&vnode->cb_lock, seq));
+
+ done_seqretry(&vnode->cb_lock, seq);
+diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
+index c232636ecdfea..bff2d1fd3c812 100644
+--- a/fs/btrfs/ioctl.c
++++ b/fs/btrfs/ioctl.c
+@@ -3160,6 +3160,11 @@ static long btrfs_ioctl_scrub(struct file *file, void __user *arg)
+ if (IS_ERR(sa))
+ return PTR_ERR(sa);
+
++ if (sa->flags & ~BTRFS_SCRUB_SUPPORTED_FLAGS) {
++ ret = -EOPNOTSUPP;
++ goto out;
++ }
++
+ if (!(sa->flags & BTRFS_SCRUB_READONLY)) {
+ ret = mnt_want_write_file(file);
+ if (ret)
+diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
+index 210e400378818..e1c7f0aa0ba66 100644
+--- a/fs/ceph/caps.c
++++ b/fs/ceph/caps.c
+@@ -430,7 +430,7 @@ void ceph_reservation_status(struct ceph_fs_client *fsc,
+ *
+ * Called with i_ceph_lock held.
+ */
+-static struct ceph_cap *__get_cap_for_mds(struct ceph_inode_info *ci, int mds)
++struct ceph_cap *__get_cap_for_mds(struct ceph_inode_info *ci, int mds)
+ {
+ struct ceph_cap *cap;
+ struct rb_node *n = ci->i_caps.rb_node;
+diff --git a/fs/ceph/debugfs.c b/fs/ceph/debugfs.c
+index bec3c4549c07d..3904333fa6c38 100644
+--- a/fs/ceph/debugfs.c
++++ b/fs/ceph/debugfs.c
+@@ -248,14 +248,20 @@ static int metrics_caps_show(struct seq_file *s, void *p)
+ return 0;
+ }
+
+-static int caps_show_cb(struct inode *inode, struct ceph_cap *cap, void *p)
++static int caps_show_cb(struct inode *inode, int mds, void *p)
+ {
++ struct ceph_inode_info *ci = ceph_inode(inode);
+ struct seq_file *s = p;
+-
+- seq_printf(s, "0x%-17llx%-3d%-17s%-17s\n", ceph_ino(inode),
+- cap->session->s_mds,
+- ceph_cap_string(cap->issued),
+- ceph_cap_string(cap->implemented));
++ struct ceph_cap *cap;
++
++ spin_lock(&ci->i_ceph_lock);
++ cap = __get_cap_for_mds(ci, mds);
++ if (cap)
++ seq_printf(s, "0x%-17llx%-3d%-17s%-17s\n", ceph_ino(inode),
++ cap->session->s_mds,
++ ceph_cap_string(cap->issued),
++ ceph_cap_string(cap->implemented));
++ spin_unlock(&ci->i_ceph_lock);
+ return 0;
+ }
+
+diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
+index 27a245d959c0a..54e3c2ab21d22 100644
+--- a/fs/ceph/mds_client.c
++++ b/fs/ceph/mds_client.c
+@@ -1632,8 +1632,8 @@ static void cleanup_session_requests(struct ceph_mds_client *mdsc,
+ * Caller must hold session s_mutex.
+ */
+ int ceph_iterate_session_caps(struct ceph_mds_session *session,
+- int (*cb)(struct inode *, struct ceph_cap *,
+- void *), void *arg)
++ int (*cb)(struct inode *, int mds, void *),
++ void *arg)
+ {
+ struct list_head *p;
+ struct ceph_cap *cap;
+@@ -1645,6 +1645,8 @@ int ceph_iterate_session_caps(struct ceph_mds_session *session,
+ spin_lock(&session->s_cap_lock);
+ p = session->s_caps.next;
+ while (p != &session->s_caps) {
++ int mds;
++
+ cap = list_entry(p, struct ceph_cap, session_caps);
+ inode = igrab(&cap->ci->netfs.inode);
+ if (!inode) {
+@@ -1652,6 +1654,7 @@ int ceph_iterate_session_caps(struct ceph_mds_session *session,
+ continue;
+ }
+ session->s_cap_iterator = cap;
++ mds = cap->mds;
+ spin_unlock(&session->s_cap_lock);
+
+ if (last_inode) {
+@@ -1663,7 +1666,7 @@ int ceph_iterate_session_caps(struct ceph_mds_session *session,
+ old_cap = NULL;
+ }
+
+- ret = cb(inode, cap, arg);
++ ret = cb(inode, mds, arg);
+ last_inode = inode;
+
+ spin_lock(&session->s_cap_lock);
+@@ -1696,20 +1699,25 @@ out:
+ return ret;
+ }
+
+-static int remove_session_caps_cb(struct inode *inode, struct ceph_cap *cap,
+- void *arg)
++static int remove_session_caps_cb(struct inode *inode, int mds, void *arg)
+ {
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ bool invalidate = false;
+- int iputs;
++ struct ceph_cap *cap;
++ int iputs = 0;
+
+- dout("removing cap %p, ci is %p, inode is %p\n",
+- cap, ci, &ci->netfs.inode);
+ spin_lock(&ci->i_ceph_lock);
+- iputs = ceph_purge_inode_cap(inode, cap, &invalidate);
++ cap = __get_cap_for_mds(ci, mds);
++ if (cap) {
++ dout(" removing cap %p, ci is %p, inode is %p\n",
++ cap, ci, &ci->netfs.inode);
++
++ iputs = ceph_purge_inode_cap(inode, cap, &invalidate);
++ }
+ spin_unlock(&ci->i_ceph_lock);
+
+- wake_up_all(&ci->i_cap_wq);
++ if (cap)
++ wake_up_all(&ci->i_cap_wq);
+ if (invalidate)
+ ceph_queue_invalidate(inode);
+ while (iputs--)
+@@ -1780,8 +1788,7 @@ enum {
+ *
+ * caller must hold s_mutex.
+ */
+-static int wake_up_session_cb(struct inode *inode, struct ceph_cap *cap,
+- void *arg)
++static int wake_up_session_cb(struct inode *inode, int mds, void *arg)
+ {
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ unsigned long ev = (unsigned long)arg;
+@@ -1792,12 +1799,14 @@ static int wake_up_session_cb(struct inode *inode, struct ceph_cap *cap,
+ ci->i_requested_max_size = 0;
+ spin_unlock(&ci->i_ceph_lock);
+ } else if (ev == RENEWCAPS) {
+- if (cap->cap_gen < atomic_read(&cap->session->s_cap_gen)) {
+- /* mds did not re-issue stale cap */
+- spin_lock(&ci->i_ceph_lock);
++ struct ceph_cap *cap;
++
++ spin_lock(&ci->i_ceph_lock);
++ cap = __get_cap_for_mds(ci, mds);
++ /* mds did not re-issue stale cap */
++ if (cap && cap->cap_gen < atomic_read(&cap->session->s_cap_gen))
+ cap->issued = cap->implemented = CEPH_CAP_PIN;
+- spin_unlock(&ci->i_ceph_lock);
+- }
++ spin_unlock(&ci->i_ceph_lock);
+ } else if (ev == FORCE_RO) {
+ }
+ wake_up_all(&ci->i_cap_wq);
+@@ -1959,16 +1968,22 @@ out:
+ * Yes, this is a bit sloppy. Our only real goal here is to respond to
+ * memory pressure from the MDS, though, so it needn't be perfect.
+ */
+-static int trim_caps_cb(struct inode *inode, struct ceph_cap *cap, void *arg)
++static int trim_caps_cb(struct inode *inode, int mds, void *arg)
+ {
+ int *remaining = arg;
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ int used, wanted, oissued, mine;
++ struct ceph_cap *cap;
+
+ if (*remaining <= 0)
+ return -1;
+
+ spin_lock(&ci->i_ceph_lock);
++ cap = __get_cap_for_mds(ci, mds);
++ if (!cap) {
++ spin_unlock(&ci->i_ceph_lock);
++ return 0;
++ }
+ mine = cap->issued | cap->implemented;
+ used = __ceph_caps_used(ci);
+ wanted = __ceph_caps_file_wanted(ci);
+@@ -3911,26 +3926,22 @@ out_unlock:
+ /*
+ * Encode information about a cap for a reconnect with the MDS.
+ */
+-static int reconnect_caps_cb(struct inode *inode, struct ceph_cap *cap,
+- void *arg)
++static int reconnect_caps_cb(struct inode *inode, int mds, void *arg)
+ {
+ union {
+ struct ceph_mds_cap_reconnect v2;
+ struct ceph_mds_cap_reconnect_v1 v1;
+ } rec;
+- struct ceph_inode_info *ci = cap->ci;
++ struct ceph_inode_info *ci = ceph_inode(inode);
+ struct ceph_reconnect_state *recon_state = arg;
+ struct ceph_pagelist *pagelist = recon_state->pagelist;
+ struct dentry *dentry;
++ struct ceph_cap *cap;
+ char *path;
+- int pathlen = 0, err;
++ int pathlen = 0, err = 0;
+ u64 pathbase;
+ u64 snap_follows;
+
+- dout(" adding %p ino %llx.%llx cap %p %lld %s\n",
+- inode, ceph_vinop(inode), cap, cap->cap_id,
+- ceph_cap_string(cap->issued));
+-
+ dentry = d_find_primary(inode);
+ if (dentry) {
+ /* set pathbase to parent dir when msg_version >= 2 */
+@@ -3947,6 +3958,15 @@ static int reconnect_caps_cb(struct inode *inode, struct ceph_cap *cap,
+ }
+
+ spin_lock(&ci->i_ceph_lock);
++ cap = __get_cap_for_mds(ci, mds);
++ if (!cap) {
++ spin_unlock(&ci->i_ceph_lock);
++ goto out_err;
++ }
++ dout(" adding %p ino %llx.%llx cap %p %lld %s\n",
++ inode, ceph_vinop(inode), cap, cap->cap_id,
++ ceph_cap_string(cap->issued));
++
+ cap->seq = 0; /* reset cap seq */
+ cap->issue_seq = 0; /* and issue_seq */
+ cap->mseq = 0; /* and migrate_seq */
+diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h
+index 0598faa50e2e0..18b026b1ac63f 100644
+--- a/fs/ceph/mds_client.h
++++ b/fs/ceph/mds_client.h
+@@ -541,8 +541,7 @@ extern void ceph_flush_cap_releases(struct ceph_mds_client *mdsc,
+ extern void ceph_queue_cap_reclaim_work(struct ceph_mds_client *mdsc);
+ extern void ceph_reclaim_caps_nr(struct ceph_mds_client *mdsc, int nr);
+ extern int ceph_iterate_session_caps(struct ceph_mds_session *session,
+- int (*cb)(struct inode *,
+- struct ceph_cap *, void *),
++ int (*cb)(struct inode *, int mds, void *),
+ void *arg);
+ extern void ceph_mdsc_pre_umount(struct ceph_mds_client *mdsc);
+
+diff --git a/fs/ceph/super.h b/fs/ceph/super.h
+index 07c6906cda70d..b89d2cea4c1d1 100644
+--- a/fs/ceph/super.h
++++ b/fs/ceph/super.h
+@@ -1192,6 +1192,8 @@ extern void ceph_kick_flushing_caps(struct ceph_mds_client *mdsc,
+ struct ceph_mds_session *session);
+ void ceph_kick_flushing_inode_caps(struct ceph_mds_session *session,
+ struct ceph_inode_info *ci);
++extern struct ceph_cap *__get_cap_for_mds(struct ceph_inode_info *ci,
++ int mds);
+ extern struct ceph_cap *ceph_get_cap_for_mds(struct ceph_inode_info *ci,
+ int mds);
+ extern void ceph_take_cap_refs(struct ceph_inode_info *ci, int caps,
+diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
+index 72e24256b5ec2..cbf7e6ab638f5 100644
+--- a/fs/cifs/cifs_debug.c
++++ b/fs/cifs/cifs_debug.c
+@@ -279,8 +279,10 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
+ seq_printf(m, "\n%d) ConnectionId: 0x%llx ",
+ c, server->conn_id);
+
++ spin_lock(&server->srv_lock);
+ if (server->hostname)
+ seq_printf(m, "Hostname: %s ", server->hostname);
++ spin_unlock(&server->srv_lock);
+ #ifdef CONFIG_CIFS_SMB_DIRECT
+ if (!server->rdma)
+ goto skip_rdma;
+@@ -620,10 +622,13 @@ static int cifs_stats_proc_show(struct seq_file *m, void *v)
+ server->fastest_cmd[j],
+ server->slowest_cmd[j]);
+ for (j = 0; j < NUMBER_OF_SMB2_COMMANDS; j++)
+- if (atomic_read(&server->smb2slowcmd[j]))
++ if (atomic_read(&server->smb2slowcmd[j])) {
++ spin_lock(&server->srv_lock);
+ seq_printf(m, " %d slow responses from %s for command %d\n",
+ atomic_read(&server->smb2slowcmd[j]),
+ server->hostname, j);
++ spin_unlock(&server->srv_lock);
++ }
+ #endif /* STATS2 */
+ list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
+ list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
+diff --git a/fs/cifs/cifs_debug.h b/fs/cifs/cifs_debug.h
+index d44808263cfba..ce5cfd236fdb8 100644
+--- a/fs/cifs/cifs_debug.h
++++ b/fs/cifs/cifs_debug.h
+@@ -81,19 +81,19 @@ do { \
+
+ #define cifs_server_dbg_func(ratefunc, type, fmt, ...) \
+ do { \
+- const char *sn = ""; \
+- if (server && server->hostname) \
+- sn = server->hostname; \
++ spin_lock(&server->srv_lock); \
+ if ((type) & FYI && cifsFYI & CIFS_INFO) { \
+ pr_debug_ ## ratefunc("%s: \\\\%s " fmt, \
+- __FILE__, sn, ##__VA_ARGS__); \
++ __FILE__, server->hostname, \
++ ##__VA_ARGS__); \
+ } else if ((type) & VFS) { \
+ pr_err_ ## ratefunc("VFS: \\\\%s " fmt, \
+- sn, ##__VA_ARGS__); \
++ server->hostname, ##__VA_ARGS__); \
+ } else if ((type) & NOISY && (NOISY != 0)) { \
+ pr_debug_ ## ratefunc("\\\\%s " fmt, \
+- sn, ##__VA_ARGS__); \
++ server->hostname, ##__VA_ARGS__); \
+ } \
++ spin_unlock(&server->srv_lock); \
+ } while (0)
+
+ #define cifs_server_dbg(type, fmt, ...) \
+diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
+index 5aaaa47dea410..ea216e9d0f944 100644
+--- a/fs/cifs/cifsglob.h
++++ b/fs/cifs/cifsglob.h
+@@ -742,17 +742,23 @@ struct TCP_Server_Info {
+ #endif
+ struct mutex refpath_lock; /* protects leaf_fullpath */
+ /*
+- * Canonical DFS full paths that were used to chase referrals in mount and reconnect.
++ * origin_fullpath: Canonical copy of smb3_fs_context::source.
++ * It is used for matching existing DFS tcons.
+ *
+- * origin_fullpath: first or original referral path
+- * leaf_fullpath: last referral path (might be changed due to nested links in reconnect)
++ * leaf_fullpath: Canonical DFS referral path related to this
++ * connection.
++ * It is used in DFS cache refresher, reconnect and may
++ * change due to nested DFS links.
+ *
+- * current_fullpath: pointer to either origin_fullpath or leaf_fullpath
+- * NOTE: cannot be accessed outside cifs_reconnect() and smb2_reconnect()
++ * Both protected by @refpath_lock and @srv_lock. The @refpath_lock is
++ * mosly used for not requiring a copy of @leaf_fullpath when getting
++ * cached or new DFS referrals (which might also sleep during I/O).
++ * While @srv_lock is held for making string and NULL comparions against
++ * both fields as in mount(2) and cache refresh.
+ *
+- * format: \\HOST\SHARE\[OPTIONAL PATH]
++ * format: \\HOST\SHARE[\OPTIONAL PATH]
+ */
+- char *origin_fullpath, *leaf_fullpath, *current_fullpath;
++ char *origin_fullpath, *leaf_fullpath;
+ };
+
+ static inline bool is_smb1(struct TCP_Server_Info *server)
+@@ -1768,7 +1774,6 @@ struct cifs_mount_ctx {
+ struct TCP_Server_Info *server;
+ struct cifs_ses *ses;
+ struct cifs_tcon *tcon;
+- char *origin_fullpath, *leaf_fullpath;
+ struct list_head dfs_ses_list;
+ };
+
+diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
+index 639df85dafd6c..1765368f373cf 100644
+--- a/fs/cifs/cifsproto.h
++++ b/fs/cifs/cifsproto.h
+@@ -8,6 +8,7 @@
+ #ifndef _CIFSPROTO_H
+ #define _CIFSPROTO_H
+ #include <linux/nls.h>
++#include <linux/ctype.h>
+ #include "trace.h"
+ #ifdef CONFIG_CIFS_DFS_UPCALL
+ #include "dfs_cache.h"
+@@ -569,7 +570,7 @@ extern int E_md4hash(const unsigned char *passwd, unsigned char *p16,
+ extern struct TCP_Server_Info *
+ cifs_find_tcp_session(struct smb3_fs_context *ctx);
+
+-extern void cifs_put_smb_ses(struct cifs_ses *ses);
++void __cifs_put_smb_ses(struct cifs_ses *ses);
+
+ extern struct cifs_ses *
+ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx);
+@@ -699,4 +700,45 @@ struct super_block *cifs_get_tcon_super(struct cifs_tcon *tcon);
+ void cifs_put_tcon_super(struct super_block *sb);
+ int cifs_wait_for_server_reconnect(struct TCP_Server_Info *server, bool retry);
+
++/* Put references of @ses and @ses->dfs_root_ses */
++static inline void cifs_put_smb_ses(struct cifs_ses *ses)
++{
++ struct cifs_ses *rses = ses->dfs_root_ses;
++
++ __cifs_put_smb_ses(ses);
++ if (rses)
++ __cifs_put_smb_ses(rses);
++}
++
++/* Get an active reference of @ses and @ses->dfs_root_ses.
++ *
++ * NOTE: make sure to call this function when incrementing reference count of
++ * @ses to ensure that any DFS root session attached to it (@ses->dfs_root_ses)
++ * will also get its reference count incremented.
++ *
++ * cifs_put_smb_ses() will put both references, so call it when you're done.
++ */
++static inline void cifs_smb_ses_inc_refcount(struct cifs_ses *ses)
++{
++ lockdep_assert_held(&cifs_tcp_ses_lock);
++
++ ses->ses_count++;
++ if (ses->dfs_root_ses)
++ ses->dfs_root_ses->ses_count++;
++}
++
++static inline bool dfs_src_pathname_equal(const char *s1, const char *s2)
++{
++ if (strlen(s1) != strlen(s2))
++ return false;
++ for (; *s1; s1++, s2++) {
++ if (*s1 == '/' || *s1 == '\\') {
++ if (*s2 != '/' && *s2 != '\\')
++ return false;
++ } else if (tolower(*s1) != tolower(*s2))
++ return false;
++ }
++ return true;
++}
++
+ #endif /* _CIFSPROTO_H */
+diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
+index 985e962cf0858..87527512c2660 100644
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -435,8 +435,10 @@ static int __reconnect_target_unlocked(struct TCP_Server_Info *server, const cha
+ if (server->hostname != target) {
+ hostname = extract_hostname(target);
+ if (!IS_ERR(hostname)) {
++ spin_lock(&server->srv_lock);
+ kfree(server->hostname);
+ server->hostname = hostname;
++ spin_unlock(&server->srv_lock);
+ } else {
+ cifs_dbg(FYI, "%s: couldn't extract hostname or address from dfs target: %ld\n",
+ __func__, PTR_ERR(hostname));
+@@ -484,7 +486,6 @@ static int reconnect_target_unlocked(struct TCP_Server_Info *server, struct dfs_
+ static int reconnect_dfs_server(struct TCP_Server_Info *server)
+ {
+ int rc = 0;
+- const char *refpath = server->current_fullpath + 1;
+ struct dfs_cache_tgt_list tl = DFS_CACHE_TGT_LIST_INIT(tl);
+ struct dfs_cache_tgt_iterator *target_hint = NULL;
+ int num_targets = 0;
+@@ -497,8 +498,10 @@ static int reconnect_dfs_server(struct TCP_Server_Info *server)
+ * through /proc/fs/cifs/dfscache or the target list is empty due to server settings after
+ * refreshing the referral, so, in this case, default it to 1.
+ */
+- if (!dfs_cache_noreq_find(refpath, NULL, &tl))
++ mutex_lock(&server->refpath_lock);
++ if (!dfs_cache_noreq_find(server->leaf_fullpath + 1, NULL, &tl))
+ num_targets = dfs_cache_get_nr_tgts(&tl);
++ mutex_unlock(&server->refpath_lock);
+ if (!num_targets)
+ num_targets = 1;
+
+@@ -542,7 +545,9 @@ static int reconnect_dfs_server(struct TCP_Server_Info *server)
+ mod_delayed_work(cifsiod_wq, &server->reconnect, 0);
+ } while (server->tcpStatus == CifsNeedReconnect);
+
+- dfs_cache_noreq_update_tgthint(refpath, target_hint);
++ mutex_lock(&server->refpath_lock);
++ dfs_cache_noreq_update_tgthint(server->leaf_fullpath + 1, target_hint);
++ mutex_unlock(&server->refpath_lock);
+ dfs_cache_free_tgts(&tl);
+
+ /* Need to set up echo worker again once connection has been established */
+@@ -593,9 +598,7 @@ cifs_echo_request(struct work_struct *work)
+ goto requeue_echo;
+
+ rc = server->ops->echo ? server->ops->echo(server) : -ENOSYS;
+- if (rc)
+- cifs_dbg(FYI, "Unable to send echo request to server: %s\n",
+- server->hostname);
++ cifs_server_dbg(FYI, "send echo request: rc = %d\n", rc);
+
+ /* Check witness registrations */
+ cifs_swn_check();
+@@ -1011,10 +1014,8 @@ static void clean_demultiplex_info(struct TCP_Server_Info *server)
+ */
+ }
+
+-#ifdef CONFIG_CIFS_DFS_UPCALL
+ kfree(server->origin_fullpath);
+ kfree(server->leaf_fullpath);
+-#endif
+ kfree(server);
+
+ length = atomic_dec_return(&tcpSesAllocCount);
+@@ -1425,26 +1426,13 @@ match_security(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
+ return true;
+ }
+
+-static bool dfs_src_pathname_equal(const char *s1, const char *s2)
+-{
+- if (strlen(s1) != strlen(s2))
+- return false;
+- for (; *s1; s1++, s2++) {
+- if (*s1 == '/' || *s1 == '\\') {
+- if (*s2 != '/' && *s2 != '\\')
+- return false;
+- } else if (tolower(*s1) != tolower(*s2))
+- return false;
+- }
+- return true;
+-}
+-
+ /* this function must be called with srv_lock held */
+-static int match_server(struct TCP_Server_Info *server, struct smb3_fs_context *ctx,
+- bool dfs_super_cmp)
++static int match_server(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
+ {
+ struct sockaddr *addr = (struct sockaddr *)&ctx->dstaddr;
+
++ lockdep_assert_held(&server->srv_lock);
++
+ if (ctx->nosharesock)
+ return 0;
+
+@@ -1470,27 +1458,41 @@ static int match_server(struct TCP_Server_Info *server, struct smb3_fs_context *
+ (struct sockaddr *)&server->srcaddr))
+ return 0;
+ /*
+- * When matching DFS superblocks, we only check for original source pathname as the
+- * currently connected target might be different than the one parsed earlier in i.e.
+- * mount.cifs(8).
++ * - Match for an DFS tcon (@server->origin_fullpath).
++ * - Match for an DFS root server connection (@server->leaf_fullpath).
++ * - If none of the above and @ctx->leaf_fullpath is set, then
++ * it is a new DFS connection.
++ * - If 'nodfs' mount option was passed, then match only connections
++ * that have no DFS referrals set
++ * (e.g. can't failover to other targets).
+ */
+- if (dfs_super_cmp) {
+- if (!ctx->source || !server->origin_fullpath ||
+- !dfs_src_pathname_equal(server->origin_fullpath, ctx->source))
+- return 0;
+- } else {
+- /* Skip addr, hostname and port matching for DFS connections */
+- if (server->leaf_fullpath) {
++ if (!ctx->nodfs) {
++ if (ctx->source && server->origin_fullpath) {
++ if (!dfs_src_pathname_equal(ctx->source,
++ server->origin_fullpath))
++ return 0;
++ } else if (server->leaf_fullpath) {
+ if (!ctx->leaf_fullpath ||
+- strcasecmp(server->leaf_fullpath, ctx->leaf_fullpath))
++ strcasecmp(server->leaf_fullpath,
++ ctx->leaf_fullpath))
+ return 0;
+- } else if (strcasecmp(server->hostname, ctx->server_hostname) ||
+- !match_server_address(server, addr) ||
+- !match_port(server, addr)) {
++ } else if (ctx->leaf_fullpath) {
+ return 0;
+ }
++ } else if (server->origin_fullpath || server->leaf_fullpath) {
++ return 0;
+ }
+
++ /*
++ * Match for a regular connection (address/hostname/port) which has no
++ * DFS referrals set.
++ */
++ if (!server->origin_fullpath && !server->leaf_fullpath &&
++ (strcasecmp(server->hostname, ctx->server_hostname) ||
++ !match_server_address(server, addr) ||
++ !match_port(server, addr)))
++ return 0;
++
+ if (!match_security(server, ctx))
+ return 0;
+
+@@ -1521,7 +1523,7 @@ cifs_find_tcp_session(struct smb3_fs_context *ctx)
+ * Skip ses channels since they're only handled in lower layers
+ * (e.g. cifs_send_recv).
+ */
+- if (CIFS_SERVER_IS_CHAN(server) || !match_server(server, ctx, false)) {
++ if (CIFS_SERVER_IS_CHAN(server) || !match_server(server, ctx)) {
+ spin_unlock(&server->srv_lock);
+ continue;
+ }
+@@ -1622,7 +1624,6 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx,
+ rc = -ENOMEM;
+ goto out_err;
+ }
+- tcp_ses->current_fullpath = tcp_ses->leaf_fullpath;
+ }
+
+ if (ctx->nosharesock)
+@@ -1859,7 +1860,9 @@ cifs_setup_ipc(struct cifs_ses *ses, struct smb3_fs_context *ctx)
+ if (tcon == NULL)
+ return -ENOMEM;
+
++ spin_lock(&server->srv_lock);
+ scnprintf(unc, sizeof(unc), "\\\\%s\\IPC$", server->hostname);
++ spin_unlock(&server->srv_lock);
+
+ xid = get_xid();
+ tcon->ses = ses;
+@@ -1912,7 +1915,7 @@ cifs_free_ipc(struct cifs_ses *ses)
+ static struct cifs_ses *
+ cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
+ {
+- struct cifs_ses *ses;
++ struct cifs_ses *ses, *ret = NULL;
+
+ spin_lock(&cifs_tcp_ses_lock);
+ list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
+@@ -1922,23 +1925,22 @@ cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
+ continue;
+ }
+ spin_lock(&ses->chan_lock);
+- if (!match_session(ses, ctx)) {
++ if (match_session(ses, ctx)) {
+ spin_unlock(&ses->chan_lock);
+ spin_unlock(&ses->ses_lock);
+- continue;
++ ret = ses;
++ break;
+ }
+ spin_unlock(&ses->chan_lock);
+ spin_unlock(&ses->ses_lock);
+-
+- ++ses->ses_count;
+- spin_unlock(&cifs_tcp_ses_lock);
+- return ses;
+ }
++ if (ret)
++ cifs_smb_ses_inc_refcount(ret);
+ spin_unlock(&cifs_tcp_ses_lock);
+- return NULL;
++ return ret;
+ }
+
+-void cifs_put_smb_ses(struct cifs_ses *ses)
++void __cifs_put_smb_ses(struct cifs_ses *ses)
+ {
+ unsigned int rc, xid;
+ unsigned int chan_count;
+@@ -2289,6 +2291,8 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
+ */
+ spin_lock(&cifs_tcp_ses_lock);
+ ses->dfs_root_ses = ctx->dfs_root_ses;
++ if (ses->dfs_root_ses)
++ ses->dfs_root_ses->ses_count++;
+ list_add(&ses->smb_ses_list, &server->smb_ses_list);
+ spin_unlock(&cifs_tcp_ses_lock);
+
+@@ -2305,12 +2309,15 @@ get_ses_fail:
+ }
+
+ /* this function must be called with tc_lock held */
+-static int match_tcon(struct cifs_tcon *tcon, struct smb3_fs_context *ctx, bool dfs_super_cmp)
++static int match_tcon(struct cifs_tcon *tcon, struct smb3_fs_context *ctx)
+ {
++ struct TCP_Server_Info *server = tcon->ses->server;
++
+ if (tcon->status == TID_EXITING)
+ return 0;
+- /* Skip UNC validation when matching DFS superblocks */
+- if (!dfs_super_cmp && strncmp(tcon->tree_name, ctx->UNC, MAX_TREE_SIZE))
++ /* Skip UNC validation when matching DFS connections or superblocks */
++ if (!server->origin_fullpath && !server->leaf_fullpath &&
++ strncmp(tcon->tree_name, ctx->UNC, MAX_TREE_SIZE))
+ return 0;
+ if (tcon->seal != ctx->seal)
+ return 0;
+@@ -2333,7 +2340,7 @@ cifs_find_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx)
+ spin_lock(&cifs_tcp_ses_lock);
+ list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
+ spin_lock(&tcon->tc_lock);
+- if (!match_tcon(tcon, ctx, false)) {
++ if (!match_tcon(tcon, ctx)) {
+ spin_unlock(&tcon->tc_lock);
+ continue;
+ }
+@@ -2704,9 +2711,11 @@ compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data)
+ return 1;
+ }
+
+-static int
+-match_prepath(struct super_block *sb, struct cifs_mnt_data *mnt_data)
++static int match_prepath(struct super_block *sb,
++ struct TCP_Server_Info *server,
++ struct cifs_mnt_data *mnt_data)
+ {
++ struct smb3_fs_context *ctx = mnt_data->ctx;
+ struct cifs_sb_info *old = CIFS_SB(sb);
+ struct cifs_sb_info *new = mnt_data->cifs_sb;
+ bool old_set = (old->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) &&
+@@ -2714,6 +2723,10 @@ match_prepath(struct super_block *sb, struct cifs_mnt_data *mnt_data)
+ bool new_set = (new->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) &&
+ new->prepath;
+
++ if (server->origin_fullpath &&
++ dfs_src_pathname_equal(server->origin_fullpath, ctx->source))
++ return 1;
++
+ if (old_set && new_set && !strcmp(new->prepath, old->prepath))
+ return 1;
+ else if (!old_set && !new_set)
+@@ -2732,7 +2745,6 @@ cifs_match_super(struct super_block *sb, void *data)
+ struct cifs_ses *ses;
+ struct cifs_tcon *tcon;
+ struct tcon_link *tlink;
+- bool dfs_super_cmp;
+ int rc = 0;
+
+ spin_lock(&cifs_tcp_ses_lock);
+@@ -2747,18 +2759,16 @@ cifs_match_super(struct super_block *sb, void *data)
+ ses = tcon->ses;
+ tcp_srv = ses->server;
+
+- dfs_super_cmp = IS_ENABLED(CONFIG_CIFS_DFS_UPCALL) && tcp_srv->origin_fullpath;
+-
+ ctx = mnt_data->ctx;
+
+ spin_lock(&tcp_srv->srv_lock);
+ spin_lock(&ses->ses_lock);
+ spin_lock(&ses->chan_lock);
+ spin_lock(&tcon->tc_lock);
+- if (!match_server(tcp_srv, ctx, dfs_super_cmp) ||
++ if (!match_server(tcp_srv, ctx) ||
+ !match_session(ses, ctx) ||
+- !match_tcon(tcon, ctx, dfs_super_cmp) ||
+- !match_prepath(sb, mnt_data)) {
++ !match_tcon(tcon, ctx) ||
++ !match_prepath(sb, tcp_srv, mnt_data)) {
+ rc = 0;
+ goto out;
+ }
+@@ -3503,8 +3513,6 @@ out:
+
+ error:
+ dfs_put_root_smb_sessions(&mnt_ctx.dfs_ses_list);
+- kfree(mnt_ctx.origin_fullpath);
+- kfree(mnt_ctx.leaf_fullpath);
+ cifs_mount_put_conns(&mnt_ctx);
+ return rc;
+ }
+diff --git a/fs/cifs/dfs.c b/fs/cifs/dfs.c
+index c8bda52fa096c..4c392bde24066 100644
+--- a/fs/cifs/dfs.c
++++ b/fs/cifs/dfs.c
+@@ -99,7 +99,7 @@ static int get_session(struct cifs_mount_ctx *mnt_ctx, const char *full_path)
+ return rc;
+ }
+
+-static int get_root_smb_session(struct cifs_mount_ctx *mnt_ctx)
++static int add_root_smb_session(struct cifs_mount_ctx *mnt_ctx)
+ {
+ struct smb3_fs_context *ctx = mnt_ctx->fs_ctx;
+ struct dfs_root_ses *root_ses;
+@@ -127,7 +127,7 @@ static int get_dfs_conn(struct cifs_mount_ctx *mnt_ctx, const char *ref_path, co
+ {
+ struct smb3_fs_context *ctx = mnt_ctx->fs_ctx;
+ struct dfs_info3_param ref = {};
+- bool is_refsrv = false;
++ bool is_refsrv;
+ int rc, rc2;
+
+ rc = dfs_cache_get_tgt_referral(ref_path + 1, tit, &ref);
+@@ -158,7 +158,7 @@ static int get_dfs_conn(struct cifs_mount_ctx *mnt_ctx, const char *ref_path, co
+ }
+
+ if (rc == -EREMOTE && is_refsrv) {
+- rc2 = get_root_smb_session(mnt_ctx);
++ rc2 = add_root_smb_session(mnt_ctx);
+ if (rc2)
+ rc = rc2;
+ }
+@@ -248,11 +248,12 @@ static int __dfs_mount_share(struct cifs_mount_ctx *mnt_ctx)
+ tcon = mnt_ctx->tcon;
+
+ mutex_lock(&server->refpath_lock);
++ spin_lock(&server->srv_lock);
+ if (!server->origin_fullpath) {
+ server->origin_fullpath = origin_fullpath;
+- server->current_fullpath = server->leaf_fullpath;
+ origin_fullpath = NULL;
+ }
++ spin_unlock(&server->srv_lock);
+ mutex_unlock(&server->refpath_lock);
+
+ if (list_empty(&tcon->dfs_ses_list)) {
+@@ -272,15 +273,21 @@ out:
+
+ int dfs_mount_share(struct cifs_mount_ctx *mnt_ctx, bool *isdfs)
+ {
+- struct cifs_sb_info *cifs_sb = mnt_ctx->cifs_sb;
+ struct smb3_fs_context *ctx = mnt_ctx->fs_ctx;
++ struct cifs_ses *ses;
++ char *source = ctx->source;
++ bool nodfs = ctx->nodfs;
+ int rc;
+
+ *isdfs = false;
+-
++ /* Temporarily set @ctx->source to NULL as we're not matching DFS
++ * superblocks yet. See cifs_match_super() and match_server().
++ */
++ ctx->source = NULL;
+ rc = get_session(mnt_ctx, NULL);
+ if (rc)
+- return rc;
++ goto out;
++
+ ctx->dfs_root_ses = mnt_ctx->ses;
+ /*
+ * If called with 'nodfs' mount option, then skip DFS resolving. Otherwise unconditionally
+@@ -289,23 +296,41 @@ int dfs_mount_share(struct cifs_mount_ctx *mnt_ctx, bool *isdfs)
+ * Skip prefix path to provide support for DFS referrals from w2k8 servers which don't seem
+ * to respond with PATH_NOT_COVERED to requests that include the prefix.
+ */
+- if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_DFS) ||
+- dfs_get_referral(mnt_ctx, ctx->UNC + 1, NULL, NULL)) {
++ if (!nodfs) {
++ rc = dfs_get_referral(mnt_ctx, ctx->UNC + 1, NULL, NULL);
++ if (rc) {
++ if (rc != -ENOENT && rc != -EOPNOTSUPP)
++ goto out;
++ nodfs = true;
++ }
++ }
++ if (nodfs) {
+ rc = cifs_mount_get_tcon(mnt_ctx);
+- if (rc)
+- return rc;
+-
+- rc = cifs_is_path_remote(mnt_ctx);
+- if (!rc || rc != -EREMOTE)
+- return rc;
++ if (!rc)
++ rc = cifs_is_path_remote(mnt_ctx);
++ goto out;
+ }
+
+ *isdfs = true;
+- rc = get_root_smb_session(mnt_ctx);
+- if (rc)
+- return rc;
+-
+- return __dfs_mount_share(mnt_ctx);
++ /*
++ * Prevent DFS root session of being put in the first call to
++ * cifs_mount_put_conns(). If another DFS root server was not found
++ * while chasing the referrals (@ctx->dfs_root_ses == @ses), then we
++ * can safely put extra refcount of @ses.
++ */
++ ses = mnt_ctx->ses;
++ mnt_ctx->ses = NULL;
++ mnt_ctx->server = NULL;
++ rc = __dfs_mount_share(mnt_ctx);
++ if (ses == ctx->dfs_root_ses)
++ cifs_put_smb_ses(ses);
++out:
++ /*
++ * Restore previous value of @ctx->source so DFS superblock can be
++ * matched in cifs_match_super().
++ */
++ ctx->source = source;
++ return rc;
+ }
+
+ /* Update dfs referral path of superblock */
+@@ -342,10 +367,11 @@ static int update_server_fullpath(struct TCP_Server_Info *server, struct cifs_sb
+ rc = PTR_ERR(npath);
+ } else {
+ mutex_lock(&server->refpath_lock);
++ spin_lock(&server->srv_lock);
+ kfree(server->leaf_fullpath);
+ server->leaf_fullpath = npath;
++ spin_unlock(&server->srv_lock);
+ mutex_unlock(&server->refpath_lock);
+- server->current_fullpath = server->leaf_fullpath;
+ }
+ return rc;
+ }
+@@ -374,6 +400,54 @@ static int target_share_matches_server(struct TCP_Server_Info *server, char *sha
+ return rc;
+ }
+
++static void __tree_connect_ipc(const unsigned int xid, char *tree,
++ struct cifs_sb_info *cifs_sb,
++ struct cifs_ses *ses)
++{
++ struct TCP_Server_Info *server = ses->server;
++ struct cifs_tcon *tcon = ses->tcon_ipc;
++ int rc;
++
++ spin_lock(&ses->ses_lock);
++ spin_lock(&ses->chan_lock);
++ if (cifs_chan_needs_reconnect(ses, server) ||
++ ses->ses_status != SES_GOOD) {
++ spin_unlock(&ses->chan_lock);
++ spin_unlock(&ses->ses_lock);
++ cifs_server_dbg(FYI, "%s: skipping ipc reconnect due to disconnected ses\n",
++ __func__);
++ return;
++ }
++ spin_unlock(&ses->chan_lock);
++ spin_unlock(&ses->ses_lock);
++
++ cifs_server_lock(server);
++ scnprintf(tree, MAX_TREE_SIZE, "\\\\%s\\IPC$", server->hostname);
++ cifs_server_unlock(server);
++
++ rc = server->ops->tree_connect(xid, ses, tree, tcon,
++ cifs_sb->local_nls);
++ cifs_server_dbg(FYI, "%s: tree_reconnect %s: %d\n", __func__, tree, rc);
++ spin_lock(&tcon->tc_lock);
++ if (rc) {
++ tcon->status = TID_NEED_TCON;
++ } else {
++ tcon->status = TID_GOOD;
++ tcon->need_reconnect = false;
++ }
++ spin_unlock(&tcon->tc_lock);
++}
++
++static void tree_connect_ipc(const unsigned int xid, char *tree,
++ struct cifs_sb_info *cifs_sb,
++ struct cifs_tcon *tcon)
++{
++ struct cifs_ses *ses = tcon->ses;
++
++ __tree_connect_ipc(xid, tree, cifs_sb, ses);
++ __tree_connect_ipc(xid, tree, cifs_sb, CIFS_DFS_ROOT_SES(ses));
++}
++
+ static int __tree_connect_dfs_target(const unsigned int xid, struct cifs_tcon *tcon,
+ struct cifs_sb_info *cifs_sb, char *tree, bool islink,
+ struct dfs_cache_tgt_list *tl)
+@@ -382,7 +456,6 @@ static int __tree_connect_dfs_target(const unsigned int xid, struct cifs_tcon *t
+ struct TCP_Server_Info *server = tcon->ses->server;
+ const struct smb_version_operations *ops = server->ops;
+ struct cifs_ses *root_ses = CIFS_DFS_ROOT_SES(tcon->ses);
+- struct cifs_tcon *ipc = root_ses->tcon_ipc;
+ char *share = NULL, *prefix = NULL;
+ struct dfs_cache_tgt_iterator *tit;
+ bool target_match;
+@@ -403,7 +476,7 @@ static int __tree_connect_dfs_target(const unsigned int xid, struct cifs_tcon *t
+ share = prefix = NULL;
+
+ /* Check if share matches with tcp ses */
+- rc = dfs_cache_get_tgt_share(server->current_fullpath + 1, tit, &share, &prefix);
++ rc = dfs_cache_get_tgt_share(server->leaf_fullpath + 1, tit, &share, &prefix);
+ if (rc) {
+ cifs_dbg(VFS, "%s: failed to parse target share: %d\n", __func__, rc);
+ break;
+@@ -417,19 +490,15 @@ static int __tree_connect_dfs_target(const unsigned int xid, struct cifs_tcon *t
+ continue;
+ }
+
+- dfs_cache_noreq_update_tgthint(server->current_fullpath + 1, tit);
+-
+- if (ipc->need_reconnect) {
+- scnprintf(tree, MAX_TREE_SIZE, "\\\\%s\\IPC$", server->hostname);
+- rc = ops->tree_connect(xid, ipc->ses, tree, ipc, cifs_sb->local_nls);
+- cifs_dbg(FYI, "%s: reconnect ipc: %d\n", __func__, rc);
+- }
++ dfs_cache_noreq_update_tgthint(server->leaf_fullpath + 1, tit);
++ tree_connect_ipc(xid, tree, cifs_sb, tcon);
+
+ scnprintf(tree, MAX_TREE_SIZE, "\\%s", share);
+ if (!islink) {
+ rc = ops->tree_connect(xid, tcon->ses, tree, tcon, cifs_sb->local_nls);
+ break;
+ }
++
+ /*
+ * If no dfs referrals were returned from link target, then just do a TREE_CONNECT
+ * to it. Otherwise, cache the dfs referral and then mark current tcp ses for
+@@ -535,8 +604,8 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru
+ cifs_sb = CIFS_SB(sb);
+
+ /* If it is not dfs or there was no cached dfs referral, then reconnect to same share */
+- if (!server->current_fullpath ||
+- dfs_cache_noreq_find(server->current_fullpath + 1, &ref, &tl)) {
++ if (!server->leaf_fullpath ||
++ dfs_cache_noreq_find(server->leaf_fullpath + 1, &ref, &tl)) {
+ rc = ops->tree_connect(xid, tcon->ses, tcon->tree_name, tcon, cifs_sb->local_nls);
+ goto out;
+ }
+diff --git a/fs/cifs/dfs.h b/fs/cifs/dfs.h
+index 0b8cbf721fff6..1c90df5ecfbda 100644
+--- a/fs/cifs/dfs.h
++++ b/fs/cifs/dfs.h
+@@ -43,8 +43,12 @@ static inline char *dfs_get_automount_devname(struct dentry *dentry, void *page)
+ size_t len;
+ char *s;
+
+- if (unlikely(!server->origin_fullpath))
++ spin_lock(&server->srv_lock);
++ if (unlikely(!server->origin_fullpath)) {
++ spin_unlock(&server->srv_lock);
+ return ERR_PTR(-EREMOTE);
++ }
++ spin_unlock(&server->srv_lock);
+
+ s = dentry_path_raw(dentry, page, PATH_MAX);
+ if (IS_ERR(s))
+@@ -53,13 +57,18 @@ static inline char *dfs_get_automount_devname(struct dentry *dentry, void *page)
+ if (!s[1])
+ s++;
+
++ spin_lock(&server->srv_lock);
+ len = strlen(server->origin_fullpath);
+- if (s < (char *)page + len)
++ if (s < (char *)page + len) {
++ spin_unlock(&server->srv_lock);
+ return ERR_PTR(-ENAMETOOLONG);
++ }
+
+ s -= len;
+ memcpy(s, server->origin_fullpath, len);
++ spin_unlock(&server->srv_lock);
+ convert_delimiter(s, '/');
++
+ return s;
+ }
+
+diff --git a/fs/cifs/dfs_cache.c b/fs/cifs/dfs_cache.c
+index 1c59811bfa73a..9ccaa0c7ac943 100644
+--- a/fs/cifs/dfs_cache.c
++++ b/fs/cifs/dfs_cache.c
+@@ -1278,8 +1278,12 @@ static void refresh_cache_worker(struct work_struct *work)
+
+ spin_lock(&cifs_tcp_ses_lock);
+ list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
+- if (!server->leaf_fullpath)
++ spin_lock(&server->srv_lock);
++ if (!server->leaf_fullpath) {
++ spin_unlock(&server->srv_lock);
+ continue;
++ }
++ spin_unlock(&server->srv_lock);
+
+ list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
+ if (ses->tcon_ipc) {
+diff --git a/fs/cifs/file.c b/fs/cifs/file.c
+index a53ddc81b698c..bef7c335ccc6e 100644
+--- a/fs/cifs/file.c
++++ b/fs/cifs/file.c
+@@ -5096,6 +5096,8 @@ void cifs_oplock_break(struct work_struct *work)
+ struct TCP_Server_Info *server = tcon->ses->server;
+ int rc = 0;
+ bool purge_cache = false;
++ struct cifs_deferred_close *dclose;
++ bool is_deferred = false;
+
+ wait_on_bit(&cinode->flags, CIFS_INODE_PENDING_WRITERS,
+ TASK_UNINTERRUPTIBLE);
+@@ -5131,6 +5133,20 @@ void cifs_oplock_break(struct work_struct *work)
+ cifs_dbg(VFS, "Push locks rc = %d\n", rc);
+
+ oplock_break_ack:
++ /*
++ * When oplock break is received and there are no active
++ * file handles but cached, then schedule deferred close immediately.
++ * So, new open will not use cached handle.
++ */
++ spin_lock(&CIFS_I(inode)->deferred_lock);
++ is_deferred = cifs_is_deferred_close(cfile, &dclose);
++ spin_unlock(&CIFS_I(inode)->deferred_lock);
++
++ if (!CIFS_CACHE_HANDLE(cinode) && is_deferred &&
++ cfile->deferred_close_scheduled && delayed_work_pending(&cfile->deferred)) {
++ cifs_close_deferred_file(cinode);
++ }
++
+ /*
+ * releasing stale oplock after recent reconnect of smb session using
+ * a now incorrect file handle is not a data integrity issue but do
+diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c
+index 6419ec47c2a85..cb3be58cd55eb 100644
+--- a/fs/cifs/ioctl.c
++++ b/fs/cifs/ioctl.c
+@@ -239,7 +239,7 @@ static int cifs_dump_full_key(struct cifs_tcon *tcon, struct smb3_full_key_debug
+ * section, we need to make sure it won't be released
+ * so increment its refcount
+ */
+- ses->ses_count++;
++ cifs_smb_ses_inc_refcount(ses);
+ found = true;
+ goto search_end;
+ }
+diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
+index 2fae6b08314d9..ee0a3c3f6b1d6 100644
+--- a/fs/cifs/misc.c
++++ b/fs/cifs/misc.c
+@@ -749,7 +749,9 @@ cifs_close_deferred_file(struct cifsInodeInfo *cifs_inode)
+ list_for_each_entry(cfile, &cifs_inode->openFileList, flist) {
+ if (delayed_work_pending(&cfile->deferred)) {
+ if (cancel_delayed_work(&cfile->deferred)) {
++ spin_lock(&cifs_inode->deferred_lock);
+ cifs_del_deferred_close(cfile);
++ spin_unlock(&cifs_inode->deferred_lock);
+
+ tmp_list = kmalloc(sizeof(struct file_list), GFP_ATOMIC);
+ if (tmp_list == NULL)
+@@ -762,7 +764,7 @@ cifs_close_deferred_file(struct cifsInodeInfo *cifs_inode)
+ spin_unlock(&cifs_inode->open_file_lock);
+
+ list_for_each_entry_safe(tmp_list, tmp_next_list, &file_head, list) {
+- _cifsFileInfo_put(tmp_list->cfile, true, false);
++ _cifsFileInfo_put(tmp_list->cfile, false, false);
+ list_del(&tmp_list->list);
+ kfree(tmp_list);
+ }
+@@ -780,7 +782,9 @@ cifs_close_all_deferred_files(struct cifs_tcon *tcon)
+ list_for_each_entry(cfile, &tcon->openFileList, tlist) {
+ if (delayed_work_pending(&cfile->deferred)) {
+ if (cancel_delayed_work(&cfile->deferred)) {
++ spin_lock(&CIFS_I(d_inode(cfile->dentry))->deferred_lock);
+ cifs_del_deferred_close(cfile);
++ spin_unlock(&CIFS_I(d_inode(cfile->dentry))->deferred_lock);
+
+ tmp_list = kmalloc(sizeof(struct file_list), GFP_ATOMIC);
+ if (tmp_list == NULL)
+@@ -815,7 +819,9 @@ cifs_close_deferred_file_under_dentry(struct cifs_tcon *tcon, const char *path)
+ if (strstr(full_path, path)) {
+ if (delayed_work_pending(&cfile->deferred)) {
+ if (cancel_delayed_work(&cfile->deferred)) {
++ spin_lock(&CIFS_I(d_inode(cfile->dentry))->deferred_lock);
+ cifs_del_deferred_close(cfile);
++ spin_unlock(&CIFS_I(d_inode(cfile->dentry))->deferred_lock);
+
+ tmp_list = kmalloc(sizeof(struct file_list), GFP_ATOMIC);
+ if (tmp_list == NULL)
+diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
+index c47b254f0d1e2..81be17845072a 100644
+--- a/fs/cifs/sess.c
++++ b/fs/cifs/sess.c
+@@ -159,6 +159,7 @@ cifs_chan_is_iface_active(struct cifs_ses *ses,
+ /* returns number of channels added */
+ int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses)
+ {
++ struct TCP_Server_Info *server = ses->server;
+ int old_chan_count, new_chan_count;
+ int left;
+ int rc = 0;
+@@ -178,16 +179,16 @@ int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses)
+ return 0;
+ }
+
+- if (ses->server->dialect < SMB30_PROT_ID) {
++ if (server->dialect < SMB30_PROT_ID) {
+ spin_unlock(&ses->chan_lock);
+ cifs_dbg(VFS, "multichannel is not supported on this protocol version, use 3.0 or above\n");
+ return 0;
+ }
+
+- if (!(ses->server->capabilities & SMB2_GLOBAL_CAP_MULTI_CHANNEL)) {
++ if (!(server->capabilities & SMB2_GLOBAL_CAP_MULTI_CHANNEL)) {
+ ses->chan_max = 1;
+ spin_unlock(&ses->chan_lock);
+- cifs_dbg(VFS, "server %s does not support multichannel\n", ses->server->hostname);
++ cifs_server_dbg(VFS, "no multichannel support\n");
+ return 0;
+ }
+ spin_unlock(&ses->chan_lock);
+diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
+index ab59faf8a06a7..0550be60dce44 100644
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -175,8 +175,17 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
+ }
+ }
+ spin_unlock(&tcon->tc_lock);
+- if ((!tcon->ses) || (tcon->ses->ses_status == SES_EXITING) ||
+- (!tcon->ses->server) || !server)
++
++ ses = tcon->ses;
++ if (!ses)
++ return -EIO;
++ spin_lock(&ses->ses_lock);
++ if (ses->ses_status == SES_EXITING) {
++ spin_unlock(&ses->ses_lock);
++ return -EIO;
++ }
++ spin_unlock(&ses->ses_lock);
++ if (!ses->server || !server)
+ return -EIO;
+
+ spin_lock(&server->srv_lock);
+@@ -204,8 +213,6 @@ again:
+ if (rc)
+ return rc;
+
+- ses = tcon->ses;
+-
+ spin_lock(&ses->chan_lock);
+ if (!cifs_chan_needs_reconnect(ses, server) && !tcon->need_reconnect) {
+ spin_unlock(&ses->chan_lock);
+@@ -3851,7 +3858,7 @@ void smb2_reconnect_server(struct work_struct *work)
+ if (ses->tcon_ipc && ses->tcon_ipc->need_reconnect) {
+ list_add_tail(&ses->tcon_ipc->rlist, &tmp_list);
+ tcon_selected = tcon_exist = true;
+- ses->ses_count++;
++ cifs_smb_ses_inc_refcount(ses);
+ }
+ /*
+ * handle the case where channel needs to reconnect
+@@ -3862,7 +3869,7 @@ void smb2_reconnect_server(struct work_struct *work)
+ if (!tcon_selected && cifs_chan_needs_reconnect(ses, server)) {
+ list_add_tail(&ses->rlist, &tmp_ses_list);
+ ses_exist = true;
+- ses->ses_count++;
++ cifs_smb_ses_inc_refcount(ses);
+ }
+ spin_unlock(&ses->chan_lock);
+ }
+diff --git a/fs/dlm/ast.c b/fs/dlm/ast.c
+index 26fef9945cc90..39805aea33367 100644
+--- a/fs/dlm/ast.c
++++ b/fs/dlm/ast.c
+@@ -45,7 +45,7 @@ void dlm_purge_lkb_callbacks(struct dlm_lkb *lkb)
+ kref_put(&cb->ref, dlm_release_callback);
+ }
+
+- lkb->lkb_flags &= ~DLM_IFL_CB_PENDING;
++ clear_bit(DLM_IFL_CB_PENDING_BIT, &lkb->lkb_iflags);
+
+ /* invalidate */
+ dlm_callback_set_last_ptr(&lkb->lkb_last_cast, NULL);
+@@ -103,10 +103,9 @@ int dlm_enqueue_lkb_callback(struct dlm_lkb *lkb, uint32_t flags, int mode,
+ cb->sb_status = status;
+ cb->sb_flags = (sbflags & 0x000000FF);
+ kref_init(&cb->ref);
+- if (!(lkb->lkb_flags & DLM_IFL_CB_PENDING)) {
+- lkb->lkb_flags |= DLM_IFL_CB_PENDING;
++ if (!test_and_set_bit(DLM_IFL_CB_PENDING_BIT, &lkb->lkb_iflags))
+ rv = DLM_ENQUEUE_CALLBACK_NEED_SCHED;
+- }
++
+ list_add_tail(&cb->list, &lkb->lkb_callbacks);
+
+ if (flags & DLM_CB_CAST)
+@@ -209,7 +208,7 @@ void dlm_callback_work(struct work_struct *work)
+ spin_lock(&lkb->lkb_cb_lock);
+ rv = dlm_dequeue_lkb_callback(lkb, &cb);
+ if (rv == DLM_DEQUEUE_CALLBACK_EMPTY) {
+- lkb->lkb_flags &= ~DLM_IFL_CB_PENDING;
++ clear_bit(DLM_IFL_CB_PENDING_BIT, &lkb->lkb_iflags);
+ spin_unlock(&lkb->lkb_cb_lock);
+ break;
+ }
+diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h
+index ab1a55337a6eb..9bf70962bc495 100644
+--- a/fs/dlm/dlm_internal.h
++++ b/fs/dlm/dlm_internal.h
+@@ -211,7 +211,9 @@ struct dlm_args {
+ #endif
+ #define DLM_IFL_DEADLOCK_CANCEL 0x01000000
+ #define DLM_IFL_STUB_MS 0x02000000 /* magic number for m_flags */
+-#define DLM_IFL_CB_PENDING 0x04000000
++
++#define DLM_IFL_CB_PENDING_BIT 0
++
+ /* least significant 2 bytes are message changed, they are full transmitted
+ * but at receive side only the 2 bytes LSB will be set.
+ *
+@@ -246,6 +248,7 @@ struct dlm_lkb {
+ uint32_t lkb_exflags; /* external flags from caller */
+ uint32_t lkb_sbflags; /* lksb flags */
+ uint32_t lkb_flags; /* internal flags */
++ unsigned long lkb_iflags; /* internal flags */
+ uint32_t lkb_lvbseq; /* lvb sequence number */
+
+ int8_t lkb_status; /* granted, waiting, convert */
+diff --git a/fs/dlm/user.c b/fs/dlm/user.c
+index 35129505ddda1..688a480879e4b 100644
+--- a/fs/dlm/user.c
++++ b/fs/dlm/user.c
+@@ -884,7 +884,7 @@ static ssize_t device_read(struct file *file, char __user *buf, size_t count,
+ goto try_another;
+ case DLM_DEQUEUE_CALLBACK_LAST:
+ list_del_init(&lkb->lkb_cb_list);
+- lkb->lkb_flags &= ~DLM_IFL_CB_PENDING;
++ clear_bit(DLM_IFL_CB_PENDING_BIT, &lkb->lkb_iflags);
+ break;
+ case DLM_DEQUEUE_CALLBACK_SUCCESS:
+ break;
+diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h
+index bb8501c0ff5b5..29b104754fb44 100644
+--- a/fs/erofs/internal.h
++++ b/fs/erofs/internal.h
+@@ -154,6 +154,7 @@ struct erofs_sb_info {
+
+ /* what we really care is nid, rather than ino.. */
+ erofs_nid_t root_nid;
++ erofs_nid_t packed_nid;
+ /* used for statfs, f_files - f_favail */
+ u64 inos;
+
+@@ -309,7 +310,7 @@ struct erofs_inode {
+
+ unsigned char datalayout;
+ unsigned char inode_isize;
+- unsigned short xattr_isize;
++ unsigned int xattr_isize;
+
+ unsigned int xattr_shared_count;
+ unsigned int *xattr_shared_xattrs;
+diff --git a/fs/erofs/super.c b/fs/erofs/super.c
+index 626a615dafc2f..bd8bf8fc2f5df 100644
+--- a/fs/erofs/super.c
++++ b/fs/erofs/super.c
+@@ -381,17 +381,7 @@ static int erofs_read_superblock(struct super_block *sb)
+ #endif
+ sbi->islotbits = ilog2(sizeof(struct erofs_inode_compact));
+ sbi->root_nid = le16_to_cpu(dsb->root_nid);
+-#ifdef CONFIG_EROFS_FS_ZIP
+- sbi->packed_inode = NULL;
+- if (erofs_sb_has_fragments(sbi) && dsb->packed_nid) {
+- sbi->packed_inode =
+- erofs_iget(sb, le64_to_cpu(dsb->packed_nid));
+- if (IS_ERR(sbi->packed_inode)) {
+- ret = PTR_ERR(sbi->packed_inode);
+- goto out;
+- }
+- }
+-#endif
++ sbi->packed_nid = le64_to_cpu(dsb->packed_nid);
+ sbi->inos = le64_to_cpu(dsb->inos);
+
+ sbi->build_time = le64_to_cpu(dsb->build_time);
+@@ -800,6 +790,16 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc)
+
+ erofs_shrinker_register(sb);
+ /* sb->s_umount is already locked, SB_ACTIVE and SB_BORN are not set */
++#ifdef CONFIG_EROFS_FS_ZIP
++ if (erofs_sb_has_fragments(sbi) && sbi->packed_nid) {
++ sbi->packed_inode = erofs_iget(sb, sbi->packed_nid);
++ if (IS_ERR(sbi->packed_inode)) {
++ err = PTR_ERR(sbi->packed_inode);
++ sbi->packed_inode = NULL;
++ return err;
++ }
++ }
++#endif
+ err = erofs_init_managed_cache(sb);
+ if (err)
+ return err;
+diff --git a/fs/erofs/zmap.c b/fs/erofs/zmap.c
+index 98fb90b9af715..91733f8ecdffc 100644
+--- a/fs/erofs/zmap.c
++++ b/fs/erofs/zmap.c
+@@ -211,6 +211,10 @@ static int legacy_load_cluster_from_disk(struct z_erofs_maprecorder *m,
+ if (advise & Z_EROFS_VLE_DI_PARTIAL_REF)
+ m->partialref = true;
+ m->clusterofs = le16_to_cpu(di->di_clusterofs);
++ if (m->clusterofs >= 1 << vi->z_logical_clusterbits) {
++ DBG_BUGON(1);
++ return -EFSCORRUPTED;
++ }
+ m->pblk = le32_to_cpu(di->di_u.blkaddr);
+ break;
+ default:
+diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
+index 9de1c9d1a13d3..ee5acf2bd5e67 100644
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -5802,7 +5802,8 @@ int ext4_clu_mapped(struct inode *inode, ext4_lblk_t lclu)
+ * mapped - no physical clusters have been allocated, and the
+ * file has no extents
+ */
+- if (ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA))
++ if (ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA) ||
++ ext4_has_inline_data(inode))
+ return 0;
+
+ /* search for the extent closest to the first block in the cluster */
+diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
+index 96517785a9f89..0b87665aaff13 100644
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -3149,6 +3149,9 @@ static int ext4_da_write_end(struct file *file,
+ ext4_has_inline_data(inode))
+ return ext4_write_inline_data_end(inode, pos, len, copied, page);
+
++ if (unlikely(copied < len) && !PageUptodate(page))
++ copied = 0;
++
+ start = pos & (PAGE_SIZE - 1);
+ end = start + copied - 1;
+
+diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
+index 2532f369cb10f..07c96fea76fe1 100644
+--- a/fs/f2fs/compress.c
++++ b/fs/f2fs/compress.c
+@@ -759,7 +759,12 @@ void f2fs_decompress_cluster(struct decompress_io_ctx *dic, bool in_task)
+
+ if (dic->clen > PAGE_SIZE * dic->nr_cpages - COMPRESS_HEADER_SIZE) {
+ ret = -EFSCORRUPTED;
+- f2fs_handle_error(sbi, ERROR_FAIL_DECOMPRESSION);
++
++ /* Avoid f2fs_commit_super in irq context */
++ if (in_task)
++ f2fs_save_errors(sbi, ERROR_FAIL_DECOMPRESSION);
++ else
++ f2fs_handle_error(sbi, ERROR_FAIL_DECOMPRESSION);
+ goto out_release;
+ }
+
+@@ -1459,6 +1464,12 @@ continue_unlock:
+ if (!PageDirty(cc->rpages[i]))
+ goto continue_unlock;
+
++ if (PageWriteback(cc->rpages[i])) {
++ if (wbc->sync_mode == WB_SYNC_NONE)
++ goto continue_unlock;
++ f2fs_wait_on_page_writeback(cc->rpages[i], DATA, true, true);
++ }
++
+ if (!clear_page_dirty_for_io(cc->rpages[i]))
+ goto continue_unlock;
+
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index a28d05895f5c7..75e59e7016590 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -873,6 +873,8 @@ void f2fs_submit_merged_ipu_write(struct f2fs_sb_info *sbi,
+ bool found = false;
+ struct bio *target = bio ? *bio : NULL;
+
++ f2fs_bug_on(sbi, !target && !page);
++
+ for (temp = HOT; temp < NR_TEMP_TYPE && !found; temp++) {
+ struct f2fs_bio_info *io = sbi->write_io[DATA] + temp;
+ struct list_head *head = &io->bio_list;
+@@ -2899,7 +2901,8 @@ out:
+
+ if (unlikely(f2fs_cp_error(sbi))) {
+ f2fs_submit_merged_write(sbi, DATA);
+- f2fs_submit_merged_ipu_write(sbi, bio, NULL);
++ if (bio && *bio)
++ f2fs_submit_merged_ipu_write(sbi, bio, NULL);
+ submitted = NULL;
+ }
+
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index e8953c3dc81ab..42962ee0a1179 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -3576,6 +3576,7 @@ int f2fs_quota_sync(struct super_block *sb, int type);
+ loff_t max_file_blocks(struct inode *inode);
+ void f2fs_quota_off_umount(struct super_block *sb);
+ void f2fs_handle_stop(struct f2fs_sb_info *sbi, unsigned char reason);
++void f2fs_save_errors(struct f2fs_sb_info *sbi, unsigned char flag);
+ void f2fs_handle_error(struct f2fs_sb_info *sbi, unsigned char error);
+ int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover);
+ int f2fs_sync_fs(struct super_block *sb, int sync);
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 05297427552ac..de92279a80020 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -2117,7 +2117,11 @@ static int f2fs_ioc_start_atomic_write(struct file *filp, bool truncate)
+ clear_inode_flag(fi->cow_inode, FI_INLINE_DATA);
+ } else {
+ /* Reuse the already created COW inode */
+- f2fs_do_truncate_blocks(fi->cow_inode, 0, true);
++ ret = f2fs_do_truncate_blocks(fi->cow_inode, 0, true);
++ if (ret) {
++ f2fs_up_write(&fi->i_gc_rwsem[WRITE]);
++ goto out;
++ }
+ }
+
+ f2fs_write_inode(inode, NULL);
+@@ -3013,15 +3017,16 @@ int f2fs_transfer_project_quota(struct inode *inode, kprojid_t kprojid)
+ struct dquot *transfer_to[MAXQUOTAS] = {};
+ struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+ struct super_block *sb = sbi->sb;
+- int err = 0;
++ int err;
+
+ transfer_to[PRJQUOTA] = dqget(sb, make_kqid_projid(kprojid));
+- if (!IS_ERR(transfer_to[PRJQUOTA])) {
+- err = __dquot_transfer(inode, transfer_to);
+- if (err)
+- set_sbi_flag(sbi, SBI_QUOTA_NEED_REPAIR);
+- dqput(transfer_to[PRJQUOTA]);
+- }
++ if (IS_ERR(transfer_to[PRJQUOTA]))
++ return PTR_ERR(transfer_to[PRJQUOTA]);
++
++ err = __dquot_transfer(inode, transfer_to);
++ if (err)
++ set_sbi_flag(sbi, SBI_QUOTA_NEED_REPAIR);
++ dqput(transfer_to[PRJQUOTA]);
+ return err;
+ }
+
+diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
+index 6e2cae3d2e717..72cda2f9380f2 100644
+--- a/fs/f2fs/gc.c
++++ b/fs/f2fs/gc.c
+@@ -1795,8 +1795,8 @@ int f2fs_gc(struct f2fs_sb_info *sbi, struct f2fs_gc_control *gc_control)
+ prefree_segments(sbi));
+
+ cpc.reason = __get_cp_reason(sbi);
+- sbi->skipped_gc_rwsem = 0;
+ gc_more:
++ sbi->skipped_gc_rwsem = 0;
+ if (unlikely(!(sbi->sb->s_flags & SB_ACTIVE))) {
+ ret = -EINVAL;
+ goto stop;
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index 269f89d202c61..06991cf643296 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -246,10 +246,16 @@ retry:
+ } else {
+ blkcnt_t count = 1;
+
++ err = inc_valid_block_count(sbi, inode, &count);
++ if (err) {
++ f2fs_put_dnode(&dn);
++ return err;
++ }
++
+ *old_addr = dn.data_blkaddr;
+ f2fs_truncate_data_blocks_range(&dn, 1);
+ dec_valid_block_count(sbi, F2FS_I(inode)->cow_inode, count);
+- inc_valid_block_count(sbi, inode, &count);
++
+ f2fs_replace_block(sbi, &dn, dn.data_blkaddr, new_addr,
+ ni.version, true, false);
+ }
+@@ -4951,48 +4957,6 @@ int f2fs_check_write_pointer(struct f2fs_sb_info *sbi)
+ return 0;
+ }
+
+-static bool is_conv_zone(struct f2fs_sb_info *sbi, unsigned int zone_idx,
+- unsigned int dev_idx)
+-{
+- if (!bdev_is_zoned(FDEV(dev_idx).bdev))
+- return true;
+- return !test_bit(zone_idx, FDEV(dev_idx).blkz_seq);
+-}
+-
+-/* Return the zone index in the given device */
+-static unsigned int get_zone_idx(struct f2fs_sb_info *sbi, unsigned int secno,
+- int dev_idx)
+-{
+- block_t sec_start_blkaddr = START_BLOCK(sbi, GET_SEG_FROM_SEC(sbi, secno));
+-
+- return (sec_start_blkaddr - FDEV(dev_idx).start_blk) >>
+- sbi->log_blocks_per_blkz;
+-}
+-
+-/*
+- * Return the usable segments in a section based on the zone's
+- * corresponding zone capacity. Zone is equal to a section.
+- */
+-static inline unsigned int f2fs_usable_zone_segs_in_sec(
+- struct f2fs_sb_info *sbi, unsigned int segno)
+-{
+- unsigned int dev_idx, zone_idx;
+-
+- dev_idx = f2fs_target_device_index(sbi, START_BLOCK(sbi, segno));
+- zone_idx = get_zone_idx(sbi, GET_SEC_FROM_SEG(sbi, segno), dev_idx);
+-
+- /* Conventional zone's capacity is always equal to zone size */
+- if (is_conv_zone(sbi, zone_idx, dev_idx))
+- return sbi->segs_per_sec;
+-
+- if (!sbi->unusable_blocks_per_sec)
+- return sbi->segs_per_sec;
+-
+- /* Get the segment count beyond zone capacity block */
+- return sbi->segs_per_sec - (sbi->unusable_blocks_per_sec >>
+- sbi->log_blocks_per_seg);
+-}
+-
+ /*
+ * Return the number of usable blocks in a segment. The number of blocks
+ * returned is always equal to the number of blocks in a segment for
+@@ -5005,23 +4969,13 @@ static inline unsigned int f2fs_usable_zone_blks_in_seg(
+ struct f2fs_sb_info *sbi, unsigned int segno)
+ {
+ block_t seg_start, sec_start_blkaddr, sec_cap_blkaddr;
+- unsigned int zone_idx, dev_idx, secno;
+-
+- secno = GET_SEC_FROM_SEG(sbi, segno);
+- seg_start = START_BLOCK(sbi, segno);
+- dev_idx = f2fs_target_device_index(sbi, seg_start);
+- zone_idx = get_zone_idx(sbi, secno, dev_idx);
+-
+- /*
+- * Conventional zone's capacity is always equal to zone size,
+- * so, blocks per segment is unchanged.
+- */
+- if (is_conv_zone(sbi, zone_idx, dev_idx))
+- return sbi->blocks_per_seg;
++ unsigned int secno;
+
+ if (!sbi->unusable_blocks_per_sec)
+ return sbi->blocks_per_seg;
+
++ secno = GET_SEC_FROM_SEG(sbi, segno);
++ seg_start = START_BLOCK(sbi, segno);
+ sec_start_blkaddr = START_BLOCK(sbi, GET_SEG_FROM_SEC(sbi, secno));
+ sec_cap_blkaddr = sec_start_blkaddr + CAP_BLKS_PER_SEC(sbi);
+
+@@ -5055,11 +5009,6 @@ static inline unsigned int f2fs_usable_zone_blks_in_seg(struct f2fs_sb_info *sbi
+ return 0;
+ }
+
+-static inline unsigned int f2fs_usable_zone_segs_in_sec(struct f2fs_sb_info *sbi,
+- unsigned int segno)
+-{
+- return 0;
+-}
+ #endif
+ unsigned int f2fs_usable_blks_in_seg(struct f2fs_sb_info *sbi,
+ unsigned int segno)
+@@ -5074,7 +5023,7 @@ unsigned int f2fs_usable_segs_in_sec(struct f2fs_sb_info *sbi,
+ unsigned int segno)
+ {
+ if (f2fs_sb_has_blkzoned(sbi))
+- return f2fs_usable_zone_segs_in_sec(sbi, segno);
++ return CAP_SEGS_PER_SEC(sbi);
+
+ return sbi->segs_per_sec;
+ }
+diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
+index 6eb5922a25361..822c47fdc6e35 100644
+--- a/fs/f2fs/segment.h
++++ b/fs/f2fs/segment.h
+@@ -104,6 +104,9 @@ static inline void sanity_check_seg_type(struct f2fs_sb_info *sbi,
+ #define CAP_BLKS_PER_SEC(sbi) \
+ ((sbi)->segs_per_sec * (sbi)->blocks_per_seg - \
+ (sbi)->unusable_blocks_per_sec)
++#define CAP_SEGS_PER_SEC(sbi) \
++ ((sbi)->segs_per_sec - ((sbi)->unusable_blocks_per_sec >>\
++ (sbi)->log_blocks_per_seg))
+ #define GET_SEC_FROM_SEG(sbi, segno) \
+ (((segno) == -1) ? -1: (segno) / (sbi)->segs_per_sec)
+ #define GET_SEG_FROM_SEC(sbi, secno) \
+diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
+index 551468dad3275..3711445a2489b 100644
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -3895,7 +3895,7 @@ void f2fs_handle_stop(struct f2fs_sb_info *sbi, unsigned char reason)
+ f2fs_up_write(&sbi->sb_lock);
+ }
+
+-static void f2fs_save_errors(struct f2fs_sb_info *sbi, unsigned char flag)
++void f2fs_save_errors(struct f2fs_sb_info *sbi, unsigned char flag)
+ {
+ spin_lock(&sbi->error_lock);
+ if (!test_bit(flag, (unsigned long *)sbi->errors)) {
+diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
+index 088b816127ecb..2884efe5269ed 100644
+--- a/fs/f2fs/sysfs.c
++++ b/fs/f2fs/sysfs.c
+@@ -564,9 +564,9 @@ out:
+ if (!strcmp(a->attr.name, "iostat_period_ms")) {
+ if (t < MIN_IOSTAT_PERIOD_MS || t > MAX_IOSTAT_PERIOD_MS)
+ return -EINVAL;
+- spin_lock(&sbi->iostat_lock);
++ spin_lock_irq(&sbi->iostat_lock);
+ sbi->iostat_period_ms = (unsigned int)t;
+- spin_unlock(&sbi->iostat_lock);
++ spin_unlock_irq(&sbi->iostat_lock);
+ return count;
+ }
+ #endif
+diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
+index 15de1385012eb..18611241f4513 100644
+--- a/fs/jbd2/transaction.c
++++ b/fs/jbd2/transaction.c
+@@ -2387,6 +2387,9 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh,
+ spin_unlock(&jh->b_state_lock);
+ write_unlock(&journal->j_state_lock);
+ jbd2_journal_put_journal_head(jh);
++ /* Already zapped buffer? Nothing to do... */
++ if (!bh->b_bdev)
++ return 0;
+ return -EBUSY;
+ }
+ /*
+diff --git a/fs/ksmbd/auth.c b/fs/ksmbd/auth.c
+index cead696b656a8..df8fb076f6f14 100644
+--- a/fs/ksmbd/auth.c
++++ b/fs/ksmbd/auth.c
+@@ -221,22 +221,22 @@ int ksmbd_auth_ntlmv2(struct ksmbd_conn *conn, struct ksmbd_session *sess,
+ {
+ char ntlmv2_hash[CIFS_ENCPWD_SIZE];
+ char ntlmv2_rsp[CIFS_HMAC_MD5_HASH_SIZE];
+- struct ksmbd_crypto_ctx *ctx;
++ struct ksmbd_crypto_ctx *ctx = NULL;
+ char *construct = NULL;
+ int rc, len;
+
+- ctx = ksmbd_crypto_ctx_find_hmacmd5();
+- if (!ctx) {
+- ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
+- return -ENOMEM;
+- }
+-
+ rc = calc_ntlmv2_hash(conn, sess, ntlmv2_hash, domain_name);
+ if (rc) {
+ ksmbd_debug(AUTH, "could not get v2 hash rc %d\n", rc);
+ goto out;
+ }
+
++ ctx = ksmbd_crypto_ctx_find_hmacmd5();
++ if (!ctx) {
++ ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
++ return -ENOMEM;
++ }
++
+ rc = crypto_shash_setkey(CRYPTO_HMACMD5_TFM(ctx),
+ ntlmv2_hash,
+ CIFS_HMAC_MD5_HASH_SIZE);
+@@ -272,6 +272,8 @@ int ksmbd_auth_ntlmv2(struct ksmbd_conn *conn, struct ksmbd_session *sess,
+ ksmbd_debug(AUTH, "Could not generate md5 hash\n");
+ goto out;
+ }
++ ksmbd_release_crypto_ctx(ctx);
++ ctx = NULL;
+
+ rc = ksmbd_gen_sess_key(sess, ntlmv2_hash, ntlmv2_rsp);
+ if (rc) {
+@@ -282,7 +284,8 @@ int ksmbd_auth_ntlmv2(struct ksmbd_conn *conn, struct ksmbd_session *sess,
+ if (memcmp(ntlmv2->ntlmv2_hash, ntlmv2_rsp, CIFS_HMAC_MD5_HASH_SIZE) != 0)
+ rc = -EINVAL;
+ out:
+- ksmbd_release_crypto_ctx(ctx);
++ if (ctx)
++ ksmbd_release_crypto_ctx(ctx);
+ kfree(construct);
+ return rc;
+ }
+diff --git a/fs/ksmbd/mgmt/tree_connect.c b/fs/ksmbd/mgmt/tree_connect.c
+index 8ce17b3fb8dad..f19de20c2960c 100644
+--- a/fs/ksmbd/mgmt/tree_connect.c
++++ b/fs/ksmbd/mgmt/tree_connect.c
+@@ -109,7 +109,15 @@ int ksmbd_tree_conn_disconnect(struct ksmbd_session *sess,
+ struct ksmbd_tree_connect *ksmbd_tree_conn_lookup(struct ksmbd_session *sess,
+ unsigned int id)
+ {
+- return xa_load(&sess->tree_conns, id);
++ struct ksmbd_tree_connect *tcon;
++
++ tcon = xa_load(&sess->tree_conns, id);
++ if (tcon) {
++ if (test_bit(TREE_CONN_EXPIRE, &tcon->status))
++ tcon = NULL;
++ }
++
++ return tcon;
+ }
+
+ struct ksmbd_share_config *ksmbd_tree_conn_share(struct ksmbd_session *sess,
+diff --git a/fs/ksmbd/mgmt/tree_connect.h b/fs/ksmbd/mgmt/tree_connect.h
+index 0f97ddc1e39c0..700df36cf3e30 100644
+--- a/fs/ksmbd/mgmt/tree_connect.h
++++ b/fs/ksmbd/mgmt/tree_connect.h
+@@ -14,6 +14,8 @@ struct ksmbd_share_config;
+ struct ksmbd_user;
+ struct ksmbd_conn;
+
++#define TREE_CONN_EXPIRE 1
++
+ struct ksmbd_tree_connect {
+ int id;
+
+@@ -25,6 +27,7 @@ struct ksmbd_tree_connect {
+
+ int maximal_access;
+ bool posix_extensions;
++ unsigned long status;
+ };
+
+ struct ksmbd_tree_conn_status {
+diff --git a/fs/ksmbd/server.c b/fs/ksmbd/server.c
+index 0d8242789dc8f..cd8a873347a79 100644
+--- a/fs/ksmbd/server.c
++++ b/fs/ksmbd/server.c
+@@ -606,6 +606,7 @@ err_unregister:
+ static void __exit ksmbd_server_exit(void)
+ {
+ ksmbd_server_shutdown();
++ rcu_barrier();
+ ksmbd_release_inode_hash();
+ }
+
+diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c
+index 32a837014cbfc..decaef3592f43 100644
+--- a/fs/ksmbd/smb2pdu.c
++++ b/fs/ksmbd/smb2pdu.c
+@@ -1456,7 +1456,7 @@ static int ntlm_authenticate(struct ksmbd_work *work)
+ * Reuse session if anonymous try to connect
+ * on reauthetication.
+ */
+- if (ksmbd_anonymous_user(user)) {
++ if (conn->binding == false && ksmbd_anonymous_user(user)) {
+ ksmbd_free_user(user);
+ return 0;
+ }
+@@ -1470,7 +1470,7 @@ static int ntlm_authenticate(struct ksmbd_work *work)
+ sess->user = user;
+ }
+
+- if (user_guest(sess->user)) {
++ if (conn->binding == false && user_guest(sess->user)) {
+ rsp->SessionFlags = SMB2_SESSION_FLAG_IS_GUEST_LE;
+ } else {
+ struct authenticate_message *authblob;
+@@ -1715,6 +1715,11 @@ int smb2_sess_setup(struct ksmbd_work *work)
+ goto out_err;
+ }
+
++ if (user_guest(sess->user)) {
++ rc = -EOPNOTSUPP;
++ goto out_err;
++ }
++
+ conn->binding = true;
+ } else if ((conn->dialect < SMB30_PROT_ID ||
+ server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL) &&
+@@ -1801,6 +1806,10 @@ int smb2_sess_setup(struct ksmbd_work *work)
+ }
+ kfree(sess->Preauth_HashValue);
+ sess->Preauth_HashValue = NULL;
++ } else {
++ pr_info_ratelimited("Unknown NTLMSSP message type : 0x%x\n",
++ le32_to_cpu(negblob->MessageType));
++ rc = -EINVAL;
+ }
+ } else {
+ /* TODO: need one more negotiation */
+@@ -1823,6 +1832,8 @@ out_err:
+ rsp->hdr.Status = STATUS_NETWORK_SESSION_EXPIRED;
+ else if (rc == -ENOMEM)
+ rsp->hdr.Status = STATUS_INSUFFICIENT_RESOURCES;
++ else if (rc == -EOPNOTSUPP)
++ rsp->hdr.Status = STATUS_NOT_SUPPORTED;
+ else if (rc)
+ rsp->hdr.Status = STATUS_LOGON_FAILURE;
+
+@@ -2055,11 +2066,12 @@ int smb2_tree_disconnect(struct ksmbd_work *work)
+
+ ksmbd_debug(SMB, "request\n");
+
+- if (!tcon) {
++ if (!tcon || test_and_set_bit(TREE_CONN_EXPIRE, &tcon->status)) {
+ struct smb2_tree_disconnect_req *req =
+ smb2_get_msg(work->request_buf);
+
+ ksmbd_debug(SMB, "Invalid tid %d\n", req->hdr.Id.SyncId.TreeId);
++
+ rsp->hdr.Status = STATUS_NETWORK_NAME_DELETED;
+ smb2_set_err_rsp(work);
+ return 0;
+@@ -4914,6 +4926,9 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
+ int rc = 0, len;
+ int fs_infoclass_size = 0;
+
++ if (!share->path)
++ return -EIO;
++
+ rc = kern_path(share->path, LOOKUP_NO_SYMLINKS, &path);
+ if (rc) {
+ pr_err("cannot create vfs path\n");
+diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
+index 2a0ca5c7f082a..660ccfaf463e4 100644
+--- a/fs/nfs/nfs4state.c
++++ b/fs/nfs/nfs4state.c
+@@ -67,6 +67,8 @@
+
+ #define OPENOWNER_POOL_SIZE 8
+
++static void nfs4_state_start_reclaim_reboot(struct nfs_client *clp);
++
+ const nfs4_stateid zero_stateid = {
+ { .data = { 0 } },
+ .type = NFS4_SPECIAL_STATEID_TYPE,
+@@ -330,6 +332,8 @@ do_confirm:
+ status = nfs4_proc_create_session(clp, cred);
+ if (status != 0)
+ goto out;
++ if (!(clp->cl_exchange_flags & EXCHGID4_FLAG_CONFIRMED_R))
++ nfs4_state_start_reclaim_reboot(clp);
+ nfs41_finish_session_reset(clp);
+ nfs_mark_client_ready(clp, NFS_CS_READY);
+ out:
+diff --git a/fs/nilfs2/bmap.c b/fs/nilfs2/bmap.c
+index 798a2c1b38c6c..7a8f166f2c8d8 100644
+--- a/fs/nilfs2/bmap.c
++++ b/fs/nilfs2/bmap.c
+@@ -67,20 +67,28 @@ int nilfs_bmap_lookup_at_level(struct nilfs_bmap *bmap, __u64 key, int level,
+
+ down_read(&bmap->b_sem);
+ ret = bmap->b_ops->bop_lookup(bmap, key, level, ptrp);
+- if (ret < 0) {
+- ret = nilfs_bmap_convert_error(bmap, __func__, ret);
++ if (ret < 0)
+ goto out;
+- }
++
+ if (NILFS_BMAP_USE_VBN(bmap)) {
+ ret = nilfs_dat_translate(nilfs_bmap_get_dat(bmap), *ptrp,
+ &blocknr);
+ if (!ret)
+ *ptrp = blocknr;
++ else if (ret == -ENOENT) {
++ /*
++ * If there was no valid entry in DAT for the block
++ * address obtained by b_ops->bop_lookup, then pass
++ * internal code -EINVAL to nilfs_bmap_convert_error
++ * to treat it as metadata corruption.
++ */
++ ret = -EINVAL;
++ }
+ }
+
+ out:
+ up_read(&bmap->b_sem);
+- return ret;
++ return nilfs_bmap_convert_error(bmap, __func__, ret);
+ }
+
+ int nilfs_bmap_lookup_contig(struct nilfs_bmap *bmap, __u64 key, __u64 *ptrp,
+diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
+index 5b15746055927..e26eb45c446f2 100644
+--- a/fs/nilfs2/segment.c
++++ b/fs/nilfs2/segment.c
+@@ -2039,6 +2039,9 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
+ struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
+ int err;
+
++ if (sb_rdonly(sci->sc_super))
++ return -EROFS;
++
+ nilfs_sc_cstage_set(sci, NILFS_ST_INIT);
+ sci->sc_cno = nilfs->ns_cno;
+
+@@ -2722,7 +2725,7 @@ static void nilfs_segctor_write_out(struct nilfs_sc_info *sci)
+
+ flush_work(&sci->sc_iput_work);
+
+- } while (ret && retrycount-- > 0);
++ } while (ret && ret != -EROFS && retrycount-- > 0);
+ }
+
+ /**
+diff --git a/fs/ntfs3/fslog.c b/fs/ntfs3/fslog.c
+index c6eb371a36951..bf73964472845 100644
+--- a/fs/ntfs3/fslog.c
++++ b/fs/ntfs3/fslog.c
+@@ -2575,7 +2575,7 @@ static int read_next_log_rec(struct ntfs_log *log, struct lcb *lcb, u64 *lsn)
+ return find_log_rec(log, *lsn, lcb);
+ }
+
+-static inline bool check_index_header(const struct INDEX_HDR *hdr, size_t bytes)
++bool check_index_header(const struct INDEX_HDR *hdr, size_t bytes)
+ {
+ __le16 mask;
+ u32 min_de, de_off, used, total;
+@@ -4256,6 +4256,10 @@ check_attribute_names:
+ rec_len -= t32;
+
+ attr_names = kmemdup(Add2Ptr(lrh, t32), rec_len, GFP_NOFS);
++ if (!attr_names) {
++ err = -ENOMEM;
++ goto out;
++ }
+
+ lcb_put(lcb);
+ lcb = NULL;
+diff --git a/fs/ntfs3/index.c b/fs/ntfs3/index.c
+index 51ab759546403..7a1e01a2ed9ae 100644
+--- a/fs/ntfs3/index.c
++++ b/fs/ntfs3/index.c
+@@ -725,9 +725,13 @@ static struct NTFS_DE *hdr_find_e(const struct ntfs_index *indx,
+ u32 e_size, e_key_len;
+ u32 end = le32_to_cpu(hdr->used);
+ u32 off = le32_to_cpu(hdr->de_off);
++ u32 total = le32_to_cpu(hdr->total);
+ u16 offs[128];
+
+ fill_table:
++ if (end > total)
++ return NULL;
++
+ if (off + sizeof(struct NTFS_DE) > end)
+ return NULL;
+
+@@ -844,6 +848,10 @@ static inline struct NTFS_DE *hdr_delete_de(struct INDEX_HDR *hdr,
+ u32 off = PtrOffset(hdr, re);
+ int bytes = used - (off + esize);
+
++ /* check INDEX_HDR valid before using INDEX_HDR */
++ if (!check_index_header(hdr, le32_to_cpu(hdr->total)))
++ return NULL;
++
+ if (off >= used || esize < sizeof(struct NTFS_DE) ||
+ bytes < sizeof(struct NTFS_DE))
+ return NULL;
+diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c
+index 20b953871574b..33494a67bf063 100644
+--- a/fs/ntfs3/inode.c
++++ b/fs/ntfs3/inode.c
+@@ -259,7 +259,6 @@ next_attr:
+ goto out;
+
+ root = Add2Ptr(attr, roff);
+- is_root = true;
+
+ if (attr->name_len != ARRAY_SIZE(I30_NAME) ||
+ memcmp(attr_name(attr), I30_NAME, sizeof(I30_NAME)))
+@@ -272,6 +271,7 @@ next_attr:
+ if (!is_dir)
+ goto next_attr;
+
++ is_root = true;
+ ni->ni_flags |= NI_FLAG_DIR;
+
+ err = indx_init(&ni->dir, sbi, attr, INDEX_MUTEX_I30);
+diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h
+index 0e051c5595a21..2050eb3f6a5a6 100644
+--- a/fs/ntfs3/ntfs_fs.h
++++ b/fs/ntfs3/ntfs_fs.h
+@@ -579,6 +579,7 @@ int ni_rename(struct ntfs_inode *dir_ni, struct ntfs_inode *new_dir_ni,
+ bool ni_is_dirty(struct inode *inode);
+
+ /* Globals from fslog.c */
++bool check_index_header(const struct INDEX_HDR *hdr, size_t bytes);
+ int log_replay(struct ntfs_inode *ni, bool *initialized);
+
+ /* Globals from fsntfs.c */
+diff --git a/fs/pstore/pmsg.c b/fs/pstore/pmsg.c
+index ab82e5f053464..b31c9c72d90b4 100644
+--- a/fs/pstore/pmsg.c
++++ b/fs/pstore/pmsg.c
+@@ -7,10 +7,9 @@
+ #include <linux/device.h>
+ #include <linux/fs.h>
+ #include <linux/uaccess.h>
+-#include <linux/rtmutex.h>
+ #include "internal.h"
+
+-static DEFINE_RT_MUTEX(pmsg_lock);
++static DEFINE_MUTEX(pmsg_lock);
+
+ static ssize_t write_pmsg(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+@@ -29,9 +28,9 @@ static ssize_t write_pmsg(struct file *file, const char __user *buf,
+ if (!access_ok(buf, count))
+ return -EFAULT;
+
+- rt_mutex_lock(&pmsg_lock);
++ mutex_lock(&pmsg_lock);
+ ret = psinfo->write_user(&record, buf);
+- rt_mutex_unlock(&pmsg_lock);
++ mutex_unlock(&pmsg_lock);
+ return ret ? ret : count;
+ }
+
+diff --git a/fs/reiserfs/xattr_security.c b/fs/reiserfs/xattr_security.c
+index 857a65b057264..157ebfe2456bb 100644
+--- a/fs/reiserfs/xattr_security.c
++++ b/fs/reiserfs/xattr_security.c
+@@ -82,11 +82,15 @@ int reiserfs_security_write(struct reiserfs_transaction_handle *th,
+ struct inode *inode,
+ struct reiserfs_security_handle *sec)
+ {
++ char xattr_name[XATTR_NAME_MAX + 1] = XATTR_SECURITY_PREFIX;
+ int error;
+- if (strlen(sec->name) < sizeof(XATTR_SECURITY_PREFIX))
++
++ if (XATTR_SECURITY_PREFIX_LEN + strlen(sec->name) > XATTR_NAME_MAX)
+ return -EINVAL;
+
+- error = reiserfs_xattr_set_handle(th, inode, sec->name, sec->value,
++ strlcat(xattr_name, sec->name, sizeof(xattr_name));
++
++ error = reiserfs_xattr_set_handle(th, inode, xattr_name, sec->value,
+ sec->length, XATTR_CREATE);
+ if (error == -ENODATA || error == -EOPNOTSUPP)
+ error = 0;
+diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
+index 5e6bcce94e641..66ba57a139d2a 100644
+--- a/fs/ubifs/dir.c
++++ b/fs/ubifs/dir.c
+@@ -358,7 +358,6 @@ static struct inode *create_whiteout(struct inode *dir, struct dentry *dentry)
+ umode_t mode = S_IFCHR | WHITEOUT_MODE;
+ struct inode *inode;
+ struct ubifs_info *c = dir->i_sb->s_fs_info;
+- struct fscrypt_name nm;
+
+ /*
+ * Create an inode('nlink = 1') for whiteout without updating journal,
+@@ -369,10 +368,6 @@ static struct inode *create_whiteout(struct inode *dir, struct dentry *dentry)
+ dbg_gen("dent '%pd', mode %#hx in dir ino %lu",
+ dentry, mode, dir->i_ino);
+
+- err = fscrypt_setup_filename(dir, &dentry->d_name, 0, &nm);
+- if (err)
+- return ERR_PTR(err);
+-
+ inode = ubifs_new_inode(c, dir, mode, false);
+ if (IS_ERR(inode)) {
+ err = PTR_ERR(inode);
+@@ -395,7 +390,6 @@ out_inode:
+ make_bad_inode(inode);
+ iput(inode);
+ out_free:
+- fscrypt_free_filename(&nm);
+ ubifs_err(c, "cannot create whiteout file, error %d", err);
+ return ERR_PTR(err);
+ }
+@@ -492,6 +486,7 @@ static int ubifs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
+ unlock_2_inodes(dir, inode);
+
+ ubifs_release_budget(c, &req);
++ fscrypt_free_filename(&nm);
+
+ return finish_open_simple(file, 0);
+
+diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c
+index 2469f72eeaabb..6b7d95b65f4b6 100644
+--- a/fs/ubifs/tnc.c
++++ b/fs/ubifs/tnc.c
+@@ -44,6 +44,33 @@ enum {
+ NOT_ON_MEDIA = 3,
+ };
+
++static void do_insert_old_idx(struct ubifs_info *c,
++ struct ubifs_old_idx *old_idx)
++{
++ struct ubifs_old_idx *o;
++ struct rb_node **p, *parent = NULL;
++
++ p = &c->old_idx.rb_node;
++ while (*p) {
++ parent = *p;
++ o = rb_entry(parent, struct ubifs_old_idx, rb);
++ if (old_idx->lnum < o->lnum)
++ p = &(*p)->rb_left;
++ else if (old_idx->lnum > o->lnum)
++ p = &(*p)->rb_right;
++ else if (old_idx->offs < o->offs)
++ p = &(*p)->rb_left;
++ else if (old_idx->offs > o->offs)
++ p = &(*p)->rb_right;
++ else {
++ ubifs_err(c, "old idx added twice!");
++ kfree(old_idx);
++ }
++ }
++ rb_link_node(&old_idx->rb, parent, p);
++ rb_insert_color(&old_idx->rb, &c->old_idx);
++}
++
+ /**
+ * insert_old_idx - record an index node obsoleted since the last commit start.
+ * @c: UBIFS file-system description object
+@@ -69,35 +96,15 @@ enum {
+ */
+ static int insert_old_idx(struct ubifs_info *c, int lnum, int offs)
+ {
+- struct ubifs_old_idx *old_idx, *o;
+- struct rb_node **p, *parent = NULL;
++ struct ubifs_old_idx *old_idx;
+
+ old_idx = kmalloc(sizeof(struct ubifs_old_idx), GFP_NOFS);
+ if (unlikely(!old_idx))
+ return -ENOMEM;
+ old_idx->lnum = lnum;
+ old_idx->offs = offs;
++ do_insert_old_idx(c, old_idx);
+
+- p = &c->old_idx.rb_node;
+- while (*p) {
+- parent = *p;
+- o = rb_entry(parent, struct ubifs_old_idx, rb);
+- if (lnum < o->lnum)
+- p = &(*p)->rb_left;
+- else if (lnum > o->lnum)
+- p = &(*p)->rb_right;
+- else if (offs < o->offs)
+- p = &(*p)->rb_left;
+- else if (offs > o->offs)
+- p = &(*p)->rb_right;
+- else {
+- ubifs_err(c, "old idx added twice!");
+- kfree(old_idx);
+- return 0;
+- }
+- }
+- rb_link_node(&old_idx->rb, parent, p);
+- rb_insert_color(&old_idx->rb, &c->old_idx);
+ return 0;
+ }
+
+@@ -199,23 +206,6 @@ static struct ubifs_znode *copy_znode(struct ubifs_info *c,
+ __set_bit(DIRTY_ZNODE, &zn->flags);
+ __clear_bit(COW_ZNODE, &zn->flags);
+
+- ubifs_assert(c, !ubifs_zn_obsolete(znode));
+- __set_bit(OBSOLETE_ZNODE, &znode->flags);
+-
+- if (znode->level != 0) {
+- int i;
+- const int n = zn->child_cnt;
+-
+- /* The children now have new parent */
+- for (i = 0; i < n; i++) {
+- struct ubifs_zbranch *zbr = &zn->zbranch[i];
+-
+- if (zbr->znode)
+- zbr->znode->parent = zn;
+- }
+- }
+-
+- atomic_long_inc(&c->dirty_zn_cnt);
+ return zn;
+ }
+
+@@ -233,6 +223,42 @@ static int add_idx_dirt(struct ubifs_info *c, int lnum, int dirt)
+ return ubifs_add_dirt(c, lnum, dirt);
+ }
+
++/**
++ * replace_znode - replace old znode with new znode.
++ * @c: UBIFS file-system description object
++ * @new_zn: new znode
++ * @old_zn: old znode
++ * @zbr: the branch of parent znode
++ *
++ * Replace old znode with new znode in TNC.
++ */
++static void replace_znode(struct ubifs_info *c, struct ubifs_znode *new_zn,
++ struct ubifs_znode *old_zn, struct ubifs_zbranch *zbr)
++{
++ ubifs_assert(c, !ubifs_zn_obsolete(old_zn));
++ __set_bit(OBSOLETE_ZNODE, &old_zn->flags);
++
++ if (old_zn->level != 0) {
++ int i;
++ const int n = new_zn->child_cnt;
++
++ /* The children now have new parent */
++ for (i = 0; i < n; i++) {
++ struct ubifs_zbranch *child = &new_zn->zbranch[i];
++
++ if (child->znode)
++ child->znode->parent = new_zn;
++ }
++ }
++
++ zbr->znode = new_zn;
++ zbr->lnum = 0;
++ zbr->offs = 0;
++ zbr->len = 0;
++
++ atomic_long_inc(&c->dirty_zn_cnt);
++}
++
+ /**
+ * dirty_cow_znode - ensure a znode is not being committed.
+ * @c: UBIFS file-system description object
+@@ -265,28 +291,32 @@ static struct ubifs_znode *dirty_cow_znode(struct ubifs_info *c,
+ return zn;
+
+ if (zbr->len) {
+- err = insert_old_idx(c, zbr->lnum, zbr->offs);
+- if (unlikely(err))
+- /*
+- * Obsolete znodes will be freed by tnc_destroy_cnext()
+- * or free_obsolete_znodes(), copied up znodes should
+- * be added back to tnc and freed by
+- * ubifs_destroy_tnc_subtree().
+- */
++ struct ubifs_old_idx *old_idx;
++
++ old_idx = kmalloc(sizeof(struct ubifs_old_idx), GFP_NOFS);
++ if (unlikely(!old_idx)) {
++ err = -ENOMEM;
+ goto out;
++ }
++ old_idx->lnum = zbr->lnum;
++ old_idx->offs = zbr->offs;
++
+ err = add_idx_dirt(c, zbr->lnum, zbr->len);
+- } else
+- err = 0;
++ if (err) {
++ kfree(old_idx);
++ goto out;
++ }
+
+-out:
+- zbr->znode = zn;
+- zbr->lnum = 0;
+- zbr->offs = 0;
+- zbr->len = 0;
++ do_insert_old_idx(c, old_idx);
++ }
++
++ replace_znode(c, zn, znode, zbr);
+
+- if (unlikely(err))
+- return ERR_PTR(err);
+ return zn;
++
++out:
++ kfree(zn);
++ return ERR_PTR(err);
+ }
+
+ /**
+diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c
+index 1eeecf2eb2a77..28c464307817d 100644
+--- a/fs/xfs/libxfs/xfs_sb.c
++++ b/fs/xfs/libxfs/xfs_sb.c
+@@ -72,7 +72,8 @@ xfs_sb_validate_v5_features(
+ }
+
+ /*
+- * We support all XFS versions newer than a v4 superblock with V2 directories.
++ * We current support XFS v5 formats with known features and v4 superblocks with
++ * at least V2 directories.
+ */
+ bool
+ xfs_sb_good_version(
+@@ -86,16 +87,16 @@ xfs_sb_good_version(
+ if (xfs_sb_is_v5(sbp))
+ return xfs_sb_validate_v5_features(sbp);
+
++ /* versions prior to v4 are not supported */
++ if (XFS_SB_VERSION_NUM(sbp) != XFS_SB_VERSION_4)
++ return false;
++
+ /* We must not have any unknown v4 feature bits set */
+ if ((sbp->sb_versionnum & ~XFS_SB_VERSION_OKBITS) ||
+ ((sbp->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT) &&
+ (sbp->sb_features2 & ~XFS_SB_VERSION2_OKBITS)))
+ return false;
+
+- /* versions prior to v4 are not supported */
+- if (XFS_SB_VERSION_NUM(sbp) < XFS_SB_VERSION_4)
+- return false;
+-
+ /* V4 filesystems need v2 directories and unwritten extents */
+ if (!(sbp->sb_versionnum & XFS_SB_VERSION_DIRV2BIT))
+ return false;
+diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h
+index 4c44a29b5e8ef..587e7e9b9a375 100644
+--- a/include/asm-generic/io.h
++++ b/include/asm-generic/io.h
+@@ -236,7 +236,7 @@ static inline u64 readq(const volatile void __iomem *addr)
+
+ log_read_mmio(64, addr, _THIS_IP_, _RET_IP_);
+ __io_br();
+- val = __le64_to_cpu(__raw_readq(addr));
++ val = __le64_to_cpu((__le64 __force)__raw_readq(addr));
+ __io_ar(val);
+ log_post_read_mmio(val, 64, addr, _THIS_IP_, _RET_IP_);
+ return val;
+@@ -287,7 +287,7 @@ static inline void writeq(u64 value, volatile void __iomem *addr)
+ {
+ log_write_mmio(value, 64, addr, _THIS_IP_, _RET_IP_);
+ __io_bw();
+- __raw_writeq(__cpu_to_le64(value), addr);
++ __raw_writeq((u64 __force)__cpu_to_le64(value), addr);
+ __io_aw();
+ log_post_write_mmio(value, 64, addr, _THIS_IP_, _RET_IP_);
+ }
+@@ -319,7 +319,7 @@ static inline u16 readw_relaxed(const volatile void __iomem *addr)
+ u16 val;
+
+ log_read_mmio(16, addr, _THIS_IP_, _RET_IP_);
+- val = __le16_to_cpu(__raw_readw(addr));
++ val = __le16_to_cpu((__le16 __force)__raw_readw(addr));
+ log_post_read_mmio(val, 16, addr, _THIS_IP_, _RET_IP_);
+ return val;
+ }
+@@ -332,7 +332,7 @@ static inline u32 readl_relaxed(const volatile void __iomem *addr)
+ u32 val;
+
+ log_read_mmio(32, addr, _THIS_IP_, _RET_IP_);
+- val = __le32_to_cpu(__raw_readl(addr));
++ val = __le32_to_cpu((__le32 __force)__raw_readl(addr));
+ log_post_read_mmio(val, 32, addr, _THIS_IP_, _RET_IP_);
+ return val;
+ }
+@@ -345,7 +345,7 @@ static inline u64 readq_relaxed(const volatile void __iomem *addr)
+ u64 val;
+
+ log_read_mmio(64, addr, _THIS_IP_, _RET_IP_);
+- val = __le64_to_cpu(__raw_readq(addr));
++ val = __le64_to_cpu((__le64 __force)__raw_readq(addr));
+ log_post_read_mmio(val, 64, addr, _THIS_IP_, _RET_IP_);
+ return val;
+ }
+@@ -366,7 +366,7 @@ static inline void writeb_relaxed(u8 value, volatile void __iomem *addr)
+ static inline void writew_relaxed(u16 value, volatile void __iomem *addr)
+ {
+ log_write_mmio(value, 16, addr, _THIS_IP_, _RET_IP_);
+- __raw_writew(cpu_to_le16(value), addr);
++ __raw_writew((u16 __force)cpu_to_le16(value), addr);
+ log_post_write_mmio(value, 16, addr, _THIS_IP_, _RET_IP_);
+ }
+ #endif
+@@ -376,7 +376,7 @@ static inline void writew_relaxed(u16 value, volatile void __iomem *addr)
+ static inline void writel_relaxed(u32 value, volatile void __iomem *addr)
+ {
+ log_write_mmio(value, 32, addr, _THIS_IP_, _RET_IP_);
+- __raw_writel(__cpu_to_le32(value), addr);
++ __raw_writel((u32 __force)__cpu_to_le32(value), addr);
+ log_post_write_mmio(value, 32, addr, _THIS_IP_, _RET_IP_);
+ }
+ #endif
+@@ -386,7 +386,7 @@ static inline void writel_relaxed(u32 value, volatile void __iomem *addr)
+ static inline void writeq_relaxed(u64 value, volatile void __iomem *addr)
+ {
+ log_write_mmio(value, 64, addr, _THIS_IP_, _RET_IP_);
+- __raw_writeq(__cpu_to_le64(value), addr);
++ __raw_writeq((u64 __force)__cpu_to_le64(value), addr);
+ log_post_write_mmio(value, 64, addr, _THIS_IP_, _RET_IP_);
+ }
+ #endif
+diff --git a/include/drm/drm_file.h b/include/drm/drm_file.h
+index 0d1f853092ab8..ecffe24e2b1b0 100644
+--- a/include/drm/drm_file.h
++++ b/include/drm/drm_file.h
+@@ -408,7 +408,8 @@ static inline bool drm_is_render_client(const struct drm_file *file_priv)
+ * Returns true if this is an open file of the compute acceleration node, i.e.
+ * &drm_file.minor of @file_priv is a accel minor.
+ *
+- * See also the :ref:`section on accel nodes <drm_accel_node>`.
++ * See also :doc:`Introduction to compute accelerators subsystem
++ * </accel/introduction>`.
+ */
+ static inline bool drm_is_accel_client(const struct drm_file *file_priv)
+ {
+diff --git a/include/drm/i915_pciids.h b/include/drm/i915_pciids.h
+index 4a4c190f76984..8f648c32a9657 100644
+--- a/include/drm/i915_pciids.h
++++ b/include/drm/i915_pciids.h
+@@ -706,7 +706,6 @@
+ INTEL_VGA_DEVICE(0x5693, info), \
+ INTEL_VGA_DEVICE(0x5694, info), \
+ INTEL_VGA_DEVICE(0x5695, info), \
+- INTEL_VGA_DEVICE(0x5698, info), \
+ INTEL_VGA_DEVICE(0x56A5, info), \
+ INTEL_VGA_DEVICE(0x56A6, info), \
+ INTEL_VGA_DEVICE(0x56B0, info), \
+diff --git a/include/linux/blk-crypto.h b/include/linux/blk-crypto.h
+index 1e3e5d0adf120..5e5822c18ee41 100644
+--- a/include/linux/blk-crypto.h
++++ b/include/linux/blk-crypto.h
+@@ -95,8 +95,8 @@ int blk_crypto_init_key(struct blk_crypto_key *blk_key, const u8 *raw_key,
+ int blk_crypto_start_using_key(struct block_device *bdev,
+ const struct blk_crypto_key *key);
+
+-int blk_crypto_evict_key(struct block_device *bdev,
+- const struct blk_crypto_key *key);
++void blk_crypto_evict_key(struct block_device *bdev,
++ const struct blk_crypto_key *key);
+
+ bool blk_crypto_config_supported_natively(struct block_device *bdev,
+ const struct blk_crypto_config *cfg);
+diff --git a/include/linux/bpf.h b/include/linux/bpf.h
+index cf0d88109e3f9..1c88f6761eea3 100644
+--- a/include/linux/bpf.h
++++ b/include/linux/bpf.h
+@@ -95,11 +95,11 @@ struct bpf_map_ops {
+
+ /* funcs callable from userspace and from eBPF programs */
+ void *(*map_lookup_elem)(struct bpf_map *map, void *key);
+- int (*map_update_elem)(struct bpf_map *map, void *key, void *value, u64 flags);
+- int (*map_delete_elem)(struct bpf_map *map, void *key);
+- int (*map_push_elem)(struct bpf_map *map, void *value, u64 flags);
+- int (*map_pop_elem)(struct bpf_map *map, void *value);
+- int (*map_peek_elem)(struct bpf_map *map, void *value);
++ long (*map_update_elem)(struct bpf_map *map, void *key, void *value, u64 flags);
++ long (*map_delete_elem)(struct bpf_map *map, void *key);
++ long (*map_push_elem)(struct bpf_map *map, void *value, u64 flags);
++ long (*map_pop_elem)(struct bpf_map *map, void *value);
++ long (*map_peek_elem)(struct bpf_map *map, void *value);
+ void *(*map_lookup_percpu_elem)(struct bpf_map *map, void *key, u32 cpu);
+
+ /* funcs called by prog_array and perf_event_array map */
+@@ -138,7 +138,7 @@ struct bpf_map_ops {
+ struct bpf_local_storage __rcu ** (*map_owner_storage_ptr)(void *owner);
+
+ /* Misc helpers.*/
+- int (*map_redirect)(struct bpf_map *map, u64 key, u64 flags);
++ long (*map_redirect)(struct bpf_map *map, u64 key, u64 flags);
+
+ /* map_meta_equal must be implemented for maps that can be
+ * used as an inner map. It is a runtime check to ensure
+@@ -156,7 +156,7 @@ struct bpf_map_ops {
+ int (*map_set_for_each_callback_args)(struct bpf_verifier_env *env,
+ struct bpf_func_state *caller,
+ struct bpf_func_state *callee);
+- int (*map_for_each_callback)(struct bpf_map *map,
++ long (*map_for_each_callback)(struct bpf_map *map,
+ bpf_callback_t callback_fn,
+ void *callback_ctx, u64 flags);
+
+@@ -180,6 +180,10 @@ enum btf_field_type {
+ BPF_KPTR = BPF_KPTR_UNREF | BPF_KPTR_REF,
+ BPF_LIST_HEAD = (1 << 4),
+ BPF_LIST_NODE = (1 << 5),
++ BPF_RB_ROOT = (1 << 6),
++ BPF_RB_NODE = (1 << 7),
++ BPF_GRAPH_NODE_OR_ROOT = BPF_LIST_NODE | BPF_LIST_HEAD |
++ BPF_RB_NODE | BPF_RB_ROOT,
+ };
+
+ struct btf_field_kptr {
+@@ -189,7 +193,7 @@ struct btf_field_kptr {
+ u32 btf_id;
+ };
+
+-struct btf_field_list_head {
++struct btf_field_graph_root {
+ struct btf *btf;
+ u32 value_btf_id;
+ u32 node_offset;
+@@ -201,7 +205,7 @@ struct btf_field {
+ enum btf_field_type type;
+ union {
+ struct btf_field_kptr kptr;
+- struct btf_field_list_head list_head;
++ struct btf_field_graph_root graph_root;
+ };
+ };
+
+@@ -283,6 +287,10 @@ static inline const char *btf_field_type_name(enum btf_field_type type)
+ return "bpf_list_head";
+ case BPF_LIST_NODE:
+ return "bpf_list_node";
++ case BPF_RB_ROOT:
++ return "bpf_rb_root";
++ case BPF_RB_NODE:
++ return "bpf_rb_node";
+ default:
+ WARN_ON_ONCE(1);
+ return "unknown";
+@@ -303,6 +311,10 @@ static inline u32 btf_field_type_size(enum btf_field_type type)
+ return sizeof(struct bpf_list_head);
+ case BPF_LIST_NODE:
+ return sizeof(struct bpf_list_node);
++ case BPF_RB_ROOT:
++ return sizeof(struct bpf_rb_root);
++ case BPF_RB_NODE:
++ return sizeof(struct bpf_rb_node);
+ default:
+ WARN_ON_ONCE(1);
+ return 0;
+@@ -323,6 +335,10 @@ static inline u32 btf_field_type_align(enum btf_field_type type)
+ return __alignof__(struct bpf_list_head);
+ case BPF_LIST_NODE:
+ return __alignof__(struct bpf_list_node);
++ case BPF_RB_ROOT:
++ return __alignof__(struct bpf_rb_root);
++ case BPF_RB_NODE:
++ return __alignof__(struct bpf_rb_node);
+ default:
+ WARN_ON_ONCE(1);
+ return 0;
+@@ -440,6 +456,9 @@ void copy_map_value_locked(struct bpf_map *map, void *dst, void *src,
+ void bpf_timer_cancel_and_free(void *timer);
+ void bpf_list_head_free(const struct btf_field *field, void *list_head,
+ struct bpf_spin_lock *spin_lock);
++void bpf_rb_root_free(const struct btf_field *field, void *rb_root,
++ struct bpf_spin_lock *spin_lock);
++
+
+ int bpf_obj_name_cpy(char *dst, const char *src, unsigned int size);
+
+@@ -582,6 +601,11 @@ enum bpf_type_flag {
+ /* MEM is tagged with rcu and memory access needs rcu_read_lock protection. */
+ MEM_RCU = BIT(13 + BPF_BASE_TYPE_BITS),
+
++ /* Used to tag PTR_TO_BTF_ID | MEM_ALLOC references which are non-owning.
++ * Currently only valid for linked-list and rbtree nodes.
++ */
++ NON_OWN_REF = BIT(14 + BPF_BASE_TYPE_BITS),
++
+ __BPF_TYPE_FLAG_MAX,
+ __BPF_TYPE_LAST_FLAG = __BPF_TYPE_FLAG_MAX - 1,
+ };
+diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
+index 53d175cbaa027..ed2f082eabb37 100644
+--- a/include/linux/bpf_verifier.h
++++ b/include/linux/bpf_verifier.h
+@@ -43,6 +43,22 @@ enum bpf_reg_liveness {
+ REG_LIVE_DONE = 0x8, /* liveness won't be updating this register anymore */
+ };
+
++/* For every reg representing a map value or allocated object pointer,
++ * we consider the tuple of (ptr, id) for them to be unique in verifier
++ * context and conside them to not alias each other for the purposes of
++ * tracking lock state.
++ */
++struct bpf_active_lock {
++ /* This can either be reg->map_ptr or reg->btf. If ptr is NULL,
++ * there's no active lock held, and other fields have no
++ * meaning. If non-NULL, it indicates that a lock is held and
++ * id member has the reg->id of the register which can be >= 0.
++ */
++ void *ptr;
++ /* This will be reg->id */
++ u32 id;
++};
++
+ struct bpf_reg_state {
+ /* Ordering of fields matters. See states_equal() */
+ enum bpf_reg_type type;
+@@ -223,11 +239,6 @@ struct bpf_reference_state {
+ * exiting a callback function.
+ */
+ int callback_ref;
+- /* Mark the reference state to release the registers sharing the same id
+- * on bpf_spin_unlock (for nodes that we will lose ownership to but are
+- * safe to access inside the critical section).
+- */
+- bool release_on_unlock;
+ };
+
+ /* state of the program:
+@@ -328,21 +339,8 @@ struct bpf_verifier_state {
+ u32 branches;
+ u32 insn_idx;
+ u32 curframe;
+- /* For every reg representing a map value or allocated object pointer,
+- * we consider the tuple of (ptr, id) for them to be unique in verifier
+- * context and conside them to not alias each other for the purposes of
+- * tracking lock state.
+- */
+- struct {
+- /* This can either be reg->map_ptr or reg->btf. If ptr is NULL,
+- * there's no active lock held, and other fields have no
+- * meaning. If non-NULL, it indicates that a lock is held and
+- * id member has the reg->id of the register which can be >= 0.
+- */
+- void *ptr;
+- /* This will be reg->id */
+- u32 id;
+- } active_lock;
++
++ struct bpf_active_lock active_lock;
+ bool speculative;
+ bool active_rcu_lock;
+
+diff --git a/include/linux/btf.h b/include/linux/btf.h
+index 5f628f323442a..ff62fa63dc197 100644
+--- a/include/linux/btf.h
++++ b/include/linux/btf.h
+@@ -72,6 +72,14 @@
+ #define KF_DESTRUCTIVE (1 << 6) /* kfunc performs destructive actions */
+ #define KF_RCU (1 << 7) /* kfunc only takes rcu pointer arguments */
+
++/*
++ * Tag marking a kernel function as a kfunc. This is meant to minimize the
++ * amount of copy-paste that kfunc authors have to include for correctness so
++ * as to avoid issues such as the compiler inlining or eliding either a static
++ * kfunc, or a global kfunc in an LTO build.
++ */
++#define __bpf_kfunc __used noinline
++
+ /*
+ * Return the name of the passed struct, if exists, or halt the build if for
+ * example the structure gets renamed. In this way, developers have to revisit
+diff --git a/include/linux/filter.h b/include/linux/filter.h
+index ccc4a4a58c727..b08ba0a643f8c 100644
+--- a/include/linux/filter.h
++++ b/include/linux/filter.h
+@@ -1503,9 +1503,9 @@ static inline bool bpf_sk_lookup_run_v6(struct net *net, int protocol,
+ }
+ #endif /* IS_ENABLED(CONFIG_IPV6) */
+
+-static __always_inline int __bpf_xdp_redirect_map(struct bpf_map *map, u64 index,
+- u64 flags, const u64 flag_mask,
+- void *lookup_elem(struct bpf_map *map, u32 key))
++static __always_inline long __bpf_xdp_redirect_map(struct bpf_map *map, u64 index,
++ u64 flags, const u64 flag_mask,
++ void *lookup_elem(struct bpf_map *map, u32 key))
+ {
+ struct bpf_redirect_info *ri = this_cpu_ptr(&bpf_redirect_info);
+ const u64 action_mask = XDP_ABORTED | XDP_DROP | XDP_PASS | XDP_TX;
+diff --git a/include/linux/mailbox/zynqmp-ipi-message.h b/include/linux/mailbox/zynqmp-ipi-message.h
+index 35ce84c8ca02c..31d8046d945e7 100644
+--- a/include/linux/mailbox/zynqmp-ipi-message.h
++++ b/include/linux/mailbox/zynqmp-ipi-message.h
+@@ -9,7 +9,7 @@
+ * @data: message payload
+ *
+ * This is the structure for data used in mbox_send_message
+- * the maximum length of data buffer is fixed to 12 bytes.
++ * the maximum length of data buffer is fixed to 32 bytes.
+ * Client is supposed to be aware of this.
+ */
+ struct zynqmp_ipi_message {
+diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
+index a9ee7bc59c901..90ab0e31ecf46 100644
+--- a/include/linux/mlx5/mlx5_ifc.h
++++ b/include/linux/mlx5/mlx5_ifc.h
+@@ -9144,7 +9144,8 @@ struct mlx5_ifc_alloc_flow_counter_in_bits {
+ u8 reserved_at_20[0x10];
+ u8 op_mod[0x10];
+
+- u8 reserved_at_40[0x38];
++ u8 reserved_at_40[0x33];
++ u8 flow_counter_bulk_log_size[0x5];
+ u8 flow_counter_bulk[0x8];
+ };
+
+diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h
+index 241e005f290ad..e9a9ab34a7ccc 100644
+--- a/include/linux/netfilter/nfnetlink.h
++++ b/include/linux/netfilter/nfnetlink.h
+@@ -45,7 +45,6 @@ struct nfnetlink_subsystem {
+ int (*commit)(struct net *net, struct sk_buff *skb);
+ int (*abort)(struct net *net, struct sk_buff *skb,
+ enum nfnl_abort_action action);
+- void (*cleanup)(struct net *net);
+ bool (*valid_genid)(struct net *net, u32 genid);
+ };
+
+diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
+index b0d5a253156ec..b845fd83f429b 100644
+--- a/include/linux/platform_device.h
++++ b/include/linux/platform_device.h
+@@ -207,7 +207,18 @@ extern void platform_device_put(struct platform_device *pdev);
+
+ struct platform_driver {
+ int (*probe)(struct platform_device *);
++
++ /*
++ * Traditionally the remove callback returned an int which however is
++ * ignored by the driver core. This led to wrong expectations by driver
++ * authors who thought returning an error code was a valid error
++ * handling strategy. To convert to a callback returning void, new
++ * drivers should implement .remove_new() until the conversion it done
++ * that eventually makes .remove() return void.
++ */
+ int (*remove)(struct platform_device *);
++ void (*remove_new)(struct platform_device *);
++
+ void (*shutdown)(struct platform_device *);
+ int (*suspend)(struct platform_device *, pm_message_t state);
+ int (*resume)(struct platform_device *);
+diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h
+index 2c6e99ca48afc..d607f51404fca 100644
+--- a/include/linux/posix-timers.h
++++ b/include/linux/posix-timers.h
+@@ -4,6 +4,7 @@
+
+ #include <linux/spinlock.h>
+ #include <linux/list.h>
++#include <linux/mutex.h>
+ #include <linux/alarmtimer.h>
+ #include <linux/timerqueue.h>
+
+@@ -62,16 +63,18 @@ static inline int clockid_to_fd(const clockid_t clk)
+ * cpu_timer - Posix CPU timer representation for k_itimer
+ * @node: timerqueue node to queue in the task/sig
+ * @head: timerqueue head on which this timer is queued
+- * @task: Pointer to target task
++ * @pid: Pointer to target task PID
+ * @elist: List head for the expiry list
+ * @firing: Timer is currently firing
++ * @handling: Pointer to the task which handles expiry
+ */
+ struct cpu_timer {
+- struct timerqueue_node node;
+- struct timerqueue_head *head;
+- struct pid *pid;
+- struct list_head elist;
+- int firing;
++ struct timerqueue_node node;
++ struct timerqueue_head *head;
++ struct pid *pid;
++ struct list_head elist;
++ int firing;
++ struct task_struct __rcu *handling;
+ };
+
+ static inline bool cpu_timer_enqueue(struct timerqueue_head *head,
+@@ -135,10 +138,12 @@ struct posix_cputimers {
+ /**
+ * posix_cputimers_work - Container for task work based posix CPU timer expiry
+ * @work: The task work to be scheduled
++ * @mutex: Mutex held around expiry in context of this task work
+ * @scheduled: @work has been scheduled already, no further processing
+ */
+ struct posix_cputimers_work {
+ struct callback_head work;
++ struct mutex mutex;
+ unsigned int scheduled;
+ };
+
+diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h
+index b8ca3ecaf8d76..8ada7dc802d30 100644
+--- a/include/linux/sunrpc/sched.h
++++ b/include/linux/sunrpc/sched.h
+@@ -90,8 +90,7 @@ struct rpc_task {
+ #endif
+ unsigned char tk_priority : 2,/* Task priority */
+ tk_garb_retry : 2,
+- tk_cred_retry : 2,
+- tk_rebind_retry : 2;
++ tk_cred_retry : 2;
+ };
+
+ typedef void (*rpc_action)(struct rpc_task *);
+diff --git a/include/linux/tick.h b/include/linux/tick.h
+index bfd571f18cfdc..9459fef5b8573 100644
+--- a/include/linux/tick.h
++++ b/include/linux/tick.h
+@@ -216,6 +216,7 @@ extern void tick_nohz_dep_set_signal(struct task_struct *tsk,
+ enum tick_dep_bits bit);
+ extern void tick_nohz_dep_clear_signal(struct signal_struct *signal,
+ enum tick_dep_bits bit);
++extern bool tick_nohz_cpu_hotpluggable(unsigned int cpu);
+
+ /*
+ * The below are tick_nohz_[set,clear]_dep() wrappers that optimize off-cases
+@@ -280,6 +281,7 @@ static inline void tick_nohz_full_add_cpus_to(struct cpumask *mask) { }
+
+ static inline void tick_nohz_dep_set_cpu(int cpu, enum tick_dep_bits bit) { }
+ static inline void tick_nohz_dep_clear_cpu(int cpu, enum tick_dep_bits bit) { }
++static inline bool tick_nohz_cpu_hotpluggable(unsigned int cpu) { return true; }
+
+ static inline void tick_dep_set(enum tick_dep_bits bit) { }
+ static inline void tick_dep_clear(enum tick_dep_bits bit) { }
+diff --git a/include/linux/vt_buffer.h b/include/linux/vt_buffer.h
+index 848db1b1569ff..919d999a8c1db 100644
+--- a/include/linux/vt_buffer.h
++++ b/include/linux/vt_buffer.h
+@@ -16,7 +16,7 @@
+
+ #include <linux/string.h>
+
+-#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_MDA_CONSOLE)
++#if IS_ENABLED(CONFIG_VGA_CONSOLE) || IS_ENABLED(CONFIG_MDA_CONSOLE)
+ #include <asm/vga.h>
+ #endif
+
+diff --git a/include/net/netfilter/nf_conntrack_core.h b/include/net/netfilter/nf_conntrack_core.h
+index 71d1269fe4d4f..3384859a89210 100644
+--- a/include/net/netfilter/nf_conntrack_core.h
++++ b/include/net/netfilter/nf_conntrack_core.h
+@@ -89,7 +89,11 @@ static inline void __nf_ct_set_timeout(struct nf_conn *ct, u64 timeout)
+ {
+ if (timeout > INT_MAX)
+ timeout = INT_MAX;
+- WRITE_ONCE(ct->timeout, nfct_time_stamp + (u32)timeout);
++
++ if (nf_ct_is_confirmed(ct))
++ WRITE_ONCE(ct->timeout, nfct_time_stamp + (u32)timeout);
++ else
++ ct->timeout = (u32)timeout;
+ }
+
+ int __nf_ct_change_timeout(struct nf_conn *ct, u64 cta_timeout);
+diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
+index 1b8e305bb54ae..9dace9bcba8e5 100644
+--- a/include/net/netfilter/nf_tables.h
++++ b/include/net/netfilter/nf_tables.h
+@@ -619,6 +619,7 @@ struct nft_set_binding {
+ };
+
+ enum nft_trans_phase;
++void nf_tables_activate_set(const struct nft_ctx *ctx, struct nft_set *set);
+ void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set,
+ struct nft_set_binding *binding,
+ enum nft_trans_phase phase);
+diff --git a/include/net/scm.h b/include/net/scm.h
+index 1ce365f4c2560..585adc1346bd0 100644
+--- a/include/net/scm.h
++++ b/include/net/scm.h
+@@ -105,16 +105,27 @@ static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct sc
+ }
+ }
+ }
++
++static inline bool scm_has_secdata(struct socket *sock)
++{
++ return test_bit(SOCK_PASSSEC, &sock->flags);
++}
+ #else
+ static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
+ { }
++
++static inline bool scm_has_secdata(struct socket *sock)
++{
++ return false;
++}
+ #endif /* CONFIG_SECURITY_NETWORK */
+
+ static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
+ struct scm_cookie *scm, int flags)
+ {
+ if (!msg->msg_control) {
+- if (test_bit(SOCK_PASSCRED, &sock->flags) || scm->fp)
++ if (test_bit(SOCK_PASSCRED, &sock->flags) || scm->fp ||
++ scm_has_secdata(sock))
+ msg->msg_flags |= MSG_CTRUNC;
+ scm_destroy(scm);
+ return;
+diff --git a/include/net/xsk_buff_pool.h b/include/net/xsk_buff_pool.h
+index f787c3f524b03..996eaf1ef1a1d 100644
+--- a/include/net/xsk_buff_pool.h
++++ b/include/net/xsk_buff_pool.h
+@@ -175,13 +175,8 @@ static inline bool xp_desc_crosses_non_contig_pg(struct xsk_buff_pool *pool,
+ if (likely(!cross_pg))
+ return false;
+
+- if (pool->dma_pages_cnt) {
+- return !(pool->dma_pages[addr >> PAGE_SHIFT] &
+- XSK_NEXT_PG_CONTIG_MASK);
+- }
+-
+- /* skb path */
+- return addr + len > pool->addrs_cnt;
++ return pool->dma_pages_cnt &&
++ !(pool->dma_pages[addr >> PAGE_SHIFT] & XSK_NEXT_PG_CONTIG_MASK);
+ }
+
+ static inline u64 xp_aligned_extract_addr(struct xsk_buff_pool *pool, u64 addr)
+diff --git a/include/target/iscsi/iscsi_target_core.h b/include/target/iscsi/iscsi_target_core.h
+index 94d06ddfd80ad..229118156a1f6 100644
+--- a/include/target/iscsi/iscsi_target_core.h
++++ b/include/target/iscsi/iscsi_target_core.h
+@@ -600,6 +600,7 @@ struct iscsit_conn {
+ struct iscsi_tpg_np *tpg_np;
+ /* Pointer to parent session */
+ struct iscsit_session *sess;
++ struct target_cmd_counter *cmd_cnt;
+ int bitmap_id;
+ int rx_thread_active;
+ struct task_struct *rx_thread;
+diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
+index 12c9ba16217ef..8cc42ad65c925 100644
+--- a/include/target/target_core_base.h
++++ b/include/target/target_core_base.h
+@@ -494,6 +494,7 @@ struct se_cmd {
+ struct se_lun *se_lun;
+ /* Only used for internal passthrough and legacy TCM fabric modules */
+ struct se_session *se_sess;
++ struct target_cmd_counter *cmd_cnt;
+ struct se_tmr_req *se_tmr_req;
+ struct llist_node se_cmd_list;
+ struct completion *free_compl;
+@@ -619,22 +620,26 @@ static inline struct se_node_acl *fabric_stat_to_nacl(struct config_item *item)
+ acl_fabric_stat_group);
+ }
+
+-struct se_session {
++struct target_cmd_counter {
++ struct percpu_ref refcnt;
++ wait_queue_head_t refcnt_wq;
++ struct completion stop_done;
+ atomic_t stopped;
++};
++
++struct se_session {
+ u64 sess_bin_isid;
+ enum target_prot_op sup_prot_ops;
+ enum target_prot_type sess_prot_type;
+ struct se_node_acl *se_node_acl;
+ struct se_portal_group *se_tpg;
+ void *fabric_sess_ptr;
+- struct percpu_ref cmd_count;
+ struct list_head sess_list;
+ struct list_head sess_acl_list;
+ spinlock_t sess_cmd_lock;
+- wait_queue_head_t cmd_count_wq;
+- struct completion stop_done;
+ void *sess_cmd_map;
+ struct sbitmap_queue sess_tag_pool;
++ struct target_cmd_counter *cmd_cnt;
+ };
+
+ struct se_device;
+@@ -867,6 +872,7 @@ struct se_device {
+ struct rcu_head rcu_head;
+ int queue_cnt;
+ struct se_device_queue *queues;
++ struct mutex lun_reset_mutex;
+ };
+
+ struct target_opcode_descriptor {
+diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h
+index 38f0662476d14..b188b1e90e1ed 100644
+--- a/include/target/target_core_fabric.h
++++ b/include/target/target_core_fabric.h
+@@ -133,7 +133,12 @@ struct se_session *target_setup_session(struct se_portal_group *,
+ struct se_session *, void *));
+ void target_remove_session(struct se_session *);
+
+-int transport_init_session(struct se_session *se_sess);
++void target_stop_cmd_counter(struct target_cmd_counter *cmd_cnt);
++void target_wait_for_cmds(struct target_cmd_counter *cmd_cnt);
++struct target_cmd_counter *target_alloc_cmd_counter(void);
++void target_free_cmd_counter(struct target_cmd_counter *cmd_cnt);
++
++void transport_init_session(struct se_session *se_sess);
+ struct se_session *transport_alloc_session(enum target_prot_op);
+ int transport_alloc_session_tags(struct se_session *, unsigned int,
+ unsigned int);
+@@ -149,9 +154,11 @@ void transport_deregister_session_configfs(struct se_session *);
+ void transport_deregister_session(struct se_session *);
+
+
+-void __target_init_cmd(struct se_cmd *,
+- const struct target_core_fabric_ops *,
+- struct se_session *, u32, int, int, unsigned char *, u64);
++void __target_init_cmd(struct se_cmd *cmd,
++ const struct target_core_fabric_ops *tfo,
++ struct se_session *sess, u32 data_length, int data_direction,
++ int task_attr, unsigned char *sense_buffer, u64 unpacked_lun,
++ struct target_cmd_counter *cmd_cnt);
+ int target_init_cmd(struct se_cmd *se_cmd, struct se_session *se_sess,
+ unsigned char *sense, u64 unpacked_lun, u32 data_length,
+ int task_attr, int data_dir, int flags);
+diff --git a/include/trace/events/qrtr.h b/include/trace/events/qrtr.h
+index b1de14c3bb934..441132c67133f 100644
+--- a/include/trace/events/qrtr.h
++++ b/include/trace/events/qrtr.h
+@@ -10,15 +10,16 @@
+
+ TRACE_EVENT(qrtr_ns_service_announce_new,
+
+- TP_PROTO(__le32 service, __le32 instance, __le32 node, __le32 port),
++ TP_PROTO(unsigned int service, unsigned int instance,
++ unsigned int node, unsigned int port),
+
+ TP_ARGS(service, instance, node, port),
+
+ TP_STRUCT__entry(
+- __field(__le32, service)
+- __field(__le32, instance)
+- __field(__le32, node)
+- __field(__le32, port)
++ __field(unsigned int, service)
++ __field(unsigned int, instance)
++ __field(unsigned int, node)
++ __field(unsigned int, port)
+ ),
+
+ TP_fast_assign(
+@@ -36,15 +37,16 @@ TRACE_EVENT(qrtr_ns_service_announce_new,
+
+ TRACE_EVENT(qrtr_ns_service_announce_del,
+
+- TP_PROTO(__le32 service, __le32 instance, __le32 node, __le32 port),
++ TP_PROTO(unsigned int service, unsigned int instance,
++ unsigned int node, unsigned int port),
+
+ TP_ARGS(service, instance, node, port),
+
+ TP_STRUCT__entry(
+- __field(__le32, service)
+- __field(__le32, instance)
+- __field(__le32, node)
+- __field(__le32, port)
++ __field(unsigned int, service)
++ __field(unsigned int, instance)
++ __field(unsigned int, node)
++ __field(unsigned int, port)
+ ),
+
+ TP_fast_assign(
+@@ -62,15 +64,16 @@ TRACE_EVENT(qrtr_ns_service_announce_del,
+
+ TRACE_EVENT(qrtr_ns_server_add,
+
+- TP_PROTO(__le32 service, __le32 instance, __le32 node, __le32 port),
++ TP_PROTO(unsigned int service, unsigned int instance,
++ unsigned int node, unsigned int port),
+
+ TP_ARGS(service, instance, node, port),
+
+ TP_STRUCT__entry(
+- __field(__le32, service)
+- __field(__le32, instance)
+- __field(__le32, node)
+- __field(__le32, port)
++ __field(unsigned int, service)
++ __field(unsigned int, instance)
++ __field(unsigned int, node)
++ __field(unsigned int, port)
+ ),
+
+ TP_fast_assign(
+diff --git a/include/trace/events/timer.h b/include/trace/events/timer.h
+index 2e713a7d9aa3a..3e8619c72f774 100644
+--- a/include/trace/events/timer.h
++++ b/include/trace/events/timer.h
+@@ -371,7 +371,8 @@ TRACE_EVENT(itimer_expire,
+ tick_dep_name(PERF_EVENTS) \
+ tick_dep_name(SCHED) \
+ tick_dep_name(CLOCK_UNSTABLE) \
+- tick_dep_name_end(RCU)
++ tick_dep_name(RCU) \
++ tick_dep_name_end(RCU_EXP)
+
+ #undef tick_dep_name
+ #undef tick_dep_mask_name
+diff --git a/include/trace/stages/stage5_get_offsets.h b/include/trace/stages/stage5_get_offsets.h
+index ac5c24d3beeb2..e30a13be46ba5 100644
+--- a/include/trace/stages/stage5_get_offsets.h
++++ b/include/trace/stages/stage5_get_offsets.h
+@@ -9,17 +9,30 @@
+ #undef __entry
+ #define __entry entry
+
++/*
++ * Fields should never declare an array: i.e. __field(int, arr[5])
++ * If they do, it will cause issues in parsing and possibly corrupt the
++ * events. To prevent that from happening, test the sizeof() a fictitious
++ * type called "struct _test_no_array_##item" which will fail if "item"
++ * contains array elements (like "arr[5]").
++ *
++ * If you hit this, use __array(int, arr, 5) instead.
++ */
+ #undef __field
+-#define __field(type, item)
++#define __field(type, item) \
++ { (void)sizeof(struct _test_no_array_##item *); }
+
+ #undef __field_ext
+-#define __field_ext(type, item, filter_type)
++#define __field_ext(type, item, filter_type) \
++ { (void)sizeof(struct _test_no_array_##item *); }
+
+ #undef __field_struct
+-#define __field_struct(type, item)
++#define __field_struct(type, item) \
++ { (void)sizeof(struct _test_no_array_##item *); }
+
+ #undef __field_struct_ext
+-#define __field_struct_ext(type, item, filter_type)
++#define __field_struct_ext(type, item, filter_type) \
++ { (void)sizeof(struct _test_no_array_##item *); }
+
+ #undef __array
+ #define __array(type, item, len)
+diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
+index 464ca3f01fe7a..bd260134c4201 100644
+--- a/include/uapi/linux/bpf.h
++++ b/include/uapi/linux/bpf.h
+@@ -6901,6 +6901,17 @@ struct bpf_list_node {
+ __u64 :64;
+ } __attribute__((aligned(8)));
+
++struct bpf_rb_root {
++ __u64 :64;
++ __u64 :64;
++} __attribute__((aligned(8)));
++
++struct bpf_rb_node {
++ __u64 :64;
++ __u64 :64;
++ __u64 :64;
++} __attribute__((aligned(8)));
++
+ struct bpf_sysctl {
+ __u32 write; /* Sysctl is being read (= 0) or written (= 1).
+ * Allows 1,2,4-byte read, but no write.
+diff --git a/include/uapi/linux/btrfs.h b/include/uapi/linux/btrfs.h
+index b4f0f9531119f..5864d2d9b79a3 100644
+--- a/include/uapi/linux/btrfs.h
++++ b/include/uapi/linux/btrfs.h
+@@ -187,6 +187,7 @@ struct btrfs_scrub_progress {
+ };
+
+ #define BTRFS_SCRUB_READONLY 1
++#define BTRFS_SCRUB_SUPPORTED_FLAGS (BTRFS_SCRUB_READONLY)
+ struct btrfs_ioctl_scrub_args {
+ __u64 devid; /* in */
+ __u64 start; /* in */
+diff --git a/include/uapi/linux/const.h b/include/uapi/linux/const.h
+index af2a44c08683d..a429381e7ca50 100644
+--- a/include/uapi/linux/const.h
++++ b/include/uapi/linux/const.h
+@@ -28,7 +28,7 @@
+ #define _BITUL(x) (_UL(1) << (x))
+ #define _BITULL(x) (_ULL(1) << (x))
+
+-#define __ALIGN_KERNEL(x, a) __ALIGN_KERNEL_MASK(x, (typeof(x))(a) - 1)
++#define __ALIGN_KERNEL(x, a) __ALIGN_KERNEL_MASK(x, (__typeof__(x))(a) - 1)
+ #define __ALIGN_KERNEL_MASK(x, mask) (((x) + (mask)) & ~(mask))
+
+ #define __KERNEL_DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
+diff --git a/include/xen/xen.h b/include/xen/xen.h
+index 7adf59837c258..0efeb652f9b8f 100644
+--- a/include/xen/xen.h
++++ b/include/xen/xen.h
+@@ -71,4 +71,15 @@ static inline void xen_free_unpopulated_pages(unsigned int nr_pages,
+ }
+ #endif
+
++#if defined(CONFIG_XEN_DOM0) && defined(CONFIG_ACPI) && defined(CONFIG_X86)
++bool __init xen_processor_present(uint32_t acpi_id);
++#else
++#include <linux/bug.h>
++static inline bool xen_processor_present(uint32_t acpi_id)
++{
++ BUG();
++ return false;
++}
++#endif
++
+ #endif /* _XEN_XEN_H */
+diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c
+index 4ccfc29216269..e100f040371b5 100644
+--- a/io_uring/rsrc.c
++++ b/io_uring/rsrc.c
+@@ -577,7 +577,7 @@ static int __io_sqe_buffers_update(struct io_ring_ctx *ctx,
+ }
+
+ ctx->user_bufs[i] = imu;
+- *io_get_tag_slot(ctx->buf_data, offset) = tag;
++ *io_get_tag_slot(ctx->buf_data, i) = tag;
+ }
+
+ if (needs_switch)
+diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c
+index 4847069595569..cb80bcc880b44 100644
+--- a/kernel/bpf/arraymap.c
++++ b/kernel/bpf/arraymap.c
+@@ -307,8 +307,8 @@ static int array_map_get_next_key(struct bpf_map *map, void *key, void *next_key
+ }
+
+ /* Called from syscall or from eBPF program */
+-static int array_map_update_elem(struct bpf_map *map, void *key, void *value,
+- u64 map_flags)
++static long array_map_update_elem(struct bpf_map *map, void *key, void *value,
++ u64 map_flags)
+ {
+ struct bpf_array *array = container_of(map, struct bpf_array, map);
+ u32 index = *(u32 *)key;
+@@ -386,7 +386,7 @@ int bpf_percpu_array_update(struct bpf_map *map, void *key, void *value,
+ }
+
+ /* Called from syscall or from eBPF program */
+-static int array_map_delete_elem(struct bpf_map *map, void *key)
++static long array_map_delete_elem(struct bpf_map *map, void *key)
+ {
+ return -EINVAL;
+ }
+@@ -686,8 +686,8 @@ static const struct bpf_iter_seq_info iter_seq_info = {
+ .seq_priv_size = sizeof(struct bpf_iter_seq_array_map_info),
+ };
+
+-static int bpf_for_each_array_elem(struct bpf_map *map, bpf_callback_t callback_fn,
+- void *callback_ctx, u64 flags)
++static long bpf_for_each_array_elem(struct bpf_map *map, bpf_callback_t callback_fn,
++ void *callback_ctx, u64 flags)
+ {
+ u32 i, key, num_elems = 0;
+ struct bpf_array *array;
+@@ -847,7 +847,7 @@ int bpf_fd_array_map_update_elem(struct bpf_map *map, struct file *map_file,
+ return 0;
+ }
+
+-static int fd_array_map_delete_elem(struct bpf_map *map, void *key)
++static long fd_array_map_delete_elem(struct bpf_map *map, void *key)
+ {
+ struct bpf_array *array = container_of(map, struct bpf_array, map);
+ void *old_ptr;
+diff --git a/kernel/bpf/bloom_filter.c b/kernel/bpf/bloom_filter.c
+index 48ee750849f25..b386a8fdf28cc 100644
+--- a/kernel/bpf/bloom_filter.c
++++ b/kernel/bpf/bloom_filter.c
+@@ -41,7 +41,7 @@ static u32 hash(struct bpf_bloom_filter *bloom, void *value,
+ return h & bloom->bitset_mask;
+ }
+
+-static int bloom_map_peek_elem(struct bpf_map *map, void *value)
++static long bloom_map_peek_elem(struct bpf_map *map, void *value)
+ {
+ struct bpf_bloom_filter *bloom =
+ container_of(map, struct bpf_bloom_filter, map);
+@@ -56,7 +56,7 @@ static int bloom_map_peek_elem(struct bpf_map *map, void *value)
+ return 0;
+ }
+
+-static int bloom_map_push_elem(struct bpf_map *map, void *value, u64 flags)
++static long bloom_map_push_elem(struct bpf_map *map, void *value, u64 flags)
+ {
+ struct bpf_bloom_filter *bloom =
+ container_of(map, struct bpf_bloom_filter, map);
+@@ -73,12 +73,12 @@ static int bloom_map_push_elem(struct bpf_map *map, void *value, u64 flags)
+ return 0;
+ }
+
+-static int bloom_map_pop_elem(struct bpf_map *map, void *value)
++static long bloom_map_pop_elem(struct bpf_map *map, void *value)
+ {
+ return -EOPNOTSUPP;
+ }
+
+-static int bloom_map_delete_elem(struct bpf_map *map, void *value)
++static long bloom_map_delete_elem(struct bpf_map *map, void *value)
+ {
+ return -EOPNOTSUPP;
+ }
+@@ -177,8 +177,8 @@ static void *bloom_map_lookup_elem(struct bpf_map *map, void *key)
+ return ERR_PTR(-EINVAL);
+ }
+
+-static int bloom_map_update_elem(struct bpf_map *map, void *key,
+- void *value, u64 flags)
++static long bloom_map_update_elem(struct bpf_map *map, void *key,
++ void *value, u64 flags)
+ {
+ /* The eBPF program should use map_push_elem instead */
+ return -EINVAL;
+diff --git a/kernel/bpf/bpf_cgrp_storage.c b/kernel/bpf/bpf_cgrp_storage.c
+index 6cdf6d9ed91df..d4a074247b64d 100644
+--- a/kernel/bpf/bpf_cgrp_storage.c
++++ b/kernel/bpf/bpf_cgrp_storage.c
+@@ -100,8 +100,8 @@ static void *bpf_cgrp_storage_lookup_elem(struct bpf_map *map, void *key)
+ return sdata ? sdata->data : NULL;
+ }
+
+-static int bpf_cgrp_storage_update_elem(struct bpf_map *map, void *key,
+- void *value, u64 map_flags)
++static long bpf_cgrp_storage_update_elem(struct bpf_map *map, void *key,
++ void *value, u64 map_flags)
+ {
+ struct bpf_local_storage_data *sdata;
+ struct cgroup *cgroup;
+@@ -132,7 +132,7 @@ static int cgroup_storage_delete(struct cgroup *cgroup, struct bpf_map *map)
+ return 0;
+ }
+
+-static int bpf_cgrp_storage_delete_elem(struct bpf_map *map, void *key)
++static long bpf_cgrp_storage_delete_elem(struct bpf_map *map, void *key)
+ {
+ struct cgroup *cgroup;
+ int err, fd;
+diff --git a/kernel/bpf/bpf_inode_storage.c b/kernel/bpf/bpf_inode_storage.c
+index 05f4c66c9089f..a8afc656808b2 100644
+--- a/kernel/bpf/bpf_inode_storage.c
++++ b/kernel/bpf/bpf_inode_storage.c
+@@ -97,8 +97,8 @@ static void *bpf_fd_inode_storage_lookup_elem(struct bpf_map *map, void *key)
+ return sdata ? sdata->data : NULL;
+ }
+
+-static int bpf_fd_inode_storage_update_elem(struct bpf_map *map, void *key,
+- void *value, u64 map_flags)
++static long bpf_fd_inode_storage_update_elem(struct bpf_map *map, void *key,
++ void *value, u64 map_flags)
+ {
+ struct bpf_local_storage_data *sdata;
+ struct file *f;
+@@ -133,7 +133,7 @@ static int inode_storage_delete(struct inode *inode, struct bpf_map *map)
+ return 0;
+ }
+
+-static int bpf_fd_inode_storage_delete_elem(struct bpf_map *map, void *key)
++static long bpf_fd_inode_storage_delete_elem(struct bpf_map *map, void *key)
+ {
+ struct file *f;
+ int fd, err;
+diff --git a/kernel/bpf/bpf_struct_ops.c b/kernel/bpf/bpf_struct_ops.c
+index ece9870cab68e..36c17271d38bd 100644
+--- a/kernel/bpf/bpf_struct_ops.c
++++ b/kernel/bpf/bpf_struct_ops.c
+@@ -349,8 +349,8 @@ int bpf_struct_ops_prepare_trampoline(struct bpf_tramp_links *tlinks,
+ model, flags, tlinks, NULL);
+ }
+
+-static int bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key,
+- void *value, u64 flags)
++static long bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key,
++ void *value, u64 flags)
+ {
+ struct bpf_struct_ops_map *st_map = (struct bpf_struct_ops_map *)map;
+ const struct bpf_struct_ops *st_ops = st_map->st_ops;
+@@ -524,7 +524,7 @@ unlock:
+ return err;
+ }
+
+-static int bpf_struct_ops_map_delete_elem(struct bpf_map *map, void *key)
++static long bpf_struct_ops_map_delete_elem(struct bpf_map *map, void *key)
+ {
+ enum bpf_struct_ops_state prev_state;
+ struct bpf_struct_ops_map *st_map;
+diff --git a/kernel/bpf/bpf_task_storage.c b/kernel/bpf/bpf_task_storage.c
+index 1e486055a523d..b29f0bf28fd15 100644
+--- a/kernel/bpf/bpf_task_storage.c
++++ b/kernel/bpf/bpf_task_storage.c
+@@ -127,8 +127,8 @@ out:
+ return ERR_PTR(err);
+ }
+
+-static int bpf_pid_task_storage_update_elem(struct bpf_map *map, void *key,
+- void *value, u64 map_flags)
++static long bpf_pid_task_storage_update_elem(struct bpf_map *map, void *key,
++ void *value, u64 map_flags)
+ {
+ struct bpf_local_storage_data *sdata;
+ struct task_struct *task;
+@@ -180,7 +180,7 @@ static int task_storage_delete(struct task_struct *task, struct bpf_map *map,
+ return 0;
+ }
+
+-static int bpf_pid_task_storage_delete_elem(struct bpf_map *map, void *key)
++static long bpf_pid_task_storage_delete_elem(struct bpf_map *map, void *key)
+ {
+ struct task_struct *task;
+ unsigned int f_flags;
+diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
+index 9880faa7e6760..6f3326417f27e 100644
+--- a/kernel/bpf/btf.c
++++ b/kernel/bpf/btf.c
+@@ -566,8 +566,8 @@ static s32 bpf_find_btf_id(const char *name, u32 kind, struct btf **btf_p)
+ *btf_p = btf;
+ return ret;
+ }
+- spin_lock_bh(&btf_idr_lock);
+ btf_put(btf);
++ spin_lock_bh(&btf_idr_lock);
+ }
+ spin_unlock_bh(&btf_idr_lock);
+ return ret;
+@@ -3228,7 +3228,7 @@ struct btf_field_info {
+ struct {
+ const char *node_name;
+ u32 value_btf_id;
+- } list_head;
++ } graph_root;
+ };
+ };
+
+@@ -3305,12 +3305,14 @@ static const char *btf_find_decl_tag_value(const struct btf *btf,
+ return NULL;
+ }
+
+-static int btf_find_list_head(const struct btf *btf, const struct btf_type *pt,
+- const struct btf_type *t, int comp_idx,
+- u32 off, int sz, struct btf_field_info *info)
++static int
++btf_find_graph_root(const struct btf *btf, const struct btf_type *pt,
++ const struct btf_type *t, int comp_idx, u32 off,
++ int sz, struct btf_field_info *info,
++ enum btf_field_type head_type)
+ {
++ const char *node_field_name;
+ const char *value_type;
+- const char *list_node;
+ s32 id;
+
+ if (!__btf_type_is_struct(t))
+@@ -3320,26 +3322,32 @@ static int btf_find_list_head(const struct btf *btf, const struct btf_type *pt,
+ value_type = btf_find_decl_tag_value(btf, pt, comp_idx, "contains:");
+ if (!value_type)
+ return -EINVAL;
+- list_node = strstr(value_type, ":");
+- if (!list_node)
++ node_field_name = strstr(value_type, ":");
++ if (!node_field_name)
+ return -EINVAL;
+- value_type = kstrndup(value_type, list_node - value_type, GFP_KERNEL | __GFP_NOWARN);
++ value_type = kstrndup(value_type, node_field_name - value_type, GFP_KERNEL | __GFP_NOWARN);
+ if (!value_type)
+ return -ENOMEM;
+ id = btf_find_by_name_kind(btf, value_type, BTF_KIND_STRUCT);
+ kfree(value_type);
+ if (id < 0)
+ return id;
+- list_node++;
+- if (str_is_empty(list_node))
++ node_field_name++;
++ if (str_is_empty(node_field_name))
+ return -EINVAL;
+- info->type = BPF_LIST_HEAD;
++ info->type = head_type;
+ info->off = off;
+- info->list_head.value_btf_id = id;
+- info->list_head.node_name = list_node;
++ info->graph_root.value_btf_id = id;
++ info->graph_root.node_name = node_field_name;
+ return BTF_FIELD_FOUND;
+ }
+
++#define field_mask_test_name(field_type, field_type_str) \
++ if (field_mask & field_type && !strcmp(name, field_type_str)) { \
++ type = field_type; \
++ goto end; \
++ }
++
+ static int btf_get_field_type(const char *name, u32 field_mask, u32 *seen_mask,
+ int *align, int *sz)
+ {
+@@ -3363,18 +3371,11 @@ static int btf_get_field_type(const char *name, u32 field_mask, u32 *seen_mask,
+ goto end;
+ }
+ }
+- if (field_mask & BPF_LIST_HEAD) {
+- if (!strcmp(name, "bpf_list_head")) {
+- type = BPF_LIST_HEAD;
+- goto end;
+- }
+- }
+- if (field_mask & BPF_LIST_NODE) {
+- if (!strcmp(name, "bpf_list_node")) {
+- type = BPF_LIST_NODE;
+- goto end;
+- }
+- }
++ field_mask_test_name(BPF_LIST_HEAD, "bpf_list_head");
++ field_mask_test_name(BPF_LIST_NODE, "bpf_list_node");
++ field_mask_test_name(BPF_RB_ROOT, "bpf_rb_root");
++ field_mask_test_name(BPF_RB_NODE, "bpf_rb_node");
++
+ /* Only return BPF_KPTR when all other types with matchable names fail */
+ if (field_mask & BPF_KPTR) {
+ type = BPF_KPTR_REF;
+@@ -3387,6 +3388,8 @@ end:
+ return type;
+ }
+
++#undef field_mask_test_name
++
+ static int btf_find_struct_field(const struct btf *btf,
+ const struct btf_type *t, u32 field_mask,
+ struct btf_field_info *info, int info_cnt)
+@@ -3419,6 +3422,7 @@ static int btf_find_struct_field(const struct btf *btf,
+ case BPF_SPIN_LOCK:
+ case BPF_TIMER:
+ case BPF_LIST_NODE:
++ case BPF_RB_NODE:
+ ret = btf_find_struct(btf, member_type, off, sz, field_type,
+ idx < info_cnt ? &info[idx] : &tmp);
+ if (ret < 0)
+@@ -3432,8 +3436,11 @@ static int btf_find_struct_field(const struct btf *btf,
+ return ret;
+ break;
+ case BPF_LIST_HEAD:
+- ret = btf_find_list_head(btf, t, member_type, i, off, sz,
+- idx < info_cnt ? &info[idx] : &tmp);
++ case BPF_RB_ROOT:
++ ret = btf_find_graph_root(btf, t, member_type,
++ i, off, sz,
++ idx < info_cnt ? &info[idx] : &tmp,
++ field_type);
+ if (ret < 0)
+ return ret;
+ break;
+@@ -3480,6 +3487,7 @@ static int btf_find_datasec_var(const struct btf *btf, const struct btf_type *t,
+ case BPF_SPIN_LOCK:
+ case BPF_TIMER:
+ case BPF_LIST_NODE:
++ case BPF_RB_NODE:
+ ret = btf_find_struct(btf, var_type, off, sz, field_type,
+ idx < info_cnt ? &info[idx] : &tmp);
+ if (ret < 0)
+@@ -3493,8 +3501,11 @@ static int btf_find_datasec_var(const struct btf *btf, const struct btf_type *t,
+ return ret;
+ break;
+ case BPF_LIST_HEAD:
+- ret = btf_find_list_head(btf, var, var_type, -1, off, sz,
+- idx < info_cnt ? &info[idx] : &tmp);
++ case BPF_RB_ROOT:
++ ret = btf_find_graph_root(btf, var, var_type,
++ -1, off, sz,
++ idx < info_cnt ? &info[idx] : &tmp,
++ field_type);
+ if (ret < 0)
+ return ret;
+ break;
+@@ -3596,21 +3607,25 @@ end_btf:
+ return ret;
+ }
+
+-static int btf_parse_list_head(const struct btf *btf, struct btf_field *field,
+- struct btf_field_info *info)
++static int btf_parse_graph_root(const struct btf *btf,
++ struct btf_field *field,
++ struct btf_field_info *info,
++ const char *node_type_name,
++ size_t node_type_align)
+ {
+ const struct btf_type *t, *n = NULL;
+ const struct btf_member *member;
+ u32 offset;
+ int i;
+
+- t = btf_type_by_id(btf, info->list_head.value_btf_id);
++ t = btf_type_by_id(btf, info->graph_root.value_btf_id);
+ /* We've already checked that value_btf_id is a struct type. We
+ * just need to figure out the offset of the list_node, and
+ * verify its type.
+ */
+ for_each_member(i, t, member) {
+- if (strcmp(info->list_head.node_name, __btf_name_by_offset(btf, member->name_off)))
++ if (strcmp(info->graph_root.node_name,
++ __btf_name_by_offset(btf, member->name_off)))
+ continue;
+ /* Invalid BTF, two members with same name */
+ if (n)
+@@ -3618,24 +3633,38 @@ static int btf_parse_list_head(const struct btf *btf, struct btf_field *field,
+ n = btf_type_by_id(btf, member->type);
+ if (!__btf_type_is_struct(n))
+ return -EINVAL;
+- if (strcmp("bpf_list_node", __btf_name_by_offset(btf, n->name_off)))
++ if (strcmp(node_type_name, __btf_name_by_offset(btf, n->name_off)))
+ return -EINVAL;
+ offset = __btf_member_bit_offset(n, member);
+ if (offset % 8)
+ return -EINVAL;
+ offset /= 8;
+- if (offset % __alignof__(struct bpf_list_node))
++ if (offset % node_type_align)
+ return -EINVAL;
+
+- field->list_head.btf = (struct btf *)btf;
+- field->list_head.value_btf_id = info->list_head.value_btf_id;
+- field->list_head.node_offset = offset;
++ field->graph_root.btf = (struct btf *)btf;
++ field->graph_root.value_btf_id = info->graph_root.value_btf_id;
++ field->graph_root.node_offset = offset;
+ }
+ if (!n)
+ return -ENOENT;
+ return 0;
+ }
+
++static int btf_parse_list_head(const struct btf *btf, struct btf_field *field,
++ struct btf_field_info *info)
++{
++ return btf_parse_graph_root(btf, field, info, "bpf_list_node",
++ __alignof__(struct bpf_list_node));
++}
++
++static int btf_parse_rb_root(const struct btf *btf, struct btf_field *field,
++ struct btf_field_info *info)
++{
++ return btf_parse_graph_root(btf, field, info, "bpf_rb_node",
++ __alignof__(struct bpf_rb_node));
++}
++
+ struct btf_record *btf_parse_fields(const struct btf *btf, const struct btf_type *t,
+ u32 field_mask, u32 value_size)
+ {
+@@ -3698,7 +3727,13 @@ struct btf_record *btf_parse_fields(const struct btf *btf, const struct btf_type
+ if (ret < 0)
+ goto end;
+ break;
++ case BPF_RB_ROOT:
++ ret = btf_parse_rb_root(btf, &rec->fields[i], &info_arr[i]);
++ if (ret < 0)
++ goto end;
++ break;
+ case BPF_LIST_NODE:
++ case BPF_RB_NODE:
+ break;
+ default:
+ ret = -EFAULT;
+@@ -3707,8 +3742,9 @@ struct btf_record *btf_parse_fields(const struct btf *btf, const struct btf_type
+ rec->cnt++;
+ }
+
+- /* bpf_list_head requires bpf_spin_lock */
+- if (btf_record_has_field(rec, BPF_LIST_HEAD) && rec->spin_lock_off < 0) {
++ /* bpf_{list_head, rb_node} require bpf_spin_lock */
++ if ((btf_record_has_field(rec, BPF_LIST_HEAD) ||
++ btf_record_has_field(rec, BPF_RB_ROOT)) && rec->spin_lock_off < 0) {
+ ret = -EINVAL;
+ goto end;
+ }
+@@ -3719,62 +3755,76 @@ end:
+ return ERR_PTR(ret);
+ }
+
++#define GRAPH_ROOT_MASK (BPF_LIST_HEAD | BPF_RB_ROOT)
++#define GRAPH_NODE_MASK (BPF_LIST_NODE | BPF_RB_NODE)
++
+ int btf_check_and_fixup_fields(const struct btf *btf, struct btf_record *rec)
+ {
+ int i;
+
+- /* There are two owning types, kptr_ref and bpf_list_head. The former
+- * only supports storing kernel types, which can never store references
+- * to program allocated local types, atleast not yet. Hence we only need
+- * to ensure that bpf_list_head ownership does not form cycles.
++ /* There are three types that signify ownership of some other type:
++ * kptr_ref, bpf_list_head, bpf_rb_root.
++ * kptr_ref only supports storing kernel types, which can't store
++ * references to program allocated local types.
++ *
++ * Hence we only need to ensure that bpf_{list_head,rb_root} ownership
++ * does not form cycles.
+ */
+- if (IS_ERR_OR_NULL(rec) || !(rec->field_mask & BPF_LIST_HEAD))
++ if (IS_ERR_OR_NULL(rec) || !(rec->field_mask & GRAPH_ROOT_MASK))
+ return 0;
+ for (i = 0; i < rec->cnt; i++) {
+ struct btf_struct_meta *meta;
+ u32 btf_id;
+
+- if (!(rec->fields[i].type & BPF_LIST_HEAD))
++ if (!(rec->fields[i].type & GRAPH_ROOT_MASK))
+ continue;
+- btf_id = rec->fields[i].list_head.value_btf_id;
++ btf_id = rec->fields[i].graph_root.value_btf_id;
+ meta = btf_find_struct_meta(btf, btf_id);
+ if (!meta)
+ return -EFAULT;
+- rec->fields[i].list_head.value_rec = meta->record;
++ rec->fields[i].graph_root.value_rec = meta->record;
+
+- if (!(rec->field_mask & BPF_LIST_NODE))
++ /* We need to set value_rec for all root types, but no need
++ * to check ownership cycle for a type unless it's also a
++ * node type.
++ */
++ if (!(rec->field_mask & GRAPH_NODE_MASK))
+ continue;
+
+ /* We need to ensure ownership acyclicity among all types. The
+ * proper way to do it would be to topologically sort all BTF
+ * IDs based on the ownership edges, since there can be multiple
+- * bpf_list_head in a type. Instead, we use the following
+- * reasoning:
++ * bpf_{list_head,rb_node} in a type. Instead, we use the
++ * following resaoning:
+ *
+ * - A type can only be owned by another type in user BTF if it
+- * has a bpf_list_node.
++ * has a bpf_{list,rb}_node. Let's call these node types.
+ * - A type can only _own_ another type in user BTF if it has a
+- * bpf_list_head.
++ * bpf_{list_head,rb_root}. Let's call these root types.
+ *
+- * We ensure that if a type has both bpf_list_head and
+- * bpf_list_node, its element types cannot be owning types.
++ * We ensure that if a type is both a root and node, its
++ * element types cannot be root types.
+ *
+ * To ensure acyclicity:
+ *
+- * When A only has bpf_list_head, ownership chain can be:
++ * When A is an root type but not a node, its ownership
++ * chain can be:
+ * A -> B -> C
+ * Where:
+- * - B has both bpf_list_head and bpf_list_node.
+- * - C only has bpf_list_node.
++ * - A is an root, e.g. has bpf_rb_root.
++ * - B is both a root and node, e.g. has bpf_rb_node and
++ * bpf_list_head.
++ * - C is only an root, e.g. has bpf_list_node
+ *
+- * When A has both bpf_list_head and bpf_list_node, some other
+- * type already owns it in the BTF domain, hence it can not own
+- * another owning type through any of the bpf_list_head edges.
++ * When A is both a root and node, some other type already
++ * owns it in the BTF domain, hence it can not own
++ * another root type through any of the ownership edges.
+ * A -> B
+ * Where:
+- * - B only has bpf_list_node.
++ * - A is both an root and node.
++ * - B is only an node.
+ */
+- if (meta->record->field_mask & BPF_LIST_HEAD)
++ if (meta->record->field_mask & GRAPH_ROOT_MASK)
+ return -ELOOP;
+ }
+ return 0;
+@@ -5237,6 +5287,8 @@ static const char *alloc_obj_fields[] = {
+ "bpf_spin_lock",
+ "bpf_list_head",
+ "bpf_list_node",
++ "bpf_rb_root",
++ "bpf_rb_node",
+ };
+
+ static struct btf_struct_metas *
+@@ -5310,7 +5362,8 @@ btf_parse_struct_metas(struct bpf_verifier_log *log, struct btf *btf)
+
+ type = &tab->types[tab->cnt];
+ type->btf_id = i;
+- record = btf_parse_fields(btf, t, BPF_SPIN_LOCK | BPF_LIST_HEAD | BPF_LIST_NODE, t->size);
++ record = btf_parse_fields(btf, t, BPF_SPIN_LOCK | BPF_LIST_HEAD | BPF_LIST_NODE |
++ BPF_RB_ROOT | BPF_RB_NODE, t->size);
+ /* The record cannot be unset, treat it as an error if so */
+ if (IS_ERR_OR_NULL(record)) {
+ ret = PTR_ERR_OR_ZERO(record) ?: -EFAULT;
+@@ -5795,12 +5848,8 @@ struct btf *bpf_prog_get_target_btf(const struct bpf_prog *prog)
+
+ static bool is_int_ptr(struct btf *btf, const struct btf_type *t)
+ {
+- /* t comes in already as a pointer */
+- t = btf_type_by_id(btf, t->type);
+-
+- /* allow const */
+- if (BTF_INFO_KIND(t->info) == BTF_KIND_CONST)
+- t = btf_type_by_id(btf, t->type);
++ /* skip modifiers */
++ t = btf_type_skip_modifiers(btf, t->type, NULL);
+
+ return btf_type_is_int(t);
+ }
+@@ -8136,12 +8185,10 @@ check_modules:
+ btf_get(mod_btf);
+ spin_unlock_bh(&btf_idr_lock);
+ cands = bpf_core_add_cands(cands, mod_btf, btf_nr_types(main_btf));
+- if (IS_ERR(cands)) {
+- btf_put(mod_btf);
++ btf_put(mod_btf);
++ if (IS_ERR(cands))
+ return ERR_CAST(cands);
+- }
+ spin_lock_bh(&btf_idr_lock);
+- btf_put(mod_btf);
+ }
+ spin_unlock_bh(&btf_idr_lock);
+ /* cands is a pointer to kmalloced memory here if cands->cnt > 0
+diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c
+index bf2fdb33fb313..819f011f0a9cd 100644
+--- a/kernel/bpf/cgroup.c
++++ b/kernel/bpf/cgroup.c
+@@ -1921,14 +1921,17 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level,
+ if (ret < 0)
+ goto out;
+
+- if (ctx.optlen > max_optlen || ctx.optlen < 0) {
++ if (optval && (ctx.optlen > max_optlen || ctx.optlen < 0)) {
+ ret = -EFAULT;
+ goto out;
+ }
+
+ if (ctx.optlen != 0) {
+- if (copy_to_user(optval, ctx.optval, ctx.optlen) ||
+- put_user(ctx.optlen, optlen)) {
++ if (optval && copy_to_user(optval, ctx.optval, ctx.optlen)) {
++ ret = -EFAULT;
++ goto out;
++ }
++ if (put_user(ctx.optlen, optlen)) {
+ ret = -EFAULT;
+ goto out;
+ }
+diff --git a/kernel/bpf/cpumap.c b/kernel/bpf/cpumap.c
+index e0b2d016f0bf9..d33785bedbe5d 100644
+--- a/kernel/bpf/cpumap.c
++++ b/kernel/bpf/cpumap.c
+@@ -540,7 +540,7 @@ static void __cpu_map_entry_replace(struct bpf_cpu_map *cmap,
+ }
+ }
+
+-static int cpu_map_delete_elem(struct bpf_map *map, void *key)
++static long cpu_map_delete_elem(struct bpf_map *map, void *key)
+ {
+ struct bpf_cpu_map *cmap = container_of(map, struct bpf_cpu_map, map);
+ u32 key_cpu = *(u32 *)key;
+@@ -553,8 +553,8 @@ static int cpu_map_delete_elem(struct bpf_map *map, void *key)
+ return 0;
+ }
+
+-static int cpu_map_update_elem(struct bpf_map *map, void *key, void *value,
+- u64 map_flags)
++static long cpu_map_update_elem(struct bpf_map *map, void *key, void *value,
++ u64 map_flags)
+ {
+ struct bpf_cpu_map *cmap = container_of(map, struct bpf_cpu_map, map);
+ struct bpf_cpumap_val cpumap_value = {};
+@@ -667,7 +667,7 @@ static int cpu_map_get_next_key(struct bpf_map *map, void *key, void *next_key)
+ return 0;
+ }
+
+-static int cpu_map_redirect(struct bpf_map *map, u64 index, u64 flags)
++static long cpu_map_redirect(struct bpf_map *map, u64 index, u64 flags)
+ {
+ return __bpf_xdp_redirect_map(map, index, flags, 0,
+ __cpu_map_lookup_elem);
+diff --git a/kernel/bpf/devmap.c b/kernel/bpf/devmap.c
+index d01e4c55b376a..95dafde24ba9c 100644
+--- a/kernel/bpf/devmap.c
++++ b/kernel/bpf/devmap.c
+@@ -799,7 +799,7 @@ static void __dev_map_entry_free(struct rcu_head *rcu)
+ kfree(dev);
+ }
+
+-static int dev_map_delete_elem(struct bpf_map *map, void *key)
++static long dev_map_delete_elem(struct bpf_map *map, void *key)
+ {
+ struct bpf_dtab *dtab = container_of(map, struct bpf_dtab, map);
+ struct bpf_dtab_netdev *old_dev;
+@@ -814,7 +814,7 @@ static int dev_map_delete_elem(struct bpf_map *map, void *key)
+ return 0;
+ }
+
+-static int dev_map_hash_delete_elem(struct bpf_map *map, void *key)
++static long dev_map_hash_delete_elem(struct bpf_map *map, void *key)
+ {
+ struct bpf_dtab *dtab = container_of(map, struct bpf_dtab, map);
+ struct bpf_dtab_netdev *old_dev;
+@@ -885,8 +885,8 @@ err_out:
+ return ERR_PTR(-EINVAL);
+ }
+
+-static int __dev_map_update_elem(struct net *net, struct bpf_map *map,
+- void *key, void *value, u64 map_flags)
++static long __dev_map_update_elem(struct net *net, struct bpf_map *map,
++ void *key, void *value, u64 map_flags)
+ {
+ struct bpf_dtab *dtab = container_of(map, struct bpf_dtab, map);
+ struct bpf_dtab_netdev *dev, *old_dev;
+@@ -925,15 +925,15 @@ static int __dev_map_update_elem(struct net *net, struct bpf_map *map,
+ return 0;
+ }
+
+-static int dev_map_update_elem(struct bpf_map *map, void *key, void *value,
+- u64 map_flags)
++static long dev_map_update_elem(struct bpf_map *map, void *key, void *value,
++ u64 map_flags)
+ {
+ return __dev_map_update_elem(current->nsproxy->net_ns,
+ map, key, value, map_flags);
+ }
+
+-static int __dev_map_hash_update_elem(struct net *net, struct bpf_map *map,
+- void *key, void *value, u64 map_flags)
++static long __dev_map_hash_update_elem(struct net *net, struct bpf_map *map,
++ void *key, void *value, u64 map_flags)
+ {
+ struct bpf_dtab *dtab = container_of(map, struct bpf_dtab, map);
+ struct bpf_dtab_netdev *dev, *old_dev;
+@@ -985,21 +985,21 @@ out_err:
+ return err;
+ }
+
+-static int dev_map_hash_update_elem(struct bpf_map *map, void *key, void *value,
+- u64 map_flags)
++static long dev_map_hash_update_elem(struct bpf_map *map, void *key, void *value,
++ u64 map_flags)
+ {
+ return __dev_map_hash_update_elem(current->nsproxy->net_ns,
+ map, key, value, map_flags);
+ }
+
+-static int dev_map_redirect(struct bpf_map *map, u64 ifindex, u64 flags)
++static long dev_map_redirect(struct bpf_map *map, u64 ifindex, u64 flags)
+ {
+ return __bpf_xdp_redirect_map(map, ifindex, flags,
+ BPF_F_BROADCAST | BPF_F_EXCLUDE_INGRESS,
+ __dev_map_lookup_elem);
+ }
+
+-static int dev_hash_map_redirect(struct bpf_map *map, u64 ifindex, u64 flags)
++static long dev_hash_map_redirect(struct bpf_map *map, u64 ifindex, u64 flags)
+ {
+ return __bpf_xdp_redirect_map(map, ifindex, flags,
+ BPF_F_BROADCAST | BPF_F_EXCLUDE_INGRESS,
+diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c
+index 5dfcb5ad0d068..90852e0e64f26 100644
+--- a/kernel/bpf/hashtab.c
++++ b/kernel/bpf/hashtab.c
+@@ -1057,8 +1057,8 @@ static int check_flags(struct bpf_htab *htab, struct htab_elem *l_old,
+ }
+
+ /* Called from syscall or from eBPF program */
+-static int htab_map_update_elem(struct bpf_map *map, void *key, void *value,
+- u64 map_flags)
++static long htab_map_update_elem(struct bpf_map *map, void *key, void *value,
++ u64 map_flags)
+ {
+ struct bpf_htab *htab = container_of(map, struct bpf_htab, map);
+ struct htab_elem *l_new = NULL, *l_old;
+@@ -1159,8 +1159,8 @@ static void htab_lru_push_free(struct bpf_htab *htab, struct htab_elem *elem)
+ bpf_lru_push_free(&htab->lru, &elem->lru_node);
+ }
+
+-static int htab_lru_map_update_elem(struct bpf_map *map, void *key, void *value,
+- u64 map_flags)
++static long htab_lru_map_update_elem(struct bpf_map *map, void *key, void *value,
++ u64 map_flags)
+ {
+ struct bpf_htab *htab = container_of(map, struct bpf_htab, map);
+ struct htab_elem *l_new, *l_old = NULL;
+@@ -1226,9 +1226,9 @@ err:
+ return ret;
+ }
+
+-static int __htab_percpu_map_update_elem(struct bpf_map *map, void *key,
+- void *value, u64 map_flags,
+- bool onallcpus)
++static long __htab_percpu_map_update_elem(struct bpf_map *map, void *key,
++ void *value, u64 map_flags,
++ bool onallcpus)
+ {
+ struct bpf_htab *htab = container_of(map, struct bpf_htab, map);
+ struct htab_elem *l_new = NULL, *l_old;
+@@ -1281,9 +1281,9 @@ err:
+ return ret;
+ }
+
+-static int __htab_lru_percpu_map_update_elem(struct bpf_map *map, void *key,
+- void *value, u64 map_flags,
+- bool onallcpus)
++static long __htab_lru_percpu_map_update_elem(struct bpf_map *map, void *key,
++ void *value, u64 map_flags,
++ bool onallcpus)
+ {
+ struct bpf_htab *htab = container_of(map, struct bpf_htab, map);
+ struct htab_elem *l_new = NULL, *l_old;
+@@ -1348,21 +1348,21 @@ err:
+ return ret;
+ }
+
+-static int htab_percpu_map_update_elem(struct bpf_map *map, void *key,
+- void *value, u64 map_flags)
++static long htab_percpu_map_update_elem(struct bpf_map *map, void *key,
++ void *value, u64 map_flags)
+ {
+ return __htab_percpu_map_update_elem(map, key, value, map_flags, false);
+ }
+
+-static int htab_lru_percpu_map_update_elem(struct bpf_map *map, void *key,
+- void *value, u64 map_flags)
++static long htab_lru_percpu_map_update_elem(struct bpf_map *map, void *key,
++ void *value, u64 map_flags)
+ {
+ return __htab_lru_percpu_map_update_elem(map, key, value, map_flags,
+ false);
+ }
+
+ /* Called from syscall or from eBPF program */
+-static int htab_map_delete_elem(struct bpf_map *map, void *key)
++static long htab_map_delete_elem(struct bpf_map *map, void *key)
+ {
+ struct bpf_htab *htab = container_of(map, struct bpf_htab, map);
+ struct hlist_nulls_head *head;
+@@ -1398,7 +1398,7 @@ static int htab_map_delete_elem(struct bpf_map *map, void *key)
+ return ret;
+ }
+
+-static int htab_lru_map_delete_elem(struct bpf_map *map, void *key)
++static long htab_lru_map_delete_elem(struct bpf_map *map, void *key)
+ {
+ struct bpf_htab *htab = container_of(map, struct bpf_htab, map);
+ struct hlist_nulls_head *head;
+@@ -2119,8 +2119,8 @@ static const struct bpf_iter_seq_info iter_seq_info = {
+ .seq_priv_size = sizeof(struct bpf_iter_seq_hash_map_info),
+ };
+
+-static int bpf_for_each_hash_elem(struct bpf_map *map, bpf_callback_t callback_fn,
+- void *callback_ctx, u64 flags)
++static long bpf_for_each_hash_elem(struct bpf_map *map, bpf_callback_t callback_fn,
++ void *callback_ctx, u64 flags)
+ {
+ struct bpf_htab *htab = container_of(map, struct bpf_htab, map);
+ struct hlist_nulls_head *head;
+diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
+index af30c6cbd65db..5b692a5f2946b 100644
+--- a/kernel/bpf/helpers.c
++++ b/kernel/bpf/helpers.c
+@@ -1745,12 +1745,12 @@ unlock:
+ while (head != orig_head) {
+ void *obj = head;
+
+- obj -= field->list_head.node_offset;
++ obj -= field->graph_root.node_offset;
+ head = head->next;
+ /* The contained type can also have resources, including a
+ * bpf_list_head which needs to be freed.
+ */
+- bpf_obj_free_fields(field->list_head.value_rec, obj);
++ bpf_obj_free_fields(field->graph_root.value_rec, obj);
+ /* bpf_mem_free requires migrate_disable(), since we can be
+ * called from map free path as well apart from BPF program (as
+ * part of map ops doing bpf_obj_free_fields).
+@@ -1761,6 +1761,46 @@ unlock:
+ }
+ }
+
++/* Like rbtree_postorder_for_each_entry_safe, but 'pos' and 'n' are
++ * 'rb_node *', so field name of rb_node within containing struct is not
++ * needed.
++ *
++ * Since bpf_rb_tree's node type has a corresponding struct btf_field with
++ * graph_root.node_offset, it's not necessary to know field name
++ * or type of node struct
++ */
++#define bpf_rbtree_postorder_for_each_entry_safe(pos, n, root) \
++ for (pos = rb_first_postorder(root); \
++ pos && ({ n = rb_next_postorder(pos); 1; }); \
++ pos = n)
++
++void bpf_rb_root_free(const struct btf_field *field, void *rb_root,
++ struct bpf_spin_lock *spin_lock)
++{
++ struct rb_root_cached orig_root, *root = rb_root;
++ struct rb_node *pos, *n;
++ void *obj;
++
++ BUILD_BUG_ON(sizeof(struct rb_root_cached) > sizeof(struct bpf_rb_root));
++ BUILD_BUG_ON(__alignof__(struct rb_root_cached) > __alignof__(struct bpf_rb_root));
++
++ __bpf_spin_lock_irqsave(spin_lock);
++ orig_root = *root;
++ *root = RB_ROOT_CACHED;
++ __bpf_spin_unlock_irqrestore(spin_lock);
++
++ bpf_rbtree_postorder_for_each_entry_safe(pos, n, &orig_root.rb_root) {
++ obj = pos;
++ obj -= field->graph_root.node_offset;
++
++ bpf_obj_free_fields(field->graph_root.value_rec, obj);
++
++ migrate_disable();
++ bpf_mem_free(&bpf_global_ma, obj);
++ migrate_enable();
++ }
++}
++
+ __diag_push();
+ __diag_ignore_all("-Wmissing-prototypes",
+ "Global functions as their definitions will be in vmlinux BTF");
+@@ -1833,6 +1873,56 @@ struct bpf_list_node *bpf_list_pop_back(struct bpf_list_head *head)
+ return __bpf_list_del(head, true);
+ }
+
++__bpf_kfunc struct bpf_rb_node *bpf_rbtree_remove(struct bpf_rb_root *root,
++ struct bpf_rb_node *node)
++{
++ struct rb_root_cached *r = (struct rb_root_cached *)root;
++ struct rb_node *n = (struct rb_node *)node;
++
++ rb_erase_cached(n, r);
++ RB_CLEAR_NODE(n);
++ return (struct bpf_rb_node *)n;
++}
++
++/* Need to copy rbtree_add_cached's logic here because our 'less' is a BPF
++ * program
++ */
++static void __bpf_rbtree_add(struct bpf_rb_root *root, struct bpf_rb_node *node,
++ void *less)
++{
++ struct rb_node **link = &((struct rb_root_cached *)root)->rb_root.rb_node;
++ bpf_callback_t cb = (bpf_callback_t)less;
++ struct rb_node *parent = NULL;
++ bool leftmost = true;
++
++ while (*link) {
++ parent = *link;
++ if (cb((uintptr_t)node, (uintptr_t)parent, 0, 0, 0)) {
++ link = &parent->rb_left;
++ } else {
++ link = &parent->rb_right;
++ leftmost = false;
++ }
++ }
++
++ rb_link_node((struct rb_node *)node, parent, link);
++ rb_insert_color_cached((struct rb_node *)node,
++ (struct rb_root_cached *)root, leftmost);
++}
++
++__bpf_kfunc void bpf_rbtree_add(struct bpf_rb_root *root, struct bpf_rb_node *node,
++ bool (less)(struct bpf_rb_node *a, const struct bpf_rb_node *b))
++{
++ __bpf_rbtree_add(root, node, (void *)less);
++}
++
++__bpf_kfunc struct bpf_rb_node *bpf_rbtree_first(struct bpf_rb_root *root)
++{
++ struct rb_root_cached *r = (struct rb_root_cached *)root;
++
++ return (struct bpf_rb_node *)rb_first_cached(r);
++}
++
+ /**
+ * bpf_task_acquire - Acquire a reference to a task. A task acquired by this
+ * kfunc which is not stored in a map as a kptr, must be released by calling
+@@ -2057,6 +2147,10 @@ BTF_ID_FLAGS(func, bpf_task_acquire, KF_ACQUIRE | KF_TRUSTED_ARGS)
+ BTF_ID_FLAGS(func, bpf_task_acquire_not_zero, KF_ACQUIRE | KF_RCU | KF_RET_NULL)
+ BTF_ID_FLAGS(func, bpf_task_kptr_get, KF_ACQUIRE | KF_KPTR_GET | KF_RET_NULL)
+ BTF_ID_FLAGS(func, bpf_task_release, KF_RELEASE)
++BTF_ID_FLAGS(func, bpf_rbtree_remove, KF_ACQUIRE)
++BTF_ID_FLAGS(func, bpf_rbtree_add)
++BTF_ID_FLAGS(func, bpf_rbtree_first, KF_RET_NULL)
++
+ #ifdef CONFIG_CGROUPS
+ BTF_ID_FLAGS(func, bpf_cgroup_acquire, KF_ACQUIRE | KF_TRUSTED_ARGS)
+ BTF_ID_FLAGS(func, bpf_cgroup_kptr_get, KF_ACQUIRE | KF_KPTR_GET | KF_RET_NULL)
+diff --git a/kernel/bpf/local_storage.c b/kernel/bpf/local_storage.c
+index e90d9f63edc5d..66d8ce2ab5b34 100644
+--- a/kernel/bpf/local_storage.c
++++ b/kernel/bpf/local_storage.c
+@@ -141,8 +141,8 @@ static void *cgroup_storage_lookup_elem(struct bpf_map *_map, void *key)
+ return &READ_ONCE(storage->buf)->data[0];
+ }
+
+-static int cgroup_storage_update_elem(struct bpf_map *map, void *key,
+- void *value, u64 flags)
++static long cgroup_storage_update_elem(struct bpf_map *map, void *key,
++ void *value, u64 flags)
+ {
+ struct bpf_cgroup_storage *storage;
+ struct bpf_storage_buffer *new;
+@@ -348,7 +348,7 @@ static void cgroup_storage_map_free(struct bpf_map *_map)
+ bpf_map_area_free(map);
+ }
+
+-static int cgroup_storage_delete_elem(struct bpf_map *map, void *key)
++static long cgroup_storage_delete_elem(struct bpf_map *map, void *key)
+ {
+ return -EINVAL;
+ }
+diff --git a/kernel/bpf/lpm_trie.c b/kernel/bpf/lpm_trie.c
+index d833496e9e426..27980506fc7d5 100644
+--- a/kernel/bpf/lpm_trie.c
++++ b/kernel/bpf/lpm_trie.c
+@@ -300,8 +300,8 @@ static struct lpm_trie_node *lpm_trie_node_alloc(const struct lpm_trie *trie,
+ }
+
+ /* Called from syscall or from eBPF program */
+-static int trie_update_elem(struct bpf_map *map,
+- void *_key, void *value, u64 flags)
++static long trie_update_elem(struct bpf_map *map,
++ void *_key, void *value, u64 flags)
+ {
+ struct lpm_trie *trie = container_of(map, struct lpm_trie, map);
+ struct lpm_trie_node *node, *im_node = NULL, *new_node = NULL;
+@@ -431,7 +431,7 @@ out:
+ }
+
+ /* Called from syscall or from eBPF program */
+-static int trie_delete_elem(struct bpf_map *map, void *_key)
++static long trie_delete_elem(struct bpf_map *map, void *_key)
+ {
+ struct lpm_trie *trie = container_of(map, struct lpm_trie, map);
+ struct bpf_lpm_trie_key *key = _key;
+diff --git a/kernel/bpf/queue_stack_maps.c b/kernel/bpf/queue_stack_maps.c
+index 8a5e060de63bc..80f958ff63966 100644
+--- a/kernel/bpf/queue_stack_maps.c
++++ b/kernel/bpf/queue_stack_maps.c
+@@ -95,7 +95,7 @@ static void queue_stack_map_free(struct bpf_map *map)
+ bpf_map_area_free(qs);
+ }
+
+-static int __queue_map_get(struct bpf_map *map, void *value, bool delete)
++static long __queue_map_get(struct bpf_map *map, void *value, bool delete)
+ {
+ struct bpf_queue_stack *qs = bpf_queue_stack(map);
+ unsigned long flags;
+@@ -124,7 +124,7 @@ out:
+ }
+
+
+-static int __stack_map_get(struct bpf_map *map, void *value, bool delete)
++static long __stack_map_get(struct bpf_map *map, void *value, bool delete)
+ {
+ struct bpf_queue_stack *qs = bpf_queue_stack(map);
+ unsigned long flags;
+@@ -156,32 +156,32 @@ out:
+ }
+
+ /* Called from syscall or from eBPF program */
+-static int queue_map_peek_elem(struct bpf_map *map, void *value)
++static long queue_map_peek_elem(struct bpf_map *map, void *value)
+ {
+ return __queue_map_get(map, value, false);
+ }
+
+ /* Called from syscall or from eBPF program */
+-static int stack_map_peek_elem(struct bpf_map *map, void *value)
++static long stack_map_peek_elem(struct bpf_map *map, void *value)
+ {
+ return __stack_map_get(map, value, false);
+ }
+
+ /* Called from syscall or from eBPF program */
+-static int queue_map_pop_elem(struct bpf_map *map, void *value)
++static long queue_map_pop_elem(struct bpf_map *map, void *value)
+ {
+ return __queue_map_get(map, value, true);
+ }
+
+ /* Called from syscall or from eBPF program */
+-static int stack_map_pop_elem(struct bpf_map *map, void *value)
++static long stack_map_pop_elem(struct bpf_map *map, void *value)
+ {
+ return __stack_map_get(map, value, true);
+ }
+
+ /* Called from syscall or from eBPF program */
+-static int queue_stack_map_push_elem(struct bpf_map *map, void *value,
+- u64 flags)
++static long queue_stack_map_push_elem(struct bpf_map *map, void *value,
++ u64 flags)
+ {
+ struct bpf_queue_stack *qs = bpf_queue_stack(map);
+ unsigned long irq_flags;
+@@ -227,14 +227,14 @@ static void *queue_stack_map_lookup_elem(struct bpf_map *map, void *key)
+ }
+
+ /* Called from syscall or from eBPF program */
+-static int queue_stack_map_update_elem(struct bpf_map *map, void *key,
+- void *value, u64 flags)
++static long queue_stack_map_update_elem(struct bpf_map *map, void *key,
++ void *value, u64 flags)
+ {
+ return -EINVAL;
+ }
+
+ /* Called from syscall or from eBPF program */
+-static int queue_stack_map_delete_elem(struct bpf_map *map, void *key)
++static long queue_stack_map_delete_elem(struct bpf_map *map, void *key)
+ {
+ return -EINVAL;
+ }
+diff --git a/kernel/bpf/reuseport_array.c b/kernel/bpf/reuseport_array.c
+index 82c61612f382a..d1188b0350914 100644
+--- a/kernel/bpf/reuseport_array.c
++++ b/kernel/bpf/reuseport_array.c
+@@ -59,7 +59,7 @@ static void *reuseport_array_lookup_elem(struct bpf_map *map, void *key)
+ }
+
+ /* Called from syscall only */
+-static int reuseport_array_delete_elem(struct bpf_map *map, void *key)
++static long reuseport_array_delete_elem(struct bpf_map *map, void *key)
+ {
+ struct reuseport_array *array = reuseport_array(map);
+ u32 index = *(u32 *)key;
+diff --git a/kernel/bpf/ringbuf.c b/kernel/bpf/ringbuf.c
+index 80f4b4d88aafa..ce8ca5511ac13 100644
+--- a/kernel/bpf/ringbuf.c
++++ b/kernel/bpf/ringbuf.c
+@@ -241,13 +241,13 @@ static void *ringbuf_map_lookup_elem(struct bpf_map *map, void *key)
+ return ERR_PTR(-ENOTSUPP);
+ }
+
+-static int ringbuf_map_update_elem(struct bpf_map *map, void *key, void *value,
+- u64 flags)
++static long ringbuf_map_update_elem(struct bpf_map *map, void *key, void *value,
++ u64 flags)
+ {
+ return -ENOTSUPP;
+ }
+
+-static int ringbuf_map_delete_elem(struct bpf_map *map, void *key)
++static long ringbuf_map_delete_elem(struct bpf_map *map, void *key)
+ {
+ return -ENOTSUPP;
+ }
+diff --git a/kernel/bpf/stackmap.c b/kernel/bpf/stackmap.c
+index aecea7451b610..496ce1695dd89 100644
+--- a/kernel/bpf/stackmap.c
++++ b/kernel/bpf/stackmap.c
+@@ -618,14 +618,14 @@ static int stack_map_get_next_key(struct bpf_map *map, void *key,
+ return 0;
+ }
+
+-static int stack_map_update_elem(struct bpf_map *map, void *key, void *value,
+- u64 map_flags)
++static long stack_map_update_elem(struct bpf_map *map, void *key, void *value,
++ u64 map_flags)
+ {
+ return -EINVAL;
+ }
+
+ /* Called from syscall or from eBPF program */
+-static int stack_map_delete_elem(struct bpf_map *map, void *key)
++static long stack_map_delete_elem(struct bpf_map *map, void *key)
+ {
+ struct bpf_stack_map *smap = container_of(map, struct bpf_stack_map, map);
+ struct stack_map_bucket *old_bucket;
+diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
+index ecca9366c7a6f..011983b39472f 100644
+--- a/kernel/bpf/syscall.c
++++ b/kernel/bpf/syscall.c
+@@ -527,9 +527,6 @@ void btf_record_free(struct btf_record *rec)
+ return;
+ for (i = 0; i < rec->cnt; i++) {
+ switch (rec->fields[i].type) {
+- case BPF_SPIN_LOCK:
+- case BPF_TIMER:
+- break;
+ case BPF_KPTR_UNREF:
+ case BPF_KPTR_REF:
+ if (rec->fields[i].kptr.module)
+@@ -538,7 +535,11 @@ void btf_record_free(struct btf_record *rec)
+ break;
+ case BPF_LIST_HEAD:
+ case BPF_LIST_NODE:
+- /* Nothing to release for bpf_list_head */
++ case BPF_RB_ROOT:
++ case BPF_RB_NODE:
++ case BPF_SPIN_LOCK:
++ case BPF_TIMER:
++ /* Nothing to release */
+ break;
+ default:
+ WARN_ON_ONCE(1);
+@@ -571,9 +572,6 @@ struct btf_record *btf_record_dup(const struct btf_record *rec)
+ new_rec->cnt = 0;
+ for (i = 0; i < rec->cnt; i++) {
+ switch (fields[i].type) {
+- case BPF_SPIN_LOCK:
+- case BPF_TIMER:
+- break;
+ case BPF_KPTR_UNREF:
+ case BPF_KPTR_REF:
+ btf_get(fields[i].kptr.btf);
+@@ -584,7 +582,11 @@ struct btf_record *btf_record_dup(const struct btf_record *rec)
+ break;
+ case BPF_LIST_HEAD:
+ case BPF_LIST_NODE:
+- /* Nothing to acquire for bpf_list_head */
++ case BPF_RB_ROOT:
++ case BPF_RB_NODE:
++ case BPF_SPIN_LOCK:
++ case BPF_TIMER:
++ /* Nothing to acquire */
+ break;
+ default:
+ ret = -EFAULT;
+@@ -664,7 +666,13 @@ void bpf_obj_free_fields(const struct btf_record *rec, void *obj)
+ continue;
+ bpf_list_head_free(field, field_ptr, obj + rec->spin_lock_off);
+ break;
++ case BPF_RB_ROOT:
++ if (WARN_ON_ONCE(rec->spin_lock_off < 0))
++ continue;
++ bpf_rb_root_free(field, field_ptr, obj + rec->spin_lock_off);
++ break;
+ case BPF_LIST_NODE:
++ case BPF_RB_NODE:
+ break;
+ default:
+ WARN_ON_ONCE(1);
+@@ -1005,7 +1013,8 @@ static int map_check_btf(struct bpf_map *map, const struct btf *btf,
+ return -EINVAL;
+
+ map->record = btf_parse_fields(btf, value_type,
+- BPF_SPIN_LOCK | BPF_TIMER | BPF_KPTR | BPF_LIST_HEAD,
++ BPF_SPIN_LOCK | BPF_TIMER | BPF_KPTR | BPF_LIST_HEAD |
++ BPF_RB_ROOT,
+ map->value_size);
+ if (!IS_ERR_OR_NULL(map->record)) {
+ int i;
+@@ -1053,6 +1062,7 @@ static int map_check_btf(struct bpf_map *map, const struct btf *btf,
+ }
+ break;
+ case BPF_LIST_HEAD:
++ case BPF_RB_ROOT:
+ if (map->map_type != BPF_MAP_TYPE_HASH &&
+ map->map_type != BPF_MAP_TYPE_LRU_HASH &&
+ map->map_type != BPF_MAP_TYPE_ARRAY) {
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index 9db6afc86733b..1c7dad0e79b92 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -190,6 +190,10 @@ struct bpf_verifier_stack_elem {
+
+ static int acquire_reference_state(struct bpf_verifier_env *env, int insn_idx);
+ static int release_reference(struct bpf_verifier_env *env, int ref_obj_id);
++static void invalidate_non_owning_refs(struct bpf_verifier_env *env);
++static bool in_rbtree_lock_required_cb(struct bpf_verifier_env *env);
++static int ref_set_non_owning(struct bpf_verifier_env *env,
++ struct bpf_reg_state *reg);
+
+ static bool bpf_map_ptr_poisoned(const struct bpf_insn_aux_data *aux)
+ {
+@@ -456,6 +460,11 @@ static bool type_is_ptr_alloc_obj(u32 type)
+ return base_type(type) == PTR_TO_BTF_ID && type_flag(type) & MEM_ALLOC;
+ }
+
++static bool type_is_non_owning_ref(u32 type)
++{
++ return type_is_ptr_alloc_obj(type) && type_flag(type) & NON_OWN_REF;
++}
++
+ static struct btf_record *reg_btf_record(const struct bpf_reg_state *reg)
+ {
+ struct btf_record *rec = NULL;
+@@ -1044,6 +1053,8 @@ static void print_verifier_state(struct bpf_verifier_env *env,
+ verbose_a("id=%d", reg->id);
+ if (reg->ref_obj_id)
+ verbose_a("ref_obj_id=%d", reg->ref_obj_id);
++ if (type_is_non_owning_ref(reg->type))
++ verbose_a("%s", "non_own_ref");
+ if (t != SCALAR_VALUE)
+ verbose_a("off=%d", reg->off);
+ if (type_is_pkt_pointer(t))
+@@ -1599,6 +1610,16 @@ static void mark_ptr_not_null_reg(struct bpf_reg_state *reg)
+ reg->type &= ~PTR_MAYBE_NULL;
+ }
+
++static void mark_reg_graph_node(struct bpf_reg_state *regs, u32 regno,
++ struct btf_field_graph_root *ds_head)
++{
++ __mark_reg_known_zero(&regs[regno]);
++ regs[regno].type = PTR_TO_BTF_ID | MEM_ALLOC;
++ regs[regno].btf = ds_head->btf;
++ regs[regno].btf_id = ds_head->value_btf_id;
++ regs[regno].off = ds_head->node_offset;
++}
++
+ static bool reg_is_pkt_pointer(const struct bpf_reg_state *reg)
+ {
+ return type_is_pkt_pointer(reg->type);
+@@ -1769,9 +1790,9 @@ static void __reg_bound_offset(struct bpf_reg_state *reg)
+ struct tnum var64_off = tnum_intersect(reg->var_off,
+ tnum_range(reg->umin_value,
+ reg->umax_value));
+- struct tnum var32_off = tnum_intersect(tnum_subreg(reg->var_off),
+- tnum_range(reg->u32_min_value,
+- reg->u32_max_value));
++ struct tnum var32_off = tnum_intersect(tnum_subreg(var64_off),
++ tnum_range(reg->u32_min_value,
++ reg->u32_max_value));
+
+ reg->var_off = tnum_or(tnum_clear_subreg(var64_off), var32_off);
+ }
+@@ -3895,17 +3916,13 @@ static int check_stack_read(struct bpf_verifier_env *env,
+ }
+ /* Variable offset is prohibited for unprivileged mode for simplicity
+ * since it requires corresponding support in Spectre masking for stack
+- * ALU. See also retrieve_ptr_limit().
++ * ALU. See also retrieve_ptr_limit(). The check in
++ * check_stack_access_for_ptr_arithmetic() called by
++ * adjust_ptr_min_max_vals() prevents users from creating stack pointers
++ * with variable offsets, therefore no check is required here. Further,
++ * just checking it here would be insufficient as speculative stack
++ * writes could still lead to unsafe speculative behaviour.
+ */
+- if (!env->bypass_spec_v1 && var_off) {
+- char tn_buf[48];
+-
+- tnum_strn(tn_buf, sizeof(tn_buf), reg->var_off);
+- verbose(env, "R%d variable offset stack access prohibited for !root, var_off=%s\n",
+- ptr_regno, tn_buf);
+- return -EACCES;
+- }
+-
+ if (!var_off) {
+ off += reg->var_off.value;
+ err = check_stack_read_fixed_off(env, state, off, size,
+@@ -5007,7 +5024,8 @@ static int check_ptr_to_btf_access(struct bpf_verifier_env *env,
+ return -EACCES;
+ }
+
+- if (type_is_alloc(reg->type) && !reg->ref_obj_id) {
++ if (type_is_alloc(reg->type) && !type_is_non_owning_ref(reg->type) &&
++ !reg->ref_obj_id) {
+ verbose(env, "verifier internal error: ref_obj_id for allocated object must be non-zero\n");
+ return -EFAULT;
+ }
+@@ -5990,9 +6008,7 @@ static int process_spin_lock(struct bpf_verifier_env *env, int regno,
+ cur->active_lock.ptr = btf;
+ cur->active_lock.id = reg->id;
+ } else {
+- struct bpf_func_state *fstate = cur_func(env);
+ void *ptr;
+- int i;
+
+ if (map)
+ ptr = map;
+@@ -6008,25 +6024,11 @@ static int process_spin_lock(struct bpf_verifier_env *env, int regno,
+ verbose(env, "bpf_spin_unlock of different lock\n");
+ return -EINVAL;
+ }
+- cur->active_lock.ptr = NULL;
+- cur->active_lock.id = 0;
+
+- for (i = fstate->acquired_refs - 1; i >= 0; i--) {
+- int err;
++ invalidate_non_owning_refs(env);
+
+- /* Complain on error because this reference state cannot
+- * be freed before this point, as bpf_spin_lock critical
+- * section does not allow functions that release the
+- * allocated object immediately.
+- */
+- if (!fstate->refs[i].release_on_unlock)
+- continue;
+- err = release_reference(env, fstate->refs[i].id);
+- if (err) {
+- verbose(env, "failed to release release_on_unlock reference");
+- return err;
+- }
+- }
++ cur->active_lock.ptr = NULL;
++ cur->active_lock.id = 0;
+ }
+ return 0;
+ }
+@@ -6494,6 +6496,23 @@ found:
+ return 0;
+ }
+
++static struct btf_field *
++reg_find_field_offset(const struct bpf_reg_state *reg, s32 off, u32 fields)
++{
++ struct btf_field *field;
++ struct btf_record *rec;
++
++ rec = reg_btf_record(reg);
++ if (!rec)
++ return NULL;
++
++ field = btf_record_find(rec, off, fields);
++ if (!field)
++ return NULL;
++
++ return field;
++}
++
+ int check_func_arg_reg_off(struct bpf_verifier_env *env,
+ const struct bpf_reg_state *reg, int regno,
+ enum bpf_arg_type arg_type)
+@@ -6515,6 +6534,18 @@ int check_func_arg_reg_off(struct bpf_verifier_env *env,
+ */
+ if (arg_type_is_dynptr(arg_type) && type == PTR_TO_STACK)
+ return 0;
++
++ if ((type_is_ptr_alloc_obj(type) || type_is_non_owning_ref(type)) && reg->off) {
++ if (reg_find_field_offset(reg, reg->off, BPF_GRAPH_NODE_OR_ROOT))
++ return __check_ptr_off_reg(env, reg, regno, true);
++
++ verbose(env, "R%d must have zero offset when passed to release func\n",
++ regno);
++ verbose(env, "No graph node or root found at R%d type:%s off:%d\n", regno,
++ kernel_type_name(reg->btf, reg->btf_id), reg->off);
++ return -EINVAL;
++ }
++
+ /* Doing check_ptr_off_reg check for the offset will catch this
+ * because fixed_off_ok is false, but checking here allows us
+ * to give the user a better error message.
+@@ -6549,6 +6580,7 @@ int check_func_arg_reg_off(struct bpf_verifier_env *env,
+ case PTR_TO_BTF_ID | PTR_TRUSTED:
+ case PTR_TO_BTF_ID | MEM_RCU:
+ case PTR_TO_BTF_ID | MEM_ALLOC | PTR_TRUSTED:
++ case PTR_TO_BTF_ID | MEM_ALLOC | NON_OWN_REF:
+ /* When referenced PTR_TO_BTF_ID is passed to release function,
+ * its fixed offset must be 0. In the other cases, fixed offset
+ * can be non-zero. This was already checked above. So pass
+@@ -6750,6 +6782,10 @@ skip_type_check:
+ meta->ret_btf_id = reg->btf_id;
+ break;
+ case ARG_PTR_TO_SPIN_LOCK:
++ if (in_rbtree_lock_required_cb(env)) {
++ verbose(env, "can't spin_{lock,unlock} in rbtree cb\n");
++ return -EACCES;
++ }
+ if (meta->func_id == BPF_FUNC_spin_lock) {
+ err = process_spin_lock(env, regno, true);
+ if (err)
+@@ -7301,6 +7337,17 @@ static int release_reference(struct bpf_verifier_env *env,
+ return 0;
+ }
+
++static void invalidate_non_owning_refs(struct bpf_verifier_env *env)
++{
++ struct bpf_func_state *unused;
++ struct bpf_reg_state *reg;
++
++ bpf_for_each_reg_in_vstate(env->cur_state, unused, reg, ({
++ if (type_is_non_owning_ref(reg->type))
++ __mark_reg_unknown(env, reg);
++ }));
++}
++
+ static void clear_caller_saved_regs(struct bpf_verifier_env *env,
+ struct bpf_reg_state *regs)
+ {
+@@ -7322,6 +7369,8 @@ static int set_callee_state(struct bpf_verifier_env *env,
+ struct bpf_func_state *caller,
+ struct bpf_func_state *callee, int insn_idx);
+
++static bool is_callback_calling_kfunc(u32 btf_id);
++
+ static int __check_func_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
+ int *insn_idx, int subprog,
+ set_callee_state_fn set_callee_state_cb)
+@@ -7376,10 +7425,18 @@ static int __check_func_call(struct bpf_verifier_env *env, struct bpf_insn *insn
+ * interested in validating only BPF helpers that can call subprogs as
+ * callbacks
+ */
+- if (set_callee_state_cb != set_callee_state && !is_callback_calling_function(insn->imm)) {
+- verbose(env, "verifier bug: helper %s#%d is not marked as callback-calling\n",
+- func_id_name(insn->imm), insn->imm);
+- return -EFAULT;
++ if (set_callee_state_cb != set_callee_state) {
++ if (bpf_pseudo_kfunc_call(insn) &&
++ !is_callback_calling_kfunc(insn->imm)) {
++ verbose(env, "verifier bug: kfunc %s#%d not marked as callback-calling\n",
++ func_id_name(insn->imm), insn->imm);
++ return -EFAULT;
++ } else if (!bpf_pseudo_kfunc_call(insn) &&
++ !is_callback_calling_function(insn->imm)) { /* helper */
++ verbose(env, "verifier bug: helper %s#%d not marked as callback-calling\n",
++ func_id_name(insn->imm), insn->imm);
++ return -EFAULT;
++ }
+ }
+
+ if (insn->code == (BPF_JMP | BPF_CALL) &&
+@@ -7644,6 +7701,63 @@ static int set_user_ringbuf_callback_state(struct bpf_verifier_env *env,
+ return 0;
+ }
+
++static int set_rbtree_add_callback_state(struct bpf_verifier_env *env,
++ struct bpf_func_state *caller,
++ struct bpf_func_state *callee,
++ int insn_idx)
++{
++ /* void bpf_rbtree_add(struct bpf_rb_root *root, struct bpf_rb_node *node,
++ * bool (less)(struct bpf_rb_node *a, const struct bpf_rb_node *b));
++ *
++ * 'struct bpf_rb_node *node' arg to bpf_rbtree_add is the same PTR_TO_BTF_ID w/ offset
++ * that 'less' callback args will be receiving. However, 'node' arg was release_reference'd
++ * by this point, so look at 'root'
++ */
++ struct btf_field *field;
++
++ field = reg_find_field_offset(&caller->regs[BPF_REG_1], caller->regs[BPF_REG_1].off,
++ BPF_RB_ROOT);
++ if (!field || !field->graph_root.value_btf_id)
++ return -EFAULT;
++
++ mark_reg_graph_node(callee->regs, BPF_REG_1, &field->graph_root);
++ ref_set_non_owning(env, &callee->regs[BPF_REG_1]);
++ mark_reg_graph_node(callee->regs, BPF_REG_2, &field->graph_root);
++ ref_set_non_owning(env, &callee->regs[BPF_REG_2]);
++
++ __mark_reg_not_init(env, &callee->regs[BPF_REG_3]);
++ __mark_reg_not_init(env, &callee->regs[BPF_REG_4]);
++ __mark_reg_not_init(env, &callee->regs[BPF_REG_5]);
++ callee->in_callback_fn = true;
++ callee->callback_ret_range = tnum_range(0, 1);
++ return 0;
++}
++
++static bool is_rbtree_lock_required_kfunc(u32 btf_id);
++
++/* Are we currently verifying the callback for a rbtree helper that must
++ * be called with lock held? If so, no need to complain about unreleased
++ * lock
++ */
++static bool in_rbtree_lock_required_cb(struct bpf_verifier_env *env)
++{
++ struct bpf_verifier_state *state = env->cur_state;
++ struct bpf_insn *insn = env->prog->insnsi;
++ struct bpf_func_state *callee;
++ int kfunc_btf_id;
++
++ if (!state->curframe)
++ return false;
++
++ callee = state->frame[state->curframe];
++
++ if (!callee->in_callback_fn)
++ return false;
++
++ kfunc_btf_id = insn[callee->callsite].imm;
++ return is_rbtree_lock_required_kfunc(kfunc_btf_id);
++}
++
+ static int prepare_func_exit(struct bpf_verifier_env *env, int *insn_idx)
+ {
+ struct bpf_verifier_state *state = env->cur_state;
+@@ -8395,6 +8509,7 @@ struct bpf_kfunc_call_arg_meta {
+ bool r0_rdonly;
+ u32 ret_btf_id;
+ u64 r0_size;
++ u32 subprogno;
+ struct {
+ u64 value;
+ bool found;
+@@ -8406,6 +8521,9 @@ struct bpf_kfunc_call_arg_meta {
+ struct {
+ struct btf_field *field;
+ } arg_list_head;
++ struct {
++ struct btf_field *field;
++ } arg_rbtree_root;
+ };
+
+ static bool is_kfunc_acquire(struct bpf_kfunc_call_arg_meta *meta)
+@@ -8517,12 +8635,16 @@ enum {
+ KF_ARG_DYNPTR_ID,
+ KF_ARG_LIST_HEAD_ID,
+ KF_ARG_LIST_NODE_ID,
++ KF_ARG_RB_ROOT_ID,
++ KF_ARG_RB_NODE_ID,
+ };
+
+ BTF_ID_LIST(kf_arg_btf_ids)
+ BTF_ID(struct, bpf_dynptr_kern)
+ BTF_ID(struct, bpf_list_head)
+ BTF_ID(struct, bpf_list_node)
++BTF_ID(struct, bpf_rb_root)
++BTF_ID(struct, bpf_rb_node)
+
+ static bool __is_kfunc_ptr_arg_type(const struct btf *btf,
+ const struct btf_param *arg, int type)
+@@ -8556,6 +8678,28 @@ static bool is_kfunc_arg_list_node(const struct btf *btf, const struct btf_param
+ return __is_kfunc_ptr_arg_type(btf, arg, KF_ARG_LIST_NODE_ID);
+ }
+
++static bool is_kfunc_arg_rbtree_root(const struct btf *btf, const struct btf_param *arg)
++{
++ return __is_kfunc_ptr_arg_type(btf, arg, KF_ARG_RB_ROOT_ID);
++}
++
++static bool is_kfunc_arg_rbtree_node(const struct btf *btf, const struct btf_param *arg)
++{
++ return __is_kfunc_ptr_arg_type(btf, arg, KF_ARG_RB_NODE_ID);
++}
++
++static bool is_kfunc_arg_callback(struct bpf_verifier_env *env, const struct btf *btf,
++ const struct btf_param *arg)
++{
++ const struct btf_type *t;
++
++ t = btf_type_resolve_func_ptr(btf, arg->type, NULL);
++ if (!t)
++ return false;
++
++ return true;
++}
++
+ /* Returns true if struct is composed of scalars, 4 levels of nesting allowed */
+ static bool __btf_type_is_scalar_struct(struct bpf_verifier_env *env,
+ const struct btf *btf,
+@@ -8615,6 +8759,9 @@ enum kfunc_ptr_arg_type {
+ KF_ARG_PTR_TO_BTF_ID, /* Also covers reg2btf_ids conversions */
+ KF_ARG_PTR_TO_MEM,
+ KF_ARG_PTR_TO_MEM_SIZE, /* Size derived from next argument, skip it */
++ KF_ARG_PTR_TO_CALLBACK,
++ KF_ARG_PTR_TO_RB_ROOT,
++ KF_ARG_PTR_TO_RB_NODE,
+ };
+
+ enum special_kfunc_type {
+@@ -8628,6 +8775,9 @@ enum special_kfunc_type {
+ KF_bpf_rdonly_cast,
+ KF_bpf_rcu_read_lock,
+ KF_bpf_rcu_read_unlock,
++ KF_bpf_rbtree_remove,
++ KF_bpf_rbtree_add,
++ KF_bpf_rbtree_first,
+ };
+
+ BTF_SET_START(special_kfunc_set)
+@@ -8639,6 +8789,9 @@ BTF_ID(func, bpf_list_pop_front)
+ BTF_ID(func, bpf_list_pop_back)
+ BTF_ID(func, bpf_cast_to_kern_ctx)
+ BTF_ID(func, bpf_rdonly_cast)
++BTF_ID(func, bpf_rbtree_remove)
++BTF_ID(func, bpf_rbtree_add)
++BTF_ID(func, bpf_rbtree_first)
+ BTF_SET_END(special_kfunc_set)
+
+ BTF_ID_LIST(special_kfunc_list)
+@@ -8652,6 +8805,9 @@ BTF_ID(func, bpf_cast_to_kern_ctx)
+ BTF_ID(func, bpf_rdonly_cast)
+ BTF_ID(func, bpf_rcu_read_lock)
+ BTF_ID(func, bpf_rcu_read_unlock)
++BTF_ID(func, bpf_rbtree_remove)
++BTF_ID(func, bpf_rbtree_add)
++BTF_ID(func, bpf_rbtree_first)
+
+ static bool is_kfunc_bpf_rcu_read_lock(struct bpf_kfunc_call_arg_meta *meta)
+ {
+@@ -8713,6 +8869,12 @@ get_kfunc_ptr_arg_type(struct bpf_verifier_env *env,
+ if (is_kfunc_arg_list_node(meta->btf, &args[argno]))
+ return KF_ARG_PTR_TO_LIST_NODE;
+
++ if (is_kfunc_arg_rbtree_root(meta->btf, &args[argno]))
++ return KF_ARG_PTR_TO_RB_ROOT;
++
++ if (is_kfunc_arg_rbtree_node(meta->btf, &args[argno]))
++ return KF_ARG_PTR_TO_RB_NODE;
++
+ if ((base_type(reg->type) == PTR_TO_BTF_ID || reg2btf_ids[base_type(reg->type)])) {
+ if (!btf_type_is_struct(ref_t)) {
+ verbose(env, "kernel function %s args#%d pointer type %s %s is not supported\n",
+@@ -8722,6 +8884,9 @@ get_kfunc_ptr_arg_type(struct bpf_verifier_env *env,
+ return KF_ARG_PTR_TO_BTF_ID;
+ }
+
++ if (is_kfunc_arg_callback(env, meta->btf, &args[argno]))
++ return KF_ARG_PTR_TO_CALLBACK;
++
+ if (argno + 1 < nargs && is_kfunc_arg_mem_size(meta->btf, &args[argno + 1], &regs[regno + 1]))
+ arg_mem_size = true;
+
+@@ -8808,38 +8973,54 @@ static int process_kf_arg_ptr_to_kptr(struct bpf_verifier_env *env,
+ return 0;
+ }
+
+-static int ref_set_release_on_unlock(struct bpf_verifier_env *env, u32 ref_obj_id)
++static int ref_set_non_owning(struct bpf_verifier_env *env, struct bpf_reg_state *reg)
+ {
+- struct bpf_func_state *state = cur_func(env);
++ struct bpf_verifier_state *state = env->cur_state;
++
++ if (!state->active_lock.ptr) {
++ verbose(env, "verifier internal error: ref_set_non_owning w/o active lock\n");
++ return -EFAULT;
++ }
++
++ if (type_flag(reg->type) & NON_OWN_REF) {
++ verbose(env, "verifier internal error: NON_OWN_REF already set\n");
++ return -EFAULT;
++ }
++
++ reg->type |= NON_OWN_REF;
++ return 0;
++}
++
++static int ref_convert_owning_non_owning(struct bpf_verifier_env *env, u32 ref_obj_id)
++{
++ struct bpf_func_state *state, *unused;
+ struct bpf_reg_state *reg;
+ int i;
+
+- /* bpf_spin_lock only allows calling list_push and list_pop, no BPF
+- * subprogs, no global functions. This means that the references would
+- * not be released inside the critical section but they may be added to
+- * the reference state, and the acquired_refs are never copied out for a
+- * different frame as BPF to BPF calls don't work in bpf_spin_lock
+- * critical sections.
+- */
++ state = cur_func(env);
++
+ if (!ref_obj_id) {
+- verbose(env, "verifier internal error: ref_obj_id is zero for release_on_unlock\n");
++ verbose(env, "verifier internal error: ref_obj_id is zero for "
++ "owning -> non-owning conversion\n");
+ return -EFAULT;
+ }
++
+ for (i = 0; i < state->acquired_refs; i++) {
+- if (state->refs[i].id == ref_obj_id) {
+- if (state->refs[i].release_on_unlock) {
+- verbose(env, "verifier internal error: expected false release_on_unlock");
+- return -EFAULT;
++ if (state->refs[i].id != ref_obj_id)
++ continue;
++
++ /* Clear ref_obj_id here so release_reference doesn't clobber
++ * the whole reg
++ */
++ bpf_for_each_reg_in_vstate(env->cur_state, unused, reg, ({
++ if (reg->ref_obj_id == ref_obj_id) {
++ reg->ref_obj_id = 0;
++ ref_set_non_owning(env, reg);
+ }
+- state->refs[i].release_on_unlock = true;
+- /* Now mark everyone sharing same ref_obj_id as untrusted */
+- bpf_for_each_reg_in_vstate(env->cur_state, state, reg, ({
+- if (reg->ref_obj_id == ref_obj_id)
+- reg->type |= PTR_UNTRUSTED;
+- }));
+- return 0;
+- }
++ }));
++ return 0;
+ }
++
+ verbose(env, "verifier internal error: ref state missing for ref_obj_id\n");
+ return -EFAULT;
+ }
+@@ -8925,101 +9106,226 @@ static bool is_bpf_list_api_kfunc(u32 btf_id)
+ btf_id == special_kfunc_list[KF_bpf_list_pop_back];
+ }
+
+-static int process_kf_arg_ptr_to_list_head(struct bpf_verifier_env *env,
+- struct bpf_reg_state *reg, u32 regno,
+- struct bpf_kfunc_call_arg_meta *meta)
++static bool is_bpf_rbtree_api_kfunc(u32 btf_id)
++{
++ return btf_id == special_kfunc_list[KF_bpf_rbtree_add] ||
++ btf_id == special_kfunc_list[KF_bpf_rbtree_remove] ||
++ btf_id == special_kfunc_list[KF_bpf_rbtree_first];
++}
++
++static bool is_bpf_graph_api_kfunc(u32 btf_id)
+ {
++ return is_bpf_list_api_kfunc(btf_id) || is_bpf_rbtree_api_kfunc(btf_id);
++}
++
++static bool is_callback_calling_kfunc(u32 btf_id)
++{
++ return btf_id == special_kfunc_list[KF_bpf_rbtree_add];
++}
++
++static bool is_rbtree_lock_required_kfunc(u32 btf_id)
++{
++ return is_bpf_rbtree_api_kfunc(btf_id);
++}
++
++static bool check_kfunc_is_graph_root_api(struct bpf_verifier_env *env,
++ enum btf_field_type head_field_type,
++ u32 kfunc_btf_id)
++{
++ bool ret;
++
++ switch (head_field_type) {
++ case BPF_LIST_HEAD:
++ ret = is_bpf_list_api_kfunc(kfunc_btf_id);
++ break;
++ case BPF_RB_ROOT:
++ ret = is_bpf_rbtree_api_kfunc(kfunc_btf_id);
++ break;
++ default:
++ verbose(env, "verifier internal error: unexpected graph root argument type %s\n",
++ btf_field_type_name(head_field_type));
++ return false;
++ }
++
++ if (!ret)
++ verbose(env, "verifier internal error: %s head arg for unknown kfunc\n",
++ btf_field_type_name(head_field_type));
++ return ret;
++}
++
++static bool check_kfunc_is_graph_node_api(struct bpf_verifier_env *env,
++ enum btf_field_type node_field_type,
++ u32 kfunc_btf_id)
++{
++ bool ret;
++
++ switch (node_field_type) {
++ case BPF_LIST_NODE:
++ ret = (kfunc_btf_id == special_kfunc_list[KF_bpf_list_push_front] ||
++ kfunc_btf_id == special_kfunc_list[KF_bpf_list_push_back]);
++ break;
++ case BPF_RB_NODE:
++ ret = (kfunc_btf_id == special_kfunc_list[KF_bpf_rbtree_remove] ||
++ kfunc_btf_id == special_kfunc_list[KF_bpf_rbtree_add]);
++ break;
++ default:
++ verbose(env, "verifier internal error: unexpected graph node argument type %s\n",
++ btf_field_type_name(node_field_type));
++ return false;
++ }
++
++ if (!ret)
++ verbose(env, "verifier internal error: %s node arg for unknown kfunc\n",
++ btf_field_type_name(node_field_type));
++ return ret;
++}
++
++static int
++__process_kf_arg_ptr_to_graph_root(struct bpf_verifier_env *env,
++ struct bpf_reg_state *reg, u32 regno,
++ struct bpf_kfunc_call_arg_meta *meta,
++ enum btf_field_type head_field_type,
++ struct btf_field **head_field)
++{
++ const char *head_type_name;
+ struct btf_field *field;
+ struct btf_record *rec;
+- u32 list_head_off;
++ u32 head_off;
+
+- if (meta->btf != btf_vmlinux || !is_bpf_list_api_kfunc(meta->func_id)) {
+- verbose(env, "verifier internal error: bpf_list_head argument for unknown kfunc\n");
++ if (meta->btf != btf_vmlinux) {
++ verbose(env, "verifier internal error: unexpected btf mismatch in kfunc call\n");
+ return -EFAULT;
+ }
+
++ if (!check_kfunc_is_graph_root_api(env, head_field_type, meta->func_id))
++ return -EFAULT;
++
++ head_type_name = btf_field_type_name(head_field_type);
+ if (!tnum_is_const(reg->var_off)) {
+ verbose(env,
+- "R%d doesn't have constant offset. bpf_list_head has to be at the constant offset\n",
+- regno);
++ "R%d doesn't have constant offset. %s has to be at the constant offset\n",
++ regno, head_type_name);
+ return -EINVAL;
+ }
+
+ rec = reg_btf_record(reg);
+- list_head_off = reg->off + reg->var_off.value;
+- field = btf_record_find(rec, list_head_off, BPF_LIST_HEAD);
++ head_off = reg->off + reg->var_off.value;
++ field = btf_record_find(rec, head_off, head_field_type);
+ if (!field) {
+- verbose(env, "bpf_list_head not found at offset=%u\n", list_head_off);
++ verbose(env, "%s not found at offset=%u\n", head_type_name, head_off);
+ return -EINVAL;
+ }
+
+ /* All functions require bpf_list_head to be protected using a bpf_spin_lock */
+ if (check_reg_allocation_locked(env, reg)) {
+- verbose(env, "bpf_spin_lock at off=%d must be held for bpf_list_head\n",
+- rec->spin_lock_off);
++ verbose(env, "bpf_spin_lock at off=%d must be held for %s\n",
++ rec->spin_lock_off, head_type_name);
+ return -EINVAL;
+ }
+
+- if (meta->arg_list_head.field) {
+- verbose(env, "verifier internal error: repeating bpf_list_head arg\n");
++ if (*head_field) {
++ verbose(env, "verifier internal error: repeating %s arg\n", head_type_name);
+ return -EFAULT;
+ }
+- meta->arg_list_head.field = field;
++ *head_field = field;
+ return 0;
+ }
+
+-static int process_kf_arg_ptr_to_list_node(struct bpf_verifier_env *env,
++static int process_kf_arg_ptr_to_list_head(struct bpf_verifier_env *env,
+ struct bpf_reg_state *reg, u32 regno,
+ struct bpf_kfunc_call_arg_meta *meta)
+ {
++ return __process_kf_arg_ptr_to_graph_root(env, reg, regno, meta, BPF_LIST_HEAD,
++ &meta->arg_list_head.field);
++}
++
++static int process_kf_arg_ptr_to_rbtree_root(struct bpf_verifier_env *env,
++ struct bpf_reg_state *reg, u32 regno,
++ struct bpf_kfunc_call_arg_meta *meta)
++{
++ return __process_kf_arg_ptr_to_graph_root(env, reg, regno, meta, BPF_RB_ROOT,
++ &meta->arg_rbtree_root.field);
++}
++
++static int
++__process_kf_arg_ptr_to_graph_node(struct bpf_verifier_env *env,
++ struct bpf_reg_state *reg, u32 regno,
++ struct bpf_kfunc_call_arg_meta *meta,
++ enum btf_field_type head_field_type,
++ enum btf_field_type node_field_type,
++ struct btf_field **node_field)
++{
++ const char *node_type_name;
+ const struct btf_type *et, *t;
+ struct btf_field *field;
+- struct btf_record *rec;
+- u32 list_node_off;
++ u32 node_off;
+
+- if (meta->btf != btf_vmlinux ||
+- (meta->func_id != special_kfunc_list[KF_bpf_list_push_front] &&
+- meta->func_id != special_kfunc_list[KF_bpf_list_push_back])) {
+- verbose(env, "verifier internal error: bpf_list_node argument for unknown kfunc\n");
++ if (meta->btf != btf_vmlinux) {
++ verbose(env, "verifier internal error: unexpected btf mismatch in kfunc call\n");
+ return -EFAULT;
+ }
+
++ if (!check_kfunc_is_graph_node_api(env, node_field_type, meta->func_id))
++ return -EFAULT;
++
++ node_type_name = btf_field_type_name(node_field_type);
+ if (!tnum_is_const(reg->var_off)) {
+ verbose(env,
+- "R%d doesn't have constant offset. bpf_list_node has to be at the constant offset\n",
+- regno);
++ "R%d doesn't have constant offset. %s has to be at the constant offset\n",
++ regno, node_type_name);
+ return -EINVAL;
+ }
+
+- rec = reg_btf_record(reg);
+- list_node_off = reg->off + reg->var_off.value;
+- field = btf_record_find(rec, list_node_off, BPF_LIST_NODE);
+- if (!field || field->offset != list_node_off) {
+- verbose(env, "bpf_list_node not found at offset=%u\n", list_node_off);
++ node_off = reg->off + reg->var_off.value;
++ field = reg_find_field_offset(reg, node_off, node_field_type);
++ if (!field || field->offset != node_off) {
++ verbose(env, "%s not found at offset=%u\n", node_type_name, node_off);
+ return -EINVAL;
+ }
+
+- field = meta->arg_list_head.field;
++ field = *node_field;
+
+- et = btf_type_by_id(field->list_head.btf, field->list_head.value_btf_id);
++ et = btf_type_by_id(field->graph_root.btf, field->graph_root.value_btf_id);
+ t = btf_type_by_id(reg->btf, reg->btf_id);
+- if (!btf_struct_ids_match(&env->log, reg->btf, reg->btf_id, 0, field->list_head.btf,
+- field->list_head.value_btf_id, true)) {
+- verbose(env, "operation on bpf_list_head expects arg#1 bpf_list_node at offset=%d "
++ if (!btf_struct_ids_match(&env->log, reg->btf, reg->btf_id, 0, field->graph_root.btf,
++ field->graph_root.value_btf_id, true)) {
++ verbose(env, "operation on %s expects arg#1 %s at offset=%d "
+ "in struct %s, but arg is at offset=%d in struct %s\n",
+- field->list_head.node_offset, btf_name_by_offset(field->list_head.btf, et->name_off),
+- list_node_off, btf_name_by_offset(reg->btf, t->name_off));
++ btf_field_type_name(head_field_type),
++ btf_field_type_name(node_field_type),
++ field->graph_root.node_offset,
++ btf_name_by_offset(field->graph_root.btf, et->name_off),
++ node_off, btf_name_by_offset(reg->btf, t->name_off));
+ return -EINVAL;
+ }
+
+- if (list_node_off != field->list_head.node_offset) {
+- verbose(env, "arg#1 offset=%d, but expected bpf_list_node at offset=%d in struct %s\n",
+- list_node_off, field->list_head.node_offset,
+- btf_name_by_offset(field->list_head.btf, et->name_off));
++ if (node_off != field->graph_root.node_offset) {
++ verbose(env, "arg#1 offset=%d, but expected %s at offset=%d in struct %s\n",
++ node_off, btf_field_type_name(node_field_type),
++ field->graph_root.node_offset,
++ btf_name_by_offset(field->graph_root.btf, et->name_off));
+ return -EINVAL;
+ }
+- /* Set arg#1 for expiration after unlock */
+- return ref_set_release_on_unlock(env, reg->ref_obj_id);
++
++ return 0;
++}
++
++static int process_kf_arg_ptr_to_list_node(struct bpf_verifier_env *env,
++ struct bpf_reg_state *reg, u32 regno,
++ struct bpf_kfunc_call_arg_meta *meta)
++{
++ return __process_kf_arg_ptr_to_graph_node(env, reg, regno, meta,
++ BPF_LIST_HEAD, BPF_LIST_NODE,
++ &meta->arg_list_head.field);
++}
++
++static int process_kf_arg_ptr_to_rbtree_node(struct bpf_verifier_env *env,
++ struct bpf_reg_state *reg, u32 regno,
++ struct bpf_kfunc_call_arg_meta *meta)
++{
++ return __process_kf_arg_ptr_to_graph_node(env, reg, regno, meta,
++ BPF_RB_ROOT, BPF_RB_NODE,
++ &meta->arg_rbtree_root.field);
+ }
+
+ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_kfunc_call_arg_meta *meta)
+@@ -9150,8 +9456,11 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_kfunc_call_
+ case KF_ARG_PTR_TO_DYNPTR:
+ case KF_ARG_PTR_TO_LIST_HEAD:
+ case KF_ARG_PTR_TO_LIST_NODE:
++ case KF_ARG_PTR_TO_RB_ROOT:
++ case KF_ARG_PTR_TO_RB_NODE:
+ case KF_ARG_PTR_TO_MEM:
+ case KF_ARG_PTR_TO_MEM_SIZE:
++ case KF_ARG_PTR_TO_CALLBACK:
+ /* Trusted by default */
+ break;
+ default:
+@@ -9228,6 +9537,20 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_kfunc_call_
+ if (ret < 0)
+ return ret;
+ break;
++ case KF_ARG_PTR_TO_RB_ROOT:
++ if (reg->type != PTR_TO_MAP_VALUE &&
++ reg->type != (PTR_TO_BTF_ID | MEM_ALLOC)) {
++ verbose(env, "arg#%d expected pointer to map value or allocated object\n", i);
++ return -EINVAL;
++ }
++ if (reg->type == (PTR_TO_BTF_ID | MEM_ALLOC) && !reg->ref_obj_id) {
++ verbose(env, "allocated object must be referenced\n");
++ return -EINVAL;
++ }
++ ret = process_kf_arg_ptr_to_rbtree_root(env, reg, regno, meta);
++ if (ret < 0)
++ return ret;
++ break;
+ case KF_ARG_PTR_TO_LIST_NODE:
+ if (reg->type != (PTR_TO_BTF_ID | MEM_ALLOC)) {
+ verbose(env, "arg#%d expected pointer to allocated object\n", i);
+@@ -9241,6 +9564,19 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_kfunc_call_
+ if (ret < 0)
+ return ret;
+ break;
++ case KF_ARG_PTR_TO_RB_NODE:
++ if (reg->type != (PTR_TO_BTF_ID | MEM_ALLOC)) {
++ verbose(env, "arg#%d expected pointer to allocated object\n", i);
++ return -EINVAL;
++ }
++ if (!reg->ref_obj_id) {
++ verbose(env, "allocated object must be referenced\n");
++ return -EINVAL;
++ }
++ ret = process_kf_arg_ptr_to_rbtree_node(env, reg, regno, meta);
++ if (ret < 0)
++ return ret;
++ break;
+ case KF_ARG_PTR_TO_BTF_ID:
+ /* Only base_type is checked, further checks are done here */
+ if ((base_type(reg->type) != PTR_TO_BTF_ID ||
+@@ -9276,6 +9612,9 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_kfunc_call_
+ /* Skip next '__sz' argument */
+ i++;
+ break;
++ case KF_ARG_PTR_TO_CALLBACK:
++ meta->subprogno = reg->subprogno;
++ break;
+ }
+ }
+
+@@ -9288,24 +9627,21 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_kfunc_call_
+ return 0;
+ }
+
+-static int check_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
+- int *insn_idx_p)
++static int fetch_kfunc_meta(struct bpf_verifier_env *env,
++ struct bpf_insn *insn,
++ struct bpf_kfunc_call_arg_meta *meta,
++ const char **kfunc_name)
+ {
+- const struct btf_type *t, *func, *func_proto, *ptr_type;
+- struct bpf_reg_state *regs = cur_regs(env);
+- const char *func_name, *ptr_type_name;
+- bool sleepable, rcu_lock, rcu_unlock;
+- struct bpf_kfunc_call_arg_meta meta;
+- u32 i, nargs, func_id, ptr_type_id;
+- int err, insn_idx = *insn_idx_p;
+- const struct btf_param *args;
+- const struct btf_type *ret_t;
++ const struct btf_type *func, *func_proto;
++ u32 func_id, *kfunc_flags;
++ const char *func_name;
+ struct btf *desc_btf;
+- u32 *kfunc_flags;
+
+- /* skip for now, but return error when we find this in fixup_kfunc_call */
++ if (kfunc_name)
++ *kfunc_name = NULL;
++
+ if (!insn->imm)
+- return 0;
++ return -EINVAL;
+
+ desc_btf = find_kfunc_desc_btf(env, insn->off);
+ if (IS_ERR(desc_btf))
+@@ -9314,22 +9650,51 @@ static int check_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
+ func_id = insn->imm;
+ func = btf_type_by_id(desc_btf, func_id);
+ func_name = btf_name_by_offset(desc_btf, func->name_off);
++ if (kfunc_name)
++ *kfunc_name = func_name;
+ func_proto = btf_type_by_id(desc_btf, func->type);
+
+ kfunc_flags = btf_kfunc_id_set_contains(desc_btf, resolve_prog_type(env->prog), func_id);
+ if (!kfunc_flags) {
+- verbose(env, "calling kernel function %s is not allowed\n",
+- func_name);
+ return -EACCES;
+ }
+
+- /* Prepare kfunc call metadata */
+- memset(&meta, 0, sizeof(meta));
+- meta.btf = desc_btf;
+- meta.func_id = func_id;
+- meta.kfunc_flags = *kfunc_flags;
+- meta.func_proto = func_proto;
+- meta.func_name = func_name;
++ memset(meta, 0, sizeof(*meta));
++ meta->btf = desc_btf;
++ meta->func_id = func_id;
++ meta->kfunc_flags = *kfunc_flags;
++ meta->func_proto = func_proto;
++ meta->func_name = func_name;
++
++ return 0;
++}
++
++static int check_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
++ int *insn_idx_p)
++{
++ const struct btf_type *t, *ptr_type;
++ u32 i, nargs, ptr_type_id, release_ref_obj_id;
++ struct bpf_reg_state *regs = cur_regs(env);
++ const char *func_name, *ptr_type_name;
++ bool sleepable, rcu_lock, rcu_unlock;
++ struct bpf_kfunc_call_arg_meta meta;
++ struct bpf_insn_aux_data *insn_aux;
++ int err, insn_idx = *insn_idx_p;
++ const struct btf_param *args;
++ const struct btf_type *ret_t;
++ struct btf *desc_btf;
++
++ /* skip for now, but return error when we find this in fixup_kfunc_call */
++ if (!insn->imm)
++ return 0;
++
++ err = fetch_kfunc_meta(env, insn, &meta, &func_name);
++ if (err == -EACCES && func_name)
++ verbose(env, "calling kernel function %s is not allowed\n", func_name);
++ if (err)
++ return err;
++ desc_btf = meta.btf;
++ insn_aux = &env->insn_aux_data[insn_idx];
+
+ if (is_kfunc_destructive(&meta) && !capable(CAP_SYS_BOOT)) {
+ verbose(env, "destructive kfunc calls require CAP_SYS_BOOT capability\n");
+@@ -9386,7 +9751,36 @@ static int check_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
+ err = release_reference(env, regs[meta.release_regno].ref_obj_id);
+ if (err) {
+ verbose(env, "kfunc %s#%d reference has not been acquired before\n",
+- func_name, func_id);
++ func_name, meta.func_id);
++ return err;
++ }
++ }
++
++ if (meta.func_id == special_kfunc_list[KF_bpf_list_push_front] ||
++ meta.func_id == special_kfunc_list[KF_bpf_list_push_back] ||
++ meta.func_id == special_kfunc_list[KF_bpf_rbtree_add]) {
++ release_ref_obj_id = regs[BPF_REG_2].ref_obj_id;
++ err = ref_convert_owning_non_owning(env, release_ref_obj_id);
++ if (err) {
++ verbose(env, "kfunc %s#%d conversion of owning ref to non-owning failed\n",
++ func_name, meta.func_id);
++ return err;
++ }
++
++ err = release_reference(env, release_ref_obj_id);
++ if (err) {
++ verbose(env, "kfunc %s#%d reference has not been acquired before\n",
++ func_name, meta.func_id);
++ return err;
++ }
++ }
++
++ if (meta.func_id == special_kfunc_list[KF_bpf_rbtree_add]) {
++ err = __check_func_call(env, insn, insn_idx_p, meta.subprogno,
++ set_rbtree_add_callback_state);
++ if (err) {
++ verbose(env, "kfunc %s#%d failed callback verification\n",
++ func_name, meta.func_id);
+ return err;
+ }
+ }
+@@ -9395,7 +9789,7 @@ static int check_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
+ mark_reg_not_init(env, regs, caller_saved[i]);
+
+ /* Check return type */
+- t = btf_type_skip_modifiers(desc_btf, func_proto->type, NULL);
++ t = btf_type_skip_modifiers(desc_btf, meta.func_proto->type, NULL);
+
+ if (is_kfunc_acquire(&meta) && !btf_type_is_struct_ptr(meta.btf, t)) {
+ /* Only exception is bpf_obj_new_impl */
+@@ -9444,22 +9838,18 @@ static int check_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
+ regs[BPF_REG_0].btf = ret_btf;
+ regs[BPF_REG_0].btf_id = ret_btf_id;
+
+- env->insn_aux_data[insn_idx].obj_new_size = ret_t->size;
+- env->insn_aux_data[insn_idx].kptr_struct_meta =
++ insn_aux->obj_new_size = ret_t->size;
++ insn_aux->kptr_struct_meta =
+ btf_find_struct_meta(ret_btf, ret_btf_id);
+- } else if (meta.func_id == special_kfunc_list[KF_bpf_obj_drop_impl]) {
+- env->insn_aux_data[insn_idx].kptr_struct_meta =
+- btf_find_struct_meta(meta.arg_obj_drop.btf,
+- meta.arg_obj_drop.btf_id);
+ } else if (meta.func_id == special_kfunc_list[KF_bpf_list_pop_front] ||
+ meta.func_id == special_kfunc_list[KF_bpf_list_pop_back]) {
+ struct btf_field *field = meta.arg_list_head.field;
+
+ mark_reg_known_zero(env, regs, BPF_REG_0);
+ regs[BPF_REG_0].type = PTR_TO_BTF_ID | MEM_ALLOC;
+- regs[BPF_REG_0].btf = field->list_head.btf;
+- regs[BPF_REG_0].btf_id = field->list_head.value_btf_id;
+- regs[BPF_REG_0].off = field->list_head.node_offset;
++ regs[BPF_REG_0].btf = field->graph_root.btf;
++ regs[BPF_REG_0].btf_id = field->graph_root.value_btf_id;
++ regs[BPF_REG_0].off = field->graph_root.node_offset;
+ } else if (meta.func_id == special_kfunc_list[KF_bpf_cast_to_kern_ctx]) {
+ mark_reg_known_zero(env, regs, BPF_REG_0);
+ regs[BPF_REG_0].type = PTR_TO_BTF_ID | PTR_TRUSTED;
+@@ -9528,10 +9918,18 @@ static int check_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
+ }
+ if (reg_may_point_to_spin_lock(&regs[BPF_REG_0]) && !regs[BPF_REG_0].id)
+ regs[BPF_REG_0].id = ++env->id_gen;
+- } /* else { add_kfunc_call() ensures it is btf_type_is_void(t) } */
++ } else if (btf_type_is_void(t)) {
++ if (meta.btf == btf_vmlinux && btf_id_set_contains(&special_kfunc_set, meta.func_id)) {
++ if (meta.func_id == special_kfunc_list[KF_bpf_obj_drop_impl]) {
++ insn_aux->kptr_struct_meta =
++ btf_find_struct_meta(meta.arg_obj_drop.btf,
++ meta.arg_obj_drop.btf_id);
++ }
++ }
++ }
+
+- nargs = btf_type_vlen(func_proto);
+- args = (const struct btf_param *)(func_proto + 1);
++ nargs = btf_type_vlen(meta.func_proto);
++ args = (const struct btf_param *)(meta.func_proto + 1);
+ for (i = 0; i < nargs; i++) {
+ u32 regno = i + 1;
+
+@@ -11711,8 +12109,10 @@ static void mark_ptr_or_null_reg(struct bpf_func_state *state,
+ */
+ if (WARN_ON_ONCE(reg->smin_value || reg->smax_value || !tnum_equals_const(reg->var_off, 0)))
+ return;
+- if (reg->type != (PTR_TO_BTF_ID | MEM_ALLOC | PTR_MAYBE_NULL) && WARN_ON_ONCE(reg->off))
++ if (!(type_is_ptr_alloc_obj(reg->type) || type_is_non_owning_ref(reg->type)) &&
++ WARN_ON_ONCE(reg->off))
+ return;
++
+ if (is_null) {
+ reg->type = SCALAR_VALUE;
+ /* We don't need id and ref_obj_id from this point
+@@ -13674,10 +14074,11 @@ static int propagate_precision(struct bpf_verifier_env *env,
+ state_reg = state->regs;
+ for (i = 0; i < BPF_REG_FP; i++, state_reg++) {
+ if (state_reg->type != SCALAR_VALUE ||
+- !state_reg->precise)
++ !state_reg->precise ||
++ !(state_reg->live & REG_LIVE_READ))
+ continue;
+ if (env->log.level & BPF_LOG_LEVEL2)
+- verbose(env, "frame %d: propagating r%d\n", i, fr);
++ verbose(env, "frame %d: propagating r%d\n", fr, i);
+ err = mark_chain_precision_frame(env, fr, i);
+ if (err < 0)
+ return err;
+@@ -13688,11 +14089,12 @@ static int propagate_precision(struct bpf_verifier_env *env,
+ continue;
+ state_reg = &state->stack[i].spilled_ptr;
+ if (state_reg->type != SCALAR_VALUE ||
+- !state_reg->precise)
++ !state_reg->precise ||
++ !(state_reg->live & REG_LIVE_READ))
+ continue;
+ if (env->log.level & BPF_LOG_LEVEL2)
+ verbose(env, "frame %d: propagating fp%d\n",
+- (-i - 1) * BPF_REG_SIZE, fr);
++ fr, (-i - 1) * BPF_REG_SIZE);
+ err = mark_chain_precision_stack_frame(env, fr, i);
+ if (err < 0)
+ return err;
+@@ -14216,7 +14618,7 @@ static int do_check(struct bpf_verifier_env *env)
+ if ((insn->src_reg == BPF_REG_0 && insn->imm != BPF_FUNC_spin_unlock) ||
+ (insn->src_reg == BPF_PSEUDO_CALL) ||
+ (insn->src_reg == BPF_PSEUDO_KFUNC_CALL &&
+- (insn->off != 0 || !is_bpf_list_api_kfunc(insn->imm)))) {
++ (insn->off != 0 || !is_bpf_graph_api_kfunc(insn->imm)))) {
+ verbose(env, "function calls are not allowed while holding a lock\n");
+ return -EINVAL;
+ }
+@@ -14252,7 +14654,8 @@ static int do_check(struct bpf_verifier_env *env)
+ return -EINVAL;
+ }
+
+- if (env->cur_state->active_lock.ptr) {
++ if (env->cur_state->active_lock.ptr &&
++ !in_rbtree_lock_required_cb(env)) {
+ verbose(env, "bpf_spin_unlock is missing\n");
+ return -EINVAL;
+ }
+@@ -14514,9 +14917,10 @@ static int check_map_prog_compatibility(struct bpf_verifier_env *env,
+ {
+ enum bpf_prog_type prog_type = resolve_prog_type(prog);
+
+- if (btf_record_has_field(map->record, BPF_LIST_HEAD)) {
++ if (btf_record_has_field(map->record, BPF_LIST_HEAD) ||
++ btf_record_has_field(map->record, BPF_RB_ROOT)) {
+ if (is_tracing_prog_type(prog_type)) {
+- verbose(env, "tracing progs cannot use bpf_list_head yet\n");
++ verbose(env, "tracing progs cannot use bpf_{list_head,rb_root} yet\n");
+ return -EINVAL;
+ }
+ }
+@@ -16115,21 +16519,21 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
+ BUILD_BUG_ON(!__same_type(ops->map_lookup_elem,
+ (void *(*)(struct bpf_map *map, void *key))NULL));
+ BUILD_BUG_ON(!__same_type(ops->map_delete_elem,
+- (int (*)(struct bpf_map *map, void *key))NULL));
++ (long (*)(struct bpf_map *map, void *key))NULL));
+ BUILD_BUG_ON(!__same_type(ops->map_update_elem,
+- (int (*)(struct bpf_map *map, void *key, void *value,
++ (long (*)(struct bpf_map *map, void *key, void *value,
+ u64 flags))NULL));
+ BUILD_BUG_ON(!__same_type(ops->map_push_elem,
+- (int (*)(struct bpf_map *map, void *value,
++ (long (*)(struct bpf_map *map, void *value,
+ u64 flags))NULL));
+ BUILD_BUG_ON(!__same_type(ops->map_pop_elem,
+- (int (*)(struct bpf_map *map, void *value))NULL));
++ (long (*)(struct bpf_map *map, void *value))NULL));
+ BUILD_BUG_ON(!__same_type(ops->map_peek_elem,
+- (int (*)(struct bpf_map *map, void *value))NULL));
++ (long (*)(struct bpf_map *map, void *value))NULL));
+ BUILD_BUG_ON(!__same_type(ops->map_redirect,
+- (int (*)(struct bpf_map *map, u64 index, u64 flags))NULL));
++ (long (*)(struct bpf_map *map, u64 index, u64 flags))NULL));
+ BUILD_BUG_ON(!__same_type(ops->map_for_each_callback,
+- (int (*)(struct bpf_map *map,
++ (long (*)(struct bpf_map *map,
+ bpf_callback_t callback_fn,
+ void *callback_ctx,
+ u64 flags))NULL));
+diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
+index ef3bc3a5bbed3..81f40821084ec 100644
+--- a/kernel/dma/swiotlb.c
++++ b/kernel/dma/swiotlb.c
+@@ -935,7 +935,9 @@ EXPORT_SYMBOL_GPL(is_swiotlb_active);
+
+ static int io_tlb_used_get(void *data, u64 *val)
+ {
+- *val = mem_used(&io_tlb_default_mem);
++ struct io_tlb_mem *mem = data;
++
++ *val = mem_used(mem);
+ return 0;
+ }
+ DEFINE_DEBUGFS_ATTRIBUTE(fops_io_tlb_used, io_tlb_used_get, NULL, "%llu\n");
+@@ -948,7 +950,7 @@ static void swiotlb_create_debugfs_files(struct io_tlb_mem *mem,
+ return;
+
+ debugfs_create_ulong("io_tlb_nslabs", 0400, mem->debugfs, &mem->nslabs);
+- debugfs_create_file("io_tlb_used", 0400, mem->debugfs, NULL,
++ debugfs_create_file("io_tlb_used", 0400, mem->debugfs, mem,
+ &fops_io_tlb_used);
+ }
+
+@@ -1003,6 +1005,11 @@ static int rmem_swiotlb_device_init(struct reserved_mem *rmem,
+ /* Set Per-device io tlb area to one */
+ unsigned int nareas = 1;
+
++ if (PageHighMem(pfn_to_page(PHYS_PFN(rmem->base)))) {
++ dev_err(dev, "Restricted DMA pool must be accessible within the linear mapping.");
++ return -EINVAL;
++ }
++
+ /*
+ * Since multiple devices can share the same pool, the private data,
+ * io_tlb_mem struct, will be initialized by the first device attached
+@@ -1064,11 +1071,6 @@ static int __init rmem_swiotlb_setup(struct reserved_mem *rmem)
+ of_get_flat_dt_prop(node, "no-map", NULL))
+ return -EINVAL;
+
+- if (PageHighMem(pfn_to_page(PHYS_PFN(rmem->base)))) {
+- pr_err("Restricted DMA pool must be accessible within the linear mapping.");
+- return -EINVAL;
+- }
+-
+ rmem->ops = &rmem_swiotlb_ops;
+ pr_info("Reserved memory: created restricted DMA pool at %pa, size %ld MiB\n",
+ &rmem->base, (unsigned long)rmem->size / SZ_1M);
+diff --git a/kernel/events/core.c b/kernel/events/core.c
+index daecb8c9126b0..2290d67ade41d 100644
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -9408,8 +9408,8 @@ __perf_event_account_interrupt(struct perf_event *event, int throttle)
+ hwc->interrupts = 1;
+ } else {
+ hwc->interrupts++;
+- if (unlikely(throttle
+- && hwc->interrupts >= max_samples_per_tick)) {
++ if (unlikely(throttle &&
++ hwc->interrupts > max_samples_per_tick)) {
+ __this_cpu_inc(perf_throttled_count);
+ tick_dep_set_cpu(smp_processor_id(), TICK_DEP_BIT_PERF_EVENTS);
+ hwc->interrupts = MAX_INTERRUPTS;
+diff --git a/kernel/kcsan/core.c b/kernel/kcsan/core.c
+index 54d077e1a2dc7..5a60cc52adc0c 100644
+--- a/kernel/kcsan/core.c
++++ b/kernel/kcsan/core.c
+@@ -337,11 +337,20 @@ static void delay_access(int type)
+ */
+ static __always_inline u64 read_instrumented_memory(const volatile void *ptr, size_t size)
+ {
++ /*
++ * In the below we don't necessarily need the read of the location to
++ * be atomic, and we don't use READ_ONCE(), since all we need for race
++ * detection is to observe 2 different values.
++ *
++ * Furthermore, on certain architectures (such as arm64), READ_ONCE()
++ * may turn into more complex instructions than a plain load that cannot
++ * do unaligned accesses.
++ */
+ switch (size) {
+- case 1: return READ_ONCE(*(const u8 *)ptr);
+- case 2: return READ_ONCE(*(const u16 *)ptr);
+- case 4: return READ_ONCE(*(const u32 *)ptr);
+- case 8: return READ_ONCE(*(const u64 *)ptr);
++ case 1: return *(const volatile u8 *)ptr;
++ case 2: return *(const volatile u16 *)ptr;
++ case 4: return *(const volatile u32 *)ptr;
++ case 8: return *(const volatile u64 *)ptr;
+ default: return 0; /* Ignore; we do not diff the values. */
+ }
+ }
+diff --git a/kernel/kheaders.c b/kernel/kheaders.c
+index 8f69772af77b4..42163c9e94e55 100644
+--- a/kernel/kheaders.c
++++ b/kernel/kheaders.c
+@@ -26,15 +26,15 @@ asm (
+ " .popsection \n"
+ );
+
+-extern char kernel_headers_data;
+-extern char kernel_headers_data_end;
++extern char kernel_headers_data[];
++extern char kernel_headers_data_end[];
+
+ static ssize_t
+ ikheaders_read(struct file *file, struct kobject *kobj,
+ struct bin_attribute *bin_attr,
+ char *buf, loff_t off, size_t len)
+ {
+- memcpy(buf, &kernel_headers_data + off, len);
++ memcpy(buf, &kernel_headers_data[off], len);
+ return len;
+ }
+
+@@ -48,8 +48,8 @@ static struct bin_attribute kheaders_attr __ro_after_init = {
+
+ static int __init ikheaders_init(void)
+ {
+- kheaders_attr.size = (&kernel_headers_data_end -
+- &kernel_headers_data);
++ kheaders_attr.size = (kernel_headers_data_end -
++ kernel_headers_data);
+ return sysfs_create_bin_file(kernel_kobj, &kheaders_attr);
+ }
+
+diff --git a/kernel/module/decompress.c b/kernel/module/decompress.c
+index bb79ac1a6d8f7..7ddc87bee2741 100644
+--- a/kernel/module/decompress.c
++++ b/kernel/module/decompress.c
+@@ -267,7 +267,7 @@ static ssize_t module_zstd_decompress(struct load_info *info,
+ zstd_dec.size = PAGE_SIZE;
+
+ ret = zstd_decompress_stream(dstream, &zstd_dec, &zstd_buf);
+- kunmap(page);
++ kunmap_local(zstd_dec.dst);
+ retval = zstd_get_error_code(ret);
+ if (retval)
+ break;
+diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
+index 793c55a2becba..30d1274f03f62 100644
+--- a/kernel/power/hibernate.c
++++ b/kernel/power/hibernate.c
+@@ -64,6 +64,7 @@ enum {
+ static int hibernation_mode = HIBERNATION_SHUTDOWN;
+
+ bool freezer_test_done;
++bool snapshot_test;
+
+ static const struct platform_hibernation_ops *hibernation_ops;
+
+@@ -687,18 +688,22 @@ static int load_image_and_restore(void)
+ {
+ int error;
+ unsigned int flags;
++ fmode_t mode = FMODE_READ;
++
++ if (snapshot_test)
++ mode |= FMODE_EXCL;
+
+ pm_pr_dbg("Loading hibernation image.\n");
+
+ lock_device_hotplug();
+ error = create_basic_memory_bitmaps();
+ if (error) {
+- swsusp_close(FMODE_READ | FMODE_EXCL);
++ swsusp_close(mode);
+ goto Unlock;
+ }
+
+ error = swsusp_read(&flags);
+- swsusp_close(FMODE_READ | FMODE_EXCL);
++ swsusp_close(mode);
+ if (!error)
+ error = hibernation_restore(flags & SF_PLATFORM_MODE);
+
+@@ -716,7 +721,6 @@ static int load_image_and_restore(void)
+ */
+ int hibernate(void)
+ {
+- bool snapshot_test = false;
+ unsigned int sleep_flags;
+ int error;
+
+@@ -744,6 +748,9 @@ int hibernate(void)
+ if (error)
+ goto Exit;
+
++ /* protected by system_transition_mutex */
++ snapshot_test = false;
++
+ lock_device_hotplug();
+ /* Allocate memory management structures */
+ error = create_basic_memory_bitmaps();
+@@ -940,6 +947,8 @@ static int software_resume(void)
+ */
+ mutex_lock_nested(&system_transition_mutex, SINGLE_DEPTH_NESTING);
+
++ snapshot_test = false;
++
+ if (swsusp_resume_device)
+ goto Check_image;
+
+diff --git a/kernel/power/power.h b/kernel/power/power.h
+index b4f4339432096..b83c8d5e188de 100644
+--- a/kernel/power/power.h
++++ b/kernel/power/power.h
+@@ -59,6 +59,7 @@ asmlinkage int swsusp_save(void);
+
+ /* kernel/power/hibernate.c */
+ extern bool freezer_test_done;
++extern bool snapshot_test;
+
+ extern int hibernation_snapshot(int platform_mode);
+ extern int hibernation_restore(int platform_mode);
+diff --git a/kernel/power/swap.c b/kernel/power/swap.c
+index 277434b6c0bfd..cc44c37699de6 100644
+--- a/kernel/power/swap.c
++++ b/kernel/power/swap.c
+@@ -1518,9 +1518,13 @@ int swsusp_check(void)
+ {
+ int error;
+ void *holder;
++ fmode_t mode = FMODE_READ;
++
++ if (snapshot_test)
++ mode |= FMODE_EXCL;
+
+ hib_resume_bdev = blkdev_get_by_dev(swsusp_resume_device,
+- FMODE_READ | FMODE_EXCL, &holder);
++ mode, &holder);
+ if (!IS_ERR(hib_resume_bdev)) {
+ set_blocksize(hib_resume_bdev, PAGE_SIZE);
+ clear_page(swsusp_header);
+@@ -1547,7 +1551,7 @@ int swsusp_check(void)
+
+ put:
+ if (error)
+- blkdev_put(hib_resume_bdev, FMODE_READ | FMODE_EXCL);
++ blkdev_put(hib_resume_bdev, mode);
+ else
+ pr_debug("Image signature found, resuming\n");
+ } else {
+diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
+index 5221291937713..20f5492e6a07b 100644
+--- a/kernel/rcu/tree.c
++++ b/kernel/rcu/tree.c
+@@ -659,6 +659,7 @@ void __rcu_irq_enter_check_tick(void)
+ }
+ raw_spin_unlock_rcu_node(rdp->mynode);
+ }
++NOKPROBE_SYMBOL(__rcu_irq_enter_check_tick);
+ #endif /* CONFIG_NO_HZ_FULL */
+
+ /*
+diff --git a/kernel/relay.c b/kernel/relay.c
+index ef12532168d9c..e16efd55571ca 100644
+--- a/kernel/relay.c
++++ b/kernel/relay.c
+@@ -989,7 +989,8 @@ static size_t relay_file_read_start_pos(struct rchan_buf *buf)
+ size_t subbuf_size = buf->chan->subbuf_size;
+ size_t n_subbufs = buf->chan->n_subbufs;
+ size_t consumed = buf->subbufs_consumed % n_subbufs;
+- size_t read_pos = consumed * subbuf_size + buf->bytes_consumed;
++ size_t read_pos = (consumed * subbuf_size + buf->bytes_consumed)
++ % (n_subbufs * subbuf_size);
+
+ read_subbuf = read_pos / subbuf_size;
+ padding = buf->padding[read_subbuf];
+diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
+index 0d97d54276cc8..238bdb36f8848 100644
+--- a/kernel/sched/deadline.c
++++ b/kernel/sched/deadline.c
+@@ -2246,6 +2246,7 @@ static struct rq *find_lock_later_rq(struct task_struct *task, struct rq *rq)
+ !cpumask_test_cpu(later_rq->cpu, &task->cpus_mask) ||
+ task_on_cpu(rq, task) ||
+ !dl_task(task) ||
++ is_migration_disabled(task) ||
+ !task_on_rq_queued(task))) {
+ double_unlock_balance(rq, later_rq);
+ later_rq = NULL;
+diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
+index 661226e38835d..6f1c7a8fa12ab 100644
+--- a/kernel/sched/fair.c
++++ b/kernel/sched/fair.c
+@@ -6487,7 +6487,7 @@ static int wake_affine(struct sched_domain *sd, struct task_struct *p,
+ target = wake_affine_weight(sd, p, this_cpu, prev_cpu, sync);
+
+ schedstat_inc(p->stats.nr_wakeups_affine_attempts);
+- if (target == nr_cpumask_bits)
++ if (target != this_cpu)
+ return prev_cpu;
+
+ schedstat_inc(sd->ttwu_move_affine);
+diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
+index 0a11f44adee57..4f5796dd26a56 100644
+--- a/kernel/sched/rt.c
++++ b/kernel/sched/rt.c
+@@ -2000,11 +2000,15 @@ static struct rq *find_lock_lowest_rq(struct task_struct *task, struct rq *rq)
+ * the mean time, task could have
+ * migrated already or had its affinity changed.
+ * Also make sure that it wasn't scheduled on its rq.
++ * It is possible the task was scheduled, set
++ * "migrate_disabled" and then got preempted, so we must
++ * check the task migration disable flag here too.
+ */
+ if (unlikely(task_rq(task) != rq ||
+ !cpumask_test_cpu(lowest_rq->cpu, &task->cpus_mask) ||
+ task_on_cpu(rq, task) ||
+ !rt_task(task) ||
++ is_migration_disabled(task) ||
+ !task_on_rq_queued(task))) {
+
+ double_unlock_balance(rq, lowest_rq);
+diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c
+index cb925e8ef9a8b..44b25ff35d28a 100644
+--- a/kernel/time/posix-cpu-timers.c
++++ b/kernel/time/posix-cpu-timers.c
+@@ -847,6 +847,8 @@ static u64 collect_timerqueue(struct timerqueue_head *head,
+ return expires;
+
+ ctmr->firing = 1;
++ /* See posix_cpu_timer_wait_running() */
++ rcu_assign_pointer(ctmr->handling, current);
+ cpu_timer_dequeue(ctmr);
+ list_add_tail(&ctmr->elist, firing);
+ }
+@@ -1162,7 +1164,49 @@ static void handle_posix_cpu_timers(struct task_struct *tsk);
+ #ifdef CONFIG_POSIX_CPU_TIMERS_TASK_WORK
+ static void posix_cpu_timers_work(struct callback_head *work)
+ {
++ struct posix_cputimers_work *cw = container_of(work, typeof(*cw), work);
++
++ mutex_lock(&cw->mutex);
+ handle_posix_cpu_timers(current);
++ mutex_unlock(&cw->mutex);
++}
++
++/*
++ * Invoked from the posix-timer core when a cancel operation failed because
++ * the timer is marked firing. The caller holds rcu_read_lock(), which
++ * protects the timer and the task which is expiring it from being freed.
++ */
++static void posix_cpu_timer_wait_running(struct k_itimer *timr)
++{
++ struct task_struct *tsk = rcu_dereference(timr->it.cpu.handling);
++
++ /* Has the handling task completed expiry already? */
++ if (!tsk)
++ return;
++
++ /* Ensure that the task cannot go away */
++ get_task_struct(tsk);
++ /* Now drop the RCU protection so the mutex can be locked */
++ rcu_read_unlock();
++ /* Wait on the expiry mutex */
++ mutex_lock(&tsk->posix_cputimers_work.mutex);
++ /* Release it immediately again. */
++ mutex_unlock(&tsk->posix_cputimers_work.mutex);
++ /* Drop the task reference. */
++ put_task_struct(tsk);
++ /* Relock RCU so the callsite is balanced */
++ rcu_read_lock();
++}
++
++static void posix_cpu_timer_wait_running_nsleep(struct k_itimer *timr)
++{
++ /* Ensure that timr->it.cpu.handling task cannot go away */
++ rcu_read_lock();
++ spin_unlock_irq(&timr->it_lock);
++ posix_cpu_timer_wait_running(timr);
++ rcu_read_unlock();
++ /* @timr is on stack and is valid */
++ spin_lock_irq(&timr->it_lock);
+ }
+
+ /*
+@@ -1178,6 +1222,7 @@ void clear_posix_cputimers_work(struct task_struct *p)
+ sizeof(p->posix_cputimers_work.work));
+ init_task_work(&p->posix_cputimers_work.work,
+ posix_cpu_timers_work);
++ mutex_init(&p->posix_cputimers_work.mutex);
+ p->posix_cputimers_work.scheduled = false;
+ }
+
+@@ -1256,6 +1301,18 @@ static inline void __run_posix_cpu_timers(struct task_struct *tsk)
+ lockdep_posixtimer_exit();
+ }
+
++static void posix_cpu_timer_wait_running(struct k_itimer *timr)
++{
++ cpu_relax();
++}
++
++static void posix_cpu_timer_wait_running_nsleep(struct k_itimer *timr)
++{
++ spin_unlock_irq(&timr->it_lock);
++ cpu_relax();
++ spin_lock_irq(&timr->it_lock);
++}
++
+ static inline bool posix_cpu_timers_work_scheduled(struct task_struct *tsk)
+ {
+ return false;
+@@ -1364,6 +1421,8 @@ static void handle_posix_cpu_timers(struct task_struct *tsk)
+ */
+ if (likely(cpu_firing >= 0))
+ cpu_timer_fire(timer);
++ /* See posix_cpu_timer_wait_running() */
++ rcu_assign_pointer(timer->it.cpu.handling, NULL);
+ spin_unlock(&timer->it_lock);
+ }
+ }
+@@ -1498,23 +1557,16 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags,
+ expires = cpu_timer_getexpires(&timer.it.cpu);
+ error = posix_cpu_timer_set(&timer, 0, &zero_it, &it);
+ if (!error) {
+- /*
+- * Timer is now unarmed, deletion can not fail.
+- */
++ /* Timer is now unarmed, deletion can not fail. */
+ posix_cpu_timer_del(&timer);
++ } else {
++ while (error == TIMER_RETRY) {
++ posix_cpu_timer_wait_running_nsleep(&timer);
++ error = posix_cpu_timer_del(&timer);
++ }
+ }
+- spin_unlock_irq(&timer.it_lock);
+
+- while (error == TIMER_RETRY) {
+- /*
+- * We need to handle case when timer was or is in the
+- * middle of firing. In other cases we already freed
+- * resources.
+- */
+- spin_lock_irq(&timer.it_lock);
+- error = posix_cpu_timer_del(&timer);
+- spin_unlock_irq(&timer.it_lock);
+- }
++ spin_unlock_irq(&timer.it_lock);
+
+ if ((it.it_value.tv_sec | it.it_value.tv_nsec) == 0) {
+ /*
+@@ -1624,6 +1676,7 @@ const struct k_clock clock_posix_cpu = {
+ .timer_del = posix_cpu_timer_del,
+ .timer_get = posix_cpu_timer_get,
+ .timer_rearm = posix_cpu_timer_rearm,
++ .timer_wait_running = posix_cpu_timer_wait_running,
+ };
+
+ const struct k_clock clock_process = {
+diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
+index 0c8a87a11b39d..808a247205a9a 100644
+--- a/kernel/time/posix-timers.c
++++ b/kernel/time/posix-timers.c
+@@ -846,6 +846,10 @@ static struct k_itimer *timer_wait_running(struct k_itimer *timer,
+ rcu_read_lock();
+ unlock_timer(timer, *flags);
+
++ /*
++ * kc->timer_wait_running() might drop RCU lock. So @timer
++ * cannot be touched anymore after the function returns!
++ */
+ if (!WARN_ON_ONCE(!kc->timer_wait_running))
+ kc->timer_wait_running(timer);
+
+diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
+index 46789356f856e..65b8658da829e 100644
+--- a/kernel/time/tick-common.c
++++ b/kernel/time/tick-common.c
+@@ -218,9 +218,19 @@ static void tick_setup_device(struct tick_device *td,
+ * this cpu:
+ */
+ if (tick_do_timer_cpu == TICK_DO_TIMER_BOOT) {
++ ktime_t next_p;
++ u32 rem;
++
+ tick_do_timer_cpu = cpu;
+
+- tick_next_period = ktime_get();
++ next_p = ktime_get();
++ div_u64_rem(next_p, TICK_NSEC, &rem);
++ if (rem) {
++ next_p -= rem;
++ next_p += TICK_NSEC;
++ }
++
++ tick_next_period = next_p;
+ #ifdef CONFIG_NO_HZ_FULL
+ /*
+ * The boot CPU may be nohz_full, in which case set
+diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
+index b0e3c9205946f..a46506f7ec6d0 100644
+--- a/kernel/time/tick-sched.c
++++ b/kernel/time/tick-sched.c
+@@ -281,6 +281,11 @@ static bool check_tick_dependency(atomic_t *dep)
+ return true;
+ }
+
++ if (val & TICK_DEP_MASK_RCU_EXP) {
++ trace_tick_stop(0, TICK_DEP_MASK_RCU_EXP);
++ return true;
++ }
++
+ return false;
+ }
+
+@@ -527,7 +532,7 @@ void __init tick_nohz_full_setup(cpumask_var_t cpumask)
+ tick_nohz_full_running = true;
+ }
+
+-static int tick_nohz_cpu_down(unsigned int cpu)
++bool tick_nohz_cpu_hotpluggable(unsigned int cpu)
+ {
+ /*
+ * The tick_do_timer_cpu CPU handles housekeeping duty (unbound
+@@ -535,8 +540,13 @@ static int tick_nohz_cpu_down(unsigned int cpu)
+ * CPUs. It must remain online when nohz full is enabled.
+ */
+ if (tick_nohz_full_running && tick_do_timer_cpu == cpu)
+- return -EBUSY;
+- return 0;
++ return false;
++ return true;
++}
++
++static int tick_nohz_cpu_down(unsigned int cpu)
++{
++ return tick_nohz_cpu_hotpluggable(cpu) ? 0 : -EBUSY;
+ }
+
+ void __init tick_nohz_init(void)
+diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
+index 5579ead449f25..09d594900ee0b 100644
+--- a/kernel/time/timekeeping.c
++++ b/kernel/time/timekeeping.c
+@@ -526,7 +526,7 @@ EXPORT_SYMBOL_GPL(ktime_get_raw_fast_ns);
+ * partially updated. Since the tk->offs_boot update is a rare event, this
+ * should be a rare occurrence which postprocessing should be able to handle.
+ *
+- * The caveats vs. timestamp ordering as documented for ktime_get_fast_ns()
++ * The caveats vs. timestamp ordering as documented for ktime_get_mono_fast_ns()
+ * apply as well.
+ */
+ u64 notrace ktime_get_boot_fast_ns(void)
+@@ -576,7 +576,7 @@ static __always_inline u64 __ktime_get_real_fast(struct tk_fast *tkf, u64 *mono)
+ /**
+ * ktime_get_real_fast_ns: - NMI safe and fast access to clock realtime.
+ *
+- * See ktime_get_fast_ns() for documentation of the time stamp ordering.
++ * See ktime_get_mono_fast_ns() for documentation of the time stamp ordering.
+ */
+ u64 ktime_get_real_fast_ns(void)
+ {
+diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
+index 12da17243747d..6f8b9e3b144c6 100644
+--- a/kernel/trace/ring_buffer.c
++++ b/kernel/trace/ring_buffer.c
+@@ -1778,6 +1778,8 @@ static void rb_free_cpu_buffer(struct ring_buffer_per_cpu *cpu_buffer)
+ struct list_head *head = cpu_buffer->pages;
+ struct buffer_page *bpage, *tmp;
+
++ irq_work_sync(&cpu_buffer->irq_work.work);
++
+ free_buffer_page(cpu_buffer->reader_page);
+
+ if (head) {
+@@ -1884,6 +1886,8 @@ ring_buffer_free(struct trace_buffer *buffer)
+
+ cpuhp_state_remove_instance(CPUHP_TRACE_RB_PREPARE, &buffer->node);
+
++ irq_work_sync(&buffer->irq_work.work);
++
+ for_each_buffer_cpu(buffer, cpu)
+ rb_free_cpu_buffer(buffer->buffers[cpu]);
+
+@@ -5349,6 +5353,9 @@ void ring_buffer_reset_cpu(struct trace_buffer *buffer, int cpu)
+ }
+ EXPORT_SYMBOL_GPL(ring_buffer_reset_cpu);
+
++/* Flag to ensure proper resetting of atomic variables */
++#define RESET_BIT (1 << 30)
++
+ /**
+ * ring_buffer_reset_online_cpus - reset a ring buffer per CPU buffer
+ * @buffer: The ring buffer to reset a per cpu buffer of
+@@ -5365,20 +5372,27 @@ void ring_buffer_reset_online_cpus(struct trace_buffer *buffer)
+ for_each_online_buffer_cpu(buffer, cpu) {
+ cpu_buffer = buffer->buffers[cpu];
+
+- atomic_inc(&cpu_buffer->resize_disabled);
++ atomic_add(RESET_BIT, &cpu_buffer->resize_disabled);
+ atomic_inc(&cpu_buffer->record_disabled);
+ }
+
+ /* Make sure all commits have finished */
+ synchronize_rcu();
+
+- for_each_online_buffer_cpu(buffer, cpu) {
++ for_each_buffer_cpu(buffer, cpu) {
+ cpu_buffer = buffer->buffers[cpu];
+
++ /*
++ * If a CPU came online during the synchronize_rcu(), then
++ * ignore it.
++ */
++ if (!(atomic_read(&cpu_buffer->resize_disabled) & RESET_BIT))
++ continue;
++
+ reset_disabled_cpu_buffer(cpu_buffer);
+
+ atomic_dec(&cpu_buffer->record_disabled);
+- atomic_dec(&cpu_buffer->resize_disabled);
++ atomic_sub(RESET_BIT, &cpu_buffer->resize_disabled);
+ }
+
+ mutex_unlock(&buffer->mutex);
+diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
+index 13b324f008256..a61a96569ef5a 100644
+--- a/kernel/trace/trace.c
++++ b/kernel/trace/trace.c
+@@ -9621,7 +9621,7 @@ init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer)
+
+ tr->buffer_percent = 50;
+
+- trace_create_file("buffer_percent", TRACE_MODE_READ, d_tracer,
++ trace_create_file("buffer_percent", TRACE_MODE_WRITE, d_tracer,
+ tr, &buffer_percent_fops);
+
+ create_trace_options_dir(tr);
+diff --git a/kernel/trace/trace_events_user.c b/kernel/trace/trace_events_user.c
+index 908e8a13c675b..625cab4b9d945 100644
+--- a/kernel/trace/trace_events_user.c
++++ b/kernel/trace/trace_events_user.c
+@@ -1398,6 +1398,9 @@ static ssize_t user_events_write_core(struct file *file, struct iov_iter *i)
+ if (unlikely(copy_from_iter(&idx, sizeof(idx), i) != sizeof(idx)))
+ return -EFAULT;
+
++ if (idx < 0)
++ return -EINVAL;
++
+ rcu_read_lock_sched();
+
+ refs = rcu_dereference_sched(info->refs);
+diff --git a/kernel/workqueue.c b/kernel/workqueue.c
+index 76ea87b0251ce..e5421775deb38 100644
+--- a/kernel/workqueue.c
++++ b/kernel/workqueue.c
+@@ -4850,10 +4850,16 @@ static void show_one_worker_pool(struct worker_pool *pool)
+ struct worker *worker;
+ bool first = true;
+ unsigned long flags;
++ unsigned long hung = 0;
+
+ raw_spin_lock_irqsave(&pool->lock, flags);
+ if (pool->nr_workers == pool->nr_idle)
+ goto next_pool;
++
++ /* How long the first pending work is waiting for a worker. */
++ if (!list_empty(&pool->worklist))
++ hung = jiffies_to_msecs(jiffies - pool->watchdog_ts) / 1000;
++
+ /*
+ * Defer printing to avoid deadlocks in console drivers that
+ * queue work while holding locks also taken in their write
+@@ -4862,9 +4868,7 @@ static void show_one_worker_pool(struct worker_pool *pool)
+ printk_deferred_enter();
+ pr_info("pool %d:", pool->id);
+ pr_cont_pool_info(pool);
+- pr_cont(" hung=%us workers=%d",
+- jiffies_to_msecs(jiffies - pool->watchdog_ts) / 1000,
+- pool->nr_workers);
++ pr_cont(" hung=%lus workers=%d", hung, pool->nr_workers);
+ if (pool->manager)
+ pr_cont(" manager: %d",
+ task_pid_nr(pool->manager->task));
+diff --git a/lib/debugobjects.c b/lib/debugobjects.c
+index df86e649d8be0..003edc5ebd673 100644
+--- a/lib/debugobjects.c
++++ b/lib/debugobjects.c
+@@ -216,10 +216,6 @@ static struct debug_obj *__alloc_object(struct hlist_head *list)
+ return obj;
+ }
+
+-/*
+- * Allocate a new object. If the pool is empty, switch off the debugger.
+- * Must be called with interrupts disabled.
+- */
+ static struct debug_obj *
+ alloc_object(void *addr, struct debug_bucket *b, const struct debug_obj_descr *descr)
+ {
+@@ -552,36 +548,74 @@ static void debug_object_is_on_stack(void *addr, int onstack)
+ WARN_ON(1);
+ }
+
+-static void
+-__debug_object_init(void *addr, const struct debug_obj_descr *descr, int onstack)
++static struct debug_obj *lookup_object_or_alloc(void *addr, struct debug_bucket *b,
++ const struct debug_obj_descr *descr,
++ bool onstack, bool alloc_ifstatic)
+ {
+- enum debug_obj_state state;
+- bool check_stack = false;
+- struct debug_bucket *db;
+- struct debug_obj *obj;
+- unsigned long flags;
++ struct debug_obj *obj = lookup_object(addr, b);
++ enum debug_obj_state state = ODEBUG_STATE_NONE;
++
++ if (likely(obj))
++ return obj;
++
++ /*
++ * debug_object_init() unconditionally allocates untracked
++ * objects. It does not matter whether it is a static object or
++ * not.
++ *
++ * debug_object_assert_init() and debug_object_activate() allow
++ * allocation only if the descriptor callback confirms that the
++ * object is static and considered initialized. For non-static
++ * objects the allocation needs to be done from the fixup callback.
++ */
++ if (unlikely(alloc_ifstatic)) {
++ if (!descr->is_static_object || !descr->is_static_object(addr))
++ return ERR_PTR(-ENOENT);
++ /* Statically allocated objects are considered initialized */
++ state = ODEBUG_STATE_INIT;
++ }
++
++ obj = alloc_object(addr, b, descr);
++ if (likely(obj)) {
++ obj->state = state;
++ debug_object_is_on_stack(addr, onstack);
++ return obj;
++ }
++
++ /* Out of memory. Do the cleanup outside of the locked region */
++ debug_objects_enabled = 0;
++ return NULL;
++}
+
++static void debug_objects_fill_pool(void)
++{
+ /*
+ * On RT enabled kernels the pool refill must happen in preemptible
+ * context:
+ */
+ if (!IS_ENABLED(CONFIG_PREEMPT_RT) || preemptible())
+ fill_pool();
++}
++
++static void
++__debug_object_init(void *addr, const struct debug_obj_descr *descr, int onstack)
++{
++ enum debug_obj_state state;
++ struct debug_bucket *db;
++ struct debug_obj *obj;
++ unsigned long flags;
++
++ debug_objects_fill_pool();
+
+ db = get_bucket((unsigned long) addr);
+
+ raw_spin_lock_irqsave(&db->lock, flags);
+
+- obj = lookup_object(addr, db);
+- if (!obj) {
+- obj = alloc_object(addr, db, descr);
+- if (!obj) {
+- debug_objects_enabled = 0;
+- raw_spin_unlock_irqrestore(&db->lock, flags);
+- debug_objects_oom();
+- return;
+- }
+- check_stack = true;
++ obj = lookup_object_or_alloc(addr, db, descr, onstack, false);
++ if (unlikely(!obj)) {
++ raw_spin_unlock_irqrestore(&db->lock, flags);
++ debug_objects_oom();
++ return;
+ }
+
+ switch (obj->state) {
+@@ -607,8 +641,6 @@ __debug_object_init(void *addr, const struct debug_obj_descr *descr, int onstack
+ }
+
+ raw_spin_unlock_irqrestore(&db->lock, flags);
+- if (check_stack)
+- debug_object_is_on_stack(addr, onstack);
+ }
+
+ /**
+@@ -648,24 +680,24 @@ EXPORT_SYMBOL_GPL(debug_object_init_on_stack);
+ */
+ int debug_object_activate(void *addr, const struct debug_obj_descr *descr)
+ {
++ struct debug_obj o = { .object = addr, .state = ODEBUG_STATE_NOTAVAILABLE, .descr = descr };
+ enum debug_obj_state state;
+ struct debug_bucket *db;
+ struct debug_obj *obj;
+ unsigned long flags;
+ int ret;
+- struct debug_obj o = { .object = addr,
+- .state = ODEBUG_STATE_NOTAVAILABLE,
+- .descr = descr };
+
+ if (!debug_objects_enabled)
+ return 0;
+
++ debug_objects_fill_pool();
++
+ db = get_bucket((unsigned long) addr);
+
+ raw_spin_lock_irqsave(&db->lock, flags);
+
+- obj = lookup_object(addr, db);
+- if (obj) {
++ obj = lookup_object_or_alloc(addr, db, descr, false, true);
++ if (likely(!IS_ERR_OR_NULL(obj))) {
+ bool print_object = false;
+
+ switch (obj->state) {
+@@ -698,24 +730,16 @@ int debug_object_activate(void *addr, const struct debug_obj_descr *descr)
+
+ raw_spin_unlock_irqrestore(&db->lock, flags);
+
+- /*
+- * We are here when a static object is activated. We
+- * let the type specific code confirm whether this is
+- * true or not. if true, we just make sure that the
+- * static object is tracked in the object tracker. If
+- * not, this must be a bug, so we try to fix it up.
+- */
+- if (descr->is_static_object && descr->is_static_object(addr)) {
+- /* track this static object */
+- debug_object_init(addr, descr);
+- debug_object_activate(addr, descr);
+- } else {
+- debug_print_object(&o, "activate");
+- ret = debug_object_fixup(descr->fixup_activate, addr,
+- ODEBUG_STATE_NOTAVAILABLE);
+- return ret ? 0 : -EINVAL;
++ /* If NULL the allocation has hit OOM */
++ if (!obj) {
++ debug_objects_oom();
++ return 0;
+ }
+- return 0;
++
++ /* Object is neither static nor tracked. It's not initialized */
++ debug_print_object(&o, "activate");
++ ret = debug_object_fixup(descr->fixup_activate, addr, ODEBUG_STATE_NOTAVAILABLE);
++ return ret ? 0 : -EINVAL;
+ }
+ EXPORT_SYMBOL_GPL(debug_object_activate);
+
+@@ -869,6 +893,7 @@ EXPORT_SYMBOL_GPL(debug_object_free);
+ */
+ void debug_object_assert_init(void *addr, const struct debug_obj_descr *descr)
+ {
++ struct debug_obj o = { .object = addr, .state = ODEBUG_STATE_NOTAVAILABLE, .descr = descr };
+ struct debug_bucket *db;
+ struct debug_obj *obj;
+ unsigned long flags;
+@@ -876,34 +901,25 @@ void debug_object_assert_init(void *addr, const struct debug_obj_descr *descr)
+ if (!debug_objects_enabled)
+ return;
+
++ debug_objects_fill_pool();
++
+ db = get_bucket((unsigned long) addr);
+
+ raw_spin_lock_irqsave(&db->lock, flags);
++ obj = lookup_object_or_alloc(addr, db, descr, false, true);
++ raw_spin_unlock_irqrestore(&db->lock, flags);
++ if (likely(!IS_ERR_OR_NULL(obj)))
++ return;
+
+- obj = lookup_object(addr, db);
++ /* If NULL the allocation has hit OOM */
+ if (!obj) {
+- struct debug_obj o = { .object = addr,
+- .state = ODEBUG_STATE_NOTAVAILABLE,
+- .descr = descr };
+-
+- raw_spin_unlock_irqrestore(&db->lock, flags);
+- /*
+- * Maybe the object is static, and we let the type specific
+- * code confirm. Track this static object if true, else invoke
+- * fixup.
+- */
+- if (descr->is_static_object && descr->is_static_object(addr)) {
+- /* Track this static object */
+- debug_object_init(addr, descr);
+- } else {
+- debug_print_object(&o, "assert_init");
+- debug_object_fixup(descr->fixup_assert_init, addr,
+- ODEBUG_STATE_NOTAVAILABLE);
+- }
++ debug_objects_oom();
+ return;
+ }
+
+- raw_spin_unlock_irqrestore(&db->lock, flags);
++ /* Object is neither tracked nor static. It's not initialized. */
++ debug_print_object(&o, "assert_init");
++ debug_object_fixup(descr->fixup_assert_init, addr, ODEBUG_STATE_NOTAVAILABLE);
+ }
+ EXPORT_SYMBOL_GPL(debug_object_assert_init);
+
+diff --git a/lib/kunit/debugfs.c b/lib/kunit/debugfs.c
+index de0ee2e03ed60..b08bb1fba106d 100644
+--- a/lib/kunit/debugfs.c
++++ b/lib/kunit/debugfs.c
+@@ -55,14 +55,24 @@ static int debugfs_print_results(struct seq_file *seq, void *v)
+ enum kunit_status success = kunit_suite_has_succeeded(suite);
+ struct kunit_case *test_case;
+
+- if (!suite || !suite->log)
++ if (!suite)
+ return 0;
+
+- seq_printf(seq, "%s", suite->log);
++ /* Print KTAP header so the debugfs log can be parsed as valid KTAP. */
++ seq_puts(seq, "KTAP version 1\n");
++ seq_puts(seq, "1..1\n");
++
++ /* Print suite header because it is not stored in the test logs. */
++ seq_puts(seq, KUNIT_SUBTEST_INDENT "KTAP version 1\n");
++ seq_printf(seq, KUNIT_SUBTEST_INDENT "# Subtest: %s\n", suite->name);
++ seq_printf(seq, KUNIT_SUBTEST_INDENT "1..%zd\n", kunit_suite_num_test_cases(suite));
+
+ kunit_suite_for_each_test_case(suite, test_case)
+ debugfs_print_result(seq, suite, test_case);
+
++ if (suite->log)
++ seq_printf(seq, "%s", suite->log);
++
+ seq_printf(seq, "%s %d %s\n",
+ kunit_status_to_ok_not_ok(success), 1, suite->name);
+ return 0;
+diff --git a/lib/kunit/test.c b/lib/kunit/test.c
+index 890ba5b3a9819..820f867e35f40 100644
+--- a/lib/kunit/test.c
++++ b/lib/kunit/test.c
+@@ -152,10 +152,18 @@ EXPORT_SYMBOL_GPL(kunit_suite_num_test_cases);
+
+ static void kunit_print_suite_start(struct kunit_suite *suite)
+ {
+- kunit_log(KERN_INFO, suite, KUNIT_SUBTEST_INDENT "KTAP version 1\n");
+- kunit_log(KERN_INFO, suite, KUNIT_SUBTEST_INDENT "# Subtest: %s",
++ /*
++ * We do not log the test suite header as doing so would
++ * mean debugfs display would consist of the test suite
++ * header prior to individual test results.
++ * Hence directly printk the suite status, and we will
++ * separately seq_printf() the suite header for the debugfs
++ * representation.
++ */
++ pr_info(KUNIT_SUBTEST_INDENT "KTAP version 1\n");
++ pr_info(KUNIT_SUBTEST_INDENT "# Subtest: %s\n",
+ suite->name);
+- kunit_log(KERN_INFO, suite, KUNIT_SUBTEST_INDENT "1..%zd",
++ pr_info(KUNIT_SUBTEST_INDENT "1..%zd\n",
+ kunit_suite_num_test_cases(suite));
+ }
+
+@@ -172,10 +180,9 @@ static void kunit_print_ok_not_ok(void *test_or_suite,
+
+ /*
+ * We do not log the test suite results as doing so would
+- * mean debugfs display would consist of the test suite
+- * description and status prior to individual test results.
+- * Hence directly printk the suite status, and we will
+- * separately seq_printf() the suite status for the debugfs
++ * mean debugfs display would consist of an incorrect test
++ * number. Hence directly printk the suite result, and we will
++ * separately seq_printf() the suite results for the debugfs
+ * representation.
+ */
+ if (suite)
+diff --git a/mm/kasan/hw_tags.c b/mm/kasan/hw_tags.c
+index b22c4f461cb0b..cc9bc99e47cd1 100644
+--- a/mm/kasan/hw_tags.c
++++ b/mm/kasan/hw_tags.c
+@@ -225,7 +225,7 @@ static void init_vmalloc_pages(const void *start, unsigned long size)
+ const void *addr;
+
+ for (addr = start; addr < start + size; addr += PAGE_SIZE) {
+- struct page *page = virt_to_page(addr);
++ struct page *page = vmalloc_to_page(addr);
+
+ clear_highpage_kasan_tagged(page);
+ }
+@@ -237,7 +237,7 @@ void *__kasan_unpoison_vmalloc(const void *start, unsigned long size,
+ u8 tag;
+ unsigned long redzone_start, redzone_size;
+
+- if (!kasan_vmalloc_enabled() || !is_vmalloc_or_module_addr(start)) {
++ if (!kasan_vmalloc_enabled()) {
+ if (flags & KASAN_VMALLOC_INIT)
+ init_vmalloc_pages(start, size);
+ return (void *)start;
+diff --git a/mm/mempolicy.c b/mm/mempolicy.c
+index e132f70a059e8..7d36dd95d1fff 100644
+--- a/mm/mempolicy.c
++++ b/mm/mempolicy.c
+@@ -802,8 +802,10 @@ static int mbind_range(struct vma_iterator *vmi, struct vm_area_struct *vma,
+ vmstart = vma->vm_start;
+ }
+
+- if (mpol_equal(vma_policy(vma), new_pol))
++ if (mpol_equal(vma_policy(vma), new_pol)) {
++ *prev = vma;
+ return 0;
++ }
+
+ pgoff = vma->vm_pgoff + ((vmstart - vma->vm_start) >> PAGE_SHIFT);
+ merged = vma_merge(vma->vm_mm, *prev, vmstart, vmend, vma->vm_flags,
+diff --git a/mm/vmscan.c b/mm/vmscan.c
+index 5b7b8d4f5297f..8168fee6a85b9 100644
+--- a/mm/vmscan.c
++++ b/mm/vmscan.c
+@@ -1905,6 +1905,16 @@ retry:
+ }
+ }
+
++ /*
++ * Folio is unmapped now so it cannot be newly pinned anymore.
++ * No point in trying to reclaim folio if it is pinned.
++ * Furthermore we don't want to reclaim underlying fs metadata
++ * if the folio is pinned and thus potentially modified by the
++ * pinning process as that may upset the filesystem.
++ */
++ if (folio_maybe_dma_pinned(folio))
++ goto activate_locked;
++
+ mapping = folio_mapping(folio);
+ if (folio_test_dirty(folio)) {
+ /*
+diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
+index 296d0145932f4..5920544e93e82 100644
+--- a/net/8021q/vlan_dev.c
++++ b/net/8021q/vlan_dev.c
+@@ -365,7 +365,7 @@ static int vlan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+
+ switch (cmd) {
+ case SIOCSHWTSTAMP:
+- if (!net_eq(dev_net(dev), &init_net))
++ if (!net_eq(dev_net(dev), dev_net(real_dev)))
+ break;
+ fallthrough;
+ case SIOCGMIIPHY:
+diff --git a/net/core/bpf_sk_storage.c b/net/core/bpf_sk_storage.c
+index bb378c33f542c..6a4b3e9313241 100644
+--- a/net/core/bpf_sk_storage.c
++++ b/net/core/bpf_sk_storage.c
+@@ -100,8 +100,8 @@ static void *bpf_fd_sk_storage_lookup_elem(struct bpf_map *map, void *key)
+ return ERR_PTR(err);
+ }
+
+-static int bpf_fd_sk_storage_update_elem(struct bpf_map *map, void *key,
+- void *value, u64 map_flags)
++static long bpf_fd_sk_storage_update_elem(struct bpf_map *map, void *key,
++ void *value, u64 map_flags)
+ {
+ struct bpf_local_storage_data *sdata;
+ struct socket *sock;
+@@ -120,7 +120,7 @@ static int bpf_fd_sk_storage_update_elem(struct bpf_map *map, void *key,
+ return err;
+ }
+
+-static int bpf_fd_sk_storage_delete_elem(struct bpf_map *map, void *key)
++static long bpf_fd_sk_storage_delete_elem(struct bpf_map *map, void *key)
+ {
+ struct socket *sock;
+ int fd, err;
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index 43e1b89695c22..6f5ef18a8b772 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -5038,6 +5038,9 @@ void __skb_tstamp_tx(struct sk_buff *orig_skb,
+ skb = alloc_skb(0, GFP_ATOMIC);
+ } else {
+ skb = skb_clone(orig_skb, GFP_ATOMIC);
++
++ if (skb_orphan_frags_rx(skb, GFP_ATOMIC))
++ return;
+ }
+ if (!skb)
+ return;
+diff --git a/net/core/sock_map.c b/net/core/sock_map.c
+index a68a7290a3b2b..a055139f410e2 100644
+--- a/net/core/sock_map.c
++++ b/net/core/sock_map.c
+@@ -437,7 +437,7 @@ static void sock_map_delete_from_link(struct bpf_map *map, struct sock *sk,
+ __sock_map_delete(stab, sk, link_raw);
+ }
+
+-static int sock_map_delete_elem(struct bpf_map *map, void *key)
++static long sock_map_delete_elem(struct bpf_map *map, void *key)
+ {
+ struct bpf_stab *stab = container_of(map, struct bpf_stab, map);
+ u32 i = *(u32 *)key;
+@@ -587,8 +587,8 @@ out:
+ return ret;
+ }
+
+-static int sock_map_update_elem(struct bpf_map *map, void *key,
+- void *value, u64 flags)
++static long sock_map_update_elem(struct bpf_map *map, void *key,
++ void *value, u64 flags)
+ {
+ struct sock *sk = (struct sock *)value;
+ int ret;
+@@ -916,7 +916,7 @@ static void sock_hash_delete_from_link(struct bpf_map *map, struct sock *sk,
+ raw_spin_unlock_bh(&bucket->lock);
+ }
+
+-static int sock_hash_delete_elem(struct bpf_map *map, void *key)
++static long sock_hash_delete_elem(struct bpf_map *map, void *key)
+ {
+ struct bpf_shtab *htab = container_of(map, struct bpf_shtab, map);
+ u32 hash, key_size = map->key_size;
+diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
+index b9d7c3dd1cb39..c0fd8f5f3b94e 100644
+--- a/net/dccp/ipv6.c
++++ b/net/dccp/ipv6.c
+@@ -783,6 +783,7 @@ lookup:
+
+ if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
+ goto discard_and_relse;
++ nf_reset_ct(skb);
+
+ return __sk_receive_skb(sk, skb, 1, dh->dccph_doff * 4,
+ refcounted) ? -1 : 0;
+diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
+index 922c87ef1ab58..2a07588265c70 100644
+--- a/net/ipv4/ip_output.c
++++ b/net/ipv4/ip_output.c
+@@ -1570,9 +1570,19 @@ struct sk_buff *__ip_make_skb(struct sock *sk,
+ cork->dst = NULL;
+ skb_dst_set(skb, &rt->dst);
+
+- if (iph->protocol == IPPROTO_ICMP)
+- icmp_out_count(net, ((struct icmphdr *)
+- skb_transport_header(skb))->type);
++ if (iph->protocol == IPPROTO_ICMP) {
++ u8 icmp_type;
++
++ /* For such sockets, transhdrlen is zero when do ip_append_data(),
++ * so icmphdr does not in skb linear region and can not get icmp_type
++ * by icmp_hdr(skb)->type.
++ */
++ if (sk->sk_type == SOCK_RAW && !inet_sk(sk)->hdrincl)
++ icmp_type = fl4->fl4_icmp_type;
++ else
++ icmp_type = icmp_hdr(skb)->type;
++ icmp_out_count(net, icmp_type);
++ }
+
+ ip_cork_release(cork);
+ out:
+diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
+index e1ebf5e42ebe9..d94041bb42872 100644
+--- a/net/ipv6/ip6_input.c
++++ b/net/ipv6/ip6_input.c
+@@ -404,10 +404,6 @@ resubmit_final:
+ /* Only do this once for first final protocol */
+ have_final = true;
+
+- /* Free reference early: we don't need it any more,
+- and it may hold ip_conntrack module loaded
+- indefinitely. */
+- nf_reset_ct(skb);
+
+ skb_postpull_rcsum(skb, skb_network_header(skb),
+ skb_network_header_len(skb));
+@@ -430,10 +426,12 @@ resubmit_final:
+ goto discard;
+ }
+ }
+- if (!(ipprot->flags & INET6_PROTO_NOPOLICY) &&
+- !xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
+- SKB_DR_SET(reason, XFRM_POLICY);
+- goto discard;
++ if (!(ipprot->flags & INET6_PROTO_NOPOLICY)) {
++ if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
++ SKB_DR_SET(reason, XFRM_POLICY);
++ goto discard;
++ }
++ nf_reset_ct(skb);
+ }
+
+ ret = INDIRECT_CALL_2(ipprot->handler, tcp_v6_rcv, udpv6_rcv,
+diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
+index 4fc511bdf176c..f44b99f7ecdcc 100644
+--- a/net/ipv6/raw.c
++++ b/net/ipv6/raw.c
+@@ -193,10 +193,8 @@ static bool ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
+ struct sk_buff *clone = skb_clone(skb, GFP_ATOMIC);
+
+ /* Not releasing hash table! */
+- if (clone) {
+- nf_reset_ct(clone);
++ if (clone)
+ rawv6_rcv(sk, clone);
+- }
+ }
+ }
+ rcu_read_unlock();
+@@ -387,6 +385,7 @@ int rawv6_rcv(struct sock *sk, struct sk_buff *skb)
+ kfree_skb(skb);
+ return NET_RX_DROP;
+ }
++ nf_reset_ct(skb);
+
+ if (!rp->checksum)
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
+index a52a4f12f1467..e4da7267ed4bd 100644
+--- a/net/ipv6/tcp_ipv6.c
++++ b/net/ipv6/tcp_ipv6.c
+@@ -1721,6 +1721,8 @@ process:
+ if (drop_reason)
+ goto discard_and_relse;
+
++ nf_reset_ct(skb);
++
+ if (tcp_filter(sk, skb)) {
+ drop_reason = SKB_DROP_REASON_SOCKET_FILTER;
+ goto discard_and_relse;
+diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
+index a675acfb901d1..c519f21632656 100644
+--- a/net/ipv6/udp.c
++++ b/net/ipv6/udp.c
+@@ -704,6 +704,7 @@ static int udpv6_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb)
+ drop_reason = SKB_DROP_REASON_XFRM_POLICY;
+ goto drop;
+ }
++ nf_reset_ct(skb);
+
+ if (static_branch_unlikely(&udpv6_encap_needed_key) && up->encap_type) {
+ int (*encap_rcv)(struct sock *sk, struct sk_buff *skb);
+@@ -1027,6 +1028,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
+
+ if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
+ goto discard;
++ nf_reset_ct(skb);
+
+ if (udp_lib_checksum_complete(skb))
+ goto csum_error;
+diff --git a/net/netfilter/nf_conntrack_bpf.c b/net/netfilter/nf_conntrack_bpf.c
+index e1af14e3b63c5..24002bc61e07e 100644
+--- a/net/netfilter/nf_conntrack_bpf.c
++++ b/net/netfilter/nf_conntrack_bpf.c
+@@ -381,6 +381,7 @@ struct nf_conn *bpf_ct_insert_entry(struct nf_conn___init *nfct_i)
+ struct nf_conn *nfct = (struct nf_conn *)nfct_i;
+ int err;
+
++ nfct->status |= IPS_CONFIRMED;
+ err = nf_conntrack_hash_check_insert(nfct);
+ if (err < 0) {
+ nf_conntrack_free(nfct);
+diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
+index 19e3afb23fdaf..cf731546e865b 100644
+--- a/net/netfilter/nf_conntrack_core.c
++++ b/net/netfilter/nf_conntrack_core.c
+@@ -934,7 +934,6 @@ nf_conntrack_hash_check_insert(struct nf_conn *ct)
+ goto out;
+ }
+
+- ct->status |= IPS_CONFIRMED;
+ smp_wmb();
+ /* The caller holds a reference to this object */
+ refcount_set(&ct->ct_general.use, 2);
+diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
+index d095d3c1ceca6..cb4325b8ebb11 100644
+--- a/net/netfilter/nf_conntrack_netlink.c
++++ b/net/netfilter/nf_conntrack_netlink.c
+@@ -176,7 +176,12 @@ nla_put_failure:
+ static int ctnetlink_dump_timeout(struct sk_buff *skb, const struct nf_conn *ct,
+ bool skip_zero)
+ {
+- long timeout = nf_ct_expires(ct) / HZ;
++ long timeout;
++
++ if (nf_ct_is_confirmed(ct))
++ timeout = nf_ct_expires(ct) / HZ;
++ else
++ timeout = ct->timeout / HZ;
+
+ if (skip_zero && timeout == 0)
+ return 0;
+@@ -2253,9 +2258,6 @@ ctnetlink_create_conntrack(struct net *net,
+ if (!cda[CTA_TIMEOUT])
+ goto err1;
+
+- timeout = (u64)ntohl(nla_get_be32(cda[CTA_TIMEOUT])) * HZ;
+- __nf_ct_set_timeout(ct, timeout);
+-
+ rcu_read_lock();
+ if (cda[CTA_HELP]) {
+ char *helpname = NULL;
+@@ -2316,6 +2318,12 @@ ctnetlink_create_conntrack(struct net *net,
+ nfct_seqadj_ext_add(ct);
+ nfct_synproxy_ext_add(ct);
+
++ /* we must add conntrack extensions before confirmation. */
++ ct->status |= IPS_CONFIRMED;
++
++ timeout = (u64)ntohl(nla_get_be32(cda[CTA_TIMEOUT])) * HZ;
++ __nf_ct_set_timeout(ct, timeout);
++
+ if (cda[CTA_STATUS]) {
+ err = ctnetlink_change_status(ct, cda);
+ if (err < 0)
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index ce8a047ef8306..96bc4b8ded423 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -4984,12 +4984,24 @@ static void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set,
+ }
+ }
+
++void nf_tables_activate_set(const struct nft_ctx *ctx, struct nft_set *set)
++{
++ if (nft_set_is_anonymous(set))
++ nft_clear(ctx->net, set);
++
++ set->use++;
++}
++EXPORT_SYMBOL_GPL(nf_tables_activate_set);
++
+ void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set,
+ struct nft_set_binding *binding,
+ enum nft_trans_phase phase)
+ {
+ switch (phase) {
+ case NFT_TRANS_PREPARE:
++ if (nft_set_is_anonymous(set))
++ nft_deactivate_next(ctx->net, set);
++
+ set->use--;
+ return;
+ case NFT_TRANS_ABORT:
+@@ -8571,6 +8583,8 @@ static int nf_tables_validate(struct net *net)
+ if (nft_table_validate(net, table) < 0)
+ return -EAGAIN;
+ }
++
++ nft_validate_state_update(net, NFT_VALIDATE_SKIP);
+ break;
+ }
+
+@@ -9491,11 +9505,6 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action)
+ return 0;
+ }
+
+-static void nf_tables_cleanup(struct net *net)
+-{
+- nft_validate_state_update(net, NFT_VALIDATE_SKIP);
+-}
+-
+ static int nf_tables_abort(struct net *net, struct sk_buff *skb,
+ enum nfnl_abort_action action)
+ {
+@@ -9529,7 +9538,6 @@ static const struct nfnetlink_subsystem nf_tables_subsys = {
+ .cb = nf_tables_cb,
+ .commit = nf_tables_commit,
+ .abort = nf_tables_abort,
+- .cleanup = nf_tables_cleanup,
+ .valid_genid = nf_tables_valid_genid,
+ .owner = THIS_MODULE,
+ };
+diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
+index 81c7737c803a6..ae7146475d17a 100644
+--- a/net/netfilter/nfnetlink.c
++++ b/net/netfilter/nfnetlink.c
+@@ -590,8 +590,6 @@ done:
+ goto replay_abort;
+ }
+ }
+- if (ss->cleanup)
+- ss->cleanup(net);
+
+ nfnl_err_deliver(&err_list, oskb);
+ kfree_skb(skb);
+diff --git a/net/netfilter/nft_dynset.c b/net/netfilter/nft_dynset.c
+index 274579b1696e0..bd19c7aec92ee 100644
+--- a/net/netfilter/nft_dynset.c
++++ b/net/netfilter/nft_dynset.c
+@@ -342,7 +342,7 @@ static void nft_dynset_activate(const struct nft_ctx *ctx,
+ {
+ struct nft_dynset *priv = nft_expr_priv(expr);
+
+- priv->set->use++;
++ nf_tables_activate_set(ctx, priv->set);
+ }
+
+ static void nft_dynset_destroy(const struct nft_ctx *ctx,
+diff --git a/net/netfilter/nft_lookup.c b/net/netfilter/nft_lookup.c
+index cecf8ab90e58f..03ef4fdaa460b 100644
+--- a/net/netfilter/nft_lookup.c
++++ b/net/netfilter/nft_lookup.c
+@@ -167,7 +167,7 @@ static void nft_lookup_activate(const struct nft_ctx *ctx,
+ {
+ struct nft_lookup *priv = nft_expr_priv(expr);
+
+- priv->set->use++;
++ nf_tables_activate_set(ctx, priv->set);
+ }
+
+ static void nft_lookup_destroy(const struct nft_ctx *ctx,
+diff --git a/net/netfilter/nft_objref.c b/net/netfilter/nft_objref.c
+index 7b01aa2ef6531..d985d361ed8ad 100644
+--- a/net/netfilter/nft_objref.c
++++ b/net/netfilter/nft_objref.c
+@@ -185,7 +185,7 @@ static void nft_objref_map_activate(const struct nft_ctx *ctx,
+ {
+ struct nft_objref_map *priv = nft_expr_priv(expr);
+
+- priv->set->use++;
++ nf_tables_activate_set(ctx, priv->set);
+ }
+
+ static void nft_objref_map_destroy(const struct nft_ctx *ctx,
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+index f365dfdd672d7..9b6eb28e6e94f 100644
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -1742,7 +1742,8 @@ static int netlink_getsockopt(struct socket *sock, int level, int optname,
+ {
+ struct sock *sk = sock->sk;
+ struct netlink_sock *nlk = nlk_sk(sk);
+- int len, val, err;
++ unsigned int flag;
++ int len, val;
+
+ if (level != SOL_NETLINK)
+ return -ENOPROTOOPT;
+@@ -1754,39 +1755,17 @@ static int netlink_getsockopt(struct socket *sock, int level, int optname,
+
+ switch (optname) {
+ case NETLINK_PKTINFO:
+- if (len < sizeof(int))
+- return -EINVAL;
+- len = sizeof(int);
+- val = nlk->flags & NETLINK_F_RECV_PKTINFO ? 1 : 0;
+- if (put_user(len, optlen) ||
+- put_user(val, optval))
+- return -EFAULT;
+- err = 0;
++ flag = NETLINK_F_RECV_PKTINFO;
+ break;
+ case NETLINK_BROADCAST_ERROR:
+- if (len < sizeof(int))
+- return -EINVAL;
+- len = sizeof(int);
+- val = nlk->flags & NETLINK_F_BROADCAST_SEND_ERROR ? 1 : 0;
+- if (put_user(len, optlen) ||
+- put_user(val, optval))
+- return -EFAULT;
+- err = 0;
++ flag = NETLINK_F_BROADCAST_SEND_ERROR;
+ break;
+ case NETLINK_NO_ENOBUFS:
+- if (len < sizeof(int))
+- return -EINVAL;
+- len = sizeof(int);
+- val = nlk->flags & NETLINK_F_RECV_NO_ENOBUFS ? 1 : 0;
+- if (put_user(len, optlen) ||
+- put_user(val, optval))
+- return -EFAULT;
+- err = 0;
++ flag = NETLINK_F_RECV_NO_ENOBUFS;
+ break;
+ case NETLINK_LIST_MEMBERSHIPS: {
+- int pos, idx, shift;
++ int pos, idx, shift, err = 0;
+
+- err = 0;
+ netlink_lock_table();
+ for (pos = 0; pos * 8 < nlk->ngroups; pos += sizeof(u32)) {
+ if (len - pos < sizeof(u32))
+@@ -1803,40 +1782,32 @@ static int netlink_getsockopt(struct socket *sock, int level, int optname,
+ if (put_user(ALIGN(nlk->ngroups / 8, sizeof(u32)), optlen))
+ err = -EFAULT;
+ netlink_unlock_table();
+- break;
++ return err;
+ }
+ case NETLINK_CAP_ACK:
+- if (len < sizeof(int))
+- return -EINVAL;
+- len = sizeof(int);
+- val = nlk->flags & NETLINK_F_CAP_ACK ? 1 : 0;
+- if (put_user(len, optlen) ||
+- put_user(val, optval))
+- return -EFAULT;
+- err = 0;
++ flag = NETLINK_F_CAP_ACK;
+ break;
+ case NETLINK_EXT_ACK:
+- if (len < sizeof(int))
+- return -EINVAL;
+- len = sizeof(int);
+- val = nlk->flags & NETLINK_F_EXT_ACK ? 1 : 0;
+- if (put_user(len, optlen) || put_user(val, optval))
+- return -EFAULT;
+- err = 0;
++ flag = NETLINK_F_EXT_ACK;
+ break;
+ case NETLINK_GET_STRICT_CHK:
+- if (len < sizeof(int))
+- return -EINVAL;
+- len = sizeof(int);
+- val = nlk->flags & NETLINK_F_STRICT_CHK ? 1 : 0;
+- if (put_user(len, optlen) || put_user(val, optval))
+- return -EFAULT;
+- err = 0;
++ flag = NETLINK_F_STRICT_CHK;
+ break;
+ default:
+- err = -ENOPROTOOPT;
++ return -ENOPROTOOPT;
+ }
+- return err;
++
++ if (len < sizeof(int))
++ return -EINVAL;
++
++ len = sizeof(int);
++ val = nlk->flags & flag ? 1 : 0;
++
++ if (put_user(len, optlen) ||
++ copy_to_user(optval, &val, len))
++ return -EFAULT;
++
++ return 0;
+ }
+
+ static void netlink_cmsg_recv_pktinfo(struct msghdr *msg, struct sk_buff *skb)
+diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
+index b5ab98ca2511b..1259b34a28ebe 100644
+--- a/net/packet/af_packet.c
++++ b/net/packet/af_packet.c
+@@ -307,7 +307,8 @@ static void packet_cached_dev_reset(struct packet_sock *po)
+
+ static bool packet_use_direct_xmit(const struct packet_sock *po)
+ {
+- return po->xmit == packet_direct_xmit;
++ /* Paired with WRITE_ONCE() in packet_setsockopt() */
++ return READ_ONCE(po->xmit) == packet_direct_xmit;
+ }
+
+ static u16 packet_pick_tx_queue(struct sk_buff *skb)
+@@ -2185,7 +2186,7 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev,
+ sll = &PACKET_SKB_CB(skb)->sa.ll;
+ sll->sll_hatype = dev->type;
+ sll->sll_pkttype = skb->pkt_type;
+- if (unlikely(po->origdev))
++ if (unlikely(packet_sock_flag(po, PACKET_SOCK_ORIGDEV)))
+ sll->sll_ifindex = orig_dev->ifindex;
+ else
+ sll->sll_ifindex = dev->ifindex;
+@@ -2460,7 +2461,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
+ sll->sll_hatype = dev->type;
+ sll->sll_protocol = skb->protocol;
+ sll->sll_pkttype = skb->pkt_type;
+- if (unlikely(po->origdev))
++ if (unlikely(packet_sock_flag(po, PACKET_SOCK_ORIGDEV)))
+ sll->sll_ifindex = orig_dev->ifindex;
+ else
+ sll->sll_ifindex = dev->ifindex;
+@@ -2867,7 +2868,8 @@ tpacket_error:
+ packet_inc_pending(&po->tx_ring);
+
+ status = TP_STATUS_SEND_REQUEST;
+- err = po->xmit(skb);
++ /* Paired with WRITE_ONCE() in packet_setsockopt() */
++ err = READ_ONCE(po->xmit)(skb);
+ if (unlikely(err != 0)) {
+ if (err > 0)
+ err = net_xmit_errno(err);
+@@ -3070,7 +3072,8 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
+ virtio_net_hdr_set_proto(skb, &vnet_hdr);
+ }
+
+- err = po->xmit(skb);
++ /* Paired with WRITE_ONCE() in packet_setsockopt() */
++ err = READ_ONCE(po->xmit)(skb);
+ if (unlikely(err != 0)) {
+ if (err > 0)
+ err = net_xmit_errno(err);
+@@ -3513,7 +3516,7 @@ static int packet_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
+ memcpy(msg->msg_name, &PACKET_SKB_CB(skb)->sa, copy_len);
+ }
+
+- if (pkt_sk(sk)->auxdata) {
++ if (packet_sock_flag(pkt_sk(sk), PACKET_SOCK_AUXDATA)) {
+ struct tpacket_auxdata aux;
+
+ aux.tp_status = TP_STATUS_USER;
+@@ -3897,9 +3900,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, sockptr_t optval,
+ if (copy_from_sockptr(&val, optval, sizeof(val)))
+ return -EFAULT;
+
+- lock_sock(sk);
+- po->auxdata = !!val;
+- release_sock(sk);
++ packet_sock_flag_set(po, PACKET_SOCK_AUXDATA, val);
+ return 0;
+ }
+ case PACKET_ORIGDEV:
+@@ -3911,9 +3912,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, sockptr_t optval,
+ if (copy_from_sockptr(&val, optval, sizeof(val)))
+ return -EFAULT;
+
+- lock_sock(sk);
+- po->origdev = !!val;
+- release_sock(sk);
++ packet_sock_flag_set(po, PACKET_SOCK_ORIGDEV, val);
+ return 0;
+ }
+ case PACKET_VNET_HDR:
+@@ -4007,7 +4006,8 @@ packet_setsockopt(struct socket *sock, int level, int optname, sockptr_t optval,
+ if (copy_from_sockptr(&val, optval, sizeof(val)))
+ return -EFAULT;
+
+- po->xmit = val ? packet_direct_xmit : dev_queue_xmit;
++ /* Paired with all lockless reads of po->xmit */
++ WRITE_ONCE(po->xmit, val ? packet_direct_xmit : dev_queue_xmit);
+ return 0;
+ }
+ default:
+@@ -4058,10 +4058,10 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
+
+ break;
+ case PACKET_AUXDATA:
+- val = po->auxdata;
++ val = packet_sock_flag(po, PACKET_SOCK_AUXDATA);
+ break;
+ case PACKET_ORIGDEV:
+- val = po->origdev;
++ val = packet_sock_flag(po, PACKET_SOCK_ORIGDEV);
+ break;
+ case PACKET_VNET_HDR:
+ val = po->has_vnet_hdr;
+diff --git a/net/packet/diag.c b/net/packet/diag.c
+index 07812ae5ca073..d704c7bf51b20 100644
+--- a/net/packet/diag.c
++++ b/net/packet/diag.c
+@@ -23,9 +23,9 @@ static int pdiag_put_info(const struct packet_sock *po, struct sk_buff *nlskb)
+ pinfo.pdi_flags = 0;
+ if (po->running)
+ pinfo.pdi_flags |= PDI_RUNNING;
+- if (po->auxdata)
++ if (packet_sock_flag(po, PACKET_SOCK_AUXDATA))
+ pinfo.pdi_flags |= PDI_AUXDATA;
+- if (po->origdev)
++ if (packet_sock_flag(po, PACKET_SOCK_ORIGDEV))
+ pinfo.pdi_flags |= PDI_ORIGDEV;
+ if (po->has_vnet_hdr)
+ pinfo.pdi_flags |= PDI_VNETHDR;
+diff --git a/net/packet/internal.h b/net/packet/internal.h
+index 48af35b1aed25..3bae8ea7a36f5 100644
+--- a/net/packet/internal.h
++++ b/net/packet/internal.h
+@@ -116,10 +116,9 @@ struct packet_sock {
+ int copy_thresh;
+ spinlock_t bind_lock;
+ struct mutex pg_vec_lock;
++ unsigned long flags;
+ unsigned int running; /* bind_lock must be held */
+- unsigned int auxdata:1, /* writer must hold sock lock */
+- origdev:1,
+- has_vnet_hdr:1,
++ unsigned int has_vnet_hdr:1, /* writer must hold sock lock */
+ tp_loss:1,
+ tp_tx_has_off:1;
+ int pressure;
+@@ -144,4 +143,25 @@ static inline struct packet_sock *pkt_sk(struct sock *sk)
+ return (struct packet_sock *)sk;
+ }
+
++enum packet_sock_flags {
++ PACKET_SOCK_ORIGDEV,
++ PACKET_SOCK_AUXDATA,
++};
++
++static inline void packet_sock_flag_set(struct packet_sock *po,
++ enum packet_sock_flags flag,
++ bool val)
++{
++ if (val)
++ set_bit(flag, &po->flags);
++ else
++ clear_bit(flag, &po->flags);
++}
++
++static inline bool packet_sock_flag(const struct packet_sock *po,
++ enum packet_sock_flags flag)
++{
++ return test_bit(flag, &po->flags);
++}
++
+ #endif
+diff --git a/net/rxrpc/key.c b/net/rxrpc/key.c
+index 8d53aded09c42..33e8302a79e33 100644
+--- a/net/rxrpc/key.c
++++ b/net/rxrpc/key.c
+@@ -680,7 +680,7 @@ static long rxrpc_read(const struct key *key,
+ return -ENOPKG;
+ }
+
+- if (WARN_ON((unsigned long)xdr - (unsigned long)oldxdr ==
++ if (WARN_ON((unsigned long)xdr - (unsigned long)oldxdr !=
+ toksize))
+ return -EIO;
+ }
+diff --git a/net/sched/sch_fq.c b/net/sched/sch_fq.c
+index 48d14fb90ba02..f59a2cb2c803d 100644
+--- a/net/sched/sch_fq.c
++++ b/net/sched/sch_fq.c
+@@ -779,13 +779,17 @@ static int fq_resize(struct Qdisc *sch, u32 log)
+ return 0;
+ }
+
++static struct netlink_range_validation iq_range = {
++ .max = INT_MAX,
++};
++
+ static const struct nla_policy fq_policy[TCA_FQ_MAX + 1] = {
+ [TCA_FQ_UNSPEC] = { .strict_start_type = TCA_FQ_TIMER_SLACK },
+
+ [TCA_FQ_PLIMIT] = { .type = NLA_U32 },
+ [TCA_FQ_FLOW_PLIMIT] = { .type = NLA_U32 },
+ [TCA_FQ_QUANTUM] = { .type = NLA_U32 },
+- [TCA_FQ_INITIAL_QUANTUM] = { .type = NLA_U32 },
++ [TCA_FQ_INITIAL_QUANTUM] = NLA_POLICY_FULL_RANGE(NLA_U32, &iq_range),
+ [TCA_FQ_RATE_ENABLE] = { .type = NLA_U32 },
+ [TCA_FQ_FLOW_DEFAULT_RATE] = { .type = NLA_U32 },
+ [TCA_FQ_FLOW_MAX_RATE] = { .type = NLA_U32 },
+diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
+index fd7e1c630493e..d2ee566343083 100644
+--- a/net/sunrpc/clnt.c
++++ b/net/sunrpc/clnt.c
+@@ -2050,9 +2050,6 @@ call_bind_status(struct rpc_task *task)
+ status = -EOPNOTSUPP;
+ break;
+ }
+- if (task->tk_rebind_retry == 0)
+- break;
+- task->tk_rebind_retry--;
+ rpc_delay(task, 3*HZ);
+ goto retry_timeout;
+ case -ENOBUFS:
+diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
+index be587a308e05a..c8321de341eea 100644
+--- a/net/sunrpc/sched.c
++++ b/net/sunrpc/sched.c
+@@ -817,7 +817,6 @@ rpc_init_task_statistics(struct rpc_task *task)
+ /* Initialize retry counters */
+ task->tk_garb_retry = 2;
+ task->tk_cred_retry = 2;
+- task->tk_rebind_retry = 2;
+
+ /* starting timestamp */
+ task->tk_start = ktime_get();
+diff --git a/net/xdp/xsk_queue.h b/net/xdp/xsk_queue.h
+index c6fb6b7636582..bdeba20aaf8ff 100644
+--- a/net/xdp/xsk_queue.h
++++ b/net/xdp/xsk_queue.h
+@@ -161,6 +161,7 @@ static inline bool xp_unaligned_validate_desc(struct xsk_buff_pool *pool,
+ return false;
+
+ if (base_addr >= pool->addrs_cnt || addr >= pool->addrs_cnt ||
++ addr + desc->len > pool->addrs_cnt ||
+ xp_desc_crosses_non_contig_pg(pool, addr, desc->len))
+ return false;
+
+diff --git a/net/xdp/xskmap.c b/net/xdp/xskmap.c
+index 771d0fa90ef58..3436a8efb8dc7 100644
+--- a/net/xdp/xskmap.c
++++ b/net/xdp/xskmap.c
+@@ -150,8 +150,8 @@ static void *xsk_map_lookup_elem_sys_only(struct bpf_map *map, void *key)
+ return ERR_PTR(-EOPNOTSUPP);
+ }
+
+-static int xsk_map_update_elem(struct bpf_map *map, void *key, void *value,
+- u64 map_flags)
++static long xsk_map_update_elem(struct bpf_map *map, void *key, void *value,
++ u64 map_flags)
+ {
+ struct xsk_map *m = container_of(map, struct xsk_map, map);
+ struct xdp_sock __rcu **map_entry;
+@@ -211,7 +211,7 @@ out:
+ return err;
+ }
+
+-static int xsk_map_delete_elem(struct bpf_map *map, void *key)
++static long xsk_map_delete_elem(struct bpf_map *map, void *key)
+ {
+ struct xsk_map *m = container_of(map, struct xsk_map, map);
+ struct xdp_sock __rcu **map_entry;
+@@ -231,7 +231,7 @@ static int xsk_map_delete_elem(struct bpf_map *map, void *key)
+ return 0;
+ }
+
+-static int xsk_map_redirect(struct bpf_map *map, u64 index, u64 flags)
++static long xsk_map_redirect(struct bpf_map *map, u64 index, u64 flags)
+ {
+ return __bpf_xdp_redirect_map(map, index, flags, 0,
+ __xsk_map_lookup_elem);
+diff --git a/scripts/gdb/linux/clk.py b/scripts/gdb/linux/clk.py
+index 061aecfa294e6..7a01fdc3e8446 100644
+--- a/scripts/gdb/linux/clk.py
++++ b/scripts/gdb/linux/clk.py
+@@ -41,6 +41,8 @@ are cached and potentially out of date"""
+ self.show_subtree(child, level + 1)
+
+ def invoke(self, arg, from_tty):
++ if utils.gdb_eval_or_none("clk_root_list") is None:
++ raise gdb.GdbError("No clocks registered")
+ gdb.write(" enable prepare protect \n")
+ gdb.write(" clock count count count rate \n")
+ gdb.write("------------------------------------------------------------------------\n")
+diff --git a/scripts/gdb/linux/constants.py.in b/scripts/gdb/linux/constants.py.in
+index 2efbec6b6b8db..08f0587d15ea1 100644
+--- a/scripts/gdb/linux/constants.py.in
++++ b/scripts/gdb/linux/constants.py.in
+@@ -39,6 +39,8 @@
+
+ import gdb
+
++LX_CONFIG(CONFIG_DEBUG_INFO_REDUCED)
++
+ /* linux/clk-provider.h */
+ if IS_BUILTIN(CONFIG_COMMON_CLK):
+ LX_GDBPARSED(CLK_GET_RATE_NOCACHE)
+diff --git a/scripts/gdb/linux/genpd.py b/scripts/gdb/linux/genpd.py
+index 39cd1abd85590..b53649c0a77a6 100644
+--- a/scripts/gdb/linux/genpd.py
++++ b/scripts/gdb/linux/genpd.py
+@@ -5,7 +5,7 @@
+ import gdb
+ import sys
+
+-from linux.utils import CachedType
++from linux.utils import CachedType, gdb_eval_or_none
+ from linux.lists import list_for_each_entry
+
+ generic_pm_domain_type = CachedType('struct generic_pm_domain')
+@@ -70,6 +70,8 @@ Output is similar to /sys/kernel/debug/pm_genpd/pm_genpd_summary'''
+ gdb.write(' %-50s %s\n' % (kobj_path, rtpm_status_str(dev)))
+
+ def invoke(self, arg, from_tty):
++ if gdb_eval_or_none("&gpd_list") is None:
++ raise gdb.GdbError("No power domain(s) registered")
+ gdb.write('domain status children\n');
+ gdb.write(' /device runtime status\n');
+ gdb.write('----------------------------------------------------------------------\n');
+diff --git a/scripts/gdb/linux/timerlist.py b/scripts/gdb/linux/timerlist.py
+index 071d0dd5a6349..51def847f1ef9 100644
+--- a/scripts/gdb/linux/timerlist.py
++++ b/scripts/gdb/linux/timerlist.py
+@@ -73,7 +73,7 @@ def print_cpu(hrtimer_bases, cpu, max_clock_bases):
+ ts = cpus.per_cpu(tick_sched_ptr, cpu)
+
+ text = "cpu: {}\n".format(cpu)
+- for i in xrange(max_clock_bases):
++ for i in range(max_clock_bases):
+ text += " clock {}:\n".format(i)
+ text += print_base(cpu_base['clock_base'][i])
+
+@@ -158,6 +158,8 @@ def pr_cpumask(mask):
+ num_bytes = (nr_cpu_ids + 7) / 8
+ buf = utils.read_memoryview(inf, bits, num_bytes).tobytes()
+ buf = binascii.b2a_hex(buf)
++ if type(buf) is not str:
++ buf=buf.decode()
+
+ chunks = []
+ i = num_bytes
+diff --git a/scripts/gdb/linux/utils.py b/scripts/gdb/linux/utils.py
+index 1553f68716cc2..7f36aee32ac66 100644
+--- a/scripts/gdb/linux/utils.py
++++ b/scripts/gdb/linux/utils.py
+@@ -88,7 +88,10 @@ def get_target_endianness():
+
+
+ def read_memoryview(inf, start, length):
+- return memoryview(inf.read_memory(start, length))
++ m = inf.read_memory(start, length)
++ if type(m) is memoryview:
++ return m
++ return memoryview(m)
+
+
+ def read_u16(buffer, offset):
+diff --git a/scripts/gdb/vmlinux-gdb.py b/scripts/gdb/vmlinux-gdb.py
+index 3e8d3669f0ce0..5564ffe8ae327 100644
+--- a/scripts/gdb/vmlinux-gdb.py
++++ b/scripts/gdb/vmlinux-gdb.py
+@@ -22,6 +22,10 @@ except:
+ gdb.write("NOTE: gdb 7.2 or later required for Linux helper scripts to "
+ "work.\n")
+ else:
++ import linux.constants
++ if linux.constants.LX_CONFIG_DEBUG_INFO_REDUCED:
++ raise gdb.GdbError("Reduced debug information will prevent GDB "
++ "from having complete types.\n")
+ import linux.utils
+ import linux.symbols
+ import linux.modules
+@@ -32,7 +36,6 @@ else:
+ import linux.lists
+ import linux.rbtree
+ import linux.proc
+- import linux.constants
+ import linux.timerlist
+ import linux.clk
+ import linux.genpd
+diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
+index 39caeca474449..60a511c6b583e 100644
+--- a/security/integrity/ima/Kconfig
++++ b/security/integrity/ima/Kconfig
+@@ -8,7 +8,7 @@ config IMA
+ select CRYPTO_HMAC
+ select CRYPTO_SHA1
+ select CRYPTO_HASH_INFO
+- select TCG_TPM if HAS_IOMEM && !UML
++ select TCG_TPM if HAS_IOMEM
+ select TCG_TIS if TCG_TPM && X86
+ select TCG_CRB if TCG_TPM && ACPI
+ select TCG_IBMVTPM if TCG_TPM && PPC_PSERIES
+diff --git a/security/selinux/Makefile b/security/selinux/Makefile
+index 7761624448826..0aecf9334ec31 100644
+--- a/security/selinux/Makefile
++++ b/security/selinux/Makefile
+@@ -23,8 +23,8 @@ ccflags-y := -I$(srctree)/security/selinux -I$(srctree)/security/selinux/include
+ $(addprefix $(obj)/,$(selinux-y)): $(obj)/flask.h
+
+ quiet_cmd_flask = GEN $(obj)/flask.h $(obj)/av_permissions.h
+- cmd_flask = scripts/selinux/genheaders/genheaders $(obj)/flask.h $(obj)/av_permissions.h
++ cmd_flask = $< $(obj)/flask.h $(obj)/av_permissions.h
+
+ targets += flask.h av_permissions.h
+-$(obj)/flask.h: $(src)/include/classmap.h FORCE
++$(obj)/flask.h $(obj)/av_permissions.h &: scripts/selinux/genheaders/genheaders FORCE
+ $(call if_changed,flask)
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index f70d6a33421d2..172ffc2c332b7 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -9428,6 +9428,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x103c, 0x8898, "HP EliteBook 845 G8 Notebook PC", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST),
+ SND_PCI_QUIRK(0x103c, 0x88d0, "HP Pavilion 15-eh1xxx (mainboard 88D0)", ALC287_FIXUP_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x8902, "HP OMEN 16", ALC285_FIXUP_HP_MUTE_LED),
++ SND_PCI_QUIRK(0x103c, 0x8919, "HP Pavilion Aero Laptop 13-be0xxx", ALC287_FIXUP_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x896d, "HP ZBook Firefly 16 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x896e, "HP EliteBook x360 830 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x8971, "HP EliteBook 830 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
+@@ -9478,6 +9479,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x103c, 0x8b8d, "HP", ALC236_FIXUP_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x8b8f, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x8b92, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
++ SND_PCI_QUIRK(0x103c, 0x8b96, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
+ SND_PCI_QUIRK(0x103c, 0x8bf0, "HP", ALC236_FIXUP_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
+ SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
+@@ -9500,6 +9502,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
+ SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A),
+ SND_PCI_QUIRK(0x1043, 0x1662, "ASUS GV301QH", ALC294_FIXUP_ASUS_DUAL_SPK),
++ SND_PCI_QUIRK(0x1043, 0x1683, "ASUS UM3402YAR", ALC287_FIXUP_CS35L41_I2C_2),
+ SND_PCI_QUIRK(0x1043, 0x16b2, "ASUS GU603", ALC289_FIXUP_ASUS_GA401),
+ SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
+ SND_PCI_QUIRK(0x1043, 0x1740, "ASUS UX430UA", ALC295_FIXUP_ASUS_DACS),
+@@ -9689,6 +9692,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x17aa, 0x22f1, "Thinkpad", ALC287_FIXUP_CS35L41_I2C_2),
+ SND_PCI_QUIRK(0x17aa, 0x22f2, "Thinkpad", ALC287_FIXUP_CS35L41_I2C_2),
+ SND_PCI_QUIRK(0x17aa, 0x22f3, "Thinkpad", ALC287_FIXUP_CS35L41_I2C_2),
++ SND_PCI_QUIRK(0x17aa, 0x2316, "Thinkpad P1 Gen 6", ALC287_FIXUP_CS35L41_I2C_2),
++ SND_PCI_QUIRK(0x17aa, 0x2317, "Thinkpad P1 Gen 6", ALC287_FIXUP_CS35L41_I2C_2),
+ SND_PCI_QUIRK(0x17aa, 0x2318, "Thinkpad Z13 Gen2", ALC287_FIXUP_CS35L41_I2C_2),
+ SND_PCI_QUIRK(0x17aa, 0x2319, "Thinkpad Z16 Gen2", ALC287_FIXUP_CS35L41_I2C_2),
+ SND_PCI_QUIRK(0x17aa, 0x231a, "Thinkpad Z16 Gen2", ALC287_FIXUP_CS35L41_I2C_2),
+diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c
+index 489f01a206999..0e029aceb6d65 100644
+--- a/sound/soc/amd/ps/pci-ps.c
++++ b/sound/soc/amd/ps/pci-ps.c
+@@ -91,7 +91,6 @@ static int acp63_init(void __iomem *acp_base, struct device *dev)
+ dev_err(dev, "ACP reset failed\n");
+ return ret;
+ }
+- acp63_writel(0x03, acp_base + ACP_CLKMUX_SEL);
+ acp63_enable_interrupts(acp_base);
+ return 0;
+ }
+@@ -106,7 +105,6 @@ static int acp63_deinit(void __iomem *acp_base, struct device *dev)
+ dev_err(dev, "ACP reset failed\n");
+ return ret;
+ }
+- acp63_writel(0, acp_base + ACP_CLKMUX_SEL);
+ acp63_writel(0, acp_base + ACP_CONTROL);
+ return 0;
+ }
+diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c
+index 4a69ce702360c..0acdf0156f075 100644
+--- a/sound/soc/amd/yc/acp6x-mach.c
++++ b/sound/soc/amd/yc/acp6x-mach.c
+@@ -269,6 +269,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
+ DMI_MATCH(DMI_BOARD_NAME, "8A43"),
+ }
+ },
++ {
++ .driver_data = &acp6x_card,
++ .matches = {
++ DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
++ DMI_MATCH(DMI_BOARD_NAME, "8A22"),
++ }
++ },
+ {}
+ };
+
+diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c
+index c223d83e02cfb..f2b5032daa6ae 100644
+--- a/sound/soc/codecs/cs35l41.c
++++ b/sound/soc/codecs/cs35l41.c
+@@ -356,6 +356,19 @@ static const struct snd_kcontrol_new cs35l41_aud_controls[] = {
+ WM_ADSP_FW_CONTROL("DSP1", 0),
+ };
+
++static void cs35l41_boost_enable(struct cs35l41_private *cs35l41, unsigned int enable)
++{
++ switch (cs35l41->hw_cfg.bst_type) {
++ case CS35L41_INT_BOOST:
++ enable = enable ? CS35L41_BST_EN_DEFAULT : CS35L41_BST_DIS_FET_OFF;
++ regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, CS35L41_BST_EN_MASK,
++ enable << CS35L41_BST_EN_SHIFT);
++ break;
++ default:
++ break;
++ }
++}
++
+ static irqreturn_t cs35l41_irq(int irq, void *data)
+ {
+ struct cs35l41_private *cs35l41 = data;
+@@ -431,8 +444,7 @@ static irqreturn_t cs35l41_irq(int irq, void *data)
+
+ if (status[0] & CS35L41_BST_OVP_ERR) {
+ dev_crit_ratelimited(cs35l41->dev, "VBST Over Voltage error\n");
+- regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
+- CS35L41_BST_EN_MASK, 0);
++ cs35l41_boost_enable(cs35l41, 0);
+ regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
+ CS35L41_BST_OVP_ERR);
+ regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
+@@ -441,16 +453,13 @@ static irqreturn_t cs35l41_irq(int irq, void *data)
+ CS35L41_BST_OVP_ERR_RLS);
+ regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
+ CS35L41_BST_OVP_ERR_RLS, 0);
+- regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
+- CS35L41_BST_EN_MASK,
+- CS35L41_BST_EN_DEFAULT << CS35L41_BST_EN_SHIFT);
++ cs35l41_boost_enable(cs35l41, 1);
+ ret = IRQ_HANDLED;
+ }
+
+ if (status[0] & CS35L41_BST_DCM_UVP_ERR) {
+ dev_crit_ratelimited(cs35l41->dev, "DCM VBST Under Voltage Error\n");
+- regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
+- CS35L41_BST_EN_MASK, 0);
++ cs35l41_boost_enable(cs35l41, 0);
+ regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
+ CS35L41_BST_DCM_UVP_ERR);
+ regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
+@@ -459,16 +468,13 @@ static irqreturn_t cs35l41_irq(int irq, void *data)
+ CS35L41_BST_UVP_ERR_RLS);
+ regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
+ CS35L41_BST_UVP_ERR_RLS, 0);
+- regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
+- CS35L41_BST_EN_MASK,
+- CS35L41_BST_EN_DEFAULT << CS35L41_BST_EN_SHIFT);
++ cs35l41_boost_enable(cs35l41, 1);
+ ret = IRQ_HANDLED;
+ }
+
+ if (status[0] & CS35L41_BST_SHORT_ERR) {
+ dev_crit_ratelimited(cs35l41->dev, "LBST error: powering off!\n");
+- regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
+- CS35L41_BST_EN_MASK, 0);
++ cs35l41_boost_enable(cs35l41, 0);
+ regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
+ CS35L41_BST_SHORT_ERR);
+ regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
+@@ -477,9 +483,7 @@ static irqreturn_t cs35l41_irq(int irq, void *data)
+ CS35L41_BST_SHORT_ERR_RLS);
+ regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
+ CS35L41_BST_SHORT_ERR_RLS, 0);
+- regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
+- CS35L41_BST_EN_MASK,
+- CS35L41_BST_EN_DEFAULT << CS35L41_BST_EN_SHIFT);
++ cs35l41_boost_enable(cs35l41, 1);
+ ret = IRQ_HANDLED;
+ }
+
+diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c
+index 544ccbcfc8844..5678683c71bee 100644
+--- a/sound/soc/codecs/da7213.c
++++ b/sound/soc/codecs/da7213.c
+@@ -1996,6 +1996,11 @@ static int da7213_i2c_probe(struct i2c_client *i2c)
+ return ret;
+ }
+
++static void da7213_i2c_remove(struct i2c_client *i2c)
++{
++ pm_runtime_disable(&i2c->dev);
++}
++
+ static int __maybe_unused da7213_runtime_suspend(struct device *dev)
+ {
+ struct da7213_priv *da7213 = dev_get_drvdata(dev);
+@@ -2039,6 +2044,7 @@ static struct i2c_driver da7213_i2c_driver = {
+ .pm = &da7213_pm,
+ },
+ .probe_new = da7213_i2c_probe,
++ .remove = da7213_i2c_remove,
+ .id_table = da7213_i2c_id,
+ };
+
+diff --git a/sound/soc/codecs/es8316.c b/sound/soc/codecs/es8316.c
+index 056c3082fe02c..f7d7a9c91e04c 100644
+--- a/sound/soc/codecs/es8316.c
++++ b/sound/soc/codecs/es8316.c
+@@ -842,12 +842,14 @@ static int es8316_i2c_probe(struct i2c_client *i2c_client)
+ es8316->irq = i2c_client->irq;
+ mutex_init(&es8316->lock);
+
+- ret = devm_request_threaded_irq(dev, es8316->irq, NULL, es8316_irq,
+- IRQF_TRIGGER_HIGH | IRQF_ONESHOT | IRQF_NO_AUTOEN,
+- "es8316", es8316);
+- if (ret) {
+- dev_warn(dev, "Failed to get IRQ %d: %d\n", es8316->irq, ret);
+- es8316->irq = -ENXIO;
++ if (es8316->irq > 0) {
++ ret = devm_request_threaded_irq(dev, es8316->irq, NULL, es8316_irq,
++ IRQF_TRIGGER_HIGH | IRQF_ONESHOT | IRQF_NO_AUTOEN,
++ "es8316", es8316);
++ if (ret) {
++ dev_warn(dev, "Failed to get IRQ %d: %d\n", es8316->irq, ret);
++ es8316->irq = -ENXIO;
++ }
+ }
+
+ return devm_snd_soc_register_component(&i2c_client->dev,
+diff --git a/sound/soc/fsl/fsl_mqs.c b/sound/soc/fsl/fsl_mqs.c
+index 4922e6795b73f..32d20d351bbf7 100644
+--- a/sound/soc/fsl/fsl_mqs.c
++++ b/sound/soc/fsl/fsl_mqs.c
+@@ -210,10 +210,10 @@ static int fsl_mqs_probe(struct platform_device *pdev)
+ }
+
+ mqs_priv->regmap = syscon_node_to_regmap(gpr_np);
++ of_node_put(gpr_np);
+ if (IS_ERR(mqs_priv->regmap)) {
+ dev_err(&pdev->dev, "failed to get gpr regmap\n");
+- ret = PTR_ERR(mqs_priv->regmap);
+- goto err_free_gpr_np;
++ return PTR_ERR(mqs_priv->regmap);
+ }
+ } else {
+ regs = devm_platform_ioremap_resource(pdev, 0);
+@@ -242,8 +242,7 @@ static int fsl_mqs_probe(struct platform_device *pdev)
+ if (IS_ERR(mqs_priv->mclk)) {
+ dev_err(&pdev->dev, "failed to get the clock: %ld\n",
+ PTR_ERR(mqs_priv->mclk));
+- ret = PTR_ERR(mqs_priv->mclk);
+- goto err_free_gpr_np;
++ return PTR_ERR(mqs_priv->mclk);
+ }
+
+ dev_set_drvdata(&pdev->dev, mqs_priv);
+@@ -252,13 +251,9 @@ static int fsl_mqs_probe(struct platform_device *pdev)
+ ret = devm_snd_soc_register_component(&pdev->dev, &soc_codec_fsl_mqs,
+ &fsl_mqs_dai, 1);
+ if (ret)
+- goto err_free_gpr_np;
+- return 0;
+-
+-err_free_gpr_np:
+- of_node_put(gpr_np);
++ return ret;
+
+- return ret;
++ return 0;
+ }
+
+ static int fsl_mqs_remove(struct platform_device *pdev)
+diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
+index 79e0039c79a38..5a12940ef9070 100644
+--- a/sound/soc/intel/boards/bytcr_rt5640.c
++++ b/sound/soc/intel/boards/bytcr_rt5640.c
+@@ -533,6 +533,18 @@ static int byt_rt5640_aif1_hw_params(struct snd_pcm_substream *substream,
+
+ /* Please keep this list alphabetically sorted */
+ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
++ { /* Acer Iconia One 7 B1-750 */
++ .matches = {
++ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Insyde"),
++ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "VESPA2"),
++ },
++ .driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
++ BYT_RT5640_JD_SRC_JD1_IN4P |
++ BYT_RT5640_OVCD_TH_1500UA |
++ BYT_RT5640_OVCD_SF_0P75 |
++ BYT_RT5640_SSP0_AIF1 |
++ BYT_RT5640_MCLK_EN),
++ },
+ { /* Acer Iconia Tab 8 W1-810 */
+ .matches = {
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"),
+diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c
+index d2ed807abde95..767fa89d08708 100644
+--- a/sound/soc/intel/boards/sof_sdw.c
++++ b/sound/soc/intel/boards/sof_sdw.c
+@@ -213,6 +213,17 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
+ SOF_SDW_PCH_DMIC |
+ RT711_JD1),
+ },
++ {
++ /* NUC15 'Rooks County' LAPRC510 and LAPRC710 skews */
++ .callback = sof_sdw_quirk_cb,
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Intel(R) Client Systems"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "LAPRC"),
++ },
++ .driver_data = (void *)(SOF_SDW_TGL_HDMI |
++ SOF_SDW_PCH_DMIC |
++ RT711_JD2_100K),
++ },
+ /* TigerLake-SDCA devices */
+ {
+ .callback = sof_sdw_quirk_cb,
+diff --git a/sound/soc/intel/common/soc-acpi-intel-adl-match.c b/sound/soc/intel/common/soc-acpi-intel-adl-match.c
+index 28dd2046e4ac5..d8c80041388a7 100644
+--- a/sound/soc/intel/common/soc-acpi-intel-adl-match.c
++++ b/sound/soc/intel/common/soc-acpi-intel-adl-match.c
+@@ -354,6 +354,20 @@ static const struct snd_soc_acpi_link_adr adl_sdw_rt711_link0_rt1316_link3[] = {
+ {}
+ };
+
++static const struct snd_soc_acpi_link_adr adl_sdw_rt711_link0_rt1316_link2[] = {
++ {
++ .mask = BIT(0),
++ .num_adr = ARRAY_SIZE(rt711_sdca_0_adr),
++ .adr_d = rt711_sdca_0_adr,
++ },
++ {
++ .mask = BIT(2),
++ .num_adr = ARRAY_SIZE(rt1316_2_single_adr),
++ .adr_d = rt1316_2_single_adr,
++ },
++ {}
++};
++
+ static const struct snd_soc_acpi_adr_device mx8373_2_adr[] = {
+ {
+ .adr = 0x000223019F837300ull,
+@@ -624,6 +638,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_sdw_machines[] = {
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-adl-rt711-l0-rt1316-l3.tplg",
+ },
++ {
++ .link_mask = 0x5, /* 2 active links required */
++ .links = adl_sdw_rt711_link0_rt1316_link2,
++ .drv_name = "sof_sdw",
++ .sof_tplg_filename = "sof-adl-rt711-l0-rt1316-l2.tplg",
++ },
+ {
+ .link_mask = 0x1, /* link0 required */
+ .links = adl_rvp,
+diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
+index e7aa6f360cabe..d649b0cf4744f 100644
+--- a/sound/soc/soc-compress.c
++++ b/sound/soc/soc-compress.c
+@@ -622,6 +622,9 @@ int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
+ return ret;
+ }
+
++ /* inherit atomicity from DAI link */
++ be_pcm->nonatomic = rtd->dai_link->nonatomic;
++
+ rtd->pcm = be_pcm;
+ rtd->fe_compr = 1;
+ if (rtd->dai_link->dpcm_playback)
+diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
+index 579a44d81d9a3..d409b99af75b2 100644
+--- a/sound/soc/soc-pcm.c
++++ b/sound/soc/soc-pcm.c
+@@ -1649,10 +1649,14 @@ static void dpcm_runtime_setup_fe(struct snd_pcm_substream *substream)
+ struct snd_pcm_hardware *hw = &runtime->hw;
+ struct snd_soc_dai *dai;
+ int stream = substream->stream;
++ u64 formats = hw->formats;
+ int i;
+
+ soc_pcm_hw_init(hw);
+
++ if (formats)
++ hw->formats &= formats;
++
+ for_each_rtd_cpu_dais(fe, i, dai) {
+ struct snd_soc_pcm_stream *cpu_stream;
+
+diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
+index 271884e350035..efb4a3311cc59 100644
+--- a/sound/usb/quirks-table.h
++++ b/sound/usb/quirks-table.h
+@@ -3884,6 +3884,64 @@ YAMAHA_DEVICE(0x7010, "UB99"),
+ }
+ },
+
++{
++ /*
++ * PIONEER DJ DDJ-800
++ * PCM is 6 channels out, 6 channels in @ 44.1 fixed
++ * The Feedback for the output is the input
++ */
++ USB_DEVICE_VENDOR_SPEC(0x2b73, 0x0029),
++ .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
++ .ifnum = QUIRK_ANY_INTERFACE,
++ .type = QUIRK_COMPOSITE,
++ .data = (const struct snd_usb_audio_quirk[]) {
++ {
++ .ifnum = 0,
++ .type = QUIRK_AUDIO_FIXED_ENDPOINT,
++ .data = &(const struct audioformat) {
++ .formats = SNDRV_PCM_FMTBIT_S24_3LE,
++ .channels = 6,
++ .iface = 0,
++ .altsetting = 1,
++ .altset_idx = 1,
++ .endpoint = 0x01,
++ .ep_attr = USB_ENDPOINT_XFER_ISOC|
++ USB_ENDPOINT_SYNC_ASYNC,
++ .rates = SNDRV_PCM_RATE_44100,
++ .rate_min = 44100,
++ .rate_max = 44100,
++ .nr_rates = 1,
++ .rate_table = (unsigned int[]) { 44100 }
++ }
++ },
++ {
++ .ifnum = 0,
++ .type = QUIRK_AUDIO_FIXED_ENDPOINT,
++ .data = &(const struct audioformat) {
++ .formats = SNDRV_PCM_FMTBIT_S24_3LE,
++ .channels = 6,
++ .iface = 0,
++ .altsetting = 1,
++ .altset_idx = 1,
++ .endpoint = 0x82,
++ .ep_idx = 1,
++ .ep_attr = USB_ENDPOINT_XFER_ISOC|
++ USB_ENDPOINT_SYNC_ASYNC|
++ USB_ENDPOINT_USAGE_IMPLICIT_FB,
++ .rates = SNDRV_PCM_RATE_44100,
++ .rate_min = 44100,
++ .rate_max = 44100,
++ .nr_rates = 1,
++ .rate_table = (unsigned int[]) { 44100 }
++ }
++ },
++ {
++ .ifnum = -1
++ }
++ }
++ }
++},
++
+ /*
+ * MacroSilicon MS2100/MS2106 based AV capture cards
+ *
+diff --git a/tools/arch/x86/kcpuid/cpuid.csv b/tools/arch/x86/kcpuid/cpuid.csv
+index 4f1c4b0c29e98..9914bdf4fc9ec 100644
+--- a/tools/arch/x86/kcpuid/cpuid.csv
++++ b/tools/arch/x86/kcpuid/cpuid.csv
+@@ -184,8 +184,8 @@
+ 7, 0, EBX, 27, avx512er, AVX512 Exponent Reciproca instr
+ 7, 0, EBX, 28, avx512cd, AVX512 Conflict Detection instr
+ 7, 0, EBX, 29, sha, Intel Secure Hash Algorithm Extensions instr
+- 7, 0, EBX, 26, avx512bw, AVX512 Byte & Word instr
+- 7, 0, EBX, 28, avx512vl, AVX512 Vector Length Extentions (VL)
++ 7, 0, EBX, 30, avx512bw, AVX512 Byte & Word instr
++ 7, 0, EBX, 31, avx512vl, AVX512 Vector Length Extentions (VL)
+ 7, 0, ECX, 0, prefetchwt1, X
+ 7, 0, ECX, 1, avx512vbmi, AVX512 Vector Byte Manipulation Instructions
+ 7, 0, ECX, 2, umip, User-mode Instruction Prevention
+diff --git a/tools/bpf/bpftool/json_writer.c b/tools/bpf/bpftool/json_writer.c
+index 7fea83bedf488..bca5dd0a59e34 100644
+--- a/tools/bpf/bpftool/json_writer.c
++++ b/tools/bpf/bpftool/json_writer.c
+@@ -80,9 +80,6 @@ static void jsonw_puts(json_writer_t *self, const char *str)
+ case '"':
+ fputs("\\\"", self->out);
+ break;
+- case '\'':
+- fputs("\\\'", self->out);
+- break;
+ default:
+ putc(*str, self->out);
+ }
+diff --git a/tools/bpf/bpftool/xlated_dumper.c b/tools/bpf/bpftool/xlated_dumper.c
+index 6fe3134ae45d4..3daa05d9bbb73 100644
+--- a/tools/bpf/bpftool/xlated_dumper.c
++++ b/tools/bpf/bpftool/xlated_dumper.c
+@@ -372,8 +372,15 @@ void dump_xlated_for_graph(struct dump_data *dd, void *buf_start, void *buf_end,
+ struct bpf_insn *insn_start = buf_start;
+ struct bpf_insn *insn_end = buf_end;
+ struct bpf_insn *cur = insn_start;
++ bool double_insn = false;
+
+ for (; cur <= insn_end; cur++) {
++ if (double_insn) {
++ double_insn = false;
++ continue;
++ }
++ double_insn = cur->code == (BPF_LD | BPF_IMM | BPF_DW);
++
+ printf("% 4d: ", (int)(cur - insn_start + start_idx));
+ print_bpf_insn(&cbs, cur, true);
+ if (cur != insn_end)
+diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
+index 464ca3f01fe7a..bd260134c4201 100644
+--- a/tools/include/uapi/linux/bpf.h
++++ b/tools/include/uapi/linux/bpf.h
+@@ -6901,6 +6901,17 @@ struct bpf_list_node {
+ __u64 :64;
+ } __attribute__((aligned(8)));
+
++struct bpf_rb_root {
++ __u64 :64;
++ __u64 :64;
++} __attribute__((aligned(8)));
++
++struct bpf_rb_node {
++ __u64 :64;
++ __u64 :64;
++ __u64 :64;
++} __attribute__((aligned(8)));
++
+ struct bpf_sysctl {
+ __u32 write; /* Sysctl is being read (= 0) or written (= 1).
+ * Allows 1,2,4-byte read, but no write.
+diff --git a/tools/lib/bpf/gen_loader.c b/tools/lib/bpf/gen_loader.c
+index 23f5c46708f8f..b74c82bb831e6 100644
+--- a/tools/lib/bpf/gen_loader.c
++++ b/tools/lib/bpf/gen_loader.c
+@@ -804,11 +804,13 @@ static void emit_relo_ksym_btf(struct bpf_gen *gen, struct ksym_relo_desc *relo,
+ return;
+ /* try to copy from existing ldimm64 insn */
+ if (kdesc->ref > 1) {
+- move_blob2blob(gen, insn + offsetof(struct bpf_insn, imm), 4,
+- kdesc->insn + offsetof(struct bpf_insn, imm));
+ move_blob2blob(gen, insn + sizeof(struct bpf_insn) + offsetof(struct bpf_insn, imm), 4,
+ kdesc->insn + sizeof(struct bpf_insn) + offsetof(struct bpf_insn, imm));
+- /* jump over src_reg adjustment if imm is not 0, reuse BPF_REG_0 from move_blob2blob */
++ move_blob2blob(gen, insn + offsetof(struct bpf_insn, imm), 4,
++ kdesc->insn + offsetof(struct bpf_insn, imm));
++ /* jump over src_reg adjustment if imm (btf_id) is not 0, reuse BPF_REG_0 from move_blob2blob
++ * If btf_id is zero, clear BPF_PSEUDO_BTF_ID flag in src_reg of ld_imm64 insn
++ */
+ emit(gen, BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 3));
+ goto clear_src_reg;
+ }
+@@ -831,7 +833,7 @@ static void emit_relo_ksym_btf(struct bpf_gen *gen, struct ksym_relo_desc *relo,
+ emit(gen, BPF_STX_MEM(BPF_W, BPF_REG_8, BPF_REG_7,
+ sizeof(struct bpf_insn) + offsetof(struct bpf_insn, imm)));
+ /* skip src_reg adjustment */
+- emit(gen, BPF_JMP_IMM(BPF_JSGE, BPF_REG_7, 0, 3));
++ emit(gen, BPF_JMP_IMM(BPF_JA, 0, 0, 3));
+ clear_src_reg:
+ /* clear bpf_object__relocate_data's src_reg assignment, otherwise we get a verifier failure */
+ reg_mask = src_reg_mask();
+diff --git a/tools/objtool/check.c b/tools/objtool/check.c
+index ea1e7cdeb1b34..3b1e19894b21a 100644
+--- a/tools/objtool/check.c
++++ b/tools/objtool/check.c
+@@ -2913,17 +2913,6 @@ static int update_cfi_state(struct instruction *insn,
+ break;
+ }
+
+- if (!cfi->drap && op->src.reg == CFI_SP &&
+- op->dest.reg == CFI_BP && cfa->base == CFI_SP &&
+- check_reg_frame_pos(&regs[CFI_BP], -cfa->offset + op->src.offset)) {
+-
+- /* lea disp(%rsp), %rbp */
+- cfa->base = CFI_BP;
+- cfa->offset -= op->src.offset;
+- cfi->bp_scratch = false;
+- break;
+- }
+-
+ if (op->src.reg == CFI_SP && cfa->base == CFI_SP) {
+
+ /* drap: lea disp(%rsp), %drap */
+diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c
+index d4b04fa07a119..e088cfced1932 100644
+--- a/tools/perf/util/auxtrace.c
++++ b/tools/perf/util/auxtrace.c
+@@ -2444,6 +2444,7 @@ static int find_entire_kern_cb(void *arg, const char *name __maybe_unused,
+ char type, u64 start)
+ {
+ struct sym_args *args = arg;
++ u64 size;
+
+ if (!kallsyms__is_function(type))
+ return 0;
+@@ -2453,7 +2454,9 @@ static int find_entire_kern_cb(void *arg, const char *name __maybe_unused,
+ args->start = start;
+ }
+ /* Don't know exactly where the kernel ends, so we add a page */
+- args->size = round_up(start, page_size) + page_size - args->start;
++ size = round_up(start, page_size) + page_size - args->start;
++ if (size > args->size)
++ args->size = size;
+
+ return 0;
+ }
+diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
+index 0ac860c8dd2b8..7145c5890de02 100644
+--- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
++++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
+@@ -1998,6 +1998,8 @@ static void intel_pt_calc_cbr(struct intel_pt_decoder *decoder)
+
+ decoder->cbr = cbr;
+ decoder->cbr_cyc_to_tsc = decoder->max_non_turbo_ratio_fp / cbr;
++ decoder->cyc_ref_timestamp = decoder->timestamp;
++ decoder->cycle_cnt = 0;
+
+ intel_pt_mtc_cyc_cnt_cbr(decoder);
+ }
+diff --git a/tools/testing/selftests/bpf/network_helpers.c b/tools/testing/selftests/bpf/network_helpers.c
+index 01de33191226b..596caa1765820 100644
+--- a/tools/testing/selftests/bpf/network_helpers.c
++++ b/tools/testing/selftests/bpf/network_helpers.c
+@@ -95,7 +95,7 @@ static int __start_server(int type, int protocol, const struct sockaddr *addr,
+ if (reuseport &&
+ setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on))) {
+ log_err("Failed to set SO_REUSEPORT");
+- return -1;
++ goto error_close;
+ }
+
+ if (bind(fd, addr, addrlen) < 0) {
+diff --git a/tools/testing/selftests/bpf/prog_tests/align.c b/tools/testing/selftests/bpf/prog_tests/align.c
+index 4666f88f2bb4f..8baebb41541dc 100644
+--- a/tools/testing/selftests/bpf/prog_tests/align.c
++++ b/tools/testing/selftests/bpf/prog_tests/align.c
+@@ -575,14 +575,14 @@ static struct bpf_align_test tests[] = {
+ /* New unknown value in R7 is (4n), >= 76 */
+ {14, "R7_w=scalar(umin=76,umax=1096,var_off=(0x0; 0x7fc))"},
+ /* Adding it to packet pointer gives nice bounds again */
+- {16, "R5_w=pkt(id=3,off=0,r=0,umin=2,umax=1082,var_off=(0x2; 0xfffffffc)"},
++ {16, "R5_w=pkt(id=3,off=0,r=0,umin=2,umax=1082,var_off=(0x2; 0x7fc)"},
+ /* At the time the word size load is performed from R5,
+ * its total fixed offset is NET_IP_ALIGN + reg->off (0)
+ * which is 2. Then the variable offset is (4n+2), so
+ * the total offset is 4-byte aligned and meets the
+ * load's requirements.
+ */
+- {20, "R5=pkt(id=3,off=0,r=4,umin=2,umax=1082,var_off=(0x2; 0xfffffffc)"},
++ {20, "R5=pkt(id=3,off=0,r=4,umin=2,umax=1082,var_off=(0x2; 0x7fc)"},
+ },
+ },
+ };
+diff --git a/tools/testing/selftests/bpf/prog_tests/cg_storage_multi.c b/tools/testing/selftests/bpf/prog_tests/cg_storage_multi.c
+index 621c572221918..63ee892bc7573 100644
+--- a/tools/testing/selftests/bpf/prog_tests/cg_storage_multi.c
++++ b/tools/testing/selftests/bpf/prog_tests/cg_storage_multi.c
+@@ -56,8 +56,9 @@ static bool assert_storage_noexist(struct bpf_map *map, const void *key)
+
+ static bool connect_send(const char *cgroup_path)
+ {
+- bool res = true;
+ int server_fd = -1, client_fd = -1;
++ char message[] = "message";
++ bool res = true;
+
+ if (join_cgroup(cgroup_path))
+ goto out_clean;
+@@ -70,7 +71,10 @@ static bool connect_send(const char *cgroup_path)
+ if (client_fd < 0)
+ goto out_clean;
+
+- if (send(client_fd, "message", strlen("message"), 0) < 0)
++ if (send(client_fd, &message, sizeof(message), 0) < 0)
++ goto out_clean;
++
++ if (read(server_fd, &message, sizeof(message)) < 0)
+ goto out_clean;
+
+ res = false;
+diff --git a/tools/testing/selftests/bpf/prog_tests/get_stackid_cannot_attach.c b/tools/testing/selftests/bpf/prog_tests/get_stackid_cannot_attach.c
+index 5308de1ed478e..2715c68301f52 100644
+--- a/tools/testing/selftests/bpf/prog_tests/get_stackid_cannot_attach.c
++++ b/tools/testing/selftests/bpf/prog_tests/get_stackid_cannot_attach.c
+@@ -65,6 +65,7 @@ void test_get_stackid_cannot_attach(void)
+ skel->links.oncpu = bpf_program__attach_perf_event(skel->progs.oncpu,
+ pmu_fd);
+ ASSERT_OK_PTR(skel->links.oncpu, "attach_perf_event_callchain");
++ bpf_link__destroy(skel->links.oncpu);
+ close(pmu_fd);
+
+ /* add exclude_callchain_kernel, attach should fail */
+diff --git a/tools/testing/selftests/bpf/prog_tests/linked_list.c b/tools/testing/selftests/bpf/prog_tests/linked_list.c
+index 9a7d4c47af633..c456b34a823ac 100644
+--- a/tools/testing/selftests/bpf/prog_tests/linked_list.c
++++ b/tools/testing/selftests/bpf/prog_tests/linked_list.c
+@@ -58,12 +58,12 @@ static struct {
+ TEST(inner_map, pop_front)
+ TEST(inner_map, pop_back)
+ #undef TEST
+- { "map_compat_kprobe", "tracing progs cannot use bpf_list_head yet" },
+- { "map_compat_kretprobe", "tracing progs cannot use bpf_list_head yet" },
+- { "map_compat_tp", "tracing progs cannot use bpf_list_head yet" },
+- { "map_compat_perf", "tracing progs cannot use bpf_list_head yet" },
+- { "map_compat_raw_tp", "tracing progs cannot use bpf_list_head yet" },
+- { "map_compat_raw_tp_w", "tracing progs cannot use bpf_list_head yet" },
++ { "map_compat_kprobe", "tracing progs cannot use bpf_{list_head,rb_root} yet" },
++ { "map_compat_kretprobe", "tracing progs cannot use bpf_{list_head,rb_root} yet" },
++ { "map_compat_tp", "tracing progs cannot use bpf_{list_head,rb_root} yet" },
++ { "map_compat_perf", "tracing progs cannot use bpf_{list_head,rb_root} yet" },
++ { "map_compat_raw_tp", "tracing progs cannot use bpf_{list_head,rb_root} yet" },
++ { "map_compat_raw_tp_w", "tracing progs cannot use bpf_{list_head,rb_root} yet" },
+ { "obj_type_id_oor", "local type ID argument must be in range [0, U32_MAX]" },
+ { "obj_new_no_composite", "bpf_obj_new type ID argument must be of a struct" },
+ { "obj_new_no_struct", "bpf_obj_new type ID argument must be of a struct" },
+@@ -78,8 +78,6 @@ static struct {
+ { "direct_write_head", "direct access to bpf_list_head is disallowed" },
+ { "direct_read_node", "direct access to bpf_list_node is disallowed" },
+ { "direct_write_node", "direct access to bpf_list_node is disallowed" },
+- { "write_after_push_front", "only read is supported" },
+- { "write_after_push_back", "only read is supported" },
+ { "use_after_unlock_push_front", "invalid mem access 'scalar'" },
+ { "use_after_unlock_push_back", "invalid mem access 'scalar'" },
+ { "double_push_front", "arg#1 expected pointer to allocated object" },
+diff --git a/tools/testing/selftests/bpf/prog_tests/perf_event_stackmap.c b/tools/testing/selftests/bpf/prog_tests/perf_event_stackmap.c
+index 33144c9432aeb..f4aad35afae16 100644
+--- a/tools/testing/selftests/bpf/prog_tests/perf_event_stackmap.c
++++ b/tools/testing/selftests/bpf/prog_tests/perf_event_stackmap.c
+@@ -63,7 +63,8 @@ void test_perf_event_stackmap(void)
+ PERF_SAMPLE_BRANCH_NO_FLAGS |
+ PERF_SAMPLE_BRANCH_NO_CYCLES |
+ PERF_SAMPLE_BRANCH_CALL_STACK,
+- .sample_period = 5000,
++ .freq = 1,
++ .sample_freq = read_perf_max_sample_freq(),
+ .size = sizeof(struct perf_event_attr),
+ };
+ struct perf_event_stackmap *skel;
+diff --git a/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id_nmi.c b/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id_nmi.c
+index f4ea1a215ce4d..704f7f6c3704a 100644
+--- a/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id_nmi.c
++++ b/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id_nmi.c
+@@ -2,21 +2,6 @@
+ #include <test_progs.h>
+ #include "test_stacktrace_build_id.skel.h"
+
+-static __u64 read_perf_max_sample_freq(void)
+-{
+- __u64 sample_freq = 5000; /* fallback to 5000 on error */
+- FILE *f;
+- __u32 duration = 0;
+-
+- f = fopen("/proc/sys/kernel/perf_event_max_sample_rate", "r");
+- if (f == NULL)
+- return sample_freq;
+- CHECK(fscanf(f, "%llu", &sample_freq) != 1, "Get max sample rate",
+- "return default value: 5000,err %d\n", -errno);
+- fclose(f);
+- return sample_freq;
+-}
+-
+ void test_stacktrace_build_id_nmi(void)
+ {
+ int control_map_fd, stackid_hmap_fd, stackmap_fd;
+diff --git a/tools/testing/selftests/bpf/progs/linked_list.c b/tools/testing/selftests/bpf/progs/linked_list.c
+index 4ad88da5cda2d..4fa4a9b01bde3 100644
+--- a/tools/testing/selftests/bpf/progs/linked_list.c
++++ b/tools/testing/selftests/bpf/progs/linked_list.c
+@@ -260,7 +260,7 @@ int test_list_push_pop_multiple(struct bpf_spin_lock *lock, struct bpf_list_head
+ {
+ int ret;
+
+- ret = list_push_pop_multiple(lock ,head, false);
++ ret = list_push_pop_multiple(lock, head, false);
+ if (ret)
+ return ret;
+ return list_push_pop_multiple(lock, head, true);
+diff --git a/tools/testing/selftests/bpf/progs/linked_list_fail.c b/tools/testing/selftests/bpf/progs/linked_list_fail.c
+index 1d9017240e197..69cdc07cba13a 100644
+--- a/tools/testing/selftests/bpf/progs/linked_list_fail.c
++++ b/tools/testing/selftests/bpf/progs/linked_list_fail.c
+@@ -54,28 +54,44 @@
+ return 0; \
+ }
+
+-CHECK(kptr, push_front, &f->head);
+-CHECK(kptr, push_back, &f->head);
+ CHECK(kptr, pop_front, &f->head);
+ CHECK(kptr, pop_back, &f->head);
+
+-CHECK(global, push_front, &ghead);
+-CHECK(global, push_back, &ghead);
+ CHECK(global, pop_front, &ghead);
+ CHECK(global, pop_back, &ghead);
+
+-CHECK(map, push_front, &v->head);
+-CHECK(map, push_back, &v->head);
+ CHECK(map, pop_front, &v->head);
+ CHECK(map, pop_back, &v->head);
+
+-CHECK(inner_map, push_front, &iv->head);
+-CHECK(inner_map, push_back, &iv->head);
+ CHECK(inner_map, pop_front, &iv->head);
+ CHECK(inner_map, pop_back, &iv->head);
+
+ #undef CHECK
+
++#define CHECK(test, op, hexpr, nexpr) \
++ SEC("?tc") \
++ int test##_missing_lock_##op(void *ctx) \
++ { \
++ INIT; \
++ void (*p)(void *, void *) = (void *)&bpf_list_##op; \
++ p(hexpr, nexpr); \
++ return 0; \
++ }
++
++CHECK(kptr, push_front, &f->head, b);
++CHECK(kptr, push_back, &f->head, b);
++
++CHECK(global, push_front, &ghead, f);
++CHECK(global, push_back, &ghead, f);
++
++CHECK(map, push_front, &v->head, f);
++CHECK(map, push_back, &v->head, f);
++
++CHECK(inner_map, push_front, &iv->head, f);
++CHECK(inner_map, push_back, &iv->head, f);
++
++#undef CHECK
++
+ #define CHECK(test, op, lexpr, hexpr) \
+ SEC("?tc") \
+ int test##_incorrect_lock_##op(void *ctx) \
+@@ -108,11 +124,47 @@ CHECK(inner_map, pop_back, &iv->head);
+ CHECK(inner_map_global, op, &iv->lock, &ghead); \
+ CHECK(inner_map_map, op, &iv->lock, &v->head);
+
+-CHECK_OP(push_front);
+-CHECK_OP(push_back);
+ CHECK_OP(pop_front);
+ CHECK_OP(pop_back);
+
++#undef CHECK
++#undef CHECK_OP
++
++#define CHECK(test, op, lexpr, hexpr, nexpr) \
++ SEC("?tc") \
++ int test##_incorrect_lock_##op(void *ctx) \
++ { \
++ INIT; \
++ void (*p)(void *, void*) = (void *)&bpf_list_##op; \
++ bpf_spin_lock(lexpr); \
++ p(hexpr, nexpr); \
++ return 0; \
++ }
++
++#define CHECK_OP(op) \
++ CHECK(kptr_kptr, op, &f1->lock, &f2->head, b); \
++ CHECK(kptr_global, op, &f1->lock, &ghead, f); \
++ CHECK(kptr_map, op, &f1->lock, &v->head, f); \
++ CHECK(kptr_inner_map, op, &f1->lock, &iv->head, f); \
++ \
++ CHECK(global_global, op, &glock2, &ghead, f); \
++ CHECK(global_kptr, op, &glock, &f1->head, b); \
++ CHECK(global_map, op, &glock, &v->head, f); \
++ CHECK(global_inner_map, op, &glock, &iv->head, f); \
++ \
++ CHECK(map_map, op, &v->lock, &v2->head, f); \
++ CHECK(map_kptr, op, &v->lock, &f2->head, b); \
++ CHECK(map_global, op, &v->lock, &ghead, f); \
++ CHECK(map_inner_map, op, &v->lock, &iv->head, f); \
++ \
++ CHECK(inner_map_inner_map, op, &iv->lock, &iv2->head, f); \
++ CHECK(inner_map_kptr, op, &iv->lock, &f2->head, b); \
++ CHECK(inner_map_global, op, &iv->lock, &ghead, f); \
++ CHECK(inner_map_map, op, &iv->lock, &v->head, f);
++
++CHECK_OP(push_front);
++CHECK_OP(push_back);
++
+ #undef CHECK
+ #undef CHECK_OP
+ #undef INIT
+@@ -303,34 +355,6 @@ int direct_write_node(void *ctx)
+ return 0;
+ }
+
+-static __always_inline
+-int write_after_op(void (*push_op)(void *head, void *node))
+-{
+- struct foo *f;
+-
+- f = bpf_obj_new(typeof(*f));
+- if (!f)
+- return 0;
+- bpf_spin_lock(&glock);
+- push_op(&ghead, &f->node);
+- f->data = 42;
+- bpf_spin_unlock(&glock);
+-
+- return 0;
+-}
+-
+-SEC("?tc")
+-int write_after_push_front(void *ctx)
+-{
+- return write_after_op((void *)bpf_list_push_front);
+-}
+-
+-SEC("?tc")
+-int write_after_push_back(void *ctx)
+-{
+- return write_after_op((void *)bpf_list_push_back);
+-}
+-
+ static __always_inline
+ int use_after_unlock(void (*op)(void *head, void *node))
+ {
+diff --git a/tools/testing/selftests/bpf/test_xsk.sh b/tools/testing/selftests/bpf/test_xsk.sh
+index d821fd0985049..4e3ec38cbe68c 100755
+--- a/tools/testing/selftests/bpf/test_xsk.sh
++++ b/tools/testing/selftests/bpf/test_xsk.sh
+@@ -118,6 +118,7 @@ setup_vethPairs() {
+ ip link add ${VETH0} numtxqueues 4 numrxqueues 4 type veth peer name ${VETH1} numtxqueues 4 numrxqueues 4
+ if [ -f /proc/net/if_inet6 ]; then
+ echo 1 > /proc/sys/net/ipv6/conf/${VETH0}/disable_ipv6
++ echo 1 > /proc/sys/net/ipv6/conf/${VETH1}/disable_ipv6
+ fi
+ if [[ $verbose -eq 1 ]]; then
+ echo "setting up ${VETH1}: namespace: ${NS1}"
+diff --git a/tools/testing/selftests/bpf/testing_helpers.c b/tools/testing/selftests/bpf/testing_helpers.c
+index 9695318e8132d..9c3de39023f60 100644
+--- a/tools/testing/selftests/bpf/testing_helpers.c
++++ b/tools/testing/selftests/bpf/testing_helpers.c
+@@ -229,3 +229,23 @@ int bpf_test_load_program(enum bpf_prog_type type, const struct bpf_insn *insns,
+
+ return bpf_prog_load(type, NULL, license, insns, insns_cnt, &opts);
+ }
++
++__u64 read_perf_max_sample_freq(void)
++{
++ __u64 sample_freq = 5000; /* fallback to 5000 on error */
++ FILE *f;
++
++ f = fopen("/proc/sys/kernel/perf_event_max_sample_rate", "r");
++ if (f == NULL) {
++ printf("Failed to open /proc/sys/kernel/perf_event_max_sample_rate: err %d\n"
++ "return default value: 5000\n", -errno);
++ return sample_freq;
++ }
++ if (fscanf(f, "%llu", &sample_freq) != 1) {
++ printf("Failed to parse /proc/sys/kernel/perf_event_max_sample_rate: err %d\n"
++ "return default value: 5000\n", -errno);
++ }
++
++ fclose(f);
++ return sample_freq;
++}
+diff --git a/tools/testing/selftests/bpf/testing_helpers.h b/tools/testing/selftests/bpf/testing_helpers.h
+index 6ec00bf79cb55..eb8790f928e4c 100644
+--- a/tools/testing/selftests/bpf/testing_helpers.h
++++ b/tools/testing/selftests/bpf/testing_helpers.h
+@@ -20,3 +20,5 @@ struct test_filter_set;
+ int parse_test_list(const char *s,
+ struct test_filter_set *test_set,
+ bool is_glob_pattern);
++
++__u64 read_perf_max_sample_freq(void);
+diff --git a/tools/testing/selftests/bpf/xskxceiver.c b/tools/testing/selftests/bpf/xskxceiver.c
+index 1b9f48daa2257..b74dddf6bbbe5 100644
+--- a/tools/testing/selftests/bpf/xskxceiver.c
++++ b/tools/testing/selftests/bpf/xskxceiver.c
+@@ -649,7 +649,6 @@ static struct pkt_stream *pkt_stream_generate(struct xsk_umem_info *umem, u32 nb
+ if (!pkt_stream)
+ exit_with_error(ENOMEM);
+
+- pkt_stream->nb_pkts = nb_pkts;
+ for (i = 0; i < nb_pkts; i++) {
+ pkt_set(umem, &pkt_stream->pkts[i], (i % umem->num_frames) * umem->frame_size,
+ pkt_len);
+@@ -1142,7 +1141,14 @@ static int validate_rx_dropped(struct ifobject *ifobject)
+ if (err)
+ return TEST_FAILURE;
+
+- if (stats.rx_dropped == ifobject->pkt_stream->nb_pkts / 2)
++ /* The receiver calls getsockopt after receiving the last (valid)
++ * packet which is not the final packet sent in this test (valid and
++ * invalid packets are sent in alternating fashion with the final
++ * packet being invalid). Since the last packet may or may not have
++ * been dropped already, both outcomes must be allowed.
++ */
++ if (stats.rx_dropped == ifobject->pkt_stream->nb_pkts / 2 ||
++ stats.rx_dropped == ifobject->pkt_stream->nb_pkts / 2 - 1)
+ return TEST_PASS;
+
+ return TEST_FAILURE;
+@@ -1662,6 +1668,7 @@ static void testapp_single_pkt(struct test_spec *test)
+
+ static void testapp_invalid_desc(struct test_spec *test)
+ {
++ u64 umem_size = test->ifobj_tx->umem->num_frames * test->ifobj_tx->umem->frame_size;
+ struct pkt pkts[] = {
+ /* Zero packet address allowed */
+ {0, PKT_SIZE, 0, true},
+@@ -1672,9 +1679,9 @@ static void testapp_invalid_desc(struct test_spec *test)
+ /* Packet too large */
+ {0x2000, XSK_UMEM__INVALID_FRAME_SIZE, 0, false},
+ /* After umem ends */
+- {UMEM_SIZE, PKT_SIZE, 0, false},
++ {umem_size, PKT_SIZE, 0, false},
+ /* Straddle the end of umem */
+- {UMEM_SIZE - PKT_SIZE / 2, PKT_SIZE, 0, false},
++ {umem_size - PKT_SIZE / 2, PKT_SIZE, 0, false},
+ /* Straddle a page boundrary */
+ {0x3000 - PKT_SIZE / 2, PKT_SIZE, 0, false},
+ /* Straddle a 2K boundrary */
+@@ -1692,8 +1699,8 @@ static void testapp_invalid_desc(struct test_spec *test)
+ }
+
+ if (test->ifobj_tx->shared_umem) {
+- pkts[4].addr += UMEM_SIZE;
+- pkts[5].addr += UMEM_SIZE;
++ pkts[4].addr += umem_size;
++ pkts[5].addr += umem_size;
+ }
+
+ pkt_stream_generate_custom(test, pkts, ARRAY_SIZE(pkts));
+diff --git a/tools/testing/selftests/bpf/xskxceiver.h b/tools/testing/selftests/bpf/xskxceiver.h
+index edb76d2def9fe..292fc943b8fdf 100644
+--- a/tools/testing/selftests/bpf/xskxceiver.h
++++ b/tools/testing/selftests/bpf/xskxceiver.h
+@@ -52,7 +52,6 @@
+ #define THREAD_TMOUT 3
+ #define DEFAULT_PKT_CNT (4 * 1024)
+ #define DEFAULT_UMEM_BUFFERS (DEFAULT_PKT_CNT / 4)
+-#define UMEM_SIZE (DEFAULT_UMEM_BUFFERS * XSK_UMEM__DEFAULT_FRAME_SIZE)
+ #define RX_FULL_RXQSIZE 32
+ #define UMEM_HEADROOM_TEST_SIZE 128
+ #define XSK_UMEM__INVALID_FRAME_SIZE (XSK_UMEM__DEFAULT_FRAME_SIZE + 1)
+diff --git a/tools/testing/selftests/mount_setattr/mount_setattr_test.c b/tools/testing/selftests/mount_setattr/mount_setattr_test.c
+index 8c5fea68ae677..969647228817b 100644
+--- a/tools/testing/selftests/mount_setattr/mount_setattr_test.c
++++ b/tools/testing/selftests/mount_setattr/mount_setattr_test.c
+@@ -18,6 +18,7 @@
+ #include <grp.h>
+ #include <stdbool.h>
+ #include <stdarg.h>
++#include <linux/mount.h>
+
+ #include "../kselftest_harness.h"
+
+diff --git a/tools/testing/selftests/powerpc/pmu/sampling_tests/mmcra_thresh_marked_sample_test.c b/tools/testing/selftests/powerpc/pmu/sampling_tests/mmcra_thresh_marked_sample_test.c
+index 022cc1655eb52..75527876ad3c1 100644
+--- a/tools/testing/selftests/powerpc/pmu/sampling_tests/mmcra_thresh_marked_sample_test.c
++++ b/tools/testing/selftests/powerpc/pmu/sampling_tests/mmcra_thresh_marked_sample_test.c
+@@ -63,9 +63,9 @@ static int mmcra_thresh_marked_sample(void)
+ get_mmcra_thd_stop(get_reg_value(intr_regs, "MMCRA"), 4));
+ FAIL_IF(EV_CODE_EXTRACT(event.attr.config, marked) !=
+ get_mmcra_marked(get_reg_value(intr_regs, "MMCRA"), 4));
+- FAIL_IF(EV_CODE_EXTRACT(event.attr.config, sample >> 2) !=
++ FAIL_IF((EV_CODE_EXTRACT(event.attr.config, sample) >> 2) !=
+ get_mmcra_rand_samp_elig(get_reg_value(intr_regs, "MMCRA"), 4));
+- FAIL_IF(EV_CODE_EXTRACT(event.attr.config, sample & 0x3) !=
++ FAIL_IF((EV_CODE_EXTRACT(event.attr.config, sample) & 0x3) !=
+ get_mmcra_sample_mode(get_reg_value(intr_regs, "MMCRA"), 4));
+ FAIL_IF(EV_CODE_EXTRACT(event.attr.config, sm) !=
+ get_mmcra_sm(get_reg_value(intr_regs, "MMCRA"), 4));
+diff --git a/tools/testing/selftests/resctrl/cache.c b/tools/testing/selftests/resctrl/cache.c
+index 68ff856d36f0b..0485863a169f2 100644
+--- a/tools/testing/selftests/resctrl/cache.c
++++ b/tools/testing/selftests/resctrl/cache.c
+@@ -244,10 +244,12 @@ int cat_val(struct resctrl_val_param *param)
+ while (1) {
+ if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR))) {
+ ret = param->setup(1, param);
+- if (ret) {
++ if (ret == END_OF_TESTS) {
+ ret = 0;
+ break;
+ }
++ if (ret < 0)
++ break;
+ ret = reset_enable_llc_perf(bm_pid, param->cpu_no);
+ if (ret)
+ break;
+diff --git a/tools/testing/selftests/resctrl/cat_test.c b/tools/testing/selftests/resctrl/cat_test.c
+index 1c5e90c632548..2d3c7c77ab6cb 100644
+--- a/tools/testing/selftests/resctrl/cat_test.c
++++ b/tools/testing/selftests/resctrl/cat_test.c
+@@ -40,7 +40,7 @@ static int cat_setup(int num, ...)
+
+ /* Run NUM_OF_RUNS times */
+ if (p->num_of_runs >= NUM_OF_RUNS)
+- return -1;
++ return END_OF_TESTS;
+
+ if (p->num_of_runs == 0) {
+ sprintf(schemata, "%lx", p->mask);
+diff --git a/tools/testing/selftests/resctrl/cmt_test.c b/tools/testing/selftests/resctrl/cmt_test.c
+index 8968e36db99d7..3b0454e7fc826 100644
+--- a/tools/testing/selftests/resctrl/cmt_test.c
++++ b/tools/testing/selftests/resctrl/cmt_test.c
+@@ -32,7 +32,7 @@ static int cmt_setup(int num, ...)
+
+ /* Run NUM_OF_RUNS times */
+ if (p->num_of_runs >= NUM_OF_RUNS)
+- return -1;
++ return END_OF_TESTS;
+
+ p->num_of_runs++;
+
+diff --git a/tools/testing/selftests/resctrl/fill_buf.c b/tools/testing/selftests/resctrl/fill_buf.c
+index 56ccbeae0638d..c20d0a7ecbe63 100644
+--- a/tools/testing/selftests/resctrl/fill_buf.c
++++ b/tools/testing/selftests/resctrl/fill_buf.c
+@@ -68,6 +68,8 @@ static void *malloc_and_init_memory(size_t s)
+ size_t s64;
+
+ void *p = memalign(PAGE_SIZE, s);
++ if (!p)
++ return NULL;
+
+ p64 = (uint64_t *)p;
+ s64 = s / sizeof(uint64_t);
+diff --git a/tools/testing/selftests/resctrl/mba_test.c b/tools/testing/selftests/resctrl/mba_test.c
+index 1a1bdb6180cf2..97dc98c0c9497 100644
+--- a/tools/testing/selftests/resctrl/mba_test.c
++++ b/tools/testing/selftests/resctrl/mba_test.c
+@@ -28,6 +28,7 @@ static int mba_setup(int num, ...)
+ struct resctrl_val_param *p;
+ char allocation_str[64];
+ va_list param;
++ int ret;
+
+ va_start(param, num);
+ p = va_arg(param, struct resctrl_val_param *);
+@@ -41,11 +42,15 @@ static int mba_setup(int num, ...)
+ return 0;
+
+ if (allocation < ALLOCATION_MIN || allocation > ALLOCATION_MAX)
+- return -1;
++ return END_OF_TESTS;
+
+ sprintf(allocation_str, "%d", allocation);
+
+- write_schemata(p->ctrlgrp, allocation_str, p->cpu_no, p->resctrl_val);
++ ret = write_schemata(p->ctrlgrp, allocation_str, p->cpu_no,
++ p->resctrl_val);
++ if (ret < 0)
++ return ret;
++
+ allocation -= ALLOCATION_STEP;
+
+ return 0;
+diff --git a/tools/testing/selftests/resctrl/mbm_test.c b/tools/testing/selftests/resctrl/mbm_test.c
+index 8392e5c55ed02..280187628054d 100644
+--- a/tools/testing/selftests/resctrl/mbm_test.c
++++ b/tools/testing/selftests/resctrl/mbm_test.c
+@@ -95,7 +95,7 @@ static int mbm_setup(int num, ...)
+
+ /* Run NUM_OF_RUNS times */
+ if (num_of_runs++ >= NUM_OF_RUNS)
+- return -1;
++ return END_OF_TESTS;
+
+ va_start(param, num);
+ p = va_arg(param, struct resctrl_val_param *);
+diff --git a/tools/testing/selftests/resctrl/resctrl.h b/tools/testing/selftests/resctrl/resctrl.h
+index f0ded31fb3c7c..f44fa2de4d986 100644
+--- a/tools/testing/selftests/resctrl/resctrl.h
++++ b/tools/testing/selftests/resctrl/resctrl.h
+@@ -37,6 +37,8 @@
+ #define ARCH_INTEL 1
+ #define ARCH_AMD 2
+
++#define END_OF_TESTS 1
++
+ #define PARENT_EXIT(err_msg) \
+ do { \
+ perror(err_msg); \
+diff --git a/tools/testing/selftests/resctrl/resctrl_val.c b/tools/testing/selftests/resctrl/resctrl_val.c
+index b32b96356ec70..00864242d76c6 100644
+--- a/tools/testing/selftests/resctrl/resctrl_val.c
++++ b/tools/testing/selftests/resctrl/resctrl_val.c
+@@ -734,29 +734,24 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param)
+
+ /* Test runs until the callback setup() tells the test to stop. */
+ while (1) {
++ ret = param->setup(1, param);
++ if (ret == END_OF_TESTS) {
++ ret = 0;
++ break;
++ }
++ if (ret < 0)
++ break;
++
+ 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;
+- break;
+- }
+-
+ ret = measure_vals(param, &bw_resc_start);
+ if (ret)
+ break;
+ } else if (!strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR))) {
+- ret = param->setup(1, param);
+- if (ret) {
+- ret = 0;
+- break;
+- }
+ sleep(1);
+ ret = measure_cache_vals(param, bm_pid);
+ if (ret)
+ break;
+- } else {
+- break;
+ }
+ }
+
+diff --git a/tools/testing/selftests/tc-testing/tc-tests/qdiscs/fq.json b/tools/testing/selftests/tc-testing/tc-tests/qdiscs/fq.json
+index 8acb904d14193..3593fb8f79ad3 100644
+--- a/tools/testing/selftests/tc-testing/tc-tests/qdiscs/fq.json
++++ b/tools/testing/selftests/tc-testing/tc-tests/qdiscs/fq.json
+@@ -114,6 +114,28 @@
+ "$IP link del dev $DUMMY type dummy"
+ ]
+ },
++ {
++ "id": "10f7",
++ "name": "Create FQ with invalid initial_quantum setting",
++ "category": [
++ "qdisc",
++ "fq"
++ ],
++ "plugins": {
++ "requires": "nsPlugin"
++ },
++ "setup": [
++ "$IP link add dev $DUMMY type dummy || /bin/true"
++ ],
++ "cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root fq initial_quantum 0x80000000",
++ "expExitCode": "2",
++ "verifyCmd": "$TC qdisc show dev $DUMMY",
++ "matchPattern": "qdisc fq 1: root.*initial_quantum 2048Mb",
++ "matchCount": "0",
++ "teardown": [
++ "$IP link del dev $DUMMY type dummy"
++ ]
++ },
+ {
+ "id": "9398",
+ "name": "Create FQ with maxrate setting",
+diff --git a/tools/testing/selftests/user_events/ftrace_test.c b/tools/testing/selftests/user_events/ftrace_test.c
+index 404a2713dcae8..1bc26e6476fc3 100644
+--- a/tools/testing/selftests/user_events/ftrace_test.c
++++ b/tools/testing/selftests/user_events/ftrace_test.c
+@@ -294,6 +294,11 @@ TEST_F(user, write_events) {
+ ASSERT_NE(-1, writev(self->data_fd, (const struct iovec *)io, 3));
+ after = trace_bytes();
+ ASSERT_GT(after, before);
++
++ /* Negative index should fail with EINVAL */
++ reg.write_index = -1;
++ ASSERT_EQ(-1, writev(self->data_fd, (const struct iovec *)io, 3));
++ ASSERT_EQ(EINVAL, errno);
+ }
+
+ TEST_F(user, write_fault) {
+diff --git a/tools/verification/rv/src/rv.c b/tools/verification/rv/src/rv.c
+index e601cd9c411e1..1ddb855328165 100644
+--- a/tools/verification/rv/src/rv.c
++++ b/tools/verification/rv/src/rv.c
+@@ -74,7 +74,7 @@ static void rv_list(int argc, char **argv)
+ static void rv_mon(int argc, char **argv)
+ {
+ char *monitor_name;
+- int i, run;
++ int i, run = 0;
+
+ static const char *const usage[] = {
+ "",