summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--0000_README4
-rw-r--r--1011_linux-5.14.12.patch5808
2 files changed, 5812 insertions, 0 deletions
diff --git a/0000_README b/0000_README
index 6096d944..4456b487 100644
--- a/0000_README
+++ b/0000_README
@@ -91,6 +91,10 @@ Patch: 1010_linux-5.14.11.patch
From: http://www.kernel.org
Desc: Linux 5.14.11
+Patch: 1011_linux-5.14.12.patch
+From: http://www.kernel.org
+Desc: Linux 5.14.12
+
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/1011_linux-5.14.12.patch b/1011_linux-5.14.12.patch
new file mode 100644
index 00000000..5f0db51a
--- /dev/null
+++ b/1011_linux-5.14.12.patch
@@ -0,0 +1,5808 @@
+diff --git a/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi86.yaml b/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi86.yaml
+index 26932d2e86aba..8608b9dd8e9db 100644
+--- a/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi86.yaml
++++ b/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi86.yaml
+@@ -18,7 +18,7 @@ properties:
+ const: ti,sn65dsi86
+
+ reg:
+- const: 0x2d
++ enum: [ 0x2c, 0x2d ]
+
+ enable-gpios:
+ maxItems: 1
+diff --git a/Makefile b/Makefile
+index ca6c4472775cb..02cde08f4978e 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 5
+ PATCHLEVEL = 14
+-SUBLEVEL = 11
++SUBLEVEL = 12
+ EXTRAVERSION =
+ NAME = Opossums on Parade
+
+diff --git a/arch/arm/boot/dts/imx53-m53menlo.dts b/arch/arm/boot/dts/imx53-m53menlo.dts
+index d3082b9774e40..4f88e96d81ddb 100644
+--- a/arch/arm/boot/dts/imx53-m53menlo.dts
++++ b/arch/arm/boot/dts/imx53-m53menlo.dts
+@@ -56,6 +56,7 @@
+ panel {
+ compatible = "edt,etm0700g0dh6";
+ pinctrl-0 = <&pinctrl_display_gpio>;
++ pinctrl-names = "default";
+ enable-gpios = <&gpio6 0 GPIO_ACTIVE_HIGH>;
+
+ port {
+@@ -76,8 +77,7 @@
+ regulator-name = "vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+- gpio = <&gpio1 2 GPIO_ACTIVE_HIGH>;
+- enable-active-high;
++ gpio = <&gpio1 2 0>;
+ };
+ };
+
+diff --git a/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi b/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi
+index cb8b539eb29d1..e5c4dc65fbabf 100644
+--- a/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi
++++ b/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi
+@@ -5,6 +5,7 @@
+ #include <dt-bindings/gpio/gpio.h>
+ #include <dt-bindings/interrupt-controller/irq.h>
+ #include <dt-bindings/input/input.h>
++#include <dt-bindings/leds/common.h>
+ #include <dt-bindings/pwm/pwm.h>
+
+ / {
+@@ -277,6 +278,7 @@
+ led-cur = /bits/ 8 <0x20>;
+ max-cur = /bits/ 8 <0x60>;
+ reg = <0>;
++ color = <LED_COLOR_ID_RED>;
+ };
+
+ chan@1 {
+@@ -284,6 +286,7 @@
+ led-cur = /bits/ 8 <0x20>;
+ max-cur = /bits/ 8 <0x60>;
+ reg = <1>;
++ color = <LED_COLOR_ID_GREEN>;
+ };
+
+ chan@2 {
+@@ -291,6 +294,7 @@
+ led-cur = /bits/ 8 <0x20>;
+ max-cur = /bits/ 8 <0x60>;
+ reg = <2>;
++ color = <LED_COLOR_ID_BLUE>;
+ };
+
+ chan@3 {
+@@ -298,6 +302,7 @@
+ led-cur = /bits/ 8 <0x0>;
+ max-cur = /bits/ 8 <0x0>;
+ reg = <3>;
++ color = <LED_COLOR_ID_WHITE>;
+ };
+ };
+
+diff --git a/arch/arm/boot/dts/imx6qdl-pico.dtsi b/arch/arm/boot/dts/imx6qdl-pico.dtsi
+index 5de4ccb979163..f7a56d6b160c8 100644
+--- a/arch/arm/boot/dts/imx6qdl-pico.dtsi
++++ b/arch/arm/boot/dts/imx6qdl-pico.dtsi
+@@ -176,7 +176,18 @@
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-mode = "rgmii-id";
+ phy-reset-gpios = <&gpio1 26 GPIO_ACTIVE_LOW>;
++ phy-handle = <&phy>;
+ status = "okay";
++
++ mdio {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ phy: ethernet-phy@1 {
++ reg = <1>;
++ qca,clk-out-frequency = <125000000>;
++ };
++ };
+ };
+
+ &hdmi {
+diff --git a/arch/arm/boot/dts/imx6sx-sdb.dts b/arch/arm/boot/dts/imx6sx-sdb.dts
+index 5a63ca6157229..99f4cf777a384 100644
+--- a/arch/arm/boot/dts/imx6sx-sdb.dts
++++ b/arch/arm/boot/dts/imx6sx-sdb.dts
+@@ -114,7 +114,7 @@
+ compatible = "micron,n25q256a", "jedec,spi-nor";
+ spi-max-frequency = <29000000>;
+ spi-rx-bus-width = <4>;
+- spi-tx-bus-width = <4>;
++ spi-tx-bus-width = <1>;
+ reg = <0>;
+ };
+
+@@ -124,7 +124,7 @@
+ compatible = "micron,n25q256a", "jedec,spi-nor";
+ spi-max-frequency = <29000000>;
+ spi-rx-bus-width = <4>;
+- spi-tx-bus-width = <4>;
++ spi-tx-bus-width = <1>;
+ reg = <2>;
+ };
+ };
+diff --git a/arch/arm/boot/dts/imx6ul-14x14-evk.dtsi b/arch/arm/boot/dts/imx6ul-14x14-evk.dtsi
+index 779cc536566d6..a3fde3316c736 100644
+--- a/arch/arm/boot/dts/imx6ul-14x14-evk.dtsi
++++ b/arch/arm/boot/dts/imx6ul-14x14-evk.dtsi
+@@ -292,7 +292,7 @@
+ compatible = "micron,n25q256a", "jedec,spi-nor";
+ spi-max-frequency = <29000000>;
+ spi-rx-bus-width = <4>;
+- spi-tx-bus-width = <4>;
++ spi-tx-bus-width = <1>;
+ reg = <0>;
+ };
+ };
+diff --git a/arch/arm/boot/dts/omap3430-sdp.dts b/arch/arm/boot/dts/omap3430-sdp.dts
+index c5b9037184149..7d530ae3483b8 100644
+--- a/arch/arm/boot/dts/omap3430-sdp.dts
++++ b/arch/arm/boot/dts/omap3430-sdp.dts
+@@ -101,7 +101,7 @@
+
+ nand@1,0 {
+ compatible = "ti,omap2-nand";
+- reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
++ reg = <1 0 4>; /* CS1, offset 0, IO size 4 */
+ interrupt-parent = <&gpmc>;
+ interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+ <1 IRQ_TYPE_NONE>; /* termcount */
+diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi
+index e36d590e83732..72c4a9fc41a20 100644
+--- a/arch/arm/boot/dts/qcom-apq8064.dtsi
++++ b/arch/arm/boot/dts/qcom-apq8064.dtsi
+@@ -198,7 +198,7 @@
+ clock-frequency = <19200000>;
+ };
+
+- pxo_board {
++ pxo_board: pxo_board {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <27000000>;
+@@ -1148,7 +1148,7 @@
+ };
+
+ gpu: adreno-3xx@4300000 {
+- compatible = "qcom,adreno-3xx";
++ compatible = "qcom,adreno-320.2", "qcom,adreno";
+ reg = <0x04300000 0x20000>;
+ reg-names = "kgsl_3d0_reg_memory";
+ interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+@@ -1163,7 +1163,6 @@
+ <&mmcc GFX3D_AHB_CLK>,
+ <&mmcc GFX3D_AXI_CLK>,
+ <&mmcc MMSS_IMEM_AHB_CLK>;
+- qcom,chipid = <0x03020002>;
+
+ iommus = <&gfx3d 0
+ &gfx3d 1
+@@ -1306,7 +1305,7 @@
+ reg-names = "dsi_pll", "dsi_phy", "dsi_phy_regulator";
+ clock-names = "iface_clk", "ref";
+ clocks = <&mmcc DSI_M_AHB_CLK>,
+- <&cxo_board>;
++ <&pxo_board>;
+ };
+
+
+diff --git a/arch/arm/configs/gemini_defconfig b/arch/arm/configs/gemini_defconfig
+index d2d5f1cf815f2..e6ff844821cfb 100644
+--- a/arch/arm/configs/gemini_defconfig
++++ b/arch/arm/configs/gemini_defconfig
+@@ -76,6 +76,7 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y
+ CONFIG_DRM=y
+ CONFIG_DRM_PANEL_ILITEK_IL9322=y
+ CONFIG_DRM_TVE200=y
++CONFIG_FB=y
+ CONFIG_LOGO=y
+ CONFIG_USB=y
+ CONFIG_USB_MON=y
+diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
+index 90dcdfe3b3d0d..2dee383f90509 100644
+--- a/arch/arm/mach-at91/pm.c
++++ b/arch/arm/mach-at91/pm.c
+@@ -514,18 +514,22 @@ static const struct of_device_id ramc_ids[] __initconst = {
+ { /*sentinel*/ }
+ };
+
+-static __init void at91_dt_ramc(void)
++static __init int at91_dt_ramc(void)
+ {
+ struct device_node *np;
+ const struct of_device_id *of_id;
+ int idx = 0;
+ void *standby = NULL;
+ const struct ramc_info *ramc;
++ int ret;
+
+ for_each_matching_node_and_match(np, ramc_ids, &of_id) {
+ soc_pm.data.ramc[idx] = of_iomap(np, 0);
+- if (!soc_pm.data.ramc[idx])
+- panic(pr_fmt("unable to map ramc[%d] cpu registers\n"), idx);
++ if (!soc_pm.data.ramc[idx]) {
++ pr_err("unable to map ramc[%d] cpu registers\n", idx);
++ ret = -ENOMEM;
++ goto unmap_ramc;
++ }
+
+ ramc = of_id->data;
+ if (!standby)
+@@ -535,15 +539,26 @@ static __init void at91_dt_ramc(void)
+ idx++;
+ }
+
+- if (!idx)
+- panic(pr_fmt("unable to find compatible ram controller node in dtb\n"));
++ if (!idx) {
++ pr_err("unable to find compatible ram controller node in dtb\n");
++ ret = -ENODEV;
++ goto unmap_ramc;
++ }
+
+ if (!standby) {
+ pr_warn("ramc no standby function available\n");
+- return;
++ return 0;
+ }
+
+ at91_cpuidle_device.dev.platform_data = standby;
++
++ return 0;
++
++unmap_ramc:
++ while (idx)
++ iounmap(soc_pm.data.ramc[--idx]);
++
++ return ret;
+ }
+
+ static void at91rm9200_idle(void)
+@@ -866,6 +881,8 @@ static void __init at91_pm_init(void (*pm_idle)(void))
+
+ void __init at91rm9200_pm_init(void)
+ {
++ int ret;
++
+ if (!IS_ENABLED(CONFIG_SOC_AT91RM9200))
+ return;
+
+@@ -877,7 +894,9 @@ void __init at91rm9200_pm_init(void)
+ soc_pm.data.standby_mode = AT91_PM_STANDBY;
+ soc_pm.data.suspend_mode = AT91_PM_ULP0;
+
+- at91_dt_ramc();
++ ret = at91_dt_ramc();
++ if (ret)
++ return;
+
+ /*
+ * AT91RM9200 SDRAM low-power mode cannot be used with self-refresh.
+@@ -892,13 +911,17 @@ void __init sam9x60_pm_init(void)
+ static const int modes[] __initconst = {
+ AT91_PM_STANDBY, AT91_PM_ULP0, AT91_PM_ULP0_FAST, AT91_PM_ULP1,
+ };
++ int ret;
+
+ if (!IS_ENABLED(CONFIG_SOC_SAM9X60))
+ return;
+
+ at91_pm_modes_validate(modes, ARRAY_SIZE(modes));
+ at91_pm_modes_init();
+- at91_dt_ramc();
++ ret = at91_dt_ramc();
++ if (ret)
++ return;
++
+ at91_pm_init(NULL);
+
+ soc_pm.ws_ids = sam9x60_ws_ids;
+@@ -907,6 +930,8 @@ void __init sam9x60_pm_init(void)
+
+ void __init at91sam9_pm_init(void)
+ {
++ int ret;
++
+ if (!IS_ENABLED(CONFIG_SOC_AT91SAM9))
+ return;
+
+@@ -918,7 +943,10 @@ void __init at91sam9_pm_init(void)
+ soc_pm.data.standby_mode = AT91_PM_STANDBY;
+ soc_pm.data.suspend_mode = AT91_PM_ULP0;
+
+- at91_dt_ramc();
++ ret = at91_dt_ramc();
++ if (ret)
++ return;
++
+ at91_pm_init(at91sam9_idle);
+ }
+
+@@ -927,12 +955,16 @@ void __init sama5_pm_init(void)
+ static const int modes[] __initconst = {
+ AT91_PM_STANDBY, AT91_PM_ULP0, AT91_PM_ULP0_FAST,
+ };
++ int ret;
+
+ if (!IS_ENABLED(CONFIG_SOC_SAMA5))
+ return;
+
+ at91_pm_modes_validate(modes, ARRAY_SIZE(modes));
+- at91_dt_ramc();
++ ret = at91_dt_ramc();
++ if (ret)
++ return;
++
+ at91_pm_init(NULL);
+ }
+
+@@ -942,13 +974,17 @@ void __init sama5d2_pm_init(void)
+ AT91_PM_STANDBY, AT91_PM_ULP0, AT91_PM_ULP0_FAST, AT91_PM_ULP1,
+ AT91_PM_BACKUP,
+ };
++ int ret;
+
+ if (!IS_ENABLED(CONFIG_SOC_SAMA5D2))
+ return;
+
+ at91_pm_modes_validate(modes, ARRAY_SIZE(modes));
+ at91_pm_modes_init();
+- at91_dt_ramc();
++ ret = at91_dt_ramc();
++ if (ret)
++ return;
++
+ at91_pm_init(NULL);
+
+ soc_pm.ws_ids = sama5d2_ws_ids;
+diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c
+index 9244437cb1b9b..f2ecca339910a 100644
+--- a/arch/arm/mach-imx/pm-imx6.c
++++ b/arch/arm/mach-imx/pm-imx6.c
+@@ -10,6 +10,7 @@
+ #include <linux/io.h>
+ #include <linux/irq.h>
+ #include <linux/genalloc.h>
++#include <linux/irqchip/arm-gic.h>
+ #include <linux/mfd/syscon.h>
+ #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
+ #include <linux/of.h>
+@@ -619,6 +620,7 @@ static void __init imx6_pm_common_init(const struct imx6_pm_socdata
+
+ static void imx6_pm_stby_poweroff(void)
+ {
++ gic_cpu_if_down(0);
+ imx6_set_lpm(STOP_POWER_OFF);
+ imx6q_suspend_finish(0);
+
+diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
+index 12b26e04686fa..0c2936c7a3799 100644
+--- a/arch/arm/mach-omap2/omap_hwmod.c
++++ b/arch/arm/mach-omap2/omap_hwmod.c
+@@ -3614,6 +3614,8 @@ int omap_hwmod_init_module(struct device *dev,
+ oh->flags |= HWMOD_SWSUP_SIDLE_ACT;
+ if (data->cfg->quirks & SYSC_QUIRK_SWSUP_MSTANDBY)
+ oh->flags |= HWMOD_SWSUP_MSTANDBY;
++ if (data->cfg->quirks & SYSC_QUIRK_CLKDM_NOAUTO)
++ oh->flags |= HWMOD_CLKDM_NOAUTO;
+
+ error = omap_hwmod_check_module(dev, oh, data, sysc_fields,
+ rev_offs, sysc_offs, syss_offs,
+diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c
+index a951276f05475..a903b26cde409 100644
+--- a/arch/arm/net/bpf_jit_32.c
++++ b/arch/arm/net/bpf_jit_32.c
+@@ -36,6 +36,10 @@
+ * +-----+
+ * |RSVD | JIT scratchpad
+ * current ARM_SP => +-----+ <= (BPF_FP - STACK_SIZE + SCRATCH_SIZE)
++ * | ... | caller-saved registers
++ * +-----+
++ * | ... | arguments passed on stack
++ * ARM_SP during call => +-----|
+ * | |
+ * | ... | Function call stack
+ * | |
+@@ -63,6 +67,12 @@
+ *
+ * When popping registers off the stack at the end of a BPF function, we
+ * reference them via the current ARM_FP register.
++ *
++ * Some eBPF operations are implemented via a call to a helper function.
++ * Such calls are "invisible" in the eBPF code, so it is up to the calling
++ * program to preserve any caller-saved ARM registers during the call. The
++ * JIT emits code to push and pop those registers onto the stack, immediately
++ * above the callee stack frame.
+ */
+ #define CALLEE_MASK (1 << ARM_R4 | 1 << ARM_R5 | 1 << ARM_R6 | \
+ 1 << ARM_R7 | 1 << ARM_R8 | 1 << ARM_R9 | \
+@@ -70,6 +80,8 @@
+ #define CALLEE_PUSH_MASK (CALLEE_MASK | 1 << ARM_LR)
+ #define CALLEE_POP_MASK (CALLEE_MASK | 1 << ARM_PC)
+
++#define CALLER_MASK (1 << ARM_R0 | 1 << ARM_R1 | 1 << ARM_R2 | 1 << ARM_R3)
++
+ enum {
+ /* Stack layout - these are offsets from (top of stack - 4) */
+ BPF_R2_HI,
+@@ -464,6 +476,7 @@ static inline int epilogue_offset(const struct jit_ctx *ctx)
+
+ static inline void emit_udivmod(u8 rd, u8 rm, u8 rn, struct jit_ctx *ctx, u8 op)
+ {
++ const int exclude_mask = BIT(ARM_R0) | BIT(ARM_R1);
+ const s8 *tmp = bpf2a32[TMP_REG_1];
+
+ #if __LINUX_ARM_ARCH__ == 7
+@@ -495,11 +508,17 @@ static inline void emit_udivmod(u8 rd, u8 rm, u8 rn, struct jit_ctx *ctx, u8 op)
+ emit(ARM_MOV_R(ARM_R0, rm), ctx);
+ }
+
++ /* Push caller-saved registers on stack */
++ emit(ARM_PUSH(CALLER_MASK & ~exclude_mask), ctx);
++
+ /* Call appropriate function */
+ emit_mov_i(ARM_IP, op == BPF_DIV ?
+ (u32)jit_udiv32 : (u32)jit_mod32, ctx);
+ emit_blx_r(ARM_IP, ctx);
+
++ /* Restore caller-saved registers from stack */
++ emit(ARM_POP(CALLER_MASK & ~exclude_mask), ctx);
++
+ /* Save return value */
+ if (rd != ARM_R0)
+ emit(ARM_MOV_R(rd, ARM_R0), ctx);
+diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
+index 343ecf0e8973a..06b36cc65865c 100644
+--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
++++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
+@@ -405,9 +405,9 @@
+ interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <0>; /* fixed up by bootloader */
+ clocks = <&clockgen QORIQ_CLK_HWACCEL 1>;
+- voltage-ranges = <1800 1800 3300 3300>;
++ voltage-ranges = <1800 1800>;
+ sdhci,auto-cmd12;
+- broken-cd;
++ non-removable;
+ little-endian;
+ bus-width = <4>;
+ status = "disabled";
+diff --git a/arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi
+index 988f8ab679ad6..40f5e7a3b0644 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi
+@@ -91,7 +91,7 @@
+ #size-cells = <1>;
+ compatible = "jedec,spi-nor";
+ spi-max-frequency = <80000000>;
+- spi-tx-bus-width = <4>;
++ spi-tx-bus-width = <1>;
+ spi-rx-bus-width = <4>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/freescale/imx8mm-evk.dts b/arch/arm64/boot/dts/freescale/imx8mm-evk.dts
+index 4e2820d19244a..a2b24d4d4e3e7 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mm-evk.dts
++++ b/arch/arm64/boot/dts/freescale/imx8mm-evk.dts
+@@ -48,7 +48,7 @@
+ #size-cells = <1>;
+ compatible = "jedec,spi-nor";
+ spi-max-frequency = <80000000>;
+- spi-tx-bus-width = <4>;
++ spi-tx-bus-width = <1>;
+ spi-rx-bus-width = <4>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-som.dtsi
+index d0456daefda88..9db9b90bf2bc9 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-som.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-som.dtsi
+@@ -102,6 +102,7 @@
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <950000>;
+ regulator-boot-on;
++ regulator-always-on;
+ regulator-ramp-delay = <3125>;
+ nxp,dvs-run-voltage = <950000>;
+ nxp,dvs-standby-voltage = <850000>;
+diff --git a/arch/arm64/boot/dts/freescale/imx8mn-beacon-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mn-beacon-som.dtsi
+index 54eaf3d6055b1..3b2d627a03428 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mn-beacon-som.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mn-beacon-som.dtsi
+@@ -101,7 +101,7 @@
+ #size-cells = <1>;
+ compatible = "jedec,spi-nor";
+ spi-max-frequency = <80000000>;
+- spi-tx-bus-width = <4>;
++ spi-tx-bus-width = <1>;
+ spi-rx-bus-width = <4>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi
+index aa78e0d8c72b2..fc178eebf8aa4 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi
+@@ -74,7 +74,7 @@
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <80000000>;
+- spi-tx-bus-width = <4>;
++ spi-tx-bus-width = <1>;
+ spi-rx-bus-width = <4>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts
+index 4d2035e3dd7cc..4886f3e31587a 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts
++++ b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts
+@@ -337,6 +337,8 @@
+ #size-cells = <1>;
+ compatible = "micron,n25q256a", "jedec,spi-nor";
+ spi-max-frequency = <29000000>;
++ spi-tx-bus-width = <1>;
++ spi-rx-bus-width = <4>;
+ };
+ };
+
+diff --git a/arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dts b/arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dts
+index f593e4ff62e1c..564746d5000d5 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dts
++++ b/arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dts
+@@ -281,7 +281,7 @@
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0>;
+- spi-tx-bus-width = <4>;
++ spi-tx-bus-width = <1>;
+ spi-rx-bus-width = <4>;
+ m25p,fast-read;
+ spi-max-frequency = <50000000>;
+diff --git a/arch/arm64/boot/dts/qcom/pm8150.dtsi b/arch/arm64/boot/dts/qcom/pm8150.dtsi
+index c566a64b1373f..00385b1fd358f 100644
+--- a/arch/arm64/boot/dts/qcom/pm8150.dtsi
++++ b/arch/arm64/boot/dts/qcom/pm8150.dtsi
+@@ -48,7 +48,7 @@
+ #size-cells = <0>;
+
+ pon: power-on@800 {
+- compatible = "qcom,pm8916-pon";
++ compatible = "qcom,pm8998-pon";
+ reg = <0x0800>;
+
+ pon_pwrkey: pwrkey {
+diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi
+index c08f074106994..188c5768a55ae 100644
+--- a/arch/arm64/boot/dts/qcom/sc7280.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi
+@@ -1437,9 +1437,9 @@
+
+ cpufreq_hw: cpufreq@18591000 {
+ compatible = "qcom,cpufreq-epss";
+- reg = <0 0x18591100 0 0x900>,
+- <0 0x18592100 0 0x900>,
+- <0 0x18593100 0 0x900>;
++ reg = <0 0x18591000 0 0x1000>,
++ <0 0x18592000 0 0x1000>,
++ <0 0x18593000 0 0x1000>;
+ clocks = <&rpmhcc RPMH_CXO_CLK>, <&gcc GCC_GPLL0>;
+ clock-names = "xo", "alternate";
+ #freq-domain-cells = <1>;
+diff --git a/arch/mips/include/asm/mips-cps.h b/arch/mips/include/asm/mips-cps.h
+index 35fb8ee6dd33e..fd43d876892ec 100644
+--- a/arch/mips/include/asm/mips-cps.h
++++ b/arch/mips/include/asm/mips-cps.h
+@@ -10,8 +10,6 @@
+ #include <linux/io.h>
+ #include <linux/types.h>
+
+-#include <asm/mips-boards/launch.h>
+-
+ extern unsigned long __cps_access_bad_size(void)
+ __compiletime_error("Bad size for CPS accessor");
+
+@@ -167,30 +165,11 @@ static inline uint64_t mips_cps_cluster_config(unsigned int cluster)
+ */
+ static inline unsigned int mips_cps_numcores(unsigned int cluster)
+ {
+- unsigned int ncores;
+-
+ if (!mips_cm_present())
+ return 0;
+
+ /* Add one before masking to handle 0xff indicating no cores */
+- ncores = (mips_cps_cluster_config(cluster) + 1) & CM_GCR_CONFIG_PCORES;
+-
+- if (IS_ENABLED(CONFIG_SOC_MT7621)) {
+- struct cpulaunch *launch;
+-
+- /*
+- * Ralink MT7621S SoC is single core, but the GCR_CONFIG method
+- * always reports 2 cores. Check the second core's LAUNCH_FREADY
+- * flag to detect if the second core is missing. This method
+- * only works before the core has been started.
+- */
+- launch = (struct cpulaunch *)CKSEG0ADDR(CPULAUNCH);
+- launch += 2; /* MT7621 has 2 VPEs per core */
+- if (!(launch->flags & LAUNCH_FREADY))
+- ncores = 1;
+- }
+-
+- return ncores;
++ return (mips_cps_cluster_config(cluster) + 1) & CM_GCR_CONFIG_PCORES;
+ }
+
+ /**
+diff --git a/arch/powerpc/boot/dts/fsl/t1023rdb.dts b/arch/powerpc/boot/dts/fsl/t1023rdb.dts
+index 5ba6fbfca2742..f82f85c65964c 100644
+--- a/arch/powerpc/boot/dts/fsl/t1023rdb.dts
++++ b/arch/powerpc/boot/dts/fsl/t1023rdb.dts
+@@ -154,7 +154,7 @@
+
+ fm1mac3: ethernet@e4000 {
+ phy-handle = <&sgmii_aqr_phy3>;
+- phy-connection-type = "sgmii-2500";
++ phy-connection-type = "2500base-x";
+ sleep = <&rcpm 0x20000000>;
+ };
+
+diff --git a/arch/powerpc/include/asm/book3s/32/kup.h b/arch/powerpc/include/asm/book3s/32/kup.h
+index d4b145b279f6c..9f38040f0641d 100644
+--- a/arch/powerpc/include/asm/book3s/32/kup.h
++++ b/arch/powerpc/include/asm/book3s/32/kup.h
+@@ -136,6 +136,14 @@ static inline void kuap_kernel_restore(struct pt_regs *regs, unsigned long kuap)
+ if (kuap_is_disabled())
+ return;
+
++ if (unlikely(kuap != KUAP_NONE)) {
++ current->thread.kuap = KUAP_NONE;
++ kuap_lock(kuap, false);
++ }
++
++ if (likely(regs->kuap == KUAP_NONE))
++ return;
++
+ current->thread.kuap = regs->kuap;
+
+ kuap_unlock(regs->kuap, false);
+diff --git a/arch/powerpc/include/asm/interrupt.h b/arch/powerpc/include/asm/interrupt.h
+index 6b800d3e2681f..a925dbc5833c7 100644
+--- a/arch/powerpc/include/asm/interrupt.h
++++ b/arch/powerpc/include/asm/interrupt.h
+@@ -525,10 +525,9 @@ static __always_inline long ____##func(struct pt_regs *regs)
+ /* kernel/traps.c */
+ DECLARE_INTERRUPT_HANDLER_NMI(system_reset_exception);
+ #ifdef CONFIG_PPC_BOOK3S_64
+-DECLARE_INTERRUPT_HANDLER_ASYNC(machine_check_exception);
+-#else
+-DECLARE_INTERRUPT_HANDLER_NMI(machine_check_exception);
++DECLARE_INTERRUPT_HANDLER_ASYNC(machine_check_exception_async);
+ #endif
++DECLARE_INTERRUPT_HANDLER_NMI(machine_check_exception);
+ DECLARE_INTERRUPT_HANDLER(SMIException);
+ DECLARE_INTERRUPT_HANDLER(handle_hmi_exception);
+ DECLARE_INTERRUPT_HANDLER(unknown_exception);
+diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c
+index 111249fd619de..038ce8d9061d1 100644
+--- a/arch/powerpc/kernel/dma-iommu.c
++++ b/arch/powerpc/kernel/dma-iommu.c
+@@ -184,6 +184,15 @@ u64 dma_iommu_get_required_mask(struct device *dev)
+ struct iommu_table *tbl = get_iommu_table_base(dev);
+ u64 mask;
+
++ if (dev_is_pci(dev)) {
++ u64 bypass_mask = dma_direct_get_required_mask(dev);
++
++ if (dma_iommu_dma_supported(dev, bypass_mask)) {
++ dev_info(dev, "%s: returning bypass mask 0x%llx\n", __func__, bypass_mask);
++ return bypass_mask;
++ }
++ }
++
+ if (!tbl)
+ return 0;
+
+diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
+index 37859e62a8dcb..eaf1f72131a18 100644
+--- a/arch/powerpc/kernel/exceptions-64s.S
++++ b/arch/powerpc/kernel/exceptions-64s.S
+@@ -1243,7 +1243,7 @@ EXC_COMMON_BEGIN(machine_check_common)
+ li r10,MSR_RI
+ mtmsrd r10,1
+ addi r3,r1,STACK_FRAME_OVERHEAD
+- bl machine_check_exception
++ bl machine_check_exception_async
+ b interrupt_return_srr
+
+
+@@ -1303,7 +1303,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
+ subi r12,r12,1
+ sth r12,PACA_IN_MCE(r13)
+
+- /* Invoke machine_check_exception to print MCE event and panic. */
++ /*
++ * Invoke machine_check_exception to print MCE event and panic.
++ * This is the NMI version of the handler because we are called from
++ * the early handler which is a true NMI.
++ */
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ bl machine_check_exception
+
+@@ -1665,27 +1669,30 @@ EXC_COMMON_BEGIN(program_check_common)
+ */
+
+ andi. r10,r12,MSR_PR
+- bne 2f /* If userspace, go normal path */
++ bne .Lnormal_stack /* If userspace, go normal path */
+
+ andis. r10,r12,(SRR1_PROGTM)@h
+- bne 1f /* If TM, emergency */
++ bne .Lemergency_stack /* If TM, emergency */
+
+ cmpdi r1,-INT_FRAME_SIZE /* check if r1 is in userspace */
+- blt 2f /* normal path if not */
++ blt .Lnormal_stack /* normal path if not */
+
+ /* Use the emergency stack */
+-1: andi. r10,r12,MSR_PR /* Set CR0 correctly for label */
++.Lemergency_stack:
++ andi. r10,r12,MSR_PR /* Set CR0 correctly for label */
+ /* 3 in EXCEPTION_PROLOG_COMMON */
+ mr r10,r1 /* Save r1 */
+ ld r1,PACAEMERGSP(r13) /* Use emergency stack */
+ subi r1,r1,INT_FRAME_SIZE /* alloc stack frame */
+ __ISTACK(program_check)=0
+ __GEN_COMMON_BODY program_check
+- b 3f
+-2:
++ b .Ldo_program_check
++
++.Lnormal_stack:
+ __ISTACK(program_check)=1
+ __GEN_COMMON_BODY program_check
+-3:
++
++.Ldo_program_check:
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ bl program_check_exception
+ REST_NVGPRS(r1) /* instruction emulation may change GPRs */
+diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
+index d56254f05e174..08356ec9bfed4 100644
+--- a/arch/powerpc/kernel/traps.c
++++ b/arch/powerpc/kernel/traps.c
+@@ -341,10 +341,16 @@ static bool exception_common(int signr, struct pt_regs *regs, int code,
+ return false;
+ }
+
+- show_signal_msg(signr, regs, code, addr);
++ /*
++ * Must not enable interrupts even for user-mode exception, because
++ * this can be called from machine check, which may be a NMI or IRQ
++ * which don't like interrupts being enabled. Could check for
++ * in_hardirq || in_nmi perhaps, but there doesn't seem to be a good
++ * reason why _exception() should enable irqs for an exception handler,
++ * the handlers themselves do that directly.
++ */
+
+- if (arch_irqs_disabled())
+- interrupt_cond_local_irq_enable(regs);
++ show_signal_msg(signr, regs, code, addr);
+
+ current->thread.trap_nr = code;
+
+@@ -791,24 +797,22 @@ void die_mce(const char *str, struct pt_regs *regs, long err)
+ * do_exit() checks for in_interrupt() and panics in that case, so
+ * exit the irq/nmi before calling die.
+ */
+- if (IS_ENABLED(CONFIG_PPC_BOOK3S_64))
+- irq_exit();
+- else
++ if (in_nmi())
+ nmi_exit();
++ else
++ irq_exit();
+ die(str, regs, err);
+ }
+
+ /*
+- * BOOK3S_64 does not call this handler as a non-maskable interrupt
++ * BOOK3S_64 does not usually call this handler as a non-maskable interrupt
+ * (it uses its own early real-mode handler to handle the MCE proper
+ * and then raises irq_work to call this handler when interrupts are
+- * enabled).
++ * enabled). The only time when this is not true is if the early handler
++ * is unrecoverable, then it does call this directly to try to get a
++ * message out.
+ */
+-#ifdef CONFIG_PPC_BOOK3S_64
+-DEFINE_INTERRUPT_HANDLER_ASYNC(machine_check_exception)
+-#else
+-DEFINE_INTERRUPT_HANDLER_NMI(machine_check_exception)
+-#endif
++static void __machine_check_exception(struct pt_regs *regs)
+ {
+ int recover = 0;
+
+@@ -842,12 +846,19 @@ bail:
+ /* Must die if the interrupt is not recoverable */
+ if (!(regs->msr & MSR_RI))
+ die_mce("Unrecoverable Machine check", regs, SIGBUS);
++}
+
+ #ifdef CONFIG_PPC_BOOK3S_64
+- return;
+-#else
+- return 0;
++DEFINE_INTERRUPT_HANDLER_ASYNC(machine_check_exception_async)
++{
++ __machine_check_exception(regs);
++}
+ #endif
++DEFINE_INTERRUPT_HANDLER_NMI(machine_check_exception)
++{
++ __machine_check_exception(regs);
++
++ return 0;
+ }
+
+ DEFINE_INTERRUPT_HANDLER(SMIException) /* async? */
+diff --git a/arch/powerpc/net/bpf_jit_comp32.c b/arch/powerpc/net/bpf_jit_comp32.c
+index beb12cbc8c299..a7759aa8043d2 100644
+--- a/arch/powerpc/net/bpf_jit_comp32.c
++++ b/arch/powerpc/net/bpf_jit_comp32.c
+@@ -355,7 +355,7 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
+ PPC_LI32(_R0, imm);
+ EMIT(PPC_RAW_ADDC(dst_reg, dst_reg, _R0));
+ }
+- if (imm >= 0)
++ if (imm >= 0 || (BPF_OP(code) == BPF_SUB && imm == 0x80000000))
+ EMIT(PPC_RAW_ADDZE(dst_reg_h, dst_reg_h));
+ else
+ EMIT(PPC_RAW_ADDME(dst_reg_h, dst_reg_h));
+@@ -623,7 +623,7 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
+ EMIT(PPC_RAW_LI(dst_reg_h, 0));
+ break;
+ case BPF_ALU | BPF_ARSH | BPF_X: /* (s32) dst >>= src */
+- EMIT(PPC_RAW_SRAW(dst_reg_h, dst_reg, src_reg));
++ EMIT(PPC_RAW_SRAW(dst_reg, dst_reg, src_reg));
+ break;
+ case BPF_ALU64 | BPF_ARSH | BPF_X: /* (s64) dst >>= src */
+ bpf_set_seen_register(ctx, tmp_reg);
+@@ -1073,7 +1073,7 @@ cond_branch:
+ break;
+ case BPF_JMP32 | BPF_JSET | BPF_K:
+ /* andi does not sign-extend the immediate */
+- if (imm >= -32768 && imm < 32768) {
++ if (imm >= 0 && imm < 32768) {
+ /* PPC_ANDI is _only/always_ dot-form */
+ EMIT(PPC_RAW_ANDI(_R0, dst_reg, imm));
+ } else {
+@@ -1103,7 +1103,7 @@ cond_branch:
+ return -EOPNOTSUPP;
+ }
+ if (BPF_CLASS(code) == BPF_ALU && !fp->aux->verifier_zext &&
+- !insn_is_zext(&insn[i + 1]))
++ !insn_is_zext(&insn[i + 1]) && !(BPF_OP(code) == BPF_END && imm == 64))
+ EMIT(PPC_RAW_LI(dst_reg_h, 0));
+ }
+
+diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c
+index b87a63dba9c8f..dff4a2930970b 100644
+--- a/arch/powerpc/net/bpf_jit_comp64.c
++++ b/arch/powerpc/net/bpf_jit_comp64.c
+@@ -328,18 +328,25 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
+ EMIT(PPC_RAW_SUB(dst_reg, dst_reg, src_reg));
+ goto bpf_alu32_trunc;
+ case BPF_ALU | BPF_ADD | BPF_K: /* (u32) dst += (u32) imm */
+- case BPF_ALU | BPF_SUB | BPF_K: /* (u32) dst -= (u32) imm */
+ case BPF_ALU64 | BPF_ADD | BPF_K: /* dst += imm */
++ if (!imm) {
++ goto bpf_alu32_trunc;
++ } else if (imm >= -32768 && imm < 32768) {
++ EMIT(PPC_RAW_ADDI(dst_reg, dst_reg, IMM_L(imm)));
++ } else {
++ PPC_LI32(b2p[TMP_REG_1], imm);
++ EMIT(PPC_RAW_ADD(dst_reg, dst_reg, b2p[TMP_REG_1]));
++ }
++ goto bpf_alu32_trunc;
++ case BPF_ALU | BPF_SUB | BPF_K: /* (u32) dst -= (u32) imm */
+ case BPF_ALU64 | BPF_SUB | BPF_K: /* dst -= imm */
+- if (BPF_OP(code) == BPF_SUB)
+- imm = -imm;
+- if (imm) {
+- if (imm >= -32768 && imm < 32768)
+- EMIT(PPC_RAW_ADDI(dst_reg, dst_reg, IMM_L(imm)));
+- else {
+- PPC_LI32(b2p[TMP_REG_1], imm);
+- EMIT(PPC_RAW_ADD(dst_reg, dst_reg, b2p[TMP_REG_1]));
+- }
++ if (!imm) {
++ goto bpf_alu32_trunc;
++ } else if (imm > -32768 && imm <= 32768) {
++ EMIT(PPC_RAW_ADDI(dst_reg, dst_reg, IMM_L(-imm)));
++ } else {
++ PPC_LI32(b2p[TMP_REG_1], imm);
++ EMIT(PPC_RAW_SUB(dst_reg, dst_reg, b2p[TMP_REG_1]));
+ }
+ goto bpf_alu32_trunc;
+ case BPF_ALU | BPF_MUL | BPF_X: /* (u32) dst *= (u32) src */
+@@ -389,8 +396,14 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
+ case BPF_ALU64 | BPF_DIV | BPF_K: /* dst /= imm */
+ if (imm == 0)
+ return -EINVAL;
+- else if (imm == 1)
+- goto bpf_alu32_trunc;
++ if (imm == 1) {
++ if (BPF_OP(code) == BPF_DIV) {
++ goto bpf_alu32_trunc;
++ } else {
++ EMIT(PPC_RAW_LI(dst_reg, 0));
++ break;
++ }
++ }
+
+ PPC_LI32(b2p[TMP_REG_1], imm);
+ switch (BPF_CLASS(code)) {
+diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c
+index bc15200852b7c..09fafcf2d3a06 100644
+--- a/arch/powerpc/platforms/pseries/eeh_pseries.c
++++ b/arch/powerpc/platforms/pseries/eeh_pseries.c
+@@ -867,6 +867,10 @@ static int __init eeh_pseries_init(void)
+ if (is_kdump_kernel() || reset_devices) {
+ pr_info("Issue PHB reset ...\n");
+ list_for_each_entry(phb, &hose_list, list_node) {
++ // Skip if the slot is empty
++ if (list_empty(&PCI_DN(phb->dn)->child_list))
++ continue;
++
+ pdn = list_first_entry(&PCI_DN(phb->dn)->child_list, struct pci_dn, list);
+ config_addr = pseries_eeh_get_pe_config_addr(pdn);
+
+diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
+index bc74afdbf31e2..83ee0e71204cb 100644
+--- a/arch/riscv/Makefile
++++ b/arch/riscv/Makefile
+@@ -108,6 +108,12 @@ PHONY += vdso_install
+ vdso_install:
+ $(Q)$(MAKE) $(build)=arch/riscv/kernel/vdso $@
+
++ifeq ($(CONFIG_MMU),y)
++prepare: vdso_prepare
++vdso_prepare: prepare0
++ $(Q)$(MAKE) $(build)=arch/riscv/kernel/vdso include/generated/vdso-offsets.h
++endif
++
+ ifneq ($(CONFIG_XIP_KERNEL),y)
+ ifeq ($(CONFIG_RISCV_M_MODE)$(CONFIG_SOC_CANAAN),yy)
+ KBUILD_IMAGE := $(boot)/loader.bin
+diff --git a/arch/riscv/include/asm/syscall.h b/arch/riscv/include/asm/syscall.h
+index b933b1583c9fd..34fbb3ea21d5b 100644
+--- a/arch/riscv/include/asm/syscall.h
++++ b/arch/riscv/include/asm/syscall.h
+@@ -82,4 +82,5 @@ static inline int syscall_get_arch(struct task_struct *task)
+ #endif
+ }
+
++asmlinkage long sys_riscv_flush_icache(uintptr_t, uintptr_t, uintptr_t);
+ #endif /* _ASM_RISCV_SYSCALL_H */
+diff --git a/arch/riscv/include/asm/vdso.h b/arch/riscv/include/asm/vdso.h
+index 1453a2f563bcc..208e31bc5d1c2 100644
+--- a/arch/riscv/include/asm/vdso.h
++++ b/arch/riscv/include/asm/vdso.h
+@@ -8,27 +8,32 @@
+ #ifndef _ASM_RISCV_VDSO_H
+ #define _ASM_RISCV_VDSO_H
+
+-#include <linux/types.h>
+
+-#ifndef CONFIG_GENERIC_TIME_VSYSCALL
+-struct vdso_data {
+-};
+-#endif
++/*
++ * All systems with an MMU have a VDSO, but systems without an MMU don't
++ * support shared libraries and therefor don't have one.
++ */
++#ifdef CONFIG_MMU
+
++#include <linux/types.h>
+ /*
+- * The VDSO symbols are mapped into Linux so we can just use regular symbol
+- * addressing to get their offsets in userspace. The symbols are mapped at an
+- * offset of 0, but since the linker must support setting weak undefined
+- * symbols to the absolute address 0 it also happens to support other low
+- * addresses even when the code model suggests those low addresses would not
+- * otherwise be availiable.
++ * All systems with an MMU have a VDSO, but systems without an MMU don't
++ * support shared libraries and therefor don't have one.
+ */
++#ifdef CONFIG_MMU
++
++#define __VVAR_PAGES 1
++
++#ifndef __ASSEMBLY__
++#include <generated/vdso-offsets.h>
++
+ #define VDSO_SYMBOL(base, name) \
+-({ \
+- extern const char __vdso_##name[]; \
+- (void __user *)((unsigned long)(base) + __vdso_##name); \
+-})
++ (void __user *)((unsigned long)(base) + __vdso_##name##_offset)
++
++#endif /* CONFIG_MMU */
++
++#endif /* !__ASSEMBLY__ */
+
+-asmlinkage long sys_riscv_flush_icache(uintptr_t, uintptr_t, uintptr_t);
++#endif /* CONFIG_MMU */
+
+ #endif /* _ASM_RISCV_VDSO_H */
+diff --git a/arch/riscv/include/uapi/asm/unistd.h b/arch/riscv/include/uapi/asm/unistd.h
+index 4b989ae15d59f..8062996c2dfd0 100644
+--- a/arch/riscv/include/uapi/asm/unistd.h
++++ b/arch/riscv/include/uapi/asm/unistd.h
+@@ -18,9 +18,10 @@
+ #ifdef __LP64__
+ #define __ARCH_WANT_NEW_STAT
+ #define __ARCH_WANT_SET_GET_RLIMIT
+-#define __ARCH_WANT_SYS_CLONE3
+ #endif /* __LP64__ */
+
++#define __ARCH_WANT_SYS_CLONE3
++
+ #include <asm-generic/unistd.h>
+
+ /*
+diff --git a/arch/riscv/kernel/syscall_table.c b/arch/riscv/kernel/syscall_table.c
+index a63c667c27b35..44b1420a22705 100644
+--- a/arch/riscv/kernel/syscall_table.c
++++ b/arch/riscv/kernel/syscall_table.c
+@@ -7,7 +7,6 @@
+ #include <linux/linkage.h>
+ #include <linux/syscalls.h>
+ #include <asm-generic/syscalls.h>
+-#include <asm/vdso.h>
+ #include <asm/syscall.h>
+
+ #undef __SYSCALL
+diff --git a/arch/riscv/kernel/vdso.c b/arch/riscv/kernel/vdso.c
+index 25a3b88495991..b70956d804081 100644
+--- a/arch/riscv/kernel/vdso.c
++++ b/arch/riscv/kernel/vdso.c
+@@ -12,14 +12,24 @@
+ #include <linux/binfmts.h>
+ #include <linux/err.h>
+ #include <asm/page.h>
++#include <asm/vdso.h>
++
+ #ifdef CONFIG_GENERIC_TIME_VSYSCALL
+ #include <vdso/datapage.h>
+ #else
+-#include <asm/vdso.h>
++struct vdso_data {
++};
+ #endif
+
+ extern char vdso_start[], vdso_end[];
+
++enum vvar_pages {
++ VVAR_DATA_PAGE_OFFSET,
++ VVAR_NR_PAGES,
++};
++
++#define VVAR_SIZE (VVAR_NR_PAGES << PAGE_SHIFT)
++
+ static unsigned int vdso_pages __ro_after_init;
+ static struct page **vdso_pagelist __ro_after_init;
+
+@@ -38,7 +48,7 @@ static int __init vdso_init(void)
+
+ vdso_pages = (vdso_end - vdso_start) >> PAGE_SHIFT;
+ vdso_pagelist =
+- kcalloc(vdso_pages + 1, sizeof(struct page *), GFP_KERNEL);
++ kcalloc(vdso_pages + VVAR_NR_PAGES, sizeof(struct page *), GFP_KERNEL);
+ if (unlikely(vdso_pagelist == NULL)) {
+ pr_err("vdso: pagelist allocation failed\n");
+ return -ENOMEM;
+@@ -63,38 +73,41 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
+ unsigned long vdso_base, vdso_len;
+ int ret;
+
+- vdso_len = (vdso_pages + 1) << PAGE_SHIFT;
++ BUILD_BUG_ON(VVAR_NR_PAGES != __VVAR_PAGES);
++
++ vdso_len = (vdso_pages + VVAR_NR_PAGES) << PAGE_SHIFT;
++
++ if (mmap_write_lock_killable(mm))
++ return -EINTR;
+
+- mmap_write_lock(mm);
+ vdso_base = get_unmapped_area(NULL, 0, vdso_len, 0, 0);
+ if (IS_ERR_VALUE(vdso_base)) {
+ ret = vdso_base;
+ goto end;
+ }
+
+- /*
+- * Put vDSO base into mm struct. We need to do this before calling
+- * install_special_mapping or the perf counter mmap tracking code
+- * will fail to recognise it as a vDSO (since arch_vma_name fails).
+- */
+- mm->context.vdso = (void *)vdso_base;
++ mm->context.vdso = NULL;
++ ret = install_special_mapping(mm, vdso_base, VVAR_SIZE,
++ (VM_READ | VM_MAYREAD), &vdso_pagelist[vdso_pages]);
++ if (unlikely(ret))
++ goto end;
+
+ ret =
+- install_special_mapping(mm, vdso_base, vdso_pages << PAGE_SHIFT,
++ install_special_mapping(mm, vdso_base + VVAR_SIZE,
++ vdso_pages << PAGE_SHIFT,
+ (VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC),
+ vdso_pagelist);
+
+- if (unlikely(ret)) {
+- mm->context.vdso = NULL;
++ if (unlikely(ret))
+ goto end;
+- }
+
+- vdso_base += (vdso_pages << PAGE_SHIFT);
+- ret = install_special_mapping(mm, vdso_base, PAGE_SIZE,
+- (VM_READ | VM_MAYREAD), &vdso_pagelist[vdso_pages]);
++ /*
++ * Put vDSO base into mm struct. We need to do this before calling
++ * install_special_mapping or the perf counter mmap tracking code
++ * will fail to recognise it as a vDSO (since arch_vma_name fails).
++ */
++ mm->context.vdso = (void *)vdso_base + VVAR_SIZE;
+
+- if (unlikely(ret))
+- mm->context.vdso = NULL;
+ end:
+ mmap_write_unlock(mm);
+ return ret;
+@@ -105,7 +118,7 @@ const char *arch_vma_name(struct vm_area_struct *vma)
+ if (vma->vm_mm && (vma->vm_start == (long)vma->vm_mm->context.vdso))
+ return "[vdso]";
+ if (vma->vm_mm && (vma->vm_start ==
+- (long)vma->vm_mm->context.vdso + PAGE_SIZE))
++ (long)vma->vm_mm->context.vdso - VVAR_SIZE))
+ return "[vdso_data]";
+ return NULL;
+ }
+diff --git a/arch/riscv/kernel/vdso/Makefile b/arch/riscv/kernel/vdso/Makefile
+index 24d936c147cdf..f8cb9144a2842 100644
+--- a/arch/riscv/kernel/vdso/Makefile
++++ b/arch/riscv/kernel/vdso/Makefile
+@@ -23,10 +23,10 @@ ifneq ($(c-gettimeofday-y),)
+ endif
+
+ # Build rules
+-targets := $(obj-vdso) vdso.so vdso.so.dbg vdso.lds vdso-syms.S
++targets := $(obj-vdso) vdso.so vdso.so.dbg vdso.lds
+ obj-vdso := $(addprefix $(obj)/, $(obj-vdso))
+
+-obj-y += vdso.o vdso-syms.o
++obj-y += vdso.o
+ CPPFLAGS_vdso.lds += -P -C -U$(ARCH)
+
+ # Disable -pg to prevent insert call site
+@@ -43,20 +43,22 @@ $(obj)/vdso.o: $(obj)/vdso.so
+ # link rule for the .so file, .lds has to be first
+ $(obj)/vdso.so.dbg: $(obj)/vdso.lds $(obj-vdso) FORCE
+ $(call if_changed,vdsold)
+-LDFLAGS_vdso.so.dbg = -shared -s -soname=linux-vdso.so.1 \
++LDFLAGS_vdso.so.dbg = -shared -S -soname=linux-vdso.so.1 \
+ --build-id=sha1 --hash-style=both --eh-frame-hdr
+
+-# We also create a special relocatable object that should mirror the symbol
+-# table and layout of the linked DSO. With ld --just-symbols we can then
+-# refer to these symbols in the kernel code rather than hand-coded addresses.
+-$(obj)/vdso-syms.S: $(obj)/vdso.so FORCE
+- $(call if_changed,so2s)
+-
+ # strip rule for the .so file
+ $(obj)/%.so: OBJCOPYFLAGS := -S
+ $(obj)/%.so: $(obj)/%.so.dbg FORCE
+ $(call if_changed,objcopy)
+
++# Generate VDSO offsets using helper script
++gen-vdsosym := $(srctree)/$(src)/gen_vdso_offsets.sh
++quiet_cmd_vdsosym = VDSOSYM $@
++ cmd_vdsosym = $(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@
++
++include/generated/vdso-offsets.h: $(obj)/vdso.so.dbg FORCE
++ $(call if_changed,vdsosym)
++
+ # actual build commands
+ # The DSO images are built using a special linker script
+ # Make sure only to export the intended __vdso_xxx symbol offsets.
+@@ -65,11 +67,6 @@ quiet_cmd_vdsold = VDSOLD $@
+ $(OBJCOPY) $(patsubst %, -G __vdso_%, $(vdso-syms)) $@.tmp $@ && \
+ rm $@.tmp
+
+-# Extracts symbol offsets from the VDSO, converting them into an assembly file
+-# that contains the same symbols at the same offsets.
+-quiet_cmd_so2s = SO2S $@
+- cmd_so2s = $(NM) -D $< | $(srctree)/$(src)/so2s.sh > $@
+-
+ # install commands for the unstripped file
+ quiet_cmd_vdso_install = INSTALL $@
+ cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@
+diff --git a/arch/riscv/kernel/vdso/gen_vdso_offsets.sh b/arch/riscv/kernel/vdso/gen_vdso_offsets.sh
+new file mode 100755
+index 0000000000000..c2e5613f34951
+--- /dev/null
++++ b/arch/riscv/kernel/vdso/gen_vdso_offsets.sh
+@@ -0,0 +1,5 @@
++#!/bin/sh
++# SPDX-License-Identifier: GPL-2.0
++
++LC_ALL=C
++sed -n -e 's/^[0]\+\(0[0-9a-fA-F]*\) . \(__vdso_[a-zA-Z0-9_]*\)$/\#define \2_offset\t0x\1/p'
+diff --git a/arch/riscv/kernel/vdso/so2s.sh b/arch/riscv/kernel/vdso/so2s.sh
+deleted file mode 100755
+index e64cb6d9440e7..0000000000000
+--- a/arch/riscv/kernel/vdso/so2s.sh
++++ /dev/null
+@@ -1,6 +0,0 @@
+-#!/bin/sh
+-# SPDX-License-Identifier: GPL-2.0+
+-# Copyright 2020 Palmer Dabbelt <palmerdabbelt@google.com>
+-
+-sed 's!\([0-9a-f]*\) T \([a-z0-9_]*\)\(@@LINUX_4.15\)*!.global \2\n.set \2,0x\1!' \
+-| grep '^\.'
+diff --git a/arch/riscv/kernel/vdso/vdso.lds.S b/arch/riscv/kernel/vdso/vdso.lds.S
+index e6f558bca71bb..e9111f700af08 100644
+--- a/arch/riscv/kernel/vdso/vdso.lds.S
++++ b/arch/riscv/kernel/vdso/vdso.lds.S
+@@ -3,12 +3,13 @@
+ * Copyright (C) 2012 Regents of the University of California
+ */
+ #include <asm/page.h>
++#include <asm/vdso.h>
+
+ OUTPUT_ARCH(riscv)
+
+ SECTIONS
+ {
+- PROVIDE(_vdso_data = . + PAGE_SIZE);
++ PROVIDE(_vdso_data = . - __VVAR_PAGES * PAGE_SIZE);
+ . = SIZEOF_HEADERS;
+
+ .hash : { *(.hash) } :text
+diff --git a/arch/riscv/mm/cacheflush.c b/arch/riscv/mm/cacheflush.c
+index 094118663285d..89f81067e09ed 100644
+--- a/arch/riscv/mm/cacheflush.c
++++ b/arch/riscv/mm/cacheflush.c
+@@ -16,6 +16,8 @@ static void ipi_remote_fence_i(void *info)
+
+ void flush_icache_all(void)
+ {
++ local_flush_icache_all();
++
+ if (IS_ENABLED(CONFIG_RISCV_SBI))
+ sbi_remote_fence_i(NULL);
+ else
+diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c
+index 840d8594437d5..1a374d021e256 100644
+--- a/arch/s390/net/bpf_jit_comp.c
++++ b/arch/s390/net/bpf_jit_comp.c
+@@ -1826,7 +1826,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
+ jit.addrs = kvcalloc(fp->len + 1, sizeof(*jit.addrs), GFP_KERNEL);
+ if (jit.addrs == NULL) {
+ fp = orig_fp;
+- goto out;
++ goto free_addrs;
+ }
+ /*
+ * Three initial passes:
+diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
+index 88fb922c23a0a..51341f2e218de 100644
+--- a/arch/x86/Kconfig
++++ b/arch/x86/Kconfig
+@@ -1400,7 +1400,7 @@ config HIGHMEM4G
+
+ config HIGHMEM64G
+ bool "64GB"
+- depends on !M486SX && !M486 && !M586 && !M586TSC && !M586MMX && !MGEODE_LX && !MGEODEGX1 && !MCYRIXIII && !MELAN && !MWINCHIPC6 && !WINCHIP3D && !MK6
++ depends on !M486SX && !M486 && !M586 && !M586TSC && !M586MMX && !MGEODE_LX && !MGEODEGX1 && !MCYRIXIII && !MELAN && !MWINCHIPC6 && !MWINCHIP3D && !MK6
+ select X86_PAE
+ help
+ Select this if you have a 32-bit processor and more than 4
+diff --git a/arch/x86/include/asm/entry-common.h b/arch/x86/include/asm/entry-common.h
+index 14ebd21965691..43184640b579a 100644
+--- a/arch/x86/include/asm/entry-common.h
++++ b/arch/x86/include/asm/entry-common.h
+@@ -25,7 +25,7 @@ static __always_inline void arch_check_user_regs(struct pt_regs *regs)
+ * For !SMAP hardware we patch out CLAC on entry.
+ */
+ if (boot_cpu_has(X86_FEATURE_SMAP) ||
+- (IS_ENABLED(CONFIG_64_BIT) && boot_cpu_has(X86_FEATURE_XENPV)))
++ (IS_ENABLED(CONFIG_64BIT) && boot_cpu_has(X86_FEATURE_XENPV)))
+ mask |= X86_EFLAGS_AC;
+
+ WARN_ON_ONCE(flags & mask);
+diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
+index 64b805bd6a542..340caa7aebfba 100644
+--- a/arch/x86/kernel/cpu/common.c
++++ b/arch/x86/kernel/cpu/common.c
+@@ -320,6 +320,7 @@ static __always_inline void setup_smap(struct cpuinfo_x86 *c)
+ #ifdef CONFIG_X86_SMAP
+ cr4_set_bits(X86_CR4_SMAP);
+ #else
++ clear_cpu_cap(c, X86_FEATURE_SMAP);
+ cr4_clear_bits(X86_CR4_SMAP);
+ #endif
+ }
+diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c
+index 38837dad46e62..391a4e2b86049 100644
+--- a/arch/x86/kernel/early-quirks.c
++++ b/arch/x86/kernel/early-quirks.c
+@@ -714,12 +714,6 @@ static struct chipset early_qrk[] __initdata = {
+ */
+ { PCI_VENDOR_ID_INTEL, 0x0f00,
+ PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet},
+- { PCI_VENDOR_ID_INTEL, 0x3e20,
+- PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet},
+- { PCI_VENDOR_ID_INTEL, 0x3ec4,
+- PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet},
+- { PCI_VENDOR_ID_INTEL, 0x8a12,
+- PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet},
+ { PCI_VENDOR_ID_BROADCOM, 0x4331,
+ PCI_CLASS_NETWORK_OTHER, PCI_ANY_ID, 0, apple_airport_reset},
+ {}
+diff --git a/arch/x86/kernel/fpu/signal.c b/arch/x86/kernel/fpu/signal.c
+index 445c57c9c5397..fa17a27390ab0 100644
+--- a/arch/x86/kernel/fpu/signal.c
++++ b/arch/x86/kernel/fpu/signal.c
+@@ -379,9 +379,14 @@ static int __fpu_restore_sig(void __user *buf, void __user *buf_fx,
+ sizeof(fpu->state.fxsave)))
+ return -EFAULT;
+
+- /* Reject invalid MXCSR values. */
+- if (fpu->state.fxsave.mxcsr & ~mxcsr_feature_mask)
+- return -EINVAL;
++ if (IS_ENABLED(CONFIG_X86_64)) {
++ /* Reject invalid MXCSR values. */
++ if (fpu->state.fxsave.mxcsr & ~mxcsr_feature_mask)
++ return -EINVAL;
++ } else {
++ /* Mask invalid bits out for historical reasons (broken hardware). */
++ fpu->state.fxsave.mxcsr &= ~mxcsr_feature_mask;
++ }
+
+ /* Enforce XFEATURE_MASK_FPSSE when XSAVE is enabled */
+ if (use_xsave())
+diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
+index 42fc41dd0e1f1..882213df37130 100644
+--- a/arch/x86/kernel/hpet.c
++++ b/arch/x86/kernel/hpet.c
+@@ -10,6 +10,7 @@
+ #include <asm/irq_remapping.h>
+ #include <asm/hpet.h>
+ #include <asm/time.h>
++#include <asm/mwait.h>
+
+ #undef pr_fmt
+ #define pr_fmt(fmt) "hpet: " fmt
+@@ -916,6 +917,83 @@ static bool __init hpet_counting(void)
+ return false;
+ }
+
++static bool __init mwait_pc10_supported(void)
++{
++ unsigned int eax, ebx, ecx, mwait_substates;
++
++ if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
++ return false;
++
++ if (!cpu_feature_enabled(X86_FEATURE_MWAIT))
++ return false;
++
++ if (boot_cpu_data.cpuid_level < CPUID_MWAIT_LEAF)
++ return false;
++
++ cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &mwait_substates);
++
++ return (ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED) &&
++ (ecx & CPUID5_ECX_INTERRUPT_BREAK) &&
++ (mwait_substates & (0xF << 28));
++}
++
++/*
++ * Check whether the system supports PC10. If so force disable HPET as that
++ * stops counting in PC10. This check is overbroad as it does not take any
++ * of the following into account:
++ *
++ * - ACPI tables
++ * - Enablement of intel_idle
++ * - Command line arguments which limit intel_idle C-state support
++ *
++ * That's perfectly fine. HPET is a piece of hardware designed by committee
++ * and the only reasons why it is still in use on modern systems is the
++ * fact that it is impossible to reliably query TSC and CPU frequency via
++ * CPUID or firmware.
++ *
++ * If HPET is functional it is useful for calibrating TSC, but this can be
++ * done via PMTIMER as well which seems to be the last remaining timer on
++ * X86/INTEL platforms that has not been completely wreckaged by feature
++ * creep.
++ *
++ * In theory HPET support should be removed altogether, but there are older
++ * systems out there which depend on it because TSC and APIC timer are
++ * dysfunctional in deeper C-states.
++ *
++ * It's only 20 years now that hardware people have been asked to provide
++ * reliable and discoverable facilities which can be used for timekeeping
++ * and per CPU timer interrupts.
++ *
++ * The probability that this problem is going to be solved in the
++ * forseeable future is close to zero, so the kernel has to be cluttered
++ * with heuristics to keep up with the ever growing amount of hardware and
++ * firmware trainwrecks. Hopefully some day hardware people will understand
++ * that the approach of "This can be fixed in software" is not sustainable.
++ * Hope dies last...
++ */
++static bool __init hpet_is_pc10_damaged(void)
++{
++ unsigned long long pcfg;
++
++ /* Check whether PC10 substates are supported */
++ if (!mwait_pc10_supported())
++ return false;
++
++ /* Check whether PC10 is enabled in PKG C-state limit */
++ rdmsrl(MSR_PKG_CST_CONFIG_CONTROL, pcfg);
++ if ((pcfg & 0xF) < 8)
++ return false;
++
++ if (hpet_force_user) {
++ pr_warn("HPET force enabled via command line, but dysfunctional in PC10.\n");
++ return false;
++ }
++
++ pr_info("HPET dysfunctional in PC10. Force disabled.\n");
++ boot_hpet_disable = true;
++ return true;
++}
++
+ /**
+ * hpet_enable - Try to setup the HPET timer. Returns 1 on success.
+ */
+@@ -929,6 +1007,9 @@ int __init hpet_enable(void)
+ if (!is_hpet_capable())
+ return 0;
+
++ if (hpet_is_pc10_damaged())
++ return 0;
++
+ hpet_set_mapping();
+ if (!hpet_virt_address)
+ return 0;
+diff --git a/arch/x86/kernel/sev-shared.c b/arch/x86/kernel/sev-shared.c
+index 9f90f460a28cc..bf1033a62e480 100644
+--- a/arch/x86/kernel/sev-shared.c
++++ b/arch/x86/kernel/sev-shared.c
+@@ -130,6 +130,8 @@ static enum es_result sev_es_ghcb_hv_call(struct ghcb *ghcb,
+ } else {
+ ret = ES_VMM_ERROR;
+ }
++ } else if (ghcb->save.sw_exit_info_1 & 0xffffffff) {
++ ret = ES_VMM_ERROR;
+ } else {
+ ret = ES_OK;
+ }
+diff --git a/arch/x86/platform/olpc/olpc.c b/arch/x86/platform/olpc/olpc.c
+index ee2beda590d0d..1d4a00e767ece 100644
+--- a/arch/x86/platform/olpc/olpc.c
++++ b/arch/x86/platform/olpc/olpc.c
+@@ -274,7 +274,7 @@ static struct olpc_ec_driver ec_xo1_driver = {
+
+ static struct olpc_ec_driver ec_xo1_5_driver = {
+ .ec_cmd = olpc_xo1_ec_cmd,
+-#ifdef CONFIG_OLPC_XO1_5_SCI
++#ifdef CONFIG_OLPC_XO15_SCI
+ /*
+ * XO-1.5 EC wakeups are available when olpc-xo15-sci driver is
+ * compiled in
+diff --git a/arch/xtensa/include/asm/kmem_layout.h b/arch/xtensa/include/asm/kmem_layout.h
+index 7cbf68ca71060..6fc05cba61a27 100644
+--- a/arch/xtensa/include/asm/kmem_layout.h
++++ b/arch/xtensa/include/asm/kmem_layout.h
+@@ -78,7 +78,7 @@
+ #endif
+ #define XCHAL_KIO_SIZE 0x10000000
+
+-#if (!XCHAL_HAVE_PTP_MMU || XCHAL_HAVE_SPANNING_WAY) && defined(CONFIG_OF)
++#if (!XCHAL_HAVE_PTP_MMU || XCHAL_HAVE_SPANNING_WAY) && defined(CONFIG_USE_OF)
+ #define XCHAL_KIO_PADDR xtensa_get_kio_paddr()
+ #ifndef __ASSEMBLY__
+ extern unsigned long xtensa_kio_paddr;
+diff --git a/arch/xtensa/kernel/irq.c b/arch/xtensa/kernel/irq.c
+index a48bf2d10ac2d..80cc9770a8d2d 100644
+--- a/arch/xtensa/kernel/irq.c
++++ b/arch/xtensa/kernel/irq.c
+@@ -145,7 +145,7 @@ unsigned xtensa_get_ext_irq_no(unsigned irq)
+
+ void __init init_IRQ(void)
+ {
+-#ifdef CONFIG_OF
++#ifdef CONFIG_USE_OF
+ irqchip_init();
+ #else
+ #ifdef CONFIG_HAVE_SMP
+diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c
+index ed184106e4cf9..ee9082a142feb 100644
+--- a/arch/xtensa/kernel/setup.c
++++ b/arch/xtensa/kernel/setup.c
+@@ -63,7 +63,7 @@ extern unsigned long initrd_end;
+ extern int initrd_below_start_ok;
+ #endif
+
+-#ifdef CONFIG_OF
++#ifdef CONFIG_USE_OF
+ void *dtb_start = __dtb_start;
+ #endif
+
+@@ -125,7 +125,7 @@ __tagtable(BP_TAG_INITRD, parse_tag_initrd);
+
+ #endif /* CONFIG_BLK_DEV_INITRD */
+
+-#ifdef CONFIG_OF
++#ifdef CONFIG_USE_OF
+
+ static int __init parse_tag_fdt(const bp_tag_t *tag)
+ {
+@@ -135,7 +135,7 @@ static int __init parse_tag_fdt(const bp_tag_t *tag)
+
+ __tagtable(BP_TAG_FDT, parse_tag_fdt);
+
+-#endif /* CONFIG_OF */
++#endif /* CONFIG_USE_OF */
+
+ static int __init parse_tag_cmdline(const bp_tag_t* tag)
+ {
+@@ -183,7 +183,7 @@ static int __init parse_bootparam(const bp_tag_t *tag)
+ }
+ #endif
+
+-#ifdef CONFIG_OF
++#ifdef CONFIG_USE_OF
+
+ #if !XCHAL_HAVE_PTP_MMU || XCHAL_HAVE_SPANNING_WAY
+ unsigned long xtensa_kio_paddr = XCHAL_KIO_DEFAULT_PADDR;
+@@ -232,7 +232,7 @@ void __init early_init_devtree(void *params)
+ strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
+ }
+
+-#endif /* CONFIG_OF */
++#endif /* CONFIG_USE_OF */
+
+ /*
+ * Initialize architecture. (Early stage)
+@@ -253,7 +253,7 @@ void __init init_arch(bp_tag_t *bp_start)
+ if (bp_start)
+ parse_bootparam(bp_start);
+
+-#ifdef CONFIG_OF
++#ifdef CONFIG_USE_OF
+ early_init_devtree(dtb_start);
+ #endif
+
+diff --git a/arch/xtensa/mm/mmu.c b/arch/xtensa/mm/mmu.c
+index 7e4d97dc8bd8f..38acda4f04e85 100644
+--- a/arch/xtensa/mm/mmu.c
++++ b/arch/xtensa/mm/mmu.c
+@@ -101,7 +101,7 @@ void init_mmu(void)
+
+ void init_kio(void)
+ {
+-#if XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY && defined(CONFIG_OF)
++#if XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY && defined(CONFIG_USE_OF)
+ /*
+ * Update the IO area mapping in case xtensa_kio_paddr has changed
+ */
+diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c
+index 148a4dd8cb9ac..418ada474a85d 100644
+--- a/drivers/bus/ti-sysc.c
++++ b/drivers/bus/ti-sysc.c
+@@ -1468,6 +1468,9 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = {
+ /* Quirks that need to be set based on detected module */
+ SYSC_QUIRK("aess", 0, 0, 0x10, -ENODEV, 0x40000000, 0xffffffff,
+ SYSC_MODULE_QUIRK_AESS),
++ /* Errata i893 handling for dra7 dcan1 and 2 */
++ SYSC_QUIRK("dcan", 0x4ae3c000, 0x20, -ENODEV, -ENODEV, 0xa3170504, 0xffffffff,
++ SYSC_QUIRK_CLKDM_NOAUTO),
+ SYSC_QUIRK("dcan", 0x48480000, 0x20, -ENODEV, -ENODEV, 0xa3170504, 0xffffffff,
+ SYSC_QUIRK_CLKDM_NOAUTO),
+ SYSC_QUIRK("dss", 0x4832a000, 0, 0x10, 0x14, 0x00000020, 0xffffffff,
+@@ -2955,6 +2958,7 @@ static int sysc_init_soc(struct sysc *ddata)
+ break;
+ case SOC_AM3:
+ sysc_add_disabled(0x48310000); /* rng */
++ break;
+ default:
+ break;
+ }
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+index 177a663a6a691..a1c5bd2859fc3 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+@@ -1082,6 +1082,7 @@ struct amdgpu_device {
+
+ bool no_hw_access;
+ struct pci_saved_state *pci_state;
++ pci_channel_state_t pci_channel_state;
+
+ struct amdgpu_reset_control *reset_cntl;
+ };
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+index 4fb15750b9bb4..b18c0697356c1 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+@@ -563,6 +563,7 @@ kfd_mem_dmaunmap_userptr(struct kgd_mem *mem,
+
+ dma_unmap_sgtable(adev->dev, ttm->sg, direction, 0);
+ sg_free_table(ttm->sg);
++ kfree(ttm->sg);
+ ttm->sg = NULL;
+ }
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+index d3247a5cceb4c..d60096b3b2c2a 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+@@ -5329,6 +5329,8 @@ pci_ers_result_t amdgpu_pci_error_detected(struct pci_dev *pdev, pci_channel_sta
+ return PCI_ERS_RESULT_DISCONNECT;
+ }
+
++ adev->pci_channel_state = state;
++
+ switch (state) {
+ case pci_channel_io_normal:
+ return PCI_ERS_RESULT_CAN_RECOVER;
+@@ -5471,6 +5473,10 @@ void amdgpu_pci_resume(struct pci_dev *pdev)
+
+ DRM_INFO("PCI error: resume callback!!\n");
+
++ /* Only continue execution for the case of pci_channel_io_frozen */
++ if (adev->pci_channel_state != pci_channel_io_frozen)
++ return;
++
+ for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
+ struct amdgpu_ring *ring = adev->rings[i];
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
+index b4ced45301bec..1795d448c7000 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
+@@ -31,6 +31,8 @@
+ /* delay 0.1 second to enable gfx off feature */
+ #define GFX_OFF_DELAY_ENABLE msecs_to_jiffies(100)
+
++#define GFX_OFF_NO_DELAY 0
++
+ /*
+ * GPU GFX IP block helpers function.
+ */
+@@ -558,6 +560,8 @@ int amdgpu_gfx_enable_kcq(struct amdgpu_device *adev)
+
+ void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable)
+ {
++ unsigned long delay = GFX_OFF_DELAY_ENABLE;
++
+ if (!(adev->pm.pp_feature & PP_GFXOFF_MASK))
+ return;
+
+@@ -573,8 +577,14 @@ void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable)
+
+ adev->gfx.gfx_off_req_count--;
+
+- if (adev->gfx.gfx_off_req_count == 0 && !adev->gfx.gfx_off_state)
+- schedule_delayed_work(&adev->gfx.gfx_off_delay_work, GFX_OFF_DELAY_ENABLE);
++ if (adev->gfx.gfx_off_req_count == 0 &&
++ !adev->gfx.gfx_off_state) {
++ /* If going to s2idle, no need to wait */
++ if (adev->in_s0ix)
++ delay = GFX_OFF_NO_DELAY;
++ schedule_delayed_work(&adev->gfx.gfx_off_delay_work,
++ delay);
++ }
+ } else {
+ if (adev->gfx.gfx_off_req_count == 0) {
+ cancel_delayed_work_sync(&adev->gfx.gfx_off_delay_work);
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h
+index d8b22618b79e8..c337588231ff0 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h
++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h
+@@ -118,6 +118,7 @@ struct dcn10_link_enc_registers {
+ uint32_t RDPCSTX_PHY_CNTL4;
+ uint32_t RDPCSTX_PHY_CNTL5;
+ uint32_t RDPCSTX_PHY_CNTL6;
++ uint32_t RDPCSPIPE_PHY_CNTL6;
+ uint32_t RDPCSTX_PHY_CNTL7;
+ uint32_t RDPCSTX_PHY_CNTL8;
+ uint32_t RDPCSTX_PHY_CNTL9;
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c
+index 90127c1f9e35d..b0892443fbd57 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c
+@@ -37,6 +37,7 @@
+
+ #include "link_enc_cfg.h"
+ #include "dc_dmub_srv.h"
++#include "dal_asic_id.h"
+
+ #define CTX \
+ enc10->base.ctx
+@@ -62,6 +63,10 @@
+ #define AUX_REG_WRITE(reg_name, val) \
+ dm_write_reg(CTX, AUX_REG(reg_name), val)
+
++#ifndef MIN
++#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
++#endif
++
+ void dcn31_link_encoder_set_dio_phy_mux(
+ struct link_encoder *enc,
+ enum encoder_type_select sel,
+@@ -215,8 +220,8 @@ static const struct link_encoder_funcs dcn31_link_enc_funcs = {
+ .fec_is_active = enc2_fec_is_active,
+ .get_dig_frontend = dcn10_get_dig_frontend,
+ .get_dig_mode = dcn10_get_dig_mode,
+- .is_in_alt_mode = dcn20_link_encoder_is_in_alt_mode,
+- .get_max_link_cap = dcn20_link_encoder_get_max_link_cap,
++ .is_in_alt_mode = dcn31_link_encoder_is_in_alt_mode,
++ .get_max_link_cap = dcn31_link_encoder_get_max_link_cap,
+ .set_dio_phy_mux = dcn31_link_encoder_set_dio_phy_mux,
+ };
+
+@@ -404,3 +409,60 @@ void dcn31_link_encoder_disable_output(
+ }
+ }
+
++bool dcn31_link_encoder_is_in_alt_mode(struct link_encoder *enc)
++{
++ struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
++ uint32_t dp_alt_mode_disable;
++ bool is_usb_c_alt_mode = false;
++
++ if (enc->features.flags.bits.DP_IS_USB_C) {
++ if (enc->ctx->asic_id.hw_internal_rev != YELLOW_CARP_B0) {
++ // [Note] no need to check hw_internal_rev once phy mux selection is ready
++ REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &dp_alt_mode_disable);
++ } else {
++ /*
++ * B0 phys use a new set of registers to check whether alt mode is disabled.
++ * if value == 1 alt mode is disabled, otherwise it is enabled.
++ */
++ if ((enc10->base.transmitter == TRANSMITTER_UNIPHY_A)
++ || (enc10->base.transmitter == TRANSMITTER_UNIPHY_B)
++ || (enc10->base.transmitter == TRANSMITTER_UNIPHY_E)) {
++ REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &dp_alt_mode_disable);
++ } else {
++ // [Note] need to change TRANSMITTER_UNIPHY_C/D to F/G once phy mux selection is ready
++ REG_GET(RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &dp_alt_mode_disable);
++ }
++ }
++
++ is_usb_c_alt_mode = (dp_alt_mode_disable == 0);
++ }
++
++ return is_usb_c_alt_mode;
++}
++
++void dcn31_link_encoder_get_max_link_cap(struct link_encoder *enc,
++ struct dc_link_settings *link_settings)
++{
++ struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
++ uint32_t is_in_usb_c_dp4_mode = 0;
++
++ dcn10_link_encoder_get_max_link_cap(enc, link_settings);
++
++ /* in usb c dp2 mode, max lane count is 2 */
++ if (enc->funcs->is_in_alt_mode && enc->funcs->is_in_alt_mode(enc)) {
++ if (enc->ctx->asic_id.hw_internal_rev != YELLOW_CARP_B0) {
++ // [Note] no need to check hw_internal_rev once phy mux selection is ready
++ REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, &is_in_usb_c_dp4_mode);
++ } else {
++ if ((enc10->base.transmitter == TRANSMITTER_UNIPHY_A)
++ || (enc10->base.transmitter == TRANSMITTER_UNIPHY_B)
++ || (enc10->base.transmitter == TRANSMITTER_UNIPHY_E)) {
++ REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, &is_in_usb_c_dp4_mode);
++ } else {
++ REG_GET(RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, &is_in_usb_c_dp4_mode);
++ }
++ }
++ if (!is_in_usb_c_dp4_mode)
++ link_settings->lane_count = MIN(LANE_COUNT_TWO, link_settings->lane_count);
++ }
++}
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.h
+index 32d146312838b..3454f1e7c1f17 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.h
++++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.h
+@@ -69,6 +69,7 @@
+ SRI(RDPCSTX_PHY_CNTL4, RDPCSTX, id), \
+ SRI(RDPCSTX_PHY_CNTL5, RDPCSTX, id), \
+ SRI(RDPCSTX_PHY_CNTL6, RDPCSTX, id), \
++ SRI(RDPCSPIPE_PHY_CNTL6, RDPCSPIPE, id), \
+ SRI(RDPCSTX_PHY_CNTL7, RDPCSTX, id), \
+ SRI(RDPCSTX_PHY_CNTL8, RDPCSTX, id), \
+ SRI(RDPCSTX_PHY_CNTL9, RDPCSTX, id), \
+@@ -115,7 +116,9 @@
+ LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL6, RDPCS_PHY_DP_TX2_MPLL_EN, mask_sh),\
+ LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL6, RDPCS_PHY_DP_TX3_MPLL_EN, mask_sh),\
+ LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, mask_sh),\
+- LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, mask_sh),\
++ LE_SF(RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, mask_sh),\
++ LE_SF(RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, mask_sh),\
++ LE_SF(RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE_ACK, mask_sh),\
+ LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL7, RDPCS_PHY_DP_MPLLB_FRACN_QUOT, mask_sh),\
+ LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL7, RDPCS_PHY_DP_MPLLB_FRACN_DEN, mask_sh),\
+ LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL8, RDPCS_PHY_DP_MPLLB_SSC_PEAK, mask_sh),\
+@@ -243,4 +246,13 @@ void dcn31_link_encoder_disable_output(
+ struct link_encoder *enc,
+ enum signal_type signal);
+
++/*
++ * Check whether USB-C DP Alt mode is disabled
++ */
++bool dcn31_link_encoder_is_in_alt_mode(
++ struct link_encoder *enc);
++
++void dcn31_link_encoder_get_max_link_cap(struct link_encoder *enc,
++ struct dc_link_settings *link_settings);
++
+ #endif /* __DC_LINK_ENCODER__DCN31_H__ */
+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 cd3248dc31d87..7ea362a864c43 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
+@@ -928,7 +928,7 @@ static const struct dc_debug_options debug_defaults_drv = {
+ .disable_dcc = DCC_ENABLE,
+ .vsr_support = true,
+ .performance_trace = false,
+- .max_downscale_src_width = 7680,/*upto 8K*/
++ .max_downscale_src_width = 3840,/*upto 4K*/
+ .disable_pplib_wm_range = false,
+ .scl_reset_length10 = true,
+ .sanity_checks = false,
+@@ -1284,6 +1284,12 @@ static struct stream_encoder *dcn31_stream_encoder_create(
+ if (!enc1 || !vpg || !afmt)
+ return NULL;
+
++ if (ctx->asic_id.chip_family == FAMILY_YELLOW_CARP &&
++ ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0) {
++ if ((eng_id == ENGINE_ID_DIGC) || (eng_id == ENGINE_ID_DIGD))
++ eng_id = eng_id + 3; // For B0 only. C->F, D->G.
++ }
++
+ dcn30_dio_stream_encoder_construct(enc1, ctx, ctx->dc_bios,
+ eng_id, vpg, afmt,
+ &stream_enc_regs[eng_id],
+diff --git a/drivers/gpu/drm/amd/display/include/dal_asic_id.h b/drivers/gpu/drm/amd/display/include/dal_asic_id.h
+index 381c17caace18..5adc471bef57f 100644
+--- a/drivers/gpu/drm/amd/display/include/dal_asic_id.h
++++ b/drivers/gpu/drm/amd/display/include/dal_asic_id.h
+@@ -227,7 +227,7 @@ enum {
+ #define FAMILY_YELLOW_CARP 146
+
+ #define YELLOW_CARP_A0 0x01
+-#define YELLOW_CARP_B0 0x02 // TODO: DCN31 - update with correct B0 ID
++#define YELLOW_CARP_B0 0x1A
+ #define YELLOW_CARP_UNKNOWN 0xFF
+
+ #ifndef ASICREV_IS_YELLOW_CARP
+diff --git a/drivers/gpu/drm/amd/include/asic_reg/dpcs/dpcs_4_2_0_offset.h b/drivers/gpu/drm/amd/include/asic_reg/dpcs/dpcs_4_2_0_offset.h
+index 92caf8441d1e0..01a56556cde13 100644
+--- a/drivers/gpu/drm/amd/include/asic_reg/dpcs/dpcs_4_2_0_offset.h
++++ b/drivers/gpu/drm/amd/include/asic_reg/dpcs/dpcs_4_2_0_offset.h
+@@ -11932,5 +11932,32 @@
+ #define ixDPCSSYS_CR4_RAWLANEX_DIG_PCS_XF_RX_OVRD_OUT_2 0xe0c7
+ #define ixDPCSSYS_CR4_RAWLANEX_DIG_PCS_XF_TX_OVRD_IN_2 0xe0c8
+
++//RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6
++#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DP4__SHIFT 0x10
++#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE__SHIFT 0x11
++#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_ACK__SHIFT 0x12
++#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DP4_MASK 0x00010000L
++#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_MASK 0x00020000L
++#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_ACK_MASK 0x00040000L
++
++//RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6
++#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DP4__SHIFT 0x10
++#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE__SHIFT 0x11
++#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_ACK__SHIFT 0x12
++#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DP4_MASK 0x00010000L
++#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_MASK 0x00020000L
++#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_ACK_MASK 0x00040000L
++
++//[Note] Hack. RDPCSPIPE only has 2 instances.
++#define regRDPCSPIPE0_RDPCSPIPE_PHY_CNTL6 0x2d73
++#define regRDPCSPIPE0_RDPCSPIPE_PHY_CNTL6_BASE_IDX 2
++#define regRDPCSPIPE1_RDPCSPIPE_PHY_CNTL6 0x2e4b
++#define regRDPCSPIPE1_RDPCSPIPE_PHY_CNTL6_BASE_IDX 2
++#define regRDPCSPIPE2_RDPCSPIPE_PHY_CNTL6 0x2d73
++#define regRDPCSPIPE2_RDPCSPIPE_PHY_CNTL6_BASE_IDX 2
++#define regRDPCSPIPE3_RDPCSPIPE_PHY_CNTL6 0x2e4b
++#define regRDPCSPIPE3_RDPCSPIPE_PHY_CNTL6_BASE_IDX 2
++#define regRDPCSPIPE4_RDPCSPIPE_PHY_CNTL6 0x2d73
++#define regRDPCSPIPE4_RDPCSPIPE_PHY_CNTL6_BASE_IDX 2
+
+ #endif
+diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
+index 16812488c5ddc..13bafa9d49c01 100644
+--- a/drivers/gpu/drm/i915/display/icl_dsi.c
++++ b/drivers/gpu/drm/i915/display/icl_dsi.c
+@@ -1253,15 +1253,36 @@ static void gen11_dsi_pre_enable(struct intel_atomic_state *state,
+ gen11_dsi_set_transcoder_timings(encoder, pipe_config);
+ }
+
++/*
++ * Wa_1409054076:icl,jsl,ehl
++ * When pipe A is disabled and MIPI DSI is enabled on pipe B,
++ * the AMT KVMR feature will incorrectly see pipe A as enabled.
++ * Set 0x42080 bit 23=1 before enabling DSI on pipe B and leave
++ * it set while DSI is enabled on pipe B
++ */
++static void icl_apply_kvmr_pipe_a_wa(struct intel_encoder *encoder,
++ enum pipe pipe, bool enable)
++{
++ struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
++
++ if (DISPLAY_VER(dev_priv) == 11 && pipe == PIPE_B)
++ intel_de_rmw(dev_priv, CHICKEN_PAR1_1,
++ IGNORE_KVMR_PIPE_A,
++ enable ? IGNORE_KVMR_PIPE_A : 0);
++}
+ static void gen11_dsi_enable(struct intel_atomic_state *state,
+ struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state,
+ const struct drm_connector_state *conn_state)
+ {
+ struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
++ struct intel_crtc *crtc = to_intel_crtc(conn_state->crtc);
+
+ drm_WARN_ON(state->base.dev, crtc_state->has_pch_encoder);
+
++ /* Wa_1409054076:icl,jsl,ehl */
++ icl_apply_kvmr_pipe_a_wa(encoder, crtc->pipe, true);
++
+ /* step6d: enable dsi transcoder */
+ gen11_dsi_enable_transcoder(encoder);
+
+@@ -1415,6 +1436,7 @@ static void gen11_dsi_disable(struct intel_atomic_state *state,
+ const struct drm_connector_state *old_conn_state)
+ {
+ struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
++ struct intel_crtc *crtc = to_intel_crtc(old_conn_state->crtc);
+
+ /* step1: turn off backlight */
+ intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_OFF);
+@@ -1423,6 +1445,9 @@ static void gen11_dsi_disable(struct intel_atomic_state *state,
+ /* step2d,e: disable transcoder and wait */
+ gen11_dsi_disable_transcoder(encoder);
+
++ /* Wa_1409054076:icl,jsl,ehl */
++ icl_apply_kvmr_pipe_a_wa(encoder, crtc->pipe, false);
++
+ /* step2f,g: powerdown panel */
+ gen11_dsi_powerdown_panel(encoder);
+
+@@ -1548,6 +1573,28 @@ static void gen11_dsi_get_config(struct intel_encoder *encoder,
+ pipe_config->mode_flags |= I915_MODE_FLAG_DSI_PERIODIC_CMD_MODE;
+ }
+
++static void gen11_dsi_sync_state(struct intel_encoder *encoder,
++ const struct intel_crtc_state *crtc_state)
++{
++ struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
++ struct intel_crtc *intel_crtc;
++ enum pipe pipe;
++
++ if (!crtc_state)
++ return;
++
++ intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
++ pipe = intel_crtc->pipe;
++
++ /* wa verify 1409054076:icl,jsl,ehl */
++ if (DISPLAY_VER(dev_priv) == 11 && pipe == PIPE_B &&
++ !(intel_de_read(dev_priv, CHICKEN_PAR1_1) & IGNORE_KVMR_PIPE_A))
++ drm_dbg_kms(&dev_priv->drm,
++ "[ENCODER:%d:%s] BIOS left IGNORE_KVMR_PIPE_A cleared with pipe B enabled\n",
++ encoder->base.base.id,
++ encoder->base.name);
++}
++
+ static int gen11_dsi_dsc_compute_config(struct intel_encoder *encoder,
+ struct intel_crtc_state *crtc_state)
+ {
+@@ -1966,6 +2013,7 @@ void icl_dsi_init(struct drm_i915_private *dev_priv)
+ encoder->post_disable = gen11_dsi_post_disable;
+ encoder->port = port;
+ encoder->get_config = gen11_dsi_get_config;
++ encoder->sync_state = gen11_dsi_sync_state;
+ encoder->update_pipe = intel_panel_update_backlight;
+ encoder->compute_config = gen11_dsi_compute_config;
+ encoder->get_hw_state = gen11_dsi_get_hw_state;
+diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c
+index 5f4f316b3ab5c..4e4429535f9e4 100644
+--- a/drivers/gpu/drm/i915/display/intel_audio.c
++++ b/drivers/gpu/drm/i915/display/intel_audio.c
+@@ -1308,8 +1308,9 @@ static void i915_audio_component_init(struct drm_i915_private *dev_priv)
+ else
+ aud_freq = aud_freq_init;
+
+- /* use BIOS provided value for TGL unless it is a known bad value */
+- if (IS_TIGERLAKE(dev_priv) && aud_freq_init != AUD_FREQ_TGL_BROKEN)
++ /* use BIOS provided value for TGL and RKL unless it is a known bad value */
++ if ((IS_TIGERLAKE(dev_priv) || IS_ROCKETLAKE(dev_priv)) &&
++ aud_freq_init != AUD_FREQ_TGL_BROKEN)
+ aud_freq = aud_freq_init;
+
+ drm_dbg_kms(&dev_priv->drm, "use AUD_FREQ_CNTRL of 0x%x (init value 0x%x)\n",
+diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c
+index aa667fa711584..106f696e50a0e 100644
+--- a/drivers/gpu/drm/i915/display/intel_bios.c
++++ b/drivers/gpu/drm/i915/display/intel_bios.c
+@@ -451,13 +451,23 @@ parse_lfp_backlight(struct drm_i915_private *i915,
+ }
+
+ i915->vbt.backlight.type = INTEL_BACKLIGHT_DISPLAY_DDI;
+- if (bdb->version >= 191 &&
+- get_blocksize(backlight_data) >= sizeof(*backlight_data)) {
+- const struct lfp_backlight_control_method *method;
++ if (bdb->version >= 191) {
++ size_t exp_size;
+
+- method = &backlight_data->backlight_control[panel_type];
+- i915->vbt.backlight.type = method->type;
+- i915->vbt.backlight.controller = method->controller;
++ if (bdb->version >= 236)
++ exp_size = sizeof(struct bdb_lfp_backlight_data);
++ else if (bdb->version >= 234)
++ exp_size = EXP_BDB_LFP_BL_DATA_SIZE_REV_234;
++ else
++ exp_size = EXP_BDB_LFP_BL_DATA_SIZE_REV_191;
++
++ if (get_blocksize(backlight_data) >= exp_size) {
++ const struct lfp_backlight_control_method *method;
++
++ method = &backlight_data->backlight_control[panel_type];
++ i915->vbt.backlight.type = method->type;
++ i915->vbt.backlight.controller = method->controller;
++ }
+ }
+
+ i915->vbt.backlight.pwm_freq_hz = entry->pwm_freq_hz;
+diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
+index 00dade49665b8..89a109f65f389 100644
+--- a/drivers/gpu/drm/i915/display/intel_ddi.c
++++ b/drivers/gpu/drm/i915/display/intel_ddi.c
+@@ -3899,7 +3899,13 @@ void hsw_ddi_get_config(struct intel_encoder *encoder,
+ static void intel_ddi_sync_state(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state)
+ {
+- if (intel_crtc_has_dp_encoder(crtc_state))
++ struct drm_i915_private *i915 = to_i915(encoder->base.dev);
++ enum phy phy = intel_port_to_phy(i915, encoder->port);
++
++ if (intel_phy_is_tc(i915, phy))
++ intel_tc_port_sanitize(enc_to_dig_port(encoder));
++
++ if (crtc_state && intel_crtc_has_dp_encoder(crtc_state))
+ intel_dp_sync_state(encoder, crtc_state);
+ }
+
+diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
+index 0a8a2395c8aca..bb1d2b19be151 100644
+--- a/drivers/gpu/drm/i915/display/intel_display.c
++++ b/drivers/gpu/drm/i915/display/intel_display.c
+@@ -12933,18 +12933,16 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
+ readout_plane_state(dev_priv);
+
+ for_each_intel_encoder(dev, encoder) {
++ struct intel_crtc_state *crtc_state = NULL;
++
+ pipe = 0;
+
+ if (encoder->get_hw_state(encoder, &pipe)) {
+- struct intel_crtc_state *crtc_state;
+-
+ crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
+ crtc_state = to_intel_crtc_state(crtc->base.state);
+
+ encoder->base.crtc = &crtc->base;
+ intel_encoder_get_config(encoder, crtc_state);
+- if (encoder->sync_state)
+- encoder->sync_state(encoder, crtc_state);
+
+ /* read out to slave crtc as well for bigjoiner */
+ if (crtc_state->bigjoiner) {
+@@ -12959,6 +12957,9 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
+ encoder->base.crtc = NULL;
+ }
+
++ if (encoder->sync_state)
++ encoder->sync_state(encoder, crtc_state);
++
+ drm_dbg_kms(&dev_priv->drm,
+ "[ENCODER:%d:%s] hw state readout: %s, pipe %c\n",
+ encoder->base.base.id, encoder->base.name,
+@@ -13241,17 +13242,6 @@ intel_modeset_setup_hw_state(struct drm_device *dev,
+ intel_modeset_readout_hw_state(dev);
+
+ /* HW state is read out, now we need to sanitize this mess. */
+-
+- /* Sanitize the TypeC port mode upfront, encoders depend on this */
+- for_each_intel_encoder(dev, encoder) {
+- enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
+-
+- /* We need to sanitize only the MST primary port. */
+- if (encoder->type != INTEL_OUTPUT_DP_MST &&
+- intel_phy_is_tc(dev_priv, phy))
+- intel_tc_port_sanitize(enc_to_dig_port(encoder));
+- }
+-
+ get_encoder_power_domains(dev_priv);
+
+ if (HAS_PCH_IBX(dev_priv))
+diff --git a/drivers/gpu/drm/i915/display/intel_vbt_defs.h b/drivers/gpu/drm/i915/display/intel_vbt_defs.h
+index dbe24d7e73759..cf1ffe4a0e46a 100644
+--- a/drivers/gpu/drm/i915/display/intel_vbt_defs.h
++++ b/drivers/gpu/drm/i915/display/intel_vbt_defs.h
+@@ -814,6 +814,11 @@ struct lfp_brightness_level {
+ u16 reserved;
+ } __packed;
+
++#define EXP_BDB_LFP_BL_DATA_SIZE_REV_191 \
++ offsetof(struct bdb_lfp_backlight_data, brightness_level)
++#define EXP_BDB_LFP_BL_DATA_SIZE_REV_234 \
++ offsetof(struct bdb_lfp_backlight_data, brightness_precision_bits)
++
+ struct bdb_lfp_backlight_data {
+ u8 entry_size;
+ struct lfp_backlight_data_entry data[16];
+diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
+index e382b7f2353b8..5ab136ffdeb2d 100644
+--- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
++++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
+@@ -118,7 +118,7 @@ i915_gem_shrink(struct i915_gem_ww_ctx *ww,
+ intel_wakeref_t wakeref = 0;
+ unsigned long count = 0;
+ unsigned long scanned = 0;
+- int err;
++ int err = 0;
+
+ /* CHV + VTD workaround use stop_machine(); need to trylock vm->mutex */
+ bool trylock_vm = !ww && intel_vm_no_concurrent_access_wa(i915);
+@@ -242,12 +242,15 @@ skip:
+ list_splice_tail(&still_in_list, phase->list);
+ spin_unlock_irqrestore(&i915->mm.obj_lock, flags);
+ if (err)
+- return err;
++ break;
+ }
+
+ if (shrink & I915_SHRINK_BOUND)
+ intel_runtime_pm_put(&i915->runtime_pm, wakeref);
+
++ if (err)
++ return err;
++
+ if (nr_scanned)
+ *nr_scanned += scanned;
+ return count;
+diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
+index 476bb3b9ad11a..5aa5ddefd22d2 100644
+--- a/drivers/gpu/drm/i915/i915_reg.h
++++ b/drivers/gpu/drm/i915/i915_reg.h
+@@ -8113,6 +8113,7 @@ enum {
+ # define CHICKEN3_DGMG_DONE_FIX_DISABLE (1 << 2)
+
+ #define CHICKEN_PAR1_1 _MMIO(0x42080)
++#define IGNORE_KVMR_PIPE_A REG_BIT(23)
+ #define KBL_ARB_FILL_SPARE_22 REG_BIT(22)
+ #define DIS_RAM_BYPASS_PSR2_MAN_TRACK (1 << 16)
+ #define SKL_DE_COMPRESSED_HASH_MODE (1 << 15)
+@@ -8150,6 +8151,11 @@ enum {
+ #define HSW_SPR_STRETCH_MAX_X1 REG_FIELD_PREP(HSW_SPR_STRETCH_MAX_MASK, 3)
+ #define HSW_FBCQ_DIS (1 << 22)
+ #define BDW_DPRS_MASK_VBLANK_SRD (1 << 0)
++#define SKL_PLANE1_STRETCH_MAX_MASK REG_GENMASK(1, 0)
++#define SKL_PLANE1_STRETCH_MAX_X8 REG_FIELD_PREP(SKL_PLANE1_STRETCH_MAX_MASK, 0)
++#define SKL_PLANE1_STRETCH_MAX_X4 REG_FIELD_PREP(SKL_PLANE1_STRETCH_MAX_MASK, 1)
++#define SKL_PLANE1_STRETCH_MAX_X2 REG_FIELD_PREP(SKL_PLANE1_STRETCH_MAX_MASK, 2)
++#define SKL_PLANE1_STRETCH_MAX_X1 REG_FIELD_PREP(SKL_PLANE1_STRETCH_MAX_MASK, 3)
+ #define CHICKEN_PIPESL_1(pipe) _MMIO_PIPE(pipe, _CHICKEN_PIPESL_1_A, _CHICKEN_PIPESL_1_B)
+
+ #define _CHICKEN_TRANS_A 0x420c0
+diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
+index 45fefa0ed1607..28959e67c00ee 100644
+--- a/drivers/gpu/drm/i915/intel_pm.c
++++ b/drivers/gpu/drm/i915/intel_pm.c
+@@ -76,6 +76,8 @@ struct intel_wm_config {
+
+ static void gen9_init_clock_gating(struct drm_i915_private *dev_priv)
+ {
++ enum pipe pipe;
++
+ if (HAS_LLC(dev_priv)) {
+ /*
+ * WaCompressedResourceDisplayNewHashMode:skl,kbl
+@@ -89,6 +91,16 @@ static void gen9_init_clock_gating(struct drm_i915_private *dev_priv)
+ SKL_DE_COMPRESSED_HASH_MODE);
+ }
+
++ for_each_pipe(dev_priv, pipe) {
++ /*
++ * "Plane N strech max must be programmed to 11b (x1)
++ * when Async flips are enabled on that plane."
++ */
++ if (!IS_GEMINILAKE(dev_priv) && intel_vtd_active())
++ intel_uncore_rmw(&dev_priv->uncore, CHICKEN_PIPESL_1(pipe),
++ SKL_PLANE1_STRETCH_MAX_MASK, SKL_PLANE1_STRETCH_MAX_X1);
++ }
++
+ /* See Bspec note for PSR2_CTL bit 31, Wa#828:skl,bxt,kbl,cfl */
+ intel_uncore_write(&dev_priv->uncore, CHICKEN_PAR1_1,
+ intel_uncore_read(&dev_priv->uncore, CHICKEN_PAR1_1) | SKL_EDP_PSR_FIX_RDWRAP);
+diff --git a/drivers/gpu/drm/nouveau/dispnv50/crc.c b/drivers/gpu/drm/nouveau/dispnv50/crc.c
+index b8c31b697797e..66f32d965c723 100644
+--- a/drivers/gpu/drm/nouveau/dispnv50/crc.c
++++ b/drivers/gpu/drm/nouveau/dispnv50/crc.c
+@@ -704,6 +704,7 @@ static const struct file_operations nv50_crc_flip_threshold_fops = {
+ .open = nv50_crc_debugfs_flip_threshold_open,
+ .read = seq_read,
+ .write = nv50_crc_debugfs_flip_threshold_set,
++ .release = single_release,
+ };
+
+ int nv50_head_crc_late_register(struct nv50_head *head)
+diff --git a/drivers/gpu/drm/nouveau/dispnv50/head.c b/drivers/gpu/drm/nouveau/dispnv50/head.c
+index d66f97280282a..72099d1e48169 100644
+--- a/drivers/gpu/drm/nouveau/dispnv50/head.c
++++ b/drivers/gpu/drm/nouveau/dispnv50/head.c
+@@ -52,6 +52,7 @@ nv50_head_flush_clr(struct nv50_head *head,
+ void
+ nv50_head_flush_set_wndw(struct nv50_head *head, struct nv50_head_atom *asyh)
+ {
++ if (asyh->set.curs ) head->func->curs_set(head, asyh);
+ if (asyh->set.olut ) {
+ asyh->olut.offset = nv50_lut_load(&head->olut,
+ asyh->olut.buffer,
+@@ -67,7 +68,6 @@ nv50_head_flush_set(struct nv50_head *head, struct nv50_head_atom *asyh)
+ if (asyh->set.view ) head->func->view (head, asyh);
+ if (asyh->set.mode ) head->func->mode (head, asyh);
+ if (asyh->set.core ) head->func->core_set(head, asyh);
+- if (asyh->set.curs ) head->func->curs_set(head, asyh);
+ if (asyh->set.base ) head->func->base (head, asyh);
+ if (asyh->set.ovly ) head->func->ovly (head, asyh);
+ if (asyh->set.dither ) head->func->dither (head, asyh);
+diff --git a/drivers/gpu/drm/nouveau/include/nvif/class.h b/drivers/gpu/drm/nouveau/include/nvif/class.h
+index c68cc957248e2..a582c0cb0cb0d 100644
+--- a/drivers/gpu/drm/nouveau/include/nvif/class.h
++++ b/drivers/gpu/drm/nouveau/include/nvif/class.h
+@@ -71,6 +71,7 @@
+ #define PASCAL_CHANNEL_GPFIFO_A /* cla06f.h */ 0x0000c06f
+ #define VOLTA_CHANNEL_GPFIFO_A /* clc36f.h */ 0x0000c36f
+ #define TURING_CHANNEL_GPFIFO_A /* clc36f.h */ 0x0000c46f
++#define AMPERE_CHANNEL_GPFIFO_B /* clc36f.h */ 0x0000c76f
+
+ #define NV50_DISP /* cl5070.h */ 0x00005070
+ #define G82_DISP /* cl5070.h */ 0x00008270
+@@ -200,6 +201,7 @@
+ #define PASCAL_DMA_COPY_B 0x0000c1b5
+ #define VOLTA_DMA_COPY_A 0x0000c3b5
+ #define TURING_DMA_COPY_A 0x0000c5b5
++#define AMPERE_DMA_COPY_B 0x0000c7b5
+
+ #define FERMI_DECOMPRESS 0x000090b8
+
+diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h
+index 54fab7cc36c1b..64ee82c7c1be5 100644
+--- a/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h
++++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h
+@@ -77,4 +77,5 @@ int gp100_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct
+ int gp10b_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
+ int gv100_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
+ int tu102_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
++int ga102_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
+ #endif
+diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
+index 6d07e653f82d5..c58bcdba2c7aa 100644
+--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
++++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
+@@ -844,6 +844,7 @@ nouveau_bo_move_init(struct nouveau_drm *drm)
+ struct ttm_resource *, struct ttm_resource *);
+ int (*init)(struct nouveau_channel *, u32 handle);
+ } _methods[] = {
++ { "COPY", 4, 0xc7b5, nve0_bo_move_copy, nve0_bo_move_init },
+ { "COPY", 4, 0xc5b5, nve0_bo_move_copy, nve0_bo_move_init },
+ { "GRCE", 0, 0xc5b5, nve0_bo_move_copy, nvc0_bo_move_init },
+ { "COPY", 4, 0xc3b5, nve0_bo_move_copy, nve0_bo_move_init },
+diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c
+index 80099ef757022..ea7769135b0dc 100644
+--- a/drivers/gpu/drm/nouveau/nouveau_chan.c
++++ b/drivers/gpu/drm/nouveau/nouveau_chan.c
+@@ -250,7 +250,8 @@ static int
+ nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device,
+ u64 runlist, bool priv, struct nouveau_channel **pchan)
+ {
+- static const u16 oclasses[] = { TURING_CHANNEL_GPFIFO_A,
++ static const u16 oclasses[] = { AMPERE_CHANNEL_GPFIFO_B,
++ TURING_CHANNEL_GPFIFO_A,
+ VOLTA_CHANNEL_GPFIFO_A,
+ PASCAL_CHANNEL_GPFIFO_A,
+ MAXWELL_CHANNEL_GPFIFO_A,
+@@ -386,7 +387,8 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart)
+
+ nvif_object_map(&chan->user, NULL, 0);
+
+- if (chan->user.oclass >= FERMI_CHANNEL_GPFIFO) {
++ if (chan->user.oclass >= FERMI_CHANNEL_GPFIFO &&
++ chan->user.oclass < AMPERE_CHANNEL_GPFIFO_B) {
+ ret = nvif_notify_ctor(&chan->user, "abi16ChanKilled",
+ nouveau_channel_killed,
+ true, NV906F_V0_NTFY_KILLED,
+diff --git a/drivers/gpu/drm/nouveau/nouveau_debugfs.c b/drivers/gpu/drm/nouveau/nouveau_debugfs.c
+index c2bc05eb2e54a..1cbe01048b930 100644
+--- a/drivers/gpu/drm/nouveau/nouveau_debugfs.c
++++ b/drivers/gpu/drm/nouveau/nouveau_debugfs.c
+@@ -207,6 +207,7 @@ static const struct file_operations nouveau_pstate_fops = {
+ .open = nouveau_debugfs_pstate_open,
+ .read = seq_read,
+ .write = nouveau_debugfs_pstate_set,
++ .release = single_release,
+ };
+
+ static struct drm_info_list nouveau_debugfs_list[] = {
+diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
+index ba4cd5f837259..9b0084e4bbcfb 100644
+--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
++++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
+@@ -345,6 +345,9 @@ nouveau_accel_gr_init(struct nouveau_drm *drm)
+ u32 arg0, arg1;
+ int ret;
+
++ if (device->info.family >= NV_DEVICE_INFO_V0_AMPERE)
++ return;
++
+ /* Allocate channel that has access to the graphics engine. */
+ if (device->info.family >= NV_DEVICE_INFO_V0_KEPLER) {
+ arg0 = nvif_fifo_runlist(device, NV_DEVICE_HOST_RUNLIST_ENGINES_GR);
+@@ -469,6 +472,7 @@ nouveau_accel_init(struct nouveau_drm *drm)
+ case PASCAL_CHANNEL_GPFIFO_A:
+ case VOLTA_CHANNEL_GPFIFO_A:
+ case TURING_CHANNEL_GPFIFO_A:
++ case AMPERE_CHANNEL_GPFIFO_B:
+ ret = nvc0_fence_create(drm);
+ break;
+ default:
+diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
+index 5b27845075a1c..8c2ecc2827232 100644
+--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
++++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
+@@ -247,10 +247,8 @@ nouveau_gem_new(struct nouveau_cli *cli, u64 size, int align, uint32_t domain,
+ }
+
+ ret = nouveau_bo_init(nvbo, size, align, domain, NULL, NULL);
+- if (ret) {
+- nouveau_bo_ref(NULL, &nvbo);
++ if (ret)
+ return ret;
+- }
+
+ /* we restrict allowed domains on nv50+ to only the types
+ * that were requested at creation time. not possibly on
+diff --git a/drivers/gpu/drm/nouveau/nv84_fence.c b/drivers/gpu/drm/nouveau/nv84_fence.c
+index 7c9c928c31966..c3526a8622e3e 100644
+--- a/drivers/gpu/drm/nouveau/nv84_fence.c
++++ b/drivers/gpu/drm/nouveau/nv84_fence.c
+@@ -204,7 +204,7 @@ nv84_fence_create(struct nouveau_drm *drm)
+ priv->base.context_new = nv84_fence_context_new;
+ priv->base.context_del = nv84_fence_context_del;
+
+- priv->base.uevent = true;
++ priv->base.uevent = drm->client.device.info.family < NV_DEVICE_INFO_V0_AMPERE;
+
+ mutex_init(&priv->mutex);
+
+diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
+index 93ddf63d11140..ca75c5f6ecaf8 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
+@@ -2602,6 +2602,7 @@ nv172_chipset = {
+ .top = { 0x00000001, ga100_top_new },
+ .disp = { 0x00000001, ga102_disp_new },
+ .dma = { 0x00000001, gv100_dma_new },
++ .fifo = { 0x00000001, ga102_fifo_new },
+ };
+
+ static const struct nvkm_device_chip
+@@ -2622,6 +2623,7 @@ nv174_chipset = {
+ .top = { 0x00000001, ga100_top_new },
+ .disp = { 0x00000001, ga102_disp_new },
+ .dma = { 0x00000001, gv100_dma_new },
++ .fifo = { 0x00000001, ga102_fifo_new },
+ };
+
+ static const struct nvkm_device_chip
+@@ -2642,6 +2644,7 @@ nv177_chipset = {
+ .top = { 0x00000001, ga100_top_new },
+ .disp = { 0x00000001, ga102_disp_new },
+ .dma = { 0x00000001, gv100_dma_new },
++ .fifo = { 0x00000001, ga102_fifo_new },
+ };
+
+ static int
+diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild
+index 3209eb7af65fb..5e831d347a957 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild
+@@ -18,6 +18,7 @@ nvkm-y += nvkm/engine/fifo/gp100.o
+ nvkm-y += nvkm/engine/fifo/gp10b.o
+ nvkm-y += nvkm/engine/fifo/gv100.o
+ nvkm-y += nvkm/engine/fifo/tu102.o
++nvkm-y += nvkm/engine/fifo/ga102.o
+
+ nvkm-y += nvkm/engine/fifo/chan.o
+ nvkm-y += nvkm/engine/fifo/channv50.o
+diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga102.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga102.c
+new file mode 100644
+index 0000000000000..c630dbd2911ae
+--- /dev/null
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga102.c
+@@ -0,0 +1,311 @@
++/*
++ * Copyright 2021 Red Hat Inc.
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining a
++ * copy of this software and associated documentation files (the "Software"),
++ * to deal in the Software without restriction, including without limitation
++ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
++ * and/or sell copies of the Software, and to permit persons to whom the
++ * Software is furnished to do so, subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be included in
++ * all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
++ * OTHER DEALINGS IN THE SOFTWARE.
++ */
++#define ga102_fifo(p) container_of((p), struct ga102_fifo, base.engine)
++#define ga102_chan(p) container_of((p), struct ga102_chan, object)
++#include <engine/fifo.h>
++#include "user.h"
++
++#include <core/memory.h>
++#include <subdev/mmu.h>
++#include <subdev/timer.h>
++#include <subdev/top.h>
++
++#include <nvif/cl0080.h>
++#include <nvif/clc36f.h>
++#include <nvif/class.h>
++
++struct ga102_fifo {
++ struct nvkm_fifo base;
++};
++
++struct ga102_chan {
++ struct nvkm_object object;
++
++ struct {
++ u32 runl;
++ u32 chan;
++ } ctrl;
++
++ struct nvkm_memory *mthd;
++ struct nvkm_memory *inst;
++ struct nvkm_memory *user;
++ struct nvkm_memory *runl;
++
++ struct nvkm_vmm *vmm;
++};
++
++static int
++ga102_chan_sclass(struct nvkm_object *object, int index, struct nvkm_oclass *oclass)
++{
++ if (index == 0) {
++ oclass->ctor = nvkm_object_new;
++ oclass->base = (struct nvkm_sclass) { -1, -1, AMPERE_DMA_COPY_B };
++ return 0;
++ }
++
++ return -EINVAL;
++}
++
++static int
++ga102_chan_map(struct nvkm_object *object, void *argv, u32 argc,
++ enum nvkm_object_map *type, u64 *addr, u64 *size)
++{
++ struct ga102_chan *chan = ga102_chan(object);
++ struct nvkm_device *device = chan->object.engine->subdev.device;
++ u64 bar2 = nvkm_memory_bar2(chan->user);
++
++ if (bar2 == ~0ULL)
++ return -EFAULT;
++
++ *type = NVKM_OBJECT_MAP_IO;
++ *addr = device->func->resource_addr(device, 3) + bar2;
++ *size = 0x1000;
++ return 0;
++}
++
++static int
++ga102_chan_fini(struct nvkm_object *object, bool suspend)
++{
++ struct ga102_chan *chan = ga102_chan(object);
++ struct nvkm_device *device = chan->object.engine->subdev.device;
++
++ nvkm_wr32(device, chan->ctrl.chan, 0x00000003);
++
++ nvkm_wr32(device, chan->ctrl.runl + 0x098, 0x01000000);
++ nvkm_msec(device, 2000,
++ if (!(nvkm_rd32(device, chan->ctrl.runl + 0x098) & 0x00100000))
++ break;
++ );
++
++ nvkm_wr32(device, chan->ctrl.runl + 0x088, 0);
++
++ nvkm_wr32(device, chan->ctrl.chan, 0xffffffff);
++ return 0;
++}
++
++static int
++ga102_chan_init(struct nvkm_object *object)
++{
++ struct ga102_chan *chan = ga102_chan(object);
++ struct nvkm_device *device = chan->object.engine->subdev.device;
++
++ nvkm_mask(device, chan->ctrl.runl + 0x300, 0x80000000, 0x80000000);
++
++ nvkm_wr32(device, chan->ctrl.runl + 0x080, lower_32_bits(nvkm_memory_addr(chan->runl)));
++ nvkm_wr32(device, chan->ctrl.runl + 0x084, upper_32_bits(nvkm_memory_addr(chan->runl)));
++ nvkm_wr32(device, chan->ctrl.runl + 0x088, 2);
++
++ nvkm_wr32(device, chan->ctrl.chan, 0x00000002);
++ nvkm_wr32(device, chan->ctrl.runl + 0x0090, 0);
++ return 0;
++}
++
++static void *
++ga102_chan_dtor(struct nvkm_object *object)
++{
++ struct ga102_chan *chan = ga102_chan(object);
++
++ if (chan->vmm) {
++ nvkm_vmm_part(chan->vmm, chan->inst);
++ nvkm_vmm_unref(&chan->vmm);
++ }
++
++ nvkm_memory_unref(&chan->runl);
++ nvkm_memory_unref(&chan->user);
++ nvkm_memory_unref(&chan->inst);
++ nvkm_memory_unref(&chan->mthd);
++ return chan;
++}
++
++static const struct nvkm_object_func
++ga102_chan = {
++ .dtor = ga102_chan_dtor,
++ .init = ga102_chan_init,
++ .fini = ga102_chan_fini,
++ .map = ga102_chan_map,
++ .sclass = ga102_chan_sclass,
++};
++
++static int
++ga102_chan_new(struct nvkm_device *device,
++ const struct nvkm_oclass *oclass, void *argv, u32 argc, struct nvkm_object **pobject)
++{
++ struct volta_channel_gpfifo_a_v0 *args = argv;
++ struct nvkm_top_device *tdev;
++ struct nvkm_vmm *vmm;
++ struct ga102_chan *chan;
++ int ret;
++
++ if (argc != sizeof(*args))
++ return -ENOSYS;
++
++ vmm = nvkm_uvmm_search(oclass->client, args->vmm);
++ if (IS_ERR(vmm))
++ return PTR_ERR(vmm);
++
++ if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL)))
++ return -ENOMEM;
++
++ nvkm_object_ctor(&ga102_chan, oclass, &chan->object);
++ *pobject = &chan->object;
++
++ list_for_each_entry(tdev, &device->top->device, head) {
++ if (tdev->type == NVKM_ENGINE_CE) {
++ chan->ctrl.runl = tdev->runlist;
++ break;
++ }
++ }
++
++ if (!chan->ctrl.runl)
++ return -ENODEV;
++
++ chan->ctrl.chan = nvkm_rd32(device, chan->ctrl.runl + 0x004) & 0xfffffff0;
++
++ args->chid = 0;
++ args->inst = 0;
++ args->token = nvkm_rd32(device, chan->ctrl.runl + 0x008) & 0xffff0000;
++
++ ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 0x1000, true, &chan->mthd);
++ if (ret)
++ return ret;
++
++ ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 0x1000, true, &chan->inst);
++ if (ret)
++ return ret;
++
++ nvkm_kmap(chan->inst);
++ nvkm_wo32(chan->inst, 0x010, 0x0000face);
++ nvkm_wo32(chan->inst, 0x030, 0x7ffff902);
++ nvkm_wo32(chan->inst, 0x048, lower_32_bits(args->ioffset));
++ nvkm_wo32(chan->inst, 0x04c, upper_32_bits(args->ioffset) |
++ (order_base_2(args->ilength / 8) << 16));
++ nvkm_wo32(chan->inst, 0x084, 0x20400000);
++ nvkm_wo32(chan->inst, 0x094, 0x30000001);
++ nvkm_wo32(chan->inst, 0x0ac, 0x00020000);
++ nvkm_wo32(chan->inst, 0x0e4, 0x00000000);
++ nvkm_wo32(chan->inst, 0x0e8, 0);
++ nvkm_wo32(chan->inst, 0x0f4, 0x00001000);
++ nvkm_wo32(chan->inst, 0x0f8, 0x10003080);
++ nvkm_mo32(chan->inst, 0x218, 0x00000000, 0x00000000);
++ nvkm_wo32(chan->inst, 0x220, lower_32_bits(nvkm_memory_bar2(chan->mthd)));
++ nvkm_wo32(chan->inst, 0x224, upper_32_bits(nvkm_memory_bar2(chan->mthd)));
++ nvkm_done(chan->inst);
++
++ ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 0x1000, true, &chan->user);
++ if (ret)
++ return ret;
++
++ ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 0x1000, true, &chan->runl);
++ if (ret)
++ return ret;
++
++ nvkm_kmap(chan->runl);
++ nvkm_wo32(chan->runl, 0x00, 0x80030001);
++ nvkm_wo32(chan->runl, 0x04, 1);
++ nvkm_wo32(chan->runl, 0x08, 0);
++ nvkm_wo32(chan->runl, 0x0c, 0x00000000);
++ nvkm_wo32(chan->runl, 0x10, lower_32_bits(nvkm_memory_addr(chan->user)));
++ nvkm_wo32(chan->runl, 0x14, upper_32_bits(nvkm_memory_addr(chan->user)));
++ nvkm_wo32(chan->runl, 0x18, lower_32_bits(nvkm_memory_addr(chan->inst)));
++ nvkm_wo32(chan->runl, 0x1c, upper_32_bits(nvkm_memory_addr(chan->inst)));
++ nvkm_done(chan->runl);
++
++ ret = nvkm_vmm_join(vmm, chan->inst);
++ if (ret)
++ return ret;
++
++ chan->vmm = nvkm_vmm_ref(vmm);
++ return 0;
++}
++
++static const struct nvkm_device_oclass
++ga102_chan_oclass = {
++ .ctor = ga102_chan_new,
++};
++
++static int
++ga102_user_new(struct nvkm_device *device,
++ const struct nvkm_oclass *oclass, void *argv, u32 argc, struct nvkm_object **pobject)
++{
++ return tu102_fifo_user_new(oclass, argv, argc, pobject);
++}
++
++static const struct nvkm_device_oclass
++ga102_user_oclass = {
++ .ctor = ga102_user_new,
++};
++
++static int
++ga102_fifo_sclass(struct nvkm_oclass *oclass, int index, const struct nvkm_device_oclass **class)
++{
++ if (index == 0) {
++ oclass->base = (struct nvkm_sclass) { -1, -1, VOLTA_USERMODE_A };
++ *class = &ga102_user_oclass;
++ return 0;
++ } else
++ if (index == 1) {
++ oclass->base = (struct nvkm_sclass) { 0, 0, AMPERE_CHANNEL_GPFIFO_B };
++ *class = &ga102_chan_oclass;
++ return 0;
++ }
++
++ return 2;
++}
++
++static int
++ga102_fifo_info(struct nvkm_engine *engine, u64 mthd, u64 *data)
++{
++ switch (mthd) {
++ case NV_DEVICE_HOST_CHANNELS: *data = 1; return 0;
++ default:
++ break;
++ }
++
++ return -ENOSYS;
++}
++
++static void *
++ga102_fifo_dtor(struct nvkm_engine *engine)
++{
++ return ga102_fifo(engine);
++}
++
++static const struct nvkm_engine_func
++ga102_fifo = {
++ .dtor = ga102_fifo_dtor,
++ .info = ga102_fifo_info,
++ .base.sclass = ga102_fifo_sclass,
++};
++
++int
++ga102_fifo_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
++ struct nvkm_fifo **pfifo)
++{
++ struct ga102_fifo *fifo;
++
++ if (!(fifo = kzalloc(sizeof(*fifo), GFP_KERNEL)))
++ return -ENOMEM;
++
++ nvkm_engine_ctor(&ga102_fifo, device, type, inst, true, &fifo->base.engine);
++ *pfifo = &fifo->base;
++ return 0;
++}
+diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/top/ga100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/top/ga100.c
+index 31933f3e5a076..c982d834c8d98 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/subdev/top/ga100.c
++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/top/ga100.c
+@@ -54,7 +54,7 @@ ga100_top_oneinit(struct nvkm_top *top)
+ info->reset = (data & 0x0000001f);
+ break;
+ case 2:
+- info->runlist = (data & 0x0000fc00) >> 10;
++ info->runlist = (data & 0x00fffc00);
+ info->engine = (data & 0x00000003);
+ break;
+ default:
+@@ -85,9 +85,10 @@ ga100_top_oneinit(struct nvkm_top *top)
+ }
+
+ nvkm_debug(subdev, "%02x.%d (%8s): addr %06x fault %2d "
+- "runlist %2d engine %2d reset %2d\n", type, inst,
++ "runlist %6x engine %2d reset %2d\n", type, inst,
+ info->type == NVKM_SUBDEV_NR ? "????????" : nvkm_subdev_type[info->type],
+- info->addr, info->fault, info->runlist, info->engine, info->reset);
++ info->addr, info->fault, info->runlist < 0 ? 0 : info->runlist,
++ info->engine, info->reset);
+ info = NULL;
+ }
+
+diff --git a/drivers/gpu/drm/panel/panel-abt-y030xx067a.c b/drivers/gpu/drm/panel/panel-abt-y030xx067a.c
+index 2d8794d495d08..3d8a9ab47cae2 100644
+--- a/drivers/gpu/drm/panel/panel-abt-y030xx067a.c
++++ b/drivers/gpu/drm/panel/panel-abt-y030xx067a.c
+@@ -146,8 +146,8 @@ static const struct reg_sequence y030xx067a_init_sequence[] = {
+ { 0x09, REG09_SUB_BRIGHT_R(0x20) },
+ { 0x0a, REG0A_SUB_BRIGHT_B(0x20) },
+ { 0x0b, REG0B_HD_FREERUN | REG0B_VD_FREERUN },
+- { 0x0c, REG0C_CONTRAST_R(0x10) },
+- { 0x0d, REG0D_CONTRAST_G(0x10) },
++ { 0x0c, REG0C_CONTRAST_R(0x00) },
++ { 0x0d, REG0D_CONTRAST_G(0x00) },
+ { 0x0e, REG0E_CONTRAST_B(0x10) },
+ { 0x0f, 0 },
+ { 0x10, REG10_BRIGHT(0x7f) },
+diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
+index f75fb157f2ff7..016b877051dab 100644
+--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
++++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
+@@ -216,11 +216,13 @@ static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master,
+ goto err_disable_clk_tmds;
+ }
+
++ ret = sun8i_hdmi_phy_init(hdmi->phy);
++ if (ret)
++ goto err_disable_clk_tmds;
++
+ drm_encoder_helper_add(encoder, &sun8i_dw_hdmi_encoder_helper_funcs);
+ drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);
+
+- sun8i_hdmi_phy_init(hdmi->phy);
+-
+ plat_data->mode_valid = hdmi->quirks->mode_valid;
+ plat_data->use_drm_infoframe = hdmi->quirks->use_drm_infoframe;
+ sun8i_hdmi_phy_set_ops(hdmi->phy, plat_data);
+@@ -262,6 +264,7 @@ static void sun8i_dw_hdmi_unbind(struct device *dev, struct device *master,
+ struct sun8i_dw_hdmi *hdmi = dev_get_drvdata(dev);
+
+ dw_hdmi_unbind(hdmi->hdmi);
++ sun8i_hdmi_phy_deinit(hdmi->phy);
+ clk_disable_unprepare(hdmi->clk_tmds);
+ reset_control_assert(hdmi->rst_ctrl);
+ gpiod_set_value(hdmi->ddc_en, 0);
+diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
+index 74f6ed0e25709..bffe1b9cd3dcb 100644
+--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
++++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
+@@ -169,6 +169,7 @@ struct sun8i_hdmi_phy {
+ struct clk *clk_phy;
+ struct clk *clk_pll0;
+ struct clk *clk_pll1;
++ struct device *dev;
+ unsigned int rcal;
+ struct regmap *regs;
+ struct reset_control *rst_phy;
+@@ -205,7 +206,8 @@ encoder_to_sun8i_dw_hdmi(struct drm_encoder *encoder)
+
+ int sun8i_hdmi_phy_get(struct sun8i_dw_hdmi *hdmi, struct device_node *node);
+
+-void sun8i_hdmi_phy_init(struct sun8i_hdmi_phy *phy);
++int sun8i_hdmi_phy_init(struct sun8i_hdmi_phy *phy);
++void sun8i_hdmi_phy_deinit(struct sun8i_hdmi_phy *phy);
+ void sun8i_hdmi_phy_set_ops(struct sun8i_hdmi_phy *phy,
+ struct dw_hdmi_plat_data *plat_data);
+
+diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
+index c9239708d398c..b64d93da651d2 100644
+--- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
++++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
+@@ -506,9 +506,60 @@ static void sun8i_hdmi_phy_init_h3(struct sun8i_hdmi_phy *phy)
+ phy->rcal = (val & SUN8I_HDMI_PHY_ANA_STS_RCAL_MASK) >> 2;
+ }
+
+-void sun8i_hdmi_phy_init(struct sun8i_hdmi_phy *phy)
++int sun8i_hdmi_phy_init(struct sun8i_hdmi_phy *phy)
+ {
++ int ret;
++
++ ret = reset_control_deassert(phy->rst_phy);
++ if (ret) {
++ dev_err(phy->dev, "Cannot deassert phy reset control: %d\n", ret);
++ return ret;
++ }
++
++ ret = clk_prepare_enable(phy->clk_bus);
++ if (ret) {
++ dev_err(phy->dev, "Cannot enable bus clock: %d\n", ret);
++ goto err_assert_rst_phy;
++ }
++
++ ret = clk_prepare_enable(phy->clk_mod);
++ if (ret) {
++ dev_err(phy->dev, "Cannot enable mod clock: %d\n", ret);
++ goto err_disable_clk_bus;
++ }
++
++ if (phy->variant->has_phy_clk) {
++ ret = sun8i_phy_clk_create(phy, phy->dev,
++ phy->variant->has_second_pll);
++ if (ret) {
++ dev_err(phy->dev, "Couldn't create the PHY clock\n");
++ goto err_disable_clk_mod;
++ }
++
++ clk_prepare_enable(phy->clk_phy);
++ }
++
+ phy->variant->phy_init(phy);
++
++ return 0;
++
++err_disable_clk_mod:
++ clk_disable_unprepare(phy->clk_mod);
++err_disable_clk_bus:
++ clk_disable_unprepare(phy->clk_bus);
++err_assert_rst_phy:
++ reset_control_assert(phy->rst_phy);
++
++ return ret;
++}
++
++void sun8i_hdmi_phy_deinit(struct sun8i_hdmi_phy *phy)
++{
++ clk_disable_unprepare(phy->clk_mod);
++ clk_disable_unprepare(phy->clk_bus);
++ clk_disable_unprepare(phy->clk_phy);
++
++ reset_control_assert(phy->rst_phy);
+ }
+
+ void sun8i_hdmi_phy_set_ops(struct sun8i_hdmi_phy *phy,
+@@ -638,6 +689,7 @@ static int sun8i_hdmi_phy_probe(struct platform_device *pdev)
+ return -ENOMEM;
+
+ phy->variant = (struct sun8i_hdmi_phy_variant *)match->data;
++ phy->dev = dev;
+
+ ret = of_address_to_resource(node, 0, &res);
+ if (ret) {
+@@ -696,47 +748,10 @@ static int sun8i_hdmi_phy_probe(struct platform_device *pdev)
+ goto err_put_clk_pll1;
+ }
+
+- ret = reset_control_deassert(phy->rst_phy);
+- if (ret) {
+- dev_err(dev, "Cannot deassert phy reset control: %d\n", ret);
+- goto err_put_rst_phy;
+- }
+-
+- ret = clk_prepare_enable(phy->clk_bus);
+- if (ret) {
+- dev_err(dev, "Cannot enable bus clock: %d\n", ret);
+- goto err_deassert_rst_phy;
+- }
+-
+- ret = clk_prepare_enable(phy->clk_mod);
+- if (ret) {
+- dev_err(dev, "Cannot enable mod clock: %d\n", ret);
+- goto err_disable_clk_bus;
+- }
+-
+- if (phy->variant->has_phy_clk) {
+- ret = sun8i_phy_clk_create(phy, dev,
+- phy->variant->has_second_pll);
+- if (ret) {
+- dev_err(dev, "Couldn't create the PHY clock\n");
+- goto err_disable_clk_mod;
+- }
+-
+- clk_prepare_enable(phy->clk_phy);
+- }
+-
+ platform_set_drvdata(pdev, phy);
+
+ return 0;
+
+-err_disable_clk_mod:
+- clk_disable_unprepare(phy->clk_mod);
+-err_disable_clk_bus:
+- clk_disable_unprepare(phy->clk_bus);
+-err_deassert_rst_phy:
+- reset_control_assert(phy->rst_phy);
+-err_put_rst_phy:
+- reset_control_put(phy->rst_phy);
+ err_put_clk_pll1:
+ clk_put(phy->clk_pll1);
+ err_put_clk_pll0:
+@@ -753,12 +768,6 @@ static int sun8i_hdmi_phy_remove(struct platform_device *pdev)
+ {
+ struct sun8i_hdmi_phy *phy = platform_get_drvdata(pdev);
+
+- clk_disable_unprepare(phy->clk_mod);
+- clk_disable_unprepare(phy->clk_bus);
+- clk_disable_unprepare(phy->clk_phy);
+-
+- reset_control_assert(phy->rst_phy);
+-
+ reset_control_put(phy->rst_phy);
+
+ clk_put(phy->clk_pll0);
+diff --git a/drivers/i2c/busses/i2c-mlxcpld.c b/drivers/i2c/busses/i2c-mlxcpld.c
+index 4e0b7c2882ced..015e11c4663f3 100644
+--- a/drivers/i2c/busses/i2c-mlxcpld.c
++++ b/drivers/i2c/busses/i2c-mlxcpld.c
+@@ -49,7 +49,7 @@
+ #define MLXCPLD_LPCI2C_NACK_IND 2
+
+ #define MLXCPLD_I2C_FREQ_1000KHZ_SET 0x04
+-#define MLXCPLD_I2C_FREQ_400KHZ_SET 0x0f
++#define MLXCPLD_I2C_FREQ_400KHZ_SET 0x0c
+ #define MLXCPLD_I2C_FREQ_100KHZ_SET 0x42
+
+ enum mlxcpld_i2c_frequency {
+@@ -495,7 +495,7 @@ mlxcpld_i2c_set_frequency(struct mlxcpld_i2c_priv *priv,
+ return err;
+
+ /* Set frequency only if it is not 100KHz, which is default. */
+- switch ((data->reg & data->mask) >> data->bit) {
++ switch ((regval & data->mask) >> data->bit) {
+ case MLXCPLD_I2C_FREQ_1000KHZ:
+ freq = MLXCPLD_I2C_FREQ_1000KHZ_SET;
+ break;
+diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
+index 477480d1de6bd..7d4b3eb7077ad 100644
+--- a/drivers/i2c/busses/i2c-mt65xx.c
++++ b/drivers/i2c/busses/i2c-mt65xx.c
+@@ -41,6 +41,8 @@
+ #define I2C_HANDSHAKE_RST 0x0020
+ #define I2C_FIFO_ADDR_CLR 0x0001
+ #define I2C_DELAY_LEN 0x0002
++#define I2C_ST_START_CON 0x8001
++#define I2C_FS_START_CON 0x1800
+ #define I2C_TIME_CLR_VALUE 0x0000
+ #define I2C_TIME_DEFAULT_VALUE 0x0003
+ #define I2C_WRRD_TRANAC_VALUE 0x0002
+@@ -480,6 +482,7 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c)
+ {
+ u16 control_reg;
+ u16 intr_stat_reg;
++ u16 ext_conf_val;
+
+ mtk_i2c_writew(i2c, I2C_CHN_CLR_FLAG, OFFSET_START);
+ intr_stat_reg = mtk_i2c_readw(i2c, OFFSET_INTR_STAT);
+@@ -518,8 +521,13 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c)
+ if (i2c->dev_comp->ltiming_adjust)
+ mtk_i2c_writew(i2c, i2c->ltiming_reg, OFFSET_LTIMING);
+
++ if (i2c->speed_hz <= I2C_MAX_STANDARD_MODE_FREQ)
++ ext_conf_val = I2C_ST_START_CON;
++ else
++ ext_conf_val = I2C_FS_START_CON;
++
+ if (i2c->dev_comp->timing_adjust) {
+- mtk_i2c_writew(i2c, i2c->ac_timing.ext, OFFSET_EXT_CONF);
++ ext_conf_val = i2c->ac_timing.ext;
+ mtk_i2c_writew(i2c, i2c->ac_timing.inter_clk_div,
+ OFFSET_CLOCK_DIV);
+ mtk_i2c_writew(i2c, I2C_SCL_MIS_COMP_VALUE,
+@@ -544,6 +552,7 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c)
+ OFFSET_HS_STA_STO_AC_TIMING);
+ }
+ }
++ mtk_i2c_writew(i2c, ext_conf_val, OFFSET_EXT_CONF);
+
+ /* If use i2c pin from PMIC mt6397 side, need set PATH_DIR first */
+ if (i2c->have_pmic)
+diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c
+index 6f0aa0ed3241e..74925621f2395 100644
+--- a/drivers/i2c/i2c-core-acpi.c
++++ b/drivers/i2c/i2c-core-acpi.c
+@@ -422,6 +422,7 @@ static int i2c_acpi_notify(struct notifier_block *nb, unsigned long value,
+ break;
+
+ i2c_acpi_register_device(adapter, adev, &info);
++ put_device(&adapter->dev);
+ break;
+ case ACPI_RECONFIG_DEVICE_REMOVE:
+ if (!acpi_device_enumerated(adev))
+diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c
+index 3f28eb4d17fe7..8f36536cb1b6d 100644
+--- a/drivers/mmc/host/meson-gx-mmc.c
++++ b/drivers/mmc/host/meson-gx-mmc.c
+@@ -746,7 +746,7 @@ static void meson_mmc_desc_chain_transfer(struct mmc_host *mmc, u32 cmd_cfg)
+ writel(start, host->regs + SD_EMMC_START);
+ }
+
+-/* local sg copy to buffer version with _to/fromio usage for dram_access_quirk */
++/* local sg copy for dram_access_quirk */
+ static void meson_mmc_copy_buffer(struct meson_host *host, struct mmc_data *data,
+ size_t buflen, bool to_buffer)
+ {
+@@ -764,21 +764,27 @@ static void meson_mmc_copy_buffer(struct meson_host *host, struct mmc_data *data
+ sg_miter_start(&miter, sgl, nents, sg_flags);
+
+ while ((offset < buflen) && sg_miter_next(&miter)) {
+- unsigned int len;
++ unsigned int buf_offset = 0;
++ unsigned int len, left;
++ u32 *buf = miter.addr;
+
+ len = min(miter.length, buflen - offset);
++ left = len;
+
+- /* When dram_access_quirk, the bounce buffer is a iomem mapping */
+- if (host->dram_access_quirk) {
+- if (to_buffer)
+- memcpy_toio(host->bounce_iomem_buf + offset, miter.addr, len);
+- else
+- memcpy_fromio(miter.addr, host->bounce_iomem_buf + offset, len);
++ if (to_buffer) {
++ do {
++ writel(*buf++, host->bounce_iomem_buf + offset + buf_offset);
++
++ buf_offset += 4;
++ left -= 4;
++ } while (left);
+ } else {
+- if (to_buffer)
+- memcpy(host->bounce_buf + offset, miter.addr, len);
+- else
+- memcpy(miter.addr, host->bounce_buf + offset, len);
++ do {
++ *buf++ = readl(host->bounce_iomem_buf + offset + buf_offset);
++
++ buf_offset += 4;
++ left -= 4;
++ } while (left);
+ }
+
+ offset += len;
+@@ -830,7 +836,11 @@ static void meson_mmc_start_cmd(struct mmc_host *mmc, struct mmc_command *cmd)
+ if (data->flags & MMC_DATA_WRITE) {
+ cmd_cfg |= CMD_CFG_DATA_WR;
+ WARN_ON(xfer_bytes > host->bounce_buf_size);
+- meson_mmc_copy_buffer(host, data, xfer_bytes, true);
++ if (host->dram_access_quirk)
++ meson_mmc_copy_buffer(host, data, xfer_bytes, true);
++ else
++ sg_copy_to_buffer(data->sg, data->sg_len,
++ host->bounce_buf, xfer_bytes);
+ dma_wmb();
+ }
+
+@@ -849,12 +859,43 @@ static void meson_mmc_start_cmd(struct mmc_host *mmc, struct mmc_command *cmd)
+ writel(cmd->arg, host->regs + SD_EMMC_CMD_ARG);
+ }
+
++static int meson_mmc_validate_dram_access(struct mmc_host *mmc, struct mmc_data *data)
++{
++ struct scatterlist *sg;
++ int i;
++
++ /* Reject request if any element offset or size is not 32bit aligned */
++ for_each_sg(data->sg, sg, data->sg_len, i) {
++ if (!IS_ALIGNED(sg->offset, sizeof(u32)) ||
++ !IS_ALIGNED(sg->length, sizeof(u32))) {
++ dev_err(mmc_dev(mmc), "unaligned sg offset %u len %u\n",
++ data->sg->offset, data->sg->length);
++ return -EINVAL;
++ }
++ }
++
++ return 0;
++}
++
+ static void meson_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
+ {
+ struct meson_host *host = mmc_priv(mmc);
+ bool needs_pre_post_req = mrq->data &&
+ !(mrq->data->host_cookie & SD_EMMC_PRE_REQ_DONE);
+
++ /*
++ * The memory at the end of the controller used as bounce buffer for
++ * the dram_access_quirk only accepts 32bit read/write access,
++ * check the aligment and length of the data before starting the request.
++ */
++ if (host->dram_access_quirk && mrq->data) {
++ mrq->cmd->error = meson_mmc_validate_dram_access(mmc, mrq->data);
++ if (mrq->cmd->error) {
++ mmc_request_done(mmc, mrq);
++ return;
++ }
++ }
++
+ if (needs_pre_post_req) {
+ meson_mmc_get_transfer_mode(mmc, mrq);
+ if (!meson_mmc_desc_chain_mode(mrq->data))
+@@ -999,7 +1040,11 @@ static irqreturn_t meson_mmc_irq_thread(int irq, void *dev_id)
+ if (meson_mmc_bounce_buf_read(data)) {
+ xfer_bytes = data->blksz * data->blocks;
+ WARN_ON(xfer_bytes > host->bounce_buf_size);
+- meson_mmc_copy_buffer(host, data, xfer_bytes, false);
++ if (host->dram_access_quirk)
++ meson_mmc_copy_buffer(host, data, xfer_bytes, false);
++ else
++ sg_copy_from_buffer(data->sg, data->sg_len,
++ host->bounce_buf, xfer_bytes);
+ }
+
+ next_cmd = meson_mmc_get_next_command(cmd);
+diff --git a/drivers/mmc/host/sdhci-of-at91.c b/drivers/mmc/host/sdhci-of-at91.c
+index 5564d7b23e7cd..d1a1c548c515f 100644
+--- a/drivers/mmc/host/sdhci-of-at91.c
++++ b/drivers/mmc/host/sdhci-of-at91.c
+@@ -11,6 +11,7 @@
+ #include <linux/delay.h>
+ #include <linux/err.h>
+ #include <linux/io.h>
++#include <linux/iopoll.h>
+ #include <linux/kernel.h>
+ #include <linux/mmc/host.h>
+ #include <linux/mmc/slot-gpio.h>
+@@ -61,7 +62,6 @@ static void sdhci_at91_set_force_card_detect(struct sdhci_host *host)
+ static void sdhci_at91_set_clock(struct sdhci_host *host, unsigned int clock)
+ {
+ u16 clk;
+- unsigned long timeout;
+
+ host->mmc->actual_clock = 0;
+
+@@ -86,16 +86,11 @@ static void sdhci_at91_set_clock(struct sdhci_host *host, unsigned int clock)
+ sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
+
+ /* Wait max 20 ms */
+- timeout = 20;
+- while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL))
+- & SDHCI_CLOCK_INT_STABLE)) {
+- if (timeout == 0) {
+- pr_err("%s: Internal clock never stabilised.\n",
+- mmc_hostname(host->mmc));
+- return;
+- }
+- timeout--;
+- mdelay(1);
++ if (read_poll_timeout(sdhci_readw, clk, (clk & SDHCI_CLOCK_INT_STABLE),
++ 1000, 20000, false, host, SDHCI_CLOCK_CONTROL)) {
++ pr_err("%s: Internal clock never stabilised.\n",
++ mmc_hostname(host->mmc));
++ return;
+ }
+
+ clk |= SDHCI_CLOCK_CARD_EN;
+@@ -114,6 +109,7 @@ static void sdhci_at91_reset(struct sdhci_host *host, u8 mask)
+ {
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct sdhci_at91_priv *priv = sdhci_pltfm_priv(pltfm_host);
++ unsigned int tmp;
+
+ sdhci_reset(host, mask);
+
+@@ -126,6 +122,10 @@ static void sdhci_at91_reset(struct sdhci_host *host, u8 mask)
+
+ sdhci_writel(host, calcr | SDMMC_CALCR_ALWYSON | SDMMC_CALCR_EN,
+ SDMMC_CALCR);
++
++ if (read_poll_timeout(sdhci_readl, tmp, !(tmp & SDMMC_CALCR_EN),
++ 10, 20000, false, host, SDMMC_CALCR))
++ dev_err(mmc_dev(host->mmc), "Failed to calibrate\n");
+ }
+ }
+
+diff --git a/drivers/net/ethernet/google/gve/gve.h b/drivers/net/ethernet/google/gve/gve.h
+index 1d3188e8e3b3c..92dc18a4bcc41 100644
+--- a/drivers/net/ethernet/google/gve/gve.h
++++ b/drivers/net/ethernet/google/gve/gve.h
+@@ -780,7 +780,7 @@ struct gve_queue_page_list *gve_assign_rx_qpl(struct gve_priv *priv)
+ gve_num_tx_qpls(priv));
+
+ /* we are out of rx qpls */
+- if (id == priv->qpl_cfg.qpl_map_size)
++ if (id == gve_num_tx_qpls(priv) + gve_num_rx_qpls(priv))
+ return NULL;
+
+ set_bit(id, priv->qpl_cfg.qpl_id_map);
+diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c
+index 099a2bc5ae670..bf8a4a7c43f78 100644
+--- a/drivers/net/ethernet/google/gve/gve_main.c
++++ b/drivers/net/ethernet/google/gve/gve_main.c
+@@ -41,6 +41,7 @@ static void gve_get_stats(struct net_device *dev, struct rtnl_link_stats64 *s)
+ {
+ struct gve_priv *priv = netdev_priv(dev);
+ unsigned int start;
++ u64 packets, bytes;
+ int ring;
+
+ if (priv->rx) {
+@@ -48,10 +49,12 @@ static void gve_get_stats(struct net_device *dev, struct rtnl_link_stats64 *s)
+ do {
+ start =
+ u64_stats_fetch_begin(&priv->rx[ring].statss);
+- s->rx_packets += priv->rx[ring].rpackets;
+- s->rx_bytes += priv->rx[ring].rbytes;
++ packets = priv->rx[ring].rpackets;
++ bytes = priv->rx[ring].rbytes;
+ } while (u64_stats_fetch_retry(&priv->rx[ring].statss,
+ start));
++ s->rx_packets += packets;
++ s->rx_bytes += bytes;
+ }
+ }
+ if (priv->tx) {
+@@ -59,10 +62,12 @@ static void gve_get_stats(struct net_device *dev, struct rtnl_link_stats64 *s)
+ do {
+ start =
+ u64_stats_fetch_begin(&priv->tx[ring].statss);
+- s->tx_packets += priv->tx[ring].pkt_done;
+- s->tx_bytes += priv->tx[ring].bytes_done;
++ packets = priv->tx[ring].pkt_done;
++ bytes = priv->tx[ring].bytes_done;
+ } while (u64_stats_fetch_retry(&priv->tx[ring].statss,
+ start));
++ s->tx_packets += packets;
++ s->tx_bytes += bytes;
+ }
+ }
+ }
+@@ -82,6 +87,9 @@ static int gve_alloc_counter_array(struct gve_priv *priv)
+
+ static void gve_free_counter_array(struct gve_priv *priv)
+ {
++ if (!priv->counter_array)
++ return;
++
+ dma_free_coherent(&priv->pdev->dev,
+ priv->num_event_counters *
+ sizeof(*priv->counter_array),
+@@ -142,6 +150,9 @@ static int gve_alloc_stats_report(struct gve_priv *priv)
+
+ static void gve_free_stats_report(struct gve_priv *priv)
+ {
++ if (!priv->stats_report)
++ return;
++
+ del_timer_sync(&priv->stats_report_timer);
+ dma_free_coherent(&priv->pdev->dev, priv->stats_report_len,
+ priv->stats_report, priv->stats_report_bus);
+@@ -370,18 +381,19 @@ static void gve_free_notify_blocks(struct gve_priv *priv)
+ {
+ int i;
+
+- if (priv->msix_vectors) {
+- /* Free the irqs */
+- for (i = 0; i < priv->num_ntfy_blks; i++) {
+- struct gve_notify_block *block = &priv->ntfy_blocks[i];
+- int msix_idx = i;
++ if (!priv->msix_vectors)
++ return;
+
+- irq_set_affinity_hint(priv->msix_vectors[msix_idx].vector,
+- NULL);
+- free_irq(priv->msix_vectors[msix_idx].vector, block);
+- }
+- free_irq(priv->msix_vectors[priv->mgmt_msix_idx].vector, priv);
++ /* Free the irqs */
++ for (i = 0; i < priv->num_ntfy_blks; i++) {
++ struct gve_notify_block *block = &priv->ntfy_blocks[i];
++ int msix_idx = i;
++
++ irq_set_affinity_hint(priv->msix_vectors[msix_idx].vector,
++ NULL);
++ free_irq(priv->msix_vectors[msix_idx].vector, block);
+ }
++ free_irq(priv->msix_vectors[priv->mgmt_msix_idx].vector, priv);
+ dma_free_coherent(&priv->pdev->dev,
+ priv->num_ntfy_blks * sizeof(*priv->ntfy_blocks),
+ priv->ntfy_blocks, priv->ntfy_block_bus);
+@@ -1185,9 +1197,10 @@ static void gve_handle_reset(struct gve_priv *priv)
+
+ void gve_handle_report_stats(struct gve_priv *priv)
+ {
+- int idx, stats_idx = 0, tx_bytes;
+- unsigned int start = 0;
+ struct stats *stats = priv->stats_report->stats;
++ int idx, stats_idx = 0;
++ unsigned int start = 0;
++ u64 tx_bytes;
+
+ if (!gve_get_report_stats(priv))
+ return;
+diff --git a/drivers/net/ethernet/google/gve/gve_rx.c b/drivers/net/ethernet/google/gve/gve_rx.c
+index bb82613682502..94941d4e47449 100644
+--- a/drivers/net/ethernet/google/gve/gve_rx.c
++++ b/drivers/net/ethernet/google/gve/gve_rx.c
+@@ -104,8 +104,14 @@ static int gve_prefill_rx_pages(struct gve_rx_ring *rx)
+ if (!rx->data.page_info)
+ return -ENOMEM;
+
+- if (!rx->data.raw_addressing)
++ if (!rx->data.raw_addressing) {
+ rx->data.qpl = gve_assign_rx_qpl(priv);
++ if (!rx->data.qpl) {
++ kvfree(rx->data.page_info);
++ rx->data.page_info = NULL;
++ return -ENOMEM;
++ }
++ }
+ for (i = 0; i < slots; i++) {
+ if (!rx->data.raw_addressing) {
+ struct page *page = rx->data.qpl->pages[i];
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
+index 1d1f52756a932..5d3d6b1dae7b0 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
+@@ -4868,7 +4868,8 @@ static void i40e_clear_interrupt_scheme(struct i40e_pf *pf)
+ {
+ int i;
+
+- i40e_free_misc_vector(pf);
++ if (test_bit(__I40E_MISC_IRQ_REQUESTED, pf->state))
++ i40e_free_misc_vector(pf);
+
+ i40e_put_lump(pf->irq_pile, pf->iwarp_base_vector,
+ I40E_IWARP_IRQ_PILE_ID);
+@@ -10110,7 +10111,7 @@ static int i40e_get_capabilities(struct i40e_pf *pf,
+ if (pf->hw.aq.asq_last_status == I40E_AQ_RC_ENOMEM) {
+ /* retry with a larger buffer */
+ buf_len = data_size;
+- } else if (pf->hw.aq.asq_last_status != I40E_AQ_RC_OK) {
++ } 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),
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
+index 23762a7ef740b..cada4e0e40b48 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
+@@ -1965,7 +1965,6 @@ static void iavf_watchdog_task(struct work_struct *work)
+ }
+ adapter->aq_required = 0;
+ adapter->current_op = VIRTCHNL_OP_UNKNOWN;
+- mutex_unlock(&adapter->crit_lock);
+ queue_delayed_work(iavf_wq,
+ &adapter->watchdog_task,
+ msecs_to_jiffies(10));
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
+index 3f67efbe12fc5..dcbdf746be35c 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
+@@ -863,6 +863,7 @@ struct mlx5e_priv {
+ struct mlx5e_channel_stats channel_stats[MLX5E_MAX_NUM_CHANNELS];
+ struct mlx5e_channel_stats trap_stats;
+ struct mlx5e_ptp_stats ptp_stats;
++ u16 stats_nch;
+ u16 max_nch;
+ u8 max_opened_tc;
+ bool tx_ptp_opened;
+@@ -1156,12 +1157,6 @@ int mlx5e_ethtool_set_pauseparam(struct mlx5e_priv *priv,
+ struct ethtool_pauseparam *pauseparam);
+
+ /* mlx5e generic netdev management API */
+-static inline unsigned int
+-mlx5e_calc_max_nch(struct mlx5e_priv *priv, const struct mlx5e_profile *profile)
+-{
+- return priv->netdev->num_rx_queues / max_t(u8, profile->rq_groups, 1);
+-}
+-
+ static inline bool
+ mlx5e_tx_mpwqe_supported(struct mlx5_core_dev *mdev)
+ {
+@@ -1170,11 +1165,13 @@ mlx5e_tx_mpwqe_supported(struct mlx5_core_dev *mdev)
+ }
+
+ int mlx5e_priv_init(struct mlx5e_priv *priv,
++ const struct mlx5e_profile *profile,
+ struct net_device *netdev,
+ struct mlx5_core_dev *mdev);
+ void mlx5e_priv_cleanup(struct mlx5e_priv *priv);
+ struct net_device *
+-mlx5e_create_netdev(struct mlx5_core_dev *mdev, unsigned int txqs, unsigned int rxqs);
++mlx5e_create_netdev(struct mlx5_core_dev *mdev, const struct mlx5e_profile *profile,
++ unsigned int txqs, unsigned int rxqs);
+ int mlx5e_attach_netdev(struct mlx5e_priv *priv);
+ void mlx5e_detach_netdev(struct mlx5e_priv *priv);
+ void mlx5e_destroy_netdev(struct mlx5e_priv *priv);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/hv_vhca_stats.c b/drivers/net/ethernet/mellanox/mlx5/core/en/hv_vhca_stats.c
+index ac44bbe95c5c1..d290d7276b8d9 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/hv_vhca_stats.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/hv_vhca_stats.c
+@@ -35,7 +35,7 @@ static void mlx5e_hv_vhca_fill_stats(struct mlx5e_priv *priv, void *data,
+ {
+ int ch, i = 0;
+
+- for (ch = 0; ch < priv->max_nch; ch++) {
++ for (ch = 0; ch < priv->stats_nch; ch++) {
+ void *buf = data + i;
+
+ if (WARN_ON_ONCE(buf +
+@@ -51,7 +51,7 @@ static void mlx5e_hv_vhca_fill_stats(struct mlx5e_priv *priv, void *data,
+ static int mlx5e_hv_vhca_stats_buf_size(struct mlx5e_priv *priv)
+ {
+ return (sizeof(struct mlx5e_hv_vhca_per_ring_stats) *
+- priv->max_nch);
++ priv->stats_nch);
+ }
+
+ static void mlx5e_hv_vhca_stats_work(struct work_struct *work)
+@@ -100,7 +100,7 @@ static void mlx5e_hv_vhca_stats_control(struct mlx5_hv_vhca_agent *agent,
+ sagent = &priv->stats_agent;
+
+ block->version = MLX5_HV_VHCA_STATS_VERSION;
+- block->rings = priv->max_nch;
++ block->rings = priv->stats_nch;
+
+ if (!block->command) {
+ cancel_delayed_work_sync(&priv->stats_agent.work);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c
+index efef4adce086a..93a8fa31255d0 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c
+@@ -13,8 +13,6 @@ struct mlx5e_ptp_fs {
+ bool valid;
+ };
+
+-#define MLX5E_PTP_CHANNEL_IX 0
+-
+ struct mlx5e_ptp_params {
+ struct mlx5e_params params;
+ struct mlx5e_sq_param txq_sq_param;
+@@ -505,6 +503,7 @@ static int mlx5e_init_ptp_rq(struct mlx5e_ptp *c, struct mlx5e_params *params,
+ rq->mdev = mdev;
+ rq->hw_mtu = MLX5E_SW2HW_MTU(params, params->sw_mtu);
+ rq->stats = &c->priv->ptp_stats.rq;
++ rq->ix = MLX5E_PTP_CHANNEL_IX;
+ rq->ptp_cyc2time = mlx5_rq_ts_translator(mdev);
+ err = mlx5e_rq_set_handlers(rq, params, false);
+ if (err)
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h
+index c96668bd701cd..a71a32e00ebb9 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h
+@@ -8,6 +8,8 @@
+ #include "en_stats.h"
+ #include <linux/ptp_classify.h>
+
++#define MLX5E_PTP_CHANNEL_IX 0
++
+ struct mlx5e_ptpsq {
+ struct mlx5e_txqsq txqsq;
+ struct mlx5e_cq ts_cq;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index fa718e71db2d4..548e8e7fc956e 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -3515,7 +3515,7 @@ void mlx5e_fold_sw_stats64(struct mlx5e_priv *priv, struct rtnl_link_stats64 *s)
+ {
+ int i;
+
+- for (i = 0; i < priv->max_nch; i++) {
++ for (i = 0; i < priv->stats_nch; i++) {
+ struct mlx5e_channel_stats *channel_stats = &priv->channel_stats[i];
+ struct mlx5e_rq_stats *xskrq_stats = &channel_stats->xskrq;
+ struct mlx5e_rq_stats *rq_stats = &channel_stats->rq;
+@@ -4661,8 +4661,6 @@ void mlx5e_build_nic_params(struct mlx5e_priv *priv, struct mlx5e_xsk *xsk, u16
+ struct mlx5_core_dev *mdev = priv->mdev;
+ u8 rx_cq_period_mode;
+
+- priv->max_nch = mlx5e_calc_max_nch(priv, priv->profile);
+-
+ params->sw_mtu = mtu;
+ params->hard_mtu = MLX5E_ETH_HARD_MTU;
+ params->num_channels = min_t(unsigned int, MLX5E_MAX_NUM_CHANNELS / 2,
+@@ -5203,8 +5201,35 @@ static const struct mlx5e_profile mlx5e_nic_profile = {
+ .rx_ptp_support = true,
+ };
+
++static unsigned int
++mlx5e_calc_max_nch(struct mlx5_core_dev *mdev, struct net_device *netdev,
++ const struct mlx5e_profile *profile)
++
++{
++ unsigned int max_nch, tmp;
++
++ /* core resources */
++ max_nch = mlx5e_get_max_num_channels(mdev);
++
++ /* netdev rx queues */
++ tmp = netdev->num_rx_queues / max_t(u8, profile->rq_groups, 1);
++ max_nch = min_t(unsigned int, max_nch, tmp);
++
++ /* netdev tx queues */
++ tmp = netdev->num_tx_queues;
++ if (mlx5_qos_is_supported(mdev))
++ tmp -= mlx5e_qos_max_leaf_nodes(mdev);
++ if (MLX5_CAP_GEN(mdev, ts_cqe_to_dest_cqn))
++ tmp -= profile->max_tc;
++ tmp = tmp / profile->max_tc;
++ max_nch = min_t(unsigned int, max_nch, tmp);
++
++ return max_nch;
++}
++
+ /* mlx5e generic netdev management API (move to en_common.c) */
+ int mlx5e_priv_init(struct mlx5e_priv *priv,
++ const struct mlx5e_profile *profile,
+ struct net_device *netdev,
+ struct mlx5_core_dev *mdev)
+ {
+@@ -5212,6 +5237,8 @@ int mlx5e_priv_init(struct mlx5e_priv *priv,
+ priv->mdev = mdev;
+ priv->netdev = netdev;
+ priv->msglevel = MLX5E_MSG_LEVEL;
++ priv->max_nch = mlx5e_calc_max_nch(mdev, netdev, profile);
++ priv->stats_nch = priv->max_nch;
+ priv->max_opened_tc = 1;
+
+ if (!alloc_cpumask_var(&priv->scratchpad.cpumask, GFP_KERNEL))
+@@ -5255,7 +5282,8 @@ void mlx5e_priv_cleanup(struct mlx5e_priv *priv)
+ }
+
+ struct net_device *
+-mlx5e_create_netdev(struct mlx5_core_dev *mdev, unsigned int txqs, unsigned int rxqs)
++mlx5e_create_netdev(struct mlx5_core_dev *mdev, const struct mlx5e_profile *profile,
++ unsigned int txqs, unsigned int rxqs)
+ {
+ struct net_device *netdev;
+ int err;
+@@ -5266,7 +5294,7 @@ mlx5e_create_netdev(struct mlx5_core_dev *mdev, unsigned int txqs, unsigned int
+ return NULL;
+ }
+
+- err = mlx5e_priv_init(netdev_priv(netdev), netdev, mdev);
++ err = mlx5e_priv_init(netdev_priv(netdev), profile, netdev, mdev);
+ if (err) {
+ mlx5_core_err(mdev, "mlx5e_priv_init failed, err=%d\n", err);
+ goto err_free_netdev;
+@@ -5308,7 +5336,7 @@ int mlx5e_attach_netdev(struct mlx5e_priv *priv)
+ clear_bit(MLX5E_STATE_DESTROYING, &priv->state);
+
+ /* max number of channels may have changed */
+- max_nch = mlx5e_get_max_num_channels(priv->mdev);
++ max_nch = mlx5e_calc_max_nch(priv->mdev, priv->netdev, profile);
+ if (priv->channels.params.num_channels > max_nch) {
+ mlx5_core_warn(priv->mdev, "MLX5E: Reducing number of channels to %d\n", max_nch);
+ /* Reducing the number of channels - RXFH has to be reset, and
+@@ -5317,6 +5345,13 @@ int mlx5e_attach_netdev(struct mlx5e_priv *priv)
+ priv->netdev->priv_flags &= ~IFF_RXFH_CONFIGURED;
+ priv->channels.params.num_channels = max_nch;
+ }
++ if (max_nch != priv->max_nch) {
++ mlx5_core_warn(priv->mdev,
++ "MLX5E: Updating max number of channels from %u to %u\n",
++ priv->max_nch, max_nch);
++ priv->max_nch = max_nch;
++ }
++
+ /* 1. Set the real number of queues in the kernel the first time.
+ * 2. Set our default XPS cpumask.
+ * 3. Build the RQT.
+@@ -5381,7 +5416,7 @@ mlx5e_netdev_attach_profile(struct net_device *netdev, struct mlx5_core_dev *mde
+ struct mlx5e_priv *priv = netdev_priv(netdev);
+ int err;
+
+- err = mlx5e_priv_init(priv, netdev, mdev);
++ err = mlx5e_priv_init(priv, new_profile, netdev, mdev);
+ if (err) {
+ mlx5_core_err(mdev, "mlx5e_priv_init failed, err=%d\n", err);
+ return err;
+@@ -5407,20 +5442,12 @@ priv_cleanup:
+ int mlx5e_netdev_change_profile(struct mlx5e_priv *priv,
+ const struct mlx5e_profile *new_profile, void *new_ppriv)
+ {
+- unsigned int new_max_nch = mlx5e_calc_max_nch(priv, new_profile);
+ const struct mlx5e_profile *orig_profile = priv->profile;
+ struct net_device *netdev = priv->netdev;
+ struct mlx5_core_dev *mdev = priv->mdev;
+ void *orig_ppriv = priv->ppriv;
+ int err, rollback_err;
+
+- /* sanity */
+- if (new_max_nch != priv->max_nch) {
+- netdev_warn(netdev, "%s: Replacing profile with different max channels\n",
+- __func__);
+- return -EINVAL;
+- }
+-
+ /* cleanup old profile */
+ mlx5e_detach_netdev(priv);
+ priv->profile->cleanup(priv);
+@@ -5516,7 +5543,7 @@ static int mlx5e_probe(struct auxiliary_device *adev,
+ nch = mlx5e_get_max_num_channels(mdev);
+ txqs = nch * profile->max_tc + ptp_txqs + qos_sqs;
+ rxqs = nch * profile->rq_groups;
+- netdev = mlx5e_create_netdev(mdev, txqs, rxqs);
++ netdev = mlx5e_create_netdev(mdev, profile, txqs, rxqs);
+ if (!netdev) {
+ mlx5_core_err(mdev, "mlx5e_create_netdev failed\n");
+ return -ENOMEM;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
+index bf94bcb6fa5d2..bec1d344481cd 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
+@@ -561,7 +561,6 @@ static void mlx5e_build_rep_params(struct net_device *netdev)
+ MLX5_CQ_PERIOD_MODE_START_FROM_CQE :
+ MLX5_CQ_PERIOD_MODE_START_FROM_EQE;
+
+- priv->max_nch = mlx5e_calc_max_nch(priv, priv->profile);
+ params = &priv->channels.params;
+
+ params->num_channels = MLX5E_REP_PARAMS_DEF_NUM_CHANNELS;
+@@ -1151,7 +1150,7 @@ mlx5e_vport_vf_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
+ nch = mlx5e_get_max_num_channels(dev);
+ txqs = nch * profile->max_tc;
+ rxqs = nch * profile->rq_groups;
+- netdev = mlx5e_create_netdev(dev, txqs, rxqs);
++ netdev = mlx5e_create_netdev(dev, profile, txqs, rxqs);
+ if (!netdev) {
+ mlx5_core_warn(dev,
+ "Failed to create representor netdev for vport %d\n",
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+index 3c65fd0bcf31c..29a6586ef28dc 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+@@ -1001,14 +1001,9 @@ static inline void mlx5e_handle_csum(struct net_device *netdev,
+ goto csum_unnecessary;
+
+ if (likely(is_last_ethertype_ip(skb, &network_depth, &proto))) {
+- u8 ipproto = get_ip_proto(skb, network_depth, proto);
+-
+- if (unlikely(ipproto == IPPROTO_SCTP))
++ if (unlikely(get_ip_proto(skb, network_depth, proto) == IPPROTO_SCTP))
+ goto csum_unnecessary;
+
+- if (unlikely(mlx5_ipsec_is_rx_flow(cqe)))
+- goto csum_none;
+-
+ stats->csum_complete++;
+ skb->ip_summed = CHECKSUM_COMPLETE;
+ skb->csum = csum_unfold((__force __sum16)cqe->check_sum);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c
+index e4f5b63951482..e1dd17019030e 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c
+@@ -34,6 +34,7 @@
+ #include "en.h"
+ #include "en_accel/tls.h"
+ #include "en_accel/en_accel.h"
++#include "en/ptp.h"
+
+ static unsigned int stats_grps_num(struct mlx5e_priv *priv)
+ {
+@@ -450,7 +451,7 @@ static MLX5E_DECLARE_STATS_GRP_OP_UPDATE_STATS(sw)
+
+ memset(s, 0, sizeof(*s));
+
+- for (i = 0; i < priv->max_nch; i++) {
++ for (i = 0; i < priv->stats_nch; i++) {
+ struct mlx5e_channel_stats *channel_stats =
+ &priv->channel_stats[i];
+ int j;
+@@ -2076,7 +2077,7 @@ static MLX5E_DECLARE_STATS_GRP_OP_FILL_STRS(ptp)
+ if (priv->rx_ptp_opened) {
+ for (i = 0; i < NUM_PTP_RQ_STATS; i++)
+ sprintf(data + (idx++) * ETH_GSTRING_LEN,
+- ptp_rq_stats_desc[i].format);
++ ptp_rq_stats_desc[i].format, MLX5E_PTP_CHANNEL_IX);
+ }
+ return idx;
+ }
+@@ -2119,7 +2120,7 @@ static MLX5E_DECLARE_STATS_GRP_OP_UPDATE_STATS(ptp) { return; }
+
+ static MLX5E_DECLARE_STATS_GRP_OP_NUM_STATS(channels)
+ {
+- int max_nch = priv->max_nch;
++ int max_nch = priv->stats_nch;
+
+ return (NUM_RQ_STATS * max_nch) +
+ (NUM_CH_STATS * max_nch) +
+@@ -2133,7 +2134,7 @@ static MLX5E_DECLARE_STATS_GRP_OP_NUM_STATS(channels)
+ static MLX5E_DECLARE_STATS_GRP_OP_FILL_STRS(channels)
+ {
+ bool is_xsk = priv->xsk.ever_used;
+- int max_nch = priv->max_nch;
++ int max_nch = priv->stats_nch;
+ int i, j, tc;
+
+ for (i = 0; i < max_nch; i++)
+@@ -2175,7 +2176,7 @@ static MLX5E_DECLARE_STATS_GRP_OP_FILL_STRS(channels)
+ static MLX5E_DECLARE_STATS_GRP_OP_FILL_STATS(channels)
+ {
+ bool is_xsk = priv->xsk.ever_used;
+- int max_nch = priv->max_nch;
++ int max_nch = priv->stats_nch;
+ int i, j, tc;
+
+ for (i = 0; i < max_nch; i++)
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/egress_lgcy.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/egress_lgcy.c
+index 0399a396d1662..60a73990017c2 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/egress_lgcy.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/egress_lgcy.c
+@@ -79,12 +79,16 @@ int esw_acl_egress_lgcy_setup(struct mlx5_eswitch *esw,
+ int dest_num = 0;
+ int err = 0;
+
+- if (MLX5_CAP_ESW_EGRESS_ACL(esw->dev, flow_counter)) {
++ if (vport->egress.legacy.drop_counter) {
++ drop_counter = vport->egress.legacy.drop_counter;
++ } else if (MLX5_CAP_ESW_EGRESS_ACL(esw->dev, flow_counter)) {
+ drop_counter = mlx5_fc_create(esw->dev, false);
+- if (IS_ERR(drop_counter))
++ if (IS_ERR(drop_counter)) {
+ esw_warn(esw->dev,
+ "vport[%d] configure egress drop rule counter err(%ld)\n",
+ vport->vport, PTR_ERR(drop_counter));
++ drop_counter = NULL;
++ }
+ vport->egress.legacy.drop_counter = drop_counter;
+ }
+
+@@ -123,7 +127,7 @@ int esw_acl_egress_lgcy_setup(struct mlx5_eswitch *esw,
+ flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP;
+
+ /* Attach egress drop flow counter */
+- if (!IS_ERR_OR_NULL(drop_counter)) {
++ if (drop_counter) {
+ flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_COUNT;
+ drop_ctr_dst.type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
+ drop_ctr_dst.counter_id = mlx5_fc_id(drop_counter);
+@@ -162,7 +166,7 @@ void esw_acl_egress_lgcy_cleanup(struct mlx5_eswitch *esw,
+ esw_acl_egress_table_destroy(vport);
+
+ clean_drop_counter:
+- if (!IS_ERR_OR_NULL(vport->egress.legacy.drop_counter)) {
++ if (vport->egress.legacy.drop_counter) {
+ mlx5_fc_destroy(esw->dev, vport->egress.legacy.drop_counter);
+ vport->egress.legacy.drop_counter = NULL;
+ }
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_lgcy.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_lgcy.c
+index f75b86abaf1cd..b1a5199260f69 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_lgcy.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_lgcy.c
+@@ -160,7 +160,9 @@ int esw_acl_ingress_lgcy_setup(struct mlx5_eswitch *esw,
+
+ esw_acl_ingress_lgcy_rules_destroy(vport);
+
+- if (MLX5_CAP_ESW_INGRESS_ACL(esw->dev, flow_counter)) {
++ if (vport->ingress.legacy.drop_counter) {
++ counter = vport->ingress.legacy.drop_counter;
++ } else if (MLX5_CAP_ESW_INGRESS_ACL(esw->dev, flow_counter)) {
+ counter = mlx5_fc_create(esw->dev, false);
+ if (IS_ERR(counter)) {
+ esw_warn(esw->dev,
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c
+index 620d638e1e8ff..1c9de6eddef86 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c
+@@ -113,7 +113,7 @@ static void mlx5i_grp_sw_update_stats(struct mlx5e_priv *priv)
+ struct mlx5e_sw_stats s = { 0 };
+ int i, j;
+
+- for (i = 0; i < priv->max_nch; i++) {
++ for (i = 0; i < priv->stats_nch; i++) {
+ struct mlx5e_channel_stats *channel_stats;
+ struct mlx5e_rq_stats *rq_stats;
+
+@@ -729,7 +729,7 @@ static int mlx5_rdma_setup_rn(struct ib_device *ibdev, u32 port_num,
+ goto destroy_ht;
+ }
+
+- err = mlx5e_priv_init(epriv, netdev, mdev);
++ err = mlx5e_priv_init(epriv, prof, netdev, mdev);
+ if (err)
+ goto destroy_mdev_resources;
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
+index ce696d5234931..c009ccc88df49 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
+@@ -448,22 +448,20 @@ static u64 find_target_cycles(struct mlx5_core_dev *mdev, s64 target_ns)
+ return cycles_now + cycles_delta;
+ }
+
+-static u64 perout_conf_internal_timer(struct mlx5_core_dev *mdev,
+- s64 sec, u32 nsec)
++static u64 perout_conf_internal_timer(struct mlx5_core_dev *mdev, s64 sec)
+ {
+- struct timespec64 ts;
++ struct timespec64 ts = {};
+ s64 target_ns;
+
+ ts.tv_sec = sec;
+- ts.tv_nsec = nsec;
+ target_ns = timespec64_to_ns(&ts);
+
+ return find_target_cycles(mdev, target_ns);
+ }
+
+-static u64 perout_conf_real_time(s64 sec, u32 nsec)
++static u64 perout_conf_real_time(s64 sec)
+ {
+- return (u64)nsec | (u64)sec << 32;
++ return (u64)sec << 32;
+ }
+
+ static int mlx5_perout_configure(struct ptp_clock_info *ptp,
+@@ -474,6 +472,7 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp,
+ container_of(ptp, struct mlx5_clock, ptp_info);
+ struct mlx5_core_dev *mdev =
+ container_of(clock, struct mlx5_core_dev, clock);
++ bool rt_mode = mlx5_real_time_mode(mdev);
+ u32 in[MLX5_ST_SZ_DW(mtpps_reg)] = {0};
+ struct timespec64 ts;
+ u32 field_select = 0;
+@@ -501,8 +500,10 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp,
+
+ if (on) {
+ bool rt_mode = mlx5_real_time_mode(mdev);
+- u32 nsec;
+- s64 sec;
++ s64 sec = rq->perout.start.sec;
++
++ if (rq->perout.start.nsec)
++ return -EINVAL;
+
+ pin_mode = MLX5_PIN_MODE_OUT;
+ pattern = MLX5_OUT_PATTERN_PERIODIC;
+@@ -513,14 +514,11 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp,
+ if ((ns >> 1) != 500000000LL)
+ return -EINVAL;
+
+- nsec = rq->perout.start.nsec;
+- sec = rq->perout.start.sec;
+-
+ if (rt_mode && sec > U32_MAX)
+ return -EINVAL;
+
+- time_stamp = rt_mode ? perout_conf_real_time(sec, nsec) :
+- perout_conf_internal_timer(mdev, sec, nsec);
++ time_stamp = rt_mode ? perout_conf_real_time(sec) :
++ perout_conf_internal_timer(mdev, sec);
+
+ field_select |= MLX5_MTPPS_FS_PIN_MODE |
+ MLX5_MTPPS_FS_PATTERN |
+@@ -538,6 +536,9 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp,
+ if (err)
+ return err;
+
++ if (rt_mode)
++ return 0;
++
+ return mlx5_set_mtppse(mdev, pin, 0,
+ MLX5_EVENT_MODE_REPETETIVE & on);
+ }
+@@ -705,20 +706,14 @@ static void ts_next_sec(struct timespec64 *ts)
+ static u64 perout_conf_next_event_timer(struct mlx5_core_dev *mdev,
+ struct mlx5_clock *clock)
+ {
+- bool rt_mode = mlx5_real_time_mode(mdev);
+ struct timespec64 ts;
+ s64 target_ns;
+
+- if (rt_mode)
+- ts = mlx5_ptp_gettimex_real_time(mdev, NULL);
+- else
+- mlx5_ptp_gettimex(&clock->ptp_info, &ts, NULL);
+-
++ mlx5_ptp_gettimex(&clock->ptp_info, &ts, NULL);
+ ts_next_sec(&ts);
+ target_ns = timespec64_to_ns(&ts);
+
+- return rt_mode ? perout_conf_real_time(ts.tv_sec, ts.tv_nsec) :
+- find_target_cycles(mdev, target_ns);
++ return find_target_cycles(mdev, target_ns);
+ }
+
+ static int mlx5_pps_event(struct notifier_block *nb,
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c
+index 3465b363fc2fe..d9345c9ebbff1 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c
+@@ -13,8 +13,8 @@
+ #endif
+
+ #define MLX5_MAX_IRQ_NAME (32)
+-/* max irq_index is 255. three chars */
+-#define MLX5_MAX_IRQ_IDX_CHARS (3)
++/* max irq_index is 2047, so four chars */
++#define MLX5_MAX_IRQ_IDX_CHARS (4)
+
+ #define MLX5_SFS_PER_CTRL_IRQ 64
+ #define MLX5_IRQ_CTRL_SF_MAX 8
+@@ -610,8 +610,9 @@ void mlx5_irq_table_destroy(struct mlx5_core_dev *dev)
+ int mlx5_irq_table_get_sfs_vec(struct mlx5_irq_table *table)
+ {
+ if (table->sf_comp_pool)
+- return table->sf_comp_pool->xa_num_irqs.max -
+- table->sf_comp_pool->xa_num_irqs.min + 1;
++ return min_t(int, num_online_cpus(),
++ table->sf_comp_pool->xa_num_irqs.max -
++ table->sf_comp_pool->xa_num_irqs.min + 1);
+ else
+ return mlx5_irq_table_get_num_comp(table);
+ }
+diff --git a/drivers/net/ethernet/mscc/ocelot_vcap.c b/drivers/net/ethernet/mscc/ocelot_vcap.c
+index 7945393a06557..99d7376a70a74 100644
+--- a/drivers/net/ethernet/mscc/ocelot_vcap.c
++++ b/drivers/net/ethernet/mscc/ocelot_vcap.c
+@@ -998,8 +998,8 @@ ocelot_vcap_block_find_filter_by_index(struct ocelot_vcap_block *block,
+ }
+
+ struct ocelot_vcap_filter *
+-ocelot_vcap_block_find_filter_by_id(struct ocelot_vcap_block *block, int cookie,
+- bool tc_offload)
++ocelot_vcap_block_find_filter_by_id(struct ocelot_vcap_block *block,
++ unsigned long cookie, bool tc_offload)
+ {
+ struct ocelot_vcap_filter *filter;
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+index ed817011a94a0..6924a6aacbd53 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+@@ -21,6 +21,7 @@
+ #include <linux/delay.h>
+ #include <linux/mfd/syscon.h>
+ #include <linux/regmap.h>
++#include <linux/pm_runtime.h>
+
+ #include "stmmac_platform.h"
+
+@@ -1528,6 +1529,8 @@ static int rk_gmac_powerup(struct rk_priv_data *bsp_priv)
+ return ret;
+ }
+
++ pm_runtime_get_sync(dev);
++
+ if (bsp_priv->integrated_phy)
+ rk_gmac_integrated_phy_powerup(bsp_priv);
+
+@@ -1539,6 +1542,8 @@ static void rk_gmac_powerdown(struct rk_priv_data *gmac)
+ if (gmac->integrated_phy)
+ rk_gmac_integrated_phy_powerdown(gmac);
+
++ pm_runtime_put_sync(&gmac->pdev->dev);
++
+ phy_power_on(gmac, false);
+ gmac_clk_enable(gmac, false);
+ }
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index 86151a817b79a..6b2a5e5769e89 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -477,6 +477,10 @@ bool stmmac_eee_init(struct stmmac_priv *priv)
+ stmmac_lpi_entry_timer_config(priv, 0);
+ del_timer_sync(&priv->eee_ctrl_timer);
+ stmmac_set_eee_timer(priv, priv->hw, 0, eee_tw_timer);
++ if (priv->hw->xpcs)
++ xpcs_config_eee(priv->hw->xpcs,
++ priv->plat->mult_fact_100ns,
++ false);
+ }
+ mutex_unlock(&priv->lock);
+ return false;
+@@ -1038,7 +1042,7 @@ static void stmmac_mac_link_down(struct phylink_config *config,
+ stmmac_mac_set(priv, priv->ioaddr, false);
+ priv->eee_active = false;
+ priv->tx_lpi_enabled = false;
+- stmmac_eee_init(priv);
++ priv->eee_enabled = stmmac_eee_init(priv);
+ stmmac_set_eee_pls(priv, priv->hw, false);
+
+ if (priv->dma_cap.fpesel)
+diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c
+index 4bd61339823ce..d4ab03a92fb59 100644
+--- a/drivers/net/pcs/pcs-xpcs.c
++++ b/drivers/net/pcs/pcs-xpcs.c
+@@ -662,6 +662,10 @@ int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns, int enable)
+ {
+ int ret;
+
++ ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL0);
++ if (ret < 0)
++ return ret;
++
+ if (enable) {
+ /* Enable EEE */
+ ret = DW_VR_MII_EEE_LTX_EN | DW_VR_MII_EEE_LRX_EN |
+@@ -669,9 +673,6 @@ int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns, int enable)
+ DW_VR_MII_EEE_TX_EN_CTRL | DW_VR_MII_EEE_RX_EN_CTRL |
+ mult_fact_100ns << DW_VR_MII_EEE_MULT_FACT_100NS_SHIFT;
+ } else {
+- ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL0);
+- if (ret < 0)
+- return ret;
+ ret &= ~(DW_VR_MII_EEE_LTX_EN | DW_VR_MII_EEE_LRX_EN |
+ DW_VR_MII_EEE_TX_QUIET_EN | DW_VR_MII_EEE_RX_QUIET_EN |
+ DW_VR_MII_EEE_TX_EN_CTRL | DW_VR_MII_EEE_RX_EN_CTRL |
+@@ -686,21 +687,28 @@ int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns, int enable)
+ if (ret < 0)
+ return ret;
+
+- ret |= DW_VR_MII_EEE_TRN_LPI;
++ if (enable)
++ ret |= DW_VR_MII_EEE_TRN_LPI;
++ else
++ ret &= ~DW_VR_MII_EEE_TRN_LPI;
++
+ return xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL1, ret);
+ }
+ EXPORT_SYMBOL_GPL(xpcs_config_eee);
+
+ static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs, unsigned int mode)
+ {
+- int ret;
++ int ret, mdio_ctrl;
+
+ /* For AN for C37 SGMII mode, the settings are :-
+- * 1) VR_MII_AN_CTRL Bit(2:1)[PCS_MODE] = 10b (SGMII AN)
+- * 2) VR_MII_AN_CTRL Bit(3) [TX_CONFIG] = 0b (MAC side SGMII)
++ * 1) VR_MII_MMD_CTRL Bit(12) [AN_ENABLE] = 0b (Disable SGMII AN in case
++ it is already enabled)
++ * 2) VR_MII_AN_CTRL Bit(2:1)[PCS_MODE] = 10b (SGMII AN)
++ * 3) VR_MII_AN_CTRL Bit(3) [TX_CONFIG] = 0b (MAC side SGMII)
+ * DW xPCS used with DW EQoS MAC is always MAC side SGMII.
+- * 3) VR_MII_DIG_CTRL1 Bit(9) [MAC_AUTO_SW] = 1b (Automatic
++ * 4) VR_MII_DIG_CTRL1 Bit(9) [MAC_AUTO_SW] = 1b (Automatic
+ * speed/duplex mode change by HW after SGMII AN complete)
++ * 5) VR_MII_MMD_CTRL Bit(12) [AN_ENABLE] = 1b (Enable SGMII AN)
+ *
+ * Note: Since it is MAC side SGMII, there is no need to set
+ * SR_MII_AN_ADV. MAC side SGMII receives AN Tx Config from
+@@ -708,6 +716,17 @@ static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs, unsigned int mode)
+ * between PHY and Link Partner. There is also no need to
+ * trigger AN restart for MAC-side SGMII.
+ */
++ mdio_ctrl = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL);
++ if (mdio_ctrl < 0)
++ return mdio_ctrl;
++
++ if (mdio_ctrl & AN_CL37_EN) {
++ ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL,
++ mdio_ctrl & ~AN_CL37_EN);
++ if (ret < 0)
++ return ret;
++ }
++
+ ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL);
+ if (ret < 0)
+ return ret;
+@@ -732,7 +751,15 @@ static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs, unsigned int mode)
+ else
+ ret &= ~DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW;
+
+- return xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1, ret);
++ ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1, ret);
++ if (ret < 0)
++ return ret;
++
++ if (phylink_autoneg_inband(mode))
++ ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL,
++ mdio_ctrl | AN_CL37_EN);
++
++ return ret;
+ }
+
+ static int xpcs_config_2500basex(struct dw_xpcs *xpcs)
+diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
+index ee8313a4ac713..6865d9319197f 100644
+--- a/drivers/net/phy/mdio_bus.c
++++ b/drivers/net/phy/mdio_bus.c
+@@ -538,6 +538,13 @@ int __mdiobus_register(struct mii_bus *bus, struct module *owner)
+ bus->dev.groups = NULL;
+ dev_set_name(&bus->dev, "%s", bus->id);
+
++ /* We need to set state to MDIOBUS_UNREGISTERED to correctly release
++ * the device in mdiobus_free()
++ *
++ * State will be updated later in this function in case of success
++ */
++ bus->state = MDIOBUS_UNREGISTERED;
++
+ err = device_register(&bus->dev);
+ if (err) {
+ pr_err("mii_bus %s failed to register\n", bus->id);
+diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c
+index 34e90216bd2cb..ab77a9f439ef9 100644
+--- a/drivers/net/phy/sfp.c
++++ b/drivers/net/phy/sfp.c
+@@ -134,7 +134,7 @@ static const char * const sm_state_strings[] = {
+ [SFP_S_LINK_UP] = "link_up",
+ [SFP_S_TX_FAULT] = "tx_fault",
+ [SFP_S_REINIT] = "reinit",
+- [SFP_S_TX_DISABLE] = "rx_disable",
++ [SFP_S_TX_DISABLE] = "tx_disable",
+ };
+
+ static const char *sm_state_to_str(unsigned short sm_state)
+diff --git a/drivers/net/wireless/ath/ath5k/Kconfig b/drivers/net/wireless/ath/ath5k/Kconfig
+index f35cd8de228e4..6914b37bb0fbc 100644
+--- a/drivers/net/wireless/ath/ath5k/Kconfig
++++ b/drivers/net/wireless/ath/ath5k/Kconfig
+@@ -3,9 +3,7 @@ config ATH5K
+ tristate "Atheros 5xxx wireless cards support"
+ depends on (PCI || ATH25) && MAC80211
+ select ATH_COMMON
+- select MAC80211_LEDS
+- select LEDS_CLASS
+- select NEW_LEDS
++ select MAC80211_LEDS if LEDS_CLASS=y || LEDS_CLASS=MAC80211
+ select ATH5K_AHB if ATH25
+ select ATH5K_PCI if !ATH25
+ help
+diff --git a/drivers/net/wireless/ath/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c
+index 6a2a168567630..33e9928af3635 100644
+--- a/drivers/net/wireless/ath/ath5k/led.c
++++ b/drivers/net/wireless/ath/ath5k/led.c
+@@ -89,7 +89,8 @@ static const struct pci_device_id ath5k_led_devices[] = {
+
+ void ath5k_led_enable(struct ath5k_hw *ah)
+ {
+- if (test_bit(ATH_STAT_LEDSOFT, ah->status)) {
++ if (IS_ENABLED(CONFIG_MAC80211_LEDS) &&
++ test_bit(ATH_STAT_LEDSOFT, ah->status)) {
+ ath5k_hw_set_gpio_output(ah, ah->led_pin);
+ ath5k_led_off(ah);
+ }
+@@ -104,7 +105,8 @@ static void ath5k_led_on(struct ath5k_hw *ah)
+
+ void ath5k_led_off(struct ath5k_hw *ah)
+ {
+- if (!test_bit(ATH_STAT_LEDSOFT, ah->status))
++ if (!IS_ENABLED(CONFIG_MAC80211_LEDS) ||
++ !test_bit(ATH_STAT_LEDSOFT, ah->status))
+ return;
+ ath5k_hw_set_gpio(ah, ah->led_pin, !ah->led_on);
+ }
+@@ -146,7 +148,7 @@ ath5k_register_led(struct ath5k_hw *ah, struct ath5k_led *led,
+ static void
+ ath5k_unregister_led(struct ath5k_led *led)
+ {
+- if (!led->ah)
++ if (!IS_ENABLED(CONFIG_MAC80211_LEDS) || !led->ah)
+ return;
+ led_classdev_unregister(&led->led_dev);
+ ath5k_led_off(led->ah);
+@@ -169,7 +171,7 @@ int ath5k_init_leds(struct ath5k_hw *ah)
+ char name[ATH5K_LED_MAX_NAME_LEN + 1];
+ const struct pci_device_id *match;
+
+- if (!ah->pdev)
++ if (!IS_ENABLED(CONFIG_MAC80211_LEDS) || !ah->pdev)
+ return 0;
+
+ #ifdef CONFIG_ATH5K_AHB
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
+index 24b658a3098aa..3ae727bc4e944 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
+@@ -652,12 +652,13 @@ static bool __iwl_mvm_remove_time_event(struct iwl_mvm *mvm,
+ u32 *uid)
+ {
+ u32 id;
+- struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif);
++ struct iwl_mvm_vif *mvmvif;
+ enum nl80211_iftype iftype;
+
+ if (!te_data->vif)
+ return false;
+
++ mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif);
+ iftype = te_data->vif->type;
+
+ /*
+diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+index 6f49950a5f6d1..be3ad42813532 100644
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+@@ -547,6 +547,8 @@ static const struct iwl_dev_info iwl_dev_info_table[] = {
+ IWL_DEV_INFO(0x43F0, 0x0074, iwl_ax201_cfg_qu_hr, NULL),
+ IWL_DEV_INFO(0x43F0, 0x0078, iwl_ax201_cfg_qu_hr, NULL),
+ IWL_DEV_INFO(0x43F0, 0x007C, 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(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(0xA0F0, 0x0070, iwl_ax201_cfg_qu_hr, NULL),
+diff --git a/drivers/of/base.c b/drivers/of/base.c
+index 48e941f99558e..073ea7cd007bb 100644
+--- a/drivers/of/base.c
++++ b/drivers/of/base.c
+@@ -36,6 +36,7 @@ LIST_HEAD(aliases_lookup);
+ struct device_node *of_root;
+ EXPORT_SYMBOL(of_root);
+ struct device_node *of_chosen;
++EXPORT_SYMBOL(of_chosen);
+ struct device_node *of_aliases;
+ struct device_node *of_stdout;
+ static const char *of_stdout_options;
+diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
+index a53bd8728d0d3..fc1a29acadbbf 100644
+--- a/drivers/pci/controller/pci-hyperv.c
++++ b/drivers/pci/controller/pci-hyperv.c
+@@ -3229,9 +3229,17 @@ static int hv_pci_bus_exit(struct hv_device *hdev, bool keep_devs)
+ return 0;
+
+ if (!keep_devs) {
+- /* Delete any children which might still exist. */
++ struct list_head removed;
++
++ /* Move all present children to the list on stack */
++ INIT_LIST_HEAD(&removed);
+ spin_lock_irqsave(&hbus->device_list_lock, flags);
+- list_for_each_entry_safe(hpdev, tmp, &hbus->children, list_entry) {
++ list_for_each_entry_safe(hpdev, tmp, &hbus->children, list_entry)
++ list_move_tail(&hpdev->list_entry, &removed);
++ spin_unlock_irqrestore(&hbus->device_list_lock, flags);
++
++ /* Remove all children in the list */
++ list_for_each_entry_safe(hpdev, tmp, &removed, list_entry) {
+ list_del(&hpdev->list_entry);
+ if (hpdev->pci_slot)
+ pci_destroy_slot(hpdev->pci_slot);
+@@ -3239,7 +3247,6 @@ static int hv_pci_bus_exit(struct hv_device *hdev, bool keep_devs)
+ put_pcichild(hpdev);
+ put_pcichild(hpdev);
+ }
+- spin_unlock_irqrestore(&hbus->device_list_lock, flags);
+ }
+
+ ret = hv_send_resources_released(hdev);
+diff --git a/drivers/ptp/ptp_pch.c b/drivers/ptp/ptp_pch.c
+index a17e8cc642c5f..8070f3fd98f01 100644
+--- a/drivers/ptp/ptp_pch.c
++++ b/drivers/ptp/ptp_pch.c
+@@ -644,6 +644,7 @@ static const struct pci_device_id pch_ieee1588_pcidev_id[] = {
+ },
+ {0}
+ };
++MODULE_DEVICE_TABLE(pci, pch_ieee1588_pcidev_id);
+
+ static SIMPLE_DEV_PM_OPS(pch_pm_ops, pch_suspend, pch_resume);
+
+diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
+index 4683c183e9d41..5bc91d34df634 100644
+--- a/drivers/scsi/libiscsi.c
++++ b/drivers/scsi/libiscsi.c
+@@ -2281,11 +2281,6 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
+ return FAILED;
+ }
+
+- conn = session->leadconn;
+- iscsi_get_conn(conn->cls_conn);
+- conn->eh_abort_cnt++;
+- age = session->age;
+-
+ spin_lock(&session->back_lock);
+ task = (struct iscsi_task *)sc->SCp.ptr;
+ if (!task || !task->sc) {
+@@ -2293,8 +2288,16 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
+ ISCSI_DBG_EH(session, "sc completed while abort in progress\n");
+
+ spin_unlock(&session->back_lock);
+- goto success;
++ spin_unlock_bh(&session->frwd_lock);
++ mutex_unlock(&session->eh_mutex);
++ return SUCCESS;
+ }
++
++ conn = session->leadconn;
++ iscsi_get_conn(conn->cls_conn);
++ conn->eh_abort_cnt++;
++ age = session->age;
++
+ ISCSI_DBG_EH(session, "aborting [sc %p itt 0x%x]\n", sc, task->itt);
+ __iscsi_get_task(task);
+ spin_unlock(&session->back_lock);
+diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
+index a3f5af088122e..b073b514dcc48 100644
+--- a/drivers/scsi/ufs/ufshcd.c
++++ b/drivers/scsi/ufs/ufshcd.c
+@@ -6365,27 +6365,6 @@ static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba, u32 intr_status)
+ return retval;
+ }
+
+-struct ctm_info {
+- struct ufs_hba *hba;
+- unsigned long pending;
+- unsigned int ncpl;
+-};
+-
+-static bool ufshcd_compl_tm(struct request *req, void *priv, bool reserved)
+-{
+- struct ctm_info *const ci = priv;
+- struct completion *c;
+-
+- WARN_ON_ONCE(reserved);
+- if (test_bit(req->tag, &ci->pending))
+- return true;
+- ci->ncpl++;
+- c = req->end_io_data;
+- if (c)
+- complete(c);
+- return true;
+-}
+-
+ /**
+ * ufshcd_tmc_handler - handle task management function completion
+ * @hba: per adapter instance
+@@ -6396,18 +6375,24 @@ static bool ufshcd_compl_tm(struct request *req, void *priv, bool reserved)
+ */
+ static irqreturn_t ufshcd_tmc_handler(struct ufs_hba *hba)
+ {
+- unsigned long flags;
+- struct request_queue *q = hba->tmf_queue;
+- struct ctm_info ci = {
+- .hba = hba,
+- };
++ unsigned long flags, pending, issued;
++ irqreturn_t ret = IRQ_NONE;
++ int tag;
++
++ pending = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL);
+
+ spin_lock_irqsave(hba->host->host_lock, flags);
+- ci.pending = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL);
+- blk_mq_tagset_busy_iter(q->tag_set, ufshcd_compl_tm, &ci);
++ issued = hba->outstanding_tasks & ~pending;
++ for_each_set_bit(tag, &issued, hba->nutmrs) {
++ struct request *req = hba->tmf_rqs[tag];
++ struct completion *c = req->end_io_data;
++
++ complete(c);
++ ret = IRQ_HANDLED;
++ }
+ spin_unlock_irqrestore(hba->host->host_lock, flags);
+
+- return ci.ncpl ? IRQ_HANDLED : IRQ_NONE;
++ return ret;
+ }
+
+ /**
+@@ -6530,9 +6515,9 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba,
+ ufshcd_hold(hba, false);
+
+ spin_lock_irqsave(host->host_lock, flags);
+- blk_mq_start_request(req);
+
+ task_tag = req->tag;
++ hba->tmf_rqs[req->tag] = req;
+ treq->upiu_req.req_header.dword_0 |= cpu_to_be32(task_tag);
+
+ memcpy(hba->utmrdl_base_addr + task_tag, treq, sizeof(*treq));
+@@ -6576,6 +6561,7 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba,
+ }
+
+ spin_lock_irqsave(hba->host->host_lock, flags);
++ hba->tmf_rqs[req->tag] = NULL;
+ __clear_bit(task_tag, &hba->outstanding_tasks);
+ spin_unlock_irqrestore(hba->host->host_lock, flags);
+
+@@ -9568,6 +9554,12 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
+ err = PTR_ERR(hba->tmf_queue);
+ goto free_tmf_tag_set;
+ }
++ hba->tmf_rqs = devm_kcalloc(hba->dev, hba->nutmrs,
++ sizeof(*hba->tmf_rqs), GFP_KERNEL);
++ if (!hba->tmf_rqs) {
++ err = -ENOMEM;
++ goto free_tmf_queue;
++ }
+
+ /* Reset the attached device */
+ ufshcd_device_reset(hba);
+diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
+index aa95deffb873a..6069e37ec983c 100644
+--- a/drivers/scsi/ufs/ufshcd.h
++++ b/drivers/scsi/ufs/ufshcd.h
+@@ -780,6 +780,7 @@ struct ufs_hba {
+
+ struct blk_mq_tag_set tmf_tag_set;
+ struct request_queue *tmf_queue;
++ struct request **tmf_rqs;
+
+ struct uic_command *active_uic_cmd;
+ struct mutex uic_cmd_mutex;
+diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c
+index eba7f76f9d61a..6034cd8992b0e 100644
+--- a/drivers/soc/qcom/mdt_loader.c
++++ b/drivers/soc/qcom/mdt_loader.c
+@@ -98,7 +98,7 @@ void *qcom_mdt_read_metadata(const struct firmware *fw, size_t *data_len)
+ if (ehdr->e_phnum < 2)
+ return ERR_PTR(-EINVAL);
+
+- if (phdrs[0].p_type == PT_LOAD || phdrs[1].p_type == PT_LOAD)
++ if (phdrs[0].p_type == PT_LOAD)
+ return ERR_PTR(-EINVAL);
+
+ if ((phdrs[1].p_flags & QCOM_MDT_TYPE_MASK) != QCOM_MDT_TYPE_HASH)
+diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c
+index b2f049faa3dfa..a6cffd57d3c7b 100644
+--- a/drivers/soc/qcom/socinfo.c
++++ b/drivers/soc/qcom/socinfo.c
+@@ -628,7 +628,7 @@ static int qcom_socinfo_probe(struct platform_device *pdev)
+ /* Feed the soc specific unique data into entropy pool */
+ add_device_randomness(info, item_size);
+
+- platform_set_drvdata(pdev, qs->soc_dev);
++ platform_set_drvdata(pdev, qs);
+
+ return 0;
+ }
+diff --git a/drivers/soc/ti/omap_prm.c b/drivers/soc/ti/omap_prm.c
+index ea64e187854eb..f32e1cbbe8c52 100644
+--- a/drivers/soc/ti/omap_prm.c
++++ b/drivers/soc/ti/omap_prm.c
+@@ -825,25 +825,28 @@ static int omap_reset_deassert(struct reset_controller_dev *rcdev,
+ writel_relaxed(v, reset->prm->base + reset->prm->data->rstctrl);
+ spin_unlock_irqrestore(&reset->lock, flags);
+
+- if (!has_rstst)
+- goto exit;
++ /* wait for the reset bit to clear */
++ ret = readl_relaxed_poll_timeout_atomic(reset->prm->base +
++ reset->prm->data->rstctrl,
++ v, !(v & BIT(id)), 1,
++ OMAP_RESET_MAX_WAIT);
++ if (ret)
++ pr_err("%s: timedout waiting for %s:%lu\n", __func__,
++ reset->prm->data->name, id);
+
+ /* wait for the status to be set */
+- ret = readl_relaxed_poll_timeout_atomic(reset->prm->base +
++ if (has_rstst) {
++ ret = readl_relaxed_poll_timeout_atomic(reset->prm->base +
+ reset->prm->data->rstst,
+ v, v & BIT(st_bit), 1,
+ OMAP_RESET_MAX_WAIT);
+- if (ret)
+- pr_err("%s: timedout waiting for %s:%lu\n", __func__,
+- reset->prm->data->name, id);
++ if (ret)
++ pr_err("%s: timedout waiting for %s:%lu\n", __func__,
++ reset->prm->data->name, id);
++ }
+
+-exit:
+- if (reset->clkdm) {
+- /* At least dra7 iva needs a delay before clkdm idle */
+- if (has_rstst)
+- udelay(1);
++ if (reset->clkdm)
+ pdata->clkdm_allow_idle(reset->clkdm);
+- }
+
+ return ret;
+ }
+diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c
+index 8b7bc10b6e8b4..f1d100671ee6a 100644
+--- a/drivers/usb/chipidea/ci_hdrc_imx.c
++++ b/drivers/usb/chipidea/ci_hdrc_imx.c
+@@ -420,11 +420,16 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
+ data->phy = devm_usb_get_phy_by_phandle(dev, "fsl,usbphy", 0);
+ if (IS_ERR(data->phy)) {
+ ret = PTR_ERR(data->phy);
+- /* Return -EINVAL if no usbphy is available */
+- if (ret == -ENODEV)
+- data->phy = NULL;
+- else
+- goto err_clk;
++ if (ret == -ENODEV) {
++ data->phy = devm_usb_get_phy_by_phandle(dev, "phys", 0);
++ if (IS_ERR(data->phy)) {
++ ret = PTR_ERR(data->phy);
++ if (ret == -ENODEV)
++ data->phy = NULL;
++ else
++ goto err_clk;
++ }
++ }
+ }
+
+ pdata.usb_phy = data->phy;
+diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
+index 5b90d0979c607..8913c58c306ef 100644
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -340,6 +340,9 @@ static void acm_process_notification(struct acm *acm, unsigned char *buf)
+ acm->iocount.overrun++;
+ spin_unlock_irqrestore(&acm->read_lock, flags);
+
++ if (newctrl & ACM_CTRL_BRK)
++ tty_flip_buffer_push(&acm->port);
++
+ if (difference)
+ wake_up_all(&acm->wioctl);
+
+@@ -475,11 +478,16 @@ static int acm_submit_read_urbs(struct acm *acm, gfp_t mem_flags)
+
+ static void acm_process_read_urb(struct acm *acm, struct urb *urb)
+ {
++ unsigned long flags;
++
+ if (!urb->actual_length)
+ return;
+
++ spin_lock_irqsave(&acm->read_lock, flags);
+ tty_insert_flip_string(&acm->port, urb->transfer_buffer,
+ urb->actual_length);
++ spin_unlock_irqrestore(&acm->read_lock, flags);
++
+ tty_flip_buffer_push(&acm->port);
+ }
+
+diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
+index 35d5908b5478a..fdf79bcf7eb09 100644
+--- a/drivers/usb/class/cdc-wdm.c
++++ b/drivers/usb/class/cdc-wdm.c
+@@ -824,7 +824,7 @@ static struct usb_class_driver wdm_class = {
+ };
+
+ /* --- WWAN framework integration --- */
+-#ifdef CONFIG_WWAN_CORE
++#ifdef CONFIG_WWAN
+ static int wdm_wwan_port_start(struct wwan_port *port)
+ {
+ struct wdm_device *desc = wwan_port_get_drvdata(port);
+@@ -963,11 +963,11 @@ static void wdm_wwan_rx(struct wdm_device *desc, int length)
+ /* inbuf has been copied, it is safe to check for outstanding data */
+ schedule_work(&desc->service_outs_intr);
+ }
+-#else /* CONFIG_WWAN_CORE */
++#else /* CONFIG_WWAN */
+ static void wdm_wwan_init(struct wdm_device *desc) {}
+ static void wdm_wwan_deinit(struct wdm_device *desc) {}
+ static void wdm_wwan_rx(struct wdm_device *desc, int length) {}
+-#endif /* CONFIG_WWAN_CORE */
++#endif /* CONFIG_WWAN */
+
+ /* --- error handling --- */
+ static void wdm_rxwork(struct work_struct *work)
+diff --git a/drivers/usb/common/Kconfig b/drivers/usb/common/Kconfig
+index 5e8a04e3dd3c8..b856622431a73 100644
+--- a/drivers/usb/common/Kconfig
++++ b/drivers/usb/common/Kconfig
+@@ -6,8 +6,7 @@ config USB_COMMON
+
+ config USB_LED_TRIG
+ bool "USB LED Triggers"
+- depends on LEDS_CLASS && LEDS_TRIGGERS
+- select USB_COMMON
++ depends on LEDS_CLASS && USB_COMMON && LEDS_TRIGGERS
+ help
+ This option adds LED triggers for USB host and/or gadget activity.
+
+diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c
+index 37c94031af1ed..53cb6b2637a09 100644
+--- a/drivers/usb/gadget/function/f_uac2.c
++++ b/drivers/usb/gadget/function/f_uac2.c
+@@ -593,11 +593,17 @@ static int set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts,
+ ssize = uac2_opts->c_ssize;
+ }
+
+- if (!is_playback && (uac2_opts->c_sync == USB_ENDPOINT_SYNC_ASYNC))
++ if (!is_playback && (uac2_opts->c_sync == USB_ENDPOINT_SYNC_ASYNC)) {
++ // Win10 requires max packet size + 1 frame
+ srate = srate * (1000 + uac2_opts->fb_max) / 1000;
+-
+- max_size_bw = num_channels(chmask) * ssize *
+- DIV_ROUND_UP(srate, factor / (1 << (ep_desc->bInterval - 1)));
++ // updated srate is always bigger, therefore DIV_ROUND_UP always yields +1
++ max_size_bw = num_channels(chmask) * ssize *
++ (DIV_ROUND_UP(srate, factor / (1 << (ep_desc->bInterval - 1))));
++ } else {
++ // adding 1 frame provision for Win10
++ max_size_bw = num_channels(chmask) * ssize *
++ (DIV_ROUND_UP(srate, factor / (1 << (ep_desc->bInterval - 1))) + 1);
++ }
+ ep_desc->wMaxPacketSize = cpu_to_le16(min_t(u16, max_size_bw,
+ max_size_ep));
+
+diff --git a/drivers/usb/typec/tcpm/tcpci.c b/drivers/usb/typec/tcpm/tcpci.c
+index 9858716698dfe..c15eec9cc460a 100644
+--- a/drivers/usb/typec/tcpm/tcpci.c
++++ b/drivers/usb/typec/tcpm/tcpci.c
+@@ -696,7 +696,7 @@ irqreturn_t tcpci_irq(struct tcpci *tcpci)
+ tcpm_pd_receive(tcpci->port, &msg);
+ }
+
+- if (status & TCPC_ALERT_EXTENDED_STATUS) {
++ if (tcpci->data->vbus_vsafe0v && (status & TCPC_ALERT_EXTENDED_STATUS)) {
+ ret = regmap_read(tcpci->regmap, TCPC_EXTENDED_STATUS, &raw);
+ if (!ret && (raw & TCPC_EXTENDED_STATUS_VSAFE0V))
+ tcpm_vbus_change(tcpci->port);
+diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c
+index 5d05de6665974..686b9245d6d67 100644
+--- a/drivers/usb/typec/tcpm/tcpm.c
++++ b/drivers/usb/typec/tcpm/tcpm.c
+@@ -4846,6 +4846,7 @@ static void _tcpm_cc_change(struct tcpm_port *port, enum typec_cc_status cc1,
+ tcpm_set_state(port, SRC_ATTACH_WAIT, 0);
+ break;
+ case SRC_ATTACHED:
++ case SRC_STARTUP:
+ case SRC_SEND_CAPABILITIES:
+ case SRC_READY:
+ if (tcpm_port_is_disconnected(port) ||
+diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c
+index 21b3ae25c76d2..ea4cc0a6e40cc 100644
+--- a/drivers/usb/typec/tipd/core.c
++++ b/drivers/usb/typec/tipd/core.c
+@@ -625,10 +625,6 @@ static int tps6598x_probe(struct i2c_client *client)
+ if (ret < 0)
+ return ret;
+
+- fwnode = device_get_named_child_node(&client->dev, "connector");
+- if (!fwnode)
+- return -ENODEV;
+-
+ /*
+ * This fwnode has a "compatible" property, but is never populated as a
+ * struct device. Instead we simply parse it to read the properties.
+@@ -636,7 +632,9 @@ static int tps6598x_probe(struct i2c_client *client)
+ * with existing DT files, we work around this by deleting any
+ * fwnode_links to/from this fwnode.
+ */
+- fw_devlink_purge_absent_suppliers(fwnode);
++ fwnode = device_get_named_child_node(&client->dev, "connector");
++ if (fwnode)
++ fw_devlink_purge_absent_suppliers(fwnode);
+
+ tps->role_sw = fwnode_usb_role_switch_get(fwnode);
+ if (IS_ERR(tps->role_sw)) {
+diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
+index d33c5cd684c0b..f71668367caf1 100644
+--- a/drivers/video/fbdev/Kconfig
++++ b/drivers/video/fbdev/Kconfig
+@@ -2191,8 +2191,9 @@ config FB_HYPERV
+ This framebuffer driver supports Microsoft Hyper-V Synthetic Video.
+
+ config FB_SIMPLE
+- bool "Simple framebuffer support"
+- depends on (FB = y) && !DRM_SIMPLEDRM
++ tristate "Simple framebuffer support"
++ depends on FB
++ depends on !DRM_SIMPLEDRM
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+diff --git a/drivers/video/fbdev/gbefb.c b/drivers/video/fbdev/gbefb.c
+index c5b99a4861e87..6b4d5a7f3e152 100644
+--- a/drivers/video/fbdev/gbefb.c
++++ b/drivers/video/fbdev/gbefb.c
+@@ -1267,7 +1267,7 @@ static struct platform_device *gbefb_device;
+ static int __init gbefb_init(void)
+ {
+ int ret = platform_driver_register(&gbefb_driver);
+- if (!ret) {
++ if (IS_ENABLED(CONFIG_SGI_IP32) && !ret) {
+ gbefb_device = platform_device_alloc("gbefb", 0);
+ if (gbefb_device) {
+ ret = platform_device_add(gbefb_device);
+diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
+index 43ebfe36ac276..3a50f097ed3ed 100644
+--- a/drivers/xen/balloon.c
++++ b/drivers/xen/balloon.c
+@@ -491,12 +491,12 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp)
+ }
+
+ /*
+- * Stop waiting if either state is not BP_EAGAIN and ballooning action is
+- * needed, or if the credit has changed while state is BP_EAGAIN.
++ * Stop waiting if either state is BP_DONE and ballooning action is
++ * needed, or if the credit has changed while state is not BP_DONE.
+ */
+ static bool balloon_thread_cond(enum bp_state state, long credit)
+ {
+- if (state != BP_EAGAIN)
++ if (state == BP_DONE)
+ credit = 0;
+
+ return current_credit() != credit || kthread_should_stop();
+@@ -516,10 +516,19 @@ static int balloon_thread(void *unused)
+
+ set_freezable();
+ for (;;) {
+- if (state == BP_EAGAIN)
+- timeout = balloon_stats.schedule_delay * HZ;
+- else
++ switch (state) {
++ case BP_DONE:
++ case BP_ECANCELED:
+ timeout = 3600 * HZ;
++ break;
++ case BP_EAGAIN:
++ timeout = balloon_stats.schedule_delay * HZ;
++ break;
++ case BP_WAIT:
++ timeout = HZ;
++ break;
++ }
++
+ credit = current_credit();
+
+ wait_event_freezable_timeout(balloon_thread_wq,
+diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c
+index 720a7b7abd46d..fe8df32bb612b 100644
+--- a/drivers/xen/privcmd.c
++++ b/drivers/xen/privcmd.c
+@@ -803,11 +803,12 @@ static long privcmd_ioctl_mmap_resource(struct file *file,
+ unsigned int domid =
+ (xdata.flags & XENMEM_rsrc_acq_caller_owned) ?
+ DOMID_SELF : kdata.dom;
+- int num;
++ int num, *errs = (int *)pfns;
+
++ BUILD_BUG_ON(sizeof(*errs) > sizeof(*pfns));
+ num = xen_remap_domain_mfn_array(vma,
+ kdata.addr & PAGE_MASK,
+- pfns, kdata.num, (int *)pfns,
++ pfns, kdata.num, errs,
+ vma->vm_page_prot,
+ domid,
+ vma->vm_private_data);
+@@ -817,7 +818,7 @@ static long privcmd_ioctl_mmap_resource(struct file *file,
+ unsigned int i;
+
+ for (i = 0; i < num; i++) {
+- rc = pfns[i];
++ rc = errs[i];
+ if (rc < 0)
+ break;
+ }
+diff --git a/fs/afs/write.c b/fs/afs/write.c
+index 2dfe3b3a53d69..f24370f5c7744 100644
+--- a/fs/afs/write.c
++++ b/fs/afs/write.c
+@@ -974,8 +974,7 @@ int afs_launder_page(struct page *page)
+ iov_iter_bvec(&iter, WRITE, bv, 1, bv[0].bv_len);
+
+ trace_afs_page_dirty(vnode, tracepoint_string("launder"), page);
+- ret = afs_store_data(vnode, &iter, (loff_t)page->index * PAGE_SIZE,
+- true);
++ ret = afs_store_data(vnode, &iter, page_offset(page) + f, true);
+ }
+
+ trace_afs_page_dirty(vnode, tracepoint_string("laundered"), page);
+diff --git a/fs/netfs/read_helper.c b/fs/netfs/read_helper.c
+index 0b6cd3b8734c6..994ec22d40402 100644
+--- a/fs/netfs/read_helper.c
++++ b/fs/netfs/read_helper.c
+@@ -150,7 +150,7 @@ static void netfs_clear_unread(struct netfs_read_subrequest *subreq)
+ {
+ struct iov_iter iter;
+
+- iov_iter_xarray(&iter, WRITE, &subreq->rreq->mapping->i_pages,
++ iov_iter_xarray(&iter, READ, &subreq->rreq->mapping->i_pages,
+ subreq->start + subreq->transferred,
+ subreq->len - subreq->transferred);
+ iov_iter_zero(iov_iter_count(&iter), &iter);
+diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
+index 7abeccb975b22..cf030ebe28275 100644
+--- a/fs/nfsd/nfs4xdr.c
++++ b/fs/nfsd/nfs4xdr.c
+@@ -3544,15 +3544,18 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen,
+ goto fail;
+ cd->rd_maxcount -= entry_bytes;
+ /*
+- * RFC 3530 14.2.24 describes rd_dircount as only a "hint", so
+- * let's always let through the first entry, at least:
++ * RFC 3530 14.2.24 describes rd_dircount as only a "hint", and
++ * notes that it could be zero. If it is zero, then the server
++ * should enforce only the rd_maxcount value.
+ */
+- if (!cd->rd_dircount)
+- goto fail;
+- name_and_cookie = 4 + 4 * XDR_QUADLEN(namlen) + 8;
+- if (name_and_cookie > cd->rd_dircount && cd->cookie_offset)
+- goto fail;
+- cd->rd_dircount -= min(cd->rd_dircount, name_and_cookie);
++ if (cd->rd_dircount) {
++ name_and_cookie = 4 + 4 * XDR_QUADLEN(namlen) + 8;
++ if (name_and_cookie > cd->rd_dircount && cd->cookie_offset)
++ goto fail;
++ cd->rd_dircount -= min(cd->rd_dircount, name_and_cookie);
++ if (!cd->rd_dircount)
++ cd->rd_maxcount = 0;
++ }
+
+ cd->cookie_offset = cookie_offset;
+ skip_entry:
+diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
+index c2c3d9077dc58..09ae1a0873d05 100644
+--- a/fs/nfsd/nfsctl.c
++++ b/fs/nfsd/nfsctl.c
+@@ -1545,7 +1545,7 @@ static int __init init_nfsd(void)
+ goto out_free_all;
+ return 0;
+ out_free_all:
+- unregister_pernet_subsys(&nfsd_net_ops);
++ unregister_filesystem(&nfsd_fs_type);
+ out_free_exports:
+ remove_proc_entry("fs/nfs/exports", NULL);
+ remove_proc_entry("fs/nfs", NULL);
+diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
+index 7c1850adec288..a4ad25f1f797f 100644
+--- a/fs/overlayfs/dir.c
++++ b/fs/overlayfs/dir.c
+@@ -1215,9 +1215,13 @@ static int ovl_rename(struct user_namespace *mnt_userns, struct inode *olddir,
+ goto out_dput;
+ }
+ } else {
+- if (!d_is_negative(newdentry) &&
+- (!new_opaque || !ovl_is_whiteout(newdentry)))
+- goto out_dput;
++ if (!d_is_negative(newdentry)) {
++ if (!new_opaque || !ovl_is_whiteout(newdentry))
++ goto out_dput;
++ } else {
++ if (flags & RENAME_EXCHANGE)
++ goto out_dput;
++ }
+ }
+
+ if (olddentry == trap)
+diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c
+index d081faa55e830..c88ac571593dc 100644
+--- a/fs/overlayfs/file.c
++++ b/fs/overlayfs/file.c
+@@ -296,6 +296,12 @@ static ssize_t ovl_read_iter(struct kiocb *iocb, struct iov_iter *iter)
+ if (ret)
+ return ret;
+
++ ret = -EINVAL;
++ if (iocb->ki_flags & IOCB_DIRECT &&
++ (!real.file->f_mapping->a_ops ||
++ !real.file->f_mapping->a_ops->direct_IO))
++ goto out_fdput;
++
+ old_cred = ovl_override_creds(file_inode(file)->i_sb);
+ if (is_sync_kiocb(iocb)) {
+ ret = vfs_iter_read(real.file, iter, &iocb->ki_pos,
+@@ -320,7 +326,7 @@ static ssize_t ovl_read_iter(struct kiocb *iocb, struct iov_iter *iter)
+ out:
+ revert_creds(old_cred);
+ ovl_file_accessed(file);
+-
++out_fdput:
+ fdput(real);
+
+ return ret;
+@@ -349,6 +355,12 @@ static ssize_t ovl_write_iter(struct kiocb *iocb, struct iov_iter *iter)
+ if (ret)
+ goto out_unlock;
+
++ ret = -EINVAL;
++ if (iocb->ki_flags & IOCB_DIRECT &&
++ (!real.file->f_mapping->a_ops ||
++ !real.file->f_mapping->a_ops->direct_IO))
++ goto out_fdput;
++
+ if (!ovl_should_sync(OVL_FS(inode->i_sb)))
+ ifl &= ~(IOCB_DSYNC | IOCB_SYNC);
+
+@@ -384,6 +396,7 @@ static ssize_t ovl_write_iter(struct kiocb *iocb, struct iov_iter *iter)
+ }
+ out:
+ revert_creds(old_cred);
++out_fdput:
+ fdput(real);
+
+ out_unlock:
+diff --git a/include/net/netfilter/ipv6/nf_defrag_ipv6.h b/include/net/netfilter/ipv6/nf_defrag_ipv6.h
+index 0fd8a4159662d..ceadf8ba25a44 100644
+--- a/include/net/netfilter/ipv6/nf_defrag_ipv6.h
++++ b/include/net/netfilter/ipv6/nf_defrag_ipv6.h
+@@ -17,7 +17,6 @@ struct inet_frags_ctl;
+ struct nft_ct_frag6_pernet {
+ struct ctl_table_header *nf_frag_frags_hdr;
+ struct fqdir *fqdir;
+- unsigned int users;
+ };
+
+ #endif /* _NF_DEFRAG_IPV6_H */
+diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
+index 148f5d8ee5ab3..a16171c5fd9eb 100644
+--- a/include/net/netfilter/nf_tables.h
++++ b/include/net/netfilter/nf_tables.h
+@@ -1202,7 +1202,7 @@ struct nft_object *nft_obj_lookup(const struct net *net,
+
+ void nft_obj_notify(struct net *net, const struct nft_table *table,
+ struct nft_object *obj, u32 portid, u32 seq,
+- int event, int family, int report, gfp_t gfp);
++ int event, u16 flags, int family, int report, gfp_t gfp);
+
+ /**
+ * struct nft_object_type - stateful object type
+diff --git a/include/net/netns/netfilter.h b/include/net/netns/netfilter.h
+index 15e2b13fb0c0f..71343b969cd31 100644
+--- a/include/net/netns/netfilter.h
++++ b/include/net/netns/netfilter.h
+@@ -28,5 +28,11 @@ struct netns_nf {
+ #if IS_ENABLED(CONFIG_DECNET)
+ struct nf_hook_entries __rcu *hooks_decnet[NF_DN_NUMHOOKS];
+ #endif
++#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV4)
++ unsigned int defrag_ipv4_users;
++#endif
++#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
++ unsigned int defrag_ipv6_users;
++#endif
+ };
+ #endif
+diff --git a/include/soc/mscc/ocelot_vcap.h b/include/soc/mscc/ocelot_vcap.h
+index 25fd525aaf928..4869ebbd438d9 100644
+--- a/include/soc/mscc/ocelot_vcap.h
++++ b/include/soc/mscc/ocelot_vcap.h
+@@ -694,7 +694,7 @@ int ocelot_vcap_filter_add(struct ocelot *ocelot,
+ int ocelot_vcap_filter_del(struct ocelot *ocelot,
+ struct ocelot_vcap_filter *rule);
+ struct ocelot_vcap_filter *
+-ocelot_vcap_block_find_filter_by_id(struct ocelot_vcap_block *block, int id,
+- bool tc_offload);
++ocelot_vcap_block_find_filter_by_id(struct ocelot_vcap_block *block,
++ unsigned long cookie, bool tc_offload);
+
+ #endif /* _OCELOT_VCAP_H_ */
+diff --git a/kernel/bpf/stackmap.c b/kernel/bpf/stackmap.c
+index 6fbc2abe9c916..2553caf4f74a3 100644
+--- a/kernel/bpf/stackmap.c
++++ b/kernel/bpf/stackmap.c
+@@ -63,7 +63,8 @@ static inline int stack_map_data_size(struct bpf_map *map)
+
+ static int prealloc_elems_and_freelist(struct bpf_stack_map *smap)
+ {
+- u32 elem_size = sizeof(struct stack_map_bucket) + smap->map.value_size;
++ u64 elem_size = sizeof(struct stack_map_bucket) +
++ (u64)smap->map.value_size;
+ int err;
+
+ smap->elems = bpf_map_area_alloc(elem_size * smap->map.max_entries,
+diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
+index 8642e56059fb2..2abfbd4b8a15e 100644
+--- a/net/bridge/br_netlink.c
++++ b/net/bridge/br_netlink.c
+@@ -1657,7 +1657,8 @@ static size_t br_get_linkxstats_size(const struct net_device *dev, int attr)
+ }
+
+ return numvls * nla_total_size(sizeof(struct bridge_vlan_xstats)) +
+- nla_total_size(sizeof(struct br_mcast_stats)) +
++ nla_total_size_64bit(sizeof(struct br_mcast_stats)) +
++ (p ? nla_total_size_64bit(sizeof(p->stp_xstats)) : 0) +
+ nla_total_size(0);
+ }
+
+diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
+index 662eb1c37f47b..10e2a0e4804b4 100644
+--- a/net/core/rtnetlink.c
++++ b/net/core/rtnetlink.c
+@@ -5265,7 +5265,7 @@ nla_put_failure:
+ static size_t if_nlmsg_stats_size(const struct net_device *dev,
+ u32 filter_mask)
+ {
+- size_t size = 0;
++ size_t size = NLMSG_ALIGN(sizeof(struct if_stats_msg));
+
+ if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_64, 0))
+ size += nla_total_size_64bit(sizeof(struct rtnl_link_stats64));
+diff --git a/net/dsa/tag_dsa.c b/net/dsa/tag_dsa.c
+index a822355afc903..26c6768b6b0c5 100644
+--- a/net/dsa/tag_dsa.c
++++ b/net/dsa/tag_dsa.c
+@@ -176,7 +176,7 @@ static struct sk_buff *dsa_rcv_ll(struct sk_buff *skb, struct net_device *dev,
+ case DSA_CMD_FORWARD:
+ skb->offload_fwd_mark = 1;
+
+- trunk = !!(dsa_header[1] & 7);
++ trunk = !!(dsa_header[1] & 4);
+ break;
+
+ case DSA_CMD_TO_CPU:
+diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
+index 80aeaf9e6e16e..bfb522e513461 100644
+--- a/net/ipv4/inet_hashtables.c
++++ b/net/ipv4/inet_hashtables.c
+@@ -242,8 +242,10 @@ static inline int compute_score(struct sock *sk, struct net *net,
+
+ if (!inet_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif))
+ return -1;
++ score = sk->sk_bound_dev_if ? 2 : 1;
+
+- score = sk->sk_family == PF_INET ? 2 : 1;
++ if (sk->sk_family == PF_INET)
++ score++;
+ if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id())
+ score++;
+ }
+diff --git a/net/ipv4/netfilter/nf_defrag_ipv4.c b/net/ipv4/netfilter/nf_defrag_ipv4.c
+index 613432a36f0a7..e61ea428ea187 100644
+--- a/net/ipv4/netfilter/nf_defrag_ipv4.c
++++ b/net/ipv4/netfilter/nf_defrag_ipv4.c
+@@ -20,13 +20,8 @@
+ #endif
+ #include <net/netfilter/nf_conntrack_zones.h>
+
+-static unsigned int defrag4_pernet_id __read_mostly;
+ static DEFINE_MUTEX(defrag4_mutex);
+
+-struct defrag4_pernet {
+- unsigned int users;
+-};
+-
+ static int nf_ct_ipv4_gather_frags(struct net *net, struct sk_buff *skb,
+ u_int32_t user)
+ {
+@@ -111,19 +106,15 @@ static const struct nf_hook_ops ipv4_defrag_ops[] = {
+
+ static void __net_exit defrag4_net_exit(struct net *net)
+ {
+- struct defrag4_pernet *nf_defrag = net_generic(net, defrag4_pernet_id);
+-
+- if (nf_defrag->users) {
++ if (net->nf.defrag_ipv4_users) {
+ nf_unregister_net_hooks(net, ipv4_defrag_ops,
+ ARRAY_SIZE(ipv4_defrag_ops));
+- nf_defrag->users = 0;
++ net->nf.defrag_ipv4_users = 0;
+ }
+ }
+
+ static struct pernet_operations defrag4_net_ops = {
+ .exit = defrag4_net_exit,
+- .id = &defrag4_pernet_id,
+- .size = sizeof(struct defrag4_pernet),
+ };
+
+ static int __init nf_defrag_init(void)
+@@ -138,24 +129,23 @@ static void __exit nf_defrag_fini(void)
+
+ int nf_defrag_ipv4_enable(struct net *net)
+ {
+- struct defrag4_pernet *nf_defrag = net_generic(net, defrag4_pernet_id);
+ int err = 0;
+
+ mutex_lock(&defrag4_mutex);
+- if (nf_defrag->users == UINT_MAX) {
++ if (net->nf.defrag_ipv4_users == UINT_MAX) {
+ err = -EOVERFLOW;
+ goto out_unlock;
+ }
+
+- if (nf_defrag->users) {
+- nf_defrag->users++;
++ if (net->nf.defrag_ipv4_users) {
++ net->nf.defrag_ipv4_users++;
+ goto out_unlock;
+ }
+
+ err = nf_register_net_hooks(net, ipv4_defrag_ops,
+ ARRAY_SIZE(ipv4_defrag_ops));
+ if (err == 0)
+- nf_defrag->users = 1;
++ net->nf.defrag_ipv4_users = 1;
+
+ out_unlock:
+ mutex_unlock(&defrag4_mutex);
+@@ -165,12 +155,10 @@ EXPORT_SYMBOL_GPL(nf_defrag_ipv4_enable);
+
+ void nf_defrag_ipv4_disable(struct net *net)
+ {
+- struct defrag4_pernet *nf_defrag = net_generic(net, defrag4_pernet_id);
+-
+ mutex_lock(&defrag4_mutex);
+- if (nf_defrag->users) {
+- nf_defrag->users--;
+- if (nf_defrag->users == 0)
++ if (net->nf.defrag_ipv4_users) {
++ net->nf.defrag_ipv4_users--;
++ if (net->nf.defrag_ipv4_users == 0)
+ nf_unregister_net_hooks(net, ipv4_defrag_ops,
+ ARRAY_SIZE(ipv4_defrag_ops));
+ }
+diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
+index 915ea635b2d5a..cbc7907f79b84 100644
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -390,7 +390,8 @@ static int compute_score(struct sock *sk, struct net *net,
+ dif, sdif);
+ if (!dev_match)
+ return -1;
+- score += 4;
++ if (sk->sk_bound_dev_if)
++ score += 4;
+
+ if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id())
+ score++;
+diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
+index 55c290d556059..67c9114835c84 100644
+--- a/net/ipv6/inet6_hashtables.c
++++ b/net/ipv6/inet6_hashtables.c
+@@ -106,7 +106,7 @@ static inline int compute_score(struct sock *sk, struct net *net,
+ if (!inet_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif))
+ return -1;
+
+- score = 1;
++ score = sk->sk_bound_dev_if ? 2 : 1;
+ if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id())
+ score++;
+ }
+diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
+index a0108415275fe..5c47be29b9ee9 100644
+--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
++++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
+@@ -33,7 +33,7 @@
+
+ static const char nf_frags_cache_name[] = "nf-frags";
+
+-unsigned int nf_frag_pernet_id __read_mostly;
++static unsigned int nf_frag_pernet_id __read_mostly;
+ static struct inet_frags nf_frags;
+
+ static struct nft_ct_frag6_pernet *nf_frag_pernet(struct net *net)
+diff --git a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
+index e8a59d8bf2adf..cb4eb1d2c620b 100644
+--- a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
++++ b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
+@@ -25,8 +25,6 @@
+ #include <net/netfilter/nf_conntrack_zones.h>
+ #include <net/netfilter/ipv6/nf_defrag_ipv6.h>
+
+-extern unsigned int nf_frag_pernet_id;
+-
+ static DEFINE_MUTEX(defrag6_mutex);
+
+ static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum,
+@@ -91,12 +89,10 @@ static const struct nf_hook_ops ipv6_defrag_ops[] = {
+
+ static void __net_exit defrag6_net_exit(struct net *net)
+ {
+- struct nft_ct_frag6_pernet *nf_frag = net_generic(net, nf_frag_pernet_id);
+-
+- if (nf_frag->users) {
++ if (net->nf.defrag_ipv6_users) {
+ nf_unregister_net_hooks(net, ipv6_defrag_ops,
+ ARRAY_SIZE(ipv6_defrag_ops));
+- nf_frag->users = 0;
++ net->nf.defrag_ipv6_users = 0;
+ }
+ }
+
+@@ -134,24 +130,23 @@ static void __exit nf_defrag_fini(void)
+
+ int nf_defrag_ipv6_enable(struct net *net)
+ {
+- struct nft_ct_frag6_pernet *nf_frag = net_generic(net, nf_frag_pernet_id);
+ int err = 0;
+
+ mutex_lock(&defrag6_mutex);
+- if (nf_frag->users == UINT_MAX) {
++ if (net->nf.defrag_ipv6_users == UINT_MAX) {
+ err = -EOVERFLOW;
+ goto out_unlock;
+ }
+
+- if (nf_frag->users) {
+- nf_frag->users++;
++ if (net->nf.defrag_ipv6_users) {
++ net->nf.defrag_ipv6_users++;
+ goto out_unlock;
+ }
+
+ err = nf_register_net_hooks(net, ipv6_defrag_ops,
+ ARRAY_SIZE(ipv6_defrag_ops));
+ if (err == 0)
+- nf_frag->users = 1;
++ net->nf.defrag_ipv6_users = 1;
+
+ out_unlock:
+ mutex_unlock(&defrag6_mutex);
+@@ -161,12 +156,10 @@ EXPORT_SYMBOL_GPL(nf_defrag_ipv6_enable);
+
+ void nf_defrag_ipv6_disable(struct net *net)
+ {
+- struct nft_ct_frag6_pernet *nf_frag = net_generic(net, nf_frag_pernet_id);
+-
+ mutex_lock(&defrag6_mutex);
+- if (nf_frag->users) {
+- nf_frag->users--;
+- if (nf_frag->users == 0)
++ if (net->nf.defrag_ipv6_users) {
++ net->nf.defrag_ipv6_users--;
++ if (net->nf.defrag_ipv6_users == 0)
+ nf_unregister_net_hooks(net, ipv6_defrag_ops,
+ ARRAY_SIZE(ipv6_defrag_ops));
+ }
+diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
+index 80ae024d13c8c..ba77955d75fbd 100644
+--- a/net/ipv6/udp.c
++++ b/net/ipv6/udp.c
+@@ -133,7 +133,8 @@ static int compute_score(struct sock *sk, struct net *net,
+ dev_match = udp_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif);
+ if (!dev_match)
+ return -1;
+- score++;
++ if (sk->sk_bound_dev_if)
++ score++;
+
+ if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id())
+ score++;
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index b9546defdc280..c0851fec11d46 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -780,6 +780,7 @@ static void nf_tables_table_notify(const struct nft_ctx *ctx, int event)
+ {
+ struct nftables_pernet *nft_net;
+ struct sk_buff *skb;
++ u16 flags = 0;
+ int err;
+
+ if (!ctx->report &&
+@@ -790,8 +791,11 @@ static void nf_tables_table_notify(const struct nft_ctx *ctx, int event)
+ if (skb == NULL)
+ goto err;
+
++ if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL))
++ flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL);
++
+ err = nf_tables_fill_table_info(skb, ctx->net, ctx->portid, ctx->seq,
+- event, 0, ctx->family, ctx->table);
++ event, flags, ctx->family, ctx->table);
+ if (err < 0) {
+ kfree_skb(skb);
+ goto err;
+@@ -1563,6 +1567,7 @@ static void nf_tables_chain_notify(const struct nft_ctx *ctx, int event)
+ {
+ struct nftables_pernet *nft_net;
+ struct sk_buff *skb;
++ u16 flags = 0;
+ int err;
+
+ if (!ctx->report &&
+@@ -1573,8 +1578,11 @@ static void nf_tables_chain_notify(const struct nft_ctx *ctx, int event)
+ if (skb == NULL)
+ goto err;
+
++ if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL))
++ flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL);
++
+ err = nf_tables_fill_chain_info(skb, ctx->net, ctx->portid, ctx->seq,
+- event, 0, ctx->family, ctx->table,
++ event, flags, ctx->family, ctx->table,
+ ctx->chain);
+ if (err < 0) {
+ kfree_skb(skb);
+@@ -2866,8 +2874,7 @@ static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net,
+ u32 flags, int family,
+ const struct nft_table *table,
+ const struct nft_chain *chain,
+- const struct nft_rule *rule,
+- const struct nft_rule *prule)
++ const struct nft_rule *rule, u64 handle)
+ {
+ struct nlmsghdr *nlh;
+ const struct nft_expr *expr, *next;
+@@ -2887,9 +2894,8 @@ static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net,
+ NFTA_RULE_PAD))
+ goto nla_put_failure;
+
+- if (event != NFT_MSG_DELRULE && prule) {
+- if (nla_put_be64(skb, NFTA_RULE_POSITION,
+- cpu_to_be64(prule->handle),
++ if (event != NFT_MSG_DELRULE && handle) {
++ if (nla_put_be64(skb, NFTA_RULE_POSITION, cpu_to_be64(handle),
+ NFTA_RULE_PAD))
+ goto nla_put_failure;
+ }
+@@ -2925,7 +2931,10 @@ static void nf_tables_rule_notify(const struct nft_ctx *ctx,
+ const struct nft_rule *rule, int event)
+ {
+ struct nftables_pernet *nft_net = nft_pernet(ctx->net);
++ const struct nft_rule *prule;
+ struct sk_buff *skb;
++ u64 handle = 0;
++ u16 flags = 0;
+ int err;
+
+ if (!ctx->report &&
+@@ -2936,9 +2945,20 @@ static void nf_tables_rule_notify(const struct nft_ctx *ctx,
+ if (skb == NULL)
+ goto err;
+
++ if (event == NFT_MSG_NEWRULE &&
++ !list_is_first(&rule->list, &ctx->chain->rules) &&
++ !list_is_last(&rule->list, &ctx->chain->rules)) {
++ prule = list_prev_entry(rule, list);
++ handle = prule->handle;
++ }
++ if (ctx->flags & (NLM_F_APPEND | NLM_F_REPLACE))
++ flags |= NLM_F_APPEND;
++ if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL))
++ flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL);
++
+ err = nf_tables_fill_rule_info(skb, ctx->net, ctx->portid, ctx->seq,
+- event, 0, ctx->family, ctx->table,
+- ctx->chain, rule, NULL);
++ event, flags, ctx->family, ctx->table,
++ ctx->chain, rule, handle);
+ if (err < 0) {
+ kfree_skb(skb);
+ goto err;
+@@ -2964,6 +2984,7 @@ static int __nf_tables_dump_rules(struct sk_buff *skb,
+ struct net *net = sock_net(skb->sk);
+ const struct nft_rule *rule, *prule;
+ unsigned int s_idx = cb->args[0];
++ u64 handle;
+
+ prule = NULL;
+ list_for_each_entry_rcu(rule, &chain->rules, list) {
+@@ -2975,12 +2996,17 @@ static int __nf_tables_dump_rules(struct sk_buff *skb,
+ memset(&cb->args[1], 0,
+ sizeof(cb->args) - sizeof(cb->args[0]));
+ }
++ if (prule)
++ handle = prule->handle;
++ else
++ handle = 0;
++
+ if (nf_tables_fill_rule_info(skb, net, NETLINK_CB(cb->skb).portid,
+ cb->nlh->nlmsg_seq,
+ NFT_MSG_NEWRULE,
+ NLM_F_MULTI | NLM_F_APPEND,
+ table->family,
+- table, chain, rule, prule) < 0)
++ table, chain, rule, handle) < 0)
+ return 1;
+
+ nl_dump_check_consistent(cb, nlmsg_hdr(skb));
+@@ -3143,7 +3169,7 @@ static int nf_tables_getrule(struct sk_buff *skb, const struct nfnl_info *info,
+
+ err = nf_tables_fill_rule_info(skb2, net, NETLINK_CB(skb).portid,
+ info->nlh->nlmsg_seq, NFT_MSG_NEWRULE, 0,
+- family, table, chain, rule, NULL);
++ family, table, chain, rule, 0);
+ if (err < 0)
+ goto err_fill_rule_info;
+
+@@ -3403,17 +3429,15 @@ static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info,
+ }
+
+ if (info->nlh->nlmsg_flags & NLM_F_REPLACE) {
++ err = nft_delrule(&ctx, old_rule);
++ if (err < 0)
++ goto err_destroy_flow_rule;
++
+ trans = nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule);
+ if (trans == NULL) {
+ err = -ENOMEM;
+ goto err_destroy_flow_rule;
+ }
+- err = nft_delrule(&ctx, old_rule);
+- if (err < 0) {
+- nft_trans_destroy(trans);
+- goto err_destroy_flow_rule;
+- }
+-
+ list_add_tail_rcu(&rule->list, &old_rule->list);
+ } else {
+ trans = nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule);
+@@ -3943,8 +3967,9 @@ static void nf_tables_set_notify(const struct nft_ctx *ctx,
+ gfp_t gfp_flags)
+ {
+ struct nftables_pernet *nft_net = nft_pernet(ctx->net);
+- struct sk_buff *skb;
+ u32 portid = ctx->portid;
++ struct sk_buff *skb;
++ u16 flags = 0;
+ int err;
+
+ if (!ctx->report &&
+@@ -3955,7 +3980,10 @@ static void nf_tables_set_notify(const struct nft_ctx *ctx,
+ if (skb == NULL)
+ goto err;
+
+- err = nf_tables_fill_set(skb, ctx, set, event, 0);
++ if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL))
++ flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL);
++
++ err = nf_tables_fill_set(skb, ctx, set, event, flags);
+ if (err < 0) {
+ kfree_skb(skb);
+ goto err;
+@@ -5231,12 +5259,13 @@ static int nf_tables_getsetelem(struct sk_buff *skb,
+ static void nf_tables_setelem_notify(const struct nft_ctx *ctx,
+ const struct nft_set *set,
+ const struct nft_set_elem *elem,
+- int event, u16 flags)
++ int event)
+ {
+ struct nftables_pernet *nft_net;
+ struct net *net = ctx->net;
+ u32 portid = ctx->portid;
+ struct sk_buff *skb;
++ u16 flags = 0;
+ int err;
+
+ if (!ctx->report && !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
+@@ -5246,6 +5275,9 @@ static void nf_tables_setelem_notify(const struct nft_ctx *ctx,
+ if (skb == NULL)
+ goto err;
+
++ if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL))
++ flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL);
++
+ err = nf_tables_fill_setelem_info(skb, ctx, 0, portid, event, flags,
+ set, elem);
+ if (err < 0) {
+@@ -6921,7 +6953,7 @@ static int nf_tables_delobj(struct sk_buff *skb, const struct nfnl_info *info,
+
+ void nft_obj_notify(struct net *net, const struct nft_table *table,
+ struct nft_object *obj, u32 portid, u32 seq, int event,
+- int family, int report, gfp_t gfp)
++ u16 flags, int family, int report, gfp_t gfp)
+ {
+ struct nftables_pernet *nft_net = nft_pernet(net);
+ struct sk_buff *skb;
+@@ -6946,8 +6978,9 @@ void nft_obj_notify(struct net *net, const struct nft_table *table,
+ if (skb == NULL)
+ goto err;
+
+- err = nf_tables_fill_obj_info(skb, net, portid, seq, event, 0, family,
+- table, obj, false);
++ err = nf_tables_fill_obj_info(skb, net, portid, seq, event,
++ flags & (NLM_F_CREATE | NLM_F_EXCL),
++ family, table, obj, false);
+ if (err < 0) {
+ kfree_skb(skb);
+ goto err;
+@@ -6964,7 +6997,7 @@ static void nf_tables_obj_notify(const struct nft_ctx *ctx,
+ struct nft_object *obj, int event)
+ {
+ nft_obj_notify(ctx->net, ctx->table, obj, ctx->portid, ctx->seq, event,
+- ctx->family, ctx->report, GFP_KERNEL);
++ ctx->flags, ctx->family, ctx->report, GFP_KERNEL);
+ }
+
+ /*
+@@ -7745,6 +7778,7 @@ static void nf_tables_flowtable_notify(struct nft_ctx *ctx,
+ {
+ struct nftables_pernet *nft_net = nft_pernet(ctx->net);
+ struct sk_buff *skb;
++ u16 flags = 0;
+ int err;
+
+ if (!ctx->report &&
+@@ -7755,8 +7789,11 @@ static void nf_tables_flowtable_notify(struct nft_ctx *ctx,
+ if (skb == NULL)
+ goto err;
+
++ if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL))
++ flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL);
++
+ err = nf_tables_fill_flowtable_info(skb, ctx->net, ctx->portid,
+- ctx->seq, event, 0,
++ ctx->seq, event, flags,
+ ctx->family, flowtable, hook_list);
+ if (err < 0) {
+ kfree_skb(skb);
+@@ -8634,7 +8671,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
+ nft_setelem_activate(net, te->set, &te->elem);
+ nf_tables_setelem_notify(&trans->ctx, te->set,
+ &te->elem,
+- NFT_MSG_NEWSETELEM, 0);
++ NFT_MSG_NEWSETELEM);
+ nft_trans_destroy(trans);
+ break;
+ case NFT_MSG_DELSETELEM:
+@@ -8642,7 +8679,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
+
+ nf_tables_setelem_notify(&trans->ctx, te->set,
+ &te->elem,
+- NFT_MSG_DELSETELEM, 0);
++ NFT_MSG_DELSETELEM);
+ nft_setelem_remove(net, te->set, &te->elem);
+ if (!nft_setelem_is_catchall(te->set, &te->elem)) {
+ atomic_dec(&te->set->nelems);
+diff --git a/net/netfilter/nft_quota.c b/net/netfilter/nft_quota.c
+index 0363f533a42b8..c4d1389f7185a 100644
+--- a/net/netfilter/nft_quota.c
++++ b/net/netfilter/nft_quota.c
+@@ -60,7 +60,7 @@ static void nft_quota_obj_eval(struct nft_object *obj,
+ if (overquota &&
+ !test_and_set_bit(NFT_QUOTA_DEPLETED_BIT, &priv->flags))
+ nft_obj_notify(nft_net(pkt), obj->key.table, obj, 0, 0,
+- NFT_MSG_NEWOBJ, nft_pf(pkt), 0, GFP_ATOMIC);
++ NFT_MSG_NEWOBJ, 0, nft_pf(pkt), 0, GFP_ATOMIC);
+ }
+
+ static int nft_quota_do_init(const struct nlattr * const tb[],
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+index 24b7cf447bc55..ada47e59647a0 100644
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -594,7 +594,10 @@ static int netlink_insert(struct sock *sk, u32 portid)
+
+ /* We need to ensure that the socket is hashed and visible. */
+ smp_wmb();
+- nlk_sk(sk)->bound = portid;
++ /* Paired with lockless reads from netlink_bind(),
++ * netlink_connect() and netlink_sendmsg().
++ */
++ WRITE_ONCE(nlk_sk(sk)->bound, portid);
+
+ err:
+ release_sock(sk);
+@@ -1012,7 +1015,8 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr,
+ if (nlk->ngroups < BITS_PER_LONG)
+ groups &= (1UL << nlk->ngroups) - 1;
+
+- bound = nlk->bound;
++ /* Paired with WRITE_ONCE() in netlink_insert() */
++ bound = READ_ONCE(nlk->bound);
+ if (bound) {
+ /* Ensure nlk->portid is up-to-date. */
+ smp_rmb();
+@@ -1098,8 +1102,9 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr,
+
+ /* No need for barriers here as we return to user-space without
+ * using any of the bound attributes.
++ * Paired with WRITE_ONCE() in netlink_insert().
+ */
+- if (!nlk->bound)
++ if (!READ_ONCE(nlk->bound))
+ err = netlink_autobind(sock);
+
+ if (err == 0) {
+@@ -1888,7 +1893,8 @@ static int netlink_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
+ dst_group = nlk->dst_group;
+ }
+
+- if (!nlk->bound) {
++ /* Paired with WRITE_ONCE() in netlink_insert() */
++ if (!READ_ONCE(nlk->bound)) {
+ err = netlink_autobind(sock);
+ if (err)
+ goto out;
+diff --git a/net/sched/sch_fifo.c b/net/sched/sch_fifo.c
+index a579a4131d22d..e1040421b7979 100644
+--- a/net/sched/sch_fifo.c
++++ b/net/sched/sch_fifo.c
+@@ -233,6 +233,9 @@ int fifo_set_limit(struct Qdisc *q, unsigned int limit)
+ if (strncmp(q->ops->id + 1, "fifo", 4) != 0)
+ return 0;
+
++ if (!q->ops->change)
++ return 0;
++
+ nla = kmalloc(nla_attr_size(sizeof(struct tc_fifo_qopt)), GFP_KERNEL);
+ if (nla) {
+ nla->nla_type = RTM_NEWQDISC;
+diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c
+index 1ab2fc933a214..b9fd18d986464 100644
+--- a/net/sched/sch_taprio.c
++++ b/net/sched/sch_taprio.c
+@@ -1641,6 +1641,10 @@ static void taprio_destroy(struct Qdisc *sch)
+ list_del(&q->taprio_list);
+ spin_unlock(&taprio_list_lock);
+
++ /* Note that taprio_reset() might not be called if an error
++ * happens in qdisc_create(), after taprio_init() has been called.
++ */
++ hrtimer_cancel(&q->advance_timer);
+
+ taprio_disable_offload(dev, q, NULL);
+
+diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
+index 3d685fe328fad..9fd35a60de6ce 100644
+--- a/net/sunrpc/auth_gss/svcauth_gss.c
++++ b/net/sunrpc/auth_gss/svcauth_gss.c
+@@ -643,7 +643,7 @@ static bool gss_check_seq_num(const struct svc_rqst *rqstp, struct rsc *rsci,
+ }
+ __set_bit(seq_num % GSS_SEQ_WIN, sd->sd_win);
+ goto ok;
+- } else if (seq_num <= sd->sd_max - GSS_SEQ_WIN) {
++ } else if (seq_num + GSS_SEQ_WIN <= sd->sd_max) {
+ goto toolow;
+ }
+ if (__test_and_set_bit(seq_num % GSS_SEQ_WIN, sd->sd_win))
+diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
+index d27e017ebfbea..f1bc09e606cd1 100644
+--- a/tools/lib/bpf/libbpf.c
++++ b/tools/lib/bpf/libbpf.c
+@@ -8115,7 +8115,8 @@ int bpf_object__load_xattr(struct bpf_object_load_attr *attr)
+
+ if (obj->gen_loader) {
+ /* reset FDs */
+- btf__set_fd(obj->btf, -1);
++ if (obj->btf)
++ btf__set_fd(obj->btf, -1);
+ for (i = 0; i < obj->nr_maps; i++)
+ obj->maps[i].fd = -1;
+ if (!err)
+diff --git a/tools/lib/bpf/strset.c b/tools/lib/bpf/strset.c
+index 1fb8b49de1d62..ea655318153f2 100644
+--- a/tools/lib/bpf/strset.c
++++ b/tools/lib/bpf/strset.c
+@@ -88,6 +88,7 @@ void strset__free(struct strset *set)
+
+ hashmap__free(set->strs_hash);
+ free(set->strs_data);
++ free(set);
+ }
+
+ size_t strset__data_size(const struct strset *set)
+diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c
+index bc821056aba90..0893436cc09f8 100644
+--- a/tools/objtool/arch/x86/decode.c
++++ b/tools/objtool/arch/x86/decode.c
+@@ -684,7 +684,7 @@ static int elf_add_alternative(struct elf *elf,
+ sec = find_section_by_name(elf, ".altinstructions");
+ if (!sec) {
+ sec = elf_create_section(elf, ".altinstructions",
+- SHF_ALLOC, size, 0);
++ SHF_ALLOC, 0, 0);
+
+ if (!sec) {
+ WARN_ELF("elf_create_section");
+diff --git a/tools/objtool/special.c b/tools/objtool/special.c
+index f1428e32a5052..83d5f969bcb00 100644
+--- a/tools/objtool/special.c
++++ b/tools/objtool/special.c
+@@ -58,22 +58,11 @@ void __weak arch_handle_alternative(unsigned short feature, struct special_alt *
+ {
+ }
+
+-static bool reloc2sec_off(struct reloc *reloc, struct section **sec, unsigned long *off)
++static void reloc_to_sec_off(struct reloc *reloc, struct section **sec,
++ unsigned long *off)
+ {
+- switch (reloc->sym->type) {
+- case STT_FUNC:
+- *sec = reloc->sym->sec;
+- *off = reloc->sym->offset + reloc->addend;
+- return true;
+-
+- case STT_SECTION:
+- *sec = reloc->sym->sec;
+- *off = reloc->addend;
+- return true;
+-
+- default:
+- return false;
+- }
++ *sec = reloc->sym->sec;
++ *off = reloc->sym->offset + reloc->addend;
+ }
+
+ static int get_alt_entry(struct elf *elf, struct special_entry *entry,
+@@ -109,13 +98,8 @@ static int get_alt_entry(struct elf *elf, struct special_entry *entry,
+ WARN_FUNC("can't find orig reloc", sec, offset + entry->orig);
+ return -1;
+ }
+- if (!reloc2sec_off(orig_reloc, &alt->orig_sec, &alt->orig_off)) {
+- WARN_FUNC("don't know how to handle reloc symbol type %d: %s",
+- sec, offset + entry->orig,
+- orig_reloc->sym->type,
+- orig_reloc->sym->name);
+- return -1;
+- }
++
++ reloc_to_sec_off(orig_reloc, &alt->orig_sec, &alt->orig_off);
+
+ if (!entry->group || alt->new_len) {
+ new_reloc = find_reloc_by_dest(elf, sec, offset + entry->new);
+@@ -133,13 +117,7 @@ static int get_alt_entry(struct elf *elf, struct special_entry *entry,
+ if (arch_is_retpoline(new_reloc->sym))
+ return 1;
+
+- if (!reloc2sec_off(new_reloc, &alt->new_sec, &alt->new_off)) {
+- WARN_FUNC("don't know how to handle reloc symbol type %d: %s",
+- sec, offset + entry->new,
+- new_reloc->sym->type,
+- new_reloc->sym->name);
+- return -1;
+- }
++ reloc_to_sec_off(new_reloc, &alt->new_sec, &alt->new_off);
+
+ /* _ASM_EXTABLE_EX hack */
+ if (alt->new_off >= 0x7ffffff0)
+diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c
+index 9604446f8360b..8b536117e154f 100644
+--- a/tools/perf/pmu-events/jevents.c
++++ b/tools/perf/pmu-events/jevents.c
+@@ -1284,6 +1284,7 @@ int main(int argc, char *argv[])
+ }
+
+ free_arch_std_events();
++ free_sys_event_tables();
+ free(mapfile);
+ return 0;
+
+@@ -1305,6 +1306,7 @@ err_close_eventsfp:
+ create_empty_mapping(output_file);
+ err_out:
+ free_arch_std_events();
++ free_sys_event_tables();
+ free(mapfile);
+ return ret;
+ }