From 937da0df889e20a86356a561a879db038ee2e219 Mon Sep 17 00:00:00 2001 From: Nicolas Pereira Date: Mon, 3 Mar 2025 23:20:12 -0300 Subject: [PATCH 01/37] rockchip64-edge: add support for yy3568 --- config/boards/yy3568.csc | 13 + .../rockchip64-6.12/board-yy3568.patch | 990 ++++++++++++++++++ .../rockchip64-6.12/dt/rk3568-yy3568.dts | 718 +++++++++++++ .../rockchip64-6.14/board-yy3568.patch | 990 ++++++++++++++++++ .../rockchip64-6.14/dt/rk3568-yy3568.dts | 718 +++++++++++++ .../add_board_yy3568_defconfig.patch | 733 +++++++++++++ .../defconfig/yy3568-rk3568_defconfig | 227 ++++ .../u-boot-radxa-rk35xx/dt/rk3568-yy3568.dts | 494 +++++++++ 8 files changed, 4883 insertions(+) create mode 100755 config/boards/yy3568.csc create mode 100644 patch/kernel/archive/rockchip64-6.12/board-yy3568.patch create mode 100755 patch/kernel/archive/rockchip64-6.12/dt/rk3568-yy3568.dts create mode 100644 patch/kernel/archive/rockchip64-6.14/board-yy3568.patch create mode 100755 patch/kernel/archive/rockchip64-6.14/dt/rk3568-yy3568.dts create mode 100644 patch/u-boot/legacy/u-boot-radxa-rk35xx/board_yy3568/add_board_yy3568_defconfig.patch create mode 100644 patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/yy3568-rk3568_defconfig create mode 100644 patch/u-boot/legacy/u-boot-radxa-rk35xx/dt/rk3568-yy3568.dts diff --git a/config/boards/yy3568.csc b/config/boards/yy3568.csc new file mode 100755 index 000000000000..b3608503d047 --- /dev/null +++ b/config/boards/yy3568.csc @@ -0,0 +1,13 @@ +# Rockchip RK3568 quad core 1-8GB SoC 2x1GBe eMMC USB3 +BOARD_NAME="yy3568" +BOARDFAMILY="rk35xx" +BOARD_MAINTAINER="hqnicolas" +BOOTCONFIG="yy3568-rk3568_defconfig" +KERNEL_TARGET="current,edge,vendor" +KERNEL_TEST_TARGET="current" +FULL_DESKTOP="yes" +BOOT_LOGO="desktop" +BOOT_FDT_FILE="rockchip/rk3568-yy3568.dtb" +BOOT_SCENARIO="spl-blobs" +IMAGE_PARTITION_TABLE="gpt" +BOOTFS_TYPE="fat" \ No newline at end of file diff --git a/patch/kernel/archive/rockchip64-6.12/board-yy3568.patch b/patch/kernel/archive/rockchip64-6.12/board-yy3568.patch new file mode 100644 index 000000000000..37958454f10d --- /dev/null +++ b/patch/kernel/archive/rockchip64-6.12/board-yy3568.patch @@ -0,0 +1,990 @@ +From a796d047927ed8db448a002bf390d5dc94fc155b Mon Sep 17 00:00:00 2001 +From: From: Nicolas Pereira +Date: Sun, 8 Oct 2023 14:16:45 +0300 +Subject: [PATCH] Add YY3568 support for mainline + +--- + arch/arm/dts/rk3568-yy3568.dts | 732 ++++++++++++++++++++++++++++++ + configs/yy3568-rk3568_defconfig | 232 ++++++++++++++ + 2 files changed, 964 insertions(+) + create mode 100644 arch/arm/dts/rk3568-yy3568.dts + create mode 100644 configs/yy3568-rk3568_defconfig + +diff --git a/arch/arm64/boot/dts/rockchip/rk3568-yy3568.dts b/arch/arm64/boot/dts/rockchip/rk3568-yy3568.dts +new file mode 100644 +index 0000000000..e32c83f8fb +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3568-yy3568.dts +@@ -0,0 +1,732 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2020 Rockchip Electronics Co., Ltd. ++ * ++ */ ++/dts-v1/; ++ ++#include ++#include ++#include ++#include ++#include "rk3568.dtsi" ++ ++/ { ++ model = "Youyeetoo YY3568"; ++ compatible = "youyeetoo,yy3568", "rockchip,rk3568"; ++ ++ aliases { ++ ethernet0 = &gmac0; ++ ethernet1 = &gmac1; ++ mmc2 = &sdmmc2; ++ mmc1 = &sdmmc0; ++ mmc0 = &sdhci; ++ }; ++ ++ gpio-leds { ++ compatible = "gpio-leds"; ++ ++ led_user: led-0 { ++ gpios = <&gpio3 RK_PA4 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "heartbeat"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&led_user_en>; ++ }; ++ led_power: led-1 { ++ gpios = <&gpio2 RK_PB2 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "heartbeat"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&led_power_en>; ++ }; ++ }; ++ ++ hdmi-con { ++ compatible = "hdmi-connector"; ++ type = "a"; ++ ++ port { ++ hdmi_con_in: endpoint { ++ remote-endpoint = <&hdmi_out_con>; ++ }; ++ }; ++ }; ++ ++ rk809-sound { ++ compatible = "simple-audio-card"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&hp_det>; ++ hp-det-gpio = <&gpio3 RK_PC2 GPIO_ACTIVE_LOW>; ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,name = "Analog RK809"; ++ simple-audio-card,mclk-fs = <256>; ++ ++ simple-audio-card,cpu { ++ sound-dai = <&i2s1_8ch>; ++ }; ++ simple-audio-card,codec { ++ sound-dai = <&rk809>; ++ }; ++ }; ++ ++ vcc5v0_otg: regulator-vbus-typec { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vcc5v0_otg_en>; ++ regulator-name = "vcc5v0_otg"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc5v0_sys>; ++ }; ++ ++ /* actually fed by vcc5v0_sys, dependent ++ * on pi6c clock generator ++ */ ++ ++ vcc5v0_host: vcc5v0-host-regulator { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vcc5v0_host_en>; ++ regulator-name = "vcc5v0_host"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc5v0_sys>; ++ }; ++ ++ vcc3v3_pcie30x1: regulator-vcc3v3-pcie30x1 { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie30x1_enable_h>; ++ regulator-name = "vcc3v3_pcie30x1"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&vcc5v0_sys>; ++ }; ++ ++ vcc3v3_pi6c_05: regulator-vcc3v3-pi6c-05 { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpios = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie_enable_h>; ++ regulator-name = "vcc3v3_pcie"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&vcc5v0_sys>; ++ }; ++ ++ pcie30_avdd0v9: regulator-pcie30-avdd0v9 { ++ compatible = "regulator-fixed"; ++ regulator-name = "pcie30_avdd0v9"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <900000>; ++ vin-supply = <&vcc3v3_sys>; ++ }; ++ ++ pcie30_avdd1v8: regulator-pcie30-avdd1v8 { ++ compatible = "regulator-fixed"; ++ regulator-name = "pcie30_avdd1v8"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ vin-supply = <&vcc3v3_sys>; ++ }; ++ ++ vcc3v3_sys: regulator-vcc3v3-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc3v3_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&vcc12v_input>; ++ }; ++ ++ vcc5v0_sys: regulator-vcc5v0-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc5v0_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc12v_input>; ++ }; ++ ++ /* labeled +12v_input in schematic */ ++ vcc12v_input: regulator-vcc5v-input { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc12v_input"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <12000000>; ++ regulator-max-microvolt = <12000000>; ++ }; ++}; ++ ++&combphy1 { ++ phy-supply = <&vcc3v3_pcie30x1>; ++ status = "okay"; ++}; ++ ++&combphy0 { ++ status = "okay"; ++}; ++ ++&combphy2 { ++ status = "okay"; ++}; ++ ++&cpu0 { ++ cpu-supply = <&vdd_cpu>; ++}; ++ ++&cpu1 { ++ cpu-supply = <&vdd_cpu>; ++}; ++ ++&cpu2 { ++ cpu-supply = <&vdd_cpu>; ++}; ++ ++&cpu3 { ++ cpu-supply = <&vdd_cpu>; ++}; ++ ++&gpu { ++ mali-supply = <&vdd_gpu>; ++ status = "okay"; ++}; ++ ++&vop { ++ assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>; ++ assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>; ++ status = "okay"; ++}; ++ ++&vop_mmu { ++ status = "okay"; ++}; ++ ++&vp0 { ++ vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 { ++ reg = ; ++ remote-endpoint = <&hdmi_in_vp0>; ++ }; ++}; ++ ++&hdmi { ++ assigned-clocks = <&cru CLK_HDMI_CEC>; ++ assigned-clock-rates = <32768>; ++ avdd-0v9-supply = <&vdda0v9_image>; ++ avdd-1v8-supply = <&vcca1v8_image>; ++ status = "okay"; ++}; ++ ++&hdmi_in { ++ hdmi_in_vp0: endpoint { ++ remote-endpoint = <&vp0_out_hdmi>; ++ }; ++}; ++ ++&hdmi_out { ++ hdmi_out_con: endpoint { ++ remote-endpoint = <&hdmi_con_in>; ++ }; ++}; ++ ++&hdmi_sound { ++ status = "okay"; ++}; ++ ++&hdmi_sound { ++ status = "okay"; ++}; ++ ++&pcie2x1 { ++ pinctrl-names = "default"; ++ reset-gpios = <&gpio1 RK_PB2 GPIO_ACTIVE_HIGH>; ++ vpcie3v3-supply = <&vcc3v3_pi6c_05>; ++ status = "okay"; ++}; ++ ++&pcie30phy { ++ data-lanes = <1 2>; ++ status = "okay"; ++}; ++ ++&pcie3x2 { ++ num-lanes = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie30x2_reset_h>; ++ reset-gpios = <&gpio2 RK_PD6 GPIO_ACTIVE_HIGH>; ++ vpcie3v3-supply = <&vcc3v3_pi6c_05>; ++ status = "okay"; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ ++ vdd_cpu: regulator@1c { ++ compatible = "tcs,tcs4525"; ++ reg = <0x1c>; ++ fcs,suspend-voltage-selector = <1>; ++ regulator-name = "vdd_cpu"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <800000>; ++ regulator-max-microvolt = <1150000>; ++ regulator-ramp-delay = <2300>; ++ vin-supply = <&vcc12v_input>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ rk809: pmic@20 { ++ compatible = "rockchip,rk809"; ++ reg = <0x20>; ++ interrupt-parent = <&gpio0>; ++ interrupts = ; ++ #clock-cells = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_int>; ++ system-power-controller; ++ wakeup-source; ++ ++ vcc1-supply = <&vcc3v3_sys>; ++ vcc2-supply = <&vcc3v3_sys>; ++ vcc3-supply = <&vcc3v3_sys>; ++ vcc4-supply = <&vcc3v3_sys>; ++ vcc5-supply = <&vcc3v3_sys>; ++ vcc6-supply = <&vcc3v3_sys>; ++ vcc7-supply = <&vcc3v3_sys>; ++ vcc8-supply = <&vcc3v3_sys>; ++ vcc9-supply = <&vcc3v3_sys>; ++ ++ regulators { ++ vdd_logic: DCDC_REG1 { ++ regulator-name = "vdd_logic"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-initial-mode = <0x2>; ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <6001>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_gpu: DCDC_REG2 { ++ regulator-name = "vdd_gpu"; ++ regulator-always-on; ++ regulator-initial-mode = <0x2>; ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <6001>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_ddr: DCDC_REG3 { ++ regulator-name = "vcc_ddr"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-initial-mode = <0x2>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vdd_npu: DCDC_REG4 { ++ regulator-name = "vdd_npu"; ++ regulator-initial-mode = <0x2>; ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <6001>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_1v8: DCDC_REG5 { ++ regulator-name = "vcc_1v8"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdda0v9_image: LDO_REG1 { ++ regulator-name = "vdda0v9_image"; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <900000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdda_0v9: LDO_REG2 { ++ regulator-name = "vdda_0v9"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <900000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdda0v9_pmu: LDO_REG3 { ++ regulator-name = "vdda0v9_pmu"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <900000>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <900000>; ++ }; ++ }; ++ ++ vccio_acodec: LDO_REG4 { ++ regulator-name = "vccio_acodec"; ++ regulator-always-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vccio_sd: LDO_REG5 { ++ regulator-name = "vccio_sd"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc3v3_pmu: LDO_REG6 { ++ regulator-name = "vcc3v3_pmu"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3300000>; ++ }; ++ }; ++ ++ vcca_1v8: LDO_REG7 { ++ regulator-name = "vcca_1v8"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcca1v8_pmu: LDO_REG8 { ++ regulator-name = "vcca1v8_pmu"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcca1v8_image: LDO_REG9 { ++ regulator-name = "vcca1v8_image"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_3v3: SWITCH_REG1 { ++ regulator-name = "vcc_3v3"; ++ regulator-always-on; ++ regulator-boot-on; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc3v3_sd: SWITCH_REG2 { ++ regulator-name = "vcc3v3_sd"; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&pinctrl { ++ leds { ++ led_user_en: led_user_en { ++ rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ led_power_en: led_power_en { ++ rockchip,pins = <2 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ headphone { ++ hp_det: hp-det { ++ rockchip,pins = <3 RK_PC2 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ }; ++ ++ pmic { ++ pmic_int: pmic_int { ++ rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ pcie { ++ pcie30x1_enable_h: pcie30x1-enable-h { ++ rockchip,pins = <0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ pcie30x2_reset_h: pcie30x2-reset-h { ++ rockchip,pins = <2 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ pcie_enable_h: pcie-enable-h { ++ rockchip,pins = <0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ usb { ++ vcc5v0_host_en: vcc5v0-host-en { ++ rockchip,pins = <0 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ vcc5v0_otg_en: vcc5v0_otg_en { ++ rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++}; ++ ++&i2s1_8ch { ++ rockchip,trcm-sync-tx-only; ++ status = "okay"; ++}; ++ ++&pmu_io_domains { ++ pmuio1-supply = <&vcc3v3_pmu>; ++ pmuio2-supply = <&vcc3v3_pmu>; ++ vccio1-supply = <&vccio_acodec>; ++ vccio2-supply = <&vcc_1v8>; ++ vccio3-supply = <&vccio_sd>; ++ vccio4-supply = <&vcc_1v8>; ++ vccio5-supply = <&vcc_3v3>; ++ vccio6-supply = <&vcc_1v8>; ++ vccio7-supply = <&vcc_3v3>; ++ status = "okay"; ++}; ++ ++&saradc { ++ vref-supply = <&vcca_1v8>; ++ status = "okay"; ++}; ++ ++&sdhci { ++ bus-width = <8>; ++ max-frequency = <200000000>; ++ non-removable; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>; ++ vmmc-supply = <&vcc_3v3>; ++ vqmmc-supply = <&vcc_1v8>; ++ status = "okay"; ++}; ++ ++&tsadc { ++ rockchip,hw-tshut-mode = <1>; ++ rockchip,hw-tshut-polarity = <0>; ++ status = "okay"; ++}; ++ ++&uart2 { ++ status = "okay"; ++}; ++ ++&sdmmc0 { ++ bus-width = <4>; ++ cap-sd-highspeed; ++ cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; ++ /* Also used in pcie30x1_clkreqnm0 */ ++ disable-wp; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd>; ++ sd-uhs-sdr104; ++ vmmc-supply = <&vcc3v3_sd>; ++ vqmmc-supply = <&vccio_sd>; ++ status = "okay"; ++}; ++ ++&sdmmc2 { ++ bus-width = <4>; ++ cap-sd-highspeed; ++ cd-gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_LOW>; ++ disable-wp; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc2m0_bus4 &sdmmc2m0_clk &sdmmc2m0_cmd>; ++ sd-uhs-sdr104; ++ status = "okay"; ++}; ++ ++&mdio0 { ++ rgmii_phy0: ethernet-phy@0 { ++ compatible = "ethernet-phy-id001c.c916"; ++ reg = <0x0>; ++ reset-assert-us = <20000>; ++ reset-deassert-us = <100000>; ++ reset-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_LOW>; ++ }; ++}; ++ ++&mdio1 { ++ rgmii_phy1: ethernet-phy@0 { ++ compatible = "ethernet-phy-id001c.c916"; ++ reg = <0x0>; ++ reset-assert-us = <20000>; ++ reset-deassert-us = <100000>; ++ reset-gpios = <&gpio2 RK_PD1 GPIO_ACTIVE_LOW>; ++ }; ++}; ++ ++&gmac0 { ++ assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>; ++ assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>; ++ assigned-clock-rates = <0>, <125000000>; ++ clock_in_out = "output"; ++ phy-handle = <&rgmii_phy0>; ++ phy-mode = "rgmii"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gmac0_miim ++ &gmac0_tx_bus2 ++ &gmac0_rx_bus2 ++ &gmac0_rgmii_clk ++ &gmac0_rgmii_bus>; ++ status = "okay"; ++}; ++ ++&gmac1 { ++ assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>; ++ assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>; ++ assigned-clock-rates = <0>, <125000000>; ++ clock_in_out = "output"; ++ phy-handle = <&rgmii_phy1>; ++ phy-mode = "rgmii"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gmac1m1_miim ++ &gmac1m1_tx_bus2 ++ &gmac1m1_rx_bus2 ++ &gmac1m1_rgmii_clk ++ &gmac1m1_rgmii_bus>; ++ status = "okay"; ++}; ++ ++&usb_host0_ehci { ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ status = "okay"; ++}; ++ ++&usb_host0_xhci { ++ dr_mode = "host"; ++ extcon = <&usb2phy0>; ++ status = "okay"; ++}; ++ ++&usb_host1_ehci { ++ status = "okay"; ++}; ++ ++&usb_host1_ohci { ++ status = "okay"; ++}; ++ ++&usb_host1_xhci { ++ status = "okay"; ++}; ++ ++&usb2phy0 { ++ status = "okay"; ++}; ++ ++&usb2phy0_host { ++ phy-supply = <&vcc5v0_host>; ++ status = "okay"; ++}; ++ ++&usb2phy1 { ++ status = "okay"; ++}; ++ ++&usb2phy1_host { ++ phy-supply = <&vcc5v0_host>; ++ status = "okay"; ++}; ++ ++&usb2phy1_otg { ++ phy-supply = <&vcc5v0_host>; ++ status = "okay"; ++}; ++ ++&usb2phy1 { ++ status = "okay"; ++}; ++ ++&usb2phy1_host { ++ phy-supply = <&vcc5v0_otg>; ++ status = "okay"; ++}; ++ ++&usb2phy1_otg { ++ phy-supply = <&vcc5v0_otg>; ++ status = "okay"; ++}; +diff --git a/configs/yy3568-rk3568_defconfig b/configs/yy3568-rk3568_defconfig +new file mode 100644 +index 0000000000..23f9251bb2 +--- /dev/null ++++ b/configs/yy3568-rk3568_defconfig +@@ -0,0 +1,232 @@ ++CONFIG_ARM=y ++CONFIG_ARCH_ROCKCHIP=y ++CONFIG_SPL_LIBCOMMON_SUPPORT=y ++CONFIG_SPL_LIBGENERIC_SUPPORT=y ++CONFIG_SYS_MALLOC_F_LEN=0x80000 ++CONFIG_SPL_FIT_GENERATOR="arch/arm/mach-rockchip/make_fit_atf.sh" ++CONFIG_ROCKCHIP_RK3568=y ++CONFIG_ROCKCHIP_FIT_IMAGE=y ++CONFIG_ROCKCHIP_VENDOR_PARTITION=y ++CONFIG_ROCKCHIP_FIT_IMAGE_PACK=y ++CONFIG_ROCKCHIP_NEW_IDB=y ++CONFIG_SPL_SERIAL_SUPPORT=y ++CONFIG_SPL_DRIVERS_MISC_SUPPORT=y ++CONFIG_TARGET_EVB_RK3568=y ++CONFIG_SPL_LIBDISK_SUPPORT=y ++CONFIG_SPL_NAND_SUPPORT=y ++CONFIG_SPL_SPI_FLASH_SUPPORT=y ++CONFIG_SPL_SPI_SUPPORT=y ++CONFIG_DEFAULT_DEVICE_TREE="rk3568-yy3568" ++CONFIG_DEBUG_UART=y ++CONFIG_FIT=y ++CONFIG_FIT_IMAGE_POST_PROCESS=y ++CONFIG_FIT_HW_CRYPTO=y ++CONFIG_SPL_LOAD_FIT=y ++CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y ++CONFIG_SPL_FIT_HW_CRYPTO=y ++# CONFIG_SPL_SYS_DCACHE_OFF is not set ++CONFIG_BOOTDELAY=0 ++CONFIG_SARADC_ROCKCHIP=y ++CONFIG_SYS_CONSOLE_INFO_QUIET=y ++# CONFIG_DISPLAY_CPUINFO is not set ++CONFIG_ANDROID_BOOTLOADER=y ++CONFIG_ANDROID_AVB=y ++CONFIG_ANDROID_BOOT_IMAGE_HASH=y ++CONFIG_SPL_BOARD_INIT=y ++# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set ++# CONFIG_SPL_LEGACY_IMAGE_SUPPORT is not set ++CONFIG_SPL_SEPARATE_BSS=y ++CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION=y ++CONFIG_SPL_SHA256_SUPPORT=y ++CONFIG_SPL_CRYPTO_SUPPORT=y ++CONFIG_SPL_HASH_SUPPORT=y ++CONFIG_SPL_MMC_WRITE=y ++CONFIG_SPL_MTD_SUPPORT=y ++CONFIG_SPL_MTD_WRITE=y ++CONFIG_SPL_ATF=y ++CONFIG_SPL_ATF_NO_PLATFORM_PARAM=y ++CONFIG_SPL_AB=y ++CONFIG_FASTBOOT_BUF_ADDR=0xc00800 ++CONFIG_FASTBOOT_BUF_SIZE=0x04000000 ++CONFIG_FASTBOOT_FLASH=y ++CONFIG_FASTBOOT_FLASH_MMC_DEV=0 ++CONFIG_CMD_BOOTZ=y ++CONFIG_CMD_DTIMG=y ++# CONFIG_CMD_ELF is not set ++# CONFIG_CMD_IMI is not set ++# CONFIG_CMD_IMLS is not set ++# CONFIG_CMD_XIMG is not set ++# CONFIG_CMD_LZMADEC is not set ++# CONFIG_CMD_UNZIP is not set ++# CONFIG_CMD_FLASH is not set ++# CONFIG_CMD_FPGA is not set ++CONFIG_CMD_GPT=y ++# CONFIG_CMD_LOADB is not set ++# CONFIG_CMD_LOADS is not set ++CONFIG_CMD_BOOT_ANDROID=y ++CONFIG_CMD_BOOT_ROCKCHIP=y ++CONFIG_CMD_MMC=y ++CONFIG_CMD_MTD=y ++CONFIG_CMD_NAND=y ++CONFIG_CMD_PCI=y ++CONFIG_CMD_USB=y ++CONFIG_CMD_USB_MASS_STORAGE=y ++# CONFIG_CMD_ITEST is not set ++# CONFIG_CMD_SETEXPR is not set ++CONFIG_CMD_TFTPPUT=y ++CONFIG_CMD_TFTP_BOOTM=y ++CONFIG_CMD_TFTP_FLASH=y ++# CONFIG_CMD_MISC is not set ++# CONFIG_CMD_CHARGE_DISPLAY is not set ++CONFIG_CMD_MTD_BLK=y ++# CONFIG_SPL_DOS_PARTITION is not set ++# CONFIG_ISO_PARTITION is not set ++CONFIG_EFI_PARTITION_ENTRIES_NUMBERS=64 ++CONFIG_SPL_OF_CONTROL=y ++CONFIG_SPL_DTB_MINIMUM=y ++CONFIG_OF_LIVE=y ++CONFIG_OF_SPL_REMOVE_PROPS="" ++# CONFIG_NET_TFTP_VARS is not set ++CONFIG_REGMAP=y ++CONFIG_SPL_REGMAP=y ++CONFIG_SYSCON=y ++CONFIG_SPL_SYSCON=y ++CONFIG_CLK=y ++CONFIG_SPL_CLK=y ++CONFIG_CLK_SCMI=y ++CONFIG_DM_CRYPTO=y ++CONFIG_SPL_DM_CRYPTO=y ++CONFIG_ROCKCHIP_CRYPTO_V2=y ++CONFIG_SPL_ROCKCHIP_CRYPTO_V2=y ++CONFIG_DM_RNG=y ++CONFIG_RNG_ROCKCHIP=y ++CONFIG_SCMI_FIRMWARE=y ++CONFIG_ROCKCHIP_GPIO=y ++CONFIG_ROCKCHIP_GPIO_V2=y ++CONFIG_SYS_I2C_ROCKCHIP=y ++CONFIG_DM_KEY=y ++CONFIG_RK8XX_PWRKEY=y ++CONFIG_ADC_KEY=y ++CONFIG_MISC=y ++CONFIG_SPL_MISC=y ++CONFIG_ROCKCHIP_OTP=y ++CONFIG_SPL_ROCKCHIP_SECURE_OTP=y ++CONFIG_MMC_DW=y ++CONFIG_MMC_DW_ROCKCHIP=y ++CONFIG_MMC_SDHCI=y ++CONFIG_MMC_SDHCI_SDMA=y ++CONFIG_MMC_SDHCI_ROCKCHIP=y ++CONFIG_MTD=y ++CONFIG_MTD_BLK=y ++CONFIG_MTD_DEVICE=y ++CONFIG_NAND=y ++CONFIG_NAND_ROCKCHIP_V9=y ++CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y ++CONFIG_SYS_NAND_U_BOOT_OFFS=0x8000 ++CONFIG_SYS_NAND_U_BOOT_OFFS_REDUND=0x10000 ++CONFIG_MTD_SPI_NAND=y ++CONFIG_SPI_FLASH=y ++CONFIG_SF_DEFAULT_SPEED=20000000 ++CONFIG_SPI_FLASH_EON=y ++CONFIG_SPI_FLASH_GIGADEVICE=y ++CONFIG_SPI_FLASH_MACRONIX=y ++CONFIG_SPI_FLASH_WINBOND=y ++CONFIG_SPI_FLASH_XMC=y ++CONFIG_SPI_FLASH_MTD=y ++CONFIG_DM_ETH=y ++CONFIG_DM_ETH_PHY=y ++CONFIG_DWC_ETH_QOS=y ++CONFIG_GMAC_ROCKCHIP=y ++CONFIG_NVME=y ++CONFIG_PCI=y ++CONFIG_DM_PCI=y ++CONFIG_DM_PCI_COMPAT=y ++CONFIG_PCIE_DW_ROCKCHIP=y ++CONFIG_PHY_ROCKCHIP_INNO_USB2=y ++CONFIG_PHY_ROCKCHIP_NANENG_COMBOPHY=y ++CONFIG_PHY_ROCKCHIP_NANENG_EDP=y ++CONFIG_PHY_ROCKCHIP_SNPS_PCIE3=y ++CONFIG_PINCTRL=y ++CONFIG_SPL_PINCTRL=y ++CONFIG_DM_FUEL_GAUGE=y ++CONFIG_POWER_FG_RK817=y ++CONFIG_IO_DOMAIN=y ++CONFIG_ROCKCHIP_IO_DOMAIN=y ++CONFIG_DM_PMIC=y ++CONFIG_PMIC_RK8XX=y ++CONFIG_REGULATOR_FAN53555=y ++CONFIG_REGULATOR_PWM=y ++CONFIG_DM_REGULATOR_FIXED=y ++CONFIG_DM_REGULATOR_GPIO=y ++CONFIG_REGULATOR_RK8XX=y ++CONFIG_DM_CHARGE_DISPLAY=y ++CONFIG_CHARGE_ANIMATION=y ++CONFIG_PWM_ROCKCHIP=y ++CONFIG_RAM=y ++CONFIG_SPL_RAM=y ++CONFIG_TPL_RAM=y ++CONFIG_DM_RAMDISK=y ++CONFIG_RAMDISK_RO=y ++CONFIG_DM_DMC=y ++CONFIG_ROCKCHIP_DMC_FSP=y ++CONFIG_ROCKCHIP_SDRAM_COMMON=y ++CONFIG_ROCKCHIP_TPL_INIT_DRAM_TYPE=0 ++CONFIG_DM_RESET=y ++CONFIG_SPL_DM_RESET=y ++CONFIG_SPL_RESET_ROCKCHIP=y ++CONFIG_BAUDRATE=1500000 ++CONFIG_DEBUG_UART_BASE=0xFE660000 ++CONFIG_DEBUG_UART_CLOCK=24000000 ++CONFIG_DEBUG_UART_SHIFT=2 ++CONFIG_ROCKCHIP_SFC=y ++CONFIG_SYSRESET=y ++CONFIG_USB=y ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_XHCI_DWC3=y ++CONFIG_USB_EHCI_HCD=y ++CONFIG_USB_EHCI_GENERIC=y ++CONFIG_USB_OHCI_HCD=y ++CONFIG_USB_OHCI_GENERIC=y ++CONFIG_USB_DWC3=y ++CONFIG_USB_DWC3_GADGET=y ++CONFIG_USB_DWC3_GENERIC=y ++CONFIG_USB_STORAGE=y ++CONFIG_USB_GADGET=y ++CONFIG_USB_GADGET_MANUFACTURER="Rockchip" ++CONFIG_USB_GADGET_VENDOR_NUM=0x2207 ++CONFIG_USB_GADGET_PRODUCT_NUM=0x350a ++CONFIG_USB_GADGET_DOWNLOAD=y ++CONFIG_DM_VIDEO=y ++CONFIG_DISPLAY=y ++CONFIG_DRM_ROCKCHIP=y ++CONFIG_DRM_ROCKCHIP_DW_HDMI=y ++CONFIG_DRM_ROCKCHIP_INNO_MIPI_PHY=y ++CONFIG_DRM_ROCKCHIP_INNO_VIDEO_COMBO_PHY=y ++CONFIG_DRM_ROCKCHIP_DW_MIPI_DSI=y ++CONFIG_DRM_ROCKCHIP_ANALOGIX_DP=y ++CONFIG_DRM_ROCKCHIP_LVDS=y ++CONFIG_DRM_ROCKCHIP_RGB=y ++CONFIG_ROCKCHIP_CUBIC_LUT_SIZE=9 ++CONFIG_LCD=y ++CONFIG_USE_TINY_PRINTF=y ++CONFIG_SPL_TINY_MEMSET=y ++CONFIG_RSA=y ++CONFIG_SPL_RSA=y ++CONFIG_RSA_N_SIZE=0x200 ++CONFIG_RSA_E_SIZE=0x10 ++CONFIG_RSA_C_SIZE=0x20 ++CONFIG_XBC=y ++CONFIG_SHA512=y ++CONFIG_LZ4=y ++CONFIG_LZMA=y ++CONFIG_SPL_GZIP=y ++CONFIG_ERRNO_STR=y ++# CONFIG_EFI_LOADER is not set ++CONFIG_AVB_LIBAVB=y ++CONFIG_AVB_LIBAVB_AB=y ++CONFIG_AVB_LIBAVB_ATX=y ++CONFIG_AVB_LIBAVB_USER=y ++CONFIG_RK_AVB_LIBAVB_USER=y ++CONFIG_OPTEE_CLIENT=y ++CONFIG_OPTEE_V2=y ++CONFIG_OPTEE_ALWAYS_USE_SECURITY_PARTITION=y +-- +2.42.0 diff --git a/patch/kernel/archive/rockchip64-6.12/dt/rk3568-yy3568.dts b/patch/kernel/archive/rockchip64-6.12/dt/rk3568-yy3568.dts new file mode 100755 index 000000000000..c50858323405 --- /dev/null +++ b/patch/kernel/archive/rockchip64-6.12/dt/rk3568-yy3568.dts @@ -0,0 +1,718 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2020 Rockchip Electronics Co., Ltd. + * + */ +/dts-v1/; + +#include +#include +#include +#include +#include "rk3568.dtsi" + +/ { + model = "Youyeetoo YY3568"; + compatible = "youyeetoo,yy3568", "rockchip,rk3568"; + + aliases { + ethernet0 = &gmac0; + ethernet1 = &gmac1; + mmc2 = &sdmmc2; + mmc1 = &sdmmc0; + mmc0 = &sdhci; + }; + + gpio-leds { + compatible = "gpio-leds"; + + led_user: led-0 { + gpios = <&gpio3 RK_PA4 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + pinctrl-names = "default"; + pinctrl-0 = <&led_user_en>; + }; + led_power: led-1 { + gpios = <&gpio2 RK_PB2 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + pinctrl-names = "default"; + pinctrl-0 = <&led_power_en>; + }; + }; + + hdmi-con { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_con_in: endpoint { + remote-endpoint = <&hdmi_out_con>; + }; + }; + }; + + rk809-sound { + compatible = "simple-audio-card"; + pinctrl-names = "default"; + pinctrl-0 = <&hp_det>; + hp-det-gpio = <&gpio3 RK_PC2 GPIO_ACTIVE_LOW>; + simple-audio-card,format = "i2s"; + simple-audio-card,name = "Analog RK809"; + simple-audio-card,mclk-fs = <256>; + + simple-audio-card,cpu { + sound-dai = <&i2s1_8ch>; + }; + simple-audio-card,codec { + sound-dai = <&rk809>; + }; + }; + + vcc5v0_otg: regulator-vbus-typec { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc5v0_otg_en>; + regulator-name = "vcc5v0_otg"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc5v0_sys>; + }; + + /* actually fed by vcc5v0_sys, dependent + * on pi6c clock generator + */ + + vcc5v0_host: vcc5v0-host-regulator { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc5v0_host_en>; + regulator-name = "vcc5v0_host"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc5v0_sys>; + }; + + vcc3v3_pcie30x1: regulator-vcc3v3-pcie30x1 { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pcie30x1_enable_h>; + regulator-name = "vcc3v3_pcie30x1"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc5v0_sys>; + }; + + vcc3v3_pi6c_05: regulator-vcc3v3-pi6c-05 { + compatible = "regulator-fixed"; + enable-active-high; + gpios = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pcie_enable_h>; + regulator-name = "vcc3v3_pcie"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc5v0_sys>; + }; + + pcie30_avdd0v9: regulator-pcie30-avdd0v9 { + compatible = "regulator-fixed"; + regulator-name = "pcie30_avdd0v9"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + vin-supply = <&vcc3v3_sys>; + }; + + pcie30_avdd1v8: regulator-pcie30-avdd1v8 { + compatible = "regulator-fixed"; + regulator-name = "pcie30_avdd1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc3v3_sys>; + }; + + vcc3v3_sys: regulator-vcc3v3-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc12v_input>; + }; + + vcc5v0_sys: regulator-vcc5v0-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc12v_input>; + }; + + /* labeled +12v_input in schematic */ + vcc12v_input: regulator-vcc5v-input { + compatible = "regulator-fixed"; + regulator-name = "vcc12v_input"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + }; +}; + +&combphy1 { + phy-supply = <&vcc3v3_pcie30x1>; + status = "okay"; +}; + +&combphy0 { + status = "okay"; +}; + +&combphy2 { + status = "okay"; +}; + +&cpu0 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu1 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu2 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu3 { + cpu-supply = <&vdd_cpu>; +}; + +&gpu { + mali-supply = <&vdd_gpu>; + status = "okay"; +}; + +&vop { + assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>; + assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>; + status = "okay"; +}; + +&vop_mmu { + status = "okay"; +}; + +&vp0 { + vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 { + reg = ; + remote-endpoint = <&hdmi_in_vp0>; + }; +}; + +&hdmi { + assigned-clocks = <&cru CLK_HDMI_CEC>; + assigned-clock-rates = <32768>; + avdd-0v9-supply = <&vdda0v9_image>; + avdd-1v8-supply = <&vcca1v8_image>; + status = "okay"; +}; + +&hdmi_in { + hdmi_in_vp0: endpoint { + remote-endpoint = <&vp0_out_hdmi>; + }; +}; + +&hdmi_out { + hdmi_out_con: endpoint { + remote-endpoint = <&hdmi_con_in>; + }; +}; + +&hdmi_sound { + status = "okay"; +}; + +&hdmi_sound { + status = "okay"; +}; + +&pcie2x1 { + pinctrl-names = "default"; + reset-gpios = <&gpio1 RK_PB2 GPIO_ACTIVE_HIGH>; + vpcie3v3-supply = <&vcc3v3_pi6c_05>; + status = "okay"; +}; + +&pcie30phy { + data-lanes = <1 2>; + status = "okay"; +}; + +&pcie3x2 { + num-lanes = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&pcie30x2_reset_h>; + reset-gpios = <&gpio2 RK_PD6 GPIO_ACTIVE_HIGH>; + vpcie3v3-supply = <&vcc3v3_pi6c_05>; + status = "okay"; +}; + +&i2c0 { + status = "okay"; + + vdd_cpu: regulator@1c { + compatible = "tcs,tcs4525"; + reg = <0x1c>; + fcs,suspend-voltage-selector = <1>; + regulator-name = "vdd_cpu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1150000>; + regulator-ramp-delay = <2300>; + vin-supply = <&vcc12v_input>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + rk809: pmic@20 { + compatible = "rockchip,rk809"; + reg = <0x20>; + interrupt-parent = <&gpio0>; + interrupts = ; + #clock-cells = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int>; + system-power-controller; + wakeup-source; + + vcc1-supply = <&vcc3v3_sys>; + vcc2-supply = <&vcc3v3_sys>; + vcc3-supply = <&vcc3v3_sys>; + vcc4-supply = <&vcc3v3_sys>; + vcc5-supply = <&vcc3v3_sys>; + vcc6-supply = <&vcc3v3_sys>; + vcc7-supply = <&vcc3v3_sys>; + vcc8-supply = <&vcc3v3_sys>; + vcc9-supply = <&vcc3v3_sys>; + + regulators { + vdd_logic: DCDC_REG1 { + regulator-name = "vdd_logic"; + regulator-always-on; + regulator-boot-on; + regulator-initial-mode = <0x2>; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_gpu: DCDC_REG2 { + regulator-name = "vdd_gpu"; + regulator-always-on; + regulator-initial-mode = <0x2>; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + regulator-initial-mode = <0x2>; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vdd_npu: DCDC_REG4 { + regulator-name = "vdd_npu"; + regulator-initial-mode = <0x2>; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_1v8: DCDC_REG5 { + regulator-name = "vcc_1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda0v9_image: LDO_REG1 { + regulator-name = "vdda0v9_image"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda_0v9: LDO_REG2 { + regulator-name = "vdda_0v9"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda0v9_pmu: LDO_REG3 { + regulator-name = "vdda0v9_pmu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <900000>; + }; + }; + + vccio_acodec: LDO_REG4 { + regulator-name = "vccio_acodec"; + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vccio_sd: LDO_REG5 { + regulator-name = "vccio_sd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc3v3_pmu: LDO_REG6 { + regulator-name = "vcc3v3_pmu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcca_1v8: LDO_REG7 { + regulator-name = "vcca_1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcca1v8_pmu: LDO_REG8 { + regulator-name = "vcca1v8_pmu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcca1v8_image: LDO_REG9 { + regulator-name = "vcca1v8_image"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_3v3: SWITCH_REG1 { + regulator-name = "vcc_3v3"; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc3v3_sd: SWITCH_REG2 { + regulator-name = "vcc3v3_sd"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + }; + }; +}; + +&pinctrl { + leds { + led_user_en: led_user_en { + rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>; + }; + led_power_en: led_power_en { + rockchip,pins = <2 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + headphone { + hp_det: hp-det { + rockchip,pins = <3 RK_PC2 RK_FUNC_GPIO &pcfg_pull_down>; + }; + }; + + pmic { + pmic_int: pmic_int { + rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + pcie { + pcie30x1_enable_h: pcie30x1-enable-h { + rockchip,pins = <0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + pcie30x2_reset_h: pcie30x2-reset-h { + rockchip,pins = <2 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + pcie_enable_h: pcie-enable-h { + rockchip,pins = <0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + usb { + vcc5v0_host_en: vcc5v0-host-en { + rockchip,pins = <0 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + vcc5v0_otg_en: vcc5v0_otg_en { + rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&i2s1_8ch { + rockchip,trcm-sync-tx-only; + status = "okay"; +}; + +&pmu_io_domains { + pmuio1-supply = <&vcc3v3_pmu>; + pmuio2-supply = <&vcc3v3_pmu>; + vccio1-supply = <&vccio_acodec>; + vccio2-supply = <&vcc_1v8>; + vccio3-supply = <&vccio_sd>; + vccio4-supply = <&vcc_1v8>; + vccio5-supply = <&vcc_3v3>; + vccio6-supply = <&vcc_1v8>; + vccio7-supply = <&vcc_3v3>; + status = "okay"; +}; + +&saradc { + vref-supply = <&vcca_1v8>; + status = "okay"; +}; + +&sdhci { + bus-width = <8>; + max-frequency = <200000000>; + non-removable; + pinctrl-names = "default"; + pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>; + vmmc-supply = <&vcc_3v3>; + vqmmc-supply = <&vcc_1v8>; + status = "okay"; +}; + +&tsadc { + rockchip,hw-tshut-mode = <1>; + rockchip,hw-tshut-polarity = <0>; + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&sdmmc0 { + bus-width = <4>; + cap-sd-highspeed; + cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; + /* Also used in pcie30x1_clkreqnm0 */ + disable-wp; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd>; + sd-uhs-sdr104; + vmmc-supply = <&vcc3v3_sd>; + vqmmc-supply = <&vccio_sd>; + status = "okay"; +}; + +&sdmmc2 { + bus-width = <4>; + cap-sd-highspeed; + cd-gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_LOW>; + disable-wp; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc2m0_bus4 &sdmmc2m0_clk &sdmmc2m0_cmd>; + sd-uhs-sdr104; + status = "okay"; +}; + +&mdio0 { + rgmii_phy0: ethernet-phy@0 { + compatible = "ethernet-phy-id001c.c916"; + reg = <0x0>; + reset-assert-us = <20000>; + reset-deassert-us = <100000>; + reset-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_LOW>; + }; +}; + +&mdio1 { + rgmii_phy1: ethernet-phy@0 { + compatible = "ethernet-phy-id001c.c916"; + reg = <0x0>; + reset-assert-us = <20000>; + reset-deassert-us = <100000>; + reset-gpios = <&gpio2 RK_PD1 GPIO_ACTIVE_LOW>; + }; +}; + +&gmac0 { + assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>; + assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>; + assigned-clock-rates = <0>, <125000000>; + clock_in_out = "output"; + phy-handle = <&rgmii_phy0>; + phy-mode = "rgmii"; + pinctrl-names = "default"; + pinctrl-0 = <&gmac0_miim + &gmac0_tx_bus2 + &gmac0_rx_bus2 + &gmac0_rgmii_clk + &gmac0_rgmii_bus>; + status = "okay"; +}; + +&gmac1 { + assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>; + assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>; + assigned-clock-rates = <0>, <125000000>; + clock_in_out = "output"; + phy-handle = <&rgmii_phy1>; + phy-mode = "rgmii"; + pinctrl-names = "default"; + pinctrl-0 = <&gmac1m1_miim + &gmac1m1_tx_bus2 + &gmac1m1_rx_bus2 + &gmac1m1_rgmii_clk + &gmac1m1_rgmii_bus>; + status = "okay"; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; + +&usb_host0_xhci { + dr_mode = "host"; + extcon = <&usb2phy0>; + status = "okay"; +}; + +&usb_host1_ehci { + status = "okay"; +}; + +&usb_host1_ohci { + status = "okay"; +}; + +&usb_host1_xhci { + status = "okay"; +}; + +&usb2phy0 { + status = "okay"; +}; + +&usb2phy0_host { + phy-supply = <&vcc5v0_host>; + status = "okay"; +}; + +&usb2phy1 { + status = "okay"; +}; + +&usb2phy1_host { + phy-supply = <&vcc5v0_host>; + status = "okay"; +}; + +&usb2phy1_otg { + phy-supply = <&vcc5v0_host>; + status = "okay"; +}; \ No newline at end of file diff --git a/patch/kernel/archive/rockchip64-6.14/board-yy3568.patch b/patch/kernel/archive/rockchip64-6.14/board-yy3568.patch new file mode 100644 index 000000000000..fa1964084bcf --- /dev/null +++ b/patch/kernel/archive/rockchip64-6.14/board-yy3568.patch @@ -0,0 +1,990 @@ +From a796d047927ed8db448a002bf390d5dc94fc155b Mon Sep 17 00:00:00 2001 +From: Nicolas Pereira +Date: Sun, 8 Oct 2023 14:16:45 +0300 +Subject: [PATCH] Add YY3568 support for mainline + +--- + arch/arm/dts/rk3568-yy3568.dts | 732 ++++++++++++++++++++++++++++++ + configs/yy3568-rk3568_defconfig | 232 ++++++++++++++ + 2 files changed, 964 insertions(+) + create mode 100644 arch/arm/dts/rk3568-yy3568.dts + create mode 100644 configs/yy3568-rk3568_defconfig + +diff --git a/arch/arm64/boot/dts/rockchip/rk3568-yy3568.dts b/arch/arm64/boot/dts/rockchip/rk3568-yy3568.dts +new file mode 100644 +index 0000000000..e32c83f8fb +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3568-yy3568.dts +@@ -0,0 +1,732 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2020 Rockchip Electronics Co., Ltd. ++ * ++ */ ++/dts-v1/; ++ ++#include ++#include ++#include ++#include ++#include "rk3568.dtsi" ++ ++/ { ++ model = "Youyeetoo YY3568"; ++ compatible = "youyeetoo,yy3568", "rockchip,rk3568"; ++ ++ aliases { ++ ethernet0 = &gmac0; ++ ethernet1 = &gmac1; ++ mmc2 = &sdmmc2; ++ mmc1 = &sdmmc0; ++ mmc0 = &sdhci; ++ }; ++ ++ gpio-leds { ++ compatible = "gpio-leds"; ++ ++ led_user: led-0 { ++ gpios = <&gpio3 RK_PA4 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "heartbeat"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&led_user_en>; ++ }; ++ led_power: led-1 { ++ gpios = <&gpio2 RK_PB2 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "heartbeat"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&led_power_en>; ++ }; ++ }; ++ ++ hdmi-con { ++ compatible = "hdmi-connector"; ++ type = "a"; ++ ++ port { ++ hdmi_con_in: endpoint { ++ remote-endpoint = <&hdmi_out_con>; ++ }; ++ }; ++ }; ++ ++ rk809-sound { ++ compatible = "simple-audio-card"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&hp_det>; ++ hp-det-gpio = <&gpio3 RK_PC2 GPIO_ACTIVE_LOW>; ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,name = "Analog RK809"; ++ simple-audio-card,mclk-fs = <256>; ++ ++ simple-audio-card,cpu { ++ sound-dai = <&i2s1_8ch>; ++ }; ++ simple-audio-card,codec { ++ sound-dai = <&rk809>; ++ }; ++ }; ++ ++ vcc5v0_otg: regulator-vbus-typec { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vcc5v0_otg_en>; ++ regulator-name = "vcc5v0_otg"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc5v0_sys>; ++ }; ++ ++ /* actually fed by vcc5v0_sys, dependent ++ * on pi6c clock generator ++ */ ++ ++ vcc5v0_host: vcc5v0-host-regulator { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vcc5v0_host_en>; ++ regulator-name = "vcc5v0_host"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc5v0_sys>; ++ }; ++ ++ vcc3v3_pcie30x1: regulator-vcc3v3-pcie30x1 { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie30x1_enable_h>; ++ regulator-name = "vcc3v3_pcie30x1"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&vcc5v0_sys>; ++ }; ++ ++ vcc3v3_pi6c_05: regulator-vcc3v3-pi6c-05 { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpios = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie_enable_h>; ++ regulator-name = "vcc3v3_pcie"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&vcc5v0_sys>; ++ }; ++ ++ pcie30_avdd0v9: regulator-pcie30-avdd0v9 { ++ compatible = "regulator-fixed"; ++ regulator-name = "pcie30_avdd0v9"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <900000>; ++ vin-supply = <&vcc3v3_sys>; ++ }; ++ ++ pcie30_avdd1v8: regulator-pcie30-avdd1v8 { ++ compatible = "regulator-fixed"; ++ regulator-name = "pcie30_avdd1v8"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ vin-supply = <&vcc3v3_sys>; ++ }; ++ ++ vcc3v3_sys: regulator-vcc3v3-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc3v3_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&vcc12v_input>; ++ }; ++ ++ vcc5v0_sys: regulator-vcc5v0-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc5v0_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc12v_input>; ++ }; ++ ++ /* labeled +12v_input in schematic */ ++ vcc12v_input: regulator-vcc5v-input { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc12v_input"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <12000000>; ++ regulator-max-microvolt = <12000000>; ++ }; ++}; ++ ++&combphy1 { ++ phy-supply = <&vcc3v3_pcie30x1>; ++ status = "okay"; ++}; ++ ++&combphy0 { ++ status = "okay"; ++}; ++ ++&combphy2 { ++ status = "okay"; ++}; ++ ++&cpu0 { ++ cpu-supply = <&vdd_cpu>; ++}; ++ ++&cpu1 { ++ cpu-supply = <&vdd_cpu>; ++}; ++ ++&cpu2 { ++ cpu-supply = <&vdd_cpu>; ++}; ++ ++&cpu3 { ++ cpu-supply = <&vdd_cpu>; ++}; ++ ++&gpu { ++ mali-supply = <&vdd_gpu>; ++ status = "okay"; ++}; ++ ++&vop { ++ assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>; ++ assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>; ++ status = "okay"; ++}; ++ ++&vop_mmu { ++ status = "okay"; ++}; ++ ++&vp0 { ++ vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 { ++ reg = ; ++ remote-endpoint = <&hdmi_in_vp0>; ++ }; ++}; ++ ++&hdmi { ++ assigned-clocks = <&cru CLK_HDMI_CEC>; ++ assigned-clock-rates = <32768>; ++ avdd-0v9-supply = <&vdda0v9_image>; ++ avdd-1v8-supply = <&vcca1v8_image>; ++ status = "okay"; ++}; ++ ++&hdmi_in { ++ hdmi_in_vp0: endpoint { ++ remote-endpoint = <&vp0_out_hdmi>; ++ }; ++}; ++ ++&hdmi_out { ++ hdmi_out_con: endpoint { ++ remote-endpoint = <&hdmi_con_in>; ++ }; ++}; ++ ++&hdmi_sound { ++ status = "okay"; ++}; ++ ++&hdmi_sound { ++ status = "okay"; ++}; ++ ++&pcie2x1 { ++ pinctrl-names = "default"; ++ reset-gpios = <&gpio1 RK_PB2 GPIO_ACTIVE_HIGH>; ++ vpcie3v3-supply = <&vcc3v3_pi6c_05>; ++ status = "okay"; ++}; ++ ++&pcie30phy { ++ data-lanes = <1 2>; ++ status = "okay"; ++}; ++ ++&pcie3x2 { ++ num-lanes = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie30x2_reset_h>; ++ reset-gpios = <&gpio2 RK_PD6 GPIO_ACTIVE_HIGH>; ++ vpcie3v3-supply = <&vcc3v3_pi6c_05>; ++ status = "okay"; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ ++ vdd_cpu: regulator@1c { ++ compatible = "tcs,tcs4525"; ++ reg = <0x1c>; ++ fcs,suspend-voltage-selector = <1>; ++ regulator-name = "vdd_cpu"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <800000>; ++ regulator-max-microvolt = <1150000>; ++ regulator-ramp-delay = <2300>; ++ vin-supply = <&vcc12v_input>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ rk809: pmic@20 { ++ compatible = "rockchip,rk809"; ++ reg = <0x20>; ++ interrupt-parent = <&gpio0>; ++ interrupts = ; ++ #clock-cells = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_int>; ++ system-power-controller; ++ wakeup-source; ++ ++ vcc1-supply = <&vcc3v3_sys>; ++ vcc2-supply = <&vcc3v3_sys>; ++ vcc3-supply = <&vcc3v3_sys>; ++ vcc4-supply = <&vcc3v3_sys>; ++ vcc5-supply = <&vcc3v3_sys>; ++ vcc6-supply = <&vcc3v3_sys>; ++ vcc7-supply = <&vcc3v3_sys>; ++ vcc8-supply = <&vcc3v3_sys>; ++ vcc9-supply = <&vcc3v3_sys>; ++ ++ regulators { ++ vdd_logic: DCDC_REG1 { ++ regulator-name = "vdd_logic"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-initial-mode = <0x2>; ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <6001>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_gpu: DCDC_REG2 { ++ regulator-name = "vdd_gpu"; ++ regulator-always-on; ++ regulator-initial-mode = <0x2>; ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <6001>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_ddr: DCDC_REG3 { ++ regulator-name = "vcc_ddr"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-initial-mode = <0x2>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vdd_npu: DCDC_REG4 { ++ regulator-name = "vdd_npu"; ++ regulator-initial-mode = <0x2>; ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <6001>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_1v8: DCDC_REG5 { ++ regulator-name = "vcc_1v8"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdda0v9_image: LDO_REG1 { ++ regulator-name = "vdda0v9_image"; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <900000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdda_0v9: LDO_REG2 { ++ regulator-name = "vdda_0v9"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <900000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdda0v9_pmu: LDO_REG3 { ++ regulator-name = "vdda0v9_pmu"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <900000>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <900000>; ++ }; ++ }; ++ ++ vccio_acodec: LDO_REG4 { ++ regulator-name = "vccio_acodec"; ++ regulator-always-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vccio_sd: LDO_REG5 { ++ regulator-name = "vccio_sd"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc3v3_pmu: LDO_REG6 { ++ regulator-name = "vcc3v3_pmu"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3300000>; ++ }; ++ }; ++ ++ vcca_1v8: LDO_REG7 { ++ regulator-name = "vcca_1v8"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcca1v8_pmu: LDO_REG8 { ++ regulator-name = "vcca1v8_pmu"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcca1v8_image: LDO_REG9 { ++ regulator-name = "vcca1v8_image"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_3v3: SWITCH_REG1 { ++ regulator-name = "vcc_3v3"; ++ regulator-always-on; ++ regulator-boot-on; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc3v3_sd: SWITCH_REG2 { ++ regulator-name = "vcc3v3_sd"; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&pinctrl { ++ leds { ++ led_user_en: led_user_en { ++ rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ led_power_en: led_power_en { ++ rockchip,pins = <2 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ headphone { ++ hp_det: hp-det { ++ rockchip,pins = <3 RK_PC2 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ }; ++ ++ pmic { ++ pmic_int: pmic_int { ++ rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ pcie { ++ pcie30x1_enable_h: pcie30x1-enable-h { ++ rockchip,pins = <0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ pcie30x2_reset_h: pcie30x2-reset-h { ++ rockchip,pins = <2 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ pcie_enable_h: pcie-enable-h { ++ rockchip,pins = <0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ usb { ++ vcc5v0_host_en: vcc5v0-host-en { ++ rockchip,pins = <0 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ vcc5v0_otg_en: vcc5v0_otg_en { ++ rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++}; ++ ++&i2s1_8ch { ++ rockchip,trcm-sync-tx-only; ++ status = "okay"; ++}; ++ ++&pmu_io_domains { ++ pmuio1-supply = <&vcc3v3_pmu>; ++ pmuio2-supply = <&vcc3v3_pmu>; ++ vccio1-supply = <&vccio_acodec>; ++ vccio2-supply = <&vcc_1v8>; ++ vccio3-supply = <&vccio_sd>; ++ vccio4-supply = <&vcc_1v8>; ++ vccio5-supply = <&vcc_3v3>; ++ vccio6-supply = <&vcc_1v8>; ++ vccio7-supply = <&vcc_3v3>; ++ status = "okay"; ++}; ++ ++&saradc { ++ vref-supply = <&vcca_1v8>; ++ status = "okay"; ++}; ++ ++&sdhci { ++ bus-width = <8>; ++ max-frequency = <200000000>; ++ non-removable; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>; ++ vmmc-supply = <&vcc_3v3>; ++ vqmmc-supply = <&vcc_1v8>; ++ status = "okay"; ++}; ++ ++&tsadc { ++ rockchip,hw-tshut-mode = <1>; ++ rockchip,hw-tshut-polarity = <0>; ++ status = "okay"; ++}; ++ ++&uart2 { ++ status = "okay"; ++}; ++ ++&sdmmc0 { ++ bus-width = <4>; ++ cap-sd-highspeed; ++ cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; ++ /* Also used in pcie30x1_clkreqnm0 */ ++ disable-wp; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd>; ++ sd-uhs-sdr104; ++ vmmc-supply = <&vcc3v3_sd>; ++ vqmmc-supply = <&vccio_sd>; ++ status = "okay"; ++}; ++ ++&sdmmc2 { ++ bus-width = <4>; ++ cap-sd-highspeed; ++ cd-gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_LOW>; ++ disable-wp; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc2m0_bus4 &sdmmc2m0_clk &sdmmc2m0_cmd>; ++ sd-uhs-sdr104; ++ status = "okay"; ++}; ++ ++&mdio0 { ++ rgmii_phy0: ethernet-phy@0 { ++ compatible = "ethernet-phy-id001c.c916"; ++ reg = <0x0>; ++ reset-assert-us = <20000>; ++ reset-deassert-us = <100000>; ++ reset-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_LOW>; ++ }; ++}; ++ ++&mdio1 { ++ rgmii_phy1: ethernet-phy@0 { ++ compatible = "ethernet-phy-id001c.c916"; ++ reg = <0x0>; ++ reset-assert-us = <20000>; ++ reset-deassert-us = <100000>; ++ reset-gpios = <&gpio2 RK_PD1 GPIO_ACTIVE_LOW>; ++ }; ++}; ++ ++&gmac0 { ++ assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>; ++ assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>; ++ assigned-clock-rates = <0>, <125000000>; ++ clock_in_out = "output"; ++ phy-handle = <&rgmii_phy0>; ++ phy-mode = "rgmii"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gmac0_miim ++ &gmac0_tx_bus2 ++ &gmac0_rx_bus2 ++ &gmac0_rgmii_clk ++ &gmac0_rgmii_bus>; ++ status = "okay"; ++}; ++ ++&gmac1 { ++ assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>; ++ assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>; ++ assigned-clock-rates = <0>, <125000000>; ++ clock_in_out = "output"; ++ phy-handle = <&rgmii_phy1>; ++ phy-mode = "rgmii"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gmac1m1_miim ++ &gmac1m1_tx_bus2 ++ &gmac1m1_rx_bus2 ++ &gmac1m1_rgmii_clk ++ &gmac1m1_rgmii_bus>; ++ status = "okay"; ++}; ++ ++&usb_host0_ehci { ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ status = "okay"; ++}; ++ ++&usb_host0_xhci { ++ dr_mode = "host"; ++ extcon = <&usb2phy0>; ++ status = "okay"; ++}; ++ ++&usb_host1_ehci { ++ status = "okay"; ++}; ++ ++&usb_host1_ohci { ++ status = "okay"; ++}; ++ ++&usb_host1_xhci { ++ status = "okay"; ++}; ++ ++&usb2phy0 { ++ status = "okay"; ++}; ++ ++&usb2phy0_host { ++ phy-supply = <&vcc5v0_host>; ++ status = "okay"; ++}; ++ ++&usb2phy1 { ++ status = "okay"; ++}; ++ ++&usb2phy1_host { ++ phy-supply = <&vcc5v0_host>; ++ status = "okay"; ++}; ++ ++&usb2phy1_otg { ++ phy-supply = <&vcc5v0_host>; ++ status = "okay"; ++}; ++ ++&usb2phy1 { ++ status = "okay"; ++}; ++ ++&usb2phy1_host { ++ phy-supply = <&vcc5v0_otg>; ++ status = "okay"; ++}; ++ ++&usb2phy1_otg { ++ phy-supply = <&vcc5v0_otg>; ++ status = "okay"; ++}; +diff --git a/configs/yy3568-rk3568_defconfig b/configs/yy3568-rk3568_defconfig +new file mode 100644 +index 0000000000..23f9251bb2 +--- /dev/null ++++ b/configs/yy3568-rk3568_defconfig +@@ -0,0 +1,232 @@ ++CONFIG_ARM=y ++CONFIG_ARCH_ROCKCHIP=y ++CONFIG_SPL_LIBCOMMON_SUPPORT=y ++CONFIG_SPL_LIBGENERIC_SUPPORT=y ++CONFIG_SYS_MALLOC_F_LEN=0x80000 ++CONFIG_SPL_FIT_GENERATOR="arch/arm/mach-rockchip/make_fit_atf.sh" ++CONFIG_ROCKCHIP_RK3568=y ++CONFIG_ROCKCHIP_FIT_IMAGE=y ++CONFIG_ROCKCHIP_VENDOR_PARTITION=y ++CONFIG_ROCKCHIP_FIT_IMAGE_PACK=y ++CONFIG_ROCKCHIP_NEW_IDB=y ++CONFIG_SPL_SERIAL_SUPPORT=y ++CONFIG_SPL_DRIVERS_MISC_SUPPORT=y ++CONFIG_TARGET_EVB_RK3568=y ++CONFIG_SPL_LIBDISK_SUPPORT=y ++CONFIG_SPL_NAND_SUPPORT=y ++CONFIG_SPL_SPI_FLASH_SUPPORT=y ++CONFIG_SPL_SPI_SUPPORT=y ++CONFIG_DEFAULT_DEVICE_TREE="rk3568-yy3568" ++CONFIG_DEBUG_UART=y ++CONFIG_FIT=y ++CONFIG_FIT_IMAGE_POST_PROCESS=y ++CONFIG_FIT_HW_CRYPTO=y ++CONFIG_SPL_LOAD_FIT=y ++CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y ++CONFIG_SPL_FIT_HW_CRYPTO=y ++# CONFIG_SPL_SYS_DCACHE_OFF is not set ++CONFIG_BOOTDELAY=0 ++CONFIG_SARADC_ROCKCHIP=y ++CONFIG_SYS_CONSOLE_INFO_QUIET=y ++# CONFIG_DISPLAY_CPUINFO is not set ++CONFIG_ANDROID_BOOTLOADER=y ++CONFIG_ANDROID_AVB=y ++CONFIG_ANDROID_BOOT_IMAGE_HASH=y ++CONFIG_SPL_BOARD_INIT=y ++# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set ++# CONFIG_SPL_LEGACY_IMAGE_SUPPORT is not set ++CONFIG_SPL_SEPARATE_BSS=y ++CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION=y ++CONFIG_SPL_SHA256_SUPPORT=y ++CONFIG_SPL_CRYPTO_SUPPORT=y ++CONFIG_SPL_HASH_SUPPORT=y ++CONFIG_SPL_MMC_WRITE=y ++CONFIG_SPL_MTD_SUPPORT=y ++CONFIG_SPL_MTD_WRITE=y ++CONFIG_SPL_ATF=y ++CONFIG_SPL_ATF_NO_PLATFORM_PARAM=y ++CONFIG_SPL_AB=y ++CONFIG_FASTBOOT_BUF_ADDR=0xc00800 ++CONFIG_FASTBOOT_BUF_SIZE=0x04000000 ++CONFIG_FASTBOOT_FLASH=y ++CONFIG_FASTBOOT_FLASH_MMC_DEV=0 ++CONFIG_CMD_BOOTZ=y ++CONFIG_CMD_DTIMG=y ++# CONFIG_CMD_ELF is not set ++# CONFIG_CMD_IMI is not set ++# CONFIG_CMD_IMLS is not set ++# CONFIG_CMD_XIMG is not set ++# CONFIG_CMD_LZMADEC is not set ++# CONFIG_CMD_UNZIP is not set ++# CONFIG_CMD_FLASH is not set ++# CONFIG_CMD_FPGA is not set ++CONFIG_CMD_GPT=y ++# CONFIG_CMD_LOADB is not set ++# CONFIG_CMD_LOADS is not set ++CONFIG_CMD_BOOT_ANDROID=y ++CONFIG_CMD_BOOT_ROCKCHIP=y ++CONFIG_CMD_MMC=y ++CONFIG_CMD_MTD=y ++CONFIG_CMD_NAND=y ++CONFIG_CMD_PCI=y ++CONFIG_CMD_USB=y ++CONFIG_CMD_USB_MASS_STORAGE=y ++# CONFIG_CMD_ITEST is not set ++# CONFIG_CMD_SETEXPR is not set ++CONFIG_CMD_TFTPPUT=y ++CONFIG_CMD_TFTP_BOOTM=y ++CONFIG_CMD_TFTP_FLASH=y ++# CONFIG_CMD_MISC is not set ++# CONFIG_CMD_CHARGE_DISPLAY is not set ++CONFIG_CMD_MTD_BLK=y ++# CONFIG_SPL_DOS_PARTITION is not set ++# CONFIG_ISO_PARTITION is not set ++CONFIG_EFI_PARTITION_ENTRIES_NUMBERS=64 ++CONFIG_SPL_OF_CONTROL=y ++CONFIG_SPL_DTB_MINIMUM=y ++CONFIG_OF_LIVE=y ++CONFIG_OF_SPL_REMOVE_PROPS="" ++# CONFIG_NET_TFTP_VARS is not set ++CONFIG_REGMAP=y ++CONFIG_SPL_REGMAP=y ++CONFIG_SYSCON=y ++CONFIG_SPL_SYSCON=y ++CONFIG_CLK=y ++CONFIG_SPL_CLK=y ++CONFIG_CLK_SCMI=y ++CONFIG_DM_CRYPTO=y ++CONFIG_SPL_DM_CRYPTO=y ++CONFIG_ROCKCHIP_CRYPTO_V2=y ++CONFIG_SPL_ROCKCHIP_CRYPTO_V2=y ++CONFIG_DM_RNG=y ++CONFIG_RNG_ROCKCHIP=y ++CONFIG_SCMI_FIRMWARE=y ++CONFIG_ROCKCHIP_GPIO=y ++CONFIG_ROCKCHIP_GPIO_V2=y ++CONFIG_SYS_I2C_ROCKCHIP=y ++CONFIG_DM_KEY=y ++CONFIG_RK8XX_PWRKEY=y ++CONFIG_ADC_KEY=y ++CONFIG_MISC=y ++CONFIG_SPL_MISC=y ++CONFIG_ROCKCHIP_OTP=y ++CONFIG_SPL_ROCKCHIP_SECURE_OTP=y ++CONFIG_MMC_DW=y ++CONFIG_MMC_DW_ROCKCHIP=y ++CONFIG_MMC_SDHCI=y ++CONFIG_MMC_SDHCI_SDMA=y ++CONFIG_MMC_SDHCI_ROCKCHIP=y ++CONFIG_MTD=y ++CONFIG_MTD_BLK=y ++CONFIG_MTD_DEVICE=y ++CONFIG_NAND=y ++CONFIG_NAND_ROCKCHIP_V9=y ++CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y ++CONFIG_SYS_NAND_U_BOOT_OFFS=0x8000 ++CONFIG_SYS_NAND_U_BOOT_OFFS_REDUND=0x10000 ++CONFIG_MTD_SPI_NAND=y ++CONFIG_SPI_FLASH=y ++CONFIG_SF_DEFAULT_SPEED=20000000 ++CONFIG_SPI_FLASH_EON=y ++CONFIG_SPI_FLASH_GIGADEVICE=y ++CONFIG_SPI_FLASH_MACRONIX=y ++CONFIG_SPI_FLASH_WINBOND=y ++CONFIG_SPI_FLASH_XMC=y ++CONFIG_SPI_FLASH_MTD=y ++CONFIG_DM_ETH=y ++CONFIG_DM_ETH_PHY=y ++CONFIG_DWC_ETH_QOS=y ++CONFIG_GMAC_ROCKCHIP=y ++CONFIG_NVME=y ++CONFIG_PCI=y ++CONFIG_DM_PCI=y ++CONFIG_DM_PCI_COMPAT=y ++CONFIG_PCIE_DW_ROCKCHIP=y ++CONFIG_PHY_ROCKCHIP_INNO_USB2=y ++CONFIG_PHY_ROCKCHIP_NANENG_COMBOPHY=y ++CONFIG_PHY_ROCKCHIP_NANENG_EDP=y ++CONFIG_PHY_ROCKCHIP_SNPS_PCIE3=y ++CONFIG_PINCTRL=y ++CONFIG_SPL_PINCTRL=y ++CONFIG_DM_FUEL_GAUGE=y ++CONFIG_POWER_FG_RK817=y ++CONFIG_IO_DOMAIN=y ++CONFIG_ROCKCHIP_IO_DOMAIN=y ++CONFIG_DM_PMIC=y ++CONFIG_PMIC_RK8XX=y ++CONFIG_REGULATOR_FAN53555=y ++CONFIG_REGULATOR_PWM=y ++CONFIG_DM_REGULATOR_FIXED=y ++CONFIG_DM_REGULATOR_GPIO=y ++CONFIG_REGULATOR_RK8XX=y ++CONFIG_DM_CHARGE_DISPLAY=y ++CONFIG_CHARGE_ANIMATION=y ++CONFIG_PWM_ROCKCHIP=y ++CONFIG_RAM=y ++CONFIG_SPL_RAM=y ++CONFIG_TPL_RAM=y ++CONFIG_DM_RAMDISK=y ++CONFIG_RAMDISK_RO=y ++CONFIG_DM_DMC=y ++CONFIG_ROCKCHIP_DMC_FSP=y ++CONFIG_ROCKCHIP_SDRAM_COMMON=y ++CONFIG_ROCKCHIP_TPL_INIT_DRAM_TYPE=0 ++CONFIG_DM_RESET=y ++CONFIG_SPL_DM_RESET=y ++CONFIG_SPL_RESET_ROCKCHIP=y ++CONFIG_BAUDRATE=1500000 ++CONFIG_DEBUG_UART_BASE=0xFE660000 ++CONFIG_DEBUG_UART_CLOCK=24000000 ++CONFIG_DEBUG_UART_SHIFT=2 ++CONFIG_ROCKCHIP_SFC=y ++CONFIG_SYSRESET=y ++CONFIG_USB=y ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_XHCI_DWC3=y ++CONFIG_USB_EHCI_HCD=y ++CONFIG_USB_EHCI_GENERIC=y ++CONFIG_USB_OHCI_HCD=y ++CONFIG_USB_OHCI_GENERIC=y ++CONFIG_USB_DWC3=y ++CONFIG_USB_DWC3_GADGET=y ++CONFIG_USB_DWC3_GENERIC=y ++CONFIG_USB_STORAGE=y ++CONFIG_USB_GADGET=y ++CONFIG_USB_GADGET_MANUFACTURER="Rockchip" ++CONFIG_USB_GADGET_VENDOR_NUM=0x2207 ++CONFIG_USB_GADGET_PRODUCT_NUM=0x350a ++CONFIG_USB_GADGET_DOWNLOAD=y ++CONFIG_DM_VIDEO=y ++CONFIG_DISPLAY=y ++CONFIG_DRM_ROCKCHIP=y ++CONFIG_DRM_ROCKCHIP_DW_HDMI=y ++CONFIG_DRM_ROCKCHIP_INNO_MIPI_PHY=y ++CONFIG_DRM_ROCKCHIP_INNO_VIDEO_COMBO_PHY=y ++CONFIG_DRM_ROCKCHIP_DW_MIPI_DSI=y ++CONFIG_DRM_ROCKCHIP_ANALOGIX_DP=y ++CONFIG_DRM_ROCKCHIP_LVDS=y ++CONFIG_DRM_ROCKCHIP_RGB=y ++CONFIG_ROCKCHIP_CUBIC_LUT_SIZE=9 ++CONFIG_LCD=y ++CONFIG_USE_TINY_PRINTF=y ++CONFIG_SPL_TINY_MEMSET=y ++CONFIG_RSA=y ++CONFIG_SPL_RSA=y ++CONFIG_RSA_N_SIZE=0x200 ++CONFIG_RSA_E_SIZE=0x10 ++CONFIG_RSA_C_SIZE=0x20 ++CONFIG_XBC=y ++CONFIG_SHA512=y ++CONFIG_LZ4=y ++CONFIG_LZMA=y ++CONFIG_SPL_GZIP=y ++CONFIG_ERRNO_STR=y ++# CONFIG_EFI_LOADER is not set ++CONFIG_AVB_LIBAVB=y ++CONFIG_AVB_LIBAVB_AB=y ++CONFIG_AVB_LIBAVB_ATX=y ++CONFIG_AVB_LIBAVB_USER=y ++CONFIG_RK_AVB_LIBAVB_USER=y ++CONFIG_OPTEE_CLIENT=y ++CONFIG_OPTEE_V2=y ++CONFIG_OPTEE_ALWAYS_USE_SECURITY_PARTITION=y +-- +2.42.0 diff --git a/patch/kernel/archive/rockchip64-6.14/dt/rk3568-yy3568.dts b/patch/kernel/archive/rockchip64-6.14/dt/rk3568-yy3568.dts new file mode 100755 index 000000000000..c50858323405 --- /dev/null +++ b/patch/kernel/archive/rockchip64-6.14/dt/rk3568-yy3568.dts @@ -0,0 +1,718 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2020 Rockchip Electronics Co., Ltd. + * + */ +/dts-v1/; + +#include +#include +#include +#include +#include "rk3568.dtsi" + +/ { + model = "Youyeetoo YY3568"; + compatible = "youyeetoo,yy3568", "rockchip,rk3568"; + + aliases { + ethernet0 = &gmac0; + ethernet1 = &gmac1; + mmc2 = &sdmmc2; + mmc1 = &sdmmc0; + mmc0 = &sdhci; + }; + + gpio-leds { + compatible = "gpio-leds"; + + led_user: led-0 { + gpios = <&gpio3 RK_PA4 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + pinctrl-names = "default"; + pinctrl-0 = <&led_user_en>; + }; + led_power: led-1 { + gpios = <&gpio2 RK_PB2 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + pinctrl-names = "default"; + pinctrl-0 = <&led_power_en>; + }; + }; + + hdmi-con { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_con_in: endpoint { + remote-endpoint = <&hdmi_out_con>; + }; + }; + }; + + rk809-sound { + compatible = "simple-audio-card"; + pinctrl-names = "default"; + pinctrl-0 = <&hp_det>; + hp-det-gpio = <&gpio3 RK_PC2 GPIO_ACTIVE_LOW>; + simple-audio-card,format = "i2s"; + simple-audio-card,name = "Analog RK809"; + simple-audio-card,mclk-fs = <256>; + + simple-audio-card,cpu { + sound-dai = <&i2s1_8ch>; + }; + simple-audio-card,codec { + sound-dai = <&rk809>; + }; + }; + + vcc5v0_otg: regulator-vbus-typec { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc5v0_otg_en>; + regulator-name = "vcc5v0_otg"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc5v0_sys>; + }; + + /* actually fed by vcc5v0_sys, dependent + * on pi6c clock generator + */ + + vcc5v0_host: vcc5v0-host-regulator { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc5v0_host_en>; + regulator-name = "vcc5v0_host"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc5v0_sys>; + }; + + vcc3v3_pcie30x1: regulator-vcc3v3-pcie30x1 { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pcie30x1_enable_h>; + regulator-name = "vcc3v3_pcie30x1"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc5v0_sys>; + }; + + vcc3v3_pi6c_05: regulator-vcc3v3-pi6c-05 { + compatible = "regulator-fixed"; + enable-active-high; + gpios = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pcie_enable_h>; + regulator-name = "vcc3v3_pcie"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc5v0_sys>; + }; + + pcie30_avdd0v9: regulator-pcie30-avdd0v9 { + compatible = "regulator-fixed"; + regulator-name = "pcie30_avdd0v9"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + vin-supply = <&vcc3v3_sys>; + }; + + pcie30_avdd1v8: regulator-pcie30-avdd1v8 { + compatible = "regulator-fixed"; + regulator-name = "pcie30_avdd1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc3v3_sys>; + }; + + vcc3v3_sys: regulator-vcc3v3-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc12v_input>; + }; + + vcc5v0_sys: regulator-vcc5v0-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc12v_input>; + }; + + /* labeled +12v_input in schematic */ + vcc12v_input: regulator-vcc5v-input { + compatible = "regulator-fixed"; + regulator-name = "vcc12v_input"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + }; +}; + +&combphy1 { + phy-supply = <&vcc3v3_pcie30x1>; + status = "okay"; +}; + +&combphy0 { + status = "okay"; +}; + +&combphy2 { + status = "okay"; +}; + +&cpu0 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu1 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu2 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu3 { + cpu-supply = <&vdd_cpu>; +}; + +&gpu { + mali-supply = <&vdd_gpu>; + status = "okay"; +}; + +&vop { + assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>; + assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>; + status = "okay"; +}; + +&vop_mmu { + status = "okay"; +}; + +&vp0 { + vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 { + reg = ; + remote-endpoint = <&hdmi_in_vp0>; + }; +}; + +&hdmi { + assigned-clocks = <&cru CLK_HDMI_CEC>; + assigned-clock-rates = <32768>; + avdd-0v9-supply = <&vdda0v9_image>; + avdd-1v8-supply = <&vcca1v8_image>; + status = "okay"; +}; + +&hdmi_in { + hdmi_in_vp0: endpoint { + remote-endpoint = <&vp0_out_hdmi>; + }; +}; + +&hdmi_out { + hdmi_out_con: endpoint { + remote-endpoint = <&hdmi_con_in>; + }; +}; + +&hdmi_sound { + status = "okay"; +}; + +&hdmi_sound { + status = "okay"; +}; + +&pcie2x1 { + pinctrl-names = "default"; + reset-gpios = <&gpio1 RK_PB2 GPIO_ACTIVE_HIGH>; + vpcie3v3-supply = <&vcc3v3_pi6c_05>; + status = "okay"; +}; + +&pcie30phy { + data-lanes = <1 2>; + status = "okay"; +}; + +&pcie3x2 { + num-lanes = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&pcie30x2_reset_h>; + reset-gpios = <&gpio2 RK_PD6 GPIO_ACTIVE_HIGH>; + vpcie3v3-supply = <&vcc3v3_pi6c_05>; + status = "okay"; +}; + +&i2c0 { + status = "okay"; + + vdd_cpu: regulator@1c { + compatible = "tcs,tcs4525"; + reg = <0x1c>; + fcs,suspend-voltage-selector = <1>; + regulator-name = "vdd_cpu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1150000>; + regulator-ramp-delay = <2300>; + vin-supply = <&vcc12v_input>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + rk809: pmic@20 { + compatible = "rockchip,rk809"; + reg = <0x20>; + interrupt-parent = <&gpio0>; + interrupts = ; + #clock-cells = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int>; + system-power-controller; + wakeup-source; + + vcc1-supply = <&vcc3v3_sys>; + vcc2-supply = <&vcc3v3_sys>; + vcc3-supply = <&vcc3v3_sys>; + vcc4-supply = <&vcc3v3_sys>; + vcc5-supply = <&vcc3v3_sys>; + vcc6-supply = <&vcc3v3_sys>; + vcc7-supply = <&vcc3v3_sys>; + vcc8-supply = <&vcc3v3_sys>; + vcc9-supply = <&vcc3v3_sys>; + + regulators { + vdd_logic: DCDC_REG1 { + regulator-name = "vdd_logic"; + regulator-always-on; + regulator-boot-on; + regulator-initial-mode = <0x2>; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_gpu: DCDC_REG2 { + regulator-name = "vdd_gpu"; + regulator-always-on; + regulator-initial-mode = <0x2>; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + regulator-initial-mode = <0x2>; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vdd_npu: DCDC_REG4 { + regulator-name = "vdd_npu"; + regulator-initial-mode = <0x2>; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_1v8: DCDC_REG5 { + regulator-name = "vcc_1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda0v9_image: LDO_REG1 { + regulator-name = "vdda0v9_image"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda_0v9: LDO_REG2 { + regulator-name = "vdda_0v9"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda0v9_pmu: LDO_REG3 { + regulator-name = "vdda0v9_pmu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <900000>; + }; + }; + + vccio_acodec: LDO_REG4 { + regulator-name = "vccio_acodec"; + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vccio_sd: LDO_REG5 { + regulator-name = "vccio_sd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc3v3_pmu: LDO_REG6 { + regulator-name = "vcc3v3_pmu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcca_1v8: LDO_REG7 { + regulator-name = "vcca_1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcca1v8_pmu: LDO_REG8 { + regulator-name = "vcca1v8_pmu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcca1v8_image: LDO_REG9 { + regulator-name = "vcca1v8_image"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_3v3: SWITCH_REG1 { + regulator-name = "vcc_3v3"; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc3v3_sd: SWITCH_REG2 { + regulator-name = "vcc3v3_sd"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + }; + }; +}; + +&pinctrl { + leds { + led_user_en: led_user_en { + rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>; + }; + led_power_en: led_power_en { + rockchip,pins = <2 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + headphone { + hp_det: hp-det { + rockchip,pins = <3 RK_PC2 RK_FUNC_GPIO &pcfg_pull_down>; + }; + }; + + pmic { + pmic_int: pmic_int { + rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + pcie { + pcie30x1_enable_h: pcie30x1-enable-h { + rockchip,pins = <0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + pcie30x2_reset_h: pcie30x2-reset-h { + rockchip,pins = <2 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + pcie_enable_h: pcie-enable-h { + rockchip,pins = <0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + usb { + vcc5v0_host_en: vcc5v0-host-en { + rockchip,pins = <0 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + vcc5v0_otg_en: vcc5v0_otg_en { + rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&i2s1_8ch { + rockchip,trcm-sync-tx-only; + status = "okay"; +}; + +&pmu_io_domains { + pmuio1-supply = <&vcc3v3_pmu>; + pmuio2-supply = <&vcc3v3_pmu>; + vccio1-supply = <&vccio_acodec>; + vccio2-supply = <&vcc_1v8>; + vccio3-supply = <&vccio_sd>; + vccio4-supply = <&vcc_1v8>; + vccio5-supply = <&vcc_3v3>; + vccio6-supply = <&vcc_1v8>; + vccio7-supply = <&vcc_3v3>; + status = "okay"; +}; + +&saradc { + vref-supply = <&vcca_1v8>; + status = "okay"; +}; + +&sdhci { + bus-width = <8>; + max-frequency = <200000000>; + non-removable; + pinctrl-names = "default"; + pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>; + vmmc-supply = <&vcc_3v3>; + vqmmc-supply = <&vcc_1v8>; + status = "okay"; +}; + +&tsadc { + rockchip,hw-tshut-mode = <1>; + rockchip,hw-tshut-polarity = <0>; + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&sdmmc0 { + bus-width = <4>; + cap-sd-highspeed; + cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; + /* Also used in pcie30x1_clkreqnm0 */ + disable-wp; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd>; + sd-uhs-sdr104; + vmmc-supply = <&vcc3v3_sd>; + vqmmc-supply = <&vccio_sd>; + status = "okay"; +}; + +&sdmmc2 { + bus-width = <4>; + cap-sd-highspeed; + cd-gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_LOW>; + disable-wp; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc2m0_bus4 &sdmmc2m0_clk &sdmmc2m0_cmd>; + sd-uhs-sdr104; + status = "okay"; +}; + +&mdio0 { + rgmii_phy0: ethernet-phy@0 { + compatible = "ethernet-phy-id001c.c916"; + reg = <0x0>; + reset-assert-us = <20000>; + reset-deassert-us = <100000>; + reset-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_LOW>; + }; +}; + +&mdio1 { + rgmii_phy1: ethernet-phy@0 { + compatible = "ethernet-phy-id001c.c916"; + reg = <0x0>; + reset-assert-us = <20000>; + reset-deassert-us = <100000>; + reset-gpios = <&gpio2 RK_PD1 GPIO_ACTIVE_LOW>; + }; +}; + +&gmac0 { + assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>; + assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>; + assigned-clock-rates = <0>, <125000000>; + clock_in_out = "output"; + phy-handle = <&rgmii_phy0>; + phy-mode = "rgmii"; + pinctrl-names = "default"; + pinctrl-0 = <&gmac0_miim + &gmac0_tx_bus2 + &gmac0_rx_bus2 + &gmac0_rgmii_clk + &gmac0_rgmii_bus>; + status = "okay"; +}; + +&gmac1 { + assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>; + assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>; + assigned-clock-rates = <0>, <125000000>; + clock_in_out = "output"; + phy-handle = <&rgmii_phy1>; + phy-mode = "rgmii"; + pinctrl-names = "default"; + pinctrl-0 = <&gmac1m1_miim + &gmac1m1_tx_bus2 + &gmac1m1_rx_bus2 + &gmac1m1_rgmii_clk + &gmac1m1_rgmii_bus>; + status = "okay"; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; + +&usb_host0_xhci { + dr_mode = "host"; + extcon = <&usb2phy0>; + status = "okay"; +}; + +&usb_host1_ehci { + status = "okay"; +}; + +&usb_host1_ohci { + status = "okay"; +}; + +&usb_host1_xhci { + status = "okay"; +}; + +&usb2phy0 { + status = "okay"; +}; + +&usb2phy0_host { + phy-supply = <&vcc5v0_host>; + status = "okay"; +}; + +&usb2phy1 { + status = "okay"; +}; + +&usb2phy1_host { + phy-supply = <&vcc5v0_host>; + status = "okay"; +}; + +&usb2phy1_otg { + phy-supply = <&vcc5v0_host>; + status = "okay"; +}; \ No newline at end of file diff --git a/patch/u-boot/legacy/u-boot-radxa-rk35xx/board_yy3568/add_board_yy3568_defconfig.patch b/patch/u-boot/legacy/u-boot-radxa-rk35xx/board_yy3568/add_board_yy3568_defconfig.patch new file mode 100644 index 000000000000..427bfd3b3b79 --- /dev/null +++ b/patch/u-boot/legacy/u-boot-radxa-rk35xx/board_yy3568/add_board_yy3568_defconfig.patch @@ -0,0 +1,733 @@ +diff --git a/arch/arm/dts/rk3568-yy3568.dts b/arch/arm/dts/rk3568-yy3568.dts +new file mode 100644 +index 00000000000..9e6df741864 +--- /dev/null ++++ b/arch/arm/dts/rk3568-yy3568.dts +@@ -0,0 +1,494 @@ ++/* ++ * SPDX-License-Identifier: GPL-2.0+ ++ * Copyright (c) 2020 Rockchip Electronics Co., Ltd. ++ * Copyright (c) 2024 Radxa Limited ++ */ ++ ++/dts-v1/; ++#include "rk3568.dtsi" ++#include "rk3568-u-boot.dtsi" ++#include ++ ++/ { ++ model = "Youyeetoo YY3568"; ++ compatible = "youyeetoo,yy3568", "rockchip,rk3568"; ++ ++ vcc5v0_sys: vcc5v0-sys { ++ u-boot,dm-pre-reloc; ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc5v0_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ }; ++ ++ vcc3v3_sys: vcc3v3-sys { ++ u-boot,dm-pre-reloc; ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc3v3_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&vcc5v0_sys>; ++ }; ++ ++ led_sys: led-sys { ++ u-boot,dm-pre-reloc; ++ compatible = "regulator-fixed"; ++ regulator-name = "led_sys"; ++ enable-active-high; ++ gpio = <&gpio0 RK_PC1 GPIO_ACTIVE_HIGH>; ++ regulator-boot-on; ++ regulator-always-on; ++ vin-supply = <&vcc3v3_sys>; ++ }; ++ ++ led_sys: led-sys { ++ u-boot,dm-pre-reloc; ++ compatible = "regulator-fixed"; ++ regulator-name = "led_sys"; ++ enable-active-high; ++ gpio = <&gpio0 RK_PC1 GPIO_ACTIVE_HIGH>; ++ regulator-boot-on; ++ regulator-always-on; ++ vin-supply = <&vcc3v3_sys>; ++ }; ++ ++ adc-keys { ++ compatible = "adc-keys"; ++ io-channels = <&saradc 0>; ++ io-channel-names = "buttons"; ++ keyup-threshold-microvolt = <1800000>; ++ u-boot,dm-spl; ++ status = "okay"; ++ ++ volumeup-key { ++ u-boot,dm-spl; ++ linux,code = ; ++ label = "volume up"; ++ press-threshold-microvolt = <9>; ++ }; ++ }; ++ ++ leds { ++ u-boot,dm-pre-reloc; ++ compatible = "gpio-leds"; ++ status = "okay"; ++ ++ blue-led { ++ u-boot,dm-pre-reloc; ++ label = "blue"; ++ gpios = <&gpio2 RK_PB2 GPIO_ACTIVE_HIGH>; ++ }; ++ }; ++}; ++ ++&gmac1 { ++ u-boot,dm-pre-reloc; ++ phy-mode = "rgmii"; ++ clock_in_out = "output"; ++ ++ snps,reset-gpio = <&gpio2 RK_PD1 GPIO_ACTIVE_LOW>; ++ snps,reset-active-low; ++ /* Reset time is 20ms, 100ms for rtl8211f */ ++ snps,reset-delays-us = <0 20000 100000>; ++ ++ assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>; ++ assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>; ++ assigned-clock-rates = <0>, <125000000>; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gmac1m1_miim ++ &gmac1m1_tx_bus2 ++ &gmac1m1_rx_bus2 ++ &gmac1m1_rgmii_clk ++ &gmac1m1_rgmii_bus>; ++ ++ tx_delay = <0x44>; ++ rx_delay = <0x26>; ++ ++ phy-handle = <&rgmii_phy1>; ++ status = "disabled"; ++}; ++ ++&mdio1 { ++ rgmii_phy1: phy@0 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <0x0>; ++ }; ++}; ++ ++&crypto { ++ status = "okay"; ++}; ++ ++&uart2 { ++ status = "okay"; ++}; ++ ++&pmu_io_domains { ++ status = "okay"; ++ pmuio2-supply = <&vcc_3v3>; ++ vccio1-supply = <&vccio_acodec>; ++ vccio3-supply = <&vccio_sd>; ++ vccio4-supply = <&vcc_1v8>; ++ vccio5-supply = <&vcc_3v3>; ++ vccio6-supply = <&vcc_1v8>; ++ vccio7-supply = <&vcc_3v3>; ++ u-boot,dm-pre-reloc; ++}; ++ ++&gpio0 { ++ u-boot,dm-pre-reloc; ++}; ++ ++&gpio4 { ++ u-boot,dm-pre-reloc; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ u-boot,dm-pre-reloc; ++ clock-frequency = <100000>; ++ ++ vdd_cpu: tcs4525@1c { ++ u-boot,dm-pre-reloc; ++ compatible = "tcs,tcs452x"; ++ reg = <0x1c>; ++ vin-supply = <&vcc5v0_sys>; ++ regulator-compatible = "fan53555-reg"; ++ regulator-name = "vdd_cpu"; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1390000>; ++ regulator-init-microvolt = <900000>; ++ regulator-ramp-delay = <2300>; ++ fcs,suspend-voltage-selector = <1>; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-state-mem { ++ u-boot,dm-pre-reloc; ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ rk809: pmic@20 { ++ u-boot,dm-pre-reloc; ++ status = "okay"; ++ compatible = "rockchip,rk809"; ++ reg = <0x20>; ++ interrupt-parent = <&gpio0>; ++ interrupts = <3 IRQ_TYPE_LEVEL_LOW>; ++ ++ pinctrl-names = "default", "pmic-sleep", ++ "pmic-power-off", "pmic-reset"; ++ pinctrl-0 = <&pmic_int>; ++ pinctrl-1 = <&soc_slppin_slp>, <&rk817_slppin_slp>; ++ pinctrl-2 = <&soc_slppin_gpio>, <&rk817_slppin_pwrdn>; ++ pinctrl-3 = <&soc_slppin_gpio>, <&rk817_slppin_rst>; ++ ++ rockchip,system-power-controller; ++ wakeup-source; ++ #clock-cells = <1>; ++ clock-output-names = "rk808-clkout1", "rk808-clkout2"; ++ //fb-inner-reg-idxs = <2>; ++ /* 1: rst regs (default in codes), 0: rst the pmic */ ++ pmic-reset-func = <0>; ++ /* not save the PMIC_POWER_EN register in uboot */ ++ not-save-power-en = <1>; ++ ++ vcc1-supply = <&vcc3v3_sys>; ++ vcc2-supply = <&vcc3v3_sys>; ++ vcc3-supply = <&vcc3v3_sys>; ++ vcc4-supply = <&vcc3v3_sys>; ++ vcc5-supply = <&vcc3v3_sys>; ++ vcc6-supply = <&vcc3v3_sys>; ++ vcc7-supply = <&vcc3v3_sys>; ++ vcc8-supply = <&vcc3v3_sys>; ++ vcc9-supply = <&vcc3v3_sys>; ++ ++ pwrkey { ++ status = "okay"; ++ u-boot,dm-pre-reloc; ++ }; ++ ++ pinctrl_rk8xx: pinctrl_rk8xx { ++ u-boot,dm-pre-reloc; ++ gpio-controller; ++ #gpio-cells = <2>; ++ ++ rk817_slppin_null: rk817_slppin_null { ++ pins = "gpio_slp"; ++ function = "pin_fun0"; ++ u-boot,dm-pre-reloc; ++ }; ++ ++ rk817_slppin_slp: rk817_slppin_slp { ++ pins = "gpio_slp"; ++ function = "pin_fun1"; ++ u-boot,dm-pre-reloc; ++ }; ++ ++ rk817_slppin_pwrdn: rk817_slppin_pwrdn { ++ pins = "gpio_slp"; ++ function = "pin_fun2"; ++ u-boot,dm-pre-reloc; ++ }; ++ ++ rk817_slppin_rst: rk817_slppin_rst { ++ pins = "gpio_slp"; ++ function = "pin_fun3"; ++ u-boot,dm-pre-reloc; ++ }; ++ }; ++ ++ regulators { ++ u-boot,dm-pre-reloc; ++ vdd_logic: DCDC_REG1 { ++ u-boot,dm-pre-reloc; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-init-microvolt = <900000>; ++ regulator-ramp-delay = <6001>; ++ regulator-initial-mode = <0x2>; ++ regulator-name = "vdd_logic"; ++ regulator-state-mem { ++ u-boot,dm-pre-reloc; ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vdd_gpu: DCDC_REG2 { ++ u-boot,dm-pre-reloc; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-init-microvolt = <900000>; ++ regulator-ramp-delay = <6001>; ++ regulator-initial-mode = <0x2>; ++ regulator-name = "vdd_gpu"; ++ regulator-state-mem { ++ u-boot,dm-pre-reloc; ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vcc_ddr: DCDC_REG3 { ++ u-boot,dm-pre-reloc; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-initial-mode = <0x2>; ++ regulator-name = "vcc_ddr"; ++ regulator-state-mem { ++ u-boot,dm-pre-reloc; ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vdd_npu: DCDC_REG4 { ++ u-boot,dm-pre-reloc; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-init-microvolt = <900000>; ++ regulator-ramp-delay = <6001>; ++ regulator-initial-mode = <0x2>; ++ regulator-name = "vdd_npu"; ++ regulator-state-mem { ++ u-boot,dm-pre-reloc; ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vdda0v9_image: LDO_REG1 { ++ u-boot,dm-pre-reloc; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <900000>; ++ regulator-name = "vdda0v9_image"; ++ regulator-state-mem { ++ u-boot,dm-pre-reloc; ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdda_0v9: LDO_REG2 { ++ u-boot,dm-pre-reloc; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <900000>; ++ regulator-name = "vdda_0v9"; ++ regulator-state-mem { ++ u-boot,dm-pre-reloc; ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdda0v9_pmu: LDO_REG3 { ++ u-boot,dm-pre-reloc; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <900000>; ++ regulator-name = "vdda0v9_pmu"; ++ regulator-state-mem { ++ u-boot,dm-pre-reloc; ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <900000>; ++ }; ++ }; ++ ++ vccio_acodec: LDO_REG4 { ++ u-boot,dm-pre-reloc; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-name = "vccio_acodec"; ++ regulator-state-mem { ++ u-boot,dm-pre-reloc; ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vccio_sd: LDO_REG5 { ++ u-boot,dm-pre-reloc; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-name = "vccio_sd"; ++ regulator-state-mem { ++ u-boot,dm-pre-reloc; ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc3v3_pmu: LDO_REG6 { ++ u-boot,dm-pre-reloc; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-name = "vcc3v3_pmu"; ++ regulator-state-mem { ++ u-boot,dm-pre-reloc; ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3300000>; ++ }; ++ }; ++ ++ vcca_1v8: LDO_REG7 { ++ u-boot,dm-pre-reloc; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-name = "vcca_1v8"; ++ regulator-state-mem { ++ u-boot,dm-pre-reloc; ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcca1v8_pmu: LDO_REG8 { ++ u-boot,dm-pre-reloc; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-name = "vcca1v8_pmu"; ++ regulator-state-mem { ++ u-boot,dm-pre-reloc; ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcca1v8_image: LDO_REG9 { ++ u-boot,dm-pre-reloc; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-name = "vcca1v8_image"; ++ regulator-state-mem { ++ u-boot,dm-pre-reloc; ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_1v8: DCDC_REG5 { ++ u-boot,dm-pre-reloc; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-name = "vcc_1v8"; ++ regulator-state-mem { ++ u-boot,dm-pre-reloc; ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_3v3: SWITCH_REG1 { ++ u-boot,dm-pre-reloc; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-name = "vcc_3v3"; ++ regulator-state-mem { ++ u-boot,dm-pre-reloc; ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc3v3_sd: SWITCH_REG2 { ++ u-boot,dm-pre-reloc; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-name = "vcc3v3_sd"; ++ regulator-state-mem { ++ u-boot,dm-pre-reloc; ++ regulator-off-in-suspend; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&pinctrl { ++ u-boot,dm-spl; ++ pmic { ++ u-boot,dm-pre-reloc; ++ pmic_int: pmic_int { ++ u-boot,dm-pre-reloc; ++ rockchip,pins = ++ <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ ++ soc_slppin_gpio: soc_slppin_gpio { ++ u-boot,dm-pre-reloc; ++ rockchip,pins = ++ <0 RK_PA2 RK_FUNC_GPIO &pcfg_output_low_pull_down>; ++ }; ++ ++ soc_slppin_slp: soc_slppin_slp { ++ u-boot,dm-pre-reloc; ++ rockchip,pins = ++ <0 RK_PA2 RK_FUNC_1 &pcfg_pull_up>; ++ }; ++ ++ soc_slppin_rst: soc_slppin_rst { ++ u-boot,dm-pre-reloc; ++ rockchip,pins = ++ <0 RK_PA2 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ }; ++}; +diff --git a/configs/yy3568-rk3568_defconfig b/configs/yy3568-rk3568_defconfig +new file mode 100644 +index 00000000000..17ac783cd0b +--- /dev/null ++++ b/configs/yy3568-rk3568_defconfig +@@ -0,0 +1,227 @@ ++CONFIG_ARM=y ++CONFIG_ARCH_ROCKCHIP=y ++CONFIG_SPL_LIBCOMMON_SUPPORT=y ++CONFIG_SPL_LIBGENERIC_SUPPORT=y ++CONFIG_SYS_MALLOC_F_LEN=0x80000 ++CONFIG_SPL_FIT_GENERATOR="arch/arm/mach-rockchip/make_fit_atf.sh" ++CONFIG_ROCKCHIP_RK3568=y ++CONFIG_ROCKCHIP_FIT_IMAGE=y ++CONFIG_ROCKCHIP_VENDOR_PARTITION=y ++CONFIG_ROCKCHIP_FIT_IMAGE_PACK=y ++CONFIG_ROCKCHIP_NEW_IDB=y ++CONFIG_ROCKCHIP_EMMC_IOMUX=y ++CONFIG_SPL_SERIAL_SUPPORT=y ++CONFIG_SPL_DRIVERS_MISC_SUPPORT=y ++CONFIG_TARGET_EVB_RK3568=y ++CONFIG_SPL_LIBDISK_SUPPORT=y ++CONFIG_SPL_NAND_SUPPORT=y ++CONFIG_SPL_SPI_FLASH_SUPPORT=y ++CONFIG_SPL_SPI_SUPPORT=y ++CONFIG_DEFAULT_DEVICE_TREE="rk3568-yy3568" ++CONFIG_DEBUG_UART=y ++CONFIG_FIT=y ++CONFIG_FIT_IMAGE_POST_PROCESS=y ++CONFIG_FIT_HW_CRYPTO=y ++CONFIG_SPL_LOAD_FIT=y ++CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y ++CONFIG_SPL_FIT_HW_CRYPTO=y ++# CONFIG_SPL_SYS_DCACHE_OFF is not set ++CONFIG_BOOTDELAY=0 ++CONFIG_SYS_CONSOLE_INFO_QUIET=y ++# CONFIG_DISPLAY_CPUINFO is not set ++CONFIG_ANDROID_BOOTLOADER=y ++CONFIG_ANDROID_AVB=y ++CONFIG_ANDROID_BOOT_IMAGE_HASH=y ++CONFIG_SPL_BOARD_INIT=y ++# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set ++# CONFIG_SPL_LEGACY_IMAGE_SUPPORT is not set ++CONFIG_SPL_SEPARATE_BSS=y ++CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION=y ++CONFIG_SPL_SHA256_SUPPORT=y ++CONFIG_SPL_CRYPTO_SUPPORT=y ++CONFIG_SPL_HASH_SUPPORT=y ++CONFIG_SPL_MTD_SUPPORT=y ++CONFIG_SPL_ATF=y ++CONFIG_SPL_ATF_NO_PLATFORM_PARAM=y ++CONFIG_SPL_AB=y ++CONFIG_FASTBOOT_BUF_ADDR=0xc00800 ++CONFIG_FASTBOOT_BUF_SIZE=0x04000000 ++CONFIG_FASTBOOT_FLASH=y ++CONFIG_FASTBOOT_FLASH_MMC_DEV=0 ++CONFIG_CMD_BOOTZ=y ++CONFIG_CMD_DTIMG=y ++# CONFIG_CMD_ELF is not set ++# CONFIG_CMD_IMI is not set ++# CONFIG_CMD_IMLS is not set ++# CONFIG_CMD_XIMG is not set ++# CONFIG_CMD_LZMADEC is not set ++# CONFIG_CMD_UNZIP is not set ++# CONFIG_CMD_FLASH is not set ++# CONFIG_CMD_FPGA is not set ++CONFIG_CMD_GPT=y ++# CONFIG_CMD_LOADB is not set ++# CONFIG_CMD_LOADS is not set ++CONFIG_CMD_BOOT_ANDROID=y ++CONFIG_CMD_BOOT_ROCKCHIP=y ++CONFIG_CMD_MMC=y ++CONFIG_CMD_MTD=y ++CONFIG_CMD_NAND=y ++CONFIG_CMD_PCI=y ++CONFIG_CMD_USB=y ++CONFIG_CMD_USB_MASS_STORAGE=y ++# CONFIG_CMD_ITEST is not set ++# CONFIG_CMD_SETEXPR is not set ++CONFIG_CMD_TFTPPUT=y ++CONFIG_CMD_TFTP_BOOTM=y ++CONFIG_CMD_TFTP_FLASH=y ++# CONFIG_CMD_MISC is not set ++# CONFIG_CMD_CHARGE_DISPLAY is not set ++CONFIG_CMD_MTD_BLK=y ++# CONFIG_SPL_DOS_PARTITION is not set ++# CONFIG_ISO_PARTITION is not set ++CONFIG_EFI_PARTITION_ENTRIES_NUMBERS=64 ++CONFIG_SPL_OF_CONTROL=y ++CONFIG_SPL_DTB_MINIMUM=y ++CONFIG_OF_LIVE=y ++CONFIG_OF_SPL_REMOVE_PROPS="" ++# CONFIG_NET_TFTP_VARS is not set ++CONFIG_REGMAP=y ++CONFIG_SPL_REGMAP=y ++CONFIG_SYSCON=y ++CONFIG_SPL_SYSCON=y ++CONFIG_CLK=y ++CONFIG_SPL_CLK=y ++CONFIG_CLK_SCMI=y ++CONFIG_DM_CRYPTO=y ++CONFIG_SPL_DM_CRYPTO=y ++CONFIG_ROCKCHIP_CRYPTO_V2=y ++CONFIG_SPL_ROCKCHIP_CRYPTO_V2=y ++CONFIG_DM_RNG=y ++CONFIG_RNG_ROCKCHIP=y ++CONFIG_SCMI_FIRMWARE=y ++CONFIG_ROCKCHIP_GPIO=y ++CONFIG_ROCKCHIP_GPIO_V2=y ++CONFIG_SYS_I2C_ROCKCHIP=y ++CONFIG_DM_KEY=y ++CONFIG_RK8XX_PWRKEY=y ++CONFIG_ADC_KEY=y ++CONFIG_MISC=y ++CONFIG_SPL_MISC=y ++CONFIG_ROCKCHIP_OTP=y ++CONFIG_SPL_ROCKCHIP_SECURE_OTP=y ++CONFIG_MMC_DW=y ++CONFIG_MMC_DW_ROCKCHIP=y ++CONFIG_MMC_SDHCI=y ++CONFIG_MMC_SDHCI_SDMA=y ++CONFIG_MMC_SDHCI_ROCKCHIP=y ++CONFIG_MTD=y ++CONFIG_MTD_BLK=y ++CONFIG_MTD_DEVICE=y ++CONFIG_NAND=y ++CONFIG_NAND_ROCKCHIP_V9=y ++CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y ++CONFIG_SYS_NAND_U_BOOT_OFFS=0x8000 ++CONFIG_SYS_NAND_U_BOOT_OFFS_REDUND=0x10000 ++CONFIG_MTD_SPI_NAND=y ++CONFIG_SPI_FLASH=y ++CONFIG_SF_DEFAULT_SPEED=20000000 ++CONFIG_SPI_FLASH_EON=y ++CONFIG_SPI_FLASH_GIGADEVICE=y ++CONFIG_SPI_FLASH_MACRONIX=y ++CONFIG_SPI_FLASH_WINBOND=y ++CONFIG_SPI_FLASH_XMC=y ++CONFIG_SPI_FLASH_MTD=y ++CONFIG_DM_ETH=y ++CONFIG_DM_ETH_PHY=y ++CONFIG_DWC_ETH_QOS=y ++CONFIG_GMAC_ROCKCHIP=y ++CONFIG_NVME=y ++CONFIG_PCI=y ++CONFIG_DM_PCI=y ++CONFIG_DM_PCI_COMPAT=y ++CONFIG_PCIE_DW_ROCKCHIP=y ++CONFIG_PHY_ROCKCHIP_INNO_USB2=y ++CONFIG_PHY_ROCKCHIP_NANENG_COMBOPHY=y ++CONFIG_PHY_ROCKCHIP_NANENG_EDP=y ++CONFIG_PHY_ROCKCHIP_SNPS_PCIE3=y ++CONFIG_PINCTRL=y ++CONFIG_SPL_PINCTRL=y ++CONFIG_DM_FUEL_GAUGE=y ++CONFIG_POWER_FG_RK817=y ++CONFIG_IO_DOMAIN=y ++CONFIG_ROCKCHIP_IO_DOMAIN=y ++CONFIG_DM_PMIC=y ++CONFIG_PMIC_RK8XX=y ++CONFIG_REGULATOR_FAN53555=y ++CONFIG_REGULATOR_PWM=y ++CONFIG_DM_REGULATOR_FIXED=y ++CONFIG_DM_REGULATOR_GPIO=y ++CONFIG_REGULATOR_RK8XX=y ++CONFIG_DM_CHARGE_DISPLAY=y ++CONFIG_CHARGE_ANIMATION=y ++CONFIG_PWM_ROCKCHIP=y ++CONFIG_RAM=y ++CONFIG_SPL_RAM=y ++CONFIG_TPL_RAM=y ++CONFIG_DM_RAMDISK=y ++CONFIG_RAMDISK_RO=y ++CONFIG_DM_DMC=y ++CONFIG_ROCKCHIP_DMC_FSP=y ++CONFIG_ROCKCHIP_SDRAM_COMMON=y ++CONFIG_ROCKCHIP_TPL_INIT_DRAM_TYPE=0 ++CONFIG_DM_RESET=y ++CONFIG_SPL_DM_RESET=y ++CONFIG_SPL_RESET_ROCKCHIP=y ++CONFIG_BAUDRATE=115200 ++CONFIG_DEBUG_UART_BASE=0xFE660000 ++CONFIG_DEBUG_UART_CLOCK=24000000 ++CONFIG_DEBUG_UART_SHIFT=2 ++CONFIG_ROCKCHIP_SFC=y ++CONFIG_SYSRESET=y ++CONFIG_USB=y ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_XHCI_DWC3=y ++CONFIG_USB_EHCI_HCD=y ++CONFIG_USB_EHCI_GENERIC=y ++CONFIG_USB_OHCI_HCD=y ++CONFIG_USB_OHCI_GENERIC=y ++CONFIG_USB_DWC3=y ++CONFIG_USB_DWC3_GADGET=y ++CONFIG_USB_DWC3_GENERIC=y ++CONFIG_USB_STORAGE=y ++CONFIG_USB_GADGET=y ++CONFIG_USB_GADGET_MANUFACTURER="Rockchip" ++CONFIG_USB_GADGET_VENDOR_NUM=0x2207 ++CONFIG_USB_GADGET_PRODUCT_NUM=0x350a ++CONFIG_USB_GADGET_DOWNLOAD=y ++CONFIG_DM_VIDEO=y ++CONFIG_DISPLAY=y ++CONFIG_DRM_ROCKCHIP=y ++CONFIG_DRM_ROCKCHIP_DW_HDMI=y ++CONFIG_DRM_ROCKCHIP_INNO_MIPI_PHY=y ++CONFIG_DRM_ROCKCHIP_INNO_VIDEO_COMBO_PHY=y ++CONFIG_DRM_ROCKCHIP_DW_MIPI_DSI=y ++CONFIG_DRM_ROCKCHIP_ANALOGIX_DP=y ++CONFIG_DRM_ROCKCHIP_LVDS=y ++CONFIG_DRM_ROCKCHIP_RGB=y ++CONFIG_ROCKCHIP_CUBIC_LUT_SIZE=9 ++CONFIG_LCD=y ++CONFIG_USE_TINY_PRINTF=y ++CONFIG_SPL_TINY_MEMSET=y ++CONFIG_RSA=y ++CONFIG_SPL_RSA=y ++CONFIG_RSA_N_SIZE=0x200 ++CONFIG_RSA_E_SIZE=0x10 ++CONFIG_RSA_C_SIZE=0x20 ++CONFIG_XBC=y ++CONFIG_SHA512=y ++CONFIG_LZ4=y ++CONFIG_LZMA=y ++CONFIG_SPL_GZIP=y ++CONFIG_ERRNO_STR=y ++# CONFIG_EFI_LOADER is not set ++CONFIG_AVB_LIBAVB=y ++CONFIG_AVB_LIBAVB_AB=y ++CONFIG_AVB_LIBAVB_ATX=y ++CONFIG_AVB_LIBAVB_USER=y ++CONFIG_RK_AVB_LIBAVB_USER=y diff --git a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/yy3568-rk3568_defconfig b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/yy3568-rk3568_defconfig new file mode 100644 index 000000000000..17ac783cd0bb --- /dev/null +++ b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/yy3568-rk3568_defconfig @@ -0,0 +1,227 @@ +CONFIG_ARM=y +CONFIG_ARCH_ROCKCHIP=y +CONFIG_SPL_LIBCOMMON_SUPPORT=y +CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_SYS_MALLOC_F_LEN=0x80000 +CONFIG_SPL_FIT_GENERATOR="arch/arm/mach-rockchip/make_fit_atf.sh" +CONFIG_ROCKCHIP_RK3568=y +CONFIG_ROCKCHIP_FIT_IMAGE=y +CONFIG_ROCKCHIP_VENDOR_PARTITION=y +CONFIG_ROCKCHIP_FIT_IMAGE_PACK=y +CONFIG_ROCKCHIP_NEW_IDB=y +CONFIG_ROCKCHIP_EMMC_IOMUX=y +CONFIG_SPL_SERIAL_SUPPORT=y +CONFIG_SPL_DRIVERS_MISC_SUPPORT=y +CONFIG_TARGET_EVB_RK3568=y +CONFIG_SPL_LIBDISK_SUPPORT=y +CONFIG_SPL_NAND_SUPPORT=y +CONFIG_SPL_SPI_FLASH_SUPPORT=y +CONFIG_SPL_SPI_SUPPORT=y +CONFIG_DEFAULT_DEVICE_TREE="rk3568-yy3568" +CONFIG_DEBUG_UART=y +CONFIG_FIT=y +CONFIG_FIT_IMAGE_POST_PROCESS=y +CONFIG_FIT_HW_CRYPTO=y +CONFIG_SPL_LOAD_FIT=y +CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y +CONFIG_SPL_FIT_HW_CRYPTO=y +# CONFIG_SPL_SYS_DCACHE_OFF is not set +CONFIG_BOOTDELAY=0 +CONFIG_SYS_CONSOLE_INFO_QUIET=y +# CONFIG_DISPLAY_CPUINFO is not set +CONFIG_ANDROID_BOOTLOADER=y +CONFIG_ANDROID_AVB=y +CONFIG_ANDROID_BOOT_IMAGE_HASH=y +CONFIG_SPL_BOARD_INIT=y +# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set +# CONFIG_SPL_LEGACY_IMAGE_SUPPORT is not set +CONFIG_SPL_SEPARATE_BSS=y +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION=y +CONFIG_SPL_SHA256_SUPPORT=y +CONFIG_SPL_CRYPTO_SUPPORT=y +CONFIG_SPL_HASH_SUPPORT=y +CONFIG_SPL_MTD_SUPPORT=y +CONFIG_SPL_ATF=y +CONFIG_SPL_ATF_NO_PLATFORM_PARAM=y +CONFIG_SPL_AB=y +CONFIG_FASTBOOT_BUF_ADDR=0xc00800 +CONFIG_FASTBOOT_BUF_SIZE=0x04000000 +CONFIG_FASTBOOT_FLASH=y +CONFIG_FASTBOOT_FLASH_MMC_DEV=0 +CONFIG_CMD_BOOTZ=y +CONFIG_CMD_DTIMG=y +# CONFIG_CMD_ELF is not set +# CONFIG_CMD_IMI is not set +# CONFIG_CMD_IMLS is not set +# CONFIG_CMD_XIMG is not set +# CONFIG_CMD_LZMADEC is not set +# CONFIG_CMD_UNZIP is not set +# CONFIG_CMD_FLASH is not set +# CONFIG_CMD_FPGA is not set +CONFIG_CMD_GPT=y +# CONFIG_CMD_LOADB is not set +# CONFIG_CMD_LOADS is not set +CONFIG_CMD_BOOT_ANDROID=y +CONFIG_CMD_BOOT_ROCKCHIP=y +CONFIG_CMD_MMC=y +CONFIG_CMD_MTD=y +CONFIG_CMD_NAND=y +CONFIG_CMD_PCI=y +CONFIG_CMD_USB=y +CONFIG_CMD_USB_MASS_STORAGE=y +# CONFIG_CMD_ITEST is not set +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_TFTPPUT=y +CONFIG_CMD_TFTP_BOOTM=y +CONFIG_CMD_TFTP_FLASH=y +# CONFIG_CMD_MISC is not set +# CONFIG_CMD_CHARGE_DISPLAY is not set +CONFIG_CMD_MTD_BLK=y +# CONFIG_SPL_DOS_PARTITION is not set +# CONFIG_ISO_PARTITION is not set +CONFIG_EFI_PARTITION_ENTRIES_NUMBERS=64 +CONFIG_SPL_OF_CONTROL=y +CONFIG_SPL_DTB_MINIMUM=y +CONFIG_OF_LIVE=y +CONFIG_OF_SPL_REMOVE_PROPS="" +# CONFIG_NET_TFTP_VARS is not set +CONFIG_REGMAP=y +CONFIG_SPL_REGMAP=y +CONFIG_SYSCON=y +CONFIG_SPL_SYSCON=y +CONFIG_CLK=y +CONFIG_SPL_CLK=y +CONFIG_CLK_SCMI=y +CONFIG_DM_CRYPTO=y +CONFIG_SPL_DM_CRYPTO=y +CONFIG_ROCKCHIP_CRYPTO_V2=y +CONFIG_SPL_ROCKCHIP_CRYPTO_V2=y +CONFIG_DM_RNG=y +CONFIG_RNG_ROCKCHIP=y +CONFIG_SCMI_FIRMWARE=y +CONFIG_ROCKCHIP_GPIO=y +CONFIG_ROCKCHIP_GPIO_V2=y +CONFIG_SYS_I2C_ROCKCHIP=y +CONFIG_DM_KEY=y +CONFIG_RK8XX_PWRKEY=y +CONFIG_ADC_KEY=y +CONFIG_MISC=y +CONFIG_SPL_MISC=y +CONFIG_ROCKCHIP_OTP=y +CONFIG_SPL_ROCKCHIP_SECURE_OTP=y +CONFIG_MMC_DW=y +CONFIG_MMC_DW_ROCKCHIP=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_SDMA=y +CONFIG_MMC_SDHCI_ROCKCHIP=y +CONFIG_MTD=y +CONFIG_MTD_BLK=y +CONFIG_MTD_DEVICE=y +CONFIG_NAND=y +CONFIG_NAND_ROCKCHIP_V9=y +CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y +CONFIG_SYS_NAND_U_BOOT_OFFS=0x8000 +CONFIG_SYS_NAND_U_BOOT_OFFS_REDUND=0x10000 +CONFIG_MTD_SPI_NAND=y +CONFIG_SPI_FLASH=y +CONFIG_SF_DEFAULT_SPEED=20000000 +CONFIG_SPI_FLASH_EON=y +CONFIG_SPI_FLASH_GIGADEVICE=y +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_SPI_FLASH_WINBOND=y +CONFIG_SPI_FLASH_XMC=y +CONFIG_SPI_FLASH_MTD=y +CONFIG_DM_ETH=y +CONFIG_DM_ETH_PHY=y +CONFIG_DWC_ETH_QOS=y +CONFIG_GMAC_ROCKCHIP=y +CONFIG_NVME=y +CONFIG_PCI=y +CONFIG_DM_PCI=y +CONFIG_DM_PCI_COMPAT=y +CONFIG_PCIE_DW_ROCKCHIP=y +CONFIG_PHY_ROCKCHIP_INNO_USB2=y +CONFIG_PHY_ROCKCHIP_NANENG_COMBOPHY=y +CONFIG_PHY_ROCKCHIP_NANENG_EDP=y +CONFIG_PHY_ROCKCHIP_SNPS_PCIE3=y +CONFIG_PINCTRL=y +CONFIG_SPL_PINCTRL=y +CONFIG_DM_FUEL_GAUGE=y +CONFIG_POWER_FG_RK817=y +CONFIG_IO_DOMAIN=y +CONFIG_ROCKCHIP_IO_DOMAIN=y +CONFIG_DM_PMIC=y +CONFIG_PMIC_RK8XX=y +CONFIG_REGULATOR_FAN53555=y +CONFIG_REGULATOR_PWM=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_DM_REGULATOR_GPIO=y +CONFIG_REGULATOR_RK8XX=y +CONFIG_DM_CHARGE_DISPLAY=y +CONFIG_CHARGE_ANIMATION=y +CONFIG_PWM_ROCKCHIP=y +CONFIG_RAM=y +CONFIG_SPL_RAM=y +CONFIG_TPL_RAM=y +CONFIG_DM_RAMDISK=y +CONFIG_RAMDISK_RO=y +CONFIG_DM_DMC=y +CONFIG_ROCKCHIP_DMC_FSP=y +CONFIG_ROCKCHIP_SDRAM_COMMON=y +CONFIG_ROCKCHIP_TPL_INIT_DRAM_TYPE=0 +CONFIG_DM_RESET=y +CONFIG_SPL_DM_RESET=y +CONFIG_SPL_RESET_ROCKCHIP=y +CONFIG_BAUDRATE=115200 +CONFIG_DEBUG_UART_BASE=0xFE660000 +CONFIG_DEBUG_UART_CLOCK=24000000 +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_ROCKCHIP_SFC=y +CONFIG_SYSRESET=y +CONFIG_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_DWC3=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_GENERIC=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_GENERIC=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_GADGET=y +CONFIG_USB_DWC3_GENERIC=y +CONFIG_USB_STORAGE=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_MANUFACTURER="Rockchip" +CONFIG_USB_GADGET_VENDOR_NUM=0x2207 +CONFIG_USB_GADGET_PRODUCT_NUM=0x350a +CONFIG_USB_GADGET_DOWNLOAD=y +CONFIG_DM_VIDEO=y +CONFIG_DISPLAY=y +CONFIG_DRM_ROCKCHIP=y +CONFIG_DRM_ROCKCHIP_DW_HDMI=y +CONFIG_DRM_ROCKCHIP_INNO_MIPI_PHY=y +CONFIG_DRM_ROCKCHIP_INNO_VIDEO_COMBO_PHY=y +CONFIG_DRM_ROCKCHIP_DW_MIPI_DSI=y +CONFIG_DRM_ROCKCHIP_ANALOGIX_DP=y +CONFIG_DRM_ROCKCHIP_LVDS=y +CONFIG_DRM_ROCKCHIP_RGB=y +CONFIG_ROCKCHIP_CUBIC_LUT_SIZE=9 +CONFIG_LCD=y +CONFIG_USE_TINY_PRINTF=y +CONFIG_SPL_TINY_MEMSET=y +CONFIG_RSA=y +CONFIG_SPL_RSA=y +CONFIG_RSA_N_SIZE=0x200 +CONFIG_RSA_E_SIZE=0x10 +CONFIG_RSA_C_SIZE=0x20 +CONFIG_XBC=y +CONFIG_SHA512=y +CONFIG_LZ4=y +CONFIG_LZMA=y +CONFIG_SPL_GZIP=y +CONFIG_ERRNO_STR=y +# CONFIG_EFI_LOADER is not set +CONFIG_AVB_LIBAVB=y +CONFIG_AVB_LIBAVB_AB=y +CONFIG_AVB_LIBAVB_ATX=y +CONFIG_AVB_LIBAVB_USER=y +CONFIG_RK_AVB_LIBAVB_USER=y diff --git a/patch/u-boot/legacy/u-boot-radxa-rk35xx/dt/rk3568-yy3568.dts b/patch/u-boot/legacy/u-boot-radxa-rk35xx/dt/rk3568-yy3568.dts new file mode 100644 index 000000000000..fa1f197e8b04 --- /dev/null +++ b/patch/u-boot/legacy/u-boot-radxa-rk35xx/dt/rk3568-yy3568.dts @@ -0,0 +1,494 @@ +/* + * SPDX-License-Identifier: GPL-2.0+ + * Copyright (c) 2020 Rockchip Electronics Co., Ltd. + * Copyright (c) 2024 Radxa Limited + */ + +/dts-v1/; +#include "rk3568.dtsi" +#include "rk3568-u-boot.dtsi" +#include + +/ { + model = "Youyeetoo YY3568"; + compatible = "youyeetoo,yy3568", "rockchip,rk3568"; + + vcc5v0_sys: vcc5v0-sys { + u-boot,dm-pre-reloc; + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + vcc3v3_sys: vcc3v3-sys { + u-boot,dm-pre-reloc; + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc5v0_sys>; + }; + + led_sys: led-sys { + u-boot,dm-pre-reloc; + compatible = "regulator-fixed"; + regulator-name = "led_sys"; + enable-active-high; + gpio = <&gpio0 RK_PC1 GPIO_ACTIVE_HIGH>; + regulator-boot-on; + regulator-always-on; + vin-supply = <&vcc3v3_sys>; + }; + + led_sys: led-sys { + u-boot,dm-pre-reloc; + compatible = "regulator-fixed"; + regulator-name = "led_sys"; + enable-active-high; + gpio = <&gpio0 RK_PC1 GPIO_ACTIVE_HIGH>; + regulator-boot-on; + regulator-always-on; + vin-supply = <&vcc3v3_sys>; + }; + + adc-keys { + compatible = "adc-keys"; + io-channels = <&saradc 0>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <1800000>; + u-boot,dm-spl; + status = "okay"; + + volumeup-key { + u-boot,dm-spl; + linux,code = ; + label = "volume up"; + press-threshold-microvolt = <9>; + }; + }; + + leds { + u-boot,dm-pre-reloc; + compatible = "gpio-leds"; + status = "okay"; + + blue-led { + u-boot,dm-pre-reloc; + label = "blue"; + gpios = <&gpio2 RK_PB2 GPIO_ACTIVE_HIGH>; + }; + }; +}; + +&gmac1 { + u-boot,dm-pre-reloc; + phy-mode = "rgmii"; + clock_in_out = "output"; + + snps,reset-gpio = <&gpio2 RK_PD1 GPIO_ACTIVE_LOW>; + snps,reset-active-low; + /* Reset time is 20ms, 100ms for rtl8211f */ + snps,reset-delays-us = <0 20000 100000>; + + assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>; + assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>; + assigned-clock-rates = <0>, <125000000>; + + pinctrl-names = "default"; + pinctrl-0 = <&gmac1m1_miim + &gmac1m1_tx_bus2 + &gmac1m1_rx_bus2 + &gmac1m1_rgmii_clk + &gmac1m1_rgmii_bus>; + + tx_delay = <0x44>; + rx_delay = <0x26>; + + phy-handle = <&rgmii_phy1>; + status = "disabled"; +}; + +&mdio1 { + rgmii_phy1: phy@0 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0x0>; + }; +}; + +&crypto { + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&pmu_io_domains { + status = "okay"; + pmuio2-supply = <&vcc_3v3>; + vccio1-supply = <&vccio_acodec>; + vccio3-supply = <&vccio_sd>; + vccio4-supply = <&vcc_1v8>; + vccio5-supply = <&vcc_3v3>; + vccio6-supply = <&vcc_1v8>; + vccio7-supply = <&vcc_3v3>; + u-boot,dm-pre-reloc; +}; + +&gpio0 { + u-boot,dm-pre-reloc; +}; + +&gpio4 { + u-boot,dm-pre-reloc; +}; + +&i2c0 { + status = "okay"; + u-boot,dm-pre-reloc; + clock-frequency = <100000>; + + vdd_cpu: tcs4525@1c { + u-boot,dm-pre-reloc; + compatible = "tcs,tcs452x"; + reg = <0x1c>; + vin-supply = <&vcc5v0_sys>; + regulator-compatible = "fan53555-reg"; + regulator-name = "vdd_cpu"; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1390000>; + regulator-init-microvolt = <900000>; + regulator-ramp-delay = <2300>; + fcs,suspend-voltage-selector = <1>; + regulator-boot-on; + regulator-always-on; + regulator-state-mem { + u-boot,dm-pre-reloc; + regulator-off-in-suspend; + }; + }; + + rk809: pmic@20 { + u-boot,dm-pre-reloc; + status = "okay"; + compatible = "rockchip,rk809"; + reg = <0x20>; + interrupt-parent = <&gpio0>; + interrupts = <3 IRQ_TYPE_LEVEL_LOW>; + + pinctrl-names = "default", "pmic-sleep", + "pmic-power-off", "pmic-reset"; + pinctrl-0 = <&pmic_int>; + pinctrl-1 = <&soc_slppin_slp>, <&rk817_slppin_slp>; + pinctrl-2 = <&soc_slppin_gpio>, <&rk817_slppin_pwrdn>; + pinctrl-3 = <&soc_slppin_gpio>, <&rk817_slppin_rst>; + + rockchip,system-power-controller; + wakeup-source; + #clock-cells = <1>; + clock-output-names = "rk808-clkout1", "rk808-clkout2"; + //fb-inner-reg-idxs = <2>; + /* 1: rst regs (default in codes), 0: rst the pmic */ + pmic-reset-func = <0>; + /* not save the PMIC_POWER_EN register in uboot */ + not-save-power-en = <1>; + + vcc1-supply = <&vcc3v3_sys>; + vcc2-supply = <&vcc3v3_sys>; + vcc3-supply = <&vcc3v3_sys>; + vcc4-supply = <&vcc3v3_sys>; + vcc5-supply = <&vcc3v3_sys>; + vcc6-supply = <&vcc3v3_sys>; + vcc7-supply = <&vcc3v3_sys>; + vcc8-supply = <&vcc3v3_sys>; + vcc9-supply = <&vcc3v3_sys>; + + pwrkey { + status = "okay"; + u-boot,dm-pre-reloc; + }; + + pinctrl_rk8xx: pinctrl_rk8xx { + u-boot,dm-pre-reloc; + gpio-controller; + #gpio-cells = <2>; + + rk817_slppin_null: rk817_slppin_null { + pins = "gpio_slp"; + function = "pin_fun0"; + u-boot,dm-pre-reloc; + }; + + rk817_slppin_slp: rk817_slppin_slp { + pins = "gpio_slp"; + function = "pin_fun1"; + u-boot,dm-pre-reloc; + }; + + rk817_slppin_pwrdn: rk817_slppin_pwrdn { + pins = "gpio_slp"; + function = "pin_fun2"; + u-boot,dm-pre-reloc; + }; + + rk817_slppin_rst: rk817_slppin_rst { + pins = "gpio_slp"; + function = "pin_fun3"; + u-boot,dm-pre-reloc; + }; + }; + + regulators { + u-boot,dm-pre-reloc; + vdd_logic: DCDC_REG1 { + u-boot,dm-pre-reloc; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1350000>; + regulator-init-microvolt = <900000>; + regulator-ramp-delay = <6001>; + regulator-initial-mode = <0x2>; + regulator-name = "vdd_logic"; + regulator-state-mem { + u-boot,dm-pre-reloc; + regulator-on-in-suspend; + }; + }; + + vdd_gpu: DCDC_REG2 { + u-boot,dm-pre-reloc; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1350000>; + regulator-init-microvolt = <900000>; + regulator-ramp-delay = <6001>; + regulator-initial-mode = <0x2>; + regulator-name = "vdd_gpu"; + regulator-state-mem { + u-boot,dm-pre-reloc; + regulator-on-in-suspend; + }; + }; + + vcc_ddr: DCDC_REG3 { + u-boot,dm-pre-reloc; + regulator-always-on; + regulator-boot-on; + regulator-initial-mode = <0x2>; + regulator-name = "vcc_ddr"; + regulator-state-mem { + u-boot,dm-pre-reloc; + regulator-on-in-suspend; + }; + }; + + vdd_npu: DCDC_REG4 { + u-boot,dm-pre-reloc; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1350000>; + regulator-init-microvolt = <900000>; + regulator-ramp-delay = <6001>; + regulator-initial-mode = <0x2>; + regulator-name = "vdd_npu"; + regulator-state-mem { + u-boot,dm-pre-reloc; + regulator-on-in-suspend; + }; + }; + + vdda0v9_image: LDO_REG1 { + u-boot,dm-pre-reloc; + regulator-boot-on; + regulator-always-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + regulator-name = "vdda0v9_image"; + regulator-state-mem { + u-boot,dm-pre-reloc; + regulator-off-in-suspend; + }; + }; + + vdda_0v9: LDO_REG2 { + u-boot,dm-pre-reloc; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + regulator-name = "vdda_0v9"; + regulator-state-mem { + u-boot,dm-pre-reloc; + regulator-off-in-suspend; + }; + }; + + vdda0v9_pmu: LDO_REG3 { + u-boot,dm-pre-reloc; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + regulator-name = "vdda0v9_pmu"; + regulator-state-mem { + u-boot,dm-pre-reloc; + regulator-on-in-suspend; + regulator-suspend-microvolt = <900000>; + }; + }; + + vccio_acodec: LDO_REG4 { + u-boot,dm-pre-reloc; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vccio_acodec"; + regulator-state-mem { + u-boot,dm-pre-reloc; + regulator-off-in-suspend; + }; + }; + + vccio_sd: LDO_REG5 { + u-boot,dm-pre-reloc; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vccio_sd"; + regulator-state-mem { + u-boot,dm-pre-reloc; + regulator-off-in-suspend; + }; + }; + + vcc3v3_pmu: LDO_REG6 { + u-boot,dm-pre-reloc; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc3v3_pmu"; + regulator-state-mem { + u-boot,dm-pre-reloc; + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcca_1v8: LDO_REG7 { + u-boot,dm-pre-reloc; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcca_1v8"; + regulator-state-mem { + u-boot,dm-pre-reloc; + regulator-off-in-suspend; + }; + }; + + vcca1v8_pmu: LDO_REG8 { + u-boot,dm-pre-reloc; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcca1v8_pmu"; + regulator-state-mem { + u-boot,dm-pre-reloc; + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcca1v8_image: LDO_REG9 { + u-boot,dm-pre-reloc; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcca1v8_image"; + regulator-state-mem { + u-boot,dm-pre-reloc; + regulator-off-in-suspend; + }; + }; + + vcc_1v8: DCDC_REG5 { + u-boot,dm-pre-reloc; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc_1v8"; + regulator-state-mem { + u-boot,dm-pre-reloc; + regulator-off-in-suspend; + }; + }; + + vcc_3v3: SWITCH_REG1 { + u-boot,dm-pre-reloc; + regulator-always-on; + regulator-boot-on; + regulator-name = "vcc_3v3"; + regulator-state-mem { + u-boot,dm-pre-reloc; + regulator-off-in-suspend; + }; + }; + + vcc3v3_sd: SWITCH_REG2 { + u-boot,dm-pre-reloc; + regulator-always-on; + regulator-boot-on; + regulator-name = "vcc3v3_sd"; + regulator-state-mem { + u-boot,dm-pre-reloc; + regulator-off-in-suspend; + }; + }; + }; + }; +}; + +&pinctrl { + u-boot,dm-spl; + pmic { + u-boot,dm-pre-reloc; + pmic_int: pmic_int { + u-boot,dm-pre-reloc; + rockchip,pins = + <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + soc_slppin_gpio: soc_slppin_gpio { + u-boot,dm-pre-reloc; + rockchip,pins = + <0 RK_PA2 RK_FUNC_GPIO &pcfg_output_low_pull_down>; + }; + + soc_slppin_slp: soc_slppin_slp { + u-boot,dm-pre-reloc; + rockchip,pins = + <0 RK_PA2 RK_FUNC_1 &pcfg_pull_up>; + }; + + soc_slppin_rst: soc_slppin_rst { + u-boot,dm-pre-reloc; + rockchip,pins = + <0 RK_PA2 RK_FUNC_2 &pcfg_pull_none>; + }; + }; +}; \ No newline at end of file From 1cbf6cd88813e84d6a443a728861da975938e657 Mon Sep 17 00:00:00 2001 From: Nicolas Pereira <41456803+hqnicolas@users.noreply.github.com> Date: Tue, 4 Mar 2025 08:54:25 -0300 Subject: [PATCH 02/37] rockchip64-edge: add support for yy3568 --- .../rockchip64-6.12/board-yy3568.patch | 990 ------------------ 1 file changed, 990 deletions(-) delete mode 100644 patch/kernel/archive/rockchip64-6.12/board-yy3568.patch diff --git a/patch/kernel/archive/rockchip64-6.12/board-yy3568.patch b/patch/kernel/archive/rockchip64-6.12/board-yy3568.patch deleted file mode 100644 index 37958454f10d..000000000000 --- a/patch/kernel/archive/rockchip64-6.12/board-yy3568.patch +++ /dev/null @@ -1,990 +0,0 @@ -From a796d047927ed8db448a002bf390d5dc94fc155b Mon Sep 17 00:00:00 2001 -From: From: Nicolas Pereira -Date: Sun, 8 Oct 2023 14:16:45 +0300 -Subject: [PATCH] Add YY3568 support for mainline - ---- - arch/arm/dts/rk3568-yy3568.dts | 732 ++++++++++++++++++++++++++++++ - configs/yy3568-rk3568_defconfig | 232 ++++++++++++++ - 2 files changed, 964 insertions(+) - create mode 100644 arch/arm/dts/rk3568-yy3568.dts - create mode 100644 configs/yy3568-rk3568_defconfig - -diff --git a/arch/arm64/boot/dts/rockchip/rk3568-yy3568.dts b/arch/arm64/boot/dts/rockchip/rk3568-yy3568.dts -new file mode 100644 -index 0000000000..e32c83f8fb ---- /dev/null -+++ b/arch/arm64/boot/dts/rockchip/rk3568-yy3568.dts -@@ -0,0 +1,732 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Copyright (c) 2020 Rockchip Electronics Co., Ltd. -+ * -+ */ -+/dts-v1/; -+ -+#include -+#include -+#include -+#include -+#include "rk3568.dtsi" -+ -+/ { -+ model = "Youyeetoo YY3568"; -+ compatible = "youyeetoo,yy3568", "rockchip,rk3568"; -+ -+ aliases { -+ ethernet0 = &gmac0; -+ ethernet1 = &gmac1; -+ mmc2 = &sdmmc2; -+ mmc1 = &sdmmc0; -+ mmc0 = &sdhci; -+ }; -+ -+ gpio-leds { -+ compatible = "gpio-leds"; -+ -+ led_user: led-0 { -+ gpios = <&gpio3 RK_PA4 GPIO_ACTIVE_HIGH>; -+ linux,default-trigger = "heartbeat"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&led_user_en>; -+ }; -+ led_power: led-1 { -+ gpios = <&gpio2 RK_PB2 GPIO_ACTIVE_HIGH>; -+ linux,default-trigger = "heartbeat"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&led_power_en>; -+ }; -+ }; -+ -+ hdmi-con { -+ compatible = "hdmi-connector"; -+ type = "a"; -+ -+ port { -+ hdmi_con_in: endpoint { -+ remote-endpoint = <&hdmi_out_con>; -+ }; -+ }; -+ }; -+ -+ rk809-sound { -+ compatible = "simple-audio-card"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&hp_det>; -+ hp-det-gpio = <&gpio3 RK_PC2 GPIO_ACTIVE_LOW>; -+ simple-audio-card,format = "i2s"; -+ simple-audio-card,name = "Analog RK809"; -+ simple-audio-card,mclk-fs = <256>; -+ -+ simple-audio-card,cpu { -+ sound-dai = <&i2s1_8ch>; -+ }; -+ simple-audio-card,codec { -+ sound-dai = <&rk809>; -+ }; -+ }; -+ -+ vcc5v0_otg: regulator-vbus-typec { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&vcc5v0_otg_en>; -+ regulator-name = "vcc5v0_otg"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ vin-supply = <&vcc5v0_sys>; -+ }; -+ -+ /* actually fed by vcc5v0_sys, dependent -+ * on pi6c clock generator -+ */ -+ -+ vcc5v0_host: vcc5v0-host-regulator { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&vcc5v0_host_en>; -+ regulator-name = "vcc5v0_host"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ vin-supply = <&vcc5v0_sys>; -+ }; -+ -+ vcc3v3_pcie30x1: regulator-vcc3v3-pcie30x1 { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie30x1_enable_h>; -+ regulator-name = "vcc3v3_pcie30x1"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ vin-supply = <&vcc5v0_sys>; -+ }; -+ -+ vcc3v3_pi6c_05: regulator-vcc3v3-pi6c-05 { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpios = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie_enable_h>; -+ regulator-name = "vcc3v3_pcie"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ vin-supply = <&vcc5v0_sys>; -+ }; -+ -+ pcie30_avdd0v9: regulator-pcie30-avdd0v9 { -+ compatible = "regulator-fixed"; -+ regulator-name = "pcie30_avdd0v9"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <900000>; -+ vin-supply = <&vcc3v3_sys>; -+ }; -+ -+ pcie30_avdd1v8: regulator-pcie30-avdd1v8 { -+ compatible = "regulator-fixed"; -+ regulator-name = "pcie30_avdd1v8"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ vin-supply = <&vcc3v3_sys>; -+ }; -+ -+ vcc3v3_sys: regulator-vcc3v3-sys { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc3v3_sys"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ vin-supply = <&vcc12v_input>; -+ }; -+ -+ vcc5v0_sys: regulator-vcc5v0-sys { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc5v0_sys"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ vin-supply = <&vcc12v_input>; -+ }; -+ -+ /* labeled +12v_input in schematic */ -+ vcc12v_input: regulator-vcc5v-input { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc12v_input"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <12000000>; -+ regulator-max-microvolt = <12000000>; -+ }; -+}; -+ -+&combphy1 { -+ phy-supply = <&vcc3v3_pcie30x1>; -+ status = "okay"; -+}; -+ -+&combphy0 { -+ status = "okay"; -+}; -+ -+&combphy2 { -+ status = "okay"; -+}; -+ -+&cpu0 { -+ cpu-supply = <&vdd_cpu>; -+}; -+ -+&cpu1 { -+ cpu-supply = <&vdd_cpu>; -+}; -+ -+&cpu2 { -+ cpu-supply = <&vdd_cpu>; -+}; -+ -+&cpu3 { -+ cpu-supply = <&vdd_cpu>; -+}; -+ -+&gpu { -+ mali-supply = <&vdd_gpu>; -+ status = "okay"; -+}; -+ -+&vop { -+ assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>; -+ assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>; -+ status = "okay"; -+}; -+ -+&vop_mmu { -+ status = "okay"; -+}; -+ -+&vp0 { -+ vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 { -+ reg = ; -+ remote-endpoint = <&hdmi_in_vp0>; -+ }; -+}; -+ -+&hdmi { -+ assigned-clocks = <&cru CLK_HDMI_CEC>; -+ assigned-clock-rates = <32768>; -+ avdd-0v9-supply = <&vdda0v9_image>; -+ avdd-1v8-supply = <&vcca1v8_image>; -+ status = "okay"; -+}; -+ -+&hdmi_in { -+ hdmi_in_vp0: endpoint { -+ remote-endpoint = <&vp0_out_hdmi>; -+ }; -+}; -+ -+&hdmi_out { -+ hdmi_out_con: endpoint { -+ remote-endpoint = <&hdmi_con_in>; -+ }; -+}; -+ -+&hdmi_sound { -+ status = "okay"; -+}; -+ -+&hdmi_sound { -+ status = "okay"; -+}; -+ -+&pcie2x1 { -+ pinctrl-names = "default"; -+ reset-gpios = <&gpio1 RK_PB2 GPIO_ACTIVE_HIGH>; -+ vpcie3v3-supply = <&vcc3v3_pi6c_05>; -+ status = "okay"; -+}; -+ -+&pcie30phy { -+ data-lanes = <1 2>; -+ status = "okay"; -+}; -+ -+&pcie3x2 { -+ num-lanes = <1>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie30x2_reset_h>; -+ reset-gpios = <&gpio2 RK_PD6 GPIO_ACTIVE_HIGH>; -+ vpcie3v3-supply = <&vcc3v3_pi6c_05>; -+ status = "okay"; -+}; -+ -+&i2c0 { -+ status = "okay"; -+ -+ vdd_cpu: regulator@1c { -+ compatible = "tcs,tcs4525"; -+ reg = <0x1c>; -+ fcs,suspend-voltage-selector = <1>; -+ regulator-name = "vdd_cpu"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <800000>; -+ regulator-max-microvolt = <1150000>; -+ regulator-ramp-delay = <2300>; -+ vin-supply = <&vcc12v_input>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ rk809: pmic@20 { -+ compatible = "rockchip,rk809"; -+ reg = <0x20>; -+ interrupt-parent = <&gpio0>; -+ interrupts = ; -+ #clock-cells = <1>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pmic_int>; -+ system-power-controller; -+ wakeup-source; -+ -+ vcc1-supply = <&vcc3v3_sys>; -+ vcc2-supply = <&vcc3v3_sys>; -+ vcc3-supply = <&vcc3v3_sys>; -+ vcc4-supply = <&vcc3v3_sys>; -+ vcc5-supply = <&vcc3v3_sys>; -+ vcc6-supply = <&vcc3v3_sys>; -+ vcc7-supply = <&vcc3v3_sys>; -+ vcc8-supply = <&vcc3v3_sys>; -+ vcc9-supply = <&vcc3v3_sys>; -+ -+ regulators { -+ vdd_logic: DCDC_REG1 { -+ regulator-name = "vdd_logic"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-initial-mode = <0x2>; -+ regulator-min-microvolt = <500000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-ramp-delay = <6001>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdd_gpu: DCDC_REG2 { -+ regulator-name = "vdd_gpu"; -+ regulator-always-on; -+ regulator-initial-mode = <0x2>; -+ regulator-min-microvolt = <500000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-ramp-delay = <6001>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_ddr: DCDC_REG3 { -+ regulator-name = "vcc_ddr"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-initial-mode = <0x2>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ vdd_npu: DCDC_REG4 { -+ regulator-name = "vdd_npu"; -+ regulator-initial-mode = <0x2>; -+ regulator-min-microvolt = <500000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-ramp-delay = <6001>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_1v8: DCDC_REG5 { -+ regulator-name = "vcc_1v8"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdda0v9_image: LDO_REG1 { -+ regulator-name = "vdda0v9_image"; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <900000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdda_0v9: LDO_REG2 { -+ regulator-name = "vdda_0v9"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <900000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdda0v9_pmu: LDO_REG3 { -+ regulator-name = "vdda0v9_pmu"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <900000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <900000>; -+ }; -+ }; -+ -+ vccio_acodec: LDO_REG4 { -+ regulator-name = "vccio_acodec"; -+ regulator-always-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vccio_sd: LDO_REG5 { -+ regulator-name = "vccio_sd"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <3300000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc3v3_pmu: LDO_REG6 { -+ regulator-name = "vcc3v3_pmu"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <3300000>; -+ }; -+ }; -+ -+ vcca_1v8: LDO_REG7 { -+ regulator-name = "vcca_1v8"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcca1v8_pmu: LDO_REG8 { -+ regulator-name = "vcca1v8_pmu"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ vcca1v8_image: LDO_REG9 { -+ regulator-name = "vcca1v8_image"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_3v3: SWITCH_REG1 { -+ regulator-name = "vcc_3v3"; -+ regulator-always-on; -+ regulator-boot-on; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc3v3_sd: SWITCH_REG2 { -+ regulator-name = "vcc3v3_sd"; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ }; -+ }; -+}; -+ -+&pinctrl { -+ leds { -+ led_user_en: led_user_en { -+ rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ led_power_en: led_power_en { -+ rockchip,pins = <2 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ headphone { -+ hp_det: hp-det { -+ rockchip,pins = <3 RK_PC2 RK_FUNC_GPIO &pcfg_pull_down>; -+ }; -+ }; -+ -+ pmic { -+ pmic_int: pmic_int { -+ rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; -+ -+ pcie { -+ pcie30x1_enable_h: pcie30x1-enable-h { -+ rockchip,pins = <0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ pcie30x2_reset_h: pcie30x2-reset-h { -+ rockchip,pins = <2 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ pcie_enable_h: pcie-enable-h { -+ rockchip,pins = <0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ usb { -+ vcc5v0_host_en: vcc5v0-host-en { -+ rockchip,pins = <0 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ vcc5v0_otg_en: vcc5v0_otg_en { -+ rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+}; -+ -+&i2s1_8ch { -+ rockchip,trcm-sync-tx-only; -+ status = "okay"; -+}; -+ -+&pmu_io_domains { -+ pmuio1-supply = <&vcc3v3_pmu>; -+ pmuio2-supply = <&vcc3v3_pmu>; -+ vccio1-supply = <&vccio_acodec>; -+ vccio2-supply = <&vcc_1v8>; -+ vccio3-supply = <&vccio_sd>; -+ vccio4-supply = <&vcc_1v8>; -+ vccio5-supply = <&vcc_3v3>; -+ vccio6-supply = <&vcc_1v8>; -+ vccio7-supply = <&vcc_3v3>; -+ status = "okay"; -+}; -+ -+&saradc { -+ vref-supply = <&vcca_1v8>; -+ status = "okay"; -+}; -+ -+&sdhci { -+ bus-width = <8>; -+ max-frequency = <200000000>; -+ non-removable; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>; -+ vmmc-supply = <&vcc_3v3>; -+ vqmmc-supply = <&vcc_1v8>; -+ status = "okay"; -+}; -+ -+&tsadc { -+ rockchip,hw-tshut-mode = <1>; -+ rockchip,hw-tshut-polarity = <0>; -+ status = "okay"; -+}; -+ -+&uart2 { -+ status = "okay"; -+}; -+ -+&sdmmc0 { -+ bus-width = <4>; -+ cap-sd-highspeed; -+ cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; -+ /* Also used in pcie30x1_clkreqnm0 */ -+ disable-wp; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd>; -+ sd-uhs-sdr104; -+ vmmc-supply = <&vcc3v3_sd>; -+ vqmmc-supply = <&vccio_sd>; -+ status = "okay"; -+}; -+ -+&sdmmc2 { -+ bus-width = <4>; -+ cap-sd-highspeed; -+ cd-gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_LOW>; -+ disable-wp; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdmmc2m0_bus4 &sdmmc2m0_clk &sdmmc2m0_cmd>; -+ sd-uhs-sdr104; -+ status = "okay"; -+}; -+ -+&mdio0 { -+ rgmii_phy0: ethernet-phy@0 { -+ compatible = "ethernet-phy-id001c.c916"; -+ reg = <0x0>; -+ reset-assert-us = <20000>; -+ reset-deassert-us = <100000>; -+ reset-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_LOW>; -+ }; -+}; -+ -+&mdio1 { -+ rgmii_phy1: ethernet-phy@0 { -+ compatible = "ethernet-phy-id001c.c916"; -+ reg = <0x0>; -+ reset-assert-us = <20000>; -+ reset-deassert-us = <100000>; -+ reset-gpios = <&gpio2 RK_PD1 GPIO_ACTIVE_LOW>; -+ }; -+}; -+ -+&gmac0 { -+ assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>; -+ assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>; -+ assigned-clock-rates = <0>, <125000000>; -+ clock_in_out = "output"; -+ phy-handle = <&rgmii_phy0>; -+ phy-mode = "rgmii"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&gmac0_miim -+ &gmac0_tx_bus2 -+ &gmac0_rx_bus2 -+ &gmac0_rgmii_clk -+ &gmac0_rgmii_bus>; -+ status = "okay"; -+}; -+ -+&gmac1 { -+ assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>; -+ assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>; -+ assigned-clock-rates = <0>, <125000000>; -+ clock_in_out = "output"; -+ phy-handle = <&rgmii_phy1>; -+ phy-mode = "rgmii"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&gmac1m1_miim -+ &gmac1m1_tx_bus2 -+ &gmac1m1_rx_bus2 -+ &gmac1m1_rgmii_clk -+ &gmac1m1_rgmii_bus>; -+ status = "okay"; -+}; -+ -+&usb_host0_ehci { -+ status = "okay"; -+}; -+ -+&usb_host0_ohci { -+ status = "okay"; -+}; -+ -+&usb_host0_xhci { -+ dr_mode = "host"; -+ extcon = <&usb2phy0>; -+ status = "okay"; -+}; -+ -+&usb_host1_ehci { -+ status = "okay"; -+}; -+ -+&usb_host1_ohci { -+ status = "okay"; -+}; -+ -+&usb_host1_xhci { -+ status = "okay"; -+}; -+ -+&usb2phy0 { -+ status = "okay"; -+}; -+ -+&usb2phy0_host { -+ phy-supply = <&vcc5v0_host>; -+ status = "okay"; -+}; -+ -+&usb2phy1 { -+ status = "okay"; -+}; -+ -+&usb2phy1_host { -+ phy-supply = <&vcc5v0_host>; -+ status = "okay"; -+}; -+ -+&usb2phy1_otg { -+ phy-supply = <&vcc5v0_host>; -+ status = "okay"; -+}; -+ -+&usb2phy1 { -+ status = "okay"; -+}; -+ -+&usb2phy1_host { -+ phy-supply = <&vcc5v0_otg>; -+ status = "okay"; -+}; -+ -+&usb2phy1_otg { -+ phy-supply = <&vcc5v0_otg>; -+ status = "okay"; -+}; -diff --git a/configs/yy3568-rk3568_defconfig b/configs/yy3568-rk3568_defconfig -new file mode 100644 -index 0000000000..23f9251bb2 ---- /dev/null -+++ b/configs/yy3568-rk3568_defconfig -@@ -0,0 +1,232 @@ -+CONFIG_ARM=y -+CONFIG_ARCH_ROCKCHIP=y -+CONFIG_SPL_LIBCOMMON_SUPPORT=y -+CONFIG_SPL_LIBGENERIC_SUPPORT=y -+CONFIG_SYS_MALLOC_F_LEN=0x80000 -+CONFIG_SPL_FIT_GENERATOR="arch/arm/mach-rockchip/make_fit_atf.sh" -+CONFIG_ROCKCHIP_RK3568=y -+CONFIG_ROCKCHIP_FIT_IMAGE=y -+CONFIG_ROCKCHIP_VENDOR_PARTITION=y -+CONFIG_ROCKCHIP_FIT_IMAGE_PACK=y -+CONFIG_ROCKCHIP_NEW_IDB=y -+CONFIG_SPL_SERIAL_SUPPORT=y -+CONFIG_SPL_DRIVERS_MISC_SUPPORT=y -+CONFIG_TARGET_EVB_RK3568=y -+CONFIG_SPL_LIBDISK_SUPPORT=y -+CONFIG_SPL_NAND_SUPPORT=y -+CONFIG_SPL_SPI_FLASH_SUPPORT=y -+CONFIG_SPL_SPI_SUPPORT=y -+CONFIG_DEFAULT_DEVICE_TREE="rk3568-yy3568" -+CONFIG_DEBUG_UART=y -+CONFIG_FIT=y -+CONFIG_FIT_IMAGE_POST_PROCESS=y -+CONFIG_FIT_HW_CRYPTO=y -+CONFIG_SPL_LOAD_FIT=y -+CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y -+CONFIG_SPL_FIT_HW_CRYPTO=y -+# CONFIG_SPL_SYS_DCACHE_OFF is not set -+CONFIG_BOOTDELAY=0 -+CONFIG_SARADC_ROCKCHIP=y -+CONFIG_SYS_CONSOLE_INFO_QUIET=y -+# CONFIG_DISPLAY_CPUINFO is not set -+CONFIG_ANDROID_BOOTLOADER=y -+CONFIG_ANDROID_AVB=y -+CONFIG_ANDROID_BOOT_IMAGE_HASH=y -+CONFIG_SPL_BOARD_INIT=y -+# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set -+# CONFIG_SPL_LEGACY_IMAGE_SUPPORT is not set -+CONFIG_SPL_SEPARATE_BSS=y -+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION=y -+CONFIG_SPL_SHA256_SUPPORT=y -+CONFIG_SPL_CRYPTO_SUPPORT=y -+CONFIG_SPL_HASH_SUPPORT=y -+CONFIG_SPL_MMC_WRITE=y -+CONFIG_SPL_MTD_SUPPORT=y -+CONFIG_SPL_MTD_WRITE=y -+CONFIG_SPL_ATF=y -+CONFIG_SPL_ATF_NO_PLATFORM_PARAM=y -+CONFIG_SPL_AB=y -+CONFIG_FASTBOOT_BUF_ADDR=0xc00800 -+CONFIG_FASTBOOT_BUF_SIZE=0x04000000 -+CONFIG_FASTBOOT_FLASH=y -+CONFIG_FASTBOOT_FLASH_MMC_DEV=0 -+CONFIG_CMD_BOOTZ=y -+CONFIG_CMD_DTIMG=y -+# CONFIG_CMD_ELF is not set -+# CONFIG_CMD_IMI is not set -+# CONFIG_CMD_IMLS is not set -+# CONFIG_CMD_XIMG is not set -+# CONFIG_CMD_LZMADEC is not set -+# CONFIG_CMD_UNZIP is not set -+# CONFIG_CMD_FLASH is not set -+# CONFIG_CMD_FPGA is not set -+CONFIG_CMD_GPT=y -+# CONFIG_CMD_LOADB is not set -+# CONFIG_CMD_LOADS is not set -+CONFIG_CMD_BOOT_ANDROID=y -+CONFIG_CMD_BOOT_ROCKCHIP=y -+CONFIG_CMD_MMC=y -+CONFIG_CMD_MTD=y -+CONFIG_CMD_NAND=y -+CONFIG_CMD_PCI=y -+CONFIG_CMD_USB=y -+CONFIG_CMD_USB_MASS_STORAGE=y -+# CONFIG_CMD_ITEST is not set -+# CONFIG_CMD_SETEXPR is not set -+CONFIG_CMD_TFTPPUT=y -+CONFIG_CMD_TFTP_BOOTM=y -+CONFIG_CMD_TFTP_FLASH=y -+# CONFIG_CMD_MISC is not set -+# CONFIG_CMD_CHARGE_DISPLAY is not set -+CONFIG_CMD_MTD_BLK=y -+# CONFIG_SPL_DOS_PARTITION is not set -+# CONFIG_ISO_PARTITION is not set -+CONFIG_EFI_PARTITION_ENTRIES_NUMBERS=64 -+CONFIG_SPL_OF_CONTROL=y -+CONFIG_SPL_DTB_MINIMUM=y -+CONFIG_OF_LIVE=y -+CONFIG_OF_SPL_REMOVE_PROPS="" -+# CONFIG_NET_TFTP_VARS is not set -+CONFIG_REGMAP=y -+CONFIG_SPL_REGMAP=y -+CONFIG_SYSCON=y -+CONFIG_SPL_SYSCON=y -+CONFIG_CLK=y -+CONFIG_SPL_CLK=y -+CONFIG_CLK_SCMI=y -+CONFIG_DM_CRYPTO=y -+CONFIG_SPL_DM_CRYPTO=y -+CONFIG_ROCKCHIP_CRYPTO_V2=y -+CONFIG_SPL_ROCKCHIP_CRYPTO_V2=y -+CONFIG_DM_RNG=y -+CONFIG_RNG_ROCKCHIP=y -+CONFIG_SCMI_FIRMWARE=y -+CONFIG_ROCKCHIP_GPIO=y -+CONFIG_ROCKCHIP_GPIO_V2=y -+CONFIG_SYS_I2C_ROCKCHIP=y -+CONFIG_DM_KEY=y -+CONFIG_RK8XX_PWRKEY=y -+CONFIG_ADC_KEY=y -+CONFIG_MISC=y -+CONFIG_SPL_MISC=y -+CONFIG_ROCKCHIP_OTP=y -+CONFIG_SPL_ROCKCHIP_SECURE_OTP=y -+CONFIG_MMC_DW=y -+CONFIG_MMC_DW_ROCKCHIP=y -+CONFIG_MMC_SDHCI=y -+CONFIG_MMC_SDHCI_SDMA=y -+CONFIG_MMC_SDHCI_ROCKCHIP=y -+CONFIG_MTD=y -+CONFIG_MTD_BLK=y -+CONFIG_MTD_DEVICE=y -+CONFIG_NAND=y -+CONFIG_NAND_ROCKCHIP_V9=y -+CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y -+CONFIG_SYS_NAND_U_BOOT_OFFS=0x8000 -+CONFIG_SYS_NAND_U_BOOT_OFFS_REDUND=0x10000 -+CONFIG_MTD_SPI_NAND=y -+CONFIG_SPI_FLASH=y -+CONFIG_SF_DEFAULT_SPEED=20000000 -+CONFIG_SPI_FLASH_EON=y -+CONFIG_SPI_FLASH_GIGADEVICE=y -+CONFIG_SPI_FLASH_MACRONIX=y -+CONFIG_SPI_FLASH_WINBOND=y -+CONFIG_SPI_FLASH_XMC=y -+CONFIG_SPI_FLASH_MTD=y -+CONFIG_DM_ETH=y -+CONFIG_DM_ETH_PHY=y -+CONFIG_DWC_ETH_QOS=y -+CONFIG_GMAC_ROCKCHIP=y -+CONFIG_NVME=y -+CONFIG_PCI=y -+CONFIG_DM_PCI=y -+CONFIG_DM_PCI_COMPAT=y -+CONFIG_PCIE_DW_ROCKCHIP=y -+CONFIG_PHY_ROCKCHIP_INNO_USB2=y -+CONFIG_PHY_ROCKCHIP_NANENG_COMBOPHY=y -+CONFIG_PHY_ROCKCHIP_NANENG_EDP=y -+CONFIG_PHY_ROCKCHIP_SNPS_PCIE3=y -+CONFIG_PINCTRL=y -+CONFIG_SPL_PINCTRL=y -+CONFIG_DM_FUEL_GAUGE=y -+CONFIG_POWER_FG_RK817=y -+CONFIG_IO_DOMAIN=y -+CONFIG_ROCKCHIP_IO_DOMAIN=y -+CONFIG_DM_PMIC=y -+CONFIG_PMIC_RK8XX=y -+CONFIG_REGULATOR_FAN53555=y -+CONFIG_REGULATOR_PWM=y -+CONFIG_DM_REGULATOR_FIXED=y -+CONFIG_DM_REGULATOR_GPIO=y -+CONFIG_REGULATOR_RK8XX=y -+CONFIG_DM_CHARGE_DISPLAY=y -+CONFIG_CHARGE_ANIMATION=y -+CONFIG_PWM_ROCKCHIP=y -+CONFIG_RAM=y -+CONFIG_SPL_RAM=y -+CONFIG_TPL_RAM=y -+CONFIG_DM_RAMDISK=y -+CONFIG_RAMDISK_RO=y -+CONFIG_DM_DMC=y -+CONFIG_ROCKCHIP_DMC_FSP=y -+CONFIG_ROCKCHIP_SDRAM_COMMON=y -+CONFIG_ROCKCHIP_TPL_INIT_DRAM_TYPE=0 -+CONFIG_DM_RESET=y -+CONFIG_SPL_DM_RESET=y -+CONFIG_SPL_RESET_ROCKCHIP=y -+CONFIG_BAUDRATE=1500000 -+CONFIG_DEBUG_UART_BASE=0xFE660000 -+CONFIG_DEBUG_UART_CLOCK=24000000 -+CONFIG_DEBUG_UART_SHIFT=2 -+CONFIG_ROCKCHIP_SFC=y -+CONFIG_SYSRESET=y -+CONFIG_USB=y -+CONFIG_USB_XHCI_HCD=y -+CONFIG_USB_XHCI_DWC3=y -+CONFIG_USB_EHCI_HCD=y -+CONFIG_USB_EHCI_GENERIC=y -+CONFIG_USB_OHCI_HCD=y -+CONFIG_USB_OHCI_GENERIC=y -+CONFIG_USB_DWC3=y -+CONFIG_USB_DWC3_GADGET=y -+CONFIG_USB_DWC3_GENERIC=y -+CONFIG_USB_STORAGE=y -+CONFIG_USB_GADGET=y -+CONFIG_USB_GADGET_MANUFACTURER="Rockchip" -+CONFIG_USB_GADGET_VENDOR_NUM=0x2207 -+CONFIG_USB_GADGET_PRODUCT_NUM=0x350a -+CONFIG_USB_GADGET_DOWNLOAD=y -+CONFIG_DM_VIDEO=y -+CONFIG_DISPLAY=y -+CONFIG_DRM_ROCKCHIP=y -+CONFIG_DRM_ROCKCHIP_DW_HDMI=y -+CONFIG_DRM_ROCKCHIP_INNO_MIPI_PHY=y -+CONFIG_DRM_ROCKCHIP_INNO_VIDEO_COMBO_PHY=y -+CONFIG_DRM_ROCKCHIP_DW_MIPI_DSI=y -+CONFIG_DRM_ROCKCHIP_ANALOGIX_DP=y -+CONFIG_DRM_ROCKCHIP_LVDS=y -+CONFIG_DRM_ROCKCHIP_RGB=y -+CONFIG_ROCKCHIP_CUBIC_LUT_SIZE=9 -+CONFIG_LCD=y -+CONFIG_USE_TINY_PRINTF=y -+CONFIG_SPL_TINY_MEMSET=y -+CONFIG_RSA=y -+CONFIG_SPL_RSA=y -+CONFIG_RSA_N_SIZE=0x200 -+CONFIG_RSA_E_SIZE=0x10 -+CONFIG_RSA_C_SIZE=0x20 -+CONFIG_XBC=y -+CONFIG_SHA512=y -+CONFIG_LZ4=y -+CONFIG_LZMA=y -+CONFIG_SPL_GZIP=y -+CONFIG_ERRNO_STR=y -+# CONFIG_EFI_LOADER is not set -+CONFIG_AVB_LIBAVB=y -+CONFIG_AVB_LIBAVB_AB=y -+CONFIG_AVB_LIBAVB_ATX=y -+CONFIG_AVB_LIBAVB_USER=y -+CONFIG_RK_AVB_LIBAVB_USER=y -+CONFIG_OPTEE_CLIENT=y -+CONFIG_OPTEE_V2=y -+CONFIG_OPTEE_ALWAYS_USE_SECURITY_PARTITION=y --- -2.42.0 From f3ffd8d9583555e2c156beece41be0683083b55e Mon Sep 17 00:00:00 2001 From: Nicolas Pereira <41456803+hqnicolas@users.noreply.github.com> Date: Tue, 4 Mar 2025 08:55:02 -0300 Subject: [PATCH 03/37] rockchip64-edge: add support for yy3568 --- .../rockchip64-6.14/board-yy3568.patch | 990 ------------------ 1 file changed, 990 deletions(-) delete mode 100644 patch/kernel/archive/rockchip64-6.14/board-yy3568.patch diff --git a/patch/kernel/archive/rockchip64-6.14/board-yy3568.patch b/patch/kernel/archive/rockchip64-6.14/board-yy3568.patch deleted file mode 100644 index fa1964084bcf..000000000000 --- a/patch/kernel/archive/rockchip64-6.14/board-yy3568.patch +++ /dev/null @@ -1,990 +0,0 @@ -From a796d047927ed8db448a002bf390d5dc94fc155b Mon Sep 17 00:00:00 2001 -From: Nicolas Pereira -Date: Sun, 8 Oct 2023 14:16:45 +0300 -Subject: [PATCH] Add YY3568 support for mainline - ---- - arch/arm/dts/rk3568-yy3568.dts | 732 ++++++++++++++++++++++++++++++ - configs/yy3568-rk3568_defconfig | 232 ++++++++++++++ - 2 files changed, 964 insertions(+) - create mode 100644 arch/arm/dts/rk3568-yy3568.dts - create mode 100644 configs/yy3568-rk3568_defconfig - -diff --git a/arch/arm64/boot/dts/rockchip/rk3568-yy3568.dts b/arch/arm64/boot/dts/rockchip/rk3568-yy3568.dts -new file mode 100644 -index 0000000000..e32c83f8fb ---- /dev/null -+++ b/arch/arm64/boot/dts/rockchip/rk3568-yy3568.dts -@@ -0,0 +1,732 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Copyright (c) 2020 Rockchip Electronics Co., Ltd. -+ * -+ */ -+/dts-v1/; -+ -+#include -+#include -+#include -+#include -+#include "rk3568.dtsi" -+ -+/ { -+ model = "Youyeetoo YY3568"; -+ compatible = "youyeetoo,yy3568", "rockchip,rk3568"; -+ -+ aliases { -+ ethernet0 = &gmac0; -+ ethernet1 = &gmac1; -+ mmc2 = &sdmmc2; -+ mmc1 = &sdmmc0; -+ mmc0 = &sdhci; -+ }; -+ -+ gpio-leds { -+ compatible = "gpio-leds"; -+ -+ led_user: led-0 { -+ gpios = <&gpio3 RK_PA4 GPIO_ACTIVE_HIGH>; -+ linux,default-trigger = "heartbeat"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&led_user_en>; -+ }; -+ led_power: led-1 { -+ gpios = <&gpio2 RK_PB2 GPIO_ACTIVE_HIGH>; -+ linux,default-trigger = "heartbeat"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&led_power_en>; -+ }; -+ }; -+ -+ hdmi-con { -+ compatible = "hdmi-connector"; -+ type = "a"; -+ -+ port { -+ hdmi_con_in: endpoint { -+ remote-endpoint = <&hdmi_out_con>; -+ }; -+ }; -+ }; -+ -+ rk809-sound { -+ compatible = "simple-audio-card"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&hp_det>; -+ hp-det-gpio = <&gpio3 RK_PC2 GPIO_ACTIVE_LOW>; -+ simple-audio-card,format = "i2s"; -+ simple-audio-card,name = "Analog RK809"; -+ simple-audio-card,mclk-fs = <256>; -+ -+ simple-audio-card,cpu { -+ sound-dai = <&i2s1_8ch>; -+ }; -+ simple-audio-card,codec { -+ sound-dai = <&rk809>; -+ }; -+ }; -+ -+ vcc5v0_otg: regulator-vbus-typec { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&vcc5v0_otg_en>; -+ regulator-name = "vcc5v0_otg"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ vin-supply = <&vcc5v0_sys>; -+ }; -+ -+ /* actually fed by vcc5v0_sys, dependent -+ * on pi6c clock generator -+ */ -+ -+ vcc5v0_host: vcc5v0-host-regulator { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&vcc5v0_host_en>; -+ regulator-name = "vcc5v0_host"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ vin-supply = <&vcc5v0_sys>; -+ }; -+ -+ vcc3v3_pcie30x1: regulator-vcc3v3-pcie30x1 { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie30x1_enable_h>; -+ regulator-name = "vcc3v3_pcie30x1"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ vin-supply = <&vcc5v0_sys>; -+ }; -+ -+ vcc3v3_pi6c_05: regulator-vcc3v3-pi6c-05 { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpios = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie_enable_h>; -+ regulator-name = "vcc3v3_pcie"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ vin-supply = <&vcc5v0_sys>; -+ }; -+ -+ pcie30_avdd0v9: regulator-pcie30-avdd0v9 { -+ compatible = "regulator-fixed"; -+ regulator-name = "pcie30_avdd0v9"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <900000>; -+ vin-supply = <&vcc3v3_sys>; -+ }; -+ -+ pcie30_avdd1v8: regulator-pcie30-avdd1v8 { -+ compatible = "regulator-fixed"; -+ regulator-name = "pcie30_avdd1v8"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ vin-supply = <&vcc3v3_sys>; -+ }; -+ -+ vcc3v3_sys: regulator-vcc3v3-sys { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc3v3_sys"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ vin-supply = <&vcc12v_input>; -+ }; -+ -+ vcc5v0_sys: regulator-vcc5v0-sys { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc5v0_sys"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ vin-supply = <&vcc12v_input>; -+ }; -+ -+ /* labeled +12v_input in schematic */ -+ vcc12v_input: regulator-vcc5v-input { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc12v_input"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <12000000>; -+ regulator-max-microvolt = <12000000>; -+ }; -+}; -+ -+&combphy1 { -+ phy-supply = <&vcc3v3_pcie30x1>; -+ status = "okay"; -+}; -+ -+&combphy0 { -+ status = "okay"; -+}; -+ -+&combphy2 { -+ status = "okay"; -+}; -+ -+&cpu0 { -+ cpu-supply = <&vdd_cpu>; -+}; -+ -+&cpu1 { -+ cpu-supply = <&vdd_cpu>; -+}; -+ -+&cpu2 { -+ cpu-supply = <&vdd_cpu>; -+}; -+ -+&cpu3 { -+ cpu-supply = <&vdd_cpu>; -+}; -+ -+&gpu { -+ mali-supply = <&vdd_gpu>; -+ status = "okay"; -+}; -+ -+&vop { -+ assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>; -+ assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>; -+ status = "okay"; -+}; -+ -+&vop_mmu { -+ status = "okay"; -+}; -+ -+&vp0 { -+ vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 { -+ reg = ; -+ remote-endpoint = <&hdmi_in_vp0>; -+ }; -+}; -+ -+&hdmi { -+ assigned-clocks = <&cru CLK_HDMI_CEC>; -+ assigned-clock-rates = <32768>; -+ avdd-0v9-supply = <&vdda0v9_image>; -+ avdd-1v8-supply = <&vcca1v8_image>; -+ status = "okay"; -+}; -+ -+&hdmi_in { -+ hdmi_in_vp0: endpoint { -+ remote-endpoint = <&vp0_out_hdmi>; -+ }; -+}; -+ -+&hdmi_out { -+ hdmi_out_con: endpoint { -+ remote-endpoint = <&hdmi_con_in>; -+ }; -+}; -+ -+&hdmi_sound { -+ status = "okay"; -+}; -+ -+&hdmi_sound { -+ status = "okay"; -+}; -+ -+&pcie2x1 { -+ pinctrl-names = "default"; -+ reset-gpios = <&gpio1 RK_PB2 GPIO_ACTIVE_HIGH>; -+ vpcie3v3-supply = <&vcc3v3_pi6c_05>; -+ status = "okay"; -+}; -+ -+&pcie30phy { -+ data-lanes = <1 2>; -+ status = "okay"; -+}; -+ -+&pcie3x2 { -+ num-lanes = <1>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie30x2_reset_h>; -+ reset-gpios = <&gpio2 RK_PD6 GPIO_ACTIVE_HIGH>; -+ vpcie3v3-supply = <&vcc3v3_pi6c_05>; -+ status = "okay"; -+}; -+ -+&i2c0 { -+ status = "okay"; -+ -+ vdd_cpu: regulator@1c { -+ compatible = "tcs,tcs4525"; -+ reg = <0x1c>; -+ fcs,suspend-voltage-selector = <1>; -+ regulator-name = "vdd_cpu"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <800000>; -+ regulator-max-microvolt = <1150000>; -+ regulator-ramp-delay = <2300>; -+ vin-supply = <&vcc12v_input>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ rk809: pmic@20 { -+ compatible = "rockchip,rk809"; -+ reg = <0x20>; -+ interrupt-parent = <&gpio0>; -+ interrupts = ; -+ #clock-cells = <1>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pmic_int>; -+ system-power-controller; -+ wakeup-source; -+ -+ vcc1-supply = <&vcc3v3_sys>; -+ vcc2-supply = <&vcc3v3_sys>; -+ vcc3-supply = <&vcc3v3_sys>; -+ vcc4-supply = <&vcc3v3_sys>; -+ vcc5-supply = <&vcc3v3_sys>; -+ vcc6-supply = <&vcc3v3_sys>; -+ vcc7-supply = <&vcc3v3_sys>; -+ vcc8-supply = <&vcc3v3_sys>; -+ vcc9-supply = <&vcc3v3_sys>; -+ -+ regulators { -+ vdd_logic: DCDC_REG1 { -+ regulator-name = "vdd_logic"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-initial-mode = <0x2>; -+ regulator-min-microvolt = <500000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-ramp-delay = <6001>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdd_gpu: DCDC_REG2 { -+ regulator-name = "vdd_gpu"; -+ regulator-always-on; -+ regulator-initial-mode = <0x2>; -+ regulator-min-microvolt = <500000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-ramp-delay = <6001>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_ddr: DCDC_REG3 { -+ regulator-name = "vcc_ddr"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-initial-mode = <0x2>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ vdd_npu: DCDC_REG4 { -+ regulator-name = "vdd_npu"; -+ regulator-initial-mode = <0x2>; -+ regulator-min-microvolt = <500000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-ramp-delay = <6001>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_1v8: DCDC_REG5 { -+ regulator-name = "vcc_1v8"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdda0v9_image: LDO_REG1 { -+ regulator-name = "vdda0v9_image"; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <900000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdda_0v9: LDO_REG2 { -+ regulator-name = "vdda_0v9"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <900000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdda0v9_pmu: LDO_REG3 { -+ regulator-name = "vdda0v9_pmu"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <900000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <900000>; -+ }; -+ }; -+ -+ vccio_acodec: LDO_REG4 { -+ regulator-name = "vccio_acodec"; -+ regulator-always-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vccio_sd: LDO_REG5 { -+ regulator-name = "vccio_sd"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <3300000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc3v3_pmu: LDO_REG6 { -+ regulator-name = "vcc3v3_pmu"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <3300000>; -+ }; -+ }; -+ -+ vcca_1v8: LDO_REG7 { -+ regulator-name = "vcca_1v8"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcca1v8_pmu: LDO_REG8 { -+ regulator-name = "vcca1v8_pmu"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ vcca1v8_image: LDO_REG9 { -+ regulator-name = "vcca1v8_image"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_3v3: SWITCH_REG1 { -+ regulator-name = "vcc_3v3"; -+ regulator-always-on; -+ regulator-boot-on; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc3v3_sd: SWITCH_REG2 { -+ regulator-name = "vcc3v3_sd"; -+ -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ }; -+ }; -+}; -+ -+&pinctrl { -+ leds { -+ led_user_en: led_user_en { -+ rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ led_power_en: led_power_en { -+ rockchip,pins = <2 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ headphone { -+ hp_det: hp-det { -+ rockchip,pins = <3 RK_PC2 RK_FUNC_GPIO &pcfg_pull_down>; -+ }; -+ }; -+ -+ pmic { -+ pmic_int: pmic_int { -+ rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; -+ -+ pcie { -+ pcie30x1_enable_h: pcie30x1-enable-h { -+ rockchip,pins = <0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ pcie30x2_reset_h: pcie30x2-reset-h { -+ rockchip,pins = <2 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ pcie_enable_h: pcie-enable-h { -+ rockchip,pins = <0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ usb { -+ vcc5v0_host_en: vcc5v0-host-en { -+ rockchip,pins = <0 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ vcc5v0_otg_en: vcc5v0_otg_en { -+ rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+}; -+ -+&i2s1_8ch { -+ rockchip,trcm-sync-tx-only; -+ status = "okay"; -+}; -+ -+&pmu_io_domains { -+ pmuio1-supply = <&vcc3v3_pmu>; -+ pmuio2-supply = <&vcc3v3_pmu>; -+ vccio1-supply = <&vccio_acodec>; -+ vccio2-supply = <&vcc_1v8>; -+ vccio3-supply = <&vccio_sd>; -+ vccio4-supply = <&vcc_1v8>; -+ vccio5-supply = <&vcc_3v3>; -+ vccio6-supply = <&vcc_1v8>; -+ vccio7-supply = <&vcc_3v3>; -+ status = "okay"; -+}; -+ -+&saradc { -+ vref-supply = <&vcca_1v8>; -+ status = "okay"; -+}; -+ -+&sdhci { -+ bus-width = <8>; -+ max-frequency = <200000000>; -+ non-removable; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>; -+ vmmc-supply = <&vcc_3v3>; -+ vqmmc-supply = <&vcc_1v8>; -+ status = "okay"; -+}; -+ -+&tsadc { -+ rockchip,hw-tshut-mode = <1>; -+ rockchip,hw-tshut-polarity = <0>; -+ status = "okay"; -+}; -+ -+&uart2 { -+ status = "okay"; -+}; -+ -+&sdmmc0 { -+ bus-width = <4>; -+ cap-sd-highspeed; -+ cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; -+ /* Also used in pcie30x1_clkreqnm0 */ -+ disable-wp; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd>; -+ sd-uhs-sdr104; -+ vmmc-supply = <&vcc3v3_sd>; -+ vqmmc-supply = <&vccio_sd>; -+ status = "okay"; -+}; -+ -+&sdmmc2 { -+ bus-width = <4>; -+ cap-sd-highspeed; -+ cd-gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_LOW>; -+ disable-wp; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdmmc2m0_bus4 &sdmmc2m0_clk &sdmmc2m0_cmd>; -+ sd-uhs-sdr104; -+ status = "okay"; -+}; -+ -+&mdio0 { -+ rgmii_phy0: ethernet-phy@0 { -+ compatible = "ethernet-phy-id001c.c916"; -+ reg = <0x0>; -+ reset-assert-us = <20000>; -+ reset-deassert-us = <100000>; -+ reset-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_LOW>; -+ }; -+}; -+ -+&mdio1 { -+ rgmii_phy1: ethernet-phy@0 { -+ compatible = "ethernet-phy-id001c.c916"; -+ reg = <0x0>; -+ reset-assert-us = <20000>; -+ reset-deassert-us = <100000>; -+ reset-gpios = <&gpio2 RK_PD1 GPIO_ACTIVE_LOW>; -+ }; -+}; -+ -+&gmac0 { -+ assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>; -+ assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>; -+ assigned-clock-rates = <0>, <125000000>; -+ clock_in_out = "output"; -+ phy-handle = <&rgmii_phy0>; -+ phy-mode = "rgmii"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&gmac0_miim -+ &gmac0_tx_bus2 -+ &gmac0_rx_bus2 -+ &gmac0_rgmii_clk -+ &gmac0_rgmii_bus>; -+ status = "okay"; -+}; -+ -+&gmac1 { -+ assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>; -+ assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>; -+ assigned-clock-rates = <0>, <125000000>; -+ clock_in_out = "output"; -+ phy-handle = <&rgmii_phy1>; -+ phy-mode = "rgmii"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&gmac1m1_miim -+ &gmac1m1_tx_bus2 -+ &gmac1m1_rx_bus2 -+ &gmac1m1_rgmii_clk -+ &gmac1m1_rgmii_bus>; -+ status = "okay"; -+}; -+ -+&usb_host0_ehci { -+ status = "okay"; -+}; -+ -+&usb_host0_ohci { -+ status = "okay"; -+}; -+ -+&usb_host0_xhci { -+ dr_mode = "host"; -+ extcon = <&usb2phy0>; -+ status = "okay"; -+}; -+ -+&usb_host1_ehci { -+ status = "okay"; -+}; -+ -+&usb_host1_ohci { -+ status = "okay"; -+}; -+ -+&usb_host1_xhci { -+ status = "okay"; -+}; -+ -+&usb2phy0 { -+ status = "okay"; -+}; -+ -+&usb2phy0_host { -+ phy-supply = <&vcc5v0_host>; -+ status = "okay"; -+}; -+ -+&usb2phy1 { -+ status = "okay"; -+}; -+ -+&usb2phy1_host { -+ phy-supply = <&vcc5v0_host>; -+ status = "okay"; -+}; -+ -+&usb2phy1_otg { -+ phy-supply = <&vcc5v0_host>; -+ status = "okay"; -+}; -+ -+&usb2phy1 { -+ status = "okay"; -+}; -+ -+&usb2phy1_host { -+ phy-supply = <&vcc5v0_otg>; -+ status = "okay"; -+}; -+ -+&usb2phy1_otg { -+ phy-supply = <&vcc5v0_otg>; -+ status = "okay"; -+}; -diff --git a/configs/yy3568-rk3568_defconfig b/configs/yy3568-rk3568_defconfig -new file mode 100644 -index 0000000000..23f9251bb2 ---- /dev/null -+++ b/configs/yy3568-rk3568_defconfig -@@ -0,0 +1,232 @@ -+CONFIG_ARM=y -+CONFIG_ARCH_ROCKCHIP=y -+CONFIG_SPL_LIBCOMMON_SUPPORT=y -+CONFIG_SPL_LIBGENERIC_SUPPORT=y -+CONFIG_SYS_MALLOC_F_LEN=0x80000 -+CONFIG_SPL_FIT_GENERATOR="arch/arm/mach-rockchip/make_fit_atf.sh" -+CONFIG_ROCKCHIP_RK3568=y -+CONFIG_ROCKCHIP_FIT_IMAGE=y -+CONFIG_ROCKCHIP_VENDOR_PARTITION=y -+CONFIG_ROCKCHIP_FIT_IMAGE_PACK=y -+CONFIG_ROCKCHIP_NEW_IDB=y -+CONFIG_SPL_SERIAL_SUPPORT=y -+CONFIG_SPL_DRIVERS_MISC_SUPPORT=y -+CONFIG_TARGET_EVB_RK3568=y -+CONFIG_SPL_LIBDISK_SUPPORT=y -+CONFIG_SPL_NAND_SUPPORT=y -+CONFIG_SPL_SPI_FLASH_SUPPORT=y -+CONFIG_SPL_SPI_SUPPORT=y -+CONFIG_DEFAULT_DEVICE_TREE="rk3568-yy3568" -+CONFIG_DEBUG_UART=y -+CONFIG_FIT=y -+CONFIG_FIT_IMAGE_POST_PROCESS=y -+CONFIG_FIT_HW_CRYPTO=y -+CONFIG_SPL_LOAD_FIT=y -+CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y -+CONFIG_SPL_FIT_HW_CRYPTO=y -+# CONFIG_SPL_SYS_DCACHE_OFF is not set -+CONFIG_BOOTDELAY=0 -+CONFIG_SARADC_ROCKCHIP=y -+CONFIG_SYS_CONSOLE_INFO_QUIET=y -+# CONFIG_DISPLAY_CPUINFO is not set -+CONFIG_ANDROID_BOOTLOADER=y -+CONFIG_ANDROID_AVB=y -+CONFIG_ANDROID_BOOT_IMAGE_HASH=y -+CONFIG_SPL_BOARD_INIT=y -+# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set -+# CONFIG_SPL_LEGACY_IMAGE_SUPPORT is not set -+CONFIG_SPL_SEPARATE_BSS=y -+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION=y -+CONFIG_SPL_SHA256_SUPPORT=y -+CONFIG_SPL_CRYPTO_SUPPORT=y -+CONFIG_SPL_HASH_SUPPORT=y -+CONFIG_SPL_MMC_WRITE=y -+CONFIG_SPL_MTD_SUPPORT=y -+CONFIG_SPL_MTD_WRITE=y -+CONFIG_SPL_ATF=y -+CONFIG_SPL_ATF_NO_PLATFORM_PARAM=y -+CONFIG_SPL_AB=y -+CONFIG_FASTBOOT_BUF_ADDR=0xc00800 -+CONFIG_FASTBOOT_BUF_SIZE=0x04000000 -+CONFIG_FASTBOOT_FLASH=y -+CONFIG_FASTBOOT_FLASH_MMC_DEV=0 -+CONFIG_CMD_BOOTZ=y -+CONFIG_CMD_DTIMG=y -+# CONFIG_CMD_ELF is not set -+# CONFIG_CMD_IMI is not set -+# CONFIG_CMD_IMLS is not set -+# CONFIG_CMD_XIMG is not set -+# CONFIG_CMD_LZMADEC is not set -+# CONFIG_CMD_UNZIP is not set -+# CONFIG_CMD_FLASH is not set -+# CONFIG_CMD_FPGA is not set -+CONFIG_CMD_GPT=y -+# CONFIG_CMD_LOADB is not set -+# CONFIG_CMD_LOADS is not set -+CONFIG_CMD_BOOT_ANDROID=y -+CONFIG_CMD_BOOT_ROCKCHIP=y -+CONFIG_CMD_MMC=y -+CONFIG_CMD_MTD=y -+CONFIG_CMD_NAND=y -+CONFIG_CMD_PCI=y -+CONFIG_CMD_USB=y -+CONFIG_CMD_USB_MASS_STORAGE=y -+# CONFIG_CMD_ITEST is not set -+# CONFIG_CMD_SETEXPR is not set -+CONFIG_CMD_TFTPPUT=y -+CONFIG_CMD_TFTP_BOOTM=y -+CONFIG_CMD_TFTP_FLASH=y -+# CONFIG_CMD_MISC is not set -+# CONFIG_CMD_CHARGE_DISPLAY is not set -+CONFIG_CMD_MTD_BLK=y -+# CONFIG_SPL_DOS_PARTITION is not set -+# CONFIG_ISO_PARTITION is not set -+CONFIG_EFI_PARTITION_ENTRIES_NUMBERS=64 -+CONFIG_SPL_OF_CONTROL=y -+CONFIG_SPL_DTB_MINIMUM=y -+CONFIG_OF_LIVE=y -+CONFIG_OF_SPL_REMOVE_PROPS="" -+# CONFIG_NET_TFTP_VARS is not set -+CONFIG_REGMAP=y -+CONFIG_SPL_REGMAP=y -+CONFIG_SYSCON=y -+CONFIG_SPL_SYSCON=y -+CONFIG_CLK=y -+CONFIG_SPL_CLK=y -+CONFIG_CLK_SCMI=y -+CONFIG_DM_CRYPTO=y -+CONFIG_SPL_DM_CRYPTO=y -+CONFIG_ROCKCHIP_CRYPTO_V2=y -+CONFIG_SPL_ROCKCHIP_CRYPTO_V2=y -+CONFIG_DM_RNG=y -+CONFIG_RNG_ROCKCHIP=y -+CONFIG_SCMI_FIRMWARE=y -+CONFIG_ROCKCHIP_GPIO=y -+CONFIG_ROCKCHIP_GPIO_V2=y -+CONFIG_SYS_I2C_ROCKCHIP=y -+CONFIG_DM_KEY=y -+CONFIG_RK8XX_PWRKEY=y -+CONFIG_ADC_KEY=y -+CONFIG_MISC=y -+CONFIG_SPL_MISC=y -+CONFIG_ROCKCHIP_OTP=y -+CONFIG_SPL_ROCKCHIP_SECURE_OTP=y -+CONFIG_MMC_DW=y -+CONFIG_MMC_DW_ROCKCHIP=y -+CONFIG_MMC_SDHCI=y -+CONFIG_MMC_SDHCI_SDMA=y -+CONFIG_MMC_SDHCI_ROCKCHIP=y -+CONFIG_MTD=y -+CONFIG_MTD_BLK=y -+CONFIG_MTD_DEVICE=y -+CONFIG_NAND=y -+CONFIG_NAND_ROCKCHIP_V9=y -+CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y -+CONFIG_SYS_NAND_U_BOOT_OFFS=0x8000 -+CONFIG_SYS_NAND_U_BOOT_OFFS_REDUND=0x10000 -+CONFIG_MTD_SPI_NAND=y -+CONFIG_SPI_FLASH=y -+CONFIG_SF_DEFAULT_SPEED=20000000 -+CONFIG_SPI_FLASH_EON=y -+CONFIG_SPI_FLASH_GIGADEVICE=y -+CONFIG_SPI_FLASH_MACRONIX=y -+CONFIG_SPI_FLASH_WINBOND=y -+CONFIG_SPI_FLASH_XMC=y -+CONFIG_SPI_FLASH_MTD=y -+CONFIG_DM_ETH=y -+CONFIG_DM_ETH_PHY=y -+CONFIG_DWC_ETH_QOS=y -+CONFIG_GMAC_ROCKCHIP=y -+CONFIG_NVME=y -+CONFIG_PCI=y -+CONFIG_DM_PCI=y -+CONFIG_DM_PCI_COMPAT=y -+CONFIG_PCIE_DW_ROCKCHIP=y -+CONFIG_PHY_ROCKCHIP_INNO_USB2=y -+CONFIG_PHY_ROCKCHIP_NANENG_COMBOPHY=y -+CONFIG_PHY_ROCKCHIP_NANENG_EDP=y -+CONFIG_PHY_ROCKCHIP_SNPS_PCIE3=y -+CONFIG_PINCTRL=y -+CONFIG_SPL_PINCTRL=y -+CONFIG_DM_FUEL_GAUGE=y -+CONFIG_POWER_FG_RK817=y -+CONFIG_IO_DOMAIN=y -+CONFIG_ROCKCHIP_IO_DOMAIN=y -+CONFIG_DM_PMIC=y -+CONFIG_PMIC_RK8XX=y -+CONFIG_REGULATOR_FAN53555=y -+CONFIG_REGULATOR_PWM=y -+CONFIG_DM_REGULATOR_FIXED=y -+CONFIG_DM_REGULATOR_GPIO=y -+CONFIG_REGULATOR_RK8XX=y -+CONFIG_DM_CHARGE_DISPLAY=y -+CONFIG_CHARGE_ANIMATION=y -+CONFIG_PWM_ROCKCHIP=y -+CONFIG_RAM=y -+CONFIG_SPL_RAM=y -+CONFIG_TPL_RAM=y -+CONFIG_DM_RAMDISK=y -+CONFIG_RAMDISK_RO=y -+CONFIG_DM_DMC=y -+CONFIG_ROCKCHIP_DMC_FSP=y -+CONFIG_ROCKCHIP_SDRAM_COMMON=y -+CONFIG_ROCKCHIP_TPL_INIT_DRAM_TYPE=0 -+CONFIG_DM_RESET=y -+CONFIG_SPL_DM_RESET=y -+CONFIG_SPL_RESET_ROCKCHIP=y -+CONFIG_BAUDRATE=1500000 -+CONFIG_DEBUG_UART_BASE=0xFE660000 -+CONFIG_DEBUG_UART_CLOCK=24000000 -+CONFIG_DEBUG_UART_SHIFT=2 -+CONFIG_ROCKCHIP_SFC=y -+CONFIG_SYSRESET=y -+CONFIG_USB=y -+CONFIG_USB_XHCI_HCD=y -+CONFIG_USB_XHCI_DWC3=y -+CONFIG_USB_EHCI_HCD=y -+CONFIG_USB_EHCI_GENERIC=y -+CONFIG_USB_OHCI_HCD=y -+CONFIG_USB_OHCI_GENERIC=y -+CONFIG_USB_DWC3=y -+CONFIG_USB_DWC3_GADGET=y -+CONFIG_USB_DWC3_GENERIC=y -+CONFIG_USB_STORAGE=y -+CONFIG_USB_GADGET=y -+CONFIG_USB_GADGET_MANUFACTURER="Rockchip" -+CONFIG_USB_GADGET_VENDOR_NUM=0x2207 -+CONFIG_USB_GADGET_PRODUCT_NUM=0x350a -+CONFIG_USB_GADGET_DOWNLOAD=y -+CONFIG_DM_VIDEO=y -+CONFIG_DISPLAY=y -+CONFIG_DRM_ROCKCHIP=y -+CONFIG_DRM_ROCKCHIP_DW_HDMI=y -+CONFIG_DRM_ROCKCHIP_INNO_MIPI_PHY=y -+CONFIG_DRM_ROCKCHIP_INNO_VIDEO_COMBO_PHY=y -+CONFIG_DRM_ROCKCHIP_DW_MIPI_DSI=y -+CONFIG_DRM_ROCKCHIP_ANALOGIX_DP=y -+CONFIG_DRM_ROCKCHIP_LVDS=y -+CONFIG_DRM_ROCKCHIP_RGB=y -+CONFIG_ROCKCHIP_CUBIC_LUT_SIZE=9 -+CONFIG_LCD=y -+CONFIG_USE_TINY_PRINTF=y -+CONFIG_SPL_TINY_MEMSET=y -+CONFIG_RSA=y -+CONFIG_SPL_RSA=y -+CONFIG_RSA_N_SIZE=0x200 -+CONFIG_RSA_E_SIZE=0x10 -+CONFIG_RSA_C_SIZE=0x20 -+CONFIG_XBC=y -+CONFIG_SHA512=y -+CONFIG_LZ4=y -+CONFIG_LZMA=y -+CONFIG_SPL_GZIP=y -+CONFIG_ERRNO_STR=y -+# CONFIG_EFI_LOADER is not set -+CONFIG_AVB_LIBAVB=y -+CONFIG_AVB_LIBAVB_AB=y -+CONFIG_AVB_LIBAVB_ATX=y -+CONFIG_AVB_LIBAVB_USER=y -+CONFIG_RK_AVB_LIBAVB_USER=y -+CONFIG_OPTEE_CLIENT=y -+CONFIG_OPTEE_V2=y -+CONFIG_OPTEE_ALWAYS_USE_SECURITY_PARTITION=y --- -2.42.0 From 3e8157540606882b15baec3dd1187dfbe20708d3 Mon Sep 17 00:00:00 2001 From: Nicolas Pereira <41456803+hqnicolas@users.noreply.github.com> Date: Tue, 4 Mar 2025 11:30:17 -0300 Subject: [PATCH 04/37] rockchip64-edge: add support for yy3568 --- .../add_board_yy3568_defconfig.patch | 733 ------------------ 1 file changed, 733 deletions(-) delete mode 100644 patch/u-boot/legacy/u-boot-radxa-rk35xx/board_yy3568/add_board_yy3568_defconfig.patch diff --git a/patch/u-boot/legacy/u-boot-radxa-rk35xx/board_yy3568/add_board_yy3568_defconfig.patch b/patch/u-boot/legacy/u-boot-radxa-rk35xx/board_yy3568/add_board_yy3568_defconfig.patch deleted file mode 100644 index 427bfd3b3b79..000000000000 --- a/patch/u-boot/legacy/u-boot-radxa-rk35xx/board_yy3568/add_board_yy3568_defconfig.patch +++ /dev/null @@ -1,733 +0,0 @@ -diff --git a/arch/arm/dts/rk3568-yy3568.dts b/arch/arm/dts/rk3568-yy3568.dts -new file mode 100644 -index 00000000000..9e6df741864 ---- /dev/null -+++ b/arch/arm/dts/rk3568-yy3568.dts -@@ -0,0 +1,494 @@ -+/* -+ * SPDX-License-Identifier: GPL-2.0+ -+ * Copyright (c) 2020 Rockchip Electronics Co., Ltd. -+ * Copyright (c) 2024 Radxa Limited -+ */ -+ -+/dts-v1/; -+#include "rk3568.dtsi" -+#include "rk3568-u-boot.dtsi" -+#include -+ -+/ { -+ model = "Youyeetoo YY3568"; -+ compatible = "youyeetoo,yy3568", "rockchip,rk3568"; -+ -+ vcc5v0_sys: vcc5v0-sys { -+ u-boot,dm-pre-reloc; -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc5v0_sys"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ }; -+ -+ vcc3v3_sys: vcc3v3-sys { -+ u-boot,dm-pre-reloc; -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc3v3_sys"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ vin-supply = <&vcc5v0_sys>; -+ }; -+ -+ led_sys: led-sys { -+ u-boot,dm-pre-reloc; -+ compatible = "regulator-fixed"; -+ regulator-name = "led_sys"; -+ enable-active-high; -+ gpio = <&gpio0 RK_PC1 GPIO_ACTIVE_HIGH>; -+ regulator-boot-on; -+ regulator-always-on; -+ vin-supply = <&vcc3v3_sys>; -+ }; -+ -+ led_sys: led-sys { -+ u-boot,dm-pre-reloc; -+ compatible = "regulator-fixed"; -+ regulator-name = "led_sys"; -+ enable-active-high; -+ gpio = <&gpio0 RK_PC1 GPIO_ACTIVE_HIGH>; -+ regulator-boot-on; -+ regulator-always-on; -+ vin-supply = <&vcc3v3_sys>; -+ }; -+ -+ adc-keys { -+ compatible = "adc-keys"; -+ io-channels = <&saradc 0>; -+ io-channel-names = "buttons"; -+ keyup-threshold-microvolt = <1800000>; -+ u-boot,dm-spl; -+ status = "okay"; -+ -+ volumeup-key { -+ u-boot,dm-spl; -+ linux,code = ; -+ label = "volume up"; -+ press-threshold-microvolt = <9>; -+ }; -+ }; -+ -+ leds { -+ u-boot,dm-pre-reloc; -+ compatible = "gpio-leds"; -+ status = "okay"; -+ -+ blue-led { -+ u-boot,dm-pre-reloc; -+ label = "blue"; -+ gpios = <&gpio2 RK_PB2 GPIO_ACTIVE_HIGH>; -+ }; -+ }; -+}; -+ -+&gmac1 { -+ u-boot,dm-pre-reloc; -+ phy-mode = "rgmii"; -+ clock_in_out = "output"; -+ -+ snps,reset-gpio = <&gpio2 RK_PD1 GPIO_ACTIVE_LOW>; -+ snps,reset-active-low; -+ /* Reset time is 20ms, 100ms for rtl8211f */ -+ snps,reset-delays-us = <0 20000 100000>; -+ -+ assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>; -+ assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>; -+ assigned-clock-rates = <0>, <125000000>; -+ -+ pinctrl-names = "default"; -+ pinctrl-0 = <&gmac1m1_miim -+ &gmac1m1_tx_bus2 -+ &gmac1m1_rx_bus2 -+ &gmac1m1_rgmii_clk -+ &gmac1m1_rgmii_bus>; -+ -+ tx_delay = <0x44>; -+ rx_delay = <0x26>; -+ -+ phy-handle = <&rgmii_phy1>; -+ status = "disabled"; -+}; -+ -+&mdio1 { -+ rgmii_phy1: phy@0 { -+ compatible = "ethernet-phy-ieee802.3-c22"; -+ reg = <0x0>; -+ }; -+}; -+ -+&crypto { -+ status = "okay"; -+}; -+ -+&uart2 { -+ status = "okay"; -+}; -+ -+&pmu_io_domains { -+ status = "okay"; -+ pmuio2-supply = <&vcc_3v3>; -+ vccio1-supply = <&vccio_acodec>; -+ vccio3-supply = <&vccio_sd>; -+ vccio4-supply = <&vcc_1v8>; -+ vccio5-supply = <&vcc_3v3>; -+ vccio6-supply = <&vcc_1v8>; -+ vccio7-supply = <&vcc_3v3>; -+ u-boot,dm-pre-reloc; -+}; -+ -+&gpio0 { -+ u-boot,dm-pre-reloc; -+}; -+ -+&gpio4 { -+ u-boot,dm-pre-reloc; -+}; -+ -+&i2c0 { -+ status = "okay"; -+ u-boot,dm-pre-reloc; -+ clock-frequency = <100000>; -+ -+ vdd_cpu: tcs4525@1c { -+ u-boot,dm-pre-reloc; -+ compatible = "tcs,tcs452x"; -+ reg = <0x1c>; -+ vin-supply = <&vcc5v0_sys>; -+ regulator-compatible = "fan53555-reg"; -+ regulator-name = "vdd_cpu"; -+ regulator-min-microvolt = <712500>; -+ regulator-max-microvolt = <1390000>; -+ regulator-init-microvolt = <900000>; -+ regulator-ramp-delay = <2300>; -+ fcs,suspend-voltage-selector = <1>; -+ regulator-boot-on; -+ regulator-always-on; -+ regulator-state-mem { -+ u-boot,dm-pre-reloc; -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ rk809: pmic@20 { -+ u-boot,dm-pre-reloc; -+ status = "okay"; -+ compatible = "rockchip,rk809"; -+ reg = <0x20>; -+ interrupt-parent = <&gpio0>; -+ interrupts = <3 IRQ_TYPE_LEVEL_LOW>; -+ -+ pinctrl-names = "default", "pmic-sleep", -+ "pmic-power-off", "pmic-reset"; -+ pinctrl-0 = <&pmic_int>; -+ pinctrl-1 = <&soc_slppin_slp>, <&rk817_slppin_slp>; -+ pinctrl-2 = <&soc_slppin_gpio>, <&rk817_slppin_pwrdn>; -+ pinctrl-3 = <&soc_slppin_gpio>, <&rk817_slppin_rst>; -+ -+ rockchip,system-power-controller; -+ wakeup-source; -+ #clock-cells = <1>; -+ clock-output-names = "rk808-clkout1", "rk808-clkout2"; -+ //fb-inner-reg-idxs = <2>; -+ /* 1: rst regs (default in codes), 0: rst the pmic */ -+ pmic-reset-func = <0>; -+ /* not save the PMIC_POWER_EN register in uboot */ -+ not-save-power-en = <1>; -+ -+ vcc1-supply = <&vcc3v3_sys>; -+ vcc2-supply = <&vcc3v3_sys>; -+ vcc3-supply = <&vcc3v3_sys>; -+ vcc4-supply = <&vcc3v3_sys>; -+ vcc5-supply = <&vcc3v3_sys>; -+ vcc6-supply = <&vcc3v3_sys>; -+ vcc7-supply = <&vcc3v3_sys>; -+ vcc8-supply = <&vcc3v3_sys>; -+ vcc9-supply = <&vcc3v3_sys>; -+ -+ pwrkey { -+ status = "okay"; -+ u-boot,dm-pre-reloc; -+ }; -+ -+ pinctrl_rk8xx: pinctrl_rk8xx { -+ u-boot,dm-pre-reloc; -+ gpio-controller; -+ #gpio-cells = <2>; -+ -+ rk817_slppin_null: rk817_slppin_null { -+ pins = "gpio_slp"; -+ function = "pin_fun0"; -+ u-boot,dm-pre-reloc; -+ }; -+ -+ rk817_slppin_slp: rk817_slppin_slp { -+ pins = "gpio_slp"; -+ function = "pin_fun1"; -+ u-boot,dm-pre-reloc; -+ }; -+ -+ rk817_slppin_pwrdn: rk817_slppin_pwrdn { -+ pins = "gpio_slp"; -+ function = "pin_fun2"; -+ u-boot,dm-pre-reloc; -+ }; -+ -+ rk817_slppin_rst: rk817_slppin_rst { -+ pins = "gpio_slp"; -+ function = "pin_fun3"; -+ u-boot,dm-pre-reloc; -+ }; -+ }; -+ -+ regulators { -+ u-boot,dm-pre-reloc; -+ vdd_logic: DCDC_REG1 { -+ u-boot,dm-pre-reloc; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <500000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-init-microvolt = <900000>; -+ regulator-ramp-delay = <6001>; -+ regulator-initial-mode = <0x2>; -+ regulator-name = "vdd_logic"; -+ regulator-state-mem { -+ u-boot,dm-pre-reloc; -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ vdd_gpu: DCDC_REG2 { -+ u-boot,dm-pre-reloc; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <500000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-init-microvolt = <900000>; -+ regulator-ramp-delay = <6001>; -+ regulator-initial-mode = <0x2>; -+ regulator-name = "vdd_gpu"; -+ regulator-state-mem { -+ u-boot,dm-pre-reloc; -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ vcc_ddr: DCDC_REG3 { -+ u-boot,dm-pre-reloc; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-initial-mode = <0x2>; -+ regulator-name = "vcc_ddr"; -+ regulator-state-mem { -+ u-boot,dm-pre-reloc; -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ vdd_npu: DCDC_REG4 { -+ u-boot,dm-pre-reloc; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <500000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-init-microvolt = <900000>; -+ regulator-ramp-delay = <6001>; -+ regulator-initial-mode = <0x2>; -+ regulator-name = "vdd_npu"; -+ regulator-state-mem { -+ u-boot,dm-pre-reloc; -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ vdda0v9_image: LDO_REG1 { -+ u-boot,dm-pre-reloc; -+ regulator-boot-on; -+ regulator-always-on; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <900000>; -+ regulator-name = "vdda0v9_image"; -+ regulator-state-mem { -+ u-boot,dm-pre-reloc; -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdda_0v9: LDO_REG2 { -+ u-boot,dm-pre-reloc; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <900000>; -+ regulator-name = "vdda_0v9"; -+ regulator-state-mem { -+ u-boot,dm-pre-reloc; -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vdda0v9_pmu: LDO_REG3 { -+ u-boot,dm-pre-reloc; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <900000>; -+ regulator-name = "vdda0v9_pmu"; -+ regulator-state-mem { -+ u-boot,dm-pre-reloc; -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <900000>; -+ }; -+ }; -+ -+ vccio_acodec: LDO_REG4 { -+ u-boot,dm-pre-reloc; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-name = "vccio_acodec"; -+ regulator-state-mem { -+ u-boot,dm-pre-reloc; -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vccio_sd: LDO_REG5 { -+ u-boot,dm-pre-reloc; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-name = "vccio_sd"; -+ regulator-state-mem { -+ u-boot,dm-pre-reloc; -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc3v3_pmu: LDO_REG6 { -+ u-boot,dm-pre-reloc; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-name = "vcc3v3_pmu"; -+ regulator-state-mem { -+ u-boot,dm-pre-reloc; -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <3300000>; -+ }; -+ }; -+ -+ vcca_1v8: LDO_REG7 { -+ u-boot,dm-pre-reloc; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-name = "vcca_1v8"; -+ regulator-state-mem { -+ u-boot,dm-pre-reloc; -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcca1v8_pmu: LDO_REG8 { -+ u-boot,dm-pre-reloc; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-name = "vcca1v8_pmu"; -+ regulator-state-mem { -+ u-boot,dm-pre-reloc; -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ vcca1v8_image: LDO_REG9 { -+ u-boot,dm-pre-reloc; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-name = "vcca1v8_image"; -+ regulator-state-mem { -+ u-boot,dm-pre-reloc; -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_1v8: DCDC_REG5 { -+ u-boot,dm-pre-reloc; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-name = "vcc_1v8"; -+ regulator-state-mem { -+ u-boot,dm-pre-reloc; -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_3v3: SWITCH_REG1 { -+ u-boot,dm-pre-reloc; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-name = "vcc_3v3"; -+ regulator-state-mem { -+ u-boot,dm-pre-reloc; -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc3v3_sd: SWITCH_REG2 { -+ u-boot,dm-pre-reloc; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-name = "vcc3v3_sd"; -+ regulator-state-mem { -+ u-boot,dm-pre-reloc; -+ regulator-off-in-suspend; -+ }; -+ }; -+ }; -+ }; -+}; -+ -+&pinctrl { -+ u-boot,dm-spl; -+ pmic { -+ u-boot,dm-pre-reloc; -+ pmic_int: pmic_int { -+ u-boot,dm-pre-reloc; -+ rockchip,pins = -+ <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ -+ soc_slppin_gpio: soc_slppin_gpio { -+ u-boot,dm-pre-reloc; -+ rockchip,pins = -+ <0 RK_PA2 RK_FUNC_GPIO &pcfg_output_low_pull_down>; -+ }; -+ -+ soc_slppin_slp: soc_slppin_slp { -+ u-boot,dm-pre-reloc; -+ rockchip,pins = -+ <0 RK_PA2 RK_FUNC_1 &pcfg_pull_up>; -+ }; -+ -+ soc_slppin_rst: soc_slppin_rst { -+ u-boot,dm-pre-reloc; -+ rockchip,pins = -+ <0 RK_PA2 RK_FUNC_2 &pcfg_pull_none>; -+ }; -+ }; -+}; -diff --git a/configs/yy3568-rk3568_defconfig b/configs/yy3568-rk3568_defconfig -new file mode 100644 -index 00000000000..17ac783cd0b ---- /dev/null -+++ b/configs/yy3568-rk3568_defconfig -@@ -0,0 +1,227 @@ -+CONFIG_ARM=y -+CONFIG_ARCH_ROCKCHIP=y -+CONFIG_SPL_LIBCOMMON_SUPPORT=y -+CONFIG_SPL_LIBGENERIC_SUPPORT=y -+CONFIG_SYS_MALLOC_F_LEN=0x80000 -+CONFIG_SPL_FIT_GENERATOR="arch/arm/mach-rockchip/make_fit_atf.sh" -+CONFIG_ROCKCHIP_RK3568=y -+CONFIG_ROCKCHIP_FIT_IMAGE=y -+CONFIG_ROCKCHIP_VENDOR_PARTITION=y -+CONFIG_ROCKCHIP_FIT_IMAGE_PACK=y -+CONFIG_ROCKCHIP_NEW_IDB=y -+CONFIG_ROCKCHIP_EMMC_IOMUX=y -+CONFIG_SPL_SERIAL_SUPPORT=y -+CONFIG_SPL_DRIVERS_MISC_SUPPORT=y -+CONFIG_TARGET_EVB_RK3568=y -+CONFIG_SPL_LIBDISK_SUPPORT=y -+CONFIG_SPL_NAND_SUPPORT=y -+CONFIG_SPL_SPI_FLASH_SUPPORT=y -+CONFIG_SPL_SPI_SUPPORT=y -+CONFIG_DEFAULT_DEVICE_TREE="rk3568-yy3568" -+CONFIG_DEBUG_UART=y -+CONFIG_FIT=y -+CONFIG_FIT_IMAGE_POST_PROCESS=y -+CONFIG_FIT_HW_CRYPTO=y -+CONFIG_SPL_LOAD_FIT=y -+CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y -+CONFIG_SPL_FIT_HW_CRYPTO=y -+# CONFIG_SPL_SYS_DCACHE_OFF is not set -+CONFIG_BOOTDELAY=0 -+CONFIG_SYS_CONSOLE_INFO_QUIET=y -+# CONFIG_DISPLAY_CPUINFO is not set -+CONFIG_ANDROID_BOOTLOADER=y -+CONFIG_ANDROID_AVB=y -+CONFIG_ANDROID_BOOT_IMAGE_HASH=y -+CONFIG_SPL_BOARD_INIT=y -+# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set -+# CONFIG_SPL_LEGACY_IMAGE_SUPPORT is not set -+CONFIG_SPL_SEPARATE_BSS=y -+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION=y -+CONFIG_SPL_SHA256_SUPPORT=y -+CONFIG_SPL_CRYPTO_SUPPORT=y -+CONFIG_SPL_HASH_SUPPORT=y -+CONFIG_SPL_MTD_SUPPORT=y -+CONFIG_SPL_ATF=y -+CONFIG_SPL_ATF_NO_PLATFORM_PARAM=y -+CONFIG_SPL_AB=y -+CONFIG_FASTBOOT_BUF_ADDR=0xc00800 -+CONFIG_FASTBOOT_BUF_SIZE=0x04000000 -+CONFIG_FASTBOOT_FLASH=y -+CONFIG_FASTBOOT_FLASH_MMC_DEV=0 -+CONFIG_CMD_BOOTZ=y -+CONFIG_CMD_DTIMG=y -+# CONFIG_CMD_ELF is not set -+# CONFIG_CMD_IMI is not set -+# CONFIG_CMD_IMLS is not set -+# CONFIG_CMD_XIMG is not set -+# CONFIG_CMD_LZMADEC is not set -+# CONFIG_CMD_UNZIP is not set -+# CONFIG_CMD_FLASH is not set -+# CONFIG_CMD_FPGA is not set -+CONFIG_CMD_GPT=y -+# CONFIG_CMD_LOADB is not set -+# CONFIG_CMD_LOADS is not set -+CONFIG_CMD_BOOT_ANDROID=y -+CONFIG_CMD_BOOT_ROCKCHIP=y -+CONFIG_CMD_MMC=y -+CONFIG_CMD_MTD=y -+CONFIG_CMD_NAND=y -+CONFIG_CMD_PCI=y -+CONFIG_CMD_USB=y -+CONFIG_CMD_USB_MASS_STORAGE=y -+# CONFIG_CMD_ITEST is not set -+# CONFIG_CMD_SETEXPR is not set -+CONFIG_CMD_TFTPPUT=y -+CONFIG_CMD_TFTP_BOOTM=y -+CONFIG_CMD_TFTP_FLASH=y -+# CONFIG_CMD_MISC is not set -+# CONFIG_CMD_CHARGE_DISPLAY is not set -+CONFIG_CMD_MTD_BLK=y -+# CONFIG_SPL_DOS_PARTITION is not set -+# CONFIG_ISO_PARTITION is not set -+CONFIG_EFI_PARTITION_ENTRIES_NUMBERS=64 -+CONFIG_SPL_OF_CONTROL=y -+CONFIG_SPL_DTB_MINIMUM=y -+CONFIG_OF_LIVE=y -+CONFIG_OF_SPL_REMOVE_PROPS="" -+# CONFIG_NET_TFTP_VARS is not set -+CONFIG_REGMAP=y -+CONFIG_SPL_REGMAP=y -+CONFIG_SYSCON=y -+CONFIG_SPL_SYSCON=y -+CONFIG_CLK=y -+CONFIG_SPL_CLK=y -+CONFIG_CLK_SCMI=y -+CONFIG_DM_CRYPTO=y -+CONFIG_SPL_DM_CRYPTO=y -+CONFIG_ROCKCHIP_CRYPTO_V2=y -+CONFIG_SPL_ROCKCHIP_CRYPTO_V2=y -+CONFIG_DM_RNG=y -+CONFIG_RNG_ROCKCHIP=y -+CONFIG_SCMI_FIRMWARE=y -+CONFIG_ROCKCHIP_GPIO=y -+CONFIG_ROCKCHIP_GPIO_V2=y -+CONFIG_SYS_I2C_ROCKCHIP=y -+CONFIG_DM_KEY=y -+CONFIG_RK8XX_PWRKEY=y -+CONFIG_ADC_KEY=y -+CONFIG_MISC=y -+CONFIG_SPL_MISC=y -+CONFIG_ROCKCHIP_OTP=y -+CONFIG_SPL_ROCKCHIP_SECURE_OTP=y -+CONFIG_MMC_DW=y -+CONFIG_MMC_DW_ROCKCHIP=y -+CONFIG_MMC_SDHCI=y -+CONFIG_MMC_SDHCI_SDMA=y -+CONFIG_MMC_SDHCI_ROCKCHIP=y -+CONFIG_MTD=y -+CONFIG_MTD_BLK=y -+CONFIG_MTD_DEVICE=y -+CONFIG_NAND=y -+CONFIG_NAND_ROCKCHIP_V9=y -+CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y -+CONFIG_SYS_NAND_U_BOOT_OFFS=0x8000 -+CONFIG_SYS_NAND_U_BOOT_OFFS_REDUND=0x10000 -+CONFIG_MTD_SPI_NAND=y -+CONFIG_SPI_FLASH=y -+CONFIG_SF_DEFAULT_SPEED=20000000 -+CONFIG_SPI_FLASH_EON=y -+CONFIG_SPI_FLASH_GIGADEVICE=y -+CONFIG_SPI_FLASH_MACRONIX=y -+CONFIG_SPI_FLASH_WINBOND=y -+CONFIG_SPI_FLASH_XMC=y -+CONFIG_SPI_FLASH_MTD=y -+CONFIG_DM_ETH=y -+CONFIG_DM_ETH_PHY=y -+CONFIG_DWC_ETH_QOS=y -+CONFIG_GMAC_ROCKCHIP=y -+CONFIG_NVME=y -+CONFIG_PCI=y -+CONFIG_DM_PCI=y -+CONFIG_DM_PCI_COMPAT=y -+CONFIG_PCIE_DW_ROCKCHIP=y -+CONFIG_PHY_ROCKCHIP_INNO_USB2=y -+CONFIG_PHY_ROCKCHIP_NANENG_COMBOPHY=y -+CONFIG_PHY_ROCKCHIP_NANENG_EDP=y -+CONFIG_PHY_ROCKCHIP_SNPS_PCIE3=y -+CONFIG_PINCTRL=y -+CONFIG_SPL_PINCTRL=y -+CONFIG_DM_FUEL_GAUGE=y -+CONFIG_POWER_FG_RK817=y -+CONFIG_IO_DOMAIN=y -+CONFIG_ROCKCHIP_IO_DOMAIN=y -+CONFIG_DM_PMIC=y -+CONFIG_PMIC_RK8XX=y -+CONFIG_REGULATOR_FAN53555=y -+CONFIG_REGULATOR_PWM=y -+CONFIG_DM_REGULATOR_FIXED=y -+CONFIG_DM_REGULATOR_GPIO=y -+CONFIG_REGULATOR_RK8XX=y -+CONFIG_DM_CHARGE_DISPLAY=y -+CONFIG_CHARGE_ANIMATION=y -+CONFIG_PWM_ROCKCHIP=y -+CONFIG_RAM=y -+CONFIG_SPL_RAM=y -+CONFIG_TPL_RAM=y -+CONFIG_DM_RAMDISK=y -+CONFIG_RAMDISK_RO=y -+CONFIG_DM_DMC=y -+CONFIG_ROCKCHIP_DMC_FSP=y -+CONFIG_ROCKCHIP_SDRAM_COMMON=y -+CONFIG_ROCKCHIP_TPL_INIT_DRAM_TYPE=0 -+CONFIG_DM_RESET=y -+CONFIG_SPL_DM_RESET=y -+CONFIG_SPL_RESET_ROCKCHIP=y -+CONFIG_BAUDRATE=115200 -+CONFIG_DEBUG_UART_BASE=0xFE660000 -+CONFIG_DEBUG_UART_CLOCK=24000000 -+CONFIG_DEBUG_UART_SHIFT=2 -+CONFIG_ROCKCHIP_SFC=y -+CONFIG_SYSRESET=y -+CONFIG_USB=y -+CONFIG_USB_XHCI_HCD=y -+CONFIG_USB_XHCI_DWC3=y -+CONFIG_USB_EHCI_HCD=y -+CONFIG_USB_EHCI_GENERIC=y -+CONFIG_USB_OHCI_HCD=y -+CONFIG_USB_OHCI_GENERIC=y -+CONFIG_USB_DWC3=y -+CONFIG_USB_DWC3_GADGET=y -+CONFIG_USB_DWC3_GENERIC=y -+CONFIG_USB_STORAGE=y -+CONFIG_USB_GADGET=y -+CONFIG_USB_GADGET_MANUFACTURER="Rockchip" -+CONFIG_USB_GADGET_VENDOR_NUM=0x2207 -+CONFIG_USB_GADGET_PRODUCT_NUM=0x350a -+CONFIG_USB_GADGET_DOWNLOAD=y -+CONFIG_DM_VIDEO=y -+CONFIG_DISPLAY=y -+CONFIG_DRM_ROCKCHIP=y -+CONFIG_DRM_ROCKCHIP_DW_HDMI=y -+CONFIG_DRM_ROCKCHIP_INNO_MIPI_PHY=y -+CONFIG_DRM_ROCKCHIP_INNO_VIDEO_COMBO_PHY=y -+CONFIG_DRM_ROCKCHIP_DW_MIPI_DSI=y -+CONFIG_DRM_ROCKCHIP_ANALOGIX_DP=y -+CONFIG_DRM_ROCKCHIP_LVDS=y -+CONFIG_DRM_ROCKCHIP_RGB=y -+CONFIG_ROCKCHIP_CUBIC_LUT_SIZE=9 -+CONFIG_LCD=y -+CONFIG_USE_TINY_PRINTF=y -+CONFIG_SPL_TINY_MEMSET=y -+CONFIG_RSA=y -+CONFIG_SPL_RSA=y -+CONFIG_RSA_N_SIZE=0x200 -+CONFIG_RSA_E_SIZE=0x10 -+CONFIG_RSA_C_SIZE=0x20 -+CONFIG_XBC=y -+CONFIG_SHA512=y -+CONFIG_LZ4=y -+CONFIG_LZMA=y -+CONFIG_SPL_GZIP=y -+CONFIG_ERRNO_STR=y -+# CONFIG_EFI_LOADER is not set -+CONFIG_AVB_LIBAVB=y -+CONFIG_AVB_LIBAVB_AB=y -+CONFIG_AVB_LIBAVB_ATX=y -+CONFIG_AVB_LIBAVB_USER=y -+CONFIG_RK_AVB_LIBAVB_USER=y From a19491096490be9310dde2ad27a6a9dcfcb11cc5 Mon Sep 17 00:00:00 2001 From: Nicolas Pereira Date: Tue, 4 Mar 2025 11:53:29 -0300 Subject: [PATCH 05/37] rockchip64-edge: add support for yy3568 --- .../archive/rockchip64-6.12/dt/rk3568-yy3568.dts | 10 +++++----- .../archive/rockchip64-6.14/dt/rk3568-yy3568.dts | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/patch/kernel/archive/rockchip64-6.12/dt/rk3568-yy3568.dts b/patch/kernel/archive/rockchip64-6.12/dt/rk3568-yy3568.dts index c50858323405..025ab4fd5a19 100755 --- a/patch/kernel/archive/rockchip64-6.12/dt/rk3568-yy3568.dts +++ b/patch/kernel/archive/rockchip64-6.12/dt/rk3568-yy3568.dts @@ -20,7 +20,7 @@ ethernet1 = &gmac1; mmc2 = &sdmmc2; mmc1 = &sdmmc0; - mmc0 = &sdhci; + mmc0 = &sdhci; }; gpio-leds { @@ -645,10 +645,10 @@ phy-mode = "rgmii"; pinctrl-names = "default"; pinctrl-0 = <&gmac0_miim - &gmac0_tx_bus2 - &gmac0_rx_bus2 - &gmac0_rgmii_clk - &gmac0_rgmii_bus>; + &gmac0_tx_bus2 + &gmac0_rx_bus2 + &gmac0_rgmii_clk + &gmac0_rgmii_bus>; status = "okay"; }; diff --git a/patch/kernel/archive/rockchip64-6.14/dt/rk3568-yy3568.dts b/patch/kernel/archive/rockchip64-6.14/dt/rk3568-yy3568.dts index c50858323405..8a425ae95cde 100755 --- a/patch/kernel/archive/rockchip64-6.14/dt/rk3568-yy3568.dts +++ b/patch/kernel/archive/rockchip64-6.14/dt/rk3568-yy3568.dts @@ -20,7 +20,7 @@ ethernet1 = &gmac1; mmc2 = &sdmmc2; mmc1 = &sdmmc0; - mmc0 = &sdhci; + mmc0 = &sdhci; }; gpio-leds { @@ -661,10 +661,10 @@ phy-mode = "rgmii"; pinctrl-names = "default"; pinctrl-0 = <&gmac1m1_miim - &gmac1m1_tx_bus2 - &gmac1m1_rx_bus2 - &gmac1m1_rgmii_clk - &gmac1m1_rgmii_bus>; + &gmac1m1_tx_bus2 + &gmac1m1_rx_bus2 + &gmac1m1_rgmii_clk + &gmac1m1_rgmii_bus>; status = "okay"; }; From 849b6c0e8e71674ce859ea0efc94acbb3cb9ba18 Mon Sep 17 00:00:00 2001 From: Nicolas Pereira Date: Tue, 4 Mar 2025 14:35:21 -0300 Subject: [PATCH 06/37] rockchip64-edge: add support for yy3568 --- config/boards/yy3568.csc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/config/boards/yy3568.csc b/config/boards/yy3568.csc index b3608503d047..e6410121c3fb 100755 --- a/config/boards/yy3568.csc +++ b/config/boards/yy3568.csc @@ -9,5 +9,4 @@ FULL_DESKTOP="yes" BOOT_LOGO="desktop" BOOT_FDT_FILE="rockchip/rk3568-yy3568.dtb" BOOT_SCENARIO="spl-blobs" -IMAGE_PARTITION_TABLE="gpt" -BOOTFS_TYPE="fat" \ No newline at end of file +IMAGE_PARTITION_TABLE="gpt" \ No newline at end of file From c0b145f74fbd8f9b67d05fc653dcc48f23383f6b Mon Sep 17 00:00:00 2001 From: Nicolas Pereira Date: Tue, 4 Mar 2025 14:53:02 -0300 Subject: [PATCH 07/37] rockchip64-edge: add support for yy3568 --- patch/kernel/archive/rockchip64-6.12/dt/rk3568-yy3568.dts | 2 +- patch/kernel/archive/rockchip64-6.14/dt/rk3568-yy3568.dts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/patch/kernel/archive/rockchip64-6.12/dt/rk3568-yy3568.dts b/patch/kernel/archive/rockchip64-6.12/dt/rk3568-yy3568.dts index 025ab4fd5a19..1de2d89ff2ad 100755 --- a/patch/kernel/archive/rockchip64-6.12/dt/rk3568-yy3568.dts +++ b/patch/kernel/archive/rockchip64-6.12/dt/rk3568-yy3568.dts @@ -501,7 +501,7 @@ }; &pinctrl { - leds { + leds { led_user_en: led_user_en { rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>; }; diff --git a/patch/kernel/archive/rockchip64-6.14/dt/rk3568-yy3568.dts b/patch/kernel/archive/rockchip64-6.14/dt/rk3568-yy3568.dts index 8a425ae95cde..70022b704618 100755 --- a/patch/kernel/archive/rockchip64-6.14/dt/rk3568-yy3568.dts +++ b/patch/kernel/archive/rockchip64-6.14/dt/rk3568-yy3568.dts @@ -501,7 +501,7 @@ }; &pinctrl { - leds { + leds { led_user_en: led_user_en { rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>; }; From 14b5681f6311ace0f565a5aeed5ab29cf61bd151 Mon Sep 17 00:00:00 2001 From: Nicolas Pereira <41456803+hqnicolas@users.noreply.github.com> Date: Thu, 6 Mar 2025 20:08:22 -0300 Subject: [PATCH 08/37] rockchip64-edge: add support for yy3568 --- config/boards/yy3568.csc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/boards/yy3568.csc b/config/boards/yy3568.csc index e6410121c3fb..98760be5fd84 100755 --- a/config/boards/yy3568.csc +++ b/config/boards/yy3568.csc @@ -1,5 +1,5 @@ # Rockchip RK3568 quad core 1-8GB SoC 2x1GBe eMMC USB3 -BOARD_NAME="yy3568" +BOARD_NAME="YouYeeToo YY3568" BOARDFAMILY="rk35xx" BOARD_MAINTAINER="hqnicolas" BOOTCONFIG="yy3568-rk3568_defconfig" @@ -9,4 +9,4 @@ FULL_DESKTOP="yes" BOOT_LOGO="desktop" BOOT_FDT_FILE="rockchip/rk3568-yy3568.dtb" BOOT_SCENARIO="spl-blobs" -IMAGE_PARTITION_TABLE="gpt" \ No newline at end of file +IMAGE_PARTITION_TABLE="gpt" From af43f0cc4346320d950a4291f271889e61b71995 Mon Sep 17 00:00:00 2001 From: Thorsten Maerz Date: Fri, 7 Mar 2025 09:50:05 +0100 Subject: [PATCH 09/37] mksklipad50: devicetree cleanups --- .../rockchip64-6.12/dt/rk3328-mksklipad50.dts | 8 ++++---- .../rockchip64-6.14/dt/rk3328-mksklipad50.dts | 8 ++++---- .../02-rk3328-mksklipad50-add-uboot-dts.patch | 12 ++++++------ 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/patch/kernel/archive/rockchip64-6.12/dt/rk3328-mksklipad50.dts b/patch/kernel/archive/rockchip64-6.12/dt/rk3328-mksklipad50.dts index 56be1bcf5078..1bb606b704a1 100644 --- a/patch/kernel/archive/rockchip64-6.12/dt/rk3328-mksklipad50.dts +++ b/patch/kernel/archive/rockchip64-6.12/dt/rk3328-mksklipad50.dts @@ -14,8 +14,8 @@ compatible = "mks,rk3328-mksklipad50", "mks,rk3328-mkspi", "rockchip,rk3328"; aliases { - ethernet0 = "/ethernet@ff540000"; - ethernet1 = "/ethernet@ff550000"; + ethernet0 = &gmac2io; + ethernet1 = &gmac2phy; mmc0 = &sdmmc; mmc1 = &emmc; }; @@ -314,7 +314,7 @@ compatible = "rockchip,rk805"; reg = <0x18>; interrupt-parent = <&gpio1>; - interrupts = ; + interrupts = <24 IRQ_TYPE_LEVEL_LOW>; #clock-cells = <1>; clock-output-names = "xin32k", "rk805-clkout2"; gpio-controller; @@ -423,7 +423,7 @@ }; &pwm3 { - interrupts = ; + interrupts = ; }; &io_domains { diff --git a/patch/kernel/archive/rockchip64-6.14/dt/rk3328-mksklipad50.dts b/patch/kernel/archive/rockchip64-6.14/dt/rk3328-mksklipad50.dts index 56be1bcf5078..1bb606b704a1 100644 --- a/patch/kernel/archive/rockchip64-6.14/dt/rk3328-mksklipad50.dts +++ b/patch/kernel/archive/rockchip64-6.14/dt/rk3328-mksklipad50.dts @@ -14,8 +14,8 @@ compatible = "mks,rk3328-mksklipad50", "mks,rk3328-mkspi", "rockchip,rk3328"; aliases { - ethernet0 = "/ethernet@ff540000"; - ethernet1 = "/ethernet@ff550000"; + ethernet0 = &gmac2io; + ethernet1 = &gmac2phy; mmc0 = &sdmmc; mmc1 = &emmc; }; @@ -314,7 +314,7 @@ compatible = "rockchip,rk805"; reg = <0x18>; interrupt-parent = <&gpio1>; - interrupts = ; + interrupts = <24 IRQ_TYPE_LEVEL_LOW>; #clock-cells = <1>; clock-output-names = "xin32k", "rk805-clkout2"; gpio-controller; @@ -423,7 +423,7 @@ }; &pwm3 { - interrupts = ; + interrupts = ; }; &io_domains { diff --git a/patch/u-boot/u-boot-rockchip64/board_mksklipad50/02-rk3328-mksklipad50-add-uboot-dts.patch b/patch/u-boot/u-boot-rockchip64/board_mksklipad50/02-rk3328-mksklipad50-add-uboot-dts.patch index 294ab3f91472..7f88f3f9e666 100644 --- a/patch/u-boot/u-boot-rockchip64/board_mksklipad50/02-rk3328-mksklipad50-add-uboot-dts.patch +++ b/patch/u-boot/u-boot-rockchip64/board_mksklipad50/02-rk3328-mksklipad50-add-uboot-dts.patch @@ -1,12 +1,12 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Thorsten Maerz -Date: Fri, 31 Jan 2025 10:35:20 +0100 +Date: Thu, 06 Mar 2025 18:25:31 +0100 Subject: feat: Add u-boot dts for MKSKLIPAD50 board --- diff --git a/arch/arm/dts/rk3328-mksklipad50.dts b/arch/arm/dts/rk3328-mksklipad50.dts --- a/arch/arm/dts/rk3328-mksklipad50.dts 1970-01-01 01:00:00.000000000 +0100 -+++ b/arch/arm/dts/rk3328-mksklipad50.dts 2025-01-31 10:35:20.328782652 +0100 ++++ b/arch/arm/dts/rk3328-mksklipad50.dts 2025-03-06 18:25:31.937819640 +0100 @@ -0,0 +1,569 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* @@ -23,8 +23,8 @@ diff --git a/arch/arm/dts/rk3328-mksklipad50.dts b/arch/arm/dts/rk3328-mksklipad + compatible = "mks,rk3328-mksklipad50", "mks,rk3328-mkspi", "rockchip,rk3328"; + + aliases { -+ ethernet0 = "/ethernet@ff540000"; -+ ethernet1 = "/ethernet@ff550000"; ++ ethernet0 = &gmac2io; ++ ethernet1 = &gmac2phy; + mmc0 = &sdmmc; + mmc1 = &emmc; + }; @@ -286,7 +286,7 @@ diff --git a/arch/arm/dts/rk3328-mksklipad50.dts b/arch/arm/dts/rk3328-mksklipad + compatible = "rockchip,rk805"; + reg = <0x18>; + interrupt-parent = <&gpio1>; -+ interrupts = ; ++ interrupts = <24 IRQ_TYPE_LEVEL_LOW>; + #clock-cells = <1>; + clock-output-names = "xin32k", "rk805-clkout2"; + gpio-controller; @@ -395,7 +395,7 @@ diff --git a/arch/arm/dts/rk3328-mksklipad50.dts b/arch/arm/dts/rk3328-mksklipad +}; + +&pwm3 { -+ interrupts = ; ++ interrupts = ; +}; + +&io_domains { From fac5777a46cdeb1887cac42cb7a08e982d7004f3 Mon Sep 17 00:00:00 2001 From: Thorsten Maerz Date: Fri, 7 Mar 2025 10:36:22 +0100 Subject: [PATCH 10/37] mksklipad50: switch to uboot v2025.01 Fixes loading initramfs into EFI memory region, leading to errors "efi_free_pool: illegal free". Which may be the cause for these bootloops: https://github.com/armbian/build/pull/7883#issuecomment-2694110296 See also: https://lore.kernel.org/all/d3f3fc7f-b29a-4503-9fe0-97468bbe1f71@gmx.de/ --- config/boards/mksklipad50.conf | 3 +++ .../01-rk3328-mksklipad50-add-defconfig.patch | 2 +- .../02-rk3328-mksklipad50-add-uboot-dts.patch | 8 ++++---- 3 files changed, 8 insertions(+), 5 deletions(-) rename patch/u-boot/{u-boot-rockchip64 => v2025.01}/board_mksklipad50/01-rk3328-mksklipad50-add-defconfig.patch (98%) rename patch/u-boot/{u-boot-rockchip64 => v2025.01}/board_mksklipad50/02-rk3328-mksklipad50-add-uboot-dts.patch (97%) diff --git a/config/boards/mksklipad50.conf b/config/boards/mksklipad50.conf index 2f7c9e71209d..5ba4cc900847 100644 --- a/config/boards/mksklipad50.conf +++ b/config/boards/mksklipad50.conf @@ -10,3 +10,6 @@ BOOT_LOGO="desktop" MODULES="pinctrl-rk805 ads7846 spidev" BOOTFS_TYPE="fat" PACKAGE_LIST_BOARD="build-essential usb-modeswitch" + +BOOTBRANCH='tag:v2025.01' +BOOTPATCHDIR='v2025.01' diff --git a/patch/u-boot/u-boot-rockchip64/board_mksklipad50/01-rk3328-mksklipad50-add-defconfig.patch b/patch/u-boot/v2025.01/board_mksklipad50/01-rk3328-mksklipad50-add-defconfig.patch similarity index 98% rename from patch/u-boot/u-boot-rockchip64/board_mksklipad50/01-rk3328-mksklipad50-add-defconfig.patch rename to patch/u-boot/v2025.01/board_mksklipad50/01-rk3328-mksklipad50-add-defconfig.patch index 5310ec16588f..bc86ea1bf2e4 100644 --- a/patch/u-boot/u-boot-rockchip64/board_mksklipad50/01-rk3328-mksklipad50-add-defconfig.patch +++ b/patch/u-boot/v2025.01/board_mksklipad50/01-rk3328-mksklipad50-add-defconfig.patch @@ -21,7 +21,7 @@ index 0000000000..1514ee63bb +CONFIG_SPL_GPIO=y +CONFIG_NR_DRAM_BANKS=1 +CONFIG_ENV_OFFSET=0x3F8000 -+CONFIG_DEFAULT_DEVICE_TREE="rk3328-mksklipad50" ++CONFIG_DEFAULT_DEVICE_TREE="rockchip/rk3328-mksklipad50" +CONFIG_ROCKCHIP_RK3328=y +CONFIG_TPL_ROCKCHIP_COMMON_BOARD=y +CONFIG_TPL_LIBCOMMON_SUPPORT=y diff --git a/patch/u-boot/u-boot-rockchip64/board_mksklipad50/02-rk3328-mksklipad50-add-uboot-dts.patch b/patch/u-boot/v2025.01/board_mksklipad50/02-rk3328-mksklipad50-add-uboot-dts.patch similarity index 97% rename from patch/u-boot/u-boot-rockchip64/board_mksklipad50/02-rk3328-mksklipad50-add-uboot-dts.patch rename to patch/u-boot/v2025.01/board_mksklipad50/02-rk3328-mksklipad50-add-uboot-dts.patch index 7f88f3f9e666..04d6ab3858a7 100644 --- a/patch/u-boot/u-boot-rockchip64/board_mksklipad50/02-rk3328-mksklipad50-add-uboot-dts.patch +++ b/patch/u-boot/v2025.01/board_mksklipad50/02-rk3328-mksklipad50-add-uboot-dts.patch @@ -4,10 +4,10 @@ Date: Thu, 06 Mar 2025 18:25:31 +0100 Subject: feat: Add u-boot dts for MKSKLIPAD50 board --- -diff --git a/arch/arm/dts/rk3328-mksklipad50.dts b/arch/arm/dts/rk3328-mksklipad50.dts ---- a/arch/arm/dts/rk3328-mksklipad50.dts 1970-01-01 01:00:00.000000000 +0100 -+++ b/arch/arm/dts/rk3328-mksklipad50.dts 2025-03-06 18:25:31.937819640 +0100 -@@ -0,0 +1,569 @@ +diff --git a/dts/upstream/src/arm64/rockchip/rk3328-mksklipad50.dts b/dts/upstream/src/arm64/rockchip/rk3328-mksklipad50.dts +--- a/dts/upstream/src/arm64/rockchip/rk3328-mksklipad50.dts 1970-01-01 01:00:00.000000000 +0100 ++++ b/dts/upstream/src/arm64/rockchip/rk3328-mksklipad50.dts 2025-03-06 18:25:31.937819640 +0100 +@@ -0,0 +1,571 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Based on rk3328-roc-cc.dtb from original MKS-Klipad50 image From d5531e5ec6cf80e92daf999101cd4abcec221abe Mon Sep 17 00:00:00 2001 From: Thorsten Maerz Date: Thu, 6 Mar 2025 18:46:02 +0100 Subject: [PATCH 11/37] mksklipad50: uboot2025: generate trust.ini (bl31.elf) --- .../04-rk3328-mksklipad50-add-trust-ini.patch | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 patch/u-boot/v2025.01/board_mksklipad50/04-rk3328-mksklipad50-add-trust-ini.patch diff --git a/patch/u-boot/v2025.01/board_mksklipad50/04-rk3328-mksklipad50-add-trust-ini.patch b/patch/u-boot/v2025.01/board_mksklipad50/04-rk3328-mksklipad50-add-trust-ini.patch new file mode 100644 index 000000000000..ca3b1c3509ae --- /dev/null +++ b/patch/u-boot/v2025.01/board_mksklipad50/04-rk3328-mksklipad50-add-trust-ini.patch @@ -0,0 +1,29 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Thorsten Maerz +Date: Thu, 06 Mar 2025 11:09:00 +0100 +Subject: Add uboot trust.ini (bl31.elf) + +Build trust.ini (required for uboot) +--- + +diff --git a/trust.ini b/trust.ini +new file mode 100644 +index 0000000..4af021a +--- /dev/null ++++ b/trust.ini +@@ -0,0 +1,15 @@ ++[VERSION] ++MAJOR=1 ++MINOR=0 ++[BL30_OPTION] ++SEC=0 ++[BL31_OPTION] ++SEC=1 ++PATH=bl31.elf ++ADDR=0x10000 ++[BL32_OPTION] ++SEC=0 ++[BL33_OPTION] ++SEC=0 ++[OUTPUT] ++PATH=trust.bin From 51f2085b2d751b3d8ed2bfc869ca3fe4abe7033e Mon Sep 17 00:00:00 2001 From: Thorsten Maerz Date: Thu, 6 Mar 2025 18:41:42 +0100 Subject: [PATCH 12/37] mksklipad50: uboot2025: fix usb dwc2-otg/dwc3-host compile RK3328 board with dwc2-otg and dwc3-host run into "multiple definition of 'dm_usb_gadget_handle_interrupts'" See https://lore.kernel.org/u-boot/7805b8d0-fb7c-41d5-8d74-f85dfd40233a@kwiboo.se/ --- .../03-rk3328-mksklipad50-uboot-dwc3.patch | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 patch/u-boot/v2025.01/board_mksklipad50/03-rk3328-mksklipad50-uboot-dwc3.patch diff --git a/patch/u-boot/v2025.01/board_mksklipad50/03-rk3328-mksklipad50-uboot-dwc3.patch b/patch/u-boot/v2025.01/board_mksklipad50/03-rk3328-mksklipad50-uboot-dwc3.patch new file mode 100644 index 000000000000..d58d38c0ce0e --- /dev/null +++ b/patch/u-boot/v2025.01/board_mksklipad50/03-rk3328-mksklipad50-uboot-dwc3.patch @@ -0,0 +1,37 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Thorsten Maerz +Date: Thu, 06 Mar 2025 11:09:00 +0100 +Subject: Fix multiple dwc2/dwc3 definitions + +Fixes "multiple definition of 'dm_usb_gadget_handle_interrupts'" +See https://lore.kernel.org/u-boot/7805b8d0-fb7c-41d5-8d74-f85dfd40233a@kwiboo.se/ +--- + +diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c +index 2ab41cbae4..ccc1803fb3 100644 +--- a/drivers/usb/dwc3/dwc3-generic.c ++++ b/drivers/usb/dwc3/dwc3-generic.c +@@ -192,7 +192,7 @@ static int dwc3_generic_of_to_plat(struct udevice *dev) + return 0; + } + +-#if CONFIG_IS_ENABLED(DM_USB_GADGET) ++#if IS_ENABLED(CONFIG_USB_DWC3_GADGET) && CONFIG_IS_ENABLED(DM_USB_GADGET) + static int dwc3_generic_peripheral_probe(struct udevice *dev) + { + struct dwc3_generic_priv *priv = dev_get_priv(dev); + + +diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c +index a35b8c2f64..9bd06afe0a 100644 +--- a/drivers/usb/dwc3/core.c ++++ b/drivers/usb/dwc3/core.c +@@ -988,7 +988,7 @@ MODULE_AUTHOR("Felipe Balbi "); + MODULE_LICENSE("GPL v2"); + MODULE_DESCRIPTION("DesignWare USB3 DRD Controller Driver"); + +-#if !CONFIG_IS_ENABLED(DM_USB_GADGET) ++#if IS_ENABLED(CONFIG_USB_DWC3_GADGET) && !CONFIG_IS_ENABLED(DM_USB_GADGET) + __weak int dwc3_uboot_interrupt_status(struct udevice *dev) + { + return 1; From 36321026b98857271de250d580222dc0fb63b323 Mon Sep 17 00:00:00 2001 From: Thorsten Maerz Date: Thu, 6 Mar 2025 19:24:22 +0100 Subject: [PATCH 13/37] mksklipad50: uboot2025: enable usb for serial access --- .../board_mksklipad50/02-rk3328-mksklipad50-add-uboot-dts.patch | 2 ++ 1 file changed, 2 insertions(+) diff --git a/patch/u-boot/v2025.01/board_mksklipad50/02-rk3328-mksklipad50-add-uboot-dts.patch b/patch/u-boot/v2025.01/board_mksklipad50/02-rk3328-mksklipad50-add-uboot-dts.patch index 04d6ab3858a7..39b4c233a197 100644 --- a/patch/u-boot/v2025.01/board_mksklipad50/02-rk3328-mksklipad50-add-uboot-dts.patch +++ b/patch/u-boot/v2025.01/board_mksklipad50/02-rk3328-mksklipad50-add-uboot-dts.patch @@ -556,10 +556,12 @@ diff --git a/dts/upstream/src/arm64/rockchip/rk3328-mksklipad50.dts b/dts/upstre +}; + +&usb_host0_ehci { ++ bootph-all; + status = "okay"; +}; + +&usb_host0_ohci { ++ bootph-all; + status = "okay"; +}; + From db5dc5ef7adbdc51c194604ebb2df8ae152dc826 Mon Sep 17 00:00:00 2001 From: Thorsten Maerz Date: Thu, 6 Mar 2025 19:34:41 +0100 Subject: [PATCH 14/37] mksklipad50: uboot2025: add boot delay (for uart to come up) --- config/boards/mksklipad50.conf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/config/boards/mksklipad50.conf b/config/boards/mksklipad50.conf index 5ba4cc900847..63d43835fc62 100644 --- a/config/boards/mksklipad50.conf +++ b/config/boards/mksklipad50.conf @@ -13,3 +13,7 @@ PACKAGE_LIST_BOARD="build-essential usb-modeswitch" BOOTBRANCH='tag:v2025.01' BOOTPATCHDIR='v2025.01' + +function post_family_config__uboot_config() { + BOOTDELAY=1 # Wait for UART +} From 0dbd7bfc9520d515eff6db5b867a248b8660ac64 Mon Sep 17 00:00:00 2001 From: SuperKali Date: Sat, 8 Mar 2025 14:14:46 +0100 Subject: [PATCH 15/37] rockchip64-6.14: Set dma mask to 64 bit (#7924) --- ...-drm-rockchip-Set-dma-mask-to-64-bit.patch | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 patch/kernel/archive/rockchip64-6.14/general-drm-rockchip-Set-dma-mask-to-64-bit.patch diff --git a/patch/kernel/archive/rockchip64-6.14/general-drm-rockchip-Set-dma-mask-to-64-bit.patch b/patch/kernel/archive/rockchip64-6.14/general-drm-rockchip-Set-dma-mask-to-64-bit.patch new file mode 100644 index 000000000000..7ce7354e6e37 --- /dev/null +++ b/patch/kernel/archive/rockchip64-6.14/general-drm-rockchip-Set-dma-mask-to-64-bit.patch @@ -0,0 +1,39 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: SuperKali +Date: Fri, 7 Mar 2025 15:06:42 +0000 +Subject: drm/rockchip: Set dma mask to 64 bit + +The vop mmu support translate physical address upper 4 GB to iova +below 4 GB. So set dma mask to 64 bit to indicate we support address +> 4GB. + +This can avoid warnging message like this on some boards with DDR +> 4 GB: + +rockchip-drm display-subsystem: swiotlb buffer is full (sz: 266240 bytes), total 32768 (slots), used 130 (slots) +rockchip-drm display-subsystem: swiotlb buffer is full (sz: 266240 bytes), total 32768 (slots), used 0 (slots) +rockchip-drm display-subsystem: swiotlb buffer is full (sz: 266240 bytes), total 32768 (slots), used 130 (slots) +rockchip-drm display-subsystem: swiotlb buffer is full (sz: 266240 bytes), total 32768 (slots), used 130 (slots) +rockchip-drm display-subsystem: swiotlb buffer is full (sz: 266240 bytes), total 32768 (slots), used 0 (slots) +--- + drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +index 111111111111..222222222222 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +@@ -472,7 +472,9 @@ static int rockchip_drm_platform_probe(struct platform_device *pdev) + return ret; + } + +- return 0; ++ ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(64)); ++ ++ return ret; + } + + static void rockchip_drm_platform_remove(struct platform_device *pdev) +-- +Armbian + From 827d673db40d7c280821d1288d618f8be145909c Mon Sep 17 00:00:00 2001 From: Lane Jennison Date: Sat, 8 Mar 2025 12:05:33 -0500 Subject: [PATCH 16/37] rk3568: removed phy patch that was merged in 6.12.18 --- ...combphy_compatible_reset_with_old_dt.patch | 46 ------------------- 1 file changed, 46 deletions(-) delete mode 100644 patch/kernel/archive/rockchip64-6.12/rk3568-bugfix-amadeus_phy_rockchip_naneng_combphy_compatible_reset_with_old_dt.patch diff --git a/patch/kernel/archive/rockchip64-6.12/rk3568-bugfix-amadeus_phy_rockchip_naneng_combphy_compatible_reset_with_old_dt.patch b/patch/kernel/archive/rockchip64-6.12/rk3568-bugfix-amadeus_phy_rockchip_naneng_combphy_compatible_reset_with_old_dt.patch deleted file mode 100644 index 28c1db437288..000000000000 --- a/patch/kernel/archive/rockchip64-6.12/rk3568-bugfix-amadeus_phy_rockchip_naneng_combphy_compatible_reset_with_old_dt.patch +++ /dev/null @@ -1,46 +0,0 @@ -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH v2 1/1] phy: rockchip: naneng-combphy: compatible reset with old DT -From: Chukun Pan -Date: Mon, 06 Jan 2025 18:00:01 +0800 -Message-Id: <20250106100001.1344418-2-amadeus@jmu.edu.cn> -To: Vinod Koul -Cc: Heiko Stuebner , Philipp Zabel , Kishon Vijay Abraham I , Jianfeng Liu , linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, linux-phy@lists.infradead.org, linux-kernel@vger.kernel.org, Chukun Pan -In-Reply-To: <20250106100001.1344418-1-amadeus@jmu.edu.cn> -References: <20250106100001.1344418-1-amadeus@jmu.edu.cn> -List-Id: -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -The device tree of RK3568 did not specify reset-names before. -So add fallback to old behaviour to be compatible with old DT. - -Fixes: fbcbffbac994 ("phy: rockchip: naneng-combphy: fix phy reset") -Cc: Jianfeng Liu -Signed-off-by: Chukun Pan -Reviewed-by: Jonas Karlman ---- - drivers/phy/rockchip/phy-rockchip-naneng-combphy.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c -index a1532ef8bbe9..8c3ce57f8915 100644 ---- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c -+++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c -@@ -324,7 +324,10 @@ static int rockchip_combphy_parse_dt(struct device *dev, struct rockchip_combphy - - priv->ext_refclk = device_property_present(dev, "rockchip,ext-refclk"); - -- priv->phy_rst = devm_reset_control_get(dev, "phy"); -+ priv->phy_rst = devm_reset_control_get_exclusive(dev, "phy"); -+ /* fallback to old behaviour */ -+ if (PTR_ERR(priv->phy_rst) == -ENOENT) -+ priv->phy_rst = devm_reset_control_array_get_exclusive(dev); - if (IS_ERR(priv->phy_rst)) - return dev_err_probe(dev, PTR_ERR(priv->phy_rst), "failed to get phy reset\n"); - - --- -2.25.1 - - From f505cc6cea9c9af5e4d2f64472b68e5e3fbb8690 Mon Sep 17 00:00:00 2001 From: Lane Jennison Date: Sat, 8 Mar 2025 12:32:48 -0500 Subject: [PATCH 17/37] rk3568: removed phy patch that was merged in 6.6.81 --- ...combphy_compatible_reset_with_old_dt.patch | 46 ------------------- 1 file changed, 46 deletions(-) delete mode 100644 patch/kernel/archive/rockchip64-6.6/rk3568-bugfix-amadeus_phy_rockchip_naneng_combphy_compatible_reset_with_old_dt.patch diff --git a/patch/kernel/archive/rockchip64-6.6/rk3568-bugfix-amadeus_phy_rockchip_naneng_combphy_compatible_reset_with_old_dt.patch b/patch/kernel/archive/rockchip64-6.6/rk3568-bugfix-amadeus_phy_rockchip_naneng_combphy_compatible_reset_with_old_dt.patch deleted file mode 100644 index 28c1db437288..000000000000 --- a/patch/kernel/archive/rockchip64-6.6/rk3568-bugfix-amadeus_phy_rockchip_naneng_combphy_compatible_reset_with_old_dt.patch +++ /dev/null @@ -1,46 +0,0 @@ -From git@z Thu Jan 1 00:00:00 1970 -Subject: [PATCH v2 1/1] phy: rockchip: naneng-combphy: compatible reset with old DT -From: Chukun Pan -Date: Mon, 06 Jan 2025 18:00:01 +0800 -Message-Id: <20250106100001.1344418-2-amadeus@jmu.edu.cn> -To: Vinod Koul -Cc: Heiko Stuebner , Philipp Zabel , Kishon Vijay Abraham I , Jianfeng Liu , linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, linux-phy@lists.infradead.org, linux-kernel@vger.kernel.org, Chukun Pan -In-Reply-To: <20250106100001.1344418-1-amadeus@jmu.edu.cn> -References: <20250106100001.1344418-1-amadeus@jmu.edu.cn> -List-Id: -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 7bit - -The device tree of RK3568 did not specify reset-names before. -So add fallback to old behaviour to be compatible with old DT. - -Fixes: fbcbffbac994 ("phy: rockchip: naneng-combphy: fix phy reset") -Cc: Jianfeng Liu -Signed-off-by: Chukun Pan -Reviewed-by: Jonas Karlman ---- - drivers/phy/rockchip/phy-rockchip-naneng-combphy.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c -index a1532ef8bbe9..8c3ce57f8915 100644 ---- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c -+++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c -@@ -324,7 +324,10 @@ static int rockchip_combphy_parse_dt(struct device *dev, struct rockchip_combphy - - priv->ext_refclk = device_property_present(dev, "rockchip,ext-refclk"); - -- priv->phy_rst = devm_reset_control_get(dev, "phy"); -+ priv->phy_rst = devm_reset_control_get_exclusive(dev, "phy"); -+ /* fallback to old behaviour */ -+ if (PTR_ERR(priv->phy_rst) == -ENOENT) -+ priv->phy_rst = devm_reset_control_array_get_exclusive(dev); - if (IS_ERR(priv->phy_rst)) - return dev_err_probe(dev, PTR_ERR(priv->phy_rst), "failed to get phy reset\n"); - - --- -2.25.1 - - From 00d19ecd87f369738afecfaa8c2016dbc7e7f86e Mon Sep 17 00:00:00 2001 From: Aleksey Komarov Date: Sat, 8 Mar 2025 13:16:48 +0300 Subject: [PATCH 18/37] Enable HDMI audio outputs for Rock 5B by detlev.casanova@collabora.com https://lore.kernel.org/all/20250217215641.372723-4-detlev.casanova@collabora.com/ --- ...-dts-rockchip-Rock-5B-add-hdmi-sound.patch | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 patch/kernel/archive/rockchip64-6.14/rk3588-1102-arm64-dts-rockchip-Rock-5B-add-hdmi-sound.patch diff --git a/patch/kernel/archive/rockchip64-6.14/rk3588-1102-arm64-dts-rockchip-Rock-5B-add-hdmi-sound.patch b/patch/kernel/archive/rockchip64-6.14/rk3588-1102-arm64-dts-rockchip-Rock-5B-add-hdmi-sound.patch new file mode 100644 index 000000000000..54b9a056a910 --- /dev/null +++ b/patch/kernel/archive/rockchip64-6.14/rk3588-1102-arm64-dts-rockchip-Rock-5B-add-hdmi-sound.patch @@ -0,0 +1,58 @@ +From: Detlev Casanova +Subject: [PATCH v7 3/3] arm64: dts: rockchip: Enable HDMI audio outputs for Rock 5B +Date: Mon, 17 Feb 2025 16:47:42 -0500 [thread overview] +Message-ID: <20250217215641.372723-4-detlev.casanova@collabora.com> (raw) +In-Reply-To: <20250217215641.372723-1-detlev.casanova@collabora.com> + +HDMI audio is available on the Rock 5B HDMI TX ports. +Enable it for both ports. + +Reviewed-by: Quentin Schulz +Signed-off-by: Detlev Casanova +--- + arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts +index 27128c6a05a2f..8f42cd0427701 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts +@@ -231,6 +231,10 @@ hdmi0_out_con: endpoint { + }; + }; + ++&hdmi0_sound { ++ status = "okay"; ++}; ++ + &hdmi1 { + pinctrl-0 = <&hdmim0_tx1_cec &hdmim0_tx1_hpd + &hdmim1_tx1_scl &hdmim1_tx1_sda>; +@@ -249,6 +253,10 @@ hdmi1_out_con: endpoint { + }; + }; + ++&hdmi1_sound { ++ status = "okay"; ++}; ++ + &hdptxphy0 { + status = "okay"; + }; +@@ -351,6 +359,14 @@ i2s0_8ch_p0_0: endpoint { + }; + }; + ++&i2s5_8ch { ++ status = "okay"; ++}; ++ ++&i2s6_8ch { ++ status = "okay"; ++}; ++ + &package_thermal { + polling-delay = <1000>; + +-- +2.48.1 From 4118ca0c5eb7de96844c79b981040323b77963dd Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Tue, 28 Jan 2025 10:33:11 -0600 Subject: [PATCH 19/37] Add initial support for BeagleBone AI-64 --- config/boards/beaglebone-ai64.conf | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 config/boards/beaglebone-ai64.conf diff --git a/config/boards/beaglebone-ai64.conf b/config/boards/beaglebone-ai64.conf new file mode 100644 index 000000000000..7efd7acb4688 --- /dev/null +++ b/config/boards/beaglebone-ai64.conf @@ -0,0 +1,18 @@ +# BeagleBone® AI-64 dual core 4GB GBE USB3 OSPI DisplayPort HDMI + +BOARD_NAME="BeagleBone AI-64" +BOARDFAMILY="k3" +BOARD_MAINTAINER="grippy98" +BOOTCONFIG="j721e_beagleboneai64_a72_defconfig" +BOOTFS_TYPE="fat" +BOOT_FDT_FILE="ti/k3-j721e-beagleboneai64.dts" +TIBOOT3_BOOTCONFIG="j721e_beagleboneai64_r5_defconfig" +TIBOOT3_FILE="tiboot3-j721e-gp-evm.bin" +SYSFW_FILE="sysfw-j721e-gp-evm.itb" +TISPL_FILE="tispl.bin_unsigned" +UBOOT_FILE="u-boot.img_unsigned" +DEFAULT_CONSOLE="serial" +KERNEL_TARGET="current,edge" +KERNEL_TEST_TARGET="current" +SERIALCON="ttyS2" +ATF_BOARD="generic" From 8ca6079fa9dfffe24552bbfc6a202b710cae17f6 Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Tue, 28 Jan 2025 10:33:11 -0600 Subject: [PATCH 20/37] Add initial support for BeaglePlay --- config/boards/beagleplay.conf | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 config/boards/beagleplay.conf diff --git a/config/boards/beagleplay.conf b/config/boards/beagleplay.conf new file mode 100644 index 000000000000..a1f819aabfb2 --- /dev/null +++ b/config/boards/beagleplay.conf @@ -0,0 +1,17 @@ +# TI AM62 quad core 2GB DDR4 16GB eMMC 1xGBE 1xSPE HDMI + +BOARD_NAME="BeaglePlay" +BOARDFAMILY="k3" +BOARD_MAINTAINER="grippy98" +BOOTCONFIG="am62x_beagleplay_a53_defconfig" +BOOTFS_TYPE="fat" +BOOT_FDT_FILE="ti/k3-am625-beagleplay.dts" +TIBOOT3_BOOTCONFIG="am62x_beagleplay_r5_defconfig" +TIBOOT3_FILE="tiboot3-am62x-gp-evm.bin" +TISPL_FILE="tispl.bin_unsigned" +UBOOT_FILE="u-boot.img_unsigned" +DEFAULT_CONSOLE="serial" +KERNEL_TARGET="current,edge" +KERNEL_TEST_TARGET="current" +SERIALCON="ttyS2" +ATF_BOARD="lite" From 131de37e5962a30913b31d06391af8c2267352f0 Mon Sep 17 00:00:00 2001 From: Igor Pecovnik Date: Thu, 6 Mar 2025 18:32:12 +0100 Subject: [PATCH 21/37] Raspbery Pi: legacy kernel is missing support for CONFIG_FW_LOADER_COMPRESS --- config/boards/rpi4b.conf | 2 +- config/kernel/linux-bcm2711-legacy.config | 117 ++++++++++++---------- 2 files changed, 67 insertions(+), 52 deletions(-) diff --git a/config/boards/rpi4b.conf b/config/boards/rpi4b.conf index 49a86cb6766e..f6a3512e7b24 100644 --- a/config/boards/rpi4b.conf +++ b/config/boards/rpi4b.conf @@ -2,7 +2,7 @@ declare -g BOARD_NAME="Raspberry Pi" declare -g BOARDFAMILY="bcm2711" declare -g BOARD_MAINTAINER="PanderMusubi teknoid" -declare -g KERNEL_TARGET="current,edge" +declare -g KERNEL_TARGET="legacy,current,edge" declare -g ASOUND_STATE="asound.state.rpi" declare -g KERNEL_TEST_TARGET="current" declare -g MODULES="i2c_dev" diff --git a/config/kernel/linux-bcm2711-legacy.config b/config/kernel/linux-bcm2711-legacy.config index 7c1d3b945e1e..c4c2d392f6ef 100644 --- a/config/kernel/linux-bcm2711-legacy.config +++ b/config/kernel/linux-bcm2711-legacy.config @@ -75,8 +75,6 @@ CONFIG_BINFMT_MISC=m CONFIG_ZSWAP=y CONFIG_ZSWAP_DEFAULT_ON=y CONFIG_ZSWAP_COMPRESSOR_DEFAULT_ZSTD=y -CONFIG_ZSWAP_ZPOOL_DEFAULT_Z3FOLD=y -CONFIG_ZBUD=y CONFIG_ZSMALLOC=y # CONFIG_COMPAT_BRK is not set CONFIG_TRANSPARENT_HUGEPAGE=y @@ -86,13 +84,11 @@ CONFIG_PERCPU_STATS=y CONFIG_NET=y CONFIG_PACKET=y CONFIG_PACKET_DIAG=m -CONFIG_UNIX=y CONFIG_UNIX_DIAG=m CONFIG_TLS=y CONFIG_XFRM_USER=m CONFIG_XFRM_INTERFACE=m CONFIG_NET_KEY=m -CONFIG_INET=y CONFIG_IP_MULTICAST=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_FIB_TRIE_STATS=y @@ -181,7 +177,6 @@ CONFIG_NFT_MASQ=m CONFIG_NFT_REDIR=m CONFIG_NFT_NAT=m CONFIG_NFT_TUNNEL=m -CONFIG_NFT_OBJREF=m CONFIG_NFT_QUEUE=m CONFIG_NFT_QUOTA=m CONFIG_NFT_REJECT=m @@ -318,7 +313,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_MANGLE=m -CONFIG_IP_NF_TARGET_CLUSTERIP=m CONFIG_IP_NF_TARGET_ECN=m CONFIG_IP_NF_TARGET_TTL=m CONFIG_IP_NF_RAW=m @@ -446,7 +440,6 @@ CONFIG_NET_ACT_SIMP=m CONFIG_NET_ACT_SKBEDIT=m CONFIG_NET_ACT_CSUM=m CONFIG_DCB=y -CONFIG_DNS_RESOLVER=y CONFIG_BATMAN_ADV=m CONFIG_OPENVSWITCH=m CONFIG_VSOCKETS=m @@ -503,13 +496,17 @@ CONFIG_NET_9P=m CONFIG_NET_9P_VIRTIO=m CONFIG_NFC=m CONFIG_PCI=y +CONFIG_PCIEPORTBUS=y +CONFIG_PCIEAER=y +CONFIG_PCIEASPM_POWERSAVE=y +CONFIG_PCIE_DPC=y CONFIG_CXL_BUS=m CONFIG_UEVENT_HELPER=y CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y -CONFIG_ARM_FFA_TRANSPORT=m -CONFIG_EFI_VARS_PSTORE=m -CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER=y +CONFIG_FW_LOADER_COMPRESS=y +CONFIG_FW_LOADER_COMPRESS_ZSTD=y +# CONFIG_EFI_VARS_PSTORE is not set CONFIG_MTD=m CONFIG_MTD_BLOCK=m CONFIG_MTD_PSTORE=m @@ -526,9 +523,11 @@ CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y CONFIG_CDROM_PKTCDVD=m CONFIG_ATA_OVER_ETH=m -CONFIG_VIRTIO_BLK=m +CONFIG_BLK_DEV_RBD=m +CONFIG_BLK_DEV_UBLK=m CONFIG_BLK_DEV_NVME=y -CONFIG_DW_XDATA_PCIE=m +CONFIG_NVME_HWMON=y +CONFIG_SRAM=y CONFIG_EEPROM_AT24=m CONFIG_EEPROM_AT25=m CONFIG_EEPROM_LEGACY=m @@ -550,16 +549,21 @@ CONFIG_SATA_AHCI=m CONFIG_SATA_MV=m CONFIG_MD=y CONFIG_MD_LINEAR=m +CONFIG_BCACHE=m CONFIG_BLK_DEV_DM=m CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m CONFIG_DM_THIN_PROVISIONING=m CONFIG_DM_CACHE=m +CONFIG_DM_WRITECACHE=m CONFIG_DM_MIRROR=m CONFIG_DM_LOG_USERSPACE=m CONFIG_DM_RAID=m CONFIG_DM_ZERO=m +CONFIG_DM_MULTIPATH=m CONFIG_DM_DELAY=m +CONFIG_DM_VERITY=m +CONFIG_DM_INTEGRITY=m CONFIG_NETDEVICES=y CONFIG_BONDING=m CONFIG_DUMMY=m @@ -711,12 +715,18 @@ CONFIG_RT2800USB_UNKNOWN=y CONFIG_RTL8187=m CONFIG_RTL8192CU=m CONFIG_RTL8XXXU=m +CONFIG_RTW88=m +CONFIG_RTW88_8822BU=m +CONFIG_RTW88_8822CU=m +CONFIG_RTW88_8723DU=m +CONFIG_RTW88_8821CU=m +CONFIG_RTL8821CU=m CONFIG_88XXAU=m CONFIG_RTL8192EU=m CONFIG_USB_ZD1201=m CONFIG_ZD1211RW=m -CONFIG_MAC80211_HWSIM=m CONFIG_USB_NET_RNDIS_WLAN=m +CONFIG_MAC80211_HWSIM=m CONFIG_IEEE802154_AT86RF230=m CONFIG_IEEE802154_MRF24J40=m CONFIG_IEEE802154_CC2520=m @@ -740,7 +750,6 @@ CONFIG_JOYSTICK_XPAD_LEDS=y CONFIG_JOYSTICK_PSXPAD_SPI=m CONFIG_JOYSTICK_PSXPAD_SPI_FF=y CONFIG_JOYSTICK_QWIIC=m -CONFIG_JOYSTICK_RPISENSE=m CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_ADS7846=m CONFIG_TOUCHSCREEN_EGALAX=m @@ -750,9 +759,13 @@ CONFIG_TOUCHSCREEN_HYCON_HY46XX=m CONFIG_TOUCHSCREEN_ILI210X=m CONFIG_TOUCHSCREEN_ILITEK=m CONFIG_TOUCHSCREEN_MSG2638=m +CONFIG_TOUCHSCREEN_IMAGIS=m CONFIG_TOUCHSCREEN_EDT_FT5X06=m CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_TSC2007=m +CONFIG_TOUCHSCREEN_TSC2007_IIO=y CONFIG_TOUCHSCREEN_STMPE=m +CONFIG_TOUCHSCREEN_IQS5XX=m CONFIG_INPUT_MISC=y CONFIG_INPUT_AD714X=m CONFIG_INPUT_ATC260X_ONKEY=m @@ -773,10 +786,7 @@ CONFIG_RMI4_SMB=m CONFIG_SERIO=m CONFIG_SERIO_RAW=m CONFIG_GAMEPORT=m -CONFIG_GAMEPORT_NS558=m -CONFIG_GAMEPORT_L4=m CONFIG_BRCM_CHAR_DRIVERS=y -CONFIG_RPIVID_MEM=m # CONFIG_LEGACY_PTYS is not set CONFIG_SERIAL_8250=y # CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set @@ -799,7 +809,6 @@ CONFIG_TCG_TPM=m CONFIG_TCG_TIS_SPI=m CONFIG_TCG_TIS_I2C_CR50=m CONFIG_XILLYUSB=m -# CONFIG_RANDOM_TRUST_CPU is not set CONFIG_I2C=y CONFIG_I2C_CHARDEV=m CONFIG_I2C_MUX_GPMUX=m @@ -811,7 +820,11 @@ CONFIG_I2C_ROBOTFUZZ_OSIF=m CONFIG_I2C_TINY_USB=m CONFIG_I2C_VIRTIO=m CONFIG_SPI=y +CONFIG_SPI_DESIGNWARE=m +CONFIG_SPI_DW_DMA=y +CONFIG_SPI_DW_MMIO=m CONFIG_SPI_GPIO=m +CONFIG_SPI_RP2040_GPIO_BRIDGE=m CONFIG_SPI_SPIDEV=m CONFIG_SPI_SLAVE=y CONFIG_PPS=m @@ -820,6 +833,7 @@ CONFIG_PPS_CLIENT_GPIO=m # CONFIG_PTP_1588_CLOCK is not set CONFIG_PINCTRL=y CONFIG_PINCTRL_MCP23S08=m +CONFIG_PINCTRL_RP1=y CONFIG_GPIO_SYSFS=y CONFIG_GPIO_ADNP=m CONFIG_GPIO_GW_PLD=m @@ -843,7 +857,6 @@ CONFIG_GPIO_VIRTIO=m CONFIG_W1=m CONFIG_W1_MASTER_DS2490=m CONFIG_W1_MASTER_DS2482=m -CONFIG_W1_MASTER_DS1WM=m CONFIG_W1_MASTER_GPIO=m CONFIG_W1_MASTER_SGI=m CONFIG_W1_SLAVE_THERM=m @@ -864,15 +877,19 @@ CONFIG_W1_SLAVE_DS28E04=m CONFIG_W1_SLAVE_DS28E17=m CONFIG_POWER_RESET_ATC260X=m CONFIG_POWER_RESET_GPIO=y +CONFIG_IP5XXX_POWER=m CONFIG_CHARGER_ADP5061=m CONFIG_BATTERY_CW2015=m CONFIG_BATTERY_DS2760=m CONFIG_BATTERY_MAX17040=m CONFIG_BATTERY_MAX1721X=m +CONFIG_CHARGER_GPIO=m CONFIG_CHARGER_LTC4162L=m +CONFIG_CHARGER_MAX77976=m CONFIG_CHARGER_BQ256XX=m CONFIG_BATTERY_GAUGE_LTC2941=m CONFIG_BATTERY_GOLDFISH=m +CONFIG_BATTERY_UG3105=m CONFIG_SENSORS_AD7314=m CONFIG_SENSORS_AD7414=m CONFIG_SENSORS_AD7418=m @@ -891,6 +908,7 @@ CONFIG_SENSORS_ADT7475=m CONFIG_SENSORS_AHT10=m CONFIG_SENSORS_AQUACOMPUTER_D5NEXT=m CONFIG_SENSORS_CORSAIR_PSU=m +CONFIG_SENSORS_DRIVETEMP=m CONFIG_SENSORS_DS1621=m CONFIG_SENSORS_GPIO_FAN=m CONFIG_SENSORS_HIH6130=m @@ -917,6 +935,7 @@ CONFIG_SENSORS_MAX1668=m CONFIG_SENSORS_MAX197=m CONFIG_SENSORS_MAX31722=m CONFIG_SENSORS_MAX31730=m +CONFIG_SENSORS_MAX6620=m CONFIG_SENSORS_MAX6621=m CONFIG_SENSORS_MAX6639=m CONFIG_SENSORS_MAX6650=m @@ -947,12 +966,13 @@ CONFIG_SENSORS_PC87427=m CONFIG_SENSORS_NTC_THERMISTOR=m CONFIG_SENSORS_NCT6683=m CONFIG_SENSORS_NCT6775=m +CONFIG_SENSORS_NCT6775_I2C=m CONFIG_SENSORS_NCT7802=m CONFIG_SENSORS_NCT7904=m CONFIG_SENSORS_NPCM7XX=m CONFIG_SENSORS_NZXT_KRAKEN2=m -CONFIG_SENSORS_SBTSI=m -CONFIG_SENSORS_SBRMI=m +CONFIG_SENSORS_NZXT_SMART2=m +CONFIG_SENSORS_PWM_FAN=m CONFIG_SENSORS_SHT21=m CONFIG_SENSORS_SHT3x=m CONFIG_SENSORS_SHT4x=m @@ -969,7 +989,6 @@ CONFIG_SENSORS_SMSC47B397=m CONFIG_SENSORS_SCH5627=m CONFIG_SENSORS_SCH5636=m CONFIG_SENSORS_STTS751=m -CONFIG_SENSORS_SMM665=m CONFIG_SENSORS_ADC128D818=m CONFIG_SENSORS_ADS7828=m CONFIG_SENSORS_ADS7871=m @@ -980,21 +999,27 @@ CONFIG_SENSORS_INA3221=m CONFIG_SENSORS_TC74=m CONFIG_SENSORS_THMC50=m CONFIG_SENSORS_TMP102=m +CONFIG_SENSORS_TMP464=m +CONFIG_SENSORS_RP1_ADC=m CONFIG_WATCHDOG=y CONFIG_WATCHDOG_CORE=y CONFIG_BD957XMUF_WATCHDOG=m CONFIG_GPIO_WATCHDOG=m +CONFIG_MAX77620_WATCHDOG=m +CONFIG_MFD_MAX77714=m CONFIG_MFD_NTXEC=m CONFIG_MFD_RASPBERRYPI_POE_HAT=m CONFIG_MFD_RT4831=m CONFIG_MFD_STMPE=y CONFIG_STMPE_SPI=y +CONFIG_MFD_SYSCON=y CONFIG_MFD_ARIZONA_I2C=m CONFIG_MFD_ARIZONA_SPI=m CONFIG_MFD_WM5102=y CONFIG_MFD_ROHM_BD957XMUF=m CONFIG_MFD_ATC260X_I2C=m CONFIG_MFD_QCOM_PM8008=m +CONFIG_MFD_RP1=y CONFIG_MFD_RSMU_I2C=m CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y @@ -1003,6 +1028,7 @@ CONFIG_REGULATOR_ARIZONA_MICSUPP=m CONFIG_REGULATOR_ATC260X=m CONFIG_REGULATOR_GPIO=y CONFIG_REGULATOR_MAX8893=m +CONFIG_REGULATOR_MAX20086=m CONFIG_REGULATOR_MCP16502=m CONFIG_REGULATOR_MP5416=m CONFIG_REGULATOR_MP8859=m @@ -1010,10 +1036,14 @@ CONFIG_REGULATOR_MP886X=m CONFIG_REGULATOR_MPQ7920=m CONFIG_REGULATOR_PF8X00=m CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY=m +CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_V2=m CONFIG_REGULATOR_RT4831=m +CONFIG_REGULATOR_RT5190A=m +CONFIG_REGULATOR_RT5759=m CONFIG_REGULATOR_RT6245=m CONFIG_REGULATOR_RTQ2134=m CONFIG_REGULATOR_RTQ6752=m +CONFIG_REGULATOR_TPS6286X=m CONFIG_RC_CORE=y CONFIG_BPF_LIRC_MODE2=y CONFIG_LIRC=y @@ -1102,7 +1132,6 @@ CONFIG_VIDEO_GO7007_USB=m CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m CONFIG_VIDEO_HDPVR=m CONFIG_VIDEO_PVRUSB2=m -CONFIG_VIDEO_STK1160_COMMON=m CONFIG_VIDEO_AU0828=m CONFIG_VIDEO_AU0828_RC=y CONFIG_VIDEO_CX231XX=m @@ -1170,6 +1199,9 @@ CONFIG_I2C_SI470X=m CONFIG_I2C_SI4713=m CONFIG_RADIO_WL128X=m CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_VIDEO_MUX=m +CONFIG_VIDEO_RASPBERRYPI_PISP_BE=m +CONFIG_VIDEO_RP1_CFE=m CONFIG_V4L_TEST_DRIVERS=y CONFIG_VIDEO_VIM2M=m CONFIG_VIDEO_VICODEC=m @@ -1193,7 +1225,6 @@ CONFIG_VIDEO_IMX519=m CONFIG_VIDEO_MT9V011=m CONFIG_VIDEO_MT9V032=m CONFIG_VIDEO_MT9V111=m -CONFIG_VIDEO_NOON010PC30=m CONFIG_VIDEO_OV02A10=m CONFIG_VIDEO_OV2311=m CONFIG_VIDEO_OV5647=m @@ -1211,14 +1242,10 @@ CONFIG_VIDEO_RDACM20=m CONFIG_VIDEO_RDACM21=m CONFIG_VIDEO_RJ54N1=m CONFIG_VIDEO_S5C73M3=m -CONFIG_VIDEO_S5K4ECGX=m CONFIG_VIDEO_S5K5BAF=m CONFIG_VIDEO_S5K6A3=m -CONFIG_VIDEO_S5K6AA=m -CONFIG_VIDEO_SR030PC30=m CONFIG_VIDEO_CCS=m CONFIG_VIDEO_ET8EK8=m -CONFIG_VIDEO_M5MOLS=m CONFIG_VIDEO_AD5398=m CONFIG_VIDEO_SONY_BTF_MPX=m CONFIG_VIDEO_UDA1342=m @@ -1226,10 +1253,12 @@ CONFIG_VIDEO_ADV7180=m CONFIG_VIDEO_TC358743=m CONFIG_VIDEO_TVP5150=m CONFIG_VIDEO_TW2804=m -CONFIG_VIDEO_OV9281=m CONFIG_VIDEO_TW9903=m CONFIG_VIDEO_TW9906=m CONFIG_VIDEO_IRS1125=m +CONFIG_AUXDISPLAY=y +CONFIG_HD44780=m +CONFIG_LCD2S=m CONFIG_DRM=m CONFIG_DRM_LOAD_EDID_FIRMWARE=y CONFIG_DRM_UDL=m @@ -1276,7 +1305,6 @@ CONFIG_FB_RPISENSE=m CONFIG_BACKLIGHT_PWM=m CONFIG_BACKLIGHT_RT4831=m CONFIG_BACKLIGHT_GPIO=m -CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set @@ -1574,7 +1602,6 @@ CONFIG_USB_LCD=m CONFIG_USB_CYPRESS_CY7C63=m CONFIG_USB_CYTHERM=m CONFIG_USB_IDMOUSE=m -CONFIG_USB_FTDI_ELAN=m CONFIG_USB_APPLEDISPLAY=m CONFIG_USB_LD=m CONFIG_USB_TRANCEVIBRATOR=m @@ -1646,7 +1673,6 @@ CONFIG_LEDS_TRIGGER_ONESHOT=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_LEDS_TRIGGER_BACKLIGHT=y CONFIG_LEDS_TRIGGER_CPU=y -CONFIG_LEDS_TRIGGER_GPIO=y CONFIG_LEDS_TRIGGER_DEFAULT_ON=y CONFIG_LEDS_TRIGGER_TRANSIENT=m CONFIG_LEDS_TRIGGER_CAMERA=m @@ -1714,9 +1740,6 @@ CONFIG_DMADEVICES=y CONFIG_DMABUF_HEAPS=y CONFIG_DMABUF_HEAPS_SYSTEM=y CONFIG_DMABUF_HEAPS_CMA=y -CONFIG_AUXDISPLAY=y -CONFIG_HD44780=m -CONFIG_LCD2S=m CONFIG_UIO=m CONFIG_UIO_PDRV_GENIRQ=m CONFIG_VIRTIO_BALLOON=m @@ -1727,7 +1750,6 @@ CONFIG_VHOST_CROSS_ENDIAN_LEGACY=y CONFIG_STAGING=y CONFIG_PRISM2_USB=m CONFIG_R8712U=m -CONFIG_R8188EU=m CONFIG_VT6656=m CONFIG_AD9832=m CONFIG_AD9834=m @@ -1772,7 +1794,6 @@ CONFIG_MAILBOX=y CONFIG_ARM_MHU_V2=m # CONFIG_IOMMU_SUPPORT is not set CONFIG_LITEX_SOC_CONTROLLER=m -CONFIG_IIO=m CONFIG_IIO_BUFFER_CB=m CONFIG_ADIS16201=m CONFIG_ADIS16209=m @@ -1965,15 +1986,10 @@ CONFIG_TSYS01=m CONFIG_TSYS02D=m CONFIG_MAX31856=m CONFIG_PWM=y -CONFIG_PWM_ATMEL_TCB=m -CONFIG_PWM_DWC=m +CONFIG_PWM_GPIO=m CONFIG_PWM_NTXEC=m CONFIG_PWM_PCA9685=m -CONFIG_RESET_CONTROLLER=y -CONFIG_PHY_CAN_TRANSCEIVER=m -CONFIG_PHY_MAPPHONE_MDM6600=m -CONFIG_PHY_OCELOT_SERDES=m -CONFIG_PHY_SAMSUNG_USB2=m +CONFIG_BCM2712_MIP=y CONFIG_ANDROID_BINDER_IPC=y CONFIG_ANDROID_BINDERFS=y CONFIG_ANDROID_BINDER_DEVICES="binder,hwbinder,vndbinder,anbox-binder,anbox-hwbinder,anbox-vndbinder" @@ -1984,8 +2000,6 @@ CONFIG_MUX_GPIO=m CONFIG_MUX_MMIO=m CONFIG_COUNTER=m CONFIG_INTERRUPT_CNT=m -CONFIG_FTM_QUADDEC=m -CONFIG_INTEL_QEP=m CONFIG_MOST=m CONFIG_MOST_SND=m CONFIG_VALIDATE_FS_PARSER=y @@ -2022,7 +2036,6 @@ CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y CONFIG_QUOTA_NETLINK_INTERFACE=y CONFIG_QFMT_V1=m CONFIG_QFMT_V2=m -CONFIG_AUTOFS4_FS=y CONFIG_FUSE_FS=m CONFIG_CUSE=m CONFIG_VIRTIO_FS=m @@ -2074,15 +2087,18 @@ CONFIG_SYSV_FS=m CONFIG_UFS_FS=m CONFIG_EROFS_FS=m # CONFIG_EROFS_FS_ZIP is not set -CONFIG_NFS_FS=m +CONFIG_NFS_FS=y CONFIG_NFS_V3_ACL=y -CONFIG_NFS_V4=m +CONFIG_NFS_V4=y CONFIG_NFS_SWAP=y CONFIG_NFS_V4_1=y CONFIG_NFS_V4_2=y CONFIG_NFS_V4_1_MIGRATION=y -CONFIG_NFS_FSCACHE=y +CONFIG_ROOT_NFS=y +# CONFIG_NFS_V4_2_READ_PLUS is not set CONFIG_NFSD=m +CONFIG_NFSD_V2=y +CONFIG_NFSD_V2_ACL=y CONFIG_NFSD_V3_ACL=y CONFIG_NFSD_V4=y CONFIG_NFSD_BLOCKLAYOUT=y @@ -2213,7 +2229,6 @@ CONFIG_BLK_DEV_IO_TRACE=y CONFIG_BPF_KPROBE_OVERRIDE=y CONFIG_FUNCTION_ERROR_INJECTION=y CONFIG_TEST_MIN_HEAP=m -CONFIG_TEST_STRSCPY=m CONFIG_TEST_XARRAY=m CONFIG_TEST_BPF=m CONFIG_TEST_BLACKHOLE_DEV=m From b39cf2bec1e9888b3650d8c729d3d3f213921b7e Mon Sep 17 00:00:00 2001 From: Andrei Aldea Date: Fri, 28 Feb 2025 16:38:11 -0600 Subject: [PATCH 22/37] Add initial support for BeagleBoard PocketBeagle2 --- config/boards/pocketbeagle2.csc | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 config/boards/pocketbeagle2.csc diff --git a/config/boards/pocketbeagle2.csc b/config/boards/pocketbeagle2.csc new file mode 100644 index 000000000000..a570c9cf125e --- /dev/null +++ b/config/boards/pocketbeagle2.csc @@ -0,0 +1,27 @@ +#Texas Instruments AM62 dual core 1GB USB2 DDR4 + +BOARD_NAME="PocketBeagle 2" +BOARDFAMILY="k3" +BOARD_MAINTAINER="grippy98" +BOOTCONFIG="am6232_pocketbeagle2_a53_defconfig" +BOOTFS_TYPE="fat" +BOOT_FDT_FILE="k3-am6232-pocketbeagle2.dts" +TIBOOT3_BOOTCONFIG="am6232_pocketbeagle2_r5_defconfig" +TIBOOT3_FILE="tiboot3-am62x-hs-fs-evm.bin" +DEFAULT_CONSOLE="serial" +KERNEL_TARGET="edge" +KERNEL_TEST_TARGET="edge" +SERIALCON="ttyS2" +ATF_BOARD="lite" + +#Until PB2 goes upstream, use this branch +function post_family_config_branch_edge__pocketbeagle2_use_beagle_kernel_uboot() { + display_alert "$BOARD" " beagleboard (next branch) u-boot and kernel overrides for $BOARD / $BRANCH" "info" + + declare -g KERNELSOURCE="https://github.com/beagleboard/linux" # BeagleBoard kernel + declare -g KERNEL_MAJOR_MINOR="6.12" + declare -g KERNELBRANCH="branch:v6.12.9-ti-arm64-r21" + + declare -g BOOTSOURCE="https://github.com/beagleboard/u-boot" # BeagleBoard u-boot + declare -g BOOTBRANCH="branch:v2025.01-pocketbeagle2" +} From 7e79b3cf020021e7edcd42545084ec01728aa03d Mon Sep 17 00:00:00 2001 From: Andrei Aldea <7153954+Grippy98@users.noreply.github.com> Date: Sat, 1 Mar 2025 06:32:23 -0600 Subject: [PATCH 23/37] Update config/boards/pocketbeagle2.csc Declare separate LinuxFamily as par rpardini suggestion. Temporary until PB2 reaches mainline. Co-authored-by: Ricardo Pardini --- config/boards/pocketbeagle2.csc | 1 + 1 file changed, 1 insertion(+) diff --git a/config/boards/pocketbeagle2.csc b/config/boards/pocketbeagle2.csc index a570c9cf125e..8818f84123c5 100644 --- a/config/boards/pocketbeagle2.csc +++ b/config/boards/pocketbeagle2.csc @@ -21,6 +21,7 @@ function post_family_config_branch_edge__pocketbeagle2_use_beagle_kernel_uboot() declare -g KERNELSOURCE="https://github.com/beagleboard/linux" # BeagleBoard kernel declare -g KERNEL_MAJOR_MINOR="6.12" declare -g KERNELBRANCH="branch:v6.12.9-ti-arm64-r21" + declare -g LINUXFAMILY="k3-pb2" # Separate kernel package from the regular `k3` family declare -g BOOTSOURCE="https://github.com/beagleboard/u-boot" # BeagleBoard u-boot declare -g BOOTBRANCH="branch:v2025.01-pocketbeagle2" From 0c1984abbf14336e6f9b6bdc5a60117fe5d8a7e5 Mon Sep 17 00:00:00 2001 From: Andrei Aldea Date: Sat, 1 Mar 2025 21:32:01 -0600 Subject: [PATCH 24/37] Fix Kernel to K3-Beagle for non-upstream boards --- config/boards/pocketbeagle2.csc | 4 +- config/kernel/linux-k3-beagle-edge.config | 891 ++++++++++++++++++++++ 2 files changed, 893 insertions(+), 2 deletions(-) create mode 100644 config/kernel/linux-k3-beagle-edge.config diff --git a/config/boards/pocketbeagle2.csc b/config/boards/pocketbeagle2.csc index 8818f84123c5..c505d50cc9a1 100644 --- a/config/boards/pocketbeagle2.csc +++ b/config/boards/pocketbeagle2.csc @@ -20,8 +20,8 @@ function post_family_config_branch_edge__pocketbeagle2_use_beagle_kernel_uboot() declare -g KERNELSOURCE="https://github.com/beagleboard/linux" # BeagleBoard kernel declare -g KERNEL_MAJOR_MINOR="6.12" - declare -g KERNELBRANCH="branch:v6.12.9-ti-arm64-r21" - declare -g LINUXFAMILY="k3-pb2" # Separate kernel package from the regular `k3` family + declare -g KERNELBRANCH="branch:v6.12.13-ti-arm64-r24" + declare -g LINUXFAMILY="k3-beagle" # Separate kernel package from the regular `k3` family declare -g BOOTSOURCE="https://github.com/beagleboard/u-boot" # BeagleBoard u-boot declare -g BOOTBRANCH="branch:v2025.01-pocketbeagle2" diff --git a/config/kernel/linux-k3-beagle-edge.config b/config/kernel/linux-k3-beagle-edge.config new file mode 100644 index 000000000000..58b4249536b3 --- /dev/null +++ b/config/kernel/linux-k3-beagle-edge.config @@ -0,0 +1,891 @@ +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_AUDIT=y +CONFIG_NO_HZ_IDLE=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BPF_SYSCALL=y +CONFIG_BPF_JIT=y +CONFIG_PREEMPT=y +CONFIG_IRQ_TIME_ACCOUNTING=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_TASKSTATS=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_MEMCG=y +CONFIG_BLK_CGROUP=y +CONFIG_CGROUP_PIDS=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_HUGETLB=y +CONFIG_CPUSETS=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_CGROUP_PERF=y +CONFIG_CGROUP_BPF=y +CONFIG_SCHED_AUTOGROUP=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_EXPERT=y +CONFIG_KALLSYMS_ALL=y +CONFIG_PROFILING=y +CONFIG_KEXEC=y +CONFIG_KEXEC_FILE=y +# CONFIG_CRASH_DUMP is not set +CONFIG_ARCH_K3=y +# CONFIG_AMPERE_ERRATUM_AC03_CPU_38 is not set +# CONFIG_ARM64_ERRATUM_832075 is not set +# CONFIG_ARM64_ERRATUM_1024718 is not set +# CONFIG_ARM64_ERRATUM_1418040 is not set +# CONFIG_ARM64_ERRATUM_1165522 is not set +# CONFIG_ARM64_ERRATUM_1530923 is not set +# CONFIG_ARM64_ERRATUM_1463225 is not set +# CONFIG_ARM64_ERRATUM_1508412 is not set +# CONFIG_ARM64_ERRATUM_2051678 is not set +# CONFIG_ARM64_ERRATUM_2077057 is not set +# CONFIG_ARM64_ERRATUM_2658417 is not set +# CONFIG_ARM64_ERRATUM_2054223 is not set +# CONFIG_ARM64_ERRATUM_2067961 is not set +# CONFIG_ARM64_ERRATUM_2457168 is not set +# CONFIG_ARM64_ERRATUM_2645198 is not set +# CONFIG_ARM64_ERRATUM_2966298 is not set +# CONFIG_ARM64_ERRATUM_3117295 is not set +# CONFIG_CAVIUM_ERRATUM_22375 is not set +# CONFIG_CAVIUM_ERRATUM_23154 is not set +# CONFIG_CAVIUM_ERRATUM_27456 is not set +# CONFIG_CAVIUM_ERRATUM_30115 is not set +# CONFIG_CAVIUM_TX2_ERRATUM_219 is not set +# CONFIG_FUJITSU_ERRATUM_010001 is not set +# CONFIG_HISILICON_ERRATUM_161600802 is not set +# CONFIG_QCOM_FALKOR_ERRATUM_1003 is not set +# CONFIG_QCOM_FALKOR_ERRATUM_1009 is not set +# CONFIG_QCOM_QDF2400_ERRATUM_0065 is not set +# CONFIG_QCOM_FALKOR_ERRATUM_E1041 is not set +# CONFIG_NVIDIA_CARMEL_CNP_ERRATUM is not set +# CONFIG_ROCKCHIP_ERRATUM_3588001 is not set +CONFIG_ARM64_VA_BITS_48=y +CONFIG_SCHED_MC=y +CONFIG_SCHED_SMT=y +CONFIG_PARAVIRT=y +CONFIG_COMPAT=y +# CONFIG_ARM64_SVE is not set +CONFIG_RANDOMIZE_BASE=y +CONFIG_HIBERNATION=y +CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y +CONFIG_ENERGY_MODEL=y +CONFIG_CPU_IDLE=y +CONFIG_ARM_PSCI_CPUIDLE=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m +CONFIG_CPUFREQ_DT=y +CONFIG_ARM_SCMI_CPUFREQ=y +CONFIG_VIRTUALIZATION=y +CONFIG_JUMP_LABEL=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_BLK_DEV_INTEGRITY=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_COMPAT_BRK is not set +CONFIG_MEMORY_HOTPLUG=y +CONFIG_MEMORY_HOTREMOVE=y +CONFIG_KSM=y +CONFIG_MEMORY_FAILURE=y +CONFIG_TRANSPARENT_HUGEPAGE=y +CONFIG_CMA=y +CONFIG_CMA_AREAS=20 +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IPV6=m +CONFIG_NETFILTER=y +CONFIG_BRIDGE_NETFILTER=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NETFILTER_XT_MARK=m +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m +CONFIG_NETFILTER_XT_TARGET_LOG=m +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_IPVS=m +CONFIG_IP_VS=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_NAT=m +CONFIG_IP6_NF_TARGET_MASQUERADE=m +CONFIG_BRIDGE=m +CONFIG_BRIDGE_VLAN_FILTERING=y +CONFIG_NET_DSA=m +CONFIG_NET_DSA_TAG_NONE=m +CONFIG_NET_DSA_TAG_BRCM=m +CONFIG_NET_DSA_TAG_BRCM_LEGACY=m +CONFIG_NET_DSA_TAG_BRCM_PREPEND=m +CONFIG_NET_DSA_TAG_OCELOT=m +CONFIG_NET_DSA_TAG_OCELOT_8021Q=m +CONFIG_VLAN_8021Q=m +CONFIG_VLAN_8021Q_GVRP=y +CONFIG_VLAN_8021Q_MVRP=y +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_CBS=m +CONFIG_NET_SCH_ETF=m +CONFIG_NET_SCH_TAPRIO=m +CONFIG_NET_SCH_MQPRIO=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_FLOWER=m +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_GACT=m +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_GATE=m +CONFIG_QRTR_SMD=m +CONFIG_QRTR_TUN=m +CONFIG_CAN=m +CONFIG_BT=m +CONFIG_BT_HIDP=m +# CONFIG_BT_LE is not set +CONFIG_BT_LEDS=y +# CONFIG_BT_DEBUGFS is not set +CONFIG_BT_HCIBTUSB=m +CONFIG_BT_HCIBTUSB_MTK=y +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIUART_BCM=y +CONFIG_BT_HCIUART_QCA=y +CONFIG_BT_HCIUART_MRVL=y +CONFIG_BT_MRVL=m +CONFIG_BT_MRVL_SDIO=m +CONFIG_BT_NXPUART=m +CONFIG_CFG80211=m +CONFIG_MAC80211=m +CONFIG_RFKILL=m +CONFIG_NFC=m +CONFIG_NFC_NCI=m +CONFIG_NFC_S3FWRN5_I2C=m +CONFIG_PAGE_POOL_STATS=y +CONFIG_PCI=y +CONFIG_PCIEPORTBUS=y +CONFIG_PCIEAER=y +CONFIG_PCI_IOV=y +CONFIG_PCI_PASID=y +CONFIG_HOTPLUG_PCI=y +CONFIG_PCI_HOST_GENERIC=y +CONFIG_PCI_ENDPOINT=y +CONFIG_PCI_ENDPOINT_CONFIGFS=y +CONFIG_PCI_EPF_TEST=m +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_FW_LOADER_USER_HELPER=y +CONFIG_MHI_BUS_PCI_GENERIC=m +CONFIG_ARM_SCMI_PROTOCOL=y +CONFIG_IMX_SCMI_BBM_EXT=y +CONFIG_IMX_SCMI_MISC_EXT=y +CONFIG_GOOGLE_FIRMWARE=y +CONFIG_GOOGLE_CBMEM=m +CONFIG_GOOGLE_COREBOOT_TABLE=m +CONFIG_EFI_CAPSULE_LOADER=y +CONFIG_IMX_SCMI_MISC_DRV=y +CONFIG_GNSS=m +CONFIG_GNSS_MTK_SERIAL=m +CONFIG_MTD=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_CFI=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_CFI_STAA=y +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_OF=y +CONFIG_MTD_DATAFLASH=y +CONFIG_MTD_SST25L=y +CONFIG_MTD_RAW_NAND=y +CONFIG_MTD_SPI_NOR=y +CONFIG_MTD_UBI=m +CONFIG_MTD_HYPERBUS=m +CONFIG_HBMC_AM654=m +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_NBD=m +CONFIG_VIRTIO_BLK=y +CONFIG_BLK_DEV_NVME=m +CONFIG_SRAM=y +CONFIG_PCI_ENDPOINT_TEST=m +CONFIG_EEPROM_AT24=m +CONFIG_EEPROM_AT25=m +CONFIG_UACCE=m +# CONFIG_SCSI_PROC_FS is not set +CONFIG_BLK_DEV_SD=y +CONFIG_SCSI_SAS_LIBSAS=y +CONFIG_SCSI_SAS_ATA=y +CONFIG_MEGARAID_SAS=y +CONFIG_SCSI_MPT3SAS=m +CONFIG_ATA=y +CONFIG_SATA_AHCI=y +CONFIG_SATA_AHCI_PLATFORM=y +CONFIG_AHCI_DWC=m +CONFIG_PATA_OF_PLATFORM=y +CONFIG_MD=y +CONFIG_BLK_DEV_MD=m +CONFIG_BLK_DEV_DM=m +CONFIG_DM_MIRROR=m +CONFIG_DM_ZERO=m +CONFIG_NETDEVICES=y +CONFIG_MACVLAN=m +CONFIG_MACVTAP=m +CONFIG_TUN=y +CONFIG_VETH=m +CONFIG_VIRTIO_NET=y +CONFIG_MHI_NET=m +# CONFIG_NET_VENDOR_ALACRITECH is not set +# CONFIG_NET_VENDOR_AMAZON is not set +# CONFIG_NET_VENDOR_AMD is not set +# CONFIG_NET_VENDOR_AQUANTIA is not set +# CONFIG_NET_VENDOR_ARC is not set +# CONFIG_NET_VENDOR_ASIX is not set +CONFIG_ATL1C=m +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_VENDOR_CADENCE is not set +# CONFIG_NET_VENDOR_CAVIUM is not set +# CONFIG_NET_VENDOR_CORTINA is not set +# CONFIG_NET_VENDOR_DAVICOM is not set +# CONFIG_NET_VENDOR_ENGLEDER is not set +# CONFIG_NET_VENDOR_EZCHIP is not set +# CONFIG_NET_VENDOR_FUNGIBLE is not set +# CONFIG_NET_VENDOR_GOOGLE is not set +# CONFIG_NET_VENDOR_HISILICON is not set +# CONFIG_NET_VENDOR_HUAWEI is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_LITEX is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MELLANOX is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_MICROCHIP is not set +# CONFIG_NET_VENDOR_MICROSEMI is not set +# CONFIG_NET_VENDOR_MICROSOFT is not set +# CONFIG_NET_VENDOR_NI is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_NETRONOME is not set +# CONFIG_NET_VENDOR_NVIDIA is not set +# CONFIG_NET_VENDOR_PENSANDO is not set +# CONFIG_NET_VENDOR_QUALCOMM is not set +CONFIG_R8169=m +# CONFIG_NET_VENDOR_RENESAS is not set +# CONFIG_NET_VENDOR_ROCKER is not set +# CONFIG_NET_VENDOR_SAMSUNG is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SOLARFLARE is not set +# CONFIG_NET_VENDOR_SMSC is not set +# CONFIG_NET_VENDOR_SOCIONEXT is not set +# CONFIG_NET_VENDOR_STMICRO is not set +# CONFIG_NET_VENDOR_SYNOPSYS is not set +CONFIG_TI_K3_AM65_CPSW_NUSS=y +CONFIG_TI_ICSSG_PRUETH=m +# CONFIG_NET_VENDOR_VERTEXCOM is not set +# CONFIG_NET_VENDOR_VIA is not set +# CONFIG_NET_VENDOR_WANGXUN is not set +# CONFIG_NET_VENDOR_WIZNET is not set +# CONFIG_NET_VENDOR_XILINX is not set +CONFIG_AQUANTIA_PHY=y +CONFIG_BCM7XXX_PHY=m +CONFIG_MARVELL_PHY=m +CONFIG_MARVELL_10G_PHY=y +CONFIG_MARVELL_88Q2XXX_PHY=y +CONFIG_MICREL_PHY=y +CONFIG_MICROSEMI_PHY=y +CONFIG_AT803X_PHY=y +CONFIG_REALTEK_PHY=y +CONFIG_DP83867_PHY=y +CONFIG_DP83869_PHY=m +CONFIG_DP83TD510_PHY=y +CONFIG_VITESSE_PHY=y +CONFIG_CAN_M_CAN=m +CONFIG_CAN_M_CAN_PLATFORM=m +CONFIG_CAN_MCP251XFD=m +CONFIG_MDIO_BCM_UNIMAC=y +CONFIG_MDIO_GPIO=y +CONFIG_MDIO_THUNDER=y +CONFIG_MDIO_BUS_MUX_MULTIPLEXER=y +CONFIG_MDIO_BUS_MUX_MMIOREG=y +CONFIG_USB_PEGASUS=m +CONFIG_USB_RTL8150=m +CONFIG_USB_RTL8152=m +CONFIG_USB_LAN78XX=m +CONFIG_USB_USBNET=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_SR9800=m +CONFIG_USB_NET_SMSC75XX=m +CONFIG_USB_NET_SMSC95XX=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_MCS7830=m +CONFIG_ATH10K=m +CONFIG_ATH10K_PCI=m +CONFIG_ATH10K_SDIO=m +CONFIG_WCN36XX=m +CONFIG_ATH11K=m +CONFIG_ATH11K_AHB=m +CONFIG_ATH11K_PCI=m +CONFIG_ATH12K=m +CONFIG_BRCMFMAC=m +CONFIG_IWLWIFI=m +CONFIG_IWLDVM=m +CONFIG_IWLMVM=m +CONFIG_MWIFIEX=m +CONFIG_MWIFIEX_SDIO=m +CONFIG_MWIFIEX_PCIE=m +CONFIG_MT7921E=m +CONFIG_RSI_91X=m +CONFIG_WL18XX=m +CONFIG_WLCORE_SDIO=m +CONFIG_WWAN=m +CONFIG_MHI_WWAN_CTRL=m +CONFIG_MHI_WWAN_MBIM=m +CONFIG_INPUT_MATRIXKMAP=y +CONFIG_INPUT_EVDEV=y +CONFIG_KEYBOARD_ADC=m +CONFIG_KEYBOARD_GPIO=y +CONFIG_KEYBOARD_GPIO_POLLED=m +CONFIG_KEYBOARD_IMX_BBM_SCMI=y +CONFIG_KEYBOARD_MTK_PMIC=m +CONFIG_MOUSE_ELAN_I2C=m +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_ATMEL_MXT=m +CONFIG_TOUCHSCREEN_GOODIX=m +CONFIG_TOUCHSCREEN_GOODIX_BERLIN_SPI=m +CONFIG_TOUCHSCREEN_ELAN=m +CONFIG_TOUCHSCREEN_EDT_FT5X06=m +CONFIG_INPUT_MISC=y +CONFIG_INPUT_TPS65219_PWRBUTTON=m +CONFIG_INPUT_PWM_BEEPER=m +CONFIG_INPUT_PWM_VIBRA=m +CONFIG_INPUT_RK805_PWRKEY=m +CONFIG_INPUT_DA9063_ONKEY=m +# CONFIG_SERIO_SERPORT is not set +CONFIG_SERIO_AMBAKMI=y +CONFIG_LEGACY_PTY_COUNT=16 +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=8 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_8250_OMAP=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SERIAL_FSL_LPUART=y +CONFIG_SERIAL_FSL_LPUART_CONSOLE=y +CONFIG_SERIAL_FSL_LINFLEXUART=y +CONFIG_SERIAL_FSL_LINFLEXUART_CONSOLE=y +CONFIG_SERIAL_DEV_BUS=y +CONFIG_VIRTIO_CONSOLE=y +CONFIG_IPMI_HANDLER=m +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_SI=m +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_VIRTIO=y +# CONFIG_HW_RANDOM_ARM_SMCCC_TRNG is not set +CONFIG_TCG_TPM=y +CONFIG_TCG_TIS=m +CONFIG_TCG_TIS_SPI=m +CONFIG_TCG_TIS_SPI_CR50=y +CONFIG_TCG_TIS_I2C_CR50=m +CONFIG_TCG_TIS_I2C_INFINEON=y +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MUX=y +CONFIG_I2C_MUX_PCA954x=y +CONFIG_I2C_DESIGNWARE_CORE=y +# CONFIG_I2C_DESIGNWARE_PLATFORM is not set +CONFIG_I2C_GPIO=m +CONFIG_I2C_OMAP=y +CONFIG_I2C_SLAVE=y +CONFIG_SPI=y +CONFIG_SPI_CADENCE_QUADSPI=y +CONFIG_SPI_OMAP24XX=m +CONFIG_SPI_SPIDEV=m +CONFIG_PINCTRL=y +CONFIG_PINCTRL_DA9062=m +CONFIG_PINCTRL_RK805=m +CONFIG_PINCTRL_SINGLE=y +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_DAVINCI=y +CONFIG_GPIO_GENERIC_PLATFORM=y +CONFIG_GPIO_SYSCON=y +CONFIG_GPIO_MAX732X=y +CONFIG_GPIO_PCA953X=y +CONFIG_GPIO_PCA953X_IRQ=y +CONFIG_GPIO_ADP5585=m +CONFIG_GPIO_BD9571MWV=m +CONFIG_GPIO_MAX77620=y +CONFIG_GPIO_AGGREGATOR=m +CONFIG_POWER_RESET_SYSCON=y +CONFIG_POWER_RESET_SYSCON_POWEROFF=y +CONFIG_SYSCON_REBOOT_MODE=y +CONFIG_NVMEM_REBOOT_MODE=m +CONFIG_POWER_SEQUENCING=m +CONFIG_POWER_SEQUENCING_QCOM_WCN=m +CONFIG_BATTERY_QCOM_BATTMGR=m +CONFIG_BATTERY_SBS=m +CONFIG_BATTERY_BQ27XXX=y +CONFIG_BATTERY_MAX17042=m +CONFIG_CHARGER_MT6360=m +CONFIG_CHARGER_BQ25890=m +CONFIG_CHARGER_BQ25980=m +CONFIG_CHARGER_RK817=m +CONFIG_SENSORS_ARM_SCMI=y +CONFIG_SENSORS_GPIO_FAN=m +CONFIG_SENSORS_JC42=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_PWM_FAN=m +CONFIG_SENSORS_INA2XX=m +CONFIG_SENSORS_INA3221=m +CONFIG_THERMAL=y +CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y +CONFIG_CPU_THERMAL=y +CONFIG_DEVFREQ_THERMAL=y +CONFIG_THERMAL_EMULATION=y +CONFIG_K3_THERMAL=m +CONFIG_GENERIC_ADC_THERMAL=m +CONFIG_WATCHDOG=y +CONFIG_K3_RTI_WATCHDOG=m +CONFIG_ARM_SMC_WATCHDOG=y +CONFIG_MFD_ADP5585=m +CONFIG_MFD_BD9571MWV=y +CONFIG_MFD_AXP20X_I2C=y +CONFIG_MFD_DA9062=m +CONFIG_MFD_HI6421_PMIC=y +CONFIG_MFD_MAX77620=y +CONFIG_MFD_MT6360=y +CONFIG_MFD_MT6397=y +CONFIG_MFD_RK8XX_I2C=y +CONFIG_MFD_RK8XX_SPI=y +CONFIG_MFD_TI_AM335X_TSCADC=m +CONFIG_MFD_TI_LP873X=m +CONFIG_MFD_TPS65219=y +CONFIG_MFD_TPS6594_I2C=m +CONFIG_MFD_WM8994=m +CONFIG_MFD_ROHM_BD718XX=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_ARM_SCMI=y +CONFIG_REGULATOR_AXP20X=y +CONFIG_REGULATOR_BD718XX=y +CONFIG_REGULATOR_BD9571MWV=y +CONFIG_REGULATOR_DA9211=m +CONFIG_REGULATOR_FAN53555=y +CONFIG_REGULATOR_GPIO=y +CONFIG_REGULATOR_HI6421V530=y +CONFIG_REGULATOR_LP873X=m +CONFIG_REGULATOR_MAX77620=y +CONFIG_REGULATOR_MAX8973=y +CONFIG_REGULATOR_MAX20411=m +CONFIG_REGULATOR_MP8859=y +CONFIG_REGULATOR_MT6357=y +CONFIG_REGULATOR_MT6358=y +CONFIG_REGULATOR_MT6359=y +CONFIG_REGULATOR_MT6360=y +CONFIG_REGULATOR_MT6397=y +CONFIG_REGULATOR_PCA9450=y +CONFIG_REGULATOR_PF8X00=y +CONFIG_REGULATOR_PFUZE100=y +CONFIG_REGULATOR_PWM=y +CONFIG_REGULATOR_RAA215300=y +CONFIG_REGULATOR_RK808=y +CONFIG_REGULATOR_TPS65132=m +CONFIG_REGULATOR_TPS65219=y +CONFIG_REGULATOR_VCTRL=m +CONFIG_MEDIA_SUPPORT=m +# CONFIG_DVB_NET is not set +CONFIG_MEDIA_USB_SUPPORT=y +CONFIG_USB_VIDEO_CLASS=m +CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_SDR_PLATFORM_DRIVERS=y +CONFIG_V4L_MEM2MEM_DRIVERS=y +CONFIG_VIDEO_CADENCE_CSI2RX=m +CONFIG_VIDEO_WAVE_VPU=m +CONFIG_VIDEO_E5010_JPEG_ENC=m +CONFIG_VIDEO_TI_J721E_CSI2RX=m +CONFIG_VIDEO_IMX219=m +CONFIG_VIDEO_IMX412=m +CONFIG_VIDEO_OV5640=m +CONFIG_VIDEO_OV5645=m +CONFIG_DRM=m +CONFIG_DRM_I2C_CH7006=m +CONFIG_DRM_I2C_SIL164=m +CONFIG_DRM_I2C_NXP_TDA998X=m +CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m +CONFIG_DRM_PANEL_LVDS=m +CONFIG_DRM_PANEL_ILITEK_ILI9882T=m +CONFIG_DRM_PANEL_KHADAS_TS050=m +CONFIG_DRM_PANEL_MANTIX_MLAF057WE51=m +CONFIG_DRM_PANEL_NOVATEK_NT36672E=m +CONFIG_DRM_PANEL_RAYDIUM_RM67191=m +CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20=m +CONFIG_DRM_PANEL_SITRONIX_ST7703=m +CONFIG_DRM_PANEL_EDP=m +CONFIG_DRM_PANEL_SIMPLE=m +CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA=m +CONFIG_DRM_PANEL_VISIONOX_VTDR6130=m +CONFIG_DRM_DISPLAY_CONNECTOR=m +CONFIG_DRM_LONTIUM_LT8912B=m +CONFIG_DRM_LONTIUM_LT9611=m +CONFIG_DRM_LONTIUM_LT9611UXC=m +CONFIG_DRM_ITE_IT66121=m +CONFIG_DRM_NWL_MIPI_DSI=m +CONFIG_DRM_PARADE_PS8640=m +CONFIG_DRM_SAMSUNG_DSIM=m +CONFIG_DRM_SII902X=m +CONFIG_DRM_SIMPLE_BRIDGE=m +CONFIG_DRM_THINE_THC63LVD1024=m +CONFIG_DRM_TOSHIBA_TC358767=m +CONFIG_DRM_TOSHIBA_TC358768=m +CONFIG_DRM_TI_TFP410=m +CONFIG_DRM_TI_SN65DSI83=m +CONFIG_DRM_TI_SN65DSI86=m +CONFIG_DRM_ANALOGIX_ANX7625=m +CONFIG_DRM_CDNS_MHDP8546=m +CONFIG_DRM_PANTHOR=m +CONFIG_DRM_TIDSS=m +CONFIG_DRM_POWERVR=m +CONFIG_FB=y +CONFIG_FB_MODE_HELPERS=y +CONFIG_BACKLIGHT_CLASS_DEVICE=m +CONFIG_BACKLIGHT_PWM=m +CONFIG_BACKLIGHT_LP855X=m +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_ALOOP=m +# CONFIG_SND_SPI is not set +CONFIG_SND_SOC=y +CONFIG_SND_SOC_SOF_TOPLEVEL=y +CONFIG_SND_SOC_SOF_OF=y +CONFIG_SND_SOC_SOF_MTK_TOPLEVEL=y +CONFIG_SND_SOC_J721E_EVM=m +CONFIG_SND_SOC_ADAU7002=m +CONFIG_SND_SOC_AK4619=m +CONFIG_SND_SOC_BT_SCO=m +CONFIG_SND_SOC_DA7213=m +CONFIG_SND_SOC_DMIC=m +CONFIG_SND_SOC_ES8316=m +CONFIG_SND_SOC_GTM601=m +CONFIG_SND_SOC_MAX98357A=m +CONFIG_SND_SOC_MAX98927=m +CONFIG_SND_SOC_MAX98390=m +CONFIG_SND_SOC_MSM8916_WCD_DIGITAL=m +CONFIG_SND_SOC_RK817=m +CONFIG_SND_SOC_RT5640=m +CONFIG_SND_SOC_RT5659=m +CONFIG_SND_SOC_SGTL5000=m +CONFIG_SND_SOC_SIMPLE_AMPLIFIER=m +CONFIG_SND_SOC_SIMPLE_MUX=m +CONFIG_SND_SOC_SPDIF=m +CONFIG_SND_SOC_TAS2552=m +CONFIG_SND_SOC_TLV320AIC31XX=m +CONFIG_SND_SOC_TLV320AIC32X4_I2C=m +CONFIG_SND_SOC_TLV320AIC3X_I2C=m +CONFIG_SND_SOC_TS3A227E=m +CONFIG_SND_SOC_WCD938X_SDW=m +CONFIG_SND_SOC_WCD939X_SDW=m +CONFIG_SND_SOC_WM8524=m +CONFIG_SND_SOC_WM8904=m +CONFIG_SND_SOC_WM8960=m +CONFIG_SND_SOC_WM8962=m +CONFIG_SND_SOC_WM8978=m +CONFIG_SND_SOC_WSA881X=m +CONFIG_SND_SOC_WSA883X=m +CONFIG_SND_SOC_WSA884X=m +CONFIG_SND_SOC_MT6357=m +CONFIG_SND_SOC_MT6358=m +CONFIG_SND_SOC_NAU8822=m +CONFIG_SND_SOC_LPASS_WSA_MACRO=m +CONFIG_SND_SOC_LPASS_VA_MACRO=m +CONFIG_SND_SOC_LPASS_RX_MACRO=m +CONFIG_SND_SOC_LPASS_TX_MACRO=m +CONFIG_SND_SIMPLE_CARD=m +CONFIG_SND_AUDIO_GRAPH_CARD=m +CONFIG_SND_AUDIO_GRAPH_CARD2=m +CONFIG_HID_MULTITOUCH=m +CONFIG_I2C_HID_OF=m +CONFIG_I2C_HID_OF_ELAN=m +CONFIG_USB_ULPI_BUS=y +CONFIG_USB_CONN_GPIO=y +CONFIG_USB=y +CONFIG_USB_OTG=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_PCI_RENESAS=m +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_HCD_PLATFORM=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PLATFORM=y +CONFIG_USB_ACM=m +CONFIG_USB_STORAGE=y +CONFIG_USB_CDNS_SUPPORT=m +CONFIG_USB_CDNS3=m +CONFIG_USB_CDNS3_GADGET=y +CONFIG_USB_CDNS3_HOST=y +CONFIG_USB_DWC3=y +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_CP210X=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_ONBOARD_DEV=m +CONFIG_NOP_USB_XCEIV=y +CONFIG_USB_ULPI=y +CONFIG_USB_GADGET=y +CONFIG_USB_SNP_UDC_PLAT=y +CONFIG_USB_BDC_UDC=y +CONFIG_USB_CONFIGFS=m +CONFIG_USB_CONFIGFS_SERIAL=y +CONFIG_USB_CONFIGFS_ACM=y +CONFIG_USB_CONFIGFS_OBEX=y +CONFIG_USB_CONFIGFS_NCM=y +CONFIG_USB_CONFIGFS_ECM=y +CONFIG_USB_CONFIGFS_ECM_SUBSET=y +CONFIG_USB_CONFIGFS_RNDIS=y +CONFIG_USB_CONFIGFS_EEM=y +CONFIG_USB_CONFIGFS_MASS_STORAGE=y +CONFIG_USB_CONFIGFS_F_FS=y +CONFIG_USB_MASS_STORAGE=m +CONFIG_TYPEC=m +CONFIG_TYPEC_TCPM=m +CONFIG_TYPEC_TCPCI=m +CONFIG_TYPEC_FUSB302=m +CONFIG_TYPEC_UCSI=m +CONFIG_UCSI_CCG=m +CONFIG_UCSI_PMIC_GLINK=m +CONFIG_TYPEC_TPS6598X=m +CONFIG_TYPEC_HD3SS3220=m +CONFIG_TYPEC_MUX_FSA4480=m +CONFIG_TYPEC_MUX_GPIO_SBU=m +CONFIG_TYPEC_MUX_NB7VPQ904M=m +CONFIG_TYPEC_MUX_WCD939X_USBSS=m +CONFIG_TYPEC_DP_ALTMODE=m +CONFIG_MMC=y +CONFIG_MMC_BLOCK_MINORS=32 +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_OF_ARASAN=y +CONFIG_MMC_SPI=y +CONFIG_MMC_SDHCI_AM654=y +CONFIG_SCSI_UFSHCD=y +CONFIG_SCSI_UFS_BSG=y +CONFIG_SCSI_UFSHCD_PLATFORM=y +CONFIG_SCSI_UFS_CDNS_PLATFORM=m +CONFIG_SCSI_UFS_TI_J721E=m +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_CLASS_MULTICOLOR=m +CONFIG_LEDS_LM3692X=m +CONFIG_LEDS_PCA9532=m +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_PWM=y +CONFIG_LEDS_SYSCON=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_DISK=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_CPU=y +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y +CONFIG_LEDS_TRIGGER_PANIC=y +CONFIG_EDAC=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_HYM8563=m +CONFIG_RTC_DRV_MAX77686=y +CONFIG_RTC_DRV_RK808=m +CONFIG_RTC_DRV_ISL1208=m +CONFIG_RTC_DRV_PCF85063=m +CONFIG_RTC_DRV_PCF85363=m +CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_DRV_M41T80=m +CONFIG_RTC_DRV_BQ32K=m +CONFIG_RTC_DRV_RX8581=m +CONFIG_RTC_DRV_RV3028=m +CONFIG_RTC_DRV_RV8803=m +CONFIG_RTC_DRV_DS3232=y +CONFIG_RTC_DRV_PCF2127=m +CONFIG_RTC_DRV_DA9063=m +CONFIG_RTC_DRV_EFI=y +CONFIG_RTC_DRV_IMX_BBM_SCMI=y +CONFIG_RTC_DRV_MT6397=m +CONFIG_RTC_DRV_TI_K3=m +CONFIG_DMADEVICES=y +CONFIG_BCM_SBA_RAID=m +CONFIG_DW_EDMA=m +CONFIG_TI_K3_UDMA=y +CONFIG_TI_K3_UDMA_GLUE_LAYER=y +CONFIG_VFIO=y +CONFIG_VFIO_PCI=y +CONFIG_VIRTIO_PCI=y +CONFIG_VIRTIO_BALLOON=y +CONFIG_VIRTIO_MMIO=y +CONFIG_STAGING=y +CONFIG_STAGING_MEDIA=y +CONFIG_VIDEO_MAX96712=m +# CONFIG_SURFACE_PLATFORMS is not set +CONFIG_COMMON_CLK_SCMI=y +CONFIG_COMMON_CLK_CS2000_CP=y +CONFIG_COMMON_CLK_PWM=y +CONFIG_COMMON_CLK_RS9_PCIE=y +CONFIG_COMMON_CLK_VC3=y +CONFIG_TI_SCI_CLK=y +CONFIG_HWSPINLOCK=y +# CONFIG_FSL_ERRATUM_A008585 is not set +# CONFIG_HISILICON_ERRATUM_161010101 is not set +CONFIG_OMAP2PLUS_MBOX=m +CONFIG_IOMMU_IO_PGTABLE_ARMV7S=y +CONFIG_IOMMU_IO_PGTABLE_DART=y +CONFIG_ARM_SMMU=y +CONFIG_ARM_SMMU_V3=y +CONFIG_REMOTEPROC=y +CONFIG_REMOTEPROC_CDEV=y +CONFIG_TI_K3_DSP_REMOTEPROC=m +CONFIG_TI_K3_R5_REMOTEPROC=m +CONFIG_RPMSG_CHAR=m +CONFIG_RPMSG_CTRL=m +CONFIG_RPMSG_VIRTIO=y +CONFIG_SOUNDWIRE=m +CONFIG_FSL_RCPM=y +CONFIG_QCOM_PMIC_GLINK=m +CONFIG_TI_PRUSS=m +CONFIG_TI_SCI_PM_DOMAINS=y +CONFIG_DEVFREQ_GOV_USERSPACE=y +CONFIG_DEVFREQ_GOV_PASSIVE=m +CONFIG_EXTCON_PTN5150=m +CONFIG_EXTCON_USB_GPIO=y +CONFIG_MEMORY=y +CONFIG_IIO=y +CONFIG_MAX9611=m +CONFIG_TI_ADS1015=m +CONFIG_TI_AM335X_ADC=m +CONFIG_IIO_ST_LSM6DSX=m +CONFIG_SENSORS_ISL29018=m +CONFIG_VCNL4000=m +CONFIG_IIO_ST_MAGN_3AXIS=m +CONFIG_MPL3115=m +CONFIG_PWM=y +CONFIG_PWM_ADP5585=m +CONFIG_PWM_TIECAP=m +CONFIG_PWM_TIEHRPWM=m +CONFIG_RESET_CONTROLLER=y +CONFIG_RESET_GPIO=m +CONFIG_RESET_TI_SCI=y +CONFIG_PHY_CAN_TRANSCEIVER=m +CONFIG_PHY_CADENCE_TORRENT=m +CONFIG_PHY_CADENCE_DPHY_RX=m +CONFIG_PHY_CADENCE_SIERRA=m +CONFIG_PHY_CADENCE_SALVO=m +CONFIG_PHY_QCOM_USB_HS=m +CONFIG_PHY_AM654_SERDES=m +CONFIG_PHY_J721E_WIZ=m +CONFIG_OMAP_USB2=m +CONFIG_ARM_CCI_PMU=m +CONFIG_ARM_CCN=m +CONFIG_ARM_CMN=m +CONFIG_ARM_SMMU_V3_PMU=m +CONFIG_ARM_DSU_PMU=m +CONFIG_ARM_SPE_PMU=m +CONFIG_ARM_CORESIGHT_PMU_ARCH_SYSTEM_PMU=m +CONFIG_NVIDIA_CORESIGHT_PMU_ARCH_SYSTEM_PMU=m +CONFIG_NVMEM_LAYOUT_SL28_VPD=m +CONFIG_NVMEM_RMEM=m +CONFIG_FPGA=y +CONFIG_FPGA_MGR_ALTERA_CVP=m +CONFIG_FPGA_BRIDGE=m +CONFIG_ALTERA_FREEZE_BRIDGE=m +CONFIG_FPGA_REGION=m +CONFIG_OF_FPGA_REGION=m +CONFIG_TEE=y +CONFIG_OPTEE=y +CONFIG_MUX_GPIO=m +CONFIG_MUX_MMIO=y +CONFIG_INTERCONNECT=y +CONFIG_COUNTER=m +CONFIG_HTE=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_BTRFS_FS=m +CONFIG_BTRFS_FS_POSIX_ACL=y +CONFIG_FANOTIFY=y +CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y +CONFIG_QUOTA=y +CONFIG_AUTOFS_FS=y +CONFIG_FUSE_FS=m +CONFIG_CUSE=m +CONFIG_OVERLAY_FS=m +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_HUGETLBFS=y +CONFIG_EFIVAR_FS=y +CONFIG_UBIFS_FS=m +CONFIG_SQUASHFS=y +CONFIG_PSTORE=y +CONFIG_PSTORE_RAM=m +CONFIG_NFS_FS=y +CONFIG_NFS_V4=y +CONFIG_NFS_V4_1=y +CONFIG_NFS_V4_2=y +CONFIG_ROOT_NFS=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ISO8859_1=y +CONFIG_SECURITY=y +CONFIG_CRYPTO_USER=y +CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_DH=m +CONFIG_CRYPTO_CURVE25519=m +CONFIG_CRYPTO_ECHAINIV=y +CONFIG_CRYPTO_ANSI_CPRNG=y +CONFIG_CRYPTO_USER_API_RNG=m +CONFIG_CRYPTO_CHACHA20_NEON=m +CONFIG_CRYPTO_GHASH_ARM64_CE=y +CONFIG_CRYPTO_SHA1_ARM64_CE=y +CONFIG_CRYPTO_SHA2_ARM64_CE=y +CONFIG_CRYPTO_SHA512_ARM64_CE=m +CONFIG_CRYPTO_SHA3_ARM64=m +CONFIG_CRYPTO_SM3_ARM64_CE=m +CONFIG_CRYPTO_AES_ARM64_BS=m +CONFIG_CRYPTO_AES_ARM64_CE_CCM=y +CONFIG_CRYPTO_CRCT10DIF_ARM64_CE=m +CONFIG_CRYPTO_DEV_CCREE=m +CONFIG_CRYPTO_DEV_AMLOGIC_GXL=m +CONFIG_CRYPTO_DEV_SA2UL=m +CONFIG_INDIRECT_PIO=y +CONFIG_CRC_CCITT=m +CONFIG_DMA_RESTRICTED_POOL=y +CONFIG_DMA_CMA=y +CONFIG_CMA_SIZE_MBYTES=32 +CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_INFO_DWARF5=y +CONFIG_DEBUG_INFO_REDUCED=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_FS=y +# CONFIG_SCHED_DEBUG is not set +# CONFIG_FTRACE is not set +CONFIG_CORESIGHT=m +CONFIG_CORESIGHT_LINK_AND_SINK_TMC=m +CONFIG_CORESIGHT_CATU=m +CONFIG_CORESIGHT_SINK_TPIU=m +CONFIG_CORESIGHT_SINK_ETBV10=m +CONFIG_CORESIGHT_STM=m +CONFIG_CORESIGHT_CPU_DEBUG=m +CONFIG_CORESIGHT_CTI=m +CONFIG_MEMTEST=y From 903e3c74eef3bff3e4f8fded60ba75196b2bdfd0 Mon Sep 17 00:00:00 2001 From: Werner Date: Sat, 8 Mar 2025 19:10:34 +0000 Subject: [PATCH 25/37] RESEND - Add initial support for Orangepi 5 Ultra (#7902) * Create rk3588-orangepi-5-ultra.dts * Create orangepi5-ultra.csc * fixups * add notes * fix u-boot compilation * Update to v7 patch series https://patchwork.kernel.org/project/linux-arm-kernel/cover/20250222193332.1761-1-honyuenkwun@gmail.com/ * Update rk3588-orangepi-5-ultra.dts While I don't fully understand either the `kernel-dtb` command nor the dt syntax itself for some reason the `nophandles` version stripped more than actually phandles. Lets see what happens this way. * Delete patch/kernel/integrate-6.15/0001-tools-Makefile-remove-pci-target.patch * disable OPTEE https://github.com/armbian/build/commit/c81f89ca90f80483c7d33e0677c0faa3bccebe36 --- config/boards/orangepi5-ultra.csc | 57 + .../dt/rk3588-orangepi-5-ultra.dts | 5109 +++++++++++++++++ .../integrate-6.15/0000.patching_config.yaml | 37 + .../orangepi-5-ultra-rk3588_defconfig | 218 + .../dt/rk3588-orangepi-5-ultra.dts | 180 + 5 files changed, 5601 insertions(+) create mode 100644 config/boards/orangepi5-ultra.csc create mode 100644 patch/kernel/archive/rockchip64-6.12/dt/rk3588-orangepi-5-ultra.dts create mode 100644 patch/kernel/integrate-6.15/0000.patching_config.yaml create mode 100644 patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/orangepi-5-ultra-rk3588_defconfig create mode 100644 patch/u-boot/legacy/u-boot-radxa-rk35xx/dt/rk3588-orangepi-5-ultra.dts diff --git a/config/boards/orangepi5-ultra.csc b/config/boards/orangepi5-ultra.csc new file mode 100644 index 000000000000..f5c389fdd40b --- /dev/null +++ b/config/boards/orangepi5-ultra.csc @@ -0,0 +1,57 @@ +# Rockchip RK3588 octa core whatever fixme +BOARD_NAME="Orange Pi 5 Ultra" +BOARDFAMILY="rockchip-rk3588" +BOARD_MAINTAINER="" +BOOTCONFIG="orangepi-5-ultra-rk3588_defconfig" # vendor name, not standard, see hook below, set BOOT_SOC below to compensate +BOOT_SOC="rk3588" +KERNEL_TARGET="current,edge" +KERNEL_TEST_TARGET="current,edge" +FULL_DESKTOP="yes" +BOOT_LOGO="desktop" +BOOT_FDT_FILE="rockchip/rk3588-orangepi-5-ultra.dtb" +BOOT_SCENARIO="spl-blobs" +BOOT_SUPPORT_SPI="yes" +BOOT_SPI_RKSPI_LOADER="yes" +IMAGE_PARTITION_TABLE="gpt" +#enable_extension "bcmdhd" +BCMDHD_TYPE="sdio" + +# for testing purpose only. needs adaption to mainline once this makes it into 6.15 or .16 +function post_family_config_branch_edge__orangepi5-ultra_use_custom_source() { + KERNEL_MAJOR_MINOR="6.14" # Major and minor versions of this kernel. + KERNELSOURCE='https://github.com/jimmyhon/linux.git' + KERNELBRANCH='branch:integrate-6.15' + KERNELPATCHDIR='integrate-6.15' + EXTRAWIFI=no # due to absence of our own fixups 3rd party wifi drivers break +} + +function post_family_tweaks__orangepi5ultra_naming_audios() { + display_alert "$BOARD" "Renaming orangepi5ultra audios" "info" + + mkdir -p $SDCARD/etc/udev/rules.d/ + echo 'SUBSYSTEM=="sound", ENV{ID_PATH}=="platform-hdmi0-sound", ENV{SOUND_DESCRIPTION}="HDMI0 Audio"' > $SDCARD/etc/udev/rules.d/90-naming-audios.rules + echo 'SUBSYSTEM=="sound", ENV{ID_PATH}=="platform-hdmi1-sound", ENV{SOUND_DESCRIPTION}="HDMI1 Audio"' >> $SDCARD/etc/udev/rules.d/90-naming-audios.rules + echo 'SUBSYSTEM=="sound", ENV{ID_PATH}=="platform-es8388-sound", ENV{SOUND_DESCRIPTION}="ES8388 Audio"' >> $SDCARD/etc/udev/rules.d/90-naming-audios.rules + + return 0 +} + +function post_family_tweaks_bsp__orangepi5ultra_bluetooth() { + display_alert "$BOARD" "Installing ap6611s-bluetooth.service" "info" + + # Bluetooth on this board is handled by a Broadcom (AP6611S) chip and requires + # a custom brcm_patchram_plus binary, plus a systemd service to run it at boot time + install -m 755 $SRC/packages/bsp/rk3399/brcm_patchram_plus_rk3399 $destination/usr/bin + cp $SRC/packages/bsp/rk3399/rk3399-bluetooth.service $destination/lib/systemd/system/ap6611s-bluetooth.service + + # Reuse the service file, ttyS0 -> ttyS7; BCM4345C5.hcd -> SYN43711A0.hcd + sed -i 's/ttyS0/ttyS7/g' $destination/lib/systemd/system/ap6611s-bluetooth.service + sed -i 's/BCM4345C5.hcd/SYN43711A0.hcd/g' $destination/lib/systemd/system/ap6611s-bluetooth.service + return 0 +} + +function post_family_tweaks__orangepi5ultra_enable_bluetooth_service() { + display_alert "$BOARD" "Enabling ap6611s-bluetooth.service" "info" + chroot_sdcard systemctl enable ap6611s-bluetooth.service + return 0 +} \ No newline at end of file diff --git a/patch/kernel/archive/rockchip64-6.12/dt/rk3588-orangepi-5-ultra.dts b/patch/kernel/archive/rockchip64-6.12/dt/rk3588-orangepi-5-ultra.dts new file mode 100644 index 000000000000..035e4a24c66b --- /dev/null +++ b/patch/kernel/archive/rockchip64-6.12/dt/rk3588-orangepi-5-ultra.dts @@ -0,0 +1,5109 @@ +/dts-v1/; + +/ { + compatible = "xunlong,orangepi-5-ultra", "rockchip,rk3588"; + interrupt-parent = <0x01>; + #address-cells = <0x02>; + #size-cells = <0x02>; + model = "Xunlong Orange Pi 5 Ultra"; + + aliases { + gpio0 = "/pinctrl/gpio@fd8a0000"; + gpio1 = "/pinctrl/gpio@fec20000"; + gpio2 = "/pinctrl/gpio@fec30000"; + gpio3 = "/pinctrl/gpio@fec40000"; + gpio4 = "/pinctrl/gpio@fec50000"; + i2c0 = "/i2c@fd880000"; + i2c1 = "/i2c@fea90000"; + i2c2 = "/i2c@feaa0000"; + i2c3 = "/i2c@feab0000"; + i2c4 = "/i2c@feac0000"; + i2c5 = "/i2c@fead0000"; + i2c6 = "/i2c@fec80000"; + i2c7 = "/i2c@fec90000"; + i2c8 = "/i2c@feca0000"; + serial0 = "/serial@fd890000"; + serial1 = "/serial@feb40000"; + serial2 = "/serial@feb50000"; + serial3 = "/serial@feb60000"; + serial4 = "/serial@feb70000"; + serial5 = "/serial@feb80000"; + serial6 = "/serial@feb90000"; + serial7 = "/serial@feba0000"; + serial8 = "/serial@febb0000"; + serial9 = "/serial@febc0000"; + spi0 = "/spi@feb00000"; + spi1 = "/spi@feb10000"; + spi2 = "/spi@feb20000"; + spi3 = "/spi@feb30000"; + spi4 = "/spi@fecb0000"; + mmc0 = "/mmc@fe2e0000"; + mmc1 = "/mmc@fe2c0000"; + }; + + cpus { + #address-cells = <0x01>; + #size-cells = <0x00>; + + cpu-map { + + cluster0 { + + core0 { + cpu = <0x02>; + }; + + core1 { + cpu = <0x03>; + }; + + core2 { + cpu = <0x04>; + }; + + core3 { + cpu = <0x05>; + }; + }; + + cluster1 { + + core0 { + cpu = <0x06>; + }; + + core1 { + cpu = <0x07>; + }; + }; + + cluster2 { + + core0 { + cpu = <0x08>; + }; + + core1 { + cpu = <0x09>; + }; + }; + }; + + cpu_l0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a55"; + reg = <0x00>; + enable-method = "psci"; + capacity-dmips-mhz = <0x212>; + clocks = <0x0a 0x00>; + assigned-clocks = <0x0a 0x00>; + assigned-clock-rates = <0x30a32c00>; + cpu-idle-states = <0x0b>; + i-cache-size = <0x8000>; + i-cache-line-size = <0x40>; + i-cache-sets = <0x80>; + d-cache-size = <0x8000>; + d-cache-line-size = <0x40>; + d-cache-sets = <0x80>; + next-level-cache = <0x0c>; + dynamic-power-coefficient = <0xe4>; + #cooling-cells = <0x02>; + operating-points-v2 = <0x0d>; + cpu-supply = <0x0e>; + phandle = <0x02>; + }; + + cpu_l1: cpu@100 { + device_type = "cpu"; + compatible = "arm,cortex-a55"; + reg = <0x100>; + enable-method = "psci"; + capacity-dmips-mhz = <0x212>; + clocks = <0x0a 0x00>; + cpu-idle-states = <0x0b>; + i-cache-size = <0x8000>; + i-cache-line-size = <0x40>; + i-cache-sets = <0x80>; + d-cache-size = <0x8000>; + d-cache-line-size = <0x40>; + d-cache-sets = <0x80>; + next-level-cache = <0x0f>; + dynamic-power-coefficient = <0xe4>; + #cooling-cells = <0x02>; + operating-points-v2 = <0x0d>; + cpu-supply = <0x0e>; + phandle = <0x03>; + }; + + cpu_l2: cpu@200 { + device_type = "cpu"; + compatible = "arm,cortex-a55"; + reg = <0x200>; + enable-method = "psci"; + capacity-dmips-mhz = <0x212>; + clocks = <0x0a 0x00>; + cpu-idle-states = <0x0b>; + i-cache-size = <0x8000>; + i-cache-line-size = <0x40>; + i-cache-sets = <0x80>; + d-cache-size = <0x8000>; + d-cache-line-size = <0x40>; + d-cache-sets = <0x80>; + next-level-cache = <0x10>; + dynamic-power-coefficient = <0xe4>; + #cooling-cells = <0x02>; + operating-points-v2 = <0x0d>; + cpu-supply = <0x0e>; + phandle = <0x04>; + }; + + cpu_l3: cpu@300 { + device_type = "cpu"; + compatible = "arm,cortex-a55"; + reg = <0x300>; + enable-method = "psci"; + capacity-dmips-mhz = <0x212>; + clocks = <0x0a 0x00>; + cpu-idle-states = <0x0b>; + i-cache-size = <0x8000>; + i-cache-line-size = <0x40>; + i-cache-sets = <0x80>; + d-cache-size = <0x8000>; + d-cache-line-size = <0x40>; + d-cache-sets = <0x80>; + next-level-cache = <0x11>; + dynamic-power-coefficient = <0xe4>; + #cooling-cells = <0x02>; + operating-points-v2 = <0x0d>; + cpu-supply = <0x0e>; + phandle = <0x05>; + }; + + cpu_b0: cpu@400 { + device_type = "cpu"; + compatible = "arm,cortex-a76"; + reg = <0x400>; + enable-method = "psci"; + capacity-dmips-mhz = <0x400>; + clocks = <0x0a 0x02>; + assigned-clocks = <0x0a 0x02>; + assigned-clock-rates = <0x30a32c00>; + cpu-idle-states = <0x0b>; + i-cache-size = <0x10000>; + i-cache-line-size = <0x40>; + i-cache-sets = <0x100>; + d-cache-size = <0x10000>; + d-cache-line-size = <0x40>; + d-cache-sets = <0x100>; + next-level-cache = <0x12>; + dynamic-power-coefficient = <0x1a0>; + #cooling-cells = <0x02>; + operating-points-v2 = <0x13>; + cpu-supply = <0x14>; + phandle = <0x06>; + }; + + cpu_b1: cpu@500 { + device_type = "cpu"; + compatible = "arm,cortex-a76"; + reg = <0x500>; + enable-method = "psci"; + capacity-dmips-mhz = <0x400>; + clocks = <0x0a 0x02>; + cpu-idle-states = <0x0b>; + i-cache-size = <0x10000>; + i-cache-line-size = <0x40>; + i-cache-sets = <0x100>; + d-cache-size = <0x10000>; + d-cache-line-size = <0x40>; + d-cache-sets = <0x100>; + next-level-cache = <0x15>; + dynamic-power-coefficient = <0x1a0>; + #cooling-cells = <0x02>; + operating-points-v2 = <0x13>; + cpu-supply = <0x14>; + phandle = <0x07>; + }; + + cpu_b2: cpu@600 { + device_type = "cpu"; + compatible = "arm,cortex-a76"; + reg = <0x600>; + enable-method = "psci"; + capacity-dmips-mhz = <0x400>; + clocks = <0x0a 0x03>; + assigned-clocks = <0x0a 0x03>; + assigned-clock-rates = <0x30a32c00>; + cpu-idle-states = <0x0b>; + i-cache-size = <0x10000>; + i-cache-line-size = <0x40>; + i-cache-sets = <0x100>; + d-cache-size = <0x10000>; + d-cache-line-size = <0x40>; + d-cache-sets = <0x100>; + next-level-cache = <0x16>; + dynamic-power-coefficient = <0x1a0>; + #cooling-cells = <0x02>; + operating-points-v2 = <0x17>; + cpu-supply = <0x18>; + phandle = <0x08>; + }; + + cpu_b3: cpu@700 { + device_type = "cpu"; + compatible = "arm,cortex-a76"; + reg = <0x700>; + enable-method = "psci"; + capacity-dmips-mhz = <0x400>; + clocks = <0x0a 0x03>; + cpu-idle-states = <0x0b>; + i-cache-size = <0x10000>; + i-cache-line-size = <0x40>; + i-cache-sets = <0x100>; + d-cache-size = <0x10000>; + d-cache-line-size = <0x40>; + d-cache-sets = <0x100>; + next-level-cache = <0x19>; + dynamic-power-coefficient = <0x1a0>; + #cooling-cells = <0x02>; + operating-points-v2 = <0x17>; + cpu-supply = <0x18>; + phandle = <0x09>; + }; + + idle-states { + entry-method = "psci"; + + CPU_SLEEP: cpu-sleep { + compatible = "arm,idle-state"; + local-timer-stop; + arm,psci-suspend-param = <0x10000>; + entry-latency-us = <0x64>; + exit-latency-us = <0x78>; + min-residency-us = <0x3e8>; + phandle = <0x0b>; + }; + }; + + l2_cache_l0: l2-cache-l0 { + compatible = "cache"; + cache-size = <0x20000>; + cache-line-size = <0x40>; + cache-sets = <0x200>; + cache-level = <0x02>; + cache-unified; + next-level-cache = <0x1a>; + phandle = <0x0c>; + }; + + l2_cache_l1: l2-cache-l1 { + compatible = "cache"; + cache-size = <0x20000>; + cache-line-size = <0x40>; + cache-sets = <0x200>; + cache-level = <0x02>; + cache-unified; + next-level-cache = <0x1a>; + phandle = <0x0f>; + }; + + l2_cache_l2: l2-cache-l2 { + compatible = "cache"; + cache-size = <0x20000>; + cache-line-size = <0x40>; + cache-sets = <0x200>; + cache-level = <0x02>; + cache-unified; + next-level-cache = <0x1a>; + phandle = <0x10>; + }; + + l2_cache_l3: l2-cache-l3 { + compatible = "cache"; + cache-size = <0x20000>; + cache-line-size = <0x40>; + cache-sets = <0x200>; + cache-level = <0x02>; + cache-unified; + next-level-cache = <0x1a>; + phandle = <0x11>; + }; + + l2_cache_b0: l2-cache-b0 { + compatible = "cache"; + cache-size = <0x80000>; + cache-line-size = <0x40>; + cache-sets = <0x400>; + cache-level = <0x02>; + cache-unified; + next-level-cache = <0x1a>; + phandle = <0x12>; + }; + + l2_cache_b1: l2-cache-b1 { + compatible = "cache"; + cache-size = <0x80000>; + cache-line-size = <0x40>; + cache-sets = <0x400>; + cache-level = <0x02>; + cache-unified; + next-level-cache = <0x1a>; + phandle = <0x15>; + }; + + l2_cache_b2: l2-cache-b2 { + compatible = "cache"; + cache-size = <0x80000>; + cache-line-size = <0x40>; + cache-sets = <0x400>; + cache-level = <0x02>; + cache-unified; + next-level-cache = <0x1a>; + phandle = <0x16>; + }; + + l2_cache_b3: l2-cache-b3 { + compatible = "cache"; + cache-size = <0x80000>; + cache-line-size = <0x40>; + cache-sets = <0x400>; + cache-level = <0x02>; + cache-unified; + next-level-cache = <0x1a>; + phandle = <0x19>; + }; + }; + + l3_cache: l3-cache { + compatible = "cache"; + cache-size = <0x300000>; + cache-line-size = <0x40>; + cache-sets = <0x1000>; + cache-level = <0x03>; + cache-unified; + phandle = <0x1a>; + }; + + display_subsystem: display-subsystem { + compatible = "rockchip,display-subsystem"; + ports = <0x1b>; + }; + + firmware { + + scmi: scmi { + compatible = "arm,scmi-smc"; + arm,smc-id = <0x82000010>; + shmem = <0x1c>; + #address-cells = <0x01>; + #size-cells = <0x00>; + + scmi_clk: protocol@14 { + reg = <0x14>; + #clock-cells = <0x01>; + phandle = <0x0a>; + }; + + scmi_reset: protocol@16 { + reg = <0x16>; + #reset-cells = <0x01>; + }; + }; + }; + + hdmi0_sound: hdmi0-sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,mclk-fs = <0x80>; + simple-audio-card,name = "hdmi0"; + status = "disabled"; + + simple-audio-card,codec { + sound-dai = <0x1d>; + }; + + simple-audio-card,cpu { + sound-dai = <0x1e>; + }; + }; + + pmu-a55 { + compatible = "arm,cortex-a55-pmu"; + interrupts = <0x01 0x07 0x04 0x1f>; + }; + + pmu-a76 { + compatible = "arm,cortex-a76-pmu"; + interrupts = <0x01 0x07 0x04 0x20>; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + spll: clock-0 { + compatible = "fixed-clock"; + clock-frequency = <0x29d7ab80>; + clock-output-names = "spll"; + #clock-cells = <0x00>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <0x01 0x0d 0x04 0x00>, <0x01 0x0e 0x04 0x00>, <0x01 0x0b 0x04 0x00>, <0x01 0x0a 0x04 0x00>, <0x01 0x0c 0x04 0x00>; + interrupt-names = "sec-phys", "phys", "virt", "hyp-phys", "hyp-virt"; + }; + + xin24m: clock-1 { + compatible = "fixed-clock"; + clock-frequency = <0x16e3600>; + clock-output-names = "xin24m"; + #clock-cells = <0x00>; + }; + + xin32k: clock-2 { + compatible = "fixed-clock"; + clock-frequency = <0x8000>; + clock-output-names = "xin32k"; + #clock-cells = <0x00>; + }; + + pmu_sram: sram@10f000 { + compatible = "mmio-sram"; + reg = <0x00 0x10f000 0x00 0x100>; + ranges = <0x00 0x00 0x10f000 0x100>; + #address-cells = <0x01>; + #size-cells = <0x01>; + + scmi_shmem: sram@0 { + compatible = "arm,scmi-shmem"; + reg = <0x00 0x100>; + phandle = <0x1c>; + }; + }; + + gpu: gpu@fb000000 { + compatible = "rockchip,rk3588-mali", "arm,mali-valhall-csf"; + reg = <0x00 0xfb000000 0x00 0x200000>; + #cooling-cells = <0x02>; + assigned-clocks = <0x0a 0x05>; + assigned-clock-rates = <0xbebc200>; + clocks = <0x21 0x106>, < 0x21 0x107>, < 0x21 0x108>; + clock-names = "core", "coregroup", "stacks"; + dynamic-power-coefficient = <0xba6>; + interrupts = <0x00 0x5c 0x04 0x00>, <0x00 0x5d 0x04 0x00>, <0x00 0x5e 0x04 0x00>; + interrupt-names = "job", "mmu", "gpu"; + power-domains = <0x22 0x0c>; + status = "okay"; + operating-points-v2 = <0x23>; + mali-supply = <0x24>; + phandle = <0xde>; + }; + + usb_host0_xhci: usb@fc000000 { + compatible = "rockchip,rk3588-dwc3", "snps,dwc3"; + reg = <0x00 0xfc000000 0x00 0x400000>; + interrupts = <0x00 0xdc 0x04 0x00>; + clocks = <0x21 0x194>, < 0x21 0x193>, < 0x21 0x192>; + clock-names = "ref_clk", "suspend_clk", "bus_clk"; + dr_mode = "host"; + phys = <0x25>, < 0x26 0x04>; + phy-names = "usb2-phy", "usb3-phy"; + phy_type = "utmi_wide"; + power-domains = <0x22 0x1f>; + resets = <0x21 0x152>; + snps,dis_enblslpm_quirk; + snps,dis-u1-entry-quirk; + snps,dis-u2-entry-quirk; + snps,dis-u2-freeclk-exists-quirk; + snps,dis-del-phy-power-chg-quirk; + snps,dis-tx-ipgap-linecheck-quirk; + status = "okay"; + }; + + usb_host0_ehci: usb@fc800000 { + compatible = "rockchip,rk3588-ehci", "generic-ehci"; + reg = <0x00 0xfc800000 0x00 0x40000>; + interrupts = <0x00 0xd7 0x04 0x00>; + clocks = <0x21 0x18e>, < 0x21 0x18f>, < 0x21 0x2c0>, < 0x27>; + phys = <0x28>; + phy-names = "usb"; + power-domains = <0x22 0x1f>; + status = "okay"; + }; + + usb_host0_ohci: usb@fc840000 { + compatible = "rockchip,rk3588-ohci", "generic-ohci"; + reg = <0x00 0xfc840000 0x00 0x40000>; + interrupts = <0x00 0xd8 0x04 0x00>; + clocks = <0x21 0x18e>, < 0x21 0x18f>, < 0x21 0x2c0>, < 0x27>; + phys = <0x28>; + phy-names = "usb"; + power-domains = <0x22 0x1f>; + status = "okay"; + }; + + usb_host1_ehci: usb@fc880000 { + compatible = "rockchip,rk3588-ehci", "generic-ehci"; + reg = <0x00 0xfc880000 0x00 0x40000>; + interrupts = <0x00 0xda 0x04 0x00>; + clocks = <0x21 0x190>, < 0x21 0x191>, < 0x21 0x2c0>, < 0x29>; + phys = <0x2a>; + phy-names = "usb"; + power-domains = <0x22 0x1f>; + status = "okay"; + }; + + usb_host1_ohci: usb@fc8c0000 { + compatible = "rockchip,rk3588-ohci", "generic-ohci"; + reg = <0x00 0xfc8c0000 0x00 0x40000>; + interrupts = <0x00 0xdb 0x04 0x00>; + clocks = <0x21 0x190>, < 0x21 0x191>, < 0x21 0x2c0>, < 0x29>; + phys = <0x2a>; + phy-names = "usb"; + power-domains = <0x22 0x1f>; + status = "okay"; + }; + + usb_host2_xhci: usb@fcd00000 { + compatible = "rockchip,rk3588-dwc3", "snps,dwc3"; + reg = <0x00 0xfcd00000 0x00 0x400000>; + interrupts = <0x00 0xde 0x04 0x00>; + clocks = <0x21 0x16a>, < 0x21 0x169>, < 0x21 0x168>, < 0x21 0x16b>, < 0x21 0x172>; + clock-names = "ref_clk", "suspend_clk", "bus_clk", "utmi", "pipe"; + dr_mode = "host"; + phys = <0x2b 0x04>; + phy-names = "usb3-phy"; + phy_type = "utmi_wide"; + resets = <0x21 0x134>; + snps,dis_enblslpm_quirk; + snps,dis-u2-freeclk-exists-quirk; + snps,dis-del-phy-power-chg-quirk; + snps,dis-tx-ipgap-linecheck-quirk; + snps,dis_rxdet_inp3_quirk; + status = "disabled"; + }; + + mmu600_pcie: iommu@fc900000 { + compatible = "arm,smmu-v3"; + reg = <0x00 0xfc900000 0x00 0x200000>; + interrupts = <0x00 0x171 0x04 0x00>, <0x00 0x173 0x04 0x00>, <0x00 0x176 0x04 0x00>, <0x00 0x16f 0x04 0x00>; + interrupt-names = "eventq", "gerror", "priq", "cmdq-sync"; + #iommu-cells = <0x01>; + phandle = <0x7c>; + }; + + mmu600_php: iommu@fcb00000 { + compatible = "arm,smmu-v3"; + reg = <0x00 0xfcb00000 0x00 0x200000>; + interrupts = <0x00 0x17d 0x04 0x00>, <0x00 0x17f 0x04 0x00>, <0x00 0x182 0x04 0x00>, <0x00 0x17b 0x04 0x00>; + interrupt-names = "eventq", "gerror", "priq", "cmdq-sync"; + #iommu-cells = <0x01>; + status = "disabled"; + }; + + pmu1grf: syscon@fd58a000 { + compatible = "rockchip,rk3588-pmugrf", "syscon", "simple-mfd"; + reg = <0x00 0xfd58a000 0x00 0x10000>; + phandle = <0x79>; + }; + + sys_grf: syscon@fd58c000 { + compatible = "rockchip,rk3588-sys-grf", "syscon"; + reg = <0x00 0xfd58c000 0x00 0x1000>; + phandle = <0x6e>; + }; + + vop_grf: syscon@fd5a4000 { + compatible = "rockchip,rk3588-vop-grf", "syscon"; + reg = <0x00 0xfd5a4000 0x00 0x2000>; + phandle = <0x6f>; + }; + + vo0_grf: syscon@fd5a6000 { + compatible = "rockchip,rk3588-vo0-grf", "syscon"; + reg = <0x00 0xfd5a6000 0x00 0x2000>; + clocks = <0x21 0x1e9>; + phandle = <0xef>; + }; + + vo1_grf: syscon@fd5a8000 { + compatible = "rockchip,rk3588-vo1-grf", "syscon"; + reg = <0x00 0xfd5a8000 0x00 0x4000>; + clocks = <0x21 0x2d1>; + phandle = <0x70>; + }; + + usb_grf: syscon@fd5ac000 { + compatible = "rockchip,rk3588-usb-grf", "syscon"; + reg = <0x00 0xfd5ac000 0x00 0x4000>; + phandle = <0xed>; + }; + + php_grf: syscon@fd5b0000 { + compatible = "rockchip,rk3588-php-grf", "syscon"; + reg = <0x00 0xfd5b0000 0x00 0x1000>; + phandle = <0x2e>; + }; + + pipe_phy0_grf: syscon@fd5bc000 { + compatible = "rockchip,rk3588-pipe-phy-grf", "syscon"; + reg = <0x00 0xfd5bc000 0x00 0x100>; + phandle = <0xf0>; + }; + + pipe_phy2_grf: syscon@fd5c4000 { + compatible = "rockchip,rk3588-pipe-phy-grf", "syscon"; + reg = <0x00 0xfd5c4000 0x00 0x100>; + phandle = <0xf1>; + }; + + usbdpphy0_grf: syscon@fd5c8000 { + compatible = "rockchip,rk3588-usbdpphy-grf", "syscon"; + reg = <0x00 0xfd5c8000 0x00 0x4000>; + phandle = <0xee>; + }; + + usb2phy0_grf: syscon@fd5d0000 { + compatible = "rockchip,rk3588-usb2phy-grf", "syscon", "simple-mfd"; + reg = <0x00 0xfd5d0000 0x00 0x4000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0xec>; + + u2phy0: usb2phy@0 { + compatible = "rockchip,rk3588-usb2phy"; + reg = <0x00 0x10>; + #clock-cells = <0x00>; + clocks = <0x21 0x2a0>; + clock-names = "phyclk"; + clock-output-names = "usb480m_phy0"; + interrupts = <0x00 0x189 0x04 0x00>; + resets = <0x21 0x26d>, < 0x21 0x21d>; + reset-names = "phy", "apb"; + status = "okay"; + phandle = <0xeb>; + + u2phy0_otg: otg-port { + #phy-cells = <0x00>; + status = "okay"; + phy-supply = <0x2c>; + phandle = <0x25>; + }; + }; + }; + + usb2phy2_grf: syscon@fd5d8000 { + compatible = "rockchip,rk3588-usb2phy-grf", "syscon", "simple-mfd"; + reg = <0x00 0xfd5d8000 0x00 0x4000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + + u2phy2: usb2phy@8000 { + compatible = "rockchip,rk3588-usb2phy"; + reg = <0x8000 0x10>; + #clock-cells = <0x00>; + clocks = <0x21 0x2a0>; + clock-names = "phyclk"; + clock-output-names = "usb480m_phy2"; + interrupts = <0x00 0x187 0x04 0x00>; + resets = <0x21 0x26f>, < 0x21 0x21f>; + reset-names = "phy", "apb"; + status = "okay"; + phandle = <0x27>; + + u2phy2_host: host-port { + #phy-cells = <0x00>; + status = "okay"; + phy-supply = <0x2d>; + phandle = <0x28>; + }; + }; + }; + + usb2phy3_grf: syscon@fd5dc000 { + compatible = "rockchip,rk3588-usb2phy-grf", "syscon", "simple-mfd"; + reg = <0x00 0xfd5dc000 0x00 0x4000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + + u2phy3: usb2phy@c000 { + compatible = "rockchip,rk3588-usb2phy"; + reg = <0xc000 0x10>; + #clock-cells = <0x00>; + clocks = <0x21 0x2a0>; + clock-names = "phyclk"; + clock-output-names = "usb480m_phy3"; + interrupts = <0x00 0x188 0x04 0x00>; + resets = <0x21 0x270>, < 0x21 0x220>; + reset-names = "phy", "apb"; + status = "okay"; + phandle = <0x29>; + + u2phy3_host: host-port { + #phy-cells = <0x00>; + status = "okay"; + phy-supply = <0x2d>; + phandle = <0x2a>; + }; + }; + }; + + hdptxphy0_grf: syscon@fd5e0000 { + compatible = "rockchip,rk3588-hdptxphy-grf", "syscon"; + reg = <0x00 0xfd5e0000 0x00 0x100>; + phandle = <0xea>; + }; + + ioc: syscon@fd5f0000 { + compatible = "rockchip,rk3588-ioc", "syscon"; + reg = <0x00 0xfd5f0000 0x00 0x10000>; + phandle = <0xf2>; + }; + + system_sram1: sram@fd600000 { + compatible = "mmio-sram"; + reg = <0x00 0xfd600000 0x00 0x100000>; + ranges = <0x00 0x00 0xfd600000 0x100000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + }; + + cru: clock-controller@fd7c0000 { + compatible = "rockchip,rk3588-cru"; + reg = <0x00 0xfd7c0000 0x00 0x5c000>; + assigned-clocks = <0x21 0x08>, < 0x21 0x04>, < 0x21 0x07>, < 0x21 0x06>, < 0x21 0xcc>, < 0x21 0xce>, < 0x21 0xcd>, < 0x21 0x100>, < 0x21 0x101>, < 0x21 0x102>, < 0x21 0x286>, < 0x21 0x287>, < 0x21 0x25d>, < 0x21 0x71>, < 0x21 0xe0>, < 0x21 0x106>; + assigned-clock-rates = <0x4190ab00>, <0x2ee00000>, <0x32a9f880>, <0x46cf7100>, <0x29d7ab80>, <0x17d78400>, <0x1dcd6500>, <0x2faf0800>, <0x5f5e100>, <0x17d78400>, <0x5f5e100>, <0xbebc200>, <0x1dcd6500>, <0x165a0bc0>, <0x8f0d180>, <0xbebc200>; + rockchip,grf = <0x2e>; + #clock-cells = <0x01>; + #reset-cells = <0x01>; + phandle = <0x21>; + }; + + i2c0: i2c@fd880000 { + compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c"; + reg = <0x00 0xfd880000 0x00 0x1000>; + interrupts = <0x00 0x13d 0x04 0x00>; + clocks = <0x21 0x274>, < 0x21 0x273>; + clock-names = "i2c", "pclk"; + pinctrl-0 = <0x2f>; + pinctrl-names = "default"; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + + vdd_cpu_big0_s0: regulator@42 { + compatible = "rockchip,rk8602"; + reg = <0x42>; + fcs,suspend-voltage-selector = <0x01>; + regulator-name = "vdd_cpu_big0_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x86470>; + regulator-max-microvolt = <0x100590>; + regulator-ramp-delay = <0x8fc>; + vin-supply = <0x30>; + phandle = <0x14>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_cpu_big1_s0: regulator@43 { + compatible = "rockchip,rk8603", "rockchip,rk8602"; + reg = <0x43>; + fcs,suspend-voltage-selector = <0x01>; + regulator-name = "vdd_cpu_big1_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x86470>; + regulator-max-microvolt = <0x100590>; + regulator-ramp-delay = <0x8fc>; + vin-supply = <0x30>; + phandle = <0x18>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + }; + + uart0: serial@fd890000 { + compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart"; + reg = <0x00 0xfd890000 0x00 0x100>; + interrupts = <0x00 0x14b 0x04 0x00>; + clocks = <0x21 0x29b>, < 0x21 0x29c>; + clock-names = "baudclk", "apb_pclk"; + dmas = <0x31 0x06>, < 0x31 0x07>; + dma-names = "tx", "rx"; + pinctrl-0 = <0x32>; + pinctrl-names = "default"; + reg-shift = <0x02>; + reg-io-width = <0x04>; + status = "disabled"; + }; + + pwm0: pwm@fd8b0000 { + compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm"; + reg = <0x00 0xfd8b0000 0x00 0x10>; + clocks = <0x21 0x292>, < 0x21 0x291>; + clock-names = "pwm", "pclk"; + pinctrl-0 = <0x33>; + pinctrl-names = "default"; + #pwm-cells = <0x03>; + status = "disabled"; + }; + + pwm1: pwm@fd8b0010 { + compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm"; + reg = <0x00 0xfd8b0010 0x00 0x10>; + clocks = <0x21 0x292>, < 0x21 0x291>; + clock-names = "pwm", "pclk"; + pinctrl-0 = <0x34>; + pinctrl-names = "default"; + #pwm-cells = <0x03>; + status = "disabled"; + }; + + pwm2: pwm@fd8b0020 { + compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm"; + reg = <0x00 0xfd8b0020 0x00 0x10>; + clocks = <0x21 0x292>, < 0x21 0x291>; + clock-names = "pwm", "pclk"; + pinctrl-0 = <0x35>; + pinctrl-names = "default"; + #pwm-cells = <0x03>; + status = "disabled"; + }; + + pwm3: pwm@fd8b0030 { + compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm"; + reg = <0x00 0xfd8b0030 0x00 0x10>; + clocks = <0x21 0x292>, < 0x21 0x291>; + clock-names = "pwm", "pclk"; + pinctrl-0 = <0x36>; + pinctrl-names = "default"; + #pwm-cells = <0x03>; + status = "disabled"; + }; + + pmu: power-management@fd8d8000 { + compatible = "rockchip,rk3588-pmu", "syscon", "simple-mfd"; + reg = <0x00 0xfd8d8000 0x00 0x400>; + phandle = <0x71>; + + power: power-controller { + compatible = "rockchip,rk3588-power-controller"; + #address-cells = <0x01>; + #power-domain-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + phandle = <0x22>; + + power-domain@8 { + reg = <0x08>; + #power-domain-cells = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + + power-domain@9 { + reg = <0x09>; + clocks = <0x21 0x121>, < 0x21 0x123>, < 0x21 0x122>, < 0x21 0x118>; + pm_qos = <0x37>, < 0x38>, < 0x39>; + #power-domain-cells = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + + power-domain@10 { + reg = <0x0a>; + clocks = <0x21 0x121>, < 0x21 0x123>, < 0x21 0x122>; + pm_qos = <0x3a>; + #power-domain-cells = <0x00>; + }; + + power-domain@11 { + reg = <0x0b>; + clocks = <0x21 0x121>, < 0x21 0x123>, < 0x21 0x122>; + pm_qos = <0x3b>; + #power-domain-cells = <0x00>; + }; + }; + }; + + power-domain@12 { + reg = <0x0c>; + clocks = <0x21 0x106>, < 0x21 0x107>, < 0x21 0x108>; + pm_qos = <0x3c>, < 0x3d>, < 0x3e>, < 0x3f>; + #power-domain-cells = <0x00>; + }; + + power-domain@13 { + reg = <0x0d>; + #address-cells = <0x01>; + #size-cells = <0x00>; + #power-domain-cells = <0x00>; + + power-domain@14 { + reg = <0x0e>; + clocks = <0x21 0x180>, < 0x21 0x1af>, < 0x21 0x1ad>, < 0x21 0x181>, < 0x21 0x17f>; + pm_qos = <0x40>; + #power-domain-cells = <0x00>; + }; + + power-domain@15 { + reg = <0x0f>; + clocks = <0x21 0x185>, < 0x21 0x1af>, < 0x21 0x1ad>, < 0x21 0x186>; + pm_qos = <0x41>; + #power-domain-cells = <0x00>; + }; + + power-domain@16 { + reg = <0x10>; + clocks = <0x21 0x1b5>, < 0x21 0x1b6>; + pm_qos = <0x42>, < 0x43>, < 0x44>; + #address-cells = <0x01>; + #size-cells = <0x00>; + #power-domain-cells = <0x00>; + + power-domain@17 { + reg = <0x11>; + clocks = <0x21 0x1ba>, < 0x21 0x1b5>, < 0x21 0x1b6>, < 0x21 0x1bb>; + pm_qos = <0x45>, < 0x46>, < 0x47>; + #power-domain-cells = <0x00>; + }; + }; + }; + + power-domain@21 { + reg = <0x15>; + clocks = <0x21 0x1af>, < 0x21 0x1ae>, < 0x21 0x1ad>, < 0x21 0x1b0>, < 0x21 0x19b>, < 0x21 0x19a>, < 0x21 0x19d>, < 0x21 0x19e>, < 0x21 0x19f>, < 0x21 0x1a0>, < 0x21 0x1a1>, < 0x21 0x1a2>, < 0x21 0x1a3>, < 0x21 0x1a4>, < 0x21 0x1a5>, < 0x21 0x1a6>, < 0x21 0x1a8>, < 0x21 0x1a7>; + pm_qos = <0x48>, < 0x49>, < 0x4a>, < 0x4b>, < 0x4c>, < 0x4d>, < 0x4e>, < 0x4f>; + #address-cells = <0x01>; + #size-cells = <0x00>; + #power-domain-cells = <0x00>; + + power-domain@23 { + reg = <0x17>; + clocks = <0x21 0x43>, < 0x21 0x41>, < 0x21 0x1af>; + pm_qos = <0x50>; + #power-domain-cells = <0x00>; + }; + + power-domain@14 { + reg = <0x0e>; + clocks = <0x21 0x180>, < 0x21 0x1af>, < 0x21 0x1ad>, < 0x21 0x181>; + pm_qos = <0x40>; + #power-domain-cells = <0x00>; + }; + + power-domain@15 { + reg = <0x0f>; + clocks = <0x21 0x185>, < 0x21 0x1af>, < 0x21 0x1ad>; + pm_qos = <0x41>; + #power-domain-cells = <0x00>; + }; + + power-domain@22 { + reg = <0x16>; + clocks = <0x21 0x1ab>, < 0x21 0x1aa>; + pm_qos = <0x51>; + #power-domain-cells = <0x00>; + }; + }; + + power-domain@24 { + reg = <0x18>; + clocks = <0x21 0x25b>, < 0x21 0x25a>, < 0x21 0x25d>; + pm_qos = <0x52>, < 0x53>; + #address-cells = <0x01>; + #size-cells = <0x00>; + #power-domain-cells = <0x00>; + + power-domain@25 { + reg = <0x19>; + clocks = <0x21 0x1e7>, < 0x21 0x1e8>, < 0x21 0x1e6>, < 0x21 0x1e4>, < 0x21 0x1df>, < 0x21 0x1de>, < 0x21 0x25a>; + pm_qos = <0x54>; + #power-domain-cells = <0x00>; + }; + }; + + power-domain@26 { + reg = <0x1a>; + clocks = <0x21 0x21d>, < 0x21 0x21e>, < 0x21 0x21c>, < 0x21 0x207>, < 0x21 0x206>, < 0x21 0x21a>, < 0x21 0x251>; + pm_qos = <0x55>, < 0x56>; + #power-domain-cells = <0x00>; + }; + + power-domain@27 { + reg = <0x1b>; + clocks = <0x21 0x1d2>, < 0x21 0x1d3>, < 0x21 0x1d0>, < 0x21 0x1cf>, < 0x21 0x1d6>, < 0x21 0x1d5>; + pm_qos = <0x57>, < 0x58>, < 0x59>, < 0x5a>; + #address-cells = <0x01>; + #size-cells = <0x00>; + #power-domain-cells = <0x00>; + + power-domain@28 { + reg = <0x1c>; + clocks = <0x21 0x113>, < 0x21 0x112>, < 0x21 0x1d2>, < 0x21 0x1d3>; + pm_qos = <0x5b>, < 0x5c>; + #power-domain-cells = <0x00>; + }; + + power-domain@29 { + reg = <0x1d>; + clocks = <0x21 0x1c7>, < 0x21 0x1c6>, < 0x21 0x1ca>, < 0x21 0x1c9>, < 0x21 0x1d3>; + pm_qos = <0x5d>, < 0x5e>; + #power-domain-cells = <0x00>; + }; + }; + + power-domain@30 { + reg = <0x1e>; + clocks = <0x21 0x17a>, < 0x21 0x17b>; + pm_qos = <0x5f>; + #power-domain-cells = <0x00>; + }; + + power-domain@31 { + reg = <0x1f>; + clocks = <0x21 0x157>, < 0x21 0x18c>, < 0x21 0x2c0>, < 0x21 0x18d>, < 0x21 0x18e>, < 0x21 0x18f>, < 0x21 0x190>, < 0x21 0x191>; + pm_qos = <0x60>, < 0x61>, < 0x62>, < 0x63>; + #power-domain-cells = <0x00>; + }; + + power-domain@33 { + reg = <0x21>; + clocks = <0x21 0x157>, < 0x21 0x15a>, < 0x21 0x15b>; + #power-domain-cells = <0x00>; + }; + + power-domain@34 { + reg = <0x22>; + clocks = <0x21 0x157>, < 0x21 0x15a>, < 0x21 0x15b>; + #power-domain-cells = <0x00>; + }; + + power-domain@37 { + reg = <0x25>; + clocks = <0x21 0x18a>, < 0x21 0x132>; + pm_qos = <0x64>; + #power-domain-cells = <0x00>; + }; + + power-domain@38 { + reg = <0x26>; + clocks = <0x21 0x34>, < 0x21 0x35>; + #power-domain-cells = <0x00>; + }; + + power-domain@40 { + reg = <0x28>; + pm_qos = <0x65>; + #power-domain-cells = <0x00>; + }; + }; + }; + + vpu121: video-codec@fdb50000 { + compatible = "rockchip,rk3588-vpu121", "rockchip,rk3568-vpu"; + reg = <0x00 0xfdb50000 0x00 0x800>; + interrupts = <0x00 0x77 0x04 0x00>; + interrupt-names = "vdpu"; + clocks = <0x21 0x1b1>, < 0x21 0x1b2>; + clock-names = "aclk", "hclk"; + iommus = <0x66>; + power-domains = <0x22 0x15>; + }; + + vpu121_mmu: iommu@fdb50800 { + compatible = "rockchip,rk3588-iommu", "rockchip,rk3568-iommu"; + reg = <0x00 0xfdb50800 0x00 0x40>; + interrupts = <0x00 0x76 0x04 0x00>; + clock-names = "aclk", "iface"; + clocks = <0x21 0x1b1>, < 0x21 0x1b2>; + power-domains = <0x22 0x15>; + #iommu-cells = <0x00>; + phandle = <0x66>; + }; + + rga: rga@fdb80000 { + compatible = "rockchip,rk3588-rga", "rockchip,rk3288-rga"; + reg = <0x00 0xfdb80000 0x00 0x180>; + interrupts = <0x00 0x74 0x04 0x00>; + clocks = <0x21 0x1a8>, < 0x21 0x1a7>, < 0x21 0x1a9>; + clock-names = "aclk", "hclk", "sclk"; + resets = <0x21 0x172>, < 0x21 0x171>, < 0x21 0x170>; + reset-names = "core", "axi", "ahb"; + power-domains = <0x22 0x15>; + }; + + vepu121_0: video-codec@fdba0000 { + compatible = "rockchip,rk3588-vepu121"; + reg = <0x00 0xfdba0000 0x00 0x800>; + interrupts = <0x00 0x7a 0x04 0x00>; + clocks = <0x21 0x19d>, < 0x21 0x19e>; + clock-names = "aclk", "hclk"; + iommus = <0x67>; + power-domains = <0x22 0x15>; + }; + + vepu121_0_mmu: iommu@fdba0800 { + compatible = "rockchip,rk3588-iommu", "rockchip,rk3568-iommu"; + reg = <0x00 0xfdba0800 0x00 0x40>; + interrupts = <0x00 0x79 0x04 0x00>; + clocks = <0x21 0x19d>, < 0x21 0x19e>; + clock-names = "aclk", "iface"; + power-domains = <0x22 0x15>; + #iommu-cells = <0x00>; + phandle = <0x67>; + }; + + vepu121_1: video-codec@fdba4000 { + compatible = "rockchip,rk3588-vepu121"; + reg = <0x00 0xfdba4000 0x00 0x800>; + interrupts = <0x00 0x7c 0x04 0x00>; + clocks = <0x21 0x19f>, < 0x21 0x1a0>; + clock-names = "aclk", "hclk"; + iommus = <0x68>; + power-domains = <0x22 0x15>; + }; + + vepu121_1_mmu: iommu@fdba4800 { + compatible = "rockchip,rk3588-iommu", "rockchip,rk3568-iommu"; + reg = <0x00 0xfdba4800 0x00 0x40>; + interrupts = <0x00 0x7b 0x04 0x00>; + clocks = <0x21 0x19f>, < 0x21 0x1a0>; + clock-names = "aclk", "iface"; + power-domains = <0x22 0x15>; + #iommu-cells = <0x00>; + phandle = <0x68>; + }; + + vepu121_2: video-codec@fdba8000 { + compatible = "rockchip,rk3588-vepu121"; + reg = <0x00 0xfdba8000 0x00 0x800>; + interrupts = <0x00 0x7e 0x04 0x00>; + clocks = <0x21 0x1a1>, < 0x21 0x1a2>; + clock-names = "aclk", "hclk"; + iommus = <0x69>; + power-domains = <0x22 0x15>; + }; + + vepu121_2_mmu: iommu@fdba8800 { + compatible = "rockchip,rk3588-iommu", "rockchip,rk3568-iommu"; + reg = <0x00 0xfdba8800 0x00 0x40>; + interrupts = <0x00 0x7d 0x04 0x00>; + clocks = <0x21 0x1a1>, < 0x21 0x1a2>; + clock-names = "aclk", "iface"; + power-domains = <0x22 0x15>; + #iommu-cells = <0x00>; + phandle = <0x69>; + }; + + vepu121_3: video-codec@fdbac000 { + compatible = "rockchip,rk3588-vepu121"; + reg = <0x00 0xfdbac000 0x00 0x800>; + interrupts = <0x00 0x80 0x04 0x00>; + clocks = <0x21 0x1a3>, < 0x21 0x1a4>; + clock-names = "aclk", "hclk"; + iommus = <0x6a>; + power-domains = <0x22 0x15>; + }; + + vepu121_3_mmu: iommu@fdbac800 { + compatible = "rockchip,rk3588-iommu", "rockchip,rk3568-iommu"; + reg = <0x00 0xfdbac800 0x00 0x40>; + interrupts = <0x00 0x7f 0x04 0x00>; + clocks = <0x21 0x1a3>, < 0x21 0x1a4>; + clock-names = "aclk", "iface"; + power-domains = <0x22 0x15>; + #iommu-cells = <0x00>; + phandle = <0x6a>; + }; + + av1d: video-codec@fdc70000 { + compatible = "rockchip,rk3588-av1-vpu"; + reg = <0x00 0xfdc70000 0x00 0x800>; + interrupts = <0x00 0x6c 0x04 0x00>; + interrupt-names = "vdpu"; + assigned-clocks = <0x21 0x41>, < 0x21 0x43>; + assigned-clock-rates = <0x17d78400>, <0x17d78400>; + clocks = <0x21 0x41>, < 0x21 0x43>; + clock-names = "aclk", "hclk"; + power-domains = <0x22 0x17>; + resets = <0x21 0x1fe>, < 0x21 0x200>, < 0x21 0x1fd>, < 0x21 0x1ff>; + }; + + vop: vop@fdd90000 { + compatible = "rockchip,rk3588-vop"; + reg = <0x00 0xfdd90000 0x00 0x4200>, <0x00 0xfdd95000 0x00 0x1000>; + reg-names = "vop", "gamma-lut"; + interrupts = <0x00 0x9c 0x04 0x00>; + clocks = <0x21 0x25d>, < 0x21 0x25c>, < 0x21 0x261>, < 0x21 0x262>, < 0x21 0x263>, < 0x21 0x264>, < 0x21 0x25b>, < 0x6b>, < 0x6c>; + clock-names = "aclk", "hclk", "dclk_vp0", "dclk_vp1", "dclk_vp2", "dclk_vp3", "pclk_vop", "pll_hdmiphy0", "pll_hdmiphy1"; + iommus = <0x6d>; + power-domains = <0x22 0x18>; + rockchip,grf = <0x6e>; + rockchip,vop-grf = <0x6f>; + rockchip,vo1-grf = <0x70>; + rockchip,pmu = <0x71>; + status = "okay"; + + vop_out: ports { + #address-cells = <0x01>; + #size-cells = <0x00>; + phandle = <0x1b>; + + vp0: port@0 { + #address-cells = <0x01>; + #size-cells = <0x00>; + reg = <0x00>; + + vp0_out_hdmi1: endpoint@8 { + reg = <0x08>; + remote-endpoint = <0x72>; + phandle = <0x103>; + }; + }; + + vp1: port@1 { + #address-cells = <0x01>; + #size-cells = <0x00>; + reg = <0x01>; + }; + + vp2: port@2 { + #address-cells = <0x01>; + #size-cells = <0x00>; + reg = <0x02>; + }; + + vp3: port@3 { + #address-cells = <0x01>; + #size-cells = <0x00>; + reg = <0x03>; + }; + }; + }; + + vop_mmu: iommu@fdd97e00 { + compatible = "rockchip,rk3588-iommu", "rockchip,rk3568-iommu"; + reg = <0x00 0xfdd97e00 0x00 0x100>, <0x00 0xfdd97f00 0x00 0x100>; + interrupts = <0x00 0x9c 0x04 0x00>; + clocks = <0x21 0x25d>, < 0x21 0x25c>; + clock-names = "aclk", "iface"; + #iommu-cells = <0x00>; + power-domains = <0x22 0x18>; + status = "okay"; + phandle = <0x6d>; + }; + + spdif_tx2: spdif-tx@fddb0000 { + compatible = "rockchip,rk3588-spdif", "rockchip,rk3568-spdif"; + reg = <0x00 0xfddb0000 0x00 0x1000>; + assigned-clock-parents = <0x21 0x04>; + assigned-clocks = <0x21 0x1f4>; + clock-names = "mclk", "hclk"; + clocks = <0x21 0x1f8>, < 0x21 0x1f3>; + dma-names = "tx"; + dmas = <0x73 0x06>; + interrupts = <0x00 0xc3 0x04 0x00>; + power-domains = <0x22 0x19>; + #sound-dai-cells = <0x00>; + status = "disabled"; + }; + + i2s4_8ch: i2s@fddc0000 { + compatible = "rockchip,rk3588-i2s-tdm"; + reg = <0x00 0xfddc0000 0x00 0x1000>; + interrupts = <0x00 0xb8 0x04 0x00>; + clocks = <0x21 0x1ec>, < 0x21 0x1ec>, < 0x21 0x1e1>; + clock-names = "mclk_tx", "mclk_rx", "hclk"; + assigned-clocks = <0x21 0x1ea>; + assigned-clock-parents = <0x21 0x04>; + dmas = <0x74 0x00>; + dma-names = "tx"; + power-domains = <0x22 0x19>; + resets = <0x21 0x1b8>; + reset-names = "tx-m"; + #sound-dai-cells = <0x00>; + status = "disabled"; + }; + + spdif_tx3: spdif-tx@fdde0000 { + compatible = "rockchip,rk3588-spdif", "rockchip,rk3568-spdif"; + reg = <0x00 0xfdde0000 0x00 0x1000>; + assigned-clock-parents = <0x21 0x04>; + assigned-clocks = <0x21 0x241>; + clock-names = "mclk", "hclk"; + clocks = <0x21 0x244>, < 0x21 0x240>; + dma-names = "tx"; + dmas = <0x73 0x07>; + interrupts = <0x00 0xc4 0x04 0x00>; + power-domains = <0x22 0x1a>; + #sound-dai-cells = <0x00>; + status = "disabled"; + }; + + i2s5_8ch: i2s@fddf0000 { + compatible = "rockchip,rk3588-i2s-tdm"; + reg = <0x00 0xfddf0000 0x00 0x1000>; + interrupts = <0x00 0xb9 0x04 0x00>; + clocks = <0x21 0x234>, < 0x21 0x234>, < 0x21 0x235>; + clock-names = "mclk_tx", "mclk_rx", "hclk"; + assigned-clocks = <0x21 0x231>; + assigned-clock-parents = <0x21 0x04>; + dmas = <0x74 0x02>; + dma-names = "tx"; + power-domains = <0x22 0x1a>; + resets = <0x21 0x1d8>; + reset-names = "tx-m"; + #sound-dai-cells = <0x00>; + status = "disabled"; + phandle = <0x1e>; + }; + + i2s9_8ch: i2s@fddfc000 { + compatible = "rockchip,rk3588-i2s-tdm"; + reg = <0x00 0xfddfc000 0x00 0x1000>; + interrupts = <0x00 0xbd 0x04 0x00>; + clocks = <0x21 0x230>, < 0x21 0x230>, < 0x21 0x22c>; + clock-names = "mclk_tx", "mclk_rx", "hclk"; + assigned-clocks = <0x21 0x22d>; + assigned-clock-parents = <0x21 0x04>; + dmas = <0x74 0x17>; + dma-names = "rx"; + power-domains = <0x22 0x1a>; + resets = <0x21 0x1ec>; + reset-names = "rx-m"; + #sound-dai-cells = <0x00>; + status = "disabled"; + }; + + hdmi0: hdmi@fde80000 { + compatible = "rockchip,rk3588-dw-hdmi-qp"; + reg = <0x00 0xfde80000 0x00 0x20000>; + clocks = <0x21 0x210>, < 0x21 0x211>, < 0x21 0x212>, < 0x21 0x234>, < 0x21 0x252>, < 0x21 0x2cd>; + clock-names = "pclk", "earc", "ref", "aud", "hdp", "hclk_vo1"; + interrupts = <0x00 0xa9 0x04 0x00>, <0x00 0xaa 0x04 0x00>, <0x00 0xab 0x04 0x00>, <0x00 0xac 0x04 0x00>, <0x00 0x168 0x04 0x00>; + interrupt-names = "avp", "cec", "earc", "main", "hpd"; + phys = <0x6b>; + pinctrl-names = "default"; + pinctrl-0 = <0x75 0x76 0x77 0x78>; + power-domains = <0x22 0x1a>; + resets = <0x21 0x1ce>, < 0x21 0x230>; + reset-names = "ref", "hdp"; + rockchip,grf = <0x6e>; + rockchip,vo-grf = <0x70>; + #sound-dai-cells = <0x00>; + status = "disabled"; + phandle = <0x1d>; + + ports { + #address-cells = <0x01>; + #size-cells = <0x00>; + + hdmi0_in: port@0 { + reg = <0x00>; + }; + + hdmi0_out: port@1 { + reg = <0x01>; + }; + }; + }; + + qos_gpu_m0: qos@fdf35000 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf35000 0x00 0x20>; + phandle = <0x3c>; + }; + + qos_gpu_m1: qos@fdf35200 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf35200 0x00 0x20>; + phandle = <0x3d>; + }; + + qos_gpu_m2: qos@fdf35400 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf35400 0x00 0x20>; + phandle = <0x3e>; + }; + + qos_gpu_m3: qos@fdf35600 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf35600 0x00 0x20>; + phandle = <0x3f>; + }; + + qos_rga3_1: qos@fdf36000 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf36000 0x00 0x20>; + phandle = <0x5f>; + }; + + qos_sdio: qos@fdf39000 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf39000 0x00 0x20>; + phandle = <0x64>; + }; + + qos_sdmmc: qos@fdf3d800 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf3d800 0x00 0x20>; + phandle = <0x65>; + }; + + qos_usb3_1: qos@fdf3e000 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf3e000 0x00 0x20>; + phandle = <0x61>; + }; + + qos_usb3_0: qos@fdf3e200 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf3e200 0x00 0x20>; + phandle = <0x60>; + }; + + qos_usb2host_0: qos@fdf3e400 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf3e400 0x00 0x20>; + phandle = <0x62>; + }; + + qos_usb2host_1: qos@fdf3e600 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf3e600 0x00 0x20>; + phandle = <0x63>; + }; + + qos_fisheye0: qos@fdf40000 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf40000 0x00 0x20>; + phandle = <0x5d>; + }; + + qos_fisheye1: qos@fdf40200 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf40200 0x00 0x20>; + phandle = <0x5e>; + }; + + qos_isp0_mro: qos@fdf40400 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf40400 0x00 0x20>; + phandle = <0x57>; + }; + + qos_isp0_mwo: qos@fdf40500 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf40500 0x00 0x20>; + phandle = <0x58>; + }; + + qos_vicap_m0: qos@fdf40600 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf40600 0x00 0x20>; + phandle = <0x59>; + }; + + qos_vicap_m1: qos@fdf40800 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf40800 0x00 0x20>; + phandle = <0x5a>; + }; + + qos_isp1_mwo: qos@fdf41000 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf41000 0x00 0x20>; + phandle = <0x5b>; + }; + + qos_isp1_mro: qos@fdf41100 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf41100 0x00 0x20>; + phandle = <0x5c>; + }; + + qos_rkvenc0_m0ro: qos@fdf60000 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf60000 0x00 0x20>; + phandle = <0x42>; + }; + + qos_rkvenc0_m1ro: qos@fdf60200 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf60200 0x00 0x20>; + phandle = <0x43>; + }; + + qos_rkvenc0_m2wo: qos@fdf60400 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf60400 0x00 0x20>; + phandle = <0x44>; + }; + + qos_rkvenc1_m0ro: qos@fdf61000 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf61000 0x00 0x20>; + phandle = <0x45>; + }; + + qos_rkvenc1_m1ro: qos@fdf61200 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf61200 0x00 0x20>; + phandle = <0x46>; + }; + + qos_rkvenc1_m2wo: qos@fdf61400 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf61400 0x00 0x20>; + phandle = <0x47>; + }; + + qos_rkvdec0: qos@fdf62000 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf62000 0x00 0x20>; + phandle = <0x40>; + }; + + qos_rkvdec1: qos@fdf63000 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf63000 0x00 0x20>; + phandle = <0x41>; + }; + + qos_av1: qos@fdf64000 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf64000 0x00 0x20>; + phandle = <0x50>; + }; + + qos_iep: qos@fdf66000 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf66000 0x00 0x20>; + phandle = <0x48>; + }; + + qos_jpeg_dec: qos@fdf66200 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf66200 0x00 0x20>; + phandle = <0x49>; + }; + + qos_jpeg_enc0: qos@fdf66400 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf66400 0x00 0x20>; + phandle = <0x4a>; + }; + + qos_jpeg_enc1: qos@fdf66600 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf66600 0x00 0x20>; + phandle = <0x4b>; + }; + + qos_jpeg_enc2: qos@fdf66800 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf66800 0x00 0x20>; + phandle = <0x4c>; + }; + + qos_jpeg_enc3: qos@fdf66a00 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf66a00 0x00 0x20>; + phandle = <0x4d>; + }; + + qos_rga2_mro: qos@fdf66c00 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf66c00 0x00 0x20>; + phandle = <0x4e>; + }; + + qos_rga2_mwo: qos@fdf66e00 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf66e00 0x00 0x20>; + phandle = <0x4f>; + }; + + qos_rga3_0: qos@fdf67000 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf67000 0x00 0x20>; + phandle = <0x51>; + }; + + qos_vdpu: qos@fdf67200 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf67200 0x00 0x20>; + }; + + qos_npu1: qos@fdf70000 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf70000 0x00 0x20>; + phandle = <0x3a>; + }; + + qos_npu2: qos@fdf71000 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf71000 0x00 0x20>; + phandle = <0x3b>; + }; + + qos_npu0_mwr: qos@fdf72000 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf72000 0x00 0x20>; + phandle = <0x37>; + }; + + qos_npu0_mro: qos@fdf72200 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf72200 0x00 0x20>; + phandle = <0x38>; + }; + + qos_mcu_npu: qos@fdf72400 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf72400 0x00 0x20>; + phandle = <0x39>; + }; + + qos_hdcp0: qos@fdf80000 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf80000 0x00 0x20>; + phandle = <0x54>; + }; + + qos_hdcp1: qos@fdf81000 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf81000 0x00 0x20>; + phandle = <0x55>; + }; + + qos_hdmirx: qos@fdf81200 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf81200 0x00 0x20>; + phandle = <0x56>; + }; + + qos_vop_m0: qos@fdf82000 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf82000 0x00 0x20>; + phandle = <0x52>; + }; + + qos_vop_m1: qos@fdf82200 { + compatible = "rockchip,rk3588-qos", "syscon"; + reg = <0x00 0xfdf82200 0x00 0x20>; + phandle = <0x53>; + }; + + dfi: dfi@fe060000 { + reg = <0x00 0xfe060000 0x00 0x10000>; + compatible = "rockchip,rk3588-dfi"; + interrupts = <0x00 0x1c 0x04 0x00>, <0x00 0x26 0x04 0x00>, <0x00 0x30 0x04 0x00>, <0x00 0x3a 0x04 0x00>; + rockchip,pmu = <0x79>; + }; + + pcie2x1l1: pcie@fe180000 { + compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie"; + bus-range = <0x30 0x3f>; + clocks = <0x21 0x143>, < 0x21 0x148>, < 0x21 0x13e>, < 0x21 0x14d>, < 0x21 0x152>, < 0x21 0x2b0>; + clock-names = "aclk_mst", "aclk_slv", "aclk_dbi", "pclk", "aux", "pipe"; + device_type = "pci"; + interrupts = <0x00 0xf8 0x04 0x00>, <0x00 0xf7 0x04 0x00>, <0x00 0xf6 0x04 0x00>, <0x00 0xf5 0x04 0x00>, <0x00 0xf4 0x04 0x00>; + interrupt-names = "sys", "pmc", "msg", "legacy", "err"; + #interrupt-cells = <0x01>; + interrupt-map-mask = <0x00 0x00 0x00 0x07>; + interrupt-map = <0x00 0x00 0x00 0x01 0x7a 0x00>, <0x00 0x00 0x00 0x02 0x7a 0x01>, <0x00 0x00 0x00 0x03 0x7a 0x02>, <0x00 0x00 0x00 0x04 0x7a 0x03>; + linux,pci-domain = <0x03>; + max-link-speed = <0x02>; + msi-map = <0x3000 0x7b 0x3000 0x1000>; + iommu-map = <0x3000 0x7c 0x3000 0x1000>; + num-lanes = <0x01>; + phys = <0x2b 0x02>; + phy-names = "pcie-phy"; + power-domains = <0x22 0x22>; + ranges = <0x1000000 0x00 0xf3100000 0x00 0xf3100000 0x00 0x100000>, <0x2000000 0x00 0xf3200000 0x00 0xf3200000 0x00 0xe00000>, <0x3000000 0x00 0x40000000 0x09 0xc0000000 0x00 0x40000000>; + reg = <0x0a 0x40c00000 0x00 0x400000>, <0x00 0xfe180000 0x00 0x10000>, <0x00 0xf3000000 0x00 0x100000>; + reg-names = "dbi", "apb", "config"; + resets = <0x21 0x129>, < 0x21 0x12e>; + reset-names = "pwr", "pipe"; + #address-cells = <0x03>; + #size-cells = <0x02>; + status = "okay"; + reset-gpios = <0x7d 0x1c 0x00>; + vpcie3v3-supply = <0x7e>; + + pcie2x1l1_intc: legacy-interrupt-controller { + interrupt-controller; + #address-cells = <0x00>; + #interrupt-cells = <0x01>; + interrupt-parent = <0x01>; + interrupts = <0x00 0xf5 0x01 0x00>; + phandle = <0x7a>; + }; + }; + + pcie2x1l2: pcie@fe190000 { + compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie"; + bus-range = <0x40 0x4f>; + clocks = <0x21 0x144>, < 0x21 0x149>, < 0x21 0x13f>, < 0x21 0x14e>, < 0x21 0x153>, < 0x21 0x173>; + clock-names = "aclk_mst", "aclk_slv", "aclk_dbi", "pclk", "aux", "pipe"; + device_type = "pci"; + interrupts = <0x00 0xfd 0x04 0x00>, <0x00 0xfc 0x04 0x00>, <0x00 0xfb 0x04 0x00>, <0x00 0xfa 0x04 0x00>, <0x00 0xf9 0x04 0x00>; + interrupt-names = "sys", "pmc", "msg", "legacy", "err"; + #interrupt-cells = <0x01>; + interrupt-map-mask = <0x00 0x00 0x00 0x07>; + interrupt-map = <0x00 0x00 0x00 0x01 0x7f 0x00>, <0x00 0x00 0x00 0x02 0x7f 0x01>, <0x00 0x00 0x00 0x03 0x7f 0x02>, <0x00 0x00 0x00 0x04 0x7f 0x03>; + linux,pci-domain = <0x04>; + max-link-speed = <0x02>; + msi-map = <0x4000 0x7b 0x4000 0x1000>; + iommu-map = <0x4000 0x7c 0x4000 0x1000>; + num-lanes = <0x01>; + phys = <0x80 0x02>; + phy-names = "pcie-phy"; + power-domains = <0x22 0x22>; + ranges = <0x1000000 0x00 0xf4100000 0x00 0xf4100000 0x00 0x100000>, <0x2000000 0x00 0xf4200000 0x00 0xf4200000 0x00 0xe00000>, <0x3000000 0x00 0x40000000 0x0a 0x00 0x00 0x40000000>; + reg = <0x0a 0x41000000 0x00 0x400000>, <0x00 0xfe190000 0x00 0x10000>, <0x00 0xf4000000 0x00 0x100000>; + reg-names = "dbi", "apb", "config"; + resets = <0x21 0x12a>, < 0x21 0x12f>; + reset-names = "pwr", "pipe"; + #address-cells = <0x03>; + #size-cells = <0x02>; + status = "disabled"; + + pcie2x1l2_intc: legacy-interrupt-controller { + interrupt-controller; + #address-cells = <0x00>; + #interrupt-cells = <0x01>; + interrupt-parent = <0x01>; + interrupts = <0x00 0xfa 0x01 0x00>; + phandle = <0x7f>; + }; + }; + + gmac1: ethernet@fe1c0000 { + compatible = "rockchip,rk3588-gmac", "snps,dwmac-4.20a"; + reg = <0x00 0xfe1c0000 0x00 0x10000>; + interrupts = <0x00 0xea 0x04 0x00>, <0x00 0xe9 0x04 0x00>; + interrupt-names = "macirq", "eth_wake_irq"; + clocks = <0x21 0x136>, < 0x21 0x137>, < 0x21 0x159>, < 0x21 0x15e>, < 0x21 0x135>; + clock-names = "stmmaceth", "clk_mac_ref", "pclk_mac", "aclk_mac", "ptp_ref"; + power-domains = <0x22 0x21>; + resets = <0x21 0x124>; + reset-names = "stmmaceth"; + rockchip,grf = <0x6e>; + rockchip,php-grf = <0x2e>; + snps,axi-config = <0x81>; + snps,mixed-burst; + snps,mtl-rx-config = <0x82>; + snps,mtl-tx-config = <0x83>; + snps,tso; + status = "disabled"; + + mdio1: mdio { + compatible = "snps,dwmac-mdio"; + #address-cells = <0x01>; + #size-cells = <0x00>; + }; + + gmac1_stmmac_axi_setup: stmmac-axi-config { + snps,blen = <0x00 0x00 0x00 0x00 0x10 0x08 0x04>; + snps,wr_osr_lmt = <0x04>; + snps,rd_osr_lmt = <0x08>; + phandle = <0x81>; + }; + + gmac1_mtl_rx_setup: rx-queues-config { + snps,rx-queues-to-use = <0x02>; + phandle = <0x82>; + + queue0 { + }; + + queue1 { + }; + }; + + gmac1_mtl_tx_setup: tx-queues-config { + snps,tx-queues-to-use = <0x02>; + phandle = <0x83>; + + queue0 { + }; + + queue1 { + }; + }; + }; + + sata0: sata@fe210000 { + compatible = "rockchip,rk3588-dwc-ahci", "snps,dwc-ahci"; + reg = <0x00 0xfe210000 0x00 0x1000>; + interrupts = <0x00 0x111 0x04 0x00>; + clocks = <0x21 0x162>, < 0x21 0x15f>, < 0x21 0x165>, < 0x21 0x154>, < 0x21 0x16f>; + clock-names = "sata", "pmalive", "rxoob", "ref", "asic"; + ports-implemented = <0x01>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + + sata-port@0 { + reg = <0x00>; + hba-port-cap = <0x400000>; + phys = <0x80 0x01>; + phy-names = "sata-phy"; + snps,rx-ts-max = <0x20>; + snps,tx-ts-max = <0x20>; + }; + }; + + sata2: sata@fe230000 { + compatible = "rockchip,rk3588-dwc-ahci", "snps,dwc-ahci"; + reg = <0x00 0xfe230000 0x00 0x1000>; + interrupts = <0x00 0x113 0x04 0x00>; + clocks = <0x21 0x164>, < 0x21 0x161>, < 0x21 0x167>, < 0x21 0x156>, < 0x21 0x171>; + clock-names = "sata", "pmalive", "rxoob", "ref", "asic"; + ports-implemented = <0x01>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + + sata-port@0 { + reg = <0x00>; + hba-port-cap = <0x400000>; + phys = <0x2b 0x01>; + phy-names = "sata-phy"; + snps,rx-ts-max = <0x20>; + snps,tx-ts-max = <0x20>; + }; + }; + + sfc: spi@fe2b0000 { + compatible = "rockchip,sfc"; + reg = <0x00 0xfe2b0000 0x00 0x4000>; + interrupts = <0x00 0xce 0x04 0x00>; + clocks = <0x21 0x12f>, < 0x21 0x130>; + clock-names = "clk_sfc", "hclk_sfc"; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <0x84>; + + spi_flash: flash@0 { + compatible = "jedec,spi-nor"; + reg = <0x00>; + spi-max-frequency = <0x5f5e100>; + spi-rx-bus-width = <0x04>; + spi-tx-bus-width = <0x01>; + }; + }; + + sdmmc: mmc@fe2c0000 { + compatible = "rockchip,rk3588-dw-mshc", "rockchip,rk3288-dw-mshc"; + reg = <0x00 0xfe2c0000 0x00 0x4000>; + interrupts = <0x00 0xcb 0x04 0x00>; + clocks = <0x0a 0x17>, < 0x0a 0x09>, < 0x21 0x2ad>, < 0x21 0x2ae>; + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; + fifo-depth = <0x100>; + max-frequency = <0x8f0d180>; + pinctrl-names = "default"; + pinctrl-0 = <0x85 0x86 0x87 0x88>; + power-domains = <0x22 0x28>; + status = "okay"; + bus-width = <0x04>; + cap-sd-highspeed; + cd-gpios = <0x89 0x04 0x01>; + disable-wp; + no-sdio; + no-mmc; + sd-uhs-sdr104; + vmmc-supply = <0x8a>; + vqmmc-supply = <0x8b>; + }; + + sdio: mmc@fe2d0000 { + compatible = "rockchip,rk3588-dw-mshc", "rockchip,rk3288-dw-mshc"; + reg = <0x00 0xfe2d0000 0x00 0x4000>; + interrupts = <0x00 0xcc 0x04 0x00>; + clocks = <0x21 0x18a>, < 0x21 0x18b>, < 0x21 0x2ab>, < 0x21 0x2ac>; + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; + fifo-depth = <0x100>; + max-frequency = <0xbebc200>; + pinctrl-names = "default"; + pinctrl-0 = <0x8c>; + power-domains = <0x22 0x25>; + status = "disabled"; + }; + + sdhci: mmc@fe2e0000 { + compatible = "rockchip,rk3588-dwcmshc"; + reg = <0x00 0xfe2e0000 0x00 0x10000>; + interrupts = <0x00 0xcd 0x04 0x00>; + assigned-clocks = <0x21 0x12d>, < 0x21 0x12e>, < 0x21 0x12c>; + assigned-clock-rates = <0xbebc200>, <0x16e3600>, <0xbebc200>; + clocks = <0x21 0x12c>, < 0x21 0x12a>, < 0x21 0x12b>, < 0x21 0x12d>, < 0x21 0x12e>; + clock-names = "core", "bus", "axi", "block", "timer"; + max-frequency = <0xbebc200>; + pinctrl-0 = <0x8d>, < 0x8e>, < 0x8f>, < 0x90>, < 0x91>; + pinctrl-names = "default"; + resets = <0x21 0x118>, < 0x21 0x116>, < 0x21 0x117>, < 0x21 0x119>, < 0x21 0x11a>; + reset-names = "core", "bus", "axi", "block", "timer"; + status = "okay"; + bus-width = <0x08>; + no-sdio; + no-sd; + non-removable; + mmc-hs400-1_8v; + mmc-hs400-enhanced-strobe; + }; + + i2s0_8ch: i2s@fe470000 { + compatible = "rockchip,rk3588-i2s-tdm"; + reg = <0x00 0xfe470000 0x00 0x1000>; + interrupts = <0x00 0xb4 0x04 0x00>; + clocks = <0x21 0x2b>, < 0x21 0x2f>, < 0x21 0x28>; + clock-names = "mclk_tx", "mclk_rx", "hclk"; + assigned-clocks = <0x21 0x29>, < 0x21 0x2d>; + assigned-clock-parents = <0x21 0x04>, < 0x21 0x04>; + dmas = <0x31 0x00>, < 0x31 0x01>; + dma-names = "tx", "rx"; + power-domains = <0x22 0x26>; + resets = <0x21 0x2a>, < 0x21 0x2b>; + reset-names = "tx-m", "rx-m"; + rockchip,trcm-sync-tx-only; + pinctrl-names = "default"; + pinctrl-0 = <0x92 0x93 0x94 0x95 0x96>; + #sound-dai-cells = <0x00>; + status = "okay"; + phandle = <0x11d>; + }; + + i2s1_8ch: i2s@fe480000 { + compatible = "rockchip,rk3588-i2s-tdm"; + reg = <0x00 0xfe480000 0x00 0x1000>; + interrupts = <0x00 0xb5 0x04 0x00>; + clocks = <0x21 0x279>, < 0x21 0x27d>, < 0x21 0x275>; + clock-names = "mclk_tx", "mclk_rx", "hclk"; + dmas = <0x31 0x02>, < 0x31 0x03>; + dma-names = "tx", "rx"; + resets = <0x21 0x25e>, < 0x21 0x25f>; + reset-names = "tx-m", "rx-m"; + rockchip,trcm-sync-tx-only; + pinctrl-names = "default"; + pinctrl-0 = <0x97 0x98 0x99 0x9a 0x9b 0x9c 0x9d 0x9e 0x9f 0xa0>; + #sound-dai-cells = <0x00>; + status = "disabled"; + }; + + i2s2_2ch: i2s@fe490000 { + compatible = "rockchip,rk3588-i2s", "rockchip,rk3066-i2s"; + reg = <0x00 0xfe490000 0x00 0x1000>; + interrupts = <0x00 0xb6 0x04 0x00>; + clocks = <0x21 0x1f>, < 0x21 0x1a>; + clock-names = "i2s_clk", "i2s_hclk"; + assigned-clocks = <0x21 0x1c>; + assigned-clock-parents = <0x21 0x04>; + dmas = <0x73 0x00>, < 0x73 0x01>; + dma-names = "tx", "rx"; + power-domains = <0x22 0x26>; + pinctrl-names = "default"; + pinctrl-0 = <0xa1 0xa2 0xa3 0xa4>; + #sound-dai-cells = <0x00>; + status = "okay"; + }; + + i2s3_2ch: i2s@fe4a0000 { + compatible = "rockchip,rk3588-i2s", "rockchip,rk3066-i2s"; + reg = <0x00 0xfe4a0000 0x00 0x1000>; + interrupts = <0x00 0xb7 0x04 0x00>; + clocks = <0x21 0x25>, < 0x21 0x1b>; + clock-names = "i2s_clk", "i2s_hclk"; + assigned-clocks = <0x21 0x22>; + assigned-clock-parents = <0x21 0x04>; + dmas = <0x73 0x02>, < 0x73 0x03>; + dma-names = "tx", "rx"; + power-domains = <0x22 0x26>; + pinctrl-names = "default"; + pinctrl-0 = <0xa5 0xa6 0xa7 0xa8>; + #sound-dai-cells = <0x00>; + status = "disabled"; + }; + + spdif_tx0: spdif-tx@fe4e0000 { + compatible = "rockchip,rk3588-spdif", "rockchip,rk3568-spdif"; + reg = <0x00 0xfe4e0000 0x00 0x1000>; + assigned-clock-parents = <0x21 0x04>; + assigned-clocks = <0x21 0x37>; + clock-names = "mclk", "hclk"; + clocks = <0x21 0x39>, < 0x21 0x36>; + dma-names = "tx"; + dmas = <0x31 0x05>; + interrupts = <0x00 0xc1 0x04 0x00>; + pinctrl-0 = <0xa9>; + pinctrl-names = "default"; + power-domains = <0x22 0x26>; + #sound-dai-cells = <0x00>; + status = "disabled"; + }; + + spdif_tx1: spdif-tx@fe4f0000 { + compatible = "rockchip,rk3588-spdif", "rockchip,rk3568-spdif"; + reg = <0x00 0xfe4f0000 0x00 0x1000>; + assigned-clock-parents = <0x21 0x04>; + assigned-clocks = <0x21 0x3d>; + clock-names = "mclk", "hclk"; + clocks = <0x21 0x3f>, < 0x21 0x3c>; + dma-names = "tx"; + dmas = <0x73 0x05>; + interrupts = <0x00 0xc2 0x04 0x00>; + pinctrl-0 = <0xaa>; + pinctrl-names = "default"; + power-domains = <0x22 0x26>; + #sound-dai-cells = <0x00>; + status = "disabled"; + }; + + gic: interrupt-controller@fe600000 { + compatible = "arm,gic-v3"; + reg = <0x00 0xfe600000 0x00 0x10000>, <0x00 0xfe680000 0x00 0x100000>; + interrupts = <0x01 0x09 0x04 0x00>; + interrupt-controller; + dma-noncoherent; + mbi-alias = <0x00 0xfe610000>; + mbi-ranges = <0x1a8 0x38>; + msi-controller; + ranges; + #address-cells = <0x02>; + #interrupt-cells = <0x04>; + #size-cells = <0x02>; + phandle = <0x01>; + + its0: msi-controller@fe640000 { + compatible = "arm,gic-v3-its"; + reg = <0x00 0xfe640000 0x00 0x20000>; + dma-noncoherent; + msi-controller; + #msi-cells = <0x01>; + phandle = <0x7b>; + }; + + its1: msi-controller@fe660000 { + compatible = "arm,gic-v3-its"; + reg = <0x00 0xfe660000 0x00 0x20000>; + dma-noncoherent; + msi-controller; + #msi-cells = <0x01>; + phandle = <0x106>; + }; + + ppi-partitions { + + ppi_partition0: interrupt-partition-0 { + affinity = <0x02 0x03 0x04 0x05>; + phandle = <0x1f>; + }; + + ppi_partition1: interrupt-partition-1 { + affinity = <0x06 0x07 0x08 0x09>; + phandle = <0x20>; + }; + }; + }; + + dmac0: dma-controller@fea10000 { + compatible = "arm,pl330", "arm,primecell"; + reg = <0x00 0xfea10000 0x00 0x4000>; + interrupts = <0x00 0x56 0x04 0x00>, <0x00 0x57 0x04 0x00>; + arm,pl330-periph-burst; + clocks = <0x21 0x6e>; + clock-names = "apb_pclk"; + #dma-cells = <0x01>; + phandle = <0x31>; + }; + + dmac1: dma-controller@fea30000 { + compatible = "arm,pl330", "arm,primecell"; + reg = <0x00 0xfea30000 0x00 0x4000>; + interrupts = <0x00 0x58 0x04 0x00>, <0x00 0x59 0x04 0x00>; + arm,pl330-periph-burst; + clocks = <0x21 0x6f>; + clock-names = "apb_pclk"; + #dma-cells = <0x01>; + phandle = <0x73>; + }; + + i2c1: i2c@fea90000 { + compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c"; + reg = <0x00 0xfea90000 0x00 0x1000>; + clocks = <0x21 0x83>, < 0x21 0x7b>; + clock-names = "i2c", "pclk"; + interrupts = <0x00 0x13e 0x04 0x00>; + pinctrl-0 = <0xab>; + pinctrl-names = "default"; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + }; + + i2c2: i2c@feaa0000 { + compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c"; + reg = <0x00 0xfeaa0000 0x00 0x1000>; + clocks = <0x21 0x84>, < 0x21 0x7c>; + clock-names = "i2c", "pclk"; + interrupts = <0x00 0x13f 0x04 0x00>; + pinctrl-0 = <0xac>; + pinctrl-names = "default"; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + }; + + i2c3: i2c@feab0000 { + compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c"; + reg = <0x00 0xfeab0000 0x00 0x1000>; + clocks = <0x21 0x85>, < 0x21 0x7d>; + clock-names = "i2c", "pclk"; + interrupts = <0x00 0x140 0x04 0x00>; + pinctrl-0 = <0xad>; + pinctrl-names = "default"; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + }; + + i2c4: i2c@feac0000 { + compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c"; + reg = <0x00 0xfeac0000 0x00 0x1000>; + clocks = <0x21 0x86>, < 0x21 0x7e>; + clock-names = "i2c", "pclk"; + interrupts = <0x00 0x141 0x04 0x00>; + pinctrl-0 = <0xae>; + pinctrl-names = "default"; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + }; + + i2c5: i2c@fead0000 { + compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c"; + reg = <0x00 0xfead0000 0x00 0x1000>; + clocks = <0x21 0x87>, < 0x21 0x7f>; + clock-names = "i2c", "pclk"; + interrupts = <0x00 0x142 0x04 0x00>; + pinctrl-0 = <0xaf>; + pinctrl-names = "default"; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + }; + + timer0: timer@feae0000 { + compatible = "rockchip,rk3588-timer", "rockchip,rk3288-timer"; + reg = <0x00 0xfeae0000 0x00 0x20>; + interrupts = <0x00 0x121 0x04 0x00>; + clocks = <0x21 0x54>, < 0x21 0x57>; + clock-names = "pclk", "timer"; + }; + + wdt: watchdog@feaf0000 { + compatible = "rockchip,rk3588-wdt", "snps,dw-wdt"; + reg = <0x00 0xfeaf0000 0x00 0x100>; + clocks = <0x21 0x64>, < 0x21 0x63>; + clock-names = "tclk", "pclk"; + interrupts = <0x00 0x13b 0x04 0x00>; + }; + + spi0: spi@feb00000 { + compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi"; + reg = <0x00 0xfeb00000 0x00 0x1000>; + interrupts = <0x00 0x146 0x04 0x00>; + clocks = <0x21 0x97>, < 0x21 0x92>; + clock-names = "spiclk", "apb_pclk"; + dmas = <0x31 0x0e>, < 0x31 0x0f>; + dma-names = "tx", "rx"; + num-cs = <0x02>; + pinctrl-0 = <0xb0 0xb1 0xb2>; + pinctrl-names = "default"; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + }; + + spi1: spi@feb10000 { + compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi"; + reg = <0x00 0xfeb10000 0x00 0x1000>; + interrupts = <0x00 0x147 0x04 0x00>; + clocks = <0x21 0x98>, < 0x21 0x93>; + clock-names = "spiclk", "apb_pclk"; + dmas = <0x31 0x10>, < 0x31 0x11>; + dma-names = "tx", "rx"; + num-cs = <0x02>; + pinctrl-0 = <0xb3 0xb4 0xb5>; + pinctrl-names = "default"; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + }; + + spi2: spi@feb20000 { + compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi"; + reg = <0x00 0xfeb20000 0x00 0x1000>; + interrupts = <0x00 0x148 0x04 0x00>; + clocks = <0x21 0x99>, < 0x21 0x94>; + clock-names = "spiclk", "apb_pclk"; + dmas = <0x73 0x0f>, < 0x73 0x10>; + dma-names = "tx", "rx"; + num-cs = <0x01>; + pinctrl-0 = <0xb6 0xb7>; + pinctrl-names = "default"; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + assigned-clocks = <0x21 0x99>; + assigned-clock-rates = <0xbebc200>; + + pmic@0 { + compatible = "rockchip,rk806"; + reg = <0x00>; + interrupt-parent = <0x89>; + interrupts = <0x07 0x08>; + pinctrl-names = "default"; + pinctrl-0 = <0xb8>, < 0xb9>, < 0xba>, < 0xbb>; + spi-max-frequency = <0xf4240>; + system-power-controller; + vcc1-supply = <0x30>; + vcc2-supply = <0x30>; + vcc3-supply = <0x30>; + vcc4-supply = <0x30>; + vcc5-supply = <0x30>; + vcc6-supply = <0x30>; + vcc7-supply = <0x30>; + vcc8-supply = <0x30>; + vcc9-supply = <0x30>; + vcc10-supply = <0x30>; + vcc11-supply = <0xbc>; + vcc12-supply = <0x30>; + vcc13-supply = <0xbd>; + vcc14-supply = <0xbd>; + vcca-supply = <0x30>; + gpio-controller; + #gpio-cells = <0x02>; + + rk806_dvs1_null: dvs1-null-pins { + pins = "gpio_pwrctrl1"; + function = "pin_fun0"; + phandle = <0xb9>; + }; + + rk806_dvs2_null: dvs2-null-pins { + pins = "gpio_pwrctrl2"; + function = "pin_fun0"; + phandle = <0xba>; + }; + + rk806_dvs3_null: dvs3-null-pins { + pins = "gpio_pwrctrl3"; + function = "pin_fun0"; + phandle = <0xbb>; + }; + + regulators { + + vdd_gpu_s0: dcdc-reg1 { + regulator-name = "vdd_gpu_s0"; + regulator-boot-on; + regulator-enable-ramp-delay = <0x190>; + regulator-min-microvolt = <0x86470>; + regulator-max-microvolt = <0xe7ef0>; + regulator-ramp-delay = <0x30d4>; + phandle = <0x24>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_cpu_lit_s0: dcdc-reg2 { + regulator-name = "vdd_cpu_lit_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x86470>; + regulator-max-microvolt = <0xe7ef0>; + regulator-ramp-delay = <0x30d4>; + phandle = <0x0e>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_log_s0: dcdc-reg3 { + regulator-name = "vdd_log_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xa4cb8>; + regulator-max-microvolt = <0xc96a8>; + regulator-ramp-delay = <0x30d4>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0xb71b0>; + }; + }; + + vdd_vdenc_s0: dcdc-reg4 { + regulator-name = "vdd_vdenc_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x86470>; + regulator-max-microvolt = <0xc96a8>; + regulator-ramp-delay = <0x30d4>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_ddr_s0: dcdc-reg5 { + regulator-name = "vdd_ddr_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xa4cb8>; + regulator-max-microvolt = <0xdbba0>; + regulator-ramp-delay = <0x30d4>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0xcf850>; + }; + }; + + vdd2_ddr_s3: dcdc-reg6 { + regulator-name = "vdd2_ddr_s3"; + regulator-always-on; + regulator-boot-on; + phandle = <0xbd>; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_2v0_pldo_s3: dcdc-reg7 { + regulator-name = "vdd_2v0_pldo_s3"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x1e8480>; + regulator-max-microvolt = <0x1e8480>; + regulator-ramp-delay = <0x30d4>; + phandle = <0xbc>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x1e8480>; + }; + }; + + vcc_3v3_s3: dcdc-reg8 { + regulator-name = "vcc_3v3_s3"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + phandle = <0x8a>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x325aa0>; + }; + }; + + vddq_ddr_s0: dcdc-reg9 { + regulator-name = "vddq_ddr_s0"; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_1v8_s3: dcdc-reg10 { + regulator-name = "vcc_1v8_s3"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1b7740>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x1b7740>; + }; + }; + + avcc_1v8_s0: pldo-reg1 { + regulator-name = "avcc_1v8_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1b7740>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0x1b7740>; + }; + }; + + vcc_1v8_s0: pldo-reg2 { + regulator-name = "vcc_1v8_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1b7740>; + phandle = <0xe1>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0x1b7740>; + }; + }; + + avdd_1v2_s0: pldo-reg3 { + regulator-name = "avdd_1v2_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x124f80>; + regulator-max-microvolt = <0x124f80>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_3v3_s0: pldo-reg4 { + regulator-name = "vcc_3v3_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + regulator-ramp-delay = <0x30d4>; + phandle = <0xe5>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vccio_sd_s0: pldo-reg5 { + regulator-name = "vccio_sd_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x325aa0>; + regulator-ramp-delay = <0x30d4>; + phandle = <0x8b>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + pldo6_s3: pldo-reg6 { + regulator-name = "pldo6_s3"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1b7740>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0x1b7740>; + }; + }; + + vdd_0v75_s3: nldo-reg1 { + regulator-name = "vdd_0v75_s3"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xb71b0>; + regulator-max-microvolt = <0xb71b0>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <0xb71b0>; + }; + }; + + vdd_ddr_pll_s0: nldo-reg2 { + regulator-name = "vdd_ddr_pll_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xcf850>; + regulator-max-microvolt = <0xcf850>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <0xcf850>; + }; + }; + + avdd_0v75_s0: nldo-reg3 { + regulator-name = "avdd_0v75_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xc96a8>; + regulator-max-microvolt = <0xc96a8>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_0v85_s0: nldo-reg4 { + regulator-name = "vdd_0v85_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xcf850>; + regulator-max-microvolt = <0xcf850>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_0v75_s0: nldo-reg5 { + regulator-name = "vdd_0v75_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0xb71b0>; + regulator-max-microvolt = <0xb71b0>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + }; + }; + }; + + spi3: spi@feb30000 { + compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi"; + reg = <0x00 0xfeb30000 0x00 0x1000>; + interrupts = <0x00 0x149 0x04 0x00>; + clocks = <0x21 0x9a>, < 0x21 0x95>; + clock-names = "spiclk", "apb_pclk"; + dmas = <0x73 0x11>, < 0x73 0x12>; + dma-names = "tx", "rx"; + num-cs = <0x02>; + pinctrl-0 = <0xbe 0xbf 0xc0>; + pinctrl-names = "default"; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + }; + + uart1: serial@feb40000 { + compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart"; + reg = <0x00 0xfeb40000 0x00 0x100>; + interrupts = <0x00 0x14c 0x04 0x00>; + clocks = <0x21 0xab>, < 0x21 0x9f>; + clock-names = "baudclk", "apb_pclk"; + dmas = <0x31 0x08>, < 0x31 0x09>; + dma-names = "tx", "rx"; + pinctrl-0 = <0xc1>; + pinctrl-names = "default"; + reg-io-width = <0x04>; + reg-shift = <0x02>; + status = "disabled"; + }; + + uart2: serial@feb50000 { + compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart"; + reg = <0x00 0xfeb50000 0x00 0x100>; + interrupts = <0x00 0x14d 0x04 0x00>; + clocks = <0x21 0xaf>, < 0x21 0xa0>; + clock-names = "baudclk", "apb_pclk"; + dmas = <0x31 0x0a>, < 0x31 0x0b>; + dma-names = "tx", "rx"; + pinctrl-0 = <0xc2>; + pinctrl-names = "default"; + reg-io-width = <0x04>; + reg-shift = <0x02>; + status = "okay"; + }; + + uart3: serial@feb60000 { + compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart"; + reg = <0x00 0xfeb60000 0x00 0x100>; + interrupts = <0x00 0x14e 0x04 0x00>; + clocks = <0x21 0xb3>, < 0x21 0xa1>; + clock-names = "baudclk", "apb_pclk"; + dmas = <0x31 0x0c>, < 0x31 0x0d>; + dma-names = "tx", "rx"; + pinctrl-0 = <0xc3>; + pinctrl-names = "default"; + reg-io-width = <0x04>; + reg-shift = <0x02>; + status = "disabled"; + }; + + uart4: serial@feb70000 { + compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart"; + reg = <0x00 0xfeb70000 0x00 0x100>; + interrupts = <0x00 0x14f 0x04 0x00>; + clocks = <0x21 0xb7>, < 0x21 0xa2>; + clock-names = "baudclk", "apb_pclk"; + dmas = <0x73 0x09>, < 0x73 0x0a>; + dma-names = "tx", "rx"; + pinctrl-0 = <0xc4>; + pinctrl-names = "default"; + reg-io-width = <0x04>; + reg-shift = <0x02>; + status = "disabled"; + }; + + uart5: serial@feb80000 { + compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart"; + reg = <0x00 0xfeb80000 0x00 0x100>; + interrupts = <0x00 0x150 0x04 0x00>; + clocks = <0x21 0xbb>, < 0x21 0xa3>; + clock-names = "baudclk", "apb_pclk"; + dmas = <0x73 0x0b>, < 0x73 0x0c>; + dma-names = "tx", "rx"; + pinctrl-0 = <0xc5>; + pinctrl-names = "default"; + reg-io-width = <0x04>; + reg-shift = <0x02>; + status = "disabled"; + }; + + uart6: serial@feb90000 { + compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart"; + reg = <0x00 0xfeb90000 0x00 0x100>; + interrupts = <0x00 0x151 0x04 0x00>; + clocks = <0x21 0xbf>, < 0x21 0xa4>; + clock-names = "baudclk", "apb_pclk"; + dmas = <0x73 0x0d>, < 0x73 0x0e>; + dma-names = "tx", "rx"; + pinctrl-0 = <0xc6>; + pinctrl-names = "default"; + reg-io-width = <0x04>; + reg-shift = <0x02>; + status = "disabled"; + }; + + uart7: serial@feba0000 { + compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart"; + reg = <0x00 0xfeba0000 0x00 0x100>; + interrupts = <0x00 0x152 0x04 0x00>; + clocks = <0x21 0xc3>, < 0x21 0xa5>; + clock-names = "baudclk", "apb_pclk"; + dmas = <0x74 0x07>, < 0x74 0x08>; + dma-names = "tx", "rx"; + pinctrl-0 = <0xc7>; + pinctrl-names = "default"; + reg-io-width = <0x04>; + reg-shift = <0x02>; + status = "disabled"; + }; + + uart8: serial@febb0000 { + compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart"; + reg = <0x00 0xfebb0000 0x00 0x100>; + interrupts = <0x00 0x153 0x04 0x00>; + clocks = <0x21 0xc7>, < 0x21 0xa6>; + clock-names = "baudclk", "apb_pclk"; + dmas = <0x74 0x09>, < 0x74 0x0a>; + dma-names = "tx", "rx"; + pinctrl-0 = <0xc8>; + pinctrl-names = "default"; + reg-io-width = <0x04>; + reg-shift = <0x02>; + status = "disabled"; + }; + + uart9: serial@febc0000 { + compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart"; + reg = <0x00 0xfebc0000 0x00 0x100>; + interrupts = <0x00 0x154 0x04 0x00>; + clocks = <0x21 0xcb>, < 0x21 0xa7>; + clock-names = "baudclk", "apb_pclk"; + dmas = <0x74 0x0b>, < 0x74 0x0c>; + dma-names = "tx", "rx"; + pinctrl-0 = <0xc9>; + pinctrl-names = "default"; + reg-io-width = <0x04>; + reg-shift = <0x02>; + status = "disabled"; + }; + + pwm4: pwm@febd0000 { + compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm"; + reg = <0x00 0xfebd0000 0x00 0x10>; + clocks = <0x21 0x4c>, < 0x21 0x4b>; + clock-names = "pwm", "pclk"; + pinctrl-0 = <0xca>; + pinctrl-names = "default"; + #pwm-cells = <0x03>; + status = "okay"; + phandle = <0x117>; + }; + + pwm5: pwm@febd0010 { + compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm"; + reg = <0x00 0xfebd0010 0x00 0x10>; + clocks = <0x21 0x4c>, < 0x21 0x4b>; + clock-names = "pwm", "pclk"; + pinctrl-0 = <0xcb>; + pinctrl-names = "default"; + #pwm-cells = <0x03>; + status = "okay"; + phandle = <0x118>; + }; + + pwm6: pwm@febd0020 { + compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm"; + reg = <0x00 0xfebd0020 0x00 0x10>; + clocks = <0x21 0x4c>, < 0x21 0x4b>; + clock-names = "pwm", "pclk"; + pinctrl-0 = <0xcc>; + pinctrl-names = "default"; + #pwm-cells = <0x03>; + status = "disabled"; + }; + + pwm7: pwm@febd0030 { + compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm"; + reg = <0x00 0xfebd0030 0x00 0x10>; + clocks = <0x21 0x4c>, < 0x21 0x4b>; + clock-names = "pwm", "pclk"; + pinctrl-0 = <0xcd>; + pinctrl-names = "default"; + #pwm-cells = <0x03>; + status = "disabled"; + }; + + pwm8: pwm@febe0000 { + compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm"; + reg = <0x00 0xfebe0000 0x00 0x10>; + clocks = <0x21 0x4f>, < 0x21 0x4e>; + clock-names = "pwm", "pclk"; + pinctrl-0 = <0xce>; + pinctrl-names = "default"; + #pwm-cells = <0x03>; + status = "disabled"; + }; + + pwm9: pwm@febe0010 { + compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm"; + reg = <0x00 0xfebe0010 0x00 0x10>; + clocks = <0x21 0x4f>, < 0x21 0x4e>; + clock-names = "pwm", "pclk"; + pinctrl-0 = <0xcf>; + pinctrl-names = "default"; + #pwm-cells = <0x03>; + status = "okay"; + phandle = <0x116>; + }; + + pwm10: pwm@febe0020 { + compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm"; + reg = <0x00 0xfebe0020 0x00 0x10>; + clocks = <0x21 0x4f>, < 0x21 0x4e>; + clock-names = "pwm", "pclk"; + pinctrl-0 = <0xd0>; + pinctrl-names = "default"; + #pwm-cells = <0x03>; + status = "disabled"; + }; + + pwm11: pwm@febe0030 { + compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm"; + reg = <0x00 0xfebe0030 0x00 0x10>; + clocks = <0x21 0x4f>, < 0x21 0x4e>; + clock-names = "pwm", "pclk"; + pinctrl-0 = <0xd1>; + pinctrl-names = "default"; + #pwm-cells = <0x03>; + status = "disabled"; + }; + + pwm12: pwm@febf0000 { + compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm"; + reg = <0x00 0xfebf0000 0x00 0x10>; + clocks = <0x21 0x52>, < 0x21 0x51>; + clock-names = "pwm", "pclk"; + pinctrl-0 = <0xd2>; + pinctrl-names = "default"; + #pwm-cells = <0x03>; + status = "disabled"; + }; + + pwm13: pwm@febf0010 { + compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm"; + reg = <0x00 0xfebf0010 0x00 0x10>; + clocks = <0x21 0x52>, < 0x21 0x51>; + clock-names = "pwm", "pclk"; + pinctrl-0 = <0xd3>; + pinctrl-names = "default"; + #pwm-cells = <0x03>; + status = "disabled"; + }; + + pwm14: pwm@febf0020 { + compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm"; + reg = <0x00 0xfebf0020 0x00 0x10>; + clocks = <0x21 0x52>, < 0x21 0x51>; + clock-names = "pwm", "pclk"; + pinctrl-0 = <0xd4>; + pinctrl-names = "default"; + #pwm-cells = <0x03>; + status = "disabled"; + }; + + pwm15: pwm@febf0030 { + compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm"; + reg = <0x00 0xfebf0030 0x00 0x10>; + clocks = <0x21 0x52>, < 0x21 0x51>; + clock-names = "pwm", "pclk"; + pinctrl-0 = <0xd5>; + pinctrl-names = "default"; + #pwm-cells = <0x03>; + status = "disabled"; + }; + + thermal_zones: thermal-zones { + + package_thermal: package-thermal { + polling-delay-passive = <0x00>; + polling-delay = <0x3e8>; + thermal-sensors = <0xd6 0x00>; + + trips { + + package_crit: package-crit { + temperature = <0x1c138>; + hysteresis = <0x00>; + type = "critical"; + }; + + package_fan0: package-fan0 { + temperature = <0xd6d8>; + hysteresis = <0x7d0>; + type = "active"; + phandle = <0xd7>; + }; + + package_fan1: package-fan1 { + temperature = <0xfde8>; + hysteresis = <0x7d0>; + type = "active"; + phandle = <0xd9>; + }; + }; + + cooling-maps { + + map0 { + trip = <0xd7>; + cooling-device = <0xd8 0xffffffff 0x01>; + }; + + map1 { + trip = <0xd9>; + cooling-device = <0xd8 0x02 0xffffffff>; + }; + }; + }; + + bigcore0_thermal: bigcore0-thermal { + polling-delay-passive = <0x64>; + polling-delay = <0x00>; + thermal-sensors = <0xd6 0x01>; + + trips { + + bigcore0_alert: bigcore0-alert { + temperature = <0x14c08>; + hysteresis = <0x7d0>; + type = "passive"; + phandle = <0xda>; + }; + + bigcore0_crit: bigcore0-crit { + temperature = <0x1c138>; + hysteresis = <0x00>; + type = "critical"; + }; + }; + + cooling-maps { + + map0 { + trip = <0xda>; + cooling-device = <0x06 0xffffffff 0xffffffff>, < 0x07 0xffffffff 0xffffffff>; + }; + }; + }; + + bigcore2_thermal: bigcore2-thermal { + polling-delay-passive = <0x64>; + polling-delay = <0x00>; + thermal-sensors = <0xd6 0x02>; + + trips { + + bigcore2_alert: bigcore2-alert { + temperature = <0x14c08>; + hysteresis = <0x7d0>; + type = "passive"; + phandle = <0xdb>; + }; + + bigcore2_crit: bigcore2-crit { + temperature = <0x1c138>; + hysteresis = <0x00>; + type = "critical"; + }; + }; + + cooling-maps { + + map0 { + trip = <0xdb>; + cooling-device = <0x08 0xffffffff 0xffffffff>, < 0x09 0xffffffff 0xffffffff>; + }; + }; + }; + + little_core_thermal: littlecore-thermal { + polling-delay-passive = <0x64>; + polling-delay = <0x00>; + thermal-sensors = <0xd6 0x03>; + + trips { + + littlecore_alert: littlecore-alert { + temperature = <0x14c08>; + hysteresis = <0x7d0>; + type = "passive"; + phandle = <0xdc>; + }; + + littlecore_crit: littlecore-crit { + temperature = <0x1c138>; + hysteresis = <0x00>; + type = "critical"; + }; + }; + + cooling-maps { + + map0 { + trip = <0xdc>; + cooling-device = <0x02 0xffffffff 0xffffffff>, < 0x03 0xffffffff 0xffffffff>, < 0x04 0xffffffff 0xffffffff>, < 0x05 0xffffffff 0xffffffff>; + }; + }; + }; + + center_thermal: center-thermal { + polling-delay-passive = <0x00>; + polling-delay = <0x00>; + thermal-sensors = <0xd6 0x04>; + + trips { + + center_crit: center-crit { + temperature = <0x1c138>; + hysteresis = <0x00>; + type = "critical"; + }; + }; + }; + + gpu_thermal: gpu-thermal { + polling-delay-passive = <0x64>; + polling-delay = <0x00>; + thermal-sensors = <0xd6 0x05>; + + trips { + + gpu_alert: gpu-alert { + temperature = <0x14c08>; + hysteresis = <0x7d0>; + type = "passive"; + phandle = <0xdd>; + }; + + gpu_crit: gpu-crit { + temperature = <0x1c138>; + hysteresis = <0x00>; + type = "critical"; + }; + }; + + cooling-maps { + + map0 { + trip = <0xdd>; + cooling-device = <0xde 0xffffffff 0xffffffff>; + }; + }; + }; + + npu_thermal: npu-thermal { + polling-delay-passive = <0x00>; + polling-delay = <0x00>; + thermal-sensors = <0xd6 0x06>; + + trips { + + npu_crit: npu-crit { + temperature = <0x1c138>; + hysteresis = <0x00>; + type = "critical"; + }; + }; + }; + }; + + tsadc: tsadc@fec00000 { + compatible = "rockchip,rk3588-tsadc"; + reg = <0x00 0xfec00000 0x00 0x400>; + interrupts = <0x00 0x18d 0x04 0x00>; + clocks = <0x21 0x9e>, < 0x21 0x9d>; + clock-names = "tsadc", "apb_pclk"; + assigned-clocks = <0x21 0x9e>; + assigned-clock-rates = <0x1e8480>; + resets = <0x21 0x56>, < 0x21 0x57>; + reset-names = "tsadc-apb", "tsadc"; + rockchip,hw-tshut-temp = <0x1d4c0>; + rockchip,hw-tshut-mode = <0x00>; + rockchip,hw-tshut-polarity = <0x00>; + pinctrl-0 = <0xdf>; + pinctrl-1 = <0xe0>; + pinctrl-names = "gpio", "otpout"; + #thermal-sensor-cells = <0x01>; + status = "okay"; + phandle = <0xd6>; + }; + + saradc: adc@fec10000 { + compatible = "rockchip,rk3588-saradc"; + reg = <0x00 0xfec10000 0x00 0x10000>; + interrupts = <0x00 0x18e 0x04 0x00>; + #io-channel-cells = <0x01>; + clocks = <0x21 0x91>, < 0x21 0x90>; + clock-names = "saradc", "apb_pclk"; + resets = <0x21 0x55>; + reset-names = "saradc-apb"; + status = "okay"; + vref-supply = <0xe1>; + phandle = <0x115>; + }; + + i2c6: i2c@fec80000 { + compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c"; + reg = <0x00 0xfec80000 0x00 0x1000>; + clocks = <0x21 0x88>, < 0x21 0x80>; + clock-names = "i2c", "pclk"; + interrupts = <0x00 0x143 0x04 0x00>; + pinctrl-0 = <0xe2>; + pinctrl-names = "default"; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + clock-frequency = <0x61a80>; + + hym8563: rtc@51 { + compatible = "haoyu,hym8563"; + reg = <0x51>; + #clock-cells = <0x00>; + clock-output-names = "hym8563"; + wakeup-source; + interrupt-parent = <0x89>; + interrupts = <0x14 0x08>; + pinctrl-names = "default"; + pinctrl-0 = <0xe3>; + }; + }; + + i2c7: i2c@fec90000 { + compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c"; + reg = <0x00 0xfec90000 0x00 0x1000>; + clocks = <0x21 0x89>, < 0x21 0x81>; + clock-names = "i2c", "pclk"; + interrupts = <0x00 0x144 0x04 0x00>; + pinctrl-0 = <0xe4>; + pinctrl-names = "default"; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + + es8388: audio-codec@11 { + compatible = "everest,es8388"; + reg = <0x11>; + clocks = <0x21 0x31>; + AVDD-supply = <0xe5>; + DVDD-supply = <0xe1>; + HPVDD-supply = <0xe5>; + PVDD-supply = <0xe1>; + assigned-clocks = <0x21 0x31>; + assigned-clock-rates = <0xbb8000>; + #sound-dai-cells = <0x00>; + phandle = <0x11e>; + }; + }; + + i2c8: i2c@feca0000 { + compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c"; + reg = <0x00 0xfeca0000 0x00 0x1000>; + clocks = <0x21 0x8a>, < 0x21 0x82>; + clock-names = "i2c", "pclk"; + interrupts = <0x00 0x145 0x04 0x00>; + pinctrl-0 = <0xe6>; + pinctrl-names = "default"; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + }; + + spi4: spi@fecb0000 { + compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi"; + reg = <0x00 0xfecb0000 0x00 0x1000>; + interrupts = <0x00 0x14a 0x04 0x00>; + clocks = <0x21 0x9b>, < 0x21 0x96>; + clock-names = "spiclk", "apb_pclk"; + dmas = <0x74 0x0d>, < 0x74 0x0e>; + dma-names = "tx", "rx"; + num-cs = <0x02>; + pinctrl-0 = <0xe7 0xe8 0xe9>; + pinctrl-names = "default"; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + }; + + otp: efuse@fecc0000 { + compatible = "rockchip,rk3588-otp"; + reg = <0x00 0xfecc0000 0x00 0x400>; + clocks = <0x21 0x8c>, < 0x21 0x8b>, < 0x21 0x8f>, < 0x21 0x8d>; + clock-names = "otp", "apb_pclk", "phy", "arb"; + resets = <0x21 0xa7>, < 0x21 0xa6>, < 0x21 0xa8>; + reset-names = "otp", "apb", "arb"; + #address-cells = <0x01>; + #size-cells = <0x01>; + + cpu_code: cpu-code@2 { + reg = <0x02 0x02>; + }; + + otp_id: id@7 { + reg = <0x07 0x10>; + }; + + cpub0_leakage: cpu-leakage@17 { + reg = <0x17 0x01>; + }; + + cpub1_leakage: cpu-leakage@18 { + reg = <0x18 0x01>; + }; + + cpul_leakage: cpu-leakage@19 { + reg = <0x19 0x01>; + }; + + log_leakage: log-leakage@1a { + reg = <0x1a 0x01>; + }; + + gpu_leakage: gpu-leakage@1b { + reg = <0x1b 0x01>; + }; + + otp_cpu_version: cpu-version@1c { + reg = <0x1c 0x01>; + bits = <0x03 0x03>; + }; + + npu_leakage: npu-leakage@28 { + reg = <0x28 0x01>; + }; + + codec_leakage: codec-leakage@29 { + reg = <0x29 0x01>; + }; + }; + + dmac2: dma-controller@fed10000 { + compatible = "arm,pl330", "arm,primecell"; + reg = <0x00 0xfed10000 0x00 0x4000>; + interrupts = <0x00 0x5a 0x04 0x00>, <0x00 0x5b 0x04 0x00>; + arm,pl330-periph-burst; + clocks = <0x21 0x70>; + clock-names = "apb_pclk"; + #dma-cells = <0x01>; + phandle = <0x74>; + }; + + hdptxphy0: phy@fed60000 { + compatible = "rockchip,rk3588-hdptx-phy"; + reg = <0x00 0xfed60000 0x00 0x2000>; + clocks = <0x21 0x2a0>, < 0x21 0x254>; + clock-names = "ref", "apb"; + #clock-cells = <0x00>; + #phy-cells = <0x00>; + resets = <0x21 0x223>, < 0x21 0x21a>, < 0x21 0x263>, < 0x21 0x264>, < 0x21 0x265>, < 0x21 0x221>, < 0x21 0x222>; + reset-names = "phy", "apb", "init", "cmn", "lane", "ropll", "lcpll"; + rockchip,grf = <0xea>; + status = "disabled"; + phandle = <0x6b>; + }; + + usbdp_phy0: phy@fed80000 { + compatible = "rockchip,rk3588-usbdp-phy"; + reg = <0x00 0xfed80000 0x00 0x10000>; + #phy-cells = <0x01>; + clocks = <0x21 0x2a1>, < 0x21 0x26c>, < 0x21 0x256>, < 0xeb>; + clock-names = "refclk", "immortal", "pclk", "utmi"; + resets = <0x21 0x0b>, < 0x21 0x0c>, < 0x21 0x0d>, < 0x21 0x0e>, < 0x21 0x217>; + reset-names = "init", "cmn", "lane", "pcs_apb", "pma_apb"; + rockchip,u2phy-grf = <0xec>; + rockchip,usb-grf = <0xed>; + rockchip,usbdpphy-grf = <0xee>; + rockchip,vo-grf = <0xef>; + status = "okay"; + phandle = <0x26>; + }; + + combphy0_ps: phy@fee00000 { + compatible = "rockchip,rk3588-naneng-combphy"; + reg = <0x00 0xfee00000 0x00 0x100>; + clocks = <0x21 0x2a8>, < 0x21 0x176>, < 0x21 0x157>; + clock-names = "ref", "apb", "pipe"; + assigned-clocks = <0x21 0x2a8>; + assigned-clock-rates = <0x5f5e100>; + #phy-cells = <0x01>; + resets = <0x21 0x23c>, < 0x21 0x243>; + reset-names = "phy", "apb"; + rockchip,pipe-grf = <0x2e>; + rockchip,pipe-phy-grf = <0xf0>; + status = "disabled"; + phandle = <0x80>; + }; + + combphy2_psu: phy@fee20000 { + compatible = "rockchip,rk3588-naneng-combphy"; + reg = <0x00 0xfee20000 0x00 0x100>; + clocks = <0x21 0x2aa>, < 0x21 0x178>, < 0x21 0x157>; + clock-names = "ref", "apb", "pipe"; + assigned-clocks = <0x21 0x2aa>; + assigned-clock-rates = <0x5f5e100>; + #phy-cells = <0x01>; + resets = <0x21 0x23e>, < 0x21 0x245>; + reset-names = "phy", "apb"; + rockchip,pipe-grf = <0x2e>; + rockchip,pipe-phy-grf = <0xf1>; + status = "okay"; + phandle = <0x2b>; + }; + + system_sram2: sram@ff001000 { + compatible = "mmio-sram"; + reg = <0x00 0xff001000 0x00 0xef000>; + ranges = <0x00 0x00 0xff001000 0xef000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + }; + + pinctrl: pinctrl { + compatible = "rockchip,rk3588-pinctrl"; + ranges; + rockchip,grf = <0xf2>; + #address-cells = <0x02>; + #size-cells = <0x02>; + phandle = <0xf3>; + + gpio0: gpio@fd8a0000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xfd8a0000 0x00 0x100>; + interrupts = <0x00 0x115 0x04 0x00>; + clocks = <0x21 0x271>, < 0x21 0x272>; + gpio-controller; + gpio-ranges = <0xf3 0x00 0x00 0x20>; + interrupt-controller; + #gpio-cells = <0x02>; + #interrupt-cells = <0x02>; + phandle = <0x89>; + }; + + gpio1: gpio@fec20000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xfec20000 0x00 0x100>; + interrupts = <0x00 0x116 0x04 0x00>; + clocks = <0x21 0x73>, < 0x21 0x74>; + gpio-controller; + gpio-ranges = <0xf3 0x00 0x20 0x20>; + interrupt-controller; + #gpio-cells = <0x02>; + #interrupt-cells = <0x02>; + }; + + gpio2: gpio@fec30000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xfec30000 0x00 0x100>; + interrupts = <0x00 0x117 0x04 0x00>; + clocks = <0x21 0x75>, < 0x21 0x76>; + gpio-controller; + gpio-ranges = <0xf3 0x00 0x40 0x20>; + interrupt-controller; + #gpio-cells = <0x02>; + #interrupt-cells = <0x02>; + phandle = <0x11f>; + }; + + gpio3: gpio@fec40000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xfec40000 0x00 0x100>; + interrupts = <0x00 0x118 0x04 0x00>; + clocks = <0x21 0x77>, < 0x21 0x78>; + gpio-controller; + gpio-ranges = <0xf3 0x00 0x60 0x20>; + interrupt-controller; + #gpio-cells = <0x02>; + #interrupt-cells = <0x02>; + phandle = <0x11c>; + }; + + gpio4: gpio@fec50000 { + compatible = "rockchip,gpio-bank"; + reg = <0x00 0xfec50000 0x00 0x100>; + interrupts = <0x00 0x119 0x04 0x00>; + clocks = <0x21 0x79>, < 0x21 0x7a>; + gpio-controller; + gpio-ranges = <0xf3 0x00 0x80 0x20>; + interrupt-controller; + #gpio-cells = <0x02>; + #interrupt-cells = <0x02>; + phandle = <0x7d>; + }; + + pcfg_pull_up: pcfg-pull-up { + bias-pull-up; + phandle = <0xf8>; + }; + + pcfg_pull_down: pcfg-pull-down { + bias-pull-down; + phandle = <0xf6>; + }; + + pcfg_pull_none: pcfg-pull-none { + bias-disable; + phandle = <0xf4>; + }; + + pcfg_pull_none_drv_level_2: pcfg-pull-none-drv-level-2 { + bias-disable; + drive-strength = <0x02>; + phandle = <0xfa>; + }; + + pcfg_pull_up_drv_level_1: pcfg-pull-up-drv-level-1 { + bias-pull-up; + drive-strength = <0x01>; + phandle = <0xf9>; + }; + + pcfg_pull_up_drv_level_2: pcfg-pull-up-drv-level-2 { + bias-pull-up; + drive-strength = <0x02>; + phandle = <0xf5>; + }; + + pcfg_pull_none_smt: pcfg-pull-none-smt { + bias-disable; + input-schmitt-enable; + phandle = <0xf7>; + }; + + auddsm { + }; + + bt1120 { + }; + + can0 { + }; + + can1 { + }; + + can2 { + }; + + cif { + }; + + clk32k { + }; + + cpu { + }; + + ddrphych0 { + }; + + ddrphych1 { + }; + + ddrphych2 { + }; + + ddrphych3 { + }; + + dp0 { + }; + + dp1 { + }; + + emmc { + + emmc_rstnout: emmc-rstnout { + rockchip,pins = <0x02 0x03 0x01 0xf4>; + phandle = <0x8d>; + }; + + emmc_bus8: emmc-bus8 { + rockchip,pins = <0x02 0x18 0x01 0xf5>, <0x02 0x19 0x01 0xf5>, <0x02 0x1a 0x01 0xf5>, <0x02 0x1b 0x01 0xf5>, <0x02 0x1c 0x01 0xf5>, <0x02 0x1d 0x01 0xf5>, <0x02 0x1e 0x01 0xf5>, <0x02 0x1f 0x01 0xf5>; + phandle = <0x8e>; + }; + + emmc_clk: emmc-clk { + rockchip,pins = <0x02 0x01 0x01 0xf5>; + phandle = <0x8f>; + }; + + emmc_cmd: emmc-cmd { + rockchip,pins = <0x02 0x00 0x01 0xf5>; + phandle = <0x90>; + }; + + emmc_data_strobe: emmc-data-strobe { + rockchip,pins = <0x02 0x02 0x01 0xf6>; + phandle = <0x91>; + }; + }; + + eth1 { + }; + + fspi { + + fspim2_pins: fspim2-pins { + rockchip,pins = <0x03 0x05 0x05 0xf5>, <0x03 0x14 0x02 0xf5>, <0x03 0x00 0x05 0xf5>, <0x03 0x01 0x05 0xf5>, <0x03 0x02 0x05 0xf5>, <0x03 0x03 0x05 0xf5>; + phandle = <0x84>; + }; + }; + + gmac1 { + }; + + gpu { + }; + + hdmi { + + hdmim0_tx0_cec: hdmim0-tx0-cec { + rockchip,pins = <0x04 0x11 0x05 0xf4>; + phandle = <0x75>; + }; + + hdmim0_tx0_hpd: hdmim0-tx0-hpd { + rockchip,pins = <0x01 0x05 0x05 0xf4>; + phandle = <0x76>; + }; + + hdmim0_tx0_scl: hdmim0-tx0-scl { + rockchip,pins = <0x04 0x0f 0x05 0xf4>; + phandle = <0x77>; + }; + + hdmim0_tx0_sda: hdmim0-tx0-sda { + rockchip,pins = <0x04 0x10 0x05 0xf4>; + phandle = <0x78>; + }; + + hdmim0_tx1_hpd: hdmim0-tx1-hpd { + rockchip,pins = <0x01 0x06 0x05 0xf4>; + phandle = <0x100>; + }; + + hdmim1_tx1_scl: hdmim1-tx1-scl { + rockchip,pins = <0x03 0x16 0x05 0xf4>; + phandle = <0x101>; + }; + + hdmim1_tx1_sda: hdmim1-tx1-sda { + rockchip,pins = <0x03 0x15 0x05 0xf4>; + phandle = <0x102>; + }; + + hdmim0_tx1_cec: hdmim0-tx1-cec { + rockchip,pins = <0x02 0x14 0x04 0xf4>; + phandle = <0xff>; + }; + }; + + i2c0 { + + i2c0m2_xfer: i2c0m2-xfer { + rockchip,pins = <0x00 0x19 0x03 0xf7>, <0x00 0x1a 0x03 0xf7>; + phandle = <0x2f>; + }; + }; + + i2c1 { + + i2c1m0_xfer: i2c1m0-xfer { + rockchip,pins = <0x00 0x0d 0x09 0xf7>, <0x00 0x0e 0x09 0xf7>; + phandle = <0xab>; + }; + }; + + i2c2 { + + i2c2m0_xfer: i2c2m0-xfer { + rockchip,pins = <0x00 0x0f 0x09 0xf7>, <0x00 0x10 0x09 0xf7>; + phandle = <0xac>; + }; + }; + + i2c3 { + + i2c3m0_xfer: i2c3m0-xfer { + rockchip,pins = <0x01 0x11 0x09 0xf7>, <0x01 0x10 0x09 0xf7>; + phandle = <0xad>; + }; + }; + + i2c4 { + + i2c4m0_xfer: i2c4m0-xfer { + rockchip,pins = <0x03 0x06 0x09 0xf7>, <0x03 0x05 0x09 0xf7>; + phandle = <0xae>; + }; + }; + + i2c5 { + + i2c5m0_xfer: i2c5m0-xfer { + rockchip,pins = <0x03 0x17 0x09 0xf7>, <0x03 0x18 0x09 0xf7>; + phandle = <0xaf>; + }; + }; + + i2c6 { + + i2c6m0_xfer: i2c6m0-xfer { + rockchip,pins = <0x00 0x18 0x09 0xf7>, <0x00 0x17 0x09 0xf7>; + phandle = <0xe2>; + }; + }; + + i2c7 { + + i2c7m0_xfer: i2c7m0-xfer { + rockchip,pins = <0x01 0x18 0x09 0xf7>, <0x01 0x19 0x09 0xf7>; + phandle = <0xe4>; + }; + }; + + i2c8 { + + i2c8m0_xfer: i2c8m0-xfer { + rockchip,pins = <0x04 0x1a 0x09 0xf7>, <0x04 0x1b 0x09 0xf7>; + phandle = <0xe6>; + }; + }; + + i2s0 { + + i2s0_lrck: i2s0-lrck { + rockchip,pins = <0x01 0x15 0x01 0xf4>; + phandle = <0x92>; + }; + + i2s0_mclk: i2s0-mclk { + rockchip,pins = <0x01 0x12 0x01 0xf4>; + phandle = <0x93>; + }; + + i2s0_sclk: i2s0-sclk { + rockchip,pins = <0x01 0x13 0x01 0xf4>; + phandle = <0x94>; + }; + + i2s0_sdi0: i2s0-sdi0 { + rockchip,pins = <0x01 0x1c 0x02 0xf4>; + phandle = <0x95>; + }; + + i2s0_sdo0: i2s0-sdo0 { + rockchip,pins = <0x01 0x17 0x01 0xf4>; + phandle = <0x96>; + }; + }; + + i2s1 { + + i2s1m0_lrck: i2s1m0-lrck { + rockchip,pins = <0x04 0x02 0x03 0xf4>; + phandle = <0x97>; + }; + + i2s1m0_sclk: i2s1m0-sclk { + rockchip,pins = <0x04 0x01 0x03 0xf4>; + phandle = <0x98>; + }; + + i2s1m0_sdi0: i2s1m0-sdi0 { + rockchip,pins = <0x04 0x05 0x03 0xf4>; + phandle = <0x99>; + }; + + i2s1m0_sdi1: i2s1m0-sdi1 { + rockchip,pins = <0x04 0x06 0x03 0xf4>; + phandle = <0x9a>; + }; + + i2s1m0_sdi2: i2s1m0-sdi2 { + rockchip,pins = <0x04 0x07 0x03 0xf4>; + phandle = <0x9b>; + }; + + i2s1m0_sdi3: i2s1m0-sdi3 { + rockchip,pins = <0x04 0x08 0x03 0xf4>; + phandle = <0x9c>; + }; + + i2s1m0_sdo0: i2s1m0-sdo0 { + rockchip,pins = <0x04 0x09 0x03 0xf4>; + phandle = <0x9d>; + }; + + i2s1m0_sdo1: i2s1m0-sdo1 { + rockchip,pins = <0x04 0x0a 0x03 0xf4>; + phandle = <0x9e>; + }; + + i2s1m0_sdo2: i2s1m0-sdo2 { + rockchip,pins = <0x04 0x0b 0x03 0xf4>; + phandle = <0x9f>; + }; + + i2s1m0_sdo3: i2s1m0-sdo3 { + rockchip,pins = <0x04 0x0c 0x03 0xf4>; + phandle = <0xa0>; + }; + }; + + i2s2 { + + i2s2m0_lrck: i2s2m0-lrck { + rockchip,pins = <0x02 0x10 0x02 0xf4>; + phandle = <0xa1>; + }; + + i2s2m0_sclk: i2s2m0-sclk { + rockchip,pins = <0x02 0x0f 0x02 0xf4>; + phandle = <0xa2>; + }; + + i2s2m0_sdi: i2s2m0-sdi { + rockchip,pins = <0x02 0x13 0x02 0xf4>; + phandle = <0xa3>; + }; + + i2s2m0_sdo: i2s2m0-sdo { + rockchip,pins = <0x04 0x13 0x02 0xf4>; + phandle = <0xa4>; + }; + }; + + i2s3 { + + i2s3_lrck: i2s3-lrck { + rockchip,pins = <0x03 0x02 0x03 0xf4>; + phandle = <0xa5>; + }; + + i2s3_sclk: i2s3-sclk { + rockchip,pins = <0x03 0x01 0x03 0xf4>; + phandle = <0xa6>; + }; + + i2s3_sdi: i2s3-sdi { + rockchip,pins = <0x03 0x04 0x03 0xf4>; + phandle = <0xa7>; + }; + + i2s3_sdo: i2s3-sdo { + rockchip,pins = <0x03 0x03 0x03 0xf4>; + phandle = <0xa8>; + }; + }; + + jtag { + }; + + litcpu { + }; + + mcu { + }; + + mipi { + }; + + npu { + }; + + pcie20x1 { + }; + + pcie30phy { + }; + + pcie30x1 { + }; + + pcie30x2 { + }; + + pcie30x4 { + }; + + pdm0 { + }; + + pdm1 { + }; + + pmic { + + pmic_pins: pmic-pins { + rockchip,pins = <0x00 0x07 0x00 0xf8>, <0x00 0x02 0x01 0xf4>, <0x00 0x03 0x01 0xf4>, <0x00 0x11 0x01 0xf4>, <0x00 0x12 0x01 0xf4>, <0x00 0x13 0x01 0xf4>, <0x00 0x1e 0x01 0xf4>; + phandle = <0xb8>; + }; + }; + + pmu { + }; + + pwm0 { + + pwm0m0_pins: pwm0m0-pins { + rockchip,pins = <0x00 0x0f 0x03 0xf4>; + phandle = <0x33>; + }; + }; + + pwm1 { + + pwm1m0_pins: pwm1m0-pins { + rockchip,pins = <0x00 0x10 0x03 0xf4>; + phandle = <0x34>; + }; + }; + + pwm2 { + + pwm2m0_pins: pwm2m0-pins { + rockchip,pins = <0x00 0x14 0x03 0xf4>; + phandle = <0x35>; + }; + }; + + pwm3 { + + pwm3m0_pins: pwm3m0-pins { + rockchip,pins = <0x00 0x1c 0x03 0xf4>; + phandle = <0x36>; + }; + }; + + pwm4 { + + pwm4m0_pins: pwm4m0-pins { + rockchip,pins = <0x00 0x15 0x0b 0xf4>; + phandle = <0xca>; + }; + }; + + pwm5 { + + pwm5m1_pins: pwm5m1-pins { + rockchip,pins = <0x00 0x16 0x0b 0xf4>; + phandle = <0xcb>; + }; + }; + + pwm6 { + + pwm6m0_pins: pwm6m0-pins { + rockchip,pins = <0x00 0x17 0x0b 0xf4>; + phandle = <0xcc>; + }; + }; + + pwm7 { + + pwm7m0_pins: pwm7m0-pins { + rockchip,pins = <0x00 0x18 0x0b 0xf4>; + phandle = <0xcd>; + }; + }; + + pwm8 { + + pwm8m0_pins: pwm8m0-pins { + rockchip,pins = <0x03 0x07 0x0b 0xf4>; + phandle = <0xce>; + }; + }; + + pwm9 { + + pwm9m2_pins: pwm9m2-pins { + rockchip,pins = <0x03 0x19 0x0b 0xf4>; + phandle = <0xcf>; + }; + }; + + pwm10 { + + pwm10m0_pins: pwm10m0-pins { + rockchip,pins = <0x03 0x00 0x0b 0xf4>; + phandle = <0xd0>; + }; + }; + + pwm11 { + + pwm11m0_pins: pwm11m0-pins { + rockchip,pins = <0x03 0x01 0x0b 0xf4>; + phandle = <0xd1>; + }; + }; + + pwm12 { + + pwm12m0_pins: pwm12m0-pins { + rockchip,pins = <0x03 0x0d 0x0b 0xf4>; + phandle = <0xd2>; + }; + }; + + pwm13 { + + pwm13m0_pins: pwm13m0-pins { + rockchip,pins = <0x03 0x0e 0x0b 0xf4>; + phandle = <0xd3>; + }; + }; + + pwm14 { + + pwm14m0_pins: pwm14m0-pins { + rockchip,pins = <0x03 0x12 0x0b 0xf4>; + phandle = <0xd4>; + }; + }; + + pwm15 { + + pwm15m0_pins: pwm15m0-pins { + rockchip,pins = <0x03 0x13 0x0b 0xf4>; + phandle = <0xd5>; + }; + }; + + refclk { + }; + + sata { + }; + + sata0 { + }; + + sata1 { + }; + + sata2 { + }; + + sdio { + + sdiom1_pins: sdiom1-pins { + rockchip,pins = <0x03 0x05 0x02 0xf4>, <0x03 0x04 0x02 0xf8>, <0x03 0x00 0x02 0xf8>, <0x03 0x01 0x02 0xf8>, <0x03 0x02 0x02 0xf8>, <0x03 0x03 0x02 0xf8>; + phandle = <0x8c>; + }; + }; + + sdmmc { + + sdmmc_bus4: sdmmc-bus4 { + rockchip,pins = <0x04 0x18 0x01 0xf5>, <0x04 0x19 0x01 0xf5>, <0x04 0x1a 0x01 0xf5>, <0x04 0x1b 0x01 0xf5>; + phandle = <0x88>; + }; + + sdmmc_clk: sdmmc-clk { + rockchip,pins = <0x04 0x1d 0x01 0xf5>; + phandle = <0x85>; + }; + + sdmmc_cmd: sdmmc-cmd { + rockchip,pins = <0x04 0x1c 0x01 0xf5>; + phandle = <0x86>; + }; + + sdmmc_det: sdmmc-det { + rockchip,pins = <0x00 0x04 0x01 0xf8>; + phandle = <0x87>; + }; + }; + + spdif0 { + + spdif0m0_tx: spdif0m0-tx { + rockchip,pins = <0x01 0x0e 0x03 0xf4>; + phandle = <0xa9>; + }; + }; + + spdif1 { + + spdif1m0_tx: spdif1m0-tx { + rockchip,pins = <0x01 0x0f 0x03 0xf4>; + phandle = <0xaa>; + }; + }; + + spi0 { + + spi0m0_pins: spi0m0-pins { + rockchip,pins = <0x00 0x16 0x08 0xf9>, <0x00 0x17 0x08 0xf9>, <0x00 0x10 0x08 0xf9>; + phandle = <0xb2>; + }; + + spi0m0_cs0: spi0m0-cs0 { + rockchip,pins = <0x00 0x19 0x08 0xf9>; + phandle = <0xb0>; + }; + + spi0m0_cs1: spi0m0-cs1 { + rockchip,pins = <0x00 0x0f 0x08 0xf9>; + phandle = <0xb1>; + }; + }; + + spi1 { + + spi1m1_pins: spi1m1-pins { + rockchip,pins = <0x03 0x11 0x08 0xf9>, <0x03 0x10 0x08 0xf9>, <0x03 0x0f 0x08 0xf9>; + phandle = <0xb5>; + }; + + spi1m1_cs0: spi1m1-cs0 { + rockchip,pins = <0x03 0x12 0x08 0xf9>; + phandle = <0xb3>; + }; + + spi1m1_cs1: spi1m1-cs1 { + rockchip,pins = <0x03 0x13 0x08 0xf9>; + phandle = <0xb4>; + }; + }; + + spi2 { + + spi2m2_pins: spi2m2-pins { + rockchip,pins = <0x00 0x05 0x01 0xf9>, <0x00 0x0b 0x01 0xf9>, <0x00 0x06 0x01 0xf9>; + phandle = <0xb7>; + }; + + spi2m2_cs0: spi2m2-cs0 { + rockchip,pins = <0x00 0x09 0x01 0xf9>; + phandle = <0xb6>; + }; + }; + + spi3 { + + spi3m1_pins: spi3m1-pins { + rockchip,pins = <0x04 0x0f 0x08 0xf9>, <0x04 0x0d 0x08 0xf9>, <0x04 0x0e 0x08 0xf9>; + phandle = <0xc0>; + }; + + spi3m1_cs0: spi3m1-cs0 { + rockchip,pins = <0x04 0x10 0x08 0xf9>; + phandle = <0xbe>; + }; + + spi3m1_cs1: spi3m1-cs1 { + rockchip,pins = <0x04 0x11 0x08 0xf9>; + phandle = <0xbf>; + }; + }; + + spi4 { + + spi4m0_pins: spi4m0-pins { + rockchip,pins = <0x01 0x12 0x08 0xf9>, <0x01 0x10 0x08 0xf9>, <0x01 0x11 0x08 0xf9>; + phandle = <0xe9>; + }; + + spi4m0_cs0: spi4m0-cs0 { + rockchip,pins = <0x01 0x13 0x08 0xf9>; + phandle = <0xe7>; + }; + + spi4m0_cs1: spi4m0-cs1 { + rockchip,pins = <0x01 0x14 0x08 0xf9>; + phandle = <0xe8>; + }; + }; + + tsadc { + + tsadc_shut: tsadc-shut { + rockchip,pins = <0x00 0x01 0x02 0xf4>; + phandle = <0xe0>; + }; + }; + + uart0 { + + uart0m1_xfer: uart0m1-xfer { + rockchip,pins = <0x00 0x08 0x04 0xf8>, <0x00 0x09 0x04 0xf8>; + phandle = <0x32>; + }; + }; + + uart1 { + + uart1m1_xfer: uart1m1-xfer { + rockchip,pins = <0x01 0x0f 0x0a 0xf8>, <0x01 0x0e 0x0a 0xf8>; + phandle = <0xc1>; + }; + }; + + uart2 { + + uart2m0_xfer: uart2m0-xfer { + rockchip,pins = <0x00 0x0e 0x0a 0xf8>, <0x00 0x0d 0x0a 0xf8>; + phandle = <0xc2>; + }; + }; + + uart3 { + + uart3m1_xfer: uart3m1-xfer { + rockchip,pins = <0x03 0x0e 0x0a 0xf8>, <0x03 0x0d 0x0a 0xf8>; + phandle = <0xc3>; + }; + }; + + uart4 { + + uart4m1_xfer: uart4m1-xfer { + rockchip,pins = <0x03 0x18 0x0a 0xf8>, <0x03 0x19 0x0a 0xf8>; + phandle = <0xc4>; + }; + }; + + uart5 { + + uart5m1_xfer: uart5m1-xfer { + rockchip,pins = <0x03 0x15 0x0a 0xf8>, <0x03 0x14 0x0a 0xf8>; + phandle = <0xc5>; + }; + }; + + uart6 { + + uart6m1_xfer: uart6m1-xfer { + rockchip,pins = <0x01 0x00 0x0a 0xf8>, <0x01 0x01 0x0a 0xf8>; + phandle = <0xc6>; + }; + }; + + uart7 { + + uart7m1_xfer: uart7m1-xfer { + rockchip,pins = <0x03 0x11 0x0a 0xf8>, <0x03 0x10 0x0a 0xf8>; + phandle = <0xc7>; + }; + }; + + uart8 { + + uart8m1_xfer: uart8m1-xfer { + rockchip,pins = <0x03 0x03 0x0a 0xf8>, <0x03 0x02 0x0a 0xf8>; + phandle = <0xc8>; + }; + }; + + uart9 { + + uart9m1_xfer: uart9m1-xfer { + rockchip,pins = <0x04 0x0d 0x0a 0xf8>, <0x04 0x0c 0x0a 0xf8>; + phandle = <0xc9>; + }; + }; + + vop { + }; + + bt656 { + }; + + gpio-func { + + tsadc_gpio_func: tsadc-gpio-func { + rockchip,pins = <0x00 0x01 0x00 0xf4>; + phandle = <0xdf>; + }; + }; + + eth0 { + }; + + gmac0 { + }; + + hym8563 { + + rtc_int_l: hym8563-int { + rockchip,pins = <0x00 0x14 0x00 0xf4>; + phandle = <0xe3>; + }; + }; + + sound { + + hp_detect: hp-detect { + rockchip,pins = <0x03 0x1a 0x00 0xf4>; + phandle = <0x11a>; + }; + }; + + usb { + + usb_host_pwren: usb-host-pwren { + rockchip,pins = <0x03 0x1d 0x00 0xf4>; + phandle = <0x120>; + }; + + usb_otg_pwren: usb-otg-pwren { + rockchip,pins = <0x04 0x09 0x00 0xf4>; + phandle = <0x121>; + }; + }; + }; + + hdmi1_sound: hdmi1-sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,mclk-fs = <0x80>; + simple-audio-card,name = "hdmi1"; + status = "okay"; + + simple-audio-card,codec { + sound-dai = <0xfb>; + }; + + simple-audio-card,cpu { + sound-dai = <0xfc>; + }; + }; + + usb_host1_xhci: usb@fc400000 { + compatible = "rockchip,rk3588-dwc3", "snps,dwc3"; + reg = <0x00 0xfc400000 0x00 0x400000>; + interrupts = <0x00 0xdd 0x04 0x00>; + clocks = <0x21 0x197>, < 0x21 0x196>, < 0x21 0x195>; + clock-names = "ref_clk", "suspend_clk", "bus_clk"; + dr_mode = "host"; + phys = <0xfd>, < 0xfe 0x04>; + phy-names = "usb2-phy", "usb3-phy"; + phy_type = "utmi_wide"; + power-domains = <0x22 0x1f>; + resets = <0x21 0x153>; + snps,dis_enblslpm_quirk; + snps,dis-u2-freeclk-exists-quirk; + snps,dis-del-phy-power-chg-quirk; + snps,dis-tx-ipgap-linecheck-quirk; + status = "okay"; + }; + + pcie30_phy_grf: syscon@fd5b8000 { + compatible = "rockchip,rk3588-pcie3-phy-grf", "syscon"; + reg = <0x00 0xfd5b8000 0x00 0x10000>; + phandle = <0x114>; + }; + + pipe_phy1_grf: syscon@fd5c0000 { + compatible = "rockchip,rk3588-pipe-phy-grf", "syscon"; + reg = <0x00 0xfd5c0000 0x00 0x100>; + phandle = <0x113>; + }; + + usbdpphy1_grf: syscon@fd5cc000 { + compatible = "rockchip,rk3588-usbdpphy-grf", "syscon"; + reg = <0x00 0xfd5cc000 0x00 0x4000>; + phandle = <0x112>; + }; + + usb2phy1_grf: syscon@fd5d4000 { + compatible = "rockchip,rk3588-usb2phy-grf", "syscon", "simple-mfd"; + reg = <0x00 0xfd5d4000 0x00 0x4000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + phandle = <0x111>; + + u2phy1: usb2phy@4000 { + compatible = "rockchip,rk3588-usb2phy"; + reg = <0x4000 0x10>; + #clock-cells = <0x00>; + clocks = <0x21 0x2a0>; + clock-names = "phyclk"; + clock-output-names = "usb480m_phy1"; + interrupts = <0x00 0x18a 0x04 0x00>; + resets = <0x21 0x26e>, < 0x21 0x21e>; + reset-names = "phy", "apb"; + status = "okay"; + phandle = <0x110>; + + u2phy1_otg: otg-port { + #phy-cells = <0x00>; + status = "okay"; + phy-supply = <0x2d>; + phandle = <0xfd>; + }; + }; + }; + + hdptxphy1_grf: syscon@fd5e4000 { + compatible = "rockchip,rk3588-hdptxphy-grf", "syscon"; + reg = <0x00 0xfd5e4000 0x00 0x100>; + phandle = <0x10f>; + }; + + spdif_tx5: spdif-tx@fddb8000 { + compatible = "rockchip,rk3588-spdif", "rockchip,rk3568-spdif"; + reg = <0x00 0xfddb8000 0x00 0x1000>; + assigned-clock-parents = <0x21 0x04>; + assigned-clocks = <0x21 0x1fa>; + clock-names = "mclk", "hclk"; + clocks = <0x21 0x1fe>, < 0x21 0x1f9>; + dma-names = "tx"; + dmas = <0x73 0x16>; + interrupts = <0x00 0xc6 0x04 0x00>; + power-domains = <0x22 0x19>; + #sound-dai-cells = <0x00>; + status = "disabled"; + }; + + i2s8_8ch: i2s@fddc8000 { + compatible = "rockchip,rk3588-i2s-tdm"; + reg = <0x00 0xfddc8000 0x00 0x1000>; + interrupts = <0x00 0xbc 0x04 0x00>; + clocks = <0x21 0x1f1>, < 0x21 0x1f1>, < 0x21 0x1ee>; + clock-names = "mclk_tx", "mclk_rx", "hclk"; + assigned-clocks = <0x21 0x1ef>; + assigned-clock-parents = <0x21 0x04>; + dmas = <0x74 0x16>; + dma-names = "tx"; + power-domains = <0x22 0x19>; + resets = <0x21 0x1ba>; + reset-names = "tx-m"; + #sound-dai-cells = <0x00>; + status = "disabled"; + }; + + spdif_tx4: spdif-tx@fdde8000 { + compatible = "rockchip,rk3588-spdif", "rockchip,rk3568-spdif"; + reg = <0x00 0xfdde8000 0x00 0x1000>; + assigned-clock-parents = <0x21 0x04>; + assigned-clocks = <0x21 0x246>; + clock-names = "mclk", "hclk"; + clocks = <0x21 0x249>, < 0x21 0x245>; + dma-names = "tx"; + dmas = <0x73 0x08>; + interrupts = <0x00 0xc5 0x04 0x00>; + power-domains = <0x22 0x1a>; + #sound-dai-cells = <0x00>; + status = "disabled"; + }; + + i2s6_8ch: i2s@fddf4000 { + compatible = "rockchip,rk3588-i2s-tdm"; + reg = <0x00 0xfddf4000 0x00 0x1000>; + interrupts = <0x00 0xba 0x04 0x00>; + clocks = <0x21 0x239>, < 0x21 0x239>, < 0x21 0x23f>; + clock-names = "mclk_tx", "mclk_rx", "hclk"; + assigned-clocks = <0x21 0x236>; + assigned-clock-parents = <0x21 0x04>; + dmas = <0x74 0x04>; + dma-names = "tx"; + power-domains = <0x22 0x1a>; + resets = <0x21 0x1da>; + reset-names = "tx-m"; + #sound-dai-cells = <0x00>; + status = "okay"; + phandle = <0xfc>; + }; + + i2s7_8ch: i2s@fddf8000 { + compatible = "rockchip,rk3588-i2s-tdm"; + reg = <0x00 0xfddf8000 0x00 0x1000>; + interrupts = <0x00 0xbb 0x04 0x00>; + clocks = <0x21 0x22b>, < 0x21 0x22b>, < 0x21 0x227>; + clock-names = "mclk_tx", "mclk_rx", "hclk"; + assigned-clocks = <0x21 0x228>; + assigned-clock-parents = <0x21 0x04>; + dmas = <0x74 0x15>; + dma-names = "rx"; + power-domains = <0x22 0x1a>; + resets = <0x21 0x1c7>; + reset-names = "rx-m"; + #sound-dai-cells = <0x00>; + status = "disabled"; + }; + + i2s10_8ch: i2s@fde00000 { + compatible = "rockchip,rk3588-i2s-tdm"; + reg = <0x00 0xfde00000 0x00 0x1000>; + interrupts = <0x00 0xbe 0x04 0x00>; + clocks = <0x21 0x226>, < 0x21 0x226>, < 0x21 0x222>; + clock-names = "mclk_tx", "mclk_rx", "hclk"; + assigned-clocks = <0x21 0x223>; + assigned-clock-parents = <0x21 0x04>; + dmas = <0x74 0x18>; + dma-names = "rx"; + power-domains = <0x22 0x1a>; + resets = <0x21 0x1ee>; + reset-names = "rx-m"; + #sound-dai-cells = <0x00>; + status = "disabled"; + }; + + hdmi1: hdmi@fdea0000 { + compatible = "rockchip,rk3588-dw-hdmi-qp"; + reg = <0x00 0xfdea0000 0x00 0x20000>; + clocks = <0x21 0x213>, < 0x21 0x214>, < 0x21 0x215>, < 0x21 0x239>, < 0x21 0x253>, < 0x21 0x2cd>; + clock-names = "pclk", "earc", "ref", "aud", "hdp", "hclk_vo1"; + interrupts = <0x00 0xad 0x04 0x00>, <0x00 0xae 0x04 0x00>, <0x00 0xaf 0x04 0x00>, <0x00 0xb0 0x04 0x00>, <0x00 0x169 0x04 0x00>; + interrupt-names = "avp", "cec", "earc", "main", "hpd"; + phys = <0x6c>; + pinctrl-names = "default"; + pinctrl-0 = <0xff 0x100 0x101 0x102>; + power-domains = <0x22 0x1a>; + resets = <0x21 0x1d0>, < 0x21 0x231>; + reset-names = "ref", "hdp"; + rockchip,grf = <0x6e>; + rockchip,vo-grf = <0x70>; + #sound-dai-cells = <0x00>; + status = "okay"; + phandle = <0xfb>; + + ports { + #address-cells = <0x01>; + #size-cells = <0x00>; + + hdmi1_in: port@0 { + reg = <0x00>; + + hdmi1_in_vp0: endpoint { + remote-endpoint = <0x103>; + phandle = <0x72>; + }; + }; + + hdmi1_out: port@1 { + reg = <0x01>; + + hdmi1_out_con: endpoint { + remote-endpoint = <0x104>; + phandle = <0x122>; + }; + }; + }; + }; + + pcie3x4: pcie@fe150000 { + compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie"; + #address-cells = <0x03>; + #size-cells = <0x02>; + bus-range = <0x00 0x0f>; + clocks = <0x21 0x140>, < 0x21 0x145>, < 0x21 0x13b>, < 0x21 0x14a>, < 0x21 0x14f>, < 0x21 0x174>; + clock-names = "aclk_mst", "aclk_slv", "aclk_dbi", "pclk", "aux", "pipe"; + device_type = "pci"; + interrupts = <0x00 0x107 0x04 0x00>, <0x00 0x106 0x04 0x00>, <0x00 0x105 0x04 0x00>, <0x00 0x104 0x04 0x00>, <0x00 0x103 0x04 0x00>; + interrupt-names = "sys", "pmc", "msg", "legacy", "err"; + #interrupt-cells = <0x01>; + interrupt-map-mask = <0x00 0x00 0x00 0x07>; + interrupt-map = <0x00 0x00 0x00 0x01 0x105 0x00>, <0x00 0x00 0x00 0x02 0x105 0x01>, <0x00 0x00 0x00 0x03 0x105 0x02>, <0x00 0x00 0x00 0x04 0x105 0x03>; + linux,pci-domain = <0x00>; + max-link-speed = <0x03>; + msi-map = <0x00 0x106 0x00 0x1000>; + iommu-map = <0x00 0x7c 0x00 0x1000>; + num-lanes = <0x04>; + phys = <0x107>; + phy-names = "pcie-phy"; + power-domains = <0x22 0x22>; + ranges = <0x1000000 0x00 0xf0100000 0x00 0xf0100000 0x00 0x100000>, <0x2000000 0x00 0xf0200000 0x00 0xf0200000 0x00 0xe00000>, <0x3000000 0x00 0x40000000 0x09 0x00 0x00 0x40000000>; + reg = <0x0a 0x40000000 0x00 0x400000>, <0x00 0xfe150000 0x00 0x10000>, <0x00 0xf0000000 0x00 0x100000>; + reg-names = "dbi", "apb", "config"; + resets = <0x21 0x126>, < 0x21 0x12b>; + reset-names = "pwr", "pipe"; + status = "okay"; + reset-gpios = <0x7d 0x0e 0x00>; + vpcie3v3-supply = <0x108>; + + pcie3x4_intc: legacy-interrupt-controller { + interrupt-controller; + #address-cells = <0x00>; + #interrupt-cells = <0x01>; + interrupt-parent = <0x01>; + interrupts = <0x00 0x104 0x01 0x00>; + phandle = <0x105>; + }; + }; + + pcie3x4_ep: pcie-ep@fe150000 { + compatible = "rockchip,rk3588-pcie-ep"; + reg = <0x0a 0x40000000 0x00 0x100000>, <0x0a 0x40100000 0x00 0x100000>, <0x00 0xfe150000 0x00 0x10000>, <0x09 0x00 0x00 0x40000000>, <0x0a 0x40300000 0x00 0x100000>; + reg-names = "dbi", "dbi2", "apb", "addr_space", "atu"; + clocks = <0x21 0x140>, < 0x21 0x145>, < 0x21 0x13b>, < 0x21 0x14a>, < 0x21 0x14f>, < 0x21 0x174>; + clock-names = "aclk_mst", "aclk_slv", "aclk_dbi", "pclk", "aux", "pipe"; + interrupts = <0x00 0x107 0x04 0x00>, <0x00 0x106 0x04 0x00>, <0x00 0x105 0x04 0x00>, <0x00 0x104 0x04 0x00>, <0x00 0x103 0x04 0x00>, <0x00 0x10f 0x04 0x00>, <0x00 0x110 0x04 0x00>, <0x00 0x10d 0x04 0x00>, <0x00 0x10e 0x04 0x00>; + interrupt-names = "sys", "pmc", "msg", "legacy", "err", "dma0", "dma1", "dma2", "dma3"; + max-link-speed = <0x03>; + iommus = <0x7c 0x00>; + num-lanes = <0x04>; + phys = <0x107>; + phy-names = "pcie-phy"; + power-domains = <0x22 0x22>; + resets = <0x21 0x126>, < 0x21 0x12b>; + reset-names = "pwr", "pipe"; + status = "disabled"; + }; + + pcie3x2: pcie@fe160000 { + compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie"; + #address-cells = <0x03>; + #size-cells = <0x02>; + bus-range = <0x10 0x1f>; + clocks = <0x21 0x141>, < 0x21 0x146>, < 0x21 0x13c>, < 0x21 0x14b>, < 0x21 0x150>, < 0x21 0x175>; + clock-names = "aclk_mst", "aclk_slv", "aclk_dbi", "pclk", "aux", "pipe"; + device_type = "pci"; + interrupts = <0x00 0x102 0x04 0x00>, <0x00 0x101 0x04 0x00>, <0x00 0x100 0x04 0x00>, <0x00 0xff 0x04 0x00>, <0x00 0xfe 0x04 0x00>; + interrupt-names = "sys", "pmc", "msg", "legacy", "err"; + #interrupt-cells = <0x01>; + interrupt-map-mask = <0x00 0x00 0x00 0x07>; + interrupt-map = <0x00 0x00 0x00 0x01 0x109 0x00>, <0x00 0x00 0x00 0x02 0x109 0x01>, <0x00 0x00 0x00 0x03 0x109 0x02>, <0x00 0x00 0x00 0x04 0x109 0x03>; + linux,pci-domain = <0x01>; + max-link-speed = <0x03>; + msi-map = <0x1000 0x106 0x1000 0x1000>; + iommu-map = <0x1000 0x7c 0x1000 0x1000>; + num-lanes = <0x02>; + phys = <0x107>; + phy-names = "pcie-phy"; + power-domains = <0x22 0x22>; + ranges = <0x1000000 0x00 0xf1100000 0x00 0xf1100000 0x00 0x100000>, <0x2000000 0x00 0xf1200000 0x00 0xf1200000 0x00 0xe00000>, <0x3000000 0x00 0x40000000 0x09 0x40000000 0x00 0x40000000>; + reg = <0x0a 0x40400000 0x00 0x400000>, <0x00 0xfe160000 0x00 0x10000>, <0x00 0xf1000000 0x00 0x100000>; + reg-names = "dbi", "apb", "config"; + resets = <0x21 0x127>, < 0x21 0x12c>; + reset-names = "pwr", "pipe"; + status = "disabled"; + + pcie3x2_intc: legacy-interrupt-controller { + interrupt-controller; + #address-cells = <0x00>; + #interrupt-cells = <0x01>; + interrupt-parent = <0x01>; + interrupts = <0x00 0xff 0x01 0x00>; + phandle = <0x109>; + }; + }; + + pcie2x1l0: pcie@fe170000 { + compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie"; + bus-range = <0x20 0x2f>; + clocks = <0x21 0x142>, < 0x21 0x147>, < 0x21 0x13d>, < 0x21 0x14c>, < 0x21 0x151>, < 0x21 0x2af>; + clock-names = "aclk_mst", "aclk_slv", "aclk_dbi", "pclk", "aux", "pipe"; + device_type = "pci"; + interrupts = <0x00 0xf3 0x04 0x00>, <0x00 0xf2 0x04 0x00>, <0x00 0xf1 0x04 0x00>, <0x00 0xf0 0x04 0x00>, <0x00 0xef 0x04 0x00>; + interrupt-names = "sys", "pmc", "msg", "legacy", "err"; + #interrupt-cells = <0x01>; + interrupt-map-mask = <0x00 0x00 0x00 0x07>; + interrupt-map = <0x00 0x00 0x00 0x01 0x10a 0x00>, <0x00 0x00 0x00 0x02 0x10a 0x01>, <0x00 0x00 0x00 0x03 0x10a 0x02>, <0x00 0x00 0x00 0x04 0x10a 0x03>; + linux,pci-domain = <0x02>; + max-link-speed = <0x02>; + msi-map = <0x2000 0x7b 0x2000 0x1000>; + iommu-map = <0x2000 0x7c 0x2000 0x1000>; + num-lanes = <0x01>; + phys = <0x10b 0x02>; + phy-names = "pcie-phy"; + power-domains = <0x22 0x22>; + ranges = <0x1000000 0x00 0xf2100000 0x00 0xf2100000 0x00 0x100000>, <0x2000000 0x00 0xf2200000 0x00 0xf2200000 0x00 0xe00000>, <0x3000000 0x00 0x40000000 0x09 0x80000000 0x00 0x40000000>; + reg = <0x0a 0x40800000 0x00 0x400000>, <0x00 0xfe170000 0x00 0x10000>, <0x00 0xf2000000 0x00 0x100000>; + reg-names = "dbi", "apb", "config"; + resets = <0x21 0x128>, < 0x21 0x12d>; + reset-names = "pwr", "pipe"; + #address-cells = <0x03>; + #size-cells = <0x02>; + status = "disabled"; + + pcie2x1l0_intc: legacy-interrupt-controller { + interrupt-controller; + #address-cells = <0x00>; + #interrupt-cells = <0x01>; + interrupt-parent = <0x01>; + interrupts = <0x00 0xf0 0x01 0x00>; + phandle = <0x10a>; + }; + }; + + gmac0: ethernet@fe1b0000 { + compatible = "rockchip,rk3588-gmac", "snps,dwmac-4.20a"; + reg = <0x00 0xfe1b0000 0x00 0x10000>; + interrupts = <0x00 0xe3 0x04 0x00>, <0x00 0xe2 0x04 0x00>; + interrupt-names = "macirq", "eth_wake_irq"; + clocks = <0x21 0x136>, < 0x21 0x137>, < 0x21 0x158>, < 0x21 0x15d>, < 0x21 0x134>; + clock-names = "stmmaceth", "clk_mac_ref", "pclk_mac", "aclk_mac", "ptp_ref"; + power-domains = <0x22 0x21>; + resets = <0x21 0x123>; + reset-names = "stmmaceth"; + rockchip,grf = <0x6e>; + rockchip,php-grf = <0x2e>; + snps,axi-config = <0x10c>; + snps,mixed-burst; + snps,mtl-rx-config = <0x10d>; + snps,mtl-tx-config = <0x10e>; + snps,tso; + status = "disabled"; + + mdio0: mdio { + compatible = "snps,dwmac-mdio"; + #address-cells = <0x01>; + #size-cells = <0x00>; + }; + + gmac0_stmmac_axi_setup: stmmac-axi-config { + snps,blen = <0x00 0x00 0x00 0x00 0x10 0x08 0x04>; + snps,wr_osr_lmt = <0x04>; + snps,rd_osr_lmt = <0x08>; + phandle = <0x10c>; + }; + + gmac0_mtl_rx_setup: rx-queues-config { + snps,rx-queues-to-use = <0x02>; + phandle = <0x10d>; + + queue0 { + }; + + queue1 { + }; + }; + + gmac0_mtl_tx_setup: tx-queues-config { + snps,tx-queues-to-use = <0x02>; + phandle = <0x10e>; + + queue0 { + }; + + queue1 { + }; + }; + }; + + sata1: sata@fe220000 { + compatible = "rockchip,rk3588-dwc-ahci", "snps,dwc-ahci"; + reg = <0x00 0xfe220000 0x00 0x1000>; + interrupts = <0x00 0x112 0x04 0x00>; + clocks = <0x21 0x163>, < 0x21 0x160>, < 0x21 0x166>, < 0x21 0x155>, < 0x21 0x170>; + clock-names = "sata", "pmalive", "rxoob", "ref", "asic"; + ports-implemented = <0x01>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + + sata-port@0 { + reg = <0x00>; + hba-port-cap = <0x400000>; + phys = <0x10b 0x01>; + phy-names = "sata-phy"; + snps,rx-ts-max = <0x20>; + snps,tx-ts-max = <0x20>; + }; + }; + + hdptxphy1: phy@fed70000 { + compatible = "rockchip,rk3588-hdptx-phy"; + reg = <0x00 0xfed70000 0x00 0x2000>; + clocks = <0x21 0x2a0>, < 0x21 0x255>; + clock-names = "ref", "apb"; + #clock-cells = <0x00>; + #phy-cells = <0x00>; + resets = <0x21 0x226>, < 0x21 0x21b>, < 0x21 0x266>, < 0x21 0x267>, < 0x21 0x268>, < 0x21 0x224>, < 0x21 0x225>; + reset-names = "phy", "apb", "init", "cmn", "lane", "ropll", "lcpll"; + rockchip,grf = <0x10f>; + status = "okay"; + phandle = <0x6c>; + }; + + usbdp_phy1: phy@fed90000 { + compatible = "rockchip,rk3588-usbdp-phy"; + reg = <0x00 0xfed90000 0x00 0x10000>; + #phy-cells = <0x01>; + clocks = <0x21 0x2a1>, < 0x21 0x26d>, < 0x21 0x257>, < 0x110>; + clock-names = "refclk", "immortal", "pclk", "utmi"; + resets = <0x21 0x0f>, < 0x21 0x10>, < 0x21 0x11>, < 0x21 0x12>, < 0x21 0x219>; + reset-names = "init", "cmn", "lane", "pcs_apb", "pma_apb"; + rockchip,u2phy-grf = <0x111>; + rockchip,usb-grf = <0xed>; + rockchip,usbdpphy-grf = <0x112>; + rockchip,vo-grf = <0xef>; + status = "okay"; + phandle = <0xfe>; + }; + + combphy1_ps: phy@fee10000 { + compatible = "rockchip,rk3588-naneng-combphy"; + reg = <0x00 0xfee10000 0x00 0x100>; + clocks = <0x21 0x2a9>, < 0x21 0x177>, < 0x21 0x157>; + clock-names = "ref", "apb", "pipe"; + assigned-clocks = <0x21 0x2a9>; + assigned-clock-rates = <0x5f5e100>; + #phy-cells = <0x01>; + resets = <0x21 0x23d>, < 0x21 0x244>; + reset-names = "phy", "apb"; + rockchip,pipe-grf = <0x2e>; + rockchip,pipe-phy-grf = <0x113>; + status = "disabled"; + phandle = <0x10b>; + }; + + pcie30phy: phy@fee80000 { + compatible = "rockchip,rk3588-pcie3-phy"; + reg = <0x00 0xfee80000 0x00 0x20000>; + #phy-cells = <0x00>; + clocks = <0x21 0x179>; + clock-names = "pclk"; + resets = <0x21 0x248>; + reset-names = "phy"; + rockchip,pipe-grf = <0x2e>; + rockchip,phy-grf = <0x114>; + status = "okay"; + phandle = <0x107>; + }; + + cluster0_opp_table: opp-table-cluster0 { + compatible = "operating-points-v2"; + opp-shared; + phandle = <0x0d>; + + opp-1008000000 { + opp-hz = /bits/ 64 <0x3c14dc00>; + opp-microvolt = <0xa4cb8 0xa4cb8 0xe7ef0>; + clock-latency-ns = <0x9c40>; + }; + + opp-1200000000 { + opp-hz = /bits/ 64 <0x47868c00>; + opp-microvolt = <0xadf34 0xadf34 0xe7ef0>; + clock-latency-ns = <0x9c40>; + }; + + opp-1416000000 { + opp-hz = /bits/ 64 <0x54667200>; + opp-microvolt = <0xba284 0xba284 0xe7ef0>; + clock-latency-ns = <0x9c40>; + opp-suspend; + }; + + opp-1608000000 { + opp-hz = /bits/ 64 <0x5fd82200>; + opp-microvolt = <0xcf850 0xcf850 0xe7ef0>; + clock-latency-ns = <0x9c40>; + }; + + opp-1800000000 { + opp-hz = /bits/ 64 <0x6b49d200>; + opp-microvolt = <0xe7ef0 0xe7ef0 0xe7ef0>; + clock-latency-ns = <0x9c40>; + }; + }; + + cluster1_opp_table: opp-table-cluster1 { + compatible = "operating-points-v2"; + opp-shared; + phandle = <0x13>; + + opp-1200000000 { + opp-hz = /bits/ 64 <0x47868c00>; + opp-microvolt = <0xa4cb8 0xa4cb8 0xf4240>; + clock-latency-ns = <0x9c40>; + }; + + opp-1416000000 { + opp-hz = /bits/ 64 <0x54667200>; + opp-microvolt = <0xb1008 0xb1008 0xf4240>; + clock-latency-ns = <0x9c40>; + }; + + opp-1608000000 { + opp-hz = /bits/ 64 <0x5fd82200>; + opp-microvolt = <0xba284 0xba284 0xf4240>; + clock-latency-ns = <0x9c40>; + }; + + opp-1800000000 { + opp-hz = /bits/ 64 <0x6b49d200>; + opp-microvolt = <0xcf850 0xcf850 0xf4240>; + clock-latency-ns = <0x9c40>; + }; + + opp-2016000000 { + opp-hz = /bits/ 64 <0x7829b800>; + opp-microvolt = <0xe1d48 0xe1d48 0xf4240>; + clock-latency-ns = <0x9c40>; + }; + + opp-2208000000 { + opp-hz = /bits/ 64 <0x839b6800>; + opp-microvolt = <0xf116c 0xf116c 0xf4240>; + clock-latency-ns = <0x9c40>; + }; + + opp-2400000000 { + opp-hz = /bits/ 64 <0x8f0d1800>; + opp-microvolt = <0xf4240 0xf4240 0xf4240>; + clock-latency-ns = <0x9c40>; + }; + }; + + cluster2_opp_table: opp-table-cluster2 { + compatible = "operating-points-v2"; + opp-shared; + phandle = <0x17>; + + opp-1200000000 { + opp-hz = /bits/ 64 <0x47868c00>; + opp-microvolt = <0xa4cb8 0xa4cb8 0xf4240>; + clock-latency-ns = <0x9c40>; + }; + + opp-1416000000 { + opp-hz = /bits/ 64 <0x54667200>; + opp-microvolt = <0xb1008 0xb1008 0xf4240>; + clock-latency-ns = <0x9c40>; + }; + + opp-1608000000 { + opp-hz = /bits/ 64 <0x5fd82200>; + opp-microvolt = <0xba284 0xba284 0xf4240>; + clock-latency-ns = <0x9c40>; + }; + + opp-1800000000 { + opp-hz = /bits/ 64 <0x6b49d200>; + opp-microvolt = <0xcf850 0xcf850 0xf4240>; + clock-latency-ns = <0x9c40>; + }; + + opp-2016000000 { + opp-hz = /bits/ 64 <0x7829b800>; + opp-microvolt = <0xe1d48 0xe1d48 0xf4240>; + clock-latency-ns = <0x9c40>; + }; + + opp-2208000000 { + opp-hz = /bits/ 64 <0x839b6800>; + opp-microvolt = <0xf116c 0xf116c 0xf4240>; + clock-latency-ns = <0x9c40>; + }; + + opp-2400000000 { + opp-hz = /bits/ 64 <0x8f0d1800>; + opp-microvolt = <0xf4240 0xf4240 0xf4240>; + clock-latency-ns = <0x9c40>; + }; + }; + + gpu_opp_table: opp-table { + compatible = "operating-points-v2"; + phandle = <0x23>; + + opp-300000000 { + opp-hz = /bits/ 64 <0x11e1a300>; + opp-microvolt = <0xa4cb8 0xa4cb8 0xcf850>; + }; + + opp-400000000 { + opp-hz = /bits/ 64 <0x17d78400>; + opp-microvolt = <0xa4cb8 0xa4cb8 0xcf850>; + }; + + opp-500000000 { + opp-hz = /bits/ 64 <0x1dcd6500>; + opp-microvolt = <0xa4cb8 0xa4cb8 0xcf850>; + }; + + opp-600000000 { + opp-hz = /bits/ 64 <0x23c34600>; + opp-microvolt = <0xa4cb8 0xa4cb8 0xcf850>; + }; + + opp-700000000 { + opp-hz = /bits/ 64 <0x29b92700>; + opp-microvolt = <0xaae60 0xaae60 0xcf850>; + }; + + opp-800000000 { + opp-hz = /bits/ 64 <0x2faf0800>; + opp-microvolt = <0xb71b0 0xb71b0 0xcf850>; + }; + + opp-900000000 { + opp-hz = /bits/ 64 <0x35a4e900>; + opp-microvolt = <0xc3500 0xc3500 0xcf850>; + }; + + opp-1000000000 { + opp-hz = /bits/ 64 <0x3b9aca00>; + opp-microvolt = <0xcf850 0xcf850 0xcf850>; + }; + }; + + chosen { + stdout-path = "serial2:1500000n8"; + }; + + adc-keys-0 { + compatible = "adc-keys"; + io-channels = <0x115 0x00>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <0x1b7740>; + poll-interval = <0x64>; + + button-maskrom { + label = "Mask Rom"; + linux,code = <0x8d>; + press-threshold-microvolt = <0x7d0>; + }; + }; + + recovery_button: adc-keys-1 { + compatible = "adc-keys"; + io-channels = <0x115 0x01>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <0x1b7740>; + poll-interval = <0x64>; + status = "disabled"; + + button-recovery { + label = "Recovery"; + linux,code = <0x168>; + press-threshold-microvolt = <0x7d0>; + }; + }; + + speaker_amp: speaker-audio-amplifier { + compatible = "simple-audio-amplifier"; + sound-name-prefix = "Speaker Amp"; + status = "disabled"; + }; + + headphone_amp: headphones-audio-amplifier { + compatible = "simple-audio-amplifier"; + sound-name-prefix = "Headphones Amp"; + enable-gpios = <0x7d 0x08 0x00>; + phandle = <0x11b>; + }; + + gpio-leds { + compatible = "gpio-leds"; + + led_blue_gpio: led { + color = <0x03>; + function = "indicator"; + function-enumerator = <0x01>; + status = "disabled"; + }; + }; + + fan: pwm-fan { + compatible = "pwm-fan"; + cooling-levels = <0x00 0x46 0x4b 0x50 0x64>; + fan-supply = <0x30>; + #cooling-cells = <0x02>; + pwms = <0x116 0x00 0xc350 0x00>; + phandle = <0xd8>; + }; + + pwm-leds { + compatible = "pwm-leds"; + + led_blue_pwm: led-1 { + color = <0x03>; + function = "status"; + linux,default-trigger = "heartbeat"; + max-brightness = <0xff>; + status = "okay"; + pwms = <0x117 0x00 0x61a8 0x01>; + }; + + led_green_pwm: led-2 { + color = <0x02>; + function = "indicator"; + function-enumerator = <0x02>; + max-brightness = <0xff>; + pwms = <0x118 0x00 0x61a8 0x01>; + }; + }; + + rfkill { + compatible = "rfkill-gpio"; + label = "rfkill-pcie-wlan"; + radio-type = "wlan"; + shutdown-gpios = <0x89 0x14 0x00>; + }; + + analog_sound: sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "Analog"; + simple-audio-card,format = "i2s"; + simple-audio-card,mclk-fs = <0x100>; + simple-audio-card,bitclock-master = <0x119>; + simple-audio-card,frame-master = <0x119>; + pinctrl-names = "default"; + pinctrl-0 = <0x11a>; + simple-audio-card,aux-devs = <0x11b>; + simple-audio-card,hp-det-gpios = <0x11c 0x1a 0x00>; + simple-audio-card,routing = "Headphones", "LOUT1", "Headphones", "ROUT1", "LINPUT1", "Microphone Jack", "RINPUT1", "Microphone Jack", "LINPUT2", "Onboard Microphone", "RINPUT2", "Onboard Microphone"; + simple-audio-card,widgets = "Microphone", "Microphone Jack", "Microphone", "Onboard Microphone", "Headphone", "Headphones"; + + daicpu: simple-audio-card,cpu { + sound-dai = <0x11d>; + system-clock-frequency = <0xbb8000>; + phandle = <0x119>; + }; + + daicodec: simple-audio-card,codec { + sound-dai = <0x11e>; + system-clock-frequency = <0xbb8000>; + }; + }; + + vcc3v3_pcie30: regulator-vcc3v3-pcie30 { + compatible = "regulator-fixed"; + enable-active-high; + gpios = <0x11f 0x0e 0x00>; + regulator-name = "vcc3v3_pcie30"; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + startup-delay-us = <0x1388>; + vin-supply = <0x30>; + phandle = <0x108>; + }; + + vcc3v3_pcie_eth: regulator-vcc3v3-pcie-eth { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_pcie_eth"; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + startup-delay-us = <0xc350>; + vin-supply = <0x8a>; + gpios = <0x89 0x1b 0x01>; + phandle = <0x7e>; + }; + + vcc3v3_wf: regulator-vcc3v3-wf { + compatible = "regulator-fixed"; + enable-active-high; + gpios = <0x11f 0x15 0x00>; + regulator-name = "vcc3v3_wf"; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + startup-delay-us = <0xc350>; + vin-supply = <0x30>; + status = "disabled"; + }; + + vcc5v0_sys: regulator-vcc5v0-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <0x4c4b40>; + regulator-max-microvolt = <0x4c4b40>; + phandle = <0x30>; + }; + + vcc5v0_usb20: regulator-vcc5v0-usb20 { + compatible = "regulator-fixed"; + enable-active-high; + regulator-name = "vcc5v0_usb20"; + regulator-min-microvolt = <0x4c4b40>; + regulator-max-microvolt = <0x4c4b40>; + vin-supply = <0x30>; + gpios = <0x11c 0x1d 0x00>; + pinctrl-names = "default"; + pinctrl-0 = <0x120>; + phandle = <0x2d>; + }; + + vcc5v0_usb30_otg: vcc5v0-usb30-otg-regulator { + compatible = "regulator-fixed"; + enable-active-high; + gpios = <0x7d 0x09 0x00>; + pinctrl-names = "default"; + pinctrl-0 = <0x121>; + regulator-name = "vcc5v0_usb30_otg"; + regulator-min-microvolt = <0x4c4b40>; + regulator-max-microvolt = <0x4c4b40>; + vin-supply = <0x30>; + phandle = <0x2c>; + }; + + hdmi1-con { + compatible = "hdmi-connector"; + type = "a"; + + port { + + hdmi1_con_in: endpoint { + remote-endpoint = <0x122>; + phandle = <0x104>; + }; + }; + }; +}; diff --git a/patch/kernel/integrate-6.15/0000.patching_config.yaml b/patch/kernel/integrate-6.15/0000.patching_config.yaml new file mode 100644 index 000000000000..33217ceceab7 --- /dev/null +++ b/patch/kernel/integrate-6.15/0000.patching_config.yaml @@ -0,0 +1,37 @@ +config: # This is file 'patch/kernel/archive/rockchip64-6.8/0000.patching_config.yaml' + + # Just some info stuff; not used by the patching scripts + name: integrate-6.15 + kind: kernel + type: mainline # or: vendor + branch: linux-6.14.y + last-known-good-tag: v6.14 + maintainers: + - { github: rpardini, name: Ricardo Pardini, email: ricardo@pardini.net, armbian-forum: rpardini } + - { github: paolosabatino, name: Paolo Sabatino, email: paolo.sabatino@gmail.com, armbian-forum: jock } + + # .dts files in these directories will be copied as-is to the build tree; later ones overwrite earlier ones. + # This is meant to provide a way to "add a board DTS" without having to null-patch them in. + dts-directories: + - { source: "dt", target: "arch/arm64/boot/dts/rockchip" } + + # every file in these directories will be copied as-is to the build tree; later ones overwrite earlier ones + # This is meant as a way to have overlays, bare, in a directory, without having to null-patch them in. + # @TODO need a solution to auto-Makefile the overlays as well + overlay-directories: + - { source: "overlay", target: "arch/arm64/boot/dts/rockchip/overlay" } + + # the Makefile in each of these directories will be magically patched to include the dts files copied + # or patched-in; overlay subdir will be included "-y" if it exists. + # No more Makefile patching needed, yay! + auto-patch-dt-makefile: + - { directory: "arch/arm64/boot/dts/rockchip", config-var: "CONFIG_ARCH_ROCKCHIP" } + + # configuration for when applying patches to git / auto-rewriting patches (development cycle helpers) + patches-to-git: + do-not-commit-files: + - "MAINTAINERS" # constant churn, drop them. sorry. + - "Documentation/devicetree/bindings/arm/rockchip.yaml" # constant churn, conflicts on every bump, drop it. sorry. + do-not-commit-regexes: # Python-style regexes + - "^arch/([a-zA-Z0-9]+)/boot/dts/([a-zA-Z0-9]+)/Makefile$" # ignore DT Makefile patches, we've an auto-patcher now + diff --git a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/orangepi-5-ultra-rk3588_defconfig b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/orangepi-5-ultra-rk3588_defconfig new file mode 100644 index 000000000000..539d77558268 --- /dev/null +++ b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/orangepi-5-ultra-rk3588_defconfig @@ -0,0 +1,218 @@ +CONFIG_ARM=y +CONFIG_ARM_CPU_SUSPEND=y +CONFIG_ARCH_ROCKCHIP=y +CONFIG_SPL_GPIO_SUPPORT=y +CONFIG_SPL_LIBCOMMON_SUPPORT=y +CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_SYS_MALLOC_F_LEN=0x80000 +CONFIG_SPL_FIT_GENERATOR="arch/arm/mach-rockchip/make_fit_atf.sh" +CONFIG_ROCKCHIP_RK3588=y +CONFIG_ROCKCHIP_FIT_IMAGE=y +CONFIG_ROCKCHIP_HWID_DTB=y +CONFIG_ROCKCHIP_VENDOR_PARTITION=y +CONFIG_USING_KERNEL_DTB_V2=y +CONFIG_ROCKCHIP_FIT_IMAGE_PACK=y +CONFIG_ROCKCHIP_NEW_IDB=y +CONFIG_LOADER_INI="RK3588MINIALL.ini" +CONFIG_TRUST_INI="RK3588TRUST.ini" +CONFIG_SPL_SERIAL_SUPPORT=y +CONFIG_SPL_DRIVERS_MISC_SUPPORT=y +CONFIG_TARGET_EVB_RK3588=y +CONFIG_SPL_LIBDISK_SUPPORT=y +CONFIG_SPL_SPI_FLASH_SUPPORT=y +CONFIG_SPL_SPI_SUPPORT=y +CONFIG_DEFAULT_DEVICE_TREE="rk3588-orangepi-5-ultra" +CONFIG_DEFAULT_FDT_FILE="rk3588-orangepi-5-ultra" +CONFIG_DEBUG_UART=y +CONFIG_FIT=y +CONFIG_FIT_IMAGE_POST_PROCESS=y +CONFIG_FIT_HW_CRYPTO=y +CONFIG_SPL_LOAD_FIT=y +CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y +CONFIG_SPL_FIT_HW_CRYPTO=y +# CONFIG_SPL_SYS_DCACHE_OFF is not set +CONFIG_BOOTDELAY=3 +CONFIG_SYS_CONSOLE_INFO_QUIET=y +# CONFIG_DISPLAY_CPUINFO is not set +CONFIG_ANDROID_BOOTLOADER=y +CONFIG_ANDROID_AVB=y +CONFIG_ANDROID_BOOT_IMAGE_HASH=y +CONFIG_SPL_BOARD_INIT=y +# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set +# CONFIG_SPL_LEGACY_IMAGE_SUPPORT is not set +CONFIG_SPL_SEPARATE_BSS=y +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION=y +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION=0x1 +CONFIG_SPL_MMC_WRITE=y +CONFIG_SPL_MTD_SUPPORT=y +CONFIG_SPL_ATF=y +CONFIG_FASTBOOT_BUF_ADDR=0xc00800 +CONFIG_FASTBOOT_BUF_SIZE=0x07000000 +CONFIG_FASTBOOT_FLASH=y +CONFIG_FASTBOOT_FLASH_MMC_DEV=0 +CONFIG_CMD_BOOTZ=y +CONFIG_CMD_DTIMG=y +# CONFIG_CMD_ELF is not set +# CONFIG_CMD_IMI is not set +# CONFIG_CMD_IMLS is not set +# CONFIG_CMD_XIMG is not set +# CONFIG_CMD_LZMADEC is not set +# CONFIG_CMD_UNZIP is not set +# CONFIG_CMD_FLASH is not set +# CONFIG_CMD_FPGA is not set +CONFIG_CMD_GPT=y +# CONFIG_CMD_LOADB is not set +# CONFIG_CMD_LOADS is not set +CONFIG_CMD_BOOT_ANDROID=y +CONFIG_CMD_MMC=y +CONFIG_CMD_PCI=y +CONFIG_CMD_SF=y +CONFIG_CMD_SPI=y +CONFIG_CMD_USB=y +CONFIG_CMD_USB_MASS_STORAGE=y +# CONFIG_CMD_ITEST is not set +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_TFTPPUT=y +CONFIG_CMD_TFTP_BOOTM=y +CONFIG_CMD_TFTP_FLASH=y +# CONFIG_CMD_MISC is not set +CONFIG_CMD_MTD_BLK=y +# CONFIG_SPL_DOS_PARTITION is not set +# CONFIG_ISO_PARTITION is not set +CONFIG_EFI_PARTITION_ENTRIES_NUMBERS=64 +CONFIG_SPL_OF_CONTROL=y +CONFIG_SPL_DTB_MINIMUM=y +CONFIG_OF_LIVE=y +CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" +# CONFIG_NET_TFTP_VARS is not set +CONFIG_REGMAP=y +CONFIG_SPL_REGMAP=y +CONFIG_SYSCON=y +CONFIG_SPL_SYSCON=y +# CONFIG_SARADC_ROCKCHIP is not set +CONFIG_SARADC_ROCKCHIP_V2=y +CONFIG_CLK=y +CONFIG_SPL_CLK=y +CONFIG_CLK_SCMI=y +CONFIG_SPL_CLK_SCMI=y +CONFIG_DM_CRYPTO=y +CONFIG_SPL_DM_CRYPTO=y +CONFIG_ROCKCHIP_CRYPTO_V2=y +CONFIG_SPL_ROCKCHIP_CRYPTO_V2=y +CONFIG_DM_RNG=y +CONFIG_RNG_ROCKCHIP=y +CONFIG_SCMI_FIRMWARE=y +CONFIG_SPL_SCMI_FIRMWARE=y +CONFIG_ROCKCHIP_GPIO=y +CONFIG_ROCKCHIP_GPIO_V2=y +CONFIG_SYS_I2C_ROCKCHIP=y +CONFIG_DM_KEY=y +CONFIG_ADC_KEY=y +CONFIG_MISC=y +CONFIG_SPL_MISC=y +CONFIG_MISC_DECOMPRESS=y +CONFIG_SPL_MISC_DECOMPRESS=y +CONFIG_ROCKCHIP_OTP=y +CONFIG_ROCKCHIP_HW_DECOMPRESS=y +CONFIG_SPL_ROCKCHIP_HW_DECOMPRESS=y +CONFIG_SPL_ROCKCHIP_SECURE_OTP=y +CONFIG_MMC_DW=y +CONFIG_MMC_DW_ROCKCHIP=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_SDMA=y +CONFIG_MMC_SDHCI_ROCKCHIP=y +CONFIG_MTD=y +CONFIG_MTD_BLK=y +CONFIG_MTD_DEVICE=y +CONFIG_NAND=y +CONFIG_MTD_SPI_NAND=y +CONFIG_SPI_FLASH=y +CONFIG_SF_DEFAULT_SPEED=80000000 +CONFIG_SPI_FLASH_EON=y +CONFIG_SPI_FLASH_GIGADEVICE=y +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_SPI_FLASH_SST=y +CONFIG_SPI_FLASH_WINBOND=y +CONFIG_SPI_FLASH_XMC=y +CONFIG_SPI_FLASH_XTX=y +CONFIG_SPI_FLASH_MTD=y +CONFIG_DM_ETH=y +CONFIG_DM_ETH_PHY=y +CONFIG_DWC_ETH_QOS=y +CONFIG_GMAC_ROCKCHIP=y +CONFIG_NVME=y +CONFIG_PCI=y +CONFIG_DM_PCI=y +CONFIG_DM_PCI_COMPAT=y +CONFIG_PCIE_DW_ROCKCHIP=y +CONFIG_PHY_ROCKCHIP_INNO_USB2=y +CONFIG_PHY_ROCKCHIP_SAMSUNG_HDPTX=y +CONFIG_PHY_ROCKCHIP_SNPS_PCIE3=y +CONFIG_PINCTRL=y +CONFIG_SPL_PINCTRL=y +CONFIG_DM_PMIC=y +CONFIG_PMIC_SPI_RK8XX=y +CONFIG_REGULATOR_PWM=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_DM_REGULATOR_GPIO=y +CONFIG_REGULATOR_RK860X=y +CONFIG_REGULATOR_RK806=y +CONFIG_PWM_ROCKCHIP=y +CONFIG_RAM=y +CONFIG_SPL_RAM=y +CONFIG_TPL_RAM=y +CONFIG_ROCKCHIP_SDRAM_COMMON=y +CONFIG_ROCKCHIP_TPL_INIT_DRAM_TYPE=0 +CONFIG_DM_RESET=y +CONFIG_SPL_DM_RESET=y +CONFIG_SPL_RESET_ROCKCHIP=y +CONFIG_BAUDRATE=1500000 +CONFIG_DEBUG_UART_BASE=0xFEB50000 +CONFIG_DEBUG_UART_CLOCK=24000000 +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_ROCKCHIP_SPI=y +CONFIG_ROCKCHIP_SFC=y +CONFIG_SYSRESET=y +CONFIG_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_DWC3=y +CONFIG_USB_XHCI_PCI=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_GENERIC=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_GENERIC=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_GADGET=y +CONFIG_USB_DWC3_GENERIC=y +CONFIG_USB_STORAGE=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_MANUFACTURER="Rockchip" +CONFIG_USB_GADGET_VENDOR_NUM=0x2207 +CONFIG_USB_GADGET_PRODUCT_NUM=0x350a +CONFIG_USB_GADGET_DOWNLOAD=y +CONFIG_DM_VIDEO=y +CONFIG_DISPLAY=y +CONFIG_DRM_ROCKCHIP=y +CONFIG_DRM_ROCKCHIP_DW_MIPI_DSI2=y +CONFIG_DRM_ROCKCHIP_ANALOGIX_DP=y +CONFIG_DRM_ROCKCHIP_SAMSUNG_MIPI_DCPHY=y +CONFIG_USE_TINY_PRINTF=y +CONFIG_LIB_RAND=y +CONFIG_SPL_TINY_MEMSET=y +CONFIG_RSA=y +CONFIG_SPL_RSA=y +CONFIG_RSA_N_SIZE=0x200 +CONFIG_RSA_E_SIZE=0x10 +CONFIG_RSA_C_SIZE=0x20 +CONFIG_LZ4=y +CONFIG_ERRNO_STR=y +# CONFIG_EFI_LOADER is not set +CONFIG_AVB_LIBAVB=y +CONFIG_AVB_LIBAVB_AB=y +CONFIG_AVB_LIBAVB_ATX=y +CONFIG_AVB_LIBAVB_USER=y +CONFIG_RK_AVB_LIBAVB_USER=y +CONFIG_OPTEE_ALWAYS_USE_SECURITY_PARTITION=y +CONFIG_SYS_PROMPT="opi# " +CONFIG_MTD_BLK_U_BOOT_OFFS=0x400 +CONFIG_ROCKCHIP_EMMC_IOMUX=y diff --git a/patch/u-boot/legacy/u-boot-radxa-rk35xx/dt/rk3588-orangepi-5-ultra.dts b/patch/u-boot/legacy/u-boot-radxa-rk35xx/dt/rk3588-orangepi-5-ultra.dts new file mode 100644 index 000000000000..53a18e68b560 --- /dev/null +++ b/patch/u-boot/legacy/u-boot-radxa-rk35xx/dt/rk3588-orangepi-5-ultra.dts @@ -0,0 +1,180 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2021 Rockchip Electronics Co., Ltd + * + */ + +/dts-v1/; +#include "rk3588.dtsi" +#include "rk3588-u-boot.dtsi" +#include + +/ { + model = "RK3588 Orange Pi 5 Ultra"; + compatible = "rockchip,rk3588-orangepi-5-ultra", "rockchip,rk3588"; + + adc-keys { + compatible = "adc-keys"; + io-channels = <&saradc 1>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <1800000>; + u-boot,dm-pre-reloc; + status = "okay"; + + volumeup-key { + u-boot,dm-pre-reloc; + linux,code = ; + label = "volume up"; + press-threshold-microvolt = <1750>; + }; + }; + + vcc5v0_sys: vcc5v0-sys { + u-boot,dm-pre-reloc; + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + vcc5v0_host: vcc5v0-host { + u-boot,dm-pre-reloc; + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_host"; + regulator-boot-on; + regulator-always-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + gpio = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>; + vin-supply = <&vcc5v0_sys>; + }; + + vcc3v3_pcie30: vcc3v3-pcie30 { + u-boot,dm-pre-reloc; + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_pcie30"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + enable-active-high; + gpio = <&gpio2 RK_PB6 GPIO_ACTIVE_HIGH>; + regulator-boot-on; + regulator-always-on; + vin-supply = <&vcc5v0_sys>; + }; +}; + +&u2phy0 { + u-boot,dm-pre-reloc; + status = "okay"; +}; + +&u2phy0_otg { + u-boot,dm-pre-reloc; + status = "okay"; +}; + + +&u2phy1 { + u-boot,dm-pre-reloc; + status = "okay"; +}; + +&u2phy1_otg { + u-boot,dm-pre-reloc; + status = "okay"; +}; + +&u2phy2 { + u-boot,dm-pre-reloc; + status = "okay"; +}; + +&u2phy2_host { + u-boot,dm-pre-reloc; + status = "okay"; +}; + +&u2phy3 { + u-boot,dm-pre-reloc; + status = "okay"; +}; + +&u2phy3_host { + u-boot,dm-pre-reloc; + status = "okay"; +}; + +&usb_host0_ehci { + u-boot,dm-pre-reloc; + compatible = "rockchip,rk3588-ehci", "generic-ehci"; + reg = <0x0 0xfc800000 0x0 0x40000>; + interrupts = <0 215 4>; + clocks = <&cru 413>, <&cru 414>, <&u2phy2>; + clock-names = "usbhost", "arbiter", "utmi"; + companion = <&usb_host0_ohci>; + phys = <&u2phy2_host>; + phy-names = "usb2-phy"; + power-domains = <&power 31>; + status = "okay"; +}; + +&usb_host0_ohci { + u-boot,dm-pre-reloc; + compatible = "generic-ohci"; + reg = <0x0 0xfc840000 0x0 0x40000>; + interrupts = <0 216 4>; + clocks = <&cru 413>, <&cru 414>, <&u2phy2>; + clock-names = "usbhost", "arbiter", "utmi"; + phys = <&u2phy2_host>; + phy-names = "usb2-phy"; + power-domains = <&power 31>; + status = "okay"; +}; + +&usb_host1_ehci { + u-boot,dm-pre-reloc; + compatible = "rockchip,rk3588-ehci", "generic-ehci"; + reg = <0x0 0xfc880000 0x0 0x40000>; + interrupts = <0 218 4>; + clocks = <&cru 415>, <&cru 416>, <&u2phy3>; + clock-names = "usbhost", "arbiter", "utmi"; + companion = <&usb_host1_ohci>; + phys = <&u2phy3_host>; + phy-names = "usb2-phy"; + power-domains = <&power 31>; + status = "okay"; +}; + +&usb_host1_ohci { + u-boot,dm-pre-reloc; + compatible = "generic-ohci"; + reg = <0x0 0xfc8c0000 0x0 0x40000>; + interrupts = <0 219 4>; + clocks = <&cru 415>, <&cru 416>, <&u2phy3>; + clock-names = "usbhost", "arbiter", "utmi"; + phys = <&u2phy3_host>; + phy-names = "usb2-phy"; + power-domains = <&power 31>; + status = "okay"; +}; + +&pcie3x4 { + u-boot,dm-pre-reloc; + vpcie3v3-supply = <&vcc3v3_pcie30>; + reset-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>; + status = "okay"; +}; + +&pcie30phy { + u-boot,dm-pre-reloc; + status = "okay"; +}; + +&sfc { + pinctrl-names = "default"; + pinctrl-0 = <&fspim2_pins &fspim2_cs1>; + +}; \ No newline at end of file From f46a3de927d53a116cf4224fc9bf360207a2fc3c Mon Sep 17 00:00:00 2001 From: Werner Date: Fri, 28 Feb 2025 12:17:06 +0100 Subject: [PATCH 26/37] bump uboot to `v2025.01` --- config/boards/orangepi5.conf | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/config/boards/orangepi5.conf b/config/boards/orangepi5.conf index c49518be0ad3..c9f2096bb729 100644 --- a/config/boards/orangepi5.conf +++ b/config/boards/orangepi5.conf @@ -21,6 +21,31 @@ declare -g UEFI_EDK2_BOARD_ID="orangepi-5" # This _only_ used for uefi-edk2-rk35 DDR_BLOB='rk35/rk3588_ddr_lp4_2112MHz_lp5_2736MHz_v1.15.bin' BL31_BLOB='rk35/rk3588_bl31_v1.44.elf' +# Mainline U-Boot for current kernel +function post_family_config_branch_current__orangepi5_use_mainline_uboot() { + display_alert "$BOARD" "Mainline U-Boot overrides for $BOARD - $BRANCH" "info" + + declare -g BOOTCONFIG="orangepi-5-rk3588s_defconfig" # override the default for the board/family + declare -g BOOTDELAY=1 # Wait for UART interrupt to enter UMS/RockUSB mode etc + declare -g BOOTSOURCE="https://github.com/u-boot/u-boot.git" # We ❤️ mainline U-Boot + declare -g BOOTBRANCH="tag:v2025.01" + declare -g BOOTPATCHDIR="v2025.01" + declare -g BOOTDIR="u-boot-${BOARD}" # do not share u-boot directory + declare -g UBOOT_TARGET_MAP="BL31=${RKBIN_DIR}/${BL31_BLOB} ROCKCHIP_TPL=${RKBIN_DIR}/${DDR_BLOB};;u-boot-rockchip.bin u-boot-rockchip-spi.bin" + unset uboot_custom_postprocess write_uboot_platform write_uboot_platform_mtd # disable stuff from rockchip64_common; we're using binman here which does all the work already + + # Just use the binman-provided u-boot-rockchip.bin, which is ready-to-go + function write_uboot_platform() { + dd "if=$1/u-boot-rockchip.bin" "of=$2" bs=32k seek=1 conv=notrunc status=none + } + + function write_uboot_platform_mtd() { + flashcp -v -p "$1/u-boot-rockchip-spi.bin" /dev/mtd0 + } +} + + + declare -g BLUETOOTH_HCIATTACH_PARAMS="-s 115200 /dev/ttyS9 bcm43xx 1500000" # For the bluetooth-hciattach extension enable_extension "bluetooth-hciattach" # Enable the bluetooth-hciattach extension From af79d20f00b07b04341a91fa56511e9c91ca8763 Mon Sep 17 00:00:00 2001 From: Werner Date: Fri, 28 Feb 2025 12:17:45 +0100 Subject: [PATCH 27/37] Unfix BL31 and DDR versions --- config/boards/orangepi5.conf | 4 ---- 1 file changed, 4 deletions(-) diff --git a/config/boards/orangepi5.conf b/config/boards/orangepi5.conf index c9f2096bb729..8a7001e1285e 100644 --- a/config/boards/orangepi5.conf +++ b/config/boards/orangepi5.conf @@ -17,10 +17,6 @@ IMAGE_PARTITION_TABLE="gpt" KERNEL_UPGRADE_FREEZE="vendor-rk35xx@24.8.1" declare -g UEFI_EDK2_BOARD_ID="orangepi-5" # This _only_ used for uefi-edk2-rk3588 extension -# @TODO: consider removing those, as the defaults in rockchip64_common have been bumped up -DDR_BLOB='rk35/rk3588_ddr_lp4_2112MHz_lp5_2736MHz_v1.15.bin' -BL31_BLOB='rk35/rk3588_bl31_v1.44.elf' - # Mainline U-Boot for current kernel function post_family_config_branch_current__orangepi5_use_mainline_uboot() { display_alert "$BOARD" "Mainline U-Boot overrides for $BOARD - $BRANCH" "info" From 8496c91cc9cb6485ba2f4c943f162c123fabee78 Mon Sep 17 00:00:00 2001 From: Werner Date: Fri, 28 Feb 2025 12:18:02 +0100 Subject: [PATCH 28/37] unfreeze `vendor` upgrades --- config/boards/orangepi5.conf | 1 - 1 file changed, 1 deletion(-) diff --git a/config/boards/orangepi5.conf b/config/boards/orangepi5.conf index 8a7001e1285e..8eb766f2d940 100644 --- a/config/boards/orangepi5.conf +++ b/config/boards/orangepi5.conf @@ -14,7 +14,6 @@ BOOT_SCENARIO="spl-blobs" BOOT_SUPPORT_SPI="yes" BOOT_SPI_RKSPI_LOADER="yes" IMAGE_PARTITION_TABLE="gpt" -KERNEL_UPGRADE_FREEZE="vendor-rk35xx@24.8.1" declare -g UEFI_EDK2_BOARD_ID="orangepi-5" # This _only_ used for uefi-edk2-rk3588 extension # Mainline U-Boot for current kernel From 7e904666bfd79f8c6352a35ba1e0fa32d9c7f3a7 Mon Sep 17 00:00:00 2001 From: SuperKali Date: Sun, 9 Mar 2025 08:23:12 +0100 Subject: [PATCH 29/37] rockchip64-6.14: rewrite rock5 hdmi audio patch (#7929) --- ...-dts-rockchip-Rock-5B-add-hdmi-sound.patch | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/patch/kernel/archive/rockchip64-6.14/rk3588-1102-arm64-dts-rockchip-Rock-5B-add-hdmi-sound.patch b/patch/kernel/archive/rockchip64-6.14/rk3588-1102-arm64-dts-rockchip-Rock-5B-add-hdmi-sound.patch index 54b9a056a910..fc3c04f36b5d 100644 --- a/patch/kernel/archive/rockchip64-6.14/rk3588-1102-arm64-dts-rockchip-Rock-5B-add-hdmi-sound.patch +++ b/patch/kernel/archive/rockchip64-6.14/rk3588-1102-arm64-dts-rockchip-Rock-5B-add-hdmi-sound.patch @@ -1,20 +1,21 @@ -From: Detlev Casanova -Subject: [PATCH v7 3/3] arm64: dts: rockchip: Enable HDMI audio outputs for Rock 5B -Date: Mon, 17 Feb 2025 16:47:42 -0500 [thread overview] -Message-ID: <20250217215641.372723-4-detlev.casanova@collabora.com> (raw) -In-Reply-To: <20250217215641.372723-1-detlev.casanova@collabora.com> +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aleksey Komarov +Date: Sat, 8 Mar 2025 19:43:05 +0100 +Subject: [ARCHEOLOGY] Enable HDMI audio outputs for Rock 5B by + detlev.casanova@collabora.com -HDMI audio is available on the Rock 5B HDMI TX ports. -Enable it for both ports. - -Reviewed-by: Quentin Schulz -Signed-off-by: Detlev Casanova +> X-Git-Archeology: > recovered message: > https://lore.kernel.org/all/20250217215641.372723-4-detlev.casanova@collabora.com/ +> X-Git-Archeology: - Revision bf9ffa6eedd5df804e3f9a86c84e00607289cd59: https://github.com/armbian/build/commit/bf9ffa6eedd5df804e3f9a86c84e00607289cd59 +> X-Git-Archeology: Date: Sat, 08 Mar 2025 19:43:05 +0100 +> X-Git-Archeology: From: Aleksey Komarov +> X-Git-Archeology: Subject: Enable HDMI audio outputs for Rock 5B by detlev.casanova@collabora.com +> X-Git-Archeology: --- - arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 16 ++++++++++++++++ + arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 16 ++++++++++ 1 file changed, 16 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts -index 27128c6a05a2f..8f42cd0427701 100644 +index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts @@ -231,6 +231,10 @@ hdmi0_out_con: endpoint { @@ -55,4 +56,5 @@ index 27128c6a05a2f..8f42cd0427701 100644 polling-delay = <1000>; -- -2.48.1 +Armbian + From 64a4d12247cb930b9cabe2752ca42632f9cac8e7 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Sat, 8 Mar 2025 22:05:56 +0100 Subject: [PATCH 30/37] fix stable mac address for rk3318-box --- .../general-support-rmii-integrated-phy.patch | 587 ++++++++++++++++-- 1 file changed, 524 insertions(+), 63 deletions(-) diff --git a/patch/u-boot/v2025.01/board_rk3318-box/general-support-rmii-integrated-phy.patch b/patch/u-boot/v2025.01/board_rk3318-box/general-support-rmii-integrated-phy.patch index 0300299efdf0..1c64bd7ed807 100644 --- a/patch/u-boot/v2025.01/board_rk3318-box/general-support-rmii-integrated-phy.patch +++ b/patch/u-boot/v2025.01/board_rk3318-box/general-support-rmii-integrated-phy.patch @@ -1,21 +1,84 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From b802c06ab4feb1ad0434ce88c701433063a0fa72 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino -Date: Thu, 25 Apr 2024 21:44:55 +0200 -Subject: support gmac rmii phy for rk322x +Date: Sat, 8 Mar 2025 21:32:37 +0100 +Subject: [PATCH] fix various rockchip gmac drivers --- - arch/arm/dts/rk322x.dtsi | 8 +- - arch/arm/include/asm/arch-rockchip/cru_rk322x.h | 1 + - doc/device-tree-bindings/net/phy.txt | 13 + - drivers/clk/rockchip/clk_rk322x.c | 14 +- - drivers/net/gmac_rockchip.c | 186 +++++++++- - 5 files changed, 205 insertions(+), 17 deletions(-) + arch/arm/dts/rk3229-evb.dts | 32 +- + arch/arm/dts/rk322x.dtsi | 8 +- + .../include/asm/arch-rockchip/cru_rk322x.h | 1 + + configs/evb-rk3229_defconfig | 2 + + configs/evb-rk3328_defconfig | 2 + + doc/device-tree-bindings/net/phy.txt | 13 + + drivers/clk/rockchip/clk_rk322x.c | 14 +- + drivers/clk/rockchip/clk_rk3328.c | 86 +++++ + drivers/net/gmac_rockchip.c | 341 ++++++++++++++++-- + 9 files changed, 453 insertions(+), 46 deletions(-) +diff --git a/arch/arm/dts/rk3328-u-boot.dtsi b/arch/arm/dts/rk3328-u-boot.dtsi +index 0135bc08d4..27700d156f 100644 +--- a/arch/arm/dts/rk3328-u-boot.dtsi ++++ b/arch/arm/dts/rk3328-u-boot.dtsi +@@ -55,6 +55,11 @@ + bootph-some-ram; + }; + ++&gmac2phy { ++ resets = <&cru SRST_GMAC2PHY_A>, <&cru SRST_MACPHY>; ++ reset-names = "stmmaceth", "mac-phy"; ++}; ++ + &gpio0 { + bootph-pre-ram; + }; +diff --git a/arch/arm/dts/rk3229-evb.dts b/arch/arm/dts/rk3229-evb.dts +index 797476e8be..65fb4f99ec 100644 +--- a/arch/arm/dts/rk3229-evb.dts ++++ b/arch/arm/dts/rk3229-evb.dts +@@ -146,19 +146,25 @@ + }; + + &gmac { +- assigned-clocks = <&cru SCLK_MAC_EXTCLK>, <&cru SCLK_MAC>; +- assigned-clock-parents = <&ext_gmac>, <&cru SCLK_MAC_EXTCLK>; +- clock_in_out = "input"; +- phy-supply = <&vcc_phy>; +- phy-mode = "rgmii"; +- pinctrl-names = "default"; +- pinctrl-0 = <&rgmii_pins>; +- snps,reset-gpio = <&gpio2 RK_PD0 GPIO_ACTIVE_LOW>; +- snps,reset-active-low; +- snps,reset-delays-us = <0 10000 1000000>; +- tx_delay = <0x30>; +- rx_delay = <0x10>; +- status = "okay"; ++ assigned-clocks = <&cru SCLK_MAC_SRC>; ++ assigned-clock-rates = <50000000>; ++ clock_in_out = "output"; ++ phy-supply = <&vcc_phy>; ++ phy-mode = "rmii"; ++ phy-handle = <&phy>; ++ status = "okay"; ++ ++ mdio { ++ compatible = "snps,dwmac-mdio"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ phy: phy@0 { ++ compatible = "ethernet-phy-id1234.d400", "ethernet-phy-ieee802.3-c22"; ++ reg = <0>; ++ phy-is-integrated; ++ }; ++ }; + }; + + &io_domains { diff --git a/arch/arm/dts/rk322x.dtsi b/arch/arm/dts/rk322x.dtsi -index 111111111111..222222222222 100644 +index 8eed9e3a92..e3109afa7b 100644 --- a/arch/arm/dts/rk322x.dtsi +++ b/arch/arm/dts/rk322x.dtsi -@@ -878,13 +878,13 @@ +@@ -870,13 +870,13 @@ clocks = <&cru SCLK_MAC>, <&cru SCLK_MAC_RX>, <&cru SCLK_MAC_TX>, <&cru SCLK_MAC_REF>, <&cru SCLK_MAC_REFOUT>, <&cru ACLK_GMAC>, @@ -34,7 +97,7 @@ index 111111111111..222222222222 100644 status = "disabled"; }; diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk322x.h b/arch/arm/include/asm/arch-rockchip/cru_rk322x.h -index 111111111111..222222222222 100644 +index ee12fa831f..cfbc7e92f7 100644 --- a/arch/arm/include/asm/arch-rockchip/cru_rk322x.h +++ b/arch/arm/include/asm/arch-rockchip/cru_rk322x.h @@ -10,6 +10,7 @@ @@ -45,8 +108,34 @@ index 111111111111..222222222222 100644 #define CORE_PERI_HZ 150000000 #define CORE_ACLK_HZ 300000000 +diff --git a/configs/evb-rk3229_defconfig b/configs/evb-rk3229_defconfig +index 3cbc22662a..75726d1283 100644 +--- a/configs/evb-rk3229_defconfig ++++ b/configs/evb-rk3229_defconfig +@@ -62,6 +62,8 @@ CONFIG_GMAC_ROCKCHIP=y + CONFIG_PHY=y + CONFIG_PINCTRL=y + CONFIG_RAM=y ++CONFIG_DM_RESET=y ++CONFIG_RESET_ROCKCHIP=y + CONFIG_SPL_RAM=y + CONFIG_TPL_RAM=y + CONFIG_BAUDRATE=1500000 +diff --git a/configs/evb-rk3328_defconfig b/configs/evb-rk3328_defconfig +index fd52853583..a87179d045 100644 +--- a/configs/evb-rk3328_defconfig ++++ b/configs/evb-rk3328_defconfig +@@ -75,6 +75,8 @@ CONFIG_DM_REGULATOR_FIXED=y + CONFIG_REGULATOR_RK8XX=y + CONFIG_PWM_ROCKCHIP=y + CONFIG_RAM=y ++CONFIG_DM_RESET=y ++CONFIG_RESET_ROCKCHIP=y + CONFIG_SPL_RAM=y + CONFIG_TPL_RAM=y + CONFIG_DM_RNG=y diff --git a/doc/device-tree-bindings/net/phy.txt b/doc/device-tree-bindings/net/phy.txt -index 111111111111..222222222222 100644 +index 6599c667b5..ca1a4a8526 100644 --- a/doc/device-tree-bindings/net/phy.txt +++ b/doc/device-tree-bindings/net/phy.txt @@ -8,6 +8,19 @@ Required properties: @@ -70,10 +159,10 @@ index 111111111111..222222222222 100644 ethernet-phy@0 { diff --git a/drivers/clk/rockchip/clk_rk322x.c b/drivers/clk/rockchip/clk_rk322x.c -index 111111111111..222222222222 100644 +index 9b71fd863b..e97b307bf4 100644 --- a/drivers/clk/rockchip/clk_rk322x.c +++ b/drivers/clk/rockchip/clk_rk322x.c -@@ -42,6 +42,7 @@ enum { +@@ -41,6 +41,7 @@ enum { /* use integer mode*/ static const struct pll_div apll_init_cfg = PLL_DIVISORS(APLL_HZ, 1, 3, 1); static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2, 1); @@ -81,7 +170,7 @@ index 111111111111..222222222222 100644 static int rkclk_set_pll(struct rk322x_cru *cru, enum rk_clk_id clk_id, const struct pll_div *div) -@@ -91,11 +92,13 @@ static void rkclk_init(struct rk322x_cru *cru) +@@ -90,11 +91,13 @@ static void rkclk_init(struct rk322x_cru *cru) rk_clrsetreg(&cru->cru_mode_con, GPLL_MODE_MASK | APLL_MODE_MASK, GPLL_MODE_SLOW << GPLL_MODE_SHIFT | @@ -96,7 +185,7 @@ index 111111111111..222222222222 100644 /* * select apll as cpu/core clock pll source and -@@ -168,7 +171,8 @@ static void rkclk_init(struct rk322x_cru *cru) +@@ -167,7 +170,8 @@ static void rkclk_init(struct rk322x_cru *cru) rk_clrsetreg(&cru->cru_mode_con, GPLL_MODE_MASK | APLL_MODE_MASK, GPLL_MODE_NORM << GPLL_MODE_SHIFT | @@ -106,7 +195,7 @@ index 111111111111..222222222222 100644 } /* Get pll rate by id */ -@@ -258,11 +262,10 @@ static ulong rk322x_mac_set_clk(struct rk322x_cru *cru, uint freq) +@@ -257,11 +261,10 @@ static ulong rk322x_mac_set_clk(struct rk322x_cru *cru, uint freq) ulong pll_rate; u8 div; @@ -120,7 +209,7 @@ index 111111111111..222222222222 100644 div = DIV_ROUND_UP(pll_rate, freq) - 1; if (div <= 0x1f) -@@ -461,6 +464,7 @@ static ulong rk322x_clk_set_rate(struct clk *clk, ulong rate) +@@ -390,6 +393,7 @@ static ulong rk322x_clk_set_rate(struct clk *clk, ulong rate) case CLK_DDR: new_rate = rk322x_ddr_set_clk(priv->cru, rate); break; @@ -128,9 +217,133 @@ index 111111111111..222222222222 100644 case SCLK_MAC: new_rate = rk322x_mac_set_clk(priv->cru, rate); break; - +diff --git a/drivers/clk/rockchip/clk_rk3328.c b/drivers/clk/rockchip/clk_rk3328.c +index 7701a9734e..8f05fbe607 100644 +--- a/drivers/clk/rockchip/clk_rk3328.c ++++ b/drivers/clk/rockchip/clk_rk3328.c +@@ -95,6 +95,14 @@ enum { + PCLK_DBG_DIV_SHIFT = 0, + PCLK_DBG_DIV_MASK = 0xF << PCLK_DBG_DIV_SHIFT, + ++ /* CLKSEL_CON26 */ ++ GMAC2PHY_PLL_SEL_SHIFT = 7, ++ GMAC2PHY_PLL_SEL_MASK = 1 << GMAC2PHY_PLL_SEL_SHIFT, ++ GMAC2PHY_PLL_SEL_CPLL = 0, ++ GMAC2PHY_PLL_SEL_GPLL = 1, ++ GMAC2PHY_CLK_DIV_MASK = 0x1f, ++ GMAC2PHY_CLK_DIV_SHIFT = 0, ++ + /* CLKSEL_CON27 */ + GMAC2IO_PLL_SEL_SHIFT = 7, + GMAC2IO_PLL_SEL_MASK = 1 << GMAC2IO_PLL_SEL_SHIFT, +@@ -445,6 +453,39 @@ static ulong rk3328_gmac2io_set_clk(struct rk3328_cru *cru, ulong rate) + return ret; + } + ++static ulong rk3328_gmac2phy_src_set_clk(struct rk3328_cru *cru, ulong rate) ++{ ++ u32 con = readl(&cru->clksel_con[26]); ++ ulong pll_rate; ++ u8 div; ++ ++ if ((con >> GMAC2PHY_PLL_SEL_SHIFT) & GMAC2PHY_PLL_SEL_GPLL) ++ pll_rate = GPLL_HZ; ++ else ++ pll_rate = CPLL_HZ; ++ ++ div = DIV_ROUND_UP(pll_rate, rate) - 1; ++ if (div <= 0x1f) ++ rk_clrsetreg(&cru->clksel_con[26], GMAC2PHY_CLK_DIV_MASK, ++ div << GMAC2PHY_CLK_DIV_SHIFT); ++ else ++ debug("Unsupported div for gmac:%d\n", div); ++ ++ return DIV_TO_RATE(pll_rate, div); ++} ++ ++static ulong rk3328_gmac2phy_set_clk(struct rk3328_cru *cru, ulong rate) ++{ ++ struct rk3328_grf_regs *grf; ++ ++ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); ++ if (readl(&grf->mac_con[2]) & BIT(10)) ++ /* An external clock will always generate the right rate... */ ++ return rate; ++ else ++ return rk3328_gmac2phy_src_set_clk(cru, rate); ++} ++ + static ulong rk3328_mmc_get_clk(struct rk3328_cru *cru, uint clk_id) + { + u32 div, con, con_id; +@@ -737,6 +778,12 @@ static ulong rk3328_clk_set_rate(struct clk *clk, ulong rate) + case SCLK_MAC2IO: + ret = rk3328_gmac2io_set_clk(priv->cru, rate); + break; ++ case SCLK_MAC2PHY: ++ ret = rk3328_gmac2phy_set_clk(priv->cru, rate); ++ break; ++ case SCLK_MAC2PHY_SRC: ++ ret = rk3328_gmac2phy_src_set_clk(priv->cru, rate); ++ break; + case SCLK_PWM: + ret = rk3328_pwm_set_clk(priv->cru, rate); + break; +@@ -866,6 +913,43 @@ static int rk3328_gmac2io_ext_set_parent(struct clk *clk, struct clk *parent) + return -EINVAL; + } + ++static int rk3328_gmac2phy_set_parent(struct clk *clk, struct clk *parent) ++{ ++ struct rk3328_grf_regs *grf; ++ const char *clock_output_name; ++ int ret; ++ ++ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); ++ ++ /* ++ * If the requested parent is in the same clock-controller and the id ++ * is SCLK_MAC2PHY_SRC ("clk_mac2phy_src"), switch to the internal clock. ++ */ ++ if ((parent->dev == clk->dev) && (parent->id == SCLK_MAC2PHY_SRC)) { ++ debug("%s: switching MAC CLK to SCLK_MAC2IO_PHY\n", __func__); ++ rk_clrreg(&grf->mac_con[2], BIT(10)); ++ return 0; ++ } ++ ++ /* ++ * Otherwise, we need to check the clock-output-names of the ++ * requested parent to see if the requested id is "phy_50m_out". ++ */ ++ ret = dev_read_string_index(parent->dev, "clock-output-names", ++ parent->id, &clock_output_name); ++ if (ret < 0) ++ return -ENODATA; ++ ++ /* If this is "phy_50m_out", switch to the external clock input */ ++ if (!strcmp(clock_output_name, "phy_50m_out")) { ++ debug("%s: switching MAC CLK to PHY_50M_OUT\n", __func__); ++ rk_setreg(&grf->mac_con[2], BIT(10)); ++ return 0; ++ } ++ ++ return -EINVAL; ++} ++ + static int rk3328_clk_set_parent(struct clk *clk, struct clk *parent) + { + switch (clk->id) { +@@ -873,6 +957,8 @@ static int rk3328_clk_set_parent(struct clk *clk, struct clk *parent) + return rk3328_gmac2io_set_parent(clk, parent); + case SCLK_MAC2IO_EXT: + return rk3328_gmac2io_ext_set_parent(clk, parent); ++ case SCLK_MAC2PHY: ++ return rk3328_gmac2phy_set_parent(clk, parent); + case DCLK_LCDC: + case USB480M: + case SCLK_PDM: diff --git a/drivers/net/gmac_rockchip.c b/drivers/net/gmac_rockchip.c -index 8cfeeffe95..c215b1b3f4 100644 +index 8cfeeffe95..2b8f1245eb 100644 --- a/drivers/net/gmac_rockchip.c +++ b/drivers/net/gmac_rockchip.c @@ -10,6 +10,7 @@ @@ -150,7 +363,7 @@ index 8cfeeffe95..c215b1b3f4 100644 #include #include #include "designware.h" -@@ -41,20 +44,29 @@ DECLARE_GLOBAL_DATA_PTR; +@@ -41,20 +44,28 @@ DECLARE_GLOBAL_DATA_PTR; struct gmac_rockchip_plat { struct dw_eth_pdata dw_eth_pdata; bool clock_input; @@ -161,11 +374,11 @@ index 8cfeeffe95..c215b1b3f4 100644 }; struct rk_gmac_ops { - int (*fix_mac_speed)(struct dw_eth_dev *priv); +- int (*fix_mac_speed)(struct dw_eth_dev *priv); + int (*fix_rmii_speed)(struct gmac_rockchip_plat *pdata, -+ struct dw_eth_dev *priv); ++ struct dw_eth_dev *priv); + int (*fix_rgmii_speed)(struct gmac_rockchip_plat *pdata, -+ struct dw_eth_dev *priv); ++ struct dw_eth_dev *priv); void (*set_to_rmii)(struct gmac_rockchip_plat *pdata); void (*set_to_rgmii)(struct gmac_rockchip_plat *pdata); + void (*integrated_phy_powerup)(struct gmac_rockchip_plat *pdata); @@ -180,7 +393,7 @@ index 8cfeeffe95..c215b1b3f4 100644 string = dev_read_string(dev, "clock_in_out"); if (!strcmp(string, "input")) -@@ -62,6 +74,25 @@ static int gmac_rockchip_of_to_plat(struct udevice *dev) +@@ -62,6 +73,25 @@ static int gmac_rockchip_of_to_plat(struct udevice *dev) else pdata->clock_input = false; @@ -206,6 +419,16 @@ index 8cfeeffe95..c215b1b3f4 100644 /* Check the new naming-style first... */ pdata->tx_delay = dev_read_u32_default(dev, "tx_delay", -ENOENT); pdata->rx_delay = dev_read_u32_default(dev, "rx_delay", -ENOENT); +@@ -75,7 +105,8 @@ static int gmac_rockchip_of_to_plat(struct udevice *dev) + return designware_eth_of_to_plat(dev); + } + +-static int px30_gmac_fix_mac_speed(struct dw_eth_dev *priv) ++static int px30_gmac_fix_rmii_speed(struct gmac_rockchip_plat *pdata, ++ struct dw_eth_dev *priv) + { + struct px30_grf *grf; + struct clk clk_speed; @@ -116,7 +147,43 @@ static int px30_gmac_fix_mac_speed(struct dw_eth_dev *priv) return 0; } @@ -251,36 +474,157 @@ index 8cfeeffe95..c215b1b3f4 100644 { struct rk322x_grf *grf; int clk; -@@ -358,6 +425,28 @@ static void px30_gmac_set_to_rmii(struct gmac_rockchip_plat *pdata) +@@ -149,7 +216,8 @@ static int rk3228_gmac_fix_mac_speed(struct dw_eth_dev *priv) + return 0; + } + +-static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv) ++static int rk3288_gmac_fix_rgmii_speed(struct gmac_rockchip_plat *pdata, ++ struct dw_eth_dev *priv) + { + struct rk3288_grf *grf; + int clk; +@@ -175,7 +243,8 @@ static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv) + return 0; + } + +-static int rk3308_gmac_fix_mac_speed(struct dw_eth_dev *priv) ++static int rk3308_gmac_fix_rmii_speed(struct gmac_rockchip_plat *pdata, ++ struct dw_eth_dev *priv) + { + struct rk3308_grf *grf; + struct clk clk_speed; +@@ -216,7 +285,43 @@ static int rk3308_gmac_fix_mac_speed(struct dw_eth_dev *priv) + return 0; + } + +-static int rk3328_gmac_fix_mac_speed(struct dw_eth_dev *priv) ++static int rk3328_gmac_fix_rmii_speed(struct gmac_rockchip_plat *pdata, ++ struct dw_eth_dev *priv) ++{ ++ struct rk3328_grf_regs *grf; ++ int clk; ++ enum { ++ RK3328_GMAC_RMII_CLK_MASK = BIT(7), ++ RK3328_GMAC_RMII_CLK_2_5M = 0, ++ RK3328_GMAC_RMII_CLK_25M = BIT(7), ++ ++ RK3328_GMAC_RMII_SPEED_MASK = BIT(2), ++ RK3328_GMAC_RMII_SPEED_10 = 0, ++ RK3328_GMAC_RMII_SPEED_100 = BIT(2), ++ }; ++ ++ switch (priv->phydev->speed) { ++ case 10: ++ clk = RK3328_GMAC_RMII_CLK_2_5M | RK3328_GMAC_RMII_SPEED_10; ++ break; ++ case 100: ++ clk = RK3328_GMAC_RMII_CLK_25M | RK3328_GMAC_RMII_SPEED_100; ++ break; ++ default: ++ debug("Unknown phy speed: %d\n", priv->phydev->speed); ++ return -EINVAL; ++ } ++ ++ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); ++ rk_clrsetreg(pdata->integrated_phy ? &grf->mac_con[2] : &grf->mac_con[1], ++ RK3328_GMAC_RMII_CLK_MASK | RK3328_GMAC_RMII_SPEED_MASK, ++ clk); ++ ++ return 0; ++} ++ ++static int rk3328_gmac_fix_rgmii_speed(struct gmac_rockchip_plat *pdata, ++ struct dw_eth_dev *priv) + { + struct rk3328_grf_regs *grf; + int clk; +@@ -249,7 +354,8 @@ static int rk3328_gmac_fix_mac_speed(struct dw_eth_dev *priv) + return 0; + } + +-static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev *priv) ++static int rk3368_gmac_fix_rgmii_speed(struct gmac_rockchip_plat *pdata, ++ struct dw_eth_dev *priv) + { + struct rk3368_grf *grf; + int clk; +@@ -281,7 +387,8 @@ static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev *priv) + return 0; + } + +-static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv) ++static int rk3399_gmac_fix_rgmii_speed(struct gmac_rockchip_plat *pdata, ++ struct dw_eth_dev *priv) + { + struct rk3399_grf_regs *grf; + int clk; +@@ -307,7 +414,8 @@ static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv) + return 0; + } + +-static int rv1108_set_rmii_speed(struct dw_eth_dev *priv) ++static int rv1108_gmac_fix_rmii_speed(struct gmac_rockchip_plat *pdata, ++ struct dw_eth_dev *priv) + { + struct rv1108_grf *grf; + int clk, speed; +@@ -358,6 +466,28 @@ static void px30_gmac_set_to_rmii(struct gmac_rockchip_plat *pdata) PX30_GMAC_PHY_INTF_SEL_RMII); } +static void rk3228_gmac_set_to_rmii(struct gmac_rockchip_plat *pdata) +{ -+ struct rk322x_grf *grf; -+ enum { -+ RK3228_GRF_CON_RMII_MODE_MASK = BIT(11), -+ RK3228_GRF_CON_RMII_MODE_SEL = BIT(11), -+ RK3228_RMII_MODE_MASK = BIT(10), -+ RK3228_RMII_MODE_SEL = BIT(10), -+ RK3228_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4), -+ RK3228_GMAC_PHY_INTF_SEL_RMII = BIT(6), -+ }; -+ -+ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); -+ rk_clrsetreg(&grf->mac_con[1], -+ RK3228_GRF_CON_RMII_MODE_MASK | -+ RK3228_RMII_MODE_MASK | -+ RK3228_GMAC_PHY_INTF_SEL_MASK, -+ RK3228_GRF_CON_RMII_MODE_SEL | -+ RK3228_RMII_MODE_SEL | -+ RK3228_GMAC_PHY_INTF_SEL_RMII); ++ struct rk322x_grf *grf; ++ enum { ++ RK3228_GRF_CON_RMII_MODE_MASK = BIT(11), ++ RK3228_GRF_CON_RMII_MODE_SEL = BIT(11), ++ RK3228_RMII_MODE_MASK = BIT(10), ++ RK3228_RMII_MODE_SEL = BIT(10), ++ RK3228_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4), ++ RK3228_GMAC_PHY_INTF_SEL_RMII = BIT(6), ++ }; ++ ++ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); ++ rk_clrsetreg(&grf->mac_con[1], ++ RK3228_GRF_CON_RMII_MODE_MASK | ++ RK3228_RMII_MODE_MASK | ++ RK3228_GMAC_PHY_INTF_SEL_MASK, ++ RK3228_GRF_CON_RMII_MODE_SEL | ++ RK3228_RMII_MODE_SEL | ++ RK3228_GMAC_PHY_INTF_SEL_RMII); +} + static void rk3228_gmac_set_to_rgmii(struct gmac_rockchip_plat *pdata) { struct rk322x_grf *grf; -@@ -551,6 +640,66 @@ static void rv1108_gmac_set_to_rmii(struct gmac_rockchip_plat *pdata) +@@ -436,6 +566,25 @@ static void rk3308_gmac_set_to_rmii(struct gmac_rockchip_plat *pdata) + RK3308_GMAC_PHY_INTF_SEL_RMII); + } + ++static void rk3328_gmac_set_to_rmii(struct gmac_rockchip_plat *pdata) ++{ ++ struct rk3328_grf_regs *grf; ++ enum { ++ RK3328_RMII_MODE_MASK = BIT(9), ++ RK3328_RMII_MODE = BIT(9), ++ ++ RK3328_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4), ++ RK3328_GMAC_PHY_INTF_SEL_RMII = BIT(6), ++ }; ++ ++ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); ++ rk_clrsetreg(pdata->integrated_phy ? &grf->mac_con[2] : &grf->mac_con[1], ++ RK3328_RMII_MODE_MASK | ++ RK3328_GMAC_PHY_INTF_SEL_MASK, ++ RK3328_GMAC_PHY_INTF_SEL_RMII | ++ RK3328_RMII_MODE); ++} ++ + static void rk3328_gmac_set_to_rgmii(struct gmac_rockchip_plat *pdata) + { + struct rk3328_grf_regs *grf; +@@ -551,6 +700,126 @@ static void rv1108_gmac_set_to_rmii(struct gmac_rockchip_plat *pdata) RV1108_GMAC_PHY_INTF_SEL_RMII); } @@ -343,11 +687,71 @@ index 8cfeeffe95..c215b1b3f4 100644 + RK3228_MACPHY_ENABLE); + udelay(30 * 1000); +} ++ ++static void rk3328_gmac_integrated_phy_powerup(struct gmac_rockchip_plat *pdata) ++{ ++ struct rk3328_grf_regs *grf; ++ enum { ++ RK3328_GRF_CON_RMII_MODE_MASK = BIT(9), ++ RK3328_GRF_CON_RMII_MODE = BIT(9), ++ }; ++ enum { ++ RK3328_MACPHY_CFG_CLK_50M_MASK = BIT(14), ++ RK3328_MACPHY_CFG_CLK_50M = BIT(14), ++ ++ RK3328_MACPHY_RMII_MODE_MASK = GENMASK(7, 6), ++ RK3328_MACPHY_RMII_MODE = BIT(6), ++ ++ RK3328_MACPHY_ENABLE_MASK = BIT(0), ++ RK3328_MACPHY_DISENABLE = 0, ++ RK3328_MACPHY_ENABLE = BIT(0), ++ }; ++ enum { ++ RK3328_RK_GRF_CON2_MACPHY_ID_MASK = GENMASK(6, 0), ++ RK3328_RK_GRF_CON2_MACPHY_ID = 0x1234, ++ }; ++ enum { ++ RK3328_RK_GRF_CON3_MACPHY_ID_MASK = GENMASK(5, 0), ++ RK3328_RK_GRF_CON3_MACPHY_ID = 0x35, ++ }; ++ ++ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); ++ rk_clrsetreg(&grf->macphy_con[1], ++ RK3328_GRF_CON_RMII_MODE_MASK, ++ RK3328_GRF_CON_RMII_MODE); ++ ++ rk_clrsetreg(&grf->macphy_con[2], ++ RK3328_RK_GRF_CON2_MACPHY_ID_MASK, ++ RK3328_RK_GRF_CON2_MACPHY_ID); ++ ++ rk_clrsetreg(&grf->macphy_con[3], ++ RK3328_RK_GRF_CON3_MACPHY_ID_MASK, ++ RK3328_RK_GRF_CON3_MACPHY_ID); ++ ++ /* disabled before trying to reset it */ ++ rk_clrsetreg(&grf->macphy_con[0], ++ RK3328_MACPHY_CFG_CLK_50M_MASK | ++ RK3328_MACPHY_RMII_MODE_MASK | ++ RK3328_MACPHY_ENABLE_MASK, ++ RK3328_MACPHY_CFG_CLK_50M | ++ RK3328_MACPHY_RMII_MODE | ++ RK3328_MACPHY_DISENABLE); ++ ++ reset_assert(&pdata->phy_reset); ++ udelay(10); ++ reset_deassert(&pdata->phy_reset); ++ udelay(10); ++ ++ rk_clrsetreg(&grf->macphy_con[0], ++ RK3328_MACPHY_ENABLE_MASK, ++ RK3328_MACPHY_ENABLE); ++ udelay(30 * 1000); ++} + static int gmac_rockchip_probe(struct udevice *dev) { struct gmac_rockchip_plat *pdata = dev_get_plat(dev); -@@ -570,6 +719,9 @@ static int gmac_rockchip_probe(struct udevice *dev) +@@ -570,6 +839,9 @@ static int gmac_rockchip_probe(struct udevice *dev) if (ret) return ret; @@ -357,7 +761,16 @@ index 8cfeeffe95..c215b1b3f4 100644 switch (eth_pdata->phy_interface) { case PHY_INTERFACE_MODE_RGMII: /* Set to RGMII mode */ -@@ -653,7 +805,7 @@ static int gmac_rockchip_probe(struct udevice *dev) +@@ -617,7 +889,7 @@ static int gmac_rockchip_probe(struct udevice *dev) + + if (!pdata->clock_input) { + rate = clk_set_rate(&clk, 50000000); +- if (rate != 50000000) ++ if (rate != 50000000 && rate != 49500000) + return -EINVAL; + } + break; +@@ -653,7 +925,7 @@ static int gmac_rockchip_probe(struct udevice *dev) break; default: @@ -366,7 +779,7 @@ index 8cfeeffe95..c215b1b3f4 100644 return -ENXIO; } -@@ -662,18 +814,33 @@ static int gmac_rockchip_probe(struct udevice *dev) +@@ -662,18 +934,33 @@ static int gmac_rockchip_probe(struct udevice *dev) static int gmac_rockchip_eth_start(struct udevice *dev) { @@ -387,25 +800,31 @@ index 8cfeeffe95..c215b1b3f4 100644 return ret; + + switch (eth_pdata->phy_interface) { -+ case PHY_INTERFACE_MODE_RGMII: -+ ret = ops->fix_rgmii_speed(pdata, priv); -+ if (ret) -+ return ret; -+ break; -+ case PHY_INTERFACE_MODE_RMII: -+ ret = ops->fix_rmii_speed(pdata, priv); -+ if (ret) -+ return ret; -+ break; -+ default: -+ debug("%s: no interface defined!\n", __func__); -+ return -ENXIO; ++ case PHY_INTERFACE_MODE_RGMII: ++ ret = ops->fix_rgmii_speed(pdata, priv); ++ if (ret) ++ return ret; ++ break; ++ case PHY_INTERFACE_MODE_RMII: ++ ret = ops->fix_rmii_speed(pdata, priv); ++ if (ret) ++ return ret; ++ break; ++ default: ++ debug("%s: no interface defined!\n", __func__); ++ return -ENXIO; + } + ret = designware_eth_enable(priv); if (ret) return ret; -@@ -696,8 +863,11 @@ const struct rk_gmac_ops px30_gmac_ops = { +@@ -691,42 +978,48 @@ const struct eth_ops gmac_rockchip_eth_ops = { + }; + + const struct rk_gmac_ops px30_gmac_ops = { +- .fix_mac_speed = px30_gmac_fix_mac_speed, ++ .fix_rmii_speed = px30_gmac_fix_rmii_speed, + .set_to_rmii = px30_gmac_set_to_rmii, }; const struct rk_gmac_ops rk3228_gmac_ops = { @@ -418,3 +837,45 @@ index 8cfeeffe95..c215b1b3f4 100644 }; const struct rk_gmac_ops rk3288_gmac_ops = { +- .fix_mac_speed = rk3288_gmac_fix_mac_speed, ++ .fix_rgmii_speed = rk3288_gmac_fix_rgmii_speed, + .set_to_rgmii = rk3288_gmac_set_to_rgmii, + }; + + const struct rk_gmac_ops rk3308_gmac_ops = { +- .fix_mac_speed = rk3308_gmac_fix_mac_speed, ++ .fix_rmii_speed = rk3308_gmac_fix_rmii_speed, + .set_to_rmii = rk3308_gmac_set_to_rmii, + }; + + const struct rk_gmac_ops rk3328_gmac_ops = { +- .fix_mac_speed = rk3328_gmac_fix_mac_speed, ++ .fix_rmii_speed = rk3328_gmac_fix_rmii_speed, ++ .fix_rgmii_speed = rk3328_gmac_fix_rgmii_speed, ++ .set_to_rmii = rk3328_gmac_set_to_rmii, + .set_to_rgmii = rk3328_gmac_set_to_rgmii, ++ .integrated_phy_powerup = rk3328_gmac_integrated_phy_powerup, + }; + + const struct rk_gmac_ops rk3368_gmac_ops = { +- .fix_mac_speed = rk3368_gmac_fix_mac_speed, ++ .fix_rgmii_speed = rk3368_gmac_fix_rgmii_speed, + .set_to_rgmii = rk3368_gmac_set_to_rgmii, + }; + + const struct rk_gmac_ops rk3399_gmac_ops = { +- .fix_mac_speed = rk3399_gmac_fix_mac_speed, ++ .fix_rgmii_speed = rk3399_gmac_fix_rgmii_speed, + .set_to_rgmii = rk3399_gmac_set_to_rgmii, + }; + + const struct rk_gmac_ops rv1108_gmac_ops = { +- .fix_mac_speed = rv1108_set_rmii_speed, ++ .fix_rmii_speed = rv1108_gmac_fix_rmii_speed, + .set_to_rmii = rv1108_gmac_set_to_rmii, + }; + +-- +2.43.0 + + From 4134dc3b19a32c7d6ac1227199c46c741473d3ab Mon Sep 17 00:00:00 2001 From: Julian Sikorski Date: Sat, 8 Mar 2025 11:28:56 +0000 Subject: [PATCH 31/37] Update odroidxu4-current to 6.6.81 --- .../odroidxu4-6.6/patch-6.6.75-76.patch | 19946 ++++++++++++++++ .../odroidxu4-6.6/patch-6.6.76-77.patch | 251 + .../odroidxu4-6.6/patch-6.6.77-78.patch | 9040 +++++++ .../odroidxu4-6.6/patch-6.6.78-79.patch | 6874 ++++++ .../odroidxu4-6.6/patch-6.6.79-80.patch | 6502 +++++ .../odroidxu4-6.6/patch-6.6.80-81.patch | 8344 +++++++ 6 files changed, 50957 insertions(+) create mode 100644 patch/kernel/archive/odroidxu4-6.6/patch-6.6.75-76.patch create mode 100644 patch/kernel/archive/odroidxu4-6.6/patch-6.6.76-77.patch create mode 100644 patch/kernel/archive/odroidxu4-6.6/patch-6.6.77-78.patch create mode 100644 patch/kernel/archive/odroidxu4-6.6/patch-6.6.78-79.patch create mode 100644 patch/kernel/archive/odroidxu4-6.6/patch-6.6.79-80.patch create mode 100644 patch/kernel/archive/odroidxu4-6.6/patch-6.6.80-81.patch diff --git a/patch/kernel/archive/odroidxu4-6.6/patch-6.6.75-76.patch b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.75-76.patch new file mode 100644 index 000000000000..a98510e558bc --- /dev/null +++ b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.75-76.patch @@ -0,0 +1,19946 @@ +diff --git a/Documentation/devicetree/bindings/leds/leds-class-multicolor.yaml b/Documentation/devicetree/bindings/leds/leds-class-multicolor.yaml +index e850a8894758df..bb40bb9e036ee0 100644 +--- a/Documentation/devicetree/bindings/leds/leds-class-multicolor.yaml ++++ b/Documentation/devicetree/bindings/leds/leds-class-multicolor.yaml +@@ -27,7 +27,7 @@ properties: + description: | + For multicolor LED support this property should be defined as either + LED_COLOR_ID_RGB or LED_COLOR_ID_MULTI which can be found in +- include/linux/leds/common.h. ++ include/dt-bindings/leds/common.h. + enum: [ 8, 9 ] + + required: +diff --git a/Documentation/devicetree/bindings/mfd/rohm,bd71815-pmic.yaml b/Documentation/devicetree/bindings/mfd/rohm,bd71815-pmic.yaml +index 05747e012516e2..ab26b1bd567fd9 100644 +--- a/Documentation/devicetree/bindings/mfd/rohm,bd71815-pmic.yaml ++++ b/Documentation/devicetree/bindings/mfd/rohm,bd71815-pmic.yaml +@@ -50,15 +50,15 @@ properties: + minimum: 0 + maximum: 1 + +- rohm,charger-sense-resistor-ohms: +- minimum: 10000000 +- maximum: 50000000 ++ rohm,charger-sense-resistor-micro-ohms: ++ minimum: 10000 ++ maximum: 50000 + description: | +- BD71827 and BD71828 have SAR ADC for measuring charging currents. +- External sense resistor (RSENSE in data sheet) should be used. If +- something other but 30MOhm resistor is used the resistance value +- should be given here in Ohms. +- default: 30000000 ++ BD71815 has SAR ADC for measuring charging currents. External sense ++ resistor (RSENSE in data sheet) should be used. If something other ++ but a 30 mOhm resistor is used the resistance value should be given ++ here in micro Ohms. ++ default: 30000 + + regulators: + $ref: ../regulator/rohm,bd71815-regulator.yaml +@@ -67,7 +67,7 @@ properties: + + gpio-reserved-ranges: + description: | +- Usage of BD71828 GPIO pins can be changed via OTP. This property can be ++ Usage of BD71815 GPIO pins can be changed via OTP. This property can be + used to mark the pins which should not be configured for GPIO. Please see + the ../gpio/gpio.txt for more information. + +@@ -113,7 +113,7 @@ examples: + gpio-controller; + #gpio-cells = <2>; + +- rohm,charger-sense-resistor-ohms = <10000000>; ++ rohm,charger-sense-resistor-micro-ohms = <10000>; + + regulators { + buck1: buck1 { +diff --git a/Documentation/devicetree/bindings/mmc/mmc-controller.yaml b/Documentation/devicetree/bindings/mmc/mmc-controller.yaml +index 58ae298cd2fcf4..23884b8184a9df 100644 +--- a/Documentation/devicetree/bindings/mmc/mmc-controller.yaml ++++ b/Documentation/devicetree/bindings/mmc/mmc-controller.yaml +@@ -25,7 +25,7 @@ properties: + "#address-cells": + const: 1 + description: | +- The cell is the slot ID if a function subnode is used. ++ The cell is the SDIO function number if a function subnode is used. + + "#size-cells": + const: 0 +diff --git a/Documentation/devicetree/bindings/regulator/mt6315-regulator.yaml b/Documentation/devicetree/bindings/regulator/mt6315-regulator.yaml +index 6317daf76d1fbe..2bed57a347827e 100644 +--- a/Documentation/devicetree/bindings/regulator/mt6315-regulator.yaml ++++ b/Documentation/devicetree/bindings/regulator/mt6315-regulator.yaml +@@ -31,10 +31,6 @@ properties: + $ref: regulator.yaml# + unevaluatedProperties: false + +- properties: +- regulator-compatible: +- pattern: "^vbuck[1-4]$" +- + additionalProperties: false + + required: +@@ -52,7 +48,6 @@ examples: + + regulators { + vbuck1 { +- regulator-compatible = "vbuck1"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1193750>; + regulator-enable-ramp-delay = <256>; +@@ -60,7 +55,6 @@ examples: + }; + + vbuck3 { +- regulator-compatible = "vbuck3"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1193750>; + regulator-enable-ramp-delay = <256>; +diff --git a/Makefile b/Makefile +index b8041104f248d3..d679a3dd5a582b 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 6 + PATCHLEVEL = 6 +-SUBLEVEL = 75 ++SUBLEVEL = 76 + EXTRAVERSION = + NAME = Pinguïn Aangedreven + +@@ -518,7 +518,7 @@ KGZIP = gzip + KBZIP2 = bzip2 + KLZOP = lzop + LZMA = lzma +-LZ4 = lz4c ++LZ4 = lz4 + XZ = xz + ZSTD = zstd + +diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-yosemite4.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-yosemite4.dts +index 64075cc41d9275..f5d38a9f47638e 100644 +--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-yosemite4.dts ++++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-yosemite4.dts +@@ -284,12 +284,12 @@ &i2c10 { + &i2c11 { + status = "okay"; + power-sensor@10 { +- compatible = "adi, adm1272"; ++ compatible = "adi,adm1272"; + reg = <0x10>; + }; + + power-sensor@12 { +- compatible = "adi, adm1272"; ++ compatible = "adi,adm1272"; + reg = <0x12>; + }; + +@@ -454,22 +454,20 @@ adc@1f { + }; + + pwm@20{ +- compatible = "max31790"; ++ compatible = "maxim,max31790"; + reg = <0x20>; +- #address-cells = <1>; +- #size-cells = <0>; + }; + + gpio@22{ + compatible = "ti,tca6424"; + reg = <0x22>; ++ gpio-controller; ++ #gpio-cells = <2>; + }; + + pwm@23{ +- compatible = "max31790"; ++ compatible = "maxim,max31790"; + reg = <0x23>; +- #address-cells = <1>; +- #size-cells = <0>; + }; + + adc@33 { +@@ -504,22 +502,20 @@ adc@1f { + }; + + pwm@20{ +- compatible = "max31790"; ++ compatible = "maxim,max31790"; + reg = <0x20>; +- #address-cells = <1>; +- #size-cells = <0>; + }; + + gpio@22{ + compatible = "ti,tca6424"; + reg = <0x22>; ++ gpio-controller; ++ #gpio-cells = <2>; + }; + + pwm@23{ +- compatible = "max31790"; ++ compatible = "maxim,max31790"; + reg = <0x23>; +- #address-cells = <1>; +- #size-cells = <0>; + }; + + adc@33 { +diff --git a/arch/arm/boot/dts/intel/socfpga/socfpga_arria10.dtsi b/arch/arm/boot/dts/intel/socfpga/socfpga_arria10.dtsi +index f36063c57c7f28..72c55e5187ca89 100644 +--- a/arch/arm/boot/dts/intel/socfpga/socfpga_arria10.dtsi ++++ b/arch/arm/boot/dts/intel/socfpga/socfpga_arria10.dtsi +@@ -440,7 +440,7 @@ gmac0: ethernet@ff800000 { + clocks = <&l4_mp_clk>, <&peri_emac_ptp_clk>; + clock-names = "stmmaceth", "ptp_ref"; + resets = <&rst EMAC0_RESET>, <&rst EMAC0_OCP_RESET>; +- reset-names = "stmmaceth", "ahb"; ++ reset-names = "stmmaceth", "stmmaceth-ocp"; + snps,axi-config = <&socfpga_axi_setup>; + status = "disabled"; + }; +@@ -460,7 +460,7 @@ gmac1: ethernet@ff802000 { + clocks = <&l4_mp_clk>, <&peri_emac_ptp_clk>; + clock-names = "stmmaceth", "ptp_ref"; + resets = <&rst EMAC1_RESET>, <&rst EMAC1_OCP_RESET>; +- reset-names = "stmmaceth", "ahb"; ++ reset-names = "stmmaceth", "stmmaceth-ocp"; + snps,axi-config = <&socfpga_axi_setup>; + status = "disabled"; + }; +@@ -480,7 +480,7 @@ gmac2: ethernet@ff804000 { + clocks = <&l4_mp_clk>, <&peri_emac_ptp_clk>; + clock-names = "stmmaceth", "ptp_ref"; + resets = <&rst EMAC2_RESET>, <&rst EMAC2_OCP_RESET>; +- reset-names = "stmmaceth", "ahb"; ++ reset-names = "stmmaceth", "stmmaceth-ocp"; + snps,axi-config = <&socfpga_axi_setup>; + status = "disabled"; + }; +diff --git a/arch/arm/boot/dts/mediatek/mt7623.dtsi b/arch/arm/boot/dts/mediatek/mt7623.dtsi +index f0b4a09004b317..9c5a52ce9351aa 100644 +--- a/arch/arm/boot/dts/mediatek/mt7623.dtsi ++++ b/arch/arm/boot/dts/mediatek/mt7623.dtsi +@@ -308,7 +308,7 @@ pwrap: pwrap@1000d000 { + clock-names = "spi", "wrap"; + }; + +- cir: cir@10013000 { ++ cir: ir-receiver@10013000 { + compatible = "mediatek,mt7623-cir"; + reg = <0 0x10013000 0 0x1000>; + interrupts = ; +diff --git a/arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1_ek.dts b/arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1_ek.dts +index e055b9e2fe3446..35a933eec5738f 100644 +--- a/arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1_ek.dts ++++ b/arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1_ek.dts +@@ -197,7 +197,7 @@ qspi1_flash: flash@0 { + + &sdmmc0 { + bus-width = <4>; +- mmc-ddr-3_3v; ++ no-1-8-v; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sdmmc0_default>; + status = "okay"; +diff --git a/arch/arm/boot/dts/st/stm32mp151.dtsi b/arch/arm/boot/dts/st/stm32mp151.dtsi +index aec7fa5ab5d8c6..fe79d5d40c1160 100644 +--- a/arch/arm/boot/dts/st/stm32mp151.dtsi ++++ b/arch/arm/boot/dts/st/stm32mp151.dtsi +@@ -1165,7 +1165,7 @@ ipcc: mailbox@4c001000 { + reg = <0x4c001000 0x400>; + st,proc-id = <0>; + interrupts-extended = +- <&exti 61 1>, ++ <&exti 61 IRQ_TYPE_LEVEL_HIGH>, + <&intc GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "rx", "tx"; + clocks = <&rcc IPCC>; +diff --git a/arch/arm/boot/dts/st/stm32mp15xx-dhcom-drc02.dtsi b/arch/arm/boot/dts/st/stm32mp15xx-dhcom-drc02.dtsi +index 35b1034aa3cf63..e4e114d8c3371e 100644 +--- a/arch/arm/boot/dts/st/stm32mp15xx-dhcom-drc02.dtsi ++++ b/arch/arm/boot/dts/st/stm32mp15xx-dhcom-drc02.dtsi +@@ -6,18 +6,6 @@ + #include + #include + +-/ { +- aliases { +- serial0 = &uart4; +- serial1 = &usart3; +- serial2 = &uart8; +- }; +- +- chosen { +- stdout-path = "serial0:115200n8"; +- }; +-}; +- + &adc { + status = "disabled"; + }; +diff --git a/arch/arm/boot/dts/st/stm32mp15xx-dhcom-pdk2.dtsi b/arch/arm/boot/dts/st/stm32mp15xx-dhcom-pdk2.dtsi +index 46b87a27d8b378..7050582837d58f 100644 +--- a/arch/arm/boot/dts/st/stm32mp15xx-dhcom-pdk2.dtsi ++++ b/arch/arm/boot/dts/st/stm32mp15xx-dhcom-pdk2.dtsi +@@ -7,16 +7,6 @@ + #include + + / { +- aliases { +- serial0 = &uart4; +- serial1 = &usart3; +- serial2 = &uart8; +- }; +- +- chosen { +- stdout-path = "serial0:115200n8"; +- }; +- + clk_ext_audio_codec: clock-codec { + compatible = "fixed-clock"; + #clock-cells = <0>; +diff --git a/arch/arm/boot/dts/st/stm32mp15xx-dhcom-picoitx.dtsi b/arch/arm/boot/dts/st/stm32mp15xx-dhcom-picoitx.dtsi +index abc595350e71a0..81743a448607b0 100644 +--- a/arch/arm/boot/dts/st/stm32mp15xx-dhcom-picoitx.dtsi ++++ b/arch/arm/boot/dts/st/stm32mp15xx-dhcom-picoitx.dtsi +@@ -7,16 +7,6 @@ + #include + + / { +- aliases { +- serial0 = &uart4; +- serial1 = &usart3; +- serial2 = &uart8; +- }; +- +- chosen { +- stdout-path = "serial0:115200n8"; +- }; +- + led { + compatible = "gpio-leds"; + +diff --git a/arch/arm/boot/dts/st/stm32mp15xx-dhcom-som.dtsi b/arch/arm/boot/dts/st/stm32mp15xx-dhcom-som.dtsi +index 74a11ccc5333f8..142d4a8731f8d4 100644 +--- a/arch/arm/boot/dts/st/stm32mp15xx-dhcom-som.dtsi ++++ b/arch/arm/boot/dts/st/stm32mp15xx-dhcom-som.dtsi +@@ -14,6 +14,13 @@ aliases { + ethernet1 = &ksz8851; + rtc0 = &hwrtc; + rtc1 = &rtc; ++ serial0 = &uart4; ++ serial1 = &uart8; ++ serial2 = &usart3; ++ }; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; + }; + + memory@c0000000 { +diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c +index 1a26af0fabc710..22ecaf09d00f96 100644 +--- a/arch/arm/mach-at91/pm.c ++++ b/arch/arm/mach-at91/pm.c +@@ -591,7 +591,21 @@ static int at91_suspend_finish(unsigned long val) + return 0; + } + +-static void at91_pm_switch_ba_to_vbat(void) ++/** ++ * at91_pm_switch_ba_to_auto() - Configure Backup Unit Power Switch ++ * to automatic/hardware mode. ++ * ++ * The Backup Unit Power Switch can be managed either by software or hardware. ++ * Enabling hardware mode allows the automatic transition of power between ++ * VDDANA (or VDDIN33) and VDDBU (or VBAT, respectively), based on the ++ * availability of these power sources. ++ * ++ * If the Backup Unit Power Switch is already in automatic mode, no action is ++ * required. If it is in software-controlled mode, it is switched to automatic ++ * mode to enhance safety and eliminate the need for toggling between power ++ * sources. ++ */ ++static void at91_pm_switch_ba_to_auto(void) + { + unsigned int offset = offsetof(struct at91_pm_sfrbu_regs, pswbu); + unsigned int val; +@@ -602,24 +616,19 @@ static void at91_pm_switch_ba_to_vbat(void) + + val = readl(soc_pm.data.sfrbu + offset); + +- /* Already on VBAT. */ +- if (!(val & soc_pm.sfrbu_regs.pswbu.state)) ++ /* Already on auto/hardware. */ ++ if (!(val & soc_pm.sfrbu_regs.pswbu.ctrl)) + return; + +- val &= ~soc_pm.sfrbu_regs.pswbu.softsw; +- val |= soc_pm.sfrbu_regs.pswbu.key | soc_pm.sfrbu_regs.pswbu.ctrl; ++ val &= ~soc_pm.sfrbu_regs.pswbu.ctrl; ++ val |= soc_pm.sfrbu_regs.pswbu.key; + writel(val, soc_pm.data.sfrbu + offset); +- +- /* Wait for update. */ +- val = readl(soc_pm.data.sfrbu + offset); +- while (val & soc_pm.sfrbu_regs.pswbu.state) +- val = readl(soc_pm.data.sfrbu + offset); + } + + static void at91_pm_suspend(suspend_state_t state) + { + if (soc_pm.data.mode == AT91_PM_BACKUP) { +- at91_pm_switch_ba_to_vbat(); ++ at91_pm_switch_ba_to_auto(); + + cpu_suspend(0, at91_suspend_finish); + +diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c +index 3312ef93355da7..a5bf5554800fe1 100644 +--- a/arch/arm/mach-omap1/board-nokia770.c ++++ b/arch/arm/mach-omap1/board-nokia770.c +@@ -289,7 +289,7 @@ static struct gpiod_lookup_table nokia770_irq_gpio_table = { + GPIO_LOOKUP("gpio-0-15", 15, "ads7846_irq", + GPIO_ACTIVE_HIGH), + /* GPIO used for retu IRQ */ +- GPIO_LOOKUP("gpio-48-63", 15, "retu_irq", ++ GPIO_LOOKUP("gpio-48-63", 14, "retu_irq", + GPIO_ACTIVE_HIGH), + /* GPIO used for tahvo IRQ */ + GPIO_LOOKUP("gpio-32-47", 8, "tahvo_irq", +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts +index 50ed2e9f10ed08..6a69d005249441 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts +@@ -390,6 +390,8 @@ &sound { + &tcon0 { + pinctrl-names = "default"; + pinctrl-0 = <&lcd_rgb666_pins>; ++ assigned-clocks = <&ccu CLK_TCON0>; ++ assigned-clock-parents = <&ccu CLK_PLL_VIDEO0_2X>; + + status = "okay"; + }; +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts +index 1128030e4c25b5..d3e5eed84f3648 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts +@@ -369,6 +369,8 @@ &sound { + &tcon0 { + pinctrl-names = "default"; + pinctrl-0 = <&lcd_rgb666_pins>; ++ assigned-clocks = <&ccu CLK_TCON0>; ++ assigned-clock-parents = <&ccu CLK_PLL_VIDEO0_2X>; + + status = "okay"; + }; +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi +index 57ac18738c995b..7103298f6a1c27 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi ++++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi +@@ -410,6 +410,8 @@ tcon0: lcd-controller@1c0c000 { + clock-names = "ahb", "tcon-ch0"; + clock-output-names = "tcon-data-clock"; + #clock-cells = <0>; ++ assigned-clocks = <&ccu CLK_TCON0>; ++ assigned-clock-parents = <&ccu CLK_PLL_MIPI>; + resets = <&ccu RST_BUS_TCON0>, <&ccu RST_BUS_LVDS>; + reset-names = "lcd", "lvds"; + +diff --git a/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi +index 111495622cacdc..8df919d39e5ba1 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi +@@ -938,7 +938,7 @@ pmic: pmic { + interrupt-controller; + #interrupt-cells = <2>; + +- clock: mt6397clock { ++ clock: clocks { + compatible = "mediatek,mt6397-clk"; + #clock-cells = <1>; + }; +@@ -949,11 +949,10 @@ pio6397: pinctrl { + #gpio-cells = <2>; + }; + +- regulator: mt6397regulator { ++ regulators { + compatible = "mediatek,mt6397-regulator"; + + mt6397_vpca15_reg: buck_vpca15 { +- regulator-compatible = "buck_vpca15"; + regulator-name = "vpca15"; + regulator-min-microvolt = < 700000>; + regulator-max-microvolt = <1350000>; +@@ -963,7 +962,6 @@ mt6397_vpca15_reg: buck_vpca15 { + }; + + mt6397_vpca7_reg: buck_vpca7 { +- regulator-compatible = "buck_vpca7"; + regulator-name = "vpca7"; + regulator-min-microvolt = < 700000>; + regulator-max-microvolt = <1350000>; +@@ -973,7 +971,6 @@ mt6397_vpca7_reg: buck_vpca7 { + }; + + mt6397_vsramca15_reg: buck_vsramca15 { +- regulator-compatible = "buck_vsramca15"; + regulator-name = "vsramca15"; + regulator-min-microvolt = < 700000>; + regulator-max-microvolt = <1350000>; +@@ -982,7 +979,6 @@ mt6397_vsramca15_reg: buck_vsramca15 { + }; + + mt6397_vsramca7_reg: buck_vsramca7 { +- regulator-compatible = "buck_vsramca7"; + regulator-name = "vsramca7"; + regulator-min-microvolt = < 700000>; + regulator-max-microvolt = <1350000>; +@@ -991,7 +987,6 @@ mt6397_vsramca7_reg: buck_vsramca7 { + }; + + mt6397_vcore_reg: buck_vcore { +- regulator-compatible = "buck_vcore"; + regulator-name = "vcore"; + regulator-min-microvolt = < 700000>; + regulator-max-microvolt = <1350000>; +@@ -1000,7 +995,6 @@ mt6397_vcore_reg: buck_vcore { + }; + + mt6397_vgpu_reg: buck_vgpu { +- regulator-compatible = "buck_vgpu"; + regulator-name = "vgpu"; + regulator-min-microvolt = < 700000>; + regulator-max-microvolt = <1350000>; +@@ -1009,7 +1003,6 @@ mt6397_vgpu_reg: buck_vgpu { + }; + + mt6397_vdrm_reg: buck_vdrm { +- regulator-compatible = "buck_vdrm"; + regulator-name = "vdrm"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1400000>; +@@ -1018,7 +1011,6 @@ mt6397_vdrm_reg: buck_vdrm { + }; + + mt6397_vio18_reg: buck_vio18 { +- regulator-compatible = "buck_vio18"; + regulator-name = "vio18"; + regulator-min-microvolt = <1620000>; + regulator-max-microvolt = <1980000>; +@@ -1027,18 +1019,15 @@ mt6397_vio18_reg: buck_vio18 { + }; + + mt6397_vtcxo_reg: ldo_vtcxo { +- regulator-compatible = "ldo_vtcxo"; + regulator-name = "vtcxo"; + regulator-always-on; + }; + + mt6397_va28_reg: ldo_va28 { +- regulator-compatible = "ldo_va28"; + regulator-name = "va28"; + }; + + mt6397_vcama_reg: ldo_vcama { +- regulator-compatible = "ldo_vcama"; + regulator-name = "vcama"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; +@@ -1046,18 +1035,15 @@ mt6397_vcama_reg: ldo_vcama { + }; + + mt6397_vio28_reg: ldo_vio28 { +- regulator-compatible = "ldo_vio28"; + regulator-name = "vio28"; + regulator-always-on; + }; + + mt6397_vusb_reg: ldo_vusb { +- regulator-compatible = "ldo_vusb"; + regulator-name = "vusb"; + }; + + mt6397_vmc_reg: ldo_vmc { +- regulator-compatible = "ldo_vmc"; + regulator-name = "vmc"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; +@@ -1065,7 +1051,6 @@ mt6397_vmc_reg: ldo_vmc { + }; + + mt6397_vmch_reg: ldo_vmch { +- regulator-compatible = "ldo_vmch"; + regulator-name = "vmch"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3300000>; +@@ -1073,7 +1058,6 @@ mt6397_vmch_reg: ldo_vmch { + }; + + mt6397_vemc_3v3_reg: ldo_vemc3v3 { +- regulator-compatible = "ldo_vemc3v3"; + regulator-name = "vemc_3v3"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3300000>; +@@ -1081,7 +1065,6 @@ mt6397_vemc_3v3_reg: ldo_vemc3v3 { + }; + + mt6397_vgp1_reg: ldo_vgp1 { +- regulator-compatible = "ldo_vgp1"; + regulator-name = "vcamd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; +@@ -1089,7 +1072,6 @@ mt6397_vgp1_reg: ldo_vgp1 { + }; + + mt6397_vgp2_reg: ldo_vgp2 { +- regulator-compatible = "ldo_vgp2"; + regulator-name = "vcamio"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; +@@ -1097,7 +1079,6 @@ mt6397_vgp2_reg: ldo_vgp2 { + }; + + mt6397_vgp3_reg: ldo_vgp3 { +- regulator-compatible = "ldo_vgp3"; + regulator-name = "vcamaf"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; +@@ -1105,7 +1086,6 @@ mt6397_vgp3_reg: ldo_vgp3 { + }; + + mt6397_vgp4_reg: ldo_vgp4 { +- regulator-compatible = "ldo_vgp4"; + regulator-name = "vgp4"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3300000>; +@@ -1113,7 +1093,6 @@ mt6397_vgp4_reg: ldo_vgp4 { + }; + + mt6397_vgp5_reg: ldo_vgp5 { +- regulator-compatible = "ldo_vgp5"; + regulator-name = "vgp5"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3000000>; +@@ -1121,7 +1100,6 @@ mt6397_vgp5_reg: ldo_vgp5 { + }; + + mt6397_vgp6_reg: ldo_vgp6 { +- regulator-compatible = "ldo_vgp6"; + regulator-name = "vgp6"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; +@@ -1130,7 +1108,6 @@ mt6397_vgp6_reg: ldo_vgp6 { + }; + + mt6397_vibr_reg: ldo_vibr { +- regulator-compatible = "ldo_vibr"; + regulator-name = "vibr"; + regulator-min-microvolt = <1300000>; + regulator-max-microvolt = <3300000>; +@@ -1138,7 +1115,7 @@ mt6397_vibr_reg: ldo_vibr { + }; + }; + +- rtc: mt6397rtc { ++ rtc: rtc { + compatible = "mediatek,mt6397-rtc"; + }; + +diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts +index d258c80213b264..f6a70f22bd0c48 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts ++++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts +@@ -308,11 +308,10 @@ pmic: pmic { + interrupt-controller; + #interrupt-cells = <2>; + +- mt6397regulator: mt6397regulator { ++ regulators { + compatible = "mediatek,mt6397-regulator"; + + mt6397_vpca15_reg: buck_vpca15 { +- regulator-compatible = "buck_vpca15"; + regulator-name = "vpca15"; + regulator-min-microvolt = < 700000>; + regulator-max-microvolt = <1350000>; +@@ -321,7 +320,6 @@ mt6397_vpca15_reg: buck_vpca15 { + }; + + mt6397_vpca7_reg: buck_vpca7 { +- regulator-compatible = "buck_vpca7"; + regulator-name = "vpca7"; + regulator-min-microvolt = < 700000>; + regulator-max-microvolt = <1350000>; +@@ -330,7 +328,6 @@ mt6397_vpca7_reg: buck_vpca7 { + }; + + mt6397_vsramca15_reg: buck_vsramca15 { +- regulator-compatible = "buck_vsramca15"; + regulator-name = "vsramca15"; + regulator-min-microvolt = < 700000>; + regulator-max-microvolt = <1350000>; +@@ -339,7 +336,6 @@ mt6397_vsramca15_reg: buck_vsramca15 { + }; + + mt6397_vsramca7_reg: buck_vsramca7 { +- regulator-compatible = "buck_vsramca7"; + regulator-name = "vsramca7"; + regulator-min-microvolt = < 700000>; + regulator-max-microvolt = <1350000>; +@@ -348,7 +344,6 @@ mt6397_vsramca7_reg: buck_vsramca7 { + }; + + mt6397_vcore_reg: buck_vcore { +- regulator-compatible = "buck_vcore"; + regulator-name = "vcore"; + regulator-min-microvolt = < 700000>; + regulator-max-microvolt = <1350000>; +@@ -357,7 +352,6 @@ mt6397_vcore_reg: buck_vcore { + }; + + mt6397_vgpu_reg: buck_vgpu { +- regulator-compatible = "buck_vgpu"; + regulator-name = "vgpu"; + regulator-min-microvolt = < 700000>; + regulator-max-microvolt = <1350000>; +@@ -366,7 +360,6 @@ mt6397_vgpu_reg: buck_vgpu { + }; + + mt6397_vdrm_reg: buck_vdrm { +- regulator-compatible = "buck_vdrm"; + regulator-name = "vdrm"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1400000>; +@@ -375,7 +368,6 @@ mt6397_vdrm_reg: buck_vdrm { + }; + + mt6397_vio18_reg: buck_vio18 { +- regulator-compatible = "buck_vio18"; + regulator-name = "vio18"; + regulator-min-microvolt = <1620000>; + regulator-max-microvolt = <1980000>; +@@ -384,19 +376,16 @@ mt6397_vio18_reg: buck_vio18 { + }; + + mt6397_vtcxo_reg: ldo_vtcxo { +- regulator-compatible = "ldo_vtcxo"; + regulator-name = "vtcxo"; + regulator-always-on; + }; + + mt6397_va28_reg: ldo_va28 { +- regulator-compatible = "ldo_va28"; + regulator-name = "va28"; + regulator-always-on; + }; + + mt6397_vcama_reg: ldo_vcama { +- regulator-compatible = "ldo_vcama"; + regulator-name = "vcama"; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <2800000>; +@@ -404,18 +393,15 @@ mt6397_vcama_reg: ldo_vcama { + }; + + mt6397_vio28_reg: ldo_vio28 { +- regulator-compatible = "ldo_vio28"; + regulator-name = "vio28"; + regulator-always-on; + }; + + mt6397_vusb_reg: ldo_vusb { +- regulator-compatible = "ldo_vusb"; + regulator-name = "vusb"; + }; + + mt6397_vmc_reg: ldo_vmc { +- regulator-compatible = "ldo_vmc"; + regulator-name = "vmc"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; +@@ -423,7 +409,6 @@ mt6397_vmc_reg: ldo_vmc { + }; + + mt6397_vmch_reg: ldo_vmch { +- regulator-compatible = "ldo_vmch"; + regulator-name = "vmch"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3300000>; +@@ -431,7 +416,6 @@ mt6397_vmch_reg: ldo_vmch { + }; + + mt6397_vemc_3v3_reg: ldo_vemc3v3 { +- regulator-compatible = "ldo_vemc3v3"; + regulator-name = "vemc_3v3"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3300000>; +@@ -439,7 +423,6 @@ mt6397_vemc_3v3_reg: ldo_vemc3v3 { + }; + + mt6397_vgp1_reg: ldo_vgp1 { +- regulator-compatible = "ldo_vgp1"; + regulator-name = "vcamd"; + regulator-min-microvolt = <1220000>; + regulator-max-microvolt = <3300000>; +@@ -447,7 +430,6 @@ mt6397_vgp1_reg: ldo_vgp1 { + }; + + mt6397_vgp2_reg: ldo_vgp2 { +- regulator-compatible = "ldo_vgp2"; + regulator-name = "vcamio"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <3300000>; +@@ -455,7 +437,6 @@ mt6397_vgp2_reg: ldo_vgp2 { + }; + + mt6397_vgp3_reg: ldo_vgp3 { +- regulator-compatible = "ldo_vgp3"; + regulator-name = "vcamaf"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3300000>; +@@ -463,7 +444,6 @@ mt6397_vgp3_reg: ldo_vgp3 { + }; + + mt6397_vgp4_reg: ldo_vgp4 { +- regulator-compatible = "ldo_vgp4"; + regulator-name = "vgp4"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3300000>; +@@ -471,7 +451,6 @@ mt6397_vgp4_reg: ldo_vgp4 { + }; + + mt6397_vgp5_reg: ldo_vgp5 { +- regulator-compatible = "ldo_vgp5"; + regulator-name = "vgp5"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3000000>; +@@ -479,7 +458,6 @@ mt6397_vgp5_reg: ldo_vgp5 { + }; + + mt6397_vgp6_reg: ldo_vgp6 { +- regulator-compatible = "ldo_vgp6"; + regulator-name = "vgp6"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3300000>; +@@ -487,7 +465,6 @@ mt6397_vgp6_reg: ldo_vgp6 { + }; + + mt6397_vibr_reg: ldo_vibr { +- regulator-compatible = "ldo_vibr"; + regulator-name = "vibr"; + regulator-min-microvolt = <1300000>; + regulator-max-microvolt = <3300000>; +diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-damu.dts b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-damu.dts +index 9a166dccd727c7..8f95b7270c3fa8 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-damu.dts ++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-damu.dts +@@ -27,6 +27,10 @@ &touchscreen { + hid-descr-addr = <0x0001>; + }; + ++&mt6358codec { ++ mediatek,dmic-mode = <1>; /* one-wire */ ++}; ++ + &qca_wifi { + qcom,ath10k-calibration-variant = "GO_DAMU"; + }; +diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-kenzo.dts b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-kenzo.dts +index 8fa89db03e6399..328294245a79d2 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-kenzo.dts ++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-kenzo.dts +@@ -11,3 +11,18 @@ / { + model = "Google kenzo sku17 board"; + compatible = "google,juniper-sku17", "google,juniper", "mediatek,mt8183"; + }; ++ ++&i2c0 { ++ touchscreen@40 { ++ compatible = "hid-over-i2c"; ++ reg = <0x40>; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&touchscreen_pins>; ++ ++ interrupts-extended = <&pio 155 IRQ_TYPE_LEVEL_LOW>; ++ ++ post-power-on-delay-ms = <70>; ++ hid-descr-addr = <0x0001>; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-willow.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-willow.dtsi +index 76d33540166f90..c942e461a177ef 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-willow.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-willow.dtsi +@@ -6,6 +6,21 @@ + /dts-v1/; + #include "mt8183-kukui-jacuzzi.dtsi" + ++&i2c0 { ++ touchscreen@40 { ++ compatible = "hid-over-i2c"; ++ reg = <0x40>; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&touchscreen_pins>; ++ ++ interrupts-extended = <&pio 155 IRQ_TYPE_LEVEL_LOW>; ++ ++ post-power-on-delay-ms = <70>; ++ hid-descr-addr = <0x0001>; ++ }; ++}; ++ + &i2c2 { + trackpad@2c { + compatible = "hid-over-i2c"; +diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi +index 629c4b7ecbc629..8e0575f8c1b275 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi +@@ -39,8 +39,6 @@ pp1800_mipibrdg: pp1800-mipibrdg { + pp3300_panel: pp3300-panel { + compatible = "regulator-fixed"; + regulator-name = "pp3300_panel"; +- regulator-min-microvolt = <3300000>; +- regulator-max-microvolt = <3300000>; + pinctrl-names = "default"; + pinctrl-0 = <&pp3300_panel_pins>; + +diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi +index 8721a5ffca30a7..d1b6355148620b 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi +@@ -1026,7 +1026,8 @@ pwrap: pwrap@1000d000 { + }; + + keyboard: keyboard@10010000 { +- compatible = "mediatek,mt6779-keypad"; ++ compatible = "mediatek,mt8183-keypad", ++ "mediatek,mt6779-keypad"; + reg = <0 0x10010000 0 0x1000>; + interrupts = ; + clocks = <&clk26m>; +diff --git a/arch/arm64/boot/dts/mediatek/mt8186.dtsi b/arch/arm64/boot/dts/mediatek/mt8186.dtsi +index 2c184f9e0fc390..a63c59bc8e9782 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8186.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8186.dtsi +@@ -1545,6 +1545,8 @@ ssusb0: usb@11201000 { + #address-cells = <2>; + #size-cells = <2>; + ranges; ++ wakeup-source; ++ mediatek,syscon-wakeup = <&pericfg 0x420 2>; + status = "disabled"; + + usb_host0: usb@11200000 { +@@ -1558,8 +1560,6 @@ usb_host0: usb@11200000 { + <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_XHCI>; + clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck", "xhci_ck"; + interrupts = ; +- mediatek,syscon-wakeup = <&pericfg 0x420 2>; +- wakeup-source; + status = "disabled"; + }; + }; +@@ -1611,6 +1611,8 @@ ssusb1: usb@11281000 { + #address-cells = <2>; + #size-cells = <2>; + ranges; ++ wakeup-source; ++ mediatek,syscon-wakeup = <&pericfg 0x424 2>; + status = "disabled"; + + usb_host1: usb@11280000 { +@@ -1624,8 +1626,6 @@ usb_host1: usb@11280000 { + <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_P1_XHCI>; + clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck","xhci_ck"; + interrupts = ; +- mediatek,syscon-wakeup = <&pericfg 0x424 2>; +- wakeup-source; + status = "disabled"; + }; + }; +diff --git a/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi b/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi +index 6b4b7a7cd35efb..54e3ec168fa9a4 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi +@@ -1391,7 +1391,6 @@ mt6315_6: pmic@6 { + + regulators { + mt6315_6_vbuck1: vbuck1 { +- regulator-compatible = "vbuck1"; + regulator-name = "Vbcpu"; + regulator-min-microvolt = <400000>; + regulator-max-microvolt = <1193750>; +@@ -1401,7 +1400,6 @@ mt6315_6_vbuck1: vbuck1 { + }; + + mt6315_6_vbuck3: vbuck3 { +- regulator-compatible = "vbuck3"; + regulator-name = "Vlcpu"; + regulator-min-microvolt = <400000>; + regulator-max-microvolt = <1193750>; +@@ -1418,7 +1416,6 @@ mt6315_7: pmic@7 { + + regulators { + mt6315_7_vbuck1: vbuck1 { +- regulator-compatible = "vbuck1"; + regulator-name = "Vgpu"; + regulator-min-microvolt = <400000>; + regulator-max-microvolt = <800000>; +diff --git a/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi b/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi +index b21663b46b5192..e3b30543c2c647 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi +@@ -1203,7 +1203,6 @@ mt6315@6 { + + regulators { + mt6315_6_vbuck1: vbuck1 { +- regulator-compatible = "vbuck1"; + regulator-name = "Vbcpu"; + regulator-min-microvolt = <400000>; + regulator-max-microvolt = <1193750>; +@@ -1221,7 +1220,6 @@ mt6315@7 { + + regulators { + mt6315_7_vbuck1: vbuck1 { +- regulator-compatible = "vbuck1"; + regulator-name = "Vgpu"; + regulator-min-microvolt = <400000>; + regulator-max-microvolt = <1193750>; +diff --git a/arch/arm64/boot/dts/mediatek/mt8195-demo.dts b/arch/arm64/boot/dts/mediatek/mt8195-demo.dts +index 9079e48aea23ea..f56aeb81c4168f 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8195-demo.dts ++++ b/arch/arm64/boot/dts/mediatek/mt8195-demo.dts +@@ -137,7 +137,6 @@ charger { + richtek,vinovp-microvolt = <14500000>; + + otg_vbus_regulator: usb-otg-vbus-regulator { +- regulator-compatible = "usb-otg-vbus"; + regulator-name = "usb-otg-vbus"; + regulator-min-microvolt = <4425000>; + regulator-max-microvolt = <5825000>; +@@ -149,7 +148,6 @@ regulator { + LDO_VIN3-supply = <&mt6360_buck2>; + + mt6360_buck1: buck1 { +- regulator-compatible = "BUCK1"; + regulator-name = "mt6360,buck1"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1300000>; +@@ -160,7 +158,6 @@ MT6360_OPMODE_LP + }; + + mt6360_buck2: buck2 { +- regulator-compatible = "BUCK2"; + regulator-name = "mt6360,buck2"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1300000>; +@@ -171,7 +168,6 @@ MT6360_OPMODE_LP + }; + + mt6360_ldo1: ldo1 { +- regulator-compatible = "LDO1"; + regulator-name = "mt6360,ldo1"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3600000>; +@@ -180,7 +176,6 @@ mt6360_ldo1: ldo1 { + }; + + mt6360_ldo2: ldo2 { +- regulator-compatible = "LDO2"; + regulator-name = "mt6360,ldo2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3600000>; +@@ -189,7 +184,6 @@ mt6360_ldo2: ldo2 { + }; + + mt6360_ldo3: ldo3 { +- regulator-compatible = "LDO3"; + regulator-name = "mt6360,ldo3"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3600000>; +@@ -198,7 +192,6 @@ mt6360_ldo3: ldo3 { + }; + + mt6360_ldo5: ldo5 { +- regulator-compatible = "LDO5"; + regulator-name = "mt6360,ldo5"; + regulator-min-microvolt = <2700000>; + regulator-max-microvolt = <3600000>; +@@ -207,7 +200,6 @@ mt6360_ldo5: ldo5 { + }; + + mt6360_ldo6: ldo6 { +- regulator-compatible = "LDO6"; + regulator-name = "mt6360,ldo6"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <2100000>; +@@ -216,7 +208,6 @@ mt6360_ldo6: ldo6 { + }; + + mt6360_ldo7: ldo7 { +- regulator-compatible = "LDO7"; + regulator-name = "mt6360,ldo7"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <2100000>; +diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi +index 5a087404ccc2d9..7ba30209ba9a9a 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi +@@ -1572,9 +1572,6 @@ pcie1: pcie@112f8000 { + phy-names = "pcie-phy"; + power-domains = <&spm MT8195_POWER_DOMAIN_PCIE_MAC_P1>; + +- resets = <&infracfg_ao MT8195_INFRA_RST2_PCIE_P1_SWRST>; +- reset-names = "mac"; +- + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &pcie_intc1 0>, +@@ -2680,7 +2677,7 @@ larb20: larb@1b010000 { + }; + + ovl0: ovl@1c000000 { +- compatible = "mediatek,mt8195-disp-ovl", "mediatek,mt8183-disp-ovl"; ++ compatible = "mediatek,mt8195-disp-ovl"; + reg = <0 0x1c000000 0 0x1000>; + interrupts = ; + power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>; +diff --git a/arch/arm64/boot/dts/mediatek/mt8365.dtsi b/arch/arm64/boot/dts/mediatek/mt8365.dtsi +index 413496c9206954..62c5b50d3c5fbe 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8365.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8365.dtsi +@@ -334,7 +334,8 @@ pwrap: pwrap@1000d000 { + }; + + keypad: keypad@10010000 { +- compatible = "mediatek,mt6779-keypad"; ++ compatible = "mediatek,mt8365-keypad", ++ "mediatek,mt6779-keypad"; + reg = <0 0x10010000 0 0x1000>; + wakeup-source; + interrupts = ; +diff --git a/arch/arm64/boot/dts/mediatek/mt8516.dtsi b/arch/arm64/boot/dts/mediatek/mt8516.dtsi +index 9cbd6dd8f671aa..6b89505a64379f 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8516.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8516.dtsi +@@ -144,10 +144,10 @@ reserved-memory { + #size-cells = <2>; + ranges; + +- /* 128 KiB reserved for ARM Trusted Firmware (BL31) */ ++ /* 192 KiB reserved for ARM Trusted Firmware (BL31) */ + bl31_secmon_reserved: secmon@43000000 { + no-map; +- reg = <0 0x43000000 0 0x20000>; ++ reg = <0 0x43000000 0 0x30000>; + }; + }; + +@@ -206,7 +206,7 @@ watchdog@10007000 { + compatible = "mediatek,mt8516-wdt", + "mediatek,mt6589-wdt"; + reg = <0 0x10007000 0 0x1000>; +- interrupts = ; ++ interrupts = ; + #reset-cells = <1>; + }; + +@@ -268,7 +268,7 @@ gic: interrupt-controller@10310000 { + interrupt-parent = <&gic>; + interrupt-controller; + reg = <0 0x10310000 0 0x1000>, +- <0 0x10320000 0 0x1000>, ++ <0 0x1032f000 0 0x2000>, + <0 0x10340000 0 0x2000>, + <0 0x10360000 0 0x2000>; + interrupts = , + <0 0x11000180 0 0x80>; + interrupts = ; ++ clock-div = <2>; + clocks = <&topckgen CLK_TOP_I2C0>, + <&topckgen CLK_TOP_APDMA>; + clock-names = "main", "dma"; +@@ -358,6 +359,7 @@ i2c1: i2c@1100a000 { + reg = <0 0x1100a000 0 0x90>, + <0 0x11000200 0 0x80>; + interrupts = ; ++ clock-div = <2>; + clocks = <&topckgen CLK_TOP_I2C1>, + <&topckgen CLK_TOP_APDMA>; + clock-names = "main", "dma"; +@@ -372,6 +374,7 @@ i2c2: i2c@1100b000 { + reg = <0 0x1100b000 0 0x90>, + <0 0x11000280 0 0x80>; + interrupts = ; ++ clock-div = <2>; + clocks = <&topckgen CLK_TOP_I2C2>, + <&topckgen CLK_TOP_APDMA>; + clock-names = "main", "dma"; +diff --git a/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi b/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi +index ec8dfb3d1c6d69..a356db5fcc5f3c 100644 +--- a/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi ++++ b/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi +@@ -47,7 +47,6 @@ key-volume-down { + }; + + &i2c0 { +- clock-div = <2>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins_a>; + status = "okay"; +@@ -156,7 +155,6 @@ cam-pwdn-hog { + }; + + &i2c2 { +- clock-div = <2>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins_a>; + status = "okay"; +diff --git a/arch/arm64/boot/dts/nvidia/tegra234.dtsi b/arch/arm64/boot/dts/nvidia/tegra234.dtsi +index ac69eacf8a6ba9..be30072fb7471f 100644 +--- a/arch/arm64/boot/dts/nvidia/tegra234.dtsi ++++ b/arch/arm64/boot/dts/nvidia/tegra234.dtsi +@@ -1794,7 +1794,7 @@ spi@c260000 { + assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLP_OUT0>; + resets = <&bpmp TEGRA234_RESET_SPI2>; + reset-names = "spi"; +- dmas = <&gpcdma 19>, <&gpcdma 19>; ++ dmas = <&gpcdma 16>, <&gpcdma 16>; + dma-names = "rx", "tx"; + dma-coherent; + status = "disabled"; +diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile +index 2cca20563a1d69..0da076db0418d8 100644 +--- a/arch/arm64/boot/dts/qcom/Makefile ++++ b/arch/arm64/boot/dts/qcom/Makefile +@@ -171,6 +171,9 @@ dtb-$(CONFIG_ARCH_QCOM) += sdm845-cheza-r1.dtb + dtb-$(CONFIG_ARCH_QCOM) += sdm845-cheza-r2.dtb + dtb-$(CONFIG_ARCH_QCOM) += sdm845-cheza-r3.dtb + dtb-$(CONFIG_ARCH_QCOM) += sdm845-db845c.dtb ++ ++sdm845-db845c-navigation-mezzanine-dtbs := sdm845-db845c.dtb sdm845-db845c-navigation-mezzanine.dtbo ++ + dtb-$(CONFIG_ARCH_QCOM) += sdm845-db845c-navigation-mezzanine.dtb + dtb-$(CONFIG_ARCH_QCOM) += sdm845-lg-judyln.dtb + dtb-$(CONFIG_ARCH_QCOM) += sdm845-lg-judyp.dtb +diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi +index 961ceb83a91fae..6f5f96853ba1c2 100644 +--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi ++++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi +@@ -104,7 +104,7 @@ xo_board: xo-board { + sleep_clk: sleep-clk { + compatible = "fixed-clock"; + #clock-cells = <0>; +- clock-frequency = <32768>; ++ clock-frequency = <32764>; + }; + }; + +diff --git a/arch/arm64/boot/dts/qcom/msm8939.dtsi b/arch/arm64/boot/dts/qcom/msm8939.dtsi +index 3fd64cafe99c5f..c844e01f9aa15b 100644 +--- a/arch/arm64/boot/dts/qcom/msm8939.dtsi ++++ b/arch/arm64/boot/dts/qcom/msm8939.dtsi +@@ -33,7 +33,7 @@ xo_board: xo-board { + sleep_clk: sleep-clk { + compatible = "fixed-clock"; + #clock-cells = <0>; +- clock-frequency = <32768>; ++ clock-frequency = <32764>; + }; + }; + +diff --git a/arch/arm64/boot/dts/qcom/msm8994.dtsi b/arch/arm64/boot/dts/qcom/msm8994.dtsi +index c3262571520d3e..a7f9259dda6de3 100644 +--- a/arch/arm64/boot/dts/qcom/msm8994.dtsi ++++ b/arch/arm64/boot/dts/qcom/msm8994.dtsi +@@ -34,7 +34,7 @@ xo_board: xo-board { + sleep_clk: sleep-clk { + compatible = "fixed-clock"; + #clock-cells = <0>; +- clock-frequency = <32768>; ++ clock-frequency = <32764>; + clock-output-names = "sleep_clk"; + }; + }; +@@ -437,6 +437,15 @@ usb3: usb@f92f8800 { + #size-cells = <1>; + ranges; + ++ interrupts = , ++ , ++ , ++ ; ++ interrupt-names = "pwr_event", ++ "qusb2_phy", ++ "hs_phy_irq", ++ "ss_phy_irq"; ++ + clocks = <&gcc GCC_USB30_MASTER_CLK>, + <&gcc GCC_SYS_NOC_USB3_AXI_CLK>, + <&gcc GCC_USB30_SLEEP_CLK>, +diff --git a/arch/arm64/boot/dts/qcom/msm8996-xiaomi-gemini.dts b/arch/arm64/boot/dts/qcom/msm8996-xiaomi-gemini.dts +index f8e9d90afab000..dbad8f57f2fa34 100644 +--- a/arch/arm64/boot/dts/qcom/msm8996-xiaomi-gemini.dts ++++ b/arch/arm64/boot/dts/qcom/msm8996-xiaomi-gemini.dts +@@ -64,7 +64,7 @@ led@0 { + }; + + led@1 { +- reg = <0>; ++ reg = <1>; + chan-name = "button-backlight1"; + led-cur = /bits/ 8 <0x32>; + max-cur = /bits/ 8 <0xc8>; +diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi +index 1f7cbb35886db5..70ef8c83e7b9f3 100644 +--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi ++++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi +@@ -3046,9 +3046,14 @@ usb3: usb@6af8800 { + #size-cells = <1>; + ranges; + +- interrupts = , ++ interrupts = , ++ , ++ , + ; +- interrupt-names = "hs_phy_irq", "ss_phy_irq"; ++ interrupt-names = "pwr_event", ++ "qusb2_phy", ++ "hs_phy_irq", ++ "ss_phy_irq"; + + clocks = <&gcc GCC_SYS_NOC_USB3_AXI_CLK>, + <&gcc GCC_USB30_MASTER_CLK>, +diff --git a/arch/arm64/boot/dts/qcom/pm6150.dtsi b/arch/arm64/boot/dts/qcom/pm6150.dtsi +index 7d4d1f2767ed6a..7ae14c53ca8fb3 100644 +--- a/arch/arm64/boot/dts/qcom/pm6150.dtsi ++++ b/arch/arm64/boot/dts/qcom/pm6150.dtsi +@@ -13,7 +13,7 @@ / { + thermal-zones { + pm6150_thermal: pm6150-thermal { + polling-delay-passive = <100>; +- polling-delay = <0>; ++ + thermal-sensors = <&pm6150_temp>; + + trips { +diff --git a/arch/arm64/boot/dts/qcom/pm6150l.dtsi b/arch/arm64/boot/dts/qcom/pm6150l.dtsi +index d13a1ab7c20b34..a20e9b9993b28f 100644 +--- a/arch/arm64/boot/dts/qcom/pm6150l.dtsi ++++ b/arch/arm64/boot/dts/qcom/pm6150l.dtsi +@@ -10,9 +10,6 @@ + / { + thermal-zones { + pm6150l-thermal { +- polling-delay-passive = <0>; +- polling-delay = <0>; +- + thermal-sensors = <&pm6150l_temp>; + + trips { +diff --git a/arch/arm64/boot/dts/qcom/qcs404.dtsi b/arch/arm64/boot/dts/qcom/qcs404.dtsi +index 2721f32dfb7104..cbe469cc159e92 100644 +--- a/arch/arm64/boot/dts/qcom/qcs404.dtsi ++++ b/arch/arm64/boot/dts/qcom/qcs404.dtsi +@@ -28,7 +28,7 @@ xo_board: xo-board { + sleep_clk: sleep-clk { + compatible = "fixed-clock"; + #clock-cells = <0>; +- clock-frequency = <32768>; ++ clock-frequency = <32764>; + }; + }; + +diff --git a/arch/arm64/boot/dts/qcom/qdu1000-idp.dts b/arch/arm64/boot/dts/qcom/qdu1000-idp.dts +index 5a25cdec969eb1..409f06978931af 100644 +--- a/arch/arm64/boot/dts/qcom/qdu1000-idp.dts ++++ b/arch/arm64/boot/dts/qcom/qdu1000-idp.dts +@@ -31,7 +31,7 @@ xo_board: xo-board-clk { + + sleep_clk: sleep-clk { + compatible = "fixed-clock"; +- clock-frequency = <32000>; ++ clock-frequency = <32764>; + #clock-cells = <0>; + }; + }; +diff --git a/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts b/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts +index 5def8c1154ceb3..331b6a76560db4 100644 +--- a/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts ++++ b/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts +@@ -492,7 +492,7 @@ can@0 { + }; + + &sleep_clk { +- clock-frequency = <32000>; ++ clock-frequency = <32764>; + }; + + &tlmm { +diff --git a/arch/arm64/boot/dts/qcom/qru1000-idp.dts b/arch/arm64/boot/dts/qcom/qru1000-idp.dts +index 2a862c83309e70..a3a7dcbc5e6d29 100644 +--- a/arch/arm64/boot/dts/qcom/qru1000-idp.dts ++++ b/arch/arm64/boot/dts/qcom/qru1000-idp.dts +@@ -31,7 +31,7 @@ xo_board: xo-board-clk { + + sleep_clk: sleep-clk { + compatible = "fixed-clock"; +- clock-frequency = <32000>; ++ clock-frequency = <32764>; + #clock-cells = <0>; + }; + }; +diff --git a/arch/arm64/boot/dts/qcom/sa8775p-ride.dts b/arch/arm64/boot/dts/qcom/sa8775p-ride.dts +index 81a7eeb9cfcd27..2e87fd760dbdde 100644 +--- a/arch/arm64/boot/dts/qcom/sa8775p-ride.dts ++++ b/arch/arm64/boot/dts/qcom/sa8775p-ride.dts +@@ -5,828 +5,43 @@ + + /dts-v1/; + +-#include +-#include +- +-#include "sa8775p.dtsi" +-#include "sa8775p-pmics.dtsi" ++#include "sa8775p-ride.dtsi" + + / { + model = "Qualcomm SA8775P Ride"; + compatible = "qcom,sa8775p-ride", "qcom,sa8775p"; +- +- aliases { +- ethernet0 = ðernet0; +- ethernet1 = ðernet1; +- i2c11 = &i2c11; +- i2c18 = &i2c18; +- serial0 = &uart10; +- serial1 = &uart12; +- serial2 = &uart17; +- spi16 = &spi16; +- ufshc1 = &ufs_mem_hc; +- }; +- +- chosen { +- stdout-path = "serial0:115200n8"; +- }; +-}; +- +-&apps_rsc { +- regulators-0 { +- compatible = "qcom,pmm8654au-rpmh-regulators"; +- qcom,pmic-id = "a"; +- +- vreg_s4a: smps4 { +- regulator-name = "vreg_s4a"; +- regulator-min-microvolt = <1800000>; +- regulator-max-microvolt = <1816000>; +- regulator-initial-mode = ; +- }; +- +- vreg_s5a: smps5 { +- regulator-name = "vreg_s5a"; +- regulator-min-microvolt = <1850000>; +- regulator-max-microvolt = <1996000>; +- regulator-initial-mode = ; +- }; +- +- vreg_s9a: smps9 { +- regulator-name = "vreg_s9a"; +- regulator-min-microvolt = <535000>; +- regulator-max-microvolt = <1120000>; +- regulator-initial-mode = ; +- }; +- +- vreg_l4a: ldo4 { +- regulator-name = "vreg_l4a"; +- regulator-min-microvolt = <788000>; +- regulator-max-microvolt = <1050000>; +- regulator-initial-mode = ; +- regulator-allow-set-load; +- regulator-allowed-modes = ; +- }; +- +- vreg_l5a: ldo5 { +- regulator-name = "vreg_l5a"; +- regulator-min-microvolt = <870000>; +- regulator-max-microvolt = <950000>; +- regulator-initial-mode = ; +- regulator-allow-set-load; +- regulator-allowed-modes = ; +- }; +- +- vreg_l6a: ldo6 { +- regulator-name = "vreg_l6a"; +- regulator-min-microvolt = <870000>; +- regulator-max-microvolt = <970000>; +- regulator-initial-mode = ; +- regulator-allow-set-load; +- regulator-allowed-modes = ; +- }; +- +- vreg_l7a: ldo7 { +- regulator-name = "vreg_l7a"; +- regulator-min-microvolt = <720000>; +- regulator-max-microvolt = <950000>; +- regulator-initial-mode = ; +- regulator-allow-set-load; +- regulator-allowed-modes = ; +- }; +- +- vreg_l8a: ldo8 { +- regulator-name = "vreg_l8a"; +- regulator-min-microvolt = <2504000>; +- regulator-max-microvolt = <3300000>; +- regulator-initial-mode = ; +- regulator-allow-set-load; +- regulator-allowed-modes = ; +- }; +- +- vreg_l9a: ldo9 { +- regulator-name = "vreg_l9a"; +- regulator-min-microvolt = <2970000>; +- regulator-max-microvolt = <3544000>; +- regulator-initial-mode = ; +- regulator-allow-set-load; +- regulator-allowed-modes = ; +- }; +- }; +- +- regulators-1 { +- compatible = "qcom,pmm8654au-rpmh-regulators"; +- qcom,pmic-id = "c"; +- +- vreg_l1c: ldo1 { +- regulator-name = "vreg_l1c"; +- regulator-min-microvolt = <1140000>; +- regulator-max-microvolt = <1260000>; +- regulator-initial-mode = ; +- regulator-allow-set-load; +- regulator-allowed-modes = ; +- }; +- +- vreg_l2c: ldo2 { +- regulator-name = "vreg_l2c"; +- regulator-min-microvolt = <900000>; +- regulator-max-microvolt = <1100000>; +- regulator-initial-mode = ; +- regulator-allow-set-load; +- regulator-allowed-modes = ; +- }; +- +- vreg_l3c: ldo3 { +- regulator-name = "vreg_l3c"; +- regulator-min-microvolt = <1100000>; +- regulator-max-microvolt = <1300000>; +- regulator-initial-mode = ; +- regulator-allow-set-load; +- regulator-allowed-modes = ; +- }; +- +- vreg_l4c: ldo4 { +- regulator-name = "vreg_l4c"; +- regulator-min-microvolt = <1200000>; +- regulator-max-microvolt = <1200000>; +- regulator-initial-mode = ; +- /* +- * FIXME: This should have regulator-allow-set-load but +- * we're getting an over-current fault from the PMIC +- * when switching to LPM. +- */ +- }; +- +- vreg_l5c: ldo5 { +- regulator-name = "vreg_l5c"; +- regulator-min-microvolt = <1100000>; +- regulator-max-microvolt = <1300000>; +- regulator-initial-mode = ; +- regulator-allow-set-load; +- regulator-allowed-modes = ; +- }; +- +- vreg_l6c: ldo6 { +- regulator-name = "vreg_l6c"; +- regulator-min-microvolt = <1620000>; +- regulator-max-microvolt = <1980000>; +- regulator-initial-mode = ; +- regulator-allow-set-load; +- regulator-allowed-modes = ; +- }; +- +- vreg_l7c: ldo7 { +- regulator-name = "vreg_l7c"; +- regulator-min-microvolt = <1620000>; +- regulator-max-microvolt = <2000000>; +- regulator-initial-mode = ; +- regulator-allow-set-load; +- regulator-allowed-modes = ; +- }; +- +- vreg_l8c: ldo8 { +- regulator-name = "vreg_l8c"; +- regulator-min-microvolt = <2400000>; +- regulator-max-microvolt = <3300000>; +- regulator-initial-mode = ; +- regulator-allow-set-load; +- regulator-allowed-modes = ; +- }; +- +- vreg_l9c: ldo9 { +- regulator-name = "vreg_l9c"; +- regulator-min-microvolt = <1650000>; +- regulator-max-microvolt = <2700000>; +- regulator-initial-mode = ; +- regulator-allow-set-load; +- regulator-allowed-modes = ; +- }; +- }; +- +- regulators-2 { +- compatible = "qcom,pmm8654au-rpmh-regulators"; +- qcom,pmic-id = "e"; +- +- vreg_s4e: smps4 { +- regulator-name = "vreg_s4e"; +- regulator-min-microvolt = <970000>; +- regulator-max-microvolt = <1520000>; +- regulator-initial-mode = ; +- }; +- +- vreg_s7e: smps7 { +- regulator-name = "vreg_s7e"; +- regulator-min-microvolt = <1010000>; +- regulator-max-microvolt = <1170000>; +- regulator-initial-mode = ; +- }; +- +- vreg_s9e: smps9 { +- regulator-name = "vreg_s9e"; +- regulator-min-microvolt = <300000>; +- regulator-max-microvolt = <570000>; +- regulator-initial-mode = ; +- }; +- +- vreg_l6e: ldo6 { +- regulator-name = "vreg_l6e"; +- regulator-min-microvolt = <1280000>; +- regulator-max-microvolt = <1450000>; +- regulator-initial-mode = ; +- regulator-allow-set-load; +- regulator-allowed-modes = ; +- }; +- +- vreg_l8e: ldo8 { +- regulator-name = "vreg_l8e"; +- regulator-min-microvolt = <1800000>; +- regulator-max-microvolt = <1950000>; +- regulator-initial-mode = ; +- regulator-allow-set-load; +- regulator-allowed-modes = ; +- }; +- }; + }; + + ðernet0 { + phy-mode = "sgmii"; +- phy-handle = <&sgmii_phy0>; +- +- pinctrl-0 = <ðernet0_default>; +- pinctrl-names = "default"; +- +- snps,mtl-rx-config = <&mtl_rx_setup>; +- snps,mtl-tx-config = <&mtl_tx_setup>; +- snps,ps-speed = <1000>; +- +- status = "okay"; +- +- mdio { +- compatible = "snps,dwmac-mdio"; +- #address-cells = <1>; +- #size-cells = <0>; +- +- sgmii_phy0: phy@8 { +- compatible = "ethernet-phy-id0141.0dd4"; +- reg = <0x8>; +- device_type = "ethernet-phy"; +- reset-gpios = <&pmm8654au_2_gpios 8 GPIO_ACTIVE_LOW>; +- reset-assert-us = <11000>; +- reset-deassert-us = <70000>; +- }; +- +- sgmii_phy1: phy@a { +- compatible = "ethernet-phy-id0141.0dd4"; +- reg = <0xa>; +- device_type = "ethernet-phy"; +- reset-gpios = <&pmm8654au_2_gpios 9 GPIO_ACTIVE_LOW>; +- reset-assert-us = <11000>; +- reset-deassert-us = <70000>; +- }; +- }; +- +- mtl_rx_setup: rx-queues-config { +- snps,rx-queues-to-use = <4>; +- snps,rx-sched-sp; +- +- queue0 { +- snps,dcb-algorithm; +- snps,map-to-dma-channel = <0x0>; +- snps,route-up; +- snps,priority = <0x1>; +- }; +- +- queue1 { +- snps,dcb-algorithm; +- snps,map-to-dma-channel = <0x1>; +- snps,route-ptp; +- }; +- +- queue2 { +- snps,avb-algorithm; +- snps,map-to-dma-channel = <0x2>; +- snps,route-avcp; +- }; +- +- queue3 { +- snps,avb-algorithm; +- snps,map-to-dma-channel = <0x3>; +- snps,priority = <0xc>; +- }; +- }; +- +- mtl_tx_setup: tx-queues-config { +- snps,tx-queues-to-use = <4>; +- snps,tx-sched-sp; +- +- queue0 { +- snps,dcb-algorithm; +- }; +- +- queue1 { +- snps,dcb-algorithm; +- }; +- +- queue2 { +- snps,avb-algorithm; +- snps,send_slope = <0x1000>; +- snps,idle_slope = <0x1000>; +- snps,high_credit = <0x3e800>; +- snps,low_credit = <0xffc18000>; +- }; +- +- queue3 { +- snps,avb-algorithm; +- snps,send_slope = <0x1000>; +- snps,idle_slope = <0x1000>; +- snps,high_credit = <0x3e800>; +- snps,low_credit = <0xffc18000>; +- }; +- }; + }; + + ðernet1 { + phy-mode = "sgmii"; +- phy-handle = <&sgmii_phy1>; +- +- snps,mtl-rx-config = <&mtl_rx_setup1>; +- snps,mtl-tx-config = <&mtl_tx_setup1>; +- snps,ps-speed = <1000>; +- +- status = "okay"; +- +- mtl_rx_setup1: rx-queues-config { +- snps,rx-queues-to-use = <4>; +- snps,rx-sched-sp; +- +- queue0 { +- snps,dcb-algorithm; +- snps,map-to-dma-channel = <0x0>; +- snps,route-up; +- snps,priority = <0x1>; +- }; +- +- queue1 { +- snps,dcb-algorithm; +- snps,map-to-dma-channel = <0x1>; +- snps,route-ptp; +- }; +- +- queue2 { +- snps,avb-algorithm; +- snps,map-to-dma-channel = <0x2>; +- snps,route-avcp; +- }; +- +- queue3 { +- snps,avb-algorithm; +- snps,map-to-dma-channel = <0x3>; +- snps,priority = <0xc>; +- }; +- }; +- +- mtl_tx_setup1: tx-queues-config { +- snps,tx-queues-to-use = <4>; +- snps,tx-sched-sp; +- +- queue0 { +- snps,dcb-algorithm; +- }; +- +- queue1 { +- snps,dcb-algorithm; +- }; +- +- queue2 { +- snps,avb-algorithm; +- snps,send_slope = <0x1000>; +- snps,idle_slope = <0x1000>; +- snps,high_credit = <0x3e800>; +- snps,low_credit = <0xffc18000>; +- }; +- +- queue3 { +- snps,avb-algorithm; +- snps,send_slope = <0x1000>; +- snps,idle_slope = <0x1000>; +- snps,high_credit = <0x3e800>; +- snps,low_credit = <0xffc18000>; +- }; +- }; +-}; +- +-&i2c11 { +- clock-frequency = <400000>; +- pinctrl-0 = <&qup_i2c11_default>; +- pinctrl-names = "default"; +- status = "okay"; +-}; +- +-&i2c18 { +- clock-frequency = <400000>; +- pinctrl-0 = <&qup_i2c18_default>; +- pinctrl-names = "default"; +- status = "okay"; +-}; +- +-&pmm8654au_0_gpios { +- gpio-line-names = "DS_EN", +- "POFF_COMPLETE", +- "UFS0_VER_ID", +- "FAST_POFF", +- "DBU1_PON_DONE", +- "AOSS_SLEEP", +- "CAM_DES0_EN", +- "CAM_DES1_EN", +- "CAM_DES2_EN", +- "CAM_DES3_EN", +- "UEFI", +- "ANALOG_PON_OPT"; +-}; +- +-&pmm8654au_1_gpios { +- gpio-line-names = "PMIC_C_ID0", +- "PMIC_C_ID1", +- "UFS1_VER_ID", +- "IPA_PWR", +- "", +- "WLAN_DBU4_EN", +- "WLAN_EN", +- "BT_EN", +- "USB2_PWR_EN", +- "USB2_FAULT"; +- +- usb2_en_state: usb2-en-state { +- pins = "gpio9"; +- function = "normal"; +- output-high; +- power-source = <0>; +- }; +-}; +- +-&pmm8654au_2_gpios { +- gpio-line-names = "PMIC_E_ID0", +- "PMIC_E_ID1", +- "USB0_PWR_EN", +- "USB0_FAULT", +- "SENSOR_IRQ_1", +- "SENSOR_IRQ_2", +- "SENSOR_RST", +- "SGMIIO0_RST", +- "SGMIIO1_RST", +- "USB1_PWR_ENABLE", +- "USB1_FAULT", +- "VMON_SPX8"; +- +- usb0_en_state: usb0-en-state { +- pins = "gpio3"; +- function = "normal"; +- output-high; +- power-source = <0>; +- }; +- +- usb1_en_state: usb1-en-state { +- pins = "gpio10"; +- function = "normal"; +- output-high; +- power-source = <0>; +- }; +-}; +- +-&pmm8654au_3_gpios { +- gpio-line-names = "PMIC_G_ID0", +- "PMIC_G_ID1", +- "GNSS_RST", +- "GNSS_EN", +- "GNSS_BOOT_MODE"; +-}; +- +-&qupv3_id_1 { +- status = "okay"; +-}; +- +-&qupv3_id_2 { +- status = "okay"; + }; + +-&serdes0 { +- phy-supply = <&vreg_l5a>; +- status = "okay"; +-}; +- +-&serdes1 { +- phy-supply = <&vreg_l5a>; +- status = "okay"; +-}; +- +-&sleep_clk { +- clock-frequency = <32764>; +-}; +- +-&spi16 { +- pinctrl-0 = <&qup_spi16_default>; +- pinctrl-names = "default"; +- status = "okay"; +-}; +- +-&tlmm { +- ethernet0_default: ethernet0-default-state { +- ethernet0_mdc: ethernet0-mdc-pins { +- pins = "gpio8"; +- function = "emac0_mdc"; +- drive-strength = <16>; +- bias-pull-up; +- }; +- +- ethernet0_mdio: ethernet0-mdio-pins { +- pins = "gpio9"; +- function = "emac0_mdio"; +- drive-strength = <16>; +- bias-pull-up; +- }; +- }; +- +- qup_uart10_default: qup-uart10-state { +- pins = "gpio46", "gpio47"; +- function = "qup1_se3"; +- }; ++&mdio { ++ compatible = "snps,dwmac-mdio"; ++ #address-cells = <1>; ++ #size-cells = <0>; + +- qup_spi16_default: qup-spi16-state { +- pins = "gpio86", "gpio87", "gpio88", "gpio89"; +- function = "qup2_se2"; +- drive-strength = <6>; +- bias-disable; ++ sgmii_phy0: phy@8 { ++ compatible = "ethernet-phy-id0141.0dd4"; ++ reg = <0x8>; ++ device_type = "ethernet-phy"; ++ interrupts-extended = <&tlmm 7 IRQ_TYPE_EDGE_FALLING>; ++ reset-gpios = <&pmm8654au_2_gpios 8 GPIO_ACTIVE_LOW>; ++ reset-assert-us = <11000>; ++ reset-deassert-us = <70000>; + }; + +- qup_i2c11_default: qup-i2c11-state { +- pins = "gpio48", "gpio49"; +- function = "qup1_se4"; +- drive-strength = <2>; +- bias-pull-up; ++ sgmii_phy1: phy@a { ++ compatible = "ethernet-phy-id0141.0dd4"; ++ reg = <0xa>; ++ device_type = "ethernet-phy"; ++ interrupts-extended = <&tlmm 26 IRQ_TYPE_EDGE_FALLING>; ++ reset-gpios = <&pmm8654au_2_gpios 9 GPIO_ACTIVE_LOW>; ++ reset-assert-us = <11000>; ++ reset-deassert-us = <70000>; + }; +- +- qup_i2c18_default: qup-i2c18-state { +- pins = "gpio95", "gpio96"; +- function = "qup2_se4"; +- drive-strength = <2>; +- bias-pull-up; +- }; +- +- qup_uart12_default: qup-uart12-state { +- qup_uart12_cts: qup-uart12-cts-pins { +- pins = "gpio52"; +- function = "qup1_se5"; +- bias-disable; +- }; +- +- qup_uart12_rts: qup-uart12-rts-pins { +- pins = "gpio53"; +- function = "qup1_se5"; +- bias-pull-down; +- }; +- +- qup_uart12_tx: qup-uart12-tx-pins { +- pins = "gpio54"; +- function = "qup1_se5"; +- bias-pull-up; +- }; +- +- qup_uart12_rx: qup-uart12-rx-pins { +- pins = "gpio55"; +- function = "qup1_se5"; +- bias-pull-down; +- }; +- }; +- +- qup_uart17_default: qup-uart17-state { +- qup_uart17_cts: qup-uart17-cts-pins { +- pins = "gpio91"; +- function = "qup2_se3"; +- bias-disable; +- }; +- +- qup_uart17_rts: qup0-uart17-rts-pins { +- pins = "gpio92"; +- function = "qup2_se3"; +- bias-pull-down; +- }; +- +- qup_uart17_tx: qup0-uart17-tx-pins { +- pins = "gpio93"; +- function = "qup2_se3"; +- bias-pull-up; +- }; +- +- qup_uart17_rx: qup0-uart17-rx-pins { +- pins = "gpio94"; +- function = "qup2_se3"; +- bias-pull-down; +- }; +- }; +- +- pcie0_default_state: pcie0-default-state { +- perst-pins { +- pins = "gpio2"; +- function = "gpio"; +- drive-strength = <2>; +- bias-pull-down; +- }; +- +- clkreq-pins { +- pins = "gpio1"; +- function = "pcie0_clkreq"; +- drive-strength = <2>; +- bias-pull-up; +- }; +- +- wake-pins { +- pins = "gpio0"; +- function = "gpio"; +- drive-strength = <2>; +- bias-pull-up; +- }; +- }; +- +- pcie1_default_state: pcie1-default-state { +- perst-pins { +- pins = "gpio4"; +- function = "gpio"; +- drive-strength = <2>; +- bias-pull-down; +- }; +- +- clkreq-pins { +- pins = "gpio3"; +- function = "pcie1_clkreq"; +- drive-strength = <2>; +- bias-pull-up; +- }; +- +- wake-pins { +- pins = "gpio5"; +- function = "gpio"; +- drive-strength = <2>; +- bias-pull-up; +- }; +- }; +-}; +- +-&pcie0 { +- perst-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>; +- wake-gpios = <&tlmm 0 GPIO_ACTIVE_HIGH>; +- +- pinctrl-names = "default"; +- pinctrl-0 = <&pcie0_default_state>; +- +- status = "okay"; +-}; +- +-&pcie1 { +- perst-gpios = <&tlmm 4 GPIO_ACTIVE_LOW>; +- wake-gpios = <&tlmm 5 GPIO_ACTIVE_HIGH>; +- +- pinctrl-names = "default"; +- pinctrl-0 = <&pcie1_default_state>; +- +- status = "okay"; +-}; +- +-&pcie0_phy { +- vdda-phy-supply = <&vreg_l5a>; +- vdda-pll-supply = <&vreg_l1c>; +- +- status = "okay"; +-}; +- +-&pcie1_phy { +- vdda-phy-supply = <&vreg_l5a>; +- vdda-pll-supply = <&vreg_l1c>; +- +- status = "okay"; +-}; +- +-&uart10 { +- compatible = "qcom,geni-debug-uart"; +- pinctrl-0 = <&qup_uart10_default>; +- pinctrl-names = "default"; +- status = "okay"; +-}; +- +-&uart12 { +- pinctrl-0 = <&qup_uart12_default>; +- pinctrl-names = "default"; +- status = "okay"; +-}; +- +-&uart17 { +- pinctrl-0 = <&qup_uart17_default>; +- pinctrl-names = "default"; +- status = "okay"; +-}; +- +-&ufs_mem_hc { +- reset-gpios = <&tlmm 149 GPIO_ACTIVE_LOW>; +- vcc-supply = <&vreg_l8a>; +- vcc-max-microamp = <1100000>; +- vccq-supply = <&vreg_l4c>; +- vccq-max-microamp = <1200000>; +- +- status = "okay"; +-}; +- +-&ufs_mem_phy { +- vdda-phy-supply = <&vreg_l4a>; +- vdda-pll-supply = <&vreg_l1c>; +- +- status = "okay"; +-}; +- +-&usb_0 { +- pinctrl-names = "default"; +- pinctrl-0 = <&usb0_en_state>; +- +- status = "okay"; +-}; +- +-&usb_0_dwc3 { +- dr_mode = "peripheral"; +-}; +- +-&usb_0_hsphy { +- vdda-pll-supply = <&vreg_l7a>; +- vdda18-supply = <&vreg_l6c>; +- vdda33-supply = <&vreg_l9a>; +- +- status = "okay"; +-}; +- +-&usb_0_qmpphy { +- vdda-phy-supply = <&vreg_l1c>; +- vdda-pll-supply = <&vreg_l7a>; +- +- status = "okay"; +-}; +- +-&usb_1 { +- pinctrl-names = "default"; +- pinctrl-0 = <&usb1_en_state>; +- +- status = "okay"; +-}; +- +-&usb_1_dwc3 { +- dr_mode = "host"; +-}; +- +-&usb_1_hsphy { +- vdda-pll-supply = <&vreg_l7a>; +- vdda18-supply = <&vreg_l6c>; +- vdda33-supply = <&vreg_l9a>; +- +- status = "okay"; +-}; +- +-&usb_1_qmpphy { +- vdda-phy-supply = <&vreg_l1c>; +- vdda-pll-supply = <&vreg_l7a>; +- +- status = "okay"; +-}; +- +-&usb_2 { +- pinctrl-names = "default"; +- pinctrl-0 = <&usb2_en_state>; +- +- status = "okay"; +-}; +- +-&usb_2_dwc3 { +- dr_mode = "host"; +-}; +- +-&usb_2_hsphy { +- vdda-pll-supply = <&vreg_l7a>; +- vdda18-supply = <&vreg_l6c>; +- vdda33-supply = <&vreg_l9a>; +- +- status = "okay"; +-}; +- +-&xo_board_clk { +- clock-frequency = <38400000>; + }; +diff --git a/arch/arm64/boot/dts/qcom/sa8775p-ride.dtsi b/arch/arm64/boot/dts/qcom/sa8775p-ride.dtsi +new file mode 100644 +index 00000000000000..864ad109371ca7 +--- /dev/null ++++ b/arch/arm64/boot/dts/qcom/sa8775p-ride.dtsi +@@ -0,0 +1,814 @@ ++// SPDX-License-Identifier: BSD-3-Clause ++/* ++ * Copyright (c) 2023, Linaro Limited ++ */ ++ ++/dts-v1/; ++ ++#include ++#include ++ ++#include "sa8775p.dtsi" ++#include "sa8775p-pmics.dtsi" ++ ++/ { ++ aliases { ++ ethernet0 = ðernet0; ++ ethernet1 = ðernet1; ++ i2c11 = &i2c11; ++ i2c18 = &i2c18; ++ serial0 = &uart10; ++ serial1 = &uart12; ++ serial2 = &uart17; ++ spi16 = &spi16; ++ ufshc1 = &ufs_mem_hc; ++ }; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++}; ++ ++&apps_rsc { ++ regulators-0 { ++ compatible = "qcom,pmm8654au-rpmh-regulators"; ++ qcom,pmic-id = "a"; ++ ++ vreg_s4a: smps4 { ++ regulator-name = "vreg_s4a"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1816000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_s5a: smps5 { ++ regulator-name = "vreg_s5a"; ++ regulator-min-microvolt = <1850000>; ++ regulator-max-microvolt = <1996000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_s9a: smps9 { ++ regulator-name = "vreg_s9a"; ++ regulator-min-microvolt = <535000>; ++ regulator-max-microvolt = <1120000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l4a: ldo4 { ++ regulator-name = "vreg_l4a"; ++ regulator-min-microvolt = <788000>; ++ regulator-max-microvolt = <1050000>; ++ regulator-initial-mode = ; ++ regulator-allow-set-load; ++ regulator-allowed-modes = ; ++ }; ++ ++ vreg_l5a: ldo5 { ++ regulator-name = "vreg_l5a"; ++ regulator-min-microvolt = <870000>; ++ regulator-max-microvolt = <950000>; ++ regulator-initial-mode = ; ++ regulator-allow-set-load; ++ regulator-allowed-modes = ; ++ }; ++ ++ vreg_l6a: ldo6 { ++ regulator-name = "vreg_l6a"; ++ regulator-min-microvolt = <870000>; ++ regulator-max-microvolt = <970000>; ++ regulator-initial-mode = ; ++ regulator-allow-set-load; ++ regulator-allowed-modes = ; ++ }; ++ ++ vreg_l7a: ldo7 { ++ regulator-name = "vreg_l7a"; ++ regulator-min-microvolt = <720000>; ++ regulator-max-microvolt = <950000>; ++ regulator-initial-mode = ; ++ regulator-allow-set-load; ++ regulator-allowed-modes = ; ++ }; ++ ++ vreg_l8a: ldo8 { ++ regulator-name = "vreg_l8a"; ++ regulator-min-microvolt = <2504000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-initial-mode = ; ++ regulator-allow-set-load; ++ regulator-allowed-modes = ; ++ }; ++ ++ vreg_l9a: ldo9 { ++ regulator-name = "vreg_l9a"; ++ regulator-min-microvolt = <2970000>; ++ regulator-max-microvolt = <3544000>; ++ regulator-initial-mode = ; ++ regulator-allow-set-load; ++ regulator-allowed-modes = ; ++ }; ++ }; ++ ++ regulators-1 { ++ compatible = "qcom,pmm8654au-rpmh-regulators"; ++ qcom,pmic-id = "c"; ++ ++ vreg_l1c: ldo1 { ++ regulator-name = "vreg_l1c"; ++ regulator-min-microvolt = <1140000>; ++ regulator-max-microvolt = <1260000>; ++ regulator-initial-mode = ; ++ regulator-allow-set-load; ++ regulator-allowed-modes = ; ++ }; ++ ++ vreg_l2c: ldo2 { ++ regulator-name = "vreg_l2c"; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <1100000>; ++ regulator-initial-mode = ; ++ regulator-allow-set-load; ++ regulator-allowed-modes = ; ++ }; ++ ++ vreg_l3c: ldo3 { ++ regulator-name = "vreg_l3c"; ++ regulator-min-microvolt = <1100000>; ++ regulator-max-microvolt = <1300000>; ++ regulator-initial-mode = ; ++ regulator-allow-set-load; ++ regulator-allowed-modes = ; ++ }; ++ ++ vreg_l4c: ldo4 { ++ regulator-name = "vreg_l4c"; ++ regulator-min-microvolt = <1200000>; ++ regulator-max-microvolt = <1200000>; ++ regulator-initial-mode = ; ++ /* ++ * FIXME: This should have regulator-allow-set-load but ++ * we're getting an over-current fault from the PMIC ++ * when switching to LPM. ++ */ ++ }; ++ ++ vreg_l5c: ldo5 { ++ regulator-name = "vreg_l5c"; ++ regulator-min-microvolt = <1100000>; ++ regulator-max-microvolt = <1300000>; ++ regulator-initial-mode = ; ++ regulator-allow-set-load; ++ regulator-allowed-modes = ; ++ }; ++ ++ vreg_l6c: ldo6 { ++ regulator-name = "vreg_l6c"; ++ regulator-min-microvolt = <1620000>; ++ regulator-max-microvolt = <1980000>; ++ regulator-initial-mode = ; ++ regulator-allow-set-load; ++ regulator-allowed-modes = ; ++ }; ++ ++ vreg_l7c: ldo7 { ++ regulator-name = "vreg_l7c"; ++ regulator-min-microvolt = <1620000>; ++ regulator-max-microvolt = <2000000>; ++ regulator-initial-mode = ; ++ regulator-allow-set-load; ++ regulator-allowed-modes = ; ++ }; ++ ++ vreg_l8c: ldo8 { ++ regulator-name = "vreg_l8c"; ++ regulator-min-microvolt = <2400000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-initial-mode = ; ++ regulator-allow-set-load; ++ regulator-allowed-modes = ; ++ }; ++ ++ vreg_l9c: ldo9 { ++ regulator-name = "vreg_l9c"; ++ regulator-min-microvolt = <1650000>; ++ regulator-max-microvolt = <2700000>; ++ regulator-initial-mode = ; ++ regulator-allow-set-load; ++ regulator-allowed-modes = ; ++ }; ++ }; ++ ++ regulators-2 { ++ compatible = "qcom,pmm8654au-rpmh-regulators"; ++ qcom,pmic-id = "e"; ++ ++ vreg_s4e: smps4 { ++ regulator-name = "vreg_s4e"; ++ regulator-min-microvolt = <970000>; ++ regulator-max-microvolt = <1520000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_s7e: smps7 { ++ regulator-name = "vreg_s7e"; ++ regulator-min-microvolt = <1010000>; ++ regulator-max-microvolt = <1170000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_s9e: smps9 { ++ regulator-name = "vreg_s9e"; ++ regulator-min-microvolt = <300000>; ++ regulator-max-microvolt = <570000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l6e: ldo6 { ++ regulator-name = "vreg_l6e"; ++ regulator-min-microvolt = <1280000>; ++ regulator-max-microvolt = <1450000>; ++ regulator-initial-mode = ; ++ regulator-allow-set-load; ++ regulator-allowed-modes = ; ++ }; ++ ++ vreg_l8e: ldo8 { ++ regulator-name = "vreg_l8e"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1950000>; ++ regulator-initial-mode = ; ++ regulator-allow-set-load; ++ regulator-allowed-modes = ; ++ }; ++ }; ++}; ++ ++ðernet0 { ++ phy-handle = <&sgmii_phy0>; ++ ++ pinctrl-0 = <ðernet0_default>; ++ pinctrl-names = "default"; ++ ++ snps,mtl-rx-config = <&mtl_rx_setup>; ++ snps,mtl-tx-config = <&mtl_tx_setup>; ++ snps,ps-speed = <1000>; ++ ++ status = "okay"; ++ ++ mdio: mdio { ++ compatible = "snps,dwmac-mdio"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ ++ mtl_rx_setup: rx-queues-config { ++ snps,rx-queues-to-use = <4>; ++ snps,rx-sched-sp; ++ ++ queue0 { ++ snps,dcb-algorithm; ++ snps,map-to-dma-channel = <0x0>; ++ snps,route-up; ++ snps,priority = <0x1>; ++ }; ++ ++ queue1 { ++ snps,dcb-algorithm; ++ snps,map-to-dma-channel = <0x1>; ++ snps,route-ptp; ++ }; ++ ++ queue2 { ++ snps,avb-algorithm; ++ snps,map-to-dma-channel = <0x2>; ++ snps,route-avcp; ++ }; ++ ++ queue3 { ++ snps,avb-algorithm; ++ snps,map-to-dma-channel = <0x3>; ++ snps,priority = <0xc>; ++ }; ++ }; ++ ++ mtl_tx_setup: tx-queues-config { ++ snps,tx-queues-to-use = <4>; ++ snps,tx-sched-sp; ++ ++ queue0 { ++ snps,dcb-algorithm; ++ }; ++ ++ queue1 { ++ snps,dcb-algorithm; ++ }; ++ ++ queue2 { ++ snps,avb-algorithm; ++ snps,send_slope = <0x1000>; ++ snps,idle_slope = <0x1000>; ++ snps,high_credit = <0x3e800>; ++ snps,low_credit = <0xffc18000>; ++ }; ++ ++ queue3 { ++ snps,avb-algorithm; ++ snps,send_slope = <0x1000>; ++ snps,idle_slope = <0x1000>; ++ snps,high_credit = <0x3e800>; ++ snps,low_credit = <0xffc18000>; ++ }; ++ }; ++}; ++ ++ðernet1 { ++ phy-handle = <&sgmii_phy1>; ++ ++ snps,mtl-rx-config = <&mtl_rx_setup1>; ++ snps,mtl-tx-config = <&mtl_tx_setup1>; ++ snps,ps-speed = <1000>; ++ ++ status = "okay"; ++ ++ mtl_rx_setup1: rx-queues-config { ++ snps,rx-queues-to-use = <4>; ++ snps,rx-sched-sp; ++ ++ queue0 { ++ snps,dcb-algorithm; ++ snps,map-to-dma-channel = <0x0>; ++ snps,route-up; ++ snps,priority = <0x1>; ++ }; ++ ++ queue1 { ++ snps,dcb-algorithm; ++ snps,map-to-dma-channel = <0x1>; ++ snps,route-ptp; ++ }; ++ ++ queue2 { ++ snps,avb-algorithm; ++ snps,map-to-dma-channel = <0x2>; ++ snps,route-avcp; ++ }; ++ ++ queue3 { ++ snps,avb-algorithm; ++ snps,map-to-dma-channel = <0x3>; ++ snps,priority = <0xc>; ++ }; ++ }; ++ ++ mtl_tx_setup1: tx-queues-config { ++ snps,tx-queues-to-use = <4>; ++ snps,tx-sched-sp; ++ ++ queue0 { ++ snps,dcb-algorithm; ++ }; ++ ++ queue1 { ++ snps,dcb-algorithm; ++ }; ++ ++ queue2 { ++ snps,avb-algorithm; ++ snps,send_slope = <0x1000>; ++ snps,idle_slope = <0x1000>; ++ snps,high_credit = <0x3e800>; ++ snps,low_credit = <0xffc18000>; ++ }; ++ ++ queue3 { ++ snps,avb-algorithm; ++ snps,send_slope = <0x1000>; ++ snps,idle_slope = <0x1000>; ++ snps,high_credit = <0x3e800>; ++ snps,low_credit = <0xffc18000>; ++ }; ++ }; ++}; ++ ++&i2c11 { ++ clock-frequency = <400000>; ++ pinctrl-0 = <&qup_i2c11_default>; ++ pinctrl-names = "default"; ++ status = "okay"; ++}; ++ ++&i2c18 { ++ clock-frequency = <400000>; ++ pinctrl-0 = <&qup_i2c18_default>; ++ pinctrl-names = "default"; ++ status = "okay"; ++}; ++ ++&pmm8654au_0_gpios { ++ gpio-line-names = "DS_EN", ++ "POFF_COMPLETE", ++ "UFS0_VER_ID", ++ "FAST_POFF", ++ "DBU1_PON_DONE", ++ "AOSS_SLEEP", ++ "CAM_DES0_EN", ++ "CAM_DES1_EN", ++ "CAM_DES2_EN", ++ "CAM_DES3_EN", ++ "UEFI", ++ "ANALOG_PON_OPT"; ++}; ++ ++&pmm8654au_0_pon_resin { ++ linux,code = ; ++ status = "okay"; ++}; ++ ++&pmm8654au_1_gpios { ++ gpio-line-names = "PMIC_C_ID0", ++ "PMIC_C_ID1", ++ "UFS1_VER_ID", ++ "IPA_PWR", ++ "", ++ "WLAN_DBU4_EN", ++ "WLAN_EN", ++ "BT_EN", ++ "USB2_PWR_EN", ++ "USB2_FAULT"; ++ ++ usb2_en_state: usb2-en-state { ++ pins = "gpio9"; ++ function = "normal"; ++ output-high; ++ power-source = <0>; ++ }; ++}; ++ ++&pmm8654au_2_gpios { ++ gpio-line-names = "PMIC_E_ID0", ++ "PMIC_E_ID1", ++ "USB0_PWR_EN", ++ "USB0_FAULT", ++ "SENSOR_IRQ_1", ++ "SENSOR_IRQ_2", ++ "SENSOR_RST", ++ "SGMIIO0_RST", ++ "SGMIIO1_RST", ++ "USB1_PWR_ENABLE", ++ "USB1_FAULT", ++ "VMON_SPX8"; ++ ++ usb0_en_state: usb0-en-state { ++ pins = "gpio3"; ++ function = "normal"; ++ output-high; ++ power-source = <0>; ++ }; ++ ++ usb1_en_state: usb1-en-state { ++ pins = "gpio10"; ++ function = "normal"; ++ output-high; ++ power-source = <0>; ++ }; ++}; ++ ++&pmm8654au_3_gpios { ++ gpio-line-names = "PMIC_G_ID0", ++ "PMIC_G_ID1", ++ "GNSS_RST", ++ "GNSS_EN", ++ "GNSS_BOOT_MODE"; ++}; ++ ++&qupv3_id_1 { ++ status = "okay"; ++}; ++ ++&qupv3_id_2 { ++ status = "okay"; ++}; ++ ++&serdes0 { ++ phy-supply = <&vreg_l5a>; ++ status = "okay"; ++}; ++ ++&serdes1 { ++ phy-supply = <&vreg_l5a>; ++ status = "okay"; ++}; ++ ++&sleep_clk { ++ clock-frequency = <32000>; ++}; ++ ++&spi16 { ++ pinctrl-0 = <&qup_spi16_default>; ++ pinctrl-names = "default"; ++ status = "okay"; ++}; ++ ++&tlmm { ++ ethernet0_default: ethernet0-default-state { ++ ethernet0_mdc: ethernet0-mdc-pins { ++ pins = "gpio8"; ++ function = "emac0_mdc"; ++ drive-strength = <16>; ++ bias-pull-up; ++ }; ++ ++ ethernet0_mdio: ethernet0-mdio-pins { ++ pins = "gpio9"; ++ function = "emac0_mdio"; ++ drive-strength = <16>; ++ bias-pull-up; ++ }; ++ }; ++ ++ qup_uart10_default: qup-uart10-state { ++ pins = "gpio46", "gpio47"; ++ function = "qup1_se3"; ++ }; ++ ++ qup_spi16_default: qup-spi16-state { ++ pins = "gpio86", "gpio87", "gpio88", "gpio89"; ++ function = "qup2_se2"; ++ drive-strength = <6>; ++ bias-disable; ++ }; ++ ++ qup_i2c11_default: qup-i2c11-state { ++ pins = "gpio48", "gpio49"; ++ function = "qup1_se4"; ++ drive-strength = <2>; ++ bias-pull-up; ++ }; ++ ++ qup_i2c18_default: qup-i2c18-state { ++ pins = "gpio95", "gpio96"; ++ function = "qup2_se4"; ++ drive-strength = <2>; ++ bias-pull-up; ++ }; ++ ++ qup_uart12_default: qup-uart12-state { ++ qup_uart12_cts: qup-uart12-cts-pins { ++ pins = "gpio52"; ++ function = "qup1_se5"; ++ bias-disable; ++ }; ++ ++ qup_uart12_rts: qup-uart12-rts-pins { ++ pins = "gpio53"; ++ function = "qup1_se5"; ++ bias-pull-down; ++ }; ++ ++ qup_uart12_tx: qup-uart12-tx-pins { ++ pins = "gpio54"; ++ function = "qup1_se5"; ++ bias-pull-up; ++ }; ++ ++ qup_uart12_rx: qup-uart12-rx-pins { ++ pins = "gpio55"; ++ function = "qup1_se5"; ++ bias-pull-down; ++ }; ++ }; ++ ++ qup_uart17_default: qup-uart17-state { ++ qup_uart17_cts: qup-uart17-cts-pins { ++ pins = "gpio91"; ++ function = "qup2_se3"; ++ bias-disable; ++ }; ++ ++ qup_uart17_rts: qup0-uart17-rts-pins { ++ pins = "gpio92"; ++ function = "qup2_se3"; ++ bias-pull-down; ++ }; ++ ++ qup_uart17_tx: qup0-uart17-tx-pins { ++ pins = "gpio93"; ++ function = "qup2_se3"; ++ bias-pull-up; ++ }; ++ ++ qup_uart17_rx: qup0-uart17-rx-pins { ++ pins = "gpio94"; ++ function = "qup2_se3"; ++ bias-pull-down; ++ }; ++ }; ++ ++ pcie0_default_state: pcie0-default-state { ++ perst-pins { ++ pins = "gpio2"; ++ function = "gpio"; ++ drive-strength = <2>; ++ bias-pull-down; ++ }; ++ ++ clkreq-pins { ++ pins = "gpio1"; ++ function = "pcie0_clkreq"; ++ drive-strength = <2>; ++ bias-pull-up; ++ }; ++ ++ wake-pins { ++ pins = "gpio0"; ++ function = "gpio"; ++ drive-strength = <2>; ++ bias-pull-up; ++ }; ++ }; ++ ++ pcie1_default_state: pcie1-default-state { ++ perst-pins { ++ pins = "gpio4"; ++ function = "gpio"; ++ drive-strength = <2>; ++ bias-pull-down; ++ }; ++ ++ clkreq-pins { ++ pins = "gpio3"; ++ function = "pcie1_clkreq"; ++ drive-strength = <2>; ++ bias-pull-up; ++ }; ++ ++ wake-pins { ++ pins = "gpio5"; ++ function = "gpio"; ++ drive-strength = <2>; ++ bias-pull-up; ++ }; ++ }; ++}; ++ ++&pcie0 { ++ perst-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>; ++ wake-gpios = <&tlmm 0 GPIO_ACTIVE_HIGH>; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie0_default_state>; ++ ++ status = "okay"; ++}; ++ ++&pcie1 { ++ perst-gpios = <&tlmm 4 GPIO_ACTIVE_LOW>; ++ wake-gpios = <&tlmm 5 GPIO_ACTIVE_HIGH>; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie1_default_state>; ++ ++ status = "okay"; ++}; ++ ++&pcie0_phy { ++ vdda-phy-supply = <&vreg_l5a>; ++ vdda-pll-supply = <&vreg_l1c>; ++ ++ status = "okay"; ++}; ++ ++&pcie1_phy { ++ vdda-phy-supply = <&vreg_l5a>; ++ vdda-pll-supply = <&vreg_l1c>; ++ ++ status = "okay"; ++}; ++ ++&uart10 { ++ compatible = "qcom,geni-debug-uart"; ++ pinctrl-0 = <&qup_uart10_default>; ++ pinctrl-names = "default"; ++ status = "okay"; ++}; ++ ++&uart12 { ++ pinctrl-0 = <&qup_uart12_default>; ++ pinctrl-names = "default"; ++ status = "okay"; ++}; ++ ++&uart17 { ++ pinctrl-0 = <&qup_uart17_default>; ++ pinctrl-names = "default"; ++ status = "okay"; ++}; ++ ++&ufs_mem_hc { ++ reset-gpios = <&tlmm 149 GPIO_ACTIVE_LOW>; ++ vcc-supply = <&vreg_l8a>; ++ vcc-max-microamp = <1100000>; ++ vccq-supply = <&vreg_l4c>; ++ vccq-max-microamp = <1200000>; ++ ++ status = "okay"; ++}; ++ ++&ufs_mem_phy { ++ vdda-phy-supply = <&vreg_l4a>; ++ vdda-pll-supply = <&vreg_l1c>; ++ ++ status = "okay"; ++}; ++ ++&usb_0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&usb0_en_state>; ++ ++ status = "okay"; ++}; ++ ++&usb_0_dwc3 { ++ dr_mode = "peripheral"; ++}; ++ ++&usb_0_hsphy { ++ vdda-pll-supply = <&vreg_l7a>; ++ vdda18-supply = <&vreg_l6c>; ++ vdda33-supply = <&vreg_l9a>; ++ ++ status = "okay"; ++}; ++ ++&usb_0_qmpphy { ++ vdda-phy-supply = <&vreg_l1c>; ++ vdda-pll-supply = <&vreg_l7a>; ++ ++ status = "okay"; ++}; ++ ++&usb_1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&usb1_en_state>; ++ ++ status = "okay"; ++}; ++ ++&usb_1_dwc3 { ++ dr_mode = "host"; ++}; ++ ++&usb_1_hsphy { ++ vdda-pll-supply = <&vreg_l7a>; ++ vdda18-supply = <&vreg_l6c>; ++ vdda33-supply = <&vreg_l9a>; ++ ++ status = "okay"; ++}; ++ ++&usb_1_qmpphy { ++ vdda-phy-supply = <&vreg_l1c>; ++ vdda-pll-supply = <&vreg_l7a>; ++ ++ status = "okay"; ++}; ++ ++&usb_2 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&usb2_en_state>; ++ ++ status = "okay"; ++}; ++ ++&usb_2_dwc3 { ++ dr_mode = "host"; ++}; ++ ++&usb_2_hsphy { ++ vdda-pll-supply = <&vreg_l7a>; ++ vdda18-supply = <&vreg_l6c>; ++ vdda33-supply = <&vreg_l9a>; ++ ++ status = "okay"; ++}; ++ ++&xo_board_clk { ++ clock-frequency = <38400000>; ++}; +diff --git a/arch/arm64/boot/dts/qcom/sc7180-firmware-tfa.dtsi b/arch/arm64/boot/dts/qcom/sc7180-firmware-tfa.dtsi +index ee35a454dbf6f3..59162b3afcb841 100644 +--- a/arch/arm64/boot/dts/qcom/sc7180-firmware-tfa.dtsi ++++ b/arch/arm64/boot/dts/qcom/sc7180-firmware-tfa.dtsi +@@ -6,82 +6,82 @@ + * by Qualcomm firmware. + */ + +-&CPU0 { ++&cpu0 { + /delete-property/ power-domains; + /delete-property/ power-domain-names; + +- cpu-idle-states = <&LITTLE_CPU_SLEEP_0 +- &LITTLE_CPU_SLEEP_1 +- &CLUSTER_SLEEP_0>; ++ cpu-idle-states = <&little_cpu_sleep_0 ++ &little_cpu_sleep_1 ++ &cluster_sleep_0>; + }; + +-&CPU1 { ++&cpu1 { + /delete-property/ power-domains; + /delete-property/ power-domain-names; + +- cpu-idle-states = <&LITTLE_CPU_SLEEP_0 +- &LITTLE_CPU_SLEEP_1 +- &CLUSTER_SLEEP_0>; ++ cpu-idle-states = <&little_cpu_sleep_0 ++ &little_cpu_sleep_1 ++ &cluster_sleep_0>; + }; + +-&CPU2 { ++&cpu2 { + /delete-property/ power-domains; + /delete-property/ power-domain-names; + +- cpu-idle-states = <&LITTLE_CPU_SLEEP_0 +- &LITTLE_CPU_SLEEP_1 +- &CLUSTER_SLEEP_0>; ++ cpu-idle-states = <&little_cpu_sleep_0 ++ &little_cpu_sleep_1 ++ &cluster_sleep_0>; + }; + +-&CPU3 { ++&cpu3 { + /delete-property/ power-domains; + /delete-property/ power-domain-names; + +- cpu-idle-states = <&LITTLE_CPU_SLEEP_0 +- &LITTLE_CPU_SLEEP_1 +- &CLUSTER_SLEEP_0>; ++ cpu-idle-states = <&little_cpu_sleep_0 ++ &little_cpu_sleep_1 ++ &cluster_sleep_0>; + }; + +-&CPU4 { ++&cpu4 { + /delete-property/ power-domains; + /delete-property/ power-domain-names; + +- cpu-idle-states = <&LITTLE_CPU_SLEEP_0 +- &LITTLE_CPU_SLEEP_1 +- &CLUSTER_SLEEP_0>; ++ cpu-idle-states = <&little_cpu_sleep_0 ++ &little_cpu_sleep_1 ++ &cluster_sleep_0>; + }; + +-&CPU5 { ++&cpu5 { + /delete-property/ power-domains; + /delete-property/ power-domain-names; + +- cpu-idle-states = <&LITTLE_CPU_SLEEP_0 +- &LITTLE_CPU_SLEEP_1 +- &CLUSTER_SLEEP_0>; ++ cpu-idle-states = <&little_cpu_sleep_0 ++ &little_cpu_sleep_1 ++ &cluster_sleep_0>; + }; + +-&CPU6 { ++&cpu6 { + /delete-property/ power-domains; + /delete-property/ power-domain-names; + +- cpu-idle-states = <&BIG_CPU_SLEEP_0 +- &BIG_CPU_SLEEP_1 +- &CLUSTER_SLEEP_0>; ++ cpu-idle-states = <&big_cpu_sleep_0 ++ &big_cpu_sleep_1 ++ &cluster_sleep_0>; + }; + +-&CPU7 { ++&cpu7 { + /delete-property/ power-domains; + /delete-property/ power-domain-names; + +- cpu-idle-states = <&BIG_CPU_SLEEP_0 +- &BIG_CPU_SLEEP_1 +- &CLUSTER_SLEEP_0>; ++ cpu-idle-states = <&big_cpu_sleep_0 ++ &big_cpu_sleep_1 ++ &cluster_sleep_0>; + }; + + /delete-node/ &domain_idle_states; + + &idle_states { +- CLUSTER_SLEEP_0: cluster-sleep-0 { ++ cluster_sleep_0: cluster-sleep-0 { + compatible = "arm,idle-state"; + idle-state-name = "cluster-power-down"; + arm,psci-suspend-param = <0x40003444>; +@@ -92,15 +92,15 @@ CLUSTER_SLEEP_0: cluster-sleep-0 { + }; + }; + +-/delete-node/ &CPU_PD0; +-/delete-node/ &CPU_PD1; +-/delete-node/ &CPU_PD2; +-/delete-node/ &CPU_PD3; +-/delete-node/ &CPU_PD4; +-/delete-node/ &CPU_PD5; +-/delete-node/ &CPU_PD6; +-/delete-node/ &CPU_PD7; +-/delete-node/ &CLUSTER_PD; ++/delete-node/ &cpu_pd0; ++/delete-node/ &cpu_pd1; ++/delete-node/ &cpu_pd2; ++/delete-node/ &cpu_pd3; ++/delete-node/ &cpu_pd4; ++/delete-node/ &cpu_pd5; ++/delete-node/ &cpu_pd6; ++/delete-node/ &cpu_pd7; ++/delete-node/ &cluster_pd; + + &apps_rsc { + /delete-property/ power-domains; +diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi +index a532cc4aac4740..d338a8a0a9a966 100644 +--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi ++++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi +@@ -26,7 +26,6 @@ adau7002: audio-codec-1 { + thermal-zones { + skin_temp_thermal: skin-temp-thermal { + polling-delay-passive = <250>; +- polling-delay = <0>; + + thermal-sensors = <&pm6150_adc_tm 1>; + sustainable-power = <965>; +@@ -54,14 +53,14 @@ skin-temp-crit { + cooling-maps { + map0 { + trip = <&skin_temp_alert0>; +- cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ cooling-device = <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + + map1 { + trip = <&skin_temp_alert1>; +- cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ cooling-device = <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; +diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi +index b27dcd2ec856f0..4452d04e4c547d 100644 +--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi ++++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi +@@ -43,7 +43,6 @@ pp3300_touch: pp3300-touch-regulator { + thermal-zones { + skin_temp_thermal: skin-temp-thermal { + polling-delay-passive = <250>; +- polling-delay = <0>; + + thermal-sensors = <&pm6150_adc_tm 1>; + sustainable-power = <965>; +@@ -71,14 +70,14 @@ skin-temp-crit { + cooling-maps { + map0 { + trip = <&skin_temp_alert0>; +- cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ cooling-device = <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + + map1 { + trip = <&skin_temp_alert1>; +- cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ cooling-device = <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; +diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom.dtsi +index fd944842dd6cdf..7a05d502620f31 100644 +--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom.dtsi ++++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom.dtsi +@@ -12,14 +12,11 @@ + + / { + thermal-zones { +- 5v-choke-thermal { +- polling-delay-passive = <0>; +- polling-delay = <250>; +- ++ choke-5v-thermal { + thermal-sensors = <&pm6150_adc_tm 1>; + + trips { +- 5v-choke-crit { ++ choke-5v-crit { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; +diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-quackingstick.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-quackingstick.dtsi +index 62ab6427dd65d6..e1e31e0fc0e14e 100644 +--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-quackingstick.dtsi ++++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-quackingstick.dtsi +@@ -84,6 +84,7 @@ panel: panel@0 { + pinctrl-names = "default"; + pinctrl-0 = <&lcd_rst>; + avdd-supply = <&ppvar_lcd>; ++ avee-supply = <&ppvar_lcd>; + pp1800-supply = <&v1p8_disp>; + pp3300-supply = <&pp3300_dx_edp>; + backlight = <&backlight>; +diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler.dtsi +index 2f6a340ddd2ae3..38335df3a275d3 100644 +--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler.dtsi ++++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler.dtsi +@@ -50,7 +50,6 @@ v1p8_mipi: v1p8-mipi-regulator { + thermal-zones { + skin_temp_thermal: skin-temp-thermal { + polling-delay-passive = <250>; +- polling-delay = <0>; + + thermal-sensors = <&pm6150_adc_tm 1>; + sustainable-power = <574>; +@@ -78,14 +77,14 @@ skin-temp-crit { + cooling-maps { + map0 { + trip = <&skin_temp_alert0>; +- cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ cooling-device = <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + + map1 { + trip = <&skin_temp_alert1>; +- cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ cooling-device = <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; +diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi +index c2f5e9f6679d69..906e616422706f 100644 +--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi ++++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi +@@ -21,9 +21,6 @@ + / { + thermal-zones { + charger_thermal: charger-thermal { +- polling-delay-passive = <0>; +- polling-delay = <0>; +- + thermal-sensors = <&pm6150_adc_tm 0>; + + trips { +diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi +index 68b1c017a9fd5f..7758136d71d645 100644 +--- a/arch/arm64/boot/dts/qcom/sc7180.dtsi ++++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi +@@ -74,28 +74,28 @@ cpus { + #address-cells = <2>; + #size-cells = <0>; + +- CPU0: cpu@0 { ++ cpu0: cpu@0 { + device_type = "cpu"; + compatible = "qcom,kryo468"; + reg = <0x0 0x0>; + clocks = <&cpufreq_hw 0>; + enable-method = "psci"; +- power-domains = <&CPU_PD0>; ++ power-domains = <&cpu_pd0>; + power-domain-names = "psci"; + capacity-dmips-mhz = <415>; + dynamic-power-coefficient = <137>; + operating-points-v2 = <&cpu0_opp_table>; + interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>, + <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>; +- next-level-cache = <&L2_0>; ++ next-level-cache = <&l2_0>; + #cooling-cells = <2>; + qcom,freq-domain = <&cpufreq_hw 0>; +- L2_0: l2-cache { ++ l2_0: l2-cache { + compatible = "cache"; + cache-level = <2>; + cache-unified; +- next-level-cache = <&L3_0>; +- L3_0: l3-cache { ++ next-level-cache = <&l3_0>; ++ l3_0: l3-cache { + compatible = "cache"; + cache-level = <3>; + cache-unified; +@@ -103,206 +103,206 @@ L3_0: l3-cache { + }; + }; + +- CPU1: cpu@100 { ++ cpu1: cpu@100 { + device_type = "cpu"; + compatible = "qcom,kryo468"; + reg = <0x0 0x100>; + clocks = <&cpufreq_hw 0>; + enable-method = "psci"; +- power-domains = <&CPU_PD1>; ++ power-domains = <&cpu_pd1>; + power-domain-names = "psci"; + capacity-dmips-mhz = <415>; + dynamic-power-coefficient = <137>; +- next-level-cache = <&L2_100>; ++ next-level-cache = <&l2_100>; + operating-points-v2 = <&cpu0_opp_table>; + interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>, + <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>; + #cooling-cells = <2>; + qcom,freq-domain = <&cpufreq_hw 0>; +- L2_100: l2-cache { ++ l2_100: l2-cache { + compatible = "cache"; + cache-level = <2>; + cache-unified; +- next-level-cache = <&L3_0>; ++ next-level-cache = <&l3_0>; + }; + }; + +- CPU2: cpu@200 { ++ cpu2: cpu@200 { + device_type = "cpu"; + compatible = "qcom,kryo468"; + reg = <0x0 0x200>; + clocks = <&cpufreq_hw 0>; + enable-method = "psci"; +- power-domains = <&CPU_PD2>; ++ power-domains = <&cpu_pd2>; + power-domain-names = "psci"; + capacity-dmips-mhz = <415>; + dynamic-power-coefficient = <137>; +- next-level-cache = <&L2_200>; ++ next-level-cache = <&l2_200>; + operating-points-v2 = <&cpu0_opp_table>; + interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>, + <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>; + #cooling-cells = <2>; + qcom,freq-domain = <&cpufreq_hw 0>; +- L2_200: l2-cache { ++ l2_200: l2-cache { + compatible = "cache"; + cache-level = <2>; + cache-unified; +- next-level-cache = <&L3_0>; ++ next-level-cache = <&l3_0>; + }; + }; + +- CPU3: cpu@300 { ++ cpu3: cpu@300 { + device_type = "cpu"; + compatible = "qcom,kryo468"; + reg = <0x0 0x300>; + clocks = <&cpufreq_hw 0>; + enable-method = "psci"; +- power-domains = <&CPU_PD3>; ++ power-domains = <&cpu_pd3>; + power-domain-names = "psci"; + capacity-dmips-mhz = <415>; + dynamic-power-coefficient = <137>; +- next-level-cache = <&L2_300>; ++ next-level-cache = <&l2_300>; + operating-points-v2 = <&cpu0_opp_table>; + interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>, + <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>; + #cooling-cells = <2>; + qcom,freq-domain = <&cpufreq_hw 0>; +- L2_300: l2-cache { ++ l2_300: l2-cache { + compatible = "cache"; + cache-level = <2>; + cache-unified; +- next-level-cache = <&L3_0>; ++ next-level-cache = <&l3_0>; + }; + }; + +- CPU4: cpu@400 { ++ cpu4: cpu@400 { + device_type = "cpu"; + compatible = "qcom,kryo468"; + reg = <0x0 0x400>; + clocks = <&cpufreq_hw 0>; + enable-method = "psci"; +- power-domains = <&CPU_PD4>; ++ power-domains = <&cpu_pd4>; + power-domain-names = "psci"; + capacity-dmips-mhz = <415>; + dynamic-power-coefficient = <137>; +- next-level-cache = <&L2_400>; ++ next-level-cache = <&l2_400>; + operating-points-v2 = <&cpu0_opp_table>; + interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>, + <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>; + #cooling-cells = <2>; + qcom,freq-domain = <&cpufreq_hw 0>; +- L2_400: l2-cache { ++ l2_400: l2-cache { + compatible = "cache"; + cache-level = <2>; + cache-unified; +- next-level-cache = <&L3_0>; ++ next-level-cache = <&l3_0>; + }; + }; + +- CPU5: cpu@500 { ++ cpu5: cpu@500 { + device_type = "cpu"; + compatible = "qcom,kryo468"; + reg = <0x0 0x500>; + clocks = <&cpufreq_hw 0>; + enable-method = "psci"; +- power-domains = <&CPU_PD5>; ++ power-domains = <&cpu_pd5>; + power-domain-names = "psci"; + capacity-dmips-mhz = <415>; + dynamic-power-coefficient = <137>; +- next-level-cache = <&L2_500>; ++ next-level-cache = <&l2_500>; + operating-points-v2 = <&cpu0_opp_table>; + interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>, + <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>; + #cooling-cells = <2>; + qcom,freq-domain = <&cpufreq_hw 0>; +- L2_500: l2-cache { ++ l2_500: l2-cache { + compatible = "cache"; + cache-level = <2>; + cache-unified; +- next-level-cache = <&L3_0>; ++ next-level-cache = <&l3_0>; + }; + }; + +- CPU6: cpu@600 { ++ cpu6: cpu@600 { + device_type = "cpu"; + compatible = "qcom,kryo468"; + reg = <0x0 0x600>; + clocks = <&cpufreq_hw 1>; + enable-method = "psci"; +- power-domains = <&CPU_PD6>; ++ power-domains = <&cpu_pd6>; + power-domain-names = "psci"; + capacity-dmips-mhz = <1024>; + dynamic-power-coefficient = <480>; +- next-level-cache = <&L2_600>; ++ next-level-cache = <&l2_600>; + operating-points-v2 = <&cpu6_opp_table>; + interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>, + <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>; + #cooling-cells = <2>; + qcom,freq-domain = <&cpufreq_hw 1>; +- L2_600: l2-cache { ++ l2_600: l2-cache { + compatible = "cache"; + cache-level = <2>; + cache-unified; +- next-level-cache = <&L3_0>; ++ next-level-cache = <&l3_0>; + }; + }; + +- CPU7: cpu@700 { ++ cpu7: cpu@700 { + device_type = "cpu"; + compatible = "qcom,kryo468"; + reg = <0x0 0x700>; + clocks = <&cpufreq_hw 1>; + enable-method = "psci"; +- power-domains = <&CPU_PD7>; ++ power-domains = <&cpu_pd7>; + power-domain-names = "psci"; + capacity-dmips-mhz = <1024>; + dynamic-power-coefficient = <480>; +- next-level-cache = <&L2_700>; ++ next-level-cache = <&l2_700>; + operating-points-v2 = <&cpu6_opp_table>; + interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>, + <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>; + #cooling-cells = <2>; + qcom,freq-domain = <&cpufreq_hw 1>; +- L2_700: l2-cache { ++ l2_700: l2-cache { + compatible = "cache"; + cache-level = <2>; + cache-unified; +- next-level-cache = <&L3_0>; ++ next-level-cache = <&l3_0>; + }; + }; + + cpu-map { + cluster0 { + core0 { +- cpu = <&CPU0>; ++ cpu = <&cpu0>; + }; + + core1 { +- cpu = <&CPU1>; ++ cpu = <&cpu1>; + }; + + core2 { +- cpu = <&CPU2>; ++ cpu = <&cpu2>; + }; + + core3 { +- cpu = <&CPU3>; ++ cpu = <&cpu3>; + }; + + core4 { +- cpu = <&CPU4>; ++ cpu = <&cpu4>; + }; + + core5 { +- cpu = <&CPU5>; ++ cpu = <&cpu5>; + }; + + core6 { +- cpu = <&CPU6>; ++ cpu = <&cpu6>; + }; + + core7 { +- cpu = <&CPU7>; ++ cpu = <&cpu7>; + }; + }; + }; +@@ -310,7 +310,7 @@ core7 { + idle_states: idle-states { + entry-method = "psci"; + +- LITTLE_CPU_SLEEP_0: cpu-sleep-0-0 { ++ little_cpu_sleep_0: cpu-sleep-0-0 { + compatible = "arm,idle-state"; + idle-state-name = "little-power-down"; + arm,psci-suspend-param = <0x40000003>; +@@ -320,7 +320,7 @@ LITTLE_CPU_SLEEP_0: cpu-sleep-0-0 { + local-timer-stop; + }; + +- LITTLE_CPU_SLEEP_1: cpu-sleep-0-1 { ++ little_cpu_sleep_1: cpu-sleep-0-1 { + compatible = "arm,idle-state"; + idle-state-name = "little-rail-power-down"; + arm,psci-suspend-param = <0x40000004>; +@@ -330,7 +330,7 @@ LITTLE_CPU_SLEEP_1: cpu-sleep-0-1 { + local-timer-stop; + }; + +- BIG_CPU_SLEEP_0: cpu-sleep-1-0 { ++ big_cpu_sleep_0: cpu-sleep-1-0 { + compatible = "arm,idle-state"; + idle-state-name = "big-power-down"; + arm,psci-suspend-param = <0x40000003>; +@@ -340,7 +340,7 @@ BIG_CPU_SLEEP_0: cpu-sleep-1-0 { + local-timer-stop; + }; + +- BIG_CPU_SLEEP_1: cpu-sleep-1-1 { ++ big_cpu_sleep_1: cpu-sleep-1-1 { + compatible = "arm,idle-state"; + idle-state-name = "big-rail-power-down"; + arm,psci-suspend-param = <0x40000004>; +@@ -352,7 +352,7 @@ BIG_CPU_SLEEP_1: cpu-sleep-1-1 { + }; + + domain_idle_states: domain-idle-states { +- CLUSTER_SLEEP_PC: cluster-sleep-0 { ++ cluster_sleep_pc: cluster-sleep-0 { + compatible = "domain-idle-state"; + idle-state-name = "cluster-l3-power-collapse"; + arm,psci-suspend-param = <0x41000044>; +@@ -361,7 +361,7 @@ CLUSTER_SLEEP_PC: cluster-sleep-0 { + min-residency-us = <6118>; + }; + +- CLUSTER_SLEEP_CX_RET: cluster-sleep-1 { ++ cluster_sleep_cx_ret: cluster-sleep-1 { + compatible = "domain-idle-state"; + idle-state-name = "cluster-cx-retention"; + arm,psci-suspend-param = <0x41001244>; +@@ -370,7 +370,7 @@ CLUSTER_SLEEP_CX_RET: cluster-sleep-1 { + min-residency-us = <8467>; + }; + +- CLUSTER_AOSS_SLEEP: cluster-sleep-2 { ++ cluster_aoss_sleep: cluster-sleep-2 { + compatible = "domain-idle-state"; + idle-state-name = "cluster-power-down"; + arm,psci-suspend-param = <0x4100b244>; +@@ -580,59 +580,59 @@ psci { + compatible = "arm,psci-1.0"; + method = "smc"; + +- CPU_PD0: cpu0 { ++ cpu_pd0: power-domain-cpu0 { + #power-domain-cells = <0>; +- power-domains = <&CLUSTER_PD>; +- domain-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>; ++ power-domains = <&cluster_pd>; ++ domain-idle-states = <&little_cpu_sleep_0 &little_cpu_sleep_1>; + }; + +- CPU_PD1: cpu1 { ++ cpu_pd1: power-domain-cpu1 { + #power-domain-cells = <0>; +- power-domains = <&CLUSTER_PD>; +- domain-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>; ++ power-domains = <&cluster_pd>; ++ domain-idle-states = <&little_cpu_sleep_0 &little_cpu_sleep_1>; + }; + +- CPU_PD2: cpu2 { ++ cpu_pd2: power-domain-cpu2 { + #power-domain-cells = <0>; +- power-domains = <&CLUSTER_PD>; +- domain-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>; ++ power-domains = <&cluster_pd>; ++ domain-idle-states = <&little_cpu_sleep_0 &little_cpu_sleep_1>; + }; + +- CPU_PD3: cpu3 { ++ cpu_pd3: power-domain-cpu3 { + #power-domain-cells = <0>; +- power-domains = <&CLUSTER_PD>; +- domain-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>; ++ power-domains = <&cluster_pd>; ++ domain-idle-states = <&little_cpu_sleep_0 &little_cpu_sleep_1>; + }; + +- CPU_PD4: cpu4 { ++ cpu_pd4: power-domain-cpu4 { + #power-domain-cells = <0>; +- power-domains = <&CLUSTER_PD>; +- domain-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>; ++ power-domains = <&cluster_pd>; ++ domain-idle-states = <&little_cpu_sleep_0 &little_cpu_sleep_1>; + }; + +- CPU_PD5: cpu5 { ++ cpu_pd5: power-domain-cpu5 { + #power-domain-cells = <0>; +- power-domains = <&CLUSTER_PD>; +- domain-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>; ++ power-domains = <&cluster_pd>; ++ domain-idle-states = <&little_cpu_sleep_0 &little_cpu_sleep_1>; + }; + +- CPU_PD6: cpu6 { ++ cpu_pd6: power-domain-cpu6 { + #power-domain-cells = <0>; +- power-domains = <&CLUSTER_PD>; +- domain-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>; ++ power-domains = <&cluster_pd>; ++ domain-idle-states = <&big_cpu_sleep_0 &big_cpu_sleep_1>; + }; + +- CPU_PD7: cpu7 { ++ cpu_pd7: power-domain-cpu7 { + #power-domain-cells = <0>; +- power-domains = <&CLUSTER_PD>; +- domain-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>; ++ power-domains = <&cluster_pd>; ++ domain-idle-states = <&big_cpu_sleep_0 &big_cpu_sleep_1>; + }; + +- CLUSTER_PD: cpu-cluster0 { ++ cluster_pd: power-domain-cluster { + #power-domain-cells = <0>; +- domain-idle-states = <&CLUSTER_SLEEP_PC +- &CLUSTER_SLEEP_CX_RET +- &CLUSTER_AOSS_SLEEP>; ++ domain-idle-states = <&cluster_sleep_pc ++ &cluster_sleep_cx_ret ++ &cluster_aoss_sleep>; + }; + }; + +@@ -2465,7 +2465,7 @@ etm@7040000 { + compatible = "arm,coresight-etm4x", "arm,primecell"; + reg = <0 0x07040000 0 0x1000>; + +- cpu = <&CPU0>; ++ cpu = <&cpu0>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; +@@ -2485,7 +2485,7 @@ etm@7140000 { + compatible = "arm,coresight-etm4x", "arm,primecell"; + reg = <0 0x07140000 0 0x1000>; + +- cpu = <&CPU1>; ++ cpu = <&cpu1>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; +@@ -2505,7 +2505,7 @@ etm@7240000 { + compatible = "arm,coresight-etm4x", "arm,primecell"; + reg = <0 0x07240000 0 0x1000>; + +- cpu = <&CPU2>; ++ cpu = <&cpu2>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; +@@ -2525,7 +2525,7 @@ etm@7340000 { + compatible = "arm,coresight-etm4x", "arm,primecell"; + reg = <0 0x07340000 0 0x1000>; + +- cpu = <&CPU3>; ++ cpu = <&cpu3>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; +@@ -2545,7 +2545,7 @@ etm@7440000 { + compatible = "arm,coresight-etm4x", "arm,primecell"; + reg = <0 0x07440000 0 0x1000>; + +- cpu = <&CPU4>; ++ cpu = <&cpu4>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; +@@ -2565,7 +2565,7 @@ etm@7540000 { + compatible = "arm,coresight-etm4x", "arm,primecell"; + reg = <0 0x07540000 0 0x1000>; + +- cpu = <&CPU5>; ++ cpu = <&cpu5>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; +@@ -2585,7 +2585,7 @@ etm@7640000 { + compatible = "arm,coresight-etm4x", "arm,primecell"; + reg = <0 0x07640000 0 0x1000>; + +- cpu = <&CPU6>; ++ cpu = <&cpu6>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; +@@ -2605,7 +2605,7 @@ etm@7740000 { + compatible = "arm,coresight-etm4x", "arm,primecell"; + reg = <0 0x07740000 0 0x1000>; + +- cpu = <&CPU7>; ++ cpu = <&cpu7>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; +@@ -3645,7 +3645,7 @@ apps_rsc: rsc@18200000 { + , + , + ; +- power-domains = <&CLUSTER_PD>; ++ power-domains = <&cluster_pd>; + + rpmhcc: clock-controller { + compatible = "qcom,sc7180-rpmh-clk"; +@@ -3827,7 +3827,6 @@ lpass_hm: clock-controller@63000000 { + thermal-zones { + cpu0_thermal: cpu0-thermal { + polling-delay-passive = <250>; +- polling-delay = <0>; + + thermal-sensors = <&tsens0 1>; + sustainable-power = <1052>; +@@ -3855,28 +3854,27 @@ cpu0_crit: cpu-crit { + cooling-maps { + map0 { + trip = <&cpu0_alert0>; +- cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + map1 { + trip = <&cpu0_alert1>; +- cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu1_thermal: cpu1-thermal { + polling-delay-passive = <250>; +- polling-delay = <0>; + + thermal-sensors = <&tsens0 2>; + sustainable-power = <1052>; +@@ -3904,28 +3902,27 @@ cpu1_crit: cpu-crit { + cooling-maps { + map0 { + trip = <&cpu1_alert0>; +- cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + map1 { + trip = <&cpu1_alert1>; +- cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu2_thermal: cpu2-thermal { + polling-delay-passive = <250>; +- polling-delay = <0>; + + thermal-sensors = <&tsens0 3>; + sustainable-power = <1052>; +@@ -3953,28 +3950,27 @@ cpu2_crit: cpu-crit { + cooling-maps { + map0 { + trip = <&cpu2_alert0>; +- cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + map1 { + trip = <&cpu2_alert1>; +- cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu3_thermal: cpu3-thermal { + polling-delay-passive = <250>; +- polling-delay = <0>; + + thermal-sensors = <&tsens0 4>; + sustainable-power = <1052>; +@@ -4002,28 +3998,27 @@ cpu3_crit: cpu-crit { + cooling-maps { + map0 { + trip = <&cpu3_alert0>; +- cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + map1 { + trip = <&cpu3_alert1>; +- cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu4_thermal: cpu4-thermal { + polling-delay-passive = <250>; +- polling-delay = <0>; + + thermal-sensors = <&tsens0 5>; + sustainable-power = <1052>; +@@ -4051,28 +4046,27 @@ cpu4_crit: cpu-crit { + cooling-maps { + map0 { + trip = <&cpu4_alert0>; +- cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + map1 { + trip = <&cpu4_alert1>; +- cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu5_thermal: cpu5-thermal { + polling-delay-passive = <250>; +- polling-delay = <0>; + + thermal-sensors = <&tsens0 6>; + sustainable-power = <1052>; +@@ -4100,28 +4094,27 @@ cpu5_crit: cpu-crit { + cooling-maps { + map0 { + trip = <&cpu5_alert0>; +- cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + map1 { + trip = <&cpu5_alert1>; +- cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu6_thermal: cpu6-thermal { + polling-delay-passive = <250>; +- polling-delay = <0>; + + thermal-sensors = <&tsens0 9>; + sustainable-power = <1425>; +@@ -4149,20 +4142,19 @@ cpu6_crit: cpu-crit { + cooling-maps { + map0 { + trip = <&cpu6_alert0>; +- cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ cooling-device = <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + map1 { + trip = <&cpu6_alert1>; +- cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ cooling-device = <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu7_thermal: cpu7-thermal { + polling-delay-passive = <250>; +- polling-delay = <0>; + + thermal-sensors = <&tsens0 10>; + sustainable-power = <1425>; +@@ -4190,20 +4182,19 @@ cpu7_crit: cpu-crit { + cooling-maps { + map0 { + trip = <&cpu7_alert0>; +- cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ cooling-device = <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + map1 { + trip = <&cpu7_alert1>; +- cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ cooling-device = <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu8_thermal: cpu8-thermal { + polling-delay-passive = <250>; +- polling-delay = <0>; + + thermal-sensors = <&tsens0 11>; + sustainable-power = <1425>; +@@ -4231,20 +4222,19 @@ cpu8_crit: cpu-crit { + cooling-maps { + map0 { + trip = <&cpu8_alert0>; +- cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ cooling-device = <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + map1 { + trip = <&cpu8_alert1>; +- cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ cooling-device = <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu9_thermal: cpu9-thermal { + polling-delay-passive = <250>; +- polling-delay = <0>; + + thermal-sensors = <&tsens0 12>; + sustainable-power = <1425>; +@@ -4272,20 +4262,19 @@ cpu9_crit: cpu-crit { + cooling-maps { + map0 { + trip = <&cpu9_alert0>; +- cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ cooling-device = <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + map1 { + trip = <&cpu9_alert1>; +- cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ cooling-device = <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + aoss0-thermal { + polling-delay-passive = <250>; +- polling-delay = <0>; + + thermal-sensors = <&tsens0 0>; + +@@ -4306,7 +4295,6 @@ aoss0_crit: aoss0-crit { + + cpuss0-thermal { + polling-delay-passive = <250>; +- polling-delay = <0>; + + thermal-sensors = <&tsens0 7>; + +@@ -4326,7 +4314,6 @@ cpuss0_crit: cluster0-crit { + + cpuss1-thermal { + polling-delay-passive = <250>; +- polling-delay = <0>; + + thermal-sensors = <&tsens0 8>; + +@@ -4346,7 +4333,6 @@ cpuss1_crit: cluster0-crit { + + gpuss0-thermal { + polling-delay-passive = <250>; +- polling-delay = <0>; + + thermal-sensors = <&tsens0 13>; + +@@ -4374,7 +4360,6 @@ map0 { + + gpuss1-thermal { + polling-delay-passive = <250>; +- polling-delay = <0>; + + thermal-sensors = <&tsens0 14>; + +@@ -4402,7 +4387,6 @@ map0 { + + aoss1-thermal { + polling-delay-passive = <250>; +- polling-delay = <0>; + + thermal-sensors = <&tsens1 0>; + +@@ -4423,7 +4407,6 @@ aoss1_crit: aoss1-crit { + + cwlan-thermal { + polling-delay-passive = <250>; +- polling-delay = <0>; + + thermal-sensors = <&tsens1 1>; + +@@ -4444,7 +4427,6 @@ cwlan_crit: cwlan-crit { + + audio-thermal { + polling-delay-passive = <250>; +- polling-delay = <0>; + + thermal-sensors = <&tsens1 2>; + +@@ -4465,7 +4447,6 @@ audio_crit: audio-crit { + + ddr-thermal { + polling-delay-passive = <250>; +- polling-delay = <0>; + + thermal-sensors = <&tsens1 3>; + +@@ -4486,7 +4467,6 @@ ddr_crit: ddr-crit { + + q6-hvx-thermal { + polling-delay-passive = <250>; +- polling-delay = <0>; + + thermal-sensors = <&tsens1 4>; + +@@ -4507,7 +4487,6 @@ q6_hvx_crit: q6-hvx-crit { + + camera-thermal { + polling-delay-passive = <250>; +- polling-delay = <0>; + + thermal-sensors = <&tsens1 5>; + +@@ -4528,7 +4507,6 @@ camera_crit: camera-crit { + + mdm-core-thermal { + polling-delay-passive = <250>; +- polling-delay = <0>; + + thermal-sensors = <&tsens1 6>; + +@@ -4549,7 +4527,6 @@ mdm_crit: mdm-crit { + + mdm-dsp-thermal { + polling-delay-passive = <250>; +- polling-delay = <0>; + + thermal-sensors = <&tsens1 7>; + +@@ -4570,7 +4547,6 @@ mdm_dsp_crit: mdm-dsp-crit { + + npu-thermal { + polling-delay-passive = <250>; +- polling-delay = <0>; + + thermal-sensors = <&tsens1 8>; + +@@ -4591,7 +4567,6 @@ npu_crit: npu-crit { + + video-thermal { + polling-delay-passive = <250>; +- polling-delay = <0>; + + thermal-sensors = <&tsens1 9>; + +diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi +index 149c7962f2cbb7..81e95604ef9870 100644 +--- a/arch/arm64/boot/dts/qcom/sc7280.dtsi ++++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi +@@ -80,7 +80,7 @@ xo_board: xo-board { + + sleep_clk: sleep-clk { + compatible = "fixed-clock"; +- clock-frequency = <32000>; ++ clock-frequency = <32764>; + #clock-cells = <0>; + }; + }; +diff --git a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi +index 6425c74edd60cc..3e70e79ce24b05 100644 +--- a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi ++++ b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi +@@ -2642,7 +2642,7 @@ usb_2_qmpphy1: phy@88f1000 { + + remoteproc_adsp: remoteproc@3000000 { + compatible = "qcom,sc8280xp-adsp-pas"; +- reg = <0 0x03000000 0 0x100>; ++ reg = <0 0x03000000 0 0x10000>; + + interrupts-extended = <&intc GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>, + <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>, +@@ -4399,7 +4399,7 @@ cpufreq_hw: cpufreq@18591000 { + + remoteproc_nsp0: remoteproc@1b300000 { + compatible = "qcom,sc8280xp-nsp0-pas"; +- reg = <0 0x1b300000 0 0x100>; ++ reg = <0 0x1b300000 0 0x10000>; + + interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_LEVEL_HIGH>, + <&smp2p_nsp0_in 0 IRQ_TYPE_EDGE_RISING>, +@@ -4530,7 +4530,7 @@ compute-cb@14 { + + remoteproc_nsp1: remoteproc@21300000 { + compatible = "qcom,sc8280xp-nsp1-pas"; +- reg = <0 0x21300000 0 0x100>; ++ reg = <0 0x21300000 0 0x10000>; + + interrupts-extended = <&intc GIC_SPI 887 IRQ_TYPE_LEVEL_HIGH>, + <&smp2p_nsp1_in 0 IRQ_TYPE_EDGE_RISING>, +diff --git a/arch/arm64/boot/dts/qcom/sdm845-db845c-navigation-mezzanine.dts b/arch/arm64/boot/dts/qcom/sdm845-db845c-navigation-mezzanine.dts +deleted file mode 100644 +index a21caa6f3fa259..00000000000000 +--- a/arch/arm64/boot/dts/qcom/sdm845-db845c-navigation-mezzanine.dts ++++ /dev/null +@@ -1,104 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0 +-/* +- * Copyright (c) 2022, Linaro Ltd. +- */ +- +-/dts-v1/; +- +-#include "sdm845-db845c.dts" +- +-&camss { +- vdda-phy-supply = <&vreg_l1a_0p875>; +- vdda-pll-supply = <&vreg_l26a_1p2>; +- +- status = "okay"; +- +- ports { +- port@0 { +- csiphy0_ep: endpoint { +- data-lanes = <0 1 2 3>; +- remote-endpoint = <&ov8856_ep>; +- }; +- }; +- }; +-}; +- +-&cci { +- status = "okay"; +-}; +- +-&cci_i2c0 { +- camera@10 { +- compatible = "ovti,ov8856"; +- reg = <0x10>; +- +- /* CAM0_RST_N */ +- reset-gpios = <&tlmm 9 GPIO_ACTIVE_LOW>; +- pinctrl-names = "default"; +- pinctrl-0 = <&cam0_default>; +- +- clocks = <&clock_camcc CAM_CC_MCLK0_CLK>; +- clock-names = "xvclk"; +- clock-frequency = <19200000>; +- +- /* +- * The &vreg_s4a_1p8 trace is powered on as a, +- * so it is represented by a fixed regulator. +- * +- * The 2.8V vdda-supply and 1.2V vddd-supply regulators +- * both have to be enabled through the power management +- * gpios. +- */ +- dovdd-supply = <&vreg_lvs1a_1p8>; +- avdd-supply = <&cam0_avdd_2v8>; +- dvdd-supply = <&cam0_dvdd_1v2>; +- +- port { +- ov8856_ep: endpoint { +- link-frequencies = /bits/ 64 +- <360000000 180000000>; +- data-lanes = <1 2 3 4>; +- remote-endpoint = <&csiphy0_ep>; +- }; +- }; +- }; +-}; +- +-&cci_i2c1 { +- camera@60 { +- compatible = "ovti,ov7251"; +- +- /* I2C address as per ov7251.txt linux documentation */ +- reg = <0x60>; +- +- /* CAM3_RST_N */ +- enable-gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>; +- pinctrl-names = "default"; +- pinctrl-0 = <&cam3_default>; +- +- clocks = <&clock_camcc CAM_CC_MCLK3_CLK>; +- clock-names = "xclk"; +- clock-frequency = <24000000>; +- +- /* +- * The &vreg_s4a_1p8 trace always powered on. +- * +- * The 2.8V vdda-supply regulator is enabled when the +- * vreg_s4a_1p8 trace is pulled high. +- * It too is represented by a fixed regulator. +- * +- * No 1.2V vddd-supply regulator is used. +- */ +- vdddo-supply = <&vreg_lvs1a_1p8>; +- vdda-supply = <&cam3_avdd_2v8>; +- +- status = "disabled"; +- +- port { +- ov7251_ep: endpoint { +- data-lanes = <0 1>; +-/* remote-endpoint = <&csiphy3_ep>; */ +- }; +- }; +- }; +-}; +diff --git a/arch/arm64/boot/dts/qcom/sdm845-db845c-navigation-mezzanine.dtso b/arch/arm64/boot/dts/qcom/sdm845-db845c-navigation-mezzanine.dtso +new file mode 100644 +index 00000000000000..51f1a4883ab8f0 +--- /dev/null ++++ b/arch/arm64/boot/dts/qcom/sdm845-db845c-navigation-mezzanine.dtso +@@ -0,0 +1,70 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (c) 2022, Linaro Ltd. ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++#include ++#include ++ ++&camss { ++ vdda-phy-supply = <&vreg_l1a_0p875>; ++ vdda-pll-supply = <&vreg_l26a_1p2>; ++ ++ status = "okay"; ++ ++ ports { ++ port@0 { ++ csiphy0_ep: endpoint { ++ data-lanes = <0 1 2 3>; ++ remote-endpoint = <&ov8856_ep>; ++ }; ++ }; ++ }; ++}; ++ ++&cci { ++ status = "okay"; ++}; ++ ++&cci_i2c0 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ camera@10 { ++ compatible = "ovti,ov8856"; ++ reg = <0x10>; ++ ++ /* CAM0_RST_N */ ++ reset-gpios = <&tlmm 9 GPIO_ACTIVE_LOW>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cam0_default>; ++ ++ clocks = <&clock_camcc CAM_CC_MCLK0_CLK>; ++ clock-names = "xvclk"; ++ clock-frequency = <19200000>; ++ ++ /* ++ * The &vreg_s4a_1p8 trace is powered on as a, ++ * so it is represented by a fixed regulator. ++ * ++ * The 2.8V vdda-supply and 1.2V vddd-supply regulators ++ * both have to be enabled through the power management ++ * gpios. ++ */ ++ dovdd-supply = <&vreg_lvs1a_1p8>; ++ avdd-supply = <&cam0_avdd_2v8>; ++ dvdd-supply = <&cam0_dvdd_1v2>; ++ ++ port { ++ ov8856_ep: endpoint { ++ link-frequencies = /bits/ 64 ++ <360000000 180000000>; ++ data-lanes = <1 2 3 4>; ++ remote-endpoint = <&csiphy0_ep>; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi +index dcdc8a0cd1819f..4ea693a0758565 100644 +--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi ++++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi +@@ -4244,16 +4244,16 @@ camss: camss@acb3000 { + "vfe1", + "vfe_lite"; + +- interrupts = , +- , +- , +- , +- , +- , +- , +- , +- , +- ; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; + interrupt-names = "csid0", + "csid1", + "csid2", +diff --git a/arch/arm64/boot/dts/qcom/sdx75.dtsi b/arch/arm64/boot/dts/qcom/sdx75.dtsi +index e180aa4023eca4..0d1b5712c5067d 100644 +--- a/arch/arm64/boot/dts/qcom/sdx75.dtsi ++++ b/arch/arm64/boot/dts/qcom/sdx75.dtsi +@@ -29,7 +29,7 @@ xo_board: xo-board { + + sleep_clk: sleep-clk { + compatible = "fixed-clock"; +- clock-frequency = <32000>; ++ clock-frequency = <32764>; + #clock-cells = <0>; + }; + }; +diff --git a/arch/arm64/boot/dts/qcom/sm4450.dtsi b/arch/arm64/boot/dts/qcom/sm4450.dtsi +index c4e5b33f5169c8..51240f45c8e846 100644 +--- a/arch/arm64/boot/dts/qcom/sm4450.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm4450.dtsi +@@ -23,7 +23,7 @@ xo_board: xo-board { + + sleep_clk: sleep-clk { + compatible = "fixed-clock"; +- clock-frequency = <32000>; ++ clock-frequency = <32764>; + #clock-cells = <0>; + }; + }; +diff --git a/arch/arm64/boot/dts/qcom/sm6125.dtsi b/arch/arm64/boot/dts/qcom/sm6125.dtsi +index 07081088ba1463..2b2c55132f6739 100644 +--- a/arch/arm64/boot/dts/qcom/sm6125.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm6125.dtsi +@@ -28,7 +28,7 @@ xo_board: xo-board { + sleep_clk: sleep-clk { + compatible = "fixed-clock"; + #clock-cells = <0>; +- clock-frequency = <32000>; ++ clock-frequency = <32764>; + clock-output-names = "sleep_clk"; + }; + }; +diff --git a/arch/arm64/boot/dts/qcom/sm6375.dtsi b/arch/arm64/boot/dts/qcom/sm6375.dtsi +index e56f7ea4ebc6ae..c5f7715626a09b 100644 +--- a/arch/arm64/boot/dts/qcom/sm6375.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm6375.dtsi +@@ -29,7 +29,7 @@ xo_board_clk: xo-board-clk { + + sleep_clk: sleep-clk { + compatible = "fixed-clock"; +- clock-frequency = <32000>; ++ clock-frequency = <32764>; + #clock-cells = <0>; + }; + }; +diff --git a/arch/arm64/boot/dts/qcom/sm7125.dtsi b/arch/arm64/boot/dts/qcom/sm7125.dtsi +new file mode 100644 +index 00000000000000..a53145a610a3c8 +--- /dev/null ++++ b/arch/arm64/boot/dts/qcom/sm7125.dtsi +@@ -0,0 +1,16 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (c) 2021, The Linux Foundation. All rights reserved. ++ */ ++ ++#include "sc7180.dtsi" ++ ++/* SM7125 uses Kryo 465 instead of Kryo 468 */ ++&cpu0 { compatible = "qcom,kryo465"; }; ++&cpu1 { compatible = "qcom,kryo465"; }; ++&cpu2 { compatible = "qcom,kryo465"; }; ++&cpu3 { compatible = "qcom,kryo465"; }; ++&cpu4 { compatible = "qcom,kryo465"; }; ++&cpu5 { compatible = "qcom,kryo465"; }; ++&cpu6 { compatible = "qcom,kryo465"; }; ++&cpu7 { compatible = "qcom,kryo465"; }; +diff --git a/arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts b/arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts +index 18171c5d8a3877..c010e86134ff93 100644 +--- a/arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts ++++ b/arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts +@@ -26,7 +26,7 @@ / { + chassis-type = "handset"; + + /* required for bootloader to select correct board */ +- qcom,msm-id = <434 0x10000>, <459 0x10000>; ++ qcom,msm-id = <459 0x10000>; + qcom,board-id = <8 32>; + + aliases { +diff --git a/arch/arm64/boot/dts/qcom/sm8150-microsoft-surface-duo.dts b/arch/arm64/boot/dts/qcom/sm8150-microsoft-surface-duo.dts +index b039773c44653a..a1323a8b8e6bfb 100644 +--- a/arch/arm64/boot/dts/qcom/sm8150-microsoft-surface-duo.dts ++++ b/arch/arm64/boot/dts/qcom/sm8150-microsoft-surface-duo.dts +@@ -376,8 +376,8 @@ da7280@4a { + pinctrl-0 = <&da7280_intr_default>; + + dlg,actuator-type = "LRA"; +- dlg,dlg,const-op-mode = <1>; +- dlg,dlg,periodic-op-mode = <1>; ++ dlg,const-op-mode = <1>; ++ dlg,periodic-op-mode = <1>; + dlg,nom-microvolt = <2000000>; + dlg,abs-max-microvolt = <2000000>; + dlg,imax-microamp = <129000>; +diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi +index b522d19f3a1327..21bbffc4e5a284 100644 +--- a/arch/arm64/boot/dts/qcom/sm8250.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi +@@ -85,7 +85,7 @@ xo_board: xo-board { + + sleep_clk: sleep-clk { + compatible = "fixed-clock"; +- clock-frequency = <32768>; ++ clock-frequency = <32764>; + #clock-cells = <0>; + }; + }; +@@ -4121,20 +4121,20 @@ camss: camss@ac6a000 { + "vfe_lite0", + "vfe_lite1"; + +- interrupts = , +- , +- , +- , +- , +- , +- , +- , +- , +- , +- , +- , +- , +- ; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; + interrupt-names = "csiphy0", + "csiphy1", + "csiphy2", +diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi +index d4f1b36c7aebe4..dded95fa52f075 100644 +--- a/arch/arm64/boot/dts/qcom/sm8350.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi +@@ -40,7 +40,7 @@ xo_board: xo-board { + + sleep_clk: sleep-clk { + compatible = "fixed-clock"; +- clock-frequency = <32000>; ++ clock-frequency = <32764>; + #clock-cells = <0>; + }; + }; +diff --git a/arch/arm64/boot/dts/qcom/sm8450.dtsi b/arch/arm64/boot/dts/qcom/sm8450.dtsi +index a34f460240a076..007689d7f4fa20 100644 +--- a/arch/arm64/boot/dts/qcom/sm8450.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8450.dtsi +@@ -40,7 +40,7 @@ xo_board: xo-board { + sleep_clk: sleep-clk { + compatible = "fixed-clock"; + #clock-cells = <0>; +- clock-frequency = <32000>; ++ clock-frequency = <32764>; + }; + }; + +diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi +index a9b47ab92a02c7..f156167b4e8a71 100644 +--- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi ++++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi +@@ -23,7 +23,6 @@ gic500: interrupt-controller@1800000 { + interrupt-controller; + reg = <0x00 0x01800000 0x00 0x10000>, /* GICD */ + <0x00 0x01880000 0x00 0xc0000>, /* GICR */ +- <0x00 0x01880000 0x00 0xc0000>, /* GICR */ + <0x01 0x00000000 0x00 0x2000>, /* GICC */ + <0x01 0x00010000 0x00 0x1000>, /* GICH */ + <0x01 0x00020000 0x00 0x2000>; /* GICV */ +diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi +index de36abb243f104..1497f7c8adfaf4 100644 +--- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi ++++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi +@@ -18,7 +18,6 @@ gic500: interrupt-controller@1800000 { + compatible = "arm,gic-v3"; + reg = <0x00 0x01800000 0x00 0x10000>, /* GICD */ + <0x00 0x01880000 0x00 0xc0000>, /* GICR */ +- <0x00 0x01880000 0x00 0xc0000>, /* GICR */ + <0x01 0x00000000 0x00 0x2000>, /* GICC */ + <0x01 0x00010000 0x00 0x1000>, /* GICH */ + <0x01 0x00020000 0x00 0x2000>; /* GICV */ +diff --git a/arch/hexagon/include/asm/cmpxchg.h b/arch/hexagon/include/asm/cmpxchg.h +index bf6cf5579cf459..9c58fb81f7fd67 100644 +--- a/arch/hexagon/include/asm/cmpxchg.h ++++ b/arch/hexagon/include/asm/cmpxchg.h +@@ -56,7 +56,7 @@ __arch_xchg(unsigned long x, volatile void *ptr, int size) + __typeof__(ptr) __ptr = (ptr); \ + __typeof__(*(ptr)) __old = (old); \ + __typeof__(*(ptr)) __new = (new); \ +- __typeof__(*(ptr)) __oldval = 0; \ ++ __typeof__(*(ptr)) __oldval = (__typeof__(*(ptr))) 0; \ + \ + asm volatile( \ + "1: %0 = memw_locked(%1);\n" \ +diff --git a/arch/hexagon/kernel/traps.c b/arch/hexagon/kernel/traps.c +index 6447763ce5a941..b7e394cebe20d6 100644 +--- a/arch/hexagon/kernel/traps.c ++++ b/arch/hexagon/kernel/traps.c +@@ -195,8 +195,10 @@ int die(const char *str, struct pt_regs *regs, long err) + printk(KERN_EMERG "Oops: %s[#%d]:\n", str, ++die.counter); + + if (notify_die(DIE_OOPS, str, regs, err, pt_cause(regs), SIGSEGV) == +- NOTIFY_STOP) ++ NOTIFY_STOP) { ++ spin_unlock_irq(&die.lock); + return 1; ++ } + + print_modules(); + show_regs(regs); +diff --git a/arch/loongarch/include/asm/hw_breakpoint.h b/arch/loongarch/include/asm/hw_breakpoint.h +index d78330916bd18a..13b2462f3d8c9d 100644 +--- a/arch/loongarch/include/asm/hw_breakpoint.h ++++ b/arch/loongarch/include/asm/hw_breakpoint.h +@@ -38,8 +38,8 @@ struct arch_hw_breakpoint { + * Limits. + * Changing these will require modifications to the register accessors. + */ +-#define LOONGARCH_MAX_BRP 8 +-#define LOONGARCH_MAX_WRP 8 ++#define LOONGARCH_MAX_BRP 14 ++#define LOONGARCH_MAX_WRP 14 + + /* Virtual debug register bases. */ + #define CSR_CFG_ADDR 0 +diff --git a/arch/loongarch/include/asm/loongarch.h b/arch/loongarch/include/asm/loongarch.h +index 23232c7bdb9ff5..2c996da6a5bf57 100644 +--- a/arch/loongarch/include/asm/loongarch.h ++++ b/arch/loongarch/include/asm/loongarch.h +@@ -928,6 +928,36 @@ + #define LOONGARCH_CSR_DB7CTRL 0x34a /* data breakpoint 7 control */ + #define LOONGARCH_CSR_DB7ASID 0x34b /* data breakpoint 7 asid */ + ++#define LOONGARCH_CSR_DB8ADDR 0x350 /* data breakpoint 8 address */ ++#define LOONGARCH_CSR_DB8MASK 0x351 /* data breakpoint 8 mask */ ++#define LOONGARCH_CSR_DB8CTRL 0x352 /* data breakpoint 8 control */ ++#define LOONGARCH_CSR_DB8ASID 0x353 /* data breakpoint 8 asid */ ++ ++#define LOONGARCH_CSR_DB9ADDR 0x358 /* data breakpoint 9 address */ ++#define LOONGARCH_CSR_DB9MASK 0x359 /* data breakpoint 9 mask */ ++#define LOONGARCH_CSR_DB9CTRL 0x35a /* data breakpoint 9 control */ ++#define LOONGARCH_CSR_DB9ASID 0x35b /* data breakpoint 9 asid */ ++ ++#define LOONGARCH_CSR_DB10ADDR 0x360 /* data breakpoint 10 address */ ++#define LOONGARCH_CSR_DB10MASK 0x361 /* data breakpoint 10 mask */ ++#define LOONGARCH_CSR_DB10CTRL 0x362 /* data breakpoint 10 control */ ++#define LOONGARCH_CSR_DB10ASID 0x363 /* data breakpoint 10 asid */ ++ ++#define LOONGARCH_CSR_DB11ADDR 0x368 /* data breakpoint 11 address */ ++#define LOONGARCH_CSR_DB11MASK 0x369 /* data breakpoint 11 mask */ ++#define LOONGARCH_CSR_DB11CTRL 0x36a /* data breakpoint 11 control */ ++#define LOONGARCH_CSR_DB11ASID 0x36b /* data breakpoint 11 asid */ ++ ++#define LOONGARCH_CSR_DB12ADDR 0x370 /* data breakpoint 12 address */ ++#define LOONGARCH_CSR_DB12MASK 0x371 /* data breakpoint 12 mask */ ++#define LOONGARCH_CSR_DB12CTRL 0x372 /* data breakpoint 12 control */ ++#define LOONGARCH_CSR_DB12ASID 0x373 /* data breakpoint 12 asid */ ++ ++#define LOONGARCH_CSR_DB13ADDR 0x378 /* data breakpoint 13 address */ ++#define LOONGARCH_CSR_DB13MASK 0x379 /* data breakpoint 13 mask */ ++#define LOONGARCH_CSR_DB13CTRL 0x37a /* data breakpoint 13 control */ ++#define LOONGARCH_CSR_DB13ASID 0x37b /* data breakpoint 13 asid */ ++ + #define LOONGARCH_CSR_FWPC 0x380 /* instruction breakpoint config */ + #define LOONGARCH_CSR_FWPS 0x381 /* instruction breakpoint status */ + +@@ -971,6 +1001,36 @@ + #define LOONGARCH_CSR_IB7CTRL 0x3ca /* inst breakpoint 7 control */ + #define LOONGARCH_CSR_IB7ASID 0x3cb /* inst breakpoint 7 asid */ + ++#define LOONGARCH_CSR_IB8ADDR 0x3d0 /* inst breakpoint 8 address */ ++#define LOONGARCH_CSR_IB8MASK 0x3d1 /* inst breakpoint 8 mask */ ++#define LOONGARCH_CSR_IB8CTRL 0x3d2 /* inst breakpoint 8 control */ ++#define LOONGARCH_CSR_IB8ASID 0x3d3 /* inst breakpoint 8 asid */ ++ ++#define LOONGARCH_CSR_IB9ADDR 0x3d8 /* inst breakpoint 9 address */ ++#define LOONGARCH_CSR_IB9MASK 0x3d9 /* inst breakpoint 9 mask */ ++#define LOONGARCH_CSR_IB9CTRL 0x3da /* inst breakpoint 9 control */ ++#define LOONGARCH_CSR_IB9ASID 0x3db /* inst breakpoint 9 asid */ ++ ++#define LOONGARCH_CSR_IB10ADDR 0x3e0 /* inst breakpoint 10 address */ ++#define LOONGARCH_CSR_IB10MASK 0x3e1 /* inst breakpoint 10 mask */ ++#define LOONGARCH_CSR_IB10CTRL 0x3e2 /* inst breakpoint 10 control */ ++#define LOONGARCH_CSR_IB10ASID 0x3e3 /* inst breakpoint 10 asid */ ++ ++#define LOONGARCH_CSR_IB11ADDR 0x3e8 /* inst breakpoint 11 address */ ++#define LOONGARCH_CSR_IB11MASK 0x3e9 /* inst breakpoint 11 mask */ ++#define LOONGARCH_CSR_IB11CTRL 0x3ea /* inst breakpoint 11 control */ ++#define LOONGARCH_CSR_IB11ASID 0x3eb /* inst breakpoint 11 asid */ ++ ++#define LOONGARCH_CSR_IB12ADDR 0x3f0 /* inst breakpoint 12 address */ ++#define LOONGARCH_CSR_IB12MASK 0x3f1 /* inst breakpoint 12 mask */ ++#define LOONGARCH_CSR_IB12CTRL 0x3f2 /* inst breakpoint 12 control */ ++#define LOONGARCH_CSR_IB12ASID 0x3f3 /* inst breakpoint 12 asid */ ++ ++#define LOONGARCH_CSR_IB13ADDR 0x3f8 /* inst breakpoint 13 address */ ++#define LOONGARCH_CSR_IB13MASK 0x3f9 /* inst breakpoint 13 mask */ ++#define LOONGARCH_CSR_IB13CTRL 0x3fa /* inst breakpoint 13 control */ ++#define LOONGARCH_CSR_IB13ASID 0x3fb /* inst breakpoint 13 asid */ ++ + #define LOONGARCH_CSR_DEBUG 0x500 /* debug config */ + #define LOONGARCH_CSR_DERA 0x501 /* debug era */ + #define LOONGARCH_CSR_DESAVE 0x502 /* debug save */ +diff --git a/arch/loongarch/kernel/hw_breakpoint.c b/arch/loongarch/kernel/hw_breakpoint.c +index a6e4b605bfa8d6..c35f9bf3803349 100644 +--- a/arch/loongarch/kernel/hw_breakpoint.c ++++ b/arch/loongarch/kernel/hw_breakpoint.c +@@ -51,7 +51,13 @@ int hw_breakpoint_slots(int type) + READ_WB_REG_CASE(OFF, 4, REG, T, VAL); \ + READ_WB_REG_CASE(OFF, 5, REG, T, VAL); \ + READ_WB_REG_CASE(OFF, 6, REG, T, VAL); \ +- READ_WB_REG_CASE(OFF, 7, REG, T, VAL); ++ READ_WB_REG_CASE(OFF, 7, REG, T, VAL); \ ++ READ_WB_REG_CASE(OFF, 8, REG, T, VAL); \ ++ READ_WB_REG_CASE(OFF, 9, REG, T, VAL); \ ++ READ_WB_REG_CASE(OFF, 10, REG, T, VAL); \ ++ READ_WB_REG_CASE(OFF, 11, REG, T, VAL); \ ++ READ_WB_REG_CASE(OFF, 12, REG, T, VAL); \ ++ READ_WB_REG_CASE(OFF, 13, REG, T, VAL); + + #define GEN_WRITE_WB_REG_CASES(OFF, REG, T, VAL) \ + WRITE_WB_REG_CASE(OFF, 0, REG, T, VAL); \ +@@ -61,7 +67,13 @@ int hw_breakpoint_slots(int type) + WRITE_WB_REG_CASE(OFF, 4, REG, T, VAL); \ + WRITE_WB_REG_CASE(OFF, 5, REG, T, VAL); \ + WRITE_WB_REG_CASE(OFF, 6, REG, T, VAL); \ +- WRITE_WB_REG_CASE(OFF, 7, REG, T, VAL); ++ WRITE_WB_REG_CASE(OFF, 7, REG, T, VAL); \ ++ WRITE_WB_REG_CASE(OFF, 8, REG, T, VAL); \ ++ WRITE_WB_REG_CASE(OFF, 9, REG, T, VAL); \ ++ WRITE_WB_REG_CASE(OFF, 10, REG, T, VAL); \ ++ WRITE_WB_REG_CASE(OFF, 11, REG, T, VAL); \ ++ WRITE_WB_REG_CASE(OFF, 12, REG, T, VAL); \ ++ WRITE_WB_REG_CASE(OFF, 13, REG, T, VAL); + + static u64 read_wb_reg(int reg, int n, int t) + { +diff --git a/arch/loongarch/power/platform.c b/arch/loongarch/power/platform.c +index 3ea8e07aa225f9..6c7735cda4d83f 100644 +--- a/arch/loongarch/power/platform.c ++++ b/arch/loongarch/power/platform.c +@@ -17,7 +17,7 @@ void enable_gpe_wakeup(void) + if (acpi_gbl_reduced_hardware) + return; + +- acpi_enable_all_wakeup_gpes(); ++ acpi_hw_enable_all_wakeup_gpes(); + } + + void enable_pci_wakeup(void) +diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h +index ea71f7245a63e5..8d8f4909ae1a4a 100644 +--- a/arch/powerpc/include/asm/hugetlb.h ++++ b/arch/powerpc/include/asm/hugetlb.h +@@ -15,6 +15,15 @@ + + extern bool hugetlb_disabled; + ++static inline bool hugepages_supported(void) ++{ ++ if (hugetlb_disabled) ++ return false; ++ ++ return HPAGE_SHIFT != 0; ++} ++#define hugepages_supported hugepages_supported ++ + void __init hugetlbpage_init_defaultsize(void); + + int slice_is_hugepage_only_range(struct mm_struct *mm, unsigned long addr, +diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c +index 5826f5108a1244..4e4870031265c7 100644 +--- a/arch/powerpc/kernel/smp.c ++++ b/arch/powerpc/kernel/smp.c +@@ -1051,7 +1051,7 @@ static struct sched_domain_topology_level powerpc_topology[] = { + #endif + { shared_cache_mask, powerpc_shared_cache_flags, SD_INIT_NAME(CACHE) }, + { cpu_mc_mask, SD_INIT_NAME(MC) }, +- { cpu_cpu_mask, SD_INIT_NAME(DIE) }, ++ { cpu_cpu_mask, SD_INIT_NAME(PKG) }, + { NULL, }, + }; + +@@ -1595,7 +1595,7 @@ static void add_cpu_to_masks(int cpu) + /* Skip all CPUs already part of current CPU core mask */ + cpumask_andnot(mask, cpu_online_mask, cpu_core_mask(cpu)); + +- /* If chip_id is -1; limit the cpu_core_mask to within DIE*/ ++ /* If chip_id is -1; limit the cpu_core_mask to within PKG */ + if (chip_id == -1) + cpumask_and(mask, mask, cpu_cpu_mask(cpu)); + +diff --git a/arch/powerpc/sysdev/xive/native.c b/arch/powerpc/sysdev/xive/native.c +index f1c0fa6ece21d0..9928b93dbc4d4d 100644 +--- a/arch/powerpc/sysdev/xive/native.c ++++ b/arch/powerpc/sysdev/xive/native.c +@@ -559,9 +559,7 @@ bool __init xive_native_init(void) + struct device_node *np; + struct resource r; + void __iomem *tima; +- struct property *prop; + u8 max_prio = 7; +- const __be32 *p; + u32 val, cpu; + s64 rc; + +@@ -592,7 +590,7 @@ bool __init xive_native_init(void) + max_prio = val - 1; + + /* Iterate the EQ sizes and pick one */ +- of_property_for_each_u32(np, "ibm,xive-eq-sizes", prop, p, val) { ++ of_property_for_each_u32(np, "ibm,xive-eq-sizes", val) { + xive_queue_shift = val; + if (val == PAGE_SHIFT) + break; +diff --git a/arch/powerpc/sysdev/xive/spapr.c b/arch/powerpc/sysdev/xive/spapr.c +index e4541926439100..f2fa985a2c7712 100644 +--- a/arch/powerpc/sysdev/xive/spapr.c ++++ b/arch/powerpc/sysdev/xive/spapr.c +@@ -814,7 +814,6 @@ bool __init xive_spapr_init(void) + struct device_node *np; + struct resource r; + void __iomem *tima; +- struct property *prop; + u8 max_prio; + u32 val; + u32 len; +@@ -866,7 +865,7 @@ bool __init xive_spapr_init(void) + } + + /* Iterate the EQ sizes and pick one */ +- of_property_for_each_u32(np, "ibm,xive-eq-sizes", prop, reg, val) { ++ of_property_for_each_u32(np, "ibm,xive-eq-sizes", val) { + xive_queue_shift = val; + if (val == PAGE_SHIFT) + break; +diff --git a/arch/riscv/kernel/vector.c b/arch/riscv/kernel/vector.c +index 8d92fb6c522cc2..81886fc36ed6ac 100644 +--- a/arch/riscv/kernel/vector.c ++++ b/arch/riscv/kernel/vector.c +@@ -270,7 +270,7 @@ static int __init riscv_v_sysctl_init(void) + static int __init riscv_v_sysctl_init(void) { return 0; } + #endif /* ! CONFIG_SYSCTL */ + +-static int riscv_v_init(void) ++static int __init riscv_v_init(void) + { + return riscv_v_sysctl_init(); + } +diff --git a/arch/s390/Makefile b/arch/s390/Makefile +index 73873e4516866a..b77294ab0c58d7 100644 +--- a/arch/s390/Makefile ++++ b/arch/s390/Makefile +@@ -21,7 +21,7 @@ KBUILD_AFLAGS_DECOMPRESSOR := $(CLANG_FLAGS) -m64 -D__ASSEMBLY__ + ifndef CONFIG_AS_IS_LLVM + KBUILD_AFLAGS_DECOMPRESSOR += $(if $(CONFIG_DEBUG_INFO),$(aflags_dwarf)) + endif +-KBUILD_CFLAGS_DECOMPRESSOR := $(CLANG_FLAGS) -m64 -O2 -mpacked-stack ++KBUILD_CFLAGS_DECOMPRESSOR := $(CLANG_FLAGS) -m64 -O2 -mpacked-stack -std=gnu11 + KBUILD_CFLAGS_DECOMPRESSOR += -DDISABLE_BRANCH_PROFILING -D__NO_FORTIFY + KBUILD_CFLAGS_DECOMPRESSOR += -fno-delete-null-pointer-checks -msoft-float -mbackchain + KBUILD_CFLAGS_DECOMPRESSOR += -fno-asynchronous-unwind-tables +diff --git a/arch/s390/kernel/perf_cpum_cf.c b/arch/s390/kernel/perf_cpum_cf.c +index 5466e7bada03d2..65a66df5bb865e 100644 +--- a/arch/s390/kernel/perf_cpum_cf.c ++++ b/arch/s390/kernel/perf_cpum_cf.c +@@ -977,7 +977,7 @@ static int cfdiag_push_sample(struct perf_event *event, + if (event->attr.sample_type & PERF_SAMPLE_RAW) { + raw.frag.size = cpuhw->usedss; + raw.frag.data = cpuhw->stop; +- perf_sample_save_raw_data(&data, &raw); ++ perf_sample_save_raw_data(&data, event, &raw); + } + + overflow = perf_event_overflow(event, &data, ®s); +diff --git a/arch/s390/kernel/perf_pai_crypto.c b/arch/s390/kernel/perf_pai_crypto.c +index 4a4e914c283c80..044fba8332b22e 100644 +--- a/arch/s390/kernel/perf_pai_crypto.c ++++ b/arch/s390/kernel/perf_pai_crypto.c +@@ -365,7 +365,7 @@ static int paicrypt_push_sample(void) + if (event->attr.sample_type & PERF_SAMPLE_RAW) { + raw.frag.size = rawsize; + raw.frag.data = cpump->save; +- perf_sample_save_raw_data(&data, &raw); ++ perf_sample_save_raw_data(&data, event, &raw); + } + + overflow = perf_event_overflow(event, &data, ®s); +diff --git a/arch/s390/kernel/perf_pai_ext.c b/arch/s390/kernel/perf_pai_ext.c +index b5febe22d05464..089bd3104b3945 100644 +--- a/arch/s390/kernel/perf_pai_ext.c ++++ b/arch/s390/kernel/perf_pai_ext.c +@@ -454,7 +454,7 @@ static int paiext_push_sample(void) + if (event->attr.sample_type & PERF_SAMPLE_RAW) { + raw.frag.size = rawsize; + raw.frag.data = cpump->save; +- perf_sample_save_raw_data(&data, &raw); ++ perf_sample_save_raw_data(&data, event, &raw); + } + + overflow = perf_event_overflow(event, &data, ®s); +diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c +index 68adf1de8888b2..66bda6a8f918c2 100644 +--- a/arch/s390/kernel/topology.c ++++ b/arch/s390/kernel/topology.c +@@ -522,7 +522,7 @@ static struct sched_domain_topology_level s390_topology[] = { + { cpu_coregroup_mask, cpu_core_flags, SD_INIT_NAME(MC) }, + { cpu_book_mask, SD_INIT_NAME(BOOK) }, + { cpu_drawer_mask, SD_INIT_NAME(DRAWER) }, +- { cpu_cpu_mask, SD_INIT_NAME(DIE) }, ++ { cpu_cpu_mask, SD_INIT_NAME(PKG) }, + { NULL, }, + }; + +diff --git a/arch/s390/purgatory/Makefile b/arch/s390/purgatory/Makefile +index 4e930f56687899..fe7e71f91711b2 100644 +--- a/arch/s390/purgatory/Makefile ++++ b/arch/s390/purgatory/Makefile +@@ -21,7 +21,7 @@ UBSAN_SANITIZE := n + KASAN_SANITIZE := n + KCSAN_SANITIZE := n + +-KBUILD_CFLAGS := -fno-strict-aliasing -Wall -Wstrict-prototypes ++KBUILD_CFLAGS := -std=gnu11 -fno-strict-aliasing -Wall -Wstrict-prototypes + KBUILD_CFLAGS += -Wno-pointer-sign -Wno-sign-compare + KBUILD_CFLAGS += -fno-zero-initialized-in-bss -fno-builtin -ffreestanding + KBUILD_CFLAGS += -Os -m64 -msoft-float -fno-common +diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c +index 6911c5399d02f3..f483874fa20f19 100644 +--- a/arch/x86/events/amd/ibs.c ++++ b/arch/x86/events/amd/ibs.c +@@ -1115,7 +1115,7 @@ static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs) + .data = ibs_data.data, + }, + }; +- perf_sample_save_raw_data(&data, &raw); ++ perf_sample_save_raw_data(&data, event, &raw); + } + + if (perf_ibs == &perf_ibs_op) +diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c +index ce77dac9a0202a..a8f2ab816d5ae2 100644 +--- a/arch/x86/kernel/smpboot.c ++++ b/arch/x86/kernel/smpboot.c +@@ -604,14 +604,6 @@ static int x86_cluster_flags(void) + } + #endif + +-static int x86_die_flags(void) +-{ +- if (cpu_feature_enabled(X86_FEATURE_HYBRID_CPU)) +- return x86_sched_itmt_flags(); +- +- return 0; +-} +- + /* + * Set if a package/die has multiple NUMA nodes inside. + * AMD Magny-Cours, Intel Cluster-on-Die, and Intel +@@ -641,13 +633,13 @@ static void __init build_sched_topology(void) + }; + #endif + /* +- * When there is NUMA topology inside the package skip the DIE domain ++ * When there is NUMA topology inside the package skip the PKG domain + * since the NUMA domains will auto-magically create the right spanning + * domains based on the SLIT. + */ + if (!x86_has_numa_in_package) { + x86_topology[i++] = (struct sched_domain_topology_level){ +- cpu_cpu_mask, x86_die_flags, SD_INIT_NAME(DIE) ++ cpu_cpu_mask, x86_sched_itmt_flags, SD_INIT_NAME(PKG) + }; + } + +diff --git a/block/genhd.c b/block/genhd.c +index 6d704c37f26e71..8f72539e08dea3 100644 +--- a/block/genhd.c ++++ b/block/genhd.c +@@ -763,7 +763,7 @@ static ssize_t disk_badblocks_store(struct device *dev, + } + + #ifdef CONFIG_BLOCK_LEGACY_AUTOLOAD +-void blk_request_module(dev_t devt) ++static bool blk_probe_dev(dev_t devt) + { + unsigned int major = MAJOR(devt); + struct blk_major_name **n; +@@ -773,14 +773,26 @@ void blk_request_module(dev_t devt) + if ((*n)->major == major && (*n)->probe) { + (*n)->probe(devt); + mutex_unlock(&major_names_lock); +- return; ++ return true; + } + } + mutex_unlock(&major_names_lock); ++ return false; ++} ++ ++void blk_request_module(dev_t devt) ++{ ++ int error; ++ ++ if (blk_probe_dev(devt)) ++ return; + +- if (request_module("block-major-%d-%d", MAJOR(devt), MINOR(devt)) > 0) +- /* Make old-style 2.4 aliases work */ +- request_module("block-major-%d", MAJOR(devt)); ++ error = request_module("block-major-%d-%d", MAJOR(devt), MINOR(devt)); ++ /* Make old-style 2.4 aliases work */ ++ if (error > 0) ++ error = request_module("block-major-%d", MAJOR(devt)); ++ if (!error) ++ blk_probe_dev(devt); + } + #endif /* CONFIG_BLOCK_LEGACY_AUTOLOAD */ + +diff --git a/block/partitions/ldm.h b/block/partitions/ldm.h +index 0a747a0c782d5d..f98dbee9414977 100644 +--- a/block/partitions/ldm.h ++++ b/block/partitions/ldm.h +@@ -1,5 +1,5 @@ + // SPDX-License-Identifier: GPL-2.0-or-later +-/** ++/* + * ldm - Part of the Linux-NTFS project. + * + * Copyright (C) 2001,2002 Richard Russon +diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h +index 79bbfe00d241f9..b8543a34caeada 100644 +--- a/drivers/acpi/acpica/achware.h ++++ b/drivers/acpi/acpica/achware.h +@@ -103,8 +103,6 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info *gpe_event_info, + + acpi_status acpi_hw_enable_all_runtime_gpes(void); + +-acpi_status acpi_hw_enable_all_wakeup_gpes(void); +- + u8 acpi_hw_check_all_gpes(acpi_handle gpe_skip_device, u32 gpe_skip_number); + + acpi_status +diff --git a/drivers/acpi/fan_core.c b/drivers/acpi/fan_core.c +index 9dccbae9e8ea76..e416897e3931c4 100644 +--- a/drivers/acpi/fan_core.c ++++ b/drivers/acpi/fan_core.c +@@ -367,19 +367,25 @@ static int acpi_fan_probe(struct platform_device *pdev) + result = sysfs_create_link(&pdev->dev.kobj, + &cdev->device.kobj, + "thermal_cooling"); +- if (result) ++ if (result) { + dev_err(&pdev->dev, "Failed to create sysfs link 'thermal_cooling'\n"); ++ goto err_unregister; ++ } + + result = sysfs_create_link(&cdev->device.kobj, + &pdev->dev.kobj, + "device"); + if (result) { + dev_err(&pdev->dev, "Failed to create sysfs link 'device'\n"); +- goto err_end; ++ goto err_remove_link; + } + + return 0; + ++err_remove_link: ++ sysfs_remove_link(&pdev->dev.kobj, "thermal_cooling"); ++err_unregister: ++ thermal_cooling_device_unregister(cdev); + err_end: + if (fan->acpi4) + acpi_fan_delete_attributes(device); +diff --git a/drivers/base/class.c b/drivers/base/class.c +index 9cd489a5770866..695e7fba580b90 100644 +--- a/drivers/base/class.c ++++ b/drivers/base/class.c +@@ -314,8 +314,12 @@ void class_dev_iter_init(struct class_dev_iter *iter, const struct class *class, + struct subsys_private *sp = class_to_subsys(class); + struct klist_node *start_knode = NULL; + +- if (!sp) ++ memset(iter, 0, sizeof(*iter)); ++ if (!sp) { ++ pr_crit("%s: class %p was not registered yet\n", ++ __func__, class); + return; ++ } + + if (start) + start_knode = &start->p->knode_class; +@@ -342,6 +346,9 @@ struct device *class_dev_iter_next(struct class_dev_iter *iter) + struct klist_node *knode; + struct device *dev; + ++ if (!iter->sp) ++ return NULL; ++ + while (1) { + knode = klist_next(&iter->ki); + if (!knode) +diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c +index 96b349148e5788..2203686156bfe0 100644 +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -2164,6 +2164,7 @@ static void nbd_disconnect_and_put(struct nbd_device *nbd) + flush_workqueue(nbd->recv_workq); + nbd_clear_que(nbd); + nbd->task_setup = NULL; ++ clear_bit(NBD_RT_BOUND, &nbd->config->runtime_flags); + mutex_unlock(&nbd->config_lock); + + if (test_and_clear_bit(NBD_RT_HAS_CONFIG_REF, +diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c +index e809bb2dbe5e07..a4274d8c7faaf3 100644 +--- a/drivers/bluetooth/btnxpuart.c ++++ b/drivers/bluetooth/btnxpuart.c +@@ -1280,13 +1280,12 @@ static void btnxpuart_tx_work(struct work_struct *work) + + while ((skb = nxp_dequeue(nxpdev))) { + len = serdev_device_write_buf(serdev, skb->data, skb->len); +- serdev_device_wait_until_sent(serdev, 0); + hdev->stat.byte_tx += len; + + skb_pull(skb, len); + if (skb->len > 0) { + skb_queue_head(&nxpdev->txq, skb); +- break; ++ continue; + } + + switch (hci_skb_pkt_type(skb)) { +diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c +index 9ed9239b1228f6..65163312dab8ac 100644 +--- a/drivers/bus/ti-sysc.c ++++ b/drivers/bus/ti-sysc.c +@@ -2283,11 +2283,9 @@ static int sysc_init_idlemode(struct sysc *ddata, u8 *idlemodes, + const char *name) + { + struct device_node *np = ddata->dev->of_node; +- struct property *prop; +- const __be32 *p; + u32 val; + +- of_property_for_each_u32(np, name, prop, p, val) { ++ of_property_for_each_u32(np, name, val) { + if (val >= SYSC_NR_IDLEMODES) { + dev_err(ddata->dev, "invalid idlemode: %i\n", val); + return -EINVAL; +diff --git a/drivers/char/ipmi/ipmb_dev_int.c b/drivers/char/ipmi/ipmb_dev_int.c +index 49100845fcb7bb..93718919151292 100644 +--- a/drivers/char/ipmi/ipmb_dev_int.c ++++ b/drivers/char/ipmi/ipmb_dev_int.c +@@ -321,6 +321,9 @@ static int ipmb_probe(struct i2c_client *client) + ipmb_dev->miscdev.name = devm_kasprintf(&client->dev, GFP_KERNEL, + "%s%d", "ipmb-", + client->adapter->nr); ++ if (!ipmb_dev->miscdev.name) ++ return -ENOMEM; ++ + ipmb_dev->miscdev.fops = &ipmb_fops; + ipmb_dev->miscdev.parent = &client->dev; + ret = misc_register(&ipmb_dev->miscdev); +diff --git a/drivers/char/ipmi/ssif_bmc.c b/drivers/char/ipmi/ssif_bmc.c +index ab4e87a99f0874..e8460e966b83e8 100644 +--- a/drivers/char/ipmi/ssif_bmc.c ++++ b/drivers/char/ipmi/ssif_bmc.c +@@ -292,7 +292,6 @@ static void complete_response(struct ssif_bmc_ctx *ssif_bmc) + ssif_bmc->nbytes_processed = 0; + ssif_bmc->remain_len = 0; + ssif_bmc->busy = false; +- memset(&ssif_bmc->part_buf, 0, sizeof(struct ssif_part_buffer)); + wake_up_all(&ssif_bmc->wait_queue); + } + +@@ -744,9 +743,11 @@ static void on_stop_event(struct ssif_bmc_ctx *ssif_bmc, u8 *val) + ssif_bmc->aborting = true; + } + } else if (ssif_bmc->state == SSIF_RES_SENDING) { +- if (ssif_bmc->is_singlepart_read || ssif_bmc->block_num == 0xFF) ++ if (ssif_bmc->is_singlepart_read || ssif_bmc->block_num == 0xFF) { ++ memset(&ssif_bmc->part_buf, 0, sizeof(struct ssif_part_buffer)); + /* Invalidate response buffer to denote it is sent */ + complete_response(ssif_bmc); ++ } + ssif_bmc->state = SSIF_READY; + } + +diff --git a/drivers/clk/analogbits/wrpll-cln28hpc.c b/drivers/clk/analogbits/wrpll-cln28hpc.c +index 09ca8235639930..d8ae3929599697 100644 +--- a/drivers/clk/analogbits/wrpll-cln28hpc.c ++++ b/drivers/clk/analogbits/wrpll-cln28hpc.c +@@ -291,7 +291,7 @@ int wrpll_configure_for_rate(struct wrpll_cfg *c, u32 target_rate, + vco = vco_pre * f; + } + +- delta = abs(target_rate - vco); ++ delta = abs(target_vco_rate - vco); + if (delta < best_delta) { + best_delta = delta; + best_r = r; +diff --git a/drivers/clk/clk-conf.c b/drivers/clk/clk-conf.c +index 1a4e6340f95ce4..05842056202079 100644 +--- a/drivers/clk/clk-conf.c ++++ b/drivers/clk/clk-conf.c +@@ -81,13 +81,11 @@ static int __set_clk_parents(struct device_node *node, bool clk_supplier) + static int __set_clk_rates(struct device_node *node, bool clk_supplier) + { + struct of_phandle_args clkspec; +- struct property *prop; +- const __be32 *cur; + int rc, index = 0; + struct clk *clk; + u32 rate; + +- of_property_for_each_u32(node, "assigned-clock-rates", prop, cur, rate) { ++ of_property_for_each_u32(node, "assigned-clock-rates", rate) { + if (rate) { + rc = of_parse_phandle_with_args(node, "assigned-clocks", + "#clock-cells", index, &clkspec); +diff --git a/drivers/clk/clk-si5351.c b/drivers/clk/clk-si5351.c +index 00fb9b09e030c3..dd3573da12545c 100644 +--- a/drivers/clk/clk-si5351.c ++++ b/drivers/clk/clk-si5351.c +@@ -506,6 +506,8 @@ static int si5351_pll_set_rate(struct clk_hw *hw, unsigned long rate, + { + struct si5351_hw_data *hwdata = + container_of(hw, struct si5351_hw_data, hw); ++ struct si5351_platform_data *pdata = ++ hwdata->drvdata->client->dev.platform_data; + u8 reg = (hwdata->num == 0) ? SI5351_PLLA_PARAMETERS : + SI5351_PLLB_PARAMETERS; + +@@ -518,9 +520,10 @@ static int si5351_pll_set_rate(struct clk_hw *hw, unsigned long rate, + (hwdata->params.p2 == 0) ? SI5351_CLK_INTEGER_MODE : 0); + + /* Do a pll soft reset on the affected pll */ +- si5351_reg_write(hwdata->drvdata, SI5351_PLL_RESET, +- hwdata->num == 0 ? SI5351_PLL_RESET_A : +- SI5351_PLL_RESET_B); ++ if (pdata->pll_reset[hwdata->num]) ++ si5351_reg_write(hwdata->drvdata, SI5351_PLL_RESET, ++ hwdata->num == 0 ? SI5351_PLL_RESET_A : ++ SI5351_PLL_RESET_B); + + dev_dbg(&hwdata->drvdata->client->dev, + "%s - %s: p1 = %lu, p2 = %lu, p3 = %lu, parent_rate = %lu, rate = %lu\n", +@@ -1172,8 +1175,8 @@ static int si5351_dt_parse(struct i2c_client *client, + { + struct device_node *child, *np = client->dev.of_node; + struct si5351_platform_data *pdata; +- struct property *prop; +- const __be32 *p; ++ u32 array[4]; ++ int sz, i; + int num = 0; + u32 val; + +@@ -1188,20 +1191,24 @@ static int si5351_dt_parse(struct i2c_client *client, + * property silabs,pll-source : , [<..>] + * allow to selectively set pll source + */ +- of_property_for_each_u32(np, "silabs,pll-source", prop, p, num) { ++ sz = of_property_read_variable_u32_array(np, "silabs,pll-source", array, 2, 4); ++ sz = (sz == -EINVAL) ? 0 : sz; /* Missing property is OK */ ++ if (sz < 0) ++ return dev_err_probe(&client->dev, sz, "invalid pll-source\n"); ++ if (sz % 2) ++ return dev_err_probe(&client->dev, -EINVAL, ++ "missing pll-source for pll %d\n", array[sz - 1]); ++ ++ for (i = 0; i < sz; i += 2) { ++ num = array[i]; ++ val = array[i + 1]; ++ + if (num >= 2) { + dev_err(&client->dev, + "invalid pll %d on pll-source prop\n", num); + return -EINVAL; + } + +- p = of_prop_next_u32(prop, p, &val); +- if (!p) { +- dev_err(&client->dev, +- "missing pll-source for pll %d\n", num); +- return -EINVAL; +- } +- + switch (val) { + case 0: + pdata->pll_src[num] = SI5351_PLL_SRC_XTAL; +@@ -1222,6 +1229,49 @@ static int si5351_dt_parse(struct i2c_client *client, + } + } + ++ /* ++ * Parse PLL reset mode. For compatibility with older device trees, the ++ * default is to always reset a PLL after setting its rate. ++ */ ++ pdata->pll_reset[0] = true; ++ pdata->pll_reset[1] = true; ++ ++ sz = of_property_read_variable_u32_array(np, "silabs,pll-reset-mode", array, 2, 4); ++ sz = (sz == -EINVAL) ? 0 : sz; /* Missing property is OK */ ++ if (sz < 0) ++ return dev_err_probe(&client->dev, sz, "invalid pll-reset-mode\n"); ++ if (sz % 2) ++ return dev_err_probe(&client->dev, -EINVAL, ++ "missing pll-reset-mode for pll %d\n", array[sz - 1]); ++ ++ for (i = 0; i < sz; i += 2) { ++ num = array[i]; ++ val = array[i + 1]; ++ ++ if (num >= 2) { ++ dev_err(&client->dev, ++ "invalid pll %d on pll-reset-mode prop\n", num); ++ return -EINVAL; ++ } ++ ++ ++ switch (val) { ++ case 0: ++ /* Reset PLL whenever its rate is adjusted */ ++ pdata->pll_reset[num] = true; ++ break; ++ case 1: ++ /* Don't reset PLL whenever its rate is adjusted */ ++ pdata->pll_reset[num] = false; ++ break; ++ default: ++ dev_err(&client->dev, ++ "invalid pll-reset-mode %d for pll %d\n", val, ++ num); ++ return -EINVAL; ++ } ++ } ++ + /* per clkout properties */ + for_each_child_of_node(np, child) { + if (of_property_read_u32(child, "reg", &num)) { +diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c +index f8776065ad1f19..5bbd036f5295f5 100644 +--- a/drivers/clk/clk.c ++++ b/drivers/clk/clk.c +@@ -5316,9 +5316,8 @@ EXPORT_SYMBOL_GPL(of_clk_get_parent_count); + const char *of_clk_get_parent_name(const struct device_node *np, int index) + { + struct of_phandle_args clkspec; +- struct property *prop; + const char *clk_name; +- const __be32 *vp; ++ bool found = false; + u32 pv; + int rc; + int count; +@@ -5335,16 +5334,19 @@ const char *of_clk_get_parent_name(const struct device_node *np, int index) + /* if there is an indices property, use it to transfer the index + * specified into an array offset for the clock-output-names property. + */ +- of_property_for_each_u32(clkspec.np, "clock-indices", prop, vp, pv) { ++ of_property_for_each_u32(clkspec.np, "clock-indices", pv) { + if (index == pv) { + index = count; ++ found = true; + break; + } + count++; + } + /* We went off the end of 'clock-indices' without finding it */ +- if (prop && !vp) ++ if (of_property_present(clkspec.np, "clock-indices") && !found) { ++ of_node_put(clkspec.np); + return NULL; ++ } + + if (of_property_read_string_index(clkspec.np, "clock-output-names", + index, +@@ -5456,14 +5458,12 @@ static int parent_ready(struct device_node *np) + int of_clk_detect_critical(struct device_node *np, int index, + unsigned long *flags) + { +- struct property *prop; +- const __be32 *cur; + uint32_t idx; + + if (!np || !flags) + return -EINVAL; + +- of_property_for_each_u32(np, "clock-critical", prop, cur, idx) ++ of_property_for_each_u32(np, "clock-critical", idx) + if (index == idx) + *flags |= CLK_IS_CRITICAL; + +diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c +index e561ff7b135fb5..747f5397692e5f 100644 +--- a/drivers/clk/imx/clk-imx8mp.c ++++ b/drivers/clk/imx/clk-imx8mp.c +@@ -399,8 +399,9 @@ static const char * const imx8mp_dram_core_sels[] = {"dram_pll_out", "dram_alt_r + + static const char * const imx8mp_clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll1_out", + "dummy", "dummy", "gpu_pll_out", "vpu_pll_out", +- "arm_pll_out", "sys_pll1", "sys_pll2", "sys_pll3", +- "dummy", "dummy", "osc_24m", "dummy", "osc_32k"}; ++ "arm_pll_out", "sys_pll1_out", "sys_pll2_out", ++ "sys_pll3_out", "dummy", "dummy", "osc_24m", ++ "dummy", "osc_32k"}; + + static struct clk_hw **hws; + static struct clk_hw_onecell_data *clk_hw_data; +diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c +index 75f09e6e057e1a..35bd987f2e52ab 100644 +--- a/drivers/clk/qcom/common.c ++++ b/drivers/clk/qcom/common.c +@@ -208,11 +208,9 @@ EXPORT_SYMBOL_GPL(qcom_cc_register_sleep_clk); + static void qcom_cc_drop_protected(struct device *dev, struct qcom_cc *cc) + { + struct device_node *np = dev->of_node; +- struct property *prop; +- const __be32 *p; + u32 i; + +- of_property_for_each_u32(np, "protected-clocks", prop, p, i) { ++ of_property_for_each_u32(np, "protected-clocks", i) { + if (i >= cc->num_rclks) + continue; + +diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c +index ea4c3bf4fb9bf7..1a23bfd9356d58 100644 +--- a/drivers/clk/qcom/gcc-sdm845.c ++++ b/drivers/clk/qcom/gcc-sdm845.c +@@ -454,7 +454,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s0_clk_src_init = { + .name = "gcc_qupv3_wrap0_s0_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = { +@@ -470,7 +470,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s1_clk_src_init = { + .name = "gcc_qupv3_wrap0_s1_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = { +@@ -486,7 +486,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s2_clk_src_init = { + .name = "gcc_qupv3_wrap0_s2_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = { +@@ -502,7 +502,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s3_clk_src_init = { + .name = "gcc_qupv3_wrap0_s3_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = { +@@ -518,7 +518,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s4_clk_src_init = { + .name = "gcc_qupv3_wrap0_s4_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = { +@@ -534,7 +534,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s5_clk_src_init = { + .name = "gcc_qupv3_wrap0_s5_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = { +@@ -550,7 +550,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s6_clk_src_init = { + .name = "gcc_qupv3_wrap0_s6_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap0_s6_clk_src = { +@@ -566,7 +566,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s7_clk_src_init = { + .name = "gcc_qupv3_wrap0_s7_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap0_s7_clk_src = { +@@ -582,7 +582,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s0_clk_src_init = { + .name = "gcc_qupv3_wrap1_s0_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = { +@@ -598,7 +598,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s1_clk_src_init = { + .name = "gcc_qupv3_wrap1_s1_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = { +@@ -614,7 +614,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s2_clk_src_init = { + .name = "gcc_qupv3_wrap1_s2_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = { +@@ -630,7 +630,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s3_clk_src_init = { + .name = "gcc_qupv3_wrap1_s3_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = { +@@ -646,7 +646,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s4_clk_src_init = { + .name = "gcc_qupv3_wrap1_s4_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = { +@@ -662,7 +662,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s5_clk_src_init = { + .name = "gcc_qupv3_wrap1_s5_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = { +@@ -678,7 +678,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s6_clk_src_init = { + .name = "gcc_qupv3_wrap1_s6_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap1_s6_clk_src = { +@@ -694,7 +694,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s7_clk_src_init = { + .name = "gcc_qupv3_wrap1_s7_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap1_s7_clk_src = { +diff --git a/drivers/clk/ralink/clk-mtmips.c b/drivers/clk/ralink/clk-mtmips.c +index 76285fbbdeaa2d..4b5d8b741e4e17 100644 +--- a/drivers/clk/ralink/clk-mtmips.c ++++ b/drivers/clk/ralink/clk-mtmips.c +@@ -264,7 +264,6 @@ static int mtmips_register_pherip_clocks(struct device_node *np, + } + + static struct mtmips_clk_fixed rt3883_fixed_clocks[] = { +- CLK_FIXED("xtal", NULL, 40000000), + CLK_FIXED("periph", "xtal", 40000000) + }; + +diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c +index 6a4b2b9ef30a82..aee1a2f14c9517 100644 +--- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c ++++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c +@@ -533,11 +533,11 @@ static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents, + CLK_SET_RATE_PARENT); + + /* +- * DSI output seems to work only when PLL_MIPI selected. Set it and prevent +- * the mux from reparenting. ++ * Experiments showed that RGB output requires pll-video0-2x, while DSI ++ * requires pll-mipi. It will not work with incorrect clock, the screen will ++ * be blank. ++ * sun50i-a64.dtsi assigns pll-mipi as TCON0 parent by default + */ +-#define SUN50I_A64_TCON0_CLK_REG 0x118 +- + static const char * const tcon0_parents[] = { "pll-mipi", "pll-video0-2x" }; + static const u8 tcon0_table[] = { 0, 2, }; + static SUNXI_CCU_MUX_TABLE_WITH_GATE_CLOSEST(tcon0_clk, "tcon0", tcon0_parents, +@@ -957,11 +957,6 @@ static int sun50i_a64_ccu_probe(struct platform_device *pdev) + + writel(0x515, reg + SUN50I_A64_PLL_MIPI_REG); + +- /* Set PLL MIPI as parent for TCON0 */ +- val = readl(reg + SUN50I_A64_TCON0_CLK_REG); +- val &= ~GENMASK(26, 24); +- writel(val | (0 << 24), reg + SUN50I_A64_TCON0_CLK_REG); +- + ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_a64_ccu_desc); + if (ret) + return ret; +diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.h b/drivers/clk/sunxi-ng/ccu-sun50i-a64.h +index a8c11c0b4e0676..dfba88a5ad0f7c 100644 +--- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.h ++++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.h +@@ -21,7 +21,6 @@ + + /* PLL_VIDEO0 exported for HDMI PHY */ + +-#define CLK_PLL_VIDEO0_2X 8 + #define CLK_PLL_VE 9 + #define CLK_PLL_DDR0 10 + +@@ -32,7 +31,6 @@ + #define CLK_PLL_PERIPH1_2X 14 + #define CLK_PLL_VIDEO1 15 + #define CLK_PLL_GPU 16 +-#define CLK_PLL_MIPI 17 + #define CLK_PLL_HSIC 18 + #define CLK_PLL_DE 19 + #define CLK_PLL_DDR1 20 +diff --git a/drivers/clk/sunxi/clk-simple-gates.c b/drivers/clk/sunxi/clk-simple-gates.c +index 0399627c226a68..845efc1ec800b9 100644 +--- a/drivers/clk/sunxi/clk-simple-gates.c ++++ b/drivers/clk/sunxi/clk-simple-gates.c +@@ -21,11 +21,9 @@ static void __init sunxi_simple_gates_setup(struct device_node *node, + { + struct clk_onecell_data *clk_data; + const char *clk_parent, *clk_name; +- struct property *prop; + struct resource res; + void __iomem *clk_reg; + void __iomem *reg; +- const __be32 *p; + int number, i = 0, j; + u8 clk_bit; + u32 index; +@@ -47,7 +45,7 @@ static void __init sunxi_simple_gates_setup(struct device_node *node, + if (!clk_data->clks) + goto err_free_data; + +- of_property_for_each_u32(node, "clock-indices", prop, p, index) { ++ of_property_for_each_u32(node, "clock-indices", index) { + of_property_read_string_index(node, "clock-output-names", + i, &clk_name); + +diff --git a/drivers/clk/sunxi/clk-sun8i-bus-gates.c b/drivers/clk/sunxi/clk-sun8i-bus-gates.c +index b87f331f63c9e8..8482ac8e5898a0 100644 +--- a/drivers/clk/sunxi/clk-sun8i-bus-gates.c ++++ b/drivers/clk/sunxi/clk-sun8i-bus-gates.c +@@ -24,11 +24,9 @@ static void __init sun8i_h3_bus_gates_init(struct device_node *node) + const char *parents[PARENT_MAX]; + struct clk_onecell_data *clk_data; + const char *clk_name; +- struct property *prop; + struct resource res; + void __iomem *clk_reg; + void __iomem *reg; +- const __be32 *p; + int number, i; + u8 clk_bit; + int index; +@@ -58,7 +56,7 @@ static void __init sun8i_h3_bus_gates_init(struct device_node *node) + goto err_free_data; + + i = 0; +- of_property_for_each_u32(node, "clock-indices", prop, p, index) { ++ of_property_for_each_u32(node, "clock-indices", index) { + of_property_read_string_index(node, "clock-output-names", + i, &clk_name); + +diff --git a/drivers/clocksource/samsung_pwm_timer.c b/drivers/clocksource/samsung_pwm_timer.c +index 6e46781bc9acff..b9561e3f196c42 100644 +--- a/drivers/clocksource/samsung_pwm_timer.c ++++ b/drivers/clocksource/samsung_pwm_timer.c +@@ -418,8 +418,6 @@ void __init samsung_pwm_clocksource_init(void __iomem *base, + static int __init samsung_pwm_alloc(struct device_node *np, + const struct samsung_pwm_variant *variant) + { +- struct property *prop; +- const __be32 *cur; + u32 val; + int i, ret; + +@@ -427,7 +425,7 @@ static int __init samsung_pwm_alloc(struct device_node *np, + for (i = 0; i < SAMSUNG_PWM_NUM; ++i) + pwm.irq[i] = irq_of_parse_and_map(np, i); + +- of_property_for_each_u32(np, "samsung,pwm-outputs", prop, cur, val) { ++ of_property_for_each_u32(np, "samsung,pwm-outputs", val) { + if (val >= SAMSUNG_PWM_NUM) { + pr_warn("%s: invalid channel index in samsung,pwm-outputs property\n", __func__); + continue; +diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c +index 4ac3a35dcd983c..0615e7fa20ad7e 100644 +--- a/drivers/cpufreq/acpi-cpufreq.c ++++ b/drivers/cpufreq/acpi-cpufreq.c +@@ -628,7 +628,14 @@ static int acpi_cpufreq_blacklist(struct cpuinfo_x86 *c) + #endif + + #ifdef CONFIG_ACPI_CPPC_LIB +-static u64 get_max_boost_ratio(unsigned int cpu) ++/* ++ * get_max_boost_ratio: Computes the max_boost_ratio as the ratio ++ * between the highest_perf and the nominal_perf. ++ * ++ * Returns the max_boost_ratio for @cpu. Returns the CPPC nominal ++ * frequency via @nominal_freq if it is non-NULL pointer. ++ */ ++static u64 get_max_boost_ratio(unsigned int cpu, u64 *nominal_freq) + { + struct cppc_perf_caps perf_caps; + u64 highest_perf, nominal_perf; +@@ -651,6 +658,9 @@ static u64 get_max_boost_ratio(unsigned int cpu) + + nominal_perf = perf_caps.nominal_perf; + ++ if (nominal_freq) ++ *nominal_freq = perf_caps.nominal_freq; ++ + if (!highest_perf || !nominal_perf) { + pr_debug("CPU%d: highest or nominal performance missing\n", cpu); + return 0; +@@ -663,8 +673,12 @@ static u64 get_max_boost_ratio(unsigned int cpu) + + return div_u64(highest_perf << SCHED_CAPACITY_SHIFT, nominal_perf); + } ++ + #else +-static inline u64 get_max_boost_ratio(unsigned int cpu) { return 0; } ++static inline u64 get_max_boost_ratio(unsigned int cpu, u64 *nominal_freq) ++{ ++ return 0; ++} + #endif + + static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) +@@ -674,9 +688,9 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) + struct acpi_cpufreq_data *data; + unsigned int cpu = policy->cpu; + struct cpuinfo_x86 *c = &cpu_data(cpu); ++ u64 max_boost_ratio, nominal_freq = 0; + unsigned int valid_states = 0; + unsigned int result = 0; +- u64 max_boost_ratio; + unsigned int i; + #ifdef CONFIG_SMP + static int blacklisted; +@@ -826,16 +840,20 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) + } + freq_table[valid_states].frequency = CPUFREQ_TABLE_END; + +- max_boost_ratio = get_max_boost_ratio(cpu); ++ max_boost_ratio = get_max_boost_ratio(cpu, &nominal_freq); + if (max_boost_ratio) { +- unsigned int freq = freq_table[0].frequency; ++ unsigned int freq = nominal_freq; + + /* +- * Because the loop above sorts the freq_table entries in the +- * descending order, freq is the maximum frequency in the table. +- * Assume that it corresponds to the CPPC nominal frequency and +- * use it to set cpuinfo.max_freq. ++ * The loop above sorts the freq_table entries in the ++ * descending order. If ACPI CPPC has not advertised ++ * the nominal frequency (this is possible in CPPC ++ * revisions prior to 3), then use the first entry in ++ * the pstate table as a proxy for nominal frequency. + */ ++ if (!freq) ++ freq = freq_table[0].frequency; ++ + policy->cpuinfo.max_freq = freq * max_boost_ratio >> SCHED_CAPACITY_SHIFT; + } else { + /* +diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c +index 70b0f21968a010..92c0fc4a3cf60b 100644 +--- a/drivers/cpufreq/qcom-cpufreq-hw.c ++++ b/drivers/cpufreq/qcom-cpufreq-hw.c +@@ -142,14 +142,12 @@ static unsigned long qcom_lmh_get_throttle_freq(struct qcom_cpufreq_data *data) + } + + /* Get the frequency requested by the cpufreq core for the CPU */ +-static unsigned int qcom_cpufreq_get_freq(unsigned int cpu) ++static unsigned int qcom_cpufreq_get_freq(struct cpufreq_policy *policy) + { + struct qcom_cpufreq_data *data; + const struct qcom_cpufreq_soc_data *soc_data; +- struct cpufreq_policy *policy; + unsigned int index; + +- policy = cpufreq_cpu_get_raw(cpu); + if (!policy) + return 0; + +@@ -162,12 +160,10 @@ static unsigned int qcom_cpufreq_get_freq(unsigned int cpu) + return policy->freq_table[index].frequency; + } + +-static unsigned int qcom_cpufreq_hw_get(unsigned int cpu) ++static unsigned int __qcom_cpufreq_hw_get(struct cpufreq_policy *policy) + { + struct qcom_cpufreq_data *data; +- struct cpufreq_policy *policy; + +- policy = cpufreq_cpu_get_raw(cpu); + if (!policy) + return 0; + +@@ -176,7 +172,12 @@ static unsigned int qcom_cpufreq_hw_get(unsigned int cpu) + if (data->throttle_irq >= 0) + return qcom_lmh_get_throttle_freq(data) / HZ_PER_KHZ; + +- return qcom_cpufreq_get_freq(cpu); ++ return qcom_cpufreq_get_freq(policy); ++} ++ ++static unsigned int qcom_cpufreq_hw_get(unsigned int cpu) ++{ ++ return __qcom_cpufreq_hw_get(cpufreq_cpu_get_raw(cpu)); + } + + static unsigned int qcom_cpufreq_hw_fast_switch(struct cpufreq_policy *policy, +@@ -362,7 +363,7 @@ static void qcom_lmh_dcvs_notify(struct qcom_cpufreq_data *data) + * If h/w throttled frequency is higher than what cpufreq has requested + * for, then stop polling and switch back to interrupt mechanism. + */ +- if (throttled_freq >= qcom_cpufreq_get_freq(cpu)) ++ if (throttled_freq >= qcom_cpufreq_get_freq(cpufreq_cpu_get_raw(cpu))) + enable_irq(data->throttle_irq); + else + mod_delayed_work(system_highpri_wq, &data->throttle_work, +@@ -440,7 +441,6 @@ static int qcom_cpufreq_hw_lmh_init(struct cpufreq_policy *policy, int index) + return data->throttle_irq; + + data->cancel_throttle = false; +- data->policy = policy; + + mutex_init(&data->throttle_lock); + INIT_DEFERRABLE_WORK(&data->throttle_work, qcom_lmh_dcvs_poll); +@@ -551,6 +551,7 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy) + + policy->driver_data = data; + policy->dvfs_possible_from_any_cpu = true; ++ data->policy = policy; + + ret = qcom_cpufreq_hw_read_lut(cpu_dev, policy); + if (ret) { +@@ -623,11 +624,24 @@ static unsigned long qcom_cpufreq_hw_recalc_rate(struct clk_hw *hw, unsigned lon + { + struct qcom_cpufreq_data *data = container_of(hw, struct qcom_cpufreq_data, cpu_clk); + +- return qcom_lmh_get_throttle_freq(data); ++ return __qcom_cpufreq_hw_get(data->policy) * HZ_PER_KHZ; ++} ++ ++/* ++ * Since we cannot determine the closest rate of the target rate, let's just ++ * return the actual rate at which the clock is running at. This is needed to ++ * make clk_set_rate() API work properly. ++ */ ++static int qcom_cpufreq_hw_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) ++{ ++ req->rate = qcom_cpufreq_hw_recalc_rate(hw, 0); ++ ++ return 0; + } + + static const struct clk_ops qcom_cpufreq_hw_clk_ops = { + .recalc_rate = qcom_cpufreq_hw_recalc_rate, ++ .determine_rate = qcom_cpufreq_hw_determine_rate, + }; + + static int qcom_cpufreq_hw_driver_probe(struct platform_device *pdev) +diff --git a/drivers/crypto/caam/blob_gen.c b/drivers/crypto/caam/blob_gen.c +index 87781c1534ee5b..079a22cc9f02be 100644 +--- a/drivers/crypto/caam/blob_gen.c ++++ b/drivers/crypto/caam/blob_gen.c +@@ -2,6 +2,7 @@ + /* + * Copyright (C) 2015 Pengutronix, Steffen Trumtrar + * Copyright (C) 2021 Pengutronix, Ahmad Fatoum ++ * Copyright 2024 NXP + */ + + #define pr_fmt(fmt) "caam blob_gen: " fmt +@@ -104,7 +105,7 @@ int caam_process_blob(struct caam_blob_priv *priv, + } + + ctrlpriv = dev_get_drvdata(jrdev->parent); +- moo = FIELD_GET(CSTA_MOO, rd_reg32(&ctrlpriv->ctrl->perfmon.status)); ++ moo = FIELD_GET(CSTA_MOO, rd_reg32(&ctrlpriv->jr[0]->perfmon.status)); + if (moo != CSTA_MOO_SECURE && moo != CSTA_MOO_TRUSTED) + dev_warn(jrdev, + "using insecure test key, enable HAB to use unique device key!\n"); +diff --git a/drivers/crypto/hisilicon/sec2/sec.h b/drivers/crypto/hisilicon/sec2/sec.h +index 410c83712e2851..30c2b1a64695c0 100644 +--- a/drivers/crypto/hisilicon/sec2/sec.h ++++ b/drivers/crypto/hisilicon/sec2/sec.h +@@ -37,6 +37,7 @@ struct sec_aead_req { + u8 *a_ivin; + dma_addr_t a_ivin_dma; + struct aead_request *aead_req; ++ bool fallback; + }; + + /* SEC request of Crypto */ +@@ -90,9 +91,7 @@ struct sec_auth_ctx { + dma_addr_t a_key_dma; + u8 *a_key; + u8 a_key_len; +- u8 mac_len; + u8 a_alg; +- bool fallback; + struct crypto_shash *hash_tfm; + struct crypto_aead *fallback_aead_tfm; + }; +diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.c b/drivers/crypto/hisilicon/sec2/sec_crypto.c +index 932cc277eb3a5e..8a6dd2513370a2 100644 +--- a/drivers/crypto/hisilicon/sec2/sec_crypto.c ++++ b/drivers/crypto/hisilicon/sec2/sec_crypto.c +@@ -849,6 +849,7 @@ static int sec_skcipher_setkey(struct crypto_skcipher *tfm, const u8 *key, + ret = sec_skcipher_aes_sm4_setkey(c_ctx, keylen, c_mode); + break; + default: ++ dev_err(dev, "sec c_alg err!\n"); + return -EINVAL; + } + +@@ -952,15 +953,14 @@ static int sec_aead_mac_init(struct sec_aead_req *req) + struct aead_request *aead_req = req->aead_req; + struct crypto_aead *tfm = crypto_aead_reqtfm(aead_req); + size_t authsize = crypto_aead_authsize(tfm); +- u8 *mac_out = req->out_mac; + struct scatterlist *sgl = aead_req->src; ++ u8 *mac_out = req->out_mac; + size_t copy_size; + off_t skip_size; + + /* Copy input mac */ + skip_size = aead_req->assoclen + aead_req->cryptlen - authsize; +- copy_size = sg_pcopy_to_buffer(sgl, sg_nents(sgl), mac_out, +- authsize, skip_size); ++ copy_size = sg_pcopy_to_buffer(sgl, sg_nents(sgl), mac_out, authsize, skip_size); + if (unlikely(copy_size != authsize)) + return -EINVAL; + +@@ -1123,10 +1123,7 @@ static int sec_aead_setauthsize(struct crypto_aead *aead, unsigned int authsize) + struct sec_ctx *ctx = crypto_tfm_ctx(tfm); + struct sec_auth_ctx *a_ctx = &ctx->a_ctx; + +- if (unlikely(a_ctx->fallback_aead_tfm)) +- return crypto_aead_setauthsize(a_ctx->fallback_aead_tfm, authsize); +- +- return 0; ++ return crypto_aead_setauthsize(a_ctx->fallback_aead_tfm, authsize); + } + + static int sec_aead_fallback_setkey(struct sec_auth_ctx *a_ctx, +@@ -1142,7 +1139,6 @@ static int sec_aead_fallback_setkey(struct sec_auth_ctx *a_ctx, + static int sec_aead_setkey(struct crypto_aead *tfm, const u8 *key, + const u32 keylen, const enum sec_hash_alg a_alg, + const enum sec_calg c_alg, +- const enum sec_mac_len mac_len, + const enum sec_cmode c_mode) + { + struct sec_ctx *ctx = crypto_aead_ctx(tfm); +@@ -1154,7 +1150,6 @@ static int sec_aead_setkey(struct crypto_aead *tfm, const u8 *key, + + ctx->a_ctx.a_alg = a_alg; + ctx->c_ctx.c_alg = c_alg; +- ctx->a_ctx.mac_len = mac_len; + c_ctx->c_mode = c_mode; + + if (c_mode == SEC_CMODE_CCM || c_mode == SEC_CMODE_GCM) { +@@ -1165,16 +1160,11 @@ static int sec_aead_setkey(struct crypto_aead *tfm, const u8 *key, + } + memcpy(c_ctx->c_key, key, keylen); + +- if (unlikely(a_ctx->fallback_aead_tfm)) { +- ret = sec_aead_fallback_setkey(a_ctx, tfm, key, keylen); +- if (ret) +- return ret; +- } +- +- return 0; ++ return sec_aead_fallback_setkey(a_ctx, tfm, key, keylen); + } + +- if (crypto_authenc_extractkeys(&keys, key, keylen)) ++ ret = crypto_authenc_extractkeys(&keys, key, keylen); ++ if (ret) + goto bad_key; + + ret = sec_aead_aes_set_key(c_ctx, &keys); +@@ -1189,9 +1179,15 @@ static int sec_aead_setkey(struct crypto_aead *tfm, const u8 *key, + goto bad_key; + } + +- if ((ctx->a_ctx.mac_len & SEC_SQE_LEN_RATE_MASK) || +- (ctx->a_ctx.a_key_len & SEC_SQE_LEN_RATE_MASK)) { +- dev_err(dev, "MAC or AUTH key length error!\n"); ++ if (ctx->a_ctx.a_key_len & SEC_SQE_LEN_RATE_MASK) { ++ ret = -EINVAL; ++ dev_err(dev, "AUTH key length error!\n"); ++ goto bad_key; ++ } ++ ++ ret = sec_aead_fallback_setkey(a_ctx, tfm, key, keylen); ++ if (ret) { ++ dev_err(dev, "set sec fallback key err!\n"); + goto bad_key; + } + +@@ -1199,31 +1195,23 @@ static int sec_aead_setkey(struct crypto_aead *tfm, const u8 *key, + + bad_key: + memzero_explicit(&keys, sizeof(struct crypto_authenc_keys)); +- return -EINVAL; ++ return ret; + } + + +-#define GEN_SEC_AEAD_SETKEY_FUNC(name, aalg, calg, maclen, cmode) \ +-static int sec_setkey_##name(struct crypto_aead *tfm, const u8 *key, \ +- u32 keylen) \ +-{ \ +- return sec_aead_setkey(tfm, key, keylen, aalg, calg, maclen, cmode);\ +-} +- +-GEN_SEC_AEAD_SETKEY_FUNC(aes_cbc_sha1, SEC_A_HMAC_SHA1, +- SEC_CALG_AES, SEC_HMAC_SHA1_MAC, SEC_CMODE_CBC) +-GEN_SEC_AEAD_SETKEY_FUNC(aes_cbc_sha256, SEC_A_HMAC_SHA256, +- SEC_CALG_AES, SEC_HMAC_SHA256_MAC, SEC_CMODE_CBC) +-GEN_SEC_AEAD_SETKEY_FUNC(aes_cbc_sha512, SEC_A_HMAC_SHA512, +- SEC_CALG_AES, SEC_HMAC_SHA512_MAC, SEC_CMODE_CBC) +-GEN_SEC_AEAD_SETKEY_FUNC(aes_ccm, 0, SEC_CALG_AES, +- SEC_HMAC_CCM_MAC, SEC_CMODE_CCM) +-GEN_SEC_AEAD_SETKEY_FUNC(aes_gcm, 0, SEC_CALG_AES, +- SEC_HMAC_GCM_MAC, SEC_CMODE_GCM) +-GEN_SEC_AEAD_SETKEY_FUNC(sm4_ccm, 0, SEC_CALG_SM4, +- SEC_HMAC_CCM_MAC, SEC_CMODE_CCM) +-GEN_SEC_AEAD_SETKEY_FUNC(sm4_gcm, 0, SEC_CALG_SM4, +- SEC_HMAC_GCM_MAC, SEC_CMODE_GCM) ++#define GEN_SEC_AEAD_SETKEY_FUNC(name, aalg, calg, cmode) \ ++static int sec_setkey_##name(struct crypto_aead *tfm, const u8 *key, u32 keylen) \ ++{ \ ++ return sec_aead_setkey(tfm, key, keylen, aalg, calg, cmode); \ ++} ++ ++GEN_SEC_AEAD_SETKEY_FUNC(aes_cbc_sha1, SEC_A_HMAC_SHA1, SEC_CALG_AES, SEC_CMODE_CBC) ++GEN_SEC_AEAD_SETKEY_FUNC(aes_cbc_sha256, SEC_A_HMAC_SHA256, SEC_CALG_AES, SEC_CMODE_CBC) ++GEN_SEC_AEAD_SETKEY_FUNC(aes_cbc_sha512, SEC_A_HMAC_SHA512, SEC_CALG_AES, SEC_CMODE_CBC) ++GEN_SEC_AEAD_SETKEY_FUNC(aes_ccm, 0, SEC_CALG_AES, SEC_CMODE_CCM) ++GEN_SEC_AEAD_SETKEY_FUNC(aes_gcm, 0, SEC_CALG_AES, SEC_CMODE_GCM) ++GEN_SEC_AEAD_SETKEY_FUNC(sm4_ccm, 0, SEC_CALG_SM4, SEC_CMODE_CCM) ++GEN_SEC_AEAD_SETKEY_FUNC(sm4_gcm, 0, SEC_CALG_SM4, SEC_CMODE_GCM) + + static int sec_aead_sgl_map(struct sec_ctx *ctx, struct sec_req *req) + { +@@ -1471,9 +1459,10 @@ static void sec_skcipher_callback(struct sec_ctx *ctx, struct sec_req *req, + static void set_aead_auth_iv(struct sec_ctx *ctx, struct sec_req *req) + { + struct aead_request *aead_req = req->aead_req.aead_req; +- struct sec_cipher_req *c_req = &req->c_req; ++ struct crypto_aead *tfm = crypto_aead_reqtfm(aead_req); ++ size_t authsize = crypto_aead_authsize(tfm); + struct sec_aead_req *a_req = &req->aead_req; +- size_t authsize = ctx->a_ctx.mac_len; ++ struct sec_cipher_req *c_req = &req->c_req; + u32 data_size = aead_req->cryptlen; + u8 flage = 0; + u8 cm, cl; +@@ -1514,10 +1503,8 @@ static void set_aead_auth_iv(struct sec_ctx *ctx, struct sec_req *req) + static void sec_aead_set_iv(struct sec_ctx *ctx, struct sec_req *req) + { + struct aead_request *aead_req = req->aead_req.aead_req; +- struct crypto_aead *tfm = crypto_aead_reqtfm(aead_req); +- size_t authsize = crypto_aead_authsize(tfm); +- struct sec_cipher_req *c_req = &req->c_req; + struct sec_aead_req *a_req = &req->aead_req; ++ struct sec_cipher_req *c_req = &req->c_req; + + memcpy(c_req->c_ivin, aead_req->iv, ctx->c_ctx.ivsize); + +@@ -1525,15 +1512,11 @@ static void sec_aead_set_iv(struct sec_ctx *ctx, struct sec_req *req) + /* + * CCM 16Byte Cipher_IV: {1B_Flage,13B_IV,2B_counter}, + * the counter must set to 0x01 ++ * CCM 16Byte Auth_IV: {1B_AFlage,13B_IV,2B_Ptext_length} + */ +- ctx->a_ctx.mac_len = authsize; +- /* CCM 16Byte Auth_IV: {1B_AFlage,13B_IV,2B_Ptext_length} */ + set_aead_auth_iv(ctx, req); +- } +- +- /* GCM 12Byte Cipher_IV == Auth_IV */ +- if (ctx->c_ctx.c_mode == SEC_CMODE_GCM) { +- ctx->a_ctx.mac_len = authsize; ++ } else if (ctx->c_ctx.c_mode == SEC_CMODE_GCM) { ++ /* GCM 12Byte Cipher_IV == Auth_IV */ + memcpy(a_req->a_ivin, c_req->c_ivin, SEC_AIV_SIZE); + } + } +@@ -1543,9 +1526,11 @@ static void sec_auth_bd_fill_xcm(struct sec_auth_ctx *ctx, int dir, + { + struct sec_aead_req *a_req = &req->aead_req; + struct aead_request *aq = a_req->aead_req; ++ struct crypto_aead *tfm = crypto_aead_reqtfm(aq); ++ size_t authsize = crypto_aead_authsize(tfm); + + /* C_ICV_Len is MAC size, 0x4 ~ 0x10 */ +- sec_sqe->type2.icvw_kmode |= cpu_to_le16((u16)ctx->mac_len); ++ sec_sqe->type2.icvw_kmode |= cpu_to_le16((u16)authsize); + + /* mode set to CCM/GCM, don't set {A_Alg, AKey_Len, MAC_Len} */ + sec_sqe->type2.a_key_addr = sec_sqe->type2.c_key_addr; +@@ -1569,9 +1554,11 @@ static void sec_auth_bd_fill_xcm_v3(struct sec_auth_ctx *ctx, int dir, + { + struct sec_aead_req *a_req = &req->aead_req; + struct aead_request *aq = a_req->aead_req; ++ struct crypto_aead *tfm = crypto_aead_reqtfm(aq); ++ size_t authsize = crypto_aead_authsize(tfm); + + /* C_ICV_Len is MAC size, 0x4 ~ 0x10 */ +- sqe3->c_icv_key |= cpu_to_le16((u16)ctx->mac_len << SEC_MAC_OFFSET_V3); ++ sqe3->c_icv_key |= cpu_to_le16((u16)authsize << SEC_MAC_OFFSET_V3); + + /* mode set to CCM/GCM, don't set {A_Alg, AKey_Len, MAC_Len} */ + sqe3->a_key_addr = sqe3->c_key_addr; +@@ -1595,11 +1582,12 @@ static void sec_auth_bd_fill_ex(struct sec_auth_ctx *ctx, int dir, + struct sec_aead_req *a_req = &req->aead_req; + struct sec_cipher_req *c_req = &req->c_req; + struct aead_request *aq = a_req->aead_req; ++ struct crypto_aead *tfm = crypto_aead_reqtfm(aq); ++ size_t authsize = crypto_aead_authsize(tfm); + + sec_sqe->type2.a_key_addr = cpu_to_le64(ctx->a_key_dma); + +- sec_sqe->type2.mac_key_alg = +- cpu_to_le32(ctx->mac_len / SEC_SQE_LEN_RATE); ++ sec_sqe->type2.mac_key_alg = cpu_to_le32(authsize / SEC_SQE_LEN_RATE); + + sec_sqe->type2.mac_key_alg |= + cpu_to_le32((u32)((ctx->a_key_len) / +@@ -1649,11 +1637,13 @@ static void sec_auth_bd_fill_ex_v3(struct sec_auth_ctx *ctx, int dir, + struct sec_aead_req *a_req = &req->aead_req; + struct sec_cipher_req *c_req = &req->c_req; + struct aead_request *aq = a_req->aead_req; ++ struct crypto_aead *tfm = crypto_aead_reqtfm(aq); ++ size_t authsize = crypto_aead_authsize(tfm); + + sqe3->a_key_addr = cpu_to_le64(ctx->a_key_dma); + + sqe3->auth_mac_key |= +- cpu_to_le32((u32)(ctx->mac_len / ++ cpu_to_le32((u32)(authsize / + SEC_SQE_LEN_RATE) << SEC_MAC_OFFSET_V3); + + sqe3->auth_mac_key |= +@@ -1704,9 +1694,9 @@ static void sec_aead_callback(struct sec_ctx *c, struct sec_req *req, int err) + { + struct aead_request *a_req = req->aead_req.aead_req; + struct crypto_aead *tfm = crypto_aead_reqtfm(a_req); ++ size_t authsize = crypto_aead_authsize(tfm); + struct sec_aead_req *aead_req = &req->aead_req; + struct sec_cipher_req *c_req = &req->c_req; +- size_t authsize = crypto_aead_authsize(tfm); + struct sec_qp_ctx *qp_ctx = req->qp_ctx; + struct aead_request *backlog_aead_req; + struct sec_req *backlog_req; +@@ -1719,10 +1709,8 @@ static void sec_aead_callback(struct sec_ctx *c, struct sec_req *req, int err) + if (!err && c_req->encrypt) { + struct scatterlist *sgl = a_req->dst; + +- sz = sg_pcopy_from_buffer(sgl, sg_nents(sgl), +- aead_req->out_mac, +- authsize, a_req->cryptlen + +- a_req->assoclen); ++ sz = sg_pcopy_from_buffer(sgl, sg_nents(sgl), aead_req->out_mac, ++ authsize, a_req->cryptlen + a_req->assoclen); + if (unlikely(sz != authsize)) { + dev_err(c->dev, "copy out mac err!\n"); + err = -EINVAL; +@@ -1930,8 +1918,10 @@ static void sec_aead_exit(struct crypto_aead *tfm) + + static int sec_aead_ctx_init(struct crypto_aead *tfm, const char *hash_name) + { ++ struct aead_alg *alg = crypto_aead_alg(tfm); + struct sec_ctx *ctx = crypto_aead_ctx(tfm); +- struct sec_auth_ctx *auth_ctx = &ctx->a_ctx; ++ struct sec_auth_ctx *a_ctx = &ctx->a_ctx; ++ const char *aead_name = alg->base.cra_name; + int ret; + + ret = sec_aead_init(tfm); +@@ -1940,11 +1930,20 @@ static int sec_aead_ctx_init(struct crypto_aead *tfm, const char *hash_name) + return ret; + } + +- auth_ctx->hash_tfm = crypto_alloc_shash(hash_name, 0, 0); +- if (IS_ERR(auth_ctx->hash_tfm)) { ++ a_ctx->hash_tfm = crypto_alloc_shash(hash_name, 0, 0); ++ if (IS_ERR(a_ctx->hash_tfm)) { + dev_err(ctx->dev, "aead alloc shash error!\n"); + sec_aead_exit(tfm); +- return PTR_ERR(auth_ctx->hash_tfm); ++ return PTR_ERR(a_ctx->hash_tfm); ++ } ++ ++ a_ctx->fallback_aead_tfm = crypto_alloc_aead(aead_name, 0, ++ CRYPTO_ALG_NEED_FALLBACK | CRYPTO_ALG_ASYNC); ++ if (IS_ERR(a_ctx->fallback_aead_tfm)) { ++ dev_err(ctx->dev, "aead driver alloc fallback tfm error!\n"); ++ crypto_free_shash(ctx->a_ctx.hash_tfm); ++ sec_aead_exit(tfm); ++ return PTR_ERR(a_ctx->fallback_aead_tfm); + } + + return 0; +@@ -1954,6 +1953,7 @@ static void sec_aead_ctx_exit(struct crypto_aead *tfm) + { + struct sec_ctx *ctx = crypto_aead_ctx(tfm); + ++ crypto_free_aead(ctx->a_ctx.fallback_aead_tfm); + crypto_free_shash(ctx->a_ctx.hash_tfm); + sec_aead_exit(tfm); + } +@@ -1980,7 +1980,6 @@ static int sec_aead_xcm_ctx_init(struct crypto_aead *tfm) + sec_aead_exit(tfm); + return PTR_ERR(a_ctx->fallback_aead_tfm); + } +- a_ctx->fallback = false; + + return 0; + } +@@ -2261,21 +2260,20 @@ static int sec_aead_spec_check(struct sec_ctx *ctx, struct sec_req *sreq) + { + struct aead_request *req = sreq->aead_req.aead_req; + struct crypto_aead *tfm = crypto_aead_reqtfm(req); +- size_t authsize = crypto_aead_authsize(tfm); ++ size_t sz = crypto_aead_authsize(tfm); + u8 c_mode = ctx->c_ctx.c_mode; + struct device *dev = ctx->dev; + int ret; + +- if (unlikely(req->cryptlen + req->assoclen > MAX_INPUT_DATA_LEN || +- req->assoclen > SEC_MAX_AAD_LEN)) { +- dev_err(dev, "aead input spec error!\n"); ++ /* Hardware does not handle cases where authsize is less than 4 bytes */ ++ if (unlikely(sz < MIN_MAC_LEN)) { ++ sreq->aead_req.fallback = true; + return -EINVAL; + } + +- if (unlikely((c_mode == SEC_CMODE_GCM && authsize < DES_BLOCK_SIZE) || +- (c_mode == SEC_CMODE_CCM && (authsize < MIN_MAC_LEN || +- authsize & MAC_LEN_MASK)))) { +- dev_err(dev, "aead input mac length error!\n"); ++ if (unlikely(req->cryptlen + req->assoclen > MAX_INPUT_DATA_LEN || ++ req->assoclen > SEC_MAX_AAD_LEN)) { ++ dev_err(dev, "aead input spec error!\n"); + return -EINVAL; + } + +@@ -2294,7 +2292,7 @@ static int sec_aead_spec_check(struct sec_ctx *ctx, struct sec_req *sreq) + if (sreq->c_req.encrypt) + sreq->c_req.c_len = req->cryptlen; + else +- sreq->c_req.c_len = req->cryptlen - authsize; ++ sreq->c_req.c_len = req->cryptlen - sz; + if (c_mode == SEC_CMODE_CBC) { + if (unlikely(sreq->c_req.c_len & (AES_BLOCK_SIZE - 1))) { + dev_err(dev, "aead crypto length error!\n"); +@@ -2320,8 +2318,8 @@ static int sec_aead_param_check(struct sec_ctx *ctx, struct sec_req *sreq) + + if (ctx->sec->qm.ver == QM_HW_V2) { + if (unlikely(!req->cryptlen || (!sreq->c_req.encrypt && +- req->cryptlen <= authsize))) { +- ctx->a_ctx.fallback = true; ++ req->cryptlen <= authsize))) { ++ sreq->aead_req.fallback = true; + return -EINVAL; + } + } +@@ -2349,16 +2347,9 @@ static int sec_aead_soft_crypto(struct sec_ctx *ctx, + bool encrypt) + { + struct sec_auth_ctx *a_ctx = &ctx->a_ctx; +- struct device *dev = ctx->dev; + struct aead_request *subreq; + int ret; + +- /* Kunpeng920 aead mode not support input 0 size */ +- if (!a_ctx->fallback_aead_tfm) { +- dev_err(dev, "aead fallback tfm is NULL!\n"); +- return -EINVAL; +- } +- + subreq = aead_request_alloc(a_ctx->fallback_aead_tfm, GFP_KERNEL); + if (!subreq) + return -ENOMEM; +@@ -2390,10 +2381,11 @@ static int sec_aead_crypto(struct aead_request *a_req, bool encrypt) + req->aead_req.aead_req = a_req; + req->c_req.encrypt = encrypt; + req->ctx = ctx; ++ req->aead_req.fallback = false; + + ret = sec_aead_param_check(ctx, req); + if (unlikely(ret)) { +- if (ctx->a_ctx.fallback) ++ if (req->aead_req.fallback) + return sec_aead_soft_crypto(ctx, a_req, encrypt); + return -EINVAL; + } +diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.h b/drivers/crypto/hisilicon/sec2/sec_crypto.h +index d033f63b583f85..db3fceb88e6937 100644 +--- a/drivers/crypto/hisilicon/sec2/sec_crypto.h ++++ b/drivers/crypto/hisilicon/sec2/sec_crypto.h +@@ -23,17 +23,6 @@ enum sec_hash_alg { + SEC_A_HMAC_SHA512 = 0x15, + }; + +-enum sec_mac_len { +- SEC_HMAC_CCM_MAC = 16, +- SEC_HMAC_GCM_MAC = 16, +- SEC_SM3_MAC = 32, +- SEC_HMAC_SM3_MAC = 32, +- SEC_HMAC_MD5_MAC = 16, +- SEC_HMAC_SHA1_MAC = 20, +- SEC_HMAC_SHA256_MAC = 32, +- SEC_HMAC_SHA512_MAC = 64, +-}; +- + enum sec_cmode { + SEC_CMODE_ECB = 0x0, + SEC_CMODE_CBC = 0x1, +diff --git a/drivers/crypto/intel/ixp4xx/ixp4xx_crypto.c b/drivers/crypto/intel/ixp4xx/ixp4xx_crypto.c +index 4a18095ae5d808..662aac9ea186df 100644 +--- a/drivers/crypto/intel/ixp4xx/ixp4xx_crypto.c ++++ b/drivers/crypto/intel/ixp4xx/ixp4xx_crypto.c +@@ -471,6 +471,7 @@ static int init_ixp_crypto(struct device *dev) + return -ENODEV; + } + npe_id = npe_spec.args[0]; ++ of_node_put(npe_spec.np); + + ret = of_parse_phandle_with_fixed_args(np, "queue-rx", 1, 0, + &queue_spec); +@@ -479,6 +480,7 @@ static int init_ixp_crypto(struct device *dev) + return -ENODEV; + } + recv_qid = queue_spec.args[0]; ++ of_node_put(queue_spec.np); + + ret = of_parse_phandle_with_fixed_args(np, "queue-txready", 1, 0, + &queue_spec); +@@ -487,6 +489,7 @@ static int init_ixp_crypto(struct device *dev) + return -ENODEV; + } + send_qid = queue_spec.args[0]; ++ of_node_put(queue_spec.np); + } else { + /* + * Hardcoded engine when using platform data, this goes away +diff --git a/drivers/dma/ti/edma.c b/drivers/dma/ti/edma.c +index 155c409d2b434d..c0fa5413246756 100644 +--- a/drivers/dma/ti/edma.c ++++ b/drivers/dma/ti/edma.c +@@ -208,7 +208,6 @@ struct edma_desc { + struct edma_cc; + + struct edma_tc { +- struct device_node *node; + u16 id; + }; + +@@ -2466,13 +2465,13 @@ static int edma_probe(struct platform_device *pdev) + if (ret || i == ecc->num_tc) + break; + +- ecc->tc_list[i].node = tc_args.np; + ecc->tc_list[i].id = i; + queue_priority_mapping[i][1] = tc_args.args[0]; + if (queue_priority_mapping[i][1] > lowest_priority) { + lowest_priority = queue_priority_mapping[i][1]; + info->default_queue = i; + } ++ of_node_put(tc_args.np); + } + + /* See if we have optional dma-channel-mask array */ +diff --git a/drivers/firmware/efi/sysfb_efi.c b/drivers/firmware/efi/sysfb_efi.c +index 456d0e5eaf78b5..f479680299838a 100644 +--- a/drivers/firmware/efi/sysfb_efi.c ++++ b/drivers/firmware/efi/sysfb_efi.c +@@ -91,6 +91,7 @@ void efifb_setup_from_dmi(struct screen_info *si, const char *opt) + _ret_; \ + }) + ++#ifdef CONFIG_EFI + static int __init efifb_set_system(const struct dmi_system_id *id) + { + struct efifb_dmi_info *info = id->driver_data; +@@ -346,7 +347,6 @@ static const struct fwnode_operations efifb_fwnode_ops = { + .add_links = efifb_add_links, + }; + +-#ifdef CONFIG_EFI + static struct fwnode_handle efifb_fwnode; + + __init void sysfb_apply_efi_quirks(void) +diff --git a/drivers/gpio/gpio-brcmstb.c b/drivers/gpio/gpio-brcmstb.c +index bccdbfd5ec805c..4588666a52d505 100644 +--- a/drivers/gpio/gpio-brcmstb.c ++++ b/drivers/gpio/gpio-brcmstb.c +@@ -594,8 +594,6 @@ static int brcmstb_gpio_probe(struct platform_device *pdev) + void __iomem *reg_base; + struct brcmstb_gpio_priv *priv; + struct resource *res; +- struct property *prop; +- const __be32 *p; + u32 bank_width; + int num_banks = 0; + int err; +@@ -640,8 +638,7 @@ static int brcmstb_gpio_probe(struct platform_device *pdev) + flags = BGPIOF_BIG_ENDIAN_BYTE_ORDER; + #endif + +- of_property_for_each_u32(np, "brcm,gpio-bank-widths", prop, p, +- bank_width) { ++ of_property_for_each_u32(np, "brcm,gpio-bank-widths", bank_width) { + struct brcmstb_gpio_bank *bank; + struct gpio_chip *gc; + +diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c +index 4cb455b2bdee71..619b6fb9d833a4 100644 +--- a/drivers/gpio/gpio-mxc.c ++++ b/drivers/gpio/gpio-mxc.c +@@ -490,8 +490,7 @@ static int mxc_gpio_probe(struct platform_device *pdev) + port->gc.request = mxc_gpio_request; + port->gc.free = mxc_gpio_free; + port->gc.to_irq = mxc_gpio_to_irq; +- port->gc.base = (pdev->id < 0) ? of_alias_get_id(np, "gpio") * 32 : +- pdev->id * 32; ++ port->gc.base = of_alias_get_id(np, "gpio") * 32; + + err = devm_gpiochip_add_data(&pdev->dev, &port->gc, port); + if (err) +diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c +index ce9a94e332801f..9c33f9da724cfd 100644 +--- a/drivers/gpio/gpio-pca953x.c ++++ b/drivers/gpio/gpio-pca953x.c +@@ -211,7 +211,6 @@ struct pca953x_chip { + + struct i2c_client *client; + struct gpio_chip gpio_chip; +- const char *const *names; + unsigned long driver_data; + struct regulator *regulator; + +@@ -712,7 +711,6 @@ static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios) + gc->label = dev_name(&chip->client->dev); + gc->parent = &chip->client->dev; + gc->owner = THIS_MODULE; +- gc->names = chip->names; + } + + #ifdef CONFIG_GPIO_PCA953X_IRQ +@@ -1000,7 +998,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, + } + #endif + +-static int device_pca95xx_init(struct pca953x_chip *chip, u32 invert) ++static int device_pca95xx_init(struct pca953x_chip *chip) + { + DECLARE_BITMAP(val, MAX_LINE); + u8 regaddr; +@@ -1018,24 +1016,21 @@ static int device_pca95xx_init(struct pca953x_chip *chip, u32 invert) + if (ret) + goto out; + +- /* set platform specific polarity inversion */ +- if (invert) +- bitmap_fill(val, MAX_LINE); +- else +- bitmap_zero(val, MAX_LINE); ++ /* clear polarity inversion */ ++ bitmap_zero(val, MAX_LINE); + + ret = pca953x_write_regs(chip, chip->regs->invert, val); + out: + return ret; + } + +-static int device_pca957x_init(struct pca953x_chip *chip, u32 invert) ++static int device_pca957x_init(struct pca953x_chip *chip) + { + DECLARE_BITMAP(val, MAX_LINE); + unsigned int i; + int ret; + +- ret = device_pca95xx_init(chip, invert); ++ ret = device_pca95xx_init(chip); + if (ret) + goto out; + +@@ -1052,14 +1047,40 @@ static int device_pca957x_init(struct pca953x_chip *chip, u32 invert) + return ret; + } + ++static void pca953x_disable_regulator(void *reg) ++{ ++ regulator_disable(reg); ++} ++ ++static int pca953x_get_and_enable_regulator(struct pca953x_chip *chip) ++{ ++ struct device *dev = &chip->client->dev; ++ struct regulator *reg = chip->regulator; ++ int ret; ++ ++ reg = devm_regulator_get(dev, "vcc"); ++ if (IS_ERR(reg)) ++ return dev_err_probe(dev, PTR_ERR(reg), "reg get err\n"); ++ ++ ret = regulator_enable(reg); ++ if (ret) ++ return dev_err_probe(dev, ret, "reg en err\n"); ++ ++ ret = devm_add_action_or_reset(dev, pca953x_disable_regulator, reg); ++ if (ret) ++ return ret; ++ ++ chip->regulator = reg; ++ return 0; ++} ++ + static int pca953x_probe(struct i2c_client *client) + { ++ struct device *dev = &client->dev; + struct pca953x_platform_data *pdata; + struct pca953x_chip *chip; +- int irq_base = 0; ++ int irq_base; + int ret; +- u32 invert = 0; +- struct regulator *reg; + const struct regmap_config *regmap_config; + + chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); +@@ -1070,8 +1091,6 @@ static int pca953x_probe(struct i2c_client *client) + if (pdata) { + irq_base = pdata->irq_base; + chip->gpio_start = pdata->gpio_base; +- invert = pdata->invert; +- chip->names = pdata->names; + } else { + struct gpio_desc *reset_gpio; + +@@ -1088,7 +1107,8 @@ static int pca953x_probe(struct i2c_client *client) + reset_gpio = devm_gpiod_get_optional(&client->dev, "reset", + GPIOD_OUT_LOW); + if (IS_ERR(reset_gpio)) +- return PTR_ERR(reset_gpio); ++ return dev_err_probe(dev, PTR_ERR(reset_gpio), ++ "Failed to get reset gpio\n"); + } + + chip->client = client; +@@ -1096,16 +1116,9 @@ static int pca953x_probe(struct i2c_client *client) + if (!chip->driver_data) + return -ENODEV; + +- reg = devm_regulator_get(&client->dev, "vcc"); +- if (IS_ERR(reg)) +- return dev_err_probe(&client->dev, PTR_ERR(reg), "reg get err\n"); +- +- ret = regulator_enable(reg); +- if (ret) { +- dev_err(&client->dev, "reg en err: %d\n", ret); ++ ret = pca953x_get_and_enable_regulator(chip); ++ if (ret) + return ret; +- } +- chip->regulator = reg; + + i2c_set_clientdata(client, chip); + +@@ -1128,10 +1141,8 @@ static int pca953x_probe(struct i2c_client *client) + } + + chip->regmap = devm_regmap_init_i2c(client, regmap_config); +- if (IS_ERR(chip->regmap)) { +- ret = PTR_ERR(chip->regmap); +- goto err_exit; +- } ++ if (IS_ERR(chip->regmap)) ++ return PTR_ERR(chip->regmap); + + regcache_mark_dirty(chip->regmap); + +@@ -1160,47 +1171,19 @@ static int pca953x_probe(struct i2c_client *client) + */ + if (PCA_CHIP_TYPE(chip->driver_data) == PCA957X_TYPE) { + chip->regs = &pca957x_regs; +- ret = device_pca957x_init(chip, invert); ++ ret = device_pca957x_init(chip); + } else { + chip->regs = &pca953x_regs; +- ret = device_pca95xx_init(chip, invert); ++ ret = device_pca95xx_init(chip); + } + if (ret) +- goto err_exit; ++ return ret; + + ret = pca953x_irq_setup(chip, irq_base); + if (ret) +- goto err_exit; +- +- ret = devm_gpiochip_add_data(&client->dev, &chip->gpio_chip, chip); +- if (ret) +- goto err_exit; +- +- if (pdata && pdata->setup) { +- ret = pdata->setup(client, chip->gpio_chip.base, +- chip->gpio_chip.ngpio, pdata->context); +- if (ret < 0) +- dev_warn(&client->dev, "setup failed, %d\n", ret); +- } +- +- return 0; +- +-err_exit: +- regulator_disable(chip->regulator); +- return ret; +-} +- +-static void pca953x_remove(struct i2c_client *client) +-{ +- struct pca953x_platform_data *pdata = dev_get_platdata(&client->dev); +- struct pca953x_chip *chip = i2c_get_clientdata(client); +- +- if (pdata && pdata->teardown) { +- pdata->teardown(client, chip->gpio_chip.base, +- chip->gpio_chip.ngpio, pdata->context); +- } ++ return ret; + +- regulator_disable(chip->regulator); ++ return devm_gpiochip_add_data(dev, &chip->gpio_chip, chip); + } + + #ifdef CONFIG_PM_SLEEP +@@ -1368,7 +1351,6 @@ static struct i2c_driver pca953x_driver = { + .acpi_match_table = pca953x_acpi_ids, + }, + .probe = pca953x_probe, +- .remove = pca953x_remove, + .id_table = pca953x_id, + }; + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +index c89264242bea3a..69dfc3da5e15c9 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +@@ -2049,6 +2049,7 @@ void amdgpu_ttm_fini(struct amdgpu_device *adev) + ttm_range_man_fini(&adev->mman.bdev, AMDGPU_PL_GDS); + ttm_range_man_fini(&adev->mman.bdev, AMDGPU_PL_GWS); + ttm_range_man_fini(&adev->mman.bdev, AMDGPU_PL_OA); ++ ttm_range_man_fini(&adev->mman.bdev, AMDGPU_PL_DOORBELL); + ttm_device_fini(&adev->mman.bdev); + adev->mman.initialized = false; + DRM_INFO("amdgpu: ttm finalized\n"); +diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c +index e80c4f5b4f4023..d1141a9baa916b 100644 +--- a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c ++++ b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c +@@ -896,6 +896,8 @@ static int vcn_v4_0_3_start_sriov(struct amdgpu_device *adev) + for (i = 0; i < adev->vcn.num_vcn_inst; i++) { + vcn_inst = GET_INST(VCN, i); + ++ vcn_v4_0_3_fw_shared_init(adev, vcn_inst); ++ + memset(&header, 0, sizeof(struct mmsch_v4_0_3_init_header)); + header.version = MMSCH_VERSION; + header.total_size = sizeof(struct mmsch_v4_0_3_init_header) >> 2; +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c +index cc3b62f7339417..1fbd23922082ae 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c +@@ -1420,6 +1420,8 @@ int atomctrl_get_smc_sclk_range_table(struct pp_hwmgr *hwmgr, struct pp_atom_ctr + GetIndexIntoMasterTable(DATA, SMU_Info), + &size, &frev, &crev); + ++ if (!psmu_info) ++ return -EINVAL; + + for (i = 0; i < psmu_info->ucSclkEntryNum; i++) { + table->entry[i].ucVco_setting = psmu_info->asSclkFcwRangeEntry[i].ucVco_setting; +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_powertune.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_powertune.c +index 3007b054c873c9..776d58ea63ae90 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_powertune.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_powertune.c +@@ -1120,13 +1120,14 @@ static int vega10_enable_se_edc_force_stall_config(struct pp_hwmgr *hwmgr) + result = vega10_program_didt_config_registers(hwmgr, SEEDCForceStallPatternConfig_Vega10, VEGA10_CONFIGREG_DIDT); + result |= vega10_program_didt_config_registers(hwmgr, SEEDCCtrlForceStallConfig_Vega10, VEGA10_CONFIGREG_DIDT); + if (0 != result) +- return result; ++ goto exit_safe_mode; + + vega10_didt_set_mask(hwmgr, false); + ++exit_safe_mode: + amdgpu_gfx_rlc_exit_safe_mode(adev, 0); + +- return 0; ++ return result; + } + + static int vega10_disable_se_edc_force_stall_config(struct pp_hwmgr *hwmgr) +diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c +index 26d3b9b8432675..24c5a926af8d1d 100644 +--- a/drivers/gpu/drm/bridge/ite-it6505.c ++++ b/drivers/gpu/drm/bridge/ite-it6505.c +@@ -299,7 +299,7 @@ + #define MAX_CR_LEVEL 0x03 + #define MAX_EQ_LEVEL 0x03 + #define AUX_WAIT_TIMEOUT_MS 15 +-#define AUX_FIFO_MAX_SIZE 32 ++#define AUX_FIFO_MAX_SIZE 16 + #define PIXEL_CLK_DELAY 1 + #define PIXEL_CLK_INVERSE 0 + #define ADJUST_PHASE_THRESHOLD 80000 +diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c +index 69fccbcd92c622..84b7789454962a 100644 +--- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c ++++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c +@@ -343,6 +343,7 @@ void *etnaviv_gem_vmap(struct drm_gem_object *obj) + static void *etnaviv_gem_vmap_impl(struct etnaviv_gem_object *obj) + { + struct page **pages; ++ pgprot_t prot; + + lockdep_assert_held(&obj->lock); + +@@ -350,8 +351,19 @@ static void *etnaviv_gem_vmap_impl(struct etnaviv_gem_object *obj) + if (IS_ERR(pages)) + return NULL; + +- return vmap(pages, obj->base.size >> PAGE_SHIFT, +- VM_MAP, pgprot_writecombine(PAGE_KERNEL)); ++ switch (obj->flags & ETNA_BO_CACHE_MASK) { ++ case ETNA_BO_CACHED: ++ prot = PAGE_KERNEL; ++ break; ++ case ETNA_BO_UNCACHED: ++ prot = pgprot_noncached(PAGE_KERNEL); ++ break; ++ case ETNA_BO_WC: ++ default: ++ prot = pgprot_writecombine(PAGE_KERNEL); ++ } ++ ++ return vmap(pages, obj->base.size >> PAGE_SHIFT, VM_MAP, prot); + } + + static inline enum dma_data_direction etnaviv_op_to_dma_dir(u32 op) +diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +index c9edaa6d763697..9009442b543dda 100644 +--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c ++++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +@@ -1510,7 +1510,9 @@ int a6xx_gmu_wrapper_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node) + + gmu->dev = &pdev->dev; + +- of_dma_configure(gmu->dev, node, true); ++ ret = of_dma_configure(gmu->dev, node, true); ++ if (ret) ++ return ret; + + pm_runtime_enable(gmu->dev); + +@@ -1574,7 +1576,9 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node) + + gmu->dev = &pdev->dev; + +- of_dma_configure(gmu->dev, node, true); ++ ret = of_dma_configure(gmu->dev, node, true); ++ if (ret) ++ return ret; + + /* Fow now, don't do anything fancy until we get our feet under us */ + gmu->idle_level = GMU_IDLE_STATE_ACTIVE; +diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h +index f0c3804f425879..76b668f36477a3 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h ++++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h +@@ -164,6 +164,7 @@ static const struct dpu_lm_cfg sm8150_lm[] = { + .sblk = &sdm845_lm_sblk, + .lm_pair = LM_3, + .pingpong = PINGPONG_2, ++ .dspp = DSPP_2, + }, { + .name = "lm_3", .id = LM_3, + .base = 0x47000, .len = 0x320, +@@ -171,6 +172,7 @@ static const struct dpu_lm_cfg sm8150_lm[] = { + .sblk = &sdm845_lm_sblk, + .lm_pair = LM_2, + .pingpong = PINGPONG_3, ++ .dspp = DSPP_3, + }, { + .name = "lm_4", .id = LM_4, + .base = 0x48000, .len = 0x320, +diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h +index 47de71e71e3108..427dec0cd1d36d 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h ++++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h +@@ -163,6 +163,7 @@ static const struct dpu_lm_cfg sc8180x_lm[] = { + .sblk = &sdm845_lm_sblk, + .lm_pair = LM_3, + .pingpong = PINGPONG_2, ++ .dspp = DSPP_2, + }, { + .name = "lm_3", .id = LM_3, + .base = 0x47000, .len = 0x320, +@@ -170,6 +171,7 @@ static const struct dpu_lm_cfg sc8180x_lm[] = { + .sblk = &sdm845_lm_sblk, + .lm_pair = LM_2, + .pingpong = PINGPONG_3, ++ .dspp = DSPP_3, + }, { + .name = "lm_4", .id = LM_4, + .base = 0x48000, .len = 0x320, +diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h +index ee781037ada93e..a38fb057ceda6b 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h ++++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h +@@ -163,6 +163,7 @@ static const struct dpu_lm_cfg sm8250_lm[] = { + .sblk = &sdm845_lm_sblk, + .lm_pair = LM_3, + .pingpong = PINGPONG_2, ++ .dspp = DSPP_2, + }, { + .name = "lm_3", .id = LM_3, + .base = 0x47000, .len = 0x320, +@@ -170,6 +171,7 @@ static const struct dpu_lm_cfg sm8250_lm[] = { + .sblk = &sdm845_lm_sblk, + .lm_pair = LM_2, + .pingpong = PINGPONG_3, ++ .dspp = DSPP_3, + }, { + .name = "lm_4", .id = LM_4, + .base = 0x48000, .len = 0x320, +diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h +index 428bcbcfbf1925..e2f181077d11e7 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h ++++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h +@@ -163,6 +163,7 @@ static const struct dpu_lm_cfg sm8350_lm[] = { + .sblk = &sdm845_lm_sblk, + .lm_pair = LM_3, + .pingpong = PINGPONG_2, ++ .dspp = DSPP_2, + }, { + .name = "lm_3", .id = LM_3, + .base = 0x47000, .len = 0x320, +@@ -170,6 +171,7 @@ static const struct dpu_lm_cfg sm8350_lm[] = { + .sblk = &sdm845_lm_sblk, + .lm_pair = LM_2, + .pingpong = PINGPONG_3, ++ .dspp = DSPP_3, + }, { + .name = "lm_4", .id = LM_4, + .base = 0x48000, .len = 0x320, +diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h +index 7bed819dfc3902..69b238ed01b980 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h ++++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h +@@ -181,6 +181,7 @@ static const struct dpu_lm_cfg sm8550_lm[] = { + .sblk = &sdm845_lm_sblk, + .lm_pair = LM_3, + .pingpong = PINGPONG_2, ++ .dspp = DSPP_2, + }, { + .name = "lm_3", .id = LM_3, + .base = 0x47000, .len = 0x320, +@@ -188,6 +189,7 @@ static const struct dpu_lm_cfg sm8550_lm[] = { + .sblk = &sdm845_lm_sblk, + .lm_pair = LM_2, + .pingpong = PINGPONG_3, ++ .dspp = DSPP_3, + }, { + .name = "lm_4", .id = LM_4, + .base = 0x48000, .len = 0x320, +diff --git a/drivers/gpu/drm/msm/dp/dp_audio.c b/drivers/gpu/drm/msm/dp/dp_audio.c +index 4a2e479723a852..610cbe23aa8398 100644 +--- a/drivers/gpu/drm/msm/dp/dp_audio.c ++++ b/drivers/gpu/drm/msm/dp/dp_audio.c +@@ -410,10 +410,10 @@ static void dp_audio_safe_to_exit_level(struct dp_audio_private *audio) + safe_to_exit_level = 5; + break; + default: ++ safe_to_exit_level = 14; + drm_dbg_dp(audio->drm_dev, + "setting the default safe_to_exit_level = %u\n", + safe_to_exit_level); +- safe_to_exit_level = 14; + break; + } + +diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +index 84aa811ca1e9cf..bd08d57486fef4 100644 +--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c ++++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +@@ -30,7 +30,6 @@ + #include + + #include "rockchip_drm_drv.h" +-#include "rockchip_drm_vop.h" + + #define RK3288_GRF_SOC_CON6 0x25c + #define RK3288_EDP_LCDC_SEL BIT(5) +diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c +index 3793863c210ebd..fca403ccce47eb 100644 +--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c ++++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c +@@ -24,7 +24,6 @@ + + #include "cdn-dp-core.h" + #include "cdn-dp-reg.h" +-#include "rockchip_drm_vop.h" + + static inline struct cdn_dp_device *connector_to_dp(struct drm_connector *connector) + { +diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c +index 0100162a73b295..002486741aec2b 100644 +--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c +@@ -26,7 +26,6 @@ + #include + + #include "rockchip_drm_drv.h" +-#include "rockchip_drm_vop.h" + + #define DSI_PHY_RSTZ 0xa0 + #define PHY_DISFORCEPLL 0 +diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +index 89bc86d620146c..aae48e906af11b 100644 +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -18,7 +18,6 @@ + #include + + #include "rockchip_drm_drv.h" +-#include "rockchip_drm_vop.h" + + #define RK3228_GRF_SOC_CON2 0x0408 + #define RK3228_HDMI_SDAIN_MSK BIT(14) +diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c +index 345253e033c538..50c984ac107d63 100644 +--- a/drivers/gpu/drm/rockchip/inno_hdmi.c ++++ b/drivers/gpu/drm/rockchip/inno_hdmi.c +@@ -23,7 +23,6 @@ + #include + + #include "rockchip_drm_drv.h" +-#include "rockchip_drm_vop.h" + + #include "inno_hdmi.h" + +diff --git a/drivers/gpu/drm/rockchip/rk3066_hdmi.c b/drivers/gpu/drm/rockchip/rk3066_hdmi.c +index fa6e592e0276c3..78136d0c5a659e 100644 +--- a/drivers/gpu/drm/rockchip/rk3066_hdmi.c ++++ b/drivers/gpu/drm/rockchip/rk3066_hdmi.c +@@ -17,7 +17,6 @@ + #include "rk3066_hdmi.h" + + #include "rockchip_drm_drv.h" +-#include "rockchip_drm_vop.h" + + #define DEFAULT_PLLA_RATE 30000000 + +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h +index aeb03a57240fd9..bbb9e0bf68048a 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h +@@ -20,6 +20,23 @@ + #define ROCKCHIP_MAX_CONNECTOR 2 + #define ROCKCHIP_MAX_CRTC 4 + ++/* ++ * display output interface supported by rockchip lcdc ++ */ ++#define ROCKCHIP_OUT_MODE_P888 0 ++#define ROCKCHIP_OUT_MODE_BT1120 0 ++#define ROCKCHIP_OUT_MODE_P666 1 ++#define ROCKCHIP_OUT_MODE_P565 2 ++#define ROCKCHIP_OUT_MODE_BT656 5 ++#define ROCKCHIP_OUT_MODE_S888 8 ++#define ROCKCHIP_OUT_MODE_S888_DUMMY 12 ++#define ROCKCHIP_OUT_MODE_YUV420 14 ++/* for use special outface */ ++#define ROCKCHIP_OUT_MODE_AAAA 15 ++ ++/* output flags */ ++#define ROCKCHIP_OUTPUT_DSI_DUAL BIT(0) ++ + struct drm_device; + struct drm_connector; + struct iommu_domain; +@@ -31,6 +48,7 @@ struct rockchip_crtc_state { + int output_bpc; + int output_flags; + bool enable_afbc; ++ bool yuv_overlay; + u32 bus_format; + u32 bus_flags; + int color_space; +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +index c5c716a69171a8..4ea369e004a912 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +@@ -277,18 +277,6 @@ struct vop_data { + /* dst alpha ctrl define */ + #define DST_FACTOR_M0(x) (((x) & 0x7) << 6) + +-/* +- * display output interface supported by rockchip lcdc +- */ +-#define ROCKCHIP_OUT_MODE_P888 0 +-#define ROCKCHIP_OUT_MODE_P666 1 +-#define ROCKCHIP_OUT_MODE_P565 2 +-/* for use special outface */ +-#define ROCKCHIP_OUT_MODE_AAAA 15 +- +-/* output flags */ +-#define ROCKCHIP_OUTPUT_DSI_DUAL BIT(0) +- + enum alpha_mode { + ALPHA_STRAIGHT, + ALPHA_INVERSE, +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +index d1de12e850e746..d8f8c37c326c43 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +@@ -33,7 +33,6 @@ + #include + #include + +-#include "rockchip_drm_drv.h" + #include "rockchip_drm_gem.h" + #include "rockchip_drm_fb.h" + #include "rockchip_drm_vop2.h" +@@ -465,6 +464,16 @@ static bool rockchip_vop2_mod_supported(struct drm_plane *plane, u32 format, + if (modifier == DRM_FORMAT_MOD_INVALID) + return false; + ++ if (vop2->data->soc_id == 3568 || vop2->data->soc_id == 3566) { ++ if (vop2_cluster_window(win)) { ++ if (modifier == DRM_FORMAT_MOD_LINEAR) { ++ drm_dbg_kms(vop2->drm, ++ "Cluster window only supports format with afbc\n"); ++ return false; ++ } ++ } ++ } ++ + if (modifier == DRM_FORMAT_MOD_LINEAR) + return true; + +@@ -1397,8 +1406,18 @@ static void vop2_post_config(struct drm_crtc *crtc) + u32 top_margin = 100, bottom_margin = 100; + u16 hsize = hdisplay * (left_margin + right_margin) / 200; + u16 vsize = vdisplay * (top_margin + bottom_margin) / 200; ++ u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; + u16 hact_end, vact_end; + u32 val; ++ u32 bg_dly; ++ u32 pre_scan_dly; ++ ++ bg_dly = vp->data->pre_scan_max_dly[3]; ++ vop2_writel(vp->vop2, RK3568_VP_BG_MIX_CTRL(vp->id), ++ FIELD_PREP(RK3568_VP_BG_MIX_CTRL__BG_DLY, bg_dly)); ++ ++ pre_scan_dly = ((bg_dly + (hdisplay >> 1) - 1) << 16) | hsync_len; ++ vop2_vp_write(vp, RK3568_VP_PRE_SCAN_HTIMING, pre_scan_dly); + + vsize = rounddown(vsize, 2); + hsize = rounddown(hsize, 2); +@@ -1560,6 +1579,8 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc, + + vop2->enable_count++; + ++ vcstate->yuv_overlay = is_yuv_output(vcstate->bus_format); ++ + vop2_crtc_enable_irq(vp, VP_INT_POST_BUF_EMPTY); + + polflags = 0; +@@ -1587,7 +1608,7 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc, + if (vop2_output_uv_swap(vcstate->bus_format, vcstate->output_mode)) + dsp_ctrl |= RK3568_VP_DSP_CTRL__DSP_RB_SWAP; + +- if (is_yuv_output(vcstate->bus_format)) ++ if (vcstate->yuv_overlay) + dsp_ctrl |= RK3568_VP_DSP_CTRL__POST_DSP_OUT_R2Y; + + vop2_dither_setup(crtc, &dsp_ctrl); +@@ -1741,7 +1762,6 @@ static int vop2_find_start_mixer_id_for_vp(struct vop2 *vop2, u8 port_id) + + static void vop2_setup_cluster_alpha(struct vop2 *vop2, struct vop2_win *main_win) + { +- u32 offset = (main_win->data->phys_id * 0x10); + struct vop2_alpha_config alpha_config; + struct vop2_alpha alpha; + struct drm_plane_state *bottom_win_pstate; +@@ -1749,6 +1769,7 @@ static void vop2_setup_cluster_alpha(struct vop2 *vop2, struct vop2_win *main_wi + u16 src_glb_alpha_val, dst_glb_alpha_val; + bool premulti_en = false; + bool swap = false; ++ u32 offset = 0; + + /* At one win mode, win0 is dst/bottom win, and win1 is a all zero src/top win */ + bottom_win_pstate = main_win->base.state; +@@ -1767,6 +1788,22 @@ static void vop2_setup_cluster_alpha(struct vop2 *vop2, struct vop2_win *main_wi + vop2_parse_alpha(&alpha_config, &alpha); + + alpha.src_color_ctrl.bits.src_dst_swap = swap; ++ ++ switch (main_win->data->phys_id) { ++ case ROCKCHIP_VOP2_CLUSTER0: ++ offset = 0x0; ++ break; ++ case ROCKCHIP_VOP2_CLUSTER1: ++ offset = 0x10; ++ break; ++ case ROCKCHIP_VOP2_CLUSTER2: ++ offset = 0x20; ++ break; ++ case ROCKCHIP_VOP2_CLUSTER3: ++ offset = 0x30; ++ break; ++ } ++ + vop2_writel(vop2, RK3568_CLUSTER0_MIX_SRC_COLOR_CTRL + offset, + alpha.src_color_ctrl.val); + vop2_writel(vop2, RK3568_CLUSTER0_MIX_DST_COLOR_CTRL + offset, +@@ -1814,6 +1851,12 @@ static void vop2_setup_alpha(struct vop2_video_port *vp) + struct vop2_win *win = to_vop2_win(plane); + int zpos = plane->state->normalized_zpos; + ++ /* ++ * Need to configure alpha from second layer. ++ */ ++ if (zpos == 0) ++ continue; ++ + if (plane->state->pixel_blend_mode == DRM_MODE_BLEND_PREMULTI) + premulti_en = 1; + else +@@ -1890,29 +1933,26 @@ static void vop2_setup_layer_mixer(struct vop2_video_port *vp) + struct drm_plane *plane; + u32 layer_sel = 0; + u32 port_sel; +- unsigned int nlayer, ofs; +- struct drm_display_mode *adjusted_mode; +- u16 hsync_len; +- u16 hdisplay; +- u32 bg_dly; +- u32 pre_scan_dly; ++ u8 layer_id; ++ u8 old_layer_id; ++ u8 layer_sel_id; ++ unsigned int ofs; ++ u32 ovl_ctrl; + int i; + struct vop2_video_port *vp0 = &vop2->vps[0]; + struct vop2_video_port *vp1 = &vop2->vps[1]; + struct vop2_video_port *vp2 = &vop2->vps[2]; ++ struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(vp->crtc.state); + +- adjusted_mode = &vp->crtc.state->adjusted_mode; +- hsync_len = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start; +- hdisplay = adjusted_mode->crtc_hdisplay; +- +- bg_dly = vp->data->pre_scan_max_dly[3]; +- vop2_writel(vop2, RK3568_VP_BG_MIX_CTRL(vp->id), +- FIELD_PREP(RK3568_VP_BG_MIX_CTRL__BG_DLY, bg_dly)); ++ ovl_ctrl = vop2_readl(vop2, RK3568_OVL_CTRL); ++ ovl_ctrl |= RK3568_OVL_CTRL__LAYERSEL_REGDONE_IMD; ++ if (vcstate->yuv_overlay) ++ ovl_ctrl |= RK3568_OVL_CTRL__YUV_MODE(vp->id); ++ else ++ ovl_ctrl &= ~RK3568_OVL_CTRL__YUV_MODE(vp->id); + +- pre_scan_dly = ((bg_dly + (hdisplay >> 1) - 1) << 16) | hsync_len; +- vop2_vp_write(vp, RK3568_VP_PRE_SCAN_HTIMING, pre_scan_dly); ++ vop2_writel(vop2, RK3568_OVL_CTRL, ovl_ctrl); + +- vop2_writel(vop2, RK3568_OVL_CTRL, 0); + port_sel = vop2_readl(vop2, RK3568_OVL_PORT_SEL); + port_sel &= RK3568_OVL_PORT_SEL__SEL_PORT; + +@@ -1940,9 +1980,30 @@ static void vop2_setup_layer_mixer(struct vop2_video_port *vp) + for (i = 0; i < vp->id; i++) + ofs += vop2->vps[i].nlayers; + +- nlayer = 0; + drm_atomic_crtc_for_each_plane(plane, &vp->crtc) { + struct vop2_win *win = to_vop2_win(plane); ++ struct vop2_win *old_win; ++ ++ layer_id = (u8)(plane->state->normalized_zpos + ofs); ++ ++ /* ++ * Find the layer this win bind in old state. ++ */ ++ for (old_layer_id = 0; old_layer_id < vop2->data->win_size; old_layer_id++) { ++ layer_sel_id = (layer_sel >> (4 * old_layer_id)) & 0xf; ++ if (layer_sel_id == win->data->layer_sel_id) ++ break; ++ } ++ ++ /* ++ * Find the win bind to this layer in old state ++ */ ++ for (i = 0; i < vop2->data->win_size; i++) { ++ old_win = &vop2->win[i]; ++ layer_sel_id = (layer_sel >> (4 * layer_id)) & 0xf; ++ if (layer_sel_id == old_win->data->layer_sel_id) ++ break; ++ } + + switch (win->data->phys_id) { + case ROCKCHIP_VOP2_CLUSTER0: +@@ -1971,22 +2032,18 @@ static void vop2_setup_layer_mixer(struct vop2_video_port *vp) + break; + } + +- layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(plane->state->normalized_zpos + ofs, +- 0x7); +- layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(plane->state->normalized_zpos + ofs, +- win->data->layer_sel_id); +- nlayer++; +- } +- +- /* configure unused layers to 0x5 (reserved) */ +- for (; nlayer < vp->nlayers; nlayer++) { +- layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(nlayer + ofs, 0x7); +- layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(nlayer + ofs, 5); ++ layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(layer_id, 0x7); ++ layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(layer_id, win->data->layer_sel_id); ++ /* ++ * When we bind a window from layerM to layerN, we also need to move the old ++ * window on layerN to layerM to avoid one window selected by two or more layers. ++ */ ++ layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, 0x7); ++ layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, old_win->data->layer_sel_id); + } + + vop2_writel(vop2, RK3568_OVL_LAYER_SEL, layer_sel); + vop2_writel(vop2, RK3568_OVL_PORT_SEL, port_sel); +- vop2_writel(vop2, RK3568_OVL_CTRL, RK3568_OVL_CTRL__LAYERSEL_REGDONE_IMD); + } + + static void vop2_setup_dly_for_windows(struct vop2 *vop2) +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h +index f1234a151130fa..eec06ab1d73713 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h +@@ -7,10 +7,10 @@ + #ifndef _ROCKCHIP_DRM_VOP2_H + #define _ROCKCHIP_DRM_VOP2_H + +-#include "rockchip_drm_vop.h" +- + #include + #include ++#include "rockchip_drm_drv.h" ++#include "rockchip_drm_vop.h" + + #define VOP_FEATURE_OUTPUT_10BIT BIT(0) + +@@ -169,19 +169,6 @@ struct vop2_data { + #define WB_YRGB_FIFO_FULL_INTR BIT(18) + #define WB_COMPLETE_INTR BIT(19) + +-/* +- * display output interface supported by rockchip lcdc +- */ +-#define ROCKCHIP_OUT_MODE_P888 0 +-#define ROCKCHIP_OUT_MODE_BT1120 0 +-#define ROCKCHIP_OUT_MODE_P666 1 +-#define ROCKCHIP_OUT_MODE_P565 2 +-#define ROCKCHIP_OUT_MODE_BT656 5 +-#define ROCKCHIP_OUT_MODE_S888 8 +-#define ROCKCHIP_OUT_MODE_S888_DUMMY 12 +-#define ROCKCHIP_OUT_MODE_YUV420 14 +-/* for use special outface */ +-#define ROCKCHIP_OUT_MODE_AAAA 15 + + enum vop_csc_format { + CSC_BT601L, +@@ -418,6 +405,7 @@ enum dst_factor_mode { + #define VOP2_COLOR_KEY_MASK BIT(31) + + #define RK3568_OVL_CTRL__LAYERSEL_REGDONE_IMD BIT(28) ++#define RK3568_OVL_CTRL__YUV_MODE(vp) BIT(vp) + + #define RK3568_VP_BG_MIX_CTRL__BG_DLY GENMASK(31, 24) + +diff --git a/drivers/gpu/drm/rockchip/rockchip_lvds.c b/drivers/gpu/drm/rockchip/rockchip_lvds.c +index 1b6e0b210aa530..107959530c2201 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_lvds.c ++++ b/drivers/gpu/drm/rockchip/rockchip_lvds.c +@@ -27,7 +27,6 @@ + #include + + #include "rockchip_drm_drv.h" +-#include "rockchip_drm_vop.h" + #include "rockchip_lvds.h" + + #define DISPLAY_OUTPUT_RGB 0 +diff --git a/drivers/gpu/drm/rockchip/rockchip_rgb.c b/drivers/gpu/drm/rockchip/rockchip_rgb.c +index c677b71ae516be..dbfbde24698ef0 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_rgb.c ++++ b/drivers/gpu/drm/rockchip/rockchip_rgb.c +@@ -19,7 +19,6 @@ + #include + + #include "rockchip_drm_drv.h" +-#include "rockchip_drm_vop.h" + #include "rockchip_rgb.h" + + struct rockchip_rgb { +diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c +index 558f3988fb2cff..8f156a69912c89 100644 +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -1125,6 +1125,8 @@ static void hid_apply_multiplier(struct hid_device *hid, + while (multiplier_collection->parent_idx != -1 && + multiplier_collection->type != HID_COLLECTION_LOGICAL) + multiplier_collection = &hid->collection[multiplier_collection->parent_idx]; ++ if (multiplier_collection->type != HID_COLLECTION_LOGICAL) ++ multiplier_collection = NULL; + + effective_multiplier = hid_calculate_multiplier(hid, multiplier); + +diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c +index fda9dce3da9980..9d80635a91ebd8 100644 +--- a/drivers/hid/hid-input.c ++++ b/drivers/hid/hid-input.c +@@ -810,10 +810,23 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel + break; + } + +- if ((usage->hid & 0xf0) == 0x90) { /* SystemControl*/ +- switch (usage->hid & 0xf) { +- case 0xb: map_key_clear(KEY_DO_NOT_DISTURB); break; +- default: goto ignore; ++ if ((usage->hid & 0xf0) == 0x90) { /* SystemControl & D-pad */ ++ switch (usage->hid) { ++ case HID_GD_UP: usage->hat_dir = 1; break; ++ case HID_GD_DOWN: usage->hat_dir = 5; break; ++ case HID_GD_RIGHT: usage->hat_dir = 3; break; ++ case HID_GD_LEFT: usage->hat_dir = 7; break; ++ case HID_GD_DO_NOT_DISTURB: ++ map_key_clear(KEY_DO_NOT_DISTURB); break; ++ default: goto unknown; ++ } ++ ++ if (usage->hid <= HID_GD_LEFT) { ++ if (field->dpad) { ++ map_abs(field->dpad); ++ goto ignore; ++ } ++ map_abs(ABS_HAT0X); + } + break; + } +@@ -844,22 +857,6 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel + if (field->application == HID_GD_SYSTEM_CONTROL) + goto ignore; + +- if ((usage->hid & 0xf0) == 0x90) { /* D-pad */ +- switch (usage->hid) { +- case HID_GD_UP: usage->hat_dir = 1; break; +- case HID_GD_DOWN: usage->hat_dir = 5; break; +- case HID_GD_RIGHT: usage->hat_dir = 3; break; +- case HID_GD_LEFT: usage->hat_dir = 7; break; +- default: goto unknown; +- } +- if (field->dpad) { +- map_abs(field->dpad); +- goto ignore; +- } +- map_abs(ABS_HAT0X); +- break; +- } +- + switch (usage->hid) { + /* These usage IDs map directly to the usage codes. */ + case HID_GD_X: case HID_GD_Y: case HID_GD_Z: +diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c +index e62104e1a6038b..5ad871a7d1a44c 100644 +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -2072,7 +2072,7 @@ static const struct hid_device_id mt_devices[] = { + I2C_DEVICE_ID_GOODIX_01E8) }, + { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT_NSMU, + HID_DEVICE(BUS_I2C, HID_GROUP_ANY, I2C_VENDOR_ID_GOODIX, +- I2C_DEVICE_ID_GOODIX_01E8) }, ++ I2C_DEVICE_ID_GOODIX_01E9) }, + + /* GoodTouch panels */ + { .driver_data = MT_CLS_NSMU, +diff --git a/drivers/hid/hid-thrustmaster.c b/drivers/hid/hid-thrustmaster.c +index cf1679b0d4fbb5..6c3e758bbb09e3 100644 +--- a/drivers/hid/hid-thrustmaster.c ++++ b/drivers/hid/hid-thrustmaster.c +@@ -170,6 +170,14 @@ static void thrustmaster_interrupts(struct hid_device *hdev) + ep = &usbif->cur_altsetting->endpoint[1]; + b_ep = ep->desc.bEndpointAddress; + ++ /* Are the expected endpoints present? */ ++ u8 ep_addr[1] = {b_ep}; ++ ++ if (!usb_check_int_endpoints(usbif, ep_addr)) { ++ hid_err(hdev, "Unexpected non-int endpoint\n"); ++ return; ++ } ++ + for (i = 0; i < ARRAY_SIZE(setup_arr); ++i) { + memcpy(send_buf, setup_arr[i], setup_arr_sizes[i]); + +diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c +index 235235613c1b99..030127525672e7 100644 +--- a/drivers/i3c/master/dw-i3c-master.c ++++ b/drivers/i3c/master/dw-i3c-master.c +@@ -1136,6 +1136,23 @@ static void dw_i3c_master_free_ibi(struct i3c_dev_desc *dev) + data->ibi_pool = NULL; + } + ++static void dw_i3c_master_enable_sir_signal(struct dw_i3c_master *master, bool enable) ++{ ++ u32 reg; ++ ++ reg = readl(master->regs + INTR_STATUS_EN); ++ reg &= ~INTR_IBI_THLD_STAT; ++ if (enable) ++ reg |= INTR_IBI_THLD_STAT; ++ writel(reg, master->regs + INTR_STATUS_EN); ++ ++ reg = readl(master->regs + INTR_SIGNAL_EN); ++ reg &= ~INTR_IBI_THLD_STAT; ++ if (enable) ++ reg |= INTR_IBI_THLD_STAT; ++ writel(reg, master->regs + INTR_SIGNAL_EN); ++} ++ + static void dw_i3c_master_set_sir_enabled(struct dw_i3c_master *master, + struct i3c_dev_desc *dev, + u8 idx, bool enable) +@@ -1170,23 +1187,34 @@ static void dw_i3c_master_set_sir_enabled(struct dw_i3c_master *master, + } + writel(reg, master->regs + IBI_SIR_REQ_REJECT); + +- if (global) { +- reg = readl(master->regs + INTR_STATUS_EN); +- reg &= ~INTR_IBI_THLD_STAT; +- if (enable) +- reg |= INTR_IBI_THLD_STAT; +- writel(reg, master->regs + INTR_STATUS_EN); +- +- reg = readl(master->regs + INTR_SIGNAL_EN); +- reg &= ~INTR_IBI_THLD_STAT; +- if (enable) +- reg |= INTR_IBI_THLD_STAT; +- writel(reg, master->regs + INTR_SIGNAL_EN); +- } ++ if (global) ++ dw_i3c_master_enable_sir_signal(master, enable); ++ + + spin_unlock_irqrestore(&master->devs_lock, flags); + } + ++static int dw_i3c_master_enable_hotjoin(struct i3c_master_controller *m) ++{ ++ struct dw_i3c_master *master = to_dw_i3c_master(m); ++ ++ dw_i3c_master_enable_sir_signal(master, true); ++ writel(readl(master->regs + DEVICE_CTRL) & ~DEV_CTRL_HOT_JOIN_NACK, ++ master->regs + DEVICE_CTRL); ++ ++ return 0; ++} ++ ++static int dw_i3c_master_disable_hotjoin(struct i3c_master_controller *m) ++{ ++ struct dw_i3c_master *master = to_dw_i3c_master(m); ++ ++ writel(readl(master->regs + DEVICE_CTRL) | DEV_CTRL_HOT_JOIN_NACK, ++ master->regs + DEVICE_CTRL); ++ ++ return 0; ++} ++ + static int dw_i3c_master_enable_ibi(struct i3c_dev_desc *dev) + { + struct dw_i3c_i2c_dev_data *data = i3c_dev_get_master_data(dev); +@@ -1326,6 +1354,8 @@ static void dw_i3c_master_irq_handle_ibis(struct dw_i3c_master *master) + + if (IBI_TYPE_SIRQ(reg)) { + dw_i3c_master_handle_ibi_sir(master, reg); ++ } else if (IBI_TYPE_HJ(reg)) { ++ queue_work(master->base.wq, &master->hj_work); + } else { + len = IBI_QUEUE_STATUS_DATA_LEN(reg); + dev_info(&master->base.dev, +@@ -1393,6 +1423,8 @@ static const struct i3c_master_controller_ops dw_mipi_i3c_ibi_ops = { + .enable_ibi = dw_i3c_master_enable_ibi, + .disable_ibi = dw_i3c_master_disable_ibi, + .recycle_ibi_slot = dw_i3c_master_recycle_ibi_slot, ++ .enable_hotjoin = dw_i3c_master_enable_hotjoin, ++ .disable_hotjoin = dw_i3c_master_disable_hotjoin, + }; + + /* default platform ops implementations */ +@@ -1412,6 +1444,14 @@ static const struct dw_i3c_platform_ops dw_i3c_platform_ops_default = { + .set_dat_ibi = dw_i3c_platform_set_dat_ibi_nop, + }; + ++static void dw_i3c_hj_work(struct work_struct *work) ++{ ++ struct dw_i3c_master *master = ++ container_of(work, typeof(*master), hj_work); ++ ++ i3c_master_do_daa(&master->base); ++} ++ + int dw_i3c_common_probe(struct dw_i3c_master *master, + struct platform_device *pdev) + { +@@ -1469,6 +1509,7 @@ int dw_i3c_common_probe(struct dw_i3c_master *master, + if (master->ibi_capable) + ops = &dw_mipi_i3c_ibi_ops; + ++ INIT_WORK(&master->hj_work, dw_i3c_hj_work); + ret = i3c_master_register(&master->base, &pdev->dev, ops, false); + if (ret) + goto err_assert_rst; +@@ -1487,6 +1528,7 @@ EXPORT_SYMBOL_GPL(dw_i3c_common_probe); + + void dw_i3c_common_remove(struct dw_i3c_master *master) + { ++ cancel_work_sync(&master->hj_work); + i3c_master_unregister(&master->base); + + reset_control_assert(master->core_rst); +diff --git a/drivers/i3c/master/dw-i3c-master.h b/drivers/i3c/master/dw-i3c-master.h +index ab862c5d15fe72..4ab94aa72252e4 100644 +--- a/drivers/i3c/master/dw-i3c-master.h ++++ b/drivers/i3c/master/dw-i3c-master.h +@@ -57,6 +57,8 @@ struct dw_i3c_master { + + /* platform-specific data */ + const struct dw_i3c_platform_ops *platform_ops; ++ ++ struct work_struct hj_work; + }; + + struct dw_i3c_platform_ops { +diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c +index 5f879598699545..32f1f91e272046 100644 +--- a/drivers/iio/adc/ti_am335x_adc.c ++++ b/drivers/iio/adc/ti_am335x_adc.c +@@ -564,13 +564,11 @@ static int tiadc_parse_dt(struct platform_device *pdev, + struct tiadc_device *adc_dev) + { + struct device_node *node = pdev->dev.of_node; +- struct property *prop; +- const __be32 *cur; + int channels = 0; + u32 val; + int i; + +- of_property_for_each_u32(node, "ti,adc-channels", prop, cur, val) { ++ of_property_for_each_u32(node, "ti,adc-channels", val) { + adc_dev->channel_line[channels] = val; + + /* Set Default values for optional DT parameters */ +diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c +index 08da793969ee55..f7345e4890a141 100644 +--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c ++++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c +@@ -4278,9 +4278,10 @@ int bnxt_re_mmap(struct ib_ucontext *ib_uctx, struct vm_area_struct *vma) + case BNXT_RE_MMAP_DBR_PAGE: + /* Driver doesn't expect write access for user space */ + if (vma->vm_flags & VM_WRITE) +- return -EFAULT; +- ret = vm_insert_page(vma, vma->vm_start, +- virt_to_page((void *)bnxt_entry->mem_offset)); ++ ret = -EFAULT; ++ else ++ ret = vm_insert_page(vma, vma->vm_start, ++ virt_to_page((void *)bnxt_entry->mem_offset)); + break; + default: + ret = -EINVAL; +diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c +index 80970a1738f8a6..034b85c4225555 100644 +--- a/drivers/infiniband/hw/cxgb4/device.c ++++ b/drivers/infiniband/hw/cxgb4/device.c +@@ -1114,8 +1114,10 @@ static inline struct sk_buff *copy_gl_to_skb_pkt(const struct pkt_gl *gl, + * The math here assumes sizeof cpl_pass_accept_req >= sizeof + * cpl_rx_pkt. + */ +- skb = alloc_skb(gl->tot_len + sizeof(struct cpl_pass_accept_req) + +- sizeof(struct rss_header) - pktshift, GFP_ATOMIC); ++ skb = alloc_skb(size_add(gl->tot_len, ++ sizeof(struct cpl_pass_accept_req) + ++ sizeof(struct rss_header)) - pktshift, ++ GFP_ATOMIC); + if (unlikely(!skb)) + return NULL; + +diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c +index 529db874d67c69..b1bbdcff631d56 100644 +--- a/drivers/infiniband/hw/mlx4/main.c ++++ b/drivers/infiniband/hw/mlx4/main.c +@@ -351,7 +351,7 @@ static int mlx4_ib_del_gid(const struct ib_gid_attr *attr, void **context) + struct mlx4_port_gid_table *port_gid_table; + int ret = 0; + int hw_update = 0; +- struct gid_entry *gids; ++ struct gid_entry *gids = NULL; + + if (!rdma_cap_roce_gid_table(attr->device, attr->port_num)) + return -EINVAL; +@@ -389,10 +389,10 @@ static int mlx4_ib_del_gid(const struct ib_gid_attr *attr, void **context) + } + spin_unlock_bh(&iboe->lock); + +- if (!ret && hw_update) { ++ if (gids) + ret = mlx4_ib_update_gids(gids, ibdev, attr->port_num); +- kfree(gids); +- } ++ ++ kfree(gids); + return ret; + } + +diff --git a/drivers/infiniband/hw/mlx5/odp.c b/drivers/infiniband/hw/mlx5/odp.c +index 3a4605fda6d57e..f1a0a324223c0d 100644 +--- a/drivers/infiniband/hw/mlx5/odp.c ++++ b/drivers/infiniband/hw/mlx5/odp.c +@@ -807,8 +807,7 @@ static bool mkey_is_eq(struct mlx5_ib_mkey *mmkey, u32 key) + /* + * Handle a single data segment in a page-fault WQE or RDMA region. + * +- * Returns number of OS pages retrieved on success. The caller may continue to +- * the next data segment. ++ * Returns zero on success. The caller may continue to the next data segment. + * Can return the following error codes: + * -EAGAIN to designate a temporary error. The caller will abort handling the + * page fault and resolve it. +@@ -821,7 +820,7 @@ static int pagefault_single_data_segment(struct mlx5_ib_dev *dev, + u32 *bytes_committed, + u32 *bytes_mapped) + { +- int npages = 0, ret, i, outlen, cur_outlen = 0, depth = 0; ++ int ret, i, outlen, cur_outlen = 0, depth = 0, pages_in_range; + struct pf_frame *head = NULL, *frame; + struct mlx5_ib_mkey *mmkey; + struct mlx5_ib_mr *mr; +@@ -864,13 +863,20 @@ static int pagefault_single_data_segment(struct mlx5_ib_dev *dev, + case MLX5_MKEY_MR: + mr = container_of(mmkey, struct mlx5_ib_mr, mmkey); + ++ pages_in_range = (ALIGN(io_virt + bcnt, PAGE_SIZE) - ++ (io_virt & PAGE_MASK)) >> ++ PAGE_SHIFT; + ret = pagefault_mr(mr, io_virt, bcnt, bytes_mapped, 0, false); + if (ret < 0) + goto end; + + mlx5_update_odp_stats(mr, faults, ret); + +- npages += ret; ++ if (ret < pages_in_range) { ++ ret = -EFAULT; ++ goto end; ++ } ++ + ret = 0; + break; + +@@ -961,7 +967,7 @@ static int pagefault_single_data_segment(struct mlx5_ib_dev *dev, + kfree(out); + + *bytes_committed = 0; +- return ret ? ret : npages; ++ return ret; + } + + /* +@@ -980,8 +986,7 @@ static int pagefault_single_data_segment(struct mlx5_ib_dev *dev, + * the committed bytes). + * @receive_queue: receive WQE end of sg list + * +- * Returns the number of pages loaded if positive, zero for an empty WQE, or a +- * negative error code. ++ * Returns zero for success or a negative error code. + */ + static int pagefault_data_segments(struct mlx5_ib_dev *dev, + struct mlx5_pagefault *pfault, +@@ -989,7 +994,7 @@ static int pagefault_data_segments(struct mlx5_ib_dev *dev, + void *wqe_end, u32 *bytes_mapped, + u32 *total_wqe_bytes, bool receive_queue) + { +- int ret = 0, npages = 0; ++ int ret = 0; + u64 io_virt; + __be32 key; + u32 byte_count; +@@ -1046,10 +1051,9 @@ static int pagefault_data_segments(struct mlx5_ib_dev *dev, + bytes_mapped); + if (ret < 0) + break; +- npages += ret; + } + +- return ret < 0 ? ret : npages; ++ return ret; + } + + /* +@@ -1285,12 +1289,6 @@ static void mlx5_ib_mr_wqe_pfault_handler(struct mlx5_ib_dev *dev, + free_page((unsigned long)wqe_start); + } + +-static int pages_in_range(u64 address, u32 length) +-{ +- return (ALIGN(address + length, PAGE_SIZE) - +- (address & PAGE_MASK)) >> PAGE_SHIFT; +-} +- + static void mlx5_ib_mr_rdma_pfault_handler(struct mlx5_ib_dev *dev, + struct mlx5_pagefault *pfault) + { +@@ -1329,7 +1327,7 @@ static void mlx5_ib_mr_rdma_pfault_handler(struct mlx5_ib_dev *dev, + if (ret == -EAGAIN) { + /* We're racing with an invalidation, don't prefetch */ + prefetch_activated = 0; +- } else if (ret < 0 || pages_in_range(address, length) > ret) { ++ } else if (ret < 0) { + mlx5_ib_page_fault_resume(dev, pfault, 1); + if (ret != -ENOENT) + mlx5_ib_dbg(dev, "PAGE FAULT error %d. QP 0x%x, type: 0x%x\n", +diff --git a/drivers/infiniband/sw/rxe/rxe.c b/drivers/infiniband/sw/rxe/rxe.c +index 6f9ec8db014c79..0f8356cea2931e 100644 +--- a/drivers/infiniband/sw/rxe/rxe.c ++++ b/drivers/infiniband/sw/rxe/rxe.c +@@ -163,7 +163,7 @@ void rxe_set_mtu(struct rxe_dev *rxe, unsigned int ndev_mtu) + port->attr.active_mtu = mtu; + port->mtu_cap = ib_mtu_enum_to_int(mtu); + +- rxe_info_dev(rxe, "Set mtu to %d", port->mtu_cap); ++ rxe_info_dev(rxe, "Set mtu to %d\n", port->mtu_cap); + } + + /* called by ifc layer to create new rxe device. +@@ -183,7 +183,7 @@ static int rxe_newlink(const char *ibdev_name, struct net_device *ndev) + int err = 0; + + if (is_vlan_dev(ndev)) { +- rxe_err("rxe creation allowed on top of a real device only"); ++ rxe_err("rxe creation allowed on top of a real device only\n"); + err = -EPERM; + goto err; + } +@@ -191,7 +191,7 @@ static int rxe_newlink(const char *ibdev_name, struct net_device *ndev) + rxe = rxe_get_dev_from_net(ndev); + if (rxe) { + ib_device_put(&rxe->ib_dev); +- rxe_err_dev(rxe, "already configured on %s", ndev->name); ++ rxe_err_dev(rxe, "already configured on %s\n", ndev->name); + err = -EEXIST; + goto err; + } +diff --git a/drivers/infiniband/sw/rxe/rxe.h b/drivers/infiniband/sw/rxe/rxe.h +index d33dd6cf83d377..d8fb2c7af30a7e 100644 +--- a/drivers/infiniband/sw/rxe/rxe.h ++++ b/drivers/infiniband/sw/rxe/rxe.h +@@ -38,7 +38,7 @@ + + #define RXE_ROCE_V2_SPORT (0xc000) + +-#define rxe_dbg(fmt, ...) pr_debug("%s: " fmt "\n", __func__, ##__VA_ARGS__) ++#define rxe_dbg(fmt, ...) pr_debug("%s: " fmt, __func__, ##__VA_ARGS__) + #define rxe_dbg_dev(rxe, fmt, ...) ibdev_dbg(&(rxe)->ib_dev, \ + "%s: " fmt, __func__, ##__VA_ARGS__) + #define rxe_dbg_uc(uc, fmt, ...) ibdev_dbg((uc)->ibuc.device, \ +@@ -58,7 +58,7 @@ + #define rxe_dbg_mw(mw, fmt, ...) ibdev_dbg((mw)->ibmw.device, \ + "mw#%d %s: " fmt, (mw)->elem.index, __func__, ##__VA_ARGS__) + +-#define rxe_err(fmt, ...) pr_err_ratelimited("%s: " fmt "\n", __func__, \ ++#define rxe_err(fmt, ...) pr_err_ratelimited("%s: " fmt, __func__, \ + ##__VA_ARGS__) + #define rxe_err_dev(rxe, fmt, ...) ibdev_err_ratelimited(&(rxe)->ib_dev, \ + "%s: " fmt, __func__, ##__VA_ARGS__) +@@ -79,7 +79,7 @@ + #define rxe_err_mw(mw, fmt, ...) ibdev_err_ratelimited((mw)->ibmw.device, \ + "mw#%d %s: " fmt, (mw)->elem.index, __func__, ##__VA_ARGS__) + +-#define rxe_info(fmt, ...) pr_info_ratelimited("%s: " fmt "\n", __func__, \ ++#define rxe_info(fmt, ...) pr_info_ratelimited("%s: " fmt, __func__, \ + ##__VA_ARGS__) + #define rxe_info_dev(rxe, fmt, ...) ibdev_info_ratelimited(&(rxe)->ib_dev, \ + "%s: " fmt, __func__, ##__VA_ARGS__) +diff --git a/drivers/infiniband/sw/rxe/rxe_comp.c b/drivers/infiniband/sw/rxe/rxe_comp.c +index acd2172bf092bd..c997b7cbf2a9e8 100644 +--- a/drivers/infiniband/sw/rxe/rxe_comp.c ++++ b/drivers/infiniband/sw/rxe/rxe_comp.c +@@ -433,7 +433,7 @@ static void make_send_cqe(struct rxe_qp *qp, struct rxe_send_wqe *wqe, + } + } else { + if (wqe->status != IB_WC_WR_FLUSH_ERR) +- rxe_err_qp(qp, "non-flush error status = %d", ++ rxe_err_qp(qp, "non-flush error status = %d\n", + wqe->status); + } + } +@@ -582,7 +582,7 @@ static int flush_send_wqe(struct rxe_qp *qp, struct rxe_send_wqe *wqe) + + err = rxe_cq_post(qp->scq, &cqe, 0); + if (err) +- rxe_dbg_cq(qp->scq, "post cq failed, err = %d", err); ++ rxe_dbg_cq(qp->scq, "post cq failed, err = %d\n", err); + + return err; + } +diff --git a/drivers/infiniband/sw/rxe/rxe_cq.c b/drivers/infiniband/sw/rxe/rxe_cq.c +index d5486cbb3f1004..fec87c9030abdc 100644 +--- a/drivers/infiniband/sw/rxe/rxe_cq.c ++++ b/drivers/infiniband/sw/rxe/rxe_cq.c +@@ -27,7 +27,7 @@ int rxe_cq_chk_attr(struct rxe_dev *rxe, struct rxe_cq *cq, + if (cq) { + count = queue_count(cq->queue, QUEUE_TYPE_TO_CLIENT); + if (cqe < count) { +- rxe_dbg_cq(cq, "cqe(%d) < current # elements in queue (%d)", ++ rxe_dbg_cq(cq, "cqe(%d) < current # elements in queue (%d)\n", + cqe, count); + goto err1; + } +@@ -96,7 +96,7 @@ int rxe_cq_post(struct rxe_cq *cq, struct rxe_cqe *cqe, int solicited) + + full = queue_full(cq->queue, QUEUE_TYPE_TO_CLIENT); + if (unlikely(full)) { +- rxe_err_cq(cq, "queue full"); ++ rxe_err_cq(cq, "queue full\n"); + spin_unlock_irqrestore(&cq->cq_lock, flags); + if (cq->ibcq.event_handler) { + ev.device = cq->ibcq.device; +diff --git a/drivers/infiniband/sw/rxe/rxe_mr.c b/drivers/infiniband/sw/rxe/rxe_mr.c +index f54042e9aeb268..bc81fde696ee96 100644 +--- a/drivers/infiniband/sw/rxe/rxe_mr.c ++++ b/drivers/infiniband/sw/rxe/rxe_mr.c +@@ -34,7 +34,7 @@ int mr_check_range(struct rxe_mr *mr, u64 iova, size_t length) + case IB_MR_TYPE_MEM_REG: + if (iova < mr->ibmr.iova || + iova + length > mr->ibmr.iova + mr->ibmr.length) { +- rxe_dbg_mr(mr, "iova/length out of range"); ++ rxe_dbg_mr(mr, "iova/length out of range\n"); + return -EINVAL; + } + return 0; +@@ -319,7 +319,7 @@ int rxe_mr_copy(struct rxe_mr *mr, u64 iova, void *addr, + + err = mr_check_range(mr, iova, length); + if (unlikely(err)) { +- rxe_dbg_mr(mr, "iova out of range"); ++ rxe_dbg_mr(mr, "iova out of range\n"); + return err; + } + +@@ -477,7 +477,7 @@ int rxe_mr_do_atomic_op(struct rxe_mr *mr, u64 iova, int opcode, + u64 *va; + + if (unlikely(mr->state != RXE_MR_STATE_VALID)) { +- rxe_dbg_mr(mr, "mr not in valid state"); ++ rxe_dbg_mr(mr, "mr not in valid state\n"); + return RESPST_ERR_RKEY_VIOLATION; + } + +@@ -490,7 +490,7 @@ int rxe_mr_do_atomic_op(struct rxe_mr *mr, u64 iova, int opcode, + + err = mr_check_range(mr, iova, sizeof(value)); + if (err) { +- rxe_dbg_mr(mr, "iova out of range"); ++ rxe_dbg_mr(mr, "iova out of range\n"); + return RESPST_ERR_RKEY_VIOLATION; + } + page_offset = rxe_mr_iova_to_page_offset(mr, iova); +@@ -501,7 +501,7 @@ int rxe_mr_do_atomic_op(struct rxe_mr *mr, u64 iova, int opcode, + } + + if (unlikely(page_offset & 0x7)) { +- rxe_dbg_mr(mr, "iova not aligned"); ++ rxe_dbg_mr(mr, "iova not aligned\n"); + return RESPST_ERR_MISALIGNED_ATOMIC; + } + +@@ -534,7 +534,7 @@ int rxe_mr_do_atomic_write(struct rxe_mr *mr, u64 iova, u64 value) + + /* See IBA oA19-28 */ + if (unlikely(mr->state != RXE_MR_STATE_VALID)) { +- rxe_dbg_mr(mr, "mr not in valid state"); ++ rxe_dbg_mr(mr, "mr not in valid state\n"); + return RESPST_ERR_RKEY_VIOLATION; + } + +@@ -548,7 +548,7 @@ int rxe_mr_do_atomic_write(struct rxe_mr *mr, u64 iova, u64 value) + /* See IBA oA19-28 */ + err = mr_check_range(mr, iova, sizeof(value)); + if (unlikely(err)) { +- rxe_dbg_mr(mr, "iova out of range"); ++ rxe_dbg_mr(mr, "iova out of range\n"); + return RESPST_ERR_RKEY_VIOLATION; + } + page_offset = rxe_mr_iova_to_page_offset(mr, iova); +@@ -560,7 +560,7 @@ int rxe_mr_do_atomic_write(struct rxe_mr *mr, u64 iova, u64 value) + + /* See IBA A19.4.2 */ + if (unlikely(page_offset & 0x7)) { +- rxe_dbg_mr(mr, "misaligned address"); ++ rxe_dbg_mr(mr, "misaligned address\n"); + return RESPST_ERR_MISALIGNED_ATOMIC; + } + +diff --git a/drivers/infiniband/sw/rxe/rxe_mw.c b/drivers/infiniband/sw/rxe/rxe_mw.c +index d9312b5c9d207e..379e65bfcd49af 100644 +--- a/drivers/infiniband/sw/rxe/rxe_mw.c ++++ b/drivers/infiniband/sw/rxe/rxe_mw.c +@@ -198,7 +198,7 @@ int rxe_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe) + } + + if (access & ~RXE_ACCESS_SUPPORTED_MW) { +- rxe_err_mw(mw, "access %#x not supported", access); ++ rxe_err_mw(mw, "access %#x not supported\n", access); + ret = -EOPNOTSUPP; + goto err_drop_mr; + } +diff --git a/drivers/infiniband/sw/rxe/rxe_param.h b/drivers/infiniband/sw/rxe/rxe_param.h +index d2f57ead78ad12..003f681e5dc022 100644 +--- a/drivers/infiniband/sw/rxe/rxe_param.h ++++ b/drivers/infiniband/sw/rxe/rxe_param.h +@@ -129,7 +129,7 @@ enum rxe_device_param { + enum rxe_port_param { + RXE_PORT_GID_TBL_LEN = 1024, + RXE_PORT_PORT_CAP_FLAGS = IB_PORT_CM_SUP, +- RXE_PORT_MAX_MSG_SZ = 0x800000, ++ RXE_PORT_MAX_MSG_SZ = (1UL << 31), + RXE_PORT_BAD_PKEY_CNTR = 0, + RXE_PORT_QKEY_VIOL_CNTR = 0, + RXE_PORT_LID = 0, +diff --git a/drivers/infiniband/sw/rxe/rxe_pool.c b/drivers/infiniband/sw/rxe/rxe_pool.c +index 6215c6de3a8408..368e366f254d49 100644 +--- a/drivers/infiniband/sw/rxe/rxe_pool.c ++++ b/drivers/infiniband/sw/rxe/rxe_pool.c +@@ -178,7 +178,6 @@ int __rxe_cleanup(struct rxe_pool_elem *elem, bool sleepable) + { + struct rxe_pool *pool = elem->pool; + struct xarray *xa = &pool->xa; +- static int timeout = RXE_POOL_TIMEOUT; + int ret, err = 0; + void *xa_ret; + +@@ -202,19 +201,19 @@ int __rxe_cleanup(struct rxe_pool_elem *elem, bool sleepable) + * return to rdma-core + */ + if (sleepable) { +- if (!completion_done(&elem->complete) && timeout) { ++ if (!completion_done(&elem->complete)) { + ret = wait_for_completion_timeout(&elem->complete, +- timeout); ++ msecs_to_jiffies(50000)); + + /* Shouldn't happen. There are still references to + * the object but, rather than deadlock, free the + * object or pass back to rdma-core. + */ + if (WARN_ON(!ret)) +- err = -EINVAL; ++ err = -ETIMEDOUT; + } + } else { +- unsigned long until = jiffies + timeout; ++ unsigned long until = jiffies + RXE_POOL_TIMEOUT; + + /* AH objects are unique in that the destroy_ah verb + * can be called in atomic context. This delay +@@ -226,7 +225,7 @@ int __rxe_cleanup(struct rxe_pool_elem *elem, bool sleepable) + mdelay(1); + + if (WARN_ON(!completion_done(&elem->complete))) +- err = -EINVAL; ++ err = -ETIMEDOUT; + } + + if (pool->cleanup) +diff --git a/drivers/infiniband/sw/rxe/rxe_qp.c b/drivers/infiniband/sw/rxe/rxe_qp.c +index 3767d7fc0aac82..287fc8b8f5bafe 100644 +--- a/drivers/infiniband/sw/rxe/rxe_qp.c ++++ b/drivers/infiniband/sw/rxe/rxe_qp.c +@@ -201,7 +201,7 @@ static int rxe_init_sq(struct rxe_qp *qp, struct ib_qp_init_attr *init, + qp->sq.queue = rxe_queue_init(rxe, &qp->sq.max_wr, wqe_size, + QUEUE_TYPE_FROM_CLIENT); + if (!qp->sq.queue) { +- rxe_err_qp(qp, "Unable to allocate send queue"); ++ rxe_err_qp(qp, "Unable to allocate send queue\n"); + err = -ENOMEM; + goto err_out; + } +@@ -211,7 +211,7 @@ static int rxe_init_sq(struct rxe_qp *qp, struct ib_qp_init_attr *init, + qp->sq.queue->buf, qp->sq.queue->buf_size, + &qp->sq.queue->ip); + if (err) { +- rxe_err_qp(qp, "do_mmap_info failed, err = %d", err); ++ rxe_err_qp(qp, "do_mmap_info failed, err = %d\n", err); + goto err_free; + } + +@@ -292,7 +292,7 @@ static int rxe_init_rq(struct rxe_qp *qp, struct ib_qp_init_attr *init, + qp->rq.queue = rxe_queue_init(rxe, &qp->rq.max_wr, wqe_size, + QUEUE_TYPE_FROM_CLIENT); + if (!qp->rq.queue) { +- rxe_err_qp(qp, "Unable to allocate recv queue"); ++ rxe_err_qp(qp, "Unable to allocate recv queue\n"); + err = -ENOMEM; + goto err_out; + } +@@ -302,7 +302,7 @@ static int rxe_init_rq(struct rxe_qp *qp, struct ib_qp_init_attr *init, + qp->rq.queue->buf, qp->rq.queue->buf_size, + &qp->rq.queue->ip); + if (err) { +- rxe_err_qp(qp, "do_mmap_info failed, err = %d", err); ++ rxe_err_qp(qp, "do_mmap_info failed, err = %d\n", err); + goto err_free; + } + +diff --git a/drivers/infiniband/sw/rxe/rxe_resp.c b/drivers/infiniband/sw/rxe/rxe_resp.c +index c02aa27fe5d817..fa2b87c7492920 100644 +--- a/drivers/infiniband/sw/rxe/rxe_resp.c ++++ b/drivers/infiniband/sw/rxe/rxe_resp.c +@@ -375,18 +375,18 @@ static enum resp_states rxe_resp_check_length(struct rxe_qp *qp, + if ((pkt->mask & RXE_START_MASK) && + (pkt->mask & RXE_END_MASK)) { + if (unlikely(payload > mtu)) { +- rxe_dbg_qp(qp, "only packet too long"); ++ rxe_dbg_qp(qp, "only packet too long\n"); + return RESPST_ERR_LENGTH; + } + } else if ((pkt->mask & RXE_START_MASK) || + (pkt->mask & RXE_MIDDLE_MASK)) { + if (unlikely(payload != mtu)) { +- rxe_dbg_qp(qp, "first or middle packet not mtu"); ++ rxe_dbg_qp(qp, "first or middle packet not mtu\n"); + return RESPST_ERR_LENGTH; + } + } else if (pkt->mask & RXE_END_MASK) { + if (unlikely((payload == 0) || (payload > mtu))) { +- rxe_dbg_qp(qp, "last packet zero or too long"); ++ rxe_dbg_qp(qp, "last packet zero or too long\n"); + return RESPST_ERR_LENGTH; + } + } +@@ -395,7 +395,7 @@ static enum resp_states rxe_resp_check_length(struct rxe_qp *qp, + /* See IBA C9-94 */ + if (pkt->mask & RXE_RETH_MASK) { + if (reth_len(pkt) > (1U << 31)) { +- rxe_dbg_qp(qp, "dma length too long"); ++ rxe_dbg_qp(qp, "dma length too long\n"); + return RESPST_ERR_LENGTH; + } + } +@@ -1146,7 +1146,7 @@ static enum resp_states do_complete(struct rxe_qp *qp, + } + } else { + if (wc->status != IB_WC_WR_FLUSH_ERR) +- rxe_err_qp(qp, "non-flush error status = %d", ++ rxe_err_qp(qp, "non-flush error status = %d\n", + wc->status); + } + +@@ -1455,7 +1455,7 @@ static int flush_recv_wqe(struct rxe_qp *qp, struct rxe_recv_wqe *wqe) + + err = rxe_cq_post(qp->rcq, &cqe, 0); + if (err) +- rxe_dbg_cq(qp->rcq, "post cq failed err = %d", err); ++ rxe_dbg_cq(qp->rcq, "post cq failed err = %d\n", err); + + return err; + } +diff --git a/drivers/infiniband/sw/rxe/rxe_task.c b/drivers/infiniband/sw/rxe/rxe_task.c +index 1501120d4f5241..80332638d9e3ac 100644 +--- a/drivers/infiniband/sw/rxe/rxe_task.c ++++ b/drivers/infiniband/sw/rxe/rxe_task.c +@@ -156,7 +156,7 @@ static void do_task(struct rxe_task *task) + + default: + WARN_ON(1); +- rxe_dbg_qp(task->qp, "unexpected task state = %d", ++ rxe_dbg_qp(task->qp, "unexpected task state = %d\n", + task->state); + task->state = TASK_STATE_IDLE; + } +@@ -167,7 +167,7 @@ static void do_task(struct rxe_task *task) + if (WARN_ON(task->num_done != task->num_sched)) + rxe_dbg_qp( + task->qp, +- "%ld tasks scheduled, %ld tasks done", ++ "%ld tasks scheduled, %ld tasks done\n", + task->num_sched, task->num_done); + } + spin_unlock_irqrestore(&task->lock, flags); +diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.c b/drivers/infiniband/sw/rxe/rxe_verbs.c +index 9f46b9f74825ff..dbb9baa4ffd002 100644 +--- a/drivers/infiniband/sw/rxe/rxe_verbs.c ++++ b/drivers/infiniband/sw/rxe/rxe_verbs.c +@@ -23,7 +23,7 @@ static int rxe_query_device(struct ib_device *ibdev, + int err; + + if (udata->inlen || udata->outlen) { +- rxe_dbg_dev(rxe, "malformed udata"); ++ rxe_dbg_dev(rxe, "malformed udata\n"); + err = -EINVAL; + goto err_out; + } +@@ -33,7 +33,7 @@ static int rxe_query_device(struct ib_device *ibdev, + return 0; + + err_out: +- rxe_err_dev(rxe, "returned err = %d", err); ++ rxe_err_dev(rxe, "returned err = %d\n", err); + return err; + } + +@@ -45,7 +45,7 @@ static int rxe_query_port(struct ib_device *ibdev, + + if (port_num != 1) { + err = -EINVAL; +- rxe_dbg_dev(rxe, "bad port_num = %d", port_num); ++ rxe_dbg_dev(rxe, "bad port_num = %d\n", port_num); + goto err_out; + } + +@@ -67,7 +67,7 @@ static int rxe_query_port(struct ib_device *ibdev, + return ret; + + err_out: +- rxe_err_dev(rxe, "returned err = %d", err); ++ rxe_err_dev(rxe, "returned err = %d\n", err); + return err; + } + +@@ -79,7 +79,7 @@ static int rxe_query_pkey(struct ib_device *ibdev, + + if (index != 0) { + err = -EINVAL; +- rxe_dbg_dev(rxe, "bad pkey index = %d", index); ++ rxe_dbg_dev(rxe, "bad pkey index = %d\n", index); + goto err_out; + } + +@@ -87,7 +87,7 @@ static int rxe_query_pkey(struct ib_device *ibdev, + return 0; + + err_out: +- rxe_err_dev(rxe, "returned err = %d", err); ++ rxe_err_dev(rxe, "returned err = %d\n", err); + return err; + } + +@@ -100,7 +100,7 @@ static int rxe_modify_device(struct ib_device *ibdev, + if (mask & ~(IB_DEVICE_MODIFY_SYS_IMAGE_GUID | + IB_DEVICE_MODIFY_NODE_DESC)) { + err = -EOPNOTSUPP; +- rxe_dbg_dev(rxe, "unsupported mask = 0x%x", mask); ++ rxe_dbg_dev(rxe, "unsupported mask = 0x%x\n", mask); + goto err_out; + } + +@@ -115,7 +115,7 @@ static int rxe_modify_device(struct ib_device *ibdev, + return 0; + + err_out: +- rxe_err_dev(rxe, "returned err = %d", err); ++ rxe_err_dev(rxe, "returned err = %d\n", err); + return err; + } + +@@ -128,14 +128,14 @@ static int rxe_modify_port(struct ib_device *ibdev, u32 port_num, + + if (port_num != 1) { + err = -EINVAL; +- rxe_dbg_dev(rxe, "bad port_num = %d", port_num); ++ rxe_dbg_dev(rxe, "bad port_num = %d\n", port_num); + goto err_out; + } + + //TODO is shutdown useful + if (mask & ~(IB_PORT_RESET_QKEY_CNTR)) { + err = -EOPNOTSUPP; +- rxe_dbg_dev(rxe, "unsupported mask = 0x%x", mask); ++ rxe_dbg_dev(rxe, "unsupported mask = 0x%x\n", mask); + goto err_out; + } + +@@ -149,7 +149,7 @@ static int rxe_modify_port(struct ib_device *ibdev, u32 port_num, + return 0; + + err_out: +- rxe_err_dev(rxe, "returned err = %d", err); ++ rxe_err_dev(rxe, "returned err = %d\n", err); + return err; + } + +@@ -161,14 +161,14 @@ static enum rdma_link_layer rxe_get_link_layer(struct ib_device *ibdev, + + if (port_num != 1) { + err = -EINVAL; +- rxe_dbg_dev(rxe, "bad port_num = %d", port_num); ++ rxe_dbg_dev(rxe, "bad port_num = %d\n", port_num); + goto err_out; + } + + return IB_LINK_LAYER_ETHERNET; + + err_out: +- rxe_err_dev(rxe, "returned err = %d", err); ++ rxe_err_dev(rxe, "returned err = %d\n", err); + return err; + } + +@@ -181,7 +181,7 @@ static int rxe_port_immutable(struct ib_device *ibdev, u32 port_num, + + if (port_num != 1) { + err = -EINVAL; +- rxe_dbg_dev(rxe, "bad port_num = %d", port_num); ++ rxe_dbg_dev(rxe, "bad port_num = %d\n", port_num); + goto err_out; + } + +@@ -197,7 +197,7 @@ static int rxe_port_immutable(struct ib_device *ibdev, u32 port_num, + return 0; + + err_out: +- rxe_err_dev(rxe, "returned err = %d", err); ++ rxe_err_dev(rxe, "returned err = %d\n", err); + return err; + } + +@@ -210,7 +210,7 @@ static int rxe_alloc_ucontext(struct ib_ucontext *ibuc, struct ib_udata *udata) + + err = rxe_add_to_pool(&rxe->uc_pool, uc); + if (err) +- rxe_err_dev(rxe, "unable to create uc"); ++ rxe_err_dev(rxe, "unable to create uc\n"); + + return err; + } +@@ -222,7 +222,7 @@ static void rxe_dealloc_ucontext(struct ib_ucontext *ibuc) + + err = rxe_cleanup(uc); + if (err) +- rxe_err_uc(uc, "cleanup failed, err = %d", err); ++ rxe_err_uc(uc, "cleanup failed, err = %d\n", err); + } + + /* pd */ +@@ -234,14 +234,14 @@ static int rxe_alloc_pd(struct ib_pd *ibpd, struct ib_udata *udata) + + err = rxe_add_to_pool(&rxe->pd_pool, pd); + if (err) { +- rxe_dbg_dev(rxe, "unable to alloc pd"); ++ rxe_dbg_dev(rxe, "unable to alloc pd\n"); + goto err_out; + } + + return 0; + + err_out: +- rxe_err_dev(rxe, "returned err = %d", err); ++ rxe_err_dev(rxe, "returned err = %d\n", err); + return err; + } + +@@ -252,7 +252,7 @@ static int rxe_dealloc_pd(struct ib_pd *ibpd, struct ib_udata *udata) + + err = rxe_cleanup(pd); + if (err) +- rxe_err_pd(pd, "cleanup failed, err = %d", err); ++ rxe_err_pd(pd, "cleanup failed, err = %d\n", err); + + return 0; + } +@@ -279,7 +279,7 @@ static int rxe_create_ah(struct ib_ah *ibah, + err = rxe_add_to_pool_ah(&rxe->ah_pool, ah, + init_attr->flags & RDMA_CREATE_AH_SLEEPABLE); + if (err) { +- rxe_dbg_dev(rxe, "unable to create ah"); ++ rxe_dbg_dev(rxe, "unable to create ah\n"); + goto err_out; + } + +@@ -288,7 +288,7 @@ static int rxe_create_ah(struct ib_ah *ibah, + + err = rxe_ah_chk_attr(ah, init_attr->ah_attr); + if (err) { +- rxe_dbg_ah(ah, "bad attr"); ++ rxe_dbg_ah(ah, "bad attr\n"); + goto err_cleanup; + } + +@@ -298,7 +298,7 @@ static int rxe_create_ah(struct ib_ah *ibah, + sizeof(uresp->ah_num)); + if (err) { + err = -EFAULT; +- rxe_dbg_ah(ah, "unable to copy to user"); ++ rxe_dbg_ah(ah, "unable to copy to user\n"); + goto err_cleanup; + } + } else if (ah->is_user) { +@@ -314,9 +314,9 @@ static int rxe_create_ah(struct ib_ah *ibah, + err_cleanup: + cleanup_err = rxe_cleanup(ah); + if (cleanup_err) +- rxe_err_ah(ah, "cleanup failed, err = %d", cleanup_err); ++ rxe_err_ah(ah, "cleanup failed, err = %d\n", cleanup_err); + err_out: +- rxe_err_ah(ah, "returned err = %d", err); ++ rxe_err_ah(ah, "returned err = %d\n", err); + return err; + } + +@@ -327,7 +327,7 @@ static int rxe_modify_ah(struct ib_ah *ibah, struct rdma_ah_attr *attr) + + err = rxe_ah_chk_attr(ah, attr); + if (err) { +- rxe_dbg_ah(ah, "bad attr"); ++ rxe_dbg_ah(ah, "bad attr\n"); + goto err_out; + } + +@@ -336,7 +336,7 @@ static int rxe_modify_ah(struct ib_ah *ibah, struct rdma_ah_attr *attr) + return 0; + + err_out: +- rxe_err_ah(ah, "returned err = %d", err); ++ rxe_err_ah(ah, "returned err = %d\n", err); + return err; + } + +@@ -358,7 +358,7 @@ static int rxe_destroy_ah(struct ib_ah *ibah, u32 flags) + + err = rxe_cleanup_ah(ah, flags & RDMA_DESTROY_AH_SLEEPABLE); + if (err) +- rxe_err_ah(ah, "cleanup failed, err = %d", err); ++ rxe_err_ah(ah, "cleanup failed, err = %d\n", err); + + return 0; + } +@@ -376,7 +376,7 @@ static int rxe_create_srq(struct ib_srq *ibsrq, struct ib_srq_init_attr *init, + if (udata) { + if (udata->outlen < sizeof(*uresp)) { + err = -EINVAL; +- rxe_err_dev(rxe, "malformed udata"); ++ rxe_err_dev(rxe, "malformed udata\n"); + goto err_out; + } + uresp = udata->outbuf; +@@ -384,20 +384,20 @@ static int rxe_create_srq(struct ib_srq *ibsrq, struct ib_srq_init_attr *init, + + if (init->srq_type != IB_SRQT_BASIC) { + err = -EOPNOTSUPP; +- rxe_dbg_dev(rxe, "srq type = %d, not supported", ++ rxe_dbg_dev(rxe, "srq type = %d, not supported\n", + init->srq_type); + goto err_out; + } + + err = rxe_srq_chk_init(rxe, init); + if (err) { +- rxe_dbg_dev(rxe, "invalid init attributes"); ++ rxe_dbg_dev(rxe, "invalid init attributes\n"); + goto err_out; + } + + err = rxe_add_to_pool(&rxe->srq_pool, srq); + if (err) { +- rxe_dbg_dev(rxe, "unable to create srq, err = %d", err); ++ rxe_dbg_dev(rxe, "unable to create srq, err = %d\n", err); + goto err_out; + } + +@@ -406,7 +406,7 @@ static int rxe_create_srq(struct ib_srq *ibsrq, struct ib_srq_init_attr *init, + + err = rxe_srq_from_init(rxe, srq, init, udata, uresp); + if (err) { +- rxe_dbg_srq(srq, "create srq failed, err = %d", err); ++ rxe_dbg_srq(srq, "create srq failed, err = %d\n", err); + goto err_cleanup; + } + +@@ -415,9 +415,9 @@ static int rxe_create_srq(struct ib_srq *ibsrq, struct ib_srq_init_attr *init, + err_cleanup: + cleanup_err = rxe_cleanup(srq); + if (cleanup_err) +- rxe_err_srq(srq, "cleanup failed, err = %d", cleanup_err); ++ rxe_err_srq(srq, "cleanup failed, err = %d\n", cleanup_err); + err_out: +- rxe_err_dev(rxe, "returned err = %d", err); ++ rxe_err_dev(rxe, "returned err = %d\n", err); + return err; + } + +@@ -433,34 +433,34 @@ static int rxe_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr, + if (udata) { + if (udata->inlen < sizeof(cmd)) { + err = -EINVAL; +- rxe_dbg_srq(srq, "malformed udata"); ++ rxe_dbg_srq(srq, "malformed udata\n"); + goto err_out; + } + + err = ib_copy_from_udata(&cmd, udata, sizeof(cmd)); + if (err) { + err = -EFAULT; +- rxe_dbg_srq(srq, "unable to read udata"); ++ rxe_dbg_srq(srq, "unable to read udata\n"); + goto err_out; + } + } + + err = rxe_srq_chk_attr(rxe, srq, attr, mask); + if (err) { +- rxe_dbg_srq(srq, "bad init attributes"); ++ rxe_dbg_srq(srq, "bad init attributes\n"); + goto err_out; + } + + err = rxe_srq_from_attr(rxe, srq, attr, mask, &cmd, udata); + if (err) { +- rxe_dbg_srq(srq, "bad attr"); ++ rxe_dbg_srq(srq, "bad attr\n"); + goto err_out; + } + + return 0; + + err_out: +- rxe_err_srq(srq, "returned err = %d", err); ++ rxe_err_srq(srq, "returned err = %d\n", err); + return err; + } + +@@ -471,7 +471,7 @@ static int rxe_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr) + + if (srq->error) { + err = -EINVAL; +- rxe_dbg_srq(srq, "srq in error state"); ++ rxe_dbg_srq(srq, "srq in error state\n"); + goto err_out; + } + +@@ -481,7 +481,7 @@ static int rxe_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr) + return 0; + + err_out: +- rxe_err_srq(srq, "returned err = %d", err); ++ rxe_err_srq(srq, "returned err = %d\n", err); + return err; + } + +@@ -505,7 +505,7 @@ static int rxe_post_srq_recv(struct ib_srq *ibsrq, const struct ib_recv_wr *wr, + + if (err) { + *bad_wr = wr; +- rxe_err_srq(srq, "returned err = %d", err); ++ rxe_err_srq(srq, "returned err = %d\n", err); + } + + return err; +@@ -518,7 +518,7 @@ static int rxe_destroy_srq(struct ib_srq *ibsrq, struct ib_udata *udata) + + err = rxe_cleanup(srq); + if (err) +- rxe_err_srq(srq, "cleanup failed, err = %d", err); ++ rxe_err_srq(srq, "cleanup failed, err = %d\n", err); + + return 0; + } +@@ -536,13 +536,13 @@ static int rxe_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *init, + if (udata) { + if (udata->inlen) { + err = -EINVAL; +- rxe_dbg_dev(rxe, "malformed udata, err = %d", err); ++ rxe_dbg_dev(rxe, "malformed udata, err = %d\n", err); + goto err_out; + } + + if (udata->outlen < sizeof(*uresp)) { + err = -EINVAL; +- rxe_dbg_dev(rxe, "malformed udata, err = %d", err); ++ rxe_dbg_dev(rxe, "malformed udata, err = %d\n", err); + goto err_out; + } + +@@ -554,25 +554,25 @@ static int rxe_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *init, + + if (init->create_flags) { + err = -EOPNOTSUPP; +- rxe_dbg_dev(rxe, "unsupported create_flags, err = %d", err); ++ rxe_dbg_dev(rxe, "unsupported create_flags, err = %d\n", err); + goto err_out; + } + + err = rxe_qp_chk_init(rxe, init); + if (err) { +- rxe_dbg_dev(rxe, "bad init attr, err = %d", err); ++ rxe_dbg_dev(rxe, "bad init attr, err = %d\n", err); + goto err_out; + } + + err = rxe_add_to_pool(&rxe->qp_pool, qp); + if (err) { +- rxe_dbg_dev(rxe, "unable to create qp, err = %d", err); ++ rxe_dbg_dev(rxe, "unable to create qp, err = %d\n", err); + goto err_out; + } + + err = rxe_qp_from_init(rxe, qp, pd, init, uresp, ibqp->pd, udata); + if (err) { +- rxe_dbg_qp(qp, "create qp failed, err = %d", err); ++ rxe_dbg_qp(qp, "create qp failed, err = %d\n", err); + goto err_cleanup; + } + +@@ -582,9 +582,9 @@ static int rxe_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *init, + err_cleanup: + cleanup_err = rxe_cleanup(qp); + if (cleanup_err) +- rxe_err_qp(qp, "cleanup failed, err = %d", cleanup_err); ++ rxe_err_qp(qp, "cleanup failed, err = %d\n", cleanup_err); + err_out: +- rxe_err_dev(rxe, "returned err = %d", err); ++ rxe_err_dev(rxe, "returned err = %d\n", err); + return err; + } + +@@ -597,20 +597,20 @@ static int rxe_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, + + if (mask & ~IB_QP_ATTR_STANDARD_BITS) { + err = -EOPNOTSUPP; +- rxe_dbg_qp(qp, "unsupported mask = 0x%x, err = %d", ++ rxe_dbg_qp(qp, "unsupported mask = 0x%x, err = %d\n", + mask, err); + goto err_out; + } + + err = rxe_qp_chk_attr(rxe, qp, attr, mask); + if (err) { +- rxe_dbg_qp(qp, "bad mask/attr, err = %d", err); ++ rxe_dbg_qp(qp, "bad mask/attr, err = %d\n", err); + goto err_out; + } + + err = rxe_qp_from_attr(qp, attr, mask, udata); + if (err) { +- rxe_dbg_qp(qp, "modify qp failed, err = %d", err); ++ rxe_dbg_qp(qp, "modify qp failed, err = %d\n", err); + goto err_out; + } + +@@ -622,7 +622,7 @@ static int rxe_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, + return 0; + + err_out: +- rxe_err_qp(qp, "returned err = %d", err); ++ rxe_err_qp(qp, "returned err = %d\n", err); + return err; + } + +@@ -644,18 +644,18 @@ static int rxe_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata) + + err = rxe_qp_chk_destroy(qp); + if (err) { +- rxe_dbg_qp(qp, "unable to destroy qp, err = %d", err); ++ rxe_dbg_qp(qp, "unable to destroy qp, err = %d\n", err); + goto err_out; + } + + err = rxe_cleanup(qp); + if (err) +- rxe_err_qp(qp, "cleanup failed, err = %d", err); ++ rxe_err_qp(qp, "cleanup failed, err = %d\n", err); + + return 0; + + err_out: +- rxe_err_qp(qp, "returned err = %d", err); ++ rxe_err_qp(qp, "returned err = %d\n", err); + return err; + } + +@@ -675,12 +675,12 @@ static int validate_send_wr(struct rxe_qp *qp, const struct ib_send_wr *ibwr, + do { + mask = wr_opcode_mask(ibwr->opcode, qp); + if (!mask) { +- rxe_err_qp(qp, "bad wr opcode for qp type"); ++ rxe_err_qp(qp, "bad wr opcode for qp type\n"); + break; + } + + if (num_sge > sq->max_sge) { +- rxe_err_qp(qp, "num_sge > max_sge"); ++ rxe_err_qp(qp, "num_sge > max_sge\n"); + break; + } + +@@ -688,28 +688,28 @@ static int validate_send_wr(struct rxe_qp *qp, const struct ib_send_wr *ibwr, + for (i = 0; i < ibwr->num_sge; i++) + length += ibwr->sg_list[i].length; + +- if (length > (1UL << 31)) { +- rxe_err_qp(qp, "message length too long"); ++ if (length > RXE_PORT_MAX_MSG_SZ) { ++ rxe_err_qp(qp, "message length too long\n"); + break; + } + + if (mask & WR_ATOMIC_MASK) { + if (length != 8) { +- rxe_err_qp(qp, "atomic length != 8"); ++ rxe_err_qp(qp, "atomic length != 8\n"); + break; + } + if (atomic_wr(ibwr)->remote_addr & 0x7) { +- rxe_err_qp(qp, "misaligned atomic address"); ++ rxe_err_qp(qp, "misaligned atomic address\n"); + break; + } + } + if (ibwr->send_flags & IB_SEND_INLINE) { + if (!(mask & WR_INLINE_MASK)) { +- rxe_err_qp(qp, "opcode doesn't support inline data"); ++ rxe_err_qp(qp, "opcode doesn't support inline data\n"); + break; + } + if (length > sq->max_inline) { +- rxe_err_qp(qp, "inline length too big"); ++ rxe_err_qp(qp, "inline length too big\n"); + break; + } + } +@@ -747,7 +747,7 @@ static int init_send_wr(struct rxe_qp *qp, struct rxe_send_wr *wr, + case IB_WR_SEND: + break; + default: +- rxe_err_qp(qp, "bad wr opcode %d for UD/GSI QP", ++ rxe_err_qp(qp, "bad wr opcode %d for UD/GSI QP\n", + wr->opcode); + return -EINVAL; + } +@@ -795,7 +795,7 @@ static int init_send_wr(struct rxe_qp *qp, struct rxe_send_wr *wr, + case IB_WR_ATOMIC_WRITE: + break; + default: +- rxe_err_qp(qp, "unsupported wr opcode %d", ++ rxe_err_qp(qp, "unsupported wr opcode %d\n", + wr->opcode); + return -EINVAL; + } +@@ -870,7 +870,7 @@ static int post_one_send(struct rxe_qp *qp, const struct ib_send_wr *ibwr) + + full = queue_full(sq->queue, QUEUE_TYPE_FROM_ULP); + if (unlikely(full)) { +- rxe_err_qp(qp, "send queue full"); ++ rxe_err_qp(qp, "send queue full\n"); + return -ENOMEM; + } + +@@ -926,14 +926,14 @@ static int rxe_post_send(struct ib_qp *ibqp, const struct ib_send_wr *wr, + /* caller has already called destroy_qp */ + if (WARN_ON_ONCE(!qp->valid)) { + spin_unlock_irqrestore(&qp->state_lock, flags); +- rxe_err_qp(qp, "qp has been destroyed"); ++ rxe_err_qp(qp, "qp has been destroyed\n"); + return -EINVAL; + } + + if (unlikely(qp_state(qp) < IB_QPS_RTS)) { + spin_unlock_irqrestore(&qp->state_lock, flags); + *bad_wr = wr; +- rxe_err_qp(qp, "qp not ready to send"); ++ rxe_err_qp(qp, "qp not ready to send\n"); + return -EINVAL; + } + spin_unlock_irqrestore(&qp->state_lock, flags); +@@ -963,13 +963,13 @@ static int post_one_recv(struct rxe_rq *rq, const struct ib_recv_wr *ibwr) + full = queue_full(rq->queue, QUEUE_TYPE_FROM_ULP); + if (unlikely(full)) { + err = -ENOMEM; +- rxe_dbg("queue full"); ++ rxe_dbg("queue full\n"); + goto err_out; + } + + if (unlikely(num_sge > rq->max_sge)) { + err = -EINVAL; +- rxe_dbg("bad num_sge > max_sge"); ++ rxe_dbg("bad num_sge > max_sge\n"); + goto err_out; + } + +@@ -977,10 +977,9 @@ static int post_one_recv(struct rxe_rq *rq, const struct ib_recv_wr *ibwr) + for (i = 0; i < num_sge; i++) + length += ibwr->sg_list[i].length; + +- /* IBA max message size is 2^31 */ +- if (length >= (1UL<<31)) { ++ if (length > RXE_PORT_MAX_MSG_SZ) { + err = -EINVAL; +- rxe_dbg("message length too long"); ++ rxe_dbg("message length too long\n"); + goto err_out; + } + +@@ -1000,7 +999,7 @@ static int post_one_recv(struct rxe_rq *rq, const struct ib_recv_wr *ibwr) + return 0; + + err_out: +- rxe_dbg("returned err = %d", err); ++ rxe_dbg("returned err = %d\n", err); + return err; + } + +@@ -1016,7 +1015,7 @@ static int rxe_post_recv(struct ib_qp *ibqp, const struct ib_recv_wr *wr, + /* caller has already called destroy_qp */ + if (WARN_ON_ONCE(!qp->valid)) { + spin_unlock_irqrestore(&qp->state_lock, flags); +- rxe_err_qp(qp, "qp has been destroyed"); ++ rxe_err_qp(qp, "qp has been destroyed\n"); + return -EINVAL; + } + +@@ -1024,14 +1023,14 @@ static int rxe_post_recv(struct ib_qp *ibqp, const struct ib_recv_wr *wr, + if (unlikely((qp_state(qp) < IB_QPS_INIT))) { + spin_unlock_irqrestore(&qp->state_lock, flags); + *bad_wr = wr; +- rxe_dbg_qp(qp, "qp not ready to post recv"); ++ rxe_dbg_qp(qp, "qp not ready to post recv\n"); + return -EINVAL; + } + spin_unlock_irqrestore(&qp->state_lock, flags); + + if (unlikely(qp->srq)) { + *bad_wr = wr; +- rxe_dbg_qp(qp, "qp has srq, use post_srq_recv instead"); ++ rxe_dbg_qp(qp, "qp has srq, use post_srq_recv instead\n"); + return -EINVAL; + } + +@@ -1069,7 +1068,7 @@ static int rxe_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr, + if (udata) { + if (udata->outlen < sizeof(*uresp)) { + err = -EINVAL; +- rxe_dbg_dev(rxe, "malformed udata, err = %d", err); ++ rxe_dbg_dev(rxe, "malformed udata, err = %d\n", err); + goto err_out; + } + uresp = udata->outbuf; +@@ -1077,26 +1076,26 @@ static int rxe_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr, + + if (attr->flags) { + err = -EOPNOTSUPP; +- rxe_dbg_dev(rxe, "bad attr->flags, err = %d", err); ++ rxe_dbg_dev(rxe, "bad attr->flags, err = %d\n", err); + goto err_out; + } + + err = rxe_cq_chk_attr(rxe, NULL, attr->cqe, attr->comp_vector); + if (err) { +- rxe_dbg_dev(rxe, "bad init attributes, err = %d", err); ++ rxe_dbg_dev(rxe, "bad init attributes, err = %d\n", err); + goto err_out; + } + + err = rxe_add_to_pool(&rxe->cq_pool, cq); + if (err) { +- rxe_dbg_dev(rxe, "unable to create cq, err = %d", err); ++ rxe_dbg_dev(rxe, "unable to create cq, err = %d\n", err); + goto err_out; + } + + err = rxe_cq_from_init(rxe, cq, attr->cqe, attr->comp_vector, udata, + uresp); + if (err) { +- rxe_dbg_cq(cq, "create cq failed, err = %d", err); ++ rxe_dbg_cq(cq, "create cq failed, err = %d\n", err); + goto err_cleanup; + } + +@@ -1105,9 +1104,9 @@ static int rxe_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr, + err_cleanup: + cleanup_err = rxe_cleanup(cq); + if (cleanup_err) +- rxe_err_cq(cq, "cleanup failed, err = %d", cleanup_err); ++ rxe_err_cq(cq, "cleanup failed, err = %d\n", cleanup_err); + err_out: +- rxe_err_dev(rxe, "returned err = %d", err); ++ rxe_err_dev(rxe, "returned err = %d\n", err); + return err; + } + +@@ -1121,7 +1120,7 @@ static int rxe_resize_cq(struct ib_cq *ibcq, int cqe, struct ib_udata *udata) + if (udata) { + if (udata->outlen < sizeof(*uresp)) { + err = -EINVAL; +- rxe_dbg_cq(cq, "malformed udata"); ++ rxe_dbg_cq(cq, "malformed udata\n"); + goto err_out; + } + uresp = udata->outbuf; +@@ -1129,20 +1128,20 @@ static int rxe_resize_cq(struct ib_cq *ibcq, int cqe, struct ib_udata *udata) + + err = rxe_cq_chk_attr(rxe, cq, cqe, 0); + if (err) { +- rxe_dbg_cq(cq, "bad attr, err = %d", err); ++ rxe_dbg_cq(cq, "bad attr, err = %d\n", err); + goto err_out; + } + + err = rxe_cq_resize_queue(cq, cqe, uresp, udata); + if (err) { +- rxe_dbg_cq(cq, "resize cq failed, err = %d", err); ++ rxe_dbg_cq(cq, "resize cq failed, err = %d\n", err); + goto err_out; + } + + return 0; + + err_out: +- rxe_err_cq(cq, "returned err = %d", err); ++ rxe_err_cq(cq, "returned err = %d\n", err); + return err; + } + +@@ -1206,18 +1205,18 @@ static int rxe_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata) + */ + if (atomic_read(&cq->num_wq)) { + err = -EINVAL; +- rxe_dbg_cq(cq, "still in use"); ++ rxe_dbg_cq(cq, "still in use\n"); + goto err_out; + } + + err = rxe_cleanup(cq); + if (err) +- rxe_err_cq(cq, "cleanup failed, err = %d", err); ++ rxe_err_cq(cq, "cleanup failed, err = %d\n", err); + + return 0; + + err_out: +- rxe_err_cq(cq, "returned err = %d", err); ++ rxe_err_cq(cq, "returned err = %d\n", err); + return err; + } + +@@ -1235,7 +1234,7 @@ static struct ib_mr *rxe_get_dma_mr(struct ib_pd *ibpd, int access) + + err = rxe_add_to_pool(&rxe->mr_pool, mr); + if (err) { +- rxe_dbg_dev(rxe, "unable to create mr"); ++ rxe_dbg_dev(rxe, "unable to create mr\n"); + goto err_free; + } + +@@ -1249,7 +1248,7 @@ static struct ib_mr *rxe_get_dma_mr(struct ib_pd *ibpd, int access) + + err_free: + kfree(mr); +- rxe_err_pd(pd, "returned err = %d", err); ++ rxe_err_pd(pd, "returned err = %d\n", err); + return ERR_PTR(err); + } + +@@ -1263,7 +1262,7 @@ static struct ib_mr *rxe_reg_user_mr(struct ib_pd *ibpd, u64 start, + int err, cleanup_err; + + if (access & ~RXE_ACCESS_SUPPORTED_MR) { +- rxe_err_pd(pd, "access = %#x not supported (%#x)", access, ++ rxe_err_pd(pd, "access = %#x not supported (%#x)\n", access, + RXE_ACCESS_SUPPORTED_MR); + return ERR_PTR(-EOPNOTSUPP); + } +@@ -1274,7 +1273,7 @@ static struct ib_mr *rxe_reg_user_mr(struct ib_pd *ibpd, u64 start, + + err = rxe_add_to_pool(&rxe->mr_pool, mr); + if (err) { +- rxe_dbg_pd(pd, "unable to create mr"); ++ rxe_dbg_pd(pd, "unable to create mr\n"); + goto err_free; + } + +@@ -1284,7 +1283,7 @@ static struct ib_mr *rxe_reg_user_mr(struct ib_pd *ibpd, u64 start, + + err = rxe_mr_init_user(rxe, start, length, iova, access, mr); + if (err) { +- rxe_dbg_mr(mr, "reg_user_mr failed, err = %d", err); ++ rxe_dbg_mr(mr, "reg_user_mr failed, err = %d\n", err); + goto err_cleanup; + } + +@@ -1294,10 +1293,10 @@ static struct ib_mr *rxe_reg_user_mr(struct ib_pd *ibpd, u64 start, + err_cleanup: + cleanup_err = rxe_cleanup(mr); + if (cleanup_err) +- rxe_err_mr(mr, "cleanup failed, err = %d", cleanup_err); ++ rxe_err_mr(mr, "cleanup failed, err = %d\n", cleanup_err); + err_free: + kfree(mr); +- rxe_err_pd(pd, "returned err = %d", err); ++ rxe_err_pd(pd, "returned err = %d\n", err); + return ERR_PTR(err); + } + +@@ -1314,7 +1313,7 @@ static struct ib_mr *rxe_rereg_user_mr(struct ib_mr *ibmr, int flags, + * rereg_pd and rereg_access + */ + if (flags & ~RXE_MR_REREG_SUPPORTED) { +- rxe_err_mr(mr, "flags = %#x not supported", flags); ++ rxe_err_mr(mr, "flags = %#x not supported\n", flags); + return ERR_PTR(-EOPNOTSUPP); + } + +@@ -1326,7 +1325,7 @@ static struct ib_mr *rxe_rereg_user_mr(struct ib_mr *ibmr, int flags, + + if (flags & IB_MR_REREG_ACCESS) { + if (access & ~RXE_ACCESS_SUPPORTED_MR) { +- rxe_err_mr(mr, "access = %#x not supported", access); ++ rxe_err_mr(mr, "access = %#x not supported\n", access); + return ERR_PTR(-EOPNOTSUPP); + } + mr->access = access; +@@ -1345,7 +1344,7 @@ static struct ib_mr *rxe_alloc_mr(struct ib_pd *ibpd, enum ib_mr_type mr_type, + + if (mr_type != IB_MR_TYPE_MEM_REG) { + err = -EINVAL; +- rxe_dbg_pd(pd, "mr type %d not supported, err = %d", ++ rxe_dbg_pd(pd, "mr type %d not supported, err = %d\n", + mr_type, err); + goto err_out; + } +@@ -1364,7 +1363,7 @@ static struct ib_mr *rxe_alloc_mr(struct ib_pd *ibpd, enum ib_mr_type mr_type, + + err = rxe_mr_init_fast(max_num_sg, mr); + if (err) { +- rxe_dbg_mr(mr, "alloc_mr failed, err = %d", err); ++ rxe_dbg_mr(mr, "alloc_mr failed, err = %d\n", err); + goto err_cleanup; + } + +@@ -1374,11 +1373,11 @@ static struct ib_mr *rxe_alloc_mr(struct ib_pd *ibpd, enum ib_mr_type mr_type, + err_cleanup: + cleanup_err = rxe_cleanup(mr); + if (cleanup_err) +- rxe_err_mr(mr, "cleanup failed, err = %d", err); ++ rxe_err_mr(mr, "cleanup failed, err = %d\n", err); + err_free: + kfree(mr); + err_out: +- rxe_err_pd(pd, "returned err = %d", err); ++ rxe_err_pd(pd, "returned err = %d\n", err); + return ERR_PTR(err); + } + +@@ -1390,19 +1389,19 @@ static int rxe_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata) + /* See IBA 10.6.7.2.6 */ + if (atomic_read(&mr->num_mw) > 0) { + err = -EINVAL; +- rxe_dbg_mr(mr, "mr has mw's bound"); ++ rxe_dbg_mr(mr, "mr has mw's bound\n"); + goto err_out; + } + + cleanup_err = rxe_cleanup(mr); + if (cleanup_err) +- rxe_err_mr(mr, "cleanup failed, err = %d", cleanup_err); ++ rxe_err_mr(mr, "cleanup failed, err = %d\n", cleanup_err); + + kfree_rcu_mightsleep(mr); + return 0; + + err_out: +- rxe_err_mr(mr, "returned err = %d", err); ++ rxe_err_mr(mr, "returned err = %d\n", err); + return err; + } + +diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c +index 2916e77f589b81..7289ae0b83aced 100644 +--- a/drivers/infiniband/ulp/srp/ib_srp.c ++++ b/drivers/infiniband/ulp/srp/ib_srp.c +@@ -3978,7 +3978,6 @@ static struct srp_host *srp_add_port(struct srp_device *device, u32 port) + return host; + + put_host: +- device_del(&host->dev); + put_device(&host->dev); + return NULL; + } +diff --git a/drivers/irqchip/irq-atmel-aic-common.c b/drivers/irqchip/irq-atmel-aic-common.c +index 072bd227b6c677..4525366d16d615 100644 +--- a/drivers/irqchip/irq-atmel-aic-common.c ++++ b/drivers/irqchip/irq-atmel-aic-common.c +@@ -111,8 +111,6 @@ static void __init aic_common_ext_irq_of_init(struct irq_domain *domain) + struct device_node *node = irq_domain_get_of_node(domain); + struct irq_chip_generic *gc; + struct aic_chip_data *aic; +- struct property *prop; +- const __be32 *p; + u32 hwirq; + + gc = irq_get_domain_generic_chip(domain, 0); +@@ -120,7 +118,7 @@ static void __init aic_common_ext_irq_of_init(struct irq_domain *domain) + aic = gc->private; + aic->ext_irqs |= 1; + +- of_property_for_each_u32(node, "atmel,external-irqs", prop, p, hwirq) { ++ of_property_for_each_u32(node, "atmel,external-irqs", hwirq) { + gc = irq_get_domain_generic_chip(domain, hwirq); + if (!gc) { + pr_warn("AIC: external irq %d >= %d skip it\n", +diff --git a/drivers/irqchip/irq-pic32-evic.c b/drivers/irqchip/irq-pic32-evic.c +index 1d9bb28d13e5d9..5d6b8e025bb876 100644 +--- a/drivers/irqchip/irq-pic32-evic.c ++++ b/drivers/irqchip/irq-pic32-evic.c +@@ -190,13 +190,11 @@ static void __init pic32_ext_irq_of_init(struct irq_domain *domain) + { + struct device_node *node = irq_domain_get_of_node(domain); + struct evic_chip_data *priv = domain->host_data; +- struct property *prop; +- const __le32 *p; + u32 hwirq; + int i = 0; + const char *pname = "microchip,external-irqs"; + +- of_property_for_each_u32(node, pname, prop, p, hwirq) { ++ of_property_for_each_u32(node, pname, hwirq) { + if (i >= ARRAY_SIZE(priv->ext_irqs)) { + pr_warn("More than %d external irq, skip rest\n", + ARRAY_SIZE(priv->ext_irqs)); +diff --git a/drivers/leds/leds-cht-wcove.c b/drivers/leds/leds-cht-wcove.c +index b4998402b8c6f0..711ac4bd60580d 100644 +--- a/drivers/leds/leds-cht-wcove.c ++++ b/drivers/leds/leds-cht-wcove.c +@@ -394,7 +394,7 @@ static int cht_wc_leds_probe(struct platform_device *pdev) + led->cdev.pattern_clear = cht_wc_leds_pattern_clear; + led->cdev.max_brightness = 255; + +- ret = led_classdev_register(&pdev->dev, &led->cdev); ++ ret = devm_led_classdev_register(&pdev->dev, &led->cdev); + if (ret < 0) + return ret; + } +@@ -406,10 +406,6 @@ static int cht_wc_leds_probe(struct platform_device *pdev) + static void cht_wc_leds_remove(struct platform_device *pdev) + { + struct cht_wc_leds *leds = platform_get_drvdata(pdev); +- int i; +- +- for (i = 0; i < CHT_WC_LED_COUNT; i++) +- led_classdev_unregister(&leds->leds[i].cdev); + + /* Restore LED1 regs if hw-control was active else leave LED1 off */ + if (!(leds->led1_initial_regs.ctrl & CHT_WC_LED1_SWCTL)) +diff --git a/drivers/leds/leds-netxbig.c b/drivers/leds/leds-netxbig.c +index 77213b79f84d95..6692de0af68f1c 100644 +--- a/drivers/leds/leds-netxbig.c ++++ b/drivers/leds/leds-netxbig.c +@@ -440,6 +440,7 @@ static int netxbig_leds_get_of_pdata(struct device *dev, + } + gpio_ext_pdev = of_find_device_by_node(gpio_ext_np); + if (!gpio_ext_pdev) { ++ of_node_put(gpio_ext_np); + dev_err(dev, "Failed to find platform device for gpio-ext\n"); + return -ENODEV; + } +diff --git a/drivers/media/i2c/imx290.c b/drivers/media/i2c/imx290.c +index 6dacd38ae947a1..f8ada6c1ef65bf 100644 +--- a/drivers/media/i2c/imx290.c ++++ b/drivers/media/i2c/imx290.c +@@ -269,7 +269,6 @@ static const struct cci_reg_sequence imx290_global_init_settings[] = { + { IMX290_WINWV, 1097 }, + { IMX290_XSOUTSEL, IMX290_XSOUTSEL_XVSOUTSEL_VSYNC | + IMX290_XSOUTSEL_XHSOUTSEL_HSYNC }, +- { CCI_REG8(0x3011), 0x02 }, + { CCI_REG8(0x3012), 0x64 }, + { CCI_REG8(0x3013), 0x00 }, + }; +@@ -277,6 +276,7 @@ static const struct cci_reg_sequence imx290_global_init_settings[] = { + static const struct cci_reg_sequence imx290_global_init_settings_290[] = { + { CCI_REG8(0x300f), 0x00 }, + { CCI_REG8(0x3010), 0x21 }, ++ { CCI_REG8(0x3011), 0x00 }, + { CCI_REG8(0x3016), 0x09 }, + { CCI_REG8(0x3070), 0x02 }, + { CCI_REG8(0x3071), 0x11 }, +@@ -330,6 +330,7 @@ static const struct cci_reg_sequence xclk_regs[][IMX290_NUM_CLK_REGS] = { + }; + + static const struct cci_reg_sequence imx290_global_init_settings_327[] = { ++ { CCI_REG8(0x3011), 0x02 }, + { CCI_REG8(0x309e), 0x4A }, + { CCI_REG8(0x309f), 0x4A }, + { CCI_REG8(0x313b), 0x61 }, +diff --git a/drivers/media/i2c/imx412.c b/drivers/media/i2c/imx412.c +index 8597f98a8dcf80..90fc8eea171f43 100644 +--- a/drivers/media/i2c/imx412.c ++++ b/drivers/media/i2c/imx412.c +@@ -549,7 +549,7 @@ static int imx412_update_exp_gain(struct imx412 *imx412, u32 exposure, u32 gain) + + lpfr = imx412->vblank + imx412->cur_mode->height; + +- dev_dbg(imx412->dev, "Set exp %u, analog gain %u, lpfr %u", ++ dev_dbg(imx412->dev, "Set exp %u, analog gain %u, lpfr %u\n", + exposure, gain, lpfr); + + ret = imx412_write_reg(imx412, IMX412_REG_HOLD, 1, 1); +@@ -596,7 +596,7 @@ static int imx412_set_ctrl(struct v4l2_ctrl *ctrl) + case V4L2_CID_VBLANK: + imx412->vblank = imx412->vblank_ctrl->val; + +- dev_dbg(imx412->dev, "Received vblank %u, new lpfr %u", ++ dev_dbg(imx412->dev, "Received vblank %u, new lpfr %u\n", + imx412->vblank, + imx412->vblank + imx412->cur_mode->height); + +@@ -615,7 +615,7 @@ static int imx412_set_ctrl(struct v4l2_ctrl *ctrl) + exposure = ctrl->val; + analog_gain = imx412->again_ctrl->val; + +- dev_dbg(imx412->dev, "Received exp %u, analog gain %u", ++ dev_dbg(imx412->dev, "Received exp %u, analog gain %u\n", + exposure, analog_gain); + + ret = imx412_update_exp_gain(imx412, exposure, analog_gain); +@@ -624,7 +624,7 @@ static int imx412_set_ctrl(struct v4l2_ctrl *ctrl) + + break; + default: +- dev_err(imx412->dev, "Invalid control %d", ctrl->id); ++ dev_err(imx412->dev, "Invalid control %d\n", ctrl->id); + ret = -EINVAL; + } + +@@ -805,14 +805,14 @@ static int imx412_start_streaming(struct imx412 *imx412) + ret = imx412_write_regs(imx412, reg_list->regs, + reg_list->num_of_regs); + if (ret) { +- dev_err(imx412->dev, "fail to write initial registers"); ++ dev_err(imx412->dev, "fail to write initial registers\n"); + return ret; + } + + /* Setup handler will write actual exposure and gain */ + ret = __v4l2_ctrl_handler_setup(imx412->sd.ctrl_handler); + if (ret) { +- dev_err(imx412->dev, "fail to setup handler"); ++ dev_err(imx412->dev, "fail to setup handler\n"); + return ret; + } + +@@ -823,7 +823,7 @@ static int imx412_start_streaming(struct imx412 *imx412) + ret = imx412_write_reg(imx412, IMX412_REG_MODE_SELECT, + 1, IMX412_MODE_STREAMING); + if (ret) { +- dev_err(imx412->dev, "fail to start streaming"); ++ dev_err(imx412->dev, "fail to start streaming\n"); + return ret; + } + +@@ -904,7 +904,7 @@ static int imx412_detect(struct imx412 *imx412) + return ret; + + if (val != IMX412_ID) { +- dev_err(imx412->dev, "chip id mismatch: %x!=%x", ++ dev_err(imx412->dev, "chip id mismatch: %x!=%x\n", + IMX412_ID, val); + return -ENXIO; + } +@@ -936,7 +936,7 @@ static int imx412_parse_hw_config(struct imx412 *imx412) + imx412->reset_gpio = devm_gpiod_get_optional(imx412->dev, "reset", + GPIOD_OUT_LOW); + if (IS_ERR(imx412->reset_gpio)) { +- dev_err(imx412->dev, "failed to get reset gpio %ld", ++ dev_err(imx412->dev, "failed to get reset gpio %ld\n", + PTR_ERR(imx412->reset_gpio)); + return PTR_ERR(imx412->reset_gpio); + } +@@ -944,13 +944,13 @@ static int imx412_parse_hw_config(struct imx412 *imx412) + /* Get sensor input clock */ + imx412->inclk = devm_clk_get(imx412->dev, NULL); + if (IS_ERR(imx412->inclk)) { +- dev_err(imx412->dev, "could not get inclk"); ++ dev_err(imx412->dev, "could not get inclk\n"); + return PTR_ERR(imx412->inclk); + } + + rate = clk_get_rate(imx412->inclk); + if (rate != IMX412_INCLK_RATE) { +- dev_err(imx412->dev, "inclk frequency mismatch"); ++ dev_err(imx412->dev, "inclk frequency mismatch\n"); + return -EINVAL; + } + +@@ -975,14 +975,14 @@ static int imx412_parse_hw_config(struct imx412 *imx412) + + if (bus_cfg.bus.mipi_csi2.num_data_lanes != IMX412_NUM_DATA_LANES) { + dev_err(imx412->dev, +- "number of CSI2 data lanes %d is not supported", ++ "number of CSI2 data lanes %d is not supported\n", + bus_cfg.bus.mipi_csi2.num_data_lanes); + ret = -EINVAL; + goto done_endpoint_free; + } + + if (!bus_cfg.nr_of_link_frequencies) { +- dev_err(imx412->dev, "no link frequencies defined"); ++ dev_err(imx412->dev, "no link frequencies defined\n"); + ret = -EINVAL; + goto done_endpoint_free; + } +@@ -1040,7 +1040,7 @@ static int imx412_power_on(struct device *dev) + + ret = clk_prepare_enable(imx412->inclk); + if (ret) { +- dev_err(imx412->dev, "fail to enable inclk"); ++ dev_err(imx412->dev, "fail to enable inclk\n"); + goto error_reset; + } + +@@ -1151,7 +1151,7 @@ static int imx412_init_controls(struct imx412 *imx412) + imx412->hblank_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; + + if (ctrl_hdlr->error) { +- dev_err(imx412->dev, "control init failed: %d", ++ dev_err(imx412->dev, "control init failed: %d\n", + ctrl_hdlr->error); + v4l2_ctrl_handler_free(ctrl_hdlr); + return ctrl_hdlr->error; +@@ -1188,7 +1188,7 @@ static int imx412_probe(struct i2c_client *client) + + ret = imx412_parse_hw_config(imx412); + if (ret) { +- dev_err(imx412->dev, "HW configuration is not supported"); ++ dev_err(imx412->dev, "HW configuration is not supported\n"); + return ret; + } + +@@ -1196,14 +1196,14 @@ static int imx412_probe(struct i2c_client *client) + + ret = imx412_power_on(imx412->dev); + if (ret) { +- dev_err(imx412->dev, "failed to power-on the sensor"); ++ dev_err(imx412->dev, "failed to power-on the sensor\n"); + goto error_mutex_destroy; + } + + /* Check module identity */ + ret = imx412_detect(imx412); + if (ret) { +- dev_err(imx412->dev, "failed to find sensor: %d", ret); ++ dev_err(imx412->dev, "failed to find sensor: %d\n", ret); + goto error_power_off; + } + +@@ -1213,7 +1213,7 @@ static int imx412_probe(struct i2c_client *client) + + ret = imx412_init_controls(imx412); + if (ret) { +- dev_err(imx412->dev, "failed to init controls: %d", ret); ++ dev_err(imx412->dev, "failed to init controls: %d\n", ret); + goto error_power_off; + } + +@@ -1227,14 +1227,14 @@ static int imx412_probe(struct i2c_client *client) + imx412->pad.flags = MEDIA_PAD_FL_SOURCE; + ret = media_entity_pads_init(&imx412->sd.entity, 1, &imx412->pad); + if (ret) { +- dev_err(imx412->dev, "failed to init entity pads: %d", ret); ++ dev_err(imx412->dev, "failed to init entity pads: %d\n", ret); + goto error_handler_free; + } + + ret = v4l2_async_register_subdev_sensor(&imx412->sd); + if (ret < 0) { + dev_err(imx412->dev, +- "failed to register async subdev: %d", ret); ++ "failed to register async subdev: %d\n", ret); + goto error_media_entity; + } + +diff --git a/drivers/media/i2c/ov9282.c b/drivers/media/i2c/ov9282.c +index 068c7449f50ed5..7498f55b3ef2b7 100644 +--- a/drivers/media/i2c/ov9282.c ++++ b/drivers/media/i2c/ov9282.c +@@ -40,7 +40,7 @@ + /* Exposure control */ + #define OV9282_REG_EXPOSURE 0x3500 + #define OV9282_EXPOSURE_MIN 1 +-#define OV9282_EXPOSURE_OFFSET 12 ++#define OV9282_EXPOSURE_OFFSET 25 + #define OV9282_EXPOSURE_STEP 1 + #define OV9282_EXPOSURE_DEFAULT 0x0282 + +diff --git a/drivers/media/platform/marvell/mcam-core.c b/drivers/media/platform/marvell/mcam-core.c +index 66688b4aece5d8..555f560238c9a1 100644 +--- a/drivers/media/platform/marvell/mcam-core.c ++++ b/drivers/media/platform/marvell/mcam-core.c +@@ -935,7 +935,12 @@ static int mclk_enable(struct clk_hw *hw) + ret = pm_runtime_resume_and_get(cam->dev); + if (ret < 0) + return ret; +- clk_enable(cam->clk[0]); ++ ret = clk_enable(cam->clk[0]); ++ if (ret) { ++ pm_runtime_put(cam->dev); ++ return ret; ++ } ++ + mcam_reg_write(cam, REG_CLKCTRL, (mclk_src << 29) | mclk_div); + mcam_ctlr_power_up(cam); + +diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c +index e8dcd44f6e4692..092d83b7e79549 100644 +--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c ++++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c +@@ -2674,11 +2674,12 @@ static void mxc_jpeg_detach_pm_domains(struct mxc_jpeg_dev *jpeg) + int i; + + for (i = 0; i < jpeg->num_domains; i++) { +- if (jpeg->pd_dev[i] && !pm_runtime_suspended(jpeg->pd_dev[i])) ++ if (!IS_ERR_OR_NULL(jpeg->pd_dev[i]) && ++ !pm_runtime_suspended(jpeg->pd_dev[i])) + pm_runtime_force_suspend(jpeg->pd_dev[i]); +- if (jpeg->pd_link[i] && !IS_ERR(jpeg->pd_link[i])) ++ if (!IS_ERR_OR_NULL(jpeg->pd_link[i])) + device_link_del(jpeg->pd_link[i]); +- if (jpeg->pd_dev[i] && !IS_ERR(jpeg->pd_dev[i])) ++ if (!IS_ERR_OR_NULL(jpeg->pd_dev[i])) + dev_pm_domain_detach(jpeg->pd_dev[i], true); + jpeg->pd_dev[i] = NULL; + jpeg->pd_link[i] = NULL; +diff --git a/drivers/media/platform/nxp/imx8-isi/imx8-isi-video.c b/drivers/media/platform/nxp/imx8-isi/imx8-isi-video.c +index 10840c9a0912b1..111be77eca1caf 100644 +--- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-video.c ++++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-video.c +@@ -861,6 +861,7 @@ int mxc_isi_video_buffer_prepare(struct mxc_isi_dev *isi, struct vb2_buffer *vb2 + const struct mxc_isi_format_info *info, + const struct v4l2_pix_format_mplane *pix) + { ++ struct vb2_v4l2_buffer *v4l2_buf = to_vb2_v4l2_buffer(vb2); + unsigned int i; + + for (i = 0; i < info->mem_planes; i++) { +@@ -875,6 +876,8 @@ int mxc_isi_video_buffer_prepare(struct mxc_isi_dev *isi, struct vb2_buffer *vb2 + vb2_set_plane_payload(vb2, i, size); + } + ++ v4l2_buf->field = pix->field; ++ + return 0; + } + +diff --git a/drivers/media/platform/samsung/exynos4-is/mipi-csis.c b/drivers/media/platform/samsung/exynos4-is/mipi-csis.c +index 686ca8753ba22a..87c6fb88ab920f 100644 +--- a/drivers/media/platform/samsung/exynos4-is/mipi-csis.c ++++ b/drivers/media/platform/samsung/exynos4-is/mipi-csis.c +@@ -940,13 +940,19 @@ static int s5pcsis_pm_resume(struct device *dev, bool runtime) + state->supplies); + goto unlock; + } +- clk_enable(state->clock[CSIS_CLK_GATE]); ++ ret = clk_enable(state->clock[CSIS_CLK_GATE]); ++ if (ret) { ++ phy_power_off(state->phy); ++ regulator_bulk_disable(CSIS_NUM_SUPPLIES, ++ state->supplies); ++ goto unlock; ++ } + } + if (state->flags & ST_STREAMING) + s5pcsis_start_stream(state); + + state->flags &= ~ST_SUSPENDED; +- unlock: ++unlock: + mutex_unlock(&state->lock); + return ret ? -EAGAIN : 0; + } +diff --git a/drivers/media/platform/samsung/s3c-camif/camif-core.c b/drivers/media/platform/samsung/s3c-camif/camif-core.c +index e4529f666e2060..8c597dd01713a6 100644 +--- a/drivers/media/platform/samsung/s3c-camif/camif-core.c ++++ b/drivers/media/platform/samsung/s3c-camif/camif-core.c +@@ -527,10 +527,19 @@ static void s3c_camif_remove(struct platform_device *pdev) + static int s3c_camif_runtime_resume(struct device *dev) + { + struct camif_dev *camif = dev_get_drvdata(dev); ++ int ret; ++ ++ ret = clk_enable(camif->clock[CLK_GATE]); ++ if (ret) ++ return ret; + +- clk_enable(camif->clock[CLK_GATE]); + /* null op on s3c244x */ +- clk_enable(camif->clock[CLK_CAM]); ++ ret = clk_enable(camif->clock[CLK_CAM]); ++ if (ret) { ++ clk_disable(camif->clock[CLK_GATE]); ++ return ret; ++ } ++ + return 0; + } + +diff --git a/drivers/media/rc/iguanair.c b/drivers/media/rc/iguanair.c +index 276bf3c8a8cb49..8af94246e5916e 100644 +--- a/drivers/media/rc/iguanair.c ++++ b/drivers/media/rc/iguanair.c +@@ -194,8 +194,10 @@ static int iguanair_send(struct iguanair *ir, unsigned size) + if (rc) + return rc; + +- if (wait_for_completion_timeout(&ir->completion, TIMEOUT) == 0) ++ if (wait_for_completion_timeout(&ir->completion, TIMEOUT) == 0) { ++ usb_kill_urb(ir->urb_out); + return -ETIMEDOUT; ++ } + + return rc; + } +diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c +index 4eb7dd4599b7e6..7caf5e90721a47 100644 +--- a/drivers/media/usb/dvb-usb-v2/af9035.c ++++ b/drivers/media/usb/dvb-usb-v2/af9035.c +@@ -322,13 +322,16 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap, + ret = -EOPNOTSUPP; + } else if ((msg[0].addr == state->af9033_i2c_addr[0]) || + (msg[0].addr == state->af9033_i2c_addr[1])) { ++ /* demod access via firmware interface */ ++ u32 reg; ++ + if (msg[0].len < 3 || msg[1].len < 1) { + ret = -EOPNOTSUPP; + goto unlock; + } +- /* demod access via firmware interface */ +- u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 | +- msg[0].buf[2]; ++ ++ reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 | ++ msg[0].buf[2]; + + if (msg[0].addr == state->af9033_i2c_addr[1]) + reg |= 0x100000; +@@ -385,13 +388,16 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap, + ret = -EOPNOTSUPP; + } else if ((msg[0].addr == state->af9033_i2c_addr[0]) || + (msg[0].addr == state->af9033_i2c_addr[1])) { ++ /* demod access via firmware interface */ ++ u32 reg; ++ + if (msg[0].len < 3) { + ret = -EOPNOTSUPP; + goto unlock; + } +- /* demod access via firmware interface */ +- u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 | +- msg[0].buf[2]; ++ ++ reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 | ++ msg[0].buf[2]; + + if (msg[0].addr == state->af9033_i2c_addr[1]) + reg |= 0x100000; +diff --git a/drivers/media/usb/dvb-usb-v2/lmedm04.c b/drivers/media/usb/dvb-usb-v2/lmedm04.c +index 8a34e6c0d6a6d1..f0537b741d1352 100644 +--- a/drivers/media/usb/dvb-usb-v2/lmedm04.c ++++ b/drivers/media/usb/dvb-usb-v2/lmedm04.c +@@ -373,6 +373,7 @@ static int lme2510_int_read(struct dvb_usb_adapter *adap) + struct dvb_usb_device *d = adap_to_d(adap); + struct lme2510_state *lme_int = adap_to_priv(adap); + struct usb_host_endpoint *ep; ++ int ret; + + lme_int->lme_urb = usb_alloc_urb(0, GFP_KERNEL); + +@@ -390,11 +391,20 @@ static int lme2510_int_read(struct dvb_usb_adapter *adap) + + /* Quirk of pipe reporting PIPE_BULK but behaves as interrupt */ + ep = usb_pipe_endpoint(d->udev, lme_int->lme_urb->pipe); ++ if (!ep) { ++ usb_free_urb(lme_int->lme_urb); ++ return -ENODEV; ++ } + + if (usb_endpoint_type(&ep->desc) == USB_ENDPOINT_XFER_BULK) + lme_int->lme_urb->pipe = usb_rcvbulkpipe(d->udev, 0xa); + +- usb_submit_urb(lme_int->lme_urb, GFP_KERNEL); ++ ret = usb_submit_urb(lme_int->lme_urb, GFP_KERNEL); ++ if (ret) { ++ usb_free_urb(lme_int->lme_urb); ++ return ret; ++ } ++ + info("INT Interrupt Service Started"); + + return 0; +diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c +index 16fa17bbd15eaa..83ed7821fa2a77 100644 +--- a/drivers/media/usb/uvc/uvc_queue.c ++++ b/drivers/media/usb/uvc/uvc_queue.c +@@ -483,7 +483,8 @@ static void uvc_queue_buffer_complete(struct kref *ref) + + buf->state = buf->error ? UVC_BUF_STATE_ERROR : UVC_BUF_STATE_DONE; + vb2_set_plane_payload(&buf->buf.vb2_buf, 0, buf->bytesused); +- vb2_buffer_done(&buf->buf.vb2_buf, VB2_BUF_STATE_DONE); ++ vb2_buffer_done(&buf->buf.vb2_buf, buf->error ? VB2_BUF_STATE_ERROR : ++ VB2_BUF_STATE_DONE); + } + + /* +diff --git a/drivers/media/usb/uvc/uvc_status.c b/drivers/media/usb/uvc/uvc_status.c +index a78a88c710e24a..b5f6682ff38311 100644 +--- a/drivers/media/usb/uvc/uvc_status.c ++++ b/drivers/media/usb/uvc/uvc_status.c +@@ -269,6 +269,7 @@ int uvc_status_init(struct uvc_device *dev) + dev->int_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!dev->int_urb) { + kfree(dev->status); ++ dev->status = NULL; + return -ENOMEM; + } + +diff --git a/drivers/memory/tegra/tegra20-emc.c b/drivers/memory/tegra/tegra20-emc.c +index fd595c851a2786..eb2813b51d770b 100644 +--- a/drivers/memory/tegra/tegra20-emc.c ++++ b/drivers/memory/tegra/tegra20-emc.c +@@ -477,14 +477,15 @@ tegra_emc_find_node_by_ram_code(struct tegra_emc *emc) + + ram_code = tegra_read_ram_code(); + +- for (np = of_find_node_by_name(dev->of_node, "emc-tables"); np; +- np = of_find_node_by_name(np, "emc-tables")) { ++ for_each_child_of_node(dev->of_node, np) { ++ if (!of_node_name_eq(np, "emc-tables")) ++ continue; + err = of_property_read_u32(np, "nvidia,ram-code", &value); + if (err || value != ram_code) { + struct device_node *lpddr2_np; + bool cfg_mismatches = false; + +- lpddr2_np = of_find_node_by_name(np, "lpddr2"); ++ lpddr2_np = of_get_child_by_name(np, "lpddr2"); + if (lpddr2_np) { + const struct lpddr2_info *info; + +@@ -521,7 +522,6 @@ tegra_emc_find_node_by_ram_code(struct tegra_emc *emc) + } + + if (cfg_mismatches) { +- of_node_put(np); + continue; + } + } +diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c +index 7d0e91164cbaa3..729e79e1be49fa 100644 +--- a/drivers/mfd/syscon.c ++++ b/drivers/mfd/syscon.c +@@ -8,12 +8,14 @@ + * Author: Dong Aisheng + */ + ++#include + #include + #include + #include + #include + #include + #include ++#include + #include + #include + #include +@@ -26,7 +28,7 @@ + + static struct platform_driver syscon_driver; + +-static DEFINE_SPINLOCK(syscon_list_slock); ++static DEFINE_MUTEX(syscon_list_lock); + static LIST_HEAD(syscon_list); + + struct syscon { +@@ -45,7 +47,6 @@ static const struct regmap_config syscon_regmap_config = { + static struct syscon *of_syscon_register(struct device_node *np, bool check_res) + { + struct clk *clk; +- struct syscon *syscon; + struct regmap *regmap; + void __iomem *base; + u32 reg_io_width; +@@ -54,20 +55,18 @@ static struct syscon *of_syscon_register(struct device_node *np, bool check_res) + struct resource res; + struct reset_control *reset; + +- syscon = kzalloc(sizeof(*syscon), GFP_KERNEL); ++ WARN_ON(!mutex_is_locked(&syscon_list_lock)); ++ ++ struct syscon *syscon __free(kfree) = kzalloc(sizeof(*syscon), GFP_KERNEL); + if (!syscon) + return ERR_PTR(-ENOMEM); + +- if (of_address_to_resource(np, 0, &res)) { +- ret = -ENOMEM; +- goto err_map; +- } ++ if (of_address_to_resource(np, 0, &res)) ++ return ERR_PTR(-ENOMEM); + + base = of_iomap(np, 0); +- if (!base) { +- ret = -ENOMEM; +- goto err_map; +- } ++ if (!base) ++ return ERR_PTR(-ENOMEM); + + /* Parse the device's DT node for an endianness specification */ + if (of_property_read_bool(np, "big-endian")) +@@ -148,11 +147,9 @@ static struct syscon *of_syscon_register(struct device_node *np, bool check_res) + syscon->regmap = regmap; + syscon->np = np; + +- spin_lock(&syscon_list_slock); + list_add_tail(&syscon->list, &syscon_list); +- spin_unlock(&syscon_list_slock); + +- return syscon; ++ return_ptr(syscon); + + err_reset: + reset_control_put(reset); +@@ -163,8 +160,6 @@ static struct syscon *of_syscon_register(struct device_node *np, bool check_res) + regmap_exit(regmap); + err_regmap: + iounmap(base); +-err_map: +- kfree(syscon); + return ERR_PTR(ret); + } + +@@ -173,7 +168,7 @@ static struct regmap *device_node_get_regmap(struct device_node *np, + { + struct syscon *entry, *syscon = NULL; + +- spin_lock(&syscon_list_slock); ++ mutex_lock(&syscon_list_lock); + + list_for_each_entry(entry, &syscon_list, list) + if (entry->np == np) { +@@ -181,17 +176,65 @@ static struct regmap *device_node_get_regmap(struct device_node *np, + break; + } + +- spin_unlock(&syscon_list_slock); +- + if (!syscon) + syscon = of_syscon_register(np, check_res); + ++ mutex_unlock(&syscon_list_lock); ++ + if (IS_ERR(syscon)) + return ERR_CAST(syscon); + + return syscon->regmap; + } + ++/** ++ * of_syscon_register_regmap() - Register regmap for specified device node ++ * @np: Device tree node ++ * @regmap: Pointer to regmap object ++ * ++ * Register an externally created regmap object with syscon for the specified ++ * device tree node. This regmap will then be returned to client drivers using ++ * the syscon_regmap_lookup_by_phandle() API. ++ * ++ * Return: 0 on success, negative error code on failure. ++ */ ++int of_syscon_register_regmap(struct device_node *np, struct regmap *regmap) ++{ ++ struct syscon *entry, *syscon = NULL; ++ int ret; ++ ++ if (!np || !regmap) ++ return -EINVAL; ++ ++ syscon = kzalloc(sizeof(*syscon), GFP_KERNEL); ++ if (!syscon) ++ return -ENOMEM; ++ ++ /* check if syscon entry already exists */ ++ mutex_lock(&syscon_list_lock); ++ ++ list_for_each_entry(entry, &syscon_list, list) ++ if (entry->np == np) { ++ ret = -EEXIST; ++ goto err_unlock; ++ } ++ ++ syscon->regmap = regmap; ++ syscon->np = np; ++ ++ /* register the regmap in syscon list */ ++ list_add_tail(&syscon->list, &syscon_list); ++ mutex_unlock(&syscon_list_lock); ++ ++ return 0; ++ ++err_unlock: ++ mutex_unlock(&syscon_list_lock); ++ kfree(syscon); ++ return ret; ++} ++EXPORT_SYMBOL_GPL(of_syscon_register_regmap); ++ + struct regmap *device_node_to_regmap(struct device_node *np) + { + return device_node_get_regmap(np, false); +diff --git a/drivers/mfd/ti_am335x_tscadc.c b/drivers/mfd/ti_am335x_tscadc.c +index b88eb70c17b353..936a9f6c16f0e4 100644 +--- a/drivers/mfd/ti_am335x_tscadc.c ++++ b/drivers/mfd/ti_am335x_tscadc.c +@@ -119,8 +119,6 @@ static int ti_tscadc_probe(struct platform_device *pdev) + struct clk *clk; + struct device_node *node; + struct mfd_cell *cell; +- struct property *prop; +- const __be32 *cur; + bool use_tsc = false, use_mag = false; + u32 val; + int err; +@@ -167,7 +165,7 @@ static int ti_tscadc_probe(struct platform_device *pdev) + } + + node = of_get_child_by_name(pdev->dev.of_node, "adc"); +- of_property_for_each_u32(node, "ti,adc-channels", prop, cur, val) { ++ of_property_for_each_u32(node, "ti,adc-channels", val) { + adc_channels++; + if (val > 7) { + dev_err(&pdev->dev, " PIN numbers are 0..7 (not %d)\n", +diff --git a/drivers/misc/cardreader/rtsx_usb.c b/drivers/misc/cardreader/rtsx_usb.c +index f150d8769f1986..285a748748d701 100644 +--- a/drivers/misc/cardreader/rtsx_usb.c ++++ b/drivers/misc/cardreader/rtsx_usb.c +@@ -286,6 +286,7 @@ static int rtsx_usb_get_status_with_bulk(struct rtsx_ucr *ucr, u16 *status) + int rtsx_usb_get_card_status(struct rtsx_ucr *ucr, u16 *status) + { + int ret; ++ u8 interrupt_val = 0; + u16 *buf; + + if (!status) +@@ -308,6 +309,20 @@ int rtsx_usb_get_card_status(struct rtsx_ucr *ucr, u16 *status) + ret = rtsx_usb_get_status_with_bulk(ucr, status); + } + ++ rtsx_usb_read_register(ucr, CARD_INT_PEND, &interrupt_val); ++ /* Cross check presence with interrupts */ ++ if (*status & XD_CD) ++ if (!(interrupt_val & XD_INT)) ++ *status &= ~XD_CD; ++ ++ if (*status & SD_CD) ++ if (!(interrupt_val & SD_INT)) ++ *status &= ~SD_CD; ++ ++ if (*status & MS_CD) ++ if (!(interrupt_val & MS_INT)) ++ *status &= ~MS_CD; ++ + /* usb_control_msg may return positive when success */ + if (ret < 0) + return ret; +diff --git a/drivers/mtd/hyperbus/hbmc-am654.c b/drivers/mtd/hyperbus/hbmc-am654.c +index a6161ce340d4eb..4b6cbee23fe893 100644 +--- a/drivers/mtd/hyperbus/hbmc-am654.c ++++ b/drivers/mtd/hyperbus/hbmc-am654.c +@@ -174,26 +174,30 @@ static int am654_hbmc_probe(struct platform_device *pdev) + priv->hbdev.np = of_get_next_child(np, NULL); + ret = of_address_to_resource(priv->hbdev.np, 0, &res); + if (ret) +- return ret; ++ goto put_node; + + if (of_property_read_bool(dev->of_node, "mux-controls")) { + struct mux_control *control = devm_mux_control_get(dev, NULL); + +- if (IS_ERR(control)) +- return PTR_ERR(control); ++ if (IS_ERR(control)) { ++ ret = PTR_ERR(control); ++ goto put_node; ++ } + + ret = mux_control_select(control, 1); + if (ret) { + dev_err(dev, "Failed to select HBMC mux\n"); +- return ret; ++ goto put_node; + } + priv->mux_ctrl = control; + } + + priv->hbdev.map.size = resource_size(&res); + priv->hbdev.map.virt = devm_ioremap_resource(dev, &res); +- if (IS_ERR(priv->hbdev.map.virt)) +- return PTR_ERR(priv->hbdev.map.virt); ++ if (IS_ERR(priv->hbdev.map.virt)) { ++ ret = PTR_ERR(priv->hbdev.map.virt); ++ goto disable_mux; ++ } + + priv->ctlr.dev = dev; + priv->ctlr.ops = &am654_hbmc_ops; +@@ -226,10 +230,12 @@ static int am654_hbmc_probe(struct platform_device *pdev) + disable_mux: + if (priv->mux_ctrl) + mux_control_deselect(priv->mux_ctrl); ++put_node: ++ of_node_put(priv->hbdev.np); + return ret; + } + +-static int am654_hbmc_remove(struct platform_device *pdev) ++static void am654_hbmc_remove(struct platform_device *pdev) + { + struct am654_hbmc_priv *priv = platform_get_drvdata(pdev); + struct am654_hbmc_device_priv *dev_priv = priv->hbdev.priv; +@@ -241,8 +247,7 @@ static int am654_hbmc_remove(struct platform_device *pdev) + + if (dev_priv->rx_chan) + dma_release_channel(dev_priv->rx_chan); +- +- return 0; ++ of_node_put(priv->hbdev.np); + } + + static const struct of_device_id am654_hbmc_dt_ids[] = { +@@ -256,7 +261,7 @@ MODULE_DEVICE_TABLE(of, am654_hbmc_dt_ids); + + static struct platform_driver am654_hbmc_platform_driver = { + .probe = am654_hbmc_probe, +- .remove = am654_hbmc_remove, ++ .remove_new = am654_hbmc_remove, + .driver = { + .name = "hbmc-am654", + .of_match_table = am654_hbmc_dt_ids, +diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c +index 440bef477930c2..085a16148a68d4 100644 +--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c ++++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c +@@ -2450,6 +2450,11 @@ static int brcmnand_write(struct mtd_info *mtd, struct nand_chip *chip, + brcmnand_send_cmd(host, CMD_PROGRAM_PAGE); + status = brcmnand_waitfunc(chip); + ++ if (status < 0) { ++ ret = status; ++ goto out; ++ } ++ + if (status & NAND_STATUS_FAIL) { + dev_info(ctrl->dev, "program failed at %llx\n", + (unsigned long long)addr); +diff --git a/drivers/net/ethernet/broadcom/bgmac.h b/drivers/net/ethernet/broadcom/bgmac.h +index d73ef262991d61..6fee9a41839c0b 100644 +--- a/drivers/net/ethernet/broadcom/bgmac.h ++++ b/drivers/net/ethernet/broadcom/bgmac.h +@@ -328,8 +328,7 @@ + #define BGMAC_RX_FRAME_OFFSET 30 /* There are 2 unused bytes between header and real data */ + #define BGMAC_RX_BUF_OFFSET (NET_SKB_PAD + NET_IP_ALIGN - \ + BGMAC_RX_FRAME_OFFSET) +-/* Jumbo frame size with FCS */ +-#define BGMAC_RX_MAX_FRAME_SIZE 9724 ++#define BGMAC_RX_MAX_FRAME_SIZE 1536 + #define BGMAC_RX_BUF_SIZE (BGMAC_RX_FRAME_OFFSET + BGMAC_RX_MAX_FRAME_SIZE) + #define BGMAC_RX_ALLOC_SIZE (SKB_DATA_ALIGN(BGMAC_RX_BUF_SIZE + BGMAC_RX_BUF_OFFSET) + \ + SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) +diff --git a/drivers/net/ethernet/davicom/dm9000.c b/drivers/net/ethernet/davicom/dm9000.c +index 05a89ab6766c41..bd38f2f57c8abc 100644 +--- a/drivers/net/ethernet/davicom/dm9000.c ++++ b/drivers/net/ethernet/davicom/dm9000.c +@@ -1778,10 +1778,11 @@ dm9000_drv_remove(struct platform_device *pdev) + + unregister_netdev(ndev); + dm9000_release_board(pdev, dm); +- free_netdev(ndev); /* free device structure */ + if (dm->power_supply) + regulator_disable(dm->power_supply); + ++ free_netdev(ndev); /* free device structure */ ++ + dev_dbg(&pdev->dev, "released and freed device\n"); + return 0; + } +diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c +index 8f5cc1f2331884..2d6b50903c923d 100644 +--- a/drivers/net/ethernet/freescale/fec_main.c ++++ b/drivers/net/ethernet/freescale/fec_main.c +@@ -821,6 +821,8 @@ static int fec_enet_txq_submit_tso(struct fec_enet_priv_tx_q *txq, + struct fec_enet_private *fep = netdev_priv(ndev); + int hdr_len, total_len, data_left; + struct bufdesc *bdp = txq->bd.cur; ++ struct bufdesc *tmp_bdp; ++ struct bufdesc_ex *ebdp; + struct tso_t tso; + unsigned int index = 0; + int ret; +@@ -894,7 +896,34 @@ static int fec_enet_txq_submit_tso(struct fec_enet_priv_tx_q *txq, + return 0; + + err_release: +- /* TODO: Release all used data descriptors for TSO */ ++ /* Release all used data descriptors for TSO */ ++ tmp_bdp = txq->bd.cur; ++ ++ while (tmp_bdp != bdp) { ++ /* Unmap data buffers */ ++ if (tmp_bdp->cbd_bufaddr && ++ !IS_TSO_HEADER(txq, fec32_to_cpu(tmp_bdp->cbd_bufaddr))) ++ dma_unmap_single(&fep->pdev->dev, ++ fec32_to_cpu(tmp_bdp->cbd_bufaddr), ++ fec16_to_cpu(tmp_bdp->cbd_datlen), ++ DMA_TO_DEVICE); ++ ++ /* Clear standard buffer descriptor fields */ ++ tmp_bdp->cbd_sc = 0; ++ tmp_bdp->cbd_datlen = 0; ++ tmp_bdp->cbd_bufaddr = 0; ++ ++ /* Handle extended descriptor if enabled */ ++ if (fep->bufdesc_ex) { ++ ebdp = (struct bufdesc_ex *)tmp_bdp; ++ ebdp->cbd_esc = 0; ++ } ++ ++ tmp_bdp = fec_enet_get_nextdesc(tmp_bdp, &txq->bd); ++ } ++ ++ dev_kfree_skb_any(skb); ++ + return ret; + } + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.c b/drivers/net/ethernet/hisilicon/hns3/hnae3.c +index 9a63fbc6940831..b25fb400f4767e 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.c +@@ -40,6 +40,21 @@ EXPORT_SYMBOL(hnae3_unregister_ae_algo_prepare); + */ + static DEFINE_MUTEX(hnae3_common_lock); + ++/* ensure the drivers being unloaded one by one */ ++static DEFINE_MUTEX(hnae3_unload_lock); ++ ++void hnae3_acquire_unload_lock(void) ++{ ++ mutex_lock(&hnae3_unload_lock); ++} ++EXPORT_SYMBOL(hnae3_acquire_unload_lock); ++ ++void hnae3_release_unload_lock(void) ++{ ++ mutex_unlock(&hnae3_unload_lock); ++} ++EXPORT_SYMBOL(hnae3_release_unload_lock); ++ + static bool hnae3_client_match(enum hnae3_client_type client_type) + { + if (client_type == HNAE3_CLIENT_KNIC || +diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h +index 57787c380fa07f..7eb22b8ea3e707 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h ++++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h +@@ -946,4 +946,6 @@ int hnae3_register_client(struct hnae3_client *client); + void hnae3_set_client_init_flag(struct hnae3_client *client, + struct hnae3_ae_dev *ae_dev, + unsigned int inited); ++void hnae3_acquire_unload_lock(void); ++void hnae3_release_unload_lock(void); + #endif +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +index 14d086b535a2dc..801801e8803e9f 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +@@ -6008,9 +6008,11 @@ module_init(hns3_init_module); + */ + static void __exit hns3_exit_module(void) + { ++ hnae3_acquire_unload_lock(); + pci_unregister_driver(&hns3_driver); + hnae3_unregister_client(&client); + hns3_dbg_unregister_debugfs(); ++ hnae3_release_unload_lock(); + } + module_exit(hns3_exit_module); + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +index 9650ce594e2fdd..4d318af748a0b7 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +@@ -12814,9 +12814,11 @@ static int __init hclge_init(void) + + static void __exit hclge_exit(void) + { ++ hnae3_acquire_unload_lock(); + hnae3_unregister_ae_algo_prepare(&ae_algo); + hnae3_unregister_ae_algo(&ae_algo); + destroy_workqueue(hclge_wq); ++ hnae3_release_unload_lock(); + } + module_init(hclge_init); + module_exit(hclge_exit); +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +index affdd9d70549ac..69bfcfb148def4 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +@@ -3345,8 +3345,10 @@ static int __init hclgevf_init(void) + + static void __exit hclgevf_exit(void) + { ++ hnae3_acquire_unload_lock(); + hnae3_unregister_ae_algo(&ae_algovf); + destroy_workqueue(hclgevf_wq); ++ hnae3_release_unload_lock(); + } + module_init(hclgevf_init); + module_exit(hclgevf_exit); +diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c +index ce0b9199952649..fde8d7b80ca662 100644 +--- a/drivers/net/ethernet/intel/iavf/iavf_main.c ++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c +@@ -801,6 +801,11 @@ iavf_vlan_filter *iavf_add_vlan(struct iavf_adapter *adapter, + f->state = IAVF_VLAN_ADD; + adapter->num_vlan_filters++; + iavf_schedule_aq_request(adapter, IAVF_FLAG_AQ_ADD_VLAN_FILTER); ++ } else if (f->state == IAVF_VLAN_REMOVE) { ++ /* IAVF_VLAN_REMOVE means that VLAN wasn't yet removed. ++ * We can safely only change the state here. ++ */ ++ f->state = IAVF_VLAN_ACTIVE; + } + + clearout: +@@ -821,8 +826,18 @@ static void iavf_del_vlan(struct iavf_adapter *adapter, struct iavf_vlan vlan) + + f = iavf_find_vlan(adapter, vlan); + if (f) { +- f->state = IAVF_VLAN_REMOVE; +- iavf_schedule_aq_request(adapter, IAVF_FLAG_AQ_DEL_VLAN_FILTER); ++ /* IAVF_ADD_VLAN means that VLAN wasn't even added yet. ++ * Remove it from the list. ++ */ ++ if (f->state == IAVF_VLAN_ADD) { ++ list_del(&f->list); ++ kfree(f); ++ adapter->num_vlan_filters--; ++ } else { ++ f->state = IAVF_VLAN_REMOVE; ++ iavf_schedule_aq_request(adapter, ++ IAVF_FLAG_AQ_DEL_VLAN_FILTER); ++ } + } + + spin_unlock_bh(&adapter->mac_vlan_list_lock); +diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c +index 2ee1374db4c06e..6f1fe7e283d4eb 100644 +--- a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c ++++ b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c +@@ -761,12 +761,6 @@ static void octep_get_stats64(struct net_device *netdev, + struct octep_device *oct = netdev_priv(netdev); + int q; + +- if (netif_running(netdev)) +- octep_ctrl_net_get_if_stats(oct, +- OCTEP_CTRL_NET_INVALID_VFID, +- &oct->iface_rx_stats, +- &oct->iface_tx_stats); +- + tx_packets = 0; + tx_bytes = 0; + rx_packets = 0; +@@ -784,10 +778,6 @@ static void octep_get_stats64(struct net_device *netdev, + stats->tx_bytes = tx_bytes; + stats->rx_packets = rx_packets; + stats->rx_bytes = rx_bytes; +- stats->multicast = oct->iface_rx_stats.mcast_pkts; +- stats->rx_errors = oct->iface_rx_stats.err_pkts; +- stats->collisions = oct->iface_tx_stats.xscol; +- stats->tx_fifo_errors = oct->iface_tx_stats.undflw; + } + + /** +diff --git a/drivers/net/ethernet/mellanox/mlxfw/mlxfw_fsm.c b/drivers/net/ethernet/mellanox/mlxfw/mlxfw_fsm.c +index 46245e0b24623d..43c84900369a36 100644 +--- a/drivers/net/ethernet/mellanox/mlxfw/mlxfw_fsm.c ++++ b/drivers/net/ethernet/mellanox/mlxfw/mlxfw_fsm.c +@@ -14,7 +14,6 @@ + #define MLXFW_FSM_STATE_WAIT_TIMEOUT_MS 30000 + #define MLXFW_FSM_STATE_WAIT_ROUNDS \ + (MLXFW_FSM_STATE_WAIT_TIMEOUT_MS / MLXFW_FSM_STATE_WAIT_CYCLE_MS) +-#define MLXFW_FSM_MAX_COMPONENT_SIZE (10 * (1 << 20)) + + static const int mlxfw_fsm_state_errno[] = { + [MLXFW_FSM_STATE_ERR_ERROR] = -EIO, +@@ -229,7 +228,6 @@ static int mlxfw_flash_component(struct mlxfw_dev *mlxfw_dev, + return err; + } + +- comp_max_size = min_t(u32, comp_max_size, MLXFW_FSM_MAX_COMPONENT_SIZE); + if (comp->data_size > comp_max_size) { + MLXFW_ERR_MSG(mlxfw_dev, extack, + "Component size is bigger than limit", -EINVAL); +diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c +index 69cd689dbc83e9..5afe6b155ef0d5 100644 +--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c +@@ -1003,10 +1003,10 @@ static void mlxsw_sp_mr_route_stats_update(struct mlxsw_sp *mlxsw_sp, + mr->mr_ops->route_stats(mlxsw_sp, mr_route->route_priv, &packets, + &bytes); + +- if (mr_route->mfc->mfc_un.res.pkt != packets) +- mr_route->mfc->mfc_un.res.lastuse = jiffies; +- mr_route->mfc->mfc_un.res.pkt = packets; +- mr_route->mfc->mfc_un.res.bytes = bytes; ++ if (atomic_long_read(&mr_route->mfc->mfc_un.res.pkt) != packets) ++ WRITE_ONCE(mr_route->mfc->mfc_un.res.lastuse, jiffies); ++ atomic_long_set(&mr_route->mfc->mfc_un.res.pkt, packets); ++ atomic_long_set(&mr_route->mfc->mfc_un.res.bytes, bytes); + } + + static void mlxsw_sp_mr_stats_update(struct work_struct *work) +diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c +index 274ea16c0a1f71..0c0fd68ded423d 100644 +--- a/drivers/net/ethernet/renesas/sh_eth.c ++++ b/drivers/net/ethernet/renesas/sh_eth.c +@@ -3496,10 +3496,12 @@ static int sh_eth_suspend(struct device *dev) + + netif_device_detach(ndev); + ++ rtnl_lock(); + if (mdp->wol_enabled) + ret = sh_eth_wol_setup(ndev); + else + ret = sh_eth_close(ndev); ++ rtnl_unlock(); + + return ret; + } +@@ -3513,10 +3515,12 @@ static int sh_eth_resume(struct device *dev) + if (!netif_running(ndev)) + return 0; + ++ rtnl_lock(); + if (mdp->wol_enabled) + ret = sh_eth_wol_restore(ndev); + else + ret = sh_eth_open(ndev); ++ rtnl_unlock(); + + if (ret < 0) + return ret; +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index d6ee90fef2eca4..d3d5c01f6dcbaa 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -7103,6 +7103,36 @@ static int stmmac_hw_init(struct stmmac_priv *priv) + if (priv->dma_cap.tsoen) + dev_info(priv->device, "TSO supported\n"); + ++ if (priv->dma_cap.number_rx_queues && ++ priv->plat->rx_queues_to_use > priv->dma_cap.number_rx_queues) { ++ dev_warn(priv->device, ++ "Number of Rx queues (%u) exceeds dma capability\n", ++ priv->plat->rx_queues_to_use); ++ priv->plat->rx_queues_to_use = priv->dma_cap.number_rx_queues; ++ } ++ if (priv->dma_cap.number_tx_queues && ++ priv->plat->tx_queues_to_use > priv->dma_cap.number_tx_queues) { ++ dev_warn(priv->device, ++ "Number of Tx queues (%u) exceeds dma capability\n", ++ priv->plat->tx_queues_to_use); ++ priv->plat->tx_queues_to_use = priv->dma_cap.number_tx_queues; ++ } ++ ++ if (priv->dma_cap.rx_fifo_size && ++ priv->plat->rx_fifo_size > priv->dma_cap.rx_fifo_size) { ++ dev_warn(priv->device, ++ "Rx FIFO size (%u) exceeds dma capability\n", ++ priv->plat->rx_fifo_size); ++ priv->plat->rx_fifo_size = priv->dma_cap.rx_fifo_size; ++ } ++ if (priv->dma_cap.tx_fifo_size && ++ priv->plat->tx_fifo_size > priv->dma_cap.tx_fifo_size) { ++ dev_warn(priv->device, ++ "Tx FIFO size (%u) exceeds dma capability\n", ++ priv->plat->tx_fifo_size); ++ priv->plat->tx_fifo_size = priv->dma_cap.tx_fifo_size; ++ } ++ + priv->hw->vlan_fail_q_en = + (priv->plat->flags & STMMAC_FLAG_VLAN_FAIL_Q_EN); + priv->hw->vlan_fail_q = priv->plat->vlan_fail_q; +diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c +index d556e705ec000d..8ffc1fbb036f9f 100644 +--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c ++++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c +@@ -1651,7 +1651,7 @@ void am65_cpsw_nuss_remove_tx_chns(struct am65_cpsw_common *common) + for (i = 0; i < common->tx_ch_num; i++) { + struct am65_cpsw_tx_chn *tx_chn = &common->tx_chns[i]; + +- if (tx_chn->irq) ++ if (tx_chn->irq > 0) + devm_free_irq(dev, tx_chn->irq, tx_chn); + + netif_napi_del(&tx_chn->napi_tx); +diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h +index 028c825b86db1e..dfc6e00b718e31 100644 +--- a/drivers/net/netdevsim/netdevsim.h ++++ b/drivers/net/netdevsim/netdevsim.h +@@ -121,6 +121,7 @@ struct netdevsim { + u32 sleep; + u32 __ports[2][NSIM_UDP_TUNNEL_N_PORTS]; + u32 (*ports)[NSIM_UDP_TUNNEL_N_PORTS]; ++ struct dentry *ddir; + struct debugfs_u32_array dfs_ports[2]; + } udp_ports; + +diff --git a/drivers/net/netdevsim/udp_tunnels.c b/drivers/net/netdevsim/udp_tunnels.c +index 02dc3123eb6c16..640b4983a9a0d1 100644 +--- a/drivers/net/netdevsim/udp_tunnels.c ++++ b/drivers/net/netdevsim/udp_tunnels.c +@@ -112,9 +112,11 @@ nsim_udp_tunnels_info_reset_write(struct file *file, const char __user *data, + struct net_device *dev = file->private_data; + struct netdevsim *ns = netdev_priv(dev); + +- memset(ns->udp_ports.ports, 0, sizeof(ns->udp_ports.__ports)); + rtnl_lock(); +- udp_tunnel_nic_reset_ntf(dev); ++ if (dev->reg_state == NETREG_REGISTERED) { ++ memset(ns->udp_ports.ports, 0, sizeof(ns->udp_ports.__ports)); ++ udp_tunnel_nic_reset_ntf(dev); ++ } + rtnl_unlock(); + + return count; +@@ -144,23 +146,23 @@ int nsim_udp_tunnels_info_create(struct nsim_dev *nsim_dev, + else + ns->udp_ports.ports = nsim_dev->udp_ports.__ports; + +- debugfs_create_u32("udp_ports_inject_error", 0600, +- ns->nsim_dev_port->ddir, ++ ns->udp_ports.ddir = debugfs_create_dir("udp_ports", ++ ns->nsim_dev_port->ddir); ++ ++ debugfs_create_u32("inject_error", 0600, ns->udp_ports.ddir, + &ns->udp_ports.inject_error); + + ns->udp_ports.dfs_ports[0].array = ns->udp_ports.ports[0]; + ns->udp_ports.dfs_ports[0].n_elements = NSIM_UDP_TUNNEL_N_PORTS; +- debugfs_create_u32_array("udp_ports_table0", 0400, +- ns->nsim_dev_port->ddir, ++ debugfs_create_u32_array("table0", 0400, ns->udp_ports.ddir, + &ns->udp_ports.dfs_ports[0]); + + ns->udp_ports.dfs_ports[1].array = ns->udp_ports.ports[1]; + ns->udp_ports.dfs_ports[1].n_elements = NSIM_UDP_TUNNEL_N_PORTS; +- debugfs_create_u32_array("udp_ports_table1", 0400, +- ns->nsim_dev_port->ddir, ++ debugfs_create_u32_array("table1", 0400, ns->udp_ports.ddir, + &ns->udp_ports.dfs_ports[1]); + +- debugfs_create_file("udp_ports_reset", 0200, ns->nsim_dev_port->ddir, ++ debugfs_create_file("reset", 0200, ns->udp_ports.ddir, + dev, &nsim_udp_tunnels_info_reset_fops); + + /* Note: it's not normal to allocate the info struct like this! +@@ -196,6 +198,9 @@ int nsim_udp_tunnels_info_create(struct nsim_dev *nsim_dev, + + void nsim_udp_tunnels_info_destroy(struct net_device *dev) + { ++ struct netdevsim *ns = netdev_priv(dev); ++ ++ debugfs_remove_recursive(ns->udp_ports.ddir); + kfree(dev->udp_tunnel_nic_info); + dev->udp_tunnel_nic_info = NULL; + } +diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c +index ae257fa43d87a3..46a7c9fb6300e3 100644 +--- a/drivers/net/team/team.c ++++ b/drivers/net/team/team.c +@@ -1169,6 +1169,13 @@ static int team_port_add(struct team *team, struct net_device *port_dev, + return -EBUSY; + } + ++ if (netdev_has_upper_dev(port_dev, dev)) { ++ NL_SET_ERR_MSG(extack, "Device is already a lower device of the team interface"); ++ netdev_err(dev, "Device %s is already a lower device of the team interface\n", ++ portname); ++ return -EBUSY; ++ } ++ + if (port_dev->features & NETIF_F_VLAN_CHALLENGED && + vlan_uses_dev(dev)) { + NL_SET_ERR_MSG(extack, "Device is VLAN challenged and team device has VLAN set up"); +diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c +index 01a3b2417a5401..ddff6f19ff98eb 100644 +--- a/drivers/net/usb/rtl8150.c ++++ b/drivers/net/usb/rtl8150.c +@@ -71,6 +71,14 @@ + #define MSR_SPEED (1<<3) + #define MSR_LINK (1<<2) + ++/* USB endpoints */ ++enum rtl8150_usb_ep { ++ RTL8150_USB_EP_CONTROL = 0, ++ RTL8150_USB_EP_BULK_IN = 1, ++ RTL8150_USB_EP_BULK_OUT = 2, ++ RTL8150_USB_EP_INT_IN = 3, ++}; ++ + /* Interrupt pipe data */ + #define INT_TSR 0x00 + #define INT_RSR 0x01 +@@ -867,6 +875,13 @@ static int rtl8150_probe(struct usb_interface *intf, + struct usb_device *udev = interface_to_usbdev(intf); + rtl8150_t *dev; + struct net_device *netdev; ++ static const u8 bulk_ep_addr[] = { ++ RTL8150_USB_EP_BULK_IN | USB_DIR_IN, ++ RTL8150_USB_EP_BULK_OUT | USB_DIR_OUT, ++ 0}; ++ static const u8 int_ep_addr[] = { ++ RTL8150_USB_EP_INT_IN | USB_DIR_IN, ++ 0}; + + netdev = alloc_etherdev(sizeof(rtl8150_t)); + if (!netdev) +@@ -880,6 +895,13 @@ static int rtl8150_probe(struct usb_interface *intf, + return -ENOMEM; + } + ++ /* Verify that all required endpoints are present */ ++ if (!usb_check_bulk_endpoints(intf, bulk_ep_addr) || ++ !usb_check_int_endpoints(intf, int_ep_addr)) { ++ dev_err(&intf->dev, "couldn't find required endpoints\n"); ++ goto out; ++ } ++ + tasklet_setup(&dev->tl, rx_fixup); + spin_lock_init(&dev->rx_pool_lock); + +diff --git a/drivers/net/vxlan/vxlan_vnifilter.c b/drivers/net/vxlan/vxlan_vnifilter.c +index d2023e7131bd4f..6e6e9f05509ab0 100644 +--- a/drivers/net/vxlan/vxlan_vnifilter.c ++++ b/drivers/net/vxlan/vxlan_vnifilter.c +@@ -411,6 +411,11 @@ static int vxlan_vnifilter_dump(struct sk_buff *skb, struct netlink_callback *cb + struct tunnel_msg *tmsg; + struct net_device *dev; + ++ if (cb->nlh->nlmsg_len < nlmsg_msg_size(sizeof(struct tunnel_msg))) { ++ NL_SET_ERR_MSG(cb->extack, "Invalid msg length"); ++ return -EINVAL; ++ } ++ + tmsg = nlmsg_data(cb->nlh); + + if (tmsg->flags & ~TUNNEL_MSG_VALID_USER_FLAGS) { +diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c +index fb426195a3f016..4c70366ac56eb0 100644 +--- a/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -3811,6 +3811,7 @@ int ath11k_dp_process_rx_err(struct ath11k_base *ab, struct napi_struct *napi, + ath11k_hal_rx_msdu_link_info_get(link_desc_va, &num_msdus, msdu_cookies, + &rbm); + if (rbm != HAL_RX_BUF_RBM_WBM_IDLE_DESC_LIST && ++ rbm != HAL_RX_BUF_RBM_SW1_BM && + rbm != HAL_RX_BUF_RBM_SW3_BM) { + ab->soc_stats.invalid_rbm++; + ath11k_warn(ab, "invalid return buffer manager %d\n", rbm); +diff --git a/drivers/net/wireless/ath/ath11k/hal_rx.c b/drivers/net/wireless/ath/ath11k/hal_rx.c +index 363adac84a8700..2bc95026335e31 100644 +--- a/drivers/net/wireless/ath/ath11k/hal_rx.c ++++ b/drivers/net/wireless/ath/ath11k/hal_rx.c +@@ -372,7 +372,8 @@ int ath11k_hal_wbm_desc_parse_err(struct ath11k_base *ab, void *desc, + + ret_buf_mgr = FIELD_GET(BUFFER_ADDR_INFO1_RET_BUF_MGR, + wbm_desc->buf_addr_info.info1); +- if (ret_buf_mgr != HAL_RX_BUF_RBM_SW3_BM) { ++ if (ret_buf_mgr != HAL_RX_BUF_RBM_SW1_BM && ++ ret_buf_mgr != HAL_RX_BUF_RBM_SW3_BM) { + ab->soc_stats.invalid_rbm++; + return -EINVAL; + } +diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c +index 713899735ccc5e..e1db6e69d22076 100644 +--- a/drivers/net/wireless/ath/ath12k/mac.c ++++ b/drivers/net/wireless/ath/ath12k/mac.c +@@ -5823,9 +5823,9 @@ ath12k_mac_vdev_start_restart(struct ath12k_vif *arvif, + arg.mode = ath12k_phymodes[chandef->chan->band][chandef->width]; + + arg.min_power = 0; +- arg.max_power = chandef->chan->max_power * 2; +- arg.max_reg_power = chandef->chan->max_reg_power * 2; +- arg.max_antenna_gain = chandef->chan->max_antenna_gain * 2; ++ arg.max_power = chandef->chan->max_power; ++ arg.max_reg_power = chandef->chan->max_reg_power; ++ arg.max_antenna_gain = chandef->chan->max_antenna_gain; + + arg.pref_tx_streams = ar->num_tx_chains; + arg.pref_rx_streams = ar->num_rx_chains; +diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c +index 2bd1163177f08f..9bbbc86fd2d93d 100644 +--- a/drivers/net/wireless/ath/wcn36xx/main.c ++++ b/drivers/net/wireless/ath/wcn36xx/main.c +@@ -1586,7 +1586,10 @@ static int wcn36xx_probe(struct platform_device *pdev) + } + + n_channels = wcn_band_2ghz.n_channels + wcn_band_5ghz.n_channels; +- wcn->chan_survey = devm_kmalloc(wcn->dev, n_channels, GFP_KERNEL); ++ wcn->chan_survey = devm_kcalloc(wcn->dev, ++ n_channels, ++ sizeof(struct wcn36xx_chan_survey), ++ GFP_KERNEL); + if (!wcn->chan_survey) { + ret = -ENOMEM; + goto out_wq; +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h +index 31e080e4da6697..ab3d6cfcb02bde 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h +@@ -6,6 +6,8 @@ + #ifndef _fwil_h_ + #define _fwil_h_ + ++#include "debug.h" ++ + /******************************************************************************* + * Dongle command codes that are interpreted by firmware + ******************************************************************************/ +diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/init.c b/drivers/net/wireless/mediatek/mt76/mt7615/init.c +index f22a1aa8850521..129350186d5d5e 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7615/init.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7615/init.c +@@ -325,7 +325,7 @@ void mt7615_init_work(struct mt7615_dev *dev) + mt7615_mcu_set_eeprom(dev); + mt7615_mac_init(dev); + mt7615_phy_init(dev); +- mt7615_mcu_del_wtbl_all(dev); ++ mt76_connac_mcu_del_wtbl_all(&dev->mt76); + mt7615_check_offload_capability(dev); + } + EXPORT_SYMBOL_GPL(mt7615_init_work); +diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +index 955974a82180fd..e92040616a1f35 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +@@ -1876,16 +1876,6 @@ int mt7615_mcu_set_dbdc(struct mt7615_dev *dev) + sizeof(req), true); + } + +-int mt7615_mcu_del_wtbl_all(struct mt7615_dev *dev) +-{ +- struct wtbl_req_hdr req = { +- .operation = WTBL_RESET_ALL, +- }; +- +- return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(WTBL_UPDATE), +- &req, sizeof(req), true); +-} +- + int mt7615_mcu_set_fcc5_lpn(struct mt7615_dev *dev, int val) + { + struct { +diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h +index a20322aae96725..fa83b255e180c3 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h ++++ b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h +@@ -399,7 +399,6 @@ void mt7615_mac_set_rates(struct mt7615_phy *phy, struct mt7615_sta *sta, + struct ieee80211_tx_rate *rates); + void mt7615_pm_wake_work(struct work_struct *work); + void mt7615_pm_power_save_work(struct work_struct *work); +-int mt7615_mcu_del_wtbl_all(struct mt7615_dev *dev); + int mt7615_mcu_set_chan_info(struct mt7615_phy *phy, int cmd); + int mt7615_mcu_set_wmm(struct mt7615_dev *dev, u8 queue, + const struct ieee80211_tx_queue_params *params); +diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c +index 998cfd73764a9c..7420d91bef0de7 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c +@@ -2926,6 +2926,17 @@ int mt76_connac_mcu_restart(struct mt76_dev *dev) + } + EXPORT_SYMBOL_GPL(mt76_connac_mcu_restart); + ++int mt76_connac_mcu_del_wtbl_all(struct mt76_dev *dev) ++{ ++ struct wtbl_req_hdr req = { ++ .operation = WTBL_RESET_ALL, ++ }; ++ ++ return mt76_mcu_send_msg(dev, MCU_EXT_CMD(WTBL_UPDATE), ++ &req, sizeof(req), true); ++} ++EXPORT_SYMBOL_GPL(mt76_connac_mcu_del_wtbl_all); ++ + int mt76_connac_mcu_rdd_cmd(struct mt76_dev *dev, int cmd, u8 index, + u8 rx_sel, u8 val) + { +diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h +index 4543e5bf0482d2..27391ee3564a11 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h ++++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h +@@ -1914,6 +1914,7 @@ void mt76_connac_mcu_wtbl_smps_tlv(struct sk_buff *skb, + void *sta_wtbl, void *wtbl_tlv); + int mt76_connac_mcu_set_pm(struct mt76_dev *dev, int band, int enter); + int mt76_connac_mcu_restart(struct mt76_dev *dev); ++int mt76_connac_mcu_del_wtbl_all(struct mt76_dev *dev); + int mt76_connac_mcu_rdd_cmd(struct mt76_dev *dev, int cmd, u8 index, + u8 rx_sel, u8 val); + int mt76_connac_mcu_sta_wed_update(struct mt76_dev *dev, struct sk_buff *skb); +diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c +index 5ff260319282c6..28f84220d50f02 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c +@@ -82,7 +82,7 @@ static ssize_t mt7915_thermal_temp_store(struct device *dev, + return ret; + + mutex_lock(&phy->dev->mt76.mutex); +- val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 60, 130); ++ val = DIV_ROUND_CLOSEST(clamp_val(val, 60 * 1000, 130 * 1000), 1000); + + if ((i - 1 == MT7915_CRIT_TEMP_IDX && + val > phy->throttle_temp[MT7915_MAX_TEMP_IDX]) || +diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c +index 38d27f87217336..92d7dc8e3cc55e 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c +@@ -1383,6 +1383,8 @@ mt7915_mac_restart(struct mt7915_dev *dev) + if (dev_is_pci(mdev->dev)) { + mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff); + if (dev->hif2) { ++ mt76_wr(dev, MT_PCIE_RECOG_ID, ++ dev->hif2->index | MT_PCIE_RECOG_ID_SEM); + if (is_mt7915(mdev)) + mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE, 0xff); + else +@@ -1437,9 +1439,11 @@ static void + mt7915_mac_full_reset(struct mt7915_dev *dev) + { + struct mt76_phy *ext_phy; ++ struct mt7915_phy *phy2; + int i; + + ext_phy = dev->mt76.phys[MT_BAND1]; ++ phy2 = ext_phy ? ext_phy->priv : NULL; + + dev->recovery.hw_full_reset = true; + +@@ -1457,26 +1461,30 @@ mt7915_mac_full_reset(struct mt7915_dev *dev) + if (!mt7915_mac_restart(dev)) + break; + } +- mutex_unlock(&dev->mt76.mutex); + + if (i == 10) + dev_err(dev->mt76.dev, "chip full reset failed\n"); + +- ieee80211_restart_hw(mt76_hw(dev)); +- if (ext_phy) +- ieee80211_restart_hw(ext_phy->hw); ++ spin_lock_bh(&dev->mt76.sta_poll_lock); ++ while (!list_empty(&dev->mt76.sta_poll_list)) ++ list_del_init(dev->mt76.sta_poll_list.next); ++ spin_unlock_bh(&dev->mt76.sta_poll_lock); + +- ieee80211_wake_queues(mt76_hw(dev)); +- if (ext_phy) +- ieee80211_wake_queues(ext_phy->hw); ++ memset(dev->mt76.wcid_mask, 0, sizeof(dev->mt76.wcid_mask)); ++ dev->mt76.vif_mask = 0; ++ dev->phy.omac_mask = 0; ++ if (phy2) ++ phy2->omac_mask = 0; + ++ i = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7915_WTBL_STA); ++ dev->mt76.global_wcid.idx = i; + dev->recovery.hw_full_reset = false; +- ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mphy.mac_work, +- MT7915_WATCHDOG_TIME); ++ ++ mutex_unlock(&dev->mt76.mutex); ++ ++ ieee80211_restart_hw(mt76_hw(dev)); + if (ext_phy) +- ieee80211_queue_delayed_work(ext_phy->hw, +- &ext_phy->mac_work, +- MT7915_WATCHDOG_TIME); ++ ieee80211_restart_hw(ext_phy->hw); + } + + /* system error recovery */ +diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c +index 4fd5fd555191a4..c312a0fa199aee 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c +@@ -614,8 +614,9 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw, + if (changed & BSS_CHANGED_ASSOC) + set_bss_info = vif->cfg.assoc; + if (changed & BSS_CHANGED_BEACON_ENABLED && ++ info->enable_beacon && + vif->type != NL80211_IFTYPE_AP) +- set_bss_info = set_sta = info->enable_beacon; ++ set_bss_info = set_sta = 1; + + if (set_bss_info == 1) + mt7915_mcu_add_bss_info(phy, vif, true); +@@ -1649,6 +1650,17 @@ mt7915_net_fill_forward_path(struct ieee80211_hw *hw, + } + #endif + ++static void ++mt7915_reconfig_complete(struct ieee80211_hw *hw, ++ enum ieee80211_reconfig_type reconfig_type) ++{ ++ struct mt7915_phy *phy = mt7915_hw_phy(hw); ++ ++ ieee80211_wake_queues(hw); ++ ieee80211_queue_delayed_work(hw, &phy->mt76->mac_work, ++ MT7915_WATCHDOG_TIME); ++} ++ + const struct ieee80211_ops mt7915_ops = { + .tx = mt7915_tx, + .start = mt7915_start, +@@ -1703,4 +1715,5 @@ const struct ieee80211_ops mt7915_ops = { + #ifdef CONFIG_NET_MEDIATEK_SOC_WED + .net_fill_forward_path = mt7915_net_fill_forward_path, + #endif ++ .reconfig_complete = mt7915_reconfig_complete, + }; +diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +index 5fba103bfd65d5..f0226db2e57c7a 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +@@ -2351,6 +2351,8 @@ int mt7915_mcu_init_firmware(struct mt7915_dev *dev) + if (ret) + return ret; + ++ mt76_connac_mcu_del_wtbl_all(&dev->mt76); ++ + if ((mtk_wed_device_active(&dev->mt76.mmio.wed) && + is_mt7915(&dev->mt76)) || + !mtk_wed_get_rx_capa(&dev->mt76.mmio.wed)) +diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c b/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c +index a306a42777d789..7db436d908a39b 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c +@@ -484,7 +484,7 @@ static u32 __mt7915_reg_addr(struct mt7915_dev *dev, u32 addr) + continue; + + ofs = addr - dev->reg.map[i].phys; +- if (ofs > dev->reg.map[i].size) ++ if (ofs >= dev->reg.map[i].size) + continue; + + return dev->reg.map[i].maps + ofs; +diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h +index e192211d4b23ee..14d4bbeae9d63f 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h ++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h +@@ -191,6 +191,7 @@ struct mt7915_hif { + struct device *dev; + void __iomem *regs; + int irq; ++ u32 index; + }; + + struct mt7915_phy { +diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/pci.c b/drivers/net/wireless/mediatek/mt76/mt7915/pci.c +index 39132894e8ea29..07b0a5766eab7d 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7915/pci.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7915/pci.c +@@ -42,6 +42,7 @@ static struct mt7915_hif *mt7915_pci_get_hif2(u32 idx) + continue; + + get_device(hif->dev); ++ hif->index = idx; + goto out; + } + hif = NULL; +diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c +index 6dec54431312ad..31ef58e2a3d2a3 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c +@@ -519,7 +519,13 @@ static int mt7921_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, + } else { + if (idx == *wcid_keyidx) + *wcid_keyidx = -1; +- goto out; ++ ++ /* For security issue we don't trigger the key deletion when ++ * reassociating. But we should trigger the deletion process ++ * to avoid using incorrect cipher after disconnection, ++ */ ++ if (vif->type != NL80211_IFTYPE_STATION || vif->cfg.assoc) ++ goto out; + } + + mt76_wcid_key_setup(&dev->mt76, wcid, key); +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/init.c b/drivers/net/wireless/mediatek/mt76/mt7996/init.c +index aee531cab46f64..0a701dcb8a92c5 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/init.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/init.c +@@ -619,6 +619,9 @@ mt7996_init_he_caps(struct mt7996_phy *phy, enum nl80211_band band, + he_cap_elem->phy_cap_info[2] = IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ | + IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ; + ++ he_cap_elem->phy_cap_info[7] = ++ IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI; ++ + switch (iftype) { + case NL80211_IFTYPE_AP: + he_cap_elem->mac_cap_info[0] |= IEEE80211_HE_MAC_CAP0_TWT_RES; +@@ -658,8 +661,7 @@ mt7996_init_he_caps(struct mt7996_phy *phy, enum nl80211_band band, + IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE | + IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT; + he_cap_elem->phy_cap_info[7] |= +- IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_SUPP | +- IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI; ++ IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_SUPP; + he_cap_elem->phy_cap_info[8] |= + IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G | + IEEE80211_HE_PHY_CAP8_20MHZ_IN_160MHZ_HE_PPDU | +@@ -729,7 +731,9 @@ mt7996_init_eht_caps(struct mt7996_phy *phy, enum nl80211_band band, + + eht_cap_elem->mac_cap_info[0] = + IEEE80211_EHT_MAC_CAP0_EPCS_PRIO_ACCESS | +- IEEE80211_EHT_MAC_CAP0_OM_CONTROL; ++ IEEE80211_EHT_MAC_CAP0_OM_CONTROL | ++ u8_encode_bits(IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_11454, ++ IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_MASK); + + eht_cap_elem->phy_cap_info[0] = + IEEE80211_EHT_PHY_CAP0_NDP_4_EHT_LFT_32_GI | +@@ -771,21 +775,20 @@ mt7996_init_eht_caps(struct mt7996_phy *phy, enum nl80211_band band, + IEEE80211_EHT_PHY_CAP3_CODEBOOK_7_5_MU_FDBK; + + eht_cap_elem->phy_cap_info[4] = ++ IEEE80211_EHT_PHY_CAP4_EHT_MU_PPDU_4_EHT_LTF_08_GI | + u8_encode_bits(min_t(int, sts - 1, 2), + IEEE80211_EHT_PHY_CAP4_MAX_NC_MASK); + + eht_cap_elem->phy_cap_info[5] = + u8_encode_bits(IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_16US, + IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_MASK) | +- u8_encode_bits(u8_get_bits(0x11, GENMASK(1, 0)), ++ u8_encode_bits(u8_get_bits(1, GENMASK(1, 0)), + IEEE80211_EHT_PHY_CAP5_MAX_NUM_SUPP_EHT_LTF_MASK); + + val = width == NL80211_CHAN_WIDTH_320 ? 0xf : + width == NL80211_CHAN_WIDTH_160 ? 0x7 : + width == NL80211_CHAN_WIDTH_80 ? 0x3 : 0x1; + eht_cap_elem->phy_cap_info[6] = +- u8_encode_bits(u8_get_bits(0x11, GENMASK(4, 2)), +- IEEE80211_EHT_PHY_CAP6_MAX_NUM_SUPP_EHT_LTF_MASK) | + u8_encode_bits(val, IEEE80211_EHT_PHY_CAP6_MCS15_SUPP_MASK); + + val = u8_encode_bits(nss, IEEE80211_EHT_MCS_NSS_RX) | +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c +index 0e69f0a508616b..c559212ea86a73 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c +@@ -474,8 +474,7 @@ static void mt7996_configure_filter(struct ieee80211_hw *hw, + + MT76_FILTER(CONTROL, MT_WF_RFCR_DROP_CTS | + MT_WF_RFCR_DROP_RTS | +- MT_WF_RFCR_DROP_CTL_RSV | +- MT_WF_RFCR_DROP_NDPA); ++ MT_WF_RFCR_DROP_CTL_RSV); + + *total_flags = flags; + mt76_wr(dev, MT_WF_RFCR(phy->mt76->band_idx), phy->rxfilter); +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +index 302171e1035977..65a5f24e53136b 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +@@ -1723,7 +1723,7 @@ mt7996_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7996_dev *dev, + cap |= STA_CAP_VHT_TX_STBC; + if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_1) + cap |= STA_CAP_VHT_RX_STBC; +- if (vif->bss_conf.vht_ldpc && ++ if ((vif->type != NL80211_IFTYPE_AP || vif->bss_conf.vht_ldpc) && + (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC)) + cap |= STA_CAP_VHT_LDPC; + +@@ -3189,6 +3189,13 @@ int mt7996_mcu_get_chip_config(struct mt7996_dev *dev, u32 *cap) + + int mt7996_mcu_get_chan_mib_info(struct mt7996_phy *phy, bool chan_switch) + { ++ enum { ++ IDX_TX_TIME, ++ IDX_RX_TIME, ++ IDX_OBSS_AIRTIME, ++ IDX_NON_WIFI_TIME, ++ IDX_NUM ++ }; + struct { + struct { + u8 band; +@@ -3198,16 +3205,15 @@ int mt7996_mcu_get_chan_mib_info(struct mt7996_phy *phy, bool chan_switch) + __le16 tag; + __le16 len; + __le32 offs; +- } data[4]; ++ } data[IDX_NUM]; + } __packed req = { + .hdr.band = phy->mt76->band_idx, + }; +- /* strict order */ + static const u32 offs[] = { +- UNI_MIB_TX_TIME, +- UNI_MIB_RX_TIME, +- UNI_MIB_OBSS_AIRTIME, +- UNI_MIB_NON_WIFI_TIME, ++ [IDX_TX_TIME] = UNI_MIB_TX_TIME, ++ [IDX_RX_TIME] = UNI_MIB_RX_TIME, ++ [IDX_OBSS_AIRTIME] = UNI_MIB_OBSS_AIRTIME, ++ [IDX_NON_WIFI_TIME] = UNI_MIB_NON_WIFI_TIME, + }; + struct mt76_channel_state *state = phy->mt76->chan_state; + struct mt76_channel_state *state_ts = &phy->state_ts; +@@ -3216,7 +3222,7 @@ int mt7996_mcu_get_chan_mib_info(struct mt7996_phy *phy, bool chan_switch) + struct sk_buff *skb; + int i, ret; + +- for (i = 0; i < 4; i++) { ++ for (i = 0; i < IDX_NUM; i++) { + req.data[i].tag = cpu_to_le16(UNI_CMD_MIB_DATA); + req.data[i].len = cpu_to_le16(sizeof(req.data[i])); + req.data[i].offs = cpu_to_le32(offs[i]); +@@ -3235,17 +3241,24 @@ int mt7996_mcu_get_chan_mib_info(struct mt7996_phy *phy, bool chan_switch) + goto out; + + #define __res_u64(s) le64_to_cpu(res[s].data) +- state->cc_tx += __res_u64(1) - state_ts->cc_tx; +- state->cc_bss_rx += __res_u64(2) - state_ts->cc_bss_rx; +- state->cc_rx += __res_u64(2) + __res_u64(3) - state_ts->cc_rx; +- state->cc_busy += __res_u64(0) + __res_u64(1) + __res_u64(2) + __res_u64(3) - ++ state->cc_tx += __res_u64(IDX_TX_TIME) - state_ts->cc_tx; ++ state->cc_bss_rx += __res_u64(IDX_RX_TIME) - state_ts->cc_bss_rx; ++ state->cc_rx += __res_u64(IDX_RX_TIME) + ++ __res_u64(IDX_OBSS_AIRTIME) - ++ state_ts->cc_rx; ++ state->cc_busy += __res_u64(IDX_TX_TIME) + ++ __res_u64(IDX_RX_TIME) + ++ __res_u64(IDX_OBSS_AIRTIME) + ++ __res_u64(IDX_NON_WIFI_TIME) - + state_ts->cc_busy; +- + out: +- state_ts->cc_tx = __res_u64(1); +- state_ts->cc_bss_rx = __res_u64(2); +- state_ts->cc_rx = __res_u64(2) + __res_u64(3); +- state_ts->cc_busy = __res_u64(0) + __res_u64(1) + __res_u64(2) + __res_u64(3); ++ state_ts->cc_tx = __res_u64(IDX_TX_TIME); ++ state_ts->cc_bss_rx = __res_u64(IDX_RX_TIME); ++ state_ts->cc_rx = __res_u64(IDX_RX_TIME) + __res_u64(IDX_OBSS_AIRTIME); ++ state_ts->cc_busy = __res_u64(IDX_TX_TIME) + ++ __res_u64(IDX_RX_TIME) + ++ __res_u64(IDX_OBSS_AIRTIME) + ++ __res_u64(IDX_NON_WIFI_TIME); + #undef __res_u64 + + dev_kfree_skb(skb); +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mmio.c b/drivers/net/wireless/mediatek/mt76/mt7996/mmio.c +index e75becadc2e54d..f0fa0f513be907 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/mmio.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mmio.c +@@ -119,7 +119,7 @@ static u32 __mt7996_reg_addr(struct mt7996_dev *dev, u32 addr) + continue; + + ofs = addr - dev->reg.map[i].phys; +- if (ofs > dev->reg.map[i].size) ++ if (ofs >= dev->reg.map[i].size) + continue; + + return dev->reg.map[i].mapped + ofs; +diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c +index 1584665fe3cb68..a8f26583b51b22 100644 +--- a/drivers/net/wireless/mediatek/mt76/usb.c ++++ b/drivers/net/wireless/mediatek/mt76/usb.c +@@ -33,9 +33,9 @@ int __mt76u_vendor_request(struct mt76_dev *dev, u8 req, u8 req_type, + + ret = usb_control_msg(udev, pipe, req, req_type, val, + offset, buf, len, MT_VEND_REQ_TOUT_MS); +- if (ret == -ENODEV) ++ if (ret == -ENODEV || ret == -EPROTO) + set_bit(MT76_REMOVED, &dev->phy.state); +- if (ret >= 0 || ret == -ENODEV) ++ if (ret >= 0 || ret == -ENODEV || ret == -EPROTO) + return ret; + usleep_range(5000, 10000); + } +diff --git a/drivers/net/wireless/realtek/rtlwifi/base.c b/drivers/net/wireless/realtek/rtlwifi/base.c +index 807a53a97325bf..c981739f707730 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/base.c ++++ b/drivers/net/wireless/realtek/rtlwifi/base.c +@@ -575,9 +575,15 @@ static void rtl_free_entries_from_ack_queue(struct ieee80211_hw *hw, + + void rtl_deinit_core(struct ieee80211_hw *hw) + { ++ struct rtl_priv *rtlpriv = rtl_priv(hw); ++ + rtl_c2hcmd_launcher(hw, 0); + rtl_free_entries_from_scan_list(hw); + rtl_free_entries_from_ack_queue(hw, false); ++ if (rtlpriv->works.rtl_wq) { ++ destroy_workqueue(rtlpriv->works.rtl_wq); ++ rtlpriv->works.rtl_wq = NULL; ++ } + } + EXPORT_SYMBOL_GPL(rtl_deinit_core); + +@@ -2710,9 +2716,6 @@ MODULE_AUTHOR("Larry Finger "); + MODULE_LICENSE("GPL"); + MODULE_DESCRIPTION("Realtek 802.11n PCI wireless core"); + +-struct rtl_global_var rtl_global_var = {}; +-EXPORT_SYMBOL_GPL(rtl_global_var); +- + static int __init rtl_core_module_init(void) + { + BUILD_BUG_ON(TX_PWR_BY_RATE_NUM_RATE < TX_PWR_BY_RATE_NUM_SECTION); +@@ -2726,10 +2729,6 @@ static int __init rtl_core_module_init(void) + /* add debugfs */ + rtl_debugfs_add_topdir(); + +- /* init some global vars */ +- INIT_LIST_HEAD(&rtl_global_var.glb_priv_list); +- spin_lock_init(&rtl_global_var.glb_list_lock); +- + return 0; + } + +diff --git a/drivers/net/wireless/realtek/rtlwifi/base.h b/drivers/net/wireless/realtek/rtlwifi/base.h +index f081a9a90563f5..f3a6a43a42eca8 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/base.h ++++ b/drivers/net/wireless/realtek/rtlwifi/base.h +@@ -124,7 +124,6 @@ int rtl_send_smps_action(struct ieee80211_hw *hw, + u8 *rtl_find_ie(u8 *data, unsigned int len, u8 ie); + void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len); + u8 rtl_tid_to_ac(u8 tid); +-extern struct rtl_global_var rtl_global_var; + void rtl_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation); + + #endif +diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.c b/drivers/net/wireless/realtek/rtlwifi/pci.c +index b118df035243c5..3abd0c4c954bc1 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/pci.c ++++ b/drivers/net/wireless/realtek/rtlwifi/pci.c +@@ -295,46 +295,6 @@ static bool rtl_pci_get_amd_l1_patch(struct ieee80211_hw *hw) + return status; + } + +-static bool rtl_pci_check_buddy_priv(struct ieee80211_hw *hw, +- struct rtl_priv **buddy_priv) +-{ +- struct rtl_priv *rtlpriv = rtl_priv(hw); +- struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); +- struct rtl_priv *tpriv = NULL, *iter; +- struct rtl_pci_priv *tpcipriv = NULL; +- +- if (!list_empty(&rtlpriv->glb_var->glb_priv_list)) { +- list_for_each_entry(iter, &rtlpriv->glb_var->glb_priv_list, +- list) { +- tpcipriv = (struct rtl_pci_priv *)iter->priv; +- rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, +- "pcipriv->ndis_adapter.funcnumber %x\n", +- pcipriv->ndis_adapter.funcnumber); +- rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, +- "tpcipriv->ndis_adapter.funcnumber %x\n", +- tpcipriv->ndis_adapter.funcnumber); +- +- if (pcipriv->ndis_adapter.busnumber == +- tpcipriv->ndis_adapter.busnumber && +- pcipriv->ndis_adapter.devnumber == +- tpcipriv->ndis_adapter.devnumber && +- pcipriv->ndis_adapter.funcnumber != +- tpcipriv->ndis_adapter.funcnumber) { +- tpriv = iter; +- break; +- } +- } +- } +- +- rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, +- "find_buddy_priv %d\n", tpriv != NULL); +- +- if (tpriv) +- *buddy_priv = tpriv; +- +- return tpriv != NULL; +-} +- + static void rtl_pci_parse_configuration(struct pci_dev *pdev, + struct ieee80211_hw *hw) + { +@@ -1697,8 +1657,6 @@ static void rtl_pci_deinit(struct ieee80211_hw *hw) + synchronize_irq(rtlpci->pdev->irq); + tasklet_kill(&rtlpriv->works.irq_tasklet); + cancel_work_sync(&rtlpriv->works.lps_change_work); +- +- destroy_workqueue(rtlpriv->works.rtl_wq); + } + + static int rtl_pci_init(struct ieee80211_hw *hw, struct pci_dev *pdev) +@@ -2013,7 +1971,6 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, + pcipriv->ndis_adapter.amd_l1_patch); + + rtl_pci_parse_configuration(pdev, hw); +- list_add_tail(&rtlpriv->list, &rtlpriv->glb_var->glb_priv_list); + + return true; + } +@@ -2160,7 +2117,6 @@ int rtl_pci_probe(struct pci_dev *pdev, + rtlpriv->rtlhal.interface = INTF_PCI; + rtlpriv->cfg = (struct rtl_hal_cfg *)(id->driver_data); + rtlpriv->intf_ops = &rtl_pci_ops; +- rtlpriv->glb_var = &rtl_global_var; + rtl_efuse_ops_init(hw); + + /* MEM map */ +@@ -2211,7 +2167,7 @@ int rtl_pci_probe(struct pci_dev *pdev, + if (rtlpriv->cfg->ops->init_sw_vars(hw)) { + pr_err("Can't init_sw_vars\n"); + err = -ENODEV; +- goto fail3; ++ goto fail2; + } + rtl_init_sw_leds(hw); + +@@ -2229,14 +2185,14 @@ int rtl_pci_probe(struct pci_dev *pdev, + err = rtl_pci_init(hw, pdev); + if (err) { + pr_err("Failed to init PCI\n"); +- goto fail3; ++ goto fail4; + } + + err = ieee80211_register_hw(hw); + if (err) { + pr_err("Can't register mac80211 hw.\n"); + err = -ENODEV; +- goto fail3; ++ goto fail5; + } + rtlpriv->mac80211.mac80211_registered = 1; + +@@ -2259,16 +2215,19 @@ int rtl_pci_probe(struct pci_dev *pdev, + set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status); + return 0; + +-fail3: +- pci_set_drvdata(pdev, NULL); ++fail5: ++ rtl_pci_deinit(hw); ++fail4: + rtl_deinit_core(hw); ++fail3: ++ wait_for_completion(&rtlpriv->firmware_loading_complete); ++ rtlpriv->cfg->ops->deinit_sw_vars(hw); + + fail2: + if (rtlpriv->io.pci_mem_start != 0) + pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start); + + pci_release_regions(pdev); +- complete(&rtlpriv->firmware_loading_complete); + + fail1: + if (hw) +@@ -2319,7 +2278,6 @@ void rtl_pci_disconnect(struct pci_dev *pdev) + if (rtlpci->using_msi) + pci_disable_msi(rtlpci->pdev); + +- list_del(&rtlpriv->list); + if (rtlpriv->io.pci_mem_start != 0) { + pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start); + pci_release_regions(pdev); +@@ -2379,7 +2337,6 @@ const struct rtl_intf_ops rtl_pci_ops = { + .read_efuse_byte = read_efuse_byte, + .adapter_start = rtl_pci_start, + .adapter_stop = rtl_pci_stop, +- .check_buddy_priv = rtl_pci_check_buddy_priv, + .adapter_tx = rtl_pci_tx, + .flush = rtl_pci_flush, + .reset_trx_ring = rtl_pci_reset_trx_ring, +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c +index 30bce381c3bb70..d7dae4488f69bb 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c +@@ -67,22 +67,23 @@ static void rtl92se_fw_cb(const struct firmware *firmware, void *context) + + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "Firmware callback routine entered!\n"); +- complete(&rtlpriv->firmware_loading_complete); + if (!firmware) { + pr_err("Firmware %s not available\n", fw_name); + rtlpriv->max_fw_size = 0; +- return; ++ goto exit; + } + if (firmware->size > rtlpriv->max_fw_size) { + pr_err("Firmware is too big!\n"); + rtlpriv->max_fw_size = 0; + release_firmware(firmware); +- return; ++ goto exit; + } + pfirmware = (struct rt_firmware *)rtlpriv->rtlhal.pfirmware; + memcpy(pfirmware->sz_fw_tmpbuffer, firmware->data, firmware->size); + pfirmware->sz_fw_tmpbufferlen = firmware->size; + release_firmware(firmware); ++exit: ++ complete(&rtlpriv->firmware_loading_complete); + } + + static int rtl92s_init_sw_vars(struct ieee80211_hw *hw) +diff --git a/drivers/net/wireless/realtek/rtlwifi/usb.c b/drivers/net/wireless/realtek/rtlwifi/usb.c +index 30bf2775a335bc..e2e1e568bdb36b 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/usb.c ++++ b/drivers/net/wireless/realtek/rtlwifi/usb.c +@@ -660,11 +660,6 @@ static void _rtl_usb_cleanup_rx(struct ieee80211_hw *hw) + tasklet_kill(&rtlusb->rx_work_tasklet); + cancel_work_sync(&rtlpriv->works.lps_change_work); + +- if (rtlpriv->works.rtl_wq) { +- destroy_workqueue(rtlpriv->works.rtl_wq); +- rtlpriv->works.rtl_wq = NULL; +- } +- + skb_queue_purge(&rtlusb->rx_queue); + + while ((urb = usb_get_from_anchor(&rtlusb->rx_cleanup_urbs))) { +@@ -1054,19 +1049,22 @@ int rtl_usb_probe(struct usb_interface *intf, + err = ieee80211_register_hw(hw); + if (err) { + pr_err("Can't register mac80211 hw.\n"); +- goto error_out; ++ goto error_init_vars; + } + rtlpriv->mac80211.mac80211_registered = 1; + + set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status); + return 0; + ++error_init_vars: ++ wait_for_completion(&rtlpriv->firmware_loading_complete); ++ rtlpriv->cfg->ops->deinit_sw_vars(hw); + error_out: ++ rtl_usb_deinit(hw); + rtl_deinit_core(hw); + error_out2: + _rtl_usb_io_handler_release(hw); + usb_put_dev(udev); +- complete(&rtlpriv->firmware_loading_complete); + kfree(rtlpriv->usb_data); + ieee80211_free_hw(hw); + return -ENODEV; +diff --git a/drivers/net/wireless/realtek/rtlwifi/wifi.h b/drivers/net/wireless/realtek/rtlwifi/wifi.h +index 8cbf3fb3885397..2106d7763badae 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/wifi.h ++++ b/drivers/net/wireless/realtek/rtlwifi/wifi.h +@@ -2321,8 +2321,6 @@ struct rtl_intf_ops { + void (*read_efuse_byte)(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf); + int (*adapter_start)(struct ieee80211_hw *hw); + void (*adapter_stop)(struct ieee80211_hw *hw); +- bool (*check_buddy_priv)(struct ieee80211_hw *hw, +- struct rtl_priv **buddy_priv); + + int (*adapter_tx)(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, +@@ -2566,14 +2564,6 @@ struct dig_t { + u32 rssi_max; + }; + +-struct rtl_global_var { +- /* from this list we can get +- * other adapter's rtl_priv +- */ +- struct list_head glb_priv_list; +- spinlock_t glb_list_lock; +-}; +- + #define IN_4WAY_TIMEOUT_TIME (30 * MSEC_PER_SEC) /* 30 seconds */ + + struct rtl_btc_info { +@@ -2719,9 +2709,7 @@ struct rtl_scan_list { + struct rtl_priv { + struct ieee80211_hw *hw; + struct completion firmware_loading_complete; +- struct list_head list; + struct rtl_priv *buddy_priv; +- struct rtl_global_var *glb_var; + struct rtl_dmsp_ctl dmsp_ctl; + struct rtl_locks locks; + struct rtl_works works; +diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c +index bf21611872a3c1..9706240ddd416b 100644 +--- a/drivers/net/wireless/ti/wlcore/main.c ++++ b/drivers/net/wireless/ti/wlcore/main.c +@@ -2533,24 +2533,24 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw, + if (test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags) || + test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags)) { + ret = -EBUSY; +- goto out; ++ goto out_unlock; + } + + + ret = wl12xx_init_vif_data(wl, vif); + if (ret < 0) +- goto out; ++ goto out_unlock; + + wlvif->wl = wl; + role_type = wl12xx_get_role_type(wl, wlvif); + if (role_type == WL12XX_INVALID_ROLE_TYPE) { + ret = -EINVAL; +- goto out; ++ goto out_unlock; + } + + ret = wlcore_allocate_hw_queue_base(wl, wlvif); + if (ret < 0) +- goto out; ++ goto out_unlock; + + /* + * TODO: after the nvs issue will be solved, move this block +@@ -2565,7 +2565,7 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw, + + ret = wl12xx_init_fw(wl); + if (ret < 0) +- goto out; ++ goto out_unlock; + } + + /* +diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c +index 4aad16390d4790..26e3f1896dc397 100644 +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -2853,7 +2853,7 @@ int nvme_get_log(struct nvme_ctrl *ctrl, u32 nsid, u8 log_page, u8 lsp, u8 csi, + static int nvme_get_effects_log(struct nvme_ctrl *ctrl, u8 csi, + struct nvme_effects_log **log) + { +- struct nvme_effects_log *cel = xa_load(&ctrl->cels, csi); ++ struct nvme_effects_log *old, *cel = xa_load(&ctrl->cels, csi); + int ret; + + if (cel) +@@ -2870,7 +2870,11 @@ static int nvme_get_effects_log(struct nvme_ctrl *ctrl, u8 csi, + return ret; + } + +- xa_store(&ctrl->cels, csi, cel, GFP_KERNEL); ++ old = xa_store(&ctrl->cels, csi, cel, GFP_KERNEL); ++ if (xa_is_err(old)) { ++ kfree(cel); ++ return xa_err(old); ++ } + out: + *log = cel; + return 0; +@@ -2941,6 +2945,25 @@ static int nvme_init_non_mdts_limits(struct nvme_ctrl *ctrl) + return ret; + } + ++static int nvme_init_effects_log(struct nvme_ctrl *ctrl, ++ u8 csi, struct nvme_effects_log **log) ++{ ++ struct nvme_effects_log *effects, *old; ++ ++ effects = kzalloc(sizeof(*effects), GFP_KERNEL); ++ if (!effects) ++ return -ENOMEM; ++ ++ old = xa_store(&ctrl->cels, csi, effects, GFP_KERNEL); ++ if (xa_is_err(old)) { ++ kfree(effects); ++ return xa_err(old); ++ } ++ ++ *log = effects; ++ return 0; ++} ++ + static void nvme_init_known_nvm_effects(struct nvme_ctrl *ctrl) + { + struct nvme_effects_log *log = ctrl->effects; +@@ -2987,10 +3010,9 @@ static int nvme_init_effects(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id) + } + + if (!ctrl->effects) { +- ctrl->effects = kzalloc(sizeof(*ctrl->effects), GFP_KERNEL); +- if (!ctrl->effects) +- return -ENOMEM; +- xa_store(&ctrl->cels, NVME_CSI_NVM, ctrl->effects, GFP_KERNEL); ++ ret = nvme_init_effects_log(ctrl, NVME_CSI_NVM, &ctrl->effects); ++ if (ret < 0) ++ return ret; + } + + nvme_init_known_nvm_effects(ctrl); +diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c +index 7ec94cfcbddb18..959f1808c240fa 100644 +--- a/drivers/of/of_reserved_mem.c ++++ b/drivers/of/of_reserved_mem.c +@@ -50,7 +50,8 @@ static int __init early_init_dt_alloc_reserved_memory_arch(phys_addr_t size, + memblock_phys_free(base, size); + } + +- kmemleak_ignore_phys(base); ++ if (!err) ++ kmemleak_ignore_phys(base); + + return err; + } +diff --git a/drivers/opp/core.c b/drivers/opp/core.c +index bceb27b1baa18a..218cb2e7f36055 100644 +--- a/drivers/opp/core.c ++++ b/drivers/opp/core.c +@@ -101,11 +101,30 @@ struct opp_table *_find_opp_table(struct device *dev) + * representation in the OPP table and manage the clock configuration themselves + * in an platform specific way. + */ +-static bool assert_single_clk(struct opp_table *opp_table) ++static bool assert_single_clk(struct opp_table *opp_table, ++ unsigned int __always_unused index) + { + return !WARN_ON(opp_table->clk_count > 1); + } + ++/* ++ * Returns true if clock table is large enough to contain the clock index. ++ */ ++static bool assert_clk_index(struct opp_table *opp_table, ++ unsigned int index) ++{ ++ return opp_table->clk_count > index; ++} ++ ++/* ++ * Returns true if bandwidth table is large enough to contain the bandwidth index. ++ */ ++static bool assert_bandwidth_index(struct opp_table *opp_table, ++ unsigned int index) ++{ ++ return opp_table->path_count > index; ++} ++ + /** + * dev_pm_opp_get_voltage() - Gets the voltage corresponding to an opp + * @opp: opp for which voltage has to be returned for +@@ -499,12 +518,12 @@ static struct dev_pm_opp *_opp_table_find_key(struct opp_table *opp_table, + unsigned long (*read)(struct dev_pm_opp *opp, int index), + bool (*compare)(struct dev_pm_opp **opp, struct dev_pm_opp *temp_opp, + unsigned long opp_key, unsigned long key), +- bool (*assert)(struct opp_table *opp_table)) ++ bool (*assert)(struct opp_table *opp_table, unsigned int index)) + { + struct dev_pm_opp *temp_opp, *opp = ERR_PTR(-ERANGE); + + /* Assert that the requirement is met */ +- if (assert && !assert(opp_table)) ++ if (assert && !assert(opp_table, index)) + return ERR_PTR(-EINVAL); + + mutex_lock(&opp_table->lock); +@@ -532,7 +551,7 @@ _find_key(struct device *dev, unsigned long *key, int index, bool available, + unsigned long (*read)(struct dev_pm_opp *opp, int index), + bool (*compare)(struct dev_pm_opp **opp, struct dev_pm_opp *temp_opp, + unsigned long opp_key, unsigned long key), +- bool (*assert)(struct opp_table *opp_table)) ++ bool (*assert)(struct opp_table *opp_table, unsigned int index)) + { + struct opp_table *opp_table; + struct dev_pm_opp *opp; +@@ -555,7 +574,7 @@ _find_key(struct device *dev, unsigned long *key, int index, bool available, + static struct dev_pm_opp *_find_key_exact(struct device *dev, + unsigned long key, int index, bool available, + unsigned long (*read)(struct dev_pm_opp *opp, int index), +- bool (*assert)(struct opp_table *opp_table)) ++ bool (*assert)(struct opp_table *opp_table, unsigned int index)) + { + /* + * The value of key will be updated here, but will be ignored as the +@@ -568,7 +587,7 @@ static struct dev_pm_opp *_find_key_exact(struct device *dev, + static struct dev_pm_opp *_opp_table_find_key_ceil(struct opp_table *opp_table, + unsigned long *key, int index, bool available, + unsigned long (*read)(struct dev_pm_opp *opp, int index), +- bool (*assert)(struct opp_table *opp_table)) ++ bool (*assert)(struct opp_table *opp_table, unsigned int index)) + { + return _opp_table_find_key(opp_table, key, index, available, read, + _compare_ceil, assert); +@@ -577,7 +596,7 @@ static struct dev_pm_opp *_opp_table_find_key_ceil(struct opp_table *opp_table, + static struct dev_pm_opp *_find_key_ceil(struct device *dev, unsigned long *key, + int index, bool available, + unsigned long (*read)(struct dev_pm_opp *opp, int index), +- bool (*assert)(struct opp_table *opp_table)) ++ bool (*assert)(struct opp_table *opp_table, unsigned int index)) + { + return _find_key(dev, key, index, available, read, _compare_ceil, + assert); +@@ -586,7 +605,7 @@ static struct dev_pm_opp *_find_key_ceil(struct device *dev, unsigned long *key, + static struct dev_pm_opp *_find_key_floor(struct device *dev, + unsigned long *key, int index, bool available, + unsigned long (*read)(struct dev_pm_opp *opp, int index), +- bool (*assert)(struct opp_table *opp_table)) ++ bool (*assert)(struct opp_table *opp_table, unsigned int index)) + { + return _find_key(dev, key, index, available, read, _compare_floor, + assert); +@@ -647,7 +666,8 @@ struct dev_pm_opp * + dev_pm_opp_find_freq_exact_indexed(struct device *dev, unsigned long freq, + u32 index, bool available) + { +- return _find_key_exact(dev, freq, index, available, _read_freq, NULL); ++ return _find_key_exact(dev, freq, index, available, _read_freq, ++ assert_clk_index); + } + EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_exact_indexed); + +@@ -707,7 +727,8 @@ struct dev_pm_opp * + dev_pm_opp_find_freq_ceil_indexed(struct device *dev, unsigned long *freq, + u32 index) + { +- return _find_key_ceil(dev, freq, index, true, _read_freq, NULL); ++ return _find_key_ceil(dev, freq, index, true, _read_freq, ++ assert_clk_index); + } + EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_ceil_indexed); + +@@ -760,7 +781,7 @@ struct dev_pm_opp * + dev_pm_opp_find_freq_floor_indexed(struct device *dev, unsigned long *freq, + u32 index) + { +- return _find_key_floor(dev, freq, index, true, _read_freq, NULL); ++ return _find_key_floor(dev, freq, index, true, _read_freq, assert_clk_index); + } + EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_floor_indexed); + +@@ -838,7 +859,8 @@ struct dev_pm_opp *dev_pm_opp_find_bw_ceil(struct device *dev, unsigned int *bw, + unsigned long temp = *bw; + struct dev_pm_opp *opp; + +- opp = _find_key_ceil(dev, &temp, index, true, _read_bw, NULL); ++ opp = _find_key_ceil(dev, &temp, index, true, _read_bw, ++ assert_bandwidth_index); + *bw = temp; + return opp; + } +@@ -869,7 +891,8 @@ struct dev_pm_opp *dev_pm_opp_find_bw_floor(struct device *dev, + unsigned long temp = *bw; + struct dev_pm_opp *opp; + +- opp = _find_key_floor(dev, &temp, index, true, _read_bw, NULL); ++ opp = _find_key_floor(dev, &temp, index, true, _read_bw, ++ assert_bandwidth_index); + *bw = temp; + return opp; + } +@@ -1676,7 +1699,7 @@ void dev_pm_opp_remove(struct device *dev, unsigned long freq) + if (IS_ERR(opp_table)) + return; + +- if (!assert_single_clk(opp_table)) ++ if (!assert_single_clk(opp_table, 0)) + goto put_table; + + mutex_lock(&opp_table->lock); +@@ -2027,7 +2050,7 @@ int _opp_add_v1(struct opp_table *opp_table, struct device *dev, + unsigned long tol; + int ret; + +- if (!assert_single_clk(opp_table)) ++ if (!assert_single_clk(opp_table, 0)) + return -EINVAL; + + new_opp = _opp_allocate(opp_table); +@@ -2889,7 +2912,7 @@ static int _opp_set_availability(struct device *dev, unsigned long freq, + return r; + } + +- if (!assert_single_clk(opp_table)) { ++ if (!assert_single_clk(opp_table, 0)) { + r = -EINVAL; + goto put_table; + } +@@ -2965,7 +2988,7 @@ int dev_pm_opp_adjust_voltage(struct device *dev, unsigned long freq, + return r; + } + +- if (!assert_single_clk(opp_table)) { ++ if (!assert_single_clk(opp_table, 0)) { + r = -EINVAL; + goto put_table; + } +diff --git a/drivers/opp/of.c b/drivers/opp/of.c +index ada4963c7cfae5..657c08d0ad979a 100644 +--- a/drivers/opp/of.c ++++ b/drivers/opp/of.c +@@ -932,7 +932,7 @@ static struct dev_pm_opp *_opp_add_static_v2(struct opp_table *opp_table, + + ret = _of_opp_alloc_required_opps(opp_table, new_opp); + if (ret) +- goto free_opp; ++ goto put_node; + + if (!of_property_read_u32(np, "clock-latency-ns", &val)) + new_opp->clock_latency_ns = val; +@@ -982,6 +982,8 @@ static struct dev_pm_opp *_opp_add_static_v2(struct opp_table *opp_table, + + free_required_opps: + _of_opp_free_required_opps(opp_table, new_opp); ++put_node: ++ of_node_put(np); + free_opp: + _opp_free(new_opp); + +diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c +index 86b09b5d7f2493..822a750b064b27 100644 +--- a/drivers/pci/controller/dwc/pci-imx6.c ++++ b/drivers/pci/controller/dwc/pci-imx6.c +@@ -61,12 +61,16 @@ enum imx6_pcie_variants { + #define IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE BIT(1) + #define IMX6_PCIE_FLAG_SUPPORTS_SUSPEND BIT(2) + ++#define IMX6_PCIE_MAX_CLKS 6 ++ + struct imx6_pcie_drvdata { + enum imx6_pcie_variants variant; + enum dw_pcie_device_mode mode; + u32 flags; + int dbi_length; + const char *gpr; ++ const char * const *clk_names; ++ const u32 clks_cnt; + }; + + struct imx6_pcie { +@@ -74,11 +78,7 @@ struct imx6_pcie { + int reset_gpio; + bool gpio_active_high; + bool link_is_up; +- struct clk *pcie_bus; +- struct clk *pcie_phy; +- struct clk *pcie_inbound_axi; +- struct clk *pcie; +- struct clk *pcie_aux; ++ struct clk_bulk_data clks[IMX6_PCIE_MAX_CLKS]; + struct regmap *iomuxc_gpr; + u16 msi_ctrl; + u32 controller_id; +@@ -407,13 +407,18 @@ static void imx7d_pcie_wait_for_phy_pll_lock(struct imx6_pcie *imx6_pcie) + + static int imx6_setup_phy_mpll(struct imx6_pcie *imx6_pcie) + { +- unsigned long phy_rate = clk_get_rate(imx6_pcie->pcie_phy); ++ unsigned long phy_rate = 0; + int mult, div; + u16 val; ++ int i; + + if (!(imx6_pcie->drvdata->flags & IMX6_PCIE_FLAG_IMX6_PHY)) + return 0; + ++ for (i = 0; i < imx6_pcie->drvdata->clks_cnt; i++) ++ if (strncmp(imx6_pcie->clks[i].id, "pcie_phy", 8) == 0) ++ phy_rate = clk_get_rate(imx6_pcie->clks[i].clk); ++ + switch (phy_rate) { + case 125000000: + /* +@@ -550,19 +555,11 @@ static int imx6_pcie_attach_pd(struct device *dev) + + static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie) + { +- struct dw_pcie *pci = imx6_pcie->pci; +- struct device *dev = pci->dev; + unsigned int offset; + int ret = 0; + + switch (imx6_pcie->drvdata->variant) { + case IMX6SX: +- ret = clk_prepare_enable(imx6_pcie->pcie_inbound_axi); +- if (ret) { +- dev_err(dev, "unable to enable pcie_axi clock\n"); +- break; +- } +- + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, + IMX6SX_GPR12_PCIE_TEST_POWERDOWN, 0); + break; +@@ -589,12 +586,6 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie) + case IMX8MQ_EP: + case IMX8MP: + case IMX8MP_EP: +- ret = clk_prepare_enable(imx6_pcie->pcie_aux); +- if (ret) { +- dev_err(dev, "unable to enable pcie_aux clock\n"); +- break; +- } +- + offset = imx6_pcie_grp_offset(imx6_pcie); + /* + * Set the over ride low and enabled +@@ -615,9 +606,6 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie) + static void imx6_pcie_disable_ref_clk(struct imx6_pcie *imx6_pcie) + { + switch (imx6_pcie->drvdata->variant) { +- case IMX6SX: +- clk_disable_unprepare(imx6_pcie->pcie_inbound_axi); +- break; + case IMX6QP: + case IMX6Q: + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, +@@ -631,14 +619,6 @@ static void imx6_pcie_disable_ref_clk(struct imx6_pcie *imx6_pcie) + IMX7D_GPR12_PCIE_PHY_REFCLK_SEL, + IMX7D_GPR12_PCIE_PHY_REFCLK_SEL); + break; +- case IMX8MM: +- case IMX8MM_EP: +- case IMX8MQ: +- case IMX8MQ_EP: +- case IMX8MP: +- case IMX8MP_EP: +- clk_disable_unprepare(imx6_pcie->pcie_aux); +- break; + default: + break; + } +@@ -650,23 +630,9 @@ static int imx6_pcie_clk_enable(struct imx6_pcie *imx6_pcie) + struct device *dev = pci->dev; + int ret; + +- ret = clk_prepare_enable(imx6_pcie->pcie_phy); +- if (ret) { +- dev_err(dev, "unable to enable pcie_phy clock\n"); ++ ret = clk_bulk_prepare_enable(imx6_pcie->drvdata->clks_cnt, imx6_pcie->clks); ++ if (ret) + return ret; +- } +- +- ret = clk_prepare_enable(imx6_pcie->pcie_bus); +- if (ret) { +- dev_err(dev, "unable to enable pcie_bus clock\n"); +- goto err_pcie_bus; +- } +- +- ret = clk_prepare_enable(imx6_pcie->pcie); +- if (ret) { +- dev_err(dev, "unable to enable pcie clock\n"); +- goto err_pcie; +- } + + ret = imx6_pcie_enable_ref_clk(imx6_pcie); + if (ret) { +@@ -679,11 +645,7 @@ static int imx6_pcie_clk_enable(struct imx6_pcie *imx6_pcie) + return 0; + + err_ref_clk: +- clk_disable_unprepare(imx6_pcie->pcie); +-err_pcie: +- clk_disable_unprepare(imx6_pcie->pcie_bus); +-err_pcie_bus: +- clk_disable_unprepare(imx6_pcie->pcie_phy); ++ clk_bulk_disable_unprepare(imx6_pcie->drvdata->clks_cnt, imx6_pcie->clks); + + return ret; + } +@@ -691,9 +653,7 @@ static int imx6_pcie_clk_enable(struct imx6_pcie *imx6_pcie) + static void imx6_pcie_clk_disable(struct imx6_pcie *imx6_pcie) + { + imx6_pcie_disable_ref_clk(imx6_pcie); +- clk_disable_unprepare(imx6_pcie->pcie); +- clk_disable_unprepare(imx6_pcie->pcie_bus); +- clk_disable_unprepare(imx6_pcie->pcie_phy); ++ clk_bulk_disable_unprepare(imx6_pcie->drvdata->clks_cnt, imx6_pcie->clks); + } + + static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie) +@@ -1253,6 +1213,7 @@ static int imx6_pcie_probe(struct platform_device *pdev) + struct device_node *node = dev->of_node; + int ret; + u16 val; ++ int i; + + imx6_pcie = devm_kzalloc(dev, sizeof(*imx6_pcie), GFP_KERNEL); + if (!imx6_pcie) +@@ -1306,33 +1267,20 @@ static int imx6_pcie_probe(struct platform_device *pdev) + return imx6_pcie->reset_gpio; + } + +- /* Fetch clocks */ +- imx6_pcie->pcie_bus = devm_clk_get(dev, "pcie_bus"); +- if (IS_ERR(imx6_pcie->pcie_bus)) +- return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_bus), +- "pcie_bus clock source missing or invalid\n"); ++ if (imx6_pcie->drvdata->clks_cnt >= IMX6_PCIE_MAX_CLKS) ++ return dev_err_probe(dev, -ENOMEM, "clks_cnt is too big\n"); ++ ++ for (i = 0; i < imx6_pcie->drvdata->clks_cnt; i++) ++ imx6_pcie->clks[i].id = imx6_pcie->drvdata->clk_names[i]; + +- imx6_pcie->pcie = devm_clk_get(dev, "pcie"); +- if (IS_ERR(imx6_pcie->pcie)) +- return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie), +- "pcie clock source missing or invalid\n"); ++ /* Fetch clocks */ ++ ret = devm_clk_bulk_get(dev, imx6_pcie->drvdata->clks_cnt, imx6_pcie->clks); ++ if (ret) ++ return ret; + + switch (imx6_pcie->drvdata->variant) { +- case IMX6SX: +- imx6_pcie->pcie_inbound_axi = devm_clk_get(dev, +- "pcie_inbound_axi"); +- if (IS_ERR(imx6_pcie->pcie_inbound_axi)) +- return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_inbound_axi), +- "pcie_inbound_axi clock missing or invalid\n"); +- break; + case IMX8MQ: + case IMX8MQ_EP: +- imx6_pcie->pcie_aux = devm_clk_get(dev, "pcie_aux"); +- if (IS_ERR(imx6_pcie->pcie_aux)) +- return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_aux), +- "pcie_aux clock source missing or invalid\n"); +- fallthrough; +- case IMX7D: + if (dbi_base->start == IMX8MQ_PCIE2_BASE_ADDR) + imx6_pcie->controller_id = 1; + +@@ -1354,10 +1302,6 @@ static int imx6_pcie_probe(struct platform_device *pdev) + case IMX8MM_EP: + case IMX8MP: + case IMX8MP_EP: +- imx6_pcie->pcie_aux = devm_clk_get(dev, "pcie_aux"); +- if (IS_ERR(imx6_pcie->pcie_aux)) +- return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_aux), +- "pcie_aux clock source missing or invalid\n"); + imx6_pcie->apps_reset = devm_reset_control_get_exclusive(dev, + "apps"); + if (IS_ERR(imx6_pcie->apps_reset)) +@@ -1373,14 +1317,6 @@ static int imx6_pcie_probe(struct platform_device *pdev) + default: + break; + } +- /* Don't fetch the pcie_phy clock, if it has abstract PHY driver */ +- if (imx6_pcie->phy == NULL) { +- imx6_pcie->pcie_phy = devm_clk_get(dev, "pcie_phy"); +- if (IS_ERR(imx6_pcie->pcie_phy)) +- return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_phy), +- "pcie_phy clock source missing or invalid\n"); +- } +- + + /* Grab turnoff reset */ + imx6_pcie->turnoff_reset = devm_reset_control_get_optional_exclusive(dev, "turnoff"); +@@ -1471,6 +1407,11 @@ static void imx6_pcie_shutdown(struct platform_device *pdev) + imx6_pcie_assert_core_reset(imx6_pcie); + } + ++static const char * const imx6q_clks[] = {"pcie_bus", "pcie", "pcie_phy"}; ++static const char * const imx8mm_clks[] = {"pcie_bus", "pcie", "pcie_aux"}; ++static const char * const imx8mq_clks[] = {"pcie_bus", "pcie", "pcie_phy", "pcie_aux"}; ++static const char * const imx6sx_clks[] = {"pcie_bus", "pcie", "pcie_phy", "pcie_inbound_axi"}; ++ + static const struct imx6_pcie_drvdata drvdata[] = { + [IMX6Q] = { + .variant = IMX6Q, +@@ -1478,6 +1419,8 @@ static const struct imx6_pcie_drvdata drvdata[] = { + IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE, + .dbi_length = 0x200, + .gpr = "fsl,imx6q-iomuxc-gpr", ++ .clk_names = imx6q_clks, ++ .clks_cnt = ARRAY_SIZE(imx6q_clks), + }, + [IMX6SX] = { + .variant = IMX6SX, +@@ -1485,6 +1428,8 @@ static const struct imx6_pcie_drvdata drvdata[] = { + IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE | + IMX6_PCIE_FLAG_SUPPORTS_SUSPEND, + .gpr = "fsl,imx6q-iomuxc-gpr", ++ .clk_names = imx6sx_clks, ++ .clks_cnt = ARRAY_SIZE(imx6sx_clks), + }, + [IMX6QP] = { + .variant = IMX6QP, +@@ -1493,40 +1438,56 @@ static const struct imx6_pcie_drvdata drvdata[] = { + IMX6_PCIE_FLAG_SUPPORTS_SUSPEND, + .dbi_length = 0x200, + .gpr = "fsl,imx6q-iomuxc-gpr", ++ .clk_names = imx6q_clks, ++ .clks_cnt = ARRAY_SIZE(imx6q_clks), + }, + [IMX7D] = { + .variant = IMX7D, + .flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND, + .gpr = "fsl,imx7d-iomuxc-gpr", ++ .clk_names = imx6q_clks, ++ .clks_cnt = ARRAY_SIZE(imx6q_clks), + }, + [IMX8MQ] = { + .variant = IMX8MQ, + .gpr = "fsl,imx8mq-iomuxc-gpr", ++ .clk_names = imx8mq_clks, ++ .clks_cnt = ARRAY_SIZE(imx8mq_clks), + }, + [IMX8MM] = { + .variant = IMX8MM, + .flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND, + .gpr = "fsl,imx8mm-iomuxc-gpr", ++ .clk_names = imx8mm_clks, ++ .clks_cnt = ARRAY_SIZE(imx8mm_clks), + }, + [IMX8MP] = { + .variant = IMX8MP, + .flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND, + .gpr = "fsl,imx8mp-iomuxc-gpr", ++ .clk_names = imx8mm_clks, ++ .clks_cnt = ARRAY_SIZE(imx8mm_clks), + }, + [IMX8MQ_EP] = { + .variant = IMX8MQ_EP, + .mode = DW_PCIE_EP_TYPE, + .gpr = "fsl,imx8mq-iomuxc-gpr", ++ .clk_names = imx8mq_clks, ++ .clks_cnt = ARRAY_SIZE(imx8mq_clks), + }, + [IMX8MM_EP] = { + .variant = IMX8MM_EP, + .mode = DW_PCIE_EP_TYPE, + .gpr = "fsl,imx8mm-iomuxc-gpr", ++ .clk_names = imx8mm_clks, ++ .clks_cnt = ARRAY_SIZE(imx8mm_clks), + }, + [IMX8MP_EP] = { + .variant = IMX8MP_EP, + .mode = DW_PCIE_EP_TYPE, + .gpr = "fsl,imx8mp-iomuxc-gpr", ++ .clk_names = imx8mm_clks, ++ .clks_cnt = ARRAY_SIZE(imx8mm_clks), + }, + }; + +diff --git a/drivers/pci/controller/pcie-rcar-ep.c b/drivers/pci/controller/pcie-rcar-ep.c +index f9682df1da6192..209719fb6ddcce 100644 +--- a/drivers/pci/controller/pcie-rcar-ep.c ++++ b/drivers/pci/controller/pcie-rcar-ep.c +@@ -107,7 +107,7 @@ static int rcar_pcie_parse_outbound_ranges(struct rcar_pcie_endpoint *ep, + } + if (!devm_request_mem_region(&pdev->dev, res->start, + resource_size(res), +- outbound_name)) { ++ res->name)) { + dev_err(pcie->dev, "Cannot request memory region %s.\n", + outbound_name); + return -EIO; +diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c +index 1f0d2b84296a34..ac1dae113f2d9f 100644 +--- a/drivers/pci/endpoint/functions/pci-epf-test.c ++++ b/drivers/pci/endpoint/functions/pci-epf-test.c +@@ -251,7 +251,7 @@ static int pci_epf_test_init_dma_chan(struct pci_epf_test *epf_test) + + fail_back_rx: + dma_release_channel(epf_test->dma_chan_rx); +- epf_test->dma_chan_tx = NULL; ++ epf_test->dma_chan_rx = NULL; + + fail_back_tx: + dma_cap_zero(mask); +@@ -361,8 +361,8 @@ static void pci_epf_test_copy(struct pci_epf_test *epf_test, + + ktime_get_ts64(&start); + if (reg->flags & FLAG_USE_DMA) { +- if (epf_test->dma_private) { +- dev_err(dev, "Cannot transfer data using DMA\n"); ++ if (!dma_has_cap(DMA_MEMCPY, epf_test->dma_chan_tx->device->cap_mask)) { ++ dev_err(dev, "DMA controller doesn't support MEMCPY\n"); + ret = -EINVAL; + goto err_map_addr; + } +diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c +index d06623c751f84e..3a82c6a613a3c9 100644 +--- a/drivers/pci/endpoint/pci-epc-core.c ++++ b/drivers/pci/endpoint/pci-epc-core.c +@@ -808,7 +808,7 @@ void devm_pci_epc_destroy(struct device *dev, struct pci_epc *epc) + { + int r; + +- r = devres_destroy(dev, devm_pci_epc_release, devm_pci_epc_match, ++ r = devres_release(dev, devm_pci_epc_release, devm_pci_epc_match, + epc); + dev_WARN_ONCE(dev, r, "couldn't find PCI EPC resource\n"); + } +diff --git a/drivers/pinctrl/nxp/pinctrl-s32cc.c b/drivers/pinctrl/nxp/pinctrl-s32cc.c +index f0cad2c501f766..08d80fb935b3ad 100644 +--- a/drivers/pinctrl/nxp/pinctrl-s32cc.c ++++ b/drivers/pinctrl/nxp/pinctrl-s32cc.c +@@ -735,9 +735,7 @@ static int s32_pinctrl_parse_groups(struct device_node *np, + struct s32_pin_group *grp, + struct s32_pinctrl_soc_info *info) + { +- const __be32 *p; + struct device *dev; +- struct property *prop; + unsigned int *pins, *sss; + int i, npins; + u32 pinmux; +@@ -768,7 +766,7 @@ static int s32_pinctrl_parse_groups(struct device_node *np, + return -ENOMEM; + + i = 0; +- of_property_for_each_u32(np, "pinmux", prop, p, pinmux) { ++ of_property_for_each_u32(np, "pinmux", pinmux) { + pins[i] = get_pin_no(pinmux); + sss[i] = get_pin_func(pinmux); + +diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c +index 86034c457c0436..75bff325a42519 100644 +--- a/drivers/pinctrl/pinctrl-amd.c ++++ b/drivers/pinctrl/pinctrl-amd.c +@@ -908,12 +908,13 @@ static bool amd_gpio_should_save(struct amd_gpio *gpio_dev, unsigned int pin) + return false; + } + +-static int amd_gpio_suspend(struct device *dev) ++static int amd_gpio_suspend_hibernate_common(struct device *dev, bool is_suspend) + { + struct amd_gpio *gpio_dev = dev_get_drvdata(dev); + struct pinctrl_desc *desc = gpio_dev->pctrl->desc; + unsigned long flags; + int i; ++ u32 wake_mask = is_suspend ? WAKE_SOURCE_SUSPEND : WAKE_SOURCE_HIBERNATE; + + for (i = 0; i < desc->npins; i++) { + int pin = desc->pins[i].number; +@@ -925,11 +926,11 @@ static int amd_gpio_suspend(struct device *dev) + gpio_dev->saved_regs[i] = readl(gpio_dev->base + pin * 4) & ~PIN_IRQ_PENDING; + + /* mask any interrupts not intended to be a wake source */ +- if (!(gpio_dev->saved_regs[i] & WAKE_SOURCE)) { ++ if (!(gpio_dev->saved_regs[i] & wake_mask)) { + writel(gpio_dev->saved_regs[i] & ~BIT(INTERRUPT_MASK_OFF), + gpio_dev->base + pin * 4); +- pm_pr_dbg("Disabling GPIO #%d interrupt for suspend.\n", +- pin); ++ pm_pr_dbg("Disabling GPIO #%d interrupt for %s.\n", ++ pin, is_suspend ? "suspend" : "hibernate"); + } + + raw_spin_unlock_irqrestore(&gpio_dev->lock, flags); +@@ -938,6 +939,16 @@ static int amd_gpio_suspend(struct device *dev) + return 0; + } + ++static int amd_gpio_suspend(struct device *dev) ++{ ++ return amd_gpio_suspend_hibernate_common(dev, true); ++} ++ ++static int amd_gpio_hibernate(struct device *dev) ++{ ++ return amd_gpio_suspend_hibernate_common(dev, false); ++} ++ + static int amd_gpio_resume(struct device *dev) + { + struct amd_gpio *gpio_dev = dev_get_drvdata(dev); +@@ -961,8 +972,12 @@ static int amd_gpio_resume(struct device *dev) + } + + static const struct dev_pm_ops amd_gpio_pm_ops = { +- SET_LATE_SYSTEM_SLEEP_PM_OPS(amd_gpio_suspend, +- amd_gpio_resume) ++ .suspend_late = amd_gpio_suspend, ++ .resume_early = amd_gpio_resume, ++ .freeze_late = amd_gpio_hibernate, ++ .thaw_early = amd_gpio_resume, ++ .poweroff_late = amd_gpio_hibernate, ++ .restore_early = amd_gpio_resume, + }; + #endif + +diff --git a/drivers/pinctrl/pinctrl-amd.h b/drivers/pinctrl/pinctrl-amd.h +index cf59089f277639..c9522c62d7910f 100644 +--- a/drivers/pinctrl/pinctrl-amd.h ++++ b/drivers/pinctrl/pinctrl-amd.h +@@ -80,10 +80,9 @@ + #define FUNCTION_MASK GENMASK(1, 0) + #define FUNCTION_INVALID GENMASK(7, 0) + +-#define WAKE_SOURCE (BIT(WAKE_CNTRL_OFF_S0I3) | \ +- BIT(WAKE_CNTRL_OFF_S3) | \ +- BIT(WAKE_CNTRL_OFF_S4) | \ +- BIT(WAKECNTRL_Z_OFF)) ++#define WAKE_SOURCE_SUSPEND (BIT(WAKE_CNTRL_OFF_S0I3) | \ ++ BIT(WAKE_CNTRL_OFF_S3)) ++#define WAKE_SOURCE_HIBERNATE BIT(WAKE_CNTRL_OFF_S4) + + struct amd_function { + const char *name; +diff --git a/drivers/pinctrl/pinctrl-k210.c b/drivers/pinctrl/pinctrl-k210.c +index 7c05dbf533e7a3..558fc2ad976fc8 100644 +--- a/drivers/pinctrl/pinctrl-k210.c ++++ b/drivers/pinctrl/pinctrl-k210.c +@@ -763,8 +763,6 @@ static int k210_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, + unsigned int *reserved_maps, + unsigned int *num_maps) + { +- struct property *prop; +- const __be32 *p; + int ret, pinmux_groups; + u32 pinmux_group; + unsigned long *configs = NULL; +@@ -797,7 +795,7 @@ static int k210_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, + if (ret < 0) + goto exit; + +- of_property_for_each_u32(np, "pinmux", prop, p, pinmux_group) { ++ of_property_for_each_u32(np, "pinmux", pinmux_group) { + const char *group_name, *func_name; + u32 pin = FIELD_GET(K210_PG_PIN, pinmux_group); + u32 func = FIELD_GET(K210_PG_FUNC, pinmux_group); +diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c +index 5e91def6078474..84121b125d90ed 100644 +--- a/drivers/pinctrl/stm32/pinctrl-stm32.c ++++ b/drivers/pinctrl/stm32/pinctrl-stm32.c +@@ -86,7 +86,6 @@ struct stm32_pinctrl_group { + + struct stm32_gpio_bank { + void __iomem *base; +- struct clk *clk; + struct reset_control *rstc; + spinlock_t lock; + struct gpio_chip gpio_chip; +@@ -108,6 +107,7 @@ struct stm32_pinctrl { + unsigned ngroups; + const char **grp_names; + struct stm32_gpio_bank *banks; ++ struct clk_bulk_data *clks; + unsigned nbanks; + const struct stm32_pinctrl_match_data *match_data; + struct irq_domain *domain; +@@ -1321,12 +1321,6 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode + if (IS_ERR(bank->base)) + return PTR_ERR(bank->base); + +- err = clk_prepare_enable(bank->clk); +- if (err) { +- dev_err(dev, "failed to prepare_enable clk (%d)\n", err); +- return err; +- } +- + bank->gpio_chip = stm32_gpio_template; + + fwnode_property_read_string(fwnode, "st,bank-name", &bank->gpio_chip.label); +@@ -1373,26 +1367,20 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode + bank->fwnode, &stm32_gpio_domain_ops, + bank); + +- if (!bank->domain) { +- err = -ENODEV; +- goto err_clk; +- } ++ if (!bank->domain) ++ return -ENODEV; + } + + names = devm_kcalloc(dev, npins, sizeof(char *), GFP_KERNEL); +- if (!names) { +- err = -ENOMEM; +- goto err_clk; +- } ++ if (!names) ++ return -ENOMEM; + + for (i = 0; i < npins; i++) { + stm32_pin = stm32_pctrl_get_desc_pin_from_gpio(pctl, bank, i); + if (stm32_pin && stm32_pin->pin.name) { + names[i] = devm_kasprintf(dev, GFP_KERNEL, "%s", stm32_pin->pin.name); +- if (!names[i]) { +- err = -ENOMEM; +- goto err_clk; +- } ++ if (!names[i]) ++ return -ENOMEM; + } else { + names[i] = NULL; + } +@@ -1403,15 +1391,11 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode + err = gpiochip_add_data(&bank->gpio_chip, bank); + if (err) { + dev_err(dev, "Failed to add gpiochip(%d)!\n", bank_nr); +- goto err_clk; ++ return err; + } + + dev_info(dev, "%s bank added\n", bank->gpio_chip.label); + return 0; +- +-err_clk: +- clk_disable_unprepare(bank->clk); +- return err; + } + + static struct irq_domain *stm32_pctrl_get_irq_domain(struct platform_device *pdev) +@@ -1634,6 +1618,11 @@ int stm32_pctl_probe(struct platform_device *pdev) + if (!pctl->banks) + return -ENOMEM; + ++ pctl->clks = devm_kcalloc(dev, banks, sizeof(*pctl->clks), ++ GFP_KERNEL); ++ if (!pctl->clks) ++ return -ENOMEM; ++ + i = 0; + for_each_gpiochip_node(dev, child) { + struct stm32_gpio_bank *bank = &pctl->banks[i]; +@@ -1645,24 +1634,27 @@ int stm32_pctl_probe(struct platform_device *pdev) + return -EPROBE_DEFER; + } + +- bank->clk = of_clk_get_by_name(np, NULL); +- if (IS_ERR(bank->clk)) { ++ pctl->clks[i].clk = of_clk_get_by_name(np, NULL); ++ if (IS_ERR(pctl->clks[i].clk)) { + fwnode_handle_put(child); +- return dev_err_probe(dev, PTR_ERR(bank->clk), ++ return dev_err_probe(dev, PTR_ERR(pctl->clks[i].clk), + "failed to get clk\n"); + } ++ pctl->clks[i].id = "pctl"; + i++; + } + ++ ret = clk_bulk_prepare_enable(banks, pctl->clks); ++ if (ret) { ++ dev_err(dev, "failed to prepare_enable clk (%d)\n", ret); ++ return ret; ++ } ++ + for_each_gpiochip_node(dev, child) { + ret = stm32_gpiolib_register_bank(pctl, child); + if (ret) { + fwnode_handle_put(child); +- +- for (i = 0; i < pctl->nbanks; i++) +- clk_disable_unprepare(pctl->banks[i].clk); +- +- return ret; ++ goto err_register; + } + + pctl->nbanks++; +@@ -1671,6 +1663,15 @@ int stm32_pctl_probe(struct platform_device *pdev) + dev_info(dev, "Pinctrl STM32 initialized\n"); + + return 0; ++err_register: ++ for (i = 0; i < pctl->nbanks; i++) { ++ struct stm32_gpio_bank *bank = &pctl->banks[i]; ++ ++ gpiochip_remove(&bank->gpio_chip); ++ } ++ ++ clk_bulk_disable_unprepare(banks, pctl->clks); ++ return ret; + } + + static int __maybe_unused stm32_pinctrl_restore_gpio_regs( +@@ -1739,10 +1740,8 @@ static int __maybe_unused stm32_pinctrl_restore_gpio_regs( + int __maybe_unused stm32_pinctrl_suspend(struct device *dev) + { + struct stm32_pinctrl *pctl = dev_get_drvdata(dev); +- int i; + +- for (i = 0; i < pctl->nbanks; i++) +- clk_disable(pctl->banks[i].clk); ++ clk_bulk_disable(pctl->nbanks, pctl->clks); + + return 0; + } +@@ -1751,10 +1750,11 @@ int __maybe_unused stm32_pinctrl_resume(struct device *dev) + { + struct stm32_pinctrl *pctl = dev_get_drvdata(dev); + struct stm32_pinctrl_group *g = pctl->groups; +- int i; ++ int i, ret; + +- for (i = 0; i < pctl->nbanks; i++) +- clk_enable(pctl->banks[i].clk); ++ ret = clk_bulk_enable(pctl->nbanks, pctl->clks); ++ if (ret) ++ return ret; + + for (i = 0; i < pctl->ngroups; i++, g++) + stm32_pinctrl_restore_gpio_regs(pctl, g->pin); +diff --git a/drivers/pps/clients/pps-gpio.c b/drivers/pps/clients/pps-gpio.c +index 2f4b11b4dfcd91..bf3b6f1aa98425 100644 +--- a/drivers/pps/clients/pps-gpio.c ++++ b/drivers/pps/clients/pps-gpio.c +@@ -214,8 +214,8 @@ static int pps_gpio_probe(struct platform_device *pdev) + return -EINVAL; + } + +- dev_info(data->pps->dev, "Registered IRQ %d as PPS source\n", +- data->irq); ++ dev_dbg(&data->pps->dev, "Registered IRQ %d as PPS source\n", ++ data->irq); + + return 0; + } +diff --git a/drivers/pps/clients/pps-ktimer.c b/drivers/pps/clients/pps-ktimer.c +index d33106bd7a290f..2f465549b843f7 100644 +--- a/drivers/pps/clients/pps-ktimer.c ++++ b/drivers/pps/clients/pps-ktimer.c +@@ -56,7 +56,7 @@ static struct pps_source_info pps_ktimer_info = { + + static void __exit pps_ktimer_exit(void) + { +- dev_info(pps->dev, "ktimer PPS source unregistered\n"); ++ dev_dbg(&pps->dev, "ktimer PPS source unregistered\n"); + + del_timer_sync(&ktimer); + pps_unregister_source(pps); +@@ -74,7 +74,7 @@ static int __init pps_ktimer_init(void) + timer_setup(&ktimer, pps_ktimer_event, 0); + mod_timer(&ktimer, jiffies + HZ); + +- dev_info(pps->dev, "ktimer PPS source registered\n"); ++ dev_dbg(&pps->dev, "ktimer PPS source registered\n"); + + return 0; + } +diff --git a/drivers/pps/clients/pps-ldisc.c b/drivers/pps/clients/pps-ldisc.c +index 443d6bae19d14d..fa5660f3c4b707 100644 +--- a/drivers/pps/clients/pps-ldisc.c ++++ b/drivers/pps/clients/pps-ldisc.c +@@ -32,7 +32,7 @@ static void pps_tty_dcd_change(struct tty_struct *tty, bool active) + pps_event(pps, &ts, active ? PPS_CAPTUREASSERT : + PPS_CAPTURECLEAR, NULL); + +- dev_dbg(pps->dev, "PPS %s at %lu\n", ++ dev_dbg(&pps->dev, "PPS %s at %lu\n", + active ? "assert" : "clear", jiffies); + } + +@@ -69,7 +69,7 @@ static int pps_tty_open(struct tty_struct *tty) + goto err_unregister; + } + +- dev_info(pps->dev, "source \"%s\" added\n", info.path); ++ dev_dbg(&pps->dev, "source \"%s\" added\n", info.path); + + return 0; + +@@ -89,7 +89,7 @@ static void pps_tty_close(struct tty_struct *tty) + if (WARN_ON(!pps)) + return; + +- dev_info(pps->dev, "removed\n"); ++ dev_info(&pps->dev, "removed\n"); + pps_unregister_source(pps); + } + +diff --git a/drivers/pps/clients/pps_parport.c b/drivers/pps/clients/pps_parport.c +index 53e9c304ae0a7a..c3f46efd64c324 100644 +--- a/drivers/pps/clients/pps_parport.c ++++ b/drivers/pps/clients/pps_parport.c +@@ -81,7 +81,7 @@ static void parport_irq(void *handle) + /* check the signal (no signal means the pulse is lost this time) */ + if (!signal_is_set(port)) { + local_irq_restore(flags); +- dev_err(dev->pps->dev, "lost the signal\n"); ++ dev_err(&dev->pps->dev, "lost the signal\n"); + goto out_assert; + } + +@@ -98,7 +98,7 @@ static void parport_irq(void *handle) + /* timeout */ + dev->cw_err++; + if (dev->cw_err >= CLEAR_WAIT_MAX_ERRORS) { +- dev_err(dev->pps->dev, "disabled clear edge capture after %d" ++ dev_err(&dev->pps->dev, "disabled clear edge capture after %d" + " timeouts\n", dev->cw_err); + dev->cw = 0; + dev->cw_err = 0; +diff --git a/drivers/pps/kapi.c b/drivers/pps/kapi.c +index d9d566f70ed199..92d1b62ea239d7 100644 +--- a/drivers/pps/kapi.c ++++ b/drivers/pps/kapi.c +@@ -41,7 +41,7 @@ static void pps_add_offset(struct pps_ktime *ts, struct pps_ktime *offset) + static void pps_echo_client_default(struct pps_device *pps, int event, + void *data) + { +- dev_info(pps->dev, "echo %s %s\n", ++ dev_info(&pps->dev, "echo %s %s\n", + event & PPS_CAPTUREASSERT ? "assert" : "", + event & PPS_CAPTURECLEAR ? "clear" : ""); + } +@@ -112,7 +112,7 @@ struct pps_device *pps_register_source(struct pps_source_info *info, + goto kfree_pps; + } + +- dev_info(pps->dev, "new PPS source %s\n", info->name); ++ dev_dbg(&pps->dev, "new PPS source %s\n", info->name); + + return pps; + +@@ -166,7 +166,7 @@ void pps_event(struct pps_device *pps, struct pps_event_time *ts, int event, + /* check event type */ + BUG_ON((event & (PPS_CAPTUREASSERT | PPS_CAPTURECLEAR)) == 0); + +- dev_dbg(pps->dev, "PPS event at %lld.%09ld\n", ++ dev_dbg(&pps->dev, "PPS event at %lld.%09ld\n", + (s64)ts->ts_real.tv_sec, ts->ts_real.tv_nsec); + + timespec_to_pps_ktime(&ts_real, ts->ts_real); +@@ -188,7 +188,7 @@ void pps_event(struct pps_device *pps, struct pps_event_time *ts, int event, + /* Save the time stamp */ + pps->assert_tu = ts_real; + pps->assert_sequence++; +- dev_dbg(pps->dev, "capture assert seq #%u\n", ++ dev_dbg(&pps->dev, "capture assert seq #%u\n", + pps->assert_sequence); + + captured = ~0; +@@ -202,7 +202,7 @@ void pps_event(struct pps_device *pps, struct pps_event_time *ts, int event, + /* Save the time stamp */ + pps->clear_tu = ts_real; + pps->clear_sequence++; +- dev_dbg(pps->dev, "capture clear seq #%u\n", ++ dev_dbg(&pps->dev, "capture clear seq #%u\n", + pps->clear_sequence); + + captured = ~0; +diff --git a/drivers/pps/kc.c b/drivers/pps/kc.c +index 50dc59af45be24..fbd23295afd7d9 100644 +--- a/drivers/pps/kc.c ++++ b/drivers/pps/kc.c +@@ -43,11 +43,11 @@ int pps_kc_bind(struct pps_device *pps, struct pps_bind_args *bind_args) + pps_kc_hardpps_mode = 0; + pps_kc_hardpps_dev = NULL; + spin_unlock_irq(&pps_kc_hardpps_lock); +- dev_info(pps->dev, "unbound kernel" ++ dev_info(&pps->dev, "unbound kernel" + " consumer\n"); + } else { + spin_unlock_irq(&pps_kc_hardpps_lock); +- dev_err(pps->dev, "selected kernel consumer" ++ dev_err(&pps->dev, "selected kernel consumer" + " is not bound\n"); + return -EINVAL; + } +@@ -57,11 +57,11 @@ int pps_kc_bind(struct pps_device *pps, struct pps_bind_args *bind_args) + pps_kc_hardpps_mode = bind_args->edge; + pps_kc_hardpps_dev = pps; + spin_unlock_irq(&pps_kc_hardpps_lock); +- dev_info(pps->dev, "bound kernel consumer: " ++ dev_info(&pps->dev, "bound kernel consumer: " + "edge=0x%x\n", bind_args->edge); + } else { + spin_unlock_irq(&pps_kc_hardpps_lock); +- dev_err(pps->dev, "another kernel consumer" ++ dev_err(&pps->dev, "another kernel consumer" + " is already bound\n"); + return -EINVAL; + } +@@ -83,7 +83,7 @@ void pps_kc_remove(struct pps_device *pps) + pps_kc_hardpps_mode = 0; + pps_kc_hardpps_dev = NULL; + spin_unlock_irq(&pps_kc_hardpps_lock); +- dev_info(pps->dev, "unbound kernel consumer" ++ dev_info(&pps->dev, "unbound kernel consumer" + " on device removal\n"); + } else + spin_unlock_irq(&pps_kc_hardpps_lock); +diff --git a/drivers/pps/pps.c b/drivers/pps/pps.c +index 5d19baae6a380a..63f96357eb9fd8 100644 +--- a/drivers/pps/pps.c ++++ b/drivers/pps/pps.c +@@ -25,7 +25,7 @@ + * Local variables + */ + +-static dev_t pps_devt; ++static int pps_major; + static struct class *pps_class; + + static DEFINE_MUTEX(pps_idr_lock); +@@ -62,7 +62,7 @@ static int pps_cdev_pps_fetch(struct pps_device *pps, struct pps_fdata *fdata) + else { + unsigned long ticks; + +- dev_dbg(pps->dev, "timeout %lld.%09d\n", ++ dev_dbg(&pps->dev, "timeout %lld.%09d\n", + (long long) fdata->timeout.sec, + fdata->timeout.nsec); + ticks = fdata->timeout.sec * HZ; +@@ -80,7 +80,7 @@ static int pps_cdev_pps_fetch(struct pps_device *pps, struct pps_fdata *fdata) + + /* Check for pending signals */ + if (err == -ERESTARTSYS) { +- dev_dbg(pps->dev, "pending signal caught\n"); ++ dev_dbg(&pps->dev, "pending signal caught\n"); + return -EINTR; + } + +@@ -98,7 +98,7 @@ static long pps_cdev_ioctl(struct file *file, + + switch (cmd) { + case PPS_GETPARAMS: +- dev_dbg(pps->dev, "PPS_GETPARAMS\n"); ++ dev_dbg(&pps->dev, "PPS_GETPARAMS\n"); + + spin_lock_irq(&pps->lock); + +@@ -114,7 +114,7 @@ static long pps_cdev_ioctl(struct file *file, + break; + + case PPS_SETPARAMS: +- dev_dbg(pps->dev, "PPS_SETPARAMS\n"); ++ dev_dbg(&pps->dev, "PPS_SETPARAMS\n"); + + /* Check the capabilities */ + if (!capable(CAP_SYS_TIME)) +@@ -124,14 +124,14 @@ static long pps_cdev_ioctl(struct file *file, + if (err) + return -EFAULT; + if (!(params.mode & (PPS_CAPTUREASSERT | PPS_CAPTURECLEAR))) { +- dev_dbg(pps->dev, "capture mode unspecified (%x)\n", ++ dev_dbg(&pps->dev, "capture mode unspecified (%x)\n", + params.mode); + return -EINVAL; + } + + /* Check for supported capabilities */ + if ((params.mode & ~pps->info.mode) != 0) { +- dev_dbg(pps->dev, "unsupported capabilities (%x)\n", ++ dev_dbg(&pps->dev, "unsupported capabilities (%x)\n", + params.mode); + return -EINVAL; + } +@@ -144,7 +144,7 @@ static long pps_cdev_ioctl(struct file *file, + /* Restore the read only parameters */ + if ((params.mode & (PPS_TSFMT_TSPEC | PPS_TSFMT_NTPFP)) == 0) { + /* section 3.3 of RFC 2783 interpreted */ +- dev_dbg(pps->dev, "time format unspecified (%x)\n", ++ dev_dbg(&pps->dev, "time format unspecified (%x)\n", + params.mode); + pps->params.mode |= PPS_TSFMT_TSPEC; + } +@@ -165,7 +165,7 @@ static long pps_cdev_ioctl(struct file *file, + break; + + case PPS_GETCAP: +- dev_dbg(pps->dev, "PPS_GETCAP\n"); ++ dev_dbg(&pps->dev, "PPS_GETCAP\n"); + + err = put_user(pps->info.mode, iuarg); + if (err) +@@ -176,7 +176,7 @@ static long pps_cdev_ioctl(struct file *file, + case PPS_FETCH: { + struct pps_fdata fdata; + +- dev_dbg(pps->dev, "PPS_FETCH\n"); ++ dev_dbg(&pps->dev, "PPS_FETCH\n"); + + err = copy_from_user(&fdata, uarg, sizeof(struct pps_fdata)); + if (err) +@@ -206,7 +206,7 @@ static long pps_cdev_ioctl(struct file *file, + case PPS_KC_BIND: { + struct pps_bind_args bind_args; + +- dev_dbg(pps->dev, "PPS_KC_BIND\n"); ++ dev_dbg(&pps->dev, "PPS_KC_BIND\n"); + + /* Check the capabilities */ + if (!capable(CAP_SYS_TIME)) +@@ -218,7 +218,7 @@ static long pps_cdev_ioctl(struct file *file, + + /* Check for supported capabilities */ + if ((bind_args.edge & ~pps->info.mode) != 0) { +- dev_err(pps->dev, "unsupported capabilities (%x)\n", ++ dev_err(&pps->dev, "unsupported capabilities (%x)\n", + bind_args.edge); + return -EINVAL; + } +@@ -227,7 +227,7 @@ static long pps_cdev_ioctl(struct file *file, + if (bind_args.tsformat != PPS_TSFMT_TSPEC || + (bind_args.edge & ~PPS_CAPTUREBOTH) != 0 || + bind_args.consumer != PPS_KC_HARDPPS) { +- dev_err(pps->dev, "invalid kernel consumer bind" ++ dev_err(&pps->dev, "invalid kernel consumer bind" + " parameters (%x)\n", bind_args.edge); + return -EINVAL; + } +@@ -259,7 +259,7 @@ static long pps_cdev_compat_ioctl(struct file *file, + struct pps_fdata fdata; + int err; + +- dev_dbg(pps->dev, "PPS_FETCH\n"); ++ dev_dbg(&pps->dev, "PPS_FETCH\n"); + + err = copy_from_user(&compat, uarg, sizeof(struct pps_fdata_compat)); + if (err) +@@ -296,20 +296,36 @@ static long pps_cdev_compat_ioctl(struct file *file, + #define pps_cdev_compat_ioctl NULL + #endif + ++static struct pps_device *pps_idr_get(unsigned long id) ++{ ++ struct pps_device *pps; ++ ++ mutex_lock(&pps_idr_lock); ++ pps = idr_find(&pps_idr, id); ++ if (pps) ++ get_device(&pps->dev); ++ ++ mutex_unlock(&pps_idr_lock); ++ return pps; ++} ++ + static int pps_cdev_open(struct inode *inode, struct file *file) + { +- struct pps_device *pps = container_of(inode->i_cdev, +- struct pps_device, cdev); ++ struct pps_device *pps = pps_idr_get(iminor(inode)); ++ ++ if (!pps) ++ return -ENODEV; ++ + file->private_data = pps; +- kobject_get(&pps->dev->kobj); + return 0; + } + + static int pps_cdev_release(struct inode *inode, struct file *file) + { +- struct pps_device *pps = container_of(inode->i_cdev, +- struct pps_device, cdev); +- kobject_put(&pps->dev->kobj); ++ struct pps_device *pps = file->private_data; ++ ++ WARN_ON(pps->id != iminor(inode)); ++ put_device(&pps->dev); + return 0; + } + +@@ -332,22 +348,13 @@ static void pps_device_destruct(struct device *dev) + { + struct pps_device *pps = dev_get_drvdata(dev); + +- cdev_del(&pps->cdev); +- +- /* Now we can release the ID for re-use */ + pr_debug("deallocating pps%d\n", pps->id); +- mutex_lock(&pps_idr_lock); +- idr_remove(&pps_idr, pps->id); +- mutex_unlock(&pps_idr_lock); +- +- kfree(dev); + kfree(pps); + } + + int pps_register_cdev(struct pps_device *pps) + { + int err; +- dev_t devt; + + mutex_lock(&pps_idr_lock); + /* +@@ -364,40 +371,29 @@ int pps_register_cdev(struct pps_device *pps) + goto out_unlock; + } + pps->id = err; +- mutex_unlock(&pps_idr_lock); +- +- devt = MKDEV(MAJOR(pps_devt), pps->id); +- +- cdev_init(&pps->cdev, &pps_cdev_fops); +- pps->cdev.owner = pps->info.owner; + +- err = cdev_add(&pps->cdev, devt, 1); +- if (err) { +- pr_err("%s: failed to add char device %d:%d\n", +- pps->info.name, MAJOR(pps_devt), pps->id); ++ pps->dev.class = pps_class; ++ pps->dev.parent = pps->info.dev; ++ pps->dev.devt = MKDEV(pps_major, pps->id); ++ dev_set_drvdata(&pps->dev, pps); ++ dev_set_name(&pps->dev, "pps%d", pps->id); ++ err = device_register(&pps->dev); ++ if (err) + goto free_idr; +- } +- pps->dev = device_create(pps_class, pps->info.dev, devt, pps, +- "pps%d", pps->id); +- if (IS_ERR(pps->dev)) { +- err = PTR_ERR(pps->dev); +- goto del_cdev; +- } + + /* Override the release function with our own */ +- pps->dev->release = pps_device_destruct; ++ pps->dev.release = pps_device_destruct; + +- pr_debug("source %s got cdev (%d:%d)\n", pps->info.name, +- MAJOR(pps_devt), pps->id); ++ pr_debug("source %s got cdev (%d:%d)\n", pps->info.name, pps_major, ++ pps->id); + ++ get_device(&pps->dev); ++ mutex_unlock(&pps_idr_lock); + return 0; + +-del_cdev: +- cdev_del(&pps->cdev); +- + free_idr: +- mutex_lock(&pps_idr_lock); + idr_remove(&pps_idr, pps->id); ++ put_device(&pps->dev); + out_unlock: + mutex_unlock(&pps_idr_lock); + return err; +@@ -407,7 +403,13 @@ void pps_unregister_cdev(struct pps_device *pps) + { + pr_debug("unregistering pps%d\n", pps->id); + pps->lookup_cookie = NULL; +- device_destroy(pps_class, pps->dev->devt); ++ device_destroy(pps_class, pps->dev.devt); ++ ++ /* Now we can release the ID for re-use */ ++ mutex_lock(&pps_idr_lock); ++ idr_remove(&pps_idr, pps->id); ++ put_device(&pps->dev); ++ mutex_unlock(&pps_idr_lock); + } + + /* +@@ -427,6 +429,11 @@ void pps_unregister_cdev(struct pps_device *pps) + * so that it will not be used again, even if the pps device cannot + * be removed from the idr due to pending references holding the minor + * number in use. ++ * ++ * Since pps_idr holds a reference to the device, the returned ++ * pps_device is guaranteed to be valid until pps_unregister_cdev() is ++ * called on it. But after calling pps_unregister_cdev(), it may be ++ * freed at any time. + */ + struct pps_device *pps_lookup_dev(void const *cookie) + { +@@ -449,13 +456,11 @@ EXPORT_SYMBOL(pps_lookup_dev); + static void __exit pps_exit(void) + { + class_destroy(pps_class); +- unregister_chrdev_region(pps_devt, PPS_MAX_SOURCES); ++ __unregister_chrdev(pps_major, 0, PPS_MAX_SOURCES, "pps"); + } + + static int __init pps_init(void) + { +- int err; +- + pps_class = class_create("pps"); + if (IS_ERR(pps_class)) { + pr_err("failed to allocate class\n"); +@@ -463,8 +468,9 @@ static int __init pps_init(void) + } + pps_class->dev_groups = pps_groups; + +- err = alloc_chrdev_region(&pps_devt, 0, PPS_MAX_SOURCES, "pps"); +- if (err < 0) { ++ pps_major = __register_chrdev(0, 0, PPS_MAX_SOURCES, "pps", ++ &pps_cdev_fops); ++ if (pps_major < 0) { + pr_err("failed to allocate char device region\n"); + goto remove_class; + } +@@ -477,8 +483,7 @@ static int __init pps_init(void) + + remove_class: + class_destroy(pps_class); +- +- return err; ++ return pps_major; + } + + subsys_initcall(pps_init); +diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c +index 91cc6ffa0095e0..6f6019fb41c0c4 100644 +--- a/drivers/ptp/ptp_chardev.c ++++ b/drivers/ptp/ptp_chardev.c +@@ -4,6 +4,7 @@ + * + * Copyright (C) 2010 OMICRON electronics GmbH + */ ++#include + #include + #include + #include +@@ -124,6 +125,9 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg) + struct timespec64 ts; + int enable, err = 0; + ++ if (in_compat_syscall() && cmd != PTP_ENABLE_PPS && cmd != PTP_ENABLE_PPS2) ++ arg = (unsigned long)compat_ptr(arg); ++ + switch (cmd) { + + case PTP_CLOCK_GETCAPS: +diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c +index a7a6947ab4bc59..13343c31987706 100644 +--- a/drivers/ptp/ptp_ocp.c ++++ b/drivers/ptp/ptp_ocp.c +@@ -4055,7 +4055,7 @@ ptp_ocp_complete(struct ptp_ocp *bp) + + pps = pps_lookup_dev(bp->ptp); + if (pps) +- ptp_ocp_symlink(bp, pps->dev, "pps"); ++ ptp_ocp_symlink(bp, &pps->dev, "pps"); + + ptp_ocp_debugfs_add_device(bp); + +diff --git a/drivers/pwm/pwm-samsung.c b/drivers/pwm/pwm-samsung.c +index e8828f57ab1502..7d0966b07dffbf 100644 +--- a/drivers/pwm/pwm-samsung.c ++++ b/drivers/pwm/pwm-samsung.c +@@ -521,8 +521,6 @@ static int pwm_samsung_parse_dt(struct samsung_pwm_chip *chip) + { + struct device_node *np = chip->chip.dev->of_node; + const struct of_device_id *match; +- struct property *prop; +- const __be32 *cur; + u32 val; + + match = of_match_node(samsung_pwm_matches, np); +@@ -531,7 +529,7 @@ static int pwm_samsung_parse_dt(struct samsung_pwm_chip *chip) + + memcpy(&chip->variant, match->data, sizeof(chip->variant)); + +- of_property_for_each_u32(np, "samsung,pwm-outputs", prop, cur, val) { ++ of_property_for_each_u32(np, "samsung,pwm-outputs", val) { + if (val >= SAMSUNG_PWM_NUM) { + dev_err(chip->chip.dev, + "%s: invalid channel index in samsung,pwm-outputs property\n", +diff --git a/drivers/pwm/pwm-stm32-lp.c b/drivers/pwm/pwm-stm32-lp.c +index bb3a045a733430..7799258638dfa9 100644 +--- a/drivers/pwm/pwm-stm32-lp.c ++++ b/drivers/pwm/pwm-stm32-lp.c +@@ -168,8 +168,12 @@ static int stm32_pwm_lp_get_state(struct pwm_chip *chip, + regmap_read(priv->regmap, STM32_LPTIM_CR, &val); + state->enabled = !!FIELD_GET(STM32_LPTIM_ENABLE, val); + /* Keep PWM counter clock refcount in sync with PWM initial state */ +- if (state->enabled) +- clk_enable(priv->clk); ++ if (state->enabled) { ++ int ret = clk_enable(priv->clk); ++ ++ if (ret) ++ return ret; ++ } + + regmap_read(priv->regmap, STM32_LPTIM_CFGR, &val); + presc = FIELD_GET(STM32_LPTIM_PRESC, val); +diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c +index b91a14c895bea8..67414b97ef4d27 100644 +--- a/drivers/pwm/pwm-stm32.c ++++ b/drivers/pwm/pwm-stm32.c +@@ -635,8 +635,11 @@ static int stm32_pwm_probe(struct platform_device *pdev) + priv->chip.npwm = stm32_pwm_detect_channels(priv, &num_enabled); + + /* Initialize clock refcount to number of enabled PWM channels. */ +- for (i = 0; i < num_enabled; i++) +- clk_enable(priv->clk); ++ for (i = 0; i < num_enabled; i++) { ++ ret = clk_enable(priv->clk); ++ if (ret) ++ return ret; ++ } + + ret = devm_pwmchip_add(dev, &priv->chip); + if (ret < 0) +diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c +index c96bf095695fd8..352131d2df4cad 100644 +--- a/drivers/regulator/core.c ++++ b/drivers/regulator/core.c +@@ -4876,7 +4876,7 @@ int _regulator_bulk_get(struct device *dev, int num_consumers, + consumers[i].supply, get_type); + if (IS_ERR(consumers[i].consumer)) { + ret = dev_err_probe(dev, PTR_ERR(consumers[i].consumer), +- "Failed to get supply '%s'", ++ "Failed to get supply '%s'\n", + consumers[i].supply); + consumers[i].consumer = NULL; + goto err; +diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c +index 59e71fd0db4390..f23c12f4ffbfad 100644 +--- a/drivers/regulator/of_regulator.c ++++ b/drivers/regulator/of_regulator.c +@@ -435,7 +435,7 @@ int of_regulator_match(struct device *dev, struct device_node *node, + "failed to parse DT for regulator %pOFn\n", + child); + of_node_put(child); +- return -EINVAL; ++ goto err_put; + } + match->of_node = of_node_get(child); + count++; +@@ -444,6 +444,18 @@ int of_regulator_match(struct device *dev, struct device_node *node, + } + + return count; ++ ++err_put: ++ for (i = 0; i < num_matches; i++) { ++ struct of_regulator_match *match = &matches[i]; ++ ++ match->init_data = NULL; ++ if (match->of_node) { ++ of_node_put(match->of_node); ++ match->of_node = NULL; ++ } ++ } ++ return -EINVAL; + } + EXPORT_SYMBOL_GPL(of_regulator_match); + +diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c +index 695cce218e8c64..e230af51a99b9f 100644 +--- a/drivers/remoteproc/remoteproc_core.c ++++ b/drivers/remoteproc/remoteproc_core.c +@@ -2465,6 +2465,13 @@ struct rproc *rproc_alloc(struct device *dev, const char *name, + rproc->dev.driver_data = rproc; + idr_init(&rproc->notifyids); + ++ /* Assign a unique device index and name */ ++ rproc->index = ida_alloc(&rproc_dev_index, GFP_KERNEL); ++ if (rproc->index < 0) { ++ dev_err(dev, "ida_alloc failed: %d\n", rproc->index); ++ goto put_device; ++ } ++ + rproc->name = kstrdup_const(name, GFP_KERNEL); + if (!rproc->name) + goto put_device; +@@ -2475,13 +2482,6 @@ struct rproc *rproc_alloc(struct device *dev, const char *name, + if (rproc_alloc_ops(rproc, ops)) + goto put_device; + +- /* Assign a unique device index and name */ +- rproc->index = ida_alloc(&rproc_dev_index, GFP_KERNEL); +- if (rproc->index < 0) { +- dev_err(dev, "ida_alloc failed: %d\n", rproc->index); +- goto put_device; +- } +- + dev_set_name(&rproc->dev, "remoteproc%d", rproc->index); + + atomic_set(&rproc->power, 0); +diff --git a/drivers/rtc/rtc-loongson.c b/drivers/rtc/rtc-loongson.c +index e8ffc1ab90b02f..90e9d97a86b487 100644 +--- a/drivers/rtc/rtc-loongson.c ++++ b/drivers/rtc/rtc-loongson.c +@@ -114,6 +114,13 @@ static irqreturn_t loongson_rtc_isr(int irq, void *id) + struct loongson_rtc_priv *priv = (struct loongson_rtc_priv *)id; + + rtc_update_irq(priv->rtcdev, 1, RTC_AF | RTC_IRQF); ++ ++ /* ++ * The TOY_MATCH0_REG should be cleared 0 here, ++ * otherwise the interrupt cannot be cleared. ++ */ ++ regmap_write(priv->regmap, TOY_MATCH0_REG, 0); ++ + return IRQ_HANDLED; + } + +@@ -131,11 +138,7 @@ static u32 loongson_rtc_handler(void *id) + writel(RTC_STS, priv->pm_base + PM1_STS_REG); + spin_unlock(&priv->lock); + +- /* +- * The TOY_MATCH0_REG should be cleared 0 here, +- * otherwise the interrupt cannot be cleared. +- */ +- return regmap_write(priv->regmap, TOY_MATCH0_REG, 0); ++ return ACPI_INTERRUPT_HANDLED; + } + + static int loongson_rtc_set_enabled(struct device *dev) +diff --git a/drivers/rtc/rtc-pcf85063.c b/drivers/rtc/rtc-pcf85063.c +index fdbc07f14036af..905986c616559b 100644 +--- a/drivers/rtc/rtc-pcf85063.c ++++ b/drivers/rtc/rtc-pcf85063.c +@@ -322,7 +322,16 @@ static const struct rtc_class_ops pcf85063_rtc_ops = { + static int pcf85063_nvmem_read(void *priv, unsigned int offset, + void *val, size_t bytes) + { +- return regmap_read(priv, PCF85063_REG_RAM, val); ++ unsigned int tmp; ++ int ret; ++ ++ ret = regmap_read(priv, PCF85063_REG_RAM, &tmp); ++ if (ret < 0) ++ return ret; ++ ++ *(u8 *)val = tmp; ++ ++ return 0; + } + + static int pcf85063_nvmem_write(void *priv, unsigned int offset, +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c +index a5d12b95fbd09f..cd00f196703551 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.c +@@ -5638,8 +5638,7 @@ _base_static_config_pages(struct MPT3SAS_ADAPTER *ioc) + if (!ioc->is_gen35_ioc && ioc->manu_pg11.EEDPTagMode == 0) { + pr_err("%s: overriding NVDATA EEDPTagMode setting\n", + ioc->name); +- ioc->manu_pg11.EEDPTagMode &= ~0x3; +- ioc->manu_pg11.EEDPTagMode |= 0x1; ++ ioc->manu_pg11.EEDPTagMode = 0x1; + mpt3sas_config_set_manufacturing_pg11(ioc, &mpi_reply, + &ioc->manu_pg11); + } +diff --git a/drivers/soc/atmel/soc.c b/drivers/soc/atmel/soc.c +index cc9a3e107479ab..c892c7083ecc9c 100644 +--- a/drivers/soc/atmel/soc.c ++++ b/drivers/soc/atmel/soc.c +@@ -376,7 +376,7 @@ static const struct of_device_id at91_soc_allowed_list[] __initconst = { + + static int __init atmel_soc_device_init(void) + { +- struct device_node *np = of_find_node_by_path("/"); ++ struct device_node *np __free(device_node) = of_find_node_by_path("/"); + + if (!of_match_node(at91_soc_allowed_list, np)) + return 0; +diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c +index 3cfd262c1abc25..35ca8fda45aae3 100644 +--- a/drivers/spi/spi-omap2-mcspi.c ++++ b/drivers/spi/spi-omap2-mcspi.c +@@ -1521,10 +1521,15 @@ static int omap2_mcspi_probe(struct platform_device *pdev) + } + + mcspi->ref_clk = devm_clk_get_optional_enabled(&pdev->dev, NULL); +- if (IS_ERR(mcspi->ref_clk)) +- mcspi->ref_clk_hz = OMAP2_MCSPI_MAX_FREQ; +- else ++ if (IS_ERR(mcspi->ref_clk)) { ++ status = PTR_ERR(mcspi->ref_clk); ++ dev_err_probe(&pdev->dev, status, "Failed to get ref_clk"); ++ goto free_ctlr; ++ } ++ if (mcspi->ref_clk) + mcspi->ref_clk_hz = clk_get_rate(mcspi->ref_clk); ++ else ++ mcspi->ref_clk_hz = OMAP2_MCSPI_MAX_FREQ; + ctlr->max_speed_hz = mcspi->ref_clk_hz; + ctlr->min_speed_hz = mcspi->ref_clk_hz >> 15; + +diff --git a/drivers/spi/spi-zynq-qspi.c b/drivers/spi/spi-zynq-qspi.c +index 0db69a2a72ffcb..9358c75a30f440 100644 +--- a/drivers/spi/spi-zynq-qspi.c ++++ b/drivers/spi/spi-zynq-qspi.c +@@ -379,12 +379,21 @@ static int zynq_qspi_setup_op(struct spi_device *spi) + { + struct spi_controller *ctlr = spi->master; + struct zynq_qspi *qspi = spi_controller_get_devdata(ctlr); ++ int ret; + + if (ctlr->busy) + return -EBUSY; + +- clk_enable(qspi->refclk); +- clk_enable(qspi->pclk); ++ ret = clk_enable(qspi->refclk); ++ if (ret) ++ return ret; ++ ++ ret = clk_enable(qspi->pclk); ++ if (ret) { ++ clk_disable(qspi->refclk); ++ return ret; ++ } ++ + zynq_qspi_write(qspi, ZYNQ_QSPI_ENABLE_OFFSET, + ZYNQ_QSPI_ENABLE_ENABLE_MASK); + +diff --git a/drivers/staging/media/imx/imx-media-of.c b/drivers/staging/media/imx/imx-media-of.c +index 118bff988bc7e6..bb28daa4d71334 100644 +--- a/drivers/staging/media/imx/imx-media-of.c ++++ b/drivers/staging/media/imx/imx-media-of.c +@@ -54,22 +54,18 @@ int imx_media_add_of_subdevs(struct imx_media_dev *imxmd, + break; + + ret = imx_media_of_add_csi(imxmd, csi_np); ++ of_node_put(csi_np); + if (ret) { + /* unavailable or already added is not an error */ + if (ret == -ENODEV || ret == -EEXIST) { +- of_node_put(csi_np); + continue; + } + + /* other error, can't continue */ +- goto err_out; ++ return ret; + } + } + + return 0; +- +-err_out: +- of_node_put(csi_np); +- return ret; + } + EXPORT_SYMBOL_GPL(imx_media_add_of_subdevs); +diff --git a/drivers/staging/media/max96712/max96712.c b/drivers/staging/media/max96712/max96712.c +index c44145284aa18f..edaa311d2009e1 100644 +--- a/drivers/staging/media/max96712/max96712.c ++++ b/drivers/staging/media/max96712/max96712.c +@@ -402,7 +402,6 @@ static int max96712_probe(struct i2c_client *client) + return -ENOMEM; + + priv->client = client; +- i2c_set_clientdata(client, priv); + + priv->regmap = devm_regmap_init_i2c(client, &max96712_i2c_regmap); + if (IS_ERR(priv->regmap)) +@@ -435,7 +434,8 @@ static int max96712_probe(struct i2c_client *client) + + static void max96712_remove(struct i2c_client *client) + { +- struct max96712_priv *priv = i2c_get_clientdata(client); ++ struct v4l2_subdev *sd = i2c_get_clientdata(client); ++ struct max96712_priv *priv = container_of(sd, struct max96712_priv, sd); + + v4l2_async_unregister_subdev(&priv->sd); + +diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c +index a17803da83f8cd..2b1b2928ef7b7c 100644 +--- a/drivers/tty/serial/8250/8250_port.c ++++ b/drivers/tty/serial/8250/8250_port.c +@@ -2074,7 +2074,8 @@ static void serial8250_break_ctl(struct uart_port *port, int break_state) + serial8250_rpm_put(up); + } + +-static void wait_for_lsr(struct uart_8250_port *up, int bits) ++/* Returns true if @bits were set, false on timeout */ ++static bool wait_for_lsr(struct uart_8250_port *up, int bits) + { + unsigned int status, tmout = 10000; + +@@ -2089,11 +2090,11 @@ static void wait_for_lsr(struct uart_8250_port *up, int bits) + udelay(1); + touch_nmi_watchdog(); + } ++ ++ return (tmout != 0); + } + +-/* +- * Wait for transmitter & holding register to empty +- */ ++/* Wait for transmitter and holding register to empty with timeout */ + static void wait_for_xmitr(struct uart_8250_port *up, int bits) + { + unsigned int tmout; +@@ -3350,6 +3351,16 @@ static void serial8250_console_restore(struct uart_8250_port *up) + serial8250_out_MCR(up, up->mcr | UART_MCR_DTR | UART_MCR_RTS); + } + ++static void fifo_wait_for_lsr(struct uart_8250_port *up, unsigned int count) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < count; i++) { ++ if (wait_for_lsr(up, UART_LSR_THRE)) ++ return; ++ } ++} ++ + /* + * Print a string to the serial port using the device FIFO + * +@@ -3359,13 +3370,15 @@ static void serial8250_console_restore(struct uart_8250_port *up) + static void serial8250_console_fifo_write(struct uart_8250_port *up, + const char *s, unsigned int count) + { +- int i; + const char *end = s + count; + unsigned int fifosize = up->tx_loadsz; ++ unsigned int tx_count = 0; + bool cr_sent = false; ++ unsigned int i; + + while (s != end) { +- wait_for_lsr(up, UART_LSR_THRE); ++ /* Allow timeout for each byte of a possibly full FIFO */ ++ fifo_wait_for_lsr(up, fifosize); + + for (i = 0; i < fifosize && s != end; ++i) { + if (*s == '\n' && !cr_sent) { +@@ -3376,7 +3389,14 @@ static void serial8250_console_fifo_write(struct uart_8250_port *up, + cr_sent = false; + } + } ++ tx_count = i; + } ++ ++ /* ++ * Allow timeout for each byte written since the caller will only wait ++ * for UART_LSR_BOTH_EMPTY using the timeout of a single character ++ */ ++ fifo_wait_for_lsr(up, tx_count); + } + + /* +diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c +index f290fbe21d633e..8a2ce2ca6b394a 100644 +--- a/drivers/tty/serial/sc16is7xx.c ++++ b/drivers/tty/serial/sc16is7xx.c +@@ -1410,6 +1410,29 @@ static int sc16is7xx_setup_gpio_chip(struct sc16is7xx_port *s) + } + #endif + ++static void sc16is7xx_setup_irda_ports(struct sc16is7xx_port *s) ++{ ++ int i; ++ int ret; ++ int count; ++ u32 irda_port[2]; ++ struct device *dev = s->p[0].port.dev; ++ ++ count = device_property_count_u32(dev, "irda-mode-ports"); ++ if (count < 0 || count > ARRAY_SIZE(irda_port)) ++ return; ++ ++ ret = device_property_read_u32_array(dev, "irda-mode-ports", ++ irda_port, count); ++ if (ret) ++ return; ++ ++ for (i = 0; i < count; i++) { ++ if (irda_port[i] < s->devtype->nr_uart) ++ s->p[irda_port[i]].irda_mode = true; ++ } ++} ++ + /* + * Configure ports designated to operate as modem control lines. + */ +@@ -1603,16 +1626,7 @@ static int sc16is7xx_probe(struct device *dev, + sc16is7xx_power(&s->p[i].port, 0); + } + +- if (dev->of_node) { +- struct property *prop; +- const __be32 *p; +- u32 u; +- +- of_property_for_each_u32(dev->of_node, "irda-mode-ports", +- prop, p, u) +- if (u < devtype->nr_uart) +- s->p[u].irda_mode = true; +- } ++ sc16is7xx_setup_irda_ports(s); + + ret = sc16is7xx_setup_mctrl_ports(s, regmaps[0]); + if (ret) +diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c +index 6b4a28bcf2f5f5..5a314f5d7630a8 100644 +--- a/drivers/tty/sysrq.c ++++ b/drivers/tty/sysrq.c +@@ -759,8 +759,6 @@ static void sysrq_of_get_keyreset_config(void) + { + u32 key; + struct device_node *np; +- struct property *prop; +- const __be32 *p; + + np = of_find_node_by_path("/chosen/linux,sysrq-reset-seq"); + if (!np) { +@@ -771,7 +769,7 @@ static void sysrq_of_get_keyreset_config(void) + /* Reset in case a __weak definition was present */ + sysrq_reset_seq_len = 0; + +- of_property_for_each_u32(np, "keyset", prop, p, key) { ++ of_property_for_each_u32(np, "keyset", key) { + if (key == KEY_RESERVED || key > KEY_MAX || + sysrq_reset_seq_len == SYSRQ_KEY_RESET_MAX) + break; +diff --git a/drivers/ufs/core/ufs_bsg.c b/drivers/ufs/core/ufs_bsg.c +index fec5993c66c39a..f21423a7a6d7db 100644 +--- a/drivers/ufs/core/ufs_bsg.c ++++ b/drivers/ufs/core/ufs_bsg.c +@@ -256,6 +256,7 @@ int ufs_bsg_probe(struct ufs_hba *hba) + q = bsg_setup_queue(bsg_dev, dev_name(bsg_dev), ufs_bsg_request, NULL, 0); + if (IS_ERR(q)) { + ret = PTR_ERR(q); ++ device_del(bsg_dev); + goto out; + } + +diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c +index fcb509059d7c49..318ae24a41f482 100644 +--- a/drivers/usb/dwc3/core.c ++++ b/drivers/usb/dwc3/core.c +@@ -1505,8 +1505,6 @@ static void dwc3_get_properties(struct dwc3 *dwc) + u8 tx_thr_num_pkt_prd = 0; + u8 tx_max_burst_prd = 0; + u8 tx_fifo_resize_max_num; +- const char *usb_psy_name; +- int ret; + + /* default to highest possible threshold */ + lpm_nyet_threshold = 0xf; +@@ -1541,13 +1539,6 @@ static void dwc3_get_properties(struct dwc3 *dwc) + + dwc->sys_wakeup = device_may_wakeup(dwc->sysdev); + +- ret = device_property_read_string(dev, "usb-psy-name", &usb_psy_name); +- if (ret >= 0) { +- dwc->usb_psy = power_supply_get_by_name(usb_psy_name); +- if (!dwc->usb_psy) +- dev_err(dev, "couldn't get usb power supply\n"); +- } +- + dwc->has_lpm_erratum = device_property_read_bool(dev, + "snps,has-lpm-erratum"); + device_property_read_u8(dev, "snps,lpm-nyet-threshold", +@@ -1887,6 +1878,23 @@ static int dwc3_get_clocks(struct dwc3 *dwc) + return 0; + } + ++static struct power_supply *dwc3_get_usb_power_supply(struct dwc3 *dwc) ++{ ++ struct power_supply *usb_psy; ++ const char *usb_psy_name; ++ int ret; ++ ++ ret = device_property_read_string(dwc->dev, "usb-psy-name", &usb_psy_name); ++ if (ret < 0) ++ return NULL; ++ ++ usb_psy = power_supply_get_by_name(usb_psy_name); ++ if (!usb_psy) ++ return ERR_PTR(-EPROBE_DEFER); ++ ++ return usb_psy; ++} ++ + static int dwc3_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +@@ -1940,6 +1948,10 @@ static int dwc3_probe(struct platform_device *pdev) + + dwc3_get_properties(dwc); + ++ dwc->usb_psy = dwc3_get_usb_power_supply(dwc); ++ if (IS_ERR(dwc->usb_psy)) ++ return dev_err_probe(dev, PTR_ERR(dwc->usb_psy), "couldn't get usb power supply\n"); ++ + dwc->reset = devm_reset_control_array_get_optional_shared(dev); + if (IS_ERR(dwc->reset)) { + ret = PTR_ERR(dwc->reset); +diff --git a/drivers/usb/dwc3/dwc3-am62.c b/drivers/usb/dwc3/dwc3-am62.c +index 056ab7246a3a2c..47d9f56333fe8d 100644 +--- a/drivers/usb/dwc3/dwc3-am62.c ++++ b/drivers/usb/dwc3/dwc3-am62.c +@@ -160,6 +160,7 @@ static int phy_syscon_pll_refclk(struct dwc3_am62 *am62) + if (ret) + return ret; + ++ of_node_put(args.np); + am62->offset = args.args[0]; + + ret = regmap_update_bits(am62->syscon, am62->offset, PHY_PLL_REFCLK_MASK, am62->rate_code); +diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c +index 79ed2e6e576aab..8ac50b9155ac40 100644 +--- a/drivers/usb/gadget/function/f_tcm.c ++++ b/drivers/usb/gadget/function/f_tcm.c +@@ -1066,7 +1066,6 @@ static void usbg_cmd_work(struct work_struct *work) + out: + transport_send_check_condition_and_sense(se_cmd, + TCM_UNSUPPORTED_SCSI_OPCODE, 1); +- transport_generic_free_cmd(&cmd->se_cmd, 0); + } + + static struct usbg_cmd *usbg_get_cmd(struct f_uas *fu, +@@ -1195,7 +1194,6 @@ static void bot_cmd_work(struct work_struct *work) + out: + transport_send_check_condition_and_sense(se_cmd, + TCM_UNSUPPORTED_SCSI_OPCODE, 1); +- transport_generic_free_cmd(&cmd->se_cmd, 0); + } + + static int bot_submit_command(struct f_uas *fu, +@@ -2048,9 +2046,14 @@ static void tcm_delayed_set_alt(struct work_struct *wq) + + static int tcm_get_alt(struct usb_function *f, unsigned intf) + { +- if (intf == bot_intf_desc.bInterfaceNumber) ++ struct f_uas *fu = to_f_uas(f); ++ ++ if (fu->iface != intf) ++ return -EOPNOTSUPP; ++ ++ if (fu->flags & USBG_IS_BOT) + return USB_G_ALT_INT_BBB; +- if (intf == uasp_intf_desc.bInterfaceNumber) ++ else if (fu->flags & USBG_IS_UAS) + return USB_G_ALT_INT_UAS; + + return -EOPNOTSUPP; +@@ -2060,6 +2063,9 @@ static int tcm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) + { + struct f_uas *fu = to_f_uas(f); + ++ if (fu->iface != intf) ++ return -EOPNOTSUPP; ++ + if ((alt == USB_G_ALT_INT_BBB) || (alt == USB_G_ALT_INT_UAS)) { + struct guas_setup_wq *work; + +diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c +index 0d628af5c3ba50..4a081685a1953e 100644 +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -420,7 +420,8 @@ static void xhci_handle_stopped_cmd_ring(struct xhci_hcd *xhci, + if ((xhci->cmd_ring->dequeue != xhci->cmd_ring->enqueue) && + !(xhci->xhc_state & XHCI_STATE_DYING)) { + xhci->current_cmd = cur_cmd; +- xhci_mod_cmd_timer(xhci); ++ if (cur_cmd) ++ xhci_mod_cmd_timer(xhci); + xhci_ring_cmd_db(xhci); + } + } +diff --git a/drivers/usb/misc/usb251xb.c b/drivers/usb/misc/usb251xb.c +index 7da404f55a6d90..3970bf9ca818af 100644 +--- a/drivers/usb/misc/usb251xb.c ++++ b/drivers/usb/misc/usb251xb.c +@@ -382,11 +382,9 @@ static void usb251xb_get_ports_field(struct usb251xb *hub, + bool ds_only, u8 *fld) + { + struct device *dev = hub->dev; +- struct property *prop; +- const __be32 *p; + u32 port; + +- of_property_for_each_u32(dev->of_node, prop_name, prop, p, port) { ++ of_property_for_each_u32(dev->of_node, prop_name, port) { + if ((port >= ds_only ? 1 : 0) && (port <= port_cnt)) + *fld |= BIT(port); + else +diff --git a/drivers/usb/typec/tcpm/tcpci.c b/drivers/usb/typec/tcpm/tcpci.c +index 7118551827f6a2..31ce2071224562 100644 +--- a/drivers/usb/typec/tcpm/tcpci.c ++++ b/drivers/usb/typec/tcpm/tcpci.c +@@ -26,6 +26,7 @@ + #define VPPS_NEW_MIN_PERCENT 95 + #define VPPS_VALID_MIN_MV 100 + #define VSINKDISCONNECT_PD_MIN_PERCENT 90 ++#define VPPS_SHUTDOWN_MIN_PERCENT 85 + + struct tcpci { + struct device *dev; +@@ -337,7 +338,8 @@ static int tcpci_enable_auto_vbus_discharge(struct tcpc_dev *dev, bool enable) + } + + static int tcpci_set_auto_vbus_discharge_threshold(struct tcpc_dev *dev, enum typec_pwr_opmode mode, +- bool pps_active, u32 requested_vbus_voltage_mv) ++ bool pps_active, u32 requested_vbus_voltage_mv, ++ u32 apdo_min_voltage_mv) + { + struct tcpci *tcpci = tcpc_to_tcpci(dev); + unsigned int pwr_ctrl, threshold = 0; +@@ -359,9 +361,12 @@ static int tcpci_set_auto_vbus_discharge_threshold(struct tcpc_dev *dev, enum ty + threshold = AUTO_DISCHARGE_DEFAULT_THRESHOLD_MV; + } else if (mode == TYPEC_PWR_MODE_PD) { + if (pps_active) +- threshold = ((VPPS_NEW_MIN_PERCENT * requested_vbus_voltage_mv / 100) - +- VSINKPD_MIN_IR_DROP_MV - VPPS_VALID_MIN_MV) * +- VSINKDISCONNECT_PD_MIN_PERCENT / 100; ++ /* ++ * To prevent disconnect when the source is in Current Limit Mode. ++ * Set the threshold to the lowest possible voltage vPpsShutdown (min) ++ */ ++ threshold = VPPS_SHUTDOWN_MIN_PERCENT * apdo_min_voltage_mv / 100 - ++ VSINKPD_MIN_IR_DROP_MV; + else + threshold = ((VSRC_NEW_MIN_PERCENT * requested_vbus_voltage_mv / 100) - + VSINKPD_MIN_IR_DROP_MV - VSRC_VALID_MIN_MV) * +diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c +index e053b6e99b9e46..790aadab72a31b 100644 +--- a/drivers/usb/typec/tcpm/tcpm.c ++++ b/drivers/usb/typec/tcpm/tcpm.c +@@ -2326,10 +2326,12 @@ static int tcpm_set_auto_vbus_discharge_threshold(struct tcpm_port *port, + return 0; + + ret = port->tcpc->set_auto_vbus_discharge_threshold(port->tcpc, mode, pps_active, +- requested_vbus_voltage); ++ requested_vbus_voltage, ++ port->pps_data.min_volt); + tcpm_log_force(port, +- "set_auto_vbus_discharge_threshold mode:%d pps_active:%c vbus:%u ret:%d", +- mode, pps_active ? 'y' : 'n', requested_vbus_voltage, ret); ++ "set_auto_vbus_discharge_threshold mode:%d pps_active:%c vbus:%u pps_apdo_min_volt:%u ret:%d", ++ mode, pps_active ? 'y' : 'n', requested_vbus_voltage, ++ port->pps_data.min_volt, ret); + + return ret; + } +@@ -4065,7 +4067,7 @@ static void run_state_machine(struct tcpm_port *port) + port->caps_count = 0; + port->pd_capable = true; + tcpm_set_state_cond(port, SRC_SEND_CAPABILITIES_TIMEOUT, +- PD_T_SEND_SOURCE_CAP); ++ PD_T_SENDER_RESPONSE); + } + break; + case SRC_SEND_CAPABILITIES_TIMEOUT: +diff --git a/drivers/vfio/iova_bitmap.c b/drivers/vfio/iova_bitmap.c +index 7af5b204990bb5..38b51613ecca90 100644 +--- a/drivers/vfio/iova_bitmap.c ++++ b/drivers/vfio/iova_bitmap.c +@@ -127,7 +127,7 @@ struct iova_bitmap { + static unsigned long iova_bitmap_offset_to_index(struct iova_bitmap *bitmap, + unsigned long iova) + { +- unsigned long pgsize = 1 << bitmap->mapped.pgshift; ++ unsigned long pgsize = 1UL << bitmap->mapped.pgshift; + + return iova / (BITS_PER_TYPE(*bitmap->bitmap) * pgsize); + } +diff --git a/drivers/video/fbdev/omap2/omapfb/dss/dss-of.c b/drivers/video/fbdev/omap2/omapfb/dss/dss-of.c +index 0282d4eef139d4..3b16c3342cb77e 100644 +--- a/drivers/video/fbdev/omap2/omapfb/dss/dss-of.c ++++ b/drivers/video/fbdev/omap2/omapfb/dss/dss-of.c +@@ -102,6 +102,7 @@ struct device_node *dss_of_port_get_parent_device(struct device_node *port) + np = of_get_next_parent(np); + } + ++ of_node_put(np); + return NULL; + } + +diff --git a/drivers/watchdog/rti_wdt.c b/drivers/watchdog/rti_wdt.c +index 563d842014dfba..cc239251e19383 100644 +--- a/drivers/watchdog/rti_wdt.c ++++ b/drivers/watchdog/rti_wdt.c +@@ -301,6 +301,7 @@ static int rti_wdt_probe(struct platform_device *pdev) + node = of_parse_phandle(pdev->dev.of_node, "memory-region", 0); + if (node) { + ret = of_address_to_resource(node, 0, &res); ++ of_node_put(node); + if (ret) { + dev_err(dev, "No memory address assigned to the region.\n"); + goto err_iomap; +diff --git a/fs/afs/dir.c b/fs/afs/dir.c +index 897569e1d3a909..cdd2abdc8975d8 100644 +--- a/fs/afs/dir.c ++++ b/fs/afs/dir.c +@@ -1458,7 +1458,12 @@ static int afs_rmdir(struct inode *dir, struct dentry *dentry) + op->file[1].vnode = vnode; + } + +- return afs_do_sync_operation(op); ++ ret = afs_do_sync_operation(op); ++ ++ /* Not all systems that can host afs servers have ENOTEMPTY. */ ++ if (ret == -EEXIST) ++ ret = -ENOTEMPTY; ++ return ret; + + error: + return afs_put_operation(op); +diff --git a/fs/afs/internal.h b/fs/afs/internal.h +index 8dcc09cf0adbeb..2f135d19545b19 100644 +--- a/fs/afs/internal.h ++++ b/fs/afs/internal.h +@@ -1286,6 +1286,15 @@ extern void afs_send_simple_reply(struct afs_call *, const void *, size_t); + extern int afs_extract_data(struct afs_call *, bool); + extern int afs_protocol_error(struct afs_call *, enum afs_eproto_cause); + ++static inline void afs_see_call(struct afs_call *call, enum afs_call_trace why) ++{ ++ int r = refcount_read(&call->ref); ++ ++ trace_afs_call(call->debug_id, why, r, ++ atomic_read(&call->net->nr_outstanding_calls), ++ __builtin_return_address(0)); ++} ++ + static inline void afs_make_op_call(struct afs_operation *op, struct afs_call *call, + gfp_t gfp) + { +diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c +index d642d06a453be7..43154c70366ae1 100644 +--- a/fs/afs/rxrpc.c ++++ b/fs/afs/rxrpc.c +@@ -396,11 +396,16 @@ void afs_make_call(struct afs_addr_cursor *ac, struct afs_call *call, gfp_t gfp) + return; + + error_do_abort: +- if (ret != -ECONNABORTED) { ++ if (ret != -ECONNABORTED) + rxrpc_kernel_abort_call(call->net->socket, rxcall, + RX_USER_ABORT, ret, + afs_abort_send_data_error); +- } else { ++ if (call->async) { ++ afs_see_call(call, afs_call_trace_async_abort); ++ return; ++ } ++ ++ if (ret == -ECONNABORTED) { + len = 0; + iov_iter_kvec(&msg.msg_iter, ITER_DEST, NULL, 0, 0); + rxrpc_kernel_recv_data(call->net->socket, rxcall, +@@ -412,6 +417,8 @@ void afs_make_call(struct afs_addr_cursor *ac, struct afs_call *call, gfp_t gfp) + call->error = ret; + trace_afs_call_done(call); + error_kill_call: ++ if (call->async) ++ afs_see_call(call, afs_call_trace_async_kill); + if (call->type->done) + call->type->done(call); + +@@ -566,7 +573,6 @@ static void afs_deliver_to_call(struct afs_call *call) + abort_code = 0; + call_complete: + afs_set_call_complete(call, ret, remote_abort); +- state = AFS_CALL_COMPLETE; + goto done; + } + +diff --git a/fs/afs/xdr_fs.h b/fs/afs/xdr_fs.h +index 8ca8681645077d..cc5f143d21a347 100644 +--- a/fs/afs/xdr_fs.h ++++ b/fs/afs/xdr_fs.h +@@ -88,7 +88,7 @@ union afs_xdr_dir_block { + + struct { + struct afs_xdr_dir_hdr hdr; +- u8 alloc_ctrs[AFS_DIR_MAX_BLOCKS]; ++ u8 alloc_ctrs[AFS_DIR_BLOCKS_WITH_CTR]; + __be16 hashtable[AFS_DIR_HASHTBL_SIZE]; + } meta; + +diff --git a/fs/afs/yfsclient.c b/fs/afs/yfsclient.c +index 11571cca86c19a..01f333e691d644 100644 +--- a/fs/afs/yfsclient.c ++++ b/fs/afs/yfsclient.c +@@ -655,8 +655,9 @@ static int yfs_deliver_fs_remove_file2(struct afs_call *call) + static void yfs_done_fs_remove_file2(struct afs_call *call) + { + if (call->error == -ECONNABORTED && +- call->abort_code == RX_INVALID_OPERATION) { +- set_bit(AFS_SERVER_FL_NO_RM2, &call->server->flags); ++ (call->abort_code == RX_INVALID_OPERATION || ++ call->abort_code == RXGEN_OPCODE)) { ++ set_bit(AFS_SERVER_FL_NO_RM2, &call->op->server->flags); + call->op->flags |= AFS_OPERATION_DOWNGRADE; + } + } +diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c +index e33587a814098a..fb4992570c2b59 100644 +--- a/fs/btrfs/super.c ++++ b/fs/btrfs/super.c +@@ -1162,7 +1162,7 @@ static int btrfs_fill_super(struct super_block *sb, + + err = open_ctree(sb, fs_devices, (char *)data); + if (err) { +- btrfs_err(fs_info, "open_ctree failed"); ++ btrfs_err(fs_info, "open_ctree failed: %d", err); + return err; + } + +diff --git a/fs/buffer.c b/fs/buffer.c +index ecd8b47507ff80..4b86e971efd8a1 100644 +--- a/fs/buffer.c ++++ b/fs/buffer.c +@@ -1640,8 +1640,8 @@ EXPORT_SYMBOL(block_invalidate_folio); + * block_dirty_folio() via private_lock. try_to_free_buffers + * is already excluded via the folio lock. + */ +-void folio_create_empty_buffers(struct folio *folio, unsigned long blocksize, +- unsigned long b_state) ++struct buffer_head *folio_create_empty_buffers(struct folio *folio, ++ unsigned long blocksize, unsigned long b_state) + { + struct buffer_head *bh, *head, *tail; + +@@ -1667,6 +1667,8 @@ void folio_create_empty_buffers(struct folio *folio, unsigned long blocksize, + } + folio_attach_private(folio, head); + spin_unlock(&folio->mapping->private_lock); ++ ++ return head; + } + EXPORT_SYMBOL(folio_create_empty_buffers); + +@@ -1768,13 +1770,15 @@ static struct buffer_head *folio_create_buffers(struct folio *folio, + struct inode *inode, + unsigned int b_state) + { ++ struct buffer_head *bh; ++ + BUG_ON(!folio_test_locked(folio)); + +- if (!folio_buffers(folio)) +- folio_create_empty_buffers(folio, +- 1 << READ_ONCE(inode->i_blkbits), +- b_state); +- return folio_buffers(folio); ++ bh = folio_buffers(folio); ++ if (!bh) ++ bh = folio_create_empty_buffers(folio, ++ 1 << READ_ONCE(inode->i_blkbits), b_state); ++ return bh; + } + + /* +@@ -2678,10 +2682,8 @@ int block_truncate_page(struct address_space *mapping, + return PTR_ERR(folio); + + bh = folio_buffers(folio); +- if (!bh) { +- folio_create_empty_buffers(folio, blocksize, 0); +- bh = folio_buffers(folio); +- } ++ if (!bh) ++ bh = folio_create_empty_buffers(folio, blocksize, 0); + + /* Find the buffer that contains "offset" */ + offset = offset_in_folio(folio, from); +diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c +index 32dbd1a828d010..0618af36f5506b 100644 +--- a/fs/dlm/lowcomms.c ++++ b/fs/dlm/lowcomms.c +@@ -460,7 +460,8 @@ static bool dlm_lowcomms_con_has_addr(const struct connection *con, + int dlm_lowcomms_addr(int nodeid, struct sockaddr_storage *addr, int len) + { + struct connection *con; +- bool ret, idx; ++ bool ret; ++ int idx; + + idx = srcu_read_lock(&connections_srcu); + con = nodeid2con(nodeid, GFP_NOFS); +diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c +index 166ec8942595e1..13268d1f8c75a6 100644 +--- a/fs/f2fs/dir.c ++++ b/fs/f2fs/dir.c +@@ -166,7 +166,8 @@ static unsigned long dir_block_index(unsigned int level, + static struct f2fs_dir_entry *find_in_block(struct inode *dir, + struct page *dentry_page, + const struct f2fs_filename *fname, +- int *max_slots) ++ int *max_slots, ++ bool use_hash) + { + struct f2fs_dentry_block *dentry_blk; + struct f2fs_dentry_ptr d; +@@ -174,7 +175,7 @@ static struct f2fs_dir_entry *find_in_block(struct inode *dir, + dentry_blk = (struct f2fs_dentry_block *)page_address(dentry_page); + + make_dentry_ptr_block(dir, &d, dentry_blk); +- return f2fs_find_target_dentry(&d, fname, max_slots); ++ return f2fs_find_target_dentry(&d, fname, max_slots, use_hash); + } + + #if IS_ENABLED(CONFIG_UNICODE) +@@ -251,7 +252,8 @@ static inline int f2fs_match_name(const struct inode *dir, + } + + struct f2fs_dir_entry *f2fs_find_target_dentry(const struct f2fs_dentry_ptr *d, +- const struct f2fs_filename *fname, int *max_slots) ++ const struct f2fs_filename *fname, int *max_slots, ++ bool use_hash) + { + struct f2fs_dir_entry *de; + unsigned long bit_pos = 0; +@@ -274,7 +276,7 @@ struct f2fs_dir_entry *f2fs_find_target_dentry(const struct f2fs_dentry_ptr *d, + continue; + } + +- if (de->hash_code == fname->hash) { ++ if (!use_hash || de->hash_code == fname->hash) { + res = f2fs_match_name(d->inode, fname, + d->filename[bit_pos], + le16_to_cpu(de->name_len)); +@@ -301,11 +303,12 @@ struct f2fs_dir_entry *f2fs_find_target_dentry(const struct f2fs_dentry_ptr *d, + static struct f2fs_dir_entry *find_in_level(struct inode *dir, + unsigned int level, + const struct f2fs_filename *fname, +- struct page **res_page) ++ struct page **res_page, ++ bool use_hash) + { + int s = GET_DENTRY_SLOTS(fname->disk_name.len); + unsigned int nbucket, nblock; +- unsigned int bidx, end_block; ++ unsigned int bidx, end_block, bucket_no; + struct page *dentry_page; + struct f2fs_dir_entry *de = NULL; + pgoff_t next_pgofs; +@@ -315,8 +318,11 @@ static struct f2fs_dir_entry *find_in_level(struct inode *dir, + nbucket = dir_buckets(level, F2FS_I(dir)->i_dir_level); + nblock = bucket_blocks(level); + ++ bucket_no = use_hash ? le32_to_cpu(fname->hash) % nbucket : 0; ++ ++start_find_bucket: + bidx = dir_block_index(level, F2FS_I(dir)->i_dir_level, +- le32_to_cpu(fname->hash) % nbucket); ++ bucket_no); + end_block = bidx + nblock; + + while (bidx < end_block) { +@@ -333,7 +339,7 @@ static struct f2fs_dir_entry *find_in_level(struct inode *dir, + } + } + +- de = find_in_block(dir, dentry_page, fname, &max_slots); ++ de = find_in_block(dir, dentry_page, fname, &max_slots, use_hash); + if (IS_ERR(de)) { + *res_page = ERR_CAST(de); + de = NULL; +@@ -350,12 +356,18 @@ static struct f2fs_dir_entry *find_in_level(struct inode *dir, + bidx++; + } + +- if (!de && room && F2FS_I(dir)->chash != fname->hash) { +- F2FS_I(dir)->chash = fname->hash; +- F2FS_I(dir)->clevel = level; +- } ++ if (de) ++ return de; + +- return de; ++ if (likely(use_hash)) { ++ if (room && F2FS_I(dir)->chash != fname->hash) { ++ F2FS_I(dir)->chash = fname->hash; ++ F2FS_I(dir)->clevel = level; ++ } ++ } else if (++bucket_no < nbucket) { ++ goto start_find_bucket; ++ } ++ return NULL; + } + + struct f2fs_dir_entry *__f2fs_find_entry(struct inode *dir, +@@ -366,11 +378,15 @@ struct f2fs_dir_entry *__f2fs_find_entry(struct inode *dir, + struct f2fs_dir_entry *de = NULL; + unsigned int max_depth; + unsigned int level; ++ bool use_hash = true; + + *res_page = NULL; + ++#if IS_ENABLED(CONFIG_UNICODE) ++start_find_entry: ++#endif + if (f2fs_has_inline_dentry(dir)) { +- de = f2fs_find_in_inline_dir(dir, fname, res_page); ++ de = f2fs_find_in_inline_dir(dir, fname, res_page, use_hash); + goto out; + } + +@@ -386,11 +402,18 @@ struct f2fs_dir_entry *__f2fs_find_entry(struct inode *dir, + } + + for (level = 0; level < max_depth; level++) { +- de = find_in_level(dir, level, fname, res_page); ++ de = find_in_level(dir, level, fname, res_page, use_hash); + if (de || IS_ERR(*res_page)) + break; + } ++ + out: ++#if IS_ENABLED(CONFIG_UNICODE) ++ if (IS_CASEFOLDED(dir) && !de && use_hash) { ++ use_hash = false; ++ goto start_find_entry; ++ } ++#endif + /* This is to increase the speed of f2fs_create */ + if (!de) + F2FS_I(dir)->task = current; +diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h +index 33620642ae5ec8..d28e3df61cc4fd 100644 +--- a/fs/f2fs/f2fs.h ++++ b/fs/f2fs/f2fs.h +@@ -3531,7 +3531,8 @@ int f2fs_prepare_lookup(struct inode *dir, struct dentry *dentry, + struct f2fs_filename *fname); + void f2fs_free_filename(struct f2fs_filename *fname); + struct f2fs_dir_entry *f2fs_find_target_dentry(const struct f2fs_dentry_ptr *d, +- const struct f2fs_filename *fname, int *max_slots); ++ const struct f2fs_filename *fname, int *max_slots, ++ bool use_hash); + int f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d, + unsigned int start_pos, struct fscrypt_str *fstr); + void f2fs_do_make_empty_dir(struct inode *inode, struct inode *parent, +@@ -4148,7 +4149,8 @@ int f2fs_write_inline_data(struct inode *inode, struct page *page); + int f2fs_recover_inline_data(struct inode *inode, struct page *npage); + struct f2fs_dir_entry *f2fs_find_in_inline_dir(struct inode *dir, + const struct f2fs_filename *fname, +- struct page **res_page); ++ struct page **res_page, ++ bool use_hash); + int f2fs_make_empty_inline_dir(struct inode *inode, struct inode *parent, + struct page *ipage); + int f2fs_add_inline_entry(struct inode *dir, const struct f2fs_filename *fname, +diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c +index a3f8b4ed495efb..d5e8f3e40cc93b 100644 +--- a/fs/f2fs/inline.c ++++ b/fs/f2fs/inline.c +@@ -353,7 +353,8 @@ int f2fs_recover_inline_data(struct inode *inode, struct page *npage) + + struct f2fs_dir_entry *f2fs_find_in_inline_dir(struct inode *dir, + const struct f2fs_filename *fname, +- struct page **res_page) ++ struct page **res_page, ++ bool use_hash) + { + struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb); + struct f2fs_dir_entry *de; +@@ -370,7 +371,7 @@ struct f2fs_dir_entry *f2fs_find_in_inline_dir(struct inode *dir, + inline_dentry = inline_data_addr(dir, ipage); + + make_dentry_ptr_inline(dir, &d, inline_dentry); +- de = f2fs_find_target_dentry(&d, fname, NULL); ++ de = f2fs_find_target_dentry(&d, fname, NULL, use_hash); + unlock_page(ipage); + if (IS_ERR(de)) { + *res_page = ERR_CAST(de); +diff --git a/fs/file_table.c b/fs/file_table.c +index ee21b3da9d0812..234284ef72a9a5 100644 +--- a/fs/file_table.c ++++ b/fs/file_table.c +@@ -133,7 +133,7 @@ static struct ctl_table fs_stat_sysctls[] = { + .data = &sysctl_nr_open, + .maxlen = sizeof(unsigned int), + .mode = 0644, +- .proc_handler = proc_dointvec_minmax, ++ .proc_handler = proc_douintvec_minmax, + .extra1 = &sysctl_nr_open_min, + .extra2 = &sysctl_nr_open_max, + }, +diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c +index ff201753fd1814..9cddd78b11d416 100644 +--- a/fs/hostfs/hostfs_kern.c ++++ b/fs/hostfs/hostfs_kern.c +@@ -16,11 +16,17 @@ + #include + #include + #include ++#include ++#include + #include + #include "hostfs.h" + #include + #include + ++struct hostfs_fs_info { ++ char *host_root_path; ++}; ++ + struct hostfs_inode_info { + int fd; + fmode_t mode; +@@ -88,30 +94,17 @@ __uml_setup("hostfs=", hostfs_args, + static char *__dentry_name(struct dentry *dentry, char *name) + { + char *p = dentry_path_raw(dentry, name, PATH_MAX); +- char *root; +- size_t len; +- +- root = dentry->d_sb->s_fs_info; +- len = strlen(root); +- if (IS_ERR(p)) { +- __putname(name); +- return NULL; +- } ++ struct hostfs_fs_info *fsi = dentry->d_sb->s_fs_info; ++ char *root = fsi->host_root_path; ++ size_t len = strlen(root); + +- /* +- * This function relies on the fact that dentry_path_raw() will place +- * the path name at the end of the provided buffer. +- */ +- BUG_ON(p + strlen(p) + 1 != name + PATH_MAX); +- +- strscpy(name, root, PATH_MAX); +- if (len > p - name) { ++ if (IS_ERR(p) || len > p - name) { + __putname(name); + return NULL; + } + +- if (p > name + len) +- strcpy(name + len, p); ++ memcpy(name, root, len); ++ memmove(name + len, p, name + PATH_MAX - p); + + return name; + } +@@ -196,8 +189,10 @@ static int hostfs_statfs(struct dentry *dentry, struct kstatfs *sf) + long long f_bavail; + long long f_files; + long long f_ffree; ++ struct hostfs_fs_info *fsi; + +- err = do_statfs(dentry->d_sb->s_fs_info, ++ fsi = dentry->d_sb->s_fs_info; ++ err = do_statfs(fsi->host_root_path, + &sf->f_bsize, &f_blocks, &f_bfree, &f_bavail, &f_files, + &f_ffree, &sf->f_fsid, sizeof(sf->f_fsid), + &sf->f_namelen); +@@ -245,7 +240,11 @@ static void hostfs_free_inode(struct inode *inode) + + static int hostfs_show_options(struct seq_file *seq, struct dentry *root) + { +- const char *root_path = root->d_sb->s_fs_info; ++ struct hostfs_fs_info *fsi; ++ const char *root_path; ++ ++ fsi = root->d_sb->s_fs_info; ++ root_path = fsi->host_root_path; + size_t offset = strlen(root_ino) + 1; + + if (strlen(root_path) > offset) +@@ -924,10 +923,10 @@ static const struct inode_operations hostfs_link_iops = { + .get_link = hostfs_get_link, + }; + +-static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent) ++static int hostfs_fill_super(struct super_block *sb, struct fs_context *fc) + { ++ struct hostfs_fs_info *fsi = sb->s_fs_info; + struct inode *root_inode; +- char *host_root_path, *req_root = d; + int err; + + sb->s_blocksize = 1024; +@@ -940,16 +939,7 @@ static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent) + if (err) + return err; + +- /* NULL is printed as '(null)' by printf(): avoid that. */ +- if (req_root == NULL) +- req_root = ""; +- +- sb->s_fs_info = host_root_path = +- kasprintf(GFP_KERNEL, "%s/%s", root_ino, req_root); +- if (host_root_path == NULL) +- return -ENOMEM; +- +- root_inode = hostfs_iget(sb, host_root_path); ++ root_inode = hostfs_iget(sb, fsi->host_root_path); + if (IS_ERR(root_inode)) + return PTR_ERR(root_inode); + +@@ -957,7 +947,7 @@ static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent) + char *name; + + iput(root_inode); +- name = follow_link(host_root_path); ++ name = follow_link(fsi->host_root_path); + if (IS_ERR(name)) + return PTR_ERR(name); + +@@ -974,11 +964,92 @@ static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent) + return 0; + } + +-static struct dentry *hostfs_read_sb(struct file_system_type *type, +- int flags, const char *dev_name, +- void *data) ++enum hostfs_parma { ++ Opt_hostfs, ++}; ++ ++static const struct fs_parameter_spec hostfs_param_specs[] = { ++ fsparam_string_empty("hostfs", Opt_hostfs), ++ {} ++}; ++ ++static int hostfs_parse_param(struct fs_context *fc, struct fs_parameter *param) ++{ ++ struct hostfs_fs_info *fsi = fc->s_fs_info; ++ struct fs_parse_result result; ++ char *host_root; ++ int opt; ++ ++ opt = fs_parse(fc, hostfs_param_specs, param, &result); ++ if (opt < 0) ++ return opt; ++ ++ switch (opt) { ++ case Opt_hostfs: ++ host_root = param->string; ++ if (!*host_root) ++ host_root = ""; ++ fsi->host_root_path = ++ kasprintf(GFP_KERNEL, "%s/%s", root_ino, host_root); ++ if (fsi->host_root_path == NULL) ++ return -ENOMEM; ++ break; ++ } ++ ++ return 0; ++} ++ ++static int hostfs_parse_monolithic(struct fs_context *fc, void *data) ++{ ++ struct hostfs_fs_info *fsi = fc->s_fs_info; ++ char *host_root = (char *)data; ++ ++ /* NULL is printed as '(null)' by printf(): avoid that. */ ++ if (host_root == NULL) ++ host_root = ""; ++ ++ fsi->host_root_path = ++ kasprintf(GFP_KERNEL, "%s/%s", root_ino, host_root); ++ if (fsi->host_root_path == NULL) ++ return -ENOMEM; ++ ++ return 0; ++} ++ ++static int hostfs_fc_get_tree(struct fs_context *fc) ++{ ++ return get_tree_nodev(fc, hostfs_fill_super); ++} ++ ++static void hostfs_fc_free(struct fs_context *fc) ++{ ++ struct hostfs_fs_info *fsi = fc->s_fs_info; ++ ++ if (!fsi) ++ return; ++ ++ kfree(fsi->host_root_path); ++ kfree(fsi); ++} ++ ++static const struct fs_context_operations hostfs_context_ops = { ++ .parse_monolithic = hostfs_parse_monolithic, ++ .parse_param = hostfs_parse_param, ++ .get_tree = hostfs_fc_get_tree, ++ .free = hostfs_fc_free, ++}; ++ ++static int hostfs_init_fs_context(struct fs_context *fc) + { +- return mount_nodev(type, flags, data, hostfs_fill_sb_common); ++ struct hostfs_fs_info *fsi; ++ ++ fsi = kzalloc(sizeof(*fsi), GFP_KERNEL); ++ if (!fsi) ++ return -ENOMEM; ++ ++ fc->s_fs_info = fsi; ++ fc->ops = &hostfs_context_ops; ++ return 0; + } + + static void hostfs_kill_sb(struct super_block *s) +@@ -988,11 +1059,11 @@ static void hostfs_kill_sb(struct super_block *s) + } + + static struct file_system_type hostfs_type = { +- .owner = THIS_MODULE, +- .name = "hostfs", +- .mount = hostfs_read_sb, +- .kill_sb = hostfs_kill_sb, +- .fs_flags = 0, ++ .owner = THIS_MODULE, ++ .name = "hostfs", ++ .init_fs_context = hostfs_init_fs_context, ++ .kill_sb = hostfs_kill_sb, ++ .fs_flags = 0, + }; + MODULE_ALIAS_FS("hostfs"); + +diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c +index 531c9c20ef1d1b..9f0d69e6526443 100644 +--- a/fs/nfs/nfs42proc.c ++++ b/fs/nfs/nfs42proc.c +@@ -552,7 +552,7 @@ static int nfs42_do_offload_cancel_async(struct file *dst, + .rpc_message = &msg, + .callback_ops = &nfs42_offload_cancel_ops, + .workqueue = nfsiod_workqueue, +- .flags = RPC_TASK_ASYNC, ++ .flags = RPC_TASK_ASYNC | RPC_TASK_MOVEABLE, + }; + int status; + +diff --git a/fs/nfs/nfs42xdr.c b/fs/nfs/nfs42xdr.c +index 9e3ae53e220583..becc3149aa9e5c 100644 +--- a/fs/nfs/nfs42xdr.c ++++ b/fs/nfs/nfs42xdr.c +@@ -144,9 +144,11 @@ + decode_putfh_maxsz + \ + decode_offload_cancel_maxsz) + #define NFS4_enc_copy_notify_sz (compound_encode_hdr_maxsz + \ ++ encode_sequence_maxsz + \ + encode_putfh_maxsz + \ + encode_copy_notify_maxsz) + #define NFS4_dec_copy_notify_sz (compound_decode_hdr_maxsz + \ ++ decode_sequence_maxsz + \ + decode_putfh_maxsz + \ + decode_copy_notify_maxsz) + #define NFS4_enc_deallocate_sz (compound_encode_hdr_maxsz + \ +diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c +index 54ffadf02e034f..875ea311ca3c20 100644 +--- a/fs/nfsd/nfs4callback.c ++++ b/fs/nfsd/nfs4callback.c +@@ -1202,6 +1202,7 @@ static bool nfsd4_cb_sequence_done(struct rpc_task *task, struct nfsd4_callback + ret = false; + break; + case -NFS4ERR_DELAY: ++ cb->cb_seq_status = 1; + if (!rpc_restart_call(task)) + goto out; + +diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c +index 0610cb12c11ca0..d4a98ac72b8eaa 100644 +--- a/fs/nilfs2/segment.c ++++ b/fs/nilfs2/segment.c +@@ -731,11 +731,9 @@ static size_t nilfs_lookup_dirty_data_buffers(struct inode *inode, + continue; + } + head = folio_buffers(folio); +- if (!head) { +- create_empty_buffers(&folio->page, i_blocksize(inode), 0); +- head = folio_buffers(folio); +- } +- folio_unlock(folio); ++ if (!head) ++ head = folio_create_empty_buffers(folio, ++ i_blocksize(inode), 0); + + bh = head; + do { +@@ -745,11 +743,14 @@ static size_t nilfs_lookup_dirty_data_buffers(struct inode *inode, + list_add_tail(&bh->b_assoc_buffers, listp); + ndirties++; + if (unlikely(ndirties >= nlimit)) { ++ folio_unlock(folio); + folio_batch_release(&fbatch); + cond_resched(); + return ndirties; + } + } while (bh = bh->b_this_page, bh != head); ++ ++ folio_unlock(folio); + } + folio_batch_release(&fbatch); + cond_resched(); +diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c +index 0dffd6a44d39dc..24b031dc44ee1e 100644 +--- a/fs/ocfs2/quota_global.c ++++ b/fs/ocfs2/quota_global.c +@@ -749,6 +749,11 @@ static int ocfs2_release_dquot(struct dquot *dquot) + handle = ocfs2_start_trans(osb, + ocfs2_calc_qdel_credits(dquot->dq_sb, dquot->dq_id.type)); + if (IS_ERR(handle)) { ++ /* ++ * Mark dquot as inactive to avoid endless cycle in ++ * quota_release_workfn(). ++ */ ++ clear_bit(DQ_ACTIVE_B, &dquot->dq_flags); + status = PTR_ERR(handle); + mlog_errno(status); + goto out_ilock; +diff --git a/fs/pstore/blk.c b/fs/pstore/blk.c +index de8cf5d75f34d5..85668cb31c3d2f 100644 +--- a/fs/pstore/blk.c ++++ b/fs/pstore/blk.c +@@ -89,7 +89,7 @@ static struct pstore_device_info *pstore_device_info; + _##name_ = check_size(name, alignsize); \ + else \ + _##name_ = 0; \ +- /* Synchronize module parameters with resuls. */ \ ++ /* Synchronize module parameters with results. */ \ + name = _##name_ / 1024; \ + dev->zone.name = _##name_; \ + } +@@ -121,7 +121,7 @@ static int __register_pstore_device(struct pstore_device_info *dev) + if (pstore_device_info) + return -EBUSY; + +- /* zero means not limit on which backends to attempt to store. */ ++ /* zero means no limit on which backends attempt to store. */ + if (!dev->flags) + dev->flags = UINT_MAX; + +diff --git a/fs/select.c b/fs/select.c +index d4d881d439dcdf..3f730b8581f65d 100644 +--- a/fs/select.c ++++ b/fs/select.c +@@ -788,7 +788,7 @@ static inline int get_sigset_argpack(struct sigset_argpack *to, + } + return 0; + Efault: +- user_access_end(); ++ user_read_access_end(); + return -EFAULT; + } + +@@ -1361,7 +1361,7 @@ static inline int get_compat_sigset_argpack(struct compat_sigset_argpack *to, + } + return 0; + Efault: +- user_access_end(); ++ user_read_access_end(); + return -EFAULT; + } + +diff --git a/fs/smb/client/cifsacl.c b/fs/smb/client/cifsacl.c +index bff8d0dd74fe7d..1fc1683b15bd84 100644 +--- a/fs/smb/client/cifsacl.c ++++ b/fs/smb/client/cifsacl.c +@@ -1395,7 +1395,7 @@ static int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *pnntsd, + #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY + struct smb_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb, + const struct cifs_fid *cifsfid, u32 *pacllen, +- u32 __maybe_unused unused) ++ u32 info) + { + struct smb_ntsd *pntsd = NULL; + unsigned int xid; +@@ -1407,7 +1407,7 @@ struct smb_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb, + + xid = get_xid(); + rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), cifsfid->netfid, &pntsd, +- pacllen); ++ pacllen, info); + free_xid(xid); + + cifs_put_tlink(tlink); +@@ -1419,7 +1419,7 @@ struct smb_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb, + } + + static struct smb_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, +- const char *path, u32 *pacllen) ++ const char *path, u32 *pacllen, u32 info) + { + struct smb_ntsd *pntsd = NULL; + int oplock = 0; +@@ -1446,9 +1446,12 @@ static struct smb_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, + .fid = &fid, + }; + ++ if (info & SACL_SECINFO) ++ oparms.desired_access |= SYSTEM_SECURITY; ++ + rc = CIFS_open(xid, &oparms, &oplock, NULL); + if (!rc) { +- rc = CIFSSMBGetCIFSACL(xid, tcon, fid.netfid, &pntsd, pacllen); ++ rc = CIFSSMBGetCIFSACL(xid, tcon, fid.netfid, &pntsd, pacllen, info); + CIFSSMBClose(xid, tcon, fid.netfid); + } + +@@ -1472,7 +1475,7 @@ struct smb_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb, + if (inode) + open_file = find_readable_file(CIFS_I(inode), true); + if (!open_file) +- return get_cifs_acl_by_path(cifs_sb, path, pacllen); ++ return get_cifs_acl_by_path(cifs_sb, path, pacllen, info); + + pntsd = get_cifs_acl_by_fid(cifs_sb, &open_file->fid, pacllen, info); + cifsFileInfo_put(open_file); +@@ -1485,7 +1488,7 @@ int set_cifs_acl(struct smb_ntsd *pnntsd, __u32 acllen, + { + int oplock = 0; + unsigned int xid; +- int rc, access_flags; ++ int rc, access_flags = 0; + struct cifs_tcon *tcon; + struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); + struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); +@@ -1498,10 +1501,12 @@ int set_cifs_acl(struct smb_ntsd *pnntsd, __u32 acllen, + tcon = tlink_tcon(tlink); + xid = get_xid(); + +- if (aclflag == CIFS_ACL_OWNER || aclflag == CIFS_ACL_GROUP) +- access_flags = WRITE_OWNER; +- else +- access_flags = WRITE_DAC; ++ if (aclflag & CIFS_ACL_OWNER || aclflag & CIFS_ACL_GROUP) ++ access_flags |= WRITE_OWNER; ++ if (aclflag & CIFS_ACL_SACL) ++ access_flags |= SYSTEM_SECURITY; ++ if (aclflag & CIFS_ACL_DACL) ++ access_flags |= WRITE_DAC; + + oparms = (struct cifs_open_parms) { + .tcon = tcon, +diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h +index a151ffffc6f38e..85b0a30493a638 100644 +--- a/fs/smb/client/cifsproto.h ++++ b/fs/smb/client/cifsproto.h +@@ -570,7 +570,7 @@ extern int CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon, + const struct nls_table *nls_codepage, + struct cifs_sb_info *cifs_sb); + extern int CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, +- __u16 fid, struct smb_ntsd **acl_inf, __u32 *buflen); ++ __u16 fid, struct smb_ntsd **acl_inf, __u32 *buflen, __u32 info); + extern int CIFSSMBSetCIFSACL(const unsigned int, struct cifs_tcon *, __u16, + struct smb_ntsd *pntsd, __u32 len, int aclflag); + extern int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon, +diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c +index 2f8745736dbb02..769950adb7763b 100644 +--- a/fs/smb/client/cifssmb.c ++++ b/fs/smb/client/cifssmb.c +@@ -3385,7 +3385,7 @@ validate_ntransact(char *buf, char **ppparm, char **ppdata, + /* Get Security Descriptor (by handle) from remote server for a file or dir */ + int + CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid, +- struct smb_ntsd **acl_inf, __u32 *pbuflen) ++ struct smb_ntsd **acl_inf, __u32 *pbuflen, __u32 info) + { + int rc = 0; + int buf_type = 0; +@@ -3408,7 +3408,7 @@ CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid, + pSMB->MaxSetupCount = 0; + pSMB->Fid = fid; /* file handle always le */ + pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP | +- CIFS_ACL_DACL); ++ CIFS_ACL_DACL | info); + pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */ + inc_rfc1001_len(pSMB, 11); + iov[0].iov_base = (char *)pSMB; +diff --git a/fs/smb/client/readdir.c b/fs/smb/client/readdir.c +index 3cffdf3975a213..75929a0a56f969 100644 +--- a/fs/smb/client/readdir.c ++++ b/fs/smb/client/readdir.c +@@ -413,7 +413,7 @@ _initiate_cifs_search(const unsigned int xid, struct file *file, + cifsFile->invalidHandle = false; + } else if ((rc == -EOPNOTSUPP) && + (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) { +- cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM; ++ cifs_autodisable_serverino(cifs_sb); + goto ffirst_retry; + } + error_exit: +diff --git a/fs/smb/client/reparse.c b/fs/smb/client/reparse.c +index d3abb99cc99094..e56a8df23fec9a 100644 +--- a/fs/smb/client/reparse.c ++++ b/fs/smb/client/reparse.c +@@ -674,11 +674,12 @@ int smb2_parse_reparse_point(struct cifs_sb_info *cifs_sb, + return parse_reparse_point(buf, plen, cifs_sb, full_path, true, data); + } + +-static void wsl_to_fattr(struct cifs_open_info_data *data, ++static bool wsl_to_fattr(struct cifs_open_info_data *data, + struct cifs_sb_info *cifs_sb, + u32 tag, struct cifs_fattr *fattr) + { + struct smb2_file_full_ea_info *ea; ++ bool have_xattr_dev = false; + u32 next = 0; + + switch (tag) { +@@ -721,13 +722,24 @@ static void wsl_to_fattr(struct cifs_open_info_data *data, + fattr->cf_uid = wsl_make_kuid(cifs_sb, v); + else if (!strncmp(name, SMB2_WSL_XATTR_GID, nlen)) + fattr->cf_gid = wsl_make_kgid(cifs_sb, v); +- else if (!strncmp(name, SMB2_WSL_XATTR_MODE, nlen)) ++ else if (!strncmp(name, SMB2_WSL_XATTR_MODE, nlen)) { ++ /* File type in reparse point tag and in xattr mode must match. */ ++ if (S_DT(fattr->cf_mode) != S_DT(le32_to_cpu(*(__le32 *)v))) ++ return false; + fattr->cf_mode = (umode_t)le32_to_cpu(*(__le32 *)v); +- else if (!strncmp(name, SMB2_WSL_XATTR_DEV, nlen)) ++ } else if (!strncmp(name, SMB2_WSL_XATTR_DEV, nlen)) { + fattr->cf_rdev = reparse_mkdev(v); ++ have_xattr_dev = true; ++ } + } while (next); + out: ++ ++ /* Major and minor numbers for char and block devices are mandatory. */ ++ if (!have_xattr_dev && (tag == IO_REPARSE_TAG_LX_CHR || tag == IO_REPARSE_TAG_LX_BLK)) ++ return false; ++ + fattr->cf_dtype = S_DT(fattr->cf_mode); ++ return true; + } + + static bool posix_reparse_to_fattr(struct cifs_sb_info *cifs_sb, +@@ -801,7 +813,9 @@ bool cifs_reparse_point_to_fattr(struct cifs_sb_info *cifs_sb, + case IO_REPARSE_TAG_AF_UNIX: + case IO_REPARSE_TAG_LX_CHR: + case IO_REPARSE_TAG_LX_BLK: +- wsl_to_fattr(data, cifs_sb, tag, fattr); ++ ok = wsl_to_fattr(data, cifs_sb, tag, fattr); ++ if (!ok) ++ return false; + break; + case IO_REPARSE_TAG_NFS: + ok = posix_reparse_to_fattr(cifs_sb, fattr, data); +diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c +index fc6d00344c50ea..d4be915bcb70c7 100644 +--- a/fs/smb/client/smb2ops.c ++++ b/fs/smb/client/smb2ops.c +@@ -622,7 +622,8 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf, + + while (bytes_left >= (ssize_t)sizeof(*p)) { + memset(&tmp_iface, 0, sizeof(tmp_iface)); +- tmp_iface.speed = le64_to_cpu(p->LinkSpeed); ++ /* default to 1Gbps when link speed is unset */ ++ tmp_iface.speed = le64_to_cpu(p->LinkSpeed) ?: 1000000000; + tmp_iface.rdma_capable = le32_to_cpu(p->Capability & RDMA_CAPABLE) ? 1 : 0; + tmp_iface.rss_capable = le32_to_cpu(p->Capability & RSS_CAPABLE) ? 1 : 0; + +diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c +index eef9e527d9ff94..ff9e574c07a87d 100644 +--- a/fs/ubifs/debug.c ++++ b/fs/ubifs/debug.c +@@ -946,16 +946,20 @@ void ubifs_dump_tnc(struct ubifs_info *c) + + pr_err("\n"); + pr_err("(pid %d) start dumping TNC tree\n", current->pid); +- znode = ubifs_tnc_levelorder_next(c, c->zroot.znode, NULL); +- level = znode->level; +- pr_err("== Level %d ==\n", level); +- while (znode) { +- if (level != znode->level) { +- level = znode->level; +- pr_err("== Level %d ==\n", level); ++ if (c->zroot.znode) { ++ znode = ubifs_tnc_levelorder_next(c, c->zroot.znode, NULL); ++ level = znode->level; ++ pr_err("== Level %d ==\n", level); ++ while (znode) { ++ if (level != znode->level) { ++ level = znode->level; ++ pr_err("== Level %d ==\n", level); ++ } ++ ubifs_dump_znode(c, znode); ++ znode = ubifs_tnc_levelorder_next(c, c->zroot.znode, znode); + } +- ubifs_dump_znode(c, znode); +- znode = ubifs_tnc_levelorder_next(c, c->zroot.znode, znode); ++ } else { ++ pr_err("empty TNC tree in memory\n"); + } + pr_err("(pid %d) finish dumping TNC tree\n", current->pid); + } +diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h +index a3c9dd4a1ac33c..7e9e7e76904369 100644 +--- a/include/acpi/acpixf.h ++++ b/include/acpi/acpixf.h +@@ -763,6 +763,7 @@ ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status + *event_status)) + ACPI_HW_DEPENDENT_RETURN_UINT32(u32 acpi_dispatch_gpe(acpi_handle gpe_device, u32 gpe_number)) + ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_hw_disable_all_gpes(void)) ++ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_hw_enable_all_wakeup_gpes(void)) + ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_disable_all_gpes(void)) + ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_enable_all_runtime_gpes(void)) + ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_enable_all_wakeup_gpes(void)) +diff --git a/include/dt-bindings/clock/sun50i-a64-ccu.h b/include/dt-bindings/clock/sun50i-a64-ccu.h +index 175892189e9dcb..4f220ea7a23cc5 100644 +--- a/include/dt-bindings/clock/sun50i-a64-ccu.h ++++ b/include/dt-bindings/clock/sun50i-a64-ccu.h +@@ -44,7 +44,9 @@ + #define _DT_BINDINGS_CLK_SUN50I_A64_H_ + + #define CLK_PLL_VIDEO0 7 ++#define CLK_PLL_VIDEO0_2X 8 + #define CLK_PLL_PERIPH0 11 ++#define CLK_PLL_MIPI 17 + + #define CLK_CPUX 21 + #define CLK_BUS_MIPI_DSI 28 +diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h +index 44e9de51eedfb6..572030db2f0616 100644 +--- a/include/linux/buffer_head.h ++++ b/include/linux/buffer_head.h +@@ -203,8 +203,8 @@ struct buffer_head *alloc_page_buffers(struct page *page, unsigned long size, + bool retry); + void create_empty_buffers(struct page *, unsigned long, + unsigned long b_state); +-void folio_create_empty_buffers(struct folio *folio, unsigned long blocksize, +- unsigned long b_state); ++struct buffer_head *folio_create_empty_buffers(struct folio *folio, ++ unsigned long blocksize, unsigned long b_state); + void end_buffer_read_sync(struct buffer_head *bh, int uptodate); + void end_buffer_write_sync(struct buffer_head *bh, int uptodate); + void end_buffer_async_write(struct buffer_head *bh, int uptodate); +diff --git a/include/linux/hid.h b/include/linux/hid.h +index af55a25db91b0d..774cb25dec34c5 100644 +--- a/include/linux/hid.h ++++ b/include/linux/hid.h +@@ -218,6 +218,7 @@ struct hid_item { + #define HID_GD_DOWN 0x00010091 + #define HID_GD_RIGHT 0x00010092 + #define HID_GD_LEFT 0x00010093 ++#define HID_GD_DO_NOT_DISTURB 0x0001009b + /* Microsoft Win8 Wireless Radio Controls CA usage codes */ + #define HID_GD_RFKILL_BTN 0x000100c6 + #define HID_GD_RFKILL_LED 0x000100c7 +diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h +index 5f1e5a16d7b2c3..0ff10007eb1a5e 100644 +--- a/include/linux/ieee80211.h ++++ b/include/linux/ieee80211.h +@@ -4826,28 +4826,24 @@ static inline u8 ieee80211_mle_common_size(const u8 *data) + { + const struct ieee80211_multi_link_elem *mle = (const void *)data; + u16 control = le16_to_cpu(mle->control); +- u8 common = 0; + + switch (u16_get_bits(control, IEEE80211_ML_CONTROL_TYPE)) { + case IEEE80211_ML_CONTROL_TYPE_BASIC: + case IEEE80211_ML_CONTROL_TYPE_PREQ: + case IEEE80211_ML_CONTROL_TYPE_TDLS: + case IEEE80211_ML_CONTROL_TYPE_RECONF: ++ case IEEE80211_ML_CONTROL_TYPE_PRIO_ACCESS: + /* + * The length is the first octet pointed by mle->variable so no + * need to add anything + */ + break; +- case IEEE80211_ML_CONTROL_TYPE_PRIO_ACCESS: +- if (control & IEEE80211_MLC_PRIO_ACCESS_PRES_AP_MLD_MAC_ADDR) +- common += ETH_ALEN; +- return common; + default: + WARN_ON(1); + return 0; + } + +- return sizeof(*mle) + common + mle->variable[0]; ++ return sizeof(*mle) + mle->variable[0]; + } + + /** +@@ -4989,8 +4985,7 @@ static inline bool ieee80211_mle_size_ok(const u8 *data, size_t len) + check_common_len = true; + break; + case IEEE80211_ML_CONTROL_TYPE_PRIO_ACCESS: +- if (control & IEEE80211_MLC_PRIO_ACCESS_PRES_AP_MLD_MAC_ADDR) +- common += ETH_ALEN; ++ common = ETH_ALEN + 1; + break; + default: + /* we don't know this type */ +diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h +index c3f075e8f60cb6..1c6a6c1704d8d0 100644 +--- a/include/linux/kallsyms.h ++++ b/include/linux/kallsyms.h +@@ -57,10 +57,10 @@ static inline void *dereference_symbol_descriptor(void *ptr) + + preempt_disable(); + mod = __module_address((unsigned long)ptr); +- preempt_enable(); + + if (mod) + ptr = dereference_module_function_descriptor(mod, ptr); ++ preempt_enable(); + #endif + return ptr; + } +diff --git a/include/linux/mfd/syscon.h b/include/linux/mfd/syscon.h +index fecc2fa2a36475..aad9c6b5046368 100644 +--- a/include/linux/mfd/syscon.h ++++ b/include/linux/mfd/syscon.h +@@ -17,20 +17,19 @@ + struct device_node; + + #ifdef CONFIG_MFD_SYSCON +-extern struct regmap *device_node_to_regmap(struct device_node *np); +-extern struct regmap *syscon_node_to_regmap(struct device_node *np); +-extern struct regmap *syscon_regmap_lookup_by_compatible(const char *s); +-extern struct regmap *syscon_regmap_lookup_by_phandle( +- struct device_node *np, +- const char *property); +-extern struct regmap *syscon_regmap_lookup_by_phandle_args( +- struct device_node *np, +- const char *property, +- int arg_count, +- unsigned int *out_args); +-extern struct regmap *syscon_regmap_lookup_by_phandle_optional( +- struct device_node *np, +- const char *property); ++struct regmap *device_node_to_regmap(struct device_node *np); ++struct regmap *syscon_node_to_regmap(struct device_node *np); ++struct regmap *syscon_regmap_lookup_by_compatible(const char *s); ++struct regmap *syscon_regmap_lookup_by_phandle(struct device_node *np, ++ const char *property); ++struct regmap *syscon_regmap_lookup_by_phandle_args(struct device_node *np, ++ const char *property, ++ int arg_count, ++ unsigned int *out_args); ++struct regmap *syscon_regmap_lookup_by_phandle_optional(struct device_node *np, ++ const char *property); ++int of_syscon_register_regmap(struct device_node *np, ++ struct regmap *regmap); + #else + static inline struct regmap *device_node_to_regmap(struct device_node *np) + { +@@ -70,6 +69,12 @@ static inline struct regmap *syscon_regmap_lookup_by_phandle_optional( + return NULL; + } + ++static inline int of_syscon_register_regmap(struct device_node *np, ++ struct regmap *regmap) ++{ ++ return -EOPNOTSUPP; ++} ++ + #endif + + #endif /* __LINUX_MFD_SYSCON_H__ */ +diff --git a/include/linux/mroute_base.h b/include/linux/mroute_base.h +index 9dd4bf1572553f..58a2401e4b551b 100644 +--- a/include/linux/mroute_base.h ++++ b/include/linux/mroute_base.h +@@ -146,9 +146,9 @@ struct mr_mfc { + unsigned long last_assert; + int minvif; + int maxvif; +- unsigned long bytes; +- unsigned long pkt; +- unsigned long wrong_if; ++ atomic_long_t bytes; ++ atomic_long_t pkt; ++ atomic_long_t wrong_if; + unsigned long lastuse; + unsigned char ttls[MAXVIFS]; + refcount_t refcount; +diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h +index 1576e7443eee50..8b5121eb8757ef 100644 +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -2217,7 +2217,7 @@ struct net_device { + void *atalk_ptr; + #endif + #if IS_ENABLED(CONFIG_AX25) +- void *ax25_ptr; ++ struct ax25_dev __rcu *ax25_ptr; + #endif + #if IS_ENABLED(CONFIG_CFG80211) + struct wireless_dev *ieee80211_ptr; +diff --git a/include/linux/of.h b/include/linux/of.h +index 024dda54b9c776..afee93163fddd5 100644 +--- a/include/linux/of.h ++++ b/include/linux/of.h +@@ -423,11 +423,9 @@ extern int of_detach_node(struct device_node *); + #define of_match_ptr(_ptr) (_ptr) + + /* +- * struct property *prop; +- * const __be32 *p; + * u32 u; + * +- * of_property_for_each_u32(np, "propname", prop, p, u) ++ * of_property_for_each_u32(np, "propname", u) + * printk("U32 value: %x\n", u); + */ + const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur, +@@ -1399,11 +1397,12 @@ static inline int of_property_read_s32(const struct device_node *np, + err == 0; \ + err = of_phandle_iterator_next(it)) + +-#define of_property_for_each_u32(np, propname, prop, p, u) \ +- for (prop = of_find_property(np, propname, NULL), \ +- p = of_prop_next_u32(prop, NULL, &u); \ +- p; \ +- p = of_prop_next_u32(prop, p, &u)) ++#define of_property_for_each_u32(np, propname, u) \ ++ for (struct {struct property *prop; const __be32 *item; } _it = \ ++ {of_find_property(np, propname, NULL), \ ++ of_prop_next_u32(_it.prop, NULL, &u)}; \ ++ _it.item; \ ++ _it.item = of_prop_next_u32(_it.prop, _it.item, &u)) + + #define of_property_for_each_string(np, propname, prop, s) \ + for (prop = of_find_property(np, propname, NULL), \ +diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h +index 7a5563ffe61b53..fcb834dd75c240 100644 +--- a/include/linux/perf_event.h ++++ b/include/linux/perf_event.h +@@ -1231,12 +1231,18 @@ static inline void perf_sample_save_callchain(struct perf_sample_data *data, + } + + static inline void perf_sample_save_raw_data(struct perf_sample_data *data, ++ struct perf_event *event, + struct perf_raw_record *raw) + { + struct perf_raw_frag *frag = &raw->frag; + u32 sum = 0; + int size; + ++ if (!(event->attr.sample_type & PERF_SAMPLE_RAW)) ++ return; ++ if (WARN_ON_ONCE(data->sample_flags & PERF_SAMPLE_RAW)) ++ return; ++ + do { + sum += frag->size; + if (perf_raw_frag_last(frag)) +diff --git a/include/linux/platform_data/pca953x.h b/include/linux/platform_data/pca953x.h +index 96c1a14ab3657a..3c3787c4d96ca2 100644 +--- a/include/linux/platform_data/pca953x.h ++++ b/include/linux/platform_data/pca953x.h +@@ -11,21 +11,8 @@ struct pca953x_platform_data { + /* number of the first GPIO */ + unsigned gpio_base; + +- /* initial polarity inversion setting */ +- u32 invert; +- + /* interrupt base */ + int irq_base; +- +- void *context; /* param to setup/teardown */ +- +- int (*setup)(struct i2c_client *client, +- unsigned gpio, unsigned ngpio, +- void *context); +- void (*teardown)(struct i2c_client *client, +- unsigned gpio, unsigned ngpio, +- void *context); +- const char *const *names; + }; + + #endif /* _LINUX_PCA953X_H */ +diff --git a/include/linux/platform_data/si5351.h b/include/linux/platform_data/si5351.h +index c71a2dd661437a..5f412a615532bb 100644 +--- a/include/linux/platform_data/si5351.h ++++ b/include/linux/platform_data/si5351.h +@@ -105,10 +105,12 @@ struct si5351_clkout_config { + * @clk_xtal: xtal input clock + * @clk_clkin: clkin input clock + * @pll_src: array of pll source clock setting ++ * @pll_reset: array indicating if plls should be reset after setting the rate + * @clkout: array of clkout configuration + */ + struct si5351_platform_data { + enum si5351_pll_src pll_src[2]; ++ bool pll_reset[2]; + struct si5351_clkout_config clkout[8]; + }; + +diff --git a/include/linux/pps_kernel.h b/include/linux/pps_kernel.h +index 78c8ac4951b581..c7abce28ed2995 100644 +--- a/include/linux/pps_kernel.h ++++ b/include/linux/pps_kernel.h +@@ -56,8 +56,7 @@ struct pps_device { + + unsigned int id; /* PPS source unique ID */ + void const *lookup_cookie; /* For pps_lookup_dev() only */ +- struct cdev cdev; +- struct device *dev; ++ struct device dev; + struct fasync_struct *async_queue; /* fasync method */ + spinlock_t lock; + }; +diff --git a/include/linux/sched.h b/include/linux/sched.h +index d4f9d82c69e0b0..2af0a8859d6473 100644 +--- a/include/linux/sched.h ++++ b/include/linux/sched.h +@@ -896,6 +896,7 @@ struct task_struct { + unsigned sched_reset_on_fork:1; + unsigned sched_contributes_to_load:1; + unsigned sched_migrated:1; ++ unsigned sched_task_hot:1; + + /* Force alignment to the next boundary: */ + unsigned :0; +diff --git a/include/linux/usb/tcpm.h b/include/linux/usb/tcpm.h +index ab7ca872950bb1..0bdb4f565d0f89 100644 +--- a/include/linux/usb/tcpm.h ++++ b/include/linux/usb/tcpm.h +@@ -150,7 +150,8 @@ struct tcpc_dev { + void (*frs_sourcing_vbus)(struct tcpc_dev *dev); + int (*enable_auto_vbus_discharge)(struct tcpc_dev *dev, bool enable); + int (*set_auto_vbus_discharge_threshold)(struct tcpc_dev *dev, enum typec_pwr_opmode mode, +- bool pps_active, u32 requested_vbus_voltage); ++ bool pps_active, u32 requested_vbus_voltage, ++ u32 pps_apdo_min_voltage); + bool (*is_vbus_vsafe0v)(struct tcpc_dev *dev); + void (*set_partner_usb_comm_capable)(struct tcpc_dev *dev, bool enable); + void (*check_contaminant)(struct tcpc_dev *dev); +diff --git a/include/net/ax25.h b/include/net/ax25.h +index c2a85fd3f5ea40..ef79023f1a286f 100644 +--- a/include/net/ax25.h ++++ b/include/net/ax25.h +@@ -229,6 +229,7 @@ typedef struct ax25_dev { + #endif + refcount_t refcount; + bool device_up; ++ struct rcu_head rcu; + } ax25_dev; + + typedef struct ax25_cb { +@@ -288,9 +289,8 @@ static inline void ax25_dev_hold(ax25_dev *ax25_dev) + + static inline void ax25_dev_put(ax25_dev *ax25_dev) + { +- if (refcount_dec_and_test(&ax25_dev->refcount)) { +- kfree(ax25_dev); +- } ++ if (refcount_dec_and_test(&ax25_dev->refcount)) ++ kfree_rcu(ax25_dev, rcu); + } + static inline __be16 ax25_type_trans(struct sk_buff *skb, struct net_device *dev) + { +@@ -333,9 +333,9 @@ void ax25_digi_invert(const ax25_digi *, ax25_digi *); + extern spinlock_t ax25_dev_lock; + + #if IS_ENABLED(CONFIG_AX25) +-static inline ax25_dev *ax25_dev_ax25dev(struct net_device *dev) ++static inline ax25_dev *ax25_dev_ax25dev(const struct net_device *dev) + { +- return dev->ax25_ptr; ++ return rcu_dereference_rtnl(dev->ax25_ptr); + } + #endif + +diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h +index 74ff688568a0c6..f475757daafba9 100644 +--- a/include/net/inetpeer.h ++++ b/include/net/inetpeer.h +@@ -96,30 +96,28 @@ static inline struct in6_addr *inetpeer_get_addr_v6(struct inetpeer_addr *iaddr) + + /* can be called with or without local BH being disabled */ + struct inet_peer *inet_getpeer(struct inet_peer_base *base, +- const struct inetpeer_addr *daddr, +- int create); ++ const struct inetpeer_addr *daddr); + + static inline struct inet_peer *inet_getpeer_v4(struct inet_peer_base *base, + __be32 v4daddr, +- int vif, int create) ++ int vif) + { + struct inetpeer_addr daddr; + + daddr.a4.addr = v4daddr; + daddr.a4.vif = vif; + daddr.family = AF_INET; +- return inet_getpeer(base, &daddr, create); ++ return inet_getpeer(base, &daddr); + } + + static inline struct inet_peer *inet_getpeer_v6(struct inet_peer_base *base, +- const struct in6_addr *v6daddr, +- int create) ++ const struct in6_addr *v6daddr) + { + struct inetpeer_addr daddr; + + daddr.a6 = *v6daddr; + daddr.family = AF_INET6; +- return inet_getpeer(base, &daddr, create); ++ return inet_getpeer(base, &daddr); + } + + static inline int inetpeer_addr_cmp(const struct inetpeer_addr *a, +diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h +index 8321915dddb284..dcbf3f299548f7 100644 +--- a/include/net/netfilter/nf_tables.h ++++ b/include/net/netfilter/nf_tables.h +@@ -429,6 +429,9 @@ struct nft_set_ext; + * @remove: remove element from set + * @walk: iterate over all set elements + * @get: get set elements ++ * @ksize: kernel set size ++ * @usize: userspace set size ++ * @adjust_maxsize: delta to adjust maximum set size + * @commit: commit set elements + * @abort: abort set elements + * @privsize: function to return size of set private data +@@ -481,7 +484,10 @@ struct nft_set_ops { + const struct nft_set *set, + const struct nft_set_elem *elem, + unsigned int flags); +- void (*commit)(const struct nft_set *set); ++ u32 (*ksize)(u32 size); ++ u32 (*usize)(u32 size); ++ u32 (*adjust_maxsize)(const struct nft_set *set); ++ void (*commit)(struct nft_set *set); + void (*abort)(const struct nft_set *set); + u64 (*privsize)(const struct nlattr * const nla[], + const struct nft_set_desc *desc); +diff --git a/include/net/xfrm.h b/include/net/xfrm.h +index 93a9866ee481fa..b33d27e42cff38 100644 +--- a/include/net/xfrm.h ++++ b/include/net/xfrm.h +@@ -1181,9 +1181,19 @@ static inline int __xfrm_policy_check2(struct sock *sk, int dir, + + if (xo) { + x = xfrm_input_state(skb); +- if (x->xso.type == XFRM_DEV_OFFLOAD_PACKET) +- return (xo->flags & CRYPTO_DONE) && +- (xo->status & CRYPTO_SUCCESS); ++ if (x->xso.type == XFRM_DEV_OFFLOAD_PACKET) { ++ bool check = (xo->flags & CRYPTO_DONE) && ++ (xo->status & CRYPTO_SUCCESS); ++ ++ /* The packets here are plain ones and secpath was ++ * needed to indicate that hardware already handled ++ * them and there is no need to do nothing in addition. ++ * ++ * Consume secpath which was set by drivers. ++ */ ++ secpath_reset(skb); ++ return check; ++ } + } + + return __xfrm_check_nopolicy(net, skb, dir) || +diff --git a/include/trace/events/afs.h b/include/trace/events/afs.h +index d1ee4272d1cb8b..ceb0146ffc7cd1 100644 +--- a/include/trace/events/afs.h ++++ b/include/trace/events/afs.h +@@ -118,6 +118,8 @@ enum yfs_cm_operation { + */ + #define afs_call_traces \ + EM(afs_call_trace_alloc, "ALLOC") \ ++ EM(afs_call_trace_async_abort, "ASYAB") \ ++ EM(afs_call_trace_async_kill, "ASYKL") \ + EM(afs_call_trace_free, "FREE ") \ + EM(afs_call_trace_get, "GET ") \ + EM(afs_call_trace_put, "PUT ") \ +diff --git a/include/trace/events/rxrpc.h b/include/trace/events/rxrpc.h +index ed36f5f577a9d3..252bb90aca599b 100644 +--- a/include/trace/events/rxrpc.h ++++ b/include/trace/events/rxrpc.h +@@ -117,6 +117,7 @@ + #define rxrpc_call_poke_traces \ + EM(rxrpc_call_poke_abort, "Abort") \ + EM(rxrpc_call_poke_complete, "Compl") \ ++ EM(rxrpc_call_poke_conn_abort, "Conn-abort") \ + EM(rxrpc_call_poke_error, "Error") \ + EM(rxrpc_call_poke_idle, "Idle") \ + EM(rxrpc_call_poke_start, "Start") \ +@@ -278,6 +279,7 @@ + EM(rxrpc_call_see_activate_client, "SEE act-clnt") \ + EM(rxrpc_call_see_connect_failed, "SEE con-fail") \ + EM(rxrpc_call_see_connected, "SEE connect ") \ ++ EM(rxrpc_call_see_conn_abort, "SEE conn-abt") \ + EM(rxrpc_call_see_disconnected, "SEE disconn ") \ + EM(rxrpc_call_see_distribute_error, "SEE dist-err") \ + EM(rxrpc_call_see_input, "SEE input ") \ +@@ -961,6 +963,29 @@ TRACE_EVENT(rxrpc_rx_abort, + __entry->abort_code) + ); + ++TRACE_EVENT(rxrpc_rx_conn_abort, ++ TP_PROTO(const struct rxrpc_connection *conn, const struct sk_buff *skb), ++ ++ TP_ARGS(conn, skb), ++ ++ TP_STRUCT__entry( ++ __field(unsigned int, conn) ++ __field(rxrpc_serial_t, serial) ++ __field(u32, abort_code) ++ ), ++ ++ TP_fast_assign( ++ __entry->conn = conn->debug_id; ++ __entry->serial = rxrpc_skb(skb)->hdr.serial; ++ __entry->abort_code = skb->priority; ++ ), ++ ++ TP_printk("C=%08x ABORT %08x ac=%d", ++ __entry->conn, ++ __entry->serial, ++ __entry->abort_code) ++ ); ++ + TRACE_EVENT(rxrpc_rx_challenge, + TP_PROTO(struct rxrpc_connection *conn, rxrpc_serial_t serial, + u32 version, u32 nonce, u32 min_level), +diff --git a/io_uring/uring_cmd.c b/io_uring/uring_cmd.c +index 5fa19861cda546..2cbd1c24414c61 100644 +--- a/io_uring/uring_cmd.c ++++ b/io_uring/uring_cmd.c +@@ -175,7 +175,7 @@ int io_uring_cmd_sock(struct io_uring_cmd *cmd, unsigned int issue_flags) + if (!prot || !prot->ioctl) + return -EOPNOTSUPP; + +- switch (cmd->sqe->cmd_op) { ++ switch (cmd->cmd_op) { + case SOCKET_URING_OP_SIOCINQ: + ret = prot->ioctl(sk, SIOCINQ, &arg); + if (ret) +diff --git a/kernel/bpf/bpf_local_storage.c b/kernel/bpf/bpf_local_storage.c +index e8d02212da7039..b4c6b9b3cb421e 100644 +--- a/kernel/bpf/bpf_local_storage.c ++++ b/kernel/bpf/bpf_local_storage.c +@@ -823,8 +823,12 @@ bpf_local_storage_map_alloc(union bpf_attr *attr, + smap->elem_size = offsetof(struct bpf_local_storage_elem, + sdata.data[attr->value_size]); + +- smap->bpf_ma = bpf_ma; +- if (bpf_ma) { ++ /* In PREEMPT_RT, kmalloc(GFP_ATOMIC) is still not safe in non ++ * preemptible context. Thus, enforce all storages to use ++ * bpf_mem_alloc when CONFIG_PREEMPT_RT is enabled. ++ */ ++ smap->bpf_ma = IS_ENABLED(CONFIG_PREEMPT_RT) ? true : bpf_ma; ++ if (smap->bpf_ma) { + err = bpf_mem_alloc_init(&smap->selem_ma, smap->elem_size, false); + if (err) + goto free_smap; +diff --git a/kernel/events/core.c b/kernel/events/core.c +index ec0fae49a0dd9a..5d6458ea675e9d 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -10157,9 +10157,9 @@ static struct pmu perf_tracepoint = { + }; + + static int perf_tp_filter_match(struct perf_event *event, +- struct perf_sample_data *data) ++ struct perf_raw_record *raw) + { +- void *record = data->raw->frag.data; ++ void *record = raw->frag.data; + + /* only top level events have filters set */ + if (event->parent) +@@ -10171,7 +10171,7 @@ static int perf_tp_filter_match(struct perf_event *event, + } + + static int perf_tp_event_match(struct perf_event *event, +- struct perf_sample_data *data, ++ struct perf_raw_record *raw, + struct pt_regs *regs) + { + if (event->hw.state & PERF_HES_STOPPED) +@@ -10182,7 +10182,7 @@ static int perf_tp_event_match(struct perf_event *event, + if (event->attr.exclude_kernel && !user_mode(regs)) + return 0; + +- if (!perf_tp_filter_match(event, data)) ++ if (!perf_tp_filter_match(event, raw)) + return 0; + + return 1; +@@ -10208,6 +10208,7 @@ EXPORT_SYMBOL_GPL(perf_trace_run_bpf_submit); + static void __perf_tp_event_target_task(u64 count, void *record, + struct pt_regs *regs, + struct perf_sample_data *data, ++ struct perf_raw_record *raw, + struct perf_event *event) + { + struct trace_entry *entry = record; +@@ -10217,13 +10218,17 @@ static void __perf_tp_event_target_task(u64 count, void *record, + /* Cannot deliver synchronous signal to other task. */ + if (event->attr.sigtrap) + return; +- if (perf_tp_event_match(event, data, regs)) ++ if (perf_tp_event_match(event, raw, regs)) { ++ perf_sample_data_init(data, 0, 0); ++ perf_sample_save_raw_data(data, event, raw); + perf_swevent_event(event, count, data, regs); ++ } + } + + static void perf_tp_event_target_task(u64 count, void *record, + struct pt_regs *regs, + struct perf_sample_data *data, ++ struct perf_raw_record *raw, + struct perf_event_context *ctx) + { + unsigned int cpu = smp_processor_id(); +@@ -10231,15 +10236,15 @@ static void perf_tp_event_target_task(u64 count, void *record, + struct perf_event *event, *sibling; + + perf_event_groups_for_cpu_pmu(event, &ctx->pinned_groups, cpu, pmu) { +- __perf_tp_event_target_task(count, record, regs, data, event); ++ __perf_tp_event_target_task(count, record, regs, data, raw, event); + for_each_sibling_event(sibling, event) +- __perf_tp_event_target_task(count, record, regs, data, sibling); ++ __perf_tp_event_target_task(count, record, regs, data, raw, sibling); + } + + perf_event_groups_for_cpu_pmu(event, &ctx->flexible_groups, cpu, pmu) { +- __perf_tp_event_target_task(count, record, regs, data, event); ++ __perf_tp_event_target_task(count, record, regs, data, raw, event); + for_each_sibling_event(sibling, event) +- __perf_tp_event_target_task(count, record, regs, data, sibling); ++ __perf_tp_event_target_task(count, record, regs, data, raw, sibling); + } + } + +@@ -10257,15 +10262,10 @@ void perf_tp_event(u16 event_type, u64 count, void *record, int entry_size, + }, + }; + +- perf_sample_data_init(&data, 0, 0); +- perf_sample_save_raw_data(&data, &raw); +- + perf_trace_buf_update(record, event_type); + + hlist_for_each_entry_rcu(event, head, hlist_entry) { +- if (perf_tp_event_match(event, &data, regs)) { +- perf_swevent_event(event, count, &data, regs); +- ++ if (perf_tp_event_match(event, &raw, regs)) { + /* + * Here use the same on-stack perf_sample_data, + * some members in data are event-specific and +@@ -10275,7 +10275,8 @@ void perf_tp_event(u16 event_type, u64 count, void *record, int entry_size, + * because data->sample_flags is set. + */ + perf_sample_data_init(&data, 0, 0); +- perf_sample_save_raw_data(&data, &raw); ++ perf_sample_save_raw_data(&data, event, &raw); ++ perf_swevent_event(event, count, &data, regs); + } + } + +@@ -10292,7 +10293,7 @@ void perf_tp_event(u16 event_type, u64 count, void *record, int entry_size, + goto unlock; + + raw_spin_lock(&ctx->lock); +- perf_tp_event_target_task(count, record, regs, &data, ctx); ++ perf_tp_event_target_task(count, record, regs, &data, &raw, ctx); + raw_spin_unlock(&ctx->lock); + unlock: + rcu_read_unlock(); +diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h +index bcc7f21db9eeb3..fbeecc608f54cc 100644 +--- a/kernel/irq/internals.h ++++ b/kernel/irq/internals.h +@@ -434,10 +434,6 @@ static inline struct cpumask *irq_desc_get_pending_mask(struct irq_desc *desc) + { + return desc->pending_mask; + } +-static inline bool handle_enforce_irqctx(struct irq_data *data) +-{ +- return irqd_is_handle_enforce_irqctx(data); +-} + bool irq_fixup_move_pending(struct irq_desc *desc, bool force_clear); + #else /* CONFIG_GENERIC_PENDING_IRQ */ + static inline bool irq_can_move_pcntxt(struct irq_data *data) +@@ -464,11 +460,12 @@ static inline bool irq_fixup_move_pending(struct irq_desc *desc, bool fclear) + { + return false; + } ++#endif /* !CONFIG_GENERIC_PENDING_IRQ */ ++ + static inline bool handle_enforce_irqctx(struct irq_data *data) + { +- return false; ++ return irqd_is_handle_enforce_irqctx(data); + } +-#endif /* !CONFIG_GENERIC_PENDING_IRQ */ + + #if !defined(CONFIG_IRQ_DOMAIN) || !defined(CONFIG_IRQ_DOMAIN_HIERARCHY) + static inline int irq_domain_activate_irq(struct irq_data *data, bool reserve) +diff --git a/kernel/padata.c b/kernel/padata.c +index 9bf77b58ee08d4..071d8cad807871 100644 +--- a/kernel/padata.c ++++ b/kernel/padata.c +@@ -47,6 +47,22 @@ struct padata_mt_job_state { + static void padata_free_pd(struct parallel_data *pd); + static void __init padata_mt_helper(struct work_struct *work); + ++static inline void padata_get_pd(struct parallel_data *pd) ++{ ++ refcount_inc(&pd->refcnt); ++} ++ ++static inline void padata_put_pd_cnt(struct parallel_data *pd, int cnt) ++{ ++ if (refcount_sub_and_test(cnt, &pd->refcnt)) ++ padata_free_pd(pd); ++} ++ ++static inline void padata_put_pd(struct parallel_data *pd) ++{ ++ padata_put_pd_cnt(pd, 1); ++} ++ + static int padata_index_to_cpu(struct parallel_data *pd, int cpu_index) + { + int cpu, target_cpu; +@@ -206,7 +222,7 @@ int padata_do_parallel(struct padata_shell *ps, + if ((pinst->flags & PADATA_RESET)) + goto out; + +- refcount_inc(&pd->refcnt); ++ padata_get_pd(pd); + padata->pd = pd; + padata->cb_cpu = *cb_cpu; + +@@ -336,8 +352,14 @@ static void padata_reorder(struct parallel_data *pd) + smp_mb(); + + reorder = per_cpu_ptr(pd->reorder_list, pd->cpu); +- if (!list_empty(&reorder->list) && padata_find_next(pd, false)) ++ if (!list_empty(&reorder->list) && padata_find_next(pd, false)) { ++ /* ++ * Other context(eg. the padata_serial_worker) can finish the request. ++ * To avoid UAF issue, add pd ref here, and put pd ref after reorder_work finish. ++ */ ++ padata_get_pd(pd); + queue_work(pinst->serial_wq, &pd->reorder_work); ++ } + } + + static void invoke_padata_reorder(struct work_struct *work) +@@ -348,6 +370,8 @@ static void invoke_padata_reorder(struct work_struct *work) + pd = container_of(work, struct parallel_data, reorder_work); + padata_reorder(pd); + local_bh_enable(); ++ /* Pairs with putting the reorder_work in the serial_wq */ ++ padata_put_pd(pd); + } + + static void padata_serial_worker(struct work_struct *serial_work) +@@ -380,8 +404,7 @@ static void padata_serial_worker(struct work_struct *serial_work) + } + local_bh_enable(); + +- if (refcount_sub_and_test(cnt, &pd->refcnt)) +- padata_free_pd(pd); ++ padata_put_pd_cnt(pd, cnt); + } + + /** +@@ -678,8 +701,7 @@ static int padata_replace(struct padata_instance *pinst) + synchronize_rcu(); + + list_for_each_entry_continue_reverse(ps, &pinst->pslist, list) +- if (refcount_dec_and_test(&ps->opd->refcnt)) +- padata_free_pd(ps->opd); ++ padata_put_pd(ps->opd); + + pinst->flags &= ~PADATA_RESET; + +@@ -967,7 +989,7 @@ static ssize_t padata_sysfs_store(struct kobject *kobj, struct attribute *attr, + + pinst = kobj2pinst(kobj); + pentry = attr2pentry(attr); +- if (pentry->show) ++ if (pentry->store) + ret = pentry->store(pinst, attr, buf, count); + + return ret; +@@ -1118,11 +1140,16 @@ void padata_free_shell(struct padata_shell *ps) + if (!ps) + return; + ++ /* ++ * Wait for all _do_serial calls to finish to avoid touching ++ * freed pd's and ps's. ++ */ ++ synchronize_rcu(); ++ + mutex_lock(&ps->pinst->lock); + list_del(&ps->list); + pd = rcu_dereference_protected(ps->pd, 1); +- if (refcount_dec_and_test(&pd->refcnt)) +- padata_free_pd(pd); ++ padata_put_pd(pd); + mutex_unlock(&ps->pinst->lock); + + kfree(ps); +diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c +index 8d35b9f9aaa3f2..c2fc58938dee5d 100644 +--- a/kernel/power/hibernate.c ++++ b/kernel/power/hibernate.c +@@ -599,7 +599,11 @@ int hibernation_platform_enter(void) + + local_irq_disable(); + system_state = SYSTEM_SUSPEND; +- syscore_suspend(); ++ ++ error = syscore_suspend(); ++ if (error) ++ goto Enable_irqs; ++ + if (pm_wakeup_pending()) { + error = -EAGAIN; + goto Power_up; +@@ -611,6 +615,7 @@ int hibernation_platform_enter(void) + + Power_up: + syscore_resume(); ++ Enable_irqs: + system_state = SYSTEM_RUNNING; + local_irq_enable(); + +diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c +index 458d359f5991ca..a49f136014ce6b 100644 +--- a/kernel/sched/cpufreq_schedutil.c ++++ b/kernel/sched/cpufreq_schedutil.c +@@ -83,7 +83,7 @@ static bool sugov_should_update_freq(struct sugov_policy *sg_policy, u64 time) + + if (unlikely(sg_policy->limits_changed)) { + sg_policy->limits_changed = false; +- sg_policy->need_freq_update = true; ++ sg_policy->need_freq_update = cpufreq_driver_test_flags(CPUFREQ_NEED_UPDATE_LIMITS); + return true; + } + +@@ -96,7 +96,7 @@ static bool sugov_update_next_freq(struct sugov_policy *sg_policy, u64 time, + unsigned int next_freq) + { + if (sg_policy->need_freq_update) +- sg_policy->need_freq_update = cpufreq_driver_test_flags(CPUFREQ_NEED_UPDATE_LIMITS); ++ sg_policy->need_freq_update = false; + else if (sg_policy->next_freq == next_freq) + return false; + +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index 3b2cfdb8d788d9..726fa69c4d88b2 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -8921,6 +8921,8 @@ int can_migrate_task(struct task_struct *p, struct lb_env *env) + int tsk_cache_hot; + + lockdep_assert_rq_held(env->src_rq); ++ if (p->sched_task_hot) ++ p->sched_task_hot = 0; + + /* + * We do not migrate tasks that are: +@@ -8993,10 +8995,8 @@ int can_migrate_task(struct task_struct *p, struct lb_env *env) + + if (tsk_cache_hot <= 0 || + env->sd->nr_balance_failed > env->sd->cache_nice_tries) { +- if (tsk_cache_hot == 1) { +- schedstat_inc(env->sd->lb_hot_gained[env->idle]); +- schedstat_inc(p->stats.nr_forced_migrations); +- } ++ if (tsk_cache_hot == 1) ++ p->sched_task_hot = 1; + return 1; + } + +@@ -9011,6 +9011,12 @@ static void detach_task(struct task_struct *p, struct lb_env *env) + { + lockdep_assert_rq_held(env->src_rq); + ++ if (p->sched_task_hot) { ++ p->sched_task_hot = 0; ++ schedstat_inc(env->sd->lb_hot_gained[env->idle]); ++ schedstat_inc(p->stats.nr_forced_migrations); ++ } ++ + deactivate_task(env->src_rq, p, DEQUEUE_NOCLOCK); + set_task_cpu(p, env->dst_cpu); + } +@@ -9171,6 +9177,9 @@ static int detach_tasks(struct lb_env *env) + + continue; + next: ++ if (p->sched_task_hot) ++ schedstat_inc(p->stats.nr_failed_migrations_hot); ++ + list_move(&p->se.group_node, tasks); + } + +@@ -9773,7 +9782,7 @@ static bool sched_use_asym_prio(struct sched_domain *sd, int cpu) + * can only do it if @group is an SMT group and has exactly on busy CPU. Larger + * imbalances in the number of CPUS are dealt with in find_busiest_group(). + * +- * If we are balancing load within an SMT core, or at DIE domain level, always ++ * If we are balancing load within an SMT core, or at PKG domain level, always + * proceed. + * + * Return: true if @env::dst_cpu can do with asym_packing load balance. False +diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c +index 3a13cecf177402..2ed884bb362137 100644 +--- a/kernel/sched/topology.c ++++ b/kernel/sched/topology.c +@@ -1117,7 +1117,7 @@ build_overlap_sched_groups(struct sched_domain *sd, int cpu) + * + * - Simultaneous multithreading (SMT) + * - Multi-Core Cache (MC) +- * - Package (DIE) ++ * - Package (PKG) + * + * Where the last one more or less denotes everything up to a NUMA node. + * +@@ -1139,13 +1139,13 @@ build_overlap_sched_groups(struct sched_domain *sd, int cpu) + * + * CPU 0 1 2 3 4 5 6 7 + * +- * DIE [ ] ++ * PKG [ ] + * MC [ ] [ ] + * SMT [ ] [ ] [ ] [ ] + * + * - or - + * +- * DIE 0-7 0-7 0-7 0-7 0-7 0-7 0-7 0-7 ++ * PKG 0-7 0-7 0-7 0-7 0-7 0-7 0-7 0-7 + * MC 0-3 0-3 0-3 0-3 4-7 4-7 4-7 4-7 + * SMT 0-1 0-1 2-3 2-3 4-5 4-5 6-7 6-7 + * +@@ -1679,7 +1679,7 @@ static struct sched_domain_topology_level default_topology[] = { + #ifdef CONFIG_SCHED_MC + { cpu_coregroup_mask, cpu_core_flags, SD_INIT_NAME(MC) }, + #endif +- { cpu_cpu_mask, SD_INIT_NAME(DIE) }, ++ { cpu_cpu_mask, SD_INIT_NAME(PKG) }, + { NULL, }, + }; + +diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c +index aab43ba3daeb51..9d8f60e0cb5546 100644 +--- a/kernel/trace/bpf_trace.c ++++ b/kernel/trace/bpf_trace.c +@@ -616,7 +616,8 @@ static const struct bpf_func_proto bpf_perf_event_read_value_proto = { + + static __always_inline u64 + __bpf_perf_event_output(struct pt_regs *regs, struct bpf_map *map, +- u64 flags, struct perf_sample_data *sd) ++ u64 flags, struct perf_raw_record *raw, ++ struct perf_sample_data *sd) + { + struct bpf_array *array = container_of(map, struct bpf_array, map); + unsigned int cpu = smp_processor_id(); +@@ -641,6 +642,8 @@ __bpf_perf_event_output(struct pt_regs *regs, struct bpf_map *map, + if (unlikely(event->oncpu != cpu)) + return -EOPNOTSUPP; + ++ perf_sample_save_raw_data(sd, event, raw); ++ + return perf_event_output(event, sd, regs); + } + +@@ -684,9 +687,8 @@ BPF_CALL_5(bpf_perf_event_output, struct pt_regs *, regs, struct bpf_map *, map, + } + + perf_sample_data_init(sd, 0, 0); +- perf_sample_save_raw_data(sd, &raw); + +- err = __bpf_perf_event_output(regs, map, flags, sd); ++ err = __bpf_perf_event_output(regs, map, flags, &raw, sd); + out: + this_cpu_dec(bpf_trace_nest_level); + preempt_enable(); +@@ -745,9 +747,8 @@ u64 bpf_event_output(struct bpf_map *map, u64 flags, void *meta, u64 meta_size, + + perf_fetch_caller_regs(regs); + perf_sample_data_init(sd, 0, 0); +- perf_sample_save_raw_data(sd, &raw); + +- ret = __bpf_perf_event_output(regs, map, flags, sd); ++ ret = __bpf_perf_event_output(regs, map, flags, &raw, sd); + out: + this_cpu_dec(bpf_event_output_nest_level); + preempt_enable(); +@@ -852,7 +853,7 @@ static int bpf_send_signal_common(u32 sig, enum pid_type type) + if (unlikely(is_global_init(current))) + return -EPERM; + +- if (irqs_disabled()) { ++ if (!preemptible()) { + /* Do an early check on signal validity. Otherwise, + * the error is lost in deferred irq_work. + */ +diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c +index 26a3095bec4620..0f66dd8715bd87 100644 +--- a/net/ax25/af_ax25.c ++++ b/net/ax25/af_ax25.c +@@ -467,7 +467,7 @@ static int ax25_ctl_ioctl(const unsigned int cmd, void __user *arg) + goto out_put; + } + +-static void ax25_fillin_cb_from_dev(ax25_cb *ax25, ax25_dev *ax25_dev) ++static void ax25_fillin_cb_from_dev(ax25_cb *ax25, const ax25_dev *ax25_dev) + { + ax25->rtt = msecs_to_jiffies(ax25_dev->values[AX25_VALUES_T1]) / 2; + ax25->t1 = msecs_to_jiffies(ax25_dev->values[AX25_VALUES_T1]); +@@ -677,22 +677,22 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname, + break; + } + +- rtnl_lock(); +- dev = __dev_get_by_name(&init_net, devname); ++ rcu_read_lock(); ++ dev = dev_get_by_name_rcu(&init_net, devname); + if (!dev) { +- rtnl_unlock(); ++ rcu_read_unlock(); + res = -ENODEV; + break; + } + + ax25->ax25_dev = ax25_dev_ax25dev(dev); + if (!ax25->ax25_dev) { +- rtnl_unlock(); ++ rcu_read_unlock(); + res = -ENODEV; + break; + } + ax25_fillin_cb(ax25, ax25->ax25_dev); +- rtnl_unlock(); ++ rcu_read_unlock(); + break; + + default: +diff --git a/net/ax25/ax25_dev.c b/net/ax25/ax25_dev.c +index 67ae6b8c52989b..0715f9b1527569 100644 +--- a/net/ax25/ax25_dev.c ++++ b/net/ax25/ax25_dev.c +@@ -87,7 +87,7 @@ void ax25_dev_device_up(struct net_device *dev) + + spin_lock_bh(&ax25_dev_lock); + list_add(&ax25_dev->list, &ax25_dev_list); +- dev->ax25_ptr = ax25_dev; ++ rcu_assign_pointer(dev->ax25_ptr, ax25_dev); + spin_unlock_bh(&ax25_dev_lock); + + ax25_register_dev_sysctl(ax25_dev); +@@ -122,7 +122,7 @@ void ax25_dev_device_down(struct net_device *dev) + } + } + +- dev->ax25_ptr = NULL; ++ RCU_INIT_POINTER(dev->ax25_ptr, NULL); + spin_unlock_bh(&ax25_dev_lock); + netdev_put(dev, &ax25_dev->dev_tracker); + ax25_dev_put(ax25_dev); +diff --git a/net/ax25/ax25_ip.c b/net/ax25/ax25_ip.c +index 36249776c021e7..215d4ccf12b913 100644 +--- a/net/ax25/ax25_ip.c ++++ b/net/ax25/ax25_ip.c +@@ -122,6 +122,7 @@ netdev_tx_t ax25_ip_xmit(struct sk_buff *skb) + if (dev == NULL) + dev = skb->dev; + ++ rcu_read_lock(); + if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL) { + kfree_skb(skb); + goto put; +@@ -202,7 +203,7 @@ netdev_tx_t ax25_ip_xmit(struct sk_buff *skb) + ax25_queue_xmit(skb, dev); + + put: +- ++ rcu_read_unlock(); + ax25_route_lock_unuse(); + return NETDEV_TX_OK; + } +diff --git a/net/ax25/ax25_out.c b/net/ax25/ax25_out.c +index 3db76d2470e954..8bca2ace98e51b 100644 +--- a/net/ax25/ax25_out.c ++++ b/net/ax25/ax25_out.c +@@ -39,10 +39,14 @@ ax25_cb *ax25_send_frame(struct sk_buff *skb, int paclen, const ax25_address *sr + * specified. + */ + if (paclen == 0) { +- if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL) ++ rcu_read_lock(); ++ ax25_dev = ax25_dev_ax25dev(dev); ++ if (!ax25_dev) { ++ rcu_read_unlock(); + return NULL; +- ++ } + paclen = ax25_dev->values[AX25_VALUES_PACLEN]; ++ rcu_read_unlock(); + } + + /* +@@ -53,13 +57,19 @@ ax25_cb *ax25_send_frame(struct sk_buff *skb, int paclen, const ax25_address *sr + return ax25; /* It already existed */ + } + +- if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL) ++ rcu_read_lock(); ++ ax25_dev = ax25_dev_ax25dev(dev); ++ if (!ax25_dev) { ++ rcu_read_unlock(); + return NULL; ++ } + +- if ((ax25 = ax25_create_cb()) == NULL) ++ if ((ax25 = ax25_create_cb()) == NULL) { ++ rcu_read_unlock(); + return NULL; +- ++ } + ax25_fillin_cb(ax25, ax25_dev); ++ rcu_read_unlock(); + + ax25->source_addr = *src; + ax25->dest_addr = *dest; +@@ -358,7 +368,9 @@ void ax25_queue_xmit(struct sk_buff *skb, struct net_device *dev) + { + unsigned char *ptr; + ++ rcu_read_lock(); + skb->protocol = ax25_type_trans(skb, ax25_fwd_dev(dev)); ++ rcu_read_unlock(); + + ptr = skb_push(skb, 1); + *ptr = 0x00; /* KISS */ +diff --git a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c +index b7c4d656a94b71..69de75db0c9c21 100644 +--- a/net/ax25/ax25_route.c ++++ b/net/ax25/ax25_route.c +@@ -406,6 +406,7 @@ int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr) + ax25_route_lock_unuse(); + return -EHOSTUNREACH; + } ++ rcu_read_lock(); + if ((ax25->ax25_dev = ax25_dev_ax25dev(ax25_rt->dev)) == NULL) { + err = -EHOSTUNREACH; + goto put; +@@ -442,6 +443,7 @@ int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr) + } + + put: ++ rcu_read_unlock(); + ax25_route_lock_unuse(); + return err; + } +diff --git a/net/core/dev.c b/net/core/dev.c +index 69da7b009f8b98..479a3892f98c3c 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -9346,6 +9346,10 @@ static int dev_xdp_attach(struct net_device *dev, struct netlink_ext_ack *extack + NL_SET_ERR_MSG(extack, "Program bound to different device"); + return -EINVAL; + } ++ if (bpf_prog_is_dev_bound(new_prog->aux) && mode == XDP_MODE_SKB) { ++ NL_SET_ERR_MSG(extack, "Can't attach device-bound programs in generic mode"); ++ return -EINVAL; ++ } + if (new_prog->expected_attach_type == BPF_XDP_DEVMAP) { + NL_SET_ERR_MSG(extack, "BPF_XDP_DEVMAP programs can not be attached to a device"); + return -EINVAL; +diff --git a/net/core/filter.c b/net/core/filter.c +index 5881944f1681c9..84992279f4b10e 100644 +--- a/net/core/filter.c ++++ b/net/core/filter.c +@@ -7604,7 +7604,7 @@ static const struct bpf_func_proto bpf_sock_ops_load_hdr_opt_proto = { + .gpl_only = false, + .ret_type = RET_INTEGER, + .arg1_type = ARG_PTR_TO_CTX, +- .arg2_type = ARG_PTR_TO_MEM, ++ .arg2_type = ARG_PTR_TO_MEM | MEM_WRITE, + .arg3_type = ARG_CONST_SIZE, + .arg4_type = ARG_ANYTHING, + }; +diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c +index 373b5b2231c492..0b15272dd2d35b 100644 +--- a/net/core/sysctl_net_core.c ++++ b/net/core/sysctl_net_core.c +@@ -297,7 +297,7 @@ static int proc_do_dev_weight(struct ctl_table *table, int write, + int ret, weight; + + mutex_lock(&dev_weight_mutex); +- ret = proc_dointvec(table, write, buffer, lenp, ppos); ++ ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); + if (!ret && write) { + weight = READ_ONCE(weight_p); + WRITE_ONCE(dev_rx_weight, weight * dev_weight_rx_bias); +@@ -422,6 +422,7 @@ static struct ctl_table net_core_table[] = { + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_do_dev_weight, ++ .extra1 = SYSCTL_ONE, + }, + { + .procname = "dev_weight_rx_bias", +@@ -429,6 +430,7 @@ static struct ctl_table net_core_table[] = { + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_do_dev_weight, ++ .extra1 = SYSCTL_ONE, + }, + { + .procname = "dev_weight_tx_bias", +@@ -436,6 +438,7 @@ static struct ctl_table net_core_table[] = { + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_do_dev_weight, ++ .extra1 = SYSCTL_ONE, + }, + { + .procname = "netdev_max_backlog", +diff --git a/net/ethtool/netlink.c b/net/ethtool/netlink.c +index fe3553f60bf39e..c1ad63bee8eade 100644 +--- a/net/ethtool/netlink.c ++++ b/net/ethtool/netlink.c +@@ -41,7 +41,7 @@ int ethnl_ops_begin(struct net_device *dev) + pm_runtime_get_sync(dev->dev.parent); + + if (!netif_device_present(dev) || +- dev->reg_state == NETREG_UNREGISTERING) { ++ dev->reg_state >= NETREG_UNREGISTERING) { + ret = -ENODEV; + goto err; + } +diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c +index 2790f3964d6bd4..9317f96127c1b1 100644 +--- a/net/hsr/hsr_forward.c ++++ b/net/hsr/hsr_forward.c +@@ -588,9 +588,12 @@ static int fill_frame_info(struct hsr_frame_info *frame, + frame->is_vlan = true; + + if (frame->is_vlan) { +- if (skb->mac_len < offsetofend(struct hsr_vlan_ethhdr, vlanhdr)) ++ /* Note: skb->mac_len might be wrong here. */ ++ if (!pskb_may_pull(skb, ++ skb_mac_offset(skb) + ++ offsetofend(struct hsr_vlan_ethhdr, vlanhdr))) + return -EINVAL; +- vlan_hdr = (struct hsr_vlan_ethhdr *)ethhdr; ++ vlan_hdr = (struct hsr_vlan_ethhdr *)skb_mac_header(skb); + proto = vlan_hdr->vlanhdr.h_vlan_encapsulated_proto; + /* FIXME: */ + netdev_warn_once(skb->dev, "VLAN not yet supported"); +diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c +index 9dffdd876fef50..a6adf6a2ec4b57 100644 +--- a/net/ipv4/icmp.c ++++ b/net/ipv4/icmp.c +@@ -316,7 +316,6 @@ static bool icmpv4_xrlim_allow(struct net *net, struct rtable *rt, + struct dst_entry *dst = &rt->dst; + struct inet_peer *peer; + bool rc = true; +- int vif; + + if (!apply_ratelimit) + return true; +@@ -325,12 +324,12 @@ static bool icmpv4_xrlim_allow(struct net *net, struct rtable *rt, + if (dst->dev && (dst->dev->flags&IFF_LOOPBACK)) + goto out; + +- vif = l3mdev_master_ifindex(dst->dev); +- peer = inet_getpeer_v4(net->ipv4.peers, fl4->daddr, vif, 1); ++ rcu_read_lock(); ++ peer = inet_getpeer_v4(net->ipv4.peers, fl4->daddr, ++ l3mdev_master_ifindex_rcu(dst->dev)); + rc = inet_peer_xrlim_allow(peer, + READ_ONCE(net->ipv4.sysctl_icmp_ratelimit)); +- if (peer) +- inet_putpeer(peer); ++ rcu_read_unlock(); + out: + if (!rc) + __ICMP_INC_STATS(net, ICMP_MIB_RATELIMITHOST); +diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c +index e9fed83e9b3cc5..23896b6b8417df 100644 +--- a/net/ipv4/inetpeer.c ++++ b/net/ipv4/inetpeer.c +@@ -98,6 +98,7 @@ static struct inet_peer *lookup(const struct inetpeer_addr *daddr, + { + struct rb_node **pp, *parent, *next; + struct inet_peer *p; ++ u32 now; + + pp = &base->rb_root.rb_node; + parent = NULL; +@@ -111,8 +112,9 @@ static struct inet_peer *lookup(const struct inetpeer_addr *daddr, + p = rb_entry(parent, struct inet_peer, rb_node); + cmp = inetpeer_addr_cmp(daddr, &p->daddr); + if (cmp == 0) { +- if (!refcount_inc_not_zero(&p->refcnt)) +- break; ++ now = jiffies; ++ if (READ_ONCE(p->dtime) != now) ++ WRITE_ONCE(p->dtime, now); + return p; + } + if (gc_stack) { +@@ -158,9 +160,6 @@ static void inet_peer_gc(struct inet_peer_base *base, + for (i = 0; i < gc_cnt; i++) { + p = gc_stack[i]; + +- /* The READ_ONCE() pairs with the WRITE_ONCE() +- * in inet_putpeer() +- */ + delta = (__u32)jiffies - READ_ONCE(p->dtime); + + if (delta < ttl || !refcount_dec_if_one(&p->refcnt)) +@@ -176,31 +175,23 @@ static void inet_peer_gc(struct inet_peer_base *base, + } + } + ++/* Must be called under RCU : No refcount change is done here. */ + struct inet_peer *inet_getpeer(struct inet_peer_base *base, +- const struct inetpeer_addr *daddr, +- int create) ++ const struct inetpeer_addr *daddr) + { + struct inet_peer *p, *gc_stack[PEER_MAX_GC]; + struct rb_node **pp, *parent; + unsigned int gc_cnt, seq; +- int invalidated; + + /* Attempt a lockless lookup first. + * Because of a concurrent writer, we might not find an existing entry. + */ +- rcu_read_lock(); + seq = read_seqbegin(&base->lock); + p = lookup(daddr, base, seq, NULL, &gc_cnt, &parent, &pp); +- invalidated = read_seqretry(&base->lock, seq); +- rcu_read_unlock(); + + if (p) + return p; + +- /* If no writer did a change during our lookup, we can return early. */ +- if (!create && !invalidated) +- return NULL; +- + /* retry an exact lookup, taking the lock before. + * At least, nodes should be hot in our cache. + */ +@@ -209,12 +200,12 @@ struct inet_peer *inet_getpeer(struct inet_peer_base *base, + + gc_cnt = 0; + p = lookup(daddr, base, seq, gc_stack, &gc_cnt, &parent, &pp); +- if (!p && create) { ++ if (!p) { + p = kmem_cache_alloc(peer_cachep, GFP_ATOMIC); + if (p) { + p->daddr = *daddr; + p->dtime = (__u32)jiffies; +- refcount_set(&p->refcnt, 2); ++ refcount_set(&p->refcnt, 1); + atomic_set(&p->rid, 0); + p->metrics[RTAX_LOCK-1] = INETPEER_METRICS_NEW; + p->rate_tokens = 0; +@@ -239,15 +230,9 @@ EXPORT_SYMBOL_GPL(inet_getpeer); + + void inet_putpeer(struct inet_peer *p) + { +- /* The WRITE_ONCE() pairs with itself (we run lockless) +- * and the READ_ONCE() in inet_peer_gc() +- */ +- WRITE_ONCE(p->dtime, (__u32)jiffies); +- + if (refcount_dec_and_test(&p->refcnt)) + call_rcu(&p->rcu, inetpeer_free_rcu); + } +-EXPORT_SYMBOL_GPL(inet_putpeer); + + /* + * Check transmit rate limitation for given message. +diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c +index fb947d1613fe2b..877d1e03150c77 100644 +--- a/net/ipv4/ip_fragment.c ++++ b/net/ipv4/ip_fragment.c +@@ -82,15 +82,20 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *skb, + static void ip4_frag_init(struct inet_frag_queue *q, const void *a) + { + struct ipq *qp = container_of(q, struct ipq, q); +- struct net *net = q->fqdir->net; +- + const struct frag_v4_compare_key *key = a; ++ struct net *net = q->fqdir->net; ++ struct inet_peer *p = NULL; + + q->key.v4 = *key; + qp->ecn = 0; +- qp->peer = q->fqdir->max_dist ? +- inet_getpeer_v4(net->ipv4.peers, key->saddr, key->vif, 1) : +- NULL; ++ if (q->fqdir->max_dist) { ++ rcu_read_lock(); ++ p = inet_getpeer_v4(net->ipv4.peers, key->saddr, key->vif); ++ if (p && !refcount_inc_not_zero(&p->refcnt)) ++ p = NULL; ++ rcu_read_unlock(); ++ } ++ qp->peer = p; + } + + static void ip4_frag_free(struct inet_frag_queue *q) +diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c +index dc0ad979a894ab..af9412a507cf34 100644 +--- a/net/ipv4/ipmr.c ++++ b/net/ipv4/ipmr.c +@@ -816,7 +816,7 @@ static void ipmr_update_thresholds(struct mr_table *mrt, struct mr_mfc *cache, + cache->mfc_un.res.maxvif = vifi + 1; + } + } +- cache->mfc_un.res.lastuse = jiffies; ++ WRITE_ONCE(cache->mfc_un.res.lastuse, jiffies); + } + + static int vif_add(struct net *net, struct mr_table *mrt, +@@ -1666,9 +1666,9 @@ int ipmr_ioctl(struct sock *sk, int cmd, void *arg) + rcu_read_lock(); + c = ipmr_cache_find(mrt, sr->src.s_addr, sr->grp.s_addr); + if (c) { +- sr->pktcnt = c->_c.mfc_un.res.pkt; +- sr->bytecnt = c->_c.mfc_un.res.bytes; +- sr->wrong_if = c->_c.mfc_un.res.wrong_if; ++ sr->pktcnt = atomic_long_read(&c->_c.mfc_un.res.pkt); ++ sr->bytecnt = atomic_long_read(&c->_c.mfc_un.res.bytes); ++ sr->wrong_if = atomic_long_read(&c->_c.mfc_un.res.wrong_if); + rcu_read_unlock(); + return 0; + } +@@ -1738,9 +1738,9 @@ int ipmr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg) + rcu_read_lock(); + c = ipmr_cache_find(mrt, sr.src.s_addr, sr.grp.s_addr); + if (c) { +- sr.pktcnt = c->_c.mfc_un.res.pkt; +- sr.bytecnt = c->_c.mfc_un.res.bytes; +- sr.wrong_if = c->_c.mfc_un.res.wrong_if; ++ sr.pktcnt = atomic_long_read(&c->_c.mfc_un.res.pkt); ++ sr.bytecnt = atomic_long_read(&c->_c.mfc_un.res.bytes); ++ sr.wrong_if = atomic_long_read(&c->_c.mfc_un.res.wrong_if); + rcu_read_unlock(); + + if (copy_to_user(arg, &sr, sizeof(sr))) +@@ -1973,9 +1973,9 @@ static void ip_mr_forward(struct net *net, struct mr_table *mrt, + int vif, ct; + + vif = c->_c.mfc_parent; +- c->_c.mfc_un.res.pkt++; +- c->_c.mfc_un.res.bytes += skb->len; +- c->_c.mfc_un.res.lastuse = jiffies; ++ atomic_long_inc(&c->_c.mfc_un.res.pkt); ++ atomic_long_add(skb->len, &c->_c.mfc_un.res.bytes); ++ WRITE_ONCE(c->_c.mfc_un.res.lastuse, jiffies); + + if (c->mfc_origin == htonl(INADDR_ANY) && true_vifi >= 0) { + struct mfc_cache *cache_proxy; +@@ -2006,7 +2006,7 @@ static void ip_mr_forward(struct net *net, struct mr_table *mrt, + goto dont_forward; + } + +- c->_c.mfc_un.res.wrong_if++; ++ atomic_long_inc(&c->_c.mfc_un.res.wrong_if); + + if (true_vifi >= 0 && mrt->mroute_do_assert && + /* pimsm uses asserts, when switching from RPT to SPT, +@@ -3013,9 +3013,9 @@ static int ipmr_mfc_seq_show(struct seq_file *seq, void *v) + + if (it->cache != &mrt->mfc_unres_queue) { + seq_printf(seq, " %8lu %8lu %8lu", +- mfc->_c.mfc_un.res.pkt, +- mfc->_c.mfc_un.res.bytes, +- mfc->_c.mfc_un.res.wrong_if); ++ atomic_long_read(&mfc->_c.mfc_un.res.pkt), ++ atomic_long_read(&mfc->_c.mfc_un.res.bytes), ++ atomic_long_read(&mfc->_c.mfc_un.res.wrong_if)); + for (n = mfc->_c.mfc_un.res.minvif; + n < mfc->_c.mfc_un.res.maxvif; n++) { + if (VIF_EXISTS(mrt, n) && +diff --git a/net/ipv4/ipmr_base.c b/net/ipv4/ipmr_base.c +index f0af12a2f70bcd..28d77d454d442e 100644 +--- a/net/ipv4/ipmr_base.c ++++ b/net/ipv4/ipmr_base.c +@@ -263,9 +263,9 @@ int mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, + lastuse = READ_ONCE(c->mfc_un.res.lastuse); + lastuse = time_after_eq(jiffies, lastuse) ? jiffies - lastuse : 0; + +- mfcs.mfcs_packets = c->mfc_un.res.pkt; +- mfcs.mfcs_bytes = c->mfc_un.res.bytes; +- mfcs.mfcs_wrong_if = c->mfc_un.res.wrong_if; ++ mfcs.mfcs_packets = atomic_long_read(&c->mfc_un.res.pkt); ++ mfcs.mfcs_bytes = atomic_long_read(&c->mfc_un.res.bytes); ++ mfcs.mfcs_wrong_if = atomic_long_read(&c->mfc_un.res.wrong_if); + if (nla_put_64bit(skb, RTA_MFC_STATS, sizeof(mfcs), &mfcs, RTA_PAD) || + nla_put_u64_64bit(skb, RTA_EXPIRES, jiffies_to_clock_t(lastuse), + RTA_PAD)) +@@ -330,9 +330,6 @@ int mr_table_dump(struct mr_table *mrt, struct sk_buff *skb, + list_for_each_entry(mfc, &mrt->mfc_unres_queue, list) { + if (e < s_e) + goto next_entry2; +- if (filter->dev && +- !mr_mfc_uses_dev(mrt, mfc, filter->dev)) +- goto next_entry2; + + err = fill(mrt, skb, NETLINK_CB(cb->skb).portid, + cb->nlh->nlmsg_seq, mfc, RTM_NEWROUTE, flags); +diff --git a/net/ipv4/route.c b/net/ipv4/route.c +index 285482060082f8..61fc2166a870e6 100644 +--- a/net/ipv4/route.c ++++ b/net/ipv4/route.c +@@ -882,11 +882,11 @@ void ip_rt_send_redirect(struct sk_buff *skb) + } + log_martians = IN_DEV_LOG_MARTIANS(in_dev); + vif = l3mdev_master_ifindex_rcu(rt->dst.dev); +- rcu_read_unlock(); + + net = dev_net(rt->dst.dev); +- peer = inet_getpeer_v4(net->ipv4.peers, ip_hdr(skb)->saddr, vif, 1); ++ peer = inet_getpeer_v4(net->ipv4.peers, ip_hdr(skb)->saddr, vif); + if (!peer) { ++ rcu_read_unlock(); + icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, + rt_nexthop(rt, ip_hdr(skb)->daddr)); + return; +@@ -905,7 +905,7 @@ void ip_rt_send_redirect(struct sk_buff *skb) + */ + if (peer->n_redirects >= ip_rt_redirect_number) { + peer->rate_last = jiffies; +- goto out_put_peer; ++ goto out_unlock; + } + + /* Check for load limit; set rate_last to the latest sent +@@ -926,8 +926,8 @@ void ip_rt_send_redirect(struct sk_buff *skb) + &ip_hdr(skb)->saddr, inet_iif(skb), + &ip_hdr(skb)->daddr, &gw); + } +-out_put_peer: +- inet_putpeer(peer); ++out_unlock: ++ rcu_read_unlock(); + } + + static int ip_error(struct sk_buff *skb) +@@ -987,9 +987,9 @@ static int ip_error(struct sk_buff *skb) + break; + } + ++ rcu_read_lock(); + peer = inet_getpeer_v4(net->ipv4.peers, ip_hdr(skb)->saddr, +- l3mdev_master_ifindex(skb->dev), 1); +- ++ l3mdev_master_ifindex_rcu(skb->dev)); + send = true; + if (peer) { + now = jiffies; +@@ -1001,8 +1001,9 @@ static int ip_error(struct sk_buff *skb) + peer->rate_tokens -= ip_rt_error_cost; + else + send = false; +- inet_putpeer(peer); + } ++ rcu_read_unlock(); ++ + if (send) + icmp_send(skb, ICMP_DEST_UNREACH, code, 0); + +diff --git a/net/ipv4/tcp_cubic.c b/net/ipv4/tcp_cubic.c +index 0fd78ecb67e756..5ff7be13deb6b7 100644 +--- a/net/ipv4/tcp_cubic.c ++++ b/net/ipv4/tcp_cubic.c +@@ -392,6 +392,10 @@ static void hystart_update(struct sock *sk, u32 delay) + if (after(tp->snd_una, ca->end_seq)) + bictcp_hystart_reset(sk); + ++ /* hystart triggers when cwnd is larger than some threshold */ ++ if (tcp_snd_cwnd(tp) < hystart_low_window) ++ return; ++ + if (hystart_detect & HYSTART_ACK_TRAIN) { + u32 now = bictcp_clock_us(sk); + +@@ -467,9 +471,7 @@ __bpf_kfunc static void cubictcp_acked(struct sock *sk, const struct ack_sample + if (ca->delay_min == 0 || ca->delay_min > delay) + ca->delay_min = delay; + +- /* hystart triggers when cwnd is larger than some threshold */ +- if (!ca->found && tcp_in_slow_start(tp) && hystart && +- tcp_snd_cwnd(tp) >= hystart_low_window) ++ if (!ca->found && tcp_in_slow_start(tp) && hystart) + hystart_update(sk, delay); + } + +diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c +index cfddc94508f0b7..3771ed22c2f56f 100644 +--- a/net/ipv4/tcp_output.c ++++ b/net/ipv4/tcp_output.c +@@ -263,11 +263,14 @@ static u16 tcp_select_window(struct sock *sk) + u32 cur_win, new_win; + + /* Make the window 0 if we failed to queue the data because we +- * are out of memory. The window is temporary, so we don't store +- * it on the socket. ++ * are out of memory. + */ +- if (unlikely(inet_csk(sk)->icsk_ack.pending & ICSK_ACK_NOMEM)) ++ if (unlikely(inet_csk(sk)->icsk_ack.pending & ICSK_ACK_NOMEM)) { ++ tp->pred_flags = 0; ++ tp->rcv_wnd = 0; ++ tp->rcv_wup = tp->rcv_nxt; + return 0; ++ } + + cur_win = tcp_receive_window(tp); + new_win = __tcp_select_window(sk); +diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c +index 25a3a726fa1177..35df405ce1f753 100644 +--- a/net/ipv6/icmp.c ++++ b/net/ipv6/icmp.c +@@ -222,10 +222,10 @@ static bool icmpv6_xrlim_allow(struct sock *sk, u8 type, + if (rt->rt6i_dst.plen < 128) + tmo >>= ((128 - rt->rt6i_dst.plen)>>5); + +- peer = inet_getpeer_v6(net->ipv6.peers, &fl6->daddr, 1); ++ rcu_read_lock(); ++ peer = inet_getpeer_v6(net->ipv6.peers, &fl6->daddr); + res = inet_peer_xrlim_allow(peer, tmo); +- if (peer) +- inet_putpeer(peer); ++ rcu_read_unlock(); + } + if (!res) + __ICMP6_INC_STATS(net, ip6_dst_idev(dst), +diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c +index 2341a4373bb949..cd89a2b35dfb56 100644 +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -612,15 +612,15 @@ int ip6_forward(struct sk_buff *skb) + else + target = &hdr->daddr; + +- peer = inet_getpeer_v6(net->ipv6.peers, &hdr->daddr, 1); ++ rcu_read_lock(); ++ peer = inet_getpeer_v6(net->ipv6.peers, &hdr->daddr); + + /* Limit redirects both by destination (here) + and by source (inside ndisc_send_redirect) + */ + if (inet_peer_xrlim_allow(peer, 1*HZ)) + ndisc_send_redirect(skb, target); +- if (peer) +- inet_putpeer(peer); ++ rcu_read_unlock(); + } else { + int addrtype = ipv6_addr_type(&hdr->saddr); + +diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c +index 1571e85a3531ed..7f19868d7d6c6b 100644 +--- a/net/ipv6/ip6mr.c ++++ b/net/ipv6/ip6mr.c +@@ -506,9 +506,9 @@ static int ipmr_mfc_seq_show(struct seq_file *seq, void *v) + + if (it->cache != &mrt->mfc_unres_queue) { + seq_printf(seq, " %8lu %8lu %8lu", +- mfc->_c.mfc_un.res.pkt, +- mfc->_c.mfc_un.res.bytes, +- mfc->_c.mfc_un.res.wrong_if); ++ atomic_long_read(&mfc->_c.mfc_un.res.pkt), ++ atomic_long_read(&mfc->_c.mfc_un.res.bytes), ++ atomic_long_read(&mfc->_c.mfc_un.res.wrong_if)); + for (n = mfc->_c.mfc_un.res.minvif; + n < mfc->_c.mfc_un.res.maxvif; n++) { + if (VIF_EXISTS(mrt, n) && +@@ -870,7 +870,7 @@ static void ip6mr_update_thresholds(struct mr_table *mrt, + cache->mfc_un.res.maxvif = vifi + 1; + } + } +- cache->mfc_un.res.lastuse = jiffies; ++ WRITE_ONCE(cache->mfc_un.res.lastuse, jiffies); + } + + static int mif6_add(struct net *net, struct mr_table *mrt, +@@ -1931,9 +1931,9 @@ int ip6mr_ioctl(struct sock *sk, int cmd, void *arg) + c = ip6mr_cache_find(mrt, &sr->src.sin6_addr, + &sr->grp.sin6_addr); + if (c) { +- sr->pktcnt = c->_c.mfc_un.res.pkt; +- sr->bytecnt = c->_c.mfc_un.res.bytes; +- sr->wrong_if = c->_c.mfc_un.res.wrong_if; ++ sr->pktcnt = atomic_long_read(&c->_c.mfc_un.res.pkt); ++ sr->bytecnt = atomic_long_read(&c->_c.mfc_un.res.bytes); ++ sr->wrong_if = atomic_long_read(&c->_c.mfc_un.res.wrong_if); + rcu_read_unlock(); + return 0; + } +@@ -2003,9 +2003,9 @@ int ip6mr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg) + rcu_read_lock(); + c = ip6mr_cache_find(mrt, &sr.src.sin6_addr, &sr.grp.sin6_addr); + if (c) { +- sr.pktcnt = c->_c.mfc_un.res.pkt; +- sr.bytecnt = c->_c.mfc_un.res.bytes; +- sr.wrong_if = c->_c.mfc_un.res.wrong_if; ++ sr.pktcnt = atomic_long_read(&c->_c.mfc_un.res.pkt); ++ sr.bytecnt = atomic_long_read(&c->_c.mfc_un.res.bytes); ++ sr.wrong_if = atomic_long_read(&c->_c.mfc_un.res.wrong_if); + rcu_read_unlock(); + + if (copy_to_user(arg, &sr, sizeof(sr))) +@@ -2128,9 +2128,9 @@ static void ip6_mr_forward(struct net *net, struct mr_table *mrt, + int true_vifi = ip6mr_find_vif(mrt, dev); + + vif = c->_c.mfc_parent; +- c->_c.mfc_un.res.pkt++; +- c->_c.mfc_un.res.bytes += skb->len; +- c->_c.mfc_un.res.lastuse = jiffies; ++ atomic_long_inc(&c->_c.mfc_un.res.pkt); ++ atomic_long_add(skb->len, &c->_c.mfc_un.res.bytes); ++ WRITE_ONCE(c->_c.mfc_un.res.lastuse, jiffies); + + if (ipv6_addr_any(&c->mf6c_origin) && true_vifi >= 0) { + struct mfc6_cache *cache_proxy; +@@ -2148,7 +2148,7 @@ static void ip6_mr_forward(struct net *net, struct mr_table *mrt, + * Wrong interface: drop packet and (maybe) send PIM assert. + */ + if (rcu_access_pointer(mrt->vif_table[vif].dev) != dev) { +- c->_c.mfc_un.res.wrong_if++; ++ atomic_long_inc(&c->_c.mfc_un.res.wrong_if); + + if (true_vifi >= 0 && mrt->mroute_do_assert && + /* pimsm uses asserts, when switching from RPT to SPT, +diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c +index 23b46b5705c537..2ad0ef47b07c24 100644 +--- a/net/ipv6/ndisc.c ++++ b/net/ipv6/ndisc.c +@@ -1717,10 +1717,12 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target) + "Redirect: destination is not a neighbour\n"); + goto release; + } +- peer = inet_getpeer_v6(net->ipv6.peers, &ipv6_hdr(skb)->saddr, 1); ++ ++ rcu_read_lock(); ++ peer = inet_getpeer_v6(net->ipv6.peers, &ipv6_hdr(skb)->saddr); + ret = inet_peer_xrlim_allow(peer, 1*HZ); +- if (peer) +- inet_putpeer(peer); ++ rcu_read_unlock(); ++ + if (!ret) + goto release; + +diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c +index 63250286dc8b7a..d6938ffd764caf 100644 +--- a/net/mac80211/debugfs_netdev.c ++++ b/net/mac80211/debugfs_netdev.c +@@ -616,7 +616,7 @@ static ssize_t ieee80211_if_parse_active_links(struct ieee80211_sub_if_data *sda + { + u16 active_links; + +- if (kstrtou16(buf, 0, &active_links)) ++ if (kstrtou16(buf, 0, &active_links) || !active_links) + return -EINVAL; + + return ieee80211_set_active_links(&sdata->vif, active_links) ?: buflen; +diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h +index 2bc2fbe58f944b..78aa3bc51586e2 100644 +--- a/net/mac80211/driver-ops.h ++++ b/net/mac80211/driver-ops.h +@@ -665,6 +665,9 @@ static inline void drv_flush_sta(struct ieee80211_local *local, + if (sdata && !check_sdata_in_driver(sdata)) + return; + ++ if (!sta->uploaded) ++ return; ++ + trace_drv_flush_sta(local, sdata, &sta->sta); + if (local->ops->flush_sta) + local->ops->flush_sta(&local->hw, &sdata->vif, &sta->sta); +diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c +index 604863cebc198a..5eb233f619817b 100644 +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -2957,6 +2957,7 @@ ieee80211_rx_mesh_data(struct ieee80211_sub_if_data *sdata, struct sta_info *sta + } + + IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames); ++ ieee80211_set_qos_hdr(sdata, fwd_skb); + ieee80211_add_pending_skb(local, fwd_skb); + + rx_accept: +diff --git a/net/mptcp/options.c b/net/mptcp/options.c +index 8e6a6dc6e0a409..838c154b2b90f5 100644 +--- a/net/mptcp/options.c ++++ b/net/mptcp/options.c +@@ -108,7 +108,6 @@ static void mptcp_parse_option(const struct sk_buff *skb, + mp_opt->suboptions |= OPTION_MPTCP_DSS; + mp_opt->use_map = 1; + mp_opt->mpc_map = 1; +- mp_opt->use_ack = 0; + mp_opt->data_len = get_unaligned_be16(ptr); + ptr += 2; + } +@@ -157,11 +156,6 @@ static void mptcp_parse_option(const struct sk_buff *skb, + pr_debug("DSS\n"); + ptr++; + +- /* we must clear 'mpc_map' be able to detect MP_CAPABLE +- * map vs DSS map in mptcp_incoming_options(), and reconstruct +- * map info accordingly +- */ +- mp_opt->mpc_map = 0; + flags = (*ptr++) & MPTCP_DSS_FLAG_MASK; + mp_opt->data_fin = (flags & MPTCP_DSS_DATA_FIN) != 0; + mp_opt->dsn64 = (flags & MPTCP_DSS_DSN64) != 0; +@@ -369,8 +363,11 @@ void mptcp_get_options(const struct sk_buff *skb, + const unsigned char *ptr; + int length; + +- /* initialize option status */ +- mp_opt->suboptions = 0; ++ /* Ensure that casting the whole status to u32 is efficient and safe */ ++ BUILD_BUG_ON(sizeof_field(struct mptcp_options_received, status) != sizeof(u32)); ++ BUILD_BUG_ON(!IS_ALIGNED(offsetof(struct mptcp_options_received, status), ++ sizeof(u32))); ++ *(u32 *)&mp_opt->status = 0; + + length = (th->doff * 4) - sizeof(struct tcphdr); + ptr = (const unsigned char *)(th + 1); +diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c +index 07f3a9703312e5..5143214695dcd8 100644 +--- a/net/mptcp/protocol.c ++++ b/net/mptcp/protocol.c +@@ -1768,8 +1768,10 @@ static int mptcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg, + * see mptcp_disconnect(). + * Attempt it again outside the problematic scope. + */ +- if (!mptcp_disconnect(sk, 0)) ++ if (!mptcp_disconnect(sk, 0)) { ++ sk->sk_disconnects++; + sk->sk_socket->state = SS_UNCONNECTED; ++ } + } + inet_clear_bit(DEFER_CONNECT, sk); + +diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h +index 88c762de772875..0bb0386aa0897e 100644 +--- a/net/mptcp/protocol.h ++++ b/net/mptcp/protocol.h +@@ -149,22 +149,24 @@ struct mptcp_options_received { + u32 subflow_seq; + u16 data_len; + __sum16 csum; +- u16 suboptions; ++ struct_group(status, ++ u16 suboptions; ++ u16 use_map:1, ++ dsn64:1, ++ data_fin:1, ++ use_ack:1, ++ ack64:1, ++ mpc_map:1, ++ reset_reason:4, ++ reset_transient:1, ++ echo:1, ++ backup:1, ++ deny_join_id0:1, ++ __unused:2; ++ ); ++ u8 join_id; + u32 token; + u32 nonce; +- u16 use_map:1, +- dsn64:1, +- data_fin:1, +- use_ack:1, +- ack64:1, +- mpc_map:1, +- reset_reason:4, +- reset_transient:1, +- echo:1, +- backup:1, +- deny_join_id0:1, +- __unused:2; +- u8 join_id; + u64 thmac; + u8 hmac[MPTCPOPT_HMAC_LEN]; + struct mptcp_addr_info addr; +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index 1d1e998acd675e..bf24c63aff7b54 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -4552,6 +4552,14 @@ static int nf_tables_fill_set_concat(struct sk_buff *skb, + return 0; + } + ++static u32 nft_set_userspace_size(const struct nft_set_ops *ops, u32 size) ++{ ++ if (ops->usize) ++ return ops->usize(size); ++ ++ return size; ++} ++ + static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx, + const struct nft_set *set, u16 event, u16 flags) + { +@@ -4622,7 +4630,8 @@ static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx, + if (!nest) + goto nla_put_failure; + if (set->size && +- nla_put_be32(skb, NFTA_SET_DESC_SIZE, htonl(set->size))) ++ nla_put_be32(skb, NFTA_SET_DESC_SIZE, ++ htonl(nft_set_userspace_size(set->ops, set->size)))) + goto nla_put_failure; + + if (set->field_count > 1 && +@@ -4866,7 +4875,7 @@ static int nft_set_desc_concat_parse(const struct nlattr *attr, + static int nft_set_desc_concat(struct nft_set_desc *desc, + const struct nlattr *nla) + { +- u32 num_regs = 0, key_num_regs = 0; ++ u32 len = 0, num_regs; + struct nlattr *attr; + int rem, err, i; + +@@ -4880,12 +4889,12 @@ static int nft_set_desc_concat(struct nft_set_desc *desc, + } + + for (i = 0; i < desc->field_count; i++) +- num_regs += DIV_ROUND_UP(desc->field_len[i], sizeof(u32)); ++ len += round_up(desc->field_len[i], sizeof(u32)); + +- key_num_regs = DIV_ROUND_UP(desc->klen, sizeof(u32)); +- if (key_num_regs != num_regs) ++ if (len != desc->klen) + return -EINVAL; + ++ num_regs = DIV_ROUND_UP(desc->klen, sizeof(u32)); + if (num_regs > NFT_REG32_COUNT) + return -E2BIG; + +@@ -4992,6 +5001,15 @@ static bool nft_set_is_same(const struct nft_set *set, + return true; + } + ++static u32 nft_set_kernel_size(const struct nft_set_ops *ops, ++ const struct nft_set_desc *desc) ++{ ++ if (ops->ksize) ++ return ops->ksize(desc->size); ++ ++ return desc->size; ++} ++ + static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info, + const struct nlattr * const nla[]) + { +@@ -5174,6 +5192,9 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info, + if (err < 0) + return err; + ++ if (desc.size) ++ desc.size = nft_set_kernel_size(set->ops, &desc); ++ + err = 0; + if (!nft_set_is_same(set, &desc, exprs, num_exprs, flags)) { + NL_SET_BAD_ATTR(extack, nla[NFTA_SET_NAME]); +@@ -5196,6 +5217,9 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info, + if (IS_ERR(ops)) + return PTR_ERR(ops); + ++ if (desc.size) ++ desc.size = nft_set_kernel_size(ops, &desc); ++ + udlen = 0; + if (nla[NFTA_SET_USERDATA]) + udlen = nla_len(nla[NFTA_SET_USERDATA]); +@@ -6679,6 +6703,27 @@ static bool nft_setelem_valid_key_end(const struct nft_set *set, + return true; + } + ++static u32 nft_set_maxsize(const struct nft_set *set) ++{ ++ u32 maxsize, delta; ++ ++ if (!set->size) ++ return UINT_MAX; ++ ++ if (set->ops->adjust_maxsize) ++ delta = set->ops->adjust_maxsize(set); ++ else ++ delta = 0; ++ ++ if (check_add_overflow(set->size, set->ndeact, &maxsize)) ++ return UINT_MAX; ++ ++ if (check_add_overflow(maxsize, delta, &maxsize)) ++ return UINT_MAX; ++ ++ return maxsize; ++} ++ + static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, + const struct nlattr *attr, u32 nlmsg_flags) + { +@@ -7023,7 +7068,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, + } + + if (!(flags & NFT_SET_ELEM_CATCHALL)) { +- unsigned int max = set->size ? set->size + set->ndeact : UINT_MAX; ++ unsigned int max = nft_set_maxsize(set); + + if (!atomic_add_unless(&set->nelems, 1, max)) { + err = -ENFILE; +diff --git a/net/netfilter/nft_flow_offload.c b/net/netfilter/nft_flow_offload.c +index 397351fa4d5f82..5a3d6854204202 100644 +--- a/net/netfilter/nft_flow_offload.c ++++ b/net/netfilter/nft_flow_offload.c +@@ -288,6 +288,15 @@ static bool nft_flow_offload_skip(struct sk_buff *skb, int family) + return false; + } + ++static void flow_offload_ct_tcp(struct nf_conn *ct) ++{ ++ /* conntrack will not see all packets, disable tcp window validation. */ ++ spin_lock_bh(&ct->lock); ++ ct->proto.tcp.seen[0].flags |= IP_CT_TCP_FLAG_BE_LIBERAL; ++ ct->proto.tcp.seen[1].flags |= IP_CT_TCP_FLAG_BE_LIBERAL; ++ spin_unlock_bh(&ct->lock); ++} ++ + static void nft_flow_offload_eval(const struct nft_expr *expr, + struct nft_regs *regs, + const struct nft_pktinfo *pkt) +@@ -355,11 +364,8 @@ static void nft_flow_offload_eval(const struct nft_expr *expr, + goto err_flow_alloc; + + flow_offload_route_init(flow, &route); +- +- if (tcph) { +- ct->proto.tcp.seen[0].flags |= IP_CT_TCP_FLAG_BE_LIBERAL; +- ct->proto.tcp.seen[1].flags |= IP_CT_TCP_FLAG_BE_LIBERAL; +- } ++ if (tcph) ++ flow_offload_ct_tcp(ct); + + ret = flow_offload_add(flowtable, flow); + if (ret < 0) +diff --git a/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c +index 334958ef8d66c8..5dab9905ebbecc 100644 +--- a/net/netfilter/nft_set_pipapo.c ++++ b/net/netfilter/nft_set_pipapo.c +@@ -1574,12 +1574,11 @@ static void nft_pipapo_gc_deactivate(struct net *net, struct nft_set *set, + + /** + * pipapo_gc() - Drop expired entries from set, destroy start and end elements +- * @_set: nftables API set representation ++ * @set: nftables API set representation + * @m: Matching data + */ +-static void pipapo_gc(const struct nft_set *_set, struct nft_pipapo_match *m) ++static void pipapo_gc(struct nft_set *set, struct nft_pipapo_match *m) + { +- struct nft_set *set = (struct nft_set *) _set; + struct nft_pipapo *priv = nft_set_priv(set); + struct net *net = read_pnet(&set->net); + int rules_f0, first_rule = 0; +@@ -1693,7 +1692,7 @@ static void pipapo_reclaim_match(struct rcu_head *rcu) + * We also need to create a new working copy for subsequent insertions and + * deletions. + */ +-static void nft_pipapo_commit(const struct nft_set *set) ++static void nft_pipapo_commit(struct nft_set *set) + { + struct nft_pipapo *priv = nft_set_priv(set); + struct nft_pipapo_match *new_clone, *old; +diff --git a/net/netfilter/nft_set_rbtree.c b/net/netfilter/nft_set_rbtree.c +index afbda7e3fd0487..8ad1e008d12b5b 100644 +--- a/net/netfilter/nft_set_rbtree.c ++++ b/net/netfilter/nft_set_rbtree.c +@@ -19,7 +19,7 @@ struct nft_rbtree { + struct rb_root root; + rwlock_t lock; + seqcount_rwlock_t count; +- struct delayed_work gc_work; ++ unsigned long last_gc; + }; + + struct nft_rbtree_elem { +@@ -48,8 +48,7 @@ static int nft_rbtree_cmp(const struct nft_set *set, + + static bool nft_rbtree_elem_expired(const struct nft_rbtree_elem *rbe) + { +- return nft_set_elem_expired(&rbe->ext) || +- nft_set_elem_is_dead(&rbe->ext); ++ return nft_set_elem_expired(&rbe->ext); + } + + static bool __nft_rbtree_lookup(const struct net *net, const struct nft_set *set, +@@ -221,14 +220,15 @@ static void *nft_rbtree_get(const struct net *net, const struct nft_set *set, + return rbe; + } + +-static void nft_rbtree_gc_remove(struct net *net, struct nft_set *set, +- struct nft_rbtree *priv, +- struct nft_rbtree_elem *rbe) ++static void nft_rbtree_gc_elem_remove(struct net *net, struct nft_set *set, ++ struct nft_rbtree *priv, ++ struct nft_rbtree_elem *rbe) + { + struct nft_set_elem elem = { + .priv = rbe, + }; + ++ lockdep_assert_held_write(&priv->lock); + nft_setelem_data_deactivate(net, set, &elem); + rb_erase(&rbe->node, &priv->root); + } +@@ -263,7 +263,7 @@ nft_rbtree_gc_elem(const struct nft_set *__set, struct nft_rbtree *priv, + rbe_prev = NULL; + if (prev) { + rbe_prev = rb_entry(prev, struct nft_rbtree_elem, node); +- nft_rbtree_gc_remove(net, set, priv, rbe_prev); ++ nft_rbtree_gc_elem_remove(net, set, priv, rbe_prev); + + /* There is always room in this trans gc for this element, + * memory allocation never actually happens, hence, the warning +@@ -277,7 +277,7 @@ nft_rbtree_gc_elem(const struct nft_set *__set, struct nft_rbtree *priv, + nft_trans_gc_elem_add(gc, rbe_prev); + } + +- nft_rbtree_gc_remove(net, set, priv, rbe); ++ nft_rbtree_gc_elem_remove(net, set, priv, rbe); + gc = nft_trans_gc_queue_sync(gc, GFP_ATOMIC); + if (WARN_ON_ONCE(!gc)) + return ERR_PTR(-ENOMEM); +@@ -507,6 +507,15 @@ static int nft_rbtree_insert(const struct net *net, const struct nft_set *set, + return err; + } + ++static void nft_rbtree_erase(struct nft_rbtree *priv, struct nft_rbtree_elem *rbe) ++{ ++ write_lock_bh(&priv->lock); ++ write_seqcount_begin(&priv->count); ++ rb_erase(&rbe->node, &priv->root); ++ write_seqcount_end(&priv->count); ++ write_unlock_bh(&priv->lock); ++} ++ + static void nft_rbtree_remove(const struct net *net, + const struct nft_set *set, + const struct nft_set_elem *elem) +@@ -514,11 +523,7 @@ static void nft_rbtree_remove(const struct net *net, + struct nft_rbtree *priv = nft_set_priv(set); + struct nft_rbtree_elem *rbe = elem->priv; + +- write_lock_bh(&priv->lock); +- write_seqcount_begin(&priv->count); +- rb_erase(&rbe->node, &priv->root); +- write_seqcount_end(&priv->count); +- write_unlock_bh(&priv->lock); ++ nft_rbtree_erase(priv, rbe); + } + + static void nft_rbtree_activate(const struct net *net, +@@ -610,45 +615,40 @@ static void nft_rbtree_walk(const struct nft_ctx *ctx, + read_unlock_bh(&priv->lock); + } + +-static void nft_rbtree_gc(struct work_struct *work) ++static void nft_rbtree_gc_remove(struct net *net, struct nft_set *set, ++ struct nft_rbtree *priv, ++ struct nft_rbtree_elem *rbe) ++{ ++ struct nft_set_elem elem = { ++ .priv = rbe, ++ }; ++ ++ nft_setelem_data_deactivate(net, set, &elem); ++ nft_rbtree_erase(priv, rbe); ++} ++ ++static void nft_rbtree_gc(struct nft_set *set) + { ++ struct nft_rbtree *priv = nft_set_priv(set); + struct nft_rbtree_elem *rbe, *rbe_end = NULL; + struct nftables_pernet *nft_net; +- struct nft_rbtree *priv; ++ struct rb_node *node, *next; + struct nft_trans_gc *gc; +- struct rb_node *node; +- struct nft_set *set; +- unsigned int gc_seq; + struct net *net; + +- priv = container_of(work, struct nft_rbtree, gc_work.work); + set = nft_set_container_of(priv); + net = read_pnet(&set->net); + nft_net = nft_pernet(net); +- gc_seq = READ_ONCE(nft_net->gc_seq); + +- if (nft_set_gc_is_pending(set)) +- goto done; +- +- gc = nft_trans_gc_alloc(set, gc_seq, GFP_KERNEL); ++ gc = nft_trans_gc_alloc(set, 0, GFP_KERNEL); + if (!gc) +- goto done; ++ return; + +- read_lock_bh(&priv->lock); +- for (node = rb_first(&priv->root); node != NULL; node = rb_next(node)) { +- +- /* Ruleset has been updated, try later. */ +- if (READ_ONCE(nft_net->gc_seq) != gc_seq) { +- nft_trans_gc_destroy(gc); +- gc = NULL; +- goto try_later; +- } ++ for (node = rb_first(&priv->root); node ; node = next) { ++ next = rb_next(node); + + rbe = rb_entry(node, struct nft_rbtree_elem, node); + +- if (nft_set_elem_is_dead(&rbe->ext)) +- goto dead_elem; +- + /* elements are reversed in the rbtree for historical reasons, + * from highest to lowest value, that is why end element is + * always visited before the start element. +@@ -660,37 +660,34 @@ static void nft_rbtree_gc(struct work_struct *work) + if (!nft_set_elem_expired(&rbe->ext)) + continue; + +- nft_set_elem_dead(&rbe->ext); +- +- if (!rbe_end) +- continue; +- +- nft_set_elem_dead(&rbe_end->ext); +- +- gc = nft_trans_gc_queue_async(gc, gc_seq, GFP_ATOMIC); ++ gc = nft_trans_gc_queue_sync(gc, GFP_KERNEL); + if (!gc) + goto try_later; + +- nft_trans_gc_elem_add(gc, rbe_end); +- rbe_end = NULL; +-dead_elem: +- gc = nft_trans_gc_queue_async(gc, gc_seq, GFP_ATOMIC); ++ /* end element needs to be removed first, it has ++ * no timeout extension. ++ */ ++ if (rbe_end) { ++ nft_rbtree_gc_remove(net, set, priv, rbe_end); ++ nft_trans_gc_elem_add(gc, rbe_end); ++ rbe_end = NULL; ++ } ++ ++ gc = nft_trans_gc_queue_sync(gc, GFP_KERNEL); + if (!gc) + goto try_later; + ++ nft_rbtree_gc_remove(net, set, priv, rbe); + nft_trans_gc_elem_add(gc, rbe); + } + +- gc = nft_trans_gc_catchall_async(gc, gc_seq); +- + try_later: +- read_unlock_bh(&priv->lock); + +- if (gc) +- nft_trans_gc_queue_async_done(gc); +-done: +- queue_delayed_work(system_power_efficient_wq, &priv->gc_work, +- nft_set_gc_interval(set)); ++ if (gc) { ++ gc = nft_trans_gc_catchall_sync(gc); ++ nft_trans_gc_queue_sync_done(gc); ++ priv->last_gc = jiffies; ++ } + } + + static u64 nft_rbtree_privsize(const struct nlattr * const nla[], +@@ -709,11 +706,6 @@ static int nft_rbtree_init(const struct nft_set *set, + seqcount_rwlock_init(&priv->count, &priv->lock); + priv->root = RB_ROOT; + +- INIT_DEFERRABLE_WORK(&priv->gc_work, nft_rbtree_gc); +- if (set->flags & NFT_SET_TIMEOUT) +- queue_delayed_work(system_power_efficient_wq, &priv->gc_work, +- nft_set_gc_interval(set)); +- + return 0; + } + +@@ -724,8 +716,6 @@ static void nft_rbtree_destroy(const struct nft_ctx *ctx, + struct nft_rbtree_elem *rbe; + struct rb_node *node; + +- cancel_delayed_work_sync(&priv->gc_work); +- rcu_barrier(); + while ((node = priv->root.rb_node) != NULL) { + rb_erase(node, &priv->root); + rbe = rb_entry(node, struct nft_rbtree_elem, node); +@@ -751,6 +741,61 @@ static bool nft_rbtree_estimate(const struct nft_set_desc *desc, u32 features, + return true; + } + ++static void nft_rbtree_commit(struct nft_set *set) ++{ ++ struct nft_rbtree *priv = nft_set_priv(set); ++ ++ if (time_after_eq(jiffies, priv->last_gc + nft_set_gc_interval(set))) ++ nft_rbtree_gc(set); ++} ++ ++static void nft_rbtree_gc_init(const struct nft_set *set) ++{ ++ struct nft_rbtree *priv = nft_set_priv(set); ++ ++ priv->last_gc = jiffies; ++} ++ ++/* rbtree stores ranges as singleton elements, each range is composed of two ++ * elements ... ++ */ ++static u32 nft_rbtree_ksize(u32 size) ++{ ++ return size * 2; ++} ++ ++/* ... hide this detail to userspace. */ ++static u32 nft_rbtree_usize(u32 size) ++{ ++ if (!size) ++ return 0; ++ ++ return size / 2; ++} ++ ++static u32 nft_rbtree_adjust_maxsize(const struct nft_set *set) ++{ ++ struct nft_rbtree *priv = nft_set_priv(set); ++ struct nft_rbtree_elem *rbe; ++ struct rb_node *node; ++ const void *key; ++ ++ node = rb_last(&priv->root); ++ if (!node) ++ return 0; ++ ++ rbe = rb_entry(node, struct nft_rbtree_elem, node); ++ if (!nft_rbtree_interval_end(rbe)) ++ return 0; ++ ++ key = nft_set_ext_key(&rbe->ext); ++ if (memchr(key, 1, set->klen)) ++ return 0; ++ ++ /* this is the all-zero no-match element. */ ++ return 1; ++} ++ + const struct nft_set_type nft_set_rbtree_type = { + .features = NFT_SET_INTERVAL | NFT_SET_MAP | NFT_SET_OBJECT | NFT_SET_TIMEOUT, + .ops = { +@@ -764,8 +809,13 @@ const struct nft_set_type nft_set_rbtree_type = { + .deactivate = nft_rbtree_deactivate, + .flush = nft_rbtree_flush, + .activate = nft_rbtree_activate, ++ .commit = nft_rbtree_commit, ++ .gc_init = nft_rbtree_gc_init, + .lookup = nft_rbtree_lookup, + .walk = nft_rbtree_walk, + .get = nft_rbtree_get, ++ .ksize = nft_rbtree_ksize, ++ .usize = nft_rbtree_usize, ++ .adjust_maxsize = nft_rbtree_adjust_maxsize, + }, + }; +diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c +index 42e8b9e37516b2..342823b918e7cc 100644 +--- a/net/rose/af_rose.c ++++ b/net/rose/af_rose.c +@@ -397,15 +397,15 @@ static int rose_setsockopt(struct socket *sock, int level, int optname, + { + struct sock *sk = sock->sk; + struct rose_sock *rose = rose_sk(sk); +- int opt; ++ unsigned int opt; + + if (level != SOL_ROSE) + return -ENOPROTOOPT; + +- if (optlen < sizeof(int)) ++ if (optlen < sizeof(unsigned int)) + return -EINVAL; + +- if (copy_from_sockptr(&opt, optval, sizeof(int))) ++ if (copy_from_sockptr(&opt, optval, sizeof(unsigned int))) + return -EFAULT; + + switch (optname) { +@@ -414,31 +414,31 @@ static int rose_setsockopt(struct socket *sock, int level, int optname, + return 0; + + case ROSE_T1: +- if (opt < 1) ++ if (opt < 1 || opt > UINT_MAX / HZ) + return -EINVAL; + rose->t1 = opt * HZ; + return 0; + + case ROSE_T2: +- if (opt < 1) ++ if (opt < 1 || opt > UINT_MAX / HZ) + return -EINVAL; + rose->t2 = opt * HZ; + return 0; + + case ROSE_T3: +- if (opt < 1) ++ if (opt < 1 || opt > UINT_MAX / HZ) + return -EINVAL; + rose->t3 = opt * HZ; + return 0; + + case ROSE_HOLDBACK: +- if (opt < 1) ++ if (opt < 1 || opt > UINT_MAX / HZ) + return -EINVAL; + rose->hb = opt * HZ; + return 0; + + case ROSE_IDLE: +- if (opt < 0) ++ if (opt > UINT_MAX / (60 * HZ)) + return -EINVAL; + rose->idle = opt * 60 * HZ; + return 0; +diff --git a/net/rose/rose_timer.c b/net/rose/rose_timer.c +index f06ddbed3fed63..1525773e94aa17 100644 +--- a/net/rose/rose_timer.c ++++ b/net/rose/rose_timer.c +@@ -122,6 +122,10 @@ static void rose_heartbeat_expiry(struct timer_list *t) + struct rose_sock *rose = rose_sk(sk); + + bh_lock_sock(sk); ++ if (sock_owned_by_user(sk)) { ++ sk_reset_timer(sk, &sk->sk_timer, jiffies + HZ/20); ++ goto out; ++ } + switch (rose->state) { + case ROSE_STATE_0: + /* Magic here: If we listen() and a new link dies before it +@@ -152,6 +156,7 @@ static void rose_heartbeat_expiry(struct timer_list *t) + } + + rose_start_heartbeat(sk); ++out: + bh_unlock_sock(sk); + sock_put(sk); + } +@@ -162,6 +167,10 @@ static void rose_timer_expiry(struct timer_list *t) + struct sock *sk = &rose->sock; + + bh_lock_sock(sk); ++ if (sock_owned_by_user(sk)) { ++ sk_reset_timer(sk, &rose->timer, jiffies + HZ/20); ++ goto out; ++ } + switch (rose->state) { + case ROSE_STATE_1: /* T1 */ + case ROSE_STATE_4: /* T2 */ +@@ -182,6 +191,7 @@ static void rose_timer_expiry(struct timer_list *t) + } + break; + } ++out: + bh_unlock_sock(sk); + sock_put(sk); + } +@@ -192,6 +202,10 @@ static void rose_idletimer_expiry(struct timer_list *t) + struct sock *sk = &rose->sock; + + bh_lock_sock(sk); ++ if (sock_owned_by_user(sk)) { ++ sk_reset_timer(sk, &rose->idletimer, jiffies + HZ/20); ++ goto out; ++ } + rose_clear_queues(sk); + + rose_write_internal(sk, ROSE_CLEAR_REQUEST); +@@ -207,6 +221,7 @@ static void rose_idletimer_expiry(struct timer_list *t) + sk->sk_state_change(sk); + sock_set_flag(sk, SOCK_DEAD); + } ++out: + bh_unlock_sock(sk); + sock_put(sk); + } +diff --git a/net/rxrpc/conn_event.c b/net/rxrpc/conn_event.c +index 598b4ee389fc1e..2a1396cd892f30 100644 +--- a/net/rxrpc/conn_event.c ++++ b/net/rxrpc/conn_event.c +@@ -63,11 +63,12 @@ int rxrpc_abort_conn(struct rxrpc_connection *conn, struct sk_buff *skb, + /* + * Mark a connection as being remotely aborted. + */ +-static bool rxrpc_input_conn_abort(struct rxrpc_connection *conn, ++static void rxrpc_input_conn_abort(struct rxrpc_connection *conn, + struct sk_buff *skb) + { +- return rxrpc_set_conn_aborted(conn, skb, skb->priority, -ECONNABORTED, +- RXRPC_CALL_REMOTELY_ABORTED); ++ trace_rxrpc_rx_conn_abort(conn, skb); ++ rxrpc_set_conn_aborted(conn, skb, skb->priority, -ECONNABORTED, ++ RXRPC_CALL_REMOTELY_ABORTED); + } + + /* +@@ -202,11 +203,14 @@ static void rxrpc_abort_calls(struct rxrpc_connection *conn) + + for (i = 0; i < RXRPC_MAXCALLS; i++) { + call = conn->channels[i].call; +- if (call) ++ if (call) { ++ rxrpc_see_call(call, rxrpc_call_see_conn_abort); + rxrpc_set_call_completion(call, + conn->completion, + conn->abort_code, + conn->error); ++ rxrpc_poke_call(call, rxrpc_call_poke_conn_abort); ++ } + } + + _leave(""); +diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c +index 00f95e7d1b9116..7cddaa6321c7c9 100644 +--- a/net/sched/sch_api.c ++++ b/net/sched/sch_api.c +@@ -1635,6 +1635,10 @@ static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n, + q = qdisc_lookup(dev, tcm->tcm_handle); + if (!q) + goto create_n_graft; ++ if (q->parent != tcm->tcm_parent) { ++ NL_SET_ERR_MSG(extack, "Cannot move an existing qdisc to a different parent"); ++ return -EINVAL; ++ } + if (n->nlmsg_flags & NLM_F_EXCL) { + NL_SET_ERR_MSG(extack, "Exclusivity flag on, cannot override"); + return -EEXIST; +diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c +index 66dcb18638fea4..60754f366ab7bc 100644 +--- a/net/sched/sch_sfq.c ++++ b/net/sched/sch_sfq.c +@@ -77,12 +77,6 @@ + #define SFQ_EMPTY_SLOT 0xffff + #define SFQ_DEFAULT_HASH_DIVISOR 1024 + +-/* We use 16 bits to store allot, and want to handle packets up to 64K +- * Scale allot by 8 (1<<3) so that no overflow occurs. +- */ +-#define SFQ_ALLOT_SHIFT 3 +-#define SFQ_ALLOT_SIZE(X) DIV_ROUND_UP(X, 1 << SFQ_ALLOT_SHIFT) +- + /* This type should contain at least SFQ_MAX_DEPTH + 1 + SFQ_MAX_FLOWS values */ + typedef u16 sfq_index; + +@@ -104,7 +98,7 @@ struct sfq_slot { + sfq_index next; /* next slot in sfq RR chain */ + struct sfq_head dep; /* anchor in dep[] chains */ + unsigned short hash; /* hash value (index in ht[]) */ +- short allot; /* credit for this slot */ ++ int allot; /* credit for this slot */ + + unsigned int backlog; + struct red_vars vars; +@@ -120,7 +114,6 @@ struct sfq_sched_data { + siphash_key_t perturbation; + u8 cur_depth; /* depth of longest slot */ + u8 flags; +- unsigned short scaled_quantum; /* SFQ_ALLOT_SIZE(quantum) */ + struct tcf_proto __rcu *filter_list; + struct tcf_block *block; + sfq_index *ht; /* Hash table ('divisor' slots) */ +@@ -456,7 +449,7 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch, struct sk_buff **to_free) + */ + q->tail = slot; + /* We could use a bigger initial quantum for new flows */ +- slot->allot = q->scaled_quantum; ++ slot->allot = q->quantum; + } + if (++sch->q.qlen <= q->limit) + return NET_XMIT_SUCCESS; +@@ -493,7 +486,7 @@ sfq_dequeue(struct Qdisc *sch) + slot = &q->slots[a]; + if (slot->allot <= 0) { + q->tail = slot; +- slot->allot += q->scaled_quantum; ++ slot->allot += q->quantum; + goto next_slot; + } + skb = slot_dequeue_head(slot); +@@ -512,7 +505,7 @@ sfq_dequeue(struct Qdisc *sch) + } + q->tail->next = next_a; + } else { +- slot->allot -= SFQ_ALLOT_SIZE(qdisc_pkt_len(skb)); ++ slot->allot -= qdisc_pkt_len(skb); + } + return skb; + } +@@ -595,7 +588,7 @@ static void sfq_rehash(struct Qdisc *sch) + q->tail->next = x; + } + q->tail = slot; +- slot->allot = q->scaled_quantum; ++ slot->allot = q->quantum; + } + } + sch->q.qlen -= dropped; +@@ -608,6 +601,7 @@ static void sfq_perturbation(struct timer_list *t) + struct Qdisc *sch = q->sch; + spinlock_t *root_lock; + siphash_key_t nkey; ++ int period; + + get_random_bytes(&nkey, sizeof(nkey)); + rcu_read_lock(); +@@ -618,12 +612,17 @@ static void sfq_perturbation(struct timer_list *t) + sfq_rehash(sch); + spin_unlock(root_lock); + +- if (q->perturb_period) +- mod_timer(&q->perturb_timer, jiffies + q->perturb_period); ++ /* q->perturb_period can change under us from ++ * sfq_change() and sfq_destroy(). ++ */ ++ period = READ_ONCE(q->perturb_period); ++ if (period) ++ mod_timer(&q->perturb_timer, jiffies + period); + rcu_read_unlock(); + } + +-static int sfq_change(struct Qdisc *sch, struct nlattr *opt) ++static int sfq_change(struct Qdisc *sch, struct nlattr *opt, ++ struct netlink_ext_ack *extack) + { + struct sfq_sched_data *q = qdisc_priv(sch); + struct tc_sfq_qopt *ctl = nla_data(opt); +@@ -641,14 +640,10 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt) + (!is_power_of_2(ctl->divisor) || ctl->divisor > 65536)) + return -EINVAL; + +- /* slot->allot is a short, make sure quantum is not too big. */ +- if (ctl->quantum) { +- unsigned int scaled = SFQ_ALLOT_SIZE(ctl->quantum); +- +- if (scaled <= 0 || scaled > SHRT_MAX) +- return -EINVAL; ++ if ((int)ctl->quantum < 0) { ++ NL_SET_ERR_MSG_MOD(extack, "invalid quantum"); ++ return -EINVAL; + } +- + if (ctl_v1 && !red_check_params(ctl_v1->qth_min, ctl_v1->qth_max, + ctl_v1->Wlog, ctl_v1->Scell_log, NULL)) + return -EINVAL; +@@ -657,12 +652,14 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt) + if (!p) + return -ENOMEM; + } ++ if (ctl->limit == 1) { ++ NL_SET_ERR_MSG_MOD(extack, "invalid limit"); ++ return -EINVAL; ++ } + sch_tree_lock(sch); +- if (ctl->quantum) { ++ if (ctl->quantum) + q->quantum = ctl->quantum; +- q->scaled_quantum = SFQ_ALLOT_SIZE(q->quantum); +- } +- q->perturb_period = ctl->perturb_period * HZ; ++ WRITE_ONCE(q->perturb_period, ctl->perturb_period * HZ); + if (ctl->flows) + q->maxflows = min_t(u32, ctl->flows, SFQ_MAX_FLOWS); + if (ctl->divisor) { +@@ -724,7 +721,7 @@ static void sfq_destroy(struct Qdisc *sch) + struct sfq_sched_data *q = qdisc_priv(sch); + + tcf_block_put(q->block); +- q->perturb_period = 0; ++ WRITE_ONCE(q->perturb_period, 0); + del_timer_sync(&q->perturb_timer); + sfq_free(q->ht); + sfq_free(q->slots); +@@ -757,12 +754,11 @@ static int sfq_init(struct Qdisc *sch, struct nlattr *opt, + q->divisor = SFQ_DEFAULT_HASH_DIVISOR; + q->maxflows = SFQ_DEFAULT_FLOWS; + q->quantum = psched_mtu(qdisc_dev(sch)); +- q->scaled_quantum = SFQ_ALLOT_SIZE(q->quantum); + q->perturb_period = 0; + get_random_bytes(&q->perturbation, sizeof(q->perturbation)); + + if (opt) { +- int err = sfq_change(sch, opt); ++ int err = sfq_change(sch, opt, extack); + if (err) + return err; + } +@@ -873,7 +869,7 @@ static int sfq_dump_class_stats(struct Qdisc *sch, unsigned long cl, + if (idx != SFQ_EMPTY_SLOT) { + const struct sfq_slot *slot = &q->slots[idx]; + +- xstats.allot = slot->allot << SFQ_ALLOT_SHIFT; ++ xstats.allot = slot->allot; + qs.qlen = slot->qlen; + qs.backlog = slot->backlog; + } +diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c +index 0acf07538840cc..45efbbfff94ae2 100644 +--- a/net/smc/af_smc.c ++++ b/net/smc/af_smc.c +@@ -2745,7 +2745,7 @@ static int smc_accept(struct socket *sock, struct socket *new_sock, + release_sock(clcsk); + } else if (!atomic_read(&smc_sk(nsk)->conn.bytes_to_rcv)) { + lock_sock(nsk); +- smc_rx_wait(smc_sk(nsk), &timeo, smc_rx_data_available); ++ smc_rx_wait(smc_sk(nsk), &timeo, 0, smc_rx_data_available); + release_sock(nsk); + } + } +diff --git a/net/smc/smc_rx.c b/net/smc/smc_rx.c +index 9a2f3638d161d2..acb14e28cad411 100644 +--- a/net/smc/smc_rx.c ++++ b/net/smc/smc_rx.c +@@ -238,22 +238,23 @@ static int smc_rx_splice(struct pipe_inode_info *pipe, char *src, size_t len, + return -ENOMEM; + } + +-static int smc_rx_data_available_and_no_splice_pend(struct smc_connection *conn) ++static int smc_rx_data_available_and_no_splice_pend(struct smc_connection *conn, size_t peeked) + { +- return atomic_read(&conn->bytes_to_rcv) && ++ return smc_rx_data_available(conn, peeked) && + !atomic_read(&conn->splice_pending); + } + + /* blocks rcvbuf consumer until >=len bytes available or timeout or interrupted + * @smc smc socket + * @timeo pointer to max seconds to wait, pointer to value 0 for no timeout ++ * @peeked number of bytes already peeked + * @fcrit add'l criterion to evaluate as function pointer + * Returns: + * 1 if at least 1 byte available in rcvbuf or if socket error/shutdown. + * 0 otherwise (nothing in rcvbuf nor timeout, e.g. interrupted). + */ +-int smc_rx_wait(struct smc_sock *smc, long *timeo, +- int (*fcrit)(struct smc_connection *conn)) ++int smc_rx_wait(struct smc_sock *smc, long *timeo, size_t peeked, ++ int (*fcrit)(struct smc_connection *conn, size_t baseline)) + { + DEFINE_WAIT_FUNC(wait, woken_wake_function); + struct smc_connection *conn = &smc->conn; +@@ -262,7 +263,7 @@ int smc_rx_wait(struct smc_sock *smc, long *timeo, + struct sock *sk = &smc->sk; + int rc; + +- if (fcrit(conn)) ++ if (fcrit(conn, peeked)) + return 1; + sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk); + add_wait_queue(sk_sleep(sk), &wait); +@@ -271,7 +272,7 @@ int smc_rx_wait(struct smc_sock *smc, long *timeo, + cflags->peer_conn_abort || + READ_ONCE(sk->sk_shutdown) & RCV_SHUTDOWN || + conn->killed || +- fcrit(conn), ++ fcrit(conn, peeked), + &wait); + remove_wait_queue(sk_sleep(sk), &wait); + sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk); +@@ -322,11 +323,11 @@ static int smc_rx_recv_urg(struct smc_sock *smc, struct msghdr *msg, int len, + return -EAGAIN; + } + +-static bool smc_rx_recvmsg_data_available(struct smc_sock *smc) ++static bool smc_rx_recvmsg_data_available(struct smc_sock *smc, size_t peeked) + { + struct smc_connection *conn = &smc->conn; + +- if (smc_rx_data_available(conn)) ++ if (smc_rx_data_available(conn, peeked)) + return true; + else if (conn->urg_state == SMC_URG_VALID) + /* we received a single urgent Byte - skip */ +@@ -344,10 +345,10 @@ static bool smc_rx_recvmsg_data_available(struct smc_sock *smc) + int smc_rx_recvmsg(struct smc_sock *smc, struct msghdr *msg, + struct pipe_inode_info *pipe, size_t len, int flags) + { +- size_t copylen, read_done = 0, read_remaining = len; ++ size_t copylen, read_done = 0, read_remaining = len, peeked_bytes = 0; + size_t chunk_len, chunk_off, chunk_len_sum; + struct smc_connection *conn = &smc->conn; +- int (*func)(struct smc_connection *conn); ++ int (*func)(struct smc_connection *conn, size_t baseline); + union smc_host_cursor cons; + int readable, chunk; + char *rcvbuf_base; +@@ -384,14 +385,14 @@ int smc_rx_recvmsg(struct smc_sock *smc, struct msghdr *msg, + if (conn->killed) + break; + +- if (smc_rx_recvmsg_data_available(smc)) ++ if (smc_rx_recvmsg_data_available(smc, peeked_bytes)) + goto copy; + + if (sk->sk_shutdown & RCV_SHUTDOWN) { + /* smc_cdc_msg_recv_action() could have run after + * above smc_rx_recvmsg_data_available() + */ +- if (smc_rx_recvmsg_data_available(smc)) ++ if (smc_rx_recvmsg_data_available(smc, peeked_bytes)) + goto copy; + break; + } +@@ -425,26 +426,28 @@ int smc_rx_recvmsg(struct smc_sock *smc, struct msghdr *msg, + } + } + +- if (!smc_rx_data_available(conn)) { +- smc_rx_wait(smc, &timeo, smc_rx_data_available); ++ if (!smc_rx_data_available(conn, peeked_bytes)) { ++ smc_rx_wait(smc, &timeo, peeked_bytes, smc_rx_data_available); + continue; + } + + copy: + /* initialize variables for 1st iteration of subsequent loop */ + /* could be just 1 byte, even after waiting on data above */ +- readable = atomic_read(&conn->bytes_to_rcv); ++ readable = smc_rx_data_available(conn, peeked_bytes); + splbytes = atomic_read(&conn->splice_pending); + if (!readable || (msg && splbytes)) { + if (splbytes) + func = smc_rx_data_available_and_no_splice_pend; + else + func = smc_rx_data_available; +- smc_rx_wait(smc, &timeo, func); ++ smc_rx_wait(smc, &timeo, peeked_bytes, func); + continue; + } + + smc_curs_copy(&cons, &conn->local_tx_ctrl.cons, conn); ++ if ((flags & MSG_PEEK) && peeked_bytes) ++ smc_curs_add(conn->rmb_desc->len, &cons, peeked_bytes); + /* subsequent splice() calls pick up where previous left */ + if (splbytes) + smc_curs_add(conn->rmb_desc->len, &cons, splbytes); +@@ -480,6 +483,8 @@ int smc_rx_recvmsg(struct smc_sock *smc, struct msghdr *msg, + } + read_remaining -= chunk_len; + read_done += chunk_len; ++ if (flags & MSG_PEEK) ++ peeked_bytes += chunk_len; + + if (chunk_len_sum == copylen) + break; /* either on 1st or 2nd iteration */ +diff --git a/net/smc/smc_rx.h b/net/smc/smc_rx.h +index db823c97d824ea..994f5e42d1ba26 100644 +--- a/net/smc/smc_rx.h ++++ b/net/smc/smc_rx.h +@@ -21,11 +21,11 @@ void smc_rx_init(struct smc_sock *smc); + + int smc_rx_recvmsg(struct smc_sock *smc, struct msghdr *msg, + struct pipe_inode_info *pipe, size_t len, int flags); +-int smc_rx_wait(struct smc_sock *smc, long *timeo, +- int (*fcrit)(struct smc_connection *conn)); +-static inline int smc_rx_data_available(struct smc_connection *conn) ++int smc_rx_wait(struct smc_sock *smc, long *timeo, size_t peeked, ++ int (*fcrit)(struct smc_connection *conn, size_t baseline)); ++static inline int smc_rx_data_available(struct smc_connection *conn, size_t peeked) + { +- return atomic_read(&conn->bytes_to_rcv); ++ return atomic_read(&conn->bytes_to_rcv) - peeked; + } + + #endif /* SMC_RX_H */ +diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c +index 83996eea100626..8d760f8fc4b5a6 100644 +--- a/net/sunrpc/svcsock.c ++++ b/net/sunrpc/svcsock.c +@@ -1093,9 +1093,6 @@ static void svc_tcp_fragment_received(struct svc_sock *svsk) + /* If we have more data, signal svc_xprt_enqueue() to try again */ + svsk->sk_tcplen = 0; + svsk->sk_marker = xdr_zero; +- +- smp_wmb(); +- tcp_set_rcvlowat(svsk->sk_sk, 1); + } + + /** +@@ -1185,17 +1182,10 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp) + goto err_delete; + if (len == want) + svc_tcp_fragment_received(svsk); +- else { +- /* Avoid more ->sk_data_ready() calls until the rest +- * of the message has arrived. This reduces service +- * thread wake-ups on large incoming messages. */ +- tcp_set_rcvlowat(svsk->sk_sk, +- svc_sock_reclen(svsk) - svsk->sk_tcplen); +- ++ else + trace_svcsock_tcp_recv_short(&svsk->sk_xprt, + svc_sock_reclen(svsk), + svsk->sk_tcplen - sizeof(rpc_fraghdr)); +- } + goto err_noclose; + error: + if (len != -EAGAIN) +diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c +index 2050d888df2ae1..f4dbf5f87962d9 100644 +--- a/net/vmw_vsock/af_vsock.c ++++ b/net/vmw_vsock/af_vsock.c +@@ -1453,6 +1453,11 @@ static int vsock_connect(struct socket *sock, struct sockaddr *addr, + if (err < 0) + goto out; + ++ /* sk_err might have been set as a result of an earlier ++ * (failed) connect attempt. ++ */ ++ sk->sk_err = 0; ++ + /* Mark sock as connecting and set the error code to in + * progress in case this is a non-blocking connect. + */ +diff --git a/net/wireless/scan.c b/net/wireless/scan.c +index 4fc6279750ea15..ce622a287abc6b 100644 +--- a/net/wireless/scan.c ++++ b/net/wireless/scan.c +@@ -831,10 +831,45 @@ static int cfg80211_scan_6ghz(struct cfg80211_registered_device *rdev) + list_for_each_entry(intbss, &rdev->bss_list, list) { + struct cfg80211_bss *res = &intbss->pub; + const struct cfg80211_bss_ies *ies; ++ const struct element *ssid_elem; ++ struct cfg80211_colocated_ap *entry; ++ u32 s_ssid_tmp; ++ int ret; + + ies = rcu_access_pointer(res->ies); + count += cfg80211_parse_colocated_ap(ies, + &coloc_ap_list); ++ ++ /* In case the scan request specified a specific BSSID ++ * and the BSS is found and operating on 6GHz band then ++ * add this AP to the collocated APs list. ++ * This is relevant for ML probe requests when the lower ++ * band APs have not been discovered. ++ */ ++ if (is_broadcast_ether_addr(rdev_req->bssid) || ++ !ether_addr_equal(rdev_req->bssid, res->bssid) || ++ res->channel->band != NL80211_BAND_6GHZ) ++ continue; ++ ++ ret = cfg80211_calc_short_ssid(ies, &ssid_elem, ++ &s_ssid_tmp); ++ if (ret) ++ continue; ++ ++ entry = kzalloc(sizeof(*entry), GFP_ATOMIC); ++ if (!entry) ++ continue; ++ ++ memcpy(entry->bssid, res->bssid, ETH_ALEN); ++ entry->short_ssid = s_ssid_tmp; ++ memcpy(entry->ssid, ssid_elem->data, ++ ssid_elem->datalen); ++ entry->ssid_len = ssid_elem->datalen; ++ entry->short_ssid_valid = true; ++ entry->center_freq = res->channel->center_freq; ++ ++ list_add_tail(&entry->list, &coloc_ap_list); ++ count++; + } + spin_unlock_bh(&rdev->bss_lock); + } +diff --git a/net/xfrm/xfrm_replay.c b/net/xfrm/xfrm_replay.c +index ce56d659c55a69..7f52bb2e14c13a 100644 +--- a/net/xfrm/xfrm_replay.c ++++ b/net/xfrm/xfrm_replay.c +@@ -714,10 +714,12 @@ static int xfrm_replay_overflow_offload_esn(struct xfrm_state *x, struct sk_buff + oseq += skb_shinfo(skb)->gso_segs; + } + +- if (unlikely(xo->seq.low < replay_esn->oseq)) { +- XFRM_SKB_CB(skb)->seq.output.hi = ++oseq_hi; +- xo->seq.hi = oseq_hi; +- replay_esn->oseq_hi = oseq_hi; ++ if (unlikely(oseq < replay_esn->oseq)) { ++ replay_esn->oseq_hi = ++oseq_hi; ++ if (xo->seq.low < replay_esn->oseq) { ++ XFRM_SKB_CB(skb)->seq.output.hi = oseq_hi; ++ xo->seq.hi = oseq_hi; ++ } + if (replay_esn->oseq_hi == 0) { + replay_esn->oseq--; + replay_esn->oseq_hi--; +diff --git a/samples/landlock/sandboxer.c b/samples/landlock/sandboxer.c +index e2056c8b902c55..be4fec95c46010 100644 +--- a/samples/landlock/sandboxer.c ++++ b/samples/landlock/sandboxer.c +@@ -65,6 +65,9 @@ static int parse_path(char *env_path, const char ***const path_list) + } + } + *path_list = malloc(num_paths * sizeof(**path_list)); ++ if (!*path_list) ++ return -1; ++ + for (i = 0; i < num_paths; i++) + (*path_list)[i] = strsep(&env_path, ENV_PATH_TOKEN); + +@@ -100,6 +103,10 @@ static int populate_ruleset(const char *const env_var, const int ruleset_fd, + env_path_name = strdup(env_path_name); + unsetenv(env_var); + num_paths = parse_path(env_path_name, &path_list); ++ if (num_paths < 0) { ++ fprintf(stderr, "Failed to allocate memory\n"); ++ goto out_free_name; ++ } + if (num_paths == 1 && path_list[0][0] == '\0') { + /* + * Allows to not use all possible restrictions (e.g. use +diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib +index e702552fb131af..44f20b1b853a50 100644 +--- a/scripts/Makefile.lib ++++ b/scripts/Makefile.lib +@@ -472,10 +472,10 @@ quiet_cmd_lzo_with_size = LZO $@ + cmd_lzo_with_size = { cat $(real-prereqs) | $(KLZOP) -9; $(size_append); } > $@ + + quiet_cmd_lz4 = LZ4 $@ +- cmd_lz4 = cat $(real-prereqs) | $(LZ4) -l -c1 stdin stdout > $@ ++ cmd_lz4 = cat $(real-prereqs) | $(LZ4) -l -9 - - > $@ + + quiet_cmd_lz4_with_size = LZ4 $@ +- cmd_lz4_with_size = { cat $(real-prereqs) | $(LZ4) -l -c1 stdin stdout; \ ++ cmd_lz4_with_size = { cat $(real-prereqs) | $(LZ4) -l -9 - -; \ + $(size_append); } > $@ + + # U-Boot mkimage +diff --git a/scripts/genksyms/genksyms.c b/scripts/genksyms/genksyms.c +index f5dfdb9d80e9d5..6b0eb3898e4ec7 100644 +--- a/scripts/genksyms/genksyms.c ++++ b/scripts/genksyms/genksyms.c +@@ -241,6 +241,7 @@ static struct symbol *__add_symbol(const char *name, enum symbol_type type, + "unchanged\n"); + } + sym->is_declared = 1; ++ free_list(defn, NULL); + return sym; + } else if (!sym->is_declared) { + if (sym->is_override && flag_preserve) { +@@ -249,6 +250,7 @@ static struct symbol *__add_symbol(const char *name, enum symbol_type type, + print_type_name(type, name); + fprintf(stderr, " modversion change\n"); + sym->is_declared = 1; ++ free_list(defn, NULL); + return sym; + } else { + status = is_unknown_symbol(sym) ? +@@ -256,6 +258,7 @@ static struct symbol *__add_symbol(const char *name, enum symbol_type type, + } + } else { + error_with_pos("redefinition of %s", name); ++ free_list(defn, NULL); + return sym; + } + break; +@@ -271,11 +274,15 @@ static struct symbol *__add_symbol(const char *name, enum symbol_type type, + break; + } + } ++ ++ free_list(sym->defn, NULL); ++ free(sym->name); ++ free(sym); + --nsyms; + } + + sym = xmalloc(sizeof(*sym)); +- sym->name = name; ++ sym->name = xstrdup(name); + sym->type = type; + sym->defn = defn; + sym->expansion_trail = NULL; +@@ -482,7 +489,7 @@ static void read_reference(FILE *f) + defn = def; + def = read_node(f); + } +- subsym = add_reference_symbol(xstrdup(sym->string), sym->tag, ++ subsym = add_reference_symbol(sym->string, sym->tag, + defn, is_extern); + subsym->is_override = is_override; + free_node(sym); +diff --git a/scripts/genksyms/genksyms.h b/scripts/genksyms/genksyms.h +index 21ed2ec2d98ca8..5621533dcb8e43 100644 +--- a/scripts/genksyms/genksyms.h ++++ b/scripts/genksyms/genksyms.h +@@ -32,7 +32,7 @@ struct string_list { + + struct symbol { + struct symbol *hash_next; +- const char *name; ++ char *name; + enum symbol_type type; + struct string_list *defn; + struct symbol *expansion_trail; +diff --git a/scripts/genksyms/parse.y b/scripts/genksyms/parse.y +index 8e9b5e69e8f01d..689cb6bb40b657 100644 +--- a/scripts/genksyms/parse.y ++++ b/scripts/genksyms/parse.y +@@ -152,14 +152,19 @@ simple_declaration: + ; + + init_declarator_list_opt: +- /* empty */ { $$ = NULL; } +- | init_declarator_list ++ /* empty */ { $$ = NULL; } ++ | init_declarator_list { free_list(decl_spec, NULL); $$ = $1; } + ; + + init_declarator_list: + init_declarator + { struct string_list *decl = *$1; + *$1 = NULL; ++ ++ /* avoid sharing among multiple init_declarators */ ++ if (decl_spec) ++ decl_spec = copy_list_range(decl_spec, NULL); ++ + add_symbol(current_name, + is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern); + current_name = NULL; +@@ -170,6 +175,11 @@ init_declarator_list: + *$3 = NULL; + free_list(*$2, NULL); + *$2 = decl_spec; ++ ++ /* avoid sharing among multiple init_declarators */ ++ if (decl_spec) ++ decl_spec = copy_list_range(decl_spec, NULL); ++ + add_symbol(current_name, + is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern); + current_name = NULL; +@@ -472,12 +482,12 @@ enumerator_list: + enumerator: + IDENT + { +- const char *name = strdup((*$1)->string); ++ const char *name = (*$1)->string; + add_symbol(name, SYM_ENUM_CONST, NULL, 0); + } + | IDENT '=' EXPRESSION_PHRASE + { +- const char *name = strdup((*$1)->string); ++ const char *name = (*$1)->string; + struct string_list *expr = copy_list_range(*$3, *$2); + add_symbol(name, SYM_ENUM_CONST, expr, 0); + } +diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c +index 33d19e419908b8..662a5e7c37c285 100644 +--- a/scripts/kconfig/conf.c ++++ b/scripts/kconfig/conf.c +@@ -827,6 +827,9 @@ int main(int ac, char **av) + break; + } + ++ if (conf_errors()) ++ exit(1); ++ + if (sync_kconfig) { + name = getenv("KCONFIG_NOSILENTUPDATE"); + if (name && *name) { +@@ -890,6 +893,9 @@ int main(int ac, char **av) + break; + } + ++ if (sym_dep_errors()) ++ exit(1); ++ + if (input_mode == savedefconfig) { + if (conf_write_defconfig(defconfig_file)) { + fprintf(stderr, "n*** Error while saving defconfig to: %s\n\n", +diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c +index 4a6811d77d1829..f214e8d3762e0a 100644 +--- a/scripts/kconfig/confdata.c ++++ b/scripts/kconfig/confdata.c +@@ -155,6 +155,13 @@ static void conf_message(const char *fmt, ...) + static const char *conf_filename; + static int conf_lineno, conf_warnings; + ++bool conf_errors(void) ++{ ++ if (conf_warnings) ++ return getenv("KCONFIG_WERROR"); ++ return false; ++} ++ + static void conf_warning(const char *fmt, ...) + { + va_list ap; +@@ -346,14 +353,12 @@ int conf_read_simple(const char *name, int def) + FILE *in = NULL; + char *line = NULL; + size_t line_asize = 0; +- char *p, *p2; ++ char *p, *p2, *val; + struct symbol *sym; + int i, def_flags; +- const char *warn_unknown; +- const char *werror; ++ const char *warn_unknown, *sym_name; + + warn_unknown = getenv("KCONFIG_WARN_UNKNOWN_SYMBOLS"); +- werror = getenv("KCONFIG_WERROR"); + if (name) { + in = zconf_fopen(name); + } else { +@@ -386,10 +391,12 @@ int conf_read_simple(const char *name, int def) + + *p = '\0'; + +- in = zconf_fopen(env); ++ name = env; ++ ++ in = zconf_fopen(name); + if (in) { + conf_message("using defaults found in %s", +- env); ++ name); + goto load; + } + +@@ -428,80 +435,34 @@ int conf_read_simple(const char *name, int def) + + while (compat_getline(&line, &line_asize, in) != -1) { + conf_lineno++; +- sym = NULL; + if (line[0] == '#') { +- if (memcmp(line + 2, CONFIG_, strlen(CONFIG_))) ++ if (line[1] != ' ') ++ continue; ++ p = line + 2; ++ if (memcmp(p, CONFIG_, strlen(CONFIG_))) + continue; +- p = strchr(line + 2 + strlen(CONFIG_), ' '); ++ sym_name = p + strlen(CONFIG_); ++ p = strchr(sym_name, ' '); + if (!p) + continue; + *p++ = 0; + if (strncmp(p, "is not set", 10)) + continue; +- if (def == S_DEF_USER) { +- sym = sym_find(line + 2 + strlen(CONFIG_)); +- if (!sym) { +- if (warn_unknown) +- conf_warning("unknown symbol: %s", +- line + 2 + strlen(CONFIG_)); +- +- conf_set_changed(true); +- continue; +- } +- } else { +- sym = sym_lookup(line + 2 + strlen(CONFIG_), 0); +- if (sym->type == S_UNKNOWN) +- sym->type = S_BOOLEAN; +- } +- if (sym->flags & def_flags) { +- conf_warning("override: reassigning to symbol %s", sym->name); +- } +- switch (sym->type) { +- case S_BOOLEAN: +- case S_TRISTATE: +- sym->def[def].tri = no; +- sym->flags |= def_flags; +- break; +- default: +- ; +- } ++ ++ val = "n"; + } else if (memcmp(line, CONFIG_, strlen(CONFIG_)) == 0) { +- p = strchr(line + strlen(CONFIG_), '='); ++ sym_name = line + strlen(CONFIG_); ++ p = strchr(sym_name, '='); + if (!p) + continue; + *p++ = 0; ++ val = p; + p2 = strchr(p, '\n'); + if (p2) { + *p2-- = 0; + if (*p2 == '\r') + *p2 = 0; + } +- +- sym = sym_find(line + strlen(CONFIG_)); +- if (!sym) { +- if (def == S_DEF_AUTO) { +- /* +- * Reading from include/config/auto.conf +- * If CONFIG_FOO previously existed in +- * auto.conf but it is missing now, +- * include/config/FOO must be touched. +- */ +- conf_touch_dep(line + strlen(CONFIG_)); +- } else { +- if (warn_unknown) +- conf_warning("unknown symbol: %s", +- line + strlen(CONFIG_)); +- +- conf_set_changed(true); +- } +- continue; +- } +- +- if (sym->flags & def_flags) { +- conf_warning("override: reassigning to symbol %s", sym->name); +- } +- if (conf_set_sym_val(sym, def, def_flags, p)) +- continue; + } else { + if (line[0] != '\r' && line[0] != '\n') + conf_warning("unexpected data: %.*s", +@@ -510,6 +471,31 @@ int conf_read_simple(const char *name, int def) + continue; + } + ++ sym = sym_find(sym_name); ++ if (!sym) { ++ if (def == S_DEF_AUTO) { ++ /* ++ * Reading from include/config/auto.conf. ++ * If CONFIG_FOO previously existed in auto.conf ++ * but it is missing now, include/config/FOO ++ * must be touched. ++ */ ++ conf_touch_dep(sym_name); ++ } else { ++ if (warn_unknown) ++ conf_warning("unknown symbol: %s", sym_name); ++ ++ conf_set_changed(true); ++ } ++ continue; ++ } ++ ++ if (sym->flags & def_flags) ++ conf_warning("override: reassigning to symbol %s", sym->name); ++ ++ if (conf_set_sym_val(sym, def, def_flags, val)) ++ continue; ++ + if (sym && sym_is_choice_value(sym)) { + struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); + switch (sym->def[def].tri) { +@@ -533,9 +519,6 @@ int conf_read_simple(const char *name, int def) + free(line); + fclose(in); + +- if (conf_warnings && werror) +- exit(1); +- + return 0; + } + +diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h +index edd1e617b25c5c..e4931bde7ca765 100644 +--- a/scripts/kconfig/lkc_proto.h ++++ b/scripts/kconfig/lkc_proto.h +@@ -12,6 +12,7 @@ void conf_set_changed(bool val); + bool conf_get_changed(void); + void conf_set_changed_callback(void (*fn)(void)); + void conf_set_message_callback(void (*fn)(const char *s)); ++bool conf_errors(void); + + /* symbol.c */ + extern struct symbol * symbol_hash[SYMBOL_HASHSIZE]; +@@ -22,6 +23,7 @@ void print_symbol_for_listconfig(struct symbol *sym); + struct symbol ** sym_re_search(const char *pattern); + const char * sym_type_name(enum symbol_type type); + void sym_calc_value(struct symbol *sym); ++bool sym_dep_errors(void); + enum symbol_type sym_get_type(struct symbol *sym); + bool sym_tristate_within_range(struct symbol *sym,tristate tri); + bool sym_set_tristate_value(struct symbol *sym,tristate tri); +diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c +index 7b1df55b017679..1c0306c9d74e2e 100644 +--- a/scripts/kconfig/symbol.c ++++ b/scripts/kconfig/symbol.c +@@ -40,6 +40,7 @@ static struct symbol symbol_empty = { + + struct symbol *modules_sym; + static tristate modules_val; ++static int sym_warnings; + + enum symbol_type sym_get_type(struct symbol *sym) + { +@@ -320,6 +321,15 @@ static void sym_warn_unmet_dep(struct symbol *sym) + " Selected by [m]:\n"); + + fputs(str_get(&gs), stderr); ++ str_free(&gs); ++ sym_warnings++; ++} ++ ++bool sym_dep_errors(void) ++{ ++ if (sym_warnings) ++ return getenv("KCONFIG_WERROR"); ++ return false; + } + + void sym_calc_value(struct symbol *sym) +diff --git a/security/landlock/fs.c b/security/landlock/fs.c +index 1bdd049e3d636a..fe4622d88eb15e 100644 +--- a/security/landlock/fs.c ++++ b/security/landlock/fs.c +@@ -664,10 +664,6 @@ static inline access_mask_t get_mode_access(const umode_t mode) + switch (mode & S_IFMT) { + case S_IFLNK: + return LANDLOCK_ACCESS_FS_MAKE_SYM; +- case 0: +- /* A zero mode translates to S_IFREG. */ +- case S_IFREG: +- return LANDLOCK_ACCESS_FS_MAKE_REG; + case S_IFDIR: + return LANDLOCK_ACCESS_FS_MAKE_DIR; + case S_IFCHR: +@@ -678,9 +674,12 @@ static inline access_mask_t get_mode_access(const umode_t mode) + return LANDLOCK_ACCESS_FS_MAKE_FIFO; + case S_IFSOCK: + return LANDLOCK_ACCESS_FS_MAKE_SOCK; ++ case S_IFREG: ++ case 0: ++ /* A zero mode translates to S_IFREG. */ + default: +- WARN_ON_ONCE(1); +- return 0; ++ /* Treats weird files as regular files. */ ++ return LANDLOCK_ACCESS_FS_MAKE_REG; + } + } + +diff --git a/sound/core/seq/Kconfig b/sound/core/seq/Kconfig +index c14981daf9432f..e4f58cb985d47c 100644 +--- a/sound/core/seq/Kconfig ++++ b/sound/core/seq/Kconfig +@@ -62,7 +62,7 @@ config SND_SEQ_VIRMIDI + + config SND_SEQ_UMP + bool "Support for UMP events" +- default y if SND_SEQ_UMP_CLIENT ++ default SND_UMP + help + Say Y here to enable the support for handling UMP (Universal MIDI + Packet) events via ALSA sequencer infrastructure, which is an +@@ -71,7 +71,6 @@ config SND_SEQ_UMP + among legacy and UMP clients. + + config SND_SEQ_UMP_CLIENT +- tristate +- def_tristate SND_UMP ++ def_tristate SND_UMP && SND_SEQ_UMP + + endif # SND_SEQUENCER +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 739f8fd1792bd5..0b679fd1b82ab9 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -9726,6 +9726,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1025, 0x1308, "Acer Aspire Z24-890", ALC286_FIXUP_ACER_AIO_HEADSET_MIC), + SND_PCI_QUIRK(0x1025, 0x132a, "Acer TravelMate B114-21", ALC233_FIXUP_ACER_HEADSET_MIC), + SND_PCI_QUIRK(0x1025, 0x1330, "Acer TravelMate X514-51T", ALC255_FIXUP_ACER_HEADSET_MIC), ++ SND_PCI_QUIRK(0x1025, 0x1360, "Acer Aspire A115", ALC255_FIXUP_ACER_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1025, 0x141f, "Acer Spin SP513-54N", ALC255_FIXUP_ACER_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1025, 0x142b, "Acer Swift SF314-42", ALC255_FIXUP_ACER_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1025, 0x1430, "Acer TravelMate B311R-31", ALC256_FIXUP_ACER_MIC_NO_PRESENCE), +diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c +index 7434aeeda292ec..402b9a2ff02406 100644 +--- a/sound/soc/codecs/arizona.c ++++ b/sound/soc/codecs/arizona.c +@@ -2786,15 +2786,13 @@ int arizona_of_get_audio_pdata(struct arizona *arizona) + { + struct arizona_pdata *pdata = &arizona->pdata; + struct device_node *np = arizona->dev->of_node; +- struct property *prop; +- const __be32 *cur; + u32 val; + u32 pdm_val[ARIZONA_MAX_PDM_SPK]; + int ret; + int count = 0; + + count = 0; +- of_property_for_each_u32(np, "wlf,inmode", prop, cur, val) { ++ of_property_for_each_u32(np, "wlf,inmode", val) { + if (count == ARRAY_SIZE(pdata->inmode)) + break; + +@@ -2803,7 +2801,7 @@ int arizona_of_get_audio_pdata(struct arizona *arizona) + } + + count = 0; +- of_property_for_each_u32(np, "wlf,dmic-ref", prop, cur, val) { ++ of_property_for_each_u32(np, "wlf,dmic-ref", val) { + if (count == ARRAY_SIZE(pdata->dmic_ref)) + break; + +@@ -2812,7 +2810,7 @@ int arizona_of_get_audio_pdata(struct arizona *arizona) + } + + count = 0; +- of_property_for_each_u32(np, "wlf,out-mono", prop, cur, val) { ++ of_property_for_each_u32(np, "wlf,out-mono", val) { + if (count == ARRAY_SIZE(pdata->out_mono)) + break; + +@@ -2821,7 +2819,7 @@ int arizona_of_get_audio_pdata(struct arizona *arizona) + } + + count = 0; +- of_property_for_each_u32(np, "wlf,max-channels-clocked", prop, cur, val) { ++ of_property_for_each_u32(np, "wlf,max-channels-clocked", val) { + if (count == ARRAY_SIZE(pdata->max_channels_clocked)) + break; + +@@ -2830,7 +2828,7 @@ int arizona_of_get_audio_pdata(struct arizona *arizona) + } + + count = 0; +- of_property_for_each_u32(np, "wlf,out-volume-limit", prop, cur, val) { ++ of_property_for_each_u32(np, "wlf,out-volume-limit", val) { + if (count == ARRAY_SIZE(pdata->out_vol_limit)) + break; + +diff --git a/sound/soc/intel/avs/apl.c b/sound/soc/intel/avs/apl.c +index 1860099c782a72..25c389632db4f7 100644 +--- a/sound/soc/intel/avs/apl.c ++++ b/sound/soc/intel/avs/apl.c +@@ -14,10 +14,10 @@ + #include "topology.h" + + static int __maybe_unused +-apl_enable_logs(struct avs_dev *adev, enum avs_log_enable enable, u32 aging_period, +- u32 fifo_full_period, unsigned long resource_mask, u32 *priorities) ++avs_apl_enable_logs(struct avs_dev *adev, enum avs_log_enable enable, u32 aging_period, ++ u32 fifo_full_period, unsigned long resource_mask, u32 *priorities) + { +- struct apl_log_state_info *info; ++ struct avs_apl_log_state_info *info; + u32 size, num_cores = adev->hw_cfg.dsp_cores; + int ret, i; + +@@ -48,9 +48,9 @@ apl_enable_logs(struct avs_dev *adev, enum avs_log_enable enable, u32 aging_peri + return 0; + } + +-static int apl_log_buffer_status(struct avs_dev *adev, union avs_notify_msg *msg) ++static int avs_apl_log_buffer_status(struct avs_dev *adev, union avs_notify_msg *msg) + { +- struct apl_log_buffer_layout layout; ++ struct avs_apl_log_buffer_layout layout; + void __iomem *addr, *buf; + + addr = avs_log_buffer_addr(adev, msg->log.core); +@@ -63,11 +63,11 @@ static int apl_log_buffer_status(struct avs_dev *adev, union avs_notify_msg *msg + /* consume the logs regardless of consumer presence */ + goto update_read_ptr; + +- buf = apl_log_payload_addr(addr); ++ buf = avs_apl_log_payload_addr(addr); + + if (layout.read_ptr > layout.write_ptr) { + avs_dump_fw_log(adev, buf + layout.read_ptr, +- apl_log_payload_size(adev) - layout.read_ptr); ++ avs_apl_log_payload_size(adev) - layout.read_ptr); + layout.read_ptr = 0; + } + avs_dump_fw_log_wakeup(adev, buf + layout.read_ptr, layout.write_ptr - layout.read_ptr); +@@ -77,7 +77,8 @@ static int apl_log_buffer_status(struct avs_dev *adev, union avs_notify_msg *msg + return 0; + } + +-static int apl_wait_log_entry(struct avs_dev *adev, u32 core, struct apl_log_buffer_layout *layout) ++static int avs_apl_wait_log_entry(struct avs_dev *adev, u32 core, ++ struct avs_apl_log_buffer_layout *layout) + { + unsigned long timeout; + void __iomem *addr; +@@ -99,14 +100,14 @@ static int apl_wait_log_entry(struct avs_dev *adev, u32 core, struct apl_log_buf + } + + /* reads log header and tests its type */ +-#define apl_is_entry_stackdump(addr) ((readl(addr) >> 30) & 0x1) ++#define avs_apl_is_entry_stackdump(addr) ((readl(addr) >> 30) & 0x1) + +-static int apl_coredump(struct avs_dev *adev, union avs_notify_msg *msg) ++static int avs_apl_coredump(struct avs_dev *adev, union avs_notify_msg *msg) + { +- struct apl_log_buffer_layout layout; ++ struct avs_apl_log_buffer_layout layout; + void __iomem *addr, *buf; + size_t dump_size; +- u16 offset = 0; ++ u32 offset = 0; + u8 *dump, *pos; + + dump_size = AVS_FW_REGS_SIZE + msg->ext.coredump.stack_dump_size; +@@ -124,9 +125,9 @@ static int apl_coredump(struct avs_dev *adev, union avs_notify_msg *msg) + if (!addr) + goto exit; + +- buf = apl_log_payload_addr(addr); ++ buf = avs_apl_log_payload_addr(addr); + memcpy_fromio(&layout, addr, sizeof(layout)); +- if (!apl_is_entry_stackdump(buf + layout.read_ptr)) { ++ if (!avs_apl_is_entry_stackdump(buf + layout.read_ptr)) { + union avs_notify_msg lbs_msg = AVS_NOTIFICATION(LOG_BUFFER_STATUS); + + /* +@@ -142,11 +143,11 @@ static int apl_coredump(struct avs_dev *adev, union avs_notify_msg *msg) + do { + u32 count; + +- if (apl_wait_log_entry(adev, msg->ext.coredump.core_id, &layout)) ++ if (avs_apl_wait_log_entry(adev, msg->ext.coredump.core_id, &layout)) + break; + + if (layout.read_ptr > layout.write_ptr) { +- count = apl_log_payload_size(adev) - layout.read_ptr; ++ count = avs_apl_log_payload_size(adev) - layout.read_ptr; + memcpy_fromio(pos + offset, buf + layout.read_ptr, count); + layout.read_ptr = 0; + offset += count; +@@ -165,7 +166,7 @@ static int apl_coredump(struct avs_dev *adev, union avs_notify_msg *msg) + return 0; + } + +-static bool apl_lp_streaming(struct avs_dev *adev) ++static bool avs_apl_lp_streaming(struct avs_dev *adev) + { + struct avs_path *path; + +@@ -201,7 +202,7 @@ static bool apl_lp_streaming(struct avs_dev *adev) + return true; + } + +-static bool apl_d0ix_toggle(struct avs_dev *adev, struct avs_ipc_msg *tx, bool wake) ++static bool avs_apl_d0ix_toggle(struct avs_dev *adev, struct avs_ipc_msg *tx, bool wake) + { + /* wake in all cases */ + if (wake) +@@ -215,10 +216,10 @@ static bool apl_d0ix_toggle(struct avs_dev *adev, struct avs_ipc_msg *tx, bool w + * Note: for cAVS 1.5+ and 1.8, D0IX is LP-firmware transition, + * not the power-gating mechanism known from cAVS 2.0. + */ +- return apl_lp_streaming(adev); ++ return avs_apl_lp_streaming(adev); + } + +-static int apl_set_d0ix(struct avs_dev *adev, bool enable) ++static int avs_apl_set_d0ix(struct avs_dev *adev, bool enable) + { + bool streaming = false; + int ret; +@@ -231,7 +232,7 @@ static int apl_set_d0ix(struct avs_dev *adev, bool enable) + return AVS_IPC_RET(ret); + } + +-const struct avs_dsp_ops apl_dsp_ops = { ++const struct avs_dsp_ops avs_apl_dsp_ops = { + .power = avs_dsp_core_power, + .reset = avs_dsp_core_reset, + .stall = avs_dsp_core_stall, +@@ -241,10 +242,10 @@ const struct avs_dsp_ops apl_dsp_ops = { + .load_basefw = avs_hda_load_basefw, + .load_lib = avs_hda_load_library, + .transfer_mods = avs_hda_transfer_modules, +- .log_buffer_offset = skl_log_buffer_offset, +- .log_buffer_status = apl_log_buffer_status, +- .coredump = apl_coredump, +- .d0ix_toggle = apl_d0ix_toggle, +- .set_d0ix = apl_set_d0ix, ++ .log_buffer_offset = avs_skl_log_buffer_offset, ++ .log_buffer_status = avs_apl_log_buffer_status, ++ .coredump = avs_apl_coredump, ++ .d0ix_toggle = avs_apl_d0ix_toggle, ++ .set_d0ix = avs_apl_set_d0ix, + AVS_SET_ENABLE_LOGS_OP(apl) + }; +diff --git a/sound/soc/intel/avs/avs.h b/sound/soc/intel/avs/avs.h +index 0cf38c9e768e7b..1fd501a6a62d9e 100644 +--- a/sound/soc/intel/avs/avs.h ++++ b/sound/soc/intel/avs/avs.h +@@ -64,8 +64,8 @@ struct avs_dsp_ops { + #define avs_dsp_op(adev, op, ...) \ + ((adev)->spec->dsp_ops->op(adev, ## __VA_ARGS__)) + +-extern const struct avs_dsp_ops skl_dsp_ops; +-extern const struct avs_dsp_ops apl_dsp_ops; ++extern const struct avs_dsp_ops avs_skl_dsp_ops; ++extern const struct avs_dsp_ops avs_apl_dsp_ops; + + #define AVS_PLATATTR_CLDMA BIT_ULL(0) + #define AVS_PLATATTR_IMR BIT_ULL(1) +@@ -73,6 +73,23 @@ extern const struct avs_dsp_ops apl_dsp_ops; + #define avs_platattr_test(adev, attr) \ + ((adev)->spec->attributes & AVS_PLATATTR_##attr) + ++struct avs_sram_spec { ++ const u32 base_offset; ++ const u32 window_size; ++ const u32 rom_status_offset; ++}; ++ ++struct avs_hipc_spec { ++ const u32 req_offset; ++ const u32 req_ext_offset; ++ const u32 req_busy_mask; ++ const u32 ack_offset; ++ const u32 ack_done_mask; ++ const u32 rsp_offset; ++ const u32 rsp_busy_mask; ++ const u32 ctl_offset; ++}; ++ + /* Platform specific descriptor */ + struct avs_spec { + const char *name; +@@ -82,9 +99,8 @@ struct avs_spec { + + const u32 core_init_mask; /* used during DSP boot */ + const u64 attributes; /* bitmask of AVS_PLATATTR_* */ +- const u32 sram_base_offset; +- const u32 sram_window_size; +- const u32 rom_status; ++ const struct avs_sram_spec *sram; ++ const struct avs_hipc_spec *hipc; + }; + + struct avs_fw_entry { +@@ -264,7 +280,7 @@ void avs_ipc_block(struct avs_ipc *ipc); + int avs_dsp_disable_d0ix(struct avs_dev *adev); + int avs_dsp_enable_d0ix(struct avs_dev *adev); + +-int skl_log_buffer_offset(struct avs_dev *adev, u32 core); ++int avs_skl_log_buffer_offset(struct avs_dev *adev, u32 core); + + /* Firmware resources management */ + +@@ -358,21 +374,21 @@ static inline int avs_log_buffer_status_locked(struct avs_dev *adev, union avs_n + return ret; + } + +-struct apl_log_buffer_layout { ++struct avs_apl_log_buffer_layout { + u32 read_ptr; + u32 write_ptr; + u8 buffer[]; + } __packed; + +-#define apl_log_payload_size(adev) \ +- (avs_log_buffer_size(adev) - sizeof(struct apl_log_buffer_layout)) ++#define avs_apl_log_payload_size(adev) \ ++ (avs_log_buffer_size(adev) - sizeof(struct avs_apl_log_buffer_layout)) + +-#define apl_log_payload_addr(addr) \ +- (addr + sizeof(struct apl_log_buffer_layout)) ++#define avs_apl_log_payload_addr(addr) \ ++ (addr + sizeof(struct avs_apl_log_buffer_layout)) + + #ifdef CONFIG_DEBUG_FS + #define AVS_SET_ENABLE_LOGS_OP(name) \ +- .enable_logs = name##_enable_logs ++ .enable_logs = avs_##name##_enable_logs + + bool avs_logging_fw(struct avs_dev *adev); + void avs_dump_fw_log(struct avs_dev *adev, const void __iomem *src, unsigned int len); +diff --git a/sound/soc/intel/avs/core.c b/sound/soc/intel/avs/core.c +index 859b217fc761ba..63e4356e8caf94 100644 +--- a/sound/soc/intel/avs/core.c ++++ b/sound/soc/intel/avs/core.c +@@ -712,36 +712,47 @@ static const struct dev_pm_ops avs_dev_pm = { + SET_RUNTIME_PM_OPS(avs_runtime_suspend, avs_runtime_resume, NULL) + }; + ++static const struct avs_sram_spec skl_sram_spec = { ++ .base_offset = SKL_ADSP_SRAM_BASE_OFFSET, ++ .window_size = SKL_ADSP_SRAM_WINDOW_SIZE, ++ .rom_status_offset = SKL_ADSP_SRAM_BASE_OFFSET, ++}; ++ ++static const struct avs_sram_spec apl_sram_spec = { ++ .base_offset = APL_ADSP_SRAM_BASE_OFFSET, ++ .window_size = APL_ADSP_SRAM_WINDOW_SIZE, ++ .rom_status_offset = APL_ADSP_SRAM_BASE_OFFSET, ++}; ++ ++static const struct avs_hipc_spec skl_hipc_spec = { ++ .req_offset = SKL_ADSP_REG_HIPCI, ++ .req_ext_offset = SKL_ADSP_REG_HIPCIE, ++ .req_busy_mask = SKL_ADSP_HIPCI_BUSY, ++ .ack_offset = SKL_ADSP_REG_HIPCIE, ++ .ack_done_mask = SKL_ADSP_HIPCIE_DONE, ++ .rsp_offset = SKL_ADSP_REG_HIPCT, ++ .rsp_busy_mask = SKL_ADSP_HIPCT_BUSY, ++ .ctl_offset = SKL_ADSP_REG_HIPCCTL, ++}; ++ + static const struct avs_spec skl_desc = { + .name = "skl", +- .min_fw_version = { +- .major = 9, +- .minor = 21, +- .hotfix = 0, +- .build = 4732, +- }, +- .dsp_ops = &skl_dsp_ops, ++ .min_fw_version = { 9, 21, 0, 4732 }, ++ .dsp_ops = &avs_skl_dsp_ops, + .core_init_mask = 1, + .attributes = AVS_PLATATTR_CLDMA, +- .sram_base_offset = SKL_ADSP_SRAM_BASE_OFFSET, +- .sram_window_size = SKL_ADSP_SRAM_WINDOW_SIZE, +- .rom_status = SKL_ADSP_SRAM_BASE_OFFSET, ++ .sram = &skl_sram_spec, ++ .hipc = &skl_hipc_spec, + }; + + static const struct avs_spec apl_desc = { + .name = "apl", +- .min_fw_version = { +- .major = 9, +- .minor = 22, +- .hotfix = 1, +- .build = 4323, +- }, +- .dsp_ops = &apl_dsp_ops, ++ .min_fw_version = { 9, 22, 1, 4323 }, ++ .dsp_ops = &avs_apl_dsp_ops, + .core_init_mask = 3, + .attributes = AVS_PLATATTR_IMR, +- .sram_base_offset = APL_ADSP_SRAM_BASE_OFFSET, +- .sram_window_size = APL_ADSP_SRAM_WINDOW_SIZE, +- .rom_status = APL_ADSP_SRAM_BASE_OFFSET, ++ .sram = &apl_sram_spec, ++ .hipc = &skl_hipc_spec, + }; + + static const struct pci_device_id avs_ids[] = { +diff --git a/sound/soc/intel/avs/ipc.c b/sound/soc/intel/avs/ipc.c +index bdf013c3dd12e2..74f676fdfba29d 100644 +--- a/sound/soc/intel/avs/ipc.c ++++ b/sound/soc/intel/avs/ipc.c +@@ -305,6 +305,7 @@ irqreturn_t avs_dsp_irq_handler(int irq, void *dev_id) + { + struct avs_dev *adev = dev_id; + struct avs_ipc *ipc = adev->ipc; ++ const struct avs_spec *const spec = adev->spec; + u32 adspis, hipc_rsp, hipc_ack; + irqreturn_t ret = IRQ_NONE; + +@@ -312,35 +313,35 @@ irqreturn_t avs_dsp_irq_handler(int irq, void *dev_id) + if (adspis == UINT_MAX || !(adspis & AVS_ADSP_ADSPIS_IPC)) + return ret; + +- hipc_ack = snd_hdac_adsp_readl(adev, SKL_ADSP_REG_HIPCIE); +- hipc_rsp = snd_hdac_adsp_readl(adev, SKL_ADSP_REG_HIPCT); ++ hipc_ack = snd_hdac_adsp_readl(adev, spec->hipc->ack_offset); ++ hipc_rsp = snd_hdac_adsp_readl(adev, spec->hipc->rsp_offset); + + /* DSP acked host's request */ +- if (hipc_ack & SKL_ADSP_HIPCIE_DONE) { ++ if (hipc_ack & spec->hipc->ack_done_mask) { + /* + * As an extra precaution, mask done interrupt. Code executed + * due to complete() found below does not assume any masking. + */ +- snd_hdac_adsp_updatel(adev, SKL_ADSP_REG_HIPCCTL, ++ snd_hdac_adsp_updatel(adev, spec->hipc->ctl_offset, + AVS_ADSP_HIPCCTL_DONE, 0); + + complete(&ipc->done_completion); + + /* tell DSP it has our attention */ +- snd_hdac_adsp_updatel(adev, SKL_ADSP_REG_HIPCIE, +- SKL_ADSP_HIPCIE_DONE, +- SKL_ADSP_HIPCIE_DONE); ++ snd_hdac_adsp_updatel(adev, spec->hipc->ack_offset, ++ spec->hipc->ack_done_mask, ++ spec->hipc->ack_done_mask); + /* unmask done interrupt */ +- snd_hdac_adsp_updatel(adev, SKL_ADSP_REG_HIPCCTL, ++ snd_hdac_adsp_updatel(adev, spec->hipc->ctl_offset, + AVS_ADSP_HIPCCTL_DONE, + AVS_ADSP_HIPCCTL_DONE); + ret = IRQ_HANDLED; + } + + /* DSP sent new response to process */ +- if (hipc_rsp & SKL_ADSP_HIPCT_BUSY) { ++ if (hipc_rsp & spec->hipc->rsp_busy_mask) { + /* mask busy interrupt */ +- snd_hdac_adsp_updatel(adev, SKL_ADSP_REG_HIPCCTL, ++ snd_hdac_adsp_updatel(adev, spec->hipc->ctl_offset, + AVS_ADSP_HIPCCTL_BUSY, 0); + + ret = IRQ_WAKE_THREAD; +@@ -379,10 +380,11 @@ irqreturn_t avs_dsp_irq_thread(int irq, void *dev_id) + static bool avs_ipc_is_busy(struct avs_ipc *ipc) + { + struct avs_dev *adev = to_avs_dev(ipc->dev); ++ const struct avs_spec *const spec = adev->spec; + u32 hipc_rsp; + +- hipc_rsp = snd_hdac_adsp_readl(adev, SKL_ADSP_REG_HIPCT); +- return hipc_rsp & SKL_ADSP_HIPCT_BUSY; ++ hipc_rsp = snd_hdac_adsp_readl(adev, spec->hipc->rsp_offset); ++ return hipc_rsp & spec->hipc->rsp_busy_mask; + } + + static int avs_ipc_wait_busy_completion(struct avs_ipc *ipc, int timeout) +@@ -440,9 +442,10 @@ static void avs_ipc_msg_init(struct avs_ipc *ipc, struct avs_ipc_msg *reply) + + static void avs_dsp_send_tx(struct avs_dev *adev, struct avs_ipc_msg *tx, bool read_fwregs) + { ++ const struct avs_spec *const spec = adev->spec; + u64 reg = ULONG_MAX; + +- tx->header |= SKL_ADSP_HIPCI_BUSY; ++ tx->header |= spec->hipc->req_busy_mask; + if (read_fwregs) + reg = readq(avs_sram_addr(adev, AVS_FW_REGS_WINDOW)); + +@@ -450,8 +453,8 @@ static void avs_dsp_send_tx(struct avs_dev *adev, struct avs_ipc_msg *tx, bool r + + if (tx->size) + memcpy_toio(avs_downlink_addr(adev), tx->data, tx->size); +- snd_hdac_adsp_writel(adev, SKL_ADSP_REG_HIPCIE, tx->header >> 32); +- snd_hdac_adsp_writel(adev, SKL_ADSP_REG_HIPCI, tx->header & UINT_MAX); ++ snd_hdac_adsp_writel(adev, spec->hipc->req_ext_offset, tx->header >> 32); ++ snd_hdac_adsp_writel(adev, spec->hipc->req_offset, tx->header & UINT_MAX); + } + + static int avs_dsp_do_send_msg(struct avs_dev *adev, struct avs_ipc_msg *request, +@@ -586,6 +589,7 @@ int avs_dsp_send_rom_msg(struct avs_dev *adev, struct avs_ipc_msg *request) + + void avs_dsp_interrupt_control(struct avs_dev *adev, bool enable) + { ++ const struct avs_spec *const spec = adev->spec; + u32 value, mask; + + /* +@@ -597,7 +601,7 @@ void avs_dsp_interrupt_control(struct avs_dev *adev, bool enable) + + mask = AVS_ADSP_HIPCCTL_DONE | AVS_ADSP_HIPCCTL_BUSY; + value = enable ? mask : 0; +- snd_hdac_adsp_updatel(adev, SKL_ADSP_REG_HIPCCTL, mask, value); ++ snd_hdac_adsp_updatel(adev, spec->hipc->ctl_offset, mask, value); + } + + int avs_ipc_init(struct avs_ipc *ipc, struct device *dev) +diff --git a/sound/soc/intel/avs/loader.c b/sound/soc/intel/avs/loader.c +index 56bb0a59249d54..5c4ae3927ed243 100644 +--- a/sound/soc/intel/avs/loader.c ++++ b/sound/soc/intel/avs/loader.c +@@ -306,7 +306,7 @@ avs_hda_init_rom(struct avs_dev *adev, unsigned int dma_id, bool purge) + } + + /* await ROM init */ +- ret = snd_hdac_adsp_readq_poll(adev, spec->rom_status, reg, ++ ret = snd_hdac_adsp_readl_poll(adev, spec->sram->rom_status_offset, reg, + (reg & 0xF) == AVS_ROM_INIT_DONE || + (reg & 0xF) == APL_ROM_FW_ENTERED, + AVS_ROM_INIT_POLLING_US, APL_ROM_INIT_TIMEOUT_US); +diff --git a/sound/soc/intel/avs/messages.h b/sound/soc/intel/avs/messages.h +index 7f23a304b4a94e..9540401b093c13 100644 +--- a/sound/soc/intel/avs/messages.h ++++ b/sound/soc/intel/avs/messages.h +@@ -357,21 +357,21 @@ enum avs_skl_log_priority { + AVS_SKL_LOG_VERBOSE, + }; + +-struct skl_log_state { ++struct avs_skl_log_state { + u32 enable; + u32 min_priority; + } __packed; + +-struct skl_log_state_info { ++struct avs_skl_log_state_info { + u32 core_mask; +- struct skl_log_state logs_core[]; ++ struct avs_skl_log_state logs_core[]; + } __packed; + +-struct apl_log_state_info { ++struct avs_apl_log_state_info { + u32 aging_timer_period; + u32 fifo_full_timer_period; + u32 core_mask; +- struct skl_log_state logs_core[]; ++ struct avs_skl_log_state logs_core[]; + } __packed; + + int avs_ipc_set_enable_logs(struct avs_dev *adev, u8 *log_info, size_t size); +diff --git a/sound/soc/intel/avs/registers.h b/sound/soc/intel/avs/registers.h +index 2b464e466ed520..5c1dce46f71d8b 100644 +--- a/sound/soc/intel/avs/registers.h ++++ b/sound/soc/intel/avs/registers.h +@@ -55,7 +55,7 @@ + #define APL_ADSP_SRAM_WINDOW_SIZE 0x20000 + + /* Constants used when accessing SRAM, space shared with firmware */ +-#define AVS_FW_REG_BASE(adev) ((adev)->spec->sram_base_offset) ++#define AVS_FW_REG_BASE(adev) ((adev)->spec->sram->base_offset) + #define AVS_FW_REG_STATUS(adev) (AVS_FW_REG_BASE(adev) + 0x0) + #define AVS_FW_REG_ERROR_CODE(adev) (AVS_FW_REG_BASE(adev) + 0x4) + +@@ -70,8 +70,8 @@ + + /* registry I/O helpers */ + #define avs_sram_offset(adev, window_idx) \ +- ((adev)->spec->sram_base_offset + \ +- (adev)->spec->sram_window_size * (window_idx)) ++ ((adev)->spec->sram->base_offset + \ ++ (adev)->spec->sram->window_size * (window_idx)) + + #define avs_sram_addr(adev, window_idx) \ + ((adev)->dsp_ba + avs_sram_offset(adev, window_idx)) +diff --git a/sound/soc/intel/avs/skl.c b/sound/soc/intel/avs/skl.c +index 6bb8bbc70442bd..7ea8d91b54d2ed 100644 +--- a/sound/soc/intel/avs/skl.c ++++ b/sound/soc/intel/avs/skl.c +@@ -13,10 +13,10 @@ + #include "messages.h" + + static int __maybe_unused +-skl_enable_logs(struct avs_dev *adev, enum avs_log_enable enable, u32 aging_period, +- u32 fifo_full_period, unsigned long resource_mask, u32 *priorities) ++avs_skl_enable_logs(struct avs_dev *adev, enum avs_log_enable enable, u32 aging_period, ++ u32 fifo_full_period, unsigned long resource_mask, u32 *priorities) + { +- struct skl_log_state_info *info; ++ struct avs_skl_log_state_info *info; + u32 size, num_cores = adev->hw_cfg.dsp_cores; + int ret, i; + +@@ -45,7 +45,7 @@ skl_enable_logs(struct avs_dev *adev, enum avs_log_enable enable, u32 aging_peri + return 0; + } + +-int skl_log_buffer_offset(struct avs_dev *adev, u32 core) ++int avs_skl_log_buffer_offset(struct avs_dev *adev, u32 core) + { + return core * avs_log_buffer_size(adev); + } +@@ -53,8 +53,7 @@ int skl_log_buffer_offset(struct avs_dev *adev, u32 core) + /* fw DbgLogWp registers */ + #define FW_REGS_DBG_LOG_WP(core) (0x30 + 0x4 * core) + +-static int +-skl_log_buffer_status(struct avs_dev *adev, union avs_notify_msg *msg) ++static int avs_skl_log_buffer_status(struct avs_dev *adev, union avs_notify_msg *msg) + { + void __iomem *buf; + u16 size, write, offset; +@@ -74,7 +73,7 @@ skl_log_buffer_status(struct avs_dev *adev, union avs_notify_msg *msg) + return 0; + } + +-static int skl_coredump(struct avs_dev *adev, union avs_notify_msg *msg) ++static int avs_skl_coredump(struct avs_dev *adev, union avs_notify_msg *msg) + { + u8 *dump; + +@@ -88,20 +87,19 @@ static int skl_coredump(struct avs_dev *adev, union avs_notify_msg *msg) + return 0; + } + +-static bool +-skl_d0ix_toggle(struct avs_dev *adev, struct avs_ipc_msg *tx, bool wake) ++static bool avs_skl_d0ix_toggle(struct avs_dev *adev, struct avs_ipc_msg *tx, bool wake) + { + /* unsupported on cAVS 1.5 hw */ + return false; + } + +-static int skl_set_d0ix(struct avs_dev *adev, bool enable) ++static int avs_skl_set_d0ix(struct avs_dev *adev, bool enable) + { + /* unsupported on cAVS 1.5 hw */ + return 0; + } + +-const struct avs_dsp_ops skl_dsp_ops = { ++const struct avs_dsp_ops avs_skl_dsp_ops = { + .power = avs_dsp_core_power, + .reset = avs_dsp_core_reset, + .stall = avs_dsp_core_stall, +@@ -111,10 +109,10 @@ const struct avs_dsp_ops skl_dsp_ops = { + .load_basefw = avs_cldma_load_basefw, + .load_lib = avs_cldma_load_library, + .transfer_mods = avs_cldma_transfer_modules, +- .log_buffer_offset = skl_log_buffer_offset, +- .log_buffer_status = skl_log_buffer_status, +- .coredump = skl_coredump, +- .d0ix_toggle = skl_d0ix_toggle, +- .set_d0ix = skl_set_d0ix, ++ .log_buffer_offset = avs_skl_log_buffer_offset, ++ .log_buffer_status = avs_skl_log_buffer_status, ++ .coredump = avs_skl_coredump, ++ .d0ix_toggle = avs_skl_d0ix_toggle, ++ .set_d0ix = avs_skl_set_d0ix, + AVS_SET_ENABLE_LOGS_OP(skl) + }; +diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.c b/sound/soc/rockchip/rockchip_i2s_tdm.c +index e6a6eabc47e5bb..14e5c53e697b0e 100644 +--- a/sound/soc/rockchip/rockchip_i2s_tdm.c ++++ b/sound/soc/rockchip/rockchip_i2s_tdm.c +@@ -24,7 +24,6 @@ + + #define DRV_NAME "rockchip-i2s-tdm" + +-#define DEFAULT_MCLK_FS 256 + #define CH_GRP_MAX 4 /* The max channel 8 / 2 */ + #define MULTIPLEX_CH_MAX 10 + +@@ -72,6 +71,8 @@ struct rk_i2s_tdm_dev { + bool has_playback; + bool has_capture; + struct snd_soc_dai_driver *dai; ++ unsigned int mclk_rx_freq; ++ unsigned int mclk_tx_freq; + }; + + static int to_ch_num(unsigned int val) +@@ -647,6 +648,27 @@ static int rockchip_i2s_trcm_mode(struct snd_pcm_substream *substream, + return 0; + } + ++static int rockchip_i2s_tdm_set_sysclk(struct snd_soc_dai *cpu_dai, int stream, ++ unsigned int freq, int dir) ++{ ++ struct rk_i2s_tdm_dev *i2s_tdm = to_info(cpu_dai); ++ ++ if (i2s_tdm->clk_trcm) { ++ i2s_tdm->mclk_tx_freq = freq; ++ i2s_tdm->mclk_rx_freq = freq; ++ } else { ++ if (stream == SNDRV_PCM_STREAM_PLAYBACK) ++ i2s_tdm->mclk_tx_freq = freq; ++ else ++ i2s_tdm->mclk_rx_freq = freq; ++ } ++ ++ dev_dbg(i2s_tdm->dev, "The target mclk_%s freq is: %d\n", ++ stream ? "rx" : "tx", freq); ++ ++ return 0; ++} ++ + static int rockchip_i2s_tdm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +@@ -661,15 +683,19 @@ static int rockchip_i2s_tdm_hw_params(struct snd_pcm_substream *substream, + + if (i2s_tdm->clk_trcm == TRCM_TX) { + mclk = i2s_tdm->mclk_tx; ++ mclk_rate = i2s_tdm->mclk_tx_freq; + } else if (i2s_tdm->clk_trcm == TRCM_RX) { + mclk = i2s_tdm->mclk_rx; ++ mclk_rate = i2s_tdm->mclk_rx_freq; + } else if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + mclk = i2s_tdm->mclk_tx; ++ mclk_rate = i2s_tdm->mclk_tx_freq; + } else { + mclk = i2s_tdm->mclk_rx; ++ mclk_rate = i2s_tdm->mclk_rx_freq; + } + +- err = clk_set_rate(mclk, DEFAULT_MCLK_FS * params_rate(params)); ++ err = clk_set_rate(mclk, mclk_rate); + if (err) + return err; + +@@ -829,6 +855,7 @@ static const struct snd_soc_dai_ops rockchip_i2s_tdm_dai_ops = { + .hw_params = rockchip_i2s_tdm_hw_params, + .set_bclk_ratio = rockchip_i2s_tdm_set_bclk_ratio, + .set_fmt = rockchip_i2s_tdm_set_fmt, ++ .set_sysclk = rockchip_i2s_tdm_set_sysclk, + .set_tdm_slot = rockchip_dai_tdm_slot, + .trigger = rockchip_i2s_tdm_trigger, + }; +diff --git a/sound/soc/sh/rz-ssi.c b/sound/soc/sh/rz-ssi.c +index 1588b93cc35d01..353863f49b3131 100644 +--- a/sound/soc/sh/rz-ssi.c ++++ b/sound/soc/sh/rz-ssi.c +@@ -245,8 +245,7 @@ static void rz_ssi_stream_quit(struct rz_ssi_priv *ssi, + static int rz_ssi_clk_setup(struct rz_ssi_priv *ssi, unsigned int rate, + unsigned int channels) + { +- static s8 ckdv[16] = { 1, 2, 4, 8, 16, 32, 64, 128, +- 6, 12, 24, 48, 96, -1, -1, -1 }; ++ static u8 ckdv[] = { 1, 2, 4, 8, 16, 32, 64, 128, 6, 12, 24, 48, 96 }; + unsigned int channel_bits = 32; /* System Word Length */ + unsigned long bclk_rate = rate * channels * channel_bits; + unsigned int div; +diff --git a/sound/soc/sunxi/sun4i-spdif.c b/sound/soc/sunxi/sun4i-spdif.c +index 2347aeb049bccf..e482238388de12 100644 +--- a/sound/soc/sunxi/sun4i-spdif.c ++++ b/sound/soc/sunxi/sun4i-spdif.c +@@ -177,6 +177,7 @@ struct sun4i_spdif_quirks { + unsigned int reg_dac_txdata; + bool has_reset; + unsigned int val_fctl_ftx; ++ unsigned int mclk_multiplier; + }; + + struct sun4i_spdif_dev { +@@ -314,6 +315,7 @@ static int sun4i_spdif_hw_params(struct snd_pcm_substream *substream, + default: + return -EINVAL; + } ++ mclk *= host->quirks->mclk_multiplier; + + ret = clk_set_rate(host->spdif_clk, mclk); + if (ret < 0) { +@@ -348,6 +350,7 @@ static int sun4i_spdif_hw_params(struct snd_pcm_substream *substream, + default: + return -EINVAL; + } ++ mclk_div *= host->quirks->mclk_multiplier; + + reg_val = 0; + reg_val |= SUN4I_SPDIF_TXCFG_ASS; +@@ -541,24 +544,28 @@ static struct snd_soc_dai_driver sun4i_spdif_dai = { + static const struct sun4i_spdif_quirks sun4i_a10_spdif_quirks = { + .reg_dac_txdata = SUN4I_SPDIF_TXFIFO, + .val_fctl_ftx = SUN4I_SPDIF_FCTL_FTX, ++ .mclk_multiplier = 1, + }; + + static const struct sun4i_spdif_quirks sun6i_a31_spdif_quirks = { + .reg_dac_txdata = SUN4I_SPDIF_TXFIFO, + .val_fctl_ftx = SUN4I_SPDIF_FCTL_FTX, + .has_reset = true, ++ .mclk_multiplier = 1, + }; + + static const struct sun4i_spdif_quirks sun8i_h3_spdif_quirks = { + .reg_dac_txdata = SUN8I_SPDIF_TXFIFO, + .val_fctl_ftx = SUN4I_SPDIF_FCTL_FTX, + .has_reset = true, ++ .mclk_multiplier = 4, + }; + + static const struct sun4i_spdif_quirks sun50i_h6_spdif_quirks = { + .reg_dac_txdata = SUN8I_SPDIF_TXFIFO, + .val_fctl_ftx = SUN50I_H6_SPDIF_FCTL_FTX, + .has_reset = true, ++ .mclk_multiplier = 1, + }; + + static const struct of_device_id sun4i_spdif_of_match[] = { +diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c +index 9cdd6cfd8219a7..93d9ed8983dfce 100644 +--- a/sound/usb/quirks.c ++++ b/sound/usb/quirks.c +@@ -2243,6 +2243,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { + QUIRK_FLAG_CTL_MSG_DELAY_1M), + DEVICE_FLG(0x2d95, 0x8021, /* VIVO USB-C-XE710 HEADSET */ + QUIRK_FLAG_CTL_MSG_DELAY_1M), ++ DEVICE_FLG(0x2fc6, 0xf0b7, /* iBasso DC07 Pro */ ++ QUIRK_FLAG_CTL_MSG_DELAY_1M), + DEVICE_FLG(0x30be, 0x0101, /* Schiit Hel */ + QUIRK_FLAG_IGNORE_CTL_ERROR), + DEVICE_FLG(0x413c, 0xa506, /* Dell AE515 sound bar */ +diff --git a/tools/bootconfig/main.c b/tools/bootconfig/main.c +index 156b62a163c5a6..8a48cc2536f566 100644 +--- a/tools/bootconfig/main.c ++++ b/tools/bootconfig/main.c +@@ -226,7 +226,7 @@ static int load_xbc_from_initrd(int fd, char **buf) + /* Wrong Checksum */ + rcsum = xbc_calc_checksum(*buf, size); + if (csum != rcsum) { +- pr_err("checksum error: %d != %d\n", csum, rcsum); ++ pr_err("checksum error: %u != %u\n", csum, rcsum); + return -EINVAL; + } + +@@ -395,7 +395,7 @@ static int apply_xbc(const char *path, const char *xbc_path) + xbc_get_info(&ret, NULL); + printf("\tNumber of nodes: %d\n", ret); + printf("\tSize: %u bytes\n", (unsigned int)size); +- printf("\tChecksum: %d\n", (unsigned int)csum); ++ printf("\tChecksum: %u\n", (unsigned int)csum); + + /* TODO: Check the options by schema */ + xbc_exit(); +diff --git a/tools/lib/bpf/linker.c b/tools/lib/bpf/linker.c +index 88cc7236f12202..736ebceea233f8 100644 +--- a/tools/lib/bpf/linker.c ++++ b/tools/lib/bpf/linker.c +@@ -567,17 +567,15 @@ static int linker_load_obj_file(struct bpf_linker *linker, const char *filename, + } + obj->elf = elf_begin(obj->fd, ELF_C_READ_MMAP, NULL); + if (!obj->elf) { +- err = -errno; + pr_warn_elf("failed to parse ELF file '%s'", filename); +- return err; ++ return -EINVAL; + } + + /* Sanity check ELF file high-level properties */ + ehdr = elf64_getehdr(obj->elf); + if (!ehdr) { +- err = -errno; + pr_warn_elf("failed to get ELF header for %s", filename); +- return err; ++ return -EINVAL; + } + if (ehdr->e_ident[EI_DATA] != host_endianness) { + err = -EOPNOTSUPP; +@@ -593,9 +591,8 @@ static int linker_load_obj_file(struct bpf_linker *linker, const char *filename, + } + + if (elf_getshdrstrndx(obj->elf, &obj->shstrs_sec_idx)) { +- err = -errno; + pr_warn_elf("failed to get SHSTRTAB section index for %s", filename); +- return err; ++ return -EINVAL; + } + + scn = NULL; +@@ -605,26 +602,23 @@ static int linker_load_obj_file(struct bpf_linker *linker, const char *filename, + + shdr = elf64_getshdr(scn); + if (!shdr) { +- err = -errno; + pr_warn_elf("failed to get section #%zu header for %s", + sec_idx, filename); +- return err; ++ return -EINVAL; + } + + sec_name = elf_strptr(obj->elf, obj->shstrs_sec_idx, shdr->sh_name); + if (!sec_name) { +- err = -errno; + pr_warn_elf("failed to get section #%zu name for %s", + sec_idx, filename); +- return err; ++ return -EINVAL; + } + + data = elf_getdata(scn, 0); + if (!data) { +- err = -errno; + pr_warn_elf("failed to get section #%zu (%s) data from %s", + sec_idx, sec_name, filename); +- return err; ++ return -EINVAL; + } + + sec = add_src_sec(obj, sec_name); +@@ -2602,14 +2596,14 @@ int bpf_linker__finalize(struct bpf_linker *linker) + + /* Finalize ELF layout */ + if (elf_update(linker->elf, ELF_C_NULL) < 0) { +- err = -errno; ++ err = -EINVAL; + pr_warn_elf("failed to finalize ELF layout"); + return libbpf_err(err); + } + + /* Write out final ELF contents */ + if (elf_update(linker->elf, ELF_C_WRITE) < 0) { +- err = -errno; ++ err = -EINVAL; + pr_warn_elf("failed to write ELF contents"); + return libbpf_err(err); + } +diff --git a/tools/lib/bpf/usdt.c b/tools/lib/bpf/usdt.c +index 93794f01bb67cb..6ff28e7bf5e3da 100644 +--- a/tools/lib/bpf/usdt.c ++++ b/tools/lib/bpf/usdt.c +@@ -659,7 +659,7 @@ static int collect_usdt_targets(struct usdt_manager *man, Elf *elf, const char * + * [0] https://sourceware.org/systemtap/wiki/UserSpaceProbeImplementation + */ + usdt_abs_ip = note.loc_addr; +- if (base_addr) ++ if (base_addr && note.base_addr) + usdt_abs_ip += base_addr - note.base_addr; + + /* When attaching uprobes (which is what USDTs basically are) +diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c +index fcb32c58bee7e4..bd24ed0af208a1 100644 +--- a/tools/perf/builtin-lock.c ++++ b/tools/perf/builtin-lock.c +@@ -1591,8 +1591,8 @@ static const struct { + { LCB_F_PERCPU | LCB_F_WRITE, "pcpu-sem:W", "percpu-rwsem" }, + { LCB_F_MUTEX, "mutex", "mutex" }, + { LCB_F_MUTEX | LCB_F_SPIN, "mutex", "mutex" }, +- /* alias for get_type_flag() */ +- { LCB_F_MUTEX | LCB_F_SPIN, "mutex-spin", "mutex" }, ++ /* alias for optimistic spinning only */ ++ { LCB_F_MUTEX | LCB_F_SPIN, "mutex:spin", "mutex-spin" }, + }; + + static const char *get_type_str(unsigned int flags) +@@ -1617,19 +1617,6 @@ static const char *get_type_name(unsigned int flags) + return "unknown"; + } + +-static unsigned int get_type_flag(const char *str) +-{ +- for (unsigned int i = 0; i < ARRAY_SIZE(lock_type_table); i++) { +- if (!strcmp(lock_type_table[i].name, str)) +- return lock_type_table[i].flags; +- } +- for (unsigned int i = 0; i < ARRAY_SIZE(lock_type_table); i++) { +- if (!strcmp(lock_type_table[i].str, str)) +- return lock_type_table[i].flags; +- } +- return UINT_MAX; +-} +- + static void lock_filter_finish(void) + { + zfree(&filters.types); +@@ -2321,29 +2308,58 @@ static int parse_lock_type(const struct option *opt __maybe_unused, const char * + int unset __maybe_unused) + { + char *s, *tmp, *tok; +- int ret = 0; + + s = strdup(str); + if (s == NULL) + return -1; + + for (tok = strtok_r(s, ", ", &tmp); tok; tok = strtok_r(NULL, ", ", &tmp)) { +- unsigned int flags = get_type_flag(tok); ++ bool found = false; + +- if (flags == -1U) { +- pr_err("Unknown lock flags: %s\n", tok); +- ret = -1; +- break; ++ /* `tok` is `str` in `lock_type_table` if it contains ':'. */ ++ if (strchr(tok, ':')) { ++ for (unsigned int i = 0; i < ARRAY_SIZE(lock_type_table); i++) { ++ if (!strcmp(lock_type_table[i].str, tok) && ++ add_lock_type(lock_type_table[i].flags)) { ++ found = true; ++ break; ++ } ++ } ++ ++ if (!found) { ++ pr_err("Unknown lock flags name: %s\n", tok); ++ free(s); ++ return -1; ++ } ++ ++ continue; + } + +- if (!add_lock_type(flags)) { +- ret = -1; +- break; ++ /* ++ * Otherwise `tok` is `name` in `lock_type_table`. ++ * Single lock name could contain multiple flags. ++ */ ++ for (unsigned int i = 0; i < ARRAY_SIZE(lock_type_table); i++) { ++ if (!strcmp(lock_type_table[i].name, tok)) { ++ if (add_lock_type(lock_type_table[i].flags)) { ++ found = true; ++ } else { ++ free(s); ++ return -1; ++ } ++ } + } ++ ++ if (!found) { ++ pr_err("Unknown lock name: %s\n", tok); ++ free(s); ++ return -1; ++ } ++ + } + + free(s); +- return ret; ++ return 0; + } + + static bool add_lock_addr(unsigned long addr) +diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c +index cd2f3f1a756330..54b06db597862f 100644 +--- a/tools/perf/builtin-report.c ++++ b/tools/perf/builtin-report.c +@@ -1352,7 +1352,7 @@ int cmd_report(int argc, const char **argv) + OPT_STRING(0, "addr2line", &addr2line_path, "path", + "addr2line binary to use for line numbers"), + OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle, +- "Disable symbol demangling"), ++ "Symbol demangling. Enabled by default, use --no-demangle to disable."), + OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel, + "Enable kernel symbol demangling"), + OPT_BOOLEAN(0, "mem-mode", &report.mem_mode, "mem access profile"), +diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c +index 1c1ec444d501ee..381274c70a9afd 100644 +--- a/tools/perf/builtin-top.c ++++ b/tools/perf/builtin-top.c +@@ -809,7 +809,7 @@ static void perf_event__process_sample(struct perf_tool *tool, + * invalid --vmlinux ;-) + */ + if (!machine->kptr_restrict_warned && !top->vmlinux_warned && +- __map__is_kernel(al.map) && map__has_symbols(al.map)) { ++ __map__is_kernel(al.map) && !map__has_symbols(al.map)) { + if (symbol_conf.vmlinux_name) { + char serr[256]; + +diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c +index 3ecd6868be2d6d..12bdbf3ecc6ae4 100644 +--- a/tools/perf/builtin-trace.c ++++ b/tools/perf/builtin-trace.c +@@ -1850,8 +1850,12 @@ static int trace__read_syscall_info(struct trace *trace, int id) + return PTR_ERR(sc->tp_format); + } + ++ /* ++ * The tracepoint format contains __syscall_nr field, so it's one more ++ * than the actual number of syscall arguments. ++ */ + if (syscall__alloc_arg_fmts(sc, IS_ERR(sc->tp_format) ? +- RAW_SYSCALL_ARGS_NUM : sc->tp_format->format.nr_fields)) ++ RAW_SYSCALL_ARGS_NUM : sc->tp_format->format.nr_fields - 1)) + return -ENOMEM; + + sc->args = sc->tp_format->format.fields; +diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c +index b00b5a2634c3d1..b94b4f16a60a54 100644 +--- a/tools/perf/util/bpf-event.c ++++ b/tools/perf/util/bpf-event.c +@@ -288,7 +288,10 @@ static int perf_event__synthesize_one_bpf_prog(struct perf_session *session, + } + + info_node->info_linear = info_linear; +- perf_env__insert_bpf_prog_info(env, info_node); ++ if (!perf_env__insert_bpf_prog_info(env, info_node)) { ++ free(info_linear); ++ free(info_node); ++ } + info_linear = NULL; + + /* +@@ -476,7 +479,10 @@ static void perf_env__add_bpf_info(struct perf_env *env, u32 id) + info_node = malloc(sizeof(struct bpf_prog_info_node)); + if (info_node) { + info_node->info_linear = info_linear; +- perf_env__insert_bpf_prog_info(env, info_node); ++ if (!perf_env__insert_bpf_prog_info(env, info_node)) { ++ free(info_linear); ++ free(info_node); ++ } + } else + free(info_linear); + +diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c +index d2c7b6e6eae51b..cea15c568602b1 100644 +--- a/tools/perf/util/env.c ++++ b/tools/perf/util/env.c +@@ -20,15 +20,19 @@ struct perf_env perf_env; + #include "bpf-utils.h" + #include + +-void perf_env__insert_bpf_prog_info(struct perf_env *env, ++bool perf_env__insert_bpf_prog_info(struct perf_env *env, + struct bpf_prog_info_node *info_node) + { ++ bool ret; ++ + down_write(&env->bpf_progs.lock); +- __perf_env__insert_bpf_prog_info(env, info_node); ++ ret = __perf_env__insert_bpf_prog_info(env, info_node); + up_write(&env->bpf_progs.lock); ++ ++ return ret; + } + +-void __perf_env__insert_bpf_prog_info(struct perf_env *env, struct bpf_prog_info_node *info_node) ++bool __perf_env__insert_bpf_prog_info(struct perf_env *env, struct bpf_prog_info_node *info_node) + { + __u32 prog_id = info_node->info_linear->info.id; + struct bpf_prog_info_node *node; +@@ -46,13 +50,14 @@ void __perf_env__insert_bpf_prog_info(struct perf_env *env, struct bpf_prog_info + p = &(*p)->rb_right; + } else { + pr_debug("duplicated bpf prog info %u\n", prog_id); +- return; ++ return false; + } + } + + rb_link_node(&info_node->rb_node, parent, p); + rb_insert_color(&info_node->rb_node, &env->bpf_progs.infos); + env->bpf_progs.infos_cnt++; ++ return true; + } + + struct bpf_prog_info_node *perf_env__find_bpf_prog_info(struct perf_env *env, +diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h +index 359eff51cb85b7..bc2d0ef3519978 100644 +--- a/tools/perf/util/env.h ++++ b/tools/perf/util/env.h +@@ -164,9 +164,9 @@ const char *perf_env__raw_arch(struct perf_env *env); + int perf_env__nr_cpus_avail(struct perf_env *env); + + void perf_env__init(struct perf_env *env); +-void __perf_env__insert_bpf_prog_info(struct perf_env *env, ++bool __perf_env__insert_bpf_prog_info(struct perf_env *env, + struct bpf_prog_info_node *info_node); +-void perf_env__insert_bpf_prog_info(struct perf_env *env, ++bool perf_env__insert_bpf_prog_info(struct perf_env *env, + struct bpf_prog_info_node *info_node); + struct bpf_prog_info_node *perf_env__find_bpf_prog_info(struct perf_env *env, + __u32 prog_id); +diff --git a/tools/perf/util/expr.c b/tools/perf/util/expr.c +index b8875aac8f8709..fa0473f7a4ff45 100644 +--- a/tools/perf/util/expr.c ++++ b/tools/perf/util/expr.c +@@ -292,7 +292,7 @@ struct expr_parse_ctx *expr__ctx_new(void) + { + struct expr_parse_ctx *ctx; + +- ctx = malloc(sizeof(struct expr_parse_ctx)); ++ ctx = calloc(1, sizeof(struct expr_parse_ctx)); + if (!ctx) + return NULL; + +@@ -301,9 +301,6 @@ struct expr_parse_ctx *expr__ctx_new(void) + free(ctx); + return NULL; + } +- ctx->sctx.user_requested_cpu_list = NULL; +- ctx->sctx.runtime = 0; +- ctx->sctx.system_wide = false; + + return ctx; + } +diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c +index 1482567e5ac1a7..0b44176826bfd9 100644 +--- a/tools/perf/util/header.c ++++ b/tools/perf/util/header.c +@@ -3177,7 +3177,10 @@ static int process_bpf_prog_info(struct feat_fd *ff, void *data __maybe_unused) + /* after reading from file, translate offset to address */ + bpil_offs_to_addr(info_linear); + info_node->info_linear = info_linear; +- __perf_env__insert_bpf_prog_info(env, info_node); ++ if (!__perf_env__insert_bpf_prog_info(env, info_node)) { ++ free(info_linear); ++ free(info_node); ++ } + } + + up_write(&env->bpf_progs.lock); +@@ -3224,7 +3227,8 @@ static int process_bpf_btf(struct feat_fd *ff, void *data __maybe_unused) + if (__do_read(ff, node->data, data_size)) + goto out; + +- __perf_env__insert_btf(env, node); ++ if (!__perf_env__insert_btf(env, node)) ++ free(node); + node = NULL; + } + +diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c +index 7c6874804660eb..e2a6facd1c4e2a 100644 +--- a/tools/perf/util/machine.c ++++ b/tools/perf/util/machine.c +@@ -1217,7 +1217,7 @@ static int machine__get_running_kernel_start(struct machine *machine, + + err = kallsyms__get_symbol_start(filename, "_edata", &addr); + if (err) +- err = kallsyms__get_function_start(filename, "_etext", &addr); ++ err = kallsyms__get_symbol_start(filename, "_etext", &addr); + if (!err) + *end = addr; + +diff --git a/tools/perf/util/namespaces.c b/tools/perf/util/namespaces.c +index cb185c5659d6b3..68f5de2d79c72c 100644 +--- a/tools/perf/util/namespaces.c ++++ b/tools/perf/util/namespaces.c +@@ -266,11 +266,16 @@ pid_t nsinfo__pid(const struct nsinfo *nsi) + return RC_CHK_ACCESS(nsi)->pid; + } + +-pid_t nsinfo__in_pidns(const struct nsinfo *nsi) ++bool nsinfo__in_pidns(const struct nsinfo *nsi) + { + return RC_CHK_ACCESS(nsi)->in_pidns; + } + ++void nsinfo__set_in_pidns(struct nsinfo *nsi) ++{ ++ RC_CHK_ACCESS(nsi)->in_pidns = true; ++} ++ + void nsinfo__mountns_enter(struct nsinfo *nsi, + struct nscookie *nc) + { +diff --git a/tools/perf/util/namespaces.h b/tools/perf/util/namespaces.h +index 8c0731c6cbb7ee..e95c79b80e27c8 100644 +--- a/tools/perf/util/namespaces.h ++++ b/tools/perf/util/namespaces.h +@@ -58,7 +58,8 @@ void nsinfo__clear_need_setns(struct nsinfo *nsi); + pid_t nsinfo__tgid(const struct nsinfo *nsi); + pid_t nsinfo__nstgid(const struct nsinfo *nsi); + pid_t nsinfo__pid(const struct nsinfo *nsi); +-pid_t nsinfo__in_pidns(const struct nsinfo *nsi); ++bool nsinfo__in_pidns(const struct nsinfo *nsi); ++void nsinfo__set_in_pidns(struct nsinfo *nsi); + + void nsinfo__mountns_enter(struct nsinfo *nsi, struct nscookie *nc); + void nsinfo__mountns_exit(struct nscookie *nc); +diff --git a/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c b/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c +index ae6af354a81db5..08a399b0be286c 100644 +--- a/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c ++++ b/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c +@@ -33,7 +33,7 @@ static int mperf_get_count_percent(unsigned int self_id, double *percent, + unsigned int cpu); + static int mperf_get_count_freq(unsigned int id, unsigned long long *count, + unsigned int cpu); +-static struct timespec time_start, time_end; ++static struct timespec *time_start, *time_end; + + static cstate_t mperf_cstates[MPERF_CSTATE_COUNT] = { + { +@@ -174,7 +174,7 @@ static int mperf_get_count_percent(unsigned int id, double *percent, + dprint("%s: TSC Ref - mperf_diff: %llu, tsc_diff: %llu\n", + mperf_cstates[id].name, mperf_diff, tsc_diff); + } else if (max_freq_mode == MAX_FREQ_SYSFS) { +- timediff = max_frequency * timespec_diff_us(time_start, time_end); ++ timediff = max_frequency * timespec_diff_us(time_start[cpu], time_end[cpu]); + *percent = 100.0 * mperf_diff / timediff; + dprint("%s: MAXFREQ - mperf_diff: %llu, time_diff: %llu\n", + mperf_cstates[id].name, mperf_diff, timediff); +@@ -207,7 +207,7 @@ static int mperf_get_count_freq(unsigned int id, unsigned long long *count, + if (max_freq_mode == MAX_FREQ_TSC_REF) { + /* Calculate max_freq from TSC count */ + tsc_diff = tsc_at_measure_end[cpu] - tsc_at_measure_start[cpu]; +- time_diff = timespec_diff_us(time_start, time_end); ++ time_diff = timespec_diff_us(time_start[cpu], time_end[cpu]); + max_frequency = tsc_diff / time_diff; + } + +@@ -226,9 +226,8 @@ static int mperf_start(void) + { + int cpu; + +- clock_gettime(CLOCK_REALTIME, &time_start); +- + for (cpu = 0; cpu < cpu_count; cpu++) { ++ clock_gettime(CLOCK_REALTIME, &time_start[cpu]); + mperf_get_tsc(&tsc_at_measure_start[cpu]); + mperf_init_stats(cpu); + } +@@ -243,9 +242,9 @@ static int mperf_stop(void) + for (cpu = 0; cpu < cpu_count; cpu++) { + mperf_measure_stats(cpu); + mperf_get_tsc(&tsc_at_measure_end[cpu]); ++ clock_gettime(CLOCK_REALTIME, &time_end[cpu]); + } + +- clock_gettime(CLOCK_REALTIME, &time_end); + return 0; + } + +@@ -349,6 +348,8 @@ struct cpuidle_monitor *mperf_register(void) + aperf_current_count = calloc(cpu_count, sizeof(unsigned long long)); + tsc_at_measure_start = calloc(cpu_count, sizeof(unsigned long long)); + tsc_at_measure_end = calloc(cpu_count, sizeof(unsigned long long)); ++ time_start = calloc(cpu_count, sizeof(struct timespec)); ++ time_end = calloc(cpu_count, sizeof(struct timespec)); + mperf_monitor.name_len = strlen(mperf_monitor.name); + return &mperf_monitor; + } +@@ -361,6 +362,8 @@ void mperf_unregister(void) + free(aperf_current_count); + free(tsc_at_measure_start); + free(tsc_at_measure_end); ++ free(time_start); ++ free(time_end); + free(is_valid); + } + +diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl +index 045090085ac5bd..83d65c2abaf010 100755 +--- a/tools/testing/ktest/ktest.pl ++++ b/tools/testing/ktest/ktest.pl +@@ -2406,6 +2406,11 @@ sub get_version { + return if ($have_version); + doprint "$make kernelrelease ... "; + $version = `$make -s kernelrelease | tail -1`; ++ if (!length($version)) { ++ run_command "$make allnoconfig" or return 0; ++ doprint "$make kernelrelease ... "; ++ $version = `$make -s kernelrelease | tail -1`; ++ } + chomp($version); + doprint "$version\n"; + $have_version = 1; +@@ -2946,8 +2951,6 @@ sub run_bisect_test { + + my $failed = 0; + my $result; +- my $output; +- my $ret; + + $in_bisect = 1; + +diff --git a/tools/testing/selftests/bpf/prog_tests/fill_link_info.c b/tools/testing/selftests/bpf/prog_tests/fill_link_info.c +index 5b0c6a04cdbfe0..e0208b0e53f162 100644 +--- a/tools/testing/selftests/bpf/prog_tests/fill_link_info.c ++++ b/tools/testing/selftests/bpf/prog_tests/fill_link_info.c +@@ -164,6 +164,10 @@ static void test_kprobe_fill_link_info(struct test_fill_link_info *skel, + /* See also arch_adjust_kprobe_addr(). */ + if (skel->kconfig->CONFIG_X86_KERNEL_IBT) + entry_offset = 4; ++ if (skel->kconfig->CONFIG_PPC64 && ++ skel->kconfig->CONFIG_KPROBES_ON_FTRACE && ++ !skel->kconfig->CONFIG_PPC_FTRACE_OUT_OF_LINE) ++ entry_offset = 4; + err = verify_perf_link_info(link_fd, type, kprobe_addr, 0, entry_offset); + ASSERT_OK(err, "verify_perf_link_info"); + } else { +diff --git a/tools/testing/selftests/bpf/progs/test_fill_link_info.c b/tools/testing/selftests/bpf/progs/test_fill_link_info.c +index 564f402d56fef7..54b53ad05339df 100644 +--- a/tools/testing/selftests/bpf/progs/test_fill_link_info.c ++++ b/tools/testing/selftests/bpf/progs/test_fill_link_info.c +@@ -6,13 +6,20 @@ + #include + + extern bool CONFIG_X86_KERNEL_IBT __kconfig __weak; ++extern bool CONFIG_PPC_FTRACE_OUT_OF_LINE __kconfig __weak; ++extern bool CONFIG_KPROBES_ON_FTRACE __kconfig __weak; ++extern bool CONFIG_PPC64 __kconfig __weak; + +-/* This function is here to have CONFIG_X86_KERNEL_IBT +- * used and added to object BTF. ++/* This function is here to have CONFIG_X86_KERNEL_IBT, ++ * CONFIG_PPC_FTRACE_OUT_OF_LINE, CONFIG_KPROBES_ON_FTRACE, ++ * CONFIG_PPC6 used and added to object BTF. + */ + int unused(void) + { +- return CONFIG_X86_KERNEL_IBT ? 0 : 1; ++ return CONFIG_X86_KERNEL_IBT || ++ CONFIG_PPC_FTRACE_OUT_OF_LINE || ++ CONFIG_KPROBES_ON_FTRACE || ++ CONFIG_PPC64 ? 0 : 1; + } + + SEC("kprobe") +diff --git a/tools/testing/selftests/bpf/test_tc_tunnel.sh b/tools/testing/selftests/bpf/test_tc_tunnel.sh +index 7989ec60845455..cb55a908bb0d70 100755 +--- a/tools/testing/selftests/bpf/test_tc_tunnel.sh ++++ b/tools/testing/selftests/bpf/test_tc_tunnel.sh +@@ -305,6 +305,7 @@ else + client_connect + verify_data + server_listen ++ wait_for_port ${port} ${netcat_opt} + fi + + # serverside, use BPF for decap +diff --git a/tools/testing/selftests/drivers/net/netdevsim/udp_tunnel_nic.sh b/tools/testing/selftests/drivers/net/netdevsim/udp_tunnel_nic.sh +index 185b02d2d4cd14..7af78990b5bb60 100755 +--- a/tools/testing/selftests/drivers/net/netdevsim/udp_tunnel_nic.sh ++++ b/tools/testing/selftests/drivers/net/netdevsim/udp_tunnel_nic.sh +@@ -142,7 +142,7 @@ function pre_ethtool { + } + + function check_table { +- local path=$NSIM_DEV_DFS/ports/$port/udp_ports_table$1 ++ local path=$NSIM_DEV_DFS/ports/$port/udp_ports/table$1 + local -n expected=$2 + local last=$3 + +@@ -212,7 +212,7 @@ function check_tables { + } + + function print_table { +- local path=$NSIM_DEV_DFS/ports/$port/udp_ports_table$1 ++ local path=$NSIM_DEV_DFS/ports/$port/udp_ports/table$1 + read -a have < $path + + tree $NSIM_DEV_DFS/ +@@ -640,7 +640,7 @@ for port in 0 1; do + NSIM_NETDEV=`get_netdev_name old_netdevs` + ifconfig $NSIM_NETDEV up + +- echo 110 > $NSIM_DEV_DFS/ports/$port/udp_ports_inject_error ++ echo 110 > $NSIM_DEV_DFS/ports/$port/udp_ports/inject_error + + msg="1 - create VxLANs v6" + exp0=( 0 0 0 0 ) +@@ -662,7 +662,7 @@ for port in 0 1; do + new_geneve gnv0 20000 + + msg="2 - destroy GENEVE" +- echo 2 > $NSIM_DEV_DFS/ports/$port/udp_ports_inject_error ++ echo 2 > $NSIM_DEV_DFS/ports/$port/udp_ports/inject_error + exp1=( `mke 20000 2` 0 0 0 ) + del_dev gnv0 + +@@ -763,7 +763,7 @@ for port in 0 1; do + msg="create VxLANs v4" + new_vxlan vxlan0 10000 $NSIM_NETDEV + +- echo 1 > $NSIM_DEV_DFS/ports/$port/udp_ports_reset ++ echo 1 > $NSIM_DEV_DFS/ports/$port/udp_ports/reset + check_tables + + msg="NIC device goes down" +@@ -774,7 +774,7 @@ for port in 0 1; do + fi + check_tables + +- echo 1 > $NSIM_DEV_DFS/ports/$port/udp_ports_reset ++ echo 1 > $NSIM_DEV_DFS/ports/$port/udp_ports/reset + check_tables + + msg="NIC device goes up again" +@@ -788,7 +788,7 @@ for port in 0 1; do + del_dev vxlan0 + check_tables + +- echo 1 > $NSIM_DEV_DFS/ports/$port/udp_ports_reset ++ echo 1 > $NSIM_DEV_DFS/ports/$port/udp_ports/reset + check_tables + + msg="destroy NIC" +@@ -895,7 +895,7 @@ msg="vacate VxLAN in overflow table" + exp0=( `mke 10000 1` `mke 10004 1` 0 `mke 10003 1` ) + del_dev vxlan2 + +-echo 1 > $NSIM_DEV_DFS/ports/$port/udp_ports_reset ++echo 1 > $NSIM_DEV_DFS/ports/$port/udp_ports/reset + check_tables + + msg="tunnels destroyed 2" +diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h +index e05ac826104678..878aac3b5ed543 100644 +--- a/tools/testing/selftests/kselftest_harness.h ++++ b/tools/testing/selftests/kselftest_harness.h +@@ -710,33 +710,33 @@ + /* Report with actual signedness to avoid weird output. */ \ + switch (is_signed_type(__exp) * 2 + is_signed_type(__seen)) { \ + case 0: { \ +- unsigned long long __exp_print = (uintptr_t)__exp; \ +- unsigned long long __seen_print = (uintptr_t)__seen; \ +- __TH_LOG("Expected %s (%llu) %s %s (%llu)", \ ++ uintmax_t __exp_print = (uintmax_t)__exp; \ ++ uintmax_t __seen_print = (uintmax_t)__seen; \ ++ __TH_LOG("Expected %s (%ju) %s %s (%ju)", \ + _expected_str, __exp_print, #_t, \ + _seen_str, __seen_print); \ + break; \ + } \ + case 1: { \ +- unsigned long long __exp_print = (uintptr_t)__exp; \ +- long long __seen_print = (intptr_t)__seen; \ +- __TH_LOG("Expected %s (%llu) %s %s (%lld)", \ ++ uintmax_t __exp_print = (uintmax_t)__exp; \ ++ intmax_t __seen_print = (intmax_t)__seen; \ ++ __TH_LOG("Expected %s (%ju) %s %s (%jd)", \ + _expected_str, __exp_print, #_t, \ + _seen_str, __seen_print); \ + break; \ + } \ + case 2: { \ +- long long __exp_print = (intptr_t)__exp; \ +- unsigned long long __seen_print = (uintptr_t)__seen; \ +- __TH_LOG("Expected %s (%lld) %s %s (%llu)", \ ++ intmax_t __exp_print = (intmax_t)__exp; \ ++ uintmax_t __seen_print = (uintmax_t)__seen; \ ++ __TH_LOG("Expected %s (%jd) %s %s (%ju)", \ + _expected_str, __exp_print, #_t, \ + _seen_str, __seen_print); \ + break; \ + } \ + case 3: { \ +- long long __exp_print = (intptr_t)__exp; \ +- long long __seen_print = (intptr_t)__seen; \ +- __TH_LOG("Expected %s (%lld) %s %s (%lld)", \ ++ intmax_t __exp_print = (intmax_t)__exp; \ ++ intmax_t __seen_print = (intmax_t)__seen; \ ++ __TH_LOG("Expected %s (%jd) %s %s (%jd)", \ + _expected_str, __exp_print, #_t, \ + _seen_str, __seen_print); \ + break; \ +diff --git a/tools/testing/selftests/landlock/fs_test.c b/tools/testing/selftests/landlock/fs_test.c +index 720bafa0f87be2..c239838c796a47 100644 +--- a/tools/testing/selftests/landlock/fs_test.c ++++ b/tools/testing/selftests/landlock/fs_test.c +@@ -1861,8 +1861,7 @@ static void test_execute(struct __test_metadata *const _metadata, const int err, + ASSERT_EQ(1, WIFEXITED(status)); + ASSERT_EQ(err ? 2 : 0, WEXITSTATUS(status)) + { +- TH_LOG("Unexpected return code for \"%s\": %s", path, +- strerror(errno)); ++ TH_LOG("Unexpected return code for \"%s\"", path); + }; + } + +diff --git a/tools/testing/selftests/powerpc/benchmarks/gettimeofday.c b/tools/testing/selftests/powerpc/benchmarks/gettimeofday.c +index 580fcac0a09f31..b71ef8a493ed1a 100644 +--- a/tools/testing/selftests/powerpc/benchmarks/gettimeofday.c ++++ b/tools/testing/selftests/powerpc/benchmarks/gettimeofday.c +@@ -20,7 +20,7 @@ static int test_gettimeofday(void) + gettimeofday(&tv_end, NULL); + } + +- timersub(&tv_start, &tv_end, &tv_diff); ++ timersub(&tv_end, &tv_start, &tv_diff); + + printf("time = %.6f\n", tv_diff.tv_sec + (tv_diff.tv_usec) * 1e-6); + +diff --git a/tools/testing/selftests/rseq/rseq.c b/tools/testing/selftests/rseq/rseq.c +index 5b9772cdf2651b..f6156790c3b4df 100644 +--- a/tools/testing/selftests/rseq/rseq.c ++++ b/tools/testing/selftests/rseq/rseq.c +@@ -61,7 +61,6 @@ unsigned int rseq_size = -1U; + unsigned int rseq_flags; + + static int rseq_ownership; +-static int rseq_reg_success; /* At least one rseq registration has succeded. */ + + /* Allocate a large area for the TLS. */ + #define RSEQ_THREAD_AREA_ALLOC_SIZE 1024 +@@ -152,14 +151,27 @@ int rseq_register_current_thread(void) + } + rc = sys_rseq(&__rseq_abi, get_rseq_min_alloc_size(), 0, RSEQ_SIG); + if (rc) { +- if (RSEQ_READ_ONCE(rseq_reg_success)) { ++ /* ++ * After at least one thread has registered successfully ++ * (rseq_size > 0), the registration of other threads should ++ * never fail. ++ */ ++ if (RSEQ_READ_ONCE(rseq_size) > 0) { + /* Incoherent success/failure within process. */ + abort(); + } + return -1; + } + assert(rseq_current_cpu_raw() >= 0); +- RSEQ_WRITE_ONCE(rseq_reg_success, 1); ++ ++ /* ++ * The first thread to register sets the rseq_size to mimic the libc ++ * behavior. ++ */ ++ if (RSEQ_READ_ONCE(rseq_size) == 0) { ++ RSEQ_WRITE_ONCE(rseq_size, get_rseq_kernel_feature_size()); ++ } ++ + return 0; + } + +@@ -235,12 +247,18 @@ void rseq_init(void) + return; + } + rseq_ownership = 1; +- if (!rseq_available()) { +- rseq_size = 0; +- return; +- } ++ ++ /* Calculate the offset of the rseq area from the thread pointer. */ + rseq_offset = (void *)&__rseq_abi - rseq_thread_pointer(); ++ ++ /* rseq flags are deprecated, always set to 0. */ + rseq_flags = 0; ++ ++ /* ++ * Set the size to 0 until at least one thread registers to mimic the ++ * libc behavior. ++ */ ++ rseq_size = 0; + } + + static __attribute__((destructor)) +diff --git a/tools/testing/selftests/rseq/rseq.h b/tools/testing/selftests/rseq/rseq.h +index 4e217b620e0c7a..062d10925a1011 100644 +--- a/tools/testing/selftests/rseq/rseq.h ++++ b/tools/testing/selftests/rseq/rseq.h +@@ -60,7 +60,14 @@ + extern ptrdiff_t rseq_offset; + + /* +- * Size of the registered rseq area. 0 if the registration was ++ * The rseq ABI is composed of extensible feature fields. The extensions ++ * are done by appending additional fields at the end of the structure. ++ * The rseq_size defines the size of the active feature set which can be ++ * used by the application for the current rseq registration. Features ++ * starting at offset >= rseq_size are inactive and should not be used. ++ * ++ * The rseq_size is the intersection between the available allocation ++ * size for the rseq area and the feature size supported by the kernel. + * unsuccessful. + */ + extern unsigned int rseq_size; +diff --git a/tools/testing/selftests/timers/clocksource-switch.c b/tools/testing/selftests/timers/clocksource-switch.c +index c5264594064c85..83faa4e354e389 100644 +--- a/tools/testing/selftests/timers/clocksource-switch.c ++++ b/tools/testing/selftests/timers/clocksource-switch.c +@@ -156,8 +156,8 @@ int main(int argc, char **argv) + /* Check everything is sane before we start switching asynchronously */ + if (do_sanity_check) { + for (i = 0; i < count; i++) { +- printf("Validating clocksource %s\n", +- clocksource_list[i]); ++ ksft_print_msg("Validating clocksource %s\n", ++ clocksource_list[i]); + if (change_clocksource(clocksource_list[i])) { + status = -1; + goto out; +@@ -169,7 +169,7 @@ int main(int argc, char **argv) + } + } + +- printf("Running Asynchronous Switching Tests...\n"); ++ ksft_print_msg("Running Asynchronous Switching Tests...\n"); + pid = fork(); + if (!pid) + return run_tests(runtime); diff --git a/patch/kernel/archive/odroidxu4-6.6/patch-6.6.76-77.patch b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.76-77.patch new file mode 100644 index 000000000000..e387e02b31b9 --- /dev/null +++ b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.76-77.patch @@ -0,0 +1,251 @@ +diff --git a/Makefile b/Makefile +index d679a3dd5a582b..1391d545aee9b0 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 6 + PATCHLEVEL = 6 +-SUBLEVEL = 76 ++SUBLEVEL = 77 + EXTRAVERSION = + NAME = Pinguïn Aangedreven + +diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c +index 9cddd78b11d416..ff201753fd1814 100644 +--- a/fs/hostfs/hostfs_kern.c ++++ b/fs/hostfs/hostfs_kern.c +@@ -16,17 +16,11 @@ + #include + #include + #include +-#include +-#include + #include + #include "hostfs.h" + #include + #include + +-struct hostfs_fs_info { +- char *host_root_path; +-}; +- + struct hostfs_inode_info { + int fd; + fmode_t mode; +@@ -94,17 +88,30 @@ __uml_setup("hostfs=", hostfs_args, + static char *__dentry_name(struct dentry *dentry, char *name) + { + char *p = dentry_path_raw(dentry, name, PATH_MAX); +- struct hostfs_fs_info *fsi = dentry->d_sb->s_fs_info; +- char *root = fsi->host_root_path; +- size_t len = strlen(root); ++ char *root; ++ size_t len; ++ ++ root = dentry->d_sb->s_fs_info; ++ len = strlen(root); ++ if (IS_ERR(p)) { ++ __putname(name); ++ return NULL; ++ } + +- if (IS_ERR(p) || len > p - name) { ++ /* ++ * This function relies on the fact that dentry_path_raw() will place ++ * the path name at the end of the provided buffer. ++ */ ++ BUG_ON(p + strlen(p) + 1 != name + PATH_MAX); ++ ++ strscpy(name, root, PATH_MAX); ++ if (len > p - name) { + __putname(name); + return NULL; + } + +- memcpy(name, root, len); +- memmove(name + len, p, name + PATH_MAX - p); ++ if (p > name + len) ++ strcpy(name + len, p); + + return name; + } +@@ -189,10 +196,8 @@ static int hostfs_statfs(struct dentry *dentry, struct kstatfs *sf) + long long f_bavail; + long long f_files; + long long f_ffree; +- struct hostfs_fs_info *fsi; + +- fsi = dentry->d_sb->s_fs_info; +- err = do_statfs(fsi->host_root_path, ++ err = do_statfs(dentry->d_sb->s_fs_info, + &sf->f_bsize, &f_blocks, &f_bfree, &f_bavail, &f_files, + &f_ffree, &sf->f_fsid, sizeof(sf->f_fsid), + &sf->f_namelen); +@@ -240,11 +245,7 @@ static void hostfs_free_inode(struct inode *inode) + + static int hostfs_show_options(struct seq_file *seq, struct dentry *root) + { +- struct hostfs_fs_info *fsi; +- const char *root_path; +- +- fsi = root->d_sb->s_fs_info; +- root_path = fsi->host_root_path; ++ const char *root_path = root->d_sb->s_fs_info; + size_t offset = strlen(root_ino) + 1; + + if (strlen(root_path) > offset) +@@ -923,10 +924,10 @@ static const struct inode_operations hostfs_link_iops = { + .get_link = hostfs_get_link, + }; + +-static int hostfs_fill_super(struct super_block *sb, struct fs_context *fc) ++static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent) + { +- struct hostfs_fs_info *fsi = sb->s_fs_info; + struct inode *root_inode; ++ char *host_root_path, *req_root = d; + int err; + + sb->s_blocksize = 1024; +@@ -939,7 +940,16 @@ static int hostfs_fill_super(struct super_block *sb, struct fs_context *fc) + if (err) + return err; + +- root_inode = hostfs_iget(sb, fsi->host_root_path); ++ /* NULL is printed as '(null)' by printf(): avoid that. */ ++ if (req_root == NULL) ++ req_root = ""; ++ ++ sb->s_fs_info = host_root_path = ++ kasprintf(GFP_KERNEL, "%s/%s", root_ino, req_root); ++ if (host_root_path == NULL) ++ return -ENOMEM; ++ ++ root_inode = hostfs_iget(sb, host_root_path); + if (IS_ERR(root_inode)) + return PTR_ERR(root_inode); + +@@ -947,7 +957,7 @@ static int hostfs_fill_super(struct super_block *sb, struct fs_context *fc) + char *name; + + iput(root_inode); +- name = follow_link(fsi->host_root_path); ++ name = follow_link(host_root_path); + if (IS_ERR(name)) + return PTR_ERR(name); + +@@ -964,92 +974,11 @@ static int hostfs_fill_super(struct super_block *sb, struct fs_context *fc) + return 0; + } + +-enum hostfs_parma { +- Opt_hostfs, +-}; +- +-static const struct fs_parameter_spec hostfs_param_specs[] = { +- fsparam_string_empty("hostfs", Opt_hostfs), +- {} +-}; +- +-static int hostfs_parse_param(struct fs_context *fc, struct fs_parameter *param) +-{ +- struct hostfs_fs_info *fsi = fc->s_fs_info; +- struct fs_parse_result result; +- char *host_root; +- int opt; +- +- opt = fs_parse(fc, hostfs_param_specs, param, &result); +- if (opt < 0) +- return opt; +- +- switch (opt) { +- case Opt_hostfs: +- host_root = param->string; +- if (!*host_root) +- host_root = ""; +- fsi->host_root_path = +- kasprintf(GFP_KERNEL, "%s/%s", root_ino, host_root); +- if (fsi->host_root_path == NULL) +- return -ENOMEM; +- break; +- } +- +- return 0; +-} +- +-static int hostfs_parse_monolithic(struct fs_context *fc, void *data) +-{ +- struct hostfs_fs_info *fsi = fc->s_fs_info; +- char *host_root = (char *)data; +- +- /* NULL is printed as '(null)' by printf(): avoid that. */ +- if (host_root == NULL) +- host_root = ""; +- +- fsi->host_root_path = +- kasprintf(GFP_KERNEL, "%s/%s", root_ino, host_root); +- if (fsi->host_root_path == NULL) +- return -ENOMEM; +- +- return 0; +-} +- +-static int hostfs_fc_get_tree(struct fs_context *fc) +-{ +- return get_tree_nodev(fc, hostfs_fill_super); +-} +- +-static void hostfs_fc_free(struct fs_context *fc) +-{ +- struct hostfs_fs_info *fsi = fc->s_fs_info; +- +- if (!fsi) +- return; +- +- kfree(fsi->host_root_path); +- kfree(fsi); +-} +- +-static const struct fs_context_operations hostfs_context_ops = { +- .parse_monolithic = hostfs_parse_monolithic, +- .parse_param = hostfs_parse_param, +- .get_tree = hostfs_fc_get_tree, +- .free = hostfs_fc_free, +-}; +- +-static int hostfs_init_fs_context(struct fs_context *fc) ++static struct dentry *hostfs_read_sb(struct file_system_type *type, ++ int flags, const char *dev_name, ++ void *data) + { +- struct hostfs_fs_info *fsi; +- +- fsi = kzalloc(sizeof(*fsi), GFP_KERNEL); +- if (!fsi) +- return -ENOMEM; +- +- fc->s_fs_info = fsi; +- fc->ops = &hostfs_context_ops; +- return 0; ++ return mount_nodev(type, flags, data, hostfs_fill_sb_common); + } + + static void hostfs_kill_sb(struct super_block *s) +@@ -1059,11 +988,11 @@ static void hostfs_kill_sb(struct super_block *s) + } + + static struct file_system_type hostfs_type = { +- .owner = THIS_MODULE, +- .name = "hostfs", +- .init_fs_context = hostfs_init_fs_context, +- .kill_sb = hostfs_kill_sb, +- .fs_flags = 0, ++ .owner = THIS_MODULE, ++ .name = "hostfs", ++ .mount = hostfs_read_sb, ++ .kill_sb = hostfs_kill_sb, ++ .fs_flags = 0, + }; + MODULE_ALIAS_FS("hostfs"); + diff --git a/patch/kernel/archive/odroidxu4-6.6/patch-6.6.77-78.patch b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.77-78.patch new file mode 100644 index 000000000000..812e381c8ba4 --- /dev/null +++ b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.77-78.patch @@ -0,0 +1,9040 @@ +diff --git a/Makefile b/Makefile +index 1391d545aee9b0..1d777c3eb7fb97 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 6 + PATCHLEVEL = 6 +-SUBLEVEL = 77 ++SUBLEVEL = 78 + EXTRAVERSION = + NAME = Pinguïn Aangedreven + +diff --git a/arch/arm/boot/dts/ti/omap/dra7-l4.dtsi b/arch/arm/boot/dts/ti/omap/dra7-l4.dtsi +index 5733e3a4ea8e71..3fdb79b0e8bfe7 100644 +--- a/arch/arm/boot/dts/ti/omap/dra7-l4.dtsi ++++ b/arch/arm/boot/dts/ti/omap/dra7-l4.dtsi +@@ -12,6 +12,7 @@ &l4_cfg { /* 0x4a000000 */ + ranges = <0x00000000 0x4a000000 0x100000>, /* segment 0 */ + <0x00100000 0x4a100000 0x100000>, /* segment 1 */ + <0x00200000 0x4a200000 0x100000>; /* segment 2 */ ++ dma-ranges; + + segment@0 { /* 0x4a000000 */ + compatible = "simple-pm-bus"; +@@ -557,6 +558,7 @@ segment@100000 { /* 0x4a100000 */ + <0x0007e000 0x0017e000 0x001000>, /* ap 124 */ + <0x00059000 0x00159000 0x001000>, /* ap 125 */ + <0x0005a000 0x0015a000 0x001000>; /* ap 126 */ ++ dma-ranges; + + target-module@2000 { /* 0x4a102000, ap 27 3c.0 */ + compatible = "ti,sysc"; +diff --git a/arch/arm/boot/dts/ti/omap/omap3-gta04.dtsi b/arch/arm/boot/dts/ti/omap/omap3-gta04.dtsi +index b6b27e93857f56..bf770c7026d79b 100644 +--- a/arch/arm/boot/dts/ti/omap/omap3-gta04.dtsi ++++ b/arch/arm/boot/dts/ti/omap/omap3-gta04.dtsi +@@ -446,6 +446,7 @@ &omap3_pmx_core2 { + pinctrl-names = "default"; + pinctrl-0 = < + &hsusb2_2_pins ++ &mcspi3hog_pins + >; + + hsusb2_2_pins: hsusb2-2-pins { +@@ -459,6 +460,15 @@ OMAP3630_CORE2_IOPAD(0x25fa, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d15.hsusb2_d + >; + }; + ++ mcspi3hog_pins: mcspi3hog-pins { ++ pinctrl-single,pins = < ++ OMAP3630_CORE2_IOPAD(0x25dc, PIN_OUTPUT_PULLDOWN | MUX_MODE4) /* etk_d0 */ ++ OMAP3630_CORE2_IOPAD(0x25de, PIN_OUTPUT_PULLDOWN | MUX_MODE4) /* etk_d1 */ ++ OMAP3630_CORE2_IOPAD(0x25e0, PIN_OUTPUT_PULLDOWN | MUX_MODE4) /* etk_d2 */ ++ OMAP3630_CORE2_IOPAD(0x25e2, PIN_OUTPUT_PULLDOWN | MUX_MODE4) /* etk_d3 */ ++ >; ++ }; ++ + spi_gpio_pins: spi-gpio-pinmux-pins { + pinctrl-single,pins = < + OMAP3630_CORE2_IOPAD(0x25d8, PIN_OUTPUT | MUX_MODE4) /* clk */ +diff --git a/arch/arm64/boot/dts/nvidia/tegra234.dtsi b/arch/arm64/boot/dts/nvidia/tegra234.dtsi +index be30072fb7471f..bcc36055ef97e6 100644 +--- a/arch/arm64/boot/dts/nvidia/tegra234.dtsi ++++ b/arch/arm64/boot/dts/nvidia/tegra234.dtsi +@@ -1709,7 +1709,7 @@ sce-fabric@b600000 { + compatible = "nvidia,tegra234-sce-fabric"; + reg = <0x0 0xb600000 0x0 0x40000>; + interrupts = ; +- status = "okay"; ++ status = "disabled"; + }; + + rce-fabric@be00000 { +@@ -1889,7 +1889,7 @@ bpmp-fabric@d600000 { + }; + + dce-fabric@de00000 { +- compatible = "nvidia,tegra234-sce-fabric"; ++ compatible = "nvidia,tegra234-dce-fabric"; + reg = <0x0 0xde00000 0x0 0x40000>; + interrupts = ; + status = "okay"; +@@ -1912,6 +1912,8 @@ gic: interrupt-controller@f400000 { + #redistributor-regions = <1>; + #interrupt-cells = <3>; + interrupt-controller; ++ ++ #address-cells = <0>; + }; + + smmu_iso: iommu@10000000 { +diff --git a/arch/arm64/boot/dts/qcom/sm6115.dtsi b/arch/arm64/boot/dts/qcom/sm6115.dtsi +index 821db9b8518557..5c6fcf725473c1 100644 +--- a/arch/arm64/boot/dts/qcom/sm6115.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm6115.dtsi +@@ -1667,7 +1667,7 @@ dispcc: clock-controller@5f00000 { + + remoteproc_mpss: remoteproc@6080000 { + compatible = "qcom,sm6115-mpss-pas"; +- reg = <0x0 0x06080000 0x0 0x100>; ++ reg = <0x0 0x06080000 0x0 0x10000>; + + interrupts-extended = <&intc GIC_SPI 307 IRQ_TYPE_EDGE_RISING>, + <&modem_smp2p_in 0 IRQ_TYPE_EDGE_RISING>, +@@ -2310,9 +2310,9 @@ funnel_apss1_in: endpoint { + }; + }; + +- remoteproc_adsp: remoteproc@ab00000 { ++ remoteproc_adsp: remoteproc@a400000 { + compatible = "qcom,sm6115-adsp-pas"; +- reg = <0x0 0x0ab00000 0x0 0x100>; ++ reg = <0x0 0x0a400000 0x0 0x4040>; + + interrupts-extended = <&intc GIC_SPI 282 IRQ_TYPE_EDGE_RISING>, + <&adsp_smp2p_in 0 IRQ_TYPE_EDGE_RISING>, +@@ -2384,7 +2384,7 @@ compute-cb@7 { + + remoteproc_cdsp: remoteproc@b300000 { + compatible = "qcom,sm6115-cdsp-pas"; +- reg = <0x0 0x0b300000 0x0 0x100000>; ++ reg = <0x0 0x0b300000 0x0 0x4040>; + + interrupts-extended = <&intc GIC_SPI 265 IRQ_TYPE_EDGE_RISING>, + <&cdsp_smp2p_in 0 IRQ_TYPE_EDGE_RISING>, +diff --git a/arch/arm64/boot/dts/qcom/sm6350.dtsi b/arch/arm64/boot/dts/qcom/sm6350.dtsi +index f271b69485c5ce..f9739841406901 100644 +--- a/arch/arm64/boot/dts/qcom/sm6350.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm6350.dtsi +@@ -935,7 +935,7 @@ uart1: serial@884000 { + power-domains = <&rpmhpd SM6350_CX>; + operating-points-v2 = <&qup_opp_table>; + interconnects = <&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>, +- <&aggre1_noc MASTER_QUP_0 0 &clk_virt SLAVE_EBI_CH0 0>; ++ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_0 0>; + interconnect-names = "qup-core", "qup-config"; + status = "disabled"; + }; +@@ -1259,7 +1259,7 @@ tcsr_mutex: hwlock@1f40000 { + + adsp: remoteproc@3000000 { + compatible = "qcom,sm6350-adsp-pas"; +- reg = <0 0x03000000 0 0x100>; ++ reg = <0x0 0x03000000 0x0 0x10000>; + + interrupts-extended = <&pdc 6 IRQ_TYPE_LEVEL_HIGH>, + <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>, +@@ -1480,7 +1480,7 @@ gpucc: clock-controller@3d90000 { + + mpss: remoteproc@4080000 { + compatible = "qcom,sm6350-mpss-pas"; +- reg = <0x0 0x04080000 0x0 0x4040>; ++ reg = <0x0 0x04080000 0x0 0x10000>; + + interrupts-extended = <&intc GIC_SPI 136 IRQ_TYPE_EDGE_RISING>, + <&modem_smp2p_in 0 IRQ_TYPE_EDGE_RISING>, +diff --git a/arch/arm64/boot/dts/qcom/sm6375.dtsi b/arch/arm64/boot/dts/qcom/sm6375.dtsi +index c5f7715626a09b..3903df8336e35d 100644 +--- a/arch/arm64/boot/dts/qcom/sm6375.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm6375.dtsi +@@ -1471,9 +1471,9 @@ gpucc: clock-controller@5990000 { + #power-domain-cells = <1>; + }; + +- remoteproc_mss: remoteproc@6000000 { ++ remoteproc_mss: remoteproc@6080000 { + compatible = "qcom,sm6375-mpss-pas"; +- reg = <0 0x06000000 0 0x4040>; ++ reg = <0x0 0x06080000 0x0 0x10000>; + + interrupts-extended = <&intc GIC_SPI 307 IRQ_TYPE_EDGE_RISING>, + <&smp2p_modem_in 0 IRQ_TYPE_EDGE_RISING>, +@@ -1514,7 +1514,7 @@ IPCC_MPROC_SIGNAL_GLINK_QMP + + remoteproc_adsp: remoteproc@a400000 { + compatible = "qcom,sm6375-adsp-pas"; +- reg = <0 0x0a400000 0 0x100>; ++ reg = <0 0x0a400000 0 0x10000>; + + interrupts-extended = <&intc GIC_SPI 282 IRQ_TYPE_LEVEL_HIGH>, + <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>, +@@ -1550,9 +1550,9 @@ IPCC_MPROC_SIGNAL_GLINK_QMP + }; + }; + +- remoteproc_cdsp: remoteproc@b000000 { ++ remoteproc_cdsp: remoteproc@b300000 { + compatible = "qcom,sm6375-cdsp-pas"; +- reg = <0x0 0x0b000000 0x0 0x100000>; ++ reg = <0x0 0x0b300000 0x0 0x10000>; + + interrupts-extended = <&intc GIC_SPI 265 IRQ_TYPE_EDGE_RISING>, + <&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>, +diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi +index dded95fa52f075..2a4d950ac02bfe 100644 +--- a/arch/arm64/boot/dts/qcom/sm8350.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi +@@ -1819,6 +1819,142 @@ tcsr_mutex: hwlock@1f40000 { + #hwlock-cells = <1>; + }; + ++ adsp: remoteproc@3000000 { ++ compatible = "qcom,sm8350-adsp-pas"; ++ reg = <0x0 0x03000000 0x0 0x10000>; ++ ++ interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>, ++ <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>, ++ <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>, ++ <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>, ++ <&smp2p_adsp_in 3 IRQ_TYPE_EDGE_RISING>; ++ interrupt-names = "wdog", "fatal", "ready", ++ "handover", "stop-ack"; ++ ++ clocks = <&rpmhcc RPMH_CXO_CLK>; ++ clock-names = "xo"; ++ ++ power-domains = <&rpmhpd RPMHPD_LCX>, ++ <&rpmhpd RPMHPD_LMX>; ++ power-domain-names = "lcx", "lmx"; ++ ++ memory-region = <&pil_adsp_mem>; ++ ++ qcom,qmp = <&aoss_qmp>; ++ ++ qcom,smem-states = <&smp2p_adsp_out 0>; ++ qcom,smem-state-names = "stop"; ++ ++ status = "disabled"; ++ ++ glink-edge { ++ interrupts-extended = <&ipcc IPCC_CLIENT_LPASS ++ IPCC_MPROC_SIGNAL_GLINK_QMP ++ IRQ_TYPE_EDGE_RISING>; ++ mboxes = <&ipcc IPCC_CLIENT_LPASS ++ IPCC_MPROC_SIGNAL_GLINK_QMP>; ++ ++ label = "lpass"; ++ qcom,remote-pid = <2>; ++ ++ apr { ++ compatible = "qcom,apr-v2"; ++ qcom,glink-channels = "apr_audio_svc"; ++ qcom,domain = ; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ service@3 { ++ reg = ; ++ compatible = "qcom,q6core"; ++ qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd"; ++ }; ++ ++ q6afe: service@4 { ++ compatible = "qcom,q6afe"; ++ reg = ; ++ qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd"; ++ ++ q6afedai: dais { ++ compatible = "qcom,q6afe-dais"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #sound-dai-cells = <1>; ++ }; ++ ++ q6afecc: clock-controller { ++ compatible = "qcom,q6afe-clocks"; ++ #clock-cells = <2>; ++ }; ++ }; ++ ++ q6asm: service@7 { ++ compatible = "qcom,q6asm"; ++ reg = ; ++ qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd"; ++ ++ q6asmdai: dais { ++ compatible = "qcom,q6asm-dais"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #sound-dai-cells = <1>; ++ iommus = <&apps_smmu 0x1801 0x0>; ++ ++ dai@0 { ++ reg = <0>; ++ }; ++ ++ dai@1 { ++ reg = <1>; ++ }; ++ ++ dai@2 { ++ reg = <2>; ++ }; ++ }; ++ }; ++ ++ q6adm: service@8 { ++ compatible = "qcom,q6adm"; ++ reg = ; ++ qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd"; ++ ++ q6routing: routing { ++ compatible = "qcom,q6adm-routing"; ++ #sound-dai-cells = <0>; ++ }; ++ }; ++ }; ++ ++ fastrpc { ++ compatible = "qcom,fastrpc"; ++ qcom,glink-channels = "fastrpcglink-apps-dsp"; ++ label = "adsp"; ++ qcom,non-secure-domain; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ compute-cb@3 { ++ compatible = "qcom,fastrpc-compute-cb"; ++ reg = <3>; ++ iommus = <&apps_smmu 0x1803 0x0>; ++ }; ++ ++ compute-cb@4 { ++ compatible = "qcom,fastrpc-compute-cb"; ++ reg = <4>; ++ iommus = <&apps_smmu 0x1804 0x0>; ++ }; ++ ++ compute-cb@5 { ++ compatible = "qcom,fastrpc-compute-cb"; ++ reg = <5>; ++ iommus = <&apps_smmu 0x1805 0x0>; ++ }; ++ }; ++ }; ++ }; ++ + lpass_tlmm: pinctrl@33c0000 { + compatible = "qcom,sm8350-lpass-lpi-pinctrl"; + reg = <0 0x033c0000 0 0x20000>, +@@ -2020,7 +2156,7 @@ lpass_ag_noc: interconnect@3c40000 { + + mpss: remoteproc@4080000 { + compatible = "qcom,sm8350-mpss-pas"; +- reg = <0x0 0x04080000 0x0 0x4040>; ++ reg = <0x0 0x04080000 0x0 0x10000>; + + interrupts-extended = <&intc GIC_SPI 264 IRQ_TYPE_EDGE_RISING>, + <&smp2p_modem_in 0 IRQ_TYPE_EDGE_RISING>, +@@ -2299,6 +2435,115 @@ compute_noc: interconnect@a0c0000 { + qcom,bcm-voters = <&apps_bcm_voter>; + }; + ++ cdsp: remoteproc@a300000 { ++ compatible = "qcom,sm8350-cdsp-pas"; ++ reg = <0x0 0x0a300000 0x0 0x10000>; ++ ++ interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>, ++ <&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>, ++ <&smp2p_cdsp_in 1 IRQ_TYPE_EDGE_RISING>, ++ <&smp2p_cdsp_in 2 IRQ_TYPE_EDGE_RISING>, ++ <&smp2p_cdsp_in 3 IRQ_TYPE_EDGE_RISING>; ++ interrupt-names = "wdog", "fatal", "ready", ++ "handover", "stop-ack"; ++ ++ clocks = <&rpmhcc RPMH_CXO_CLK>; ++ clock-names = "xo"; ++ ++ power-domains = <&rpmhpd RPMHPD_CX>, ++ <&rpmhpd RPMHPD_MXC>; ++ power-domain-names = "cx", "mxc"; ++ ++ interconnects = <&compute_noc MASTER_CDSP_PROC 0 &mc_virt SLAVE_EBI1 0>; ++ ++ memory-region = <&pil_cdsp_mem>; ++ ++ qcom,qmp = <&aoss_qmp>; ++ ++ qcom,smem-states = <&smp2p_cdsp_out 0>; ++ qcom,smem-state-names = "stop"; ++ ++ status = "disabled"; ++ ++ glink-edge { ++ interrupts-extended = <&ipcc IPCC_CLIENT_CDSP ++ IPCC_MPROC_SIGNAL_GLINK_QMP ++ IRQ_TYPE_EDGE_RISING>; ++ mboxes = <&ipcc IPCC_CLIENT_CDSP ++ IPCC_MPROC_SIGNAL_GLINK_QMP>; ++ ++ label = "cdsp"; ++ qcom,remote-pid = <5>; ++ ++ fastrpc { ++ compatible = "qcom,fastrpc"; ++ qcom,glink-channels = "fastrpcglink-apps-dsp"; ++ label = "cdsp"; ++ qcom,non-secure-domain; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ compute-cb@1 { ++ compatible = "qcom,fastrpc-compute-cb"; ++ reg = <1>; ++ iommus = <&apps_smmu 0x2161 0x0400>, ++ <&apps_smmu 0x1181 0x0420>; ++ }; ++ ++ compute-cb@2 { ++ compatible = "qcom,fastrpc-compute-cb"; ++ reg = <2>; ++ iommus = <&apps_smmu 0x2162 0x0400>, ++ <&apps_smmu 0x1182 0x0420>; ++ }; ++ ++ compute-cb@3 { ++ compatible = "qcom,fastrpc-compute-cb"; ++ reg = <3>; ++ iommus = <&apps_smmu 0x2163 0x0400>, ++ <&apps_smmu 0x1183 0x0420>; ++ }; ++ ++ compute-cb@4 { ++ compatible = "qcom,fastrpc-compute-cb"; ++ reg = <4>; ++ iommus = <&apps_smmu 0x2164 0x0400>, ++ <&apps_smmu 0x1184 0x0420>; ++ }; ++ ++ compute-cb@5 { ++ compatible = "qcom,fastrpc-compute-cb"; ++ reg = <5>; ++ iommus = <&apps_smmu 0x2165 0x0400>, ++ <&apps_smmu 0x1185 0x0420>; ++ }; ++ ++ compute-cb@6 { ++ compatible = "qcom,fastrpc-compute-cb"; ++ reg = <6>; ++ iommus = <&apps_smmu 0x2166 0x0400>, ++ <&apps_smmu 0x1186 0x0420>; ++ }; ++ ++ compute-cb@7 { ++ compatible = "qcom,fastrpc-compute-cb"; ++ reg = <7>; ++ iommus = <&apps_smmu 0x2167 0x0400>, ++ <&apps_smmu 0x1187 0x0420>; ++ }; ++ ++ compute-cb@8 { ++ compatible = "qcom,fastrpc-compute-cb"; ++ reg = <8>; ++ iommus = <&apps_smmu 0x2168 0x0400>, ++ <&apps_smmu 0x1188 0x0420>; ++ }; ++ ++ /* note: secure cb9 in downstream */ ++ }; ++ }; ++ }; ++ + usb_1: usb@a6f8800 { + compatible = "qcom,sm8350-dwc3", "qcom,dwc3"; + reg = <0 0x0a6f8800 0 0x400>; +@@ -3204,142 +3449,6 @@ apps_smmu: iommu@15000000 { + ; + }; + +- adsp: remoteproc@17300000 { +- compatible = "qcom,sm8350-adsp-pas"; +- reg = <0 0x17300000 0 0x100>; +- +- interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>, +- <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>, +- <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>, +- <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>, +- <&smp2p_adsp_in 3 IRQ_TYPE_EDGE_RISING>; +- interrupt-names = "wdog", "fatal", "ready", +- "handover", "stop-ack"; +- +- clocks = <&rpmhcc RPMH_CXO_CLK>; +- clock-names = "xo"; +- +- power-domains = <&rpmhpd RPMHPD_LCX>, +- <&rpmhpd RPMHPD_LMX>; +- power-domain-names = "lcx", "lmx"; +- +- memory-region = <&pil_adsp_mem>; +- +- qcom,qmp = <&aoss_qmp>; +- +- qcom,smem-states = <&smp2p_adsp_out 0>; +- qcom,smem-state-names = "stop"; +- +- status = "disabled"; +- +- glink-edge { +- interrupts-extended = <&ipcc IPCC_CLIENT_LPASS +- IPCC_MPROC_SIGNAL_GLINK_QMP +- IRQ_TYPE_EDGE_RISING>; +- mboxes = <&ipcc IPCC_CLIENT_LPASS +- IPCC_MPROC_SIGNAL_GLINK_QMP>; +- +- label = "lpass"; +- qcom,remote-pid = <2>; +- +- apr { +- compatible = "qcom,apr-v2"; +- qcom,glink-channels = "apr_audio_svc"; +- qcom,domain = ; +- #address-cells = <1>; +- #size-cells = <0>; +- +- service@3 { +- reg = ; +- compatible = "qcom,q6core"; +- qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd"; +- }; +- +- q6afe: service@4 { +- compatible = "qcom,q6afe"; +- reg = ; +- qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd"; +- +- q6afedai: dais { +- compatible = "qcom,q6afe-dais"; +- #address-cells = <1>; +- #size-cells = <0>; +- #sound-dai-cells = <1>; +- }; +- +- q6afecc: clock-controller { +- compatible = "qcom,q6afe-clocks"; +- #clock-cells = <2>; +- }; +- }; +- +- q6asm: service@7 { +- compatible = "qcom,q6asm"; +- reg = ; +- qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd"; +- +- q6asmdai: dais { +- compatible = "qcom,q6asm-dais"; +- #address-cells = <1>; +- #size-cells = <0>; +- #sound-dai-cells = <1>; +- iommus = <&apps_smmu 0x1801 0x0>; +- +- dai@0 { +- reg = <0>; +- }; +- +- dai@1 { +- reg = <1>; +- }; +- +- dai@2 { +- reg = <2>; +- }; +- }; +- }; +- +- q6adm: service@8 { +- compatible = "qcom,q6adm"; +- reg = ; +- qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd"; +- +- q6routing: routing { +- compatible = "qcom,q6adm-routing"; +- #sound-dai-cells = <0>; +- }; +- }; +- }; +- +- fastrpc { +- compatible = "qcom,fastrpc"; +- qcom,glink-channels = "fastrpcglink-apps-dsp"; +- label = "adsp"; +- qcom,non-secure-domain; +- #address-cells = <1>; +- #size-cells = <0>; +- +- compute-cb@3 { +- compatible = "qcom,fastrpc-compute-cb"; +- reg = <3>; +- iommus = <&apps_smmu 0x1803 0x0>; +- }; +- +- compute-cb@4 { +- compatible = "qcom,fastrpc-compute-cb"; +- reg = <4>; +- iommus = <&apps_smmu 0x1804 0x0>; +- }; +- +- compute-cb@5 { +- compatible = "qcom,fastrpc-compute-cb"; +- reg = <5>; +- iommus = <&apps_smmu 0x1805 0x0>; +- }; +- }; +- }; +- }; +- + intc: interrupt-controller@17a00000 { + compatible = "arm,gic-v3"; + #interrupt-cells = <3>; +@@ -3508,115 +3617,6 @@ cpufreq_hw: cpufreq@18591000 { + #freq-domain-cells = <1>; + #clock-cells = <1>; + }; +- +- cdsp: remoteproc@98900000 { +- compatible = "qcom,sm8350-cdsp-pas"; +- reg = <0 0x98900000 0 0x1400000>; +- +- interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>, +- <&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>, +- <&smp2p_cdsp_in 1 IRQ_TYPE_EDGE_RISING>, +- <&smp2p_cdsp_in 2 IRQ_TYPE_EDGE_RISING>, +- <&smp2p_cdsp_in 3 IRQ_TYPE_EDGE_RISING>; +- interrupt-names = "wdog", "fatal", "ready", +- "handover", "stop-ack"; +- +- clocks = <&rpmhcc RPMH_CXO_CLK>; +- clock-names = "xo"; +- +- power-domains = <&rpmhpd RPMHPD_CX>, +- <&rpmhpd RPMHPD_MXC>; +- power-domain-names = "cx", "mxc"; +- +- interconnects = <&compute_noc MASTER_CDSP_PROC 0 &mc_virt SLAVE_EBI1 0>; +- +- memory-region = <&pil_cdsp_mem>; +- +- qcom,qmp = <&aoss_qmp>; +- +- qcom,smem-states = <&smp2p_cdsp_out 0>; +- qcom,smem-state-names = "stop"; +- +- status = "disabled"; +- +- glink-edge { +- interrupts-extended = <&ipcc IPCC_CLIENT_CDSP +- IPCC_MPROC_SIGNAL_GLINK_QMP +- IRQ_TYPE_EDGE_RISING>; +- mboxes = <&ipcc IPCC_CLIENT_CDSP +- IPCC_MPROC_SIGNAL_GLINK_QMP>; +- +- label = "cdsp"; +- qcom,remote-pid = <5>; +- +- fastrpc { +- compatible = "qcom,fastrpc"; +- qcom,glink-channels = "fastrpcglink-apps-dsp"; +- label = "cdsp"; +- qcom,non-secure-domain; +- #address-cells = <1>; +- #size-cells = <0>; +- +- compute-cb@1 { +- compatible = "qcom,fastrpc-compute-cb"; +- reg = <1>; +- iommus = <&apps_smmu 0x2161 0x0400>, +- <&apps_smmu 0x1181 0x0420>; +- }; +- +- compute-cb@2 { +- compatible = "qcom,fastrpc-compute-cb"; +- reg = <2>; +- iommus = <&apps_smmu 0x2162 0x0400>, +- <&apps_smmu 0x1182 0x0420>; +- }; +- +- compute-cb@3 { +- compatible = "qcom,fastrpc-compute-cb"; +- reg = <3>; +- iommus = <&apps_smmu 0x2163 0x0400>, +- <&apps_smmu 0x1183 0x0420>; +- }; +- +- compute-cb@4 { +- compatible = "qcom,fastrpc-compute-cb"; +- reg = <4>; +- iommus = <&apps_smmu 0x2164 0x0400>, +- <&apps_smmu 0x1184 0x0420>; +- }; +- +- compute-cb@5 { +- compatible = "qcom,fastrpc-compute-cb"; +- reg = <5>; +- iommus = <&apps_smmu 0x2165 0x0400>, +- <&apps_smmu 0x1185 0x0420>; +- }; +- +- compute-cb@6 { +- compatible = "qcom,fastrpc-compute-cb"; +- reg = <6>; +- iommus = <&apps_smmu 0x2166 0x0400>, +- <&apps_smmu 0x1186 0x0420>; +- }; +- +- compute-cb@7 { +- compatible = "qcom,fastrpc-compute-cb"; +- reg = <7>; +- iommus = <&apps_smmu 0x2167 0x0400>, +- <&apps_smmu 0x1187 0x0420>; +- }; +- +- compute-cb@8 { +- compatible = "qcom,fastrpc-compute-cb"; +- reg = <8>; +- iommus = <&apps_smmu 0x2168 0x0400>, +- <&apps_smmu 0x1188 0x0420>; +- }; +- +- /* note: secure cb9 in downstream */ +- }; +- }; +- }; + }; + + thermal_zones: thermal-zones { +diff --git a/arch/arm64/boot/dts/qcom/sm8450.dtsi b/arch/arm64/boot/dts/qcom/sm8450.dtsi +index 007689d7f4fa20..2a49a29713752b 100644 +--- a/arch/arm64/boot/dts/qcom/sm8450.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8450.dtsi +@@ -2475,7 +2475,7 @@ compute-cb@5 { + + remoteproc_cdsp: remoteproc@32300000 { + compatible = "qcom,sm8450-cdsp-pas"; +- reg = <0 0x32300000 0 0x1400000>; ++ reg = <0 0x32300000 0 0x10000>; + + interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>, + <&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>, +@@ -2581,7 +2581,7 @@ compute-cb@8 { + + remoteproc_mpss: remoteproc@4080000 { + compatible = "qcom,sm8450-mpss-pas"; +- reg = <0x0 0x04080000 0x0 0x4040>; ++ reg = <0x0 0x04080000 0x0 0x10000>; + + interrupts-extended = <&intc GIC_SPI 264 IRQ_TYPE_EDGE_RISING>, + <&smp2p_modem_in 0 IRQ_TYPE_EDGE_RISING>, +diff --git a/arch/arm64/boot/dts/qcom/sm8550.dtsi b/arch/arm64/boot/dts/qcom/sm8550.dtsi +index 90e6cd239f5699..f3a0e1fe333c4d 100644 +--- a/arch/arm64/boot/dts/qcom/sm8550.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8550.dtsi +@@ -1986,7 +1986,7 @@ gpucc: clock-controller@3d90000 { + + remoteproc_mpss: remoteproc@4080000 { + compatible = "qcom,sm8550-mpss-pas"; +- reg = <0x0 0x04080000 0x0 0x4040>; ++ reg = <0x0 0x04080000 0x0 0x10000>; + + interrupts-extended = <&intc GIC_SPI 264 IRQ_TYPE_EDGE_RISING>, + <&smp2p_modem_in 0 IRQ_TYPE_EDGE_RISING>, +@@ -2448,9 +2448,8 @@ mdss: display-subsystem@ae00000 { + + power-domains = <&dispcc MDSS_GDSC>; + +- interconnects = <&mmss_noc MASTER_MDP 0 &gem_noc SLAVE_LLCC 0>, +- <&mc_virt MASTER_LLCC 0 &mc_virt SLAVE_EBI1 0>; +- interconnect-names = "mdp0-mem", "mdp1-mem"; ++ interconnects = <&mmss_noc MASTER_MDP 0 &mc_virt SLAVE_EBI1 0>; ++ interconnect-names = "mdp0-mem"; + + iommus = <&apps_smmu 0x1c00 0x2>; + +@@ -4089,7 +4088,7 @@ nsp_noc: interconnect@320c0000 { + + remoteproc_cdsp: remoteproc@32300000 { + compatible = "qcom,sm8550-cdsp-pas"; +- reg = <0x0 0x32300000 0x0 0x1400000>; ++ reg = <0x0 0x32300000 0x0 0x10000>; + + interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>, + <&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>, +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi +index aba2748fe54c77..35a0fb73a96a5d 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi +@@ -147,7 +147,7 @@ &gmac { + snps,reset-active-low; + snps,reset-delays-us = <0 10000 50000>; + tx_delay = <0x10>; +- rx_delay = <0x10>; ++ rx_delay = <0x23>; + status = "okay"; + }; + +diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c +index d221829502f3e0..a795dad2b99ab1 100644 +--- a/arch/arm64/kvm/arch_timer.c ++++ b/arch/arm64/kvm/arch_timer.c +@@ -467,10 +467,8 @@ static void timer_emulate(struct arch_timer_context *ctx) + + trace_kvm_timer_emulate(ctx, should_fire); + +- if (should_fire != ctx->irq.level) { ++ if (should_fire != ctx->irq.level) + kvm_timer_update_irq(ctx->vcpu, should_fire, ctx); +- return; +- } + + /* + * If the timer can fire now, we don't need to have a soft timer +diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c +index 13fd592228b188..a5e1588780b2ce 100644 +--- a/arch/arm64/mm/hugetlbpage.c ++++ b/arch/arm64/mm/hugetlbpage.c +@@ -526,6 +526,18 @@ pte_t huge_ptep_clear_flush(struct vm_area_struct *vma, + + static int __init hugetlbpage_init(void) + { ++ /* ++ * HugeTLB pages are supported on maximum four page table ++ * levels (PUD, CONT PMD, PMD, CONT PTE) for a given base ++ * page size, corresponding to hugetlb_add_hstate() calls ++ * here. ++ * ++ * HUGE_MAX_HSTATE should at least match maximum supported ++ * HugeTLB page sizes on the platform. Any new addition to ++ * supported HugeTLB page sizes will also require changing ++ * HUGE_MAX_HSTATE as well. ++ */ ++ BUILD_BUG_ON(HUGE_MAX_HSTATE < 4); + if (pud_sect_supported()) + hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT); + +diff --git a/arch/loongarch/include/uapi/asm/ptrace.h b/arch/loongarch/include/uapi/asm/ptrace.h +index ac915f84165053..aafb3cd9e943e5 100644 +--- a/arch/loongarch/include/uapi/asm/ptrace.h ++++ b/arch/loongarch/include/uapi/asm/ptrace.h +@@ -72,6 +72,16 @@ struct user_watch_state { + } dbg_regs[8]; + }; + ++struct user_watch_state_v2 { ++ uint64_t dbg_info; ++ struct { ++ uint64_t addr; ++ uint64_t mask; ++ uint32_t ctrl; ++ uint32_t pad; ++ } dbg_regs[14]; ++}; ++ + #define PTRACE_SYSEMU 0x1f + #define PTRACE_SYSEMU_SINGLESTEP 0x20 + +diff --git a/arch/loongarch/kernel/ptrace.c b/arch/loongarch/kernel/ptrace.c +index 19dc6eff45ccc8..5e2402cfcab0a1 100644 +--- a/arch/loongarch/kernel/ptrace.c ++++ b/arch/loongarch/kernel/ptrace.c +@@ -720,7 +720,7 @@ static int hw_break_set(struct task_struct *target, + unsigned int note_type = regset->core_note_type; + + /* Resource info */ +- offset = offsetof(struct user_watch_state, dbg_regs); ++ offset = offsetof(struct user_watch_state_v2, dbg_regs); + user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, 0, offset); + + /* (address, mask, ctrl) registers */ +@@ -920,7 +920,7 @@ static const struct user_regset loongarch64_regsets[] = { + #ifdef CONFIG_HAVE_HW_BREAKPOINT + [REGSET_HW_BREAK] = { + .core_note_type = NT_LOONGARCH_HW_BREAK, +- .n = sizeof(struct user_watch_state) / sizeof(u32), ++ .n = sizeof(struct user_watch_state_v2) / sizeof(u32), + .size = sizeof(u32), + .align = sizeof(u32), + .regset_get = hw_break_get, +@@ -928,7 +928,7 @@ static const struct user_regset loongarch64_regsets[] = { + }, + [REGSET_HW_WATCH] = { + .core_note_type = NT_LOONGARCH_HW_WATCH, +- .n = sizeof(struct user_watch_state) / sizeof(u32), ++ .n = sizeof(struct user_watch_state_v2) / sizeof(u32), + .size = sizeof(u32), + .align = sizeof(u32), + .regset_get = hw_break_get, +diff --git a/arch/m68k/include/asm/vga.h b/arch/m68k/include/asm/vga.h +index 4742e6bc3ab8ea..cdd414fa8710a9 100644 +--- a/arch/m68k/include/asm/vga.h ++++ b/arch/m68k/include/asm/vga.h +@@ -9,7 +9,7 @@ + */ + #ifndef CONFIG_PCI + +-#include ++#include + #include + + /* +@@ -29,9 +29,9 @@ + #define inw_p(port) 0 + #define outb_p(port, val) do { } while (0) + #define outw(port, val) do { } while (0) +-#define readb raw_inb +-#define writeb raw_outb +-#define writew raw_outw ++#define readb __raw_readb ++#define writeb __raw_writeb ++#define writew __raw_writew + + #endif /* CONFIG_PCI */ + #endif /* _ASM_M68K_VGA_H */ +diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c +index 8c401e42301cbf..f39e85fd58fa99 100644 +--- a/arch/mips/kernel/ftrace.c ++++ b/arch/mips/kernel/ftrace.c +@@ -248,7 +248,7 @@ int ftrace_disable_ftrace_graph_caller(void) + #define S_R_SP (0xafb0 << 16) /* s{d,w} R, offset(sp) */ + #define OFFSET_MASK 0xffff /* stack offset range: 0 ~ PT_SIZE */ + +-unsigned long ftrace_get_parent_ra_addr(unsigned long self_ra, unsigned long ++static unsigned long ftrace_get_parent_ra_addr(unsigned long self_ra, unsigned long + old_parent_ra, unsigned long parent_ra_addr, unsigned long fp) + { + unsigned long sp, ip, tmp; +diff --git a/arch/mips/loongson64/boardinfo.c b/arch/mips/loongson64/boardinfo.c +index 280989c5a137b5..8bb275c93ac099 100644 +--- a/arch/mips/loongson64/boardinfo.c ++++ b/arch/mips/loongson64/boardinfo.c +@@ -21,13 +21,11 @@ static ssize_t boardinfo_show(struct kobject *kobj, + "BIOS Info\n" + "Vendor\t\t\t: %s\n" + "Version\t\t\t: %s\n" +- "ROM Size\t\t: %d KB\n" + "Release Date\t\t: %s\n", + strsep(&tmp_board_manufacturer, "-"), + eboard->name, + strsep(&tmp_bios_vendor, "-"), + einter->description, +- einter->size, + especial->special_name); + } + static struct kobj_attribute boardinfo_attr = __ATTR(boardinfo, 0444, +diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c +index 265bc57819dfb5..c89e70df43d82b 100644 +--- a/arch/mips/math-emu/cp1emu.c ++++ b/arch/mips/math-emu/cp1emu.c +@@ -1660,7 +1660,7 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, + break; + } + +- case 0x3: ++ case 0x7: + if (MIPSInst_FUNC(ir) != pfetch_op) + return SIGILL; + +diff --git a/arch/powerpc/kvm/e500_mmu_host.c b/arch/powerpc/kvm/e500_mmu_host.c +index ccb8f16ffe412f..bd413dafbaf969 100644 +--- a/arch/powerpc/kvm/e500_mmu_host.c ++++ b/arch/powerpc/kvm/e500_mmu_host.c +@@ -242,7 +242,7 @@ static inline int tlbe_is_writable(struct kvm_book3e_206_tlb_entry *tlbe) + return tlbe->mas7_3 & (MAS3_SW|MAS3_UW); + } + +-static inline void kvmppc_e500_ref_setup(struct tlbe_ref *ref, ++static inline bool kvmppc_e500_ref_setup(struct tlbe_ref *ref, + struct kvm_book3e_206_tlb_entry *gtlbe, + kvm_pfn_t pfn, unsigned int wimg) + { +@@ -252,11 +252,7 @@ static inline void kvmppc_e500_ref_setup(struct tlbe_ref *ref, + /* Use guest supplied MAS2_G and MAS2_E */ + ref->flags |= (gtlbe->mas2 & MAS2_ATTRIB_MASK) | wimg; + +- /* Mark the page accessed */ +- kvm_set_pfn_accessed(pfn); +- +- if (tlbe_is_writable(gtlbe)) +- kvm_set_pfn_dirty(pfn); ++ return tlbe_is_writable(gtlbe); + } + + static inline void kvmppc_e500_ref_release(struct tlbe_ref *ref) +@@ -326,6 +322,7 @@ static inline int kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500, + { + struct kvm_memory_slot *slot; + unsigned long pfn = 0; /* silence GCC warning */ ++ struct page *page = NULL; + unsigned long hva; + int pfnmap = 0; + int tsize = BOOK3E_PAGESZ_4K; +@@ -337,6 +334,7 @@ static inline int kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500, + unsigned int wimg = 0; + pgd_t *pgdir; + unsigned long flags; ++ bool writable = false; + + /* used to check for invalidations in progress */ + mmu_seq = kvm->mmu_invalidate_seq; +@@ -446,7 +444,7 @@ static inline int kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500, + + if (likely(!pfnmap)) { + tsize_pages = 1UL << (tsize + 10 - PAGE_SHIFT); +- pfn = gfn_to_pfn_memslot(slot, gfn); ++ pfn = __kvm_faultin_pfn(slot, gfn, FOLL_WRITE, NULL, &page); + if (is_error_noslot_pfn(pfn)) { + if (printk_ratelimit()) + pr_err("%s: real page not found for gfn %lx\n", +@@ -481,7 +479,6 @@ static inline int kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500, + if (pte_present(pte)) { + wimg = (pte_val(pte) >> PTE_WIMGE_SHIFT) & + MAS2_WIMGE_MASK; +- local_irq_restore(flags); + } else { + local_irq_restore(flags); + pr_err_ratelimited("%s: pte not present: gfn %lx,pfn %lx\n", +@@ -490,8 +487,9 @@ static inline int kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500, + goto out; + } + } +- kvmppc_e500_ref_setup(ref, gtlbe, pfn, wimg); ++ local_irq_restore(flags); + ++ writable = kvmppc_e500_ref_setup(ref, gtlbe, pfn, wimg); + kvmppc_e500_setup_stlbe(&vcpu_e500->vcpu, gtlbe, tsize, + ref, gvaddr, stlbe); + +@@ -499,11 +497,8 @@ static inline int kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500, + kvmppc_mmu_flush_icache(pfn); + + out: ++ kvm_release_faultin_page(kvm, page, !!ret, writable); + spin_unlock(&kvm->mmu_lock); +- +- /* Drop refcount on page, so that mmu notifiers can clear it */ +- kvm_release_pfn_clean(pfn); +- + return ret; + } + +diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c +index def184da51cf0e..3269c814f65479 100644 +--- a/arch/powerpc/platforms/pseries/eeh_pseries.c ++++ b/arch/powerpc/platforms/pseries/eeh_pseries.c +@@ -580,8 +580,10 @@ static int pseries_eeh_get_state(struct eeh_pe *pe, int *delay) + + switch(rets[0]) { + case 0: +- result = EEH_STATE_MMIO_ACTIVE | +- EEH_STATE_DMA_ACTIVE; ++ result = EEH_STATE_MMIO_ACTIVE | ++ EEH_STATE_DMA_ACTIVE | ++ EEH_STATE_MMIO_ENABLED | ++ EEH_STATE_DMA_ENABLED; + break; + case 1: + result = EEH_STATE_RESET_ACTIVE | +diff --git a/arch/s390/include/asm/futex.h b/arch/s390/include/asm/futex.h +index eaeaeb3ff0be3e..752a2310f0d6c1 100644 +--- a/arch/s390/include/asm/futex.h ++++ b/arch/s390/include/asm/futex.h +@@ -44,7 +44,7 @@ static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, + break; + case FUTEX_OP_ANDN: + __futex_atomic_op("lr %2,%1\nnr %2,%5\n", +- ret, oldval, newval, uaddr, oparg); ++ ret, oldval, newval, uaddr, ~oparg); + break; + case FUTEX_OP_XOR: + __futex_atomic_op("lr %2,%1\nxr %2,%5\n", +diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h +index e7338ed540d8fc..2f373e8cfed33e 100644 +--- a/arch/s390/include/asm/processor.h ++++ b/arch/s390/include/asm/processor.h +@@ -140,8 +140,7 @@ static __always_inline void __stackleak_poison(unsigned long erase_low, + " la %[addr],256(%[addr])\n" + " brctg %[tmp],0b\n" + "1: stg %[poison],0(%[addr])\n" +- " larl %[tmp],3f\n" +- " ex %[count],0(%[tmp])\n" ++ " exrl %[count],3f\n" + " j 4f\n" + "2: stg %[poison],0(%[addr])\n" + " j 4f\n" +diff --git a/arch/s390/kvm/vsie.c b/arch/s390/kvm/vsie.c +index db9a180de65f1f..b82620cefa684b 100644 +--- a/arch/s390/kvm/vsie.c ++++ b/arch/s390/kvm/vsie.c +@@ -1335,8 +1335,14 @@ static struct vsie_page *get_vsie_page(struct kvm *kvm, unsigned long addr) + page = radix_tree_lookup(&kvm->arch.vsie.addr_to_page, addr >> 9); + rcu_read_unlock(); + if (page) { +- if (page_ref_inc_return(page) == 2) +- return page_to_virt(page); ++ if (page_ref_inc_return(page) == 2) { ++ if (page->index == addr) ++ return page_to_virt(page); ++ /* ++ * We raced with someone reusing + putting this vsie ++ * page before we grabbed it. ++ */ ++ } + page_ref_dec(page); + } + +@@ -1366,15 +1372,20 @@ static struct vsie_page *get_vsie_page(struct kvm *kvm, unsigned long addr) + kvm->arch.vsie.next++; + kvm->arch.vsie.next %= nr_vcpus; + } +- radix_tree_delete(&kvm->arch.vsie.addr_to_page, page->index >> 9); ++ if (page->index != ULONG_MAX) ++ radix_tree_delete(&kvm->arch.vsie.addr_to_page, ++ page->index >> 9); + } +- page->index = addr; +- /* double use of the same address */ ++ /* Mark it as invalid until it resides in the tree. */ ++ page->index = ULONG_MAX; ++ ++ /* Double use of the same address or allocation failure. */ + if (radix_tree_insert(&kvm->arch.vsie.addr_to_page, addr >> 9, page)) { + page_ref_dec(page); + mutex_unlock(&kvm->arch.vsie.mutex); + return NULL; + } ++ page->index = addr; + mutex_unlock(&kvm->arch.vsie.mutex); + + vsie_page = page_to_virt(page); +@@ -1467,7 +1478,9 @@ void kvm_s390_vsie_destroy(struct kvm *kvm) + vsie_page = page_to_virt(page); + release_gmap_shadow(vsie_page); + /* free the radix tree entry */ +- radix_tree_delete(&kvm->arch.vsie.addr_to_page, page->index >> 9); ++ if (page->index != ULONG_MAX) ++ radix_tree_delete(&kvm->arch.vsie.addr_to_page, ++ page->index >> 9); + __free_page(page); + } + kvm->arch.vsie.page_count = 0; +diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile +index 658e9ec065c476..ba17496fad1b3b 100644 +--- a/arch/x86/boot/compressed/Makefile ++++ b/arch/x86/boot/compressed/Makefile +@@ -34,6 +34,7 @@ targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma \ + # avoid errors with '-march=i386', and future flags may depend on the target to + # be valid. + KBUILD_CFLAGS := -m$(BITS) -O2 $(CLANG_FLAGS) ++KBUILD_CFLAGS += -std=gnu11 + KBUILD_CFLAGS += -fno-strict-aliasing -fPIE + KBUILD_CFLAGS += -Wundef + KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING +diff --git a/arch/x86/include/asm/kexec.h b/arch/x86/include/asm/kexec.h +index c9f6a6c5de3cf6..d54dd7084a3e1c 100644 +--- a/arch/x86/include/asm/kexec.h ++++ b/arch/x86/include/asm/kexec.h +@@ -16,6 +16,7 @@ + # define PAGES_NR 4 + #endif + ++# define KEXEC_CONTROL_PAGE_SIZE 4096 + # define KEXEC_CONTROL_CODE_MAX_SIZE 2048 + + #ifndef __ASSEMBLY__ +@@ -44,7 +45,6 @@ struct kimage; + /* Maximum address we can use for the control code buffer */ + # define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE + +-# define KEXEC_CONTROL_PAGE_SIZE 4096 + + /* The native architecture */ + # define KEXEC_ARCH KEXEC_ARCH_386 +@@ -59,9 +59,6 @@ struct kimage; + /* Maximum address we can use for the control pages */ + # define KEXEC_CONTROL_MEMORY_LIMIT (MAXMEM-1) + +-/* Allocate one page for the pdp and the second for the code */ +-# define KEXEC_CONTROL_PAGE_SIZE (4096UL + 4096UL) +- + /* The native architecture */ + # define KEXEC_ARCH KEXEC_ARCH_X86_64 + #endif +@@ -146,6 +143,19 @@ struct kimage_arch { + }; + #else + struct kimage_arch { ++ /* ++ * This is a kimage control page, as it must not overlap with either ++ * source or destination address ranges. ++ */ ++ pgd_t *pgd; ++ /* ++ * The virtual mapping of the control code page itself is used only ++ * during the transition, while the current kernel's pages are all ++ * in place. Thus the intermediate page table pages used to map it ++ * are not control pages, but instead just normal pages obtained ++ * with get_zeroed_page(). And have to be tracked (below) so that ++ * they can be freed. ++ */ + p4d_t *p4d; + pud_t *pud; + pmd_t *pmd; +diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h +index 257bf2e71d0605..39672561c6be87 100644 +--- a/arch/x86/include/asm/kvm_host.h ++++ b/arch/x86/include/asm/kvm_host.h +@@ -1650,6 +1650,8 @@ struct kvm_x86_ops { + void (*enable_irq_window)(struct kvm_vcpu *vcpu); + void (*update_cr8_intercept)(struct kvm_vcpu *vcpu, int tpr, int irr); + bool (*check_apicv_inhibit_reasons)(enum kvm_apicv_inhibit reason); ++ ++ const bool x2apic_icr_is_split; + const unsigned long required_apicv_inhibits; + bool allow_apicv_in_x2apic_without_x2apic_virtualization; + void (*refresh_apicv_exec_ctrl)(struct kvm_vcpu *vcpu); +diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c +index 6dabb53f58a445..b6d5fc396f88c8 100644 +--- a/arch/x86/kernel/amd_nb.c ++++ b/arch/x86/kernel/amd_nb.c +@@ -537,6 +537,10 @@ static __init void fix_erratum_688(void) + + static __init int init_amd_nbs(void) + { ++ if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD && ++ boot_cpu_data.x86_vendor != X86_VENDOR_HYGON) ++ return 0; ++ + amd_cache_northbridges(); + amd_cache_gart(); + +diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c +index 2fa12d1dc67602..8509d809a9f1bb 100644 +--- a/arch/x86/kernel/machine_kexec_64.c ++++ b/arch/x86/kernel/machine_kexec_64.c +@@ -149,7 +149,8 @@ static void free_transition_pgtable(struct kimage *image) + image->arch.pte = NULL; + } + +-static int init_transition_pgtable(struct kimage *image, pgd_t *pgd) ++static int init_transition_pgtable(struct kimage *image, pgd_t *pgd, ++ unsigned long control_page) + { + pgprot_t prot = PAGE_KERNEL_EXEC_NOENC; + unsigned long vaddr, paddr; +@@ -160,7 +161,7 @@ static int init_transition_pgtable(struct kimage *image, pgd_t *pgd) + pte_t *pte; + + vaddr = (unsigned long)relocate_kernel; +- paddr = __pa(page_address(image->control_code_page)+PAGE_SIZE); ++ paddr = control_page; + pgd += pgd_index(vaddr); + if (!pgd_present(*pgd)) { + p4d = (p4d_t *)get_zeroed_page(GFP_KERNEL); +@@ -219,7 +220,7 @@ static void *alloc_pgt_page(void *data) + return p; + } + +-static int init_pgtable(struct kimage *image, unsigned long start_pgtable) ++static int init_pgtable(struct kimage *image, unsigned long control_page) + { + struct x86_mapping_info info = { + .alloc_pgt_page = alloc_pgt_page, +@@ -228,12 +229,12 @@ static int init_pgtable(struct kimage *image, unsigned long start_pgtable) + .kernpg_flag = _KERNPG_TABLE_NOENC, + }; + unsigned long mstart, mend; +- pgd_t *level4p; + int result; + int i; + +- level4p = (pgd_t *)__va(start_pgtable); +- clear_page(level4p); ++ image->arch.pgd = alloc_pgt_page(image); ++ if (!image->arch.pgd) ++ return -ENOMEM; + + if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT)) { + info.page_flag |= _PAGE_ENC; +@@ -247,8 +248,8 @@ static int init_pgtable(struct kimage *image, unsigned long start_pgtable) + mstart = pfn_mapped[i].start << PAGE_SHIFT; + mend = pfn_mapped[i].end << PAGE_SHIFT; + +- result = kernel_ident_mapping_init(&info, +- level4p, mstart, mend); ++ result = kernel_ident_mapping_init(&info, image->arch.pgd, ++ mstart, mend); + if (result) + return result; + } +@@ -263,8 +264,8 @@ static int init_pgtable(struct kimage *image, unsigned long start_pgtable) + mstart = image->segment[i].mem; + mend = mstart + image->segment[i].memsz; + +- result = kernel_ident_mapping_init(&info, +- level4p, mstart, mend); ++ result = kernel_ident_mapping_init(&info, image->arch.pgd, ++ mstart, mend); + + if (result) + return result; +@@ -274,15 +275,19 @@ static int init_pgtable(struct kimage *image, unsigned long start_pgtable) + * Prepare EFI systab and ACPI tables for kexec kernel since they are + * not covered by pfn_mapped. + */ +- result = map_efi_systab(&info, level4p); ++ result = map_efi_systab(&info, image->arch.pgd); + if (result) + return result; + +- result = map_acpi_tables(&info, level4p); ++ result = map_acpi_tables(&info, image->arch.pgd); + if (result) + return result; + +- return init_transition_pgtable(image, level4p); ++ /* ++ * This must be last because the intermediate page table pages it ++ * allocates will not be control pages and may overlap the image. ++ */ ++ return init_transition_pgtable(image, image->arch.pgd, control_page); + } + + static void load_segments(void) +@@ -299,14 +304,14 @@ static void load_segments(void) + + int machine_kexec_prepare(struct kimage *image) + { +- unsigned long start_pgtable; ++ unsigned long control_page; + int result; + + /* Calculate the offsets */ +- start_pgtable = page_to_pfn(image->control_code_page) << PAGE_SHIFT; ++ control_page = page_to_pfn(image->control_code_page) << PAGE_SHIFT; + + /* Setup the identity mapped 64bit page table */ +- result = init_pgtable(image, start_pgtable); ++ result = init_pgtable(image, control_page); + if (result) + return result; + +@@ -360,13 +365,12 @@ void machine_kexec(struct kimage *image) + #endif + } + +- control_page = page_address(image->control_code_page) + PAGE_SIZE; ++ control_page = page_address(image->control_code_page); + __memcpy(control_page, relocate_kernel, KEXEC_CONTROL_CODE_MAX_SIZE); + + page_list[PA_CONTROL_PAGE] = virt_to_phys(control_page); + page_list[VA_CONTROL_PAGE] = (unsigned long)control_page; +- page_list[PA_TABLE_PAGE] = +- (unsigned long)__pa(page_address(image->control_code_page)); ++ page_list[PA_TABLE_PAGE] = (unsigned long)__pa(image->arch.pgd); + + if (image->type == KEXEC_TYPE_DEFAULT) + page_list[PA_SWAP_PAGE] = (page_to_pfn(image->swap_page) +@@ -574,8 +578,7 @@ static void kexec_mark_crashkres(bool protect) + + /* Don't touch the control code page used in crash_kexec().*/ + control = PFN_PHYS(page_to_pfn(kexec_crash_image->control_code_page)); +- /* Control code page is located in the 2nd page. */ +- kexec_mark_range(crashk_res.start, control + PAGE_SIZE - 1, protect); ++ kexec_mark_range(crashk_res.start, control - 1, protect); + control += KEXEC_CONTROL_PAGE_SIZE; + kexec_mark_range(control, crashk_res.end, protect); + } +diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c +index 34766abbabd84f..66c7f2367bb34e 100644 +--- a/arch/x86/kvm/lapic.c ++++ b/arch/x86/kvm/lapic.c +@@ -338,10 +338,8 @@ static void kvm_recalculate_logical_map(struct kvm_apic_map *new, + * reversing the LDR calculation to get cluster of APICs, i.e. no + * additional work is required. + */ +- if (apic_x2apic_mode(apic)) { +- WARN_ON_ONCE(ldr != kvm_apic_calc_x2apic_ldr(kvm_x2apic_id(apic))); ++ if (apic_x2apic_mode(apic)) + return; +- } + + if (WARN_ON_ONCE(!kvm_apic_map_get_logical_dest(new, ldr, + &cluster, &mask))) { +@@ -2461,11 +2459,25 @@ int kvm_x2apic_icr_write(struct kvm_lapic *apic, u64 data) + data &= ~APIC_ICR_BUSY; + + kvm_apic_send_ipi(apic, (u32)data, (u32)(data >> 32)); +- kvm_lapic_set_reg64(apic, APIC_ICR, data); ++ if (kvm_x86_ops.x2apic_icr_is_split) { ++ kvm_lapic_set_reg(apic, APIC_ICR, data); ++ kvm_lapic_set_reg(apic, APIC_ICR2, data >> 32); ++ } else { ++ kvm_lapic_set_reg64(apic, APIC_ICR, data); ++ } + trace_kvm_apic_write(APIC_ICR, data); + return 0; + } + ++static u64 kvm_x2apic_icr_read(struct kvm_lapic *apic) ++{ ++ if (kvm_x86_ops.x2apic_icr_is_split) ++ return (u64)kvm_lapic_get_reg(apic, APIC_ICR) | ++ (u64)kvm_lapic_get_reg(apic, APIC_ICR2) << 32; ++ ++ return kvm_lapic_get_reg64(apic, APIC_ICR); ++} ++ + /* emulate APIC access in a trap manner */ + void kvm_apic_write_nodecode(struct kvm_vcpu *vcpu, u32 offset) + { +@@ -2483,7 +2495,7 @@ void kvm_apic_write_nodecode(struct kvm_vcpu *vcpu, u32 offset) + * maybe-unecessary write, and both are in the noise anyways. + */ + if (apic_x2apic_mode(apic) && offset == APIC_ICR) +- WARN_ON_ONCE(kvm_x2apic_icr_write(apic, kvm_lapic_get_reg64(apic, APIC_ICR))); ++ WARN_ON_ONCE(kvm_x2apic_icr_write(apic, kvm_x2apic_icr_read(apic))); + else + kvm_lapic_reg_write(apic, offset, kvm_lapic_get_reg(apic, offset)); + } +@@ -2964,34 +2976,48 @@ static int kvm_apic_state_fixup(struct kvm_vcpu *vcpu, + struct kvm_lapic_state *s, bool set) + { + if (apic_x2apic_mode(vcpu->arch.apic)) { ++ u32 x2apic_id = kvm_x2apic_id(vcpu->arch.apic); + u32 *id = (u32 *)(s->regs + APIC_ID); + u32 *ldr = (u32 *)(s->regs + APIC_LDR); + u64 icr; + + if (vcpu->kvm->arch.x2apic_format) { +- if (*id != vcpu->vcpu_id) ++ if (*id != x2apic_id) + return -EINVAL; + } else { ++ /* ++ * Ignore the userspace value when setting APIC state. ++ * KVM's model is that the x2APIC ID is readonly, e.g. ++ * KVM only supports delivering interrupts to KVM's ++ * version of the x2APIC ID. However, for backwards ++ * compatibility, don't reject attempts to set a ++ * mismatched ID for userspace that hasn't opted into ++ * x2apic_format. ++ */ + if (set) +- *id >>= 24; ++ *id = x2apic_id; + else +- *id <<= 24; ++ *id = x2apic_id << 24; + } + + /* + * In x2APIC mode, the LDR is fixed and based on the id. And +- * ICR is internally a single 64-bit register, but needs to be +- * split to ICR+ICR2 in userspace for backwards compatibility. ++ * if the ICR is _not_ split, ICR is internally a single 64-bit ++ * register, but needs to be split to ICR+ICR2 in userspace for ++ * backwards compatibility. + */ +- if (set) { +- *ldr = kvm_apic_calc_x2apic_ldr(*id); +- +- icr = __kvm_lapic_get_reg(s->regs, APIC_ICR) | +- (u64)__kvm_lapic_get_reg(s->regs, APIC_ICR2) << 32; +- __kvm_lapic_set_reg64(s->regs, APIC_ICR, icr); +- } else { +- icr = __kvm_lapic_get_reg64(s->regs, APIC_ICR); +- __kvm_lapic_set_reg(s->regs, APIC_ICR2, icr >> 32); ++ if (set) ++ *ldr = kvm_apic_calc_x2apic_ldr(x2apic_id); ++ ++ if (!kvm_x86_ops.x2apic_icr_is_split) { ++ if (set) { ++ icr = __kvm_lapic_get_reg(s->regs, APIC_ICR) | ++ (u64)__kvm_lapic_get_reg(s->regs, APIC_ICR2) << 32; ++ __kvm_lapic_set_reg64(s->regs, APIC_ICR, icr); ++ } else { ++ icr = __kvm_lapic_get_reg64(s->regs, APIC_ICR); ++ __kvm_lapic_set_reg(s->regs, APIC_ICR2, icr >> 32); ++ } + } + } + +@@ -3188,7 +3214,7 @@ static int kvm_lapic_msr_read(struct kvm_lapic *apic, u32 reg, u64 *data) + u32 low; + + if (reg == APIC_ICR) { +- *data = kvm_lapic_get_reg64(apic, APIC_ICR); ++ *data = kvm_x2apic_icr_read(apic); + return 0; + } + +diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c +index 413f1f2aadd1a3..d762330bce166c 100644 +--- a/arch/x86/kvm/svm/svm.c ++++ b/arch/x86/kvm/svm/svm.c +@@ -5014,6 +5014,8 @@ static struct kvm_x86_ops svm_x86_ops __initdata = { + .enable_nmi_window = svm_enable_nmi_window, + .enable_irq_window = svm_enable_irq_window, + .update_cr8_intercept = svm_update_cr8_intercept, ++ ++ .x2apic_icr_is_split = true, + .set_virtual_apic_mode = avic_refresh_virtual_apic_mode, + .refresh_apicv_exec_ctrl = avic_refresh_apicv_exec_ctrl, + .apicv_post_state_restore = avic_apicv_post_state_restore, +diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c +index 479ef26626f2fe..52098844290ad4 100644 +--- a/arch/x86/kvm/vmx/vmx.c ++++ b/arch/x86/kvm/vmx/vmx.c +@@ -8323,6 +8323,8 @@ static struct kvm_x86_ops vmx_x86_ops __initdata = { + .enable_nmi_window = vmx_enable_nmi_window, + .enable_irq_window = vmx_enable_irq_window, + .update_cr8_intercept = vmx_update_cr8_intercept, ++ ++ .x2apic_icr_is_split = false, + .set_virtual_apic_mode = vmx_set_virtual_apic_mode, + .set_apic_access_page_addr = vmx_set_apic_access_page_addr, + .refresh_apicv_exec_ctrl = vmx_refresh_apicv_exec_ctrl, +diff --git a/arch/x86/mm/ident_map.c b/arch/x86/mm/ident_map.c +index 7cbad417e094f6..fe0b2e66ded93f 100644 +--- a/arch/x86/mm/ident_map.c ++++ b/arch/x86/mm/ident_map.c +@@ -26,18 +26,31 @@ static int ident_pud_init(struct x86_mapping_info *info, pud_t *pud_page, + for (; addr < end; addr = next) { + pud_t *pud = pud_page + pud_index(addr); + pmd_t *pmd; ++ bool use_gbpage; + + next = (addr & PUD_MASK) + PUD_SIZE; + if (next > end) + next = end; + +- if (info->direct_gbpages) { +- pud_t pudval; ++ /* if this is already a gbpage, this portion is already mapped */ ++ if (pud_leaf(*pud)) ++ continue; ++ ++ /* Is using a gbpage allowed? */ ++ use_gbpage = info->direct_gbpages; + +- if (pud_present(*pud)) +- continue; ++ /* Don't use gbpage if it maps more than the requested region. */ ++ /* at the begining: */ ++ use_gbpage &= ((addr & ~PUD_MASK) == 0); ++ /* ... or at the end: */ ++ use_gbpage &= ((next & ~PUD_MASK) == 0); ++ ++ /* Never overwrite existing mappings */ ++ use_gbpage &= !pud_present(*pud); ++ ++ if (use_gbpage) { ++ pud_t pudval; + +- addr &= PUD_MASK; + pudval = __pud((addr - info->offset) | info->page_flag); + set_pud(pud, pudval); + continue; +diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c +index 98a9bb92d75c88..12d5a0f37432ea 100644 +--- a/arch/x86/pci/fixup.c ++++ b/arch/x86/pci/fixup.c +@@ -1010,4 +1010,34 @@ DECLARE_PCI_FIXUP_SUSPEND(PCI_VENDOR_ID_AMD, 0x1668, amd_rp_pme_suspend); + DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, 0x1668, amd_rp_pme_resume); + DECLARE_PCI_FIXUP_SUSPEND(PCI_VENDOR_ID_AMD, 0x1669, amd_rp_pme_suspend); + DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, 0x1669, amd_rp_pme_resume); ++ ++/* ++ * Putting PCIe root ports on Ryzen SoCs with USB4 controllers into D3hot ++ * may cause problems when the system attempts wake up from s2idle. ++ * ++ * On the TUXEDO Sirius 16 Gen 1 with a specific old BIOS this manifests as ++ * a system hang. ++ */ ++static const struct dmi_system_id quirk_tuxeo_rp_d3_dmi_table[] = { ++ { ++ .matches = { ++ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TUXEDO"), ++ DMI_EXACT_MATCH(DMI_BOARD_NAME, "APX958"), ++ DMI_EXACT_MATCH(DMI_BIOS_VERSION, "V1.00A00_20240108"), ++ }, ++ }, ++ {} ++}; ++ ++static void quirk_tuxeo_rp_d3(struct pci_dev *pdev) ++{ ++ struct pci_dev *root_pdev; ++ ++ if (dmi_check_system(quirk_tuxeo_rp_d3_dmi_table)) { ++ root_pdev = pcie_find_root_port(pdev); ++ if (root_pdev) ++ root_pdev->dev_flags |= PCI_DEV_FLAGS_NO_D3; ++ } ++} ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x1502, quirk_tuxeo_rp_d3); + #endif /* CONFIG_SUSPEND */ +diff --git a/arch/x86/xen/xen-head.S b/arch/x86/xen/xen-head.S +index 4fd814321ed021..059f343da76d61 100644 +--- a/arch/x86/xen/xen-head.S ++++ b/arch/x86/xen/xen-head.S +@@ -117,8 +117,8 @@ SYM_FUNC_START(xen_hypercall_hvm) + pop %ebx + pop %eax + #else +- lea xen_hypercall_amd(%rip), %rbx +- cmp %rax, %rbx ++ lea xen_hypercall_amd(%rip), %rcx ++ cmp %rax, %rcx + #ifdef CONFIG_FRAME_POINTER + pop %rax /* Dummy pop. */ + #endif +@@ -132,6 +132,7 @@ SYM_FUNC_START(xen_hypercall_hvm) + pop %rcx + pop %rax + #endif ++ FRAME_END + /* Use correct hypercall function. */ + jz xen_hypercall_amd + jmp xen_hypercall_intel +diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c +index 7347eb29524df1..64551b0aa51e66 100644 +--- a/block/blk-cgroup.c ++++ b/block/blk-cgroup.c +@@ -1139,6 +1139,7 @@ static void blkcg_fill_root_iostats(void) + blkg_iostat_set(&blkg->iostat.cur, &tmp); + u64_stats_update_end_irqrestore(&blkg->iostat.sync, flags); + } ++ class_dev_iter_exit(&iter); + } + + static void blkcg_print_one_stat(struct blkcg_gq *blkg, struct seq_file *s) +diff --git a/block/fops.c b/block/fops.c +index 1df187b3067920..7c257eb3564d0c 100644 +--- a/block/fops.c ++++ b/block/fops.c +@@ -718,11 +718,12 @@ static ssize_t blkdev_read_iter(struct kiocb *iocb, struct iov_iter *to) + file_accessed(iocb->ki_filp); + + ret = blkdev_direct_IO(iocb, to); +- if (ret >= 0) { ++ if (ret > 0) { + iocb->ki_pos += ret; + count -= ret; + } +- iov_iter_revert(to, count - iov_iter_count(to)); ++ if (ret != -EIOCBQUEUED) ++ iov_iter_revert(to, count - iov_iter_count(to)); + if (ret < 0 || !count) + goto reexpand; + } +diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c +index ab2a82cb1b0b48..3aadc632d7dd53 100644 +--- a/drivers/acpi/apei/ghes.c ++++ b/drivers/acpi/apei/ghes.c +@@ -170,8 +170,6 @@ static struct gen_pool *ghes_estatus_pool; + static struct ghes_estatus_cache __rcu *ghes_estatus_caches[GHES_ESTATUS_CACHES_SIZE]; + static atomic_t ghes_estatus_cache_alloced; + +-static int ghes_panic_timeout __read_mostly = 30; +- + static void __iomem *ghes_map(u64 pfn, enum fixed_addresses fixmap_idx) + { + phys_addr_t paddr; +@@ -899,14 +897,16 @@ static void __ghes_panic(struct ghes *ghes, + struct acpi_hest_generic_status *estatus, + u64 buf_paddr, enum fixed_addresses fixmap_idx) + { ++ const char *msg = GHES_PFX "Fatal hardware error"; ++ + __ghes_print_estatus(KERN_EMERG, ghes->generic, estatus); + + ghes_clear_estatus(ghes, estatus, buf_paddr, fixmap_idx); + +- /* reboot to log the error! */ + if (!panic_timeout) +- panic_timeout = ghes_panic_timeout; +- panic("Fatal hardware error!"); ++ pr_emerg("%s but panic disabled\n", msg); ++ ++ panic(msg); + } + + static int ghes_proc(struct ghes *ghes) +diff --git a/drivers/acpi/prmt.c b/drivers/acpi/prmt.c +index 8b391f12853bb6..a34f7d37877c9a 100644 +--- a/drivers/acpi/prmt.c ++++ b/drivers/acpi/prmt.c +@@ -263,9 +263,7 @@ static acpi_status acpi_platformrt_space_handler(u32 function, + if (!handler || !module) + goto invalid_guid; + +- if (!handler->handler_addr || +- !handler->static_data_buffer_addr || +- !handler->acpi_param_buffer_addr) { ++ if (!handler->handler_addr) { + buffer->prm_status = PRM_HANDLER_ERROR; + return AE_OK; + } +diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c +index 4d958a165da058..dca5682308cb32 100644 +--- a/drivers/acpi/property.c ++++ b/drivers/acpi/property.c +@@ -1116,8 +1116,6 @@ static int acpi_data_prop_read(const struct acpi_device_data *data, + } + break; + } +- if (nval == 0) +- return -EINVAL; + + if (obj->type == ACPI_TYPE_BUFFER) { + if (proptype != DEV_PROP_U8) +@@ -1141,9 +1139,11 @@ static int acpi_data_prop_read(const struct acpi_device_data *data, + ret = acpi_copy_property_array_uint(items, (u64 *)val, nval); + break; + case DEV_PROP_STRING: +- ret = acpi_copy_property_array_string( +- items, (char **)val, +- min_t(u32, nval, obj->package.count)); ++ nval = min_t(u32, nval, obj->package.count); ++ if (nval == 0) ++ return -ENODATA; ++ ++ ret = acpi_copy_property_array_string(items, (char **)val, nval); + break; + default: + ret = -EINVAL; +diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c +index 8fcc622fcb3d49..9b6529f2dfcbd9 100644 +--- a/drivers/ata/libata-sff.c ++++ b/drivers/ata/libata-sff.c +@@ -602,7 +602,7 @@ static void ata_pio_sector(struct ata_queued_cmd *qc) + { + struct ata_port *ap = qc->ap; + struct page *page; +- unsigned int offset; ++ unsigned int offset, count; + + if (!qc->cursg) { + qc->curbytes = qc->nbytes; +@@ -618,25 +618,27 @@ static void ata_pio_sector(struct ata_queued_cmd *qc) + page = nth_page(page, (offset >> PAGE_SHIFT)); + offset %= PAGE_SIZE; + +- trace_ata_sff_pio_transfer_data(qc, offset, qc->sect_size); ++ /* don't overrun current sg */ ++ count = min(qc->cursg->length - qc->cursg_ofs, qc->sect_size); ++ ++ trace_ata_sff_pio_transfer_data(qc, offset, count); + + /* + * Split the transfer when it splits a page boundary. Note that the + * split still has to be dword aligned like all ATA data transfers. + */ + WARN_ON_ONCE(offset % 4); +- if (offset + qc->sect_size > PAGE_SIZE) { ++ if (offset + count > PAGE_SIZE) { + unsigned int split_len = PAGE_SIZE - offset; + + ata_pio_xfer(qc, page, offset, split_len); +- ata_pio_xfer(qc, nth_page(page, 1), 0, +- qc->sect_size - split_len); ++ ata_pio_xfer(qc, nth_page(page, 1), 0, count - split_len); + } else { +- ata_pio_xfer(qc, page, offset, qc->sect_size); ++ ata_pio_xfer(qc, page, offset, count); + } + +- qc->curbytes += qc->sect_size; +- qc->cursg_ofs += qc->sect_size; ++ qc->curbytes += count; ++ qc->cursg_ofs += count; + + if (qc->cursg_ofs == qc->cursg->length) { + qc->cursg = sg_next(qc->cursg); +diff --git a/drivers/char/misc.c b/drivers/char/misc.c +index 541edc26ec89a1..2cf595d2e10b85 100644 +--- a/drivers/char/misc.c ++++ b/drivers/char/misc.c +@@ -63,16 +63,30 @@ static DEFINE_MUTEX(misc_mtx); + #define DYNAMIC_MINORS 128 /* like dynamic majors */ + static DEFINE_IDA(misc_minors_ida); + +-static int misc_minor_alloc(void) ++static int misc_minor_alloc(int minor) + { +- int ret; +- +- ret = ida_alloc_max(&misc_minors_ida, DYNAMIC_MINORS - 1, GFP_KERNEL); +- if (ret >= 0) { +- ret = DYNAMIC_MINORS - ret - 1; ++ int ret = 0; ++ ++ if (minor == MISC_DYNAMIC_MINOR) { ++ /* allocate free id */ ++ ret = ida_alloc_max(&misc_minors_ida, DYNAMIC_MINORS - 1, GFP_KERNEL); ++ if (ret >= 0) { ++ ret = DYNAMIC_MINORS - ret - 1; ++ } else { ++ ret = ida_alloc_range(&misc_minors_ida, MISC_DYNAMIC_MINOR + 1, ++ MINORMASK, GFP_KERNEL); ++ } + } else { +- ret = ida_alloc_range(&misc_minors_ida, MISC_DYNAMIC_MINOR + 1, +- MINORMASK, GFP_KERNEL); ++ /* specific minor, check if it is in dynamic or misc dynamic range */ ++ if (minor < DYNAMIC_MINORS) { ++ minor = DYNAMIC_MINORS - minor - 1; ++ ret = ida_alloc_range(&misc_minors_ida, minor, minor, GFP_KERNEL); ++ } else if (minor > MISC_DYNAMIC_MINOR) { ++ ret = ida_alloc_range(&misc_minors_ida, minor, minor, GFP_KERNEL); ++ } else { ++ /* case of non-dynamic minors, no need to allocate id */ ++ ret = 0; ++ } + } + return ret; + } +@@ -219,7 +233,7 @@ int misc_register(struct miscdevice *misc) + mutex_lock(&misc_mtx); + + if (is_dynamic) { +- int i = misc_minor_alloc(); ++ int i = misc_minor_alloc(misc->minor); + + if (i < 0) { + err = -EBUSY; +@@ -228,6 +242,7 @@ int misc_register(struct miscdevice *misc) + misc->minor = i; + } else { + struct miscdevice *c; ++ int i; + + list_for_each_entry(c, &misc_list, list) { + if (c->minor == misc->minor) { +@@ -235,6 +250,12 @@ int misc_register(struct miscdevice *misc) + goto out; + } + } ++ ++ i = misc_minor_alloc(misc->minor); ++ if (i < 0) { ++ err = -EBUSY; ++ goto out; ++ } + } + + dev = MKDEV(MISC_MAJOR, misc->minor); +diff --git a/drivers/char/tpm/eventlog/acpi.c b/drivers/char/tpm/eventlog/acpi.c +index bd757d836c5cf9..1a5644051d3103 100644 +--- a/drivers/char/tpm/eventlog/acpi.c ++++ b/drivers/char/tpm/eventlog/acpi.c +@@ -63,6 +63,11 @@ static bool tpm_is_tpm2_log(void *bios_event_log, u64 len) + return n == 0; + } + ++static void tpm_bios_log_free(void *data) ++{ ++ kvfree(data); ++} ++ + /* read binary bios log */ + int tpm_read_log_acpi(struct tpm_chip *chip) + { +@@ -136,7 +141,7 @@ int tpm_read_log_acpi(struct tpm_chip *chip) + } + + /* malloc EventLog space */ +- log->bios_event_log = devm_kmalloc(&chip->dev, len, GFP_KERNEL); ++ log->bios_event_log = kvmalloc(len, GFP_KERNEL); + if (!log->bios_event_log) + return -ENOMEM; + +@@ -162,10 +167,16 @@ int tpm_read_log_acpi(struct tpm_chip *chip) + goto err; + } + ++ ret = devm_add_action(&chip->dev, tpm_bios_log_free, log->bios_event_log); ++ if (ret) { ++ log->bios_event_log = NULL; ++ goto err; ++ } ++ + return format; + + err: +- devm_kfree(&chip->dev, log->bios_event_log); ++ tpm_bios_log_free(log->bios_event_log); + log->bios_event_log = NULL; + return ret; + } +diff --git a/drivers/clk/mediatek/clk-mt2701-aud.c b/drivers/clk/mediatek/clk-mt2701-aud.c +index 27eecb6d3a533b..d157b07effa2a6 100644 +--- a/drivers/clk/mediatek/clk-mt2701-aud.c ++++ b/drivers/clk/mediatek/clk-mt2701-aud.c +@@ -55,10 +55,16 @@ static const struct mtk_gate audio_clks[] = { + GATE_DUMMY(CLK_DUMMY, "aud_dummy"), + /* AUDIO0 */ + GATE_AUDIO0(CLK_AUD_AFE, "audio_afe", "aud_intbus_sel", 2), ++ GATE_DUMMY(CLK_AUD_LRCK_DETECT, "audio_lrck_detect_dummy"), ++ GATE_DUMMY(CLK_AUD_I2S, "audio_i2c_dummy"), ++ GATE_DUMMY(CLK_AUD_APLL_TUNER, "audio_apll_tuner_dummy"), + GATE_AUDIO0(CLK_AUD_HDMI, "audio_hdmi", "audpll_sel", 20), + GATE_AUDIO0(CLK_AUD_SPDF, "audio_spdf", "audpll_sel", 21), + GATE_AUDIO0(CLK_AUD_SPDF2, "audio_spdf2", "audpll_sel", 22), + GATE_AUDIO0(CLK_AUD_APLL, "audio_apll", "audpll_sel", 23), ++ GATE_DUMMY(CLK_AUD_TML, "audio_tml_dummy"), ++ GATE_DUMMY(CLK_AUD_AHB_IDLE_EXT, "audio_ahb_idle_ext_dummy"), ++ GATE_DUMMY(CLK_AUD_AHB_IDLE_INT, "audio_ahb_idle_int_dummy"), + /* AUDIO1 */ + GATE_AUDIO1(CLK_AUD_I2SIN1, "audio_i2sin1", "aud_mux1_sel", 0), + GATE_AUDIO1(CLK_AUD_I2SIN2, "audio_i2sin2", "aud_mux1_sel", 1), +@@ -76,10 +82,12 @@ static const struct mtk_gate audio_clks[] = { + GATE_AUDIO1(CLK_AUD_ASRCI2, "audio_asrci2", "asm_h_sel", 13), + GATE_AUDIO1(CLK_AUD_ASRCO1, "audio_asrco1", "asm_h_sel", 14), + GATE_AUDIO1(CLK_AUD_ASRCO2, "audio_asrco2", "asm_h_sel", 15), ++ GATE_DUMMY(CLK_AUD_HDMIRX, "audio_hdmirx_dummy"), + GATE_AUDIO1(CLK_AUD_INTDIR, "audio_intdir", "intdir_sel", 20), + GATE_AUDIO1(CLK_AUD_A1SYS, "audio_a1sys", "aud_mux1_sel", 21), + GATE_AUDIO1(CLK_AUD_A2SYS, "audio_a2sys", "aud_mux2_sel", 22), + GATE_AUDIO1(CLK_AUD_AFE_CONN, "audio_afe_conn", "aud_mux1_sel", 23), ++ GATE_DUMMY(CLK_AUD_AFE_PCMIF, "audio_afe_pcmif_dummy"), + GATE_AUDIO1(CLK_AUD_AFE_MRGIF, "audio_afe_mrgif", "aud_mux1_sel", 25), + /* AUDIO2 */ + GATE_AUDIO2(CLK_AUD_MMIF_UL1, "audio_ul1", "aud_mux1_sel", 0), +@@ -100,6 +108,8 @@ static const struct mtk_gate audio_clks[] = { + GATE_AUDIO2(CLK_AUD_MMIF_AWB2, "audio_awb2", "aud_mux1_sel", 15), + GATE_AUDIO2(CLK_AUD_MMIF_DAI, "audio_dai", "aud_mux1_sel", 16), + /* AUDIO3 */ ++ GATE_DUMMY(CLK_AUD_DMIC1, "audio_dmic1_dummy"), ++ GATE_DUMMY(CLK_AUD_DMIC2, "audio_dmic2_dummy"), + GATE_AUDIO3(CLK_AUD_ASRCI3, "audio_asrci3", "asm_h_sel", 2), + GATE_AUDIO3(CLK_AUD_ASRCI4, "audio_asrci4", "asm_h_sel", 3), + GATE_AUDIO3(CLK_AUD_ASRCI5, "audio_asrci5", "asm_h_sel", 4), +diff --git a/drivers/clk/mediatek/clk-mt2701-bdp.c b/drivers/clk/mediatek/clk-mt2701-bdp.c +index b25703ec8dc08f..0728484d6f173d 100644 +--- a/drivers/clk/mediatek/clk-mt2701-bdp.c ++++ b/drivers/clk/mediatek/clk-mt2701-bdp.c +@@ -31,6 +31,7 @@ static const struct mtk_gate_regs bdp1_cg_regs = { + GATE_MTK(_id, _name, _parent, &bdp1_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv) + + static const struct mtk_gate bdp_clks[] = { ++ GATE_DUMMY(CLK_DUMMY, "bdp_dummy"), + GATE_BDP0(CLK_BDP_BRG_BA, "brg_baclk", "mm_sel", 0), + GATE_BDP0(CLK_BDP_BRG_DRAM, "brg_dram", "mm_sel", 1), + GATE_BDP0(CLK_BDP_LARB_DRAM, "larb_dram", "mm_sel", 2), +diff --git a/drivers/clk/mediatek/clk-mt2701-img.c b/drivers/clk/mediatek/clk-mt2701-img.c +index 2768360b213efc..b972deed7ef4ee 100644 +--- a/drivers/clk/mediatek/clk-mt2701-img.c ++++ b/drivers/clk/mediatek/clk-mt2701-img.c +@@ -22,6 +22,7 @@ static const struct mtk_gate_regs img_cg_regs = { + GATE_MTK(_id, _name, _parent, &img_cg_regs, _shift, &mtk_clk_gate_ops_setclr) + + static const struct mtk_gate img_clks[] = { ++ GATE_DUMMY(CLK_DUMMY, "img_dummy"), + GATE_IMG(CLK_IMG_SMI_COMM, "img_smi_comm", "mm_sel", 0), + GATE_IMG(CLK_IMG_RESZ, "img_resz", "mm_sel", 1), + GATE_IMG(CLK_IMG_JPGDEC_SMI, "img_jpgdec_smi", "mm_sel", 5), +diff --git a/drivers/clk/mediatek/clk-mt2701-mm.c b/drivers/clk/mediatek/clk-mt2701-mm.c +index 2b990b5a0422a4..bebb22b32fafa3 100644 +--- a/drivers/clk/mediatek/clk-mt2701-mm.c ++++ b/drivers/clk/mediatek/clk-mt2701-mm.c +@@ -31,6 +31,7 @@ static const struct mtk_gate_regs disp1_cg_regs = { + GATE_MTK(_id, _name, _parent, &disp1_cg_regs, _shift, &mtk_clk_gate_ops_setclr) + + static const struct mtk_gate mm_clks[] = { ++ GATE_DUMMY(CLK_DUMMY, "mm_dummy"), + GATE_DISP0(CLK_MM_SMI_COMMON, "mm_smi_comm", "mm_sel", 0), + GATE_DISP0(CLK_MM_SMI_LARB0, "mm_smi_larb0", "mm_sel", 1), + GATE_DISP0(CLK_MM_CMDQ, "mm_cmdq", "mm_sel", 2), +diff --git a/drivers/clk/mediatek/clk-mt2701-vdec.c b/drivers/clk/mediatek/clk-mt2701-vdec.c +index 57711b953b7f90..5b8035c6794e2e 100644 +--- a/drivers/clk/mediatek/clk-mt2701-vdec.c ++++ b/drivers/clk/mediatek/clk-mt2701-vdec.c +@@ -31,6 +31,7 @@ static const struct mtk_gate_regs vdec1_cg_regs = { + GATE_MTK(_id, _name, _parent, &vdec1_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv) + + static const struct mtk_gate vdec_clks[] = { ++ GATE_DUMMY(CLK_DUMMY, "vdec_dummy"), + GATE_VDEC0(CLK_VDEC_CKGEN, "vdec_cken", "vdec_sel", 0), + GATE_VDEC1(CLK_VDEC_LARB, "vdec_larb_cken", "mm_sel", 0), + }; +diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig +index a79b837583894f..1de1661037b1b1 100644 +--- a/drivers/clk/qcom/Kconfig ++++ b/drivers/clk/qcom/Kconfig +@@ -881,6 +881,7 @@ config SM_GCC_7150 + config SM_GCC_8150 + tristate "SM8150 Global Clock Controller" + depends on ARM64 || COMPILE_TEST ++ select QCOM_GDSC + help + Support for the global clock controller on SM8150 devices. + Say Y if you want to use peripheral devices such as UART, +diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c +index ce44dbfd47e275..80aadafffacdb1 100644 +--- a/drivers/clk/qcom/clk-alpha-pll.c ++++ b/drivers/clk/qcom/clk-alpha-pll.c +@@ -407,6 +407,8 @@ void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, + mask |= config->pre_div_mask; + mask |= config->post_div_mask; + mask |= config->vco_mask; ++ mask |= config->alpha_en_mask; ++ mask |= config->alpha_mode_mask; + + regmap_update_bits(regmap, PLL_USER_CTL(pll), mask, val); + +diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c +index a8b5f4d8a7b9e6..edbae2a88afcf1 100644 +--- a/drivers/clk/qcom/clk-rpmh.c ++++ b/drivers/clk/qcom/clk-rpmh.c +@@ -329,7 +329,7 @@ static unsigned long clk_rpmh_bcm_recalc_rate(struct clk_hw *hw, + { + struct clk_rpmh *c = to_clk_rpmh(hw); + +- return c->aggr_state * c->unit; ++ return (unsigned long)c->aggr_state * c->unit; + } + + static const struct clk_ops clk_rpmh_bcm_ops = { +diff --git a/drivers/clk/qcom/dispcc-sm6350.c b/drivers/clk/qcom/dispcc-sm6350.c +index 441f042f5ea459..ddacb4f76eca5f 100644 +--- a/drivers/clk/qcom/dispcc-sm6350.c ++++ b/drivers/clk/qcom/dispcc-sm6350.c +@@ -187,13 +187,12 @@ static struct clk_rcg2 disp_cc_mdss_dp_aux_clk_src = { + .cmd_rcgr = 0x1144, + .mnd_width = 0, + .hid_width = 5, ++ .parent_map = disp_cc_parent_map_6, + .freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_dp_aux_clk_src", +- .parent_data = &(const struct clk_parent_data){ +- .fw_name = "bi_tcxo", +- }, +- .num_parents = 1, ++ .parent_data = disp_cc_parent_data_6, ++ .num_parents = ARRAY_SIZE(disp_cc_parent_data_6), + .ops = &clk_rcg2_ops, + }, + }; +diff --git a/drivers/clk/qcom/gcc-mdm9607.c b/drivers/clk/qcom/gcc-mdm9607.c +index fb290e73ce9487..9169cdccf3ed88 100644 +--- a/drivers/clk/qcom/gcc-mdm9607.c ++++ b/drivers/clk/qcom/gcc-mdm9607.c +@@ -535,7 +535,7 @@ static struct clk_rcg2 blsp1_uart5_apps_clk_src = { + }; + + static struct clk_rcg2 blsp1_uart6_apps_clk_src = { +- .cmd_rcgr = 0x6044, ++ .cmd_rcgr = 0x7044, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, +diff --git a/drivers/clk/qcom/gcc-sm6350.c b/drivers/clk/qcom/gcc-sm6350.c +index 0559a33faf00e6..428cd99dcdcbe5 100644 +--- a/drivers/clk/qcom/gcc-sm6350.c ++++ b/drivers/clk/qcom/gcc-sm6350.c +@@ -182,6 +182,14 @@ static const struct clk_parent_data gcc_parent_data_2_ao[] = { + { .hw = &gpll0_out_odd.clkr.hw }, + }; + ++static const struct parent_map gcc_parent_map_3[] = { ++ { P_BI_TCXO, 0 }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_3[] = { ++ { .fw_name = "bi_tcxo" }, ++}; ++ + static const struct parent_map gcc_parent_map_4[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, +@@ -701,13 +709,12 @@ static struct clk_rcg2 gcc_ufs_phy_phy_aux_clk_src = { + .cmd_rcgr = 0x3a0b0, + .mnd_width = 0, + .hid_width = 5, ++ .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_gcc_ufs_phy_phy_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_phy_aux_clk_src", +- .parent_data = &(const struct clk_parent_data){ +- .fw_name = "bi_tcxo", +- }, +- .num_parents = 1, ++ .parent_data = gcc_parent_data_3, ++ .num_parents = ARRAY_SIZE(gcc_parent_data_3), + .ops = &clk_rcg2_ops, + }, + }; +@@ -764,13 +771,12 @@ static struct clk_rcg2 gcc_usb30_prim_mock_utmi_clk_src = { + .cmd_rcgr = 0x1a034, + .mnd_width = 0, + .hid_width = 5, ++ .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_gcc_usb30_prim_mock_utmi_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_prim_mock_utmi_clk_src", +- .parent_data = &(const struct clk_parent_data){ +- .fw_name = "bi_tcxo", +- }, +- .num_parents = 1, ++ .parent_data = gcc_parent_data_3, ++ .num_parents = ARRAY_SIZE(gcc_parent_data_3), + .ops = &clk_rcg2_ops, + }, + }; +diff --git a/drivers/clk/qcom/gcc-sm8550.c b/drivers/clk/qcom/gcc-sm8550.c +index eb3765c57b6502..b30ece62216f7e 100644 +--- a/drivers/clk/qcom/gcc-sm8550.c ++++ b/drivers/clk/qcom/gcc-sm8550.c +@@ -3003,7 +3003,7 @@ static struct gdsc pcie_0_gdsc = { + .pd = { + .name = "pcie_0_gdsc", + }, +- .pwrsts = PWRSTS_OFF_ON, ++ .pwrsts = PWRSTS_RET_ON, + .flags = VOTABLE | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + }; + +@@ -3014,7 +3014,7 @@ static struct gdsc pcie_0_phy_gdsc = { + .pd = { + .name = "pcie_0_phy_gdsc", + }, +- .pwrsts = PWRSTS_OFF_ON, ++ .pwrsts = PWRSTS_RET_ON, + .flags = VOTABLE | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + }; + +@@ -3025,7 +3025,7 @@ static struct gdsc pcie_1_gdsc = { + .pd = { + .name = "pcie_1_gdsc", + }, +- .pwrsts = PWRSTS_OFF_ON, ++ .pwrsts = PWRSTS_RET_ON, + .flags = VOTABLE | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + }; + +@@ -3036,7 +3036,7 @@ static struct gdsc pcie_1_phy_gdsc = { + .pd = { + .name = "pcie_1_phy_gdsc", + }, +- .pwrsts = PWRSTS_OFF_ON, ++ .pwrsts = PWRSTS_RET_ON, + .flags = VOTABLE | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + }; + +diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a100.c b/drivers/clk/sunxi-ng/ccu-sun50i-a100.c +index 5f93b5526e13d6..52c1d5ebb0a12a 100644 +--- a/drivers/clk/sunxi-ng/ccu-sun50i-a100.c ++++ b/drivers/clk/sunxi-ng/ccu-sun50i-a100.c +@@ -436,7 +436,7 @@ static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc0_clk, "mmc0", mmc_parents, 0x830, + 24, 2, /* mux */ + BIT(31), /* gate */ + 2, /* post-div */ +- CLK_SET_RATE_NO_REPARENT); ++ 0); + + static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc1_clk, "mmc1", mmc_parents, 0x834, + 0, 4, /* M */ +@@ -444,7 +444,7 @@ static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc1_clk, "mmc1", mmc_parents, 0x834, + 24, 2, /* mux */ + BIT(31), /* gate */ + 2, /* post-div */ +- CLK_SET_RATE_NO_REPARENT); ++ 0); + + static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc2_clk, "mmc2", mmc_parents, 0x838, + 0, 4, /* M */ +@@ -452,7 +452,7 @@ static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc2_clk, "mmc2", mmc_parents, 0x838, + 24, 2, /* mux */ + BIT(31), /* gate */ + 2, /* post-div */ +- CLK_SET_RATE_NO_REPARENT); ++ 0); + + static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb3", 0x84c, BIT(0), 0); + static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb3", 0x84c, BIT(1), 0); +diff --git a/drivers/cpufreq/s3c64xx-cpufreq.c b/drivers/cpufreq/s3c64xx-cpufreq.c +index c6bdfc308e9908..9cef7152807626 100644 +--- a/drivers/cpufreq/s3c64xx-cpufreq.c ++++ b/drivers/cpufreq/s3c64xx-cpufreq.c +@@ -24,6 +24,7 @@ struct s3c64xx_dvfs { + unsigned int vddarm_max; + }; + ++#ifdef CONFIG_REGULATOR + static struct s3c64xx_dvfs s3c64xx_dvfs_table[] = { + [0] = { 1000000, 1150000 }, + [1] = { 1050000, 1150000 }, +@@ -31,6 +32,7 @@ static struct s3c64xx_dvfs s3c64xx_dvfs_table[] = { + [3] = { 1200000, 1350000 }, + [4] = { 1300000, 1350000 }, + }; ++#endif + + static struct cpufreq_frequency_table s3c64xx_freq_table[] = { + { 0, 0, 66000 }, +@@ -51,15 +53,16 @@ static struct cpufreq_frequency_table s3c64xx_freq_table[] = { + static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy, + unsigned int index) + { +- struct s3c64xx_dvfs *dvfs; +- unsigned int old_freq, new_freq; ++ unsigned int new_freq = s3c64xx_freq_table[index].frequency; + int ret; + ++#ifdef CONFIG_REGULATOR ++ struct s3c64xx_dvfs *dvfs; ++ unsigned int old_freq; ++ + old_freq = clk_get_rate(policy->clk) / 1000; +- new_freq = s3c64xx_freq_table[index].frequency; + dvfs = &s3c64xx_dvfs_table[s3c64xx_freq_table[index].driver_data]; + +-#ifdef CONFIG_REGULATOR + if (vddarm && new_freq > old_freq) { + ret = regulator_set_voltage(vddarm, + dvfs->vddarm_min, +diff --git a/drivers/crypto/qce/aead.c b/drivers/crypto/qce/aead.c +index 7d811728f04782..97b56e92ea33f5 100644 +--- a/drivers/crypto/qce/aead.c ++++ b/drivers/crypto/qce/aead.c +@@ -786,7 +786,7 @@ static int qce_aead_register_one(const struct qce_aead_def *def, struct qce_devi + alg->init = qce_aead_init; + alg->exit = qce_aead_exit; + +- alg->base.cra_priority = 300; ++ alg->base.cra_priority = 275; + alg->base.cra_flags = CRYPTO_ALG_ASYNC | + CRYPTO_ALG_ALLOCATES_MEMORY | + CRYPTO_ALG_KERN_DRIVER_ONLY | +diff --git a/drivers/crypto/qce/core.c b/drivers/crypto/qce/core.c +index fce49c0dee3e2d..8bcb9adf1aee3f 100644 +--- a/drivers/crypto/qce/core.c ++++ b/drivers/crypto/qce/core.c +@@ -51,16 +51,19 @@ static void qce_unregister_algs(struct qce_device *qce) + static int qce_register_algs(struct qce_device *qce) + { + const struct qce_algo_ops *ops; +- int i, ret = -ENODEV; ++ int i, j, ret = -ENODEV; + + for (i = 0; i < ARRAY_SIZE(qce_ops); i++) { + ops = qce_ops[i]; + ret = ops->register_algs(qce); +- if (ret) +- break; ++ if (ret) { ++ for (j = i - 1; j >= 0; j--) ++ ops->unregister_algs(qce); ++ return ret; ++ } + } + +- return ret; ++ return 0; + } + + static int qce_handle_request(struct crypto_async_request *async_req) +@@ -247,7 +250,7 @@ static int qce_crypto_probe(struct platform_device *pdev) + + ret = qce_check_version(qce); + if (ret) +- goto err_clks; ++ goto err_dma; + + spin_lock_init(&qce->lock); + tasklet_init(&qce->done_tasklet, qce_tasklet_req_done, +diff --git a/drivers/crypto/qce/sha.c b/drivers/crypto/qce/sha.c +index fc72af8aa9a725..71b748183cfa86 100644 +--- a/drivers/crypto/qce/sha.c ++++ b/drivers/crypto/qce/sha.c +@@ -482,7 +482,7 @@ static int qce_ahash_register_one(const struct qce_ahash_def *def, + + base = &alg->halg.base; + base->cra_blocksize = def->blocksize; +- base->cra_priority = 300; ++ base->cra_priority = 175; + base->cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY; + base->cra_ctxsize = sizeof(struct qce_sha_ctx); + base->cra_alignmask = 0; +diff --git a/drivers/crypto/qce/skcipher.c b/drivers/crypto/qce/skcipher.c +index 5b493fdc1e747f..ffb334eb5b3461 100644 +--- a/drivers/crypto/qce/skcipher.c ++++ b/drivers/crypto/qce/skcipher.c +@@ -461,7 +461,7 @@ static int qce_skcipher_register_one(const struct qce_skcipher_def *def, + alg->encrypt = qce_skcipher_encrypt; + alg->decrypt = qce_skcipher_decrypt; + +- alg->base.cra_priority = 300; ++ alg->base.cra_priority = 275; + alg->base.cra_flags = CRYPTO_ALG_ASYNC | + CRYPTO_ALG_ALLOCATES_MEMORY | + CRYPTO_ALG_KERN_DRIVER_ONLY; +diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig +index f0e9f250669e2f..3f2f22e47bfa1a 100644 +--- a/drivers/firmware/Kconfig ++++ b/drivers/firmware/Kconfig +@@ -139,7 +139,7 @@ config ISCSI_IBFT + select ISCSI_BOOT_SYSFS + select ISCSI_IBFT_FIND if X86 + depends on ACPI && SCSI && SCSI_LOWLEVEL +- default n ++ default n + help + This option enables support for detection and exposing of iSCSI + Boot Firmware Table (iBFT) via sysfs to userspace. If you wish to +diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile +index a0f1569b790da5..29afa73e4b282c 100644 +--- a/drivers/firmware/efi/libstub/Makefile ++++ b/drivers/firmware/efi/libstub/Makefile +@@ -11,7 +11,7 @@ cflags-y := $(KBUILD_CFLAGS) + + cflags-$(CONFIG_X86_32) := -march=i386 + cflags-$(CONFIG_X86_64) := -mcmodel=small +-cflags-$(CONFIG_X86) += -m$(BITS) -D__KERNEL__ \ ++cflags-$(CONFIG_X86) += -m$(BITS) -D__KERNEL__ -std=gnu11 \ + -fPIC -fno-strict-aliasing -mno-red-zone \ + -mno-mmx -mno-sse -fshort-wchar \ + -Wno-pointer-sign \ +diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c +index 9c33f9da724cfd..b882b26ab5007b 100644 +--- a/drivers/gpio/gpio-pca953x.c ++++ b/drivers/gpio/gpio-pca953x.c +@@ -847,25 +847,6 @@ static bool pca953x_irq_pending(struct pca953x_chip *chip, unsigned long *pendin + DECLARE_BITMAP(trigger, MAX_LINE); + int ret; + +- if (chip->driver_data & PCA_PCAL) { +- /* Read the current interrupt status from the device */ +- ret = pca953x_read_regs(chip, PCAL953X_INT_STAT, trigger); +- if (ret) +- return false; +- +- /* Check latched inputs and clear interrupt status */ +- ret = pca953x_read_regs(chip, chip->regs->input, cur_stat); +- if (ret) +- return false; +- +- /* Apply filter for rising/falling edge selection */ +- bitmap_replace(new_stat, chip->irq_trig_fall, chip->irq_trig_raise, cur_stat, gc->ngpio); +- +- bitmap_and(pending, new_stat, trigger, gc->ngpio); +- +- return !bitmap_empty(pending, gc->ngpio); +- } +- + ret = pca953x_read_regs(chip, chip->regs->input, cur_stat); + if (ret) + return false; +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c +index 0583af4e84fa3f..a02777694d9951 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c +@@ -86,9 +86,12 @@ void kfd_process_dequeue_from_device(struct kfd_process_device *pdd) + + if (pdd->already_dequeued) + return; +- ++ /* The MES context flush needs to filter out the case which the ++ * KFD process is created without setting up the MES context and ++ * queue for creating a compute queue. ++ */ + dev->dqm->ops.process_termination(dev->dqm, &pdd->qpd); +- if (dev->kfd->shared_resources.enable_mes && ++ if (dev->kfd->shared_resources.enable_mes && !!pdd->proc_ctx_gpu_addr && + down_read_trylock(&dev->adev->reset_domain->sem)) { + amdgpu_mes_flush_shader_debugger(dev->adev, + pdd->proc_ctx_gpu_addr); +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +index 8a152f4974d3c5..aab99df3ba1ae4 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -955,8 +955,10 @@ static int amdgpu_dm_audio_component_get_eld(struct device *kdev, int port, + continue; + + *enabled = true; ++ mutex_lock(&connector->eld_mutex); + ret = drm_eld_size(connector->eld); + memcpy(buf, connector->eld, min(max_bytes, ret)); ++ mutex_unlock(&connector->eld_mutex); + + break; + } +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +index 385a5a75fdf873..5858e288b3fd66 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +@@ -1578,16 +1578,16 @@ int pre_validate_dsc(struct drm_atomic_state *state, + return ret; + } + +-static unsigned int kbps_from_pbn(unsigned int pbn) ++static uint32_t kbps_from_pbn(unsigned int pbn) + { +- unsigned int kbps = pbn; ++ uint64_t kbps = (uint64_t)pbn; + + kbps *= (1000000 / PEAK_FACTOR_X1000); + kbps *= 8; + kbps *= 54; + kbps /= 64; + +- return kbps; ++ return (uint32_t)kbps; + } + + static bool is_dsc_common_config_possible(struct dc_stream_state *stream, +diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c +index f11b071a896f59..2aa0e01a6891b0 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c ++++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c +@@ -63,8 +63,7 @@ void dmub_hw_lock_mgr_inbox0_cmd(struct dc_dmub_srv *dmub_srv, + + bool should_use_dmub_lock(struct dc_link *link) + { +- if (link->psr_settings.psr_version == DC_PSR_VERSION_SU_1 || +- link->psr_settings.psr_version == DC_PSR_VERSION_1) ++ if (link->psr_settings.psr_version == DC_PSR_VERSION_SU_1) + return true; + return false; + } +diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c +index ded8952d984907..b2256178014990 100644 +--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c +@@ -1752,7 +1752,6 @@ static ssize_t aldebaran_get_gpu_metrics(struct smu_context *smu, + + gpu_metrics->average_gfx_activity = metrics.AverageGfxActivity; + gpu_metrics->average_umc_activity = metrics.AverageUclkActivity; +- gpu_metrics->average_mm_activity = 0; + + /* Valid power data is available only from primary die */ + if (aldebaran_is_primary(smu)) { +diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c +index ebccb74306a765..f30b3d5eeca5c5 100644 +--- a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c ++++ b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c +@@ -160,6 +160,10 @@ static int komeda_wb_connector_add(struct komeda_kms_dev *kms, + formats = komeda_get_layer_fourcc_list(&mdev->fmt_tbl, + kwb_conn->wb_layer->layer_type, + &n_formats); ++ if (!formats) { ++ kfree(kwb_conn); ++ return -ENOMEM; ++ } + + err = drm_writeback_connector_init(&kms->base, wb_conn, + &komeda_wb_connector_funcs, +diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c +index 412c6575e87b74..ddf944651c55a9 100644 +--- a/drivers/gpu/drm/bridge/analogix/anx7625.c ++++ b/drivers/gpu/drm/bridge/analogix/anx7625.c +@@ -2014,8 +2014,10 @@ static int anx7625_audio_get_eld(struct device *dev, void *data, + memset(buf, 0, len); + } else { + dev_dbg(dev, "audio copy eld\n"); ++ mutex_lock(&ctx->connector->eld_mutex); + memcpy(buf, ctx->connector->eld, + min(sizeof(ctx->connector->eld), len)); ++ mutex_unlock(&ctx->connector->eld_mutex); + } + + return 0; +diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c +index 24c5a926af8d1d..fe33b988d7523e 100644 +--- a/drivers/gpu/drm/bridge/ite-it6505.c ++++ b/drivers/gpu/drm/bridge/ite-it6505.c +@@ -295,7 +295,7 @@ + #define MAX_LANE_COUNT 4 + #define MAX_LINK_RATE HBR + #define AUTO_TRAIN_RETRY 3 +-#define MAX_HDCP_DOWN_STREAM_COUNT 10 ++#define MAX_HDCP_DOWN_STREAM_COUNT 127 + #define MAX_CR_LEVEL 0x03 + #define MAX_EQ_LEVEL 0x03 + #define AUX_WAIT_TIMEOUT_MS 15 +@@ -2020,7 +2020,7 @@ static bool it6505_hdcp_part2_ksvlist_check(struct it6505 *it6505) + { + struct device *dev = it6505->dev; + u8 av[5][4], bv[5][4]; +- int i, err; ++ int i, err, retry; + + i = it6505_setup_sha1_input(it6505, it6505->sha1_input); + if (i <= 0) { +@@ -2029,22 +2029,28 @@ static bool it6505_hdcp_part2_ksvlist_check(struct it6505 *it6505) + } + + it6505_sha1_digest(it6505, it6505->sha1_input, i, (u8 *)av); ++ /*1B-05 V' must retry 3 times */ ++ for (retry = 0; retry < 3; retry++) { ++ err = it6505_get_dpcd(it6505, DP_AUX_HDCP_V_PRIME(0), (u8 *)bv, ++ sizeof(bv)); + +- err = it6505_get_dpcd(it6505, DP_AUX_HDCP_V_PRIME(0), (u8 *)bv, +- sizeof(bv)); ++ if (err < 0) { ++ dev_err(dev, "Read V' value Fail %d", retry); ++ continue; ++ } + +- if (err < 0) { +- dev_err(dev, "Read V' value Fail"); +- return false; +- } ++ for (i = 0; i < 5; i++) { ++ if (bv[i][3] != av[i][0] || bv[i][2] != av[i][1] || ++ av[i][1] != av[i][2] || bv[i][0] != av[i][3]) ++ break; + +- for (i = 0; i < 5; i++) +- if (bv[i][3] != av[i][0] || bv[i][2] != av[i][1] || +- bv[i][1] != av[i][2] || bv[i][0] != av[i][3]) +- return false; ++ DRM_DEV_DEBUG_DRIVER(dev, "V' all match!! %d, %d", retry, i); ++ return true; ++ } ++ } + +- DRM_DEV_DEBUG_DRIVER(dev, "V' all match!!"); +- return true; ++ DRM_DEV_DEBUG_DRIVER(dev, "V' NOT match!! %d", retry); ++ return false; + } + + static void it6505_hdcp_wait_ksv_list(struct work_struct *work) +@@ -2052,12 +2058,13 @@ static void it6505_hdcp_wait_ksv_list(struct work_struct *work) + struct it6505 *it6505 = container_of(work, struct it6505, + hdcp_wait_ksv_list); + struct device *dev = it6505->dev; +- unsigned int timeout = 5000; +- u8 bstatus = 0; ++ u8 bstatus; + bool ksv_list_check; ++ /* 1B-04 wait ksv list for 5s */ ++ unsigned long timeout = jiffies + ++ msecs_to_jiffies(5000) + 1; + +- timeout /= 20; +- while (timeout > 0) { ++ for (;;) { + if (!it6505_get_sink_hpd_status(it6505)) + return; + +@@ -2066,27 +2073,23 @@ static void it6505_hdcp_wait_ksv_list(struct work_struct *work) + if (bstatus & DP_BSTATUS_READY) + break; + +- msleep(20); +- timeout--; +- } ++ if (time_after(jiffies, timeout)) { ++ DRM_DEV_DEBUG_DRIVER(dev, "KSV list wait timeout"); ++ goto timeout; ++ } + +- if (timeout == 0) { +- DRM_DEV_DEBUG_DRIVER(dev, "timeout and ksv list wait failed"); +- goto timeout; ++ msleep(20); + } + + ksv_list_check = it6505_hdcp_part2_ksvlist_check(it6505); + DRM_DEV_DEBUG_DRIVER(dev, "ksv list ready, ksv list check %s", + ksv_list_check ? "pass" : "fail"); +- if (ksv_list_check) { +- it6505_set_bits(it6505, REG_HDCP_TRIGGER, +- HDCP_TRIGGER_KSV_DONE, HDCP_TRIGGER_KSV_DONE); ++ ++ if (ksv_list_check) + return; +- } ++ + timeout: +- it6505_set_bits(it6505, REG_HDCP_TRIGGER, +- HDCP_TRIGGER_KSV_DONE | HDCP_TRIGGER_KSV_FAIL, +- HDCP_TRIGGER_KSV_DONE | HDCP_TRIGGER_KSV_FAIL); ++ it6505_start_hdcp(it6505); + } + + static void it6505_hdcp_work(struct work_struct *work) +@@ -2309,14 +2312,20 @@ static int it6505_process_hpd_irq(struct it6505 *it6505) + DRM_DEV_DEBUG_DRIVER(dev, "dp_irq_vector = 0x%02x", dp_irq_vector); + + if (dp_irq_vector & DP_CP_IRQ) { +- it6505_set_bits(it6505, REG_HDCP_TRIGGER, HDCP_TRIGGER_CPIRQ, +- HDCP_TRIGGER_CPIRQ); +- + bstatus = it6505_dpcd_read(it6505, DP_AUX_HDCP_BSTATUS); + if (bstatus < 0) + return bstatus; + + DRM_DEV_DEBUG_DRIVER(dev, "Bstatus = 0x%02x", bstatus); ++ ++ /*Check BSTATUS when recive CP_IRQ */ ++ if (bstatus & DP_BSTATUS_R0_PRIME_READY && ++ it6505->hdcp_status == HDCP_AUTH_GOING) ++ it6505_set_bits(it6505, REG_HDCP_TRIGGER, HDCP_TRIGGER_CPIRQ, ++ HDCP_TRIGGER_CPIRQ); ++ else if (bstatus & (DP_BSTATUS_REAUTH_REQ | DP_BSTATUS_LINK_FAILURE) && ++ it6505->hdcp_status == HDCP_AUTH_DONE) ++ it6505_start_hdcp(it6505); + } + + ret = drm_dp_dpcd_read_link_status(&it6505->aux, link_status); +@@ -2453,7 +2462,11 @@ static void it6505_irq_hdcp_ksv_check(struct it6505 *it6505) + { + struct device *dev = it6505->dev; + +- DRM_DEV_DEBUG_DRIVER(dev, "HDCP event Interrupt"); ++ DRM_DEV_DEBUG_DRIVER(dev, "HDCP repeater R0 event Interrupt"); ++ /* 1B01 HDCP encription should start when R0 is ready*/ ++ it6505_set_bits(it6505, REG_HDCP_TRIGGER, ++ HDCP_TRIGGER_KSV_DONE, HDCP_TRIGGER_KSV_DONE); ++ + schedule_work(&it6505->hdcp_wait_ksv_list); + } + +diff --git a/drivers/gpu/drm/bridge/ite-it66121.c b/drivers/gpu/drm/bridge/ite-it66121.c +index 8f5846b76d5943..2381cd1cba8797 100644 +--- a/drivers/gpu/drm/bridge/ite-it66121.c ++++ b/drivers/gpu/drm/bridge/ite-it66121.c +@@ -1452,8 +1452,10 @@ static int it66121_audio_get_eld(struct device *dev, void *data, + dev_dbg(dev, "No connector present, passing empty EDID data"); + memset(buf, 0, len); + } else { ++ mutex_lock(&ctx->connector->eld_mutex); + memcpy(buf, ctx->connector->eld, + min(sizeof(ctx->connector->eld), len)); ++ mutex_unlock(&ctx->connector->eld_mutex); + } + mutex_unlock(&ctx->lock); + +diff --git a/drivers/gpu/drm/display/drm_dp_cec.c b/drivers/gpu/drm/display/drm_dp_cec.c +index ae39dc79419030..868bf53db66ce0 100644 +--- a/drivers/gpu/drm/display/drm_dp_cec.c ++++ b/drivers/gpu/drm/display/drm_dp_cec.c +@@ -310,16 +310,6 @@ void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid) + if (!aux->transfer) + return; + +-#ifndef CONFIG_MEDIA_CEC_RC +- /* +- * CEC_CAP_RC is part of CEC_CAP_DEFAULTS, but it is stripped by +- * cec_allocate_adapter() if CONFIG_MEDIA_CEC_RC is undefined. +- * +- * Do this here as well to ensure the tests against cec_caps are +- * correct. +- */ +- cec_caps &= ~CEC_CAP_RC; +-#endif + cancel_delayed_work_sync(&aux->cec.unregister_work); + + mutex_lock(&aux->cec.lock); +@@ -336,7 +326,9 @@ void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid) + num_las = CEC_MAX_LOG_ADDRS; + + if (aux->cec.adap) { +- if (aux->cec.adap->capabilities == cec_caps && ++ /* Check if the adapter properties have changed */ ++ if ((aux->cec.adap->capabilities & CEC_CAP_MONITOR_ALL) == ++ (cec_caps & CEC_CAP_MONITOR_ALL) && + aux->cec.adap->available_log_addrs == num_las) { + /* Unchanged, so just set the phys addr */ + cec_s_phys_addr_from_edid(aux->cec.adap, edid); +diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c +index 309aad5f0c808d..35bed66214474a 100644 +--- a/drivers/gpu/drm/drm_connector.c ++++ b/drivers/gpu/drm/drm_connector.c +@@ -277,6 +277,7 @@ static int __drm_connector_init(struct drm_device *dev, + INIT_LIST_HEAD(&connector->probed_modes); + INIT_LIST_HEAD(&connector->modes); + mutex_init(&connector->mutex); ++ mutex_init(&connector->eld_mutex); + mutex_init(&connector->edid_override_mutex); + connector->edid_blob_ptr = NULL; + connector->epoch_counter = 0; +diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c +index ee3fab115c4b5b..ad872c61aac0e3 100644 +--- a/drivers/gpu/drm/drm_edid.c ++++ b/drivers/gpu/drm/drm_edid.c +@@ -5499,7 +5499,9 @@ EXPORT_SYMBOL(drm_edid_get_monitor_name); + + static void clear_eld(struct drm_connector *connector) + { ++ mutex_lock(&connector->eld_mutex); + memset(connector->eld, 0, sizeof(connector->eld)); ++ mutex_unlock(&connector->eld_mutex); + + connector->latency_present[0] = false; + connector->latency_present[1] = false; +@@ -5530,6 +5532,8 @@ static void drm_edid_to_eld(struct drm_connector *connector, + if (!drm_edid) + return; + ++ mutex_lock(&connector->eld_mutex); ++ + mnl = get_monitor_name(drm_edid, &eld[DRM_ELD_MONITOR_NAME_STRING]); + drm_dbg_kms(connector->dev, "[CONNECTOR:%d:%s] ELD monitor %s\n", + connector->base.id, connector->name, +@@ -5590,6 +5594,8 @@ static void drm_edid_to_eld(struct drm_connector *connector, + drm_dbg_kms(connector->dev, "[CONNECTOR:%d:%s] ELD size %d, SAD count %d\n", + connector->base.id, connector->name, + drm_eld_size(eld), total_sad_count); ++ ++ mutex_unlock(&connector->eld_mutex); + } + + static int _drm_edid_to_sad(const struct drm_edid *drm_edid, +diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c +index 618b045230336e..b507c1c008a3e9 100644 +--- a/drivers/gpu/drm/drm_fb_helper.c ++++ b/drivers/gpu/drm/drm_fb_helper.c +@@ -1361,14 +1361,14 @@ int drm_fb_helper_set_par(struct fb_info *info) + } + EXPORT_SYMBOL(drm_fb_helper_set_par); + +-static void pan_set(struct drm_fb_helper *fb_helper, int x, int y) ++static void pan_set(struct drm_fb_helper *fb_helper, int dx, int dy) + { + struct drm_mode_set *mode_set; + + mutex_lock(&fb_helper->client.modeset_mutex); + drm_client_for_each_modeset(mode_set, &fb_helper->client) { +- mode_set->x = x; +- mode_set->y = y; ++ mode_set->x += dx; ++ mode_set->y += dy; + } + mutex_unlock(&fb_helper->client.modeset_mutex); + } +@@ -1377,16 +1377,18 @@ static int pan_display_atomic(struct fb_var_screeninfo *var, + struct fb_info *info) + { + struct drm_fb_helper *fb_helper = info->par; +- int ret; ++ int ret, dx, dy; + +- pan_set(fb_helper, var->xoffset, var->yoffset); ++ dx = var->xoffset - info->var.xoffset; ++ dy = var->yoffset - info->var.yoffset; ++ pan_set(fb_helper, dx, dy); + + ret = drm_client_modeset_commit_locked(&fb_helper->client); + if (!ret) { + info->var.xoffset = var->xoffset; + info->var.yoffset = var->yoffset; + } else +- pan_set(fb_helper, info->var.xoffset, info->var.yoffset); ++ pan_set(fb_helper, -dx, -dy); + + return ret; + } +diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c +index 906133331a4424..c234f9245b1448 100644 +--- a/drivers/gpu/drm/exynos/exynos_hdmi.c ++++ b/drivers/gpu/drm/exynos/exynos_hdmi.c +@@ -1643,7 +1643,9 @@ static int hdmi_audio_get_eld(struct device *dev, void *data, uint8_t *buf, + struct hdmi_context *hdata = dev_get_drvdata(dev); + struct drm_connector *connector = &hdata->connector; + ++ mutex_lock(&connector->eld_mutex); + memcpy(buf, connector->eld, min(sizeof(connector->eld), len)); ++ mutex_unlock(&connector->eld_mutex); + + return 0; + } +diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c +index d557ecd4e1ebe1..18c27542eb3b93 100644 +--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c ++++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c +@@ -102,8 +102,6 @@ static const u32 icl_sdr_y_plane_formats[] = { + DRM_FORMAT_Y216, + DRM_FORMAT_XYUV8888, + DRM_FORMAT_XVYU2101010, +- DRM_FORMAT_XVYU12_16161616, +- DRM_FORMAT_XVYU16161616, + }; + + static const u32 icl_sdr_uv_plane_formats[] = { +@@ -130,8 +128,6 @@ static const u32 icl_sdr_uv_plane_formats[] = { + DRM_FORMAT_Y216, + DRM_FORMAT_XYUV8888, + DRM_FORMAT_XVYU2101010, +- DRM_FORMAT_XVYU12_16161616, +- DRM_FORMAT_XVYU16161616, + }; + + static const u32 icl_hdr_plane_formats[] = { +diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c +index 73a4a4eb29e086..ba0e45fe432854 100644 +--- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c ++++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c +@@ -209,8 +209,6 @@ static int shmem_get_pages(struct drm_i915_gem_object *obj) + struct address_space *mapping = obj->base.filp->f_mapping; + unsigned int max_segment = i915_sg_segment_size(i915->drm.dev); + struct sg_table *st; +- struct sgt_iter sgt_iter; +- struct page *page; + int ret; + + /* +@@ -239,9 +237,7 @@ static int shmem_get_pages(struct drm_i915_gem_object *obj) + * for PAGE_SIZE chunks instead may be helpful. + */ + if (max_segment > PAGE_SIZE) { +- for_each_sgt_page(page, sgt_iter, st) +- put_page(page); +- sg_free_table(st); ++ shmem_sg_free_table(st, mapping, false, false); + kfree(st); + + max_segment = PAGE_SIZE; +diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +index ccaf9437cd0d2d..9f8afffbfccb17 100644 +--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c ++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +@@ -5154,12 +5154,20 @@ static inline void guc_log_context(struct drm_printer *p, + { + drm_printf(p, "GuC lrc descriptor %u:\n", ce->guc_id.id); + drm_printf(p, "\tHW Context Desc: 0x%08x\n", ce->lrc.lrca); +- drm_printf(p, "\t\tLRC Head: Internal %u, Memory %u\n", +- ce->ring->head, +- ce->lrc_reg_state[CTX_RING_HEAD]); +- drm_printf(p, "\t\tLRC Tail: Internal %u, Memory %u\n", +- ce->ring->tail, +- ce->lrc_reg_state[CTX_RING_TAIL]); ++ if (intel_context_pin_if_active(ce)) { ++ drm_printf(p, "\t\tLRC Head: Internal %u, Memory %u\n", ++ ce->ring->head, ++ ce->lrc_reg_state[CTX_RING_HEAD]); ++ drm_printf(p, "\t\tLRC Tail: Internal %u, Memory %u\n", ++ ce->ring->tail, ++ ce->lrc_reg_state[CTX_RING_TAIL]); ++ intel_context_unpin(ce); ++ } else { ++ drm_printf(p, "\t\tLRC Head: Internal %u, Memory not pinned\n", ++ ce->ring->head); ++ drm_printf(p, "\t\tLRC Tail: Internal %u, Memory not pinned\n", ++ ce->ring->tail); ++ } + drm_printf(p, "\t\tContext Pin Count: %u\n", + atomic_read(&ce->pin_count)); + drm_printf(p, "\t\tGuC ID Ref Count: %u\n", +diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c +index fc22fe709b9c1b..da37a827337bc5 100644 +--- a/drivers/gpu/drm/radeon/radeon_audio.c ++++ b/drivers/gpu/drm/radeon/radeon_audio.c +@@ -773,8 +773,10 @@ static int radeon_audio_component_get_eld(struct device *kdev, int port, + if (!dig->pin || dig->pin->id != port) + continue; + *enabled = true; ++ mutex_lock(&connector->eld_mutex); + ret = drm_eld_size(connector->eld); + memcpy(buf, connector->eld, min(max_bytes, ret)); ++ mutex_unlock(&connector->eld_mutex); + break; + } + +diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c +index fca403ccce47eb..3fd55eafdf106b 100644 +--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c ++++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c +@@ -946,9 +946,6 @@ static void cdn_dp_pd_event_work(struct work_struct *work) + { + struct cdn_dp_device *dp = container_of(work, struct cdn_dp_device, + event_work); +- struct drm_connector *connector = &dp->connector; +- enum drm_connector_status old_status; +- + int ret; + + mutex_lock(&dp->lock); +@@ -1010,11 +1007,7 @@ static void cdn_dp_pd_event_work(struct work_struct *work) + + out: + mutex_unlock(&dp->lock); +- +- old_status = connector->status; +- connector->status = connector->funcs->detect(connector, false); +- if (old_status != connector->status) +- drm_kms_helper_hotplug_event(dp->drm_dev); ++ drm_connector_helper_hpd_irq_event(&dp->connector); + } + + static int cdn_dp_pd_event(struct notifier_block *nb, +diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c +index 500936d5743c52..90c68e0f493fb5 100644 +--- a/drivers/gpu/drm/sti/sti_hdmi.c ++++ b/drivers/gpu/drm/sti/sti_hdmi.c +@@ -1221,7 +1221,9 @@ static int hdmi_audio_get_eld(struct device *dev, void *data, uint8_t *buf, size + struct drm_connector *connector = hdmi->drm_connector; + + DRM_DEBUG_DRIVER("\n"); ++ mutex_lock(&connector->eld_mutex); + memcpy(buf, connector->eld, min(sizeof(connector->eld), len)); ++ mutex_unlock(&connector->eld_mutex); + + return 0; + } +diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c +index 1727d447786f14..541aba80c14492 100644 +--- a/drivers/gpu/drm/vc4/vc4_hdmi.c ++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c +@@ -2655,9 +2655,9 @@ static int vc4_hdmi_audio_get_eld(struct device *dev, void *data, + struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev); + struct drm_connector *connector = &vc4_hdmi->connector; + +- mutex_lock(&vc4_hdmi->mutex); ++ mutex_lock(&connector->eld_mutex); + memcpy(buf, connector->eld, min(sizeof(connector->eld), len)); +- mutex_unlock(&vc4_hdmi->mutex); ++ mutex_unlock(&connector->eld_mutex); + + return 0; + } +diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h +index 4126c384286bff..61fd37f95fbd9f 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_drv.h ++++ b/drivers/gpu/drm/virtio/virtgpu_drv.h +@@ -191,6 +191,13 @@ struct virtio_gpu_framebuffer { + #define to_virtio_gpu_framebuffer(x) \ + container_of(x, struct virtio_gpu_framebuffer, base) + ++struct virtio_gpu_plane_state { ++ struct drm_plane_state base; ++ struct virtio_gpu_fence *fence; ++}; ++#define to_virtio_gpu_plane_state(x) \ ++ container_of(x, struct virtio_gpu_plane_state, base) ++ + struct virtio_gpu_queue { + struct virtqueue *vq; + spinlock_t qlock; +diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c +index a1ef657eba0774..36de73e03bbfa2 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_plane.c ++++ b/drivers/gpu/drm/virtio/virtgpu_plane.c +@@ -66,11 +66,28 @@ uint32_t virtio_gpu_translate_format(uint32_t drm_fourcc) + return format; + } + ++static struct ++drm_plane_state *virtio_gpu_plane_duplicate_state(struct drm_plane *plane) ++{ ++ struct virtio_gpu_plane_state *new; ++ ++ if (WARN_ON(!plane->state)) ++ return NULL; ++ ++ new = kzalloc(sizeof(*new), GFP_KERNEL); ++ if (!new) ++ return NULL; ++ ++ __drm_atomic_helper_plane_duplicate_state(plane, &new->base); ++ ++ return &new->base; ++} ++ + static const struct drm_plane_funcs virtio_gpu_plane_funcs = { + .update_plane = drm_atomic_helper_update_plane, + .disable_plane = drm_atomic_helper_disable_plane, + .reset = drm_atomic_helper_plane_reset, +- .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, ++ .atomic_duplicate_state = virtio_gpu_plane_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, + }; + +@@ -138,11 +155,13 @@ static void virtio_gpu_resource_flush(struct drm_plane *plane, + struct drm_device *dev = plane->dev; + struct virtio_gpu_device *vgdev = dev->dev_private; + struct virtio_gpu_framebuffer *vgfb; ++ struct virtio_gpu_plane_state *vgplane_st; + struct virtio_gpu_object *bo; + + vgfb = to_virtio_gpu_framebuffer(plane->state->fb); ++ vgplane_st = to_virtio_gpu_plane_state(plane->state); + bo = gem_to_virtio_gpu_obj(vgfb->base.obj[0]); +- if (vgfb->fence) { ++ if (vgplane_st->fence) { + struct virtio_gpu_object_array *objs; + + objs = virtio_gpu_array_alloc(1); +@@ -151,13 +170,11 @@ static void virtio_gpu_resource_flush(struct drm_plane *plane, + virtio_gpu_array_add_obj(objs, vgfb->base.obj[0]); + virtio_gpu_array_lock_resv(objs); + virtio_gpu_cmd_resource_flush(vgdev, bo->hw_res_handle, x, y, +- width, height, objs, vgfb->fence); ++ width, height, objs, ++ vgplane_st->fence); + virtio_gpu_notify(vgdev); +- +- dma_fence_wait_timeout(&vgfb->fence->f, true, ++ dma_fence_wait_timeout(&vgplane_st->fence->f, true, + msecs_to_jiffies(50)); +- dma_fence_put(&vgfb->fence->f); +- vgfb->fence = NULL; + } else { + virtio_gpu_cmd_resource_flush(vgdev, bo->hw_res_handle, x, y, + width, height, NULL, NULL); +@@ -247,20 +264,23 @@ static int virtio_gpu_plane_prepare_fb(struct drm_plane *plane, + struct drm_device *dev = plane->dev; + struct virtio_gpu_device *vgdev = dev->dev_private; + struct virtio_gpu_framebuffer *vgfb; ++ struct virtio_gpu_plane_state *vgplane_st; + struct virtio_gpu_object *bo; + + if (!new_state->fb) + return 0; + + vgfb = to_virtio_gpu_framebuffer(new_state->fb); ++ vgplane_st = to_virtio_gpu_plane_state(new_state); + bo = gem_to_virtio_gpu_obj(vgfb->base.obj[0]); + if (!bo || (plane->type == DRM_PLANE_TYPE_PRIMARY && !bo->guest_blob)) + return 0; + +- if (bo->dumb && (plane->state->fb != new_state->fb)) { +- vgfb->fence = virtio_gpu_fence_alloc(vgdev, vgdev->fence_drv.context, ++ if (bo->dumb) { ++ vgplane_st->fence = virtio_gpu_fence_alloc(vgdev, ++ vgdev->fence_drv.context, + 0); +- if (!vgfb->fence) ++ if (!vgplane_st->fence) + return -ENOMEM; + } + +@@ -270,15 +290,15 @@ static int virtio_gpu_plane_prepare_fb(struct drm_plane *plane, + static void virtio_gpu_plane_cleanup_fb(struct drm_plane *plane, + struct drm_plane_state *state) + { +- struct virtio_gpu_framebuffer *vgfb; ++ struct virtio_gpu_plane_state *vgplane_st; + + if (!state->fb) + return; + +- vgfb = to_virtio_gpu_framebuffer(state->fb); +- if (vgfb->fence) { +- dma_fence_put(&vgfb->fence->f); +- vgfb->fence = NULL; ++ vgplane_st = to_virtio_gpu_plane_state(state); ++ if (vgplane_st->fence) { ++ dma_fence_put(&vgplane_st->fence->f); ++ vgplane_st->fence = NULL; + } + } + +@@ -291,6 +311,7 @@ static void virtio_gpu_cursor_plane_update(struct drm_plane *plane, + struct virtio_gpu_device *vgdev = dev->dev_private; + struct virtio_gpu_output *output = NULL; + struct virtio_gpu_framebuffer *vgfb; ++ struct virtio_gpu_plane_state *vgplane_st; + struct virtio_gpu_object *bo = NULL; + uint32_t handle; + +@@ -303,6 +324,7 @@ static void virtio_gpu_cursor_plane_update(struct drm_plane *plane, + + if (plane->state->fb) { + vgfb = to_virtio_gpu_framebuffer(plane->state->fb); ++ vgplane_st = to_virtio_gpu_plane_state(plane->state); + bo = gem_to_virtio_gpu_obj(vgfb->base.obj[0]); + handle = bo->hw_res_handle; + } else { +@@ -322,11 +344,9 @@ static void virtio_gpu_cursor_plane_update(struct drm_plane *plane, + (vgdev, 0, + plane->state->crtc_w, + plane->state->crtc_h, +- 0, 0, objs, vgfb->fence); ++ 0, 0, objs, vgplane_st->fence); + virtio_gpu_notify(vgdev); +- dma_fence_wait(&vgfb->fence->f, true); +- dma_fence_put(&vgfb->fence->f); +- vgfb->fence = NULL; ++ dma_fence_wait(&vgplane_st->fence->f, true); + } + + if (plane->state->fb != old_state->fb) { +diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c +index 26e93a331a5107..3cd00afa453a6d 100644 +--- a/drivers/hid/hid-sensor-hub.c ++++ b/drivers/hid/hid-sensor-hub.c +@@ -730,23 +730,30 @@ static int sensor_hub_probe(struct hid_device *hdev, + return ret; + } + ++static int sensor_hub_finalize_pending_fn(struct device *dev, void *data) ++{ ++ struct hid_sensor_hub_device *hsdev = dev->platform_data; ++ ++ if (hsdev->pending.status) ++ complete(&hsdev->pending.ready); ++ ++ return 0; ++} ++ + static void sensor_hub_remove(struct hid_device *hdev) + { + struct sensor_hub_data *data = hid_get_drvdata(hdev); + unsigned long flags; +- int i; + + hid_dbg(hdev, " hardware removed\n"); + hid_hw_close(hdev); + hid_hw_stop(hdev); ++ + spin_lock_irqsave(&data->lock, flags); +- for (i = 0; i < data->hid_sensor_client_cnt; ++i) { +- struct hid_sensor_hub_device *hsdev = +- data->hid_sensor_hub_client_devs[i].platform_data; +- if (hsdev->pending.status) +- complete(&hsdev->pending.ready); +- } ++ device_for_each_child(&hdev->dev, NULL, ++ sensor_hub_finalize_pending_fn); + spin_unlock_irqrestore(&data->lock, flags); ++ + mfd_remove_devices(&hdev->dev); + mutex_destroy(&data->mutex); + } +diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c +index 33466c71c9da78..dd44373ba930e2 100644 +--- a/drivers/hid/wacom_wac.c ++++ b/drivers/hid/wacom_wac.c +@@ -4911,6 +4911,10 @@ static const struct wacom_features wacom_features_0x94 = + HID_DEVICE(BUS_I2C, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\ + .driver_data = (kernel_ulong_t)&wacom_features_##prod + ++#define PCI_DEVICE_WACOM(prod) \ ++ HID_DEVICE(BUS_PCI, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\ ++ .driver_data = (kernel_ulong_t)&wacom_features_##prod ++ + #define USB_DEVICE_LENOVO(prod) \ + HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, prod), \ + .driver_data = (kernel_ulong_t)&wacom_features_##prod +@@ -5080,6 +5084,7 @@ const struct hid_device_id wacom_ids[] = { + + { USB_DEVICE_WACOM(HID_ANY_ID) }, + { I2C_DEVICE_WACOM(HID_ANY_ID) }, ++ { PCI_DEVICE_WACOM(HID_ANY_ID) }, + { BT_DEVICE_WACOM(HID_ANY_ID) }, + { } + }; +diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c +index 14ae0cfc325efb..d2499f302b5083 100644 +--- a/drivers/i2c/i2c-core-acpi.c ++++ b/drivers/i2c/i2c-core-acpi.c +@@ -355,6 +355,25 @@ static const struct acpi_device_id i2c_acpi_force_400khz_device_ids[] = { + {} + }; + ++static const struct acpi_device_id i2c_acpi_force_100khz_device_ids[] = { ++ /* ++ * When a 400KHz freq is used on this model of ELAN touchpad in Linux, ++ * excessive smoothing (similar to when the touchpad's firmware detects ++ * a noisy signal) is sometimes applied. As some devices' (e.g, Lenovo ++ * V15 G4) ACPI tables specify a 400KHz frequency for this device and ++ * some I2C busses (e.g, Designware I2C) default to a 400KHz freq, ++ * force the speed to 100KHz as a workaround. ++ * ++ * For future investigation: This problem may be related to the default ++ * HCNT/LCNT values given by some busses' drivers, because they are not ++ * specified in the aforementioned devices' ACPI tables, and because ++ * the device works without issues on Windows at what is expected to be ++ * a 400KHz frequency. The root cause of the issue is not known. ++ */ ++ { "ELAN06FA", 0 }, ++ {} ++}; ++ + static acpi_status i2c_acpi_lookup_speed(acpi_handle handle, u32 level, + void *data, void **return_value) + { +@@ -373,6 +392,9 @@ static acpi_status i2c_acpi_lookup_speed(acpi_handle handle, u32 level, + if (acpi_match_device_ids(adev, i2c_acpi_force_400khz_device_ids) == 0) + lookup->force_speed = I2C_MAX_FAST_MODE_FREQ; + ++ if (acpi_match_device_ids(adev, i2c_acpi_force_100khz_device_ids) == 0) ++ lookup->force_speed = I2C_MAX_STANDARD_MODE_FREQ; ++ + return AE_OK; + } + +diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c +index 1750b315e97011..c073ee74e3dabb 100644 +--- a/drivers/i3c/master.c ++++ b/drivers/i3c/master.c +@@ -1878,7 +1878,7 @@ static int i3c_master_bus_init(struct i3c_master_controller *master) + goto err_bus_cleanup; + + if (master->ops->set_speed) { +- master->ops->set_speed(master, I3C_OPEN_DRAIN_NORMAL_SPEED); ++ ret = master->ops->set_speed(master, I3C_OPEN_DRAIN_NORMAL_SPEED); + if (ret) + goto err_bus_cleanup; + } +diff --git a/drivers/iio/light/as73211.c b/drivers/iio/light/as73211.c +index ec97a3a468392d..c1f9604c27141e 100644 +--- a/drivers/iio/light/as73211.c ++++ b/drivers/iio/light/as73211.c +@@ -154,6 +154,12 @@ struct as73211_data { + BIT(AS73211_SCAN_INDEX_TEMP) | \ + AS73211_SCAN_MASK_COLOR) + ++static const unsigned long as73211_scan_masks[] = { ++ AS73211_SCAN_MASK_COLOR, ++ AS73211_SCAN_MASK_ALL, ++ 0 ++}; ++ + static const struct iio_chan_spec as73211_channels[] = { + { + .type = IIO_TEMP, +@@ -602,9 +608,12 @@ static irqreturn_t as73211_trigger_handler(int irq __always_unused, void *p) + + /* AS73211 starts reading at address 2 */ + ret = i2c_master_recv(data->client, +- (char *)&scan.chan[1], 3 * sizeof(scan.chan[1])); ++ (char *)&scan.chan[0], 3 * sizeof(scan.chan[0])); + if (ret < 0) + goto done; ++ ++ /* Avoid pushing uninitialized data */ ++ scan.chan[3] = 0; + } + + if (data_result) { +@@ -612,9 +621,15 @@ static irqreturn_t as73211_trigger_handler(int irq __always_unused, void *p) + * Saturate all channels (in case of overflows). Temperature channel + * is not affected by overflows. + */ +- scan.chan[1] = cpu_to_le16(U16_MAX); +- scan.chan[2] = cpu_to_le16(U16_MAX); +- scan.chan[3] = cpu_to_le16(U16_MAX); ++ if (*indio_dev->active_scan_mask == AS73211_SCAN_MASK_ALL) { ++ scan.chan[1] = cpu_to_le16(U16_MAX); ++ scan.chan[2] = cpu_to_le16(U16_MAX); ++ scan.chan[3] = cpu_to_le16(U16_MAX); ++ } else { ++ scan.chan[0] = cpu_to_le16(U16_MAX); ++ scan.chan[1] = cpu_to_le16(U16_MAX); ++ scan.chan[2] = cpu_to_le16(U16_MAX); ++ } + } + + iio_push_to_buffers_with_timestamp(indio_dev, &scan, iio_get_time_ns(indio_dev)); +@@ -684,6 +699,7 @@ static int as73211_probe(struct i2c_client *client) + indio_dev->channels = as73211_channels; + indio_dev->num_channels = ARRAY_SIZE(as73211_channels); + indio_dev->modes = INDIO_DIRECT_MODE; ++ indio_dev->available_scan_masks = as73211_scan_masks; + + ret = i2c_smbus_read_byte_data(data->client, AS73211_REG_OSR); + if (ret < 0) +diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +index 68b81f9c2f4b17..6cecbac0e6babf 100644 +--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c ++++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +@@ -3875,7 +3875,7 @@ static int arm_smmu_device_probe(struct platform_device *pdev) + /* Initialise in-memory data structures */ + ret = arm_smmu_init_structures(smmu); + if (ret) +- return ret; ++ goto err_free_iopf; + + /* Record our private device structure */ + platform_set_drvdata(pdev, smmu); +@@ -3886,22 +3886,29 @@ static int arm_smmu_device_probe(struct platform_device *pdev) + /* Reset the device */ + ret = arm_smmu_device_reset(smmu, bypass); + if (ret) +- return ret; ++ goto err_disable; + + /* And we're up. Go go go! */ + ret = iommu_device_sysfs_add(&smmu->iommu, dev, NULL, + "smmu3.%pa", &ioaddr); + if (ret) +- return ret; ++ goto err_disable; + + ret = iommu_device_register(&smmu->iommu, &arm_smmu_ops, dev); + if (ret) { + dev_err(dev, "Failed to register iommu\n"); +- iommu_device_sysfs_remove(&smmu->iommu); +- return ret; ++ goto err_free_sysfs; + } + + return 0; ++ ++err_free_sysfs: ++ iommu_device_sysfs_remove(&smmu->iommu); ++err_disable: ++ arm_smmu_device_disable(smmu); ++err_free_iopf: ++ iopf_queue_free(smmu->evtq.iopf); ++ return ret; + } + + static void arm_smmu_device_remove(struct platform_device *pdev) +diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +index d4915893601979..e6b4bab0dde2e5 100644 +--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c ++++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +@@ -554,6 +554,7 @@ static const struct of_device_id __maybe_unused qcom_smmu_impl_of_match[] = { + { .compatible = "qcom,sc8180x-smmu-500", .data = &qcom_smmu_500_impl0_data }, + { .compatible = "qcom,sc8280xp-smmu-500", .data = &qcom_smmu_500_impl0_data }, + { .compatible = "qcom,sdm630-smmu-v2", .data = &qcom_smmu_v2_data }, ++ { .compatible = "qcom,sdm670-smmu-v2", .data = &qcom_smmu_v2_data }, + { .compatible = "qcom,sdm845-smmu-v2", .data = &qcom_smmu_v2_data }, + { .compatible = "qcom,sdm845-smmu-500", .data = &sdm845_smmu_500_data }, + { .compatible = "qcom,sm6115-smmu-500", .data = &qcom_smmu_500_impl0_data}, +diff --git a/drivers/irqchip/irq-apple-aic.c b/drivers/irqchip/irq-apple-aic.c +index 5c534d9fd2b00d..08d3ff8dba0060 100644 +--- a/drivers/irqchip/irq-apple-aic.c ++++ b/drivers/irqchip/irq-apple-aic.c +@@ -563,7 +563,8 @@ static void __exception_irq_entry aic_handle_fiq(struct pt_regs *regs) + AIC_FIQ_HWIRQ(AIC_TMR_EL02_VIRT)); + } + +- if (read_sysreg_s(SYS_IMP_APL_PMCR0_EL1) & PMCR0_IACT) { ++ if ((read_sysreg_s(SYS_IMP_APL_PMCR0_EL1) & (PMCR0_IMODE | PMCR0_IACT)) == ++ (FIELD_PREP(PMCR0_IMODE, PMCR0_IMODE_FIQ) | PMCR0_IACT)) { + int irq; + if (cpumask_test_cpu(smp_processor_id(), + &aic_irqc->fiq_aff[AIC_CPU_PMU_P]->aff)) +diff --git a/drivers/leds/leds-lp8860.c b/drivers/leds/leds-lp8860.c +index 19b621012e582f..03d3ca414a75db 100644 +--- a/drivers/leds/leds-lp8860.c ++++ b/drivers/leds/leds-lp8860.c +@@ -265,7 +265,7 @@ static int lp8860_init(struct lp8860_led *led) + goto out; + } + +- reg_count = ARRAY_SIZE(lp8860_eeprom_disp_regs) / sizeof(lp8860_eeprom_disp_regs[0]); ++ reg_count = ARRAY_SIZE(lp8860_eeprom_disp_regs); + for (i = 0; i < reg_count; i++) { + ret = regmap_write(led->eeprom_regmap, + lp8860_eeprom_disp_regs[i].reg, +diff --git a/drivers/mailbox/tegra-hsp.c b/drivers/mailbox/tegra-hsp.c +index fe29fc2ca5260d..694550fdfddddb 100644 +--- a/drivers/mailbox/tegra-hsp.c ++++ b/drivers/mailbox/tegra-hsp.c +@@ -388,7 +388,6 @@ static void tegra_hsp_sm_recv32(struct tegra_hsp_channel *channel) + value = tegra_hsp_channel_readl(channel, HSP_SM_SHRD_MBOX); + value &= ~HSP_SM_SHRD_MBOX_FULL; + msg = (void *)(unsigned long)value; +- mbox_chan_received_data(channel->chan, msg); + + /* + * Need to clear all bits here since some producers, such as TCU, depend +@@ -398,6 +397,8 @@ static void tegra_hsp_sm_recv32(struct tegra_hsp_channel *channel) + * explicitly, so we have to make sure we cover all possible cases. + */ + tegra_hsp_channel_writel(channel, 0x0, HSP_SM_SHRD_MBOX); ++ ++ mbox_chan_received_data(channel->chan, msg); + } + + static const struct tegra_hsp_sm_ops tegra_hsp_sm_32bit_ops = { +@@ -433,7 +434,6 @@ static void tegra_hsp_sm_recv128(struct tegra_hsp_channel *channel) + value[3] = tegra_hsp_channel_readl(channel, HSP_SHRD_MBOX_TYPE1_DATA3); + + msg = (void *)(unsigned long)value; +- mbox_chan_received_data(channel->chan, msg); + + /* + * Clear data registers and tag. +@@ -443,6 +443,8 @@ static void tegra_hsp_sm_recv128(struct tegra_hsp_channel *channel) + tegra_hsp_channel_writel(channel, 0x0, HSP_SHRD_MBOX_TYPE1_DATA2); + tegra_hsp_channel_writel(channel, 0x0, HSP_SHRD_MBOX_TYPE1_DATA3); + tegra_hsp_channel_writel(channel, 0x0, HSP_SHRD_MBOX_TYPE1_TAG); ++ ++ mbox_chan_received_data(channel->chan, msg); + } + + static const struct tegra_hsp_sm_ops tegra_hsp_sm_128bit_ops = { +diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c +index aa6bb5b4704ba6..1ff16b8264cbdf 100644 +--- a/drivers/md/dm-crypt.c ++++ b/drivers/md/dm-crypt.c +@@ -57,6 +57,7 @@ struct convert_context { + struct bio *bio_out; + struct bvec_iter iter_out; + atomic_t cc_pending; ++ unsigned int tag_offset; + u64 cc_sector; + union { + struct skcipher_request *req; +@@ -1232,6 +1233,7 @@ static void crypt_convert_init(struct crypt_config *cc, + if (bio_out) + ctx->iter_out = bio_out->bi_iter; + ctx->cc_sector = sector + cc->iv_offset; ++ ctx->tag_offset = 0; + init_completion(&ctx->restart); + } + +@@ -1564,7 +1566,6 @@ static void crypt_free_req(struct crypt_config *cc, void *req, struct bio *base_ + static blk_status_t crypt_convert(struct crypt_config *cc, + struct convert_context *ctx, bool atomic, bool reset_pending) + { +- unsigned int tag_offset = 0; + unsigned int sector_step = cc->sector_size >> SECTOR_SHIFT; + int r; + +@@ -1587,9 +1588,9 @@ static blk_status_t crypt_convert(struct crypt_config *cc, + atomic_inc(&ctx->cc_pending); + + if (crypt_integrity_aead(cc)) +- r = crypt_convert_block_aead(cc, ctx, ctx->r.req_aead, tag_offset); ++ r = crypt_convert_block_aead(cc, ctx, ctx->r.req_aead, ctx->tag_offset); + else +- r = crypt_convert_block_skcipher(cc, ctx, ctx->r.req, tag_offset); ++ r = crypt_convert_block_skcipher(cc, ctx, ctx->r.req, ctx->tag_offset); + + switch (r) { + /* +@@ -1609,8 +1610,8 @@ static blk_status_t crypt_convert(struct crypt_config *cc, + * exit and continue processing in a workqueue + */ + ctx->r.req = NULL; ++ ctx->tag_offset++; + ctx->cc_sector += sector_step; +- tag_offset++; + return BLK_STS_DEV_RESOURCE; + } + } else { +@@ -1624,8 +1625,8 @@ static blk_status_t crypt_convert(struct crypt_config *cc, + */ + case -EINPROGRESS: + ctx->r.req = NULL; ++ ctx->tag_offset++; + ctx->cc_sector += sector_step; +- tag_offset++; + continue; + /* + * The request was already processed (synchronously). +@@ -1633,7 +1634,7 @@ static blk_status_t crypt_convert(struct crypt_config *cc, + case 0: + atomic_dec(&ctx->cc_pending); + ctx->cc_sector += sector_step; +- tag_offset++; ++ ctx->tag_offset++; + if (!atomic) + cond_resched(); + continue; +@@ -2068,7 +2069,6 @@ static void kcryptd_crypt_write_continue(struct work_struct *work) + struct crypt_config *cc = io->cc; + struct convert_context *ctx = &io->ctx; + int crypt_finished; +- sector_t sector = io->sector; + blk_status_t r; + + wait_for_completion(&ctx->restart); +@@ -2085,10 +2085,8 @@ static void kcryptd_crypt_write_continue(struct work_struct *work) + } + + /* Encryption was already finished, submit io now */ +- if (crypt_finished) { ++ if (crypt_finished) + kcryptd_crypt_write_io_submit(io, 0); +- io->sector = sector; +- } + + crypt_dec_pending(io); + } +@@ -2099,14 +2097,13 @@ static void kcryptd_crypt_write_convert(struct dm_crypt_io *io) + struct convert_context *ctx = &io->ctx; + struct bio *clone; + int crypt_finished; +- sector_t sector = io->sector; + blk_status_t r; + + /* + * Prevent io from disappearing until this function completes. + */ + crypt_inc_pending(io); +- crypt_convert_init(cc, ctx, NULL, io->base_bio, sector); ++ crypt_convert_init(cc, ctx, NULL, io->base_bio, io->sector); + + clone = crypt_alloc_buffer(io, io->base_bio->bi_iter.bi_size); + if (unlikely(!clone)) { +@@ -2123,8 +2120,6 @@ static void kcryptd_crypt_write_convert(struct dm_crypt_io *io) + io->ctx.iter_in = clone->bi_iter; + } + +- sector += bio_sectors(clone); +- + crypt_inc_pending(io); + r = crypt_convert(cc, ctx, + test_bit(DM_CRYPT_NO_WRITE_WORKQUEUE, &cc->flags), true); +@@ -2148,10 +2143,8 @@ static void kcryptd_crypt_write_convert(struct dm_crypt_io *io) + } + + /* Encryption was already finished, submit io now */ +- if (crypt_finished) { ++ if (crypt_finished) + kcryptd_crypt_write_io_submit(io, 0); +- io->sector = sector; +- } + + dec: + crypt_dec_pending(io); +diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c +index 6f8fbd82e21c8f..92ee86ca80a63d 100644 +--- a/drivers/media/i2c/ccs/ccs-core.c ++++ b/drivers/media/i2c/ccs/ccs-core.c +@@ -3658,15 +3658,15 @@ static int ccs_probe(struct i2c_client *client) + out_cleanup: + ccs_cleanup(sensor); + ++out_free_ccs_limits: ++ kfree(sensor->ccs_limits); ++ + out_release_mdata: + kvfree(sensor->mdata.backing); + + out_release_sdata: + kvfree(sensor->sdata.backing); + +-out_free_ccs_limits: +- kfree(sensor->ccs_limits); +- + out_power_off: + ccs_power_off(&client->dev); + mutex_destroy(&sensor->mutex); +diff --git a/drivers/media/i2c/ccs/ccs-data.c b/drivers/media/i2c/ccs/ccs-data.c +index 08400edf77ced1..2591dba51e17e2 100644 +--- a/drivers/media/i2c/ccs/ccs-data.c ++++ b/drivers/media/i2c/ccs/ccs-data.c +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + + #include "ccs-data-defs.h" + +@@ -97,7 +98,7 @@ ccs_data_parse_length_specifier(const struct __ccs_data_length_specifier *__len, + plen = ((size_t) + (__len3->length[0] & + ((1 << CCS_DATA_LENGTH_SPECIFIER_SIZE_SHIFT) - 1)) +- << 16) + (__len3->length[0] << 8) + __len3->length[1]; ++ << 16) + (__len3->length[1] << 8) + __len3->length[2]; + break; + } + default: +@@ -948,15 +949,15 @@ int ccs_data_parse(struct ccs_data_container *ccsdata, const void *data, + + rval = __ccs_data_parse(&bin, ccsdata, data, len, dev, verbose); + if (rval) +- return rval; ++ goto out_cleanup; + + rval = bin_backing_alloc(&bin); + if (rval) +- return rval; ++ goto out_cleanup; + + rval = __ccs_data_parse(&bin, ccsdata, data, len, dev, false); + if (rval) +- goto out_free; ++ goto out_cleanup; + + if (verbose && ccsdata->version) + print_ccs_data_version(dev, ccsdata->version); +@@ -965,15 +966,16 @@ int ccs_data_parse(struct ccs_data_container *ccsdata, const void *data, + rval = -EPROTO; + dev_dbg(dev, "parsing mismatch; base %p; now %p; end %p\n", + bin.base, bin.now, bin.end); +- goto out_free; ++ goto out_cleanup; + } + + ccsdata->backing = bin.base; + + return 0; + +-out_free: ++out_cleanup: + kvfree(bin.base); ++ memset(ccsdata, 0, sizeof(*ccsdata)); + + return rval; + } +diff --git a/drivers/media/i2c/ds90ub913.c b/drivers/media/i2c/ds90ub913.c +index 4bfa3b3cf619b3..5a650facae4153 100644 +--- a/drivers/media/i2c/ds90ub913.c ++++ b/drivers/media/i2c/ds90ub913.c +@@ -792,7 +792,6 @@ static void ub913_subdev_uninit(struct ub913_data *priv) + v4l2_async_unregister_subdev(&priv->sd); + ub913_v4l2_nf_unregister(priv); + v4l2_subdev_cleanup(&priv->sd); +- fwnode_handle_put(priv->sd.fwnode); + media_entity_cleanup(&priv->sd.entity); + } + +diff --git a/drivers/media/i2c/ds90ub953.c b/drivers/media/i2c/ds90ub953.c +index dc394e22a42c43..1dd29137d2d9f2 100644 +--- a/drivers/media/i2c/ds90ub953.c ++++ b/drivers/media/i2c/ds90ub953.c +@@ -1290,7 +1290,6 @@ static void ub953_subdev_uninit(struct ub953_data *priv) + v4l2_async_unregister_subdev(&priv->sd); + ub953_v4l2_notifier_unregister(priv); + v4l2_subdev_cleanup(&priv->sd); +- fwnode_handle_put(priv->sd.fwnode); + media_entity_cleanup(&priv->sd.entity); + } + +diff --git a/drivers/media/i2c/ds90ub960.c b/drivers/media/i2c/ds90ub960.c +index 7f30e8923633ef..67714047588ac2 100644 +--- a/drivers/media/i2c/ds90ub960.c ++++ b/drivers/media/i2c/ds90ub960.c +@@ -352,6 +352,8 @@ + + #define UB960_SR_I2C_RX_ID(n) (0xf8 + (n)) /* < UB960_FPD_RX_NPORTS */ + ++#define UB9702_SR_REFCLK_FREQ 0x3d ++ + /* Indirect register blocks */ + #define UB960_IND_TARGET_PAT_GEN 0x00 + #define UB960_IND_TARGET_RX_ANA(n) (0x01 + (n)) +@@ -1575,16 +1577,24 @@ static int ub960_rxport_wait_locks(struct ub960_data *priv, + + ub960_rxport_read16(priv, nport, UB960_RR_RX_FREQ_HIGH, &v); + +- ret = ub960_rxport_get_strobe_pos(priv, nport, &strobe_pos); +- if (ret) +- return ret; ++ if (priv->hw_data->is_ub9702) { ++ dev_dbg(dev, "\trx%u: locked, freq %llu Hz\n", ++ nport, (v * 1000000ULL) >> 8); ++ } else { ++ ret = ub960_rxport_get_strobe_pos(priv, nport, ++ &strobe_pos); ++ if (ret) ++ return ret; + +- ret = ub960_rxport_get_eq_level(priv, nport, &eq_level); +- if (ret) +- return ret; ++ ret = ub960_rxport_get_eq_level(priv, nport, &eq_level); ++ if (ret) ++ return ret; + +- dev_dbg(dev, "\trx%u: locked, SP: %d, EQ: %u, freq %llu Hz\n", +- nport, strobe_pos, eq_level, (v * 1000000ULL) >> 8); ++ dev_dbg(dev, ++ "\trx%u: locked, SP: %d, EQ: %u, freq %llu Hz\n", ++ nport, strobe_pos, eq_level, ++ (v * 1000000ULL) >> 8); ++ } + } + + return 0; +@@ -2524,7 +2534,7 @@ static int ub960_configure_ports_for_streaming(struct ub960_data *priv, + for (i = 0; i < 8; i++) + ub960_rxport_write(priv, nport, + UB960_RR_VC_ID_MAP(i), +- nport); ++ (nport << 4) | nport); + } + + break; +@@ -2946,6 +2956,54 @@ static const struct v4l2_subdev_pad_ops ub960_pad_ops = { + .init_cfg = ub960_init_cfg, + }; + ++static void ub960_log_status_ub960_sp_eq(struct ub960_data *priv, ++ unsigned int nport) ++{ ++ struct device *dev = &priv->client->dev; ++ u8 eq_level; ++ s8 strobe_pos; ++ u8 v = 0; ++ ++ /* Strobe */ ++ ++ ub960_read(priv, UB960_XR_AEQ_CTL1, &v); ++ ++ dev_info(dev, "\t%s strobe\n", ++ (v & UB960_XR_AEQ_CTL1_AEQ_SFILTER_EN) ? "Adaptive" : ++ "Manual"); ++ ++ if (v & UB960_XR_AEQ_CTL1_AEQ_SFILTER_EN) { ++ ub960_read(priv, UB960_XR_SFILTER_CFG, &v); ++ ++ dev_info(dev, "\tStrobe range [%d, %d]\n", ++ ((v >> UB960_XR_SFILTER_CFG_SFILTER_MIN_SHIFT) & 0xf) - 7, ++ ((v >> UB960_XR_SFILTER_CFG_SFILTER_MAX_SHIFT) & 0xf) - 7); ++ } ++ ++ ub960_rxport_get_strobe_pos(priv, nport, &strobe_pos); ++ ++ dev_info(dev, "\tStrobe pos %d\n", strobe_pos); ++ ++ /* EQ */ ++ ++ ub960_rxport_read(priv, nport, UB960_RR_AEQ_BYPASS, &v); ++ ++ dev_info(dev, "\t%s EQ\n", ++ (v & UB960_RR_AEQ_BYPASS_ENABLE) ? "Manual" : ++ "Adaptive"); ++ ++ if (!(v & UB960_RR_AEQ_BYPASS_ENABLE)) { ++ ub960_rxport_read(priv, nport, UB960_RR_AEQ_MIN_MAX, &v); ++ ++ dev_info(dev, "\tEQ range [%u, %u]\n", ++ (v >> UB960_RR_AEQ_MIN_MAX_AEQ_FLOOR_SHIFT) & 0xf, ++ (v >> UB960_RR_AEQ_MIN_MAX_AEQ_MAX_SHIFT) & 0xf); ++ } ++ ++ if (ub960_rxport_get_eq_level(priv, nport, &eq_level) == 0) ++ dev_info(dev, "\tEQ level %u\n", eq_level); ++} ++ + static int ub960_log_status(struct v4l2_subdev *sd) + { + struct ub960_data *priv = sd_to_ub960(sd); +@@ -2993,8 +3051,6 @@ static int ub960_log_status(struct v4l2_subdev *sd) + + for (nport = 0; nport < priv->hw_data->num_rxports; nport++) { + struct ub960_rxport *rxport = priv->rxports[nport]; +- u8 eq_level; +- s8 strobe_pos; + unsigned int i; + + dev_info(dev, "RX %u\n", nport); +@@ -3030,44 +3086,8 @@ static int ub960_log_status(struct v4l2_subdev *sd) + ub960_rxport_read(priv, nport, UB960_RR_CSI_ERR_COUNTER, &v); + dev_info(dev, "\tcsi_err_counter %u\n", v); + +- /* Strobe */ +- +- ub960_read(priv, UB960_XR_AEQ_CTL1, &v); +- +- dev_info(dev, "\t%s strobe\n", +- (v & UB960_XR_AEQ_CTL1_AEQ_SFILTER_EN) ? "Adaptive" : +- "Manual"); +- +- if (v & UB960_XR_AEQ_CTL1_AEQ_SFILTER_EN) { +- ub960_read(priv, UB960_XR_SFILTER_CFG, &v); +- +- dev_info(dev, "\tStrobe range [%d, %d]\n", +- ((v >> UB960_XR_SFILTER_CFG_SFILTER_MIN_SHIFT) & 0xf) - 7, +- ((v >> UB960_XR_SFILTER_CFG_SFILTER_MAX_SHIFT) & 0xf) - 7); +- } +- +- ub960_rxport_get_strobe_pos(priv, nport, &strobe_pos); +- +- dev_info(dev, "\tStrobe pos %d\n", strobe_pos); +- +- /* EQ */ +- +- ub960_rxport_read(priv, nport, UB960_RR_AEQ_BYPASS, &v); +- +- dev_info(dev, "\t%s EQ\n", +- (v & UB960_RR_AEQ_BYPASS_ENABLE) ? "Manual" : +- "Adaptive"); +- +- if (!(v & UB960_RR_AEQ_BYPASS_ENABLE)) { +- ub960_rxport_read(priv, nport, UB960_RR_AEQ_MIN_MAX, &v); +- +- dev_info(dev, "\tEQ range [%u, %u]\n", +- (v >> UB960_RR_AEQ_MIN_MAX_AEQ_FLOOR_SHIFT) & 0xf, +- (v >> UB960_RR_AEQ_MIN_MAX_AEQ_MAX_SHIFT) & 0xf); +- } +- +- if (ub960_rxport_get_eq_level(priv, nport, &eq_level) == 0) +- dev_info(dev, "\tEQ level %u\n", eq_level); ++ if (!priv->hw_data->is_ub9702) ++ ub960_log_status_ub960_sp_eq(priv, nport); + + /* GPIOs */ + for (i = 0; i < UB960_NUM_BC_GPIOS; i++) { +@@ -3838,7 +3858,10 @@ static int ub960_enable_core_hw(struct ub960_data *priv) + if (ret) + goto err_pd_gpio; + +- ret = ub960_read(priv, UB960_XR_REFCLK_FREQ, &refclk_freq); ++ if (priv->hw_data->is_ub9702) ++ ret = ub960_read(priv, UB9702_SR_REFCLK_FREQ, &refclk_freq); ++ else ++ ret = ub960_read(priv, UB960_XR_REFCLK_FREQ, &refclk_freq); + if (ret) + goto err_pd_gpio; + +diff --git a/drivers/media/i2c/imx296.c b/drivers/media/i2c/imx296.c +index 3b4539b622b43b..330e7e149a620a 100644 +--- a/drivers/media/i2c/imx296.c ++++ b/drivers/media/i2c/imx296.c +@@ -960,6 +960,8 @@ static int imx296_identify_model(struct imx296 *sensor) + return ret; + } + ++ usleep_range(2000, 5000); ++ + ret = imx296_read(sensor, IMX296_SENSOR_INFO); + if (ret < 0) { + dev_err(sensor->dev, "failed to read sensor information (%d)\n", +diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c +index 40532f7bcabea8..b8a6acc30a252d 100644 +--- a/drivers/media/i2c/ov5640.c ++++ b/drivers/media/i2c/ov5640.c +@@ -1982,6 +1982,7 @@ static int ov5640_get_light_freq(struct ov5640_dev *sensor) + light_freq = 50; + } else { + /* 60Hz */ ++ light_freq = 60; + } + } + +diff --git a/drivers/media/platform/marvell/mmp-driver.c b/drivers/media/platform/marvell/mmp-driver.c +index 170907cc1885cf..f8d595c0687f72 100644 +--- a/drivers/media/platform/marvell/mmp-driver.c ++++ b/drivers/media/platform/marvell/mmp-driver.c +@@ -230,13 +230,23 @@ static int mmpcam_probe(struct platform_device *pdev) + + mcam_init_clk(mcam); + ++ /* ++ * Register with V4L. ++ */ ++ ++ ret = v4l2_device_register(mcam->dev, &mcam->v4l2_dev); ++ if (ret) ++ return ret; ++ + /* + * Create a match of the sensor against its OF node. + */ + ep = fwnode_graph_get_next_endpoint(of_fwnode_handle(pdev->dev.of_node), + NULL); +- if (!ep) +- return -ENODEV; ++ if (!ep) { ++ ret = -ENODEV; ++ goto out_v4l2_device_unregister; ++ } + + v4l2_async_nf_init(&mcam->notifier, &mcam->v4l2_dev); + +@@ -245,7 +255,7 @@ static int mmpcam_probe(struct platform_device *pdev) + fwnode_handle_put(ep); + if (IS_ERR(asd)) { + ret = PTR_ERR(asd); +- goto out; ++ goto out_v4l2_device_unregister; + } + + /* +@@ -253,7 +263,7 @@ static int mmpcam_probe(struct platform_device *pdev) + */ + ret = mccic_register(mcam); + if (ret) +- goto out; ++ goto out_v4l2_device_unregister; + + /* + * Add OF clock provider. +@@ -282,6 +292,8 @@ static int mmpcam_probe(struct platform_device *pdev) + return 0; + out: + mccic_shutdown(mcam); ++out_v4l2_device_unregister: ++ v4l2_device_unregister(&mcam->v4l2_dev); + + return ret; + } +@@ -292,6 +304,7 @@ static void mmpcam_remove(struct platform_device *pdev) + struct mcam_camera *mcam = &cam->mcam; + + mccic_shutdown(mcam); ++ v4l2_device_unregister(&mcam->v4l2_dev); + pm_runtime_force_suspend(mcam->dev); + } + +diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c +index 07158e9451fed1..ce70e96b8fb52e 100644 +--- a/drivers/media/usb/uvc/uvc_ctrl.c ++++ b/drivers/media/usb/uvc/uvc_ctrl.c +@@ -1593,10 +1593,8 @@ bool uvc_ctrl_status_event_async(struct urb *urb, struct uvc_video_chain *chain, + struct uvc_device *dev = chain->dev; + struct uvc_ctrl_work *w = &dev->async_ctrl; + +- if (list_empty(&ctrl->info.mappings)) { +- ctrl->handle = NULL; ++ if (list_empty(&ctrl->info.mappings)) + return false; +- } + + w->data = data; + w->urb = urb; +@@ -1626,13 +1624,13 @@ static void uvc_ctrl_send_events(struct uvc_fh *handle, + { + struct uvc_control_mapping *mapping; + struct uvc_control *ctrl; +- u32 changes = V4L2_EVENT_CTRL_CH_VALUE; + unsigned int i; + unsigned int j; + + for (i = 0; i < xctrls_count; ++i) { +- ctrl = uvc_find_control(handle->chain, xctrls[i].id, &mapping); ++ u32 changes = V4L2_EVENT_CTRL_CH_VALUE; + ++ ctrl = uvc_find_control(handle->chain, xctrls[i].id, &mapping); + if (ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS) + /* Notification will be sent from an Interrupt event. */ + continue; +diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c +index 1b05890f99f4f4..95c5b90f3e7c11 100644 +--- a/drivers/media/usb/uvc/uvc_driver.c ++++ b/drivers/media/usb/uvc/uvc_driver.c +@@ -775,27 +775,14 @@ static const u8 uvc_media_transport_input_guid[16] = + UVC_GUID_UVC_MEDIA_TRANSPORT_INPUT; + static const u8 uvc_processing_guid[16] = UVC_GUID_UVC_PROCESSING; + +-static struct uvc_entity *uvc_alloc_new_entity(struct uvc_device *dev, u16 type, +- u16 id, unsigned int num_pads, +- unsigned int extra_size) ++static struct uvc_entity *uvc_alloc_entity(u16 type, u16 id, ++ unsigned int num_pads, unsigned int extra_size) + { + struct uvc_entity *entity; + unsigned int num_inputs; + unsigned int size; + unsigned int i; + +- /* Per UVC 1.1+ spec 3.7.2, the ID should be non-zero. */ +- if (id == 0) { +- dev_err(&dev->udev->dev, "Found Unit with invalid ID 0.\n"); +- return ERR_PTR(-EINVAL); +- } +- +- /* Per UVC 1.1+ spec 3.7.2, the ID is unique. */ +- if (uvc_entity_by_id(dev, id)) { +- dev_err(&dev->udev->dev, "Found multiple Units with ID %u\n", id); +- return ERR_PTR(-EINVAL); +- } +- + extra_size = roundup(extra_size, sizeof(*entity->pads)); + if (num_pads) + num_inputs = type & UVC_TERM_OUTPUT ? num_pads : num_pads - 1; +@@ -805,7 +792,7 @@ static struct uvc_entity *uvc_alloc_new_entity(struct uvc_device *dev, u16 type, + + num_inputs; + entity = kzalloc(size, GFP_KERNEL); + if (entity == NULL) +- return ERR_PTR(-ENOMEM); ++ return NULL; + + entity->id = id; + entity->type = type; +@@ -917,10 +904,10 @@ static int uvc_parse_vendor_control(struct uvc_device *dev, + break; + } + +- unit = uvc_alloc_new_entity(dev, UVC_VC_EXTENSION_UNIT, +- buffer[3], p + 1, 2 * n); +- if (IS_ERR(unit)) +- return PTR_ERR(unit); ++ unit = uvc_alloc_entity(UVC_VC_EXTENSION_UNIT, buffer[3], ++ p + 1, 2*n); ++ if (unit == NULL) ++ return -ENOMEM; + + memcpy(unit->guid, &buffer[4], 16); + unit->extension.bNumControls = buffer[20]; +@@ -1029,10 +1016,10 @@ static int uvc_parse_standard_control(struct uvc_device *dev, + return -EINVAL; + } + +- term = uvc_alloc_new_entity(dev, type | UVC_TERM_INPUT, +- buffer[3], 1, n + p); +- if (IS_ERR(term)) +- return PTR_ERR(term); ++ term = uvc_alloc_entity(type | UVC_TERM_INPUT, buffer[3], ++ 1, n + p); ++ if (term == NULL) ++ return -ENOMEM; + + if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA) { + term->camera.bControlSize = n; +@@ -1088,10 +1075,10 @@ static int uvc_parse_standard_control(struct uvc_device *dev, + return 0; + } + +- term = uvc_alloc_new_entity(dev, type | UVC_TERM_OUTPUT, +- buffer[3], 1, 0); +- if (IS_ERR(term)) +- return PTR_ERR(term); ++ term = uvc_alloc_entity(type | UVC_TERM_OUTPUT, buffer[3], ++ 1, 0); ++ if (term == NULL) ++ return -ENOMEM; + + memcpy(term->baSourceID, &buffer[7], 1); + +@@ -1110,10 +1097,9 @@ static int uvc_parse_standard_control(struct uvc_device *dev, + return -EINVAL; + } + +- unit = uvc_alloc_new_entity(dev, buffer[2], buffer[3], +- p + 1, 0); +- if (IS_ERR(unit)) +- return PTR_ERR(unit); ++ unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, 0); ++ if (unit == NULL) ++ return -ENOMEM; + + memcpy(unit->baSourceID, &buffer[5], p); + +@@ -1133,9 +1119,9 @@ static int uvc_parse_standard_control(struct uvc_device *dev, + return -EINVAL; + } + +- unit = uvc_alloc_new_entity(dev, buffer[2], buffer[3], 2, n); +- if (IS_ERR(unit)) +- return PTR_ERR(unit); ++ unit = uvc_alloc_entity(buffer[2], buffer[3], 2, n); ++ if (unit == NULL) ++ return -ENOMEM; + + memcpy(unit->baSourceID, &buffer[4], 1); + unit->processing.wMaxMultiplier = +@@ -1162,10 +1148,9 @@ static int uvc_parse_standard_control(struct uvc_device *dev, + return -EINVAL; + } + +- unit = uvc_alloc_new_entity(dev, buffer[2], buffer[3], +- p + 1, n); +- if (IS_ERR(unit)) +- return PTR_ERR(unit); ++ unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, n); ++ if (unit == NULL) ++ return -ENOMEM; + + memcpy(unit->guid, &buffer[4], 16); + unit->extension.bNumControls = buffer[20]; +@@ -1295,20 +1280,19 @@ static int uvc_gpio_parse(struct uvc_device *dev) + struct gpio_desc *gpio_privacy; + int irq; + +- gpio_privacy = devm_gpiod_get_optional(&dev->udev->dev, "privacy", ++ gpio_privacy = devm_gpiod_get_optional(&dev->intf->dev, "privacy", + GPIOD_IN); + if (IS_ERR_OR_NULL(gpio_privacy)) + return PTR_ERR_OR_ZERO(gpio_privacy); + + irq = gpiod_to_irq(gpio_privacy); + if (irq < 0) +- return dev_err_probe(&dev->udev->dev, irq, ++ return dev_err_probe(&dev->intf->dev, irq, + "No IRQ for privacy GPIO\n"); + +- unit = uvc_alloc_new_entity(dev, UVC_EXT_GPIO_UNIT, +- UVC_EXT_GPIO_UNIT_ID, 0, 1); +- if (IS_ERR(unit)) +- return PTR_ERR(unit); ++ unit = uvc_alloc_entity(UVC_EXT_GPIO_UNIT, UVC_EXT_GPIO_UNIT_ID, 0, 1); ++ if (!unit) ++ return -ENOMEM; + + unit->gpio.gpio_privacy = gpio_privacy; + unit->gpio.irq = irq; +@@ -1329,15 +1313,27 @@ static int uvc_gpio_parse(struct uvc_device *dev) + static int uvc_gpio_init_irq(struct uvc_device *dev) + { + struct uvc_entity *unit = dev->gpio_unit; ++ int ret; + + if (!unit || unit->gpio.irq < 0) + return 0; + +- return devm_request_threaded_irq(&dev->udev->dev, unit->gpio.irq, NULL, +- uvc_gpio_irq, +- IRQF_ONESHOT | IRQF_TRIGGER_FALLING | +- IRQF_TRIGGER_RISING, +- "uvc_privacy_gpio", dev); ++ ret = request_threaded_irq(unit->gpio.irq, NULL, uvc_gpio_irq, ++ IRQF_ONESHOT | IRQF_TRIGGER_FALLING | ++ IRQF_TRIGGER_RISING, ++ "uvc_privacy_gpio", dev); ++ ++ unit->gpio.initialized = !ret; ++ ++ return ret; ++} ++ ++static void uvc_gpio_deinit(struct uvc_device *dev) ++{ ++ if (!dev->gpio_unit || !dev->gpio_unit->gpio.initialized) ++ return; ++ ++ free_irq(dev->gpio_unit->gpio.irq, dev); + } + + /* ------------------------------------------------------------------------ +@@ -1934,6 +1930,8 @@ static void uvc_unregister_video(struct uvc_device *dev) + { + struct uvc_streaming *stream; + ++ uvc_gpio_deinit(dev); ++ + list_for_each_entry(stream, &dev->streams, list) { + /* Nothing to do here, continue. */ + if (!video_is_registered(&stream->vdev)) +diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c +index 91c350b2541267..a2504e1e991b93 100644 +--- a/drivers/media/usb/uvc/uvc_video.c ++++ b/drivers/media/usb/uvc/uvc_video.c +@@ -79,6 +79,27 @@ int uvc_query_ctrl(struct uvc_device *dev, u8 query, u8 unit, + if (likely(ret == size)) + return 0; + ++ /* ++ * Some devices return shorter USB control packets than expected if the ++ * returned value can fit in less bytes. Zero all the bytes that the ++ * device has not written. ++ * ++ * This quirk is applied to all controls, regardless of their data type. ++ * Most controls are little-endian integers, in which case the missing ++ * bytes become 0 MSBs. For other data types, a different heuristic ++ * could be implemented if a device is found needing it. ++ * ++ * We exclude UVC_GET_INFO from the quirk. UVC_GET_LEN does not need ++ * to be excluded because its size is always 1. ++ */ ++ if (ret > 0 && query != UVC_GET_INFO) { ++ memset(data + ret, 0, size - ret); ++ dev_warn_once(&dev->udev->dev, ++ "UVC non compliance: %s control %u on unit %u returned %d bytes when we expected %u.\n", ++ uvc_query_name(query), cs, unit, ret, size); ++ return 0; ++ } ++ + if (ret != -EPIPE) { + dev_err(&dev->udev->dev, + "Failed to query (%s) UVC control %u on unit %u: %d (exp. %u).\n", +diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h +index e5b12717016fa3..997f4b5b5e22ac 100644 +--- a/drivers/media/usb/uvc/uvcvideo.h ++++ b/drivers/media/usb/uvc/uvcvideo.h +@@ -229,6 +229,7 @@ struct uvc_entity { + u8 *bmControls; + struct gpio_desc *gpio_privacy; + int irq; ++ bool initialized; + } gpio; + }; + +diff --git a/drivers/media/v4l2-core/v4l2-mc.c b/drivers/media/v4l2-core/v4l2-mc.c +index 52d349e72b8ca5..788a4ac3805751 100644 +--- a/drivers/media/v4l2-core/v4l2-mc.c ++++ b/drivers/media/v4l2-core/v4l2-mc.c +@@ -329,7 +329,7 @@ int v4l2_create_fwnode_links_to_pad(struct v4l2_subdev *src_sd, + if (!(sink->flags & MEDIA_PAD_FL_SINK)) + return -EINVAL; + +- fwnode_graph_for_each_endpoint(dev_fwnode(src_sd->dev), endpoint) { ++ fwnode_graph_for_each_endpoint(src_sd->fwnode, endpoint) { + struct fwnode_handle *remote_ep; + int src_idx, sink_idx, ret; + struct media_pad *src; +diff --git a/drivers/mfd/lpc_ich.c b/drivers/mfd/lpc_ich.c +index 7b1c597b6879fb..03367fcac42a7f 100644 +--- a/drivers/mfd/lpc_ich.c ++++ b/drivers/mfd/lpc_ich.c +@@ -756,8 +756,9 @@ static const struct pci_device_id lpc_ich_ids[] = { + { PCI_VDEVICE(INTEL, 0x2917), LPC_ICH9ME}, + { PCI_VDEVICE(INTEL, 0x2918), LPC_ICH9}, + { PCI_VDEVICE(INTEL, 0x2919), LPC_ICH9M}, +- { PCI_VDEVICE(INTEL, 0x3197), LPC_GLK}, + { PCI_VDEVICE(INTEL, 0x2b9c), LPC_COUGARMOUNTAIN}, ++ { PCI_VDEVICE(INTEL, 0x3197), LPC_GLK}, ++ { PCI_VDEVICE(INTEL, 0x31e8), LPC_GLK}, + { PCI_VDEVICE(INTEL, 0x3a14), LPC_ICH10DO}, + { PCI_VDEVICE(INTEL, 0x3a16), LPC_ICH10R}, + { PCI_VDEVICE(INTEL, 0x3a18), LPC_ICH10}, +diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c +index 4df0d7a0cd1184..fc021e265edc01 100644 +--- a/drivers/misc/fastrpc.c ++++ b/drivers/misc/fastrpc.c +@@ -988,7 +988,7 @@ static int fastrpc_get_args(u32 kernel, struct fastrpc_invoke_ctx *ctx) + mmap_read_lock(current->mm); + vma = find_vma(current->mm, ctx->args[i].ptr); + if (vma) +- pages[i].addr += ctx->args[i].ptr - ++ pages[i].addr += (ctx->args[i].ptr & PAGE_MASK) - + vma->vm_start; + mmap_read_unlock(current->mm); + +@@ -1015,8 +1015,8 @@ static int fastrpc_get_args(u32 kernel, struct fastrpc_invoke_ctx *ctx) + (pkt_size - rlen); + pages[i].addr = pages[i].addr & PAGE_MASK; + +- pg_start = (args & PAGE_MASK) >> PAGE_SHIFT; +- pg_end = ((args + len - 1) & PAGE_MASK) >> PAGE_SHIFT; ++ pg_start = (rpra[i].buf.pv & PAGE_MASK) >> PAGE_SHIFT; ++ pg_end = ((rpra[i].buf.pv + len - 1) & PAGE_MASK) >> PAGE_SHIFT; + pages[i].size = (pg_end - pg_start + 1) * PAGE_SIZE; + args = args + mlen; + rlen -= mlen; +@@ -2327,7 +2327,7 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev) + + err = fastrpc_device_register(rdev, data, false, domains[domain_id]); + if (err) +- goto fdev_error; ++ goto populate_error; + break; + default: + err = -EINVAL; +diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c +index 5914516df2f7fd..cb87e827377934 100644 +--- a/drivers/mmc/core/sdio.c ++++ b/drivers/mmc/core/sdio.c +@@ -458,6 +458,8 @@ static unsigned mmc_sdio_get_max_clock(struct mmc_card *card) + if (mmc_card_sd_combo(card)) + max_dtr = min(max_dtr, mmc_sd_get_max_clock(card)); + ++ max_dtr = min_not_zero(max_dtr, card->quirk_max_rate); ++ + return max_dtr; + } + +diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c +index 8716004fcf6c90..945d08531de376 100644 +--- a/drivers/mmc/host/sdhci-msm.c ++++ b/drivers/mmc/host/sdhci-msm.c +@@ -134,9 +134,18 @@ + /* Timeout value to avoid infinite waiting for pwr_irq */ + #define MSM_PWR_IRQ_TIMEOUT_MS 5000 + ++/* Max load for eMMC Vdd supply */ ++#define MMC_VMMC_MAX_LOAD_UA 570000 ++ + /* Max load for eMMC Vdd-io supply */ + #define MMC_VQMMC_MAX_LOAD_UA 325000 + ++/* Max load for SD Vdd supply */ ++#define SD_VMMC_MAX_LOAD_UA 800000 ++ ++/* Max load for SD Vdd-io supply */ ++#define SD_VQMMC_MAX_LOAD_UA 22000 ++ + #define msm_host_readl(msm_host, host, offset) \ + msm_host->var_ops->msm_readl_relaxed(host, offset) + +@@ -1403,11 +1412,48 @@ static int sdhci_msm_set_pincfg(struct sdhci_msm_host *msm_host, bool level) + return ret; + } + +-static int sdhci_msm_set_vmmc(struct mmc_host *mmc) ++static void msm_config_vmmc_regulator(struct mmc_host *mmc, bool hpm) ++{ ++ int load; ++ ++ if (!hpm) ++ load = 0; ++ else if (!mmc->card) ++ load = max(MMC_VMMC_MAX_LOAD_UA, SD_VMMC_MAX_LOAD_UA); ++ else if (mmc_card_mmc(mmc->card)) ++ load = MMC_VMMC_MAX_LOAD_UA; ++ else if (mmc_card_sd(mmc->card)) ++ load = SD_VMMC_MAX_LOAD_UA; ++ else ++ return; ++ ++ regulator_set_load(mmc->supply.vmmc, load); ++} ++ ++static void msm_config_vqmmc_regulator(struct mmc_host *mmc, bool hpm) ++{ ++ int load; ++ ++ if (!hpm) ++ load = 0; ++ else if (!mmc->card) ++ load = max(MMC_VQMMC_MAX_LOAD_UA, SD_VQMMC_MAX_LOAD_UA); ++ else if (mmc_card_sd(mmc->card)) ++ load = SD_VQMMC_MAX_LOAD_UA; ++ else ++ return; ++ ++ regulator_set_load(mmc->supply.vqmmc, load); ++} ++ ++static int sdhci_msm_set_vmmc(struct sdhci_msm_host *msm_host, ++ struct mmc_host *mmc, bool hpm) + { + if (IS_ERR(mmc->supply.vmmc)) + return 0; + ++ msm_config_vmmc_regulator(mmc, hpm); ++ + return mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, mmc->ios.vdd); + } + +@@ -1420,6 +1466,8 @@ static int msm_toggle_vqmmc(struct sdhci_msm_host *msm_host, + if (msm_host->vqmmc_enabled == level) + return 0; + ++ msm_config_vqmmc_regulator(mmc, level); ++ + if (level) { + /* Set the IO voltage regulator to default voltage level */ + if (msm_host->caps_0 & CORE_3_0V_SUPPORT) +@@ -1642,7 +1690,8 @@ static void sdhci_msm_handle_pwr_irq(struct sdhci_host *host, int irq) + } + + if (pwr_state) { +- ret = sdhci_msm_set_vmmc(mmc); ++ ret = sdhci_msm_set_vmmc(msm_host, mmc, ++ pwr_state & REQ_BUS_ON); + if (!ret) + ret = sdhci_msm_set_vqmmc(msm_host, mmc, + pwr_state & REQ_BUS_ON); +diff --git a/drivers/mtd/nand/onenand/onenand_base.c b/drivers/mtd/nand/onenand/onenand_base.c +index f66385faf631cd..0dc2ea4fc857b7 100644 +--- a/drivers/mtd/nand/onenand/onenand_base.c ++++ b/drivers/mtd/nand/onenand/onenand_base.c +@@ -2923,6 +2923,7 @@ static int do_otp_read(struct mtd_info *mtd, loff_t from, size_t len, + ret = ONENAND_IS_4KB_PAGE(this) ? + onenand_mlc_read_ops_nolock(mtd, from, &ops) : + onenand_read_ops_nolock(mtd, from, &ops); ++ *retlen = ops.retlen; + + /* Exit OTP access mode */ + this->command(mtd, ONENAND_CMD_RESET, 0, 0); +diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c +index 8ee51e49fced55..144aa76d13e904 100644 +--- a/drivers/mtd/ubi/build.c ++++ b/drivers/mtd/ubi/build.c +@@ -1462,7 +1462,7 @@ static int ubi_mtd_param_parse(const char *val, const struct kernel_param *kp) + if (token) { + int err = kstrtoint(token, 10, &p->ubi_num); + +- if (err) { ++ if (err || p->ubi_num < UBI_DEV_NUM_AUTO) { + pr_err("UBI error: bad value for ubi_num parameter: %s\n", + token); + return -EINVAL; +diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c +index d6d6d5d37ff3e6..c9b0d57696a487 100644 +--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c ++++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c +@@ -1441,7 +1441,9 @@ void aq_nic_deinit(struct aq_nic_s *self, bool link_down) + aq_ptp_ring_free(self); + aq_ptp_free(self); + +- if (likely(self->aq_fw_ops->deinit) && link_down) { ++ /* May be invoked during hot unplug. */ ++ if (pci_device_is_present(self->pdev) && ++ likely(self->aq_fw_ops->deinit) && link_down) { + mutex_lock(&self->fwreq_mutex); + self->aq_fw_ops->deinit(self->aq_hw); + mutex_unlock(&self->fwreq_mutex); +diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c +index 0715ea5bf13ed9..3b082114f2e538 100644 +--- a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c ++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c +@@ -41,9 +41,12 @@ void bcmgenet_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) + { + struct bcmgenet_priv *priv = netdev_priv(dev); + struct device *kdev = &priv->pdev->dev; ++ u32 phy_wolopts = 0; + +- if (dev->phydev) ++ if (dev->phydev) { + phy_ethtool_get_wol(dev->phydev, wol); ++ phy_wolopts = wol->wolopts; ++ } + + /* MAC is not wake-up capable, return what the PHY does */ + if (!device_can_wakeup(kdev)) +@@ -51,9 +54,14 @@ void bcmgenet_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) + + /* Overlay MAC capabilities with that of the PHY queried before */ + wol->supported |= WAKE_MAGIC | WAKE_MAGICSECURE | WAKE_FILTER; +- wol->wolopts = priv->wolopts; +- memset(wol->sopass, 0, sizeof(wol->sopass)); ++ wol->wolopts |= priv->wolopts; + ++ /* Return the PHY configured magic password */ ++ if (phy_wolopts & WAKE_MAGICSECURE) ++ return; ++ ++ /* Otherwise the MAC one */ ++ memset(wol->sopass, 0, sizeof(wol->sopass)); + if (wol->wolopts & WAKE_MAGICSECURE) + memcpy(wol->sopass, priv->sopass, sizeof(priv->sopass)); + } +@@ -70,7 +78,7 @@ int bcmgenet_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) + /* Try Wake-on-LAN from the PHY first */ + if (dev->phydev) { + ret = phy_ethtool_set_wol(dev->phydev, wol); +- if (ret != -EOPNOTSUPP) ++ if (ret != -EOPNOTSUPP && wol->wolopts) + return ret; + } + +diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c +index 7f74e5e106d9d4..b3878975bd9c05 100644 +--- a/drivers/net/ethernet/broadcom/tg3.c ++++ b/drivers/net/ethernet/broadcom/tg3.c +@@ -55,6 +55,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -18106,6 +18107,50 @@ static int tg3_resume(struct device *device) + + static SIMPLE_DEV_PM_OPS(tg3_pm_ops, tg3_suspend, tg3_resume); + ++/* Systems where ACPI _PTS (Prepare To Sleep) S5 will result in a fatal ++ * PCIe AER event on the tg3 device if the tg3 device is not, or cannot ++ * be, powered down. ++ */ ++static const struct dmi_system_id tg3_restart_aer_quirk_table[] = { ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R440"), ++ }, ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R540"), ++ }, ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R640"), ++ }, ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R650"), ++ }, ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R740"), ++ }, ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R750"), ++ }, ++ }, ++ {} ++}; ++ + static void tg3_shutdown(struct pci_dev *pdev) + { + struct net_device *dev = pci_get_drvdata(pdev); +@@ -18122,6 +18167,19 @@ static void tg3_shutdown(struct pci_dev *pdev) + + if (system_state == SYSTEM_POWER_OFF) + tg3_power_down(tp); ++ else if (system_state == SYSTEM_RESTART && ++ dmi_first_match(tg3_restart_aer_quirk_table) && ++ pdev->current_state != PCI_D3cold && ++ pdev->current_state != PCI_UNKNOWN) { ++ /* Disable PCIe AER on the tg3 to avoid a fatal ++ * error during this system restart. ++ */ ++ pcie_capability_clear_word(pdev, PCI_EXP_DEVCTL, ++ PCI_EXP_DEVCTL_CERE | ++ PCI_EXP_DEVCTL_NFERE | ++ PCI_EXP_DEVCTL_FERE | ++ PCI_EXP_DEVCTL_URRE); ++ } + + rtnl_unlock(); + +diff --git a/drivers/net/ethernet/intel/ice/ice_devlink.c b/drivers/net/ethernet/intel/ice/ice_devlink.c +index 80dc5445b50d45..030ca0ef71d876 100644 +--- a/drivers/net/ethernet/intel/ice/ice_devlink.c ++++ b/drivers/net/ethernet/intel/ice/ice_devlink.c +@@ -999,6 +999,9 @@ static int ice_devlink_rate_node_new(struct devlink_rate *rate_node, void **priv + + /* preallocate memory for ice_sched_node */ + node = devm_kzalloc(ice_hw_to_dev(pi->hw), sizeof(*node), GFP_KERNEL); ++ if (!node) ++ return -ENOMEM; ++ + *priv = node; + + return 0; +diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c +index 429afffa4c3169..f5023ac9ab8323 100644 +--- a/drivers/net/ethernet/intel/ice/ice_txrx.c ++++ b/drivers/net/ethernet/intel/ice/ice_txrx.c +@@ -1101,6 +1101,49 @@ ice_put_rx_buf(struct ice_rx_ring *rx_ring, struct ice_rx_buf *rx_buf) + rx_buf->page = NULL; + } + ++/** ++ * ice_put_rx_mbuf - ice_put_rx_buf() caller, for all frame frags ++ * @rx_ring: Rx ring with all the auxiliary data ++ * @xdp: XDP buffer carrying linear + frags part ++ * @xdp_xmit: XDP_TX/XDP_REDIRECT verdict storage ++ * @ntc: a current next_to_clean value to be stored at rx_ring ++ * ++ * Walk through gathered fragments and satisfy internal page ++ * recycle mechanism; we take here an action related to verdict ++ * returned by XDP program; ++ */ ++static void ice_put_rx_mbuf(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp, ++ u32 *xdp_xmit, u32 ntc) ++{ ++ u32 nr_frags = rx_ring->nr_frags + 1; ++ u32 idx = rx_ring->first_desc; ++ u32 cnt = rx_ring->count; ++ struct ice_rx_buf *buf; ++ int i; ++ ++ for (i = 0; i < nr_frags; i++) { ++ buf = &rx_ring->rx_buf[idx]; ++ ++ if (buf->act & (ICE_XDP_TX | ICE_XDP_REDIR)) { ++ ice_rx_buf_adjust_pg_offset(buf, xdp->frame_sz); ++ *xdp_xmit |= buf->act; ++ } else if (buf->act & ICE_XDP_CONSUMED) { ++ buf->pagecnt_bias++; ++ } else if (buf->act == ICE_XDP_PASS) { ++ ice_rx_buf_adjust_pg_offset(buf, xdp->frame_sz); ++ } ++ ++ ice_put_rx_buf(rx_ring, buf); ++ ++ if (++idx == cnt) ++ idx = 0; ++ } ++ ++ xdp->data = NULL; ++ rx_ring->first_desc = ntc; ++ rx_ring->nr_frags = 0; ++} ++ + /** + * ice_clean_rx_irq - Clean completed descriptors from Rx ring - bounce buf + * @rx_ring: Rx descriptor ring to transact packets on +@@ -1118,7 +1161,6 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget) + unsigned int total_rx_bytes = 0, total_rx_pkts = 0; + unsigned int offset = rx_ring->rx_offset; + struct xdp_buff *xdp = &rx_ring->xdp; +- u32 cached_ntc = rx_ring->first_desc; + struct ice_tx_ring *xdp_ring = NULL; + struct bpf_prog *xdp_prog = NULL; + u32 ntc = rx_ring->next_to_clean; +@@ -1126,7 +1168,6 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget) + u32 xdp_xmit = 0; + u32 cached_ntu; + bool failure; +- u32 first; + + xdp_prog = READ_ONCE(rx_ring->xdp_prog); + if (xdp_prog) { +@@ -1189,6 +1230,7 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget) + xdp_prepare_buff(xdp, hard_start, offset, size, !!offset); + xdp_buff_clear_frags_flag(xdp); + } else if (ice_add_xdp_frag(rx_ring, xdp, rx_buf, size)) { ++ ice_put_rx_mbuf(rx_ring, xdp, NULL, ntc); + break; + } + if (++ntc == cnt) +@@ -1204,9 +1246,8 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget) + total_rx_bytes += xdp_get_buff_len(xdp); + total_rx_pkts++; + +- xdp->data = NULL; +- rx_ring->first_desc = ntc; +- rx_ring->nr_frags = 0; ++ ice_put_rx_mbuf(rx_ring, xdp, &xdp_xmit, ntc); ++ + continue; + construct_skb: + if (likely(ice_ring_uses_build_skb(rx_ring))) +@@ -1220,14 +1261,11 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget) + if (unlikely(xdp_buff_has_frags(xdp))) + ice_set_rx_bufs_act(xdp, rx_ring, + ICE_XDP_CONSUMED); +- xdp->data = NULL; +- rx_ring->first_desc = ntc; +- rx_ring->nr_frags = 0; +- break; + } +- xdp->data = NULL; +- rx_ring->first_desc = ntc; +- rx_ring->nr_frags = 0; ++ ice_put_rx_mbuf(rx_ring, xdp, &xdp_xmit, ntc); ++ ++ if (!skb) ++ break; + + stat_err_bits = BIT(ICE_RX_FLEX_DESC_STATUS0_RXE_S); + if (unlikely(ice_test_staterr(rx_desc->wb.status_error0, +@@ -1259,23 +1297,6 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget) + total_rx_pkts++; + } + +- first = rx_ring->first_desc; +- while (cached_ntc != first) { +- struct ice_rx_buf *buf = &rx_ring->rx_buf[cached_ntc]; +- +- if (buf->act & (ICE_XDP_TX | ICE_XDP_REDIR)) { +- ice_rx_buf_adjust_pg_offset(buf, xdp->frame_sz); +- xdp_xmit |= buf->act; +- } else if (buf->act & ICE_XDP_CONSUMED) { +- buf->pagecnt_bias++; +- } else if (buf->act == ICE_XDP_PASS) { +- ice_rx_buf_adjust_pg_offset(buf, xdp->frame_sz); +- } +- +- ice_put_rx_buf(rx_ring, buf); +- if (++cached_ntc >= cnt) +- cached_ntc = 0; +- } + rx_ring->next_to_clean = ntc; + /* return up to cleaned_count buffers to hardware */ + failure = ice_alloc_rx_bufs(rx_ring, ICE_RX_DESC_UNUSED(rx_ring)); +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c +index 0c83ef174275a7..f00702bf781f17 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c +@@ -237,17 +237,16 @@ static void mlx5_pps_out(struct work_struct *work) + } + } + +-static void mlx5_timestamp_overflow(struct work_struct *work) ++static long mlx5_timestamp_overflow(struct ptp_clock_info *ptp_info) + { +- struct delayed_work *dwork = to_delayed_work(work); + struct mlx5_core_dev *mdev; + struct mlx5_timer *timer; + struct mlx5_clock *clock; + unsigned long flags; + +- timer = container_of(dwork, struct mlx5_timer, overflow_work); +- clock = container_of(timer, struct mlx5_clock, timer); ++ clock = container_of(ptp_info, struct mlx5_clock, ptp_info); + mdev = container_of(clock, struct mlx5_core_dev, clock); ++ timer = &clock->timer; + + if (mdev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) + goto out; +@@ -258,7 +257,7 @@ static void mlx5_timestamp_overflow(struct work_struct *work) + write_sequnlock_irqrestore(&clock->lock, flags); + + out: +- schedule_delayed_work(&timer->overflow_work, timer->overflow_period); ++ return timer->overflow_period; + } + + static int mlx5_ptp_settime_real_time(struct mlx5_core_dev *mdev, +@@ -435,6 +434,7 @@ static int mlx5_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) + timer->cycles.mult = mult; + mlx5_update_clock_info_page(mdev); + write_sequnlock_irqrestore(&clock->lock, flags); ++ ptp_schedule_worker(clock->ptp, timer->overflow_period); + + return 0; + } +@@ -770,6 +770,7 @@ static const struct ptp_clock_info mlx5_ptp_clock_info = { + .settime64 = mlx5_ptp_settime, + .enable = NULL, + .verify = NULL, ++ .do_aux_work = mlx5_timestamp_overflow, + }; + + static int mlx5_query_mtpps_pin_mode(struct mlx5_core_dev *mdev, u8 pin, +@@ -970,12 +971,11 @@ static void mlx5_init_overflow_period(struct mlx5_clock *clock) + do_div(ns, NSEC_PER_SEC / HZ); + timer->overflow_period = ns; + +- INIT_DELAYED_WORK(&timer->overflow_work, mlx5_timestamp_overflow); +- if (timer->overflow_period) +- schedule_delayed_work(&timer->overflow_work, 0); +- else ++ if (!timer->overflow_period) { ++ timer->overflow_period = HZ; + mlx5_core_warn(mdev, +- "invalid overflow period, overflow_work is not scheduled\n"); ++ "invalid overflow period, overflow_work is scheduled once per second\n"); ++ } + + if (clock_info) + clock_info->overflow_period = timer->overflow_period; +@@ -1061,6 +1061,9 @@ void mlx5_init_clock(struct mlx5_core_dev *mdev) + + MLX5_NB_INIT(&clock->pps_nb, mlx5_pps_event, PPS_EVENT); + mlx5_eq_notifier_register(mdev, &clock->pps_nb); ++ ++ if (clock->ptp) ++ ptp_schedule_worker(clock->ptp, 0); + } + + void mlx5_cleanup_clock(struct mlx5_core_dev *mdev) +@@ -1077,7 +1080,6 @@ void mlx5_cleanup_clock(struct mlx5_core_dev *mdev) + } + + cancel_work_sync(&clock->pps_info.out_work); +- cancel_delayed_work_sync(&clock->timer.overflow_work); + + if (mdev->clock_info) { + free_page((unsigned long)mdev->clock_info); +diff --git a/drivers/net/phy/nxp-c45-tja11xx.c b/drivers/net/phy/nxp-c45-tja11xx.c +index 7ab080ff02dfa6..77292c944c76d2 100644 +--- a/drivers/net/phy/nxp-c45-tja11xx.c ++++ b/drivers/net/phy/nxp-c45-tja11xx.c +@@ -1302,6 +1302,8 @@ static int nxp_c45_soft_reset(struct phy_device *phydev) + if (ret) + return ret; + ++ usleep_range(2000, 2050); ++ + return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, + VEND1_DEVICE_CONTROL, ret, + !(ret & DEVICE_CONTROL_RESET), 20000, +diff --git a/drivers/net/tun.c b/drivers/net/tun.c +index cbb2f78ffde03c..c1fdf8804d60b6 100644 +--- a/drivers/net/tun.c ++++ b/drivers/net/tun.c +@@ -580,7 +580,7 @@ static inline bool tun_not_capable(struct tun_struct *tun) + struct net *net = dev_net(tun->dev); + + return ((uid_valid(tun->owner) && !uid_eq(cred->euid, tun->owner)) || +- (gid_valid(tun->group) && !in_egroup_p(tun->group))) && ++ (gid_valid(tun->group) && !in_egroup_p(tun->group))) && + !ns_capable(net->user_ns, CAP_NET_ADMIN); + } + +diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c +index 46afb95ffabe3b..a19789b571905a 100644 +--- a/drivers/net/usb/ipheth.c ++++ b/drivers/net/usb/ipheth.c +@@ -61,7 +61,18 @@ + #define IPHETH_USBINTF_PROTO 1 + + #define IPHETH_IP_ALIGN 2 /* padding at front of URB */ +-#define IPHETH_NCM_HEADER_SIZE (12 + 96) /* NCMH + NCM0 */ ++/* On iOS devices, NCM headers in RX have a fixed size regardless of DPE count: ++ * - NTH16 (NCMH): 12 bytes, as per CDC NCM 1.0 spec ++ * - NDP16 (NCM0): 96 bytes, of which ++ * - NDP16 fixed header: 8 bytes ++ * - maximum of 22 DPEs (21 datagrams + trailer), 4 bytes each ++ */ ++#define IPHETH_NDP16_MAX_DPE 22 ++#define IPHETH_NDP16_HEADER_SIZE (sizeof(struct usb_cdc_ncm_ndp16) + \ ++ IPHETH_NDP16_MAX_DPE * \ ++ sizeof(struct usb_cdc_ncm_dpe16)) ++#define IPHETH_NCM_HEADER_SIZE (sizeof(struct usb_cdc_ncm_nth16) + \ ++ IPHETH_NDP16_HEADER_SIZE) + #define IPHETH_TX_BUF_SIZE ETH_FRAME_LEN + #define IPHETH_RX_BUF_SIZE_LEGACY (IPHETH_IP_ALIGN + ETH_FRAME_LEN) + #define IPHETH_RX_BUF_SIZE_NCM 65536 +@@ -207,15 +218,23 @@ static int ipheth_rcvbulk_callback_legacy(struct urb *urb) + return ipheth_consume_skb(buf, len, dev); + } + ++/* In "NCM mode", the iOS device encapsulates RX (phone->computer) traffic ++ * in NCM Transfer Blocks (similarly to CDC NCM). However, unlike reverse ++ * tethering (handled by the `cdc_ncm` driver), regular tethering is not ++ * compliant with the CDC NCM spec, as the device is missing the necessary ++ * descriptors, and TX (computer->phone) traffic is not encapsulated ++ * at all. Thus `ipheth` implements a very limited subset of the spec with ++ * the sole purpose of parsing RX URBs. ++ */ + static int ipheth_rcvbulk_callback_ncm(struct urb *urb) + { + struct usb_cdc_ncm_nth16 *ncmh; + struct usb_cdc_ncm_ndp16 *ncm0; + struct usb_cdc_ncm_dpe16 *dpe; + struct ipheth_device *dev; ++ u16 dg_idx, dg_len; + int retval = -EINVAL; + char *buf; +- int len; + + dev = urb->context; + +@@ -226,40 +245,42 @@ static int ipheth_rcvbulk_callback_ncm(struct urb *urb) + + ncmh = urb->transfer_buffer; + if (ncmh->dwSignature != cpu_to_le32(USB_CDC_NCM_NTH16_SIGN) || +- le16_to_cpu(ncmh->wNdpIndex) >= urb->actual_length) { +- dev->net->stats.rx_errors++; +- return retval; +- } ++ /* On iOS, NDP16 directly follows NTH16 */ ++ ncmh->wNdpIndex != cpu_to_le16(sizeof(struct usb_cdc_ncm_nth16))) ++ goto rx_error; + +- ncm0 = urb->transfer_buffer + le16_to_cpu(ncmh->wNdpIndex); +- if (ncm0->dwSignature != cpu_to_le32(USB_CDC_NCM_NDP16_NOCRC_SIGN) || +- le16_to_cpu(ncmh->wHeaderLength) + le16_to_cpu(ncm0->wLength) >= +- urb->actual_length) { +- dev->net->stats.rx_errors++; +- return retval; +- } ++ ncm0 = urb->transfer_buffer + sizeof(struct usb_cdc_ncm_nth16); ++ if (ncm0->dwSignature != cpu_to_le32(USB_CDC_NCM_NDP16_NOCRC_SIGN)) ++ goto rx_error; + + dpe = ncm0->dpe16; +- while (le16_to_cpu(dpe->wDatagramIndex) != 0 && +- le16_to_cpu(dpe->wDatagramLength) != 0) { +- if (le16_to_cpu(dpe->wDatagramIndex) >= urb->actual_length || +- le16_to_cpu(dpe->wDatagramIndex) + +- le16_to_cpu(dpe->wDatagramLength) > urb->actual_length) { ++ for (int dpe_i = 0; dpe_i < IPHETH_NDP16_MAX_DPE; ++dpe_i, ++dpe) { ++ dg_idx = le16_to_cpu(dpe->wDatagramIndex); ++ dg_len = le16_to_cpu(dpe->wDatagramLength); ++ ++ /* Null DPE must be present after last datagram pointer entry ++ * (3.3.1 USB CDC NCM spec v1.0) ++ */ ++ if (dg_idx == 0 && dg_len == 0) ++ return 0; ++ ++ if (dg_idx < IPHETH_NCM_HEADER_SIZE || ++ dg_idx >= urb->actual_length || ++ dg_len > urb->actual_length - dg_idx) { + dev->net->stats.rx_length_errors++; + return retval; + } + +- buf = urb->transfer_buffer + le16_to_cpu(dpe->wDatagramIndex); +- len = le16_to_cpu(dpe->wDatagramLength); ++ buf = urb->transfer_buffer + dg_idx; + +- retval = ipheth_consume_skb(buf, len, dev); ++ retval = ipheth_consume_skb(buf, dg_len, dev); + if (retval != 0) + return retval; +- +- dpe++; + } + +- return 0; ++rx_error: ++ dev->net->stats.rx_errors++; ++ return retval; + } + + static void ipheth_rcvbulk_callback(struct urb *urb) +diff --git a/drivers/net/vmxnet3/vmxnet3_xdp.c b/drivers/net/vmxnet3/vmxnet3_xdp.c +index 1341374a4588a0..616ecc38d1726c 100644 +--- a/drivers/net/vmxnet3/vmxnet3_xdp.c ++++ b/drivers/net/vmxnet3/vmxnet3_xdp.c +@@ -28,7 +28,7 @@ vmxnet3_xdp_get_tq(struct vmxnet3_adapter *adapter) + if (likely(cpu < tq_number)) + tq = &adapter->tx_queue[cpu]; + else +- tq = &adapter->tx_queue[reciprocal_scale(cpu, tq_number)]; ++ tq = &adapter->tx_queue[cpu % tq_number]; + + return tq; + } +@@ -124,6 +124,7 @@ vmxnet3_xdp_xmit_frame(struct vmxnet3_adapter *adapter, + u32 buf_size; + u32 dw2; + ++ spin_lock_irq(&tq->tx_lock); + dw2 = (tq->tx_ring.gen ^ 0x1) << VMXNET3_TXD_GEN_SHIFT; + dw2 |= xdpf->len; + ctx.sop_txd = tq->tx_ring.base + tq->tx_ring.next2fill; +@@ -134,6 +135,7 @@ vmxnet3_xdp_xmit_frame(struct vmxnet3_adapter *adapter, + + if (vmxnet3_cmd_ring_desc_avail(&tq->tx_ring) == 0) { + tq->stats.tx_ring_full++; ++ spin_unlock_irq(&tq->tx_lock); + return -ENOSPC; + } + +@@ -142,8 +144,10 @@ vmxnet3_xdp_xmit_frame(struct vmxnet3_adapter *adapter, + tbi->dma_addr = dma_map_single(&adapter->pdev->dev, + xdpf->data, buf_size, + DMA_TO_DEVICE); +- if (dma_mapping_error(&adapter->pdev->dev, tbi->dma_addr)) ++ if (dma_mapping_error(&adapter->pdev->dev, tbi->dma_addr)) { ++ spin_unlock_irq(&tq->tx_lock); + return -EFAULT; ++ } + tbi->map_type |= VMXNET3_MAP_SINGLE; + } else { /* XDP buffer from page pool */ + page = virt_to_page(xdpf->data); +@@ -182,6 +186,7 @@ vmxnet3_xdp_xmit_frame(struct vmxnet3_adapter *adapter, + dma_wmb(); + gdesc->dword[2] = cpu_to_le32(le32_to_cpu(gdesc->dword[2]) ^ + VMXNET3_TXD_GEN); ++ spin_unlock_irq(&tq->tx_lock); + + /* No need to handle the case when tx_num_deferred doesn't reach + * threshold. Backend driver at hypervisor side will poll and reset +@@ -225,6 +230,7 @@ vmxnet3_xdp_xmit(struct net_device *dev, + { + struct vmxnet3_adapter *adapter = netdev_priv(dev); + struct vmxnet3_tx_queue *tq; ++ struct netdev_queue *nq; + int i; + + if (unlikely(test_bit(VMXNET3_STATE_BIT_QUIESCED, &adapter->state))) +@@ -236,6 +242,9 @@ vmxnet3_xdp_xmit(struct net_device *dev, + if (tq->stopped) + return -ENETDOWN; + ++ nq = netdev_get_tx_queue(adapter->netdev, tq->qid); ++ ++ __netif_tx_lock(nq, smp_processor_id()); + for (i = 0; i < n; i++) { + if (vmxnet3_xdp_xmit_frame(adapter, frames[i], tq, true)) { + tq->stats.xdp_xmit_err++; +@@ -243,6 +252,7 @@ vmxnet3_xdp_xmit(struct net_device *dev, + } + } + tq->stats.xdp_xmit += i; ++ __netif_tx_unlock(nq); + + return i; + } +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +index f599d5f896e89e..96f607f35490da 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -540,6 +540,11 @@ void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success) + struct ethhdr *eh; + u16 type; + ++ if (!ifp) { ++ brcmu_pkt_buf_free_skb(txp); ++ return; ++ } ++ + eh = (struct ethhdr *)(txp->data); + type = ntohs(eh->h_proto); + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c +index 73fc701204e29b..90d2c536bdaf06 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c +@@ -96,13 +96,13 @@ void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, + /* Set board-type to the first string of the machine compatible prop */ + root = of_find_node_by_path("/"); + if (root && err) { +- char *board_type; ++ char *board_type = NULL; + const char *tmp; + +- of_property_read_string_index(root, "compatible", 0, &tmp); +- + /* get rid of '/' in the compatible string to be able to find the FW */ +- board_type = devm_kstrdup(dev, tmp, GFP_KERNEL); ++ if (!of_property_read_string_index(root, "compatible", 0, &tmp)) ++ board_type = devm_kstrdup(dev, tmp, GFP_KERNEL); ++ + if (!board_type) { + of_node_put(root); + return; +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c +index 8580a275478918..42e7bc67e9143e 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c +@@ -23427,6 +23427,9 @@ wlc_phy_iqcal_gainparams_nphy(struct brcms_phy *pi, u16 core_no, + break; + } + ++ if (WARN_ON(k == NPHY_IQCAL_NUMGAINS)) ++ return; ++ + params->txgm = tbl_iqcal_gainparams_nphy[band_idx][k][1]; + params->pga = tbl_iqcal_gainparams_nphy[band_idx][k][2]; + params->pad = tbl_iqcal_gainparams_nphy[band_idx][k][3]; +diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c +index 9943e2d21a8f53..e72f238ff7b23c 100644 +--- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c ++++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c +@@ -155,7 +155,7 @@ static int iwl_acpi_get_dsm_integer(struct device *dev, int rev, int func, + size_t expected_size) + { + union acpi_object *obj; +- int ret = 0; ++ int ret; + + obj = iwl_acpi_get_dsm_object(dev, rev, func, NULL, guid); + if (IS_ERR(obj)) { +@@ -170,8 +170,10 @@ static int iwl_acpi_get_dsm_integer(struct device *dev, int rev, int func, + } else if (obj->type == ACPI_TYPE_BUFFER) { + __le64 le_value = 0; + +- if (WARN_ON_ONCE(expected_size > sizeof(le_value))) +- return -EINVAL; ++ if (WARN_ON_ONCE(expected_size > sizeof(le_value))) { ++ ret = -EINVAL; ++ goto out; ++ } + + /* if the buffer size doesn't match the expected size */ + if (obj->buffer.length != expected_size) +@@ -192,8 +194,9 @@ static int iwl_acpi_get_dsm_integer(struct device *dev, int rev, int func, + } + + IWL_DEBUG_DEV_RADIO(dev, +- "ACPI: DSM method evaluated: func=%d, ret=%d\n", +- func, ret); ++ "ACPI: DSM method evaluated: func=%d, value=%lld\n", ++ func, *value); ++ ret = 0; + out: + ACPI_FREE(obj); + return ret; +diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c +index 76be7308460b06..1c47a4d95978a4 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c +@@ -2,9 +2,14 @@ + /* Copyright (C) 2020 MediaTek Inc. */ + + #include ++#include + #include "mt7915.h" + #include "eeprom.h" + ++static bool enable_6ghz; ++module_param(enable_6ghz, bool, 0644); ++MODULE_PARM_DESC(enable_6ghz, "Enable 6 GHz instead of 5 GHz on hardware that supports both"); ++ + static int mt7915_eeprom_load_precal(struct mt7915_dev *dev) + { + struct mt76_dev *mdev = &dev->mt76; +@@ -159,8 +164,20 @@ static void mt7915_eeprom_parse_band_config(struct mt7915_phy *phy) + phy->mt76->cap.has_6ghz = true; + return; + case MT_EE_V2_BAND_SEL_5GHZ_6GHZ: +- phy->mt76->cap.has_5ghz = true; +- phy->mt76->cap.has_6ghz = true; ++ if (enable_6ghz) { ++ phy->mt76->cap.has_6ghz = true; ++ u8p_replace_bits(&eeprom[MT_EE_WIFI_CONF + band], ++ MT_EE_V2_BAND_SEL_6GHZ, ++ MT_EE_WIFI_CONF0_BAND_SEL); ++ } else { ++ phy->mt76->cap.has_5ghz = true; ++ u8p_replace_bits(&eeprom[MT_EE_WIFI_CONF + band], ++ MT_EE_V2_BAND_SEL_5GHZ, ++ MT_EE_WIFI_CONF0_BAND_SEL); ++ } ++ /* force to buffer mode */ ++ dev->flash_mode = true; ++ + return; + default: + phy->mt76->cap.has_2ghz = true; +diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c +index 28f84220d50f02..e9068718b3d1f6 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c +@@ -1220,14 +1220,14 @@ int mt7915_register_device(struct mt7915_dev *dev) + if (ret) + goto unreg_dev; + +- ieee80211_queue_work(mt76_hw(dev), &dev->init_work); +- + if (phy2) { + ret = mt7915_register_ext_phy(dev, phy2); + if (ret) + goto unreg_thermal; + } + ++ ieee80211_queue_work(mt76_hw(dev), &dev->init_work); ++ + dev->recovery.hw_init_done = true; + + ret = mt7915_init_debugfs(&dev->phy); +diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/usb.c b/drivers/net/wireless/mediatek/mt76/mt7921/usb.c +index 59cd3d98bf9086..13e892d788b277 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7921/usb.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7921/usb.c +@@ -21,6 +21,9 @@ static const struct usb_device_id mt7921u_device_table[] = { + /* Netgear, Inc. [A8000,AXE3000] */ + { USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9060, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)MT7921_FIRMWARE_WM }, ++ /* TP-Link TXE50UH */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x35bc, 0x0107, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)MT7921_FIRMWARE_WM }, + { }, + }; + +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.h +index c269942b3f4ab1..af8d17b9e012ca 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.h ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.h +@@ -197,9 +197,9 @@ enum rtl8821a_h2c_cmd { + + /* _MEDIA_STATUS_RPT_PARM_CMD1 */ + #define SET_H2CCMD_MSRRPT_PARM_OPMODE(__cmd, __value) \ +- u8p_replace_bits(__cmd + 1, __value, BIT(0)) ++ u8p_replace_bits(__cmd, __value, BIT(0)) + #define SET_H2CCMD_MSRRPT_PARM_MACID_IND(__cmd, __value) \ +- u8p_replace_bits(__cmd + 1, __value, BIT(1)) ++ u8p_replace_bits(__cmd, __value, BIT(1)) + + /* AP_OFFLOAD */ + #define SET_H2CCMD_AP_OFFLOAD_ON(__cmd, __value) \ +diff --git a/drivers/net/wireless/realtek/rtw88/sdio.c b/drivers/net/wireless/realtek/rtw88/sdio.c +index 5bd1ee81210d1d..9043569935796b 100644 +--- a/drivers/net/wireless/realtek/rtw88/sdio.c ++++ b/drivers/net/wireless/realtek/rtw88/sdio.c +@@ -1191,6 +1191,8 @@ static void rtw_sdio_indicate_tx_status(struct rtw_dev *rtwdev, + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_hw *hw = rtwdev->hw; + ++ skb_pull(skb, rtwdev->chip->tx_pkt_desc_sz); ++ + /* enqueue to wait for tx report */ + if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) { + rtw_tx_report_enqueue(rtwdev, skb, tx_data->sn); +diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c +index fac83b718a30cd..457c1dd31bf9d9 100644 +--- a/drivers/net/wireless/realtek/rtw89/phy.c ++++ b/drivers/net/wireless/realtek/rtw89/phy.c +@@ -2438,7 +2438,6 @@ static void rtw89_phy_cfo_set_crystal_cap(struct rtw89_dev *rtwdev, + + if (!force && cfo->crystal_cap == crystal_cap) + return; +- crystal_cap = clamp_t(u8, crystal_cap, 0, 127); + if (chip->chip_id == RTL8852A || chip->chip_id == RTL8851B) { + rtw89_phy_cfo_set_xcap_reg(rtwdev, true, crystal_cap); + rtw89_phy_cfo_set_xcap_reg(rtwdev, false, crystal_cap); +@@ -2552,7 +2551,7 @@ static void rtw89_phy_cfo_crystal_cap_adjust(struct rtw89_dev *rtwdev, + s32 curr_cfo) + { + struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; +- s8 crystal_cap = cfo->crystal_cap; ++ int crystal_cap = cfo->crystal_cap; + s32 cfo_abs = abs(curr_cfo); + int sign; + +@@ -2569,15 +2568,17 @@ static void rtw89_phy_cfo_crystal_cap_adjust(struct rtw89_dev *rtwdev, + } + sign = curr_cfo > 0 ? 1 : -1; + if (cfo_abs > CFO_TRK_STOP_TH_4) +- crystal_cap += 7 * sign; ++ crystal_cap += 3 * sign; + else if (cfo_abs > CFO_TRK_STOP_TH_3) +- crystal_cap += 5 * sign; +- else if (cfo_abs > CFO_TRK_STOP_TH_2) + crystal_cap += 3 * sign; ++ else if (cfo_abs > CFO_TRK_STOP_TH_2) ++ crystal_cap += 1 * sign; + else if (cfo_abs > CFO_TRK_STOP_TH_1) + crystal_cap += 1 * sign; + else + return; ++ ++ crystal_cap = clamp(crystal_cap, 0, 127); + rtw89_phy_cfo_set_crystal_cap(rtwdev, (u8)crystal_cap, false); + rtw89_debug(rtwdev, RTW89_DBG_CFO, + "X_cap{Curr,Default}={0x%x,0x%x}\n", +diff --git a/drivers/net/wireless/realtek/rtw89/phy.h b/drivers/net/wireless/realtek/rtw89/phy.h +index d6dc0cbbae43bf..15ed23fa4218fd 100644 +--- a/drivers/net/wireless/realtek/rtw89/phy.h ++++ b/drivers/net/wireless/realtek/rtw89/phy.h +@@ -51,7 +51,7 @@ + #define CFO_TRK_STOP_TH_4 (30 << 2) + #define CFO_TRK_STOP_TH_3 (20 << 2) + #define CFO_TRK_STOP_TH_2 (10 << 2) +-#define CFO_TRK_STOP_TH_1 (00 << 2) ++#define CFO_TRK_STOP_TH_1 (03 << 2) + #define CFO_TRK_STOP_TH (2 << 2) + #define CFO_SW_COMP_FINE_TUNE (2 << 2) + #define CFO_PERIOD_CNT 15 +diff --git a/drivers/net/wwan/iosm/iosm_ipc_pcie.c b/drivers/net/wwan/iosm/iosm_ipc_pcie.c +index 04517bd3325a2a..a066977af0be5c 100644 +--- a/drivers/net/wwan/iosm/iosm_ipc_pcie.c ++++ b/drivers/net/wwan/iosm/iosm_ipc_pcie.c +@@ -6,6 +6,7 @@ + #include + #include + #include ++#include + #include + + #include "iosm_ipc_imem.h" +@@ -18,6 +19,7 @@ MODULE_LICENSE("GPL v2"); + /* WWAN GUID */ + static guid_t wwan_acpi_guid = GUID_INIT(0xbad01b75, 0x22a8, 0x4f48, 0x87, 0x92, + 0xbd, 0xde, 0x94, 0x67, 0x74, 0x7d); ++static bool pci_registered; + + static void ipc_pcie_resources_release(struct iosm_pcie *ipc_pcie) + { +@@ -448,7 +450,6 @@ static struct pci_driver iosm_ipc_driver = { + }, + .id_table = iosm_ipc_ids, + }; +-module_pci_driver(iosm_ipc_driver); + + int ipc_pcie_addr_map(struct iosm_pcie *ipc_pcie, unsigned char *data, + size_t size, dma_addr_t *mapping, int direction) +@@ -530,3 +531,56 @@ void ipc_pcie_kfree_skb(struct iosm_pcie *ipc_pcie, struct sk_buff *skb) + IPC_CB(skb)->mapping = 0; + dev_kfree_skb(skb); + } ++ ++static int pm_notify(struct notifier_block *nb, unsigned long mode, void *_unused) ++{ ++ if (mode == PM_HIBERNATION_PREPARE || mode == PM_RESTORE_PREPARE) { ++ if (pci_registered) { ++ pci_unregister_driver(&iosm_ipc_driver); ++ pci_registered = false; ++ } ++ } else if (mode == PM_POST_HIBERNATION || mode == PM_POST_RESTORE) { ++ if (!pci_registered) { ++ int ret; ++ ++ ret = pci_register_driver(&iosm_ipc_driver); ++ if (ret) { ++ pr_err(KBUILD_MODNAME ": unable to re-register PCI driver: %d\n", ++ ret); ++ } else { ++ pci_registered = true; ++ } ++ } ++ } ++ ++ return 0; ++} ++ ++static struct notifier_block pm_notifier = { ++ .notifier_call = pm_notify, ++}; ++ ++static int __init iosm_ipc_driver_init(void) ++{ ++ int ret; ++ ++ ret = pci_register_driver(&iosm_ipc_driver); ++ if (ret) ++ return ret; ++ ++ pci_registered = true; ++ ++ register_pm_notifier(&pm_notifier); ++ ++ return 0; ++} ++module_init(iosm_ipc_driver_init); ++ ++static void __exit iosm_ipc_driver_exit(void) ++{ ++ unregister_pm_notifier(&pm_notifier); ++ ++ if (pci_registered) ++ pci_unregister_driver(&iosm_ipc_driver); ++} ++module_exit(iosm_ipc_driver_exit); +diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c +index 26e3f1896dc397..8a200931bc297a 100644 +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -1553,7 +1553,13 @@ int nvme_set_queue_count(struct nvme_ctrl *ctrl, int *count) + + status = nvme_set_features(ctrl, NVME_FEAT_NUM_QUEUES, q_count, NULL, 0, + &result); +- if (status < 0) ++ ++ /* ++ * It's either a kernel error or the host observed a connection ++ * lost. In either case it's not possible communicate with the ++ * controller and thus enter the error code path. ++ */ ++ if (status < 0 || status == NVME_SC_HOST_PATH_ERROR) + return status; + + /* +diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c +index cdb1e706f855e5..91324791a5b66e 100644 +--- a/drivers/nvme/host/fc.c ++++ b/drivers/nvme/host/fc.c +@@ -2080,7 +2080,8 @@ nvme_fc_fcpio_done(struct nvmefc_fcp_req *req) + nvme_fc_complete_rq(rq); + + check_error: +- if (terminate_assoc && ctrl->ctrl.state != NVME_CTRL_RESETTING) ++ if (terminate_assoc && ++ nvme_ctrl_state(&ctrl->ctrl) != NVME_CTRL_RESETTING) + queue_work(nvme_reset_wq, &ctrl->ioerr_work); + } + +@@ -2534,6 +2535,8 @@ __nvme_fc_abort_outstanding_ios(struct nvme_fc_ctrl *ctrl, bool start_queues) + static void + nvme_fc_error_recovery(struct nvme_fc_ctrl *ctrl, char *errmsg) + { ++ enum nvme_ctrl_state state = nvme_ctrl_state(&ctrl->ctrl); ++ + /* + * if an error (io timeout, etc) while (re)connecting, the remote + * port requested terminating of the association (disconnect_ls) +@@ -2541,7 +2544,7 @@ nvme_fc_error_recovery(struct nvme_fc_ctrl *ctrl, char *errmsg) + * the controller. Abort any ios on the association and let the + * create_association error path resolve things. + */ +- if (ctrl->ctrl.state == NVME_CTRL_CONNECTING) { ++ if (state == NVME_CTRL_CONNECTING) { + __nvme_fc_abort_outstanding_ios(ctrl, true); + set_bit(ASSOC_FAILED, &ctrl->flags); + dev_warn(ctrl->ctrl.device, +@@ -2551,7 +2554,7 @@ nvme_fc_error_recovery(struct nvme_fc_ctrl *ctrl, char *errmsg) + } + + /* Otherwise, only proceed if in LIVE state - e.g. on first error */ +- if (ctrl->ctrl.state != NVME_CTRL_LIVE) ++ if (state != NVME_CTRL_LIVE) + return; + + dev_warn(ctrl->ctrl.device, +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index 52c8fd3d5c4796..b1310e69d07daf 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -2949,7 +2949,9 @@ static unsigned long check_vendor_combination_bug(struct pci_dev *pdev) + * because of high power consumption (> 2 Watt) in s2idle + * sleep. Only some boards with Intel CPU are affected. + */ +- if (dmi_match(DMI_BOARD_NAME, "GMxPXxx") || ++ if (dmi_match(DMI_BOARD_NAME, "DN50Z-140HC-YD") || ++ dmi_match(DMI_BOARD_NAME, "GMxPXxx") || ++ dmi_match(DMI_BOARD_NAME, "GXxMRXx") || + dmi_match(DMI_BOARD_NAME, "PH4PG31") || + dmi_match(DMI_BOARD_NAME, "PH4PRX1_PH6PRX1") || + dmi_match(DMI_BOARD_NAME, "PH6PG01_PH6PG71")) +diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c +index f28c005c2bb265..fd11d3825cf854 100644 +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -1725,6 +1725,8 @@ static int __nvmem_cell_entry_write(struct nvmem_cell_entry *cell, void *buf, si + return -EINVAL; + + if (cell->bit_offset || cell->nbits) { ++ if (len != BITS_TO_BYTES(cell->nbits) && len != cell->bytes) ++ return -EINVAL; + buf = nvmem_cell_prepare_write_buffer(cell, buf, len); + if (IS_ERR(buf)) + return PTR_ERR(buf); +diff --git a/drivers/nvmem/imx-ocotp-ele.c b/drivers/nvmem/imx-ocotp-ele.c +index cf920542f939ea..dfc925edfc83e0 100644 +--- a/drivers/nvmem/imx-ocotp-ele.c ++++ b/drivers/nvmem/imx-ocotp-ele.c +@@ -70,13 +70,15 @@ static int imx_ocotp_reg_read(void *context, unsigned int offset, void *val, siz + u32 *buf; + void *p; + int i; ++ u8 skipbytes; + +- index = offset; +- num_bytes = round_up(bytes, 4); +- count = num_bytes >> 2; ++ if (offset + bytes > priv->data->size) ++ bytes = priv->data->size - offset; + +- if (count > ((priv->data->size >> 2) - index)) +- count = (priv->data->size >> 2) - index; ++ index = offset >> 2; ++ skipbytes = offset - (index << 2); ++ num_bytes = round_up(bytes + skipbytes, 4); ++ count = num_bytes >> 2; + + p = kzalloc(num_bytes, GFP_KERNEL); + if (!p) +@@ -96,7 +98,7 @@ static int imx_ocotp_reg_read(void *context, unsigned int offset, void *val, siz + *buf++ = readl_relaxed(reg + (i << 2)); + } + +- memcpy(val, (u8 *)p, bytes); ++ memcpy(val, ((u8 *)p) + skipbytes, bytes); + + mutex_unlock(&priv->lock); + +@@ -127,7 +129,7 @@ static int imx_ele_ocotp_probe(struct platform_device *pdev) + priv->config.owner = THIS_MODULE; + priv->config.size = priv->data->size; + priv->config.reg_read = priv->data->reg_read; +- priv->config.word_size = 4; ++ priv->config.word_size = 1; + priv->config.stride = 1; + priv->config.priv = priv; + priv->config.read_only = true; +diff --git a/drivers/nvmem/qcom-spmi-sdam.c b/drivers/nvmem/qcom-spmi-sdam.c +index 9aa8f42faa4c93..4f1cca6eab71e1 100644 +--- a/drivers/nvmem/qcom-spmi-sdam.c ++++ b/drivers/nvmem/qcom-spmi-sdam.c +@@ -144,6 +144,7 @@ static int sdam_probe(struct platform_device *pdev) + sdam->sdam_config.owner = THIS_MODULE; + sdam->sdam_config.add_legacy_fixed_of_cells = true; + sdam->sdam_config.stride = 1; ++ sdam->sdam_config.size = sdam->size; + sdam->sdam_config.word_size = 1; + sdam->sdam_config.reg_read = sdam_read; + sdam->sdam_config.reg_write = sdam_write; +diff --git a/drivers/of/base.c b/drivers/of/base.c +index 7a3c05622d9821..ccadc22f18c0ec 100644 +--- a/drivers/of/base.c ++++ b/drivers/of/base.c +@@ -788,10 +788,10 @@ struct device_node *of_find_node_opts_by_path(const char *path, const char **opt + /* The path could begin with an alias */ + if (*path != '/') { + int len; +- const char *p = separator; ++ const char *p = strchrnul(path, '/'); + +- if (!p) +- p = strchrnul(path, '/'); ++ if (separator && separator < p) ++ p = separator; + len = p - path; + + /* of_aliases must not be NULL */ +@@ -1453,7 +1453,6 @@ int of_parse_phandle_with_args_map(const struct device_node *np, + * specifier into the out_args structure, keeping the + * bits specified in -map-pass-thru. + */ +- match_array = map - new_size; + for (i = 0; i < new_size; i++) { + __be32 val = *(map - new_size + i); + +@@ -1462,6 +1461,7 @@ int of_parse_phandle_with_args_map(const struct device_node *np, + val |= cpu_to_be32(out_args->args[i]) & pass[i]; + } + ++ initial_match_array[i] = val; + out_args->args[i] = be32_to_cpu(val); + } + out_args->args_count = list_size = new_size; +diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c +index 959f1808c240fa..4a30daa0a9b9cc 100644 +--- a/drivers/of/of_reserved_mem.c ++++ b/drivers/of/of_reserved_mem.c +@@ -156,12 +156,12 @@ static int __init __reserved_mem_alloc_size(unsigned long node, + + prop = of_get_flat_dt_prop(node, "alignment", &len); + if (prop) { +- if (len != dt_root_addr_cells * sizeof(__be32)) { ++ if (len != dt_root_size_cells * sizeof(__be32)) { + pr_err("invalid alignment property in '%s' node.\n", + uname); + return -EINVAL; + } +- align = dt_mem_next_cell(dt_root_addr_cells, &prop); ++ align = dt_mem_next_cell(dt_root_size_cells, &prop); + } + + nomap = of_get_flat_dt_prop(node, "no-map", NULL) != NULL; +diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c +index 2c32de66793778..059f8639f21e92 100644 +--- a/drivers/pci/endpoint/pci-epf-core.c ++++ b/drivers/pci/endpoint/pci-epf-core.c +@@ -202,6 +202,7 @@ void pci_epf_remove_vepf(struct pci_epf *epf_pf, struct pci_epf *epf_vf) + + mutex_lock(&epf_pf->lock); + clear_bit(epf_vf->vfunc_no, &epf_pf->vfunction_num_map); ++ epf_vf->epf_pf = NULL; + list_del(&epf_vf->list); + mutex_unlock(&epf_pf->lock); + } +diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c +index e54847040b4a92..c3609d830873f6 100644 +--- a/drivers/pinctrl/samsung/pinctrl-samsung.c ++++ b/drivers/pinctrl/samsung/pinctrl-samsung.c +@@ -1150,7 +1150,7 @@ static int samsung_pinctrl_probe(struct platform_device *pdev) + + ret = platform_get_irq_optional(pdev, 0); + if (ret < 0 && ret != -ENXIO) +- return ret; ++ goto err_put_banks; + if (ret > 0) + drvdata->irq = ret; + +diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c +index 377a0becd1a181..868faccfb86285 100644 +--- a/drivers/platform/x86/acer-wmi.c ++++ b/drivers/platform/x86/acer-wmi.c +@@ -88,6 +88,7 @@ enum acer_wmi_event_ids { + WMID_HOTKEY_EVENT = 0x1, + WMID_ACCEL_OR_KBD_DOCK_EVENT = 0x5, + WMID_GAMING_TURBO_KEY_EVENT = 0x7, ++ WMID_AC_EVENT = 0x8, + }; + + static const struct key_entry acer_wmi_keymap[] __initconst = { +@@ -1999,6 +2000,9 @@ static void acer_wmi_notify(u32 value, void *context) + if (return_value.key_num == 0x4) + acer_toggle_turbo(); + break; ++ case WMID_AC_EVENT: ++ /* We ignore AC events here */ ++ break; + default: + pr_warn("Unknown function number - %d - %d\n", + return_value.function, return_value.key_num); +diff --git a/drivers/platform/x86/intel/int3472/discrete.c b/drivers/platform/x86/intel/int3472/discrete.c +index e33c2d75975cf5..d56f79043f5e24 100644 +--- a/drivers/platform/x86/intel/int3472/discrete.c ++++ b/drivers/platform/x86/intel/int3472/discrete.c +@@ -284,6 +284,9 @@ static int skl_int3472_discrete_probe(struct platform_device *pdev) + struct int3472_cldb cldb; + int ret; + ++ if (!adev) ++ return -ENODEV; ++ + ret = skl_int3472_fill_cldb(adev, &cldb); + if (ret) { + dev_err(&pdev->dev, "Couldn't fill CLDB structure\n"); +diff --git a/drivers/platform/x86/intel/int3472/tps68470.c b/drivers/platform/x86/intel/int3472/tps68470.c +index 1e107fd49f828c..81ac4c69196309 100644 +--- a/drivers/platform/x86/intel/int3472/tps68470.c ++++ b/drivers/platform/x86/intel/int3472/tps68470.c +@@ -152,6 +152,9 @@ static int skl_int3472_tps68470_probe(struct i2c_client *client) + int ret; + int i; + ++ if (!adev) ++ return -ENODEV; ++ + n_consumers = skl_int3472_fill_clk_pdata(&client->dev, &clk_pdata); + if (n_consumers < 0) + return n_consumers; +diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c +index b586da2e30023c..6b7e8b7ebcef5e 100644 +--- a/drivers/ptp/ptp_clock.c ++++ b/drivers/ptp/ptp_clock.c +@@ -189,6 +189,11 @@ static int ptp_getcycles64(struct ptp_clock_info *info, struct timespec64 *ts) + return info->gettime64(info, ts); + } + ++static int ptp_enable(struct ptp_clock_info *ptp, struct ptp_clock_request *request, int on) ++{ ++ return -EOPNOTSUPP; ++} ++ + static void ptp_aux_kworker(struct kthread_work *work) + { + struct ptp_clock *ptp = container_of(work, struct ptp_clock, +@@ -251,6 +256,9 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, + ptp->info->getcrosscycles = ptp->info->getcrosststamp; + } + ++ if (!ptp->info->enable) ++ ptp->info->enable = ptp_enable; ++ + if (ptp->info->do_aux_work) { + kthread_init_delayed_work(&ptp->aux_work, ptp_aux_kworker); + ptp->kworker = kthread_create_worker(0, "ptp%d", ptp->index); +diff --git a/drivers/pwm/pwm-microchip-core.c b/drivers/pwm/pwm-microchip-core.c +index e7525c98105ebc..d3e60d5d085bc2 100644 +--- a/drivers/pwm/pwm-microchip-core.c ++++ b/drivers/pwm/pwm-microchip-core.c +@@ -328,7 +328,7 @@ static int mchp_core_pwm_apply_locked(struct pwm_chip *chip, struct pwm_device * + * mchp_core_pwm_calc_period(). + * The period is locked and we cannot change this, so we abort. + */ +- if (hw_period_steps == MCHPCOREPWM_PERIOD_STEPS_MAX) ++ if (hw_period_steps > MCHPCOREPWM_PERIOD_STEPS_MAX) + return -EINVAL; + + prescale = hw_prescale; +diff --git a/drivers/rtc/rtc-zynqmp.c b/drivers/rtc/rtc-zynqmp.c +index 08ed171bdab43a..b6f96c10196ae3 100644 +--- a/drivers/rtc/rtc-zynqmp.c ++++ b/drivers/rtc/rtc-zynqmp.c +@@ -318,8 +318,8 @@ static int xlnx_rtc_probe(struct platform_device *pdev) + return ret; + } + +- /* Getting the rtc_clk info */ +- xrtcdev->rtc_clk = devm_clk_get_optional(&pdev->dev, "rtc_clk"); ++ /* Getting the rtc info */ ++ xrtcdev->rtc_clk = devm_clk_get_optional(&pdev->dev, "rtc"); + if (IS_ERR(xrtcdev->rtc_clk)) { + if (PTR_ERR(xrtcdev->rtc_clk) != -EPROBE_DEFER) + dev_warn(&pdev->dev, "Device clock not found.\n"); +diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h +index 7cf998e3cc681c..78a10d4979e90e 100644 +--- a/drivers/scsi/qla2xxx/qla_def.h ++++ b/drivers/scsi/qla2xxx/qla_def.h +@@ -4099,6 +4099,8 @@ struct qla_hw_data { + uint32_t npiv_supported :1; + uint32_t pci_channel_io_perm_failure :1; + uint32_t fce_enabled :1; ++ uint32_t user_enabled_fce :1; ++ uint32_t fce_dump_buf_alloced :1; + uint32_t fac_supported :1; + + uint32_t chip_reset_done :1; +diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c +index 081af4d420a05f..4a82b377928d49 100644 +--- a/drivers/scsi/qla2xxx/qla_dfs.c ++++ b/drivers/scsi/qla2xxx/qla_dfs.c +@@ -409,26 +409,31 @@ qla2x00_dfs_fce_show(struct seq_file *s, void *unused) + + mutex_lock(&ha->fce_mutex); + +- seq_puts(s, "FCE Trace Buffer\n"); +- seq_printf(s, "In Pointer = %llx\n\n", (unsigned long long)ha->fce_wr); +- seq_printf(s, "Base = %llx\n\n", (unsigned long long) ha->fce_dma); +- seq_puts(s, "FCE Enable Registers\n"); +- seq_printf(s, "%08x %08x %08x %08x %08x %08x\n", +- ha->fce_mb[0], ha->fce_mb[2], ha->fce_mb[3], ha->fce_mb[4], +- ha->fce_mb[5], ha->fce_mb[6]); +- +- fce = (uint32_t *) ha->fce; +- fce_start = (unsigned long long) ha->fce_dma; +- for (cnt = 0; cnt < fce_calc_size(ha->fce_bufs) / 4; cnt++) { +- if (cnt % 8 == 0) +- seq_printf(s, "\n%llx: ", +- (unsigned long long)((cnt * 4) + fce_start)); +- else +- seq_putc(s, ' '); +- seq_printf(s, "%08x", *fce++); +- } ++ if (ha->flags.user_enabled_fce) { ++ seq_puts(s, "FCE Trace Buffer\n"); ++ seq_printf(s, "In Pointer = %llx\n\n", (unsigned long long)ha->fce_wr); ++ seq_printf(s, "Base = %llx\n\n", (unsigned long long)ha->fce_dma); ++ seq_puts(s, "FCE Enable Registers\n"); ++ seq_printf(s, "%08x %08x %08x %08x %08x %08x\n", ++ ha->fce_mb[0], ha->fce_mb[2], ha->fce_mb[3], ha->fce_mb[4], ++ ha->fce_mb[5], ha->fce_mb[6]); ++ ++ fce = (uint32_t *)ha->fce; ++ fce_start = (unsigned long long)ha->fce_dma; ++ for (cnt = 0; cnt < fce_calc_size(ha->fce_bufs) / 4; cnt++) { ++ if (cnt % 8 == 0) ++ seq_printf(s, "\n%llx: ", ++ (unsigned long long)((cnt * 4) + fce_start)); ++ else ++ seq_putc(s, ' '); ++ seq_printf(s, "%08x", *fce++); ++ } + +- seq_puts(s, "\nEnd\n"); ++ seq_puts(s, "\nEnd\n"); ++ } else { ++ seq_puts(s, "FCE Trace is currently not enabled\n"); ++ seq_puts(s, "\techo [ 1 | 0 ] > fce\n"); ++ } + + mutex_unlock(&ha->fce_mutex); + +@@ -467,7 +472,7 @@ qla2x00_dfs_fce_release(struct inode *inode, struct file *file) + struct qla_hw_data *ha = vha->hw; + int rval; + +- if (ha->flags.fce_enabled) ++ if (ha->flags.fce_enabled || !ha->fce) + goto out; + + mutex_lock(&ha->fce_mutex); +@@ -488,11 +493,88 @@ qla2x00_dfs_fce_release(struct inode *inode, struct file *file) + return single_release(inode, file); + } + ++static ssize_t ++qla2x00_dfs_fce_write(struct file *file, const char __user *buffer, ++ size_t count, loff_t *pos) ++{ ++ struct seq_file *s = file->private_data; ++ struct scsi_qla_host *vha = s->private; ++ struct qla_hw_data *ha = vha->hw; ++ char *buf; ++ int rc = 0; ++ unsigned long enable; ++ ++ if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) && ++ !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) { ++ ql_dbg(ql_dbg_user, vha, 0xd034, ++ "this adapter does not support FCE."); ++ return -EINVAL; ++ } ++ ++ buf = memdup_user_nul(buffer, count); ++ if (IS_ERR(buf)) { ++ ql_dbg(ql_dbg_user, vha, 0xd037, ++ "fail to copy user buffer."); ++ return PTR_ERR(buf); ++ } ++ ++ enable = kstrtoul(buf, 0, 0); ++ rc = count; ++ ++ mutex_lock(&ha->fce_mutex); ++ ++ if (enable) { ++ if (ha->flags.user_enabled_fce) { ++ mutex_unlock(&ha->fce_mutex); ++ goto out_free; ++ } ++ ha->flags.user_enabled_fce = 1; ++ if (!ha->fce) { ++ rc = qla2x00_alloc_fce_trace(vha); ++ if (rc) { ++ ha->flags.user_enabled_fce = 0; ++ mutex_unlock(&ha->fce_mutex); ++ goto out_free; ++ } ++ ++ /* adjust fw dump buffer to take into account of this feature */ ++ if (!ha->flags.fce_dump_buf_alloced) ++ qla2x00_alloc_fw_dump(vha); ++ } ++ ++ if (!ha->flags.fce_enabled) ++ qla_enable_fce_trace(vha); ++ ++ ql_dbg(ql_dbg_user, vha, 0xd045, "User enabled FCE .\n"); ++ } else { ++ if (!ha->flags.user_enabled_fce) { ++ mutex_unlock(&ha->fce_mutex); ++ goto out_free; ++ } ++ ha->flags.user_enabled_fce = 0; ++ if (ha->flags.fce_enabled) { ++ qla2x00_disable_fce_trace(vha, NULL, NULL); ++ ha->flags.fce_enabled = 0; ++ } ++ ++ qla2x00_free_fce_trace(ha); ++ /* no need to re-adjust fw dump buffer */ ++ ++ ql_dbg(ql_dbg_user, vha, 0xd04f, "User disabled FCE .\n"); ++ } ++ ++ mutex_unlock(&ha->fce_mutex); ++out_free: ++ kfree(buf); ++ return rc; ++} ++ + static const struct file_operations dfs_fce_ops = { + .open = qla2x00_dfs_fce_open, + .read = seq_read, + .llseek = seq_lseek, + .release = qla2x00_dfs_fce_release, ++ .write = qla2x00_dfs_fce_write, + }; + + static int +@@ -671,8 +753,6 @@ qla2x00_dfs_setup(scsi_qla_host_t *vha) + if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) && + !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) + goto out; +- if (!ha->fce) +- goto out; + + if (qla2x00_dfs_root) + goto create_dir; +diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h +index cededfda9d0e31..e556f57c91af62 100644 +--- a/drivers/scsi/qla2xxx/qla_gbl.h ++++ b/drivers/scsi/qla2xxx/qla_gbl.h +@@ -11,6 +11,9 @@ + /* + * Global Function Prototypes in qla_init.c source file. + */ ++int qla2x00_alloc_fce_trace(scsi_qla_host_t *); ++void qla2x00_free_fce_trace(struct qla_hw_data *ha); ++void qla_enable_fce_trace(scsi_qla_host_t *); + extern int qla2x00_initialize_adapter(scsi_qla_host_t *); + extern int qla24xx_post_prli_work(struct scsi_qla_host *vha, fc_port_t *fcport); + +diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c +index eda3bdab934d57..5fa2727c1bea76 100644 +--- a/drivers/scsi/qla2xxx/qla_init.c ++++ b/drivers/scsi/qla2xxx/qla_init.c +@@ -2681,7 +2681,7 @@ qla83xx_nic_core_fw_load(scsi_qla_host_t *vha) + return rval; + } + +-static void qla_enable_fce_trace(scsi_qla_host_t *vha) ++void qla_enable_fce_trace(scsi_qla_host_t *vha) + { + int rval; + struct qla_hw_data *ha = vha->hw; +@@ -3717,25 +3717,24 @@ qla24xx_chip_diag(scsi_qla_host_t *vha) + return rval; + } + +-static void +-qla2x00_alloc_fce_trace(scsi_qla_host_t *vha) ++int qla2x00_alloc_fce_trace(scsi_qla_host_t *vha) + { + dma_addr_t tc_dma; + void *tc; + struct qla_hw_data *ha = vha->hw; + + if (!IS_FWI2_CAPABLE(ha)) +- return; ++ return -EINVAL; + + if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) && + !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) +- return; ++ return -EINVAL; + + if (ha->fce) { + ql_dbg(ql_dbg_init, vha, 0x00bd, + "%s: FCE Mem is already allocated.\n", + __func__); +- return; ++ return -EIO; + } + + /* Allocate memory for Fibre Channel Event Buffer. */ +@@ -3745,7 +3744,7 @@ qla2x00_alloc_fce_trace(scsi_qla_host_t *vha) + ql_log(ql_log_warn, vha, 0x00be, + "Unable to allocate (%d KB) for FCE.\n", + FCE_SIZE / 1024); +- return; ++ return -ENOMEM; + } + + ql_dbg(ql_dbg_init, vha, 0x00c0, +@@ -3754,6 +3753,16 @@ qla2x00_alloc_fce_trace(scsi_qla_host_t *vha) + ha->fce_dma = tc_dma; + ha->fce = tc; + ha->fce_bufs = FCE_NUM_BUFFERS; ++ return 0; ++} ++ ++void qla2x00_free_fce_trace(struct qla_hw_data *ha) ++{ ++ if (!ha->fce) ++ return; ++ dma_free_coherent(&ha->pdev->dev, FCE_SIZE, ha->fce, ha->fce_dma); ++ ha->fce = NULL; ++ ha->fce_dma = 0; + } + + static void +@@ -3844,9 +3853,10 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha) + if (ha->tgt.atio_ring) + mq_size += ha->tgt.atio_q_length * sizeof(request_t); + +- qla2x00_alloc_fce_trace(vha); +- if (ha->fce) ++ if (ha->fce) { + fce_size = sizeof(struct qla2xxx_fce_chain) + FCE_SIZE; ++ ha->flags.fce_dump_buf_alloced = 1; ++ } + qla2x00_alloc_eft_trace(vha); + if (ha->eft) + eft_size = EFT_SIZE; +diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c +index 4e872f2559d138..bdbe94f30f0706 100644 +--- a/drivers/scsi/st.c ++++ b/drivers/scsi/st.c +@@ -1028,6 +1028,11 @@ static int test_ready(struct scsi_tape *STp, int do_wait) + retval = new_session ? CHKRES_NEW_SESSION : CHKRES_READY; + break; + } ++ if (STp->first_tur) { ++ /* Don't set pos_unknown right after device recognition */ ++ STp->pos_unknown = 0; ++ STp->first_tur = 0; ++ } + + if (SRpnt != NULL) + st_release_request(SRpnt); +@@ -4326,6 +4331,7 @@ static int st_probe(struct device *dev) + blk_queue_rq_timeout(tpnt->device->request_queue, ST_TIMEOUT); + tpnt->long_timeout = ST_LONG_TIMEOUT; + tpnt->try_dio = try_direct_io; ++ tpnt->first_tur = 1; + + for (i = 0; i < ST_NBR_MODES; i++) { + STm = &(tpnt->modes[i]); +diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h +index 7a68eaba7e810c..1aaaf5369a40fc 100644 +--- a/drivers/scsi/st.h ++++ b/drivers/scsi/st.h +@@ -170,6 +170,7 @@ struct scsi_tape { + unsigned char rew_at_close; /* rewind necessary at close */ + unsigned char inited; + unsigned char cleaning_req; /* cleaning requested? */ ++ unsigned char first_tur; /* first TEST UNIT READY */ + int block_size; + int min_block; + int max_block; +diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c +index b3c588b102d900..b8186feccdf5aa 100644 +--- a/drivers/scsi/storvsc_drv.c ++++ b/drivers/scsi/storvsc_drv.c +@@ -1800,6 +1800,7 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd) + + length = scsi_bufflen(scmnd); + payload = (struct vmbus_packet_mpb_array *)&cmd_request->mpb; ++ payload->range.len = 0; + payload_sz = 0; + + if (scsi_sg_count(scmnd)) { +diff --git a/drivers/soc/mediatek/mtk-devapc.c b/drivers/soc/mediatek/mtk-devapc.c +index b28feb96754021..0dfc1da9471cba 100644 +--- a/drivers/soc/mediatek/mtk-devapc.c ++++ b/drivers/soc/mediatek/mtk-devapc.c +@@ -273,23 +273,31 @@ static int mtk_devapc_probe(struct platform_device *pdev) + return -EINVAL; + + devapc_irq = irq_of_parse_and_map(node, 0); +- if (!devapc_irq) +- return -EINVAL; ++ if (!devapc_irq) { ++ ret = -EINVAL; ++ goto err; ++ } + + ctx->infra_clk = devm_clk_get_enabled(&pdev->dev, "devapc-infra-clock"); +- if (IS_ERR(ctx->infra_clk)) +- return -EINVAL; ++ if (IS_ERR(ctx->infra_clk)) { ++ ret = -EINVAL; ++ goto err; ++ } + + ret = devm_request_irq(&pdev->dev, devapc_irq, devapc_violation_irq, + IRQF_TRIGGER_NONE, "devapc", ctx); + if (ret) +- return ret; ++ goto err; + + platform_set_drvdata(pdev, ctx); + + start_devapc(ctx); + + return 0; ++ ++err: ++ iounmap(ctx->infra_base); ++ return ret; + } + + static int mtk_devapc_remove(struct platform_device *pdev) +diff --git a/drivers/soc/qcom/smem_state.c b/drivers/soc/qcom/smem_state.c +index e848cc9a3cf801..a8be3a2f33824f 100644 +--- a/drivers/soc/qcom/smem_state.c ++++ b/drivers/soc/qcom/smem_state.c +@@ -116,7 +116,8 @@ struct qcom_smem_state *qcom_smem_state_get(struct device *dev, + + if (args.args_count != 1) { + dev_err(dev, "invalid #qcom,smem-state-cells\n"); +- return ERR_PTR(-EINVAL); ++ state = ERR_PTR(-EINVAL); ++ goto put; + } + + state = of_node_to_state(args.np); +diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c +index 2af2b2406fdf39..714d1259b3137c 100644 +--- a/drivers/soc/qcom/socinfo.c ++++ b/drivers/soc/qcom/socinfo.c +@@ -760,7 +760,7 @@ static int qcom_socinfo_probe(struct platform_device *pdev) + if (!qs->attr.soc_id || !qs->attr.revision) + return -ENOMEM; + +- if (offsetof(struct socinfo, serial_num) <= item_size) { ++ if (offsetofend(struct socinfo, serial_num) <= item_size) { + qs->attr.serial_number = devm_kasprintf(&pdev->dev, GFP_KERNEL, + "%u", + le32_to_cpu(info->serial_num)); +diff --git a/drivers/spi/atmel-quadspi.c b/drivers/spi/atmel-quadspi.c +index e7ae7cb4b92a8b..4396d988768f65 100644 +--- a/drivers/spi/atmel-quadspi.c ++++ b/drivers/spi/atmel-quadspi.c +@@ -138,11 +138,15 @@ + #define QSPI_WPSR_WPVSRC_MASK GENMASK(15, 8) + #define QSPI_WPSR_WPVSRC(src) (((src) << 8) & QSPI_WPSR_WPVSRC) + ++#define ATMEL_QSPI_TIMEOUT 1000 /* ms */ ++ + struct atmel_qspi_caps { + bool has_qspick; + bool has_ricr; + }; + ++struct atmel_qspi_ops; ++ + struct atmel_qspi { + void __iomem *regs; + void __iomem *mem; +@@ -150,13 +154,22 @@ struct atmel_qspi { + struct clk *qspick; + struct platform_device *pdev; + const struct atmel_qspi_caps *caps; ++ const struct atmel_qspi_ops *ops; + resource_size_t mmap_size; + u32 pending; ++ u32 irq_mask; + u32 mr; + u32 scr; + struct completion cmd_completion; + }; + ++struct atmel_qspi_ops { ++ int (*set_cfg)(struct atmel_qspi *aq, const struct spi_mem_op *op, ++ u32 *offset); ++ int (*transfer)(struct spi_mem *mem, const struct spi_mem_op *op, ++ u32 offset); ++}; ++ + struct atmel_qspi_mode { + u8 cmd_buswidth; + u8 addr_buswidth; +@@ -404,10 +417,67 @@ static int atmel_qspi_set_cfg(struct atmel_qspi *aq, + return 0; + } + ++static int atmel_qspi_wait_for_completion(struct atmel_qspi *aq, u32 irq_mask) ++{ ++ int err = 0; ++ u32 sr; ++ ++ /* Poll INSTRuction End status */ ++ sr = atmel_qspi_read(aq, QSPI_SR); ++ if ((sr & irq_mask) == irq_mask) ++ return 0; ++ ++ /* Wait for INSTRuction End interrupt */ ++ reinit_completion(&aq->cmd_completion); ++ aq->pending = sr & irq_mask; ++ aq->irq_mask = irq_mask; ++ atmel_qspi_write(irq_mask, aq, QSPI_IER); ++ if (!wait_for_completion_timeout(&aq->cmd_completion, ++ msecs_to_jiffies(ATMEL_QSPI_TIMEOUT))) ++ err = -ETIMEDOUT; ++ atmel_qspi_write(irq_mask, aq, QSPI_IDR); ++ ++ return err; ++} ++ ++static int atmel_qspi_transfer(struct spi_mem *mem, ++ const struct spi_mem_op *op, u32 offset) ++{ ++ struct atmel_qspi *aq = spi_controller_get_devdata(mem->spi->controller); ++ ++ /* Skip to the final steps if there is no data */ ++ if (!op->data.nbytes) ++ return atmel_qspi_wait_for_completion(aq, ++ QSPI_SR_CMD_COMPLETED); ++ ++ /* Dummy read of QSPI_IFR to synchronize APB and AHB accesses */ ++ (void)atmel_qspi_read(aq, QSPI_IFR); ++ ++ /* Send/Receive data */ ++ if (op->data.dir == SPI_MEM_DATA_IN) { ++ memcpy_fromio(op->data.buf.in, aq->mem + offset, ++ op->data.nbytes); ++ ++ /* Synchronize AHB and APB accesses again */ ++ rmb(); ++ } else { ++ memcpy_toio(aq->mem + offset, op->data.buf.out, ++ op->data.nbytes); ++ ++ /* Synchronize AHB and APB accesses again */ ++ wmb(); ++ } ++ ++ /* Release the chip-select */ ++ atmel_qspi_write(QSPI_CR_LASTXFER, aq, QSPI_CR); ++ ++ return atmel_qspi_wait_for_completion(aq, QSPI_SR_CMD_COMPLETED); ++} ++ + static int atmel_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) + { + struct atmel_qspi *aq = spi_controller_get_devdata(mem->spi->controller); +- u32 sr, offset; ++ u32 offset; + int err; + + /* +@@ -416,46 +486,20 @@ static int atmel_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) + * when the flash memories overrun the controller's memory space. + */ + if (op->addr.val + op->data.nbytes > aq->mmap_size) +- return -ENOTSUPP; ++ return -EOPNOTSUPP; ++ ++ if (op->addr.nbytes > 4) ++ return -EOPNOTSUPP; + + err = pm_runtime_resume_and_get(&aq->pdev->dev); + if (err < 0) + return err; + +- err = atmel_qspi_set_cfg(aq, op, &offset); ++ err = aq->ops->set_cfg(aq, op, &offset); + if (err) + goto pm_runtime_put; + +- /* Skip to the final steps if there is no data */ +- if (op->data.nbytes) { +- /* Dummy read of QSPI_IFR to synchronize APB and AHB accesses */ +- (void)atmel_qspi_read(aq, QSPI_IFR); +- +- /* Send/Receive data */ +- if (op->data.dir == SPI_MEM_DATA_IN) +- memcpy_fromio(op->data.buf.in, aq->mem + offset, +- op->data.nbytes); +- else +- memcpy_toio(aq->mem + offset, op->data.buf.out, +- op->data.nbytes); +- +- /* Release the chip-select */ +- atmel_qspi_write(QSPI_CR_LASTXFER, aq, QSPI_CR); +- } +- +- /* Poll INSTRuction End status */ +- sr = atmel_qspi_read(aq, QSPI_SR); +- if ((sr & QSPI_SR_CMD_COMPLETED) == QSPI_SR_CMD_COMPLETED) +- goto pm_runtime_put; +- +- /* Wait for INSTRuction End interrupt */ +- reinit_completion(&aq->cmd_completion); +- aq->pending = sr & QSPI_SR_CMD_COMPLETED; +- atmel_qspi_write(QSPI_SR_CMD_COMPLETED, aq, QSPI_IER); +- if (!wait_for_completion_timeout(&aq->cmd_completion, +- msecs_to_jiffies(1000))) +- err = -ETIMEDOUT; +- atmel_qspi_write(QSPI_SR_CMD_COMPLETED, aq, QSPI_IDR); ++ err = aq->ops->transfer(mem, op, offset); + + pm_runtime_put: + pm_runtime_mark_last_busy(&aq->pdev->dev); +@@ -571,12 +615,17 @@ static irqreturn_t atmel_qspi_interrupt(int irq, void *dev_id) + return IRQ_NONE; + + aq->pending |= pending; +- if ((aq->pending & QSPI_SR_CMD_COMPLETED) == QSPI_SR_CMD_COMPLETED) ++ if ((aq->pending & aq->irq_mask) == aq->irq_mask) + complete(&aq->cmd_completion); + + return IRQ_HANDLED; + } + ++static const struct atmel_qspi_ops atmel_qspi_ops = { ++ .set_cfg = atmel_qspi_set_cfg, ++ .transfer = atmel_qspi_transfer, ++}; ++ + static int atmel_qspi_probe(struct platform_device *pdev) + { + struct spi_controller *ctrl; +@@ -601,6 +650,7 @@ static int atmel_qspi_probe(struct platform_device *pdev) + + init_completion(&aq->cmd_completion); + aq->pdev = pdev; ++ aq->ops = &atmel_qspi_ops; + + /* Map the registers */ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qspi_base"); +diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c +index f793624fd5018f..4350a69d97d7ac 100644 +--- a/drivers/tty/serial/sh-sci.c ++++ b/drivers/tty/serial/sh-sci.c +@@ -164,6 +164,7 @@ struct sci_port { + static struct sci_port sci_ports[SCI_NPORTS]; + static unsigned long sci_ports_in_use; + static struct uart_driver sci_uart_driver; ++static bool sci_uart_earlycon; + + static inline struct sci_port * + to_sci_port(struct uart_port *uart) +@@ -3391,6 +3392,7 @@ static int sci_probe_single(struct platform_device *dev, + static int sci_probe(struct platform_device *dev) + { + struct plat_sci_port *p; ++ struct resource *res; + struct sci_port *sp; + unsigned int dev_id; + int ret; +@@ -3420,6 +3422,26 @@ static int sci_probe(struct platform_device *dev) + } + + sp = &sci_ports[dev_id]; ++ ++ /* ++ * In case: ++ * - the probed port alias is zero (as the one used by earlycon), and ++ * - the earlycon is still active (e.g., "earlycon keep_bootcon" in ++ * bootargs) ++ * ++ * defer the probe of this serial. This is a debug scenario and the user ++ * must be aware of it. ++ * ++ * Except when the probed port is the same as the earlycon port. ++ */ ++ ++ res = platform_get_resource(dev, IORESOURCE_MEM, 0); ++ if (!res) ++ return -ENODEV; ++ ++ if (sci_uart_earlycon && sp == &sci_ports[0] && sp->port.mapbase != res->start) ++ return dev_err_probe(&dev->dev, -EBUSY, "sci_port[0] is used by earlycon!\n"); ++ + platform_set_drvdata(dev, sp); + + ret = sci_probe_single(dev, dev_id, p, sp); +@@ -3503,7 +3525,7 @@ sh_early_platform_init_buffer("earlyprintk", &sci_driver, + early_serial_buf, ARRAY_SIZE(early_serial_buf)); + #endif + #ifdef CONFIG_SERIAL_SH_SCI_EARLYCON +-static struct plat_sci_port port_cfg __initdata; ++static struct plat_sci_port port_cfg; + + static int __init early_console_setup(struct earlycon_device *device, + int type) +@@ -3518,6 +3540,7 @@ static int __init early_console_setup(struct earlycon_device *device, + port_cfg.type = type; + sci_ports[0].cfg = &port_cfg; + sci_ports[0].params = sci_probe_regmap(&port_cfg); ++ sci_uart_earlycon = true; + port_cfg.scscr = sci_serial_in(&sci_ports[0].port, SCSCR); + sci_serial_out(&sci_ports[0].port, SCSCR, + SCSCR_RE | SCSCR_TE | port_cfg.scscr); +diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c +index 2e5e86a00a77d7..7f83d278001701 100644 +--- a/drivers/tty/serial/xilinx_uartps.c ++++ b/drivers/tty/serial/xilinx_uartps.c +@@ -268,7 +268,7 @@ static void cdns_uart_handle_rx(void *dev_id, unsigned int isrstatus) + continue; + } + +- if (uart_handle_sysrq_char(port, data)) ++ if (uart_prepare_sysrq_char(port, data)) + continue; + + if (is_rxbs_support) { +@@ -369,7 +369,7 @@ static irqreturn_t cdns_uart_isr(int irq, void *dev_id) + !(readl(port->membase + CDNS_UART_CR) & CDNS_UART_CR_RX_DIS)) + cdns_uart_handle_rx(dev_id, isrstatus); + +- spin_unlock(&port->lock); ++ uart_unlock_and_check_sysrq(port); + return IRQ_HANDLED; + } + +@@ -1229,10 +1229,8 @@ static void cdns_uart_console_write(struct console *co, const char *s, + unsigned int imr, ctrl; + int locked = 1; + +- if (port->sysrq) +- locked = 0; +- else if (oops_in_progress) +- locked = spin_trylock_irqsave(&port->lock, flags); ++ if (oops_in_progress) ++ locked = uart_port_trylock_irqsave(port, &flags); + else + spin_lock_irqsave(&port->lock, flags); + +diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c +index c999acba0f30c3..c5a6b133d3643f 100644 +--- a/drivers/ufs/host/ufs-qcom.c ++++ b/drivers/ufs/host/ufs-qcom.c +@@ -158,8 +158,9 @@ static int ufs_qcom_ice_program_key(struct ufs_hba *hba, + { + struct ufs_qcom_host *host = ufshcd_get_variant(hba); + union ufs_crypto_cap_entry cap; +- bool config_enable = +- cfg->config_enable & UFS_CRYPTO_CONFIGURATION_ENABLE; ++ ++ if (!(cfg->config_enable & UFS_CRYPTO_CONFIGURATION_ENABLE)) ++ return qcom_ice_evict_key(host->ice, slot); + + /* Only AES-256-XTS has been tested so far. */ + cap = hba->crypto_cap_array[cfg->crypto_cap_idx]; +@@ -167,14 +168,11 @@ static int ufs_qcom_ice_program_key(struct ufs_hba *hba, + cap.key_size != UFS_CRYPTO_KEY_SIZE_256) + return -EOPNOTSUPP; + +- if (config_enable) +- return qcom_ice_program_key(host->ice, +- QCOM_ICE_CRYPTO_ALG_AES_XTS, +- QCOM_ICE_CRYPTO_KEY_SIZE_256, +- cfg->crypto_key, +- cfg->data_unit_size, slot); +- else +- return qcom_ice_evict_key(host->ice, slot); ++ return qcom_ice_program_key(host->ice, ++ QCOM_ICE_CRYPTO_ALG_AES_XTS, ++ QCOM_ICE_CRYPTO_KEY_SIZE_256, ++ cfg->crypto_key, ++ cfg->data_unit_size, slot); + } + + #else +diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c +index 8ac50b9155ac40..a7cd0a06879e61 100644 +--- a/drivers/usb/gadget/function/f_tcm.c ++++ b/drivers/usb/gadget/function/f_tcm.c +@@ -245,7 +245,6 @@ static int bot_send_write_request(struct usbg_cmd *cmd) + { + struct f_uas *fu = cmd->fu; + struct se_cmd *se_cmd = &cmd->se_cmd; +- struct usb_gadget *gadget = fuas_to_gadget(fu); + int ret; + + init_completion(&cmd->write_complete); +@@ -256,22 +255,6 @@ static int bot_send_write_request(struct usbg_cmd *cmd) + return -EINVAL; + } + +- if (!gadget->sg_supported) { +- cmd->data_buf = kmalloc(se_cmd->data_length, GFP_KERNEL); +- if (!cmd->data_buf) +- return -ENOMEM; +- +- fu->bot_req_out->buf = cmd->data_buf; +- } else { +- fu->bot_req_out->buf = NULL; +- fu->bot_req_out->num_sgs = se_cmd->t_data_nents; +- fu->bot_req_out->sg = se_cmd->t_data_sg; +- } +- +- fu->bot_req_out->complete = usbg_data_write_cmpl; +- fu->bot_req_out->length = se_cmd->data_length; +- fu->bot_req_out->context = cmd; +- + ret = usbg_prepare_w_request(cmd, fu->bot_req_out); + if (ret) + goto cleanup; +@@ -973,6 +956,7 @@ static void usbg_data_write_cmpl(struct usb_ep *ep, struct usb_request *req) + return; + + cleanup: ++ target_put_sess_cmd(se_cmd); + transport_generic_free_cmd(&cmd->se_cmd, 0); + } + +@@ -1065,7 +1049,7 @@ static void usbg_cmd_work(struct work_struct *work) + + out: + transport_send_check_condition_and_sense(se_cmd, +- TCM_UNSUPPORTED_SCSI_OPCODE, 1); ++ TCM_UNSUPPORTED_SCSI_OPCODE, 0); + } + + static struct usbg_cmd *usbg_get_cmd(struct f_uas *fu, +@@ -1193,7 +1177,7 @@ static void bot_cmd_work(struct work_struct *work) + + out: + transport_send_check_condition_and_sense(se_cmd, +- TCM_UNSUPPORTED_SCSI_OPCODE, 1); ++ TCM_UNSUPPORTED_SCSI_OPCODE, 0); + } + + static int bot_submit_command(struct f_uas *fu, +@@ -1966,43 +1950,39 @@ static int tcm_bind(struct usb_configuration *c, struct usb_function *f) + bot_intf_desc.bInterfaceNumber = iface; + uasp_intf_desc.bInterfaceNumber = iface; + fu->iface = iface; +- ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_bi_desc, +- &uasp_bi_ep_comp_desc); ++ ep = usb_ep_autoconfig(gadget, &uasp_fs_bi_desc); + if (!ep) + goto ep_fail; + + fu->ep_in = ep; + +- ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_bo_desc, +- &uasp_bo_ep_comp_desc); ++ ep = usb_ep_autoconfig(gadget, &uasp_fs_bo_desc); + if (!ep) + goto ep_fail; + fu->ep_out = ep; + +- ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_status_desc, +- &uasp_status_in_ep_comp_desc); ++ ep = usb_ep_autoconfig(gadget, &uasp_fs_status_desc); + if (!ep) + goto ep_fail; + fu->ep_status = ep; + +- ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_cmd_desc, +- &uasp_cmd_comp_desc); ++ ep = usb_ep_autoconfig(gadget, &uasp_fs_cmd_desc); + if (!ep) + goto ep_fail; + fu->ep_cmd = ep; + + /* Assume endpoint addresses are the same for both speeds */ +- uasp_bi_desc.bEndpointAddress = uasp_ss_bi_desc.bEndpointAddress; +- uasp_bo_desc.bEndpointAddress = uasp_ss_bo_desc.bEndpointAddress; ++ uasp_bi_desc.bEndpointAddress = uasp_fs_bi_desc.bEndpointAddress; ++ uasp_bo_desc.bEndpointAddress = uasp_fs_bo_desc.bEndpointAddress; + uasp_status_desc.bEndpointAddress = +- uasp_ss_status_desc.bEndpointAddress; +- uasp_cmd_desc.bEndpointAddress = uasp_ss_cmd_desc.bEndpointAddress; +- +- uasp_fs_bi_desc.bEndpointAddress = uasp_ss_bi_desc.bEndpointAddress; +- uasp_fs_bo_desc.bEndpointAddress = uasp_ss_bo_desc.bEndpointAddress; +- uasp_fs_status_desc.bEndpointAddress = +- uasp_ss_status_desc.bEndpointAddress; +- uasp_fs_cmd_desc.bEndpointAddress = uasp_ss_cmd_desc.bEndpointAddress; ++ uasp_fs_status_desc.bEndpointAddress; ++ uasp_cmd_desc.bEndpointAddress = uasp_fs_cmd_desc.bEndpointAddress; ++ ++ uasp_ss_bi_desc.bEndpointAddress = uasp_fs_bi_desc.bEndpointAddress; ++ uasp_ss_bo_desc.bEndpointAddress = uasp_fs_bo_desc.bEndpointAddress; ++ uasp_ss_status_desc.bEndpointAddress = ++ uasp_fs_status_desc.bEndpointAddress; ++ uasp_ss_cmd_desc.bEndpointAddress = uasp_fs_cmd_desc.bEndpointAddress; + + ret = usb_assign_descriptors(f, uasp_fs_function_desc, + uasp_hs_function_desc, uasp_ss_function_desc, +diff --git a/drivers/vfio/platform/vfio_platform_common.c b/drivers/vfio/platform/vfio_platform_common.c +index 3bf1043cd7957c..d63c2d266d0735 100644 +--- a/drivers/vfio/platform/vfio_platform_common.c ++++ b/drivers/vfio/platform/vfio_platform_common.c +@@ -393,6 +393,11 @@ static ssize_t vfio_platform_read_mmio(struct vfio_platform_region *reg, + + count = min_t(size_t, count, reg->size - off); + ++ if (off >= reg->size) ++ return -EINVAL; ++ ++ count = min_t(size_t, count, reg->size - off); ++ + if (!reg->ioaddr) { + reg->ioaddr = + ioremap(reg->addr, reg->size); +@@ -477,6 +482,11 @@ static ssize_t vfio_platform_write_mmio(struct vfio_platform_region *reg, + + count = min_t(size_t, count, reg->size - off); + ++ if (off >= reg->size) ++ return -EINVAL; ++ ++ count = min_t(size_t, count, reg->size - off); ++ + if (!reg->ioaddr) { + reg->ioaddr = + ioremap(reg->addr, reg->size); +diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c +index cd6d5bbb4b9df5..3f740d8abb4fe2 100644 +--- a/fs/binfmt_flat.c ++++ b/fs/binfmt_flat.c +@@ -478,7 +478,7 @@ static int load_flat_file(struct linux_binprm *bprm, + * 28 bits (256 MB) is way more than reasonable in this case. + * If some top bits are set we have probable binary corruption. + */ +- if ((text_len | data_len | bss_len | stack_len | full_data) >> 28) { ++ if ((text_len | data_len | bss_len | stack_len | relocs | full_data) >> 28) { + pr_err("bad header\n"); + ret = -ENOEXEC; + goto err; +diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c +index fc6c91773bc894..c2d0c62b087c22 100644 +--- a/fs/btrfs/file.c ++++ b/fs/btrfs/file.c +@@ -241,7 +241,7 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans, + if (args->drop_cache) + btrfs_drop_extent_map_range(inode, args->start, args->end - 1, false); + +- if (args->start >= inode->disk_i_size && !args->replace_extent) ++ if (data_race(args->start >= inode->disk_i_size) && !args->replace_extent) + modify_tree = 0; + + update_refs = (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID); +diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c +index eb9319d856f2d8..cedffa567a7584 100644 +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -7153,8 +7153,6 @@ noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len, + ret = -EAGAIN; + goto out; + } +- +- cond_resched(); + } + + if (orig_start) +@@ -10835,6 +10833,8 @@ static int btrfs_swap_activate(struct swap_info_struct *sis, struct file *file, + } + + start += len; ++ ++ cond_resched(); + } + + if (bsi.block_len) +diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c +index 8a3c46cb67f538..86d846eb5ed492 100644 +--- a/fs/btrfs/ordered-data.c ++++ b/fs/btrfs/ordered-data.c +@@ -1171,6 +1171,18 @@ struct btrfs_ordered_extent *btrfs_split_ordered_extent( + */ + if (WARN_ON_ONCE(len >= ordered->num_bytes)) + return ERR_PTR(-EINVAL); ++ /* ++ * If our ordered extent had an error there's no point in continuing. ++ * The error may have come from a transaction abort done either by this ++ * task or some other concurrent task, and the transaction abort path ++ * iterates over all existing ordered extents and sets the flag ++ * BTRFS_ORDERED_IOERR on them. ++ */ ++ if (unlikely(flags & (1U << BTRFS_ORDERED_IOERR))) { ++ const int fs_error = BTRFS_FS_ERROR(fs_info); ++ ++ return fs_error ? ERR_PTR(fs_error) : ERR_PTR(-EIO); ++ } + /* We cannot split partially completed ordered extents. */ + if (ordered->bytes_left) { + ASSERT(!(flags & ~BTRFS_ORDERED_TYPE_FLAGS)); +diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c +index 299eac696eb426..537e184b4b1dfc 100644 +--- a/fs/btrfs/relocation.c ++++ b/fs/btrfs/relocation.c +@@ -4378,8 +4378,18 @@ int btrfs_reloc_cow_block(struct btrfs_trans_handle *trans, + WARN_ON(!first_cow && level == 0); + + node = rc->backref_cache.path[level]; +- BUG_ON(node->bytenr != buf->start && +- node->new_bytenr != buf->start); ++ ++ /* ++ * If node->bytenr != buf->start and node->new_bytenr != ++ * buf->start then we've got the wrong backref node for what we ++ * expected to see here and the cache is incorrect. ++ */ ++ if (unlikely(node->bytenr != buf->start && node->new_bytenr != buf->start)) { ++ btrfs_err(fs_info, ++"bytenr %llu was found but our backref cache was expecting %llu or %llu", ++ buf->start, node->bytenr, node->new_bytenr); ++ return -EUCLEAN; ++ } + + btrfs_backref_drop_node_buffer(node); + atomic_inc(&cow->refs); +diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c +index 0548072c642fb0..aa03db69a0164c 100644 +--- a/fs/btrfs/transaction.c ++++ b/fs/btrfs/transaction.c +@@ -278,8 +278,10 @@ static noinline int join_transaction(struct btrfs_fs_info *fs_info, + cur_trans = fs_info->running_transaction; + if (cur_trans) { + if (TRANS_ABORTED(cur_trans)) { ++ const int abort_error = cur_trans->aborted; ++ + spin_unlock(&fs_info->trans_lock); +- return cur_trans->aborted; ++ return abort_error; + } + if (btrfs_blocked_trans_types[cur_trans->state] & type) { + spin_unlock(&fs_info->trans_lock); +diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c +index 35ba2117a6f652..3e63cfe1587472 100644 +--- a/fs/cachefiles/interface.c ++++ b/fs/cachefiles/interface.c +@@ -327,6 +327,8 @@ static void cachefiles_commit_object(struct cachefiles_object *object, + static void cachefiles_clean_up_object(struct cachefiles_object *object, + struct cachefiles_cache *cache) + { ++ struct file *file; ++ + if (test_bit(FSCACHE_COOKIE_RETIRED, &object->cookie->flags)) { + if (!test_bit(CACHEFILES_OBJECT_USING_TMPFILE, &object->flags)) { + cachefiles_see_object(object, cachefiles_obj_see_clean_delete); +@@ -342,10 +344,14 @@ static void cachefiles_clean_up_object(struct cachefiles_object *object, + } + + cachefiles_unmark_inode_in_use(object, object->file); +- if (object->file) { +- fput(object->file); +- object->file = NULL; +- } ++ ++ spin_lock(&object->lock); ++ file = object->file; ++ object->file = NULL; ++ spin_unlock(&object->lock); ++ ++ if (file) ++ fput(file); + } + + /* +diff --git a/fs/cachefiles/ondemand.c b/fs/cachefiles/ondemand.c +index d1a0264b08a6c1..3389a373faf680 100644 +--- a/fs/cachefiles/ondemand.c ++++ b/fs/cachefiles/ondemand.c +@@ -61,20 +61,26 @@ static ssize_t cachefiles_ondemand_fd_write_iter(struct kiocb *kiocb, + { + struct cachefiles_object *object = kiocb->ki_filp->private_data; + struct cachefiles_cache *cache = object->volume->cache; +- struct file *file = object->file; ++ struct file *file; + size_t len = iter->count; + loff_t pos = kiocb->ki_pos; + const struct cred *saved_cred; + int ret; + +- if (!file) ++ spin_lock(&object->lock); ++ file = object->file; ++ if (!file) { ++ spin_unlock(&object->lock); + return -ENOBUFS; ++ } ++ get_file(file); ++ spin_unlock(&object->lock); + + cachefiles_begin_secure(cache, &saved_cred); + ret = __cachefiles_prepare_write(object, file, &pos, &len, true); + cachefiles_end_secure(cache, saved_cred); + if (ret < 0) +- return ret; ++ goto out; + + trace_cachefiles_ondemand_fd_write(object, file_inode(file), pos, len); + ret = __cachefiles_write(object, file, pos, iter, NULL, NULL); +@@ -83,6 +89,8 @@ static ssize_t cachefiles_ondemand_fd_write_iter(struct kiocb *kiocb, + kiocb->ki_pos += ret; + } + ++out: ++ fput(file); + return ret; + } + +@@ -90,12 +98,22 @@ static loff_t cachefiles_ondemand_fd_llseek(struct file *filp, loff_t pos, + int whence) + { + struct cachefiles_object *object = filp->private_data; +- struct file *file = object->file; ++ struct file *file; ++ loff_t ret; + +- if (!file) ++ spin_lock(&object->lock); ++ file = object->file; ++ if (!file) { ++ spin_unlock(&object->lock); + return -ENOBUFS; ++ } ++ get_file(file); ++ spin_unlock(&object->lock); + +- return vfs_llseek(file, pos, whence); ++ ret = vfs_llseek(file, pos, whence); ++ fput(file); ++ ++ return ret; + } + + static long cachefiles_ondemand_fd_ioctl(struct file *filp, unsigned int ioctl, +diff --git a/fs/exec.c b/fs/exec.c +index 7776209d98c10b..4a6255aa4ea7f3 100644 +--- a/fs/exec.c ++++ b/fs/exec.c +@@ -1362,7 +1362,28 @@ int begin_new_exec(struct linux_binprm * bprm) + set_dumpable(current->mm, SUID_DUMP_USER); + + perf_event_exec(); +- __set_task_comm(me, kbasename(bprm->filename), true); ++ ++ /* ++ * If the original filename was empty, alloc_bprm() made up a path ++ * that will probably not be useful to admins running ps or similar. ++ * Let's fix it up to be something reasonable. ++ */ ++ if (bprm->comm_from_dentry) { ++ /* ++ * Hold RCU lock to keep the name from being freed behind our back. ++ * Use acquire semantics to make sure the terminating NUL from ++ * __d_alloc() is seen. ++ * ++ * Note, we're deliberately sloppy here. We don't need to care about ++ * detecting a concurrent rename and just want a terminated name. ++ */ ++ rcu_read_lock(); ++ __set_task_comm(me, smp_load_acquire(&bprm->file->f_path.dentry->d_name.name), ++ true); ++ rcu_read_unlock(); ++ } else { ++ __set_task_comm(me, kbasename(bprm->filename), true); ++ } + + /* An exec changes our domain. We are no longer part of the thread + group */ +@@ -1521,11 +1542,13 @@ static struct linux_binprm *alloc_bprm(int fd, struct filename *filename) + if (fd == AT_FDCWD || filename->name[0] == '/') { + bprm->filename = filename->name; + } else { +- if (filename->name[0] == '\0') ++ if (filename->name[0] == '\0') { + bprm->fdpath = kasprintf(GFP_KERNEL, "/dev/fd/%d", fd); +- else ++ bprm->comm_from_dentry = 1; ++ } else { + bprm->fdpath = kasprintf(GFP_KERNEL, "/dev/fd/%d/%s", + fd, filename->name); ++ } + if (!bprm->fdpath) + goto out_free; + +diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c +index 3e724cb7ef01d8..2b3c5eea1f1345 100644 +--- a/fs/nfs/flexfilelayout/flexfilelayout.c ++++ b/fs/nfs/flexfilelayout/flexfilelayout.c +@@ -839,6 +839,9 @@ ff_layout_pg_init_read(struct nfs_pageio_descriptor *pgio, + struct nfs4_pnfs_ds *ds; + u32 ds_idx; + ++ if (NFS_SERVER(pgio->pg_inode)->flags & ++ (NFS_MOUNT_SOFT|NFS_MOUNT_SOFTERR)) ++ pgio->pg_maxretrans = io_maxretrans; + retry: + ff_layout_pg_check_layout(pgio, req); + /* Use full layout for now */ +@@ -852,6 +855,8 @@ ff_layout_pg_init_read(struct nfs_pageio_descriptor *pgio, + if (!pgio->pg_lseg) + goto out_nolseg; + } ++ /* Reset wb_nio, since getting layout segment was successful */ ++ req->wb_nio = 0; + + ds = ff_layout_get_ds_for_read(pgio, &ds_idx); + if (!ds) { +@@ -868,14 +873,24 @@ ff_layout_pg_init_read(struct nfs_pageio_descriptor *pgio, + pgm->pg_bsize = mirror->mirror_ds->ds_versions[0].rsize; + + pgio->pg_mirror_idx = ds_idx; +- +- if (NFS_SERVER(pgio->pg_inode)->flags & +- (NFS_MOUNT_SOFT|NFS_MOUNT_SOFTERR)) +- pgio->pg_maxretrans = io_maxretrans; + return; + out_nolseg: +- if (pgio->pg_error < 0) +- return; ++ if (pgio->pg_error < 0) { ++ if (pgio->pg_error != -EAGAIN) ++ return; ++ /* Retry getting layout segment if lower layer returned -EAGAIN */ ++ if (pgio->pg_maxretrans && req->wb_nio++ > pgio->pg_maxretrans) { ++ if (NFS_SERVER(pgio->pg_inode)->flags & NFS_MOUNT_SOFTERR) ++ pgio->pg_error = -ETIMEDOUT; ++ else ++ pgio->pg_error = -EIO; ++ return; ++ } ++ pgio->pg_error = 0; ++ /* Sleep for 1 second before retrying */ ++ ssleep(1); ++ goto retry; ++ } + out_mds: + trace_pnfs_mds_fallback_pg_init_read(pgio->pg_inode, + 0, NFS4_MAX_UINT64, IOMODE_READ, +diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c +index 489592644b68f5..5f2d73f36e0d2f 100644 +--- a/fs/nilfs2/inode.c ++++ b/fs/nilfs2/inode.c +@@ -1267,7 +1267,7 @@ int nilfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, + if (size) { + if (phys && blkphy << blkbits == phys + size) { + /* The current extent goes on */ +- size += n << blkbits; ++ size += (u64)n << blkbits; + } else { + /* Terminate the current extent */ + ret = fiemap_fill_next_extent( +@@ -1280,14 +1280,14 @@ int nilfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, + flags = FIEMAP_EXTENT_MERGED; + logical = blkoff << blkbits; + phys = blkphy << blkbits; +- size = n << blkbits; ++ size = (u64)n << blkbits; + } + } else { + /* Start a new extent */ + flags = FIEMAP_EXTENT_MERGED; + logical = blkoff << blkbits; + phys = blkphy << blkbits; +- size = n << blkbits; ++ size = (u64)n << blkbits; + } + blkoff += n; + } +diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c +index 429c22f911fdae..da1ab3282c1817 100644 +--- a/fs/ocfs2/dir.c ++++ b/fs/ocfs2/dir.c +@@ -1065,26 +1065,39 @@ int ocfs2_find_entry(const char *name, int namelen, + { + struct buffer_head *bh; + struct ocfs2_dir_entry *res_dir = NULL; ++ int ret = 0; + + if (ocfs2_dir_indexed(dir)) + return ocfs2_find_entry_dx(name, namelen, dir, lookup); + ++ if (unlikely(i_size_read(dir) <= 0)) { ++ ret = -EFSCORRUPTED; ++ mlog_errno(ret); ++ goto out; ++ } + /* + * The unindexed dir code only uses part of the lookup + * structure, so there's no reason to push it down further + * than this. + */ +- if (OCFS2_I(dir)->ip_dyn_features & OCFS2_INLINE_DATA_FL) ++ if (OCFS2_I(dir)->ip_dyn_features & OCFS2_INLINE_DATA_FL) { ++ if (unlikely(i_size_read(dir) > dir->i_sb->s_blocksize)) { ++ ret = -EFSCORRUPTED; ++ mlog_errno(ret); ++ goto out; ++ } + bh = ocfs2_find_entry_id(name, namelen, dir, &res_dir); +- else ++ } else { + bh = ocfs2_find_entry_el(name, namelen, dir, &res_dir); ++ } + + if (bh == NULL) + return -ENOENT; + + lookup->dl_leaf_bh = bh; + lookup->dl_entry = res_dir; +- return 0; ++out: ++ return ret; + } + + /* +@@ -2012,6 +2025,7 @@ int ocfs2_lookup_ino_from_name(struct inode *dir, const char *name, + * + * Return 0 if the name does not exist + * Return -EEXIST if the directory contains the name ++ * Return -EFSCORRUPTED if found corruption + * + * Callers should have i_rwsem + a cluster lock on dir + */ +@@ -2025,9 +2039,12 @@ int ocfs2_check_dir_for_entry(struct inode *dir, + trace_ocfs2_check_dir_for_entry( + (unsigned long long)OCFS2_I(dir)->ip_blkno, namelen, name); + +- if (ocfs2_find_entry(name, namelen, dir, &lookup) == 0) { ++ ret = ocfs2_find_entry(name, namelen, dir, &lookup); ++ if (ret == 0) { + ret = -EEXIST; + mlog_errno(ret); ++ } else if (ret == -ENOENT) { ++ ret = 0; + } + + ocfs2_free_dir_lookup_result(&lookup); +diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c +index 9f6bbb4a0844aa..84fa585c6513a5 100644 +--- a/fs/ocfs2/super.c ++++ b/fs/ocfs2/super.c +@@ -2343,7 +2343,7 @@ static int ocfs2_verify_volume(struct ocfs2_dinode *di, + mlog(ML_ERROR, "found superblock with incorrect block " + "size bits: found %u, should be 9, 10, 11, or 12\n", + blksz_bits); +- } else if ((1 << le32_to_cpu(blksz_bits)) != blksz) { ++ } else if ((1 << blksz_bits) != blksz) { + mlog(ML_ERROR, "found superblock with incorrect block " + "size: found %u, should be %u\n", 1 << blksz_bits, blksz); + } else if (le16_to_cpu(di->id2.i_super.s_major_rev_level) != +diff --git a/fs/ocfs2/symlink.c b/fs/ocfs2/symlink.c +index d4c5fdcfa1e464..f5cf2255dc0972 100644 +--- a/fs/ocfs2/symlink.c ++++ b/fs/ocfs2/symlink.c +@@ -65,7 +65,7 @@ static int ocfs2_fast_symlink_read_folio(struct file *f, struct folio *folio) + + if (status < 0) { + mlog_errno(status); +- return status; ++ goto out; + } + + fe = (struct ocfs2_dinode *) bh->b_data; +@@ -76,9 +76,10 @@ static int ocfs2_fast_symlink_read_folio(struct file *f, struct folio *folio) + memcpy(kaddr, link, len + 1); + kunmap_atomic(kaddr); + SetPageUptodate(page); ++out: + unlock_page(page); + brelse(bh); +- return 0; ++ return status; + } + + const struct address_space_operations ocfs2_fast_symlink_aops = { +diff --git a/fs/proc/array.c b/fs/proc/array.c +index 34a47fb0c57f25..5e4f7b411fbdb9 100644 +--- a/fs/proc/array.c ++++ b/fs/proc/array.c +@@ -500,7 +500,7 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns, + * a program is not able to use ptrace(2) in that case. It is + * safe because the task has stopped executing permanently. + */ +- if (permitted && (task->flags & (PF_EXITING|PF_DUMPCORE))) { ++ if (permitted && (task->flags & (PF_EXITING|PF_DUMPCORE|PF_POSTCOREDUMP))) { + if (try_get_task_stack(task)) { + eip = KSTK_EIP(task); + esp = KSTK_ESP(task); +diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h +index 43b42eca6780cf..6992e1ec02e416 100644 +--- a/fs/smb/client/cifsglob.h ++++ b/fs/smb/client/cifsglob.h +@@ -323,7 +323,7 @@ struct smb_version_operations { + int (*handle_cancelled_mid)(struct mid_q_entry *, struct TCP_Server_Info *); + void (*downgrade_oplock)(struct TCP_Server_Info *server, + struct cifsInodeInfo *cinode, __u32 oplock, +- unsigned int epoch, bool *purge_cache); ++ __u16 epoch, bool *purge_cache); + /* process transaction2 response */ + bool (*check_trans2)(struct mid_q_entry *, struct TCP_Server_Info *, + char *, int); +@@ -519,12 +519,12 @@ struct smb_version_operations { + /* if we can do cache read operations */ + bool (*is_read_op)(__u32); + /* set oplock level for the inode */ +- void (*set_oplock_level)(struct cifsInodeInfo *, __u32, unsigned int, +- bool *); ++ void (*set_oplock_level)(struct cifsInodeInfo *cinode, __u32 oplock, __u16 epoch, ++ bool *purge_cache); + /* create lease context buffer for CREATE request */ + char * (*create_lease_buf)(u8 *lease_key, u8 oplock); + /* parse lease context buffer and return oplock/epoch info */ +- __u8 (*parse_lease_buf)(void *buf, unsigned int *epoch, char *lkey); ++ __u8 (*parse_lease_buf)(void *buf, __u16 *epoch, char *lkey); + ssize_t (*copychunk_range)(const unsigned int, + struct cifsFileInfo *src_file, + struct cifsFileInfo *target_file, +@@ -1412,7 +1412,7 @@ struct cifs_fid { + __u8 create_guid[16]; + __u32 access; + struct cifs_pending_open *pending_open; +- unsigned int epoch; ++ __u16 epoch; + #ifdef CONFIG_CIFS_DEBUG2 + __u64 mid; + #endif /* CIFS_DEBUG2 */ +@@ -1445,7 +1445,7 @@ struct cifsFileInfo { + bool oplock_break_cancelled:1; + bool status_file_deleted:1; /* file has been deleted */ + bool offload:1; /* offload final part of _put to a wq */ +- unsigned int oplock_epoch; /* epoch from the lease break */ ++ __u16 oplock_epoch; /* epoch from the lease break */ + __u32 oplock_level; /* oplock/lease level from the lease break */ + int count; + spinlock_t file_info_lock; /* protects four flag/count fields above */ +@@ -1584,7 +1584,7 @@ struct cifsInodeInfo { + spinlock_t open_file_lock; /* protects openFileList */ + __u32 cifsAttrs; /* e.g. DOS archive bit, sparse, compressed, system */ + unsigned int oplock; /* oplock/lease level we have */ +- unsigned int epoch; /* used to track lease state changes */ ++ __u16 epoch; /* used to track lease state changes */ + #define CIFS_INODE_PENDING_OPLOCK_BREAK (0) /* oplock break in progress */ + #define CIFS_INODE_PENDING_WRITERS (1) /* Writes in progress */ + #define CIFS_INODE_FLAG_UNUSED (2) /* Unused flag */ +diff --git a/fs/smb/client/dir.c b/fs/smb/client/dir.c +index 864b194dbaa0a0..1822493dd0842e 100644 +--- a/fs/smb/client/dir.c ++++ b/fs/smb/client/dir.c +@@ -627,7 +627,7 @@ int cifs_mknod(struct mnt_idmap *idmap, struct inode *inode, + goto mknod_out; + } + +- trace_smb3_mknod_enter(xid, tcon->ses->Suid, tcon->tid, full_path); ++ trace_smb3_mknod_enter(xid, tcon->tid, tcon->ses->Suid, full_path); + + rc = tcon->ses->server->ops->make_node(xid, inode, direntry, tcon, + full_path, mode, +@@ -635,9 +635,9 @@ int cifs_mknod(struct mnt_idmap *idmap, struct inode *inode, + + mknod_out: + if (rc) +- trace_smb3_mknod_err(xid, tcon->ses->Suid, tcon->tid, rc); ++ trace_smb3_mknod_err(xid, tcon->tid, tcon->ses->Suid, rc); + else +- trace_smb3_mknod_done(xid, tcon->ses->Suid, tcon->tid); ++ trace_smb3_mknod_done(xid, tcon->tid, tcon->ses->Suid); + + free_dentry_path(page); + free_xid(xid); +diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c +index b0c0572f9d1fbc..bc1bac36c1b291 100644 +--- a/fs/smb/client/smb1ops.c ++++ b/fs/smb/client/smb1ops.c +@@ -377,7 +377,7 @@ coalesce_t2(char *second_buf, struct smb_hdr *target_hdr) + static void + cifs_downgrade_oplock(struct TCP_Server_Info *server, + struct cifsInodeInfo *cinode, __u32 oplock, +- unsigned int epoch, bool *purge_cache) ++ __u16 epoch, bool *purge_cache) + { + cifs_set_oplock_level(cinode, oplock); + } +diff --git a/fs/smb/client/smb2inode.c b/fs/smb/client/smb2inode.c +index 9ebd7a5ee23c21..e1078a1decdfa3 100644 +--- a/fs/smb/client/smb2inode.c ++++ b/fs/smb/client/smb2inode.c +@@ -298,8 +298,8 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, + goto finished; + } + num_rqst++; +- trace_smb3_query_info_compound_enter(xid, ses->Suid, +- tcon->tid, full_path); ++ trace_smb3_query_info_compound_enter(xid, tcon->tid, ++ ses->Suid, full_path); + break; + case SMB2_OP_POSIX_QUERY_INFO: + rqst[num_rqst].rq_iov = &vars->qi_iov; +@@ -334,18 +334,18 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, + goto finished; + } + num_rqst++; +- trace_smb3_posix_query_info_compound_enter(xid, ses->Suid, +- tcon->tid, full_path); ++ trace_smb3_posix_query_info_compound_enter(xid, tcon->tid, ++ ses->Suid, full_path); + break; + case SMB2_OP_DELETE: +- trace_smb3_delete_enter(xid, ses->Suid, tcon->tid, full_path); ++ trace_smb3_delete_enter(xid, tcon->tid, ses->Suid, full_path); + break; + case SMB2_OP_MKDIR: + /* + * Directories are created through parameters in the + * SMB2_open() call. + */ +- trace_smb3_mkdir_enter(xid, ses->Suid, tcon->tid, full_path); ++ trace_smb3_mkdir_enter(xid, tcon->tid, ses->Suid, full_path); + break; + case SMB2_OP_RMDIR: + rqst[num_rqst].rq_iov = &vars->si_iov[0]; +@@ -363,7 +363,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, + goto finished; + smb2_set_next_command(tcon, &rqst[num_rqst]); + smb2_set_related(&rqst[num_rqst++]); +- trace_smb3_rmdir_enter(xid, ses->Suid, tcon->tid, full_path); ++ trace_smb3_rmdir_enter(xid, tcon->tid, ses->Suid, full_path); + break; + case SMB2_OP_SET_EOF: + rqst[num_rqst].rq_iov = &vars->si_iov[0]; +@@ -398,7 +398,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, + goto finished; + } + num_rqst++; +- trace_smb3_set_eof_enter(xid, ses->Suid, tcon->tid, full_path); ++ trace_smb3_set_eof_enter(xid, tcon->tid, ses->Suid, full_path); + break; + case SMB2_OP_SET_INFO: + rqst[num_rqst].rq_iov = &vars->si_iov[0]; +@@ -429,8 +429,8 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, + goto finished; + } + num_rqst++; +- trace_smb3_set_info_compound_enter(xid, ses->Suid, +- tcon->tid, full_path); ++ trace_smb3_set_info_compound_enter(xid, tcon->tid, ++ ses->Suid, full_path); + break; + case SMB2_OP_RENAME: + rqst[num_rqst].rq_iov = &vars->si_iov[0]; +@@ -469,7 +469,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, + goto finished; + } + num_rqst++; +- trace_smb3_rename_enter(xid, ses->Suid, tcon->tid, full_path); ++ trace_smb3_rename_enter(xid, tcon->tid, ses->Suid, full_path); + break; + case SMB2_OP_HARDLINK: + rqst[num_rqst].rq_iov = &vars->si_iov[0]; +@@ -496,7 +496,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, + goto finished; + smb2_set_next_command(tcon, &rqst[num_rqst]); + smb2_set_related(&rqst[num_rqst++]); +- trace_smb3_hardlink_enter(xid, ses->Suid, tcon->tid, full_path); ++ trace_smb3_hardlink_enter(xid, tcon->tid, ses->Suid, full_path); + break; + case SMB2_OP_SET_REPARSE: + rqst[num_rqst].rq_iov = vars->io_iov; +@@ -523,8 +523,8 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, + goto finished; + } + num_rqst++; +- trace_smb3_set_reparse_compound_enter(xid, ses->Suid, +- tcon->tid, full_path); ++ trace_smb3_set_reparse_compound_enter(xid, tcon->tid, ++ ses->Suid, full_path); + break; + case SMB2_OP_GET_REPARSE: + rqst[num_rqst].rq_iov = vars->io_iov; +@@ -549,8 +549,8 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, + goto finished; + } + num_rqst++; +- trace_smb3_get_reparse_compound_enter(xid, ses->Suid, +- tcon->tid, full_path); ++ trace_smb3_get_reparse_compound_enter(xid, tcon->tid, ++ ses->Suid, full_path); + break; + case SMB2_OP_QUERY_WSL_EA: + rqst[num_rqst].rq_iov = &vars->ea_iov; +@@ -663,11 +663,11 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, + } + SMB2_query_info_free(&rqst[num_rqst++]); + if (rc) +- trace_smb3_query_info_compound_err(xid, ses->Suid, +- tcon->tid, rc); ++ trace_smb3_query_info_compound_err(xid, tcon->tid, ++ ses->Suid, rc); + else +- trace_smb3_query_info_compound_done(xid, ses->Suid, +- tcon->tid); ++ trace_smb3_query_info_compound_done(xid, tcon->tid, ++ ses->Suid); + break; + case SMB2_OP_POSIX_QUERY_INFO: + idata = in_iov[i].iov_base; +@@ -690,15 +690,15 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, + + SMB2_query_info_free(&rqst[num_rqst++]); + if (rc) +- trace_smb3_posix_query_info_compound_err(xid, ses->Suid, +- tcon->tid, rc); ++ trace_smb3_posix_query_info_compound_err(xid, tcon->tid, ++ ses->Suid, rc); + else +- trace_smb3_posix_query_info_compound_done(xid, ses->Suid, +- tcon->tid); ++ trace_smb3_posix_query_info_compound_done(xid, tcon->tid, ++ ses->Suid); + break; + case SMB2_OP_DELETE: + if (rc) +- trace_smb3_delete_err(xid, ses->Suid, tcon->tid, rc); ++ trace_smb3_delete_err(xid, tcon->tid, ses->Suid, rc); + else { + /* + * If dentry (hence, inode) is NULL, lease break is going to +@@ -706,59 +706,59 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, + */ + if (inode) + cifs_mark_open_handles_for_deleted_file(inode, full_path); +- trace_smb3_delete_done(xid, ses->Suid, tcon->tid); ++ trace_smb3_delete_done(xid, tcon->tid, ses->Suid); + } + break; + case SMB2_OP_MKDIR: + if (rc) +- trace_smb3_mkdir_err(xid, ses->Suid, tcon->tid, rc); ++ trace_smb3_mkdir_err(xid, tcon->tid, ses->Suid, rc); + else +- trace_smb3_mkdir_done(xid, ses->Suid, tcon->tid); ++ trace_smb3_mkdir_done(xid, tcon->tid, ses->Suid); + break; + case SMB2_OP_HARDLINK: + if (rc) +- trace_smb3_hardlink_err(xid, ses->Suid, tcon->tid, rc); ++ trace_smb3_hardlink_err(xid, tcon->tid, ses->Suid, rc); + else +- trace_smb3_hardlink_done(xid, ses->Suid, tcon->tid); ++ trace_smb3_hardlink_done(xid, tcon->tid, ses->Suid); + SMB2_set_info_free(&rqst[num_rqst++]); + break; + case SMB2_OP_RENAME: + if (rc) +- trace_smb3_rename_err(xid, ses->Suid, tcon->tid, rc); ++ trace_smb3_rename_err(xid, tcon->tid, ses->Suid, rc); + else +- trace_smb3_rename_done(xid, ses->Suid, tcon->tid); ++ trace_smb3_rename_done(xid, tcon->tid, ses->Suid); + SMB2_set_info_free(&rqst[num_rqst++]); + break; + case SMB2_OP_RMDIR: + if (rc) +- trace_smb3_rmdir_err(xid, ses->Suid, tcon->tid, rc); ++ trace_smb3_rmdir_err(xid, tcon->tid, ses->Suid, rc); + else +- trace_smb3_rmdir_done(xid, ses->Suid, tcon->tid); ++ trace_smb3_rmdir_done(xid, tcon->tid, ses->Suid); + SMB2_set_info_free(&rqst[num_rqst++]); + break; + case SMB2_OP_SET_EOF: + if (rc) +- trace_smb3_set_eof_err(xid, ses->Suid, tcon->tid, rc); ++ trace_smb3_set_eof_err(xid, tcon->tid, ses->Suid, rc); + else +- trace_smb3_set_eof_done(xid, ses->Suid, tcon->tid); ++ trace_smb3_set_eof_done(xid, tcon->tid, ses->Suid); + SMB2_set_info_free(&rqst[num_rqst++]); + break; + case SMB2_OP_SET_INFO: + if (rc) +- trace_smb3_set_info_compound_err(xid, ses->Suid, +- tcon->tid, rc); ++ trace_smb3_set_info_compound_err(xid, tcon->tid, ++ ses->Suid, rc); + else +- trace_smb3_set_info_compound_done(xid, ses->Suid, +- tcon->tid); ++ trace_smb3_set_info_compound_done(xid, tcon->tid, ++ ses->Suid); + SMB2_set_info_free(&rqst[num_rqst++]); + break; + case SMB2_OP_SET_REPARSE: + if (rc) { +- trace_smb3_set_reparse_compound_err(xid, ses->Suid, +- tcon->tid, rc); ++ trace_smb3_set_reparse_compound_err(xid, tcon->tid, ++ ses->Suid, rc); + } else { +- trace_smb3_set_reparse_compound_done(xid, ses->Suid, +- tcon->tid); ++ trace_smb3_set_reparse_compound_done(xid, tcon->tid, ++ ses->Suid); + } + SMB2_ioctl_free(&rqst[num_rqst++]); + break; +@@ -771,18 +771,18 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, + rbuf = reparse_buf_ptr(iov); + if (IS_ERR(rbuf)) { + rc = PTR_ERR(rbuf); +- trace_smb3_set_reparse_compound_err(xid, ses->Suid, +- tcon->tid, rc); ++ trace_smb3_get_reparse_compound_err(xid, tcon->tid, ++ ses->Suid, rc); + } else { + idata->reparse.tag = le32_to_cpu(rbuf->ReparseTag); +- trace_smb3_set_reparse_compound_done(xid, ses->Suid, +- tcon->tid); ++ trace_smb3_get_reparse_compound_done(xid, tcon->tid, ++ ses->Suid); + } + memset(iov, 0, sizeof(*iov)); + resp_buftype[i + 1] = CIFS_NO_BUFFER; + } else { +- trace_smb3_set_reparse_compound_err(xid, ses->Suid, +- tcon->tid, rc); ++ trace_smb3_get_reparse_compound_err(xid, tcon->tid, ++ ses->Suid, rc); + } + SMB2_ioctl_free(&rqst[num_rqst++]); + break; +@@ -799,11 +799,11 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, + } + } + if (!rc) { +- trace_smb3_query_wsl_ea_compound_done(xid, ses->Suid, +- tcon->tid); ++ trace_smb3_query_wsl_ea_compound_done(xid, tcon->tid, ++ ses->Suid); + } else { +- trace_smb3_query_wsl_ea_compound_err(xid, ses->Suid, +- tcon->tid, rc); ++ trace_smb3_query_wsl_ea_compound_err(xid, tcon->tid, ++ ses->Suid, rc); + } + SMB2_query_info_free(&rqst[num_rqst++]); + break; +diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c +index d4be915bcb70c7..8d3fa2a3b8a956 100644 +--- a/fs/smb/client/smb2ops.c ++++ b/fs/smb/client/smb2ops.c +@@ -3867,22 +3867,22 @@ static long smb3_fallocate(struct file *file, struct cifs_tcon *tcon, int mode, + static void + smb2_downgrade_oplock(struct TCP_Server_Info *server, + struct cifsInodeInfo *cinode, __u32 oplock, +- unsigned int epoch, bool *purge_cache) ++ __u16 epoch, bool *purge_cache) + { + server->ops->set_oplock_level(cinode, oplock, 0, NULL); + } + + static void + smb21_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, +- unsigned int epoch, bool *purge_cache); ++ __u16 epoch, bool *purge_cache); + + static void + smb3_downgrade_oplock(struct TCP_Server_Info *server, + struct cifsInodeInfo *cinode, __u32 oplock, +- unsigned int epoch, bool *purge_cache) ++ __u16 epoch, bool *purge_cache) + { + unsigned int old_state = cinode->oplock; +- unsigned int old_epoch = cinode->epoch; ++ __u16 old_epoch = cinode->epoch; + unsigned int new_state; + + if (epoch > old_epoch) { +@@ -3902,7 +3902,7 @@ smb3_downgrade_oplock(struct TCP_Server_Info *server, + + static void + smb2_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, +- unsigned int epoch, bool *purge_cache) ++ __u16 epoch, bool *purge_cache) + { + oplock &= 0xFF; + cinode->lease_granted = false; +@@ -3926,7 +3926,7 @@ smb2_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, + + static void + smb21_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, +- unsigned int epoch, bool *purge_cache) ++ __u16 epoch, bool *purge_cache) + { + char message[5] = {0}; + unsigned int new_oplock = 0; +@@ -3963,7 +3963,7 @@ smb21_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, + + static void + smb3_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, +- unsigned int epoch, bool *purge_cache) ++ __u16 epoch, bool *purge_cache) + { + unsigned int old_oplock = cinode->oplock; + +@@ -4077,7 +4077,7 @@ smb3_create_lease_buf(u8 *lease_key, u8 oplock) + } + + static __u8 +-smb2_parse_lease_buf(void *buf, unsigned int *epoch, char *lease_key) ++smb2_parse_lease_buf(void *buf, __u16 *epoch, char *lease_key) + { + struct create_lease *lc = (struct create_lease *)buf; + +@@ -4088,7 +4088,7 @@ smb2_parse_lease_buf(void *buf, unsigned int *epoch, char *lease_key) + } + + static __u8 +-smb3_parse_lease_buf(void *buf, unsigned int *epoch, char *lease_key) ++smb3_parse_lease_buf(void *buf, __u16 *epoch, char *lease_key) + { + struct create_lease_v2 *lc = (struct create_lease_v2 *)buf; + +diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c +index c012fbc2638ed5..24b1738a35a155 100644 +--- a/fs/smb/client/smb2pdu.c ++++ b/fs/smb/client/smb2pdu.c +@@ -2322,7 +2322,7 @@ parse_posix_ctxt(struct create_context *cc, struct smb2_file_all_info *info, + + int smb2_parse_contexts(struct TCP_Server_Info *server, + struct kvec *rsp_iov, +- unsigned int *epoch, ++ __u16 *epoch, + char *lease_key, __u8 *oplock, + struct smb2_file_all_info *buf, + struct create_posix_rsp *posix) +diff --git a/fs/smb/client/smb2proto.h b/fs/smb/client/smb2proto.h +index 750e4e397b1393..f553e3edd54ecf 100644 +--- a/fs/smb/client/smb2proto.h ++++ b/fs/smb/client/smb2proto.h +@@ -283,7 +283,7 @@ extern enum securityEnum smb2_select_sectype(struct TCP_Server_Info *, + enum securityEnum); + int smb2_parse_contexts(struct TCP_Server_Info *server, + struct kvec *rsp_iov, +- unsigned int *epoch, ++ __u16 *epoch, + char *lease_key, __u8 *oplock, + struct smb2_file_all_info *buf, + struct create_posix_rsp *posix); +diff --git a/fs/smb/server/transport_ipc.c b/fs/smb/server/transport_ipc.c +index c12b70d01880c0..449999576a141e 100644 +--- a/fs/smb/server/transport_ipc.c ++++ b/fs/smb/server/transport_ipc.c +@@ -570,6 +570,9 @@ ksmbd_ipc_spnego_authen_request(const char *spnego_blob, int blob_len) + struct ksmbd_spnego_authen_request *req; + struct ksmbd_spnego_authen_response *resp; + ++ if (blob_len > KSMBD_IPC_MAX_PAYLOAD) ++ return NULL; ++ + msg = ipc_msg_alloc(sizeof(struct ksmbd_spnego_authen_request) + + blob_len + 1); + if (!msg) +@@ -749,6 +752,9 @@ struct ksmbd_rpc_command *ksmbd_rpc_write(struct ksmbd_session *sess, int handle + struct ksmbd_rpc_command *req; + struct ksmbd_rpc_command *resp; + ++ if (payload_sz > KSMBD_IPC_MAX_PAYLOAD) ++ return NULL; ++ + msg = ipc_msg_alloc(sizeof(struct ksmbd_rpc_command) + payload_sz + 1); + if (!msg) + return NULL; +@@ -797,6 +803,9 @@ struct ksmbd_rpc_command *ksmbd_rpc_ioctl(struct ksmbd_session *sess, int handle + struct ksmbd_rpc_command *req; + struct ksmbd_rpc_command *resp; + ++ if (payload_sz > KSMBD_IPC_MAX_PAYLOAD) ++ return NULL; ++ + msg = ipc_msg_alloc(sizeof(struct ksmbd_rpc_command) + payload_sz + 1); + if (!msg) + return NULL; +diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c +index 6f7dca1c14c75a..b9784348ebc5c4 100644 +--- a/fs/xfs/xfs_inode.c ++++ b/fs/xfs/xfs_inode.c +@@ -1738,8 +1738,11 @@ xfs_inactive( + goto out; + + /* Try to clean out the cow blocks if there are any. */ +- if (xfs_inode_has_cow_data(ip)) +- xfs_reflink_cancel_cow_range(ip, 0, NULLFILEOFF, true); ++ if (xfs_inode_has_cow_data(ip)) { ++ error = xfs_reflink_cancel_cow_range(ip, 0, NULLFILEOFF, true); ++ if (error) ++ goto out; ++ } + + if (VFS_I(ip)->i_nlink != 0) { + /* +diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c +index 9ce2f48b4ebc01..40d02a1450d3cf 100644 +--- a/fs/xfs/xfs_iomap.c ++++ b/fs/xfs/xfs_iomap.c +@@ -923,10 +923,8 @@ xfs_dax_write_iomap_end( + if (!xfs_is_cow_inode(ip)) + return 0; + +- if (!written) { +- xfs_reflink_cancel_cow_range(ip, pos, length, true); +- return 0; +- } ++ if (!written) ++ return xfs_reflink_cancel_cow_range(ip, pos, length, true); + + return xfs_reflink_end_cow(ip, pos, written); + } +diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h +index d300fde6c1a47a..b2e9dc02fa3495 100644 +--- a/include/drm/drm_connector.h ++++ b/include/drm/drm_connector.h +@@ -1764,8 +1764,11 @@ struct drm_connector { + struct drm_encoder *encoder; + + #define MAX_ELD_BYTES 128 +- /** @eld: EDID-like data, if present */ ++ /** @eld: EDID-like data, if present, protected by @eld_mutex */ + uint8_t eld[MAX_ELD_BYTES]; ++ /** @eld_mutex: protection for concurrenct access to @eld */ ++ struct mutex eld_mutex; ++ + /** @latency_present: AV delay info from ELD, if found */ + bool latency_present[2]; + /** +diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h +index 8d51f69f9f5ef8..af9056d78fadff 100644 +--- a/include/linux/binfmts.h ++++ b/include/linux/binfmts.h +@@ -42,7 +42,9 @@ struct linux_binprm { + * Set when errors can no longer be returned to the + * original userspace. + */ +- point_of_no_return:1; ++ point_of_no_return:1, ++ /* Set when "comm" must come from the dentry. */ ++ comm_from_dentry:1; + struct file *executable; /* Executable to pass to the interpreter */ + struct file *interpreter; + struct file *file; +diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h +index fb6c6109fdcad6..26a8c4ae224459 100644 +--- a/include/linux/kvm_host.h ++++ b/include/linux/kvm_host.h +@@ -920,6 +920,15 @@ static inline struct kvm_io_bus *kvm_get_bus(struct kvm *kvm, enum kvm_bus idx) + static inline struct kvm_vcpu *kvm_get_vcpu(struct kvm *kvm, int i) + { + int num_vcpus = atomic_read(&kvm->online_vcpus); ++ ++ /* ++ * Explicitly verify the target vCPU is online, as the anti-speculation ++ * logic only limits the CPU's ability to speculate, e.g. given a "bad" ++ * index, clamping the index to 0 would return vCPU0, not NULL. ++ */ ++ if (i >= num_vcpus) ++ return NULL; ++ + i = array_index_nospec(i, num_vcpus); + + /* Pairs with smp_wmb() in kvm_vm_ioctl_create_vcpu. */ +diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h +index 38a8ff9c685cb8..69d844b34da0d3 100644 +--- a/include/linux/mlx5/driver.h ++++ b/include/linux/mlx5/driver.h +@@ -709,7 +709,6 @@ struct mlx5_timer { + struct timecounter tc; + u32 nominal_c_mult; + unsigned long overflow_period; +- struct delayed_work overflow_work; + }; + + struct mlx5_clock { +diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h +index 326d3a322c109e..4ec2a948ae3dbb 100644 +--- a/include/net/sch_generic.h ++++ b/include/net/sch_generic.h +@@ -849,7 +849,7 @@ static inline int qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch, + } + + static inline void _bstats_update(struct gnet_stats_basic_sync *bstats, +- __u64 bytes, __u32 packets) ++ __u64 bytes, __u64 packets) + { + u64_stats_update_begin(&bstats->syncp); + u64_stats_add(&bstats->bytes, bytes); +diff --git a/include/rv/da_monitor.h b/include/rv/da_monitor.h +index 9705b2a98e49e1..510c88bfabd433 100644 +--- a/include/rv/da_monitor.h ++++ b/include/rv/da_monitor.h +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + + #ifdef CONFIG_RV_REACTORS + +@@ -324,10 +325,13 @@ static inline struct da_monitor *da_get_monitor_##name(struct task_struct *tsk) + static void da_monitor_reset_all_##name(void) \ + { \ + struct task_struct *g, *p; \ ++ int cpu; \ + \ + read_lock(&tasklist_lock); \ + for_each_process_thread(g, p) \ + da_monitor_reset_##name(da_get_monitor_##name(p)); \ ++ for_each_present_cpu(cpu) \ ++ da_monitor_reset_##name(da_get_monitor_##name(idle_task(cpu))); \ + read_unlock(&tasklist_lock); \ + } \ + \ +diff --git a/include/trace/events/rxrpc.h b/include/trace/events/rxrpc.h +index 252bb90aca599b..e7c7b638943629 100644 +--- a/include/trace/events/rxrpc.h ++++ b/include/trace/events/rxrpc.h +@@ -214,6 +214,7 @@ + EM(rxrpc_conn_get_conn_input, "GET inp-conn") \ + EM(rxrpc_conn_get_idle, "GET idle ") \ + EM(rxrpc_conn_get_poke_abort, "GET pk-abort") \ ++ EM(rxrpc_conn_get_poke_secured, "GET secured ") \ + EM(rxrpc_conn_get_poke_timer, "GET poke ") \ + EM(rxrpc_conn_get_service_conn, "GET svc-conn") \ + EM(rxrpc_conn_new_client, "NEW client ") \ +diff --git a/include/uapi/linux/input-event-codes.h b/include/uapi/linux/input-event-codes.h +index a4206723f50333..5a199f3d4a26a2 100644 +--- a/include/uapi/linux/input-event-codes.h ++++ b/include/uapi/linux/input-event-codes.h +@@ -519,6 +519,7 @@ + #define KEY_NOTIFICATION_CENTER 0x1bc /* Show/hide the notification center */ + #define KEY_PICKUP_PHONE 0x1bd /* Answer incoming call */ + #define KEY_HANGUP_PHONE 0x1be /* Decline incoming call */ ++#define KEY_LINK_PHONE 0x1bf /* AL Phone Syncing */ + + #define KEY_DEL_EOL 0x1c0 + #define KEY_DEL_EOS 0x1c1 +diff --git a/include/ufs/ufs.h b/include/ufs/ufs.h +index 0cced88f4531e8..49c90795a2a677 100644 +--- a/include/ufs/ufs.h ++++ b/include/ufs/ufs.h +@@ -384,8 +384,8 @@ enum { + + /* Possible values for dExtendedUFSFeaturesSupport */ + enum { +- UFS_DEV_LOW_TEMP_NOTIF = BIT(4), +- UFS_DEV_HIGH_TEMP_NOTIF = BIT(5), ++ UFS_DEV_HIGH_TEMP_NOTIF = BIT(4), ++ UFS_DEV_LOW_TEMP_NOTIF = BIT(5), + UFS_DEV_EXT_TEMP_NOTIF = BIT(6), + UFS_DEV_HPB_SUPPORT = BIT(7), + UFS_DEV_WRITE_BOOSTER_SUP = BIT(8), +diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c +index c7198fbcf734f7..b61637dad442a7 100644 +--- a/io_uring/io_uring.c ++++ b/io_uring/io_uring.c +@@ -1779,6 +1779,7 @@ int io_req_prep_async(struct io_kiocb *req) + { + const struct io_cold_def *cdef = &io_cold_defs[req->opcode]; + const struct io_issue_def *def = &io_issue_defs[req->opcode]; ++ int ret; + + /* assign early for deferred execution for non-fixed file */ + if (def->needs_file && !(req->flags & REQ_F_FIXED_FILE) && !req->file) +@@ -1791,7 +1792,9 @@ int io_req_prep_async(struct io_kiocb *req) + if (io_alloc_async_data(req)) + return -EAGAIN; + } +- return cdef->prep_async(req); ++ ret = cdef->prep_async(req); ++ io_kbuf_recycle(req, 0); ++ return ret; + } + + static u32 io_get_sequence(struct io_kiocb *req) +diff --git a/io_uring/net.c b/io_uring/net.c +index 7412904387bfa0..56091292950fd6 100644 +--- a/io_uring/net.c ++++ b/io_uring/net.c +@@ -1533,6 +1533,11 @@ int io_connect(struct io_kiocb *req, unsigned int issue_flags) + io = &__io; + } + ++ if (unlikely(req->flags & REQ_F_FAIL)) { ++ ret = -ECONNRESET; ++ goto out; ++ } ++ + file_flags = force_nonblock ? O_NONBLOCK : 0; + + ret = __sys_connect_file(req->file, &io->address, +diff --git a/io_uring/poll.c b/io_uring/poll.c +index 5cf4fffe8b6c81..cf8e86bc96deb5 100644 +--- a/io_uring/poll.c ++++ b/io_uring/poll.c +@@ -308,6 +308,8 @@ static int io_poll_check_events(struct io_kiocb *req, struct io_tw_state *ts) + return IOU_POLL_REISSUE; + } + } ++ if (unlikely(req->cqe.res & EPOLLERR)) ++ req_set_fail(req); + if (req->apoll_events & EPOLLONESHOT) + return IOU_POLL_DONE; + +@@ -350,8 +352,10 @@ void io_poll_task_func(struct io_kiocb *req, struct io_tw_state *ts) + + ret = io_poll_check_events(req, ts); + if (ret == IOU_POLL_NO_ACTION) { ++ io_kbuf_recycle(req, 0); + return; + } else if (ret == IOU_POLL_REQUEUE) { ++ io_kbuf_recycle(req, 0); + __io_poll_execute(req, 0); + return; + } +diff --git a/io_uring/rw.c b/io_uring/rw.c +index a62f84e28bac35..75b001febb4d28 100644 +--- a/io_uring/rw.c ++++ b/io_uring/rw.c +@@ -793,6 +793,8 @@ static int __io_read(struct io_kiocb *req, unsigned int issue_flags) + goto done; + ret = 0; + } else if (ret == -EIOCBQUEUED) { ++ req->flags |= REQ_F_PARTIAL_IO; ++ io_kbuf_recycle(req, issue_flags); + if (iovec) + kfree(iovec); + return IOU_ISSUE_SKIP_COMPLETE; +@@ -816,6 +818,9 @@ static int __io_read(struct io_kiocb *req, unsigned int issue_flags) + goto done; + } + ++ req->flags |= REQ_F_PARTIAL_IO; ++ io_kbuf_recycle(req, issue_flags); ++ + io = req->async_data; + s = &io->s; + /* +@@ -956,6 +961,11 @@ int io_write(struct io_kiocb *req, unsigned int issue_flags) + else + ret2 = -EINVAL; + ++ if (ret2 == -EIOCBQUEUED) { ++ req->flags |= REQ_F_PARTIAL_IO; ++ io_kbuf_recycle(req, issue_flags); ++ } ++ + if (req->flags & REQ_F_REISSUE) { + req->flags &= ~REQ_F_REISSUE; + ret2 = -EAGAIN; +diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c +index 0fca282c0a2547..dcdf449615bdac 100644 +--- a/kernel/printk/printk.c ++++ b/kernel/printk/printk.c +@@ -474,7 +474,7 @@ static struct latched_seq clear_seq = { + /* record buffer */ + #define LOG_ALIGN __alignof__(unsigned long) + #define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT) +-#define LOG_BUF_LEN_MAX (u32)(1 << 31) ++#define LOG_BUF_LEN_MAX ((u32)1 << 31) + static char __log_buf[__LOG_BUF_LEN] __aligned(LOG_ALIGN); + static char *log_buf = __log_buf; + static u32 log_buf_len = __LOG_BUF_LEN; +diff --git a/kernel/sched/core.c b/kernel/sched/core.c +index 86606fb9e6bc6c..c686d826a91cf5 100644 +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -726,13 +726,15 @@ static void update_rq_clock_task(struct rq *rq, s64 delta) + #endif + #ifdef CONFIG_PARAVIRT_TIME_ACCOUNTING + if (static_key_false((¶virt_steal_rq_enabled))) { +- steal = paravirt_steal_clock(cpu_of(rq)); ++ u64 prev_steal; ++ ++ steal = prev_steal = paravirt_steal_clock(cpu_of(rq)); + steal -= rq->prev_steal_time_rq; + + if (unlikely(steal > delta)) + steal = delta; + +- rq->prev_steal_time_rq += steal; ++ rq->prev_steal_time_rq = prev_steal; + delta -= steal; + } + #endif +diff --git a/kernel/trace/trace_osnoise.c b/kernel/trace/trace_osnoise.c +index 3e2bc029fa8c83..cc155590018f65 100644 +--- a/kernel/trace/trace_osnoise.c ++++ b/kernel/trace/trace_osnoise.c +@@ -1235,6 +1235,8 @@ static void trace_sched_migrate_callback(void *data, struct task_struct *p, int + } + } + ++static bool monitor_enabled; ++ + static int register_migration_monitor(void) + { + int ret = 0; +@@ -1243,16 +1245,25 @@ static int register_migration_monitor(void) + * Timerlat thread migration check is only required when running timerlat in user-space. + * Thus, enable callback only if timerlat is set with no workload. + */ +- if (timerlat_enabled() && !test_bit(OSN_WORKLOAD, &osnoise_options)) ++ if (timerlat_enabled() && !test_bit(OSN_WORKLOAD, &osnoise_options)) { ++ if (WARN_ON_ONCE(monitor_enabled)) ++ return 0; ++ + ret = register_trace_sched_migrate_task(trace_sched_migrate_callback, NULL); ++ if (!ret) ++ monitor_enabled = true; ++ } + + return ret; + } + + static void unregister_migration_monitor(void) + { +- if (timerlat_enabled() && !test_bit(OSN_WORKLOAD, &osnoise_options)) +- unregister_trace_sched_migrate_task(trace_sched_migrate_callback, NULL); ++ if (!monitor_enabled) ++ return; ++ ++ unregister_trace_sched_migrate_task(trace_sched_migrate_callback, NULL); ++ monitor_enabled = false; + } + #else + static int register_migration_monitor(void) +diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug +index f94c3e957b8298..e809b6d8bc5373 100644 +--- a/lib/Kconfig.debug ++++ b/lib/Kconfig.debug +@@ -1454,7 +1454,7 @@ config LOCKDEP_SMALL + config LOCKDEP_BITS + int "Bitsize for MAX_LOCKDEP_ENTRIES" + depends on LOCKDEP && !LOCKDEP_SMALL +- range 10 30 ++ range 10 24 + default 15 + help + Try increasing this value if you hit "BUG: MAX_LOCKDEP_ENTRIES too low!" message. +@@ -1470,7 +1470,7 @@ config LOCKDEP_CHAINS_BITS + config LOCKDEP_STACK_TRACE_BITS + int "Bitsize for MAX_STACK_TRACE_ENTRIES" + depends on LOCKDEP && !LOCKDEP_SMALL +- range 10 30 ++ range 10 26 + default 19 + help + Try increasing this value if you hit "BUG: MAX_STACK_TRACE_ENTRIES too low!" message. +@@ -1478,7 +1478,7 @@ config LOCKDEP_STACK_TRACE_BITS + config LOCKDEP_STACK_TRACE_HASH_BITS + int "Bitsize for STACK_TRACE_HASH_SIZE" + depends on LOCKDEP && !LOCKDEP_SMALL +- range 10 30 ++ range 10 26 + default 14 + help + Try increasing this value if you need large STACK_TRACE_HASH_SIZE. +@@ -1486,7 +1486,7 @@ config LOCKDEP_STACK_TRACE_HASH_BITS + config LOCKDEP_CIRCULAR_QUEUE_BITS + int "Bitsize for elements in circular_queue struct" + depends on LOCKDEP +- range 10 30 ++ range 10 26 + default 12 + help + Try increasing this value if you hit "lockdep bfs error:-1" warning due to __cq_enqueue() failure. +diff --git a/lib/maple_tree.c b/lib/maple_tree.c +index 4eda9490636024..a4a2592413b1b6 100644 +--- a/lib/maple_tree.c ++++ b/lib/maple_tree.c +@@ -1870,11 +1870,11 @@ static inline int mab_no_null_split(struct maple_big_node *b_node, + * Return: The first split location. The middle split is set in @mid_split. + */ + static inline int mab_calc_split(struct ma_state *mas, +- struct maple_big_node *bn, unsigned char *mid_split, unsigned long min) ++ struct maple_big_node *bn, unsigned char *mid_split) + { + unsigned char b_end = bn->b_end; + int split = b_end / 2; /* Assume equal split. */ +- unsigned char slot_min, slot_count = mt_slots[bn->type]; ++ unsigned char slot_count = mt_slots[bn->type]; + + /* + * To support gap tracking, all NULL entries are kept together and a node cannot +@@ -1907,18 +1907,7 @@ static inline int mab_calc_split(struct ma_state *mas, + split = b_end / 3; + *mid_split = split * 2; + } else { +- slot_min = mt_min_slots[bn->type]; +- + *mid_split = 0; +- /* +- * Avoid having a range less than the slot count unless it +- * causes one node to be deficient. +- * NOTE: mt_min_slots is 1 based, b_end and split are zero. +- */ +- while ((split < slot_count - 1) && +- ((bn->pivot[split] - min) < slot_count - 1) && +- (b_end - split > slot_min)) +- split++; + } + + /* Avoid ending a node on a NULL entry */ +@@ -2402,7 +2391,7 @@ static inline struct maple_enode + static inline unsigned char mas_mab_to_node(struct ma_state *mas, + struct maple_big_node *b_node, struct maple_enode **left, + struct maple_enode **right, struct maple_enode **middle, +- unsigned char *mid_split, unsigned long min) ++ unsigned char *mid_split) + { + unsigned char split = 0; + unsigned char slot_count = mt_slots[b_node->type]; +@@ -2415,7 +2404,7 @@ static inline unsigned char mas_mab_to_node(struct ma_state *mas, + if (b_node->b_end < slot_count) { + split = b_node->b_end; + } else { +- split = mab_calc_split(mas, b_node, mid_split, min); ++ split = mab_calc_split(mas, b_node, mid_split); + *right = mas_new_ma_node(mas, b_node); + } + +@@ -2905,7 +2894,7 @@ static int mas_spanning_rebalance(struct ma_state *mas, + mast->bn->b_end--; + mast->bn->type = mte_node_type(mast->orig_l->node); + split = mas_mab_to_node(mas, mast->bn, &left, &right, &middle, +- &mid_split, mast->orig_l->min); ++ &mid_split); + mast_set_split_parents(mast, left, middle, right, split, + mid_split); + mast_cp_to_nodes(mast, left, middle, right, split, mid_split); +@@ -3413,7 +3402,7 @@ static int mas_split(struct ma_state *mas, struct maple_big_node *b_node) + if (mas_push_data(mas, height, &mast, false)) + break; + +- split = mab_calc_split(mas, b_node, &mid_split, prev_l_mas.min); ++ split = mab_calc_split(mas, b_node, &mid_split); + mast_split_data(&mast, mas, split); + /* + * Usually correct, mab_mas_cp in the above call overwrites +diff --git a/mm/kfence/core.c b/mm/kfence/core.c +index 3872528d096380..937bbae2611fee 100644 +--- a/mm/kfence/core.c ++++ b/mm/kfence/core.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -1065,6 +1066,7 @@ void *__kfence_alloc(struct kmem_cache *s, size_t size, gfp_t flags) + * properties (e.g. reside in DMAable memory). + */ + if ((flags & GFP_ZONEMASK) || ++ ((flags & __GFP_THISNODE) && num_online_nodes() > 1) || + (s->flags & (SLAB_CACHE_DMA | SLAB_CACHE_DMA32))) { + atomic_long_inc(&counters[KFENCE_COUNTER_SKIP_INCOMPAT]); + return NULL; +diff --git a/mm/kmemleak.c b/mm/kmemleak.c +index 5811a11cc53a6d..f86d4e04d95e12 100644 +--- a/mm/kmemleak.c ++++ b/mm/kmemleak.c +@@ -1549,7 +1549,7 @@ static void kmemleak_scan(void) + unsigned long phys = object->pointer; + + if (PHYS_PFN(phys) < min_low_pfn || +- PHYS_PFN(phys + object->size) >= max_low_pfn) ++ PHYS_PFN(phys + object->size) > max_low_pfn) + __paint_it(object, KMEMLEAK_BLACK); + } + +diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c +index 379ca86c41cd5b..3451c64fc42dce 100644 +--- a/net/bluetooth/l2cap_sock.c ++++ b/net/bluetooth/l2cap_sock.c +@@ -709,12 +709,12 @@ static bool l2cap_valid_mtu(struct l2cap_chan *chan, u16 mtu) + { + switch (chan->scid) { + case L2CAP_CID_ATT: +- if (mtu < L2CAP_LE_MIN_MTU) ++ if (mtu && mtu < L2CAP_LE_MIN_MTU) + return false; + break; + + default: +- if (mtu < L2CAP_DEFAULT_MIN_MTU) ++ if (mtu && mtu < L2CAP_DEFAULT_MIN_MTU) + return false; + } + +@@ -1885,7 +1885,8 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, + chan = l2cap_chan_create(); + if (!chan) { + sk_free(sk); +- sock->sk = NULL; ++ if (sock) ++ sock->sk = NULL; + return NULL; + } + +diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c +index e3440f0d7d9d97..b36254107ef578 100644 +--- a/net/bluetooth/mgmt.c ++++ b/net/bluetooth/mgmt.c +@@ -5453,10 +5453,16 @@ static void mgmt_remove_adv_monitor_complete(struct hci_dev *hdev, + { + struct mgmt_rp_remove_adv_monitor rp; + struct mgmt_pending_cmd *cmd = data; +- struct mgmt_cp_remove_adv_monitor *cp = cmd->param; ++ struct mgmt_cp_remove_adv_monitor *cp; ++ ++ if (status == -ECANCELED || ++ cmd != pending_find(MGMT_OP_REMOVE_ADV_MONITOR, hdev)) ++ return; + + hci_dev_lock(hdev); + ++ cp = cmd->param; ++ + rp.monitor_handle = cp->monitor_handle; + + if (!status) +@@ -5474,6 +5480,10 @@ static void mgmt_remove_adv_monitor_complete(struct hci_dev *hdev, + static int mgmt_remove_adv_monitor_sync(struct hci_dev *hdev, void *data) + { + struct mgmt_pending_cmd *cmd = data; ++ ++ if (cmd != pending_find(MGMT_OP_REMOVE_ADV_MONITOR, hdev)) ++ return -ECANCELED; ++ + struct mgmt_cp_remove_adv_monitor *cp = cmd->param; + u16 handle = __le16_to_cpu(cp->monitor_handle); + +diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c +index 2e4e5356039480..b84d18fcd9e2cd 100644 +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -930,9 +930,9 @@ static int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4, + const int hlen = skb_network_header_len(skb) + + sizeof(struct udphdr); + +- if (hlen + cork->gso_size > cork->fragsize) { ++ if (hlen + min(datalen, cork->gso_size) > cork->fragsize) { + kfree_skb(skb); +- return -EINVAL; ++ return -EMSGSIZE; + } + if (datalen > cork->gso_size * UDP_MAX_SEGMENTS) { + kfree_skb(skb); +diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c +index 954afe6ba883e7..9ff8e723402ba8 100644 +--- a/net/ipv6/udp.c ++++ b/net/ipv6/udp.c +@@ -1246,9 +1246,9 @@ static int udp_v6_send_skb(struct sk_buff *skb, struct flowi6 *fl6, + const int hlen = skb_network_header_len(skb) + + sizeof(struct udphdr); + +- if (hlen + cork->gso_size > cork->fragsize) { ++ if (hlen + min(datalen, cork->gso_size) > cork->fragsize) { + kfree_skb(skb); +- return -EINVAL; ++ return -EMSGSIZE; + } + if (datalen > cork->gso_size * UDP_MAX_SEGMENTS) { + kfree_skb(skb); +diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c +index 2cf4393e48dc06..2b63c5492eedc2 100644 +--- a/net/mptcp/pm_netlink.c ++++ b/net/mptcp/pm_netlink.c +@@ -2069,7 +2069,8 @@ int mptcp_pm_nl_set_flags(struct net *net, struct mptcp_pm_addr_entry *addr, u8 + return -EINVAL; + } + if ((addr->flags & MPTCP_PM_ADDR_FLAG_FULLMESH) && +- (entry->flags & MPTCP_PM_ADDR_FLAG_SIGNAL)) { ++ (entry->flags & (MPTCP_PM_ADDR_FLAG_SIGNAL | ++ MPTCP_PM_ADDR_FLAG_IMPLICIT))) { + spin_unlock_bh(&pernet->lock); + return -EINVAL; + } +diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c +index 5143214695dcd8..140c3ffcb86ba0 100644 +--- a/net/mptcp/protocol.c ++++ b/net/mptcp/protocol.c +@@ -138,6 +138,7 @@ static bool mptcp_try_coalesce(struct sock *sk, struct sk_buff *to, + int delta; + + if (MPTCP_SKB_CB(from)->offset || ++ ((to->len + from->len) > (sk->sk_rcvbuf >> 3)) || + !skb_try_coalesce(to, from, &fragstolen, &delta)) + return false; + +diff --git a/net/ncsi/internal.h b/net/ncsi/internal.h +index ef0f8f73826f53..4e0842df5234ea 100644 +--- a/net/ncsi/internal.h ++++ b/net/ncsi/internal.h +@@ -289,6 +289,7 @@ enum { + ncsi_dev_state_config_sp = 0x0301, + ncsi_dev_state_config_cis, + ncsi_dev_state_config_oem_gma, ++ ncsi_dev_state_config_apply_mac, + ncsi_dev_state_config_clear_vids, + ncsi_dev_state_config_svf, + ncsi_dev_state_config_ev, +@@ -322,6 +323,7 @@ struct ncsi_dev_priv { + #define NCSI_DEV_RESHUFFLE 4 + #define NCSI_DEV_RESET 8 /* Reset state of NC */ + unsigned int gma_flag; /* OEM GMA flag */ ++ struct sockaddr pending_mac; /* MAC address received from GMA */ + spinlock_t lock; /* Protect the NCSI device */ + unsigned int package_probe_id;/* Current ID during probe */ + unsigned int package_num; /* Number of packages */ +diff --git a/net/ncsi/ncsi-cmd.c b/net/ncsi/ncsi-cmd.c +index fd2236ee9a79d3..b3ff37a181d73e 100644 +--- a/net/ncsi/ncsi-cmd.c ++++ b/net/ncsi/ncsi-cmd.c +@@ -270,7 +270,8 @@ static struct ncsi_cmd_handler { + { NCSI_PKT_CMD_GPS, 0, ncsi_cmd_handler_default }, + { NCSI_PKT_CMD_OEM, -1, ncsi_cmd_handler_oem }, + { NCSI_PKT_CMD_PLDM, 0, NULL }, +- { NCSI_PKT_CMD_GPUUID, 0, ncsi_cmd_handler_default } ++ { NCSI_PKT_CMD_GPUUID, 0, ncsi_cmd_handler_default }, ++ { NCSI_PKT_CMD_GMCMA, 0, ncsi_cmd_handler_default } + }; + + static struct ncsi_request *ncsi_alloc_command(struct ncsi_cmd_arg *nca) +diff --git a/net/ncsi/ncsi-manage.c b/net/ncsi/ncsi-manage.c +index 90c6cf676221af..a5d3615d7996e6 100644 +--- a/net/ncsi/ncsi-manage.c ++++ b/net/ncsi/ncsi-manage.c +@@ -1038,17 +1038,34 @@ static void ncsi_configure_channel(struct ncsi_dev_priv *ndp) + : ncsi_dev_state_config_clear_vids; + break; + case ncsi_dev_state_config_oem_gma: +- nd->state = ncsi_dev_state_config_clear_vids; ++ nd->state = ncsi_dev_state_config_apply_mac; + +- nca.type = NCSI_PKT_CMD_OEM; + nca.package = np->id; + nca.channel = nc->id; + ndp->pending_req_num = 1; +- ret = ncsi_gma_handler(&nca, nc->version.mf_id); +- if (ret < 0) ++ if (nc->version.major >= 1 && nc->version.minor >= 2) { ++ nca.type = NCSI_PKT_CMD_GMCMA; ++ ret = ncsi_xmit_cmd(&nca); ++ } else { ++ nca.type = NCSI_PKT_CMD_OEM; ++ ret = ncsi_gma_handler(&nca, nc->version.mf_id); ++ } ++ if (ret < 0) { ++ nd->state = ncsi_dev_state_config_clear_vids; + schedule_work(&ndp->work); ++ } + + break; ++ case ncsi_dev_state_config_apply_mac: ++ rtnl_lock(); ++ ret = dev_set_mac_address(dev, &ndp->pending_mac, NULL); ++ rtnl_unlock(); ++ if (ret < 0) ++ netdev_warn(dev, "NCSI: 'Writing MAC address to device failed\n"); ++ ++ nd->state = ncsi_dev_state_config_clear_vids; ++ ++ fallthrough; + case ncsi_dev_state_config_clear_vids: + case ncsi_dev_state_config_svf: + case ncsi_dev_state_config_ev: +@@ -1368,6 +1385,12 @@ static void ncsi_probe_channel(struct ncsi_dev_priv *ndp) + nd->state = ncsi_dev_state_probe_package; + break; + case ncsi_dev_state_probe_package: ++ if (ndp->package_probe_id >= 8) { ++ /* Last package probed, finishing */ ++ ndp->flags |= NCSI_DEV_PROBED; ++ break; ++ } ++ + ndp->pending_req_num = 1; + + nca.type = NCSI_PKT_CMD_SP; +@@ -1484,13 +1507,8 @@ static void ncsi_probe_channel(struct ncsi_dev_priv *ndp) + if (ret) + goto error; + +- /* Probe next package */ ++ /* Probe next package after receiving response */ + ndp->package_probe_id++; +- if (ndp->package_probe_id >= 8) { +- /* Probe finished */ +- ndp->flags |= NCSI_DEV_PROBED; +- break; +- } + nd->state = ncsi_dev_state_probe_package; + ndp->active_package = NULL; + break; +diff --git a/net/ncsi/ncsi-pkt.h b/net/ncsi/ncsi-pkt.h +index c9d1da34dc4dc5..f2f3b5c1b94126 100644 +--- a/net/ncsi/ncsi-pkt.h ++++ b/net/ncsi/ncsi-pkt.h +@@ -338,6 +338,14 @@ struct ncsi_rsp_gpuuid_pkt { + __be32 checksum; + }; + ++/* Get MC MAC Address */ ++struct ncsi_rsp_gmcma_pkt { ++ struct ncsi_rsp_pkt_hdr rsp; ++ unsigned char address_count; ++ unsigned char reserved[3]; ++ unsigned char addresses[][ETH_ALEN]; ++}; ++ + /* AEN: Link State Change */ + struct ncsi_aen_lsc_pkt { + struct ncsi_aen_pkt_hdr aen; /* AEN header */ +@@ -398,6 +406,7 @@ struct ncsi_aen_hncdsc_pkt { + #define NCSI_PKT_CMD_GPUUID 0x52 /* Get package UUID */ + #define NCSI_PKT_CMD_QPNPR 0x56 /* Query Pending NC PLDM request */ + #define NCSI_PKT_CMD_SNPR 0x57 /* Send NC PLDM Reply */ ++#define NCSI_PKT_CMD_GMCMA 0x58 /* Get MC MAC Address */ + + + /* NCSI packet responses */ +@@ -433,6 +442,7 @@ struct ncsi_aen_hncdsc_pkt { + #define NCSI_PKT_RSP_GPUUID (NCSI_PKT_CMD_GPUUID + 0x80) + #define NCSI_PKT_RSP_QPNPR (NCSI_PKT_CMD_QPNPR + 0x80) + #define NCSI_PKT_RSP_SNPR (NCSI_PKT_CMD_SNPR + 0x80) ++#define NCSI_PKT_RSP_GMCMA (NCSI_PKT_CMD_GMCMA + 0x80) + + /* NCSI response code/reason */ + #define NCSI_PKT_RSP_C_COMPLETED 0x0000 /* Command Completed */ +diff --git a/net/ncsi/ncsi-rsp.c b/net/ncsi/ncsi-rsp.c +index f22d67cb04d371..4a8ce2949faeac 100644 +--- a/net/ncsi/ncsi-rsp.c ++++ b/net/ncsi/ncsi-rsp.c +@@ -628,16 +628,14 @@ static int ncsi_rsp_handler_snfc(struct ncsi_request *nr) + static int ncsi_rsp_handler_oem_gma(struct ncsi_request *nr, int mfr_id) + { + struct ncsi_dev_priv *ndp = nr->ndp; ++ struct sockaddr *saddr = &ndp->pending_mac; + struct net_device *ndev = ndp->ndev.dev; + struct ncsi_rsp_oem_pkt *rsp; +- struct sockaddr saddr; + u32 mac_addr_off = 0; +- int ret = 0; + + /* Get the response header */ + rsp = (struct ncsi_rsp_oem_pkt *)skb_network_header(nr->rsp); + +- saddr.sa_family = ndev->type; + ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE; + if (mfr_id == NCSI_OEM_MFR_BCM_ID) + mac_addr_off = BCM_MAC_ADDR_OFFSET; +@@ -646,22 +644,17 @@ static int ncsi_rsp_handler_oem_gma(struct ncsi_request *nr, int mfr_id) + else if (mfr_id == NCSI_OEM_MFR_INTEL_ID) + mac_addr_off = INTEL_MAC_ADDR_OFFSET; + +- memcpy(saddr.sa_data, &rsp->data[mac_addr_off], ETH_ALEN); ++ saddr->sa_family = ndev->type; ++ memcpy(saddr->sa_data, &rsp->data[mac_addr_off], ETH_ALEN); + if (mfr_id == NCSI_OEM_MFR_BCM_ID || mfr_id == NCSI_OEM_MFR_INTEL_ID) +- eth_addr_inc((u8 *)saddr.sa_data); +- if (!is_valid_ether_addr((const u8 *)saddr.sa_data)) ++ eth_addr_inc((u8 *)saddr->sa_data); ++ if (!is_valid_ether_addr((const u8 *)saddr->sa_data)) + return -ENXIO; + + /* Set the flag for GMA command which should only be called once */ + ndp->gma_flag = 1; + +- rtnl_lock(); +- ret = dev_set_mac_address(ndev, &saddr, NULL); +- rtnl_unlock(); +- if (ret < 0) +- netdev_warn(ndev, "NCSI: 'Writing mac address to device failed\n"); +- +- return ret; ++ return 0; + } + + /* Response handler for Mellanox card */ +@@ -1093,6 +1086,42 @@ static int ncsi_rsp_handler_netlink(struct ncsi_request *nr) + return ret; + } + ++static int ncsi_rsp_handler_gmcma(struct ncsi_request *nr) ++{ ++ struct ncsi_dev_priv *ndp = nr->ndp; ++ struct sockaddr *saddr = &ndp->pending_mac; ++ struct net_device *ndev = ndp->ndev.dev; ++ struct ncsi_rsp_gmcma_pkt *rsp; ++ int i; ++ ++ rsp = (struct ncsi_rsp_gmcma_pkt *)skb_network_header(nr->rsp); ++ ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE; ++ ++ netdev_info(ndev, "NCSI: Received %d provisioned MAC addresses\n", ++ rsp->address_count); ++ for (i = 0; i < rsp->address_count; i++) { ++ netdev_info(ndev, "NCSI: MAC address %d: %02x:%02x:%02x:%02x:%02x:%02x\n", ++ i, rsp->addresses[i][0], rsp->addresses[i][1], ++ rsp->addresses[i][2], rsp->addresses[i][3], ++ rsp->addresses[i][4], rsp->addresses[i][5]); ++ } ++ ++ saddr->sa_family = ndev->type; ++ for (i = 0; i < rsp->address_count; i++) { ++ if (!is_valid_ether_addr(rsp->addresses[i])) { ++ netdev_warn(ndev, "NCSI: Unable to assign %pM to device\n", ++ rsp->addresses[i]); ++ continue; ++ } ++ memcpy(saddr->sa_data, rsp->addresses[i], ETH_ALEN); ++ netdev_warn(ndev, "NCSI: Will set MAC address to %pM\n", saddr->sa_data); ++ break; ++ } ++ ++ ndp->gma_flag = 1; ++ return 0; ++} ++ + static struct ncsi_rsp_handler { + unsigned char type; + int payload; +@@ -1129,7 +1158,8 @@ static struct ncsi_rsp_handler { + { NCSI_PKT_RSP_PLDM, -1, ncsi_rsp_handler_pldm }, + { NCSI_PKT_RSP_GPUUID, 20, ncsi_rsp_handler_gpuuid }, + { NCSI_PKT_RSP_QPNPR, -1, ncsi_rsp_handler_pldm }, +- { NCSI_PKT_RSP_SNPR, -1, ncsi_rsp_handler_pldm } ++ { NCSI_PKT_RSP_SNPR, -1, ncsi_rsp_handler_pldm }, ++ { NCSI_PKT_RSP_GMCMA, -1, ncsi_rsp_handler_gmcma }, + }; + + int ncsi_rcv_rsp(struct sk_buff *skb, struct net_device *dev, +diff --git a/net/nfc/nci/hci.c b/net/nfc/nci/hci.c +index de175318a3a0f3..082ab66f120b73 100644 +--- a/net/nfc/nci/hci.c ++++ b/net/nfc/nci/hci.c +@@ -542,6 +542,8 @@ static u8 nci_hci_create_pipe(struct nci_dev *ndev, u8 dest_host, + + pr_debug("pipe created=%d\n", pipe); + ++ if (pipe >= NCI_HCI_MAX_PIPES) ++ pipe = NCI_HCI_INVALID_PIPE; + return pipe; + } + +diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c +index 342823b918e7cc..66e9ceaaa43a14 100644 +--- a/net/rose/af_rose.c ++++ b/net/rose/af_rose.c +@@ -701,11 +701,9 @@ static int rose_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) + struct net_device *dev; + ax25_address *source; + ax25_uid_assoc *user; ++ int err = -EINVAL; + int n; + +- if (!sock_flag(sk, SOCK_ZAPPED)) +- return -EINVAL; +- + if (addr_len != sizeof(struct sockaddr_rose) && addr_len != sizeof(struct full_sockaddr_rose)) + return -EINVAL; + +@@ -718,8 +716,15 @@ static int rose_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) + if ((unsigned int) addr->srose_ndigis > ROSE_MAX_DIGIS) + return -EINVAL; + +- if ((dev = rose_dev_get(&addr->srose_addr)) == NULL) +- return -EADDRNOTAVAIL; ++ lock_sock(sk); ++ ++ if (!sock_flag(sk, SOCK_ZAPPED)) ++ goto out_release; ++ ++ err = -EADDRNOTAVAIL; ++ dev = rose_dev_get(&addr->srose_addr); ++ if (!dev) ++ goto out_release; + + source = &addr->srose_call; + +@@ -730,7 +735,8 @@ static int rose_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) + } else { + if (ax25_uid_policy && !capable(CAP_NET_BIND_SERVICE)) { + dev_put(dev); +- return -EACCES; ++ err = -EACCES; ++ goto out_release; + } + rose->source_call = *source; + } +@@ -753,8 +759,10 @@ static int rose_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) + rose_insert_socket(sk); + + sock_reset_flag(sk, SOCK_ZAPPED); +- +- return 0; ++ err = 0; ++out_release: ++ release_sock(sk); ++ return err; + } + + static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags) +diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h +index 66ad7dc10864e0..86438c86eb2fd3 100644 +--- a/net/rxrpc/ar-internal.h ++++ b/net/rxrpc/ar-internal.h +@@ -558,6 +558,7 @@ enum rxrpc_call_flag { + RXRPC_CALL_EXCLUSIVE, /* The call uses a once-only connection */ + RXRPC_CALL_RX_IS_IDLE, /* recvmsg() is idle - send an ACK */ + RXRPC_CALL_RECVMSG_READ_ALL, /* recvmsg() read all of the received data */ ++ RXRPC_CALL_CONN_CHALLENGING, /* The connection is being challenged */ + }; + + /* +@@ -578,7 +579,6 @@ enum rxrpc_call_state { + RXRPC_CALL_CLIENT_AWAIT_REPLY, /* - client awaiting reply */ + RXRPC_CALL_CLIENT_RECV_REPLY, /* - client receiving reply phase */ + RXRPC_CALL_SERVER_PREALLOC, /* - service preallocation */ +- RXRPC_CALL_SERVER_SECURING, /* - server securing request connection */ + RXRPC_CALL_SERVER_RECV_REQUEST, /* - server receiving request */ + RXRPC_CALL_SERVER_ACK_REQUEST, /* - server pending ACK of request */ + RXRPC_CALL_SERVER_SEND_REPLY, /* - server sending reply */ +diff --git a/net/rxrpc/call_object.c b/net/rxrpc/call_object.c +index 29385908099efc..4f8e8f884d102c 100644 +--- a/net/rxrpc/call_object.c ++++ b/net/rxrpc/call_object.c +@@ -22,7 +22,6 @@ const char *const rxrpc_call_states[NR__RXRPC_CALL_STATES] = { + [RXRPC_CALL_CLIENT_AWAIT_REPLY] = "ClAwtRpl", + [RXRPC_CALL_CLIENT_RECV_REPLY] = "ClRcvRpl", + [RXRPC_CALL_SERVER_PREALLOC] = "SvPrealc", +- [RXRPC_CALL_SERVER_SECURING] = "SvSecure", + [RXRPC_CALL_SERVER_RECV_REQUEST] = "SvRcvReq", + [RXRPC_CALL_SERVER_ACK_REQUEST] = "SvAckReq", + [RXRPC_CALL_SERVER_SEND_REPLY] = "SvSndRpl", +@@ -458,17 +457,16 @@ void rxrpc_incoming_call(struct rxrpc_sock *rx, + call->cong_tstamp = skb->tstamp; + + __set_bit(RXRPC_CALL_EXPOSED, &call->flags); +- rxrpc_set_call_state(call, RXRPC_CALL_SERVER_SECURING); ++ rxrpc_set_call_state(call, RXRPC_CALL_SERVER_RECV_REQUEST); + + spin_lock(&conn->state_lock); + + switch (conn->state) { + case RXRPC_CONN_SERVICE_UNSECURED: + case RXRPC_CONN_SERVICE_CHALLENGING: +- rxrpc_set_call_state(call, RXRPC_CALL_SERVER_SECURING); ++ __set_bit(RXRPC_CALL_CONN_CHALLENGING, &call->flags); + break; + case RXRPC_CONN_SERVICE: +- rxrpc_set_call_state(call, RXRPC_CALL_SERVER_RECV_REQUEST); + break; + + case RXRPC_CONN_ABORTED: +diff --git a/net/rxrpc/conn_event.c b/net/rxrpc/conn_event.c +index 2a1396cd892f30..c4eb7986efddf8 100644 +--- a/net/rxrpc/conn_event.c ++++ b/net/rxrpc/conn_event.c +@@ -222,10 +222,8 @@ static void rxrpc_abort_calls(struct rxrpc_connection *conn) + */ + static void rxrpc_call_is_secure(struct rxrpc_call *call) + { +- if (call && __rxrpc_call_state(call) == RXRPC_CALL_SERVER_SECURING) { +- rxrpc_set_call_state(call, RXRPC_CALL_SERVER_RECV_REQUEST); ++ if (call && __test_and_clear_bit(RXRPC_CALL_CONN_CHALLENGING, &call->flags)) + rxrpc_notify_socket(call); +- } + } + + /* +@@ -266,6 +264,7 @@ static int rxrpc_process_event(struct rxrpc_connection *conn, + * we've already received the packet, put it on the + * front of the queue. + */ ++ sp->conn = rxrpc_get_connection(conn, rxrpc_conn_get_poke_secured); + skb->mark = RXRPC_SKB_MARK_SERVICE_CONN_SECURED; + rxrpc_get_skb(skb, rxrpc_skb_get_conn_secured); + skb_queue_head(&conn->local->rx_queue, skb); +@@ -431,14 +430,16 @@ void rxrpc_input_conn_event(struct rxrpc_connection *conn, struct sk_buff *skb) + if (test_and_clear_bit(RXRPC_CONN_EV_ABORT_CALLS, &conn->events)) + rxrpc_abort_calls(conn); + +- switch (skb->mark) { +- case RXRPC_SKB_MARK_SERVICE_CONN_SECURED: +- if (conn->state != RXRPC_CONN_SERVICE) +- break; ++ if (skb) { ++ switch (skb->mark) { ++ case RXRPC_SKB_MARK_SERVICE_CONN_SECURED: ++ if (conn->state != RXRPC_CONN_SERVICE) ++ break; + +- for (loop = 0; loop < RXRPC_MAXCALLS; loop++) +- rxrpc_call_is_secure(conn->channels[loop].call); +- break; ++ for (loop = 0; loop < RXRPC_MAXCALLS; loop++) ++ rxrpc_call_is_secure(conn->channels[loop].call); ++ break; ++ } + } + + /* Process delayed ACKs whose time has come. */ +diff --git a/net/rxrpc/conn_object.c b/net/rxrpc/conn_object.c +index 7aa58129ae4550..f0c77f437b6167 100644 +--- a/net/rxrpc/conn_object.c ++++ b/net/rxrpc/conn_object.c +@@ -67,6 +67,7 @@ struct rxrpc_connection *rxrpc_alloc_connection(struct rxrpc_net *rxnet, + INIT_WORK(&conn->destructor, rxrpc_clean_up_connection); + INIT_LIST_HEAD(&conn->proc_link); + INIT_LIST_HEAD(&conn->link); ++ INIT_LIST_HEAD(&conn->attend_link); + mutex_init(&conn->security_lock); + skb_queue_head_init(&conn->rx_queue); + conn->rxnet = rxnet; +diff --git a/net/rxrpc/input.c b/net/rxrpc/input.c +index 5dfda1ac51dda7..9a162035d4c1d0 100644 +--- a/net/rxrpc/input.c ++++ b/net/rxrpc/input.c +@@ -574,7 +574,7 @@ static bool rxrpc_input_split_jumbo(struct rxrpc_call *call, struct sk_buff *skb + rxrpc_propose_delay_ACK(call, sp->hdr.serial, + rxrpc_propose_ack_input_data); + } +- if (notify) { ++ if (notify && !test_bit(RXRPC_CALL_CONN_CHALLENGING, &call->flags)) { + trace_rxrpc_notify_socket(call->debug_id, sp->hdr.serial); + rxrpc_notify_socket(call); + } +diff --git a/net/rxrpc/sendmsg.c b/net/rxrpc/sendmsg.c +index 24f765d243db1c..b9f2f12281b33e 100644 +--- a/net/rxrpc/sendmsg.c ++++ b/net/rxrpc/sendmsg.c +@@ -658,7 +658,7 @@ int rxrpc_do_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, size_t len) + } else { + switch (rxrpc_call_state(call)) { + case RXRPC_CALL_CLIENT_AWAIT_CONN: +- case RXRPC_CALL_SERVER_SECURING: ++ case RXRPC_CALL_SERVER_RECV_REQUEST: + if (p.command == RXRPC_CMD_SEND_ABORT) + break; + fallthrough; +diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c +index 152dbbe8fd31ab..447d3e836a24f0 100644 +--- a/net/sched/sch_netem.c ++++ b/net/sched/sch_netem.c +@@ -748,9 +748,9 @@ static struct sk_buff *netem_dequeue(struct Qdisc *sch) + if (err != NET_XMIT_SUCCESS) { + if (net_xmit_drop_count(err)) + qdisc_qstats_drop(sch); +- qdisc_tree_reduce_backlog(sch, 1, pkt_len); + sch->qstats.backlog -= pkt_len; + sch->q.qlen--; ++ qdisc_tree_reduce_backlog(sch, 1, pkt_len); + } + goto tfifo_dequeue; + } +diff --git a/net/tipc/crypto.c b/net/tipc/crypto.c +index 43c3f1c971b8fd..c524421ec65252 100644 +--- a/net/tipc/crypto.c ++++ b/net/tipc/crypto.c +@@ -2293,8 +2293,8 @@ static bool tipc_crypto_key_rcv(struct tipc_crypto *rx, struct tipc_msg *hdr) + keylen = ntohl(*((__be32 *)(data + TIPC_AEAD_ALG_NAME))); + + /* Verify the supplied size values */ +- if (unlikely(size != keylen + sizeof(struct tipc_aead_key) || +- keylen > TIPC_AEAD_KEY_SIZE_MAX)) { ++ if (unlikely(keylen > TIPC_AEAD_KEY_SIZE_MAX || ++ size != keylen + sizeof(struct tipc_aead_key))) { + pr_debug("%s: invalid MSG_CRYPTO key size\n", rx->name); + goto exit; + } +diff --git a/rust/kernel/init.rs b/rust/kernel/init.rs +index 0fe043c0eaacdc..2d4b19b8685771 100644 +--- a/rust/kernel/init.rs ++++ b/rust/kernel/init.rs +@@ -788,7 +788,7 @@ pub unsafe trait PinInit: Sized { + /// use kernel::{types::Opaque, init::pin_init_from_closure}; + /// #[repr(C)] + /// struct RawFoo([u8; 16]); +- /// extern { ++ /// extern "C" { + /// fn init_foo(_: *mut RawFoo); + /// } + /// +diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn +index 16c750bb95fafd..0ea3281a92e1eb 100644 +--- a/scripts/Makefile.extrawarn ++++ b/scripts/Makefile.extrawarn +@@ -144,7 +144,6 @@ KBUILD_CFLAGS += -Wno-tautological-constant-out-of-range-compare + KBUILD_CFLAGS += $(call cc-disable-warning, unaligned-access) + KBUILD_CFLAGS += $(call cc-disable-warning, cast-function-type-strict) + KBUILD_CFLAGS += -Wno-enum-compare-conditional +-KBUILD_CFLAGS += -Wno-enum-enum-conversion + endif + + endif +@@ -175,6 +174,10 @@ KBUILD_CFLAGS += -Wno-missing-field-initializers + KBUILD_CFLAGS += -Wno-type-limits + KBUILD_CFLAGS += -Wno-shift-negative-value + ++ifdef CONFIG_CC_IS_CLANG ++KBUILD_CFLAGS += -Wno-enum-enum-conversion ++endif ++ + ifdef CONFIG_CC_IS_CLANG + KBUILD_CFLAGS += -Wno-initializer-overrides + else +diff --git a/scripts/gdb/linux/cpus.py b/scripts/gdb/linux/cpus.py +index 255dc18cb9da45..5563c3a79fc17a 100644 +--- a/scripts/gdb/linux/cpus.py ++++ b/scripts/gdb/linux/cpus.py +@@ -172,7 +172,7 @@ def get_current_task(cpu): + var_ptr = gdb.parse_and_eval("&pcpu_hot.current_task") + return per_cpu(var_ptr, cpu).dereference() + elif utils.is_target_arch("aarch64"): +- current_task_addr = gdb.parse_and_eval("$SP_EL0") ++ current_task_addr = gdb.parse_and_eval("(unsigned long)$SP_EL0") + if (current_task_addr >> 63) != 0: + current_task = current_task_addr.cast(task_ptr_type) + return current_task.dereference() +diff --git a/security/safesetid/securityfs.c b/security/safesetid/securityfs.c +index 25310468bcddff..8e1ffd70b18ab4 100644 +--- a/security/safesetid/securityfs.c ++++ b/security/safesetid/securityfs.c +@@ -143,6 +143,9 @@ static ssize_t handle_policy_update(struct file *file, + char *buf, *p, *end; + int err; + ++ if (len >= KMALLOC_MAX_SIZE) ++ return -EINVAL; ++ + pol = kmalloc(sizeof(struct setid_ruleset), GFP_KERNEL); + if (!pol) + return -ENOMEM; +diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c +index ea3140d510ecbf..e58e265d16578e 100644 +--- a/security/tomoyo/common.c ++++ b/security/tomoyo/common.c +@@ -2665,7 +2665,7 @@ ssize_t tomoyo_write_control(struct tomoyo_io_buffer *head, + + if (head->w.avail >= head->writebuf_size - 1) { + const int len = head->writebuf_size * 2; +- char *cp = kzalloc(len, GFP_NOFS); ++ char *cp = kzalloc(len, GFP_NOFS | __GFP_NOWARN); + + if (!cp) { + error = -ENOMEM; +diff --git a/sound/pci/hda/hda_auto_parser.c b/sound/pci/hda/hda_auto_parser.c +index 8e74be038b0fad..0091ab3f2bd56b 100644 +--- a/sound/pci/hda/hda_auto_parser.c ++++ b/sound/pci/hda/hda_auto_parser.c +@@ -80,7 +80,11 @@ static int compare_input_type(const void *ap, const void *bp) + + /* In case one has boost and the other one has not, + pick the one with boost first. */ +- return (int)(b->has_boost_on_pin - a->has_boost_on_pin); ++ if (a->has_boost_on_pin != b->has_boost_on_pin) ++ return (int)(b->has_boost_on_pin - a->has_boost_on_pin); ++ ++ /* Keep the original order */ ++ return a->order - b->order; + } + + /* Reorder the surround channels +@@ -400,6 +404,8 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec, + reorder_outputs(cfg->speaker_outs, cfg->speaker_pins); + + /* sort inputs in the order of AUTO_PIN_* type */ ++ for (i = 0; i < cfg->num_inputs; i++) ++ cfg->inputs[i].order = i; + sort(cfg->inputs, cfg->num_inputs, sizeof(cfg->inputs[0]), + compare_input_type, NULL); + +diff --git a/sound/pci/hda/hda_auto_parser.h b/sound/pci/hda/hda_auto_parser.h +index 579b11beac718e..87af3d8c02f7f6 100644 +--- a/sound/pci/hda/hda_auto_parser.h ++++ b/sound/pci/hda/hda_auto_parser.h +@@ -37,6 +37,7 @@ struct auto_pin_cfg_item { + unsigned int is_headset_mic:1; + unsigned int is_headphone_mic:1; /* Mic-only in headphone jack */ + unsigned int has_boost_on_pin:1; ++ int order; + }; + + struct auto_pin_cfg; +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 0b679fd1b82ab9..abe3d5b9b84b3e 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -9949,6 +9949,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x103c, 0x8870, "HP ZBook Fury 15.6 Inch G8 Mobile Workstation PC", ALC285_FIXUP_HP_GPIO_AMP_INIT), + SND_PCI_QUIRK(0x103c, 0x8873, "HP ZBook Studio 15.6 Inch G8 Mobile Workstation PC", ALC285_FIXUP_HP_GPIO_AMP_INIT), + SND_PCI_QUIRK(0x103c, 0x887a, "HP Laptop 15s-eq2xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), ++ SND_PCI_QUIRK(0x103c, 0x887c, "HP Laptop 14s-fq1xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), + SND_PCI_QUIRK(0x103c, 0x888a, "HP ENVY x360 Convertible 15-eu0xxx", ALC245_FIXUP_HP_X360_MUTE_LEDS), + SND_PCI_QUIRK(0x103c, 0x888d, "HP ZBook Power 15.6 inch G8 Mobile Workstation PC", ALC236_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8895, "HP EliteBook 855 G8 Notebook PC", ALC285_FIXUP_HP_SPEAKERS_MICMUTE_LED), +@@ -10401,6 +10402,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x17aa, 0x511f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK), + SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), + SND_PCI_QUIRK(0x17aa, 0x9e56, "Lenovo ZhaoYang CF4620Z", ALC286_FIXUP_SONY_MIC_NO_PRESENCE), ++ SND_PCI_QUIRK(0x1849, 0x0269, "Positivo Master C6400", ALC269VB_FIXUP_ASUS_ZENBOOK), + SND_PCI_QUIRK(0x1849, 0x1233, "ASRock NUC Box 1100", ALC233_FIXUP_NO_AUDIO_JACK), + SND_PCI_QUIRK(0x1849, 0xa233, "Positivo Master C6300", ALC269_FIXUP_HEADSET_MIC), + SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MACH-WX9", ALC256_FIXUP_HUAWEI_MACH_WX9_PINS), +diff --git a/sound/soc/amd/Kconfig b/sound/soc/amd/Kconfig +index 273688c053172f..0b6a01c6bbb1b1 100644 +--- a/sound/soc/amd/Kconfig ++++ b/sound/soc/amd/Kconfig +@@ -105,7 +105,7 @@ config SND_SOC_AMD_ACP6x + config SND_SOC_AMD_YC_MACH + tristate "AMD YC support for DMIC" + select SND_SOC_DMIC +- depends on SND_SOC_AMD_ACP6x ++ depends on SND_SOC_AMD_ACP6x && ACPI + help + This option enables machine driver for Yellow Carp platform + using dmic. ACP IP has PDM Decoder block with DMA controller. +diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c +index f7fbde1bc2ed2e..eac023283ff790 100644 +--- a/sound/soc/amd/yc/acp6x-mach.c ++++ b/sound/soc/amd/yc/acp6x-mach.c +@@ -304,6 +304,34 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "83AS"), + } + }, ++ { ++ .driver_data = &acp6x_card, ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "83L3"), ++ } ++ }, ++ { ++ .driver_data = &acp6x_card, ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "83N6"), ++ } ++ }, ++ { ++ .driver_data = &acp6x_card, ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "83Q2"), ++ } ++ }, ++ { ++ .driver_data = &acp6x_card, ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "83Q3"), ++ } ++ }, + { + .driver_data = &acp6x_card, + .matches = { +diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c +index 511446a30c057b..60248a6820aacc 100644 +--- a/sound/soc/soc-pcm.c ++++ b/sound/soc/soc-pcm.c +@@ -38,7 +38,6 @@ static inline int _soc_pcm_ret(struct snd_soc_pcm_runtime *rtd, + switch (ret) { + case -EPROBE_DEFER: + case -ENOTSUPP: +- case -EINVAL: + break; + default: + dev_err(rtd->dev, +@@ -902,7 +901,13 @@ static int __soc_pcm_prepare(struct snd_soc_pcm_runtime *rtd, + } + + out: +- return soc_pcm_ret(rtd, ret); ++ /* ++ * Don't use soc_pcm_ret() on .prepare callback to lower error log severity ++ * ++ * We don't want to log an error since we do not want to give userspace a way to do a ++ * denial-of-service attack on the syslog / diskspace. ++ */ ++ return ret; + } + + /* PCM prepare ops for non-DPCM streams */ +@@ -914,6 +919,13 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream) + snd_soc_dpcm_mutex_lock(rtd); + ret = __soc_pcm_prepare(rtd, substream); + snd_soc_dpcm_mutex_unlock(rtd); ++ ++ /* ++ * Don't use soc_pcm_ret() on .prepare callback to lower error log severity ++ * ++ * We don't want to log an error since we do not want to give userspace a way to do a ++ * denial-of-service attack on the syslog / diskspace. ++ */ + return ret; + } + +@@ -2461,7 +2473,13 @@ int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream) + be->dpcm[stream].state = SND_SOC_DPCM_STATE_PREPARE; + } + +- return soc_pcm_ret(fe, ret); ++ /* ++ * Don't use soc_pcm_ret() on .prepare callback to lower error log severity ++ * ++ * We don't want to log an error since we do not want to give userspace a way to do a ++ * denial-of-service attack on the syslog / diskspace. ++ */ ++ return ret; + } + + static int dpcm_fe_dai_prepare(struct snd_pcm_substream *substream) +@@ -2501,7 +2519,13 @@ static int dpcm_fe_dai_prepare(struct snd_pcm_substream *substream) + dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO); + snd_soc_dpcm_mutex_unlock(fe); + +- return soc_pcm_ret(fe, ret); ++ /* ++ * Don't use soc_pcm_ret() on .prepare callback to lower error log severity ++ * ++ * We don't want to log an error since we do not want to give userspace a way to do a ++ * denial-of-service attack on the syslog / diskspace. ++ */ ++ return ret; + } + + static int dpcm_run_update_shutdown(struct snd_soc_pcm_runtime *fe, int stream) +diff --git a/tools/perf/bench/epoll-wait.c b/tools/perf/bench/epoll-wait.c +index cb5174b53940b2..f370f7872ba4c9 100644 +--- a/tools/perf/bench/epoll-wait.c ++++ b/tools/perf/bench/epoll-wait.c +@@ -420,7 +420,12 @@ static int cmpworker(const void *p1, const void *p2) + + struct worker *w1 = (struct worker *) p1; + struct worker *w2 = (struct worker *) p2; +- return w1->tid > w2->tid; ++ ++ if (w1->tid > w2->tid) ++ return 1; ++ if (w1->tid < w2->tid) ++ return -1; ++ return 0; + } + + int bench_epoll_wait(int argc, const char **argv) +diff --git a/tools/testing/selftests/net/ipsec.c b/tools/testing/selftests/net/ipsec.c +index be4a30a0d02aef..9b44a091802cbb 100644 +--- a/tools/testing/selftests/net/ipsec.c ++++ b/tools/testing/selftests/net/ipsec.c +@@ -227,7 +227,8 @@ static int rtattr_pack(struct nlmsghdr *nh, size_t req_sz, + + attr->rta_len = RTA_LENGTH(size); + attr->rta_type = rta_type; +- memcpy(RTA_DATA(attr), payload, size); ++ if (payload) ++ memcpy(RTA_DATA(attr), payload, size); + + return 0; + } +diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect.c b/tools/testing/selftests/net/mptcp/mptcp_connect.c +index 414addef9a4514..d240d02fa443a1 100644 +--- a/tools/testing/selftests/net/mptcp/mptcp_connect.c ++++ b/tools/testing/selftests/net/mptcp/mptcp_connect.c +@@ -1302,7 +1302,7 @@ int main_loop(void) + return ret; + + if (cfg_truncate > 0) { +- xdisconnect(fd); ++ shutdown(fd, SHUT_WR); + } else if (--cfg_repeat > 0) { + xdisconnect(fd); + +diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh +index 17ace5627ce365..497dc187387f8d 100755 +--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh ++++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh +@@ -2941,7 +2941,7 @@ verify_listener_events() + type=$(mptcp_lib_evts_get_info type "$evt" "$e_type") + family=$(mptcp_lib_evts_get_info family "$evt" "$e_type") + sport=$(mptcp_lib_evts_get_info sport "$evt" "$e_type") +- if [ $family ] && [ $family = $AF_INET6 ]; then ++ if [ $family ] && [ $family = $MPTCP_LIB_AF_INET6 ]; then + saddr=$(mptcp_lib_evts_get_info saddr6 "$evt" "$e_type") + else + saddr=$(mptcp_lib_evts_get_info saddr4 "$evt" "$e_type") +diff --git a/tools/testing/selftests/net/udpgso.c b/tools/testing/selftests/net/udpgso.c +index b02080d09fbc05..d0fba50bd6ef08 100644 +--- a/tools/testing/selftests/net/udpgso.c ++++ b/tools/testing/selftests/net/udpgso.c +@@ -94,6 +94,19 @@ struct testcase testcases_v4[] = { + .gso_len = CONST_MSS_V4, + .r_num_mss = 1, + }, ++ { ++ /* datalen <= MSS < gso_len: will fall back to no GSO */ ++ .tlen = CONST_MSS_V4, ++ .gso_len = CONST_MSS_V4 + 1, ++ .r_num_mss = 0, ++ .r_len_last = CONST_MSS_V4, ++ }, ++ { ++ /* MSS < datalen < gso_len: fail */ ++ .tlen = CONST_MSS_V4 + 1, ++ .gso_len = CONST_MSS_V4 + 2, ++ .tfail = true, ++ }, + { + /* send a single MSS + 1B */ + .tlen = CONST_MSS_V4 + 1, +@@ -197,6 +210,19 @@ struct testcase testcases_v6[] = { + .gso_len = CONST_MSS_V6, + .r_num_mss = 1, + }, ++ { ++ /* datalen <= MSS < gso_len: will fall back to no GSO */ ++ .tlen = CONST_MSS_V6, ++ .gso_len = CONST_MSS_V6 + 1, ++ .r_num_mss = 0, ++ .r_len_last = CONST_MSS_V6, ++ }, ++ { ++ /* MSS < datalen < gso_len: fail */ ++ .tlen = CONST_MSS_V6 + 1, ++ .gso_len = CONST_MSS_V6 + 2, ++ .tfail = true ++ }, + { + /* send a single MSS + 1B */ + .tlen = CONST_MSS_V6 + 1, +diff --git a/tools/tracing/rtla/src/osnoise.c b/tools/tracing/rtla/src/osnoise.c +index 245e9344932bc4..699a83f538a8e8 100644 +--- a/tools/tracing/rtla/src/osnoise.c ++++ b/tools/tracing/rtla/src/osnoise.c +@@ -867,7 +867,7 @@ int osnoise_set_workload(struct osnoise_context *context, bool onoff) + + retval = osnoise_options_set_option("OSNOISE_WORKLOAD", onoff); + if (retval < 0) +- return -1; ++ return -2; + + context->opt_workload = onoff; + +diff --git a/tools/tracing/rtla/src/timerlat_hist.c b/tools/tracing/rtla/src/timerlat_hist.c +index 667f12f2d67f69..1525e88c6cf968 100644 +--- a/tools/tracing/rtla/src/timerlat_hist.c ++++ b/tools/tracing/rtla/src/timerlat_hist.c +@@ -900,12 +900,15 @@ timerlat_hist_apply_config(struct osnoise_tool *tool, struct timerlat_hist_param + auto_house_keeping(¶ms->monitored_cpus); + } + +- if (params->user_hist) { +- retval = osnoise_set_workload(tool->context, 0); +- if (retval) { +- err_msg("Failed to set OSNOISE_WORKLOAD option\n"); +- goto out_err; +- } ++ /* ++ * Set workload according to type of thread if the kernel supports it. ++ * On kernels without support, user threads will have already failed ++ * on missing timerlat_fd, and kernel threads do not need it. ++ */ ++ retval = osnoise_set_workload(tool->context, params->kernel_workload); ++ if (retval < -1) { ++ err_msg("Failed to set OSNOISE_WORKLOAD option\n"); ++ goto out_err; + } + + return 0; +@@ -946,9 +949,12 @@ static struct osnoise_tool + } + + static int stop_tracing; ++static struct trace_instance *hist_inst = NULL; + static void stop_hist(int sig) + { + stop_tracing = 1; ++ if (hist_inst) ++ trace_instance_stop(hist_inst); + } + + /* +@@ -994,6 +1000,12 @@ int timerlat_hist_main(int argc, char *argv[]) + } + + trace = &tool->trace; ++ /* ++ * Save trace instance into global variable so that SIGINT can stop ++ * the timerlat tracer. ++ * Otherwise, rtla could loop indefinitely when overloaded. ++ */ ++ hist_inst = trace; + + retval = enable_timerlat(trace); + if (retval) { +@@ -1126,7 +1138,7 @@ int timerlat_hist_main(int argc, char *argv[]) + + return_value = 0; + +- if (trace_is_off(&tool->trace, &record->trace)) { ++ if (trace_is_off(&tool->trace, &record->trace) && !stop_tracing) { + printf("rtla timerlat hit stop tracing\n"); + + if (!params->no_aa) +diff --git a/tools/tracing/rtla/src/timerlat_top.c b/tools/tracing/rtla/src/timerlat_top.c +index 0915092057f853..5a33789a375e3c 100644 +--- a/tools/tracing/rtla/src/timerlat_top.c ++++ b/tools/tracing/rtla/src/timerlat_top.c +@@ -679,12 +679,15 @@ timerlat_top_apply_config(struct osnoise_tool *top, struct timerlat_top_params * + auto_house_keeping(¶ms->monitored_cpus); + } + +- if (params->user_top) { +- retval = osnoise_set_workload(top->context, 0); +- if (retval) { +- err_msg("Failed to set OSNOISE_WORKLOAD option\n"); +- goto out_err; +- } ++ /* ++ * Set workload according to type of thread if the kernel supports it. ++ * On kernels without support, user threads will have already failed ++ * on missing timerlat_fd, and kernel threads do not need it. ++ */ ++ retval = osnoise_set_workload(top->context, params->kernel_workload); ++ if (retval < -1) { ++ err_msg("Failed to set OSNOISE_WORKLOAD option\n"); ++ goto out_err; + } + + return 0; +@@ -725,9 +728,12 @@ static struct osnoise_tool + } + + static int stop_tracing; ++static struct trace_instance *top_inst = NULL; + static void stop_top(int sig) + { + stop_tracing = 1; ++ if (top_inst) ++ trace_instance_stop(top_inst); + } + + /* +@@ -774,6 +780,13 @@ int timerlat_top_main(int argc, char *argv[]) + } + + trace = &top->trace; ++ /* ++ * Save trace instance into global variable so that SIGINT can stop ++ * the timerlat tracer. ++ * Otherwise, rtla could loop indefinitely when overloaded. ++ */ ++ top_inst = trace; ++ + + retval = enable_timerlat(trace); + if (retval) { +@@ -922,7 +935,7 @@ int timerlat_top_main(int argc, char *argv[]) + + return_value = 0; + +- if (trace_is_off(&top->trace, &record->trace)) { ++ if (trace_is_off(&top->trace, &record->trace) && !stop_tracing) { + printf("rtla timerlat hit stop tracing\n"); + + if (!params->no_aa) +diff --git a/tools/tracing/rtla/src/trace.c b/tools/tracing/rtla/src/trace.c +index e1ba6d9f426580..93e4032b2397af 100644 +--- a/tools/tracing/rtla/src/trace.c ++++ b/tools/tracing/rtla/src/trace.c +@@ -196,6 +196,14 @@ int trace_instance_start(struct trace_instance *trace) + return tracefs_trace_on(trace->inst); + } + ++/* ++ * trace_instance_stop - stop tracing a given rtla instance ++ */ ++int trace_instance_stop(struct trace_instance *trace) ++{ ++ return tracefs_trace_off(trace->inst); ++} ++ + /* + * trace_events_free - free a list of trace events + */ +diff --git a/tools/tracing/rtla/src/trace.h b/tools/tracing/rtla/src/trace.h +index 2e9a89a256150b..551a7cb81f6361 100644 +--- a/tools/tracing/rtla/src/trace.h ++++ b/tools/tracing/rtla/src/trace.h +@@ -21,6 +21,7 @@ struct trace_instance { + + int trace_instance_init(struct trace_instance *trace, char *tool_name); + int trace_instance_start(struct trace_instance *trace); ++int trace_instance_stop(struct trace_instance *trace); + void trace_instance_destroy(struct trace_instance *trace); + + struct trace_seq *get_trace_seq(void); diff --git a/patch/kernel/archive/odroidxu4-6.6/patch-6.6.78-79.patch b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.78-79.patch new file mode 100644 index 000000000000..a913f5bd71e1 --- /dev/null +++ b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.78-79.patch @@ -0,0 +1,6874 @@ +diff --git a/Documentation/arch/arm64/elf_hwcaps.rst b/Documentation/arch/arm64/elf_hwcaps.rst +index 76ff9d7398fda7..f88a24d621dd43 100644 +--- a/Documentation/arch/arm64/elf_hwcaps.rst ++++ b/Documentation/arch/arm64/elf_hwcaps.rst +@@ -174,22 +174,28 @@ HWCAP2_DCPODP + Functionality implied by ID_AA64ISAR1_EL1.DPB == 0b0010. + + HWCAP2_SVE2 +- Functionality implied by ID_AA64ZFR0_EL1.SVEVer == 0b0001. ++ Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001 and ++ ID_AA64ZFR0_EL1.SVEver == 0b0001. + + HWCAP2_SVEAES +- Functionality implied by ID_AA64ZFR0_EL1.AES == 0b0001. ++ Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001 and ++ ID_AA64ZFR0_EL1.AES == 0b0001. + + HWCAP2_SVEPMULL +- Functionality implied by ID_AA64ZFR0_EL1.AES == 0b0010. ++ Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001 and ++ ID_AA64ZFR0_EL1.AES == 0b0010. + + HWCAP2_SVEBITPERM +- Functionality implied by ID_AA64ZFR0_EL1.BitPerm == 0b0001. ++ Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001 and ++ ID_AA64ZFR0_EL1.BitPerm == 0b0001. + + HWCAP2_SVESHA3 +- Functionality implied by ID_AA64ZFR0_EL1.SHA3 == 0b0001. ++ Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001 and ++ ID_AA64ZFR0_EL1.SHA3 == 0b0001. + + HWCAP2_SVESM4 +- Functionality implied by ID_AA64ZFR0_EL1.SM4 == 0b0001. ++ Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001 and ++ ID_AA64ZFR0_EL1.SM4 == 0b0001. + + HWCAP2_FLAGM2 + Functionality implied by ID_AA64ISAR0_EL1.TS == 0b0010. +@@ -198,16 +204,20 @@ HWCAP2_FRINT + Functionality implied by ID_AA64ISAR1_EL1.FRINTTS == 0b0001. + + HWCAP2_SVEI8MM +- Functionality implied by ID_AA64ZFR0_EL1.I8MM == 0b0001. ++ Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001 and ++ ID_AA64ZFR0_EL1.I8MM == 0b0001. + + HWCAP2_SVEF32MM +- Functionality implied by ID_AA64ZFR0_EL1.F32MM == 0b0001. ++ Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001 and ++ ID_AA64ZFR0_EL1.F32MM == 0b0001. + + HWCAP2_SVEF64MM +- Functionality implied by ID_AA64ZFR0_EL1.F64MM == 0b0001. ++ Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001 and ++ ID_AA64ZFR0_EL1.F64MM == 0b0001. + + HWCAP2_SVEBF16 +- Functionality implied by ID_AA64ZFR0_EL1.BF16 == 0b0001. ++ Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001 and ++ ID_AA64ZFR0_EL1.BF16 == 0b0001. + + HWCAP2_I8MM + Functionality implied by ID_AA64ISAR1_EL1.I8MM == 0b0001. +@@ -273,7 +283,8 @@ HWCAP2_EBF16 + Functionality implied by ID_AA64ISAR1_EL1.BF16 == 0b0010. + + HWCAP2_SVE_EBF16 +- Functionality implied by ID_AA64ZFR0_EL1.BF16 == 0b0010. ++ Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001 and ++ ID_AA64ZFR0_EL1.BF16 == 0b0010. + + HWCAP2_CSSC + Functionality implied by ID_AA64ISAR2_EL1.CSSC == 0b0001. +@@ -282,7 +293,8 @@ HWCAP2_RPRFM + Functionality implied by ID_AA64ISAR2_EL1.RPRFM == 0b0001. + + HWCAP2_SVE2P1 +- Functionality implied by ID_AA64ZFR0_EL1.SVEver == 0b0010. ++ Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001 and ++ ID_AA64ZFR0_EL1.SVEver == 0b0010. + + HWCAP2_SME2 + Functionality implied by ID_AA64SMFR0_EL1.SMEver == 0b0001. +diff --git a/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.yaml b/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.yaml +index 9ea8ac0786acce..a72175a0910ba5 100644 +--- a/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.yaml ++++ b/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.yaml +@@ -22,7 +22,7 @@ description: + Each sub-node is identified using the node's name, with valid values listed + for each of the pmics below. + +- For mp5496, s1, s2 ++ For mp5496, s1, s2, l2, l5 + + For pm2250, s1, s2, s3, s4, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, + l12, l13, l14, l15, l16, l17, l18, l19, l20, l21, l22 +diff --git a/Makefile b/Makefile +index 1d777c3eb7fb97..de16ab06861410 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 6 + PATCHLEVEL = 6 +-SUBLEVEL = 78 ++SUBLEVEL = 79 + EXTRAVERSION = + NAME = Pinguïn Aangedreven + +@@ -1054,8 +1054,8 @@ LDFLAGS_vmlinux += --orphan-handling=$(CONFIG_LD_ORPHAN_WARN_LEVEL) + endif + + # Align the bit size of userspace programs with the kernel +-KBUILD_USERCFLAGS += $(filter -m32 -m64 --target=%, $(KBUILD_CFLAGS)) +-KBUILD_USERLDFLAGS += $(filter -m32 -m64 --target=%, $(KBUILD_CFLAGS)) ++KBUILD_USERCFLAGS += $(filter -m32 -m64 --target=%, $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS)) ++KBUILD_USERLDFLAGS += $(filter -m32 -m64 --target=%, $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS)) + + # make the checker run with the right architecture + CHECKFLAGS += --arch=$(ARCH) +@@ -1348,18 +1348,13 @@ ifneq ($(wildcard $(resolve_btfids_O)),) + $(Q)$(MAKE) -sC $(srctree)/tools/bpf/resolve_btfids O=$(resolve_btfids_O) clean + endif + +-# Clear a bunch of variables before executing the submake +-ifeq ($(quiet),silent_) +-tools_silent=s +-endif +- + tools/: FORCE + $(Q)mkdir -p $(objtree)/tools +- $(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(tools_silent) $(filter --j% -j,$(MAKEFLAGS))" O=$(abspath $(objtree)) subdir=tools -C $(srctree)/tools/ ++ $(Q)$(MAKE) LDFLAGS= O=$(abspath $(objtree)) subdir=tools -C $(srctree)/tools/ + + tools/%: FORCE + $(Q)mkdir -p $(objtree)/tools +- $(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(tools_silent) $(filter --j% -j,$(MAKEFLAGS))" O=$(abspath $(objtree)) subdir=tools -C $(srctree)/tools/ $* ++ $(Q)$(MAKE) LDFLAGS= O=$(abspath $(objtree)) subdir=tools -C $(srctree)/tools/ $* + + # --------------------------------------------------------------------------- + # Kernel selftest +diff --git a/arch/alpha/include/uapi/asm/ptrace.h b/arch/alpha/include/uapi/asm/ptrace.h +index 5ca45934fcbb82..72ed913a910f25 100644 +--- a/arch/alpha/include/uapi/asm/ptrace.h ++++ b/arch/alpha/include/uapi/asm/ptrace.h +@@ -42,6 +42,8 @@ struct pt_regs { + unsigned long trap_a0; + unsigned long trap_a1; + unsigned long trap_a2; ++/* This makes the stack 16-byte aligned as GCC expects */ ++ unsigned long __pad0; + /* These are saved by PAL-code: */ + unsigned long ps; + unsigned long pc; +diff --git a/arch/alpha/kernel/asm-offsets.c b/arch/alpha/kernel/asm-offsets.c +index b121294bee2663..11c35cf45b4610 100644 +--- a/arch/alpha/kernel/asm-offsets.c ++++ b/arch/alpha/kernel/asm-offsets.c +@@ -34,7 +34,9 @@ void foo(void) + DEFINE(CRED_EGID, offsetof(struct cred, egid)); + BLANK(); + ++ DEFINE(SP_OFF, offsetof(struct pt_regs, ps)); + DEFINE(SIZEOF_PT_REGS, sizeof(struct pt_regs)); ++ DEFINE(SWITCH_STACK_SIZE, sizeof(struct switch_stack)); + DEFINE(PT_PTRACED, PT_PTRACED); + DEFINE(CLONE_VM, CLONE_VM); + DEFINE(CLONE_UNTRACED, CLONE_UNTRACED); +diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S +index eb51f93a70c8f1..602f701a1c3963 100644 +--- a/arch/alpha/kernel/entry.S ++++ b/arch/alpha/kernel/entry.S +@@ -15,10 +15,6 @@ + .set noat + .cfi_sections .debug_frame + +-/* Stack offsets. */ +-#define SP_OFF 184 +-#define SWITCH_STACK_SIZE 64 +- + .macro CFI_START_OSF_FRAME func + .align 4 + .globl \func +@@ -198,8 +194,8 @@ CFI_END_OSF_FRAME entArith + CFI_START_OSF_FRAME entMM + SAVE_ALL + /* save $9 - $15 so the inline exception code can manipulate them. */ +- subq $sp, 56, $sp +- .cfi_adjust_cfa_offset 56 ++ subq $sp, 64, $sp ++ .cfi_adjust_cfa_offset 64 + stq $9, 0($sp) + stq $10, 8($sp) + stq $11, 16($sp) +@@ -214,7 +210,7 @@ CFI_START_OSF_FRAME entMM + .cfi_rel_offset $13, 32 + .cfi_rel_offset $14, 40 + .cfi_rel_offset $15, 48 +- addq $sp, 56, $19 ++ addq $sp, 64, $19 + /* handle the fault */ + lda $8, 0x3fff + bic $sp, $8, $8 +@@ -227,7 +223,7 @@ CFI_START_OSF_FRAME entMM + ldq $13, 32($sp) + ldq $14, 40($sp) + ldq $15, 48($sp) +- addq $sp, 56, $sp ++ addq $sp, 64, $sp + .cfi_restore $9 + .cfi_restore $10 + .cfi_restore $11 +@@ -235,7 +231,7 @@ CFI_START_OSF_FRAME entMM + .cfi_restore $13 + .cfi_restore $14 + .cfi_restore $15 +- .cfi_adjust_cfa_offset -56 ++ .cfi_adjust_cfa_offset -64 + /* finish up the syscall as normal. */ + br ret_from_sys_call + CFI_END_OSF_FRAME entMM +@@ -382,8 +378,8 @@ entUnaUser: + .cfi_restore $0 + .cfi_adjust_cfa_offset -256 + SAVE_ALL /* setup normal kernel stack */ +- lda $sp, -56($sp) +- .cfi_adjust_cfa_offset 56 ++ lda $sp, -64($sp) ++ .cfi_adjust_cfa_offset 64 + stq $9, 0($sp) + stq $10, 8($sp) + stq $11, 16($sp) +@@ -399,7 +395,7 @@ entUnaUser: + .cfi_rel_offset $14, 40 + .cfi_rel_offset $15, 48 + lda $8, 0x3fff +- addq $sp, 56, $19 ++ addq $sp, 64, $19 + bic $sp, $8, $8 + jsr $26, do_entUnaUser + ldq $9, 0($sp) +@@ -409,7 +405,7 @@ entUnaUser: + ldq $13, 32($sp) + ldq $14, 40($sp) + ldq $15, 48($sp) +- lda $sp, 56($sp) ++ lda $sp, 64($sp) + .cfi_restore $9 + .cfi_restore $10 + .cfi_restore $11 +@@ -417,7 +413,7 @@ entUnaUser: + .cfi_restore $13 + .cfi_restore $14 + .cfi_restore $15 +- .cfi_adjust_cfa_offset -56 ++ .cfi_adjust_cfa_offset -64 + br ret_from_sys_call + CFI_END_OSF_FRAME entUna + +diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c +index d9a67b370e0476..de72bd837c5af7 100644 +--- a/arch/alpha/kernel/traps.c ++++ b/arch/alpha/kernel/traps.c +@@ -707,7 +707,7 @@ s_reg_to_mem (unsigned long s_reg) + static int unauser_reg_offsets[32] = { + R(r0), R(r1), R(r2), R(r3), R(r4), R(r5), R(r6), R(r7), R(r8), + /* r9 ... r15 are stored in front of regs. */ +- -56, -48, -40, -32, -24, -16, -8, ++ -64, -56, -48, -40, -32, -24, -16, /* padding at -8 */ + R(r16), R(r17), R(r18), + R(r19), R(r20), R(r21), R(r22), R(r23), R(r24), R(r25), R(r26), + R(r27), R(r28), R(gp), +diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c +index 8c9850437e6744..a9816bbc9f34d3 100644 +--- a/arch/alpha/mm/fault.c ++++ b/arch/alpha/mm/fault.c +@@ -78,8 +78,8 @@ __load_new_mm_context(struct mm_struct *next_mm) + + /* Macro for exception fixup code to access integer registers. */ + #define dpf_reg(r) \ +- (((unsigned long *)regs)[(r) <= 8 ? (r) : (r) <= 15 ? (r)-16 : \ +- (r) <= 18 ? (r)+10 : (r)-10]) ++ (((unsigned long *)regs)[(r) <= 8 ? (r) : (r) <= 15 ? (r)-17 : \ ++ (r) <= 18 ? (r)+11 : (r)-10]) + + asmlinkage void + do_page_fault(unsigned long address, unsigned long mmcsr, +diff --git a/arch/arm64/kernel/cacheinfo.c b/arch/arm64/kernel/cacheinfo.c +index d9c9218fa1fddc..309942b06c5bc2 100644 +--- a/arch/arm64/kernel/cacheinfo.c ++++ b/arch/arm64/kernel/cacheinfo.c +@@ -101,16 +101,18 @@ int populate_cache_leaves(unsigned int cpu) + unsigned int level, idx; + enum cache_type type; + struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); +- struct cacheinfo *this_leaf = this_cpu_ci->info_list; ++ struct cacheinfo *infos = this_cpu_ci->info_list; + + for (idx = 0, level = 1; level <= this_cpu_ci->num_levels && +- idx < this_cpu_ci->num_leaves; idx++, level++) { ++ idx < this_cpu_ci->num_leaves; level++) { + type = get_cache_type(level); + if (type == CACHE_TYPE_SEPARATE) { +- ci_leaf_init(this_leaf++, CACHE_TYPE_DATA, level); +- ci_leaf_init(this_leaf++, CACHE_TYPE_INST, level); ++ if (idx + 1 >= this_cpu_ci->num_leaves) ++ break; ++ ci_leaf_init(&infos[idx++], CACHE_TYPE_DATA, level); ++ ci_leaf_init(&infos[idx++], CACHE_TYPE_INST, level); + } else { +- ci_leaf_init(this_leaf++, type, level); ++ ci_leaf_init(&infos[idx++], type, level); + } + } + return 0; +diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c +index 7e96604559004b..82778258855d1a 100644 +--- a/arch/arm64/kernel/cpufeature.c ++++ b/arch/arm64/kernel/cpufeature.c +@@ -2762,6 +2762,13 @@ static const struct arm64_cpu_capabilities arm64_features[] = { + .matches = match, \ + } + ++#define HWCAP_CAP_MATCH_ID(match, reg, field, min_value, cap_type, cap) \ ++ { \ ++ __HWCAP_CAP(#cap, cap_type, cap) \ ++ HWCAP_CPUID_MATCH(reg, field, min_value) \ ++ .matches = match, \ ++ } ++ + #ifdef CONFIG_ARM64_PTR_AUTH + static const struct arm64_cpu_capabilities ptr_auth_hwcap_addr_matches[] = { + { +@@ -2790,6 +2797,13 @@ static const struct arm64_cpu_capabilities ptr_auth_hwcap_gen_matches[] = { + }; + #endif + ++#ifdef CONFIG_ARM64_SVE ++static bool has_sve_feature(const struct arm64_cpu_capabilities *cap, int scope) ++{ ++ return system_supports_sve() && has_user_cpuid_feature(cap, scope); ++} ++#endif ++ + static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = { + HWCAP_CAP(ID_AA64ISAR0_EL1, AES, PMULL, CAP_HWCAP, KERNEL_HWCAP_PMULL), + HWCAP_CAP(ID_AA64ISAR0_EL1, AES, AES, CAP_HWCAP, KERNEL_HWCAP_AES), +@@ -2827,18 +2841,18 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = { + HWCAP_CAP(ID_AA64MMFR2_EL1, AT, IMP, CAP_HWCAP, KERNEL_HWCAP_USCAT), + #ifdef CONFIG_ARM64_SVE + HWCAP_CAP(ID_AA64PFR0_EL1, SVE, IMP, CAP_HWCAP, KERNEL_HWCAP_SVE), +- HWCAP_CAP(ID_AA64ZFR0_EL1, SVEver, SVE2p1, CAP_HWCAP, KERNEL_HWCAP_SVE2P1), +- HWCAP_CAP(ID_AA64ZFR0_EL1, SVEver, SVE2, CAP_HWCAP, KERNEL_HWCAP_SVE2), +- HWCAP_CAP(ID_AA64ZFR0_EL1, AES, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEAES), +- HWCAP_CAP(ID_AA64ZFR0_EL1, AES, PMULL128, CAP_HWCAP, KERNEL_HWCAP_SVEPMULL), +- HWCAP_CAP(ID_AA64ZFR0_EL1, BitPerm, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEBITPERM), +- HWCAP_CAP(ID_AA64ZFR0_EL1, BF16, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEBF16), +- HWCAP_CAP(ID_AA64ZFR0_EL1, BF16, EBF16, CAP_HWCAP, KERNEL_HWCAP_SVE_EBF16), +- HWCAP_CAP(ID_AA64ZFR0_EL1, SHA3, IMP, CAP_HWCAP, KERNEL_HWCAP_SVESHA3), +- HWCAP_CAP(ID_AA64ZFR0_EL1, SM4, IMP, CAP_HWCAP, KERNEL_HWCAP_SVESM4), +- HWCAP_CAP(ID_AA64ZFR0_EL1, I8MM, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEI8MM), +- HWCAP_CAP(ID_AA64ZFR0_EL1, F32MM, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEF32MM), +- HWCAP_CAP(ID_AA64ZFR0_EL1, F64MM, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEF64MM), ++ HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, SVEver, SVE2p1, CAP_HWCAP, KERNEL_HWCAP_SVE2P1), ++ HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, SVEver, SVE2, CAP_HWCAP, KERNEL_HWCAP_SVE2), ++ HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, AES, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEAES), ++ HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, AES, PMULL128, CAP_HWCAP, KERNEL_HWCAP_SVEPMULL), ++ HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, BitPerm, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEBITPERM), ++ HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, BF16, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEBF16), ++ HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, BF16, EBF16, CAP_HWCAP, KERNEL_HWCAP_SVE_EBF16), ++ HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, SHA3, IMP, CAP_HWCAP, KERNEL_HWCAP_SVESHA3), ++ HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, SM4, IMP, CAP_HWCAP, KERNEL_HWCAP_SVESM4), ++ HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, I8MM, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEI8MM), ++ HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, F32MM, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEF32MM), ++ HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, F64MM, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEF64MM), + #endif + HWCAP_CAP(ID_AA64PFR1_EL1, SSBS, SSBS2, CAP_HWCAP, KERNEL_HWCAP_SSBS), + #ifdef CONFIG_ARM64_BTI +diff --git a/arch/arm64/kernel/vdso/vdso.lds.S b/arch/arm64/kernel/vdso/vdso.lds.S +index 45354f2ddf7069..2e126ab79ecd86 100644 +--- a/arch/arm64/kernel/vdso/vdso.lds.S ++++ b/arch/arm64/kernel/vdso/vdso.lds.S +@@ -38,6 +38,7 @@ SECTIONS + */ + /DISCARD/ : { + *(.note.GNU-stack .note.gnu.property) ++ *(.ARM.attributes) + } + .note : { *(.note.*) } :text :note + +diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S +index a553dae9a0d482..d4353741f331e3 100644 +--- a/arch/arm64/kernel/vmlinux.lds.S ++++ b/arch/arm64/kernel/vmlinux.lds.S +@@ -162,6 +162,7 @@ SECTIONS + /DISCARD/ : { + *(.interp .dynamic) + *(.dynsym .dynstr .hash .gnu.hash) ++ *(.ARM.attributes) + } + + . = KIMAGE_VADDR; +diff --git a/arch/loongarch/kernel/genex.S b/arch/loongarch/kernel/genex.S +index 2bb3aa2dcfcb2e..e75c2dbd5f2c52 100644 +--- a/arch/loongarch/kernel/genex.S ++++ b/arch/loongarch/kernel/genex.S +@@ -18,27 +18,29 @@ + + .align 5 + SYM_FUNC_START(__arch_cpu_idle) +- /* start of rollback region */ +- LONG_L t0, tp, TI_FLAGS +- nop +- andi t0, t0, _TIF_NEED_RESCHED +- bnez t0, 1f +- nop +- nop +- nop ++ /* start of idle interrupt region */ ++ ori t0, zero, CSR_CRMD_IE ++ /* idle instruction needs irq enabled */ ++ csrxchg t0, t0, LOONGARCH_CSR_CRMD ++ /* ++ * If an interrupt lands here; between enabling interrupts above and ++ * going idle on the next instruction, we must *NOT* go idle since the ++ * interrupt could have set TIF_NEED_RESCHED or caused an timer to need ++ * reprogramming. Fall through -- see handle_vint() below -- and have ++ * the idle loop take care of things. ++ */ + idle 0 +- /* end of rollback region */ ++ /* end of idle interrupt region */ + 1: jr ra + SYM_FUNC_END(__arch_cpu_idle) + + SYM_CODE_START(handle_vint) + BACKUP_T0T1 + SAVE_ALL +- la_abs t1, __arch_cpu_idle ++ la_abs t1, 1b + LONG_L t0, sp, PT_ERA +- /* 32 byte rollback region */ +- ori t0, t0, 0x1f +- xori t0, t0, 0x1f ++ /* 3 instructions idle interrupt region */ ++ ori t0, t0, 0b1100 + bne t0, t1, 1f + LONG_S t0, sp, PT_ERA + 1: move a0, sp +diff --git a/arch/loongarch/kernel/idle.c b/arch/loongarch/kernel/idle.c +index 0b5dd2faeb90b8..54b247d8cdb695 100644 +--- a/arch/loongarch/kernel/idle.c ++++ b/arch/loongarch/kernel/idle.c +@@ -11,7 +11,6 @@ + + void __cpuidle arch_cpu_idle(void) + { +- raw_local_irq_enable(); +- __arch_cpu_idle(); /* idle instruction needs irq enabled */ ++ __arch_cpu_idle(); + raw_local_irq_disable(); + } +diff --git a/arch/loongarch/kernel/reset.c b/arch/loongarch/kernel/reset.c +index 1ef8c63835351b..de8fa5a8a825cd 100644 +--- a/arch/loongarch/kernel/reset.c ++++ b/arch/loongarch/kernel/reset.c +@@ -33,7 +33,7 @@ void machine_halt(void) + console_flush_on_panic(CONSOLE_FLUSH_PENDING); + + while (true) { +- __arch_cpu_idle(); ++ __asm__ __volatile__("idle 0" : : : "memory"); + } + } + +@@ -53,7 +53,7 @@ void machine_power_off(void) + #endif + + while (true) { +- __arch_cpu_idle(); ++ __asm__ __volatile__("idle 0" : : : "memory"); + } + } + +@@ -74,6 +74,6 @@ void machine_restart(char *command) + acpi_reboot(); + + while (true) { +- __arch_cpu_idle(); ++ __asm__ __volatile__("idle 0" : : : "memory"); + } + } +diff --git a/arch/loongarch/lib/csum.c b/arch/loongarch/lib/csum.c +index a5e84b403c3b34..df309ae4045dee 100644 +--- a/arch/loongarch/lib/csum.c ++++ b/arch/loongarch/lib/csum.c +@@ -25,7 +25,7 @@ unsigned int __no_sanitize_address do_csum(const unsigned char *buff, int len) + const u64 *ptr; + u64 data, sum64 = 0; + +- if (unlikely(len == 0)) ++ if (unlikely(len <= 0)) + return 0; + + offset = (unsigned long)buff & 7; +diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c +index 37c8badd270155..df286789c94f18 100644 +--- a/arch/x86/events/intel/core.c ++++ b/arch/x86/events/intel/core.c +@@ -4715,8 +4715,11 @@ static void intel_pmu_cpu_starting(int cpu) + + init_debug_store_on_cpu(cpu); + /* +- * Deal with CPUs that don't clear their LBRs on power-up. ++ * Deal with CPUs that don't clear their LBRs on power-up, and that may ++ * even boot with LBRs enabled. + */ ++ if (!static_cpu_has(X86_FEATURE_ARCH_LBR) && x86_pmu.lbr_nr) ++ msr_clear_bit(MSR_IA32_DEBUGCTLMSR, DEBUGCTLMSR_LBR_BIT); + intel_pmu_lbr_reset(); + + cpuc->lbr_sel = NULL; +diff --git a/arch/x86/include/asm/mmu.h b/arch/x86/include/asm/mmu.h +index 0da5c227f490c0..53763cf1927775 100644 +--- a/arch/x86/include/asm/mmu.h ++++ b/arch/x86/include/asm/mmu.h +@@ -37,6 +37,8 @@ typedef struct { + */ + atomic64_t tlb_gen; + ++ unsigned long next_trim_cpumask; ++ + #ifdef CONFIG_MODIFY_LDT_SYSCALL + struct rw_semaphore ldt_usr_sem; + struct ldt_struct *ldt; +diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h +index 8dac45a2c7fcf2..f5afd956d5e50a 100644 +--- a/arch/x86/include/asm/mmu_context.h ++++ b/arch/x86/include/asm/mmu_context.h +@@ -145,6 +145,7 @@ static inline int init_new_context(struct task_struct *tsk, + + mm->context.ctx_id = atomic64_inc_return(&last_mm_ctx_id); + atomic64_set(&mm->context.tlb_gen, 0); ++ mm->context.next_trim_cpumask = jiffies + HZ; + + #ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS + if (cpu_feature_enabled(X86_FEATURE_OSPKE)) { +diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h +index 24b7bd255e9830..623bb48774d44c 100644 +--- a/arch/x86/include/asm/msr-index.h ++++ b/arch/x86/include/asm/msr-index.h +@@ -358,7 +358,8 @@ + #define MSR_IA32_PASID_VALID BIT_ULL(31) + + /* DEBUGCTLMSR bits (others vary by model): */ +-#define DEBUGCTLMSR_LBR (1UL << 0) /* last branch recording */ ++#define DEBUGCTLMSR_LBR_BIT 0 /* last branch recording */ ++#define DEBUGCTLMSR_LBR (1UL << DEBUGCTLMSR_LBR_BIT) + #define DEBUGCTLMSR_BTF_SHIFT 1 + #define DEBUGCTLMSR_BTF (1UL << 1) /* single-step on branches */ + #define DEBUGCTLMSR_BUS_LOCK_DETECT (1UL << 2) +diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h +index 25726893c6f4dd..5d61adc6e892ea 100644 +--- a/arch/x86/include/asm/tlbflush.h ++++ b/arch/x86/include/asm/tlbflush.h +@@ -222,6 +222,7 @@ struct flush_tlb_info { + unsigned int initiating_cpu; + u8 stride_shift; + u8 freed_tables; ++ u8 trim_cpumask; + }; + + void flush_tlb_local(void); +diff --git a/arch/x86/kernel/i8253.c b/arch/x86/kernel/i8253.c +index 2b7999a1a50a83..80e262bb627fe1 100644 +--- a/arch/x86/kernel/i8253.c ++++ b/arch/x86/kernel/i8253.c +@@ -8,6 +8,7 @@ + #include + #include + ++#include + #include + #include + #include +@@ -39,9 +40,15 @@ static bool __init use_pit(void) + + bool __init pit_timer_init(void) + { +- if (!use_pit()) ++ if (!use_pit()) { ++ /* ++ * Don't just ignore the PIT. Ensure it's stopped, because ++ * VMMs otherwise steal CPU time just to pointlessly waggle ++ * the (masked) IRQ. ++ */ ++ clockevent_i8253_disable(); + return false; +- ++ } + clockevent_i8253_init(true); + global_clock_event = &i8253_clockevent; + return true; +diff --git a/arch/x86/kernel/static_call.c b/arch/x86/kernel/static_call.c +index e332d835d6583f..07961b362e2a0c 100644 +--- a/arch/x86/kernel/static_call.c ++++ b/arch/x86/kernel/static_call.c +@@ -175,7 +175,6 @@ EXPORT_SYMBOL_GPL(arch_static_call_transform); + noinstr void __static_call_update_early(void *tramp, void *func) + { + BUG_ON(system_state != SYSTEM_BOOTING); +- BUG_ON(!early_boot_irqs_disabled); + BUG_ON(static_call_initialized); + __text_gen_insn(tramp, JMP32_INSN_OPCODE, tramp, func, JMP32_INSN_SIZE); + sync_core(); +diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c +index 238afd7335e46d..bd3fbd5be5da6e 100644 +--- a/arch/x86/kvm/hyperv.c ++++ b/arch/x86/kvm/hyperv.c +@@ -2175,6 +2175,9 @@ static u64 kvm_hv_send_ipi(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc) + u32 vector; + bool all_cpus; + ++ if (!lapic_in_kernel(vcpu)) ++ return HV_STATUS_INVALID_HYPERCALL_INPUT; ++ + if (hc->code == HVCALL_SEND_IPI) { + if (!hc->fast) { + if (unlikely(kvm_read_guest(kvm, hc->ingpa, &send_ipi, +@@ -2801,7 +2804,8 @@ int kvm_get_hv_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid2 *cpuid, + ent->eax |= HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED; + ent->eax |= HV_X64_APIC_ACCESS_RECOMMENDED; + ent->eax |= HV_X64_RELAXED_TIMING_RECOMMENDED; +- ent->eax |= HV_X64_CLUSTER_IPI_RECOMMENDED; ++ if (!vcpu || lapic_in_kernel(vcpu)) ++ ent->eax |= HV_X64_CLUSTER_IPI_RECOMMENDED; + ent->eax |= HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED; + if (evmcs_ver) + ent->eax |= HV_X64_ENLIGHTENED_VMCS_RECOMMENDED; +diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c +index ff85526a9d4819..04b9b919235ecf 100644 +--- a/arch/x86/kvm/mmu/mmu.c ++++ b/arch/x86/kvm/mmu/mmu.c +@@ -5289,7 +5289,7 @@ void kvm_init_shadow_npt_mmu(struct kvm_vcpu *vcpu, unsigned long cr0, + union kvm_mmu_page_role root_role; + + /* NPT requires CR0.PG=1. */ +- WARN_ON_ONCE(cpu_role.base.direct); ++ WARN_ON_ONCE(cpu_role.base.direct || !cpu_role.base.guest_mode); + + root_role = cpu_role.base; + root_role.level = kvm_mmu_get_tdp_level(vcpu); +diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c +index acf22bd99efcd8..e3f3e30fc89cac 100644 +--- a/arch/x86/kvm/svm/nested.c ++++ b/arch/x86/kvm/svm/nested.c +@@ -644,6 +644,11 @@ static void nested_vmcb02_prepare_control(struct vcpu_svm *svm, + u32 pause_count12; + u32 pause_thresh12; + ++ nested_svm_transition_tlb_flush(vcpu); ++ ++ /* Enter Guest-Mode */ ++ enter_guest_mode(vcpu); ++ + /* + * Filled at exit: exit_code, exit_code_hi, exit_info_1, exit_info_2, + * exit_int_info, exit_int_info_err, next_rip, insn_len, insn_bytes. +@@ -760,11 +765,6 @@ static void nested_vmcb02_prepare_control(struct vcpu_svm *svm, + } + } + +- nested_svm_transition_tlb_flush(vcpu); +- +- /* Enter Guest-Mode */ +- enter_guest_mode(vcpu); +- + /* + * Merge guest and host intercepts - must be called with vcpu in + * guest-mode to take effect. +diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c +index 64f594826a2822..df1794a5e38a57 100644 +--- a/arch/x86/mm/tlb.c ++++ b/arch/x86/mm/tlb.c +@@ -898,9 +898,36 @@ static void flush_tlb_func(void *info) + nr_invalidate); + } + +-static bool tlb_is_not_lazy(int cpu, void *data) ++static bool should_flush_tlb(int cpu, void *data) + { +- return !per_cpu(cpu_tlbstate_shared.is_lazy, cpu); ++ struct flush_tlb_info *info = data; ++ ++ /* Lazy TLB will get flushed at the next context switch. */ ++ if (per_cpu(cpu_tlbstate_shared.is_lazy, cpu)) ++ return false; ++ ++ /* No mm means kernel memory flush. */ ++ if (!info->mm) ++ return true; ++ ++ /* The target mm is loaded, and the CPU is not lazy. */ ++ if (per_cpu(cpu_tlbstate.loaded_mm, cpu) == info->mm) ++ return true; ++ ++ /* In cpumask, but not the loaded mm? Periodically remove by flushing. */ ++ if (info->trim_cpumask) ++ return true; ++ ++ return false; ++} ++ ++static bool should_trim_cpumask(struct mm_struct *mm) ++{ ++ if (time_after(jiffies, READ_ONCE(mm->context.next_trim_cpumask))) { ++ WRITE_ONCE(mm->context.next_trim_cpumask, jiffies + HZ); ++ return true; ++ } ++ return false; + } + + DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state_shared, cpu_tlbstate_shared); +@@ -934,7 +961,7 @@ STATIC_NOPV void native_flush_tlb_multi(const struct cpumask *cpumask, + if (info->freed_tables) + on_each_cpu_mask(cpumask, flush_tlb_func, (void *)info, true); + else +- on_each_cpu_cond_mask(tlb_is_not_lazy, flush_tlb_func, ++ on_each_cpu_cond_mask(should_flush_tlb, flush_tlb_func, + (void *)info, 1, cpumask); + } + +@@ -985,6 +1012,7 @@ static struct flush_tlb_info *get_flush_tlb_info(struct mm_struct *mm, + info->freed_tables = freed_tables; + info->new_tlb_gen = new_tlb_gen; + info->initiating_cpu = smp_processor_id(); ++ info->trim_cpumask = 0; + + return info; + } +@@ -1027,6 +1055,7 @@ void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start, + * flush_tlb_func_local() directly in this case. + */ + if (cpumask_any_but(mm_cpumask(mm), cpu) < nr_cpu_ids) { ++ info->trim_cpumask = should_trim_cpumask(mm); + flush_tlb_multi(mm_cpumask(mm), info); + } else if (mm == this_cpu_read(cpu_tlbstate.loaded_mm)) { + lockdep_assert_irqs_enabled(); +diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c +index 6b201e64d8abc8..88a722954f3f78 100644 +--- a/arch/x86/xen/mmu_pv.c ++++ b/arch/x86/xen/mmu_pv.c +@@ -113,6 +113,51 @@ static pud_t level3_user_vsyscall[PTRS_PER_PUD] __page_aligned_bss; + */ + static DEFINE_SPINLOCK(xen_reservation_lock); + ++/* Protected by xen_reservation_lock. */ ++#define MIN_CONTIG_ORDER 9 /* 2MB */ ++static unsigned int discontig_frames_order = MIN_CONTIG_ORDER; ++static unsigned long discontig_frames_early[1UL << MIN_CONTIG_ORDER] __initdata; ++static unsigned long *discontig_frames __refdata = discontig_frames_early; ++static bool discontig_frames_dyn; ++ ++static int alloc_discontig_frames(unsigned int order) ++{ ++ unsigned long *new_array, *old_array; ++ unsigned int old_order; ++ unsigned long flags; ++ ++ BUG_ON(order < MIN_CONTIG_ORDER); ++ BUILD_BUG_ON(sizeof(discontig_frames_early) != PAGE_SIZE); ++ ++ new_array = (unsigned long *)__get_free_pages(GFP_KERNEL, ++ order - MIN_CONTIG_ORDER); ++ if (!new_array) ++ return -ENOMEM; ++ ++ spin_lock_irqsave(&xen_reservation_lock, flags); ++ ++ old_order = discontig_frames_order; ++ ++ if (order > discontig_frames_order || !discontig_frames_dyn) { ++ if (!discontig_frames_dyn) ++ old_array = NULL; ++ else ++ old_array = discontig_frames; ++ ++ discontig_frames = new_array; ++ discontig_frames_order = order; ++ discontig_frames_dyn = true; ++ } else { ++ old_array = new_array; ++ } ++ ++ spin_unlock_irqrestore(&xen_reservation_lock, flags); ++ ++ free_pages((unsigned long)old_array, old_order - MIN_CONTIG_ORDER); ++ ++ return 0; ++} ++ + /* + * Note about cr3 (pagetable base) values: + * +@@ -782,6 +827,7 @@ void xen_mm_pin_all(void) + { + struct page *page; + ++ spin_lock(&init_mm.page_table_lock); + spin_lock(&pgd_lock); + + list_for_each_entry(page, &pgd_list, lru) { +@@ -792,6 +838,7 @@ void xen_mm_pin_all(void) + } + + spin_unlock(&pgd_lock); ++ spin_unlock(&init_mm.page_table_lock); + } + + static void __init xen_mark_pinned(struct mm_struct *mm, struct page *page, +@@ -813,6 +860,9 @@ static void __init xen_after_bootmem(void) + SetPagePinned(virt_to_page(level3_user_vsyscall)); + #endif + xen_pgd_walk(&init_mm, xen_mark_pinned, FIXADDR_TOP); ++ ++ if (alloc_discontig_frames(MIN_CONTIG_ORDER)) ++ BUG(); + } + + static void xen_unpin_page(struct mm_struct *mm, struct page *page, +@@ -888,6 +938,7 @@ void xen_mm_unpin_all(void) + { + struct page *page; + ++ spin_lock(&init_mm.page_table_lock); + spin_lock(&pgd_lock); + + list_for_each_entry(page, &pgd_list, lru) { +@@ -899,6 +950,7 @@ void xen_mm_unpin_all(void) + } + + spin_unlock(&pgd_lock); ++ spin_unlock(&init_mm.page_table_lock); + } + + static void xen_enter_mmap(struct mm_struct *mm) +@@ -2199,10 +2251,6 @@ void __init xen_init_mmu_ops(void) + memset(dummy_mapping, 0xff, PAGE_SIZE); + } + +-/* Protected by xen_reservation_lock. */ +-#define MAX_CONTIG_ORDER 9 /* 2MB */ +-static unsigned long discontig_frames[1< MAX_CONTIG_ORDER)) +- return -ENOMEM; ++ if (unlikely(order > discontig_frames_order)) { ++ if (!discontig_frames_dyn) ++ return -ENOMEM; ++ ++ if (alloc_discontig_frames(order)) ++ return -ENOMEM; ++ } + + memset((void *) vstart, 0, PAGE_SIZE << order); + + spin_lock_irqsave(&xen_reservation_lock, flags); + ++ in_frames = discontig_frames; ++ + /* 1. Zap current PTEs, remembering MFNs. */ + xen_zap_pfn_range(vstart, order, in_frames, NULL); + +@@ -2354,12 +2409,12 @@ int xen_create_contiguous_region(phys_addr_t pstart, unsigned int order, + + void xen_destroy_contiguous_region(phys_addr_t pstart, unsigned int order) + { +- unsigned long *out_frames = discontig_frames, in_frame; ++ unsigned long *out_frames, in_frame; + unsigned long flags; + int success; + unsigned long vstart; + +- if (unlikely(order > MAX_CONTIG_ORDER)) ++ if (unlikely(order > discontig_frames_order)) + return; + + vstart = (unsigned long)phys_to_virt(pstart); +@@ -2367,6 +2422,8 @@ void xen_destroy_contiguous_region(phys_addr_t pstart, unsigned int order) + + spin_lock_irqsave(&xen_reservation_lock, flags); + ++ out_frames = discontig_frames; ++ + /* 1. Find start MFN of contiguous extent. */ + in_frame = virt_to_mfn((void *)vstart); + +diff --git a/block/partitions/mac.c b/block/partitions/mac.c +index 7b521df00a39f4..6415213cd184e7 100644 +--- a/block/partitions/mac.c ++++ b/block/partitions/mac.c +@@ -51,13 +51,25 @@ int mac_partition(struct parsed_partitions *state) + } + secsize = be16_to_cpu(md->block_size); + put_dev_sector(sect); ++ ++ /* ++ * If the "block size" is not a power of 2, things get weird - we might ++ * end up with a partition straddling a sector boundary, so we wouldn't ++ * be able to read a partition entry with read_part_sector(). ++ * Real block sizes are probably (?) powers of two, so just require ++ * that. ++ */ ++ if (!is_power_of_2(secsize)) ++ return -1; + datasize = round_down(secsize, 512); + data = read_part_sector(state, datasize / 512, §); + if (!data) + return -1; + partoffset = secsize % 512; +- if (partoffset + sizeof(*part) > datasize) ++ if (partoffset + sizeof(*part) > datasize) { ++ put_dev_sector(sect); + return -1; ++ } + part = (struct mac_partition *) (data + partoffset); + if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC) { + put_dev_sector(sect); +@@ -110,8 +122,8 @@ int mac_partition(struct parsed_partitions *state) + int i, l; + + goodness++; +- l = strlen(part->name); +- if (strcmp(part->name, "/") == 0) ++ l = strnlen(part->name, sizeof(part->name)); ++ if (strncmp(part->name, "/", sizeof(part->name)) == 0) + goodness++; + for (i = 0; i <= l - 4; ++i) { + if (strncasecmp(part->name + i, "root", +diff --git a/drivers/acpi/x86/utils.c b/drivers/acpi/x86/utils.c +index fdfc88e09986ec..e894fdf6d5531d 100644 +--- a/drivers/acpi/x86/utils.c ++++ b/drivers/acpi/x86/utils.c +@@ -400,6 +400,19 @@ static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = { + .driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS | + ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY), + }, ++ { ++ /* Vexia Edu Atla 10 tablet 5V version */ ++ .matches = { ++ /* Having all 3 of these not set is somewhat unique */ ++ DMI_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "To be filled by O.E.M."), ++ DMI_MATCH(DMI_BOARD_NAME, "To be filled by O.E.M."), ++ /* Above strings are too generic, also match on BIOS date */ ++ DMI_MATCH(DMI_BIOS_DATE, "05/14/2015"), ++ }, ++ .driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS | ++ ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY), ++ }, + { + /* Vexia Edu Atla 10 tablet 9V version */ + .matches = { +diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c +index dceab5d013dec9..d99c9fb666c2d3 100644 +--- a/drivers/base/regmap/regmap-irq.c ++++ b/drivers/base/regmap/regmap-irq.c +@@ -894,6 +894,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode, + kfree(d->wake_buf); + kfree(d->mask_buf_def); + kfree(d->mask_buf); ++ kfree(d->main_status_buf); + kfree(d->status_buf); + kfree(d->status_reg_buf); + if (d->config_buf) { +@@ -969,6 +970,7 @@ void regmap_del_irq_chip(int irq, struct regmap_irq_chip_data *d) + kfree(d->wake_buf); + kfree(d->mask_buf_def); + kfree(d->mask_buf); ++ kfree(d->main_status_buf); + kfree(d->status_reg_buf); + kfree(d->status_buf); + if (d->config_buf) { +diff --git a/drivers/clocksource/i8253.c b/drivers/clocksource/i8253.c +index d4350bb10b83a2..cb215e6f2e8344 100644 +--- a/drivers/clocksource/i8253.c ++++ b/drivers/clocksource/i8253.c +@@ -108,11 +108,8 @@ int __init clocksource_i8253_init(void) + #endif + + #ifdef CONFIG_CLKEVT_I8253 +-static int pit_shutdown(struct clock_event_device *evt) ++void clockevent_i8253_disable(void) + { +- if (!clockevent_state_oneshot(evt) && !clockevent_state_periodic(evt)) +- return 0; +- + raw_spin_lock(&i8253_lock); + + outb_p(0x30, PIT_MODE); +@@ -123,6 +120,14 @@ static int pit_shutdown(struct clock_event_device *evt) + } + + raw_spin_unlock(&i8253_lock); ++} ++ ++static int pit_shutdown(struct clock_event_device *evt) ++{ ++ if (!clockevent_state_oneshot(evt) && !clockevent_state_periodic(evt)) ++ return 0; ++ ++ clockevent_i8253_disable(); + return 0; + } + +diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c +index 2c1095dcc2f2f8..1ab161e00c8679 100644 +--- a/drivers/firmware/efi/efi.c ++++ b/drivers/firmware/efi/efi.c +@@ -908,13 +908,15 @@ char * __init efi_md_typeattr_format(char *buf, size_t size, + EFI_MEMORY_WB | EFI_MEMORY_UCE | EFI_MEMORY_RO | + EFI_MEMORY_WP | EFI_MEMORY_RP | EFI_MEMORY_XP | + EFI_MEMORY_NV | EFI_MEMORY_SP | EFI_MEMORY_CPU_CRYPTO | +- EFI_MEMORY_RUNTIME | EFI_MEMORY_MORE_RELIABLE)) ++ EFI_MEMORY_MORE_RELIABLE | EFI_MEMORY_HOT_PLUGGABLE | ++ EFI_MEMORY_RUNTIME)) + snprintf(pos, size, "|attr=0x%016llx]", + (unsigned long long)attr); + else + snprintf(pos, size, +- "|%3s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]", ++ "|%3s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]", + attr & EFI_MEMORY_RUNTIME ? "RUN" : "", ++ attr & EFI_MEMORY_HOT_PLUGGABLE ? "HP" : "", + attr & EFI_MEMORY_MORE_RELIABLE ? "MR" : "", + attr & EFI_MEMORY_CPU_CRYPTO ? "CC" : "", + attr & EFI_MEMORY_SP ? "SP" : "", +diff --git a/drivers/firmware/efi/libstub/randomalloc.c b/drivers/firmware/efi/libstub/randomalloc.c +index c41e7b2091cdd1..8ad3efb9b1ff16 100644 +--- a/drivers/firmware/efi/libstub/randomalloc.c ++++ b/drivers/firmware/efi/libstub/randomalloc.c +@@ -25,6 +25,9 @@ static unsigned long get_entry_num_slots(efi_memory_desc_t *md, + if (md->type != EFI_CONVENTIONAL_MEMORY) + return 0; + ++ if (md->attribute & EFI_MEMORY_HOT_PLUGGABLE) ++ return 0; ++ + if (efi_soft_reserve_enabled() && + (md->attribute & EFI_MEMORY_SP)) + return 0; +diff --git a/drivers/firmware/efi/libstub/relocate.c b/drivers/firmware/efi/libstub/relocate.c +index bf6fbd5d22a1a5..713ee2de02cf3f 100644 +--- a/drivers/firmware/efi/libstub/relocate.c ++++ b/drivers/firmware/efi/libstub/relocate.c +@@ -53,6 +53,9 @@ efi_status_t efi_low_alloc_above(unsigned long size, unsigned long align, + if (desc->type != EFI_CONVENTIONAL_MEMORY) + continue; + ++ if (desc->attribute & EFI_MEMORY_HOT_PLUGGABLE) ++ continue; ++ + if (efi_soft_reserve_enabled() && + (desc->attribute & EFI_MEMORY_SP)) + continue; +diff --git a/drivers/gpio/gpio-bcm-kona.c b/drivers/gpio/gpio-bcm-kona.c +index 5321ef98f4427d..64908f1a5e7f9b 100644 +--- a/drivers/gpio/gpio-bcm-kona.c ++++ b/drivers/gpio/gpio-bcm-kona.c +@@ -69,6 +69,22 @@ struct bcm_kona_gpio { + struct bcm_kona_gpio_bank { + int id; + int irq; ++ /* ++ * Used to keep track of lock/unlock operations for each GPIO in the ++ * bank. ++ * ++ * All GPIOs are locked by default (see bcm_kona_gpio_reset), and the ++ * unlock count for all GPIOs is 0 by default. Each unlock increments ++ * the counter, and each lock decrements the counter. ++ * ++ * The lock function only locks the GPIO once its unlock counter is ++ * down to 0. This is necessary because the GPIO is unlocked in two ++ * places in this driver: once for requested GPIOs, and once for ++ * requested IRQs. Since it is possible for a GPIO to be requested ++ * as both a GPIO and an IRQ, we need to ensure that we don't lock it ++ * too early. ++ */ ++ u8 gpio_unlock_count[GPIO_PER_BANK]; + /* Used in the interrupt handler */ + struct bcm_kona_gpio *kona_gpio; + }; +@@ -86,14 +102,24 @@ static void bcm_kona_gpio_lock_gpio(struct bcm_kona_gpio *kona_gpio, + u32 val; + unsigned long flags; + int bank_id = GPIO_BANK(gpio); ++ int bit = GPIO_BIT(gpio); ++ struct bcm_kona_gpio_bank *bank = &kona_gpio->banks[bank_id]; + +- raw_spin_lock_irqsave(&kona_gpio->lock, flags); ++ if (bank->gpio_unlock_count[bit] == 0) { ++ dev_err(kona_gpio->gpio_chip.parent, ++ "Unbalanced locks for GPIO %u\n", gpio); ++ return; ++ } + +- val = readl(kona_gpio->reg_base + GPIO_PWD_STATUS(bank_id)); +- val |= BIT(gpio); +- bcm_kona_gpio_write_lock_regs(kona_gpio->reg_base, bank_id, val); ++ if (--bank->gpio_unlock_count[bit] == 0) { ++ raw_spin_lock_irqsave(&kona_gpio->lock, flags); + +- raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); ++ val = readl(kona_gpio->reg_base + GPIO_PWD_STATUS(bank_id)); ++ val |= BIT(bit); ++ bcm_kona_gpio_write_lock_regs(kona_gpio->reg_base, bank_id, val); ++ ++ raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); ++ } + } + + static void bcm_kona_gpio_unlock_gpio(struct bcm_kona_gpio *kona_gpio, +@@ -102,14 +128,20 @@ static void bcm_kona_gpio_unlock_gpio(struct bcm_kona_gpio *kona_gpio, + u32 val; + unsigned long flags; + int bank_id = GPIO_BANK(gpio); ++ int bit = GPIO_BIT(gpio); ++ struct bcm_kona_gpio_bank *bank = &kona_gpio->banks[bank_id]; + +- raw_spin_lock_irqsave(&kona_gpio->lock, flags); ++ if (bank->gpio_unlock_count[bit] == 0) { ++ raw_spin_lock_irqsave(&kona_gpio->lock, flags); + +- val = readl(kona_gpio->reg_base + GPIO_PWD_STATUS(bank_id)); +- val &= ~BIT(gpio); +- bcm_kona_gpio_write_lock_regs(kona_gpio->reg_base, bank_id, val); ++ val = readl(kona_gpio->reg_base + GPIO_PWD_STATUS(bank_id)); ++ val &= ~BIT(bit); ++ bcm_kona_gpio_write_lock_regs(kona_gpio->reg_base, bank_id, val); + +- raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); ++ raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); ++ } ++ ++ ++bank->gpio_unlock_count[bit]; + } + + static int bcm_kona_gpio_get_dir(struct gpio_chip *chip, unsigned gpio) +@@ -360,6 +392,7 @@ static void bcm_kona_gpio_irq_mask(struct irq_data *d) + + kona_gpio = irq_data_get_irq_chip_data(d); + reg_base = kona_gpio->reg_base; ++ + raw_spin_lock_irqsave(&kona_gpio->lock, flags); + + val = readl(reg_base + GPIO_INT_MASK(bank_id)); +@@ -382,6 +415,7 @@ static void bcm_kona_gpio_irq_unmask(struct irq_data *d) + + kona_gpio = irq_data_get_irq_chip_data(d); + reg_base = kona_gpio->reg_base; ++ + raw_spin_lock_irqsave(&kona_gpio->lock, flags); + + val = readl(reg_base + GPIO_INT_MSKCLR(bank_id)); +@@ -477,15 +511,26 @@ static void bcm_kona_gpio_irq_handler(struct irq_desc *desc) + static int bcm_kona_gpio_irq_reqres(struct irq_data *d) + { + struct bcm_kona_gpio *kona_gpio = irq_data_get_irq_chip_data(d); ++ unsigned int gpio = d->hwirq; + +- return gpiochip_reqres_irq(&kona_gpio->gpio_chip, d->hwirq); ++ /* ++ * We need to unlock the GPIO before any other operations are performed ++ * on the relevant GPIO configuration registers ++ */ ++ bcm_kona_gpio_unlock_gpio(kona_gpio, gpio); ++ ++ return gpiochip_reqres_irq(&kona_gpio->gpio_chip, gpio); + } + + static void bcm_kona_gpio_irq_relres(struct irq_data *d) + { + struct bcm_kona_gpio *kona_gpio = irq_data_get_irq_chip_data(d); ++ unsigned int gpio = d->hwirq; ++ ++ /* Once we no longer use it, lock the GPIO again */ ++ bcm_kona_gpio_lock_gpio(kona_gpio, gpio); + +- gpiochip_relres_irq(&kona_gpio->gpio_chip, d->hwirq); ++ gpiochip_relres_irq(&kona_gpio->gpio_chip, gpio); + } + + static struct irq_chip bcm_gpio_irq_chip = { +@@ -614,7 +659,7 @@ static int bcm_kona_gpio_probe(struct platform_device *pdev) + bank->irq = platform_get_irq(pdev, i); + bank->kona_gpio = kona_gpio; + if (bank->irq < 0) { +- dev_err(dev, "Couldn't get IRQ for bank %d", i); ++ dev_err(dev, "Couldn't get IRQ for bank %d\n", i); + ret = -ENOENT; + goto err_irq_domain; + } +diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c +index 27cc4da5356540..2731e97f2812ce 100644 +--- a/drivers/gpio/gpio-stmpe.c ++++ b/drivers/gpio/gpio-stmpe.c +@@ -191,7 +191,7 @@ static void stmpe_gpio_irq_sync_unlock(struct irq_data *d) + [REG_IE][CSB] = STMPE_IDX_IEGPIOR_CSB, + [REG_IE][MSB] = STMPE_IDX_IEGPIOR_MSB, + }; +- int i, j; ++ int ret, i, j; + + /* + * STMPE1600: to be able to get IRQ from pins, +@@ -199,8 +199,16 @@ static void stmpe_gpio_irq_sync_unlock(struct irq_data *d) + * GPSR or GPCR registers + */ + if (stmpe->partnum == STMPE1600) { +- stmpe_reg_read(stmpe, stmpe->regs[STMPE_IDX_GPMR_LSB]); +- stmpe_reg_read(stmpe, stmpe->regs[STMPE_IDX_GPMR_CSB]); ++ ret = stmpe_reg_read(stmpe, stmpe->regs[STMPE_IDX_GPMR_LSB]); ++ if (ret < 0) { ++ dev_err(stmpe->dev, "Failed to read GPMR_LSB: %d\n", ret); ++ goto err; ++ } ++ ret = stmpe_reg_read(stmpe, stmpe->regs[STMPE_IDX_GPMR_CSB]); ++ if (ret < 0) { ++ dev_err(stmpe->dev, "Failed to read GPMR_CSB: %d\n", ret); ++ goto err; ++ } + } + + for (i = 0; i < CACHE_NR_REGS; i++) { +@@ -222,6 +230,7 @@ static void stmpe_gpio_irq_sync_unlock(struct irq_data *d) + } + } + ++err: + mutex_unlock(&stmpe_gpio->irq_lock); + } + +diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c +index b366b4ca4c40e9..8ddd5e8341a05b 100644 +--- a/drivers/gpio/gpiolib-acpi.c ++++ b/drivers/gpio/gpiolib-acpi.c +@@ -1706,6 +1706,20 @@ static const struct dmi_system_id gpiolib_acpi_quirks[] __initconst = { + .ignore_wake = "PNP0C50:00@8", + }, + }, ++ { ++ /* ++ * Spurious wakeups from GPIO 11 ++ * Found in BIOS 1.04 ++ * https://gitlab.freedesktop.org/drm/amd/-/issues/3954 ++ */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Acer"), ++ DMI_MATCH(DMI_PRODUCT_FAMILY, "Acer Nitro V 14"), ++ }, ++ .driver_data = &(struct acpi_gpiolib_dmi_quirk) { ++ .ignore_interrupt = "AMDI0030:00@11", ++ }, ++ }, + {} /* Terminating entry */ + }; + +diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c +index 5c0016c77d2abe..efb592b6f6aa7a 100644 +--- a/drivers/gpio/gpiolib.c ++++ b/drivers/gpio/gpiolib.c +@@ -723,13 +723,13 @@ int gpiochip_get_ngpios(struct gpio_chip *gc, struct device *dev) + } + + if (gc->ngpio == 0) { +- chip_err(gc, "tried to insert a GPIO chip with zero lines\n"); ++ dev_err(dev, "tried to insert a GPIO chip with zero lines\n"); + return -EINVAL; + } + + if (gc->ngpio > FASTPATH_NGPIO) +- chip_warn(gc, "line cnt %u is greater than fast path cnt %u\n", +- gc->ngpio, FASTPATH_NGPIO); ++ dev_warn(dev, "line cnt %u is greater than fast path cnt %u\n", ++ gc->ngpio, FASTPATH_NGPIO); + + return 0; + } +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +index a4f9015345ccb5..6a24e8ceb94493 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +@@ -3450,9 +3450,10 @@ int psp_init_cap_microcode(struct psp_context *psp, const char *chip_name) + if (err == -ENODEV) { + dev_warn(adev->dev, "cap microcode does not exist, skip\n"); + err = 0; +- goto out; ++ } else { ++ dev_err(adev->dev, "fail to initialize cap microcode\n"); + } +- dev_err(adev->dev, "fail to initialize cap microcode\n"); ++ goto out; + } + + info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CAP]; +diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +index d587f807dfd7c4..294609557b73ab 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +@@ -2026,6 +2026,7 @@ bool dcn20_fast_validate_bw( + { + bool out = false; + int split[MAX_PIPES] = { 0 }; ++ bool merge[MAX_PIPES] = { false }; + int pipe_cnt, i, pipe_idx, vlevel; + + ASSERT(pipes); +@@ -2050,7 +2051,7 @@ bool dcn20_fast_validate_bw( + if (vlevel > context->bw_ctx.dml.soc.num_states) + goto validate_fail; + +- vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, vlevel, split, NULL); ++ vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, vlevel, split, merge); + + /*initialize pipe_just_split_from to invalid idx*/ + for (i = 0; i < MAX_PIPES; i++) +diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c +index 2dc4d2c1410b81..8efe3f32a0e79b 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c +@@ -1002,8 +1002,10 @@ static struct pipe_ctx *dcn201_acquire_free_pipe_for_layer( + struct pipe_ctx *head_pipe = resource_get_otg_master_for_stream(res_ctx, opp_head_pipe->stream); + struct pipe_ctx *idle_pipe = resource_find_free_secondary_pipe_legacy(res_ctx, pool, head_pipe); + +- if (!head_pipe) ++ if (!head_pipe) { + ASSERT(0); ++ return NULL; ++ } + + if (!idle_pipe) + return NULL; +diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +index 8dffa5b6426e1c..24105a5b9f2a59 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +@@ -800,6 +800,7 @@ bool dcn21_fast_validate_bw(struct dc *dc, + { + bool out = false; + int split[MAX_PIPES] = { 0 }; ++ bool merge[MAX_PIPES] = { false }; + int pipe_cnt, i, pipe_idx, vlevel; + + ASSERT(pipes); +@@ -842,7 +843,7 @@ bool dcn21_fast_validate_bw(struct dc *dc, + goto validate_fail; + } + +- vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, vlevel, split, NULL); ++ vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, vlevel, split, merge); + + for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) { + struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; +diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +index 4d17b6958397ed..2997aeed634084 100644 +--- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +@@ -517,7 +517,8 @@ static int smu_sys_set_pp_table(void *handle, + return -EIO; + } + +- if (!smu_table->hardcode_pptable) { ++ if (!smu_table->hardcode_pptable || smu_table->power_play_table_size < size) { ++ kfree(smu_table->hardcode_pptable); + smu_table->hardcode_pptable = kzalloc(size, GFP_KERNEL); + if (!smu_table->hardcode_pptable) + return -ENOMEM; +diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c +index 5c397a2df70e28..5d27e1c733c527 100644 +--- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c ++++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c +@@ -168,7 +168,7 @@ static int igt_ppgtt_alloc(void *arg) + return PTR_ERR(ppgtt); + + if (!ppgtt->vm.allocate_va_range) +- goto err_ppgtt_cleanup; ++ goto ppgtt_vm_put; + + /* + * While we only allocate the page tables here and so we could +@@ -236,7 +236,7 @@ static int igt_ppgtt_alloc(void *arg) + goto retry; + } + i915_gem_ww_ctx_fini(&ww); +- ++ppgtt_vm_put: + i915_vm_put(&ppgtt->vm); + return err; + } +diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c +index 2dba7c5ffd2c62..92f4261305bd9d 100644 +--- a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c ++++ b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c +@@ -587,7 +587,7 @@ static int rcar_mipi_dsi_startup(struct rcar_mipi_dsi *dsi, + for (timeout = 10; timeout > 0; --timeout) { + if ((rcar_mipi_dsi_read(dsi, PPICLSR) & PPICLSR_STPST) && + (rcar_mipi_dsi_read(dsi, PPIDLSR) & PPIDLSR_STPST) && +- (rcar_mipi_dsi_read(dsi, CLOCKSET1) & CLOCKSET1_LOCK)) ++ (rcar_mipi_dsi_read(dsi, CLOCKSET1) & CLOCKSET1_LOCK_PHY)) + break; + + usleep_range(1000, 2000); +diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h +index f8114d11f2d158..a6b276f1d6ee15 100644 +--- a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h ++++ b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h +@@ -142,7 +142,6 @@ + + #define CLOCKSET1 0x101c + #define CLOCKSET1_LOCK_PHY (1 << 17) +-#define CLOCKSET1_LOCK (1 << 16) + #define CLOCKSET1_CLKSEL (1 << 8) + #define CLOCKSET1_CLKINSEL_EXTAL (0 << 2) + #define CLOCKSET1_CLKINSEL_DIG (1 << 2) +diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/tidss_dispc.c +index 98efbaf3b0c23f..ee3531bbccd7df 100644 +--- a/drivers/gpu/drm/tidss/tidss_dispc.c ++++ b/drivers/gpu/drm/tidss/tidss_dispc.c +@@ -646,7 +646,7 @@ void dispc_k2g_set_irqenable(struct dispc_device *dispc, dispc_irq_t mask) + { + dispc_irq_t old_mask = dispc_k2g_read_irqenable(dispc); + +- /* clear the irqstatus for newly enabled irqs */ ++ /* clear the irqstatus for irqs that will be enabled */ + dispc_k2g_clear_irqstatus(dispc, (mask ^ old_mask) & mask); + + dispc_k2g_vp_set_irqenable(dispc, 0, mask); +@@ -654,6 +654,9 @@ void dispc_k2g_set_irqenable(struct dispc_device *dispc, dispc_irq_t mask) + + dispc_write(dispc, DISPC_IRQENABLE_SET, (1 << 0) | (1 << 7)); + ++ /* clear the irqstatus for irqs that were disabled */ ++ dispc_k2g_clear_irqstatus(dispc, (mask ^ old_mask) & old_mask); ++ + /* flush posted write */ + dispc_k2g_read_irqenable(dispc); + } +@@ -726,24 +729,20 @@ static + void dispc_k3_clear_irqstatus(struct dispc_device *dispc, dispc_irq_t clearmask) + { + unsigned int i; +- u32 top_clear = 0; + + for (i = 0; i < dispc->feat->num_vps; ++i) { +- if (clearmask & DSS_IRQ_VP_MASK(i)) { ++ if (clearmask & DSS_IRQ_VP_MASK(i)) + dispc_k3_vp_write_irqstatus(dispc, i, clearmask); +- top_clear |= BIT(i); +- } + } + for (i = 0; i < dispc->feat->num_planes; ++i) { +- if (clearmask & DSS_IRQ_PLANE_MASK(i)) { ++ if (clearmask & DSS_IRQ_PLANE_MASK(i)) + dispc_k3_vid_write_irqstatus(dispc, i, clearmask); +- top_clear |= BIT(4 + i); +- } + } + if (dispc->feat->subrev == DISPC_K2G) + return; + +- dispc_write(dispc, DISPC_IRQSTATUS, top_clear); ++ /* always clear the top level irqstatus */ ++ dispc_write(dispc, DISPC_IRQSTATUS, dispc_read(dispc, DISPC_IRQSTATUS)); + + /* Flush posted writes */ + dispc_read(dispc, DISPC_IRQSTATUS); +@@ -789,7 +788,7 @@ static void dispc_k3_set_irqenable(struct dispc_device *dispc, + + old_mask = dispc_k3_read_irqenable(dispc); + +- /* clear the irqstatus for newly enabled irqs */ ++ /* clear the irqstatus for irqs that will be enabled */ + dispc_k3_clear_irqstatus(dispc, (old_mask ^ mask) & mask); + + for (i = 0; i < dispc->feat->num_vps; ++i) { +@@ -814,6 +813,9 @@ static void dispc_k3_set_irqenable(struct dispc_device *dispc, + if (main_disable) + dispc_write(dispc, DISPC_IRQENABLE_CLR, main_disable); + ++ /* clear the irqstatus for irqs that were disabled */ ++ dispc_k3_clear_irqstatus(dispc, (old_mask ^ mask) & old_mask); ++ + /* Flush posted writes */ + dispc_read(dispc, DISPC_IRQENABLE_SET); + } +diff --git a/drivers/gpu/drm/v3d/v3d_perfmon.c b/drivers/gpu/drm/v3d/v3d_perfmon.c +index 141b8abf08629f..e56b5935f2f1c1 100644 +--- a/drivers/gpu/drm/v3d/v3d_perfmon.c ++++ b/drivers/gpu/drm/v3d/v3d_perfmon.c +@@ -179,6 +179,7 @@ int v3d_perfmon_destroy_ioctl(struct drm_device *dev, void *data, + { + struct v3d_file_priv *v3d_priv = file_priv->driver_priv; + struct drm_v3d_perfmon_destroy *req = data; ++ struct v3d_dev *v3d = v3d_priv->v3d; + struct v3d_perfmon *perfmon; + + mutex_lock(&v3d_priv->perfmon.lock); +@@ -188,6 +189,10 @@ int v3d_perfmon_destroy_ioctl(struct drm_device *dev, void *data, + if (!perfmon) + return -EINVAL; + ++ /* If the active perfmon is being destroyed, stop it first */ ++ if (perfmon == v3d->active_perfmon) ++ v3d_perfmon_stop(v3d, perfmon, false); ++ + v3d_perfmon_put(perfmon); + + return 0; +diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c +index 5ad871a7d1a44c..6386043aab0bbf 100644 +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -1668,9 +1668,12 @@ static int mt_input_configured(struct hid_device *hdev, struct hid_input *hi) + break; + } + +- if (suffix) ++ if (suffix) { + hi->input->name = devm_kasprintf(&hdev->dev, GFP_KERNEL, + "%s %s", hdev->name, suffix); ++ if (!hi->input->name) ++ return -ENOMEM; ++ } + + return 0; + } +diff --git a/drivers/hid/hid-steam.c b/drivers/hid/hid-steam.c +index b110818fc94586..49c067133975f7 100644 +--- a/drivers/hid/hid-steam.c ++++ b/drivers/hid/hid-steam.c +@@ -66,55 +66,225 @@ static LIST_HEAD(steam_devices); + #define STEAM_DECK_TRIGGER_RESOLUTION 5461 + /* Joystick runs are about 5 mm and 32768 units */ + #define STEAM_DECK_JOYSTICK_RESOLUTION 6553 ++/* Accelerometer has 16 bit resolution and a range of +/- 2g */ ++#define STEAM_DECK_ACCEL_RES_PER_G 16384 ++#define STEAM_DECK_ACCEL_RANGE 32768 ++#define STEAM_DECK_ACCEL_FUZZ 32 ++/* Gyroscope has 16 bit resolution and a range of +/- 2000 dps */ ++#define STEAM_DECK_GYRO_RES_PER_DPS 16 ++#define STEAM_DECK_GYRO_RANGE 32768 ++#define STEAM_DECK_GYRO_FUZZ 1 + + #define STEAM_PAD_FUZZ 256 + + /* + * Commands that can be sent in a feature report. +- * Thanks to Valve for some valuable hints. ++ * Thanks to Valve and SDL for the names. + */ +-#define STEAM_CMD_SET_MAPPINGS 0x80 +-#define STEAM_CMD_CLEAR_MAPPINGS 0x81 +-#define STEAM_CMD_GET_MAPPINGS 0x82 +-#define STEAM_CMD_GET_ATTRIB 0x83 +-#define STEAM_CMD_GET_ATTRIB_LABEL 0x84 +-#define STEAM_CMD_DEFAULT_MAPPINGS 0x85 +-#define STEAM_CMD_FACTORY_RESET 0x86 +-#define STEAM_CMD_WRITE_REGISTER 0x87 +-#define STEAM_CMD_CLEAR_REGISTER 0x88 +-#define STEAM_CMD_READ_REGISTER 0x89 +-#define STEAM_CMD_GET_REGISTER_LABEL 0x8a +-#define STEAM_CMD_GET_REGISTER_MAX 0x8b +-#define STEAM_CMD_GET_REGISTER_DEFAULT 0x8c +-#define STEAM_CMD_SET_MODE 0x8d +-#define STEAM_CMD_DEFAULT_MOUSE 0x8e +-#define STEAM_CMD_FORCEFEEDBAK 0x8f +-#define STEAM_CMD_REQUEST_COMM_STATUS 0xb4 +-#define STEAM_CMD_GET_SERIAL 0xae +-#define STEAM_CMD_HAPTIC_RUMBLE 0xeb +- +-/* Some useful register ids */ +-#define STEAM_REG_LPAD_MODE 0x07 +-#define STEAM_REG_RPAD_MODE 0x08 +-#define STEAM_REG_RPAD_MARGIN 0x18 +-#define STEAM_REG_LED 0x2d +-#define STEAM_REG_GYRO_MODE 0x30 +-#define STEAM_REG_LPAD_CLICK_PRESSURE 0x34 +-#define STEAM_REG_RPAD_CLICK_PRESSURE 0x35 +- +-/* Raw event identifiers */ +-#define STEAM_EV_INPUT_DATA 0x01 +-#define STEAM_EV_CONNECT 0x03 +-#define STEAM_EV_BATTERY 0x04 +-#define STEAM_EV_DECK_INPUT_DATA 0x09 ++enum { ++ ID_SET_DIGITAL_MAPPINGS = 0x80, ++ ID_CLEAR_DIGITAL_MAPPINGS = 0x81, ++ ID_GET_DIGITAL_MAPPINGS = 0x82, ++ ID_GET_ATTRIBUTES_VALUES = 0x83, ++ ID_GET_ATTRIBUTE_LABEL = 0x84, ++ ID_SET_DEFAULT_DIGITAL_MAPPINGS = 0x85, ++ ID_FACTORY_RESET = 0x86, ++ ID_SET_SETTINGS_VALUES = 0x87, ++ ID_CLEAR_SETTINGS_VALUES = 0x88, ++ ID_GET_SETTINGS_VALUES = 0x89, ++ ID_GET_SETTING_LABEL = 0x8A, ++ ID_GET_SETTINGS_MAXS = 0x8B, ++ ID_GET_SETTINGS_DEFAULTS = 0x8C, ++ ID_SET_CONTROLLER_MODE = 0x8D, ++ ID_LOAD_DEFAULT_SETTINGS = 0x8E, ++ ID_TRIGGER_HAPTIC_PULSE = 0x8F, ++ ID_TURN_OFF_CONTROLLER = 0x9F, ++ ++ ID_GET_DEVICE_INFO = 0xA1, ++ ++ ID_CALIBRATE_TRACKPADS = 0xA7, ++ ID_RESERVED_0 = 0xA8, ++ ID_SET_SERIAL_NUMBER = 0xA9, ++ ID_GET_TRACKPAD_CALIBRATION = 0xAA, ++ ID_GET_TRACKPAD_FACTORY_CALIBRATION = 0xAB, ++ ID_GET_TRACKPAD_RAW_DATA = 0xAC, ++ ID_ENABLE_PAIRING = 0xAD, ++ ID_GET_STRING_ATTRIBUTE = 0xAE, ++ ID_RADIO_ERASE_RECORDS = 0xAF, ++ ID_RADIO_WRITE_RECORD = 0xB0, ++ ID_SET_DONGLE_SETTING = 0xB1, ++ ID_DONGLE_DISCONNECT_DEVICE = 0xB2, ++ ID_DONGLE_COMMIT_DEVICE = 0xB3, ++ ID_DONGLE_GET_WIRELESS_STATE = 0xB4, ++ ID_CALIBRATE_GYRO = 0xB5, ++ ID_PLAY_AUDIO = 0xB6, ++ ID_AUDIO_UPDATE_START = 0xB7, ++ ID_AUDIO_UPDATE_DATA = 0xB8, ++ ID_AUDIO_UPDATE_COMPLETE = 0xB9, ++ ID_GET_CHIPID = 0xBA, ++ ++ ID_CALIBRATE_JOYSTICK = 0xBF, ++ ID_CALIBRATE_ANALOG_TRIGGERS = 0xC0, ++ ID_SET_AUDIO_MAPPING = 0xC1, ++ ID_CHECK_GYRO_FW_LOAD = 0xC2, ++ ID_CALIBRATE_ANALOG = 0xC3, ++ ID_DONGLE_GET_CONNECTED_SLOTS = 0xC4, ++ ++ ID_RESET_IMU = 0xCE, ++ ++ ID_TRIGGER_HAPTIC_CMD = 0xEA, ++ ID_TRIGGER_RUMBLE_CMD = 0xEB, ++}; ++ ++/* Settings IDs */ ++enum { ++ /* 0 */ ++ SETTING_MOUSE_SENSITIVITY, ++ SETTING_MOUSE_ACCELERATION, ++ SETTING_TRACKBALL_ROTATION_ANGLE, ++ SETTING_HAPTIC_INTENSITY_UNUSED, ++ SETTING_LEFT_GAMEPAD_STICK_ENABLED, ++ SETTING_RIGHT_GAMEPAD_STICK_ENABLED, ++ SETTING_USB_DEBUG_MODE, ++ SETTING_LEFT_TRACKPAD_MODE, ++ SETTING_RIGHT_TRACKPAD_MODE, ++ SETTING_MOUSE_POINTER_ENABLED, ++ ++ /* 10 */ ++ SETTING_DPAD_DEADZONE, ++ SETTING_MINIMUM_MOMENTUM_VEL, ++ SETTING_MOMENTUM_DECAY_AMMOUNT, ++ SETTING_TRACKPAD_RELATIVE_MODE_TICKS_PER_PIXEL, ++ SETTING_HAPTIC_INCREMENT, ++ SETTING_DPAD_ANGLE_SIN, ++ SETTING_DPAD_ANGLE_COS, ++ SETTING_MOMENTUM_VERTICAL_DIVISOR, ++ SETTING_MOMENTUM_MAXIMUM_VELOCITY, ++ SETTING_TRACKPAD_Z_ON, ++ ++ /* 20 */ ++ SETTING_TRACKPAD_Z_OFF, ++ SETTING_SENSITIVY_SCALE_AMMOUNT, ++ SETTING_LEFT_TRACKPAD_SECONDARY_MODE, ++ SETTING_RIGHT_TRACKPAD_SECONDARY_MODE, ++ SETTING_SMOOTH_ABSOLUTE_MOUSE, ++ SETTING_STEAMBUTTON_POWEROFF_TIME, ++ SETTING_UNUSED_1, ++ SETTING_TRACKPAD_OUTER_RADIUS, ++ SETTING_TRACKPAD_Z_ON_LEFT, ++ SETTING_TRACKPAD_Z_OFF_LEFT, ++ ++ /* 30 */ ++ SETTING_TRACKPAD_OUTER_SPIN_VEL, ++ SETTING_TRACKPAD_OUTER_SPIN_RADIUS, ++ SETTING_TRACKPAD_OUTER_SPIN_HORIZONTAL_ONLY, ++ SETTING_TRACKPAD_RELATIVE_MODE_DEADZONE, ++ SETTING_TRACKPAD_RELATIVE_MODE_MAX_VEL, ++ SETTING_TRACKPAD_RELATIVE_MODE_INVERT_Y, ++ SETTING_TRACKPAD_DOUBLE_TAP_BEEP_ENABLED, ++ SETTING_TRACKPAD_DOUBLE_TAP_BEEP_PERIOD, ++ SETTING_TRACKPAD_DOUBLE_TAP_BEEP_COUNT, ++ SETTING_TRACKPAD_OUTER_RADIUS_RELEASE_ON_TRANSITION, ++ ++ /* 40 */ ++ SETTING_RADIAL_MODE_ANGLE, ++ SETTING_HAPTIC_INTENSITY_MOUSE_MODE, ++ SETTING_LEFT_DPAD_REQUIRES_CLICK, ++ SETTING_RIGHT_DPAD_REQUIRES_CLICK, ++ SETTING_LED_BASELINE_BRIGHTNESS, ++ SETTING_LED_USER_BRIGHTNESS, ++ SETTING_ENABLE_RAW_JOYSTICK, ++ SETTING_ENABLE_FAST_SCAN, ++ SETTING_IMU_MODE, ++ SETTING_WIRELESS_PACKET_VERSION, ++ ++ /* 50 */ ++ SETTING_SLEEP_INACTIVITY_TIMEOUT, ++ SETTING_TRACKPAD_NOISE_THRESHOLD, ++ SETTING_LEFT_TRACKPAD_CLICK_PRESSURE, ++ SETTING_RIGHT_TRACKPAD_CLICK_PRESSURE, ++ SETTING_LEFT_BUMPER_CLICK_PRESSURE, ++ SETTING_RIGHT_BUMPER_CLICK_PRESSURE, ++ SETTING_LEFT_GRIP_CLICK_PRESSURE, ++ SETTING_RIGHT_GRIP_CLICK_PRESSURE, ++ SETTING_LEFT_GRIP2_CLICK_PRESSURE, ++ SETTING_RIGHT_GRIP2_CLICK_PRESSURE, ++ ++ /* 60 */ ++ SETTING_PRESSURE_MODE, ++ SETTING_CONTROLLER_TEST_MODE, ++ SETTING_TRIGGER_MODE, ++ SETTING_TRACKPAD_Z_THRESHOLD, ++ SETTING_FRAME_RATE, ++ SETTING_TRACKPAD_FILT_CTRL, ++ SETTING_TRACKPAD_CLIP, ++ SETTING_DEBUG_OUTPUT_SELECT, ++ SETTING_TRIGGER_THRESHOLD_PERCENT, ++ SETTING_TRACKPAD_FREQUENCY_HOPPING, ++ ++ /* 70 */ ++ SETTING_HAPTICS_ENABLED, ++ SETTING_STEAM_WATCHDOG_ENABLE, ++ SETTING_TIMP_TOUCH_THRESHOLD_ON, ++ SETTING_TIMP_TOUCH_THRESHOLD_OFF, ++ SETTING_FREQ_HOPPING, ++ SETTING_TEST_CONTROL, ++ SETTING_HAPTIC_MASTER_GAIN_DB, ++ SETTING_THUMB_TOUCH_THRESH, ++ SETTING_DEVICE_POWER_STATUS, ++ SETTING_HAPTIC_INTENSITY, ++ ++ /* 80 */ ++ SETTING_STABILIZER_ENABLED, ++ SETTING_TIMP_MODE_MTE, ++}; ++ ++/* Input report identifiers */ ++enum ++{ ++ ID_CONTROLLER_STATE = 1, ++ ID_CONTROLLER_DEBUG = 2, ++ ID_CONTROLLER_WIRELESS = 3, ++ ID_CONTROLLER_STATUS = 4, ++ ID_CONTROLLER_DEBUG2 = 5, ++ ID_CONTROLLER_SECONDARY_STATE = 6, ++ ID_CONTROLLER_BLE_STATE = 7, ++ ID_CONTROLLER_DECK_STATE = 9 ++}; ++ ++/* String attribute idenitifiers */ ++enum { ++ ATTRIB_STR_BOARD_SERIAL, ++ ATTRIB_STR_UNIT_SERIAL, ++}; + + /* Values for GYRO_MODE (bitmask) */ +-#define STEAM_GYRO_MODE_OFF 0x0000 +-#define STEAM_GYRO_MODE_STEERING 0x0001 +-#define STEAM_GYRO_MODE_TILT 0x0002 +-#define STEAM_GYRO_MODE_SEND_ORIENTATION 0x0004 +-#define STEAM_GYRO_MODE_SEND_RAW_ACCEL 0x0008 +-#define STEAM_GYRO_MODE_SEND_RAW_GYRO 0x0010 ++enum { ++ SETTING_GYRO_MODE_OFF = 0, ++ SETTING_GYRO_MODE_STEERING = BIT(0), ++ SETTING_GYRO_MODE_TILT = BIT(1), ++ SETTING_GYRO_MODE_SEND_ORIENTATION = BIT(2), ++ SETTING_GYRO_MODE_SEND_RAW_ACCEL = BIT(3), ++ SETTING_GYRO_MODE_SEND_RAW_GYRO = BIT(4), ++}; ++ ++/* Trackpad modes */ ++enum { ++ TRACKPAD_ABSOLUTE_MOUSE, ++ TRACKPAD_RELATIVE_MOUSE, ++ TRACKPAD_DPAD_FOUR_WAY_DISCRETE, ++ TRACKPAD_DPAD_FOUR_WAY_OVERLAP, ++ TRACKPAD_DPAD_EIGHT_WAY, ++ TRACKPAD_RADIAL_MODE, ++ TRACKPAD_ABSOLUTE_DPAD, ++ TRACKPAD_NONE, ++ TRACKPAD_GESTURE_KEYBOARD, ++}; ++ ++/* Pad identifiers for the deck */ ++#define STEAM_PAD_LEFT 0 ++#define STEAM_PAD_RIGHT 1 ++#define STEAM_PAD_BOTH 2 + + /* Other random constants */ + #define STEAM_SERIAL_LEN 10 +@@ -123,9 +293,10 @@ struct steam_device { + struct list_head list; + spinlock_t lock; + struct hid_device *hdev, *client_hdev; +- struct mutex mutex; ++ struct mutex report_mutex; + bool client_opened; + struct input_dev __rcu *input; ++ struct input_dev __rcu *sensors; + unsigned long quirks; + struct work_struct work_connect; + bool connected; +@@ -134,10 +305,14 @@ struct steam_device { + struct power_supply __rcu *battery; + u8 battery_charge; + u16 voltage; +- struct delayed_work heartbeat; ++ struct delayed_work mode_switch; ++ bool did_mode_switch; ++ bool gamepad_mode; + struct work_struct rumble_work; + u16 rumble_left; + u16 rumble_right; ++ unsigned int sensor_timestamp_us; ++ struct work_struct unregister_work; + }; + + static int steam_recv_report(struct steam_device *steam, +@@ -226,13 +401,13 @@ static inline int steam_send_report_byte(struct steam_device *steam, u8 cmd) + return steam_send_report(steam, &cmd, 1); + } + +-static int steam_write_registers(struct steam_device *steam, ++static int steam_write_settings(struct steam_device *steam, + /* u8 reg, u16 val */...) + { + /* Send: 0x87 len (reg valLo valHi)* */ + u8 reg; + u16 val; +- u8 cmd[64] = {STEAM_CMD_WRITE_REGISTER, 0x00}; ++ u8 cmd[64] = {ID_SET_SETTINGS_VALUES, 0x00}; + int ret; + va_list args; + +@@ -267,21 +442,26 @@ static int steam_get_serial(struct steam_device *steam) + * Send: 0xae 0x15 0x01 + * Recv: 0xae 0x15 0x01 serialnumber (10 chars) + */ +- int ret; +- u8 cmd[] = {STEAM_CMD_GET_SERIAL, 0x15, 0x01}; ++ int ret = 0; ++ u8 cmd[] = {ID_GET_STRING_ATTRIBUTE, 0x15, ATTRIB_STR_UNIT_SERIAL}; + u8 reply[3 + STEAM_SERIAL_LEN + 1]; + ++ mutex_lock(&steam->report_mutex); + ret = steam_send_report(steam, cmd, sizeof(cmd)); + if (ret < 0) +- return ret; ++ goto out; + ret = steam_recv_report(steam, reply, sizeof(reply)); + if (ret < 0) +- return ret; +- if (reply[0] != 0xae || reply[1] != 0x15 || reply[2] != 0x01) +- return -EIO; ++ goto out; ++ if (reply[0] != ID_GET_STRING_ATTRIBUTE || reply[1] != 0x15 || reply[2] != ATTRIB_STR_UNIT_SERIAL) { ++ ret = -EIO; ++ goto out; ++ } + reply[3 + STEAM_SERIAL_LEN] = 0; + strscpy(steam->serial_no, reply + 3, sizeof(steam->serial_no)); +- return 0; ++out: ++ mutex_unlock(&steam->report_mutex); ++ return ret; + } + + /* +@@ -291,14 +471,50 @@ static int steam_get_serial(struct steam_device *steam) + */ + static inline int steam_request_conn_status(struct steam_device *steam) + { +- return steam_send_report_byte(steam, STEAM_CMD_REQUEST_COMM_STATUS); ++ int ret; ++ mutex_lock(&steam->report_mutex); ++ ret = steam_send_report_byte(steam, ID_DONGLE_GET_WIRELESS_STATE); ++ mutex_unlock(&steam->report_mutex); ++ return ret; ++} ++ ++/* ++ * Send a haptic pulse to the trackpads ++ * Duration and interval are measured in microseconds, count is the number ++ * of pulses to send for duration time with interval microseconds between them ++ * and gain is measured in decibels, ranging from -24 to +6 ++ */ ++static inline int steam_haptic_pulse(struct steam_device *steam, u8 pad, ++ u16 duration, u16 interval, u16 count, u8 gain) ++{ ++ int ret; ++ u8 report[10] = {ID_TRIGGER_HAPTIC_PULSE, 8}; ++ ++ /* Left and right are swapped on this report for legacy reasons */ ++ if (pad < STEAM_PAD_BOTH) ++ pad ^= 1; ++ ++ report[2] = pad; ++ report[3] = duration & 0xFF; ++ report[4] = duration >> 8; ++ report[5] = interval & 0xFF; ++ report[6] = interval >> 8; ++ report[7] = count & 0xFF; ++ report[8] = count >> 8; ++ report[9] = gain; ++ ++ mutex_lock(&steam->report_mutex); ++ ret = steam_send_report(steam, report, sizeof(report)); ++ mutex_unlock(&steam->report_mutex); ++ return ret; + } + + static inline int steam_haptic_rumble(struct steam_device *steam, + u16 intensity, u16 left_speed, u16 right_speed, + u8 left_gain, u8 right_gain) + { +- u8 report[11] = {STEAM_CMD_HAPTIC_RUMBLE, 9}; ++ int ret; ++ u8 report[11] = {ID_TRIGGER_RUMBLE_CMD, 9}; + + report[3] = intensity & 0xFF; + report[4] = intensity >> 8; +@@ -309,7 +525,10 @@ static inline int steam_haptic_rumble(struct steam_device *steam, + report[9] = left_gain; + report[10] = right_gain; + +- return steam_send_report(steam, report, sizeof(report)); ++ mutex_lock(&steam->report_mutex); ++ ret = steam_send_report(steam, report, sizeof(report)); ++ mutex_unlock(&steam->report_mutex); ++ return ret; + } + + static void steam_haptic_rumble_cb(struct work_struct *work) +@@ -335,40 +554,36 @@ static int steam_play_effect(struct input_dev *dev, void *data, + + static void steam_set_lizard_mode(struct steam_device *steam, bool enable) + { ++ if (steam->gamepad_mode) ++ enable = false; ++ + if (enable) { ++ mutex_lock(&steam->report_mutex); + /* enable esc, enter, cursors */ +- steam_send_report_byte(steam, STEAM_CMD_DEFAULT_MAPPINGS); +- /* enable mouse */ +- steam_send_report_byte(steam, STEAM_CMD_DEFAULT_MOUSE); +- steam_write_registers(steam, +- STEAM_REG_RPAD_MARGIN, 0x01, /* enable margin */ +- 0); +- +- cancel_delayed_work_sync(&steam->heartbeat); ++ steam_send_report_byte(steam, ID_SET_DEFAULT_DIGITAL_MAPPINGS); ++ /* reset settings */ ++ steam_send_report_byte(steam, ID_LOAD_DEFAULT_SETTINGS); ++ mutex_unlock(&steam->report_mutex); + } else { ++ mutex_lock(&steam->report_mutex); + /* disable esc, enter, cursor */ +- steam_send_report_byte(steam, STEAM_CMD_CLEAR_MAPPINGS); ++ steam_send_report_byte(steam, ID_CLEAR_DIGITAL_MAPPINGS); + + if (steam->quirks & STEAM_QUIRK_DECK) { +- steam_write_registers(steam, +- STEAM_REG_RPAD_MARGIN, 0x00, /* disable margin */ +- STEAM_REG_LPAD_MODE, 0x07, /* disable mouse */ +- STEAM_REG_RPAD_MODE, 0x07, /* disable mouse */ +- STEAM_REG_LPAD_CLICK_PRESSURE, 0xFFFF, /* disable clicky pad */ +- STEAM_REG_RPAD_CLICK_PRESSURE, 0xFFFF, /* disable clicky pad */ ++ steam_write_settings(steam, ++ SETTING_LEFT_TRACKPAD_MODE, TRACKPAD_NONE, /* disable mouse */ ++ SETTING_RIGHT_TRACKPAD_MODE, TRACKPAD_NONE, /* disable mouse */ ++ SETTING_LEFT_TRACKPAD_CLICK_PRESSURE, 0xFFFF, /* disable haptic click */ ++ SETTING_RIGHT_TRACKPAD_CLICK_PRESSURE, 0xFFFF, /* disable haptic click */ ++ SETTING_STEAM_WATCHDOG_ENABLE, 0, /* disable watchdog that tests if Steam is active */ + 0); +- /* +- * The Steam Deck has a watchdog that automatically enables +- * lizard mode if it doesn't see any traffic for too long +- */ +- if (!work_busy(&steam->heartbeat.work)) +- schedule_delayed_work(&steam->heartbeat, 5 * HZ); ++ mutex_unlock(&steam->report_mutex); + } else { +- steam_write_registers(steam, +- STEAM_REG_RPAD_MARGIN, 0x00, /* disable margin */ +- STEAM_REG_LPAD_MODE, 0x07, /* disable mouse */ +- STEAM_REG_RPAD_MODE, 0x07, /* disable mouse */ ++ steam_write_settings(steam, ++ SETTING_LEFT_TRACKPAD_MODE, TRACKPAD_NONE, /* disable mouse */ ++ SETTING_RIGHT_TRACKPAD_MODE, TRACKPAD_NONE, /* disable mouse */ + 0); ++ mutex_unlock(&steam->report_mutex); + } + } + } +@@ -376,22 +591,38 @@ static void steam_set_lizard_mode(struct steam_device *steam, bool enable) + static int steam_input_open(struct input_dev *dev) + { + struct steam_device *steam = input_get_drvdata(dev); ++ unsigned long flags; ++ bool set_lizard_mode; ++ ++ /* ++ * Disabling lizard mode automatically is only done on the Steam ++ * Controller. On the Steam Deck, this is toggled manually by holding ++ * the options button instead, handled by steam_mode_switch_cb. ++ */ ++ if (!(steam->quirks & STEAM_QUIRK_DECK)) { ++ spin_lock_irqsave(&steam->lock, flags); ++ set_lizard_mode = !steam->client_opened && lizard_mode; ++ spin_unlock_irqrestore(&steam->lock, flags); ++ if (set_lizard_mode) ++ steam_set_lizard_mode(steam, false); ++ } + +- mutex_lock(&steam->mutex); +- if (!steam->client_opened && lizard_mode) +- steam_set_lizard_mode(steam, false); +- mutex_unlock(&steam->mutex); + return 0; + } + + static void steam_input_close(struct input_dev *dev) + { + struct steam_device *steam = input_get_drvdata(dev); ++ unsigned long flags; ++ bool set_lizard_mode; + +- mutex_lock(&steam->mutex); +- if (!steam->client_opened && lizard_mode) +- steam_set_lizard_mode(steam, true); +- mutex_unlock(&steam->mutex); ++ if (!(steam->quirks & STEAM_QUIRK_DECK)) { ++ spin_lock_irqsave(&steam->lock, flags); ++ set_lizard_mode = !steam->client_opened && lizard_mode; ++ spin_unlock_irqrestore(&steam->lock, flags); ++ if (set_lizard_mode) ++ steam_set_lizard_mode(steam, true); ++ } + } + + static enum power_supply_property steam_battery_props[] = { +@@ -604,6 +835,74 @@ static int steam_input_register(struct steam_device *steam) + return ret; + } + ++static int steam_sensors_register(struct steam_device *steam) ++{ ++ struct hid_device *hdev = steam->hdev; ++ struct input_dev *sensors; ++ int ret; ++ ++ if (!(steam->quirks & STEAM_QUIRK_DECK)) ++ return 0; ++ ++ rcu_read_lock(); ++ sensors = rcu_dereference(steam->sensors); ++ rcu_read_unlock(); ++ if (sensors) { ++ dbg_hid("%s: already connected\n", __func__); ++ return 0; ++ } ++ ++ sensors = input_allocate_device(); ++ if (!sensors) ++ return -ENOMEM; ++ ++ input_set_drvdata(sensors, steam); ++ sensors->dev.parent = &hdev->dev; ++ ++ sensors->name = "Steam Deck Motion Sensors"; ++ sensors->phys = hdev->phys; ++ sensors->uniq = steam->serial_no; ++ sensors->id.bustype = hdev->bus; ++ sensors->id.vendor = hdev->vendor; ++ sensors->id.product = hdev->product; ++ sensors->id.version = hdev->version; ++ ++ __set_bit(INPUT_PROP_ACCELEROMETER, sensors->propbit); ++ __set_bit(EV_MSC, sensors->evbit); ++ __set_bit(MSC_TIMESTAMP, sensors->mscbit); ++ ++ input_set_abs_params(sensors, ABS_X, -STEAM_DECK_ACCEL_RANGE, ++ STEAM_DECK_ACCEL_RANGE, STEAM_DECK_ACCEL_FUZZ, 0); ++ input_set_abs_params(sensors, ABS_Y, -STEAM_DECK_ACCEL_RANGE, ++ STEAM_DECK_ACCEL_RANGE, STEAM_DECK_ACCEL_FUZZ, 0); ++ input_set_abs_params(sensors, ABS_Z, -STEAM_DECK_ACCEL_RANGE, ++ STEAM_DECK_ACCEL_RANGE, STEAM_DECK_ACCEL_FUZZ, 0); ++ input_abs_set_res(sensors, ABS_X, STEAM_DECK_ACCEL_RES_PER_G); ++ input_abs_set_res(sensors, ABS_Y, STEAM_DECK_ACCEL_RES_PER_G); ++ input_abs_set_res(sensors, ABS_Z, STEAM_DECK_ACCEL_RES_PER_G); ++ ++ input_set_abs_params(sensors, ABS_RX, -STEAM_DECK_GYRO_RANGE, ++ STEAM_DECK_GYRO_RANGE, STEAM_DECK_GYRO_FUZZ, 0); ++ input_set_abs_params(sensors, ABS_RY, -STEAM_DECK_GYRO_RANGE, ++ STEAM_DECK_GYRO_RANGE, STEAM_DECK_GYRO_FUZZ, 0); ++ input_set_abs_params(sensors, ABS_RZ, -STEAM_DECK_GYRO_RANGE, ++ STEAM_DECK_GYRO_RANGE, STEAM_DECK_GYRO_FUZZ, 0); ++ input_abs_set_res(sensors, ABS_RX, STEAM_DECK_GYRO_RES_PER_DPS); ++ input_abs_set_res(sensors, ABS_RY, STEAM_DECK_GYRO_RES_PER_DPS); ++ input_abs_set_res(sensors, ABS_RZ, STEAM_DECK_GYRO_RES_PER_DPS); ++ ++ ret = input_register_device(sensors); ++ if (ret) ++ goto sensors_register_fail; ++ ++ rcu_assign_pointer(steam->sensors, sensors); ++ return 0; ++ ++sensors_register_fail: ++ input_free_device(sensors); ++ return ret; ++} ++ + static void steam_input_unregister(struct steam_device *steam) + { + struct input_dev *input; +@@ -617,6 +916,24 @@ static void steam_input_unregister(struct steam_device *steam) + input_unregister_device(input); + } + ++static void steam_sensors_unregister(struct steam_device *steam) ++{ ++ struct input_dev *sensors; ++ ++ if (!(steam->quirks & STEAM_QUIRK_DECK)) ++ return; ++ ++ rcu_read_lock(); ++ sensors = rcu_dereference(steam->sensors); ++ rcu_read_unlock(); ++ ++ if (!sensors) ++ return; ++ RCU_INIT_POINTER(steam->sensors, NULL); ++ synchronize_rcu(); ++ input_unregister_device(sensors); ++} ++ + static void steam_battery_unregister(struct steam_device *steam) + { + struct power_supply *battery; +@@ -636,6 +953,7 @@ static int steam_register(struct steam_device *steam) + { + int ret; + bool client_opened; ++ unsigned long flags; + + /* + * This function can be called several times in a row with the +@@ -648,11 +966,9 @@ static int steam_register(struct steam_device *steam) + * Unlikely, but getting the serial could fail, and it is not so + * important, so make up a serial number and go on. + */ +- mutex_lock(&steam->mutex); + if (steam_get_serial(steam) < 0) + strscpy(steam->serial_no, "XXXXXXXXXX", + sizeof(steam->serial_no)); +- mutex_unlock(&steam->mutex); + + hid_info(steam->hdev, "Steam Controller '%s' connected", + steam->serial_no); +@@ -667,23 +983,31 @@ static int steam_register(struct steam_device *steam) + mutex_unlock(&steam_devices_lock); + } + +- mutex_lock(&steam->mutex); ++ spin_lock_irqsave(&steam->lock, flags); + client_opened = steam->client_opened; +- if (!client_opened) +- steam_set_lizard_mode(steam, lizard_mode); +- mutex_unlock(&steam->mutex); ++ spin_unlock_irqrestore(&steam->lock, flags); + +- if (!client_opened) ++ if (!client_opened) { ++ steam_set_lizard_mode(steam, lizard_mode); + ret = steam_input_register(steam); +- else +- ret = 0; ++ if (ret != 0) ++ goto steam_register_input_fail; ++ ret = steam_sensors_register(steam); ++ if (ret != 0) ++ goto steam_register_sensors_fail; ++ } ++ return 0; + ++steam_register_sensors_fail: ++ steam_input_unregister(steam); ++steam_register_input_fail: + return ret; + } + + static void steam_unregister(struct steam_device *steam) + { + steam_battery_unregister(steam); ++ steam_sensors_unregister(steam); + steam_input_unregister(steam); + if (steam->serial_no[0]) { + hid_info(steam->hdev, "Steam Controller '%s' disconnected", +@@ -719,6 +1043,59 @@ static void steam_work_connect_cb(struct work_struct *work) + } + } + ++static void steam_mode_switch_cb(struct work_struct *work) ++{ ++ struct steam_device *steam = container_of(to_delayed_work(work), ++ struct steam_device, mode_switch); ++ unsigned long flags; ++ bool client_opened; ++ steam->gamepad_mode = !steam->gamepad_mode; ++ if (!lizard_mode) ++ return; ++ ++ if (steam->gamepad_mode) ++ steam_set_lizard_mode(steam, false); ++ else { ++ spin_lock_irqsave(&steam->lock, flags); ++ client_opened = steam->client_opened; ++ spin_unlock_irqrestore(&steam->lock, flags); ++ if (!client_opened) ++ steam_set_lizard_mode(steam, lizard_mode); ++ } ++ ++ steam_haptic_pulse(steam, STEAM_PAD_RIGHT, 0x190, 0, 1, 0); ++ if (steam->gamepad_mode) { ++ steam_haptic_pulse(steam, STEAM_PAD_LEFT, 0x14D, 0x14D, 0x2D, 0); ++ } else { ++ steam_haptic_pulse(steam, STEAM_PAD_LEFT, 0x1F4, 0x1F4, 0x1E, 0); ++ } ++} ++ ++static void steam_work_unregister_cb(struct work_struct *work) ++{ ++ struct steam_device *steam = container_of(work, struct steam_device, ++ unregister_work); ++ unsigned long flags; ++ bool connected; ++ bool opened; ++ ++ spin_lock_irqsave(&steam->lock, flags); ++ opened = steam->client_opened; ++ connected = steam->connected; ++ spin_unlock_irqrestore(&steam->lock, flags); ++ ++ if (connected) { ++ if (opened) { ++ steam_sensors_unregister(steam); ++ steam_input_unregister(steam); ++ } else { ++ steam_set_lizard_mode(steam, lizard_mode); ++ steam_input_register(steam); ++ steam_sensors_register(steam); ++ } ++ } ++} ++ + static bool steam_is_valve_interface(struct hid_device *hdev) + { + struct hid_report_enum *rep_enum; +@@ -738,22 +1115,6 @@ static bool steam_is_valve_interface(struct hid_device *hdev) + return !list_empty(&rep_enum->report_list); + } + +-static void steam_lizard_mode_heartbeat(struct work_struct *work) +-{ +- struct steam_device *steam = container_of(work, struct steam_device, +- heartbeat.work); +- +- mutex_lock(&steam->mutex); +- if (!steam->client_opened && steam->client_hdev) { +- steam_send_report_byte(steam, STEAM_CMD_CLEAR_MAPPINGS); +- steam_write_registers(steam, +- STEAM_REG_RPAD_MODE, 0x07, /* disable mouse */ +- 0); +- schedule_delayed_work(&steam->heartbeat, 5 * HZ); +- } +- mutex_unlock(&steam->mutex); +-} +- + static int steam_client_ll_parse(struct hid_device *hdev) + { + struct steam_device *steam = hdev->driver_data; +@@ -774,12 +1135,13 @@ static void steam_client_ll_stop(struct hid_device *hdev) + static int steam_client_ll_open(struct hid_device *hdev) + { + struct steam_device *steam = hdev->driver_data; ++ unsigned long flags; + +- mutex_lock(&steam->mutex); ++ spin_lock_irqsave(&steam->lock, flags); + steam->client_opened = true; +- mutex_unlock(&steam->mutex); ++ spin_unlock_irqrestore(&steam->lock, flags); + +- steam_input_unregister(steam); ++ schedule_work(&steam->unregister_work); + + return 0; + } +@@ -792,17 +1154,11 @@ static void steam_client_ll_close(struct hid_device *hdev) + bool connected; + + spin_lock_irqsave(&steam->lock, flags); +- connected = steam->connected; +- spin_unlock_irqrestore(&steam->lock, flags); +- +- mutex_lock(&steam->mutex); + steam->client_opened = false; +- if (connected) +- steam_set_lizard_mode(steam, lizard_mode); +- mutex_unlock(&steam->mutex); ++ connected = steam->connected && !steam->client_opened; ++ spin_unlock_irqrestore(&steam->lock, flags); + +- if (connected) +- steam_input_register(steam); ++ schedule_work(&steam->unregister_work); + } + + static int steam_client_ll_raw_request(struct hid_device *hdev, +@@ -881,26 +1237,20 @@ static int steam_probe(struct hid_device *hdev, + return hid_hw_start(hdev, HID_CONNECT_DEFAULT); + + steam = devm_kzalloc(&hdev->dev, sizeof(*steam), GFP_KERNEL); +- if (!steam) { +- ret = -ENOMEM; +- goto steam_alloc_fail; +- } ++ if (!steam) ++ return -ENOMEM; ++ + steam->hdev = hdev; + hid_set_drvdata(hdev, steam); + spin_lock_init(&steam->lock); +- mutex_init(&steam->mutex); ++ mutex_init(&steam->report_mutex); + steam->quirks = id->driver_data; + INIT_WORK(&steam->work_connect, steam_work_connect_cb); ++ INIT_DELAYED_WORK(&steam->mode_switch, steam_mode_switch_cb); + INIT_LIST_HEAD(&steam->list); +- INIT_DEFERRABLE_WORK(&steam->heartbeat, steam_lizard_mode_heartbeat); + INIT_WORK(&steam->rumble_work, steam_haptic_rumble_cb); +- +- steam->client_hdev = steam_create_client_hid(hdev); +- if (IS_ERR(steam->client_hdev)) { +- ret = PTR_ERR(steam->client_hdev); +- goto client_hdev_fail; +- } +- steam->client_hdev->driver_data = steam; ++ steam->sensor_timestamp_us = 0; ++ INIT_WORK(&steam->unregister_work, steam_work_unregister_cb); + + /* + * With the real steam controller interface, do not connect hidraw. +@@ -908,18 +1258,14 @@ static int steam_probe(struct hid_device *hdev, + */ + ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_HIDRAW); + if (ret) +- goto hid_hw_start_fail; +- +- ret = hid_add_device(steam->client_hdev); +- if (ret) +- goto client_hdev_add_fail; ++ goto err_cancel_work; + + ret = hid_hw_open(hdev); + if (ret) { + hid_err(hdev, + "%s:hid_hw_open\n", + __func__); +- goto hid_hw_open_fail; ++ goto err_hw_stop; + } + + if (steam->quirks & STEAM_QUIRK_WIRELESS) { +@@ -935,25 +1281,38 @@ static int steam_probe(struct hid_device *hdev, + hid_err(hdev, + "%s:steam_register failed with error %d\n", + __func__, ret); +- goto input_register_fail; ++ goto err_hw_close; + } + } + ++ steam->client_hdev = steam_create_client_hid(hdev); ++ if (IS_ERR(steam->client_hdev)) { ++ ret = PTR_ERR(steam->client_hdev); ++ goto err_stream_unregister; ++ } ++ steam->client_hdev->driver_data = steam; ++ ++ ret = hid_add_device(steam->client_hdev); ++ if (ret) ++ goto err_destroy; ++ + return 0; + +-input_register_fail: +-hid_hw_open_fail: +-client_hdev_add_fail: +- hid_hw_stop(hdev); +-hid_hw_start_fail: ++err_destroy: + hid_destroy_device(steam->client_hdev); +-client_hdev_fail: ++err_stream_unregister: ++ if (steam->connected) ++ steam_unregister(steam); ++err_hw_close: ++ hid_hw_close(hdev); ++err_hw_stop: ++ hid_hw_stop(hdev); ++err_cancel_work: + cancel_work_sync(&steam->work_connect); +- cancel_delayed_work_sync(&steam->heartbeat); ++ cancel_delayed_work_sync(&steam->mode_switch); + cancel_work_sync(&steam->rumble_work); +-steam_alloc_fail: +- hid_err(hdev, "%s: failed with error %d\n", +- __func__, ret); ++ cancel_work_sync(&steam->unregister_work); ++ + return ret; + } + +@@ -966,13 +1325,13 @@ static void steam_remove(struct hid_device *hdev) + return; + } + ++ cancel_delayed_work_sync(&steam->mode_switch); ++ cancel_work_sync(&steam->work_connect); ++ cancel_work_sync(&steam->rumble_work); ++ cancel_work_sync(&steam->unregister_work); + hid_destroy_device(steam->client_hdev); +- mutex_lock(&steam->mutex); + steam->client_hdev = NULL; + steam->client_opened = false; +- cancel_delayed_work_sync(&steam->heartbeat); +- mutex_unlock(&steam->mutex); +- cancel_work_sync(&steam->work_connect); + if (steam->quirks & STEAM_QUIRK_WIRELESS) { + hid_info(hdev, "Steam wireless receiver disconnected"); + } +@@ -1154,12 +1513,12 @@ static void steam_do_input_event(struct steam_device *steam, + * 18-19 | s16 | ABS_HAT0Y | left-pad Y value + * 20-21 | s16 | ABS_HAT1X | right-pad X value + * 22-23 | s16 | ABS_HAT1Y | right-pad Y value +- * 24-25 | s16 | -- | accelerometer X value +- * 26-27 | s16 | -- | accelerometer Y value +- * 28-29 | s16 | -- | accelerometer Z value +- * 30-31 | s16 | -- | gyro X value +- * 32-33 | s16 | -- | gyro Y value +- * 34-35 | s16 | -- | gyro Z value ++ * 24-25 | s16 | IMU ABS_X | accelerometer X value ++ * 26-27 | s16 | IMU ABS_Z | accelerometer Y value ++ * 28-29 | s16 | IMU ABS_Y | accelerometer Z value ++ * 30-31 | s16 | IMU ABS_RX | gyro X value ++ * 32-33 | s16 | IMU ABS_RZ | gyro Y value ++ * 34-35 | s16 | IMU ABS_RY | gyro Z value + * 36-37 | s16 | -- | quaternion W value + * 38-39 | s16 | -- | quaternion X value + * 40-41 | s16 | -- | quaternion Y value +@@ -1254,6 +1613,17 @@ static void steam_do_deck_input_event(struct steam_device *steam, + b13 = data[13]; + b14 = data[14]; + ++ if (!(b9 & BIT(6)) && steam->did_mode_switch) { ++ steam->did_mode_switch = false; ++ cancel_delayed_work(&steam->mode_switch); ++ } else if (!steam->client_opened && (b9 & BIT(6)) && !steam->did_mode_switch) { ++ steam->did_mode_switch = true; ++ schedule_delayed_work(&steam->mode_switch, 45 * HZ / 100); ++ } ++ ++ if (!steam->gamepad_mode) ++ return; ++ + lpad_touched = b10 & BIT(3); + rpad_touched = b10 & BIT(4); + +@@ -1309,6 +1679,32 @@ static void steam_do_deck_input_event(struct steam_device *steam, + input_sync(input); + } + ++static void steam_do_deck_sensors_event(struct steam_device *steam, ++ struct input_dev *sensors, u8 *data) ++{ ++ /* ++ * The deck input report is received every 4 ms on average, ++ * with a jitter of +/- 4 ms even though the USB descriptor claims ++ * that it uses 1 kHz. ++ * Since the HID report does not include a sensor timestamp, ++ * use a fixed increment here. ++ */ ++ steam->sensor_timestamp_us += 4000; ++ ++ if (!steam->gamepad_mode) ++ return; ++ ++ input_event(sensors, EV_MSC, MSC_TIMESTAMP, steam->sensor_timestamp_us); ++ input_report_abs(sensors, ABS_X, steam_le16(data + 24)); ++ input_report_abs(sensors, ABS_Z, -steam_le16(data + 26)); ++ input_report_abs(sensors, ABS_Y, steam_le16(data + 28)); ++ input_report_abs(sensors, ABS_RX, steam_le16(data + 30)); ++ input_report_abs(sensors, ABS_RZ, -steam_le16(data + 32)); ++ input_report_abs(sensors, ABS_RY, steam_le16(data + 34)); ++ ++ input_sync(sensors); ++} ++ + /* + * The size for this message payload is 11. + * The known values are: +@@ -1346,6 +1742,7 @@ static int steam_raw_event(struct hid_device *hdev, + { + struct steam_device *steam = hid_get_drvdata(hdev); + struct input_dev *input; ++ struct input_dev *sensors; + struct power_supply *battery; + + if (!steam) +@@ -1375,7 +1772,7 @@ static int steam_raw_event(struct hid_device *hdev, + return 0; + + switch (data[2]) { +- case STEAM_EV_INPUT_DATA: ++ case ID_CONTROLLER_STATE: + if (steam->client_opened) + return 0; + rcu_read_lock(); +@@ -1384,16 +1781,19 @@ static int steam_raw_event(struct hid_device *hdev, + steam_do_input_event(steam, input, data); + rcu_read_unlock(); + break; +- case STEAM_EV_DECK_INPUT_DATA: ++ case ID_CONTROLLER_DECK_STATE: + if (steam->client_opened) + return 0; + rcu_read_lock(); + input = rcu_dereference(steam->input); + if (likely(input)) + steam_do_deck_input_event(steam, input, data); ++ sensors = rcu_dereference(steam->sensors); ++ if (likely(sensors)) ++ steam_do_deck_sensors_event(steam, sensors, data); + rcu_read_unlock(); + break; +- case STEAM_EV_CONNECT: ++ case ID_CONTROLLER_WIRELESS: + /* + * The payload of this event is a single byte: + * 0x01: disconnected. +@@ -1408,7 +1808,7 @@ static int steam_raw_event(struct hid_device *hdev, + break; + } + break; +- case STEAM_EV_BATTERY: ++ case ID_CONTROLLER_STATUS: + if (steam->quirks & STEAM_QUIRK_WIRELESS) { + rcu_read_lock(); + battery = rcu_dereference(steam->battery); +@@ -1439,10 +1839,8 @@ static int steam_param_set_lizard_mode(const char *val, + + mutex_lock(&steam_devices_lock); + list_for_each_entry(steam, &steam_devices, list) { +- mutex_lock(&steam->mutex); + if (!steam->client_opened) + steam_set_lizard_mode(steam, lizard_mode); +- mutex_unlock(&steam->mutex); + } + mutex_unlock(&steam_devices_lock); + return 0; +diff --git a/drivers/hid/hid-thrustmaster.c b/drivers/hid/hid-thrustmaster.c +index 6c3e758bbb09e3..3b81468a1df297 100644 +--- a/drivers/hid/hid-thrustmaster.c ++++ b/drivers/hid/hid-thrustmaster.c +@@ -171,7 +171,7 @@ static void thrustmaster_interrupts(struct hid_device *hdev) + b_ep = ep->desc.bEndpointAddress; + + /* Are the expected endpoints present? */ +- u8 ep_addr[1] = {b_ep}; ++ u8 ep_addr[2] = {b_ep, 0}; + + if (!usb_check_int_endpoints(usbif, ep_addr)) { + hid_err(hdev, "Unexpected non-int endpoint\n"); +diff --git a/drivers/infiniband/hw/efa/efa_main.c b/drivers/infiniband/hw/efa/efa_main.c +index 15ee9208111879..924940ca9de0a0 100644 +--- a/drivers/infiniband/hw/efa/efa_main.c ++++ b/drivers/infiniband/hw/efa/efa_main.c +@@ -452,7 +452,6 @@ static void efa_ib_device_remove(struct efa_dev *dev) + ibdev_info(&dev->ibdev, "Unregister ib device\n"); + ib_unregister_device(&dev->ibdev); + efa_destroy_eqs(dev); +- efa_com_dev_reset(&dev->edev, EFA_REGS_RESET_NORMAL); + efa_release_doorbell_bar(dev); + } + +@@ -623,12 +622,14 @@ static struct efa_dev *efa_probe_device(struct pci_dev *pdev) + return ERR_PTR(err); + } + +-static void efa_remove_device(struct pci_dev *pdev) ++static void efa_remove_device(struct pci_dev *pdev, ++ enum efa_regs_reset_reason_types reset_reason) + { + struct efa_dev *dev = pci_get_drvdata(pdev); + struct efa_com_dev *edev; + + edev = &dev->edev; ++ efa_com_dev_reset(edev, reset_reason); + efa_com_admin_destroy(edev); + efa_free_irq(dev, &dev->admin_irq); + efa_disable_msix(dev); +@@ -656,7 +657,7 @@ static int efa_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + return 0; + + err_remove_device: +- efa_remove_device(pdev); ++ efa_remove_device(pdev, EFA_REGS_RESET_INIT_ERR); + return err; + } + +@@ -665,7 +666,7 @@ static void efa_remove(struct pci_dev *pdev) + struct efa_dev *dev = pci_get_drvdata(pdev); + + efa_ib_device_remove(dev); +- efa_remove_device(pdev); ++ efa_remove_device(pdev, EFA_REGS_RESET_NORMAL); + } + + static struct pci_driver efa_pci_driver = { +diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c +index ba63076cd8f2b2..2085b1705f144f 100644 +--- a/drivers/md/md-bitmap.c ++++ b/drivers/md/md-bitmap.c +@@ -1465,22 +1465,12 @@ __acquires(bitmap->lock) + &(bitmap->bp[page].map[pageoff]); + } + +-int md_bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors, int behind) ++int md_bitmap_startwrite(struct bitmap *bitmap, sector_t offset, ++ unsigned long sectors) + { + if (!bitmap) + return 0; + +- if (behind) { +- int bw; +- atomic_inc(&bitmap->behind_writes); +- bw = atomic_read(&bitmap->behind_writes); +- if (bw > bitmap->behind_writes_used) +- bitmap->behind_writes_used = bw; +- +- pr_debug("inc write-behind count %d/%lu\n", +- bw, bitmap->mddev->bitmap_info.max_write_behind); +- } +- + while (sectors) { + sector_t blocks; + bitmap_counter_t *bmc; +@@ -1527,20 +1517,12 @@ int md_bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long s + } + return 0; + } +-EXPORT_SYMBOL(md_bitmap_startwrite); + + void md_bitmap_endwrite(struct bitmap *bitmap, sector_t offset, +- unsigned long sectors, int success, int behind) ++ unsigned long sectors) + { + if (!bitmap) + return; +- if (behind) { +- if (atomic_dec_and_test(&bitmap->behind_writes)) +- wake_up(&bitmap->behind_wait); +- pr_debug("dec write-behind count %d/%lu\n", +- atomic_read(&bitmap->behind_writes), +- bitmap->mddev->bitmap_info.max_write_behind); +- } + + while (sectors) { + sector_t blocks; +@@ -1554,15 +1536,16 @@ void md_bitmap_endwrite(struct bitmap *bitmap, sector_t offset, + return; + } + +- if (success && !bitmap->mddev->degraded && +- bitmap->events_cleared < bitmap->mddev->events) { +- bitmap->events_cleared = bitmap->mddev->events; +- bitmap->need_sync = 1; +- sysfs_notify_dirent_safe(bitmap->sysfs_can_clear); +- } +- +- if (!success && !NEEDED(*bmc)) ++ if (!bitmap->mddev->degraded) { ++ if (bitmap->events_cleared < bitmap->mddev->events) { ++ bitmap->events_cleared = bitmap->mddev->events; ++ bitmap->need_sync = 1; ++ sysfs_notify_dirent_safe( ++ bitmap->sysfs_can_clear); ++ } ++ } else if (!NEEDED(*bmc)) { + *bmc |= NEEDED_MASK; ++ } + + if (COUNTER(*bmc) == COUNTER_MAX) + wake_up(&bitmap->overflow_wait); +@@ -1580,7 +1563,6 @@ void md_bitmap_endwrite(struct bitmap *bitmap, sector_t offset, + sectors = 0; + } + } +-EXPORT_SYMBOL(md_bitmap_endwrite); + + static int __bitmap_start_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, + int degraded) +@@ -1842,6 +1824,39 @@ void md_bitmap_free(struct bitmap *bitmap) + } + EXPORT_SYMBOL(md_bitmap_free); + ++void md_bitmap_start_behind_write(struct mddev *mddev) ++{ ++ struct bitmap *bitmap = mddev->bitmap; ++ int bw; ++ ++ if (!bitmap) ++ return; ++ ++ atomic_inc(&bitmap->behind_writes); ++ bw = atomic_read(&bitmap->behind_writes); ++ if (bw > bitmap->behind_writes_used) ++ bitmap->behind_writes_used = bw; ++ ++ pr_debug("inc write-behind count %d/%lu\n", ++ bw, bitmap->mddev->bitmap_info.max_write_behind); ++} ++EXPORT_SYMBOL_GPL(md_bitmap_start_behind_write); ++ ++void md_bitmap_end_behind_write(struct mddev *mddev) ++{ ++ struct bitmap *bitmap = mddev->bitmap; ++ ++ if (!bitmap) ++ return; ++ ++ if (atomic_dec_and_test(&bitmap->behind_writes)) ++ wake_up(&bitmap->behind_wait); ++ pr_debug("dec write-behind count %d/%lu\n", ++ atomic_read(&bitmap->behind_writes), ++ bitmap->mddev->bitmap_info.max_write_behind); ++} ++EXPORT_SYMBOL_GPL(md_bitmap_end_behind_write); ++ + void md_bitmap_wait_behind_writes(struct mddev *mddev) + { + struct bitmap *bitmap = mddev->bitmap; +diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h +index bb9eb418780a62..8b89e260a93b71 100644 +--- a/drivers/md/md-bitmap.h ++++ b/drivers/md/md-bitmap.h +@@ -253,9 +253,11 @@ void md_bitmap_dirty_bits(struct bitmap *bitmap, unsigned long s, unsigned long + + /* these are exported */ + int md_bitmap_startwrite(struct bitmap *bitmap, sector_t offset, +- unsigned long sectors, int behind); ++ unsigned long sectors); + void md_bitmap_endwrite(struct bitmap *bitmap, sector_t offset, +- unsigned long sectors, int success, int behind); ++ unsigned long sectors); ++void md_bitmap_start_behind_write(struct mddev *mddev); ++void md_bitmap_end_behind_write(struct mddev *mddev); + int md_bitmap_start_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, int degraded); + void md_bitmap_end_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, int aborted); + void md_bitmap_close_sync(struct bitmap *bitmap); +diff --git a/drivers/md/md.c b/drivers/md/md.c +index d1f6770c5cc094..9bc19a5a4119bd 100644 +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -8713,12 +8713,32 @@ void md_submit_discard_bio(struct mddev *mddev, struct md_rdev *rdev, + } + EXPORT_SYMBOL_GPL(md_submit_discard_bio); + ++static void md_bitmap_start(struct mddev *mddev, ++ struct md_io_clone *md_io_clone) ++{ ++ if (mddev->pers->bitmap_sector) ++ mddev->pers->bitmap_sector(mddev, &md_io_clone->offset, ++ &md_io_clone->sectors); ++ ++ md_bitmap_startwrite(mddev->bitmap, md_io_clone->offset, ++ md_io_clone->sectors); ++} ++ ++static void md_bitmap_end(struct mddev *mddev, struct md_io_clone *md_io_clone) ++{ ++ md_bitmap_endwrite(mddev->bitmap, md_io_clone->offset, ++ md_io_clone->sectors); ++} ++ + static void md_end_clone_io(struct bio *bio) + { + struct md_io_clone *md_io_clone = bio->bi_private; + struct bio *orig_bio = md_io_clone->orig_bio; + struct mddev *mddev = md_io_clone->mddev; + ++ if (bio_data_dir(orig_bio) == WRITE && mddev->bitmap) ++ md_bitmap_end(mddev, md_io_clone); ++ + if (bio->bi_status && !orig_bio->bi_status) + orig_bio->bi_status = bio->bi_status; + +@@ -8743,6 +8763,12 @@ static void md_clone_bio(struct mddev *mddev, struct bio **bio) + if (blk_queue_io_stat(bdev->bd_disk->queue)) + md_io_clone->start_time = bio_start_io_acct(*bio); + ++ if (bio_data_dir(*bio) == WRITE && mddev->bitmap) { ++ md_io_clone->offset = (*bio)->bi_iter.bi_sector; ++ md_io_clone->sectors = bio_sectors(*bio); ++ md_bitmap_start(mddev, md_io_clone); ++ } ++ + clone->bi_end_io = md_end_clone_io; + clone->bi_private = md_io_clone; + *bio = clone; +diff --git a/drivers/md/md.h b/drivers/md/md.h +index 7c9c13abd7cac0..f29fa8650cd0f0 100644 +--- a/drivers/md/md.h ++++ b/drivers/md/md.h +@@ -661,6 +661,9 @@ struct md_personality + void *(*takeover) (struct mddev *mddev); + /* Changes the consistency policy of an active array. */ + int (*change_consistency_policy)(struct mddev *mddev, const char *buf); ++ /* convert io ranges from array to bitmap */ ++ void (*bitmap_sector)(struct mddev *mddev, sector_t *offset, ++ unsigned long *sectors); + }; + + struct md_sysfs_entry { +@@ -743,6 +746,8 @@ struct md_io_clone { + struct mddev *mddev; + struct bio *orig_bio; + unsigned long start_time; ++ sector_t offset; ++ unsigned long sectors; + struct bio bio_clone; + }; + +diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c +index cc02e7ec72c08c..65309da1dca340 100644 +--- a/drivers/md/raid1.c ++++ b/drivers/md/raid1.c +@@ -419,11 +419,8 @@ static void close_write(struct r1bio *r1_bio) + bio_put(r1_bio->behind_master_bio); + r1_bio->behind_master_bio = NULL; + } +- /* clear the bitmap if all writes complete successfully */ +- md_bitmap_endwrite(r1_bio->mddev->bitmap, r1_bio->sector, +- r1_bio->sectors, +- !test_bit(R1BIO_Degraded, &r1_bio->state), +- test_bit(R1BIO_BehindIO, &r1_bio->state)); ++ if (test_bit(R1BIO_BehindIO, &r1_bio->state)) ++ md_bitmap_end_behind_write(r1_bio->mddev); + md_write_end(r1_bio->mddev); + } + +@@ -480,8 +477,6 @@ static void raid1_end_write_request(struct bio *bio) + if (!test_bit(Faulty, &rdev->flags)) + set_bit(R1BIO_WriteError, &r1_bio->state); + else { +- /* Fail the request */ +- set_bit(R1BIO_Degraded, &r1_bio->state); + /* Finished with this branch */ + r1_bio->bios[mirror] = NULL; + to_put = bio; +@@ -1414,11 +1409,8 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio, + break; + } + r1_bio->bios[i] = NULL; +- if (!rdev || test_bit(Faulty, &rdev->flags)) { +- if (i < conf->raid_disks) +- set_bit(R1BIO_Degraded, &r1_bio->state); ++ if (!rdev || test_bit(Faulty, &rdev->flags)) + continue; +- } + + atomic_inc(&rdev->nr_pending); + if (test_bit(WriteErrorSeen, &rdev->flags)) { +@@ -1444,16 +1436,6 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio, + */ + max_sectors = bad_sectors; + rdev_dec_pending(rdev, mddev); +- /* We don't set R1BIO_Degraded as that +- * only applies if the disk is +- * missing, so it might be re-added, +- * and we want to know to recover this +- * chunk. +- * In this case the device is here, +- * and the fact that this chunk is not +- * in-sync is recorded in the bad +- * block log +- */ + continue; + } + if (is_bad) { +@@ -1530,8 +1512,8 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio, + alloc_behind_master_bio(r1_bio, bio); + } + +- md_bitmap_startwrite(bitmap, r1_bio->sector, r1_bio->sectors, +- test_bit(R1BIO_BehindIO, &r1_bio->state)); ++ if (test_bit(R1BIO_BehindIO, &r1_bio->state)) ++ md_bitmap_start_behind_write(mddev); + first_clone = 0; + } + +@@ -2476,12 +2458,9 @@ static void handle_write_finished(struct r1conf *conf, struct r1bio *r1_bio) + * errors. + */ + fail = true; +- if (!narrow_write_error(r1_bio, m)) { ++ if (!narrow_write_error(r1_bio, m)) + md_error(conf->mddev, + conf->mirrors[m].rdev); +- /* an I/O failed, we can't clear the bitmap */ +- set_bit(R1BIO_Degraded, &r1_bio->state); +- } + rdev_dec_pending(conf->mirrors[m].rdev, + conf->mddev); + } +@@ -2573,8 +2552,6 @@ static void raid1d(struct md_thread *thread) + list_del(&r1_bio->retry_list); + idx = sector_to_idx(r1_bio->sector); + atomic_dec(&conf->nr_queued[idx]); +- if (mddev->degraded) +- set_bit(R1BIO_Degraded, &r1_bio->state); + if (test_bit(R1BIO_WriteError, &r1_bio->state)) + close_write(r1_bio); + raid_end_bio_io(r1_bio); +diff --git a/drivers/md/raid1.h b/drivers/md/raid1.h +index 14d4211a123a8e..44f2390a886690 100644 +--- a/drivers/md/raid1.h ++++ b/drivers/md/raid1.h +@@ -187,7 +187,6 @@ struct r1bio { + enum r1bio_state { + R1BIO_Uptodate, + R1BIO_IsSync, +- R1BIO_Degraded, + R1BIO_BehindIO, + /* Set ReadError on bios that experience a readerror so that + * raid1d knows what to do with them. +diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c +index 02341312085162..c300fd609ef08c 100644 +--- a/drivers/md/raid10.c ++++ b/drivers/md/raid10.c +@@ -427,11 +427,6 @@ static void raid10_end_read_request(struct bio *bio) + + static void close_write(struct r10bio *r10_bio) + { +- /* clear the bitmap if all writes complete successfully */ +- md_bitmap_endwrite(r10_bio->mddev->bitmap, r10_bio->sector, +- r10_bio->sectors, +- !test_bit(R10BIO_Degraded, &r10_bio->state), +- 0); + md_write_end(r10_bio->mddev); + } + +@@ -501,7 +496,6 @@ static void raid10_end_write_request(struct bio *bio) + set_bit(R10BIO_WriteError, &r10_bio->state); + else { + /* Fail the request */ +- set_bit(R10BIO_Degraded, &r10_bio->state); + r10_bio->devs[slot].bio = NULL; + to_put = bio; + dec_rdev = 1; +@@ -1490,10 +1484,8 @@ static void raid10_write_request(struct mddev *mddev, struct bio *bio, + r10_bio->devs[i].bio = NULL; + r10_bio->devs[i].repl_bio = NULL; + +- if (!rdev && !rrdev) { +- set_bit(R10BIO_Degraded, &r10_bio->state); ++ if (!rdev && !rrdev) + continue; +- } + if (rdev && test_bit(WriteErrorSeen, &rdev->flags)) { + sector_t first_bad; + sector_t dev_sector = r10_bio->devs[i].addr; +@@ -1510,14 +1502,6 @@ static void raid10_write_request(struct mddev *mddev, struct bio *bio, + * to other devices yet + */ + max_sectors = bad_sectors; +- /* We don't set R10BIO_Degraded as that +- * only applies if the disk is missing, +- * so it might be re-added, and we want to +- * know to recover this chunk. +- * In this case the device is here, and the +- * fact that this chunk is not in-sync is +- * recorded in the bad block log. +- */ + continue; + } + if (is_bad) { +@@ -1554,7 +1538,6 @@ static void raid10_write_request(struct mddev *mddev, struct bio *bio, + md_account_bio(mddev, &bio); + r10_bio->master_bio = bio; + atomic_set(&r10_bio->remaining, 1); +- md_bitmap_startwrite(mddev->bitmap, r10_bio->sector, r10_bio->sectors, 0); + + for (i = 0; i < conf->copies; i++) { + if (r10_bio->devs[i].bio) +@@ -3063,11 +3046,8 @@ static void handle_write_completed(struct r10conf *conf, struct r10bio *r10_bio) + rdev_dec_pending(rdev, conf->mddev); + } else if (bio != NULL && bio->bi_status) { + fail = true; +- if (!narrow_write_error(r10_bio, m)) { ++ if (!narrow_write_error(r10_bio, m)) + md_error(conf->mddev, rdev); +- set_bit(R10BIO_Degraded, +- &r10_bio->state); +- } + rdev_dec_pending(rdev, conf->mddev); + } + bio = r10_bio->devs[m].repl_bio; +@@ -3126,8 +3106,6 @@ static void raid10d(struct md_thread *thread) + r10_bio = list_first_entry(&tmp, struct r10bio, + retry_list); + list_del(&r10_bio->retry_list); +- if (mddev->degraded) +- set_bit(R10BIO_Degraded, &r10_bio->state); + + if (test_bit(R10BIO_WriteError, + &r10_bio->state)) +diff --git a/drivers/md/raid10.h b/drivers/md/raid10.h +index 2e75e88d08023f..3f16ad6904a9fb 100644 +--- a/drivers/md/raid10.h ++++ b/drivers/md/raid10.h +@@ -161,7 +161,6 @@ enum r10bio_state { + R10BIO_IsSync, + R10BIO_IsRecover, + R10BIO_IsReshape, +- R10BIO_Degraded, + /* Set ReadError on bios that experience a read error + * so that raid10d knows what to do with them. + */ +diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c +index 889bba60d6ff71..53f3718c01ebe1 100644 +--- a/drivers/md/raid5-cache.c ++++ b/drivers/md/raid5-cache.c +@@ -313,10 +313,6 @@ void r5c_handle_cached_data_endio(struct r5conf *conf, + if (sh->dev[i].written) { + set_bit(R5_UPTODATE, &sh->dev[i].flags); + r5c_return_dev_pending_writes(conf, &sh->dev[i]); +- md_bitmap_endwrite(conf->mddev->bitmap, sh->sector, +- RAID5_STRIPE_SECTORS(conf), +- !test_bit(STRIPE_DEGRADED, &sh->state), +- 0); + } + } + } +diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c +index 2c7f11e5766735..f69e4a6a8a5923 100644 +--- a/drivers/md/raid5.c ++++ b/drivers/md/raid5.c +@@ -905,7 +905,6 @@ static bool stripe_can_batch(struct stripe_head *sh) + if (raid5_has_log(conf) || raid5_has_ppl(conf)) + return false; + return test_bit(STRIPE_BATCH_READY, &sh->state) && +- !test_bit(STRIPE_BITMAP_PENDING, &sh->state) && + is_full_stripe_write(sh); + } + +@@ -1359,8 +1358,6 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s) + submit_bio_noacct(rbi); + } + if (!rdev && !rrdev) { +- if (op_is_write(op)) +- set_bit(STRIPE_DEGRADED, &sh->state); + pr_debug("skip op %d on disc %d for sector %llu\n", + bi->bi_opf, i, (unsigned long long)sh->sector); + clear_bit(R5_LOCKED, &sh->dev[i].flags); +@@ -2925,7 +2922,6 @@ static void raid5_end_write_request(struct bio *bi) + set_bit(R5_MadeGoodRepl, &sh->dev[i].flags); + } else { + if (bi->bi_status) { +- set_bit(STRIPE_DEGRADED, &sh->state); + set_bit(WriteErrorSeen, &rdev->flags); + set_bit(R5_WriteError, &sh->dev[i].flags); + if (!test_and_set_bit(WantReplacement, &rdev->flags)) +@@ -3590,29 +3586,9 @@ static void __add_stripe_bio(struct stripe_head *sh, struct bio *bi, + (*bip)->bi_iter.bi_sector, sh->sector, dd_idx, + sh->dev[dd_idx].sector); + +- if (conf->mddev->bitmap && firstwrite) { +- /* Cannot hold spinlock over bitmap_startwrite, +- * but must ensure this isn't added to a batch until +- * we have added to the bitmap and set bm_seq. +- * So set STRIPE_BITMAP_PENDING to prevent +- * batching. +- * If multiple __add_stripe_bio() calls race here they +- * much all set STRIPE_BITMAP_PENDING. So only the first one +- * to complete "bitmap_startwrite" gets to set +- * STRIPE_BIT_DELAY. This is important as once a stripe +- * is added to a batch, STRIPE_BIT_DELAY cannot be changed +- * any more. +- */ +- set_bit(STRIPE_BITMAP_PENDING, &sh->state); +- spin_unlock_irq(&sh->stripe_lock); +- md_bitmap_startwrite(conf->mddev->bitmap, sh->sector, +- RAID5_STRIPE_SECTORS(conf), 0); +- spin_lock_irq(&sh->stripe_lock); +- clear_bit(STRIPE_BITMAP_PENDING, &sh->state); +- if (!sh->batch_head) { +- sh->bm_seq = conf->seq_flush+1; +- set_bit(STRIPE_BIT_DELAY, &sh->state); +- } ++ if (conf->mddev->bitmap && firstwrite && !sh->batch_head) { ++ sh->bm_seq = conf->seq_flush+1; ++ set_bit(STRIPE_BIT_DELAY, &sh->state); + } + } + +@@ -3663,7 +3639,6 @@ handle_failed_stripe(struct r5conf *conf, struct stripe_head *sh, + BUG_ON(sh->batch_head); + for (i = disks; i--; ) { + struct bio *bi; +- int bitmap_end = 0; + + if (test_bit(R5_ReadError, &sh->dev[i].flags)) { + struct md_rdev *rdev; +@@ -3690,8 +3665,6 @@ handle_failed_stripe(struct r5conf *conf, struct stripe_head *sh, + sh->dev[i].towrite = NULL; + sh->overwrite_disks = 0; + spin_unlock_irq(&sh->stripe_lock); +- if (bi) +- bitmap_end = 1; + + log_stripe_write_finished(sh); + +@@ -3706,10 +3679,6 @@ handle_failed_stripe(struct r5conf *conf, struct stripe_head *sh, + bio_io_error(bi); + bi = nextbi; + } +- if (bitmap_end) +- md_bitmap_endwrite(conf->mddev->bitmap, sh->sector, +- RAID5_STRIPE_SECTORS(conf), 0, 0); +- bitmap_end = 0; + /* and fail all 'written' */ + bi = sh->dev[i].written; + sh->dev[i].written = NULL; +@@ -3718,7 +3687,6 @@ handle_failed_stripe(struct r5conf *conf, struct stripe_head *sh, + sh->dev[i].page = sh->dev[i].orig_page; + } + +- if (bi) bitmap_end = 1; + while (bi && bi->bi_iter.bi_sector < + sh->dev[i].sector + RAID5_STRIPE_SECTORS(conf)) { + struct bio *bi2 = r5_next_bio(conf, bi, sh->dev[i].sector); +@@ -3752,9 +3720,6 @@ handle_failed_stripe(struct r5conf *conf, struct stripe_head *sh, + bi = nextbi; + } + } +- if (bitmap_end) +- md_bitmap_endwrite(conf->mddev->bitmap, sh->sector, +- RAID5_STRIPE_SECTORS(conf), 0, 0); + /* If we were in the middle of a write the parity block might + * still be locked - so just clear all R5_LOCKED flags + */ +@@ -4105,10 +4070,7 @@ static void handle_stripe_clean_event(struct r5conf *conf, + bio_endio(wbi); + wbi = wbi2; + } +- md_bitmap_endwrite(conf->mddev->bitmap, sh->sector, +- RAID5_STRIPE_SECTORS(conf), +- !test_bit(STRIPE_DEGRADED, &sh->state), +- 0); ++ + if (head_sh->batch_head) { + sh = list_first_entry(&sh->batch_list, + struct stripe_head, +@@ -4385,7 +4347,6 @@ static void handle_parity_checks5(struct r5conf *conf, struct stripe_head *sh, + s->locked++; + set_bit(R5_Wantwrite, &dev->flags); + +- clear_bit(STRIPE_DEGRADED, &sh->state); + set_bit(STRIPE_INSYNC, &sh->state); + break; + case check_state_run: +@@ -4542,7 +4503,6 @@ static void handle_parity_checks6(struct r5conf *conf, struct stripe_head *sh, + clear_bit(R5_Wantwrite, &dev->flags); + s->locked--; + } +- clear_bit(STRIPE_DEGRADED, &sh->state); + + set_bit(STRIPE_INSYNC, &sh->state); + break; +@@ -4942,8 +4902,7 @@ static void break_stripe_batch_list(struct stripe_head *head_sh, + (1 << STRIPE_COMPUTE_RUN) | + (1 << STRIPE_DISCARD) | + (1 << STRIPE_BATCH_READY) | +- (1 << STRIPE_BATCH_ERR) | +- (1 << STRIPE_BITMAP_PENDING)), ++ (1 << STRIPE_BATCH_ERR)), + "stripe state: %lx\n", sh->state); + WARN_ONCE(head_sh->state & ((1 << STRIPE_DISCARD) | + (1 << STRIPE_REPLACED)), +@@ -4951,7 +4910,6 @@ static void break_stripe_batch_list(struct stripe_head *head_sh, + + set_mask_bits(&sh->state, ~(STRIPE_EXPAND_SYNC_FLAGS | + (1 << STRIPE_PREREAD_ACTIVE) | +- (1 << STRIPE_DEGRADED) | + (1 << STRIPE_ON_UNPLUG_LIST)), + head_sh->state & (1 << STRIPE_INSYNC)); + +@@ -5848,13 +5806,6 @@ static void make_discard_request(struct mddev *mddev, struct bio *bi) + } + spin_unlock_irq(&sh->stripe_lock); + if (conf->mddev->bitmap) { +- for (d = 0; +- d < conf->raid_disks - conf->max_degraded; +- d++) +- md_bitmap_startwrite(mddev->bitmap, +- sh->sector, +- RAID5_STRIPE_SECTORS(conf), +- 0); + sh->bm_seq = conf->seq_flush + 1; + set_bit(STRIPE_BIT_DELAY, &sh->state); + } +@@ -5972,6 +5923,87 @@ static bool reshape_disabled(struct mddev *mddev) + return is_md_suspended(mddev) || !md_is_rdwr(mddev); + } + ++enum reshape_loc { ++ LOC_NO_RESHAPE, ++ LOC_AHEAD_OF_RESHAPE, ++ LOC_INSIDE_RESHAPE, ++ LOC_BEHIND_RESHAPE, ++}; ++ ++static enum reshape_loc get_reshape_loc(struct mddev *mddev, ++ struct r5conf *conf, sector_t logical_sector) ++{ ++ sector_t reshape_progress, reshape_safe; ++ /* ++ * Spinlock is needed as reshape_progress may be ++ * 64bit on a 32bit platform, and so it might be ++ * possible to see a half-updated value ++ * Of course reshape_progress could change after ++ * the lock is dropped, so once we get a reference ++ * to the stripe that we think it is, we will have ++ * to check again. ++ */ ++ spin_lock_irq(&conf->device_lock); ++ reshape_progress = conf->reshape_progress; ++ reshape_safe = conf->reshape_safe; ++ spin_unlock_irq(&conf->device_lock); ++ if (reshape_progress == MaxSector) ++ return LOC_NO_RESHAPE; ++ if (ahead_of_reshape(mddev, logical_sector, reshape_progress)) ++ return LOC_AHEAD_OF_RESHAPE; ++ if (ahead_of_reshape(mddev, logical_sector, reshape_safe)) ++ return LOC_INSIDE_RESHAPE; ++ return LOC_BEHIND_RESHAPE; ++} ++ ++static void raid5_bitmap_sector(struct mddev *mddev, sector_t *offset, ++ unsigned long *sectors) ++{ ++ struct r5conf *conf = mddev->private; ++ sector_t start = *offset; ++ sector_t end = start + *sectors; ++ sector_t prev_start = start; ++ sector_t prev_end = end; ++ int sectors_per_chunk; ++ enum reshape_loc loc; ++ int dd_idx; ++ ++ sectors_per_chunk = conf->chunk_sectors * ++ (conf->raid_disks - conf->max_degraded); ++ start = round_down(start, sectors_per_chunk); ++ end = round_up(end, sectors_per_chunk); ++ ++ start = raid5_compute_sector(conf, start, 0, &dd_idx, NULL); ++ end = raid5_compute_sector(conf, end, 0, &dd_idx, NULL); ++ ++ /* ++ * For LOC_INSIDE_RESHAPE, this IO will wait for reshape to make ++ * progress, hence it's the same as LOC_BEHIND_RESHAPE. ++ */ ++ loc = get_reshape_loc(mddev, conf, prev_start); ++ if (likely(loc != LOC_AHEAD_OF_RESHAPE)) { ++ *offset = start; ++ *sectors = end - start; ++ return; ++ } ++ ++ sectors_per_chunk = conf->prev_chunk_sectors * ++ (conf->previous_raid_disks - conf->max_degraded); ++ prev_start = round_down(prev_start, sectors_per_chunk); ++ prev_end = round_down(prev_end, sectors_per_chunk); ++ ++ prev_start = raid5_compute_sector(conf, prev_start, 1, &dd_idx, NULL); ++ prev_end = raid5_compute_sector(conf, prev_end, 1, &dd_idx, NULL); ++ ++ /* ++ * for LOC_AHEAD_OF_RESHAPE, reshape can make progress before this IO ++ * is handled in make_stripe_request(), we can't know this here hence ++ * we set bits for both. ++ */ ++ *offset = min(start, prev_start); ++ *sectors = max(end, prev_end) - *offset; ++} ++ + static enum stripe_result make_stripe_request(struct mddev *mddev, + struct r5conf *conf, struct stripe_request_ctx *ctx, + sector_t logical_sector, struct bio *bi) +@@ -5986,28 +6018,14 @@ static enum stripe_result make_stripe_request(struct mddev *mddev, + seq = read_seqcount_begin(&conf->gen_lock); + + if (unlikely(conf->reshape_progress != MaxSector)) { +- /* +- * Spinlock is needed as reshape_progress may be +- * 64bit on a 32bit platform, and so it might be +- * possible to see a half-updated value +- * Of course reshape_progress could change after +- * the lock is dropped, so once we get a reference +- * to the stripe that we think it is, we will have +- * to check again. +- */ +- spin_lock_irq(&conf->device_lock); +- if (ahead_of_reshape(mddev, logical_sector, +- conf->reshape_progress)) { +- previous = 1; +- } else { +- if (ahead_of_reshape(mddev, logical_sector, +- conf->reshape_safe)) { +- spin_unlock_irq(&conf->device_lock); +- ret = STRIPE_SCHEDULE_AND_RETRY; +- goto out; +- } ++ enum reshape_loc loc = get_reshape_loc(mddev, conf, ++ logical_sector); ++ if (loc == LOC_INSIDE_RESHAPE) { ++ ret = STRIPE_SCHEDULE_AND_RETRY; ++ goto out; + } +- spin_unlock_irq(&conf->device_lock); ++ if (loc == LOC_AHEAD_OF_RESHAPE) ++ previous = 1; + } + + new_sector = raid5_compute_sector(conf, logical_sector, previous, +@@ -6189,8 +6207,7 @@ static bool raid5_make_request(struct mddev *mddev, struct bio * bi) + /* Bail out if conflicts with reshape and REQ_NOWAIT is set */ + if ((bi->bi_opf & REQ_NOWAIT) && + (conf->reshape_progress != MaxSector) && +- !ahead_of_reshape(mddev, logical_sector, conf->reshape_progress) && +- ahead_of_reshape(mddev, logical_sector, conf->reshape_safe)) { ++ get_reshape_loc(mddev, conf, logical_sector) == LOC_INSIDE_RESHAPE) { + bio_wouldblock_error(bi); + if (rw == WRITE) + md_write_end(mddev); +@@ -9090,6 +9107,7 @@ static struct md_personality raid6_personality = + .quiesce = raid5_quiesce, + .takeover = raid6_takeover, + .change_consistency_policy = raid5_change_consistency_policy, ++ .bitmap_sector = raid5_bitmap_sector, + }; + static struct md_personality raid5_personality = + { +@@ -9115,6 +9133,7 @@ static struct md_personality raid5_personality = + .quiesce = raid5_quiesce, + .takeover = raid5_takeover, + .change_consistency_policy = raid5_change_consistency_policy, ++ .bitmap_sector = raid5_bitmap_sector, + }; + + static struct md_personality raid4_personality = +@@ -9141,6 +9160,7 @@ static struct md_personality raid4_personality = + .quiesce = raid5_quiesce, + .takeover = raid4_takeover, + .change_consistency_policy = raid5_change_consistency_policy, ++ .bitmap_sector = raid5_bitmap_sector, + }; + + static int __init raid5_init(void) +diff --git a/drivers/md/raid5.h b/drivers/md/raid5.h +index 97a795979a3502..fd617155388000 100644 +--- a/drivers/md/raid5.h ++++ b/drivers/md/raid5.h +@@ -358,7 +358,6 @@ enum { + STRIPE_REPLACED, + STRIPE_PREREAD_ACTIVE, + STRIPE_DELAYED, +- STRIPE_DEGRADED, + STRIPE_BIT_DELAY, + STRIPE_EXPANDING, + STRIPE_EXPAND_SOURCE, +@@ -372,9 +371,6 @@ enum { + STRIPE_ON_RELEASE_LIST, + STRIPE_BATCH_READY, + STRIPE_BATCH_ERR, +- STRIPE_BITMAP_PENDING, /* Being added to bitmap, don't add +- * to batch yet. +- */ + STRIPE_LOG_TRAPPED, /* trapped into log (see raid5-cache.c) + * this bit is used in two scenarios: + * +diff --git a/drivers/media/dvb-frontends/cxd2841er.c b/drivers/media/dvb-frontends/cxd2841er.c +index d925ca24183b50..415f1f91cc3072 100644 +--- a/drivers/media/dvb-frontends/cxd2841er.c ++++ b/drivers/media/dvb-frontends/cxd2841er.c +@@ -311,12 +311,8 @@ static int cxd2841er_set_reg_bits(struct cxd2841er_priv *priv, + + static u32 cxd2841er_calc_iffreq_xtal(enum cxd2841er_xtal xtal, u32 ifhz) + { +- u64 tmp; +- +- tmp = (u64) ifhz * 16777216; +- do_div(tmp, ((xtal == SONY_XTAL_24000) ? 48000000 : 41000000)); +- +- return (u32) tmp; ++ return div_u64(ifhz * 16777216ull, ++ (xtal == SONY_XTAL_24000) ? 48000000 : 41000000); + } + + static u32 cxd2841er_calc_iffreq(u32 ifhz) +diff --git a/drivers/media/i2c/ds90ub913.c b/drivers/media/i2c/ds90ub913.c +index 5a650facae4153..ae33d1ecf835df 100644 +--- a/drivers/media/i2c/ds90ub913.c ++++ b/drivers/media/i2c/ds90ub913.c +@@ -8,6 +8,7 @@ + * Copyright (c) 2023 Tomi Valkeinen + */ + ++#include + #include + #include + #include +@@ -146,6 +147,19 @@ static int ub913_write(const struct ub913_data *priv, u8 reg, u8 val) + return ret; + } + ++static int ub913_update_bits(const struct ub913_data *priv, u8 reg, u8 mask, ++ u8 val) ++{ ++ int ret; ++ ++ ret = regmap_update_bits(priv->regmap, reg, mask, val); ++ if (ret < 0) ++ dev_err(&priv->client->dev, ++ "Cannot update register 0x%02x %d!\n", reg, ret); ++ ++ return ret; ++} ++ + /* + * GPIO chip + */ +@@ -733,10 +747,13 @@ static int ub913_hw_init(struct ub913_data *priv) + if (ret) + return dev_err_probe(dev, ret, "i2c master init failed\n"); + +- ub913_read(priv, UB913_REG_GENERAL_CFG, &v); +- v &= ~UB913_REG_GENERAL_CFG_PCLK_RISING; +- v |= priv->pclk_polarity_rising ? UB913_REG_GENERAL_CFG_PCLK_RISING : 0; +- ub913_write(priv, UB913_REG_GENERAL_CFG, v); ++ ret = ub913_update_bits(priv, UB913_REG_GENERAL_CFG, ++ UB913_REG_GENERAL_CFG_PCLK_RISING, ++ FIELD_PREP(UB913_REG_GENERAL_CFG_PCLK_RISING, ++ priv->pclk_polarity_rising)); ++ ++ if (ret) ++ return ret; + + return 0; + } +diff --git a/drivers/media/i2c/ds90ub953.c b/drivers/media/i2c/ds90ub953.c +index 1dd29137d2d9f2..007c95ac34d931 100644 +--- a/drivers/media/i2c/ds90ub953.c ++++ b/drivers/media/i2c/ds90ub953.c +@@ -398,8 +398,13 @@ static int ub953_gpiochip_probe(struct ub953_data *priv) + int ret; + + /* Set all GPIOs to local input mode */ +- ub953_write(priv, UB953_REG_LOCAL_GPIO_DATA, 0); +- ub953_write(priv, UB953_REG_GPIO_INPUT_CTRL, 0xf); ++ ret = ub953_write(priv, UB953_REG_LOCAL_GPIO_DATA, 0); ++ if (ret) ++ return ret; ++ ++ ret = ub953_write(priv, UB953_REG_GPIO_INPUT_CTRL, 0xf); ++ if (ret) ++ return ret; + + gc->label = dev_name(dev); + gc->parent = dev; +@@ -961,10 +966,11 @@ static void ub953_calc_clkout_params(struct ub953_data *priv, + clkout_data->rate = clkout_rate; + } + +-static void ub953_write_clkout_regs(struct ub953_data *priv, +- const struct ub953_clkout_data *clkout_data) ++static int ub953_write_clkout_regs(struct ub953_data *priv, ++ const struct ub953_clkout_data *clkout_data) + { + u8 clkout_ctrl0, clkout_ctrl1; ++ int ret; + + if (priv->hw_data->is_ub971) + clkout_ctrl0 = clkout_data->m; +@@ -974,8 +980,15 @@ static void ub953_write_clkout_regs(struct ub953_data *priv, + + clkout_ctrl1 = clkout_data->n; + +- ub953_write(priv, UB953_REG_CLKOUT_CTRL0, clkout_ctrl0); +- ub953_write(priv, UB953_REG_CLKOUT_CTRL1, clkout_ctrl1); ++ ret = ub953_write(priv, UB953_REG_CLKOUT_CTRL0, clkout_ctrl0); ++ if (ret) ++ return ret; ++ ++ ret = ub953_write(priv, UB953_REG_CLKOUT_CTRL1, clkout_ctrl1); ++ if (ret) ++ return ret; ++ ++ return 0; + } + + static unsigned long ub953_clkout_recalc_rate(struct clk_hw *hw, +@@ -1055,9 +1068,7 @@ static int ub953_clkout_set_rate(struct clk_hw *hw, unsigned long rate, + dev_dbg(&priv->client->dev, "%s %lu (requested %lu)\n", __func__, + clkout_data.rate, rate); + +- ub953_write_clkout_regs(priv, &clkout_data); +- +- return 0; ++ return ub953_write_clkout_regs(priv, &clkout_data); + } + + static const struct clk_ops ub953_clkout_ops = { +@@ -1082,7 +1093,9 @@ static int ub953_register_clkout(struct ub953_data *priv) + + /* Initialize clkout to 25MHz by default */ + ub953_calc_clkout_params(priv, UB953_DEFAULT_CLKOUT_RATE, &clkout_data); +- ub953_write_clkout_regs(priv, &clkout_data); ++ ret = ub953_write_clkout_regs(priv, &clkout_data); ++ if (ret) ++ return ret; + + priv->clkout_clk_hw.init = &init; + +@@ -1229,10 +1242,15 @@ static int ub953_hw_init(struct ub953_data *priv) + if (ret) + return dev_err_probe(dev, ret, "i2c init failed\n"); + +- ub953_write(priv, UB953_REG_GENERAL_CFG, +- (priv->non_continous_clk ? 0 : UB953_REG_GENERAL_CFG_CONT_CLK) | +- ((priv->num_data_lanes - 1) << UB953_REG_GENERAL_CFG_CSI_LANE_SEL_SHIFT) | +- UB953_REG_GENERAL_CFG_CRC_TX_GEN_ENABLE); ++ v = 0; ++ v |= priv->non_continous_clk ? 0 : UB953_REG_GENERAL_CFG_CONT_CLK; ++ v |= (priv->num_data_lanes - 1) << ++ UB953_REG_GENERAL_CFG_CSI_LANE_SEL_SHIFT; ++ v |= UB953_REG_GENERAL_CFG_CRC_TX_GEN_ENABLE; ++ ++ ret = ub953_write(priv, UB953_REG_GENERAL_CFG, v); ++ if (ret) ++ return ret; + + return 0; + } +diff --git a/drivers/media/test-drivers/vidtv/vidtv_bridge.c b/drivers/media/test-drivers/vidtv/vidtv_bridge.c +index 8b04e12af286cc..6e030584d598a7 100644 +--- a/drivers/media/test-drivers/vidtv/vidtv_bridge.c ++++ b/drivers/media/test-drivers/vidtv/vidtv_bridge.c +@@ -191,10 +191,11 @@ static int vidtv_start_streaming(struct vidtv_dvb *dvb) + + mux_args.mux_buf_sz = mux_buf_sz; + +- dvb->streaming = true; + dvb->mux = vidtv_mux_init(dvb->fe[0], dev, &mux_args); + if (!dvb->mux) + return -ENOMEM; ++ ++ dvb->streaming = true; + vidtv_mux_start_thread(dvb->mux); + + dev_dbg_ratelimited(dev, "Started streaming\n"); +@@ -205,6 +206,11 @@ static int vidtv_stop_streaming(struct vidtv_dvb *dvb) + { + struct device *dev = &dvb->pdev->dev; + ++ if (!dvb->streaming) { ++ dev_warn_ratelimited(dev, "No streaming. Skipping.\n"); ++ return 0; ++ } ++ + dvb->streaming = false; + vidtv_mux_stop_thread(dvb->mux); + vidtv_mux_destroy(dvb->mux); +diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c +index 95c5b90f3e7c11..ae2e8bd2b3f73d 100644 +--- a/drivers/media/usb/uvc/uvc_driver.c ++++ b/drivers/media/usb/uvc/uvc_driver.c +@@ -2886,6 +2886,15 @@ static const struct usb_device_id uvc_ids[] = { + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = (kernel_ulong_t)&uvc_quirk_probe_minmax }, ++ /* Sonix Technology Co. Ltd. - 292A IPC AR0330 */ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x0c45, ++ .idProduct = 0x6366, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = 0, ++ .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_MJPEG_NO_EOF) }, + /* MT6227 */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, +@@ -2914,6 +2923,15 @@ static const struct usb_device_id uvc_ids[] = { + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = (kernel_ulong_t)&uvc_quirk_probe_minmax }, ++ /* Kurokesu C1 PRO */ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x16d0, ++ .idProduct = 0x0ed1, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = 0, ++ .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_MJPEG_NO_EOF) }, + /* Syntek (HP Spartan) */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, +diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c +index a2504e1e991b93..9572fdfe74f246 100644 +--- a/drivers/media/usb/uvc/uvc_video.c ++++ b/drivers/media/usb/uvc/uvc_video.c +@@ -20,6 +20,7 @@ + #include + #include + ++#include + #include + + #include "uvcvideo.h" +@@ -1114,6 +1115,7 @@ static void uvc_video_stats_stop(struct uvc_streaming *stream) + static int uvc_video_decode_start(struct uvc_streaming *stream, + struct uvc_buffer *buf, const u8 *data, int len) + { ++ u8 header_len; + u8 fid; + + /* +@@ -1127,6 +1129,7 @@ static int uvc_video_decode_start(struct uvc_streaming *stream, + return -EINVAL; + } + ++ header_len = data[0]; + fid = data[1] & UVC_STREAM_FID; + + /* +@@ -1208,9 +1211,31 @@ static int uvc_video_decode_start(struct uvc_streaming *stream, + return -EAGAIN; + } + ++ /* ++ * Some cameras, when running two parallel streams (one MJPEG alongside ++ * another non-MJPEG stream), are known to lose the EOF packet for a frame. ++ * We can detect the end of a frame by checking for a new SOI marker, as ++ * the SOI always lies on the packet boundary between two frames for ++ * these devices. ++ */ ++ if (stream->dev->quirks & UVC_QUIRK_MJPEG_NO_EOF && ++ (stream->cur_format->fcc == V4L2_PIX_FMT_MJPEG || ++ stream->cur_format->fcc == V4L2_PIX_FMT_JPEG)) { ++ const u8 *packet = data + header_len; ++ ++ if (len >= header_len + 2 && ++ packet[0] == 0xff && packet[1] == JPEG_MARKER_SOI && ++ buf->bytesused != 0) { ++ buf->state = UVC_BUF_STATE_READY; ++ buf->error = 1; ++ stream->last_fid ^= UVC_STREAM_FID; ++ return -EAGAIN; ++ } ++ } ++ + stream->last_fid = fid; + +- return data[0]; ++ return header_len; + } + + static inline enum dma_data_direction uvc_stream_dir( +diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h +index 997f4b5b5e22ac..30fd056b2aec9d 100644 +--- a/drivers/media/usb/uvc/uvcvideo.h ++++ b/drivers/media/usb/uvc/uvcvideo.h +@@ -76,6 +76,7 @@ + #define UVC_QUIRK_NO_RESET_RESUME 0x00004000 + #define UVC_QUIRK_DISABLE_AUTOSUSPEND 0x00008000 + #define UVC_QUIRK_INVALID_DEVICE_SOF 0x00010000 ++#define UVC_QUIRK_MJPEG_NO_EOF 0x00020000 + + /* Format flags */ + #define UVC_FMT_FLAG_COMPRESSED 0x00000001 +diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c +index 4f4b7607eaa9b1..02f3748e46c144 100644 +--- a/drivers/mmc/host/mtk-sd.c ++++ b/drivers/mmc/host/mtk-sd.c +@@ -260,6 +260,7 @@ + #define MSDC_PAD_TUNE_CMD_SEL BIT(21) /* RW */ + + #define PAD_DS_TUNE_DLY_SEL BIT(0) /* RW */ ++#define PAD_DS_TUNE_DLY2_SEL BIT(1) /* RW */ + #define PAD_DS_TUNE_DLY1 GENMASK(6, 2) /* RW */ + #define PAD_DS_TUNE_DLY2 GENMASK(11, 7) /* RW */ + #define PAD_DS_TUNE_DLY3 GENMASK(16, 12) /* RW */ +@@ -305,6 +306,7 @@ + + /* EMMC50_PAD_DS_TUNE mask */ + #define PAD_DS_DLY_SEL BIT(16) /* RW */ ++#define PAD_DS_DLY2_SEL BIT(15) /* RW */ + #define PAD_DS_DLY1 GENMASK(14, 10) /* RW */ + #define PAD_DS_DLY3 GENMASK(4, 0) /* RW */ + +@@ -2309,13 +2311,23 @@ static int msdc_execute_tuning(struct mmc_host *mmc, u32 opcode) + static int msdc_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios) + { + struct msdc_host *host = mmc_priv(mmc); ++ + host->hs400_mode = true; + +- if (host->top_base) +- writel(host->hs400_ds_delay, +- host->top_base + EMMC50_PAD_DS_TUNE); +- else +- writel(host->hs400_ds_delay, host->base + PAD_DS_TUNE); ++ if (host->top_base) { ++ if (host->hs400_ds_dly3) ++ sdr_set_field(host->top_base + EMMC50_PAD_DS_TUNE, ++ PAD_DS_DLY3, host->hs400_ds_dly3); ++ if (host->hs400_ds_delay) ++ writel(host->hs400_ds_delay, ++ host->top_base + EMMC50_PAD_DS_TUNE); ++ } else { ++ if (host->hs400_ds_dly3) ++ sdr_set_field(host->base + PAD_DS_TUNE, ++ PAD_DS_TUNE_DLY3, host->hs400_ds_dly3); ++ if (host->hs400_ds_delay) ++ writel(host->hs400_ds_delay, host->base + PAD_DS_TUNE); ++ } + /* hs400 mode must set it to 0 */ + sdr_clr_bits(host->base + MSDC_PATCH_BIT2, MSDC_PATCH_BIT2_CFGCRCSTS); + /* to improve read performance, set outstanding to 2 */ +@@ -2335,14 +2347,11 @@ static int msdc_execute_hs400_tuning(struct mmc_host *mmc, struct mmc_card *card + if (host->top_base) { + sdr_set_bits(host->top_base + EMMC50_PAD_DS_TUNE, + PAD_DS_DLY_SEL); +- if (host->hs400_ds_dly3) +- sdr_set_field(host->top_base + EMMC50_PAD_DS_TUNE, +- PAD_DS_DLY3, host->hs400_ds_dly3); ++ sdr_clr_bits(host->top_base + EMMC50_PAD_DS_TUNE, ++ PAD_DS_DLY2_SEL); + } else { + sdr_set_bits(host->base + PAD_DS_TUNE, PAD_DS_TUNE_DLY_SEL); +- if (host->hs400_ds_dly3) +- sdr_set_field(host->base + PAD_DS_TUNE, +- PAD_DS_TUNE_DLY3, host->hs400_ds_dly3); ++ sdr_clr_bits(host->base + PAD_DS_TUNE, PAD_DS_TUNE_DLY2_SEL); + } + + host->hs400_tuning = true; +diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c +index f44ba2600415f6..7f405bcf11c23e 100644 +--- a/drivers/net/can/c_can/c_can_platform.c ++++ b/drivers/net/can/c_can/c_can_platform.c +@@ -394,15 +394,16 @@ static int c_can_plat_probe(struct platform_device *pdev) + if (ret) { + dev_err(&pdev->dev, "registering %s failed (err=%d)\n", + KBUILD_MODNAME, ret); +- goto exit_free_device; ++ goto exit_pm_runtime; + } + + dev_info(&pdev->dev, "%s device registered (regs=%p, irq=%d)\n", + KBUILD_MODNAME, priv->base, dev->irq); + return 0; + +-exit_free_device: ++exit_pm_runtime: + pm_runtime_disable(priv->device); ++exit_free_device: + free_c_can_dev(dev); + exit: + dev_err(&pdev->dev, "probe failed\n"); +diff --git a/drivers/net/can/ctucanfd/ctucanfd_base.c b/drivers/net/can/ctucanfd/ctucanfd_base.c +index 64c349fd46007f..f65c1a1e05ccdf 100644 +--- a/drivers/net/can/ctucanfd/ctucanfd_base.c ++++ b/drivers/net/can/ctucanfd/ctucanfd_base.c +@@ -867,10 +867,12 @@ static void ctucan_err_interrupt(struct net_device *ndev, u32 isr) + } + break; + case CAN_STATE_ERROR_ACTIVE: +- cf->can_id |= CAN_ERR_CNT; +- cf->data[1] = CAN_ERR_CRTL_ACTIVE; +- cf->data[6] = bec.txerr; +- cf->data[7] = bec.rxerr; ++ if (skb) { ++ cf->can_id |= CAN_ERR_CNT; ++ cf->data[1] = CAN_ERR_CRTL_ACTIVE; ++ cf->data[6] = bec.txerr; ++ cf->data[7] = bec.rxerr; ++ } + break; + default: + netdev_warn(ndev, "unhandled error state (%d:%s)!\n", +diff --git a/drivers/net/can/usb/etas_es58x/es58x_devlink.c b/drivers/net/can/usb/etas_es58x/es58x_devlink.c +index 635edeb8f68cdf..e763a9904bedd0 100644 +--- a/drivers/net/can/usb/etas_es58x/es58x_devlink.c ++++ b/drivers/net/can/usb/etas_es58x/es58x_devlink.c +@@ -248,7 +248,11 @@ static int es58x_devlink_info_get(struct devlink *devlink, + return ret; + } + +- return devlink_info_serial_number_put(req, es58x_dev->udev->serial); ++ if (es58x_dev->udev->serial) ++ ret = devlink_info_serial_number_put(req, ++ es58x_dev->udev->serial); ++ ++ return ret; + } + + const struct devlink_ops es58x_dl_ops = { +diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c +index 91a4722460f66a..ae93b45cf55e8e 100644 +--- a/drivers/net/ethernet/intel/igc/igc_main.c ++++ b/drivers/net/ethernet/intel/igc/igc_main.c +@@ -1096,6 +1096,7 @@ static int igc_init_empty_frame(struct igc_ring *ring, + return -ENOMEM; + } + ++ buffer->type = IGC_TX_BUFFER_TYPE_SKB; + buffer->skb = skb; + buffer->protocol = 0; + buffer->bytecount = skb->len; +diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c +index 472830d07ac12e..13b5281d676b45 100644 +--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c +@@ -768,7 +768,9 @@ static void __mlxsw_sp_port_get_stats(struct net_device *dev, + err = mlxsw_sp_get_hw_stats_by_group(&hw_stats, &len, grp); + if (err) + return; +- mlxsw_sp_port_get_stats_raw(dev, grp, prio, ppcnt_pl); ++ err = mlxsw_sp_port_get_stats_raw(dev, grp, prio, ppcnt_pl); ++ if (err) ++ return; + for (i = 0; i < len; i++) { + data[data_index + i] = hw_stats[i].getter(ppcnt_pl); + if (!hw_stats[i].cells_bytes) +diff --git a/drivers/net/netdevsim/ipsec.c b/drivers/net/netdevsim/ipsec.c +index 3612b0633bd177..88187dd4eb2d40 100644 +--- a/drivers/net/netdevsim/ipsec.c ++++ b/drivers/net/netdevsim/ipsec.c +@@ -39,10 +39,14 @@ static ssize_t nsim_dbg_netdev_ops_read(struct file *filp, + if (!sap->used) + continue; + +- p += scnprintf(p, bufsize - (p - buf), +- "sa[%i] %cx ipaddr=0x%08x %08x %08x %08x\n", +- i, (sap->rx ? 'r' : 't'), sap->ipaddr[0], +- sap->ipaddr[1], sap->ipaddr[2], sap->ipaddr[3]); ++ if (sap->xs->props.family == AF_INET6) ++ p += scnprintf(p, bufsize - (p - buf), ++ "sa[%i] %cx ipaddr=%pI6c\n", ++ i, (sap->rx ? 'r' : 't'), &sap->ipaddr); ++ else ++ p += scnprintf(p, bufsize - (p - buf), ++ "sa[%i] %cx ipaddr=%pI4\n", ++ i, (sap->rx ? 'r' : 't'), &sap->ipaddr[3]); + p += scnprintf(p, bufsize - (p - buf), + "sa[%i] spi=0x%08x proto=0x%x salt=0x%08x crypt=%d\n", + i, be32_to_cpu(sap->xs->id.spi), +diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c +index 46a7c9fb6300e3..1ce3bccd4ebd4e 100644 +--- a/drivers/net/team/team.c ++++ b/drivers/net/team/team.c +@@ -2657,7 +2657,9 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info) + ctx.data.u32_val = nla_get_u32(attr_data); + break; + case TEAM_OPTION_TYPE_STRING: +- if (nla_len(attr_data) > TEAM_STRING_MAX_LEN) { ++ if (nla_len(attr_data) > TEAM_STRING_MAX_LEN || ++ !memchr(nla_data(attr_data), '\0', ++ nla_len(attr_data))) { + err = -EINVAL; + goto team_put; + } +diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c +index ee02a92338da1b..64db3e98a1b664 100644 +--- a/drivers/net/vxlan/vxlan_core.c ++++ b/drivers/net/vxlan/vxlan_core.c +@@ -2966,8 +2966,11 @@ static int vxlan_init(struct net_device *dev) + struct vxlan_dev *vxlan = netdev_priv(dev); + int err; + +- if (vxlan->cfg.flags & VXLAN_F_VNIFILTER) +- vxlan_vnigroup_init(vxlan); ++ if (vxlan->cfg.flags & VXLAN_F_VNIFILTER) { ++ err = vxlan_vnigroup_init(vxlan); ++ if (err) ++ return err; ++ } + + dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); + if (!dev->tstats) { +diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c +index 9105fdd14c6671..c977dfbae0a464 100644 +--- a/drivers/net/wireless/ath/ath12k/wmi.c ++++ b/drivers/net/wireless/ath/ath12k/wmi.c +@@ -4418,6 +4418,22 @@ static struct ath12k_reg_rule + return reg_rule_ptr; + } + ++static u8 ath12k_wmi_ignore_num_extra_rules(struct ath12k_wmi_reg_rule_ext_params *rule, ++ u32 num_reg_rules) ++{ ++ u8 num_invalid_5ghz_rules = 0; ++ u32 count, start_freq; ++ ++ for (count = 0; count < num_reg_rules; count++) { ++ start_freq = le32_get_bits(rule[count].freq_info, REG_RULE_START_FREQ); ++ ++ if (start_freq >= ATH12K_MIN_6G_FREQ) ++ num_invalid_5ghz_rules++; ++ } ++ ++ return num_invalid_5ghz_rules; ++} ++ + static int ath12k_pull_reg_chan_list_ext_update_ev(struct ath12k_base *ab, + struct sk_buff *skb, + struct ath12k_reg_info *reg_info) +@@ -4428,6 +4444,7 @@ static int ath12k_pull_reg_chan_list_ext_update_ev(struct ath12k_base *ab, + u32 num_2g_reg_rules, num_5g_reg_rules; + u32 num_6g_reg_rules_ap[WMI_REG_CURRENT_MAX_AP_TYPE]; + u32 num_6g_reg_rules_cl[WMI_REG_CURRENT_MAX_AP_TYPE][WMI_REG_MAX_CLIENT_TYPE]; ++ u8 num_invalid_5ghz_ext_rules; + u32 total_reg_rules = 0; + int ret, i, j; + +@@ -4521,20 +4538,6 @@ static int ath12k_pull_reg_chan_list_ext_update_ev(struct ath12k_base *ab, + + memcpy(reg_info->alpha2, &ev->alpha2, REG_ALPHA2_LEN); + +- /* FIXME: Currently FW includes 6G reg rule also in 5G rule +- * list for country US. +- * Having same 6G reg rule in 5G and 6G rules list causes +- * intersect check to be true, and same rules will be shown +- * multiple times in iw cmd. So added hack below to avoid +- * parsing 6G rule from 5G reg rule list, and this can be +- * removed later, after FW updates to remove 6G reg rule +- * from 5G rules list. +- */ +- if (memcmp(reg_info->alpha2, "US", 2) == 0) { +- reg_info->num_5g_reg_rules = REG_US_5G_NUM_REG_RULES; +- num_5g_reg_rules = reg_info->num_5g_reg_rules; +- } +- + reg_info->dfs_region = le32_to_cpu(ev->dfs_region); + reg_info->phybitmap = le32_to_cpu(ev->phybitmap); + reg_info->num_phy = le32_to_cpu(ev->num_phy); +@@ -4636,8 +4639,29 @@ static int ath12k_pull_reg_chan_list_ext_update_ev(struct ath12k_base *ab, + } + } + ++ ext_wmi_reg_rule += num_2g_reg_rules; ++ ++ /* Firmware might include 6 GHz reg rule in 5 GHz rule list ++ * for few countries along with separate 6 GHz rule. ++ * Having same 6 GHz reg rule in 5 GHz and 6 GHz rules list ++ * causes intersect check to be true, and same rules will be ++ * shown multiple times in iw cmd. ++ * Hence, avoid parsing 6 GHz rule from 5 GHz reg rule list ++ */ ++ num_invalid_5ghz_ext_rules = ath12k_wmi_ignore_num_extra_rules(ext_wmi_reg_rule, ++ num_5g_reg_rules); ++ ++ if (num_invalid_5ghz_ext_rules) { ++ ath12k_dbg(ab, ATH12K_DBG_WMI, ++ "CC: %s 5 GHz reg rules number %d from fw, %d number of invalid 5 GHz rules", ++ reg_info->alpha2, reg_info->num_5g_reg_rules, ++ num_invalid_5ghz_ext_rules); ++ ++ num_5g_reg_rules = num_5g_reg_rules - num_invalid_5ghz_ext_rules; ++ reg_info->num_5g_reg_rules = num_5g_reg_rules; ++ } ++ + if (num_5g_reg_rules) { +- ext_wmi_reg_rule += num_2g_reg_rules; + reg_info->reg_rules_5g_ptr = + create_ext_reg_rules_from_wmi(num_5g_reg_rules, + ext_wmi_reg_rule); +@@ -4649,7 +4673,12 @@ static int ath12k_pull_reg_chan_list_ext_update_ev(struct ath12k_base *ab, + } + } + +- ext_wmi_reg_rule += num_5g_reg_rules; ++ /* We have adjusted the number of 5 GHz reg rules above. But still those ++ * many rules needs to be adjusted in ext_wmi_reg_rule. ++ * ++ * NOTE: num_invalid_5ghz_ext_rules will be 0 for rest other cases. ++ */ ++ ext_wmi_reg_rule += (num_5g_reg_rules + num_invalid_5ghz_ext_rules); + + for (i = 0; i < WMI_REG_CURRENT_MAX_AP_TYPE; i++) { + reg_info->reg_rules_6g_ap_ptr[i] = +diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h +index a19a2c29f2264a..4cfcc83f52269b 100644 +--- a/drivers/net/wireless/ath/ath12k/wmi.h ++++ b/drivers/net/wireless/ath/ath12k/wmi.h +@@ -3891,7 +3891,6 @@ struct ath12k_wmi_eht_rate_set_params { + #define MAX_REG_RULES 10 + #define REG_ALPHA2_LEN 2 + #define MAX_6G_REG_RULES 5 +-#define REG_US_5G_NUM_REG_RULES 4 + + enum wmi_start_event_param { + WMI_VDEV_START_RESP_EVENT = 0, +diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c +index fd35ad0648a07b..70f484b811dea7 100644 +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -5978,6 +5978,17 @@ SWITCHTEC_QUIRK(0x5552); /* PAXA 52XG5 */ + SWITCHTEC_QUIRK(0x5536); /* PAXA 36XG5 */ + SWITCHTEC_QUIRK(0x5528); /* PAXA 28XG5 */ + ++#define SWITCHTEC_PCI100X_QUIRK(vid) \ ++ DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_EFAR, vid, \ ++ PCI_CLASS_BRIDGE_OTHER, 8, quirk_switchtec_ntb_dma_alias) ++SWITCHTEC_PCI100X_QUIRK(0x1001); /* PCI1001XG4 */ ++SWITCHTEC_PCI100X_QUIRK(0x1002); /* PCI1002XG4 */ ++SWITCHTEC_PCI100X_QUIRK(0x1003); /* PCI1003XG4 */ ++SWITCHTEC_PCI100X_QUIRK(0x1004); /* PCI1004XG4 */ ++SWITCHTEC_PCI100X_QUIRK(0x1005); /* PCI1005XG4 */ ++SWITCHTEC_PCI100X_QUIRK(0x1006); /* PCI1006XG4 */ ++ ++ + /* + * The PLX NTB uses devfn proxy IDs to move TLPs between NT endpoints. + * These IDs are used to forward responses to the originator on the other +@@ -6247,6 +6258,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a2b, dpc_log_size); + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a2d, dpc_log_size); + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a2f, dpc_log_size); + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a31, dpc_log_size); ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0xa72f, dpc_log_size); + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0xa73f, dpc_log_size); + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0xa76e, dpc_log_size); + #endif +diff --git a/drivers/pci/switch/switchtec.c b/drivers/pci/switch/switchtec.c +index 5a4adf6c04cf89..455fa5035a2450 100644 +--- a/drivers/pci/switch/switchtec.c ++++ b/drivers/pci/switch/switchtec.c +@@ -1737,6 +1737,26 @@ static void switchtec_pci_remove(struct pci_dev *pdev) + .driver_data = gen, \ + } + ++#define SWITCHTEC_PCI100X_DEVICE(device_id, gen) \ ++ { \ ++ .vendor = PCI_VENDOR_ID_EFAR, \ ++ .device = device_id, \ ++ .subvendor = PCI_ANY_ID, \ ++ .subdevice = PCI_ANY_ID, \ ++ .class = (PCI_CLASS_MEMORY_OTHER << 8), \ ++ .class_mask = 0xFFFFFFFF, \ ++ .driver_data = gen, \ ++ }, \ ++ { \ ++ .vendor = PCI_VENDOR_ID_EFAR, \ ++ .device = device_id, \ ++ .subvendor = PCI_ANY_ID, \ ++ .subdevice = PCI_ANY_ID, \ ++ .class = (PCI_CLASS_BRIDGE_OTHER << 8), \ ++ .class_mask = 0xFFFFFFFF, \ ++ .driver_data = gen, \ ++ } ++ + static const struct pci_device_id switchtec_pci_tbl[] = { + SWITCHTEC_PCI_DEVICE(0x8531, SWITCHTEC_GEN3), /* PFX 24xG3 */ + SWITCHTEC_PCI_DEVICE(0x8532, SWITCHTEC_GEN3), /* PFX 32xG3 */ +@@ -1831,6 +1851,12 @@ static const struct pci_device_id switchtec_pci_tbl[] = { + SWITCHTEC_PCI_DEVICE(0x5552, SWITCHTEC_GEN5), /* PAXA 52XG5 */ + SWITCHTEC_PCI_DEVICE(0x5536, SWITCHTEC_GEN5), /* PAXA 36XG5 */ + SWITCHTEC_PCI_DEVICE(0x5528, SWITCHTEC_GEN5), /* PAXA 28XG5 */ ++ SWITCHTEC_PCI100X_DEVICE(0x1001, SWITCHTEC_GEN4), /* PCI1001 16XG4 */ ++ SWITCHTEC_PCI100X_DEVICE(0x1002, SWITCHTEC_GEN4), /* PCI1002 12XG4 */ ++ SWITCHTEC_PCI100X_DEVICE(0x1003, SWITCHTEC_GEN4), /* PCI1003 16XG4 */ ++ SWITCHTEC_PCI100X_DEVICE(0x1004, SWITCHTEC_GEN4), /* PCI1004 16XG4 */ ++ SWITCHTEC_PCI100X_DEVICE(0x1005, SWITCHTEC_GEN4), /* PCI1005 16XG4 */ ++ SWITCHTEC_PCI100X_DEVICE(0x1006, SWITCHTEC_GEN4), /* PCI1006 16XG4 */ + {0} + }; + MODULE_DEVICE_TABLE(pci, switchtec_pci_tbl); +diff --git a/drivers/pinctrl/pinctrl-cy8c95x0.c b/drivers/pinctrl/pinctrl-cy8c95x0.c +index f2b9db66fdb6a4..d2488d80912c9f 100644 +--- a/drivers/pinctrl/pinctrl-cy8c95x0.c ++++ b/drivers/pinctrl/pinctrl-cy8c95x0.c +@@ -1281,7 +1281,7 @@ static int cy8c95x0_irq_setup(struct cy8c95x0_pinctrl *chip, int irq) + + ret = devm_request_threaded_irq(chip->dev, irq, + NULL, cy8c95x0_irq_handler, +- IRQF_ONESHOT | IRQF_SHARED | IRQF_TRIGGER_HIGH, ++ IRQF_ONESHOT | IRQF_SHARED, + dev_name(chip->dev), chip); + if (ret) { + dev_err(chip->dev, "failed to request irq %d\n", irq); +diff --git a/drivers/soc/tegra/fuse/fuse-tegra30.c b/drivers/soc/tegra/fuse/fuse-tegra30.c +index e94d46372a6396..402cf939c03263 100644 +--- a/drivers/soc/tegra/fuse/fuse-tegra30.c ++++ b/drivers/soc/tegra/fuse/fuse-tegra30.c +@@ -646,15 +646,20 @@ static const struct nvmem_cell_lookup tegra234_fuse_lookups[] = { + }; + + static const struct nvmem_keepout tegra234_fuse_keepouts[] = { +- { .start = 0x01c, .end = 0x0c8 }, +- { .start = 0x12c, .end = 0x184 }, ++ { .start = 0x01c, .end = 0x064 }, ++ { .start = 0x084, .end = 0x0a0 }, ++ { .start = 0x0a4, .end = 0x0c8 }, ++ { .start = 0x12c, .end = 0x164 }, ++ { .start = 0x16c, .end = 0x184 }, + { .start = 0x190, .end = 0x198 }, + { .start = 0x1a0, .end = 0x204 }, +- { .start = 0x21c, .end = 0x250 }, +- { .start = 0x25c, .end = 0x2f0 }, ++ { .start = 0x21c, .end = 0x2f0 }, + { .start = 0x310, .end = 0x3d8 }, +- { .start = 0x400, .end = 0x4f0 }, +- { .start = 0x4f8, .end = 0x7e8 }, ++ { .start = 0x400, .end = 0x420 }, ++ { .start = 0x444, .end = 0x490 }, ++ { .start = 0x4bc, .end = 0x4f0 }, ++ { .start = 0x4f8, .end = 0x54c }, ++ { .start = 0x57c, .end = 0x7e8 }, + { .start = 0x8d0, .end = 0x8d8 }, + { .start = 0xacc, .end = 0xf00 } + }; +diff --git a/drivers/spi/spi-sn-f-ospi.c b/drivers/spi/spi-sn-f-ospi.c +index a7c3b3923b4af7..fd8c8eb37d01d6 100644 +--- a/drivers/spi/spi-sn-f-ospi.c ++++ b/drivers/spi/spi-sn-f-ospi.c +@@ -116,6 +116,9 @@ struct f_ospi { + + static u32 f_ospi_get_dummy_cycle(const struct spi_mem_op *op) + { ++ if (!op->dummy.nbytes) ++ return 0; ++ + return (op->dummy.nbytes * 8) / op->dummy.buswidth; + } + +diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h +index 1aa3e55c8b47da..f76c9ecc51bcd6 100644 +--- a/drivers/tty/serial/8250/8250.h ++++ b/drivers/tty/serial/8250/8250.h +@@ -350,6 +350,7 @@ static inline int is_omap1510_8250(struct uart_8250_port *pt) + + #ifdef CONFIG_SERIAL_8250_DMA + extern int serial8250_tx_dma(struct uart_8250_port *); ++extern void serial8250_tx_dma_flush(struct uart_8250_port *); + extern int serial8250_rx_dma(struct uart_8250_port *); + extern void serial8250_rx_dma_flush(struct uart_8250_port *); + extern int serial8250_request_dma(struct uart_8250_port *); +@@ -382,6 +383,7 @@ static inline int serial8250_tx_dma(struct uart_8250_port *p) + { + return -1; + } ++static inline void serial8250_tx_dma_flush(struct uart_8250_port *p) { } + static inline int serial8250_rx_dma(struct uart_8250_port *p) + { + return -1; +diff --git a/drivers/tty/serial/8250/8250_dma.c b/drivers/tty/serial/8250/8250_dma.c +index 7fa66501792dd8..7f23037813bc85 100644 +--- a/drivers/tty/serial/8250/8250_dma.c ++++ b/drivers/tty/serial/8250/8250_dma.c +@@ -139,6 +139,22 @@ int serial8250_tx_dma(struct uart_8250_port *p) + return ret; + } + ++void serial8250_tx_dma_flush(struct uart_8250_port *p) ++{ ++ struct uart_8250_dma *dma = p->dma; ++ ++ if (!dma->tx_running) ++ return; ++ ++ /* ++ * kfifo_reset() has been called by the serial core, avoid ++ * advancing and underflowing in __dma_tx_complete(). ++ */ ++ dma->tx_size = 0; ++ ++ dmaengine_terminate_async(dma->rxchan); ++} ++ + int serial8250_rx_dma(struct uart_8250_port *p) + { + struct uart_8250_dma *dma = p->dma; +diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c +index 2b1b2928ef7b7c..c2778300e15100 100644 +--- a/drivers/tty/serial/8250/8250_port.c ++++ b/drivers/tty/serial/8250/8250_port.c +@@ -2557,6 +2557,14 @@ static unsigned int npcm_get_divisor(struct uart_8250_port *up, + return DIV_ROUND_CLOSEST(port->uartclk, 16 * baud + 2) - 2; + } + ++static void serial8250_flush_buffer(struct uart_port *port) ++{ ++ struct uart_8250_port *up = up_to_u8250p(port); ++ ++ if (up->dma) ++ serial8250_tx_dma_flush(up); ++} ++ + static unsigned int serial8250_do_get_divisor(struct uart_port *port, + unsigned int baud, + unsigned int *frac) +@@ -3260,6 +3268,7 @@ static const struct uart_ops serial8250_pops = { + .break_ctl = serial8250_break_ctl, + .startup = serial8250_startup, + .shutdown = serial8250_shutdown, ++ .flush_buffer = serial8250_flush_buffer, + .set_termios = serial8250_set_termios, + .set_ldisc = serial8250_set_ldisc, + .pm = serial8250_pm, +diff --git a/drivers/tty/serial/serial_port.c b/drivers/tty/serial/serial_port.c +index 469ad26cde4870..a21c287077039d 100644 +--- a/drivers/tty/serial/serial_port.c ++++ b/drivers/tty/serial/serial_port.c +@@ -172,6 +172,7 @@ EXPORT_SYMBOL(uart_remove_one_port); + * The caller is responsible to initialize the following fields of the @port + * ->dev (must be valid) + * ->flags ++ * ->iobase + * ->mapbase + * ->mapsize + * ->regshift (if @use_defaults is false) +@@ -213,7 +214,7 @@ static int __uart_read_properties(struct uart_port *port, bool use_defaults) + /* Read the registers I/O access type (default: MMIO 8-bit) */ + ret = device_property_read_u32(dev, "reg-io-width", &value); + if (ret) { +- port->iotype = UPIO_MEM; ++ port->iotype = port->iobase ? UPIO_PORT : UPIO_MEM; + } else { + switch (value) { + case 1: +@@ -226,11 +227,11 @@ static int __uart_read_properties(struct uart_port *port, bool use_defaults) + port->iotype = device_is_big_endian(dev) ? UPIO_MEM32BE : UPIO_MEM32; + break; + default: ++ port->iotype = UPIO_UNKNOWN; + if (!use_defaults) { + dev_err(dev, "Unsupported reg-io-width (%u)\n", value); + return -EINVAL; + } +- port->iotype = UPIO_UNKNOWN; + break; + } + } +diff --git a/drivers/ufs/core/ufs_bsg.c b/drivers/ufs/core/ufs_bsg.c +index f21423a7a6d7db..8fbd46cd8c2b8e 100644 +--- a/drivers/ufs/core/ufs_bsg.c ++++ b/drivers/ufs/core/ufs_bsg.c +@@ -216,6 +216,7 @@ void ufs_bsg_remove(struct ufs_hba *hba) + return; + + bsg_remove_queue(hba->bsg_queue); ++ hba->bsg_queue = NULL; + + device_del(bsg_dev); + put_device(bsg_dev); +diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c +index 605fea4611029b..c1d7d87b32cc5a 100644 +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -371,7 +371,7 @@ static void acm_process_notification(struct acm *acm, unsigned char *buf) + static void acm_ctrl_irq(struct urb *urb) + { + struct acm *acm = urb->context; +- struct usb_cdc_notification *dr = urb->transfer_buffer; ++ struct usb_cdc_notification *dr; + unsigned int current_size = urb->actual_length; + unsigned int expected_size, copy_size, alloc_size; + int retval; +@@ -398,14 +398,25 @@ static void acm_ctrl_irq(struct urb *urb) + + usb_mark_last_busy(acm->dev); + +- if (acm->nb_index) ++ if (acm->nb_index == 0) { ++ /* ++ * The first chunk of a message must contain at least the ++ * notification header with the length field, otherwise we ++ * can't get an expected_size. ++ */ ++ if (current_size < sizeof(struct usb_cdc_notification)) { ++ dev_dbg(&acm->control->dev, "urb too short\n"); ++ goto exit; ++ } ++ dr = urb->transfer_buffer; ++ } else { + dr = (struct usb_cdc_notification *)acm->notification_buffer; +- ++ } + /* size = notification-header + (optional) data */ + expected_size = sizeof(struct usb_cdc_notification) + + le16_to_cpu(dr->wLength); + +- if (current_size < expected_size) { ++ if (acm->nb_index != 0 || current_size < expected_size) { + /* notification is transmitted fragmented, reassemble */ + if (acm->nb_size < expected_size) { + u8 *new_buffer; +@@ -1727,13 +1738,16 @@ static const struct usb_device_id acm_ids[] = { + { USB_DEVICE(0x0870, 0x0001), /* Metricom GS Modem */ + .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ + }, +- { USB_DEVICE(0x045b, 0x023c), /* Renesas USB Download mode */ ++ { USB_DEVICE(0x045b, 0x023c), /* Renesas R-Car H3 USB Download mode */ ++ .driver_info = DISABLE_ECHO, /* Don't echo banner */ ++ }, ++ { USB_DEVICE(0x045b, 0x0247), /* Renesas R-Car D3 USB Download mode */ + .driver_info = DISABLE_ECHO, /* Don't echo banner */ + }, +- { USB_DEVICE(0x045b, 0x0248), /* Renesas USB Download mode */ ++ { USB_DEVICE(0x045b, 0x0248), /* Renesas R-Car M3-N USB Download mode */ + .driver_info = DISABLE_ECHO, /* Don't echo banner */ + }, +- { USB_DEVICE(0x045b, 0x024D), /* Renesas USB Download mode */ ++ { USB_DEVICE(0x045b, 0x024D), /* Renesas R-Car E3 USB Download mode */ + .driver_info = DISABLE_ECHO, /* Don't echo banner */ + }, + { USB_DEVICE(0x0e8d, 0x0003), /* FIREFLY, MediaTek Inc; andrey.arapov@gmail.com */ +diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c +index 0944cfae8b5567..38f3f5a766dfdf 100644 +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -1818,6 +1818,17 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) + desc = intf->cur_altsetting; + hdev = interface_to_usbdev(intf); + ++ /* ++ * The USB 2.0 spec prohibits hubs from having more than one ++ * configuration or interface, and we rely on this prohibition. ++ * Refuse to accept a device that violates it. ++ */ ++ if (hdev->descriptor.bNumConfigurations > 1 || ++ hdev->actconfig->desc.bNumInterfaces > 1) { ++ dev_err(&intf->dev, "Invalid hub with more than one config or interface\n"); ++ return -EINVAL; ++ } ++ + /* + * Set default autosuspend delay as 0 to speedup bus suspend, + * based on the below considerations: +@@ -4666,7 +4677,6 @@ void usb_ep0_reinit(struct usb_device *udev) + EXPORT_SYMBOL_GPL(usb_ep0_reinit); + + #define usb_sndaddr0pipe() (PIPE_CONTROL << 30) +-#define usb_rcvaddr0pipe() ((PIPE_CONTROL << 30) | USB_DIR_IN) + + static int hub_set_address(struct usb_device *udev, int devnum) + { +@@ -4772,7 +4782,7 @@ static int get_bMaxPacketSize0(struct usb_device *udev, + for (i = 0; i < GET_MAXPACKET0_TRIES; ++i) { + /* Start with invalid values in case the transfer fails */ + buf->bDescriptorType = buf->bMaxPacketSize0 = 0; +- rc = usb_control_msg(udev, usb_rcvaddr0pipe(), ++ rc = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, + USB_DT_DEVICE << 8, 0, + buf, size, +diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c +index 13171454f9591a..027479179f09e9 100644 +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -432,6 +432,9 @@ static const struct usb_device_id usb_quirk_list[] = { + { USB_DEVICE(0x0c45, 0x7056), .driver_info = + USB_QUIRK_IGNORE_REMOTE_WAKEUP }, + ++ /* Sony Xperia XZ1 Compact (lilac) smartphone in fastboot mode */ ++ { USB_DEVICE(0x0fce, 0x0dde), .driver_info = USB_QUIRK_NO_LPM }, ++ + /* Action Semiconductor flash disk */ + { USB_DEVICE(0x10d6, 0x2200), .driver_info = + USB_QUIRK_STRING_FETCH_255 }, +@@ -522,6 +525,9 @@ static const struct usb_device_id usb_quirk_list[] = { + /* Blackmagic Design UltraStudio SDI */ + { USB_DEVICE(0x1edb, 0xbd4f), .driver_info = USB_QUIRK_NO_LPM }, + ++ /* Teclast disk */ ++ { USB_DEVICE(0x1f75, 0x0917), .driver_info = USB_QUIRK_NO_LPM }, ++ + /* Hauppauge HVR-950q */ + { USB_DEVICE(0x2040, 0x7200), .driver_info = + USB_QUIRK_CONFIG_INTF_STRINGS }, +diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c +index b26de09f6b6d5e..ce20c06a902531 100644 +--- a/drivers/usb/dwc2/gadget.c ++++ b/drivers/usb/dwc2/gadget.c +@@ -4612,6 +4612,7 @@ static int dwc2_hsotg_udc_stop(struct usb_gadget *gadget) + spin_lock_irqsave(&hsotg->lock, flags); + + hsotg->driver = NULL; ++ hsotg->gadget.dev.of_node = NULL; + hsotg->gadget.speed = USB_SPEED_UNKNOWN; + hsotg->enabled = 0; + +diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c +index 9b8099cba41429..f6d9a9c67db4e2 100644 +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -2618,10 +2618,38 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on) + { + u32 reg; + u32 timeout = 2000; ++ u32 saved_config = 0; + + if (pm_runtime_suspended(dwc->dev)) + return 0; + ++ /* ++ * When operating in USB 2.0 speeds (HS/FS), ensure that ++ * GUSB2PHYCFG.ENBLSLPM and GUSB2PHYCFG.SUSPHY are cleared before starting ++ * or stopping the controller. This resolves timeout issues that occur ++ * during frequent role switches between host and device modes. ++ * ++ * Save and clear these settings, then restore them after completing the ++ * controller start or stop sequence. ++ * ++ * This solution was discovered through experimentation as it is not ++ * mentioned in the dwc3 programming guide. It has been tested on an ++ * Exynos platforms. ++ */ ++ reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); ++ if (reg & DWC3_GUSB2PHYCFG_SUSPHY) { ++ saved_config |= DWC3_GUSB2PHYCFG_SUSPHY; ++ reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; ++ } ++ ++ if (reg & DWC3_GUSB2PHYCFG_ENBLSLPM) { ++ saved_config |= DWC3_GUSB2PHYCFG_ENBLSLPM; ++ reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM; ++ } ++ ++ if (saved_config) ++ dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); ++ + reg = dwc3_readl(dwc->regs, DWC3_DCTL); + if (is_on) { + if (DWC3_VER_IS_WITHIN(DWC3, ANY, 187A)) { +@@ -2649,6 +2677,12 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on) + reg &= DWC3_DSTS_DEVCTRLHLT; + } while (--timeout && !(!is_on ^ !reg)); + ++ if (saved_config) { ++ reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); ++ reg |= saved_config; ++ dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); ++ } ++ + if (!timeout) + return -ETIMEDOUT; + +diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c +index 2d02f25f959791..49946af11a9058 100644 +--- a/drivers/usb/gadget/function/f_midi.c ++++ b/drivers/usb/gadget/function/f_midi.c +@@ -906,6 +906,15 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f) + + status = -ENODEV; + ++ /* ++ * Reset wMaxPacketSize with maximum packet size of FS bulk transfer before ++ * endpoint claim. This ensures that the wMaxPacketSize does not exceed the ++ * limit during bind retries where configured dwc3 TX/RX FIFO's maxpacket ++ * size of 512 bytes for IN/OUT endpoints in support HS speed only. ++ */ ++ bulk_in_desc.wMaxPacketSize = cpu_to_le16(64); ++ bulk_out_desc.wMaxPacketSize = cpu_to_le16(64); ++ + /* allocate instance-specific endpoints */ + midi->in_ep = usb_ep_autoconfig(cdev->gadget, &bulk_in_desc); + if (!midi->in_ep) +@@ -999,11 +1008,11 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f) + } + + /* configure the endpoint descriptors ... */ +- ms_out_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->in_ports); +- ms_out_desc.bNumEmbMIDIJack = midi->in_ports; ++ ms_out_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->out_ports); ++ ms_out_desc.bNumEmbMIDIJack = midi->out_ports; + +- ms_in_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->out_ports); +- ms_in_desc.bNumEmbMIDIJack = midi->out_ports; ++ ms_in_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->in_ports); ++ ms_in_desc.bNumEmbMIDIJack = midi->in_ports; + + /* ... and add them to the list */ + endpoint_descriptor_index = i; +diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c +index 3b01734ce1b7e5..a93ad93390ba17 100644 +--- a/drivers/usb/gadget/udc/renesas_usb3.c ++++ b/drivers/usb/gadget/udc/renesas_usb3.c +@@ -310,7 +310,7 @@ struct renesas_usb3_request { + struct list_head queue; + }; + +-#define USB3_EP_NAME_SIZE 8 ++#define USB3_EP_NAME_SIZE 16 + struct renesas_usb3_ep { + struct usb_ep ep; + struct renesas_usb3 *usb3; +diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c +index 2665832f9addff..b96d9062a0837a 100644 +--- a/drivers/usb/host/pci-quirks.c ++++ b/drivers/usb/host/pci-quirks.c +@@ -946,6 +946,15 @@ static void quirk_usb_disable_ehci(struct pci_dev *pdev) + * booting from USB disk or using a usb keyboard + */ + hcc_params = readl(base + EHCI_HCC_PARAMS); ++ ++ /* LS7A EHCI controller doesn't have extended capabilities, the ++ * EECP (EHCI Extended Capabilities Pointer) field of HCCPARAMS ++ * register should be 0x0 but it reads as 0xa0. So clear it to ++ * avoid error messages on boot. ++ */ ++ if (pdev->vendor == PCI_VENDOR_ID_LOONGSON && pdev->device == 0x7a14) ++ hcc_params &= ~(0xffL << 8); ++ + offset = (hcc_params >> 8) & 0xff; + while (offset && --count) { + pci_read_config_dword(pdev, offset, &cap); +diff --git a/drivers/usb/roles/class.c b/drivers/usb/roles/class.c +index 70165dd86b5de9..8664449ca2ff8a 100644 +--- a/drivers/usb/roles/class.c ++++ b/drivers/usb/roles/class.c +@@ -355,14 +355,15 @@ usb_role_switch_register(struct device *parent, + dev_set_name(&sw->dev, "%s-role-switch", + desc->name ? desc->name : dev_name(parent)); + ++ sw->registered = true; ++ + ret = device_register(&sw->dev); + if (ret) { ++ sw->registered = false; + put_device(&sw->dev); + return ERR_PTR(ret); + } + +- sw->registered = true; +- + /* TODO: Symlinks for the host port and the device controller. */ + + return sw; +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index 86ac20e2874bab..37ff48702e43e1 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -619,15 +619,6 @@ static void option_instat_callback(struct urb *urb); + /* Luat Air72*U series based on UNISOC UIS8910 uses UNISOC's vendor ID */ + #define LUAT_PRODUCT_AIR720U 0x4e00 + +-/* MeiG Smart Technology products */ +-#define MEIGSMART_VENDOR_ID 0x2dee +-/* MeiG Smart SRM815/SRM825L based on Qualcomm 315 */ +-#define MEIGSMART_PRODUCT_SRM825L 0x4d22 +-/* MeiG Smart SLM320 based on UNISOC UIS8910 */ +-#define MEIGSMART_PRODUCT_SLM320 0x4d41 +-/* MeiG Smart SLM770A based on ASR1803 */ +-#define MEIGSMART_PRODUCT_SLM770A 0x4d57 +- + /* Device flags */ + + /* Highest interface number which can be used with NCTRL() and RSVD() */ +@@ -1367,15 +1358,15 @@ static const struct usb_device_id option_ids[] = { + .driver_info = NCTRL(2) | RSVD(3) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1063, 0xff), /* Telit LN920 (ECM) */ + .driver_info = NCTRL(0) | RSVD(1) }, +- { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1070, 0xff), /* Telit FN990 (rmnet) */ ++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1070, 0xff), /* Telit FN990A (rmnet) */ + .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) }, +- { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1071, 0xff), /* Telit FN990 (MBIM) */ ++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1071, 0xff), /* Telit FN990A (MBIM) */ + .driver_info = NCTRL(0) | RSVD(1) }, +- { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1072, 0xff), /* Telit FN990 (RNDIS) */ ++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1072, 0xff), /* Telit FN990A (RNDIS) */ + .driver_info = NCTRL(2) | RSVD(3) }, +- { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1073, 0xff), /* Telit FN990 (ECM) */ ++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1073, 0xff), /* Telit FN990A (ECM) */ + .driver_info = NCTRL(0) | RSVD(1) }, +- { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1075, 0xff), /* Telit FN990 (PCIe) */ ++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1075, 0xff), /* Telit FN990A (PCIe) */ + .driver_info = RSVD(0) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1080, 0xff), /* Telit FE990 (rmnet) */ + .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) }, +@@ -1403,6 +1394,22 @@ static const struct usb_device_id option_ids[] = { + .driver_info = RSVD(0) | NCTRL(3) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10c8, 0xff), /* Telit FE910C04 (rmnet) */ + .driver_info = RSVD(0) | NCTRL(2) | RSVD(3) | RSVD(4) }, ++ { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d0, 0x60) }, /* Telit FN990B (rmnet) */ ++ { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d0, 0x40) }, ++ { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d0, 0x30), ++ .driver_info = NCTRL(5) }, ++ { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d1, 0x60) }, /* Telit FN990B (MBIM) */ ++ { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d1, 0x40) }, ++ { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d1, 0x30), ++ .driver_info = NCTRL(6) }, ++ { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d2, 0x60) }, /* Telit FN990B (RNDIS) */ ++ { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d2, 0x40) }, ++ { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d2, 0x30), ++ .driver_info = NCTRL(6) }, ++ { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d3, 0x60) }, /* Telit FN990B (ECM) */ ++ { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d3, 0x40) }, ++ { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d3, 0x30), ++ .driver_info = NCTRL(6) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910), + .driver_info = NCTRL(0) | RSVD(1) | RSVD(3) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM), +@@ -2347,6 +2354,14 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a05, 0xff) }, /* Fibocom FM650-CN (NCM mode) */ + { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a06, 0xff) }, /* Fibocom FM650-CN (RNDIS mode) */ + { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a07, 0xff) }, /* Fibocom FM650-CN (MBIM mode) */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d41, 0xff, 0, 0) }, /* MeiG Smart SLM320 */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d57, 0xff, 0, 0) }, /* MeiG Smart SLM770A */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0, 0) }, /* MeiG Smart SRM815 */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0x10, 0x02) }, /* MeiG Smart SLM828 */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0x10, 0x03) }, /* MeiG Smart SLM828 */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0xff, 0x30) }, /* MeiG Smart SRM815 and SRM825L */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0xff, 0x40) }, /* MeiG Smart SRM825L */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0xff, 0x60) }, /* MeiG Smart SRM825L */ + { USB_DEVICE_INTERFACE_CLASS(0x2df3, 0x9d03, 0xff) }, /* LongSung M5710 */ + { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1404, 0xff) }, /* GosunCn GM500 RNDIS */ + { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1405, 0xff) }, /* GosunCn GM500 MBIM */ +@@ -2403,12 +2418,6 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, TOZED_PRODUCT_LT70C, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, LUAT_PRODUCT_AIR720U, 0xff, 0, 0) }, +- { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SLM320, 0xff, 0, 0) }, +- { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SLM770A, 0xff, 0, 0) }, +- { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0, 0) }, +- { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x30) }, +- { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x40) }, +- { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x60) }, + { USB_DEVICE_INTERFACE_CLASS(0x1bbb, 0x0530, 0xff), /* TCL IK512 MBIM */ + .driver_info = NCTRL(1) }, + { USB_DEVICE_INTERFACE_CLASS(0x1bbb, 0x0640, 0xff), /* TCL IK512 ECM */ +diff --git a/drivers/vfio/pci/vfio_pci_rdwr.c b/drivers/vfio/pci/vfio_pci_rdwr.c +index e27de61ac9fe75..8191c8fcfb2565 100644 +--- a/drivers/vfio/pci/vfio_pci_rdwr.c ++++ b/drivers/vfio/pci/vfio_pci_rdwr.c +@@ -16,6 +16,7 @@ + #include + #include + #include ++#include + + #include "vfio_pci_priv.h" + +diff --git a/drivers/vfio/platform/vfio_platform_common.c b/drivers/vfio/platform/vfio_platform_common.c +index d63c2d266d0735..3bf1043cd7957c 100644 +--- a/drivers/vfio/platform/vfio_platform_common.c ++++ b/drivers/vfio/platform/vfio_platform_common.c +@@ -393,11 +393,6 @@ static ssize_t vfio_platform_read_mmio(struct vfio_platform_region *reg, + + count = min_t(size_t, count, reg->size - off); + +- if (off >= reg->size) +- return -EINVAL; +- +- count = min_t(size_t, count, reg->size - off); +- + if (!reg->ioaddr) { + reg->ioaddr = + ioremap(reg->addr, reg->size); +@@ -482,11 +477,6 @@ static ssize_t vfio_platform_write_mmio(struct vfio_platform_region *reg, + + count = min_t(size_t, count, reg->size - off); + +- if (off >= reg->size) +- return -EINVAL; +- +- count = min_t(size_t, count, reg->size - off); +- + if (!reg->ioaddr) { + reg->ioaddr = + ioremap(reg->addr, reg->size); +diff --git a/drivers/video/fbdev/omap/lcd_dma.c b/drivers/video/fbdev/omap/lcd_dma.c +index f85817635a8c2c..0da23c57e4757e 100644 +--- a/drivers/video/fbdev/omap/lcd_dma.c ++++ b/drivers/video/fbdev/omap/lcd_dma.c +@@ -432,8 +432,8 @@ static int __init omap_init_lcd_dma(void) + + spin_lock_init(&lcd_dma.lock); + +- r = request_irq(INT_DMA_LCD, lcd_dma_irq_handler, 0, +- "LCD DMA", NULL); ++ r = request_threaded_irq(INT_DMA_LCD, NULL, lcd_dma_irq_handler, ++ IRQF_ONESHOT, "LCD DMA", NULL); + if (r != 0) + pr_err("unable to request IRQ for LCD DMA (error %d)\n", r); + +diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c +index 6d0d1c8a508bf9..b6e54ab3b6f3bb 100644 +--- a/drivers/xen/swiotlb-xen.c ++++ b/drivers/xen/swiotlb-xen.c +@@ -74,19 +74,21 @@ static inline phys_addr_t xen_dma_to_phys(struct device *dev, + return xen_bus_to_phys(dev, dma_to_phys(dev, dma_addr)); + } + ++static inline bool range_requires_alignment(phys_addr_t p, size_t size) ++{ ++ phys_addr_t algn = 1ULL << (get_order(size) + PAGE_SHIFT); ++ phys_addr_t bus_addr = pfn_to_bfn(XEN_PFN_DOWN(p)) << XEN_PAGE_SHIFT; ++ ++ return IS_ALIGNED(p, algn) && !IS_ALIGNED(bus_addr, algn); ++} ++ + static inline int range_straddles_page_boundary(phys_addr_t p, size_t size) + { + unsigned long next_bfn, xen_pfn = XEN_PFN_DOWN(p); + unsigned int i, nr_pages = XEN_PFN_UP(xen_offset_in_page(p) + size); +- phys_addr_t algn = 1ULL << (get_order(size) + PAGE_SHIFT); + + next_bfn = pfn_to_bfn(xen_pfn); + +- /* If buffer is physically aligned, ensure DMA alignment. */ +- if (IS_ALIGNED(p, algn) && +- !IS_ALIGNED((phys_addr_t)next_bfn << XEN_PAGE_SHIFT, algn)) +- return 1; +- + for (i = 1; i < nr_pages; i++) + if (pfn_to_bfn(++xen_pfn) != ++next_bfn) + return 1; +@@ -155,7 +157,8 @@ xen_swiotlb_alloc_coherent(struct device *dev, size_t size, + + *dma_handle = xen_phys_to_dma(dev, phys); + if (*dma_handle + size - 1 > dma_mask || +- range_straddles_page_boundary(phys, size)) { ++ range_straddles_page_boundary(phys, size) || ++ range_requires_alignment(phys, size)) { + if (xen_create_contiguous_region(phys, order, fls64(dma_mask), + dma_handle) != 0) + goto out_free_pages; +@@ -181,7 +184,8 @@ xen_swiotlb_free_coherent(struct device *dev, size_t size, void *vaddr, + size = ALIGN(size, XEN_PAGE_SIZE); + + if (WARN_ON_ONCE(dma_handle + size - 1 > dev->coherent_dma_mask) || +- WARN_ON_ONCE(range_straddles_page_boundary(phys, size))) ++ WARN_ON_ONCE(range_straddles_page_boundary(phys, size) || ++ range_requires_alignment(phys, size))) + return; + + if (TestClearPageXenRemapped(virt_to_page(vaddr))) +diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c +index c2d0c62b087c22..68092b64e29eac 100644 +--- a/fs/btrfs/file.c ++++ b/fs/btrfs/file.c +@@ -1134,7 +1134,6 @@ static int btrfs_write_check(struct kiocb *iocb, struct iov_iter *from, + loff_t pos = iocb->ki_pos; + int ret; + loff_t oldsize; +- loff_t start_pos; + + /* + * Quickly bail out on NOWAIT writes if we don't have the nodatacow or +@@ -1158,9 +1157,8 @@ static int btrfs_write_check(struct kiocb *iocb, struct iov_iter *from, + */ + update_time_for_write(inode); + +- start_pos = round_down(pos, fs_info->sectorsize); + oldsize = i_size_read(inode); +- if (start_pos > oldsize) { ++ if (pos > oldsize) { + /* Expand hole size to cover write data, preventing empty gap */ + loff_t end_pos = round_up(pos + count, fs_info->sectorsize); + +diff --git a/fs/nfs/sysfs.c b/fs/nfs/sysfs.c +index bf378ecd5d9fdd..7b59a40d40c061 100644 +--- a/fs/nfs/sysfs.c ++++ b/fs/nfs/sysfs.c +@@ -280,9 +280,9 @@ void nfs_sysfs_link_rpc_client(struct nfs_server *server, + char name[RPC_CLIENT_NAME_SIZE]; + int ret; + +- strcpy(name, clnt->cl_program->name); +- strcat(name, uniq ? uniq : ""); +- strcat(name, "_client"); ++ strscpy(name, clnt->cl_program->name, sizeof(name)); ++ strncat(name, uniq ? uniq : "", sizeof(name) - strlen(name) - 1); ++ strncat(name, "_client", sizeof(name) - strlen(name) - 1); + + ret = sysfs_create_link_nowarn(&server->kobj, + &clnt->cl_sysfs->kobject, name); +diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c +index 12b2b9bc07bfe3..f1f32ad4f42ca1 100644 +--- a/fs/nfsd/nfs2acl.c ++++ b/fs/nfsd/nfs2acl.c +@@ -84,6 +84,8 @@ static __be32 nfsacld_proc_getacl(struct svc_rqst *rqstp) + fail: + posix_acl_release(resp->acl_access); + posix_acl_release(resp->acl_default); ++ resp->acl_access = NULL; ++ resp->acl_default = NULL; + goto out; + } + +diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c +index 73adca47d37398..d7af28f445044e 100644 +--- a/fs/nfsd/nfs3acl.c ++++ b/fs/nfsd/nfs3acl.c +@@ -76,6 +76,8 @@ static __be32 nfsd3_proc_getacl(struct svc_rqst *rqstp) + fail: + posix_acl_release(resp->acl_access); + posix_acl_release(resp->acl_default); ++ resp->acl_access = NULL; ++ resp->acl_default = NULL; + goto out; + } + +diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c +index 875ea311ca3c20..d47173d98eef71 100644 +--- a/fs/nfsd/nfs4callback.c ++++ b/fs/nfsd/nfs4callback.c +@@ -1410,8 +1410,11 @@ nfsd4_run_cb_work(struct work_struct *work) + nfsd4_process_cb_update(cb); + + clnt = clp->cl_cb_client; +- if (!clnt) { +- /* Callback channel broken, or client killed; give up: */ ++ if (!clnt || clp->cl_state == NFSD4_COURTESY) { ++ /* ++ * Callback channel broken, client killed or ++ * nfs4_client in courtesy state; give up. ++ */ + nfsd41_destroy_cb(cb); + return; + } +diff --git a/fs/orangefs/orangefs-debugfs.c b/fs/orangefs/orangefs-debugfs.c +index 1b508f5433846e..fa41db08848802 100644 +--- a/fs/orangefs/orangefs-debugfs.c ++++ b/fs/orangefs/orangefs-debugfs.c +@@ -393,9 +393,9 @@ static ssize_t orangefs_debug_write(struct file *file, + * Thwart users who try to jamb a ridiculous number + * of bytes into the debug file... + */ +- if (count > ORANGEFS_MAX_DEBUG_STRING_LEN + 1) { ++ if (count > ORANGEFS_MAX_DEBUG_STRING_LEN) { + silly = count; +- count = ORANGEFS_MAX_DEBUG_STRING_LEN + 1; ++ count = ORANGEFS_MAX_DEBUG_STRING_LEN; + } + + buf = kzalloc(ORANGEFS_MAX_DEBUG_STRING_LEN, GFP_KERNEL); +diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h +index 958ed7e89b301e..1d482c2aabbdfa 100644 +--- a/include/linux/blk-mq.h ++++ b/include/linux/blk-mq.h +@@ -849,12 +849,22 @@ static inline bool blk_mq_add_to_batch(struct request *req, + void (*complete)(struct io_comp_batch *)) + { + /* +- * blk_mq_end_request_batch() can't end request allocated from +- * sched tags ++ * Check various conditions that exclude batch processing: ++ * 1) No batch container ++ * 2) Has scheduler data attached ++ * 3) Not a passthrough request and end_io set ++ * 4) Not a passthrough request and an ioerror + */ +- if (!iob || (req->rq_flags & RQF_SCHED_TAGS) || ioerror || +- (req->end_io && !blk_rq_is_passthrough(req))) ++ if (!iob) + return false; ++ if (req->rq_flags & RQF_SCHED_TAGS) ++ return false; ++ if (!blk_rq_is_passthrough(req)) { ++ if (req->end_io) ++ return false; ++ if (ioerror < 0) ++ return false; ++ } + + if (!iob->complete) + iob->complete = complete; +diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h +index 6eefe5153a6ff7..c0c2b26725d0fc 100644 +--- a/include/linux/cgroup-defs.h ++++ b/include/linux/cgroup-defs.h +@@ -71,9 +71,6 @@ enum { + + /* Cgroup is frozen. */ + CGRP_FROZEN, +- +- /* Control group has to be killed. */ +- CGRP_KILL, + }; + + /* cgroup_root->flags */ +@@ -438,6 +435,9 @@ struct cgroup { + + int nr_threaded_children; /* # of live threaded child cgroups */ + ++ /* sequence number for cgroup.kill, serialized by css_set_lock. */ ++ unsigned int kill_seq; ++ + struct kernfs_node *kn; /* cgroup kernfs entry */ + struct cgroup_file procs_file; /* handle for "cgroup.procs" */ + struct cgroup_file events_file; /* handle for "cgroup.events" */ +diff --git a/include/linux/efi.h b/include/linux/efi.h +index 80b21d1c6eafaf..7db1c0759c0969 100644 +--- a/include/linux/efi.h ++++ b/include/linux/efi.h +@@ -127,6 +127,7 @@ typedef struct { + #define EFI_MEMORY_RO ((u64)0x0000000000020000ULL) /* read-only */ + #define EFI_MEMORY_SP ((u64)0x0000000000040000ULL) /* soft reserved */ + #define EFI_MEMORY_CPU_CRYPTO ((u64)0x0000000000080000ULL) /* supports encryption */ ++#define EFI_MEMORY_HOT_PLUGGABLE BIT_ULL(20) /* supports unplugging at runtime */ + #define EFI_MEMORY_RUNTIME ((u64)0x8000000000000000ULL) /* range requires runtime mapping */ + #define EFI_MEMORY_DESCRIPTOR_VERSION 1 + +diff --git a/include/linux/i8253.h b/include/linux/i8253.h +index 8336b2f6f83462..bf169cfef7f12d 100644 +--- a/include/linux/i8253.h ++++ b/include/linux/i8253.h +@@ -24,6 +24,7 @@ extern raw_spinlock_t i8253_lock; + extern bool i8253_clear_counter_on_shutdown; + extern struct clock_event_device i8253_clockevent; + extern void clockevent_i8253_init(bool oneshot); ++extern void clockevent_i8253_disable(void); + + extern void setup_pit_timer(void); + +diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h +index 8b5121eb8757ef..95ee88dfe0b9c6 100644 +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -2593,6 +2593,12 @@ struct net *dev_net(const struct net_device *dev) + return read_pnet(&dev->nd_net); + } + ++static inline ++struct net *dev_net_rcu(const struct net_device *dev) ++{ ++ return read_pnet_rcu(&dev->nd_net); ++} ++ + static inline + void dev_net_set(struct net_device *dev, struct net *net) + { +diff --git a/include/linux/sched/task.h b/include/linux/sched/task.h +index a23af225c89839..8dbecab4c4000f 100644 +--- a/include/linux/sched/task.h ++++ b/include/linux/sched/task.h +@@ -41,6 +41,7 @@ struct kernel_clone_args { + void *fn_arg; + struct cgroup *cgrp; + struct css_set *cset; ++ unsigned int kill_seq; + }; + + /* +diff --git a/include/net/l3mdev.h b/include/net/l3mdev.h +index 031c661aa14df7..bdfa9d414360c7 100644 +--- a/include/net/l3mdev.h ++++ b/include/net/l3mdev.h +@@ -198,10 +198,12 @@ struct sk_buff *l3mdev_l3_out(struct sock *sk, struct sk_buff *skb, u16 proto) + if (netif_is_l3_slave(dev)) { + struct net_device *master; + ++ rcu_read_lock(); + master = netdev_master_upper_dev_get_rcu(dev); + if (master && master->l3mdev_ops->l3mdev_l3_out) + skb = master->l3mdev_ops->l3mdev_l3_out(master, sk, + skb, proto); ++ rcu_read_unlock(); + } + + return skb; +diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h +index 1befad79a67349..ce3f84c6eb8eb3 100644 +--- a/include/net/net_namespace.h ++++ b/include/net/net_namespace.h +@@ -369,21 +369,30 @@ static inline void put_net_track(struct net *net, netns_tracker *tracker) + + typedef struct { + #ifdef CONFIG_NET_NS +- struct net *net; ++ struct net __rcu *net; + #endif + } possible_net_t; + + static inline void write_pnet(possible_net_t *pnet, struct net *net) + { + #ifdef CONFIG_NET_NS +- pnet->net = net; ++ rcu_assign_pointer(pnet->net, net); + #endif + } + + static inline struct net *read_pnet(const possible_net_t *pnet) + { + #ifdef CONFIG_NET_NS +- return pnet->net; ++ return rcu_dereference_protected(pnet->net, true); ++#else ++ return &init_net; ++#endif ++} ++ ++static inline struct net *read_pnet_rcu(const possible_net_t *pnet) ++{ ++#ifdef CONFIG_NET_NS ++ return rcu_dereference(pnet->net); + #else + return &init_net; + #endif +diff --git a/include/net/route.h b/include/net/route.h +index 51a45b1887b562..0171e9e1bbea3d 100644 +--- a/include/net/route.h ++++ b/include/net/route.h +@@ -357,10 +357,15 @@ static inline int inet_iif(const struct sk_buff *skb) + static inline int ip4_dst_hoplimit(const struct dst_entry *dst) + { + int hoplimit = dst_metric_raw(dst, RTAX_HOPLIMIT); +- struct net *net = dev_net(dst->dev); + +- if (hoplimit == 0) ++ if (hoplimit == 0) { ++ const struct net *net; ++ ++ rcu_read_lock(); ++ net = dev_net_rcu(dst->dev); + hoplimit = READ_ONCE(net->ipv4.sysctl_ip_default_ttl); ++ rcu_read_unlock(); ++ } + return hoplimit; + } + +diff --git a/io_uring/kbuf.c b/io_uring/kbuf.c +index 702c08c26cd4fa..b6fbae874f27f7 100644 +--- a/io_uring/kbuf.c ++++ b/io_uring/kbuf.c +@@ -301,6 +301,12 @@ void io_destroy_buffers(struct io_ring_ctx *ctx) + } + } + ++static void io_destroy_bl(struct io_ring_ctx *ctx, struct io_buffer_list *bl) ++{ ++ xa_erase(&ctx->io_bl_xa, bl->bgid); ++ io_put_bl(ctx, bl); ++} ++ + int io_remove_buffers_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) + { + struct io_provide_buf *p = io_kiocb_to_cmd(req, struct io_provide_buf); +@@ -642,12 +648,13 @@ int io_register_pbuf_ring(struct io_ring_ctx *ctx, void __user *arg) + /* if mapped buffer ring OR classic exists, don't allow */ + if (bl->is_mapped || !list_empty(&bl->buf_list)) + return -EEXIST; +- } else { +- free_bl = bl = kzalloc(sizeof(*bl), GFP_KERNEL); +- if (!bl) +- return -ENOMEM; ++ io_destroy_bl(ctx, bl); + } + ++ free_bl = bl = kzalloc(sizeof(*bl), GFP_KERNEL); ++ if (!bl) ++ return -ENOMEM; ++ + if (!(reg.flags & IOU_PBUF_RING_MMAP)) + ret = io_pin_pbuf_ring(®, bl); + else +diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c +index 36097e8c904fe5..3ccf80dfa587a3 100644 +--- a/kernel/cgroup/cgroup.c ++++ b/kernel/cgroup/cgroup.c +@@ -3941,7 +3941,7 @@ static void __cgroup_kill(struct cgroup *cgrp) + lockdep_assert_held(&cgroup_mutex); + + spin_lock_irq(&css_set_lock); +- set_bit(CGRP_KILL, &cgrp->flags); ++ cgrp->kill_seq++; + spin_unlock_irq(&css_set_lock); + + css_task_iter_start(&cgrp->self, CSS_TASK_ITER_PROCS | CSS_TASK_ITER_THREADED, &it); +@@ -3957,10 +3957,6 @@ static void __cgroup_kill(struct cgroup *cgrp) + send_sig(SIGKILL, task, 0); + } + css_task_iter_end(&it); +- +- spin_lock_irq(&css_set_lock); +- clear_bit(CGRP_KILL, &cgrp->flags); +- spin_unlock_irq(&css_set_lock); + } + + static void cgroup_kill(struct cgroup *cgrp) +@@ -6399,6 +6395,10 @@ static int cgroup_css_set_fork(struct kernel_clone_args *kargs) + spin_lock_irq(&css_set_lock); + cset = task_css_set(current); + get_css_set(cset); ++ if (kargs->cgrp) ++ kargs->kill_seq = kargs->cgrp->kill_seq; ++ else ++ kargs->kill_seq = cset->dfl_cgrp->kill_seq; + spin_unlock_irq(&css_set_lock); + + if (!(kargs->flags & CLONE_INTO_CGROUP)) { +@@ -6582,6 +6582,7 @@ void cgroup_post_fork(struct task_struct *child, + struct kernel_clone_args *kargs) + __releases(&cgroup_threadgroup_rwsem) __releases(&cgroup_mutex) + { ++ unsigned int cgrp_kill_seq = 0; + unsigned long cgrp_flags = 0; + bool kill = false; + struct cgroup_subsys *ss; +@@ -6595,10 +6596,13 @@ void cgroup_post_fork(struct task_struct *child, + + /* init tasks are special, only link regular threads */ + if (likely(child->pid)) { +- if (kargs->cgrp) ++ if (kargs->cgrp) { + cgrp_flags = kargs->cgrp->flags; +- else ++ cgrp_kill_seq = kargs->cgrp->kill_seq; ++ } else { + cgrp_flags = cset->dfl_cgrp->flags; ++ cgrp_kill_seq = cset->dfl_cgrp->kill_seq; ++ } + + WARN_ON_ONCE(!list_empty(&child->cg_list)); + cset->nr_tasks++; +@@ -6633,7 +6637,7 @@ void cgroup_post_fork(struct task_struct *child, + * child down right after we finished preparing it for + * userspace. + */ +- kill = test_bit(CGRP_KILL, &cgrp_flags); ++ kill = kargs->kill_seq != cgrp_kill_seq; + } + + spin_unlock_irq(&css_set_lock); +diff --git a/kernel/cgroup/rstat.c b/kernel/cgroup/rstat.c +index d80d7a60814129..c32439b855f5dd 100644 +--- a/kernel/cgroup/rstat.c ++++ b/kernel/cgroup/rstat.c +@@ -469,7 +469,6 @@ static void root_cgroup_cputime(struct cgroup_base_stat *bstat) + + cputime->sum_exec_runtime += user; + cputime->sum_exec_runtime += sys; +- cputime->sum_exec_runtime += cpustat[CPUTIME_STEAL]; + + #ifdef CONFIG_SCHED_CORE + bstat->forceidle_sum += cpustat[CPUTIME_FORCEIDLE]; +diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c +index aa864999dc21be..3130f24daf5979 100644 +--- a/kernel/time/clocksource.c ++++ b/kernel/time/clocksource.c +@@ -351,16 +351,18 @@ void clocksource_verify_percpu(struct clocksource *cs) + cpumask_clear(&cpus_ahead); + cpumask_clear(&cpus_behind); + cpus_read_lock(); +- preempt_disable(); ++ migrate_disable(); + clocksource_verify_choose_cpus(); + if (cpumask_empty(&cpus_chosen)) { +- preempt_enable(); ++ migrate_enable(); + cpus_read_unlock(); + pr_warn("Not enough CPUs to check clocksource '%s'.\n", cs->name); + return; + } + testcpu = smp_processor_id(); +- pr_warn("Checking clocksource %s synchronization from CPU %d to CPUs %*pbl.\n", cs->name, testcpu, cpumask_pr_args(&cpus_chosen)); ++ pr_info("Checking clocksource %s synchronization from CPU %d to CPUs %*pbl.\n", ++ cs->name, testcpu, cpumask_pr_args(&cpus_chosen)); ++ preempt_disable(); + for_each_cpu(cpu, &cpus_chosen) { + if (cpu == testcpu) + continue; +@@ -380,6 +382,7 @@ void clocksource_verify_percpu(struct clocksource *cs) + cs_nsec_min = cs_nsec; + } + preempt_enable(); ++ migrate_enable(); + cpus_read_unlock(); + if (!cpumask_empty(&cpus_ahead)) + pr_warn(" CPUs %*pbl ahead of CPU %d for clocksource %s.\n", +diff --git a/mm/gup.c b/mm/gup.c +index fdd75384160d8d..69d259f7bf37ec 100644 +--- a/mm/gup.c ++++ b/mm/gup.c +@@ -1946,14 +1946,14 @@ struct page *get_dump_page(unsigned long addr) + /* + * Returns the number of collected pages. Return value is always >= 0. + */ +-static unsigned long collect_longterm_unpinnable_pages( ++static void collect_longterm_unpinnable_pages( + struct list_head *movable_page_list, + unsigned long nr_pages, + struct page **pages) + { +- unsigned long i, collected = 0; + struct folio *prev_folio = NULL; + bool drain_allow = true; ++ unsigned long i; + + for (i = 0; i < nr_pages; i++) { + struct folio *folio = page_folio(pages[i]); +@@ -1965,8 +1965,6 @@ static unsigned long collect_longterm_unpinnable_pages( + if (folio_is_longterm_pinnable(folio)) + continue; + +- collected++; +- + if (folio_is_device_coherent(folio)) + continue; + +@@ -1988,8 +1986,6 @@ static unsigned long collect_longterm_unpinnable_pages( + NR_ISOLATED_ANON + folio_is_file_lru(folio), + folio_nr_pages(folio)); + } +- +- return collected; + } + + /* +@@ -2082,12 +2078,10 @@ static int migrate_longterm_unpinnable_pages( + static long check_and_migrate_movable_pages(unsigned long nr_pages, + struct page **pages) + { +- unsigned long collected; + LIST_HEAD(movable_page_list); + +- collected = collect_longterm_unpinnable_pages(&movable_page_list, +- nr_pages, pages); +- if (!collected) ++ collect_longterm_unpinnable_pages(&movable_page_list, nr_pages, pages); ++ if (list_empty(&movable_page_list)) + return 0; + + return migrate_longterm_unpinnable_pages(&movable_page_list, nr_pages, +diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c +index 0f66dd8715bd87..4a16142ac58a94 100644 +--- a/net/ax25/af_ax25.c ++++ b/net/ax25/af_ax25.c +@@ -685,6 +685,15 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname, + break; + } + ++ if (ax25->ax25_dev) { ++ if (dev == ax25->ax25_dev->dev) { ++ rcu_read_unlock(); ++ break; ++ } ++ netdev_put(ax25->ax25_dev->dev, &ax25->dev_tracker); ++ ax25_dev_put(ax25->ax25_dev); ++ } ++ + ax25->ax25_dev = ax25_dev_ax25dev(dev); + if (!ax25->ax25_dev) { + rcu_read_unlock(); +@@ -692,6 +701,8 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname, + break; + } + ax25_fillin_cb(ax25, ax25->ax25_dev); ++ netdev_hold(dev, &ax25->dev_tracker, GFP_ATOMIC); ++ ax25_dev_hold(ax25->ax25_dev); + rcu_read_unlock(); + break; + +diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c +index ac11f1f08db0f9..d35479c465e2c4 100644 +--- a/net/batman-adv/bat_v.c ++++ b/net/batman-adv/bat_v.c +@@ -113,8 +113,6 @@ static void + batadv_v_hardif_neigh_init(struct batadv_hardif_neigh_node *hardif_neigh) + { + ewma_throughput_init(&hardif_neigh->bat_v.throughput); +- INIT_WORK(&hardif_neigh->bat_v.metric_work, +- batadv_v_elp_throughput_metric_update); + } + + /** +diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c +index 1d704574e6bf54..b065578b4436ee 100644 +--- a/net/batman-adv/bat_v_elp.c ++++ b/net/batman-adv/bat_v_elp.c +@@ -18,6 +18,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -26,6 +27,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -41,6 +43,18 @@ + #include "routing.h" + #include "send.h" + ++/** ++ * struct batadv_v_metric_queue_entry - list of hardif neighbors which require ++ * and metric update ++ */ ++struct batadv_v_metric_queue_entry { ++ /** @hardif_neigh: hardif neighbor scheduled for metric update */ ++ struct batadv_hardif_neigh_node *hardif_neigh; ++ ++ /** @list: list node for metric_queue */ ++ struct list_head list; ++}; ++ + /** + * batadv_v_elp_start_timer() - restart timer for ELP periodic work + * @hard_iface: the interface for which the timer has to be reset +@@ -59,25 +73,36 @@ static void batadv_v_elp_start_timer(struct batadv_hard_iface *hard_iface) + /** + * batadv_v_elp_get_throughput() - get the throughput towards a neighbour + * @neigh: the neighbour for which the throughput has to be obtained ++ * @pthroughput: calculated throughput towards the given neighbour in multiples ++ * of 100kpbs (a value of '1' equals 0.1Mbps, '10' equals 1Mbps, etc). + * +- * Return: The throughput towards the given neighbour in multiples of 100kpbs +- * (a value of '1' equals 0.1Mbps, '10' equals 1Mbps, etc). ++ * Return: true when value behind @pthroughput was set + */ +-static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh) ++static bool batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh, ++ u32 *pthroughput) + { + struct batadv_hard_iface *hard_iface = neigh->if_incoming; ++ struct net_device *soft_iface = hard_iface->soft_iface; + struct ethtool_link_ksettings link_settings; + struct net_device *real_netdev; + struct station_info sinfo; + u32 throughput; + int ret; + ++ /* don't query throughput when no longer associated with any ++ * batman-adv interface ++ */ ++ if (!soft_iface) ++ return false; ++ + /* if the user specified a customised value for this interface, then + * return it directly + */ + throughput = atomic_read(&hard_iface->bat_v.throughput_override); +- if (throughput != 0) +- return throughput; ++ if (throughput != 0) { ++ *pthroughput = throughput; ++ return true; ++ } + + /* if this is a wireless device, then ask its throughput through + * cfg80211 API +@@ -104,27 +129,39 @@ static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh) + * possible to delete this neighbor. For now set + * the throughput metric to 0. + */ +- return 0; ++ *pthroughput = 0; ++ return true; + } + if (ret) + goto default_throughput; + +- if (sinfo.filled & BIT(NL80211_STA_INFO_EXPECTED_THROUGHPUT)) +- return sinfo.expected_throughput / 100; ++ if (sinfo.filled & BIT(NL80211_STA_INFO_EXPECTED_THROUGHPUT)) { ++ *pthroughput = sinfo.expected_throughput / 100; ++ return true; ++ } + + /* try to estimate the expected throughput based on reported tx + * rates + */ +- if (sinfo.filled & BIT(NL80211_STA_INFO_TX_BITRATE)) +- return cfg80211_calculate_bitrate(&sinfo.txrate) / 3; ++ if (sinfo.filled & BIT(NL80211_STA_INFO_TX_BITRATE)) { ++ *pthroughput = cfg80211_calculate_bitrate(&sinfo.txrate) / 3; ++ return true; ++ } + + goto default_throughput; + } + ++ /* only use rtnl_trylock because the elp worker will be cancelled while ++ * the rntl_lock is held. the cancel_delayed_work_sync() would otherwise ++ * wait forever when the elp work_item was started and it is then also ++ * trying to rtnl_lock ++ */ ++ if (!rtnl_trylock()) ++ return false; ++ + /* if not a wifi interface, check if this device provides data via + * ethtool (e.g. an Ethernet adapter) + */ +- rtnl_lock(); + ret = __ethtool_get_link_ksettings(hard_iface->net_dev, &link_settings); + rtnl_unlock(); + if (ret == 0) { +@@ -135,13 +172,15 @@ static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh) + hard_iface->bat_v.flags &= ~BATADV_FULL_DUPLEX; + + throughput = link_settings.base.speed; +- if (throughput && throughput != SPEED_UNKNOWN) +- return throughput * 10; ++ if (throughput && throughput != SPEED_UNKNOWN) { ++ *pthroughput = throughput * 10; ++ return true; ++ } + } + + default_throughput: + if (!(hard_iface->bat_v.flags & BATADV_WARNING_DEFAULT)) { +- batadv_info(hard_iface->soft_iface, ++ batadv_info(soft_iface, + "WiFi driver or ethtool info does not provide information about link speeds on interface %s, therefore defaulting to hardcoded throughput values of %u.%1u Mbps. Consider overriding the throughput manually or checking your driver.\n", + hard_iface->net_dev->name, + BATADV_THROUGHPUT_DEFAULT_VALUE / 10, +@@ -150,31 +189,26 @@ static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh) + } + + /* if none of the above cases apply, return the base_throughput */ +- return BATADV_THROUGHPUT_DEFAULT_VALUE; ++ *pthroughput = BATADV_THROUGHPUT_DEFAULT_VALUE; ++ return true; + } + + /** + * batadv_v_elp_throughput_metric_update() - worker updating the throughput + * metric of a single hop neighbour +- * @work: the work queue item ++ * @neigh: the neighbour to probe + */ +-void batadv_v_elp_throughput_metric_update(struct work_struct *work) ++static void ++batadv_v_elp_throughput_metric_update(struct batadv_hardif_neigh_node *neigh) + { +- struct batadv_hardif_neigh_node_bat_v *neigh_bat_v; +- struct batadv_hardif_neigh_node *neigh; +- +- neigh_bat_v = container_of(work, struct batadv_hardif_neigh_node_bat_v, +- metric_work); +- neigh = container_of(neigh_bat_v, struct batadv_hardif_neigh_node, +- bat_v); ++ u32 throughput; ++ bool valid; + +- ewma_throughput_add(&neigh->bat_v.throughput, +- batadv_v_elp_get_throughput(neigh)); ++ valid = batadv_v_elp_get_throughput(neigh, &throughput); ++ if (!valid) ++ return; + +- /* decrement refcounter to balance increment performed before scheduling +- * this task +- */ +- batadv_hardif_neigh_put(neigh); ++ ewma_throughput_add(&neigh->bat_v.throughput, throughput); + } + + /** +@@ -248,14 +282,16 @@ batadv_v_elp_wifi_neigh_probe(struct batadv_hardif_neigh_node *neigh) + */ + static void batadv_v_elp_periodic_work(struct work_struct *work) + { ++ struct batadv_v_metric_queue_entry *metric_entry; ++ struct batadv_v_metric_queue_entry *metric_safe; + struct batadv_hardif_neigh_node *hardif_neigh; + struct batadv_hard_iface *hard_iface; + struct batadv_hard_iface_bat_v *bat_v; + struct batadv_elp_packet *elp_packet; ++ struct list_head metric_queue; + struct batadv_priv *bat_priv; + struct sk_buff *skb; + u32 elp_interval; +- bool ret; + + bat_v = container_of(work, struct batadv_hard_iface_bat_v, elp_wq.work); + hard_iface = container_of(bat_v, struct batadv_hard_iface, bat_v); +@@ -291,6 +327,8 @@ static void batadv_v_elp_periodic_work(struct work_struct *work) + + atomic_inc(&hard_iface->bat_v.elp_seqno); + ++ INIT_LIST_HEAD(&metric_queue); ++ + /* The throughput metric is updated on each sent packet. This way, if a + * node is dead and no longer sends packets, batman-adv is still able to + * react timely to its death. +@@ -315,16 +353,28 @@ static void batadv_v_elp_periodic_work(struct work_struct *work) + + /* Reading the estimated throughput from cfg80211 is a task that + * may sleep and that is not allowed in an rcu protected +- * context. Therefore schedule a task for that. ++ * context. Therefore add it to metric_queue and process it ++ * outside rcu protected context. + */ +- ret = queue_work(batadv_event_workqueue, +- &hardif_neigh->bat_v.metric_work); +- +- if (!ret) ++ metric_entry = kzalloc(sizeof(*metric_entry), GFP_ATOMIC); ++ if (!metric_entry) { + batadv_hardif_neigh_put(hardif_neigh); ++ continue; ++ } ++ ++ metric_entry->hardif_neigh = hardif_neigh; ++ list_add(&metric_entry->list, &metric_queue); + } + rcu_read_unlock(); + ++ list_for_each_entry_safe(metric_entry, metric_safe, &metric_queue, list) { ++ batadv_v_elp_throughput_metric_update(metric_entry->hardif_neigh); ++ ++ batadv_hardif_neigh_put(metric_entry->hardif_neigh); ++ list_del(&metric_entry->list); ++ kfree(metric_entry); ++ } ++ + restart_timer: + batadv_v_elp_start_timer(hard_iface); + out: +diff --git a/net/batman-adv/bat_v_elp.h b/net/batman-adv/bat_v_elp.h +index 9e2740195fa2d4..c9cb0a30710045 100644 +--- a/net/batman-adv/bat_v_elp.h ++++ b/net/batman-adv/bat_v_elp.h +@@ -10,7 +10,6 @@ + #include "main.h" + + #include +-#include + + int batadv_v_elp_iface_enable(struct batadv_hard_iface *hard_iface); + void batadv_v_elp_iface_disable(struct batadv_hard_iface *hard_iface); +@@ -19,6 +18,5 @@ void batadv_v_elp_iface_activate(struct batadv_hard_iface *primary_iface, + void batadv_v_elp_primary_iface_set(struct batadv_hard_iface *primary_iface); + int batadv_v_elp_packet_recv(struct sk_buff *skb, + struct batadv_hard_iface *if_incoming); +-void batadv_v_elp_throughput_metric_update(struct work_struct *work); + + #endif /* _NET_BATMAN_ADV_BAT_V_ELP_H_ */ +diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h +index 17d5ea1d8e84e3..d6854c109cd291 100644 +--- a/net/batman-adv/types.h ++++ b/net/batman-adv/types.h +@@ -596,9 +596,6 @@ struct batadv_hardif_neigh_node_bat_v { + * neighbor + */ + unsigned long last_unicast_tx; +- +- /** @metric_work: work queue callback item for metric update */ +- struct work_struct metric_work; + }; + + /** +diff --git a/net/can/j1939/socket.c b/net/can/j1939/socket.c +index 1f49d6164ea1da..cf9a12d8da6f90 100644 +--- a/net/can/j1939/socket.c ++++ b/net/can/j1939/socket.c +@@ -1132,7 +1132,7 @@ static int j1939_sk_send_loop(struct j1939_priv *priv, struct sock *sk, + + todo_size = size; + +- while (todo_size) { ++ do { + struct j1939_sk_buff_cb *skcb; + + segment_size = min_t(size_t, J1939_MAX_TP_PACKET_SIZE, +@@ -1177,7 +1177,7 @@ static int j1939_sk_send_loop(struct j1939_priv *priv, struct sock *sk, + + todo_size -= segment_size; + session->total_queued_size += segment_size; +- } ++ } while (todo_size); + + switch (ret) { + case 0: /* OK */ +diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c +index 95f7a7e65a73fa..9b72d118d756dd 100644 +--- a/net/can/j1939/transport.c ++++ b/net/can/j1939/transport.c +@@ -382,8 +382,9 @@ sk_buff *j1939_session_skb_get_by_offset(struct j1939_session *session, + skb_queue_walk(&session->skb_queue, do_skb) { + do_skcb = j1939_skb_to_cb(do_skb); + +- if (offset_start >= do_skcb->offset && +- offset_start < (do_skcb->offset + do_skb->len)) { ++ if ((offset_start >= do_skcb->offset && ++ offset_start < (do_skcb->offset + do_skb->len)) || ++ (offset_start == 0 && do_skcb->offset == 0 && do_skb->len == 0)) { + skb = do_skb; + } + } +diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c +index b22d20cc417b21..00a5c41c1831df 100644 +--- a/net/core/flow_dissector.c ++++ b/net/core/flow_dissector.c +@@ -1084,10 +1084,12 @@ bool __skb_flow_dissect(const struct net *net, + FLOW_DISSECTOR_KEY_BASIC, + target_container); + ++ rcu_read_lock(); ++ + if (skb) { + if (!net) { + if (skb->dev) +- net = dev_net(skb->dev); ++ net = dev_net_rcu(skb->dev); + else if (skb->sk) + net = sock_net(skb->sk); + } +@@ -1098,7 +1100,6 @@ bool __skb_flow_dissect(const struct net *net, + enum netns_bpf_attach_type type = NETNS_BPF_FLOW_DISSECTOR; + struct bpf_prog_array *run_array; + +- rcu_read_lock(); + run_array = rcu_dereference(init_net.bpf.run_array[type]); + if (!run_array) + run_array = rcu_dereference(net->bpf.run_array[type]); +@@ -1126,17 +1127,17 @@ bool __skb_flow_dissect(const struct net *net, + prog = READ_ONCE(run_array->items[0].prog); + result = bpf_flow_dissect(prog, &ctx, n_proto, nhoff, + hlen, flags); +- if (result == BPF_FLOW_DISSECTOR_CONTINUE) +- goto dissect_continue; +- __skb_flow_bpf_to_target(&flow_keys, flow_dissector, +- target_container); +- rcu_read_unlock(); +- return result == BPF_OK; ++ if (result != BPF_FLOW_DISSECTOR_CONTINUE) { ++ __skb_flow_bpf_to_target(&flow_keys, flow_dissector, ++ target_container); ++ rcu_read_unlock(); ++ return result == BPF_OK; ++ } + } +-dissect_continue: +- rcu_read_unlock(); + } + ++ rcu_read_unlock(); ++ + if (dissector_uses_key(flow_dissector, + FLOW_DISSECTOR_KEY_ETH_ADDRS)) { + struct ethhdr *eth = eth_hdr(skb); +diff --git a/net/core/neighbour.c b/net/core/neighbour.c +index cb0c233e83962f..e44feb39d459a7 100644 +--- a/net/core/neighbour.c ++++ b/net/core/neighbour.c +@@ -3508,10 +3508,12 @@ static const struct seq_operations neigh_stat_seq_ops = { + static void __neigh_notify(struct neighbour *n, int type, int flags, + u32 pid) + { +- struct net *net = dev_net(n->dev); + struct sk_buff *skb; + int err = -ENOBUFS; ++ struct net *net; + ++ rcu_read_lock(); ++ net = dev_net_rcu(n->dev); + skb = nlmsg_new(neigh_nlmsg_size(), GFP_ATOMIC); + if (skb == NULL) + goto errout; +@@ -3524,10 +3526,11 @@ static void __neigh_notify(struct neighbour *n, int type, int flags, + goto errout; + } + rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC); +- return; ++ goto out; + errout: +- if (err < 0) +- rtnl_set_sk_err(net, RTNLGRP_NEIGH, err); ++ rtnl_set_sk_err(net, RTNLGRP_NEIGH, err); ++out: ++ rcu_read_unlock(); + } + + void neigh_app_ns(struct neighbour *n) +diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c +index 0d0d725b46ad0c..02776453bf97a8 100644 +--- a/net/ipv4/arp.c ++++ b/net/ipv4/arp.c +@@ -658,10 +658,12 @@ static int arp_xmit_finish(struct net *net, struct sock *sk, struct sk_buff *skb + */ + void arp_xmit(struct sk_buff *skb) + { ++ rcu_read_lock(); + /* Send it off, maybe filter it using firewalling first. */ + NF_HOOK(NFPROTO_ARP, NF_ARP_OUT, +- dev_net(skb->dev), NULL, skb, NULL, skb->dev, ++ dev_net_rcu(skb->dev), NULL, skb, NULL, skb->dev, + arp_xmit_finish); ++ rcu_read_unlock(); + } + EXPORT_SYMBOL(arp_xmit); + +diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c +index 4822f68edbf08b..c33b1ecc591e4e 100644 +--- a/net/ipv4/devinet.c ++++ b/net/ipv4/devinet.c +@@ -1341,10 +1341,11 @@ __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope) + __be32 addr = 0; + unsigned char localnet_scope = RT_SCOPE_HOST; + struct in_device *in_dev; +- struct net *net = dev_net(dev); ++ struct net *net; + int master_idx; + + rcu_read_lock(); ++ net = dev_net_rcu(dev); + in_dev = __in_dev_get_rcu(dev); + if (!in_dev) + goto no_in_dev; +diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c +index a6adf6a2ec4b57..a21d32b3ae6c36 100644 +--- a/net/ipv4/icmp.c ++++ b/net/ipv4/icmp.c +@@ -403,10 +403,10 @@ static void icmp_push_reply(struct sock *sk, + + static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) + { +- struct ipcm_cookie ipc; + struct rtable *rt = skb_rtable(skb); +- struct net *net = dev_net(rt->dst.dev); ++ struct net *net = dev_net_rcu(rt->dst.dev); + bool apply_ratelimit = false; ++ struct ipcm_cookie ipc; + struct flowi4 fl4; + struct sock *sk; + struct inet_sock *inet; +@@ -609,12 +609,14 @@ void __icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info, + struct sock *sk; + + if (!rt) +- goto out; ++ return; ++ ++ rcu_read_lock(); + + if (rt->dst.dev) +- net = dev_net(rt->dst.dev); ++ net = dev_net_rcu(rt->dst.dev); + else if (skb_in->dev) +- net = dev_net(skb_in->dev); ++ net = dev_net_rcu(skb_in->dev); + else + goto out; + +@@ -783,7 +785,8 @@ void __icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info, + icmp_xmit_unlock(sk); + out_bh_enable: + local_bh_enable(); +-out:; ++out: ++ rcu_read_unlock(); + } + EXPORT_SYMBOL(__icmp_send); + +@@ -832,7 +835,7 @@ static void icmp_socket_deliver(struct sk_buff *skb, u32 info) + * avoid additional coding at protocol handlers. + */ + if (!pskb_may_pull(skb, iph->ihl * 4 + 8)) { +- __ICMP_INC_STATS(dev_net(skb->dev), ICMP_MIB_INERRORS); ++ __ICMP_INC_STATS(dev_net_rcu(skb->dev), ICMP_MIB_INERRORS); + return; + } + +@@ -866,7 +869,7 @@ static enum skb_drop_reason icmp_unreach(struct sk_buff *skb) + struct net *net; + u32 info = 0; + +- net = dev_net(skb_dst(skb)->dev); ++ net = dev_net_rcu(skb_dst(skb)->dev); + + /* + * Incomplete header ? +@@ -977,7 +980,7 @@ static enum skb_drop_reason icmp_unreach(struct sk_buff *skb) + static enum skb_drop_reason icmp_redirect(struct sk_buff *skb) + { + if (skb->len < sizeof(struct iphdr)) { +- __ICMP_INC_STATS(dev_net(skb->dev), ICMP_MIB_INERRORS); ++ __ICMP_INC_STATS(dev_net_rcu(skb->dev), ICMP_MIB_INERRORS); + return SKB_DROP_REASON_PKT_TOO_SMALL; + } + +@@ -1009,7 +1012,7 @@ static enum skb_drop_reason icmp_echo(struct sk_buff *skb) + struct icmp_bxm icmp_param; + struct net *net; + +- net = dev_net(skb_dst(skb)->dev); ++ net = dev_net_rcu(skb_dst(skb)->dev); + /* should there be an ICMP stat for ignored echos? */ + if (READ_ONCE(net->ipv4.sysctl_icmp_echo_ignore_all)) + return SKB_NOT_DROPPED_YET; +@@ -1038,9 +1041,9 @@ static enum skb_drop_reason icmp_echo(struct sk_buff *skb) + + bool icmp_build_probe(struct sk_buff *skb, struct icmphdr *icmphdr) + { ++ struct net *net = dev_net_rcu(skb->dev); + struct icmp_ext_hdr *ext_hdr, _ext_hdr; + struct icmp_ext_echo_iio *iio, _iio; +- struct net *net = dev_net(skb->dev); + struct inet6_dev *in6_dev; + struct in_device *in_dev; + struct net_device *dev; +@@ -1179,7 +1182,7 @@ static enum skb_drop_reason icmp_timestamp(struct sk_buff *skb) + return SKB_NOT_DROPPED_YET; + + out_err: +- __ICMP_INC_STATS(dev_net(skb_dst(skb)->dev), ICMP_MIB_INERRORS); ++ __ICMP_INC_STATS(dev_net_rcu(skb_dst(skb)->dev), ICMP_MIB_INERRORS); + return SKB_DROP_REASON_PKT_TOO_SMALL; + } + +@@ -1196,7 +1199,7 @@ int icmp_rcv(struct sk_buff *skb) + { + enum skb_drop_reason reason = SKB_DROP_REASON_NOT_SPECIFIED; + struct rtable *rt = skb_rtable(skb); +- struct net *net = dev_net(rt->dst.dev); ++ struct net *net = dev_net_rcu(rt->dst.dev); + struct icmphdr *icmph; + + if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) { +@@ -1369,9 +1372,9 @@ int icmp_err(struct sk_buff *skb, u32 info) + struct iphdr *iph = (struct iphdr *)skb->data; + int offset = iph->ihl<<2; + struct icmphdr *icmph = (struct icmphdr *)(skb->data + offset); ++ struct net *net = dev_net_rcu(skb->dev); + int type = icmp_hdr(skb)->type; + int code = icmp_hdr(skb)->code; +- struct net *net = dev_net(skb->dev); + + /* + * Use ping_err to handle all icmp errors except those +diff --git a/net/ipv4/route.c b/net/ipv4/route.c +index 61fc2166a870e6..97dc30a03dbf26 100644 +--- a/net/ipv4/route.c ++++ b/net/ipv4/route.c +@@ -393,7 +393,13 @@ static inline int ip_rt_proc_init(void) + + static inline bool rt_is_expired(const struct rtable *rth) + { +- return rth->rt_genid != rt_genid_ipv4(dev_net(rth->dst.dev)); ++ bool res; ++ ++ rcu_read_lock(); ++ res = rth->rt_genid != rt_genid_ipv4(dev_net_rcu(rth->dst.dev)); ++ rcu_read_unlock(); ++ ++ return res; + } + + void rt_cache_flush(struct net *net) +@@ -1014,9 +1020,9 @@ out: kfree_skb_reason(skb, reason); + static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu) + { + struct dst_entry *dst = &rt->dst; +- struct net *net = dev_net(dst->dev); + struct fib_result res; + bool lock = false; ++ struct net *net; + u32 old_mtu; + + if (ip_mtu_locked(dst)) +@@ -1026,6 +1032,8 @@ static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu) + if (old_mtu < mtu) + return; + ++ rcu_read_lock(); ++ net = dev_net_rcu(dst->dev); + if (mtu < net->ipv4.ip_rt_min_pmtu) { + lock = true; + mtu = min(old_mtu, net->ipv4.ip_rt_min_pmtu); +@@ -1033,17 +1041,29 @@ static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu) + + if (rt->rt_pmtu == mtu && !lock && + time_before(jiffies, dst->expires - net->ipv4.ip_rt_mtu_expires / 2)) +- return; ++ goto out; + +- rcu_read_lock(); + if (fib_lookup(net, fl4, &res, 0) == 0) { + struct fib_nh_common *nhc; + + fib_select_path(net, &res, fl4, NULL); ++#ifdef CONFIG_IP_ROUTE_MULTIPATH ++ if (fib_info_num_path(res.fi) > 1) { ++ int nhsel; ++ ++ for (nhsel = 0; nhsel < fib_info_num_path(res.fi); nhsel++) { ++ nhc = fib_info_nhc(res.fi, nhsel); ++ update_or_create_fnhe(nhc, fl4->daddr, 0, mtu, lock, ++ jiffies + net->ipv4.ip_rt_mtu_expires); ++ } ++ goto out; ++ } ++#endif /* CONFIG_IP_ROUTE_MULTIPATH */ + nhc = FIB_RES_NHC(res); + update_or_create_fnhe(nhc, fl4->daddr, 0, mtu, lock, + jiffies + net->ipv4.ip_rt_mtu_expires); + } ++out: + rcu_read_unlock(); + } + +@@ -1306,10 +1326,15 @@ static void set_class_tag(struct rtable *rt, u32 tag) + + static unsigned int ipv4_default_advmss(const struct dst_entry *dst) + { +- struct net *net = dev_net(dst->dev); + unsigned int header_size = sizeof(struct tcphdr) + sizeof(struct iphdr); +- unsigned int advmss = max_t(unsigned int, ipv4_mtu(dst) - header_size, +- net->ipv4.ip_rt_min_advmss); ++ unsigned int advmss; ++ struct net *net; ++ ++ rcu_read_lock(); ++ net = dev_net_rcu(dst->dev); ++ advmss = max_t(unsigned int, ipv4_mtu(dst) - header_size, ++ net->ipv4.ip_rt_min_advmss); ++ rcu_read_unlock(); + + return min(advmss, IPV4_MAX_PMTU - header_size); + } +diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c +index 35df405ce1f753..fd91fd139d76cf 100644 +--- a/net/ipv6/icmp.c ++++ b/net/ipv6/icmp.c +@@ -76,7 +76,7 @@ static int icmpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, + { + /* icmpv6_notify checks 8 bytes can be pulled, icmp6hdr is 8 bytes */ + struct icmp6hdr *icmp6 = (struct icmp6hdr *) (skb->data + offset); +- struct net *net = dev_net(skb->dev); ++ struct net *net = dev_net_rcu(skb->dev); + + if (type == ICMPV6_PKT_TOOBIG) + ip6_update_pmtu(skb, net, info, skb->dev->ifindex, 0, sock_net_uid(net, NULL)); +@@ -473,7 +473,10 @@ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info, + + if (!skb->dev) + return; +- net = dev_net(skb->dev); ++ ++ rcu_read_lock(); ++ ++ net = dev_net_rcu(skb->dev); + mark = IP6_REPLY_MARK(net, skb->mark); + /* + * Make sure we respect the rules +@@ -496,7 +499,7 @@ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info, + !(type == ICMPV6_PARAMPROB && + code == ICMPV6_UNK_OPTION && + (opt_unrec(skb, info)))) +- return; ++ goto out; + + saddr = NULL; + } +@@ -526,7 +529,7 @@ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info, + if ((addr_type == IPV6_ADDR_ANY) || (addr_type & IPV6_ADDR_MULTICAST)) { + net_dbg_ratelimited("icmp6_send: addr_any/mcast source [%pI6c > %pI6c]\n", + &hdr->saddr, &hdr->daddr); +- return; ++ goto out; + } + + /* +@@ -535,7 +538,7 @@ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info, + if (is_ineligible(skb)) { + net_dbg_ratelimited("icmp6_send: no reply to icmp error [%pI6c > %pI6c]\n", + &hdr->saddr, &hdr->daddr); +- return; ++ goto out; + } + + /* Needed by both icmpv6_global_allow and icmpv6_xmit_lock */ +@@ -582,7 +585,7 @@ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info, + np = inet6_sk(sk); + + if (!icmpv6_xrlim_allow(sk, type, &fl6, apply_ratelimit)) +- goto out; ++ goto out_unlock; + + tmp_hdr.icmp6_type = type; + tmp_hdr.icmp6_code = code; +@@ -600,7 +603,7 @@ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info, + + dst = icmpv6_route_lookup(net, skb, sk, &fl6); + if (IS_ERR(dst)) +- goto out; ++ goto out_unlock; + + ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst); + +@@ -616,7 +619,6 @@ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info, + goto out_dst_release; + } + +- rcu_read_lock(); + idev = __in6_dev_get(skb->dev); + + if (ip6_append_data(sk, icmpv6_getfrag, &msg, +@@ -630,13 +632,15 @@ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info, + icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr, + len + sizeof(struct icmp6hdr)); + } +- rcu_read_unlock(); ++ + out_dst_release: + dst_release(dst); +-out: ++out_unlock: + icmpv6_xmit_unlock(sk); + out_bh_enable: + local_bh_enable(); ++out: ++ rcu_read_unlock(); + } + EXPORT_SYMBOL(icmp6_send); + +@@ -679,8 +683,8 @@ int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs, int type, + skb_pull(skb2, nhs); + skb_reset_network_header(skb2); + +- rt = rt6_lookup(dev_net(skb->dev), &ipv6_hdr(skb2)->saddr, NULL, 0, +- skb, 0); ++ rt = rt6_lookup(dev_net_rcu(skb->dev), &ipv6_hdr(skb2)->saddr, ++ NULL, 0, skb, 0); + + if (rt && rt->dst.dev) + skb2->dev = rt->dst.dev; +@@ -717,7 +721,7 @@ EXPORT_SYMBOL(ip6_err_gen_icmpv6_unreach); + + static enum skb_drop_reason icmpv6_echo_reply(struct sk_buff *skb) + { +- struct net *net = dev_net(skb->dev); ++ struct net *net = dev_net_rcu(skb->dev); + struct sock *sk; + struct inet6_dev *idev; + struct ipv6_pinfo *np; +@@ -832,7 +836,7 @@ enum skb_drop_reason icmpv6_notify(struct sk_buff *skb, u8 type, + u8 code, __be32 info) + { + struct inet6_skb_parm *opt = IP6CB(skb); +- struct net *net = dev_net(skb->dev); ++ struct net *net = dev_net_rcu(skb->dev); + const struct inet6_protocol *ipprot; + enum skb_drop_reason reason; + int inner_offset; +@@ -889,7 +893,7 @@ enum skb_drop_reason icmpv6_notify(struct sk_buff *skb, u8 type, + static int icmpv6_rcv(struct sk_buff *skb) + { + enum skb_drop_reason reason = SKB_DROP_REASON_NOT_SPECIFIED; +- struct net *net = dev_net(skb->dev); ++ struct net *net = dev_net_rcu(skb->dev); + struct net_device *dev = icmp6_dev(skb); + struct inet6_dev *idev = __in6_dev_get(dev); + const struct in6_addr *saddr, *daddr; +@@ -921,7 +925,7 @@ static int icmpv6_rcv(struct sk_buff *skb) + skb_set_network_header(skb, nh); + } + +- __ICMP6_INC_STATS(dev_net(dev), idev, ICMP6_MIB_INMSGS); ++ __ICMP6_INC_STATS(dev_net_rcu(dev), idev, ICMP6_MIB_INMSGS); + + saddr = &ipv6_hdr(skb)->saddr; + daddr = &ipv6_hdr(skb)->daddr; +@@ -939,7 +943,7 @@ static int icmpv6_rcv(struct sk_buff *skb) + + type = hdr->icmp6_type; + +- ICMP6MSGIN_INC_STATS(dev_net(dev), idev, type); ++ ICMP6MSGIN_INC_STATS(dev_net_rcu(dev), idev, type); + + switch (type) { + case ICMPV6_ECHO_REQUEST: +@@ -1034,9 +1038,9 @@ static int icmpv6_rcv(struct sk_buff *skb) + + csum_error: + reason = SKB_DROP_REASON_ICMP_CSUM; +- __ICMP6_INC_STATS(dev_net(dev), idev, ICMP6_MIB_CSUMERRORS); ++ __ICMP6_INC_STATS(dev_net_rcu(dev), idev, ICMP6_MIB_CSUMERRORS); + discard_it: +- __ICMP6_INC_STATS(dev_net(dev), idev, ICMP6_MIB_INERRORS); ++ __ICMP6_INC_STATS(dev_net_rcu(dev), idev, ICMP6_MIB_INERRORS); + drop_no_count: + kfree_skb_reason(skb, reason); + return 0; +diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c +index 6e2f77a95a657a..9bb246c09fcee8 100644 +--- a/net/ipv6/mcast.c ++++ b/net/ipv6/mcast.c +@@ -1729,21 +1729,19 @@ static struct sk_buff *mld_newpack(struct inet6_dev *idev, unsigned int mtu) + struct net_device *dev = idev->dev; + int hlen = LL_RESERVED_SPACE(dev); + int tlen = dev->needed_tailroom; +- struct net *net = dev_net(dev); + const struct in6_addr *saddr; + struct in6_addr addr_buf; + struct mld2_report *pmr; + struct sk_buff *skb; + unsigned int size; + struct sock *sk; +- int err; ++ struct net *net; + +- sk = net->ipv6.igmp_sk; + /* we assume size > sizeof(ra) here + * Also try to not allocate high-order pages for big MTU + */ + size = min_t(int, mtu, PAGE_SIZE / 2) + hlen + tlen; +- skb = sock_alloc_send_skb(sk, size, 1, &err); ++ skb = alloc_skb(size, GFP_KERNEL); + if (!skb) + return NULL; + +@@ -1751,6 +1749,12 @@ static struct sk_buff *mld_newpack(struct inet6_dev *idev, unsigned int mtu) + skb_reserve(skb, hlen); + skb_tailroom_reserve(skb, mtu, tlen); + ++ rcu_read_lock(); ++ ++ net = dev_net_rcu(dev); ++ sk = net->ipv6.igmp_sk; ++ skb_set_owner_w(skb, sk); ++ + if (ipv6_get_lladdr(dev, &addr_buf, IFA_F_TENTATIVE)) { + /* : + * use unspecified address as the source address +@@ -1762,6 +1766,8 @@ static struct sk_buff *mld_newpack(struct inet6_dev *idev, unsigned int mtu) + + ip6_mc_hdr(sk, skb, dev, saddr, &mld2_all_mcr, NEXTHDR_HOP, 0); + ++ rcu_read_unlock(); ++ + skb_put_data(skb, ra, sizeof(ra)); + + skb_set_transport_header(skb, skb_tail_pointer(skb) - skb->data); +@@ -2121,21 +2127,21 @@ static void mld_send_cr(struct inet6_dev *idev) + + static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) + { +- struct net *net = dev_net(dev); +- struct sock *sk = net->ipv6.igmp_sk; ++ const struct in6_addr *snd_addr, *saddr; ++ int err, len, payload_len, full_len; ++ struct in6_addr addr_buf; + struct inet6_dev *idev; + struct sk_buff *skb; + struct mld_msg *hdr; +- const struct in6_addr *snd_addr, *saddr; +- struct in6_addr addr_buf; + int hlen = LL_RESERVED_SPACE(dev); + int tlen = dev->needed_tailroom; +- int err, len, payload_len, full_len; + u8 ra[8] = { IPPROTO_ICMPV6, 0, + IPV6_TLV_ROUTERALERT, 2, 0, 0, + IPV6_TLV_PADN, 0 }; +- struct flowi6 fl6; + struct dst_entry *dst; ++ struct flowi6 fl6; ++ struct net *net; ++ struct sock *sk; + + if (type == ICMPV6_MGM_REDUCTION) + snd_addr = &in6addr_linklocal_allrouters; +@@ -2146,19 +2152,21 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) + payload_len = len + sizeof(ra); + full_len = sizeof(struct ipv6hdr) + payload_len; + +- rcu_read_lock(); +- IP6_INC_STATS(net, __in6_dev_get(dev), IPSTATS_MIB_OUTREQUESTS); +- rcu_read_unlock(); ++ skb = alloc_skb(hlen + tlen + full_len, GFP_KERNEL); + +- skb = sock_alloc_send_skb(sk, hlen + tlen + full_len, 1, &err); ++ rcu_read_lock(); + ++ net = dev_net_rcu(dev); ++ idev = __in6_dev_get(dev); ++ IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTREQUESTS); + if (!skb) { +- rcu_read_lock(); +- IP6_INC_STATS(net, __in6_dev_get(dev), +- IPSTATS_MIB_OUTDISCARDS); ++ IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS); + rcu_read_unlock(); + return; + } ++ sk = net->ipv6.igmp_sk; ++ skb_set_owner_w(skb, sk); ++ + skb->priority = TC_PRIO_CONTROL; + skb_reserve(skb, hlen); + +@@ -2183,9 +2191,6 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) + IPPROTO_ICMPV6, + csum_partial(hdr, len, 0)); + +- rcu_read_lock(); +- idev = __in6_dev_get(skb->dev); +- + icmpv6_flow_init(sk, &fl6, type, + &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, + skb->dev->ifindex); +diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c +index 2ad0ef47b07c24..8d853971f2f68e 100644 +--- a/net/ipv6/ndisc.c ++++ b/net/ipv6/ndisc.c +@@ -418,15 +418,11 @@ static struct sk_buff *ndisc_alloc_skb(struct net_device *dev, + { + int hlen = LL_RESERVED_SPACE(dev); + int tlen = dev->needed_tailroom; +- struct sock *sk = dev_net(dev)->ipv6.ndisc_sk; + struct sk_buff *skb; + + skb = alloc_skb(hlen + sizeof(struct ipv6hdr) + len + tlen, GFP_ATOMIC); +- if (!skb) { +- ND_PRINTK(0, err, "ndisc: %s failed to allocate an skb\n", +- __func__); ++ if (!skb) + return NULL; +- } + + skb->protocol = htons(ETH_P_IPV6); + skb->dev = dev; +@@ -437,7 +433,9 @@ static struct sk_buff *ndisc_alloc_skb(struct net_device *dev, + /* Manually assign socket ownership as we avoid calling + * sock_alloc_send_pskb() to bypass wmem buffer limits + */ +- skb_set_owner_w(skb, sk); ++ rcu_read_lock(); ++ skb_set_owner_w(skb, dev_net_rcu(dev)->ipv6.ndisc_sk); ++ rcu_read_unlock(); + + return skb; + } +@@ -473,16 +471,20 @@ static void ip6_nd_hdr(struct sk_buff *skb, + void ndisc_send_skb(struct sk_buff *skb, const struct in6_addr *daddr, + const struct in6_addr *saddr) + { ++ struct icmp6hdr *icmp6h = icmp6_hdr(skb); + struct dst_entry *dst = skb_dst(skb); +- struct net *net = dev_net(skb->dev); +- struct sock *sk = net->ipv6.ndisc_sk; + struct inet6_dev *idev; ++ struct net *net; ++ struct sock *sk; + int err; +- struct icmp6hdr *icmp6h = icmp6_hdr(skb); + u8 type; + + type = icmp6h->icmp6_type; + ++ rcu_read_lock(); ++ ++ net = dev_net_rcu(skb->dev); ++ sk = net->ipv6.ndisc_sk; + if (!dst) { + struct flowi6 fl6; + int oif = skb->dev->ifindex; +@@ -490,6 +492,7 @@ void ndisc_send_skb(struct sk_buff *skb, const struct in6_addr *daddr, + icmpv6_flow_init(sk, &fl6, type, saddr, daddr, oif); + dst = icmp6_dst_alloc(skb->dev, &fl6); + if (IS_ERR(dst)) { ++ rcu_read_unlock(); + kfree_skb(skb); + return; + } +@@ -504,7 +507,6 @@ void ndisc_send_skb(struct sk_buff *skb, const struct in6_addr *daddr, + + ip6_nd_hdr(skb, saddr, daddr, inet6_sk(sk)->hop_limit, skb->len); + +- rcu_read_lock(); + idev = __in6_dev_get(dst->dev); + IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTREQUESTS); + +@@ -1680,7 +1682,7 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target) + bool ret; + + if (netif_is_l3_master(skb->dev)) { +- dev = __dev_get_by_index(dev_net(skb->dev), IPCB(skb)->iif); ++ dev = dev_get_by_index_rcu(dev_net(skb->dev), IPCB(skb)->iif); + if (!dev) + return; + } +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index c5cee40a658b46..5715d54f3d0bed 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -3188,13 +3188,18 @@ static unsigned int ip6_default_advmss(const struct dst_entry *dst) + { + struct net_device *dev = dst->dev; + unsigned int mtu = dst_mtu(dst); +- struct net *net = dev_net(dev); ++ struct net *net; + + mtu -= sizeof(struct ipv6hdr) + sizeof(struct tcphdr); + ++ rcu_read_lock(); ++ ++ net = dev_net_rcu(dev); + if (mtu < net->ipv6.sysctl.ip6_rt_min_advmss) + mtu = net->ipv6.sysctl.ip6_rt_min_advmss; + ++ rcu_read_unlock(); ++ + /* + * Maximal non-jumbo IPv6 payload is IPV6_MAXPLEN and + * corresponding MSS is IPV6_MAXPLEN - tcp_header_size. +diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c +index b7232142c13f83..cb52fac7caa3cd 100644 +--- a/net/openvswitch/datapath.c ++++ b/net/openvswitch/datapath.c +@@ -2103,6 +2103,7 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb, + { + struct ovs_header *ovs_header; + struct ovs_vport_stats vport_stats; ++ struct net *net_vport; + int err; + + ovs_header = genlmsg_put(skb, portid, seq, &dp_vport_genl_family, +@@ -2119,12 +2120,15 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb, + nla_put_u32(skb, OVS_VPORT_ATTR_IFINDEX, vport->dev->ifindex)) + goto nla_put_failure; + +- if (!net_eq(net, dev_net(vport->dev))) { +- int id = peernet2id_alloc(net, dev_net(vport->dev), gfp); ++ rcu_read_lock(); ++ net_vport = dev_net_rcu(vport->dev); ++ if (!net_eq(net, net_vport)) { ++ int id = peernet2id_alloc(net, net_vport, GFP_ATOMIC); + + if (nla_put_s32(skb, OVS_VPORT_ATTR_NETNSID, id)) +- goto nla_put_failure; ++ goto nla_put_failure_unlock; + } ++ rcu_read_unlock(); + + ovs_vport_get_stats(vport, &vport_stats); + if (nla_put_64bit(skb, OVS_VPORT_ATTR_STATS, +@@ -2145,6 +2149,8 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb, + genlmsg_end(skb, ovs_header); + return 0; + ++nla_put_failure_unlock: ++ rcu_read_unlock(); + nla_put_failure: + err = -EMSGSIZE; + error: +diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c +index f4dbf5f87962d9..618b18e80cea04 100644 +--- a/net/vmw_vsock/af_vsock.c ++++ b/net/vmw_vsock/af_vsock.c +@@ -336,7 +336,10 @@ EXPORT_SYMBOL_GPL(vsock_find_connected_socket); + + void vsock_remove_sock(struct vsock_sock *vsk) + { +- vsock_remove_bound(vsk); ++ /* Transport reassignment must not remove the binding. */ ++ if (sock_flag(sk_vsock(vsk), SOCK_DEAD)) ++ vsock_remove_bound(vsk); ++ + vsock_remove_connected(vsk); + } + EXPORT_SYMBOL_GPL(vsock_remove_sock); +@@ -820,6 +823,13 @@ static void __vsock_release(struct sock *sk, int level) + */ + lock_sock_nested(sk, level); + ++ /* Indicate to vsock_remove_sock() that the socket is being released and ++ * can be removed from the bound_table. Unlike transport reassignment ++ * case, where the socket must remain bound despite vsock_remove_sock() ++ * being called from the transport release() callback. ++ */ ++ sock_set_flag(sk, SOCK_DEAD); ++ + if (vsk->transport) + vsk->transport->release(vsk); + else if (sock_type_connectible(sk->sk_type)) +diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c +index ddf68be0af14a5..ce80adc30fe946 100644 +--- a/sound/soc/intel/boards/bytcr_rt5640.c ++++ b/sound/soc/intel/boards/bytcr_rt5640.c +@@ -1132,7 +1132,22 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { + BYT_RT5640_SSP0_AIF2 | + BYT_RT5640_MCLK_EN), + }, +- { /* Vexia Edu Atla 10 tablet */ ++ { ++ /* Vexia Edu Atla 10 tablet 5V version */ ++ .matches = { ++ /* Having all 3 of these not set is somewhat unique */ ++ DMI_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "To be filled by O.E.M."), ++ DMI_MATCH(DMI_BOARD_NAME, "To be filled by O.E.M."), ++ /* Above strings are too generic, also match on BIOS date */ ++ DMI_MATCH(DMI_BIOS_DATE, "05/14/2015"), ++ }, ++ .driver_data = (void *)(BYTCR_INPUT_DEFAULTS | ++ BYT_RT5640_JD_NOT_INV | ++ BYT_RT5640_SSP0_AIF1 | ++ BYT_RT5640_MCLK_EN), ++ }, ++ { /* Vexia Edu Atla 10 tablet 9V version */ + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), + DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"), +diff --git a/tools/testing/selftests/gpio/gpio-sim.sh b/tools/testing/selftests/gpio/gpio-sim.sh +index 6fb66a687f1737..bbc29ed9c60a91 100755 +--- a/tools/testing/selftests/gpio/gpio-sim.sh ++++ b/tools/testing/selftests/gpio/gpio-sim.sh +@@ -46,12 +46,6 @@ remove_chip() { + rmdir $CONFIGFS_DIR/$CHIP || fail "Unable to remove the chip" + } + +-configfs_cleanup() { +- for CHIP in `ls $CONFIGFS_DIR/`; do +- remove_chip $CHIP +- done +-} +- + create_chip() { + local CHIP=$1 + +@@ -105,6 +99,13 @@ disable_chip() { + echo 0 > $CONFIGFS_DIR/$CHIP/live || fail "Unable to disable the chip" + } + ++configfs_cleanup() { ++ for CHIP in `ls $CONFIGFS_DIR/`; do ++ disable_chip $CHIP ++ remove_chip $CHIP ++ done ++} ++ + configfs_chip_name() { + local CHIP=$1 + local BANK=$2 +@@ -181,6 +182,7 @@ create_chip chip + create_bank chip bank + enable_chip chip + test -n `cat $CONFIGFS_DIR/chip/bank/chip_name` || fail "chip_name doesn't work" ++disable_chip chip + remove_chip chip + + echo "1.2. chip_name returns 'none' if the chip is still pending" +@@ -195,6 +197,7 @@ create_chip chip + create_bank chip bank + enable_chip chip + test -n `cat $CONFIGFS_DIR/chip/dev_name` || fail "dev_name doesn't work" ++disable_chip chip + remove_chip chip + + echo "2. Creating and configuring simulated chips" +@@ -204,6 +207,7 @@ create_chip chip + create_bank chip bank + enable_chip chip + test "`get_chip_num_lines chip bank`" = "1" || fail "default number of lines is not 1" ++disable_chip chip + remove_chip chip + + echo "2.2. Number of lines can be specified" +@@ -212,6 +216,7 @@ create_bank chip bank + set_num_lines chip bank 16 + enable_chip chip + test "`get_chip_num_lines chip bank`" = "16" || fail "number of lines is not 16" ++disable_chip chip + remove_chip chip + + echo "2.3. Label can be set" +@@ -220,6 +225,7 @@ create_bank chip bank + set_label chip bank foobar + enable_chip chip + test "`get_chip_label chip bank`" = "foobar" || fail "label is incorrect" ++disable_chip chip + remove_chip chip + + echo "2.4. Label can be left empty" +@@ -227,6 +233,7 @@ create_chip chip + create_bank chip bank + enable_chip chip + test -z "`cat $CONFIGFS_DIR/chip/bank/label`" || fail "label is not empty" ++disable_chip chip + remove_chip chip + + echo "2.5. Line names can be configured" +@@ -238,6 +245,7 @@ set_line_name chip bank 2 bar + enable_chip chip + test "`get_line_name chip bank 0`" = "foo" || fail "line name is incorrect" + test "`get_line_name chip bank 2`" = "bar" || fail "line name is incorrect" ++disable_chip chip + remove_chip chip + + echo "2.6. Line config can remain unused if offset is greater than number of lines" +@@ -248,6 +256,7 @@ set_line_name chip bank 5 foobar + enable_chip chip + test "`get_line_name chip bank 0`" = "" || fail "line name is incorrect" + test "`get_line_name chip bank 1`" = "" || fail "line name is incorrect" ++disable_chip chip + remove_chip chip + + echo "2.7. Line configfs directory names are sanitized" +@@ -267,6 +276,7 @@ for CHIP in $CHIPS; do + enable_chip $CHIP + done + for CHIP in $CHIPS; do ++ disable_chip $CHIP + remove_chip $CHIP + done + +@@ -278,6 +288,7 @@ echo foobar > $CONFIGFS_DIR/chip/bank/label 2> /dev/null && \ + fail "Setting label of a live chip should fail" + echo 8 > $CONFIGFS_DIR/chip/bank/num_lines 2> /dev/null && \ + fail "Setting number of lines of a live chip should fail" ++disable_chip chip + remove_chip chip + + echo "2.10. Can't create line items when chip is live" +@@ -285,6 +296,7 @@ create_chip chip + create_bank chip bank + enable_chip chip + mkdir $CONFIGFS_DIR/chip/bank/line0 2> /dev/null && fail "Creating line item should fail" ++disable_chip chip + remove_chip chip + + echo "2.11. Probe errors are propagated to user-space" +@@ -316,6 +328,7 @@ mkdir -p $CONFIGFS_DIR/chip/bank/line4/hog + enable_chip chip + $BASE_DIR/gpio-mockup-cdev -s 1 /dev/`configfs_chip_name chip bank` 4 2> /dev/null && \ + fail "Setting the value of a hogged line shouldn't succeed" ++disable_chip chip + remove_chip chip + + echo "3. Controlling simulated chips" +@@ -331,6 +344,7 @@ test "$?" = "1" || fail "pull set incorrectly" + sysfs_set_pull chip bank 0 pull-down + $BASE_DIR/gpio-mockup-cdev /dev/`configfs_chip_name chip bank` 1 + test "$?" = "0" || fail "pull set incorrectly" ++disable_chip chip + remove_chip chip + + echo "3.2. Pull can be read from sysfs" +@@ -344,6 +358,7 @@ SYSFS_PATH=/sys/devices/platform/$DEVNAME/$CHIPNAME/sim_gpio0/pull + test `cat $SYSFS_PATH` = "pull-down" || fail "reading the pull failed" + sysfs_set_pull chip bank 0 pull-up + test `cat $SYSFS_PATH` = "pull-up" || fail "reading the pull failed" ++disable_chip chip + remove_chip chip + + echo "3.3. Incorrect input in sysfs is rejected" +@@ -355,6 +370,7 @@ DEVNAME=`configfs_dev_name chip` + CHIPNAME=`configfs_chip_name chip bank` + SYSFS_PATH="/sys/devices/platform/$DEVNAME/$CHIPNAME/sim_gpio0/pull" + echo foobar > $SYSFS_PATH 2> /dev/null && fail "invalid input not detected" ++disable_chip chip + remove_chip chip + + echo "3.4. Can't write to value" +@@ -365,6 +381,7 @@ DEVNAME=`configfs_dev_name chip` + CHIPNAME=`configfs_chip_name chip bank` + SYSFS_PATH="/sys/devices/platform/$DEVNAME/$CHIPNAME/sim_gpio0/value" + echo 1 > $SYSFS_PATH 2> /dev/null && fail "writing to 'value' succeeded unexpectedly" ++disable_chip chip + remove_chip chip + + echo "4. Simulated GPIO chips are functional" +@@ -382,6 +399,7 @@ $BASE_DIR/gpio-mockup-cdev -s 1 /dev/`configfs_chip_name chip bank` 0 & + sleep 0.1 # FIXME Any better way? + test `cat $SYSFS_PATH` = "1" || fail "incorrect value read from sysfs" + kill $! ++disable_chip chip + remove_chip chip + + echo "4.2. Bias settings work correctly" +@@ -394,6 +412,7 @@ CHIPNAME=`configfs_chip_name chip bank` + SYSFS_PATH="/sys/devices/platform/$DEVNAME/$CHIPNAME/sim_gpio0/value" + $BASE_DIR/gpio-mockup-cdev -b pull-up /dev/`configfs_chip_name chip bank` 0 + test `cat $SYSFS_PATH` = "1" || fail "bias setting does not work" ++disable_chip chip + remove_chip chip + + echo "GPIO $MODULE test PASS" +diff --git a/tools/testing/selftests/net/pmtu.sh b/tools/testing/selftests/net/pmtu.sh +index 1c0dd2f7816782..771f237c43534e 100755 +--- a/tools/testing/selftests/net/pmtu.sh ++++ b/tools/testing/selftests/net/pmtu.sh +@@ -197,6 +197,12 @@ + # + # - pmtu_ipv6_route_change + # Same as above but with IPv6 ++# ++# - pmtu_ipv4_mp_exceptions ++# Use the same topology as in pmtu_ipv4, but add routeable addresses ++# on host A and B on lo reachable via both routers. Host A and B ++# addresses have multipath routes to each other, b_r1 mtu = 1500. ++# Check that PMTU exceptions are created for both paths. + + source lib.sh + source net_helper.sh +@@ -266,7 +272,8 @@ tests=" + list_flush_ipv4_exception ipv4: list and flush cached exceptions 1 + list_flush_ipv6_exception ipv6: list and flush cached exceptions 1 + pmtu_ipv4_route_change ipv4: PMTU exception w/route replace 1 +- pmtu_ipv6_route_change ipv6: PMTU exception w/route replace 1" ++ pmtu_ipv6_route_change ipv6: PMTU exception w/route replace 1 ++ pmtu_ipv4_mp_exceptions ipv4: PMTU multipath nh exceptions 1" + + # Addressing and routing for tests with routers: four network segments, with + # index SEGMENT between 1 and 4, a common prefix (PREFIX4 or PREFIX6) and an +@@ -343,6 +350,9 @@ tunnel6_a_addr="fd00:2::a" + tunnel6_b_addr="fd00:2::b" + tunnel6_mask="64" + ++host4_a_addr="192.168.99.99" ++host4_b_addr="192.168.88.88" ++ + dummy6_0_prefix="fc00:1000::" + dummy6_1_prefix="fc00:1001::" + dummy6_mask="64" +@@ -902,6 +912,52 @@ setup_ovs_bridge() { + run_cmd ip route add ${prefix6}:${b_r1}::1 via ${prefix6}:${a_r1}::2 + } + ++setup_multipath_new() { ++ # Set up host A with multipath routes to host B host4_b_addr ++ run_cmd ${ns_a} ip addr add ${host4_a_addr} dev lo ++ run_cmd ${ns_a} ip nexthop add id 401 via ${prefix4}.${a_r1}.2 dev veth_A-R1 ++ run_cmd ${ns_a} ip nexthop add id 402 via ${prefix4}.${a_r2}.2 dev veth_A-R2 ++ run_cmd ${ns_a} ip nexthop add id 403 group 401/402 ++ run_cmd ${ns_a} ip route add ${host4_b_addr} src ${host4_a_addr} nhid 403 ++ ++ # Set up host B with multipath routes to host A host4_a_addr ++ run_cmd ${ns_b} ip addr add ${host4_b_addr} dev lo ++ run_cmd ${ns_b} ip nexthop add id 401 via ${prefix4}.${b_r1}.2 dev veth_B-R1 ++ run_cmd ${ns_b} ip nexthop add id 402 via ${prefix4}.${b_r2}.2 dev veth_B-R2 ++ run_cmd ${ns_b} ip nexthop add id 403 group 401/402 ++ run_cmd ${ns_b} ip route add ${host4_a_addr} src ${host4_b_addr} nhid 403 ++} ++ ++setup_multipath_old() { ++ # Set up host A with multipath routes to host B host4_b_addr ++ run_cmd ${ns_a} ip addr add ${host4_a_addr} dev lo ++ run_cmd ${ns_a} ip route add ${host4_b_addr} \ ++ src ${host4_a_addr} \ ++ nexthop via ${prefix4}.${a_r1}.2 weight 1 \ ++ nexthop via ${prefix4}.${a_r2}.2 weight 1 ++ ++ # Set up host B with multipath routes to host A host4_a_addr ++ run_cmd ${ns_b} ip addr add ${host4_b_addr} dev lo ++ run_cmd ${ns_b} ip route add ${host4_a_addr} \ ++ src ${host4_b_addr} \ ++ nexthop via ${prefix4}.${b_r1}.2 weight 1 \ ++ nexthop via ${prefix4}.${b_r2}.2 weight 1 ++} ++ ++setup_multipath() { ++ if [ "$USE_NH" = "yes" ]; then ++ setup_multipath_new ++ else ++ setup_multipath_old ++ fi ++ ++ # Set up routers with routes to dummies ++ run_cmd ${ns_r1} ip route add ${host4_a_addr} via ${prefix4}.${a_r1}.1 ++ run_cmd ${ns_r2} ip route add ${host4_a_addr} via ${prefix4}.${a_r2}.1 ++ run_cmd ${ns_r1} ip route add ${host4_b_addr} via ${prefix4}.${b_r1}.1 ++ run_cmd ${ns_r2} ip route add ${host4_b_addr} via ${prefix4}.${b_r2}.1 ++} ++ + setup() { + [ "$(id -u)" -ne 0 ] && echo " need to run as root" && return $ksft_skip + +@@ -982,23 +1038,15 @@ link_get_mtu() { + } + + route_get_dst_exception() { +- ns_cmd="${1}" +- dst="${2}" +- dsfield="${3}" ++ ns_cmd="${1}"; shift + +- if [ -z "${dsfield}" ]; then +- dsfield=0 +- fi +- +- ${ns_cmd} ip route get "${dst}" dsfield "${dsfield}" ++ ${ns_cmd} ip route get "$@" + } + + route_get_dst_pmtu_from_exception() { +- ns_cmd="${1}" +- dst="${2}" +- dsfield="${3}" ++ ns_cmd="${1}"; shift + +- mtu_parse "$(route_get_dst_exception "${ns_cmd}" "${dst}" "${dsfield}")" ++ mtu_parse "$(route_get_dst_exception "${ns_cmd}" "$@")" + } + + check_pmtu_value() { +@@ -1141,10 +1189,10 @@ test_pmtu_ipv4_dscp_icmp_exception() { + run_cmd "${ns_a}" ping -q -M want -Q "${dsfield}" -c 1 -w 1 -s "${len}" "${dst2}" + + # Check that exceptions have been created with the correct PMTU +- pmtu_1="$(route_get_dst_pmtu_from_exception "${ns_a}" "${dst1}" "${policy_mark}")" ++ pmtu_1="$(route_get_dst_pmtu_from_exception "${ns_a}" "${dst1}" dsfield "${policy_mark}")" + check_pmtu_value "1400" "${pmtu_1}" "exceeding MTU" || return 1 + +- pmtu_2="$(route_get_dst_pmtu_from_exception "${ns_a}" "${dst2}" "${policy_mark}")" ++ pmtu_2="$(route_get_dst_pmtu_from_exception "${ns_a}" "${dst2}" dsfield "${policy_mark}")" + check_pmtu_value "1500" "${pmtu_2}" "exceeding MTU" || return 1 + } + +@@ -1191,9 +1239,9 @@ test_pmtu_ipv4_dscp_udp_exception() { + UDP:"${dst2}":50000,tos="${dsfield}" + + # Check that exceptions have been created with the correct PMTU +- pmtu_1="$(route_get_dst_pmtu_from_exception "${ns_a}" "${dst1}" "${policy_mark}")" ++ pmtu_1="$(route_get_dst_pmtu_from_exception "${ns_a}" "${dst1}" dsfield "${policy_mark}")" + check_pmtu_value "1400" "${pmtu_1}" "exceeding MTU" || return 1 +- pmtu_2="$(route_get_dst_pmtu_from_exception "${ns_a}" "${dst2}" "${policy_mark}")" ++ pmtu_2="$(route_get_dst_pmtu_from_exception "${ns_a}" "${dst2}" dsfield "${policy_mark}")" + check_pmtu_value "1500" "${pmtu_2}" "exceeding MTU" || return 1 + } + +@@ -2234,6 +2282,36 @@ test_pmtu_ipv6_route_change() { + test_pmtu_ipvX_route_change 6 + } + ++test_pmtu_ipv4_mp_exceptions() { ++ setup namespaces routing multipath || return $ksft_skip ++ ++ trace "${ns_a}" veth_A-R1 "${ns_r1}" veth_R1-A \ ++ "${ns_r1}" veth_R1-B "${ns_b}" veth_B-R1 \ ++ "${ns_a}" veth_A-R2 "${ns_r2}" veth_R2-A \ ++ "${ns_r2}" veth_R2-B "${ns_b}" veth_B-R2 ++ ++ # Set up initial MTU values ++ mtu "${ns_a}" veth_A-R1 2000 ++ mtu "${ns_r1}" veth_R1-A 2000 ++ mtu "${ns_r1}" veth_R1-B 1500 ++ mtu "${ns_b}" veth_B-R1 1500 ++ ++ mtu "${ns_a}" veth_A-R2 2000 ++ mtu "${ns_r2}" veth_R2-A 2000 ++ mtu "${ns_r2}" veth_R2-B 1500 ++ mtu "${ns_b}" veth_B-R2 1500 ++ ++ # Ping and expect two nexthop exceptions for two routes ++ run_cmd ${ns_a} ping -q -M want -i 0.1 -c 1 -s 1800 "${host4_b_addr}" ++ ++ # Check that exceptions have been created with the correct PMTU ++ pmtu_a_R1="$(route_get_dst_pmtu_from_exception "${ns_a}" "${host4_b_addr}" oif veth_A-R1)" ++ pmtu_a_R2="$(route_get_dst_pmtu_from_exception "${ns_a}" "${host4_b_addr}" oif veth_A-R2)" ++ ++ check_pmtu_value "1500" "${pmtu_a_R1}" "exceeding MTU (veth_A-R1)" || return 1 ++ check_pmtu_value "1500" "${pmtu_a_R2}" "exceeding MTU (veth_A-R2)" || return 1 ++} ++ + usage() { + echo + echo "$0 [OPTIONS] [TEST]..." +diff --git a/tools/testing/selftests/net/rtnetlink.sh b/tools/testing/selftests/net/rtnetlink.sh +index 488f4964365e73..855505c40ed8eb 100755 +--- a/tools/testing/selftests/net/rtnetlink.sh ++++ b/tools/testing/selftests/net/rtnetlink.sh +@@ -921,10 +921,10 @@ kci_test_ipsec_offload() + # does driver have correct offload info + diff $sysfsf - << EOF + SA count=2 tx=3 +-sa[0] tx ipaddr=0x00000000 00000000 00000000 00000000 ++sa[0] tx ipaddr=$dstip + sa[0] spi=0x00000009 proto=0x32 salt=0x61626364 crypt=1 + sa[0] key=0x34333231 38373635 32313039 36353433 +-sa[1] rx ipaddr=0x00000000 00000000 00000000 037ba8c0 ++sa[1] rx ipaddr=$srcip + sa[1] spi=0x00000009 proto=0x32 salt=0x61626364 crypt=1 + sa[1] key=0x34333231 38373635 32313039 36353433 + EOF +diff --git a/tools/tracing/rtla/src/timerlat_hist.c b/tools/tracing/rtla/src/timerlat_hist.c +index 1525e88c6cf968..a985e57954820e 100644 +--- a/tools/tracing/rtla/src/timerlat_hist.c ++++ b/tools/tracing/rtla/src/timerlat_hist.c +@@ -952,6 +952,14 @@ static int stop_tracing; + static struct trace_instance *hist_inst = NULL; + static void stop_hist(int sig) + { ++ if (stop_tracing) { ++ /* ++ * Stop requested twice in a row; abort event processing and ++ * exit immediately ++ */ ++ tracefs_iterate_stop(hist_inst->inst); ++ return; ++ } + stop_tracing = 1; + if (hist_inst) + trace_instance_stop(hist_inst); +diff --git a/tools/tracing/rtla/src/timerlat_top.c b/tools/tracing/rtla/src/timerlat_top.c +index 5a33789a375e3c..1fed4c8d8520f9 100644 +--- a/tools/tracing/rtla/src/timerlat_top.c ++++ b/tools/tracing/rtla/src/timerlat_top.c +@@ -731,6 +731,14 @@ static int stop_tracing; + static struct trace_instance *top_inst = NULL; + static void stop_top(int sig) + { ++ if (stop_tracing) { ++ /* ++ * Stop requested twice in a row; abort event processing and ++ * exit immediately ++ */ ++ tracefs_iterate_stop(top_inst->inst); ++ return; ++ } + stop_tracing = 1; + if (top_inst) + trace_instance_stop(top_inst); diff --git a/patch/kernel/archive/odroidxu4-6.6/patch-6.6.79-80.patch b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.79-80.patch new file mode 100644 index 000000000000..e9285d473f0b --- /dev/null +++ b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.79-80.patch @@ -0,0 +1,6502 @@ +diff --git a/Documentation/networking/strparser.rst b/Documentation/networking/strparser.rst +index 6cab1f74ae05a3..7f623d1db72aae 100644 +--- a/Documentation/networking/strparser.rst ++++ b/Documentation/networking/strparser.rst +@@ -112,7 +112,7 @@ Functions + Callbacks + ========= + +-There are six callbacks: ++There are seven callbacks: + + :: + +@@ -182,6 +182,13 @@ There are six callbacks: + the length of the message. skb->len - offset may be greater + then full_len since strparser does not trim the skb. + ++ :: ++ ++ int (*read_sock)(struct strparser *strp, read_descriptor_t *desc, ++ sk_read_actor_t recv_actor); ++ ++ The read_sock callback is used by strparser instead of ++ sock->ops->read_sock, if provided. + :: + + int (*read_sock_done)(struct strparser *strp, int err); +diff --git a/Makefile b/Makefile +index de16ab06861410..67c5799f259e2e 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 6 + PATCHLEVEL = 6 +-SUBLEVEL = 79 ++SUBLEVEL = 80 + EXTRAVERSION = + NAME = Pinguïn Aangedreven + +diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi +index d1b6355148620b..f3a1b96f1ee4db 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi +@@ -1828,6 +1828,7 @@ dsi0: dsi@14014000 { + resets = <&mmsys MT8183_MMSYS_SW0_RST_B_DISP_DSI0>; + phys = <&mipi_tx0>; + phy-names = "dphy"; ++ status = "disabled"; + }; + + mutex: mutex@14016000 { +diff --git a/arch/arm64/boot/dts/qcom/sm8450.dtsi b/arch/arm64/boot/dts/qcom/sm8450.dtsi +index 2a49a29713752b..3b4d7882300897 100644 +--- a/arch/arm64/boot/dts/qcom/sm8450.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8450.dtsi +@@ -2135,6 +2135,7 @@ fastrpc { + compatible = "qcom,fastrpc"; + qcom,glink-channels = "fastrpcglink-apps-dsp"; + label = "sdsp"; ++ qcom,non-secure-domain; + #address-cells = <1>; + #size-cells = <0>; + +@@ -2160,6 +2161,112 @@ compute-cb@3 { + }; + }; + ++ remoteproc_adsp: remoteproc@3000000 { ++ compatible = "qcom,sm8450-adsp-pas"; ++ reg = <0x0 0x03000000 0x0 0x10000>; ++ ++ interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>, ++ <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>, ++ <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>, ++ <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>, ++ <&smp2p_adsp_in 3 IRQ_TYPE_EDGE_RISING>; ++ interrupt-names = "wdog", "fatal", "ready", ++ "handover", "stop-ack"; ++ ++ clocks = <&rpmhcc RPMH_CXO_CLK>; ++ clock-names = "xo"; ++ ++ power-domains = <&rpmhpd RPMHPD_LCX>, ++ <&rpmhpd RPMHPD_LMX>; ++ power-domain-names = "lcx", "lmx"; ++ ++ memory-region = <&adsp_mem>; ++ ++ qcom,qmp = <&aoss_qmp>; ++ ++ qcom,smem-states = <&smp2p_adsp_out 0>; ++ qcom,smem-state-names = "stop"; ++ ++ status = "disabled"; ++ ++ remoteproc_adsp_glink: glink-edge { ++ interrupts-extended = <&ipcc IPCC_CLIENT_LPASS ++ IPCC_MPROC_SIGNAL_GLINK_QMP ++ IRQ_TYPE_EDGE_RISING>; ++ mboxes = <&ipcc IPCC_CLIENT_LPASS ++ IPCC_MPROC_SIGNAL_GLINK_QMP>; ++ ++ label = "lpass"; ++ qcom,remote-pid = <2>; ++ ++ gpr { ++ compatible = "qcom,gpr"; ++ qcom,glink-channels = "adsp_apps"; ++ qcom,domain = ; ++ qcom,intents = <512 20>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ q6apm: service@1 { ++ compatible = "qcom,q6apm"; ++ reg = ; ++ #sound-dai-cells = <0>; ++ qcom,protection-domain = "avs/audio", ++ "msm/adsp/audio_pd"; ++ ++ q6apmdai: dais { ++ compatible = "qcom,q6apm-dais"; ++ iommus = <&apps_smmu 0x1801 0x0>; ++ }; ++ ++ q6apmbedai: bedais { ++ compatible = "qcom,q6apm-lpass-dais"; ++ #sound-dai-cells = <1>; ++ }; ++ }; ++ ++ q6prm: service@2 { ++ compatible = "qcom,q6prm"; ++ reg = ; ++ qcom,protection-domain = "avs/audio", ++ "msm/adsp/audio_pd"; ++ ++ q6prmcc: clock-controller { ++ compatible = "qcom,q6prm-lpass-clocks"; ++ #clock-cells = <2>; ++ }; ++ }; ++ }; ++ ++ fastrpc { ++ compatible = "qcom,fastrpc"; ++ qcom,glink-channels = "fastrpcglink-apps-dsp"; ++ label = "adsp"; ++ qcom,non-secure-domain; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ compute-cb@3 { ++ compatible = "qcom,fastrpc-compute-cb"; ++ reg = <3>; ++ iommus = <&apps_smmu 0x1803 0x0>; ++ }; ++ ++ compute-cb@4 { ++ compatible = "qcom,fastrpc-compute-cb"; ++ reg = <4>; ++ iommus = <&apps_smmu 0x1804 0x0>; ++ }; ++ ++ compute-cb@5 { ++ compatible = "qcom,fastrpc-compute-cb"; ++ reg = <5>; ++ iommus = <&apps_smmu 0x1805 0x0>; ++ }; ++ }; ++ }; ++ }; ++ + wsa2macro: codec@31e0000 { + compatible = "qcom,sm8450-lpass-wsa-macro"; + reg = <0 0x031e0000 0 0x1000>; +@@ -2368,111 +2475,6 @@ vamacro: codec@33f0000 { + status = "disabled"; + }; + +- remoteproc_adsp: remoteproc@30000000 { +- compatible = "qcom,sm8450-adsp-pas"; +- reg = <0 0x30000000 0 0x100>; +- +- interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>, +- <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>, +- <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>, +- <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>, +- <&smp2p_adsp_in 3 IRQ_TYPE_EDGE_RISING>; +- interrupt-names = "wdog", "fatal", "ready", +- "handover", "stop-ack"; +- +- clocks = <&rpmhcc RPMH_CXO_CLK>; +- clock-names = "xo"; +- +- power-domains = <&rpmhpd RPMHPD_LCX>, +- <&rpmhpd RPMHPD_LMX>; +- power-domain-names = "lcx", "lmx"; +- +- memory-region = <&adsp_mem>; +- +- qcom,qmp = <&aoss_qmp>; +- +- qcom,smem-states = <&smp2p_adsp_out 0>; +- qcom,smem-state-names = "stop"; +- +- status = "disabled"; +- +- remoteproc_adsp_glink: glink-edge { +- interrupts-extended = <&ipcc IPCC_CLIENT_LPASS +- IPCC_MPROC_SIGNAL_GLINK_QMP +- IRQ_TYPE_EDGE_RISING>; +- mboxes = <&ipcc IPCC_CLIENT_LPASS +- IPCC_MPROC_SIGNAL_GLINK_QMP>; +- +- label = "lpass"; +- qcom,remote-pid = <2>; +- +- gpr { +- compatible = "qcom,gpr"; +- qcom,glink-channels = "adsp_apps"; +- qcom,domain = ; +- qcom,intents = <512 20>; +- #address-cells = <1>; +- #size-cells = <0>; +- +- q6apm: service@1 { +- compatible = "qcom,q6apm"; +- reg = ; +- #sound-dai-cells = <0>; +- qcom,protection-domain = "avs/audio", +- "msm/adsp/audio_pd"; +- +- q6apmdai: dais { +- compatible = "qcom,q6apm-dais"; +- iommus = <&apps_smmu 0x1801 0x0>; +- }; +- +- q6apmbedai: bedais { +- compatible = "qcom,q6apm-lpass-dais"; +- #sound-dai-cells = <1>; +- }; +- }; +- +- q6prm: service@2 { +- compatible = "qcom,q6prm"; +- reg = ; +- qcom,protection-domain = "avs/audio", +- "msm/adsp/audio_pd"; +- +- q6prmcc: clock-controller { +- compatible = "qcom,q6prm-lpass-clocks"; +- #clock-cells = <2>; +- }; +- }; +- }; +- +- fastrpc { +- compatible = "qcom,fastrpc"; +- qcom,glink-channels = "fastrpcglink-apps-dsp"; +- label = "adsp"; +- #address-cells = <1>; +- #size-cells = <0>; +- +- compute-cb@3 { +- compatible = "qcom,fastrpc-compute-cb"; +- reg = <3>; +- iommus = <&apps_smmu 0x1803 0x0>; +- }; +- +- compute-cb@4 { +- compatible = "qcom,fastrpc-compute-cb"; +- reg = <4>; +- iommus = <&apps_smmu 0x1804 0x0>; +- }; +- +- compute-cb@5 { +- compatible = "qcom,fastrpc-compute-cb"; +- reg = <5>; +- iommus = <&apps_smmu 0x1805 0x0>; +- }; +- }; +- }; +- }; +- + remoteproc_cdsp: remoteproc@32300000 { + compatible = "qcom,sm8450-cdsp-pas"; + reg = <0 0x32300000 0 0x10000>; +@@ -2515,6 +2517,7 @@ fastrpc { + compatible = "qcom,fastrpc"; + qcom,glink-channels = "fastrpcglink-apps-dsp"; + label = "cdsp"; ++ qcom,non-secure-domain; + #address-cells = <1>; + #size-cells = <0>; + +diff --git a/arch/arm64/boot/dts/qcom/sm8550.dtsi b/arch/arm64/boot/dts/qcom/sm8550.dtsi +index f3a0e1fe333c4d..bc9a1fca2db3ae 100644 +--- a/arch/arm64/boot/dts/qcom/sm8550.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8550.dtsi +@@ -2026,6 +2026,137 @@ IPCC_MPROC_SIGNAL_GLINK_QMP + }; + }; + ++ remoteproc_adsp: remoteproc@6800000 { ++ compatible = "qcom,sm8550-adsp-pas"; ++ reg = <0x0 0x06800000 0x0 0x10000>; ++ ++ interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>, ++ <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>, ++ <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>, ++ <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>, ++ <&smp2p_adsp_in 3 IRQ_TYPE_EDGE_RISING>; ++ interrupt-names = "wdog", "fatal", "ready", ++ "handover", "stop-ack"; ++ ++ clocks = <&rpmhcc RPMH_CXO_CLK>; ++ clock-names = "xo"; ++ ++ power-domains = <&rpmhpd RPMHPD_LCX>, ++ <&rpmhpd RPMHPD_LMX>; ++ power-domain-names = "lcx", "lmx"; ++ ++ interconnects = <&lpass_lpicx_noc MASTER_LPASS_PROC 0 &mc_virt SLAVE_EBI1 0>; ++ ++ memory-region = <&adspslpi_mem>, <&q6_adsp_dtb_mem>; ++ ++ qcom,qmp = <&aoss_qmp>; ++ ++ qcom,smem-states = <&smp2p_adsp_out 0>; ++ qcom,smem-state-names = "stop"; ++ ++ status = "disabled"; ++ ++ remoteproc_adsp_glink: glink-edge { ++ interrupts-extended = <&ipcc IPCC_CLIENT_LPASS ++ IPCC_MPROC_SIGNAL_GLINK_QMP ++ IRQ_TYPE_EDGE_RISING>; ++ mboxes = <&ipcc IPCC_CLIENT_LPASS ++ IPCC_MPROC_SIGNAL_GLINK_QMP>; ++ ++ label = "lpass"; ++ qcom,remote-pid = <2>; ++ ++ fastrpc { ++ compatible = "qcom,fastrpc"; ++ qcom,glink-channels = "fastrpcglink-apps-dsp"; ++ label = "adsp"; ++ qcom,non-secure-domain; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ compute-cb@3 { ++ compatible = "qcom,fastrpc-compute-cb"; ++ reg = <3>; ++ iommus = <&apps_smmu 0x1003 0x80>, ++ <&apps_smmu 0x1063 0x0>; ++ dma-coherent; ++ }; ++ ++ compute-cb@4 { ++ compatible = "qcom,fastrpc-compute-cb"; ++ reg = <4>; ++ iommus = <&apps_smmu 0x1004 0x80>, ++ <&apps_smmu 0x1064 0x0>; ++ dma-coherent; ++ }; ++ ++ compute-cb@5 { ++ compatible = "qcom,fastrpc-compute-cb"; ++ reg = <5>; ++ iommus = <&apps_smmu 0x1005 0x80>, ++ <&apps_smmu 0x1065 0x0>; ++ dma-coherent; ++ }; ++ ++ compute-cb@6 { ++ compatible = "qcom,fastrpc-compute-cb"; ++ reg = <6>; ++ iommus = <&apps_smmu 0x1006 0x80>, ++ <&apps_smmu 0x1066 0x0>; ++ dma-coherent; ++ }; ++ ++ compute-cb@7 { ++ compatible = "qcom,fastrpc-compute-cb"; ++ reg = <7>; ++ iommus = <&apps_smmu 0x1007 0x80>, ++ <&apps_smmu 0x1067 0x0>; ++ dma-coherent; ++ }; ++ }; ++ ++ gpr { ++ compatible = "qcom,gpr"; ++ qcom,glink-channels = "adsp_apps"; ++ qcom,domain = ; ++ qcom,intents = <512 20>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ q6apm: service@1 { ++ compatible = "qcom,q6apm"; ++ reg = ; ++ #sound-dai-cells = <0>; ++ qcom,protection-domain = "avs/audio", ++ "msm/adsp/audio_pd"; ++ ++ q6apmdai: dais { ++ compatible = "qcom,q6apm-dais"; ++ iommus = <&apps_smmu 0x1001 0x80>, ++ <&apps_smmu 0x1061 0x0>; ++ }; ++ ++ q6apmbedai: bedais { ++ compatible = "qcom,q6apm-lpass-dais"; ++ #sound-dai-cells = <1>; ++ }; ++ }; ++ ++ q6prm: service@2 { ++ compatible = "qcom,q6prm"; ++ reg = ; ++ qcom,protection-domain = "avs/audio", ++ "msm/adsp/audio_pd"; ++ ++ q6prmcc: clock-controller { ++ compatible = "qcom,q6prm-lpass-clocks"; ++ #clock-cells = <2>; ++ }; ++ }; ++ }; ++ }; ++ }; ++ + lpass_wsa2macro: codec@6aa0000 { + compatible = "qcom,sm8550-lpass-wsa-macro"; + reg = <0 0x06aa0000 0 0x1000>; +@@ -3954,131 +4085,6 @@ system-cache-controller@25000000 { + interrupts = ; + }; + +- remoteproc_adsp: remoteproc@30000000 { +- compatible = "qcom,sm8550-adsp-pas"; +- reg = <0x0 0x30000000 0x0 0x100>; +- +- interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>, +- <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>, +- <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>, +- <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>, +- <&smp2p_adsp_in 3 IRQ_TYPE_EDGE_RISING>; +- interrupt-names = "wdog", "fatal", "ready", +- "handover", "stop-ack"; +- +- clocks = <&rpmhcc RPMH_CXO_CLK>; +- clock-names = "xo"; +- +- power-domains = <&rpmhpd RPMHPD_LCX>, +- <&rpmhpd RPMHPD_LMX>; +- power-domain-names = "lcx", "lmx"; +- +- interconnects = <&lpass_lpicx_noc MASTER_LPASS_PROC 0 &mc_virt SLAVE_EBI1 0>; +- +- memory-region = <&adspslpi_mem>, <&q6_adsp_dtb_mem>; +- +- qcom,qmp = <&aoss_qmp>; +- +- qcom,smem-states = <&smp2p_adsp_out 0>; +- qcom,smem-state-names = "stop"; +- +- status = "disabled"; +- +- remoteproc_adsp_glink: glink-edge { +- interrupts-extended = <&ipcc IPCC_CLIENT_LPASS +- IPCC_MPROC_SIGNAL_GLINK_QMP +- IRQ_TYPE_EDGE_RISING>; +- mboxes = <&ipcc IPCC_CLIENT_LPASS +- IPCC_MPROC_SIGNAL_GLINK_QMP>; +- +- label = "lpass"; +- qcom,remote-pid = <2>; +- +- fastrpc { +- compatible = "qcom,fastrpc"; +- qcom,glink-channels = "fastrpcglink-apps-dsp"; +- label = "adsp"; +- #address-cells = <1>; +- #size-cells = <0>; +- +- compute-cb@3 { +- compatible = "qcom,fastrpc-compute-cb"; +- reg = <3>; +- iommus = <&apps_smmu 0x1003 0x80>, +- <&apps_smmu 0x1063 0x0>; +- }; +- +- compute-cb@4 { +- compatible = "qcom,fastrpc-compute-cb"; +- reg = <4>; +- iommus = <&apps_smmu 0x1004 0x80>, +- <&apps_smmu 0x1064 0x0>; +- }; +- +- compute-cb@5 { +- compatible = "qcom,fastrpc-compute-cb"; +- reg = <5>; +- iommus = <&apps_smmu 0x1005 0x80>, +- <&apps_smmu 0x1065 0x0>; +- }; +- +- compute-cb@6 { +- compatible = "qcom,fastrpc-compute-cb"; +- reg = <6>; +- iommus = <&apps_smmu 0x1006 0x80>, +- <&apps_smmu 0x1066 0x0>; +- }; +- +- compute-cb@7 { +- compatible = "qcom,fastrpc-compute-cb"; +- reg = <7>; +- iommus = <&apps_smmu 0x1007 0x80>, +- <&apps_smmu 0x1067 0x0>; +- }; +- }; +- +- gpr { +- compatible = "qcom,gpr"; +- qcom,glink-channels = "adsp_apps"; +- qcom,domain = ; +- qcom,intents = <512 20>; +- #address-cells = <1>; +- #size-cells = <0>; +- +- q6apm: service@1 { +- compatible = "qcom,q6apm"; +- reg = ; +- #sound-dai-cells = <0>; +- qcom,protection-domain = "avs/audio", +- "msm/adsp/audio_pd"; +- +- q6apmdai: dais { +- compatible = "qcom,q6apm-dais"; +- iommus = <&apps_smmu 0x1001 0x80>, +- <&apps_smmu 0x1061 0x0>; +- }; +- +- q6apmbedai: bedais { +- compatible = "qcom,q6apm-lpass-dais"; +- #sound-dai-cells = <1>; +- }; +- }; +- +- q6prm: service@2 { +- compatible = "qcom,q6prm"; +- reg = ; +- qcom,protection-domain = "avs/audio", +- "msm/adsp/audio_pd"; +- +- q6prmcc: clock-controller { +- compatible = "qcom,q6prm-lpass-clocks"; +- #clock-cells = <2>; +- }; +- }; +- }; +- }; +- }; +- + nsp_noc: interconnect@320c0000 { + compatible = "qcom,sm8550-nsp-noc"; + reg = <0 0x320c0000 0 0xe080>; +@@ -4131,6 +4137,7 @@ fastrpc { + compatible = "qcom,fastrpc"; + qcom,glink-channels = "fastrpcglink-apps-dsp"; + label = "cdsp"; ++ qcom,non-secure-domain; + #address-cells = <1>; + #size-cells = <0>; + +@@ -4140,6 +4147,7 @@ compute-cb@1 { + iommus = <&apps_smmu 0x1961 0x0>, + <&apps_smmu 0x0c01 0x20>, + <&apps_smmu 0x19c1 0x10>; ++ dma-coherent; + }; + + compute-cb@2 { +@@ -4148,6 +4156,7 @@ compute-cb@2 { + iommus = <&apps_smmu 0x1962 0x0>, + <&apps_smmu 0x0c02 0x20>, + <&apps_smmu 0x19c2 0x10>; ++ dma-coherent; + }; + + compute-cb@3 { +@@ -4156,6 +4165,7 @@ compute-cb@3 { + iommus = <&apps_smmu 0x1963 0x0>, + <&apps_smmu 0x0c03 0x20>, + <&apps_smmu 0x19c3 0x10>; ++ dma-coherent; + }; + + compute-cb@4 { +@@ -4164,6 +4174,7 @@ compute-cb@4 { + iommus = <&apps_smmu 0x1964 0x0>, + <&apps_smmu 0x0c04 0x20>, + <&apps_smmu 0x19c4 0x10>; ++ dma-coherent; + }; + + compute-cb@5 { +@@ -4172,6 +4183,7 @@ compute-cb@5 { + iommus = <&apps_smmu 0x1965 0x0>, + <&apps_smmu 0x0c05 0x20>, + <&apps_smmu 0x19c5 0x10>; ++ dma-coherent; + }; + + compute-cb@6 { +@@ -4180,6 +4192,7 @@ compute-cb@6 { + iommus = <&apps_smmu 0x1966 0x0>, + <&apps_smmu 0x0c06 0x20>, + <&apps_smmu 0x19c6 0x10>; ++ dma-coherent; + }; + + compute-cb@7 { +@@ -4188,6 +4201,7 @@ compute-cb@7 { + iommus = <&apps_smmu 0x1967 0x0>, + <&apps_smmu 0x0c07 0x20>, + <&apps_smmu 0x19c7 0x10>; ++ dma-coherent; + }; + + compute-cb@8 { +@@ -4196,6 +4210,7 @@ compute-cb@8 { + iommus = <&apps_smmu 0x1968 0x0>, + <&apps_smmu 0x0c08 0x20>, + <&apps_smmu 0x19c8 0x10>; ++ dma-coherent; + }; + + /* note: secure cb9 in downstream */ +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus-lts.dts b/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus-lts.dts +index 4237f2ee8fee33..f57d4acd9807cb 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus-lts.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus-lts.dts +@@ -15,9 +15,11 @@ / { + }; + + &gmac2io { ++ /delete-property/ tx_delay; ++ /delete-property/ rx_delay; ++ + phy-handle = <&yt8531c>; +- tx_delay = <0x19>; +- rx_delay = <0x05>; ++ phy-mode = "rgmii-id"; + + mdio { + /delete-node/ ethernet-phy@1; +diff --git a/arch/arm64/include/asm/mman.h b/arch/arm64/include/asm/mman.h +index ef35c52aabd66d..101771c60d80d2 100644 +--- a/arch/arm64/include/asm/mman.h ++++ b/arch/arm64/include/asm/mman.h +@@ -31,9 +31,12 @@ static inline unsigned long arch_calc_vm_flag_bits(struct file *file, + * backed by tags-capable memory. The vm_flags may be overridden by a + * filesystem supporting MTE (RAM-based). + */ +- if (system_supports_mte() && +- ((flags & MAP_ANONYMOUS) || shmem_file(file))) +- return VM_MTE_ALLOWED; ++ if (system_supports_mte()) { ++ if ((flags & MAP_ANONYMOUS) && !(flags & MAP_HUGETLB)) ++ return VM_MTE_ALLOWED; ++ if (shmem_file(file)) ++ return VM_MTE_ALLOWED; ++ } + + return 0; + } +diff --git a/arch/powerpc/include/asm/book3s/64/hash-4k.h b/arch/powerpc/include/asm/book3s/64/hash-4k.h +index 6472b08fa1b0cd..2a2649e0f91dff 100644 +--- a/arch/powerpc/include/asm/book3s/64/hash-4k.h ++++ b/arch/powerpc/include/asm/book3s/64/hash-4k.h +@@ -89,6 +89,34 @@ static inline int hash__hugepd_ok(hugepd_t hpd) + } + #endif + ++/* ++ * With 4K page size the real_pte machinery is all nops. ++ */ ++static inline real_pte_t __real_pte(pte_t pte, pte_t *ptep, int offset) ++{ ++ return (real_pte_t){pte}; ++} ++ ++#define __rpte_to_pte(r) ((r).pte) ++ ++static inline unsigned long __rpte_to_hidx(real_pte_t rpte, unsigned long index) ++{ ++ return pte_val(__rpte_to_pte(rpte)) >> H_PAGE_F_GIX_SHIFT; ++} ++ ++#define pte_iterate_hashed_subpages(rpte, psize, va, index, shift) \ ++ do { \ ++ index = 0; \ ++ shift = mmu_psize_defs[psize].shift; \ ++ ++#define pte_iterate_hashed_end() } while(0) ++ ++/* ++ * We expect this to be called only for user addresses or kernel virtual ++ * addresses other than the linear mapping. ++ */ ++#define pte_pagesize_index(mm, addr, pte) MMU_PAGE_4K ++ + /* + * 4K PTE format is different from 64K PTE format. Saving the hash_slot is just + * a matter of returning the PTE bits that need to be modified. On 64K PTE, +diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h +index 5c497c862d757e..8a6e6b6daa9065 100644 +--- a/arch/powerpc/include/asm/book3s/64/pgtable.h ++++ b/arch/powerpc/include/asm/book3s/64/pgtable.h +@@ -319,32 +319,6 @@ extern unsigned long pci_io_base; + + #ifndef __ASSEMBLY__ + +-/* +- * This is the default implementation of various PTE accessors, it's +- * used in all cases except Book3S with 64K pages where we have a +- * concept of sub-pages +- */ +-#ifndef __real_pte +- +-#define __real_pte(e, p, o) ((real_pte_t){(e)}) +-#define __rpte_to_pte(r) ((r).pte) +-#define __rpte_to_hidx(r,index) (pte_val(__rpte_to_pte(r)) >> H_PAGE_F_GIX_SHIFT) +- +-#define pte_iterate_hashed_subpages(rpte, psize, va, index, shift) \ +- do { \ +- index = 0; \ +- shift = mmu_psize_defs[psize].shift; \ +- +-#define pte_iterate_hashed_end() } while(0) +- +-/* +- * We expect this to be called only for user addresses or kernel virtual +- * addresses other than the linear mapping. +- */ +-#define pte_pagesize_index(mm, addr, pte) MMU_PAGE_4K +- +-#endif /* __real_pte */ +- + static inline unsigned long pte_update(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, unsigned long clr, + unsigned long set, int huge) +diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c +index b00112d7ad467d..4426a77c8f063b 100644 +--- a/arch/powerpc/lib/code-patching.c ++++ b/arch/powerpc/lib/code-patching.c +@@ -105,7 +105,7 @@ static int text_area_cpu_up(unsigned int cpu) + unsigned long addr; + int err; + +- area = get_vm_area(PAGE_SIZE, VM_ALLOC); ++ area = get_vm_area(PAGE_SIZE, 0); + if (!area) { + WARN_ONCE(1, "Failed to create text area for cpu %d\n", + cpu); +diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig +index 05c82fd5d0f60b..989d432b58345d 100644 +--- a/arch/x86/Kconfig ++++ b/arch/x86/Kconfig +@@ -2514,7 +2514,8 @@ config CPU_IBPB_ENTRY + depends on CPU_SUP_AMD && X86_64 + default y + help +- Compile the kernel with support for the retbleed=ibpb mitigation. ++ Compile the kernel with support for the retbleed=ibpb and ++ spec_rstack_overflow={ibpb,ibpb-vmexit} mitigations. + + config CPU_IBRS_ENTRY + bool "Enable IBRS on kernel entry" +diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c +index df286789c94f18..61ac094e26bd78 100644 +--- a/arch/x86/events/intel/core.c ++++ b/arch/x86/events/intel/core.c +@@ -4643,16 +4643,19 @@ static void intel_pmu_check_num_counters(int *num_counters, + + static void update_pmu_cap(struct x86_hybrid_pmu *pmu) + { +- unsigned int sub_bitmaps = cpuid_eax(ARCH_PERFMON_EXT_LEAF); +- unsigned int eax, ebx, ecx, edx; ++ unsigned int cntr, fixed_cntr, ecx, edx; ++ union cpuid35_eax eax; ++ union cpuid35_ebx ebx; + +- if (sub_bitmaps & ARCH_PERFMON_NUM_COUNTER_LEAF_BIT) { ++ cpuid(ARCH_PERFMON_EXT_LEAF, &eax.full, &ebx.full, &ecx, &edx); ++ ++ if (eax.split.cntr_subleaf) { + cpuid_count(ARCH_PERFMON_EXT_LEAF, ARCH_PERFMON_NUM_COUNTER_LEAF, +- &eax, &ebx, &ecx, &edx); +- pmu->num_counters = fls(eax); +- pmu->num_counters_fixed = fls(ebx); ++ &cntr, &fixed_cntr, &ecx, &edx); ++ pmu->num_counters = fls(cntr); ++ pmu->num_counters_fixed = fls(fixed_cntr); + intel_pmu_check_num_counters(&pmu->num_counters, &pmu->num_counters_fixed, +- &pmu->intel_ctrl, ebx); ++ &pmu->intel_ctrl, fixed_cntr); + } + } + +diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h +index 85a9fd5a3ec331..384e8a7db4827b 100644 +--- a/arch/x86/include/asm/perf_event.h ++++ b/arch/x86/include/asm/perf_event.h +@@ -177,9 +177,33 @@ union cpuid10_edx { + * detection/enumeration details: + */ + #define ARCH_PERFMON_EXT_LEAF 0x00000023 +-#define ARCH_PERFMON_NUM_COUNTER_LEAF_BIT 0x1 + #define ARCH_PERFMON_NUM_COUNTER_LEAF 0x1 + ++union cpuid35_eax { ++ struct { ++ unsigned int leaf0:1; ++ /* Counters Sub-Leaf */ ++ unsigned int cntr_subleaf:1; ++ /* Auto Counter Reload Sub-Leaf */ ++ unsigned int acr_subleaf:1; ++ /* Events Sub-Leaf */ ++ unsigned int events_subleaf:1; ++ unsigned int reserved:28; ++ } split; ++ unsigned int full; ++}; ++ ++union cpuid35_ebx { ++ struct { ++ /* UnitMask2 Supported */ ++ unsigned int umask2:1; ++ /* EQ-bit Supported */ ++ unsigned int eq:1; ++ unsigned int reserved:30; ++ } split; ++ unsigned int full; ++}; ++ + /* + * Intel Architectural LBR CPUID detection/enumeration details: + */ +diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c +index 7b5ba5b8592a25..7df458a6553eb2 100644 +--- a/arch/x86/kernel/cpu/bugs.c ++++ b/arch/x86/kernel/cpu/bugs.c +@@ -1113,6 +1113,8 @@ static void __init retbleed_select_mitigation(void) + + case RETBLEED_MITIGATION_IBPB: + setup_force_cpu_cap(X86_FEATURE_ENTRY_IBPB); ++ setup_force_cpu_cap(X86_FEATURE_IBPB_ON_VMEXIT); ++ mitigate_smt = true; + + /* + * IBPB on entry already obviates the need for +@@ -1122,9 +1124,6 @@ static void __init retbleed_select_mitigation(void) + setup_clear_cpu_cap(X86_FEATURE_UNRET); + setup_clear_cpu_cap(X86_FEATURE_RETHUNK); + +- setup_force_cpu_cap(X86_FEATURE_IBPB_ON_VMEXIT); +- mitigate_smt = true; +- + /* + * There is no need for RSB filling: entry_ibpb() ensures + * all predictions, including the RSB, are invalidated, +@@ -2626,6 +2625,7 @@ static void __init srso_select_mitigation(void) + if (IS_ENABLED(CONFIG_CPU_IBPB_ENTRY)) { + if (has_microcode) { + setup_force_cpu_cap(X86_FEATURE_ENTRY_IBPB); ++ setup_force_cpu_cap(X86_FEATURE_IBPB_ON_VMEXIT); + srso_mitigation = SRSO_MITIGATION_IBPB; + + /* +@@ -2635,6 +2635,13 @@ static void __init srso_select_mitigation(void) + */ + setup_clear_cpu_cap(X86_FEATURE_UNRET); + setup_clear_cpu_cap(X86_FEATURE_RETHUNK); ++ ++ /* ++ * There is no need for RSB filling: entry_ibpb() ensures ++ * all predictions, including the RSB, are invalidated, ++ * regardless of IBPB implementation. ++ */ ++ setup_clear_cpu_cap(X86_FEATURE_RSB_VMEXIT); + } + } else { + pr_err("WARNING: kernel not compiled with CPU_IBPB_ENTRY.\n"); +@@ -2643,8 +2650,8 @@ static void __init srso_select_mitigation(void) + break; + + case SRSO_CMD_IBPB_ON_VMEXIT: +- if (IS_ENABLED(CONFIG_CPU_SRSO)) { +- if (!boot_cpu_has(X86_FEATURE_ENTRY_IBPB) && has_microcode) { ++ if (IS_ENABLED(CONFIG_CPU_IBPB_ENTRY)) { ++ if (has_microcode) { + setup_force_cpu_cap(X86_FEATURE_IBPB_ON_VMEXIT); + srso_mitigation = SRSO_MITIGATION_IBPB_ON_VMEXIT; + +@@ -2656,9 +2663,9 @@ static void __init srso_select_mitigation(void) + setup_clear_cpu_cap(X86_FEATURE_RSB_VMEXIT); + } + } else { +- pr_err("WARNING: kernel not compiled with CPU_SRSO.\n"); ++ pr_err("WARNING: kernel not compiled with CPU_IBPB_ENTRY.\n"); + goto pred_cmd; +- } ++ } + break; + + default: +diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c +index 35fb26cbf22941..892e2540f008ae 100644 +--- a/drivers/bluetooth/btqca.c ++++ b/drivers/bluetooth/btqca.c +@@ -289,6 +289,39 @@ int qca_send_pre_shutdown_cmd(struct hci_dev *hdev) + } + EXPORT_SYMBOL_GPL(qca_send_pre_shutdown_cmd); + ++static bool qca_filename_has_extension(const char *filename) ++{ ++ const char *suffix = strrchr(filename, '.'); ++ ++ /* File extensions require a dot, but not as the first or last character */ ++ if (!suffix || suffix == filename || *(suffix + 1) == '\0') ++ return 0; ++ ++ /* Avoid matching directories with names that look like files with extensions */ ++ return !strchr(suffix, '/'); ++} ++ ++static bool qca_get_alt_nvm_file(char *filename, size_t max_size) ++{ ++ char fwname[64]; ++ const char *suffix; ++ ++ /* nvm file name has an extension, replace with .bin */ ++ if (qca_filename_has_extension(filename)) { ++ suffix = strrchr(filename, '.'); ++ strscpy(fwname, filename, suffix - filename + 1); ++ snprintf(fwname + (suffix - filename), ++ sizeof(fwname) - (suffix - filename), ".bin"); ++ /* If nvm file is already the default one, return false to skip the retry. */ ++ if (strcmp(fwname, filename) == 0) ++ return false; ++ ++ snprintf(filename, max_size, "%s", fwname); ++ return true; ++ } ++ return false; ++} ++ + static int qca_tlv_check_data(struct hci_dev *hdev, + struct qca_fw_config *config, + u8 *fw_data, size_t fw_size, +@@ -586,6 +619,19 @@ static int qca_download_firmware(struct hci_dev *hdev, + config->fwname, ret); + return ret; + } ++ } ++ /* If the board-specific file is missing, try loading the default ++ * one, unless that was attempted already. ++ */ ++ else if (config->type == TLV_TYPE_NVM && ++ qca_get_alt_nvm_file(config->fwname, sizeof(config->fwname))) { ++ bt_dev_info(hdev, "QCA Downloading %s", config->fwname); ++ ret = request_firmware(&fw, config->fwname, &hdev->dev); ++ if (ret) { ++ bt_dev_err(hdev, "QCA Failed to request file: %s (%d)", ++ config->fwname, ret); ++ return ret; ++ } + } else { + bt_dev_err(hdev, "QCA Failed to request file: %s (%d)", + config->fwname, ret); +@@ -722,21 +768,38 @@ static int qca_check_bdaddr(struct hci_dev *hdev, const struct qca_fw_config *co + return 0; + } + +-static void qca_generate_hsp_nvm_name(char *fwname, size_t max_size, ++static void qca_get_nvm_name_by_board(char *fwname, size_t max_size, ++ const char *stem, enum qca_btsoc_type soc_type, + struct qca_btsoc_version ver, u8 rom_ver, u16 bid) + { + const char *variant; ++ const char *prefix; + +- /* hsp gf chip */ +- if ((le32_to_cpu(ver.soc_id) & QCA_HSP_GF_SOC_MASK) == QCA_HSP_GF_SOC_ID) +- variant = "g"; +- else +- variant = ""; ++ /* Set the default value to variant and prefix */ ++ variant = ""; ++ prefix = "b"; + +- if (bid == 0x0) +- snprintf(fwname, max_size, "qca/hpnv%02x%s.bin", rom_ver, variant); +- else +- snprintf(fwname, max_size, "qca/hpnv%02x%s.%x", rom_ver, variant, bid); ++ if (soc_type == QCA_QCA2066) ++ prefix = ""; ++ ++ if (soc_type == QCA_WCN6855 || soc_type == QCA_QCA2066) { ++ /* If the chip is manufactured by GlobalFoundries */ ++ if ((le32_to_cpu(ver.soc_id) & QCA_HSP_GF_SOC_MASK) == QCA_HSP_GF_SOC_ID) ++ variant = "g"; ++ } ++ ++ if (rom_ver != 0) { ++ if (bid == 0x0 || bid == 0xffff) ++ snprintf(fwname, max_size, "qca/%s%02x%s.bin", stem, rom_ver, variant); ++ else ++ snprintf(fwname, max_size, "qca/%s%02x%s.%s%02x", stem, rom_ver, ++ variant, prefix, bid); ++ } else { ++ if (bid == 0x0 || bid == 0xffff) ++ snprintf(fwname, max_size, "qca/%s%s.bin", stem, variant); ++ else ++ snprintf(fwname, max_size, "qca/%s%s.%s%02x", stem, variant, prefix, bid); ++ } + } + + int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, +@@ -819,14 +882,20 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, + /* Give the controller some time to get ready to receive the NVM */ + msleep(10); + +- if (soc_type == QCA_QCA2066) ++ if (soc_type == QCA_QCA2066 || soc_type == QCA_WCN7850) + qca_read_fw_board_id(hdev, &boardid); + + /* Download NVM configuration */ + config.type = TLV_TYPE_NVM; + if (firmware_name) { +- snprintf(config.fwname, sizeof(config.fwname), +- "qca/%s", firmware_name); ++ /* The firmware name has an extension, use it directly */ ++ if (qca_filename_has_extension(firmware_name)) { ++ snprintf(config.fwname, sizeof(config.fwname), "qca/%s", firmware_name); ++ } else { ++ qca_read_fw_board_id(hdev, &boardid); ++ qca_get_nvm_name_by_board(config.fwname, sizeof(config.fwname), ++ firmware_name, soc_type, ver, 0, boardid); ++ } + } else { + switch (soc_type) { + case QCA_WCN3990: +@@ -845,8 +914,9 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, + "qca/apnv%02x.bin", rom_ver); + break; + case QCA_QCA2066: +- qca_generate_hsp_nvm_name(config.fwname, +- sizeof(config.fwname), ver, rom_ver, boardid); ++ qca_get_nvm_name_by_board(config.fwname, ++ sizeof(config.fwname), "hpnv", soc_type, ver, ++ rom_ver, boardid); + break; + case QCA_QCA6390: + snprintf(config.fwname, sizeof(config.fwname), +@@ -857,14 +927,14 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, + "qca/msnv%02x.bin", rom_ver); + break; + case QCA_WCN6855: +- snprintf(config.fwname, sizeof(config.fwname), +- "qca/hpnv%02x.bin", rom_ver); ++ qca_read_fw_board_id(hdev, &boardid); ++ qca_get_nvm_name_by_board(config.fwname, sizeof(config.fwname), ++ "hpnv", soc_type, ver, rom_ver, boardid); + break; + case QCA_WCN7850: +- snprintf(config.fwname, sizeof(config.fwname), +- "qca/hmtnv%02x.bin", rom_ver); ++ qca_get_nvm_name_by_board(config.fwname, sizeof(config.fwname), ++ "hmtnv", soc_type, ver, rom_ver, boardid); + break; +- + default: + snprintf(config.fwname, sizeof(config.fwname), + "qca/nvm_%08x.bin", soc_ver); +diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig +index f429b9b37b76c7..7e773c47a4fcd2 100644 +--- a/drivers/cpufreq/Kconfig ++++ b/drivers/cpufreq/Kconfig +@@ -218,7 +218,7 @@ config CPUFREQ_DT + If in doubt, say N. + + config CPUFREQ_DT_PLATDEV +- tristate "Generic DT based cpufreq platdev driver" ++ bool "Generic DT based cpufreq platdev driver" + depends on OF + help + This adds a generic DT based cpufreq platdev driver for frequency +diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c +index fb2875ce1fdd57..09becf14653b58 100644 +--- a/drivers/cpufreq/cpufreq-dt-platdev.c ++++ b/drivers/cpufreq/cpufreq-dt-platdev.c +@@ -225,4 +225,3 @@ static int __init cpufreq_dt_platdev_init(void) + sizeof(struct cpufreq_dt_platform_data))); + } + core_initcall(cpufreq_dt_platdev_init); +-MODULE_LICENSE("GPL"); +diff --git a/drivers/edac/qcom_edac.c b/drivers/edac/qcom_edac.c +index b2db545c681031..345cae059c029a 100644 +--- a/drivers/edac/qcom_edac.c ++++ b/drivers/edac/qcom_edac.c +@@ -95,7 +95,7 @@ static int qcom_llcc_core_setup(struct llcc_drv_data *drv, struct regmap *llcc_b + * Configure interrupt enable registers such that Tag, Data RAM related + * interrupts are propagated to interrupt controller for servicing + */ +- ret = regmap_update_bits(llcc_bcast_regmap, drv->edac_reg_offset->cmn_interrupt_2_enable, ++ ret = regmap_update_bits(llcc_bcast_regmap, drv->edac_reg_offset->cmn_interrupt_0_enable, + TRP0_INTERRUPT_ENABLE, + TRP0_INTERRUPT_ENABLE); + if (ret) +@@ -113,7 +113,7 @@ static int qcom_llcc_core_setup(struct llcc_drv_data *drv, struct regmap *llcc_b + if (ret) + return ret; + +- ret = regmap_update_bits(llcc_bcast_regmap, drv->edac_reg_offset->cmn_interrupt_2_enable, ++ ret = regmap_update_bits(llcc_bcast_regmap, drv->edac_reg_offset->cmn_interrupt_0_enable, + DRP0_INTERRUPT_ENABLE, + DRP0_INTERRUPT_ENABLE); + if (ret) +diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c +index 7af59985f1c1f9..4c5c2b73d42c21 100644 +--- a/drivers/firmware/qcom_scm.c ++++ b/drivers/firmware/qcom_scm.c +@@ -1339,7 +1339,8 @@ static int qcom_scm_find_dload_address(struct device *dev, u64 *addr) + */ + bool qcom_scm_is_available(void) + { +- return !!READ_ONCE(__scm); ++ /* Paired with smp_store_release() in qcom_scm_probe */ ++ return !!smp_load_acquire(&__scm); + } + EXPORT_SYMBOL_GPL(qcom_scm_is_available); + +@@ -1457,7 +1458,7 @@ static int qcom_scm_probe(struct platform_device *pdev) + if (ret) + return ret; + +- /* Let all above stores be available after this */ ++ /* Paired with smp_load_acquire() in qcom_scm_is_available(). */ + smp_store_release(&__scm, scm); + + irq = platform_get_irq_optional(pdev, 0); +diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c +index 1a59fca40252cd..347527885ffd75 100644 +--- a/drivers/gpu/drm/i915/display/intel_display.c ++++ b/drivers/gpu/drm/i915/display/intel_display.c +@@ -6141,12 +6141,30 @@ static int intel_async_flip_check_hw(struct intel_atomic_state *state, struct in + static int intel_bigjoiner_add_affected_crtcs(struct intel_atomic_state *state) + { + struct drm_i915_private *i915 = to_i915(state->base.dev); ++ const struct intel_plane_state *plane_state; + struct intel_crtc_state *crtc_state; ++ struct intel_plane *plane; + struct intel_crtc *crtc; + u8 affected_pipes = 0; + u8 modeset_pipes = 0; + int i; + ++ /* ++ * Any plane which is in use by the joiner needs its crtc. ++ * Pull those in first as this will not have happened yet ++ * if the plane remains disabled according to uapi. ++ */ ++ for_each_new_intel_plane_in_state(state, plane, plane_state, i) { ++ crtc = to_intel_crtc(plane_state->hw.crtc); ++ if (!crtc) ++ continue; ++ ++ crtc_state = intel_atomic_get_crtc_state(&state->base, crtc); ++ if (IS_ERR(crtc_state)) ++ return PTR_ERR(crtc_state); ++ } ++ ++ /* Now pull in all joined crtcs */ + for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) { + affected_pipes |= crtc_state->bigjoiner_pipes; + if (intel_crtc_needs_modeset(crtc_state)) +diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c +index eb5559e1a20024..f79809a48672ed 100644 +--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c ++++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c +@@ -1364,7 +1364,7 @@ intel_dp_128b132b_link_train(struct intel_dp *intel_dp, + + if (wait_for(intel_dp_128b132b_intra_hop(intel_dp, crtc_state) == 0, 500)) { + lt_err(intel_dp, DP_PHY_DPRX, "128b/132b intra-hop not clear\n"); +- return false; ++ goto out; + } + + if (intel_dp_128b132b_lane_eq(intel_dp, crtc_state) && +@@ -1376,6 +1376,19 @@ intel_dp_128b132b_link_train(struct intel_dp *intel_dp, + passed ? "passed" : "failed", + crtc_state->port_clock, crtc_state->lane_count); + ++out: ++ /* ++ * Ensure that the training pattern does get set to TPS2 even in case ++ * of a failure, as is the case at the end of a passing link training ++ * and what is expected by the transcoder. Leaving TPS1 set (and ++ * disabling the link train mode in DP_TP_CTL later from TPS1 directly) ++ * would result in a stuck transcoder HW state and flip-done timeouts ++ * later in the modeset sequence. ++ */ ++ if (!passed) ++ intel_dp_program_link_training_pattern(intel_dp, crtc_state, ++ DP_PHY_DPRX, DP_TRAINING_PATTERN_2); ++ + return passed; + } + +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +index 10c68de1bf22ca..35cf9080168b12 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +@@ -2075,6 +2075,9 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc) + } + } + ++ if (phys_enc->hw_pp && phys_enc->hw_pp->ops.setup_dither) ++ phys_enc->hw_pp->ops.setup_dither(phys_enc->hw_pp, NULL); ++ + /* reset the merge 3D HW block */ + if (phys_enc->hw_pp && phys_enc->hw_pp->merge_3d) { + phys_enc->hw_pp->merge_3d->ops.setup_3d_mode(phys_enc->hw_pp->merge_3d, +diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h +index 48e1a8c6942c9f..223bf904235a81 100644 +--- a/drivers/gpu/drm/msm/msm_drv.h ++++ b/drivers/gpu/drm/msm/msm_drv.h +@@ -533,15 +533,12 @@ static inline int align_pitch(int width, int bpp) + static inline unsigned long timeout_to_jiffies(const ktime_t *timeout) + { + ktime_t now = ktime_get(); +- s64 remaining_jiffies; + +- if (ktime_compare(*timeout, now) < 0) { +- remaining_jiffies = 0; +- } else { +- ktime_t rem = ktime_sub(*timeout, now); +- remaining_jiffies = ktime_divns(rem, NSEC_PER_SEC / HZ); +- } ++ if (ktime_compare(*timeout, now) <= 0) ++ return 0; + ++ ktime_t rem = ktime_sub(*timeout, now); ++ s64 remaining_jiffies = ktime_divns(rem, NSEC_PER_SEC / HZ); + return clamp(remaining_jiffies, 1LL, (s64)INT_MAX); + } + +diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c +index db1e748daa753f..1113e6b2ec8ec9 100644 +--- a/drivers/gpu/drm/msm/msm_gem.c ++++ b/drivers/gpu/drm/msm/msm_gem.c +@@ -226,9 +226,9 @@ static struct page **msm_gem_pin_pages_locked(struct drm_gem_object *obj, + + msm_gem_assert_locked(obj); + +- if (GEM_WARN_ON(msm_obj->madv > madv)) { +- DRM_DEV_ERROR(obj->dev->dev, "Invalid madv state: %u vs %u\n", +- msm_obj->madv, madv); ++ if (msm_obj->madv > madv) { ++ DRM_DEV_DEBUG_DRIVER(obj->dev->dev, "Invalid madv state: %u vs %u\n", ++ msm_obj->madv, madv); + return ERR_PTR(-EBUSY); + } + +diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c +index 99744de6c05a1b..018b39546fc1dd 100644 +--- a/drivers/gpu/drm/msm/msm_gem_submit.c ++++ b/drivers/gpu/drm/msm/msm_gem_submit.c +@@ -17,6 +17,12 @@ + #include "msm_gem.h" + #include "msm_gpu_trace.h" + ++/* For userspace errors, use DRM_UT_DRIVER.. so that userspace can enable ++ * error msgs for debugging, but we don't spam dmesg by default ++ */ ++#define SUBMIT_ERROR(submit, fmt, ...) \ ++ DRM_DEV_DEBUG_DRIVER((submit)->dev->dev, fmt, ##__VA_ARGS__) ++ + /* + * Cmdstream submission: + */ +@@ -136,7 +142,7 @@ static int submit_lookup_objects(struct msm_gem_submit *submit, + + if ((submit_bo.flags & ~MSM_SUBMIT_BO_FLAGS) || + !(submit_bo.flags & MANDATORY_FLAGS)) { +- DRM_ERROR("invalid flags: %x\n", submit_bo.flags); ++ SUBMIT_ERROR(submit, "invalid flags: %x\n", submit_bo.flags); + ret = -EINVAL; + i = 0; + goto out; +@@ -158,7 +164,7 @@ static int submit_lookup_objects(struct msm_gem_submit *submit, + */ + obj = idr_find(&file->object_idr, submit->bos[i].handle); + if (!obj) { +- DRM_ERROR("invalid handle %u at index %u\n", submit->bos[i].handle, i); ++ SUBMIT_ERROR(submit, "invalid handle %u at index %u\n", submit->bos[i].handle, i); + ret = -EINVAL; + goto out_unlock; + } +@@ -202,13 +208,13 @@ static int submit_lookup_cmds(struct msm_gem_submit *submit, + case MSM_SUBMIT_CMD_CTX_RESTORE_BUF: + break; + default: +- DRM_ERROR("invalid type: %08x\n", submit_cmd.type); ++ SUBMIT_ERROR(submit, "invalid type: %08x\n", submit_cmd.type); + return -EINVAL; + } + + if (submit_cmd.size % 4) { +- DRM_ERROR("non-aligned cmdstream buffer size: %u\n", +- submit_cmd.size); ++ SUBMIT_ERROR(submit, "non-aligned cmdstream buffer size: %u\n", ++ submit_cmd.size); + ret = -EINVAL; + goto out; + } +@@ -306,8 +312,8 @@ static int submit_lock_objects(struct msm_gem_submit *submit) + + fail: + if (ret == -EALREADY) { +- DRM_ERROR("handle %u at index %u already on submit list\n", +- submit->bos[i].handle, i); ++ SUBMIT_ERROR(submit, "handle %u at index %u already on submit list\n", ++ submit->bos[i].handle, i); + ret = -EINVAL; + } + +@@ -448,8 +454,8 @@ static int submit_bo(struct msm_gem_submit *submit, uint32_t idx, + struct drm_gem_object **obj, uint64_t *iova, bool *valid) + { + if (idx >= submit->nr_bos) { +- DRM_ERROR("invalid buffer index: %u (out of %u)\n", +- idx, submit->nr_bos); ++ SUBMIT_ERROR(submit, "invalid buffer index: %u (out of %u)\n", ++ idx, submit->nr_bos); + return -EINVAL; + } + +@@ -475,7 +481,7 @@ static int submit_reloc(struct msm_gem_submit *submit, struct drm_gem_object *ob + return 0; + + if (offset % 4) { +- DRM_ERROR("non-aligned cmdstream buffer: %u\n", offset); ++ SUBMIT_ERROR(submit, "non-aligned cmdstream buffer: %u\n", offset); + return -EINVAL; + } + +@@ -497,8 +503,8 @@ static int submit_reloc(struct msm_gem_submit *submit, struct drm_gem_object *ob + bool valid; + + if (submit_reloc.submit_offset % 4) { +- DRM_ERROR("non-aligned reloc offset: %u\n", +- submit_reloc.submit_offset); ++ SUBMIT_ERROR(submit, "non-aligned reloc offset: %u\n", ++ submit_reloc.submit_offset); + ret = -EINVAL; + goto out; + } +@@ -508,7 +514,7 @@ static int submit_reloc(struct msm_gem_submit *submit, struct drm_gem_object *ob + + if ((off >= (obj->size / 4)) || + (off < last_offset)) { +- DRM_ERROR("invalid offset %u at reloc %u\n", off, i); ++ SUBMIT_ERROR(submit, "invalid offset %u at reloc %u\n", off, i); + ret = -EINVAL; + goto out; + } +@@ -879,9 +885,8 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, + goto out; + + if (!submit->cmd[i].size || +- ((submit->cmd[i].size + submit->cmd[i].offset) > +- obj->size / 4)) { +- DRM_ERROR("invalid cmdstream size: %u\n", submit->cmd[i].size * 4); ++ (size_add(submit->cmd[i].size, submit->cmd[i].offset) > obj->size / 4)) { ++ SUBMIT_ERROR(submit, "invalid cmdstream size: %u\n", submit->cmd[i].size * 4); + ret = -EINVAL; + goto out; + } +@@ -893,7 +898,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, + + if (!gpu->allow_relocs) { + if (submit->cmd[i].nr_relocs) { +- DRM_ERROR("relocs not allowed\n"); ++ SUBMIT_ERROR(submit, "relocs not allowed\n"); + ret = -EINVAL; + goto out; + } +diff --git a/drivers/gpu/drm/nouveau/nouveau_svm.c b/drivers/gpu/drm/nouveau/nouveau_svm.c +index ec9f307370fa8a..6c71f6738ca510 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_svm.c ++++ b/drivers/gpu/drm/nouveau/nouveau_svm.c +@@ -593,6 +593,7 @@ static int nouveau_atomic_range_fault(struct nouveau_svmm *svmm, + unsigned long timeout = + jiffies + msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT); + struct mm_struct *mm = svmm->notifier.mm; ++ struct folio *folio; + struct page *page; + unsigned long start = args->p.addr; + unsigned long notifier_seq; +@@ -619,12 +620,16 @@ static int nouveau_atomic_range_fault(struct nouveau_svmm *svmm, + ret = -EINVAL; + goto out; + } ++ folio = page_folio(page); + + mutex_lock(&svmm->mutex); + if (!mmu_interval_read_retry(¬ifier->notifier, + notifier_seq)) + break; + mutex_unlock(&svmm->mutex); ++ ++ folio_unlock(folio); ++ folio_put(folio); + } + + /* Map the page on the GPU. */ +@@ -640,8 +645,8 @@ static int nouveau_atomic_range_fault(struct nouveau_svmm *svmm, + ret = nvif_object_ioctl(&svmm->vmm->vmm.object, args, size, NULL); + mutex_unlock(&svmm->mutex); + +- unlock_page(page); +- put_page(page); ++ folio_unlock(folio); ++ folio_put(folio); + + out: + mmu_interval_notifier_remove(¬ifier->notifier); +diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp10b.c +index a6f410ba60bc94..d393bc540f8628 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp10b.c ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp10b.c +@@ -75,7 +75,7 @@ gp10b_pmu_acr = { + .bootstrap_multiple_falcons = gp10b_pmu_acr_bootstrap_multiple_falcons, + }; + +-#if IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC) ++#if IS_ENABLED(CONFIG_ARCH_TEGRA_186_SOC) + MODULE_FIRMWARE("nvidia/gp10b/pmu/desc.bin"); + MODULE_FIRMWARE("nvidia/gp10b/pmu/image.bin"); + MODULE_FIRMWARE("nvidia/gp10b/pmu/sig.bin"); +diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/tidss_dispc.c +index ee3531bbccd7df..355c64bafb82b8 100644 +--- a/drivers/gpu/drm/tidss/tidss_dispc.c ++++ b/drivers/gpu/drm/tidss/tidss_dispc.c +@@ -2704,14 +2704,32 @@ static void dispc_init_errata(struct dispc_device *dispc) + } + } + ++/* ++ * K2G display controller does not support soft reset, so we do a basic manual ++ * reset here: make sure the IRQs are masked and VPs are disabled. ++ */ ++static void dispc_softreset_k2g(struct dispc_device *dispc) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&dispc->tidss->wait_lock, flags); ++ dispc_set_irqenable(dispc, 0); ++ dispc_read_and_clear_irqstatus(dispc); ++ spin_unlock_irqrestore(&dispc->tidss->wait_lock, flags); ++ ++ for (unsigned int vp_idx = 0; vp_idx < dispc->feat->num_vps; ++vp_idx) ++ VP_REG_FLD_MOD(dispc, vp_idx, DISPC_VP_CONTROL, 0, 0, 0); ++} ++ + static int dispc_softreset(struct dispc_device *dispc) + { + u32 val; + int ret = 0; + +- /* K2G display controller does not support soft reset */ +- if (dispc->feat->subrev == DISPC_K2G) ++ if (dispc->feat->subrev == DISPC_K2G) { ++ dispc_softreset_k2g(dispc); + return 0; ++ } + + /* Soft reset */ + REG_FLD_MOD(dispc, DSS_SYSCONFIG, 1, 1, 1); +diff --git a/drivers/gpu/drm/tidss/tidss_irq.c b/drivers/gpu/drm/tidss/tidss_irq.c +index 0c681c7600bcb2..f13c7e434f8ede 100644 +--- a/drivers/gpu/drm/tidss/tidss_irq.c ++++ b/drivers/gpu/drm/tidss/tidss_irq.c +@@ -60,7 +60,9 @@ static irqreturn_t tidss_irq_handler(int irq, void *arg) + unsigned int id; + dispc_irq_t irqstatus; + ++ spin_lock(&tidss->wait_lock); + irqstatus = dispc_read_and_clear_irqstatus(tidss->dispc); ++ spin_unlock(&tidss->wait_lock); + + for (id = 0; id < tidss->num_crtcs; id++) { + struct drm_crtc *crtc = tidss->crtcs[id]; +diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c +index cff3393f0dd000..26677432ac8361 100644 +--- a/drivers/input/mouse/synaptics.c ++++ b/drivers/input/mouse/synaptics.c +@@ -667,23 +667,50 @@ static void synaptics_pt_stop(struct serio *serio) + serio_continue_rx(parent->ps2dev.serio); + } + ++static int synaptics_pt_open(struct serio *serio) ++{ ++ struct psmouse *parent = psmouse_from_serio(serio->parent); ++ struct synaptics_data *priv = parent->private; ++ ++ guard(serio_pause_rx)(parent->ps2dev.serio); ++ priv->pt_port_open = true; ++ ++ return 0; ++} ++ ++static void synaptics_pt_close(struct serio *serio) ++{ ++ struct psmouse *parent = psmouse_from_serio(serio->parent); ++ struct synaptics_data *priv = parent->private; ++ ++ guard(serio_pause_rx)(parent->ps2dev.serio); ++ priv->pt_port_open = false; ++} ++ + static int synaptics_is_pt_packet(u8 *buf) + { + return (buf[0] & 0xFC) == 0x84 && (buf[3] & 0xCC) == 0xC4; + } + +-static void synaptics_pass_pt_packet(struct serio *ptport, u8 *packet) ++static void synaptics_pass_pt_packet(struct synaptics_data *priv, u8 *packet) + { +- struct psmouse *child = psmouse_from_serio(ptport); ++ struct serio *ptport; + +- if (child && child->state == PSMOUSE_ACTIVATED) { +- serio_interrupt(ptport, packet[1], 0); +- serio_interrupt(ptport, packet[4], 0); +- serio_interrupt(ptport, packet[5], 0); +- if (child->pktsize == 4) +- serio_interrupt(ptport, packet[2], 0); +- } else { +- serio_interrupt(ptport, packet[1], 0); ++ ptport = priv->pt_port; ++ if (!ptport) ++ return; ++ ++ serio_interrupt(ptport, packet[1], 0); ++ ++ if (priv->pt_port_open) { ++ struct psmouse *child = psmouse_from_serio(ptport); ++ ++ if (child->state == PSMOUSE_ACTIVATED) { ++ serio_interrupt(ptport, packet[4], 0); ++ serio_interrupt(ptport, packet[5], 0); ++ if (child->pktsize == 4) ++ serio_interrupt(ptport, packet[2], 0); ++ } + } + } + +@@ -722,6 +749,8 @@ static void synaptics_pt_create(struct psmouse *psmouse) + serio->write = synaptics_pt_write; + serio->start = synaptics_pt_start; + serio->stop = synaptics_pt_stop; ++ serio->open = synaptics_pt_open; ++ serio->close = synaptics_pt_close; + serio->parent = psmouse->ps2dev.serio; + + psmouse->pt_activate = synaptics_pt_activate; +@@ -1218,11 +1247,10 @@ static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse) + + if (SYN_CAP_PASS_THROUGH(priv->info.capabilities) && + synaptics_is_pt_packet(psmouse->packet)) { +- if (priv->pt_port) +- synaptics_pass_pt_packet(priv->pt_port, +- psmouse->packet); +- } else ++ synaptics_pass_pt_packet(priv, psmouse->packet); ++ } else { + synaptics_process_packet(psmouse); ++ } + + return PSMOUSE_FULL_PACKET; + } +diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h +index 08533d1b1b16fc..4b34f13b9f7616 100644 +--- a/drivers/input/mouse/synaptics.h ++++ b/drivers/input/mouse/synaptics.h +@@ -188,6 +188,7 @@ struct synaptics_data { + bool disable_gesture; /* disable gestures */ + + struct serio *pt_port; /* Pass-through serio port */ ++ bool pt_port_open; + + /* + * Last received Advanced Gesture Mode (AGM) packet. An AGM packet +diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c +index 2085b1705f144f..deb40a8ba39995 100644 +--- a/drivers/md/md-bitmap.c ++++ b/drivers/md/md-bitmap.c +@@ -2112,33 +2112,29 @@ int md_bitmap_copy_from_slot(struct mddev *mddev, int slot, + } + EXPORT_SYMBOL_GPL(md_bitmap_copy_from_slot); + +- +-void md_bitmap_status(struct seq_file *seq, struct bitmap *bitmap) ++int md_bitmap_get_stats(struct bitmap *bitmap, struct md_bitmap_stats *stats) + { +- unsigned long chunk_kb; + struct bitmap_counts *counts; ++ bitmap_super_t *sb; + + if (!bitmap) +- return; ++ return -ENOENT; ++ if (bitmap->mddev->bitmap_info.external) ++ return -ENOENT; ++ if (!bitmap->storage.sb_page) /* no superblock */ ++ return -EINVAL; ++ sb = kmap_local_page(bitmap->storage.sb_page); ++ stats->sync_size = le64_to_cpu(sb->sync_size); ++ kunmap_local(sb); + + counts = &bitmap->counts; ++ stats->missing_pages = counts->missing_pages; ++ stats->pages = counts->pages; ++ stats->file = bitmap->storage.file; + +- chunk_kb = bitmap->mddev->bitmap_info.chunksize >> 10; +- seq_printf(seq, "bitmap: %lu/%lu pages [%luKB], " +- "%lu%s chunk", +- counts->pages - counts->missing_pages, +- counts->pages, +- (counts->pages - counts->missing_pages) +- << (PAGE_SHIFT - 10), +- chunk_kb ? chunk_kb : bitmap->mddev->bitmap_info.chunksize, +- chunk_kb ? "KB" : "B"); +- if (bitmap->storage.file) { +- seq_printf(seq, ", file: "); +- seq_file_path(seq, bitmap->storage.file, " \t\n"); +- } +- +- seq_printf(seq, "\n"); ++ return 0; + } ++EXPORT_SYMBOL_GPL(md_bitmap_get_stats); + + int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks, + int chunksize, int init) +diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h +index 8b89e260a93b71..840efd1b8a01cd 100644 +--- a/drivers/md/md-bitmap.h ++++ b/drivers/md/md-bitmap.h +@@ -234,6 +234,13 @@ struct bitmap { + int cluster_slot; /* Slot offset for clustered env */ + }; + ++struct md_bitmap_stats { ++ unsigned long missing_pages; ++ unsigned long sync_size; ++ unsigned long pages; ++ struct file *file; ++}; ++ + /* the bitmap API */ + + /* these are used only by md/bitmap */ +@@ -244,7 +251,7 @@ void md_bitmap_destroy(struct mddev *mddev); + + void md_bitmap_print_sb(struct bitmap *bitmap); + void md_bitmap_update_sb(struct bitmap *bitmap); +-void md_bitmap_status(struct seq_file *seq, struct bitmap *bitmap); ++int md_bitmap_get_stats(struct bitmap *bitmap, struct md_bitmap_stats *stats); + + int md_bitmap_setallbits(struct bitmap *bitmap); + void md_bitmap_write_all(struct bitmap *bitmap); +diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c +index 1e26eb22334950..6a89f6b5d64f98 100644 +--- a/drivers/md/md-cluster.c ++++ b/drivers/md/md-cluster.c +@@ -1190,18 +1190,21 @@ static int resize_bitmaps(struct mddev *mddev, sector_t newsize, sector_t oldsiz + */ + static int cluster_check_sync_size(struct mddev *mddev) + { +- int i, rv; +- bitmap_super_t *sb; +- unsigned long my_sync_size, sync_size = 0; +- int node_num = mddev->bitmap_info.nodes; + int current_slot = md_cluster_ops->slot_number(mddev); ++ int node_num = mddev->bitmap_info.nodes; + struct bitmap *bitmap = mddev->bitmap; +- char str[64]; + struct dlm_lock_resource *bm_lockres; ++ struct md_bitmap_stats stats; ++ unsigned long sync_size = 0; ++ unsigned long my_sync_size; ++ char str[64]; ++ int i, rv; + +- sb = kmap_atomic(bitmap->storage.sb_page); +- my_sync_size = sb->sync_size; +- kunmap_atomic(sb); ++ rv = md_bitmap_get_stats(bitmap, &stats); ++ if (rv) ++ return rv; ++ ++ my_sync_size = stats.sync_size; + + for (i = 0; i < node_num; i++) { + if (i == current_slot) +@@ -1230,15 +1233,18 @@ static int cluster_check_sync_size(struct mddev *mddev) + md_bitmap_update_sb(bitmap); + lockres_free(bm_lockres); + +- sb = kmap_atomic(bitmap->storage.sb_page); +- if (sync_size == 0) +- sync_size = sb->sync_size; +- else if (sync_size != sb->sync_size) { +- kunmap_atomic(sb); ++ rv = md_bitmap_get_stats(bitmap, &stats); ++ if (rv) { ++ md_bitmap_free(bitmap); ++ return rv; ++ } ++ ++ if (sync_size == 0) { ++ sync_size = stats.sync_size; ++ } else if (sync_size != stats.sync_size) { + md_bitmap_free(bitmap); + return -1; + } +- kunmap_atomic(sb); + md_bitmap_free(bitmap); + } + +diff --git a/drivers/md/md.c b/drivers/md/md.c +index 9bc19a5a4119bd..a8ac4afc51d91d 100644 +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -633,28 +633,33 @@ static inline struct mddev *mddev_get(struct mddev *mddev) + + static void mddev_delayed_delete(struct work_struct *ws); + ++static void __mddev_put(struct mddev *mddev) ++{ ++ if (mddev->raid_disks || !list_empty(&mddev->disks) || ++ mddev->ctime || mddev->hold_active) ++ return; ++ ++ /* Array is not configured at all, and not held active, so destroy it */ ++ set_bit(MD_DELETED, &mddev->flags); ++ ++ /* ++ * Call queue_work inside the spinlock so that flush_workqueue() after ++ * mddev_find will succeed in waiting for the work to be done. ++ */ ++ queue_work(md_misc_wq, &mddev->del_work); ++} ++ + void mddev_put(struct mddev *mddev) + { + if (!atomic_dec_and_lock(&mddev->active, &all_mddevs_lock)) + return; +- if (!mddev->raid_disks && list_empty(&mddev->disks) && +- mddev->ctime == 0 && !mddev->hold_active) { +- /* Array is not configured at all, and not held active, +- * so destroy it */ +- set_bit(MD_DELETED, &mddev->flags); + +- /* +- * Call queue_work inside the spinlock so that +- * flush_workqueue() after mddev_find will succeed in waiting +- * for the work to be done. +- */ +- INIT_WORK(&mddev->del_work, mddev_delayed_delete); +- queue_work(md_misc_wq, &mddev->del_work); +- } ++ __mddev_put(mddev); + spin_unlock(&all_mddevs_lock); + } + + static void md_safemode_timeout(struct timer_list *t); ++static void md_start_sync(struct work_struct *ws); + + void mddev_init(struct mddev *mddev) + { +@@ -679,6 +684,9 @@ void mddev_init(struct mddev *mddev) + mddev->resync_min = 0; + mddev->resync_max = MaxSector; + mddev->level = LEVEL_NONE; ++ ++ INIT_WORK(&mddev->sync_work, md_start_sync); ++ INIT_WORK(&mddev->del_work, mddev_delayed_delete); + } + EXPORT_SYMBOL_GPL(mddev_init); + +@@ -4828,7 +4836,7 @@ static void stop_sync_thread(struct mddev *mddev) + return; + } + +- if (work_pending(&mddev->del_work)) ++ if (work_pending(&mddev->sync_work)) + flush_workqueue(md_misc_wq); + + set_bit(MD_RECOVERY_INTR, &mddev->recovery); +@@ -6285,7 +6293,7 @@ static void md_clean(struct mddev *mddev) + static void __md_stop_writes(struct mddev *mddev) + { + set_bit(MD_RECOVERY_FROZEN, &mddev->recovery); +- if (work_pending(&mddev->del_work)) ++ if (work_pending(&mddev->sync_work)) + flush_workqueue(md_misc_wq); + if (mddev->sync_thread) { + set_bit(MD_RECOVERY_INTR, &mddev->recovery); +@@ -8113,6 +8121,19 @@ static void status_unused(struct seq_file *seq) + seq_printf(seq, "\n"); + } + ++static void status_personalities(struct seq_file *seq) ++{ ++ struct md_personality *pers; ++ ++ seq_puts(seq, "Personalities : "); ++ spin_lock(&pers_lock); ++ list_for_each_entry(pers, &pers_list, list) ++ seq_printf(seq, "[%s] ", pers->name); ++ ++ spin_unlock(&pers_lock); ++ seq_puts(seq, "\n"); ++} ++ + static int status_resync(struct seq_file *seq, struct mddev *mddev) + { + sector_t max_sectors, resync, res; +@@ -8252,104 +8273,73 @@ static int status_resync(struct seq_file *seq, struct mddev *mddev) + } + + static void *md_seq_start(struct seq_file *seq, loff_t *pos) ++ __acquires(&all_mddevs_lock) + { +- struct list_head *tmp; +- loff_t l = *pos; +- struct mddev *mddev; +- +- if (l == 0x10000) { +- ++*pos; +- return (void *)2; +- } +- if (l > 0x10000) +- return NULL; +- if (!l--) +- /* header */ +- return (void*)1; +- ++ seq->poll_event = atomic_read(&md_event_count); + spin_lock(&all_mddevs_lock); +- list_for_each(tmp,&all_mddevs) +- if (!l--) { +- mddev = list_entry(tmp, struct mddev, all_mddevs); +- if (!mddev_get(mddev)) +- continue; +- spin_unlock(&all_mddevs_lock); +- return mddev; +- } +- spin_unlock(&all_mddevs_lock); +- if (!l--) +- return (void*)2;/* tail */ +- return NULL; ++ ++ return seq_list_start_head(&all_mddevs, *pos); + } + + static void *md_seq_next(struct seq_file *seq, void *v, loff_t *pos) + { +- struct list_head *tmp; +- struct mddev *next_mddev, *mddev = v; +- struct mddev *to_put = NULL; ++ return seq_list_next(v, &all_mddevs, pos); ++} + +- ++*pos; +- if (v == (void*)2) +- return NULL; ++static void md_seq_stop(struct seq_file *seq, void *v) ++ __releases(&all_mddevs_lock) ++{ ++ spin_unlock(&all_mddevs_lock); ++} + +- spin_lock(&all_mddevs_lock); +- if (v == (void*)1) { +- tmp = all_mddevs.next; +- } else { +- to_put = mddev; +- tmp = mddev->all_mddevs.next; +- } ++static void md_bitmap_status(struct seq_file *seq, struct mddev *mddev) ++{ ++ struct md_bitmap_stats stats; ++ unsigned long used_pages; ++ unsigned long chunk_kb; ++ int err; + +- for (;;) { +- if (tmp == &all_mddevs) { +- next_mddev = (void*)2; +- *pos = 0x10000; +- break; +- } +- next_mddev = list_entry(tmp, struct mddev, all_mddevs); +- if (mddev_get(next_mddev)) +- break; +- mddev = next_mddev; +- tmp = mddev->all_mddevs.next; +- } +- spin_unlock(&all_mddevs_lock); ++ err = md_bitmap_get_stats(mddev->bitmap, &stats); ++ if (err) ++ return; + +- if (to_put) +- mddev_put(to_put); +- return next_mddev; ++ chunk_kb = mddev->bitmap_info.chunksize >> 10; ++ used_pages = stats.pages - stats.missing_pages; + +-} ++ seq_printf(seq, "bitmap: %lu/%lu pages [%luKB], %lu%s chunk", ++ used_pages, stats.pages, used_pages << (PAGE_SHIFT - 10), ++ chunk_kb ? chunk_kb : mddev->bitmap_info.chunksize, ++ chunk_kb ? "KB" : "B"); + +-static void md_seq_stop(struct seq_file *seq, void *v) +-{ +- struct mddev *mddev = v; ++ if (stats.file) { ++ seq_puts(seq, ", file: "); ++ seq_file_path(seq, stats.file, " \t\n"); ++ } + +- if (mddev && v != (void*)1 && v != (void*)2) +- mddev_put(mddev); ++ seq_putc(seq, '\n'); + } + + static int md_seq_show(struct seq_file *seq, void *v) + { +- struct mddev *mddev = v; ++ struct mddev *mddev; + sector_t sectors; + struct md_rdev *rdev; + +- if (v == (void*)1) { +- struct md_personality *pers; +- seq_printf(seq, "Personalities : "); +- spin_lock(&pers_lock); +- list_for_each_entry(pers, &pers_list, list) +- seq_printf(seq, "[%s] ", pers->name); +- +- spin_unlock(&pers_lock); +- seq_printf(seq, "\n"); +- seq->poll_event = atomic_read(&md_event_count); ++ if (v == &all_mddevs) { ++ status_personalities(seq); ++ if (list_empty(&all_mddevs)) ++ status_unused(seq); + return 0; + } +- if (v == (void*)2) { +- status_unused(seq); ++ ++ mddev = list_entry(v, struct mddev, all_mddevs); ++ if (!mddev_get(mddev)) + return 0; +- } ++ ++ spin_unlock(&all_mddevs_lock); ++ ++ /* prevent bitmap to be freed after checking */ ++ mutex_lock(&mddev->bitmap_info.mutex); + + spin_lock(&mddev->lock); + if (mddev->pers || mddev->raid_disks || !list_empty(&mddev->disks)) { +@@ -8416,11 +8406,19 @@ static int md_seq_show(struct seq_file *seq, void *v) + } else + seq_printf(seq, "\n "); + +- md_bitmap_status(seq, mddev->bitmap); ++ md_bitmap_status(seq, mddev); + + seq_printf(seq, "\n"); + } + spin_unlock(&mddev->lock); ++ mutex_unlock(&mddev->bitmap_info.mutex); ++ spin_lock(&all_mddevs_lock); ++ ++ if (mddev == list_last_entry(&all_mddevs, struct mddev, all_mddevs)) ++ status_unused(seq); ++ ++ if (atomic_dec_and_test(&mddev->active)) ++ __mddev_put(mddev); + + return 0; + } +@@ -9333,7 +9331,7 @@ static int remove_and_add_spares(struct mddev *mddev, + + static void md_start_sync(struct work_struct *ws) + { +- struct mddev *mddev = container_of(ws, struct mddev, del_work); ++ struct mddev *mddev = container_of(ws, struct mddev, sync_work); + + rcu_assign_pointer(mddev->sync_thread, + md_register_thread(md_do_sync, mddev, "resync")); +@@ -9546,8 +9544,7 @@ void md_check_recovery(struct mddev *mddev) + */ + md_bitmap_write_all(mddev->bitmap); + } +- INIT_WORK(&mddev->del_work, md_start_sync); +- queue_work(md_misc_wq, &mddev->del_work); ++ queue_work(md_misc_wq, &mddev->sync_work); + goto unlock; + } + not_running: +diff --git a/drivers/md/md.h b/drivers/md/md.h +index f29fa8650cd0f0..46995558d3bd91 100644 +--- a/drivers/md/md.h ++++ b/drivers/md/md.h +@@ -453,7 +453,10 @@ struct mddev { + struct kernfs_node *sysfs_degraded; /*handle for 'degraded' */ + struct kernfs_node *sysfs_level; /*handle for 'level' */ + +- struct work_struct del_work; /* used for delayed sysfs removal */ ++ /* used for delayed sysfs removal */ ++ struct work_struct del_work; ++ /* used for register new sync thread */ ++ struct work_struct sync_work; + + /* "lock" protects: + * flush_bio transition from NULL to !NULL +diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c +index ce70e96b8fb52e..028c4a5049af97 100644 +--- a/drivers/media/usb/uvc/uvc_ctrl.c ++++ b/drivers/media/usb/uvc/uvc_ctrl.c +@@ -1532,6 +1532,40 @@ static void uvc_ctrl_send_slave_event(struct uvc_video_chain *chain, + uvc_ctrl_send_event(chain, handle, ctrl, mapping, val, changes); + } + ++static void uvc_ctrl_set_handle(struct uvc_fh *handle, struct uvc_control *ctrl, ++ struct uvc_fh *new_handle) ++{ ++ lockdep_assert_held(&handle->chain->ctrl_mutex); ++ ++ if (new_handle) { ++ if (ctrl->handle) ++ dev_warn_ratelimited(&handle->stream->dev->udev->dev, ++ "UVC non compliance: Setting an async control with a pending operation."); ++ ++ if (new_handle == ctrl->handle) ++ return; ++ ++ if (ctrl->handle) { ++ WARN_ON(!ctrl->handle->pending_async_ctrls); ++ if (ctrl->handle->pending_async_ctrls) ++ ctrl->handle->pending_async_ctrls--; ++ } ++ ++ ctrl->handle = new_handle; ++ handle->pending_async_ctrls++; ++ return; ++ } ++ ++ /* Cannot clear the handle for a control not owned by us.*/ ++ if (WARN_ON(ctrl->handle != handle)) ++ return; ++ ++ ctrl->handle = NULL; ++ if (WARN_ON(!handle->pending_async_ctrls)) ++ return; ++ handle->pending_async_ctrls--; ++} ++ + void uvc_ctrl_status_event(struct uvc_video_chain *chain, + struct uvc_control *ctrl, const u8 *data) + { +@@ -1542,7 +1576,8 @@ void uvc_ctrl_status_event(struct uvc_video_chain *chain, + mutex_lock(&chain->ctrl_mutex); + + handle = ctrl->handle; +- ctrl->handle = NULL; ++ if (handle) ++ uvc_ctrl_set_handle(handle, ctrl, NULL); + + list_for_each_entry(mapping, &ctrl->info.mappings, list) { + s32 value = __uvc_ctrl_get_value(mapping, data); +@@ -1762,7 +1797,10 @@ int uvc_ctrl_begin(struct uvc_video_chain *chain) + } + + static int uvc_ctrl_commit_entity(struct uvc_device *dev, +- struct uvc_entity *entity, int rollback, struct uvc_control **err_ctrl) ++ struct uvc_fh *handle, ++ struct uvc_entity *entity, ++ int rollback, ++ struct uvc_control **err_ctrl) + { + struct uvc_control *ctrl; + unsigned int i; +@@ -1810,6 +1848,10 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev, + *err_ctrl = ctrl; + return ret; + } ++ ++ if (!rollback && handle && ++ ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS) ++ uvc_ctrl_set_handle(handle, ctrl, handle); + } + + return 0; +@@ -1846,18 +1888,20 @@ int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback, + + /* Find the control. */ + list_for_each_entry(entity, &chain->entities, chain) { +- ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback, +- &err_ctrl); +- if (ret < 0) ++ ret = uvc_ctrl_commit_entity(chain->dev, handle, entity, ++ rollback, &err_ctrl); ++ if (ret < 0) { ++ if (ctrls) ++ ctrls->error_idx = ++ uvc_ctrl_find_ctrl_idx(entity, ctrls, ++ err_ctrl); + goto done; ++ } + } + + if (!rollback) + uvc_ctrl_send_events(handle, ctrls->controls, ctrls->count); + done: +- if (ret < 0 && ctrls) +- ctrls->error_idx = uvc_ctrl_find_ctrl_idx(entity, ctrls, +- err_ctrl); + mutex_unlock(&chain->ctrl_mutex); + return ret; + } +@@ -1995,9 +2039,6 @@ int uvc_ctrl_set(struct uvc_fh *handle, + mapping->set(mapping, value, + uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT)); + +- if (ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS) +- ctrl->handle = handle; +- + ctrl->dirty = 1; + ctrl->modified = 1; + return 0; +@@ -2170,7 +2211,7 @@ static int uvc_ctrl_init_xu_ctrl(struct uvc_device *dev, + int uvc_xu_ctrl_query(struct uvc_video_chain *chain, + struct uvc_xu_control_query *xqry) + { +- struct uvc_entity *entity; ++ struct uvc_entity *entity, *iter; + struct uvc_control *ctrl; + unsigned int i; + bool found; +@@ -2180,16 +2221,16 @@ int uvc_xu_ctrl_query(struct uvc_video_chain *chain, + int ret; + + /* Find the extension unit. */ +- found = false; +- list_for_each_entry(entity, &chain->entities, chain) { +- if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT && +- entity->id == xqry->unit) { +- found = true; ++ entity = NULL; ++ list_for_each_entry(iter, &chain->entities, chain) { ++ if (UVC_ENTITY_TYPE(iter) == UVC_VC_EXTENSION_UNIT && ++ iter->id == xqry->unit) { ++ entity = iter; + break; + } + } + +- if (!found) { ++ if (!entity) { + uvc_dbg(chain->dev, CONTROL, "Extension unit %u not found\n", + xqry->unit); + return -ENOENT; +@@ -2326,7 +2367,7 @@ int uvc_ctrl_restore_values(struct uvc_device *dev) + ctrl->dirty = 1; + } + +- ret = uvc_ctrl_commit_entity(dev, entity, 0, NULL); ++ ret = uvc_ctrl_commit_entity(dev, NULL, entity, 0, NULL); + if (ret < 0) + return ret; + } +@@ -2748,6 +2789,26 @@ int uvc_ctrl_init_device(struct uvc_device *dev) + return 0; + } + ++void uvc_ctrl_cleanup_fh(struct uvc_fh *handle) ++{ ++ struct uvc_entity *entity; ++ ++ guard(mutex)(&handle->chain->ctrl_mutex); ++ ++ if (!handle->pending_async_ctrls) ++ return; ++ ++ list_for_each_entry(entity, &handle->chain->dev->entities, list) { ++ for (unsigned int i = 0; i < entity->ncontrols; ++i) { ++ if (entity->controls[i].handle != handle) ++ continue; ++ uvc_ctrl_set_handle(handle, &entity->controls[i], NULL); ++ } ++ } ++ ++ WARN_ON(handle->pending_async_ctrls); ++} ++ + /* + * Cleanup device controls. + */ +diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c +index f4988f03640aec..7bcd706281daf3 100644 +--- a/drivers/media/usb/uvc/uvc_v4l2.c ++++ b/drivers/media/usb/uvc/uvc_v4l2.c +@@ -659,6 +659,8 @@ static int uvc_v4l2_release(struct file *file) + + uvc_dbg(stream->dev, CALLS, "%s\n", __func__); + ++ uvc_ctrl_cleanup_fh(handle); ++ + /* Only free resources if this is a privileged handle. */ + if (uvc_has_privileges(handle)) + uvc_queue_release(&stream->queue); +diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h +index 30fd056b2aec9d..e99bfaa622669b 100644 +--- a/drivers/media/usb/uvc/uvcvideo.h ++++ b/drivers/media/usb/uvc/uvcvideo.h +@@ -334,7 +334,11 @@ struct uvc_video_chain { + struct uvc_entity *processing; /* Processing unit */ + struct uvc_entity *selector; /* Selector unit */ + +- struct mutex ctrl_mutex; /* Protects ctrl.info */ ++ struct mutex ctrl_mutex; /* ++ * Protects ctrl.info, ++ * ctrl.handle and ++ * uvc_fh.pending_async_ctrls ++ */ + + struct v4l2_prio_state prio; /* V4L2 priority state */ + u32 caps; /* V4L2 chain-wide caps */ +@@ -609,6 +613,7 @@ struct uvc_fh { + struct uvc_video_chain *chain; + struct uvc_streaming *stream; + enum uvc_handle_state state; ++ unsigned int pending_async_ctrls; + }; + + struct uvc_driver { +@@ -794,6 +799,8 @@ int uvc_ctrl_is_accessible(struct uvc_video_chain *chain, u32 v4l2_id, + int uvc_xu_ctrl_query(struct uvc_video_chain *chain, + struct uvc_xu_control_query *xqry); + ++void uvc_ctrl_cleanup_fh(struct uvc_fh *handle); ++ + /* Utility functions */ + struct usb_host_endpoint *uvc_find_endpoint(struct usb_host_interface *alts, + u8 epaddr); +diff --git a/drivers/mtd/nand/raw/cadence-nand-controller.c b/drivers/mtd/nand/raw/cadence-nand-controller.c +index 034ec564c2edb0..4f37ca894d18a1 100644 +--- a/drivers/mtd/nand/raw/cadence-nand-controller.c ++++ b/drivers/mtd/nand/raw/cadence-nand-controller.c +@@ -469,6 +469,8 @@ struct cdns_nand_ctrl { + struct { + void __iomem *virt; + dma_addr_t dma; ++ dma_addr_t iova_dma; ++ u32 size; + } io; + + int irq; +@@ -1838,11 +1840,11 @@ static int cadence_nand_slave_dma_transfer(struct cdns_nand_ctrl *cdns_ctrl, + } + + if (dir == DMA_FROM_DEVICE) { +- src_dma = cdns_ctrl->io.dma; ++ src_dma = cdns_ctrl->io.iova_dma; + dst_dma = buf_dma; + } else { + src_dma = buf_dma; +- dst_dma = cdns_ctrl->io.dma; ++ dst_dma = cdns_ctrl->io.iova_dma; + } + + tx = dmaengine_prep_dma_memcpy(cdns_ctrl->dmac, dst_dma, src_dma, len, +@@ -1864,12 +1866,12 @@ static int cadence_nand_slave_dma_transfer(struct cdns_nand_ctrl *cdns_ctrl, + dma_async_issue_pending(cdns_ctrl->dmac); + wait_for_completion(&finished); + +- dma_unmap_single(cdns_ctrl->dev, buf_dma, len, dir); ++ dma_unmap_single(dma_dev->dev, buf_dma, len, dir); + + return 0; + + err_unmap: +- dma_unmap_single(cdns_ctrl->dev, buf_dma, len, dir); ++ dma_unmap_single(dma_dev->dev, buf_dma, len, dir); + + err: + dev_dbg(cdns_ctrl->dev, "Fall back to CPU I/O\n"); +@@ -2874,6 +2876,7 @@ cadence_nand_irq_cleanup(int irqnum, struct cdns_nand_ctrl *cdns_ctrl) + static int cadence_nand_init(struct cdns_nand_ctrl *cdns_ctrl) + { + dma_cap_mask_t mask; ++ struct dma_device *dma_dev = cdns_ctrl->dmac->device; + int ret; + + cdns_ctrl->cdma_desc = dma_alloc_coherent(cdns_ctrl->dev, +@@ -2909,15 +2912,24 @@ static int cadence_nand_init(struct cdns_nand_ctrl *cdns_ctrl) + dma_cap_set(DMA_MEMCPY, mask); + + if (cdns_ctrl->caps1->has_dma) { +- cdns_ctrl->dmac = dma_request_channel(mask, NULL, NULL); +- if (!cdns_ctrl->dmac) { +- dev_err(cdns_ctrl->dev, +- "Unable to get a DMA channel\n"); +- ret = -EBUSY; ++ cdns_ctrl->dmac = dma_request_chan_by_mask(&mask); ++ if (IS_ERR(cdns_ctrl->dmac)) { ++ ret = dev_err_probe(cdns_ctrl->dev, PTR_ERR(cdns_ctrl->dmac), ++ "%d: Failed to get a DMA channel\n", ret); + goto disable_irq; + } + } + ++ cdns_ctrl->io.iova_dma = dma_map_resource(dma_dev->dev, cdns_ctrl->io.dma, ++ cdns_ctrl->io.size, ++ DMA_BIDIRECTIONAL, 0); ++ ++ ret = dma_mapping_error(dma_dev->dev, cdns_ctrl->io.iova_dma); ++ if (ret) { ++ dev_err(cdns_ctrl->dev, "Failed to map I/O resource to DMA\n"); ++ goto dma_release_chnl; ++ } ++ + nand_controller_init(&cdns_ctrl->controller); + INIT_LIST_HEAD(&cdns_ctrl->chips); + +@@ -2928,18 +2940,22 @@ static int cadence_nand_init(struct cdns_nand_ctrl *cdns_ctrl) + if (ret) { + dev_err(cdns_ctrl->dev, "Failed to register MTD: %d\n", + ret); +- goto dma_release_chnl; ++ goto unmap_dma_resource; + } + + kfree(cdns_ctrl->buf); + cdns_ctrl->buf = kzalloc(cdns_ctrl->buf_size, GFP_KERNEL); + if (!cdns_ctrl->buf) { + ret = -ENOMEM; +- goto dma_release_chnl; ++ goto unmap_dma_resource; + } + + return 0; + ++unmap_dma_resource: ++ dma_unmap_resource(dma_dev->dev, cdns_ctrl->io.iova_dma, ++ cdns_ctrl->io.size, DMA_BIDIRECTIONAL, 0); ++ + dma_release_chnl: + if (cdns_ctrl->dmac) + dma_release_channel(cdns_ctrl->dmac); +@@ -2961,6 +2977,8 @@ static int cadence_nand_init(struct cdns_nand_ctrl *cdns_ctrl) + static void cadence_nand_remove(struct cdns_nand_ctrl *cdns_ctrl) + { + cadence_nand_chips_cleanup(cdns_ctrl); ++ dma_unmap_resource(cdns_ctrl->dmac->device->dev, cdns_ctrl->io.iova_dma, ++ cdns_ctrl->io.size, DMA_BIDIRECTIONAL, 0); + cadence_nand_irq_cleanup(cdns_ctrl->irq, cdns_ctrl); + kfree(cdns_ctrl->buf); + dma_free_coherent(cdns_ctrl->dev, sizeof(struct cadence_nand_cdma_desc), +@@ -3029,7 +3047,9 @@ static int cadence_nand_dt_probe(struct platform_device *ofdev) + cdns_ctrl->io.virt = devm_platform_get_and_ioremap_resource(ofdev, 1, &res); + if (IS_ERR(cdns_ctrl->io.virt)) + return PTR_ERR(cdns_ctrl->io.virt); ++ + cdns_ctrl->io.dma = res->start; ++ cdns_ctrl->io.size = resource_size(res); + + dt->clk = devm_clk_get(cdns_ctrl->dev, "nf_clk"); + if (IS_ERR(dt->clk)) +diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c +index 61685c3053ad7e..4f18addc191b85 100644 +--- a/drivers/net/ethernet/ibm/ibmvnic.c ++++ b/drivers/net/ethernet/ibm/ibmvnic.c +@@ -117,6 +117,7 @@ static void free_long_term_buff(struct ibmvnic_adapter *adapter, + struct ibmvnic_long_term_buff *ltb); + static void ibmvnic_disable_irqs(struct ibmvnic_adapter *adapter); + static void flush_reset_queue(struct ibmvnic_adapter *adapter); ++static void print_subcrq_error(struct device *dev, int rc, const char *func); + + struct ibmvnic_stat { + char name[ETH_GSTRING_LEN]; +@@ -2325,7 +2326,7 @@ static void ibmvnic_tx_scrq_clean_buffer(struct ibmvnic_adapter *adapter, + tx_buff = &tx_pool->tx_buff[index]; + adapter->netdev->stats.tx_packets--; + adapter->netdev->stats.tx_bytes -= tx_buff->skb->len; +- adapter->tx_stats_buffers[queue_num].packets--; ++ adapter->tx_stats_buffers[queue_num].batched_packets--; + adapter->tx_stats_buffers[queue_num].bytes -= + tx_buff->skb->len; + dev_kfree_skb_any(tx_buff->skb); +@@ -2350,8 +2351,29 @@ static void ibmvnic_tx_scrq_clean_buffer(struct ibmvnic_adapter *adapter, + } + } + ++static int send_subcrq_direct(struct ibmvnic_adapter *adapter, ++ u64 remote_handle, u64 *entry) ++{ ++ unsigned int ua = adapter->vdev->unit_address; ++ struct device *dev = &adapter->vdev->dev; ++ int rc; ++ ++ /* Make sure the hypervisor sees the complete request */ ++ dma_wmb(); ++ rc = plpar_hcall_norets(H_SEND_SUB_CRQ, ua, ++ cpu_to_be64(remote_handle), ++ cpu_to_be64(entry[0]), cpu_to_be64(entry[1]), ++ cpu_to_be64(entry[2]), cpu_to_be64(entry[3])); ++ ++ if (rc) ++ print_subcrq_error(dev, rc, __func__); ++ ++ return rc; ++} ++ + static int ibmvnic_tx_scrq_flush(struct ibmvnic_adapter *adapter, +- struct ibmvnic_sub_crq_queue *tx_scrq) ++ struct ibmvnic_sub_crq_queue *tx_scrq, ++ bool indirect) + { + struct ibmvnic_ind_xmit_queue *ind_bufp; + u64 dma_addr; +@@ -2366,12 +2388,18 @@ static int ibmvnic_tx_scrq_flush(struct ibmvnic_adapter *adapter, + + if (!entries) + return 0; +- rc = send_subcrq_indirect(adapter, handle, dma_addr, entries); ++ ++ if (indirect) ++ rc = send_subcrq_indirect(adapter, handle, dma_addr, entries); ++ else ++ rc = send_subcrq_direct(adapter, handle, ++ (u64 *)ind_bufp->indir_arr); ++ + if (rc) + ibmvnic_tx_scrq_clean_buffer(adapter, tx_scrq); + else + ind_bufp->index = 0; +- return 0; ++ return rc; + } + + static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev) +@@ -2390,11 +2418,13 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev) + unsigned int tx_map_failed = 0; + union sub_crq indir_arr[16]; + unsigned int tx_dropped = 0; +- unsigned int tx_packets = 0; ++ unsigned int tx_dpackets = 0; ++ unsigned int tx_bpackets = 0; + unsigned int tx_bytes = 0; + dma_addr_t data_dma_addr; + struct netdev_queue *txq; + unsigned long lpar_rc; ++ unsigned int skblen; + union sub_crq tx_crq; + unsigned int offset; + int num_entries = 1; +@@ -2424,7 +2454,9 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev) + tx_dropped++; + tx_send_failed++; + ret = NETDEV_TX_OK; +- ibmvnic_tx_scrq_flush(adapter, tx_scrq); ++ lpar_rc = ibmvnic_tx_scrq_flush(adapter, tx_scrq, true); ++ if (lpar_rc != H_SUCCESS) ++ goto tx_err; + goto out; + } + +@@ -2439,8 +2471,10 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev) + dev_kfree_skb_any(skb); + tx_send_failed++; + tx_dropped++; +- ibmvnic_tx_scrq_flush(adapter, tx_scrq); + ret = NETDEV_TX_OK; ++ lpar_rc = ibmvnic_tx_scrq_flush(adapter, tx_scrq, true); ++ if (lpar_rc != H_SUCCESS) ++ goto tx_err; + goto out; + } + +@@ -2493,6 +2527,7 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev) + tx_buff->skb = skb; + tx_buff->index = bufidx; + tx_buff->pool_index = queue_num; ++ skblen = skb->len; + + memset(&tx_crq, 0, sizeof(tx_crq)); + tx_crq.v1.first = IBMVNIC_CRQ_CMD; +@@ -2536,6 +2571,17 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev) + tx_crq.v1.flags1 |= IBMVNIC_TX_LSO; + tx_crq.v1.mss = cpu_to_be16(skb_shinfo(skb)->gso_size); + hdrs += 2; ++ } else if (!ind_bufp->index && !netdev_xmit_more()) { ++ ind_bufp->indir_arr[0] = tx_crq; ++ ind_bufp->index = 1; ++ tx_buff->num_entries = 1; ++ netdev_tx_sent_queue(txq, skb->len); ++ lpar_rc = ibmvnic_tx_scrq_flush(adapter, tx_scrq, false); ++ if (lpar_rc != H_SUCCESS) ++ goto tx_err; ++ ++ tx_dpackets++; ++ goto early_exit; + } + + if ((*hdrs >> 7) & 1) +@@ -2545,7 +2591,7 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev) + tx_buff->num_entries = num_entries; + /* flush buffer if current entry can not fit */ + if (num_entries + ind_bufp->index > IBMVNIC_MAX_IND_DESCS) { +- lpar_rc = ibmvnic_tx_scrq_flush(adapter, tx_scrq); ++ lpar_rc = ibmvnic_tx_scrq_flush(adapter, tx_scrq, true); + if (lpar_rc != H_SUCCESS) + goto tx_flush_err; + } +@@ -2553,23 +2599,26 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev) + indir_arr[0] = tx_crq; + memcpy(&ind_bufp->indir_arr[ind_bufp->index], &indir_arr[0], + num_entries * sizeof(struct ibmvnic_generic_scrq)); ++ + ind_bufp->index += num_entries; + if (__netdev_tx_sent_queue(txq, skb->len, + netdev_xmit_more() && + ind_bufp->index < IBMVNIC_MAX_IND_DESCS)) { +- lpar_rc = ibmvnic_tx_scrq_flush(adapter, tx_scrq); ++ lpar_rc = ibmvnic_tx_scrq_flush(adapter, tx_scrq, true); + if (lpar_rc != H_SUCCESS) + goto tx_err; + } + ++ tx_bpackets++; ++ ++early_exit: + if (atomic_add_return(num_entries, &tx_scrq->used) + >= adapter->req_tx_entries_per_subcrq) { + netdev_dbg(netdev, "Stopping queue %d\n", queue_num); + netif_stop_subqueue(netdev, queue_num); + } + +- tx_packets++; +- tx_bytes += skb->len; ++ tx_bytes += skblen; + txq_trans_cond_update(txq); + ret = NETDEV_TX_OK; + goto out; +@@ -2598,10 +2647,11 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev) + rcu_read_unlock(); + netdev->stats.tx_dropped += tx_dropped; + netdev->stats.tx_bytes += tx_bytes; +- netdev->stats.tx_packets += tx_packets; ++ netdev->stats.tx_packets += tx_bpackets + tx_dpackets; + adapter->tx_send_failed += tx_send_failed; + adapter->tx_map_failed += tx_map_failed; +- adapter->tx_stats_buffers[queue_num].packets += tx_packets; ++ adapter->tx_stats_buffers[queue_num].batched_packets += tx_bpackets; ++ adapter->tx_stats_buffers[queue_num].direct_packets += tx_dpackets; + adapter->tx_stats_buffers[queue_num].bytes += tx_bytes; + adapter->tx_stats_buffers[queue_num].dropped_packets += tx_dropped; + +@@ -3767,7 +3817,10 @@ static void ibmvnic_get_strings(struct net_device *dev, u32 stringset, u8 *data) + memcpy(data, ibmvnic_stats[i].name, ETH_GSTRING_LEN); + + for (i = 0; i < adapter->req_tx_queues; i++) { +- snprintf(data, ETH_GSTRING_LEN, "tx%d_packets", i); ++ snprintf(data, ETH_GSTRING_LEN, "tx%d_batched_packets", i); ++ data += ETH_GSTRING_LEN; ++ ++ snprintf(data, ETH_GSTRING_LEN, "tx%d_direct_packets", i); + data += ETH_GSTRING_LEN; + + snprintf(data, ETH_GSTRING_LEN, "tx%d_bytes", i); +@@ -3832,7 +3885,9 @@ static void ibmvnic_get_ethtool_stats(struct net_device *dev, + (adapter, ibmvnic_stats[i].offset)); + + for (j = 0; j < adapter->req_tx_queues; j++) { +- data[i] = adapter->tx_stats_buffers[j].packets; ++ data[i] = adapter->tx_stats_buffers[j].batched_packets; ++ i++; ++ data[i] = adapter->tx_stats_buffers[j].direct_packets; + i++; + data[i] = adapter->tx_stats_buffers[j].bytes; + i++; +diff --git a/drivers/net/ethernet/ibm/ibmvnic.h b/drivers/net/ethernet/ibm/ibmvnic.h +index 4e18b4cefa972c..b3fc18db4f4c39 100644 +--- a/drivers/net/ethernet/ibm/ibmvnic.h ++++ b/drivers/net/ethernet/ibm/ibmvnic.h +@@ -213,7 +213,8 @@ struct ibmvnic_statistics { + + #define NUM_TX_STATS 3 + struct ibmvnic_tx_queue_stats { +- u64 packets; ++ u64 batched_packets; ++ u64 direct_packets; + u64 bytes; + u64 dropped_packets; + }; +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +index 6e431f587c233a..b34f57ab9755ce 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +@@ -6110,7 +6110,9 @@ static void mlx5e_remove(struct auxiliary_device *adev) + mlx5e_dcbnl_delete_app(priv); + unregister_netdev(priv->netdev); + mlx5e_suspend(adev, state); +- priv->profile->cleanup(priv); ++ /* Avoid cleanup if profile rollback failed. */ ++ if (priv->profile) ++ priv->profile->cleanup(priv); + mlx5e_destroy_netdev(priv); + mlx5e_devlink_port_unregister(mlx5e_dev); + mlx5e_destroy_devlink(mlx5e_dev); +diff --git a/drivers/net/ethernet/netronome/nfp/bpf/cmsg.c b/drivers/net/ethernet/netronome/nfp/bpf/cmsg.c +index 2ec62c8d86e1c1..59486fe2ad18c2 100644 +--- a/drivers/net/ethernet/netronome/nfp/bpf/cmsg.c ++++ b/drivers/net/ethernet/netronome/nfp/bpf/cmsg.c +@@ -20,6 +20,8 @@ nfp_bpf_cmsg_alloc(struct nfp_app_bpf *bpf, unsigned int size) + struct sk_buff *skb; + + skb = nfp_app_ctrl_msg_alloc(bpf->app, size, GFP_KERNEL); ++ if (!skb) ++ return NULL; + skb_put(skb, size); + + return skb; +diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +index 02e11827440b5c..3517a2275821ff 100644 +--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c ++++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +@@ -2161,6 +2161,7 @@ static int axienet_probe(struct platform_device *pdev) + + lp->phylink_config.dev = &ndev->dev; + lp->phylink_config.type = PHYLINK_NETDEV; ++ lp->phylink_config.mac_managed_pm = true; + lp->phylink_config.mac_capabilities = MAC_SYM_PAUSE | MAC_ASYM_PAUSE | + MAC_10FD | MAC_100FD | MAC_1000FD; + +diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c +index b939d4711c59b6..27761334e1bff7 100644 +--- a/drivers/net/geneve.c ++++ b/drivers/net/geneve.c +@@ -1961,21 +1961,9 @@ static void geneve_destroy_tunnels(struct net *net, struct list_head *head) + { + struct geneve_net *gn = net_generic(net, geneve_net_id); + struct geneve_dev *geneve, *next; +- struct net_device *dev, *aux; + +- /* gather any geneve devices that were moved into this ns */ +- for_each_netdev_safe(net, dev, aux) +- if (dev->rtnl_link_ops == &geneve_link_ops) +- unregister_netdevice_queue(dev, head); +- +- /* now gather any other geneve devices that were created in this ns */ +- list_for_each_entry_safe(geneve, next, &gn->geneve_list, next) { +- /* If geneve->dev is in the same netns, it was already added +- * to the list by the previous loop. +- */ +- if (!net_eq(dev_net(geneve->dev), net)) +- unregister_netdevice_queue(geneve->dev, head); +- } ++ list_for_each_entry_safe(geneve, next, &gn->geneve_list, next) ++ geneve_dellink(geneve->dev, head); + } + + static void __net_exit geneve_exit_batch_net(struct list_head *net_list) +diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c +index 47238c3ec82e75..55160a5fc90fc6 100644 +--- a/drivers/net/gtp.c ++++ b/drivers/net/gtp.c +@@ -1895,11 +1895,6 @@ static void __net_exit gtp_net_exit_batch_rtnl(struct list_head *net_list, + list_for_each_entry(net, net_list, exit_list) { + struct gtp_net *gn = net_generic(net, gtp_net_id); + struct gtp_dev *gtp, *gtp_next; +- struct net_device *dev; +- +- for_each_netdev(net, dev) +- if (dev->rtnl_link_ops == >p_link_ops) +- gtp_dellink(dev, dev_to_kill); + + list_for_each_entry_safe(gtp, gtp_next, &gn->gtp_dev_list, list) + gtp_dellink(gtp->dev, dev_to_kill); +diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c +index 19a7f0160618d1..4ce31f9f069475 100644 +--- a/drivers/nvme/host/ioctl.c ++++ b/drivers/nvme/host/ioctl.c +@@ -336,8 +336,7 @@ static bool nvme_validate_passthru_nsid(struct nvme_ctrl *ctrl, + { + if (ns && nsid != ns->head->ns_id) { + dev_err(ctrl->device, +- "%s: nsid (%u) in cmd does not match nsid (%u)" +- "of namespace\n", ++ "%s: nsid (%u) in cmd does not match nsid (%u) of namespace\n", + current->comm, nsid, ns->head->ns_id); + return false; + } +diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c +index fd11d3825cf854..3ea94bc26e8003 100644 +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -19,29 +19,7 @@ + #include + #include + +-struct nvmem_device { +- struct module *owner; +- struct device dev; +- int stride; +- int word_size; +- int id; +- struct kref refcnt; +- size_t size; +- bool read_only; +- bool root_only; +- int flags; +- enum nvmem_type type; +- struct bin_attribute eeprom; +- struct device *base_dev; +- struct list_head cells; +- const struct nvmem_keepout *keepout; +- unsigned int nkeepout; +- nvmem_reg_read_t reg_read; +- nvmem_reg_write_t reg_write; +- struct gpio_desc *wp_gpio; +- struct nvmem_layout *layout; +- void *priv; +-}; ++#include "internals.h" + + #define to_nvmem_device(d) container_of(d, struct nvmem_device, dev) + +@@ -696,7 +674,6 @@ static int nvmem_validate_keepouts(struct nvmem_device *nvmem) + + static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_node *np) + { +- struct nvmem_layout *layout = nvmem->layout; + struct device *dev = &nvmem->dev; + struct device_node *child; + const __be32 *addr; +@@ -726,8 +703,8 @@ static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_nod + + info.np = of_node_get(child); + +- if (layout && layout->fixup_cell_info) +- layout->fixup_cell_info(nvmem, layout, &info); ++ if (nvmem->fixup_dt_cell_info) ++ nvmem->fixup_dt_cell_info(nvmem, &info); + + ret = nvmem_add_one_cell(nvmem, &info); + kfree(info.name); +@@ -837,7 +814,7 @@ static int nvmem_add_cells_from_layout(struct nvmem_device *nvmem) + int ret; + + if (layout && layout->add_cells) { +- ret = layout->add_cells(&nvmem->dev, nvmem, layout); ++ ret = layout->add_cells(&nvmem->dev, nvmem); + if (ret) + return ret; + } +@@ -924,6 +901,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) + + kref_init(&nvmem->refcnt); + INIT_LIST_HEAD(&nvmem->cells); ++ nvmem->fixup_dt_cell_info = config->fixup_dt_cell_info; + + nvmem->owner = config->owner; + if (!nvmem->owner && config->dev->driver) +diff --git a/drivers/nvmem/imx-ocotp-ele.c b/drivers/nvmem/imx-ocotp-ele.c +index dfc925edfc83e0..1356ec93bfd00c 100644 +--- a/drivers/nvmem/imx-ocotp-ele.c ++++ b/drivers/nvmem/imx-ocotp-ele.c +@@ -107,6 +107,26 @@ static int imx_ocotp_reg_read(void *context, unsigned int offset, void *val, siz + return 0; + }; + ++static int imx_ocotp_cell_pp(void *context, const char *id, int index, ++ unsigned int offset, void *data, size_t bytes) ++{ ++ u8 *buf = data; ++ int i; ++ ++ /* Deal with some post processing of nvmem cell data */ ++ if (id && !strcmp(id, "mac-address")) ++ for (i = 0; i < bytes / 2; i++) ++ swap(buf[i], buf[bytes - i - 1]); ++ ++ return 0; ++} ++ ++static void imx_ocotp_fixup_dt_cell_info(struct nvmem_device *nvmem, ++ struct nvmem_cell_info *cell) ++{ ++ cell->read_post_process = imx_ocotp_cell_pp; ++} ++ + static int imx_ele_ocotp_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +@@ -133,6 +153,8 @@ static int imx_ele_ocotp_probe(struct platform_device *pdev) + priv->config.stride = 1; + priv->config.priv = priv; + priv->config.read_only = true; ++ priv->config.add_legacy_fixed_of_cells = true; ++ priv->config.fixup_dt_cell_info = imx_ocotp_fixup_dt_cell_info; + mutex_init(&priv->lock); + + nvmem = devm_nvmem_register(dev, &priv->config); +diff --git a/drivers/nvmem/imx-ocotp.c b/drivers/nvmem/imx-ocotp.c +index f1e202efaa4970..79dd4fda03295a 100644 +--- a/drivers/nvmem/imx-ocotp.c ++++ b/drivers/nvmem/imx-ocotp.c +@@ -583,17 +583,12 @@ static const struct of_device_id imx_ocotp_dt_ids[] = { + }; + MODULE_DEVICE_TABLE(of, imx_ocotp_dt_ids); + +-static void imx_ocotp_fixup_cell_info(struct nvmem_device *nvmem, +- struct nvmem_layout *layout, +- struct nvmem_cell_info *cell) ++static void imx_ocotp_fixup_dt_cell_info(struct nvmem_device *nvmem, ++ struct nvmem_cell_info *cell) + { + cell->read_post_process = imx_ocotp_cell_pp; + } + +-static struct nvmem_layout imx_ocotp_layout = { +- .fixup_cell_info = imx_ocotp_fixup_cell_info, +-}; +- + static int imx_ocotp_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +@@ -619,7 +614,7 @@ static int imx_ocotp_probe(struct platform_device *pdev) + imx_ocotp_nvmem_config.size = 4 * priv->params->nregs; + imx_ocotp_nvmem_config.dev = dev; + imx_ocotp_nvmem_config.priv = priv; +- imx_ocotp_nvmem_config.layout = &imx_ocotp_layout; ++ imx_ocotp_nvmem_config.fixup_dt_cell_info = &imx_ocotp_fixup_dt_cell_info; + + priv->config = &imx_ocotp_nvmem_config; + +diff --git a/drivers/nvmem/internals.h b/drivers/nvmem/internals.h +new file mode 100644 +index 00000000000000..893553fbdf51aa +--- /dev/null ++++ b/drivers/nvmem/internals.h +@@ -0,0 +1,37 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++ ++#ifndef _LINUX_NVMEM_INTERNALS_H ++#define _LINUX_NVMEM_INTERNALS_H ++ ++#include ++#include ++#include ++ ++struct nvmem_device { ++ struct module *owner; ++ struct device dev; ++ struct list_head node; ++ int stride; ++ int word_size; ++ int id; ++ struct kref refcnt; ++ size_t size; ++ bool read_only; ++ bool root_only; ++ int flags; ++ enum nvmem_type type; ++ struct bin_attribute eeprom; ++ struct device *base_dev; ++ struct list_head cells; ++ void (*fixup_dt_cell_info)(struct nvmem_device *nvmem, ++ struct nvmem_cell_info *cell); ++ const struct nvmem_keepout *keepout; ++ unsigned int nkeepout; ++ nvmem_reg_read_t reg_read; ++ nvmem_reg_write_t reg_write; ++ struct gpio_desc *wp_gpio; ++ struct nvmem_layout *layout; ++ void *priv; ++}; ++ ++#endif /* ifndef _LINUX_NVMEM_INTERNALS_H */ +diff --git a/drivers/nvmem/layouts/onie-tlv.c b/drivers/nvmem/layouts/onie-tlv.c +index 59fc87ccfcffeb..defd42d4375cc1 100644 +--- a/drivers/nvmem/layouts/onie-tlv.c ++++ b/drivers/nvmem/layouts/onie-tlv.c +@@ -182,8 +182,7 @@ static bool onie_tlv_crc_is_valid(struct device *dev, size_t table_len, u8 *tabl + return true; + } + +-static int onie_tlv_parse_table(struct device *dev, struct nvmem_device *nvmem, +- struct nvmem_layout *layout) ++static int onie_tlv_parse_table(struct device *dev, struct nvmem_device *nvmem) + { + struct onie_tlv_hdr hdr; + size_t table_len, data_len, hdr_len; +diff --git a/drivers/nvmem/layouts/sl28vpd.c b/drivers/nvmem/layouts/sl28vpd.c +index 05671371f63166..26c7cf21b52336 100644 +--- a/drivers/nvmem/layouts/sl28vpd.c ++++ b/drivers/nvmem/layouts/sl28vpd.c +@@ -80,8 +80,7 @@ static int sl28vpd_v1_check_crc(struct device *dev, struct nvmem_device *nvmem) + return 0; + } + +-static int sl28vpd_add_cells(struct device *dev, struct nvmem_device *nvmem, +- struct nvmem_layout *layout) ++static int sl28vpd_add_cells(struct device *dev, struct nvmem_device *nvmem) + { + const struct nvmem_cell_info *pinfo; + struct nvmem_cell_info info = {0}; +diff --git a/drivers/nvmem/mtk-efuse.c b/drivers/nvmem/mtk-efuse.c +index 87c94686cfd216..84f05b40a4112e 100644 +--- a/drivers/nvmem/mtk-efuse.c ++++ b/drivers/nvmem/mtk-efuse.c +@@ -45,9 +45,8 @@ static int mtk_efuse_gpu_speedbin_pp(void *context, const char *id, int index, + return 0; + } + +-static void mtk_efuse_fixup_cell_info(struct nvmem_device *nvmem, +- struct nvmem_layout *layout, +- struct nvmem_cell_info *cell) ++static void mtk_efuse_fixup_dt_cell_info(struct nvmem_device *nvmem, ++ struct nvmem_cell_info *cell) + { + size_t sz = strlen(cell->name); + +@@ -61,10 +60,6 @@ static void mtk_efuse_fixup_cell_info(struct nvmem_device *nvmem, + cell->read_post_process = mtk_efuse_gpu_speedbin_pp; + } + +-static struct nvmem_layout mtk_efuse_layout = { +- .fixup_cell_info = mtk_efuse_fixup_cell_info, +-}; +- + static int mtk_efuse_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +@@ -91,7 +86,7 @@ static int mtk_efuse_probe(struct platform_device *pdev) + econfig.priv = priv; + econfig.dev = dev; + if (pdata->uses_post_processing) +- econfig.layout = &mtk_efuse_layout; ++ econfig.fixup_dt_cell_info = &mtk_efuse_fixup_dt_cell_info; + nvmem = devm_nvmem_register(dev, &econfig); + + return PTR_ERR_OR_ZERO(nvmem); +diff --git a/drivers/power/supply/da9150-fg.c b/drivers/power/supply/da9150-fg.c +index 652c1f213af1c2..4f28ef1bba1a3c 100644 +--- a/drivers/power/supply/da9150-fg.c ++++ b/drivers/power/supply/da9150-fg.c +@@ -247,9 +247,9 @@ static int da9150_fg_current_avg(struct da9150_fg *fg, + DA9150_QIF_SD_GAIN_SIZE); + da9150_fg_read_sync_end(fg); + +- div = (u64) (sd_gain * shunt_val * 65536ULL); ++ div = 65536ULL * sd_gain * shunt_val; + do_div(div, 1000000); +- res = (u64) (iavg * 1000000ULL); ++ res = 1000000ULL * iavg; + do_div(res, div); + + val->intval = (int) res; +diff --git a/drivers/s390/net/ism_drv.c b/drivers/s390/net/ism_drv.c +index f6a0626a6b3ec6..af0d90beba6380 100644 +--- a/drivers/s390/net/ism_drv.c ++++ b/drivers/s390/net/ism_drv.c +@@ -611,6 +611,15 @@ static int ism_dev_init(struct ism_dev *ism) + return ret; + } + ++static void ism_dev_release(struct device *dev) ++{ ++ struct ism_dev *ism; ++ ++ ism = container_of(dev, struct ism_dev, dev); ++ ++ kfree(ism); ++} ++ + static int ism_probe(struct pci_dev *pdev, const struct pci_device_id *id) + { + struct ism_dev *ism; +@@ -624,6 +633,7 @@ static int ism_probe(struct pci_dev *pdev, const struct pci_device_id *id) + dev_set_drvdata(&pdev->dev, ism); + ism->pdev = pdev; + ism->dev.parent = &pdev->dev; ++ ism->dev.release = ism_dev_release; + device_initialize(&ism->dev); + dev_set_name(&ism->dev, dev_name(&pdev->dev)); + ret = device_add(&ism->dev); +@@ -660,7 +670,7 @@ static int ism_probe(struct pci_dev *pdev, const struct pci_device_id *id) + device_del(&ism->dev); + err_dev: + dev_set_drvdata(&pdev->dev, NULL); +- kfree(ism); ++ put_device(&ism->dev); + + return ret; + } +@@ -706,7 +716,7 @@ static void ism_remove(struct pci_dev *pdev) + pci_disable_device(pdev); + device_del(&ism->dev); + dev_set_drvdata(&pdev->dev, NULL); +- kfree(ism); ++ put_device(&ism->dev); + } + + static struct pci_driver ism_driver = { +diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c +index 97def2619ecf2a..f026377f1cf1c4 100644 +--- a/drivers/scsi/scsi_lib.c ++++ b/drivers/scsi/scsi_lib.c +@@ -774,12 +774,18 @@ static void scsi_io_completion_action(struct scsi_cmnd *cmd, int result) + case 0x1a: /* start stop unit in progress */ + case 0x1b: /* sanitize in progress */ + case 0x1d: /* configuration in progress */ +- case 0x24: /* depopulation in progress */ + action = ACTION_DELAYED_RETRY; + break; + case 0x0a: /* ALUA state transition */ + action = ACTION_DELAYED_REPREP; + break; ++ /* ++ * Depopulation might take many hours, ++ * thus it is not worthwhile to retry. ++ */ ++ case 0x24: /* depopulation in progress */ ++ case 0x25: /* depopulation restore in progress */ ++ fallthrough; + default: + action = ACTION_FAIL; + break; +diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c +index 2c627deedc1fa2..fe694fec16b516 100644 +--- a/drivers/scsi/sd.c ++++ b/drivers/scsi/sd.c +@@ -2309,6 +2309,10 @@ sd_spinup_disk(struct scsi_disk *sdkp) + break; /* unavailable */ + if (sshdr.asc == 4 && sshdr.ascq == 0x1b) + break; /* sanitize in progress */ ++ if (sshdr.asc == 4 && sshdr.ascq == 0x24) ++ break; /* depopulation in progress */ ++ if (sshdr.asc == 4 && sshdr.ascq == 0x25) ++ break; /* depopulation restoration in progress */ + /* + * Issue command to spin up drive when not ready + */ +diff --git a/drivers/soc/loongson/loongson2_guts.c b/drivers/soc/loongson/loongson2_guts.c +index 9a469779eea75b..2d7045ee4ac87d 100644 +--- a/drivers/soc/loongson/loongson2_guts.c ++++ b/drivers/soc/loongson/loongson2_guts.c +@@ -114,8 +114,11 @@ static int loongson2_guts_probe(struct platform_device *pdev) + if (of_property_read_string(root, "model", &machine)) + of_property_read_string_index(root, "compatible", 0, &machine); + of_node_put(root); +- if (machine) ++ if (machine) { + soc_dev_attr.machine = devm_kstrdup(dev, machine, GFP_KERNEL); ++ if (!soc_dev_attr.machine) ++ return -ENOMEM; ++ } + + svr = loongson2_guts_get_svr(); + soc_die = loongson2_soc_die_match(svr, loongson2_soc_die); +diff --git a/drivers/soc/mediatek/mtk-devapc.c b/drivers/soc/mediatek/mtk-devapc.c +index 0dfc1da9471cba..d83a46334adbbe 100644 +--- a/drivers/soc/mediatek/mtk-devapc.c ++++ b/drivers/soc/mediatek/mtk-devapc.c +@@ -300,18 +300,17 @@ static int mtk_devapc_probe(struct platform_device *pdev) + return ret; + } + +-static int mtk_devapc_remove(struct platform_device *pdev) ++static void mtk_devapc_remove(struct platform_device *pdev) + { + struct mtk_devapc_context *ctx = platform_get_drvdata(pdev); + + stop_devapc(ctx); +- +- return 0; ++ iounmap(ctx->infra_base); + } + + static struct platform_driver mtk_devapc_driver = { + .probe = mtk_devapc_probe, +- .remove = mtk_devapc_remove, ++ .remove_new = mtk_devapc_remove, + .driver = { + .name = "mtk-devapc", + .of_match_table = mtk_devapc_dt_match, +diff --git a/drivers/tee/optee/supp.c b/drivers/tee/optee/supp.c +index 322a543b8c278a..d0f397c9024201 100644 +--- a/drivers/tee/optee/supp.c ++++ b/drivers/tee/optee/supp.c +@@ -80,7 +80,6 @@ u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params, + struct optee *optee = tee_get_drvdata(ctx->teedev); + struct optee_supp *supp = &optee->supp; + struct optee_supp_req *req; +- bool interruptable; + u32 ret; + + /* +@@ -111,36 +110,18 @@ u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params, + /* + * Wait for supplicant to process and return result, once we've + * returned from wait_for_completion(&req->c) successfully we have +- * exclusive access again. ++ * exclusive access again. Allow the wait to be killable such that ++ * the wait doesn't turn into an indefinite state if the supplicant ++ * gets hung for some reason. + */ +- while (wait_for_completion_interruptible(&req->c)) { ++ if (wait_for_completion_killable(&req->c)) { + mutex_lock(&supp->mutex); +- interruptable = !supp->ctx; +- if (interruptable) { +- /* +- * There's no supplicant available and since the +- * supp->mutex currently is held none can +- * become available until the mutex released +- * again. +- * +- * Interrupting an RPC to supplicant is only +- * allowed as a way of slightly improving the user +- * experience in case the supplicant hasn't been +- * started yet. During normal operation the supplicant +- * will serve all requests in a timely manner and +- * interrupting then wouldn't make sense. +- */ +- if (req->in_queue) { +- list_del(&req->link); +- req->in_queue = false; +- } ++ if (req->in_queue) { ++ list_del(&req->link); ++ req->in_queue = false; + } + mutex_unlock(&supp->mutex); +- +- if (interruptable) { +- req->ret = TEEC_ERROR_COMMUNICATION; +- break; +- } ++ req->ret = TEEC_ERROR_COMMUNICATION; + } + + ret = req->ret; +diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c +index 49946af11a9058..6d91d7d7a23f85 100644 +--- a/drivers/usb/gadget/function/f_midi.c ++++ b/drivers/usb/gadget/function/f_midi.c +@@ -282,7 +282,7 @@ f_midi_complete(struct usb_ep *ep, struct usb_request *req) + /* Our transmit completed. See if there's more to go. + * f_midi_transmit eats req, don't queue it again. */ + req->length = 0; +- f_midi_transmit(midi); ++ queue_work(system_highpri_wq, &midi->work); + return; + } + break; +diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c +index 33979f61dc4dd7..a4120a25428e5d 100644 +--- a/drivers/usb/gadget/udc/core.c ++++ b/drivers/usb/gadget/udc/core.c +@@ -1419,8 +1419,16 @@ int usb_add_gadget(struct usb_gadget *gadget) + if (ret) + goto err_free_id; + ++ ret = sysfs_create_link(&udc->dev.kobj, ++ &gadget->dev.kobj, "gadget"); ++ if (ret) ++ goto err_del_gadget; ++ + return 0; + ++ err_del_gadget: ++ device_del(&gadget->dev); ++ + err_free_id: + ida_free(&gadget_id_numbers, gadget->id_number); + +@@ -1529,8 +1537,9 @@ void usb_del_gadget(struct usb_gadget *gadget) + mutex_unlock(&udc_lock); + + kobject_uevent(&udc->dev.kobj, KOBJ_REMOVE); +- flush_work(&gadget->work); ++ sysfs_remove_link(&udc->dev.kobj, "gadget"); + device_del(&gadget->dev); ++ flush_work(&gadget->work); + ida_free(&gadget_id_numbers, gadget->id_number); + cancel_work_sync(&udc->vbus_work); + device_unregister(&udc->dev); +diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c +index 652279c8b1680a..49ca762baa8f15 100644 +--- a/fs/nilfs2/dir.c ++++ b/fs/nilfs2/dir.c +@@ -64,12 +64,6 @@ static inline unsigned int nilfs_chunk_size(struct inode *inode) + return inode->i_sb->s_blocksize; + } + +-static inline void nilfs_put_page(struct page *page) +-{ +- kunmap(page); +- put_page(page); +-} +- + /* + * Return the offset into page `page_nr' of the last valid + * byte in that page, plus one. +@@ -450,8 +444,7 @@ int nilfs_inode_by_name(struct inode *dir, const struct qstr *qstr, ino_t *ino) + return 0; + } + +-/* Releases the page */ +-void nilfs_set_link(struct inode *dir, struct nilfs_dir_entry *de, ++int nilfs_set_link(struct inode *dir, struct nilfs_dir_entry *de, + struct page *page, struct inode *inode) + { + unsigned int from = (char *)de - (char *)page_address(page); +@@ -461,12 +454,15 @@ void nilfs_set_link(struct inode *dir, struct nilfs_dir_entry *de, + + lock_page(page); + err = nilfs_prepare_chunk(page, from, to); +- BUG_ON(err); ++ if (unlikely(err)) { ++ unlock_page(page); ++ return err; ++ } + de->inode = cpu_to_le64(inode->i_ino); + nilfs_set_de_type(de, inode); + nilfs_commit_chunk(page, mapping, from, to); +- nilfs_put_page(page); + dir->i_mtime = inode_set_ctime_current(dir); ++ return 0; + } + + /* +@@ -569,7 +565,7 @@ int nilfs_add_link(struct dentry *dentry, struct inode *inode) + + /* + * nilfs_delete_entry deletes a directory entry by merging it with the +- * previous entry. Page is up-to-date. Releases the page. ++ * previous entry. Page is up-to-date. + */ + int nilfs_delete_entry(struct nilfs_dir_entry *dir, struct page *page) + { +@@ -598,14 +594,16 @@ int nilfs_delete_entry(struct nilfs_dir_entry *dir, struct page *page) + from = (char *)pde - (char *)page_address(page); + lock_page(page); + err = nilfs_prepare_chunk(page, from, to); +- BUG_ON(err); ++ if (unlikely(err)) { ++ unlock_page(page); ++ goto out; ++ } + if (pde) + pde->rec_len = nilfs_rec_len_to_disk(to - from); + dir->inode = 0; + nilfs_commit_chunk(page, mapping, from, to); + inode->i_mtime = inode_set_ctime_current(inode); + out: +- nilfs_put_page(page); + return err; + } + +diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c +index ac0adeb58e4104..43f01fe556fe17 100644 +--- a/fs/nilfs2/namei.c ++++ b/fs/nilfs2/namei.c +@@ -297,6 +297,7 @@ static int nilfs_do_unlink(struct inode *dir, struct dentry *dentry) + set_nlink(inode, 1); + } + err = nilfs_delete_entry(de, page); ++ nilfs_put_page(page); + if (err) + goto out; + +@@ -405,7 +406,10 @@ static int nilfs_rename(struct mnt_idmap *idmap, + err = PTR_ERR(new_de); + goto out_dir; + } +- nilfs_set_link(new_dir, new_de, new_page, old_inode); ++ err = nilfs_set_link(new_dir, new_de, new_page, old_inode); ++ nilfs_put_page(new_page); ++ if (unlikely(err)) ++ goto out_dir; + nilfs_mark_inode_dirty(new_dir); + inode_set_ctime_current(new_inode); + if (dir_de) +@@ -428,28 +432,27 @@ static int nilfs_rename(struct mnt_idmap *idmap, + */ + inode_set_ctime_current(old_inode); + +- nilfs_delete_entry(old_de, old_page); +- +- if (dir_de) { +- nilfs_set_link(old_inode, dir_de, dir_page, new_dir); +- drop_nlink(old_dir); ++ err = nilfs_delete_entry(old_de, old_page); ++ if (likely(!err)) { ++ if (dir_de) { ++ err = nilfs_set_link(old_inode, dir_de, dir_page, ++ new_dir); ++ drop_nlink(old_dir); ++ } ++ nilfs_mark_inode_dirty(old_dir); + } +- nilfs_mark_inode_dirty(old_dir); + nilfs_mark_inode_dirty(old_inode); + +- err = nilfs_transaction_commit(old_dir->i_sb); +- return err; +- + out_dir: +- if (dir_de) { +- kunmap(dir_page); +- put_page(dir_page); +- } ++ if (dir_de) ++ nilfs_put_page(dir_page); + out_old: +- kunmap(old_page); +- put_page(old_page); ++ nilfs_put_page(old_page); + out: +- nilfs_transaction_abort(old_dir->i_sb); ++ if (likely(!err)) ++ err = nilfs_transaction_commit(old_dir->i_sb); ++ else ++ nilfs_transaction_abort(old_dir->i_sb); + return err; + } + +diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h +index e2c5376b56cd8e..4c4b7686548434 100644 +--- a/fs/nilfs2/nilfs.h ++++ b/fs/nilfs2/nilfs.h +@@ -240,8 +240,14 @@ nilfs_find_entry(struct inode *, const struct qstr *, struct page **); + extern int nilfs_delete_entry(struct nilfs_dir_entry *, struct page *); + extern int nilfs_empty_dir(struct inode *); + extern struct nilfs_dir_entry *nilfs_dotdot(struct inode *, struct page **); +-extern void nilfs_set_link(struct inode *, struct nilfs_dir_entry *, +- struct page *, struct inode *); ++int nilfs_set_link(struct inode *dir, struct nilfs_dir_entry *de, ++ struct page *page, struct inode *inode); ++ ++static inline void nilfs_put_page(struct page *page) ++{ ++ kunmap(page); ++ put_page(page); ++} + + /* file.c */ + extern int nilfs_sync_file(struct file *, loff_t, loff_t, int); +diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c +index 8d3fa2a3b8a956..b809a616728f27 100644 +--- a/fs/smb/client/smb2ops.c ++++ b/fs/smb/client/smb2ops.c +@@ -4905,6 +4905,10 @@ receive_encrypted_standard(struct TCP_Server_Info *server, + next_buffer = (char *)cifs_buf_get(); + else + next_buffer = (char *)cifs_small_buf_get(); ++ if (!next_buffer) { ++ cifs_server_dbg(VFS, "No memory for (large) SMB response\n"); ++ return -1; ++ } + memcpy(next_buffer, buf + next_cmd, pdu_length - next_cmd); + } + +diff --git a/fs/xfs/libxfs/xfs_ag.c b/fs/xfs/libxfs/xfs_ag.c +index 1531bd0ee359c9..ea0e9492b37402 100644 +--- a/fs/xfs/libxfs/xfs_ag.c ++++ b/fs/xfs/libxfs/xfs_ag.c +@@ -357,31 +357,37 @@ xfs_free_unused_perag_range( + } + } + ++int ++xfs_update_last_ag_size( ++ struct xfs_mount *mp, ++ xfs_agnumber_t prev_agcount) ++{ ++ struct xfs_perag *pag = xfs_perag_grab(mp, prev_agcount - 1); ++ ++ if (!pag) ++ return -EFSCORRUPTED; ++ pag->block_count = __xfs_ag_block_count(mp, prev_agcount - 1, ++ mp->m_sb.sb_agcount, mp->m_sb.sb_dblocks); ++ __xfs_agino_range(mp, pag->block_count, &pag->agino_min, ++ &pag->agino_max); ++ xfs_perag_rele(pag); ++ return 0; ++} ++ + int + xfs_initialize_perag( + struct xfs_mount *mp, +- xfs_agnumber_t agcount, ++ xfs_agnumber_t old_agcount, ++ xfs_agnumber_t new_agcount, + xfs_rfsblock_t dblocks, + xfs_agnumber_t *maxagi) + { + struct xfs_perag *pag; + xfs_agnumber_t index; +- xfs_agnumber_t first_initialised = NULLAGNUMBER; + int error; + +- /* +- * Walk the current per-ag tree so we don't try to initialise AGs +- * that already exist (growfs case). Allocate and insert all the +- * AGs we don't find ready for initialisation. +- */ +- for (index = 0; index < agcount; index++) { +- pag = xfs_perag_get(mp, index); +- if (pag) { +- xfs_perag_put(pag); +- continue; +- } +- +- pag = kmem_zalloc(sizeof(*pag), KM_MAYFAIL); ++ for (index = old_agcount; index < new_agcount; index++) { ++ pag = kmem_zalloc(sizeof(*pag), 0); + if (!pag) { + error = -ENOMEM; + goto out_unwind_new_pags; +@@ -425,21 +431,17 @@ xfs_initialize_perag( + /* Active ref owned by mount indicates AG is online. */ + atomic_set(&pag->pag_active_ref, 1); + +- /* first new pag is fully initialized */ +- if (first_initialised == NULLAGNUMBER) +- first_initialised = index; +- + /* + * Pre-calculated geometry + */ +- pag->block_count = __xfs_ag_block_count(mp, index, agcount, ++ pag->block_count = __xfs_ag_block_count(mp, index, new_agcount, + dblocks); + pag->min_block = XFS_AGFL_BLOCK(mp); + __xfs_agino_range(mp, pag->block_count, &pag->agino_min, + &pag->agino_max); + } + +- index = xfs_set_inode_alloc(mp, agcount); ++ index = xfs_set_inode_alloc(mp, new_agcount); + + if (maxagi) + *maxagi = index; +@@ -455,8 +457,7 @@ xfs_initialize_perag( + out_free_pag: + kmem_free(pag); + out_unwind_new_pags: +- /* unwind any prior newly initialized pags */ +- xfs_free_unused_perag_range(mp, first_initialised, agcount); ++ xfs_free_unused_perag_range(mp, old_agcount, index); + return error; + } + +diff --git a/fs/xfs/libxfs/xfs_ag.h b/fs/xfs/libxfs/xfs_ag.h +index 40d7b6427afb5d..423c489fec5832 100644 +--- a/fs/xfs/libxfs/xfs_ag.h ++++ b/fs/xfs/libxfs/xfs_ag.h +@@ -135,10 +135,12 @@ __XFS_AG_OPSTATE(agfl_needs_reset, AGFL_NEEDS_RESET) + + void xfs_free_unused_perag_range(struct xfs_mount *mp, xfs_agnumber_t agstart, + xfs_agnumber_t agend); +-int xfs_initialize_perag(struct xfs_mount *mp, xfs_agnumber_t agcount, +- xfs_rfsblock_t dcount, xfs_agnumber_t *maxagi); ++int xfs_initialize_perag(struct xfs_mount *mp, xfs_agnumber_t old_agcount, ++ xfs_agnumber_t agcount, xfs_rfsblock_t dcount, ++ xfs_agnumber_t *maxagi); + int xfs_initialize_perag_data(struct xfs_mount *mp, xfs_agnumber_t agno); + void xfs_free_perag(struct xfs_mount *mp); ++int xfs_update_last_ag_size(struct xfs_mount *mp, xfs_agnumber_t prev_agcount); + + /* Passive AG references */ + struct xfs_perag *xfs_perag_get(struct xfs_mount *mp, xfs_agnumber_t agno); +diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c +index 100ab5931b3132..ad2fa3c26f8a94 100644 +--- a/fs/xfs/libxfs/xfs_alloc.c ++++ b/fs/xfs/libxfs/xfs_alloc.c +@@ -1783,7 +1783,7 @@ xfs_alloc_ag_vextent_size( + error = -EFSCORRUPTED; + goto error0; + } +- if (flen < bestrlen) ++ if (flen <= bestrlen) + break; + busy = xfs_alloc_compute_aligned(args, fbno, flen, + &rbno, &rlen, &busy_gen); +@@ -2581,7 +2581,6 @@ __xfs_free_extent_later( + return 0; + } + +-#ifdef DEBUG + /* + * Check if an AGF has a free extent record whose length is equal to + * args->minlen. +@@ -2620,7 +2619,6 @@ xfs_exact_minlen_extent_available( + + return error; + } +-#endif + + /* + * Decide whether to use this allocation group for this allocation. +@@ -2694,15 +2692,14 @@ xfs_alloc_fix_freelist( + if (!xfs_alloc_space_available(args, need, alloc_flags)) + goto out_agbp_relse; + +-#ifdef DEBUG +- if (args->alloc_minlen_only) { ++ if (IS_ENABLED(CONFIG_XFS_DEBUG) && args->alloc_minlen_only) { + int stat; + + error = xfs_exact_minlen_extent_available(args, agbp, &stat); + if (error || !stat) + goto out_agbp_relse; + } +-#endif ++ + /* + * Make the freelist shorter if it's too long. + * +diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h +index 6bb8d295c321d2..a12294cb83bbaf 100644 +--- a/fs/xfs/libxfs/xfs_alloc.h ++++ b/fs/xfs/libxfs/xfs_alloc.h +@@ -53,11 +53,9 @@ typedef struct xfs_alloc_arg { + int datatype; /* mask defining data type treatment */ + char wasdel; /* set if allocation was prev delayed */ + char wasfromfl; /* set if allocation is from freelist */ ++ bool alloc_minlen_only; /* allocate exact minlen extent */ + struct xfs_owner_info oinfo; /* owner of blocks being allocated */ + enum xfs_ag_resv_type resv; /* block reservation to use */ +-#ifdef DEBUG +- bool alloc_minlen_only; /* allocate exact minlen extent */ +-#endif + } xfs_alloc_arg_t; + + /* +diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c +index 33edf047e0ad2f..50172bb8026fd9 100644 +--- a/fs/xfs/libxfs/xfs_attr.c ++++ b/fs/xfs/libxfs/xfs_attr.c +@@ -50,7 +50,6 @@ STATIC int xfs_attr_shortform_addname(xfs_da_args_t *args); + STATIC int xfs_attr_leaf_get(xfs_da_args_t *args); + STATIC int xfs_attr_leaf_removename(xfs_da_args_t *args); + STATIC int xfs_attr_leaf_hasname(struct xfs_da_args *args, struct xfs_buf **bp); +-STATIC int xfs_attr_leaf_try_add(struct xfs_da_args *args); + + /* + * Internal routines when attribute list is more than one block. +@@ -401,6 +400,33 @@ xfs_attr_sf_addname( + return error; + } + ++/* Save the current remote block info and clear the current pointers. */ ++static void ++xfs_attr_save_rmt_blk( ++ struct xfs_da_args *args) ++{ ++ args->blkno2 = args->blkno; ++ args->index2 = args->index; ++ args->rmtblkno2 = args->rmtblkno; ++ args->rmtblkcnt2 = args->rmtblkcnt; ++ args->rmtvaluelen2 = args->rmtvaluelen; ++ args->rmtblkno = 0; ++ args->rmtblkcnt = 0; ++ args->rmtvaluelen = 0; ++} ++ ++/* Set stored info about a remote block */ ++static void ++xfs_attr_restore_rmt_blk( ++ struct xfs_da_args *args) ++{ ++ args->blkno = args->blkno2; ++ args->index = args->index2; ++ args->rmtblkno = args->rmtblkno2; ++ args->rmtblkcnt = args->rmtblkcnt2; ++ args->rmtvaluelen = args->rmtvaluelen2; ++} ++ + /* + * Handle the state change on completion of a multi-state attr operation. + * +@@ -428,48 +454,73 @@ xfs_attr_complete_op( + return XFS_DAS_DONE; + } + ++/* ++ * Try to add an attribute to an inode in leaf form. ++ */ + static int + xfs_attr_leaf_addname( + struct xfs_attr_intent *attr) + { + struct xfs_da_args *args = attr->xattri_da_args; ++ struct xfs_buf *bp; + int error; + + ASSERT(xfs_attr_is_leaf(args->dp)); + ++ error = xfs_attr3_leaf_read(args->trans, args->dp, 0, &bp); ++ if (error) ++ return error; ++ + /* +- * Use the leaf buffer we may already hold locked as a result of +- * a sf-to-leaf conversion. ++ * Look up the xattr name to set the insertion point for the new xattr. + */ +- error = xfs_attr_leaf_try_add(args); +- +- if (error == -ENOSPC) { +- error = xfs_attr3_leaf_to_node(args); +- if (error) +- return error; ++ error = xfs_attr3_leaf_lookup_int(bp, args); ++ switch (error) { ++ case -ENOATTR: ++ if (args->op_flags & XFS_DA_OP_REPLACE) ++ goto out_brelse; ++ break; ++ case -EEXIST: ++ if (!(args->op_flags & XFS_DA_OP_REPLACE)) ++ goto out_brelse; + ++ trace_xfs_attr_leaf_replace(args); + /* +- * We're not in leaf format anymore, so roll the transaction and +- * retry the add to the newly allocated node block. ++ * Save the existing remote attr state so that the current ++ * values reflect the state of the new attribute we are about to ++ * add, not the attribute we just found and will remove later. + */ +- attr->xattri_dela_state = XFS_DAS_NODE_ADD; +- goto out; ++ xfs_attr_save_rmt_blk(args); ++ break; ++ case 0: ++ break; ++ default: ++ goto out_brelse; + } +- if (error) +- return error; + + /* + * We need to commit and roll if we need to allocate remote xattr blocks + * or perform more xattr manipulations. Otherwise there is nothing more + * to do and we can return success. + */ +- if (args->rmtblkno) ++ if (!xfs_attr3_leaf_add(bp, args)) { ++ error = xfs_attr3_leaf_to_node(args); ++ if (error) ++ return error; ++ ++ attr->xattri_dela_state = XFS_DAS_NODE_ADD; ++ } else if (args->rmtblkno) { + attr->xattri_dela_state = XFS_DAS_LEAF_SET_RMT; +- else +- attr->xattri_dela_state = xfs_attr_complete_op(attr, +- XFS_DAS_LEAF_REPLACE); +-out: ++ } else { ++ attr->xattri_dela_state = ++ xfs_attr_complete_op(attr, XFS_DAS_LEAF_REPLACE); ++ } ++ + trace_xfs_attr_leaf_addname_return(attr->xattri_dela_state, args->dp); ++ return 0; ++ ++out_brelse: ++ xfs_trans_brelse(args->trans, bp); + return error; + } + +@@ -492,7 +543,7 @@ xfs_attr_node_addname( + return error; + + error = xfs_attr_node_try_addname(attr); +- if (error == -ENOSPC) { ++ if (error == 1) { + error = xfs_attr3_leaf_to_node(args); + if (error) + return error; +@@ -1164,88 +1215,6 @@ xfs_attr_shortform_addname( + * External routines when attribute list is one block + *========================================================================*/ + +-/* Save the current remote block info and clear the current pointers. */ +-static void +-xfs_attr_save_rmt_blk( +- struct xfs_da_args *args) +-{ +- args->blkno2 = args->blkno; +- args->index2 = args->index; +- args->rmtblkno2 = args->rmtblkno; +- args->rmtblkcnt2 = args->rmtblkcnt; +- args->rmtvaluelen2 = args->rmtvaluelen; +- args->rmtblkno = 0; +- args->rmtblkcnt = 0; +- args->rmtvaluelen = 0; +-} +- +-/* Set stored info about a remote block */ +-static void +-xfs_attr_restore_rmt_blk( +- struct xfs_da_args *args) +-{ +- args->blkno = args->blkno2; +- args->index = args->index2; +- args->rmtblkno = args->rmtblkno2; +- args->rmtblkcnt = args->rmtblkcnt2; +- args->rmtvaluelen = args->rmtvaluelen2; +-} +- +-/* +- * Tries to add an attribute to an inode in leaf form +- * +- * This function is meant to execute as part of a delayed operation and leaves +- * the transaction handling to the caller. On success the attribute is added +- * and the inode and transaction are left dirty. If there is not enough space, +- * the attr data is converted to node format and -ENOSPC is returned. Caller is +- * responsible for handling the dirty inode and transaction or adding the attr +- * in node format. +- */ +-STATIC int +-xfs_attr_leaf_try_add( +- struct xfs_da_args *args) +-{ +- struct xfs_buf *bp; +- int error; +- +- error = xfs_attr3_leaf_read(args->trans, args->dp, 0, &bp); +- if (error) +- return error; +- +- /* +- * Look up the xattr name to set the insertion point for the new xattr. +- */ +- error = xfs_attr3_leaf_lookup_int(bp, args); +- switch (error) { +- case -ENOATTR: +- if (args->op_flags & XFS_DA_OP_REPLACE) +- goto out_brelse; +- break; +- case -EEXIST: +- if (!(args->op_flags & XFS_DA_OP_REPLACE)) +- goto out_brelse; +- +- trace_xfs_attr_leaf_replace(args); +- /* +- * Save the existing remote attr state so that the current +- * values reflect the state of the new attribute we are about to +- * add, not the attribute we just found and will remove later. +- */ +- xfs_attr_save_rmt_blk(args); +- break; +- case 0: +- break; +- default: +- goto out_brelse; +- } +- +- return xfs_attr3_leaf_add(bp, args); +- +-out_brelse: +- xfs_trans_brelse(args->trans, bp); +- return error; +-} +- + /* + * Return EEXIST if attr is found, or ENOATTR if not + */ +@@ -1411,9 +1380,12 @@ xfs_attr_node_addname_find_attr( + /* + * Add a name to a Btree-format attribute list. + * +- * This will involve walking down the Btree, and may involve splitting +- * leaf nodes and even splitting intermediate nodes up to and including +- * the root node (a special case of an intermediate node). ++ * This will involve walking down the Btree, and may involve splitting leaf ++ * nodes and even splitting intermediate nodes up to and including the root ++ * node (a special case of an intermediate node). ++ * ++ * If the tree was still in single leaf format and needs to converted to ++ * real node format return 1 and let the caller handle that. + */ + static int + xfs_attr_node_try_addname( +@@ -1421,21 +1393,21 @@ xfs_attr_node_try_addname( + { + struct xfs_da_state *state = attr->xattri_da_state; + struct xfs_da_state_blk *blk; +- int error; ++ int error = 0; + + trace_xfs_attr_node_addname(state->args); + + blk = &state->path.blk[state->path.active-1]; + ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC); + +- error = xfs_attr3_leaf_add(blk->bp, state->args); +- if (error == -ENOSPC) { ++ if (!xfs_attr3_leaf_add(blk->bp, state->args)) { + if (state->path.active == 1) { + /* + * Its really a single leaf node, but it had + * out-of-line values so it looked like it *might* + * have been a b-tree. Let the caller deal with this. + */ ++ error = 1; + goto out; + } + +diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c +index 51ff4406867539..4e5ede2a296a58 100644 +--- a/fs/xfs/libxfs/xfs_attr_leaf.c ++++ b/fs/xfs/libxfs/xfs_attr_leaf.c +@@ -46,7 +46,7 @@ + */ + STATIC int xfs_attr3_leaf_create(struct xfs_da_args *args, + xfs_dablk_t which_block, struct xfs_buf **bpp); +-STATIC int xfs_attr3_leaf_add_work(struct xfs_buf *leaf_buffer, ++STATIC void xfs_attr3_leaf_add_work(struct xfs_buf *leaf_buffer, + struct xfs_attr3_icleaf_hdr *ichdr, + struct xfs_da_args *args, int freemap_index); + STATIC void xfs_attr3_leaf_compact(struct xfs_da_args *args, +@@ -990,10 +990,8 @@ xfs_attr_shortform_to_leaf( + } + error = xfs_attr3_leaf_lookup_int(bp, &nargs); /* set a->index */ + ASSERT(error == -ENOATTR); +- error = xfs_attr3_leaf_add(bp, &nargs); +- ASSERT(error != -ENOSPC); +- if (error) +- goto out; ++ if (!xfs_attr3_leaf_add(bp, &nargs)) ++ ASSERT(0); + sfe = xfs_attr_sf_nextentry(sfe); + } + error = 0; +@@ -1342,6 +1340,9 @@ xfs_attr3_leaf_create( + + /* + * Split the leaf node, rebalance, then add the new entry. ++ * ++ * Returns 0 if the entry was added, 1 if a further split is needed or a ++ * negative error number otherwise. + */ + int + xfs_attr3_leaf_split( +@@ -1349,8 +1350,9 @@ xfs_attr3_leaf_split( + struct xfs_da_state_blk *oldblk, + struct xfs_da_state_blk *newblk) + { +- xfs_dablk_t blkno; +- int error; ++ bool added; ++ xfs_dablk_t blkno; ++ int error; + + trace_xfs_attr_leaf_split(state->args); + +@@ -1385,10 +1387,10 @@ xfs_attr3_leaf_split( + */ + if (state->inleaf) { + trace_xfs_attr_leaf_add_old(state->args); +- error = xfs_attr3_leaf_add(oldblk->bp, state->args); ++ added = xfs_attr3_leaf_add(oldblk->bp, state->args); + } else { + trace_xfs_attr_leaf_add_new(state->args); +- error = xfs_attr3_leaf_add(newblk->bp, state->args); ++ added = xfs_attr3_leaf_add(newblk->bp, state->args); + } + + /* +@@ -1396,13 +1398,15 @@ xfs_attr3_leaf_split( + */ + oldblk->hashval = xfs_attr_leaf_lasthash(oldblk->bp, NULL); + newblk->hashval = xfs_attr_leaf_lasthash(newblk->bp, NULL); +- return error; ++ if (!added) ++ return 1; ++ return 0; + } + + /* + * Add a name to the leaf attribute list structure. + */ +-int ++bool + xfs_attr3_leaf_add( + struct xfs_buf *bp, + struct xfs_da_args *args) +@@ -1411,6 +1415,7 @@ xfs_attr3_leaf_add( + struct xfs_attr3_icleaf_hdr ichdr; + int tablesize; + int entsize; ++ bool added = true; + int sum; + int tmp; + int i; +@@ -1439,7 +1444,7 @@ xfs_attr3_leaf_add( + if (ichdr.freemap[i].base < ichdr.firstused) + tmp += sizeof(xfs_attr_leaf_entry_t); + if (ichdr.freemap[i].size >= tmp) { +- tmp = xfs_attr3_leaf_add_work(bp, &ichdr, args, i); ++ xfs_attr3_leaf_add_work(bp, &ichdr, args, i); + goto out_log_hdr; + } + sum += ichdr.freemap[i].size; +@@ -1451,7 +1456,7 @@ xfs_attr3_leaf_add( + * no good and we should just give up. + */ + if (!ichdr.holes && sum < entsize) +- return -ENOSPC; ++ return false; + + /* + * Compact the entries to coalesce free space. +@@ -1464,24 +1469,24 @@ xfs_attr3_leaf_add( + * free region, in freemap[0]. If it is not big enough, give up. + */ + if (ichdr.freemap[0].size < (entsize + sizeof(xfs_attr_leaf_entry_t))) { +- tmp = -ENOSPC; ++ added = false; + goto out_log_hdr; + } + +- tmp = xfs_attr3_leaf_add_work(bp, &ichdr, args, 0); ++ xfs_attr3_leaf_add_work(bp, &ichdr, args, 0); + + out_log_hdr: + xfs_attr3_leaf_hdr_to_disk(args->geo, leaf, &ichdr); + xfs_trans_log_buf(args->trans, bp, + XFS_DA_LOGRANGE(leaf, &leaf->hdr, + xfs_attr3_leaf_hdr_size(leaf))); +- return tmp; ++ return added; + } + + /* + * Add a name to a leaf attribute list structure. + */ +-STATIC int ++STATIC void + xfs_attr3_leaf_add_work( + struct xfs_buf *bp, + struct xfs_attr3_icleaf_hdr *ichdr, +@@ -1599,7 +1604,6 @@ xfs_attr3_leaf_add_work( + } + } + ichdr->usedbytes += xfs_attr_leaf_entsize(leaf, args->index); +- return 0; + } + + /* +diff --git a/fs/xfs/libxfs/xfs_attr_leaf.h b/fs/xfs/libxfs/xfs_attr_leaf.h +index 368f4d9fa1d596..d15cc5b6f4a943 100644 +--- a/fs/xfs/libxfs/xfs_attr_leaf.h ++++ b/fs/xfs/libxfs/xfs_attr_leaf.h +@@ -78,7 +78,7 @@ int xfs_attr3_leaf_split(struct xfs_da_state *state, + int xfs_attr3_leaf_lookup_int(struct xfs_buf *leaf, + struct xfs_da_args *args); + int xfs_attr3_leaf_getvalue(struct xfs_buf *bp, struct xfs_da_args *args); +-int xfs_attr3_leaf_add(struct xfs_buf *leaf_buffer, ++bool xfs_attr3_leaf_add(struct xfs_buf *leaf_buffer, + struct xfs_da_args *args); + int xfs_attr3_leaf_remove(struct xfs_buf *leaf_buffer, + struct xfs_da_args *args); +diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c +index e6ea35098e07f8..c111f691ea51a1 100644 +--- a/fs/xfs/libxfs/xfs_bmap.c ++++ b/fs/xfs/libxfs/xfs_bmap.c +@@ -3388,31 +3388,19 @@ xfs_bmap_process_allocated_extent( + xfs_bmap_btalloc_accounting(ap, args); + } + +-#ifdef DEBUG + static int + xfs_bmap_exact_minlen_extent_alloc( +- struct xfs_bmalloca *ap) ++ struct xfs_bmalloca *ap, ++ struct xfs_alloc_arg *args) + { +- struct xfs_mount *mp = ap->ip->i_mount; +- struct xfs_alloc_arg args = { .tp = ap->tp, .mp = mp }; +- xfs_fileoff_t orig_offset; +- xfs_extlen_t orig_length; +- int error; +- +- ASSERT(ap->length); +- + if (ap->minlen != 1) { +- ap->blkno = NULLFSBLOCK; +- ap->length = 0; ++ args->fsbno = NULLFSBLOCK; + return 0; + } + +- orig_offset = ap->offset; +- orig_length = ap->length; +- +- args.alloc_minlen_only = 1; +- +- xfs_bmap_compute_alignments(ap, &args); ++ args->alloc_minlen_only = 1; ++ args->minlen = args->maxlen = ap->minlen; ++ args->total = ap->total; + + /* + * Unlike the longest extent available in an AG, we don't track +@@ -3422,39 +3410,16 @@ xfs_bmap_exact_minlen_extent_alloc( + * we need not be concerned about a drop in performance in + * "debug only" code paths. + */ +- ap->blkno = XFS_AGB_TO_FSB(mp, 0, 0); ++ ap->blkno = XFS_AGB_TO_FSB(ap->ip->i_mount, 0, 0); + +- args.oinfo = XFS_RMAP_OINFO_SKIP_UPDATE; +- args.minlen = args.maxlen = ap->minlen; +- args.total = ap->total; +- +- args.alignment = 1; +- args.minalignslop = 0; +- +- args.minleft = ap->minleft; +- args.wasdel = ap->wasdel; +- args.resv = XFS_AG_RESV_NONE; +- args.datatype = ap->datatype; +- +- error = xfs_alloc_vextent_first_ag(&args, ap->blkno); +- if (error) +- return error; +- +- if (args.fsbno != NULLFSBLOCK) { +- xfs_bmap_process_allocated_extent(ap, &args, orig_offset, +- orig_length); +- } else { +- ap->blkno = NULLFSBLOCK; +- ap->length = 0; +- } +- +- return 0; ++ /* ++ * Call xfs_bmap_btalloc_low_space here as it first does a "normal" AG ++ * iteration and then drops args->total to args->minlen, which might be ++ * required to find an allocation for the transaction reservation when ++ * the file system is very full. ++ */ ++ return xfs_bmap_btalloc_low_space(ap, args); + } +-#else +- +-#define xfs_bmap_exact_minlen_extent_alloc(bma) (-EFSCORRUPTED) +- +-#endif + + /* + * If we are not low on available data blocks and we are allocating at +@@ -3712,8 +3677,11 @@ xfs_bmap_btalloc( + /* Trim the allocation back to the maximum an AG can fit. */ + args.maxlen = min(ap->length, mp->m_ag_max_usable); + +- if ((ap->datatype & XFS_ALLOC_USERDATA) && +- xfs_inode_is_filestream(ap->ip)) ++ if (unlikely(XFS_TEST_ERROR(false, mp, ++ XFS_ERRTAG_BMAP_ALLOC_MINLEN_EXTENT))) ++ error = xfs_bmap_exact_minlen_extent_alloc(ap, &args); ++ else if ((ap->datatype & XFS_ALLOC_USERDATA) && ++ xfs_inode_is_filestream(ap->ip)) + error = xfs_bmap_btalloc_filestreams(ap, &args, stripe_align); + else + error = xfs_bmap_btalloc_best_length(ap, &args, stripe_align); +@@ -4077,43 +4045,6 @@ xfs_bmapi_reserve_delalloc( + return error; + } + +-static int +-xfs_bmap_alloc_userdata( +- struct xfs_bmalloca *bma) +-{ +- struct xfs_mount *mp = bma->ip->i_mount; +- int whichfork = xfs_bmapi_whichfork(bma->flags); +- int error; +- +- /* +- * Set the data type being allocated. For the data fork, the first data +- * in the file is treated differently to all other allocations. For the +- * attribute fork, we only need to ensure the allocated range is not on +- * the busy list. +- */ +- bma->datatype = XFS_ALLOC_NOBUSY; +- if (whichfork == XFS_DATA_FORK || whichfork == XFS_COW_FORK) { +- bma->datatype |= XFS_ALLOC_USERDATA; +- if (bma->offset == 0) +- bma->datatype |= XFS_ALLOC_INITIAL_USER_DATA; +- +- if (mp->m_dalign && bma->length >= mp->m_dalign) { +- error = xfs_bmap_isaeof(bma, whichfork); +- if (error) +- return error; +- } +- +- if (XFS_IS_REALTIME_INODE(bma->ip)) +- return xfs_bmap_rtalloc(bma); +- } +- +- if (unlikely(XFS_TEST_ERROR(false, mp, +- XFS_ERRTAG_BMAP_ALLOC_MINLEN_EXTENT))) +- return xfs_bmap_exact_minlen_extent_alloc(bma); +- +- return xfs_bmap_btalloc(bma); +-} +- + static int + xfs_bmapi_allocate( + struct xfs_bmalloca *bma) +@@ -4147,15 +4078,32 @@ xfs_bmapi_allocate( + else + bma->minlen = 1; + +- if (bma->flags & XFS_BMAPI_METADATA) { +- if (unlikely(XFS_TEST_ERROR(false, mp, +- XFS_ERRTAG_BMAP_ALLOC_MINLEN_EXTENT))) +- error = xfs_bmap_exact_minlen_extent_alloc(bma); +- else +- error = xfs_bmap_btalloc(bma); +- } else { +- error = xfs_bmap_alloc_userdata(bma); ++ if (!(bma->flags & XFS_BMAPI_METADATA)) { ++ /* ++ * For the data and COW fork, the first data in the file is ++ * treated differently to all other allocations. For the ++ * attribute fork, we only need to ensure the allocated range ++ * is not on the busy list. ++ */ ++ bma->datatype = XFS_ALLOC_NOBUSY; ++ if (whichfork == XFS_DATA_FORK || whichfork == XFS_COW_FORK) { ++ bma->datatype |= XFS_ALLOC_USERDATA; ++ if (bma->offset == 0) ++ bma->datatype |= XFS_ALLOC_INITIAL_USER_DATA; ++ ++ if (mp->m_dalign && bma->length >= mp->m_dalign) { ++ error = xfs_bmap_isaeof(bma, whichfork); ++ if (error) ++ return error; ++ } ++ } + } ++ ++ if ((bma->datatype & XFS_ALLOC_USERDATA) && ++ XFS_IS_REALTIME_INODE(bma->ip)) ++ error = xfs_bmap_rtalloc(bma); ++ else ++ error = xfs_bmap_btalloc(bma); + if (error) + return error; + if (bma->blkno == NULLFSBLOCK) +diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c +index 12e3cca804b7ec..28bbfc31039c0e 100644 +--- a/fs/xfs/libxfs/xfs_da_btree.c ++++ b/fs/xfs/libxfs/xfs_da_btree.c +@@ -522,9 +522,8 @@ xfs_da3_split( + switch (oldblk->magic) { + case XFS_ATTR_LEAF_MAGIC: + error = xfs_attr3_leaf_split(state, oldblk, newblk); +- if ((error != 0) && (error != -ENOSPC)) { ++ if (error < 0) + return error; /* GROT: attr is inconsistent */ +- } + if (!error) { + addblk = newblk; + break; +@@ -546,6 +545,8 @@ xfs_da3_split( + error = xfs_attr3_leaf_split(state, newblk, + &state->extrablk); + } ++ if (error == 1) ++ return -ENOSPC; + if (error) + return error; /* GROT: attr inconsistent */ + addblk = newblk; +diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c +index 5a2e7ddfa76d63..25b86ffc2ce327 100644 +--- a/fs/xfs/libxfs/xfs_inode_fork.c ++++ b/fs/xfs/libxfs/xfs_inode_fork.c +@@ -449,15 +449,15 @@ xfs_iroot_realloc( + } + + /* +- * Only copy the records and pointers if there are any. ++ * Only copy the keys and pointers if there are any. + */ + if (new_max > 0) { + /* +- * First copy the records. ++ * First copy the keys. + */ +- op = (char *)XFS_BMBT_REC_ADDR(mp, ifp->if_broot, 1); +- np = (char *)XFS_BMBT_REC_ADDR(mp, new_broot, 1); +- memcpy(np, op, new_max * (uint)sizeof(xfs_bmbt_rec_t)); ++ op = (char *)XFS_BMBT_KEY_ADDR(mp, ifp->if_broot, 1); ++ np = (char *)XFS_BMBT_KEY_ADDR(mp, new_broot, 1); ++ memcpy(np, op, new_max * (uint)sizeof(xfs_bmbt_key_t)); + + /* + * Then copy the pointers. +diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c +index 760172a65aff31..d7d06dc89eb7e3 100644 +--- a/fs/xfs/libxfs/xfs_rtbitmap.c ++++ b/fs/xfs/libxfs/xfs_rtbitmap.c +@@ -288,6 +288,8 @@ xfs_rtfind_forw( + xfs_rtword_t wdiff; /* difference from wanted value */ + int word; /* word number in the buffer */ + ++ ASSERT(start <= limit); ++ + /* + * Compute and read in starting bitmap block for starting block. + */ +diff --git a/fs/xfs/xfs_buf_item_recover.c b/fs/xfs/xfs_buf_item_recover.c +index 43167f543afc33..c12dee0cb7fc96 100644 +--- a/fs/xfs/xfs_buf_item_recover.c ++++ b/fs/xfs/xfs_buf_item_recover.c +@@ -22,6 +22,9 @@ + #include "xfs_inode.h" + #include "xfs_dir2.h" + #include "xfs_quota.h" ++#include "xfs_alloc.h" ++#include "xfs_ag.h" ++#include "xfs_sb.h" + + /* + * This is the number of entries in the l_buf_cancel_table used during +@@ -684,6 +687,67 @@ xlog_recover_do_inode_buffer( + return 0; + } + ++/* ++ * Update the in-memory superblock and perag structures from the primary SB ++ * buffer. ++ * ++ * This is required because transactions running after growfs may require the ++ * updated values to be set in a previous fully commit transaction. ++ */ ++static int ++xlog_recover_do_primary_sb_buffer( ++ struct xfs_mount *mp, ++ struct xlog_recover_item *item, ++ struct xfs_buf *bp, ++ struct xfs_buf_log_format *buf_f, ++ xfs_lsn_t current_lsn) ++{ ++ struct xfs_dsb *dsb = bp->b_addr; ++ xfs_agnumber_t orig_agcount = mp->m_sb.sb_agcount; ++ int error; ++ ++ xlog_recover_do_reg_buffer(mp, item, bp, buf_f, current_lsn); ++ ++ if (orig_agcount == 0) { ++ xfs_alert(mp, "Trying to grow file system without AGs"); ++ return -EFSCORRUPTED; ++ } ++ ++ /* ++ * Update the in-core super block from the freshly recovered on-disk one. ++ */ ++ xfs_sb_from_disk(&mp->m_sb, dsb); ++ ++ if (mp->m_sb.sb_agcount < orig_agcount) { ++ xfs_alert(mp, "Shrinking AG count in log recovery not supported"); ++ return -EFSCORRUPTED; ++ } ++ ++ /* ++ * Growfs can also grow the last existing AG. In this case we also need ++ * to update the length in the in-core perag structure and values ++ * depending on it. ++ */ ++ error = xfs_update_last_ag_size(mp, orig_agcount); ++ if (error) ++ return error; ++ ++ /* ++ * Initialize the new perags, and also update various block and inode ++ * allocator setting based off the number of AGs or total blocks. ++ * Because of the latter this also needs to happen if the agcount did ++ * not change. ++ */ ++ error = xfs_initialize_perag(mp, orig_agcount, mp->m_sb.sb_agcount, ++ mp->m_sb.sb_dblocks, &mp->m_maxagi); ++ if (error) { ++ xfs_warn(mp, "Failed recovery per-ag init: %d", error); ++ return error; ++ } ++ mp->m_alloc_set_aside = xfs_alloc_set_aside(mp); ++ return 0; ++} ++ + /* + * V5 filesystems know the age of the buffer on disk being recovered. We can + * have newer objects on disk than we are replaying, and so for these cases we +@@ -967,6 +1031,12 @@ xlog_recover_buf_commit_pass2( + dirty = xlog_recover_do_dquot_buffer(mp, log, item, bp, buf_f); + if (!dirty) + goto out_release; ++ } else if ((xfs_blft_from_flags(buf_f) & XFS_BLFT_SB_BUF) && ++ xfs_buf_daddr(bp) == 0) { ++ error = xlog_recover_do_primary_sb_buffer(mp, item, bp, buf_f, ++ current_lsn); ++ if (error) ++ goto out_release; + } else { + xlog_recover_do_reg_buffer(mp, item, bp, buf_f, current_lsn); + } +diff --git a/fs/xfs/xfs_filestream.c b/fs/xfs/xfs_filestream.c +index f62b023f274e96..4e1e8356121851 100644 +--- a/fs/xfs/xfs_filestream.c ++++ b/fs/xfs/xfs_filestream.c +@@ -67,22 +67,28 @@ xfs_filestream_pick_ag( + xfs_extlen_t minfree, maxfree = 0; + xfs_agnumber_t agno; + bool first_pass = true; +- int err; + + /* 2% of an AG's blocks must be free for it to be chosen. */ + minfree = mp->m_sb.sb_agblocks / 50; + + restart: + for_each_perag_wrap(mp, start_agno, agno, pag) { ++ int err; ++ + trace_xfs_filestream_scan(pag, pino); ++ + *longest = 0; + err = xfs_bmap_longest_free_extent(pag, NULL, longest); + if (err) { +- if (err != -EAGAIN) +- break; +- /* Couldn't lock the AGF, skip this AG. */ +- err = 0; +- continue; ++ if (err == -EAGAIN) { ++ /* Couldn't lock the AGF, skip this AG. */ ++ err = 0; ++ continue; ++ } ++ xfs_perag_rele(pag); ++ if (max_pag) ++ xfs_perag_rele(max_pag); ++ return err; + } + + /* Keep track of the AG with the most free blocks. */ +@@ -107,7 +113,9 @@ xfs_filestream_pick_ag( + !(flags & XFS_PICK_USERDATA) || + (flags & XFS_PICK_LOWSPACE))) { + /* Break out, retaining the reference on the AG. */ +- break; ++ if (max_pag) ++ xfs_perag_rele(max_pag); ++ goto done; + } + } + +@@ -115,56 +123,44 @@ xfs_filestream_pick_ag( + atomic_dec(&pag->pagf_fstrms); + } + +- if (err) { +- xfs_perag_rele(pag); +- if (max_pag) +- xfs_perag_rele(max_pag); +- return err; ++ /* ++ * Allow a second pass to give xfs_bmap_longest_free_extent() another ++ * attempt at locking AGFs that it might have skipped over before we ++ * fail. ++ */ ++ if (first_pass) { ++ first_pass = false; ++ goto restart; + } + +- if (!pag) { +- /* +- * Allow a second pass to give xfs_bmap_longest_free_extent() +- * another attempt at locking AGFs that it might have skipped +- * over before we fail. +- */ +- if (first_pass) { +- first_pass = false; +- goto restart; +- } +- +- /* +- * We must be low on data space, so run a final lowspace +- * optimised selection pass if we haven't already. +- */ +- if (!(flags & XFS_PICK_LOWSPACE)) { +- flags |= XFS_PICK_LOWSPACE; +- goto restart; +- } +- +- /* +- * No unassociated AGs are available, so select the AG with the +- * most free space, regardless of whether it's already in use by +- * another filestream. It none suit, just use whatever AG we can +- * grab. +- */ +- if (!max_pag) { +- for_each_perag_wrap(args->mp, 0, start_agno, pag) { +- max_pag = pag; +- break; +- } ++ /* ++ * We must be low on data space, so run a final lowspace optimised ++ * selection pass if we haven't already. ++ */ ++ if (!(flags & XFS_PICK_LOWSPACE)) { ++ flags |= XFS_PICK_LOWSPACE; ++ goto restart; ++ } + +- /* Bail if there are no AGs at all to select from. */ +- if (!max_pag) +- return -ENOSPC; ++ /* ++ * No unassociated AGs are available, so select the AG with the most ++ * free space, regardless of whether it's already in use by another ++ * filestream. It none suit, just use whatever AG we can grab. ++ */ ++ if (!max_pag) { ++ for_each_perag_wrap(args->mp, 0, start_agno, pag) { ++ max_pag = pag; ++ break; + } + +- pag = max_pag; +- atomic_inc(&pag->pagf_fstrms); +- } else if (max_pag) { +- xfs_perag_rele(max_pag); ++ /* Bail if there are no AGs at all to select from. */ ++ if (!max_pag) ++ return -ENOSPC; + } + ++ pag = max_pag; ++ atomic_inc(&pag->pagf_fstrms); ++done: + trace_xfs_filestream_pick(pag, pino); + args->pag = pag; + return 0; +diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c +index c3f0e3cae87e56..a2c1eab5fa4af8 100644 +--- a/fs/xfs/xfs_fsops.c ++++ b/fs/xfs/xfs_fsops.c +@@ -87,6 +87,7 @@ xfs_growfs_data_private( + struct xfs_mount *mp, /* mount point for filesystem */ + struct xfs_growfs_data *in) /* growfs data input struct */ + { ++ xfs_agnumber_t oagcount = mp->m_sb.sb_agcount; + struct xfs_buf *bp; + int error; + xfs_agnumber_t nagcount; +@@ -94,7 +95,6 @@ xfs_growfs_data_private( + xfs_rfsblock_t nb, nb_div, nb_mod; + int64_t delta; + bool lastag_extended = false; +- xfs_agnumber_t oagcount; + struct xfs_trans *tp; + struct aghdr_init_data id = {}; + struct xfs_perag *last_pag; +@@ -138,16 +138,14 @@ xfs_growfs_data_private( + if (delta == 0) + return 0; + +- oagcount = mp->m_sb.sb_agcount; +- /* allocate the new per-ag structures */ +- if (nagcount > oagcount) { +- error = xfs_initialize_perag(mp, nagcount, nb, &nagimax); +- if (error) +- return error; +- } else if (nagcount < oagcount) { +- /* TODO: shrinking the entire AGs hasn't yet completed */ ++ /* TODO: shrinking the entire AGs hasn't yet completed */ ++ if (nagcount < oagcount) + return -EINVAL; +- } ++ ++ /* allocate the new per-ag structures */ ++ error = xfs_initialize_perag(mp, oagcount, nagcount, nb, &nagimax); ++ if (error) ++ return error; + + if (delta > 0) + error = xfs_trans_alloc(mp, &M_RES(mp)->tr_growdata, +diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c +index 57a9f23175250a..c54a7c60e06332 100644 +--- a/fs/xfs/xfs_icache.c ++++ b/fs/xfs/xfs_icache.c +@@ -748,7 +748,7 @@ xfs_iget( + ASSERT((lock_flags & (XFS_IOLOCK_EXCL | XFS_IOLOCK_SHARED)) == 0); + + /* reject inode numbers outside existing AGs */ +- if (!ino || XFS_INO_TO_AGNO(mp, ino) >= mp->m_sb.sb_agcount) ++ if (!xfs_verify_ino(mp, ino)) + return -EINVAL; + + XFS_STATS_INC(mp, xs_ig_attempts); +@@ -1234,14 +1234,17 @@ xfs_inode_clear_eofblocks_tag( + } + + /* +- * Set ourselves up to free CoW blocks from this file. If it's already clean +- * then we can bail out quickly, but otherwise we must back off if the file +- * is undergoing some kind of write. ++ * Prepare to free COW fork blocks from an inode. + */ + static bool + xfs_prep_free_cowblocks( +- struct xfs_inode *ip) ++ struct xfs_inode *ip, ++ struct xfs_icwalk *icw) + { ++ bool sync; ++ ++ sync = icw && (icw->icw_flags & XFS_ICWALK_FLAG_SYNC); ++ + /* + * Just clear the tag if we have an empty cow fork or none at all. It's + * possible the inode was fully unshared since it was originally tagged. +@@ -1253,16 +1256,22 @@ xfs_prep_free_cowblocks( + } + + /* +- * If the mapping is dirty or under writeback we cannot touch the +- * CoW fork. Leave it alone if we're in the midst of a directio. ++ * A cowblocks trim of an inode can have a significant effect on ++ * fragmentation even when a reasonable COW extent size hint is set. ++ * Therefore, we prefer to not process cowblocks unless they are clean ++ * and idle. We can never process a cowblocks inode that is dirty or has ++ * in-flight I/O under any circumstances, because outstanding writeback ++ * or dio expects targeted COW fork blocks exist through write ++ * completion where they can be remapped into the data fork. ++ * ++ * Therefore, the heuristic used here is to never process inodes ++ * currently opened for write from background (i.e. non-sync) scans. For ++ * sync scans, use the pagecache/dio state of the inode to ensure we ++ * never free COW fork blocks out from under pending I/O. + */ +- if ((VFS_I(ip)->i_state & I_DIRTY_PAGES) || +- mapping_tagged(VFS_I(ip)->i_mapping, PAGECACHE_TAG_DIRTY) || +- mapping_tagged(VFS_I(ip)->i_mapping, PAGECACHE_TAG_WRITEBACK) || +- atomic_read(&VFS_I(ip)->i_dio_count)) ++ if (!sync && inode_is_open_for_write(VFS_I(ip))) + return false; +- +- return true; ++ return xfs_can_free_cowblocks(ip); + } + + /* +@@ -1291,7 +1300,7 @@ xfs_inode_free_cowblocks( + if (!xfs_iflags_test(ip, XFS_ICOWBLOCKS)) + return 0; + +- if (!xfs_prep_free_cowblocks(ip)) ++ if (!xfs_prep_free_cowblocks(ip, icw)) + return 0; + + if (!xfs_icwalk_match(ip, icw)) +@@ -1320,7 +1329,7 @@ xfs_inode_free_cowblocks( + * Check again, nobody else should be able to dirty blocks or change + * the reflink iflag now that we have the first two locks held. + */ +- if (xfs_prep_free_cowblocks(ip)) ++ if (xfs_prep_free_cowblocks(ip, icw)) + ret = xfs_reflink_cancel_cow_range(ip, 0, NULLFILEOFF, false); + return ret; + } +diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c +index b9784348ebc5c4..e1adad91dba666 100644 +--- a/fs/xfs/xfs_inode.c ++++ b/fs/xfs/xfs_inode.c +@@ -1758,7 +1758,7 @@ xfs_inactive( + + if (S_ISREG(VFS_I(ip)->i_mode) && + (ip->i_disk_size != 0 || XFS_ISIZE(ip) != 0 || +- ip->i_df.if_nextents > 0 || ip->i_delayed_blks > 0)) ++ xfs_inode_has_filedata(ip))) + truncate = 1; + + if (xfs_iflags_test(ip, XFS_IQUOTAUNCHECKED)) { +diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h +index 0f2999b84e7d96..4820c4699f7d0f 100644 +--- a/fs/xfs/xfs_inode.h ++++ b/fs/xfs/xfs_inode.h +@@ -286,6 +286,11 @@ static inline bool xfs_is_metadata_inode(struct xfs_inode *ip) + xfs_is_quota_inode(&mp->m_sb, ip->i_ino); + } + ++static inline bool xfs_inode_has_filedata(const struct xfs_inode *ip) ++{ ++ return ip->i_df.if_nextents > 0 || ip->i_delayed_blks > 0; ++} ++ + /* + * Check if an inode has any data in the COW fork. This might be often false + * even for inodes with the reflink flag when there is no pending COW operation. +diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c +index 32e718043e0e2e..d22285a7453940 100644 +--- a/fs/xfs/xfs_ioctl.c ++++ b/fs/xfs/xfs_ioctl.c +@@ -1126,7 +1126,7 @@ xfs_ioctl_setattr_xflags( + + if (rtflag != XFS_IS_REALTIME_INODE(ip)) { + /* Can't change realtime flag if any extents are allocated. */ +- if (ip->i_df.if_nextents || ip->i_delayed_blks) ++ if (xfs_inode_has_filedata(ip)) + return -EINVAL; + + /* +@@ -1247,7 +1247,7 @@ xfs_ioctl_setattr_check_extsize( + if (!fa->fsx_valid) + return 0; + +- if (S_ISREG(VFS_I(ip)->i_mode) && ip->i_df.if_nextents && ++ if (S_ISREG(VFS_I(ip)->i_mode) && xfs_inode_has_filedata(ip) && + XFS_FSB_TO_B(mp, ip->i_extsize) != fa->fsx_extsize) + return -EINVAL; + +diff --git a/fs/xfs/xfs_log.h b/fs/xfs/xfs_log.h +index 2728886c296390..8e0f52599d8db5 100644 +--- a/fs/xfs/xfs_log.h ++++ b/fs/xfs/xfs_log.h +@@ -161,6 +161,5 @@ bool xlog_force_shutdown(struct xlog *log, uint32_t shutdown_flags); + + void xlog_use_incompat_feat(struct xlog *log); + void xlog_drop_incompat_feat(struct xlog *log); +-int xfs_attr_use_log_assist(struct xfs_mount *mp); + + #endif /* __XFS_LOG_H__ */ +diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c +index 67a99d94701e5b..d152d0945dab1c 100644 +--- a/fs/xfs/xfs_log_cil.c ++++ b/fs/xfs/xfs_log_cil.c +@@ -156,7 +156,6 @@ xlog_cil_insert_pcp_aggregate( + struct xfs_cil *cil, + struct xfs_cil_ctx *ctx) + { +- struct xlog_cil_pcp *cilpcp; + int cpu; + int count = 0; + +@@ -171,13 +170,11 @@ xlog_cil_insert_pcp_aggregate( + * structures that could have a nonzero space_used. + */ + for_each_cpu(cpu, &ctx->cil_pcpmask) { +- int old, prev; ++ struct xlog_cil_pcp *cilpcp = per_cpu_ptr(cil->xc_pcp, cpu); ++ int old = READ_ONCE(cilpcp->space_used); + +- cilpcp = per_cpu_ptr(cil->xc_pcp, cpu); +- do { +- old = cilpcp->space_used; +- prev = cmpxchg(&cilpcp->space_used, old, 0); +- } while (old != prev); ++ while (!try_cmpxchg(&cilpcp->space_used, &old, 0)) ++ ; + count += old; + } + atomic_add(count, &ctx->space_used); +diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c +index d11de0fa5c5f80..60382eb4996105 100644 +--- a/fs/xfs/xfs_log_recover.c ++++ b/fs/xfs/xfs_log_recover.c +@@ -1820,7 +1820,7 @@ xlog_find_item_ops( + * from the transaction. However, we can't do that until after we've + * replayed all the other items because they may be dependent on the + * cancelled buffer and replaying the cancelled buffer can remove it +- * form the cancelled buffer table. Hence they have tobe done last. ++ * form the cancelled buffer table. Hence they have to be done last. + * + * 3. Inode allocation buffers must be replayed before inode items that + * read the buffer and replay changes into it. For filesystems using the +@@ -3365,13 +3365,6 @@ xlog_do_recover( + /* re-initialise in-core superblock and geometry structures */ + mp->m_features |= xfs_sb_version_to_features(sbp); + xfs_reinit_percpu_counters(mp); +- error = xfs_initialize_perag(mp, sbp->sb_agcount, sbp->sb_dblocks, +- &mp->m_maxagi); +- if (error) { +- xfs_warn(mp, "Failed post-recovery per-ag init: %d", error); +- return error; +- } +- mp->m_alloc_set_aside = xfs_alloc_set_aside(mp); + + /* Normal transactions can now occur */ + clear_bit(XLOG_ACTIVE_RECOVERY, &log->l_opstate); +diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c +index 0a0fd19573d8ce..747db90731e894 100644 +--- a/fs/xfs/xfs_mount.c ++++ b/fs/xfs/xfs_mount.c +@@ -797,8 +797,8 @@ xfs_mountfs( + /* + * Allocate and initialize the per-ag data. + */ +- error = xfs_initialize_perag(mp, sbp->sb_agcount, mp->m_sb.sb_dblocks, +- &mp->m_maxagi); ++ error = xfs_initialize_perag(mp, 0, sbp->sb_agcount, ++ mp->m_sb.sb_dblocks, &mp->m_maxagi); + if (error) { + xfs_warn(mp, "Failed per-ag init: %d", error); + goto out_free_dir; +diff --git a/fs/xfs/xfs_qm_bhv.c b/fs/xfs/xfs_qm_bhv.c +index b77673dd05581e..26b2c449f3c665 100644 +--- a/fs/xfs/xfs_qm_bhv.c ++++ b/fs/xfs/xfs_qm_bhv.c +@@ -19,28 +19,41 @@ + STATIC void + xfs_fill_statvfs_from_dquot( + struct kstatfs *statp, ++ struct xfs_inode *ip, + struct xfs_dquot *dqp) + { ++ struct xfs_dquot_res *blkres = &dqp->q_blk; + uint64_t limit; + +- limit = dqp->q_blk.softlimit ? +- dqp->q_blk.softlimit : +- dqp->q_blk.hardlimit; +- if (limit && statp->f_blocks > limit) { +- statp->f_blocks = limit; +- statp->f_bfree = statp->f_bavail = +- (statp->f_blocks > dqp->q_blk.reserved) ? +- (statp->f_blocks - dqp->q_blk.reserved) : 0; ++ if (XFS_IS_REALTIME_MOUNT(ip->i_mount) && ++ (ip->i_diflags & (XFS_DIFLAG_RTINHERIT | XFS_DIFLAG_REALTIME))) ++ blkres = &dqp->q_rtb; ++ ++ limit = blkres->softlimit ? ++ blkres->softlimit : ++ blkres->hardlimit; ++ if (limit) { ++ uint64_t remaining = 0; ++ ++ if (limit > blkres->reserved) ++ remaining = limit - blkres->reserved; ++ ++ statp->f_blocks = min(statp->f_blocks, limit); ++ statp->f_bfree = min(statp->f_bfree, remaining); ++ statp->f_bavail = min(statp->f_bavail, remaining); + } + + limit = dqp->q_ino.softlimit ? + dqp->q_ino.softlimit : + dqp->q_ino.hardlimit; +- if (limit && statp->f_files > limit) { +- statp->f_files = limit; +- statp->f_ffree = +- (statp->f_files > dqp->q_ino.reserved) ? +- (statp->f_files - dqp->q_ino.reserved) : 0; ++ if (limit) { ++ uint64_t remaining = 0; ++ ++ if (limit > dqp->q_ino.reserved) ++ remaining = limit - dqp->q_ino.reserved; ++ ++ statp->f_files = min(statp->f_files, limit); ++ statp->f_ffree = min(statp->f_ffree, remaining); + } + } + +@@ -61,7 +74,7 @@ xfs_qm_statvfs( + struct xfs_dquot *dqp; + + if (!xfs_qm_dqget(mp, ip->i_projid, XFS_DQTYPE_PROJ, false, &dqp)) { +- xfs_fill_statvfs_from_dquot(statp, dqp); ++ xfs_fill_statvfs_from_dquot(statp, ip, dqp); + xfs_qm_dqput(dqp); + } + } +diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c +index 3431d0d8b6f3a1..4058cf361d2153 100644 +--- a/fs/xfs/xfs_reflink.c ++++ b/fs/xfs/xfs_reflink.c +@@ -1600,6 +1600,9 @@ xfs_reflink_clear_inode_flag( + + ASSERT(xfs_is_reflink_inode(ip)); + ++ if (!xfs_can_free_cowblocks(ip)) ++ return 0; ++ + error = xfs_reflink_inode_has_shared_extents(*tpp, ip, &needs_flag); + if (error || needs_flag) + return error; +diff --git a/fs/xfs/xfs_reflink.h b/fs/xfs/xfs_reflink.h +index 65c5dfe17ecf7f..67a335b247b157 100644 +--- a/fs/xfs/xfs_reflink.h ++++ b/fs/xfs/xfs_reflink.h +@@ -16,6 +16,25 @@ static inline bool xfs_is_cow_inode(struct xfs_inode *ip) + return xfs_is_reflink_inode(ip) || xfs_is_always_cow_inode(ip); + } + ++/* ++ * Check whether it is safe to free COW fork blocks from an inode. It is unsafe ++ * to do so when an inode has dirty cache or I/O in-flight, even if no shared ++ * extents exist in the data fork, because outstanding I/O may target blocks ++ * that were speculatively allocated to the COW fork. ++ */ ++static inline bool ++xfs_can_free_cowblocks(struct xfs_inode *ip) ++{ ++ struct inode *inode = VFS_I(ip); ++ ++ if ((inode->i_state & I_DIRTY_PAGES) || ++ mapping_tagged(inode->i_mapping, PAGECACHE_TAG_DIRTY) || ++ mapping_tagged(inode->i_mapping, PAGECACHE_TAG_WRITEBACK) || ++ atomic_read(&inode->i_dio_count)) ++ return false; ++ return true; ++} ++ + extern int xfs_reflink_trim_around_shared(struct xfs_inode *ip, + struct xfs_bmbt_irec *irec, bool *shared); + int xfs_bmap_trim_cow(struct xfs_inode *ip, struct xfs_bmbt_irec *imap, +diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c +index 13007b6bc9f337..a726fbba49e40a 100644 +--- a/fs/xfs/xfs_super.c ++++ b/fs/xfs/xfs_super.c +@@ -878,12 +878,6 @@ xfs_fs_statfs( + ffree = statp->f_files - (icount - ifree); + statp->f_ffree = max_t(int64_t, ffree, 0); + +- +- if ((ip->i_diflags & XFS_DIFLAG_PROJINHERIT) && +- ((mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_PQUOTA_ENFD))) == +- (XFS_PQUOTA_ACCT|XFS_PQUOTA_ENFD)) +- xfs_qm_statvfs(ip, statp); +- + if (XFS_IS_REALTIME_MOUNT(mp) && + (ip->i_diflags & (XFS_DIFLAG_RTINHERIT | XFS_DIFLAG_REALTIME))) { + s64 freertx; +@@ -893,6 +887,11 @@ xfs_fs_statfs( + statp->f_bavail = statp->f_bfree = freertx * sbp->sb_rextsize; + } + ++ if ((ip->i_diflags & XFS_DIFLAG_PROJINHERIT) && ++ ((mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_PQUOTA_ENFD))) == ++ (XFS_PQUOTA_ACCT|XFS_PQUOTA_ENFD)) ++ xfs_qm_statvfs(ip, statp); ++ + return 0; + } + +diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h +index 95ee88dfe0b9c6..337a9d1c558f3c 100644 +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -3072,6 +3072,8 @@ static inline struct net_device *first_net_device_rcu(struct net *net) + } + + int netdev_boot_setup_check(struct net_device *dev); ++struct net_device *dev_getbyhwaddr(struct net *net, unsigned short type, ++ const char *hwaddr); + struct net_device *dev_getbyhwaddr_rcu(struct net *net, unsigned short type, + const char *hwaddr); + struct net_device *dev_getfirstbyhwtype(struct net *net, unsigned short type); +diff --git a/include/linux/nvmem-provider.h b/include/linux/nvmem-provider.h +index 1b81adebdb8beb..9a015e4d428ccb 100644 +--- a/include/linux/nvmem-provider.h ++++ b/include/linux/nvmem-provider.h +@@ -83,6 +83,8 @@ struct nvmem_cell_info { + * @cells: Optional array of pre-defined NVMEM cells. + * @ncells: Number of elements in cells. + * @add_legacy_fixed_of_cells: Read fixed NVMEM cells from old OF syntax. ++ * @fixup_dt_cell_info: Will be called before a cell is added. Can be ++ * used to modify the nvmem_cell_info. + * @keepout: Optional array of keepout ranges (sorted ascending by start). + * @nkeepout: Number of elements in the keepout array. + * @type: Type of the nvmem storage +@@ -114,6 +116,8 @@ struct nvmem_config { + const struct nvmem_cell_info *cells; + int ncells; + bool add_legacy_fixed_of_cells; ++ void (*fixup_dt_cell_info)(struct nvmem_device *nvmem, ++ struct nvmem_cell_info *cell); + const struct nvmem_keepout *keepout; + unsigned int nkeepout; + enum nvmem_type type; +@@ -158,11 +162,8 @@ struct nvmem_cell_table { + * + * @name: Layout name. + * @of_match_table: Open firmware match table. +- * @add_cells: Will be called if a nvmem device is found which +- * has this layout. The function will add layout +- * specific cells with nvmem_add_one_cell(). +- * @fixup_cell_info: Will be called before a cell is added. Can be +- * used to modify the nvmem_cell_info. ++ * @add_cells: Called to populate the layout using ++ * nvmem_add_one_cell(). + * @owner: Pointer to struct module. + * @node: List node. + * +@@ -174,11 +175,7 @@ struct nvmem_cell_table { + struct nvmem_layout { + const char *name; + const struct of_device_id *of_match_table; +- int (*add_cells)(struct device *dev, struct nvmem_device *nvmem, +- struct nvmem_layout *layout); +- void (*fixup_cell_info)(struct nvmem_device *nvmem, +- struct nvmem_layout *layout, +- struct nvmem_cell_info *cell); ++ int (*add_cells)(struct device *dev, struct nvmem_device *nvmem); + + /* private */ + struct module *owner; +diff --git a/include/linux/serio.h b/include/linux/serio.h +index 6c27d413da921d..e105ff2ee651a6 100644 +--- a/include/linux/serio.h ++++ b/include/linux/serio.h +@@ -6,6 +6,7 @@ + #define _SERIO_H + + ++#include + #include + #include + #include +@@ -161,4 +162,6 @@ static inline void serio_continue_rx(struct serio *serio) + spin_unlock_irq(&serio->lock); + } + ++DEFINE_GUARD(serio_pause_rx, struct serio *, serio_pause_rx(_T), serio_continue_rx(_T)) ++ + #endif +diff --git a/include/linux/skmsg.h b/include/linux/skmsg.h +index 6ccfd9236387c6..32bbebf5b71e3c 100644 +--- a/include/linux/skmsg.h ++++ b/include/linux/skmsg.h +@@ -87,6 +87,8 @@ struct sk_psock { + struct sk_psock_progs progs; + #if IS_ENABLED(CONFIG_BPF_STREAM_PARSER) + struct strparser strp; ++ u32 copied_seq; ++ u32 ingress_bytes; + #endif + struct sk_buff_head ingress_skb; + struct list_head ingress_msg; +diff --git a/include/net/strparser.h b/include/net/strparser.h +index 41e2ce9e9e10ff..0a83010b3a64a9 100644 +--- a/include/net/strparser.h ++++ b/include/net/strparser.h +@@ -43,6 +43,8 @@ struct strparser; + struct strp_callbacks { + int (*parse_msg)(struct strparser *strp, struct sk_buff *skb); + void (*rcv_msg)(struct strparser *strp, struct sk_buff *skb); ++ int (*read_sock)(struct strparser *strp, read_descriptor_t *desc, ++ sk_read_actor_t recv_actor); + int (*read_sock_done)(struct strparser *strp, int err); + void (*abort_parser)(struct strparser *strp, int err); + void (*lock)(struct strparser *strp); +diff --git a/include/net/tcp.h b/include/net/tcp.h +index b3917af309e0f1..a6def0aab3ed31 100644 +--- a/include/net/tcp.h ++++ b/include/net/tcp.h +@@ -40,6 +40,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -630,6 +631,19 @@ void tcp_fin(struct sock *sk); + void tcp_check_space(struct sock *sk); + void tcp_sack_compress_send_ack(struct sock *sk); + ++static inline void tcp_cleanup_skb(struct sk_buff *skb) ++{ ++ skb_dst_drop(skb); ++ secpath_reset(skb); ++} ++ ++static inline void tcp_add_receive_queue(struct sock *sk, struct sk_buff *skb) ++{ ++ DEBUG_NET_WARN_ON_ONCE(skb_dst(skb)); ++ DEBUG_NET_WARN_ON_ONCE(secpath_exists(skb)); ++ __skb_queue_tail(&sk->sk_receive_queue, skb); ++} ++ + /* tcp_timer.c */ + void tcp_init_xmit_timers(struct sock *); + static inline void tcp_clear_xmit_timers(struct sock *sk) +@@ -676,6 +690,9 @@ void tcp_get_info(struct sock *, struct tcp_info *); + /* Read 'sendfile()'-style from a TCP socket */ + int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, + sk_read_actor_t recv_actor); ++int tcp_read_sock_noack(struct sock *sk, read_descriptor_t *desc, ++ sk_read_actor_t recv_actor, bool noack, ++ u32 *copied_seq); + int tcp_read_skb(struct sock *sk, skb_read_actor_t recv_actor); + struct sk_buff *tcp_recv_skb(struct sock *sk, u32 seq, u32 *off); + void tcp_read_done(struct sock *sk, size_t len); +@@ -2390,6 +2407,11 @@ struct sk_psock; + #ifdef CONFIG_BPF_SYSCALL + int tcp_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool restore); + void tcp_bpf_clone(const struct sock *sk, struct sock *newsk); ++#ifdef CONFIG_BPF_STREAM_PARSER ++struct strparser; ++int tcp_bpf_strp_read_sock(struct strparser *strp, read_descriptor_t *desc, ++ sk_read_actor_t recv_actor); ++#endif /* CONFIG_BPF_STREAM_PARSER */ + #endif /* CONFIG_BPF_SYSCALL */ + + #ifdef CONFIG_INET +diff --git a/include/trace/events/oom.h b/include/trace/events/oom.h +index 26a11e4a2c361d..b799f3bcba8233 100644 +--- a/include/trace/events/oom.h ++++ b/include/trace/events/oom.h +@@ -7,6 +7,8 @@ + #include + #include + ++#define PG_COUNT_TO_KB(x) ((x) << (PAGE_SHIFT - 10)) ++ + TRACE_EVENT(oom_score_adj_update, + + TP_PROTO(struct task_struct *task), +@@ -72,19 +74,45 @@ TRACE_EVENT(reclaim_retry_zone, + ); + + TRACE_EVENT(mark_victim, +- TP_PROTO(int pid), ++ TP_PROTO(struct task_struct *task, uid_t uid), + +- TP_ARGS(pid), ++ TP_ARGS(task, uid), + + TP_STRUCT__entry( + __field(int, pid) ++ __string(comm, task->comm) ++ __field(unsigned long, total_vm) ++ __field(unsigned long, anon_rss) ++ __field(unsigned long, file_rss) ++ __field(unsigned long, shmem_rss) ++ __field(uid_t, uid) ++ __field(unsigned long, pgtables) ++ __field(short, oom_score_adj) + ), + + TP_fast_assign( +- __entry->pid = pid; ++ __entry->pid = task->pid; ++ __assign_str(comm, task->comm); ++ __entry->total_vm = PG_COUNT_TO_KB(task->mm->total_vm); ++ __entry->anon_rss = PG_COUNT_TO_KB(get_mm_counter(task->mm, MM_ANONPAGES)); ++ __entry->file_rss = PG_COUNT_TO_KB(get_mm_counter(task->mm, MM_FILEPAGES)); ++ __entry->shmem_rss = PG_COUNT_TO_KB(get_mm_counter(task->mm, MM_SHMEMPAGES)); ++ __entry->uid = uid; ++ __entry->pgtables = mm_pgtables_bytes(task->mm) >> 10; ++ __entry->oom_score_adj = task->signal->oom_score_adj; + ), + +- TP_printk("pid=%d", __entry->pid) ++ TP_printk("pid=%d comm=%s total-vm=%lukB anon-rss=%lukB file-rss:%lukB shmem-rss:%lukB uid=%u pgtables=%lukB oom_score_adj=%hd", ++ __entry->pid, ++ __get_str(comm), ++ __entry->total_vm, ++ __entry->anon_rss, ++ __entry->file_rss, ++ __entry->shmem_rss, ++ __entry->uid, ++ __entry->pgtables, ++ __entry->oom_score_adj ++ ) + ); + + TRACE_EVENT(wake_reaper, +diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c +index b61637dad442a7..5776440f584c76 100644 +--- a/io_uring/io_uring.c ++++ b/io_uring/io_uring.c +@@ -2176,6 +2176,8 @@ static int io_init_req(struct io_ring_ctx *ctx, struct io_kiocb *req, + req->opcode = 0; + return io_init_fail_req(req, -EINVAL); + } ++ opcode = array_index_nospec(opcode, IORING_OP_LAST); ++ + def = &io_issue_defs[opcode]; + if (unlikely(sqe_flags & ~SQE_COMMON_FLAGS)) { + /* enforce forwards compatibility on users */ +diff --git a/kernel/acct.c b/kernel/acct.c +index 1a9f929fe629e7..a58a284f1f38de 100644 +--- a/kernel/acct.c ++++ b/kernel/acct.c +@@ -104,48 +104,50 @@ struct bsd_acct_struct { + atomic_long_t count; + struct rcu_head rcu; + struct mutex lock; +- int active; ++ bool active; ++ bool check_space; + unsigned long needcheck; + struct file *file; + struct pid_namespace *ns; + struct work_struct work; + struct completion done; ++ acct_t ac; + }; + +-static void do_acct_process(struct bsd_acct_struct *acct); ++static void fill_ac(struct bsd_acct_struct *acct); ++static void acct_write_process(struct bsd_acct_struct *acct); + + /* + * Check the amount of free space and suspend/resume accordingly. + */ +-static int check_free_space(struct bsd_acct_struct *acct) ++static bool check_free_space(struct bsd_acct_struct *acct) + { + struct kstatfs sbuf; + +- if (time_is_after_jiffies(acct->needcheck)) +- goto out; ++ if (!acct->check_space) ++ return acct->active; + + /* May block */ + if (vfs_statfs(&acct->file->f_path, &sbuf)) +- goto out; ++ return acct->active; + + if (acct->active) { + u64 suspend = sbuf.f_blocks * SUSPEND; + do_div(suspend, 100); + if (sbuf.f_bavail <= suspend) { +- acct->active = 0; ++ acct->active = false; + pr_info("Process accounting paused\n"); + } + } else { + u64 resume = sbuf.f_blocks * RESUME; + do_div(resume, 100); + if (sbuf.f_bavail >= resume) { +- acct->active = 1; ++ acct->active = true; + pr_info("Process accounting resumed\n"); + } + } + + acct->needcheck = jiffies + ACCT_TIMEOUT*HZ; +-out: + return acct->active; + } + +@@ -190,7 +192,11 @@ static void acct_pin_kill(struct fs_pin *pin) + { + struct bsd_acct_struct *acct = to_acct(pin); + mutex_lock(&acct->lock); +- do_acct_process(acct); ++ /* ++ * Fill the accounting struct with the exiting task's info ++ * before punting to the workqueue. ++ */ ++ fill_ac(acct); + schedule_work(&acct->work); + wait_for_completion(&acct->done); + cmpxchg(&acct->ns->bacct, pin, NULL); +@@ -203,6 +209,9 @@ static void close_work(struct work_struct *work) + { + struct bsd_acct_struct *acct = container_of(work, struct bsd_acct_struct, work); + struct file *file = acct->file; ++ ++ /* We were fired by acct_pin_kill() which holds acct->lock. */ ++ acct_write_process(acct); + if (file->f_op->flush) + file->f_op->flush(file, NULL); + __fput_sync(file); +@@ -235,6 +244,20 @@ static int acct_on(struct filename *pathname) + return -EACCES; + } + ++ /* Exclude kernel kernel internal filesystems. */ ++ if (file_inode(file)->i_sb->s_flags & (SB_NOUSER | SB_KERNMOUNT)) { ++ kfree(acct); ++ filp_close(file, NULL); ++ return -EINVAL; ++ } ++ ++ /* Exclude procfs and sysfs. */ ++ if (file_inode(file)->i_sb->s_iflags & SB_I_USERNS_VISIBLE) { ++ kfree(acct); ++ filp_close(file, NULL); ++ return -EINVAL; ++ } ++ + if (!(file->f_mode & FMODE_CAN_WRITE)) { + kfree(acct); + filp_close(file, NULL); +@@ -431,13 +454,27 @@ static u32 encode_float(u64 value) + * do_exit() or when switching to a different output file. + */ + +-static void fill_ac(acct_t *ac) ++static void fill_ac(struct bsd_acct_struct *acct) + { + struct pacct_struct *pacct = ¤t->signal->pacct; ++ struct file *file = acct->file; ++ acct_t *ac = &acct->ac; + u64 elapsed, run_time; + time64_t btime; + struct tty_struct *tty; + ++ lockdep_assert_held(&acct->lock); ++ ++ if (time_is_after_jiffies(acct->needcheck)) { ++ acct->check_space = false; ++ ++ /* Don't fill in @ac if nothing will be written. */ ++ if (!acct->active) ++ return; ++ } else { ++ acct->check_space = true; ++ } ++ + /* + * Fill the accounting struct with the needed info as recorded + * by the different kernel functions. +@@ -485,64 +522,61 @@ static void fill_ac(acct_t *ac) + ac->ac_majflt = encode_comp_t(pacct->ac_majflt); + ac->ac_exitcode = pacct->ac_exitcode; + spin_unlock_irq(¤t->sighand->siglock); +-} +-/* +- * do_acct_process does all actual work. Caller holds the reference to file. +- */ +-static void do_acct_process(struct bsd_acct_struct *acct) +-{ +- acct_t ac; +- unsigned long flim; +- const struct cred *orig_cred; +- struct file *file = acct->file; + +- /* +- * Accounting records are not subject to resource limits. +- */ +- flim = rlimit(RLIMIT_FSIZE); +- current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY; +- /* Perform file operations on behalf of whoever enabled accounting */ +- orig_cred = override_creds(file->f_cred); +- +- /* +- * First check to see if there is enough free_space to continue +- * the process accounting system. +- */ +- if (!check_free_space(acct)) +- goto out; +- +- fill_ac(&ac); + /* we really need to bite the bullet and change layout */ +- ac.ac_uid = from_kuid_munged(file->f_cred->user_ns, orig_cred->uid); +- ac.ac_gid = from_kgid_munged(file->f_cred->user_ns, orig_cred->gid); ++ ac->ac_uid = from_kuid_munged(file->f_cred->user_ns, current_uid()); ++ ac->ac_gid = from_kgid_munged(file->f_cred->user_ns, current_gid()); + #if ACCT_VERSION == 1 || ACCT_VERSION == 2 + /* backward-compatible 16 bit fields */ +- ac.ac_uid16 = ac.ac_uid; +- ac.ac_gid16 = ac.ac_gid; ++ ac->ac_uid16 = ac->ac_uid; ++ ac->ac_gid16 = ac->ac_gid; + #elif ACCT_VERSION == 3 + { + struct pid_namespace *ns = acct->ns; + +- ac.ac_pid = task_tgid_nr_ns(current, ns); ++ ac->ac_pid = task_tgid_nr_ns(current, ns); + rcu_read_lock(); +- ac.ac_ppid = task_tgid_nr_ns(rcu_dereference(current->real_parent), +- ns); ++ ac->ac_ppid = task_tgid_nr_ns(rcu_dereference(current->real_parent), ns); + rcu_read_unlock(); + } + #endif ++} ++ ++static void acct_write_process(struct bsd_acct_struct *acct) ++{ ++ struct file *file = acct->file; ++ const struct cred *cred; ++ acct_t *ac = &acct->ac; ++ ++ /* Perform file operations on behalf of whoever enabled accounting */ ++ cred = override_creds(file->f_cred); ++ + /* +- * Get freeze protection. If the fs is frozen, just skip the write +- * as we could deadlock the system otherwise. ++ * First check to see if there is enough free_space to continue ++ * the process accounting system. Then get freeze protection. If ++ * the fs is frozen, just skip the write as we could deadlock ++ * the system otherwise. + */ +- if (file_start_write_trylock(file)) { ++ if (check_free_space(acct) && file_start_write_trylock(file)) { + /* it's been opened O_APPEND, so position is irrelevant */ + loff_t pos = 0; +- __kernel_write(file, &ac, sizeof(acct_t), &pos); ++ __kernel_write(file, ac, sizeof(acct_t), &pos); + file_end_write(file); + } +-out: ++ ++ revert_creds(cred); ++} ++ ++static void do_acct_process(struct bsd_acct_struct *acct) ++{ ++ unsigned long flim; ++ ++ /* Accounting records are not subject to resource limits. */ ++ flim = rlimit(RLIMIT_FSIZE); ++ current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY; ++ fill_ac(acct); ++ acct_write_process(acct); + current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim; +- revert_creds(orig_cred); + } + + /** +diff --git a/kernel/bpf/bpf_cgrp_storage.c b/kernel/bpf/bpf_cgrp_storage.c +index d44fe8dd973295..ee1c7b77096e7b 100644 +--- a/kernel/bpf/bpf_cgrp_storage.c ++++ b/kernel/bpf/bpf_cgrp_storage.c +@@ -154,7 +154,7 @@ static struct bpf_map *cgroup_storage_map_alloc(union bpf_attr *attr) + + static void cgroup_storage_map_free(struct bpf_map *map) + { +- bpf_local_storage_map_free(map, &cgroup_cache, NULL); ++ bpf_local_storage_map_free(map, &cgroup_cache, &bpf_cgrp_storage_busy); + } + + /* *gfp_flags* is a hidden argument provided by the verifier */ +diff --git a/kernel/bpf/ringbuf.c b/kernel/bpf/ringbuf.c +index 246559c3e93d0d..528f4d6342262e 100644 +--- a/kernel/bpf/ringbuf.c ++++ b/kernel/bpf/ringbuf.c +@@ -268,8 +268,6 @@ static int ringbuf_map_mmap_kern(struct bpf_map *map, struct vm_area_struct *vma + /* allow writable mapping for the consumer_pos only */ + if (vma->vm_pgoff != 0 || vma->vm_end - vma->vm_start != PAGE_SIZE) + return -EPERM; +- } else { +- vm_flags_clear(vma, VM_MAYWRITE); + } + /* remap_vmalloc_range() checks size and offset constraints */ + return remap_vmalloc_range(vma, rb_map->rb, +@@ -289,8 +287,6 @@ static int ringbuf_map_mmap_user(struct bpf_map *map, struct vm_area_struct *vma + * position, and the ring buffer data itself. + */ + return -EPERM; +- } else { +- vm_flags_clear(vma, VM_MAYWRITE); + } + /* remap_vmalloc_range() checks size and offset constraints */ + return remap_vmalloc_range(vma, rb_map->rb, vma->vm_pgoff + RINGBUF_PGOFF); +diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c +index ba38c08a9a059a..f089a616301119 100644 +--- a/kernel/bpf/syscall.c ++++ b/kernel/bpf/syscall.c +@@ -882,7 +882,7 @@ static const struct vm_operations_struct bpf_map_default_vmops = { + static int bpf_map_mmap(struct file *filp, struct vm_area_struct *vma) + { + struct bpf_map *map = filp->private_data; +- int err; ++ int err = 0; + + if (!map->ops->map_mmap || !IS_ERR_OR_NULL(map->record)) + return -ENOTSUPP; +@@ -906,24 +906,33 @@ static int bpf_map_mmap(struct file *filp, struct vm_area_struct *vma) + err = -EACCES; + goto out; + } ++ bpf_map_write_active_inc(map); + } ++out: ++ mutex_unlock(&map->freeze_mutex); ++ if (err) ++ return err; + + /* set default open/close callbacks */ + vma->vm_ops = &bpf_map_default_vmops; + vma->vm_private_data = map; + vm_flags_clear(vma, VM_MAYEXEC); ++ /* If mapping is read-only, then disallow potentially re-mapping with ++ * PROT_WRITE by dropping VM_MAYWRITE flag. This VM_MAYWRITE clearing ++ * means that as far as BPF map's memory-mapped VMAs are concerned, ++ * VM_WRITE and VM_MAYWRITE and equivalent, if one of them is set, ++ * both should be set, so we can forget about VM_MAYWRITE and always ++ * check just VM_WRITE ++ */ + if (!(vma->vm_flags & VM_WRITE)) +- /* disallow re-mapping with PROT_WRITE */ + vm_flags_clear(vma, VM_MAYWRITE); + + err = map->ops->map_mmap(map, vma); +- if (err) +- goto out; ++ if (err) { ++ if (vma->vm_flags & VM_WRITE) ++ bpf_map_write_active_dec(map); ++ } + +- if (vma->vm_flags & VM_MAYWRITE) +- bpf_map_write_active_inc(map); +-out: +- mutex_unlock(&map->freeze_mutex); + return err; + } + +@@ -1798,8 +1807,6 @@ int generic_map_update_batch(struct bpf_map *map, struct file *map_file, + return err; + } + +-#define MAP_LOOKUP_RETRIES 3 +- + int generic_map_lookup_batch(struct bpf_map *map, + const union bpf_attr *attr, + union bpf_attr __user *uattr) +@@ -1809,8 +1816,8 @@ int generic_map_lookup_batch(struct bpf_map *map, + void __user *values = u64_to_user_ptr(attr->batch.values); + void __user *keys = u64_to_user_ptr(attr->batch.keys); + void *buf, *buf_prevkey, *prev_key, *key, *value; +- int err, retry = MAP_LOOKUP_RETRIES; + u32 value_size, cp, max_count; ++ int err; + + if (attr->batch.elem_flags & ~BPF_F_LOCK) + return -EINVAL; +@@ -1856,14 +1863,8 @@ int generic_map_lookup_batch(struct bpf_map *map, + err = bpf_map_copy_value(map, key, value, + attr->batch.elem_flags); + +- if (err == -ENOENT) { +- if (retry) { +- retry--; +- continue; +- } +- err = -EINTR; +- break; +- } ++ if (err == -ENOENT) ++ goto next_key; + + if (err) + goto free_buf; +@@ -1878,12 +1879,12 @@ int generic_map_lookup_batch(struct bpf_map *map, + goto free_buf; + } + ++ cp++; ++next_key: + if (!prev_key) + prev_key = buf_prevkey; + + swap(prev_key, key); +- retry = MAP_LOOKUP_RETRIES; +- cp++; + cond_resched(); + } + +diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c +index 1043936b352d12..6e6b2a5aa1402b 100644 +--- a/kernel/trace/ftrace.c ++++ b/kernel/trace/ftrace.c +@@ -5233,6 +5233,9 @@ __ftrace_match_addr(struct ftrace_hash *hash, unsigned long ip, int remove) + return -ENOENT; + free_hash_entry(hash, entry); + return 0; ++ } else if (__ftrace_lookup_ip(hash, ip) != NULL) { ++ /* Already exists */ ++ return 0; + } + + entry = add_hash_entry(hash, ip); +diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c +index 9f1bfbe105e8d9..69e92c7359fb9a 100644 +--- a/kernel/trace/trace_functions.c ++++ b/kernel/trace/trace_functions.c +@@ -185,7 +185,7 @@ function_trace_call(unsigned long ip, unsigned long parent_ip, + if (bit < 0) + return; + +- trace_ctx = tracing_gen_ctx(); ++ trace_ctx = tracing_gen_ctx_dec(); + + cpu = smp_processor_id(); + data = per_cpu_ptr(tr->array_buffer.data, cpu); +@@ -285,7 +285,6 @@ function_no_repeats_trace_call(unsigned long ip, unsigned long parent_ip, + struct trace_array *tr = op->private; + struct trace_array_cpu *data; + unsigned int trace_ctx; +- unsigned long flags; + int bit; + int cpu; + +@@ -312,8 +311,7 @@ function_no_repeats_trace_call(unsigned long ip, unsigned long parent_ip, + if (is_repeat_check(tr, last_info, ip, parent_ip)) + goto out; + +- local_save_flags(flags); +- trace_ctx = tracing_gen_ctx_flags(flags); ++ trace_ctx = tracing_gen_ctx_dec(); + process_repeats(tr, ip, parent_ip, last_info, trace_ctx); + + trace_function(tr, ip, parent_ip, trace_ctx); +diff --git a/lib/iov_iter.c b/lib/iov_iter.c +index a4bb47efafe37d..d6620eaa951539 100644 +--- a/lib/iov_iter.c ++++ b/lib/iov_iter.c +@@ -1441,6 +1441,8 @@ static ssize_t __import_iovec_ubuf(int type, const struct iovec __user *uvec, + struct iovec *iov = *iovp; + ssize_t ret; + ++ *iovp = NULL; ++ + if (compat) + ret = copy_compat_iovec_from_user(iov, uvec, 1); + else +@@ -1451,7 +1453,6 @@ static ssize_t __import_iovec_ubuf(int type, const struct iovec __user *uvec, + ret = import_ubuf(type, iov->iov_base, iov->iov_len, i); + if (unlikely(ret)) + return ret; +- *iovp = NULL; + return i->count; + } + +diff --git a/mm/madvise.c b/mm/madvise.c +index 98fdb9288a68a8..9d2a6cb655ff20 100644 +--- a/mm/madvise.c ++++ b/mm/madvise.c +@@ -899,7 +899,16 @@ static long madvise_dontneed_free(struct vm_area_struct *vma, + */ + end = vma->vm_end; + } +- VM_WARN_ON(start >= end); ++ /* ++ * If the memory region between start and end was ++ * originally backed by 4kB pages and then remapped to ++ * be backed by hugepages while mmap_lock was dropped, ++ * the adjustment for hugetlb vma above may have rounded ++ * end down to the start address. ++ */ ++ if (start == end) ++ return 0; ++ VM_WARN_ON(start > end); + } + + if (behavior == MADV_DONTNEED || behavior == MADV_DONTNEED_LOCKED) +diff --git a/mm/memcontrol.c b/mm/memcontrol.c +index d2ceadd11b1004..9bf5a69e20d87a 100644 +--- a/mm/memcontrol.c ++++ b/mm/memcontrol.c +@@ -1266,6 +1266,7 @@ void mem_cgroup_scan_tasks(struct mem_cgroup *memcg, + { + struct mem_cgroup *iter; + int ret = 0; ++ int i = 0; + + BUG_ON(mem_cgroup_is_root(memcg)); + +@@ -1274,8 +1275,12 @@ void mem_cgroup_scan_tasks(struct mem_cgroup *memcg, + struct task_struct *task; + + css_task_iter_start(&iter->css, CSS_TASK_ITER_PROCS, &it); +- while (!ret && (task = css_task_iter_next(&it))) ++ while (!ret && (task = css_task_iter_next(&it))) { ++ /* Avoid potential softlockup warning */ ++ if ((++i & 1023) == 0) ++ cond_resched(); + ret = fn(task, arg); ++ } + css_task_iter_end(&it); + if (ret) { + mem_cgroup_iter_break(memcg, iter); +diff --git a/mm/oom_kill.c b/mm/oom_kill.c +index 44bde56ecd025a..17a2ef9f93d3d3 100644 +--- a/mm/oom_kill.c ++++ b/mm/oom_kill.c +@@ -44,6 +44,8 @@ + #include + #include + #include ++#include ++#include + + #include + #include "internal.h" +@@ -429,10 +431,15 @@ static void dump_tasks(struct oom_control *oc) + mem_cgroup_scan_tasks(oc->memcg, dump_task, oc); + else { + struct task_struct *p; ++ int i = 0; + + rcu_read_lock(); +- for_each_process(p) ++ for_each_process(p) { ++ /* Avoid potential softlockup warning */ ++ if ((++i & 1023) == 0) ++ touch_softlockup_watchdog(); + dump_task(p, oc); ++ } + rcu_read_unlock(); + } + } +@@ -755,6 +762,7 @@ static inline void queue_oom_reaper(struct task_struct *tsk) + */ + static void mark_oom_victim(struct task_struct *tsk) + { ++ const struct cred *cred; + struct mm_struct *mm = tsk->mm; + + WARN_ON(oom_killer_disabled); +@@ -774,7 +782,9 @@ static void mark_oom_victim(struct task_struct *tsk) + */ + __thaw_task(tsk); + atomic_inc(&oom_victims); +- trace_mark_victim(tsk->pid); ++ cred = get_task_cred(tsk); ++ trace_mark_victim(tsk, cred->uid.val); ++ put_cred(cred); + } + + /** +diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c +index 905de361f8623f..73fb9db55798c8 100644 +--- a/net/bpf/test_run.c ++++ b/net/bpf/test_run.c +@@ -630,12 +630,9 @@ static void *bpf_test_init(const union bpf_attr *kattr, u32 user_size, + void __user *data_in = u64_to_user_ptr(kattr->test.data_in); + void *data; + +- if (size < ETH_HLEN || size > PAGE_SIZE - headroom - tailroom) ++ if (user_size < ETH_HLEN || user_size > PAGE_SIZE - headroom - tailroom) + return ERR_PTR(-EINVAL); + +- if (user_size > size) +- return ERR_PTR(-EMSGSIZE); +- + size = SKB_DATA_ALIGN(size); + data = kzalloc(size + headroom + tailroom, GFP_USER); + if (!data) +diff --git a/net/core/dev.c b/net/core/dev.c +index 479a3892f98c3c..8c30cdcf05d4bd 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -954,6 +954,12 @@ int netdev_get_name(struct net *net, char *name, int ifindex) + return ret; + } + ++static bool dev_addr_cmp(struct net_device *dev, unsigned short type, ++ const char *ha) ++{ ++ return dev->type == type && !memcmp(dev->dev_addr, ha, dev->addr_len); ++} ++ + /** + * dev_getbyhwaddr_rcu - find a device by its hardware address + * @net: the applicable net namespace +@@ -962,7 +968,7 @@ int netdev_get_name(struct net *net, char *name, int ifindex) + * + * Search for an interface by MAC address. Returns NULL if the device + * is not found or a pointer to the device. +- * The caller must hold RCU or RTNL. ++ * The caller must hold RCU. + * The returned device has not had its ref count increased + * and the caller must therefore be careful about locking + * +@@ -974,14 +980,39 @@ struct net_device *dev_getbyhwaddr_rcu(struct net *net, unsigned short type, + struct net_device *dev; + + for_each_netdev_rcu(net, dev) +- if (dev->type == type && +- !memcmp(dev->dev_addr, ha, dev->addr_len)) ++ if (dev_addr_cmp(dev, type, ha)) + return dev; + + return NULL; + } + EXPORT_SYMBOL(dev_getbyhwaddr_rcu); + ++/** ++ * dev_getbyhwaddr() - find a device by its hardware address ++ * @net: the applicable net namespace ++ * @type: media type of device ++ * @ha: hardware address ++ * ++ * Similar to dev_getbyhwaddr_rcu(), but the owner needs to hold ++ * rtnl_lock. ++ * ++ * Context: rtnl_lock() must be held. ++ * Return: pointer to the net_device, or NULL if not found ++ */ ++struct net_device *dev_getbyhwaddr(struct net *net, unsigned short type, ++ const char *ha) ++{ ++ struct net_device *dev; ++ ++ ASSERT_RTNL(); ++ for_each_netdev(net, dev) ++ if (dev_addr_cmp(dev, type, ha)) ++ return dev; ++ ++ return NULL; ++} ++EXPORT_SYMBOL(dev_getbyhwaddr); ++ + struct net_device *dev_getfirstbyhwtype(struct net *net, unsigned short type) + { + struct net_device *dev, *ret = NULL; +diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c +index 58843a52bad0e7..fccda85ce8fe1f 100644 +--- a/net/core/drop_monitor.c ++++ b/net/core/drop_monitor.c +@@ -1731,30 +1731,30 @@ static int __init init_net_drop_monitor(void) + return -ENOSPC; + } + +- rc = genl_register_family(&net_drop_monitor_family); +- if (rc) { +- pr_err("Could not create drop monitor netlink family\n"); +- return rc; ++ for_each_possible_cpu(cpu) { ++ net_dm_cpu_data_init(cpu); ++ net_dm_hw_cpu_data_init(cpu); + } +- WARN_ON(net_drop_monitor_family.mcgrp_offset != NET_DM_GRP_ALERT); + + rc = register_netdevice_notifier(&dropmon_net_notifier); + if (rc < 0) { + pr_crit("Failed to register netdevice notifier\n"); ++ return rc; ++ } ++ ++ rc = genl_register_family(&net_drop_monitor_family); ++ if (rc) { ++ pr_err("Could not create drop monitor netlink family\n"); + goto out_unreg; + } ++ WARN_ON(net_drop_monitor_family.mcgrp_offset != NET_DM_GRP_ALERT); + + rc = 0; + +- for_each_possible_cpu(cpu) { +- net_dm_cpu_data_init(cpu); +- net_dm_hw_cpu_data_init(cpu); +- } +- + goto out; + + out_unreg: +- genl_unregister_family(&net_drop_monitor_family); ++ WARN_ON(unregister_netdevice_notifier(&dropmon_net_notifier)); + out: + return rc; + } +@@ -1763,19 +1763,18 @@ static void exit_net_drop_monitor(void) + { + int cpu; + +- BUG_ON(unregister_netdevice_notifier(&dropmon_net_notifier)); +- + /* + * Because of the module_get/put we do in the trace state change path + * we are guaranteed not to have any current users when we get here + */ ++ BUG_ON(genl_unregister_family(&net_drop_monitor_family)); ++ ++ BUG_ON(unregister_netdevice_notifier(&dropmon_net_notifier)); + + for_each_possible_cpu(cpu) { + net_dm_hw_cpu_data_fini(cpu); + net_dm_cpu_data_fini(cpu); + } +- +- BUG_ON(genl_unregister_family(&net_drop_monitor_family)); + } + + module_init(init_net_drop_monitor); +diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c +index 00a5c41c1831df..aafa754b6cbab9 100644 +--- a/net/core/flow_dissector.c ++++ b/net/core/flow_dissector.c +@@ -829,23 +829,30 @@ __skb_flow_dissect_ports(const struct sk_buff *skb, + void *target_container, const void *data, + int nhoff, u8 ip_proto, int hlen) + { +- enum flow_dissector_key_id dissector_ports = FLOW_DISSECTOR_KEY_MAX; +- struct flow_dissector_key_ports *key_ports; ++ struct flow_dissector_key_ports_range *key_ports_range = NULL; ++ struct flow_dissector_key_ports *key_ports = NULL; ++ __be32 ports; + + if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_PORTS)) +- dissector_ports = FLOW_DISSECTOR_KEY_PORTS; +- else if (dissector_uses_key(flow_dissector, +- FLOW_DISSECTOR_KEY_PORTS_RANGE)) +- dissector_ports = FLOW_DISSECTOR_KEY_PORTS_RANGE; ++ key_ports = skb_flow_dissector_target(flow_dissector, ++ FLOW_DISSECTOR_KEY_PORTS, ++ target_container); + +- if (dissector_ports == FLOW_DISSECTOR_KEY_MAX) ++ if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_PORTS_RANGE)) ++ key_ports_range = skb_flow_dissector_target(flow_dissector, ++ FLOW_DISSECTOR_KEY_PORTS_RANGE, ++ target_container); ++ ++ if (!key_ports && !key_ports_range) + return; + +- key_ports = skb_flow_dissector_target(flow_dissector, +- dissector_ports, +- target_container); +- key_ports->ports = __skb_flow_get_ports(skb, nhoff, ip_proto, +- data, hlen); ++ ports = __skb_flow_get_ports(skb, nhoff, ip_proto, data, hlen); ++ ++ if (key_ports) ++ key_ports->ports = ports; ++ ++ if (key_ports_range) ++ key_ports_range->tp.ports = ports; + } + + static void +@@ -900,6 +907,7 @@ static void __skb_flow_bpf_to_target(const struct bpf_flow_keys *flow_keys, + struct flow_dissector *flow_dissector, + void *target_container) + { ++ struct flow_dissector_key_ports_range *key_ports_range = NULL; + struct flow_dissector_key_ports *key_ports = NULL; + struct flow_dissector_key_control *key_control; + struct flow_dissector_key_basic *key_basic; +@@ -944,20 +952,21 @@ static void __skb_flow_bpf_to_target(const struct bpf_flow_keys *flow_keys, + key_control->addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS; + } + +- if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_PORTS)) ++ if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_PORTS)) { + key_ports = skb_flow_dissector_target(flow_dissector, + FLOW_DISSECTOR_KEY_PORTS, + target_container); +- else if (dissector_uses_key(flow_dissector, +- FLOW_DISSECTOR_KEY_PORTS_RANGE)) +- key_ports = skb_flow_dissector_target(flow_dissector, +- FLOW_DISSECTOR_KEY_PORTS_RANGE, +- target_container); +- +- if (key_ports) { + key_ports->src = flow_keys->sport; + key_ports->dst = flow_keys->dport; + } ++ if (dissector_uses_key(flow_dissector, ++ FLOW_DISSECTOR_KEY_PORTS_RANGE)) { ++ key_ports_range = skb_flow_dissector_target(flow_dissector, ++ FLOW_DISSECTOR_KEY_PORTS_RANGE, ++ target_container); ++ key_ports_range->tp.src = flow_keys->sport; ++ key_ports_range->tp.dst = flow_keys->dport; ++ } + + if (dissector_uses_key(flow_dissector, + FLOW_DISSECTOR_KEY_FLOW_LABEL)) { +diff --git a/net/core/skmsg.c b/net/core/skmsg.c +index 902098e221b396..b9b941c487c8a7 100644 +--- a/net/core/skmsg.c ++++ b/net/core/skmsg.c +@@ -548,6 +548,9 @@ static int sk_psock_skb_ingress_enqueue(struct sk_buff *skb, + return num_sge; + } + ++#if IS_ENABLED(CONFIG_BPF_STREAM_PARSER) ++ psock->ingress_bytes += len; ++#endif + copied = len; + msg->sg.start = 0; + msg->sg.size = copied; +@@ -1143,6 +1146,10 @@ int sk_psock_init_strp(struct sock *sk, struct sk_psock *psock) + if (!ret) + sk_psock_set_state(psock, SK_PSOCK_RX_STRP_ENABLED); + ++ if (sk_is_tcp(sk)) { ++ psock->strp.cb.read_sock = tcp_bpf_strp_read_sock; ++ psock->copied_seq = tcp_sk(sk)->copied_seq; ++ } + return ret; + } + +diff --git a/net/core/sock_map.c b/net/core/sock_map.c +index f37a26efdd8abe..3a53b6a0e76e2b 100644 +--- a/net/core/sock_map.c ++++ b/net/core/sock_map.c +@@ -300,7 +300,10 @@ static int sock_map_link(struct bpf_map *map, struct sock *sk) + + write_lock_bh(&sk->sk_callback_lock); + if (stream_parser && stream_verdict && !psock->saved_data_ready) { +- ret = sk_psock_init_strp(sk, psock); ++ if (sk_is_tcp(sk)) ++ ret = sk_psock_init_strp(sk, psock); ++ else ++ ret = -EOPNOTSUPP; + if (ret) { + write_unlock_bh(&sk->sk_callback_lock); + sk_psock_put(sk, psock); +@@ -538,6 +541,9 @@ static bool sock_map_sk_state_allowed(const struct sock *sk) + return (1 << sk->sk_state) & (TCPF_ESTABLISHED | TCPF_LISTEN); + if (sk_is_stream_unix(sk)) + return (1 << sk->sk_state) & TCPF_ESTABLISHED; ++ if (sk_is_vsock(sk) && ++ (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET)) ++ return (1 << sk->sk_state) & TCPF_ESTABLISHED; + return true; + } + +diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c +index 02776453bf97a8..784dc8b37be5a2 100644 +--- a/net/ipv4/arp.c ++++ b/net/ipv4/arp.c +@@ -1030,7 +1030,7 @@ static int arp_req_set_public(struct net *net, struct arpreq *r, + if (mask && mask != htonl(0xFFFFFFFF)) + return -EINVAL; + if (!dev && (r->arp_flags & ATF_COM)) { +- dev = dev_getbyhwaddr_rcu(net, r->arp_ha.sa_family, ++ dev = dev_getbyhwaddr(net, r->arp_ha.sa_family, + r->arp_ha.sa_data); + if (!dev) + return -ENODEV; +diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c +index 5e6615f69f175d..7ad82be40f348d 100644 +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -1553,12 +1553,13 @@ EXPORT_SYMBOL(tcp_recv_skb); + * or for 'peeking' the socket using this routine + * (although both would be easy to implement). + */ +-int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, +- sk_read_actor_t recv_actor) ++static int __tcp_read_sock(struct sock *sk, read_descriptor_t *desc, ++ sk_read_actor_t recv_actor, bool noack, ++ u32 *copied_seq) + { + struct sk_buff *skb; + struct tcp_sock *tp = tcp_sk(sk); +- u32 seq = tp->copied_seq; ++ u32 seq = *copied_seq; + u32 offset; + int copied = 0; + +@@ -1612,9 +1613,12 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, + tcp_eat_recv_skb(sk, skb); + if (!desc->count) + break; +- WRITE_ONCE(tp->copied_seq, seq); ++ WRITE_ONCE(*copied_seq, seq); + } +- WRITE_ONCE(tp->copied_seq, seq); ++ WRITE_ONCE(*copied_seq, seq); ++ ++ if (noack) ++ goto out; + + tcp_rcv_space_adjust(sk); + +@@ -1623,10 +1627,25 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, + tcp_recv_skb(sk, seq, &offset); + tcp_cleanup_rbuf(sk, copied); + } ++out: + return copied; + } ++ ++int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, ++ sk_read_actor_t recv_actor) ++{ ++ return __tcp_read_sock(sk, desc, recv_actor, false, ++ &tcp_sk(sk)->copied_seq); ++} + EXPORT_SYMBOL(tcp_read_sock); + ++int tcp_read_sock_noack(struct sock *sk, read_descriptor_t *desc, ++ sk_read_actor_t recv_actor, bool noack, ++ u32 *copied_seq) ++{ ++ return __tcp_read_sock(sk, desc, recv_actor, noack, copied_seq); ++} ++ + int tcp_read_skb(struct sock *sk, skb_read_actor_t recv_actor) + { + struct sk_buff *skb; +diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c +index f882054fae5ee1..5312237e804093 100644 +--- a/net/ipv4/tcp_bpf.c ++++ b/net/ipv4/tcp_bpf.c +@@ -646,6 +646,42 @@ static int tcp_bpf_assert_proto_ops(struct proto *ops) + ops->sendmsg == tcp_sendmsg ? 0 : -ENOTSUPP; + } + ++#if IS_ENABLED(CONFIG_BPF_STREAM_PARSER) ++int tcp_bpf_strp_read_sock(struct strparser *strp, read_descriptor_t *desc, ++ sk_read_actor_t recv_actor) ++{ ++ struct sock *sk = strp->sk; ++ struct sk_psock *psock; ++ struct tcp_sock *tp; ++ int copied = 0; ++ ++ tp = tcp_sk(sk); ++ rcu_read_lock(); ++ psock = sk_psock(sk); ++ if (WARN_ON_ONCE(!psock)) { ++ desc->error = -EINVAL; ++ goto out; ++ } ++ ++ psock->ingress_bytes = 0; ++ copied = tcp_read_sock_noack(sk, desc, recv_actor, true, ++ &psock->copied_seq); ++ if (copied < 0) ++ goto out; ++ /* recv_actor may redirect skb to another socket (SK_REDIRECT) or ++ * just put skb into ingress queue of current socket (SK_PASS). ++ * For SK_REDIRECT, we need to ack the frame immediately but for ++ * SK_PASS, we want to delay the ack until tcp_bpf_recvmsg_parser(). ++ */ ++ tp->copied_seq = psock->copied_seq - psock->ingress_bytes; ++ tcp_rcv_space_adjust(sk); ++ __tcp_cleanup_rbuf(sk, copied - psock->ingress_bytes); ++out: ++ rcu_read_unlock(); ++ return copied; ++} ++#endif /* CONFIG_BPF_STREAM_PARSER */ ++ + int tcp_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool restore) + { + int family = sk->sk_family == AF_INET6 ? TCP_BPF_IPV6 : TCP_BPF_IPV4; +diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c +index 0f523cbfe329ef..32b28fc21b63c0 100644 +--- a/net/ipv4/tcp_fastopen.c ++++ b/net/ipv4/tcp_fastopen.c +@@ -178,7 +178,7 @@ void tcp_fastopen_add_skb(struct sock *sk, struct sk_buff *skb) + if (!skb) + return; + +- skb_dst_drop(skb); ++ tcp_cleanup_skb(skb); + /* segs_in has been initialized to 1 in tcp_create_openreq_child(). + * Hence, reset segs_in to 0 before calling tcp_segs_in() + * to avoid double counting. Also, tcp_segs_in() expects +@@ -195,7 +195,7 @@ void tcp_fastopen_add_skb(struct sock *sk, struct sk_buff *skb) + TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_SYN; + + tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq; +- __skb_queue_tail(&sk->sk_receive_queue, skb); ++ tcp_add_receive_queue(sk, skb); + tp->syn_data_acked = 1; + + /* u64_stats_update_begin(&tp->syncp) not needed here, +diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c +index f6a213bae5cccb..10d38ec0ff5acd 100644 +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -248,9 +248,15 @@ static void tcp_measure_rcv_mss(struct sock *sk, const struct sk_buff *skb) + do_div(val, skb->truesize); + tcp_sk(sk)->scaling_ratio = val ? val : 1; + +- if (old_ratio != tcp_sk(sk)->scaling_ratio) +- WRITE_ONCE(tcp_sk(sk)->window_clamp, +- tcp_win_from_space(sk, sk->sk_rcvbuf)); ++ if (old_ratio != tcp_sk(sk)->scaling_ratio) { ++ struct tcp_sock *tp = tcp_sk(sk); ++ ++ val = tcp_win_from_space(sk, sk->sk_rcvbuf); ++ tcp_set_window_clamp(sk, val); ++ ++ if (tp->window_clamp < tp->rcvq_space.space) ++ tp->rcvq_space.space = tp->window_clamp; ++ } + } + icsk->icsk_ack.rcv_mss = min_t(unsigned int, len, + tcp_sk(sk)->advmss); +@@ -4868,7 +4874,7 @@ static void tcp_ofo_queue(struct sock *sk) + tcp_rcv_nxt_update(tp, TCP_SKB_CB(skb)->end_seq); + fin = TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN; + if (!eaten) +- __skb_queue_tail(&sk->sk_receive_queue, skb); ++ tcp_add_receive_queue(sk, skb); + else + kfree_skb_partial(skb, fragstolen); + +@@ -5059,7 +5065,7 @@ static int __must_check tcp_queue_rcv(struct sock *sk, struct sk_buff *skb, + skb, fragstolen)) ? 1 : 0; + tcp_rcv_nxt_update(tcp_sk(sk), TCP_SKB_CB(skb)->end_seq); + if (!eaten) { +- __skb_queue_tail(&sk->sk_receive_queue, skb); ++ tcp_add_receive_queue(sk, skb); + skb_set_owner_r(skb, sk); + } + return eaten; +@@ -5142,7 +5148,7 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) + __kfree_skb(skb); + return; + } +- skb_dst_drop(skb); ++ tcp_cleanup_skb(skb); + __skb_pull(skb, tcp_hdr(skb)->doff * 4); + + reason = SKB_DROP_REASON_NOT_SPECIFIED; +@@ -6092,7 +6098,7 @@ void tcp_rcv_established(struct sock *sk, struct sk_buff *skb) + NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPHPHITS); + + /* Bulk data transfer: receiver */ +- skb_dst_drop(skb); ++ tcp_cleanup_skb(skb); + __skb_pull(skb, tcp_header_len); + eaten = tcp_queue_rcv(sk, skb, &fragstolen); + +diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c +index 705320f160ac86..2f49a504c9d3e3 100644 +--- a/net/ipv4/tcp_ipv4.c ++++ b/net/ipv4/tcp_ipv4.c +@@ -1842,7 +1842,7 @@ bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb, + */ + skb_condense(skb); + +- skb_dst_drop(skb); ++ tcp_cleanup_skb(skb); + + if (unlikely(tcp_checksum_complete(skb))) { + bh_unlock_sock(sk); +diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c +index 84e18b5f72a305..96c39e9a873c75 100644 +--- a/net/sched/cls_api.c ++++ b/net/sched/cls_api.c +@@ -97,7 +97,7 @@ tcf_exts_miss_cookie_base_alloc(struct tcf_exts *exts, struct tcf_proto *tp, + + err = xa_alloc_cyclic(&tcf_exts_miss_cookies_xa, &n->miss_cookie_base, + n, xa_limit_32b, &next, GFP_KERNEL); +- if (err) ++ if (err < 0) + goto err_xa_alloc; + + exts->miss_cookie_node = n; +diff --git a/net/strparser/strparser.c b/net/strparser/strparser.c +index 8299ceb3e3739d..95696f42647ec1 100644 +--- a/net/strparser/strparser.c ++++ b/net/strparser/strparser.c +@@ -347,7 +347,10 @@ static int strp_read_sock(struct strparser *strp) + struct socket *sock = strp->sk->sk_socket; + read_descriptor_t desc; + +- if (unlikely(!sock || !sock->ops || !sock->ops->read_sock)) ++ if (unlikely(!sock || !sock->ops)) ++ return -EBUSY; ++ ++ if (unlikely(!strp->cb.read_sock && !sock->ops->read_sock)) + return -EBUSY; + + desc.arg.data = strp; +@@ -355,7 +358,10 @@ static int strp_read_sock(struct strparser *strp) + desc.count = 1; /* give more than one skb per call */ + + /* sk should be locked here, so okay to do read_sock */ +- sock->ops->read_sock(strp->sk, &desc, strp_recv); ++ if (strp->cb.read_sock) ++ strp->cb.read_sock(strp, &desc, strp_recv); ++ else ++ sock->ops->read_sock(strp->sk, &desc, strp_recv); + + desc.error = strp->cb.read_sock_done(strp, desc.error); + +@@ -468,6 +474,7 @@ int strp_init(struct strparser *strp, struct sock *sk, + strp->cb.unlock = cb->unlock ? : strp_sock_unlock; + strp->cb.rcv_msg = cb->rcv_msg; + strp->cb.parse_msg = cb->parse_msg; ++ strp->cb.read_sock = cb->read_sock; + strp->cb.read_sock_done = cb->read_sock_done ? : default_read_sock_done; + strp->cb.abort_parser = cb->abort_parser ? : strp_abort_strp; + +diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c +index 618b18e80cea04..622875a6f787ca 100644 +--- a/net/vmw_vsock/af_vsock.c ++++ b/net/vmw_vsock/af_vsock.c +@@ -1185,6 +1185,9 @@ static int vsock_read_skb(struct sock *sk, skb_read_actor_t read_actor) + { + struct vsock_sock *vsk = vsock_sk(sk); + ++ if (WARN_ON_ONCE(!vsk->transport)) ++ return -ENODEV; ++ + return vsk->transport->read_skb(vsk, read_actor); + } + +diff --git a/net/vmw_vsock/vsock_bpf.c b/net/vmw_vsock/vsock_bpf.c +index f201d9eca1df2f..07b96d56f3a577 100644 +--- a/net/vmw_vsock/vsock_bpf.c ++++ b/net/vmw_vsock/vsock_bpf.c +@@ -87,7 +87,7 @@ static int vsock_bpf_recvmsg(struct sock *sk, struct msghdr *msg, + lock_sock(sk); + vsk = vsock_sk(sk); + +- if (!vsk->transport) { ++ if (WARN_ON_ONCE(!vsk->transport)) { + copied = -ENODEV; + goto out; + } +diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c +index 8b7dfbc8e82075..54931ad0dc990f 100644 +--- a/sound/core/seq/seq_clientmgr.c ++++ b/sound/core/seq/seq_clientmgr.c +@@ -682,12 +682,18 @@ static int snd_seq_deliver_single_event(struct snd_seq_client *client, + dest_port->time_real); + + #if IS_ENABLED(CONFIG_SND_SEQ_UMP) +- if (!(dest->filter & SNDRV_SEQ_FILTER_NO_CONVERT)) { +- if (snd_seq_ev_is_ump(event)) { ++ if (snd_seq_ev_is_ump(event)) { ++ if (!(dest->filter & SNDRV_SEQ_FILTER_NO_CONVERT)) { + result = snd_seq_deliver_from_ump(client, dest, dest_port, + event, atomic, hop); + goto __skip; +- } else if (snd_seq_client_is_ump(dest)) { ++ } else if (dest->type == USER_CLIENT && ++ !snd_seq_client_is_ump(dest)) { ++ result = 0; // drop the event ++ goto __skip; ++ } ++ } else if (snd_seq_client_is_ump(dest)) { ++ if (!(dest->filter & SNDRV_SEQ_FILTER_NO_CONVERT)) { + result = snd_seq_deliver_to_ump(client, dest, dest_port, + event, atomic, hop); + goto __skip; +diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c +index 33af707a65ab11..aa6dc00985b514 100644 +--- a/sound/pci/hda/hda_codec.c ++++ b/sound/pci/hda/hda_codec.c +@@ -2463,7 +2463,9 @@ int snd_hda_create_dig_out_ctls(struct hda_codec *codec, + break; + id = kctl->id; + id.index = spdif_index; +- snd_ctl_rename_id(codec->card, &kctl->id, &id); ++ err = snd_ctl_rename_id(codec->card, &kctl->id, &id); ++ if (err < 0) ++ return err; + } + bus->primary_dig_out_type = HDA_PCM_TYPE_HDMI; + } +diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c +index 989ce0fb62919f..157efd1530fbf3 100644 +--- a/sound/pci/hda/patch_conexant.c ++++ b/sound/pci/hda/patch_conexant.c +@@ -1084,6 +1084,7 @@ static const struct hda_quirk cxt5066_fixups[] = { + SND_PCI_QUIRK(0x103c, 0x814f, "HP ZBook 15u G3", CXT_FIXUP_MUTE_LED_GPIO), + SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE), + SND_PCI_QUIRK(0x103c, 0x822e, "HP ProBook 440 G4", CXT_FIXUP_MUTE_LED_GPIO), ++ SND_PCI_QUIRK(0x103c, 0x8231, "HP ProBook 450 G4", CXT_FIXUP_MUTE_LED_GPIO), + SND_PCI_QUIRK(0x103c, 0x828c, "HP EliteBook 840 G4", CXT_FIXUP_HP_DOCK), + SND_PCI_QUIRK(0x103c, 0x8299, "HP 800 G3 SFF", CXT_FIXUP_HP_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x103c, 0x829a, "HP 800 G3 DM", CXT_FIXUP_HP_MIC_NO_PRESENCE), +diff --git a/sound/pci/hda/patch_cs8409-tables.c b/sound/pci/hda/patch_cs8409-tables.c +index 759f48038273df..621f947e38174d 100644 +--- a/sound/pci/hda/patch_cs8409-tables.c ++++ b/sound/pci/hda/patch_cs8409-tables.c +@@ -121,7 +121,7 @@ static const struct cs8409_i2c_param cs42l42_init_reg_seq[] = { + { CS42L42_MIXER_CHA_VOL, 0x3F }, + { CS42L42_MIXER_CHB_VOL, 0x3F }, + { CS42L42_MIXER_ADC_VOL, 0x3f }, +- { CS42L42_HP_CTL, 0x03 }, ++ { CS42L42_HP_CTL, 0x0D }, + { CS42L42_MIC_DET_CTL1, 0xB6 }, + { CS42L42_TIPSENSE_CTL, 0xC2 }, + { CS42L42_HS_CLAMP_DISABLE, 0x01 }, +@@ -315,7 +315,7 @@ static const struct cs8409_i2c_param dolphin_c0_init_reg_seq[] = { + { CS42L42_ASP_TX_SZ_EN, 0x01 }, + { CS42L42_PWR_CTL1, 0x0A }, + { CS42L42_PWR_CTL2, 0x84 }, +- { CS42L42_HP_CTL, 0x03 }, ++ { CS42L42_HP_CTL, 0x0D }, + { CS42L42_MIXER_CHA_VOL, 0x3F }, + { CS42L42_MIXER_CHB_VOL, 0x3F }, + { CS42L42_MIXER_ADC_VOL, 0x3f }, +@@ -371,7 +371,7 @@ static const struct cs8409_i2c_param dolphin_c1_init_reg_seq[] = { + { CS42L42_ASP_TX_SZ_EN, 0x00 }, + { CS42L42_PWR_CTL1, 0x0E }, + { CS42L42_PWR_CTL2, 0x84 }, +- { CS42L42_HP_CTL, 0x01 }, ++ { CS42L42_HP_CTL, 0x0D }, + { CS42L42_MIXER_CHA_VOL, 0x3F }, + { CS42L42_MIXER_CHB_VOL, 0x3F }, + { CS42L42_MIXER_ADC_VOL, 0x3f }, +diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c +index 892223d9e64aba..b003ac1990ba86 100644 +--- a/sound/pci/hda/patch_cs8409.c ++++ b/sound/pci/hda/patch_cs8409.c +@@ -876,7 +876,7 @@ static void cs42l42_resume(struct sub_codec *cs42l42) + { CS42L42_DET_INT_STATUS2, 0x00 }, + { CS42L42_TSRS_PLUG_STATUS, 0x00 }, + }; +- int fsv_old, fsv_new; ++ unsigned int fsv; + + /* Bring CS42L42 out of Reset */ + spec->gpio_data = snd_hda_codec_read(codec, CS8409_PIN_AFG, 0, AC_VERB_GET_GPIO_DATA, 0); +@@ -893,13 +893,15 @@ static void cs42l42_resume(struct sub_codec *cs42l42) + /* Clear interrupts, by reading interrupt status registers */ + cs8409_i2c_bulk_read(cs42l42, irq_regs, ARRAY_SIZE(irq_regs)); + +- fsv_old = cs8409_i2c_read(cs42l42, CS42L42_HP_CTL); +- if (cs42l42->full_scale_vol == CS42L42_FULL_SCALE_VOL_0DB) +- fsv_new = fsv_old & ~CS42L42_FULL_SCALE_VOL_MASK; +- else +- fsv_new = fsv_old & CS42L42_FULL_SCALE_VOL_MASK; +- if (fsv_new != fsv_old) +- cs8409_i2c_write(cs42l42, CS42L42_HP_CTL, fsv_new); ++ fsv = cs8409_i2c_read(cs42l42, CS42L42_HP_CTL); ++ if (cs42l42->full_scale_vol) { ++ // Set the full scale volume bit ++ fsv |= CS42L42_FULL_SCALE_VOL_MASK; ++ cs8409_i2c_write(cs42l42, CS42L42_HP_CTL, fsv); ++ } ++ // Unmute analog channels A and B ++ fsv = (fsv & ~CS42L42_ANA_MUTE_AB); ++ cs8409_i2c_write(cs42l42, CS42L42_HP_CTL, fsv); + + /* we have to explicitly allow unsol event handling even during the + * resume phase so that the jack event is processed properly +@@ -921,7 +923,7 @@ static void cs42l42_suspend(struct sub_codec *cs42l42) + { CS42L42_MIXER_CHA_VOL, 0x3F }, + { CS42L42_MIXER_ADC_VOL, 0x3F }, + { CS42L42_MIXER_CHB_VOL, 0x3F }, +- { CS42L42_HP_CTL, 0x0F }, ++ { CS42L42_HP_CTL, 0x0D }, + { CS42L42_ASP_RX_DAI0_EN, 0x00 }, + { CS42L42_ASP_CLK_CFG, 0x00 }, + { CS42L42_PWR_CTL1, 0xFE }, +diff --git a/sound/pci/hda/patch_cs8409.h b/sound/pci/hda/patch_cs8409.h +index 5e48115caf096b..14645d25e70fd2 100644 +--- a/sound/pci/hda/patch_cs8409.h ++++ b/sound/pci/hda/patch_cs8409.h +@@ -230,9 +230,10 @@ enum cs8409_coefficient_index_registers { + #define CS42L42_PDN_TIMEOUT_US (250000) + #define CS42L42_PDN_SLEEP_US (2000) + #define CS42L42_INIT_TIMEOUT_MS (45) ++#define CS42L42_ANA_MUTE_AB (0x0C) + #define CS42L42_FULL_SCALE_VOL_MASK (2) +-#define CS42L42_FULL_SCALE_VOL_0DB (1) +-#define CS42L42_FULL_SCALE_VOL_MINUS6DB (0) ++#define CS42L42_FULL_SCALE_VOL_0DB (0) ++#define CS42L42_FULL_SCALE_VOL_MINUS6DB (1) + + /* Dell BULLSEYE / WARLOCK / CYBORG Specific Definitions */ + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index abe3d5b9b84b3e..75162e5f712b40 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -3779,6 +3779,7 @@ static void alc225_init(struct hda_codec *codec) + AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); + + msleep(75); ++ alc_update_coef_idx(codec, 0x4a, 3 << 10, 0); + alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */ + } + } +diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c +index f57f0ab8a1add1..80ff1d1359f64c 100644 +--- a/sound/soc/fsl/fsl_micfil.c ++++ b/sound/soc/fsl/fsl_micfil.c +@@ -156,6 +156,8 @@ static int micfil_set_quality(struct fsl_micfil *micfil) + case QUALITY_VLOW2: + qsel = MICFIL_QSEL_VLOW2_QUALITY; + break; ++ default: ++ return -EINVAL; + } + + return regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL2, +diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.c b/sound/soc/rockchip/rockchip_i2s_tdm.c +index 14e5c53e697b0e..7ae93cbaea9a77 100644 +--- a/sound/soc/rockchip/rockchip_i2s_tdm.c ++++ b/sound/soc/rockchip/rockchip_i2s_tdm.c +@@ -453,11 +453,11 @@ static int rockchip_i2s_tdm_set_fmt(struct snd_soc_dai *cpu_dai, + break; + case SND_SOC_DAIFMT_DSP_A: + val = I2S_TXCR_TFS_TDM_PCM; +- tdm_val = TDM_SHIFT_CTRL(0); ++ tdm_val = TDM_SHIFT_CTRL(2); + break; + case SND_SOC_DAIFMT_DSP_B: + val = I2S_TXCR_TFS_TDM_PCM; +- tdm_val = TDM_SHIFT_CTRL(2); ++ tdm_val = TDM_SHIFT_CTRL(4); + break; + default: + ret = -EINVAL; +diff --git a/sound/soc/sh/rz-ssi.c b/sound/soc/sh/rz-ssi.c +index 353863f49b3131..54f096bdc7ee27 100644 +--- a/sound/soc/sh/rz-ssi.c ++++ b/sound/soc/sh/rz-ssi.c +@@ -484,6 +484,8 @@ static int rz_ssi_pio_send(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm) + sample_space = strm->fifo_sample_size; + ssifsr = rz_ssi_reg_readl(ssi, SSIFSR); + sample_space -= (ssifsr >> SSIFSR_TDC_SHIFT) & SSIFSR_TDC_MASK; ++ if (sample_space < 0) ++ return -EINVAL; + + /* Only add full frames at a time */ + while (frames_left && (sample_space >= runtime->channels)) { +diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c +index 8e602e42afee23..7a8eebb078e83d 100644 +--- a/sound/soc/sof/pcm.c ++++ b/sound/soc/sof/pcm.c +@@ -507,6 +507,8 @@ static int sof_pcm_close(struct snd_soc_component *component, + */ + } + ++ spcm->stream[substream->stream].substream = NULL; ++ + return 0; + } + +diff --git a/sound/soc/sof/stream-ipc.c b/sound/soc/sof/stream-ipc.c +index 216b454f6b94e3..3edcb0ea38488c 100644 +--- a/sound/soc/sof/stream-ipc.c ++++ b/sound/soc/sof/stream-ipc.c +@@ -43,7 +43,7 @@ int sof_ipc_msg_data(struct snd_sof_dev *sdev, + return -ESTRPIPE; + + posn_offset = stream->posn_offset; +- } else { ++ } else if (sps->cstream) { + + struct sof_compr_stream *sstream = sps->cstream->runtime->private_data; + +@@ -51,6 +51,10 @@ int sof_ipc_msg_data(struct snd_sof_dev *sdev, + return -ESTRPIPE; + + posn_offset = sstream->posn_offset; ++ ++ } else { ++ dev_err(sdev->dev, "%s: No stream opened\n", __func__); ++ return -EINVAL; + } + + snd_sof_dsp_mailbox_read(sdev, posn_offset, p, sz); diff --git a/patch/kernel/archive/odroidxu4-6.6/patch-6.6.80-81.patch b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.80-81.patch new file mode 100644 index 000000000000..6ca4d5297aa5 --- /dev/null +++ b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.80-81.patch @@ -0,0 +1,8344 @@ +diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt +index d83a3f47e20074..184f2f96f6a547 100644 +--- a/Documentation/admin-guide/kernel-parameters.txt ++++ b/Documentation/admin-guide/kernel-parameters.txt +@@ -3287,6 +3287,11 @@ + + mga= [HW,DRM] + ++ microcode.force_minrev= [X86] ++ Format: ++ Enable or disable the microcode minimal revision ++ enforcement for the runtime microcode loader. ++ + min_addr=nn[KMG] [KNL,BOOT,IA-64] All physical memory below this + physical address is ignored. + +diff --git a/Makefile b/Makefile +index 67c5799f259e2e..892ed237b1e1b6 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 6 + PATCHLEVEL = 6 +-SUBLEVEL = 80 ++SUBLEVEL = 81 + EXTRAVERSION = + NAME = Pinguïn Aangedreven + +diff --git a/arch/arm64/boot/dts/rockchip/px30-ringneck.dtsi b/arch/arm64/boot/dts/rockchip/px30-ringneck.dtsi +index 5fcc5f32be2d79..2963d634baba99 100644 +--- a/arch/arm64/boot/dts/rockchip/px30-ringneck.dtsi ++++ b/arch/arm64/boot/dts/rockchip/px30-ringneck.dtsi +@@ -367,6 +367,11 @@ &u2phy_host { + status = "okay"; + }; + ++&uart5 { ++ /delete-property/ dmas; ++ /delete-property/ dma-names; ++}; ++ + /* Mule UCAN */ + &usb_host0_ehci { + status = "okay"; +diff --git a/arch/riscv/include/asm/futex.h b/arch/riscv/include/asm/futex.h +index fc8130f995c1ee..6907c456ac8c05 100644 +--- a/arch/riscv/include/asm/futex.h ++++ b/arch/riscv/include/asm/futex.h +@@ -93,7 +93,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, + _ASM_EXTABLE_UACCESS_ERR(1b, 3b, %[r]) \ + _ASM_EXTABLE_UACCESS_ERR(2b, 3b, %[r]) \ + : [r] "+r" (ret), [v] "=&r" (val), [u] "+m" (*uaddr), [t] "=&r" (tmp) +- : [ov] "Jr" (oldval), [nv] "Jr" (newval) ++ : [ov] "Jr" ((long)(int)oldval), [nv] "Jr" (newval) + : "memory"); + __disable_user_access(); + +diff --git a/arch/riscv/include/asm/kvm_host.h b/arch/riscv/include/asm/kvm_host.h +index 1ebf20dfbaa698..459e61ad7d2b68 100644 +--- a/arch/riscv/include/asm/kvm_host.h ++++ b/arch/riscv/include/asm/kvm_host.h +@@ -236,8 +236,9 @@ struct kvm_vcpu_arch { + /* Cache pages needed to program page tables with spinlock held */ + struct kvm_mmu_memory_cache mmu_page_cache; + +- /* VCPU power-off state */ +- bool power_off; ++ /* VCPU power state */ ++ struct kvm_mp_state mp_state; ++ spinlock_t mp_state_lock; + + /* Don't run the VCPU (blocked) */ + bool pause; +@@ -351,7 +352,10 @@ int kvm_riscv_vcpu_unset_interrupt(struct kvm_vcpu *vcpu, unsigned int irq); + void kvm_riscv_vcpu_flush_interrupts(struct kvm_vcpu *vcpu); + void kvm_riscv_vcpu_sync_interrupts(struct kvm_vcpu *vcpu); + bool kvm_riscv_vcpu_has_interrupts(struct kvm_vcpu *vcpu, u64 mask); ++void __kvm_riscv_vcpu_power_off(struct kvm_vcpu *vcpu); + void kvm_riscv_vcpu_power_off(struct kvm_vcpu *vcpu); ++void __kvm_riscv_vcpu_power_on(struct kvm_vcpu *vcpu); + void kvm_riscv_vcpu_power_on(struct kvm_vcpu *vcpu); ++bool kvm_riscv_vcpu_stopped(struct kvm_vcpu *vcpu); + + #endif /* __RISCV_KVM_HOST_H__ */ +diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c +index 88b6220b260879..048b9b23d7543e 100644 +--- a/arch/riscv/kernel/signal.c ++++ b/arch/riscv/kernel/signal.c +@@ -211,12 +211,6 @@ static size_t get_rt_frame_size(bool cal_all) + if (cal_all || riscv_v_vstate_query(task_pt_regs(current))) + total_context_size += riscv_v_sc_size; + } +- /* +- * Preserved a __riscv_ctx_hdr for END signal context header if an +- * extension uses __riscv_extra_ext_header +- */ +- if (total_context_size) +- total_context_size += sizeof(struct __riscv_ctx_hdr); + + frame_size += total_context_size; + +diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c +index 82229db1ce73f3..9584d62c96ee74 100644 +--- a/arch/riscv/kvm/vcpu.c ++++ b/arch/riscv/kvm/vcpu.c +@@ -100,6 +100,8 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) + struct kvm_cpu_context *cntx; + struct kvm_vcpu_csr *reset_csr = &vcpu->arch.guest_reset_csr; + ++ spin_lock_init(&vcpu->arch.mp_state_lock); ++ + /* Mark this VCPU never ran */ + vcpu->arch.ran_atleast_once = false; + vcpu->arch.mmu_page_cache.gfp_zero = __GFP_ZERO; +@@ -193,7 +195,7 @@ void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) + int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu) + { + return (kvm_riscv_vcpu_has_interrupts(vcpu, -1UL) && +- !vcpu->arch.power_off && !vcpu->arch.pause); ++ !kvm_riscv_vcpu_stopped(vcpu) && !vcpu->arch.pause); + } + + int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu) +@@ -421,26 +423,42 @@ bool kvm_riscv_vcpu_has_interrupts(struct kvm_vcpu *vcpu, u64 mask) + return kvm_riscv_vcpu_aia_has_interrupts(vcpu, mask); + } + +-void kvm_riscv_vcpu_power_off(struct kvm_vcpu *vcpu) ++void __kvm_riscv_vcpu_power_off(struct kvm_vcpu *vcpu) + { +- vcpu->arch.power_off = true; ++ WRITE_ONCE(vcpu->arch.mp_state.mp_state, KVM_MP_STATE_STOPPED); + kvm_make_request(KVM_REQ_SLEEP, vcpu); + kvm_vcpu_kick(vcpu); + } + +-void kvm_riscv_vcpu_power_on(struct kvm_vcpu *vcpu) ++void kvm_riscv_vcpu_power_off(struct kvm_vcpu *vcpu) + { +- vcpu->arch.power_off = false; ++ spin_lock(&vcpu->arch.mp_state_lock); ++ __kvm_riscv_vcpu_power_off(vcpu); ++ spin_unlock(&vcpu->arch.mp_state_lock); ++} ++ ++void __kvm_riscv_vcpu_power_on(struct kvm_vcpu *vcpu) ++{ ++ WRITE_ONCE(vcpu->arch.mp_state.mp_state, KVM_MP_STATE_RUNNABLE); + kvm_vcpu_wake_up(vcpu); + } + ++void kvm_riscv_vcpu_power_on(struct kvm_vcpu *vcpu) ++{ ++ spin_lock(&vcpu->arch.mp_state_lock); ++ __kvm_riscv_vcpu_power_on(vcpu); ++ spin_unlock(&vcpu->arch.mp_state_lock); ++} ++ ++bool kvm_riscv_vcpu_stopped(struct kvm_vcpu *vcpu) ++{ ++ return READ_ONCE(vcpu->arch.mp_state.mp_state) == KVM_MP_STATE_STOPPED; ++} ++ + int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu, + struct kvm_mp_state *mp_state) + { +- if (vcpu->arch.power_off) +- mp_state->mp_state = KVM_MP_STATE_STOPPED; +- else +- mp_state->mp_state = KVM_MP_STATE_RUNNABLE; ++ *mp_state = READ_ONCE(vcpu->arch.mp_state); + + return 0; + } +@@ -450,17 +468,21 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu, + { + int ret = 0; + ++ spin_lock(&vcpu->arch.mp_state_lock); ++ + switch (mp_state->mp_state) { + case KVM_MP_STATE_RUNNABLE: +- vcpu->arch.power_off = false; ++ WRITE_ONCE(vcpu->arch.mp_state, *mp_state); + break; + case KVM_MP_STATE_STOPPED: +- kvm_riscv_vcpu_power_off(vcpu); ++ __kvm_riscv_vcpu_power_off(vcpu); + break; + default: + ret = -EINVAL; + } + ++ spin_unlock(&vcpu->arch.mp_state_lock); ++ + return ret; + } + +@@ -561,11 +583,11 @@ static void kvm_riscv_check_vcpu_requests(struct kvm_vcpu *vcpu) + if (kvm_check_request(KVM_REQ_SLEEP, vcpu)) { + kvm_vcpu_srcu_read_unlock(vcpu); + rcuwait_wait_event(wait, +- (!vcpu->arch.power_off) && (!vcpu->arch.pause), ++ (!kvm_riscv_vcpu_stopped(vcpu)) && (!vcpu->arch.pause), + TASK_INTERRUPTIBLE); + kvm_vcpu_srcu_read_lock(vcpu); + +- if (vcpu->arch.power_off || vcpu->arch.pause) { ++ if (kvm_riscv_vcpu_stopped(vcpu) || vcpu->arch.pause) { + /* + * Awaken to handle a signal, request to + * sleep again later. +diff --git a/arch/riscv/kvm/vcpu_sbi.c b/arch/riscv/kvm/vcpu_sbi.c +index 7a7fe40d0930be..be43278109f4e8 100644 +--- a/arch/riscv/kvm/vcpu_sbi.c ++++ b/arch/riscv/kvm/vcpu_sbi.c +@@ -102,8 +102,11 @@ void kvm_riscv_vcpu_sbi_system_reset(struct kvm_vcpu *vcpu, + unsigned long i; + struct kvm_vcpu *tmp; + +- kvm_for_each_vcpu(i, tmp, vcpu->kvm) +- tmp->arch.power_off = true; ++ kvm_for_each_vcpu(i, tmp, vcpu->kvm) { ++ spin_lock(&vcpu->arch.mp_state_lock); ++ WRITE_ONCE(tmp->arch.mp_state.mp_state, KVM_MP_STATE_STOPPED); ++ spin_unlock(&vcpu->arch.mp_state_lock); ++ } + kvm_make_all_cpus_request(vcpu->kvm, KVM_REQ_SLEEP); + + memset(&run->system_event, 0, sizeof(run->system_event)); +diff --git a/arch/riscv/kvm/vcpu_sbi_hsm.c b/arch/riscv/kvm/vcpu_sbi_hsm.c +index 7dca0e9381d9a5..7e349b4ee926cb 100644 +--- a/arch/riscv/kvm/vcpu_sbi_hsm.c ++++ b/arch/riscv/kvm/vcpu_sbi_hsm.c +@@ -18,12 +18,18 @@ static int kvm_sbi_hsm_vcpu_start(struct kvm_vcpu *vcpu) + struct kvm_cpu_context *cp = &vcpu->arch.guest_context; + struct kvm_vcpu *target_vcpu; + unsigned long target_vcpuid = cp->a0; ++ int ret = 0; + + target_vcpu = kvm_get_vcpu_by_id(vcpu->kvm, target_vcpuid); + if (!target_vcpu) + return SBI_ERR_INVALID_PARAM; +- if (!target_vcpu->arch.power_off) +- return SBI_ERR_ALREADY_AVAILABLE; ++ ++ spin_lock(&target_vcpu->arch.mp_state_lock); ++ ++ if (!kvm_riscv_vcpu_stopped(target_vcpu)) { ++ ret = SBI_ERR_ALREADY_AVAILABLE; ++ goto out; ++ } + + reset_cntx = &target_vcpu->arch.guest_reset_context; + /* start address */ +@@ -34,19 +40,31 @@ static int kvm_sbi_hsm_vcpu_start(struct kvm_vcpu *vcpu) + reset_cntx->a1 = cp->a2; + kvm_make_request(KVM_REQ_VCPU_RESET, target_vcpu); + +- kvm_riscv_vcpu_power_on(target_vcpu); ++ __kvm_riscv_vcpu_power_on(target_vcpu); + +- return 0; ++out: ++ spin_unlock(&target_vcpu->arch.mp_state_lock); ++ ++ return ret; + } + + static int kvm_sbi_hsm_vcpu_stop(struct kvm_vcpu *vcpu) + { +- if (vcpu->arch.power_off) +- return SBI_ERR_FAILURE; ++ int ret = 0; + +- kvm_riscv_vcpu_power_off(vcpu); ++ spin_lock(&vcpu->arch.mp_state_lock); + +- return 0; ++ if (kvm_riscv_vcpu_stopped(vcpu)) { ++ ret = SBI_ERR_FAILURE; ++ goto out; ++ } ++ ++ __kvm_riscv_vcpu_power_off(vcpu); ++ ++out: ++ spin_unlock(&vcpu->arch.mp_state_lock); ++ ++ return ret; + } + + static int kvm_sbi_hsm_vcpu_get_status(struct kvm_vcpu *vcpu) +@@ -58,12 +76,12 @@ static int kvm_sbi_hsm_vcpu_get_status(struct kvm_vcpu *vcpu) + target_vcpu = kvm_get_vcpu_by_id(vcpu->kvm, target_vcpuid); + if (!target_vcpu) + return SBI_ERR_INVALID_PARAM; +- if (!target_vcpu->arch.power_off) +- return SBI_HSM_STATE_STARTED; +- else if (vcpu->stat.generic.blocking) ++ if (kvm_riscv_vcpu_stopped(target_vcpu)) ++ return SBI_HSM_STATE_STOPPED; ++ else if (target_vcpu->stat.generic.blocking) + return SBI_HSM_STATE_SUSPENDED; + else +- return SBI_HSM_STATE_STOPPED; ++ return SBI_HSM_STATE_STARTED; + } + + static int kvm_sbi_ext_hsm_handler(struct kvm_vcpu *vcpu, struct kvm_run *run, +@@ -71,14 +89,11 @@ static int kvm_sbi_ext_hsm_handler(struct kvm_vcpu *vcpu, struct kvm_run *run, + { + int ret = 0; + struct kvm_cpu_context *cp = &vcpu->arch.guest_context; +- struct kvm *kvm = vcpu->kvm; + unsigned long funcid = cp->a6; + + switch (funcid) { + case SBI_EXT_HSM_HART_START: +- mutex_lock(&kvm->lock); + ret = kvm_sbi_hsm_vcpu_start(vcpu); +- mutex_unlock(&kvm->lock); + break; + case SBI_EXT_HSM_HART_STOP: + ret = kvm_sbi_hsm_vcpu_stop(vcpu); +diff --git a/arch/riscv/kvm/vcpu_sbi_replace.c b/arch/riscv/kvm/vcpu_sbi_replace.c +index 7c4d5d38a33908..87ec68ed52d762 100644 +--- a/arch/riscv/kvm/vcpu_sbi_replace.c ++++ b/arch/riscv/kvm/vcpu_sbi_replace.c +@@ -21,7 +21,7 @@ static int kvm_sbi_ext_time_handler(struct kvm_vcpu *vcpu, struct kvm_run *run, + u64 next_cycle; + + if (cp->a6 != SBI_EXT_TIME_SET_TIMER) { +- retdata->err_val = SBI_ERR_INVALID_PARAM; ++ retdata->err_val = SBI_ERR_NOT_SUPPORTED; + return 0; + } + +@@ -51,9 +51,10 @@ static int kvm_sbi_ext_ipi_handler(struct kvm_vcpu *vcpu, struct kvm_run *run, + struct kvm_cpu_context *cp = &vcpu->arch.guest_context; + unsigned long hmask = cp->a0; + unsigned long hbase = cp->a1; ++ unsigned long hart_bit = 0, sentmask = 0; + + if (cp->a6 != SBI_EXT_IPI_SEND_IPI) { +- retdata->err_val = SBI_ERR_INVALID_PARAM; ++ retdata->err_val = SBI_ERR_NOT_SUPPORTED; + return 0; + } + +@@ -62,15 +63,23 @@ static int kvm_sbi_ext_ipi_handler(struct kvm_vcpu *vcpu, struct kvm_run *run, + if (hbase != -1UL) { + if (tmp->vcpu_id < hbase) + continue; +- if (!(hmask & (1UL << (tmp->vcpu_id - hbase)))) ++ hart_bit = tmp->vcpu_id - hbase; ++ if (hart_bit >= __riscv_xlen) ++ goto done; ++ if (!(hmask & (1UL << hart_bit))) + continue; + } + ret = kvm_riscv_vcpu_set_interrupt(tmp, IRQ_VS_SOFT); + if (ret < 0) + break; ++ sentmask |= 1UL << hart_bit; + kvm_riscv_vcpu_pmu_incr_fw(tmp, SBI_PMU_FW_IPI_RCVD); + } + ++done: ++ if (hbase != -1UL && (hmask ^ sentmask)) ++ retdata->err_val = SBI_ERR_INVALID_PARAM; ++ + return ret; + } + +diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig +index 989d432b58345d..1e666454ebdc3e 100644 +--- a/arch/x86/Kconfig ++++ b/arch/x86/Kconfig +@@ -1313,17 +1313,39 @@ config X86_REBOOTFIXUPS + config MICROCODE + def_bool y + depends on CPU_SUP_AMD || CPU_SUP_INTEL ++ select CRYPTO_LIB_SHA256 if CPU_SUP_AMD + + config MICROCODE_LATE_LOADING + bool "Late microcode loading (DANGEROUS)" + default n +- depends on MICROCODE ++ depends on MICROCODE && SMP + help + Loading microcode late, when the system is up and executing instructions + is a tricky business and should be avoided if possible. Just the sequence + of synchronizing all cores and SMT threads is one fragile dance which does + not guarantee that cores might not softlock after the loading. Therefore, +- use this at your own risk. Late loading taints the kernel too. ++ use this at your own risk. Late loading taints the kernel unless the ++ microcode header indicates that it is safe for late loading via the ++ minimal revision check. This minimal revision check can be enforced on ++ the kernel command line with "microcode.minrev=Y". ++ ++config MICROCODE_LATE_FORCE_MINREV ++ bool "Enforce late microcode loading minimal revision check" ++ default n ++ depends on MICROCODE_LATE_LOADING ++ help ++ To prevent that users load microcode late which modifies already ++ in use features, newer microcode patches have a minimum revision field ++ in the microcode header, which tells the kernel which minimum ++ revision must be active in the CPU to safely load that new microcode ++ late into the running system. If disabled the check will not ++ be enforced but the kernel will be tainted when the minimal ++ revision check fails. ++ ++ This minimal revision check can also be controlled via the ++ "microcode.minrev" parameter on the kernel command line. ++ ++ If unsure say Y. + + config X86_MSR + tristate "/dev/cpu/*/msr - Model-specific register support" +diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c +index 150a365b4fbc89..1458ccaa6a0579 100644 +--- a/arch/x86/events/core.c ++++ b/arch/x86/events/core.c +@@ -623,7 +623,7 @@ int x86_pmu_hw_config(struct perf_event *event) + if (event->attr.type == event->pmu->type) + event->hw.config |= event->attr.config & X86_RAW_EVENT_MASK; + +- if (event->attr.sample_period && x86_pmu.limit_period) { ++ if (!event->attr.freq && x86_pmu.limit_period) { + s64 left = event->attr.sample_period; + x86_pmu.limit_period(event, &left); + if (left > event->attr.sample_period) +diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h +index 33aa0c31c21cf1..a2258c894244a8 100644 +--- a/arch/x86/include/asm/apic.h ++++ b/arch/x86/include/asm/apic.h +@@ -277,7 +277,8 @@ struct apic { + + u32 disable_esr : 1, + dest_mode_logical : 1, +- x2apic_set_max_apicid : 1; ++ x2apic_set_max_apicid : 1, ++ nmi_to_offline_cpu : 1; + + u32 (*calc_dest_apicid)(unsigned int cpu); + +@@ -543,6 +544,8 @@ extern bool default_check_apicid_used(physid_mask_t *map, int apicid); + extern void default_ioapic_phys_id_map(physid_mask_t *phys_map, physid_mask_t *retmap); + extern int default_cpu_present_to_apicid(int mps_cpu); + ++void apic_send_nmi_to_offline_cpu(unsigned int cpu); ++ + #else /* CONFIG_X86_LOCAL_APIC */ + + static inline unsigned int read_apic_id(void) { return 0; } +diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h +index 25050d953eee02..fecc4fe1d68aff 100644 +--- a/arch/x86/include/asm/cpu.h ++++ b/arch/x86/include/asm/cpu.h +@@ -71,26 +71,12 @@ static inline void init_ia32_feat_ctl(struct cpuinfo_x86 *c) {} + + extern __noendbr void cet_disable(void); + +-struct ucode_cpu_info; ++struct cpu_signature; + +-int intel_cpu_collect_info(struct ucode_cpu_info *uci); +- +-static inline bool intel_cpu_signatures_match(unsigned int s1, unsigned int p1, +- unsigned int s2, unsigned int p2) +-{ +- if (s1 != s2) +- return false; +- +- /* Processor flags are either both 0 ... */ +- if (!p1 && !p2) +- return true; +- +- /* ... or they intersect. */ +- return p1 & p2; +-} ++void intel_collect_cpu_info(struct cpu_signature *sig); + + extern u64 x86_read_arch_cap_msr(void); +-int intel_find_matching_signature(void *mc, unsigned int csig, int cpf); ++bool intel_find_matching_signature(void *mc, struct cpu_signature *sig); + int intel_microcode_sanity_check(void *mc, bool print_err, int hdr_type); + + extern struct cpumask cpus_stop_mask; +diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h +index bbbe9d744977d0..1ab475a518e9a5 100644 +--- a/arch/x86/include/asm/microcode.h ++++ b/arch/x86/include/asm/microcode.h +@@ -68,11 +68,19 @@ static inline u32 intel_get_microcode_revision(void) + + return rev; + } ++#endif /* !CONFIG_CPU_SUP_INTEL */ + +-void show_ucode_info_early(void); ++bool microcode_nmi_handler(void); ++void microcode_offline_nmi_handler(void); + +-#else /* CONFIG_CPU_SUP_INTEL */ +-static inline void show_ucode_info_early(void) { } +-#endif /* !CONFIG_CPU_SUP_INTEL */ ++#ifdef CONFIG_MICROCODE_LATE_LOADING ++DECLARE_STATIC_KEY_FALSE(microcode_nmi_handler_enable); ++static __always_inline bool microcode_nmi_handler_enabled(void) ++{ ++ return static_branch_unlikely(µcode_nmi_handler_enable); ++} ++#else ++static __always_inline bool microcode_nmi_handler_enabled(void) { return false; } ++#endif + + #endif /* _ASM_X86_MICROCODE_H */ +diff --git a/arch/x86/kernel/apic/apic_flat_64.c b/arch/x86/kernel/apic/apic_flat_64.c +index 032a84e2c3ccc7..cd16228611ce8f 100644 +--- a/arch/x86/kernel/apic/apic_flat_64.c ++++ b/arch/x86/kernel/apic/apic_flat_64.c +@@ -103,6 +103,7 @@ static struct apic apic_flat __ro_after_init = { + .send_IPI_allbutself = default_send_IPI_allbutself, + .send_IPI_all = default_send_IPI_all, + .send_IPI_self = default_send_IPI_self, ++ .nmi_to_offline_cpu = true, + + .read = native_apic_mem_read, + .write = native_apic_mem_write, +@@ -175,6 +176,7 @@ static struct apic apic_physflat __ro_after_init = { + .send_IPI_allbutself = default_send_IPI_allbutself, + .send_IPI_all = default_send_IPI_all, + .send_IPI_self = default_send_IPI_self, ++ .nmi_to_offline_cpu = true, + + .read = native_apic_mem_read, + .write = native_apic_mem_write, +diff --git a/arch/x86/kernel/apic/ipi.c b/arch/x86/kernel/apic/ipi.c +index a44ba7209ef3a8..edad86f32e38cb 100644 +--- a/arch/x86/kernel/apic/ipi.c ++++ b/arch/x86/kernel/apic/ipi.c +@@ -97,6 +97,14 @@ void native_send_call_func_ipi(const struct cpumask *mask) + __apic_send_IPI_mask(mask, CALL_FUNCTION_VECTOR); + } + ++void apic_send_nmi_to_offline_cpu(unsigned int cpu) ++{ ++ if (WARN_ON_ONCE(!apic->nmi_to_offline_cpu)) ++ return; ++ if (WARN_ON_ONCE(!cpumask_test_cpu(cpu, &cpus_booted_once_mask))) ++ return; ++ apic->send_IPI(cpu, NMI_VECTOR); ++} + #endif /* CONFIG_SMP */ + + static inline int __prepare_ICR2(unsigned int mask) +diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c +index affbff65e49713..a8306089c91bca 100644 +--- a/arch/x86/kernel/apic/x2apic_cluster.c ++++ b/arch/x86/kernel/apic/x2apic_cluster.c +@@ -251,6 +251,7 @@ static struct apic apic_x2apic_cluster __ro_after_init = { + .send_IPI_allbutself = x2apic_send_IPI_allbutself, + .send_IPI_all = x2apic_send_IPI_all, + .send_IPI_self = x2apic_send_IPI_self, ++ .nmi_to_offline_cpu = true, + + .read = native_apic_msr_read, + .write = native_apic_msr_write, +diff --git a/arch/x86/kernel/apic/x2apic_phys.c b/arch/x86/kernel/apic/x2apic_phys.c +index 788cdb4ee394da..c8ac1b12b8ac6c 100644 +--- a/arch/x86/kernel/apic/x2apic_phys.c ++++ b/arch/x86/kernel/apic/x2apic_phys.c +@@ -166,6 +166,7 @@ static struct apic apic_x2apic_phys __ro_after_init = { + .send_IPI_allbutself = x2apic_send_IPI_allbutself, + .send_IPI_all = x2apic_send_IPI_all, + .send_IPI_self = x2apic_send_IPI_self, ++ .nmi_to_offline_cpu = true, + + .read = native_apic_msr_read, + .write = native_apic_msr_write, +diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c +index 8bc90a501e7b80..a844110691f978 100644 +--- a/arch/x86/kernel/cpu/common.c ++++ b/arch/x86/kernel/cpu/common.c +@@ -2224,8 +2224,6 @@ static inline void setup_getcpu(int cpu) + } + + #ifdef CONFIG_X86_64 +-static inline void ucode_cpu_init(int cpu) { } +- + static inline void tss_setup_ist(struct tss_struct *tss) + { + /* Set up the per-CPU TSS IST stacks */ +@@ -2236,16 +2234,8 @@ static inline void tss_setup_ist(struct tss_struct *tss) + /* Only mapped when SEV-ES is active */ + tss->x86_tss.ist[IST_INDEX_VC] = __this_cpu_ist_top_va(VC); + } +- + #else /* CONFIG_X86_64 */ +- +-static inline void ucode_cpu_init(int cpu) +-{ +- show_ucode_info_early(); +-} +- + static inline void tss_setup_ist(struct tss_struct *tss) { } +- + #endif /* !CONFIG_X86_64 */ + + static inline void tss_setup_io_bitmap(struct tss_struct *tss) +@@ -2301,8 +2291,6 @@ void cpu_init(void) + struct task_struct *cur = current; + int cpu = raw_smp_processor_id(); + +- ucode_cpu_init(cpu); +- + #ifdef CONFIG_NUMA + if (this_cpu_read(numa_node) == 0 && + early_cpu_to_node(cpu) != NUMA_NO_NODE) +diff --git a/arch/x86/kernel/cpu/cyrix.c b/arch/x86/kernel/cpu/cyrix.c +index 9651275aecd1bb..dfec2c61e3547d 100644 +--- a/arch/x86/kernel/cpu/cyrix.c ++++ b/arch/x86/kernel/cpu/cyrix.c +@@ -153,8 +153,8 @@ static void geode_configure(void) + u8 ccr3; + local_irq_save(flags); + +- /* Suspend on halt power saving and enable #SUSP pin */ +- setCx86(CX86_CCR2, getCx86(CX86_CCR2) | 0x88); ++ /* Suspend on halt power saving */ ++ setCx86(CX86_CCR2, getCx86(CX86_CCR2) | 0x08); + + ccr3 = getCx86(CX86_CCR3); + setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN */ +diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c +index bbd1dc38ea0316..13a632da09ed7b 100644 +--- a/arch/x86/kernel/cpu/microcode/amd.c ++++ b/arch/x86/kernel/cpu/microcode/amd.c +@@ -23,20 +23,35 @@ + + #include + #include ++#include + #include + #include + #include + #include + #include + ++#include ++ + #include + #include ++#include + #include + #include + #include ++#include + + #include "internal.h" + ++struct ucode_patch { ++ struct list_head plist; ++ void *data; ++ unsigned int size; ++ u32 patch_id; ++ u16 equiv_cpu; ++}; ++ ++static LIST_HEAD(microcode_cache); ++ + #define UCODE_MAGIC 0x00414d44 + #define UCODE_EQUIV_CPU_TABLE_TYPE 0x00000000 + #define UCODE_UCODE_TYPE 0x00000001 +@@ -81,6 +96,31 @@ static struct equiv_cpu_table { + struct equiv_cpu_entry *entry; + } equiv_table; + ++union zen_patch_rev { ++ struct { ++ __u32 rev : 8, ++ stepping : 4, ++ model : 4, ++ __reserved : 4, ++ ext_model : 4, ++ ext_fam : 8; ++ }; ++ __u32 ucode_rev; ++}; ++ ++union cpuid_1_eax { ++ struct { ++ __u32 stepping : 4, ++ model : 4, ++ family : 4, ++ __reserved0 : 4, ++ ext_model : 4, ++ ext_fam : 8, ++ __reserved1 : 4; ++ }; ++ __u32 full; ++}; ++ + /* + * This points to the current valid container of microcode patches which we will + * save from the initrd/builtin before jettisoning its contents. @mc is the +@@ -88,14 +128,11 @@ static struct equiv_cpu_table { + */ + struct cont_desc { + struct microcode_amd *mc; +- u32 cpuid_1_eax; + u32 psize; + u8 *data; + size_t size; + }; + +-static u32 ucode_new_rev; +- + /* + * Microcode patch container file is prepended to the initrd in cpio + * format. See Documentation/arch/x86/microcode.rst +@@ -103,10 +140,143 @@ static u32 ucode_new_rev; + static const char + ucode_path[] __maybe_unused = "kernel/x86/microcode/AuthenticAMD.bin"; + ++/* ++ * This is CPUID(1).EAX on the BSP. It is used in two ways: ++ * ++ * 1. To ignore the equivalence table on Zen1 and newer. ++ * ++ * 2. To match which patches to load because the patch revision ID ++ * already contains the f/m/s for which the microcode is destined ++ * for. ++ */ ++static u32 bsp_cpuid_1_eax __ro_after_init; ++ ++static bool sha_check = true; ++ ++struct patch_digest { ++ u32 patch_id; ++ u8 sha256[SHA256_DIGEST_SIZE]; ++}; ++ ++#include "amd_shas.c" ++ ++static int cmp_id(const void *key, const void *elem) ++{ ++ struct patch_digest *pd = (struct patch_digest *)elem; ++ u32 patch_id = *(u32 *)key; ++ ++ if (patch_id == pd->patch_id) ++ return 0; ++ else if (patch_id < pd->patch_id) ++ return -1; ++ else ++ return 1; ++} ++ ++static bool need_sha_check(u32 cur_rev) ++{ ++ switch (cur_rev >> 8) { ++ case 0x80012: return cur_rev <= 0x800126f; break; ++ case 0x83010: return cur_rev <= 0x830107c; break; ++ case 0x86001: return cur_rev <= 0x860010e; break; ++ case 0x86081: return cur_rev <= 0x8608108; break; ++ case 0x87010: return cur_rev <= 0x8701034; break; ++ case 0x8a000: return cur_rev <= 0x8a0000a; break; ++ case 0xa0011: return cur_rev <= 0xa0011da; break; ++ case 0xa0012: return cur_rev <= 0xa001243; break; ++ case 0xa1011: return cur_rev <= 0xa101153; break; ++ case 0xa1012: return cur_rev <= 0xa10124e; break; ++ case 0xa1081: return cur_rev <= 0xa108109; break; ++ case 0xa2010: return cur_rev <= 0xa20102f; break; ++ case 0xa2012: return cur_rev <= 0xa201212; break; ++ case 0xa6012: return cur_rev <= 0xa60120a; break; ++ case 0xa7041: return cur_rev <= 0xa704109; break; ++ case 0xa7052: return cur_rev <= 0xa705208; break; ++ case 0xa7080: return cur_rev <= 0xa708009; break; ++ case 0xa70c0: return cur_rev <= 0xa70C009; break; ++ case 0xaa002: return cur_rev <= 0xaa00218; break; ++ default: break; ++ } ++ ++ pr_info("You should not be seeing this. Please send the following couple of lines to x86--kernel.org\n"); ++ pr_info("CPUID(1).EAX: 0x%x, current revision: 0x%x\n", bsp_cpuid_1_eax, cur_rev); ++ return true; ++} ++ ++static bool verify_sha256_digest(u32 patch_id, u32 cur_rev, const u8 *data, unsigned int len) ++{ ++ struct patch_digest *pd = NULL; ++ u8 digest[SHA256_DIGEST_SIZE]; ++ struct sha256_state s; ++ int i; ++ ++ if (x86_family(bsp_cpuid_1_eax) < 0x17 || ++ x86_family(bsp_cpuid_1_eax) > 0x19) ++ return true; ++ ++ if (!need_sha_check(cur_rev)) ++ return true; ++ ++ if (!sha_check) ++ return true; ++ ++ pd = bsearch(&patch_id, phashes, ARRAY_SIZE(phashes), sizeof(struct patch_digest), cmp_id); ++ if (!pd) { ++ pr_err("No sha256 digest for patch ID: 0x%x found\n", patch_id); ++ return false; ++ } ++ ++ sha256_init(&s); ++ sha256_update(&s, data, len); ++ sha256_final(&s, digest); ++ ++ if (memcmp(digest, pd->sha256, sizeof(digest))) { ++ pr_err("Patch 0x%x SHA256 digest mismatch!\n", patch_id); ++ ++ for (i = 0; i < SHA256_DIGEST_SIZE; i++) ++ pr_cont("0x%x ", digest[i]); ++ pr_info("\n"); ++ ++ return false; ++ } ++ ++ return true; ++} ++ ++static u32 get_patch_level(void) ++{ ++ u32 rev, dummy __always_unused; ++ ++ native_rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy); ++ ++ return rev; ++} ++ ++static union cpuid_1_eax ucode_rev_to_cpuid(unsigned int val) ++{ ++ union zen_patch_rev p; ++ union cpuid_1_eax c; ++ ++ p.ucode_rev = val; ++ c.full = 0; ++ ++ c.stepping = p.stepping; ++ c.model = p.model; ++ c.ext_model = p.ext_model; ++ c.family = 0xf; ++ c.ext_fam = p.ext_fam; ++ ++ return c; ++} ++ + static u16 find_equiv_id(struct equiv_cpu_table *et, u32 sig) + { + unsigned int i; + ++ /* Zen and newer do not need an equivalence table. */ ++ if (x86_family(bsp_cpuid_1_eax) >= 0x17) ++ return 0; ++ + if (!et || !et->num_entries) + return 0; + +@@ -121,24 +291,20 @@ static u16 find_equiv_id(struct equiv_cpu_table *et, u32 sig) + + /* + * Check whether there is a valid microcode container file at the beginning +- * of @buf of size @buf_size. Set @early to use this function in the early path. ++ * of @buf of size @buf_size. + */ +-static bool verify_container(const u8 *buf, size_t buf_size, bool early) ++static bool verify_container(const u8 *buf, size_t buf_size) + { + u32 cont_magic; + + if (buf_size <= CONTAINER_HDR_SZ) { +- if (!early) +- pr_debug("Truncated microcode container header.\n"); +- ++ pr_debug("Truncated microcode container header.\n"); + return false; + } + + cont_magic = *(const u32 *)buf; + if (cont_magic != UCODE_MAGIC) { +- if (!early) +- pr_debug("Invalid magic value (0x%08x).\n", cont_magic); +- ++ pr_debug("Invalid magic value (0x%08x).\n", cont_magic); + return false; + } + +@@ -147,23 +313,24 @@ static bool verify_container(const u8 *buf, size_t buf_size, bool early) + + /* + * Check whether there is a valid, non-truncated CPU equivalence table at the +- * beginning of @buf of size @buf_size. Set @early to use this function in the +- * early path. ++ * beginning of @buf of size @buf_size. + */ +-static bool verify_equivalence_table(const u8 *buf, size_t buf_size, bool early) ++static bool verify_equivalence_table(const u8 *buf, size_t buf_size) + { + const u32 *hdr = (const u32 *)buf; + u32 cont_type, equiv_tbl_len; + +- if (!verify_container(buf, buf_size, early)) ++ if (!verify_container(buf, buf_size)) + return false; + ++ /* Zen and newer do not need an equivalence table. */ ++ if (x86_family(bsp_cpuid_1_eax) >= 0x17) ++ return true; ++ + cont_type = hdr[1]; + if (cont_type != UCODE_EQUIV_CPU_TABLE_TYPE) { +- if (!early) +- pr_debug("Wrong microcode container equivalence table type: %u.\n", +- cont_type); +- ++ pr_debug("Wrong microcode container equivalence table type: %u.\n", ++ cont_type); + return false; + } + +@@ -172,9 +339,7 @@ static bool verify_equivalence_table(const u8 *buf, size_t buf_size, bool early) + equiv_tbl_len = hdr[2]; + if (equiv_tbl_len < sizeof(struct equiv_cpu_entry) || + buf_size < equiv_tbl_len) { +- if (!early) +- pr_debug("Truncated equivalence table.\n"); +- ++ pr_debug("Truncated equivalence table.\n"); + return false; + } + +@@ -183,22 +348,19 @@ static bool verify_equivalence_table(const u8 *buf, size_t buf_size, bool early) + + /* + * Check whether there is a valid, non-truncated microcode patch section at the +- * beginning of @buf of size @buf_size. Set @early to use this function in the +- * early path. ++ * beginning of @buf of size @buf_size. + * + * On success, @sh_psize returns the patch size according to the section header, + * to the caller. + */ + static bool +-__verify_patch_section(const u8 *buf, size_t buf_size, u32 *sh_psize, bool early) ++__verify_patch_section(const u8 *buf, size_t buf_size, u32 *sh_psize) + { + u32 p_type, p_size; + const u32 *hdr; + + if (buf_size < SECTION_HDR_SIZE) { +- if (!early) +- pr_debug("Truncated patch section.\n"); +- ++ pr_debug("Truncated patch section.\n"); + return false; + } + +@@ -207,17 +369,13 @@ __verify_patch_section(const u8 *buf, size_t buf_size, u32 *sh_psize, bool early + p_size = hdr[1]; + + if (p_type != UCODE_UCODE_TYPE) { +- if (!early) +- pr_debug("Invalid type field (0x%x) in container file section header.\n", +- p_type); +- ++ pr_debug("Invalid type field (0x%x) in container file section header.\n", ++ p_type); + return false; + } + + if (p_size < sizeof(struct microcode_header_amd)) { +- if (!early) +- pr_debug("Patch of size %u too short.\n", p_size); +- ++ pr_debug("Patch of size %u too short.\n", p_size); + return false; + } + +@@ -232,12 +390,13 @@ __verify_patch_section(const u8 *buf, size_t buf_size, u32 *sh_psize, bool early + * exceed the per-family maximum). @sh_psize is the size read from the section + * header. + */ +-static unsigned int __verify_patch_size(u8 family, u32 sh_psize, size_t buf_size) ++static bool __verify_patch_size(u32 sh_psize, size_t buf_size) + { ++ u8 family = x86_family(bsp_cpuid_1_eax); + u32 max_size; + + if (family >= 0x15) +- return min_t(u32, sh_psize, buf_size); ++ goto ret; + + #define F1XH_MPB_MAX_SIZE 2048 + #define F14H_MPB_MAX_SIZE 1824 +@@ -251,13 +410,15 @@ static unsigned int __verify_patch_size(u8 family, u32 sh_psize, size_t buf_size + break; + default: + WARN(1, "%s: WTF family: 0x%x\n", __func__, family); +- return 0; ++ return false; + } + +- if (sh_psize > min_t(u32, buf_size, max_size)) +- return 0; ++ if (sh_psize > max_size) ++ return false; + +- return sh_psize; ++ret: ++ /* Working with the whole buffer so < is ok. */ ++ return sh_psize <= buf_size; + } + + /* +@@ -268,16 +429,15 @@ static unsigned int __verify_patch_size(u8 family, u32 sh_psize, size_t buf_size + * positive: patch is not for this family, skip it + * 0: success + */ +-static int +-verify_patch(u8 family, const u8 *buf, size_t buf_size, u32 *patch_size, bool early) ++static int verify_patch(const u8 *buf, size_t buf_size, u32 *patch_size) + { ++ u8 family = x86_family(bsp_cpuid_1_eax); + struct microcode_header_amd *mc_hdr; +- unsigned int ret; + u32 sh_psize; + u16 proc_id; + u8 patch_fam; + +- if (!__verify_patch_section(buf, buf_size, &sh_psize, early)) ++ if (!__verify_patch_section(buf, buf_size, &sh_psize)) + return -1; + + /* +@@ -292,16 +452,12 @@ verify_patch(u8 family, const u8 *buf, size_t buf_size, u32 *patch_size, bool ea + * size sh_psize, as the section claims. + */ + if (buf_size < sh_psize) { +- if (!early) +- pr_debug("Patch of size %u truncated.\n", sh_psize); +- ++ pr_debug("Patch of size %u truncated.\n", sh_psize); + return -1; + } + +- ret = __verify_patch_size(family, sh_psize, buf_size); +- if (!ret) { +- if (!early) +- pr_debug("Per-family patch size mismatch.\n"); ++ if (!__verify_patch_size(sh_psize, buf_size)) { ++ pr_debug("Per-family patch size mismatch.\n"); + return -1; + } + +@@ -309,8 +465,7 @@ verify_patch(u8 family, const u8 *buf, size_t buf_size, u32 *patch_size, bool ea + + mc_hdr = (struct microcode_header_amd *)(buf + SECTION_HDR_SIZE); + if (mc_hdr->nb_dev_id || mc_hdr->sb_dev_id) { +- if (!early) +- pr_err("Patch-ID 0x%08x: chipset-specific code unsupported.\n", mc_hdr->patch_id); ++ pr_err("Patch-ID 0x%08x: chipset-specific code unsupported.\n", mc_hdr->patch_id); + return -1; + } + +@@ -322,6 +477,15 @@ verify_patch(u8 family, const u8 *buf, size_t buf_size, u32 *patch_size, bool ea + return 0; + } + ++static bool mc_patch_matches(struct microcode_amd *mc, u16 eq_id) ++{ ++ /* Zen and newer do not need an equivalence table. */ ++ if (x86_family(bsp_cpuid_1_eax) >= 0x17) ++ return ucode_rev_to_cpuid(mc->hdr.patch_id).full == bsp_cpuid_1_eax; ++ else ++ return eq_id == mc->hdr.processor_rev_id; ++} ++ + /* + * This scans the ucode blob for the proper container as we can have multiple + * containers glued together. Returns the equivalence ID from the equivalence +@@ -337,7 +501,7 @@ static size_t parse_container(u8 *ucode, size_t size, struct cont_desc *desc) + u16 eq_id; + u8 *buf; + +- if (!verify_equivalence_table(ucode, size, true)) ++ if (!verify_equivalence_table(ucode, size)) + return 0; + + buf = ucode; +@@ -350,7 +514,7 @@ static size_t parse_container(u8 *ucode, size_t size, struct cont_desc *desc) + * doesn't contain a patch for the CPU, scan through the whole container + * so that it can be skipped in case there are other containers appended. + */ +- eq_id = find_equiv_id(&table, desc->cpuid_1_eax); ++ eq_id = find_equiv_id(&table, bsp_cpuid_1_eax); + + buf += hdr[2] + CONTAINER_HDR_SZ; + size -= hdr[2] + CONTAINER_HDR_SZ; +@@ -364,7 +528,7 @@ static size_t parse_container(u8 *ucode, size_t size, struct cont_desc *desc) + u32 patch_size; + int ret; + +- ret = verify_patch(x86_family(desc->cpuid_1_eax), buf, size, &patch_size, true); ++ ret = verify_patch(buf, size, &patch_size); + if (ret < 0) { + /* + * Patch verification failed, skip to the next container, if +@@ -377,7 +541,7 @@ static size_t parse_container(u8 *ucode, size_t size, struct cont_desc *desc) + } + + mc = (struct microcode_amd *)(buf + SECTION_HDR_SIZE); +- if (eq_id == mc->hdr.processor_rev_id) { ++ if (mc_patch_matches(mc, eq_id)) { + desc->psize = patch_size; + desc->mc = mc; + } +@@ -427,73 +591,42 @@ static void scan_containers(u8 *ucode, size_t size, struct cont_desc *desc) + } + } + +-static int __apply_microcode_amd(struct microcode_amd *mc) ++static bool __apply_microcode_amd(struct microcode_amd *mc, u32 *cur_rev, ++ unsigned int psize) + { +- u32 rev, dummy; ++ unsigned long p_addr = (unsigned long)&mc->hdr.data_code; + +- native_wrmsrl(MSR_AMD64_PATCH_LOADER, (u64)(long)&mc->hdr.data_code); +- +- /* verify patch application was successful */ +- native_rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy); +- if (rev != mc->hdr.patch_id) ++ if (!verify_sha256_digest(mc->hdr.patch_id, *cur_rev, (const u8 *)p_addr, psize)) + return -1; + +- return 0; +-} +- +-/* +- * Early load occurs before we can vmalloc(). So we look for the microcode +- * patch container file in initrd, traverse equivalent cpu table, look for a +- * matching microcode patch, and update, all in initrd memory in place. +- * When vmalloc() is available for use later -- on 64-bit during first AP load, +- * and on 32-bit during save_microcode_in_initrd_amd() -- we can call +- * load_microcode_amd() to save equivalent cpu table and microcode patches in +- * kernel heap memory. +- * +- * Returns true if container found (sets @desc), false otherwise. +- */ +-static bool early_apply_microcode(u32 cpuid_1_eax, void *ucode, size_t size) +-{ +- struct cont_desc desc = { 0 }; +- struct microcode_amd *mc; +- u32 rev, dummy, *new_rev; +- bool ret = false; +- +-#ifdef CONFIG_X86_32 +- new_rev = (u32 *)__pa_nodebug(&ucode_new_rev); +-#else +- new_rev = &ucode_new_rev; +-#endif +- +- desc.cpuid_1_eax = cpuid_1_eax; +- +- scan_containers(ucode, size, &desc); +- +- mc = desc.mc; +- if (!mc) +- return ret; ++ native_wrmsrl(MSR_AMD64_PATCH_LOADER, p_addr); + +- native_rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy); ++ if (x86_family(bsp_cpuid_1_eax) == 0x17) { ++ unsigned long p_addr_end = p_addr + psize - 1; + +- /* +- * Allow application of the same revision to pick up SMT-specific +- * changes even if the revision of the other SMT thread is already +- * up-to-date. +- */ +- if (rev > mc->hdr.patch_id) +- return ret; ++ invlpg(p_addr); + +- if (!__apply_microcode_amd(mc)) { +- *new_rev = mc->hdr.patch_id; +- ret = true; ++ /* ++ * Flush next page too if patch image is crossing a page ++ * boundary. ++ */ ++ if (p_addr >> PAGE_SHIFT != p_addr_end >> PAGE_SHIFT) ++ invlpg(p_addr_end); + } + +- return ret; ++ /* verify patch application was successful */ ++ *cur_rev = get_patch_level(); ++ if (*cur_rev != mc->hdr.patch_id) ++ return false; ++ ++ return true; + } + +-static bool get_builtin_microcode(struct cpio_data *cp, unsigned int family) ++ ++static bool get_builtin_microcode(struct cpio_data *cp) + { + char fw_name[36] = "amd-ucode/microcode_amd.bin"; ++ u8 family = x86_family(bsp_cpuid_1_eax); + struct firmware fw; + + if (IS_ENABLED(CONFIG_X86_32)) +@@ -512,93 +645,144 @@ static bool get_builtin_microcode(struct cpio_data *cp, unsigned int family) + return false; + } + +-static void find_blobs_in_containers(unsigned int cpuid_1_eax, struct cpio_data *ret) ++static bool __init find_blobs_in_containers(struct cpio_data *ret) + { +- struct ucode_cpu_info *uci; + struct cpio_data cp; +- const char *path; +- bool use_pa; +- +- if (IS_ENABLED(CONFIG_X86_32)) { +- uci = (struct ucode_cpu_info *)__pa_nodebug(ucode_cpu_info); +- path = (const char *)__pa_nodebug(ucode_path); +- use_pa = true; +- } else { +- uci = ucode_cpu_info; +- path = ucode_path; +- use_pa = false; +- } ++ bool found; + +- if (!get_builtin_microcode(&cp, x86_family(cpuid_1_eax))) +- cp = find_microcode_in_initrd(path, use_pa); ++ if (!get_builtin_microcode(&cp)) ++ cp = find_microcode_in_initrd(ucode_path); + +- /* Needed in load_microcode_amd() */ +- uci->cpu_sig.sig = cpuid_1_eax; ++ found = cp.data && cp.size; ++ if (found) ++ *ret = cp; + +- *ret = cp; ++ return found; + } + +-static void apply_ucode_from_containers(unsigned int cpuid_1_eax) ++/* ++ * Early load occurs before we can vmalloc(). So we look for the microcode ++ * patch container file in initrd, traverse equivalent cpu table, look for a ++ * matching microcode patch, and update, all in initrd memory in place. ++ * When vmalloc() is available for use later -- on 64-bit during first AP load, ++ * and on 32-bit during save_microcode_in_initrd() -- we can call ++ * load_microcode_amd() to save equivalent cpu table and microcode patches in ++ * kernel heap memory. ++ */ ++void __init load_ucode_amd_bsp(struct early_load_data *ed, unsigned int cpuid_1_eax) + { ++ struct cont_desc desc = { }; ++ struct microcode_amd *mc; + struct cpio_data cp = { }; ++ char buf[4]; ++ u32 rev; ++ ++ if (cmdline_find_option(boot_command_line, "microcode.amd_sha_check", buf, 4)) { ++ if (!strncmp(buf, "off", 3)) { ++ sha_check = false; ++ pr_warn_once("It is a very very bad idea to disable the blobs SHA check!\n"); ++ add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_STILL_OK); ++ } ++ } + +- find_blobs_in_containers(cpuid_1_eax, &cp); +- if (!(cp.data && cp.size)) +- return; ++ bsp_cpuid_1_eax = cpuid_1_eax; + +- early_apply_microcode(cpuid_1_eax, cp.data, cp.size); +-} ++ rev = get_patch_level(); ++ ed->old_rev = rev; + +-void load_ucode_amd_early(unsigned int cpuid_1_eax) +-{ +- return apply_ucode_from_containers(cpuid_1_eax); +-} ++ /* Needed in load_microcode_amd() */ ++ ucode_cpu_info[0].cpu_sig.sig = cpuid_1_eax; + +-static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t size); ++ if (!find_blobs_in_containers(&cp)) ++ return; + +-int __init save_microcode_in_initrd_amd(unsigned int cpuid_1_eax) +-{ +- struct cont_desc desc = { 0 }; +- enum ucode_state ret; +- struct cpio_data cp; ++ scan_containers(cp.data, cp.size, &desc); + +- cp = find_microcode_in_initrd(ucode_path, false); +- if (!(cp.data && cp.size)) +- return -EINVAL; ++ mc = desc.mc; ++ if (!mc) ++ return; + +- desc.cpuid_1_eax = cpuid_1_eax; ++ /* ++ * Allow application of the same revision to pick up SMT-specific ++ * changes even if the revision of the other SMT thread is already ++ * up-to-date. ++ */ ++ if (ed->old_rev > mc->hdr.patch_id) ++ return; + +- scan_containers(cp.data, cp.size, &desc); +- if (!desc.mc) +- return -EINVAL; ++ if (__apply_microcode_amd(mc, &rev, desc.psize)) ++ ed->new_rev = rev; ++} + +- ret = load_microcode_amd(x86_family(cpuid_1_eax), desc.data, desc.size); +- if (ret > UCODE_UPDATED) +- return -EINVAL; ++static inline bool patch_cpus_equivalent(struct ucode_patch *p, ++ struct ucode_patch *n, ++ bool ignore_stepping) ++{ ++ /* Zen and newer hardcode the f/m/s in the patch ID */ ++ if (x86_family(bsp_cpuid_1_eax) >= 0x17) { ++ union cpuid_1_eax p_cid = ucode_rev_to_cpuid(p->patch_id); ++ union cpuid_1_eax n_cid = ucode_rev_to_cpuid(n->patch_id); ++ ++ if (ignore_stepping) { ++ p_cid.stepping = 0; ++ n_cid.stepping = 0; ++ } + +- return 0; ++ return p_cid.full == n_cid.full; ++ } else { ++ return p->equiv_cpu == n->equiv_cpu; ++ } + } + + /* + * a small, trivial cache of per-family ucode patches + */ +-static struct ucode_patch *cache_find_patch(u16 equiv_cpu) ++static struct ucode_patch *cache_find_patch(struct ucode_cpu_info *uci, u16 equiv_cpu) + { + struct ucode_patch *p; ++ struct ucode_patch n; ++ ++ n.equiv_cpu = equiv_cpu; ++ n.patch_id = uci->cpu_sig.rev; ++ ++ WARN_ON_ONCE(!n.patch_id); + + list_for_each_entry(p, µcode_cache, plist) +- if (p->equiv_cpu == equiv_cpu) ++ if (patch_cpus_equivalent(p, &n, false)) + return p; ++ + return NULL; + } + ++static inline int patch_newer(struct ucode_patch *p, struct ucode_patch *n) ++{ ++ /* Zen and newer hardcode the f/m/s in the patch ID */ ++ if (x86_family(bsp_cpuid_1_eax) >= 0x17) { ++ union zen_patch_rev zp, zn; ++ ++ zp.ucode_rev = p->patch_id; ++ zn.ucode_rev = n->patch_id; ++ ++ if (zn.stepping != zp.stepping) ++ return -1; ++ ++ return zn.rev > zp.rev; ++ } else { ++ return n->patch_id > p->patch_id; ++ } ++} ++ + static void update_cache(struct ucode_patch *new_patch) + { + struct ucode_patch *p; ++ int ret; + + list_for_each_entry(p, µcode_cache, plist) { +- if (p->equiv_cpu == new_patch->equiv_cpu) { +- if (p->patch_id >= new_patch->patch_id) { ++ if (patch_cpus_equivalent(p, new_patch, true)) { ++ ret = patch_newer(p, new_patch); ++ if (ret < 0) ++ continue; ++ else if (!ret) { + /* we already have the latest patch */ + kfree(new_patch->data); + kfree(new_patch); +@@ -629,14 +813,17 @@ static void free_cache(void) + static struct ucode_patch *find_patch(unsigned int cpu) + { + struct ucode_cpu_info *uci = ucode_cpu_info + cpu; +- u16 equiv_id; ++ u16 equiv_id = 0; + ++ uci->cpu_sig.rev = get_patch_level(); + +- equiv_id = find_equiv_id(&equiv_table, uci->cpu_sig.sig); +- if (!equiv_id) +- return NULL; ++ if (x86_family(bsp_cpuid_1_eax) < 0x17) { ++ equiv_id = find_equiv_id(&equiv_table, uci->cpu_sig.sig); ++ if (!equiv_id) ++ return NULL; ++ } + +- return cache_find_patch(equiv_id); ++ return cache_find_patch(uci, equiv_id); + } + + void reload_ucode_amd(unsigned int cpu) +@@ -651,24 +838,20 @@ void reload_ucode_amd(unsigned int cpu) + + mc = p->data; + +- rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy); +- ++ rev = get_patch_level(); + if (rev < mc->hdr.patch_id) { +- if (!__apply_microcode_amd(mc)) { +- ucode_new_rev = mc->hdr.patch_id; +- pr_info("reload patch_level=0x%08x\n", ucode_new_rev); +- } ++ if (__apply_microcode_amd(mc, &rev, p->size)) ++ pr_info_once("reload revision: 0x%08x\n", rev); + } + } + + static int collect_cpu_info_amd(int cpu, struct cpu_signature *csig) + { +- struct cpuinfo_x86 *c = &cpu_data(cpu); + struct ucode_cpu_info *uci = ucode_cpu_info + cpu; + struct ucode_patch *p; + + csig->sig = cpuid_eax(0x00000001); +- csig->rev = c->microcode; ++ csig->rev = get_patch_level(); + + /* + * a patch could have been loaded early, set uci->mc so that +@@ -678,8 +861,6 @@ static int collect_cpu_info_amd(int cpu, struct cpu_signature *csig) + if (p && (p->patch_id == csig->rev)) + uci->mc = p->data; + +- pr_info("CPU%d: patch_level=0x%08x\n", cpu, csig->rev); +- + return 0; + } + +@@ -690,7 +871,7 @@ static enum ucode_state apply_microcode_amd(int cpu) + struct ucode_cpu_info *uci; + struct ucode_patch *p; + enum ucode_state ret; +- u32 rev, dummy __always_unused; ++ u32 rev; + + BUG_ON(raw_smp_processor_id() != cpu); + +@@ -700,18 +881,18 @@ static enum ucode_state apply_microcode_amd(int cpu) + if (!p) + return UCODE_NFOUND; + ++ rev = uci->cpu_sig.rev; ++ + mc_amd = p->data; + uci->mc = p->data; + +- rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy); +- + /* need to apply patch? */ + if (rev > mc_amd->hdr.patch_id) { + ret = UCODE_OK; + goto out; + } + +- if (__apply_microcode_amd(mc_amd)) { ++ if (!__apply_microcode_amd(mc_amd, &rev, p->size)) { + pr_err("CPU%d: update failed for patch_level=0x%08x\n", + cpu, mc_amd->hdr.patch_id); + return UCODE_ERROR; +@@ -720,8 +901,6 @@ static enum ucode_state apply_microcode_amd(int cpu) + rev = mc_amd->hdr.patch_id; + ret = UCODE_UPDATED; + +- pr_info("CPU%d: new patch_level=0x%08x\n", cpu, rev); +- + out: + uci->cpu_sig.rev = rev; + c->microcode = rev; +@@ -733,17 +912,29 @@ static enum ucode_state apply_microcode_amd(int cpu) + return ret; + } + ++void load_ucode_amd_ap(unsigned int cpuid_1_eax) ++{ ++ unsigned int cpu = smp_processor_id(); ++ ++ ucode_cpu_info[cpu].cpu_sig.sig = cpuid_1_eax; ++ apply_microcode_amd(cpu); ++} ++ + static size_t install_equiv_cpu_table(const u8 *buf, size_t buf_size) + { + u32 equiv_tbl_len; + const u32 *hdr; + +- if (!verify_equivalence_table(buf, buf_size, false)) ++ if (!verify_equivalence_table(buf, buf_size)) + return 0; + + hdr = (const u32 *)buf; + equiv_tbl_len = hdr[2]; + ++ /* Zen and newer do not need an equivalence table. */ ++ if (x86_family(bsp_cpuid_1_eax) >= 0x17) ++ goto out; ++ + equiv_table.entry = vmalloc(equiv_tbl_len); + if (!equiv_table.entry) { + pr_err("failed to allocate equivalent CPU table\n"); +@@ -753,12 +944,16 @@ static size_t install_equiv_cpu_table(const u8 *buf, size_t buf_size) + memcpy(equiv_table.entry, buf + CONTAINER_HDR_SZ, equiv_tbl_len); + equiv_table.num_entries = equiv_tbl_len / sizeof(struct equiv_cpu_entry); + ++out: + /* add header length */ + return equiv_tbl_len + CONTAINER_HDR_SZ; + } + + static void free_equiv_cpu_table(void) + { ++ if (x86_family(bsp_cpuid_1_eax) >= 0x17) ++ return; ++ + vfree(equiv_table.entry); + memset(&equiv_table, 0, sizeof(equiv_table)); + } +@@ -784,7 +979,7 @@ static int verify_and_add_patch(u8 family, u8 *fw, unsigned int leftover, + u16 proc_id; + int ret; + +- ret = verify_patch(family, fw, leftover, patch_size, false); ++ ret = verify_patch(fw, leftover, patch_size); + if (ret) + return ret; + +@@ -809,7 +1004,7 @@ static int verify_and_add_patch(u8 family, u8 *fw, unsigned int leftover, + patch->patch_id = mc_hdr->patch_id; + patch->equiv_cpu = proc_id; + +- pr_debug("%s: Added patch_id: 0x%08x, proc_id: 0x%04x\n", ++ pr_debug("%s: Adding patch_id: 0x%08x, proc_id: 0x%04x\n", + __func__, patch->patch_id, proc_id); + + /* ... and add to cache. */ +@@ -819,8 +1014,7 @@ static int verify_and_add_patch(u8 family, u8 *fw, unsigned int leftover, + } + + /* Scan the blob in @data and add microcode patches to the cache. */ +-static enum ucode_state __load_microcode_amd(u8 family, const u8 *data, +- size_t size) ++static enum ucode_state __load_microcode_amd(u8 family, const u8 *data, size_t size) + { + u8 *fw = (u8 *)data; + size_t offset; +@@ -853,21 +1047,30 @@ static enum ucode_state __load_microcode_amd(u8 family, const u8 *data, + return UCODE_OK; + } + +-static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t size) ++static enum ucode_state _load_microcode_amd(u8 family, const u8 *data, size_t size) + { +- struct cpuinfo_x86 *c; +- unsigned int nid, cpu; +- struct ucode_patch *p; + enum ucode_state ret; + + /* free old equiv table */ + free_equiv_cpu_table(); + + ret = __load_microcode_amd(family, data, size); +- if (ret != UCODE_OK) { ++ if (ret != UCODE_OK) + cleanup(); ++ ++ return ret; ++} ++ ++static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t size) ++{ ++ struct cpuinfo_x86 *c; ++ unsigned int nid, cpu; ++ struct ucode_patch *p; ++ enum ucode_state ret; ++ ++ ret = _load_microcode_amd(family, data, size); ++ if (ret != UCODE_OK) + return ret; +- } + + for_each_node(nid) { + cpu = cpumask_first(cpumask_of_node(nid)); +@@ -886,6 +1089,32 @@ static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t siz + return ret; + } + ++static int __init save_microcode_in_initrd(void) ++{ ++ unsigned int cpuid_1_eax = native_cpuid_eax(1); ++ struct cpuinfo_x86 *c = &boot_cpu_data; ++ struct cont_desc desc = { 0 }; ++ enum ucode_state ret; ++ struct cpio_data cp; ++ ++ if (dis_ucode_ldr || c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10) ++ return 0; ++ ++ if (!find_blobs_in_containers(&cp)) ++ return -EINVAL; ++ ++ scan_containers(cp.data, cp.size, &desc); ++ if (!desc.mc) ++ return -EINVAL; ++ ++ ret = _load_microcode_amd(x86_family(cpuid_1_eax), desc.data, desc.size); ++ if (ret > UCODE_UPDATED) ++ return -EINVAL; ++ ++ return 0; ++} ++early_initcall(save_microcode_in_initrd); ++ + /* + * AMD microcode firmware naming convention, up to family 15h they are in + * the legacy file: +@@ -909,6 +1138,9 @@ static enum ucode_state request_microcode_amd(int cpu, struct device *device) + enum ucode_state ret = UCODE_NFOUND; + const struct firmware *fw; + ++ if (force_minrev) ++ return UCODE_NFOUND; ++ + if (c->x86 >= 0x15) + snprintf(fw_name, sizeof(fw_name), "amd-ucode/microcode_amd_fam%.2xh.bin", c->x86); + +@@ -918,7 +1150,7 @@ static enum ucode_state request_microcode_amd(int cpu, struct device *device) + } + + ret = UCODE_ERROR; +- if (!verify_container(fw->data, fw->size, false)) ++ if (!verify_container(fw->data, fw->size)) + goto fw_release; + + ret = load_microcode_amd(c->x86, fw->data, fw->size); +@@ -938,10 +1170,11 @@ static void microcode_fini_cpu_amd(int cpu) + } + + static struct microcode_ops microcode_amd_ops = { +- .request_microcode_fw = request_microcode_amd, +- .collect_cpu_info = collect_cpu_info_amd, +- .apply_microcode = apply_microcode_amd, +- .microcode_fini_cpu = microcode_fini_cpu_amd, ++ .request_microcode_fw = request_microcode_amd, ++ .collect_cpu_info = collect_cpu_info_amd, ++ .apply_microcode = apply_microcode_amd, ++ .microcode_fini_cpu = microcode_fini_cpu_amd, ++ .nmi_safe = true, + }; + + struct microcode_ops * __init init_amd_microcode(void) +@@ -952,11 +1185,6 @@ struct microcode_ops * __init init_amd_microcode(void) + pr_warn("AMD CPU family 0x%x not supported\n", c->x86); + return NULL; + } +- +- if (ucode_new_rev) +- pr_info_once("microcode updated early to new patch_level=0x%08x\n", +- ucode_new_rev); +- + return µcode_amd_ops; + } + +diff --git a/arch/x86/kernel/cpu/microcode/amd_shas.c b/arch/x86/kernel/cpu/microcode/amd_shas.c +new file mode 100644 +index 00000000000000..2a1655b1fdd883 +--- /dev/null ++++ b/arch/x86/kernel/cpu/microcode/amd_shas.c +@@ -0,0 +1,444 @@ ++/* Keep 'em sorted. */ ++static const struct patch_digest phashes[] = { ++ { 0x8001227, { ++ 0x99,0xc0,0x9b,0x2b,0xcc,0x9f,0x52,0x1b, ++ 0x1a,0x5f,0x1d,0x83,0xa1,0x6c,0xc4,0x46, ++ 0xe2,0x6c,0xda,0x73,0xfb,0x2d,0x23,0xa8, ++ 0x77,0xdc,0x15,0x31,0x33,0x4a,0x46,0x18, ++ } ++ }, ++ { 0x8001250, { ++ 0xc0,0x0b,0x6b,0x19,0xfd,0x5c,0x39,0x60, ++ 0xd5,0xc3,0x57,0x46,0x54,0xe4,0xd1,0xaa, ++ 0xa8,0xf7,0x1f,0xa8,0x6a,0x60,0x3e,0xe3, ++ 0x27,0x39,0x8e,0x53,0x30,0xf8,0x49,0x19, ++ } ++ }, ++ { 0x800126e, { ++ 0xf3,0x8b,0x2b,0xb6,0x34,0xe3,0xc8,0x2c, ++ 0xef,0xec,0x63,0x6d,0xc8,0x76,0x77,0xb3, ++ 0x25,0x5a,0xb7,0x52,0x8c,0x83,0x26,0xe6, ++ 0x4c,0xbe,0xbf,0xe9,0x7d,0x22,0x6a,0x43, ++ } ++ }, ++ { 0x800126f, { ++ 0x2b,0x5a,0xf2,0x9c,0xdd,0xd2,0x7f,0xec, ++ 0xec,0x96,0x09,0x57,0xb0,0x96,0x29,0x8b, ++ 0x2e,0x26,0x91,0xf0,0x49,0x33,0x42,0x18, ++ 0xdd,0x4b,0x65,0x5a,0xd4,0x15,0x3d,0x33, ++ } ++ }, ++ { 0x800820d, { ++ 0x68,0x98,0x83,0xcd,0x22,0x0d,0xdd,0x59, ++ 0x73,0x2c,0x5b,0x37,0x1f,0x84,0x0e,0x67, ++ 0x96,0x43,0x83,0x0c,0x46,0x44,0xab,0x7c, ++ 0x7b,0x65,0x9e,0x57,0xb5,0x90,0x4b,0x0e, ++ } ++ }, ++ { 0x8301025, { ++ 0xe4,0x7d,0xdb,0x1e,0x14,0xb4,0x5e,0x36, ++ 0x8f,0x3e,0x48,0x88,0x3c,0x6d,0x76,0xa1, ++ 0x59,0xc6,0xc0,0x72,0x42,0xdf,0x6c,0x30, ++ 0x6f,0x0b,0x28,0x16,0x61,0xfc,0x79,0x77, ++ } ++ }, ++ { 0x8301055, { ++ 0x81,0x7b,0x99,0x1b,0xae,0x2d,0x4f,0x9a, ++ 0xef,0x13,0xce,0xb5,0x10,0xaf,0x6a,0xea, ++ 0xe5,0xb0,0x64,0x98,0x10,0x68,0x34,0x3b, ++ 0x9d,0x7a,0xd6,0x22,0x77,0x5f,0xb3,0x5b, ++ } ++ }, ++ { 0x8301072, { ++ 0xcf,0x76,0xa7,0x1a,0x49,0xdf,0x2a,0x5e, ++ 0x9e,0x40,0x70,0xe5,0xdd,0x8a,0xa8,0x28, ++ 0x20,0xdc,0x91,0xd8,0x2c,0xa6,0xa0,0xb1, ++ 0x2d,0x22,0x26,0x94,0x4b,0x40,0x85,0x30, ++ } ++ }, ++ { 0x830107a, { ++ 0x2a,0x65,0x8c,0x1a,0x5e,0x07,0x21,0x72, ++ 0xdf,0x90,0xa6,0x51,0x37,0xd3,0x4b,0x34, ++ 0xc4,0xda,0x03,0xe1,0x8a,0x6c,0xfb,0x20, ++ 0x04,0xb2,0x81,0x05,0xd4,0x87,0xf4,0x0a, ++ } ++ }, ++ { 0x830107b, { ++ 0xb3,0x43,0x13,0x63,0x56,0xc1,0x39,0xad, ++ 0x10,0xa6,0x2b,0xcc,0x02,0xe6,0x76,0x2a, ++ 0x1e,0x39,0x58,0x3e,0x23,0x6e,0xa4,0x04, ++ 0x95,0xea,0xf9,0x6d,0xc2,0x8a,0x13,0x19, ++ } ++ }, ++ { 0x830107c, { ++ 0x21,0x64,0xde,0xfb,0x9f,0x68,0x96,0x47, ++ 0x70,0x5c,0xe2,0x8f,0x18,0x52,0x6a,0xac, ++ 0xa4,0xd2,0x2e,0xe0,0xde,0x68,0x66,0xc3, ++ 0xeb,0x1e,0xd3,0x3f,0xbc,0x51,0x1d,0x38, ++ } ++ }, ++ { 0x860010d, { ++ 0x86,0xb6,0x15,0x83,0xbc,0x3b,0x9c,0xe0, ++ 0xb3,0xef,0x1d,0x99,0x84,0x35,0x15,0xf7, ++ 0x7c,0x2a,0xc6,0x42,0xdb,0x73,0x07,0x5c, ++ 0x7d,0xc3,0x02,0xb5,0x43,0x06,0x5e,0xf8, ++ } ++ }, ++ { 0x8608108, { ++ 0x14,0xfe,0x57,0x86,0x49,0xc8,0x68,0xe2, ++ 0x11,0xa3,0xcb,0x6e,0xff,0x6e,0xd5,0x38, ++ 0xfe,0x89,0x1a,0xe0,0x67,0xbf,0xc4,0xcc, ++ 0x1b,0x9f,0x84,0x77,0x2b,0x9f,0xaa,0xbd, ++ } ++ }, ++ { 0x8701034, { ++ 0xc3,0x14,0x09,0xa8,0x9c,0x3f,0x8d,0x83, ++ 0x9b,0x4c,0xa5,0xb7,0x64,0x8b,0x91,0x5d, ++ 0x85,0x6a,0x39,0x26,0x1e,0x14,0x41,0xa8, ++ 0x75,0xea,0xa6,0xf9,0xc9,0xd1,0xea,0x2b, ++ } ++ }, ++ { 0x8a00008, { ++ 0xd7,0x2a,0x93,0xdc,0x05,0x2f,0xa5,0x6e, ++ 0x0c,0x61,0x2c,0x07,0x9f,0x38,0xe9,0x8e, ++ 0xef,0x7d,0x2a,0x05,0x4d,0x56,0xaf,0x72, ++ 0xe7,0x56,0x47,0x6e,0x60,0x27,0xd5,0x8c, ++ } ++ }, ++ { 0x8a0000a, { ++ 0x73,0x31,0x26,0x22,0xd4,0xf9,0xee,0x3c, ++ 0x07,0x06,0xe7,0xb9,0xad,0xd8,0x72,0x44, ++ 0x33,0x31,0xaa,0x7d,0xc3,0x67,0x0e,0xdb, ++ 0x47,0xb5,0xaa,0xbc,0xf5,0xbb,0xd9,0x20, ++ } ++ }, ++ { 0xa00104c, { ++ 0x3c,0x8a,0xfe,0x04,0x62,0xd8,0x6d,0xbe, ++ 0xa7,0x14,0x28,0x64,0x75,0xc0,0xa3,0x76, ++ 0xb7,0x92,0x0b,0x97,0x0a,0x8e,0x9c,0x5b, ++ 0x1b,0xc8,0x9d,0x3a,0x1e,0x81,0x3d,0x3b, ++ } ++ }, ++ { 0xa00104e, { ++ 0xc4,0x35,0x82,0x67,0xd2,0x86,0xe5,0xb2, ++ 0xfd,0x69,0x12,0x38,0xc8,0x77,0xba,0xe0, ++ 0x70,0xf9,0x77,0x89,0x10,0xa6,0x74,0x4e, ++ 0x56,0x58,0x13,0xf5,0x84,0x70,0x28,0x0b, ++ } ++ }, ++ { 0xa001053, { ++ 0x92,0x0e,0xf4,0x69,0x10,0x3b,0xf9,0x9d, ++ 0x31,0x1b,0xa6,0x99,0x08,0x7d,0xd7,0x25, ++ 0x7e,0x1e,0x89,0xba,0x35,0x8d,0xac,0xcb, ++ 0x3a,0xb4,0xdf,0x58,0x12,0xcf,0xc0,0xc3, ++ } ++ }, ++ { 0xa001058, { ++ 0x33,0x7d,0xa9,0xb5,0x4e,0x62,0x13,0x36, ++ 0xef,0x66,0xc9,0xbd,0x0a,0xa6,0x3b,0x19, ++ 0xcb,0xf5,0xc2,0xc3,0x55,0x47,0x20,0xec, ++ 0x1f,0x7b,0xa1,0x44,0x0e,0x8e,0xa4,0xb2, ++ } ++ }, ++ { 0xa001075, { ++ 0x39,0x02,0x82,0xd0,0x7c,0x26,0x43,0xe9, ++ 0x26,0xa3,0xd9,0x96,0xf7,0x30,0x13,0x0a, ++ 0x8a,0x0e,0xac,0xe7,0x1d,0xdc,0xe2,0x0f, ++ 0xcb,0x9e,0x8d,0xbc,0xd2,0xa2,0x44,0xe0, ++ } ++ }, ++ { 0xa001078, { ++ 0x2d,0x67,0xc7,0x35,0xca,0xef,0x2f,0x25, ++ 0x4c,0x45,0x93,0x3f,0x36,0x01,0x8c,0xce, ++ 0xa8,0x5b,0x07,0xd3,0xc1,0x35,0x3c,0x04, ++ 0x20,0xa2,0xfc,0xdc,0xe6,0xce,0x26,0x3e, ++ } ++ }, ++ { 0xa001079, { ++ 0x43,0xe2,0x05,0x9c,0xfd,0xb7,0x5b,0xeb, ++ 0x5b,0xe9,0xeb,0x3b,0x96,0xf4,0xe4,0x93, ++ 0x73,0x45,0x3e,0xac,0x8d,0x3b,0xe4,0xdb, ++ 0x10,0x31,0xc1,0xe4,0xa2,0xd0,0x5a,0x8a, ++ } ++ }, ++ { 0xa00107a, { ++ 0x5f,0x92,0xca,0xff,0xc3,0x59,0x22,0x5f, ++ 0x02,0xa0,0x91,0x3b,0x4a,0x45,0x10,0xfd, ++ 0x19,0xe1,0x8a,0x6d,0x9a,0x92,0xc1,0x3f, ++ 0x75,0x78,0xac,0x78,0x03,0x1d,0xdb,0x18, ++ } ++ }, ++ { 0xa001143, { ++ 0x56,0xca,0xf7,0x43,0x8a,0x4c,0x46,0x80, ++ 0xec,0xde,0xe5,0x9c,0x50,0x84,0x9a,0x42, ++ 0x27,0xe5,0x51,0x84,0x8f,0x19,0xc0,0x8d, ++ 0x0c,0x25,0xb4,0xb0,0x8f,0x10,0xf3,0xf8, ++ } ++ }, ++ { 0xa001144, { ++ 0x42,0xd5,0x9b,0xa7,0xd6,0x15,0x29,0x41, ++ 0x61,0xc4,0x72,0x3f,0xf3,0x06,0x78,0x4b, ++ 0x65,0xf3,0x0e,0xfa,0x9c,0x87,0xde,0x25, ++ 0xbd,0xb3,0x9a,0xf4,0x75,0x13,0x53,0xdc, ++ } ++ }, ++ { 0xa00115d, { ++ 0xd4,0xc4,0x49,0x36,0x89,0x0b,0x47,0xdd, ++ 0xfb,0x2f,0x88,0x3b,0x5f,0xf2,0x8e,0x75, ++ 0xc6,0x6c,0x37,0x5a,0x90,0x25,0x94,0x3e, ++ 0x36,0x9c,0xae,0x02,0x38,0x6c,0xf5,0x05, ++ } ++ }, ++ { 0xa001173, { ++ 0x28,0xbb,0x9b,0xd1,0xa0,0xa0,0x7e,0x3a, ++ 0x59,0x20,0xc0,0xa9,0xb2,0x5c,0xc3,0x35, ++ 0x53,0x89,0xe1,0x4c,0x93,0x2f,0x1d,0xc3, ++ 0xe5,0xf7,0xf3,0xc8,0x9b,0x61,0xaa,0x9e, ++ } ++ }, ++ { 0xa0011a8, { ++ 0x97,0xc6,0x16,0x65,0x99,0xa4,0x85,0x3b, ++ 0xf6,0xce,0xaa,0x49,0x4a,0x3a,0xc5,0xb6, ++ 0x78,0x25,0xbc,0x53,0xaf,0x5d,0xcf,0xf4, ++ 0x23,0x12,0xbb,0xb1,0xbc,0x8a,0x02,0x2e, ++ } ++ }, ++ { 0xa0011ce, { ++ 0xcf,0x1c,0x90,0xa3,0x85,0x0a,0xbf,0x71, ++ 0x94,0x0e,0x80,0x86,0x85,0x4f,0xd7,0x86, ++ 0xae,0x38,0x23,0x28,0x2b,0x35,0x9b,0x4e, ++ 0xfe,0xb8,0xcd,0x3d,0x3d,0x39,0xc9,0x6a, ++ } ++ }, ++ { 0xa0011d1, { ++ 0xdf,0x0e,0xca,0xde,0xf6,0xce,0x5c,0x1e, ++ 0x4c,0xec,0xd7,0x71,0x83,0xcc,0xa8,0x09, ++ 0xc7,0xc5,0xfe,0xb2,0xf7,0x05,0xd2,0xc5, ++ 0x12,0xdd,0xe4,0xf3,0x92,0x1c,0x3d,0xb8, ++ } ++ }, ++ { 0xa0011d3, { ++ 0x91,0xe6,0x10,0xd7,0x57,0xb0,0x95,0x0b, ++ 0x9a,0x24,0xee,0xf7,0xcf,0x56,0xc1,0xa6, ++ 0x4a,0x52,0x7d,0x5f,0x9f,0xdf,0xf6,0x00, ++ 0x65,0xf7,0xea,0xe8,0x2a,0x88,0xe2,0x26, ++ } ++ }, ++ { 0xa0011d5, { ++ 0xed,0x69,0x89,0xf4,0xeb,0x64,0xc2,0x13, ++ 0xe0,0x51,0x1f,0x03,0x26,0x52,0x7d,0xb7, ++ 0x93,0x5d,0x65,0xca,0xb8,0x12,0x1d,0x62, ++ 0x0d,0x5b,0x65,0x34,0x69,0xb2,0x62,0x21, ++ } ++ }, ++ { 0xa001223, { ++ 0xfb,0x32,0x5f,0xc6,0x83,0x4f,0x8c,0xb8, ++ 0xa4,0x05,0xf9,0x71,0x53,0x01,0x16,0xc4, ++ 0x83,0x75,0x94,0xdd,0xeb,0x7e,0xb7,0x15, ++ 0x8e,0x3b,0x50,0x29,0x8a,0x9c,0xcc,0x45, ++ } ++ }, ++ { 0xa001224, { ++ 0x0e,0x0c,0xdf,0xb4,0x89,0xee,0x35,0x25, ++ 0xdd,0x9e,0xdb,0xc0,0x69,0x83,0x0a,0xad, ++ 0x26,0xa9,0xaa,0x9d,0xfc,0x3c,0xea,0xf9, ++ 0x6c,0xdc,0xd5,0x6d,0x8b,0x6e,0x85,0x4a, ++ } ++ }, ++ { 0xa001227, { ++ 0xab,0xc6,0x00,0x69,0x4b,0x50,0x87,0xad, ++ 0x5f,0x0e,0x8b,0xea,0x57,0x38,0xce,0x1d, ++ 0x0f,0x75,0x26,0x02,0xf6,0xd6,0x96,0xe9, ++ 0x87,0xb9,0xd6,0x20,0x27,0x7c,0xd2,0xe0, ++ } ++ }, ++ { 0xa001229, { ++ 0x7f,0x49,0x49,0x48,0x46,0xa5,0x50,0xa6, ++ 0x28,0x89,0x98,0xe2,0x9e,0xb4,0x7f,0x75, ++ 0x33,0xa7,0x04,0x02,0xe4,0x82,0xbf,0xb4, ++ 0xa5,0x3a,0xba,0x24,0x8d,0x31,0x10,0x1d, ++ } ++ }, ++ { 0xa00122e, { ++ 0x56,0x94,0xa9,0x5d,0x06,0x68,0xfe,0xaf, ++ 0xdf,0x7a,0xff,0x2d,0xdf,0x74,0x0f,0x15, ++ 0x66,0xfb,0x00,0xb5,0x51,0x97,0x9b,0xfa, ++ 0xcb,0x79,0x85,0x46,0x25,0xb4,0xd2,0x10, ++ } ++ }, ++ { 0xa001231, { ++ 0x0b,0x46,0xa5,0xfc,0x18,0x15,0xa0,0x9e, ++ 0xa6,0xdc,0xb7,0xff,0x17,0xf7,0x30,0x64, ++ 0xd4,0xda,0x9e,0x1b,0xc3,0xfc,0x02,0x3b, ++ 0xe2,0xc6,0x0e,0x41,0x54,0xb5,0x18,0xdd, ++ } ++ }, ++ { 0xa001234, { ++ 0x88,0x8d,0xed,0xab,0xb5,0xbd,0x4e,0xf7, ++ 0x7f,0xd4,0x0e,0x95,0x34,0x91,0xff,0xcc, ++ 0xfb,0x2a,0xcd,0xf7,0xd5,0xdb,0x4c,0x9b, ++ 0xd6,0x2e,0x73,0x50,0x8f,0x83,0x79,0x1a, ++ } ++ }, ++ { 0xa001236, { ++ 0x3d,0x30,0x00,0xb9,0x71,0xba,0x87,0x78, ++ 0xa8,0x43,0x55,0xc4,0x26,0x59,0xcf,0x9d, ++ 0x93,0xce,0x64,0x0e,0x8b,0x72,0x11,0x8b, ++ 0xa3,0x8f,0x51,0xe9,0xca,0x98,0xaa,0x25, ++ } ++ }, ++ { 0xa001238, { ++ 0x72,0xf7,0x4b,0x0c,0x7d,0x58,0x65,0xcc, ++ 0x00,0xcc,0x57,0x16,0x68,0x16,0xf8,0x2a, ++ 0x1b,0xb3,0x8b,0xe1,0xb6,0x83,0x8c,0x7e, ++ 0xc0,0xcd,0x33,0xf2,0x8d,0xf9,0xef,0x59, ++ } ++ }, ++ { 0xa00820c, { ++ 0xa8,0x0c,0x81,0xc0,0xa6,0x00,0xe7,0xf3, ++ 0x5f,0x65,0xd3,0xb9,0x6f,0xea,0x93,0x63, ++ 0xf1,0x8c,0x88,0x45,0xd7,0x82,0x80,0xd1, ++ 0xe1,0x3b,0x8d,0xb2,0xf8,0x22,0x03,0xe2, ++ } ++ }, ++ { 0xa10113e, { ++ 0x05,0x3c,0x66,0xd7,0xa9,0x5a,0x33,0x10, ++ 0x1b,0xf8,0x9c,0x8f,0xed,0xfc,0xa7,0xa0, ++ 0x15,0xe3,0x3f,0x4b,0x1d,0x0d,0x0a,0xd5, ++ 0xfa,0x90,0xc4,0xed,0x9d,0x90,0xaf,0x53, ++ } ++ }, ++ { 0xa101144, { ++ 0xb3,0x0b,0x26,0x9a,0xf8,0x7c,0x02,0x26, ++ 0x35,0x84,0x53,0xa4,0xd3,0x2c,0x7c,0x09, ++ 0x68,0x7b,0x96,0xb6,0x93,0xef,0xde,0xbc, ++ 0xfd,0x4b,0x15,0xd2,0x81,0xd3,0x51,0x47, ++ } ++ }, ++ { 0xa101148, { ++ 0x20,0xd5,0x6f,0x40,0x4a,0xf6,0x48,0x90, ++ 0xc2,0x93,0x9a,0xc2,0xfd,0xac,0xef,0x4f, ++ 0xfa,0xc0,0x3d,0x92,0x3c,0x6d,0x01,0x08, ++ 0xf1,0x5e,0xb0,0xde,0xb4,0x98,0xae,0xc4, ++ } ++ }, ++ { 0xa10123e, { ++ 0x03,0xb9,0x2c,0x76,0x48,0x93,0xc9,0x18, ++ 0xfb,0x56,0xfd,0xf7,0xe2,0x1d,0xca,0x4d, ++ 0x1d,0x13,0x53,0x63,0xfe,0x42,0x6f,0xfc, ++ 0x19,0x0f,0xf1,0xfc,0xa7,0xdd,0x89,0x1b, ++ } ++ }, ++ { 0xa101244, { ++ 0x71,0x56,0xb5,0x9f,0x21,0xbf,0xb3,0x3c, ++ 0x8c,0xd7,0x36,0xd0,0x34,0x52,0x1b,0xb1, ++ 0x46,0x2f,0x04,0xf0,0x37,0xd8,0x1e,0x72, ++ 0x24,0xa2,0x80,0x84,0x83,0x65,0x84,0xc0, ++ } ++ }, ++ { 0xa101248, { ++ 0xed,0x3b,0x95,0xa6,0x68,0xa7,0x77,0x3e, ++ 0xfc,0x17,0x26,0xe2,0x7b,0xd5,0x56,0x22, ++ 0x2c,0x1d,0xef,0xeb,0x56,0xdd,0xba,0x6e, ++ 0x1b,0x7d,0x64,0x9d,0x4b,0x53,0x13,0x75, ++ } ++ }, ++ { 0xa108108, { ++ 0xed,0xc2,0xec,0xa1,0x15,0xc6,0x65,0xe9, ++ 0xd0,0xef,0x39,0xaa,0x7f,0x55,0x06,0xc6, ++ 0xf5,0xd4,0x3f,0x7b,0x14,0xd5,0x60,0x2c, ++ 0x28,0x1e,0x9c,0x59,0x69,0x99,0x4d,0x16, ++ } ++ }, ++ { 0xa20102d, { ++ 0xf9,0x6e,0xf2,0x32,0xd3,0x0f,0x5f,0x11, ++ 0x59,0xa1,0xfe,0xcc,0xcd,0x9b,0x42,0x89, ++ 0x8b,0x89,0x2f,0xb5,0xbb,0x82,0xef,0x23, ++ 0x8c,0xe9,0x19,0x3e,0xcc,0x3f,0x7b,0xb4, ++ } ++ }, ++ { 0xa201210, { ++ 0xe8,0x6d,0x51,0x6a,0x8e,0x72,0xf3,0xfe, ++ 0x6e,0x16,0xbc,0x62,0x59,0x40,0x17,0xe9, ++ 0x6d,0x3d,0x0e,0x6b,0xa7,0xac,0xe3,0x68, ++ 0xf7,0x55,0xf0,0x13,0xbb,0x22,0xf6,0x41, ++ } ++ }, ++ { 0xa404107, { ++ 0xbb,0x04,0x4e,0x47,0xdd,0x5e,0x26,0x45, ++ 0x1a,0xc9,0x56,0x24,0xa4,0x4c,0x82,0xb0, ++ 0x8b,0x0d,0x9f,0xf9,0x3a,0xdf,0xc6,0x81, ++ 0x13,0xbc,0xc5,0x25,0xe4,0xc5,0xc3,0x99, ++ } ++ }, ++ { 0xa500011, { ++ 0x23,0x3d,0x70,0x7d,0x03,0xc3,0xc4,0xf4, ++ 0x2b,0x82,0xc6,0x05,0xda,0x80,0x0a,0xf1, ++ 0xd7,0x5b,0x65,0x3a,0x7d,0xab,0xdf,0xa2, ++ 0x11,0x5e,0x96,0x7e,0x71,0xe9,0xfc,0x74, ++ } ++ }, ++ { 0xa601209, { ++ 0x66,0x48,0xd4,0x09,0x05,0xcb,0x29,0x32, ++ 0x66,0xb7,0x9a,0x76,0xcd,0x11,0xf3,0x30, ++ 0x15,0x86,0xcc,0x5d,0x97,0x0f,0xc0,0x46, ++ 0xe8,0x73,0xe2,0xd6,0xdb,0xd2,0x77,0x1d, ++ } ++ }, ++ { 0xa704107, { ++ 0xf3,0xc6,0x58,0x26,0xee,0xac,0x3f,0xd6, ++ 0xce,0xa1,0x72,0x47,0x3b,0xba,0x2b,0x93, ++ 0x2a,0xad,0x8e,0x6b,0xea,0x9b,0xb7,0xc2, ++ 0x64,0x39,0x71,0x8c,0xce,0xe7,0x41,0x39, ++ } ++ }, ++ { 0xa705206, { ++ 0x8d,0xc0,0x76,0xbd,0x58,0x9f,0x8f,0xa4, ++ 0x12,0x9d,0x21,0xfb,0x48,0x21,0xbc,0xe7, ++ 0x67,0x6f,0x04,0x18,0xae,0x20,0x87,0x4b, ++ 0x03,0x35,0xe9,0xbe,0xfb,0x06,0xdf,0xfc, ++ } ++ }, ++ { 0xa708007, { ++ 0x6b,0x76,0xcc,0x78,0xc5,0x8a,0xa3,0xe3, ++ 0x32,0x2d,0x79,0xe4,0xc3,0x80,0xdb,0xb2, ++ 0x07,0xaa,0x3a,0xe0,0x57,0x13,0x72,0x80, ++ 0xdf,0x92,0x73,0x84,0x87,0x3c,0x73,0x93, ++ } ++ }, ++ { 0xa70c005, { ++ 0x88,0x5d,0xfb,0x79,0x64,0xd8,0x46,0x3b, ++ 0x4a,0x83,0x8e,0x77,0x7e,0xcf,0xb3,0x0f, ++ 0x1f,0x1f,0xf1,0x97,0xeb,0xfe,0x56,0x55, ++ 0xee,0x49,0xac,0xe1,0x8b,0x13,0xc5,0x13, ++ } ++ }, ++ { 0xaa00116, { ++ 0xe8,0x4c,0x2c,0x88,0xa1,0xac,0x24,0x63, ++ 0x65,0xe5,0xaa,0x2d,0x16,0xa9,0xc3,0xf5, ++ 0xfe,0x1d,0x5e,0x65,0xc7,0xaa,0x92,0x4d, ++ 0x91,0xee,0x76,0xbb,0x4c,0x66,0x78,0xc9, ++ } ++ }, ++ { 0xaa00212, { ++ 0xbd,0x57,0x5d,0x0a,0x0a,0x30,0xc1,0x75, ++ 0x95,0x58,0x5e,0x93,0x02,0x28,0x43,0x71, ++ 0xed,0x42,0x29,0xc8,0xec,0x34,0x2b,0xb2, ++ 0x1a,0x65,0x4b,0xfe,0x07,0x0f,0x34,0xa1, ++ } ++ }, ++ { 0xaa00213, { ++ 0xed,0x58,0xb7,0x76,0x81,0x7f,0xd9,0x3a, ++ 0x1a,0xff,0x8b,0x34,0xb8,0x4a,0x99,0x0f, ++ 0x28,0x49,0x6c,0x56,0x2b,0xdc,0xb7,0xed, ++ 0x96,0xd5,0x9d,0xc1,0x7a,0xd4,0x51,0x9b, ++ } ++ }, ++ { 0xaa00215, { ++ 0x55,0xd3,0x28,0xcb,0x87,0xa9,0x32,0xe9, ++ 0x4e,0x85,0x4b,0x7c,0x6b,0xd5,0x7c,0xd4, ++ 0x1b,0x51,0x71,0x3a,0x0e,0x0b,0xdc,0x9b, ++ 0x68,0x2f,0x46,0xee,0xfe,0xc6,0x6d,0xef, ++ } ++ }, ++}; +diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c +index a4ebd5e0ae8287..c15c7b862bec1c 100644 +--- a/arch/x86/kernel/cpu/microcode/core.c ++++ b/arch/x86/kernel/cpu/microcode/core.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -31,6 +32,7 @@ + #include + #include + ++#include + #include + #include + #include +@@ -42,11 +44,10 @@ + #define DRIVER_VERSION "2.2" + + static struct microcode_ops *microcode_ops; +-static bool dis_ucode_ldr = true; ++bool dis_ucode_ldr = true; + +-bool initrd_gone; +- +-LIST_HEAD(microcode_cache); ++bool force_minrev = IS_ENABLED(CONFIG_MICROCODE_LATE_FORCE_MINREV); ++module_param(force_minrev, bool, S_IRUSR | S_IWUSR); + + /* + * Synchronization. +@@ -76,6 +77,8 @@ static u32 final_levels[] = { + 0, /* T-101 terminator */ + }; + ++struct early_load_data early_data; ++ + /* + * Check the current patch level on this CPU. + * +@@ -90,10 +93,7 @@ static bool amd_check_current_patch_level(void) + + native_rdmsr(MSR_AMD64_PATCH_LEVEL, lvl, dummy); + +- if (IS_ENABLED(CONFIG_X86_32)) +- levels = (u32 *)__pa_nodebug(&final_levels); +- else +- levels = final_levels; ++ levels = final_levels; + + for (i = 0; levels[i]; i++) { + if (lvl == levels[i]) +@@ -105,17 +105,8 @@ static bool amd_check_current_patch_level(void) + static bool __init check_loader_disabled_bsp(void) + { + static const char *__dis_opt_str = "dis_ucode_ldr"; +- +-#ifdef CONFIG_X86_32 +- const char *cmdline = (const char *)__pa_nodebug(boot_command_line); +- const char *option = (const char *)__pa_nodebug(__dis_opt_str); +- bool *res = (bool *)__pa_nodebug(&dis_ucode_ldr); +- +-#else /* CONFIG_X86_64 */ + const char *cmdline = boot_command_line; + const char *option = __dis_opt_str; +- bool *res = &dis_ucode_ldr; +-#endif + + /* + * CPUID(1).ECX[31]: reserved for hypervisor use. This is still not +@@ -123,17 +114,17 @@ static bool __init check_loader_disabled_bsp(void) + * that's good enough as they don't land on the BSP path anyway. + */ + if (native_cpuid_ecx(1) & BIT(31)) +- return *res; ++ return true; + + if (x86_cpuid_vendor() == X86_VENDOR_AMD) { + if (amd_check_current_patch_level()) +- return *res; ++ return true; + } + + if (cmdline_find_option_bool(cmdline, option) <= 0) +- *res = false; ++ dis_ucode_ldr = false; + +- return *res; ++ return dis_ucode_ldr; + } + + void __init load_ucode_bsp(void) +@@ -166,25 +157,16 @@ void __init load_ucode_bsp(void) + return; + + if (intel) +- load_ucode_intel_bsp(); ++ load_ucode_intel_bsp(&early_data); + else +- load_ucode_amd_early(cpuid_1_eax); +-} +- +-static bool check_loader_disabled_ap(void) +-{ +-#ifdef CONFIG_X86_32 +- return *((bool *)__pa_nodebug(&dis_ucode_ldr)); +-#else +- return dis_ucode_ldr; +-#endif ++ load_ucode_amd_bsp(&early_data, cpuid_1_eax); + } + + void load_ucode_ap(void) + { + unsigned int cpuid_1_eax; + +- if (check_loader_disabled_ap()) ++ if (dis_ucode_ldr) + return; + + cpuid_1_eax = native_cpuid_eax(1); +@@ -196,103 +178,44 @@ void load_ucode_ap(void) + break; + case X86_VENDOR_AMD: + if (x86_family(cpuid_1_eax) >= 0x10) +- load_ucode_amd_early(cpuid_1_eax); ++ load_ucode_amd_ap(cpuid_1_eax); + break; + default: + break; + } + } + +-static int __init save_microcode_in_initrd(void) +-{ +- struct cpuinfo_x86 *c = &boot_cpu_data; +- int ret = -EINVAL; +- +- if (dis_ucode_ldr) { +- ret = 0; +- goto out; +- } +- +- switch (c->x86_vendor) { +- case X86_VENDOR_INTEL: +- if (c->x86 >= 6) +- ret = save_microcode_in_initrd_intel(); +- break; +- case X86_VENDOR_AMD: +- if (c->x86 >= 0x10) +- ret = save_microcode_in_initrd_amd(cpuid_eax(1)); +- break; +- default: +- break; +- } +- +-out: +- initrd_gone = true; +- +- return ret; +-} +- +-struct cpio_data find_microcode_in_initrd(const char *path, bool use_pa) ++struct cpio_data __init find_microcode_in_initrd(const char *path) + { + #ifdef CONFIG_BLK_DEV_INITRD + unsigned long start = 0; + size_t size; + + #ifdef CONFIG_X86_32 +- struct boot_params *params; +- +- if (use_pa) +- params = (struct boot_params *)__pa_nodebug(&boot_params); +- else +- params = &boot_params; +- +- size = params->hdr.ramdisk_size; +- +- /* +- * Set start only if we have an initrd image. We cannot use initrd_start +- * because it is not set that early yet. +- */ ++ size = boot_params.hdr.ramdisk_size; ++ /* Early load on BSP has a temporary mapping. */ + if (size) +- start = params->hdr.ramdisk_image; ++ start = initrd_start_early; + +-# else /* CONFIG_X86_64 */ ++#else /* CONFIG_X86_64 */ + size = (unsigned long)boot_params.ext_ramdisk_size << 32; + size |= boot_params.hdr.ramdisk_size; + + if (size) { + start = (unsigned long)boot_params.ext_ramdisk_image << 32; + start |= boot_params.hdr.ramdisk_image; +- + start += PAGE_OFFSET; + } +-# endif ++#endif + + /* + * Fixup the start address: after reserve_initrd() runs, initrd_start + * has the virtual address of the beginning of the initrd. It also + * possibly relocates the ramdisk. In either case, initrd_start contains + * the updated address so use that instead. +- * +- * initrd_gone is for the hotplug case where we've thrown out initrd +- * already. + */ +- if (!use_pa) { +- if (initrd_gone) +- return (struct cpio_data){ NULL, 0, "" }; +- if (initrd_start) +- start = initrd_start; +- } else { +- /* +- * The picture with physical addresses is a bit different: we +- * need to get the *physical* address to which the ramdisk was +- * relocated, i.e., relocated_ramdisk (not initrd_start) and +- * since we're running from physical addresses, we need to access +- * relocated_ramdisk through its *physical* address too. +- */ +- u64 *rr = (u64 *)__pa_nodebug(&relocated_ramdisk); +- if (*rr) +- start = *rr; +- } ++ if (initrd_start) ++ start = initrd_start; + + return find_cpio_data(path, (void *)start, size, NULL); + #else /* !CONFIG_BLK_DEV_INITRD */ +@@ -336,117 +259,298 @@ static struct platform_device *microcode_pdev; + * requirement can be relaxed in the future. Right now, this is conservative + * and good. + */ +-#define SPINUNIT 100 /* 100 nsec */ ++enum sibling_ctrl { ++ /* Spinwait with timeout */ ++ SCTRL_WAIT, ++ /* Invoke the microcode_apply() callback */ ++ SCTRL_APPLY, ++ /* Proceed without invoking the microcode_apply() callback */ ++ SCTRL_DONE, ++}; + +-static int check_online_cpus(void) ++struct microcode_ctrl { ++ enum sibling_ctrl ctrl; ++ enum ucode_state result; ++ unsigned int ctrl_cpu; ++ bool nmi_enabled; ++}; ++ ++DEFINE_STATIC_KEY_FALSE(microcode_nmi_handler_enable); ++static DEFINE_PER_CPU(struct microcode_ctrl, ucode_ctrl); ++static atomic_t late_cpus_in, offline_in_nmi; ++static unsigned int loops_per_usec; ++static cpumask_t cpu_offline_mask; ++ ++static noinstr bool wait_for_cpus(atomic_t *cnt) + { +- unsigned int cpu; ++ unsigned int timeout, loops; + +- /* +- * Make sure all CPUs are online. It's fine for SMT to be disabled if +- * all the primary threads are still online. +- */ +- for_each_present_cpu(cpu) { +- if (topology_is_primary_thread(cpu) && !cpu_online(cpu)) { +- pr_err("Not all CPUs online, aborting microcode update.\n"); +- return -EINVAL; ++ WARN_ON_ONCE(raw_atomic_dec_return(cnt) < 0); ++ ++ for (timeout = 0; timeout < USEC_PER_SEC; timeout++) { ++ if (!raw_atomic_read(cnt)) ++ return true; ++ ++ for (loops = 0; loops < loops_per_usec; loops++) ++ cpu_relax(); ++ ++ /* If invoked directly, tickle the NMI watchdog */ ++ if (!microcode_ops->use_nmi && !(timeout % USEC_PER_MSEC)) { ++ instrumentation_begin(); ++ touch_nmi_watchdog(); ++ instrumentation_end(); + } + } +- +- return 0; ++ /* Prevent the late comers from making progress and let them time out */ ++ raw_atomic_inc(cnt); ++ return false; + } + +-static atomic_t late_cpus_in; +-static atomic_t late_cpus_out; +- +-static int __wait_for_cpus(atomic_t *t, long long timeout) ++static noinstr bool wait_for_ctrl(void) + { +- int all_cpus = num_online_cpus(); +- +- atomic_inc(t); ++ unsigned int timeout, loops; + +- while (atomic_read(t) < all_cpus) { +- if (timeout < SPINUNIT) { +- pr_err("Timeout while waiting for CPUs rendezvous, remaining: %d\n", +- all_cpus - atomic_read(t)); +- return 1; +- } ++ for (timeout = 0; timeout < USEC_PER_SEC; timeout++) { ++ if (raw_cpu_read(ucode_ctrl.ctrl) != SCTRL_WAIT) ++ return true; + +- ndelay(SPINUNIT); +- timeout -= SPINUNIT; ++ for (loops = 0; loops < loops_per_usec; loops++) ++ cpu_relax(); + +- touch_nmi_watchdog(); ++ /* If invoked directly, tickle the NMI watchdog */ ++ if (!microcode_ops->use_nmi && !(timeout % USEC_PER_MSEC)) { ++ instrumentation_begin(); ++ touch_nmi_watchdog(); ++ instrumentation_end(); ++ } + } +- return 0; ++ return false; + } + + /* +- * Returns: +- * < 0 - on error +- * 0 - success (no update done or microcode was updated) ++ * Protected against instrumentation up to the point where the primary ++ * thread completed the update. See microcode_nmi_handler() for details. + */ +-static int __reload_late(void *info) ++static noinstr bool load_secondary_wait(unsigned int ctrl_cpu) + { +- int cpu = smp_processor_id(); +- enum ucode_state err; +- int ret = 0; ++ /* Initial rendezvous to ensure that all CPUs have arrived */ ++ if (!wait_for_cpus(&late_cpus_in)) { ++ raw_cpu_write(ucode_ctrl.result, UCODE_TIMEOUT); ++ return false; ++ } + + /* +- * Wait for all CPUs to arrive. A load will not be attempted unless all +- * CPUs show up. +- * */ +- if (__wait_for_cpus(&late_cpus_in, NSEC_PER_SEC)) +- return -1; ++ * Wait for primary threads to complete. If one of them hangs due ++ * to the update, there is no way out. This is non-recoverable ++ * because the CPU might hold locks or resources and confuse the ++ * scheduler, watchdogs etc. There is no way to safely evacuate the ++ * machine. ++ */ ++ if (wait_for_ctrl()) ++ return true; ++ ++ instrumentation_begin(); ++ panic("Microcode load: Primary CPU %d timed out\n", ctrl_cpu); ++ instrumentation_end(); ++} ++ ++/* ++ * Protected against instrumentation up to the point where the primary ++ * thread completed the update. See microcode_nmi_handler() for details. ++ */ ++static noinstr void load_secondary(unsigned int cpu) ++{ ++ unsigned int ctrl_cpu = raw_cpu_read(ucode_ctrl.ctrl_cpu); ++ enum ucode_state ret; ++ ++ if (!load_secondary_wait(ctrl_cpu)) { ++ instrumentation_begin(); ++ pr_err_once("load: %d CPUs timed out\n", ++ atomic_read(&late_cpus_in) - 1); ++ instrumentation_end(); ++ return; ++ } + ++ /* Primary thread completed. Allow to invoke instrumentable code */ ++ instrumentation_begin(); + /* +- * On an SMT system, it suffices to load the microcode on one sibling of +- * the core because the microcode engine is shared between the threads. +- * Synchronization still needs to take place so that no concurrent +- * loading attempts happen on multiple threads of an SMT core. See +- * below. ++ * If the primary succeeded then invoke the apply() callback, ++ * otherwise copy the state from the primary thread. + */ +- if (cpumask_first(topology_sibling_cpumask(cpu)) == cpu) +- err = microcode_ops->apply_microcode(cpu); ++ if (this_cpu_read(ucode_ctrl.ctrl) == SCTRL_APPLY) ++ ret = microcode_ops->apply_microcode(cpu); + else +- goto wait_for_siblings; ++ ret = per_cpu(ucode_ctrl.result, ctrl_cpu); + +- if (err >= UCODE_NFOUND) { +- if (err == UCODE_ERROR) { +- pr_warn("Error reloading microcode on CPU %d\n", cpu); +- ret = -1; +- } ++ this_cpu_write(ucode_ctrl.result, ret); ++ this_cpu_write(ucode_ctrl.ctrl, SCTRL_DONE); ++ instrumentation_end(); ++} ++ ++static void __load_primary(unsigned int cpu) ++{ ++ struct cpumask *secondaries = topology_sibling_cpumask(cpu); ++ enum sibling_ctrl ctrl; ++ enum ucode_state ret; ++ unsigned int sibling; ++ ++ /* Initial rendezvous to ensure that all CPUs have arrived */ ++ if (!wait_for_cpus(&late_cpus_in)) { ++ this_cpu_write(ucode_ctrl.result, UCODE_TIMEOUT); ++ pr_err_once("load: %d CPUs timed out\n", atomic_read(&late_cpus_in) - 1); ++ return; + } + +-wait_for_siblings: +- if (__wait_for_cpus(&late_cpus_out, NSEC_PER_SEC)) +- panic("Timeout during microcode update!\n"); ++ ret = microcode_ops->apply_microcode(cpu); ++ this_cpu_write(ucode_ctrl.result, ret); ++ this_cpu_write(ucode_ctrl.ctrl, SCTRL_DONE); + + /* +- * At least one thread has completed update on each core. +- * For others, simply call the update to make sure the +- * per-cpu cpuinfo can be updated with right microcode +- * revision. ++ * If the update was successful, let the siblings run the apply() ++ * callback. If not, tell them it's done. This also covers the ++ * case where the CPU has uniform loading at package or system ++ * scope implemented but does not advertise it. + */ +- if (cpumask_first(topology_sibling_cpumask(cpu)) != cpu) +- err = microcode_ops->apply_microcode(cpu); ++ if (ret == UCODE_UPDATED || ret == UCODE_OK) ++ ctrl = SCTRL_APPLY; ++ else ++ ctrl = SCTRL_DONE; ++ ++ for_each_cpu(sibling, secondaries) { ++ if (sibling != cpu) ++ per_cpu(ucode_ctrl.ctrl, sibling) = ctrl; ++ } ++} ++ ++static bool kick_offline_cpus(unsigned int nr_offl) ++{ ++ unsigned int cpu, timeout; ++ ++ for_each_cpu(cpu, &cpu_offline_mask) { ++ /* Enable the rendezvous handler and send NMI */ ++ per_cpu(ucode_ctrl.nmi_enabled, cpu) = true; ++ apic_send_nmi_to_offline_cpu(cpu); ++ } ++ ++ /* Wait for them to arrive */ ++ for (timeout = 0; timeout < (USEC_PER_SEC / 2); timeout++) { ++ if (atomic_read(&offline_in_nmi) == nr_offl) ++ return true; ++ udelay(1); ++ } ++ /* Let the others time out */ ++ return false; ++} ++ ++static void release_offline_cpus(void) ++{ ++ unsigned int cpu; ++ ++ for_each_cpu(cpu, &cpu_offline_mask) ++ per_cpu(ucode_ctrl.ctrl, cpu) = SCTRL_DONE; ++} ++ ++static void load_primary(unsigned int cpu) ++{ ++ unsigned int nr_offl = cpumask_weight(&cpu_offline_mask); ++ bool proceed = true; ++ ++ /* Kick soft-offlined SMT siblings if required */ ++ if (!cpu && nr_offl) ++ proceed = kick_offline_cpus(nr_offl); + +- return ret; ++ /* If the soft-offlined CPUs did not respond, abort */ ++ if (proceed) ++ __load_primary(cpu); ++ ++ /* Unconditionally release soft-offlined SMT siblings if required */ ++ if (!cpu && nr_offl) ++ release_offline_cpus(); + } + + /* +- * Reload microcode late on all CPUs. Wait for a sec until they +- * all gather together. ++ * Minimal stub rendezvous handler for soft-offlined CPUs which participate ++ * in the NMI rendezvous to protect against a concurrent NMI on affected ++ * CPUs. + */ +-static int microcode_reload_late(void) ++void noinstr microcode_offline_nmi_handler(void) + { +- int old = boot_cpu_data.microcode, ret; ++ if (!raw_cpu_read(ucode_ctrl.nmi_enabled)) ++ return; ++ raw_cpu_write(ucode_ctrl.nmi_enabled, false); ++ raw_cpu_write(ucode_ctrl.result, UCODE_OFFLINE); ++ raw_atomic_inc(&offline_in_nmi); ++ wait_for_ctrl(); ++} ++ ++static noinstr bool microcode_update_handler(void) ++{ ++ unsigned int cpu = raw_smp_processor_id(); ++ ++ if (raw_cpu_read(ucode_ctrl.ctrl_cpu) == cpu) { ++ instrumentation_begin(); ++ load_primary(cpu); ++ instrumentation_end(); ++ } else { ++ load_secondary(cpu); ++ } ++ ++ instrumentation_begin(); ++ touch_nmi_watchdog(); ++ instrumentation_end(); ++ ++ return true; ++} ++ ++/* ++ * Protection against instrumentation is required for CPUs which are not ++ * safe against an NMI which is delivered to the secondary SMT sibling ++ * while the primary thread updates the microcode. Instrumentation can end ++ * up in #INT3, #DB and #PF. The IRET from those exceptions reenables NMI ++ * which is the opposite of what the NMI rendezvous is trying to achieve. ++ * ++ * The primary thread is safe versus instrumentation as the actual ++ * microcode update handles this correctly. It's only the sibling code ++ * path which must be NMI safe until the primary thread completed the ++ * update. ++ */ ++bool noinstr microcode_nmi_handler(void) ++{ ++ if (!raw_cpu_read(ucode_ctrl.nmi_enabled)) ++ return false; ++ ++ raw_cpu_write(ucode_ctrl.nmi_enabled, false); ++ return microcode_update_handler(); ++} ++ ++static int load_cpus_stopped(void *unused) ++{ ++ if (microcode_ops->use_nmi) { ++ /* Enable the NMI handler and raise NMI */ ++ this_cpu_write(ucode_ctrl.nmi_enabled, true); ++ apic->send_IPI(smp_processor_id(), NMI_VECTOR); ++ } else { ++ /* Just invoke the handler directly */ ++ microcode_update_handler(); ++ } ++ return 0; ++} ++ ++static int load_late_stop_cpus(bool is_safe) ++{ ++ unsigned int cpu, updated = 0, failed = 0, timedout = 0, siblings = 0; ++ unsigned int nr_offl, offline = 0; ++ int old_rev = boot_cpu_data.microcode; + struct cpuinfo_x86 prev_info; + +- pr_err("Attempting late microcode loading - it is dangerous and taints the kernel.\n"); +- pr_err("You should switch to early loading, if possible.\n"); ++ if (!is_safe) { ++ pr_err("Late microcode loading without minimal revision check.\n"); ++ pr_err("You should switch to early loading, if possible.\n"); ++ } + +- atomic_set(&late_cpus_in, 0); +- atomic_set(&late_cpus_out, 0); ++ atomic_set(&late_cpus_in, num_online_cpus()); ++ atomic_set(&offline_in_nmi, 0); ++ loops_per_usec = loops_per_jiffy / (TICK_NSEC / 1000); + + /* + * Take a snapshot before the microcode update in order to compare and +@@ -454,52 +558,162 @@ static int microcode_reload_late(void) + */ + store_cpu_caps(&prev_info); + +- ret = stop_machine_cpuslocked(__reload_late, NULL, cpu_online_mask); +- if (!ret) { +- pr_info("Reload succeeded, microcode revision: 0x%x -> 0x%x\n", +- old, boot_cpu_data.microcode); +- microcode_check(&prev_info); +- } else { +- pr_info("Reload failed, current microcode revision: 0x%x\n", +- boot_cpu_data.microcode); ++ if (microcode_ops->use_nmi) ++ static_branch_enable_cpuslocked(µcode_nmi_handler_enable); ++ ++ stop_machine_cpuslocked(load_cpus_stopped, NULL, cpu_online_mask); ++ ++ if (microcode_ops->use_nmi) ++ static_branch_disable_cpuslocked(µcode_nmi_handler_enable); ++ ++ /* Analyze the results */ ++ for_each_cpu_and(cpu, cpu_present_mask, &cpus_booted_once_mask) { ++ switch (per_cpu(ucode_ctrl.result, cpu)) { ++ case UCODE_UPDATED: updated++; break; ++ case UCODE_TIMEOUT: timedout++; break; ++ case UCODE_OK: siblings++; break; ++ case UCODE_OFFLINE: offline++; break; ++ default: failed++; break; ++ } ++ } ++ ++ if (microcode_ops->finalize_late_load) ++ microcode_ops->finalize_late_load(!updated); ++ ++ if (!updated) { ++ /* Nothing changed. */ ++ if (!failed && !timedout) ++ return 0; ++ ++ nr_offl = cpumask_weight(&cpu_offline_mask); ++ if (offline < nr_offl) { ++ pr_warn("%u offline siblings did not respond.\n", ++ nr_offl - atomic_read(&offline_in_nmi)); ++ return -EIO; ++ } ++ pr_err("update failed: %u CPUs failed %u CPUs timed out\n", ++ failed, timedout); ++ return -EIO; ++ } ++ ++ if (!is_safe || failed || timedout) ++ add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_STILL_OK); ++ ++ pr_info("load: updated on %u primary CPUs with %u siblings\n", updated, siblings); ++ if (failed || timedout) { ++ pr_err("load incomplete. %u CPUs timed out or failed\n", ++ num_online_cpus() - (updated + siblings)); + } ++ pr_info("revision: 0x%x -> 0x%x\n", old_rev, boot_cpu_data.microcode); ++ microcode_check(&prev_info); + +- return ret; ++ return updated + siblings == num_online_cpus() ? 0 : -EIO; ++} ++ ++/* ++ * This function does two things: ++ * ++ * 1) Ensure that all required CPUs which are present and have been booted ++ * once are online. ++ * ++ * To pass this check, all primary threads must be online. ++ * ++ * If the microcode load is not safe against NMI then all SMT threads ++ * must be online as well because they still react to NMIs when they are ++ * soft-offlined and parked in one of the play_dead() variants. So if a ++ * NMI hits while the primary thread updates the microcode the resulting ++ * behaviour is undefined. The default play_dead() implementation on ++ * modern CPUs uses MWAIT, which is also not guaranteed to be safe ++ * against a microcode update which affects MWAIT. ++ * ++ * As soft-offlined CPUs still react on NMIs, the SMT sibling ++ * restriction can be lifted when the vendor driver signals to use NMI ++ * for rendezvous and the APIC provides a mechanism to send an NMI to a ++ * soft-offlined CPU. The soft-offlined CPUs are then able to ++ * participate in the rendezvous in a trivial stub handler. ++ * ++ * 2) Initialize the per CPU control structure and create a cpumask ++ * which contains "offline"; secondary threads, so they can be handled ++ * correctly by a control CPU. ++ */ ++static bool setup_cpus(void) ++{ ++ struct microcode_ctrl ctrl = { .ctrl = SCTRL_WAIT, .result = -1, }; ++ bool allow_smt_offline; ++ unsigned int cpu; ++ ++ allow_smt_offline = microcode_ops->nmi_safe || ++ (microcode_ops->use_nmi && apic->nmi_to_offline_cpu); ++ ++ cpumask_clear(&cpu_offline_mask); ++ ++ for_each_cpu_and(cpu, cpu_present_mask, &cpus_booted_once_mask) { ++ /* ++ * Offline CPUs sit in one of the play_dead() functions ++ * with interrupts disabled, but they still react on NMIs ++ * and execute arbitrary code. Also MWAIT being updated ++ * while the offline CPU sits there is not necessarily safe ++ * on all CPU variants. ++ * ++ * Mark them in the offline_cpus mask which will be handled ++ * by CPU0 later in the update process. ++ * ++ * Ensure that the primary thread is online so that it is ++ * guaranteed that all cores are updated. ++ */ ++ if (!cpu_online(cpu)) { ++ if (topology_is_primary_thread(cpu) || !allow_smt_offline) { ++ pr_err("CPU %u not online, loading aborted\n", cpu); ++ return false; ++ } ++ cpumask_set_cpu(cpu, &cpu_offline_mask); ++ per_cpu(ucode_ctrl, cpu) = ctrl; ++ continue; ++ } ++ ++ /* ++ * Initialize the per CPU state. This is core scope for now, ++ * but prepared to take package or system scope into account. ++ */ ++ ctrl.ctrl_cpu = cpumask_first(topology_sibling_cpumask(cpu)); ++ per_cpu(ucode_ctrl, cpu) = ctrl; ++ } ++ return true; ++} ++ ++static int load_late_locked(void) ++{ ++ if (!setup_cpus()) ++ return -EBUSY; ++ ++ switch (microcode_ops->request_microcode_fw(0, µcode_pdev->dev)) { ++ case UCODE_NEW: ++ return load_late_stop_cpus(false); ++ case UCODE_NEW_SAFE: ++ return load_late_stop_cpus(true); ++ case UCODE_NFOUND: ++ return -ENOENT; ++ default: ++ return -EBADFD; ++ } + } + + static ssize_t reload_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) + { +- enum ucode_state tmp_ret = UCODE_OK; +- int bsp = boot_cpu_data.cpu_index; + unsigned long val; +- ssize_t ret = 0; ++ ssize_t ret; + + ret = kstrtoul(buf, 0, &val); + if (ret || val != 1) + return -EINVAL; + + cpus_read_lock(); +- +- ret = check_online_cpus(); +- if (ret) +- goto put; +- +- tmp_ret = microcode_ops->request_microcode_fw(bsp, µcode_pdev->dev); +- if (tmp_ret != UCODE_NEW) +- goto put; +- +- ret = microcode_reload_late(); +-put: ++ ret = load_late_locked(); + cpus_read_unlock(); + +- if (ret == 0) +- ret = size; +- +- add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_STILL_OK); +- +- return ret; ++ return ret ? : size; + } + + static DEVICE_ATTR_WO(reload); +@@ -541,17 +755,6 @@ static void microcode_fini_cpu(int cpu) + microcode_ops->microcode_fini_cpu(cpu); + } + +-static enum ucode_state microcode_init_cpu(int cpu) +-{ +- struct ucode_cpu_info *uci = ucode_cpu_info + cpu; +- +- memset(uci, 0, sizeof(*uci)); +- +- microcode_ops->collect_cpu_info(cpu, &uci->cpu_sig); +- +- return microcode_ops->apply_microcode(cpu); +-} +- + /** + * microcode_bsp_resume - Update boot CPU microcode during resume. + */ +@@ -570,19 +773,18 @@ static struct syscore_ops mc_syscore_ops = { + .resume = microcode_bsp_resume, + }; + +-static int mc_cpu_starting(unsigned int cpu) +-{ +- enum ucode_state err = microcode_ops->apply_microcode(cpu); +- +- pr_debug("%s: CPU%d, err: %d\n", __func__, cpu, err); +- +- return err == UCODE_ERROR; +-} +- + static int mc_cpu_online(unsigned int cpu) + { ++ struct ucode_cpu_info *uci = ucode_cpu_info + cpu; + struct device *dev = get_cpu_device(cpu); + ++ memset(uci, 0, sizeof(*uci)); ++ ++ microcode_ops->collect_cpu_info(cpu, &uci->cpu_sig); ++ cpu_data(cpu).microcode = uci->cpu_sig.rev; ++ if (!cpu) ++ boot_cpu_data.microcode = uci->cpu_sig.rev; ++ + if (sysfs_create_group(&dev->kobj, &mc_attr_group)) + pr_err("Failed to create group for CPU%d\n", cpu); + return 0; +@@ -590,33 +792,13 @@ static int mc_cpu_online(unsigned int cpu) + + static int mc_cpu_down_prep(unsigned int cpu) + { +- struct device *dev; +- +- dev = get_cpu_device(cpu); ++ struct device *dev = get_cpu_device(cpu); + + microcode_fini_cpu(cpu); +- +- /* Suspend is in progress, only remove the interface */ + sysfs_remove_group(&dev->kobj, &mc_attr_group); +- pr_debug("%s: CPU%d\n", __func__, cpu); +- + return 0; + } + +-static void setup_online_cpu(struct work_struct *work) +-{ +- int cpu = smp_processor_id(); +- enum ucode_state err; +- +- err = microcode_init_cpu(cpu); +- if (err == UCODE_ERROR) { +- pr_err("Error applying microcode on CPU%d\n", cpu); +- return; +- } +- +- mc_cpu_online(cpu); +-} +- + static struct attribute *cpu_root_microcode_attrs[] = { + #ifdef CONFIG_MICROCODE_LATE_LOADING + &dev_attr_reload.attr, +@@ -648,6 +830,11 @@ static int __init microcode_init(void) + if (!microcode_ops) + return -ENODEV; + ++ pr_info_once("Current revision: 0x%08x\n", (early_data.new_rev ?: early_data.old_rev)); ++ ++ if (early_data.new_rev) ++ pr_info_once("Updated early from: 0x%08x\n", early_data.old_rev); ++ + microcode_pdev = platform_device_register_simple("microcode", -1, NULL, 0); + if (IS_ERR(microcode_pdev)) + return PTR_ERR(microcode_pdev); +@@ -662,14 +849,9 @@ static int __init microcode_init(void) + } + } + +- /* Do per-CPU setup */ +- schedule_on_each_cpu(setup_online_cpu); +- + register_syscore_ops(&mc_syscore_ops); +- cpuhp_setup_state_nocalls(CPUHP_AP_MICROCODE_LOADER, "x86/microcode:starting", +- mc_cpu_starting, NULL); +- cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, "x86/microcode:online", +- mc_cpu_online, mc_cpu_down_prep); ++ cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "x86/microcode:online", ++ mc_cpu_online, mc_cpu_down_prep); + + pr_info("Microcode Update Driver: v%s.", DRIVER_VERSION); + +@@ -680,5 +862,4 @@ static int __init microcode_init(void) + return error; + + } +-fs_initcall(save_microcode_in_initrd); + late_initcall(microcode_init); +diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c +index 94dd6af9c963a8..9d7baf2573bcde 100644 +--- a/arch/x86/kernel/cpu/microcode/intel.c ++++ b/arch/x86/kernel/cpu/microcode/intel.c +@@ -14,7 +14,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -32,11 +31,14 @@ + + static const char ucode_path[] = "kernel/x86/microcode/GenuineIntel.bin"; + ++#define UCODE_BSP_LOADED ((struct microcode_intel *)0x1UL) ++ + /* Current microcode patch used in early patching on the APs. */ +-static struct microcode_intel *intel_ucode_patch; ++static struct microcode_intel *ucode_patch_va __read_mostly; ++static struct microcode_intel *ucode_patch_late __read_mostly; + + /* last level cache size per core */ +-static int llc_size_per_core; ++static unsigned int llc_size_per_core __ro_after_init; + + /* microcode format is extended from prescott processors */ + struct extended_signature { +@@ -66,60 +68,52 @@ static inline unsigned int exttable_size(struct extended_sigtable *et) + return et->count * EXT_SIGNATURE_SIZE + EXT_HEADER_SIZE; + } + +-int intel_cpu_collect_info(struct ucode_cpu_info *uci) ++void intel_collect_cpu_info(struct cpu_signature *sig) + { +- unsigned int val[2]; +- unsigned int family, model; +- struct cpu_signature csig = { 0 }; +- unsigned int eax, ebx, ecx, edx; +- +- memset(uci, 0, sizeof(*uci)); +- +- eax = 0x00000001; +- ecx = 0; +- native_cpuid(&eax, &ebx, &ecx, &edx); +- csig.sig = eax; ++ sig->sig = cpuid_eax(1); ++ sig->pf = 0; ++ sig->rev = intel_get_microcode_revision(); + +- family = x86_family(eax); +- model = x86_model(eax); ++ if (x86_model(sig->sig) >= 5 || x86_family(sig->sig) > 6) { ++ unsigned int val[2]; + +- if (model >= 5 || family > 6) { + /* get processor flags from MSR 0x17 */ + native_rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]); +- csig.pf = 1 << ((val[1] >> 18) & 7); ++ sig->pf = 1 << ((val[1] >> 18) & 7); + } ++} ++EXPORT_SYMBOL_GPL(intel_collect_cpu_info); + +- csig.rev = intel_get_microcode_revision(); +- +- uci->cpu_sig = csig; ++static inline bool cpu_signatures_match(struct cpu_signature *s1, unsigned int sig2, ++ unsigned int pf2) ++{ ++ if (s1->sig != sig2) ++ return false; + +- return 0; ++ /* Processor flags are either both 0 or they intersect. */ ++ return ((!s1->pf && !pf2) || (s1->pf & pf2)); + } +-EXPORT_SYMBOL_GPL(intel_cpu_collect_info); + +-/* +- * Returns 1 if update has been found, 0 otherwise. +- */ +-int intel_find_matching_signature(void *mc, unsigned int csig, int cpf) ++bool intel_find_matching_signature(void *mc, struct cpu_signature *sig) + { + struct microcode_header_intel *mc_hdr = mc; +- struct extended_sigtable *ext_hdr; + struct extended_signature *ext_sig; ++ struct extended_sigtable *ext_hdr; + int i; + +- if (intel_cpu_signatures_match(csig, cpf, mc_hdr->sig, mc_hdr->pf)) +- return 1; ++ if (cpu_signatures_match(sig, mc_hdr->sig, mc_hdr->pf)) ++ return true; + + /* Look for ext. headers: */ + if (get_totalsize(mc_hdr) <= intel_microcode_get_datasize(mc_hdr) + MC_HEADER_SIZE) +- return 0; ++ return false; + + ext_hdr = mc + intel_microcode_get_datasize(mc_hdr) + MC_HEADER_SIZE; + ext_sig = (void *)ext_hdr + EXT_HEADER_SIZE; + + for (i = 0; i < ext_hdr->count; i++) { +- if (intel_cpu_signatures_match(csig, cpf, ext_sig->sig, ext_sig->pf)) +- return 1; ++ if (cpu_signatures_match(sig, ext_sig->sig, ext_sig->pf)) ++ return true; + ext_sig++; + } + return 0; +@@ -240,516 +234,245 @@ int intel_microcode_sanity_check(void *mc, bool print_err, int hdr_type) + } + EXPORT_SYMBOL_GPL(intel_microcode_sanity_check); + +-/* +- * Returns 1 if update has been found, 0 otherwise. +- */ +-static int has_newer_microcode(void *mc, unsigned int csig, int cpf, int new_rev) +-{ +- struct microcode_header_intel *mc_hdr = mc; +- +- if (mc_hdr->rev <= new_rev) +- return 0; +- +- return intel_find_matching_signature(mc, csig, cpf); +-} +- +-static struct ucode_patch *memdup_patch(void *data, unsigned int size) +-{ +- struct ucode_patch *p; +- +- p = kzalloc(sizeof(struct ucode_patch), GFP_KERNEL); +- if (!p) +- return NULL; +- +- p->data = kmemdup(data, size, GFP_KERNEL); +- if (!p->data) { +- kfree(p); +- return NULL; +- } +- +- return p; +-} +- +-static void save_microcode_patch(struct ucode_cpu_info *uci, void *data, unsigned int size) ++static void update_ucode_pointer(struct microcode_intel *mc) + { +- struct microcode_header_intel *mc_hdr, *mc_saved_hdr; +- struct ucode_patch *iter, *tmp, *p = NULL; +- bool prev_found = false; +- unsigned int sig, pf; +- +- mc_hdr = (struct microcode_header_intel *)data; +- +- list_for_each_entry_safe(iter, tmp, µcode_cache, plist) { +- mc_saved_hdr = (struct microcode_header_intel *)iter->data; +- sig = mc_saved_hdr->sig; +- pf = mc_saved_hdr->pf; +- +- if (intel_find_matching_signature(data, sig, pf)) { +- prev_found = true; +- +- if (mc_hdr->rev <= mc_saved_hdr->rev) +- continue; +- +- p = memdup_patch(data, size); +- if (!p) +- pr_err("Error allocating buffer %p\n", data); +- else { +- list_replace(&iter->plist, &p->plist); +- kfree(iter->data); +- kfree(iter); +- } +- } +- } ++ kvfree(ucode_patch_va); + + /* +- * There weren't any previous patches found in the list cache; save the +- * newly found. ++ * Save the virtual address for early loading and for eventual free ++ * on late loading. + */ +- if (!prev_found) { +- p = memdup_patch(data, size); +- if (!p) +- pr_err("Error allocating buffer for %p\n", data); +- else +- list_add_tail(&p->plist, µcode_cache); +- } +- +- if (!p) +- return; ++ ucode_patch_va = mc; ++} + +- if (!intel_find_matching_signature(p->data, uci->cpu_sig.sig, uci->cpu_sig.pf)) +- return; ++static void save_microcode_patch(struct microcode_intel *patch) ++{ ++ unsigned int size = get_totalsize(&patch->hdr); ++ struct microcode_intel *mc; + +- /* +- * Save for early loading. On 32-bit, that needs to be a physical +- * address as the APs are running from physical addresses, before +- * paging has been enabled. +- */ +- if (IS_ENABLED(CONFIG_X86_32)) +- intel_ucode_patch = (struct microcode_intel *)__pa_nodebug(p->data); ++ mc = kvmemdup(patch, size, GFP_KERNEL); ++ if (mc) ++ update_ucode_pointer(mc); + else +- intel_ucode_patch = p->data; ++ pr_err("Unable to allocate microcode memory size: %u\n", size); + } + +-/* +- * Get microcode matching with BSP's model. Only CPUs with the same model as +- * BSP can stay in the platform. +- */ +-static struct microcode_intel * +-scan_microcode(void *data, size_t size, struct ucode_cpu_info *uci, bool save) ++/* Scan blob for microcode matching the boot CPUs family, model, stepping */ ++static __init struct microcode_intel *scan_microcode(void *data, size_t size, ++ struct ucode_cpu_info *uci, ++ bool save) + { + struct microcode_header_intel *mc_header; + struct microcode_intel *patch = NULL; ++ u32 cur_rev = uci->cpu_sig.rev; + unsigned int mc_size; + +- while (size) { +- if (size < sizeof(struct microcode_header_intel)) +- break; +- ++ for (; size >= sizeof(struct microcode_header_intel); size -= mc_size, data += mc_size) { + mc_header = (struct microcode_header_intel *)data; + + mc_size = get_totalsize(mc_header); +- if (!mc_size || +- mc_size > size || ++ if (!mc_size || mc_size > size || + intel_microcode_sanity_check(data, false, MC_HEADER_TYPE_MICROCODE) < 0) + break; + +- size -= mc_size; +- +- if (!intel_find_matching_signature(data, uci->cpu_sig.sig, +- uci->cpu_sig.pf)) { +- data += mc_size; ++ if (!intel_find_matching_signature(data, &uci->cpu_sig)) + continue; +- } + ++ /* ++ * For saving the early microcode, find the matching revision which ++ * was loaded on the BSP. ++ * ++ * On the BSP during early boot, find a newer revision than ++ * actually loaded in the CPU. ++ */ + if (save) { +- save_microcode_patch(uci, data, mc_size); +- goto next; +- } +- +- +- if (!patch) { +- if (!has_newer_microcode(data, +- uci->cpu_sig.sig, +- uci->cpu_sig.pf, +- uci->cpu_sig.rev)) +- goto next; +- +- } else { +- struct microcode_header_intel *phdr = &patch->hdr; +- +- if (!has_newer_microcode(data, +- phdr->sig, +- phdr->pf, +- phdr->rev)) +- goto next; ++ if (cur_rev != mc_header->rev) ++ continue; ++ } else if (cur_rev >= mc_header->rev) { ++ continue; + } + +- /* We have a newer patch, save it. */ + patch = data; +- +-next: +- data += mc_size; ++ cur_rev = mc_header->rev; + } + +- if (size) +- return NULL; +- +- return patch; ++ return size ? NULL : patch; + } + +-static bool load_builtin_intel_microcode(struct cpio_data *cp) ++static enum ucode_state __apply_microcode(struct ucode_cpu_info *uci, ++ struct microcode_intel *mc, ++ u32 *cur_rev) + { +- unsigned int eax = 1, ebx, ecx = 0, edx; +- struct firmware fw; +- char name[30]; +- +- if (IS_ENABLED(CONFIG_X86_32)) +- return false; +- +- native_cpuid(&eax, &ebx, &ecx, &edx); +- +- sprintf(name, "intel-ucode/%02x-%02x-%02x", +- x86_family(eax), x86_model(eax), x86_stepping(eax)); +- +- if (firmware_request_builtin(&fw, name)) { +- cp->size = fw.size; +- cp->data = (void *)fw.data; +- return true; +- } +- +- return false; +-} +- +-static void print_ucode_info(int old_rev, int new_rev, unsigned int date) +-{ +- pr_info_once("updated early: 0x%x -> 0x%x, date = %04x-%02x-%02x\n", +- old_rev, +- new_rev, +- date & 0xffff, +- date >> 24, +- (date >> 16) & 0xff); +-} +- +-#ifdef CONFIG_X86_32 +- +-static int delay_ucode_info; +-static int current_mc_date; +-static int early_old_rev; +- +-/* +- * Print early updated ucode info after printk works. This is delayed info dump. +- */ +-void show_ucode_info_early(void) +-{ +- struct ucode_cpu_info uci; +- +- if (delay_ucode_info) { +- intel_cpu_collect_info(&uci); +- print_ucode_info(early_old_rev, uci.cpu_sig.rev, current_mc_date); +- delay_ucode_info = 0; +- } +-} +- +-/* +- * At this point, we can not call printk() yet. Delay printing microcode info in +- * show_ucode_info_early() until printk() works. +- */ +-static void print_ucode(int old_rev, int new_rev, int date) +-{ +- int *delay_ucode_info_p; +- int *current_mc_date_p; +- int *early_old_rev_p; +- +- delay_ucode_info_p = (int *)__pa_nodebug(&delay_ucode_info); +- current_mc_date_p = (int *)__pa_nodebug(¤t_mc_date); +- early_old_rev_p = (int *)__pa_nodebug(&early_old_rev); +- +- *delay_ucode_info_p = 1; +- *current_mc_date_p = date; +- *early_old_rev_p = old_rev; +-} +-#else +- +-static inline void print_ucode(int old_rev, int new_rev, int date) +-{ +- print_ucode_info(old_rev, new_rev, date); +-} +-#endif +- +-static int apply_microcode_early(struct ucode_cpu_info *uci, bool early) +-{ +- struct microcode_intel *mc; +- u32 rev, old_rev; ++ u32 rev; + +- mc = uci->mc; + if (!mc) +- return 0; ++ return UCODE_NFOUND; + + /* + * Save us the MSR write below - which is a particular expensive + * operation - when the other hyperthread has updated the microcode + * already. + */ +- rev = intel_get_microcode_revision(); +- if (rev >= mc->hdr.rev) { +- uci->cpu_sig.rev = rev; ++ *cur_rev = intel_get_microcode_revision(); ++ if (*cur_rev >= mc->hdr.rev) { ++ uci->cpu_sig.rev = *cur_rev; + return UCODE_OK; + } + +- old_rev = rev; +- +- /* +- * Writeback and invalidate caches before updating microcode to avoid +- * internal issues depending on what the microcode is updating. +- */ +- native_wbinvd(); +- + /* write microcode via MSR 0x79 */ + native_wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc->bits); + + rev = intel_get_microcode_revision(); + if (rev != mc->hdr.rev) +- return -1; ++ return UCODE_ERROR; + + uci->cpu_sig.rev = rev; ++ return UCODE_UPDATED; ++} + +- if (early) +- print_ucode(old_rev, uci->cpu_sig.rev, mc->hdr.date); +- else +- print_ucode_info(old_rev, uci->cpu_sig.rev, mc->hdr.date); ++static enum ucode_state apply_microcode_early(struct ucode_cpu_info *uci) ++{ ++ struct microcode_intel *mc = uci->mc; ++ u32 cur_rev; + +- return 0; ++ return __apply_microcode(uci, mc, &cur_rev); + } + +-int __init save_microcode_in_initrd_intel(void) ++static __init bool load_builtin_intel_microcode(struct cpio_data *cp) + { +- struct ucode_cpu_info uci; +- struct cpio_data cp; +- +- /* +- * initrd is going away, clear patch ptr. We will scan the microcode one +- * last time before jettisoning and save a patch, if found. Then we will +- * update that pointer too, with a stable patch address to use when +- * resuming the cores. +- */ +- intel_ucode_patch = NULL; ++ unsigned int eax = 1, ebx, ecx = 0, edx; ++ struct firmware fw; ++ char name[30]; + +- if (!load_builtin_intel_microcode(&cp)) +- cp = find_microcode_in_initrd(ucode_path, false); ++ if (IS_ENABLED(CONFIG_X86_32)) ++ return false; + +- if (!(cp.data && cp.size)) +- return 0; ++ native_cpuid(&eax, &ebx, &ecx, &edx); + +- intel_cpu_collect_info(&uci); ++ sprintf(name, "intel-ucode/%02x-%02x-%02x", ++ x86_family(eax), x86_model(eax), x86_stepping(eax)); + +- scan_microcode(cp.data, cp.size, &uci, true); +- return 0; ++ if (firmware_request_builtin(&fw, name)) { ++ cp->size = fw.size; ++ cp->data = (void *)fw.data; ++ return true; ++ } ++ return false; + } + +-/* +- * @res_patch, output: a pointer to the patch we found. +- */ +-static struct microcode_intel *__load_ucode_intel(struct ucode_cpu_info *uci) ++static __init struct microcode_intel *get_microcode_blob(struct ucode_cpu_info *uci, bool save) + { +- static const char *path; + struct cpio_data cp; +- bool use_pa; +- +- if (IS_ENABLED(CONFIG_X86_32)) { +- path = (const char *)__pa_nodebug(ucode_path); +- use_pa = true; +- } else { +- path = ucode_path; +- use_pa = false; +- } + +- /* try built-in microcode first */ ++ intel_collect_cpu_info(&uci->cpu_sig); ++ + if (!load_builtin_intel_microcode(&cp)) +- cp = find_microcode_in_initrd(path, use_pa); ++ cp = find_microcode_in_initrd(ucode_path); + + if (!(cp.data && cp.size)) + return NULL; + +- intel_cpu_collect_info(uci); +- +- return scan_microcode(cp.data, cp.size, uci, false); ++ return scan_microcode(cp.data, cp.size, uci, save); + } + +-void __init load_ucode_intel_bsp(void) ++/* ++ * Invoked from an early init call to save the microcode blob which was ++ * selected during early boot when mm was not usable. The microcode must be ++ * saved because initrd is going away. It's an early init call so the APs ++ * just can use the pointer and do not have to scan initrd/builtin firmware ++ * again. ++ */ ++static int __init save_builtin_microcode(void) + { +- struct microcode_intel *patch; + struct ucode_cpu_info uci; + +- patch = __load_ucode_intel(&uci); +- if (!patch) +- return; ++ if (xchg(&ucode_patch_va, NULL) != UCODE_BSP_LOADED) ++ return 0; + +- uci.mc = patch; ++ if (dis_ucode_ldr || boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) ++ return 0; + +- apply_microcode_early(&uci, true); ++ uci.mc = get_microcode_blob(&uci, true); ++ if (uci.mc) ++ save_microcode_patch(uci.mc); ++ return 0; + } ++early_initcall(save_builtin_microcode); + +-void load_ucode_intel_ap(void) ++/* Load microcode on BSP from initrd or builtin blobs */ ++void __init load_ucode_intel_bsp(struct early_load_data *ed) + { +- struct microcode_intel *patch, **iup; + struct ucode_cpu_info uci; + +- if (IS_ENABLED(CONFIG_X86_32)) +- iup = (struct microcode_intel **) __pa_nodebug(&intel_ucode_patch); +- else +- iup = &intel_ucode_patch; ++ uci.mc = get_microcode_blob(&uci, false); ++ ed->old_rev = uci.cpu_sig.rev; + +- if (!*iup) { +- patch = __load_ucode_intel(&uci); +- if (!patch) +- return; +- +- *iup = patch; ++ if (uci.mc && apply_microcode_early(&uci) == UCODE_UPDATED) { ++ ucode_patch_va = UCODE_BSP_LOADED; ++ ed->new_rev = uci.cpu_sig.rev; + } +- +- uci.mc = *iup; +- +- apply_microcode_early(&uci, true); + } + +-static struct microcode_intel *find_patch(struct ucode_cpu_info *uci) ++void load_ucode_intel_ap(void) + { +- struct microcode_header_intel *phdr; +- struct ucode_patch *iter, *tmp; +- +- list_for_each_entry_safe(iter, tmp, µcode_cache, plist) { +- +- phdr = (struct microcode_header_intel *)iter->data; +- +- if (phdr->rev <= uci->cpu_sig.rev) +- continue; +- +- if (!intel_find_matching_signature(phdr, +- uci->cpu_sig.sig, +- uci->cpu_sig.pf)) +- continue; ++ struct ucode_cpu_info uci; + +- return iter->data; +- } +- return NULL; ++ uci.mc = ucode_patch_va; ++ if (uci.mc) ++ apply_microcode_early(&uci); + } + ++/* Reload microcode on resume */ + void reload_ucode_intel(void) + { +- struct microcode_intel *p; +- struct ucode_cpu_info uci; +- +- intel_cpu_collect_info(&uci); +- +- p = find_patch(&uci); +- if (!p) +- return; +- +- uci.mc = p; ++ struct ucode_cpu_info uci = { .mc = ucode_patch_va, }; + +- apply_microcode_early(&uci, false); ++ if (uci.mc) ++ apply_microcode_early(&uci); + } + + static int collect_cpu_info(int cpu_num, struct cpu_signature *csig) + { +- struct cpuinfo_x86 *c = &cpu_data(cpu_num); +- unsigned int val[2]; +- +- memset(csig, 0, sizeof(*csig)); +- +- csig->sig = cpuid_eax(0x00000001); +- +- if ((c->x86_model >= 5) || (c->x86 > 6)) { +- /* get processor flags from MSR 0x17 */ +- rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]); +- csig->pf = 1 << ((val[1] >> 18) & 7); +- } +- +- csig->rev = c->microcode; +- ++ intel_collect_cpu_info(csig); + return 0; + } + +-static enum ucode_state apply_microcode_intel(int cpu) ++static enum ucode_state apply_microcode_late(int cpu) + { + struct ucode_cpu_info *uci = ucode_cpu_info + cpu; +- struct cpuinfo_x86 *c = &cpu_data(cpu); +- bool bsp = c->cpu_index == boot_cpu_data.cpu_index; +- struct microcode_intel *mc; ++ struct microcode_intel *mc = ucode_patch_late; + enum ucode_state ret; +- static int prev_rev; +- u32 rev; ++ u32 cur_rev; + +- /* We should bind the task to the CPU */ +- if (WARN_ON(raw_smp_processor_id() != cpu)) ++ if (WARN_ON_ONCE(smp_processor_id() != cpu)) + return UCODE_ERROR; + +- /* Look for a newer patch in our cache: */ +- mc = find_patch(uci); +- if (!mc) { +- mc = uci->mc; +- if (!mc) +- return UCODE_NFOUND; +- } ++ ret = __apply_microcode(uci, mc, &cur_rev); ++ if (ret != UCODE_UPDATED && ret != UCODE_OK) ++ return ret; + +- /* +- * Save us the MSR write below - which is a particular expensive +- * operation - when the other hyperthread has updated the microcode +- * already. +- */ +- rev = intel_get_microcode_revision(); +- if (rev >= mc->hdr.rev) { +- ret = UCODE_OK; +- goto out; +- } +- +- /* +- * Writeback and invalidate caches before updating microcode to avoid +- * internal issues depending on what the microcode is updating. +- */ +- native_wbinvd(); +- +- /* write microcode via MSR 0x79 */ +- wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc->bits); +- +- rev = intel_get_microcode_revision(); +- +- if (rev != mc->hdr.rev) { +- pr_err("CPU%d update to revision 0x%x failed\n", +- cpu, mc->hdr.rev); +- return UCODE_ERROR; +- } +- +- if (bsp && rev != prev_rev) { +- pr_info("updated to revision 0x%x, date = %04x-%02x-%02x\n", +- rev, +- mc->hdr.date & 0xffff, +- mc->hdr.date >> 24, ++ if (!cpu && uci->cpu_sig.rev != cur_rev) { ++ pr_info("Updated to revision 0x%x, date = %04x-%02x-%02x\n", ++ uci->cpu_sig.rev, mc->hdr.date & 0xffff, mc->hdr.date >> 24, + (mc->hdr.date >> 16) & 0xff); +- prev_rev = rev; + } + +- ret = UCODE_UPDATED; +- +-out: +- uci->cpu_sig.rev = rev; +- c->microcode = rev; +- +- /* Update boot_cpu_data's revision too, if we're on the BSP: */ +- if (bsp) +- boot_cpu_data.microcode = rev; ++ cpu_data(cpu).microcode = uci->cpu_sig.rev; ++ if (!cpu) ++ boot_cpu_data.microcode = uci->cpu_sig.rev; + + return ret; + } + +-static enum ucode_state generic_load_microcode(int cpu, struct iov_iter *iter) ++static enum ucode_state parse_microcode_blobs(int cpu, struct iov_iter *iter) + { + struct ucode_cpu_info *uci = ucode_cpu_info + cpu; +- unsigned int curr_mc_size = 0, new_mc_size = 0; +- enum ucode_state ret = UCODE_OK; +- int new_rev = uci->cpu_sig.rev; ++ int cur_rev = uci->cpu_sig.rev; ++ unsigned int curr_mc_size = 0; + u8 *new_mc = NULL, *mc = NULL; +- unsigned int csig, cpf; ++ ++ if (force_minrev) ++ return UCODE_NFOUND; + + while (iov_iter_count(iter)) { + struct microcode_header_intel mc_header; +@@ -758,68 +481,61 @@ static enum ucode_state generic_load_microcode(int cpu, struct iov_iter *iter) + + if (!copy_from_iter_full(&mc_header, sizeof(mc_header), iter)) { + pr_err("error! Truncated or inaccessible header in microcode data file\n"); +- break; ++ goto fail; + } + + mc_size = get_totalsize(&mc_header); + if (mc_size < sizeof(mc_header)) { + pr_err("error! Bad data in microcode data file (totalsize too small)\n"); +- break; ++ goto fail; + } + data_size = mc_size - sizeof(mc_header); + if (data_size > iov_iter_count(iter)) { + pr_err("error! Bad data in microcode data file (truncated file?)\n"); +- break; ++ goto fail; + } + + /* For performance reasons, reuse mc area when possible */ + if (!mc || mc_size > curr_mc_size) { +- vfree(mc); +- mc = vmalloc(mc_size); ++ kvfree(mc); ++ mc = kvmalloc(mc_size, GFP_KERNEL); + if (!mc) +- break; ++ goto fail; + curr_mc_size = mc_size; + } + + memcpy(mc, &mc_header, sizeof(mc_header)); + data = mc + sizeof(mc_header); + if (!copy_from_iter_full(data, data_size, iter) || +- intel_microcode_sanity_check(mc, true, MC_HEADER_TYPE_MICROCODE) < 0) { +- break; +- } ++ intel_microcode_sanity_check(mc, true, MC_HEADER_TYPE_MICROCODE) < 0) ++ goto fail; + +- csig = uci->cpu_sig.sig; +- cpf = uci->cpu_sig.pf; +- if (has_newer_microcode(mc, csig, cpf, new_rev)) { +- vfree(new_mc); +- new_rev = mc_header.rev; +- new_mc = mc; +- new_mc_size = mc_size; +- mc = NULL; /* trigger new vmalloc */ +- ret = UCODE_NEW; +- } +- } ++ if (cur_rev >= mc_header.rev) ++ continue; + +- vfree(mc); ++ if (!intel_find_matching_signature(mc, &uci->cpu_sig)) ++ continue; + +- if (iov_iter_count(iter)) { +- vfree(new_mc); +- return UCODE_ERROR; ++ kvfree(new_mc); ++ cur_rev = mc_header.rev; ++ new_mc = mc; ++ mc = NULL; + } + ++ if (iov_iter_count(iter)) ++ goto fail; ++ ++ kvfree(mc); + if (!new_mc) + return UCODE_NFOUND; + +- vfree(uci->mc); +- uci->mc = (struct microcode_intel *)new_mc; +- +- /* Save for CPU hotplug */ +- save_microcode_patch(uci, new_mc, new_mc_size); ++ ucode_patch_late = (struct microcode_intel *)new_mc; ++ return UCODE_NEW; + +- pr_debug("CPU%d found a matching microcode update with version 0x%x (current=0x%x)\n", +- cpu, new_rev, uci->cpu_sig.rev); +- +- return ret; ++fail: ++ kvfree(mc); ++ kvfree(new_mc); ++ return UCODE_ERROR; + } + + static bool is_blacklisted(unsigned int cpu) +@@ -829,7 +545,7 @@ static bool is_blacklisted(unsigned int cpu) + /* + * Late loading on model 79 with microcode revision less than 0x0b000021 + * and LLC size per core bigger than 2.5MB may result in a system hang. +- * This behavior is documented in item BDF90, #334165 (Intel Xeon ++ * This behavior is documented in item BDX90, #334165 (Intel Xeon + * Processor E7-8800/4800 v4 Product Family). + */ + if (c->x86 == 6 && +@@ -837,7 +553,7 @@ static bool is_blacklisted(unsigned int cpu) + c->x86_stepping == 0x01 && + llc_size_per_core > 2621440 && + c->microcode < 0x0b000021) { +- pr_err_once("Erratum BDF90: late loading with revision < 0x0b000021 (0x%x) disabled.\n", c->microcode); ++ pr_err_once("Erratum BDX90: late loading with revision < 0x0b000021 (0x%x) disabled.\n", c->microcode); + pr_err_once("Please consider either early loading through initrd/built-in or a potential BIOS update.\n"); + return true; + } +@@ -868,26 +584,36 @@ static enum ucode_state request_microcode_fw(int cpu, struct device *device) + kvec.iov_base = (void *)firmware->data; + kvec.iov_len = firmware->size; + iov_iter_kvec(&iter, ITER_SOURCE, &kvec, 1, firmware->size); +- ret = generic_load_microcode(cpu, &iter); ++ ret = parse_microcode_blobs(cpu, &iter); + + release_firmware(firmware); + + return ret; + } + ++static void finalize_late_load(int result) ++{ ++ if (!result) ++ update_ucode_pointer(ucode_patch_late); ++ else ++ kvfree(ucode_patch_late); ++ ucode_patch_late = NULL; ++} ++ + static struct microcode_ops microcode_intel_ops = { +- .request_microcode_fw = request_microcode_fw, +- .collect_cpu_info = collect_cpu_info, +- .apply_microcode = apply_microcode_intel, ++ .request_microcode_fw = request_microcode_fw, ++ .collect_cpu_info = collect_cpu_info, ++ .apply_microcode = apply_microcode_late, ++ .finalize_late_load = finalize_late_load, ++ .use_nmi = IS_ENABLED(CONFIG_X86_64), + }; + +-static int __init calc_llc_size_per_core(struct cpuinfo_x86 *c) ++static __init void calc_llc_size_per_core(struct cpuinfo_x86 *c) + { + u64 llc_size = c->x86_cache_size * 1024ULL; + + do_div(llc_size, c->x86_max_cores); +- +- return (int)llc_size; ++ llc_size_per_core = (unsigned int)llc_size; + } + + struct microcode_ops * __init init_intel_microcode(void) +@@ -900,7 +626,7 @@ struct microcode_ops * __init init_intel_microcode(void) + return NULL; + } + +- llc_size_per_core = calc_llc_size_per_core(c); ++ calc_llc_size_per_core(c); + + return µcode_intel_ops; + } +diff --git a/arch/x86/kernel/cpu/microcode/internal.h b/arch/x86/kernel/cpu/microcode/internal.h +index bf883aa712330a..21776c529fa97a 100644 +--- a/arch/x86/kernel/cpu/microcode/internal.h ++++ b/arch/x86/kernel/cpu/microcode/internal.h +@@ -8,43 +8,43 @@ + #include + #include + +-struct ucode_patch { +- struct list_head plist; +- void *data; /* Intel uses only this one */ +- unsigned int size; +- u32 patch_id; +- u16 equiv_cpu; +-}; +- +-extern struct list_head microcode_cache; +- + struct device; + + enum ucode_state { + UCODE_OK = 0, + UCODE_NEW, ++ UCODE_NEW_SAFE, + UCODE_UPDATED, + UCODE_NFOUND, + UCODE_ERROR, ++ UCODE_TIMEOUT, ++ UCODE_OFFLINE, + }; + + struct microcode_ops { + enum ucode_state (*request_microcode_fw)(int cpu, struct device *dev); +- + void (*microcode_fini_cpu)(int cpu); + + /* +- * The generic 'microcode_core' part guarantees that +- * the callbacks below run on a target cpu when they +- * are being called. ++ * The generic 'microcode_core' part guarantees that the callbacks ++ * below run on a target CPU when they are being called. + * See also the "Synchronization" section in microcode_core.c. + */ +- enum ucode_state (*apply_microcode)(int cpu); +- int (*collect_cpu_info)(int cpu, struct cpu_signature *csig); ++ enum ucode_state (*apply_microcode)(int cpu); ++ int (*collect_cpu_info)(int cpu, struct cpu_signature *csig); ++ void (*finalize_late_load)(int result); ++ unsigned int nmi_safe : 1, ++ use_nmi : 1; ++}; ++ ++struct early_load_data { ++ u32 old_rev; ++ u32 new_rev; + }; + ++extern struct early_load_data early_data; + extern struct ucode_cpu_info ucode_cpu_info[]; +-struct cpio_data find_microcode_in_initrd(const char *path, bool use_pa); ++struct cpio_data find_microcode_in_initrd(const char *path); + + #define MAX_UCODE_COUNT 128 + +@@ -94,20 +94,19 @@ static inline unsigned int x86_cpuid_family(void) + return x86_family(eax); + } + +-extern bool initrd_gone; ++extern bool dis_ucode_ldr; ++extern bool force_minrev; + + #ifdef CONFIG_CPU_SUP_AMD +-void load_ucode_amd_bsp(unsigned int family); ++void load_ucode_amd_bsp(struct early_load_data *ed, unsigned int family); + void load_ucode_amd_ap(unsigned int family); +-void load_ucode_amd_early(unsigned int cpuid_1_eax); + int save_microcode_in_initrd_amd(unsigned int family); + void reload_ucode_amd(unsigned int cpu); + struct microcode_ops *init_amd_microcode(void); + void exit_amd_microcode(void); + #else /* CONFIG_CPU_SUP_AMD */ +-static inline void load_ucode_amd_bsp(unsigned int family) { } ++static inline void load_ucode_amd_bsp(struct early_load_data *ed, unsigned int family) { } + static inline void load_ucode_amd_ap(unsigned int family) { } +-static inline void load_ucode_amd_early(unsigned int family) { } + static inline int save_microcode_in_initrd_amd(unsigned int family) { return -EINVAL; } + static inline void reload_ucode_amd(unsigned int cpu) { } + static inline struct microcode_ops *init_amd_microcode(void) { return NULL; } +@@ -115,15 +114,13 @@ static inline void exit_amd_microcode(void) { } + #endif /* !CONFIG_CPU_SUP_AMD */ + + #ifdef CONFIG_CPU_SUP_INTEL +-void load_ucode_intel_bsp(void); ++void load_ucode_intel_bsp(struct early_load_data *ed); + void load_ucode_intel_ap(void); +-int save_microcode_in_initrd_intel(void); + void reload_ucode_intel(void); + struct microcode_ops *init_intel_microcode(void); + #else /* CONFIG_CPU_SUP_INTEL */ +-static inline void load_ucode_intel_bsp(void) { } ++static inline void load_ucode_intel_bsp(struct early_load_data *ed) { } + static inline void load_ucode_intel_ap(void) { } +-static inline int save_microcode_in_initrd_intel(void) { return -EINVAL; } + static inline void reload_ucode_intel(void) { } + static inline struct microcode_ops *init_intel_microcode(void) { return NULL; } + #endif /* !CONFIG_CPU_SUP_INTEL */ +diff --git a/arch/x86/kernel/head32.c b/arch/x86/kernel/head32.c +index 246a609f889b20..bde27a35bf2e28 100644 +--- a/arch/x86/kernel/head32.c ++++ b/arch/x86/kernel/head32.c +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -34,6 +35,8 @@ asmlinkage __visible void __init __noreturn i386_start_kernel(void) + /* Make sure IDT is set up before any exception happens */ + idt_setup_early_handler(); + ++ load_ucode_bsp(); ++ + cr4_init_shadow(); + + sanitize_boot_params(&boot_params); +diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S +index c9318993f95945..63f6ff4b28eb17 100644 +--- a/arch/x86/kernel/head_32.S ++++ b/arch/x86/kernel/head_32.S +@@ -118,11 +118,6 @@ SYM_CODE_START(startup_32) + movl %eax, pa(olpc_ofw_pgd) + #endif + +-#ifdef CONFIG_MICROCODE +- /* Early load ucode on BSP. */ +- call load_ucode_bsp +-#endif +- + /* Create early pagetables. */ + call mk_early_pgtbl_32 + +@@ -157,11 +152,6 @@ SYM_FUNC_START(startup_32_smp) + movl %eax,%ss + leal -__PAGE_OFFSET(%ecx),%esp + +-#ifdef CONFIG_MICROCODE +- /* Early load ucode on AP. */ +- call load_ucode_ap +-#endif +- + .Ldefault_entry: + movl $(CR0_STATE & ~X86_CR0_PG),%eax + movl %eax,%cr0 +diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c +index 87aee638e1a5d8..6da2cfa23c2939 100644 +--- a/arch/x86/kernel/nmi.c ++++ b/arch/x86/kernel/nmi.c +@@ -33,6 +33,7 @@ + #include + #include + #include ++#include + #include + + #define CREATE_TRACE_POINTS +@@ -343,6 +344,9 @@ static noinstr void default_do_nmi(struct pt_regs *regs) + + instrumentation_begin(); + ++ if (microcode_nmi_handler_enabled() && microcode_nmi_handler()) ++ goto out; ++ + handled = nmi_handle(NMI_LOCAL, regs); + __this_cpu_add(nmi_stats.normal, handled); + if (handled) { +@@ -498,8 +502,11 @@ DEFINE_IDTENTRY_RAW(exc_nmi) + if (IS_ENABLED(CONFIG_NMI_CHECK_CPU)) + raw_atomic_long_inc(&nsp->idt_calls); + +- if (IS_ENABLED(CONFIG_SMP) && arch_cpu_is_offline(smp_processor_id())) ++ if (IS_ENABLED(CONFIG_SMP) && arch_cpu_is_offline(smp_processor_id())) { ++ if (microcode_nmi_handler_enabled()) ++ microcode_offline_nmi_handler(); + return; ++ } + + if (this_cpu_read(nmi_state) != NMI_NOT_RUNNING) { + this_cpu_write(nmi_state, NMI_LATCHED); +diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c +index a8f2ab816d5ae2..77f0d9ccb2c004 100644 +--- a/arch/x86/kernel/smpboot.c ++++ b/arch/x86/kernel/smpboot.c +@@ -259,12 +259,9 @@ static void notrace start_secondary(void *unused) + cpu_init_exception_handling(); + + /* +- * 32-bit systems load the microcode from the ASM startup code for +- * historical reasons. +- * +- * On 64-bit systems load it before reaching the AP alive +- * synchronization point below so it is not part of the full per +- * CPU serialized bringup part when "parallel" bringup is enabled. ++ * Load the microcode before reaching the AP alive synchronization ++ * point below so it is not part of the full per CPU serialized ++ * bringup part when "parallel" bringup is enabled. + * + * That's even safe when hyperthreading is enabled in the CPU as + * the core code starts the primary threads first and leaves the +@@ -277,8 +274,7 @@ static void notrace start_secondary(void *unused) + * CPUID, MSRs etc. must be strictly serialized to maintain + * software state correctness. + */ +- if (IS_ENABLED(CONFIG_X86_64)) +- load_ucode_ap(); ++ load_ucode_ap(); + + /* + * Synchronization point with the hotplug core. Sets this CPUs +diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c +index e62ffffe5fb8d4..4ce5681be18f05 100644 +--- a/drivers/firmware/cirrus/cs_dsp.c ++++ b/drivers/firmware/cirrus/cs_dsp.c +@@ -1562,8 +1562,8 @@ static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware, + goto out_fw; + } + +- ret = regmap_raw_write_async(regmap, reg, buf->buf, +- le32_to_cpu(region->len)); ++ ret = regmap_raw_write(regmap, reg, buf->buf, ++ le32_to_cpu(region->len)); + if (ret != 0) { + cs_dsp_err(dsp, + "%s.%d: Failed to write %d bytes at %d in %s: %d\n", +@@ -1578,12 +1578,6 @@ static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware, + regions++; + } + +- ret = regmap_async_complete(regmap); +- if (ret != 0) { +- cs_dsp_err(dsp, "Failed to complete async write: %d\n", ret); +- goto out_fw; +- } +- + if (pos > firmware->size) + cs_dsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", + file, regions, pos - firmware->size); +@@ -1591,7 +1585,6 @@ static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware, + cs_dsp_debugfs_save_wmfwname(dsp, file); + + out_fw: +- regmap_async_complete(regmap); + cs_dsp_buf_free(&buf_list); + kfree(text); + +@@ -2287,8 +2280,8 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware + cs_dsp_dbg(dsp, "%s.%d: Writing %d bytes at %x\n", + file, blocks, le32_to_cpu(blk->len), + reg); +- ret = regmap_raw_write_async(regmap, reg, buf->buf, +- le32_to_cpu(blk->len)); ++ ret = regmap_raw_write(regmap, reg, buf->buf, ++ le32_to_cpu(blk->len)); + if (ret != 0) { + cs_dsp_err(dsp, + "%s.%d: Failed to write to %x in %s: %d\n", +@@ -2300,10 +2293,6 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware + blocks++; + } + +- ret = regmap_async_complete(regmap); +- if (ret != 0) +- cs_dsp_err(dsp, "Failed to complete async write: %d\n", ret); +- + if (pos > firmware->size) + cs_dsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", + file, blocks, pos - firmware->size); +@@ -2311,7 +2300,6 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware + cs_dsp_debugfs_save_binname(dsp, file); + + out_fw: +- regmap_async_complete(regmap); + cs_dsp_buf_free(&buf_list); + kfree(text); + +@@ -2523,8 +2511,8 @@ static int cs_dsp_adsp2_enable_core(struct cs_dsp *dsp) + { + int ret; + +- ret = regmap_update_bits_async(dsp->regmap, dsp->base + ADSP2_CONTROL, +- ADSP2_SYS_ENA, ADSP2_SYS_ENA); ++ ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, ++ ADSP2_SYS_ENA, ADSP2_SYS_ENA); + if (ret != 0) + return ret; + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c +index 51467f132c2604..da47e68b10ce0d 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c +@@ -891,6 +891,7 @@ void amdgpu_dm_hpd_init(struct amdgpu_device *adev) + struct drm_device *dev = adev_to_drm(adev); + struct drm_connector *connector; + struct drm_connector_list_iter iter; ++ int i; + + drm_connector_list_iter_begin(dev, &iter); + drm_for_each_connector_iter(connector, &iter) { +@@ -912,6 +913,12 @@ void amdgpu_dm_hpd_init(struct amdgpu_device *adev) + } + } + drm_connector_list_iter_end(&iter); ++ ++ /* Update reference counts for HPDs */ ++ for (i = DC_IRQ_SOURCE_HPD1; i <= adev->mode_info.num_hpd; i++) { ++ if (amdgpu_irq_get(adev, &adev->hpd_irq, i - DC_IRQ_SOURCE_HPD1)) ++ drm_err(dev, "DM_IRQ: Failed get HPD for source=%d)!\n", i); ++ } + } + + /** +@@ -927,6 +934,7 @@ void amdgpu_dm_hpd_fini(struct amdgpu_device *adev) + struct drm_device *dev = adev_to_drm(adev); + struct drm_connector *connector; + struct drm_connector_list_iter iter; ++ int i; + + drm_connector_list_iter_begin(dev, &iter); + drm_for_each_connector_iter(connector, &iter) { +@@ -947,4 +955,10 @@ void amdgpu_dm_hpd_fini(struct amdgpu_device *adev) + } + } + drm_connector_list_iter_end(&iter); ++ ++ /* Update reference counts for HPDs */ ++ for (i = DC_IRQ_SOURCE_HPD1; i <= adev->mode_info.num_hpd; i++) { ++ if (amdgpu_irq_put(adev, &adev->hpd_irq, i - DC_IRQ_SOURCE_HPD1)) ++ drm_err(dev, "DM_IRQ: Failed put HPD for source=%d!\n", i); ++ } + } +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c +index 08ce3bb8f640d9..fe96bab7d05d7b 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c +@@ -51,7 +51,8 @@ static bool link_supports_psrsu(struct dc_link *link) + !link->dpcd_caps.psr_info.psr2_su_y_granularity_cap) + return false; + +- return dc_dmub_check_min_version(dc->ctx->dmub_srv->dmub); ++ /* Temporarily disable PSR-SU to avoid glitches */ ++ return false; + } + + /* +diff --git a/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c b/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c +index c8586cb7d0fec5..4d193313a6d6e3 100644 +--- a/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c ++++ b/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c +@@ -3043,6 +3043,7 @@ static int kv_dpm_hw_init(void *handle) + if (!amdgpu_dpm) + return 0; + ++ mutex_lock(&adev->pm.mutex); + kv_dpm_setup_asic(adev); + ret = kv_dpm_enable(adev); + if (ret) +@@ -3050,6 +3051,8 @@ static int kv_dpm_hw_init(void *handle) + else + adev->pm.dpm_enabled = true; + amdgpu_legacy_dpm_compute_clocks(adev); ++ mutex_unlock(&adev->pm.mutex); ++ + return ret; + } + +@@ -3067,32 +3070,42 @@ static int kv_dpm_suspend(void *handle) + { + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + ++ cancel_work_sync(&adev->pm.dpm.thermal.work); ++ + if (adev->pm.dpm_enabled) { ++ mutex_lock(&adev->pm.mutex); ++ adev->pm.dpm_enabled = false; + /* disable dpm */ + kv_dpm_disable(adev); + /* reset the power state */ + adev->pm.dpm.current_ps = adev->pm.dpm.requested_ps = adev->pm.dpm.boot_ps; ++ mutex_unlock(&adev->pm.mutex); + } + return 0; + } + + static int kv_dpm_resume(void *handle) + { +- int ret; ++ int ret = 0; + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + +- if (adev->pm.dpm_enabled) { ++ if (!amdgpu_dpm) ++ return 0; ++ ++ if (!adev->pm.dpm_enabled) { ++ mutex_lock(&adev->pm.mutex); + /* asic init will reset to the boot state */ + kv_dpm_setup_asic(adev); + ret = kv_dpm_enable(adev); +- if (ret) ++ if (ret) { + adev->pm.dpm_enabled = false; +- else ++ } else { + adev->pm.dpm_enabled = true; +- if (adev->pm.dpm_enabled) + amdgpu_legacy_dpm_compute_clocks(adev); ++ } ++ mutex_unlock(&adev->pm.mutex); + } +- return 0; ++ return ret; + } + + static bool kv_dpm_is_idle(void *handle) +diff --git a/drivers/gpu/drm/amd/pm/legacy-dpm/legacy_dpm.c b/drivers/gpu/drm/amd/pm/legacy-dpm/legacy_dpm.c +index 60377747bab4fc..48ad413d72afe7 100644 +--- a/drivers/gpu/drm/amd/pm/legacy-dpm/legacy_dpm.c ++++ b/drivers/gpu/drm/amd/pm/legacy-dpm/legacy_dpm.c +@@ -1018,9 +1018,12 @@ void amdgpu_dpm_thermal_work_handler(struct work_struct *work) + enum amd_pm_state_type dpm_state = POWER_STATE_TYPE_INTERNAL_THERMAL; + int temp, size = sizeof(temp); + +- if (!adev->pm.dpm_enabled) +- return; ++ mutex_lock(&adev->pm.mutex); + ++ if (!adev->pm.dpm_enabled) { ++ mutex_unlock(&adev->pm.mutex); ++ return; ++ } + if (!pp_funcs->read_sensor(adev->powerplay.pp_handle, + AMDGPU_PP_SENSOR_GPU_TEMP, + (void *)&temp, +@@ -1042,4 +1045,5 @@ void amdgpu_dpm_thermal_work_handler(struct work_struct *work) + adev->pm.dpm.state = dpm_state; + + amdgpu_legacy_dpm_compute_clocks(adev->powerplay.pp_handle); ++ mutex_unlock(&adev->pm.mutex); + } +diff --git a/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c b/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c +index 99dde52a429013..e7b1fa2feb9288 100644 +--- a/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c ++++ b/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c +@@ -7789,6 +7789,7 @@ static int si_dpm_hw_init(void *handle) + if (!amdgpu_dpm) + return 0; + ++ mutex_lock(&adev->pm.mutex); + si_dpm_setup_asic(adev); + ret = si_dpm_enable(adev); + if (ret) +@@ -7796,6 +7797,7 @@ static int si_dpm_hw_init(void *handle) + else + adev->pm.dpm_enabled = true; + amdgpu_legacy_dpm_compute_clocks(adev); ++ mutex_unlock(&adev->pm.mutex); + return ret; + } + +@@ -7813,32 +7815,44 @@ static int si_dpm_suspend(void *handle) + { + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + ++ cancel_work_sync(&adev->pm.dpm.thermal.work); ++ + if (adev->pm.dpm_enabled) { ++ mutex_lock(&adev->pm.mutex); ++ adev->pm.dpm_enabled = false; + /* disable dpm */ + si_dpm_disable(adev); + /* reset the power state */ + adev->pm.dpm.current_ps = adev->pm.dpm.requested_ps = adev->pm.dpm.boot_ps; ++ mutex_unlock(&adev->pm.mutex); + } ++ + return 0; + } + + static int si_dpm_resume(void *handle) + { +- int ret; ++ int ret = 0; + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + +- if (adev->pm.dpm_enabled) { ++ if (!amdgpu_dpm) ++ return 0; ++ ++ if (!adev->pm.dpm_enabled) { + /* asic init will reset to the boot state */ ++ mutex_lock(&adev->pm.mutex); + si_dpm_setup_asic(adev); + ret = si_dpm_enable(adev); +- if (ret) ++ if (ret) { + adev->pm.dpm_enabled = false; +- else ++ } else { + adev->pm.dpm_enabled = true; +- if (adev->pm.dpm_enabled) + amdgpu_legacy_dpm_compute_clocks(adev); ++ } ++ mutex_unlock(&adev->pm.mutex); + } +- return 0; ++ ++ return ret; + } + + static bool si_dpm_is_idle(void *handle) +diff --git a/drivers/i2c/busses/i2c-ls2x.c b/drivers/i2c/busses/i2c-ls2x.c +index ebae6035701db7..d74625d72f4c52 100644 +--- a/drivers/i2c/busses/i2c-ls2x.c ++++ b/drivers/i2c/busses/i2c-ls2x.c +@@ -10,6 +10,7 @@ + * Rewritten for mainline by Binbin Zhou + */ + ++#include + #include + #include + #include +@@ -26,7 +27,8 @@ + #include + + /* I2C Registers */ +-#define I2C_LS2X_PRER 0x0 /* Freq Division Register(16 bits) */ ++#define I2C_LS2X_PRER_LO 0x0 /* Freq Division Low Byte Register */ ++#define I2C_LS2X_PRER_HI 0x1 /* Freq Division High Byte Register */ + #define I2C_LS2X_CTR 0x2 /* Control Register */ + #define I2C_LS2X_TXR 0x3 /* Transport Data Register */ + #define I2C_LS2X_RXR 0x3 /* Receive Data Register */ +@@ -93,6 +95,7 @@ static irqreturn_t ls2x_i2c_isr(int this_irq, void *dev_id) + */ + static void ls2x_i2c_adjust_bus_speed(struct ls2x_i2c_priv *priv) + { ++ u16 val; + struct i2c_timings *t = &priv->i2c_t; + struct device *dev = priv->adapter.dev.parent; + u32 acpi_speed = i2c_acpi_find_bus_speed(dev); +@@ -104,9 +107,14 @@ static void ls2x_i2c_adjust_bus_speed(struct ls2x_i2c_priv *priv) + else + t->bus_freq_hz = LS2X_I2C_FREQ_STD; + +- /* Calculate and set i2c frequency. */ +- writew(LS2X_I2C_PCLK_FREQ / (5 * t->bus_freq_hz) - 1, +- priv->base + I2C_LS2X_PRER); ++ /* ++ * According to the chip manual, we can only access the registers as bytes, ++ * otherwise the high bits will be truncated. ++ * So set the I2C frequency with a sequential writeb() instead of writew(). ++ */ ++ val = LS2X_I2C_PCLK_FREQ / (5 * t->bus_freq_hz) - 1; ++ writeb(FIELD_GET(GENMASK(7, 0), val), priv->base + I2C_LS2X_PRER_LO); ++ writeb(FIELD_GET(GENMASK(15, 8), val), priv->base + I2C_LS2X_PRER_HI); + } + + static void ls2x_i2c_init(struct ls2x_i2c_priv *priv) +diff --git a/drivers/i2c/busses/i2c-npcm7xx.c b/drivers/i2c/busses/i2c-npcm7xx.c +index ae4bae63ad4f3c..91f508d50e7ab4 100644 +--- a/drivers/i2c/busses/i2c-npcm7xx.c ++++ b/drivers/i2c/busses/i2c-npcm7xx.c +@@ -2333,6 +2333,13 @@ static int npcm_i2c_probe_bus(struct platform_device *pdev) + if (irq < 0) + return irq; + ++ /* ++ * Disable the interrupt to avoid the interrupt handler being triggered ++ * incorrectly by the asynchronous interrupt status since the machine ++ * might do a warm reset during the last smbus/i2c transfer session. ++ */ ++ npcm_i2c_int_enable(bus, false); ++ + ret = devm_request_irq(bus->dev, irq, npcm_i2c_bus_irq, 0, + dev_name(bus->dev), bus); + if (ret) +diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c +index 45500d2d5b4bb5..44842f243f40b5 100644 +--- a/drivers/idle/intel_idle.c ++++ b/drivers/idle/intel_idle.c +@@ -56,6 +56,7 @@ + #include + #include + #include ++#include + #include + + #define INTEL_IDLE_VERSION "0.5.1" +@@ -1573,6 +1574,9 @@ static void __init intel_idle_init_cstates_acpi(struct cpuidle_driver *drv) + if (intel_idle_state_needs_timer_stop(state)) + state->flags |= CPUIDLE_FLAG_TIMER_STOP; + ++ if (cx->type > ACPI_STATE_C1 && !boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) ++ mark_tsc_unstable("TSC halts in idle"); ++ + state->enter = intel_idle; + state->enter_s2idle = intel_idle_s2idle; + } +diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c +index ec5efdc1666013..9f97bef0214975 100644 +--- a/drivers/infiniband/core/sysfs.c ++++ b/drivers/infiniband/core/sysfs.c +@@ -342,6 +342,10 @@ static ssize_t rate_show(struct ib_device *ibdev, u32 port_num, + speed = " NDR"; + rate = 1000; + break; ++ case IB_SPEED_XDR: ++ speed = " XDR"; ++ rate = 2000; ++ break; + case IB_SPEED_SDR: + default: /* default to SDR for invalid rates */ + speed = " SDR"; +diff --git a/drivers/infiniband/core/uverbs_std_types_device.c b/drivers/infiniband/core/uverbs_std_types_device.c +index 049684880ae03d..fb0555647336f4 100644 +--- a/drivers/infiniband/core/uverbs_std_types_device.c ++++ b/drivers/infiniband/core/uverbs_std_types_device.c +@@ -203,6 +203,7 @@ static int UVERBS_HANDLER(UVERBS_METHOD_QUERY_PORT)( + + copy_port_attr_to_resp(&attr, &resp.legacy_resp, ib_dev, port_num); + resp.port_cap_flags2 = attr.port_cap_flags2; ++ resp.active_speed_ex = attr.active_speed; + + return uverbs_copy_to_struct_or_zero(attrs, UVERBS_ATTR_QUERY_PORT_RESP, + &resp, sizeof(resp)); +@@ -461,7 +462,7 @@ DECLARE_UVERBS_NAMED_METHOD( + UVERBS_ATTR_PTR_OUT( + UVERBS_ATTR_QUERY_PORT_RESP, + UVERBS_ATTR_STRUCT(struct ib_uverbs_query_port_resp_ex, +- reserved), ++ active_speed_ex), + UA_MANDATORY)); + + DECLARE_UVERBS_NAMED_METHOD( +diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c +index 186ed3c22ec9e3..ba05de0380e96e 100644 +--- a/drivers/infiniband/core/verbs.c ++++ b/drivers/infiniband/core/verbs.c +@@ -147,6 +147,7 @@ __attribute_const__ int ib_rate_to_mult(enum ib_rate rate) + case IB_RATE_50_GBPS: return 20; + case IB_RATE_400_GBPS: return 160; + case IB_RATE_600_GBPS: return 240; ++ case IB_RATE_800_GBPS: return 320; + default: return -1; + } + } +@@ -176,6 +177,7 @@ __attribute_const__ enum ib_rate mult_to_ib_rate(int mult) + case 20: return IB_RATE_50_GBPS; + case 160: return IB_RATE_400_GBPS; + case 240: return IB_RATE_600_GBPS; ++ case 320: return IB_RATE_800_GBPS; + default: return IB_RATE_PORT_CURRENT; + } + } +@@ -205,6 +207,7 @@ __attribute_const__ int ib_rate_to_mbps(enum ib_rate rate) + case IB_RATE_50_GBPS: return 53125; + case IB_RATE_400_GBPS: return 425000; + case IB_RATE_600_GBPS: return 637500; ++ case IB_RATE_800_GBPS: return 850000; + default: return -1; + } + } +diff --git a/drivers/infiniband/hw/mana/main.c b/drivers/infiniband/hw/mana/main.c +index 85717482a616e7..6fa9b125329970 100644 +--- a/drivers/infiniband/hw/mana/main.c ++++ b/drivers/infiniband/hw/mana/main.c +@@ -180,7 +180,7 @@ static int mana_gd_allocate_doorbell_page(struct gdma_context *gc, + + req.resource_type = GDMA_RESOURCE_DOORBELL_PAGE; + req.num_resources = 1; +- req.alignment = 1; ++ req.alignment = PAGE_SIZE / MANA_PAGE_SIZE; + + /* Have GDMA start searching from 0 */ + req.allocated_resources = 0; +diff --git a/drivers/infiniband/hw/mlx5/ah.c b/drivers/infiniband/hw/mlx5/ah.c +index 505bc47fd575d5..99036afb3aef0b 100644 +--- a/drivers/infiniband/hw/mlx5/ah.c ++++ b/drivers/infiniband/hw/mlx5/ah.c +@@ -67,7 +67,8 @@ static void create_ib_ah(struct mlx5_ib_dev *dev, struct mlx5_ib_ah *ah, + ah->av.tclass = grh->traffic_class; + } + +- ah->av.stat_rate_sl = (rdma_ah_get_static_rate(ah_attr) << 4); ++ ah->av.stat_rate_sl = ++ (mlx5r_ib_rate(dev, rdma_ah_get_static_rate(ah_attr)) << 4); + + if (ah_attr->type == RDMA_AH_ATTR_TYPE_ROCE) { + if (init_attr->xmit_slave) +diff --git a/drivers/infiniband/hw/mlx5/counters.c b/drivers/infiniband/hw/mlx5/counters.c +index 8300ce6228350d..b049bba2157905 100644 +--- a/drivers/infiniband/hw/mlx5/counters.c ++++ b/drivers/infiniband/hw/mlx5/counters.c +@@ -542,6 +542,7 @@ static int mlx5_ib_counter_bind_qp(struct rdma_counter *counter, + struct ib_qp *qp) + { + struct mlx5_ib_dev *dev = to_mdev(qp->device); ++ bool new = false; + int err; + + if (!counter->id) { +@@ -556,6 +557,7 @@ static int mlx5_ib_counter_bind_qp(struct rdma_counter *counter, + return err; + counter->id = + MLX5_GET(alloc_q_counter_out, out, counter_set_id); ++ new = true; + } + + err = mlx5_ib_qp_set_counter(qp, counter); +@@ -565,8 +567,10 @@ static int mlx5_ib_counter_bind_qp(struct rdma_counter *counter, + return 0; + + fail_set_counter: +- mlx5_ib_counter_dealloc(counter); +- counter->id = 0; ++ if (new) { ++ mlx5_ib_counter_dealloc(counter); ++ counter->id = 0; ++ } + + return err; + } +diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c +index 71a856409cee2c..0a9ae84600b204 100644 +--- a/drivers/infiniband/hw/mlx5/qp.c ++++ b/drivers/infiniband/hw/mlx5/qp.c +@@ -3433,11 +3433,11 @@ static int ib_to_mlx5_rate_map(u8 rate) + return 0; + } + +-static int ib_rate_to_mlx5(struct mlx5_ib_dev *dev, u8 rate) ++int mlx5r_ib_rate(struct mlx5_ib_dev *dev, u8 rate) + { + u32 stat_rate_support; + +- if (rate == IB_RATE_PORT_CURRENT) ++ if (rate == IB_RATE_PORT_CURRENT || rate == IB_RATE_800_GBPS) + return 0; + + if (rate < IB_RATE_2_5_GBPS || rate > IB_RATE_600_GBPS) +@@ -3582,7 +3582,7 @@ static int mlx5_set_path(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp, + sizeof(grh->dgid.raw)); + } + +- err = ib_rate_to_mlx5(dev, rdma_ah_get_static_rate(ah)); ++ err = mlx5r_ib_rate(dev, rdma_ah_get_static_rate(ah)); + if (err < 0) + return err; + MLX5_SET(ads, path, stat_rate, err); +@@ -4555,6 +4555,8 @@ static int mlx5_ib_modify_dct(struct ib_qp *ibqp, struct ib_qp_attr *attr, + + set_id = mlx5_ib_get_counters_id(dev, attr->port_num - 1); + MLX5_SET(dctc, dctc, counter_set_id, set_id); ++ ++ qp->port = attr->port_num; + } else if (cur_state == IB_QPS_INIT && new_state == IB_QPS_RTR) { + struct mlx5_ib_modify_qp_resp resp = {}; + u32 out[MLX5_ST_SZ_DW(create_dct_out)] = {}; +@@ -5045,7 +5047,7 @@ static int mlx5_ib_dct_query_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *mqp, + } + + if (qp_attr_mask & IB_QP_PORT) +- qp_attr->port_num = MLX5_GET(dctc, dctc, port); ++ qp_attr->port_num = mqp->port; + if (qp_attr_mask & IB_QP_MIN_RNR_TIMER) + qp_attr->min_rnr_timer = MLX5_GET(dctc, dctc, min_rnr_nak); + if (qp_attr_mask & IB_QP_AV) { +diff --git a/drivers/infiniband/hw/mlx5/qp.h b/drivers/infiniband/hw/mlx5/qp.h +index b6ee7c3ee1ca1b..2530e7730635f3 100644 +--- a/drivers/infiniband/hw/mlx5/qp.h ++++ b/drivers/infiniband/hw/mlx5/qp.h +@@ -56,4 +56,5 @@ int mlx5_core_xrcd_dealloc(struct mlx5_ib_dev *dev, u32 xrcdn); + int mlx5_ib_qp_set_counter(struct ib_qp *qp, struct rdma_counter *counter); + int mlx5_ib_qp_event_init(void); + void mlx5_ib_qp_event_cleanup(void); ++int mlx5r_ib_rate(struct mlx5_ib_dev *dev, u8 rate); + #endif /* _MLX5_IB_QP_H */ +diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h +index 78c972bb1d9623..9fb5a18e056d41 100644 +--- a/drivers/net/ethernet/cadence/macb.h ++++ b/drivers/net/ethernet/cadence/macb.h +@@ -1270,6 +1270,8 @@ struct macb { + struct clk *rx_clk; + struct clk *tsu_clk; + struct net_device *dev; ++ /* Protects hw_stats and ethtool_stats */ ++ spinlock_t stats_lock; + union { + struct macb_stats macb; + struct gem_stats gem; +diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c +index 8f61731e4554ba..4325d0ace1f268 100644 +--- a/drivers/net/ethernet/cadence/macb_main.c ++++ b/drivers/net/ethernet/cadence/macb_main.c +@@ -1992,10 +1992,12 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id) + + if (status & MACB_BIT(ISR_ROVR)) { + /* We missed at least one packet */ ++ spin_lock(&bp->stats_lock); + if (macb_is_gem(bp)) + bp->hw_stats.gem.rx_overruns++; + else + bp->hw_stats.macb.rx_overruns++; ++ spin_unlock(&bp->stats_lock); + + if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) + queue_writel(queue, ISR, MACB_BIT(ISR_ROVR)); +@@ -3084,6 +3086,7 @@ static struct net_device_stats *gem_get_stats(struct macb *bp) + if (!netif_running(bp->dev)) + return nstat; + ++ spin_lock_irq(&bp->stats_lock); + gem_update_stats(bp); + + nstat->rx_errors = (hwstat->rx_frame_check_sequence_errors + +@@ -3113,6 +3116,7 @@ static struct net_device_stats *gem_get_stats(struct macb *bp) + nstat->tx_aborted_errors = hwstat->tx_excessive_collisions; + nstat->tx_carrier_errors = hwstat->tx_carrier_sense_errors; + nstat->tx_fifo_errors = hwstat->tx_underrun; ++ spin_unlock_irq(&bp->stats_lock); + + return nstat; + } +@@ -3120,12 +3124,13 @@ static struct net_device_stats *gem_get_stats(struct macb *bp) + static void gem_get_ethtool_stats(struct net_device *dev, + struct ethtool_stats *stats, u64 *data) + { +- struct macb *bp; ++ struct macb *bp = netdev_priv(dev); + +- bp = netdev_priv(dev); ++ spin_lock_irq(&bp->stats_lock); + gem_update_stats(bp); + memcpy(data, &bp->ethtool_stats, sizeof(u64) + * (GEM_STATS_LEN + QUEUE_STATS_LEN * MACB_MAX_QUEUES)); ++ spin_unlock_irq(&bp->stats_lock); + } + + static int gem_get_sset_count(struct net_device *dev, int sset) +@@ -3175,6 +3180,7 @@ static struct net_device_stats *macb_get_stats(struct net_device *dev) + return gem_get_stats(bp); + + /* read stats from hardware */ ++ spin_lock_irq(&bp->stats_lock); + macb_update_stats(bp); + + /* Convert HW stats into netdevice stats */ +@@ -3208,6 +3214,7 @@ static struct net_device_stats *macb_get_stats(struct net_device *dev) + nstat->tx_carrier_errors = hwstat->tx_carrier_errors; + nstat->tx_fifo_errors = hwstat->tx_underruns; + /* Don't know about heartbeat or window errors... */ ++ spin_unlock_irq(&bp->stats_lock); + + return nstat; + } +@@ -5063,6 +5070,7 @@ static int macb_probe(struct platform_device *pdev) + } + } + spin_lock_init(&bp->lock); ++ spin_lock_init(&bp->stats_lock); + + /* setup capabilities */ + macb_configure_caps(bp, macb_config); +diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c +index 87b27bd7a13bb1..9aa57134f460cd 100644 +--- a/drivers/net/ethernet/freescale/enetc/enetc.c ++++ b/drivers/net/ethernet/freescale/enetc/enetc.c +@@ -145,6 +145,24 @@ static int enetc_ptp_parse(struct sk_buff *skb, u8 *udp, + return 0; + } + ++/** ++ * enetc_unwind_tx_frame() - Unwind the DMA mappings of a multi-buffer Tx frame ++ * @tx_ring: Pointer to the Tx ring on which the buffer descriptors are located ++ * @count: Number of Tx buffer descriptors which need to be unmapped ++ * @i: Index of the last successfully mapped Tx buffer descriptor ++ */ ++static void enetc_unwind_tx_frame(struct enetc_bdr *tx_ring, int count, int i) ++{ ++ while (count--) { ++ struct enetc_tx_swbd *tx_swbd = &tx_ring->tx_swbd[i]; ++ ++ enetc_free_tx_frame(tx_ring, tx_swbd); ++ if (i == 0) ++ i = tx_ring->bd_count; ++ i--; ++ } ++} ++ + static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb) + { + bool do_vlan, do_onestep_tstamp = false, do_twostep_tstamp = false; +@@ -235,9 +253,11 @@ static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb) + } + + if (do_onestep_tstamp) { +- u32 lo, hi, val; +- u64 sec, nsec; ++ __be32 new_sec_l, new_nsec; ++ u32 lo, hi, nsec, val; ++ __be16 new_sec_h; + u8 *data; ++ u64 sec; + + lo = enetc_rd_hot(hw, ENETC_SICTR0); + hi = enetc_rd_hot(hw, ENETC_SICTR1); +@@ -251,13 +271,38 @@ static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb) + /* Update originTimestamp field of Sync packet + * - 48 bits seconds field + * - 32 bits nanseconds field ++ * ++ * In addition, the UDP checksum needs to be updated ++ * by software after updating originTimestamp field, ++ * otherwise the hardware will calculate the wrong ++ * checksum when updating the correction field and ++ * update it to the packet. + */ + data = skb_mac_header(skb); +- *(__be16 *)(data + offset2) = +- htons((sec >> 32) & 0xffff); +- *(__be32 *)(data + offset2 + 2) = +- htonl(sec & 0xffffffff); +- *(__be32 *)(data + offset2 + 6) = htonl(nsec); ++ new_sec_h = htons((sec >> 32) & 0xffff); ++ new_sec_l = htonl(sec & 0xffffffff); ++ new_nsec = htonl(nsec); ++ if (udp) { ++ struct udphdr *uh = udp_hdr(skb); ++ __be32 old_sec_l, old_nsec; ++ __be16 old_sec_h; ++ ++ old_sec_h = *(__be16 *)(data + offset2); ++ inet_proto_csum_replace2(&uh->check, skb, old_sec_h, ++ new_sec_h, false); ++ ++ old_sec_l = *(__be32 *)(data + offset2 + 2); ++ inet_proto_csum_replace4(&uh->check, skb, old_sec_l, ++ new_sec_l, false); ++ ++ old_nsec = *(__be32 *)(data + offset2 + 6); ++ inet_proto_csum_replace4(&uh->check, skb, old_nsec, ++ new_nsec, false); ++ } ++ ++ *(__be16 *)(data + offset2) = new_sec_h; ++ *(__be32 *)(data + offset2 + 2) = new_sec_l; ++ *(__be32 *)(data + offset2 + 6) = new_nsec; + + /* Configure single-step register */ + val = ENETC_PM0_SINGLE_STEP_EN; +@@ -328,25 +373,20 @@ static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb) + dma_err: + dev_err(tx_ring->dev, "DMA map error"); + +- do { +- tx_swbd = &tx_ring->tx_swbd[i]; +- enetc_free_tx_frame(tx_ring, tx_swbd); +- if (i == 0) +- i = tx_ring->bd_count; +- i--; +- } while (count--); ++ enetc_unwind_tx_frame(tx_ring, count, i); + + return 0; + } + +-static void enetc_map_tx_tso_hdr(struct enetc_bdr *tx_ring, struct sk_buff *skb, +- struct enetc_tx_swbd *tx_swbd, +- union enetc_tx_bd *txbd, int *i, int hdr_len, +- int data_len) ++static int enetc_map_tx_tso_hdr(struct enetc_bdr *tx_ring, struct sk_buff *skb, ++ struct enetc_tx_swbd *tx_swbd, ++ union enetc_tx_bd *txbd, int *i, int hdr_len, ++ int data_len) + { + union enetc_tx_bd txbd_tmp; + u8 flags = 0, e_flags = 0; + dma_addr_t addr; ++ int count = 1; + + enetc_clear_tx_bd(&txbd_tmp); + addr = tx_ring->tso_headers_dma + *i * TSO_HEADER_SIZE; +@@ -389,7 +429,10 @@ static void enetc_map_tx_tso_hdr(struct enetc_bdr *tx_ring, struct sk_buff *skb, + /* Write the BD */ + txbd_tmp.ext.e_flags = e_flags; + *txbd = txbd_tmp; ++ count++; + } ++ ++ return count; + } + + static int enetc_map_tx_tso_data(struct enetc_bdr *tx_ring, struct sk_buff *skb, +@@ -521,9 +564,9 @@ static int enetc_map_tx_tso_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb + + /* compute the csum over the L4 header */ + csum = enetc_tso_hdr_csum(&tso, skb, hdr, hdr_len, &pos); +- enetc_map_tx_tso_hdr(tx_ring, skb, tx_swbd, txbd, &i, hdr_len, data_len); ++ count += enetc_map_tx_tso_hdr(tx_ring, skb, tx_swbd, txbd, ++ &i, hdr_len, data_len); + bd_data_num = 0; +- count++; + + while (data_len > 0) { + int size; +@@ -547,8 +590,13 @@ static int enetc_map_tx_tso_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb + err = enetc_map_tx_tso_data(tx_ring, skb, tx_swbd, txbd, + tso.data, size, + size == data_len); +- if (err) ++ if (err) { ++ if (i == 0) ++ i = tx_ring->bd_count; ++ i--; ++ + goto err_map_data; ++ } + + data_len -= size; + count++; +@@ -577,13 +625,7 @@ static int enetc_map_tx_tso_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb + dev_err(tx_ring->dev, "DMA map error"); + + err_chained_bd: +- do { +- tx_swbd = &tx_ring->tx_swbd[i]; +- enetc_free_tx_frame(tx_ring, tx_swbd); +- if (i == 0) +- i = tx_ring->bd_count; +- i--; +- } while (count--); ++ enetc_unwind_tx_frame(tx_ring, count, i); + + return 0; + } +@@ -1626,7 +1668,7 @@ static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring, + enetc_xdp_drop(rx_ring, orig_i, i); + tx_ring->stats.xdp_tx_drops++; + } else { +- tx_ring->stats.xdp_tx += xdp_tx_bd_cnt; ++ tx_ring->stats.xdp_tx++; + rx_ring->xdp.xdp_tx_in_flight += xdp_tx_bd_cnt; + xdp_tx_frm_cnt++; + /* The XDP_TX enqueue was successful, so we +diff --git a/drivers/net/ethernet/google/gve/gve.h b/drivers/net/ethernet/google/gve/gve.h +index 0d1e681be25070..d59e28c8677523 100644 +--- a/drivers/net/ethernet/google/gve/gve.h ++++ b/drivers/net/ethernet/google/gve/gve.h +@@ -1030,6 +1030,16 @@ static inline u32 gve_xdp_tx_start_queue_id(struct gve_priv *priv) + return gve_xdp_tx_queue_id(priv, 0); + } + ++static inline bool gve_supports_xdp_xmit(struct gve_priv *priv) ++{ ++ switch (priv->queue_format) { ++ case GVE_GQI_QPL_FORMAT: ++ return true; ++ default: ++ return false; ++ } ++} ++ + /* buffers */ + int gve_alloc_page(struct gve_priv *priv, struct device *dev, + struct page **page, dma_addr_t *dma, +diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c +index 90d433b36799fb..8cd098fe88ef26 100644 +--- a/drivers/net/ethernet/google/gve/gve_main.c ++++ b/drivers/net/ethernet/google/gve/gve_main.c +@@ -1753,6 +1753,8 @@ static void gve_turndown(struct gve_priv *priv) + /* Stop tx queues */ + netif_tx_disable(priv->dev); + ++ xdp_features_clear_redirect_target(priv->dev); ++ + gve_clear_napi_enabled(priv); + gve_clear_report_stats(priv); + +@@ -1793,6 +1795,9 @@ static void gve_turnup(struct gve_priv *priv) + } + } + ++ if (priv->num_xdp_queues && gve_supports_xdp_xmit(priv)) ++ xdp_features_set_redirect_target(priv->dev, false); ++ + gve_set_napi_enabled(priv); + } + +@@ -2014,7 +2019,6 @@ static void gve_set_netdev_xdp_features(struct gve_priv *priv) + if (priv->queue_format == GVE_GQI_QPL_FORMAT) { + xdp_features = NETDEV_XDP_ACT_BASIC; + xdp_features |= NETDEV_XDP_ACT_REDIRECT; +- xdp_features |= NETDEV_XDP_ACT_NDO_XMIT; + xdp_features |= NETDEV_XDP_ACT_XSK_ZEROCOPY; + } else { + xdp_features = 0; +diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h +index f943964ec05ae7..e29a7ffd5f1437 100644 +--- a/drivers/net/ethernet/intel/ice/ice.h ++++ b/drivers/net/ethernet/intel/ice/ice.h +@@ -202,6 +202,7 @@ enum ice_feature { + ICE_F_GNSS, + ICE_F_ROCE_LAG, + ICE_F_SRIOV_LAG, ++ ICE_F_MBX_LIMIT, + ICE_F_MAX + }; + +diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c +index 80deca45ab599a..983332cbace21f 100644 +--- a/drivers/net/ethernet/intel/ice/ice_common.c ++++ b/drivers/net/ethernet/intel/ice/ice_common.c +@@ -1,5 +1,5 @@ + // SPDX-License-Identifier: GPL-2.0 +-/* Copyright (c) 2018, Intel Corporation. */ ++/* Copyright (c) 2018-2023, Intel Corporation. */ + + #include "ice_common.h" + #include "ice_sched.h" +@@ -153,6 +153,12 @@ static int ice_set_mac_type(struct ice_hw *hw) + case ICE_DEV_ID_E823L_SFP: + hw->mac_type = ICE_MAC_GENERIC; + break; ++ case ICE_DEV_ID_E830_BACKPLANE: ++ case ICE_DEV_ID_E830_QSFP56: ++ case ICE_DEV_ID_E830_SFP: ++ case ICE_DEV_ID_E830_SFP_DD: ++ hw->mac_type = ICE_MAC_E830; ++ break; + default: + hw->mac_type = ICE_MAC_UNKNOWN; + break; +@@ -684,8 +690,7 @@ static void + ice_fill_tx_timer_and_fc_thresh(struct ice_hw *hw, + struct ice_aqc_set_mac_cfg *cmd) + { +- u16 fc_thres_val, tx_timer_val; +- u32 val; ++ u32 val, fc_thres_m; + + /* We read back the transmit timer and FC threshold value of + * LFC. Thus, we will use index = +@@ -694,19 +699,32 @@ ice_fill_tx_timer_and_fc_thresh(struct ice_hw *hw, + * Also, because we are operating on transmit timer and FC + * threshold of LFC, we don't turn on any bit in tx_tmr_priority + */ +-#define IDX_OF_LFC PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA_MAX_INDEX +- +- /* Retrieve the transmit timer */ +- val = rd32(hw, PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA(IDX_OF_LFC)); +- tx_timer_val = val & +- PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA_HSEC_CTL_TX_PAUSE_QUANTA_M; +- cmd->tx_tmr_value = cpu_to_le16(tx_timer_val); +- +- /* Retrieve the FC threshold */ +- val = rd32(hw, PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER(IDX_OF_LFC)); +- fc_thres_val = val & PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_M; +- +- cmd->fc_refresh_threshold = cpu_to_le16(fc_thres_val); ++#define E800_IDX_OF_LFC E800_PRTMAC_HSEC_CTL_TX_PS_QNT_MAX ++#define E800_REFRESH_TMR E800_PRTMAC_HSEC_CTL_TX_PS_RFSH_TMR ++ ++ if (hw->mac_type == ICE_MAC_E830) { ++ /* Retrieve the transmit timer */ ++ val = rd32(hw, E830_PRTMAC_CL01_PS_QNT); ++ cmd->tx_tmr_value = ++ le16_encode_bits(val, E830_PRTMAC_CL01_PS_QNT_CL0_M); ++ ++ /* Retrieve the fc threshold */ ++ val = rd32(hw, E830_PRTMAC_CL01_QNT_THR); ++ fc_thres_m = E830_PRTMAC_CL01_QNT_THR_CL0_M; ++ } else { ++ /* Retrieve the transmit timer */ ++ val = rd32(hw, ++ E800_PRTMAC_HSEC_CTL_TX_PS_QNT(E800_IDX_OF_LFC)); ++ cmd->tx_tmr_value = ++ le16_encode_bits(val, ++ E800_PRTMAC_HSEC_CTL_TX_PS_QNT_M); ++ ++ /* Retrieve the fc threshold */ ++ val = rd32(hw, ++ E800_REFRESH_TMR(E800_IDX_OF_LFC)); ++ fc_thres_m = E800_PRTMAC_HSEC_CTL_TX_PS_RFSH_TMR_M; ++ } ++ cmd->fc_refresh_threshold = le16_encode_bits(val, fc_thres_m); + } + + /** +@@ -2389,16 +2407,21 @@ ice_parse_1588_func_caps(struct ice_hw *hw, struct ice_hw_func_caps *func_p, + static void + ice_parse_fdir_func_caps(struct ice_hw *hw, struct ice_hw_func_caps *func_p) + { +- u32 reg_val, val; ++ u32 reg_val, gsize, bsize; + + reg_val = rd32(hw, GLQF_FD_SIZE); +- val = (reg_val & GLQF_FD_SIZE_FD_GSIZE_M) >> +- GLQF_FD_SIZE_FD_GSIZE_S; +- func_p->fd_fltr_guar = +- ice_get_num_per_func(hw, val); +- val = (reg_val & GLQF_FD_SIZE_FD_BSIZE_M) >> +- GLQF_FD_SIZE_FD_BSIZE_S; +- func_p->fd_fltr_best_effort = val; ++ switch (hw->mac_type) { ++ case ICE_MAC_E830: ++ gsize = FIELD_GET(E830_GLQF_FD_SIZE_FD_GSIZE_M, reg_val); ++ bsize = FIELD_GET(E830_GLQF_FD_SIZE_FD_BSIZE_M, reg_val); ++ break; ++ case ICE_MAC_E810: ++ default: ++ gsize = FIELD_GET(E800_GLQF_FD_SIZE_FD_GSIZE_M, reg_val); ++ bsize = FIELD_GET(E800_GLQF_FD_SIZE_FD_BSIZE_M, reg_val); ++ } ++ func_p->fd_fltr_guar = ice_get_num_per_func(hw, gsize); ++ func_p->fd_fltr_best_effort = bsize; + + ice_debug(hw, ICE_DBG_INIT, "func caps: fd_fltr_guar = %d\n", + func_p->fd_fltr_guar); +diff --git a/drivers/net/ethernet/intel/ice/ice_devids.h b/drivers/net/ethernet/intel/ice/ice_devids.h +index 6d560d1c74a4a3..a2d384dbfc767b 100644 +--- a/drivers/net/ethernet/intel/ice/ice_devids.h ++++ b/drivers/net/ethernet/intel/ice/ice_devids.h +@@ -1,5 +1,5 @@ + /* SPDX-License-Identifier: GPL-2.0 */ +-/* Copyright (c) 2018, Intel Corporation. */ ++/* Copyright (c) 2018-2023, Intel Corporation. */ + + #ifndef _ICE_DEVIDS_H_ + #define _ICE_DEVIDS_H_ +@@ -16,6 +16,14 @@ + #define ICE_DEV_ID_E823L_1GBE 0x124F + /* Intel(R) Ethernet Connection E823-L for QSFP */ + #define ICE_DEV_ID_E823L_QSFP 0x151D ++/* Intel(R) Ethernet Controller E830-C for backplane */ ++#define ICE_DEV_ID_E830_BACKPLANE 0x12D1 ++/* Intel(R) Ethernet Controller E830-C for QSFP */ ++#define ICE_DEV_ID_E830_QSFP56 0x12D2 ++/* Intel(R) Ethernet Controller E830-C for SFP */ ++#define ICE_DEV_ID_E830_SFP 0x12D3 ++/* Intel(R) Ethernet Controller E830-C for SFP-DD */ ++#define ICE_DEV_ID_E830_SFP_DD 0x12D4 + /* Intel(R) Ethernet Controller E810-C for backplane */ + #define ICE_DEV_ID_E810C_BACKPLANE 0x1591 + /* Intel(R) Ethernet Controller E810-C for QSFP */ +diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c b/drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c +index b6bbf2376ef5c1..d43b642cbc01cc 100644 +--- a/drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c ++++ b/drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c +@@ -1,5 +1,5 @@ + // SPDX-License-Identifier: GPL-2.0 +-/* Copyright (C) 2018-2020, Intel Corporation. */ ++/* Copyright (C) 2018-2023, Intel Corporation. */ + + /* flow director ethtool support for ice */ + +@@ -540,16 +540,24 @@ int ice_fdir_num_avail_fltr(struct ice_hw *hw, struct ice_vsi *vsi) + /* total guaranteed filters assigned to this VSI */ + num_guar = vsi->num_gfltr; + +- /* minus the guaranteed filters programed by this VSI */ +- num_guar -= (rd32(hw, VSIQF_FD_CNT(vsi_num)) & +- VSIQF_FD_CNT_FD_GCNT_M) >> VSIQF_FD_CNT_FD_GCNT_S; +- + /* total global best effort filters */ + num_be = hw->func_caps.fd_fltr_best_effort; + +- /* minus the global best effort filters programmed */ +- num_be -= (rd32(hw, GLQF_FD_CNT) & GLQF_FD_CNT_FD_BCNT_M) >> +- GLQF_FD_CNT_FD_BCNT_S; ++ /* Subtract the number of programmed filters from the global values */ ++ switch (hw->mac_type) { ++ case ICE_MAC_E830: ++ num_guar -= FIELD_GET(E830_VSIQF_FD_CNT_FD_GCNT_M, ++ rd32(hw, VSIQF_FD_CNT(vsi_num))); ++ num_be -= FIELD_GET(E830_GLQF_FD_CNT_FD_BCNT_M, ++ rd32(hw, GLQF_FD_CNT)); ++ break; ++ case ICE_MAC_E810: ++ default: ++ num_guar -= FIELD_GET(E800_VSIQF_FD_CNT_FD_GCNT_M, ++ rd32(hw, VSIQF_FD_CNT(vsi_num))); ++ num_be -= FIELD_GET(E800_GLQF_FD_CNT_FD_BCNT_M, ++ rd32(hw, GLQF_FD_CNT)); ++ } + + return num_guar + num_be; + } +diff --git a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h +index 531cc2194741ed..96f70c0a965980 100644 +--- a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h ++++ b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h +@@ -1,5 +1,5 @@ + /* SPDX-License-Identifier: GPL-2.0 */ +-/* Copyright (c) 2018, Intel Corporation. */ ++/* Copyright (c) 2018-2023, Intel Corporation. */ + + /* Machine-generated file */ + +@@ -284,11 +284,11 @@ + #define VPLAN_TX_QBASE_VFNUMQ_M ICE_M(0xFF, 16) + #define VPLAN_TXQ_MAPENA(_VF) (0x00073800 + ((_VF) * 4)) + #define VPLAN_TXQ_MAPENA_TX_ENA_M BIT(0) +-#define PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA(_i) (0x001E36E0 + ((_i) * 32)) +-#define PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA_MAX_INDEX 8 +-#define PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA_HSEC_CTL_TX_PAUSE_QUANTA_M ICE_M(0xFFFF, 0) +-#define PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER(_i) (0x001E3800 + ((_i) * 32)) +-#define PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_M ICE_M(0xFFFF, 0) ++#define E800_PRTMAC_HSEC_CTL_TX_PS_QNT(_i) (0x001E36E0 + ((_i) * 32)) ++#define E800_PRTMAC_HSEC_CTL_TX_PS_QNT_MAX 8 ++#define E800_PRTMAC_HSEC_CTL_TX_PS_QNT_M GENMASK(15, 0) ++#define E800_PRTMAC_HSEC_CTL_TX_PS_RFSH_TMR(_i) (0x001E3800 + ((_i) * 32)) ++#define E800_PRTMAC_HSEC_CTL_TX_PS_RFSH_TMR_M GENMASK(15, 0) + #define GL_MDCK_TX_TDPU 0x00049348 + #define GL_MDCK_TX_TDPU_RCU_ANTISPOOF_ITR_DIS_M BIT(1) + #define GL_MDET_RX 0x00294C00 +@@ -311,7 +311,11 @@ + #define GL_MDET_TX_PQM_MAL_TYPE_S 26 + #define GL_MDET_TX_PQM_MAL_TYPE_M ICE_M(0x1F, 26) + #define GL_MDET_TX_PQM_VALID_M BIT(31) +-#define GL_MDET_TX_TCLAN 0x000FC068 ++#define GL_MDET_TX_TCLAN_BY_MAC(hw) \ ++ ((hw)->mac_type == ICE_MAC_E830 ? E830_GL_MDET_TX_TCLAN : \ ++ E800_GL_MDET_TX_TCLAN) ++#define E800_GL_MDET_TX_TCLAN 0x000FC068 ++#define E830_GL_MDET_TX_TCLAN 0x000FCCC0 + #define GL_MDET_TX_TCLAN_QNUM_S 0 + #define GL_MDET_TX_TCLAN_QNUM_M ICE_M(0x7FFF, 0) + #define GL_MDET_TX_TCLAN_VF_NUM_S 15 +@@ -325,7 +329,11 @@ + #define PF_MDET_RX_VALID_M BIT(0) + #define PF_MDET_TX_PQM 0x002D2C80 + #define PF_MDET_TX_PQM_VALID_M BIT(0) +-#define PF_MDET_TX_TCLAN 0x000FC000 ++#define PF_MDET_TX_TCLAN_BY_MAC(hw) \ ++ ((hw)->mac_type == ICE_MAC_E830 ? E830_PF_MDET_TX_TCLAN : \ ++ E800_PF_MDET_TX_TCLAN) ++#define E800_PF_MDET_TX_TCLAN 0x000FC000 ++#define E830_PF_MDET_TX_TCLAN 0x000FCC00 + #define PF_MDET_TX_TCLAN_VALID_M BIT(0) + #define VP_MDET_RX(_VF) (0x00294400 + ((_VF) * 4)) + #define VP_MDET_RX_VALID_M BIT(0) +@@ -335,6 +343,8 @@ + #define VP_MDET_TX_TCLAN_VALID_M BIT(0) + #define VP_MDET_TX_TDPU(_VF) (0x00040000 + ((_VF) * 4)) + #define VP_MDET_TX_TDPU_VALID_M BIT(0) ++#define E800_GL_MNG_FWSM_FW_MODES_M GENMASK(2, 0) ++#define E830_GL_MNG_FWSM_FW_MODES_M GENMASK(1, 0) + #define GL_MNG_FWSM 0x000B6134 + #define GL_MNG_FWSM_FW_LOADING_M BIT(30) + #define GLNVM_FLA 0x000B6108 +@@ -363,13 +373,18 @@ + #define GL_PWR_MODE_CTL_CAR_MAX_BW_S 30 + #define GL_PWR_MODE_CTL_CAR_MAX_BW_M ICE_M(0x3, 30) + #define GLQF_FD_CNT 0x00460018 ++#define E800_GLQF_FD_CNT_FD_GCNT_M GENMASK(14, 0) ++#define E830_GLQF_FD_CNT_FD_GCNT_M GENMASK(15, 0) + #define GLQF_FD_CNT_FD_BCNT_S 16 +-#define GLQF_FD_CNT_FD_BCNT_M ICE_M(0x7FFF, 16) ++#define E800_GLQF_FD_CNT_FD_BCNT_M GENMASK(30, 16) ++#define E830_GLQF_FD_CNT_FD_BCNT_M GENMASK(31, 16) + #define GLQF_FD_SIZE 0x00460010 + #define GLQF_FD_SIZE_FD_GSIZE_S 0 +-#define GLQF_FD_SIZE_FD_GSIZE_M ICE_M(0x7FFF, 0) ++#define E800_GLQF_FD_SIZE_FD_GSIZE_M GENMASK(14, 0) ++#define E830_GLQF_FD_SIZE_FD_GSIZE_M GENMASK(15, 0) + #define GLQF_FD_SIZE_FD_BSIZE_S 16 +-#define GLQF_FD_SIZE_FD_BSIZE_M ICE_M(0x7FFF, 16) ++#define E800_GLQF_FD_SIZE_FD_BSIZE_M GENMASK(30, 16) ++#define E830_GLQF_FD_SIZE_FD_BSIZE_M GENMASK(31, 16) + #define GLQF_FDINSET(_i, _j) (0x00412000 + ((_i) * 4 + (_j) * 512)) + #define GLQF_FDMASK(_i) (0x00410800 + ((_i) * 4)) + #define GLQF_FDMASK_MAX_INDEX 31 +@@ -388,6 +403,10 @@ + #define GLQF_HMASK_SEL(_i) (0x00410000 + ((_i) * 4)) + #define GLQF_HMASK_SEL_MAX_INDEX 127 + #define GLQF_HMASK_SEL_MASK_SEL_S 0 ++#define E800_PFQF_FD_CNT_FD_GCNT_M GENMASK(14, 0) ++#define E830_PFQF_FD_CNT_FD_GCNT_M GENMASK(15, 0) ++#define E800_PFQF_FD_CNT_FD_BCNT_M GENMASK(30, 16) ++#define E830_PFQF_FD_CNT_FD_BCNT_M GENMASK(31, 16) + #define PFQF_FD_ENA 0x0043A000 + #define PFQF_FD_ENA_FD_ENA_M BIT(0) + #define PFQF_FD_SIZE 0x00460100 +@@ -478,6 +497,7 @@ + #define GLTSYN_SYNC_DLAY 0x00088818 + #define GLTSYN_TGT_H_0(_i) (0x00088930 + ((_i) * 4)) + #define GLTSYN_TGT_L_0(_i) (0x00088928 + ((_i) * 4)) ++#define GLTSYN_TIME_0(_i) (0x000888C8 + ((_i) * 4)) + #define GLTSYN_TIME_H(_i) (0x000888D8 + ((_i) * 4)) + #define GLTSYN_TIME_L(_i) (0x000888D0 + ((_i) * 4)) + #define PFHH_SEM 0x000A4200 /* Reset Source: PFR */ +@@ -486,9 +506,11 @@ + #define PFTSYN_SEM_BUSY_M BIT(0) + #define VSIQF_FD_CNT(_VSI) (0x00464000 + ((_VSI) * 4)) + #define VSIQF_FD_CNT_FD_GCNT_S 0 +-#define VSIQF_FD_CNT_FD_GCNT_M ICE_M(0x3FFF, 0) ++#define E800_VSIQF_FD_CNT_FD_GCNT_M GENMASK(13, 0) ++#define E830_VSIQF_FD_CNT_FD_GCNT_M GENMASK(15, 0) + #define VSIQF_FD_CNT_FD_BCNT_S 16 +-#define VSIQF_FD_CNT_FD_BCNT_M ICE_M(0x3FFF, 16) ++#define E800_VSIQF_FD_CNT_FD_BCNT_M GENMASK(29, 16) ++#define E830_VSIQF_FD_CNT_FD_BCNT_M GENMASK(31, 16) + #define VSIQF_FD_SIZE(_VSI) (0x00462000 + ((_VSI) * 4)) + #define VSIQF_HKEY_MAX_INDEX 12 + #define PFPM_APM 0x000B8080 +@@ -500,7 +522,14 @@ + #define PFPM_WUS_MAG_M BIT(1) + #define PFPM_WUS_MNG_M BIT(3) + #define PFPM_WUS_FW_RST_WK_M BIT(31) ++#define E830_PRTMAC_CL01_PS_QNT 0x001E32A0 ++#define E830_PRTMAC_CL01_PS_QNT_CL0_M GENMASK(15, 0) ++#define E830_PRTMAC_CL01_QNT_THR 0x001E3320 ++#define E830_PRTMAC_CL01_QNT_THR_CL0_M GENMASK(15, 0) + #define VFINT_DYN_CTLN(_i) (0x00003800 + ((_i) * 4)) + #define VFINT_DYN_CTLN_CLEARPBA_M BIT(1) ++#define E830_MBX_PF_IN_FLIGHT_VF_MSGS_THRESH 0x00234000 ++#define E830_MBX_VF_DEC_TRIG(_VF) (0x00233800 + (_VF) * 4) ++#define E830_MBX_VF_IN_FLIGHT_MSGS_AT_PF_CNT(_VF) (0x00233000 + (_VF) * 4) + + #endif /* _ICE_HW_AUTOGEN_H_ */ +diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c +index 3a0ef56d3edcac..1fc4805353eb58 100644 +--- a/drivers/net/ethernet/intel/ice/ice_lib.c ++++ b/drivers/net/ethernet/intel/ice/ice_lib.c +@@ -4023,6 +4023,9 @@ void ice_init_feature_support(struct ice_pf *pf) + default: + break; + } ++ ++ if (pf->hw.mac_type == ICE_MAC_E830) ++ ice_set_feature_support(pf, ICE_F_MBX_LIMIT); + } + + /** +diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c +index 9f12c9a0fe2968..0ae7bdfff83fb2 100644 +--- a/drivers/net/ethernet/intel/ice/ice_main.c ++++ b/drivers/net/ethernet/intel/ice/ice_main.c +@@ -1,5 +1,5 @@ + // SPDX-License-Identifier: GPL-2.0 +-/* Copyright (c) 2018, Intel Corporation. */ ++/* Copyright (c) 2018-2023, Intel Corporation. */ + + /* Intel(R) Ethernet Connection E800 Series Linux Driver */ + +@@ -1514,12 +1514,20 @@ static int __ice_clean_ctrlq(struct ice_pf *pf, enum ice_ctl_q q_type) + ice_vf_lan_overflow_event(pf, &event); + break; + case ice_mbx_opc_send_msg_to_pf: +- data.num_msg_proc = i; +- data.num_pending_arq = pending; +- data.max_num_msgs_mbx = hw->mailboxq.num_rq_entries; +- data.async_watermark_val = ICE_MBX_OVERFLOW_WATERMARK; ++ if (ice_is_feature_supported(pf, ICE_F_MBX_LIMIT)) { ++ ice_vc_process_vf_msg(pf, &event, NULL); ++ ice_mbx_vf_dec_trig_e830(hw, &event); ++ } else { ++ u16 val = hw->mailboxq.num_rq_entries; ++ ++ data.max_num_msgs_mbx = val; ++ val = ICE_MBX_OVERFLOW_WATERMARK; ++ data.async_watermark_val = val; ++ data.num_msg_proc = i; ++ data.num_pending_arq = pending; + +- ice_vc_process_vf_msg(pf, &event, &data); ++ ice_vc_process_vf_msg(pf, &event, &data); ++ } + break; + case ice_aqc_opc_fw_logging: + ice_output_fw_log(hw, &event.desc, event.msg_buf); +@@ -1748,7 +1756,7 @@ static void ice_handle_mdd_event(struct ice_pf *pf) + wr32(hw, GL_MDET_TX_PQM, 0xffffffff); + } + +- reg = rd32(hw, GL_MDET_TX_TCLAN); ++ reg = rd32(hw, GL_MDET_TX_TCLAN_BY_MAC(hw)); + if (reg & GL_MDET_TX_TCLAN_VALID_M) { + u8 pf_num = (reg & GL_MDET_TX_TCLAN_PF_NUM_M) >> + GL_MDET_TX_TCLAN_PF_NUM_S; +@@ -1762,7 +1770,7 @@ static void ice_handle_mdd_event(struct ice_pf *pf) + if (netif_msg_tx_err(pf)) + dev_info(dev, "Malicious Driver Detection event %d on TX queue %d PF# %d VF# %d\n", + event, queue, pf_num, vf_num); +- wr32(hw, GL_MDET_TX_TCLAN, 0xffffffff); ++ wr32(hw, GL_MDET_TX_TCLAN_BY_MAC(hw), U32_MAX); + } + + reg = rd32(hw, GL_MDET_RX); +@@ -1790,9 +1798,9 @@ static void ice_handle_mdd_event(struct ice_pf *pf) + dev_info(dev, "Malicious Driver Detection event TX_PQM detected on PF\n"); + } + +- reg = rd32(hw, PF_MDET_TX_TCLAN); ++ reg = rd32(hw, PF_MDET_TX_TCLAN_BY_MAC(hw)); + if (reg & PF_MDET_TX_TCLAN_VALID_M) { +- wr32(hw, PF_MDET_TX_TCLAN, 0xFFFF); ++ wr32(hw, PF_MDET_TX_TCLAN_BY_MAC(hw), 0xffff); + if (netif_msg_tx_err(pf)) + dev_info(dev, "Malicious Driver Detection event TX_TCLAN detected on PF\n"); + } +@@ -3873,7 +3881,8 @@ static void ice_set_pf_caps(struct ice_pf *pf) + } + + clear_bit(ICE_FLAG_PTP_SUPPORTED, pf->flags); +- if (func_caps->common_cap.ieee_1588) ++ if (func_caps->common_cap.ieee_1588 && ++ !(pf->hw.mac_type == ICE_MAC_E830)) + set_bit(ICE_FLAG_PTP_SUPPORTED, pf->flags); + + pf->max_pf_txqs = func_caps->common_cap.num_txq; +@@ -3919,7 +3928,11 @@ static int ice_init_pf(struct ice_pf *pf) + + mutex_init(&pf->vfs.table_lock); + hash_init(pf->vfs.table); +- ice_mbx_init_snapshot(&pf->hw); ++ if (ice_is_feature_supported(pf, ICE_F_MBX_LIMIT)) ++ wr32(&pf->hw, E830_MBX_PF_IN_FLIGHT_VF_MSGS_THRESH, ++ ICE_MBX_OVERFLOW_WATERMARK); ++ else ++ ice_mbx_init_snapshot(&pf->hw); + + return 0; + } +diff --git a/drivers/net/ethernet/intel/ice/ice_sriov.c b/drivers/net/ethernet/intel/ice/ice_sriov.c +index 31314e7540f8cf..56345fe6537079 100644 +--- a/drivers/net/ethernet/intel/ice/ice_sriov.c ++++ b/drivers/net/ethernet/intel/ice/ice_sriov.c +@@ -36,6 +36,7 @@ static void ice_free_vf_entries(struct ice_pf *pf) + + hash_for_each_safe(vfs->table, bkt, tmp, vf, entry) { + hash_del_rcu(&vf->entry); ++ ice_deinitialize_vf_entry(vf); + ice_put_vf(vf); + } + } +@@ -194,9 +195,6 @@ void ice_free_vfs(struct ice_pf *pf) + wr32(hw, GLGEN_VFLRSTAT(reg_idx), BIT(bit_idx)); + } + +- /* clear malicious info since the VF is getting released */ +- list_del(&vf->mbx_info.list_entry); +- + mutex_unlock(&vf->cfg_lock); + } + +diff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h +index 5e353b0cbe6f73..35ee5b29ea34e4 100644 +--- a/drivers/net/ethernet/intel/ice/ice_type.h ++++ b/drivers/net/ethernet/intel/ice/ice_type.h +@@ -1,5 +1,5 @@ + /* SPDX-License-Identifier: GPL-2.0 */ +-/* Copyright (c) 2018, Intel Corporation. */ ++/* Copyright (c) 2018-2023, Intel Corporation. */ + + #ifndef _ICE_TYPE_H_ + #define _ICE_TYPE_H_ +@@ -129,6 +129,7 @@ enum ice_set_fc_aq_failures { + enum ice_mac_type { + ICE_MAC_UNKNOWN = 0, + ICE_MAC_E810, ++ ICE_MAC_E830, + ICE_MAC_GENERIC, + }; + +diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib.c b/drivers/net/ethernet/intel/ice/ice_vf_lib.c +index 03b9d7d748518c..58f9ac81dfbb2c 100644 +--- a/drivers/net/ethernet/intel/ice/ice_vf_lib.c ++++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.c +@@ -701,6 +701,23 @@ ice_vf_clear_vsi_promisc(struct ice_vf *vf, struct ice_vsi *vsi, u8 promisc_m) + return 0; + } + ++/** ++ * ice_reset_vf_mbx_cnt - reset VF mailbox message count ++ * @vf: pointer to the VF structure ++ * ++ * This function clears the VF mailbox message count, and should be called on ++ * VF reset. ++ */ ++static void ice_reset_vf_mbx_cnt(struct ice_vf *vf) ++{ ++ struct ice_pf *pf = vf->pf; ++ ++ if (ice_is_feature_supported(pf, ICE_F_MBX_LIMIT)) ++ ice_mbx_vf_clear_cnt_e830(&pf->hw, vf->vf_id); ++ else ++ ice_mbx_clear_malvf(&vf->mbx_info); ++} ++ + /** + * ice_reset_all_vfs - reset all allocated VFs in one go + * @pf: pointer to the PF structure +@@ -727,7 +744,7 @@ void ice_reset_all_vfs(struct ice_pf *pf) + + /* clear all malicious info if the VFs are getting reset */ + ice_for_each_vf(pf, bkt, vf) +- ice_mbx_clear_malvf(&vf->mbx_info); ++ ice_reset_vf_mbx_cnt(vf); + + /* If VFs have been disabled, there is no need to reset */ + if (test_and_set_bit(ICE_VF_DIS, pf->state)) { +@@ -944,7 +961,7 @@ int ice_reset_vf(struct ice_vf *vf, u32 flags) + ice_eswitch_update_repr(vsi); + + /* if the VF has been reset allow it to come up again */ +- ice_mbx_clear_malvf(&vf->mbx_info); ++ ice_reset_vf_mbx_cnt(vf); + + out_unlock: + if (lag && lag->bonded && lag->primary && +@@ -994,11 +1011,22 @@ void ice_initialize_vf_entry(struct ice_vf *vf) + ice_vf_fdir_init(vf); + + /* Initialize mailbox info for this VF */ +- ice_mbx_init_vf_info(&pf->hw, &vf->mbx_info); ++ if (ice_is_feature_supported(pf, ICE_F_MBX_LIMIT)) ++ ice_mbx_vf_clear_cnt_e830(&pf->hw, vf->vf_id); ++ else ++ ice_mbx_init_vf_info(&pf->hw, &vf->mbx_info); + + mutex_init(&vf->cfg_lock); + } + ++void ice_deinitialize_vf_entry(struct ice_vf *vf) ++{ ++ struct ice_pf *pf = vf->pf; ++ ++ if (!ice_is_feature_supported(pf, ICE_F_MBX_LIMIT)) ++ list_del(&vf->mbx_info.list_entry); ++} ++ + /** + * ice_dis_vf_qs - Disable the VF queues + * @vf: pointer to the VF structure +diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib_private.h b/drivers/net/ethernet/intel/ice/ice_vf_lib_private.h +index 0c7e77c0a09fa6..5392b040498621 100644 +--- a/drivers/net/ethernet/intel/ice/ice_vf_lib_private.h ++++ b/drivers/net/ethernet/intel/ice/ice_vf_lib_private.h +@@ -24,6 +24,7 @@ + #endif + + void ice_initialize_vf_entry(struct ice_vf *vf); ++void ice_deinitialize_vf_entry(struct ice_vf *vf); + void ice_dis_vf_qs(struct ice_vf *vf); + int ice_check_vf_init(struct ice_vf *vf); + enum virtchnl_status_code ice_err_to_virt_err(int err); +diff --git a/drivers/net/ethernet/intel/ice/ice_vf_mbx.c b/drivers/net/ethernet/intel/ice/ice_vf_mbx.c +index 40cb4ba0789ced..75c8113e58ee92 100644 +--- a/drivers/net/ethernet/intel/ice/ice_vf_mbx.c ++++ b/drivers/net/ethernet/intel/ice/ice_vf_mbx.c +@@ -210,6 +210,38 @@ ice_mbx_detect_malvf(struct ice_hw *hw, struct ice_mbx_vf_info *vf_info, + return 0; + } + ++/** ++ * ice_mbx_vf_dec_trig_e830 - Decrements the VF mailbox queue counter ++ * @hw: pointer to the HW struct ++ * @event: pointer to the control queue receive event ++ * ++ * This function triggers to decrement the counter ++ * MBX_VF_IN_FLIGHT_MSGS_AT_PF_CNT when the driver replenishes ++ * the buffers at the PF mailbox queue. ++ */ ++void ice_mbx_vf_dec_trig_e830(const struct ice_hw *hw, ++ const struct ice_rq_event_info *event) ++{ ++ u16 vfid = le16_to_cpu(event->desc.retval); ++ ++ wr32(hw, E830_MBX_VF_DEC_TRIG(vfid), 1); ++} ++ ++/** ++ * ice_mbx_vf_clear_cnt_e830 - Clear the VF mailbox queue count ++ * @hw: pointer to the HW struct ++ * @vf_id: VF ID in the PF space ++ * ++ * This function clears the counter MBX_VF_IN_FLIGHT_MSGS_AT_PF_CNT, and should ++ * be called when a VF is created and on VF reset. ++ */ ++void ice_mbx_vf_clear_cnt_e830(const struct ice_hw *hw, u16 vf_id) ++{ ++ u32 reg = rd32(hw, E830_MBX_VF_IN_FLIGHT_MSGS_AT_PF_CNT(vf_id)); ++ ++ wr32(hw, E830_MBX_VF_DEC_TRIG(vf_id), reg); ++} ++ + /** + * ice_mbx_vf_state_handler - Handle states of the overflow algorithm + * @hw: pointer to the HW struct +diff --git a/drivers/net/ethernet/intel/ice/ice_vf_mbx.h b/drivers/net/ethernet/intel/ice/ice_vf_mbx.h +index 44bc030d17e07a..684de89e5c5ed7 100644 +--- a/drivers/net/ethernet/intel/ice/ice_vf_mbx.h ++++ b/drivers/net/ethernet/intel/ice/ice_vf_mbx.h +@@ -19,6 +19,9 @@ ice_aq_send_msg_to_vf(struct ice_hw *hw, u16 vfid, u32 v_opcode, u32 v_retval, + u8 *msg, u16 msglen, struct ice_sq_cd *cd); + + u32 ice_conv_link_speed_to_virtchnl(bool adv_link_support, u16 link_speed); ++void ice_mbx_vf_dec_trig_e830(const struct ice_hw *hw, ++ const struct ice_rq_event_info *event); ++void ice_mbx_vf_clear_cnt_e830(const struct ice_hw *hw, u16 vf_id); + int + ice_mbx_vf_state_handler(struct ice_hw *hw, struct ice_mbx_data *mbx_data, + struct ice_mbx_vf_info *vf_info, bool *report_malvf); +@@ -47,5 +50,11 @@ static inline void ice_mbx_init_snapshot(struct ice_hw *hw) + { + } + ++static inline void ++ice_mbx_vf_dec_trig_e830(const struct ice_hw *hw, ++ const struct ice_rq_event_info *event) ++{ ++} ++ + #endif /* CONFIG_PCI_IOV */ + #endif /* _ICE_VF_MBX_H_ */ +diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl.c b/drivers/net/ethernet/intel/ice/ice_virtchnl.c +index 9f7268bb2ee3b4..e709b10a29761b 100644 +--- a/drivers/net/ethernet/intel/ice/ice_virtchnl.c ++++ b/drivers/net/ethernet/intel/ice/ice_virtchnl.c +@@ -3899,8 +3899,10 @@ ice_is_malicious_vf(struct ice_vf *vf, struct ice_mbx_data *mbxdata) + * @event: pointer to the AQ event + * @mbxdata: information used to detect VF attempting mailbox overflow + * +- * called from the common asq/arq handler to +- * process request from VF ++ * Called from the common asq/arq handler to process request from VF. When this ++ * flow is used for devices with hardware VF to PF message queue overflow ++ * support (ICE_F_MBX_LIMIT) mbxdata is set to NULL and ice_is_malicious_vf ++ * check is skipped. + */ + void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event, + struct ice_mbx_data *mbxdata) +@@ -3926,7 +3928,7 @@ void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event, + mutex_lock(&vf->cfg_lock); + + /* Check if the VF is trying to overflow the mailbox */ +- if (ice_is_malicious_vf(vf, mbxdata)) ++ if (mbxdata && ice_is_malicious_vf(vf, mbxdata)) + goto finish; + + /* Check if VF is disabled. */ +diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c b/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c +index 974c71490d97c0..3ca5f44dea26eb 100644 +--- a/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c ++++ b/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c +@@ -1,5 +1,5 @@ + // SPDX-License-Identifier: GPL-2.0 +-/* Copyright (C) 2021, Intel Corporation. */ ++/* Copyright (C) 2021-2023, Intel Corporation. */ + + #include "ice.h" + #include "ice_base.h" +@@ -1421,8 +1421,8 @@ ice_vc_fdir_irq_handler(struct ice_vsi *ctrl_vsi, + */ + static void ice_vf_fdir_dump_info(struct ice_vf *vf) + { ++ u32 fd_size, fd_cnt, fd_size_g, fd_cnt_g, fd_size_b, fd_cnt_b; + struct ice_vsi *vf_vsi; +- u32 fd_size, fd_cnt; + struct device *dev; + struct ice_pf *pf; + struct ice_hw *hw; +@@ -1441,12 +1441,25 @@ static void ice_vf_fdir_dump_info(struct ice_vf *vf) + + fd_size = rd32(hw, VSIQF_FD_SIZE(vsi_num)); + fd_cnt = rd32(hw, VSIQF_FD_CNT(vsi_num)); +- dev_dbg(dev, "VF %d: space allocated: guar:0x%x, be:0x%x, space consumed: guar:0x%x, be:0x%x\n", +- vf->vf_id, +- (fd_size & VSIQF_FD_CNT_FD_GCNT_M) >> VSIQF_FD_CNT_FD_GCNT_S, +- (fd_size & VSIQF_FD_CNT_FD_BCNT_M) >> VSIQF_FD_CNT_FD_BCNT_S, +- (fd_cnt & VSIQF_FD_CNT_FD_GCNT_M) >> VSIQF_FD_CNT_FD_GCNT_S, +- (fd_cnt & VSIQF_FD_CNT_FD_BCNT_M) >> VSIQF_FD_CNT_FD_BCNT_S); ++ switch (hw->mac_type) { ++ case ICE_MAC_E830: ++ fd_size_g = FIELD_GET(E830_VSIQF_FD_CNT_FD_GCNT_M, fd_size); ++ fd_size_b = FIELD_GET(E830_VSIQF_FD_CNT_FD_BCNT_M, fd_size); ++ fd_cnt_g = FIELD_GET(E830_VSIQF_FD_CNT_FD_GCNT_M, fd_cnt); ++ fd_cnt_b = FIELD_GET(E830_VSIQF_FD_CNT_FD_BCNT_M, fd_cnt); ++ break; ++ case ICE_MAC_E810: ++ default: ++ fd_size_g = FIELD_GET(E800_VSIQF_FD_CNT_FD_GCNT_M, fd_size); ++ fd_size_b = FIELD_GET(E800_VSIQF_FD_CNT_FD_BCNT_M, fd_size); ++ fd_cnt_g = FIELD_GET(E800_VSIQF_FD_CNT_FD_GCNT_M, fd_cnt); ++ fd_cnt_b = FIELD_GET(E800_VSIQF_FD_CNT_FD_BCNT_M, fd_cnt); ++ } ++ ++ dev_dbg(dev, "VF %d: Size in the FD table: guaranteed:0x%x, best effort:0x%x\n", ++ vf->vf_id, fd_size_g, fd_size_b); ++ dev_dbg(dev, "VF %d: Filter counter in the FD table: guaranteed:0x%x, best effort:0x%x\n", ++ vf->vf_id, fd_cnt_g, fd_cnt_b); + } + + /** +diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c +index 40aeaa7bd739fa..d2757cc1161391 100644 +--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c ++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c +@@ -324,7 +324,7 @@ static const struct mvpp2_cls_flow cls_flows[MVPP2_N_PRS_FLOWS] = { + MVPP2_PRS_RI_VLAN_MASK), + /* Non IP flow, with vlan tag */ + MVPP2_DEF_FLOW(MVPP22_FLOW_ETHERNET, MVPP2_FL_NON_IP_TAG, +- MVPP22_CLS_HEK_OPT_VLAN, ++ MVPP22_CLS_HEK_TAGGED, + 0, 0), + }; + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c +index 6bac8ad70ba60b..a8d6fd18c0f557 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c +@@ -617,7 +617,7 @@ irq_pool_alloc(struct mlx5_core_dev *dev, int start, int size, char *name, + pool->min_threshold = min_threshold * MLX5_EQ_REFS_PER_IRQ; + pool->max_threshold = max_threshold * MLX5_EQ_REFS_PER_IRQ; + mlx5_core_dbg(dev, "pool->name = %s, pool->size = %d, pool->start = %d", +- name, size, start); ++ name ? name : "mlx5_pcif_pool", size, start); + return pool; + } + +diff --git a/drivers/net/ethernet/ti/icssg/icss_iep.c b/drivers/net/ethernet/ti/icssg/icss_iep.c +index f06cdec14ed7a1..3f9a030471fe2f 100644 +--- a/drivers/net/ethernet/ti/icssg/icss_iep.c ++++ b/drivers/net/ethernet/ti/icssg/icss_iep.c +@@ -110,7 +110,6 @@ struct icss_iep { + struct ptp_clock_info ptp_info; + struct ptp_clock *ptp_clock; + struct mutex ptp_clk_mutex; /* PHC access serializer */ +- spinlock_t irq_lock; /* CMP IRQ vs icss_iep_ptp_enable access */ + u32 def_inc; + s16 slow_cmp_inc; + u32 slow_cmp_count; +@@ -192,14 +191,11 @@ static void icss_iep_update_to_next_boundary(struct icss_iep *iep, u64 start_ns) + */ + static void icss_iep_settime(struct icss_iep *iep, u64 ns) + { +- unsigned long flags; +- + if (iep->ops && iep->ops->settime) { + iep->ops->settime(iep->clockops_data, ns); + return; + } + +- spin_lock_irqsave(&iep->irq_lock, flags); + if (iep->pps_enabled || iep->perout_enabled) + writel(0, iep->base + iep->plat_data->reg_offs[ICSS_IEP_SYNC_CTRL_REG]); + +@@ -210,7 +206,6 @@ static void icss_iep_settime(struct icss_iep *iep, u64 ns) + writel(IEP_SYNC_CTRL_SYNC_N_EN(0) | IEP_SYNC_CTRL_SYNC_EN, + iep->base + iep->plat_data->reg_offs[ICSS_IEP_SYNC_CTRL_REG]); + } +- spin_unlock_irqrestore(&iep->irq_lock, flags); + } + + /** +@@ -549,36 +544,13 @@ static int icss_iep_perout_enable_hw(struct icss_iep *iep, + static int icss_iep_perout_enable(struct icss_iep *iep, + struct ptp_perout_request *req, int on) + { +- unsigned long flags; +- int ret = 0; +- +- mutex_lock(&iep->ptp_clk_mutex); +- +- if (iep->pps_enabled) { +- ret = -EBUSY; +- goto exit; +- } +- +- if (iep->perout_enabled == !!on) +- goto exit; +- +- spin_lock_irqsave(&iep->irq_lock, flags); +- ret = icss_iep_perout_enable_hw(iep, req, on); +- if (!ret) +- iep->perout_enabled = !!on; +- spin_unlock_irqrestore(&iep->irq_lock, flags); +- +-exit: +- mutex_unlock(&iep->ptp_clk_mutex); +- +- return ret; ++ return -EOPNOTSUPP; + } + + static int icss_iep_pps_enable(struct icss_iep *iep, int on) + { + struct ptp_clock_request rq; + struct timespec64 ts; +- unsigned long flags; + int ret = 0; + u64 ns; + +@@ -592,8 +564,6 @@ static int icss_iep_pps_enable(struct icss_iep *iep, int on) + if (iep->pps_enabled == !!on) + goto exit; + +- spin_lock_irqsave(&iep->irq_lock, flags); +- + rq.perout.index = 0; + if (on) { + ns = icss_iep_gettime(iep, NULL); +@@ -610,8 +580,6 @@ static int icss_iep_pps_enable(struct icss_iep *iep, int on) + if (!ret) + iep->pps_enabled = !!on; + +- spin_unlock_irqrestore(&iep->irq_lock, flags); +- + exit: + mutex_unlock(&iep->ptp_clk_mutex); + +@@ -861,7 +829,6 @@ static int icss_iep_probe(struct platform_device *pdev) + + iep->ptp_info = icss_iep_ptp_info; + mutex_init(&iep->ptp_clk_mutex); +- spin_lock_init(&iep->irq_lock); + dev_set_drvdata(dev, iep); + icss_iep_disable(iep); + +diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c +index fef4eff7753a7a..ca62188a317ad4 100644 +--- a/drivers/net/ipvlan/ipvlan_core.c ++++ b/drivers/net/ipvlan/ipvlan_core.c +@@ -2,6 +2,9 @@ + /* Copyright (c) 2014 Mahesh Bandewar + */ + ++#include ++#include ++ + #include "ipvlan.h" + + static u32 ipvlan_jhash_secret __read_mostly; +@@ -413,20 +416,25 @@ struct ipvl_addr *ipvlan_addr_lookup(struct ipvl_port *port, void *lyr3h, + + static noinline_for_stack int ipvlan_process_v4_outbound(struct sk_buff *skb) + { +- const struct iphdr *ip4h = ip_hdr(skb); + struct net_device *dev = skb->dev; + struct net *net = dev_net(dev); +- struct rtable *rt; + int err, ret = NET_XMIT_DROP; ++ const struct iphdr *ip4h; ++ struct rtable *rt; + struct flowi4 fl4 = { + .flowi4_oif = dev->ifindex, +- .flowi4_tos = RT_TOS(ip4h->tos), + .flowi4_flags = FLOWI_FLAG_ANYSRC, + .flowi4_mark = skb->mark, +- .daddr = ip4h->daddr, +- .saddr = ip4h->saddr, + }; + ++ if (!pskb_network_may_pull(skb, sizeof(struct iphdr))) ++ goto err; ++ ++ ip4h = ip_hdr(skb); ++ fl4.daddr = ip4h->daddr; ++ fl4.saddr = ip4h->saddr; ++ fl4.flowi4_tos = inet_dscp_to_dsfield(ip4h_dscp(ip4h)); ++ + rt = ip_route_output_flow(net, &fl4, NULL); + if (IS_ERR(rt)) + goto err; +@@ -485,6 +493,12 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb) + struct net_device *dev = skb->dev; + int err, ret = NET_XMIT_DROP; + ++ if (!pskb_network_may_pull(skb, sizeof(struct ipv6hdr))) { ++ DEV_STATS_INC(dev, tx_errors); ++ kfree_skb(skb); ++ return ret; ++ } ++ + err = ipvlan_route_v6_outbound(dev, skb); + if (unlikely(err)) { + DEV_STATS_INC(dev, tx_errors); +diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c +index f6eab66c266081..6aa00f62b1f902 100644 +--- a/drivers/net/loopback.c ++++ b/drivers/net/loopback.c +@@ -247,8 +247,22 @@ static netdev_tx_t blackhole_netdev_xmit(struct sk_buff *skb, + return NETDEV_TX_OK; + } + ++static int blackhole_neigh_output(struct neighbour *n, struct sk_buff *skb) ++{ ++ kfree_skb(skb); ++ return 0; ++} ++ ++static int blackhole_neigh_construct(struct net_device *dev, ++ struct neighbour *n) ++{ ++ n->output = blackhole_neigh_output; ++ return 0; ++} ++ + static const struct net_device_ops blackhole_netdev_ops = { + .ndo_start_xmit = blackhole_netdev_xmit, ++ .ndo_neigh_construct = blackhole_neigh_construct, + }; + + /* This is a dst-dummy device used specifically for invalidated +diff --git a/drivers/net/usb/gl620a.c b/drivers/net/usb/gl620a.c +index 46af78caf457a6..0bfa37c1405918 100644 +--- a/drivers/net/usb/gl620a.c ++++ b/drivers/net/usb/gl620a.c +@@ -179,9 +179,7 @@ static int genelink_bind(struct usbnet *dev, struct usb_interface *intf) + { + dev->hard_mtu = GL_RCV_BUF_SIZE; + dev->net->hard_header_len += 4; +- dev->in = usb_rcvbulkpipe(dev->udev, dev->driver_info->in); +- dev->out = usb_sndbulkpipe(dev->udev, dev->driver_info->out); +- return 0; ++ return usbnet_get_endpoints(dev, intf); + } + + static const struct driver_info genelink_info = { +diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c +index 9c231094ba3594..2354ce8b215943 100644 +--- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c ++++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c +@@ -309,7 +309,10 @@ static int rockchip_combphy_parse_dt(struct device *dev, struct rockchip_combphy + + priv->ext_refclk = device_property_present(dev, "rockchip,ext-refclk"); + +- priv->phy_rst = devm_reset_control_get(dev, "phy"); ++ priv->phy_rst = devm_reset_control_get_exclusive(dev, "phy"); ++ /* fallback to old behaviour */ ++ if (PTR_ERR(priv->phy_rst) == -ENOENT) ++ priv->phy_rst = devm_reset_control_array_get_exclusive(dev); + if (IS_ERR(priv->phy_rst)) + return dev_err_probe(dev, PTR_ERR(priv->phy_rst), "failed to get phy reset\n"); + +diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c +index 3f310b28bfff79..fea76f2ce6fff6 100644 +--- a/drivers/phy/samsung/phy-exynos5-usbdrd.c ++++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c +@@ -319,9 +319,9 @@ exynos5_usbdrd_pipe3_set_refclk(struct phy_usb_instance *inst) + reg |= PHYCLKRST_REFCLKSEL_EXT_REFCLK; + + /* FSEL settings corresponding to reference clock */ +- reg &= ~PHYCLKRST_FSEL_PIPE_MASK | +- PHYCLKRST_MPLL_MULTIPLIER_MASK | +- PHYCLKRST_SSC_REFCLKSEL_MASK; ++ reg &= ~(PHYCLKRST_FSEL_PIPE_MASK | ++ PHYCLKRST_MPLL_MULTIPLIER_MASK | ++ PHYCLKRST_SSC_REFCLKSEL_MASK); + switch (phy_drd->extrefclk) { + case EXYNOS5_FSEL_50MHZ: + reg |= (PHYCLKRST_MPLL_MULTIPLIER_50M_REF | +@@ -363,9 +363,9 @@ exynos5_usbdrd_utmi_set_refclk(struct phy_usb_instance *inst) + reg &= ~PHYCLKRST_REFCLKSEL_MASK; + reg |= PHYCLKRST_REFCLKSEL_EXT_REFCLK; + +- reg &= ~PHYCLKRST_FSEL_UTMI_MASK | +- PHYCLKRST_MPLL_MULTIPLIER_MASK | +- PHYCLKRST_SSC_REFCLKSEL_MASK; ++ reg &= ~(PHYCLKRST_FSEL_UTMI_MASK | ++ PHYCLKRST_MPLL_MULTIPLIER_MASK | ++ PHYCLKRST_SSC_REFCLKSEL_MASK); + reg |= PHYCLKRST_FSEL(phy_drd->extrefclk); + + return reg; +diff --git a/drivers/phy/tegra/xusb-tegra186.c b/drivers/phy/tegra/xusb-tegra186.c +index 0f60d5d1c1678d..fae6242aa730e0 100644 +--- a/drivers/phy/tegra/xusb-tegra186.c ++++ b/drivers/phy/tegra/xusb-tegra186.c +@@ -928,6 +928,7 @@ static int tegra186_utmi_phy_init(struct phy *phy) + unsigned int index = lane->index; + struct device *dev = padctl->dev; + int err; ++ u32 reg; + + port = tegra_xusb_find_usb2_port(padctl, index); + if (!port) { +@@ -935,6 +936,16 @@ static int tegra186_utmi_phy_init(struct phy *phy) + return -ENODEV; + } + ++ if (port->mode == USB_DR_MODE_OTG || ++ port->mode == USB_DR_MODE_PERIPHERAL) { ++ /* reset VBUS&ID OVERRIDE */ ++ reg = padctl_readl(padctl, USB2_VBUS_ID); ++ reg &= ~VBUS_OVERRIDE; ++ reg &= ~ID_OVERRIDE(~0); ++ reg |= ID_OVERRIDE_FLOATING; ++ padctl_writel(padctl, reg, USB2_VBUS_ID); ++ } ++ + if (port->supply && port->mode == USB_DR_MODE_HOST) { + err = regulator_enable(port->supply); + if (err) { +diff --git a/drivers/platform/x86/intel/ifs/load.c b/drivers/platform/x86/intel/ifs/load.c +index 53d957d4eea4d1..1c50ecd8a03299 100644 +--- a/drivers/platform/x86/intel/ifs/load.c ++++ b/drivers/platform/x86/intel/ifs/load.c +@@ -227,7 +227,7 @@ static int scan_chunks_sanity_check(struct device *dev) + + static int image_sanity_check(struct device *dev, const struct microcode_header_intel *data) + { +- struct ucode_cpu_info uci; ++ struct cpu_signature sig; + + /* Provide a specific error message when loading an older/unsupported image */ + if (data->hdrver != MC_HEADER_TYPE_IFS) { +@@ -240,11 +240,9 @@ static int image_sanity_check(struct device *dev, const struct microcode_header_ + return -EINVAL; + } + +- intel_cpu_collect_info(&uci); ++ intel_collect_cpu_info(&sig); + +- if (!intel_find_matching_signature((void *)data, +- uci.cpu_sig.sig, +- uci.cpu_sig.pf)) { ++ if (!intel_find_matching_signature((void *)data, &sig)) { + dev_err(dev, "cpu signature, processor flags not matching\n"); + return -EINVAL; + } +diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c +index f026377f1cf1c4..e6dc2c556fde9e 100644 +--- a/drivers/scsi/scsi_lib.c ++++ b/drivers/scsi/scsi_lib.c +@@ -1570,13 +1570,6 @@ static blk_status_t scsi_prepare_cmd(struct request *req) + if (in_flight) + __set_bit(SCMD_STATE_INFLIGHT, &cmd->state); + +- /* +- * Only clear the driver-private command data if the LLD does not supply +- * a function to initialize that data. +- */ +- if (!shost->hostt->init_cmd_priv) +- memset(cmd + 1, 0, shost->hostt->cmd_size); +- + cmd->prot_op = SCSI_PROT_NORMAL; + if (blk_rq_bytes(req)) + cmd->sc_data_direction = rq_dma_dir(req); +@@ -1743,6 +1736,13 @@ static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx, + if (!scsi_host_queue_ready(q, shost, sdev, cmd)) + goto out_dec_target_busy; + ++ /* ++ * Only clear the driver-private command data if the LLD does not supply ++ * a function to initialize that data. ++ */ ++ if (shost->hostt->cmd_size && !shost->hostt->init_cmd_priv) ++ memset(cmd + 1, 0, shost->hostt->cmd_size); ++ + if (!(req->rq_flags & RQF_DONTPREP)) { + ret = scsi_prepare_cmd(req); + if (ret != BLK_STS_OK) +diff --git a/drivers/ufs/core/ufs_bsg.c b/drivers/ufs/core/ufs_bsg.c +index 8fbd46cd8c2b8e..0043d69077b646 100644 +--- a/drivers/ufs/core/ufs_bsg.c ++++ b/drivers/ufs/core/ufs_bsg.c +@@ -194,10 +194,12 @@ static int ufs_bsg_request(struct bsg_job *job) + ufshcd_rpm_put_sync(hba); + kfree(buff); + bsg_reply->result = ret; +- job->reply_len = !rpmb ? sizeof(struct ufs_bsg_reply) : sizeof(struct ufs_rpmb_reply); + /* complete the job here only if no error */ +- if (ret == 0) ++ if (ret == 0) { ++ job->reply_len = rpmb ? sizeof(struct ufs_rpmb_reply) : ++ sizeof(struct ufs_bsg_reply); + bsg_job_done(job, ret, bsg_reply->reply_payload_rcv_len); ++ } + + return ret; + } +diff --git a/drivers/ufs/core/ufshcd-priv.h b/drivers/ufs/core/ufshcd-priv.h +index 524863b157e8aa..dffc932285ac50 100644 +--- a/drivers/ufs/core/ufshcd-priv.h ++++ b/drivers/ufs/core/ufshcd-priv.h +@@ -324,6 +324,11 @@ static inline int ufshcd_rpm_get_sync(struct ufs_hba *hba) + return pm_runtime_get_sync(&hba->ufs_device_wlun->sdev_gendev); + } + ++static inline int ufshcd_rpm_get_if_active(struct ufs_hba *hba) ++{ ++ return pm_runtime_get_if_active(&hba->ufs_device_wlun->sdev_gendev, true); ++} ++ + static inline int ufshcd_rpm_put_sync(struct ufs_hba *hba) + { + return pm_runtime_put_sync(&hba->ufs_device_wlun->sdev_gendev); +diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c +index 0ac0b6aaf9c62c..6d53dd7d411a85 100644 +--- a/drivers/ufs/core/ufshcd.c ++++ b/drivers/ufs/core/ufshcd.c +@@ -98,6 +98,9 @@ + /* Polling time to wait for fDeviceInit */ + #define FDEVICEINIT_COMPL_TIMEOUT 1500 /* millisecs */ + ++/* Default RTC update every 10 seconds */ ++#define UFS_RTC_UPDATE_INTERVAL_MS (10 * MSEC_PER_SEC) ++ + /* UFSHC 4.0 compliant HC support this mode. */ + static bool use_mcq_mode = true; + +@@ -234,6 +237,17 @@ ufs_get_desired_pm_lvl_for_dev_link_state(enum ufs_dev_pwr_mode dev_state, + return UFS_PM_LVL_0; + } + ++static bool ufshcd_has_pending_tasks(struct ufs_hba *hba) ++{ ++ return hba->outstanding_tasks || hba->active_uic_cmd || ++ hba->uic_async_done; ++} ++ ++static bool ufshcd_is_ufs_dev_busy(struct ufs_hba *hba) ++{ ++ return scsi_host_busy(hba->host) || ufshcd_has_pending_tasks(hba); ++} ++ + static const struct ufs_dev_quirk ufs_fixups[] = { + /* UFS cards deviations table */ + { .wmanufacturerid = UFS_VENDOR_MICRON, +@@ -602,8 +616,8 @@ static void ufshcd_print_host_state(struct ufs_hba *hba) + const struct scsi_device *sdev_ufs = hba->ufs_device_wlun; + + dev_err(hba->dev, "UFS Host state=%d\n", hba->ufshcd_state); +- dev_err(hba->dev, "outstanding reqs=0x%lx tasks=0x%lx\n", +- hba->outstanding_reqs, hba->outstanding_tasks); ++ dev_err(hba->dev, "%d outstanding reqs, tasks=0x%lx\n", ++ scsi_host_busy(hba->host), hba->outstanding_tasks); + dev_err(hba->dev, "saved_err=0x%x, saved_uic_err=0x%x\n", + hba->saved_err, hba->saved_uic_err); + dev_err(hba->dev, "Device power mode=%d, UIC link state=%d\n", +@@ -676,6 +690,8 @@ static void ufshcd_device_reset(struct ufs_hba *hba) + hba->dev_info.wb_enabled = false; + hba->dev_info.wb_buf_flush_enabled = false; + } ++ if (hba->dev_info.rtc_type == UFS_RTC_RELATIVE) ++ hba->dev_info.rtc_time_baseline = 0; + } + if (err != -EOPNOTSUPP) + ufshcd_update_evt_hist(hba, UFS_EVT_DEV_RESET, err); +@@ -1816,10 +1832,9 @@ static void ufshcd_gate_work(struct work_struct *work) + goto rel_lock; + } + +- if (hba->clk_gating.active_reqs +- || hba->ufshcd_state != UFSHCD_STATE_OPERATIONAL +- || hba->outstanding_reqs || hba->outstanding_tasks +- || hba->active_uic_cmd || hba->uic_async_done) ++ if (ufshcd_is_ufs_dev_busy(hba) || ++ hba->ufshcd_state != UFSHCD_STATE_OPERATIONAL || ++ hba->clk_gating.active_reqs) + goto rel_lock; + + spin_unlock_irqrestore(hba->host->host_lock, flags); +@@ -1875,8 +1890,7 @@ static void __ufshcd_release(struct ufs_hba *hba) + + if (hba->clk_gating.active_reqs || hba->clk_gating.is_suspended || + hba->ufshcd_state != UFSHCD_STATE_OPERATIONAL || +- hba->outstanding_tasks || !hba->clk_gating.is_initialized || +- hba->active_uic_cmd || hba->uic_async_done || ++ ufshcd_has_pending_tasks(hba) || !hba->clk_gating.is_initialized || + hba->clk_gating.state == CLKS_OFF) + return; + +@@ -8146,6 +8160,77 @@ static void ufs_fixup_device_setup(struct ufs_hba *hba) + ufshcd_vops_fixup_dev_quirks(hba); + } + ++static void ufshcd_update_rtc(struct ufs_hba *hba) ++{ ++ struct timespec64 ts64; ++ int err; ++ u32 val; ++ ++ ktime_get_real_ts64(&ts64); ++ ++ if (ts64.tv_sec < hba->dev_info.rtc_time_baseline) { ++ dev_warn_once(hba->dev, "%s: Current time precedes previous setting!\n", __func__); ++ return; ++ } ++ ++ /* ++ * The Absolute RTC mode has a 136-year limit, spanning from 2010 to 2146. If a time beyond ++ * 2146 is required, it is recommended to choose the relative RTC mode. ++ */ ++ val = ts64.tv_sec - hba->dev_info.rtc_time_baseline; ++ ++ /* Skip update RTC if RPM state is not RPM_ACTIVE */ ++ if (ufshcd_rpm_get_if_active(hba) <= 0) ++ return; ++ ++ err = ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_WRITE_ATTR, QUERY_ATTR_IDN_SECONDS_PASSED, ++ 0, 0, &val); ++ ufshcd_rpm_put(hba); ++ ++ if (err) ++ dev_err(hba->dev, "%s: Failed to update rtc %d\n", __func__, err); ++ else if (hba->dev_info.rtc_type == UFS_RTC_RELATIVE) ++ hba->dev_info.rtc_time_baseline = ts64.tv_sec; ++} ++ ++static void ufshcd_rtc_work(struct work_struct *work) ++{ ++ struct ufs_hba *hba; ++ ++ hba = container_of(to_delayed_work(work), struct ufs_hba, ufs_rtc_update_work); ++ ++ /* Update RTC only when there are no requests in progress and UFSHCI is operational */ ++ if (!ufshcd_is_ufs_dev_busy(hba) && ++ hba->ufshcd_state == UFSHCD_STATE_OPERATIONAL && ++ !hba->clk_gating.active_reqs) ++ ufshcd_update_rtc(hba); ++ ++ if (ufshcd_is_ufs_dev_active(hba)) ++ schedule_delayed_work(&hba->ufs_rtc_update_work, ++ msecs_to_jiffies(UFS_RTC_UPDATE_INTERVAL_MS)); ++} ++ ++static void ufs_init_rtc(struct ufs_hba *hba, u8 *desc_buf) ++{ ++ u16 periodic_rtc_update = get_unaligned_be16(&desc_buf[DEVICE_DESC_PARAM_FRQ_RTC]); ++ struct ufs_dev_info *dev_info = &hba->dev_info; ++ ++ if (periodic_rtc_update & UFS_RTC_TIME_BASELINE) { ++ dev_info->rtc_type = UFS_RTC_ABSOLUTE; ++ ++ /* ++ * The concept of measuring time in Linux as the number of seconds elapsed since ++ * 00:00:00 UTC on January 1, 1970, and UFS ABS RTC is elapsed from January 1st ++ * 2010 00:00, here we need to adjust ABS baseline. ++ */ ++ dev_info->rtc_time_baseline = mktime64(2010, 1, 1, 0, 0, 0) - ++ mktime64(1970, 1, 1, 0, 0, 0); ++ } else { ++ dev_info->rtc_type = UFS_RTC_RELATIVE; ++ dev_info->rtc_time_baseline = 0; ++ } ++} ++ + static int ufs_get_device_desc(struct ufs_hba *hba) + { + int err; +@@ -8198,6 +8283,8 @@ static int ufs_get_device_desc(struct ufs_hba *hba) + + ufshcd_temp_notif_probe(hba, desc_buf); + ++ ufs_init_rtc(hba, desc_buf); ++ + if (hba->ext_iid_sup) + ufshcd_ext_iid_probe(hba, desc_buf); + +@@ -8591,6 +8678,14 @@ static int ufshcd_add_lus(struct ufs_hba *hba) + ufshcd_init_clk_scaling_sysfs(hba); + } + ++ /* ++ * The RTC update code accesses the hba->ufs_device_wlun->sdev_gendev ++ * pointer and hence must only be started after the WLUN pointer has ++ * been initialized by ufshcd_scsi_add_wlus(). ++ */ ++ schedule_delayed_work(&hba->ufs_rtc_update_work, ++ msecs_to_jiffies(UFS_RTC_UPDATE_INTERVAL_MS)); ++ + ufs_bsg_probe(hba); + scsi_scan_host(hba->host); + +@@ -8887,7 +8982,7 @@ static enum scsi_timeout_action ufshcd_eh_timed_out(struct scsi_cmnd *scmd) + dev_info(hba->dev, "%s() finished; outstanding_tasks = %#lx.\n", + __func__, hba->outstanding_tasks); + +- return hba->outstanding_reqs ? SCSI_EH_RESET_TIMER : SCSI_EH_DONE; ++ return scsi_host_busy(hba->host) ? SCSI_EH_RESET_TIMER : SCSI_EH_DONE; + } + + static const struct attribute_group *ufshcd_driver_groups[] = { +@@ -9695,6 +9790,8 @@ static int __ufshcd_wl_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) + ret = ufshcd_vops_suspend(hba, pm_op, POST_CHANGE); + if (ret) + goto set_link_active; ++ ++ cancel_delayed_work_sync(&hba->ufs_rtc_update_work); + goto out; + + set_link_active: +@@ -9789,6 +9886,8 @@ static int __ufshcd_wl_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) + if (ret) + goto set_old_link_state; + ufshcd_set_timestamp_attr(hba); ++ schedule_delayed_work(&hba->ufs_rtc_update_work, ++ msecs_to_jiffies(UFS_RTC_UPDATE_INTERVAL_MS)); + } + + if (ufshcd_keep_autobkops_enabled_except_suspend(hba)) +@@ -10160,6 +10259,7 @@ void ufshcd_remove(struct ufs_hba *hba) + ufs_hwmon_remove(hba); + ufs_bsg_remove(hba); + ufs_sysfs_remove_nodes(hba->dev); ++ cancel_delayed_work_sync(&hba->ufs_rtc_update_work); + blk_mq_destroy_queue(hba->tmf_queue); + blk_put_queue(hba->tmf_queue); + blk_mq_free_tag_set(&hba->tmf_tag_set); +@@ -10497,8 +10597,8 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) + UFS_SLEEP_PWR_MODE, + UIC_LINK_HIBERN8_STATE); + +- INIT_DELAYED_WORK(&hba->rpm_dev_flush_recheck_work, +- ufshcd_rpm_dev_flush_recheck_work); ++ INIT_DELAYED_WORK(&hba->rpm_dev_flush_recheck_work, ufshcd_rpm_dev_flush_recheck_work); ++ INIT_DELAYED_WORK(&hba->ufs_rtc_update_work, ufshcd_rtc_work); + + /* Set the default auto-hiberate idle timer value to 150 ms */ + if (ufshcd_is_auto_hibern8_supported(hba) && !hba->ahit) { +diff --git a/fs/afs/cell.c b/fs/afs/cell.c +index 926cb1188eba6c..7c0dce8eecadd1 100644 +--- a/fs/afs/cell.c ++++ b/fs/afs/cell.c +@@ -161,6 +161,7 @@ static struct afs_cell *afs_alloc_cell(struct afs_net *net, + refcount_set(&cell->ref, 1); + atomic_set(&cell->active, 0); + INIT_WORK(&cell->manager, afs_manage_cell_work); ++ spin_lock_init(&cell->vs_lock); + cell->volumes = RB_ROOT; + INIT_HLIST_HEAD(&cell->proc_volumes); + seqlock_init(&cell->volume_lock); +diff --git a/fs/afs/internal.h b/fs/afs/internal.h +index 2f135d19545b19..0973cd0a396959 100644 +--- a/fs/afs/internal.h ++++ b/fs/afs/internal.h +@@ -379,6 +379,7 @@ struct afs_cell { + unsigned int debug_id; + + /* The volumes belonging to this cell */ ++ spinlock_t vs_lock; /* Lock for server->volumes */ + struct rb_root volumes; /* Tree of volumes on this server */ + struct hlist_head proc_volumes; /* procfs volume list */ + seqlock_t volume_lock; /* For volumes */ +@@ -502,6 +503,7 @@ struct afs_server { + struct hlist_node addr4_link; /* Link in net->fs_addresses4 */ + struct hlist_node addr6_link; /* Link in net->fs_addresses6 */ + struct hlist_node proc_link; /* Link in net->fs_proc */ ++ struct list_head volumes; /* RCU list of afs_server_entry objects */ + struct work_struct initcb_work; /* Work for CB.InitCallBackState* */ + struct afs_server *gc_next; /* Next server in manager's list */ + time64_t unuse_time; /* Time at which last unused */ +@@ -550,12 +552,14 @@ struct afs_server { + */ + struct afs_server_entry { + struct afs_server *server; ++ struct afs_volume *volume; ++ struct list_head slink; /* Link in server->volumes */ + }; + + struct afs_server_list { + struct rcu_head rcu; +- afs_volid_t vids[AFS_MAXTYPES]; /* Volume IDs */ + refcount_t usage; ++ bool attached; /* T if attached to servers */ + unsigned char nr_servers; + unsigned char preferred; /* Preferred server */ + unsigned short vnovol_mask; /* Servers to be skipped due to VNOVOL */ +@@ -568,10 +572,9 @@ struct afs_server_list { + * Live AFS volume management. + */ + struct afs_volume { +- union { +- struct rcu_head rcu; +- afs_volid_t vid; /* volume ID */ +- }; ++ struct rcu_head rcu; ++ afs_volid_t vid; /* The volume ID of this volume */ ++ afs_volid_t vids[AFS_MAXTYPES]; /* All associated volume IDs */ + refcount_t ref; + time64_t update_at; /* Time at which to next update */ + struct afs_cell *cell; /* Cell to which belongs (pins ref) */ +@@ -1453,10 +1456,14 @@ static inline struct afs_server_list *afs_get_serverlist(struct afs_server_list + } + + extern void afs_put_serverlist(struct afs_net *, struct afs_server_list *); +-extern struct afs_server_list *afs_alloc_server_list(struct afs_cell *, struct key *, +- struct afs_vldb_entry *, +- u8); ++struct afs_server_list *afs_alloc_server_list(struct afs_volume *volume, ++ struct key *key, ++ struct afs_vldb_entry *vldb); + extern bool afs_annotate_server_list(struct afs_server_list *, struct afs_server_list *); ++void afs_attach_volume_to_servers(struct afs_volume *volume, struct afs_server_list *slist); ++void afs_reattach_volume_to_servers(struct afs_volume *volume, struct afs_server_list *slist, ++ struct afs_server_list *old); ++void afs_detach_volume_from_servers(struct afs_volume *volume, struct afs_server_list *slist); + + /* + * super.c +diff --git a/fs/afs/server.c b/fs/afs/server.c +index 0bd2f5ba6900c1..87381c2ffe374c 100644 +--- a/fs/afs/server.c ++++ b/fs/afs/server.c +@@ -236,6 +236,7 @@ static struct afs_server *afs_alloc_server(struct afs_cell *cell, + server->addr_version = alist->version; + server->uuid = *uuid; + rwlock_init(&server->fs_lock); ++ INIT_LIST_HEAD(&server->volumes); + INIT_WORK(&server->initcb_work, afs_server_init_callback_work); + init_waitqueue_head(&server->probe_wq); + INIT_LIST_HEAD(&server->probe_link); +diff --git a/fs/afs/server_list.c b/fs/afs/server_list.c +index b59896b1de0af2..89c75d934f79e1 100644 +--- a/fs/afs/server_list.c ++++ b/fs/afs/server_list.c +@@ -24,13 +24,13 @@ void afs_put_serverlist(struct afs_net *net, struct afs_server_list *slist) + /* + * Build a server list from a VLDB record. + */ +-struct afs_server_list *afs_alloc_server_list(struct afs_cell *cell, ++struct afs_server_list *afs_alloc_server_list(struct afs_volume *volume, + struct key *key, +- struct afs_vldb_entry *vldb, +- u8 type_mask) ++ struct afs_vldb_entry *vldb) + { + struct afs_server_list *slist; + struct afs_server *server; ++ unsigned int type_mask = 1 << volume->type; + int ret = -ENOMEM, nr_servers = 0, i, j; + + for (i = 0; i < vldb->nr_servers; i++) +@@ -44,15 +44,12 @@ struct afs_server_list *afs_alloc_server_list(struct afs_cell *cell, + refcount_set(&slist->usage, 1); + rwlock_init(&slist->lock); + +- for (i = 0; i < AFS_MAXTYPES; i++) +- slist->vids[i] = vldb->vid[i]; +- + /* Make sure a records exists for each server in the list. */ + for (i = 0; i < vldb->nr_servers; i++) { + if (!(vldb->fs_mask[i] & type_mask)) + continue; + +- server = afs_lookup_server(cell, key, &vldb->fs_server[i], ++ server = afs_lookup_server(volume->cell, key, &vldb->fs_server[i], + vldb->addr_version[i]); + if (IS_ERR(server)) { + ret = PTR_ERR(server); +@@ -70,8 +67,8 @@ struct afs_server_list *afs_alloc_server_list(struct afs_cell *cell, + break; + if (j < slist->nr_servers) { + if (slist->servers[j].server == server) { +- afs_put_server(cell->net, server, +- afs_server_trace_put_slist_isort); ++ afs_unuse_server(volume->cell->net, server, ++ afs_server_trace_put_slist_isort); + continue; + } + +@@ -81,6 +78,7 @@ struct afs_server_list *afs_alloc_server_list(struct afs_cell *cell, + } + + slist->servers[j].server = server; ++ slist->servers[j].volume = volume; + slist->nr_servers++; + } + +@@ -92,7 +90,7 @@ struct afs_server_list *afs_alloc_server_list(struct afs_cell *cell, + return slist; + + error_2: +- afs_put_serverlist(cell->net, slist); ++ afs_put_serverlist(volume->cell->net, slist); + error: + return ERR_PTR(ret); + } +@@ -127,3 +125,99 @@ bool afs_annotate_server_list(struct afs_server_list *new, + + return true; + } ++ ++/* ++ * Attach a volume to the servers it is going to use. ++ */ ++void afs_attach_volume_to_servers(struct afs_volume *volume, struct afs_server_list *slist) ++{ ++ struct afs_server_entry *se, *pe; ++ struct afs_server *server; ++ struct list_head *p; ++ unsigned int i; ++ ++ spin_lock(&volume->cell->vs_lock); ++ ++ for (i = 0; i < slist->nr_servers; i++) { ++ se = &slist->servers[i]; ++ server = se->server; ++ ++ list_for_each(p, &server->volumes) { ++ pe = list_entry(p, struct afs_server_entry, slink); ++ if (volume->vid <= pe->volume->vid) ++ break; ++ } ++ list_add_tail_rcu(&se->slink, p); ++ } ++ ++ slist->attached = true; ++ spin_unlock(&volume->cell->vs_lock); ++} ++ ++/* ++ * Reattach a volume to the servers it is going to use when server list is ++ * replaced. We try to switch the attachment points to avoid rewalking the ++ * lists. ++ */ ++void afs_reattach_volume_to_servers(struct afs_volume *volume, struct afs_server_list *new, ++ struct afs_server_list *old) ++{ ++ unsigned int n = 0, o = 0; ++ ++ spin_lock(&volume->cell->vs_lock); ++ ++ while (n < new->nr_servers || o < old->nr_servers) { ++ struct afs_server_entry *pn = n < new->nr_servers ? &new->servers[n] : NULL; ++ struct afs_server_entry *po = o < old->nr_servers ? &old->servers[o] : NULL; ++ struct afs_server_entry *s; ++ struct list_head *p; ++ int diff; ++ ++ if (pn && po && pn->server == po->server) { ++ list_replace_rcu(&po->slink, &pn->slink); ++ n++; ++ o++; ++ continue; ++ } ++ ++ if (pn && po) ++ diff = memcmp(&pn->server->uuid, &po->server->uuid, ++ sizeof(pn->server->uuid)); ++ else ++ diff = pn ? -1 : 1; ++ ++ if (diff < 0) { ++ list_for_each(p, &pn->server->volumes) { ++ s = list_entry(p, struct afs_server_entry, slink); ++ if (volume->vid <= s->volume->vid) ++ break; ++ } ++ list_add_tail_rcu(&pn->slink, p); ++ n++; ++ } else { ++ list_del_rcu(&po->slink); ++ o++; ++ } ++ } ++ ++ spin_unlock(&volume->cell->vs_lock); ++} ++ ++/* ++ * Detach a volume from the servers it has been using. ++ */ ++void afs_detach_volume_from_servers(struct afs_volume *volume, struct afs_server_list *slist) ++{ ++ unsigned int i; ++ ++ if (!slist->attached) ++ return; ++ ++ spin_lock(&volume->cell->vs_lock); ++ ++ for (i = 0; i < slist->nr_servers; i++) ++ list_del_rcu(&slist->servers[i].slink); ++ ++ slist->attached = false; ++ spin_unlock(&volume->cell->vs_lock); ++} +diff --git a/fs/afs/vl_alias.c b/fs/afs/vl_alias.c +index 83cf1bfbe343ae..b2cc10df95308c 100644 +--- a/fs/afs/vl_alias.c ++++ b/fs/afs/vl_alias.c +@@ -126,7 +126,7 @@ static int afs_compare_volume_slists(const struct afs_volume *vol_a, + lb = rcu_dereference(vol_b->servers); + + for (i = 0; i < AFS_MAXTYPES; i++) +- if (la->vids[i] != lb->vids[i]) ++ if (vol_a->vids[i] != vol_b->vids[i]) + return 0; + + while (a < la->nr_servers && b < lb->nr_servers) { +diff --git a/fs/afs/volume.c b/fs/afs/volume.c +index c028598a903c9c..0f64b97581272e 100644 +--- a/fs/afs/volume.c ++++ b/fs/afs/volume.c +@@ -72,11 +72,11 @@ static void afs_remove_volume_from_cell(struct afs_volume *volume) + */ + static struct afs_volume *afs_alloc_volume(struct afs_fs_context *params, + struct afs_vldb_entry *vldb, +- unsigned long type_mask) ++ struct afs_server_list **_slist) + { + struct afs_server_list *slist; + struct afs_volume *volume; +- int ret = -ENOMEM; ++ int ret = -ENOMEM, i; + + volume = kzalloc(sizeof(struct afs_volume), GFP_KERNEL); + if (!volume) +@@ -95,13 +95,16 @@ static struct afs_volume *afs_alloc_volume(struct afs_fs_context *params, + rwlock_init(&volume->cb_v_break_lock); + memcpy(volume->name, vldb->name, vldb->name_len + 1); + +- slist = afs_alloc_server_list(params->cell, params->key, vldb, type_mask); ++ for (i = 0; i < AFS_MAXTYPES; i++) ++ volume->vids[i] = vldb->vid[i]; ++ ++ slist = afs_alloc_server_list(volume, params->key, vldb); + if (IS_ERR(slist)) { + ret = PTR_ERR(slist); + goto error_1; + } + +- refcount_set(&slist->usage, 1); ++ *_slist = slist; + rcu_assign_pointer(volume->servers, slist); + trace_afs_volume(volume->vid, 1, afs_volume_trace_alloc); + return volume; +@@ -117,17 +120,19 @@ static struct afs_volume *afs_alloc_volume(struct afs_fs_context *params, + * Look up or allocate a volume record. + */ + static struct afs_volume *afs_lookup_volume(struct afs_fs_context *params, +- struct afs_vldb_entry *vldb, +- unsigned long type_mask) ++ struct afs_vldb_entry *vldb) + { ++ struct afs_server_list *slist; + struct afs_volume *candidate, *volume; + +- candidate = afs_alloc_volume(params, vldb, type_mask); ++ candidate = afs_alloc_volume(params, vldb, &slist); + if (IS_ERR(candidate)) + return candidate; + + volume = afs_insert_volume_into_cell(params->cell, candidate); +- if (volume != candidate) ++ if (volume == candidate) ++ afs_attach_volume_to_servers(volume, slist); ++ else + afs_put_volume(params->net, candidate, afs_volume_trace_put_cell_dup); + return volume; + } +@@ -208,8 +213,7 @@ struct afs_volume *afs_create_volume(struct afs_fs_context *params) + goto error; + } + +- type_mask = 1UL << params->type; +- volume = afs_lookup_volume(params, vldb, type_mask); ++ volume = afs_lookup_volume(params, vldb); + + error: + kfree(vldb); +@@ -221,14 +225,17 @@ struct afs_volume *afs_create_volume(struct afs_fs_context *params) + */ + static void afs_destroy_volume(struct afs_net *net, struct afs_volume *volume) + { ++ struct afs_server_list *slist = rcu_access_pointer(volume->servers); ++ + _enter("%p", volume); + + #ifdef CONFIG_AFS_FSCACHE + ASSERTCMP(volume->cache, ==, NULL); + #endif + ++ afs_detach_volume_from_servers(volume, slist); + afs_remove_volume_from_cell(volume); +- afs_put_serverlist(net, rcu_access_pointer(volume->servers)); ++ afs_put_serverlist(net, slist); + afs_put_cell(volume->cell, afs_cell_trace_put_vol); + trace_afs_volume(volume->vid, refcount_read(&volume->ref), + afs_volume_trace_free); +@@ -362,8 +369,7 @@ static int afs_update_volume_status(struct afs_volume *volume, struct key *key) + } + + /* See if the volume's server list got updated. */ +- new = afs_alloc_server_list(volume->cell, key, +- vldb, (1 << volume->type)); ++ new = afs_alloc_server_list(volume, key, vldb); + if (IS_ERR(new)) { + ret = PTR_ERR(new); + goto error_vldb; +@@ -384,9 +390,11 @@ static int afs_update_volume_status(struct afs_volume *volume, struct key *key) + + volume->update_at = ktime_get_real_seconds() + afs_volume_record_life; + write_unlock(&volume->servers_lock); +- ret = 0; + ++ if (discard == old) ++ afs_reattach_volume_to_servers(volume, new, old); + afs_put_serverlist(volume->cell->net, discard); ++ ret = 0; + error_vldb: + kfree(vldb); + error: +diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c +index 18e018cb181179..dbf7b3cd70ca5e 100644 +--- a/fs/overlayfs/copy_up.c ++++ b/fs/overlayfs/copy_up.c +@@ -570,7 +570,6 @@ static int ovl_link_up(struct ovl_copy_up_ctx *c) + err = PTR_ERR(upper); + if (!IS_ERR(upper)) { + err = ovl_do_link(ofs, ovl_dentry_upper(c->dentry), udir, upper); +- dput(upper); + + if (!err) { + /* Restore timestamps on parent (best effort) */ +@@ -578,6 +577,7 @@ static int ovl_link_up(struct ovl_copy_up_ctx *c) + ovl_dentry_set_upper_alias(c->dentry); + ovl_dentry_update_reval(c->dentry, upper); + } ++ dput(upper); + } + inode_unlock(udir); + if (err) +diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h +index 7e11ca6f86dcda..cf3f8b9bf43f08 100644 +--- a/include/asm-generic/vmlinux.lds.h ++++ b/include/asm-generic/vmlinux.lds.h +@@ -445,7 +445,7 @@ + . = ALIGN((align)); \ + .rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { \ + __start_rodata = .; \ +- *(.rodata) *(.rodata.*) \ ++ *(.rodata) *(.rodata.*) *(.data.rel.ro*) \ + SCHED_DATA \ + RO_AFTER_INIT_DATA /* Read only after init */ \ + . = ALIGN(8); \ +diff --git a/include/linux/rcuref.h b/include/linux/rcuref.h +index 2c8bfd0f1b6b3a..6322d8c1c6b429 100644 +--- a/include/linux/rcuref.h ++++ b/include/linux/rcuref.h +@@ -71,27 +71,30 @@ static inline __must_check bool rcuref_get(rcuref_t *ref) + return rcuref_get_slowpath(ref); + } + +-extern __must_check bool rcuref_put_slowpath(rcuref_t *ref); ++extern __must_check bool rcuref_put_slowpath(rcuref_t *ref, unsigned int cnt); + + /* + * Internal helper. Do not invoke directly. + */ + static __always_inline __must_check bool __rcuref_put(rcuref_t *ref) + { ++ int cnt; ++ + RCU_LOCKDEP_WARN(!rcu_read_lock_held() && preemptible(), + "suspicious rcuref_put_rcusafe() usage"); + /* + * Unconditionally decrease the reference count. The saturation and + * dead zones provide enough tolerance for this. + */ +- if (likely(!atomic_add_negative_release(-1, &ref->refcnt))) ++ cnt = atomic_sub_return_release(1, &ref->refcnt); ++ if (likely(cnt >= 0)) + return false; + + /* + * Handle the last reference drop and cases inside the saturation + * and dead zones. + */ +- return rcuref_put_slowpath(ref); ++ return rcuref_put_slowpath(ref, cnt); + } + + /** +diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h +index 8f9bee0e21c3bc..a220b28904ca52 100644 +--- a/include/linux/sunrpc/sched.h ++++ b/include/linux/sunrpc/sched.h +@@ -140,13 +140,14 @@ struct rpc_task_setup { + #define RPC_WAS_SENT(t) ((t)->tk_flags & RPC_TASK_SENT) + #define RPC_IS_MOVEABLE(t) ((t)->tk_flags & RPC_TASK_MOVEABLE) + +-#define RPC_TASK_RUNNING 0 +-#define RPC_TASK_QUEUED 1 +-#define RPC_TASK_ACTIVE 2 +-#define RPC_TASK_NEED_XMIT 3 +-#define RPC_TASK_NEED_RECV 4 +-#define RPC_TASK_MSG_PIN_WAIT 5 +-#define RPC_TASK_SIGNALLED 6 ++enum { ++ RPC_TASK_RUNNING, ++ RPC_TASK_QUEUED, ++ RPC_TASK_ACTIVE, ++ RPC_TASK_NEED_XMIT, ++ RPC_TASK_NEED_RECV, ++ RPC_TASK_MSG_PIN_WAIT, ++}; + + #define rpc_test_and_set_running(t) \ + test_and_set_bit(RPC_TASK_RUNNING, &(t)->tk_runstate) +@@ -158,7 +159,7 @@ struct rpc_task_setup { + + #define RPC_IS_ACTIVATED(t) test_bit(RPC_TASK_ACTIVE, &(t)->tk_runstate) + +-#define RPC_SIGNALLED(t) test_bit(RPC_TASK_SIGNALLED, &(t)->tk_runstate) ++#define RPC_SIGNALLED(t) (READ_ONCE(task->tk_rpc_status) == -ERESTARTSYS) + + /* + * Task priorities. +diff --git a/include/net/dst.h b/include/net/dst.h +index 78884429deed82..16b7b99b5f309c 100644 +--- a/include/net/dst.h ++++ b/include/net/dst.h +@@ -448,6 +448,15 @@ static inline void dst_set_expires(struct dst_entry *dst, int timeout) + dst->expires = expires; + } + ++static inline unsigned int dst_dev_overhead(struct dst_entry *dst, ++ struct sk_buff *skb) ++{ ++ if (likely(dst)) ++ return LL_RESERVED_SPACE(dst->dev); ++ ++ return skb->mac_len; ++} ++ + INDIRECT_CALLABLE_DECLARE(int ip6_output(struct net *, struct sock *, + struct sk_buff *)); + INDIRECT_CALLABLE_DECLARE(int ip_output(struct net *, struct sock *, +diff --git a/include/net/ip.h b/include/net/ip.h +index 7db5912e0c5f63..d8bf1f0a6919c4 100644 +--- a/include/net/ip.h ++++ b/include/net/ip.h +@@ -415,6 +415,11 @@ int ip_decrease_ttl(struct iphdr *iph) + return --iph->ttl; + } + ++static inline dscp_t ip4h_dscp(const struct iphdr *ip4h) ++{ ++ return inet_dsfield_to_dscp(ip4h->tos); ++} ++ + static inline int ip_mtu_locked(const struct dst_entry *dst) + { + const struct rtable *rt = (const struct rtable *)dst; +diff --git a/include/net/route.h b/include/net/route.h +index 0171e9e1bbea3d..27c17aff0bbe14 100644 +--- a/include/net/route.h ++++ b/include/net/route.h +@@ -200,12 +200,13 @@ int ip_route_use_hint(struct sk_buff *skb, __be32 dst, __be32 src, + const struct sk_buff *hint); + + static inline int ip_route_input(struct sk_buff *skb, __be32 dst, __be32 src, +- u8 tos, struct net_device *devin) ++ dscp_t dscp, struct net_device *devin) + { + int err; + + rcu_read_lock(); +- err = ip_route_input_noref(skb, dst, src, tos, devin); ++ err = ip_route_input_noref(skb, dst, src, inet_dscp_to_dsfield(dscp), ++ devin); + if (!err) { + skb_dst_force(skb); + if (!skb_dst(skb)) +diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h +index 62f9d126a71ad1..bc459d06162971 100644 +--- a/include/rdma/ib_verbs.h ++++ b/include/rdma/ib_verbs.h +@@ -561,6 +561,7 @@ enum ib_port_speed { + IB_SPEED_EDR = 32, + IB_SPEED_HDR = 64, + IB_SPEED_NDR = 128, ++ IB_SPEED_XDR = 256, + }; + + enum ib_stat_flag { +@@ -840,6 +841,7 @@ enum ib_rate { + IB_RATE_50_GBPS = 20, + IB_RATE_400_GBPS = 21, + IB_RATE_600_GBPS = 22, ++ IB_RATE_800_GBPS = 23, + }; + + /** +diff --git a/include/trace/events/icmp.h b/include/trace/events/icmp.h +new file mode 100644 +index 00000000000000..31559796949a78 +--- /dev/null ++++ b/include/trace/events/icmp.h +@@ -0,0 +1,67 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++#undef TRACE_SYSTEM ++#define TRACE_SYSTEM icmp ++ ++#if !defined(_TRACE_ICMP_H) || defined(TRACE_HEADER_MULTI_READ) ++#define _TRACE_ICMP_H ++ ++#include ++#include ++ ++TRACE_EVENT(icmp_send, ++ ++ TP_PROTO(const struct sk_buff *skb, int type, int code), ++ ++ TP_ARGS(skb, type, code), ++ ++ TP_STRUCT__entry( ++ __field(const void *, skbaddr) ++ __field(int, type) ++ __field(int, code) ++ __array(__u8, saddr, 4) ++ __array(__u8, daddr, 4) ++ __field(__u16, sport) ++ __field(__u16, dport) ++ __field(unsigned short, ulen) ++ ), ++ ++ TP_fast_assign( ++ struct iphdr *iph = ip_hdr(skb); ++ struct udphdr *uh = udp_hdr(skb); ++ int proto_4 = iph->protocol; ++ __be32 *p32; ++ ++ __entry->skbaddr = skb; ++ __entry->type = type; ++ __entry->code = code; ++ ++ if (proto_4 != IPPROTO_UDP || (u8 *)uh < skb->head || ++ (u8 *)uh + sizeof(struct udphdr) ++ > skb_tail_pointer(skb)) { ++ __entry->sport = 0; ++ __entry->dport = 0; ++ __entry->ulen = 0; ++ } else { ++ __entry->sport = ntohs(uh->source); ++ __entry->dport = ntohs(uh->dest); ++ __entry->ulen = ntohs(uh->len); ++ } ++ ++ p32 = (__be32 *) __entry->saddr; ++ *p32 = iph->saddr; ++ ++ p32 = (__be32 *) __entry->daddr; ++ *p32 = iph->daddr; ++ ), ++ ++ TP_printk("icmp_send: type=%d, code=%d. From %pI4:%u to %pI4:%u ulen=%d skbaddr=%p", ++ __entry->type, __entry->code, ++ __entry->saddr, __entry->sport, __entry->daddr, ++ __entry->dport, __entry->ulen, __entry->skbaddr) ++); ++ ++#endif /* _TRACE_ICMP_H */ ++ ++/* This part must be outside protection */ ++#include ++ +diff --git a/include/trace/events/sunrpc.h b/include/trace/events/sunrpc.h +index 6beb38c1dcb5eb..9eba2ca0a6ff80 100644 +--- a/include/trace/events/sunrpc.h ++++ b/include/trace/events/sunrpc.h +@@ -360,8 +360,7 @@ TRACE_EVENT(rpc_request, + { (1UL << RPC_TASK_ACTIVE), "ACTIVE" }, \ + { (1UL << RPC_TASK_NEED_XMIT), "NEED_XMIT" }, \ + { (1UL << RPC_TASK_NEED_RECV), "NEED_RECV" }, \ +- { (1UL << RPC_TASK_MSG_PIN_WAIT), "MSG_PIN_WAIT" }, \ +- { (1UL << RPC_TASK_SIGNALLED), "SIGNALLED" }) ++ { (1UL << RPC_TASK_MSG_PIN_WAIT), "MSG_PIN_WAIT" }) + + DECLARE_EVENT_CLASS(rpc_task_running, + +diff --git a/include/uapi/rdma/ib_user_ioctl_verbs.h b/include/uapi/rdma/ib_user_ioctl_verbs.h +index d7c5aaa3274453..fe15bc7e9f707b 100644 +--- a/include/uapi/rdma/ib_user_ioctl_verbs.h ++++ b/include/uapi/rdma/ib_user_ioctl_verbs.h +@@ -220,7 +220,8 @@ enum ib_uverbs_advise_mr_flag { + struct ib_uverbs_query_port_resp_ex { + struct ib_uverbs_query_port_resp legacy_resp; + __u16 port_cap_flags2; +- __u8 reserved[6]; ++ __u8 reserved[2]; ++ __u32 active_speed_ex; + }; + + struct ib_uverbs_qp_cap { +diff --git a/include/ufs/ufs.h b/include/ufs/ufs.h +index 49c90795a2a677..571a08ce912429 100644 +--- a/include/ufs/ufs.h ++++ b/include/ufs/ufs.h +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + + /* + * Using static_assert() is not allowed in UAPI header files. Hence the check +@@ -550,6 +551,14 @@ struct ufs_vreg_info { + struct ufs_vreg *vdd_hba; + }; + ++/* UFS device descriptor wPeriodicRTCUpdate bit9 defines RTC time baseline */ ++#define UFS_RTC_TIME_BASELINE BIT(9) ++ ++enum ufs_rtc_time { ++ UFS_RTC_RELATIVE, ++ UFS_RTC_ABSOLUTE ++}; ++ + struct ufs_dev_info { + bool f_power_on_wp_en; + /* Keeps information if any of the LU is power on write protected */ +@@ -577,6 +586,10 @@ struct ufs_dev_info { + + /* UFS EXT_IID Enable */ + bool b_ext_iid_en; ++ ++ /* UFS RTC */ ++ enum ufs_rtc_time rtc_type; ++ time64_t rtc_time_baseline; + }; + + /* +diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h +index 20d129914121d5..d5aa832f8dba3c 100644 +--- a/include/ufs/ufshcd.h ++++ b/include/ufs/ufshcd.h +@@ -908,6 +908,8 @@ enum ufshcd_mcq_opr { + * @mcq_base: Multi circular queue registers base address + * @uhq: array of supported hardware queues + * @dev_cmd_queue: Queue for issuing device management commands ++ * @mcq_opr: MCQ operation and runtime registers ++ * @ufs_rtc_update_work: A work for UFS RTC periodic update + */ + struct ufs_hba { + void __iomem *mmio_base; +@@ -1068,6 +1070,8 @@ struct ufs_hba { + struct ufs_hw_queue *uhq; + struct ufs_hw_queue *dev_cmd_queue; + struct ufshcd_mcq_opr_info_t mcq_opr[OPR_MAX]; ++ ++ struct delayed_work ufs_rtc_update_work; + }; + + /** +diff --git a/io_uring/net.c b/io_uring/net.c +index 56091292950fd6..1a0e98e19dc0ed 100644 +--- a/io_uring/net.c ++++ b/io_uring/net.c +@@ -303,7 +303,9 @@ static int io_sendmsg_copy_hdr(struct io_kiocb *req, + if (unlikely(ret)) + return ret; + +- return __get_compat_msghdr(&iomsg->msg, &cmsg, NULL); ++ ret = __get_compat_msghdr(&iomsg->msg, &cmsg, NULL); ++ sr->msg_control = iomsg->msg.msg_control_user; ++ return ret; + } + #endif + +diff --git a/kernel/events/core.c b/kernel/events/core.c +index 5d6458ea675e9d..4f6b18ecfdb219 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -4842,7 +4842,7 @@ static struct perf_event_pmu_context * + find_get_pmu_context(struct pmu *pmu, struct perf_event_context *ctx, + struct perf_event *event) + { +- struct perf_event_pmu_context *new = NULL, *epc; ++ struct perf_event_pmu_context *new = NULL, *pos = NULL, *epc; + void *task_ctx_data = NULL; + + if (!ctx->task) { +@@ -4899,12 +4899,19 @@ find_get_pmu_context(struct pmu *pmu, struct perf_event_context *ctx, + atomic_inc(&epc->refcount); + goto found_epc; + } ++ /* Make sure the pmu_ctx_list is sorted by PMU type: */ ++ if (!pos && epc->pmu->type > pmu->type) ++ pos = epc; + } + + epc = new; + new = NULL; + +- list_add(&epc->pmu_ctx_entry, &ctx->pmu_ctx_list); ++ if (!pos) ++ list_add_tail(&epc->pmu_ctx_entry, &ctx->pmu_ctx_list); ++ else ++ list_add(&epc->pmu_ctx_entry, pos->pmu_ctx_entry.prev); ++ + epc->ctx = ctx; + + found_epc: +@@ -5854,14 +5861,15 @@ static int _perf_event_period(struct perf_event *event, u64 value) + if (!value) + return -EINVAL; + +- if (event->attr.freq && value > sysctl_perf_event_sample_rate) +- return -EINVAL; +- +- if (perf_event_check_period(event, value)) +- return -EINVAL; +- +- if (!event->attr.freq && (value & (1ULL << 63))) +- return -EINVAL; ++ if (event->attr.freq) { ++ if (value > sysctl_perf_event_sample_rate) ++ return -EINVAL; ++ } else { ++ if (perf_event_check_period(event, value)) ++ return -EINVAL; ++ if (value & (1ULL << 63)) ++ return -EINVAL; ++ } + + event_function_call(event, __perf_event_period, &value); + +@@ -8106,7 +8114,8 @@ void perf_event_exec(void) + + perf_event_enable_on_exec(ctx); + perf_event_remove_on_exec(ctx); +- perf_iterate_ctx(ctx, perf_event_addr_filters_exec, NULL, true); ++ scoped_guard(rcu) ++ perf_iterate_ctx(ctx, perf_event_addr_filters_exec, NULL, true); + + perf_unpin_context(ctx); + put_ctx(ctx); +diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c +index 6dac0b5798213b..7e2edd1b069397 100644 +--- a/kernel/events/uprobes.c ++++ b/kernel/events/uprobes.c +@@ -481,6 +481,11 @@ int uprobe_write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm, + if (ret <= 0) + goto put_old; + ++ if (is_zero_page(old_page)) { ++ ret = -EINVAL; ++ goto put_old; ++ } ++ + if (WARN(!is_register && PageCompound(old_page), + "uprobe unregister should never work on compound page\n")) { + ret = -EINVAL; +diff --git a/kernel/sched/core.c b/kernel/sched/core.c +index c686d826a91cf5..784a4f8409453d 100644 +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -8561,7 +8561,7 @@ SYSCALL_DEFINE0(sched_yield) + #if !defined(CONFIG_PREEMPTION) || defined(CONFIG_PREEMPT_DYNAMIC) + int __sched __cond_resched(void) + { +- if (should_resched(0)) { ++ if (should_resched(0) && !irqs_disabled()) { + preempt_schedule_common(); + return 1; + } +diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c +index 6e6b2a5aa1402b..99fdeee3bcd87a 100644 +--- a/kernel/trace/ftrace.c ++++ b/kernel/trace/ftrace.c +@@ -538,6 +538,7 @@ static int function_stat_show(struct seq_file *m, void *v) + static struct trace_seq s; + unsigned long long avg; + unsigned long long stddev; ++ unsigned long long stddev_denom; + #endif + mutex_lock(&ftrace_profile_lock); + +@@ -559,23 +560,19 @@ static int function_stat_show(struct seq_file *m, void *v) + #ifdef CONFIG_FUNCTION_GRAPH_TRACER + seq_puts(m, " "); + +- /* Sample standard deviation (s^2) */ +- if (rec->counter <= 1) +- stddev = 0; +- else { +- /* +- * Apply Welford's method: +- * s^2 = 1 / (n * (n-1)) * (n * \Sum (x_i)^2 - (\Sum x_i)^2) +- */ ++ /* ++ * Variance formula: ++ * s^2 = 1 / (n * (n-1)) * (n * \Sum (x_i)^2 - (\Sum x_i)^2) ++ * Maybe Welford's method is better here? ++ * Divide only by 1000 for ns^2 -> us^2 conversion. ++ * trace_print_graph_duration will divide by 1000 again. ++ */ ++ stddev = 0; ++ stddev_denom = rec->counter * (rec->counter - 1) * 1000; ++ if (stddev_denom) { + stddev = rec->counter * rec->time_squared - + rec->time * rec->time; +- +- /* +- * Divide only 1000 for ns^2 -> us^2 conversion. +- * trace_print_graph_duration will divide 1000 again. +- */ +- stddev = div64_ul(stddev, +- rec->counter * (rec->counter - 1) * 1000); ++ stddev = div64_ul(stddev, stddev_denom); + } + + trace_seq_init(&s); +diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c +index dd16faf0d1500c..604d63380a90b1 100644 +--- a/kernel/trace/trace_events_hist.c ++++ b/kernel/trace/trace_events_hist.c +@@ -6660,27 +6660,27 @@ static int event_hist_trigger_parse(struct event_command *cmd_ops, + if (existing_hist_update_only(glob, trigger_data, file)) + goto out_free; + +- ret = event_trigger_register(cmd_ops, file, glob, trigger_data); +- if (ret < 0) +- goto out_free; ++ if (!get_named_trigger_data(trigger_data)) { + +- if (get_named_trigger_data(trigger_data)) +- goto enable; ++ ret = create_actions(hist_data); ++ if (ret) ++ goto out_free; + +- ret = create_actions(hist_data); +- if (ret) +- goto out_unreg; ++ if (has_hist_vars(hist_data) || hist_data->n_var_refs) { ++ ret = save_hist_vars(hist_data); ++ if (ret) ++ goto out_free; ++ } + +- if (has_hist_vars(hist_data) || hist_data->n_var_refs) { +- ret = save_hist_vars(hist_data); ++ ret = tracing_map_init(hist_data->map); + if (ret) +- goto out_unreg; ++ goto out_free; + } + +- ret = tracing_map_init(hist_data->map); +- if (ret) +- goto out_unreg; +-enable: ++ ret = event_trigger_register(cmd_ops, file, glob, trigger_data); ++ if (ret < 0) ++ goto out_free; ++ + ret = hist_trigger_enable(trigger_data, file); + if (ret) + goto out_unreg; +diff --git a/lib/rcuref.c b/lib/rcuref.c +index 5ec00a4a64d11c..185967b8508e86 100644 +--- a/lib/rcuref.c ++++ b/lib/rcuref.c +@@ -220,6 +220,7 @@ EXPORT_SYMBOL_GPL(rcuref_get_slowpath); + /** + * rcuref_put_slowpath - Slowpath of __rcuref_put() + * @ref: Pointer to the reference count ++ * @cnt: The resulting value of the fastpath decrement + * + * Invoked when the reference count is outside of the valid zone. + * +@@ -233,10 +234,8 @@ EXPORT_SYMBOL_GPL(rcuref_get_slowpath); + * with a concurrent get()/put() pair. Caller is not allowed to + * deconstruct the protected object. + */ +-bool rcuref_put_slowpath(rcuref_t *ref) ++bool rcuref_put_slowpath(rcuref_t *ref, unsigned int cnt) + { +- unsigned int cnt = atomic_read(&ref->refcnt); +- + /* Did this drop the last reference? */ + if (likely(cnt == RCUREF_NOREF)) { + /* +diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c +index acb148759bd049..304ebb31cebba6 100644 +--- a/net/bluetooth/l2cap_core.c ++++ b/net/bluetooth/l2cap_core.c +@@ -636,7 +636,8 @@ void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) + test_bit(FLAG_HOLD_HCI_CONN, &chan->flags)) + hci_conn_hold(conn->hcon); + +- list_add(&chan->list, &conn->chan_l); ++ /* Append to the list since the order matters for ECRED */ ++ list_add_tail(&chan->list, &conn->chan_l); + } + + void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) +@@ -3774,7 +3775,11 @@ static void l2cap_ecred_rsp_defer(struct l2cap_chan *chan, void *data) + { + struct l2cap_ecred_rsp_data *rsp = data; + +- if (test_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags)) ++ /* Check if channel for outgoing connection or if it wasn't deferred ++ * since in those cases it must be skipped. ++ */ ++ if (test_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags) || ++ !test_and_clear_bit(FLAG_DEFER_SETUP, &chan->flags)) + return; + + /* Reset ident so only one response is sent */ +diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c +index a1cfa75bbadb97..2a4958e995f2d9 100644 +--- a/net/bridge/br_netfilter_hooks.c ++++ b/net/bridge/br_netfilter_hooks.c +@@ -366,9 +366,9 @@ br_nf_ipv4_daddr_was_changed(const struct sk_buff *skb, + */ + static int br_nf_pre_routing_finish(struct net *net, struct sock *sk, struct sk_buff *skb) + { +- struct net_device *dev = skb->dev, *br_indev; +- struct iphdr *iph = ip_hdr(skb); + struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb); ++ struct net_device *dev = skb->dev, *br_indev; ++ const struct iphdr *iph = ip_hdr(skb); + struct rtable *rt; + int err; + +@@ -386,7 +386,9 @@ static int br_nf_pre_routing_finish(struct net *net, struct sock *sk, struct sk_ + } + nf_bridge->in_prerouting = 0; + if (br_nf_ipv4_daddr_was_changed(skb, nf_bridge)) { +- if ((err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))) { ++ err = ip_route_input(skb, iph->daddr, iph->saddr, ++ ip4h_dscp(iph), dev); ++ if (err) { + struct in_device *in_dev = __in_dev_get_rcu(dev); + + /* If err equals -EHOSTUNREACH the error is due to a +diff --git a/net/core/gro.c b/net/core/gro.c +index 85d3f686ba539b..397cf598425034 100644 +--- a/net/core/gro.c ++++ b/net/core/gro.c +@@ -627,6 +627,7 @@ static void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb) + skb->pkt_type = PACKET_HOST; + + skb->encapsulation = 0; ++ skb->ip_summed = CHECKSUM_NONE; + skb_shinfo(skb)->gso_type = 0; + skb_shinfo(skb)->gso_size = 0; + if (unlikely(skb->slow_gro)) { +diff --git a/net/core/skbuff.c b/net/core/skbuff.c +index f0a9ef1aeaa298..21a83e26f004bb 100644 +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -5867,11 +5867,11 @@ void skb_scrub_packet(struct sk_buff *skb, bool xnet) + skb->offload_fwd_mark = 0; + skb->offload_l3_fwd_mark = 0; + #endif ++ ipvs_reset(skb); + + if (!xnet) + return; + +- ipvs_reset(skb); + skb->mark = 0; + skb_clear_tstamp(skb); + } +diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c +index 0b15272dd2d35b..a7fa17b6a12978 100644 +--- a/net/core/sysctl_net_core.c ++++ b/net/core/sysctl_net_core.c +@@ -31,6 +31,7 @@ static int min_sndbuf = SOCK_MIN_SNDBUF; + static int min_rcvbuf = SOCK_MIN_RCVBUF; + static int max_skb_frags = MAX_SKB_FRAGS; + static int min_mem_pcpu_rsv = SK_MEMORY_PCPU_RESERVE; ++static int netdev_budget_usecs_min = 2 * USEC_PER_SEC / HZ; + + static int net_msg_warn; /* Unused, but still a sysctl */ + +@@ -613,7 +614,7 @@ static struct ctl_table net_core_table[] = { + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = proc_dointvec_minmax, +- .extra1 = SYSCTL_ZERO, ++ .extra1 = &netdev_budget_usecs_min, + }, + { + .procname = "fb_tunnels_only_for_init_net", +diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c +index a21d32b3ae6c36..94501bb30c431b 100644 +--- a/net/ipv4/icmp.c ++++ b/net/ipv4/icmp.c +@@ -93,6 +93,9 @@ + #include + #include + #include ++#include ++#define CREATE_TRACE_POINTS ++#include + + /* + * Build xmit assembly blocks +@@ -481,13 +484,11 @@ static struct net_device *icmp_get_route_lookup_dev(struct sk_buff *skb) + return route_lookup_dev; + } + +-static struct rtable *icmp_route_lookup(struct net *net, +- struct flowi4 *fl4, ++static struct rtable *icmp_route_lookup(struct net *net, struct flowi4 *fl4, + struct sk_buff *skb_in, +- const struct iphdr *iph, +- __be32 saddr, u8 tos, u32 mark, +- int type, int code, +- struct icmp_bxm *param) ++ const struct iphdr *iph, __be32 saddr, ++ dscp_t dscp, u32 mark, int type, ++ int code, struct icmp_bxm *param) + { + struct net_device *route_lookup_dev; + struct rtable *rt, *rt2; +@@ -500,7 +501,7 @@ static struct rtable *icmp_route_lookup(struct net *net, + fl4->saddr = saddr; + fl4->flowi4_mark = mark; + fl4->flowi4_uid = sock_net_uid(net, NULL); +- fl4->flowi4_tos = RT_TOS(tos); ++ fl4->flowi4_tos = inet_dscp_to_dsfield(dscp); + fl4->flowi4_proto = IPPROTO_ICMP; + fl4->fl4_icmp_type = type; + fl4->fl4_icmp_code = code; +@@ -548,7 +549,7 @@ static struct rtable *icmp_route_lookup(struct net *net, + orefdst = skb_in->_skb_refdst; /* save old refdst */ + skb_dst_set(skb_in, NULL); + err = ip_route_input(skb_in, fl4_dec.daddr, fl4_dec.saddr, +- RT_TOS(tos), rt2->dst.dev); ++ dscp, rt2->dst.dev); + + dst_release(&rt2->dst); + rt2 = skb_rtable(skb_in); +@@ -744,8 +745,9 @@ void __icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info, + ipc.opt = &icmp_param.replyopts.opt; + ipc.sockc.mark = mark; + +- rt = icmp_route_lookup(net, &fl4, skb_in, iph, saddr, tos, mark, +- type, code, &icmp_param); ++ rt = icmp_route_lookup(net, &fl4, skb_in, iph, saddr, ++ inet_dsfield_to_dscp(tos), mark, type, code, ++ &icmp_param); + if (IS_ERR(rt)) + goto out_unlock; + +@@ -778,6 +780,8 @@ void __icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info, + if (!fl4.saddr) + fl4.saddr = htonl(INADDR_DUMMY); + ++ trace_icmp_send(skb_in, type, code); ++ + icmp_push_reply(sk, &icmp_param, &fl4, &ipc, &rt); + ende: + ip_rt_put(rt); +diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c +index a9e22a098872fa..b4c59708fc0956 100644 +--- a/net/ipv4/ip_options.c ++++ b/net/ipv4/ip_options.c +@@ -617,7 +617,8 @@ int ip_options_rcv_srr(struct sk_buff *skb, struct net_device *dev) + + orefdst = skb->_skb_refdst; + skb_dst_set(skb, NULL); +- err = ip_route_input(skb, nexthop, iph->saddr, iph->tos, dev); ++ err = ip_route_input(skb, nexthop, iph->saddr, ip4h_dscp(iph), ++ dev); + rt2 = skb_rtable(skb); + if (err || (rt2->rt_type != RTN_UNICAST && rt2->rt_type != RTN_LOCAL)) { + skb_dst_drop(skb); +diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c +index cc2b608b1a8e78..ddb90b9057e756 100644 +--- a/net/ipv4/tcp_minisocks.c ++++ b/net/ipv4/tcp_minisocks.c +@@ -754,12 +754,6 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, + + /* In sequence, PAWS is OK. */ + +- /* TODO: We probably should defer ts_recent change once +- * we take ownership of @req. +- */ +- if (tmp_opt.saw_tstamp && !after(TCP_SKB_CB(skb)->seq, tcp_rsk(req)->rcv_nxt)) +- WRITE_ONCE(req->ts_recent, tmp_opt.rcv_tsval); +- + if (TCP_SKB_CB(skb)->seq == tcp_rsk(req)->rcv_isn) { + /* Truncate SYN, it is out of window starting + at tcp_rsk(req)->rcv_isn + 1. */ +@@ -808,6 +802,10 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, + if (!child) + goto listen_overflow; + ++ if (own_req && tmp_opt.saw_tstamp && ++ !after(TCP_SKB_CB(skb)->seq, tcp_rsk(req)->rcv_nxt)) ++ tcp_sk(child)->rx_opt.ts_recent = tmp_opt.rcv_tsval; ++ + if (own_req && rsk_drop_req(req)) { + reqsk_queue_removed(&inet_csk(req->rsk_listener)->icsk_accept_queue, req); + inet_csk_reqsk_queue_drop_and_put(req->rsk_listener, req); +diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c +index 97905d4174eca5..d645d022ce7745 100644 +--- a/net/ipv6/ip6_tunnel.c ++++ b/net/ipv6/ip6_tunnel.c +@@ -628,8 +628,8 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, + } + skb_dst_set(skb2, &rt->dst); + } else { +- if (ip_route_input(skb2, eiph->daddr, eiph->saddr, eiph->tos, +- skb2->dev) || ++ if (ip_route_input(skb2, eiph->daddr, eiph->saddr, ++ ip4h_dscp(eiph), skb2->dev) || + skb_dst(skb2)->dev->type != ARPHRD_TUNNEL6) + goto out; + } +diff --git a/net/ipv6/rpl_iptunnel.c b/net/ipv6/rpl_iptunnel.c +index db3c19a42e1ca7..28fc7fae579723 100644 +--- a/net/ipv6/rpl_iptunnel.c ++++ b/net/ipv6/rpl_iptunnel.c +@@ -125,7 +125,8 @@ static void rpl_destroy_state(struct lwtunnel_state *lwt) + } + + static int rpl_do_srh_inline(struct sk_buff *skb, const struct rpl_lwt *rlwt, +- const struct ipv6_rpl_sr_hdr *srh) ++ const struct ipv6_rpl_sr_hdr *srh, ++ struct dst_entry *cache_dst) + { + struct ipv6_rpl_sr_hdr *isrh, *csrh; + const struct ipv6hdr *oldhdr; +@@ -153,7 +154,7 @@ static int rpl_do_srh_inline(struct sk_buff *skb, const struct rpl_lwt *rlwt, + + hdrlen = ((csrh->hdrlen + 1) << 3); + +- err = skb_cow_head(skb, hdrlen + skb->mac_len); ++ err = skb_cow_head(skb, hdrlen + dst_dev_overhead(cache_dst, skb)); + if (unlikely(err)) { + kfree(buf); + return err; +@@ -186,7 +187,8 @@ static int rpl_do_srh_inline(struct sk_buff *skb, const struct rpl_lwt *rlwt, + return 0; + } + +-static int rpl_do_srh(struct sk_buff *skb, const struct rpl_lwt *rlwt) ++static int rpl_do_srh(struct sk_buff *skb, const struct rpl_lwt *rlwt, ++ struct dst_entry *cache_dst) + { + struct dst_entry *dst = skb_dst(skb); + struct rpl_iptunnel_encap *tinfo; +@@ -196,7 +198,7 @@ static int rpl_do_srh(struct sk_buff *skb, const struct rpl_lwt *rlwt) + + tinfo = rpl_encap_lwtunnel(dst->lwtstate); + +- return rpl_do_srh_inline(skb, rlwt, tinfo->srh); ++ return rpl_do_srh_inline(skb, rlwt, tinfo->srh, cache_dst); + } + + static int rpl_output(struct net *net, struct sock *sk, struct sk_buff *skb) +@@ -208,14 +210,14 @@ static int rpl_output(struct net *net, struct sock *sk, struct sk_buff *skb) + + rlwt = rpl_lwt_lwtunnel(orig_dst->lwtstate); + +- err = rpl_do_srh(skb, rlwt); +- if (unlikely(err)) +- goto drop; +- + local_bh_disable(); + dst = dst_cache_get(&rlwt->cache); + local_bh_enable(); + ++ err = rpl_do_srh(skb, rlwt, dst); ++ if (unlikely(err)) ++ goto drop; ++ + if (unlikely(!dst)) { + struct ipv6hdr *hdr = ipv6_hdr(skb); + struct flowi6 fl6; +@@ -237,15 +239,15 @@ static int rpl_output(struct net *net, struct sock *sk, struct sk_buff *skb) + local_bh_disable(); + dst_cache_set_ip6(&rlwt->cache, dst, &fl6.saddr); + local_bh_enable(); ++ ++ err = skb_cow_head(skb, LL_RESERVED_SPACE(dst->dev)); ++ if (unlikely(err)) ++ goto drop; + } + + skb_dst_drop(skb); + skb_dst_set(skb, dst); + +- err = skb_cow_head(skb, LL_RESERVED_SPACE(dst->dev)); +- if (unlikely(err)) +- goto drop; +- + return dst_output(net, sk, skb); + + drop: +@@ -257,34 +259,46 @@ static int rpl_input(struct sk_buff *skb) + { + struct dst_entry *orig_dst = skb_dst(skb); + struct dst_entry *dst = NULL; ++ struct lwtunnel_state *lwtst; + struct rpl_lwt *rlwt; + int err; + +- rlwt = rpl_lwt_lwtunnel(orig_dst->lwtstate); ++ /* We cannot dereference "orig_dst" once ip6_route_input() or ++ * skb_dst_drop() is called. However, in order to detect a dst loop, we ++ * need the address of its lwtstate. So, save the address of lwtstate ++ * now and use it later as a comparison. ++ */ ++ lwtst = orig_dst->lwtstate; + +- err = rpl_do_srh(skb, rlwt); +- if (unlikely(err)) +- goto drop; ++ rlwt = rpl_lwt_lwtunnel(lwtst); + + local_bh_disable(); + dst = dst_cache_get(&rlwt->cache); ++ local_bh_enable(); ++ ++ err = rpl_do_srh(skb, rlwt, dst); ++ if (unlikely(err)) ++ goto drop; + + if (!dst) { + ip6_route_input(skb); + dst = skb_dst(skb); +- if (!dst->error) { ++ ++ /* cache only if we don't create a dst reference loop */ ++ if (!dst->error && lwtst != dst->lwtstate) { ++ local_bh_disable(); + dst_cache_set_ip6(&rlwt->cache, dst, + &ipv6_hdr(skb)->saddr); ++ local_bh_enable(); + } ++ ++ err = skb_cow_head(skb, LL_RESERVED_SPACE(dst->dev)); ++ if (unlikely(err)) ++ goto drop; + } else { + skb_dst_drop(skb); + skb_dst_set(skb, dst); + } +- local_bh_enable(); +- +- err = skb_cow_head(skb, LL_RESERVED_SPACE(dst->dev)); +- if (unlikely(err)) +- goto drop; + + return dst_input(skb); + +diff --git a/net/ipv6/seg6_iptunnel.c b/net/ipv6/seg6_iptunnel.c +index 098632adc9b5af..c44e4c0824e0d8 100644 +--- a/net/ipv6/seg6_iptunnel.c ++++ b/net/ipv6/seg6_iptunnel.c +@@ -124,8 +124,8 @@ static __be32 seg6_make_flowlabel(struct net *net, struct sk_buff *skb, + return flowlabel; + } + +-/* encapsulate an IPv6 packet within an outer IPv6 header with a given SRH */ +-int seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh, int proto) ++static int __seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh, ++ int proto, struct dst_entry *cache_dst) + { + struct dst_entry *dst = skb_dst(skb); + struct net *net = dev_net(dst->dev); +@@ -137,7 +137,7 @@ int seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh, int proto) + hdrlen = (osrh->hdrlen + 1) << 3; + tot_len = hdrlen + sizeof(*hdr); + +- err = skb_cow_head(skb, tot_len + skb->mac_len); ++ err = skb_cow_head(skb, tot_len + dst_dev_overhead(cache_dst, skb)); + if (unlikely(err)) + return err; + +@@ -197,11 +197,18 @@ int seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh, int proto) + + return 0; + } ++ ++/* encapsulate an IPv6 packet within an outer IPv6 header with a given SRH */ ++int seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh, int proto) ++{ ++ return __seg6_do_srh_encap(skb, osrh, proto, NULL); ++} + EXPORT_SYMBOL_GPL(seg6_do_srh_encap); + + /* encapsulate an IPv6 packet within an outer IPv6 header with reduced SRH */ + static int seg6_do_srh_encap_red(struct sk_buff *skb, +- struct ipv6_sr_hdr *osrh, int proto) ++ struct ipv6_sr_hdr *osrh, int proto, ++ struct dst_entry *cache_dst) + { + __u8 first_seg = osrh->first_segment; + struct dst_entry *dst = skb_dst(skb); +@@ -230,7 +237,7 @@ static int seg6_do_srh_encap_red(struct sk_buff *skb, + + tot_len = red_hdrlen + sizeof(struct ipv6hdr); + +- err = skb_cow_head(skb, tot_len + skb->mac_len); ++ err = skb_cow_head(skb, tot_len + dst_dev_overhead(cache_dst, skb)); + if (unlikely(err)) + return err; + +@@ -317,8 +324,8 @@ static int seg6_do_srh_encap_red(struct sk_buff *skb, + return 0; + } + +-/* insert an SRH within an IPv6 packet, just after the IPv6 header */ +-int seg6_do_srh_inline(struct sk_buff *skb, struct ipv6_sr_hdr *osrh) ++static int __seg6_do_srh_inline(struct sk_buff *skb, struct ipv6_sr_hdr *osrh, ++ struct dst_entry *cache_dst) + { + struct ipv6hdr *hdr, *oldhdr; + struct ipv6_sr_hdr *isrh; +@@ -326,7 +333,7 @@ int seg6_do_srh_inline(struct sk_buff *skb, struct ipv6_sr_hdr *osrh) + + hdrlen = (osrh->hdrlen + 1) << 3; + +- err = skb_cow_head(skb, hdrlen + skb->mac_len); ++ err = skb_cow_head(skb, hdrlen + dst_dev_overhead(cache_dst, skb)); + if (unlikely(err)) + return err; + +@@ -369,9 +376,8 @@ int seg6_do_srh_inline(struct sk_buff *skb, struct ipv6_sr_hdr *osrh) + + return 0; + } +-EXPORT_SYMBOL_GPL(seg6_do_srh_inline); + +-static int seg6_do_srh(struct sk_buff *skb) ++static int seg6_do_srh(struct sk_buff *skb, struct dst_entry *cache_dst) + { + struct dst_entry *dst = skb_dst(skb); + struct seg6_iptunnel_encap *tinfo; +@@ -384,7 +390,7 @@ static int seg6_do_srh(struct sk_buff *skb) + if (skb->protocol != htons(ETH_P_IPV6)) + return -EINVAL; + +- err = seg6_do_srh_inline(skb, tinfo->srh); ++ err = __seg6_do_srh_inline(skb, tinfo->srh, cache_dst); + if (err) + return err; + break; +@@ -402,9 +408,11 @@ static int seg6_do_srh(struct sk_buff *skb) + return -EINVAL; + + if (tinfo->mode == SEG6_IPTUN_MODE_ENCAP) +- err = seg6_do_srh_encap(skb, tinfo->srh, proto); ++ err = __seg6_do_srh_encap(skb, tinfo->srh, ++ proto, cache_dst); + else +- err = seg6_do_srh_encap_red(skb, tinfo->srh, proto); ++ err = seg6_do_srh_encap_red(skb, tinfo->srh, ++ proto, cache_dst); + + if (err) + return err; +@@ -425,11 +433,13 @@ static int seg6_do_srh(struct sk_buff *skb) + skb_push(skb, skb->mac_len); + + if (tinfo->mode == SEG6_IPTUN_MODE_L2ENCAP) +- err = seg6_do_srh_encap(skb, tinfo->srh, +- IPPROTO_ETHERNET); ++ err = __seg6_do_srh_encap(skb, tinfo->srh, ++ IPPROTO_ETHERNET, ++ cache_dst); + else + err = seg6_do_srh_encap_red(skb, tinfo->srh, +- IPPROTO_ETHERNET); ++ IPPROTO_ETHERNET, ++ cache_dst); + + if (err) + return err; +@@ -444,6 +454,13 @@ static int seg6_do_srh(struct sk_buff *skb) + return 0; + } + ++/* insert an SRH within an IPv6 packet, just after the IPv6 header */ ++int seg6_do_srh_inline(struct sk_buff *skb, struct ipv6_sr_hdr *osrh) ++{ ++ return __seg6_do_srh_inline(skb, osrh, NULL); ++} ++EXPORT_SYMBOL_GPL(seg6_do_srh_inline); ++ + static int seg6_input_finish(struct net *net, struct sock *sk, + struct sk_buff *skb) + { +@@ -455,34 +472,46 @@ static int seg6_input_core(struct net *net, struct sock *sk, + { + struct dst_entry *orig_dst = skb_dst(skb); + struct dst_entry *dst = NULL; ++ struct lwtunnel_state *lwtst; + struct seg6_lwt *slwt; + int err; + +- err = seg6_do_srh(skb); +- if (unlikely(err)) +- goto drop; ++ /* We cannot dereference "orig_dst" once ip6_route_input() or ++ * skb_dst_drop() is called. However, in order to detect a dst loop, we ++ * need the address of its lwtstate. So, save the address of lwtstate ++ * now and use it later as a comparison. ++ */ ++ lwtst = orig_dst->lwtstate; + +- slwt = seg6_lwt_lwtunnel(orig_dst->lwtstate); ++ slwt = seg6_lwt_lwtunnel(lwtst); + + local_bh_disable(); + dst = dst_cache_get(&slwt->cache); ++ local_bh_enable(); ++ ++ err = seg6_do_srh(skb, dst); ++ if (unlikely(err)) ++ goto drop; + + if (!dst) { + ip6_route_input(skb); + dst = skb_dst(skb); +- if (!dst->error) { ++ ++ /* cache only if we don't create a dst reference loop */ ++ if (!dst->error && lwtst != dst->lwtstate) { ++ local_bh_disable(); + dst_cache_set_ip6(&slwt->cache, dst, + &ipv6_hdr(skb)->saddr); ++ local_bh_enable(); + } ++ ++ err = skb_cow_head(skb, LL_RESERVED_SPACE(dst->dev)); ++ if (unlikely(err)) ++ goto drop; + } else { + skb_dst_drop(skb); + skb_dst_set(skb, dst); + } +- local_bh_enable(); +- +- err = skb_cow_head(skb, LL_RESERVED_SPACE(dst->dev)); +- if (unlikely(err)) +- goto drop; + + if (static_branch_unlikely(&nf_hooks_lwtunnel_enabled)) + return NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, +@@ -528,16 +557,16 @@ static int seg6_output_core(struct net *net, struct sock *sk, + struct seg6_lwt *slwt; + int err; + +- err = seg6_do_srh(skb); +- if (unlikely(err)) +- goto drop; +- + slwt = seg6_lwt_lwtunnel(orig_dst->lwtstate); + + local_bh_disable(); + dst = dst_cache_get(&slwt->cache); + local_bh_enable(); + ++ err = seg6_do_srh(skb, dst); ++ if (unlikely(err)) ++ goto drop; ++ + if (unlikely(!dst)) { + struct ipv6hdr *hdr = ipv6_hdr(skb); + struct flowi6 fl6; +@@ -559,15 +588,15 @@ static int seg6_output_core(struct net *net, struct sock *sk, + local_bh_disable(); + dst_cache_set_ip6(&slwt->cache, dst, &fl6.saddr); + local_bh_enable(); ++ ++ err = skb_cow_head(skb, LL_RESERVED_SPACE(dst->dev)); ++ if (unlikely(err)) ++ goto drop; + } + + skb_dst_drop(skb); + skb_dst_set(skb, dst); + +- err = skb_cow_head(skb, LL_RESERVED_SPACE(dst->dev)); +- if (unlikely(err)) +- goto drop; +- + if (static_branch_unlikely(&nf_hooks_lwtunnel_enabled)) + return NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, net, sk, skb, + NULL, skb_dst(skb)->dev, dst_output); +diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c +index 2b63c5492eedc2..5f16e2fa2de67a 100644 +--- a/net/mptcp/pm_netlink.c ++++ b/net/mptcp/pm_netlink.c +@@ -1559,11 +1559,6 @@ static int mptcp_nl_remove_subflow_and_signal_addr(struct net *net, + if (mptcp_pm_is_userspace(msk)) + goto next; + +- if (list_empty(&msk->conn_list)) { +- mptcp_pm_remove_anno_addr(msk, addr, false); +- goto next; +- } +- + lock_sock(sk); + remove_subflow = lookup_subflow_by_saddr(&msk->conn_list, addr); + mptcp_pm_remove_anno_addr(msk, addr, remove_subflow && +diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c +index 282ecc8bf75e80..b3eeeb948b6132 100644 +--- a/net/mptcp/subflow.c ++++ b/net/mptcp/subflow.c +@@ -1109,7 +1109,6 @@ static enum mapping_status get_mapping_status(struct sock *ssk, + if (data_len == 0) { + pr_debug("infinite mapping received\n"); + MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_INFINITEMAPRX); +- subflow->map_data_len = 0; + return MAPPING_INVALID; + } + +@@ -1251,18 +1250,6 @@ static void subflow_sched_work_if_closed(struct mptcp_sock *msk, struct sock *ss + mptcp_schedule_work(sk); + } + +-static bool subflow_can_fallback(struct mptcp_subflow_context *subflow) +-{ +- struct mptcp_sock *msk = mptcp_sk(subflow->conn); +- +- if (subflow->mp_join) +- return false; +- else if (READ_ONCE(msk->csum_enabled)) +- return !subflow->valid_csum_seen; +- else +- return READ_ONCE(msk->allow_infinite_fallback); +-} +- + static void mptcp_subflow_fail(struct mptcp_sock *msk, struct sock *ssk) + { + struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk); +@@ -1358,7 +1345,7 @@ static bool subflow_check_data_avail(struct sock *ssk) + return true; + } + +- if (!subflow_can_fallback(subflow) && subflow->map_data_len) { ++ if (!READ_ONCE(msk->allow_infinite_fallback)) { + /* fatal protocol error, close the socket. + * subflow_error_report() will introduce the appropriate barriers + */ +diff --git a/net/rxrpc/rxperf.c b/net/rxrpc/rxperf.c +index 085e7892d31040..b1536da2246b82 100644 +--- a/net/rxrpc/rxperf.c ++++ b/net/rxrpc/rxperf.c +@@ -478,6 +478,18 @@ static int rxperf_deliver_request(struct rxperf_call *call) + call->unmarshal++; + fallthrough; + case 2: ++ ret = rxperf_extract_data(call, true); ++ if (ret < 0) ++ return ret; ++ ++ /* Deal with the terminal magic cookie. */ ++ call->iov_len = 4; ++ call->kvec[0].iov_len = call->iov_len; ++ call->kvec[0].iov_base = call->tmp; ++ iov_iter_kvec(&call->iter, READ, call->kvec, 1, call->iov_len); ++ call->unmarshal++; ++ fallthrough; ++ case 3: + ret = rxperf_extract_data(call, false); + if (ret < 0) + return ret; +diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c +index 3298da2e37e43d..cb6a6bc9fea77d 100644 +--- a/net/sunrpc/cache.c ++++ b/net/sunrpc/cache.c +@@ -1675,12 +1675,14 @@ static void remove_cache_proc_entries(struct cache_detail *cd) + } + } + +-#ifdef CONFIG_PROC_FS + static int create_cache_proc_entries(struct cache_detail *cd, struct net *net) + { + struct proc_dir_entry *p; + struct sunrpc_net *sn; + ++ if (!IS_ENABLED(CONFIG_PROC_FS)) ++ return 0; ++ + sn = net_generic(net, sunrpc_net_id); + cd->procfs = proc_mkdir(cd->name, sn->proc_net_rpc); + if (cd->procfs == NULL) +@@ -1708,12 +1710,6 @@ static int create_cache_proc_entries(struct cache_detail *cd, struct net *net) + remove_cache_proc_entries(cd); + return -ENOMEM; + } +-#else /* CONFIG_PROC_FS */ +-static int create_cache_proc_entries(struct cache_detail *cd, struct net *net) +-{ +- return 0; +-} +-#endif + + void __init cache_initialize(void) + { +diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c +index cef623ea150609..9b45fbdc90cabe 100644 +--- a/net/sunrpc/sched.c ++++ b/net/sunrpc/sched.c +@@ -864,8 +864,6 @@ void rpc_signal_task(struct rpc_task *task) + if (!rpc_task_set_rpc_status(task, -ERESTARTSYS)) + return; + trace_rpc_task_signalled(task, task->tk_action); +- set_bit(RPC_TASK_SIGNALLED, &task->tk_runstate); +- smp_mb__after_atomic(); + queue = READ_ONCE(task->tk_waitqueue); + if (queue) + rpc_wake_up_queued_task(queue, task); +diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c +index 1c4bc8234ea875..29df05879c8e95 100644 +--- a/net/sunrpc/xprtsock.c ++++ b/net/sunrpc/xprtsock.c +@@ -2561,7 +2561,15 @@ static void xs_tls_handshake_done(void *data, int status, key_serial_t peerid) + struct sock_xprt *lower_transport = + container_of(lower_xprt, struct sock_xprt, xprt); + +- lower_transport->xprt_err = status ? -EACCES : 0; ++ switch (status) { ++ case 0: ++ case -EACCES: ++ case -ETIMEDOUT: ++ lower_transport->xprt_err = status; ++ break; ++ default: ++ lower_transport->xprt_err = -EACCES; ++ } + complete(&lower_transport->handshake_done); + xprt_put(lower_xprt); + } +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 75162e5f712b40..822bd9a00892c3 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -10084,23 +10084,27 @@ static const struct hda_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1043, 0x1313, "Asus K42JZ", ALC269VB_FIXUP_ASUS_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC), + SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK), +- SND_PCI_QUIRK(0x1043, 0x1433, "ASUS GX650P", ALC285_FIXUP_ASUS_I2C_HEADSET_MIC), +- SND_PCI_QUIRK(0x1043, 0x1463, "Asus GA402X", ALC285_FIXUP_ASUS_I2C_HEADSET_MIC), +- SND_PCI_QUIRK(0x1043, 0x1473, "ASUS GU604V", ALC285_FIXUP_ASUS_HEADSET_MIC), +- SND_PCI_QUIRK(0x1043, 0x1483, "ASUS GU603V", ALC285_FIXUP_ASUS_HEADSET_MIC), +- SND_PCI_QUIRK(0x1043, 0x1493, "ASUS GV601V", ALC285_FIXUP_ASUS_HEADSET_MIC), ++ SND_PCI_QUIRK(0x1043, 0x1433, "ASUS GX650PY/PZ/PV/PU/PYV/PZV/PIV/PVV", ALC285_FIXUP_ASUS_I2C_HEADSET_MIC), ++ SND_PCI_QUIRK(0x1043, 0x1460, "Asus VivoBook 15", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE), ++ SND_PCI_QUIRK(0x1043, 0x1463, "Asus GA402X/GA402N", ALC285_FIXUP_ASUS_I2C_HEADSET_MIC), ++ SND_PCI_QUIRK(0x1043, 0x1473, "ASUS GU604VI/VC/VE/VG/VJ/VQ/VU/VV/VY/VZ", ALC285_FIXUP_ASUS_HEADSET_MIC), ++ SND_PCI_QUIRK(0x1043, 0x1483, "ASUS GU603VQ/VU/VV/VJ/VI", ALC285_FIXUP_ASUS_HEADSET_MIC), ++ SND_PCI_QUIRK(0x1043, 0x1493, "ASUS GV601VV/VU/VJ/VQ/VI", ALC285_FIXUP_ASUS_HEADSET_MIC), ++ SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G614JY/JZ/JG", ALC245_FIXUP_CS35L41_SPI_2), ++ SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS G513PI/PU/PV", ALC287_FIXUP_CS35L41_I2C_2), ++ SND_PCI_QUIRK(0x1043, 0x1503, "ASUS G733PY/PZ/PZV/PYV", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A), +- SND_PCI_QUIRK(0x1043, 0x1533, "ASUS GV302XA", ALC287_FIXUP_CS35L41_I2C_2), +- SND_PCI_QUIRK(0x1043, 0x1573, "ASUS GZ301V", ALC285_FIXUP_ASUS_HEADSET_MIC), ++ SND_PCI_QUIRK(0x1043, 0x1533, "ASUS GV302XA/XJ/XQ/XU/XV/XI", ALC287_FIXUP_CS35L41_I2C_2), ++ SND_PCI_QUIRK(0x1043, 0x1573, "ASUS GZ301VV/VQ/VU/VJ/VA/VC/VE/VVC/VQC/VUC/VJC/VEC/VCC", ALC285_FIXUP_ASUS_HEADSET_MIC), + SND_PCI_QUIRK(0x1043, 0x1662, "ASUS GV301QH", ALC294_FIXUP_ASUS_DUAL_SPK), +- SND_PCI_QUIRK(0x1043, 0x1663, "ASUS GU603ZV", ALC285_FIXUP_ASUS_HEADSET_MIC), ++ SND_PCI_QUIRK(0x1043, 0x1663, "ASUS GU603ZI/ZJ/ZQ/ZU/ZV", ALC285_FIXUP_ASUS_HEADSET_MIC), + SND_PCI_QUIRK(0x1043, 0x1683, "ASUS UM3402YAR", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS UX3402VA", ALC245_FIXUP_CS35L41_SPI_2), + SND_PCI_QUIRK(0x1043, 0x16b2, "ASUS GU603", ALC289_FIXUP_ASUS_GA401), + SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), + SND_PCI_QUIRK(0x1043, 0x1740, "ASUS UX430UA", ALC295_FIXUP_ASUS_DACS), + SND_PCI_QUIRK(0x1043, 0x17d1, "ASUS UX431FL", ALC294_FIXUP_ASUS_DUAL_SPK), +- SND_PCI_QUIRK(0x1043, 0x17f3, "ROG Ally RC71L_RC71L", ALC294_FIXUP_ASUS_ALLY), ++ SND_PCI_QUIRK(0x1043, 0x17f3, "ROG Ally NR2301L/X", ALC294_FIXUP_ASUS_ALLY), + SND_PCI_QUIRK(0x1043, 0x1881, "ASUS Zephyrus S/M", ALC294_FIXUP_ASUS_GX502_PINS), + SND_PCI_QUIRK(0x1043, 0x18b1, "Asus MJ401TA", ALC256_FIXUP_ASUS_HEADSET_MIC), + SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS UM3504DA", ALC294_FIXUP_CS35L41_I2C_2), +@@ -10111,7 +10115,6 @@ static const struct hda_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1043, 0x19ce, "ASUS B9450FA", ALC294_FIXUP_ASUS_HPE), + SND_PCI_QUIRK(0x1043, 0x19e1, "ASUS UX581LV", ALC295_FIXUP_ASUS_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), +- SND_PCI_QUIRK(0x1043, 0x1a30, "ASUS X705UD", ALC256_FIXUP_ASUS_MIC), + SND_PCI_QUIRK(0x1043, 0x1a63, "ASUS UX3405MA", ALC245_FIXUP_CS35L41_SPI_2), + SND_PCI_QUIRK(0x1043, 0x1a83, "ASUS UM5302LA", ALC294_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x1043, 0x1a8f, "ASUS UX582ZS", ALC245_FIXUP_CS35L41_SPI_2), +@@ -10125,10 +10128,13 @@ static const struct hda_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1043, 0x1c43, "ASUS UX8406MA", ALC245_FIXUP_CS35L41_SPI_2), + SND_PCI_QUIRK(0x1043, 0x1c62, "ASUS GU603", ALC289_FIXUP_ASUS_GA401), + SND_PCI_QUIRK(0x1043, 0x1c92, "ASUS ROG Strix G15", ALC285_FIXUP_ASUS_G533Z_PINS), +- SND_PCI_QUIRK(0x1043, 0x1c9f, "ASUS G614JI", ALC285_FIXUP_ASUS_HEADSET_MIC), +- SND_PCI_QUIRK(0x1043, 0x1caf, "ASUS G634JYR/JZR", ALC285_FIXUP_ASUS_SPI_REAR_SPEAKERS), ++ SND_PCI_QUIRK(0x1043, 0x1c9f, "ASUS G614JU/JV/JI", ALC285_FIXUP_ASUS_HEADSET_MIC), ++ SND_PCI_QUIRK(0x1043, 0x1caf, "ASUS G634JY/JZ/JI/JG", ALC285_FIXUP_ASUS_SPI_REAR_SPEAKERS), + SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC), +- SND_PCI_QUIRK(0x1043, 0x1d1f, "ASUS ROG Strix G17 2023 (G713PV)", ALC287_FIXUP_CS35L41_I2C_2), ++ SND_PCI_QUIRK(0x1043, 0x1ccf, "ASUS G814JU/JV/JI", ALC245_FIXUP_CS35L41_SPI_2), ++ SND_PCI_QUIRK(0x1043, 0x1cdf, "ASUS G814JY/JZ/JG", ALC245_FIXUP_CS35L41_SPI_2), ++ SND_PCI_QUIRK(0x1043, 0x1cef, "ASUS G834JY/JZ/JI/JG", ALC285_FIXUP_ASUS_HEADSET_MIC), ++ SND_PCI_QUIRK(0x1043, 0x1d1f, "ASUS G713PI/PU/PV/PVN", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x1043, 0x1d42, "ASUS Zephyrus G14 2022", ALC289_FIXUP_ASUS_GA401), + SND_PCI_QUIRK(0x1043, 0x1d4e, "ASUS TM420", ALC256_FIXUP_ASUS_HPE), + SND_PCI_QUIRK(0x1043, 0x1da2, "ASUS UP6502ZA/ZD", ALC245_FIXUP_CS35L41_SPI_2), +diff --git a/sound/soc/codecs/es8328.c b/sound/soc/codecs/es8328.c +index 0bd9ba5a11b4e5..43792e175d75f1 100644 +--- a/sound/soc/codecs/es8328.c ++++ b/sound/soc/codecs/es8328.c +@@ -234,7 +234,6 @@ static const struct snd_kcontrol_new es8328_right_line_controls = + + /* Left Mixer */ + static const struct snd_kcontrol_new es8328_left_mixer_controls[] = { +- SOC_DAPM_SINGLE("Playback Switch", ES8328_DACCONTROL17, 7, 1, 0), + SOC_DAPM_SINGLE("Left Bypass Switch", ES8328_DACCONTROL17, 6, 1, 0), + SOC_DAPM_SINGLE("Right Playback Switch", ES8328_DACCONTROL18, 7, 1, 0), + SOC_DAPM_SINGLE("Right Bypass Switch", ES8328_DACCONTROL18, 6, 1, 0), +@@ -244,7 +243,6 @@ static const struct snd_kcontrol_new es8328_left_mixer_controls[] = { + static const struct snd_kcontrol_new es8328_right_mixer_controls[] = { + SOC_DAPM_SINGLE("Left Playback Switch", ES8328_DACCONTROL19, 7, 1, 0), + SOC_DAPM_SINGLE("Left Bypass Switch", ES8328_DACCONTROL19, 6, 1, 0), +- SOC_DAPM_SINGLE("Playback Switch", ES8328_DACCONTROL20, 7, 1, 0), + SOC_DAPM_SINGLE("Right Bypass Switch", ES8328_DACCONTROL20, 6, 1, 0), + }; + +@@ -337,10 +335,10 @@ static const struct snd_soc_dapm_widget es8328_dapm_widgets[] = { + SND_SOC_DAPM_DAC("Left DAC", "Left Playback", ES8328_DACPOWER, + ES8328_DACPOWER_LDAC_OFF, 1), + +- SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0, ++ SND_SOC_DAPM_MIXER("Left Mixer", ES8328_DACCONTROL17, 7, 0, + &es8328_left_mixer_controls[0], + ARRAY_SIZE(es8328_left_mixer_controls)), +- SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0, ++ SND_SOC_DAPM_MIXER("Right Mixer", ES8328_DACCONTROL20, 7, 0, + &es8328_right_mixer_controls[0], + ARRAY_SIZE(es8328_right_mixer_controls)), + +@@ -419,19 +417,14 @@ static const struct snd_soc_dapm_route es8328_dapm_routes[] = { + { "Right Line Mux", "PGA", "Right PGA Mux" }, + { "Right Line Mux", "Differential", "Differential Mux" }, + +- { "Left Out 1", NULL, "Left DAC" }, +- { "Right Out 1", NULL, "Right DAC" }, +- { "Left Out 2", NULL, "Left DAC" }, +- { "Right Out 2", NULL, "Right DAC" }, +- +- { "Left Mixer", "Playback Switch", "Left DAC" }, ++ { "Left Mixer", NULL, "Left DAC" }, + { "Left Mixer", "Left Bypass Switch", "Left Line Mux" }, + { "Left Mixer", "Right Playback Switch", "Right DAC" }, + { "Left Mixer", "Right Bypass Switch", "Right Line Mux" }, + + { "Right Mixer", "Left Playback Switch", "Left DAC" }, + { "Right Mixer", "Left Bypass Switch", "Left Line Mux" }, +- { "Right Mixer", "Playback Switch", "Right DAC" }, ++ { "Right Mixer", NULL, "Right DAC" }, + { "Right Mixer", "Right Bypass Switch", "Right Line Mux" }, + + { "DAC DIG", NULL, "DAC STM" }, +diff --git a/sound/usb/midi.c b/sound/usb/midi.c +index 6b0993258e039b..6d861046b582b5 100644 +--- a/sound/usb/midi.c ++++ b/sound/usb/midi.c +@@ -1145,7 +1145,7 @@ static int snd_usbmidi_output_close(struct snd_rawmidi_substream *substream) + { + struct usbmidi_out_port *port = substream->runtime->private_data; + +- cancel_work_sync(&port->ep->work); ++ flush_work(&port->ep->work); + return substream_open(substream, 0, 0); + } + +diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c +index 93d9ed8983dfce..d9d4c5922a50bb 100644 +--- a/sound/usb/quirks.c ++++ b/sound/usb/quirks.c +@@ -1775,6 +1775,7 @@ void snd_usb_set_format_quirk(struct snd_usb_substream *subs, + case USB_ID(0x534d, 0x2109): /* MacroSilicon MS2109 */ + subs->stream_offset_adj = 2; + break; ++ case USB_ID(0x2b73, 0x000a): /* Pioneer DJM-900NXS2 */ + case USB_ID(0x2b73, 0x0013): /* Pioneer DJM-450 */ + pioneer_djm_set_format_quirk(subs, 0x0082); + break; +diff --git a/tools/testing/selftests/rseq/rseq-riscv-bits.h b/tools/testing/selftests/rseq/rseq-riscv-bits.h +index de31a0143139b7..f02f411d550d18 100644 +--- a/tools/testing/selftests/rseq/rseq-riscv-bits.h ++++ b/tools/testing/selftests/rseq/rseq-riscv-bits.h +@@ -243,7 +243,7 @@ int RSEQ_TEMPLATE_IDENTIFIER(rseq_offset_deref_addv)(intptr_t *ptr, off_t off, i + #ifdef RSEQ_COMPARE_TWICE + RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, "%l[error1]") + #endif +- RSEQ_ASM_OP_R_DEREF_ADDV(ptr, off, 3) ++ RSEQ_ASM_OP_R_DEREF_ADDV(ptr, off, inc, 3) + RSEQ_INJECT_ASM(4) + RSEQ_ASM_DEFINE_ABORT(4, abort) + : /* gcc asm goto does not allow outputs */ +@@ -251,8 +251,8 @@ int RSEQ_TEMPLATE_IDENTIFIER(rseq_offset_deref_addv)(intptr_t *ptr, off_t off, i + [current_cpu_id] "m" (rseq_get_abi()->RSEQ_TEMPLATE_CPU_ID_FIELD), + [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr), + [ptr] "r" (ptr), +- [off] "er" (off), +- [inc] "er" (inc) ++ [off] "r" (off), ++ [inc] "r" (inc) + RSEQ_INJECT_INPUT + : "memory", RSEQ_ASM_TMP_REG_1 + RSEQ_INJECT_CLOBBER +diff --git a/tools/testing/selftests/rseq/rseq-riscv.h b/tools/testing/selftests/rseq/rseq-riscv.h +index 37e598d0a365e2..67d544aaa9a3b0 100644 +--- a/tools/testing/selftests/rseq/rseq-riscv.h ++++ b/tools/testing/selftests/rseq/rseq-riscv.h +@@ -158,7 +158,7 @@ do { \ + "bnez " RSEQ_ASM_TMP_REG_1 ", 222b\n" \ + "333:\n" + +-#define RSEQ_ASM_OP_R_DEREF_ADDV(ptr, off, post_commit_label) \ ++#define RSEQ_ASM_OP_R_DEREF_ADDV(ptr, off, inc, post_commit_label) \ + "mv " RSEQ_ASM_TMP_REG_1 ", %[" __rseq_str(ptr) "]\n" \ + RSEQ_ASM_OP_R_ADD(off) \ + REG_L RSEQ_ASM_TMP_REG_1 ", 0(" RSEQ_ASM_TMP_REG_1 ")\n" \ +diff --git a/tools/tracing/rtla/src/timerlat_hist.c b/tools/tracing/rtla/src/timerlat_hist.c +index a985e57954820e..198cdf75c837bb 100644 +--- a/tools/tracing/rtla/src/timerlat_hist.c ++++ b/tools/tracing/rtla/src/timerlat_hist.c +@@ -905,7 +905,7 @@ timerlat_hist_apply_config(struct osnoise_tool *tool, struct timerlat_hist_param + * On kernels without support, user threads will have already failed + * on missing timerlat_fd, and kernel threads do not need it. + */ +- retval = osnoise_set_workload(tool->context, params->kernel_workload); ++ retval = osnoise_set_workload(tool->context, !params->user_hist); + if (retval < -1) { + err_msg("Failed to set OSNOISE_WORKLOAD option\n"); + goto out_err; +diff --git a/tools/tracing/rtla/src/timerlat_top.c b/tools/tracing/rtla/src/timerlat_top.c +index 1fed4c8d8520f9..7212855d336417 100644 +--- a/tools/tracing/rtla/src/timerlat_top.c ++++ b/tools/tracing/rtla/src/timerlat_top.c +@@ -684,7 +684,7 @@ timerlat_top_apply_config(struct osnoise_tool *top, struct timerlat_top_params * + * On kernels without support, user threads will have already failed + * on missing timerlat_fd, and kernel threads do not need it. + */ +- retval = osnoise_set_workload(top->context, params->kernel_workload); ++ retval = osnoise_set_workload(top->context, !params->user_top); + if (retval < -1) { + err_msg("Failed to set OSNOISE_WORKLOAD option\n"); + goto out_err; From 34311b6d0d603004fd755976a3c6e6901155fa94 Mon Sep 17 00:00:00 2001 From: igorpecovnik <6281704+igorpecovnik@users.noreply.github.com> Date: Sun, 9 Mar 2025 09:06:36 +0000 Subject: [PATCH 32/37] `Automatic` board configs status synchronise --- .github/CODEOWNERS | 26 +++++++++++++++++--------- config/boards/bananapim2plus.csc | 2 +- config/boards/beaglebone-ai64.conf | 2 +- config/boards/beagleplay.conf | 2 +- config/boards/pocketbeagle2.csc | 2 +- 5 files changed, 21 insertions(+), 13 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index f109a4a2ccd5..b08f8568f8b2 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -27,6 +27,7 @@ config/boards/ayn-odin2.csc @FantasyGmm config/boards/bananapi.conf @DylanHP @janprunk config/boards/bananapicm4io.conf @pyavitz config/boards/bananapif3.conf @pyavitz +config/boards/bananapim2plus.csc @leggewie config/boards/bananapim2pro.conf @igorpecovnik config/boards/bananapim2s.conf @jeanrhum @pyavitz config/boards/bananapim2zero.csc @mhawkins-consultant @@ -36,6 +37,8 @@ config/boards/bananapim4zero.conf @pyavitz config/boards/bananapim5.conf @igorpecovnik config/boards/bananapim64.csc @devdotnetorg config/boards/bananapim7.conf @amazingfate +config/boards/beaglebone-ai64.conf @Grippy98 +config/boards/beagleplay.conf @Grippy98 config/boards/bigtreetech-cb1.conf @JohnTheCoolingFan config/boards/bigtreetech-cb2.conf @JohnTheCoolingFan config/boards/cherryba-m1.csc @IsMrX @@ -118,6 +121,7 @@ config/boards/orangepizeroplus.csc @schwar3kat config/boards/phytiumpi.conf @chainsx config/boards/pine64.conf @PanderMusubi config/boards/pinebook-pro.csc @TRSx80 @ahoneybun +config/boards/pocketbeagle2.csc @Grippy98 config/boards/pocketchip-sd.csc @TheSnowfield config/boards/qemu-uboot-arm64.csc @rpardini config/boards/qemu-uboot-x86.csc @rpardini @@ -173,7 +177,8 @@ config/boards/youyeetoo-r1-v3.csc @SuperKali config/boards/yy3568.csc @hqnicolas config/kernel/linux-arm64-*.config @FantasyGmm @PeterChrz @rpardini config/kernel/linux-bcm2711-*.config @PanderMusubi @teknoid -config/kernel/linux-k3-*.config @glneo +config/kernel/linux-k3-*.config @Grippy98 @glneo +config/kernel/linux-k3-beagle-*.config @Grippy98 config/kernel/linux-meson-*.config @hzyitc @juanlufont config/kernel/linux-meson-s4t7-*.config @adeepn @rpardini @viraniac config/kernel/linux-meson64-*.config @NicoD-SBC @SteeManMI @Tonymac32 @adeepn @clee @engineer-80 @igorpecovnik @jeanrhum @jomadeto @monkaBlyat @pyavitz @rpardini @teknoid @@ -186,7 +191,7 @@ config/kernel/linux-rockchip64-*.config @150balbes @ColorfulRhino @HeyMeco @Joh config/kernel/linux-sm8250-*.config @FantasyGmm @amazingfate config/kernel/linux-spacemit-*.config @pyavitz config/kernel/linux-sun55iw3-syterkit-*.config @chainsx -config/kernel/linux-sunxi-*.config @1ubuntuuser @AaronNGray @DylanHP @Janmcha @StephenGraf @TheSnowfield @Tonymac32 @janprunk @lbmendes @mhawkins-consultant @sgjava @spendist +config/kernel/linux-sunxi-*.config @1ubuntuuser @AaronNGray @DylanHP @Janmcha @StephenGraf @TheSnowfield @Tonymac32 @janprunk @lbmendes @leggewie @mhawkins-consultant @sgjava @spendist config/kernel/linux-sunxi64-*.config @AGM1968 @IsMrX @JohnTheCoolingFan @Kreyren @NicoD-SBC @PanderMusubi @Ressetkk @The-going @Tonymac32 @alexl83 @chraac @devdotnetorg @eliasbakken @krachlatte @pyavitz @schwar3kat @sicXnull @spendist @teknoid config/kernel/linux-thead-*.config @chainsx config/kernel/linux-tqma-*.config @schmiedelm @@ -197,7 +202,8 @@ config/kernel/linux-wsl2-x86-*.config @rpardini patch/atf/atf-arm64/ @FantasyGmm @PeterChrz @rpardini patch/atf/atf-bcm2711/ @PanderMusubi @teknoid patch/atf/atf-imx8m/ @schmiedelm -patch/atf/atf-k3/ @glneo +patch/atf/atf-k3-beagle/ @Grippy98 +patch/atf/atf-k3/ @Grippy98 @glneo patch/atf/atf-phytium-embedded/ @chainsx patch/atf/atf-rockchip64/ @ColorfulRhino @TRSx80 @ahoneybun @andyshrk @clee @joekhoobyar @paolosabatino @prahal patch/atf/atf-sm8250/ @FantasyGmm @amazingfate @@ -207,7 +213,8 @@ patch/atf/atf-sunxi64/ @AGM1968 @IsMrX @JohnTheCoolingFan @Kreyren @NicoD-SBC @ patch/atf/atf-wsl2-arm64/ @rpardini patch/kernel/archive/bcm2711-*/ @PanderMusubi @teknoid patch/kernel/archive/imx8m-*/ @schmiedelm -patch/kernel/archive/k3-*/ @glneo +patch/kernel/archive/k3-*/ @Grippy98 @glneo +patch/kernel/archive/k3-beagle-*/ @Grippy98 patch/kernel/archive/meson-*/ @hzyitc @juanlufont patch/kernel/archive/meson-s4t7-*/ @adeepn @rpardini @viraniac patch/kernel/archive/meson64-*/ @NicoD-SBC @SteeManMI @Tonymac32 @adeepn @clee @engineer-80 @igorpecovnik @jeanrhum @jomadeto @monkaBlyat @pyavitz @rpardini @teknoid @@ -217,7 +224,7 @@ patch/kernel/archive/rockchip-*/ @paolosabatino patch/kernel/archive/rockchip64-*/ @150balbes @ColorfulRhino @HeyMeco @JohnTheCoolingFan @Manouchehri @SuperKali @TRSx80 @TheSnowfield @Tonymac32 @ZazaBR @ahoneybun @alexl83 @amazingfate @andyshrk @brentr @catalinii @clee @efectn @fridtjof @hqnicolas @igorpecovnik @joekhoobyar @krachlatte @lanefu @linhz0hz @mlegenovic @paolosabatino @prahal @redrathnure @rpardini @schwar3kat @sicXnull @tdleiyao @torte71 @utlark @vamzii patch/kernel/archive/sm8250-*/ @FantasyGmm @amazingfate patch/kernel/archive/spacemit-*/ @pyavitz -patch/kernel/archive/sunxi-*/ @1ubuntuuser @AGM1968 @AaronNGray @DylanHP @IsMrX @Janmcha @JohnTheCoolingFan @Kreyren @NicoD-SBC @PanderMusubi @Ressetkk @StephenGraf @The-going @TheSnowfield @Tonymac32 @alexl83 @chraac @devdotnetorg @eliasbakken @janprunk @krachlatte @lbmendes @mhawkins-consultant @pyavitz @schwar3kat @sgjava @sicXnull @spendist @teknoid +patch/kernel/archive/sunxi-*/ @1ubuntuuser @AGM1968 @AaronNGray @DylanHP @IsMrX @Janmcha @JohnTheCoolingFan @Kreyren @NicoD-SBC @PanderMusubi @Ressetkk @StephenGraf @The-going @TheSnowfield @Tonymac32 @alexl83 @chraac @devdotnetorg @eliasbakken @janprunk @krachlatte @lbmendes @leggewie @mhawkins-consultant @pyavitz @schwar3kat @sgjava @sicXnull @spendist @teknoid patch/kernel/archive/uefi-arm64-*/ @PeterChrz @rpardini patch/kernel/archive/uefi-x86-*/ @davidandreoletti @rpardini patch/kernel/archive/wsl2-arm64-*/ @rpardini @@ -234,14 +241,15 @@ patch/u-boot/legacy/u-boot-helios4/ @Heisath patch/u-boot/legacy/u-boot-khadas-edge2-rk3588/ @efectn patch/u-boot/legacy/u-boot-radxa-rk35xx/ @CodeChenL @HeyMeco @SeeleVolleri @SuperKali @Tonymac32 @ZazaBR @alexl83 @amazingfate @catalinii @chainsx @efectn @fridtjof @ginkage @hoochiwetech @hqnicolas @krachlatte @linhz0hz @mahdichi @mattx433 @monkaBlyat @prahal @rpardini @schwar3kat @sputnik2019 @tdleiyao @vamzii patch/u-boot/legacy/u-boot-spacemit-k1/ @pyavitz -patch/u-boot/u-boot-k3/ @glneo +patch/u-boot/u-boot-k3-beagle/ @Grippy98 +patch/u-boot/u-boot-k3/ @Grippy98 @glneo patch/u-boot/u-boot-meson-s4t7/ @adeepn @rpardini @viraniac patch/u-boot/u-boot-qemu-arm64/ @rpardini patch/u-boot/u-boot-qemu-x86/ @rpardini patch/u-boot/u-boot-rockchip64-v2022.04/ @Manouchehri @TRSx80 @TheSnowfield @ahoneybun @paolosabatino patch/u-boot/u-boot-rockchip64/ @Tonymac32 @andyshrk @clee @igorpecovnik @paolosabatino @prahal @redrathnure @sicXnull @torte71 patch/u-boot/u-boot-sunxi-crust/ @AGM1968 @Kreyren @NicoD-SBC @PanderMusubi @Tonymac32 @devdotnetorg @schwar3kat @spendist @teknoid -patch/u-boot/u-boot-sunxi/ @1ubuntuuser @AGM1968 @DylanHP @Janmcha @JohnTheCoolingFan @Kreyren @NicoD-SBC @PanderMusubi @Ressetkk @StephenGraf @TheSnowfield @Tonymac32 @alexl83 @chraac @devdotnetorg @eliasbakken @janprunk @krachlatte @lbmendes @mhawkins-consultant @schwar3kat @sgjava @sicXnull @spendist @teknoid +patch/u-boot/u-boot-sunxi/ @1ubuntuuser @AGM1968 @DylanHP @Janmcha @JohnTheCoolingFan @Kreyren @NicoD-SBC @PanderMusubi @Ressetkk @StephenGraf @TheSnowfield @Tonymac32 @alexl83 @chraac @devdotnetorg @eliasbakken @janprunk @krachlatte @lbmendes @leggewie @mhawkins-consultant @schwar3kat @sgjava @sicXnull @spendist @teknoid patch/u-boot/u-boot-sunxi/board_bananapim3/ @AaronNGray patch/u-boot/u-boot-tqma/ @schmiedelm patch/u-boot/v2022.01/ @teknoid @@ -267,7 +275,7 @@ patch/u-boot/v2025.04/ @SuperKali @Tonymac32 sources/families/bcm2711.conf @PanderMusubi @teknoid sources/families/imx8m.conf @schmiedelm sources/families/jethub.conf @adeepn -sources/families/k3.conf @glneo +sources/families/k3.conf @Grippy98 @glneo sources/families/meson-axg.conf @pyavitz sources/families/meson-g12a.conf @clee @engineer-80 sources/families/meson-g12b.conf @NicoD-SBC @Tonymac32 @jeanrhum @monkaBlyat @pyavitz @rpardini @@ -294,7 +302,7 @@ sources/families/sun50iw9.conf @AGM1968 @IsMrX @JohnTheCoolingFan @Ressetkk @al sources/families/sun55iw3-syterkit.conf @chainsx sources/families/sun5i.conf @TheSnowfield sources/families/sun7i.conf @DylanHP @janprunk -sources/families/sun8i.conf @1ubuntuuser @AaronNGray @Janmcha @StephenGraf @Tonymac32 @lbmendes @mhawkins-consultant @sgjava @spendist +sources/families/sun8i.conf @1ubuntuuser @AaronNGray @Janmcha @StephenGraf @Tonymac32 @lbmendes @leggewie @mhawkins-consultant @sgjava @spendist sources/families/thead.conf @chainsx sources/families/uefi-arm64.conf @PeterChrz @rpardini sources/families/uefi-x86.conf @davidandreoletti @rpardini diff --git a/config/boards/bananapim2plus.csc b/config/boards/bananapim2plus.csc index 1c0480828f0d..af92dc95a98d 100644 --- a/config/boards/bananapim2plus.csc +++ b/config/boards/bananapim2plus.csc @@ -1,7 +1,7 @@ # Allwinner H3 quad core 1Gb RAM SoC Wifi GBE BOARD_NAME="Banana Pi M2+" BOARDFAMILY="sun8i" -BOARD_MAINTAINER="" +BOARD_MAINTAINER="leggewie" BOOTCONFIG="bananapi_m2_plus_h3_defconfig" DEFAULT_OVERLAYS="analog-codec" MODULES_CURRENT="g_serial" diff --git a/config/boards/beaglebone-ai64.conf b/config/boards/beaglebone-ai64.conf index 7efd7acb4688..6b4b1479f5f3 100644 --- a/config/boards/beaglebone-ai64.conf +++ b/config/boards/beaglebone-ai64.conf @@ -2,7 +2,7 @@ BOARD_NAME="BeagleBone AI-64" BOARDFAMILY="k3" -BOARD_MAINTAINER="grippy98" +BOARD_MAINTAINER="Grippy98" BOOTCONFIG="j721e_beagleboneai64_a72_defconfig" BOOTFS_TYPE="fat" BOOT_FDT_FILE="ti/k3-j721e-beagleboneai64.dts" diff --git a/config/boards/beagleplay.conf b/config/boards/beagleplay.conf index a1f819aabfb2..a1f65e692afb 100644 --- a/config/boards/beagleplay.conf +++ b/config/boards/beagleplay.conf @@ -2,7 +2,7 @@ BOARD_NAME="BeaglePlay" BOARDFAMILY="k3" -BOARD_MAINTAINER="grippy98" +BOARD_MAINTAINER="Grippy98" BOOTCONFIG="am62x_beagleplay_a53_defconfig" BOOTFS_TYPE="fat" BOOT_FDT_FILE="ti/k3-am625-beagleplay.dts" diff --git a/config/boards/pocketbeagle2.csc b/config/boards/pocketbeagle2.csc index c505d50cc9a1..d39c51547032 100644 --- a/config/boards/pocketbeagle2.csc +++ b/config/boards/pocketbeagle2.csc @@ -2,7 +2,7 @@ BOARD_NAME="PocketBeagle 2" BOARDFAMILY="k3" -BOARD_MAINTAINER="grippy98" +BOARD_MAINTAINER="Grippy98" BOOTCONFIG="am6232_pocketbeagle2_a53_defconfig" BOOTFS_TYPE="fat" BOOT_FDT_FILE="k3-am6232-pocketbeagle2.dts" From 6da2bbd1715c522ce1fc4d9a3a723ba17e1a7360 Mon Sep 17 00:00:00 2001 From: amazingfate Date: Fri, 7 Mar 2025 18:09:15 +0800 Subject: [PATCH 33/37] rockchip64-6.12: slow down emmc freq instead of toggling to HS200 for rock5b --- ...5b-Slow-down-emmc-to-hs200-and-add-ts.patch | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/patch/kernel/archive/rockchip64-6.12/rk3588-1010-arm64-dts-rock-5b-Slow-down-emmc-to-hs200-and-add-ts.patch b/patch/kernel/archive/rockchip64-6.12/rk3588-1010-arm64-dts-rock-5b-Slow-down-emmc-to-hs200-and-add-ts.patch index cad0ed1438f8..fd36ba64c1fd 100644 --- a/patch/kernel/archive/rockchip64-6.12/rk3588-1010-arm64-dts-rock-5b-Slow-down-emmc-to-hs200-and-add-ts.patch +++ b/patch/kernel/archive/rockchip64-6.12/rk3588-1010-arm64-dts-rock-5b-Slow-down-emmc-to-hs200-and-add-ts.patch @@ -1,27 +1,25 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: amazingfate Date: Wed, 27 Dec 2023 15:03:57 +0800 -Subject: arm64: dts: rock-5b: Slow down emmc to hs200 and add tsadc node +Subject: arm64: dts: rock-5b: Slow down emmc freq and add tsadc node --- - arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) + arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 5 +++++ + 1 file changed, 5 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts -@@ -408,8 +408,7 @@ &sdhci { +@@ -408,6 +408,7 @@ &sdhci { no-sdio; no-sd; non-removable; -- mmc-hs400-1_8v; -- mmc-hs400-enhanced-strobe; -+ mmc-hs200-1_8v; ++ max-frequency = <150000000>; + mmc-hs400-1_8v; + mmc-hs400-enhanced-strobe; status = "okay"; - }; - -@@ -463,6 +462,10 @@ flash@0 { +@@ -463,6 +464,10 @@ flash@0 { }; }; From 5f519b7b7b151db98260f817bf4774d4eb8ca479 Mon Sep 17 00:00:00 2001 From: amazingfate Date: Fri, 7 Mar 2025 18:09:29 +0800 Subject: [PATCH 34/37] rockchip64-6.14: slow down emmc freq instead of toggling to HS200 for rock5b --- ...-rock-5b-Slow-down-emmc-to-hs200-and-add-ts.patch | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/patch/kernel/archive/rockchip64-6.14/rk3588-1010-arm64-dts-rock-5b-Slow-down-emmc-to-hs200-and-add-ts.patch b/patch/kernel/archive/rockchip64-6.14/rk3588-1010-arm64-dts-rock-5b-Slow-down-emmc-to-hs200-and-add-ts.patch index a6cdd893ad99..593cfd1f134b 100644 --- a/patch/kernel/archive/rockchip64-6.14/rk3588-1010-arm64-dts-rock-5b-Slow-down-emmc-to-hs200-and-add-ts.patch +++ b/patch/kernel/archive/rockchip64-6.14/rk3588-1010-arm64-dts-rock-5b-Slow-down-emmc-to-hs200-and-add-ts.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: amazingfate Date: Wed, 27 Dec 2023 15:03:57 +0800 -Subject: arm64: dts: rock-5b: Slow down emmc to hs200 and add tsadc node +Subject: arm64: dts: rock-5b: Slow down emmc freq and add tsadc node --- arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 7 +++++-- @@ -11,16 +11,14 @@ diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/arm64/boot/d index 111111111111..222222222222 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts -@@ -440,8 +440,7 @@ &sdhci { +@@ -440,6 +440,7 @@ &sdhci { no-sdio; no-sd; non-removable; -- mmc-hs400-1_8v; -- mmc-hs400-enhanced-strobe; -+ mmc-hs200-1_8v; ++ max-frequency = <150000000>; + mmc-hs400-1_8v; + mmc-hs400-enhanced-strobe; status = "okay"; - }; - @@ -495,6 +494,10 @@ flash@0 { }; }; From bc4f99ed544eae5cf3c559fa4bc1019a2ce98361 Mon Sep 17 00:00:00 2001 From: amazingfate Date: Fri, 7 Mar 2025 18:10:04 +0800 Subject: [PATCH 35/37] rockchip64-6.12: rock-5-itx: slow down emmc freq --- ...ip-disable-emmc-hs400-for-rock-5-itx.patch | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 patch/kernel/archive/rockchip64-6.12/rk3588-1013-arm64-dts-rockchip-disable-emmc-hs400-for-rock-5-itx.patch diff --git a/patch/kernel/archive/rockchip64-6.12/rk3588-1013-arm64-dts-rockchip-disable-emmc-hs400-for-rock-5-itx.patch b/patch/kernel/archive/rockchip64-6.12/rk3588-1013-arm64-dts-rockchip-disable-emmc-hs400-for-rock-5-itx.patch new file mode 100644 index 000000000000..181980197f2a --- /dev/null +++ b/patch/kernel/archive/rockchip64-6.12/rk3588-1013-arm64-dts-rockchip-disable-emmc-hs400-for-rock-5-itx.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jianfeng Liu +Date: Fri, 28 Feb 2025 22:04:34 +0800 +Subject: arm64: dts: rockchip: slow down emmc freq for rock 5 itx + +--- + arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts +index 111111111111..222222222222 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts +@@ -656,10 +656,9 @@ &saradc { + + &sdhci { + bus-width = <8>; +- max-frequency = <200000000>; ++ max-frequency = <150000000>; + mmc-hs400-1_8v; + mmc-hs400-enhanced-strobe; +- mmc-hs200-1_8v; + no-sdio; + no-sd; + non-removable; +-- +Armbian + From 3afb49c4cd0bc0b144bd0c476d9f7ca98643081c Mon Sep 17 00:00:00 2001 From: amazingfate Date: Fri, 7 Mar 2025 18:10:27 +0800 Subject: [PATCH 36/37] rockchip64-6.14: rock-5-itx: slow down emmc freq --- ...ip-disable-emmc-hs400-for-rock-5-itx.patch | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 patch/kernel/archive/rockchip64-6.14/rk3588-1013-arm64-dts-rockchip-disable-emmc-hs400-for-rock-5-itx.patch diff --git a/patch/kernel/archive/rockchip64-6.14/rk3588-1013-arm64-dts-rockchip-disable-emmc-hs400-for-rock-5-itx.patch b/patch/kernel/archive/rockchip64-6.14/rk3588-1013-arm64-dts-rockchip-disable-emmc-hs400-for-rock-5-itx.patch new file mode 100644 index 000000000000..181980197f2a --- /dev/null +++ b/patch/kernel/archive/rockchip64-6.14/rk3588-1013-arm64-dts-rockchip-disable-emmc-hs400-for-rock-5-itx.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jianfeng Liu +Date: Fri, 28 Feb 2025 22:04:34 +0800 +Subject: arm64: dts: rockchip: slow down emmc freq for rock 5 itx + +--- + arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts +index 111111111111..222222222222 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts +@@ -656,10 +656,9 @@ &saradc { + + &sdhci { + bus-width = <8>; +- max-frequency = <200000000>; ++ max-frequency = <150000000>; + mmc-hs400-1_8v; + mmc-hs400-enhanced-strobe; +- mmc-hs200-1_8v; + no-sdio; + no-sd; + non-removable; +-- +Armbian + From b10e9733fcf4c210fedd0dd6328ae43e2767a26c Mon Sep 17 00:00:00 2001 From: FantasyGmm <16450052+FantasyGmm@users.noreply.github.com> Date: Mon, 10 Mar 2025 11:06:48 +0800 Subject: [PATCH 37/37] Remove Xiaomi umi Support --- config/boards/xiaomi-umi.eos | 99 -- packages/bsp/xiaomi-umi/umi.conf | 6 - packages/bsp/xiaomi-umi/umi_HiFi.conf | 67 -- packages/bsp/xiaomi-umi/zz-update-abl-kernel | 33 - .../archive/sm8250-6.12/dt/.placeholder | 0 .../dt/sm8250-xiaomi-umi-common.dtsi | 938 ------------------ .../sm8250-6.12/dt/sm8250-xiaomi-umi-csot.dts | 13 - .../sm8250-6.12/dt/sm8250-xiaomi-umi-sms.dts | 13 - 8 files changed, 1169 deletions(-) delete mode 100644 config/boards/xiaomi-umi.eos delete mode 100644 packages/bsp/xiaomi-umi/umi.conf delete mode 100644 packages/bsp/xiaomi-umi/umi_HiFi.conf delete mode 100755 packages/bsp/xiaomi-umi/zz-update-abl-kernel create mode 100644 patch/kernel/archive/sm8250-6.12/dt/.placeholder delete mode 100644 patch/kernel/archive/sm8250-6.12/dt/sm8250-xiaomi-umi-common.dtsi delete mode 100644 patch/kernel/archive/sm8250-6.12/dt/sm8250-xiaomi-umi-csot.dts delete mode 100644 patch/kernel/archive/sm8250-6.12/dt/sm8250-xiaomi-umi-sms.dts diff --git a/config/boards/xiaomi-umi.eos b/config/boards/xiaomi-umi.eos deleted file mode 100644 index b559a084a05d..000000000000 --- a/config/boards/xiaomi-umi.eos +++ /dev/null @@ -1,99 +0,0 @@ -# Generate kernel and rootfs image for Qcom ABL booting -declare -g BOARD_NAME="Xiaomi Umi" -declare -g BOARD_MAINTAINER="FantasyGmm" -declare -g BOARDFAMILY="sm8250" -declare -g KERNEL_TARGET="current,edge" -declare -g KERNEL_TEST_TARGET="edge" -declare -g EXTRAWIFI="no" -declare -g MODULES="spi-geni-qcom" -declare -g BOOTCONFIG="none" -declare -g BOOTIMG_CMDLINE_EXTRA="clk_ignore_unused pd_ignore_unused" -declare -g IMAGE_PARTITION_TABLE="gpt" -declare -g -a ABL_DTB_LIST=("sm8250-xiaomi-umi-csot" "sm8250-xiaomi-umi-sms") - -# Use the full firmware, complete linux-firmware plus Armbian's (for qcom/a650_sqe.fw) -declare -g BOARD_FIRMWARE_INSTALL="-full" - -function xiaomi-umi_is_userspace_supported() { - [[ "${RELEASE}" == "jammy" ]] && return 0 - [[ "${RELEASE}" == "trixie" ]] && return 0 - [[ "${RELEASE}" == "noble" ]] && return 0 - return 1 -} - -function post_family_tweaks_bsp__xiaomi-umi_firmware() { - display_alert "$BOARD" "Install firmwares for xiaomi umi" "info" - - # Alsa-ucm-conf profile for Xiaomi Umi - mkdir -p $destination/usr/share/alsa/ucm2/conf.d/sm8250 - install -Dm644 $SRC/packages/bsp/xiaomi-umi/umi.conf $destination/usr/share/alsa/ucm2/Xiaomi/umi/umi.conf - install -Dm644 $SRC/packages/bsp/xiaomi-umi/umi_HiFi.conf $destination/usr/share/alsa/ucm2/Xiaomi/umi/HiFi.conf - ln -sfv ../../Xiaomi/umi/umi.conf \ - "$destination/usr/share/alsa/ucm2/conf.d/sm8250/Xiaomi Mi 10.conf" - - # USB Gadget Network service - mkdir -p $destination/usr/local/bin/ - mkdir -p $destination/usr/lib/systemd/system/ - install -Dm655 $SRC/packages/bsp/usb-gadget-network/setup-usbgadget-network.sh $destination/usr/local/bin/ - install -Dm655 $SRC/packages/bsp/usb-gadget-network/remove-usbgadget-network.sh $destination/usr/local/bin/ - install -Dm644 $SRC/packages/bsp/usb-gadget-network/usbgadget-rndis.service $destination/usr/lib/systemd/system/ - - # Kernel postinst script to update abl boot partition - install -Dm655 $SRC/packages/bsp/xiaomi-umi/zz-update-abl-kernel $destination/etc/kernel/postinst.d/ - - return 0 -} - -function post_family_tweaks__xiaomi-umi_enable_services() { - if ! xiaomi-umi_is_userspace_supported; then - if [[ "${RELEASE}" != "" ]]; then - display_alert "Missing userspace for ${BOARD}" "${RELEASE} does not have the userspace necessary to support the ${BOARD}" "warn" - fi - return 0 - fi - - if [[ "${RELEASE}" == "jammy" ]] || [[ "${RELEASE}" == "noble" ]]; then - display_alert "Adding qcom-mainline PPA" "${BOARD}" "info" - do_with_retries 3 chroot_sdcard add-apt-repository ppa:liujianfeng1994/qcom-mainline --yes --no-update - fi - - # We need unudhcpd from armbian repo, so enable it - mv "${SDCARD}"/etc/apt/sources.list.d/armbian.sources.disabled "${SDCARD}"/etc/apt/sources.list.d/armbian.sources - - do_with_retries 3 chroot_sdcard_apt_get_update - display_alert "$BOARD" "Installing board tweaks" "info" - do_with_retries 3 chroot_sdcard_apt_get_install alsa-ucm-conf qbootctl qrtr-tools unudhcpd mkbootimg - - # Disable armbian repo back - mv "${SDCARD}"/etc/apt/sources.list.d/armbian.sources "${SDCARD}"/etc/apt/sources.list.d/armbian.sources.disabled - do_with_retries 3 chroot_sdcard_apt_get_update - - chroot_sdcard systemctl enable qbootctl.service - chroot_sdcard systemctl enable usbgadget-rndis.service - return 0 -} - -function post_family_tweaks_bsp__xiaomi-umi_bsp_firmware_in_initrd() { - display_alert "Adding to bsp-cli" "${BOARD}: firmware in initrd" "info" - declare file_added_to_bsp_destination # Will be filled in by add_file_from_stdin_to_bsp_destination - # Using Elish's firmware for now - add_file_from_stdin_to_bsp_destination "/etc/initramfs-tools/hooks/xiaomi-elish-firmware" <<- 'FIRMWARE_HOOK' - #!/bin/bash - [[ "$1" == "prereqs" ]] && exit 0 - . /usr/share/initramfs-tools/hook-functions - for f in /lib/firmware/qcom/sm8250/xiaomi/elish/* ; do - add_firmware "${f#/lib/firmware/}" - done - add_firmware "qcom/a650_sqe.fw" # Extra one for dpu - add_firmware "qcom/a650_gmu.bin" # Extra one for gpu - FIRMWARE_HOOK - run_host_command_logged chmod -v +x "${file_added_to_bsp_destination}" -} - -## Modules, required to boot, add them to initrd -function post_family_tweaks_bsp__xiaomi-umi_bsp_modules_in_initrd() { - display_alert "Adding to bsp-cli" "${BOARD}: modules in initrd" "info" - add_file_from_stdin_to_bsp_destination "/etc/initramfs-tools/modules" <<- 'EXTRA_MODULES' - spi-geni-qcom - EXTRA_MODULES -} diff --git a/packages/bsp/xiaomi-umi/umi.conf b/packages/bsp/xiaomi-umi/umi.conf deleted file mode 100644 index 9993d8ee87c8..000000000000 --- a/packages/bsp/xiaomi-umi/umi.conf +++ /dev/null @@ -1,6 +0,0 @@ -Syntax 3 - -SectionUseCase."HiFi" { - File "/Xiaomi/umi/HiFi.conf" - Comment "HiFi quality Music." -} diff --git a/packages/bsp/xiaomi-umi/umi_HiFi.conf b/packages/bsp/xiaomi-umi/umi_HiFi.conf deleted file mode 100644 index 6b247adf130a..000000000000 --- a/packages/bsp/xiaomi-umi/umi_HiFi.conf +++ /dev/null @@ -1,67 +0,0 @@ -SectionVerb { - EnableSequence [ - cset "name='BRH DSP1 Preload Switch' 1" - cset "name='BRH DRE Switch' 1" - cset "name='BRH PCM Soft Ramp' 4ms" - cset "name='BRH Analog PCM Volume' 18" - cset "name='BRH ASP TX1 Source' DSPTX1" - cset "name='BRH DSP RX1 Source' ASPRX1" - cset "name='BRH DSP RX2 Source' ASPTX2" - - cset "name='BLH DSP1 Preload Switch' 1" - cset "name='BLH DRE Switch' 1" - cset "name='BLH PCM Soft Ramp' 4ms" - cset "name='BLH Analog PCM Volume' 18" - cset "name='BLH ASP TX1 Source' DSPTX1" - cset "name='BLH DSP RX1 Source' ASPRX1" - cset "name='BLH DSP RX2 Source' ASPTX2" - - cset "name='TERT_MI2S_RX Audio Mixer MultiMedia1' 1" - ] - - DisableSequence [ - cset "name='BRH DSP1 Preload Switch' 0" - cset "name='BRH DRE Switch' 0" - cset "name='BRH PCM Soft Ramp' zero" - cset "name='BRH Analog PCM Volume' 0" - cset "name='BRH ASP TX1 Source' zero" - cset "name='BRH DSP RX1 Source' zero" - cset "name='BRH DSP RX2 Source' zero" - - cset "name='BLH DSP1 Preload Switch' 0" - cset "name='BLH DRE Switch' 0" - cset "name='BLH PCM Soft Ramp' zero" - cset "name='BLH Analog PCM Volume' 0" - cset "name='BLH ASP TX1 Source' zero" - cset "name='BLH DSP RX1 Source' zero" - cset "name='BLH DSP RX2 Source' zero" - - cset "name='TERT_MI2S_RX Audio Mixer MultiMedia1' 0" - ] - - Value { - TQ "HiFi" - } -} - -SectionDevice."Speaker" { - Comment "Speaker playback" - - EnableSequence [ - cset "name='BRH PCM Source' DSP" - cset "name='BLH PCM Source' DSP" - ] - - DisableSequence [ - cset "name='BRH PCM Source' zero" - cset "name='BLH PCM Source' zero" - ] - - Value { - PlaybackPriority 100 - PlaybackPCM "hw:${CardId},0" - PlaybackMixerElem "Digital PCM" - PlaybackMasterElem "Analog PCM" - PlaybackVolume "Digital PCM Volume" - } -} diff --git a/packages/bsp/xiaomi-umi/zz-update-abl-kernel b/packages/bsp/xiaomi-umi/zz-update-abl-kernel deleted file mode 100755 index b007c32f492c..000000000000 --- a/packages/bsp/xiaomi-umi/zz-update-abl-kernel +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash -set -ex -machine_model=$(cat /sys/firmware/devicetree/base/model|tr '\0' '\n') -case $machine_model in - "Xiaomi Mi 10 (SMS)") - panel_type=sms - ;; - "Xiaomi Mi 10 (CSOT)") - panel_type=csot - ;; - *) - echo "$machine_model is not supported, exit" - exit - ;; -esac -new_rootfs_image_uuid=$(sed -e 's/^.*root=UUID=//' -e 's/ .*$//' < /proc/cmdline) -gzip -c /boot/vmlinuz-*-sm8250 > /tmp/Image.gz - -cat /tmp/Image.gz /usr/lib/linux-image-*-sm8250/qcom/sm8250-xiaomi-umi-${panel_type}.dtb > /tmp/Image.gz-dtb-${panel_type} - -source /boot/armbianEnv.txt -/usr/bin/mkbootimg \ - --kernel /tmp/Image.gz-dtb-${panel_type} \ - --ramdisk /boot/initrd.img-*-sm8250 \ - --base 0x0 \ - --second_offset 0x00f00000 \ - --cmdline "clk_ignore_unused pd_ignore_unused root=UUID=${new_rootfs_image_uuid}" \ - --kernel_offset 0x8000 \ - --ramdisk_offset 0x1000000 \ - --tags_offset 0x100 \ - --pagesize 4096 \ - -o /boot/armbian-kernel-${panel_type}.img -rm -f /tmp/Image.gz /tmp/Image.gz-dtb-${panel_type} diff --git a/patch/kernel/archive/sm8250-6.12/dt/.placeholder b/patch/kernel/archive/sm8250-6.12/dt/.placeholder new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/patch/kernel/archive/sm8250-6.12/dt/sm8250-xiaomi-umi-common.dtsi b/patch/kernel/archive/sm8250-6.12/dt/sm8250-xiaomi-umi-common.dtsi deleted file mode 100644 index eb297472a82e..000000000000 --- a/patch/kernel/archive/sm8250-6.12/dt/sm8250-xiaomi-umi-common.dtsi +++ /dev/null @@ -1,938 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -/* - * Copyright (c) 2020, The Linux Foundation. All rights reserved. - */ - - /dts-v1/; - - #include - #include - #include - #include - #include - #include - #include "sm8250.dtsi" - #include "pm8150.dtsi" - #include "pm8150b.dtsi" - #include "pm8150l.dtsi" - #include "pm8009.dtsi" - - /* - * Delete following upstream (sm8250.dtsi) reserved - * memory mappings which are different on this device. - */ - /delete-node/ &adsp_mem; - /delete-node/ &cdsp_secure_heap; - /delete-node/ &slpi_mem; - /delete-node/ &spss_mem; - /delete-node/ &xbl_aop_mem; - - / { - chassis-type = "handset"; - - qcom,msm-id = ; - qcom,board-id = <0x2b 0>; - - aliases { - hsuart0 = &uart6; - }; - - chosen { - #address-cells = <2>; - #size-cells = <2>; - ranges; - - framebuffer: framebuffer@9c000000 { - compatible = "simple-framebuffer"; - reg = <0x0 0x9c000000 0x0 0x2300000>; - width = <1080>; - height = <2340>; - stride = <(1080 * 4)>; - format = "a8r8g8b8"; - }; - }; - - // battery: battery { - // compatible = "simple-battery"; - // voltage-min-design-microvolt = <3870000>; - // energy-full-design-microwatt-hours = <16600000>; - // charge-full-design-microamp-hours = <4300000>; - // }; - - gpio_keys: gpio-keys { - compatible = "gpio-keys"; - - pinctrl-names = "default"; - pinctrl-0 = <&vol_up_n>; - - vol_up { - label = "Volume Up"; - gpios = <&pm8150_gpios 6 GPIO_ACTIVE_LOW>; - linux,code = ; - debounce-interval = <15>; - linux,can-disable; - wakeup-source; - }; - - hall_key { - label = "Hall Key"; - gpios = <&tlmm 14 GPIO_ACTIVE_LOW>; - linux,code = ; - debounce-interval = <15>; - linux,can-disable; - wakeup-source; - }; - }; - - vph_pwr: vph-pwr-regulator { - compatible = "regulator-fixed"; - regulator-name = "vph_pwr"; - regulator-min-microvolt = <3700000>; - regulator-max-microvolt = <3700000>; - }; - - vreg_s6c_0p88: smpc6-regulator { - compatible = "regulator-fixed"; - regulator-name = "vreg_s6c_0p88"; - - regulator-min-microvolt = <880000>; - regulator-max-microvolt = <880000>; - regulator-always-on; - vin-supply = <&vph_pwr>; - }; - - vreg_touch_vddio: vreg-touch-vddio{ - compatible = "regulator-fixed"; - regulator-name = "vreg_touch_vddio"; - enable-active-high; - /*regulator-boot-on*/ - gpio = <&tlmm 69 0>; - }; - - wcd938x: audio-codec { - compatible = "qcom,wcd9380-codec"; - - reset-gpios = <&tlmm 32 GPIO_ACTIVE_LOW>; - - vdd-buck-supply = <&vreg_s4a_1p8>; - vdd-rxtx-supply = <&vreg_s4a_1p8>; - vdd-io-supply = <&vreg_s4a_1p8>; - vdd-mic-bias-supply = <&vreg_bob>; - - qcom,micbias1-microvolt = <2750000>; - qcom,micbias2-microvolt = <2750000>; - qcom,micbias3-microvolt = <2750000>; - qcom,micbias4-microvolt = <2750000>; - qcom,rx-device = <&wcd_rx>; - qcom,tx-device = <&wcd_tx>; - - #sound-dai-cells = <1>; - }; - - qca639x: qca639x { - compatible = "qcom,qca6390"; - #power-domain-cells = <0>; - - vddaon-supply = <&vreg_s6a_0p95>; - vddpmu-supply = <&vreg_s2f_0p95>; - vddrfa1-supply = <&vreg_s2f_0p95>; - vddrfa2-supply = <&vreg_s8c_1p35>; - vddrfa3-supply = <&vreg_s5a_1p9>; - vddpcie1-supply = <&vreg_s8c_1p35>; - vddpcie2-supply = <&vreg_s5a_1p9>; - vddio-supply = <&vreg_s4a_1p8>; - - pinctrl-names = "default"; - pinctrl-0 = <&wlan_en_state>; - - wlan-en-gpios = <&tlmm 20 GPIO_ACTIVE_HIGH>; - }; - - reserved-memory { - xbl_aop_mem: xbl-aop@80600000 { - reg = <0x0 0x80600000 0x0 0x260000>; - no-map; - }; - - slpi_mem: slpi@88c00000 { - reg = <0x0 0x88c00000 0x0 0x2f00000>; - no-map; - }; - - adsp_mem: adsp@8bb00000 { - reg = <0x0 0x8bb00000 0x0 0x2500000>; - no-map; - }; - - spss_mem: spss@8e000000 { - reg = <0x0 0x8e000000 0x0 0x100000>; - no-map; - }; - - cdsp_secure_heap: cdsp-secure-heap@8e100000 { - reg = <0x0 0x8e100000 0x0 0x4600000>; - no-map; - }; - - cont_splash_mem: cont-splash@9c000000 { - reg = <0x0 0x9c000000 0x0 0x2300000>; - no-map; - }; - }; -}; - -&adsp { - firmware-name = "qcom/sm8250/xiaomi/elish/adsp.mbn"; - status = "okay"; -}; - -&apps_rsc { - regulators-0 { - compatible = "qcom,pm8150-rpmh-regulators"; - qcom,pmic-id = "a"; - - vdd-s1-supply = <&vph_pwr>; - vdd-s2-supply = <&vph_pwr>; - vdd-s3-supply = <&vph_pwr>; - vdd-s4-supply = <&vph_pwr>; - vdd-s5-supply = <&vph_pwr>; - vdd-s6-supply = <&vph_pwr>; - vdd-s7-supply = <&vph_pwr>; - vdd-s8-supply = <&vph_pwr>; - vdd-s9-supply = <&vph_pwr>; - vdd-s10-supply = <&vph_pwr>; - vdd-l1-l8-l11-supply = <&vreg_s6c_0p88>; - vdd-l2-l10-supply = <&vreg_bob>; - vdd-l3-l4-l5-l18-supply = <&vreg_s6a_0p95>; - vdd-l6-l9-supply = <&vreg_s8c_1p35>; - vdd-l7-l12-l14-l15-supply = <&vreg_s5a_1p9>; - vdd-l13-l16-l17-supply = <&vreg_bob>; - - vreg_s4a_1p8: smps4 { - regulator-name = "vreg_s4a_1p8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1920000>; - regulator-initial-mode = ; - }; - - vreg_s5a_1p9: smps5 { - regulator-name = "vreg_s5a_1p9"; - regulator-min-microvolt = <1900000>; - regulator-max-microvolt = <2040000>; - regulator-initial-mode = ; - }; - - vreg_s6a_0p95: smps6 { - regulator-name = "vreg_s6a_0p95"; - regulator-min-microvolt = <950000>; - regulator-max-microvolt = <1128000>; - regulator-initial-mode = ; - }; - - vreg_l2a_3p1: ldo2 { - regulator-name = "vreg_l2a_3p1"; - regulator-min-microvolt = <3072000>; - regulator-max-microvolt = <3072000>; - regulator-initial-mode = ; - }; - - vreg_l3a_0p9: ldo3 { - regulator-name = "vreg_l3a_0p9"; - regulator-min-microvolt = <928000>; - regulator-max-microvolt = <932000>; - regulator-initial-mode = ; - }; - - /* L4 - lmx.lvl (ARC) */ - - vreg_l5a_0p88: ldo5 { - regulator-name = "vreg_l5a_0p88"; - regulator-min-microvolt = <880000>; - regulator-max-microvolt = <880000>; - regulator-initial-mode = ; - }; - - vreg_l6a_1p2: ldo6 { - regulator-name = "vreg_l6a_1p2"; - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <1200000>; - regulator-initial-mode = ; - }; - - /* L7 is unused. */ - - vreg_l9a_1p2: ldo9 { - regulator-name = "vreg_l9a_1p2"; - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <1200000>; - regulator-initial-mode = ; - }; - - /* L10 is unused, L11 - lcx.lvl (ARC) */ - - vreg_l12a_1p8: ldo12 { - regulator-name = "vreg_l12a_1p8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-initial-mode = ; - }; - - vreg_l13a_3p0: ldo13 { - regulator-name = "vreg_l13a_3p0"; - regulator-min-microvolt = <3000000>; - regulator-max-microvolt = <3008000>; - regulator-initial-mode = ; - }; - - vreg_l14a_1p88: ldo14 { - regulator-name = "vreg_l14a_1p88"; - regulator-min-microvolt = <1880000>; - regulator-max-microvolt = <1880000>; - regulator-initial-mode = ; - }; - - /* L15 & L16 are unused. */ - - vreg_l17a_3p0: ldo17 { - regulator-name = "vreg_l17a_3p0"; - regulator-min-microvolt = <2856000>; - regulator-max-microvolt = <3008000>; - regulator-initial-mode = ; - }; - - vreg_l18a_0p9: ldo18 { - regulator-name = "vreg_l18a_0p9"; - regulator-min-microvolt = <912000>; - regulator-max-microvolt = <912000>; - regulator-initial-mode = ; - }; - }; - - regulators-1 { - compatible = "qcom,pm8150l-rpmh-regulators"; - qcom,pmic-id = "c"; - - vdd-s1-supply = <&vph_pwr>; - vdd-s2-supply = <&vph_pwr>; - vdd-s3-supply = <&vph_pwr>; - vdd-s4-supply = <&vph_pwr>; - vdd-s5-supply = <&vph_pwr>; - vdd-s6-supply = <&vph_pwr>; - vdd-s7-supply = <&vph_pwr>; - vdd-s8-supply = <&vph_pwr>; - vdd-l1-l8-supply = <&vreg_s4a_1p8>; - vdd-l2-l3-supply = <&vreg_s8c_1p35>; - vdd-l4-l5-l6-supply = <&vreg_bob>; - vdd-l7-l11-supply = <&vreg_bob>; - vdd-l9-l10-supply = <&vreg_bob>; - vdd-bob-supply = <&vph_pwr>; - - vreg_bob: bob { - regulator-name = "vreg_bob"; - regulator-min-microvolt = <3008000>; - regulator-max-microvolt = <3960000>; - regulator-initial-mode = ; - }; - - vreg_s8c_1p35: smps8 { - regulator-name = "vreg_s8c_1p35"; - regulator-min-microvolt = <1350000>; - regulator-max-microvolt = <1400000>; - regulator-initial-mode = ; - }; - - vreg_l1c_1p8: ldo1 { - regulator-name = "vreg_l1c_1p8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-initial-mode = ; - }; - - vreg_l2c_1p2: ldo2 { - regulator-name = "vreg_l2c_1p2"; - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <1200000>; - regulator-initial-mode = ; - }; - - vreg_l3c_0p92: ldo3 { - regulator-name = "vreg_l3c_0p92"; - regulator-min-microvolt = <920000>; - regulator-max-microvolt = <920000>; - regulator-initial-mode = ; - }; - - vreg_l4c_1p7: ldo4 { - regulator-name = "vreg_l4c_1p7"; - regulator-min-microvolt = <1704000>; - regulator-max-microvolt = <2928000>; - regulator-initial-mode = ; - }; - - vreg_l5c_1p8: ldo5 { - regulator-name = "vreg_l5c_1p8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <2928000>; - regulator-initial-mode = ; - }; - - vreg_l6c_2p9: ldo6 { - regulator-name = "vreg_l6c_2p9"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <2960000>; - regulator-initial-mode = ; - }; - - vreg_l7c_cam_vcm0_2p85: ldo7 { - regulator-name = "vreg_l7c_cam_vcm0_2p85"; - regulator-min-microvolt = <2856000>; - regulator-max-microvolt = <3104000>; - regulator-initial-mode = ; - }; - - vreg_l8c_1p8: ldo8 { - regulator-name = "vreg_l8c_1p8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-initial-mode = ; - }; - - vreg_l9c_2p9: ldo9 { - regulator-name = "vreg_l9c_2p9"; - regulator-min-microvolt = <2704000>; - regulator-max-microvolt = <2960000>; - regulator-initial-mode = ; - }; - - vreg_l10c_3p0: ldo10 { - regulator-name = "vreg_l10c_3p0"; - regulator-min-microvolt = <3000000>; - regulator-max-microvolt = <3000000>; - regulator-initial-mode = ; - }; - - vreg_l11c_3p3: ldo11 { - regulator-name = "vreg_l11c_3p3"; - regulator-min-microvolt = <3000000>; - regulator-max-microvolt = <3312000>; - regulator-initial-mode = ; - }; - }; - - regulators-2 { - compatible = "qcom,pm8009-rpmh-regulators"; - qcom,pmic-id = "f"; - - vdd-s1-supply = <&vph_pwr>; - vdd-s2-supply = <&vreg_bob>; - vdd-l2-supply = <&vreg_s8c_1p35>; - vdd-l5-l6-supply = <&vreg_bob>; - vdd-l7-supply = <&vreg_s4a_1p8>; - - vreg_s1f_1p2: smps1 { - regulator-name = "vreg_s1f_1p2"; - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <1200000>; - regulator-initial-mode = ; - }; - - vreg_s2f_0p95: smps2 { - regulator-name = "vreg_s2f_0p95"; - regulator-min-microvolt = <950000>; - regulator-max-microvolt = <1100000>; - regulator-initial-mode = ; - }; - - /* L1 is unused. */ - - vreg_l2f_1p3: ldo2 { - regulator-name = "vreg_l2f_1p3"; - regulator-min-microvolt = <1304000>; - regulator-max-microvolt = <1304000>; - regulator-initial-mode = ; - }; - - /* L3 & L4 are unused. */ - - vreg_l5f_2p8: ldo5 { - regulator-name = "vreg_l5f_2p85"; - regulator-min-microvolt = <2800000>; - regulator-max-microvolt = <2800000>; - regulator-initial-mode = ; - }; - - vreg_l6f_2p8: ldo6 { - regulator-name = "vreg_l6f_2p8"; - regulator-min-microvolt = <2800000>; - regulator-max-microvolt = <2800000>; - regulator-initial-mode = ; - }; - - vreg_l7f_1p8: ldo7 { - regulator-name = "vreg_l7f_1p8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-initial-mode = ; - }; - }; -}; - -&cdsp { - firmware-name = "qcom/sm8250/xiaomi/elish/cdsp.mbn"; - status = "okay"; -}; - -&gmu { - status = "okay"; -}; - -&gpu { - tatus = "okay"; - - zap-shader { - memory-region = <&gpu_mem>; - firmware-name = "qcom/sm8250/xiaomi/elish/a650_zap.mbn"; - }; -}; - -&qupv3_id_0 { - status = "okay"; -}; - -&qupv3_id_1 { - status = "okay"; -}; - -&qupv3_id_2 { - status = "okay"; -}; - -&gpi_dma0 { - status = "okay"; -}; - -&gpi_dma1 { - status = "okay"; -}; - -&gpi_dma2 { - status = "okay"; -}; - -&i2c3 { - clock-frequency = <400000>; - status = "okay"; - - cs35l41_brh: speaker-amp@40 { - compatible = "cirrus,cs35l41"; - reg = <0x40>; - interrupt-parent = <&tlmm>; - interrupts = <113 IRQ_TYPE_LEVEL_LOW>; - reset-gpios = <&tlmm 114 GPIO_ACTIVE_HIGH>; - cirrus,temp-warn_threshold = <3>; - cirrus,boost-peak-milliamp = <4000>; - cirrus,boost-ind-nanohenry = <1000>; - cirrus,boost-cap-microfarad = <15>; - cirrus,asp-sdout-hiz = <1>; - cirrus,gpio2-src-select = <4>; - cirrus,gpio2-output-enable; - sound-name-prefix = "BRH"; - #sound-dai-cells = <1>; - }; - - cs35l41_blh: speaker-amp@42 { - compatible = "cirrus,cs35l41"; - reg = <0x42>; - interrupt-parent = <&tlmm>; - interrupts = <112 IRQ_TYPE_LEVEL_LOW>; - reset-gpios = <&tlmm 114 GPIO_ACTIVE_HIGH>; - cirrus,boost-peak-milliamp = <4000>; - cirrus,boost-ind-nanohenry = <1000>; - cirrus,boost-cap-microfarad = <15>; - cirrus,asp-sdout-hiz = <1>; - cirrus,gpio2-src-select = <4>; - cirrus,gpio2-output-enable; - sound-name-prefix = "BLH"; - #sound-dai-cells = <1>; - }; -}; - -&i2c13 { - clock-frequency = <400000>; - status = "okay"; - - touchscreen: fts@49 { - status = "okay"; - compatible = "st,fts"; - reg = <0x49>; - interrupt-parent = <&tlmm>; - interrupts = <39 0x2008>; - pinctrl-names = "pmx_ts_active", "pmx_ts_suspend"; - pinctrl-0 = <&ts_active>; - pinctrl-1 = <&ts_int_suspend &ts_reset_suspend>; - avdd-supply = <&vreg_touch_vddio>; - vdd-supply = <&vreg_l1c_1p8>; - fts,pwr-reg-name = "avdd"; - fts,bus-reg-name = "vdd"; - fts,irq-gpio = <&tlmm 39 0x2008>; - fts,irq-gpio-name = "fts_irq"; - fts,reset-gpio-enable; - fts,reset-gpio = <&tlmm 38 0x00>; - fts,reset-gpio-name = "fts_rst"; - fts,irq-flags = <0x2008>; /* IRQF_ONESHOT | IRQF_TRIGGER_LOW */ - fts,x-max = <1080>; - fts,y-max = <2340>; - // fts,fod-lx = <421>; - // fts,fod-ly = <1788>; - // fts,fod-x-size = <238>; - // fts,fod-y-size = <238>; - fts,default-fw-name = "st_fts_j2.ftb"; - fts,config-array-size = <2>; - fts,dump-click-count; - // fts,support-fod; - fts,touch-up-threshold-min = <40>; - fts,touch-up-threshold-max = <120>; - fts,touch-up-threshold-def = <80>; - fts,touch-tolerance-min = <5>; - fts,touch-tolerance-max = <35>; - fts,touch-tolerance-def = <25>; - fts,touch-idletime-min = <0>; - fts,touch-idletime-max = <12750>; - fts,touch-idletime-def = <12450>; - /*edge filter rects in gamemode*/ - fts,cornerfilter-area-step1 = <100>; - fts,cornerfilter-area-step2 = <170>; - fts,cornerfilter-area-step3 = <250>; - fts,touch-deadzone-filter-ver = <2 0 0 0 0 0 0 0 - 2 1 0 0 0 0 0 0 - 2 2 0 0 5 2339 0 0 - 2 3 1074 0 1079 2339 0 0>; - fts,touch-deadzone-filter-hor = <2 0 0 0 1079 5 0 0 - 2 1 0 2334 1079 2339 0 0 - 2 2 0 0 5 2339 0 0 - 2 3 1074 0 1079 2339 0 0>; - fts,touch-edgezone-filter-ver = <1 0 0 0 0 0 0 0 - 1 1 0 0 0 0 0 0 - 1 2 0 0 40 2339 0 0 - 1 3 1039 0 1079 2339 0 0>; - fts,touch-edgezone-filter-hor = <1 0 0 0 1079 40 0 0 - 1 1 0 2299 1079 2339 0 0 - 1 2 0 0 40 2339 0 0 - 1 3 1039 0 1079 2339 0 0>; - fts,touch-cornerzone-filter-ver = <0 0 0 0 0 0 0 0 - 0 1 0 0 0 0 0 0 - 0 2 0 2039 150 2339 0 0 - 0 3 929 2039 1079 2339 0 0>; - fts,touch-cornerzone-filter-hor1 = <0 0 0 0 170 170 0 0 - 0 1 0 0 0 0 0 0 - 0 2 0 2169 170 2339 0 0 - 0 3 0 0 0 0 0 0>; - fts,touch-cornerzone-filter-hor2 = <0 0 0 0 0 0 0 0 - 0 1 909 0 1079 170 0 0 - 0 2 0 0 0 0 0 0 - 0 3 909 2169 1079 2339 0 0>; - fts,cfg_0 { - fts,tp-vendor = <0x38>; - fts,tp-module = <0>; - fts,fw-name = "st_fts_j2_1.ftb"; - fts,limit-name = "stm_fts_production_limits_1.csv"; - }; - fts,cfg_1 { - fts,tp-vendor = <0x42>; - fts,tp-module = <1>; - fts,fw-name = "st_fts_j2_2.ftb"; - fts,limit-name = "stm_fts_production_limits_2.csv"; - }; - }; -}; - -//TODO: Port the CHARGER Driver -&i2c15{ - status = "disabled"; - - // bq25970: bq25970-standalone@66 { - // compatible = "ti,bq2597x-standalone"; - // reg = <0x66>; - // interrupt-parent = <&tlmm>; - // interrupts = <68 0x2002>; - // pinctrl-names = "default"; - // pinctrl-0 = <&bq2597x_master_int_default>; - - // ti,bq2597x,bat-ovp-alarm-disable; - // ti,bq2597x,bat-ocp-disable; - // ti,bq2597x,bat-ocp-alarm-disable; - // ti,bq2597x,bat-ucp-alarm-disable; - // ti,bq2597x,bat-ucp-disable; - - // ti,bq2597x,bat-therm-disable; - // ti,bq2597x,bus-therm-disable; - // ti,bq2597x,die-therm-disable; - - // ti,bq2597x,bat-ovp-threshold = <4550>; - // ti,bq2597x,bat-ovp-alarm-threshold = <4525>; - - // ti,bq2597x,bus-ovp-threshold = <12000>; - // ti,bq2597x,bus-ovp-alarm-threshold = <11000>; - // ti,bq2597x,bus-ocp-threshold = <3750>; - // ti,bq2597x,bus-ocp-alarm-threshold = <3500>; - - // ti,bq2597x,bat-therm-threshold = <0x15>;/*4.1%*/ - // ti,bq2597x,bus-therm-threshold = <0x15>;/*4.1%*/ - // ti,bq2597x,die-therm-threshold = <145>; - // ti,bq2597x,ac-ovp-threshold = <14>; - // }; -}; - -//TODO: There are some issues with DSC CMD Mode that need to be fixed,https://gitlab.freedesktop.org/drm/msm/-/issues/42 -// &mdss { -// status = "okay"; -// }; - -// &mdss_dsi0 { -// vdda-supply = <&vreg_l9a_1p2>; -// qcom,master-dsi; -// status = "okay"; - -// display_panel: panel@0 { -// reg = <0>; -// vddio-supply = <&vreg_l14a_1p88>; -// reset-gpios = <&tlmm 12 0>; - -// port { -// panel_in: endpoint { -// remote-endpoint = <&mdss_dsi0_out>; -// }; -// }; -// }; -// }; - -// &mdss_dsi0_out { -// data-lanes = <0 1 2 3>; -// remote-endpoint = <&panel_in>; -// }; - -// &mdss_dsi0_phy { -// vdds-supply = <&vreg_l5a_0p88>; -// status = "okay"; -// }; - -&pcie0 { - status = "okay"; -}; - -&pcie0_phy { - vdda-phy-supply = <&vreg_l5a_0p88>; - vdda-pll-supply = <&vreg_l9a_1p2>; - status = "okay"; - - /* Power on QCA639x chip, otherwise PCIe bus timeouts */ - power-domains = <&qca639x>; -}; - -&pm8150_gpios { - vol_up_n: vol-up-n-state { - pins = "gpio6"; - function = "normal"; - power-source = <1>; - input-enable; - bias-pull-up; - }; -}; - -&pon_pwrkey { - status = "okay"; -}; - -&pon_resin { - linux,code = ; - status = "okay"; -}; - -&slpi { - firmware-name = "qcom/sm8250/xiaomi/elish/slpi.mbn"; - status = "disabled"; -}; - -&q6afedai { - dai@20 { - reg = ; - qcom,sd-lines = <0>; - }; -}; - -&q6asmdai { - dai@0 { - reg = <0>; - }; -}; - -&swr1 { - status = "okay"; - - wcd_rx: wcd9380-rx@0,4 { - compatible = "sdw20217010d00"; - reg = <0x0d 0x1170224>; - qcom,rx-port-mapping = <1 2 3 4 5>; - }; -}; - -&swr2 { - status = "okay"; - - wcd_tx: wcd9380-tx@0,3 { - compatible = "sdw20217010d00"; - reg = <0x0d 0x1170223>; - qcom,tx-port-mapping = <2 3 4 5>; - }; -}; - -&sound { - compatible = "qcom,sm8250-sndcard"; - model = "Xiaomi Mi 10"; - pinctrl-names = "default"; - pinctrl-0 = <&tert_mi2s_active>; - - mm1-dai-link { - link-name = "MultiMedia1"; - - cpu { - sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA1>; - }; - }; - - speaker-dai-link { - link-name = "Tertiary MI2S Playback"; - - cpu { - sound-dai = <&q6afedai TERTIARY_MI2S_RX>; - }; - - platform { - sound-dai = <&q6routing>; - }; - - codec { - sound-dai = <&cs35l41_brh 0>, <&cs35l41_blh 0>; - }; - }; -}; - -&tlmm { - gpio-reserved-ranges = <28 4>, <40 4>, <52 4>; - - mdss_te_default: mdss-te-default-state { - pins = "gpio66"; - function = "mdp_vsync"; - drive-strength = <2>; - bias-pull-down; - }; - - bt_en_state: bt-default-state { - bt-en-pins { - pins = "gpio21"; - function = "gpio"; - - drive-strength = <16>; - output-low; - bias-pull-up; - }; - }; - - wlan_en_state: wlan-default-state { - wlan-en-pins { - pins = "gpio20"; - function = "gpio"; - - drive-strength = <16>; - output-low; - bias-pull-up; - }; - }; - - key_confirm: key_confirm_default { - pins = "gpio7"; - function = "normal"; - input-enable; - bias-pull-up; - }; - - ts_active: ts-active { - pins = "gpio38", "gpio39"; - function = "gpio"; - drive-strength = <2>; - bias-pull-up; - }; - - ts_int_suspend: ts-int-suspend { - pins = "gpio39"; - function = "gpio"; - drive-strength = <2>; - bias-pull-down; - }; - - ts_reset_suspend: ts-reset-suspend { - pins = "gpio38"; - function = "gpio"; - drive-strength = <2>; - bias-pull-down; - }; -}; - -&uart6 { - status = "okay"; - - bluetooth { - compatible = "qcom,qca6390-bt"; - - pinctrl-names = "default"; - pinctrl-0 = <&bt_en_state>; - - power-domains = <&qca639x>; - enable-gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>; - swctrl-gpios = <&tlmm 124 GPIO_ACTIVE_HIGH>; - }; -}; - -&ufs_mem_hc { - vcc-supply = <&vreg_l17a_3p0>; - vcc-max-microamp = <800000>; - vccq-supply = <&vreg_l6a_1p2>; - vccq-max-microamp = <800000>; - vccq2-supply = <&vreg_s4a_1p8>; - vccq2-max-microamp = <800000>; - status = "okay"; -}; - -&ufs_mem_phy { - vdda-phy-supply = <&vreg_l5a_0p88>; - vdda-pll-supply = <&vreg_l9a_1p2>; - status = "okay"; -}; - -&usb_1 { - /* USB 2.0 only */ - qcom,select-utmi-as-pipe-clk; - status = "okay"; -}; - -&usb_1_dwc3 { - dr_mode = "otg"; - maximum-speed = "high-speed"; - /* Remove USB3 phy */ - phys = <&usb_1_hsphy>; - phy-names = "usb2-phy"; - usb-role-switch; -}; - -&usb_1_hsphy { - vdda-pll-supply = <&vreg_l5a_0p88>; - vdda18-supply = <&vreg_l12a_1p8>; - vdda33-supply = <&vreg_l2a_3p1>; - status = "okay"; -}; - -&venus { - firmware-name = "qcom/sm8250/xiaomi/elish/venus.mbn"; - status = "okay"; -}; - \ No newline at end of file diff --git a/patch/kernel/archive/sm8250-6.12/dt/sm8250-xiaomi-umi-csot.dts b/patch/kernel/archive/sm8250-6.12/dt/sm8250-xiaomi-umi-csot.dts deleted file mode 100644 index 912471898d53..000000000000 --- a/patch/kernel/archive/sm8250-6.12/dt/sm8250-xiaomi-umi-csot.dts +++ /dev/null @@ -1,13 +0,0 @@ -/dts-v1/; - -#include "sm8250-xiaomi-umi-common.dtsi" - -/ { - model = "Xiaomi Mi 10 (CSOT)"; - compatible = "xiaomi,umi", "qcom,sm8250"; -}; - -// &display_panel { -// compatible = "xiaomi-umi-csot"; -// status = "okay"; -// }; diff --git a/patch/kernel/archive/sm8250-6.12/dt/sm8250-xiaomi-umi-sms.dts b/patch/kernel/archive/sm8250-6.12/dt/sm8250-xiaomi-umi-sms.dts deleted file mode 100644 index 21223ff425cc..000000000000 --- a/patch/kernel/archive/sm8250-6.12/dt/sm8250-xiaomi-umi-sms.dts +++ /dev/null @@ -1,13 +0,0 @@ -/dts-v1/; - -#include "sm8250-xiaomi-umi-common.dtsi" - -/ { - model = "Xiaomi Mi 10 (SMS)"; - compatible = "xiaomi,umi", "qcom,sm8250"; -}; - -// &display_panel { -// compatible = "xiaomi-umi-sms"; -// status = "okay"; -// };