diff options
author | Mike Pagano <mpagano@gentoo.org> | 2024-08-03 11:22:30 -0400 |
---|---|---|
committer | Mike Pagano <mpagano@gentoo.org> | 2024-08-03 11:22:30 -0400 |
commit | 0fa3c6801dc634944e162c6b16a89f5b8cf7adc0 (patch) | |
tree | ad58ac3b8ec50caad15a1c964d340f3dbf109330 | |
parent | Linux patch 6.6.43 (diff) | |
download | linux-patches-0fa3c6801dc634944e162c6b16a89f5b8cf7adc0.tar.gz linux-patches-0fa3c6801dc634944e162c6b16a89f5b8cf7adc0.tar.bz2 linux-patches-0fa3c6801dc634944e162c6b16a89f5b8cf7adc0.zip |
Linnux patch 6.6.44, and addtional patch6.6-51
Add jump label fix patch thanks to Holger Hoffstätte
Signed-off-by: Mike Pagano <mpagano@gentoo.org>
-rw-r--r-- | 0000_README | 8 | ||||
-rw-r--r-- | 1043_linux-6.6.44.patch | 22138 | ||||
-rw-r--r-- | 2950_jump-label-fix.patch | 57 |
3 files changed, 22203 insertions, 0 deletions
diff --git a/0000_README b/0000_README index 45e65975..f2b8c71e 100644 --- a/0000_README +++ b/0000_README @@ -215,6 +215,10 @@ Patch: 1042_linux-6.6.43.patch From: https://www.kernel.org Desc: Linux 6.6.43 +Patch: 1043_linux-6.6.44.patch +From: https://www.kernel.org +Desc: Linux 6.6.44 + Patch: 1510_fs-enable-link-security-restrictions-by-default.patch From: http://sources.debian.net/src/linux/3.16.7-ckt4-3/debian/patches/debian/fs-enable-link-security-restrictions-by-default.patch Desc: Enable link security restrictions by default. @@ -267,6 +271,10 @@ Patch: 2932_gcc14-objtool-Fix-calloc-call-for-new-Walloc-size.patch From: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git Desc: objtool: Fix calloc call for new -Walloc-size +Patch: 2950_jump-label-fix.patch +From: https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git/ +Desc: jump_label: Fix a regression + Patch: 3000_Support-printing-firmware-info.patch From: https://bugs.gentoo.org/732852 Desc: Print firmware info (Reqs CONFIG_GENTOO_PRINT_FIRMWARE_INFO). Thanks to Georgy Yakovlev diff --git a/1043_linux-6.6.44.patch b/1043_linux-6.6.44.patch new file mode 100644 index 00000000..06b4a39e --- /dev/null +++ b/1043_linux-6.6.44.patch @@ -0,0 +1,22138 @@ +diff --git a/Documentation/devicetree/bindings/thermal/thermal-zones.yaml b/Documentation/devicetree/bindings/thermal/thermal-zones.yaml +index 4f3acdc4dec0e..98cdd98212c49 100644 +--- a/Documentation/devicetree/bindings/thermal/thermal-zones.yaml ++++ b/Documentation/devicetree/bindings/thermal/thermal-zones.yaml +@@ -49,7 +49,10 @@ properties: + to take when the temperature crosses those thresholds. + + patternProperties: +- "^[a-zA-Z][a-zA-Z0-9\\-]{1,12}-thermal$": ++ # Node name is limited in size due to Linux kernel requirements - 19 ++ # characters in total (see THERMAL_NAME_LENGTH, including terminating NUL ++ # byte): ++ "^[a-zA-Z][a-zA-Z0-9\\-]{1,10}-thermal$": + type: object + description: + Each thermal zone node contains information about how frequently it +diff --git a/Makefile b/Makefile +index 37b5144449a93..2e5d92ce2774d 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 6 + PATCHLEVEL = 6 +-SUBLEVEL = 43 ++SUBLEVEL = 44 + EXTRAVERSION = + NAME = Hurr durr I'ma ninja sloth + +diff --git a/arch/arm/boot/dts/allwinner/Makefile b/arch/arm/boot/dts/allwinner/Makefile +index eebb5a0c873ad..296be33ec9346 100644 +--- a/arch/arm/boot/dts/allwinner/Makefile ++++ b/arch/arm/boot/dts/allwinner/Makefile +@@ -259,68 +259,6 @@ dtb-$(CONFIG_MACH_SUN8I) += \ + sun8i-v3s-licheepi-zero.dtb \ + sun8i-v3s-licheepi-zero-dock.dtb \ + sun8i-v40-bananapi-m2-berry.dtb +-dtb-$(CONFIG_MACH_SUN8I) += \ +- sun8i-a23-evb.dtb \ +- sun8i-a23-gt90h-v4.dtb \ +- sun8i-a23-inet86dz.dtb \ +- sun8i-a23-ippo-q8h-v5.dtb \ +- sun8i-a23-ippo-q8h-v1.2.dtb \ +- sun8i-a23-polaroid-mid2407pxe03.dtb \ +- sun8i-a23-polaroid-mid2809pxe04.dtb \ +- sun8i-a23-q8-tablet.dtb \ +- sun8i-a33-et-q8-v1.6.dtb \ +- sun8i-a33-ga10h-v1.1.dtb \ +- sun8i-a33-inet-d978-rev2.dtb \ +- sun8i-a33-ippo-q8h-v1.2.dtb \ +- sun8i-a33-olinuxino.dtb \ +- sun8i-a33-q8-tablet.dtb \ +- sun8i-a33-sinlinx-sina33.dtb \ +- sun8i-a83t-allwinner-h8homlet-v2.dtb \ +- sun8i-a83t-bananapi-m3.dtb \ +- sun8i-a83t-cubietruck-plus.dtb \ +- sun8i-a83t-tbs-a711.dtb \ +- sun8i-h2-plus-bananapi-m2-zero.dtb \ +- sun8i-h2-plus-libretech-all-h3-cc.dtb \ +- sun8i-h2-plus-orangepi-r1.dtb \ +- sun8i-h2-plus-orangepi-zero.dtb \ +- sun8i-h3-bananapi-m2-plus.dtb \ +- sun8i-h3-bananapi-m2-plus-v1.2.dtb \ +- sun8i-h3-beelink-x2.dtb \ +- sun8i-h3-libretech-all-h3-cc.dtb \ +- sun8i-h3-mapleboard-mp130.dtb \ +- sun8i-h3-nanopi-duo2.dtb \ +- sun8i-h3-nanopi-m1.dtb\ +- \ +- sun8i-h3-nanopi-m1-plus.dtb \ +- sun8i-h3-nanopi-neo.dtb \ +- sun8i-h3-nanopi-neo-air.dtb \ +- sun8i-h3-nanopi-r1.dtb \ +- sun8i-h3-orangepi-2.dtb \ +- sun8i-h3-orangepi-lite.dtb \ +- sun8i-h3-orangepi-one.dtb \ +- sun8i-h3-orangepi-pc.dtb \ +- sun8i-h3-orangepi-pc-plus.dtb \ +- sun8i-h3-orangepi-plus.dtb \ +- sun8i-h3-orangepi-plus2e.dtb \ +- sun8i-h3-orangepi-zero-plus2.dtb \ +- sun8i-h3-rervision-dvk.dtb \ +- sun8i-h3-zeropi.dtb \ +- sun8i-h3-emlid-neutis-n5h3-devboard.dtb \ +- sun8i-r16-bananapi-m2m.dtb \ +- sun8i-r16-nintendo-nes-classic.dtb \ +- sun8i-r16-nintendo-super-nes-classic.dtb \ +- sun8i-r16-parrot.dtb \ +- sun8i-r40-bananapi-m2-ultra.dtb \ +- sun8i-r40-oka40i-c.dtb \ +- sun8i-s3-elimo-initium.dtb \ +- sun8i-s3-lichee-zero-plus.dtb \ +- sun8i-s3-pinecube.dtb \ +- sun8i-t113s-mangopi-mq-r-t113.dtb \ +- sun8i-t3-cqa3t-bv3.dtb \ +- sun8i-v3-sl631-imx179.dtb \ +- sun8i-v3s-licheepi-zero.dtb \ +- sun8i-v3s-licheepi-zero-dock.dtb \ +- sun8i-v40-bananapi-m2-berry.dtb + dtb-$(CONFIG_MACH_SUN9I) += \ + sun9i-a80-optimus.dtb \ + sun9i-a80-cubieboard4.dtb +diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-kontron-samx6i.dtsi b/arch/arm/boot/dts/nxp/imx/imx6q-kontron-samx6i.dtsi +index 4d6a0c3e8455f..ff062f4fd726e 100644 +--- a/arch/arm/boot/dts/nxp/imx/imx6q-kontron-samx6i.dtsi ++++ b/arch/arm/boot/dts/nxp/imx/imx6q-kontron-samx6i.dtsi +@@ -5,31 +5,8 @@ + + #include "imx6q.dtsi" + #include "imx6qdl-kontron-samx6i.dtsi" +-#include <dt-bindings/gpio/gpio.h> + + / { + model = "Kontron SMARC sAMX6i Quad/Dual"; + compatible = "kontron,imx6q-samx6i", "fsl,imx6q"; + }; +- +-/* Quad/Dual SoMs have 3 chip-select signals */ +-&ecspi4 { +- cs-gpios = <&gpio3 24 GPIO_ACTIVE_LOW>, +- <&gpio3 29 GPIO_ACTIVE_LOW>, +- <&gpio3 25 GPIO_ACTIVE_LOW>; +-}; +- +-&pinctrl_ecspi4 { +- fsl,pins = < +- MX6QDL_PAD_EIM_D21__ECSPI4_SCLK 0x100b1 +- MX6QDL_PAD_EIM_D28__ECSPI4_MOSI 0x100b1 +- MX6QDL_PAD_EIM_D22__ECSPI4_MISO 0x100b1 +- +- /* SPI4_IMX_CS2# - connected to internal flash */ +- MX6QDL_PAD_EIM_D24__GPIO3_IO24 0x1b0b0 +- /* SPI4_IMX_CS0# - connected to SMARC SPI0_CS0# */ +- MX6QDL_PAD_EIM_D29__GPIO3_IO29 0x1b0b0 +- /* SPI4_CS3# - connected to SMARC SPI0_CS1# */ +- MX6QDL_PAD_EIM_D25__GPIO3_IO25 0x1b0b0 +- >; +-}; +diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-kontron-samx6i.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-kontron-samx6i.dtsi +index 85aeebc9485dd..668d33d1ff0c1 100644 +--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-kontron-samx6i.dtsi ++++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-kontron-samx6i.dtsi +@@ -244,7 +244,8 @@ &ecspi4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ecspi4>; + cs-gpios = <&gpio3 24 GPIO_ACTIVE_LOW>, +- <&gpio3 29 GPIO_ACTIVE_LOW>; ++ <&gpio3 29 GPIO_ACTIVE_LOW>, ++ <&gpio3 25 GPIO_ACTIVE_LOW>; + status = "okay"; + + /* default boot source: workaround #1 for errata ERR006282 */ +@@ -259,7 +260,7 @@ smarc_flash: flash@0 { + &fec { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_enet>; +- phy-mode = "rgmii"; ++ phy-connection-type = "rgmii-id"; + phy-handle = <ðphy>; + + mdio { +@@ -269,7 +270,7 @@ mdio { + ethphy: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; +- reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>; ++ reset-gpios = <&gpio2 1 GPIO_ACTIVE_LOW>; + reset-assert-us = <1000>; + }; + }; +@@ -464,6 +465,8 @@ MX6QDL_PAD_EIM_D22__ECSPI4_MISO 0x100b1 + MX6QDL_PAD_EIM_D24__GPIO3_IO24 0x1b0b0 + /* SPI_IMX_CS0# - connected to SMARC SPI0_CS0# */ + MX6QDL_PAD_EIM_D29__GPIO3_IO29 0x1b0b0 ++ /* SPI4_CS3# - connected to SMARC SPI0_CS1# */ ++ MX6QDL_PAD_EIM_D25__GPIO3_IO25 0x1b0b0 + >; + }; + +@@ -516,7 +519,7 @@ MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0 + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0 + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0 + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0 +- MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25 0x1b0b0 /* RST_GBE0_PHY# */ ++ MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x1b0b0 /* RST_GBE0_PHY# */ + >; + }; + +@@ -729,7 +732,7 @@ &pcie { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie>; + wake-up-gpio = <&gpio6 18 GPIO_ACTIVE_HIGH>; +- reset-gpio = <&gpio3 13 GPIO_ACTIVE_HIGH>; ++ reset-gpio = <&gpio3 13 GPIO_ACTIVE_LOW>; + }; + + /* LCD_BKLT_PWM */ +@@ -817,5 +820,6 @@ &wdog1 { + /* CPLD is feeded by watchdog (hardwired) */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wdog1>; ++ fsl,ext-reset-output; + status = "okay"; + }; +diff --git a/arch/arm/boot/dts/st/stm32mp151.dtsi b/arch/arm/boot/dts/st/stm32mp151.dtsi +index 61508917521c3..aec7fa5ab5d8c 100644 +--- a/arch/arm/boot/dts/st/stm32mp151.dtsi ++++ b/arch/arm/boot/dts/st/stm32mp151.dtsi +@@ -50,6 +50,7 @@ timer { + <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>; + interrupt-parent = <&intc>; ++ arm,no-tick-in-suspend; + }; + + clocks { +diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c +index cc691b199429c..a42417de53f74 100644 +--- a/arch/arm/mach-pxa/spitz.c ++++ b/arch/arm/mach-pxa/spitz.c +@@ -520,10 +520,8 @@ static struct gpiod_lookup_table spitz_ads7846_gpio_table = { + static struct gpiod_lookup_table spitz_lcdcon_gpio_table = { + .dev_id = "spi2.1", + .table = { +- GPIO_LOOKUP("gpio-pxa", SPITZ_GPIO_BACKLIGHT_CONT, +- "BL_CONT", GPIO_ACTIVE_LOW), +- GPIO_LOOKUP("gpio-pxa", SPITZ_GPIO_BACKLIGHT_ON, +- "BL_ON", GPIO_ACTIVE_HIGH), ++ GPIO_LOOKUP("sharp-scoop.1", 6, "BL_CONT", GPIO_ACTIVE_LOW), ++ GPIO_LOOKUP("sharp-scoop.1", 7, "BL_ON", GPIO_ACTIVE_HIGH), + { }, + }, + }; +@@ -531,10 +529,8 @@ static struct gpiod_lookup_table spitz_lcdcon_gpio_table = { + static struct gpiod_lookup_table akita_lcdcon_gpio_table = { + .dev_id = "spi2.1", + .table = { +- GPIO_LOOKUP("gpio-pxa", AKITA_GPIO_BACKLIGHT_CONT, +- "BL_CONT", GPIO_ACTIVE_LOW), +- GPIO_LOOKUP("gpio-pxa", AKITA_GPIO_BACKLIGHT_ON, +- "BL_ON", GPIO_ACTIVE_HIGH), ++ GPIO_LOOKUP("i2c-max7310", 3, "BL_ON", GPIO_ACTIVE_HIGH), ++ GPIO_LOOKUP("i2c-max7310", 4, "BL_CONT", GPIO_ACTIVE_LOW), + { }, + }, + }; +@@ -941,12 +937,9 @@ static inline void spitz_i2c_init(void) {} + static struct gpiod_lookup_table spitz_audio_gpio_table = { + .dev_id = "spitz-audio", + .table = { +- GPIO_LOOKUP("sharp-scoop.0", SPITZ_GPIO_MUTE_L - SPITZ_SCP_GPIO_BASE, +- "mute-l", GPIO_ACTIVE_HIGH), +- GPIO_LOOKUP("sharp-scoop.0", SPITZ_GPIO_MUTE_R - SPITZ_SCP_GPIO_BASE, +- "mute-r", GPIO_ACTIVE_HIGH), +- GPIO_LOOKUP("sharp-scoop.1", SPITZ_GPIO_MIC_BIAS - SPITZ_SCP2_GPIO_BASE, +- "mic", GPIO_ACTIVE_HIGH), ++ GPIO_LOOKUP("sharp-scoop.0", 3, "mute-l", GPIO_ACTIVE_HIGH), ++ GPIO_LOOKUP("sharp-scoop.0", 4, "mute-r", GPIO_ACTIVE_HIGH), ++ GPIO_LOOKUP("sharp-scoop.1", 8, "mic", GPIO_ACTIVE_HIGH), + { }, + }, + }; +@@ -954,12 +947,9 @@ static struct gpiod_lookup_table spitz_audio_gpio_table = { + static struct gpiod_lookup_table akita_audio_gpio_table = { + .dev_id = "spitz-audio", + .table = { +- GPIO_LOOKUP("sharp-scoop.0", SPITZ_GPIO_MUTE_L - SPITZ_SCP_GPIO_BASE, +- "mute-l", GPIO_ACTIVE_HIGH), +- GPIO_LOOKUP("sharp-scoop.0", SPITZ_GPIO_MUTE_R - SPITZ_SCP_GPIO_BASE, +- "mute-r", GPIO_ACTIVE_HIGH), +- GPIO_LOOKUP("i2c-max7310", AKITA_GPIO_MIC_BIAS - AKITA_IOEXP_GPIO_BASE, +- "mic", GPIO_ACTIVE_HIGH), ++ GPIO_LOOKUP("sharp-scoop.0", 3, "mute-l", GPIO_ACTIVE_HIGH), ++ GPIO_LOOKUP("sharp-scoop.0", 4, "mute-r", GPIO_ACTIVE_HIGH), ++ GPIO_LOOKUP("i2c-max7310", 2, "mic", GPIO_ACTIVE_HIGH), + { }, + }, + }; +diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi +index ff68b911b7297..0ff0d090548d0 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi +@@ -215,6 +215,11 @@ hdmi_tx: hdmi-tx@0 { + #sound-dai-cells = <0>; + status = "disabled"; + ++ assigned-clocks = <&clkc CLKID_HDMI_SEL>, ++ <&clkc CLKID_HDMI>; ++ assigned-clock-parents = <&xtal>, <0>; ++ assigned-clock-rates = <0>, <24000000>; ++ + /* VPU VENC Input */ + hdmi_tx_venc_port: port@0 { + reg = <0>; +diff --git a/arch/arm64/boot/dts/amlogic/meson-g12.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12.dtsi +index 6a1f4dcf64885..7b655e07e80cf 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-g12.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-g12.dtsi +@@ -367,6 +367,10 @@ ðmac { + power-domains = <&pwrc PWRC_G12A_ETH_ID>; + }; + ++&hdmi_tx { ++ power-domains = <&pwrc PWRC_G12A_VPU_ID>; ++}; ++ + &vpu { + power-domains = <&pwrc PWRC_G12A_VPU_ID>; + }; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +index 12ef6e81c8bd6..ed00e67e6923a 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +@@ -311,10 +311,16 @@ &hdmi_tx { + <&reset RESET_HDMI_SYSTEM_RESET>, + <&reset RESET_HDMI_TX>; + reset-names = "hdmitx_apb", "hdmitx", "hdmitx_phy"; +- clocks = <&clkc CLKID_HDMI_PCLK>, +- <&clkc CLKID_CLK81>, ++ clocks = <&clkc CLKID_HDMI>, ++ <&clkc CLKID_HDMI_PCLK>, + <&clkc CLKID_GCLK_VENCI_INT0>; + clock-names = "isfr", "iahb", "venci"; ++ power-domains = <&pwrc PWRC_GXBB_VPU_ID>; ++ ++ assigned-clocks = <&clkc CLKID_HDMI_SEL>, ++ <&clkc CLKID_HDMI>; ++ assigned-clock-parents = <&xtal>, <0>; ++ assigned-clock-rates = <0>, <24000000>; + }; + + &sysctrl { +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +index 17bcfa4702e17..f58d1790de1cb 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +@@ -323,10 +323,16 @@ &hdmi_tx { + <&reset RESET_HDMI_SYSTEM_RESET>, + <&reset RESET_HDMI_TX>; + reset-names = "hdmitx_apb", "hdmitx", "hdmitx_phy"; +- clocks = <&clkc CLKID_HDMI_PCLK>, +- <&clkc CLKID_CLK81>, ++ clocks = <&clkc CLKID_HDMI>, ++ <&clkc CLKID_HDMI_PCLK>, + <&clkc CLKID_GCLK_VENCI_INT0>; + clock-names = "isfr", "iahb", "venci"; ++ power-domains = <&pwrc PWRC_GXBB_VPU_ID>; ++ ++ assigned-clocks = <&clkc CLKID_HDMI_SEL>, ++ <&clkc CLKID_HDMI>; ++ assigned-clock-parents = <&xtal>, <0>; ++ assigned-clock-rates = <0>, <24000000>; + }; + + &sysctrl { +diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi +index 643f94d9d08e1..13e742ba00bea 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi +@@ -339,7 +339,7 @@ tdmin_lb: audio-controller@3c0 { + }; + + spdifin: audio-controller@400 { +- compatible = "amlogic,g12a-spdifin", ++ compatible = "amlogic,sm1-spdifin", + "amlogic,axg-spdifin"; + reg = <0x0 0x400 0x0 0x30>; + #sound-dai-cells = <0>; +@@ -353,7 +353,7 @@ spdifin: audio-controller@400 { + }; + + spdifout_a: audio-controller@480 { +- compatible = "amlogic,g12a-spdifout", ++ compatible = "amlogic,sm1-spdifout", + "amlogic,axg-spdifout"; + reg = <0x0 0x480 0x0 0x50>; + #sound-dai-cells = <0>; +@@ -518,6 +518,10 @@ &gpio_intc { + "amlogic,meson-gpio-intc"; + }; + ++&hdmi_tx { ++ power-domains = <&pwrc PWRC_SM1_VPU_ID>; ++}; ++ + &pcie { + power-domains = <&pwrc PWRC_SM1_PCIE_ID>; + }; +diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi +index 4b50920ac2049..d1488ebfef3f0 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi +@@ -785,6 +785,23 @@ pgc_usb2_phy: power-domain@3 { + reg = <IMX8MP_POWER_DOMAIN_USB2_PHY>; + }; + ++ pgc_mlmix: power-domain@4 { ++ #power-domain-cells = <0>; ++ reg = <IMX8MP_POWER_DOMAIN_MLMIX>; ++ clocks = <&clk IMX8MP_CLK_ML_AXI>, ++ <&clk IMX8MP_CLK_ML_AHB>, ++ <&clk IMX8MP_CLK_NPU_ROOT>; ++ assigned-clocks = <&clk IMX8MP_CLK_ML_CORE>, ++ <&clk IMX8MP_CLK_ML_AXI>, ++ <&clk IMX8MP_CLK_ML_AHB>; ++ assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_800M>, ++ <&clk IMX8MP_SYS_PLL1_800M>, ++ <&clk IMX8MP_SYS_PLL1_800M>; ++ assigned-clock-rates = <800000000>, ++ <800000000>, ++ <300000000>; ++ }; ++ + pgc_audio: power-domain@5 { + #power-domain-cells = <0>; + reg = <IMX8MP_POWER_DOMAIN_AUDIOMIX>; +@@ -817,6 +834,12 @@ pgc_gpumix: power-domain@7 { + assigned-clock-rates = <800000000>, <400000000>; + }; + ++ pgc_vpumix: power-domain@8 { ++ #power-domain-cells = <0>; ++ reg = <IMX8MP_POWER_DOMAIN_VPUMIX>; ++ clocks = <&clk IMX8MP_CLK_VPU_ROOT>; ++ }; ++ + pgc_gpu3d: power-domain@9 { + #power-domain-cells = <0>; + reg = <IMX8MP_POWER_DOMAIN_GPU3D>; +@@ -832,60 +855,64 @@ pgc_mediamix: power-domain@10 { + <&clk IMX8MP_CLK_MEDIA_APB_ROOT>; + }; + +- pgc_mipi_phy2: power-domain@16 { ++ pgc_vpu_g1: power-domain@11 { + #power-domain-cells = <0>; +- reg = <IMX8MP_POWER_DOMAIN_MIPI_PHY2>; ++ power-domains = <&pgc_vpumix>; ++ reg = <IMX8MP_POWER_DOMAIN_VPU_G1>; ++ clocks = <&clk IMX8MP_CLK_VPU_G1_ROOT>; + }; + +- pgc_hsiomix: power-domain@17 { ++ pgc_vpu_g2: power-domain@12 { + #power-domain-cells = <0>; +- reg = <IMX8MP_POWER_DOMAIN_HSIOMIX>; +- clocks = <&clk IMX8MP_CLK_HSIO_AXI>, +- <&clk IMX8MP_CLK_HSIO_ROOT>; +- assigned-clocks = <&clk IMX8MP_CLK_HSIO_AXI>; +- assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_500M>; +- assigned-clock-rates = <500000000>; ++ power-domains = <&pgc_vpumix>; ++ reg = <IMX8MP_POWER_DOMAIN_VPU_G2>; ++ clocks = <&clk IMX8MP_CLK_VPU_G2_ROOT>; ++ + }; + +- pgc_ispdwp: power-domain@18 { ++ pgc_vpu_vc8000e: power-domain@13 { + #power-domain-cells = <0>; +- reg = <IMX8MP_POWER_DOMAIN_MEDIAMIX_ISPDWP>; +- clocks = <&clk IMX8MP_CLK_MEDIA_ISP_ROOT>; ++ power-domains = <&pgc_vpumix>; ++ reg = <IMX8MP_POWER_DOMAIN_VPU_VC8000E>; ++ clocks = <&clk IMX8MP_CLK_VPU_VC8KE_ROOT>; + }; + +- pgc_vpumix: power-domain@19 { ++ pgc_hdmimix: power-domain@14 { + #power-domain-cells = <0>; +- reg = <IMX8MP_POWER_DOMAIN_VPUMIX>; +- clocks = <&clk IMX8MP_CLK_VPU_ROOT>; ++ reg = <IMX8MP_POWER_DOMAIN_HDMIMIX>; ++ clocks = <&clk IMX8MP_CLK_HDMI_ROOT>, ++ <&clk IMX8MP_CLK_HDMI_APB>; ++ assigned-clocks = <&clk IMX8MP_CLK_HDMI_AXI>, ++ <&clk IMX8MP_CLK_HDMI_APB>; ++ assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_500M>, ++ <&clk IMX8MP_SYS_PLL1_133M>; ++ assigned-clock-rates = <500000000>, <133000000>; + }; + +- pgc_vpu_g1: power-domain@20 { ++ pgc_hdmi_phy: power-domain@15 { + #power-domain-cells = <0>; +- power-domains = <&pgc_vpumix>; +- reg = <IMX8MP_POWER_DOMAIN_VPU_G1>; +- clocks = <&clk IMX8MP_CLK_VPU_G1_ROOT>; ++ reg = <IMX8MP_POWER_DOMAIN_HDMI_PHY>; + }; + +- pgc_vpu_g2: power-domain@21 { ++ pgc_mipi_phy2: power-domain@16 { + #power-domain-cells = <0>; +- power-domains = <&pgc_vpumix>; +- reg = <IMX8MP_POWER_DOMAIN_VPU_G2>; +- clocks = <&clk IMX8MP_CLK_VPU_G2_ROOT>; ++ reg = <IMX8MP_POWER_DOMAIN_MIPI_PHY2>; + }; + +- pgc_vpu_vc8000e: power-domain@22 { ++ pgc_hsiomix: power-domain@17 { + #power-domain-cells = <0>; +- power-domains = <&pgc_vpumix>; +- reg = <IMX8MP_POWER_DOMAIN_VPU_VC8000E>; +- clocks = <&clk IMX8MP_CLK_VPU_VC8KE_ROOT>; ++ reg = <IMX8MP_POWER_DOMAIN_HSIOMIX>; ++ clocks = <&clk IMX8MP_CLK_HSIO_AXI>, ++ <&clk IMX8MP_CLK_HSIO_ROOT>; ++ assigned-clocks = <&clk IMX8MP_CLK_HSIO_AXI>; ++ assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_500M>; ++ assigned-clock-rates = <500000000>; + }; + +- pgc_mlmix: power-domain@24 { ++ pgc_ispdwp: power-domain@18 { + #power-domain-cells = <0>; +- reg = <IMX8MP_POWER_DOMAIN_MLMIX>; +- clocks = <&clk IMX8MP_CLK_ML_AXI>, +- <&clk IMX8MP_CLK_ML_AHB>, +- <&clk IMX8MP_CLK_NPU_ROOT>; ++ reg = <IMX8MP_POWER_DOMAIN_MEDIAMIX_ISPDWP>; ++ clocks = <&clk IMX8MP_CLK_MEDIA_ISP_ROOT>; + }; + }; + }; +@@ -1831,6 +1858,27 @@ hsio_blk_ctrl: blk-ctrl@32f10000 { + #power-domain-cells = <1>; + #clock-cells = <0>; + }; ++ ++ hdmi_blk_ctrl: blk-ctrl@32fc0000 { ++ compatible = "fsl,imx8mp-hdmi-blk-ctrl", "syscon"; ++ reg = <0x32fc0000 0x1000>; ++ clocks = <&clk IMX8MP_CLK_HDMI_APB>, ++ <&clk IMX8MP_CLK_HDMI_ROOT>, ++ <&clk IMX8MP_CLK_HDMI_REF_266M>, ++ <&clk IMX8MP_CLK_HDMI_24M>, ++ <&clk IMX8MP_CLK_HDMI_FDCC_TST>; ++ clock-names = "apb", "axi", "ref_266m", "ref_24m", "fdcc"; ++ power-domains = <&pgc_hdmimix>, <&pgc_hdmimix>, ++ <&pgc_hdmimix>, <&pgc_hdmimix>, ++ <&pgc_hdmimix>, <&pgc_hdmimix>, ++ <&pgc_hdmimix>, <&pgc_hdmi_phy>, ++ <&pgc_hdmimix>, <&pgc_hdmimix>; ++ power-domain-names = "bus", "irqsteer", "lcdif", ++ "pai", "pvi", "trng", ++ "hdmi-tx", "hdmi-tx-phy", ++ "hdcp", "hrv"; ++ #power-domain-cells = <1>; ++ }; + }; + + pcie: pcie@33800000 { +@@ -1970,6 +2018,18 @@ vpumix_blk_ctrl: blk-ctrl@38330000 { + interconnect-names = "g1", "g2", "vc8000e"; + }; + ++ npu: npu@38500000 { ++ compatible = "vivante,gc"; ++ reg = <0x38500000 0x200000>; ++ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&clk IMX8MP_CLK_NPU_ROOT>, ++ <&clk IMX8MP_CLK_NPU_ROOT>, ++ <&clk IMX8MP_CLK_ML_AXI>, ++ <&clk IMX8MP_CLK_ML_AHB>; ++ clock-names = "core", "shader", "bus", "reg"; ++ power-domains = <&pgc_mlmix>; ++ }; ++ + gic: interrupt-controller@38800000 { + compatible = "arm,gic-v3"; + reg = <0x38800000 0x10000>, +diff --git a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts +index 7ef517e9e3746..15838c1ee8cc3 100644 +--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts ++++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts +@@ -318,8 +318,8 @@ asm_sel { + /* eMMC is shared pin with parallel NAND */ + emmc_pins_default: emmc-pins-default { + mux { +- function = "emmc", "emmc_rst"; +- groups = "emmc"; ++ function = "emmc"; ++ groups = "emmc", "emmc_rst"; + }; + + /* "NDL0","NDL1","NDL2","NDL3","NDL4","NDL5","NDL6","NDL7", +diff --git a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts +index a75dc63a1362a..0a14ef1da60de 100644 +--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts ++++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts +@@ -244,8 +244,8 @@ &pio { + /* eMMC is shared pin with parallel NAND */ + emmc_pins_default: emmc-pins-default { + mux { +- function = "emmc", "emmc_rst"; +- groups = "emmc"; ++ function = "emmc"; ++ groups = "emmc", "emmc_rst"; + }; + + /* "NDL0","NDL1","NDL2","NDL3","NDL4","NDL5","NDL6","NDL7", +diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-da7219.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-da7219.dtsi +index 2c69e7658dba6..b9a6fd4f86d4a 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-da7219.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-da7219.dtsi +@@ -28,7 +28,7 @@ da7219_aad { + dlg,btn-cfg = <50>; + dlg,mic-det-thr = <500>; + dlg,jack-ins-deb = <20>; +- dlg,jack-det-rate = "32ms_64ms"; ++ dlg,jack-det-rate = "32_64"; + dlg,jack-rem-deb = <1>; + + dlg,a-d-btn-thr = <0xa>; +diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi +index 820260348de9b..32f6899f885ef 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi +@@ -156,21 +156,24 @@ anx_bridge: anx7625@58 { + vdd18-supply = <&pp1800_mipibrdg>; + vdd33-supply = <&vddio_mipibrdg>; + +- #address-cells = <1>; +- #size-cells = <0>; +- port@0 { +- reg = <0>; ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; + +- anx7625_in: endpoint { +- remote-endpoint = <&dsi_out>; ++ port@0 { ++ reg = <0>; ++ ++ anx7625_in: endpoint { ++ remote-endpoint = <&dsi_out>; ++ }; + }; +- }; + +- port@1 { +- reg = <1>; ++ port@1 { ++ reg = <1>; + +- anx7625_out: endpoint { +- remote-endpoint = <&panel_in>; ++ anx7625_out: endpoint { ++ remote-endpoint = <&panel_in>; ++ }; + }; + }; + +diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi +index d846342c1d3b2..2c6587f260f82 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi +@@ -775,7 +775,6 @@ pins-tx { + }; + pins-rts { + pinmux = <PINMUX_GPIO47__FUNC_URTS1>; +- output-enable; + }; + pins-cts { + pinmux = <PINMUX_GPIO46__FUNC_UCTS1>; +@@ -794,7 +793,6 @@ pins-tx { + }; + pins-rts { + pinmux = <PINMUX_GPIO47__FUNC_URTS1>; +- output-enable; + }; + pins-cts { + pinmux = <PINMUX_GPIO46__FUNC_UCTS1>; +diff --git a/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi b/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi +index dc39ebd1bbfc8..6b4b7a7cd35ef 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi +@@ -147,6 +147,7 @@ pp3300_mipibrdg: regulator-3v3-mipibrdg { + regulator-boot-on; + gpio = <&pio 127 GPIO_ACTIVE_HIGH>; + vin-supply = <&pp3300_g>; ++ off-on-delay-us = <500000>; + }; + + /* separately switched 3.3V power rail */ +diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi +index 2bb9d9aa65fed..20e6d90cc4118 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi +@@ -3395,7 +3395,7 @@ vpu1_crit: trip-crit { + }; + }; + +- gpu0-thermal { ++ gpu-thermal { + polling-delay = <1000>; + polling-delay-passive = <250>; + thermal-sensors = <&lvts_ap MT8195_AP_GPU0>; +diff --git a/arch/arm64/boot/dts/qcom/msm8996-xiaomi-common.dtsi b/arch/arm64/boot/dts/qcom/msm8996-xiaomi-common.dtsi +index 06f8ff624181f..d5b35ff0175cd 100644 +--- a/arch/arm64/boot/dts/qcom/msm8996-xiaomi-common.dtsi ++++ b/arch/arm64/boot/dts/qcom/msm8996-xiaomi-common.dtsi +@@ -405,7 +405,6 @@ &usb3_dwc3 { + + &hsusb_phy1 { + status = "okay"; +- extcon = <&typec>; + + vdda-pll-supply = <&vreg_l12a_1p8>; + vdda-phy-dpdm-supply = <&vreg_l24a_3p075>; +diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi +index dd407aa3abfb9..1f7cbb35886db 100644 +--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi ++++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi +@@ -2090,7 +2090,7 @@ ufshc: ufshc@624000 { + <&gcc GCC_UFS_RX_SYMBOL_0_CLK>; + freq-table-hz = + <100000000 200000000>, +- <0 0>, ++ <100000000 200000000>, + <0 0>, + <0 0>, + <0 0>, +diff --git a/arch/arm64/boot/dts/qcom/msm8998.dtsi b/arch/arm64/boot/dts/qcom/msm8998.dtsi +index f91c58c844afd..9c072ce197358 100644 +--- a/arch/arm64/boot/dts/qcom/msm8998.dtsi ++++ b/arch/arm64/boot/dts/qcom/msm8998.dtsi +@@ -1588,7 +1588,6 @@ adreno_smmu: iommu@5040000 { + * SoC VDDMX RPM Power Domain in the Adreno driver. + */ + power-domains = <&gpucc GPU_GX_GDSC>; +- status = "disabled"; + }; + + gpucc: clock-controller@5065000 { +diff --git a/arch/arm64/boot/dts/qcom/qdu1000.dtsi b/arch/arm64/boot/dts/qcom/qdu1000.dtsi +index 1c0e5d271e91b..dbdc06be6260b 100644 +--- a/arch/arm64/boot/dts/qcom/qdu1000.dtsi ++++ b/arch/arm64/boot/dts/qcom/qdu1000.dtsi +@@ -1452,7 +1452,21 @@ system-cache-controller@19200000 { + "llcc_broadcast_base", + "multi_channel_register"; + interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>; +- multi-ch-bit-off = <24 2>; ++ ++ nvmem-cells = <&multi_chan_ddr>; ++ nvmem-cell-names = "multi-chan-ddr"; ++ }; ++ ++ sec_qfprom: efuse@221c8000 { ++ compatible = "qcom,qdu1000-sec-qfprom", "qcom,sec-qfprom"; ++ reg = <0 0x221c8000 0 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ multi_chan_ddr: multi-chan-ddr@12b { ++ reg = <0x12b 0x1>; ++ bits = <0 2>; ++ }; + }; + }; + +diff --git a/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts b/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts +index c8e80bb405e71..5def8c1154ceb 100644 +--- a/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts ++++ b/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts +@@ -364,6 +364,8 @@ vreg_l8a_0p664: l8 { + vreg_l9a_1p8: l9 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2000000>; ++ regulator-always-on; ++ regulator-boot-on; + }; + + vreg_l10a_1p8: l10 { +diff --git a/arch/arm64/boot/dts/qcom/sa8775p.dtsi b/arch/arm64/boot/dts/qcom/sa8775p.dtsi +index 88ef3b5d374b3..44bea063aedba 100644 +--- a/arch/arm64/boot/dts/qcom/sa8775p.dtsi ++++ b/arch/arm64/boot/dts/qcom/sa8775p.dtsi +@@ -2350,6 +2350,7 @@ ethernet1: ethernet@23000000 { + phy-names = "serdes"; + + iommus = <&apps_smmu 0x140 0xf>; ++ dma-coherent; + + snps,tso; + snps,pbl = <32>; +@@ -2383,6 +2384,7 @@ ethernet0: ethernet@23040000 { + phy-names = "serdes"; + + iommus = <&apps_smmu 0x120 0xf>; ++ dma-coherent; + + snps,tso; + snps,pbl = <32>; +diff --git a/arch/arm64/boot/dts/qcom/sc8180x.dtsi b/arch/arm64/boot/dts/qcom/sc8180x.dtsi +index dd207eb81360a..92b85de7706d3 100644 +--- a/arch/arm64/boot/dts/qcom/sc8180x.dtsi ++++ b/arch/arm64/boot/dts/qcom/sc8180x.dtsi +@@ -1853,7 +1853,7 @@ pcie3: pci@1c08000 { + power-domains = <&gcc PCIE_3_GDSC>; + + interconnects = <&aggre2_noc MASTER_PCIE_3 0 &mc_virt SLAVE_EBI_CH0 0>, +- <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_PCIE_0 0>; ++ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_PCIE_3 0>; + interconnect-names = "pcie-mem", "cpu-pcie"; + + phys = <&pcie3_phy>; +@@ -1952,7 +1952,7 @@ pcie1: pci@1c10000 { + power-domains = <&gcc PCIE_1_GDSC>; + + interconnects = <&aggre2_noc MASTER_PCIE_1 0 &mc_virt SLAVE_EBI_CH0 0>, +- <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_PCIE_0 0>; ++ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_PCIE_1 0>; + interconnect-names = "pcie-mem", "cpu-pcie"; + + phys = <&pcie1_phy>; +@@ -2051,7 +2051,7 @@ pcie2: pci@1c18000 { + power-domains = <&gcc PCIE_2_GDSC>; + + interconnects = <&aggre2_noc MASTER_PCIE_2 0 &mc_virt SLAVE_EBI_CH0 0>, +- <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_PCIE_0 0>; ++ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_PCIE_2 0>; + interconnect-names = "pcie-mem", "cpu-pcie"; + + phys = <&pcie2_phy>; +@@ -2093,7 +2093,7 @@ ufs_mem_hc: ufshc@1d84000 { + "jedec,ufs-2.0"; + reg = <0 0x01d84000 0 0x2500>; + interrupts = <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>; +- phys = <&ufs_mem_phy_lanes>; ++ phys = <&ufs_mem_phy>; + phy-names = "ufsphy"; + lanes-per-direction = <2>; + #reset-cells = <1>; +@@ -2132,10 +2132,8 @@ ufs_mem_hc: ufshc@1d84000 { + + ufs_mem_phy: phy-wrapper@1d87000 { + compatible = "qcom,sc8180x-qmp-ufs-phy"; +- reg = <0 0x01d87000 0 0x1c0>; +- #address-cells = <2>; +- #size-cells = <2>; +- ranges; ++ reg = <0 0x01d87000 0 0x1000>; ++ + clocks = <&rpmhcc RPMH_CXO_CLK>, + <&gcc GCC_UFS_PHY_PHY_AUX_CLK>; + clock-names = "ref", +@@ -2143,16 +2141,12 @@ ufs_mem_phy: phy-wrapper@1d87000 { + + resets = <&ufs_mem_hc 0>; + reset-names = "ufsphy"; +- status = "disabled"; + +- ufs_mem_phy_lanes: phy@1d87400 { +- reg = <0 0x01d87400 0 0x108>, +- <0 0x01d87600 0 0x1e0>, +- <0 0x01d87c00 0 0x1dc>, +- <0 0x01d87800 0 0x108>, +- <0 0x01d87a00 0 0x1e0>; +- #phy-cells = <0>; +- }; ++ power-domains = <&gcc UFS_PHY_GDSC>; ++ ++ #phy-cells = <0>; ++ ++ status = "disabled"; + }; + + ipa_virt: interconnect@1e00000 { +diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi +index 5bf0d5af452af..9d9b378c07e14 100644 +--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi ++++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi +@@ -2634,6 +2634,8 @@ ufs_mem_phy: phy@1d87000 { + clocks = <&gcc GCC_UFS_MEM_CLKREF_CLK>, + <&gcc GCC_UFS_PHY_PHY_AUX_CLK>; + ++ power-domains = <&gcc UFS_PHY_GDSC>; ++ + resets = <&ufs_mem_hc 0>; + reset-names = "ufsphy"; + status = "disabled"; +diff --git a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts +index 92a812b5f4238..fe5c12da666e4 100644 +--- a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts ++++ b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts +@@ -488,6 +488,7 @@ ecsh: hid@5c { + &ipa { + qcom,gsi-loader = "self"; + memory-region = <&ipa_fw_mem>; ++ firmware-name = "qcom/sdm850/LENOVO/81JL/ipa_fws.elf"; + status = "okay"; + }; + +diff --git a/arch/arm64/boot/dts/qcom/sm6115.dtsi b/arch/arm64/boot/dts/qcom/sm6115.dtsi +index 87cbc4e8b1ed5..821db9b851855 100644 +--- a/arch/arm64/boot/dts/qcom/sm6115.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm6115.dtsi +@@ -1043,6 +1043,8 @@ ufs_mem_phy: phy@4807000 { + clocks = <&gcc GCC_UFS_CLKREF_CLK>, <&gcc GCC_UFS_PHY_PHY_AUX_CLK>; + clock-names = "ref", "ref_aux"; + ++ power-domains = <&gcc GCC_UFS_PHY_GDSC>; ++ + resets = <&ufs_mem_hc 0>; + reset-names = "ufsphy"; + status = "disabled"; +diff --git a/arch/arm64/boot/dts/qcom/sm6350.dtsi b/arch/arm64/boot/dts/qcom/sm6350.dtsi +index 71ccda7389ee1..2efceb49a3218 100644 +--- a/arch/arm64/boot/dts/qcom/sm6350.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm6350.dtsi +@@ -1197,6 +1197,8 @@ ufs_mem_phy: phy@1d87000 { + clocks = <&gcc GCC_UFS_MEM_CLKREF_CLK>, + <&gcc GCC_UFS_PHY_PHY_AUX_CLK>; + ++ power-domains = <&gcc UFS_PHY_GDSC>; ++ + resets = <&ufs_mem_hc 0>; + reset-names = "ufsphy"; + +@@ -1297,6 +1299,7 @@ fastrpc { + compatible = "qcom,fastrpc"; + qcom,glink-channels = "fastrpcglink-apps-dsp"; + label = "adsp"; ++ qcom,non-secure-domain; + #address-cells = <1>; + #size-cells = <0>; + +@@ -1557,6 +1560,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/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi +index 64a656dcfa1f5..b522d19f3a132 100644 +--- a/arch/arm64/boot/dts/qcom/sm8250.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi +@@ -2169,7 +2169,7 @@ ufs_mem_hc: ufshc@1d84000 { + "jedec,ufs-2.0"; + reg = <0 0x01d84000 0 0x3000>; + interrupts = <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>; +- phys = <&ufs_mem_phy_lanes>; ++ phys = <&ufs_mem_phy>; + phy-names = "ufsphy"; + lanes-per-direction = <2>; + #reset-cells = <1>; +@@ -2217,10 +2217,8 @@ ufs_mem_hc: ufshc@1d84000 { + + ufs_mem_phy: phy@1d87000 { + compatible = "qcom,sm8250-qmp-ufs-phy"; +- reg = <0 0x01d87000 0 0x1c0>; +- #address-cells = <2>; +- #size-cells = <2>; +- ranges; ++ reg = <0 0x01d87000 0 0x1000>; ++ + clock-names = "ref", + "ref_aux"; + clocks = <&rpmhcc RPMH_CXO_CLK>, +@@ -2228,16 +2226,12 @@ ufs_mem_phy: phy@1d87000 { + + resets = <&ufs_mem_hc 0>; + reset-names = "ufsphy"; +- status = "disabled"; + +- ufs_mem_phy_lanes: phy@1d87400 { +- reg = <0 0x01d87400 0 0x16c>, +- <0 0x01d87600 0 0x200>, +- <0 0x01d87c00 0 0x200>, +- <0 0x01d87800 0 0x16c>, +- <0 0x01d87a00 0 0x200>; +- #phy-cells = <0>; +- }; ++ power-domains = <&gcc UFS_PHY_GDSC>; ++ ++ #phy-cells = <0>; ++ ++ status = "disabled"; + }; + + cryptobam: dma-controller@1dc4000 { +diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi +index 5ed464c37422d..d4f1b36c7aebe 100644 +--- a/arch/arm64/boot/dts/qcom/sm8350.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi +@@ -1731,6 +1731,8 @@ ufs_mem_phy: phy@1d87000 { + clocks = <&rpmhcc RPMH_CXO_CLK>, + <&gcc GCC_UFS_PHY_PHY_AUX_CLK>; + ++ power-domains = <&gcc UFS_PHY_GDSC>; ++ + resets = <&ufs_mem_hc 0>; + reset-names = "ufsphy"; + status = "disabled"; +diff --git a/arch/arm64/boot/dts/qcom/sm8450.dtsi b/arch/arm64/boot/dts/qcom/sm8450.dtsi +index 0229bd706a2e9..a34f460240a07 100644 +--- a/arch/arm64/boot/dts/qcom/sm8450.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8450.dtsi +@@ -4200,6 +4200,8 @@ ufs_mem_phy: phy@1d87000 { + <&gcc GCC_UFS_PHY_PHY_AUX_CLK>, + <&gcc GCC_UFS_0_CLKREF_EN>; + ++ power-domains = <&gcc UFS_PHY_GDSC>; ++ + resets = <&ufs_mem_hc 0>; + reset-names = "ufsphy"; + status = "disabled"; +diff --git a/arch/arm64/boot/dts/renesas/r8a779a0.dtsi b/arch/arm64/boot/dts/renesas/r8a779a0.dtsi +index 504ac8c93faf5..84e0eb48a1b8a 100644 +--- a/arch/arm64/boot/dts/renesas/r8a779a0.dtsi ++++ b/arch/arm64/boot/dts/renesas/r8a779a0.dtsi +@@ -2910,6 +2910,9 @@ timer { + interrupts-extended = <&gic GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, + <&gic GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, + <&gic GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, +- <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>; ++ <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>, ++ <&gic GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys", ++ "hyp-virt"; + }; + }; +diff --git a/arch/arm64/boot/dts/renesas/r8a779f0.dtsi b/arch/arm64/boot/dts/renesas/r8a779f0.dtsi +index ecdd5a523fa34..555fff9364e35 100644 +--- a/arch/arm64/boot/dts/renesas/r8a779f0.dtsi ++++ b/arch/arm64/boot/dts/renesas/r8a779f0.dtsi +@@ -1181,7 +1181,10 @@ timer { + interrupts-extended = <&gic GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, + <&gic GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, + <&gic GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, +- <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>; ++ <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>, ++ <&gic GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys", ++ "hyp-virt"; + }; + + ufs30_clk: ufs30-clk { +diff --git a/arch/arm64/boot/dts/renesas/r8a779g0.dtsi b/arch/arm64/boot/dts/renesas/r8a779g0.dtsi +index d7677595204dc..87fbc53316906 100644 +--- a/arch/arm64/boot/dts/renesas/r8a779g0.dtsi ++++ b/arch/arm64/boot/dts/renesas/r8a779g0.dtsi +@@ -2350,6 +2350,9 @@ timer { + interrupts-extended = <&gic GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, + <&gic GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, + <&gic GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, +- <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>; ++ <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>, ++ <&gic GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys", ++ "hyp-virt"; + }; + }; +diff --git a/arch/arm64/boot/dts/renesas/r9a07g043u.dtsi b/arch/arm64/boot/dts/renesas/r9a07g043u.dtsi +index b3f83d0ebcbb5..4b72de43b71cc 100644 +--- a/arch/arm64/boot/dts/renesas/r9a07g043u.dtsi ++++ b/arch/arm64/boot/dts/renesas/r9a07g043u.dtsi +@@ -50,7 +50,10 @@ timer { + interrupts-extended = <&gic GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, + <&gic GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, + <&gic GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, +- <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>; ++ <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>, ++ <&gic GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys", ++ "hyp-virt"; + }; + }; + +diff --git a/arch/arm64/boot/dts/renesas/r9a07g044.dtsi b/arch/arm64/boot/dts/renesas/r9a07g044.dtsi +index 081d8f49db879..a877738c30484 100644 +--- a/arch/arm64/boot/dts/renesas/r9a07g044.dtsi ++++ b/arch/arm64/boot/dts/renesas/r9a07g044.dtsi +@@ -1288,6 +1288,9 @@ timer { + interrupts-extended = <&gic GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, + <&gic GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, + <&gic GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, +- <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>; ++ <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>, ++ <&gic GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys", ++ "hyp-virt"; + }; + }; +diff --git a/arch/arm64/boot/dts/renesas/r9a07g054.dtsi b/arch/arm64/boot/dts/renesas/r9a07g054.dtsi +index 0d327464d2baf..3f01b096cfb71 100644 +--- a/arch/arm64/boot/dts/renesas/r9a07g054.dtsi ++++ b/arch/arm64/boot/dts/renesas/r9a07g054.dtsi +@@ -1295,6 +1295,9 @@ timer { + interrupts-extended = <&gic GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, + <&gic GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, + <&gic GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, +- <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>; ++ <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>, ++ <&gic GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys", ++ "hyp-virt"; + }; + }; +diff --git a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts +index 4f6541262ab84..5ca0cc19f92c8 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts +@@ -17,6 +17,7 @@ aliases { + ethernet0 = &gmac; + mmc0 = &emmc; + mmc1 = &sdmmc; ++ mmc2 = &sdio; + }; + + chosen { +@@ -144,11 +145,25 @@ &emmc { + + &gmac { + clock_in_out = "output"; ++ phy-handle = <&rtl8201f>; + phy-supply = <&vcc_io>; +- snps,reset-gpio = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>; +- snps,reset-active-low; +- snps,reset-delays-us = <0 50000 50000>; + status = "okay"; ++ ++ mdio { ++ compatible = "snps,dwmac-mdio"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ rtl8201f: ethernet-phy@1 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&mac_rst>; ++ reset-assert-us = <20000>; ++ reset-deassert-us = <50000>; ++ reset-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>; ++ }; ++ }; + }; + + &i2c1 { +@@ -159,6 +174,26 @@ &pinctrl { + pinctrl-names = "default"; + pinctrl-0 = <&rtc_32k>; + ++ bluetooth { ++ bt_reg_on: bt-reg-on { ++ rockchip,pins = <4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ bt_wake_host: bt-wake-host { ++ rockchip,pins = <4 RK_PB4 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ ++ host_wake_bt: host-wake-bt { ++ rockchip,pins = <4 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ gmac { ++ mac_rst: mac-rst { ++ rockchip,pins = <0 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ + leds { + green_led: green-led { + rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; +@@ -202,15 +237,31 @@ &sdio { + cap-sd-highspeed; + cap-sdio-irq; + keep-power-in-suspend; +- max-frequency = <1000000>; ++ max-frequency = <100000000>; + mmc-pwrseq = <&sdio_pwrseq>; ++ no-mmc; ++ no-sd; + non-removable; +- sd-uhs-sdr104; ++ sd-uhs-sdr50; ++ vmmc-supply = <&vcc_io>; ++ vqmmc-supply = <&vcc_1v8>; + status = "okay"; ++ ++ rtl8723ds: wifi@1 { ++ reg = <1>; ++ interrupt-parent = <&gpio0>; ++ interrupts = <RK_PA0 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-names = "host-wake"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_host_wake>; ++ }; + }; + + &sdmmc { ++ cap-mmc-highspeed; + cap-sd-highspeed; ++ disable-wp; ++ vmmc-supply = <&vcc_io>; + status = "okay"; + }; + +@@ -229,16 +280,22 @@ u2phy_otg: otg-port { + }; + + &uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_xfer>; + status = "okay"; + }; + + &uart4 { ++ uart-has-rtscts; + status = "okay"; + + bluetooth { +- compatible = "realtek,rtl8723bs-bt"; +- device-wake-gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_HIGH>; ++ compatible = "realtek,rtl8723ds-bt"; ++ device-wake-gpios = <&gpio4 RK_PB2 GPIO_ACTIVE_HIGH>; ++ enable-gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_HIGH>; + host-wake-gpios = <&gpio4 RK_PB4 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&bt_reg_on &bt_wake_host &host_wake_bt>; + }; + }; + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +index 3778fe5c42a4b..126165ba1ea26 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -822,8 +822,8 @@ cru: clock-controller@ff440000 { + <0>, <24000000>, + <24000000>, <24000000>, + <15000000>, <15000000>, +- <100000000>, <100000000>, +- <100000000>, <100000000>, ++ <300000000>, <100000000>, ++ <400000000>, <100000000>, + <50000000>, <100000000>, + <100000000>, <100000000>, + <50000000>, <50000000>, +diff --git a/arch/arm64/boot/dts/rockchip/rk3566-roc-pc.dts b/arch/arm64/boot/dts/rockchip/rk3566-roc-pc.dts +index 938092fce1866..68a72ac24cd4b 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3566-roc-pc.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3566-roc-pc.dts +@@ -268,7 +268,7 @@ rk809: pmic@20 { + vcc9-supply = <&vcc3v3_sys>; + + codec { +- mic-in-differential; ++ rockchip,mic-in-differential; + }; + + regulators { +diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts +index 19f8fc369b130..8c3ab07d38079 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts +@@ -475,7 +475,7 @@ regulator-state-mem { + }; + + codec { +- mic-in-differential; ++ rockchip,mic-in-differential; + }; + }; + }; +diff --git a/arch/arm64/boot/dts/rockchip/rk3568-fastrhino-r66s.dts b/arch/arm64/boot/dts/rockchip/rk3568-fastrhino-r66s.dts +index 58ab7e9971dbc..b5e67990dd0f8 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3568-fastrhino-r66s.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3568-fastrhino-r66s.dts +@@ -11,6 +11,10 @@ aliases { + }; + }; + ++&pmu_io_domains { ++ vccio3-supply = <&vccio_sd>; ++}; ++ + &sdmmc0 { + bus-width = <4>; + cap-mmc-highspeed; +diff --git a/arch/arm64/boot/dts/rockchip/rk3568-fastrhino-r66s.dtsi b/arch/arm64/boot/dts/rockchip/rk3568-fastrhino-r66s.dtsi +index 89e84e3a92629..25c49bdbadbcb 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3568-fastrhino-r66s.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3568-fastrhino-r66s.dtsi +@@ -39,9 +39,9 @@ status_led: led-status { + }; + }; + +- dc_12v: dc-12v-regulator { ++ vcc12v_dcin: vcc12v-dcin-regulator { + compatible = "regulator-fixed"; +- regulator-name = "dc_12v"; ++ regulator-name = "vcc12v_dcin"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <12000000>; +@@ -65,7 +65,7 @@ vcc3v3_sys: vcc3v3-sys-regulator { + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; +- vin-supply = <&dc_12v>; ++ vin-supply = <&vcc12v_dcin>; + }; + + vcc5v0_sys: vcc5v0-sys-regulator { +@@ -75,16 +75,7 @@ vcc5v0_sys: vcc5v0-sys-regulator { + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; +- vin-supply = <&dc_12v>; +- }; +- +- vcc5v0_usb_host: vcc5v0-usb-host-regulator { +- compatible = "regulator-fixed"; +- regulator-name = "vcc5v0_usb_host"; +- regulator-always-on; +- regulator-boot-on; +- regulator-min-microvolt = <5000000>; +- regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc12v_dcin>; + }; + + vcc5v0_usb_otg: vcc5v0-usb-otg-regulator { +@@ -94,8 +85,9 @@ vcc5v0_usb_otg: vcc5v0-usb-otg-regulator { + pinctrl-names = "default"; + pinctrl-0 = <&vcc5v0_usb_otg_en>; + regulator-name = "vcc5v0_usb_otg"; +- regulator-always-on; +- regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc5v0_sys>; + }; + }; + +@@ -123,6 +115,10 @@ &cpu3 { + cpu-supply = <&vdd_cpu>; + }; + ++&display_subsystem { ++ status = "disabled"; ++}; ++ + &gpu { + mali-supply = <&vdd_gpu>; + status = "okay"; +@@ -405,8 +401,8 @@ vcc5v0_usb_otg_en: vcc5v0-usb-otg-en { + &pmu_io_domains { + pmuio1-supply = <&vcc3v3_pmu>; + pmuio2-supply = <&vcc3v3_pmu>; +- vccio1-supply = <&vccio_acodec>; +- vccio3-supply = <&vccio_sd>; ++ vccio1-supply = <&vcc_3v3>; ++ vccio2-supply = <&vcc_1v8>; + vccio4-supply = <&vcc_1v8>; + vccio5-supply = <&vcc_3v3>; + vccio6-supply = <&vcc_1v8>; +@@ -429,28 +425,12 @@ &uart2 { + 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"; + }; +@@ -460,7 +440,7 @@ &usb2phy0 { + }; + + &usb2phy0_host { +- phy-supply = <&vcc5v0_usb_host>; ++ phy-supply = <&vcc5v0_sys>; + status = "okay"; + }; + +diff --git a/arch/arm64/boot/dts/rockchip/rk3568-fastrhino-r68s.dts b/arch/arm64/boot/dts/rockchip/rk3568-fastrhino-r68s.dts +index e1fe5e442689a..ce2a5e1ccefc3 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3568-fastrhino-r68s.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3568-fastrhino-r68s.dts +@@ -39,7 +39,7 @@ &gmac0_tx_bus2 + &gmac0_rx_bus2 + &gmac0_rgmii_clk + &gmac0_rgmii_bus>; +- snps,reset-gpio = <&gpio0 RK_PB0 GPIO_ACTIVE_LOW>; ++ snps,reset-gpio = <&gpio1 RK_PB0 GPIO_ACTIVE_LOW>; + snps,reset-active-low; + /* Reset time is 15ms, 50ms for rtl8211f */ + snps,reset-delays-us = <0 15000 50000>; +@@ -61,7 +61,7 @@ &gmac1m1_tx_bus2 + &gmac1m1_rx_bus2 + &gmac1m1_rgmii_clk + &gmac1m1_rgmii_bus>; +- snps,reset-gpio = <&gpio0 RK_PB1 GPIO_ACTIVE_LOW>; ++ snps,reset-gpio = <&gpio1 RK_PB1 GPIO_ACTIVE_LOW>; + snps,reset-active-low; + /* Reset time is 15ms, 50ms for rtl8211f */ + snps,reset-delays-us = <0 15000 50000>; +@@ -71,18 +71,18 @@ &gmac1m1_rgmii_clk + }; + + &mdio0 { +- rgmii_phy0: ethernet-phy@0 { ++ rgmii_phy0: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; +- reg = <0>; ++ reg = <0x1>; + pinctrl-0 = <ð_phy0_reset_pin>; + pinctrl-names = "default"; + }; + }; + + &mdio1 { +- rgmii_phy1: ethernet-phy@0 { ++ rgmii_phy1: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; +- reg = <0>; ++ reg = <0x1>; + pinctrl-0 = <ð_phy1_reset_pin>; + pinctrl-names = "default"; + }; +@@ -102,6 +102,10 @@ eth_phy1_reset_pin: eth-phy1-reset-pin { + }; + }; + ++&pmu_io_domains { ++ vccio3-supply = <&vcc_3v3>; ++}; ++ + &sdhci { + bus-width = <8>; + max-frequency = <200000000>; +diff --git a/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts b/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts +index e05ab11981f55..17830e8c9a59b 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts +@@ -530,10 +530,6 @@ regulator-state-mem { + }; + }; + }; +- +- codec { +- mic-in-differential; +- }; + }; + }; + +diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi +index 820c98dbccc0a..2f885bc3665b5 100644 +--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi +@@ -749,6 +749,7 @@ vop_mmu: iommu@fe043e00 { + clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>; + clock-names = "aclk", "iface"; + #iommu-cells = <0>; ++ power-domains = <&power RK3568_PD_VO>; + status = "disabled"; + }; + +diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi +index d4f8776c9277a..0a5634ca005df 100644 +--- a/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi ++++ b/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi +@@ -1309,8 +1309,6 @@ &mcasp0 { + 0 0 0 0 + >; + tdm-slots = <2>; +- rx-num-evt = <32>; +- tx-num-evt = <32>; + #sound-dai-cells = <0>; + status = "disabled"; + }; +@@ -1327,8 +1325,6 @@ &mcasp1 { + 0 0 0 0 + >; + tdm-slots = <2>; +- rx-num-evt = <32>; +- tx-num-evt = <32>; + #sound-dai-cells = <0>; + status = "disabled"; + }; +diff --git a/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts b/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts +index 2de74428a8bde..3560349d63051 100644 +--- a/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts ++++ b/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts +@@ -903,6 +903,4 @@ &mcasp1 { + 0 0 0 0 + 0 0 0 0 + >; +- tx-num-evt = <32>; +- rx-num-evt = <32>; + }; +diff --git a/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi b/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi +index 677ff8de4b6ec..0f8c0f6a0f573 100644 +--- a/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi ++++ b/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi +@@ -481,8 +481,6 @@ &mcasp1 { + 0 0 0 0 + 0 0 0 0 + >; +- tx-num-evt = <32>; +- rx-num-evt = <32>; + }; + + &dss { +diff --git a/arch/loongarch/kernel/hw_breakpoint.c b/arch/loongarch/kernel/hw_breakpoint.c +index 621ad7634df71..a6e4b605bfa8d 100644 +--- a/arch/loongarch/kernel/hw_breakpoint.c ++++ b/arch/loongarch/kernel/hw_breakpoint.c +@@ -221,7 +221,7 @@ static int hw_breakpoint_control(struct perf_event *bp, + } + enable = csr_read64(LOONGARCH_CSR_CRMD); + csr_write64(CSR_CRMD_WE | enable, LOONGARCH_CSR_CRMD); +- if (bp->hw.target) ++ if (bp->hw.target && test_tsk_thread_flag(bp->hw.target, TIF_LOAD_WATCH)) + regs->csr_prmd |= CSR_PRMD_PWE; + break; + case HW_BREAKPOINT_UNINSTALL: +diff --git a/arch/loongarch/kernel/ptrace.c b/arch/loongarch/kernel/ptrace.c +index 200109de1971a..19dc6eff45ccc 100644 +--- a/arch/loongarch/kernel/ptrace.c ++++ b/arch/loongarch/kernel/ptrace.c +@@ -589,6 +589,7 @@ static int ptrace_hbp_set_ctrl(unsigned int note_type, + struct perf_event *bp; + struct perf_event_attr attr; + struct arch_hw_breakpoint_ctrl ctrl; ++ struct thread_info *ti = task_thread_info(tsk); + + bp = ptrace_hbp_get_initialised_bp(note_type, tsk, idx); + if (IS_ERR(bp)) +@@ -613,8 +614,10 @@ static int ptrace_hbp_set_ctrl(unsigned int note_type, + if (err) + return err; + attr.disabled = 0; ++ set_ti_thread_flag(ti, TIF_LOAD_WATCH); + } else { + attr.disabled = 1; ++ clear_ti_thread_flag(ti, TIF_LOAD_WATCH); + } + + return modify_user_hw_breakpoint(bp, &attr); +diff --git a/arch/m68k/amiga/config.c b/arch/m68k/amiga/config.c +index 3137b45750dfc..b7cb28f5ee290 100644 +--- a/arch/m68k/amiga/config.c ++++ b/arch/m68k/amiga/config.c +@@ -180,6 +180,15 @@ int __init amiga_parse_bootinfo(const struct bi_record *record) + dev->slotsize = be16_to_cpu(cd->cd_SlotSize); + dev->boardaddr = be32_to_cpu(cd->cd_BoardAddr); + dev->boardsize = be32_to_cpu(cd->cd_BoardSize); ++ ++ /* CS-LAB Warp 1260 workaround */ ++ if (be16_to_cpu(dev->rom.er_Manufacturer) == ZORRO_MANUF(ZORRO_PROD_CSLAB_WARP_1260) && ++ dev->rom.er_Product == ZORRO_PROD(ZORRO_PROD_CSLAB_WARP_1260)) { ++ ++ /* turn off all interrupts */ ++ pr_info("Warp 1260 card detected: applying interrupt storm workaround\n"); ++ *(uint32_t *)(dev->boardaddr + 0x1000) = 0xfff; ++ } + } else + pr_warn("amiga_parse_bootinfo: too many AutoConfig devices\n"); + #endif /* CONFIG_ZORRO */ +diff --git a/arch/m68k/atari/ataints.c b/arch/m68k/atari/ataints.c +index 56f02ea2c248d..715d1e0d973e6 100644 +--- a/arch/m68k/atari/ataints.c ++++ b/arch/m68k/atari/ataints.c +@@ -302,11 +302,7 @@ void __init atari_init_IRQ(void) + + if (ATARIHW_PRESENT(SCU)) { + /* init the SCU if present */ +- tt_scu.sys_mask = 0x10; /* enable VBL (for the cursor) and +- * disable HSYNC interrupts (who +- * needs them?) MFP and SCC are +- * enabled in VME mask +- */ ++ tt_scu.sys_mask = 0x0; /* disable all interrupts */ + tt_scu.vme_mask = 0x60; /* enable MFP and SCC ints */ + } else { + /* If no SCU and no Hades, the HSYNC interrupt needs to be +diff --git a/arch/m68k/include/asm/cmpxchg.h b/arch/m68k/include/asm/cmpxchg.h +index d7f3de9c5d6f7..4ba14f3535fcb 100644 +--- a/arch/m68k/include/asm/cmpxchg.h ++++ b/arch/m68k/include/asm/cmpxchg.h +@@ -32,7 +32,7 @@ static inline unsigned long __arch_xchg(unsigned long x, volatile void * ptr, in + x = tmp; + break; + default: +- tmp = __invalid_xchg_size(x, ptr, size); ++ x = __invalid_xchg_size(x, ptr, size); + break; + } + +diff --git a/arch/mips/boot/dts/loongson/loongson64-2k1000.dtsi b/arch/mips/boot/dts/loongson/loongson64-2k1000.dtsi +index ee3e2153dd13f..c0be84a6e81fd 100644 +--- a/arch/mips/boot/dts/loongson/loongson64-2k1000.dtsi ++++ b/arch/mips/boot/dts/loongson/loongson64-2k1000.dtsi +@@ -23,14 +23,6 @@ cpu0: cpu@0 { + }; + }; + +- memory@200000 { +- compatible = "memory"; +- device_type = "memory"; +- reg = <0x00000000 0x00200000 0x00000000 0x0ee00000>, /* 238 MB at 2 MB */ +- <0x00000000 0x20000000 0x00000000 0x1f000000>, /* 496 MB at 512 MB */ +- <0x00000001 0x10000000 0x00000001 0xb0000000>; /* 6912 MB at 4352MB */ +- }; +- + cpu_clk: cpu_clk { + #clock-cells = <0>; + compatible = "fixed-clock"; +@@ -52,6 +44,13 @@ package0: bus@10000000 { + 0 0x40000000 0 0x40000000 0 0x40000000 + 0xfe 0x00000000 0xfe 0x00000000 0 0x40000000>; + ++ isa@18000000 { ++ compatible = "isa"; ++ #size-cells = <1>; ++ #address-cells = <2>; ++ ranges = <1 0x0 0x0 0x18000000 0x4000>; ++ }; ++ + pm: reset-controller@1fe07000 { + compatible = "loongson,ls2k-pm"; + reg = <0 0x1fe07000 0 0x422>; +@@ -137,7 +136,8 @@ gmac@3,0 { + <13 IRQ_TYPE_LEVEL_LOW>; + interrupt-names = "macirq", "eth_lpi"; + interrupt-parent = <&liointc0>; +- phy-mode = "rgmii"; ++ phy-mode = "rgmii-id"; ++ phy-handle = <&phy1>; + mdio { + #address-cells = <1>; + #size-cells = <0>; +@@ -160,7 +160,8 @@ gmac@3,1 { + <15 IRQ_TYPE_LEVEL_LOW>; + interrupt-names = "macirq", "eth_lpi"; + interrupt-parent = <&liointc0>; +- phy-mode = "rgmii"; ++ phy-mode = "rgmii-id"; ++ phy-handle = <&phy1>; + mdio { + #address-cells = <1>; + #size-cells = <0>; +diff --git a/arch/mips/include/asm/mach-loongson64/boot_param.h b/arch/mips/include/asm/mach-loongson64/boot_param.h +index e007edd6b60a7..9218b3ae33832 100644 +--- a/arch/mips/include/asm/mach-loongson64/boot_param.h ++++ b/arch/mips/include/asm/mach-loongson64/boot_param.h +@@ -42,12 +42,14 @@ enum loongson_cpu_type { + Legacy_1B = 0x5, + Legacy_2G = 0x6, + Legacy_2H = 0x7, ++ Legacy_2K = 0x8, + Loongson_1A = 0x100, + Loongson_1B = 0x101, + Loongson_2E = 0x200, + Loongson_2F = 0x201, + Loongson_2G = 0x202, + Loongson_2H = 0x203, ++ Loongson_2K = 0x204, + Loongson_3A = 0x300, + Loongson_3B = 0x301 + }; +diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h +index 23c67c0871b17..696b40beb774f 100644 +--- a/arch/mips/include/asm/mips-cm.h ++++ b/arch/mips/include/asm/mips-cm.h +@@ -228,6 +228,10 @@ GCR_ACCESSOR_RO(32, 0x0d0, gic_status) + GCR_ACCESSOR_RO(32, 0x0f0, cpc_status) + #define CM_GCR_CPC_STATUS_EX BIT(0) + ++/* GCR_ACCESS - Controls core/IOCU access to GCRs */ ++GCR_ACCESSOR_RW(32, 0x120, access_cm3) ++#define CM_GCR_ACCESS_ACCESSEN GENMASK(7, 0) ++ + /* GCR_L2_CONFIG - Indicates L2 cache configuration when Config5.L2C=1 */ + GCR_ACCESSOR_RW(32, 0x130, l2_config) + #define CM_GCR_L2_CONFIG_BYPASS BIT(20) +diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c +index dd55d59b88db3..d445f8e849abd 100644 +--- a/arch/mips/kernel/smp-cps.c ++++ b/arch/mips/kernel/smp-cps.c +@@ -222,7 +222,10 @@ static void boot_core(unsigned int core, unsigned int vpe_id) + write_gcr_co_reset_ext_base(CM_GCR_Cx_RESET_EXT_BASE_UEB); + + /* Ensure the core can access the GCRs */ +- set_gcr_access(1 << core); ++ if (mips_cm_revision() < CM_REV_CM3) ++ set_gcr_access(1 << core); ++ else ++ set_gcr_access_cm3(1 << core); + + if (mips_cpc_present()) { + /* Reset the core */ +diff --git a/arch/mips/loongson64/env.c b/arch/mips/loongson64/env.c +index ef3750a6ffacf..09ff052698614 100644 +--- a/arch/mips/loongson64/env.c ++++ b/arch/mips/loongson64/env.c +@@ -88,6 +88,12 @@ void __init prom_lefi_init_env(void) + cpu_clock_freq = ecpu->cpu_clock_freq; + loongson_sysconf.cputype = ecpu->cputype; + switch (ecpu->cputype) { ++ case Legacy_2K: ++ case Loongson_2K: ++ smp_group[0] = 0x900000001fe11000; ++ loongson_sysconf.cores_per_node = 2; ++ loongson_sysconf.cores_per_package = 2; ++ break; + case Legacy_3A: + case Loongson_3A: + loongson_sysconf.cores_per_node = 4; +@@ -221,6 +227,8 @@ void __init prom_lefi_init_env(void) + default: + break; + } ++ } else if ((read_c0_prid() & PRID_IMP_MASK) == PRID_IMP_LOONGSON_64R) { ++ loongson_fdt_blob = __dtb_loongson64_2core_2k1000_begin; + } else if ((read_c0_prid() & PRID_IMP_MASK) == PRID_IMP_LOONGSON_64G) { + if (loongson_sysconf.bridgetype == LS7A) + loongson_fdt_blob = __dtb_loongson64g_4core_ls7a_begin; +diff --git a/arch/mips/loongson64/reset.c b/arch/mips/loongson64/reset.c +index e420800043b08..2a8e4cd72605d 100644 +--- a/arch/mips/loongson64/reset.c ++++ b/arch/mips/loongson64/reset.c +@@ -11,6 +11,7 @@ + #include <linux/init.h> + #include <linux/kexec.h> + #include <linux/pm.h> ++#include <linux/reboot.h> + #include <linux/slab.h> + + #include <asm/bootinfo.h> +@@ -21,36 +22,21 @@ + #include <loongson.h> + #include <boot_param.h> + +-static void loongson_restart(char *command) ++static int firmware_restart(struct sys_off_data *unusedd) + { + + void (*fw_restart)(void) = (void *)loongson_sysconf.restart_addr; + + fw_restart(); +- while (1) { +- if (cpu_wait) +- cpu_wait(); +- } ++ return NOTIFY_DONE; + } + +-static void loongson_poweroff(void) ++static int firmware_poweroff(struct sys_off_data *unused) + { + void (*fw_poweroff)(void) = (void *)loongson_sysconf.poweroff_addr; + + fw_poweroff(); +- while (1) { +- if (cpu_wait) +- cpu_wait(); +- } +-} +- +-static void loongson_halt(void) +-{ +- pr_notice("\n\n** You can safely turn off the power now **\n\n"); +- while (1) { +- if (cpu_wait) +- cpu_wait(); +- } ++ return NOTIFY_DONE; + } + + #ifdef CONFIG_KEXEC +@@ -154,9 +140,17 @@ static void loongson_crash_shutdown(struct pt_regs *regs) + + static int __init mips_reboot_setup(void) + { +- _machine_restart = loongson_restart; +- _machine_halt = loongson_halt; +- pm_power_off = loongson_poweroff; ++ if (loongson_sysconf.restart_addr) { ++ register_sys_off_handler(SYS_OFF_MODE_RESTART, ++ SYS_OFF_PRIO_FIRMWARE, ++ firmware_restart, NULL); ++ } ++ ++ if (loongson_sysconf.poweroff_addr) { ++ register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, ++ SYS_OFF_PRIO_FIRMWARE, ++ firmware_poweroff, NULL); ++ } + + #ifdef CONFIG_KEXEC + kexec_argv = kmalloc(KEXEC_ARGV_SIZE, GFP_KERNEL); +diff --git a/arch/mips/loongson64/smp.c b/arch/mips/loongson64/smp.c +index e015a26a40f7a..979993679d913 100644 +--- a/arch/mips/loongson64/smp.c ++++ b/arch/mips/loongson64/smp.c +@@ -466,12 +466,25 @@ static void loongson3_smp_finish(void) + static void __init loongson3_smp_setup(void) + { + int i = 0, num = 0; /* i: physical id, num: logical id */ ++ int max_cpus = 0; + + init_cpu_possible(cpu_none_mask); + ++ for (i = 0; i < ARRAY_SIZE(smp_group); i++) { ++ if (!smp_group[i]) ++ break; ++ max_cpus += loongson_sysconf.cores_per_node; ++ } ++ ++ if (max_cpus < loongson_sysconf.nr_cpus) { ++ pr_err("SMP Groups are less than the number of CPUs\n"); ++ loongson_sysconf.nr_cpus = max_cpus ? max_cpus : 1; ++ } ++ + /* For unified kernel, NR_CPUS is the maximum possible value, + * loongson_sysconf.nr_cpus is the really present value + */ ++ i = 0; + while (i < loongson_sysconf.nr_cpus) { + if (loongson_sysconf.reserved_cpus_mask & (1<<i)) { + /* Reserved physical CPU cores */ +@@ -492,14 +505,14 @@ static void __init loongson3_smp_setup(void) + __cpu_logical_map[num] = -1; + num++; + } +- + csr_ipi_probe(); + ipi_set0_regs_init(); + ipi_clear0_regs_init(); + ipi_status0_regs_init(); + ipi_en0_regs_init(); + ipi_mailbox_buf_init(); +- ipi_write_enable(0); ++ if (smp_group[0]) ++ ipi_write_enable(0); + + cpu_set_core(&cpu_data[0], + cpu_logical_map(0) % loongson_sysconf.cores_per_package); +@@ -818,6 +831,9 @@ static int loongson3_disable_clock(unsigned int cpu) + uint64_t core_id = cpu_core(&cpu_data[cpu]); + uint64_t package_id = cpu_data[cpu].package; + ++ if (!loongson_chipcfg[package_id] || !loongson_freqctrl[package_id]) ++ return 0; ++ + if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) { + LOONGSON_CHIPCFG(package_id) &= ~(1 << (12 + core_id)); + } else { +@@ -832,6 +848,9 @@ static int loongson3_enable_clock(unsigned int cpu) + uint64_t core_id = cpu_core(&cpu_data[cpu]); + uint64_t package_id = cpu_data[cpu].package; + ++ if (!loongson_chipcfg[package_id] || !loongson_freqctrl[package_id]) ++ return 0; ++ + if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) { + LOONGSON_CHIPCFG(package_id) |= 1 << (12 + core_id); + } else { +diff --git a/arch/mips/pci/pcie-octeon.c b/arch/mips/pci/pcie-octeon.c +old mode 100755 +new mode 100644 +diff --git a/arch/mips/sgi-ip30/ip30-console.c b/arch/mips/sgi-ip30/ip30-console.c +index b91f8c4fdc786..a087b7ebe1293 100644 +--- a/arch/mips/sgi-ip30/ip30-console.c ++++ b/arch/mips/sgi-ip30/ip30-console.c +@@ -1,6 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0 + + #include <linux/io.h> ++#include <linux/processor.h> + + #include <asm/sn/ioc3.h> + +diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig +index 722e83edad282..2834a64064970 100644 +--- a/arch/parisc/Kconfig ++++ b/arch/parisc/Kconfig +@@ -83,6 +83,7 @@ config PARISC + select HAVE_SOFTIRQ_ON_OWN_STACK if IRQSTACKS + select TRACE_IRQFLAGS_SUPPORT + select HAVE_FUNCTION_DESCRIPTORS if 64BIT ++ select PCI_MSI_ARCH_FALLBACKS if PCI_MSI + + help + The PA-RISC microprocessor is designed by Hewlett-Packard and used +diff --git a/arch/powerpc/configs/85xx-hw.config b/arch/powerpc/configs/85xx-hw.config +index 524db76f47b73..8aff832173977 100644 +--- a/arch/powerpc/configs/85xx-hw.config ++++ b/arch/powerpc/configs/85xx-hw.config +@@ -24,6 +24,7 @@ CONFIG_FS_ENET=y + CONFIG_FSL_CORENET_CF=y + CONFIG_FSL_DMA=y + CONFIG_FSL_HV_MANAGER=y ++CONFIG_FSL_IFC=y + CONFIG_FSL_PQ_MDIO=y + CONFIG_FSL_RIO=y + CONFIG_FSL_XGMAC_MDIO=y +@@ -58,6 +59,7 @@ CONFIG_INPUT_FF_MEMLESS=m + CONFIG_MARVELL_PHY=y + CONFIG_MDIO_BUS_MUX_GPIO=y + CONFIG_MDIO_BUS_MUX_MMIOREG=y ++CONFIG_MEMORY=y + CONFIG_MMC_SDHCI_OF_ESDHC=y + CONFIG_MMC_SDHCI_PLTFM=y + CONFIG_MMC_SDHCI=y +diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c +index 77364729a1b61..bf6d8ad3819e9 100644 +--- a/arch/powerpc/kernel/prom.c ++++ b/arch/powerpc/kernel/prom.c +@@ -327,6 +327,7 @@ static int __init early_init_dt_scan_cpus(unsigned long node, + void *data) + { + const char *type = of_get_flat_dt_prop(node, "device_type", NULL); ++ const __be32 *cpu_version = NULL; + const __be32 *prop; + const __be32 *intserv; + int i, nthreads; +@@ -410,7 +411,7 @@ static int __init early_init_dt_scan_cpus(unsigned long node, + prop = of_get_flat_dt_prop(node, "cpu-version", NULL); + if (prop && (be32_to_cpup(prop) & 0xff000000) == 0x0f000000) { + identify_cpu(0, be32_to_cpup(prop)); +- seq_buf_printf(&ppc_hw_desc, "0x%04x ", be32_to_cpup(prop)); ++ cpu_version = prop; + } + + check_cpu_feature_properties(node); +@@ -421,6 +422,12 @@ static int __init early_init_dt_scan_cpus(unsigned long node, + } + + identical_pvr_fixup(node); ++ ++ // We can now add the CPU name & PVR to the hardware description ++ seq_buf_printf(&ppc_hw_desc, "%s 0x%04lx ", cur_cpu_spec->cpu_name, mfspr(SPRN_PVR)); ++ if (cpu_version) ++ seq_buf_printf(&ppc_hw_desc, "0x%04x ", be32_to_cpup(cpu_version)); ++ + init_mmu_slb_size(node); + + #ifdef CONFIG_PPC64 +@@ -858,9 +865,6 @@ void __init early_init_devtree(void *params) + + dt_cpu_ftrs_scan(); + +- // We can now add the CPU name & PVR to the hardware description +- seq_buf_printf(&ppc_hw_desc, "%s 0x%04lx ", cur_cpu_spec->cpu_name, mfspr(SPRN_PVR)); +- + /* Retrieve CPU related informations from the flat tree + * (altivec support, boot CPU ID, ...) + */ +diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c +index 0429488ba170d..1bb00c7215440 100644 +--- a/arch/powerpc/kvm/book3s_hv.c ++++ b/arch/powerpc/kvm/book3s_hv.c +@@ -2249,7 +2249,7 @@ static int kvmppc_get_one_reg_hv(struct kvm_vcpu *vcpu, u64 id, + *val = get_reg_val(id, kvmppc_get_siar_hv(vcpu)); + break; + case KVM_REG_PPC_SDAR: +- *val = get_reg_val(id, kvmppc_get_siar_hv(vcpu)); ++ *val = get_reg_val(id, kvmppc_get_sdar_hv(vcpu)); + break; + case KVM_REG_PPC_SIER: + *val = get_reg_val(id, kvmppc_get_sier_hv(vcpu, 0)); +@@ -2484,7 +2484,7 @@ static int kvmppc_set_one_reg_hv(struct kvm_vcpu *vcpu, u64 id, + vcpu->arch.mmcrs = set_reg_val(id, *val); + break; + case KVM_REG_PPC_MMCR3: +- *val = get_reg_val(id, vcpu->arch.mmcr[3]); ++ kvmppc_set_mmcr_hv(vcpu, 3, set_reg_val(id, *val)); + break; + case KVM_REG_PPC_PMC1 ... KVM_REG_PPC_PMC8: + i = id - KVM_REG_PPC_PMC1; +diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c +index 7197c8256668b..6cef200c2404d 100644 +--- a/arch/powerpc/kvm/powerpc.c ++++ b/arch/powerpc/kvm/powerpc.c +@@ -1990,8 +1990,10 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu, + break; + + r = -ENXIO; +- if (!xive_enabled()) ++ if (!xive_enabled()) { ++ fdput(f); + break; ++ } + + r = -EPERM; + dev = kvm_device_from_filp(f.file); +diff --git a/arch/powerpc/mm/nohash/8xx.c b/arch/powerpc/mm/nohash/8xx.c +index a642a79298929..3245016302787 100644 +--- a/arch/powerpc/mm/nohash/8xx.c ++++ b/arch/powerpc/mm/nohash/8xx.c +@@ -92,7 +92,8 @@ static int __ref __early_map_kernel_hugepage(unsigned long va, phys_addr_t pa, + return -EINVAL; + + set_huge_pte_at(&init_mm, va, ptep, +- pte_mkhuge(pfn_pte(pa >> PAGE_SHIFT, prot)), psize); ++ pte_mkhuge(pfn_pte(pa >> PAGE_SHIFT, prot)), ++ 1UL << mmu_psize_to_shift(psize)); + + return 0; + } +diff --git a/arch/powerpc/xmon/ppc-dis.c b/arch/powerpc/xmon/ppc-dis.c +index 75fa98221d485..af105e1bc3fca 100644 +--- a/arch/powerpc/xmon/ppc-dis.c ++++ b/arch/powerpc/xmon/ppc-dis.c +@@ -122,32 +122,21 @@ int print_insn_powerpc (unsigned long insn, unsigned long memaddr) + bool insn_is_short; + ppc_cpu_t dialect; + +- dialect = PPC_OPCODE_PPC | PPC_OPCODE_COMMON +- | PPC_OPCODE_64 | PPC_OPCODE_POWER4 | PPC_OPCODE_ALTIVEC; ++ dialect = PPC_OPCODE_PPC | PPC_OPCODE_COMMON; + +- if (cpu_has_feature(CPU_FTRS_POWER5)) +- dialect |= PPC_OPCODE_POWER5; ++ if (IS_ENABLED(CONFIG_PPC64)) ++ dialect |= PPC_OPCODE_64 | PPC_OPCODE_POWER4 | PPC_OPCODE_CELL | ++ PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | ++ PPC_OPCODE_POWER9; + +- if (cpu_has_feature(CPU_FTRS_CELL)) +- dialect |= (PPC_OPCODE_CELL | PPC_OPCODE_ALTIVEC); ++ if (cpu_has_feature(CPU_FTR_TM)) ++ dialect |= PPC_OPCODE_HTM; + +- if (cpu_has_feature(CPU_FTRS_POWER6)) +- dialect |= (PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_ALTIVEC); ++ if (cpu_has_feature(CPU_FTR_ALTIVEC)) ++ dialect |= PPC_OPCODE_ALTIVEC | PPC_OPCODE_ALTIVEC2; + +- if (cpu_has_feature(CPU_FTRS_POWER7)) +- dialect |= (PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7 +- | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX); +- +- if (cpu_has_feature(CPU_FTRS_POWER8)) +- dialect |= (PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7 +- | PPC_OPCODE_POWER8 | PPC_OPCODE_HTM +- | PPC_OPCODE_ALTIVEC | PPC_OPCODE_ALTIVEC2 | PPC_OPCODE_VSX); +- +- if (cpu_has_feature(CPU_FTRS_POWER9)) +- dialect |= (PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7 +- | PPC_OPCODE_POWER8 | PPC_OPCODE_POWER9 | PPC_OPCODE_HTM +- | PPC_OPCODE_ALTIVEC | PPC_OPCODE_ALTIVEC2 +- | PPC_OPCODE_VSX | PPC_OPCODE_VSX3); ++ if (cpu_has_feature(CPU_FTR_VSX)) ++ dialect |= PPC_OPCODE_VSX | PPC_OPCODE_VSX3; + + /* Get the major opcode of the insn. */ + opcode = NULL; +diff --git a/arch/s390/kernel/perf_cpum_cf.c b/arch/s390/kernel/perf_cpum_cf.c +index 850c11ea631a6..5466e7bada03d 100644 +--- a/arch/s390/kernel/perf_cpum_cf.c ++++ b/arch/s390/kernel/perf_cpum_cf.c +@@ -556,25 +556,31 @@ static int cfdiag_diffctr(struct cpu_cf_events *cpuhw, unsigned long auth) + struct cf_trailer_entry *trailer_start, *trailer_stop; + struct cf_ctrset_entry *ctrstart, *ctrstop; + size_t offset = 0; ++ int i; + +- auth &= (1 << CPUMF_LCCTL_ENABLE_SHIFT) - 1; +- do { ++ for (i = CPUMF_CTR_SET_BASIC; i < CPUMF_CTR_SET_MAX; ++i) { + ctrstart = (struct cf_ctrset_entry *)(cpuhw->start + offset); + ctrstop = (struct cf_ctrset_entry *)(cpuhw->stop + offset); + ++ /* Counter set not authorized */ ++ if (!(auth & cpumf_ctr_ctl[i])) ++ continue; ++ /* Counter set size zero was not saved */ ++ if (!cpum_cf_read_setsize(i)) ++ continue; ++ + if (memcmp(ctrstop, ctrstart, sizeof(*ctrstop))) { + pr_err_once("cpum_cf_diag counter set compare error " + "in set %i\n", ctrstart->set); + return 0; + } +- auth &= ~cpumf_ctr_ctl[ctrstart->set]; + if (ctrstart->def == CF_DIAG_CTRSET_DEF) { + cfdiag_diffctrset((u64 *)(ctrstart + 1), + (u64 *)(ctrstop + 1), ctrstart->ctr); + offset += ctrstart->ctr * sizeof(u64) + + sizeof(*ctrstart); + } +- } while (ctrstart->def && auth); ++ } + + /* Save time_stamp from start of event in stop's trailer */ + trailer_start = (struct cf_trailer_entry *)(cpuhw->start + offset); +diff --git a/arch/s390/kernel/uv.c b/arch/s390/kernel/uv.c +index fc07bc39e6983..81fdee22a497d 100644 +--- a/arch/s390/kernel/uv.c ++++ b/arch/s390/kernel/uv.c +@@ -181,36 +181,36 @@ int uv_convert_owned_from_secure(unsigned long paddr) + } + + /* +- * Calculate the expected ref_count for a page that would otherwise have no ++ * Calculate the expected ref_count for a folio that would otherwise have no + * further pins. This was cribbed from similar functions in other places in + * the kernel, but with some slight modifications. We know that a secure +- * page can not be a huge page for example. ++ * folio can not be a large folio, for example. + */ +-static int expected_page_refs(struct page *page) ++static int expected_folio_refs(struct folio *folio) + { + int res; + +- res = page_mapcount(page); +- if (PageSwapCache(page)) { ++ res = folio_mapcount(folio); ++ if (folio_test_swapcache(folio)) { + res++; +- } else if (page_mapping(page)) { ++ } else if (folio_mapping(folio)) { + res++; +- if (page_has_private(page)) ++ if (folio->private) + res++; + } + return res; + } + +-static int make_page_secure(struct page *page, struct uv_cb_header *uvcb) ++static int make_folio_secure(struct folio *folio, struct uv_cb_header *uvcb) + { + int expected, cc = 0; + +- if (PageWriteback(page)) ++ if (folio_test_writeback(folio)) + return -EAGAIN; +- expected = expected_page_refs(page); +- if (!page_ref_freeze(page, expected)) ++ expected = expected_folio_refs(folio); ++ if (!folio_ref_freeze(folio, expected)) + return -EBUSY; +- set_bit(PG_arch_1, &page->flags); ++ set_bit(PG_arch_1, &folio->flags); + /* + * If the UVC does not succeed or fail immediately, we don't want to + * loop for long, or we might get stall notifications. +@@ -220,9 +220,9 @@ static int make_page_secure(struct page *page, struct uv_cb_header *uvcb) + * -EAGAIN and we let the callers deal with it. + */ + cc = __uv_call(0, (u64)uvcb); +- page_ref_unfreeze(page, expected); ++ folio_ref_unfreeze(folio, expected); + /* +- * Return -ENXIO if the page was not mapped, -EINVAL for other errors. ++ * Return -ENXIO if the folio was not mapped, -EINVAL for other errors. + * If busy or partially completed, return -EAGAIN. + */ + if (cc == UVC_CC_OK) +@@ -277,7 +277,7 @@ int gmap_make_secure(struct gmap *gmap, unsigned long gaddr, void *uvcb) + bool local_drain = false; + spinlock_t *ptelock; + unsigned long uaddr; +- struct page *page; ++ struct folio *folio; + pte_t *ptep; + int rc; + +@@ -306,15 +306,26 @@ int gmap_make_secure(struct gmap *gmap, unsigned long gaddr, void *uvcb) + if (!ptep) + goto out; + if (pte_present(*ptep) && !(pte_val(*ptep) & _PAGE_INVALID) && pte_write(*ptep)) { +- page = pte_page(*ptep); ++ folio = page_folio(pte_page(*ptep)); ++ rc = -EINVAL; ++ if (folio_test_large(folio)) ++ goto unlock; + rc = -EAGAIN; +- if (trylock_page(page)) { ++ if (folio_trylock(folio)) { + if (should_export_before_import(uvcb, gmap->mm)) +- uv_convert_from_secure(page_to_phys(page)); +- rc = make_page_secure(page, uvcb); +- unlock_page(page); ++ uv_convert_from_secure(PFN_PHYS(folio_pfn(folio))); ++ rc = make_folio_secure(folio, uvcb); ++ folio_unlock(folio); + } ++ ++ /* ++ * Once we drop the PTL, the folio may get unmapped and ++ * freed immediately. We need a temporary reference. ++ */ ++ if (rc == -EAGAIN) ++ folio_get(folio); + } ++unlock: + pte_unmap_unlock(ptep, ptelock); + out: + mmap_read_unlock(gmap->mm); +@@ -324,10 +335,11 @@ int gmap_make_secure(struct gmap *gmap, unsigned long gaddr, void *uvcb) + * If we are here because the UVC returned busy or partial + * completion, this is just a useless check, but it is safe. + */ +- wait_on_page_writeback(page); ++ folio_wait_writeback(folio); ++ folio_put(folio); + } else if (rc == -EBUSY) { + /* +- * If we have tried a local drain and the page refcount ++ * If we have tried a local drain and the folio refcount + * still does not match our expected safe value, try with a + * system wide drain. This is needed if the pagevecs holding + * the page are on a different CPU. +@@ -338,7 +350,7 @@ int gmap_make_secure(struct gmap *gmap, unsigned long gaddr, void *uvcb) + return -EAGAIN; + } + /* +- * We are here if the page refcount does not match the ++ * We are here if the folio refcount does not match the + * expected safe value. The main culprits are usually + * pagevecs. With lru_add_drain() we drain the pagevecs + * on the local CPU so that hopefully the refcount will +diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c +index b678295931c31..1a231181a413b 100644 +--- a/arch/s390/mm/fault.c ++++ b/arch/s390/mm/fault.c +@@ -331,14 +331,16 @@ static noinline void do_fault_error(struct pt_regs *regs, vm_fault_t fault) + do_no_context(regs, fault); + else + do_sigsegv(regs, SEGV_MAPERR); +- } else if (fault & VM_FAULT_SIGBUS) { ++ } else if (fault & (VM_FAULT_SIGBUS | VM_FAULT_HWPOISON)) { + /* Kernel mode? Handle exceptions or die */ + if (!user_mode(regs)) + do_no_context(regs, fault); + else + do_sigbus(regs); +- } else ++ } else { ++ pr_emerg("Unexpected fault flags: %08x\n", fault); + BUG(); ++ } + break; + } + } +diff --git a/arch/s390/pci/pci_irq.c b/arch/s390/pci/pci_irq.c +index 0ef83b6ac0db7..84482a9213322 100644 +--- a/arch/s390/pci/pci_irq.c ++++ b/arch/s390/pci/pci_irq.c +@@ -268,33 +268,20 @@ static void zpci_floating_irq_handler(struct airq_struct *airq, + } + } + +-int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) ++static int __alloc_airq(struct zpci_dev *zdev, int msi_vecs, ++ unsigned long *bit) + { +- struct zpci_dev *zdev = to_zpci(pdev); +- unsigned int hwirq, msi_vecs, cpu; +- unsigned long bit; +- struct msi_desc *msi; +- struct msi_msg msg; +- int cpu_addr; +- int rc, irq; +- +- zdev->aisb = -1UL; +- zdev->msi_first_bit = -1U; +- if (type == PCI_CAP_ID_MSI && nvec > 1) +- return 1; +- msi_vecs = min_t(unsigned int, nvec, zdev->max_msi); +- + if (irq_delivery == DIRECTED) { + /* Allocate cpu vector bits */ +- bit = airq_iv_alloc(zpci_ibv[0], msi_vecs); +- if (bit == -1UL) ++ *bit = airq_iv_alloc(zpci_ibv[0], msi_vecs); ++ if (*bit == -1UL) + return -EIO; + } else { + /* Allocate adapter summary indicator bit */ +- bit = airq_iv_alloc_bit(zpci_sbv); +- if (bit == -1UL) ++ *bit = airq_iv_alloc_bit(zpci_sbv); ++ if (*bit == -1UL) + return -EIO; +- zdev->aisb = bit; ++ zdev->aisb = *bit; + + /* Create adapter interrupt vector */ + zdev->aibv = airq_iv_create(msi_vecs, AIRQ_IV_DATA | AIRQ_IV_BITLOCK, NULL); +@@ -302,27 +289,66 @@ int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) + return -ENOMEM; + + /* Wire up shortcut pointer */ +- zpci_ibv[bit] = zdev->aibv; ++ zpci_ibv[*bit] = zdev->aibv; + /* Each function has its own interrupt vector */ +- bit = 0; ++ *bit = 0; + } ++ return 0; ++} + +- /* Request MSI interrupts */ ++int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) ++{ ++ unsigned int hwirq, msi_vecs, irqs_per_msi, i, cpu; ++ struct zpci_dev *zdev = to_zpci(pdev); ++ struct msi_desc *msi; ++ struct msi_msg msg; ++ unsigned long bit; ++ int cpu_addr; ++ int rc, irq; ++ ++ zdev->aisb = -1UL; ++ zdev->msi_first_bit = -1U; ++ ++ msi_vecs = min_t(unsigned int, nvec, zdev->max_msi); ++ if (msi_vecs < nvec) { ++ pr_info("%s requested %d irqs, allocate system limit of %d", ++ pci_name(pdev), nvec, zdev->max_msi); ++ } ++ ++ rc = __alloc_airq(zdev, msi_vecs, &bit); ++ if (rc < 0) ++ return rc; ++ ++ /* ++ * Request MSI interrupts: ++ * When using MSI, nvec_used interrupt sources and their irq ++ * descriptors are controlled through one msi descriptor. ++ * Thus the outer loop over msi descriptors shall run only once, ++ * while two inner loops iterate over the interrupt vectors. ++ * When using MSI-X, each interrupt vector/irq descriptor ++ * is bound to exactly one msi descriptor (nvec_used is one). ++ * So the inner loops are executed once, while the outer iterates ++ * over the MSI-X descriptors. ++ */ + hwirq = bit; + msi_for_each_desc(msi, &pdev->dev, MSI_DESC_NOTASSOCIATED) { +- rc = -EIO; + if (hwirq - bit >= msi_vecs) + break; +- irq = __irq_alloc_descs(-1, 0, 1, 0, THIS_MODULE, +- (irq_delivery == DIRECTED) ? +- msi->affinity : NULL); ++ irqs_per_msi = min_t(unsigned int, msi_vecs, msi->nvec_used); ++ irq = __irq_alloc_descs(-1, 0, irqs_per_msi, 0, THIS_MODULE, ++ (irq_delivery == DIRECTED) ? ++ msi->affinity : NULL); + if (irq < 0) + return -ENOMEM; +- rc = irq_set_msi_desc(irq, msi); +- if (rc) +- return rc; +- irq_set_chip_and_handler(irq, &zpci_irq_chip, +- handle_percpu_irq); ++ ++ for (i = 0; i < irqs_per_msi; i++) { ++ rc = irq_set_msi_desc_off(irq, i, msi); ++ if (rc) ++ return rc; ++ irq_set_chip_and_handler(irq + i, &zpci_irq_chip, ++ handle_percpu_irq); ++ } ++ + msg.data = hwirq - bit; + if (irq_delivery == DIRECTED) { + if (msi->affinity) +@@ -335,31 +361,35 @@ int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) + msg.address_lo |= (cpu_addr << 8); + + for_each_possible_cpu(cpu) { +- airq_iv_set_data(zpci_ibv[cpu], hwirq, irq); ++ for (i = 0; i < irqs_per_msi; i++) ++ airq_iv_set_data(zpci_ibv[cpu], ++ hwirq + i, irq + i); + } + } else { + msg.address_lo = zdev->msi_addr & 0xffffffff; +- airq_iv_set_data(zdev->aibv, hwirq, irq); ++ for (i = 0; i < irqs_per_msi; i++) ++ airq_iv_set_data(zdev->aibv, hwirq + i, irq + i); + } + msg.address_hi = zdev->msi_addr >> 32; + pci_write_msi_msg(irq, &msg); +- hwirq++; ++ hwirq += irqs_per_msi; + } + + zdev->msi_first_bit = bit; +- zdev->msi_nr_irqs = msi_vecs; ++ zdev->msi_nr_irqs = hwirq - bit; + + rc = zpci_set_irq(zdev); + if (rc) + return rc; + +- return (msi_vecs == nvec) ? 0 : msi_vecs; ++ return (zdev->msi_nr_irqs == nvec) ? 0 : zdev->msi_nr_irqs; + } + + void arch_teardown_msi_irqs(struct pci_dev *pdev) + { + struct zpci_dev *zdev = to_zpci(pdev); + struct msi_desc *msi; ++ unsigned int i; + int rc; + + /* Disable interrupts */ +@@ -369,8 +399,10 @@ void arch_teardown_msi_irqs(struct pci_dev *pdev) + + /* Release MSI interrupts */ + msi_for_each_desc(msi, &pdev->dev, MSI_DESC_ASSOCIATED) { +- irq_set_msi_desc(msi->irq, NULL); +- irq_free_desc(msi->irq); ++ for (i = 0; i < msi->nvec_used; i++) { ++ irq_set_msi_desc(msi->irq + i, NULL); ++ irq_free_desc(msi->irq + i); ++ } + msi->msg.address_lo = 0; + msi->msg.address_hi = 0; + msi->msg.data = 0; +diff --git a/arch/sparc/include/asm/oplib_64.h b/arch/sparc/include/asm/oplib_64.h +index a67abebd43592..1b86d02a84556 100644 +--- a/arch/sparc/include/asm/oplib_64.h ++++ b/arch/sparc/include/asm/oplib_64.h +@@ -247,6 +247,7 @@ void prom_sun4v_guest_soft_state(void); + int prom_ihandle2path(int handle, char *buffer, int bufsize); + + /* Client interface level routines. */ ++void prom_cif_init(void *cif_handler); + void p1275_cmd_direct(unsigned long *); + + #endif /* !(__SPARC64_OPLIB_H) */ +diff --git a/arch/sparc/prom/init_64.c b/arch/sparc/prom/init_64.c +index 103aa91043185..f7b8a1a865b8f 100644 +--- a/arch/sparc/prom/init_64.c ++++ b/arch/sparc/prom/init_64.c +@@ -26,9 +26,6 @@ phandle prom_chosen_node; + * routines in the prom library. + * It gets passed the pointer to the PROM vector. + */ +- +-extern void prom_cif_init(void *); +- + void __init prom_init(void *cif_handler) + { + phandle node; +diff --git a/arch/sparc/prom/p1275.c b/arch/sparc/prom/p1275.c +index 889aa602f8d86..51c3f984bbf72 100644 +--- a/arch/sparc/prom/p1275.c ++++ b/arch/sparc/prom/p1275.c +@@ -49,7 +49,7 @@ void p1275_cmd_direct(unsigned long *args) + local_irq_restore(flags); + } + +-void prom_cif_init(void *cif_handler, void *cif_stack) ++void prom_cif_init(void *cif_handler) + { + p1275buf.prom_cif_handler = (void (*)(long *))cif_handler; + } +diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c +index 81405aeab8bf1..ef7b4b911a455 100644 +--- a/arch/um/drivers/ubd_kern.c ++++ b/arch/um/drivers/ubd_kern.c +@@ -456,43 +456,31 @@ static int bulk_req_safe_read( + return n; + } + +-/* Called without dev->lock held, and only in interrupt context. */ +-static void ubd_handler(void) ++static void ubd_end_request(struct io_thread_req *io_req) + { +- int n; +- int count; +- +- while(1){ +- n = bulk_req_safe_read( +- thread_fd, +- irq_req_buffer, +- &irq_remainder, +- &irq_remainder_size, +- UBD_REQ_BUFFER_SIZE +- ); +- if (n < 0) { +- if(n == -EAGAIN) +- break; +- printk(KERN_ERR "spurious interrupt in ubd_handler, " +- "err = %d\n", -n); +- return; +- } +- for (count = 0; count < n/sizeof(struct io_thread_req *); count++) { +- struct io_thread_req *io_req = (*irq_req_buffer)[count]; +- +- if ((io_req->error == BLK_STS_NOTSUPP) && (req_op(io_req->req) == REQ_OP_DISCARD)) { +- blk_queue_max_discard_sectors(io_req->req->q, 0); +- blk_queue_max_write_zeroes_sectors(io_req->req->q, 0); +- } +- blk_mq_end_request(io_req->req, io_req->error); +- kfree(io_req); +- } ++ if (io_req->error == BLK_STS_NOTSUPP) { ++ if (req_op(io_req->req) == REQ_OP_DISCARD) ++ blk_queue_max_discard_sectors(io_req->req->q, 0); ++ else if (req_op(io_req->req) == REQ_OP_WRITE_ZEROES) ++ blk_queue_max_write_zeroes_sectors(io_req->req->q, 0); + } ++ blk_mq_end_request(io_req->req, io_req->error); ++ kfree(io_req); + } + + static irqreturn_t ubd_intr(int irq, void *dev) + { +- ubd_handler(); ++ int len, i; ++ ++ while ((len = bulk_req_safe_read(thread_fd, irq_req_buffer, ++ &irq_remainder, &irq_remainder_size, ++ UBD_REQ_BUFFER_SIZE)) >= 0) { ++ for (i = 0; i < len / sizeof(struct io_thread_req *); i++) ++ ubd_end_request((*irq_req_buffer)[i]); ++ } ++ ++ if (len < 0 && len != -EAGAIN) ++ pr_err("spurious interrupt in %s, err = %d\n", __func__, len); + return IRQ_HANDLED; + } + +diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c +index 3e270da6b6f67..c8c4ef94c753f 100644 +--- a/arch/um/kernel/time.c ++++ b/arch/um/kernel/time.c +@@ -874,9 +874,9 @@ int setup_time_travel_start(char *str) + return 1; + } + +-__setup("time-travel-start", setup_time_travel_start); ++__setup("time-travel-start=", setup_time_travel_start); + __uml_help(setup_time_travel_start, +-"time-travel-start=<seconds>\n" ++"time-travel-start=<nanoseconds>\n" + "Configure the UML instance's wall clock to start at this value rather than\n" + "the host's wall clock at the time of UML boot.\n"); + #endif +diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c +index 24a403a70a020..850d21e6473ee 100644 +--- a/arch/um/os-Linux/signal.c ++++ b/arch/um/os-Linux/signal.c +@@ -8,6 +8,7 @@ + + #include <stdlib.h> + #include <stdarg.h> ++#include <stdbool.h> + #include <errno.h> + #include <signal.h> + #include <string.h> +@@ -65,9 +66,7 @@ static void sig_handler_common(int sig, struct siginfo *si, mcontext_t *mc) + + int signals_enabled; + #ifdef UML_CONFIG_UML_TIME_TRAVEL_SUPPORT +-static int signals_blocked; +-#else +-#define signals_blocked 0 ++static int signals_blocked, signals_blocked_pending; + #endif + static unsigned int signals_pending; + static unsigned int signals_active = 0; +@@ -76,14 +75,27 @@ void sig_handler(int sig, struct siginfo *si, mcontext_t *mc) + { + int enabled = signals_enabled; + +- if ((signals_blocked || !enabled) && (sig == SIGIO)) { ++#ifdef UML_CONFIG_UML_TIME_TRAVEL_SUPPORT ++ if ((signals_blocked || ++ __atomic_load_n(&signals_blocked_pending, __ATOMIC_SEQ_CST)) && ++ (sig == SIGIO)) { ++ /* increment so unblock will do another round */ ++ __atomic_add_fetch(&signals_blocked_pending, 1, ++ __ATOMIC_SEQ_CST); ++ return; ++ } ++#endif ++ ++ if (!enabled && (sig == SIGIO)) { + /* + * In TT_MODE_EXTERNAL, need to still call time-travel +- * handlers unless signals are also blocked for the +- * external time message processing. This will mark +- * signals_pending by itself (only if necessary.) ++ * handlers. This will mark signals_pending by itself ++ * (only if necessary.) ++ * Note we won't get here if signals are hard-blocked ++ * (which is handled above), in that case the hard- ++ * unblock will handle things. + */ +- if (!signals_blocked && time_travel_mode == TT_MODE_EXTERNAL) ++ if (time_travel_mode == TT_MODE_EXTERNAL) + sigio_run_timetravel_handlers(); + else + signals_pending |= SIGIO_MASK; +@@ -380,33 +392,99 @@ int um_set_signals_trace(int enable) + #ifdef UML_CONFIG_UML_TIME_TRAVEL_SUPPORT + void mark_sigio_pending(void) + { ++ /* ++ * It would seem that this should be atomic so ++ * it isn't a read-modify-write with a signal ++ * that could happen in the middle, losing the ++ * value set by the signal. ++ * ++ * However, this function is only called when in ++ * time-travel=ext simulation mode, in which case ++ * the only signal ever pending is SIGIO, which ++ * is blocked while this can be called, and the ++ * timer signal (SIGALRM) cannot happen. ++ */ + signals_pending |= SIGIO_MASK; + } + + void block_signals_hard(void) + { +- if (signals_blocked) +- return; +- signals_blocked = 1; ++ signals_blocked++; + barrier(); + } + + void unblock_signals_hard(void) + { ++ static bool unblocking; ++ + if (!signals_blocked) ++ panic("unblocking signals while not blocked"); ++ ++ if (--signals_blocked) + return; +- /* Must be set to 0 before we check the pending bits etc. */ +- signals_blocked = 0; ++ /* ++ * Must be set to 0 before we check pending so the ++ * SIGIO handler will run as normal unless we're still ++ * going to process signals_blocked_pending. ++ */ + barrier(); + +- if (signals_pending && signals_enabled) { +- /* this is a bit inefficient, but that's not really important */ +- block_signals(); +- unblock_signals(); +- } else if (signals_pending & SIGIO_MASK) { +- /* we need to run time-travel handlers even if not enabled */ +- sigio_run_timetravel_handlers(); ++ /* ++ * Note that block_signals_hard()/unblock_signals_hard() can be called ++ * within the unblock_signals()/sigio_run_timetravel_handlers() below. ++ * This would still be prone to race conditions since it's actually a ++ * call _within_ e.g. vu_req_read_message(), where we observed this ++ * issue, which loops. Thus, if the inner call handles the recorded ++ * pending signals, we can get out of the inner call with the real ++ * signal hander no longer blocked, and still have a race. Thus don't ++ * handle unblocking in the inner call, if it happens, but only in ++ * the outermost call - 'unblocking' serves as an ownership for the ++ * signals_blocked_pending decrement. ++ */ ++ if (unblocking) ++ return; ++ unblocking = true; ++ ++ while (__atomic_load_n(&signals_blocked_pending, __ATOMIC_SEQ_CST)) { ++ if (signals_enabled) { ++ /* signals are enabled so we can touch this */ ++ signals_pending |= SIGIO_MASK; ++ /* ++ * this is a bit inefficient, but that's ++ * not really important ++ */ ++ block_signals(); ++ unblock_signals(); ++ } else { ++ /* ++ * we need to run time-travel handlers even ++ * if not enabled ++ */ ++ sigio_run_timetravel_handlers(); ++ } ++ ++ /* ++ * The decrement of signals_blocked_pending must be atomic so ++ * that the signal handler will either happen before or after ++ * the decrement, not during a read-modify-write: ++ * - If it happens before, it can increment it and we'll ++ * decrement it and do another round in the loop. ++ * - If it happens after it'll see 0 for both signals_blocked ++ * and signals_blocked_pending and thus run the handler as ++ * usual (subject to signals_enabled, but that's unrelated.) ++ * ++ * Note that a call to unblock_signals_hard() within the calls ++ * to unblock_signals() or sigio_run_timetravel_handlers() above ++ * will do nothing due to the 'unblocking' state, so this cannot ++ * underflow as the only one decrementing will be the outermost ++ * one. ++ */ ++ if (__atomic_sub_fetch(&signals_blocked_pending, 1, ++ __ATOMIC_SEQ_CST) < 0) ++ panic("signals_blocked_pending underflow"); + } ++ ++ unblocking = false; + } + #endif + +diff --git a/arch/x86/Kconfig.assembler b/arch/x86/Kconfig.assembler +index 8ad41da301e53..16d0b022d6fff 100644 +--- a/arch/x86/Kconfig.assembler ++++ b/arch/x86/Kconfig.assembler +@@ -26,6 +26,6 @@ config AS_GFNI + Supported by binutils >= 2.30 and LLVM integrated assembler + + config AS_WRUSS +- def_bool $(as-instr,wrussq %rax$(comma)(%rbx)) ++ def_bool $(as-instr64,wrussq %rax$(comma)(%rbx)) + help + Supported by binutils >= 2.31 and LLVM integrated assembler +diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c +index c688cb22dcd6d..8811fedc9776a 100644 +--- a/arch/x86/events/core.c ++++ b/arch/x86/events/core.c +@@ -2547,6 +2547,7 @@ static ssize_t set_attr_rdpmc(struct device *cdev, + struct device_attribute *attr, + const char *buf, size_t count) + { ++ static DEFINE_MUTEX(rdpmc_mutex); + unsigned long val; + ssize_t ret; + +@@ -2560,6 +2561,8 @@ static ssize_t set_attr_rdpmc(struct device *cdev, + if (x86_pmu.attr_rdpmc_broken) + return -ENOTSUPP; + ++ guard(mutex)(&rdpmc_mutex); ++ + if (val != x86_pmu.attr_rdpmc) { + /* + * Changing into or out of never available or always available, +diff --git a/arch/x86/events/intel/cstate.c b/arch/x86/events/intel/cstate.c +index 96fffb2d521d2..cc6609cbfc8da 100644 +--- a/arch/x86/events/intel/cstate.c ++++ b/arch/x86/events/intel/cstate.c +@@ -80,7 +80,7 @@ + * MSR_PKG_C7_RESIDENCY: Package C7 Residency Counter. + * perf code: 0x03 + * Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL,CNL, +- * KBL,CML,ICL,TGL,RKL,ADL,RPL,MTL ++ * KBL,CML,ICL,TGL,RKL + * Scope: Package (physical package) + * MSR_PKG_C8_RESIDENCY: Package C8 Residency Counter. + * perf code: 0x04 +@@ -89,8 +89,7 @@ + * Scope: Package (physical package) + * MSR_PKG_C9_RESIDENCY: Package C9 Residency Counter. + * perf code: 0x05 +- * Available model: HSW ULT,KBL,CNL,CML,ICL,TGL,RKL, +- * ADL,RPL,MTL ++ * Available model: HSW ULT,KBL,CNL,CML,ICL,TGL,RKL + * Scope: Package (physical package) + * MSR_PKG_C10_RESIDENCY: Package C10 Residency Counter. + * perf code: 0x06 +@@ -582,9 +581,7 @@ static const struct cstate_model adl_cstates __initconst = { + .pkg_events = BIT(PERF_CSTATE_PKG_C2_RES) | + BIT(PERF_CSTATE_PKG_C3_RES) | + BIT(PERF_CSTATE_PKG_C6_RES) | +- BIT(PERF_CSTATE_PKG_C7_RES) | + BIT(PERF_CSTATE_PKG_C8_RES) | +- BIT(PERF_CSTATE_PKG_C9_RES) | + BIT(PERF_CSTATE_PKG_C10_RES), + }; + +diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c +index 2b53f696c3c96..b592bed9ebcc4 100644 +--- a/arch/x86/events/intel/ds.c ++++ b/arch/x86/events/intel/ds.c +@@ -1830,8 +1830,12 @@ static void setup_pebs_adaptive_sample_data(struct perf_event *event, + set_linear_ip(regs, basic->ip); + regs->flags = PERF_EFLAGS_EXACT; + +- if ((sample_type & PERF_SAMPLE_WEIGHT_STRUCT) && (x86_pmu.flags & PMU_FL_RETIRE_LATENCY)) +- data->weight.var3_w = format_size >> PEBS_RETIRE_LATENCY_OFFSET & PEBS_LATENCY_MASK; ++ if (sample_type & PERF_SAMPLE_WEIGHT_STRUCT) { ++ if (x86_pmu.flags & PMU_FL_RETIRE_LATENCY) ++ data->weight.var3_w = format_size >> PEBS_RETIRE_LATENCY_OFFSET & PEBS_LATENCY_MASK; ++ else ++ data->weight.var3_w = 0; ++ } + + /* + * The record for MEMINFO is in front of GP +diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c +index 42a55794004a7..cc5c6a3264967 100644 +--- a/arch/x86/events/intel/pt.c ++++ b/arch/x86/events/intel/pt.c +@@ -877,7 +877,7 @@ static void pt_update_head(struct pt *pt) + */ + static void *pt_buffer_region(struct pt_buffer *buf) + { +- return phys_to_virt(TOPA_ENTRY(buf->cur, buf->cur_idx)->base << TOPA_SHIFT); ++ return phys_to_virt((phys_addr_t)TOPA_ENTRY(buf->cur, buf->cur_idx)->base << TOPA_SHIFT); + } + + /** +@@ -989,7 +989,7 @@ pt_topa_entry_for_page(struct pt_buffer *buf, unsigned int pg) + * order allocations, there shouldn't be many of these. + */ + list_for_each_entry(topa, &buf->tables, list) { +- if (topa->offset + topa->size > pg << PAGE_SHIFT) ++ if (topa->offset + topa->size > (unsigned long)pg << PAGE_SHIFT) + goto found; + } + +diff --git a/arch/x86/events/intel/pt.h b/arch/x86/events/intel/pt.h +index 96906a62aacda..f5e46c04c145d 100644 +--- a/arch/x86/events/intel/pt.h ++++ b/arch/x86/events/intel/pt.h +@@ -33,8 +33,8 @@ struct topa_entry { + u64 rsvd2 : 1; + u64 size : 4; + u64 rsvd3 : 2; +- u64 base : 36; +- u64 rsvd4 : 16; ++ u64 base : 40; ++ u64 rsvd4 : 12; + }; + + /* TSC to Core Crystal Clock Ratio */ +diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c +index 49bc27ab26ad0..a8f11e60b9879 100644 +--- a/arch/x86/events/intel/uncore_snbep.c ++++ b/arch/x86/events/intel/uncore_snbep.c +@@ -461,6 +461,7 @@ + #define SPR_UBOX_DID 0x3250 + + /* SPR CHA */ ++#define SPR_CHA_EVENT_MASK_EXT 0xffffffff + #define SPR_CHA_PMON_CTL_TID_EN (1 << 16) + #define SPR_CHA_PMON_EVENT_MASK (SNBEP_PMON_RAW_EVENT_MASK | \ + SPR_CHA_PMON_CTL_TID_EN) +@@ -477,6 +478,7 @@ DEFINE_UNCORE_FORMAT_ATTR(umask_ext, umask, "config:8-15,32-43,45-55"); + DEFINE_UNCORE_FORMAT_ATTR(umask_ext2, umask, "config:8-15,32-57"); + DEFINE_UNCORE_FORMAT_ATTR(umask_ext3, umask, "config:8-15,32-39"); + DEFINE_UNCORE_FORMAT_ATTR(umask_ext4, umask, "config:8-15,32-55"); ++DEFINE_UNCORE_FORMAT_ATTR(umask_ext5, umask, "config:8-15,32-63"); + DEFINE_UNCORE_FORMAT_ATTR(qor, qor, "config:16"); + DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18"); + DEFINE_UNCORE_FORMAT_ATTR(tid_en, tid_en, "config:19"); +@@ -5954,7 +5956,7 @@ static struct intel_uncore_ops spr_uncore_chabox_ops = { + + static struct attribute *spr_uncore_cha_formats_attr[] = { + &format_attr_event.attr, +- &format_attr_umask_ext4.attr, ++ &format_attr_umask_ext5.attr, + &format_attr_tid_en2.attr, + &format_attr_edge.attr, + &format_attr_inv.attr, +@@ -5990,7 +5992,7 @@ ATTRIBUTE_GROUPS(uncore_alias); + static struct intel_uncore_type spr_uncore_chabox = { + .name = "cha", + .event_mask = SPR_CHA_PMON_EVENT_MASK, +- .event_mask_ext = SPR_RAW_EVENT_MASK_EXT, ++ .event_mask_ext = SPR_CHA_EVENT_MASK_EXT, + .num_shared_regs = 1, + .constraints = skx_uncore_chabox_constraints, + .ops = &spr_uncore_chabox_ops, +diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h +index ccba66da7a5d7..257bf2e71d060 100644 +--- a/arch/x86/include/asm/kvm_host.h ++++ b/arch/x86/include/asm/kvm_host.h +@@ -1758,7 +1758,7 @@ struct kvm_x86_nested_ops { + bool (*is_exception_vmexit)(struct kvm_vcpu *vcpu, u8 vector, + u32 error_code); + int (*check_events)(struct kvm_vcpu *vcpu); +- bool (*has_events)(struct kvm_vcpu *vcpu); ++ bool (*has_events)(struct kvm_vcpu *vcpu, bool for_injection); + void (*triple_fault)(struct kvm_vcpu *vcpu); + int (*get_state)(struct kvm_vcpu *vcpu, + struct kvm_nested_state __user *user_kvm_nested_state, +diff --git a/arch/x86/include/asm/shstk.h b/arch/x86/include/asm/shstk.h +index 42fee8959df7b..896909f306e30 100644 +--- a/arch/x86/include/asm/shstk.h ++++ b/arch/x86/include/asm/shstk.h +@@ -21,6 +21,7 @@ unsigned long shstk_alloc_thread_stack(struct task_struct *p, unsigned long clon + void shstk_free(struct task_struct *p); + int setup_signal_shadow_stack(struct ksignal *ksig); + int restore_signal_shadow_stack(void); ++int shstk_update_last_frame(unsigned long val); + #else + static inline long shstk_prctl(struct task_struct *task, int option, + unsigned long arg2) { return -EINVAL; } +@@ -31,6 +32,7 @@ static inline unsigned long shstk_alloc_thread_stack(struct task_struct *p, + static inline void shstk_free(struct task_struct *p) {} + static inline int setup_signal_shadow_stack(struct ksignal *ksig) { return 0; } + static inline int restore_signal_shadow_stack(void) { return 0; } ++static inline int shstk_update_last_frame(unsigned long val) { return 0; } + #endif /* CONFIG_X86_USER_SHADOW_STACK */ + + #endif /* __ASSEMBLY__ */ +diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c +index 87d38f17ff5c9..c13c9cb40b9b4 100644 +--- a/arch/x86/kernel/devicetree.c ++++ b/arch/x86/kernel/devicetree.c +@@ -82,7 +82,7 @@ static int x86_of_pci_irq_enable(struct pci_dev *dev) + + ret = pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); + if (ret) +- return ret; ++ return pcibios_err_to_errno(ret); + if (!pin) + return 0; + +diff --git a/arch/x86/kernel/shstk.c b/arch/x86/kernel/shstk.c +index 59e15dd8d0f86..19e4db582fb69 100644 +--- a/arch/x86/kernel/shstk.c ++++ b/arch/x86/kernel/shstk.c +@@ -577,3 +577,14 @@ long shstk_prctl(struct task_struct *task, int option, unsigned long arg2) + return wrss_control(true); + return -EINVAL; + } ++ ++int shstk_update_last_frame(unsigned long val) ++{ ++ unsigned long ssp; ++ ++ if (!features_enabled(ARCH_SHSTK_SHSTK)) ++ return 0; ++ ++ ssp = get_user_shstk_addr(); ++ return write_user_shstk_64((u64 __user *)ssp, (u64)val); ++} +diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c +index 6c07f6daaa227..6402fb3089d26 100644 +--- a/arch/x86/kernel/uprobes.c ++++ b/arch/x86/kernel/uprobes.c +@@ -1076,8 +1076,13 @@ arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, struct pt_regs + return orig_ret_vaddr; + + nleft = copy_to_user((void __user *)regs->sp, &trampoline_vaddr, rasize); +- if (likely(!nleft)) ++ if (likely(!nleft)) { ++ if (shstk_update_last_frame(trampoline_vaddr)) { ++ force_sig(SIGSEGV); ++ return -1; ++ } + return orig_ret_vaddr; ++ } + + if (nleft != rasize) { + pr_err("return address clobbered: pid=%d, %%sp=%#lx, %%ip=%#lx\n", +diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c +index c5ec0ef51ff78..d1b4a85def0a6 100644 +--- a/arch/x86/kvm/vmx/nested.c ++++ b/arch/x86/kvm/vmx/nested.c +@@ -3962,7 +3962,7 @@ static bool nested_vmx_preemption_timer_pending(struct kvm_vcpu *vcpu) + to_vmx(vcpu)->nested.preemption_timer_expired; + } + +-static bool vmx_has_nested_events(struct kvm_vcpu *vcpu) ++static bool vmx_has_nested_events(struct kvm_vcpu *vcpu, bool for_injection) + { + return nested_vmx_preemption_timer_pending(vcpu) || + to_vmx(vcpu)->nested.mtf_pending; +diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c +index dae499e2da84e..f5f652a546bf2 100644 +--- a/arch/x86/kvm/vmx/vmx.c ++++ b/arch/x86/kvm/vmx/vmx.c +@@ -5048,14 +5048,19 @@ static int vmx_nmi_allowed(struct kvm_vcpu *vcpu, bool for_injection) + return !vmx_nmi_blocked(vcpu); + } + ++bool __vmx_interrupt_blocked(struct kvm_vcpu *vcpu) ++{ ++ return !(vmx_get_rflags(vcpu) & X86_EFLAGS_IF) || ++ (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & ++ (GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS)); ++} ++ + bool vmx_interrupt_blocked(struct kvm_vcpu *vcpu) + { + if (is_guest_mode(vcpu) && nested_exit_on_intr(vcpu)) + return false; + +- return !(vmx_get_rflags(vcpu) & X86_EFLAGS_IF) || +- (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & +- (GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS)); ++ return __vmx_interrupt_blocked(vcpu); + } + + static int vmx_interrupt_allowed(struct kvm_vcpu *vcpu, bool for_injection) +diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h +index c2130d2c8e24b..912b0c4697429 100644 +--- a/arch/x86/kvm/vmx/vmx.h ++++ b/arch/x86/kvm/vmx/vmx.h +@@ -400,6 +400,7 @@ u64 construct_eptp(struct kvm_vcpu *vcpu, hpa_t root_hpa, int root_level); + bool vmx_guest_inject_ac(struct kvm_vcpu *vcpu); + void vmx_update_exception_bitmap(struct kvm_vcpu *vcpu); + bool vmx_nmi_blocked(struct kvm_vcpu *vcpu); ++bool __vmx_interrupt_blocked(struct kvm_vcpu *vcpu); + bool vmx_interrupt_blocked(struct kvm_vcpu *vcpu); + bool vmx_get_nmi_mask(struct kvm_vcpu *vcpu); + void vmx_set_nmi_mask(struct kvm_vcpu *vcpu, bool masked); +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index 9dd4624bdef2d..c7e7ab1593d5b 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -10254,7 +10254,7 @@ static int kvm_check_and_inject_events(struct kvm_vcpu *vcpu, + + if (is_guest_mode(vcpu) && + kvm_x86_ops.nested_ops->has_events && +- kvm_x86_ops.nested_ops->has_events(vcpu)) ++ kvm_x86_ops.nested_ops->has_events(vcpu, true)) + *req_immediate_exit = true; + + /* +@@ -12882,7 +12882,7 @@ static inline bool kvm_vcpu_has_events(struct kvm_vcpu *vcpu) + + if (is_guest_mode(vcpu) && + kvm_x86_ops.nested_ops->has_events && +- kvm_x86_ops.nested_ops->has_events(vcpu)) ++ kvm_x86_ops.nested_ops->has_events(vcpu, false)) + return true; + + if (kvm_xen_has_pending_events(vcpu)) +diff --git a/arch/x86/pci/intel_mid_pci.c b/arch/x86/pci/intel_mid_pci.c +index 8edd622066044..722a33be08a18 100644 +--- a/arch/x86/pci/intel_mid_pci.c ++++ b/arch/x86/pci/intel_mid_pci.c +@@ -233,9 +233,9 @@ static int intel_mid_pci_irq_enable(struct pci_dev *dev) + return 0; + + ret = pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &gsi); +- if (ret < 0) { ++ if (ret) { + dev_warn(&dev->dev, "Failed to read interrupt line: %d\n", ret); +- return ret; ++ return pcibios_err_to_errno(ret); + } + + id = x86_match_cpu(intel_mid_cpu_ids); +diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c +index 652cd53e77f64..0f2fe524f60dc 100644 +--- a/arch/x86/pci/xen.c ++++ b/arch/x86/pci/xen.c +@@ -38,10 +38,10 @@ static int xen_pcifront_enable_irq(struct pci_dev *dev) + u8 gsi; + + rc = pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &gsi); +- if (rc < 0) { ++ if (rc) { + dev_warn(&dev->dev, "Xen PCI: failed to read interrupt line: %d\n", + rc); +- return rc; ++ return pcibios_err_to_errno(rc); + } + /* In PV DomU the Xen PCI backend puts the PIRQ in the interrupt line.*/ + pirq = gsi; +diff --git a/arch/x86/platform/intel/iosf_mbi.c b/arch/x86/platform/intel/iosf_mbi.c +index fdd49d70b4373..c81cea208c2c4 100644 +--- a/arch/x86/platform/intel/iosf_mbi.c ++++ b/arch/x86/platform/intel/iosf_mbi.c +@@ -62,7 +62,7 @@ static int iosf_mbi_pci_read_mdr(u32 mcrx, u32 mcr, u32 *mdr) + + fail_read: + dev_err(&mbi_pdev->dev, "PCI config access failed with %d\n", result); +- return result; ++ return pcibios_err_to_errno(result); + } + + static int iosf_mbi_pci_write_mdr(u32 mcrx, u32 mcr, u32 mdr) +@@ -91,7 +91,7 @@ static int iosf_mbi_pci_write_mdr(u32 mcrx, u32 mcr, u32 mdr) + + fail_write: + dev_err(&mbi_pdev->dev, "PCI config access failed with %d\n", result); +- return result; ++ return pcibios_err_to_errno(result); + } + + int iosf_mbi_read(u8 port, u8 opcode, u32 offset, u32 *mdr) +diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c +index 9bdc3b656b2c4..4c2bf989edafc 100644 +--- a/arch/x86/xen/p2m.c ++++ b/arch/x86/xen/p2m.c +@@ -731,7 +731,7 @@ int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops, + * immediate unmapping. + */ + map_ops[i].status = GNTST_general_error; +- unmap[0].host_addr = map_ops[i].host_addr, ++ unmap[0].host_addr = map_ops[i].host_addr; + unmap[0].handle = map_ops[i].handle; + map_ops[i].handle = INVALID_GRANT_HANDLE; + if (map_ops[i].flags & GNTMAP_device_map) +@@ -741,7 +741,7 @@ int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops, + + if (kmap_ops) { + kmap_ops[i].status = GNTST_general_error; +- unmap[1].host_addr = kmap_ops[i].host_addr, ++ unmap[1].host_addr = kmap_ops[i].host_addr; + unmap[1].handle = kmap_ops[i].handle; + kmap_ops[i].handle = INVALID_GRANT_HANDLE; + if (kmap_ops[i].flags & GNTMAP_device_map) +diff --git a/block/bio-integrity.c b/block/bio-integrity.c +index ec8ac8cf6e1b9..15e444b2fcc12 100644 +--- a/block/bio-integrity.c ++++ b/block/bio-integrity.c +@@ -217,6 +217,7 @@ bool bio_integrity_prep(struct bio *bio) + unsigned long start, end; + unsigned int len, nr_pages; + unsigned int bytes, offset, i; ++ gfp_t gfp = GFP_NOIO; + + if (!bi) + return true; +@@ -239,11 +240,19 @@ bool bio_integrity_prep(struct bio *bio) + if (!bi->profile->generate_fn || + !(bi->flags & BLK_INTEGRITY_GENERATE)) + return true; ++ ++ /* ++ * Zero the memory allocated to not leak uninitialized kernel ++ * memory to disk. For PI this only affects the app tag, but ++ * for non-integrity metadata it affects the entire metadata ++ * buffer. ++ */ ++ gfp |= __GFP_ZERO; + } + + /* Allocate kernel buffer for protection data */ + len = bio_integrity_bytes(bi, bio_sectors(bio)); +- buf = kmalloc(len, GFP_NOIO); ++ buf = kmalloc(len, gfp); + if (unlikely(buf == NULL)) { + printk(KERN_ERR "could not allocate integrity buffer\n"); + goto err_end_io; +diff --git a/block/blk-mq.c b/block/blk-mq.c +index 4c91889affa7c..7cc315527a44c 100644 +--- a/block/blk-mq.c ++++ b/block/blk-mq.c +@@ -447,6 +447,10 @@ static struct request *__blk_mq_alloc_requests(struct blk_mq_alloc_data *data) + if (data->cmd_flags & REQ_NOWAIT) + data->flags |= BLK_MQ_REQ_NOWAIT; + ++retry: ++ data->ctx = blk_mq_get_ctx(q); ++ data->hctx = blk_mq_map_queue(q, data->cmd_flags, data->ctx); ++ + if (q->elevator) { + /* + * All requests use scheduler tags when an I/O scheduler is +@@ -468,13 +472,9 @@ static struct request *__blk_mq_alloc_requests(struct blk_mq_alloc_data *data) + if (ops->limit_depth) + ops->limit_depth(data->cmd_flags, data); + } +- } +- +-retry: +- data->ctx = blk_mq_get_ctx(q); +- data->hctx = blk_mq_map_queue(q, data->cmd_flags, data->ctx); +- if (!(data->rq_flags & RQF_SCHED_TAGS)) ++ } else { + blk_mq_tag_busy(data->hctx); ++ } + + if (data->flags & BLK_MQ_REQ_RESERVED) + data->rq_flags |= RQF_RESV; +diff --git a/block/genhd.c b/block/genhd.c +index 33b1ebf6ef82d..203c880c3e1cd 100644 +--- a/block/genhd.c ++++ b/block/genhd.c +@@ -655,12 +655,12 @@ void del_gendisk(struct gendisk *disk) + */ + if (!test_bit(GD_DEAD, &disk->state)) + blk_report_disk_dead(disk, false); +- __blk_mark_disk_dead(disk); + + /* + * Drop all partitions now that the disk is marked dead. + */ + mutex_lock(&disk->open_mutex); ++ __blk_mark_disk_dead(disk); + xa_for_each_start(&disk->part_tbl, idx, part, 1) + drop_partition(part); + mutex_unlock(&disk->open_mutex); +diff --git a/block/mq-deadline.c b/block/mq-deadline.c +index 02a916ba62ee7..78a8aa204c156 100644 +--- a/block/mq-deadline.c ++++ b/block/mq-deadline.c +@@ -621,6 +621,20 @@ static struct request *dd_dispatch_request(struct blk_mq_hw_ctx *hctx) + return rq; + } + ++/* ++ * 'depth' is a number in the range 1..INT_MAX representing a number of ++ * requests. Scale it with a factor (1 << bt->sb.shift) / q->nr_requests since ++ * 1..(1 << bt->sb.shift) is the range expected by sbitmap_get_shallow(). ++ * Values larger than q->nr_requests have the same effect as q->nr_requests. ++ */ ++static int dd_to_word_depth(struct blk_mq_hw_ctx *hctx, unsigned int qdepth) ++{ ++ struct sbitmap_queue *bt = &hctx->sched_tags->bitmap_tags; ++ const unsigned int nrr = hctx->queue->nr_requests; ++ ++ return ((qdepth << bt->sb.shift) + nrr - 1) / nrr; ++} ++ + /* + * Called by __blk_mq_alloc_request(). The shallow_depth value set by this + * function is used by __blk_mq_get_tag(). +@@ -637,7 +651,7 @@ static void dd_limit_depth(blk_opf_t opf, struct blk_mq_alloc_data *data) + * Throttle asynchronous requests and writes such that these requests + * do not block the allocation of synchronous requests. + */ +- data->shallow_depth = dd->async_depth; ++ data->shallow_depth = dd_to_word_depth(data->hctx, dd->async_depth); + } + + /* Called by blk_mq_update_nr_requests(). */ +@@ -647,9 +661,9 @@ static void dd_depth_updated(struct blk_mq_hw_ctx *hctx) + struct deadline_data *dd = q->elevator->elevator_data; + struct blk_mq_tags *tags = hctx->sched_tags; + +- dd->async_depth = max(1UL, 3 * q->nr_requests / 4); ++ dd->async_depth = q->nr_requests; + +- sbitmap_queue_min_shallow_depth(&tags->bitmap_tags, dd->async_depth); ++ sbitmap_queue_min_shallow_depth(&tags->bitmap_tags, 1); + } + + /* Called by blk_mq_init_hctx() and blk_mq_init_sched(). */ +diff --git a/drivers/android/binder.c b/drivers/android/binder.c +index e67a91120385d..ccaceedbc2c01 100644 +--- a/drivers/android/binder.c ++++ b/drivers/android/binder.c +@@ -570,9 +570,7 @@ static bool binder_has_work(struct binder_thread *thread, bool do_proc_work) + static bool binder_available_for_proc_work_ilocked(struct binder_thread *thread) + { + return !thread->transaction_stack && +- binder_worklist_empty_ilocked(&thread->todo) && +- (thread->looper & (BINDER_LOOPER_STATE_ENTERED | +- BINDER_LOOPER_STATE_REGISTERED)); ++ binder_worklist_empty_ilocked(&thread->todo); + } + + static void binder_wakeup_poll_threads_ilocked(struct binder_proc *proc, +diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c +index 0e078bf5aba0e..77dbd516a0546 100644 +--- a/drivers/ata/libata-scsi.c ++++ b/drivers/ata/libata-scsi.c +@@ -230,6 +230,80 @@ void ata_scsi_set_sense_information(struct ata_device *dev, + SCSI_SENSE_BUFFERSIZE, information); + } + ++/** ++ * ata_scsi_set_passthru_sense_fields - Set ATA fields in sense buffer ++ * @qc: ATA PASS-THROUGH command. ++ * ++ * Populates "ATA Status Return sense data descriptor" / "Fixed format ++ * sense data" with ATA taskfile fields. ++ * ++ * LOCKING: ++ * None. ++ */ ++static void ata_scsi_set_passthru_sense_fields(struct ata_queued_cmd *qc) ++{ ++ struct scsi_cmnd *cmd = qc->scsicmd; ++ struct ata_taskfile *tf = &qc->result_tf; ++ unsigned char *sb = cmd->sense_buffer; ++ ++ if ((sb[0] & 0x7f) >= 0x72) { ++ unsigned char *desc; ++ u8 len; ++ ++ /* descriptor format */ ++ len = sb[7]; ++ desc = (char *)scsi_sense_desc_find(sb, len + 8, 9); ++ if (!desc) { ++ if (SCSI_SENSE_BUFFERSIZE < len + 14) ++ return; ++ sb[7] = len + 14; ++ desc = sb + 8 + len; ++ } ++ desc[0] = 9; ++ desc[1] = 12; ++ /* ++ * Copy registers into sense buffer. ++ */ ++ desc[2] = 0x00; ++ desc[3] = tf->error; ++ desc[5] = tf->nsect; ++ desc[7] = tf->lbal; ++ desc[9] = tf->lbam; ++ desc[11] = tf->lbah; ++ desc[12] = tf->device; ++ desc[13] = tf->status; ++ ++ /* ++ * Fill in Extend bit, and the high order bytes ++ * if applicable. ++ */ ++ if (tf->flags & ATA_TFLAG_LBA48) { ++ desc[2] |= 0x01; ++ desc[4] = tf->hob_nsect; ++ desc[6] = tf->hob_lbal; ++ desc[8] = tf->hob_lbam; ++ desc[10] = tf->hob_lbah; ++ } ++ } else { ++ /* Fixed sense format */ ++ sb[0] |= 0x80; ++ sb[3] = tf->error; ++ sb[4] = tf->status; ++ sb[5] = tf->device; ++ sb[6] = tf->nsect; ++ if (tf->flags & ATA_TFLAG_LBA48) { ++ sb[8] |= 0x80; ++ if (tf->hob_nsect) ++ sb[8] |= 0x40; ++ if (tf->hob_lbal || tf->hob_lbam || tf->hob_lbah) ++ sb[8] |= 0x20; ++ } ++ sb[9] = tf->lbal; ++ sb[10] = tf->lbam; ++ sb[11] = tf->lbah; ++ } ++} ++ + static void ata_scsi_set_invalid_field(struct ata_device *dev, + struct scsi_cmnd *cmd, u16 field, u8 bit) + { +@@ -837,10 +911,8 @@ static void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, + * ata_gen_passthru_sense - Generate check condition sense block. + * @qc: Command that completed. + * +- * This function is specific to the ATA descriptor format sense +- * block specified for the ATA pass through commands. Regardless +- * of whether the command errored or not, return a sense +- * block. Copy all controller registers into the sense ++ * This function is specific to the ATA pass through commands. ++ * Regardless of whether the command errored or not, return a sense + * block. If there was no error, we get the request from an ATA + * passthrough command, so we use the following sense data: + * sk = RECOVERED ERROR +@@ -855,7 +927,6 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc) + struct scsi_cmnd *cmd = qc->scsicmd; + struct ata_taskfile *tf = &qc->result_tf; + unsigned char *sb = cmd->sense_buffer; +- unsigned char *desc = sb + 8; + u8 sense_key, asc, ascq; + + memset(sb, 0, SCSI_SENSE_BUFFERSIZE); +@@ -870,67 +941,8 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc) + &sense_key, &asc, &ascq); + ata_scsi_set_sense(qc->dev, cmd, sense_key, asc, ascq); + } else { +- /* +- * ATA PASS-THROUGH INFORMATION AVAILABLE +- * Always in descriptor format sense. +- */ +- scsi_build_sense(cmd, 1, RECOVERED_ERROR, 0, 0x1D); +- } +- +- if ((cmd->sense_buffer[0] & 0x7f) >= 0x72) { +- u8 len; +- +- /* descriptor format */ +- len = sb[7]; +- desc = (char *)scsi_sense_desc_find(sb, len + 8, 9); +- if (!desc) { +- if (SCSI_SENSE_BUFFERSIZE < len + 14) +- return; +- sb[7] = len + 14; +- desc = sb + 8 + len; +- } +- desc[0] = 9; +- desc[1] = 12; +- /* +- * Copy registers into sense buffer. +- */ +- desc[2] = 0x00; +- desc[3] = tf->error; +- desc[5] = tf->nsect; +- desc[7] = tf->lbal; +- desc[9] = tf->lbam; +- desc[11] = tf->lbah; +- desc[12] = tf->device; +- desc[13] = tf->status; +- +- /* +- * Fill in Extend bit, and the high order bytes +- * if applicable. +- */ +- if (tf->flags & ATA_TFLAG_LBA48) { +- desc[2] |= 0x01; +- desc[4] = tf->hob_nsect; +- desc[6] = tf->hob_lbal; +- desc[8] = tf->hob_lbam; +- desc[10] = tf->hob_lbah; +- } +- } else { +- /* Fixed sense format */ +- desc[0] = tf->error; +- desc[1] = tf->status; +- desc[2] = tf->device; +- desc[3] = tf->nsect; +- desc[7] = 0; +- if (tf->flags & ATA_TFLAG_LBA48) { +- desc[8] |= 0x80; +- if (tf->hob_nsect) +- desc[8] |= 0x40; +- if (tf->hob_lbal || tf->hob_lbam || tf->hob_lbah) +- desc[8] |= 0x20; +- } +- desc[9] = tf->lbal; +- desc[10] = tf->lbam; +- desc[11] = tf->lbah; ++ /* ATA PASS-THROUGH INFORMATION AVAILABLE */ ++ ata_scsi_set_sense(qc->dev, cmd, RECOVERED_ERROR, 0, 0x1D); + } + } + +@@ -1664,26 +1676,32 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) + { + struct scsi_cmnd *cmd = qc->scsicmd; + u8 *cdb = cmd->cmnd; +- int need_sense = (qc->err_mask != 0) && +- !(qc->flags & ATA_QCFLAG_SENSE_VALID); ++ bool have_sense = qc->flags & ATA_QCFLAG_SENSE_VALID; ++ bool is_ata_passthru = cdb[0] == ATA_16 || cdb[0] == ATA_12; ++ bool is_ck_cond_request = cdb[2] & 0x20; ++ bool is_error = qc->err_mask != 0; + + /* For ATA pass thru (SAT) commands, generate a sense block if + * user mandated it or if there's an error. Note that if we +- * generate because the user forced us to [CK_COND =1], a check ++ * generate because the user forced us to [CK_COND=1], a check + * condition is generated and the ATA register values are returned + * whether the command completed successfully or not. If there +- * was no error, we use the following sense data: ++ * was no error, and CK_COND=1, we use the following sense data: + * sk = RECOVERED ERROR + * asc,ascq = ATA PASS-THROUGH INFORMATION AVAILABLE + */ +- if (((cdb[0] == ATA_16) || (cdb[0] == ATA_12)) && +- ((cdb[2] & 0x20) || need_sense)) +- ata_gen_passthru_sense(qc); +- else if (need_sense) ++ if (is_ata_passthru && (is_ck_cond_request || is_error || have_sense)) { ++ if (!have_sense) ++ ata_gen_passthru_sense(qc); ++ ata_scsi_set_passthru_sense_fields(qc); ++ if (is_ck_cond_request) ++ set_status_byte(qc->scsicmd, SAM_STAT_CHECK_CONDITION); ++ } else if (is_error && !have_sense) { + ata_gen_ata_sense(qc); +- else ++ } else { + /* Keep the SCSI ML and status byte, clear host byte. */ + cmd->result &= 0x0000ffff; ++ } + + ata_qc_done(qc); + } +@@ -2622,14 +2640,8 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc) + /* handle completion from EH */ + if (unlikely(err_mask || qc->flags & ATA_QCFLAG_SENSE_VALID)) { + +- if (!(qc->flags & ATA_QCFLAG_SENSE_VALID)) { +- /* FIXME: not quite right; we don't want the +- * translation of taskfile registers into a +- * sense descriptors, since that's only +- * correct for ATA, not ATAPI +- */ ++ if (!(qc->flags & ATA_QCFLAG_SENSE_VALID)) + ata_gen_passthru_sense(qc); +- } + + /* SCSI EH automatically locks door if sdev->locked is + * set. Sometimes door lock request continues to +diff --git a/drivers/auxdisplay/ht16k33.c b/drivers/auxdisplay/ht16k33.c +index 3a2d883872249..b360ddefc4238 100644 +--- a/drivers/auxdisplay/ht16k33.c ++++ b/drivers/auxdisplay/ht16k33.c +@@ -507,6 +507,7 @@ static int ht16k33_led_probe(struct device *dev, struct led_classdev *led, + led->max_brightness = MAX_BRIGHTNESS; + + err = devm_led_classdev_register_ext(dev, led, &init_data); ++ fwnode_handle_put(init_data.fwnode); + if (err) + dev_err(dev, "Failed to register LED\n"); + +diff --git a/drivers/base/devres.c b/drivers/base/devres.c +index 3df0025d12aa4..8d709dbd4e0c1 100644 +--- a/drivers/base/devres.c ++++ b/drivers/base/devres.c +@@ -896,9 +896,12 @@ void *devm_krealloc(struct device *dev, void *ptr, size_t new_size, gfp_t gfp) + /* + * Otherwise: allocate new, larger chunk. We need to allocate before + * taking the lock as most probably the caller uses GFP_KERNEL. ++ * alloc_dr() will call check_dr_size() to reserve extra memory ++ * for struct devres automatically, so size @new_size user request ++ * is delivered to it directly as devm_kmalloc() does. + */ + new_dr = alloc_dr(devm_kmalloc_release, +- total_new_size, gfp, dev_to_node(dev)); ++ new_size, gfp, dev_to_node(dev)); + if (!new_dr) + return NULL; + +@@ -1222,7 +1225,11 @@ EXPORT_SYMBOL_GPL(__devm_alloc_percpu); + */ + void devm_free_percpu(struct device *dev, void __percpu *pdata) + { +- WARN_ON(devres_destroy(dev, devm_percpu_release, devm_percpu_match, ++ /* ++ * Use devres_release() to prevent memory leakage as ++ * devm_free_pages() does. ++ */ ++ WARN_ON(devres_release(dev, devm_percpu_release, devm_percpu_match, + (__force void *)pdata)); + } + EXPORT_SYMBOL_GPL(devm_free_percpu); +diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c +index 1e2596c5efd81..6fcd7f0fe4f03 100644 +--- a/drivers/block/rbd.c ++++ b/drivers/block/rbd.c +@@ -362,7 +362,7 @@ enum rbd_watch_state { + enum rbd_lock_state { + RBD_LOCK_STATE_UNLOCKED, + RBD_LOCK_STATE_LOCKED, +- RBD_LOCK_STATE_RELEASING, ++ RBD_LOCK_STATE_QUIESCING, + }; + + /* WatchNotify::ClientId */ +@@ -422,7 +422,7 @@ struct rbd_device { + struct list_head running_list; + struct completion acquire_wait; + int acquire_err; +- struct completion releasing_wait; ++ struct completion quiescing_wait; + + spinlock_t object_map_lock; + u8 *object_map; +@@ -525,7 +525,7 @@ static bool __rbd_is_lock_owner(struct rbd_device *rbd_dev) + lockdep_assert_held(&rbd_dev->lock_rwsem); + + return rbd_dev->lock_state == RBD_LOCK_STATE_LOCKED || +- rbd_dev->lock_state == RBD_LOCK_STATE_RELEASING; ++ rbd_dev->lock_state == RBD_LOCK_STATE_QUIESCING; + } + + static bool rbd_is_lock_owner(struct rbd_device *rbd_dev) +@@ -3457,13 +3457,14 @@ static void rbd_lock_del_request(struct rbd_img_request *img_req) + lockdep_assert_held(&rbd_dev->lock_rwsem); + spin_lock(&rbd_dev->lock_lists_lock); + if (!list_empty(&img_req->lock_item)) { ++ rbd_assert(!list_empty(&rbd_dev->running_list)); + list_del_init(&img_req->lock_item); +- need_wakeup = (rbd_dev->lock_state == RBD_LOCK_STATE_RELEASING && ++ need_wakeup = (rbd_dev->lock_state == RBD_LOCK_STATE_QUIESCING && + list_empty(&rbd_dev->running_list)); + } + spin_unlock(&rbd_dev->lock_lists_lock); + if (need_wakeup) +- complete(&rbd_dev->releasing_wait); ++ complete(&rbd_dev->quiescing_wait); + } + + static int rbd_img_exclusive_lock(struct rbd_img_request *img_req) +@@ -3476,11 +3477,6 @@ static int rbd_img_exclusive_lock(struct rbd_img_request *img_req) + if (rbd_lock_add_request(img_req)) + return 1; + +- if (rbd_dev->opts->exclusive) { +- WARN_ON(1); /* lock got released? */ +- return -EROFS; +- } +- + /* + * Note the use of mod_delayed_work() in rbd_acquire_lock() + * and cancel_delayed_work() in wake_lock_waiters(). +@@ -4181,16 +4177,16 @@ static bool rbd_quiesce_lock(struct rbd_device *rbd_dev) + /* + * Ensure that all in-flight IO is flushed. + */ +- rbd_dev->lock_state = RBD_LOCK_STATE_RELEASING; +- rbd_assert(!completion_done(&rbd_dev->releasing_wait)); ++ rbd_dev->lock_state = RBD_LOCK_STATE_QUIESCING; ++ rbd_assert(!completion_done(&rbd_dev->quiescing_wait)); + if (list_empty(&rbd_dev->running_list)) + return true; + + up_write(&rbd_dev->lock_rwsem); +- wait_for_completion(&rbd_dev->releasing_wait); ++ wait_for_completion(&rbd_dev->quiescing_wait); + + down_write(&rbd_dev->lock_rwsem); +- if (rbd_dev->lock_state != RBD_LOCK_STATE_RELEASING) ++ if (rbd_dev->lock_state != RBD_LOCK_STATE_QUIESCING) + return false; + + rbd_assert(list_empty(&rbd_dev->running_list)); +@@ -4601,6 +4597,10 @@ static void rbd_reacquire_lock(struct rbd_device *rbd_dev) + rbd_warn(rbd_dev, "failed to update lock cookie: %d", + ret); + ++ if (rbd_dev->opts->exclusive) ++ rbd_warn(rbd_dev, ++ "temporarily releasing lock on exclusive mapping"); ++ + /* + * Lock cookie cannot be updated on older OSDs, so do + * a manual release and queue an acquire. +@@ -5382,7 +5382,7 @@ static struct rbd_device *__rbd_dev_create(struct rbd_spec *spec) + INIT_LIST_HEAD(&rbd_dev->acquiring_list); + INIT_LIST_HEAD(&rbd_dev->running_list); + init_completion(&rbd_dev->acquire_wait); +- init_completion(&rbd_dev->releasing_wait); ++ init_completion(&rbd_dev->quiescing_wait); + + spin_lock_init(&rbd_dev->object_map_lock); + +@@ -6588,11 +6588,6 @@ static int rbd_add_acquire_lock(struct rbd_device *rbd_dev) + if (ret) + return ret; + +- /* +- * The lock may have been released by now, unless automatic lock +- * transitions are disabled. +- */ +- rbd_assert(!rbd_dev->opts->exclusive || rbd_is_lock_owner(rbd_dev)); + return 0; + } + +diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c +index ac1562d9ef26b..3da3c266a66f3 100644 +--- a/drivers/bluetooth/btintel.c ++++ b/drivers/bluetooth/btintel.c +@@ -26,21 +26,11 @@ + #define ECDSA_OFFSET 644 + #define ECDSA_HEADER_LEN 320 + +-#define BTINTEL_PPAG_NAME "PPAG" +- + enum { + DSM_SET_WDISABLE2_DELAY = 1, + DSM_SET_RESET_METHOD = 3, + }; + +-/* structure to store the PPAG data read from ACPI table */ +-struct btintel_ppag { +- u32 domain; +- u32 mode; +- acpi_status status; +- struct hci_dev *hdev; +-}; +- + #define CMD_WRITE_BOOT_PARAMS 0xfc0e + struct cmd_write_boot_params { + __le32 boot_addr; +@@ -1312,65 +1302,6 @@ static int btintel_read_debug_features(struct hci_dev *hdev, + return 0; + } + +-static acpi_status btintel_ppag_callback(acpi_handle handle, u32 lvl, void *data, +- void **ret) +-{ +- acpi_status status; +- size_t len; +- struct btintel_ppag *ppag = data; +- union acpi_object *p, *elements; +- struct acpi_buffer string = {ACPI_ALLOCATE_BUFFER, NULL}; +- struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; +- struct hci_dev *hdev = ppag->hdev; +- +- status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &string); +- if (ACPI_FAILURE(status)) { +- bt_dev_warn(hdev, "PPAG-BT: ACPI Failure: %s", acpi_format_exception(status)); +- return status; +- } +- +- len = strlen(string.pointer); +- if (len < strlen(BTINTEL_PPAG_NAME)) { +- kfree(string.pointer); +- return AE_OK; +- } +- +- if (strncmp((char *)string.pointer + len - 4, BTINTEL_PPAG_NAME, 4)) { +- kfree(string.pointer); +- return AE_OK; +- } +- kfree(string.pointer); +- +- status = acpi_evaluate_object(handle, NULL, NULL, &buffer); +- if (ACPI_FAILURE(status)) { +- ppag->status = status; +- bt_dev_warn(hdev, "PPAG-BT: ACPI Failure: %s", acpi_format_exception(status)); +- return status; +- } +- +- p = buffer.pointer; +- ppag = (struct btintel_ppag *)data; +- +- if (p->type != ACPI_TYPE_PACKAGE || p->package.count != 2) { +- kfree(buffer.pointer); +- bt_dev_warn(hdev, "PPAG-BT: Invalid object type: %d or package count: %d", +- p->type, p->package.count); +- ppag->status = AE_ERROR; +- return AE_ERROR; +- } +- +- elements = p->package.elements; +- +- /* PPAG table is located at element[1] */ +- p = &elements[1]; +- +- ppag->domain = (u32)p->package.elements[0].integer.value; +- ppag->mode = (u32)p->package.elements[1].integer.value; +- ppag->status = AE_OK; +- kfree(buffer.pointer); +- return AE_CTRL_TERMINATE; +-} +- + static int btintel_set_debug_features(struct hci_dev *hdev, + const struct intel_debug_features *features) + { +@@ -2399,10 +2330,13 @@ static int btintel_configure_offload(struct hci_dev *hdev) + + static void btintel_set_ppag(struct hci_dev *hdev, struct intel_version_tlv *ver) + { +- struct btintel_ppag ppag; + struct sk_buff *skb; + struct hci_ppag_enable_cmd ppag_cmd; + acpi_handle handle; ++ struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; ++ union acpi_object *p, *elements; ++ u32 domain, mode; ++ acpi_status status; + + /* PPAG is not supported if CRF is HrP2, Jfp2, JfP1 */ + switch (ver->cnvr_top & 0xFFF) { +@@ -2420,22 +2354,34 @@ static void btintel_set_ppag(struct hci_dev *hdev, struct intel_version_tlv *ver + return; + } + +- memset(&ppag, 0, sizeof(ppag)); +- +- ppag.hdev = hdev; +- ppag.status = AE_NOT_FOUND; +- acpi_walk_namespace(ACPI_TYPE_PACKAGE, handle, 1, NULL, +- btintel_ppag_callback, &ppag, NULL); +- +- if (ACPI_FAILURE(ppag.status)) { +- if (ppag.status == AE_NOT_FOUND) { ++ status = acpi_evaluate_object(handle, "PPAG", NULL, &buffer); ++ if (ACPI_FAILURE(status)) { ++ if (status == AE_NOT_FOUND) { + bt_dev_dbg(hdev, "PPAG-BT: ACPI entry not found"); + return; + } ++ bt_dev_warn(hdev, "PPAG-BT: ACPI Failure: %s", acpi_format_exception(status)); ++ return; ++ } ++ ++ p = buffer.pointer; ++ if (p->type != ACPI_TYPE_PACKAGE || p->package.count != 2) { ++ bt_dev_warn(hdev, "PPAG-BT: Invalid object type: %d or package count: %d", ++ p->type, p->package.count); ++ kfree(buffer.pointer); + return; + } + +- if (ppag.domain != 0x12) { ++ elements = p->package.elements; ++ ++ /* PPAG table is located at element[1] */ ++ p = &elements[1]; ++ ++ domain = (u32)p->package.elements[0].integer.value; ++ mode = (u32)p->package.elements[1].integer.value; ++ kfree(buffer.pointer); ++ ++ if (domain != 0x12) { + bt_dev_dbg(hdev, "PPAG-BT: Bluetooth domain is disabled in ACPI firmware"); + return; + } +@@ -2446,19 +2392,22 @@ static void btintel_set_ppag(struct hci_dev *hdev, struct intel_version_tlv *ver + * BIT 1 : 0 Disabled in China + * 1 Enabled in China + */ +- if ((ppag.mode & 0x01) != BIT(0) && (ppag.mode & 0x02) != BIT(1)) { +- bt_dev_dbg(hdev, "PPAG-BT: EU, China mode are disabled in CB/BIOS"); ++ mode &= 0x03; ++ ++ if (!mode) { ++ bt_dev_dbg(hdev, "PPAG-BT: EU, China mode are disabled in BIOS"); + return; + } + +- ppag_cmd.ppag_enable_flags = cpu_to_le32(ppag.mode); ++ ppag_cmd.ppag_enable_flags = cpu_to_le32(mode); + +- skb = __hci_cmd_sync(hdev, INTEL_OP_PPAG_CMD, sizeof(ppag_cmd), &ppag_cmd, HCI_CMD_TIMEOUT); ++ skb = __hci_cmd_sync(hdev, INTEL_OP_PPAG_CMD, sizeof(ppag_cmd), ++ &ppag_cmd, HCI_CMD_TIMEOUT); + if (IS_ERR(skb)) { + bt_dev_warn(hdev, "Failed to send PPAG Enable (%ld)", PTR_ERR(skb)); + return; + } +- bt_dev_info(hdev, "PPAG-BT: Enabled (Mode %d)", ppag.mode); ++ bt_dev_info(hdev, "PPAG-BT: Enabled (Mode %d)", mode); + kfree_skb(skb); + } + +diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c +index 5c5a5b752419e..83e8e27a5ecec 100644 +--- a/drivers/bluetooth/btnxpuart.c ++++ b/drivers/bluetooth/btnxpuart.c +@@ -186,6 +186,11 @@ struct btnxpuart_dev { + #define NXP_NAK_V3 0x7b + #define NXP_CRC_ERROR_V3 0x7c + ++/* Bootloader signature error codes */ ++#define NXP_ACK_RX_TIMEOUT 0x0002 /* ACK not received from host */ ++#define NXP_HDR_RX_TIMEOUT 0x0003 /* FW Header chunk not received */ ++#define NXP_DATA_RX_TIMEOUT 0x0004 /* FW Data chunk not received */ ++ + #define HDR_LEN 16 + + #define NXP_RECV_CHIP_VER_V1 \ +@@ -276,6 +281,17 @@ struct nxp_bootloader_cmd { + __be32 crc; + } __packed; + ++struct nxp_v3_rx_timeout_nak { ++ u8 nak; ++ __le32 offset; ++ u8 crc; ++} __packed; ++ ++union nxp_v3_rx_timeout_nak_u { ++ struct nxp_v3_rx_timeout_nak pkt; ++ u8 buf[6]; ++}; ++ + static u8 crc8_table[CRC8_TABLE_SIZE]; + + /* Default configurations */ +@@ -883,6 +899,32 @@ static int nxp_recv_chip_ver_v3(struct hci_dev *hdev, struct sk_buff *skb) + return 0; + } + ++static void nxp_handle_fw_download_error(struct hci_dev *hdev, struct v3_data_req *req) ++{ ++ struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev); ++ __u32 offset = __le32_to_cpu(req->offset); ++ __u16 err = __le16_to_cpu(req->error); ++ union nxp_v3_rx_timeout_nak_u nak_tx_buf; ++ ++ switch (err) { ++ case NXP_ACK_RX_TIMEOUT: ++ case NXP_HDR_RX_TIMEOUT: ++ case NXP_DATA_RX_TIMEOUT: ++ nak_tx_buf.pkt.nak = NXP_NAK_V3; ++ nak_tx_buf.pkt.offset = __cpu_to_le32(offset); ++ nak_tx_buf.pkt.crc = crc8(crc8_table, nak_tx_buf.buf, ++ sizeof(nak_tx_buf) - 1, 0xff); ++ serdev_device_write_buf(nxpdev->serdev, nak_tx_buf.buf, ++ sizeof(nak_tx_buf)); ++ break; ++ default: ++ bt_dev_dbg(hdev, "Unknown bootloader error code: %d", err); ++ break; ++ ++ } ++ ++} ++ + static int nxp_recv_fw_req_v3(struct hci_dev *hdev, struct sk_buff *skb) + { + struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev); +@@ -897,7 +939,12 @@ static int nxp_recv_fw_req_v3(struct hci_dev *hdev, struct sk_buff *skb) + if (!req || !nxpdev->fw) + goto free_skb; + +- nxp_send_ack(NXP_ACK_V3, hdev); ++ if (!req->error) { ++ nxp_send_ack(NXP_ACK_V3, hdev); ++ } else { ++ nxp_handle_fw_download_error(hdev, req); ++ goto free_skb; ++ } + + len = __le16_to_cpu(req->len); + +@@ -924,9 +971,6 @@ static int nxp_recv_fw_req_v3(struct hci_dev *hdev, struct sk_buff *skb) + wake_up_interruptible(&nxpdev->fw_dnld_done_wait_q); + goto free_skb; + } +- if (req->error) +- bt_dev_dbg(hdev, "FW Download received err 0x%02x from chip", +- req->error); + + offset = __le32_to_cpu(req->offset); + if (offset < nxpdev->fw_v3_offset_correction) { +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index 7c271f55a9b49..c495fceda20a2 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -551,6 +551,10 @@ static const struct usb_device_id quirks_table[] = { + BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x13d3, 0x3571), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x13d3, 0x3591), .driver_info = BTUSB_REALTEK | ++ BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x0489, 0xe125), .driver_info = BTUSB_REALTEK | ++ BTUSB_WIDEBAND_SPEECH }, + + /* Realtek Bluetooth devices */ + { USB_VENDOR_AND_INTERFACE_INFO(0x0bda, 0xe0, 0x01, 0x01), +diff --git a/drivers/bluetooth/hci_bcm4377.c b/drivers/bluetooth/hci_bcm4377.c +index cf36cdac652d6..0dc3ca3d41073 100644 +--- a/drivers/bluetooth/hci_bcm4377.c ++++ b/drivers/bluetooth/hci_bcm4377.c +@@ -32,7 +32,7 @@ enum bcm4377_chip { + #define BCM4378_DEVICE_ID 0x5f69 + #define BCM4387_DEVICE_ID 0x5f71 + +-#define BCM4377_TIMEOUT 1000 ++#define BCM4377_TIMEOUT msecs_to_jiffies(1000) + + /* + * These devices only support DMA transactions inside a 32bit window +diff --git a/drivers/char/hw_random/amd-rng.c b/drivers/char/hw_random/amd-rng.c +index 86162a13681e6..9a24d19236dc7 100644 +--- a/drivers/char/hw_random/amd-rng.c ++++ b/drivers/char/hw_random/amd-rng.c +@@ -143,8 +143,10 @@ static int __init amd_rng_mod_init(void) + + found: + err = pci_read_config_dword(pdev, 0x58, &pmbase); +- if (err) ++ if (err) { ++ err = pcibios_err_to_errno(err); + goto put_dev; ++ } + + pmbase &= 0x0000FF00; + if (pmbase == 0) { +diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c +index a3bbdd6e60fca..a182fe794f985 100644 +--- a/drivers/char/hw_random/core.c ++++ b/drivers/char/hw_random/core.c +@@ -174,7 +174,6 @@ static int hwrng_init(struct hwrng *rng) + reinit_completion(&rng->cleanup_done); + + skip_init: +- rng->quality = min_t(u16, min_t(u16, default_quality, 1024), rng->quality ?: 1024); + current_quality = rng->quality; /* obsolete */ + + return 0; +@@ -563,6 +562,9 @@ int hwrng_register(struct hwrng *rng) + complete(&rng->cleanup_done); + init_completion(&rng->dying); + ++ /* Adjust quality field to always have a proper value */ ++ rng->quality = min_t(u16, min_t(u16, default_quality, 1024), rng->quality ?: 1024); ++ + if (!current_rng || + (!cur_rng_set_by_user && rng->quality > current_rng->quality)) { + /* +diff --git a/drivers/char/ipmi/ssif_bmc.c b/drivers/char/ipmi/ssif_bmc.c +index 56346fb328727..ab4e87a99f087 100644 +--- a/drivers/char/ipmi/ssif_bmc.c ++++ b/drivers/char/ipmi/ssif_bmc.c +@@ -177,13 +177,15 @@ static ssize_t ssif_bmc_write(struct file *file, const char __user *buf, size_t + unsigned long flags; + ssize_t ret; + +- if (count > sizeof(struct ipmi_ssif_msg)) ++ if (count < sizeof(msg.len) || ++ count > sizeof(struct ipmi_ssif_msg)) + return -EINVAL; + + if (copy_from_user(&msg, buf, count)) + return -EFAULT; + +- if (!msg.len || count < sizeof_field(struct ipmi_ssif_msg, len) + msg.len) ++ if (!msg.len || msg.len > IPMI_SSIF_PAYLOAD_MAX || ++ count < sizeof_field(struct ipmi_ssif_msg, len) + msg.len) + return -EINVAL; + + spin_lock_irqsave(&ssif_bmc->lock, flags); +diff --git a/drivers/char/tpm/eventlog/common.c b/drivers/char/tpm/eventlog/common.c +index 639c3f395a5af..4c0bbba64ee50 100644 +--- a/drivers/char/tpm/eventlog/common.c ++++ b/drivers/char/tpm/eventlog/common.c +@@ -47,6 +47,8 @@ static int tpm_bios_measurements_open(struct inode *inode, + if (!err) { + seq = file->private_data; + seq->private = chip; ++ } else { ++ put_device(&chip->dev); + } + + return err; +diff --git a/drivers/clk/clk-en7523.c b/drivers/clk/clk-en7523.c +index 7cde328495e2b..7914e60f3d6c5 100644 +--- a/drivers/clk/clk-en7523.c ++++ b/drivers/clk/clk-en7523.c +@@ -40,6 +40,7 @@ struct en_clk_desc { + u8 div_shift; + u16 div_val0; + u8 div_step; ++ u8 div_offset; + }; + + struct en_clk_gate { +@@ -67,6 +68,7 @@ static const struct en_clk_desc en7523_base_clks[] = { + .div_bits = 3, + .div_shift = 0, + .div_step = 1, ++ .div_offset = 1, + }, { + .id = EN7523_CLK_EMI, + .name = "emi", +@@ -80,6 +82,7 @@ static const struct en_clk_desc en7523_base_clks[] = { + .div_bits = 3, + .div_shift = 0, + .div_step = 1, ++ .div_offset = 1, + }, { + .id = EN7523_CLK_BUS, + .name = "bus", +@@ -93,6 +96,7 @@ static const struct en_clk_desc en7523_base_clks[] = { + .div_bits = 3, + .div_shift = 0, + .div_step = 1, ++ .div_offset = 1, + }, { + .id = EN7523_CLK_SLIC, + .name = "slic", +@@ -133,13 +137,14 @@ static const struct en_clk_desc en7523_base_clks[] = { + .div_bits = 3, + .div_shift = 0, + .div_step = 1, ++ .div_offset = 1, + }, { + .id = EN7523_CLK_CRYPTO, + .name = "crypto", + + .base_reg = REG_CRYPTO_CLKSRC, + .base_bits = 1, +- .base_shift = 8, ++ .base_shift = 0, + .base_values = emi_base, + .n_base_values = ARRAY_SIZE(emi_base), + } +@@ -184,7 +189,7 @@ static u32 en7523_get_div(void __iomem *base, int i) + if (!val && desc->div_val0) + return desc->div_val0; + +- return (val + 1) * desc->div_step; ++ return (val + desc->div_offset) * desc->div_step; + } + + static int en7523_pci_is_enabled(struct clk_hw *hw) +diff --git a/drivers/clk/davinci/da8xx-cfgchip.c b/drivers/clk/davinci/da8xx-cfgchip.c +index e5b2cdfe88ce1..dff7ca35536cc 100644 +--- a/drivers/clk/davinci/da8xx-cfgchip.c ++++ b/drivers/clk/davinci/da8xx-cfgchip.c +@@ -508,7 +508,7 @@ da8xx_cfgchip_register_usb0_clk48(struct device *dev, + const char * const parent_names[] = { "usb_refclkin", "pll0_auxclk" }; + struct clk *fck_clk; + struct da8xx_usb0_clk48 *usb0; +- struct clk_init_data init; ++ struct clk_init_data init = {}; + int ret; + + fck_clk = devm_clk_get(dev, "fck"); +@@ -583,7 +583,7 @@ da8xx_cfgchip_register_usb1_clk48(struct device *dev, + { + const char * const parent_names[] = { "usb0_clk48", "usb_refclkin" }; + struct da8xx_usb1_clk48 *usb1; +- struct clk_init_data init; ++ struct clk_init_data init = {}; + int ret; + + usb1 = devm_kzalloc(dev, sizeof(*usb1), GFP_KERNEL); +diff --git a/drivers/clk/qcom/camcc-sc7280.c b/drivers/clk/qcom/camcc-sc7280.c +index 49f046ea857cb..c1551de51d401 100644 +--- a/drivers/clk/qcom/camcc-sc7280.c ++++ b/drivers/clk/qcom/camcc-sc7280.c +@@ -2260,6 +2260,7 @@ static struct gdsc cam_cc_bps_gdsc = { + .name = "cam_cc_bps_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &cam_cc_titan_top_gdsc.pd, + .flags = HW_CTRL | RETAIN_FF_ENABLE, + }; + +@@ -2269,6 +2270,7 @@ static struct gdsc cam_cc_ife_0_gdsc = { + .name = "cam_cc_ife_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &cam_cc_titan_top_gdsc.pd, + .flags = RETAIN_FF_ENABLE, + }; + +@@ -2278,6 +2280,7 @@ static struct gdsc cam_cc_ife_1_gdsc = { + .name = "cam_cc_ife_1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &cam_cc_titan_top_gdsc.pd, + .flags = RETAIN_FF_ENABLE, + }; + +@@ -2287,6 +2290,7 @@ static struct gdsc cam_cc_ife_2_gdsc = { + .name = "cam_cc_ife_2_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &cam_cc_titan_top_gdsc.pd, + .flags = RETAIN_FF_ENABLE, + }; + +@@ -2296,6 +2300,7 @@ static struct gdsc cam_cc_ipe_0_gdsc = { + .name = "cam_cc_ipe_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &cam_cc_titan_top_gdsc.pd, + .flags = HW_CTRL | RETAIN_FF_ENABLE, + }; + +diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c +index 5183c74b074f8..b9f2a29be927c 100644 +--- a/drivers/clk/qcom/clk-rcg2.c ++++ b/drivers/clk/qcom/clk-rcg2.c +@@ -1138,7 +1138,39 @@ clk_rcg2_shared_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) + return clk_rcg2_recalc_rate(hw, parent_rate); + } + ++static int clk_rcg2_shared_init(struct clk_hw *hw) ++{ ++ /* ++ * This does a few things: ++ * ++ * 1. Sets rcg->parked_cfg to reflect the value at probe so that the ++ * proper parent is reported from clk_rcg2_shared_get_parent(). ++ * ++ * 2. Clears the force enable bit of the RCG because we rely on child ++ * clks (branches) to turn the RCG on/off with a hardware feedback ++ * mechanism and only set the force enable bit in the RCG when we ++ * want to make sure the clk stays on for parent switches or ++ * parking. ++ * ++ * 3. Parks shared RCGs on the safe source at registration because we ++ * can't be certain that the parent clk will stay on during boot, ++ * especially if the parent is shared. If this RCG is enabled at ++ * boot, and the parent is turned off, the RCG will get stuck on. A ++ * GDSC can wedge if is turned on and the RCG is stuck on because ++ * the GDSC's controller will hang waiting for the clk status to ++ * toggle on when it never does. ++ * ++ * The safest option here is to "park" the RCG at init so that the clk ++ * can never get stuck on or off. This ensures the GDSC can't get ++ * wedged. ++ */ ++ clk_rcg2_shared_disable(hw); ++ ++ return 0; ++} ++ + const struct clk_ops clk_rcg2_shared_ops = { ++ .init = clk_rcg2_shared_init, + .enable = clk_rcg2_shared_enable, + .disable = clk_rcg2_shared_disable, + .get_parent = clk_rcg2_shared_get_parent, +diff --git a/drivers/clk/qcom/gcc-sa8775p.c b/drivers/clk/qcom/gcc-sa8775p.c +index 8171d23c96e64..a54438205698c 100644 +--- a/drivers/clk/qcom/gcc-sa8775p.c ++++ b/drivers/clk/qcom/gcc-sa8775p.c +@@ -4305,74 +4305,114 @@ static struct clk_branch gcc_video_axi1_clk = { + + static struct gdsc pcie_0_gdsc = { + .gdscr = 0xa9004, ++ .collapse_ctrl = 0x4b104, ++ .collapse_mask = BIT(0), ++ .en_rest_wait_val = 0x2, ++ .en_few_wait_val = 0x2, ++ .clk_dis_wait_val = 0xf, + .pd = { + .name = "pcie_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .flags = VOTABLE | RETAIN_FF_ENABLE | POLL_CFG_GDSCR, + }; + + static struct gdsc pcie_1_gdsc = { + .gdscr = 0x77004, ++ .collapse_ctrl = 0x4b104, ++ .collapse_mask = BIT(1), ++ .en_rest_wait_val = 0x2, ++ .en_few_wait_val = 0x2, ++ .clk_dis_wait_val = 0xf, + .pd = { + .name = "pcie_1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .flags = VOTABLE | RETAIN_FF_ENABLE | POLL_CFG_GDSCR, + }; + + static struct gdsc ufs_card_gdsc = { + .gdscr = 0x81004, ++ .en_rest_wait_val = 0x2, ++ .en_few_wait_val = 0x2, ++ .clk_dis_wait_val = 0xf, + .pd = { + .name = "ufs_card_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR, + }; + + static struct gdsc ufs_phy_gdsc = { + .gdscr = 0x83004, ++ .en_rest_wait_val = 0x2, ++ .en_few_wait_val = 0x2, ++ .clk_dis_wait_val = 0xf, + .pd = { + .name = "ufs_phy_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR, + }; + + static struct gdsc usb20_prim_gdsc = { + .gdscr = 0x1c004, ++ .en_rest_wait_val = 0x2, ++ .en_few_wait_val = 0x2, ++ .clk_dis_wait_val = 0xf, + .pd = { + .name = "usb20_prim_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR, + }; + + static struct gdsc usb30_prim_gdsc = { + .gdscr = 0x1b004, ++ .en_rest_wait_val = 0x2, ++ .en_few_wait_val = 0x2, ++ .clk_dis_wait_val = 0xf, + .pd = { + .name = "usb30_prim_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR, + }; + + static struct gdsc usb30_sec_gdsc = { + .gdscr = 0x2f004, ++ .en_rest_wait_val = 0x2, ++ .en_few_wait_val = 0x2, ++ .clk_dis_wait_val = 0xf, + .pd = { + .name = "usb30_sec_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR, + }; + + static struct gdsc emac0_gdsc = { + .gdscr = 0xb6004, ++ .en_rest_wait_val = 0x2, ++ .en_few_wait_val = 0x2, ++ .clk_dis_wait_val = 0xf, + .pd = { + .name = "emac0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR, + }; + + static struct gdsc emac1_gdsc = { + .gdscr = 0xb4004, ++ .en_rest_wait_val = 0x2, ++ .en_few_wait_val = 0x2, ++ .clk_dis_wait_val = 0xf, + .pd = { + .name = "emac1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR, + }; + + static struct clk_regmap *gcc_sa8775p_clocks[] = { +diff --git a/drivers/clk/qcom/gcc-sc7280.c b/drivers/clk/qcom/gcc-sc7280.c +index 2b661df5de266..bc81026292fc9 100644 +--- a/drivers/clk/qcom/gcc-sc7280.c ++++ b/drivers/clk/qcom/gcc-sc7280.c +@@ -3467,6 +3467,9 @@ static int gcc_sc7280_probe(struct platform_device *pdev) + regmap_update_bits(regmap, 0x71004, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0x7100C, BIT(13), BIT(13)); + ++ /* FORCE_MEM_CORE_ON for ufs phy ice core clocks */ ++ qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_ice_core_clk, true); ++ + ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks, + ARRAY_SIZE(gcc_dfs_clocks)); + if (ret) +diff --git a/drivers/clk/qcom/gpucc-sa8775p.c b/drivers/clk/qcom/gpucc-sa8775p.c +index 26ecfa63be193..0d9a8379efaa8 100644 +--- a/drivers/clk/qcom/gpucc-sa8775p.c ++++ b/drivers/clk/qcom/gpucc-sa8775p.c +@@ -1,6 +1,6 @@ + // SPDX-License-Identifier: GPL-2.0-only + /* +- * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) 2021-2022, 2024, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2023, Linaro Limited + */ + +@@ -161,7 +161,7 @@ static struct clk_rcg2 gpu_cc_ff_clk_src = { + .name = "gpu_cc_ff_clk_src", + .parent_data = gpu_cc_parent_data_0, + .num_parents = ARRAY_SIZE(gpu_cc_parent_data_0), +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -181,7 +181,7 @@ static struct clk_rcg2 gpu_cc_gmu_clk_src = { + .parent_data = gpu_cc_parent_data_1, + .num_parents = ARRAY_SIZE(gpu_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -200,7 +200,7 @@ static struct clk_rcg2 gpu_cc_hub_clk_src = { + .name = "gpu_cc_hub_clk_src", + .parent_data = gpu_cc_parent_data_2, + .num_parents = ARRAY_SIZE(gpu_cc_parent_data_2), +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -280,7 +280,7 @@ static struct clk_branch gpu_cc_ahb_clk = { + &gpu_cc_hub_ahb_div_clk_src.clkr.hw, + }, + .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -294,8 +294,7 @@ static struct clk_branch gpu_cc_cb_clk = { + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "gpu_cc_cb_clk", +- .flags = CLK_IS_CRITICAL, +- .ops = &clk_branch2_ops, ++ .ops = &clk_branch2_aon_ops, + }, + }, + }; +@@ -312,7 +311,7 @@ static struct clk_branch gpu_cc_crc_ahb_clk = { + &gpu_cc_hub_ahb_div_clk_src.clkr.hw, + }, + .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -330,7 +329,7 @@ static struct clk_branch gpu_cc_cx_ff_clk = { + &gpu_cc_ff_clk_src.clkr.hw, + }, + .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -348,7 +347,7 @@ static struct clk_branch gpu_cc_cx_gmu_clk = { + &gpu_cc_gmu_clk_src.clkr.hw, + }, + .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_aon_ops, + }, + }, +@@ -362,7 +361,6 @@ static struct clk_branch gpu_cc_cx_snoc_dvm_clk = { + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "gpu_cc_cx_snoc_dvm_clk", +- .flags = CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, +@@ -380,7 +378,7 @@ static struct clk_branch gpu_cc_cxo_aon_clk = { + &gpu_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -398,7 +396,7 @@ static struct clk_branch gpu_cc_cxo_clk = { + &gpu_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -416,7 +414,7 @@ static struct clk_branch gpu_cc_demet_clk = { + &gpu_cc_demet_div_clk_src.clkr.hw, + }, + .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_aon_ops, + }, + }, +@@ -430,7 +428,6 @@ static struct clk_branch gpu_cc_hlos1_vote_gpu_smmu_clk = { + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "gpu_cc_hlos1_vote_gpu_smmu_clk", +- .flags = CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, +@@ -448,7 +445,7 @@ static struct clk_branch gpu_cc_hub_aon_clk = { + &gpu_cc_hub_clk_src.clkr.hw, + }, + .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_aon_ops, + }, + }, +@@ -466,7 +463,7 @@ static struct clk_branch gpu_cc_hub_cx_int_clk = { + &gpu_cc_hub_cx_int_div_clk_src.clkr.hw, + }, + .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_aon_ops, + }, + }, +@@ -480,7 +477,6 @@ static struct clk_branch gpu_cc_memnoc_gfx_clk = { + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "gpu_cc_memnoc_gfx_clk", +- .flags = CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, +@@ -494,7 +490,6 @@ static struct clk_branch gpu_cc_sleep_clk = { + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "gpu_cc_sleep_clk", +- .flags = CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, +@@ -528,16 +523,22 @@ static struct clk_regmap *gpu_cc_sa8775p_clocks[] = { + + static struct gdsc cx_gdsc = { + .gdscr = 0x9108, ++ .en_rest_wait_val = 0x2, ++ .en_few_wait_val = 0x2, ++ .clk_dis_wait_val = 0xf, + .gds_hw_ctrl = 0x953c, + .pd = { + .name = "cx_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +- .flags = VOTABLE | RETAIN_FF_ENABLE | ALWAYS_ON, ++ .flags = VOTABLE | RETAIN_FF_ENABLE, + }; + + static struct gdsc gx_gdsc = { + .gdscr = 0x905c, ++ .en_rest_wait_val = 0x2, ++ .en_few_wait_val = 0x2, ++ .clk_dis_wait_val = 0xf, + .pd = { + .name = "gx_gdsc", + .power_on = gdsc_gx_do_nothing_enable, +diff --git a/drivers/clk/qcom/gpucc-sm8350.c b/drivers/clk/qcom/gpucc-sm8350.c +index 8dc54dff983f3..33c4fb8891caa 100644 +--- a/drivers/clk/qcom/gpucc-sm8350.c ++++ b/drivers/clk/qcom/gpucc-sm8350.c +@@ -2,6 +2,7 @@ + /* + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2022, Linaro Limited ++ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include <linux/clk.h> +@@ -147,7 +148,7 @@ static struct clk_rcg2 gpu_cc_gmu_clk_src = { + .parent_data = gpu_cc_parent_data_0, + .num_parents = ARRAY_SIZE(gpu_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -169,7 +170,7 @@ static struct clk_rcg2 gpu_cc_hub_clk_src = { + .parent_data = gpu_cc_parent_data_1, + .num_parents = ARRAY_SIZE(gpu_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +diff --git a/drivers/clk/qcom/kpss-xcc.c b/drivers/clk/qcom/kpss-xcc.c +index 97358c98c6c98..d8c1f2b41eeb3 100644 +--- a/drivers/clk/qcom/kpss-xcc.c ++++ b/drivers/clk/qcom/kpss-xcc.c +@@ -63,9 +63,7 @@ static int kpss_xcc_driver_probe(struct platform_device *pdev) + if (IS_ERR(hw)) + return PTR_ERR(hw); + +- of_clk_add_hw_provider(dev->of_node, of_clk_hw_simple_get, hw); +- +- return 0; ++ return of_clk_add_hw_provider(dev->of_node, of_clk_hw_simple_get, hw); + } + + static struct platform_driver kpss_xcc_driver = { +diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c +index 3efc2aef31ce4..23c74e9f04c48 100644 +--- a/drivers/cpufreq/amd-pstate.c ++++ b/drivers/cpufreq/amd-pstate.c +@@ -175,6 +175,26 @@ static int amd_pstate_get_energy_pref_index(struct amd_cpudata *cpudata) + return index; + } + ++static void pstate_update_perf(struct amd_cpudata *cpudata, u32 min_perf, ++ u32 des_perf, u32 max_perf, bool fast_switch) ++{ ++ if (fast_switch) ++ wrmsrl(MSR_AMD_CPPC_REQ, READ_ONCE(cpudata->cppc_req_cached)); ++ else ++ wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, ++ READ_ONCE(cpudata->cppc_req_cached)); ++} ++ ++DEFINE_STATIC_CALL(amd_pstate_update_perf, pstate_update_perf); ++ ++static inline void amd_pstate_update_perf(struct amd_cpudata *cpudata, ++ u32 min_perf, u32 des_perf, ++ u32 max_perf, bool fast_switch) ++{ ++ static_call(amd_pstate_update_perf)(cpudata, min_perf, des_perf, ++ max_perf, fast_switch); ++} ++ + static int amd_pstate_set_epp(struct amd_cpudata *cpudata, u32 epp) + { + int ret; +@@ -191,6 +211,9 @@ static int amd_pstate_set_epp(struct amd_cpudata *cpudata, u32 epp) + if (!ret) + cpudata->epp_cached = epp; + } else { ++ amd_pstate_update_perf(cpudata, cpudata->min_limit_perf, 0U, ++ cpudata->max_limit_perf, false); ++ + perf_ctrls.energy_perf = epp; + ret = cppc_set_epp_perf(cpudata->cpu, &perf_ctrls, 1); + if (ret) { +@@ -361,16 +384,6 @@ static inline int amd_pstate_init_perf(struct amd_cpudata *cpudata) + return static_call(amd_pstate_init_perf)(cpudata); + } + +-static void pstate_update_perf(struct amd_cpudata *cpudata, u32 min_perf, +- u32 des_perf, u32 max_perf, bool fast_switch) +-{ +- if (fast_switch) +- wrmsrl(MSR_AMD_CPPC_REQ, READ_ONCE(cpudata->cppc_req_cached)); +- else +- wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, +- READ_ONCE(cpudata->cppc_req_cached)); +-} +- + static void cppc_update_perf(struct amd_cpudata *cpudata, + u32 min_perf, u32 des_perf, + u32 max_perf, bool fast_switch) +@@ -384,16 +397,6 @@ static void cppc_update_perf(struct amd_cpudata *cpudata, + cppc_set_perf(cpudata->cpu, &perf_ctrls); + } + +-DEFINE_STATIC_CALL(amd_pstate_update_perf, pstate_update_perf); +- +-static inline void amd_pstate_update_perf(struct amd_cpudata *cpudata, +- u32 min_perf, u32 des_perf, +- u32 max_perf, bool fast_switch) +-{ +- static_call(amd_pstate_update_perf)(cpudata, min_perf, des_perf, +- max_perf, fast_switch); +-} +- + static inline bool amd_pstate_sample(struct amd_cpudata *cpudata) + { + u64 aperf, mperf, tsc; +diff --git a/drivers/cpufreq/ti-cpufreq.c b/drivers/cpufreq/ti-cpufreq.c +index 3c37d78996607..d88ee87b1cd6f 100644 +--- a/drivers/cpufreq/ti-cpufreq.c ++++ b/drivers/cpufreq/ti-cpufreq.c +@@ -418,7 +418,7 @@ static int ti_cpufreq_probe(struct platform_device *pdev) + + ret = dev_pm_opp_set_config(opp_data->cpu_dev, &config); + if (ret < 0) { +- dev_err(opp_data->cpu_dev, "Failed to set OPP config\n"); ++ dev_err_probe(opp_data->cpu_dev, ret, "Failed to set OPP config\n"); + goto fail_put_node; + } + +diff --git a/drivers/crypto/intel/qat/qat_common/adf_cfg.c b/drivers/crypto/intel/qat/qat_common/adf_cfg.c +index 8836f015c39c4..2cf102ad4ca82 100644 +--- a/drivers/crypto/intel/qat/qat_common/adf_cfg.c ++++ b/drivers/crypto/intel/qat/qat_common/adf_cfg.c +@@ -290,17 +290,19 @@ int adf_cfg_add_key_value_param(struct adf_accel_dev *accel_dev, + * 3. if the key exists with the same value, then return without doing + * anything (the newly created key_val is freed). + */ ++ down_write(&cfg->lock); + if (!adf_cfg_key_val_get(accel_dev, section_name, key, temp_val)) { + if (strncmp(temp_val, key_val->val, sizeof(temp_val))) { + adf_cfg_keyval_remove(key, section); + } else { + kfree(key_val); +- return 0; ++ goto out; + } + } + +- down_write(&cfg->lock); + adf_cfg_keyval_add(key_val, section); ++ ++out: + up_write(&cfg->lock); + return 0; + } +diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c +index 037f1408e7983..02a1ab04f498e 100644 +--- a/drivers/dma/ti/k3-udma.c ++++ b/drivers/dma/ti/k3-udma.c +@@ -4470,7 +4470,9 @@ static int udma_get_mmrs(struct platform_device *pdev, struct udma_dev *ud) + ud->rchan_cnt = UDMA_CAP2_RCHAN_CNT(cap2); + break; + case DMA_TYPE_BCDMA: +- ud->bchan_cnt = BCDMA_CAP2_BCHAN_CNT(cap2); ++ ud->bchan_cnt = BCDMA_CAP2_BCHAN_CNT(cap2) + ++ BCDMA_CAP3_HBCHAN_CNT(cap3) + ++ BCDMA_CAP3_UBCHAN_CNT(cap3); + ud->tchan_cnt = BCDMA_CAP2_TCHAN_CNT(cap2); + ud->rchan_cnt = BCDMA_CAP2_RCHAN_CNT(cap2); + ud->rflow_cnt = ud->rchan_cnt; +diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile +index 61945d3113cc3..446364264e2b1 100644 +--- a/drivers/edac/Makefile ++++ b/drivers/edac/Makefile +@@ -54,11 +54,13 @@ obj-$(CONFIG_EDAC_MPC85XX) += mpc85xx_edac_mod.o + layerscape_edac_mod-y := fsl_ddr_edac.o layerscape_edac.o + obj-$(CONFIG_EDAC_LAYERSCAPE) += layerscape_edac_mod.o + +-skx_edac-y := skx_common.o skx_base.o +-obj-$(CONFIG_EDAC_SKX) += skx_edac.o ++skx_edac_common-y := skx_common.o + +-i10nm_edac-y := skx_common.o i10nm_base.o +-obj-$(CONFIG_EDAC_I10NM) += i10nm_edac.o ++skx_edac-y := skx_base.o ++obj-$(CONFIG_EDAC_SKX) += skx_edac.o skx_edac_common.o ++ ++i10nm_edac-y := i10nm_base.o ++obj-$(CONFIG_EDAC_I10NM) += i10nm_edac.o skx_edac_common.o + + obj-$(CONFIG_EDAC_CELL) += cell_edac.o + obj-$(CONFIG_EDAC_PPC4XX) += ppc4xx_edac.o +diff --git a/drivers/edac/skx_common.c b/drivers/edac/skx_common.c +index ce3e0069e028d..03d7a74ca22dc 100644 +--- a/drivers/edac/skx_common.c ++++ b/drivers/edac/skx_common.c +@@ -48,7 +48,7 @@ static u64 skx_tolm, skx_tohm; + static LIST_HEAD(dev_edac_list); + static bool skx_mem_cfg_2lm; + +-int __init skx_adxl_get(void) ++int skx_adxl_get(void) + { + const char * const *names; + int i, j; +@@ -110,12 +110,14 @@ int __init skx_adxl_get(void) + + return -ENODEV; + } ++EXPORT_SYMBOL_GPL(skx_adxl_get); + +-void __exit skx_adxl_put(void) ++void skx_adxl_put(void) + { + kfree(adxl_values); + kfree(adxl_msg); + } ++EXPORT_SYMBOL_GPL(skx_adxl_put); + + static bool skx_adxl_decode(struct decoded_addr *res, bool error_in_1st_level_mem) + { +@@ -187,12 +189,14 @@ void skx_set_mem_cfg(bool mem_cfg_2lm) + { + skx_mem_cfg_2lm = mem_cfg_2lm; + } ++EXPORT_SYMBOL_GPL(skx_set_mem_cfg); + + void skx_set_decode(skx_decode_f decode, skx_show_retry_log_f show_retry_log) + { + driver_decode = decode; + skx_show_retry_rd_err_log = show_retry_log; + } ++EXPORT_SYMBOL_GPL(skx_set_decode); + + int skx_get_src_id(struct skx_dev *d, int off, u8 *id) + { +@@ -206,6 +210,7 @@ int skx_get_src_id(struct skx_dev *d, int off, u8 *id) + *id = GET_BITFIELD(reg, 12, 14); + return 0; + } ++EXPORT_SYMBOL_GPL(skx_get_src_id); + + int skx_get_node_id(struct skx_dev *d, u8 *id) + { +@@ -219,6 +224,7 @@ int skx_get_node_id(struct skx_dev *d, u8 *id) + *id = GET_BITFIELD(reg, 0, 2); + return 0; + } ++EXPORT_SYMBOL_GPL(skx_get_node_id); + + static int get_width(u32 mtr) + { +@@ -284,6 +290,7 @@ int skx_get_all_bus_mappings(struct res_config *cfg, struct list_head **list) + *list = &dev_edac_list; + return ndev; + } ++EXPORT_SYMBOL_GPL(skx_get_all_bus_mappings); + + int skx_get_hi_lo(unsigned int did, int off[], u64 *tolm, u64 *tohm) + { +@@ -323,6 +330,7 @@ int skx_get_hi_lo(unsigned int did, int off[], u64 *tolm, u64 *tohm) + pci_dev_put(pdev); + return -ENODEV; + } ++EXPORT_SYMBOL_GPL(skx_get_hi_lo); + + static int skx_get_dimm_attr(u32 reg, int lobit, int hibit, int add, + int minval, int maxval, const char *name) +@@ -394,6 +402,7 @@ int skx_get_dimm_info(u32 mtr, u32 mcmtr, u32 amap, struct dimm_info *dimm, + + return 1; + } ++EXPORT_SYMBOL_GPL(skx_get_dimm_info); + + int skx_get_nvdimm_info(struct dimm_info *dimm, struct skx_imc *imc, + int chan, int dimmno, const char *mod_str) +@@ -442,6 +451,7 @@ int skx_get_nvdimm_info(struct dimm_info *dimm, struct skx_imc *imc, + + return (size == 0 || size == ~0ull) ? 0 : 1; + } ++EXPORT_SYMBOL_GPL(skx_get_nvdimm_info); + + int skx_register_mci(struct skx_imc *imc, struct pci_dev *pdev, + const char *ctl_name, const char *mod_str, +@@ -512,6 +522,7 @@ int skx_register_mci(struct skx_imc *imc, struct pci_dev *pdev, + imc->mci = NULL; + return rc; + } ++EXPORT_SYMBOL_GPL(skx_register_mci); + + static void skx_unregister_mci(struct skx_imc *imc) + { +@@ -684,6 +695,7 @@ int skx_mce_check_error(struct notifier_block *nb, unsigned long val, + mce->kflags |= MCE_HANDLED_EDAC; + return NOTIFY_DONE; + } ++EXPORT_SYMBOL_GPL(skx_mce_check_error); + + void skx_remove(void) + { +@@ -721,3 +733,8 @@ void skx_remove(void) + kfree(d); + } + } ++EXPORT_SYMBOL_GPL(skx_remove); ++ ++MODULE_LICENSE("GPL v2"); ++MODULE_AUTHOR("Tony Luck"); ++MODULE_DESCRIPTION("MC Driver for Intel server processors"); +diff --git a/drivers/edac/skx_common.h b/drivers/edac/skx_common.h +index b6d3607dffe27..11faf1db4fa48 100644 +--- a/drivers/edac/skx_common.h ++++ b/drivers/edac/skx_common.h +@@ -231,8 +231,8 @@ typedef int (*get_dimm_config_f)(struct mem_ctl_info *mci, + typedef bool (*skx_decode_f)(struct decoded_addr *res); + typedef void (*skx_show_retry_log_f)(struct decoded_addr *res, char *msg, int len, bool scrub_err); + +-int __init skx_adxl_get(void); +-void __exit skx_adxl_put(void); ++int skx_adxl_get(void); ++void skx_adxl_put(void); + void skx_set_decode(skx_decode_f decode, skx_show_retry_log_f show_retry_log); + void skx_set_mem_cfg(bool mem_cfg_2lm); + +diff --git a/drivers/firmware/efi/libstub/screen_info.c b/drivers/firmware/efi/libstub/screen_info.c +index a51ec201ca3cb..5d3a1e32d1776 100644 +--- a/drivers/firmware/efi/libstub/screen_info.c ++++ b/drivers/firmware/efi/libstub/screen_info.c +@@ -32,6 +32,8 @@ struct screen_info *__alloc_screen_info(void) + if (status != EFI_SUCCESS) + return NULL; + ++ memset(si, 0, sizeof(*si)); ++ + status = efi_bs_call(install_configuration_table, + &screen_info_guid, si); + if (status == EFI_SUCCESS) +diff --git a/drivers/firmware/efi/libstub/x86-stub.c b/drivers/firmware/efi/libstub/x86-stub.c +index 8e9f2ddfbe467..b2b06d18b7b4a 100644 +--- a/drivers/firmware/efi/libstub/x86-stub.c ++++ b/drivers/firmware/efi/libstub/x86-stub.c +@@ -469,11 +469,12 @@ void __noreturn efi_stub_entry(efi_handle_t handle, + efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, + efi_system_table_t *sys_table_arg) + { +- static struct boot_params boot_params __page_aligned_bss; +- struct setup_header *hdr = &boot_params.hdr; + efi_guid_t proto = LOADED_IMAGE_PROTOCOL_GUID; ++ struct boot_params *boot_params; ++ struct setup_header *hdr; + int options_size = 0; + efi_status_t status; ++ unsigned long alloc; + char *cmdline_ptr; + + if (efi_is_native()) +@@ -491,6 +492,13 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, + efi_exit(handle, status); + } + ++ status = efi_allocate_pages(PARAM_SIZE, &alloc, ULONG_MAX); ++ if (status != EFI_SUCCESS) ++ efi_exit(handle, status); ++ ++ boot_params = memset((void *)alloc, 0x0, PARAM_SIZE); ++ hdr = &boot_params->hdr; ++ + /* Assign the setup_header fields that the kernel actually cares about */ + hdr->root_flags = 1; + hdr->vid_mode = 0xffff; +@@ -500,17 +508,16 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, + + /* Convert unicode cmdline to ascii */ + cmdline_ptr = efi_convert_cmdline(image, &options_size); +- if (!cmdline_ptr) +- goto fail; ++ if (!cmdline_ptr) { ++ efi_free(PARAM_SIZE, alloc); ++ efi_exit(handle, EFI_OUT_OF_RESOURCES); ++ } + + efi_set_u64_split((unsigned long)cmdline_ptr, &hdr->cmd_line_ptr, +- &boot_params.ext_cmd_line_ptr); ++ &boot_params->ext_cmd_line_ptr); + +- efi_stub_entry(handle, sys_table_arg, &boot_params); ++ efi_stub_entry(handle, sys_table_arg, boot_params); + /* not reached */ +- +-fail: +- efi_exit(handle, status); + } + + static void add_e820ext(struct boot_params *params, +diff --git a/drivers/firmware/turris-mox-rwtm.c b/drivers/firmware/turris-mox-rwtm.c +index 2de0fb139ce17..3d354ebd38c28 100644 +--- a/drivers/firmware/turris-mox-rwtm.c ++++ b/drivers/firmware/turris-mox-rwtm.c +@@ -2,7 +2,7 @@ + /* + * Turris Mox rWTM firmware driver + * +- * Copyright (C) 2019 Marek Behún <kabel@kernel.org> ++ * Copyright (C) 2019, 2024 Marek Behún <kabel@kernel.org> + */ + + #include <linux/armada-37xx-rwtm-mailbox.h> +@@ -174,6 +174,9 @@ static void mox_rwtm_rx_callback(struct mbox_client *cl, void *data) + struct mox_rwtm *rwtm = dev_get_drvdata(cl->dev); + struct armada_37xx_rwtm_rx_msg *msg = data; + ++ if (completion_done(&rwtm->cmd_done)) ++ return; ++ + rwtm->reply = *msg; + complete(&rwtm->cmd_done); + } +@@ -199,9 +202,8 @@ static int mox_get_board_info(struct mox_rwtm *rwtm) + if (ret < 0) + return ret; + +- ret = wait_for_completion_timeout(&rwtm->cmd_done, HZ / 2); +- if (ret < 0) +- return ret; ++ if (!wait_for_completion_timeout(&rwtm->cmd_done, HZ / 2)) ++ return -ETIMEDOUT; + + ret = mox_get_status(MBOX_CMD_BOARD_INFO, reply->retval); + if (ret == -ENODATA) { +@@ -235,9 +237,8 @@ static int mox_get_board_info(struct mox_rwtm *rwtm) + if (ret < 0) + return ret; + +- ret = wait_for_completion_timeout(&rwtm->cmd_done, HZ / 2); +- if (ret < 0) +- return ret; ++ if (!wait_for_completion_timeout(&rwtm->cmd_done, HZ / 2)) ++ return -ETIMEDOUT; + + ret = mox_get_status(MBOX_CMD_ECDSA_PUB_KEY, reply->retval); + if (ret == -ENODATA) { +@@ -274,9 +275,8 @@ static int check_get_random_support(struct mox_rwtm *rwtm) + if (ret < 0) + return ret; + +- ret = wait_for_completion_timeout(&rwtm->cmd_done, HZ / 2); +- if (ret < 0) +- return ret; ++ if (!wait_for_completion_timeout(&rwtm->cmd_done, HZ / 2)) ++ return -ETIMEDOUT; + + return mox_get_status(MBOX_CMD_GET_RANDOM, rwtm->reply.retval); + } +@@ -499,6 +499,7 @@ static int turris_mox_rwtm_probe(struct platform_device *pdev) + platform_set_drvdata(pdev, rwtm); + + mutex_init(&rwtm->busy); ++ init_completion(&rwtm->cmd_done); + + rwtm->mbox_client.dev = dev; + rwtm->mbox_client.rx_callback = mox_rwtm_rx_callback; +@@ -512,8 +513,6 @@ static int turris_mox_rwtm_probe(struct platform_device *pdev) + goto remove_files; + } + +- init_completion(&rwtm->cmd_done); +- + ret = mox_get_board_info(rwtm); + if (ret < 0) + dev_warn(dev, "Cannot read board information: %i\n", ret); +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +index e1227b7c71b16..ea1bce13db941 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +@@ -5645,7 +5645,7 @@ int amdgpu_device_baco_exit(struct drm_device *dev) + adev->nbio.funcs->enable_doorbell_interrupt) + adev->nbio.funcs->enable_doorbell_interrupt(adev, true); + +- if (amdgpu_passthrough(adev) && ++ if (amdgpu_passthrough(adev) && adev->nbio.funcs && + adev->nbio.funcs->clear_doorbell_interrupt) + adev->nbio.funcs->clear_doorbell_interrupt(adev); + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c +index bc0eda1a729c5..0b6a0e149f1c4 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c +@@ -650,7 +650,6 @@ void amdgpu_gmc_noretry_set(struct amdgpu_device *adev) + struct amdgpu_gmc *gmc = &adev->gmc; + uint32_t gc_ver = adev->ip_versions[GC_HWIP][0]; + bool noretry_default = (gc_ver == IP_VERSION(9, 0, 1) || +- gc_ver == IP_VERSION(9, 3, 0) || + gc_ver == IP_VERSION(9, 4, 0) || + gc_ver == IP_VERSION(9, 4, 1) || + gc_ver == IP_VERSION(9, 4, 2) || +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +index f5e78b0c08f7e..f02b6232680f3 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +@@ -418,7 +418,7 @@ uint64_t amdgpu_vm_generation(struct amdgpu_device *adev, struct amdgpu_vm *vm) + if (!vm) + return result; + +- result += vm->generation; ++ result += lower_32_bits(vm->generation); + /* Add one if the page tables will be re-generated on next CS */ + if (drm_sched_entity_error(&vm->delayed)) + ++result; +@@ -443,13 +443,14 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm, + int (*validate)(void *p, struct amdgpu_bo *bo), + void *param) + { ++ uint64_t new_vm_generation = amdgpu_vm_generation(adev, vm); + struct amdgpu_vm_bo_base *bo_base; + struct amdgpu_bo *shadow; + struct amdgpu_bo *bo; + int r; + +- if (drm_sched_entity_error(&vm->delayed)) { +- ++vm->generation; ++ if (vm->generation != new_vm_generation) { ++ vm->generation = new_vm_generation; + amdgpu_vm_bo_reset_state_machine(vm); + amdgpu_vm_fini_entities(vm); + r = amdgpu_vm_init_entities(adev, vm); +@@ -2192,7 +2193,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, + vm->last_update = dma_fence_get_stub(); + vm->last_unlocked = dma_fence_get_stub(); + vm->last_tlb_flush = dma_fence_get_stub(); +- vm->generation = 0; ++ vm->generation = amdgpu_vm_generation(adev, NULL); + + mutex_init(&vm->eviction_lock); + vm->evicting = false; +diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +index 8ace3f6210d37..6d2b9d260d92c 100644 +--- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +@@ -1949,7 +1949,7 @@ gmc_v9_0_init_sw_mem_ranges(struct amdgpu_device *adev, + break; + } + +- size = adev->gmc.real_vram_size >> AMDGPU_GPU_PAGE_SHIFT; ++ size = (adev->gmc.real_vram_size + SZ_16M) >> AMDGPU_GPU_PAGE_SHIFT; + size /= adev->gmc.num_mem_partitions; + + for (i = 0; i < adev->gmc.num_mem_partitions; ++i) { +diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c +index 72b18156debbd..47d4840c6275c 100644 +--- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c ++++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c +@@ -188,6 +188,14 @@ static void sdma_v5_2_ring_set_wptr(struct amdgpu_ring *ring) + DRM_DEBUG("calling WDOORBELL64(0x%08x, 0x%016llx)\n", + ring->doorbell_index, ring->wptr << 2); + WDOORBELL64(ring->doorbell_index, ring->wptr << 2); ++ /* SDMA seems to miss doorbells sometimes when powergating kicks in. ++ * Updating the wptr directly will wake it. This is only safe because ++ * we disallow gfxoff in begin_use() and then allow it again in end_use(). ++ */ ++ WREG32(sdma_v5_2_get_reg_offset(adev, ring->me, mmSDMA0_GFX_RB_WPTR), ++ lower_32_bits(ring->wptr << 2)); ++ WREG32(sdma_v5_2_get_reg_offset(adev, ring->me, mmSDMA0_GFX_RB_WPTR_HI), ++ upper_32_bits(ring->wptr << 2)); + } else { + DRM_DEBUG("Not using doorbell -- " + "mmSDMA%i_GFX_RB_WPTR == 0x%08x " +@@ -1666,6 +1674,10 @@ static void sdma_v5_2_ring_begin_use(struct amdgpu_ring *ring) + * but it shouldn't hurt for other parts since + * this GFXOFF will be disallowed anyway when SDMA is + * active, this just makes it explicit. ++ * sdma_v5_2_ring_set_wptr() takes advantage of this ++ * to update the wptr because sometimes SDMA seems to miss ++ * doorbells when entering PG. If you remove this, update ++ * sdma_v5_2_ring_set_wptr() as well! + */ + amdgpu_gfx_off_ctrl(adev, false); + } +diff --git a/drivers/gpu/drm/amd/amdgpu/smu_v13_0_10.c b/drivers/gpu/drm/amd/amdgpu/smu_v13_0_10.c +index ae29620b1ea40..a7cef33a2a3da 100644 +--- a/drivers/gpu/drm/amd/amdgpu/smu_v13_0_10.c ++++ b/drivers/gpu/drm/amd/amdgpu/smu_v13_0_10.c +@@ -92,7 +92,7 @@ static int smu_v13_0_10_mode2_suspend_ip(struct amdgpu_device *adev) + adev->ip_blocks[i].status.hw = false; + } + +- return r; ++ return 0; + } + + static int +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c +index 42d881809dc70..1ac66c5337df4 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c +@@ -686,7 +686,7 @@ static void update_mqd_v9_4_3(struct mqd_manager *mm, void *mqd, + m = get_mqd(mqd + size * xcc); + update_mqd(mm, m, q, minfo); + +- update_cu_mask(mm, mqd, minfo, xcc); ++ update_cu_mask(mm, m, minfo, xcc); + + if (q->format == KFD_QUEUE_FORMAT_AQL) { + switch (xcc) { +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c +index a80e45300783c..f4f3ca7aad60e 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c +@@ -154,7 +154,8 @@ const struct dc_plane_status *dc_plane_get_status( + if (pipe_ctx->plane_state != plane_state) + continue; + +- pipe_ctx->plane_state->status.is_flip_pending = false; ++ if (pipe_ctx->plane_state) ++ pipe_ctx->plane_state->status.is_flip_pending = false; + + break; + } +diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c +index c097aed4722b9..c0adfa46ac789 100644 +--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c +@@ -79,8 +79,8 @@ MODULE_FIRMWARE("amdgpu/smu_13_0_10.bin"); + #define PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD_MASK 0x00000070L + #define PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD__SHIFT 0x4 + #define smnPCIE_LC_SPEED_CNTL 0x11140290 +-#define PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK 0xC000 +-#define PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT 0xE ++#define PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK 0xE0 ++#define PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT 0x5 + + static const int link_width[] = {0, 1, 2, 4, 8, 12, 16}; + +diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c +index 2c661f28410ed..b645c5998230b 100644 +--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c ++++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c +@@ -5,6 +5,7 @@ + * + */ + #include <linux/clk.h> ++#include <linux/of.h> + #include <linux/pm_runtime.h> + #include <linux/spinlock.h> + +@@ -610,12 +611,34 @@ get_crtc_primary(struct komeda_kms_dev *kms, struct komeda_crtc *crtc) + return NULL; + } + ++static int komeda_attach_bridge(struct device *dev, ++ struct komeda_pipeline *pipe, ++ struct drm_encoder *encoder) ++{ ++ struct drm_bridge *bridge; ++ int err; ++ ++ bridge = devm_drm_of_get_bridge(dev, pipe->of_node, ++ KOMEDA_OF_PORT_OUTPUT, 0); ++ if (IS_ERR(bridge)) ++ return dev_err_probe(dev, PTR_ERR(bridge), "remote bridge not found for pipe: %s\n", ++ of_node_full_name(pipe->of_node)); ++ ++ err = drm_bridge_attach(encoder, bridge, NULL, 0); ++ if (err) ++ dev_err(dev, "bridge_attach() failed for pipe: %s\n", ++ of_node_full_name(pipe->of_node)); ++ ++ return err; ++} ++ + static int komeda_crtc_add(struct komeda_kms_dev *kms, + struct komeda_crtc *kcrtc) + { + struct drm_crtc *crtc = &kcrtc->base; + struct drm_device *base = &kms->base; +- struct drm_bridge *bridge; ++ struct komeda_pipeline *pipe = kcrtc->master; ++ struct drm_encoder *encoder = &kcrtc->encoder; + int err; + + err = drm_crtc_init_with_planes(base, crtc, +@@ -626,27 +649,25 @@ static int komeda_crtc_add(struct komeda_kms_dev *kms, + + drm_crtc_helper_add(crtc, &komeda_crtc_helper_funcs); + +- crtc->port = kcrtc->master->of_output_port; ++ crtc->port = pipe->of_output_port; + + /* Construct an encoder for each pipeline and attach it to the remote + * bridge + */ + kcrtc->encoder.possible_crtcs = drm_crtc_mask(crtc); +- err = drm_simple_encoder_init(base, &kcrtc->encoder, +- DRM_MODE_ENCODER_TMDS); ++ err = drm_simple_encoder_init(base, encoder, DRM_MODE_ENCODER_TMDS); + if (err) + return err; + +- bridge = devm_drm_of_get_bridge(base->dev, kcrtc->master->of_node, +- KOMEDA_OF_PORT_OUTPUT, 0); +- if (IS_ERR(bridge)) +- return PTR_ERR(bridge); +- +- err = drm_bridge_attach(&kcrtc->encoder, bridge, NULL, 0); ++ if (pipe->of_output_links[0]) { ++ err = komeda_attach_bridge(base->dev, pipe, encoder); ++ if (err) ++ return err; ++ } + + drm_crtc_enable_color_mgmt(crtc, 0, true, KOMEDA_COLOR_LUT_SIZE); + +- return err; ++ return 0; + } + + int komeda_kms_add_crtcs(struct komeda_kms_dev *kms, struct komeda_dev *mdev) +diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c +index 2f300f5ca051c..4ad527fe04f27 100644 +--- a/drivers/gpu/drm/bridge/ite-it6505.c ++++ b/drivers/gpu/drm/bridge/ite-it6505.c +@@ -1306,9 +1306,15 @@ static void it6505_video_reset(struct it6505 *it6505) + it6505_link_reset_step_train(it6505); + it6505_set_bits(it6505, REG_DATA_MUTE_CTRL, EN_VID_MUTE, EN_VID_MUTE); + it6505_set_bits(it6505, REG_INFOFRAME_CTRL, EN_VID_CTRL_PKT, 0x00); +- it6505_set_bits(it6505, REG_RESET_CTRL, VIDEO_RESET, VIDEO_RESET); ++ ++ it6505_set_bits(it6505, REG_VID_BUS_CTRL1, TX_FIFO_RESET, TX_FIFO_RESET); ++ it6505_set_bits(it6505, REG_VID_BUS_CTRL1, TX_FIFO_RESET, 0x00); ++ + it6505_set_bits(it6505, REG_501_FIFO_CTRL, RST_501_FIFO, RST_501_FIFO); + it6505_set_bits(it6505, REG_501_FIFO_CTRL, RST_501_FIFO, 0x00); ++ ++ it6505_set_bits(it6505, REG_RESET_CTRL, VIDEO_RESET, VIDEO_RESET); ++ usleep_range(1000, 2000); + it6505_set_bits(it6505, REG_RESET_CTRL, VIDEO_RESET, 0x00); + } + +@@ -2240,14 +2246,15 @@ static void it6505_link_training_work(struct work_struct *work) + ret = it6505_link_start_auto_train(it6505); + DRM_DEV_DEBUG_DRIVER(dev, "auto train %s, auto_train_retry: %d", + ret ? "pass" : "failed", it6505->auto_train_retry); +- it6505->auto_train_retry--; + + if (ret) { ++ it6505->auto_train_retry = AUTO_TRAIN_RETRY; + it6505_link_train_ok(it6505); +- return; ++ } else { ++ it6505->auto_train_retry--; ++ it6505_dump(it6505); + } + +- it6505_dump(it6505); + } + + static void it6505_plugged_status_to_codec(struct it6505 *it6505) +@@ -2468,31 +2475,53 @@ static void it6505_irq_link_train_fail(struct it6505 *it6505) + schedule_work(&it6505->link_works); + } + +-static void it6505_irq_video_fifo_error(struct it6505 *it6505) ++static bool it6505_test_bit(unsigned int bit, const unsigned int *addr) + { +- struct device *dev = it6505->dev; +- +- DRM_DEV_DEBUG_DRIVER(dev, "video fifo overflow interrupt"); +- it6505->auto_train_retry = AUTO_TRAIN_RETRY; +- flush_work(&it6505->link_works); +- it6505_stop_hdcp(it6505); +- it6505_video_reset(it6505); ++ return 1 & (addr[bit / BITS_PER_BYTE] >> (bit % BITS_PER_BYTE)); + } + +-static void it6505_irq_io_latch_fifo_overflow(struct it6505 *it6505) ++static void it6505_irq_video_handler(struct it6505 *it6505, const int *int_status) + { + struct device *dev = it6505->dev; ++ int reg_0d, reg_int03; + +- DRM_DEV_DEBUG_DRIVER(dev, "IO latch fifo overflow interrupt"); +- it6505->auto_train_retry = AUTO_TRAIN_RETRY; +- flush_work(&it6505->link_works); +- it6505_stop_hdcp(it6505); +- it6505_video_reset(it6505); +-} ++ /* ++ * When video SCDT change with video not stable, ++ * Or video FIFO error, need video reset ++ */ + +-static bool it6505_test_bit(unsigned int bit, const unsigned int *addr) +-{ +- return 1 & (addr[bit / BITS_PER_BYTE] >> (bit % BITS_PER_BYTE)); ++ if ((!it6505_get_video_status(it6505) && ++ (it6505_test_bit(INT_SCDT_CHANGE, (unsigned int *)int_status))) || ++ (it6505_test_bit(BIT_INT_IO_FIFO_OVERFLOW, ++ (unsigned int *)int_status)) || ++ (it6505_test_bit(BIT_INT_VID_FIFO_ERROR, ++ (unsigned int *)int_status))) { ++ it6505->auto_train_retry = AUTO_TRAIN_RETRY; ++ flush_work(&it6505->link_works); ++ it6505_stop_hdcp(it6505); ++ it6505_video_reset(it6505); ++ ++ usleep_range(10000, 11000); ++ ++ /* ++ * Clear FIFO error IRQ to prevent fifo error -> reset loop ++ * HW will trigger SCDT change IRQ again when video stable ++ */ ++ ++ reg_int03 = it6505_read(it6505, INT_STATUS_03); ++ reg_0d = it6505_read(it6505, REG_SYSTEM_STS); ++ ++ reg_int03 &= (BIT(INT_VID_FIFO_ERROR) | BIT(INT_IO_LATCH_FIFO_OVERFLOW)); ++ it6505_write(it6505, INT_STATUS_03, reg_int03); ++ ++ DRM_DEV_DEBUG_DRIVER(dev, "reg08 = 0x%02x", reg_int03); ++ DRM_DEV_DEBUG_DRIVER(dev, "reg0D = 0x%02x", reg_0d); ++ ++ return; ++ } ++ ++ if (it6505_test_bit(INT_SCDT_CHANGE, (unsigned int *)int_status)) ++ it6505_irq_scdt(it6505); + } + + static irqreturn_t it6505_int_threaded_handler(int unused, void *data) +@@ -2505,15 +2534,12 @@ static irqreturn_t it6505_int_threaded_handler(int unused, void *data) + } irq_vec[] = { + { BIT_INT_HPD, it6505_irq_hpd }, + { BIT_INT_HPD_IRQ, it6505_irq_hpd_irq }, +- { BIT_INT_SCDT, it6505_irq_scdt }, + { BIT_INT_HDCP_FAIL, it6505_irq_hdcp_fail }, + { BIT_INT_HDCP_DONE, it6505_irq_hdcp_done }, + { BIT_INT_AUX_CMD_FAIL, it6505_irq_aux_cmd_fail }, + { BIT_INT_HDCP_KSV_CHECK, it6505_irq_hdcp_ksv_check }, + { BIT_INT_AUDIO_FIFO_ERROR, it6505_irq_audio_fifo_error }, + { BIT_INT_LINK_TRAIN_FAIL, it6505_irq_link_train_fail }, +- { BIT_INT_VID_FIFO_ERROR, it6505_irq_video_fifo_error }, +- { BIT_INT_IO_FIFO_OVERFLOW, it6505_irq_io_latch_fifo_overflow }, + }; + int int_status[3], i; + +@@ -2543,6 +2569,7 @@ static irqreturn_t it6505_int_threaded_handler(int unused, void *data) + if (it6505_test_bit(irq_vec[i].bit, (unsigned int *)int_status)) + irq_vec[i].handler(it6505); + } ++ it6505_irq_video_handler(it6505, (unsigned int *)int_status); + } + + pm_runtime_put_sync(dev); +diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c +index 6d169c83b0623..9023c0216a8a4 100644 +--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c ++++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c +@@ -2923,7 +2923,7 @@ static int drm_dp_send_link_address(struct drm_dp_mst_topology_mgr *mgr, + + /* FIXME: Actually do some real error handling here */ + ret = drm_dp_mst_wait_tx_reply(mstb, txmsg); +- if (ret <= 0) { ++ if (ret < 0) { + drm_err(mgr->dev, "Sending link address failed with %d\n", ret); + goto out; + } +@@ -2975,7 +2975,7 @@ static int drm_dp_send_link_address(struct drm_dp_mst_topology_mgr *mgr, + mutex_unlock(&mgr->lock); + + out: +- if (ret <= 0) ++ if (ret < 0) + mstb->link_address_sent = false; + kfree(txmsg); + return ret < 0 ? ret : changed; +diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c +index b5f73502e3dd4..69fccbcd92c62 100644 +--- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c ++++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c +@@ -356,9 +356,11 @@ static void *etnaviv_gem_vmap_impl(struct etnaviv_gem_object *obj) + + static inline enum dma_data_direction etnaviv_op_to_dma_dir(u32 op) + { +- if (op & ETNA_PREP_READ) ++ op &= ETNA_PREP_READ | ETNA_PREP_WRITE; ++ ++ if (op == ETNA_PREP_READ) + return DMA_FROM_DEVICE; +- else if (op & ETNA_PREP_WRITE) ++ else if (op == ETNA_PREP_WRITE) + return DMA_TO_DEVICE; + else + return DMA_BIDIRECTIONAL; +diff --git a/drivers/gpu/drm/etnaviv/etnaviv_sched.c b/drivers/gpu/drm/etnaviv/etnaviv_sched.c +index 345fec6cb1a4c..97e406d9ac06f 100644 +--- a/drivers/gpu/drm/etnaviv/etnaviv_sched.c ++++ b/drivers/gpu/drm/etnaviv/etnaviv_sched.c +@@ -38,9 +38,6 @@ static enum drm_gpu_sched_stat etnaviv_sched_timedout_job(struct drm_sched_job + u32 dma_addr; + int change; + +- /* block scheduler */ +- drm_sched_stop(&gpu->sched, sched_job); +- + /* + * If the GPU managed to complete this jobs fence, the timout is + * spurious. Bail out. +@@ -63,6 +60,9 @@ static enum drm_gpu_sched_stat etnaviv_sched_timedout_job(struct drm_sched_job + goto out_no_timeout; + } + ++ /* block scheduler */ ++ drm_sched_stop(&gpu->sched, sched_job); ++ + if(sched_job) + drm_sched_increase_karma(sched_job); + +@@ -76,8 +76,7 @@ static enum drm_gpu_sched_stat etnaviv_sched_timedout_job(struct drm_sched_job + return DRM_GPU_SCHED_STAT_NOMINAL; + + out_no_timeout: +- /* restart scheduler after GPU is usable again */ +- drm_sched_start(&gpu->sched, true); ++ list_add(&sched_job->list, &sched_job->sched->pending_list); + return DRM_GPU_SCHED_STAT_NOMINAL; + } + +diff --git a/drivers/gpu/drm/gma500/cdv_intel_lvds.c b/drivers/gpu/drm/gma500/cdv_intel_lvds.c +index f08a6803dc184..3adc2c9ab72da 100644 +--- a/drivers/gpu/drm/gma500/cdv_intel_lvds.c ++++ b/drivers/gpu/drm/gma500/cdv_intel_lvds.c +@@ -311,6 +311,9 @@ static int cdv_intel_lvds_get_modes(struct drm_connector *connector) + if (mode_dev->panel_fixed_mode != NULL) { + struct drm_display_mode *mode = + drm_mode_duplicate(dev, mode_dev->panel_fixed_mode); ++ if (!mode) ++ return 0; ++ + drm_mode_probed_add(connector, mode); + return 1; + } +diff --git a/drivers/gpu/drm/gma500/psb_intel_lvds.c b/drivers/gpu/drm/gma500/psb_intel_lvds.c +index 8486de230ec91..8d1be94a443b2 100644 +--- a/drivers/gpu/drm/gma500/psb_intel_lvds.c ++++ b/drivers/gpu/drm/gma500/psb_intel_lvds.c +@@ -504,6 +504,9 @@ static int psb_intel_lvds_get_modes(struct drm_connector *connector) + if (mode_dev->panel_fixed_mode != NULL) { + struct drm_display_mode *mode = + drm_mode_duplicate(dev, mode_dev->panel_fixed_mode); ++ if (!mode) ++ return 0; ++ + drm_mode_probed_add(connector, mode); + return 1; + } +diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c +index 2936a6c02d6a1..c8b6d0f79c9b4 100644 +--- a/drivers/gpu/drm/i915/display/intel_dp.c ++++ b/drivers/gpu/drm/i915/display/intel_dp.c +@@ -4374,6 +4374,8 @@ int intel_dp_retrain_link(struct intel_encoder *encoder, + !intel_dp_mst_is_master_trans(crtc_state)) + continue; + ++ intel_dp->link_trained = false; ++ + intel_dp_check_frl_training(intel_dp); + intel_dp_pcon_dsc_configure(intel_dp, crtc_state); + intel_dp_start_link_train(intel_dp, 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 a62bca622b0a1..eb5559e1a2002 100644 +--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c ++++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c +@@ -114,10 +114,24 @@ intel_dp_set_lttpr_transparent_mode(struct intel_dp *intel_dp, bool enable) + return drm_dp_dpcd_write(&intel_dp->aux, DP_PHY_REPEATER_MODE, &val, 1) == 1; + } + +-static int intel_dp_init_lttpr(struct intel_dp *intel_dp, const u8 dpcd[DP_RECEIVER_CAP_SIZE]) ++static bool intel_dp_lttpr_transparent_mode_enabled(struct intel_dp *intel_dp) ++{ ++ return intel_dp->lttpr_common_caps[DP_PHY_REPEATER_MODE - ++ DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV] == ++ DP_PHY_REPEATER_MODE_TRANSPARENT; ++} ++ ++/* ++ * Read the LTTPR common capabilities and switch the LTTPR PHYs to ++ * non-transparent mode if this is supported. Preserve the ++ * transparent/non-transparent mode on an active link. ++ * ++ * Return the number of detected LTTPRs in non-transparent mode or 0 if the ++ * LTTPRs are in transparent mode or the detection failed. ++ */ ++static int intel_dp_init_lttpr_phys(struct intel_dp *intel_dp, const u8 dpcd[DP_RECEIVER_CAP_SIZE]) + { + int lttpr_count; +- int i; + + if (!intel_dp_read_lttpr_common_caps(intel_dp, dpcd)) + return 0; +@@ -131,6 +145,19 @@ static int intel_dp_init_lttpr(struct intel_dp *intel_dp, const u8 dpcd[DP_RECEI + if (lttpr_count == 0) + return 0; + ++ /* ++ * Don't change the mode on an active link, to prevent a loss of link ++ * synchronization. See DP Standard v2.0 3.6.7. about the LTTPR ++ * resetting its internal state when the mode is changed from ++ * non-transparent to transparent. ++ */ ++ if (intel_dp->link_trained) { ++ if (lttpr_count < 0 || intel_dp_lttpr_transparent_mode_enabled(intel_dp)) ++ goto out_reset_lttpr_count; ++ ++ return lttpr_count; ++ } ++ + /* + * See DP Standard v2.0 3.6.6.1. about the explicit disabling of + * non-transparent mode and the disable->enable non-transparent mode +@@ -151,11 +178,25 @@ static int intel_dp_init_lttpr(struct intel_dp *intel_dp, const u8 dpcd[DP_RECEI + "Switching to LTTPR non-transparent LT mode failed, fall-back to transparent mode\n"); + + intel_dp_set_lttpr_transparent_mode(intel_dp, true); +- intel_dp_reset_lttpr_count(intel_dp); + +- return 0; ++ goto out_reset_lttpr_count; + } + ++ return lttpr_count; ++ ++out_reset_lttpr_count: ++ intel_dp_reset_lttpr_count(intel_dp); ++ ++ return 0; ++} ++ ++static int intel_dp_init_lttpr(struct intel_dp *intel_dp, const u8 dpcd[DP_RECEIVER_CAP_SIZE]) ++{ ++ int lttpr_count; ++ int i; ++ ++ lttpr_count = intel_dp_init_lttpr_phys(intel_dp, dpcd); ++ + for (i = 0; i < lttpr_count; i++) + intel_dp_read_lttpr_phy_caps(intel_dp, dpcd, DP_PHY_LTTPR(i)); + +@@ -1353,10 +1394,10 @@ void intel_dp_start_link_train(struct intel_dp *intel_dp, + { + struct drm_i915_private *i915 = dp_to_i915(intel_dp); + bool passed; +- + /* +- * TODO: Reiniting LTTPRs here won't be needed once proper connector +- * HW state readout is added. ++ * Reinit the LTTPRs here to ensure that they are switched to ++ * non-transparent mode. During an earlier LTTPR detection this ++ * could've been prevented by an active link. + */ + int lttpr_count = intel_dp_init_lttpr_and_dprx_caps(intel_dp); + +diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c +index 42e09f1589205..2065be5a196bf 100644 +--- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c ++++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c +@@ -3315,11 +3315,7 @@ static void remove_from_engine(struct i915_request *rq) + + static bool can_preempt(struct intel_engine_cs *engine) + { +- if (GRAPHICS_VER(engine->i915) > 8) +- return true; +- +- /* GPGPU on bdw requires extra w/a; not implemented */ +- return engine->class != RENDER_CLASS; ++ return GRAPHICS_VER(engine->i915) > 8; + } + + static void kick_execlists(const struct i915_request *rq, int prio) +diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +index 2bffe42454666..6f15069da8b02 100644 +--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c ++++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +@@ -38,6 +38,7 @@ + #define DISP_REG_OVL_PITCH_MSB(n) (0x0040 + 0x20 * (n)) + #define OVL_PITCH_MSB_2ND_SUBBUF BIT(16) + #define DISP_REG_OVL_PITCH(n) (0x0044 + 0x20 * (n)) ++#define OVL_CONST_BLEND BIT(28) + #define DISP_REG_OVL_RDMA_CTRL(n) (0x00c0 + 0x20 * (n)) + #define DISP_REG_OVL_RDMA_GMC(n) (0x00c8 + 0x20 * (n)) + #define DISP_REG_OVL_ADDR_MT2701 0x0040 +@@ -71,6 +72,8 @@ + #define OVL_CON_VIRT_FLIP BIT(9) + #define OVL_CON_HORZ_FLIP BIT(10) + ++#define OVL_COLOR_ALPHA GENMASK(31, 24) ++ + static const u32 mt8173_formats[] = { + DRM_FORMAT_XRGB8888, + DRM_FORMAT_ARGB8888, +@@ -273,7 +276,13 @@ void mtk_ovl_config(struct device *dev, unsigned int w, + if (w != 0 && h != 0) + mtk_ddp_write_relaxed(cmdq_pkt, h << 16 | w, &ovl->cmdq_reg, ovl->regs, + DISP_REG_OVL_ROI_SIZE); +- mtk_ddp_write_relaxed(cmdq_pkt, 0x0, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_ROI_BGCLR); ++ ++ /* ++ * The background color must be opaque black (ARGB), ++ * otherwise the alpha blending will have no effect ++ */ ++ mtk_ddp_write_relaxed(cmdq_pkt, OVL_COLOR_ALPHA, &ovl->cmdq_reg, ++ ovl->regs, DISP_REG_OVL_ROI_BGCLR); + + mtk_ddp_write(cmdq_pkt, 0x1, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_RST); + mtk_ddp_write(cmdq_pkt, 0x0, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_RST); +@@ -407,6 +416,7 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx, + unsigned int fmt = pending->format; + unsigned int offset = (pending->y << 16) | pending->x; + unsigned int src_size = (pending->height << 16) | pending->width; ++ unsigned int ignore_pixel_alpha = 0; + unsigned int con; + bool is_afbc = pending->modifier != DRM_FORMAT_MOD_LINEAR; + union overlay_pitch { +@@ -428,6 +438,14 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx, + if (state->base.fb && state->base.fb->format->has_alpha) + con |= OVL_CON_AEN | OVL_CON_ALPHA; + ++ /* CONST_BLD must be enabled for XRGB formats although the alpha channel ++ * can be ignored, or OVL will still read the value from memory. ++ * For RGB888 related formats, whether CONST_BLD is enabled or not won't ++ * affect the result. Therefore we use !has_alpha as the condition. ++ */ ++ if (state->base.fb && !state->base.fb->format->has_alpha) ++ ignore_pixel_alpha = OVL_CONST_BLEND; ++ + if (pending->rotation & DRM_MODE_REFLECT_Y) { + con |= OVL_CON_VIRT_FLIP; + addr += (pending->height - 1) * pending->pitch; +@@ -443,8 +461,8 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx, + + mtk_ddp_write_relaxed(cmdq_pkt, con, &ovl->cmdq_reg, ovl->regs, + DISP_REG_OVL_CON(idx)); +- mtk_ddp_write_relaxed(cmdq_pkt, overlay_pitch.split_pitch.lsb, &ovl->cmdq_reg, ovl->regs, +- DISP_REG_OVL_PITCH(idx)); ++ mtk_ddp_write_relaxed(cmdq_pkt, overlay_pitch.split_pitch.lsb | ignore_pixel_alpha, ++ &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH(idx)); + mtk_ddp_write_relaxed(cmdq_pkt, src_size, &ovl->cmdq_reg, ovl->regs, + DISP_REG_OVL_SRC_SIZE(idx)); + mtk_ddp_write_relaxed(cmdq_pkt, offset, &ovl->cmdq_reg, ovl->regs, +diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c +index 6bf6367853fba..8f0c47e868748 100644 +--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c ++++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c +@@ -111,7 +111,7 @@ void mtk_ovl_adaptor_layer_config(struct device *dev, unsigned int idx, + merge = ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MERGE0 + idx]; + ethdr = ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0]; + +- if (!pending->enable) { ++ if (!pending->enable || !pending->width || !pending->height) { + mtk_merge_stop_cmdq(merge, cmdq_pkt); + mtk_mdp_rdma_stop(rdma_l, cmdq_pkt); + mtk_mdp_rdma_stop(rdma_r, cmdq_pkt); +diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c +index af03a22772fed..48a4defbc66cc 100644 +--- a/drivers/gpu/drm/mediatek/mtk_dp.c ++++ b/drivers/gpu/drm/mediatek/mtk_dp.c +@@ -2027,12 +2027,12 @@ static enum drm_connector_status mtk_dp_bdg_detect(struct drm_bridge *bridge) + return ret; + } + +-static struct edid *mtk_dp_get_edid(struct drm_bridge *bridge, +- struct drm_connector *connector) ++static const struct drm_edid *mtk_dp_edid_read(struct drm_bridge *bridge, ++ struct drm_connector *connector) + { + struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge); + bool enabled = mtk_dp->enabled; +- struct edid *new_edid = NULL; ++ const struct drm_edid *drm_edid; + struct mtk_dp_audio_cfg *audio_caps = &mtk_dp->info.audio_cur_cfg; + + if (!enabled) { +@@ -2040,7 +2040,7 @@ static struct edid *mtk_dp_get_edid(struct drm_bridge *bridge, + mtk_dp_aux_panel_poweron(mtk_dp, true); + } + +- new_edid = drm_get_edid(connector, &mtk_dp->aux.ddc); ++ drm_edid = drm_edid_read_ddc(connector, &mtk_dp->aux.ddc); + + /* + * Parse capability here to let atomic_get_input_bus_fmts and +@@ -2048,17 +2048,32 @@ static struct edid *mtk_dp_get_edid(struct drm_bridge *bridge, + */ + if (mtk_dp_parse_capabilities(mtk_dp)) { + drm_err(mtk_dp->drm_dev, "Can't parse capabilities\n"); +- kfree(new_edid); +- new_edid = NULL; ++ drm_edid_free(drm_edid); ++ drm_edid = NULL; + } + +- if (new_edid) { ++ if (drm_edid) { ++ /* ++ * FIXME: get rid of drm_edid_raw() ++ */ ++ const struct edid *edid = drm_edid_raw(drm_edid); + struct cea_sad *sads; ++ int ret; + +- audio_caps->sad_count = drm_edid_to_sad(new_edid, &sads); +- kfree(sads); ++ ret = drm_edid_to_sad(edid, &sads); ++ /* Ignore any errors */ ++ if (ret < 0) ++ ret = 0; ++ if (ret) ++ kfree(sads); ++ audio_caps->sad_count = ret; + +- audio_caps->detect_monitor = drm_detect_monitor_audio(new_edid); ++ /* ++ * FIXME: This should use connector->display_info.has_audio from ++ * a path that has read the EDID and called ++ * drm_edid_connector_update(). ++ */ ++ audio_caps->detect_monitor = drm_detect_monitor_audio(edid); + } + + if (!enabled) { +@@ -2066,7 +2081,7 @@ static struct edid *mtk_dp_get_edid(struct drm_bridge *bridge, + drm_atomic_bridge_chain_post_disable(bridge, connector->state->state); + } + +- return new_edid; ++ return drm_edid; + } + + static ssize_t mtk_dp_aux_transfer(struct drm_dp_aux *mtk_aux, +@@ -2418,7 +2433,7 @@ static const struct drm_bridge_funcs mtk_dp_bridge_funcs = { + .atomic_enable = mtk_dp_bridge_atomic_enable, + .atomic_disable = mtk_dp_bridge_atomic_disable, + .mode_valid = mtk_dp_bridge_mode_valid, +- .get_edid = mtk_dp_get_edid, ++ .edid_read = mtk_dp_edid_read, + .detect = mtk_dp_bdg_detect, + }; + +diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c +index 771f4e1733539..66ccde966e3c1 100644 +--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c ++++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c +@@ -553,7 +553,7 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp, + int ret; + #endif + +- if (comp_id < 0 || comp_id >= DDP_COMPONENT_DRM_ID_MAX) ++ if (comp_id >= DDP_COMPONENT_DRM_ID_MAX) + return -EINVAL; + + type = mtk_ddp_matches[comp_id].type; +diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c +index 37d8113ba92f0..ffe016d6cbcfe 100644 +--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c ++++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c +@@ -719,6 +719,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = { + .data = (void *)MTK_DISP_OVL }, + { .compatible = "mediatek,mt8192-disp-ovl", + .data = (void *)MTK_DISP_OVL }, ++ { .compatible = "mediatek,mt8195-disp-ovl", ++ .data = (void *)MTK_DISP_OVL }, + { .compatible = "mediatek,mt8183-disp-ovl-2l", + .data = (void *)MTK_DISP_OVL_2L }, + { .compatible = "mediatek,mt8192-disp-ovl-2l", +diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c b/drivers/gpu/drm/mediatek/mtk_drm_plane.c +index ddc9355b06d51..f10d4cc6c2234 100644 +--- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c ++++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c +@@ -227,6 +227,8 @@ static void mtk_plane_atomic_async_update(struct drm_plane *plane, + plane->state->src_y = new_state->src_y; + plane->state->src_h = new_state->src_h; + plane->state->src_w = new_state->src_w; ++ plane->state->dst.x1 = new_state->dst.x1; ++ plane->state->dst.y1 = new_state->dst.y1; + + mtk_plane_update_new_state(new_state, new_plane_state); + swap(plane->state->fb, new_state->fb); +diff --git a/drivers/gpu/drm/mediatek/mtk_ethdr.c b/drivers/gpu/drm/mediatek/mtk_ethdr.c +index db7ac666ec5e1..0cf8c88994156 100644 +--- a/drivers/gpu/drm/mediatek/mtk_ethdr.c ++++ b/drivers/gpu/drm/mediatek/mtk_ethdr.c +@@ -50,7 +50,6 @@ + + #define MIXER_INX_MODE_BYPASS 0 + #define MIXER_INX_MODE_EVEN_EXTEND 1 +-#define DEFAULT_9BIT_ALPHA 0x100 + #define MIXER_ALPHA_AEN BIT(8) + #define MIXER_ALPHA 0xff + #define ETHDR_CLK_NUM 13 +@@ -154,13 +153,19 @@ void mtk_ethdr_layer_config(struct device *dev, unsigned int idx, + unsigned int offset = (pending->x & 1) << 31 | pending->y << 16 | pending->x; + unsigned int align_width = ALIGN_DOWN(pending->width, 2); + unsigned int alpha_con = 0; ++ bool replace_src_a = false; + + dev_dbg(dev, "%s+ idx:%d", __func__, idx); + + if (idx >= 4) + return; + +- if (!pending->enable) { ++ if (!pending->enable || !pending->width || !pending->height) { ++ /* ++ * instead of disabling layer with MIX_SRC_CON directly ++ * set the size to 0 to avoid screen shift due to mixer ++ * mode switch (hardware behavior) ++ */ + mtk_ddp_write(cmdq_pkt, 0, &mixer->cmdq_base, mixer->regs, MIX_L_SRC_SIZE(idx)); + return; + } +@@ -168,8 +173,16 @@ void mtk_ethdr_layer_config(struct device *dev, unsigned int idx, + if (state->base.fb && state->base.fb->format->has_alpha) + alpha_con = MIXER_ALPHA_AEN | MIXER_ALPHA; + +- mtk_mmsys_mixer_in_config(priv->mmsys_dev, idx + 1, alpha_con ? false : true, +- DEFAULT_9BIT_ALPHA, ++ if (state->base.fb && !state->base.fb->format->has_alpha) { ++ /* ++ * Mixer doesn't support CONST_BLD mode, ++ * use a trick to make the output equivalent ++ */ ++ replace_src_a = true; ++ } ++ ++ mtk_mmsys_mixer_in_config(priv->mmsys_dev, idx + 1, replace_src_a, ++ MIXER_ALPHA, + pending->x & 1 ? MIXER_INX_MODE_EVEN_EXTEND : + MIXER_INX_MODE_BYPASS, align_width / 2 - 1, cmdq_pkt); + +diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c +index cb674966e9aca..095f634ff7c79 100644 +--- a/drivers/gpu/drm/meson/meson_drv.c ++++ b/drivers/gpu/drm/meson/meson_drv.c +@@ -250,29 +250,20 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) + if (ret) + goto free_drm; + ret = meson_canvas_alloc(priv->canvas, &priv->canvas_id_vd1_0); +- if (ret) { +- meson_canvas_free(priv->canvas, priv->canvas_id_osd1); +- goto free_drm; +- } ++ if (ret) ++ goto free_canvas_osd1; + ret = meson_canvas_alloc(priv->canvas, &priv->canvas_id_vd1_1); +- if (ret) { +- meson_canvas_free(priv->canvas, priv->canvas_id_osd1); +- meson_canvas_free(priv->canvas, priv->canvas_id_vd1_0); +- goto free_drm; +- } ++ if (ret) ++ goto free_canvas_vd1_0; + ret = meson_canvas_alloc(priv->canvas, &priv->canvas_id_vd1_2); +- if (ret) { +- meson_canvas_free(priv->canvas, priv->canvas_id_osd1); +- meson_canvas_free(priv->canvas, priv->canvas_id_vd1_0); +- meson_canvas_free(priv->canvas, priv->canvas_id_vd1_1); +- goto free_drm; +- } ++ if (ret) ++ goto free_canvas_vd1_1; + + priv->vsync_irq = platform_get_irq(pdev, 0); + + ret = drm_vblank_init(drm, 1); + if (ret) +- goto free_drm; ++ goto free_canvas_vd1_2; + + /* Assign limits per soc revision/package */ + for (i = 0 ; i < ARRAY_SIZE(meson_drm_soc_attrs) ; ++i) { +@@ -288,11 +279,11 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) + */ + ret = drm_aperture_remove_framebuffers(&meson_driver); + if (ret) +- goto free_drm; ++ goto free_canvas_vd1_2; + + ret = drmm_mode_config_init(drm); + if (ret) +- goto free_drm; ++ goto free_canvas_vd1_2; + drm->mode_config.max_width = 3840; + drm->mode_config.max_height = 2160; + drm->mode_config.funcs = &meson_mode_config_funcs; +@@ -307,7 +298,7 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) + if (priv->afbcd.ops) { + ret = priv->afbcd.ops->init(priv); + if (ret) +- goto free_drm; ++ goto free_canvas_vd1_2; + } + + /* Encoder Initialization */ +@@ -371,6 +362,14 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) + exit_afbcd: + if (priv->afbcd.ops) + priv->afbcd.ops->exit(priv); ++free_canvas_vd1_2: ++ meson_canvas_free(priv->canvas, priv->canvas_id_vd1_2); ++free_canvas_vd1_1: ++ meson_canvas_free(priv->canvas, priv->canvas_id_vd1_1); ++free_canvas_vd1_0: ++ meson_canvas_free(priv->canvas, priv->canvas_id_vd1_0); ++free_canvas_osd1: ++ meson_canvas_free(priv->canvas, priv->canvas_id_osd1); + free_drm: + drm_dev_put(drm); + +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +index 5fb7e2e10801d..e454b80907121 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +@@ -1672,8 +1672,7 @@ void dpu_encoder_trigger_kickoff_pending(struct drm_encoder *drm_enc) + phys = dpu_enc->phys_encs[i]; + + ctl = phys->hw_ctl; +- if (ctl->ops.clear_pending_flush) +- ctl->ops.clear_pending_flush(ctl); ++ ctl->ops.clear_pending_flush(ctl); + + /* update only for command mode primary ctl */ + if ((phys == dpu_enc->cur_master) && +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c +index 870a1f5060e30..a81a9ee71a86c 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c +@@ -528,8 +528,7 @@ static void dpu_encoder_phys_wb_disable(struct dpu_encoder_phys *phys_enc) + } + + /* reset h/w before final flush */ +- if (phys_enc->hw_ctl->ops.clear_pending_flush) +- phys_enc->hw_ctl->ops.clear_pending_flush(phys_enc->hw_ctl); ++ phys_enc->hw_ctl->ops.clear_pending_flush(phys_enc->hw_ctl); + + /* + * New CTL reset sequence from 5.0 MDP onwards. +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h +index 1c242298ff2ee..dca87ea78e251 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h +@@ -81,7 +81,8 @@ struct dpu_hw_ctl_ops { + + /** + * Clear the value of the cached pending_flush_mask +- * No effect on hardware ++ * No effect on hardware. ++ * Required to be implemented. + * @ctx : ctl path ctx pointer + */ + void (*clear_pending_flush)(struct dpu_hw_ctl *ctx); +diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c +index ab393bdaba6cd..77b805eacb1b1 100644 +--- a/drivers/gpu/drm/msm/dsi/dsi_host.c ++++ b/drivers/gpu/drm/msm/dsi/dsi_host.c +@@ -832,6 +832,7 @@ static void dsi_update_dsc_timing(struct msm_dsi_host *msm_host, bool is_cmd_mod + u32 slice_per_intf, total_bytes_per_intf; + u32 pkt_per_line; + u32 eol_byte_num; ++ u32 bytes_per_pkt; + + /* first calculate dsc parameters and then program + * compress mode registers +@@ -839,6 +840,7 @@ static void dsi_update_dsc_timing(struct msm_dsi_host *msm_host, bool is_cmd_mod + slice_per_intf = msm_dsc_get_slices_per_intf(dsc, hdisplay); + + total_bytes_per_intf = dsc->slice_chunk_size * slice_per_intf; ++ bytes_per_pkt = dsc->slice_chunk_size; /* * slice_per_pkt; */ + + eol_byte_num = total_bytes_per_intf % 3; + +@@ -876,6 +878,7 @@ static void dsi_update_dsc_timing(struct msm_dsi_host *msm_host, bool is_cmd_mod + dsi_write(msm_host, REG_DSI_COMMAND_COMPRESSION_MODE_CTRL, reg_ctrl); + dsi_write(msm_host, REG_DSI_COMMAND_COMPRESSION_MODE_CTRL2, reg_ctrl2); + } else { ++ reg |= DSI_VIDEO_COMPRESSION_MODE_CTRL_WC(bytes_per_pkt); + dsi_write(msm_host, REG_DSI_VIDEO_COMPRESSION_MODE_CTRL, reg); + } + } +diff --git a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c +index 7990c519a56b1..cfa5b54ed6fe7 100644 +--- a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c ++++ b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c +@@ -1847,7 +1847,11 @@ static int boe_panel_prepare(struct drm_panel *panel) + usleep_range(10000, 11000); + + if (boe->desc->lp11_before_reset) { +- mipi_dsi_dcs_nop(boe->dsi); ++ ret = mipi_dsi_dcs_nop(boe->dsi); ++ if (ret < 0) { ++ dev_err(&boe->dsi->dev, "Failed to send NOP: %d\n", ret); ++ goto poweroff; ++ } + usleep_range(1000, 2000); + } + gpiod_set_value(boe->enable_gpio, 1); +@@ -1868,13 +1872,13 @@ static int boe_panel_prepare(struct drm_panel *panel) + return 0; + + poweroff: ++ gpiod_set_value(boe->enable_gpio, 0); + regulator_disable(boe->avee); + poweroffavdd: + regulator_disable(boe->avdd); + poweroff1v8: + usleep_range(5000, 7000); + regulator_disable(boe->pp1800); +- gpiod_set_value(boe->enable_gpio, 0); + + return ret; + } +diff --git a/drivers/gpu/drm/panel/panel-himax-hx8394.c b/drivers/gpu/drm/panel/panel-himax-hx8394.c +index c73243d85de71..631420d28be4c 100644 +--- a/drivers/gpu/drm/panel/panel-himax-hx8394.c ++++ b/drivers/gpu/drm/panel/panel-himax-hx8394.c +@@ -234,8 +234,7 @@ static int hx8394_enable(struct drm_panel *panel) + + sleep_in: + /* This will probably fail, but let's try orderly power off anyway. */ +- ret = mipi_dsi_dcs_enter_sleep_mode(dsi); +- if (!ret) ++ if (!mipi_dsi_dcs_enter_sleep_mode(dsi)) + msleep(50); + + return ret; +diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c +index a2ab99698ca80..ddcc8259061bb 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_drv.c ++++ b/drivers/gpu/drm/panfrost/panfrost_drv.c +@@ -731,3 +731,4 @@ module_platform_driver(panfrost_driver); + MODULE_AUTHOR("Panfrost Project Developers"); + MODULE_DESCRIPTION("Panfrost DRM Driver"); + MODULE_LICENSE("GPL v2"); ++MODULE_SOFTDEP("pre: governor_simpleondemand"); +diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c +index 404b0483bb7cb..8ee614be9adf3 100644 +--- a/drivers/gpu/drm/qxl/qxl_display.c ++++ b/drivers/gpu/drm/qxl/qxl_display.c +@@ -236,6 +236,9 @@ static int qxl_add_mode(struct drm_connector *connector, + return 0; + + mode = drm_cvt_mode(dev, width, height, 60, false, false, false); ++ if (!mode) ++ return 0; ++ + if (preferred) + mode->type |= DRM_MODE_TYPE_PREFERRED; + mode->hdisplay = width; +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +index c5ec4169616de..f2a956f973613 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +@@ -1927,7 +1927,7 @@ static void vop2_setup_layer_mixer(struct vop2_video_port *vp) + port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT2_MUX, + (vp2->nlayers + vp1->nlayers + vp0->nlayers - 1)); + else +- port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT1_MUX, 8); ++ port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT2_MUX, 8); + + layer_sel = vop2_readl(vop2, RK3568_OVL_LAYER_SEL); + +diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c +index 40876bcdd79a4..5a1539914ce89 100644 +--- a/drivers/gpu/drm/udl/udl_modeset.c ++++ b/drivers/gpu/drm/udl/udl_modeset.c +@@ -512,8 +512,7 @@ struct drm_connector *udl_connector_init(struct drm_device *dev) + + drm_connector_helper_add(connector, &udl_connector_helper_funcs); + +- connector->polled = DRM_CONNECTOR_POLL_HPD | +- DRM_CONNECTOR_POLL_CONNECT | ++ connector->polled = DRM_CONNECTOR_POLL_CONNECT | + DRM_CONNECTOR_POLL_DISCONNECT; + + return connector; +diff --git a/drivers/gpu/drm/xlnx/zynqmp_dpsub.c b/drivers/gpu/drm/xlnx/zynqmp_dpsub.c +index face8d6b2a6fb..f5781939de9c3 100644 +--- a/drivers/gpu/drm/xlnx/zynqmp_dpsub.c ++++ b/drivers/gpu/drm/xlnx/zynqmp_dpsub.c +@@ -269,6 +269,7 @@ static int zynqmp_dpsub_probe(struct platform_device *pdev) + return 0; + + err_disp: ++ drm_bridge_remove(dpsub->bridge); + zynqmp_disp_remove(dpsub); + err_dp: + zynqmp_dp_remove(dpsub); +diff --git a/drivers/gpu/drm/xlnx/zynqmp_kms.c b/drivers/gpu/drm/xlnx/zynqmp_kms.c +index a7f8611be6f42..44d4a510ad7d6 100644 +--- a/drivers/gpu/drm/xlnx/zynqmp_kms.c ++++ b/drivers/gpu/drm/xlnx/zynqmp_kms.c +@@ -434,23 +434,28 @@ static int zynqmp_dpsub_kms_init(struct zynqmp_dpsub *dpsub) + DRM_BRIDGE_ATTACH_NO_CONNECTOR); + if (ret) { + dev_err(dpsub->dev, "failed to attach bridge to encoder\n"); +- return ret; ++ goto err_encoder; + } + + /* Create the connector for the chain of bridges. */ + connector = drm_bridge_connector_init(&dpsub->drm->dev, encoder); + if (IS_ERR(connector)) { + dev_err(dpsub->dev, "failed to created connector\n"); +- return PTR_ERR(connector); ++ ret = PTR_ERR(connector); ++ goto err_encoder; + } + + ret = drm_connector_attach_encoder(connector, encoder); + if (ret < 0) { + dev_err(dpsub->dev, "failed to attach connector to encoder\n"); +- return ret; ++ goto err_encoder; + } + + return 0; ++ ++err_encoder: ++ drm_encoder_cleanup(encoder); ++ return ret; + } + + static void zynqmp_dpsub_drm_release(struct drm_device *drm, void *res) +@@ -530,5 +535,6 @@ void zynqmp_dpsub_drm_cleanup(struct zynqmp_dpsub *dpsub) + + drm_dev_unregister(drm); + drm_atomic_helper_shutdown(drm); ++ drm_encoder_cleanup(&dpsub->drm->encoder); + drm_kms_helper_poll_fini(drm); + } +diff --git a/drivers/hwmon/adt7475.c b/drivers/hwmon/adt7475.c +index 03acadc3a6cb4..14b2547adae8d 100644 +--- a/drivers/hwmon/adt7475.c ++++ b/drivers/hwmon/adt7475.c +@@ -1862,7 +1862,7 @@ static void adt7475_read_pwm(struct i2c_client *client, int index) + data->pwm[CONTROL][index] &= ~0xE0; + data->pwm[CONTROL][index] |= (7 << 5); + +- i2c_smbus_write_byte_data(client, PWM_CONFIG_REG(index), ++ i2c_smbus_write_byte_data(client, PWM_REG(index), + data->pwm[INPUT][index]); + + i2c_smbus_write_byte_data(client, PWM_CONFIG_REG(index), +diff --git a/drivers/hwmon/max6697.c b/drivers/hwmon/max6697.c +index 7d10dd434f2e1..a338dd4e990d5 100644 +--- a/drivers/hwmon/max6697.c ++++ b/drivers/hwmon/max6697.c +@@ -311,6 +311,7 @@ static ssize_t temp_store(struct device *dev, + return ret; + + mutex_lock(&data->update_lock); ++ temp = clamp_val(temp, -1000000, 1000000); /* prevent underflow */ + temp = DIV_ROUND_CLOSEST(temp, 1000) + data->temp_offset; + temp = clamp_val(temp, 0, data->type == max6581 ? 255 : 127); + data->temp[nr][index] = temp; +@@ -428,14 +429,14 @@ static SENSOR_DEVICE_ATTR_RO(temp6_max_alarm, alarm, 20); + static SENSOR_DEVICE_ATTR_RO(temp7_max_alarm, alarm, 21); + static SENSOR_DEVICE_ATTR_RO(temp8_max_alarm, alarm, 23); + +-static SENSOR_DEVICE_ATTR_RO(temp1_crit_alarm, alarm, 14); ++static SENSOR_DEVICE_ATTR_RO(temp1_crit_alarm, alarm, 15); + static SENSOR_DEVICE_ATTR_RO(temp2_crit_alarm, alarm, 8); + static SENSOR_DEVICE_ATTR_RO(temp3_crit_alarm, alarm, 9); + static SENSOR_DEVICE_ATTR_RO(temp4_crit_alarm, alarm, 10); + static SENSOR_DEVICE_ATTR_RO(temp5_crit_alarm, alarm, 11); + static SENSOR_DEVICE_ATTR_RO(temp6_crit_alarm, alarm, 12); + static SENSOR_DEVICE_ATTR_RO(temp7_crit_alarm, alarm, 13); +-static SENSOR_DEVICE_ATTR_RO(temp8_crit_alarm, alarm, 15); ++static SENSOR_DEVICE_ATTR_RO(temp8_crit_alarm, alarm, 14); + + static SENSOR_DEVICE_ATTR_RO(temp2_fault, alarm, 1); + static SENSOR_DEVICE_ATTR_RO(temp3_fault, alarm, 2); +diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c +index 9d550f5697fa8..57a009552cc5c 100644 +--- a/drivers/hwtracing/coresight/coresight-platform.c ++++ b/drivers/hwtracing/coresight/coresight-platform.c +@@ -297,8 +297,10 @@ static int of_get_coresight_platform_data(struct device *dev, + continue; + + ret = of_coresight_parse_endpoint(dev, ep, pdata); +- if (ret) ++ if (ret) { ++ of_node_put(ep); + return ret; ++ } + } + + return 0; +diff --git a/drivers/iio/frequency/adrf6780.c b/drivers/iio/frequency/adrf6780.c +index b4defb82f37e3..3f46032c92752 100644 +--- a/drivers/iio/frequency/adrf6780.c ++++ b/drivers/iio/frequency/adrf6780.c +@@ -9,7 +9,6 @@ + #include <linux/bits.h> + #include <linux/clk.h> + #include <linux/clkdev.h> +-#include <linux/clk-provider.h> + #include <linux/delay.h> + #include <linux/device.h> + #include <linux/iio/iio.h> +diff --git a/drivers/iio/industrialio-gts-helper.c b/drivers/iio/industrialio-gts-helper.c +index b51eb6cb766f3..59d7615c0f565 100644 +--- a/drivers/iio/industrialio-gts-helper.c ++++ b/drivers/iio/industrialio-gts-helper.c +@@ -362,17 +362,20 @@ static int iio_gts_build_avail_time_table(struct iio_gts *gts) + for (i = gts->num_itime - 1; i >= 0; i--) { + int new = gts->itime_table[i].time_us; + +- if (times[idx] < new) { ++ if (idx == 0 || times[idx - 1] < new) { + times[idx++] = new; + continue; + } + +- for (j = 0; j <= idx; j++) { ++ for (j = 0; j < idx; j++) { ++ if (times[j] == new) ++ break; + if (times[j] > new) { + memmove(×[j + 1], ×[j], + (idx - j) * sizeof(int)); + times[j] = new; + idx++; ++ break; + } + } + } +diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c +index 7acc0f936dad3..b7251ed7a8dfb 100644 +--- a/drivers/infiniband/core/cache.c ++++ b/drivers/infiniband/core/cache.c +@@ -794,7 +794,6 @@ static struct ib_gid_table *alloc_gid_table(int sz) + static void release_gid_table(struct ib_device *device, + struct ib_gid_table *table) + { +- bool leak = false; + int i; + + if (!table) +@@ -803,15 +802,12 @@ static void release_gid_table(struct ib_device *device, + for (i = 0; i < table->sz; i++) { + if (is_gid_entry_free(table->data_vec[i])) + continue; +- if (kref_read(&table->data_vec[i]->kref) > 1) { +- dev_err(&device->dev, +- "GID entry ref leak for index %d ref=%u\n", i, +- kref_read(&table->data_vec[i]->kref)); +- leak = true; +- } ++ ++ WARN_ONCE(true, ++ "GID entry ref leak for dev %s index %d ref=%u\n", ++ dev_name(&device->dev), i, ++ kref_read(&table->data_vec[i]->kref)); + } +- if (leak) +- return; + + mutex_destroy(&table->lock); + kfree(table->data_vec); +diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c +index db0a58c82838d..56dd030045a20 100644 +--- a/drivers/infiniband/core/device.c ++++ b/drivers/infiniband/core/device.c +@@ -2146,6 +2146,9 @@ int ib_device_set_netdev(struct ib_device *ib_dev, struct net_device *ndev, + unsigned long flags; + int ret; + ++ if (!rdma_is_port_valid(ib_dev, port)) ++ return -EINVAL; ++ + /* + * Drivers wish to call this before ib_register_driver, so we have to + * setup the port data early. +@@ -2154,9 +2157,6 @@ int ib_device_set_netdev(struct ib_device *ib_dev, struct net_device *ndev, + if (ret) + return ret; + +- if (!rdma_is_port_valid(ib_dev, port)) +- return -EINVAL; +- + pdata = &ib_dev->port_data[port]; + spin_lock_irqsave(&pdata->netdev_lock, flags); + old_ndev = rcu_dereference_protected( +@@ -2166,17 +2166,12 @@ int ib_device_set_netdev(struct ib_device *ib_dev, struct net_device *ndev, + return 0; + } + +- if (old_ndev) +- netdev_tracker_free(ndev, &pdata->netdev_tracker); +- if (ndev) +- netdev_hold(ndev, &pdata->netdev_tracker, GFP_ATOMIC); + rcu_assign_pointer(pdata->netdev, ndev); ++ netdev_put(old_ndev, &pdata->netdev_tracker); ++ netdev_hold(ndev, &pdata->netdev_tracker, GFP_ATOMIC); + spin_unlock_irqrestore(&pdata->netdev_lock, flags); + + add_ndev_hash(pdata); +- if (old_ndev) +- __dev_put(old_ndev); +- + return 0; + } + EXPORT_SYMBOL(ib_device_set_netdev); +@@ -2235,8 +2230,7 @@ struct net_device *ib_device_get_netdev(struct ib_device *ib_dev, + spin_lock(&pdata->netdev_lock); + res = rcu_dereference_protected( + pdata->netdev, lockdep_is_held(&pdata->netdev_lock)); +- if (res) +- dev_hold(res); ++ dev_hold(res); + spin_unlock(&pdata->netdev_lock); + } + +@@ -2311,9 +2305,7 @@ void ib_enum_roce_netdev(struct ib_device *ib_dev, + + if (filter(ib_dev, port, idev, filter_cookie)) + cb(ib_dev, port, idev, cookie); +- +- if (idev) +- dev_put(idev); ++ dev_put(idev); + } + } + +diff --git a/drivers/infiniband/core/iwcm.c b/drivers/infiniband/core/iwcm.c +index 2b47073c61a65..2d09d1be38f19 100644 +--- a/drivers/infiniband/core/iwcm.c ++++ b/drivers/infiniband/core/iwcm.c +@@ -369,8 +369,10 @@ EXPORT_SYMBOL(iw_cm_disconnect); + * + * Clean up all resources associated with the connection and release + * the initial reference taken by iw_create_cm_id. ++ * ++ * Returns true if and only if the last cm_id_priv reference has been dropped. + */ +-static void destroy_cm_id(struct iw_cm_id *cm_id) ++static bool destroy_cm_id(struct iw_cm_id *cm_id) + { + struct iwcm_id_private *cm_id_priv; + struct ib_qp *qp; +@@ -440,7 +442,7 @@ static void destroy_cm_id(struct iw_cm_id *cm_id) + iwpm_remove_mapping(&cm_id->local_addr, RDMA_NL_IWCM); + } + +- (void)iwcm_deref_id(cm_id_priv); ++ return iwcm_deref_id(cm_id_priv); + } + + /* +@@ -451,7 +453,8 @@ static void destroy_cm_id(struct iw_cm_id *cm_id) + */ + void iw_destroy_cm_id(struct iw_cm_id *cm_id) + { +- destroy_cm_id(cm_id); ++ if (!destroy_cm_id(cm_id)) ++ flush_workqueue(iwcm_wq); + } + EXPORT_SYMBOL(iw_destroy_cm_id); + +@@ -1035,7 +1038,7 @@ static void cm_work_handler(struct work_struct *_work) + if (!test_bit(IWCM_F_DROP_EVENTS, &cm_id_priv->flags)) { + ret = process_event(cm_id_priv, &levent); + if (ret) +- destroy_cm_id(&cm_id_priv->id); ++ WARN_ON_ONCE(destroy_cm_id(&cm_id_priv->id)); + } else + pr_debug("dropping event %d\n", levent.event); + if (iwcm_deref_id(cm_id_priv)) +diff --git a/drivers/infiniband/core/lag.c b/drivers/infiniband/core/lag.c +index c77d7d2559a11..66c7e1e6600dc 100644 +--- a/drivers/infiniband/core/lag.c ++++ b/drivers/infiniband/core/lag.c +@@ -93,8 +93,7 @@ static struct net_device *rdma_get_xmit_slave_udp(struct ib_device *device, + slave = netdev_get_xmit_slave(master, skb, + !!(device->lag_flags & + RDMA_LAG_FLAGS_HASH_ALL_SLAVES)); +- if (slave) +- dev_hold(slave); ++ dev_hold(slave); + rcu_read_unlock(); + kfree_skb(skb); + return slave; +diff --git a/drivers/infiniband/core/roce_gid_mgmt.c b/drivers/infiniband/core/roce_gid_mgmt.c +index e958c43dd28fd..d5131b3ba8ab0 100644 +--- a/drivers/infiniband/core/roce_gid_mgmt.c ++++ b/drivers/infiniband/core/roce_gid_mgmt.c +@@ -601,8 +601,7 @@ static void del_netdev_default_ips_join(struct ib_device *ib_dev, u32 port, + + rcu_read_lock(); + master_ndev = netdev_master_upper_dev_get_rcu(rdma_ndev); +- if (master_ndev) +- dev_hold(master_ndev); ++ dev_hold(master_ndev); + rcu_read_unlock(); + + if (master_ndev) { +diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c +index fd69be982ce06..b4d3e7dfc939f 100644 +--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c ++++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c +@@ -2467,7 +2467,7 @@ static int bnxt_re_build_send_wqe(struct bnxt_re_qp *qp, + break; + case IB_WR_SEND_WITH_IMM: + wqe->type = BNXT_QPLIB_SWQE_TYPE_SEND_WITH_IMM; +- wqe->send.imm_data = wr->ex.imm_data; ++ wqe->send.imm_data = be32_to_cpu(wr->ex.imm_data); + break; + case IB_WR_SEND_WITH_INV: + wqe->type = BNXT_QPLIB_SWQE_TYPE_SEND_WITH_INV; +@@ -2497,7 +2497,7 @@ static int bnxt_re_build_rdma_wqe(const struct ib_send_wr *wr, + break; + case IB_WR_RDMA_WRITE_WITH_IMM: + wqe->type = BNXT_QPLIB_SWQE_TYPE_RDMA_WRITE_WITH_IMM; +- wqe->rdma.imm_data = wr->ex.imm_data; ++ wqe->rdma.imm_data = be32_to_cpu(wr->ex.imm_data); + break; + case IB_WR_RDMA_READ: + wqe->type = BNXT_QPLIB_SWQE_TYPE_RDMA_READ; +@@ -3545,7 +3545,7 @@ static void bnxt_re_process_res_shadow_qp_wc(struct bnxt_re_qp *gsi_sqp, + wc->byte_len = orig_cqe->length; + wc->qp = &gsi_qp->ib_qp; + +- wc->ex.imm_data = orig_cqe->immdata; ++ wc->ex.imm_data = cpu_to_be32(le32_to_cpu(orig_cqe->immdata)); + wc->src_qp = orig_cqe->src_qp; + memcpy(wc->smac, orig_cqe->smac, ETH_ALEN); + if (bnxt_re_is_vlan_pkt(orig_cqe, &vlan_id, &sl)) { +@@ -3690,7 +3690,7 @@ int bnxt_re_poll_cq(struct ib_cq *ib_cq, int num_entries, struct ib_wc *wc) + (unsigned long)(cqe->qp_handle), + struct bnxt_re_qp, qplib_qp); + wc->qp = &qp->ib_qp; +- wc->ex.imm_data = cqe->immdata; ++ wc->ex.imm_data = cpu_to_be32(le32_to_cpu(cqe->immdata)); + wc->src_qp = cqe->src_qp; + memcpy(wc->smac, cqe->smac, ETH_ALEN); + wc->port_num = 1; +diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.h b/drivers/infiniband/hw/bnxt_re/qplib_fp.h +index 113be429f0aac..a6f38d8f12efe 100644 +--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.h ++++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.h +@@ -164,7 +164,7 @@ struct bnxt_qplib_swqe { + /* Send, with imm, inval key */ + struct { + union { +- __be32 imm_data; ++ u32 imm_data; + u32 inv_key; + }; + u32 q_key; +@@ -182,7 +182,7 @@ struct bnxt_qplib_swqe { + /* RDMA write, with imm, read */ + struct { + union { +- __be32 imm_data; ++ u32 imm_data; + u32 inv_key; + }; + u64 remote_va; +@@ -389,7 +389,7 @@ struct bnxt_qplib_cqe { + u16 cfa_meta; + u64 wr_id; + union { +- __be32 immdata; ++ __le32 immdata; + u32 invrkey; + }; + u64 qp_handle; +diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h +index 82066859cc113..cd593d651e4ca 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_device.h ++++ b/drivers/infiniband/hw/hns/hns_roce_device.h +@@ -82,6 +82,7 @@ + #define MR_TYPE_DMA 0x03 + + #define HNS_ROCE_FRMR_MAX_PA 512 ++#define HNS_ROCE_FRMR_ALIGN_SIZE 128 + + #define PKEY_ID 0xffff + #define NODE_DESC_SIZE 64 +@@ -90,6 +91,8 @@ + /* Configure to HW for PAGE_SIZE larger than 4KB */ + #define PG_SHIFT_OFFSET (PAGE_SHIFT - 12) + ++#define ATOMIC_WR_LEN 8 ++ + #define HNS_ROCE_IDX_QUE_ENTRY_SZ 4 + #define SRQ_DB_REG 0x230 + +@@ -181,6 +184,9 @@ enum { + #define HNS_HW_PAGE_SHIFT 12 + #define HNS_HW_PAGE_SIZE (1 << HNS_HW_PAGE_SHIFT) + ++#define HNS_HW_MAX_PAGE_SHIFT 27 ++#define HNS_HW_MAX_PAGE_SIZE (1 << HNS_HW_MAX_PAGE_SHIFT) ++ + struct hns_roce_uar { + u64 pfn; + unsigned long index; +diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +index 32fb2c00a8f26..a49280e2df8ca 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c ++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +@@ -595,11 +595,16 @@ static inline int set_rc_wqe(struct hns_roce_qp *qp, + (wr->send_flags & IB_SEND_SIGNALED) ? 1 : 0); + + if (wr->opcode == IB_WR_ATOMIC_CMP_AND_SWP || +- wr->opcode == IB_WR_ATOMIC_FETCH_AND_ADD) ++ wr->opcode == IB_WR_ATOMIC_FETCH_AND_ADD) { ++ if (msg_len != ATOMIC_WR_LEN) ++ return -EINVAL; + set_atomic_seg(wr, rc_sq_wqe, valid_num_sge); +- else if (wr->opcode != IB_WR_REG_MR) ++ } else if (wr->opcode != IB_WR_REG_MR) { + ret = set_rwqe_data_seg(&qp->ibqp, wr, rc_sq_wqe, + &curr_idx, valid_num_sge); ++ if (ret) ++ return ret; ++ } + + /* + * The pipeline can sequentially post all valid WQEs into WQ buffer, +@@ -2443,14 +2448,16 @@ static int set_llm_cfg_to_hw(struct hns_roce_dev *hr_dev, + static struct hns_roce_link_table * + alloc_link_table_buf(struct hns_roce_dev *hr_dev) + { ++ u16 total_sl = hr_dev->caps.sl_num * hr_dev->func_num; + struct hns_roce_v2_priv *priv = hr_dev->priv; + struct hns_roce_link_table *link_tbl; + u32 pg_shift, size, min_size; + + link_tbl = &priv->ext_llm; + pg_shift = hr_dev->caps.llm_buf_pg_sz + PAGE_SHIFT; +- size = hr_dev->caps.num_qps * HNS_ROCE_V2_EXT_LLM_ENTRY_SZ; +- min_size = HNS_ROCE_EXT_LLM_MIN_PAGES(hr_dev->caps.sl_num) << pg_shift; ++ size = hr_dev->caps.num_qps * hr_dev->func_num * ++ HNS_ROCE_V2_EXT_LLM_ENTRY_SZ; ++ min_size = HNS_ROCE_EXT_LLM_MIN_PAGES(total_sl) << pg_shift; + + /* Alloc data table */ + size = max(size, min_size); +@@ -6256,9 +6263,16 @@ static void hns_roce_v2_int_mask_enable(struct hns_roce_dev *hr_dev, + roce_write(hr_dev, ROCEE_VF_ABN_INT_CFG_REG, enable_flag); + } + +-static void hns_roce_v2_destroy_eqc(struct hns_roce_dev *hr_dev, u32 eqn) ++static void free_eq_buf(struct hns_roce_dev *hr_dev, struct hns_roce_eq *eq) ++{ ++ hns_roce_mtr_destroy(hr_dev, &eq->mtr); ++} ++ ++static void hns_roce_v2_destroy_eqc(struct hns_roce_dev *hr_dev, ++ struct hns_roce_eq *eq) + { + struct device *dev = hr_dev->dev; ++ int eqn = eq->eqn; + int ret; + u8 cmd; + +@@ -6269,12 +6283,9 @@ static void hns_roce_v2_destroy_eqc(struct hns_roce_dev *hr_dev, u32 eqn) + + ret = hns_roce_destroy_hw_ctx(hr_dev, cmd, eqn & HNS_ROCE_V2_EQN_M); + if (ret) +- dev_err(dev, "[mailbox cmd] destroy eqc(%u) failed.\n", eqn); +-} ++ dev_err(dev, "[mailbox cmd] destroy eqc(%d) failed.\n", eqn); + +-static void free_eq_buf(struct hns_roce_dev *hr_dev, struct hns_roce_eq *eq) +-{ +- hns_roce_mtr_destroy(hr_dev, &eq->mtr); ++ free_eq_buf(hr_dev, eq); + } + + static void init_eq_config(struct hns_roce_dev *hr_dev, struct hns_roce_eq *eq) +@@ -6580,7 +6591,7 @@ static int hns_roce_v2_init_eq_table(struct hns_roce_dev *hr_dev) + + err_create_eq_fail: + for (i -= 1; i >= 0; i--) +- free_eq_buf(hr_dev, &eq_table->eq[i]); ++ hns_roce_v2_destroy_eqc(hr_dev, &eq_table->eq[i]); + kfree(eq_table->eq); + + return ret; +@@ -6600,11 +6611,8 @@ static void hns_roce_v2_cleanup_eq_table(struct hns_roce_dev *hr_dev) + __hns_roce_free_irq(hr_dev); + destroy_workqueue(hr_dev->irq_workq); + +- for (i = 0; i < eq_num; i++) { +- hns_roce_v2_destroy_eqc(hr_dev, i); +- +- free_eq_buf(hr_dev, &eq_table->eq[i]); +- } ++ for (i = 0; i < eq_num; i++) ++ hns_roce_v2_destroy_eqc(hr_dev, &eq_table->eq[i]); + + kfree(eq_table->eq); + } +diff --git a/drivers/infiniband/hw/hns/hns_roce_mr.c b/drivers/infiniband/hw/hns/hns_roce_mr.c +index 190e62da98e4b..980261969b0c0 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_mr.c ++++ b/drivers/infiniband/hw/hns/hns_roce_mr.c +@@ -423,6 +423,11 @@ int hns_roce_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, int sg_nents, + struct hns_roce_mtr *mtr = &mr->pbl_mtr; + int ret, sg_num = 0; + ++ if (!IS_ALIGNED(*sg_offset, HNS_ROCE_FRMR_ALIGN_SIZE) || ++ ibmr->page_size < HNS_HW_PAGE_SIZE || ++ ibmr->page_size > HNS_HW_MAX_PAGE_SIZE) ++ return sg_num; ++ + mr->npages = 0; + mr->page_list = kvcalloc(mr->pbl_mtr.hem_cfg.buf_pg_count, + sizeof(dma_addr_t), GFP_KERNEL); +diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c +index 828b58534aa97..bff00b3af41fb 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_qp.c ++++ b/drivers/infiniband/hw/hns/hns_roce_qp.c +@@ -531,13 +531,15 @@ static unsigned int get_sge_num_from_max_inl_data(bool is_ud_or_gsi, + { + unsigned int inline_sge; + +- inline_sge = roundup_pow_of_two(max_inline_data) / HNS_ROCE_SGE_SIZE; ++ if (!max_inline_data) ++ return 0; + + /* + * if max_inline_data less than + * HNS_ROCE_SGE_IN_WQE * HNS_ROCE_SGE_SIZE, + * In addition to ud's mode, no need to extend sge. + */ ++ inline_sge = roundup_pow_of_two(max_inline_data) / HNS_ROCE_SGE_SIZE; + if (!is_ud_or_gsi && inline_sge <= HNS_ROCE_SGE_IN_WQE) + inline_sge = 0; + +diff --git a/drivers/infiniband/hw/hns/hns_roce_srq.c b/drivers/infiniband/hw/hns/hns_roce_srq.c +index 6a4923c21cbc6..727f926500712 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_srq.c ++++ b/drivers/infiniband/hw/hns/hns_roce_srq.c +@@ -296,7 +296,7 @@ static int set_srq_basic_param(struct hns_roce_srq *srq, + + max_sge = proc_srq_sge(hr_dev, srq, !!udata); + if (attr->max_wr > hr_dev->caps.max_srq_wrs || +- attr->max_sge > max_sge) { ++ attr->max_sge > max_sge || !attr->max_sge) { + ibdev_err(&hr_dev->ib_dev, + "invalid SRQ attr, depth = %u, sge = %u.\n", + attr->max_wr, attr->max_sge); +diff --git a/drivers/infiniband/hw/mlx4/alias_GUID.c b/drivers/infiniband/hw/mlx4/alias_GUID.c +index 111fa88a3be44..9a439569ffcf3 100644 +--- a/drivers/infiniband/hw/mlx4/alias_GUID.c ++++ b/drivers/infiniband/hw/mlx4/alias_GUID.c +@@ -829,7 +829,7 @@ void mlx4_ib_destroy_alias_guid_service(struct mlx4_ib_dev *dev) + + int mlx4_ib_init_alias_guid_service(struct mlx4_ib_dev *dev) + { +- char alias_wq_name[15]; ++ char alias_wq_name[22]; + int ret = 0; + int i, j; + union ib_gid gid; +diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c +index a37cfac5e23f9..dc9cf45d2d320 100644 +--- a/drivers/infiniband/hw/mlx4/mad.c ++++ b/drivers/infiniband/hw/mlx4/mad.c +@@ -2158,7 +2158,7 @@ static int mlx4_ib_alloc_demux_ctx(struct mlx4_ib_dev *dev, + struct mlx4_ib_demux_ctx *ctx, + int port) + { +- char name[12]; ++ char name[21]; + int ret = 0; + int i; + +diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h +index 6a57af8fa231b..43a963e205eb4 100644 +--- a/drivers/infiniband/hw/mlx5/mlx5_ib.h ++++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h +@@ -115,6 +115,19 @@ unsigned long __mlx5_umem_find_best_quantized_pgoff( + __mlx5_bit_sz(typ, page_offset_fld), 0, scale, \ + page_offset_quantized) + ++static inline unsigned long ++mlx5_umem_dmabuf_find_best_pgsz(struct ib_umem_dmabuf *umem_dmabuf) ++{ ++ /* ++ * mkeys used for dmabuf are fixed at PAGE_SIZE because we must be able ++ * to hold any sgl after a move operation. Ideally the mkc page size ++ * could be changed at runtime to be optimal, but right now the driver ++ * cannot do that. ++ */ ++ return ib_umem_find_best_pgsz(&umem_dmabuf->umem, PAGE_SIZE, ++ umem_dmabuf->umem.iova); ++} ++ + enum { + MLX5_IB_MMAP_OFFSET_START = 9, + MLX5_IB_MMAP_OFFSET_END = 255, +diff --git a/drivers/infiniband/hw/mlx5/odp.c b/drivers/infiniband/hw/mlx5/odp.c +index 4a04cbc5b78a4..a524181f34df9 100644 +--- a/drivers/infiniband/hw/mlx5/odp.c ++++ b/drivers/infiniband/hw/mlx5/odp.c +@@ -705,10 +705,8 @@ static int pagefault_dmabuf_mr(struct mlx5_ib_mr *mr, size_t bcnt, + return err; + } + +- page_size = mlx5_umem_find_best_pgsz(&umem_dmabuf->umem, mkc, +- log_page_size, 0, +- umem_dmabuf->umem.iova); +- if (unlikely(page_size < PAGE_SIZE)) { ++ page_size = mlx5_umem_dmabuf_find_best_pgsz(umem_dmabuf); ++ if (!page_size) { + ib_umem_dmabuf_unmap_pages(umem_dmabuf); + err = -EINVAL; + } else { +diff --git a/drivers/infiniband/sw/rxe/rxe_req.c b/drivers/infiniband/sw/rxe/rxe_req.c +index d8c41fd626a94..7a36080d2baef 100644 +--- a/drivers/infiniband/sw/rxe/rxe_req.c ++++ b/drivers/infiniband/sw/rxe/rxe_req.c +@@ -424,7 +424,7 @@ static struct sk_buff *init_req_packet(struct rxe_qp *qp, + int paylen; + int solicited; + u32 qp_num; +- int ack_req; ++ int ack_req = 0; + + /* length from start of bth to end of icrc */ + paylen = rxe_opcode[opcode].length + payload + pad + RXE_ICRC_SIZE; +@@ -445,8 +445,9 @@ static struct sk_buff *init_req_packet(struct rxe_qp *qp, + qp_num = (pkt->mask & RXE_DETH_MASK) ? ibwr->wr.ud.remote_qpn : + qp->attr.dest_qp_num; + +- ack_req = ((pkt->mask & RXE_END_MASK) || +- (qp->req.noack_pkts++ > RXE_MAX_PKT_PER_ACK)); ++ if (qp_type(qp) != IB_QPT_UD && qp_type(qp) != IB_QPT_UC) ++ ack_req = ((pkt->mask & RXE_END_MASK) || ++ (qp->req.noack_pkts++ > RXE_MAX_PKT_PER_ACK)); + if (ack_req) + qp->req.noack_pkts = 0; + +diff --git a/drivers/input/keyboard/qt1050.c b/drivers/input/keyboard/qt1050.c +index 6953097db4456..cd2f4216daf86 100644 +--- a/drivers/input/keyboard/qt1050.c ++++ b/drivers/input/keyboard/qt1050.c +@@ -226,7 +226,12 @@ static bool qt1050_identify(struct qt1050_priv *ts) + int err; + + /* Read Chip ID */ +- regmap_read(ts->regmap, QT1050_CHIP_ID, &val); ++ err = regmap_read(ts->regmap, QT1050_CHIP_ID, &val); ++ if (err) { ++ dev_err(&ts->client->dev, "Failed to read chip ID: %d\n", err); ++ return false; ++ } ++ + if (val != QT1050_CHIP_ID_VER) { + dev_err(&ts->client->dev, "ID %d not supported\n", val); + return false; +diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c +index 148a601396f92..dc80e407fb860 100644 +--- a/drivers/input/mouse/elan_i2c_core.c ++++ b/drivers/input/mouse/elan_i2c_core.c +@@ -1356,6 +1356,8 @@ static int elan_suspend(struct device *dev) + } + + err: ++ if (ret) ++ enable_irq(client->irq); + mutex_unlock(&data->sysfs_mutex); + return ret; + } +diff --git a/drivers/interconnect/qcom/qcm2290.c b/drivers/interconnect/qcom/qcm2290.c +index 52346f7319acc..69960a357a682 100644 +--- a/drivers/interconnect/qcom/qcm2290.c ++++ b/drivers/interconnect/qcom/qcm2290.c +@@ -163,7 +163,7 @@ static struct qcom_icc_node mas_snoc_bimc = { + .qos.ap_owned = true, + .qos.qos_port = 6, + .qos.qos_mode = NOC_QOS_MODE_BYPASS, +- .mas_rpm_id = 164, ++ .mas_rpm_id = 3, + .slv_rpm_id = -1, + .num_links = ARRAY_SIZE(mas_snoc_bimc_links), + .links = mas_snoc_bimc_links, +diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c +index 744e4e6b8d72d..9918af222c516 100644 +--- a/drivers/iommu/intel/iommu.c ++++ b/drivers/iommu/intel/iommu.c +@@ -2411,7 +2411,7 @@ static int __init si_domain_init(int hw) + for_each_mem_pfn_range(i, nid, &start_pfn, &end_pfn, NULL) { + ret = iommu_domain_identity_map(si_domain, + mm_to_dma_pfn_start(start_pfn), +- mm_to_dma_pfn_end(end_pfn)); ++ mm_to_dma_pfn_end(end_pfn-1)); + if (ret) + return ret; + } +diff --git a/drivers/iommu/sprd-iommu.c b/drivers/iommu/sprd-iommu.c +index 2fa9afebd4f5f..c8e79a2d8b4c6 100644 +--- a/drivers/iommu/sprd-iommu.c ++++ b/drivers/iommu/sprd-iommu.c +@@ -236,8 +236,8 @@ static void sprd_iommu_cleanup(struct sprd_iommu_domain *dom) + + pgt_size = sprd_iommu_pgt_size(&dom->domain); + dma_free_coherent(dom->sdev->dev, pgt_size, dom->pgt_va, dom->pgt_pa); +- dom->sdev = NULL; + sprd_iommu_hw_en(dom->sdev, false); ++ dom->sdev = NULL; + } + + static void sprd_iommu_domain_free(struct iommu_domain *domain) +diff --git a/drivers/irqchip/irq-imx-irqsteer.c b/drivers/irqchip/irq-imx-irqsteer.c +index bd95433145399..7df53b4532b43 100644 +--- a/drivers/irqchip/irq-imx-irqsteer.c ++++ b/drivers/irqchip/irq-imx-irqsteer.c +@@ -36,6 +36,7 @@ struct irqsteer_data { + int channel; + struct irq_domain *domain; + u32 *saved_reg; ++ struct device *dev; + }; + + static int imx_irqsteer_get_reg_index(struct irqsteer_data *data, +@@ -72,10 +73,26 @@ static void imx_irqsteer_irq_mask(struct irq_data *d) + raw_spin_unlock_irqrestore(&data->lock, flags); + } + ++static void imx_irqsteer_irq_bus_lock(struct irq_data *d) ++{ ++ struct irqsteer_data *data = d->chip_data; ++ ++ pm_runtime_get_sync(data->dev); ++} ++ ++static void imx_irqsteer_irq_bus_sync_unlock(struct irq_data *d) ++{ ++ struct irqsteer_data *data = d->chip_data; ++ ++ pm_runtime_put_autosuspend(data->dev); ++} ++ + static const struct irq_chip imx_irqsteer_irq_chip = { +- .name = "irqsteer", +- .irq_mask = imx_irqsteer_irq_mask, +- .irq_unmask = imx_irqsteer_irq_unmask, ++ .name = "irqsteer", ++ .irq_mask = imx_irqsteer_irq_mask, ++ .irq_unmask = imx_irqsteer_irq_unmask, ++ .irq_bus_lock = imx_irqsteer_irq_bus_lock, ++ .irq_bus_sync_unlock = imx_irqsteer_irq_bus_sync_unlock, + }; + + static int imx_irqsteer_irq_map(struct irq_domain *h, unsigned int irq, +@@ -150,6 +167,7 @@ static int imx_irqsteer_probe(struct platform_device *pdev) + if (!data) + return -ENOMEM; + ++ data->dev = &pdev->dev; + data->regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(data->regs)) { + dev_err(&pdev->dev, "failed to initialize reg\n"); +diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c +index 2e5cb9dde3ec5..44383cec1f47a 100644 +--- a/drivers/isdn/hardware/mISDN/hfcmulti.c ++++ b/drivers/isdn/hardware/mISDN/hfcmulti.c +@@ -1900,7 +1900,7 @@ hfcmulti_dtmf(struct hfc_multi *hc) + static void + hfcmulti_tx(struct hfc_multi *hc, int ch) + { +- int i, ii, temp, len = 0; ++ int i, ii, temp, tmp_len, len = 0; + int Zspace, z1, z2; /* must be int for calculation */ + int Fspace, f1, f2; + u_char *d; +@@ -2121,14 +2121,15 @@ hfcmulti_tx(struct hfc_multi *hc, int ch) + HFC_wait_nodebug(hc); + } + ++ tmp_len = (*sp)->len; + dev_kfree_skb(*sp); + /* check for next frame */ + if (bch && get_next_bframe(bch)) { +- len = (*sp)->len; ++ len = tmp_len; + goto next_frame; + } + if (dch && get_next_dframe(dch)) { +- len = (*sp)->len; ++ len = tmp_len; + goto next_frame; + } + +diff --git a/drivers/leds/flash/leds-mt6360.c b/drivers/leds/flash/leds-mt6360.c +index 1af6c58983434..fdf0812774cee 100644 +--- a/drivers/leds/flash/leds-mt6360.c ++++ b/drivers/leds/flash/leds-mt6360.c +@@ -633,14 +633,17 @@ static int mt6360_init_isnk_properties(struct mt6360_led *led, + + ret = fwnode_property_read_u32(child, "reg", ®); + if (ret || reg > MT6360_LED_ISNK3 || +- priv->leds_active & BIT(reg)) ++ priv->leds_active & BIT(reg)) { ++ fwnode_handle_put(child); + return -EINVAL; ++ } + + ret = fwnode_property_read_u32(child, "color", &color); + if (ret) { + dev_err(priv->dev, + "led %d, no color specified\n", + led->led_no); ++ fwnode_handle_put(child); + return ret; + } + +diff --git a/drivers/leds/flash/leds-qcom-flash.c b/drivers/leds/flash/leds-qcom-flash.c +index a73d3ea5c97a3..17391aefeb941 100644 +--- a/drivers/leds/flash/leds-qcom-flash.c ++++ b/drivers/leds/flash/leds-qcom-flash.c +@@ -505,6 +505,7 @@ qcom_flash_v4l2_init(struct device *dev, struct qcom_flash_led *led, struct fwno + struct qcom_flash_data *flash_data = led->flash_data; + struct v4l2_flash_config v4l2_cfg = { 0 }; + struct led_flash_setting *intensity = &v4l2_cfg.intensity; ++ struct v4l2_flash *v4l2_flash; + + if (!(led->flash.led_cdev.flags & LED_DEV_CAP_FLASH)) + return 0; +@@ -523,9 +524,12 @@ qcom_flash_v4l2_init(struct device *dev, struct qcom_flash_led *led, struct fwno + LED_FAULT_OVER_TEMPERATURE | + LED_FAULT_TIMEOUT; + +- flash_data->v4l2_flash[flash_data->leds_count] = +- v4l2_flash_init(dev, fwnode, &led->flash, &qcom_v4l2_flash_ops, &v4l2_cfg); +- return PTR_ERR_OR_ZERO(flash_data->v4l2_flash); ++ v4l2_flash = v4l2_flash_init(dev, fwnode, &led->flash, &qcom_v4l2_flash_ops, &v4l2_cfg); ++ if (IS_ERR(v4l2_flash)) ++ return PTR_ERR(v4l2_flash); ++ ++ flash_data->v4l2_flash[flash_data->leds_count] = v4l2_flash; ++ return 0; + } + # else + static int +diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c +index ba1be15cfd8ea..c66d1bead0a4a 100644 +--- a/drivers/leds/led-class.c ++++ b/drivers/leds/led-class.c +@@ -258,7 +258,6 @@ struct led_classdev *of_led_get(struct device_node *np, int index) + + led_dev = class_find_device_by_of_node(&leds_class, led_node); + of_node_put(led_node); +- put_device(led_dev); + + return led_module_get(led_dev); + } +diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c +index 6a5e1f41f9a45..4f5829b726a75 100644 +--- a/drivers/leds/led-triggers.c ++++ b/drivers/leds/led-triggers.c +@@ -179,9 +179,9 @@ int led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig) + + cancel_work_sync(&led_cdev->set_brightness_work); + led_stop_software_blink(led_cdev); ++ device_remove_groups(led_cdev->dev, led_cdev->trigger->groups); + if (led_cdev->trigger->deactivate) + led_cdev->trigger->deactivate(led_cdev); +- device_remove_groups(led_cdev->dev, led_cdev->trigger->groups); + led_cdev->trigger = NULL; + led_cdev->trigger_data = NULL; + led_cdev->activated = false; +diff --git a/drivers/leds/leds-ss4200.c b/drivers/leds/leds-ss4200.c +index fcaa34706b6ca..2ef9fc7371bd1 100644 +--- a/drivers/leds/leds-ss4200.c ++++ b/drivers/leds/leds-ss4200.c +@@ -356,8 +356,10 @@ static int ich7_lpc_probe(struct pci_dev *dev, + + nas_gpio_pci_dev = dev; + status = pci_read_config_dword(dev, PMBASE, &g_pm_io_base); +- if (status) ++ if (status) { ++ status = pcibios_err_to_errno(status); + goto out; ++ } + g_pm_io_base &= 0x00000ff80; + + status = pci_read_config_dword(dev, GPIO_CTRL, &gc); +@@ -369,8 +371,9 @@ static int ich7_lpc_probe(struct pci_dev *dev, + } + + status = pci_read_config_dword(dev, GPIO_BASE, &nas_gpio_io_base); +- if (0 > status) { ++ if (status) { + dev_info(&dev->dev, "Unable to read GPIOBASE.\n"); ++ status = pcibios_err_to_errno(status); + goto out; + } + dev_dbg(&dev->dev, ": GPIOBASE = 0x%08x\n", nas_gpio_io_base); +diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c +index 3c1b29476ce24..5c001105cdd9e 100644 +--- a/drivers/macintosh/therm_windtunnel.c ++++ b/drivers/macintosh/therm_windtunnel.c +@@ -551,7 +551,7 @@ g4fan_exit( void ) + platform_driver_unregister( &therm_of_driver ); + + if( x.of_dev ) +- of_device_unregister( x.of_dev ); ++ of_platform_device_destroy(&x.of_dev->dev, NULL); + } + + module_init(g4fan_init); +diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c +index 49e4a35d70196..3636387ce565a 100644 +--- a/drivers/md/dm-verity-target.c ++++ b/drivers/md/dm-verity-target.c +@@ -1511,14 +1511,6 @@ static int verity_ctr(struct dm_target *ti, unsigned int argc, char **argv) + return r; + } + +-/* +- * Check whether a DM target is a verity target. +- */ +-bool dm_is_verity_target(struct dm_target *ti) +-{ +- return ti->type->module == THIS_MODULE; +-} +- + /* + * Get the verity mode (error behavior) of a verity target. + * +@@ -1572,6 +1564,14 @@ static struct target_type verity_target = { + }; + module_dm(verity); + ++/* ++ * Check whether a DM target is a verity target. ++ */ ++bool dm_is_verity_target(struct dm_target *ti) ++{ ++ return ti->type == &verity_target; ++} ++ + MODULE_AUTHOR("Mikulas Patocka <mpatocka@redhat.com>"); + MODULE_AUTHOR("Mandeep Baines <msb@chromium.org>"); + MODULE_AUTHOR("Will Drewry <wad@chromium.org>"); +diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c +index d9235ee7dcc46..be65472d8f8b3 100644 +--- a/drivers/md/md-bitmap.c ++++ b/drivers/md/md-bitmap.c +@@ -227,6 +227,8 @@ static int __write_sb_page(struct md_rdev *rdev, struct bitmap *bitmap, + struct block_device *bdev; + struct mddev *mddev = bitmap->mddev; + struct bitmap_storage *store = &bitmap->storage; ++ unsigned int bitmap_limit = (bitmap->storage.file_pages - pg_index) << ++ PAGE_SHIFT; + loff_t sboff, offset = mddev->bitmap_info.offset; + sector_t ps = pg_index * PAGE_SIZE / SECTOR_SIZE; + unsigned int size = PAGE_SIZE; +@@ -269,11 +271,9 @@ static int __write_sb_page(struct md_rdev *rdev, struct bitmap *bitmap, + if (size == 0) + /* bitmap runs in to data */ + return -EINVAL; +- } else { +- /* DATA METADATA BITMAP - no problems */ + } + +- md_super_write(mddev, rdev, sboff + ps, (int) size, page); ++ md_super_write(mddev, rdev, sboff + ps, (int)min(size, bitmap_limit), page); + return 0; + } + +diff --git a/drivers/md/md.c b/drivers/md/md.c +index e4d3741234d90..b5dea664f946d 100644 +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -493,13 +493,9 @@ static void md_end_flush(struct bio *bio) + + rdev_dec_pending(rdev, mddev); + +- if (atomic_dec_and_test(&mddev->flush_pending)) { +- /* The pair is percpu_ref_get() from md_flush_request() */ +- percpu_ref_put(&mddev->active_io); +- ++ if (atomic_dec_and_test(&mddev->flush_pending)) + /* The pre-request flush has finished */ + queue_work(md_wq, &mddev->flush_work); +- } + } + + static void md_submit_flush_data(struct work_struct *ws); +@@ -530,12 +526,8 @@ static void submit_flushes(struct work_struct *ws) + rcu_read_lock(); + } + rcu_read_unlock(); +- if (atomic_dec_and_test(&mddev->flush_pending)) { +- /* The pair is percpu_ref_get() from md_flush_request() */ +- percpu_ref_put(&mddev->active_io); +- ++ if (atomic_dec_and_test(&mddev->flush_pending)) + queue_work(md_wq, &mddev->flush_work); +- } + } + + static void md_submit_flush_data(struct work_struct *ws) +@@ -560,8 +552,20 @@ static void md_submit_flush_data(struct work_struct *ws) + bio_endio(bio); + } else { + bio->bi_opf &= ~REQ_PREFLUSH; +- md_handle_request(mddev, bio); ++ ++ /* ++ * make_requst() will never return error here, it only ++ * returns error in raid5_make_request() by dm-raid. ++ * Since dm always splits data and flush operation into ++ * two separate io, io size of flush submitted by dm ++ * always is 0, make_request() will not be called here. ++ */ ++ if (WARN_ON_ONCE(!mddev->pers->make_request(mddev, bio))) ++ bio_io_error(bio);; + } ++ ++ /* The pair is percpu_ref_get() from md_flush_request() */ ++ percpu_ref_put(&mddev->active_io); + } + + /* +@@ -7680,12 +7684,6 @@ static int md_ioctl(struct block_device *bdev, blk_mode_t mode, + + } + +- if (cmd == HOT_REMOVE_DISK) +- /* need to ensure recovery thread has run */ +- wait_event_interruptible_timeout(mddev->sb_wait, +- !test_bit(MD_RECOVERY_NEEDED, +- &mddev->recovery), +- msecs_to_jiffies(5000)); + if (cmd == STOP_ARRAY || cmd == STOP_ARRAY_RO) { + /* Need to flush page cache, and ensure no-one else opens + * and writes +diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c +index 3afa3f79c8a26..a9a8cd148f4fc 100644 +--- a/drivers/media/i2c/imx219.c ++++ b/drivers/media/i2c/imx219.c +@@ -188,8 +188,8 @@ static const struct cci_reg_sequence imx219_common_regs[] = { + { IMX219_REG_MODE_SELECT, 0x00 }, /* Mode Select */ + + /* To Access Addresses 3000-5fff, send the following commands */ +- { CCI_REG8(0x30eb), 0x0c }, + { CCI_REG8(0x30eb), 0x05 }, ++ { CCI_REG8(0x30eb), 0x0c }, + { CCI_REG8(0x300a), 0xff }, + { CCI_REG8(0x300b), 0xff }, + { CCI_REG8(0x30eb), 0x05 }, +diff --git a/drivers/media/i2c/imx412.c b/drivers/media/i2c/imx412.c +index c7e862ae4040f..8597f98a8dcf8 100644 +--- a/drivers/media/i2c/imx412.c ++++ b/drivers/media/i2c/imx412.c +@@ -544,14 +544,13 @@ static int imx412_update_controls(struct imx412 *imx412, + */ + static int imx412_update_exp_gain(struct imx412 *imx412, u32 exposure, u32 gain) + { +- u32 lpfr, shutter; ++ u32 lpfr; + int ret; + + lpfr = imx412->vblank + imx412->cur_mode->height; +- shutter = lpfr - exposure; + +- dev_dbg(imx412->dev, "Set exp %u, analog gain %u, shutter %u, lpfr %u", +- exposure, gain, shutter, lpfr); ++ dev_dbg(imx412->dev, "Set exp %u, analog gain %u, lpfr %u", ++ exposure, gain, lpfr); + + ret = imx412_write_reg(imx412, IMX412_REG_HOLD, 1, 1); + if (ret) +@@ -561,7 +560,7 @@ static int imx412_update_exp_gain(struct imx412 *imx412, u32 exposure, u32 gain) + if (ret) + goto error_release_group_hold; + +- ret = imx412_write_reg(imx412, IMX412_REG_EXPOSURE_CIT, 2, shutter); ++ ret = imx412_write_reg(imx412, IMX412_REG_EXPOSURE_CIT, 2, exposure); + if (ret) + goto error_release_group_hold; + +diff --git a/drivers/media/pci/intel/ivsc/mei_csi.c b/drivers/media/pci/intel/ivsc/mei_csi.c +index 5132a7527febb..685b2ec96071a 100644 +--- a/drivers/media/pci/intel/ivsc/mei_csi.c ++++ b/drivers/media/pci/intel/ivsc/mei_csi.c +@@ -124,6 +124,8 @@ struct mei_csi { + struct v4l2_ctrl_handler ctrl_handler; + struct v4l2_ctrl *freq_ctrl; + struct v4l2_ctrl *privacy_ctrl; ++ /* lock for v4l2 controls */ ++ struct mutex ctrl_lock; + unsigned int remote_pad; + /* start streaming or not */ + int streaming; +@@ -189,7 +191,11 @@ static int mei_csi_send(struct mei_csi *csi, u8 *buf, size_t len) + + /* command response status */ + ret = csi->cmd_response.status; +- if (ret) { ++ if (ret == -1) { ++ /* notify privacy on instead of reporting error */ ++ ret = 0; ++ v4l2_ctrl_s_ctrl(csi->privacy_ctrl, 1); ++ } else if (ret) { + ret = -EINVAL; + goto out; + } +@@ -609,11 +615,13 @@ static int mei_csi_init_controls(struct mei_csi *csi) + u32 max; + int ret; + ++ mutex_init(&csi->ctrl_lock); ++ + ret = v4l2_ctrl_handler_init(&csi->ctrl_handler, 2); + if (ret) + return ret; + +- csi->ctrl_handler.lock = &csi->lock; ++ csi->ctrl_handler.lock = &csi->ctrl_lock; + + max = ARRAY_SIZE(link_freq_menu_items) - 1; + csi->freq_ctrl = v4l2_ctrl_new_int_menu(&csi->ctrl_handler, +@@ -772,6 +780,7 @@ static int mei_csi_probe(struct mei_cl_device *cldev, + + err_ctrl_handler: + v4l2_ctrl_handler_free(&csi->ctrl_handler); ++ mutex_destroy(&csi->ctrl_lock); + v4l2_async_nf_unregister(&csi->notifier); + v4l2_async_nf_cleanup(&csi->notifier); + +@@ -791,6 +800,7 @@ static void mei_csi_remove(struct mei_cl_device *cldev) + v4l2_async_nf_unregister(&csi->notifier); + v4l2_async_nf_cleanup(&csi->notifier); + v4l2_ctrl_handler_free(&csi->ctrl_handler); ++ mutex_destroy(&csi->ctrl_lock); + v4l2_async_unregister_subdev(&csi->subdev); + v4l2_subdev_cleanup(&csi->subdev); + media_entity_cleanup(&csi->subdev.entity); +diff --git a/drivers/media/pci/ivtv/ivtv-udma.c b/drivers/media/pci/ivtv/ivtv-udma.c +index 99b9f55ca8292..f467a00492f4b 100644 +--- a/drivers/media/pci/ivtv/ivtv-udma.c ++++ b/drivers/media/pci/ivtv/ivtv-udma.c +@@ -131,6 +131,8 @@ int ivtv_udma_setup(struct ivtv *itv, unsigned long ivtv_dest_addr, + + /* Fill SG List with new values */ + if (ivtv_udma_fill_sg_list(dma, &user_dma, 0) < 0) { ++ IVTV_DEBUG_WARN("%s: could not allocate bounce buffers for highmem userspace buffers\n", ++ __func__); + unpin_user_pages(dma->map, dma->page_count); + dma->page_count = 0; + return -ENOMEM; +@@ -139,6 +141,12 @@ int ivtv_udma_setup(struct ivtv *itv, unsigned long ivtv_dest_addr, + /* Map SG List */ + dma->SG_length = dma_map_sg(&itv->pdev->dev, dma->SGlist, + dma->page_count, DMA_TO_DEVICE); ++ if (!dma->SG_length) { ++ IVTV_DEBUG_WARN("%s: DMA map error, SG_length is 0\n", __func__); ++ unpin_user_pages(dma->map, dma->page_count); ++ dma->page_count = 0; ++ return -EINVAL; ++ } + + /* Fill SG Array with new values */ + ivtv_udma_fill_sg_array (dma, ivtv_dest_addr, 0, -1); +diff --git a/drivers/media/pci/ivtv/ivtv-yuv.c b/drivers/media/pci/ivtv/ivtv-yuv.c +index 582146f8d70d5..2d9274537725a 100644 +--- a/drivers/media/pci/ivtv/ivtv-yuv.c ++++ b/drivers/media/pci/ivtv/ivtv-yuv.c +@@ -114,6 +114,12 @@ static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma, + } + dma->SG_length = dma_map_sg(&itv->pdev->dev, dma->SGlist, + dma->page_count, DMA_TO_DEVICE); ++ if (!dma->SG_length) { ++ IVTV_DEBUG_WARN("%s: DMA map error, SG_length is 0\n", __func__); ++ unpin_user_pages(dma->map, dma->page_count); ++ dma->page_count = 0; ++ return -EINVAL; ++ } + + /* Fill SG Array with new values */ + ivtv_udma_fill_sg_array(dma, y_buffer_offset, uv_buffer_offset, y_size); +diff --git a/drivers/media/pci/ivtv/ivtvfb.c b/drivers/media/pci/ivtv/ivtvfb.c +index 23c8c094e791b..9cdd14a3033c9 100644 +--- a/drivers/media/pci/ivtv/ivtvfb.c ++++ b/drivers/media/pci/ivtv/ivtvfb.c +@@ -281,10 +281,10 @@ static int ivtvfb_prep_dec_dma_to_device(struct ivtv *itv, + /* Map User DMA */ + if (ivtv_udma_setup(itv, ivtv_dest_addr, userbuf, size_in_bytes) <= 0) { + mutex_unlock(&itv->udma.lock); +- IVTVFB_WARN("ivtvfb_prep_dec_dma_to_device, Error with pin_user_pages: %d bytes, %d pages returned\n", +- size_in_bytes, itv->udma.page_count); ++ IVTVFB_WARN("%s, Error in ivtv_udma_setup: %d bytes, %d pages returned\n", ++ __func__, size_in_bytes, itv->udma.page_count); + +- /* pin_user_pages must have failed completely */ ++ /* pin_user_pages or DMA must have failed completely */ + return -EIO; + } + +diff --git a/drivers/media/pci/saa7134/saa7134-dvb.c b/drivers/media/pci/saa7134/saa7134-dvb.c +index 9c6cfef03331d..a66df6adfaad8 100644 +--- a/drivers/media/pci/saa7134/saa7134-dvb.c ++++ b/drivers/media/pci/saa7134/saa7134-dvb.c +@@ -466,7 +466,9 @@ static int philips_europa_tuner_sleep(struct dvb_frontend *fe) + /* switch the board to analog mode */ + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); +- i2c_transfer(&dev->i2c_adap, &analog_msg, 1); ++ if (i2c_transfer(&dev->i2c_adap, &analog_msg, 1) != 1) ++ return -EIO; ++ + return 0; + } + +@@ -1018,7 +1020,9 @@ static int md8800_set_voltage2(struct dvb_frontend *fe, + else + wbuf[1] = rbuf & 0xef; + msg[0].len = 2; +- i2c_transfer(&dev->i2c_adap, msg, 1); ++ if (i2c_transfer(&dev->i2c_adap, msg, 1) != 1) ++ return -EIO; ++ + return 0; + } + +diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c +index da6be556727bb..145958206e38a 100644 +--- a/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c ++++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c +@@ -233,6 +233,12 @@ int vpu_dec_init(struct vdec_vpu_inst *vpu) + mtk_vdec_debug(vpu->ctx, "vdec_inst=%p", vpu); + + err = vcodec_vpu_send_msg(vpu, (void *)&msg, sizeof(msg)); ++ ++ if (IS_ERR_OR_NULL(vpu->vsi)) { ++ mtk_vdec_err(vpu->ctx, "invalid vdec vsi, status=%d", err); ++ return -EINVAL; ++ } ++ + mtk_vdec_debug(vpu->ctx, "- ret=%d", err); + return err; + } +diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c +index 0c8b204535ffc..2007152cd7a40 100644 +--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c ++++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c +@@ -1632,6 +1632,9 @@ static int mxc_jpeg_start_streaming(struct vb2_queue *q, unsigned int count) + dev_dbg(ctx->mxc_jpeg->dev, "Start streaming ctx=%p", ctx); + q_data->sequence = 0; + ++ if (V4L2_TYPE_IS_CAPTURE(q->type)) ++ ctx->need_initial_source_change_evt = false; ++ + ret = pm_runtime_resume_and_get(ctx->mxc_jpeg->dev); + if (ret < 0) { + dev_err(ctx->mxc_jpeg->dev, "Failed to power up jpeg\n"); +diff --git a/drivers/media/platform/nxp/imx-pxp.c b/drivers/media/platform/nxp/imx-pxp.c +index e62dc5c1a4aea..e4427e6487fba 100644 +--- a/drivers/media/platform/nxp/imx-pxp.c ++++ b/drivers/media/platform/nxp/imx-pxp.c +@@ -1805,6 +1805,9 @@ static int pxp_probe(struct platform_device *pdev) + return PTR_ERR(mmio); + dev->regmap = devm_regmap_init_mmio(&pdev->dev, mmio, + &pxp_regmap_config); ++ if (IS_ERR(dev->regmap)) ++ return dev_err_probe(&pdev->dev, PTR_ERR(dev->regmap), ++ "Failed to init regmap\n"); + + irq = platform_get_irq(pdev, 0); + if (irq < 0) +diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c +index dbf305cec1202..884ee6e9d4bd1 100644 +--- a/drivers/media/platform/qcom/venus/vdec.c ++++ b/drivers/media/platform/qcom/venus/vdec.c +@@ -1255,7 +1255,7 @@ static int vdec_stop_output(struct venus_inst *inst) + break; + case VENUS_DEC_STATE_INIT: + case VENUS_DEC_STATE_CAPTURE_SETUP: +- ret = hfi_session_flush(inst, HFI_FLUSH_INPUT, true); ++ ret = hfi_session_flush(inst, HFI_FLUSH_ALL, true); + break; + default: + break; +@@ -1747,6 +1747,7 @@ static int vdec_close(struct file *file) + + vdec_pm_get(inst); + ++ cancel_work_sync(&inst->delayed_process_work); + v4l2_m2m_ctx_release(inst->m2m_ctx); + v4l2_m2m_release(inst->m2m_dev); + vdec_ctrl_deinit(inst); +diff --git a/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c b/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c +index f6326df0b09be..109cca91f733a 100644 +--- a/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c ++++ b/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c +@@ -1914,12 +1914,14 @@ static int rcsi2_probe(struct platform_device *pdev) + + ret = v4l2_async_register_subdev(&priv->subdev); + if (ret < 0) +- goto error_async; ++ goto error_pm_runtime; + + dev_info(priv->dev, "%d lanes found\n", priv->lanes); + + return 0; + ++error_pm_runtime: ++ pm_runtime_disable(&pdev->dev); + error_async: + v4l2_async_nf_unregister(&priv->notifier); + v4l2_async_nf_cleanup(&priv->notifier); +@@ -1936,6 +1938,7 @@ static void rcsi2_remove(struct platform_device *pdev) + v4l2_async_nf_unregister(&priv->notifier); + v4l2_async_nf_cleanup(&priv->notifier); + v4l2_async_unregister_subdev(&priv->subdev); ++ v4l2_subdev_cleanup(&priv->subdev); + + pm_runtime_disable(&pdev->dev); + +diff --git a/drivers/media/platform/renesas/rcar-vin/rcar-dma.c b/drivers/media/platform/renesas/rcar-vin/rcar-dma.c +index 2a77353f10b59..bb4774e2f335e 100644 +--- a/drivers/media/platform/renesas/rcar-vin/rcar-dma.c ++++ b/drivers/media/platform/renesas/rcar-vin/rcar-dma.c +@@ -742,12 +742,22 @@ static int rvin_setup(struct rvin_dev *vin) + */ + switch (vin->mbus_code) { + case MEDIA_BUS_FMT_YUYV8_1X16: +- /* BT.601/BT.1358 16bit YCbCr422 */ +- vnmc |= VNMC_INF_YUV16; ++ if (vin->is_csi) ++ /* YCbCr422 8-bit */ ++ vnmc |= VNMC_INF_YUV8_BT601; ++ else ++ /* BT.601/BT.1358 16bit YCbCr422 */ ++ vnmc |= VNMC_INF_YUV16; + input_is_yuv = true; + break; + case MEDIA_BUS_FMT_UYVY8_1X16: +- vnmc |= VNMC_INF_YUV16 | VNMC_YCAL; ++ if (vin->is_csi) ++ /* YCbCr422 8-bit */ ++ vnmc |= VNMC_INF_YUV8_BT601; ++ else ++ /* BT.601/BT.1358 16bit YCbCr422 */ ++ vnmc |= VNMC_INF_YUV16; ++ vnmc |= VNMC_YCAL; + input_is_yuv = true; + break; + case MEDIA_BUS_FMT_UYVY8_2X8: +diff --git a/drivers/media/platform/renesas/vsp1/vsp1_histo.c b/drivers/media/platform/renesas/vsp1/vsp1_histo.c +index f22449dd654cb..c0f1002f4ecf1 100644 +--- a/drivers/media/platform/renesas/vsp1/vsp1_histo.c ++++ b/drivers/media/platform/renesas/vsp1/vsp1_histo.c +@@ -36,9 +36,8 @@ struct vsp1_histogram_buffer * + vsp1_histogram_buffer_get(struct vsp1_histogram *histo) + { + struct vsp1_histogram_buffer *buf = NULL; +- unsigned long flags; + +- spin_lock_irqsave(&histo->irqlock, flags); ++ spin_lock(&histo->irqlock); + + if (list_empty(&histo->irqqueue)) + goto done; +@@ -49,7 +48,7 @@ vsp1_histogram_buffer_get(struct vsp1_histogram *histo) + histo->readout = true; + + done: +- spin_unlock_irqrestore(&histo->irqlock, flags); ++ spin_unlock(&histo->irqlock); + return buf; + } + +@@ -58,7 +57,6 @@ void vsp1_histogram_buffer_complete(struct vsp1_histogram *histo, + size_t size) + { + struct vsp1_pipeline *pipe = histo->entity.pipe; +- unsigned long flags; + + /* + * The pipeline pointer is guaranteed to be valid as this function is +@@ -70,10 +68,10 @@ void vsp1_histogram_buffer_complete(struct vsp1_histogram *histo, + vb2_set_plane_payload(&buf->buf.vb2_buf, 0, size); + vb2_buffer_done(&buf->buf.vb2_buf, VB2_BUF_STATE_DONE); + +- spin_lock_irqsave(&histo->irqlock, flags); ++ spin_lock(&histo->irqlock); + histo->readout = false; + wake_up(&histo->wait_queue); +- spin_unlock_irqrestore(&histo->irqlock, flags); ++ spin_unlock(&histo->irqlock); + } + + /* ----------------------------------------------------------------------------- +@@ -124,11 +122,10 @@ static void histo_buffer_queue(struct vb2_buffer *vb) + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); + struct vsp1_histogram *histo = vb2_get_drv_priv(vb->vb2_queue); + struct vsp1_histogram_buffer *buf = to_vsp1_histogram_buffer(vbuf); +- unsigned long flags; + +- spin_lock_irqsave(&histo->irqlock, flags); ++ spin_lock_irq(&histo->irqlock); + list_add_tail(&buf->queue, &histo->irqqueue); +- spin_unlock_irqrestore(&histo->irqlock, flags); ++ spin_unlock_irq(&histo->irqlock); + } + + static int histo_start_streaming(struct vb2_queue *vq, unsigned int count) +@@ -140,9 +137,8 @@ static void histo_stop_streaming(struct vb2_queue *vq) + { + struct vsp1_histogram *histo = vb2_get_drv_priv(vq); + struct vsp1_histogram_buffer *buffer; +- unsigned long flags; + +- spin_lock_irqsave(&histo->irqlock, flags); ++ spin_lock_irq(&histo->irqlock); + + /* Remove all buffers from the IRQ queue. */ + list_for_each_entry(buffer, &histo->irqqueue, queue) +@@ -152,7 +148,7 @@ static void histo_stop_streaming(struct vb2_queue *vq) + /* Wait for the buffer being read out (if any) to complete. */ + wait_event_lock_irq(histo->wait_queue, !histo->readout, histo->irqlock); + +- spin_unlock_irqrestore(&histo->irqlock, flags); ++ spin_unlock_irq(&histo->irqlock); + } + + static const struct vb2_ops histo_video_queue_qops = { +diff --git a/drivers/media/platform/renesas/vsp1/vsp1_pipe.h b/drivers/media/platform/renesas/vsp1/vsp1_pipe.h +index 674b5748d929e..85ecd53cda495 100644 +--- a/drivers/media/platform/renesas/vsp1/vsp1_pipe.h ++++ b/drivers/media/platform/renesas/vsp1/vsp1_pipe.h +@@ -73,7 +73,7 @@ struct vsp1_partition_window { + * @wpf: The WPF partition window configuration + */ + struct vsp1_partition { +- struct vsp1_partition_window rpf; ++ struct vsp1_partition_window rpf[VSP1_MAX_RPF]; + struct vsp1_partition_window uds_sink; + struct vsp1_partition_window uds_source; + struct vsp1_partition_window sru; +diff --git a/drivers/media/platform/renesas/vsp1/vsp1_rpf.c b/drivers/media/platform/renesas/vsp1/vsp1_rpf.c +index ea12c3f12c92a..78b6cefc5a019 100644 +--- a/drivers/media/platform/renesas/vsp1/vsp1_rpf.c ++++ b/drivers/media/platform/renesas/vsp1/vsp1_rpf.c +@@ -315,8 +315,8 @@ static void rpf_configure_partition(struct vsp1_entity *entity, + * 'width' need to be adjusted. + */ + if (pipe->partitions > 1) { +- crop.width = pipe->partition->rpf.width; +- crop.left += pipe->partition->rpf.left; ++ crop.width = pipe->partition->rpf[rpf->entity.index].width; ++ crop.left += pipe->partition->rpf[rpf->entity.index].left; + } + + if (pipe->interlaced) { +@@ -371,7 +371,9 @@ static void rpf_partition(struct vsp1_entity *entity, + unsigned int partition_idx, + struct vsp1_partition_window *window) + { +- partition->rpf = *window; ++ struct vsp1_rwpf *rpf = to_rwpf(&entity->subdev); ++ ++ partition->rpf[rpf->entity.index] = *window; + } + + static const struct vsp1_entity_operations rpf_entity_ops = { +diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c +index 5719dda6e0f0e..e5590a708f1c5 100644 +--- a/drivers/media/rc/imon.c ++++ b/drivers/media/rc/imon.c +@@ -1148,10 +1148,7 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 *rc_proto) + + memcpy(ictx->usb_tx_buf, &ir_proto_packet, sizeof(ir_proto_packet)); + +- if (!mutex_is_locked(&ictx->lock)) { +- unlock = true; +- mutex_lock(&ictx->lock); +- } ++ unlock = mutex_trylock(&ictx->lock); + + retval = send_packet(ictx); + if (retval) +diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c +index caad59f76793f..f8901d6fbe9bf 100644 +--- a/drivers/media/rc/lirc_dev.c ++++ b/drivers/media/rc/lirc_dev.c +@@ -828,8 +828,10 @@ struct rc_dev *rc_dev_get_from_fd(int fd, bool write) + return ERR_PTR(-EINVAL); + } + +- if (write && !(f.file->f_mode & FMODE_WRITE)) ++ if (write && !(f.file->f_mode & FMODE_WRITE)) { ++ fdput(f); + return ERR_PTR(-EPERM); ++ } + + fh = f.file->private_data; + dev = fh->rc; +diff --git a/drivers/media/usb/dvb-usb/dvb-usb-init.c b/drivers/media/usb/dvb-usb/dvb-usb-init.c +index fbf58012becdf..22d83ac18eb73 100644 +--- a/drivers/media/usb/dvb-usb/dvb-usb-init.c ++++ b/drivers/media/usb/dvb-usb/dvb-usb-init.c +@@ -23,11 +23,40 @@ static int dvb_usb_force_pid_filter_usage; + module_param_named(force_pid_filter_usage, dvb_usb_force_pid_filter_usage, int, 0444); + MODULE_PARM_DESC(force_pid_filter_usage, "force all dvb-usb-devices to use a PID filter, if any (default: 0)."); + ++static int dvb_usb_check_bulk_endpoint(struct dvb_usb_device *d, u8 endpoint) ++{ ++ if (endpoint) { ++ int ret; ++ ++ ret = usb_pipe_type_check(d->udev, usb_sndbulkpipe(d->udev, endpoint)); ++ if (ret) ++ return ret; ++ ret = usb_pipe_type_check(d->udev, usb_rcvbulkpipe(d->udev, endpoint)); ++ if (ret) ++ return ret; ++ } ++ return 0; ++} ++ ++static void dvb_usb_clear_halt(struct dvb_usb_device *d, u8 endpoint) ++{ ++ if (endpoint) { ++ usb_clear_halt(d->udev, usb_sndbulkpipe(d->udev, endpoint)); ++ usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, endpoint)); ++ } ++} ++ + static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs) + { + struct dvb_usb_adapter *adap; + int ret, n, o; + ++ ret = dvb_usb_check_bulk_endpoint(d, d->props.generic_bulk_ctrl_endpoint); ++ if (ret) ++ return ret; ++ ret = dvb_usb_check_bulk_endpoint(d, d->props.generic_bulk_ctrl_endpoint_response); ++ if (ret) ++ return ret; + for (n = 0; n < d->props.num_adapters; n++) { + adap = &d->adapter[n]; + adap->dev = d; +@@ -103,10 +132,8 @@ static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs) + * when reloading the driver w/o replugging the device + * sometimes a timeout occurs, this helps + */ +- if (d->props.generic_bulk_ctrl_endpoint != 0) { +- usb_clear_halt(d->udev, usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); +- usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); +- } ++ dvb_usb_clear_halt(d, d->props.generic_bulk_ctrl_endpoint); ++ dvb_usb_clear_halt(d, d->props.generic_bulk_ctrl_endpoint_response); + + return 0; + +diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c +index e59a463c27618..07158e9451fed 100644 +--- a/drivers/media/usb/uvc/uvc_ctrl.c ++++ b/drivers/media/usb/uvc/uvc_ctrl.c +@@ -2029,7 +2029,13 @@ static int uvc_ctrl_get_flags(struct uvc_device *dev, + else + ret = uvc_query_ctrl(dev, UVC_GET_INFO, ctrl->entity->id, + dev->intfnum, info->selector, data, 1); +- if (!ret) ++ ++ if (!ret) { ++ info->flags &= ~(UVC_CTRL_FLAG_GET_CUR | ++ UVC_CTRL_FLAG_SET_CUR | ++ UVC_CTRL_FLAG_AUTO_UPDATE | ++ UVC_CTRL_FLAG_ASYNCHRONOUS); ++ + info->flags |= (data[0] & UVC_CONTROL_CAP_GET ? + UVC_CTRL_FLAG_GET_CUR : 0) + | (data[0] & UVC_CONTROL_CAP_SET ? +@@ -2038,6 +2044,7 @@ static int uvc_ctrl_get_flags(struct uvc_device *dev, + UVC_CTRL_FLAG_AUTO_UPDATE : 0) + | (data[0] & UVC_CONTROL_CAP_ASYNCHRONOUS ? + UVC_CTRL_FLAG_ASYNCHRONOUS : 0); ++ } + + kfree(data); + return ret; +diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c +index 91a41aa3ced24..68bf41147a619 100644 +--- a/drivers/media/usb/uvc/uvc_driver.c ++++ b/drivers/media/usb/uvc/uvc_driver.c +@@ -2236,8 +2236,11 @@ static int uvc_probe(struct usb_interface *intf, + if (dev->quirks & UVC_QUIRK_NO_RESET_RESUME) + udev->quirks &= ~USB_QUIRK_RESET_RESUME; + ++ if (!(dev->quirks & UVC_QUIRK_DISABLE_AUTOSUSPEND)) ++ usb_enable_autosuspend(udev); ++ + uvc_dbg(dev, PROBE, "UVC device initialized\n"); +- usb_enable_autosuspend(udev); ++ + return 0; + + error: +@@ -2577,7 +2580,17 @@ static const struct usb_device_id uvc_ids[] = { + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, +- .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_RESTORE_CTRLS_ON_INIT) }, ++ .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_RESTORE_CTRLS_ON_INIT ++ | UVC_QUIRK_INVALID_DEVICE_SOF) }, ++ /* Logitech HD Pro Webcam C922 */ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x046d, ++ .idProduct = 0x085c, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = 0, ++ .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_INVALID_DEVICE_SOF) }, + /* Logitech Rally Bar Huddle */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, +@@ -3043,6 +3056,15 @@ static const struct usb_device_id uvc_ids[] = { + .bInterfaceSubClass = 1, + .bInterfaceProtocol = UVC_PC_PROTOCOL_15, + .driver_info = (kernel_ulong_t)&uvc_ctrl_power_line_uvc11 }, ++ /* Insta360 Link */ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x2e1a, ++ .idProduct = 0x4c01, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = 0, ++ .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_DISABLE_AUTOSUSPEND) }, + /* Lenovo Integrated Camera */ + { .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 28dde08ec6c5d..5eef560bc8cd8 100644 +--- a/drivers/media/usb/uvc/uvc_video.c ++++ b/drivers/media/usb/uvc/uvc_video.c +@@ -529,6 +529,17 @@ uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf, + stream->clock.last_sof = dev_sof; + + host_sof = usb_get_current_frame_number(stream->dev->udev); ++ ++ /* ++ * On some devices, like the Logitech C922, the device SOF does not run ++ * at a stable rate of 1kHz. For those devices use the host SOF instead. ++ * In the tests performed so far, this improves the timestamp precision. ++ * This is probably explained by a small packet handling jitter from the ++ * host, but the exact reason hasn't been fully determined. ++ */ ++ if (stream->dev->quirks & UVC_QUIRK_INVALID_DEVICE_SOF) ++ dev_sof = host_sof; ++ + time = uvc_video_get_time(); + + /* +@@ -709,11 +720,11 @@ void uvc_video_clock_update(struct uvc_streaming *stream, + unsigned long flags; + u64 timestamp; + u32 delta_stc; +- u32 y1, y2; ++ u32 y1; + u32 x1, x2; + u32 mean; + u32 sof; +- u64 y; ++ u64 y, y2; + + if (!uvc_hw_timestamps_param) + return; +@@ -753,7 +764,7 @@ void uvc_video_clock_update(struct uvc_streaming *stream, + sof = y; + + uvc_dbg(stream->dev, CLOCK, +- "%s: PTS %u y %llu.%06llu SOF %u.%06llu (x1 %u x2 %u y1 %u y2 %u SOF offset %u)\n", ++ "%s: PTS %u y %llu.%06llu SOF %u.%06llu (x1 %u x2 %u y1 %u y2 %llu SOF offset %u)\n", + stream->dev->name, buf->pts, + y >> 16, div_u64((y & 0xffff) * 1000000, 65536), + sof >> 16, div_u64(((u64)sof & 0xffff) * 1000000LLU, 65536), +@@ -768,7 +779,7 @@ void uvc_video_clock_update(struct uvc_streaming *stream, + goto done; + + y1 = NSEC_PER_SEC; +- y2 = (u32)ktime_to_ns(ktime_sub(last->host_time, first->host_time)) + y1; ++ y2 = ktime_to_ns(ktime_sub(last->host_time, first->host_time)) + y1; + + /* + * Interpolated and host SOF timestamps can wrap around at slightly +@@ -789,7 +800,7 @@ void uvc_video_clock_update(struct uvc_streaming *stream, + timestamp = ktime_to_ns(first->host_time) + y - y1; + + uvc_dbg(stream->dev, CLOCK, +- "%s: SOF %u.%06llu y %llu ts %llu buf ts %llu (x1 %u/%u/%u x2 %u/%u/%u y1 %u y2 %u)\n", ++ "%s: SOF %u.%06llu y %llu ts %llu buf ts %llu (x1 %u/%u/%u x2 %u/%u/%u y1 %u y2 %llu)\n", + stream->dev->name, + sof >> 16, div_u64(((u64)sof & 0xffff) * 1000000LLU, 65536), + y, timestamp, vbuf->vb2_buf.timestamp, +diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h +index 88218693f6f0b..e5b12717016fa 100644 +--- a/drivers/media/usb/uvc/uvcvideo.h ++++ b/drivers/media/usb/uvc/uvcvideo.h +@@ -74,6 +74,8 @@ + #define UVC_QUIRK_FORCE_BPP 0x00001000 + #define UVC_QUIRK_WAKE_AUTOSUSPEND 0x00002000 + #define UVC_QUIRK_NO_RESET_RESUME 0x00004000 ++#define UVC_QUIRK_DISABLE_AUTOSUSPEND 0x00008000 ++#define UVC_QUIRK_INVALID_DEVICE_SOF 0x00010000 + + /* Format flags */ + #define UVC_FMT_FLAG_COMPRESSED 0x00000001 +diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c +index eaa15b8df76df..ac4d987bba255 100644 +--- a/drivers/media/v4l2-core/v4l2-async.c ++++ b/drivers/media/v4l2-core/v4l2-async.c +@@ -324,6 +324,9 @@ static int v4l2_async_create_ancillary_links(struct v4l2_async_notifier *n, + sd->entity.function != MEDIA_ENT_F_FLASH) + return 0; + ++ if (!n->sd) ++ return 0; ++ + link = media_create_ancillary_link(&n->sd->entity, &sd->entity); + + #endif +diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig +index 8efdd1f971395..c82d8d8a16eaf 100644 +--- a/drivers/memory/Kconfig ++++ b/drivers/memory/Kconfig +@@ -167,7 +167,7 @@ config FSL_CORENET_CF + represents a coherency violation. + + config FSL_IFC +- bool "Freescale IFC driver" if COMPILE_TEST ++ bool "Freescale IFC driver" + depends on FSL_SOC || ARCH_LAYERSCAPE || SOC_LS1021A || COMPILE_TEST + depends on HAS_IOMEM + +diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile +index c66f07edcd0e6..db1ba39de3b59 100644 +--- a/drivers/mfd/Makefile ++++ b/drivers/mfd/Makefile +@@ -280,7 +280,5 @@ obj-$(CONFIG_MFD_INTEL_M10_BMC_PMCI) += intel-m10-bmc-pmci.o + obj-$(CONFIG_MFD_ATC260X) += atc260x-core.o + obj-$(CONFIG_MFD_ATC260X_I2C) += atc260x-i2c.o + +-rsmu-i2c-objs := rsmu_core.o rsmu_i2c.o +-rsmu-spi-objs := rsmu_core.o rsmu_spi.o +-obj-$(CONFIG_MFD_RSMU_I2C) += rsmu-i2c.o +-obj-$(CONFIG_MFD_RSMU_SPI) += rsmu-spi.o ++obj-$(CONFIG_MFD_RSMU_I2C) += rsmu_i2c.o rsmu_core.o ++obj-$(CONFIG_MFD_RSMU_SPI) += rsmu_spi.o rsmu_core.o +diff --git a/drivers/mfd/omap-usb-tll.c b/drivers/mfd/omap-usb-tll.c +index 906353735c782..5ba2b2352749d 100644 +--- a/drivers/mfd/omap-usb-tll.c ++++ b/drivers/mfd/omap-usb-tll.c +@@ -230,8 +230,7 @@ static int usbtll_omap_probe(struct platform_device *pdev) + break; + } + +- tll = devm_kzalloc(dev, sizeof(*tll) + sizeof(tll->ch_clk[nch]), +- GFP_KERNEL); ++ tll = devm_kzalloc(dev, struct_size(tll, ch_clk, nch), GFP_KERNEL); + if (!tll) { + pm_runtime_put_sync(dev); + pm_runtime_disable(dev); +diff --git a/drivers/mfd/rsmu_core.c b/drivers/mfd/rsmu_core.c +index 29437fd0bd5bf..fd04a6e5dfa31 100644 +--- a/drivers/mfd/rsmu_core.c ++++ b/drivers/mfd/rsmu_core.c +@@ -78,11 +78,13 @@ int rsmu_core_init(struct rsmu_ddata *rsmu) + + return ret; + } ++EXPORT_SYMBOL_GPL(rsmu_core_init); + + void rsmu_core_exit(struct rsmu_ddata *rsmu) + { + mutex_destroy(&rsmu->lock); + } ++EXPORT_SYMBOL_GPL(rsmu_core_exit); + + MODULE_DESCRIPTION("Renesas SMU core driver"); + MODULE_LICENSE("GPL"); +diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig +index cbf8ae85e1ae0..6142573085169 100644 +--- a/drivers/mtd/nand/raw/Kconfig ++++ b/drivers/mtd/nand/raw/Kconfig +@@ -234,8 +234,7 @@ config MTD_NAND_FSL_IFC + tristate "Freescale IFC NAND controller" + depends on FSL_SOC || ARCH_LAYERSCAPE || SOC_LS1021A || COMPILE_TEST + depends on HAS_IOMEM +- select FSL_IFC +- select MEMORY ++ depends on FSL_IFC + help + Various Freescale chips e.g P1010, include a NAND Flash machine + with built-in hardware ECC capabilities. +diff --git a/drivers/mtd/tests/Makefile b/drivers/mtd/tests/Makefile +index 5de0378f90dbd..7dae831ee8b6b 100644 +--- a/drivers/mtd/tests/Makefile ++++ b/drivers/mtd/tests/Makefile +@@ -1,19 +1,19 @@ + # SPDX-License-Identifier: GPL-2.0 +-obj-$(CONFIG_MTD_TESTS) += mtd_oobtest.o +-obj-$(CONFIG_MTD_TESTS) += mtd_pagetest.o +-obj-$(CONFIG_MTD_TESTS) += mtd_readtest.o +-obj-$(CONFIG_MTD_TESTS) += mtd_speedtest.o +-obj-$(CONFIG_MTD_TESTS) += mtd_stresstest.o +-obj-$(CONFIG_MTD_TESTS) += mtd_subpagetest.o +-obj-$(CONFIG_MTD_TESTS) += mtd_torturetest.o +-obj-$(CONFIG_MTD_TESTS) += mtd_nandecctest.o +-obj-$(CONFIG_MTD_TESTS) += mtd_nandbiterrs.o ++obj-$(CONFIG_MTD_TESTS) += mtd_oobtest.o mtd_test.o ++obj-$(CONFIG_MTD_TESTS) += mtd_pagetest.o mtd_test.o ++obj-$(CONFIG_MTD_TESTS) += mtd_readtest.o mtd_test.o ++obj-$(CONFIG_MTD_TESTS) += mtd_speedtest.o mtd_test.o ++obj-$(CONFIG_MTD_TESTS) += mtd_stresstest.o mtd_test.o ++obj-$(CONFIG_MTD_TESTS) += mtd_subpagetest.o mtd_test.o ++obj-$(CONFIG_MTD_TESTS) += mtd_torturetest.o mtd_test.o ++obj-$(CONFIG_MTD_TESTS) += mtd_nandecctest.o mtd_test.o ++obj-$(CONFIG_MTD_TESTS) += mtd_nandbiterrs.o mtd_test.o + +-mtd_oobtest-objs := oobtest.o mtd_test.o +-mtd_pagetest-objs := pagetest.o mtd_test.o +-mtd_readtest-objs := readtest.o mtd_test.o +-mtd_speedtest-objs := speedtest.o mtd_test.o +-mtd_stresstest-objs := stresstest.o mtd_test.o +-mtd_subpagetest-objs := subpagetest.o mtd_test.o +-mtd_torturetest-objs := torturetest.o mtd_test.o +-mtd_nandbiterrs-objs := nandbiterrs.o mtd_test.o ++mtd_oobtest-objs := oobtest.o ++mtd_pagetest-objs := pagetest.o ++mtd_readtest-objs := readtest.o ++mtd_speedtest-objs := speedtest.o ++mtd_stresstest-objs := stresstest.o ++mtd_subpagetest-objs := subpagetest.o ++mtd_torturetest-objs := torturetest.o ++mtd_nandbiterrs-objs := nandbiterrs.o +diff --git a/drivers/mtd/tests/mtd_test.c b/drivers/mtd/tests/mtd_test.c +index c84250beffdc9..f391e0300cdc9 100644 +--- a/drivers/mtd/tests/mtd_test.c ++++ b/drivers/mtd/tests/mtd_test.c +@@ -25,6 +25,7 @@ int mtdtest_erase_eraseblock(struct mtd_info *mtd, unsigned int ebnum) + + return 0; + } ++EXPORT_SYMBOL_GPL(mtdtest_erase_eraseblock); + + static int is_block_bad(struct mtd_info *mtd, unsigned int ebnum) + { +@@ -57,6 +58,7 @@ int mtdtest_scan_for_bad_eraseblocks(struct mtd_info *mtd, unsigned char *bbt, + + return 0; + } ++EXPORT_SYMBOL_GPL(mtdtest_scan_for_bad_eraseblocks); + + int mtdtest_erase_good_eraseblocks(struct mtd_info *mtd, unsigned char *bbt, + unsigned int eb, int ebcnt) +@@ -75,6 +77,7 @@ int mtdtest_erase_good_eraseblocks(struct mtd_info *mtd, unsigned char *bbt, + + return 0; + } ++EXPORT_SYMBOL_GPL(mtdtest_erase_good_eraseblocks); + + int mtdtest_read(struct mtd_info *mtd, loff_t addr, size_t size, void *buf) + { +@@ -92,6 +95,7 @@ int mtdtest_read(struct mtd_info *mtd, loff_t addr, size_t size, void *buf) + + return err; + } ++EXPORT_SYMBOL_GPL(mtdtest_read); + + int mtdtest_write(struct mtd_info *mtd, loff_t addr, size_t size, + const void *buf) +@@ -107,3 +111,8 @@ int mtdtest_write(struct mtd_info *mtd, loff_t addr, size_t size, + + return err; + } ++EXPORT_SYMBOL_GPL(mtdtest_write); ++ ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("MTD function test helpers"); ++MODULE_AUTHOR("Akinobu Mita"); +diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c +index 655ff41863e2b..3b71924f49209 100644 +--- a/drivers/mtd/ubi/eba.c ++++ b/drivers/mtd/ubi/eba.c +@@ -1560,6 +1560,7 @@ int self_check_eba(struct ubi_device *ubi, struct ubi_attach_info *ai_fastmap, + GFP_KERNEL); + if (!fm_eba[i]) { + ret = -ENOMEM; ++ kfree(scan_eba[i]); + goto out_free; + } + +@@ -1595,7 +1596,7 @@ int self_check_eba(struct ubi_device *ubi, struct ubi_attach_info *ai_fastmap, + } + + out_free: +- for (i = 0; i < num_volumes; i++) { ++ while (--i >= 0) { + if (!ubi->volumes[i]) + continue; + +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index 34880b2db8050..722ac5c4992c9 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -1121,13 +1121,10 @@ static struct slave *bond_find_best_slave(struct bonding *bond) + return bestslave; + } + ++/* must be called in RCU critical section or with RTNL held */ + static bool bond_should_notify_peers(struct bonding *bond) + { +- struct slave *slave; +- +- rcu_read_lock(); +- slave = rcu_dereference(bond->curr_active_slave); +- rcu_read_unlock(); ++ struct slave *slave = rcu_dereference_rtnl(bond->curr_active_slave); + + if (!slave || !bond->send_peer_notif || + bond->send_peer_notif % +diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c +index 4e27dc913cf71..ae1c4dc35fe33 100644 +--- a/drivers/net/dsa/b53/b53_common.c ++++ b/drivers/net/dsa/b53/b53_common.c +@@ -2265,6 +2265,9 @@ static int b53_change_mtu(struct dsa_switch *ds, int port, int mtu) + if (is5325(dev) || is5365(dev)) + return -EOPNOTSUPP; + ++ if (!dsa_is_cpu_port(ds, port)) ++ return 0; ++ + enable_jumbo = (mtu >= JMS_MIN_SIZE); + allow_10_100 = (dev->chip_id == BCM583XX_DEVICE_ID); + +diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c +index 354d4af134562..3877744193e2a 100644 +--- a/drivers/net/dsa/mv88e6xxx/chip.c ++++ b/drivers/net/dsa/mv88e6xxx/chip.c +@@ -3490,7 +3490,8 @@ static int mv88e6xxx_change_mtu(struct dsa_switch *ds, int port, int new_mtu) + mv88e6xxx_reg_lock(chip); + if (chip->info->ops->port_set_jumbo_size) + ret = chip->info->ops->port_set_jumbo_size(chip, port, new_mtu); +- else if (chip->info->ops->set_max_frame_size) ++ else if (chip->info->ops->set_max_frame_size && ++ dsa_is_cpu_port(ds, port)) + ret = chip->info->ops->set_max_frame_size(chip, new_mtu); + mv88e6xxx_reg_unlock(chip); + +diff --git a/drivers/net/ethernet/brocade/bna/bna_types.h b/drivers/net/ethernet/brocade/bna/bna_types.h +index a5ebd7110e073..986f43d277119 100644 +--- a/drivers/net/ethernet/brocade/bna/bna_types.h ++++ b/drivers/net/ethernet/brocade/bna/bna_types.h +@@ -416,7 +416,7 @@ struct bna_ib { + /* Tx object */ + + /* Tx datapath control structure */ +-#define BNA_Q_NAME_SIZE 16 ++#define BNA_Q_NAME_SIZE (IFNAMSIZ + 6) + struct bna_tcb { + /* Fast path */ + void **sw_qpt; +diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c +index 31191b520b587..6cf06a93bedfb 100644 +--- a/drivers/net/ethernet/brocade/bna/bnad.c ++++ b/drivers/net/ethernet/brocade/bna/bnad.c +@@ -1534,8 +1534,9 @@ bnad_tx_msix_register(struct bnad *bnad, struct bnad_tx_info *tx_info, + + for (i = 0; i < num_txqs; i++) { + vector_num = tx_info->tcb[i]->intr_vector; +- sprintf(tx_info->tcb[i]->name, "%s TXQ %d", bnad->netdev->name, +- tx_id + tx_info->tcb[i]->id); ++ snprintf(tx_info->tcb[i]->name, BNA_Q_NAME_SIZE, "%s TXQ %d", ++ bnad->netdev->name, ++ tx_id + tx_info->tcb[i]->id); + err = request_irq(bnad->msix_table[vector_num].vector, + (irq_handler_t)bnad_msix_tx, 0, + tx_info->tcb[i]->name, +@@ -1585,9 +1586,9 @@ bnad_rx_msix_register(struct bnad *bnad, struct bnad_rx_info *rx_info, + + for (i = 0; i < num_rxps; i++) { + vector_num = rx_info->rx_ctrl[i].ccb->intr_vector; +- sprintf(rx_info->rx_ctrl[i].ccb->name, "%s CQ %d", +- bnad->netdev->name, +- rx_id + rx_info->rx_ctrl[i].ccb->id); ++ snprintf(rx_info->rx_ctrl[i].ccb->name, BNA_Q_NAME_SIZE, ++ "%s CQ %d", bnad->netdev->name, ++ rx_id + rx_info->rx_ctrl[i].ccb->id); + err = request_irq(bnad->msix_table[vector_num].vector, + (irq_handler_t)bnad_msix_rx, 0, + rx_info->rx_ctrl[i].ccb->name, +diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c +index d675f9d5f3612..5604a47b35b2a 100644 +--- a/drivers/net/ethernet/freescale/fec_main.c ++++ b/drivers/net/ethernet/freescale/fec_main.c +@@ -283,8 +283,8 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address"); + #define PKT_MINBUF_SIZE 64 + + /* FEC receive acceleration */ +-#define FEC_RACC_IPDIS (1 << 1) +-#define FEC_RACC_PRODIS (1 << 2) ++#define FEC_RACC_IPDIS BIT(1) ++#define FEC_RACC_PRODIS BIT(2) + #define FEC_RACC_SHIFT16 BIT(7) + #define FEC_RACC_OPTIONS (FEC_RACC_IPDIS | FEC_RACC_PRODIS) + +@@ -316,8 +316,23 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address"); + #define FEC_MMFR_TA (2 << 16) + #define FEC_MMFR_DATA(v) (v & 0xffff) + /* FEC ECR bits definition */ +-#define FEC_ECR_MAGICEN (1 << 2) +-#define FEC_ECR_SLEEP (1 << 3) ++#define FEC_ECR_RESET BIT(0) ++#define FEC_ECR_ETHEREN BIT(1) ++#define FEC_ECR_MAGICEN BIT(2) ++#define FEC_ECR_SLEEP BIT(3) ++#define FEC_ECR_EN1588 BIT(4) ++#define FEC_ECR_BYTESWP BIT(8) ++/* FEC RCR bits definition */ ++#define FEC_RCR_LOOP BIT(0) ++#define FEC_RCR_HALFDPX BIT(1) ++#define FEC_RCR_MII BIT(2) ++#define FEC_RCR_PROMISC BIT(3) ++#define FEC_RCR_BC_REJ BIT(4) ++#define FEC_RCR_FLOWCTL BIT(5) ++#define FEC_RCR_RMII BIT(8) ++#define FEC_RCR_10BASET BIT(9) ++/* TX WMARK bits */ ++#define FEC_TXWMRK_STRFWD BIT(8) + + #define FEC_MII_TIMEOUT 30000 /* us */ + +@@ -1041,7 +1056,7 @@ fec_restart(struct net_device *ndev) + struct fec_enet_private *fep = netdev_priv(ndev); + u32 temp_mac[2]; + u32 rcntl = OPT_FRAME_SIZE | 0x04; +- u32 ecntl = 0x2; /* ETHEREN */ ++ u32 ecntl = FEC_ECR_ETHEREN; + + /* Whack a reset. We should wait for this. + * For i.MX6SX SOC, enet use AXI bus, we use disable MAC +@@ -1116,18 +1131,18 @@ fec_restart(struct net_device *ndev) + fep->phy_interface == PHY_INTERFACE_MODE_RGMII_TXID) + rcntl |= (1 << 6); + else if (fep->phy_interface == PHY_INTERFACE_MODE_RMII) +- rcntl |= (1 << 8); ++ rcntl |= FEC_RCR_RMII; + else +- rcntl &= ~(1 << 8); ++ rcntl &= ~FEC_RCR_RMII; + + /* 1G, 100M or 10M */ + if (ndev->phydev) { + if (ndev->phydev->speed == SPEED_1000) + ecntl |= (1 << 5); + else if (ndev->phydev->speed == SPEED_100) +- rcntl &= ~(1 << 9); ++ rcntl &= ~FEC_RCR_10BASET; + else +- rcntl |= (1 << 9); ++ rcntl |= FEC_RCR_10BASET; + } + } else { + #ifdef FEC_MIIGSK_ENR +@@ -1186,13 +1201,13 @@ fec_restart(struct net_device *ndev) + + if (fep->quirks & FEC_QUIRK_ENET_MAC) { + /* enable ENET endian swap */ +- ecntl |= (1 << 8); ++ ecntl |= FEC_ECR_BYTESWP; + /* enable ENET store and forward mode */ +- writel(1 << 8, fep->hwp + FEC_X_WMRK); ++ writel(FEC_TXWMRK_STRFWD, fep->hwp + FEC_X_WMRK); + } + + if (fep->bufdesc_ex) +- ecntl |= (1 << 4); ++ ecntl |= FEC_ECR_EN1588; + + if (fep->quirks & FEC_QUIRK_DELAYED_CLKS_SUPPORT && + fep->rgmii_txc_dly) +@@ -1291,7 +1306,7 @@ static void + fec_stop(struct net_device *ndev) + { + struct fec_enet_private *fep = netdev_priv(ndev); +- u32 rmii_mode = readl(fep->hwp + FEC_R_CNTRL) & (1 << 8); ++ u32 rmii_mode = readl(fep->hwp + FEC_R_CNTRL) & FEC_RCR_RMII; + u32 val; + + /* We cannot expect a graceful transmit stop without link !!! */ +@@ -1310,7 +1325,7 @@ fec_stop(struct net_device *ndev) + if (fep->quirks & FEC_QUIRK_HAS_MULTI_QUEUES) { + writel(0, fep->hwp + FEC_ECNTRL); + } else { +- writel(1, fep->hwp + FEC_ECNTRL); ++ writel(FEC_ECR_RESET, fep->hwp + FEC_ECNTRL); + udelay(10); + } + } else { +@@ -1324,11 +1339,16 @@ fec_stop(struct net_device *ndev) + /* We have to keep ENET enabled to have MII interrupt stay working */ + if (fep->quirks & FEC_QUIRK_ENET_MAC && + !(fep->wol_flag & FEC_WOL_FLAG_SLEEP_ON)) { +- writel(2, fep->hwp + FEC_ECNTRL); ++ writel(FEC_ECR_ETHEREN, fep->hwp + FEC_ECNTRL); + writel(rmii_mode, fep->hwp + FEC_R_CNTRL); + } +-} + ++ if (fep->bufdesc_ex) { ++ val = readl(fep->hwp + FEC_ECNTRL); ++ val |= FEC_ECR_EN1588; ++ writel(val, fep->hwp + FEC_ECNTRL); ++ } ++} + + static void + fec_timeout(struct net_device *ndev, unsigned int txqueue) +diff --git a/drivers/net/ethernet/google/gve/gve_tx.c b/drivers/net/ethernet/google/gve/gve_tx.c +index 9f6ffc4a54f0b..2ae891a62875c 100644 +--- a/drivers/net/ethernet/google/gve/gve_tx.c ++++ b/drivers/net/ethernet/google/gve/gve_tx.c +@@ -158,15 +158,16 @@ static int gve_clean_xdp_done(struct gve_priv *priv, struct gve_tx_ring *tx, + u32 to_do) + { + struct gve_tx_buffer_state *info; +- u32 clean_end = tx->done + to_do; + u64 pkts = 0, bytes = 0; + size_t space_freed = 0; + u32 xsk_complete = 0; + u32 idx; ++ int i; + +- for (; tx->done < clean_end; tx->done++) { ++ for (i = 0; i < to_do; i++) { + idx = tx->done & tx->mask; + info = &tx->info[idx]; ++ tx->done++; + + if (unlikely(!info->xdp.size)) + continue; +diff --git a/drivers/net/ethernet/google/gve/gve_tx_dqo.c b/drivers/net/ethernet/google/gve/gve_tx_dqo.c +index 5a44354bbdfdf..89b62b8d16e14 100644 +--- a/drivers/net/ethernet/google/gve/gve_tx_dqo.c ++++ b/drivers/net/ethernet/google/gve/gve_tx_dqo.c +@@ -812,22 +812,42 @@ static bool gve_can_send_tso(const struct sk_buff *skb) + const int header_len = skb_tcp_all_headers(skb); + const int gso_size = shinfo->gso_size; + int cur_seg_num_bufs; ++ int prev_frag_size; + int cur_seg_size; + int i; + + cur_seg_size = skb_headlen(skb) - header_len; ++ prev_frag_size = skb_headlen(skb); + cur_seg_num_bufs = cur_seg_size > 0; + + for (i = 0; i < shinfo->nr_frags; i++) { + if (cur_seg_size >= gso_size) { + cur_seg_size %= gso_size; + cur_seg_num_bufs = cur_seg_size > 0; ++ ++ if (prev_frag_size > GVE_TX_MAX_BUF_SIZE_DQO) { ++ int prev_frag_remain = prev_frag_size % ++ GVE_TX_MAX_BUF_SIZE_DQO; ++ ++ /* If the last descriptor of the previous frag ++ * is less than cur_seg_size, the segment will ++ * span two descriptors in the previous frag. ++ * Since max gso size (9728) is less than ++ * GVE_TX_MAX_BUF_SIZE_DQO, it is impossible ++ * for the segment to span more than two ++ * descriptors. ++ */ ++ if (prev_frag_remain && ++ cur_seg_size > prev_frag_remain) ++ cur_seg_num_bufs++; ++ } + } + + if (unlikely(++cur_seg_num_bufs > max_bufs_per_seg)) + return false; + +- cur_seg_size += skb_frag_size(&shinfo->frags[i]); ++ prev_frag_size = skb_frag_size(&shinfo->frags[i]); ++ cur_seg_size += prev_frag_size; + } + + return true; +diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c b/drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c +index 8c6e13f87b7d3..1839a37139dc1 100644 +--- a/drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c ++++ b/drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c +@@ -531,7 +531,7 @@ ice_parse_rx_flow_user_data(struct ethtool_rx_flow_spec *fsp, + * + * Returns the number of available flow director filters to this VSI + */ +-static int ice_fdir_num_avail_fltr(struct ice_hw *hw, struct ice_vsi *vsi) ++int ice_fdir_num_avail_fltr(struct ice_hw *hw, struct ice_vsi *vsi) + { + u16 vsi_num = ice_get_hw_vsi_num(hw, vsi->idx); + u16 num_guar; +diff --git a/drivers/net/ethernet/intel/ice/ice_fdir.h b/drivers/net/ethernet/intel/ice/ice_fdir.h +index 1b9b844906899..b384d2a4ab198 100644 +--- a/drivers/net/ethernet/intel/ice/ice_fdir.h ++++ b/drivers/net/ethernet/intel/ice/ice_fdir.h +@@ -202,6 +202,8 @@ struct ice_fdir_base_pkt { + const u8 *tun_pkt; + }; + ++struct ice_vsi; ++ + int ice_alloc_fd_res_cntr(struct ice_hw *hw, u16 *cntr_id); + int ice_free_fd_res_cntr(struct ice_hw *hw, u16 cntr_id); + int ice_alloc_fd_guar_item(struct ice_hw *hw, u16 *cntr_id, u16 num_fltr); +@@ -213,6 +215,7 @@ int + ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input, + u8 *pkt, bool frag, bool tun); + int ice_get_fdir_cnt_all(struct ice_hw *hw); ++int ice_fdir_num_avail_fltr(struct ice_hw *hw, struct ice_vsi *vsi); + bool ice_fdir_is_dup_fltr(struct ice_hw *hw, struct ice_fdir_fltr *input); + bool ice_fdir_has_frag(enum ice_fltr_ptype flow); + struct ice_fdir_fltr * +diff --git a/drivers/net/ethernet/intel/ice/ice_switch.c b/drivers/net/ethernet/intel/ice/ice_switch.c +index d2a2388d4fa0a..88ee2491312a5 100644 +--- a/drivers/net/ethernet/intel/ice/ice_switch.c ++++ b/drivers/net/ethernet/intel/ice/ice_switch.c +@@ -2271,10 +2271,10 @@ ice_get_recp_frm_fw(struct ice_hw *hw, struct ice_sw_recipe *recps, u8 rid, + /* Propagate some data to the recipe database */ + recps[idx].is_root = !!is_root; + recps[idx].priority = root_bufs.content.act_ctrl_fwd_priority; +- recps[idx].need_pass_l2 = root_bufs.content.act_ctrl & +- ICE_AQ_RECIPE_ACT_NEED_PASS_L2; +- recps[idx].allow_pass_l2 = root_bufs.content.act_ctrl & +- ICE_AQ_RECIPE_ACT_ALLOW_PASS_L2; ++ recps[idx].need_pass_l2 = !!(root_bufs.content.act_ctrl & ++ ICE_AQ_RECIPE_ACT_NEED_PASS_L2); ++ recps[idx].allow_pass_l2 = !!(root_bufs.content.act_ctrl & ++ ICE_AQ_RECIPE_ACT_ALLOW_PASS_L2); + bitmap_zero(recps[idx].res_idxs, ICE_MAX_FV_WORDS); + if (root_bufs.content.result_indx & ICE_AQ_RECIPE_RESULT_EN) { + recps[idx].chain_idx = root_bufs.content.result_indx & +diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c b/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c +index 6fdbd73804d16..974c71490d97c 100644 +--- a/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c ++++ b/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c +@@ -551,6 +551,8 @@ static void ice_vc_fdir_reset_cnt_all(struct ice_vf_fdir *fdir) + fdir->fdir_fltr_cnt[flow][0] = 0; + fdir->fdir_fltr_cnt[flow][1] = 0; + } ++ ++ fdir->fdir_fltr_cnt_total = 0; + } + + /** +@@ -1567,6 +1569,7 @@ ice_vc_add_fdir_fltr_post(struct ice_vf *vf, struct ice_vf_fdir_ctx *ctx, + resp->status = status; + resp->flow_id = conf->flow_id; + vf->fdir.fdir_fltr_cnt[conf->input.flow_type][is_tun]++; ++ vf->fdir.fdir_fltr_cnt_total++; + + ret = ice_vc_send_msg_to_vf(vf, ctx->v_opcode, v_ret, + (u8 *)resp, len); +@@ -1631,6 +1634,7 @@ ice_vc_del_fdir_fltr_post(struct ice_vf *vf, struct ice_vf_fdir_ctx *ctx, + resp->status = status; + ice_vc_fdir_remove_entry(vf, conf, conf->flow_id); + vf->fdir.fdir_fltr_cnt[conf->input.flow_type][is_tun]--; ++ vf->fdir.fdir_fltr_cnt_total--; + + ret = ice_vc_send_msg_to_vf(vf, ctx->v_opcode, v_ret, + (u8 *)resp, len); +@@ -1797,6 +1801,7 @@ int ice_vc_add_fdir_fltr(struct ice_vf *vf, u8 *msg) + struct virtchnl_fdir_add *stat = NULL; + struct virtchnl_fdir_fltr_conf *conf; + enum virtchnl_status_code v_ret; ++ struct ice_vsi *vf_vsi; + struct device *dev; + struct ice_pf *pf; + int is_tun = 0; +@@ -1805,6 +1810,17 @@ int ice_vc_add_fdir_fltr(struct ice_vf *vf, u8 *msg) + + pf = vf->pf; + dev = ice_pf_to_dev(pf); ++ vf_vsi = ice_get_vf_vsi(vf); ++ ++#define ICE_VF_MAX_FDIR_FILTERS 128 ++ if (!ice_fdir_num_avail_fltr(&pf->hw, vf_vsi) || ++ vf->fdir.fdir_fltr_cnt_total >= ICE_VF_MAX_FDIR_FILTERS) { ++ v_ret = VIRTCHNL_STATUS_ERR_PARAM; ++ dev_err(dev, "Max number of FDIR filters for VF %d is reached\n", ++ vf->vf_id); ++ goto err_exit; ++ } ++ + ret = ice_vc_fdir_param_check(vf, fltr->vsi_id); + if (ret) { + v_ret = VIRTCHNL_STATUS_ERR_PARAM; +diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.h b/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.h +index c5bcc8d7481ca..ac6dcab454b49 100644 +--- a/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.h ++++ b/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.h +@@ -29,6 +29,7 @@ struct ice_vf_fdir_ctx { + struct ice_vf_fdir { + u16 fdir_fltr_cnt[ICE_FLTR_PTYPE_MAX][ICE_FD_HW_SEG_MAX]; + int prof_entry_cnt[ICE_FLTR_PTYPE_MAX][ICE_FD_HW_SEG_MAX]; ++ u16 fdir_fltr_cnt_total; + struct ice_fd_hw_prof **fdir_prof; + + struct idr fdir_rule_idr; +diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_atcam.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_atcam.c +index 4b713832fdd55..f5c0a4214c4e5 100644 +--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_atcam.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_atcam.c +@@ -391,7 +391,8 @@ mlxsw_sp_acl_atcam_region_entry_insert(struct mlxsw_sp *mlxsw_sp, + if (err) + return err; + +- lkey_id = aregion->ops->lkey_id_get(aregion, aentry->enc_key, erp_id); ++ lkey_id = aregion->ops->lkey_id_get(aregion, aentry->ht_key.enc_key, ++ erp_id); + if (IS_ERR(lkey_id)) + return PTR_ERR(lkey_id); + aentry->lkey_id = lkey_id; +@@ -399,7 +400,7 @@ mlxsw_sp_acl_atcam_region_entry_insert(struct mlxsw_sp *mlxsw_sp, + kvdl_index = mlxsw_afa_block_first_kvdl_index(rulei->act_block); + mlxsw_reg_ptce3_pack(ptce3_pl, true, MLXSW_REG_PTCE3_OP_WRITE_WRITE, + priority, region->tcam_region_info, +- aentry->enc_key, erp_id, ++ aentry->ht_key.enc_key, erp_id, + aentry->delta_info.start, + aentry->delta_info.mask, + aentry->delta_info.value, +@@ -428,7 +429,7 @@ mlxsw_sp_acl_atcam_region_entry_remove(struct mlxsw_sp *mlxsw_sp, + + mlxsw_reg_ptce3_pack(ptce3_pl, false, MLXSW_REG_PTCE3_OP_WRITE_WRITE, 0, + region->tcam_region_info, +- aentry->enc_key, erp_id, ++ aentry->ht_key.enc_key, erp_id, + aentry->delta_info.start, + aentry->delta_info.mask, + aentry->delta_info.value, +@@ -457,7 +458,7 @@ mlxsw_sp_acl_atcam_region_entry_action_replace(struct mlxsw_sp *mlxsw_sp, + kvdl_index = mlxsw_afa_block_first_kvdl_index(rulei->act_block); + mlxsw_reg_ptce3_pack(ptce3_pl, true, MLXSW_REG_PTCE3_OP_WRITE_UPDATE, + priority, region->tcam_region_info, +- aentry->enc_key, erp_id, ++ aentry->ht_key.enc_key, erp_id, + aentry->delta_info.start, + aentry->delta_info.mask, + aentry->delta_info.value, +@@ -480,15 +481,13 @@ __mlxsw_sp_acl_atcam_entry_add(struct mlxsw_sp *mlxsw_sp, + int err; + + mlxsw_afk_encode(afk, region->key_info, &rulei->values, +- aentry->ht_key.full_enc_key, mask); ++ aentry->ht_key.enc_key, mask); + + erp_mask = mlxsw_sp_acl_erp_mask_get(aregion, mask, false); + if (IS_ERR(erp_mask)) + return PTR_ERR(erp_mask); + aentry->erp_mask = erp_mask; + aentry->ht_key.erp_id = mlxsw_sp_acl_erp_mask_erp_id(erp_mask); +- memcpy(aentry->enc_key, aentry->ht_key.full_enc_key, +- sizeof(aentry->enc_key)); + + /* Compute all needed delta information and clear the delta bits + * from the encrypted key. +@@ -497,9 +496,8 @@ __mlxsw_sp_acl_atcam_entry_add(struct mlxsw_sp *mlxsw_sp, + aentry->delta_info.start = mlxsw_sp_acl_erp_delta_start(delta); + aentry->delta_info.mask = mlxsw_sp_acl_erp_delta_mask(delta); + aentry->delta_info.value = +- mlxsw_sp_acl_erp_delta_value(delta, +- aentry->ht_key.full_enc_key); +- mlxsw_sp_acl_erp_delta_clear(delta, aentry->enc_key); ++ mlxsw_sp_acl_erp_delta_value(delta, aentry->ht_key.enc_key); ++ mlxsw_sp_acl_erp_delta_clear(delta, aentry->ht_key.enc_key); + + /* Add rule to the list of A-TCAM rules, assuming this + * rule is intended to A-TCAM. In case this rule does +diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_bloom_filter.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_bloom_filter.c +index 95f63fcf4ba1f..a54eedb69a3f5 100644 +--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_bloom_filter.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_bloom_filter.c +@@ -249,7 +249,7 @@ __mlxsw_sp_acl_bf_key_encode(struct mlxsw_sp_acl_atcam_region *aregion, + memcpy(chunk + pad_bytes, &erp_region_id, + sizeof(erp_region_id)); + memcpy(chunk + key_offset, +- &aentry->enc_key[chunk_key_offsets[chunk_index]], ++ &aentry->ht_key.enc_key[chunk_key_offsets[chunk_index]], + chunk_key_len); + chunk += chunk_len; + } +diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c +index d231f4d2888be..9eee229303cce 100644 +--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c +@@ -1217,18 +1217,6 @@ static bool mlxsw_sp_acl_erp_delta_check(void *priv, const void *parent_obj, + return err ? false : true; + } + +-static int mlxsw_sp_acl_erp_hints_obj_cmp(const void *obj1, const void *obj2) +-{ +- const struct mlxsw_sp_acl_erp_key *key1 = obj1; +- const struct mlxsw_sp_acl_erp_key *key2 = obj2; +- +- /* For hints purposes, two objects are considered equal +- * in case the masks are the same. Does not matter what +- * the "ctcam" value is. +- */ +- return memcmp(key1->mask, key2->mask, sizeof(key1->mask)); +-} +- + static void *mlxsw_sp_acl_erp_delta_create(void *priv, void *parent_obj, + void *obj) + { +@@ -1308,7 +1296,6 @@ static void mlxsw_sp_acl_erp_root_destroy(void *priv, void *root_priv) + static const struct objagg_ops mlxsw_sp_acl_erp_objagg_ops = { + .obj_size = sizeof(struct mlxsw_sp_acl_erp_key), + .delta_check = mlxsw_sp_acl_erp_delta_check, +- .hints_obj_cmp = mlxsw_sp_acl_erp_hints_obj_cmp, + .delta_create = mlxsw_sp_acl_erp_delta_create, + .delta_destroy = mlxsw_sp_acl_erp_delta_destroy, + .root_create = mlxsw_sp_acl_erp_root_create, +diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h +index 79a1d86065125..010204f73ea46 100644 +--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h ++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h +@@ -167,9 +167,9 @@ struct mlxsw_sp_acl_atcam_region { + }; + + struct mlxsw_sp_acl_atcam_entry_ht_key { +- char full_enc_key[MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN]; /* Encoded +- * key. +- */ ++ char enc_key[MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN]; /* Encoded key, minus ++ * delta bits. ++ */ + u8 erp_id; + }; + +@@ -181,9 +181,6 @@ struct mlxsw_sp_acl_atcam_entry { + struct rhash_head ht_node; + struct list_head list; /* Member in entries_list */ + struct mlxsw_sp_acl_atcam_entry_ht_key ht_key; +- char enc_key[MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN]; /* Encoded key, +- * minus delta bits. +- */ + struct { + u16 start; + u8 mask; +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +index 4ead0ddf43a7a..bf99495b51a9c 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +@@ -982,7 +982,7 @@ static void dwmac4_set_mac_loopback(void __iomem *ioaddr, bool enable) + } + + static void dwmac4_update_vlan_hash(struct mac_device_info *hw, u32 hash, +- __le16 perfect_match, bool is_double) ++ u16 perfect_match, bool is_double) + { + void __iomem *ioaddr = hw->pcsr; + u32 value; +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c +index 8bc317d2f7a61..052566f5b7f36 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c +@@ -615,7 +615,7 @@ static int dwxgmac2_rss_configure(struct mac_device_info *hw, + } + + static void dwxgmac2_update_vlan_hash(struct mac_device_info *hw, u32 hash, +- __le16 perfect_match, bool is_double) ++ u16 perfect_match, bool is_double) + { + void __iomem *ioaddr = hw->pcsr; + +diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h +index 68aa2d5ca6e56..47fb8e1646c2e 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/hwif.h ++++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h +@@ -386,7 +386,7 @@ struct stmmac_ops { + struct stmmac_rss *cfg, u32 num_rxq); + /* VLAN */ + void (*update_vlan_hash)(struct mac_device_info *hw, u32 hash, +- __le16 perfect_match, bool is_double); ++ u16 perfect_match, bool is_double); + void (*enable_vlan)(struct mac_device_info *hw, u32 type); + int (*add_hw_vlan_rx_fltr)(struct net_device *dev, + struct mac_device_info *hw, +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index 19c58ad8df345..d6167a7b19f21 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -6473,7 +6473,7 @@ static u32 stmmac_vid_crc32_le(__le16 vid_le) + static int stmmac_vlan_update(struct stmmac_priv *priv, bool is_double) + { + u32 crc, hash = 0; +- __le16 pmatch = 0; ++ u16 pmatch = 0; + int count = 0; + u16 vid = 0; + +@@ -6488,7 +6488,7 @@ static int stmmac_vlan_update(struct stmmac_priv *priv, bool is_double) + if (count > 2) /* VID = 0 always passes filter */ + return -EOPNOTSUPP; + +- pmatch = cpu_to_le16(vid); ++ pmatch = vid; + hash = 0; + } + +diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c +index 3111e16485921..9c2e71b9c0324 100644 +--- a/drivers/net/netconsole.c ++++ b/drivers/net/netconsole.c +@@ -770,6 +770,7 @@ static int netconsole_netdev_event(struct notifier_block *this, + /* rtnl_lock already held + * we might sleep in __netpoll_cleanup() + */ ++ nt->enabled = false; + spin_unlock_irqrestore(&target_list_lock, flags); + + __netpoll_cleanup(&nt->np); +@@ -777,7 +778,6 @@ static int netconsole_netdev_event(struct notifier_block *this, + spin_lock_irqsave(&target_list_lock, flags); + netdev_put(nt->np.dev, &nt->np.dev_tracker); + nt->np.dev = NULL; +- nt->enabled = false; + stopped = true; + netconsole_target_put(nt); + goto restart; +diff --git a/drivers/net/wireless/ath/ath11k/ce.c b/drivers/net/wireless/ath/ath11k/ce.c +index 289d47ae92afc..e66e86bdec20f 100644 +--- a/drivers/net/wireless/ath/ath11k/ce.c ++++ b/drivers/net/wireless/ath/ath11k/ce.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. +- * Copyright (c) 2021, Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include "dp_rx.h" +diff --git a/drivers/net/wireless/ath/ath11k/ce.h b/drivers/net/wireless/ath/ath11k/ce.h +index c0f6a0ba86df0..bcde2fcf02cf7 100644 +--- a/drivers/net/wireless/ath/ath11k/ce.h ++++ b/drivers/net/wireless/ath/ath11k/ce.h +@@ -1,6 +1,7 @@ + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ + /* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef ATH11K_CE_H +@@ -145,7 +146,7 @@ struct ath11k_ce_ring { + /* Host address space */ + void *base_addr_owner_space_unaligned; + /* CE address space */ +- u32 base_addr_ce_space_unaligned; ++ dma_addr_t base_addr_ce_space_unaligned; + + /* Actual start of descriptors. + * Aligned to descriptor-size boundary. +@@ -155,7 +156,7 @@ struct ath11k_ce_ring { + void *base_addr_owner_space; + + /* CE address space */ +- u32 base_addr_ce_space; ++ dma_addr_t base_addr_ce_space; + + /* HAL ring id */ + u32 hal_ring_id; +diff --git a/drivers/net/wireless/ath/ath11k/dbring.c b/drivers/net/wireless/ath/ath11k/dbring.c +index 5536e86423312..fbb6e8d8a4769 100644 +--- a/drivers/net/wireless/ath/ath11k/dbring.c ++++ b/drivers/net/wireless/ath/ath11k/dbring.c +@@ -1,6 +1,7 @@ + // SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include "core.h" +diff --git a/drivers/net/wireless/ath/ath11k/dbring.h b/drivers/net/wireless/ath/ath11k/dbring.h +index ef906c687b8cd..2f93b78a50df0 100644 +--- a/drivers/net/wireless/ath/ath11k/dbring.h ++++ b/drivers/net/wireless/ath/ath11k/dbring.h +@@ -1,6 +1,7 @@ + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ + /* + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef ATH11K_DBRING_H +diff --git a/drivers/net/wireless/ath/ath11k/debug.c b/drivers/net/wireless/ath/ath11k/debug.c +index f5c8a34c8802f..2b8544355fc1a 100644 +--- a/drivers/net/wireless/ath/ath11k/debug.c ++++ b/drivers/net/wireless/ath/ath11k/debug.c +@@ -1,6 +1,7 @@ + // SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include <linux/vmalloc.h> +diff --git a/drivers/net/wireless/ath/ath11k/debug.h b/drivers/net/wireless/ath/ath11k/debug.h +index 9c52804ef8ac3..cc8934d156977 100644 +--- a/drivers/net/wireless/ath/ath11k/debug.h ++++ b/drivers/net/wireless/ath/ath11k/debug.h +@@ -1,7 +1,7 @@ + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ + /* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. +- * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef _ATH11K_DEBUG_H_ +diff --git a/drivers/net/wireless/ath/ath11k/debugfs.c b/drivers/net/wireless/ath/ath11k/debugfs.c +index 5bb6fd17fdf6f..8cda73b78ebf4 100644 +--- a/drivers/net/wireless/ath/ath11k/debugfs.c ++++ b/drivers/net/wireless/ath/ath11k/debugfs.c +@@ -1,6 +1,7 @@ + // SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include <linux/vmalloc.h> +diff --git a/drivers/net/wireless/ath/ath11k/debugfs.h b/drivers/net/wireless/ath/ath11k/debugfs.h +index 3af0169f6cf21..44d15845f39a6 100644 +--- a/drivers/net/wireless/ath/ath11k/debugfs.h ++++ b/drivers/net/wireless/ath/ath11k/debugfs.h +@@ -1,6 +1,7 @@ + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ + /* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef _ATH11K_DEBUGFS_H_ +diff --git a/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.c b/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.c +index 0207fc4910f34..870e86a31bf89 100644 +--- a/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.c ++++ b/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. +- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include <linux/vmalloc.h> +diff --git a/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.h b/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.h +index 96219301f05bd..476689bbd4dad 100644 +--- a/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.h ++++ b/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.h +@@ -1,7 +1,7 @@ + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ + /* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. +- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef DEBUG_HTT_STATS_H +diff --git a/drivers/net/wireless/ath/ath11k/debugfs_sta.c b/drivers/net/wireless/ath/ath11k/debugfs_sta.c +index 9cc4ef28e7519..168879a380cb2 100644 +--- a/drivers/net/wireless/ath/ath11k/debugfs_sta.c ++++ b/drivers/net/wireless/ath/ath11k/debugfs_sta.c +@@ -1,6 +1,7 @@ + // SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include <linux/vmalloc.h> +diff --git a/drivers/net/wireless/ath/ath11k/debugfs_sta.h b/drivers/net/wireless/ath/ath11k/debugfs_sta.h +index e6c11b3a40aa9..ace877e19275e 100644 +--- a/drivers/net/wireless/ath/ath11k/debugfs_sta.h ++++ b/drivers/net/wireless/ath/ath11k/debugfs_sta.h +@@ -1,6 +1,7 @@ + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ + /* + * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef _ATH11K_DEBUGFS_STA_H_ +diff --git a/drivers/net/wireless/ath/ath11k/dp.c b/drivers/net/wireless/ath/ath11k/dp.c +index d070bcb3fe247..be0beb6bae8fb 100644 +--- a/drivers/net/wireless/ath/ath11k/dp.c ++++ b/drivers/net/wireless/ath/ath11k/dp.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. +- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include <crypto/hash.h> +diff --git a/drivers/net/wireless/ath/ath11k/dp.h b/drivers/net/wireless/ath/ath11k/dp.h +index 15815af453b2a..2f6dd69d3be27 100644 +--- a/drivers/net/wireless/ath/ath11k/dp.h ++++ b/drivers/net/wireless/ath/ath11k/dp.h +@@ -1,7 +1,7 @@ + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ + /* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. +- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef ATH11K_DP_H +diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c +index a993e74bbae83..b3499f966a9d6 100644 +--- a/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -1,6 +1,7 @@ + // SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include <linux/ieee80211.h> +@@ -1879,8 +1880,7 @@ static void ath11k_dp_rx_h_csum_offload(struct ath11k *ar, struct sk_buff *msdu) + CHECKSUM_NONE : CHECKSUM_UNNECESSARY; + } + +-static int ath11k_dp_rx_crypto_mic_len(struct ath11k *ar, +- enum hal_encrypt_type enctype) ++int ath11k_dp_rx_crypto_mic_len(struct ath11k *ar, enum hal_encrypt_type enctype) + { + switch (enctype) { + case HAL_ENCRYPT_TYPE_OPEN: +diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.h b/drivers/net/wireless/ath/ath11k/dp_rx.h +index 623da3bf9dc81..c322e30caa968 100644 +--- a/drivers/net/wireless/ath/ath11k/dp_rx.h ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.h +@@ -1,6 +1,7 @@ + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ + /* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. + */ + #ifndef ATH11K_DP_RX_H + #define ATH11K_DP_RX_H +@@ -95,4 +96,6 @@ int ath11k_peer_rx_frag_setup(struct ath11k *ar, const u8 *peer_mac, int vdev_id + int ath11k_dp_rx_pktlog_start(struct ath11k_base *ab); + int ath11k_dp_rx_pktlog_stop(struct ath11k_base *ab, bool stop_timer); + ++int ath11k_dp_rx_crypto_mic_len(struct ath11k *ar, enum hal_encrypt_type enctype); ++ + #endif /* ATH11K_DP_RX_H */ +diff --git a/drivers/net/wireless/ath/ath11k/dp_tx.c b/drivers/net/wireless/ath/ath11k/dp_tx.c +index 0dda76f7a4b50..7dd1ee5898017 100644 +--- a/drivers/net/wireless/ath/ath11k/dp_tx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_tx.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. +- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include "core.h" +diff --git a/drivers/net/wireless/ath/ath11k/dp_tx.h b/drivers/net/wireless/ath/ath11k/dp_tx.h +index 68a21ea9b9346..61be2265e09f0 100644 +--- a/drivers/net/wireless/ath/ath11k/dp_tx.h ++++ b/drivers/net/wireless/ath/ath11k/dp_tx.h +@@ -1,6 +1,7 @@ + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ + /* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2021, 2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef ATH11K_DP_TX_H +diff --git a/drivers/net/wireless/ath/ath11k/hal.c b/drivers/net/wireless/ath/ath11k/hal.c +index 0a99aa7ddbf45..ae5f7e401e21b 100644 +--- a/drivers/net/wireless/ath/ath11k/hal.c ++++ b/drivers/net/wireless/ath/ath11k/hal.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. +- * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + #include <linux/dma-mapping.h> + #include "hal_tx.h" +diff --git a/drivers/net/wireless/ath/ath11k/hal.h b/drivers/net/wireless/ath/ath11k/hal.h +index 1942d41d6de54..80447f488954a 100644 +--- a/drivers/net/wireless/ath/ath11k/hal.h ++++ b/drivers/net/wireless/ath/ath11k/hal.h +@@ -1,7 +1,7 @@ + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ + /* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. +- * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef ATH11K_HAL_H +diff --git a/drivers/net/wireless/ath/ath11k/hal_desc.h b/drivers/net/wireless/ath/ath11k/hal_desc.h +index d895ea878d9f0..b2fd180bd28e6 100644 +--- a/drivers/net/wireless/ath/ath11k/hal_desc.h ++++ b/drivers/net/wireless/ath/ath11k/hal_desc.h +@@ -1,6 +1,7 @@ + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ + /* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + #include "core.h" + +diff --git a/drivers/net/wireless/ath/ath11k/hal_rx.c b/drivers/net/wireless/ath/ath11k/hal_rx.c +index e5ed5efb139e1..363adac84a870 100644 +--- a/drivers/net/wireless/ath/ath11k/hal_rx.c ++++ b/drivers/net/wireless/ath/ath11k/hal_rx.c +@@ -1,6 +1,7 @@ + // SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include "debug.h" +diff --git a/drivers/net/wireless/ath/ath11k/hal_rx.h b/drivers/net/wireless/ath/ath11k/hal_rx.h +index 61bd8416c4fde..e05411005fc61 100644 +--- a/drivers/net/wireless/ath/ath11k/hal_rx.h ++++ b/drivers/net/wireless/ath/ath11k/hal_rx.h +@@ -1,6 +1,7 @@ + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ + /* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef ATH11K_HAL_RX_H +diff --git a/drivers/net/wireless/ath/ath11k/hif.h b/drivers/net/wireless/ath/ath11k/hif.h +index 659b80d2abd4d..e0952c0629293 100644 +--- a/drivers/net/wireless/ath/ath11k/hif.h ++++ b/drivers/net/wireless/ath/ath11k/hif.h +@@ -1,6 +1,7 @@ + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ + /* + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef _HIF_H_ +diff --git a/drivers/net/wireless/ath/ath11k/htc.c b/drivers/net/wireless/ath/ath11k/htc.c +index 2c2e425c86659..23054ab29a5ee 100644 +--- a/drivers/net/wireless/ath/ath11k/htc.c ++++ b/drivers/net/wireless/ath/ath11k/htc.c +@@ -1,6 +1,7 @@ + // SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + #include <linux/skbuff.h> + #include <linux/ctype.h> +diff --git a/drivers/net/wireless/ath/ath11k/htc.h b/drivers/net/wireless/ath/ath11k/htc.h +index f429b37cfdf75..e9b123a50b5d9 100644 +--- a/drivers/net/wireless/ath/ath11k/htc.h ++++ b/drivers/net/wireless/ath/ath11k/htc.h +@@ -1,6 +1,7 @@ + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ + /* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef ATH11K_HTC_H +diff --git a/drivers/net/wireless/ath/ath11k/hw.c b/drivers/net/wireless/ath/ath11k/hw.c +index d7b5ec6e69049..77d8f9237680b 100644 +--- a/drivers/net/wireless/ath/ath11k/hw.c ++++ b/drivers/net/wireless/ath/ath11k/hw.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. +- * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include <linux/types.h> +diff --git a/drivers/net/wireless/ath/ath11k/hw.h b/drivers/net/wireless/ath/ath11k/hw.h +index d51a99669dd6e..1b070747a5dbf 100644 +--- a/drivers/net/wireless/ath/ath11k/hw.h ++++ b/drivers/net/wireless/ath/ath11k/hw.h +@@ -1,7 +1,7 @@ + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ + /* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. +- * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef ATH11K_HW_H +diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c +index 445f59ad1fc08..33f2c189b4d86 100644 +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -4130,6 +4130,7 @@ static int ath11k_install_key(struct ath11k_vif *arvif, + + switch (key->cipher) { + case WLAN_CIPHER_SUITE_CCMP: ++ case WLAN_CIPHER_SUITE_CCMP_256: + arg.key_cipher = WMI_CIPHER_AES_CCM; + /* TODO: Re-check if flag is valid */ + key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV_MGMT; +@@ -4139,12 +4140,10 @@ static int ath11k_install_key(struct ath11k_vif *arvif, + arg.key_txmic_len = 8; + arg.key_rxmic_len = 8; + break; +- case WLAN_CIPHER_SUITE_CCMP_256: +- arg.key_cipher = WMI_CIPHER_AES_CCM; +- break; + case WLAN_CIPHER_SUITE_GCMP: + case WLAN_CIPHER_SUITE_GCMP_256: + arg.key_cipher = WMI_CIPHER_AES_GCM; ++ key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV_MGMT; + break; + default: + ath11k_warn(ar->ab, "cipher %d is not supported\n", key->cipher); +@@ -6023,7 +6022,10 @@ static int ath11k_mac_mgmt_tx_wmi(struct ath11k *ar, struct ath11k_vif *arvif, + { + struct ath11k_base *ab = ar->ab; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; ++ struct ath11k_skb_cb *skb_cb = ATH11K_SKB_CB(skb); + struct ieee80211_tx_info *info; ++ enum hal_encrypt_type enctype; ++ unsigned int mic_len; + dma_addr_t paddr; + int buf_id; + int ret; +@@ -6047,7 +6049,12 @@ static int ath11k_mac_mgmt_tx_wmi(struct ath11k *ar, struct ath11k_vif *arvif, + ieee80211_is_deauth(hdr->frame_control) || + ieee80211_is_disassoc(hdr->frame_control)) && + ieee80211_has_protected(hdr->frame_control)) { +- skb_put(skb, IEEE80211_CCMP_MIC_LEN); ++ if (!(skb_cb->flags & ATH11K_SKB_CIPHER_SET)) ++ ath11k_warn(ab, "WMI management tx frame without ATH11K_SKB_CIPHER_SET"); ++ ++ enctype = ath11k_dp_tx_get_encrypt_type(skb_cb->cipher); ++ mic_len = ath11k_dp_rx_crypto_mic_len(ar, enctype); ++ skb_put(skb, mic_len); + } + } + +diff --git a/drivers/net/wireless/ath/ath11k/mac.h b/drivers/net/wireless/ath/ath11k/mac.h +index 0231783ad754b..0dfdeed5177b8 100644 +--- a/drivers/net/wireless/ath/ath11k/mac.h ++++ b/drivers/net/wireless/ath/ath11k/mac.h +@@ -1,6 +1,7 @@ + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ + /* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef ATH11K_MAC_H +diff --git a/drivers/net/wireless/ath/ath11k/mhi.c b/drivers/net/wireless/ath/ath11k/mhi.c +index 76de891d6c0f1..48ae81efc2696 100644 +--- a/drivers/net/wireless/ath/ath11k/mhi.c ++++ b/drivers/net/wireless/ath/ath11k/mhi.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2020 The Linux Foundation. All rights reserved. +- * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include <linux/msi.h> +diff --git a/drivers/net/wireless/ath/ath11k/mhi.h b/drivers/net/wireless/ath/ath11k/mhi.h +index 8d9f852da6952..f81fba2644a4c 100644 +--- a/drivers/net/wireless/ath/ath11k/mhi.h ++++ b/drivers/net/wireless/ath/ath11k/mhi.h +@@ -1,6 +1,7 @@ + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ + /* + * Copyright (c) 2020 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + #ifndef _ATH11K_MHI_H + #define _ATH11K_MHI_H +diff --git a/drivers/net/wireless/ath/ath11k/pcic.c b/drivers/net/wireless/ath/ath11k/pcic.c +index 011cf5fb8023e..803ee9dd7967d 100644 +--- a/drivers/net/wireless/ath/ath11k/pcic.c ++++ b/drivers/net/wireless/ath/ath11k/pcic.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved. +- * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include "core.h" +diff --git a/drivers/net/wireless/ath/ath11k/peer.c b/drivers/net/wireless/ath/ath11k/peer.c +index 114aa3a9a3397..ca719eb3f7f82 100644 +--- a/drivers/net/wireless/ath/ath11k/peer.c ++++ b/drivers/net/wireless/ath/ath11k/peer.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. +- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include "core.h" +diff --git a/drivers/net/wireless/ath/ath11k/peer.h b/drivers/net/wireless/ath/ath11k/peer.h +index 9bd385d0a38c9..3ad2f3355b14f 100644 +--- a/drivers/net/wireless/ath/ath11k/peer.h ++++ b/drivers/net/wireless/ath/ath11k/peer.h +@@ -1,7 +1,7 @@ + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ + /* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. +- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef ATH11K_PEER_H +diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c +index 41fad03a3025c..a831d9474e9e0 100644 +--- a/drivers/net/wireless/ath/ath11k/qmi.c ++++ b/drivers/net/wireless/ath/ath11k/qmi.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. +- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include <linux/elf.h> +diff --git a/drivers/net/wireless/ath/ath11k/qmi.h b/drivers/net/wireless/ath/ath11k/qmi.h +index d477e2be814b1..7e06d100af575 100644 +--- a/drivers/net/wireless/ath/ath11k/qmi.h ++++ b/drivers/net/wireless/ath/ath11k/qmi.h +@@ -1,7 +1,7 @@ + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ + /* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. +- * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef ATH11K_QMI_H +diff --git a/drivers/net/wireless/ath/ath11k/reg.c b/drivers/net/wireless/ath/ath11k/reg.c +index 7f9fb968dac6d..c9e8bbc4896f3 100644 +--- a/drivers/net/wireless/ath/ath11k/reg.c ++++ b/drivers/net/wireless/ath/ath11k/reg.c +@@ -1,6 +1,7 @@ + // SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + #include <linux/rtnetlink.h> + +diff --git a/drivers/net/wireless/ath/ath11k/reg.h b/drivers/net/wireless/ath/ath11k/reg.h +index 2f284f26378d1..d873b9cf7fc4f 100644 +--- a/drivers/net/wireless/ath/ath11k/reg.h ++++ b/drivers/net/wireless/ath/ath11k/reg.h +@@ -1,6 +1,7 @@ + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ + /* + * Copyright (c) 2019 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef ATH11K_REG_H +diff --git a/drivers/net/wireless/ath/ath11k/rx_desc.h b/drivers/net/wireless/ath/ath11k/rx_desc.h +index 786d5f36f5e54..2da6da7272789 100644 +--- a/drivers/net/wireless/ath/ath11k/rx_desc.h ++++ b/drivers/net/wireless/ath/ath11k/rx_desc.h +@@ -1,6 +1,7 @@ + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ + /* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + #ifndef ATH11K_RX_DESC_H + #define ATH11K_RX_DESC_H +diff --git a/drivers/net/wireless/ath/ath11k/spectral.c b/drivers/net/wireless/ath/ath11k/spectral.c +index 705868198df4b..ae2abe8ae9920 100644 +--- a/drivers/net/wireless/ath/ath11k/spectral.c ++++ b/drivers/net/wireless/ath/ath11k/spectral.c +@@ -1,6 +1,7 @@ + // SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include <linux/relay.h> +diff --git a/drivers/net/wireless/ath/ath11k/spectral.h b/drivers/net/wireless/ath/ath11k/spectral.h +index 96bfa16e18e96..789cff7c64a72 100644 +--- a/drivers/net/wireless/ath/ath11k/spectral.h ++++ b/drivers/net/wireless/ath/ath11k/spectral.h +@@ -1,6 +1,7 @@ + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ + /* + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef ATH11K_SPECTRAL_H +diff --git a/drivers/net/wireless/ath/ath11k/thermal.c b/drivers/net/wireless/ath/ath11k/thermal.c +index 23ed01bd44f9a..d39acc03be5b1 100644 +--- a/drivers/net/wireless/ath/ath11k/thermal.c ++++ b/drivers/net/wireless/ath/ath11k/thermal.c +@@ -1,6 +1,7 @@ + // SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2020 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include <linux/device.h> +diff --git a/drivers/net/wireless/ath/ath11k/thermal.h b/drivers/net/wireless/ath/ath11k/thermal.h +index 3e39675ef7f57..40c1a9563e0c2 100644 +--- a/drivers/net/wireless/ath/ath11k/thermal.h ++++ b/drivers/net/wireless/ath/ath11k/thermal.h +@@ -1,6 +1,7 @@ + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ + /* + * Copyright (c) 2020 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef _ATH11K_THERMAL_ +diff --git a/drivers/net/wireless/ath/ath11k/trace.h b/drivers/net/wireless/ath/ath11k/trace.h +index 9535745fe026c..235ab8ea715fe 100644 +--- a/drivers/net/wireless/ath/ath11k/trace.h ++++ b/drivers/net/wireless/ath/ath11k/trace.h +@@ -1,6 +1,7 @@ + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ + /* + * Copyright (c) 2019 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #if !defined(_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ) +diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c +index 1c07f55c25e67..2cc13e60f422f 100644 +--- a/drivers/net/wireless/ath/ath11k/wmi.c ++++ b/drivers/net/wireless/ath/ath11k/wmi.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. +- * Copyright (c) 2021, 2023 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + #include <linux/skbuff.h> + #include <linux/ctype.h> +diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h +index 100bb816b5923..fa3b480b9d24f 100644 +--- a/drivers/net/wireless/ath/ath11k/wmi.h ++++ b/drivers/net/wireless/ath/ath11k/wmi.h +@@ -1,7 +1,7 @@ + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ + /* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. +- * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef ATH11K_WMI_H +diff --git a/drivers/net/wireless/ath/ath11k/wow.h b/drivers/net/wireless/ath/ath11k/wow.h +index 553ba850d910b..c85811e3f42b2 100644 +--- a/drivers/net/wireless/ath/ath11k/wow.h ++++ b/drivers/net/wireless/ath/ath11k/wow.h +@@ -1,6 +1,7 @@ + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ + /* + * Copyright (c) 2020 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef _WOW_H_ +diff --git a/drivers/net/wireless/ath/ath12k/ce.h b/drivers/net/wireless/ath/ath12k/ce.h +index 79af3b6159f1c..857bc5f9e946a 100644 +--- a/drivers/net/wireless/ath/ath12k/ce.h ++++ b/drivers/net/wireless/ath/ath12k/ce.h +@@ -1,7 +1,7 @@ + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ + /* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. +- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) 2021-2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef ATH12K_CE_H +@@ -119,7 +119,7 @@ struct ath12k_ce_ring { + /* Host address space */ + void *base_addr_owner_space_unaligned; + /* CE address space */ +- u32 base_addr_ce_space_unaligned; ++ dma_addr_t base_addr_ce_space_unaligned; + + /* Actual start of descriptors. + * Aligned to descriptor-size boundary. +@@ -129,7 +129,7 @@ struct ath12k_ce_ring { + void *base_addr_owner_space; + + /* CE address space */ +- u32 base_addr_ce_space; ++ dma_addr_t base_addr_ce_space; + + /* HAL ring id */ + u32 hal_ring_id; +diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c +index 6893466f61f04..907655c45a4b9 100644 +--- a/drivers/net/wireless/ath/ath12k/dp.c ++++ b/drivers/net/wireless/ath/ath12k/dp.c +@@ -127,7 +127,9 @@ static int ath12k_dp_srng_find_ring_in_mask(int ring_num, const u8 *grp_mask) + static int ath12k_dp_srng_calculate_msi_group(struct ath12k_base *ab, + enum hal_ring_type type, int ring_num) + { ++ const struct ath12k_hal_tcl_to_wbm_rbm_map *map; + const u8 *grp_mask; ++ int i; + + switch (type) { + case HAL_WBM2SW_RELEASE: +@@ -135,6 +137,14 @@ static int ath12k_dp_srng_calculate_msi_group(struct ath12k_base *ab, + grp_mask = &ab->hw_params->ring_mask->rx_wbm_rel[0]; + ring_num = 0; + } else { ++ map = ab->hw_params->hal_ops->tcl_to_wbm_rbm_map; ++ for (i = 0; i < ab->hw_params->max_tx_ring; i++) { ++ if (ring_num == map[i].wbm_ring_num) { ++ ring_num = i; ++ break; ++ } ++ } ++ + grp_mask = &ab->hw_params->ring_mask->tx[0]; + } + break; +@@ -876,11 +886,9 @@ int ath12k_dp_service_srng(struct ath12k_base *ab, + enum dp_monitor_mode monitor_mode; + u8 ring_mask; + +- while (i < ab->hw_params->max_tx_ring) { +- if (ab->hw_params->ring_mask->tx[grp_id] & +- BIT(ab->hw_params->hal_ops->tcl_to_wbm_rbm_map[i].wbm_ring_num)) +- ath12k_dp_tx_completion_handler(ab, i); +- i++; ++ if (ab->hw_params->ring_mask->tx[grp_id]) { ++ i = fls(ab->hw_params->ring_mask->tx[grp_id]) - 1; ++ ath12k_dp_tx_completion_handler(ab, i); + } + + if (ab->hw_params->ring_mask->rx_err[grp_id]) { +diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c +index dbcbe7e0cd2a7..2c17b1e7681a5 100644 +--- a/drivers/net/wireless/ath/ath12k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath12k/dp_rx.c +@@ -2376,8 +2376,10 @@ void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct hal_rx_desc *rx_desc, + channel_num = meta_data; + center_freq = meta_data >> 16; + +- if (center_freq >= 5935 && center_freq <= 7105) { ++ if (center_freq >= ATH12K_MIN_6G_FREQ && ++ center_freq <= ATH12K_MAX_6G_FREQ) { + rx_status->band = NL80211_BAND_6GHZ; ++ rx_status->freq = center_freq; + } else if (channel_num >= 1 && channel_num <= 14) { + rx_status->band = NL80211_BAND_2GHZ; + } else if (channel_num >= 36 && channel_num <= 173) { +@@ -2395,8 +2397,9 @@ void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct hal_rx_desc *rx_desc, + rx_desc, sizeof(*rx_desc)); + } + +- rx_status->freq = ieee80211_channel_to_frequency(channel_num, +- rx_status->band); ++ if (rx_status->band != NL80211_BAND_6GHZ) ++ rx_status->freq = ieee80211_channel_to_frequency(channel_num, ++ rx_status->band); + + ath12k_dp_rx_h_rate(ar, rx_desc, rx_status); + } +@@ -2985,7 +2988,7 @@ static int ath12k_dp_rx_h_defrag_reo_reinject(struct ath12k *ar, + struct hal_srng *srng; + dma_addr_t link_paddr, buf_paddr; + u32 desc_bank, msdu_info, msdu_ext_info, mpdu_info; +- u32 cookie, hal_rx_desc_sz, dest_ring_info0; ++ u32 cookie, hal_rx_desc_sz, dest_ring_info0, queue_addr_hi; + int ret; + struct ath12k_rx_desc_info *desc_info; + u8 dst_ind; +@@ -3021,7 +3024,7 @@ static int ath12k_dp_rx_h_defrag_reo_reinject(struct ath12k *ar, + + buf_paddr = dma_map_single(ab->dev, defrag_skb->data, + defrag_skb->len + skb_tailroom(defrag_skb), +- DMA_FROM_DEVICE); ++ DMA_TO_DEVICE); + if (dma_mapping_error(ab->dev, buf_paddr)) + return -ENOMEM; + +@@ -3077,13 +3080,11 @@ static int ath12k_dp_rx_h_defrag_reo_reinject(struct ath12k *ar, + reo_ent_ring->rx_mpdu_info.peer_meta_data = + reo_dest_ring->rx_mpdu_info.peer_meta_data; + +- /* Firmware expects physical address to be filled in queue_addr_lo in +- * the MLO scenario and in case of non MLO peer meta data needs to be +- * filled. +- * TODO: Need to handle for MLO scenario. +- */ +- reo_ent_ring->queue_addr_lo = reo_dest_ring->rx_mpdu_info.peer_meta_data; +- reo_ent_ring->info0 = le32_encode_bits(dst_ind, ++ reo_ent_ring->queue_addr_lo = cpu_to_le32(lower_32_bits(rx_tid->paddr)); ++ queue_addr_hi = upper_32_bits(rx_tid->paddr); ++ reo_ent_ring->info0 = le32_encode_bits(queue_addr_hi, ++ HAL_REO_ENTR_RING_INFO0_QUEUE_ADDR_HI) | ++ le32_encode_bits(dst_ind, + HAL_REO_ENTR_RING_INFO0_DEST_IND); + + reo_ent_ring->info1 = le32_encode_bits(rx_tid->cur_sn, +@@ -3107,7 +3108,7 @@ static int ath12k_dp_rx_h_defrag_reo_reinject(struct ath12k *ar, + spin_unlock_bh(&dp->rx_desc_lock); + err_unmap_dma: + dma_unmap_single(ab->dev, buf_paddr, defrag_skb->len + skb_tailroom(defrag_skb), +- DMA_FROM_DEVICE); ++ DMA_TO_DEVICE); + return ret; + } + +diff --git a/drivers/net/wireless/ath/ath12k/hw.c b/drivers/net/wireless/ath/ath12k/hw.c +index ba7720f760c55..dafd7c34d7465 100644 +--- a/drivers/net/wireless/ath/ath12k/hw.c ++++ b/drivers/net/wireless/ath/ath12k/hw.c +@@ -540,9 +540,6 @@ static const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_qcn9274 = { + }, + .rx_mon_dest = { + 0, 0, 0, +- ATH12K_RX_MON_RING_MASK_0, +- ATH12K_RX_MON_RING_MASK_1, +- ATH12K_RX_MON_RING_MASK_2, + }, + .rx = { + 0, 0, 0, 0, +@@ -568,16 +565,15 @@ static const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_qcn9274 = { + ATH12K_HOST2RXDMA_RING_MASK_0, + }, + .tx_mon_dest = { +- ATH12K_TX_MON_RING_MASK_0, +- ATH12K_TX_MON_RING_MASK_1, ++ 0, 0, 0, + }, + }; + + static const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_wcn7850 = { + .tx = { + ATH12K_TX_RING_MASK_0, ++ ATH12K_TX_RING_MASK_1, + ATH12K_TX_RING_MASK_2, +- ATH12K_TX_RING_MASK_4, + }, + .rx_mon_dest = { + }, +diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c +index cd89032fa25e1..21399ad233c02 100644 +--- a/drivers/net/wireless/ath/ath12k/wmi.c ++++ b/drivers/net/wireless/ath/ath12k/wmi.c +@@ -5772,8 +5772,10 @@ static void ath12k_mgmt_rx_event(struct ath12k_base *ab, struct sk_buff *skb) + if (rx_ev.status & WMI_RX_STATUS_ERR_MIC) + status->flag |= RX_FLAG_MMIC_ERROR; + +- if (rx_ev.chan_freq >= ATH12K_MIN_6G_FREQ) { ++ if (rx_ev.chan_freq >= ATH12K_MIN_6G_FREQ && ++ rx_ev.chan_freq <= ATH12K_MAX_6G_FREQ) { + status->band = NL80211_BAND_6GHZ; ++ status->freq = rx_ev.chan_freq; + } else if (rx_ev.channel >= 1 && rx_ev.channel <= 14) { + status->band = NL80211_BAND_2GHZ; + } else if (rx_ev.channel >= 36 && rx_ev.channel <= ATH12K_MAX_5G_CHAN) { +@@ -5794,8 +5796,10 @@ static void ath12k_mgmt_rx_event(struct ath12k_base *ab, struct sk_buff *skb) + + sband = &ar->mac.sbands[status->band]; + +- status->freq = ieee80211_channel_to_frequency(rx_ev.channel, +- status->band); ++ if (status->band != NL80211_BAND_6GHZ) ++ status->freq = ieee80211_channel_to_frequency(rx_ev.channel, ++ status->band); ++ + status->signal = rx_ev.snr + ATH12K_DEFAULT_NOISE_FLOOR; + status->rate_idx = ath12k_mac_bitrate_to_idx(sband, rx_ev.rate / 100); + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_lcn.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_lcn.c +index 7717eb85a1db6..47c0e8e429e54 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_lcn.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_lcn.c +@@ -2567,7 +2567,6 @@ wlc_lcnphy_tx_iqlo_cal(struct brcms_phy *pi, + + struct lcnphy_txgains cal_gains, temp_gains; + u16 hash; +- u8 band_idx; + int j; + u16 ncorr_override[5]; + u16 syst_coeffs[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +@@ -2599,6 +2598,9 @@ wlc_lcnphy_tx_iqlo_cal(struct brcms_phy *pi, + u16 *values_to_save; + struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; + ++ if (WARN_ON(CHSPEC_IS5G(pi->radio_chanspec))) ++ return; ++ + values_to_save = kmalloc_array(20, sizeof(u16), GFP_ATOMIC); + if (NULL == values_to_save) + return; +@@ -2662,20 +2664,18 @@ wlc_lcnphy_tx_iqlo_cal(struct brcms_phy *pi, + hash = (target_gains->gm_gain << 8) | + (target_gains->pga_gain << 4) | (target_gains->pad_gain); + +- band_idx = (CHSPEC_IS5G(pi->radio_chanspec) ? 1 : 0); +- + cal_gains = *target_gains; + memset(ncorr_override, 0, sizeof(ncorr_override)); +- for (j = 0; j < iqcal_gainparams_numgains_lcnphy[band_idx]; j++) { +- if (hash == tbl_iqcal_gainparams_lcnphy[band_idx][j][0]) { ++ for (j = 0; j < iqcal_gainparams_numgains_lcnphy[0]; j++) { ++ if (hash == tbl_iqcal_gainparams_lcnphy[0][j][0]) { + cal_gains.gm_gain = +- tbl_iqcal_gainparams_lcnphy[band_idx][j][1]; ++ tbl_iqcal_gainparams_lcnphy[0][j][1]; + cal_gains.pga_gain = +- tbl_iqcal_gainparams_lcnphy[band_idx][j][2]; ++ tbl_iqcal_gainparams_lcnphy[0][j][2]; + cal_gains.pad_gain = +- tbl_iqcal_gainparams_lcnphy[band_idx][j][3]; ++ tbl_iqcal_gainparams_lcnphy[0][j][3]; + memcpy(ncorr_override, +- &tbl_iqcal_gainparams_lcnphy[band_idx][j][3], ++ &tbl_iqcal_gainparams_lcnphy[0][j][3], + sizeof(ncorr_override)); + break; + } +diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c +index 4389cf3f889f9..6f01b7573b23c 100644 +--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c ++++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c +@@ -926,6 +926,8 @@ mwifiex_init_new_priv_params(struct mwifiex_private *priv, + return -EOPNOTSUPP; + } + ++ priv->bss_num = mwifiex_get_unused_bss_num(adapter, priv->bss_type); ++ + spin_lock_irqsave(&adapter->main_proc_lock, flags); + adapter->main_locked = false; + spin_unlock_irqrestore(&adapter->main_proc_lock, flags); +diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188f.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188f.c +index 1e1c8fa194cb8..0466b8be5df01 100644 +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188f.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188f.c +@@ -713,9 +713,14 @@ static void rtl8188fu_init_statistics(struct rtl8xxxu_priv *priv) + rtl8xxxu_write32(priv, REG_OFDM0_FA_RSTC, val32); + } + ++#define TX_POWER_INDEX_MAX 0x3F ++#define TX_POWER_INDEX_DEFAULT_CCK 0x22 ++#define TX_POWER_INDEX_DEFAULT_HT40 0x27 ++ + static int rtl8188fu_parse_efuse(struct rtl8xxxu_priv *priv) + { + struct rtl8188fu_efuse *efuse = &priv->efuse_wifi.efuse8188fu; ++ int i; + + if (efuse->rtl_id != cpu_to_le16(0x8129)) + return -EINVAL; +@@ -729,6 +734,16 @@ static int rtl8188fu_parse_efuse(struct rtl8xxxu_priv *priv) + efuse->tx_power_index_A.ht40_base, + sizeof(efuse->tx_power_index_A.ht40_base)); + ++ for (i = 0; i < ARRAY_SIZE(priv->cck_tx_power_index_A); i++) { ++ if (priv->cck_tx_power_index_A[i] > TX_POWER_INDEX_MAX) ++ priv->cck_tx_power_index_A[i] = TX_POWER_INDEX_DEFAULT_CCK; ++ } ++ ++ for (i = 0; i < ARRAY_SIZE(priv->ht40_1s_tx_power_index_A); i++) { ++ if (priv->ht40_1s_tx_power_index_A[i] > TX_POWER_INDEX_MAX) ++ priv->ht40_1s_tx_power_index_A[i] = TX_POWER_INDEX_DEFAULT_HT40; ++ } ++ + priv->ofdm_tx_power_diff[0].a = efuse->tx_power_index_A.ht20_ofdm_1s_diff.a; + priv->ht20_tx_power_diff[0].a = efuse->tx_power_index_A.ht20_ofdm_1s_diff.b; + +diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c +index a0188511099a1..efd0c2915a051 100644 +--- a/drivers/net/wireless/realtek/rtw88/usb.c ++++ b/drivers/net/wireless/realtek/rtw88/usb.c +@@ -273,6 +273,8 @@ static void rtw_usb_write_port_tx_complete(struct urb *urb) + info = IEEE80211_SKB_CB(skb); + tx_data = rtw_usb_get_tx_data(skb); + ++ 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/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c +index d162e64f60647..94fe921e9ff28 100644 +--- a/drivers/net/wireless/realtek/rtw89/debug.c ++++ b/drivers/net/wireless/realtek/rtw89/debug.c +@@ -3292,7 +3292,7 @@ static void rtw89_sta_info_get_iter(void *data, struct ieee80211_sta *sta) + case RX_ENC_HE: + seq_printf(m, "HE %dSS MCS-%d GI:%s", status->nss, status->rate_idx, + status->he_gi <= NL80211_RATE_INFO_HE_GI_3_2 ? +- he_gi_str[rate->he_gi] : "N/A"); ++ he_gi_str[status->he_gi] : "N/A"); + break; + } + seq_printf(m, " BW:%u", rtw89_rate_info_bw_to_mhz(status->bw)); +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c +index 259df67836a0e..a2fa1d339bc21 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c +@@ -20,7 +20,7 @@ + #define RTW8852B_RF_REL_VERSION 34 + #define RTW8852B_DPK_VER 0x0d + #define RTW8852B_DPK_RF_PATH 2 +-#define RTW8852B_DPK_KIP_REG_NUM 2 ++#define RTW8852B_DPK_KIP_REG_NUM 3 + + #define _TSSI_DE_MASK GENMASK(21, 12) + #define ADDC_T_AVG 100 +diff --git a/drivers/net/wireless/virtual/virt_wifi.c b/drivers/net/wireless/virtual/virt_wifi.c +index ba14d83353a4b..fb4d95a027fef 100644 +--- a/drivers/net/wireless/virtual/virt_wifi.c ++++ b/drivers/net/wireless/virtual/virt_wifi.c +@@ -136,6 +136,9 @@ static struct ieee80211_supported_band band_5ghz = { + /* Assigned at module init. Guaranteed locally-administered and unicast. */ + static u8 fake_router_bssid[ETH_ALEN] __ro_after_init = {}; + ++#define VIRT_WIFI_SSID "VirtWifi" ++#define VIRT_WIFI_SSID_LEN 8 ++ + static void virt_wifi_inform_bss(struct wiphy *wiphy) + { + u64 tsf = div_u64(ktime_get_boottime_ns(), 1000); +@@ -146,8 +149,8 @@ static void virt_wifi_inform_bss(struct wiphy *wiphy) + u8 ssid[8]; + } __packed ssid = { + .tag = WLAN_EID_SSID, +- .len = 8, +- .ssid = "VirtWifi", ++ .len = VIRT_WIFI_SSID_LEN, ++ .ssid = VIRT_WIFI_SSID, + }; + + informed_bss = cfg80211_inform_bss(wiphy, &channel_5ghz, +@@ -213,6 +216,8 @@ struct virt_wifi_netdev_priv { + struct net_device *upperdev; + u32 tx_packets; + u32 tx_failed; ++ u32 connect_requested_ssid_len; ++ u8 connect_requested_ssid[IEEE80211_MAX_SSID_LEN]; + u8 connect_requested_bss[ETH_ALEN]; + bool is_up; + bool is_connected; +@@ -229,6 +234,12 @@ static int virt_wifi_connect(struct wiphy *wiphy, struct net_device *netdev, + if (priv->being_deleted || !priv->is_up) + return -EBUSY; + ++ if (!sme->ssid) ++ return -EINVAL; ++ ++ priv->connect_requested_ssid_len = sme->ssid_len; ++ memcpy(priv->connect_requested_ssid, sme->ssid, sme->ssid_len); ++ + could_schedule = schedule_delayed_work(&priv->connect, HZ * 2); + if (!could_schedule) + return -EBUSY; +@@ -252,12 +263,15 @@ static void virt_wifi_connect_complete(struct work_struct *work) + container_of(work, struct virt_wifi_netdev_priv, connect.work); + u8 *requested_bss = priv->connect_requested_bss; + bool right_addr = ether_addr_equal(requested_bss, fake_router_bssid); ++ bool right_ssid = priv->connect_requested_ssid_len == VIRT_WIFI_SSID_LEN && ++ !memcmp(priv->connect_requested_ssid, VIRT_WIFI_SSID, ++ priv->connect_requested_ssid_len); + u16 status = WLAN_STATUS_SUCCESS; + + if (is_zero_ether_addr(requested_bss)) + requested_bss = NULL; + +- if (!priv->is_up || (requested_bss && !right_addr)) ++ if (!priv->is_up || (requested_bss && !right_addr) || !right_ssid) + status = WLAN_STATUS_UNSPECIFIED_FAILURE; + else + priv->is_connected = true; +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index 710fd4d862520..796c2a00fea4a 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -863,7 +863,8 @@ static blk_status_t nvme_prep_rq(struct nvme_dev *dev, struct request *req) + nvme_start_request(req); + return BLK_STS_OK; + out_unmap_data: +- nvme_unmap_data(dev, req); ++ if (blk_rq_nr_phys_segments(req)) ++ nvme_unmap_data(dev, req); + out_free_cmd: + nvme_cleanup_cmd(req); + return ret; +@@ -1275,7 +1276,7 @@ static void nvme_warn_reset(struct nvme_dev *dev, u32 csts) + dev_warn(dev->ctrl.device, + "Does your device have a faulty power saving mode enabled?\n"); + dev_warn(dev->ctrl.device, +- "Try \"nvme_core.default_ps_max_latency_us=0 pcie_aspm=off\" and report a bug\n"); ++ "Try \"nvme_core.default_ps_max_latency_us=0 pcie_aspm=off pcie_port_pm=off\" and report a bug\n"); + } + + static enum blk_eh_timer_return nvme_timeout(struct request *req) +diff --git a/drivers/nvme/target/auth.c b/drivers/nvme/target/auth.c +index e900525b78665..aacc05ec00c2b 100644 +--- a/drivers/nvme/target/auth.c ++++ b/drivers/nvme/target/auth.c +@@ -314,7 +314,7 @@ int nvmet_auth_host_hash(struct nvmet_req *req, u8 *response, + req->sq->dhchap_c1, + challenge, shash_len); + if (ret) +- goto out_free_response; ++ goto out_free_challenge; + } + + pr_debug("ctrl %d qid %d host response seq %u transaction %d\n", +@@ -325,7 +325,7 @@ int nvmet_auth_host_hash(struct nvmet_req *req, u8 *response, + GFP_KERNEL); + if (!shash) { + ret = -ENOMEM; +- goto out_free_response; ++ goto out_free_challenge; + } + shash->tfm = shash_tfm; + ret = crypto_shash_init(shash); +@@ -361,9 +361,10 @@ int nvmet_auth_host_hash(struct nvmet_req *req, u8 *response, + goto out; + ret = crypto_shash_final(shash, response); + out: ++ kfree(shash); ++out_free_challenge: + if (challenge != req->sq->dhchap_c1) + kfree(challenge); +- kfree(shash); + out_free_response: + kfree_sensitive(host_response); + out_free_tfm: +@@ -426,14 +427,14 @@ int nvmet_auth_ctrl_hash(struct nvmet_req *req, u8 *response, + req->sq->dhchap_c2, + challenge, shash_len); + if (ret) +- goto out_free_response; ++ goto out_free_challenge; + } + + shash = kzalloc(sizeof(*shash) + crypto_shash_descsize(shash_tfm), + GFP_KERNEL); + if (!shash) { + ret = -ENOMEM; +- goto out_free_response; ++ goto out_free_challenge; + } + shash->tfm = shash_tfm; + +@@ -470,9 +471,10 @@ int nvmet_auth_ctrl_hash(struct nvmet_req *req, u8 *response, + goto out; + ret = crypto_shash_final(shash, response); + out: ++ kfree(shash); ++out_free_challenge: + if (challenge != req->sq->dhchap_c2) + kfree(challenge); +- kfree(shash); + out_free_response: + kfree_sensitive(ctrl_response); + out_free_tfm: +diff --git a/drivers/nvmem/rockchip-otp.c b/drivers/nvmem/rockchip-otp.c +index cb9aa5428350a..7107d68a2f8c7 100644 +--- a/drivers/nvmem/rockchip-otp.c ++++ b/drivers/nvmem/rockchip-otp.c +@@ -255,6 +255,7 @@ static int rockchip_otp_read(void *context, unsigned int offset, + static struct nvmem_config otp_config = { + .name = "rockchip-otp", + .owner = THIS_MODULE, ++ .add_legacy_fixed_of_cells = true, + .read_only = true, + .stride = 1, + .word_size = 1, +diff --git a/drivers/opp/ti-opp-supply.c b/drivers/opp/ti-opp-supply.c +index 8f3f13fbbb25a..a8a696d2e03ab 100644 +--- a/drivers/opp/ti-opp-supply.c ++++ b/drivers/opp/ti-opp-supply.c +@@ -400,10 +400,12 @@ static int ti_opp_supply_probe(struct platform_device *pdev) + } + + ret = dev_pm_opp_set_config_regulators(cpu_dev, ti_opp_config_regulators); +- if (ret < 0) ++ if (ret < 0) { + _free_optimized_voltages(dev, &opp_data); ++ return ret; ++ } + +- return ret; ++ return 0; + } + + static struct platform_driver ti_opp_supply_driver = { +diff --git a/drivers/parport/procfs.c b/drivers/parport/procfs.c +index 4e5b972c3e263..c334ef6e3b3ff 100644 +--- a/drivers/parport/procfs.c ++++ b/drivers/parport/procfs.c +@@ -58,12 +58,12 @@ static int do_active_device(struct ctl_table *table, int write, + + for (dev = port->devices; dev ; dev = dev->next) { + if(dev == port->cad) { +- len += sprintf(buffer, "%s\n", dev->name); ++ len += snprintf(buffer, sizeof(buffer), "%s\n", dev->name); + } + } + + if(!len) { +- len += sprintf(buffer, "%s\n", "none"); ++ len += snprintf(buffer, sizeof(buffer), "%s\n", "none"); + } + + if (len > *lenp) +@@ -94,19 +94,19 @@ static int do_autoprobe(struct ctl_table *table, int write, + } + + if ((str = info->class_name) != NULL) +- len += sprintf (buffer + len, "CLASS:%s;\n", str); ++ len += snprintf (buffer + len, sizeof(buffer) - len, "CLASS:%s;\n", str); + + if ((str = info->model) != NULL) +- len += sprintf (buffer + len, "MODEL:%s;\n", str); ++ len += snprintf (buffer + len, sizeof(buffer) - len, "MODEL:%s;\n", str); + + if ((str = info->mfr) != NULL) +- len += sprintf (buffer + len, "MANUFACTURER:%s;\n", str); ++ len += snprintf (buffer + len, sizeof(buffer) - len, "MANUFACTURER:%s;\n", str); + + if ((str = info->description) != NULL) +- len += sprintf (buffer + len, "DESCRIPTION:%s;\n", str); ++ len += snprintf (buffer + len, sizeof(buffer) - len, "DESCRIPTION:%s;\n", str); + + if ((str = info->cmdset) != NULL) +- len += sprintf (buffer + len, "COMMAND SET:%s;\n", str); ++ len += snprintf (buffer + len, sizeof(buffer) - len, "COMMAND SET:%s;\n", str); + + if (len > *lenp) + len = *lenp; +@@ -124,7 +124,7 @@ static int do_hardware_base_addr(struct ctl_table *table, int write, + void *result, size_t *lenp, loff_t *ppos) + { + struct parport *port = (struct parport *)table->extra1; +- char buffer[20]; ++ char buffer[64]; + int len = 0; + + if (*ppos) { +@@ -135,7 +135,7 @@ static int do_hardware_base_addr(struct ctl_table *table, int write, + if (write) /* permissions prevent this anyway */ + return -EACCES; + +- len += sprintf (buffer, "%lu\t%lu\n", port->base, port->base_hi); ++ len += snprintf (buffer, sizeof(buffer), "%lu\t%lu\n", port->base, port->base_hi); + + if (len > *lenp) + len = *lenp; +@@ -162,7 +162,7 @@ static int do_hardware_irq(struct ctl_table *table, int write, + if (write) /* permissions prevent this anyway */ + return -EACCES; + +- len += sprintf (buffer, "%d\n", port->irq); ++ len += snprintf (buffer, sizeof(buffer), "%d\n", port->irq); + + if (len > *lenp) + len = *lenp; +@@ -189,7 +189,7 @@ static int do_hardware_dma(struct ctl_table *table, int write, + if (write) /* permissions prevent this anyway */ + return -EACCES; + +- len += sprintf (buffer, "%d\n", port->dma); ++ len += snprintf (buffer, sizeof(buffer), "%d\n", port->dma); + + if (len > *lenp) + len = *lenp; +@@ -220,7 +220,7 @@ static int do_hardware_modes(struct ctl_table *table, int write, + #define printmode(x) \ + do { \ + if (port->modes & PARPORT_MODE_##x) \ +- len += sprintf(buffer + len, "%s%s", f++ ? "," : "", #x); \ ++ len += snprintf(buffer + len, sizeof(buffer) - len, "%s%s", f++ ? "," : "", #x); \ + } while (0) + int f = 0; + printmode(PCSPP); +diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c +index cf3836561316d..54a3c7f29f78a 100644 +--- a/drivers/pci/controller/dwc/pci-keystone.c ++++ b/drivers/pci/controller/dwc/pci-keystone.c +@@ -246,8 +246,68 @@ static struct irq_chip ks_pcie_msi_irq_chip = { + .irq_unmask = ks_pcie_msi_unmask, + }; + ++/** ++ * ks_pcie_set_dbi_mode() - Set DBI mode to access overlaid BAR mask registers ++ * @ks_pcie: A pointer to the keystone_pcie structure which holds the KeyStone ++ * PCIe host controller driver information. ++ * ++ * Since modification of dbi_cs2 involves different clock domain, read the ++ * status back to ensure the transition is complete. ++ */ ++static void ks_pcie_set_dbi_mode(struct keystone_pcie *ks_pcie) ++{ ++ u32 val; ++ ++ val = ks_pcie_app_readl(ks_pcie, CMD_STATUS); ++ val |= DBI_CS2; ++ ks_pcie_app_writel(ks_pcie, CMD_STATUS, val); ++ ++ do { ++ val = ks_pcie_app_readl(ks_pcie, CMD_STATUS); ++ } while (!(val & DBI_CS2)); ++} ++ ++/** ++ * ks_pcie_clear_dbi_mode() - Disable DBI mode ++ * @ks_pcie: A pointer to the keystone_pcie structure which holds the KeyStone ++ * PCIe host controller driver information. ++ * ++ * Since modification of dbi_cs2 involves different clock domain, read the ++ * status back to ensure the transition is complete. ++ */ ++static void ks_pcie_clear_dbi_mode(struct keystone_pcie *ks_pcie) ++{ ++ u32 val; ++ ++ val = ks_pcie_app_readl(ks_pcie, CMD_STATUS); ++ val &= ~DBI_CS2; ++ ks_pcie_app_writel(ks_pcie, CMD_STATUS, val); ++ ++ do { ++ val = ks_pcie_app_readl(ks_pcie, CMD_STATUS); ++ } while (val & DBI_CS2); ++} ++ + static int ks_pcie_msi_host_init(struct dw_pcie_rp *pp) + { ++ struct dw_pcie *pci = to_dw_pcie_from_pp(pp); ++ struct keystone_pcie *ks_pcie = to_keystone_pcie(pci); ++ ++ /* Configure and set up BAR0 */ ++ ks_pcie_set_dbi_mode(ks_pcie); ++ ++ /* Enable BAR0 */ ++ dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_0, 1); ++ dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_0, SZ_4K - 1); ++ ++ ks_pcie_clear_dbi_mode(ks_pcie); ++ ++ /* ++ * For BAR0, just setting bus address for inbound writes (MSI) should ++ * be sufficient. Use physical address to avoid any conflicts. ++ */ ++ dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_0, ks_pcie->app.start); ++ + pp->msi_irq_chip = &ks_pcie_msi_irq_chip; + return dw_pcie_allocate_domains(pp); + } +@@ -342,59 +402,22 @@ static const struct irq_domain_ops ks_pcie_legacy_irq_domain_ops = { + .xlate = irq_domain_xlate_onetwocell, + }; + +-/** +- * ks_pcie_set_dbi_mode() - Set DBI mode to access overlaid BAR mask registers +- * @ks_pcie: A pointer to the keystone_pcie structure which holds the KeyStone +- * PCIe host controller driver information. +- * +- * Since modification of dbi_cs2 involves different clock domain, read the +- * status back to ensure the transition is complete. +- */ +-static void ks_pcie_set_dbi_mode(struct keystone_pcie *ks_pcie) +-{ +- u32 val; +- +- val = ks_pcie_app_readl(ks_pcie, CMD_STATUS); +- val |= DBI_CS2; +- ks_pcie_app_writel(ks_pcie, CMD_STATUS, val); +- +- do { +- val = ks_pcie_app_readl(ks_pcie, CMD_STATUS); +- } while (!(val & DBI_CS2)); +-} +- +-/** +- * ks_pcie_clear_dbi_mode() - Disable DBI mode +- * @ks_pcie: A pointer to the keystone_pcie structure which holds the KeyStone +- * PCIe host controller driver information. +- * +- * Since modification of dbi_cs2 involves different clock domain, read the +- * status back to ensure the transition is complete. +- */ +-static void ks_pcie_clear_dbi_mode(struct keystone_pcie *ks_pcie) +-{ +- u32 val; +- +- val = ks_pcie_app_readl(ks_pcie, CMD_STATUS); +- val &= ~DBI_CS2; +- ks_pcie_app_writel(ks_pcie, CMD_STATUS, val); +- +- do { +- val = ks_pcie_app_readl(ks_pcie, CMD_STATUS); +- } while (val & DBI_CS2); +-} +- +-static void ks_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie) ++static int ks_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie) + { + u32 val; + u32 num_viewport = ks_pcie->num_viewport; + struct dw_pcie *pci = ks_pcie->pci; + struct dw_pcie_rp *pp = &pci->pp; +- u64 start, end; ++ struct resource_entry *entry; + struct resource *mem; ++ u64 start, end; + int i; + +- mem = resource_list_first_type(&pp->bridge->windows, IORESOURCE_MEM)->res; ++ entry = resource_list_first_type(&pp->bridge->windows, IORESOURCE_MEM); ++ if (!entry) ++ return -ENODEV; ++ ++ mem = entry->res; + start = mem->start; + end = mem->end; + +@@ -405,7 +428,7 @@ static void ks_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie) + ks_pcie_clear_dbi_mode(ks_pcie); + + if (ks_pcie->is_am6) +- return; ++ return 0; + + val = ilog2(OB_WIN_SIZE); + ks_pcie_app_writel(ks_pcie, OB_SIZE, val); +@@ -422,6 +445,8 @@ static void ks_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie) + val = ks_pcie_app_readl(ks_pcie, CMD_STATUS); + val |= OB_XLAT_EN_VAL; + ks_pcie_app_writel(ks_pcie, CMD_STATUS, val); ++ ++ return 0; + } + + static void __iomem *ks_pcie_other_map_bus(struct pci_bus *bus, +@@ -447,44 +472,10 @@ static struct pci_ops ks_child_pcie_ops = { + .write = pci_generic_config_write, + }; + +-/** +- * ks_pcie_v3_65_add_bus() - keystone add_bus post initialization +- * @bus: A pointer to the PCI bus structure. +- * +- * This sets BAR0 to enable inbound access for MSI_IRQ register +- */ +-static int ks_pcie_v3_65_add_bus(struct pci_bus *bus) +-{ +- struct dw_pcie_rp *pp = bus->sysdata; +- struct dw_pcie *pci = to_dw_pcie_from_pp(pp); +- struct keystone_pcie *ks_pcie = to_keystone_pcie(pci); +- +- if (!pci_is_root_bus(bus)) +- return 0; +- +- /* Configure and set up BAR0 */ +- ks_pcie_set_dbi_mode(ks_pcie); +- +- /* Enable BAR0 */ +- dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_0, 1); +- dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_0, SZ_4K - 1); +- +- ks_pcie_clear_dbi_mode(ks_pcie); +- +- /* +- * For BAR0, just setting bus address for inbound writes (MSI) should +- * be sufficient. Use physical address to avoid any conflicts. +- */ +- dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_0, ks_pcie->app.start); +- +- return 0; +-} +- + static struct pci_ops ks_pcie_ops = { + .map_bus = dw_pcie_own_conf_map_bus, + .read = pci_generic_config_read, + .write = pci_generic_config_write, +- .add_bus = ks_pcie_v3_65_add_bus, + }; + + /** +@@ -817,7 +808,10 @@ static int __init ks_pcie_host_init(struct dw_pcie_rp *pp) + return ret; + + ks_pcie_stop_link(pci); +- ks_pcie_setup_rc_app_regs(ks_pcie); ++ ret = ks_pcie_setup_rc_app_regs(ks_pcie); ++ if (ret) ++ return ret; ++ + writew(PCI_IO_RANGE_TYPE_32 | (PCI_IO_RANGE_TYPE_32 << 8), + pci->dbi_base + PCI_IO_BASE); + +diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c +index ad6516a3ae6ea..f2e5feba55267 100644 +--- a/drivers/pci/controller/dwc/pcie-designware-ep.c ++++ b/drivers/pci/controller/dwc/pcie-designware-ep.c +@@ -163,7 +163,7 @@ static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, u8 func_no, int type, + if (!ep->bar_to_atu[bar]) + free_win = find_first_zero_bit(ep->ib_window_map, pci->num_ib_windows); + else +- free_win = ep->bar_to_atu[bar]; ++ free_win = ep->bar_to_atu[bar] - 1; + + if (free_win >= pci->num_ib_windows) { + dev_err(pci->dev, "No free inbound window\n"); +@@ -177,7 +177,11 @@ static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, u8 func_no, int type, + return ret; + } + +- ep->bar_to_atu[bar] = free_win; ++ /* ++ * Always increment free_win before assignment, since value 0 is used to identify ++ * unallocated mapping. ++ */ ++ ep->bar_to_atu[bar] = free_win + 1; + set_bit(free_win, ep->ib_window_map); + + return 0; +@@ -214,7 +218,10 @@ static void dw_pcie_ep_clear_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no, + struct dw_pcie_ep *ep = epc_get_drvdata(epc); + struct dw_pcie *pci = to_dw_pcie_from_ep(ep); + enum pci_barno bar = epf_bar->barno; +- u32 atu_index = ep->bar_to_atu[bar]; ++ u32 atu_index = ep->bar_to_atu[bar] - 1; ++ ++ if (!ep->bar_to_atu[bar]) ++ return; + + __dw_pcie_ep_reset_bar(pci, func_no, bar, epf_bar->flags); + +diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c +index 2fe42c70097fd..9b1256da096cb 100644 +--- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c ++++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c +@@ -240,7 +240,7 @@ static int rockchip_pcie_resource_get(struct platform_device *pdev, + return PTR_ERR(rockchip->apb_base); + + rockchip->rst_gpio = devm_gpiod_get_optional(&pdev->dev, "reset", +- GPIOD_OUT_HIGH); ++ GPIOD_OUT_LOW); + if (IS_ERR(rockchip->rst_gpio)) + return PTR_ERR(rockchip->rst_gpio); + +diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c +index 9b62ee6992f0e..66e080c99d5df 100644 +--- a/drivers/pci/controller/dwc/pcie-qcom-ep.c ++++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c +@@ -519,12 +519,6 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci) + static void qcom_pcie_perst_assert(struct dw_pcie *pci) + { + struct qcom_pcie_ep *pcie_ep = to_pcie_ep(pci); +- struct device *dev = pci->dev; +- +- if (pcie_ep->link_status == QCOM_PCIE_EP_LINK_DISABLED) { +- dev_dbg(dev, "Link is already disabled\n"); +- return; +- } + + qcom_pcie_disable_resources(pcie_ep); + pcie_ep->link_status = QCOM_PCIE_EP_LINK_DISABLED; +diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c +index 5ab1a035c4969..4c34909810d8e 100644 +--- a/drivers/pci/controller/pci-hyperv.c ++++ b/drivers/pci/controller/pci-hyperv.c +@@ -1137,8 +1137,8 @@ static void _hv_pcifront_read_config(struct hv_pci_dev *hpdev, int where, + PCI_CAPABILITY_LIST) { + /* ROM BARs are unimplemented */ + *val = 0; +- } else if (where >= PCI_INTERRUPT_LINE && where + size <= +- PCI_INTERRUPT_PIN) { ++ } else if ((where >= PCI_INTERRUPT_LINE && where + size <= PCI_INTERRUPT_PIN) || ++ (where >= PCI_INTERRUPT_PIN && where + size <= PCI_MIN_GNT)) { + /* + * Interrupt Line and Interrupt PIN are hard-wired to zero + * because this front-end only supports message-signaled +diff --git a/drivers/pci/controller/pci-loongson.c b/drivers/pci/controller/pci-loongson.c +index 8b34ccff073a9..bc630ab8a2831 100644 +--- a/drivers/pci/controller/pci-loongson.c ++++ b/drivers/pci/controller/pci-loongson.c +@@ -163,6 +163,19 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, + DEV_LS7A_HDMI, loongson_pci_pin_quirk); + ++static void loongson_pci_msi_quirk(struct pci_dev *dev) ++{ ++ u16 val, class = dev->class >> 8; ++ ++ if (class != PCI_CLASS_BRIDGE_HOST) ++ return; ++ ++ pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &val); ++ val |= PCI_MSI_FLAGS_ENABLE; ++ pci_write_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, val); ++} ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, DEV_LS7A_PCIE_PORT5, loongson_pci_msi_quirk); ++ + static struct loongson_pci *pci_bus_to_loongson_pci(struct pci_bus *bus) + { + struct pci_config_window *cfg; +diff --git a/drivers/pci/controller/pcie-rcar-host.c b/drivers/pci/controller/pcie-rcar-host.c +index 88975e40ee2fb..704ab5d723a95 100644 +--- a/drivers/pci/controller/pcie-rcar-host.c ++++ b/drivers/pci/controller/pcie-rcar-host.c +@@ -77,7 +77,11 @@ static int rcar_pcie_wakeup(struct device *pcie_dev, void __iomem *pcie_base) + writel(L1IATN, pcie_base + PMCTLR); + ret = readl_poll_timeout_atomic(pcie_base + PMSR, val, + val & L1FAEG, 10, 1000); +- WARN(ret, "Timeout waiting for L1 link state, ret=%d\n", ret); ++ if (ret) { ++ dev_warn_ratelimited(pcie_dev, ++ "Timeout waiting for L1 link state, ret=%d\n", ++ ret); ++ } + writel(L1FAEG | PMEL1RX, pcie_base + PMSR); + } + +diff --git a/drivers/pci/controller/pcie-rockchip.c b/drivers/pci/controller/pcie-rockchip.c +index 0ef2e622d36e1..c07d7129f1c7c 100644 +--- a/drivers/pci/controller/pcie-rockchip.c ++++ b/drivers/pci/controller/pcie-rockchip.c +@@ -121,7 +121,7 @@ int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip) + + if (rockchip->is_rc) { + rockchip->ep_gpio = devm_gpiod_get_optional(dev, "ep", +- GPIOD_OUT_HIGH); ++ GPIOD_OUT_LOW); + if (IS_ERR(rockchip->ep_gpio)) + return dev_err_probe(dev, PTR_ERR(rockchip->ep_gpio), + "failed to get ep GPIO\n"); +diff --git a/drivers/pci/endpoint/functions/pci-epf-vntb.c b/drivers/pci/endpoint/functions/pci-epf-vntb.c +index 2b7bc5a731dd6..3368f483f818d 100644 +--- a/drivers/pci/endpoint/functions/pci-epf-vntb.c ++++ b/drivers/pci/endpoint/functions/pci-epf-vntb.c +@@ -810,8 +810,9 @@ static int epf_ntb_epc_init(struct epf_ntb *ntb) + */ + static void epf_ntb_epc_cleanup(struct epf_ntb *ntb) + { +- epf_ntb_db_bar_clear(ntb); + epf_ntb_mw_bar_clear(ntb, ntb->num_mws); ++ epf_ntb_db_bar_clear(ntb); ++ epf_ntb_config_sspad_bar_clear(ntb); + } + + #define EPF_NTB_R(_name) \ +@@ -1029,8 +1030,10 @@ static int vpci_scan_bus(void *sysdata) + struct epf_ntb *ndev = sysdata; + + vpci_bus = pci_scan_bus(ndev->vbus_number, &vpci_ops, sysdata); +- if (vpci_bus) +- pr_err("create pci bus\n"); ++ if (!vpci_bus) { ++ pr_err("create pci bus failed\n"); ++ return -EINVAL; ++ } + + pci_bus_add_devices(vpci_bus); + +@@ -1349,13 +1352,19 @@ static int epf_ntb_bind(struct pci_epf *epf) + ret = pci_register_driver(&vntb_pci_driver); + if (ret) { + dev_err(dev, "failure register vntb pci driver\n"); +- goto err_bar_alloc; ++ goto err_epc_cleanup; + } + +- vpci_scan_bus(ntb); ++ ret = vpci_scan_bus(ntb); ++ if (ret) ++ goto err_unregister; + + return 0; + ++err_unregister: ++ pci_unregister_driver(&vntb_pci_driver); ++err_epc_cleanup: ++ epf_ntb_epc_cleanup(ntb); + err_bar_alloc: + epf_ntb_config_spad_bar_free(ntb); + +diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c +index cd759e19cc18e..a0f961a380fa9 100644 +--- a/drivers/pci/pci.c ++++ b/drivers/pci/pci.c +@@ -5123,7 +5123,7 @@ static int pci_bus_max_d3cold_delay(const struct pci_bus *bus) + */ + int pci_bridge_wait_for_secondary_bus(struct pci_dev *dev, char *reset_type) + { +- struct pci_dev *child; ++ struct pci_dev *child __free(pci_dev_put) = NULL; + int delay; + + if (pci_dev_is_disconnected(dev)) +@@ -5152,8 +5152,8 @@ int pci_bridge_wait_for_secondary_bus(struct pci_dev *dev, char *reset_type) + return 0; + } + +- child = list_first_entry(&dev->subordinate->devices, struct pci_dev, +- bus_list); ++ child = pci_dev_get(list_first_entry(&dev->subordinate->devices, ++ struct pci_dev, bus_list)); + up_read(&pci_bus_sem); + + /* +diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c +index dae490f256417..5a143ad5fca24 100644 +--- a/drivers/pci/setup-bus.c ++++ b/drivers/pci/setup-bus.c +@@ -820,11 +820,9 @@ static resource_size_t calculate_memsize(resource_size_t size, + size = min_size; + if (old_size == 1) + old_size = 0; +- if (size < old_size) +- size = old_size; + +- size = ALIGN(max(size, add_size) + children_add_size, align); +- return size; ++ size = max(size, add_size) + children_add_size; ++ return ALIGN(max(size, old_size), align); + } + + resource_size_t __weak pcibios_window_alignment(struct pci_bus *bus, +diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c +index a75c96385c57a..a23d7f9b7d10f 100644 +--- a/drivers/phy/cadence/phy-cadence-torrent.c ++++ b/drivers/phy/cadence/phy-cadence-torrent.c +@@ -1154,6 +1154,9 @@ static int cdns_torrent_dp_set_power_state(struct cdns_torrent_phy *cdns_phy, + ret = regmap_read_poll_timeout(regmap, PHY_PMA_XCVR_POWER_STATE_ACK, + read_val, (read_val & mask) == value, 0, + POLL_TIMEOUT_US); ++ if (ret) ++ return ret; ++ + cdns_torrent_dp_write(regmap, PHY_PMA_XCVR_POWER_STATE_REQ, 0x00000000); + ndelay(100); + +diff --git a/drivers/phy/xilinx/phy-zynqmp.c b/drivers/phy/xilinx/phy-zynqmp.c +index 2559c6594cea2..0cb5088e460b5 100644 +--- a/drivers/phy/xilinx/phy-zynqmp.c ++++ b/drivers/phy/xilinx/phy-zynqmp.c +@@ -80,7 +80,8 @@ + + /* Reference clock selection parameters */ + #define L0_Ln_REF_CLK_SEL(n) (0x2860 + (n) * 4) +-#define L0_REF_CLK_SEL_MASK 0x8f ++#define L0_REF_CLK_LCL_SEL BIT(7) ++#define L0_REF_CLK_SEL_MASK 0x9f + + /* Calibration digital logic parameters */ + #define L3_TM_CALIB_DIG19 0xec4c +@@ -349,11 +350,12 @@ static void xpsgtr_configure_pll(struct xpsgtr_phy *gtr_phy) + PLL_FREQ_MASK, ssc->pll_ref_clk); + + /* Enable lane clock sharing, if required */ +- if (gtr_phy->refclk != gtr_phy->lane) { +- /* Lane3 Ref Clock Selection Register */ ++ if (gtr_phy->refclk == gtr_phy->lane) ++ xpsgtr_clr_set(gtr_phy->dev, L0_Ln_REF_CLK_SEL(gtr_phy->lane), ++ L0_REF_CLK_SEL_MASK, L0_REF_CLK_LCL_SEL); ++ else + xpsgtr_clr_set(gtr_phy->dev, L0_Ln_REF_CLK_SEL(gtr_phy->lane), + L0_REF_CLK_SEL_MASK, 1 << gtr_phy->refclk); +- } + + /* SSC step size [7:0] */ + xpsgtr_clr_set_phy(gtr_phy, L0_PLL_SS_STEP_SIZE_0_LSB, +@@ -573,7 +575,7 @@ static int xpsgtr_phy_init(struct phy *phy) + mutex_lock(>r_dev->gtr_mutex); + + /* Configure and enable the clock when peripheral phy_init call */ +- if (clk_prepare_enable(gtr_dev->clk[gtr_phy->lane])) ++ if (clk_prepare_enable(gtr_dev->clk[gtr_phy->refclk])) + goto out; + + /* Skip initialization if not required. */ +@@ -625,7 +627,7 @@ static int xpsgtr_phy_exit(struct phy *phy) + gtr_phy->skip_phy_init = false; + + /* Ensure that disable clock only, which configure for lane */ +- clk_disable_unprepare(gtr_dev->clk[gtr_phy->lane]); ++ clk_disable_unprepare(gtr_dev->clk[gtr_phy->refclk]); + + return 0; + } +diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c +index e19ee66e027bb..88ee086e13763 100644 +--- a/drivers/pinctrl/core.c ++++ b/drivers/pinctrl/core.c +@@ -2072,6 +2072,14 @@ pinctrl_init_controller(struct pinctrl_desc *pctldesc, struct device *dev, + return ERR_PTR(ret); + } + ++static void pinctrl_uninit_controller(struct pinctrl_dev *pctldev, struct pinctrl_desc *pctldesc) ++{ ++ pinctrl_free_pindescs(pctldev, pctldesc->pins, ++ pctldesc->npins); ++ mutex_destroy(&pctldev->mutex); ++ kfree(pctldev); ++} ++ + static int pinctrl_claim_hogs(struct pinctrl_dev *pctldev) + { + pctldev->p = create_pinctrl(pctldev->dev, pctldev); +@@ -2152,8 +2160,10 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, + return pctldev; + + error = pinctrl_enable(pctldev); +- if (error) ++ if (error) { ++ pinctrl_uninit_controller(pctldev, pctldesc); + return ERR_PTR(error); ++ } + + return pctldev; + } +diff --git a/drivers/pinctrl/freescale/pinctrl-mxs.c b/drivers/pinctrl/freescale/pinctrl-mxs.c +index cf3f4d2e0c168..a53287aaa653d 100644 +--- a/drivers/pinctrl/freescale/pinctrl-mxs.c ++++ b/drivers/pinctrl/freescale/pinctrl-mxs.c +@@ -408,8 +408,8 @@ static int mxs_pinctrl_probe_dt(struct platform_device *pdev, + int ret; + u32 val; + +- child = of_get_next_child(np, NULL); +- if (!child) { ++ val = of_get_child_count(np); ++ if (val == 0) { + dev_err(&pdev->dev, "no group is defined\n"); + return -ENOENT; + } +diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c +index caf8d0a98c327..b02eaba010d10 100644 +--- a/drivers/pinctrl/pinctrl-rockchip.c ++++ b/drivers/pinctrl/pinctrl-rockchip.c +@@ -915,9 +915,8 @@ static struct rockchip_mux_route_data rk3308_mux_route_data[] = { + RK_MUXROUTE_SAME(0, RK_PC3, 1, 0x314, BIT(16 + 0) | BIT(0)), /* rtc_clk */ + RK_MUXROUTE_SAME(1, RK_PC6, 2, 0x314, BIT(16 + 2) | BIT(16 + 3)), /* uart2_rxm0 */ + RK_MUXROUTE_SAME(4, RK_PD2, 2, 0x314, BIT(16 + 2) | BIT(16 + 3) | BIT(2)), /* uart2_rxm1 */ +- RK_MUXROUTE_SAME(0, RK_PB7, 2, 0x608, BIT(16 + 8) | BIT(16 + 9)), /* i2c3_sdam0 */ +- RK_MUXROUTE_SAME(3, RK_PB4, 2, 0x608, BIT(16 + 8) | BIT(16 + 9) | BIT(8)), /* i2c3_sdam1 */ +- RK_MUXROUTE_SAME(2, RK_PA0, 3, 0x608, BIT(16 + 8) | BIT(16 + 9) | BIT(9)), /* i2c3_sdam2 */ ++ RK_MUXROUTE_SAME(0, RK_PB7, 2, 0x314, BIT(16 + 4)), /* i2c3_sdam0 */ ++ RK_MUXROUTE_SAME(3, RK_PB4, 2, 0x314, BIT(16 + 4) | BIT(4)), /* i2c3_sdam1 */ + RK_MUXROUTE_SAME(1, RK_PA3, 2, 0x308, BIT(16 + 3)), /* i2s-8ch-1-sclktxm0 */ + RK_MUXROUTE_SAME(1, RK_PA4, 2, 0x308, BIT(16 + 3)), /* i2s-8ch-1-sclkrxm0 */ + RK_MUXROUTE_SAME(1, RK_PB5, 2, 0x308, BIT(16 + 3) | BIT(3)), /* i2s-8ch-1-sclktxm1 */ +@@ -926,18 +925,6 @@ static struct rockchip_mux_route_data rk3308_mux_route_data[] = { + RK_MUXROUTE_SAME(1, RK_PB6, 4, 0x308, BIT(16 + 12) | BIT(16 + 13) | BIT(12)), /* pdm-clkm1 */ + RK_MUXROUTE_SAME(2, RK_PA6, 2, 0x308, BIT(16 + 12) | BIT(16 + 13) | BIT(13)), /* pdm-clkm2 */ + RK_MUXROUTE_SAME(2, RK_PA4, 3, 0x600, BIT(16 + 2) | BIT(2)), /* pdm-clkm-m2 */ +- RK_MUXROUTE_SAME(3, RK_PB2, 3, 0x314, BIT(16 + 9)), /* spi1_miso */ +- RK_MUXROUTE_SAME(2, RK_PA4, 2, 0x314, BIT(16 + 9) | BIT(9)), /* spi1_miso_m1 */ +- RK_MUXROUTE_SAME(0, RK_PB3, 3, 0x314, BIT(16 + 10) | BIT(16 + 11)), /* owire_m0 */ +- RK_MUXROUTE_SAME(1, RK_PC6, 7, 0x314, BIT(16 + 10) | BIT(16 + 11) | BIT(10)), /* owire_m1 */ +- RK_MUXROUTE_SAME(2, RK_PA2, 5, 0x314, BIT(16 + 10) | BIT(16 + 11) | BIT(11)), /* owire_m2 */ +- RK_MUXROUTE_SAME(0, RK_PB3, 2, 0x314, BIT(16 + 12) | BIT(16 + 13)), /* can_rxd_m0 */ +- RK_MUXROUTE_SAME(1, RK_PC6, 5, 0x314, BIT(16 + 12) | BIT(16 + 13) | BIT(12)), /* can_rxd_m1 */ +- RK_MUXROUTE_SAME(2, RK_PA2, 4, 0x314, BIT(16 + 12) | BIT(16 + 13) | BIT(13)), /* can_rxd_m2 */ +- RK_MUXROUTE_SAME(1, RK_PC4, 3, 0x314, BIT(16 + 14)), /* mac_rxd0_m0 */ +- RK_MUXROUTE_SAME(4, RK_PA2, 2, 0x314, BIT(16 + 14) | BIT(14)), /* mac_rxd0_m1 */ +- RK_MUXROUTE_SAME(3, RK_PB4, 4, 0x314, BIT(16 + 15)), /* uart3_rx */ +- RK_MUXROUTE_SAME(0, RK_PC1, 3, 0x314, BIT(16 + 15) | BIT(15)), /* uart3_rx_m1 */ + }; + + static struct rockchip_mux_route_data rk3328_mux_route_data[] = { +diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c +index 461a7c02d4a39..17e08f21756c3 100644 +--- a/drivers/pinctrl/pinctrl-single.c ++++ b/drivers/pinctrl/pinctrl-single.c +@@ -1327,7 +1327,6 @@ static void pcs_irq_free(struct pcs_device *pcs) + static void pcs_free_resources(struct pcs_device *pcs) + { + pcs_irq_free(pcs); +- pinctrl_unregister(pcs->pctl); + + #if IS_BUILTIN(CONFIG_PINCTRL_SINGLE) + if (pcs->missing_nr_pinctrl_cells) +@@ -1884,7 +1883,7 @@ static int pcs_probe(struct platform_device *pdev) + if (ret < 0) + goto free; + +- ret = pinctrl_register_and_init(&pcs->desc, pcs->dev, pcs, &pcs->pctl); ++ ret = devm_pinctrl_register_and_init(pcs->dev, &pcs->desc, pcs, &pcs->pctl); + if (ret) { + dev_err(pcs->dev, "could not register single pinctrl driver\n"); + goto free; +@@ -1917,8 +1916,10 @@ static int pcs_probe(struct platform_device *pdev) + + dev_info(pcs->dev, "%i pins, size %u\n", pcs->desc.npins, pcs->size); + +- return pinctrl_enable(pcs->pctl); ++ if (pinctrl_enable(pcs->pctl)) ++ goto free; + ++ return 0; + free: + pcs_free_resources(pcs); + +diff --git a/drivers/pinctrl/renesas/pfc-r8a779g0.c b/drivers/pinctrl/renesas/pfc-r8a779g0.c +index d2de526a3b588..bb843e333c880 100644 +--- a/drivers/pinctrl/renesas/pfc-r8a779g0.c ++++ b/drivers/pinctrl/renesas/pfc-r8a779g0.c +@@ -68,20 +68,20 @@ + #define GPSR0_9 F_(MSIOF5_SYNC, IP1SR0_7_4) + #define GPSR0_8 F_(MSIOF5_SS1, IP1SR0_3_0) + #define GPSR0_7 F_(MSIOF5_SS2, IP0SR0_31_28) +-#define GPSR0_6 F_(IRQ0, IP0SR0_27_24) +-#define GPSR0_5 F_(IRQ1, IP0SR0_23_20) +-#define GPSR0_4 F_(IRQ2, IP0SR0_19_16) +-#define GPSR0_3 F_(IRQ3, IP0SR0_15_12) ++#define GPSR0_6 F_(IRQ0_A, IP0SR0_27_24) ++#define GPSR0_5 F_(IRQ1_A, IP0SR0_23_20) ++#define GPSR0_4 F_(IRQ2_A, IP0SR0_19_16) ++#define GPSR0_3 F_(IRQ3_A, IP0SR0_15_12) + #define GPSR0_2 F_(GP0_02, IP0SR0_11_8) + #define GPSR0_1 F_(GP0_01, IP0SR0_7_4) + #define GPSR0_0 F_(GP0_00, IP0SR0_3_0) + + /* GPSR1 */ +-#define GPSR1_28 F_(HTX3, IP3SR1_19_16) +-#define GPSR1_27 F_(HCTS3_N, IP3SR1_15_12) +-#define GPSR1_26 F_(HRTS3_N, IP3SR1_11_8) +-#define GPSR1_25 F_(HSCK3, IP3SR1_7_4) +-#define GPSR1_24 F_(HRX3, IP3SR1_3_0) ++#define GPSR1_28 F_(HTX3_A, IP3SR1_19_16) ++#define GPSR1_27 F_(HCTS3_N_A, IP3SR1_15_12) ++#define GPSR1_26 F_(HRTS3_N_A, IP3SR1_11_8) ++#define GPSR1_25 F_(HSCK3_A, IP3SR1_7_4) ++#define GPSR1_24 F_(HRX3_A, IP3SR1_3_0) + #define GPSR1_23 F_(GP1_23, IP2SR1_31_28) + #define GPSR1_22 F_(AUDIO_CLKIN, IP2SR1_27_24) + #define GPSR1_21 F_(AUDIO_CLKOUT, IP2SR1_23_20) +@@ -119,14 +119,14 @@ + #define GPSR2_11 F_(CANFD0_RX, IP1SR2_15_12) + #define GPSR2_10 F_(CANFD0_TX, IP1SR2_11_8) + #define GPSR2_9 F_(CAN_CLK, IP1SR2_7_4) +-#define GPSR2_8 F_(TPU0TO0, IP1SR2_3_0) +-#define GPSR2_7 F_(TPU0TO1, IP0SR2_31_28) ++#define GPSR2_8 F_(TPU0TO0_A, IP1SR2_3_0) ++#define GPSR2_7 F_(TPU0TO1_A, IP0SR2_31_28) + #define GPSR2_6 F_(FXR_TXDB, IP0SR2_27_24) +-#define GPSR2_5 F_(FXR_TXENB_N, IP0SR2_23_20) ++#define GPSR2_5 F_(FXR_TXENB_N_A, IP0SR2_23_20) + #define GPSR2_4 F_(RXDB_EXTFXR, IP0SR2_19_16) + #define GPSR2_3 F_(CLK_EXTFXR, IP0SR2_15_12) + #define GPSR2_2 F_(RXDA_EXTFXR, IP0SR2_11_8) +-#define GPSR2_1 F_(FXR_TXENA_N, IP0SR2_7_4) ++#define GPSR2_1 F_(FXR_TXENA_N_A, IP0SR2_7_4) + #define GPSR2_0 F_(FXR_TXDA, IP0SR2_3_0) + + /* GPSR3 */ +@@ -275,13 +275,13 @@ + + /* SR0 */ + /* IP0SR0 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ +-#define IP0SR0_3_0 F_(0, 0) FM(ERROROUTC_N_B) FM(TCLK2_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP0SR0_3_0 F_(0, 0) FM(ERROROUTC_N_B) FM(TCLK2_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + #define IP0SR0_7_4 F_(0, 0) FM(MSIOF3_SS1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + #define IP0SR0_11_8 F_(0, 0) FM(MSIOF3_SS2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP0SR0_15_12 FM(IRQ3) FM(MSIOF3_SCK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP0SR0_19_16 FM(IRQ2) FM(MSIOF3_TXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP0SR0_23_20 FM(IRQ1) FM(MSIOF3_RXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP0SR0_27_24 FM(IRQ0) FM(MSIOF3_SYNC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP0SR0_15_12 FM(IRQ3_A) FM(MSIOF3_SCK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP0SR0_19_16 FM(IRQ2_A) FM(MSIOF3_TXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP0SR0_23_20 FM(IRQ1_A) FM(MSIOF3_RXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP0SR0_27_24 FM(IRQ0_A) FM(MSIOF3_SYNC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + #define IP0SR0_31_28 FM(MSIOF5_SS2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + + /* IP1SR0 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ +@@ -290,72 +290,72 @@ + #define IP1SR0_11_8 FM(MSIOF5_TXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + #define IP1SR0_15_12 FM(MSIOF5_SCK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + #define IP1SR0_19_16 FM(MSIOF5_RXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP1SR0_23_20 FM(MSIOF2_SS2) FM(TCLK1) FM(IRQ2_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP1SR0_27_24 FM(MSIOF2_SS1) FM(HTX1) FM(TX1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP1SR0_31_28 FM(MSIOF2_SYNC) FM(HRX1) FM(RX1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP1SR0_23_20 FM(MSIOF2_SS2) FM(TCLK1_A) FM(IRQ2_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP1SR0_27_24 FM(MSIOF2_SS1) FM(HTX1_A) FM(TX1_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP1SR0_31_28 FM(MSIOF2_SYNC) FM(HRX1_A) FM(RX1_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + + /* IP2SR0 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ +-#define IP2SR0_3_0 FM(MSIOF2_TXD) FM(HCTS1_N) FM(CTS1_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP2SR0_7_4 FM(MSIOF2_SCK) FM(HRTS1_N) FM(RTS1_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP2SR0_11_8 FM(MSIOF2_RXD) FM(HSCK1) FM(SCK1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP2SR0_3_0 FM(MSIOF2_TXD) FM(HCTS1_N_A) FM(CTS1_N_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP2SR0_7_4 FM(MSIOF2_SCK) FM(HRTS1_N_A) FM(RTS1_N_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP2SR0_11_8 FM(MSIOF2_RXD) FM(HSCK1_A) FM(SCK1_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + + /* SR1 */ + /* IP0SR1 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ +-#define IP0SR1_3_0 FM(MSIOF1_SS2) FM(HTX3_A) FM(TX3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP0SR1_7_4 FM(MSIOF1_SS1) FM(HCTS3_N_A) FM(RX3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP0SR1_11_8 FM(MSIOF1_SYNC) FM(HRTS3_N_A) FM(RTS3_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP0SR1_15_12 FM(MSIOF1_SCK) FM(HSCK3_A) FM(CTS3_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP0SR1_19_16 FM(MSIOF1_TXD) FM(HRX3_A) FM(SCK3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP0SR1_3_0 FM(MSIOF1_SS2) FM(HTX3_B) FM(TX3_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP0SR1_7_4 FM(MSIOF1_SS1) FM(HCTS3_N_B) FM(RX3_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP0SR1_11_8 FM(MSIOF1_SYNC) FM(HRTS3_N_B) FM(RTS3_N_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP0SR1_15_12 FM(MSIOF1_SCK) FM(HSCK3_B) FM(CTS3_N_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP0SR1_19_16 FM(MSIOF1_TXD) FM(HRX3_B) FM(SCK3_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + #define IP0SR1_23_20 FM(MSIOF1_RXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP0SR1_27_24 FM(MSIOF0_SS2) FM(HTX1_X) FM(TX1_X) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP0SR1_31_28 FM(MSIOF0_SS1) FM(HRX1_X) FM(RX1_X) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP0SR1_27_24 FM(MSIOF0_SS2) FM(HTX1_B) FM(TX1_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP0SR1_31_28 FM(MSIOF0_SS1) FM(HRX1_B) FM(RX1_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + + /* IP1SR1 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ +-#define IP1SR1_3_0 FM(MSIOF0_SYNC) FM(HCTS1_N_X) FM(CTS1_N_X) FM(CANFD5_TX_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP1SR1_7_4 FM(MSIOF0_TXD) FM(HRTS1_N_X) FM(RTS1_N_X) FM(CANFD5_RX_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP1SR1_11_8 FM(MSIOF0_SCK) FM(HSCK1_X) FM(SCK1_X) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP1SR1_3_0 FM(MSIOF0_SYNC) FM(HCTS1_N_B) FM(CTS1_N_B) FM(CANFD5_TX_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP1SR1_7_4 FM(MSIOF0_TXD) FM(HRTS1_N_B) FM(RTS1_N_B) FM(CANFD5_RX_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP1SR1_11_8 FM(MSIOF0_SCK) FM(HSCK1_B) FM(SCK1_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + #define IP1SR1_15_12 FM(MSIOF0_RXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + #define IP1SR1_19_16 FM(HTX0) FM(TX0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP1SR1_23_20 FM(HCTS0_N) FM(CTS0_N) FM(PWM8_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP1SR1_27_24 FM(HRTS0_N) FM(RTS0_N) FM(PWM9_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP1SR1_31_28 FM(HSCK0) FM(SCK0) FM(PWM0_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP1SR1_23_20 FM(HCTS0_N) FM(CTS0_N) FM(PWM8) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP1SR1_27_24 FM(HRTS0_N) FM(RTS0_N) FM(PWM9) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP1SR1_31_28 FM(HSCK0) FM(SCK0) FM(PWM0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + + /* IP2SR1 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ + #define IP2SR1_3_0 FM(HRX0) FM(RX0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + #define IP2SR1_7_4 FM(SCIF_CLK) FM(IRQ4_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP2SR1_11_8 FM(SSI_SCK) FM(TCLK3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP2SR1_15_12 FM(SSI_WS) FM(TCLK4) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP2SR1_19_16 FM(SSI_SD) FM(IRQ0_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP2SR1_23_20 FM(AUDIO_CLKOUT) FM(IRQ1_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP2SR1_11_8 FM(SSI_SCK) FM(TCLK3_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP2SR1_15_12 FM(SSI_WS) FM(TCLK4_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP2SR1_19_16 FM(SSI_SD) FM(IRQ0_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP2SR1_23_20 FM(AUDIO_CLKOUT) FM(IRQ1_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + #define IP2SR1_27_24 FM(AUDIO_CLKIN) FM(PWM3_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP2SR1_31_28 F_(0, 0) FM(TCLK2) FM(MSIOF4_SS1) FM(IRQ3_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP2SR1_31_28 F_(0, 0) FM(TCLK2_A) FM(MSIOF4_SS1) FM(IRQ3_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + + /* IP3SR1 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ +-#define IP3SR1_3_0 FM(HRX3) FM(SCK3_A) FM(MSIOF4_SS2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP3SR1_7_4 FM(HSCK3) FM(CTS3_N_A) FM(MSIOF4_SCK) FM(TPU0TO0_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP3SR1_11_8 FM(HRTS3_N) FM(RTS3_N_A) FM(MSIOF4_TXD) FM(TPU0TO1_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP3SR1_15_12 FM(HCTS3_N) FM(RX3_A) FM(MSIOF4_RXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP3SR1_19_16 FM(HTX3) FM(TX3_A) FM(MSIOF4_SYNC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP3SR1_3_0 FM(HRX3_A) FM(SCK3_A) FM(MSIOF4_SS2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP3SR1_7_4 FM(HSCK3_A) FM(CTS3_N_A) FM(MSIOF4_SCK) FM(TPU0TO0_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP3SR1_11_8 FM(HRTS3_N_A) FM(RTS3_N_A) FM(MSIOF4_TXD) FM(TPU0TO1_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP3SR1_15_12 FM(HCTS3_N_A) FM(RX3_A) FM(MSIOF4_RXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP3SR1_19_16 FM(HTX3_A) FM(TX3_A) FM(MSIOF4_SYNC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + + /* SR2 */ + /* IP0SR2 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ +-#define IP0SR2_3_0 FM(FXR_TXDA) FM(CANFD1_TX) FM(TPU0TO2_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP0SR2_7_4 FM(FXR_TXENA_N) FM(CANFD1_RX) FM(TPU0TO3_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP0SR2_11_8 FM(RXDA_EXTFXR) FM(CANFD5_TX) FM(IRQ5) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP0SR2_15_12 FM(CLK_EXTFXR) FM(CANFD5_RX) FM(IRQ4_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP0SR2_3_0 FM(FXR_TXDA) FM(CANFD1_TX) FM(TPU0TO2_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP0SR2_7_4 FM(FXR_TXENA_N_A) FM(CANFD1_RX) FM(TPU0TO3_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP0SR2_11_8 FM(RXDA_EXTFXR) FM(CANFD5_TX_A) FM(IRQ5) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP0SR2_15_12 FM(CLK_EXTFXR) FM(CANFD5_RX_A) FM(IRQ4_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + #define IP0SR2_19_16 FM(RXDB_EXTFXR) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP0SR2_23_20 FM(FXR_TXENB_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP0SR2_23_20 FM(FXR_TXENB_N_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + #define IP0SR2_27_24 FM(FXR_TXDB) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP0SR2_31_28 FM(TPU0TO1) FM(CANFD6_TX) F_(0, 0) FM(TCLK2_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP0SR2_31_28 FM(TPU0TO1_A) FM(CANFD6_TX) F_(0, 0) FM(TCLK2_C) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + + /* IP1SR2 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ +-#define IP1SR2_3_0 FM(TPU0TO0) FM(CANFD6_RX) F_(0, 0) FM(TCLK1_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP1SR2_7_4 FM(CAN_CLK) FM(FXR_TXENA_N_X) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP1SR2_11_8 FM(CANFD0_TX) FM(FXR_TXENB_N_X) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP1SR2_3_0 FM(TPU0TO0_A) FM(CANFD6_RX) F_(0, 0) FM(TCLK1_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP1SR2_7_4 FM(CAN_CLK) FM(FXR_TXENA_N_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP1SR2_11_8 FM(CANFD0_TX) FM(FXR_TXENB_N_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + #define IP1SR2_15_12 FM(CANFD0_RX) FM(STPWT_EXTFXR) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP1SR2_19_16 FM(CANFD2_TX) FM(TPU0TO2) F_(0, 0) FM(TCLK3_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP1SR2_23_20 FM(CANFD2_RX) FM(TPU0TO3) FM(PWM1_B) FM(TCLK4_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP1SR2_27_24 FM(CANFD3_TX) F_(0, 0) FM(PWM2_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP1SR2_19_16 FM(CANFD2_TX) FM(TPU0TO2_A) F_(0, 0) FM(TCLK3_C) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP1SR2_23_20 FM(CANFD2_RX) FM(TPU0TO3_A) FM(PWM1_B) FM(TCLK4_C) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP1SR2_27_24 FM(CANFD3_TX) F_(0, 0) FM(PWM2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + #define IP1SR2_31_28 FM(CANFD3_RX) F_(0, 0) FM(PWM3_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + + /* IP2SR2 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ +@@ -381,8 +381,8 @@ + #define IP1SR3_11_8 FM(MMC_SD_CMD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + #define IP1SR3_15_12 FM(SD_CD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + #define IP1SR3_19_16 FM(SD_WP) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP1SR3_23_20 FM(IPC_CLKIN) FM(IPC_CLKEN_IN) FM(PWM1_A) FM(TCLK3_X) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +-#define IP1SR3_27_24 FM(IPC_CLKOUT) FM(IPC_CLKEN_OUT) FM(ERROROUTC_N_A) FM(TCLK4_X) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP1SR3_23_20 FM(IPC_CLKIN) FM(IPC_CLKEN_IN) FM(PWM1_A) FM(TCLK3_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) ++#define IP1SR3_27_24 FM(IPC_CLKOUT) FM(IPC_CLKEN_OUT) FM(ERROROUTC_N_A) FM(TCLK4_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + #define IP1SR3_31_28 FM(QSPI0_SSL) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) + + /* IP2SR3 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ +@@ -718,22 +718,22 @@ static const u16 pinmux_data[] = { + + /* IP0SR0 */ + PINMUX_IPSR_GPSR(IP0SR0_3_0, ERROROUTC_N_B), +- PINMUX_IPSR_GPSR(IP0SR0_3_0, TCLK2_A), ++ PINMUX_IPSR_GPSR(IP0SR0_3_0, TCLK2_B), + + PINMUX_IPSR_GPSR(IP0SR0_7_4, MSIOF3_SS1), + + PINMUX_IPSR_GPSR(IP0SR0_11_8, MSIOF3_SS2), + +- PINMUX_IPSR_GPSR(IP0SR0_15_12, IRQ3), ++ PINMUX_IPSR_GPSR(IP0SR0_15_12, IRQ3_A), + PINMUX_IPSR_GPSR(IP0SR0_15_12, MSIOF3_SCK), + +- PINMUX_IPSR_GPSR(IP0SR0_19_16, IRQ2), ++ PINMUX_IPSR_GPSR(IP0SR0_19_16, IRQ2_A), + PINMUX_IPSR_GPSR(IP0SR0_19_16, MSIOF3_TXD), + +- PINMUX_IPSR_GPSR(IP0SR0_23_20, IRQ1), ++ PINMUX_IPSR_GPSR(IP0SR0_23_20, IRQ1_A), + PINMUX_IPSR_GPSR(IP0SR0_23_20, MSIOF3_RXD), + +- PINMUX_IPSR_GPSR(IP0SR0_27_24, IRQ0), ++ PINMUX_IPSR_GPSR(IP0SR0_27_24, IRQ0_A), + PINMUX_IPSR_GPSR(IP0SR0_27_24, MSIOF3_SYNC), + + PINMUX_IPSR_GPSR(IP0SR0_31_28, MSIOF5_SS2), +@@ -750,75 +750,75 @@ static const u16 pinmux_data[] = { + PINMUX_IPSR_GPSR(IP1SR0_19_16, MSIOF5_RXD), + + PINMUX_IPSR_GPSR(IP1SR0_23_20, MSIOF2_SS2), +- PINMUX_IPSR_GPSR(IP1SR0_23_20, TCLK1), +- PINMUX_IPSR_GPSR(IP1SR0_23_20, IRQ2_A), ++ PINMUX_IPSR_GPSR(IP1SR0_23_20, TCLK1_A), ++ PINMUX_IPSR_GPSR(IP1SR0_23_20, IRQ2_B), + + PINMUX_IPSR_GPSR(IP1SR0_27_24, MSIOF2_SS1), +- PINMUX_IPSR_GPSR(IP1SR0_27_24, HTX1), +- PINMUX_IPSR_GPSR(IP1SR0_27_24, TX1), ++ PINMUX_IPSR_GPSR(IP1SR0_27_24, HTX1_A), ++ PINMUX_IPSR_GPSR(IP1SR0_27_24, TX1_A), + + PINMUX_IPSR_GPSR(IP1SR0_31_28, MSIOF2_SYNC), +- PINMUX_IPSR_GPSR(IP1SR0_31_28, HRX1), +- PINMUX_IPSR_GPSR(IP1SR0_31_28, RX1), ++ PINMUX_IPSR_GPSR(IP1SR0_31_28, HRX1_A), ++ PINMUX_IPSR_GPSR(IP1SR0_31_28, RX1_A), + + /* IP2SR0 */ + PINMUX_IPSR_GPSR(IP2SR0_3_0, MSIOF2_TXD), +- PINMUX_IPSR_GPSR(IP2SR0_3_0, HCTS1_N), +- PINMUX_IPSR_GPSR(IP2SR0_3_0, CTS1_N), ++ PINMUX_IPSR_GPSR(IP2SR0_3_0, HCTS1_N_A), ++ PINMUX_IPSR_GPSR(IP2SR0_3_0, CTS1_N_A), + + PINMUX_IPSR_GPSR(IP2SR0_7_4, MSIOF2_SCK), +- PINMUX_IPSR_GPSR(IP2SR0_7_4, HRTS1_N), +- PINMUX_IPSR_GPSR(IP2SR0_7_4, RTS1_N), ++ PINMUX_IPSR_GPSR(IP2SR0_7_4, HRTS1_N_A), ++ PINMUX_IPSR_GPSR(IP2SR0_7_4, RTS1_N_A), + + PINMUX_IPSR_GPSR(IP2SR0_11_8, MSIOF2_RXD), +- PINMUX_IPSR_GPSR(IP2SR0_11_8, HSCK1), +- PINMUX_IPSR_GPSR(IP2SR0_11_8, SCK1), ++ PINMUX_IPSR_GPSR(IP2SR0_11_8, HSCK1_A), ++ PINMUX_IPSR_GPSR(IP2SR0_11_8, SCK1_A), + + /* IP0SR1 */ + PINMUX_IPSR_GPSR(IP0SR1_3_0, MSIOF1_SS2), +- PINMUX_IPSR_GPSR(IP0SR1_3_0, HTX3_A), +- PINMUX_IPSR_GPSR(IP0SR1_3_0, TX3), ++ PINMUX_IPSR_GPSR(IP0SR1_3_0, HTX3_B), ++ PINMUX_IPSR_GPSR(IP0SR1_3_0, TX3_B), + + PINMUX_IPSR_GPSR(IP0SR1_7_4, MSIOF1_SS1), +- PINMUX_IPSR_GPSR(IP0SR1_7_4, HCTS3_N_A), +- PINMUX_IPSR_GPSR(IP0SR1_7_4, RX3), ++ PINMUX_IPSR_GPSR(IP0SR1_7_4, HCTS3_N_B), ++ PINMUX_IPSR_GPSR(IP0SR1_7_4, RX3_B), + + PINMUX_IPSR_GPSR(IP0SR1_11_8, MSIOF1_SYNC), +- PINMUX_IPSR_GPSR(IP0SR1_11_8, HRTS3_N_A), +- PINMUX_IPSR_GPSR(IP0SR1_11_8, RTS3_N), ++ PINMUX_IPSR_GPSR(IP0SR1_11_8, HRTS3_N_B), ++ PINMUX_IPSR_GPSR(IP0SR1_11_8, RTS3_N_B), + + PINMUX_IPSR_GPSR(IP0SR1_15_12, MSIOF1_SCK), +- PINMUX_IPSR_GPSR(IP0SR1_15_12, HSCK3_A), +- PINMUX_IPSR_GPSR(IP0SR1_15_12, CTS3_N), ++ PINMUX_IPSR_GPSR(IP0SR1_15_12, HSCK3_B), ++ PINMUX_IPSR_GPSR(IP0SR1_15_12, CTS3_N_B), + + PINMUX_IPSR_GPSR(IP0SR1_19_16, MSIOF1_TXD), +- PINMUX_IPSR_GPSR(IP0SR1_19_16, HRX3_A), +- PINMUX_IPSR_GPSR(IP0SR1_19_16, SCK3), ++ PINMUX_IPSR_GPSR(IP0SR1_19_16, HRX3_B), ++ PINMUX_IPSR_GPSR(IP0SR1_19_16, SCK3_B), + + PINMUX_IPSR_GPSR(IP0SR1_23_20, MSIOF1_RXD), + + PINMUX_IPSR_GPSR(IP0SR1_27_24, MSIOF0_SS2), +- PINMUX_IPSR_GPSR(IP0SR1_27_24, HTX1_X), +- PINMUX_IPSR_GPSR(IP0SR1_27_24, TX1_X), ++ PINMUX_IPSR_GPSR(IP0SR1_27_24, HTX1_B), ++ PINMUX_IPSR_GPSR(IP0SR1_27_24, TX1_B), + + PINMUX_IPSR_GPSR(IP0SR1_31_28, MSIOF0_SS1), +- PINMUX_IPSR_GPSR(IP0SR1_31_28, HRX1_X), +- PINMUX_IPSR_GPSR(IP0SR1_31_28, RX1_X), ++ PINMUX_IPSR_GPSR(IP0SR1_31_28, HRX1_B), ++ PINMUX_IPSR_GPSR(IP0SR1_31_28, RX1_B), + + /* IP1SR1 */ + PINMUX_IPSR_GPSR(IP1SR1_3_0, MSIOF0_SYNC), +- PINMUX_IPSR_GPSR(IP1SR1_3_0, HCTS1_N_X), +- PINMUX_IPSR_GPSR(IP1SR1_3_0, CTS1_N_X), ++ PINMUX_IPSR_GPSR(IP1SR1_3_0, HCTS1_N_B), ++ PINMUX_IPSR_GPSR(IP1SR1_3_0, CTS1_N_B), + PINMUX_IPSR_GPSR(IP1SR1_3_0, CANFD5_TX_B), + + PINMUX_IPSR_GPSR(IP1SR1_7_4, MSIOF0_TXD), +- PINMUX_IPSR_GPSR(IP1SR1_7_4, HRTS1_N_X), +- PINMUX_IPSR_GPSR(IP1SR1_7_4, RTS1_N_X), ++ PINMUX_IPSR_GPSR(IP1SR1_7_4, HRTS1_N_B), ++ PINMUX_IPSR_GPSR(IP1SR1_7_4, RTS1_N_B), + PINMUX_IPSR_GPSR(IP1SR1_7_4, CANFD5_RX_B), + + PINMUX_IPSR_GPSR(IP1SR1_11_8, MSIOF0_SCK), +- PINMUX_IPSR_GPSR(IP1SR1_11_8, HSCK1_X), +- PINMUX_IPSR_GPSR(IP1SR1_11_8, SCK1_X), ++ PINMUX_IPSR_GPSR(IP1SR1_11_8, HSCK1_B), ++ PINMUX_IPSR_GPSR(IP1SR1_11_8, SCK1_B), + + PINMUX_IPSR_GPSR(IP1SR1_15_12, MSIOF0_RXD), + +@@ -827,15 +827,15 @@ static const u16 pinmux_data[] = { + + PINMUX_IPSR_GPSR(IP1SR1_23_20, HCTS0_N), + PINMUX_IPSR_GPSR(IP1SR1_23_20, CTS0_N), +- PINMUX_IPSR_GPSR(IP1SR1_23_20, PWM8_A), ++ PINMUX_IPSR_GPSR(IP1SR1_23_20, PWM8), + + PINMUX_IPSR_GPSR(IP1SR1_27_24, HRTS0_N), + PINMUX_IPSR_GPSR(IP1SR1_27_24, RTS0_N), +- PINMUX_IPSR_GPSR(IP1SR1_27_24, PWM9_A), ++ PINMUX_IPSR_GPSR(IP1SR1_27_24, PWM9), + + PINMUX_IPSR_GPSR(IP1SR1_31_28, HSCK0), + PINMUX_IPSR_GPSR(IP1SR1_31_28, SCK0), +- PINMUX_IPSR_GPSR(IP1SR1_31_28, PWM0_A), ++ PINMUX_IPSR_GPSR(IP1SR1_31_28, PWM0), + + /* IP2SR1 */ + PINMUX_IPSR_GPSR(IP2SR1_3_0, HRX0), +@@ -845,99 +845,99 @@ static const u16 pinmux_data[] = { + PINMUX_IPSR_GPSR(IP2SR1_7_4, IRQ4_A), + + PINMUX_IPSR_GPSR(IP2SR1_11_8, SSI_SCK), +- PINMUX_IPSR_GPSR(IP2SR1_11_8, TCLK3), ++ PINMUX_IPSR_GPSR(IP2SR1_11_8, TCLK3_B), + + PINMUX_IPSR_GPSR(IP2SR1_15_12, SSI_WS), +- PINMUX_IPSR_GPSR(IP2SR1_15_12, TCLK4), ++ PINMUX_IPSR_GPSR(IP2SR1_15_12, TCLK4_B), + + PINMUX_IPSR_GPSR(IP2SR1_19_16, SSI_SD), +- PINMUX_IPSR_GPSR(IP2SR1_19_16, IRQ0_A), ++ PINMUX_IPSR_GPSR(IP2SR1_19_16, IRQ0_B), + + PINMUX_IPSR_GPSR(IP2SR1_23_20, AUDIO_CLKOUT), +- PINMUX_IPSR_GPSR(IP2SR1_23_20, IRQ1_A), ++ PINMUX_IPSR_GPSR(IP2SR1_23_20, IRQ1_B), + + PINMUX_IPSR_GPSR(IP2SR1_27_24, AUDIO_CLKIN), + PINMUX_IPSR_GPSR(IP2SR1_27_24, PWM3_A), + +- PINMUX_IPSR_GPSR(IP2SR1_31_28, TCLK2), ++ PINMUX_IPSR_GPSR(IP2SR1_31_28, TCLK2_A), + PINMUX_IPSR_GPSR(IP2SR1_31_28, MSIOF4_SS1), + PINMUX_IPSR_GPSR(IP2SR1_31_28, IRQ3_B), + + /* IP3SR1 */ +- PINMUX_IPSR_GPSR(IP3SR1_3_0, HRX3), ++ PINMUX_IPSR_GPSR(IP3SR1_3_0, HRX3_A), + PINMUX_IPSR_GPSR(IP3SR1_3_0, SCK3_A), + PINMUX_IPSR_GPSR(IP3SR1_3_0, MSIOF4_SS2), + +- PINMUX_IPSR_GPSR(IP3SR1_7_4, HSCK3), ++ PINMUX_IPSR_GPSR(IP3SR1_7_4, HSCK3_A), + PINMUX_IPSR_GPSR(IP3SR1_7_4, CTS3_N_A), + PINMUX_IPSR_GPSR(IP3SR1_7_4, MSIOF4_SCK), +- PINMUX_IPSR_GPSR(IP3SR1_7_4, TPU0TO0_A), ++ PINMUX_IPSR_GPSR(IP3SR1_7_4, TPU0TO0_B), + +- PINMUX_IPSR_GPSR(IP3SR1_11_8, HRTS3_N), ++ PINMUX_IPSR_GPSR(IP3SR1_11_8, HRTS3_N_A), + PINMUX_IPSR_GPSR(IP3SR1_11_8, RTS3_N_A), + PINMUX_IPSR_GPSR(IP3SR1_11_8, MSIOF4_TXD), +- PINMUX_IPSR_GPSR(IP3SR1_11_8, TPU0TO1_A), ++ PINMUX_IPSR_GPSR(IP3SR1_11_8, TPU0TO1_B), + +- PINMUX_IPSR_GPSR(IP3SR1_15_12, HCTS3_N), ++ PINMUX_IPSR_GPSR(IP3SR1_15_12, HCTS3_N_A), + PINMUX_IPSR_GPSR(IP3SR1_15_12, RX3_A), + PINMUX_IPSR_GPSR(IP3SR1_15_12, MSIOF4_RXD), + +- PINMUX_IPSR_GPSR(IP3SR1_19_16, HTX3), ++ PINMUX_IPSR_GPSR(IP3SR1_19_16, HTX3_A), + PINMUX_IPSR_GPSR(IP3SR1_19_16, TX3_A), + PINMUX_IPSR_GPSR(IP3SR1_19_16, MSIOF4_SYNC), + + /* IP0SR2 */ + PINMUX_IPSR_GPSR(IP0SR2_3_0, FXR_TXDA), + PINMUX_IPSR_GPSR(IP0SR2_3_0, CANFD1_TX), +- PINMUX_IPSR_GPSR(IP0SR2_3_0, TPU0TO2_A), ++ PINMUX_IPSR_GPSR(IP0SR2_3_0, TPU0TO2_B), + +- PINMUX_IPSR_GPSR(IP0SR2_7_4, FXR_TXENA_N), ++ PINMUX_IPSR_GPSR(IP0SR2_7_4, FXR_TXENA_N_A), + PINMUX_IPSR_GPSR(IP0SR2_7_4, CANFD1_RX), +- PINMUX_IPSR_GPSR(IP0SR2_7_4, TPU0TO3_A), ++ PINMUX_IPSR_GPSR(IP0SR2_7_4, TPU0TO3_B), + + PINMUX_IPSR_GPSR(IP0SR2_11_8, RXDA_EXTFXR), +- PINMUX_IPSR_GPSR(IP0SR2_11_8, CANFD5_TX), ++ PINMUX_IPSR_GPSR(IP0SR2_11_8, CANFD5_TX_A), + PINMUX_IPSR_GPSR(IP0SR2_11_8, IRQ5), + + PINMUX_IPSR_GPSR(IP0SR2_15_12, CLK_EXTFXR), +- PINMUX_IPSR_GPSR(IP0SR2_15_12, CANFD5_RX), ++ PINMUX_IPSR_GPSR(IP0SR2_15_12, CANFD5_RX_A), + PINMUX_IPSR_GPSR(IP0SR2_15_12, IRQ4_B), + + PINMUX_IPSR_GPSR(IP0SR2_19_16, RXDB_EXTFXR), + +- PINMUX_IPSR_GPSR(IP0SR2_23_20, FXR_TXENB_N), ++ PINMUX_IPSR_GPSR(IP0SR2_23_20, FXR_TXENB_N_A), + + PINMUX_IPSR_GPSR(IP0SR2_27_24, FXR_TXDB), + +- PINMUX_IPSR_GPSR(IP0SR2_31_28, TPU0TO1), ++ PINMUX_IPSR_GPSR(IP0SR2_31_28, TPU0TO1_A), + PINMUX_IPSR_GPSR(IP0SR2_31_28, CANFD6_TX), +- PINMUX_IPSR_GPSR(IP0SR2_31_28, TCLK2_B), ++ PINMUX_IPSR_GPSR(IP0SR2_31_28, TCLK2_C), + + /* IP1SR2 */ +- PINMUX_IPSR_GPSR(IP1SR2_3_0, TPU0TO0), ++ PINMUX_IPSR_GPSR(IP1SR2_3_0, TPU0TO0_A), + PINMUX_IPSR_GPSR(IP1SR2_3_0, CANFD6_RX), +- PINMUX_IPSR_GPSR(IP1SR2_3_0, TCLK1_A), ++ PINMUX_IPSR_GPSR(IP1SR2_3_0, TCLK1_B), + + PINMUX_IPSR_GPSR(IP1SR2_7_4, CAN_CLK), +- PINMUX_IPSR_GPSR(IP1SR2_7_4, FXR_TXENA_N_X), ++ PINMUX_IPSR_GPSR(IP1SR2_7_4, FXR_TXENA_N_B), + + PINMUX_IPSR_GPSR(IP1SR2_11_8, CANFD0_TX), +- PINMUX_IPSR_GPSR(IP1SR2_11_8, FXR_TXENB_N_X), ++ PINMUX_IPSR_GPSR(IP1SR2_11_8, FXR_TXENB_N_B), + + PINMUX_IPSR_GPSR(IP1SR2_15_12, CANFD0_RX), + PINMUX_IPSR_GPSR(IP1SR2_15_12, STPWT_EXTFXR), + + PINMUX_IPSR_GPSR(IP1SR2_19_16, CANFD2_TX), +- PINMUX_IPSR_GPSR(IP1SR2_19_16, TPU0TO2), +- PINMUX_IPSR_GPSR(IP1SR2_19_16, TCLK3_A), ++ PINMUX_IPSR_GPSR(IP1SR2_19_16, TPU0TO2_A), ++ PINMUX_IPSR_GPSR(IP1SR2_19_16, TCLK3_C), + + PINMUX_IPSR_GPSR(IP1SR2_23_20, CANFD2_RX), +- PINMUX_IPSR_GPSR(IP1SR2_23_20, TPU0TO3), ++ PINMUX_IPSR_GPSR(IP1SR2_23_20, TPU0TO3_A), + PINMUX_IPSR_GPSR(IP1SR2_23_20, PWM1_B), +- PINMUX_IPSR_GPSR(IP1SR2_23_20, TCLK4_A), ++ PINMUX_IPSR_GPSR(IP1SR2_23_20, TCLK4_C), + + PINMUX_IPSR_GPSR(IP1SR2_27_24, CANFD3_TX), +- PINMUX_IPSR_GPSR(IP1SR2_27_24, PWM2_B), ++ PINMUX_IPSR_GPSR(IP1SR2_27_24, PWM2), + + PINMUX_IPSR_GPSR(IP1SR2_31_28, CANFD3_RX), + PINMUX_IPSR_GPSR(IP1SR2_31_28, PWM3_B), +@@ -979,12 +979,12 @@ static const u16 pinmux_data[] = { + PINMUX_IPSR_GPSR(IP1SR3_23_20, IPC_CLKIN), + PINMUX_IPSR_GPSR(IP1SR3_23_20, IPC_CLKEN_IN), + PINMUX_IPSR_GPSR(IP1SR3_23_20, PWM1_A), +- PINMUX_IPSR_GPSR(IP1SR3_23_20, TCLK3_X), ++ PINMUX_IPSR_GPSR(IP1SR3_23_20, TCLK3_A), + + PINMUX_IPSR_GPSR(IP1SR3_27_24, IPC_CLKOUT), + PINMUX_IPSR_GPSR(IP1SR3_27_24, IPC_CLKEN_OUT), + PINMUX_IPSR_GPSR(IP1SR3_27_24, ERROROUTC_N_A), +- PINMUX_IPSR_GPSR(IP1SR3_27_24, TCLK4_X), ++ PINMUX_IPSR_GPSR(IP1SR3_27_24, TCLK4_A), + + PINMUX_IPSR_GPSR(IP1SR3_31_28, QSPI0_SSL), + +@@ -1531,15 +1531,14 @@ static const unsigned int canfd4_data_mux[] = { + }; + + /* - CANFD5 ----------------------------------------------------------------- */ +-static const unsigned int canfd5_data_pins[] = { +- /* CANFD5_TX, CANFD5_RX */ ++static const unsigned int canfd5_data_a_pins[] = { ++ /* CANFD5_TX_A, CANFD5_RX_A */ + RCAR_GP_PIN(2, 2), RCAR_GP_PIN(2, 3), + }; +-static const unsigned int canfd5_data_mux[] = { +- CANFD5_TX_MARK, CANFD5_RX_MARK, ++static const unsigned int canfd5_data_a_mux[] = { ++ CANFD5_TX_A_MARK, CANFD5_RX_A_MARK, + }; + +-/* - CANFD5_B ----------------------------------------------------------------- */ + static const unsigned int canfd5_data_b_pins[] = { + /* CANFD5_TX_B, CANFD5_RX_B */ + RCAR_GP_PIN(1, 8), RCAR_GP_PIN(1, 9), +@@ -1599,49 +1598,48 @@ static const unsigned int hscif0_ctrl_mux[] = { + }; + + /* - HSCIF1 ----------------------------------------------------------------- */ +-static const unsigned int hscif1_data_pins[] = { +- /* HRX1, HTX1 */ ++static const unsigned int hscif1_data_a_pins[] = { ++ /* HRX1_A, HTX1_A */ + RCAR_GP_PIN(0, 15), RCAR_GP_PIN(0, 14), + }; +-static const unsigned int hscif1_data_mux[] = { +- HRX1_MARK, HTX1_MARK, ++static const unsigned int hscif1_data_a_mux[] = { ++ HRX1_A_MARK, HTX1_A_MARK, + }; +-static const unsigned int hscif1_clk_pins[] = { +- /* HSCK1 */ ++static const unsigned int hscif1_clk_a_pins[] = { ++ /* HSCK1_A */ + RCAR_GP_PIN(0, 18), + }; +-static const unsigned int hscif1_clk_mux[] = { +- HSCK1_MARK, ++static const unsigned int hscif1_clk_a_mux[] = { ++ HSCK1_A_MARK, + }; +-static const unsigned int hscif1_ctrl_pins[] = { +- /* HRTS1_N, HCTS1_N */ ++static const unsigned int hscif1_ctrl_a_pins[] = { ++ /* HRTS1_N_A, HCTS1_N_A */ + RCAR_GP_PIN(0, 17), RCAR_GP_PIN(0, 16), + }; +-static const unsigned int hscif1_ctrl_mux[] = { +- HRTS1_N_MARK, HCTS1_N_MARK, ++static const unsigned int hscif1_ctrl_a_mux[] = { ++ HRTS1_N_A_MARK, HCTS1_N_A_MARK, + }; + +-/* - HSCIF1_X---------------------------------------------------------------- */ +-static const unsigned int hscif1_data_x_pins[] = { +- /* HRX1_X, HTX1_X */ ++static const unsigned int hscif1_data_b_pins[] = { ++ /* HRX1_B, HTX1_B */ + RCAR_GP_PIN(1, 7), RCAR_GP_PIN(1, 6), + }; +-static const unsigned int hscif1_data_x_mux[] = { +- HRX1_X_MARK, HTX1_X_MARK, ++static const unsigned int hscif1_data_b_mux[] = { ++ HRX1_B_MARK, HTX1_B_MARK, + }; +-static const unsigned int hscif1_clk_x_pins[] = { +- /* HSCK1_X */ ++static const unsigned int hscif1_clk_b_pins[] = { ++ /* HSCK1_B */ + RCAR_GP_PIN(1, 10), + }; +-static const unsigned int hscif1_clk_x_mux[] = { +- HSCK1_X_MARK, ++static const unsigned int hscif1_clk_b_mux[] = { ++ HSCK1_B_MARK, + }; +-static const unsigned int hscif1_ctrl_x_pins[] = { +- /* HRTS1_N_X, HCTS1_N_X */ ++static const unsigned int hscif1_ctrl_b_pins[] = { ++ /* HRTS1_N_B, HCTS1_N_B */ + RCAR_GP_PIN(1, 9), RCAR_GP_PIN(1, 8), + }; +-static const unsigned int hscif1_ctrl_x_mux[] = { +- HRTS1_N_X_MARK, HCTS1_N_X_MARK, ++static const unsigned int hscif1_ctrl_b_mux[] = { ++ HRTS1_N_B_MARK, HCTS1_N_B_MARK, + }; + + /* - HSCIF2 ----------------------------------------------------------------- */ +@@ -1668,49 +1666,48 @@ static const unsigned int hscif2_ctrl_mux[] = { + }; + + /* - HSCIF3 ----------------------------------------------------------------- */ +-static const unsigned int hscif3_data_pins[] = { +- /* HRX3, HTX3 */ ++static const unsigned int hscif3_data_a_pins[] = { ++ /* HRX3_A, HTX3_A */ + RCAR_GP_PIN(1, 24), RCAR_GP_PIN(1, 28), + }; +-static const unsigned int hscif3_data_mux[] = { +- HRX3_MARK, HTX3_MARK, ++static const unsigned int hscif3_data_a_mux[] = { ++ HRX3_A_MARK, HTX3_A_MARK, + }; +-static const unsigned int hscif3_clk_pins[] = { +- /* HSCK3 */ ++static const unsigned int hscif3_clk_a_pins[] = { ++ /* HSCK3_A */ + RCAR_GP_PIN(1, 25), + }; +-static const unsigned int hscif3_clk_mux[] = { +- HSCK3_MARK, ++static const unsigned int hscif3_clk_a_mux[] = { ++ HSCK3_A_MARK, + }; +-static const unsigned int hscif3_ctrl_pins[] = { +- /* HRTS3_N, HCTS3_N */ ++static const unsigned int hscif3_ctrl_a_pins[] = { ++ /* HRTS3_N_A, HCTS3_N_A */ + RCAR_GP_PIN(1, 26), RCAR_GP_PIN(1, 27), + }; +-static const unsigned int hscif3_ctrl_mux[] = { +- HRTS3_N_MARK, HCTS3_N_MARK, ++static const unsigned int hscif3_ctrl_a_mux[] = { ++ HRTS3_N_A_MARK, HCTS3_N_A_MARK, + }; + +-/* - HSCIF3_A ----------------------------------------------------------------- */ +-static const unsigned int hscif3_data_a_pins[] = { +- /* HRX3_A, HTX3_A */ ++static const unsigned int hscif3_data_b_pins[] = { ++ /* HRX3_B, HTX3_B */ + RCAR_GP_PIN(1, 4), RCAR_GP_PIN(1, 0), + }; +-static const unsigned int hscif3_data_a_mux[] = { +- HRX3_A_MARK, HTX3_A_MARK, ++static const unsigned int hscif3_data_b_mux[] = { ++ HRX3_B_MARK, HTX3_B_MARK, + }; +-static const unsigned int hscif3_clk_a_pins[] = { +- /* HSCK3_A */ ++static const unsigned int hscif3_clk_b_pins[] = { ++ /* HSCK3_B */ + RCAR_GP_PIN(1, 3), + }; +-static const unsigned int hscif3_clk_a_mux[] = { +- HSCK3_A_MARK, ++static const unsigned int hscif3_clk_b_mux[] = { ++ HSCK3_B_MARK, + }; +-static const unsigned int hscif3_ctrl_a_pins[] = { +- /* HRTS3_N_A, HCTS3_N_A */ ++static const unsigned int hscif3_ctrl_b_pins[] = { ++ /* HRTS3_N_B, HCTS3_N_B */ + RCAR_GP_PIN(1, 2), RCAR_GP_PIN(1, 1), + }; +-static const unsigned int hscif3_ctrl_a_mux[] = { +- HRTS3_N_A_MARK, HCTS3_N_A_MARK, ++static const unsigned int hscif3_ctrl_b_mux[] = { ++ HRTS3_N_B_MARK, HCTS3_N_B_MARK, + }; + + /* - I2C0 ------------------------------------------------------------------- */ +@@ -2093,13 +2090,13 @@ static const unsigned int pcie1_clkreq_n_mux[] = { + PCIE1_CLKREQ_N_MARK, + }; + +-/* - PWM0_A ------------------------------------------------------------------- */ +-static const unsigned int pwm0_a_pins[] = { +- /* PWM0_A */ ++/* - PWM0 ------------------------------------------------------------------- */ ++static const unsigned int pwm0_pins[] = { ++ /* PWM0 */ + RCAR_GP_PIN(1, 15), + }; +-static const unsigned int pwm0_a_mux[] = { +- PWM0_A_MARK, ++static const unsigned int pwm0_mux[] = { ++ PWM0_MARK, + }; + + /* - PWM1_A ------------------------------------------------------------------- */ +@@ -2120,13 +2117,13 @@ static const unsigned int pwm1_b_mux[] = { + PWM1_B_MARK, + }; + +-/* - PWM2_B ------------------------------------------------------------------- */ +-static const unsigned int pwm2_b_pins[] = { +- /* PWM2_B */ ++/* - PWM2 ------------------------------------------------------------------- */ ++static const unsigned int pwm2_pins[] = { ++ /* PWM2 */ + RCAR_GP_PIN(2, 14), + }; +-static const unsigned int pwm2_b_mux[] = { +- PWM2_B_MARK, ++static const unsigned int pwm2_mux[] = { ++ PWM2_MARK, + }; + + /* - PWM3_A ------------------------------------------------------------------- */ +@@ -2183,22 +2180,22 @@ static const unsigned int pwm7_mux[] = { + PWM7_MARK, + }; + +-/* - PWM8_A ------------------------------------------------------------------- */ +-static const unsigned int pwm8_a_pins[] = { +- /* PWM8_A */ ++/* - PWM8 ------------------------------------------------------------------- */ ++static const unsigned int pwm8_pins[] = { ++ /* PWM8 */ + RCAR_GP_PIN(1, 13), + }; +-static const unsigned int pwm8_a_mux[] = { +- PWM8_A_MARK, ++static const unsigned int pwm8_mux[] = { ++ PWM8_MARK, + }; + +-/* - PWM9_A ------------------------------------------------------------------- */ +-static const unsigned int pwm9_a_pins[] = { +- /* PWM9_A */ ++/* - PWM9 ------------------------------------------------------------------- */ ++static const unsigned int pwm9_pins[] = { ++ /* PWM9 */ + RCAR_GP_PIN(1, 14), + }; +-static const unsigned int pwm9_a_mux[] = { +- PWM9_A_MARK, ++static const unsigned int pwm9_mux[] = { ++ PWM9_MARK, + }; + + /* - QSPI0 ------------------------------------------------------------------ */ +@@ -2261,75 +2258,51 @@ static const unsigned int scif0_ctrl_mux[] = { + }; + + /* - SCIF1 ------------------------------------------------------------------ */ +-static const unsigned int scif1_data_pins[] = { +- /* RX1, TX1 */ ++static const unsigned int scif1_data_a_pins[] = { ++ /* RX1_A, TX1_A */ + RCAR_GP_PIN(0, 15), RCAR_GP_PIN(0, 14), + }; +-static const unsigned int scif1_data_mux[] = { +- RX1_MARK, TX1_MARK, ++static const unsigned int scif1_data_a_mux[] = { ++ RX1_A_MARK, TX1_A_MARK, + }; +-static const unsigned int scif1_clk_pins[] = { +- /* SCK1 */ ++static const unsigned int scif1_clk_a_pins[] = { ++ /* SCK1_A */ + RCAR_GP_PIN(0, 18), + }; +-static const unsigned int scif1_clk_mux[] = { +- SCK1_MARK, ++static const unsigned int scif1_clk_a_mux[] = { ++ SCK1_A_MARK, + }; +-static const unsigned int scif1_ctrl_pins[] = { +- /* RTS1_N, CTS1_N */ ++static const unsigned int scif1_ctrl_a_pins[] = { ++ /* RTS1_N_A, CTS1_N_A */ + RCAR_GP_PIN(0, 17), RCAR_GP_PIN(0, 16), + }; +-static const unsigned int scif1_ctrl_mux[] = { +- RTS1_N_MARK, CTS1_N_MARK, ++static const unsigned int scif1_ctrl_a_mux[] = { ++ RTS1_N_A_MARK, CTS1_N_A_MARK, + }; + +-/* - SCIF1_X ------------------------------------------------------------------ */ +-static const unsigned int scif1_data_x_pins[] = { +- /* RX1_X, TX1_X */ ++static const unsigned int scif1_data_b_pins[] = { ++ /* RX1_B, TX1_B */ + RCAR_GP_PIN(1, 7), RCAR_GP_PIN(1, 6), + }; +-static const unsigned int scif1_data_x_mux[] = { +- RX1_X_MARK, TX1_X_MARK, ++static const unsigned int scif1_data_b_mux[] = { ++ RX1_B_MARK, TX1_B_MARK, + }; +-static const unsigned int scif1_clk_x_pins[] = { +- /* SCK1_X */ ++static const unsigned int scif1_clk_b_pins[] = { ++ /* SCK1_B */ + RCAR_GP_PIN(1, 10), + }; +-static const unsigned int scif1_clk_x_mux[] = { +- SCK1_X_MARK, ++static const unsigned int scif1_clk_b_mux[] = { ++ SCK1_B_MARK, + }; +-static const unsigned int scif1_ctrl_x_pins[] = { +- /* RTS1_N_X, CTS1_N_X */ ++static const unsigned int scif1_ctrl_b_pins[] = { ++ /* RTS1_N_B, CTS1_N_B */ + RCAR_GP_PIN(1, 9), RCAR_GP_PIN(1, 8), + }; +-static const unsigned int scif1_ctrl_x_mux[] = { +- RTS1_N_X_MARK, CTS1_N_X_MARK, ++static const unsigned int scif1_ctrl_b_mux[] = { ++ RTS1_N_B_MARK, CTS1_N_B_MARK, + }; + + /* - SCIF3 ------------------------------------------------------------------ */ +-static const unsigned int scif3_data_pins[] = { +- /* RX3, TX3 */ +- RCAR_GP_PIN(1, 1), RCAR_GP_PIN(1, 0), +-}; +-static const unsigned int scif3_data_mux[] = { +- RX3_MARK, TX3_MARK, +-}; +-static const unsigned int scif3_clk_pins[] = { +- /* SCK3 */ +- RCAR_GP_PIN(1, 4), +-}; +-static const unsigned int scif3_clk_mux[] = { +- SCK3_MARK, +-}; +-static const unsigned int scif3_ctrl_pins[] = { +- /* RTS3_N, CTS3_N */ +- RCAR_GP_PIN(1, 2), RCAR_GP_PIN(1, 3), +-}; +-static const unsigned int scif3_ctrl_mux[] = { +- RTS3_N_MARK, CTS3_N_MARK, +-}; +- +-/* - SCIF3_A ------------------------------------------------------------------ */ + static const unsigned int scif3_data_a_pins[] = { + /* RX3_A, TX3_A */ + RCAR_GP_PIN(1, 27), RCAR_GP_PIN(1, 28), +@@ -2352,6 +2325,28 @@ static const unsigned int scif3_ctrl_a_mux[] = { + RTS3_N_A_MARK, CTS3_N_A_MARK, + }; + ++static const unsigned int scif3_data_b_pins[] = { ++ /* RX3_B, TX3_B */ ++ RCAR_GP_PIN(1, 1), RCAR_GP_PIN(1, 0), ++}; ++static const unsigned int scif3_data_b_mux[] = { ++ RX3_B_MARK, TX3_B_MARK, ++}; ++static const unsigned int scif3_clk_b_pins[] = { ++ /* SCK3_B */ ++ RCAR_GP_PIN(1, 4), ++}; ++static const unsigned int scif3_clk_b_mux[] = { ++ SCK3_B_MARK, ++}; ++static const unsigned int scif3_ctrl_b_pins[] = { ++ /* RTS3_N_B, CTS3_N_B */ ++ RCAR_GP_PIN(1, 2), RCAR_GP_PIN(1, 3), ++}; ++static const unsigned int scif3_ctrl_b_mux[] = { ++ RTS3_N_B_MARK, CTS3_N_B_MARK, ++}; ++ + /* - SCIF4 ------------------------------------------------------------------ */ + static const unsigned int scif4_data_pins[] = { + /* RX4, TX4 */ +@@ -2408,64 +2403,63 @@ static const unsigned int ssi_ctrl_mux[] = { + SSI_SCK_MARK, SSI_WS_MARK, + }; + +-/* - TPU ------------------------------------------------------------------- */ +-static const unsigned int tpu_to0_pins[] = { +- /* TPU0TO0 */ ++/* - TPU -------------------------------------------------------------------- */ ++static const unsigned int tpu_to0_a_pins[] = { ++ /* TPU0TO0_A */ + RCAR_GP_PIN(2, 8), + }; +-static const unsigned int tpu_to0_mux[] = { +- TPU0TO0_MARK, ++static const unsigned int tpu_to0_a_mux[] = { ++ TPU0TO0_A_MARK, + }; +-static const unsigned int tpu_to1_pins[] = { +- /* TPU0TO1 */ ++static const unsigned int tpu_to1_a_pins[] = { ++ /* TPU0TO1_A */ + RCAR_GP_PIN(2, 7), + }; +-static const unsigned int tpu_to1_mux[] = { +- TPU0TO1_MARK, ++static const unsigned int tpu_to1_a_mux[] = { ++ TPU0TO1_A_MARK, + }; +-static const unsigned int tpu_to2_pins[] = { +- /* TPU0TO2 */ ++static const unsigned int tpu_to2_a_pins[] = { ++ /* TPU0TO2_A */ + RCAR_GP_PIN(2, 12), + }; +-static const unsigned int tpu_to2_mux[] = { +- TPU0TO2_MARK, ++static const unsigned int tpu_to2_a_mux[] = { ++ TPU0TO2_A_MARK, + }; +-static const unsigned int tpu_to3_pins[] = { +- /* TPU0TO3 */ ++static const unsigned int tpu_to3_a_pins[] = { ++ /* TPU0TO3_A */ + RCAR_GP_PIN(2, 13), + }; +-static const unsigned int tpu_to3_mux[] = { +- TPU0TO3_MARK, ++static const unsigned int tpu_to3_a_mux[] = { ++ TPU0TO3_A_MARK, + }; + +-/* - TPU_A ------------------------------------------------------------------- */ +-static const unsigned int tpu_to0_a_pins[] = { +- /* TPU0TO0_A */ ++static const unsigned int tpu_to0_b_pins[] = { ++ /* TPU0TO0_B */ + RCAR_GP_PIN(1, 25), + }; +-static const unsigned int tpu_to0_a_mux[] = { +- TPU0TO0_A_MARK, ++static const unsigned int tpu_to0_b_mux[] = { ++ TPU0TO0_B_MARK, + }; +-static const unsigned int tpu_to1_a_pins[] = { +- /* TPU0TO1_A */ ++static const unsigned int tpu_to1_b_pins[] = { ++ /* TPU0TO1_B */ + RCAR_GP_PIN(1, 26), + }; +-static const unsigned int tpu_to1_a_mux[] = { +- TPU0TO1_A_MARK, ++static const unsigned int tpu_to1_b_mux[] = { ++ TPU0TO1_B_MARK, + }; +-static const unsigned int tpu_to2_a_pins[] = { +- /* TPU0TO2_A */ ++static const unsigned int tpu_to2_b_pins[] = { ++ /* TPU0TO2_B */ + RCAR_GP_PIN(2, 0), + }; +-static const unsigned int tpu_to2_a_mux[] = { +- TPU0TO2_A_MARK, ++static const unsigned int tpu_to2_b_mux[] = { ++ TPU0TO2_B_MARK, + }; +-static const unsigned int tpu_to3_a_pins[] = { +- /* TPU0TO3_A */ ++static const unsigned int tpu_to3_b_pins[] = { ++ /* TPU0TO3_B */ + RCAR_GP_PIN(2, 1), + }; +-static const unsigned int tpu_to3_a_mux[] = { +- TPU0TO3_A_MARK, ++static const unsigned int tpu_to3_b_mux[] = { ++ TPU0TO3_B_MARK, + }; + + /* - TSN0 ------------------------------------------------ */ +@@ -2578,8 +2572,8 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { + SH_PFC_PIN_GROUP(canfd2_data), + SH_PFC_PIN_GROUP(canfd3_data), + SH_PFC_PIN_GROUP(canfd4_data), +- SH_PFC_PIN_GROUP(canfd5_data), /* suffix might be updated */ +- SH_PFC_PIN_GROUP(canfd5_data_b), /* suffix might be updated */ ++ SH_PFC_PIN_GROUP(canfd5_data_a), ++ SH_PFC_PIN_GROUP(canfd5_data_b), + SH_PFC_PIN_GROUP(canfd6_data), + SH_PFC_PIN_GROUP(canfd7_data), + SH_PFC_PIN_GROUP(can_clk), +@@ -2587,21 +2581,21 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { + SH_PFC_PIN_GROUP(hscif0_data), + SH_PFC_PIN_GROUP(hscif0_clk), + SH_PFC_PIN_GROUP(hscif0_ctrl), +- SH_PFC_PIN_GROUP(hscif1_data), /* suffix might be updated */ +- SH_PFC_PIN_GROUP(hscif1_clk), /* suffix might be updated */ +- SH_PFC_PIN_GROUP(hscif1_ctrl), /* suffix might be updated */ +- SH_PFC_PIN_GROUP(hscif1_data_x), /* suffix might be updated */ +- SH_PFC_PIN_GROUP(hscif1_clk_x), /* suffix might be updated */ +- SH_PFC_PIN_GROUP(hscif1_ctrl_x), /* suffix might be updated */ ++ SH_PFC_PIN_GROUP(hscif1_data_a), ++ SH_PFC_PIN_GROUP(hscif1_clk_a), ++ SH_PFC_PIN_GROUP(hscif1_ctrl_a), ++ SH_PFC_PIN_GROUP(hscif1_data_b), ++ SH_PFC_PIN_GROUP(hscif1_clk_b), ++ SH_PFC_PIN_GROUP(hscif1_ctrl_b), + SH_PFC_PIN_GROUP(hscif2_data), + SH_PFC_PIN_GROUP(hscif2_clk), + SH_PFC_PIN_GROUP(hscif2_ctrl), +- SH_PFC_PIN_GROUP(hscif3_data), /* suffix might be updated */ +- SH_PFC_PIN_GROUP(hscif3_clk), /* suffix might be updated */ +- SH_PFC_PIN_GROUP(hscif3_ctrl), /* suffix might be updated */ +- SH_PFC_PIN_GROUP(hscif3_data_a), /* suffix might be updated */ +- SH_PFC_PIN_GROUP(hscif3_clk_a), /* suffix might be updated */ +- SH_PFC_PIN_GROUP(hscif3_ctrl_a), /* suffix might be updated */ ++ SH_PFC_PIN_GROUP(hscif3_data_a), ++ SH_PFC_PIN_GROUP(hscif3_clk_a), ++ SH_PFC_PIN_GROUP(hscif3_ctrl_a), ++ SH_PFC_PIN_GROUP(hscif3_data_b), ++ SH_PFC_PIN_GROUP(hscif3_clk_b), ++ SH_PFC_PIN_GROUP(hscif3_ctrl_b), + + SH_PFC_PIN_GROUP(i2c0), + SH_PFC_PIN_GROUP(i2c1), +@@ -2663,18 +2657,18 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { + SH_PFC_PIN_GROUP(pcie0_clkreq_n), + SH_PFC_PIN_GROUP(pcie1_clkreq_n), + +- SH_PFC_PIN_GROUP(pwm0_a), /* suffix might be updated */ ++ SH_PFC_PIN_GROUP(pwm0), + SH_PFC_PIN_GROUP(pwm1_a), + SH_PFC_PIN_GROUP(pwm1_b), +- SH_PFC_PIN_GROUP(pwm2_b), /* suffix might be updated */ ++ SH_PFC_PIN_GROUP(pwm2), + SH_PFC_PIN_GROUP(pwm3_a), + SH_PFC_PIN_GROUP(pwm3_b), + SH_PFC_PIN_GROUP(pwm4), + SH_PFC_PIN_GROUP(pwm5), + SH_PFC_PIN_GROUP(pwm6), + SH_PFC_PIN_GROUP(pwm7), +- SH_PFC_PIN_GROUP(pwm8_a), /* suffix might be updated */ +- SH_PFC_PIN_GROUP(pwm9_a), /* suffix might be updated */ ++ SH_PFC_PIN_GROUP(pwm8), ++ SH_PFC_PIN_GROUP(pwm9), + + SH_PFC_PIN_GROUP(qspi0_ctrl), + BUS_DATA_PIN_GROUP(qspi0_data, 2), +@@ -2686,18 +2680,18 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { + SH_PFC_PIN_GROUP(scif0_data), + SH_PFC_PIN_GROUP(scif0_clk), + SH_PFC_PIN_GROUP(scif0_ctrl), +- SH_PFC_PIN_GROUP(scif1_data), /* suffix might be updated */ +- SH_PFC_PIN_GROUP(scif1_clk), /* suffix might be updated */ +- SH_PFC_PIN_GROUP(scif1_ctrl), /* suffix might be updated */ +- SH_PFC_PIN_GROUP(scif1_data_x), /* suffix might be updated */ +- SH_PFC_PIN_GROUP(scif1_clk_x), /* suffix might be updated */ +- SH_PFC_PIN_GROUP(scif1_ctrl_x), /* suffix might be updated */ +- SH_PFC_PIN_GROUP(scif3_data), /* suffix might be updated */ +- SH_PFC_PIN_GROUP(scif3_clk), /* suffix might be updated */ +- SH_PFC_PIN_GROUP(scif3_ctrl), /* suffix might be updated */ +- SH_PFC_PIN_GROUP(scif3_data_a), /* suffix might be updated */ +- SH_PFC_PIN_GROUP(scif3_clk_a), /* suffix might be updated */ +- SH_PFC_PIN_GROUP(scif3_ctrl_a), /* suffix might be updated */ ++ SH_PFC_PIN_GROUP(scif1_data_a), ++ SH_PFC_PIN_GROUP(scif1_clk_a), ++ SH_PFC_PIN_GROUP(scif1_ctrl_a), ++ SH_PFC_PIN_GROUP(scif1_data_b), ++ SH_PFC_PIN_GROUP(scif1_clk_b), ++ SH_PFC_PIN_GROUP(scif1_ctrl_b), ++ SH_PFC_PIN_GROUP(scif3_data_a), ++ SH_PFC_PIN_GROUP(scif3_clk_a), ++ SH_PFC_PIN_GROUP(scif3_ctrl_a), ++ SH_PFC_PIN_GROUP(scif3_data_b), ++ SH_PFC_PIN_GROUP(scif3_clk_b), ++ SH_PFC_PIN_GROUP(scif3_ctrl_b), + SH_PFC_PIN_GROUP(scif4_data), + SH_PFC_PIN_GROUP(scif4_clk), + SH_PFC_PIN_GROUP(scif4_ctrl), +@@ -2707,14 +2701,14 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { + SH_PFC_PIN_GROUP(ssi_data), + SH_PFC_PIN_GROUP(ssi_ctrl), + +- SH_PFC_PIN_GROUP(tpu_to0), /* suffix might be updated */ +- SH_PFC_PIN_GROUP(tpu_to0_a), /* suffix might be updated */ +- SH_PFC_PIN_GROUP(tpu_to1), /* suffix might be updated */ +- SH_PFC_PIN_GROUP(tpu_to1_a), /* suffix might be updated */ +- SH_PFC_PIN_GROUP(tpu_to2), /* suffix might be updated */ +- SH_PFC_PIN_GROUP(tpu_to2_a), /* suffix might be updated */ +- SH_PFC_PIN_GROUP(tpu_to3), /* suffix might be updated */ +- SH_PFC_PIN_GROUP(tpu_to3_a), /* suffix might be updated */ ++ SH_PFC_PIN_GROUP(tpu_to0_a), ++ SH_PFC_PIN_GROUP(tpu_to0_b), ++ SH_PFC_PIN_GROUP(tpu_to1_a), ++ SH_PFC_PIN_GROUP(tpu_to1_b), ++ SH_PFC_PIN_GROUP(tpu_to2_a), ++ SH_PFC_PIN_GROUP(tpu_to2_b), ++ SH_PFC_PIN_GROUP(tpu_to3_a), ++ SH_PFC_PIN_GROUP(tpu_to3_b), + + SH_PFC_PIN_GROUP(tsn0_link), + SH_PFC_PIN_GROUP(tsn0_phy_int), +@@ -2788,8 +2782,7 @@ static const char * const canfd4_groups[] = { + }; + + static const char * const canfd5_groups[] = { +- /* suffix might be updated */ +- "canfd5_data", ++ "canfd5_data_a", + "canfd5_data_b", + }; + +@@ -2812,13 +2805,12 @@ static const char * const hscif0_groups[] = { + }; + + static const char * const hscif1_groups[] = { +- /* suffix might be updated */ +- "hscif1_data", +- "hscif1_clk", +- "hscif1_ctrl", +- "hscif1_data_x", +- "hscif1_clk_x", +- "hscif1_ctrl_x", ++ "hscif1_data_a", ++ "hscif1_clk_a", ++ "hscif1_ctrl_a", ++ "hscif1_data_b", ++ "hscif1_clk_b", ++ "hscif1_ctrl_b", + }; + + static const char * const hscif2_groups[] = { +@@ -2828,13 +2820,12 @@ static const char * const hscif2_groups[] = { + }; + + static const char * const hscif3_groups[] = { +- /* suffix might be updated */ +- "hscif3_data", +- "hscif3_clk", +- "hscif3_ctrl", + "hscif3_data_a", + "hscif3_clk_a", + "hscif3_ctrl_a", ++ "hscif3_data_b", ++ "hscif3_clk_b", ++ "hscif3_ctrl_b", + }; + + static const char * const i2c0_groups[] = { +@@ -2931,8 +2922,7 @@ static const char * const pcie_groups[] = { + }; + + static const char * const pwm0_groups[] = { +- /* suffix might be updated */ +- "pwm0_a", ++ "pwm0", + }; + + static const char * const pwm1_groups[] = { +@@ -2941,8 +2931,7 @@ static const char * const pwm1_groups[] = { + }; + + static const char * const pwm2_groups[] = { +- /* suffix might be updated */ +- "pwm2_b", ++ "pwm2", + }; + + static const char * const pwm3_groups[] = { +@@ -2967,13 +2956,11 @@ static const char * const pwm7_groups[] = { + }; + + static const char * const pwm8_groups[] = { +- /* suffix might be updated */ +- "pwm8_a", ++ "pwm8", + }; + + static const char * const pwm9_groups[] = { +- /* suffix might be updated */ +- "pwm9_a", ++ "pwm9", + }; + + static const char * const qspi0_groups[] = { +@@ -2995,23 +2982,21 @@ static const char * const scif0_groups[] = { + }; + + static const char * const scif1_groups[] = { +- /* suffix might be updated */ +- "scif1_data", +- "scif1_clk", +- "scif1_ctrl", +- "scif1_data_x", +- "scif1_clk_x", +- "scif1_ctrl_x", ++ "scif1_data_a", ++ "scif1_clk_a", ++ "scif1_ctrl_a", ++ "scif1_data_b", ++ "scif1_clk_b", ++ "scif1_ctrl_b", + }; + + static const char * const scif3_groups[] = { +- /* suffix might be updated */ +- "scif3_data", +- "scif3_clk", +- "scif3_ctrl", + "scif3_data_a", + "scif3_clk_a", + "scif3_ctrl_a", ++ "scif3_data_b", ++ "scif3_clk_b", ++ "scif3_ctrl_b", + }; + + static const char * const scif4_groups[] = { +@@ -3034,15 +3019,14 @@ static const char * const ssi_groups[] = { + }; + + static const char * const tpu_groups[] = { +- /* suffix might be updated */ +- "tpu_to0", + "tpu_to0_a", +- "tpu_to1", ++ "tpu_to0_b", + "tpu_to1_a", +- "tpu_to2", ++ "tpu_to1_b", + "tpu_to2_a", +- "tpu_to3", ++ "tpu_to2_b", + "tpu_to3_a", ++ "tpu_to3_b", + }; + + static const char * const tsn0_groups[] = { +diff --git a/drivers/pinctrl/ti/pinctrl-ti-iodelay.c b/drivers/pinctrl/ti/pinctrl-ti-iodelay.c +index c1477f6578393..5370bbdf2e1a1 100644 +--- a/drivers/pinctrl/ti/pinctrl-ti-iodelay.c ++++ b/drivers/pinctrl/ti/pinctrl-ti-iodelay.c +@@ -878,7 +878,7 @@ static int ti_iodelay_probe(struct platform_device *pdev) + iod->desc.name = dev_name(dev); + iod->desc.owner = THIS_MODULE; + +- ret = pinctrl_register_and_init(&iod->desc, dev, iod, &iod->pctl); ++ ret = devm_pinctrl_register_and_init(dev, &iod->desc, iod, &iod->pctl); + if (ret) { + dev_err(dev, "Failed to register pinctrl\n"); + goto exit_out; +@@ -886,7 +886,11 @@ static int ti_iodelay_probe(struct platform_device *pdev) + + platform_set_drvdata(pdev, iod); + +- return pinctrl_enable(iod->pctl); ++ ret = pinctrl_enable(iod->pctl); ++ if (ret) ++ goto exit_out; ++ ++ return 0; + + exit_out: + of_node_put(np); +@@ -903,12 +907,6 @@ static int ti_iodelay_remove(struct platform_device *pdev) + { + struct ti_iodelay_device *iod = platform_get_drvdata(pdev); + +- if (!iod) +- return 0; +- +- if (iod->pctl) +- pinctrl_unregister(iod->pctl); +- + ti_iodelay_pinconf_deinit_dev(iod); + + /* Expect other allocations to be freed by devm */ +diff --git a/drivers/platform/chrome/cros_ec_debugfs.c b/drivers/platform/chrome/cros_ec_debugfs.c +index c876120e0ebc9..793c8c4bf35ba 100644 +--- a/drivers/platform/chrome/cros_ec_debugfs.c ++++ b/drivers/platform/chrome/cros_ec_debugfs.c +@@ -329,6 +329,7 @@ static int ec_read_version_supported(struct cros_ec_dev *ec) + if (!msg) + return 0; + ++ msg->version = 1; + msg->command = EC_CMD_GET_CMD_VERSIONS + ec->cmd_offset; + msg->outsize = sizeof(*params); + msg->insize = sizeof(*response); +diff --git a/drivers/platform/mips/cpu_hwmon.c b/drivers/platform/mips/cpu_hwmon.c +index d8c5f9195f85f..2ac2f31090f96 100644 +--- a/drivers/platform/mips/cpu_hwmon.c ++++ b/drivers/platform/mips/cpu_hwmon.c +@@ -139,6 +139,9 @@ static int __init loongson_hwmon_init(void) + csr_temp_enable = csr_readl(LOONGSON_CSR_FEATURES) & + LOONGSON_CSRF_TEMP; + ++ if (!csr_temp_enable && !loongson_chiptemp[0]) ++ return -ENODEV; ++ + nr_packages = loongson_sysconf.nr_cpus / + loongson_sysconf.cores_per_package; + +diff --git a/drivers/pwm/pwm-atmel-tcb.c b/drivers/pwm/pwm-atmel-tcb.c +index c00dd37c5fbd8..06df8c6127416 100644 +--- a/drivers/pwm/pwm-atmel-tcb.c ++++ b/drivers/pwm/pwm-atmel-tcb.c +@@ -82,7 +82,8 @@ static int atmel_tcb_pwm_request(struct pwm_chip *chip, + tcbpwm->period = 0; + tcbpwm->div = 0; + +- spin_lock(&tcbpwmc->lock); ++ guard(spinlock)(&tcbpwmc->lock); ++ + regmap_read(tcbpwmc->regmap, ATMEL_TC_REG(tcbpwmc->channel, CMR), &cmr); + /* + * Get init config from Timer Counter registers if +@@ -108,7 +109,6 @@ static int atmel_tcb_pwm_request(struct pwm_chip *chip, + + cmr |= ATMEL_TC_WAVE | ATMEL_TC_WAVESEL_UP_AUTO | ATMEL_TC_EEVT_XC0; + regmap_write(tcbpwmc->regmap, ATMEL_TC_REG(tcbpwmc->channel, CMR), cmr); +- spin_unlock(&tcbpwmc->lock); + + return 0; + } +@@ -138,7 +138,6 @@ static void atmel_tcb_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm, + if (tcbpwm->duty == 0) + polarity = !polarity; + +- spin_lock(&tcbpwmc->lock); + regmap_read(tcbpwmc->regmap, ATMEL_TC_REG(tcbpwmc->channel, CMR), &cmr); + + /* flush old setting and set the new one */ +@@ -173,8 +172,6 @@ static void atmel_tcb_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm, + ATMEL_TC_SWTRG); + tcbpwmc->bkup.enabled = 0; + } +- +- spin_unlock(&tcbpwmc->lock); + } + + static int atmel_tcb_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm, +@@ -195,7 +192,6 @@ static int atmel_tcb_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm, + if (tcbpwm->duty == 0) + polarity = !polarity; + +- spin_lock(&tcbpwmc->lock); + regmap_read(tcbpwmc->regmap, ATMEL_TC_REG(tcbpwmc->channel, CMR), &cmr); + + /* flush old setting and set the new one */ +@@ -257,7 +253,6 @@ static int atmel_tcb_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm, + regmap_write(tcbpwmc->regmap, ATMEL_TC_REG(tcbpwmc->channel, CCR), + ATMEL_TC_SWTRG | ATMEL_TC_CLKEN); + tcbpwmc->bkup.enabled = 1; +- spin_unlock(&tcbpwmc->lock); + return 0; + } + +@@ -342,9 +337,12 @@ static int atmel_tcb_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, + static int atmel_tcb_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, + const struct pwm_state *state) + { ++ struct atmel_tcb_pwm_chip *tcbpwmc = to_tcb_chip(chip); + int duty_cycle, period; + int ret; + ++ guard(spinlock)(&tcbpwmc->lock); ++ + if (!state->enabled) { + atmel_tcb_pwm_disable(chip, pwm, state->polarity); + return 0; +diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c +index 9bdab6c24fbaf..b91a14c895bea 100644 +--- a/drivers/pwm/pwm-stm32.c ++++ b/drivers/pwm/pwm-stm32.c +@@ -456,8 +456,9 @@ static int stm32_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, + + enabled = pwm->state.enabled; + +- if (enabled && !state->enabled) { +- stm32_pwm_disable(priv, pwm->hwpwm); ++ if (!state->enabled) { ++ if (enabled) ++ stm32_pwm_disable(priv, pwm->hwpwm); + return 0; + } + +diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c +index 8bb293b9f327c..cfee164dd645c 100644 +--- a/drivers/remoteproc/imx_rproc.c ++++ b/drivers/remoteproc/imx_rproc.c +@@ -729,31 +729,37 @@ static int imx_rproc_addr_init(struct imx_rproc *priv, + struct resource res; + + node = of_parse_phandle(np, "memory-region", a); ++ if (!node) ++ continue; + /* Not map vdevbuffer, vdevring region */ + if (!strncmp(node->name, "vdev", strlen("vdev"))) { + of_node_put(node); + continue; + } + err = of_address_to_resource(node, 0, &res); +- of_node_put(node); + if (err) { + dev_err(dev, "unable to resolve memory region\n"); ++ of_node_put(node); + return err; + } + +- if (b >= IMX_RPROC_MEM_MAX) ++ if (b >= IMX_RPROC_MEM_MAX) { ++ of_node_put(node); + break; ++ } + + /* Not use resource version, because we might share region */ + priv->mem[b].cpu_addr = devm_ioremap_wc(&pdev->dev, res.start, resource_size(&res)); + if (!priv->mem[b].cpu_addr) { + dev_err(dev, "failed to remap %pr\n", &res); ++ of_node_put(node); + return -ENOMEM; + } + priv->mem[b].sys_addr = res.start; + priv->mem[b].size = resource_size(&res); + if (!strcmp(node->name, "rsc-table")) + priv->rsc_table = priv->mem[b].cpu_addr; ++ of_node_put(node); + b++; + } + +diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c +index 61794c9c080fb..c786badf08fa6 100644 +--- a/drivers/remoteproc/stm32_rproc.c ++++ b/drivers/remoteproc/stm32_rproc.c +@@ -294,7 +294,7 @@ static void stm32_rproc_mb_vq_work(struct work_struct *work) + + mutex_lock(&rproc->lock); + +- if (rproc->state != RPROC_RUNNING) ++ if (rproc->state != RPROC_RUNNING && rproc->state != RPROC_ATTACHED) + goto unlock_mutex; + + if (rproc_vq_interrupt(rproc, mb->vq_id) == IRQ_NONE) +diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c +index 1b63111cdda2e..0b23706d9fd3c 100644 +--- a/drivers/rtc/interface.c ++++ b/drivers/rtc/interface.c +@@ -274,10 +274,9 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) + return err; + + /* full-function RTCs won't have such missing fields */ +- if (rtc_valid_tm(&alarm->time) == 0) { +- rtc_add_offset(rtc, &alarm->time); +- return 0; +- } ++ err = rtc_valid_tm(&alarm->time); ++ if (!err) ++ goto done; + + /* get the "after" timestamp, to detect wrapped fields */ + err = rtc_read_time(rtc, &now); +@@ -379,6 +378,8 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) + if (err && alarm->enabled) + dev_warn(&rtc->dev, "invalid alarm value: %ptR\n", + &alarm->time); ++ else ++ rtc_add_offset(rtc, &alarm->time); + + return err; + } +diff --git a/drivers/rtc/rtc-abx80x.c b/drivers/rtc/rtc-abx80x.c +index fde2b8054c2ea..1298962402ff4 100644 +--- a/drivers/rtc/rtc-abx80x.c ++++ b/drivers/rtc/rtc-abx80x.c +@@ -705,14 +705,18 @@ static int abx80x_nvmem_xfer(struct abx80x_priv *priv, unsigned int offset, + if (ret) + return ret; + +- if (write) ++ if (write) { + ret = i2c_smbus_write_i2c_block_data(priv->client, reg, + len, val); +- else ++ if (ret) ++ return ret; ++ } else { + ret = i2c_smbus_read_i2c_block_data(priv->client, reg, + len, val); +- if (ret) +- return ret; ++ if (ret <= 0) ++ return ret ? ret : -EIO; ++ len = ret; ++ } + + offset += len; + val += len; +diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c +index 7d99cd2c37a0b..35dca2accbb8d 100644 +--- a/drivers/rtc/rtc-cmos.c ++++ b/drivers/rtc/rtc-cmos.c +@@ -643,11 +643,10 @@ static int cmos_nvram_read(void *priv, unsigned int off, void *val, + size_t count) + { + unsigned char *buf = val; +- int retval; + + off += NVRAM_OFFSET; + spin_lock_irq(&rtc_lock); +- for (retval = 0; count; count--, off++, retval++) { ++ for (; count; count--, off++) { + if (off < 128) + *buf++ = CMOS_READ(off); + else if (can_bank2) +@@ -657,7 +656,7 @@ static int cmos_nvram_read(void *priv, unsigned int off, void *val, + } + spin_unlock_irq(&rtc_lock); + +- return retval; ++ return count ? -EIO : 0; + } + + static int cmos_nvram_write(void *priv, unsigned int off, void *val, +@@ -665,7 +664,6 @@ static int cmos_nvram_write(void *priv, unsigned int off, void *val, + { + struct cmos_rtc *cmos = priv; + unsigned char *buf = val; +- int retval; + + /* NOTE: on at least PCs and Ataris, the boot firmware uses a + * checksum on part of the NVRAM data. That's currently ignored +@@ -674,7 +672,7 @@ static int cmos_nvram_write(void *priv, unsigned int off, void *val, + */ + off += NVRAM_OFFSET; + spin_lock_irq(&rtc_lock); +- for (retval = 0; count; count--, off++, retval++) { ++ for (; count; count--, off++) { + /* don't trash RTC registers */ + if (off == cmos->day_alrm + || off == cmos->mon_alrm +@@ -689,7 +687,7 @@ static int cmos_nvram_write(void *priv, unsigned int off, void *val, + } + spin_unlock_irq(&rtc_lock); + +- return retval; ++ return count ? -EIO : 0; + } + + /*----------------------------------------------------------------*/ +diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c +index e50c23ee1646a..206f96b90f58b 100644 +--- a/drivers/rtc/rtc-isl1208.c ++++ b/drivers/rtc/rtc-isl1208.c +@@ -775,14 +775,13 @@ static int isl1208_nvmem_read(void *priv, unsigned int off, void *buf, + { + struct isl1208_state *isl1208 = priv; + struct i2c_client *client = to_i2c_client(isl1208->rtc->dev.parent); +- int ret; + + /* nvmem sanitizes offset/count for us, but count==0 is possible */ + if (!count) + return count; +- ret = isl1208_i2c_read_regs(client, ISL1208_REG_USR1 + off, buf, ++ ++ return isl1208_i2c_read_regs(client, ISL1208_REG_USR1 + off, buf, + count); +- return ret == 0 ? count : ret; + } + + static int isl1208_nvmem_write(void *priv, unsigned int off, void *buf, +@@ -790,15 +789,13 @@ static int isl1208_nvmem_write(void *priv, unsigned int off, void *buf, + { + struct isl1208_state *isl1208 = priv; + struct i2c_client *client = to_i2c_client(isl1208->rtc->dev.parent); +- int ret; + + /* nvmem sanitizes off/count for us, but count==0 is possible */ + if (!count) + return count; +- ret = isl1208_i2c_set_regs(client, ISL1208_REG_USR1 + off, buf, +- count); + +- return ret == 0 ? count : ret; ++ return isl1208_i2c_set_regs(client, ISL1208_REG_USR1 + off, buf, ++ count); + } + + static const struct nvmem_config isl1208_nvmem_config = { +diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c +index c4e36650c4264..91522dba9fd98 100644 +--- a/drivers/s390/block/dasd_devmap.c ++++ b/drivers/s390/block/dasd_devmap.c +@@ -2258,13 +2258,19 @@ static ssize_t dasd_copy_pair_store(struct device *dev, + + /* allocate primary devmap if needed */ + prim_devmap = dasd_find_busid(prim_busid); +- if (IS_ERR(prim_devmap)) ++ if (IS_ERR(prim_devmap)) { + prim_devmap = dasd_add_busid(prim_busid, DASD_FEATURE_DEFAULT); ++ if (IS_ERR(prim_devmap)) ++ return PTR_ERR(prim_devmap); ++ } + + /* allocate secondary devmap if needed */ + sec_devmap = dasd_find_busid(sec_busid); +- if (IS_ERR(sec_devmap)) ++ if (IS_ERR(sec_devmap)) { + sec_devmap = dasd_add_busid(sec_busid, DASD_FEATURE_DEFAULT); ++ if (IS_ERR(sec_devmap)) ++ return PTR_ERR(sec_devmap); ++ } + + /* setting copy relation is only allowed for offline secondary */ + if (sec_devmap->device) +diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c +index 79b45ea5fdb5e..8123062ec2faf 100644 +--- a/drivers/scsi/lpfc/lpfc_attr.c ++++ b/drivers/scsi/lpfc/lpfc_attr.c +@@ -1904,6 +1904,11 @@ lpfc_xcvr_data_show(struct device *dev, struct device_attribute *attr, + + /* Get transceiver information */ + rdp_context = kmalloc(sizeof(*rdp_context), GFP_KERNEL); ++ if (!rdp_context) { ++ len = scnprintf(buf, PAGE_SIZE - len, ++ "SPF info NA: alloc failure\n"); ++ return len; ++ } + + rc = lpfc_get_sfp_info_wait(phba, rdp_context); + if (rc) { +diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c +index 93703ab6ce037..0a01575ab06dd 100644 +--- a/drivers/scsi/lpfc/lpfc_hbadisc.c ++++ b/drivers/scsi/lpfc/lpfc_hbadisc.c +@@ -5782,7 +5782,7 @@ lpfc_setup_disc_node(struct lpfc_vport *vport, uint32_t did) + return NULL; + + if (ndlp->nlp_state > NLP_STE_UNUSED_NODE && +- ndlp->nlp_state < NLP_STE_PRLI_ISSUE) { ++ ndlp->nlp_state <= NLP_STE_PRLI_ISSUE) { + lpfc_disc_state_machine(vport, ndlp, NULL, + NLP_EVT_DEVICE_RECOVERY); + } +diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c +index 19bb64bdd88b1..52dc9604f5674 100644 +--- a/drivers/scsi/qla2xxx/qla_bsg.c ++++ b/drivers/scsi/qla2xxx/qla_bsg.c +@@ -324,7 +324,7 @@ qla2x00_process_els(struct bsg_job *bsg_job) + "request_sg_cnt=%x reply_sg_cnt=%x.\n", + bsg_job->request_payload.sg_cnt, + bsg_job->reply_payload.sg_cnt); +- rval = -EPERM; ++ rval = -ENOBUFS; + goto done; + } + +@@ -3059,17 +3059,61 @@ qla24xx_bsg_request(struct bsg_job *bsg_job) + return ret; + } + +-int +-qla24xx_bsg_timeout(struct bsg_job *bsg_job) ++static bool qla_bsg_found(struct qla_qpair *qpair, struct bsg_job *bsg_job) + { ++ bool found = false; + struct fc_bsg_reply *bsg_reply = bsg_job->reply; + scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job)); + struct qla_hw_data *ha = vha->hw; +- srb_t *sp; +- int cnt, que; ++ srb_t *sp = NULL; ++ int cnt; + unsigned long flags; + struct req_que *req; + ++ spin_lock_irqsave(qpair->qp_lock_ptr, flags); ++ req = qpair->req; ++ ++ for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) { ++ sp = req->outstanding_cmds[cnt]; ++ if (sp && ++ (sp->type == SRB_CT_CMD || ++ sp->type == SRB_ELS_CMD_HST || ++ sp->type == SRB_ELS_CMD_HST_NOLOGIN) && ++ sp->u.bsg_job == bsg_job) { ++ req->outstanding_cmds[cnt] = NULL; ++ spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); ++ ++ if (!ha->flags.eeh_busy && ha->isp_ops->abort_command(sp)) { ++ ql_log(ql_log_warn, vha, 0x7089, ++ "mbx abort_command failed.\n"); ++ bsg_reply->result = -EIO; ++ } else { ++ ql_dbg(ql_dbg_user, vha, 0x708a, ++ "mbx abort_command success.\n"); ++ bsg_reply->result = 0; ++ } ++ /* ref: INIT */ ++ kref_put(&sp->cmd_kref, qla2x00_sp_release); ++ ++ found = true; ++ goto done; ++ } ++ } ++ spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); ++ ++done: ++ return found; ++} ++ ++int ++qla24xx_bsg_timeout(struct bsg_job *bsg_job) ++{ ++ struct fc_bsg_reply *bsg_reply = bsg_job->reply; ++ scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job)); ++ struct qla_hw_data *ha = vha->hw; ++ int i; ++ struct qla_qpair *qpair; ++ + ql_log(ql_log_info, vha, 0x708b, "%s CMD timeout. bsg ptr %p.\n", + __func__, bsg_job); + +@@ -3079,48 +3123,22 @@ qla24xx_bsg_timeout(struct bsg_job *bsg_job) + qla_pci_set_eeh_busy(vha); + } + ++ if (qla_bsg_found(ha->base_qpair, bsg_job)) ++ goto done; ++ + /* find the bsg job from the active list of commands */ +- spin_lock_irqsave(&ha->hardware_lock, flags); +- for (que = 0; que < ha->max_req_queues; que++) { +- req = ha->req_q_map[que]; +- if (!req) ++ for (i = 0; i < ha->max_qpairs; i++) { ++ qpair = vha->hw->queue_pair_map[i]; ++ if (!qpair) + continue; +- +- for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) { +- sp = req->outstanding_cmds[cnt]; +- if (sp && +- (sp->type == SRB_CT_CMD || +- sp->type == SRB_ELS_CMD_HST || +- sp->type == SRB_ELS_CMD_HST_NOLOGIN || +- sp->type == SRB_FXIOCB_BCMD) && +- sp->u.bsg_job == bsg_job) { +- req->outstanding_cmds[cnt] = NULL; +- spin_unlock_irqrestore(&ha->hardware_lock, flags); +- +- if (!ha->flags.eeh_busy && ha->isp_ops->abort_command(sp)) { +- ql_log(ql_log_warn, vha, 0x7089, +- "mbx abort_command failed.\n"); +- bsg_reply->result = -EIO; +- } else { +- ql_dbg(ql_dbg_user, vha, 0x708a, +- "mbx abort_command success.\n"); +- bsg_reply->result = 0; +- } +- spin_lock_irqsave(&ha->hardware_lock, flags); +- goto done; +- +- } +- } ++ if (qla_bsg_found(qpair, bsg_job)) ++ goto done; + } +- spin_unlock_irqrestore(&ha->hardware_lock, flags); ++ + ql_log(ql_log_info, vha, 0x708b, "SRB not found to abort.\n"); + bsg_reply->result = -ENXIO; +- return 0; + + done: +- spin_unlock_irqrestore(&ha->hardware_lock, flags); +- /* ref: INIT */ +- kref_put(&sp->cmd_kref, qla2x00_sp_release); + return 0; + } + +diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h +index 2f49baf131e26..7cf998e3cc681 100644 +--- a/drivers/scsi/qla2xxx/qla_def.h ++++ b/drivers/scsi/qla2xxx/qla_def.h +@@ -3309,9 +3309,20 @@ struct fab_scan_rp { + u8 node_name[8]; + }; + ++enum scan_step { ++ FAB_SCAN_START, ++ FAB_SCAN_GPNFT_FCP, ++ FAB_SCAN_GNNFT_FCP, ++ FAB_SCAN_GPNFT_NVME, ++ FAB_SCAN_GNNFT_NVME, ++}; ++ + struct fab_scan { + struct fab_scan_rp *l; + u32 size; ++ u32 rscn_gen_start; ++ u32 rscn_gen_end; ++ enum scan_step step; + u16 scan_retry; + #define MAX_SCAN_RETRIES 5 + enum scan_flags_t scan_flags; +@@ -3537,9 +3548,8 @@ enum qla_work_type { + QLA_EVT_RELOGIN, + QLA_EVT_ASYNC_PRLO, + QLA_EVT_ASYNC_PRLO_DONE, +- QLA_EVT_GPNFT, +- QLA_EVT_GPNFT_DONE, +- QLA_EVT_GNNFT_DONE, ++ QLA_EVT_SCAN_CMD, ++ QLA_EVT_SCAN_FINISH, + QLA_EVT_GFPNID, + QLA_EVT_SP_RETRY, + QLA_EVT_IIDMA, +@@ -5030,6 +5040,7 @@ typedef struct scsi_qla_host { + + /* Counter to detect races between ELS and RSCN events */ + atomic_t generation_tick; ++ atomic_t rscn_gen; + /* Time when global fcport update has been scheduled */ + int total_fcport_update_gen; + /* List of pending LOGOs, protected by tgt_mutex */ +diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h +index 7309310d2ab94..cededfda9d0e3 100644 +--- a/drivers/scsi/qla2xxx/qla_gbl.h ++++ b/drivers/scsi/qla2xxx/qla_gbl.h +@@ -728,9 +728,9 @@ int qla24xx_async_gpsc(scsi_qla_host_t *, fc_port_t *); + void qla24xx_handle_gpsc_event(scsi_qla_host_t *, struct event_arg *); + int qla2x00_mgmt_svr_login(scsi_qla_host_t *); + int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport, bool); +-int qla24xx_async_gpnft(scsi_qla_host_t *, u8, srb_t *); +-void qla24xx_async_gpnft_done(scsi_qla_host_t *, srb_t *); +-void qla24xx_async_gnnft_done(scsi_qla_host_t *, srb_t *); ++int qla_fab_async_scan(scsi_qla_host_t *, srb_t *); ++void qla_fab_scan_start(struct scsi_qla_host *); ++void qla_fab_scan_finish(scsi_qla_host_t *, srb_t *); + int qla24xx_post_gfpnid_work(struct scsi_qla_host *, fc_port_t *); + int qla24xx_async_gfpnid(scsi_qla_host_t *, fc_port_t *); + void qla24xx_handle_gfpnid_event(scsi_qla_host_t *, struct event_arg *); +diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c +index 1cf9d200d5630..d2bddca7045aa 100644 +--- a/drivers/scsi/qla2xxx/qla_gs.c ++++ b/drivers/scsi/qla2xxx/qla_gs.c +@@ -1710,7 +1710,7 @@ qla2x00_hba_attributes(scsi_qla_host_t *vha, void *entries, + eiter->type = cpu_to_be16(FDMI_HBA_OPTION_ROM_VERSION); + alen = scnprintf( + eiter->a.orom_version, sizeof(eiter->a.orom_version), +- "%d.%02d", ha->bios_revision[1], ha->bios_revision[0]); ++ "%d.%02d", ha->efi_revision[1], ha->efi_revision[0]); + alen += FDMI_ATTR_ALIGNMENT(alen); + alen += FDMI_ATTR_TYPELEN(eiter); + eiter->len = cpu_to_be16(alen); +@@ -3168,7 +3168,30 @@ static int qla2x00_is_a_vp(scsi_qla_host_t *vha, u64 wwn) + return rc; + } + +-void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp) ++static bool qla_ok_to_clear_rscn(scsi_qla_host_t *vha, fc_port_t *fcport) ++{ ++ u32 rscn_gen; ++ ++ rscn_gen = atomic_read(&vha->rscn_gen); ++ ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x2017, ++ "%s %d %8phC rscn_gen %x start %x end %x current %x\n", ++ __func__, __LINE__, fcport->port_name, fcport->rscn_gen, ++ vha->scan.rscn_gen_start, vha->scan.rscn_gen_end, rscn_gen); ++ ++ if (val_is_in_range(fcport->rscn_gen, vha->scan.rscn_gen_start, ++ vha->scan.rscn_gen_end)) ++ /* rscn came in before fabric scan */ ++ return true; ++ ++ if (val_is_in_range(fcport->rscn_gen, vha->scan.rscn_gen_end, rscn_gen)) ++ /* rscn came in after fabric scan */ ++ return false; ++ ++ /* rare: fcport's scan_needed + rscn_gen must be stale */ ++ return true; ++} ++ ++void qla_fab_scan_finish(scsi_qla_host_t *vha, srb_t *sp) + { + fc_port_t *fcport; + u32 i, rc; +@@ -3281,10 +3304,10 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp) + (fcport->scan_needed && + fcport->port_type != FCT_INITIATOR && + fcport->port_type != FCT_NVME_INITIATOR)) { ++ fcport->scan_needed = 0; + qlt_schedule_sess_for_deletion(fcport); + } + fcport->d_id.b24 = rp->id.b24; +- fcport->scan_needed = 0; + break; + } + +@@ -3325,7 +3348,9 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp) + do_delete = true; + } + +- fcport->scan_needed = 0; ++ if (qla_ok_to_clear_rscn(vha, fcport)) ++ fcport->scan_needed = 0; ++ + if (((qla_dual_mode_enabled(vha) || + qla_ini_mode_enabled(vha)) && + atomic_read(&fcport->state) == FCS_ONLINE) || +@@ -3355,7 +3380,9 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp) + fcport->port_name, fcport->loop_id, + fcport->login_retry); + } +- fcport->scan_needed = 0; ++ ++ if (qla_ok_to_clear_rscn(vha, fcport)) ++ fcport->scan_needed = 0; + qla24xx_fcport_handle_login(vha, fcport); + } + } +@@ -3379,14 +3406,11 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp) + } + } + +-static int qla2x00_post_gnnft_gpnft_done_work(struct scsi_qla_host *vha, ++static int qla2x00_post_next_scan_work(struct scsi_qla_host *vha, + srb_t *sp, int cmd) + { + struct qla_work_evt *e; + +- if (cmd != QLA_EVT_GPNFT_DONE && cmd != QLA_EVT_GNNFT_DONE) +- return QLA_PARAMETER_ERROR; +- + e = qla2x00_alloc_work(vha, cmd); + if (!e) + return QLA_FUNCTION_FAILED; +@@ -3396,37 +3420,15 @@ static int qla2x00_post_gnnft_gpnft_done_work(struct scsi_qla_host *vha, + return qla2x00_post_work(vha, e); + } + +-static int qla2x00_post_nvme_gpnft_work(struct scsi_qla_host *vha, +- srb_t *sp, int cmd) +-{ +- struct qla_work_evt *e; +- +- if (cmd != QLA_EVT_GPNFT) +- return QLA_PARAMETER_ERROR; +- +- e = qla2x00_alloc_work(vha, cmd); +- if (!e) +- return QLA_FUNCTION_FAILED; +- +- e->u.gpnft.fc4_type = FC4_TYPE_NVME; +- e->u.gpnft.sp = sp; +- +- return qla2x00_post_work(vha, e); +-} +- + static void qla2x00_find_free_fcp_nvme_slot(struct scsi_qla_host *vha, + struct srb *sp) + { + struct qla_hw_data *ha = vha->hw; + int num_fibre_dev = ha->max_fibre_devices; +- struct ct_sns_req *ct_req = +- (struct ct_sns_req *)sp->u.iocb_cmd.u.ctarg.req; + struct ct_sns_gpnft_rsp *ct_rsp = + (struct ct_sns_gpnft_rsp *)sp->u.iocb_cmd.u.ctarg.rsp; + struct ct_sns_gpn_ft_data *d; + struct fab_scan_rp *rp; +- u16 cmd = be16_to_cpu(ct_req->command); +- u8 fc4_type = sp->gen2; + int i, j, k; + port_id_t id; + u8 found; +@@ -3445,85 +3447,83 @@ static void qla2x00_find_free_fcp_nvme_slot(struct scsi_qla_host *vha, + if (id.b24 == 0 || wwn == 0) + continue; + +- if (fc4_type == FC4_TYPE_FCP_SCSI) { +- if (cmd == GPN_FT_CMD) { +- rp = &vha->scan.l[j]; +- rp->id = id; +- memcpy(rp->port_name, d->port_name, 8); +- j++; +- rp->fc4type = FS_FC4TYPE_FCP; +- } else { +- for (k = 0; k < num_fibre_dev; k++) { +- rp = &vha->scan.l[k]; +- if (id.b24 == rp->id.b24) { +- memcpy(rp->node_name, +- d->port_name, 8); +- break; +- } ++ ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x2025, ++ "%s %06x %8ph \n", ++ __func__, id.b24, d->port_name); ++ ++ switch (vha->scan.step) { ++ case FAB_SCAN_GPNFT_FCP: ++ rp = &vha->scan.l[j]; ++ rp->id = id; ++ memcpy(rp->port_name, d->port_name, 8); ++ j++; ++ rp->fc4type = FS_FC4TYPE_FCP; ++ break; ++ case FAB_SCAN_GNNFT_FCP: ++ for (k = 0; k < num_fibre_dev; k++) { ++ rp = &vha->scan.l[k]; ++ if (id.b24 == rp->id.b24) { ++ memcpy(rp->node_name, ++ d->port_name, 8); ++ break; + } + } +- } else { +- /* Search if the fibre device supports FC4_TYPE_NVME */ +- if (cmd == GPN_FT_CMD) { +- found = 0; +- +- for (k = 0; k < num_fibre_dev; k++) { +- rp = &vha->scan.l[k]; +- if (!memcmp(rp->port_name, +- d->port_name, 8)) { +- /* +- * Supports FC-NVMe & FCP +- */ +- rp->fc4type |= FS_FC4TYPE_NVME; +- found = 1; +- break; +- } ++ break; ++ case FAB_SCAN_GPNFT_NVME: ++ found = 0; ++ ++ for (k = 0; k < num_fibre_dev; k++) { ++ rp = &vha->scan.l[k]; ++ if (!memcmp(rp->port_name, d->port_name, 8)) { ++ /* ++ * Supports FC-NVMe & FCP ++ */ ++ rp->fc4type |= FS_FC4TYPE_NVME; ++ found = 1; ++ break; + } ++ } + +- /* We found new FC-NVMe only port */ +- if (!found) { +- for (k = 0; k < num_fibre_dev; k++) { +- rp = &vha->scan.l[k]; +- if (wwn_to_u64(rp->port_name)) { +- continue; +- } else { +- rp->id = id; +- memcpy(rp->port_name, +- d->port_name, 8); +- rp->fc4type = +- FS_FC4TYPE_NVME; +- break; +- } +- } +- } +- } else { ++ /* We found new FC-NVMe only port */ ++ if (!found) { + for (k = 0; k < num_fibre_dev; k++) { + rp = &vha->scan.l[k]; +- if (id.b24 == rp->id.b24) { +- memcpy(rp->node_name, +- d->port_name, 8); ++ if (wwn_to_u64(rp->port_name)) { ++ continue; ++ } else { ++ rp->id = id; ++ memcpy(rp->port_name, d->port_name, 8); ++ rp->fc4type = FS_FC4TYPE_NVME; + break; + } + } + } ++ break; ++ case FAB_SCAN_GNNFT_NVME: ++ for (k = 0; k < num_fibre_dev; k++) { ++ rp = &vha->scan.l[k]; ++ if (id.b24 == rp->id.b24) { ++ memcpy(rp->node_name, d->port_name, 8); ++ break; ++ } ++ } ++ break; ++ default: ++ break; + } + } + } + +-static void qla2x00_async_gpnft_gnnft_sp_done(srb_t *sp, int res) ++static void qla_async_scan_sp_done(srb_t *sp, int res) + { + struct scsi_qla_host *vha = sp->vha; +- struct ct_sns_req *ct_req = +- (struct ct_sns_req *)sp->u.iocb_cmd.u.ctarg.req; +- u16 cmd = be16_to_cpu(ct_req->command); +- u8 fc4_type = sp->gen2; + unsigned long flags; + int rc; + + /* gen2 field is holding the fc4type */ +- ql_dbg(ql_dbg_disc, vha, 0xffff, +- "Async done-%s res %x FC4Type %x\n", +- sp->name, res, sp->gen2); ++ ql_dbg(ql_dbg_disc, vha, 0x2026, ++ "Async done-%s res %x step %x\n", ++ sp->name, res, vha->scan.step); + + sp->rc = res; + if (res) { +@@ -3547,8 +3547,7 @@ static void qla2x00_async_gpnft_gnnft_sp_done(srb_t *sp, int res) + * sp for GNNFT_DONE work. This will allow all + * the resource to get freed up. + */ +- rc = qla2x00_post_gnnft_gpnft_done_work(vha, sp, +- QLA_EVT_GNNFT_DONE); ++ rc = qla2x00_post_next_scan_work(vha, sp, QLA_EVT_SCAN_FINISH); + if (rc) { + /* Cleanup here to prevent memory leak */ + qla24xx_sp_unmap(vha, sp); +@@ -3573,28 +3572,30 @@ static void qla2x00_async_gpnft_gnnft_sp_done(srb_t *sp, int res) + + qla2x00_find_free_fcp_nvme_slot(vha, sp); + +- if ((fc4_type == FC4_TYPE_FCP_SCSI) && vha->flags.nvme_enabled && +- cmd == GNN_FT_CMD) { +- spin_lock_irqsave(&vha->work_lock, flags); +- vha->scan.scan_flags &= ~SF_SCANNING; +- spin_unlock_irqrestore(&vha->work_lock, flags); ++ spin_lock_irqsave(&vha->work_lock, flags); ++ vha->scan.scan_flags &= ~SF_SCANNING; ++ spin_unlock_irqrestore(&vha->work_lock, flags); + +- sp->rc = res; +- rc = qla2x00_post_nvme_gpnft_work(vha, sp, QLA_EVT_GPNFT); +- if (rc) { +- qla24xx_sp_unmap(vha, sp); +- set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); +- set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); +- } +- return; +- } ++ switch (vha->scan.step) { ++ case FAB_SCAN_GPNFT_FCP: ++ case FAB_SCAN_GPNFT_NVME: ++ rc = qla2x00_post_next_scan_work(vha, sp, QLA_EVT_SCAN_CMD); ++ break; ++ case FAB_SCAN_GNNFT_FCP: ++ if (vha->flags.nvme_enabled) ++ rc = qla2x00_post_next_scan_work(vha, sp, QLA_EVT_SCAN_CMD); ++ else ++ rc = qla2x00_post_next_scan_work(vha, sp, QLA_EVT_SCAN_FINISH); + +- if (cmd == GPN_FT_CMD) { +- rc = qla2x00_post_gnnft_gpnft_done_work(vha, sp, +- QLA_EVT_GPNFT_DONE); +- } else { +- rc = qla2x00_post_gnnft_gpnft_done_work(vha, sp, +- QLA_EVT_GNNFT_DONE); ++ break; ++ case FAB_SCAN_GNNFT_NVME: ++ rc = qla2x00_post_next_scan_work(vha, sp, QLA_EVT_SCAN_FINISH); ++ break; ++ default: ++ /* should not be here */ ++ WARN_ON(1); ++ rc = QLA_FUNCTION_FAILED; ++ break; + } + + if (rc) { +@@ -3605,127 +3606,16 @@ static void qla2x00_async_gpnft_gnnft_sp_done(srb_t *sp, int res) + } + } + +-/* +- * Get WWNN list for fc4_type +- * +- * It is assumed the same SRB is re-used from GPNFT to avoid +- * mem free & re-alloc +- */ +-static int qla24xx_async_gnnft(scsi_qla_host_t *vha, struct srb *sp, +- u8 fc4_type) +-{ +- int rval = QLA_FUNCTION_FAILED; +- struct ct_sns_req *ct_req; +- struct ct_sns_pkt *ct_sns; +- unsigned long flags; +- +- if (!vha->flags.online) { +- spin_lock_irqsave(&vha->work_lock, flags); +- vha->scan.scan_flags &= ~SF_SCANNING; +- spin_unlock_irqrestore(&vha->work_lock, flags); +- goto done_free_sp; +- } +- +- if (!sp->u.iocb_cmd.u.ctarg.req || !sp->u.iocb_cmd.u.ctarg.rsp) { +- ql_log(ql_log_warn, vha, 0xffff, +- "%s: req %p rsp %p are not setup\n", +- __func__, sp->u.iocb_cmd.u.ctarg.req, +- sp->u.iocb_cmd.u.ctarg.rsp); +- spin_lock_irqsave(&vha->work_lock, flags); +- vha->scan.scan_flags &= ~SF_SCANNING; +- spin_unlock_irqrestore(&vha->work_lock, flags); +- WARN_ON(1); +- set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); +- set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); +- goto done_free_sp; +- } +- +- ql_dbg(ql_dbg_disc, vha, 0xfffff, +- "%s: FC4Type %x, CT-PASSTHRU %s command ctarg rsp size %d, ctarg req size %d\n", +- __func__, fc4_type, sp->name, sp->u.iocb_cmd.u.ctarg.rsp_size, +- sp->u.iocb_cmd.u.ctarg.req_size); +- +- sp->type = SRB_CT_PTHRU_CMD; +- sp->name = "gnnft"; +- sp->gen1 = vha->hw->base_qpair->chip_reset; +- sp->gen2 = fc4_type; +- qla2x00_init_async_sp(sp, qla2x00_get_async_timeout(vha) + 2, +- qla2x00_async_gpnft_gnnft_sp_done); +- +- memset(sp->u.iocb_cmd.u.ctarg.rsp, 0, sp->u.iocb_cmd.u.ctarg.rsp_size); +- memset(sp->u.iocb_cmd.u.ctarg.req, 0, sp->u.iocb_cmd.u.ctarg.req_size); +- +- ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req; +- /* CT_IU preamble */ +- ct_req = qla2x00_prep_ct_req(ct_sns, GNN_FT_CMD, +- sp->u.iocb_cmd.u.ctarg.rsp_size); +- +- /* GPN_FT req */ +- ct_req->req.gpn_ft.port_type = fc4_type; +- +- sp->u.iocb_cmd.u.ctarg.req_size = GNN_FT_REQ_SIZE; +- sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; +- +- ql_dbg(ql_dbg_disc, vha, 0xffff, +- "Async-%s hdl=%x FC4Type %x.\n", sp->name, +- sp->handle, ct_req->req.gpn_ft.port_type); +- +- rval = qla2x00_start_sp(sp); +- if (rval != QLA_SUCCESS) { +- goto done_free_sp; +- } +- +- return rval; +- +-done_free_sp: +- if (sp->u.iocb_cmd.u.ctarg.req) { +- dma_free_coherent(&vha->hw->pdev->dev, +- sp->u.iocb_cmd.u.ctarg.req_allocated_size, +- sp->u.iocb_cmd.u.ctarg.req, +- sp->u.iocb_cmd.u.ctarg.req_dma); +- sp->u.iocb_cmd.u.ctarg.req = NULL; +- } +- if (sp->u.iocb_cmd.u.ctarg.rsp) { +- dma_free_coherent(&vha->hw->pdev->dev, +- sp->u.iocb_cmd.u.ctarg.rsp_allocated_size, +- sp->u.iocb_cmd.u.ctarg.rsp, +- sp->u.iocb_cmd.u.ctarg.rsp_dma); +- sp->u.iocb_cmd.u.ctarg.rsp = NULL; +- } +- /* ref: INIT */ +- kref_put(&sp->cmd_kref, qla2x00_sp_release); +- +- spin_lock_irqsave(&vha->work_lock, flags); +- vha->scan.scan_flags &= ~SF_SCANNING; +- if (vha->scan.scan_flags == 0) { +- ql_dbg(ql_dbg_disc, vha, 0xffff, +- "%s: schedule\n", __func__); +- vha->scan.scan_flags |= SF_QUEUED; +- schedule_delayed_work(&vha->scan.scan_work, 5); +- } +- spin_unlock_irqrestore(&vha->work_lock, flags); +- +- +- return rval; +-} /* GNNFT */ +- +-void qla24xx_async_gpnft_done(scsi_qla_host_t *vha, srb_t *sp) +-{ +- ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff, +- "%s enter\n", __func__); +- qla24xx_async_gnnft(vha, sp, sp->gen2); +-} +- + /* Get WWPN list for certain fc4_type */ +-int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp) ++int qla_fab_async_scan(scsi_qla_host_t *vha, srb_t *sp) + { + int rval = QLA_FUNCTION_FAILED; + struct ct_sns_req *ct_req; + struct ct_sns_pkt *ct_sns; +- u32 rspsz; ++ u32 rspsz = 0; + unsigned long flags; + +- ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff, ++ ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x200c, + "%s enter\n", __func__); + + if (!vha->flags.online) +@@ -3734,22 +3624,21 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp) + spin_lock_irqsave(&vha->work_lock, flags); + if (vha->scan.scan_flags & SF_SCANNING) { + spin_unlock_irqrestore(&vha->work_lock, flags); +- ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff, ++ ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x2012, + "%s: scan active\n", __func__); + return rval; + } + vha->scan.scan_flags |= SF_SCANNING; ++ if (!sp) ++ vha->scan.step = FAB_SCAN_START; ++ + spin_unlock_irqrestore(&vha->work_lock, flags); + +- if (fc4_type == FC4_TYPE_FCP_SCSI) { +- ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff, ++ switch (vha->scan.step) { ++ case FAB_SCAN_START: ++ ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x2018, + "%s: Performing FCP Scan\n", __func__); + +- if (sp) { +- /* ref: INIT */ +- kref_put(&sp->cmd_kref, qla2x00_sp_release); +- } +- + /* ref: INIT */ + sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL); + if (!sp) { +@@ -3765,7 +3654,7 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp) + GFP_KERNEL); + sp->u.iocb_cmd.u.ctarg.req_allocated_size = sizeof(struct ct_sns_pkt); + if (!sp->u.iocb_cmd.u.ctarg.req) { +- ql_log(ql_log_warn, vha, 0xffff, ++ ql_log(ql_log_warn, vha, 0x201a, + "Failed to allocate ct_sns request.\n"); + spin_lock_irqsave(&vha->work_lock, flags); + vha->scan.scan_flags &= ~SF_SCANNING; +@@ -3773,7 +3662,6 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp) + qla2x00_rel_sp(sp); + return rval; + } +- sp->u.iocb_cmd.u.ctarg.req_size = GPN_FT_REQ_SIZE; + + rspsz = sizeof(struct ct_sns_gpnft_rsp) + + vha->hw->max_fibre_devices * +@@ -3785,7 +3673,7 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp) + GFP_KERNEL); + sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = rspsz; + if (!sp->u.iocb_cmd.u.ctarg.rsp) { +- ql_log(ql_log_warn, vha, 0xffff, ++ ql_log(ql_log_warn, vha, 0x201b, + "Failed to allocate ct_sns request.\n"); + spin_lock_irqsave(&vha->work_lock, flags); + vha->scan.scan_flags &= ~SF_SCANNING; +@@ -3805,35 +3693,95 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp) + "%s scan list size %d\n", __func__, vha->scan.size); + + memset(vha->scan.l, 0, vha->scan.size); +- } else if (!sp) { +- ql_dbg(ql_dbg_disc, vha, 0xffff, +- "NVME scan did not provide SP\n"); ++ ++ vha->scan.step = FAB_SCAN_GPNFT_FCP; ++ break; ++ case FAB_SCAN_GPNFT_FCP: ++ vha->scan.step = FAB_SCAN_GNNFT_FCP; ++ break; ++ case FAB_SCAN_GNNFT_FCP: ++ vha->scan.step = FAB_SCAN_GPNFT_NVME; ++ break; ++ case FAB_SCAN_GPNFT_NVME: ++ vha->scan.step = FAB_SCAN_GNNFT_NVME; ++ break; ++ case FAB_SCAN_GNNFT_NVME: ++ default: ++ /* should not be here */ ++ WARN_ON(1); ++ goto done_free_sp; ++ } ++ ++ if (!sp) { ++ ql_dbg(ql_dbg_disc, vha, 0x201c, ++ "scan did not provide SP\n"); + return rval; + } ++ if (!sp->u.iocb_cmd.u.ctarg.req || !sp->u.iocb_cmd.u.ctarg.rsp) { ++ ql_log(ql_log_warn, vha, 0x201d, ++ "%s: req %p rsp %p are not setup\n", ++ __func__, sp->u.iocb_cmd.u.ctarg.req, ++ sp->u.iocb_cmd.u.ctarg.rsp); ++ spin_lock_irqsave(&vha->work_lock, flags); ++ vha->scan.scan_flags &= ~SF_SCANNING; ++ spin_unlock_irqrestore(&vha->work_lock, flags); ++ WARN_ON(1); ++ set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); ++ set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); ++ goto done_free_sp; ++ } ++ ++ rspsz = sp->u.iocb_cmd.u.ctarg.rsp_size; ++ memset(sp->u.iocb_cmd.u.ctarg.req, 0, sp->u.iocb_cmd.u.ctarg.req_size); ++ memset(sp->u.iocb_cmd.u.ctarg.rsp, 0, sp->u.iocb_cmd.u.ctarg.rsp_size); ++ + + sp->type = SRB_CT_PTHRU_CMD; +- sp->name = "gpnft"; + sp->gen1 = vha->hw->base_qpair->chip_reset; +- sp->gen2 = fc4_type; + qla2x00_init_async_sp(sp, qla2x00_get_async_timeout(vha) + 2, +- qla2x00_async_gpnft_gnnft_sp_done); +- +- rspsz = sp->u.iocb_cmd.u.ctarg.rsp_size; +- memset(sp->u.iocb_cmd.u.ctarg.rsp, 0, sp->u.iocb_cmd.u.ctarg.rsp_size); +- memset(sp->u.iocb_cmd.u.ctarg.req, 0, sp->u.iocb_cmd.u.ctarg.req_size); ++ qla_async_scan_sp_done); + + ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req; +- /* CT_IU preamble */ +- ct_req = qla2x00_prep_ct_req(ct_sns, GPN_FT_CMD, rspsz); + +- /* GPN_FT req */ +- ct_req->req.gpn_ft.port_type = fc4_type; ++ /* CT_IU preamble */ ++ switch (vha->scan.step) { ++ case FAB_SCAN_GPNFT_FCP: ++ sp->name = "gpnft"; ++ ct_req = qla2x00_prep_ct_req(ct_sns, GPN_FT_CMD, rspsz); ++ ct_req->req.gpn_ft.port_type = FC4_TYPE_FCP_SCSI; ++ sp->u.iocb_cmd.u.ctarg.req_size = GPN_FT_REQ_SIZE; ++ break; ++ case FAB_SCAN_GNNFT_FCP: ++ sp->name = "gnnft"; ++ ct_req = qla2x00_prep_ct_req(ct_sns, GNN_FT_CMD, rspsz); ++ ct_req->req.gpn_ft.port_type = FC4_TYPE_FCP_SCSI; ++ sp->u.iocb_cmd.u.ctarg.req_size = GNN_FT_REQ_SIZE; ++ break; ++ case FAB_SCAN_GPNFT_NVME: ++ sp->name = "gpnft"; ++ ct_req = qla2x00_prep_ct_req(ct_sns, GPN_FT_CMD, rspsz); ++ ct_req->req.gpn_ft.port_type = FC4_TYPE_NVME; ++ sp->u.iocb_cmd.u.ctarg.req_size = GPN_FT_REQ_SIZE; ++ break; ++ case FAB_SCAN_GNNFT_NVME: ++ sp->name = "gnnft"; ++ ct_req = qla2x00_prep_ct_req(ct_sns, GNN_FT_CMD, rspsz); ++ ct_req->req.gpn_ft.port_type = FC4_TYPE_NVME; ++ sp->u.iocb_cmd.u.ctarg.req_size = GNN_FT_REQ_SIZE; ++ break; ++ default: ++ /* should not be here */ ++ WARN_ON(1); ++ goto done_free_sp; ++ } + + sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; + +- ql_dbg(ql_dbg_disc, vha, 0xffff, +- "Async-%s hdl=%x FC4Type %x.\n", sp->name, +- sp->handle, ct_req->req.gpn_ft.port_type); ++ ql_dbg(ql_dbg_disc, vha, 0x2003, ++ "%s: step %d, rsp size %d, req size %d hdl %x %s FC4TYPE %x \n", ++ __func__, vha->scan.step, sp->u.iocb_cmd.u.ctarg.rsp_size, ++ sp->u.iocb_cmd.u.ctarg.req_size, sp->handle, sp->name, ++ ct_req->req.gpn_ft.port_type); + + rval = qla2x00_start_sp(sp); + if (rval != QLA_SUCCESS) { +@@ -3864,7 +3812,7 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp) + spin_lock_irqsave(&vha->work_lock, flags); + vha->scan.scan_flags &= ~SF_SCANNING; + if (vha->scan.scan_flags == 0) { +- ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff, ++ ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x2007, + "%s: Scan scheduled.\n", __func__); + vha->scan.scan_flags |= SF_QUEUED; + schedule_delayed_work(&vha->scan.scan_work, 5); +@@ -3875,6 +3823,15 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp) + return rval; + } + ++void qla_fab_scan_start(struct scsi_qla_host *vha) ++{ ++ int rval; ++ ++ rval = qla_fab_async_scan(vha, NULL); ++ if (rval) ++ set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); ++} ++ + void qla_scan_work_fn(struct work_struct *work) + { + struct fab_scan *s = container_of(to_delayed_work(work), +diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c +index 8377624d76c98..eda3bdab934d5 100644 +--- a/drivers/scsi/qla2xxx/qla_init.c ++++ b/drivers/scsi/qla2xxx/qla_init.c +@@ -1842,10 +1842,18 @@ int qla24xx_post_newsess_work(struct scsi_qla_host *vha, port_id_t *id, + return qla2x00_post_work(vha, e); + } + ++static void qla_rscn_gen_tick(scsi_qla_host_t *vha, u32 *ret_rscn_gen) ++{ ++ *ret_rscn_gen = atomic_inc_return(&vha->rscn_gen); ++ /* memory barrier */ ++ wmb(); ++} ++ + void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea) + { + fc_port_t *fcport; + unsigned long flags; ++ u32 rscn_gen; + + switch (ea->id.b.rsvd_1) { + case RSCN_PORT_ADDR: +@@ -1875,15 +1883,16 @@ void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea) + * Otherwise we're already in the middle of a relogin + */ + fcport->scan_needed = 1; +- fcport->rscn_gen++; ++ qla_rscn_gen_tick(vha, &fcport->rscn_gen); + } + } else { + fcport->scan_needed = 1; +- fcport->rscn_gen++; ++ qla_rscn_gen_tick(vha, &fcport->rscn_gen); + } + } + break; + case RSCN_AREA_ADDR: ++ qla_rscn_gen_tick(vha, &rscn_gen); + list_for_each_entry(fcport, &vha->vp_fcports, list) { + if (fcport->flags & FCF_FCP2_DEVICE && + atomic_read(&fcport->state) == FCS_ONLINE) +@@ -1891,11 +1900,12 @@ void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea) + + if ((ea->id.b24 & 0xffff00) == (fcport->d_id.b24 & 0xffff00)) { + fcport->scan_needed = 1; +- fcport->rscn_gen++; ++ fcport->rscn_gen = rscn_gen; + } + } + break; + case RSCN_DOM_ADDR: ++ qla_rscn_gen_tick(vha, &rscn_gen); + list_for_each_entry(fcport, &vha->vp_fcports, list) { + if (fcport->flags & FCF_FCP2_DEVICE && + atomic_read(&fcport->state) == FCS_ONLINE) +@@ -1903,19 +1913,20 @@ void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea) + + if ((ea->id.b24 & 0xff0000) == (fcport->d_id.b24 & 0xff0000)) { + fcport->scan_needed = 1; +- fcport->rscn_gen++; ++ fcport->rscn_gen = rscn_gen; + } + } + break; + case RSCN_FAB_ADDR: + default: ++ qla_rscn_gen_tick(vha, &rscn_gen); + list_for_each_entry(fcport, &vha->vp_fcports, list) { + if (fcport->flags & FCF_FCP2_DEVICE && + atomic_read(&fcport->state) == FCS_ONLINE) + continue; + + fcport->scan_needed = 1; +- fcport->rscn_gen++; ++ fcport->rscn_gen = rscn_gen; + } + break; + } +@@ -1924,6 +1935,7 @@ void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea) + if (vha->scan.scan_flags == 0) { + ql_dbg(ql_dbg_disc, vha, 0xffff, "%s: schedule\n", __func__); + vha->scan.scan_flags |= SF_QUEUED; ++ vha->scan.rscn_gen_start = atomic_read(&vha->rscn_gen); + schedule_delayed_work(&vha->scan.scan_work, 5); + } + spin_unlock_irqrestore(&vha->work_lock, flags); +@@ -6393,10 +6405,9 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha) + qlt_do_generation_tick(vha, &discovery_gen); + + if (USE_ASYNC_SCAN(ha)) { +- rval = qla24xx_async_gpnft(vha, FC4_TYPE_FCP_SCSI, +- NULL); +- if (rval) +- set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); ++ /* start of scan begins here */ ++ vha->scan.rscn_gen_end = atomic_read(&vha->rscn_gen); ++ qla_fab_scan_start(vha); + } else { + list_for_each_entry(fcport, &vha->vp_fcports, list) + fcport->scan_state = QLA_FCPORT_SCAN; +@@ -8207,15 +8218,21 @@ qla28xx_get_aux_images( + struct qla27xx_image_status pri_aux_image_status, sec_aux_image_status; + bool valid_pri_image = false, valid_sec_image = false; + bool active_pri_image = false, active_sec_image = false; ++ int rc; + + if (!ha->flt_region_aux_img_status_pri) { + ql_dbg(ql_dbg_init, vha, 0x018a, "Primary aux image not addressed\n"); + goto check_sec_image; + } + +- qla24xx_read_flash_data(vha, (uint32_t *)&pri_aux_image_status, ++ rc = qla24xx_read_flash_data(vha, (uint32_t *)&pri_aux_image_status, + ha->flt_region_aux_img_status_pri, + sizeof(pri_aux_image_status) >> 2); ++ if (rc) { ++ ql_log(ql_log_info, vha, 0x01a1, ++ "Unable to read Primary aux image(%x).\n", rc); ++ goto check_sec_image; ++ } + qla27xx_print_image(vha, "Primary aux image", &pri_aux_image_status); + + if (qla28xx_check_aux_image_status_signature(&pri_aux_image_status)) { +@@ -8246,9 +8263,15 @@ qla28xx_get_aux_images( + goto check_valid_image; + } + +- qla24xx_read_flash_data(vha, (uint32_t *)&sec_aux_image_status, ++ rc = qla24xx_read_flash_data(vha, (uint32_t *)&sec_aux_image_status, + ha->flt_region_aux_img_status_sec, + sizeof(sec_aux_image_status) >> 2); ++ if (rc) { ++ ql_log(ql_log_info, vha, 0x01a2, ++ "Unable to read Secondary aux image(%x).\n", rc); ++ goto check_valid_image; ++ } ++ + qla27xx_print_image(vha, "Secondary aux image", &sec_aux_image_status); + + if (qla28xx_check_aux_image_status_signature(&sec_aux_image_status)) { +@@ -8306,6 +8329,7 @@ qla27xx_get_active_image(struct scsi_qla_host *vha, + struct qla27xx_image_status pri_image_status, sec_image_status; + bool valid_pri_image = false, valid_sec_image = false; + bool active_pri_image = false, active_sec_image = false; ++ int rc; + + if (!ha->flt_region_img_status_pri) { + ql_dbg(ql_dbg_init, vha, 0x018a, "Primary image not addressed\n"); +@@ -8347,8 +8371,14 @@ qla27xx_get_active_image(struct scsi_qla_host *vha, + goto check_valid_image; + } + +- qla24xx_read_flash_data(vha, (uint32_t *)(&sec_image_status), ++ rc = qla24xx_read_flash_data(vha, (uint32_t *)(&sec_image_status), + ha->flt_region_img_status_sec, sizeof(sec_image_status) >> 2); ++ if (rc) { ++ ql_log(ql_log_info, vha, 0x01a3, ++ "Unable to read Secondary image status(%x).\n", rc); ++ goto check_valid_image; ++ } ++ + qla27xx_print_image(vha, "Secondary image", &sec_image_status); + + if (qla27xx_check_image_status_signature(&sec_image_status)) { +@@ -8420,11 +8450,10 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr, + "FW: Loading firmware from flash (%x).\n", faddr); + + dcode = (uint32_t *)req->ring; +- qla24xx_read_flash_data(vha, dcode, faddr, 8); +- if (qla24xx_risc_firmware_invalid(dcode)) { ++ rval = qla24xx_read_flash_data(vha, dcode, faddr, 8); ++ if (rval || qla24xx_risc_firmware_invalid(dcode)) { + ql_log(ql_log_fatal, vha, 0x008c, +- "Unable to verify the integrity of flash firmware " +- "image.\n"); ++ "Unable to verify the integrity of flash firmware image (rval %x).\n", rval); + ql_log(ql_log_fatal, vha, 0x008d, + "Firmware data: %08x %08x %08x %08x.\n", + dcode[0], dcode[1], dcode[2], dcode[3]); +@@ -8438,7 +8467,12 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr, + for (j = 0; j < segments; j++) { + ql_dbg(ql_dbg_init, vha, 0x008d, + "-> Loading segment %u...\n", j); +- qla24xx_read_flash_data(vha, dcode, faddr, 10); ++ rval = qla24xx_read_flash_data(vha, dcode, faddr, 10); ++ if (rval) { ++ ql_log(ql_log_fatal, vha, 0x016a, ++ "-> Unable to read segment addr + size .\n"); ++ return QLA_FUNCTION_FAILED; ++ } + risc_addr = be32_to_cpu((__force __be32)dcode[2]); + risc_size = be32_to_cpu((__force __be32)dcode[3]); + if (!*srisc_addr) { +@@ -8454,7 +8488,13 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr, + ql_dbg(ql_dbg_init, vha, 0x008e, + "-> Loading fragment %u: %#x <- %#x (%#lx dwords)...\n", + fragment, risc_addr, faddr, dlen); +- qla24xx_read_flash_data(vha, dcode, faddr, dlen); ++ rval = qla24xx_read_flash_data(vha, dcode, faddr, dlen); ++ if (rval) { ++ ql_log(ql_log_fatal, vha, 0x016b, ++ "-> Unable to read fragment(faddr %#x dlen %#lx).\n", ++ faddr, dlen); ++ return QLA_FUNCTION_FAILED; ++ } + for (i = 0; i < dlen; i++) + dcode[i] = swab32(dcode[i]); + +@@ -8483,7 +8523,14 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr, + fwdt->length = 0; + + dcode = (uint32_t *)req->ring; +- qla24xx_read_flash_data(vha, dcode, faddr, 7); ++ ++ rval = qla24xx_read_flash_data(vha, dcode, faddr, 7); ++ if (rval) { ++ ql_log(ql_log_fatal, vha, 0x016c, ++ "-> Unable to read template size.\n"); ++ goto failed; ++ } ++ + risc_size = be32_to_cpu((__force __be32)dcode[2]); + ql_dbg(ql_dbg_init, vha, 0x0161, + "-> fwdt%u template array at %#x (%#x dwords)\n", +@@ -8509,11 +8556,12 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr, + } + + dcode = fwdt->template; +- qla24xx_read_flash_data(vha, dcode, faddr, risc_size); ++ rval = qla24xx_read_flash_data(vha, dcode, faddr, risc_size); + +- if (!qla27xx_fwdt_template_valid(dcode)) { ++ if (rval || !qla27xx_fwdt_template_valid(dcode)) { + ql_log(ql_log_warn, vha, 0x0165, +- "-> fwdt%u failed template validate\n", j); ++ "-> fwdt%u failed template validate (rval %x)\n", ++ j, rval); + goto failed; + } + +diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h +index a4a56ab0ba747..ef4b3cc1cd77e 100644 +--- a/drivers/scsi/qla2xxx/qla_inline.h ++++ b/drivers/scsi/qla2xxx/qla_inline.h +@@ -631,3 +631,11 @@ static inline int qla_mapq_alloc_qp_cpu_map(struct qla_hw_data *ha) + } + return 0; + } ++ ++static inline bool val_is_in_range(u32 val, u32 start, u32 end) ++{ ++ if (val >= start && val <= end) ++ return true; ++ else ++ return false; ++} +diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c +index b67416951a5f7..76703f2706b8e 100644 +--- a/drivers/scsi/qla2xxx/qla_mid.c ++++ b/drivers/scsi/qla2xxx/qla_mid.c +@@ -180,7 +180,7 @@ qla24xx_disable_vp(scsi_qla_host_t *vha) + atomic_set(&vha->loop_state, LOOP_DOWN); + atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); + list_for_each_entry(fcport, &vha->vp_fcports, list) +- fcport->logout_on_delete = 0; ++ fcport->logout_on_delete = 1; + + if (!vha->hw->flags.edif_enabled) + qla2x00_wait_for_sess_deletion(vha); +diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c +index a8ddf356e6626..8f4cc136a9c9c 100644 +--- a/drivers/scsi/qla2xxx/qla_nvme.c ++++ b/drivers/scsi/qla2xxx/qla_nvme.c +@@ -49,7 +49,10 @@ int qla_nvme_register_remote(struct scsi_qla_host *vha, struct fc_port *fcport) + return 0; + } + +- if (!vha->nvme_local_port && qla_nvme_register_hba(vha)) ++ if (qla_nvme_register_hba(vha)) ++ return 0; ++ ++ if (!vha->nvme_local_port) + return 0; + + if (!(fcport->nvme_prli_service_param & +diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c +index 63f45d50bf834..da8331dbb01ce 100644 +--- a/drivers/scsi/qla2xxx/qla_os.c ++++ b/drivers/scsi/qla2xxx/qla_os.c +@@ -1874,14 +1874,9 @@ __qla2x00_abort_all_cmds(struct qla_qpair *qp, int res) + for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) { + sp = req->outstanding_cmds[cnt]; + if (sp) { +- /* +- * perform lockless completion during driver unload +- */ + if (qla2x00_chip_is_down(vha)) { + req->outstanding_cmds[cnt] = NULL; +- spin_unlock_irqrestore(qp->qp_lock_ptr, flags); + sp->done(sp, res); +- spin_lock_irqsave(qp->qp_lock_ptr, flags); + continue; + } + +@@ -4688,7 +4683,7 @@ static void + qla2x00_number_of_exch(scsi_qla_host_t *vha, u32 *ret_cnt, u16 max_cnt) + { + u32 temp; +- struct init_cb_81xx *icb = (struct init_cb_81xx *)&vha->hw->init_cb; ++ struct init_cb_81xx *icb = (struct init_cb_81xx *)vha->hw->init_cb; + *ret_cnt = FW_DEF_EXCHANGES_CNT; + + if (max_cnt > vha->hw->max_exchg) +@@ -5562,15 +5557,11 @@ qla2x00_do_work(struct scsi_qla_host *vha) + qla2x00_async_prlo_done(vha, e->u.logio.fcport, + e->u.logio.data); + break; +- case QLA_EVT_GPNFT: +- qla24xx_async_gpnft(vha, e->u.gpnft.fc4_type, +- e->u.gpnft.sp); +- break; +- case QLA_EVT_GPNFT_DONE: +- qla24xx_async_gpnft_done(vha, e->u.iosb.sp); ++ case QLA_EVT_SCAN_CMD: ++ qla_fab_async_scan(vha, e->u.iosb.sp); + break; +- case QLA_EVT_GNNFT_DONE: +- qla24xx_async_gnnft_done(vha, e->u.iosb.sp); ++ case QLA_EVT_SCAN_FINISH: ++ qla_fab_scan_finish(vha, e->u.iosb.sp); + break; + case QLA_EVT_GFPNID: + qla24xx_async_gfpnid(vha, e->u.fcport.fcport); +diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c +index c092a6b1ced4f..6d16546e17292 100644 +--- a/drivers/scsi/qla2xxx/qla_sup.c ++++ b/drivers/scsi/qla2xxx/qla_sup.c +@@ -555,6 +555,7 @@ qla2xxx_find_flt_start(scsi_qla_host_t *vha, uint32_t *start) + struct qla_flt_location *fltl = (void *)req->ring; + uint32_t *dcode = (uint32_t *)req->ring; + uint8_t *buf = (void *)req->ring, *bcode, last_image; ++ int rc; + + /* + * FLT-location structure resides after the last PCI region. +@@ -584,14 +585,24 @@ qla2xxx_find_flt_start(scsi_qla_host_t *vha, uint32_t *start) + pcihdr = 0; + do { + /* Verify PCI expansion ROM header. */ +- qla24xx_read_flash_data(vha, dcode, pcihdr >> 2, 0x20); ++ rc = qla24xx_read_flash_data(vha, dcode, pcihdr >> 2, 0x20); ++ if (rc) { ++ ql_log(ql_log_info, vha, 0x016d, ++ "Unable to read PCI Expansion Rom Header (%x).\n", rc); ++ return QLA_FUNCTION_FAILED; ++ } + bcode = buf + (pcihdr % 4); + if (bcode[0x0] != 0x55 || bcode[0x1] != 0xaa) + goto end; + + /* Locate PCI data structure. */ + pcids = pcihdr + ((bcode[0x19] << 8) | bcode[0x18]); +- qla24xx_read_flash_data(vha, dcode, pcids >> 2, 0x20); ++ rc = qla24xx_read_flash_data(vha, dcode, pcids >> 2, 0x20); ++ if (rc) { ++ ql_log(ql_log_info, vha, 0x0179, ++ "Unable to read PCI Data Structure (%x).\n", rc); ++ return QLA_FUNCTION_FAILED; ++ } + bcode = buf + (pcihdr % 4); + + /* Validate signature of PCI data structure. */ +@@ -606,7 +617,12 @@ qla2xxx_find_flt_start(scsi_qla_host_t *vha, uint32_t *start) + } while (!last_image); + + /* Now verify FLT-location structure. */ +- qla24xx_read_flash_data(vha, dcode, pcihdr >> 2, sizeof(*fltl) >> 2); ++ rc = qla24xx_read_flash_data(vha, dcode, pcihdr >> 2, sizeof(*fltl) >> 2); ++ if (rc) { ++ ql_log(ql_log_info, vha, 0x017a, ++ "Unable to read FLT (%x).\n", rc); ++ return QLA_FUNCTION_FAILED; ++ } + if (memcmp(fltl->sig, "QFLT", 4)) + goto end; + +@@ -2605,13 +2621,18 @@ qla24xx_read_optrom_data(struct scsi_qla_host *vha, void *buf, + uint32_t offset, uint32_t length) + { + struct qla_hw_data *ha = vha->hw; ++ int rc; + + /* Suspend HBA. */ + scsi_block_requests(vha->host); + set_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); + + /* Go with read. */ +- qla24xx_read_flash_data(vha, buf, offset >> 2, length >> 2); ++ rc = qla24xx_read_flash_data(vha, buf, offset >> 2, length >> 2); ++ if (rc) { ++ ql_log(ql_log_info, vha, 0x01a0, ++ "Unable to perform optrom read(%x).\n", rc); ++ } + + /* Resume HBA. */ + clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); +@@ -3412,7 +3433,7 @@ qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf) + struct active_regions active_regions = { }; + + if (IS_P3P_TYPE(ha)) +- return ret; ++ return QLA_SUCCESS; + + if (!mbuf) + return QLA_FUNCTION_FAILED; +@@ -3432,20 +3453,31 @@ qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf) + + do { + /* Verify PCI expansion ROM header. */ +- qla24xx_read_flash_data(vha, dcode, pcihdr >> 2, 0x20); ++ ret = qla24xx_read_flash_data(vha, dcode, pcihdr >> 2, 0x20); ++ if (ret) { ++ ql_log(ql_log_info, vha, 0x017d, ++ "Unable to read PCI EXP Rom Header(%x).\n", ret); ++ return QLA_FUNCTION_FAILED; ++ } ++ + bcode = mbuf + (pcihdr % 4); + if (memcmp(bcode, "\x55\xaa", 2)) { + /* No signature */ + ql_log(ql_log_fatal, vha, 0x0059, + "No matching ROM signature.\n"); +- ret = QLA_FUNCTION_FAILED; +- break; ++ return QLA_FUNCTION_FAILED; + } + + /* Locate PCI data structure. */ + pcids = pcihdr + ((bcode[0x19] << 8) | bcode[0x18]); + +- qla24xx_read_flash_data(vha, dcode, pcids >> 2, 0x20); ++ ret = qla24xx_read_flash_data(vha, dcode, pcids >> 2, 0x20); ++ if (ret) { ++ ql_log(ql_log_info, vha, 0x018e, ++ "Unable to read PCI Data Structure (%x).\n", ret); ++ return QLA_FUNCTION_FAILED; ++ } ++ + bcode = mbuf + (pcihdr % 4); + + /* Validate signature of PCI data structure. */ +@@ -3454,8 +3486,7 @@ qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf) + ql_log(ql_log_fatal, vha, 0x005a, + "PCI data struct not found pcir_adr=%x.\n", pcids); + ql_dump_buffer(ql_dbg_init, vha, 0x0059, dcode, 32); +- ret = QLA_FUNCTION_FAILED; +- break; ++ return QLA_FUNCTION_FAILED; + } + + /* Read version */ +@@ -3507,20 +3538,26 @@ qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf) + faddr = ha->flt_region_fw_sec; + } + +- qla24xx_read_flash_data(vha, dcode, faddr, 8); +- if (qla24xx_risc_firmware_invalid(dcode)) { +- ql_log(ql_log_warn, vha, 0x005f, +- "Unrecognized fw revision at %x.\n", +- ha->flt_region_fw * 4); +- ql_dump_buffer(ql_dbg_init, vha, 0x005f, dcode, 32); ++ ret = qla24xx_read_flash_data(vha, dcode, faddr, 8); ++ if (ret) { ++ ql_log(ql_log_info, vha, 0x019e, ++ "Unable to read FW version (%x).\n", ret); ++ return ret; + } else { +- for (i = 0; i < 4; i++) +- ha->fw_revision[i] = ++ if (qla24xx_risc_firmware_invalid(dcode)) { ++ ql_log(ql_log_warn, vha, 0x005f, ++ "Unrecognized fw revision at %x.\n", ++ ha->flt_region_fw * 4); ++ ql_dump_buffer(ql_dbg_init, vha, 0x005f, dcode, 32); ++ } else { ++ for (i = 0; i < 4; i++) ++ ha->fw_revision[i] = + be32_to_cpu((__force __be32)dcode[4+i]); +- ql_dbg(ql_dbg_init, vha, 0x0060, +- "Firmware revision (flash) %u.%u.%u (%x).\n", +- ha->fw_revision[0], ha->fw_revision[1], +- ha->fw_revision[2], ha->fw_revision[3]); ++ ql_dbg(ql_dbg_init, vha, 0x0060, ++ "Firmware revision (flash) %u.%u.%u (%x).\n", ++ ha->fw_revision[0], ha->fw_revision[1], ++ ha->fw_revision[2], ha->fw_revision[3]); ++ } + } + + /* Check for golden firmware and get version if available */ +@@ -3531,18 +3568,23 @@ qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf) + + memset(ha->gold_fw_version, 0, sizeof(ha->gold_fw_version)); + faddr = ha->flt_region_gold_fw; +- qla24xx_read_flash_data(vha, dcode, ha->flt_region_gold_fw, 8); +- if (qla24xx_risc_firmware_invalid(dcode)) { +- ql_log(ql_log_warn, vha, 0x0056, +- "Unrecognized golden fw at %#x.\n", faddr); +- ql_dump_buffer(ql_dbg_init, vha, 0x0056, dcode, 32); ++ ret = qla24xx_read_flash_data(vha, dcode, ha->flt_region_gold_fw, 8); ++ if (ret) { ++ ql_log(ql_log_info, vha, 0x019f, ++ "Unable to read Gold FW version (%x).\n", ret); + return ret; +- } +- +- for (i = 0; i < 4; i++) +- ha->gold_fw_version[i] = +- be32_to_cpu((__force __be32)dcode[4+i]); ++ } else { ++ if (qla24xx_risc_firmware_invalid(dcode)) { ++ ql_log(ql_log_warn, vha, 0x0056, ++ "Unrecognized golden fw at %#x.\n", faddr); ++ ql_dump_buffer(ql_dbg_init, vha, 0x0056, dcode, 32); ++ return QLA_FUNCTION_FAILED; ++ } + ++ for (i = 0; i < 4; i++) ++ ha->gold_fw_version[i] = ++ be32_to_cpu((__force __be32)dcode[4+i]); ++ } + return ret; + } + +diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c +index a0d2556a27bba..089653018d32c 100644 +--- a/drivers/scsi/sr_ioctl.c ++++ b/drivers/scsi/sr_ioctl.c +@@ -431,7 +431,7 @@ int sr_select_speed(struct cdrom_device_info *cdi, unsigned long speed) + struct packet_command cgc; + + /* avoid exceeding the max speed or overflowing integer bounds */ +- speed = clamp(0, speed, 0xffff / 177); ++ speed = clamp(speed, 0, 0xffff / 177); + + if (speed == 0) + speed = 0xffff; /* set to max */ +diff --git a/drivers/soc/qcom/icc-bwmon.c b/drivers/soc/qcom/icc-bwmon.c +index adf2d523f103c..59ef8d739e93b 100644 +--- a/drivers/soc/qcom/icc-bwmon.c ++++ b/drivers/soc/qcom/icc-bwmon.c +@@ -565,7 +565,7 @@ static void bwmon_start(struct icc_bwmon *bwmon) + int window; + + /* No need to check for errors, as this must have succeeded before. */ +- dev_pm_opp_find_bw_ceil(bwmon->dev, &bw_low, 0); ++ dev_pm_opp_put(dev_pm_opp_find_bw_ceil(bwmon->dev, &bw_low, 0)); + + bwmon_clear_counters(bwmon, true); + +@@ -772,11 +772,13 @@ static int bwmon_probe(struct platform_device *pdev) + opp = dev_pm_opp_find_bw_floor(dev, &bwmon->max_bw_kbps, 0); + if (IS_ERR(opp)) + return dev_err_probe(dev, PTR_ERR(opp), "failed to find max peak bandwidth\n"); ++ dev_pm_opp_put(opp); + + bwmon->min_bw_kbps = 0; + opp = dev_pm_opp_find_bw_ceil(dev, &bwmon->min_bw_kbps, 0); + if (IS_ERR(opp)) + return dev_err_probe(dev, PTR_ERR(opp), "failed to find min peak bandwidth\n"); ++ dev_pm_opp_put(opp); + + bwmon->dev = dev; + +diff --git a/drivers/soc/qcom/pdr_interface.c b/drivers/soc/qcom/pdr_interface.c +index 0034af927b488..c7cd4daa10b0f 100644 +--- a/drivers/soc/qcom/pdr_interface.c ++++ b/drivers/soc/qcom/pdr_interface.c +@@ -76,12 +76,12 @@ static int pdr_locator_new_server(struct qmi_handle *qmi, + locator_hdl); + struct pdr_service *pds; + ++ mutex_lock(&pdr->lock); + /* Create a local client port for QMI communication */ + pdr->locator_addr.sq_family = AF_QIPCRTR; + pdr->locator_addr.sq_node = svc->node; + pdr->locator_addr.sq_port = svc->port; + +- mutex_lock(&pdr->lock); + pdr->locator_init_complete = true; + mutex_unlock(&pdr->lock); + +@@ -104,10 +104,10 @@ static void pdr_locator_del_server(struct qmi_handle *qmi, + + mutex_lock(&pdr->lock); + pdr->locator_init_complete = false; +- mutex_unlock(&pdr->lock); + + pdr->locator_addr.sq_node = 0; + pdr->locator_addr.sq_port = 0; ++ mutex_unlock(&pdr->lock); + } + + static const struct qmi_ops pdr_locator_ops = { +@@ -365,12 +365,14 @@ static int pdr_get_domain_list(struct servreg_get_domain_list_req *req, + if (ret < 0) + return ret; + ++ mutex_lock(&pdr->lock); + ret = qmi_send_request(&pdr->locator_hdl, + &pdr->locator_addr, + &txn, SERVREG_GET_DOMAIN_LIST_REQ, + SERVREG_GET_DOMAIN_LIST_REQ_MAX_LEN, + servreg_get_domain_list_req_ei, + req); ++ mutex_unlock(&pdr->lock); + if (ret < 0) { + qmi_txn_cancel(&txn); + return ret; +@@ -415,7 +417,7 @@ static int pdr_locate_service(struct pdr_handle *pdr, struct pdr_service *pds) + if (ret < 0) + goto out; + +- for (i = domains_read; i < resp->domain_list_len; i++) { ++ for (i = 0; i < resp->domain_list_len; i++) { + entry = &resp->domain_list[i]; + + if (strnlen(entry->name, sizeof(entry->name)) == sizeof(entry->name)) +diff --git a/drivers/soc/qcom/pmic_glink.c b/drivers/soc/qcom/pmic_glink.c +index 61a359938b6c4..71d261ac8aa45 100644 +--- a/drivers/soc/qcom/pmic_glink.c ++++ b/drivers/soc/qcom/pmic_glink.c +@@ -376,8 +376,17 @@ static struct platform_driver pmic_glink_driver = { + + static int pmic_glink_init(void) + { +- platform_driver_register(&pmic_glink_driver); +- register_rpmsg_driver(&pmic_glink_rpmsg_driver); ++ int ret; ++ ++ ret = platform_driver_register(&pmic_glink_driver); ++ if (ret < 0) ++ return ret; ++ ++ ret = register_rpmsg_driver(&pmic_glink_rpmsg_driver); ++ if (ret < 0) { ++ platform_driver_unregister(&pmic_glink_driver); ++ return ret; ++ } + + return 0; + }; +diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c +index daf64be966fe1..dfc2d4e38fa9b 100644 +--- a/drivers/soc/qcom/rpmh-rsc.c ++++ b/drivers/soc/qcom/rpmh-rsc.c +@@ -646,13 +646,14 @@ int rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg) + { + struct tcs_group *tcs; + int tcs_id; +- unsigned long flags; ++ ++ might_sleep(); + + tcs = get_tcs_for_msg(drv, msg); + if (IS_ERR(tcs)) + return PTR_ERR(tcs); + +- spin_lock_irqsave(&drv->lock, flags); ++ spin_lock_irq(&drv->lock); + + /* Wait forever for a free tcs. It better be there eventually! */ + wait_event_lock_irq(drv->tcs_wait, +@@ -670,7 +671,7 @@ int rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg) + write_tcs_reg_sync(drv, drv->regs[RSC_DRV_CMD_ENABLE], tcs_id, 0); + enable_tcs_irq(drv, tcs_id, true); + } +- spin_unlock_irqrestore(&drv->lock, flags); ++ spin_unlock_irq(&drv->lock); + + /* + * These two can be done after the lock is released because: +diff --git a/drivers/soc/qcom/rpmh.c b/drivers/soc/qcom/rpmh.c +index 08e09642d7f55..62dfc7df93541 100644 +--- a/drivers/soc/qcom/rpmh.c ++++ b/drivers/soc/qcom/rpmh.c +@@ -183,7 +183,6 @@ static int __rpmh_write(const struct device *dev, enum rpmh_state state, + } + + if (state == RPMH_ACTIVE_ONLY_STATE) { +- WARN_ON(irqs_disabled()); + ret = rpmh_rsc_send_data(ctrlr_to_drv(ctrlr), &rpm_msg->msg); + } else { + /* Clean up our call by spoofing tx_done */ +diff --git a/drivers/soc/xilinx/xlnx_event_manager.c b/drivers/soc/xilinx/xlnx_event_manager.c +index 042553abe1bf8..098a2ecfd5c68 100644 +--- a/drivers/soc/xilinx/xlnx_event_manager.c ++++ b/drivers/soc/xilinx/xlnx_event_manager.c +@@ -3,6 +3,7 @@ + * Xilinx Event Management Driver + * + * Copyright (C) 2021 Xilinx, Inc. ++ * Copyright (C) 2024 Advanced Micro Devices, Inc. + * + * Abhyuday Godhasara <abhyuday.godhasara@xilinx.com> + */ +@@ -19,7 +20,7 @@ + #include <linux/platform_device.h> + #include <linux/slab.h> + +-static DEFINE_PER_CPU_READ_MOSTLY(int, cpu_number1); ++static DEFINE_PER_CPU_READ_MOSTLY(int, dummy_cpu_number); + + static int virq_sgi; + static int event_manager_availability = -EACCES; +@@ -555,7 +556,6 @@ static void xlnx_disable_percpu_irq(void *data) + static int xlnx_event_init_sgi(struct platform_device *pdev) + { + int ret = 0; +- int cpu; + /* + * IRQ related structures are used for the following: + * for each SGI interrupt ensure its mapped by GIC IRQ domain +@@ -592,11 +592,8 @@ static int xlnx_event_init_sgi(struct platform_device *pdev) + sgi_fwspec.param[0] = sgi_num; + virq_sgi = irq_create_fwspec_mapping(&sgi_fwspec); + +- cpu = get_cpu(); +- per_cpu(cpu_number1, cpu) = cpu; + ret = request_percpu_irq(virq_sgi, xlnx_event_handler, "xlnx_event_mgmt", +- &cpu_number1); +- put_cpu(); ++ &dummy_cpu_number); + + WARN_ON(ret); + if (ret) { +@@ -612,16 +609,12 @@ static int xlnx_event_init_sgi(struct platform_device *pdev) + + static void xlnx_event_cleanup_sgi(struct platform_device *pdev) + { +- int cpu = smp_processor_id(); +- +- per_cpu(cpu_number1, cpu) = cpu; +- + cpuhp_remove_state(CPUHP_AP_ONLINE_DYN); + + on_each_cpu(xlnx_disable_percpu_irq, NULL, 1); + + irq_clear_status_flags(virq_sgi, IRQ_PER_CPU); +- free_percpu_irq(virq_sgi, &cpu_number1); ++ free_percpu_irq(virq_sgi, &dummy_cpu_number); + irq_dispose_mapping(virq_sgi); + } + +diff --git a/drivers/soc/xilinx/zynqmp_power.c b/drivers/soc/xilinx/zynqmp_power.c +index c2c819701eec1..d7c784d77208c 100644 +--- a/drivers/soc/xilinx/zynqmp_power.c ++++ b/drivers/soc/xilinx/zynqmp_power.c +@@ -188,7 +188,9 @@ static int zynqmp_pm_probe(struct platform_device *pdev) + u32 pm_api_version; + struct mbox_client *client; + +- zynqmp_pm_get_api_version(&pm_api_version); ++ ret = zynqmp_pm_get_api_version(&pm_api_version); ++ if (ret) ++ return ret; + + /* Check PM API version number */ + if (pm_api_version < ZYNQMP_PM_VERSION) +diff --git a/drivers/spi/atmel-quadspi.c b/drivers/spi/atmel-quadspi.c +index 3d1252566134b..4cc4f32ca4490 100644 +--- a/drivers/spi/atmel-quadspi.c ++++ b/drivers/spi/atmel-quadspi.c +@@ -756,8 +756,15 @@ static int __maybe_unused atmel_qspi_resume(struct device *dev) + struct atmel_qspi *aq = spi_controller_get_devdata(ctrl); + int ret; + +- clk_prepare(aq->pclk); +- clk_prepare(aq->qspick); ++ ret = clk_prepare(aq->pclk); ++ if (ret) ++ return ret; ++ ++ ret = clk_prepare(aq->qspick); ++ if (ret) { ++ clk_unprepare(aq->pclk); ++ return ret; ++ } + + ret = pm_runtime_force_resume(dev); + if (ret < 0) +diff --git a/drivers/spi/spi-microchip-core.c b/drivers/spi/spi-microchip-core.c +index b451cd4860ecb..aa05127c8696c 100644 +--- a/drivers/spi/spi-microchip-core.c ++++ b/drivers/spi/spi-microchip-core.c +@@ -21,7 +21,7 @@ + #include <linux/spi/spi.h> + + #define MAX_LEN (0xffff) +-#define MAX_CS (8) ++#define MAX_CS (1) + #define DEFAULT_FRAMESIZE (8) + #define FIFO_DEPTH (32) + #define CLK_GEN_MODE1_MAX (255) +@@ -75,6 +75,7 @@ + + #define REG_CONTROL (0x00) + #define REG_FRAME_SIZE (0x04) ++#define FRAME_SIZE_MASK GENMASK(5, 0) + #define REG_STATUS (0x08) + #define REG_INT_CLEAR (0x0c) + #define REG_RX_DATA (0x10) +@@ -89,6 +90,9 @@ + #define REG_RIS (0x24) + #define REG_CONTROL2 (0x28) + #define REG_COMMAND (0x2c) ++#define COMMAND_CLRFRAMECNT BIT(4) ++#define COMMAND_TXFIFORST BIT(3) ++#define COMMAND_RXFIFORST BIT(2) + #define REG_PKTSIZE (0x30) + #define REG_CMD_SIZE (0x34) + #define REG_HWSTATUS (0x38) +@@ -103,6 +107,7 @@ struct mchp_corespi { + u8 *rx_buf; + u32 clk_gen; /* divider for spi output clock generated by the controller */ + u32 clk_mode; ++ u32 pending_slave_select; + int irq; + int tx_len; + int rx_len; +@@ -148,62 +153,59 @@ static inline void mchp_corespi_read_fifo(struct mchp_corespi *spi) + + static void mchp_corespi_enable_ints(struct mchp_corespi *spi) + { +- u32 control, mask = INT_ENABLE_MASK; +- +- mchp_corespi_disable(spi); +- +- control = mchp_corespi_read(spi, REG_CONTROL); +- +- control |= mask; +- mchp_corespi_write(spi, REG_CONTROL, control); ++ u32 control = mchp_corespi_read(spi, REG_CONTROL); + +- control |= CONTROL_ENABLE; ++ control |= INT_ENABLE_MASK; + mchp_corespi_write(spi, REG_CONTROL, control); + } + + static void mchp_corespi_disable_ints(struct mchp_corespi *spi) + { +- u32 control, mask = INT_ENABLE_MASK; +- +- mchp_corespi_disable(spi); +- +- control = mchp_corespi_read(spi, REG_CONTROL); +- control &= ~mask; +- mchp_corespi_write(spi, REG_CONTROL, control); ++ u32 control = mchp_corespi_read(spi, REG_CONTROL); + +- control |= CONTROL_ENABLE; ++ control &= ~INT_ENABLE_MASK; + mchp_corespi_write(spi, REG_CONTROL, control); + } + + static inline void mchp_corespi_set_xfer_size(struct mchp_corespi *spi, int len) + { + u32 control; +- u16 lenpart; ++ u32 lenpart; ++ u32 frames = mchp_corespi_read(spi, REG_FRAMESUP); + + /* +- * Disable the SPI controller. Writes to transfer length have +- * no effect when the controller is enabled. ++ * Writing to FRAMECNT in REG_CONTROL will reset the frame count, taking ++ * a shortcut requires an explicit clear. + */ +- mchp_corespi_disable(spi); ++ if (frames == len) { ++ mchp_corespi_write(spi, REG_COMMAND, COMMAND_CLRFRAMECNT); ++ return; ++ } + + /* + * The lower 16 bits of the frame count are stored in the control reg + * for legacy reasons, but the upper 16 written to a different register: + * FRAMESUP. While both the upper and lower bits can be *READ* from the +- * FRAMESUP register, writing to the lower 16 bits is a NOP ++ * FRAMESUP register, writing to the lower 16 bits is (supposedly) a NOP. ++ * ++ * The driver used to disable the controller while modifying the frame ++ * count, and mask off the lower 16 bits of len while writing to ++ * FRAMES_UP. When the driver was changed to disable the controller as ++ * infrequently as possible, it was discovered that the logic of ++ * lenpart = len & 0xffff_0000 ++ * write(REG_FRAMESUP, lenpart) ++ * would actually write zeros into the lower 16 bits on an mpfs250t-es, ++ * despite documentation stating these bits were read-only. ++ * Writing len unmasked into FRAMES_UP ensures those bits aren't zeroed ++ * on an mpfs250t-es and will be a NOP for the lower 16 bits on hardware ++ * that matches the documentation. + */ + lenpart = len & 0xffff; +- + control = mchp_corespi_read(spi, REG_CONTROL); + control &= ~CONTROL_FRAMECNT_MASK; + control |= lenpart << CONTROL_FRAMECNT_SHIFT; + mchp_corespi_write(spi, REG_CONTROL, control); +- +- lenpart = len & 0xffff0000; +- mchp_corespi_write(spi, REG_FRAMESUP, lenpart); +- +- control |= CONTROL_ENABLE; +- mchp_corespi_write(spi, REG_CONTROL, control); ++ mchp_corespi_write(spi, REG_FRAMESUP, len); + } + + static inline void mchp_corespi_write_fifo(struct mchp_corespi *spi) +@@ -226,17 +228,22 @@ static inline void mchp_corespi_write_fifo(struct mchp_corespi *spi) + + static inline void mchp_corespi_set_framesize(struct mchp_corespi *spi, int bt) + { ++ u32 frame_size = mchp_corespi_read(spi, REG_FRAME_SIZE); + u32 control; + ++ if ((frame_size & FRAME_SIZE_MASK) == bt) ++ return; ++ + /* + * Disable the SPI controller. Writes to the frame size have + * no effect when the controller is enabled. + */ +- mchp_corespi_disable(spi); ++ control = mchp_corespi_read(spi, REG_CONTROL); ++ control &= ~CONTROL_ENABLE; ++ mchp_corespi_write(spi, REG_CONTROL, control); + + mchp_corespi_write(spi, REG_FRAME_SIZE, bt); + +- control = mchp_corespi_read(spi, REG_CONTROL); + control |= CONTROL_ENABLE; + mchp_corespi_write(spi, REG_CONTROL, control); + } +@@ -244,49 +251,56 @@ static inline void mchp_corespi_set_framesize(struct mchp_corespi *spi, int bt) + static void mchp_corespi_set_cs(struct spi_device *spi, bool disable) + { + u32 reg; +- struct mchp_corespi *corespi = spi_master_get_devdata(spi->master); ++ struct mchp_corespi *corespi = spi_controller_get_devdata(spi->controller); + + reg = mchp_corespi_read(corespi, REG_SLAVE_SELECT); + reg &= ~BIT(spi_get_chipselect(spi, 0)); + reg |= !disable << spi_get_chipselect(spi, 0); ++ corespi->pending_slave_select = reg; + +- mchp_corespi_write(corespi, REG_SLAVE_SELECT, reg); ++ /* ++ * Only deassert chip select immediately. Writing to some registers ++ * requires the controller to be disabled, which results in the ++ * output pins being tristated and can cause the SCLK and MOSI lines ++ * to transition. Therefore asserting the chip select is deferred ++ * until just before writing to the TX FIFO, to ensure the device ++ * doesn't see any spurious clock transitions whilst CS is enabled. ++ */ ++ if (((spi->mode & SPI_CS_HIGH) == 0) == disable) ++ mchp_corespi_write(corespi, REG_SLAVE_SELECT, reg); + } + + static int mchp_corespi_setup(struct spi_device *spi) + { +- struct mchp_corespi *corespi = spi_master_get_devdata(spi->master); ++ struct mchp_corespi *corespi = spi_controller_get_devdata(spi->controller); + u32 reg; + + /* +- * Active high slaves need to be specifically set to their inactive ++ * Active high targets need to be specifically set to their inactive + * states during probe by adding them to the "control group" & thus + * driving their select line low. + */ + if (spi->mode & SPI_CS_HIGH) { + reg = mchp_corespi_read(corespi, REG_SLAVE_SELECT); + reg |= BIT(spi_get_chipselect(spi, 0)); ++ corespi->pending_slave_select = reg; + mchp_corespi_write(corespi, REG_SLAVE_SELECT, reg); + } + return 0; + } + +-static void mchp_corespi_init(struct spi_master *master, struct mchp_corespi *spi) ++static void mchp_corespi_init(struct spi_controller *host, struct mchp_corespi *spi) + { + unsigned long clk_hz; + u32 control = mchp_corespi_read(spi, REG_CONTROL); + +- control |= CONTROL_MASTER; ++ control &= ~CONTROL_ENABLE; ++ mchp_corespi_write(spi, REG_CONTROL, control); + ++ control |= CONTROL_MASTER; + control &= ~CONTROL_MODE_MASK; + control |= MOTOROLA_MODE; + +- mchp_corespi_set_framesize(spi, DEFAULT_FRAMESIZE); +- +- /* max. possible spi clock rate is the apb clock rate */ +- clk_hz = clk_get_rate(spi->clk); +- master->max_speed_hz = clk_hz; +- + /* + * The controller must be configured so that it doesn't remove Chip + * Select until the entire message has been transferred, even if at +@@ -295,19 +309,25 @@ static void mchp_corespi_init(struct spi_master *master, struct mchp_corespi *sp + * BIGFIFO mode is also enabled, which sets the fifo depth to 32 frames + * for the 8 bit transfers that this driver uses. + */ +- control = mchp_corespi_read(spi, REG_CONTROL); + control |= CONTROL_SPS | CONTROL_BIGFIFO; + + mchp_corespi_write(spi, REG_CONTROL, control); + ++ mchp_corespi_set_framesize(spi, DEFAULT_FRAMESIZE); ++ ++ /* max. possible spi clock rate is the apb clock rate */ ++ clk_hz = clk_get_rate(spi->clk); ++ host->max_speed_hz = clk_hz; ++ + mchp_corespi_enable_ints(spi); + + /* + * It is required to enable direct mode, otherwise control over the chip + * select is relinquished to the hardware. SSELOUT is enabled too so we +- * can deal with active high slaves. ++ * can deal with active high targets. + */ +- mchp_corespi_write(spi, REG_SLAVE_SELECT, SSELOUT | SSEL_DIRECT); ++ spi->pending_slave_select = SSELOUT | SSEL_DIRECT; ++ mchp_corespi_write(spi, REG_SLAVE_SELECT, spi->pending_slave_select); + + control = mchp_corespi_read(spi, REG_CONTROL); + +@@ -321,8 +341,6 @@ static inline void mchp_corespi_set_clk_gen(struct mchp_corespi *spi) + { + u32 control; + +- mchp_corespi_disable(spi); +- + control = mchp_corespi_read(spi, REG_CONTROL); + if (spi->clk_mode) + control |= CONTROL_CLKMODE; +@@ -331,12 +349,12 @@ static inline void mchp_corespi_set_clk_gen(struct mchp_corespi *spi) + + mchp_corespi_write(spi, REG_CLK_GEN, spi->clk_gen); + mchp_corespi_write(spi, REG_CONTROL, control); +- mchp_corespi_write(spi, REG_CONTROL, control | CONTROL_ENABLE); + } + + static inline void mchp_corespi_set_mode(struct mchp_corespi *spi, unsigned int mode) + { +- u32 control, mode_val; ++ u32 mode_val; ++ u32 control = mchp_corespi_read(spi, REG_CONTROL); + + switch (mode & SPI_MODE_X_MASK) { + case SPI_MODE_0: +@@ -354,12 +372,13 @@ static inline void mchp_corespi_set_mode(struct mchp_corespi *spi, unsigned int + } + + /* +- * Disable the SPI controller. Writes to the frame size have ++ * Disable the SPI controller. Writes to the frame protocol have + * no effect when the controller is enabled. + */ +- mchp_corespi_disable(spi); + +- control = mchp_corespi_read(spi, REG_CONTROL); ++ control &= ~CONTROL_ENABLE; ++ mchp_corespi_write(spi, REG_CONTROL, control); ++ + control &= ~(SPI_MODE_X_MASK << MODE_X_MASK_SHIFT); + control |= mode_val; + +@@ -371,8 +390,8 @@ static inline void mchp_corespi_set_mode(struct mchp_corespi *spi, unsigned int + + static irqreturn_t mchp_corespi_interrupt(int irq, void *dev_id) + { +- struct spi_master *master = dev_id; +- struct mchp_corespi *spi = spi_master_get_devdata(master); ++ struct spi_controller *host = dev_id; ++ struct mchp_corespi *spi = spi_controller_get_devdata(host); + u32 intfield = mchp_corespi_read(spi, REG_MIS) & 0xf; + bool finalise = false; + +@@ -380,26 +399,23 @@ static irqreturn_t mchp_corespi_interrupt(int irq, void *dev_id) + if (intfield == 0) + return IRQ_NONE; + +- if (intfield & INT_TXDONE) { ++ if (intfield & INT_TXDONE) + mchp_corespi_write(spi, REG_INT_CLEAR, INT_TXDONE); + ++ if (intfield & INT_RXRDY) { ++ mchp_corespi_write(spi, REG_INT_CLEAR, INT_RXRDY); ++ + if (spi->rx_len) + mchp_corespi_read_fifo(spi); +- +- if (spi->tx_len) +- mchp_corespi_write_fifo(spi); +- +- if (!spi->rx_len) +- finalise = true; + } + +- if (intfield & INT_RXRDY) +- mchp_corespi_write(spi, REG_INT_CLEAR, INT_RXRDY); ++ if (!spi->rx_len && !spi->tx_len) ++ finalise = true; + + if (intfield & INT_RX_CHANNEL_OVERFLOW) { + mchp_corespi_write(spi, REG_INT_CLEAR, INT_RX_CHANNEL_OVERFLOW); + finalise = true; +- dev_err(&master->dev, ++ dev_err(&host->dev, + "%s: RX OVERFLOW: rxlen: %d, txlen: %d\n", __func__, + spi->rx_len, spi->tx_len); + } +@@ -407,13 +423,13 @@ static irqreturn_t mchp_corespi_interrupt(int irq, void *dev_id) + if (intfield & INT_TX_CHANNEL_UNDERRUN) { + mchp_corespi_write(spi, REG_INT_CLEAR, INT_TX_CHANNEL_UNDERRUN); + finalise = true; +- dev_err(&master->dev, ++ dev_err(&host->dev, + "%s: TX UNDERFLOW: rxlen: %d, txlen: %d\n", __func__, + spi->rx_len, spi->tx_len); + } + + if (finalise) +- spi_finalize_current_transfer(master); ++ spi_finalize_current_transfer(host); + + return IRQ_HANDLED; + } +@@ -455,16 +471,16 @@ static int mchp_corespi_calculate_clkgen(struct mchp_corespi *spi, + return 0; + } + +-static int mchp_corespi_transfer_one(struct spi_master *master, ++static int mchp_corespi_transfer_one(struct spi_controller *host, + struct spi_device *spi_dev, + struct spi_transfer *xfer) + { +- struct mchp_corespi *spi = spi_master_get_devdata(master); ++ struct mchp_corespi *spi = spi_controller_get_devdata(host); + int ret; + + ret = mchp_corespi_calculate_clkgen(spi, (unsigned long)xfer->speed_hz); + if (ret) { +- dev_err(&master->dev, "failed to set clk_gen for target %u Hz\n", xfer->speed_hz); ++ dev_err(&host->dev, "failed to set clk_gen for target %u Hz\n", xfer->speed_hz); + return ret; + } + +@@ -479,16 +495,21 @@ static int mchp_corespi_transfer_one(struct spi_master *master, + mchp_corespi_set_xfer_size(spi, (spi->tx_len > FIFO_DEPTH) + ? FIFO_DEPTH : spi->tx_len); + +- if (spi->tx_len) ++ mchp_corespi_write(spi, REG_COMMAND, COMMAND_RXFIFORST | COMMAND_TXFIFORST); ++ ++ mchp_corespi_write(spi, REG_SLAVE_SELECT, spi->pending_slave_select); ++ ++ while (spi->tx_len) + mchp_corespi_write_fifo(spi); ++ + return 1; + } + +-static int mchp_corespi_prepare_message(struct spi_master *master, ++static int mchp_corespi_prepare_message(struct spi_controller *host, + struct spi_message *msg) + { + struct spi_device *spi_dev = msg->spi; +- struct mchp_corespi *spi = spi_master_get_devdata(master); ++ struct mchp_corespi *spi = spi_controller_get_devdata(host); + + mchp_corespi_set_framesize(spi, DEFAULT_FRAMESIZE); + mchp_corespi_set_mode(spi, spi_dev->mode); +@@ -498,32 +519,32 @@ static int mchp_corespi_prepare_message(struct spi_master *master, + + static int mchp_corespi_probe(struct platform_device *pdev) + { +- struct spi_master *master; ++ struct spi_controller *host; + struct mchp_corespi *spi; + struct resource *res; + u32 num_cs; + int ret = 0; + +- master = devm_spi_alloc_master(&pdev->dev, sizeof(*spi)); +- if (!master) ++ host = devm_spi_alloc_host(&pdev->dev, sizeof(*spi)); ++ if (!host) + return dev_err_probe(&pdev->dev, -ENOMEM, +- "unable to allocate master for SPI controller\n"); ++ "unable to allocate host for SPI controller\n"); + +- platform_set_drvdata(pdev, master); ++ platform_set_drvdata(pdev, host); + + if (of_property_read_u32(pdev->dev.of_node, "num-cs", &num_cs)) + num_cs = MAX_CS; + +- master->num_chipselect = num_cs; +- master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; +- master->setup = mchp_corespi_setup; +- master->bits_per_word_mask = SPI_BPW_MASK(8); +- master->transfer_one = mchp_corespi_transfer_one; +- master->prepare_message = mchp_corespi_prepare_message; +- master->set_cs = mchp_corespi_set_cs; +- master->dev.of_node = pdev->dev.of_node; ++ host->num_chipselect = num_cs; ++ host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; ++ host->setup = mchp_corespi_setup; ++ host->bits_per_word_mask = SPI_BPW_MASK(8); ++ host->transfer_one = mchp_corespi_transfer_one; ++ host->prepare_message = mchp_corespi_prepare_message; ++ host->set_cs = mchp_corespi_set_cs; ++ host->dev.of_node = pdev->dev.of_node; + +- spi = spi_master_get_devdata(master); ++ spi = spi_controller_get_devdata(host); + + spi->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res); + if (IS_ERR(spi->regs)) +@@ -534,7 +555,7 @@ static int mchp_corespi_probe(struct platform_device *pdev) + return spi->irq; + + ret = devm_request_irq(&pdev->dev, spi->irq, mchp_corespi_interrupt, +- IRQF_SHARED, dev_name(&pdev->dev), master); ++ IRQF_SHARED, dev_name(&pdev->dev), host); + if (ret) + return dev_err_probe(&pdev->dev, ret, + "could not request irq\n"); +@@ -549,25 +570,25 @@ static int mchp_corespi_probe(struct platform_device *pdev) + return dev_err_probe(&pdev->dev, ret, + "failed to enable clock\n"); + +- mchp_corespi_init(master, spi); ++ mchp_corespi_init(host, spi); + +- ret = devm_spi_register_master(&pdev->dev, master); ++ ret = devm_spi_register_controller(&pdev->dev, host); + if (ret) { + mchp_corespi_disable(spi); + clk_disable_unprepare(spi->clk); + return dev_err_probe(&pdev->dev, ret, +- "unable to register master for SPI controller\n"); ++ "unable to register host for SPI controller\n"); + } + +- dev_info(&pdev->dev, "Registered SPI controller %d\n", master->bus_num); ++ dev_info(&pdev->dev, "Registered SPI controller %d\n", host->bus_num); + + return 0; + } + + static void mchp_corespi_remove(struct platform_device *pdev) + { +- struct spi_master *master = platform_get_drvdata(pdev); +- struct mchp_corespi *spi = spi_master_get_devdata(master); ++ struct spi_controller *host = platform_get_drvdata(pdev); ++ struct mchp_corespi *spi = spi_controller_get_devdata(host); + + mchp_corespi_disable_ints(spi); + clk_disable_unprepare(spi->clk); +diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c +index d13dc15cc1919..1a8dd10012448 100644 +--- a/drivers/spi/spidev.c ++++ b/drivers/spi/spidev.c +@@ -738,6 +738,7 @@ static const struct of_device_id spidev_dt_ids[] = { + { .compatible = "lwn,bk4", .data = &spidev_of_check }, + { .compatible = "menlo,m53cpld", .data = &spidev_of_check }, + { .compatible = "micron,spi-authenta", .data = &spidev_of_check }, ++ { .compatible = "rohm,bh2228fv", .data = &spidev_of_check }, + { .compatible = "rohm,dh2228fv", .data = &spidev_of_check }, + { .compatible = "semtech,sx1301", .data = &spidev_of_check }, + { .compatible = "silabs,em3581", .data = &spidev_of_check }, +diff --git a/drivers/ufs/core/ufs-mcq.c b/drivers/ufs/core/ufs-mcq.c +index a10fc7a697109..af5ce45315b3c 100644 +--- a/drivers/ufs/core/ufs-mcq.c ++++ b/drivers/ufs/core/ufs-mcq.c +@@ -230,8 +230,6 @@ int ufshcd_mcq_memory_alloc(struct ufs_hba *hba) + + /* Operation and runtime registers configuration */ + #define MCQ_CFG_n(r, i) ((r) + MCQ_QCFG_SIZE * (i)) +-#define MCQ_OPR_OFFSET_n(p, i) \ +- (hba->mcq_opr[(p)].offset + hba->mcq_opr[(p)].stride * (i)) + + static void __iomem *mcq_opr_base(struct ufs_hba *hba, + enum ufshcd_mcq_opr n, int i) +@@ -344,10 +342,10 @@ void ufshcd_mcq_make_queues_operational(struct ufs_hba *hba) + ufsmcq_writelx(hba, upper_32_bits(hwq->sqe_dma_addr), + MCQ_CFG_n(REG_SQUBA, i)); + /* Submission Queue Doorbell Address Offset */ +- ufsmcq_writelx(hba, MCQ_OPR_OFFSET_n(OPR_SQD, i), ++ ufsmcq_writelx(hba, ufshcd_mcq_opr_offset(hba, OPR_SQD, i), + MCQ_CFG_n(REG_SQDAO, i)); + /* Submission Queue Interrupt Status Address Offset */ +- ufsmcq_writelx(hba, MCQ_OPR_OFFSET_n(OPR_SQIS, i), ++ ufsmcq_writelx(hba, ufshcd_mcq_opr_offset(hba, OPR_SQIS, i), + MCQ_CFG_n(REG_SQISAO, i)); + + /* Completion Queue Lower Base Address */ +@@ -357,10 +355,10 @@ void ufshcd_mcq_make_queues_operational(struct ufs_hba *hba) + ufsmcq_writelx(hba, upper_32_bits(hwq->cqe_dma_addr), + MCQ_CFG_n(REG_CQUBA, i)); + /* Completion Queue Doorbell Address Offset */ +- ufsmcq_writelx(hba, MCQ_OPR_OFFSET_n(OPR_CQD, i), ++ ufsmcq_writelx(hba, ufshcd_mcq_opr_offset(hba, OPR_CQD, i), + MCQ_CFG_n(REG_CQDAO, i)); + /* Completion Queue Interrupt Status Address Offset */ +- ufsmcq_writelx(hba, MCQ_OPR_OFFSET_n(OPR_CQIS, i), ++ ufsmcq_writelx(hba, ufshcd_mcq_opr_offset(hba, OPR_CQIS, i), + MCQ_CFG_n(REG_CQISAO, i)); + + /* Save the base addresses for quicker access */ +diff --git a/drivers/usb/typec/mux/nb7vpq904m.c b/drivers/usb/typec/mux/nb7vpq904m.c +index cda206cf0c387..596639dad31d7 100644 +--- a/drivers/usb/typec/mux/nb7vpq904m.c ++++ b/drivers/usb/typec/mux/nb7vpq904m.c +@@ -453,7 +453,7 @@ static int nb7vpq904m_probe(struct i2c_client *client) + + ret = nb7vpq904m_parse_data_lanes_mapping(nb7); + if (ret) +- return ret; ++ goto err_switch_put; + + ret = regulator_enable(nb7->vcc_supply); + if (ret) +@@ -496,6 +496,9 @@ static int nb7vpq904m_probe(struct i2c_client *client) + gpiod_set_value(nb7->enable_gpio, 0); + regulator_disable(nb7->vcc_supply); + ++err_switch_put: ++ typec_switch_put(nb7->typec_switch); ++ + return ret; + } + +@@ -509,6 +512,8 @@ static void nb7vpq904m_remove(struct i2c_client *client) + gpiod_set_value(nb7->enable_gpio, 0); + + regulator_disable(nb7->vcc_supply); ++ ++ typec_switch_put(nb7->typec_switch); + } + + static const struct i2c_device_id nb7vpq904m_table[] = { +diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c +index 61255855d4906..d94a06008ff64 100644 +--- a/drivers/vhost/vsock.c ++++ b/drivers/vhost/vsock.c +@@ -656,6 +656,7 @@ static int vhost_vsock_dev_open(struct inode *inode, struct file *file) + } + + vsock->guest_cid = 0; /* no CID assigned yet */ ++ vsock->seqpacket_allow = false; + + atomic_set(&vsock->queued_replies, 0); + +@@ -799,8 +800,7 @@ static int vhost_vsock_set_features(struct vhost_vsock *vsock, u64 features) + goto err; + } + +- if (features & (1ULL << VIRTIO_VSOCK_F_SEQPACKET)) +- vsock->seqpacket_allow = true; ++ vsock->seqpacket_allow = features & (1ULL << VIRTIO_VSOCK_F_SEQPACKET); + + for (i = 0; i < ARRAY_SIZE(vsock->vqs); i++) { + vq = &vsock->vqs[i]; +diff --git a/drivers/video/logo/pnmtologo.c b/drivers/video/logo/pnmtologo.c +index ada5ef6e51b7a..87912cc35e924 100644 +--- a/drivers/video/logo/pnmtologo.c ++++ b/drivers/video/logo/pnmtologo.c +@@ -235,8 +235,6 @@ static void write_header(void) + fputs("/*\n", out); + fputs(" * DO NOT EDIT THIS FILE!\n", out); + fputs(" *\n", out); +- fprintf(out, " * It was automatically generated from %s\n", filename); +- fputs(" *\n", out); + fprintf(out, " * Linux logo %s\n", logoname); + fputs(" */\n\n", out); + fputs("#include <linux/linux_logo.h>\n\n", out); +diff --git a/drivers/watchdog/rzg2l_wdt.c b/drivers/watchdog/rzg2l_wdt.c +index 1741f98ca67c5..7bce093316c4d 100644 +--- a/drivers/watchdog/rzg2l_wdt.c ++++ b/drivers/watchdog/rzg2l_wdt.c +@@ -123,8 +123,11 @@ static void rzg2l_wdt_init_timeout(struct watchdog_device *wdev) + static int rzg2l_wdt_start(struct watchdog_device *wdev) + { + struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev); ++ int ret; + +- pm_runtime_get_sync(wdev->parent); ++ ret = pm_runtime_resume_and_get(wdev->parent); ++ if (ret) ++ return ret; + + /* Initialize time out */ + rzg2l_wdt_init_timeout(wdev); +@@ -141,15 +144,21 @@ static int rzg2l_wdt_start(struct watchdog_device *wdev) + static int rzg2l_wdt_stop(struct watchdog_device *wdev) + { + struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev); ++ int ret; + + rzg2l_wdt_reset(priv); +- pm_runtime_put(wdev->parent); ++ ++ ret = pm_runtime_put(wdev->parent); ++ if (ret < 0) ++ return ret; + + return 0; + } + + static int rzg2l_wdt_set_timeout(struct watchdog_device *wdev, unsigned int timeout) + { ++ int ret = 0; ++ + wdev->timeout = timeout; + + /* +@@ -158,11 +167,14 @@ static int rzg2l_wdt_set_timeout(struct watchdog_device *wdev, unsigned int time + * to reset the module) so that it is updated with new timeout values. + */ + if (watchdog_active(wdev)) { +- rzg2l_wdt_stop(wdev); +- rzg2l_wdt_start(wdev); ++ ret = rzg2l_wdt_stop(wdev); ++ if (ret) ++ return ret; ++ ++ ret = rzg2l_wdt_start(wdev); + } + +- return 0; ++ return ret; + } + + static int rzg2l_wdt_restart(struct watchdog_device *wdev, +diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c +index 8818ed5c390fa..a815ce9cfb518 100644 +--- a/fs/btrfs/compression.c ++++ b/fs/btrfs/compression.c +@@ -420,6 +420,7 @@ static noinline int add_ra_bio_pages(struct inode *inode, + put_page(page); + break; + } ++ add_size = min(em->start + em->len, page_end + 1) - cur; + free_extent_map(em); + + if (page->index == end_index) { +@@ -432,7 +433,6 @@ static noinline int add_ra_bio_pages(struct inode *inode, + } + } + +- add_size = min(em->start + em->len, page_end + 1) - cur; + ret = bio_add_page(orig_bio, page, add_size, offset_in_page(cur)); + if (ret != add_size) { + unlock_extent(tree, cur, page_end, NULL); +diff --git a/fs/ceph/super.c b/fs/ceph/super.c +index 52af90beab000..ec51e398562c6 100644 +--- a/fs/ceph/super.c ++++ b/fs/ceph/super.c +@@ -958,7 +958,8 @@ static int __init init_caches(void) + if (!ceph_mds_request_cachep) + goto bad_mds_req; + +- ceph_wb_pagevec_pool = mempool_create_kmalloc_pool(10, CEPH_MAX_WRITE_SIZE >> PAGE_SHIFT); ++ ceph_wb_pagevec_pool = mempool_create_kmalloc_pool(10, ++ (CEPH_MAX_WRITE_SIZE >> PAGE_SHIFT) * sizeof(struct page *)); + if (!ceph_wb_pagevec_pool) + goto bad_pagevec_pool; + +diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c +index e1586bba6d862..7a715016b96f3 100644 +--- a/fs/exfat/dir.c ++++ b/fs/exfat/dir.c +@@ -890,7 +890,7 @@ int exfat_get_dentry_set(struct exfat_entry_set_cache *es, + + num_bh = EXFAT_B_TO_BLK_ROUND_UP(off + num_entries * DENTRY_SIZE, sb); + if (num_bh > ARRAY_SIZE(es->__bh)) { +- es->bh = kmalloc_array(num_bh, sizeof(*es->bh), GFP_KERNEL); ++ es->bh = kmalloc_array(num_bh, sizeof(*es->bh), GFP_NOFS); + if (!es->bh) { + brelse(bh); + return -ENOMEM; +diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c +index e124f3d709b23..f2052723821af 100644 +--- a/fs/ext2/balloc.c ++++ b/fs/ext2/balloc.c +@@ -77,26 +77,33 @@ static int ext2_valid_block_bitmap(struct super_block *sb, + ext2_grpblk_t next_zero_bit; + ext2_fsblk_t bitmap_blk; + ext2_fsblk_t group_first_block; ++ ext2_grpblk_t max_bit; + + group_first_block = ext2_group_first_block_no(sb, block_group); ++ max_bit = ext2_group_last_block_no(sb, block_group) - group_first_block; + + /* check whether block bitmap block number is set */ + bitmap_blk = le32_to_cpu(desc->bg_block_bitmap); + offset = bitmap_blk - group_first_block; +- if (!ext2_test_bit(offset, bh->b_data)) ++ if (offset < 0 || offset > max_bit || ++ !ext2_test_bit(offset, bh->b_data)) + /* bad block bitmap */ + goto err_out; + + /* check whether the inode bitmap block number is set */ + bitmap_blk = le32_to_cpu(desc->bg_inode_bitmap); + offset = bitmap_blk - group_first_block; +- if (!ext2_test_bit(offset, bh->b_data)) ++ if (offset < 0 || offset > max_bit || ++ !ext2_test_bit(offset, bh->b_data)) + /* bad block bitmap */ + goto err_out; + + /* check whether the inode table block number is set */ + bitmap_blk = le32_to_cpu(desc->bg_inode_table); + offset = bitmap_blk - group_first_block; ++ if (offset < 0 || offset > max_bit || ++ offset + EXT2_SB(sb)->s_itb_per_group - 1 > max_bit) ++ goto err_out; + next_zero_bit = ext2_find_next_zero_bit(bh->b_data, + offset + EXT2_SB(sb)->s_itb_per_group, + offset); +diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c +index f4b50652f0cce..d9d5cfb9c951a 100644 +--- a/fs/ext4/extents_status.c ++++ b/fs/ext4/extents_status.c +@@ -310,6 +310,8 @@ void ext4_es_find_extent_range(struct inode *inode, + ext4_lblk_t lblk, ext4_lblk_t end, + struct extent_status *es) + { ++ es->es_lblk = es->es_len = es->es_pblk = 0; ++ + if (EXT4_SB(inode->i_sb)->s_mount_state & EXT4_FC_REPLAY) + return; + +diff --git a/fs/ext4/fast_commit.c b/fs/ext4/fast_commit.c +index b06de728b3b6c..5d473e50598f9 100644 +--- a/fs/ext4/fast_commit.c ++++ b/fs/ext4/fast_commit.c +@@ -649,6 +649,12 @@ void ext4_fc_track_range(handle_t *handle, struct inode *inode, ext4_lblk_t star + if (ext4_test_mount_flag(inode->i_sb, EXT4_MF_FC_INELIGIBLE)) + return; + ++ if (ext4_has_inline_data(inode)) { ++ ext4_fc_mark_ineligible(inode->i_sb, EXT4_FC_REASON_XATTR, ++ handle); ++ return; ++ } ++ + args.start = start; + args.end = end; + +diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c +index a2ee882e5ebb0..3bd2301cb48e7 100644 +--- a/fs/ext4/namei.c ++++ b/fs/ext4/namei.c +@@ -151,10 +151,11 @@ static struct buffer_head *__ext4_read_dirblock(struct inode *inode, + + return bh; + } +- if (!bh && (type == INDEX || type == DIRENT_HTREE)) { ++ /* The first directory block must not be a hole. */ ++ if (!bh && (type == INDEX || type == DIRENT_HTREE || block == 0)) { + ext4_error_inode(inode, func, line, block, +- "Directory hole found for htree %s block", +- (type == INDEX) ? "index" : "leaf"); ++ "Directory hole found for htree %s block %u", ++ (type == INDEX) ? "index" : "leaf", block); + return ERR_PTR(-EFSCORRUPTED); + } + if (!bh) +@@ -2218,6 +2219,52 @@ static int add_dirent_to_buf(handle_t *handle, struct ext4_filename *fname, + return err ? err : err2; + } + ++static bool ext4_check_dx_root(struct inode *dir, struct dx_root *root) ++{ ++ struct fake_dirent *fde; ++ const char *error_msg; ++ unsigned int rlen; ++ unsigned int blocksize = dir->i_sb->s_blocksize; ++ char *blockend = (char *)root + dir->i_sb->s_blocksize; ++ ++ fde = &root->dot; ++ if (unlikely(fde->name_len != 1)) { ++ error_msg = "invalid name_len for '.'"; ++ goto corrupted; ++ } ++ if (unlikely(strncmp(root->dot_name, ".", fde->name_len))) { ++ error_msg = "invalid name for '.'"; ++ goto corrupted; ++ } ++ rlen = ext4_rec_len_from_disk(fde->rec_len, blocksize); ++ if (unlikely((char *)fde + rlen >= blockend)) { ++ error_msg = "invalid rec_len for '.'"; ++ goto corrupted; ++ } ++ ++ fde = &root->dotdot; ++ if (unlikely(fde->name_len != 2)) { ++ error_msg = "invalid name_len for '..'"; ++ goto corrupted; ++ } ++ if (unlikely(strncmp(root->dotdot_name, "..", fde->name_len))) { ++ error_msg = "invalid name for '..'"; ++ goto corrupted; ++ } ++ rlen = ext4_rec_len_from_disk(fde->rec_len, blocksize); ++ if (unlikely((char *)fde + rlen >= blockend)) { ++ error_msg = "invalid rec_len for '..'"; ++ goto corrupted; ++ } ++ ++ return true; ++ ++corrupted: ++ EXT4_ERROR_INODE(dir, "Corrupt dir, %s, running e2fsck is recommended", ++ error_msg); ++ return false; ++} ++ + /* + * This converts a one block unindexed directory to a 3 block indexed + * directory, and adds the dentry to the indexed directory. +@@ -2252,17 +2299,17 @@ static int make_indexed_dir(handle_t *handle, struct ext4_filename *fname, + brelse(bh); + return retval; + } ++ + root = (struct dx_root *) bh->b_data; ++ if (!ext4_check_dx_root(dir, root)) { ++ brelse(bh); ++ return -EFSCORRUPTED; ++ } + + /* The 0th block becomes the root, move the dirents out */ + fde = &root->dotdot; + de = (struct ext4_dir_entry_2 *)((char *)fde + + ext4_rec_len_from_disk(fde->rec_len, blocksize)); +- if ((char *) de >= (((char *) root) + blocksize)) { +- EXT4_ERROR_INODE(dir, "invalid rec_len for '..'"); +- brelse(bh); +- return -EFSCORRUPTED; +- } + len = ((char *) root) + (blocksize - csum_size) - (char *) de; + + /* Allocate new block for the 0th block's dirents */ +@@ -3087,10 +3134,7 @@ bool ext4_empty_dir(struct inode *inode) + EXT4_ERROR_INODE(inode, "invalid size"); + return false; + } +- /* The first directory block must not be a hole, +- * so treat it as DIRENT_HTREE +- */ +- bh = ext4_read_dirblock(inode, 0, DIRENT_HTREE); ++ bh = ext4_read_dirblock(inode, 0, EITHER); + if (IS_ERR(bh)) + return false; + +@@ -3535,10 +3579,7 @@ static struct buffer_head *ext4_get_first_dir_block(handle_t *handle, + struct ext4_dir_entry_2 *de; + unsigned int offset; + +- /* The first directory block must not be a hole, so +- * treat it as DIRENT_HTREE +- */ +- bh = ext4_read_dirblock(inode, 0, DIRENT_HTREE); ++ bh = ext4_read_dirblock(inode, 0, EITHER); + if (IS_ERR(bh)) { + *retval = PTR_ERR(bh); + return NULL; +diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c +index 41b4630b17d64..c58cbe9f7809c 100644 +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -1433,6 +1433,12 @@ static int ext4_xattr_inode_write(handle_t *handle, struct inode *ea_inode, + goto out; + + memcpy(bh->b_data, buf, csize); ++ /* ++ * Zero out block tail to avoid writing uninitialized memory ++ * to disk. ++ */ ++ if (csize < blocksize) ++ memset(bh->b_data + csize, 0, blocksize - csize); + set_buffer_uptodate(bh); + ext4_handle_dirty_metadata(handle, ea_inode, bh); + +diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c +index 58ce751da92bf..1a33a8c1623f2 100644 +--- a/fs/f2fs/checkpoint.c ++++ b/fs/f2fs/checkpoint.c +@@ -1170,6 +1170,11 @@ static void __prepare_cp_block(struct f2fs_sb_info *sbi) + ckpt->valid_node_count = cpu_to_le32(valid_node_count(sbi)); + ckpt->valid_inode_count = cpu_to_le32(valid_inode_count(sbi)); + ckpt->next_free_nid = cpu_to_le32(last_nid); ++ ++ /* update user_block_counts */ ++ sbi->last_valid_block_count = sbi->total_valid_block_count; ++ percpu_counter_set(&sbi->alloc_valid_block_count, 0); ++ percpu_counter_set(&sbi->rf_node_block_count, 0); + } + + static bool __need_flush_quota(struct f2fs_sb_info *sbi) +@@ -1559,11 +1564,6 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) + start_blk += NR_CURSEG_NODE_TYPE; + } + +- /* update user_block_counts */ +- sbi->last_valid_block_count = sbi->total_valid_block_count; +- percpu_counter_set(&sbi->alloc_valid_block_count, 0); +- percpu_counter_set(&sbi->rf_node_block_count, 0); +- + /* Here, we have one bio having CP pack except cp pack 2 page */ + f2fs_sync_meta_pages(sbi, META, LONG_MAX, FS_CP_META_IO); + /* Wait for all dirty meta pages to be submitted for IO */ +diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c +index 2c4cb801899e8..84fc87018180f 100644 +--- a/fs/f2fs/data.c ++++ b/fs/f2fs/data.c +@@ -2586,7 +2586,7 @@ bool f2fs_should_update_outplace(struct inode *inode, struct f2fs_io_info *fio) + return true; + if (IS_NOQUOTA(inode)) + return true; +- if (f2fs_is_atomic_file(inode)) ++ if (f2fs_used_in_atomic_write(inode)) + return true; + + /* swap file is migrating in aligned write mode */ +@@ -2672,7 +2672,7 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio) + } + + /* wait for GCed page writeback via META_MAPPING */ +- if (fio->post_read) ++ if (fio->meta_gc) + f2fs_wait_on_block_writeback(inode, fio->old_blkaddr); + + /* +@@ -2768,7 +2768,7 @@ int f2fs_write_single_data_page(struct page *page, int *submitted, + .submitted = 0, + .compr_blocks = compr_blocks, + .need_lock = compr_blocks ? LOCK_DONE : LOCK_RETRY, +- .post_read = f2fs_post_read_required(inode) ? 1 : 0, ++ .meta_gc = f2fs_meta_inode_gc_required(inode) ? 1 : 0, + .io_type = io_type, + .io_wbc = wbc, + .bio = bio, +diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h +index c7e717ab09000..19490dd832194 100644 +--- a/fs/f2fs/f2fs.h ++++ b/fs/f2fs/f2fs.h +@@ -798,6 +798,7 @@ enum { + FI_COW_FILE, /* indicate COW file */ + FI_ATOMIC_COMMITTED, /* indicate atomic commit completed except disk sync */ + FI_ATOMIC_REPLACE, /* indicate atomic replace */ ++ FI_OPENED_FILE, /* indicate file has been opened */ + FI_MAX, /* max flag, never be used */ + }; + +@@ -836,7 +837,11 @@ struct f2fs_inode_info { + struct task_struct *atomic_write_task; /* store atomic write task */ + struct extent_tree *extent_tree[NR_EXTENT_CACHES]; + /* cached extent_tree entry */ +- struct inode *cow_inode; /* copy-on-write inode for atomic write */ ++ union { ++ struct inode *cow_inode; /* copy-on-write inode for atomic write */ ++ struct inode *atomic_inode; ++ /* point to atomic_inode, available only for cow_inode */ ++ }; + + /* avoid racing between foreground op and gc */ + struct f2fs_rwsem i_gc_rwsem[2]; +@@ -1204,7 +1209,7 @@ struct f2fs_io_info { + unsigned int in_list:1; /* indicate fio is in io_list */ + unsigned int is_por:1; /* indicate IO is from recovery or not */ + unsigned int encrypted:1; /* indicate file is encrypted */ +- unsigned int post_read:1; /* require post read */ ++ unsigned int meta_gc:1; /* require meta inode GC */ + enum iostat_type io_type; /* io type */ + struct writeback_control *io_wbc; /* writeback control */ + struct bio **bio; /* bio for ipu */ +@@ -4255,6 +4260,16 @@ static inline bool f2fs_post_read_required(struct inode *inode) + f2fs_compressed_file(inode); + } + ++static inline bool f2fs_used_in_atomic_write(struct inode *inode) ++{ ++ return f2fs_is_atomic_file(inode) || f2fs_is_cow_file(inode); ++} ++ ++static inline bool f2fs_meta_inode_gc_required(struct inode *inode) ++{ ++ return f2fs_post_read_required(inode) || f2fs_used_in_atomic_write(inode); ++} ++ + /* + * compress.c + */ +diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c +index 154c55c1a0f47..523896200908a 100644 +--- a/fs/f2fs/file.c ++++ b/fs/f2fs/file.c +@@ -534,6 +534,42 @@ static int f2fs_file_mmap(struct file *file, struct vm_area_struct *vma) + return 0; + } + ++static int finish_preallocate_blocks(struct inode *inode) ++{ ++ int ret; ++ ++ inode_lock(inode); ++ if (is_inode_flag_set(inode, FI_OPENED_FILE)) { ++ inode_unlock(inode); ++ return 0; ++ } ++ ++ if (!file_should_truncate(inode)) { ++ set_inode_flag(inode, FI_OPENED_FILE); ++ inode_unlock(inode); ++ return 0; ++ } ++ ++ f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); ++ filemap_invalidate_lock(inode->i_mapping); ++ ++ truncate_setsize(inode, i_size_read(inode)); ++ ret = f2fs_truncate(inode); ++ ++ filemap_invalidate_unlock(inode->i_mapping); ++ f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); ++ ++ if (!ret) ++ set_inode_flag(inode, FI_OPENED_FILE); ++ ++ inode_unlock(inode); ++ if (ret) ++ return ret; ++ ++ file_dont_truncate(inode); ++ return 0; ++} ++ + static int f2fs_file_open(struct inode *inode, struct file *filp) + { + int err = fscrypt_file_open(inode, filp); +@@ -551,7 +587,11 @@ static int f2fs_file_open(struct inode *inode, struct file *filp) + filp->f_mode |= FMODE_NOWAIT | FMODE_BUF_RASYNC; + filp->f_mode |= FMODE_CAN_ODIRECT; + +- return dquot_file_open(inode, filp); ++ err = dquot_file_open(inode, filp); ++ if (err) ++ return err; ++ ++ return finish_preallocate_blocks(inode); + } + + void f2fs_truncate_data_blocks_range(struct dnode_of_data *dn, int count) +@@ -803,6 +843,8 @@ static bool f2fs_force_buffered_io(struct inode *inode, int rw) + return true; + if (f2fs_compressed_file(inode)) + return true; ++ if (f2fs_has_inline_data(inode)) ++ return true; + + /* disallow direct IO if any of devices has unaligned blksize */ + if (f2fs_is_multi_device(sbi) && !sbi->aligned_blksize) +@@ -2117,6 +2159,9 @@ static int f2fs_ioc_start_atomic_write(struct file *filp, bool truncate) + + set_inode_flag(fi->cow_inode, FI_COW_FILE); + clear_inode_flag(fi->cow_inode, FI_INLINE_DATA); ++ ++ /* Set the COW inode's atomic_inode to the atomic inode */ ++ F2FS_I(fi->cow_inode)->atomic_inode = inode; + } else { + /* Reuse the already created COW inode */ + ret = f2fs_do_truncate_blocks(fi->cow_inode, 0, true); +diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c +index 3f0632dd9d2e6..afb7c88ba06b2 100644 +--- a/fs/f2fs/gc.c ++++ b/fs/f2fs/gc.c +@@ -1171,7 +1171,8 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, + static int ra_data_block(struct inode *inode, pgoff_t index) + { + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); +- struct address_space *mapping = inode->i_mapping; ++ struct address_space *mapping = f2fs_is_cow_file(inode) ? ++ F2FS_I(inode)->atomic_inode->i_mapping : inode->i_mapping; + struct dnode_of_data dn; + struct page *page; + struct f2fs_io_info fio = { +@@ -1262,6 +1263,8 @@ static int ra_data_block(struct inode *inode, pgoff_t index) + static int move_data_block(struct inode *inode, block_t bidx, + int gc_type, unsigned int segno, int off) + { ++ struct address_space *mapping = f2fs_is_cow_file(inode) ? ++ F2FS_I(inode)->atomic_inode->i_mapping : inode->i_mapping; + struct f2fs_io_info fio = { + .sbi = F2FS_I_SB(inode), + .ino = inode->i_ino, +@@ -1284,7 +1287,7 @@ static int move_data_block(struct inode *inode, block_t bidx, + CURSEG_ALL_DATA_ATGC : CURSEG_COLD_DATA; + + /* do not read out */ +- page = f2fs_grab_cache_page(inode->i_mapping, bidx, false); ++ page = f2fs_grab_cache_page(mapping, bidx, false); + if (!page) + return -ENOMEM; + +@@ -1576,7 +1579,7 @@ static int gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, + start_bidx = f2fs_start_bidx_of_node(nofs, inode) + + ofs_in_node; + +- if (f2fs_post_read_required(inode)) { ++ if (f2fs_meta_inode_gc_required(inode)) { + int err = ra_data_block(inode, start_bidx); + + f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); +@@ -1627,7 +1630,7 @@ static int gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, + + start_bidx = f2fs_start_bidx_of_node(nofs, inode) + + ofs_in_node; +- if (f2fs_post_read_required(inode)) ++ if (f2fs_meta_inode_gc_required(inode)) + err = move_data_block(inode, start_bidx, + gc_type, segno, off); + else +@@ -1635,7 +1638,7 @@ static int gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, + segno, off); + + if (!err && (gc_type == FG_GC || +- f2fs_post_read_required(inode))) ++ f2fs_meta_inode_gc_required(inode))) + submitted++; + + if (locked) { +diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c +index 2fe25619ccb5f..2cbe557f971e7 100644 +--- a/fs/f2fs/inline.c ++++ b/fs/f2fs/inline.c +@@ -16,7 +16,7 @@ + + static bool support_inline_data(struct inode *inode) + { +- if (f2fs_is_atomic_file(inode)) ++ if (f2fs_used_in_atomic_write(inode)) + return false; + if (!S_ISREG(inode->i_mode) && !S_ISLNK(inode->i_mode)) + return false; +@@ -203,8 +203,10 @@ int f2fs_convert_inline_inode(struct inode *inode) + struct page *ipage, *page; + int err = 0; + +- if (!f2fs_has_inline_data(inode) || +- f2fs_hw_is_readonly(sbi) || f2fs_readonly(sbi->sb)) ++ if (f2fs_hw_is_readonly(sbi) || f2fs_readonly(sbi->sb)) ++ return -EROFS; ++ ++ if (!f2fs_has_inline_data(inode)) + return 0; + + err = f2fs_dquot_initialize(inode); +diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c +index ab2eecd986ec5..0172f4e503061 100644 +--- a/fs/f2fs/inode.c ++++ b/fs/f2fs/inode.c +@@ -29,6 +29,9 @@ void f2fs_mark_inode_dirty_sync(struct inode *inode, bool sync) + if (is_inode_flag_set(inode, FI_NEW_INODE)) + return; + ++ if (f2fs_readonly(F2FS_I_SB(inode)->sb)) ++ return; ++ + if (f2fs_inode_dirtied(inode, sync)) + return; + +@@ -610,14 +613,6 @@ struct inode *f2fs_iget(struct super_block *sb, unsigned long ino) + } + f2fs_set_inode_flags(inode); + +- if (file_should_truncate(inode) && +- !is_sbi_flag_set(sbi, SBI_POR_DOING)) { +- ret = f2fs_truncate(inode); +- if (ret) +- goto bad_inode; +- file_dont_truncate(inode); +- } +- + unlock_new_inode(inode); + trace_f2fs_iget(inode); + return inode; +@@ -813,8 +808,9 @@ void f2fs_evict_inode(struct inode *inode) + + f2fs_abort_atomic_write(inode, true); + +- if (fi->cow_inode) { ++ if (fi->cow_inode && f2fs_is_cow_file(fi->cow_inode)) { + clear_inode_flag(fi->cow_inode, FI_COW_FILE); ++ F2FS_I(fi->cow_inode)->atomic_inode = NULL; + iput(fi->cow_inode); + fi->cow_inode = NULL; + } +diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c +index b578ce3757ef8..22080606b8769 100644 +--- a/fs/f2fs/segment.c ++++ b/fs/f2fs/segment.c +@@ -3659,7 +3659,7 @@ int f2fs_inplace_write_data(struct f2fs_io_info *fio) + goto drop_bio; + } + +- if (fio->post_read) ++ if (fio->meta_gc) + f2fs_truncate_meta_inode_pages(sbi, fio->new_blkaddr, 1); + + stat_inc_inplace_blocks(fio->sbi); +@@ -3825,7 +3825,7 @@ void f2fs_wait_on_block_writeback(struct inode *inode, block_t blkaddr) + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + struct page *cpage; + +- if (!f2fs_post_read_required(inode)) ++ if (!f2fs_meta_inode_gc_required(inode)) + return; + + if (!__is_valid_data_blkaddr(blkaddr)) +@@ -3844,7 +3844,7 @@ void f2fs_wait_on_block_writeback_range(struct inode *inode, block_t blkaddr, + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + block_t i; + +- if (!f2fs_post_read_required(inode)) ++ if (!f2fs_meta_inode_gc_required(inode)) + return; + + for (i = 0; i < len; i++) +diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h +index 4595f1cc03828..952970166d5da 100644 +--- a/fs/f2fs/segment.h ++++ b/fs/f2fs/segment.h +@@ -348,7 +348,8 @@ static inline unsigned int get_ckpt_valid_blocks(struct f2fs_sb_info *sbi, + unsigned int segno, bool use_section) + { + if (use_section && __is_large_section(sbi)) { +- unsigned int start_segno = START_SEGNO(segno); ++ unsigned int secno = GET_SEC_FROM_SEG(sbi, segno); ++ unsigned int start_segno = GET_SEG_FROM_SEC(sbi, secno); + unsigned int blocks = 0; + int i; + +diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c +index 23ab31b967a13..04c7ba3ea03a2 100644 +--- a/fs/fuse/inode.c ++++ b/fs/fuse/inode.c +@@ -751,6 +751,8 @@ static int fuse_parse_param(struct fs_context *fsc, struct fs_parameter *param) + struct fs_parse_result result; + struct fuse_fs_context *ctx = fsc->fs_private; + int opt; ++ kuid_t kuid; ++ kgid_t kgid; + + if (fsc->purpose == FS_CONTEXT_FOR_RECONFIGURE) { + /* +@@ -795,16 +797,30 @@ static int fuse_parse_param(struct fs_context *fsc, struct fs_parameter *param) + break; + + case OPT_USER_ID: +- ctx->user_id = make_kuid(fsc->user_ns, result.uint_32); +- if (!uid_valid(ctx->user_id)) ++ kuid = make_kuid(fsc->user_ns, result.uint_32); ++ if (!uid_valid(kuid)) + return invalfc(fsc, "Invalid user_id"); ++ /* ++ * The requested uid must be representable in the ++ * filesystem's idmapping. ++ */ ++ if (!kuid_has_mapping(fsc->user_ns, kuid)) ++ return invalfc(fsc, "Invalid user_id"); ++ ctx->user_id = kuid; + ctx->user_id_present = true; + break; + + case OPT_GROUP_ID: +- ctx->group_id = make_kgid(fsc->user_ns, result.uint_32); +- if (!gid_valid(ctx->group_id)) ++ kgid = make_kgid(fsc->user_ns, result.uint_32);; ++ if (!gid_valid(kgid)) ++ return invalfc(fsc, "Invalid group_id"); ++ /* ++ * The requested gid must be representable in the ++ * filesystem's idmapping. ++ */ ++ if (!kgid_has_mapping(fsc->user_ns, kgid)) + return invalfc(fsc, "Invalid group_id"); ++ ctx->group_id = kgid; + ctx->group_id_present = true; + break; + +diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c +index ee349b72cfb3c..61ed76d103927 100644 +--- a/fs/hfs/inode.c ++++ b/fs/hfs/inode.c +@@ -204,6 +204,7 @@ struct inode *hfs_new_inode(struct inode *dir, const struct qstr *name, umode_t + HFS_I(inode)->flags = 0; + HFS_I(inode)->rsrc_inode = NULL; + HFS_I(inode)->fs_blocks = 0; ++ HFS_I(inode)->tz_secondswest = sys_tz.tz_minuteswest * 60; + if (S_ISDIR(mode)) { + inode->i_size = 2; + HFS_SB(sb)->folder_count++; +@@ -279,6 +280,8 @@ void hfs_inode_read_fork(struct inode *inode, struct hfs_extent *ext, + for (count = 0, i = 0; i < 3; i++) + count += be16_to_cpu(ext[i].count); + HFS_I(inode)->first_blocks = count; ++ HFS_I(inode)->cached_start = 0; ++ HFS_I(inode)->cached_blocks = 0; + + inode->i_size = HFS_I(inode)->phys_size = log_size; + HFS_I(inode)->fs_blocks = (log_size + sb->s_blocksize - 1) >> sb->s_blocksize_bits; +diff --git a/fs/hfsplus/bfind.c b/fs/hfsplus/bfind.c +index ca2ba8c9f82ef..901e83d65d202 100644 +--- a/fs/hfsplus/bfind.c ++++ b/fs/hfsplus/bfind.c +@@ -25,19 +25,8 @@ int hfs_find_init(struct hfs_btree *tree, struct hfs_find_data *fd) + fd->key = ptr + tree->max_key_len + 2; + hfs_dbg(BNODE_REFS, "find_init: %d (%p)\n", + tree->cnid, __builtin_return_address(0)); +- switch (tree->cnid) { +- case HFSPLUS_CAT_CNID: +- mutex_lock_nested(&tree->tree_lock, CATALOG_BTREE_MUTEX); +- break; +- case HFSPLUS_EXT_CNID: +- mutex_lock_nested(&tree->tree_lock, EXTENTS_BTREE_MUTEX); +- break; +- case HFSPLUS_ATTR_CNID: +- mutex_lock_nested(&tree->tree_lock, ATTR_BTREE_MUTEX); +- break; +- default: +- BUG(); +- } ++ mutex_lock_nested(&tree->tree_lock, ++ hfsplus_btree_lock_class(tree)); + return 0; + } + +diff --git a/fs/hfsplus/extents.c b/fs/hfsplus/extents.c +index 3c572e44f2adf..9c51867dddc51 100644 +--- a/fs/hfsplus/extents.c ++++ b/fs/hfsplus/extents.c +@@ -430,7 +430,8 @@ int hfsplus_free_fork(struct super_block *sb, u32 cnid, + hfsplus_free_extents(sb, ext_entry, total_blocks - start, + total_blocks); + total_blocks = start; +- mutex_lock(&fd.tree->tree_lock); ++ mutex_lock_nested(&fd.tree->tree_lock, ++ hfsplus_btree_lock_class(fd.tree)); + } while (total_blocks > blocks); + hfs_find_exit(&fd); + +@@ -592,7 +593,8 @@ void hfsplus_file_truncate(struct inode *inode) + alloc_cnt, alloc_cnt - blk_cnt); + hfsplus_dump_extent(hip->first_extents); + hip->first_blocks = blk_cnt; +- mutex_lock(&fd.tree->tree_lock); ++ mutex_lock_nested(&fd.tree->tree_lock, ++ hfsplus_btree_lock_class(fd.tree)); + break; + } + res = __hfsplus_ext_cache_extent(&fd, inode, alloc_cnt); +@@ -606,7 +608,8 @@ void hfsplus_file_truncate(struct inode *inode) + hfsplus_free_extents(sb, hip->cached_extents, + alloc_cnt - start, alloc_cnt - blk_cnt); + hfsplus_dump_extent(hip->cached_extents); +- mutex_lock(&fd.tree->tree_lock); ++ mutex_lock_nested(&fd.tree->tree_lock, ++ hfsplus_btree_lock_class(fd.tree)); + if (blk_cnt > start) { + hip->extent_state |= HFSPLUS_EXT_DIRTY; + break; +diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h +index 7ededcb720c12..583c196ecd520 100644 +--- a/fs/hfsplus/hfsplus_fs.h ++++ b/fs/hfsplus/hfsplus_fs.h +@@ -552,6 +552,27 @@ static inline __be32 __hfsp_ut2mt(time64_t ut) + return cpu_to_be32(lower_32_bits(ut) + HFSPLUS_UTC_OFFSET); + } + ++static inline enum hfsplus_btree_mutex_classes ++hfsplus_btree_lock_class(struct hfs_btree *tree) ++{ ++ enum hfsplus_btree_mutex_classes class; ++ ++ switch (tree->cnid) { ++ case HFSPLUS_CAT_CNID: ++ class = CATALOG_BTREE_MUTEX; ++ break; ++ case HFSPLUS_EXT_CNID: ++ class = EXTENTS_BTREE_MUTEX; ++ break; ++ case HFSPLUS_ATTR_CNID: ++ class = ATTR_BTREE_MUTEX; ++ break; ++ default: ++ BUG(); ++ } ++ return class; ++} ++ + /* compatibility */ + #define hfsp_mt2ut(t) (struct timespec64){ .tv_sec = __hfsp_mt2ut(t) } + #define hfsp_ut2mt(t) __hfsp_ut2mt((t).tv_sec) +diff --git a/fs/hostfs/hostfs.h b/fs/hostfs/hostfs.h +index 0239e3af39455..8b39c15c408cc 100644 +--- a/fs/hostfs/hostfs.h ++++ b/fs/hostfs/hostfs.h +@@ -63,9 +63,10 @@ struct hostfs_stat { + struct hostfs_timespec atime, mtime, ctime; + unsigned int blksize; + unsigned long long blocks; +- unsigned int maj; +- unsigned int min; +- dev_t dev; ++ struct { ++ unsigned int maj; ++ unsigned int min; ++ } rdev, dev; + }; + + extern int stat_file(const char *path, struct hostfs_stat *p, int fd); +diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c +index dc5a5cea5fae4..ff201753fd181 100644 +--- a/fs/hostfs/hostfs_kern.c ++++ b/fs/hostfs/hostfs_kern.c +@@ -526,10 +526,11 @@ static int hostfs_inode_update(struct inode *ino, const struct hostfs_stat *st) + static int hostfs_inode_set(struct inode *ino, void *data) + { + struct hostfs_stat *st = data; +- dev_t rdev; ++ dev_t dev, rdev; + + /* Reencode maj and min with the kernel encoding.*/ +- rdev = MKDEV(st->maj, st->min); ++ rdev = MKDEV(st->rdev.maj, st->rdev.min); ++ dev = MKDEV(st->dev.maj, st->dev.min); + + switch (st->mode & S_IFMT) { + case S_IFLNK: +@@ -555,7 +556,7 @@ static int hostfs_inode_set(struct inode *ino, void *data) + return -EIO; + } + +- HOSTFS_I(ino)->dev = st->dev; ++ HOSTFS_I(ino)->dev = dev; + ino->i_ino = st->ino; + ino->i_mode = st->mode; + return hostfs_inode_update(ino, st); +@@ -564,8 +565,9 @@ static int hostfs_inode_set(struct inode *ino, void *data) + static int hostfs_inode_test(struct inode *inode, void *data) + { + const struct hostfs_stat *st = data; ++ dev_t dev = MKDEV(st->dev.maj, st->dev.min); + +- return inode->i_ino == st->ino && HOSTFS_I(inode)->dev == st->dev; ++ return inode->i_ino == st->ino && HOSTFS_I(inode)->dev == dev; + } + + static struct inode *hostfs_iget(struct super_block *sb, char *name) +diff --git a/fs/hostfs/hostfs_user.c b/fs/hostfs/hostfs_user.c +index 840619e39a1a6..97e9c40a94488 100644 +--- a/fs/hostfs/hostfs_user.c ++++ b/fs/hostfs/hostfs_user.c +@@ -34,9 +34,10 @@ static void stat64_to_hostfs(const struct stat64 *buf, struct hostfs_stat *p) + p->mtime.tv_nsec = 0; + p->blksize = buf->st_blksize; + p->blocks = buf->st_blocks; +- p->maj = os_major(buf->st_rdev); +- p->min = os_minor(buf->st_rdev); +- p->dev = buf->st_dev; ++ p->rdev.maj = os_major(buf->st_rdev); ++ p->rdev.min = os_minor(buf->st_rdev); ++ p->dev.maj = os_major(buf->st_dev); ++ p->dev.min = os_minor(buf->st_dev); + } + + int stat_file(const char *path, struct hostfs_stat *p, int fd) +diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c +index 5e122586e06ed..0cd7439470fc4 100644 +--- a/fs/jbd2/commit.c ++++ b/fs/jbd2/commit.c +@@ -767,7 +767,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) + if (first_block < journal->j_tail) + freed += journal->j_last - journal->j_first; + /* Update tail only if we free significant amount of space */ +- if (freed < jbd2_journal_get_max_txn_bufs(journal)) ++ if (freed < journal->j_max_transaction_buffers) + update_tail = 0; + } + J_ASSERT(commit_transaction->t_state == T_COMMIT); +diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c +index 19c69229ac6ec..0168d28427077 100644 +--- a/fs/jbd2/journal.c ++++ b/fs/jbd2/journal.c +@@ -1451,6 +1451,48 @@ static int journal_revoke_records_per_block(journal_t *journal) + return space / record_size; + } + ++static int jbd2_journal_get_max_txn_bufs(journal_t *journal) ++{ ++ return (journal->j_total_len - journal->j_fc_wbufsize) / 4; ++} ++ ++/* ++ * Base amount of descriptor blocks we reserve for each transaction. ++ */ ++static int jbd2_descriptor_blocks_per_trans(journal_t *journal) ++{ ++ int tag_space = journal->j_blocksize - sizeof(journal_header_t); ++ int tags_per_block; ++ ++ /* Subtract UUID */ ++ tag_space -= 16; ++ if (jbd2_journal_has_csum_v2or3(journal)) ++ tag_space -= sizeof(struct jbd2_journal_block_tail); ++ /* Commit code leaves a slack space of 16 bytes at the end of block */ ++ tags_per_block = (tag_space - 16) / journal_tag_bytes(journal); ++ /* ++ * Revoke descriptors are accounted separately so we need to reserve ++ * space for commit block and normal transaction descriptor blocks. ++ */ ++ return 1 + DIV_ROUND_UP(jbd2_journal_get_max_txn_bufs(journal), ++ tags_per_block); ++} ++ ++/* ++ * Initialize number of blocks each transaction reserves for its bookkeeping ++ * and maximum number of blocks a transaction can use. This needs to be called ++ * after the journal size and the fastcommit area size are initialized. ++ */ ++static void jbd2_journal_init_transaction_limits(journal_t *journal) ++{ ++ journal->j_revoke_records_per_block = ++ journal_revoke_records_per_block(journal); ++ journal->j_transaction_overhead_buffers = ++ jbd2_descriptor_blocks_per_trans(journal); ++ journal->j_max_transaction_buffers = ++ jbd2_journal_get_max_txn_bufs(journal); ++} ++ + /* + * Load the on-disk journal superblock and read the key fields into the + * journal_t. +@@ -1492,8 +1534,8 @@ static int journal_load_superblock(journal_t *journal) + if (jbd2_journal_has_csum_v2or3(journal)) + journal->j_csum_seed = jbd2_chksum(journal, ~0, sb->s_uuid, + sizeof(sb->s_uuid)); +- journal->j_revoke_records_per_block = +- journal_revoke_records_per_block(journal); ++ /* After journal features are set, we can compute transaction limits */ ++ jbd2_journal_init_transaction_limits(journal); + + if (jbd2_has_feature_fast_commit(journal)) { + journal->j_fc_last = be32_to_cpu(sb->s_maxlen); +@@ -1735,8 +1777,6 @@ static int journal_reset(journal_t *journal) + journal->j_commit_sequence = journal->j_transaction_sequence - 1; + journal->j_commit_request = journal->j_commit_sequence; + +- journal->j_max_transaction_buffers = jbd2_journal_get_max_txn_bufs(journal); +- + /* + * Now that journal recovery is done, turn fast commits off here. This + * way, if fast commit was enabled before the crash but if now FS has +@@ -2277,8 +2317,6 @@ jbd2_journal_initialize_fast_commit(journal_t *journal) + journal->j_fc_first = journal->j_last + 1; + journal->j_fc_off = 0; + journal->j_free = journal->j_last - journal->j_first; +- journal->j_max_transaction_buffers = +- jbd2_journal_get_max_txn_bufs(journal); + + return 0; + } +@@ -2366,8 +2404,7 @@ int jbd2_journal_set_features(journal_t *journal, unsigned long compat, + sb->s_feature_ro_compat |= cpu_to_be32(ro); + sb->s_feature_incompat |= cpu_to_be32(incompat); + unlock_buffer(journal->j_sb_buffer); +- journal->j_revoke_records_per_block = +- journal_revoke_records_per_block(journal); ++ jbd2_journal_init_transaction_limits(journal); + + return 1; + #undef COMPAT_FEATURE_ON +@@ -2398,8 +2435,7 @@ void jbd2_journal_clear_features(journal_t *journal, unsigned long compat, + sb->s_feature_compat &= ~cpu_to_be32(compat); + sb->s_feature_ro_compat &= ~cpu_to_be32(ro); + sb->s_feature_incompat &= ~cpu_to_be32(incompat); +- journal->j_revoke_records_per_block = +- journal_revoke_records_per_block(journal); ++ jbd2_journal_init_transaction_limits(journal); + } + EXPORT_SYMBOL(jbd2_journal_clear_features); + +diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c +index 5f08b5fd105a3..76adab83cac36 100644 +--- a/fs/jbd2/transaction.c ++++ b/fs/jbd2/transaction.c +@@ -62,28 +62,6 @@ void jbd2_journal_free_transaction(transaction_t *transaction) + kmem_cache_free(transaction_cache, transaction); + } + +-/* +- * Base amount of descriptor blocks we reserve for each transaction. +- */ +-static int jbd2_descriptor_blocks_per_trans(journal_t *journal) +-{ +- int tag_space = journal->j_blocksize - sizeof(journal_header_t); +- int tags_per_block; +- +- /* Subtract UUID */ +- tag_space -= 16; +- if (jbd2_journal_has_csum_v2or3(journal)) +- tag_space -= sizeof(struct jbd2_journal_block_tail); +- /* Commit code leaves a slack space of 16 bytes at the end of block */ +- tags_per_block = (tag_space - 16) / journal_tag_bytes(journal); +- /* +- * Revoke descriptors are accounted separately so we need to reserve +- * space for commit block and normal transaction descriptor blocks. +- */ +- return 1 + DIV_ROUND_UP(journal->j_max_transaction_buffers, +- tags_per_block); +-} +- + /* + * jbd2_get_transaction: obtain a new transaction_t object. + * +@@ -109,7 +87,7 @@ static void jbd2_get_transaction(journal_t *journal, + transaction->t_expires = jiffies + journal->j_commit_interval; + atomic_set(&transaction->t_updates, 0); + atomic_set(&transaction->t_outstanding_credits, +- jbd2_descriptor_blocks_per_trans(journal) + ++ journal->j_transaction_overhead_buffers + + atomic_read(&journal->j_reserved_credits)); + atomic_set(&transaction->t_outstanding_revokes, 0); + atomic_set(&transaction->t_handle_count, 0); +@@ -213,6 +191,13 @@ static void sub_reserved_credits(journal_t *journal, int blocks) + wake_up(&journal->j_wait_reserved); + } + ++/* Maximum number of blocks for user transaction payload */ ++static int jbd2_max_user_trans_buffers(journal_t *journal) ++{ ++ return journal->j_max_transaction_buffers - ++ journal->j_transaction_overhead_buffers; ++} ++ + /* + * Wait until we can add credits for handle to the running transaction. Called + * with j_state_lock held for reading. Returns 0 if handle joined the running +@@ -262,12 +247,12 @@ __must_hold(&journal->j_state_lock) + * big to fit this handle? Wait until reserved credits are freed. + */ + if (atomic_read(&journal->j_reserved_credits) + total > +- journal->j_max_transaction_buffers) { ++ jbd2_max_user_trans_buffers(journal)) { + read_unlock(&journal->j_state_lock); + jbd2_might_wait_for_commit(journal); + wait_event(journal->j_wait_reserved, + atomic_read(&journal->j_reserved_credits) + total <= +- journal->j_max_transaction_buffers); ++ jbd2_max_user_trans_buffers(journal)); + __acquire(&journal->j_state_lock); /* fake out sparse */ + return 1; + } +@@ -307,14 +292,14 @@ __must_hold(&journal->j_state_lock) + + needed = atomic_add_return(rsv_blocks, &journal->j_reserved_credits); + /* We allow at most half of a transaction to be reserved */ +- if (needed > journal->j_max_transaction_buffers / 2) { ++ if (needed > jbd2_max_user_trans_buffers(journal) / 2) { + sub_reserved_credits(journal, rsv_blocks); + atomic_sub(total, &t->t_outstanding_credits); + read_unlock(&journal->j_state_lock); + jbd2_might_wait_for_commit(journal); + wait_event(journal->j_wait_reserved, + atomic_read(&journal->j_reserved_credits) + rsv_blocks +- <= journal->j_max_transaction_buffers / 2); ++ <= jbd2_max_user_trans_buffers(journal) / 2); + __acquire(&journal->j_state_lock); /* fake out sparse */ + return 1; + } +@@ -344,12 +329,12 @@ static int start_this_handle(journal_t *journal, handle_t *handle, + * size and limit the number of total credits to not exceed maximum + * transaction size per operation. + */ +- if ((rsv_blocks > journal->j_max_transaction_buffers / 2) || +- (rsv_blocks + blocks > journal->j_max_transaction_buffers)) { ++ if (rsv_blocks > jbd2_max_user_trans_buffers(journal) / 2 || ++ rsv_blocks + blocks > jbd2_max_user_trans_buffers(journal)) { + printk(KERN_ERR "JBD2: %s wants too many credits " + "credits:%d rsv_credits:%d max:%d\n", + current->comm, blocks, rsv_blocks, +- journal->j_max_transaction_buffers); ++ jbd2_max_user_trans_buffers(journal)); + WARN_ON(1); + return -ENOSPC; + } +diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c +index eeedf606cf9d4..4bc589c4dcca9 100644 +--- a/fs/jfs/jfs_imap.c ++++ b/fs/jfs/jfs_imap.c +@@ -290,7 +290,7 @@ int diSync(struct inode *ipimap) + int diRead(struct inode *ip) + { + struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb); +- int iagno, ino, extno, rc; ++ int iagno, ino, extno, rc, agno; + struct inode *ipimap; + struct dinode *dp; + struct iag *iagp; +@@ -339,8 +339,11 @@ int diRead(struct inode *ip) + + /* get the ag for the iag */ + agstart = le64_to_cpu(iagp->agstart); ++ agno = BLKTOAG(agstart, JFS_SBI(ip->i_sb)); + + release_metapage(mp); ++ if (agno >= MAXAG || agno < 0) ++ return -EIO; + + rel_inode = (ino & (INOSPERPAGE - 1)); + pageno = blkno >> sbi->l2nbperpage; +diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c +index 2405aeb39b9a2..b068ed32d7b32 100644 +--- a/fs/kernfs/dir.c ++++ b/fs/kernfs/dir.c +@@ -127,7 +127,7 @@ static struct kernfs_node *kernfs_common_ancestor(struct kernfs_node *a, + * + * [3] when @kn_to is %NULL result will be "(null)" + * +- * Return: the length of the full path. If the full length is equal to or ++ * Return: the length of the constructed path. If the path would have been + * greater than @buflen, @buf contains the truncated path with the trailing + * '\0'. On error, -errno is returned. + */ +@@ -138,16 +138,17 @@ static int kernfs_path_from_node_locked(struct kernfs_node *kn_to, + struct kernfs_node *kn, *common; + const char parent_str[] = "/.."; + size_t depth_from, depth_to, len = 0; ++ ssize_t copied; + int i, j; + + if (!kn_to) +- return strlcpy(buf, "(null)", buflen); ++ return strscpy(buf, "(null)", buflen); + + if (!kn_from) + kn_from = kernfs_root(kn_to)->kn; + + if (kn_from == kn_to) +- return strlcpy(buf, "/", buflen); ++ return strscpy(buf, "/", buflen); + + common = kernfs_common_ancestor(kn_from, kn_to); + if (WARN_ON(!common)) +@@ -158,18 +159,19 @@ static int kernfs_path_from_node_locked(struct kernfs_node *kn_to, + + buf[0] = '\0'; + +- for (i = 0; i < depth_from; i++) +- len += strlcpy(buf + len, parent_str, +- len < buflen ? buflen - len : 0); ++ for (i = 0; i < depth_from; i++) { ++ copied = strscpy(buf + len, parent_str, buflen - len); ++ if (copied < 0) ++ return copied; ++ len += copied; ++ } + + /* Calculate how many bytes we need for the rest */ + for (i = depth_to - 1; i >= 0; i--) { + for (kn = kn_to, j = 0; j < i; j++) + kn = kn->parent; +- len += strlcpy(buf + len, "/", +- len < buflen ? buflen - len : 0); +- len += strlcpy(buf + len, kn->name, +- len < buflen ? buflen - len : 0); ++ ++ len += scnprintf(buf + len, buflen - len, "/%s", kn->name); + } + + return len; +@@ -214,7 +216,7 @@ int kernfs_name(struct kernfs_node *kn, char *buf, size_t buflen) + * path (which includes '..'s) as needed to reach from @from to @to is + * returned. + * +- * Return: the length of the full path. If the full length is equal to or ++ * Return: the length of the constructed path. If the path would have been + * greater than @buflen, @buf contains the truncated path with the trailing + * '\0'. On error, -errno is returned. + */ +@@ -265,12 +267,10 @@ void pr_cont_kernfs_path(struct kernfs_node *kn) + sz = kernfs_path_from_node(kn, NULL, kernfs_pr_cont_buf, + sizeof(kernfs_pr_cont_buf)); + if (sz < 0) { +- pr_cont("(error)"); +- goto out; +- } +- +- if (sz >= sizeof(kernfs_pr_cont_buf)) { +- pr_cont("(name too long)"); ++ if (sz == -E2BIG) ++ pr_cont("(name too long)"); ++ else ++ pr_cont("(error)"); + goto out; + } + +diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c +index 11e3a285594c2..ac80f87cb9d99 100644 +--- a/fs/nfs/nfs4client.c ++++ b/fs/nfs/nfs4client.c +@@ -231,9 +231,8 @@ struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *cl_init) + __set_bit(NFS_CS_INFINITE_SLOTS, &clp->cl_flags); + __set_bit(NFS_CS_DISCRTRY, &clp->cl_flags); + __set_bit(NFS_CS_NO_RETRANS_TIMEOUT, &clp->cl_flags); +- +- if (test_bit(NFS_CS_DS, &cl_init->init_flags)) +- __set_bit(NFS_CS_DS, &clp->cl_flags); ++ if (test_bit(NFS_CS_PNFS, &cl_init->init_flags)) ++ __set_bit(NFS_CS_PNFS, &clp->cl_flags); + /* + * Set up the connection to the server before we add add to the + * global list. +@@ -1011,7 +1010,6 @@ struct nfs_client *nfs4_set_ds_client(struct nfs_server *mds_srv, + if (mds_srv->flags & NFS_MOUNT_NORESVPORT) + __set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags); + +- __set_bit(NFS_CS_DS, &cl_init.init_flags); + __set_bit(NFS_CS_PNFS, &cl_init.init_flags); + cl_init.max_connect = NFS_MAX_TRANSPORTS; + /* +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index 05490d4784f1a..e7ac249df1ad6 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -8816,7 +8816,7 @@ nfs4_run_exchange_id(struct nfs_client *clp, const struct cred *cred, + #ifdef CONFIG_NFS_V4_1_MIGRATION + calldata->args.flags |= EXCHGID4_FLAG_SUPP_MOVED_MIGR; + #endif +- if (test_bit(NFS_CS_DS, &clp->cl_flags)) ++ if (test_bit(NFS_CS_PNFS, &clp->cl_flags)) + calldata->args.flags |= EXCHGID4_FLAG_USE_PNFS_DS; + msg.rpc_argp = &calldata->args; + msg.rpc_resp = &calldata->res; +diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c +index 4199ede0583c7..451026f9986b6 100644 +--- a/fs/nfsd/nfs4proc.c ++++ b/fs/nfsd/nfs4proc.c +@@ -2218,7 +2218,7 @@ nfsd4_layoutget(struct svc_rqst *rqstp, + const struct nfsd4_layout_ops *ops; + struct nfs4_layout_stateid *ls; + __be32 nfserr; +- int accmode = NFSD_MAY_READ_IF_EXEC; ++ int accmode = NFSD_MAY_READ_IF_EXEC | NFSD_MAY_OWNER_OVERRIDE; + + switch (lgp->lg_seg.iomode) { + case IOMODE_READ: +@@ -2308,7 +2308,8 @@ nfsd4_layoutcommit(struct svc_rqst *rqstp, + struct nfs4_layout_stateid *ls; + __be32 nfserr; + +- nfserr = fh_verify(rqstp, current_fh, 0, NFSD_MAY_WRITE); ++ nfserr = fh_verify(rqstp, current_fh, 0, ++ NFSD_MAY_WRITE | NFSD_MAY_OWNER_OVERRIDE); + if (nfserr) + goto out; + +diff --git a/fs/nilfs2/btnode.c b/fs/nilfs2/btnode.c +index 5710833ac1cc7..8fe348bceabe0 100644 +--- a/fs/nilfs2/btnode.c ++++ b/fs/nilfs2/btnode.c +@@ -51,12 +51,21 @@ nilfs_btnode_create_block(struct address_space *btnc, __u64 blocknr) + + bh = nilfs_grab_buffer(inode, btnc, blocknr, BIT(BH_NILFS_Node)); + if (unlikely(!bh)) +- return NULL; ++ return ERR_PTR(-ENOMEM); + + if (unlikely(buffer_mapped(bh) || buffer_uptodate(bh) || + buffer_dirty(bh))) { +- brelse(bh); +- BUG(); ++ /* ++ * The block buffer at the specified new address was already ++ * in use. This can happen if it is a virtual block number ++ * and has been reallocated due to corruption of the bitmap ++ * used to manage its allocation state (if not, the buffer ++ * clearing of an abandoned b-tree node is missing somewhere). ++ */ ++ nilfs_error(inode->i_sb, ++ "state inconsistency probably due to duplicate use of b-tree node block address %llu (ino=%lu)", ++ (unsigned long long)blocknr, inode->i_ino); ++ goto failed; + } + memset(bh->b_data, 0, i_blocksize(inode)); + bh->b_bdev = inode->i_sb->s_bdev; +@@ -67,6 +76,12 @@ nilfs_btnode_create_block(struct address_space *btnc, __u64 blocknr) + unlock_page(bh->b_page); + put_page(bh->b_page); + return bh; ++ ++failed: ++ unlock_page(bh->b_page); ++ put_page(bh->b_page); ++ brelse(bh); ++ return ERR_PTR(-EIO); + } + + int nilfs_btnode_submit_block(struct address_space *btnc, __u64 blocknr, +@@ -217,8 +232,8 @@ int nilfs_btnode_prepare_change_key(struct address_space *btnc, + } + + nbh = nilfs_btnode_create_block(btnc, newkey); +- if (!nbh) +- return -ENOMEM; ++ if (IS_ERR(nbh)) ++ return PTR_ERR(nbh); + + BUG_ON(nbh == obh); + ctxt->newbh = nbh; +diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c +index 65659fa0372e6..598f058670595 100644 +--- a/fs/nilfs2/btree.c ++++ b/fs/nilfs2/btree.c +@@ -63,8 +63,8 @@ static int nilfs_btree_get_new_block(const struct nilfs_bmap *btree, + struct buffer_head *bh; + + bh = nilfs_btnode_create_block(btnc, ptr); +- if (!bh) +- return -ENOMEM; ++ if (IS_ERR(bh)) ++ return PTR_ERR(bh); + + set_buffer_nilfs_volatile(bh); + *bhp = bh; +diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c +index 5783efafbabda..e10f8a777ab06 100644 +--- a/fs/nilfs2/segment.c ++++ b/fs/nilfs2/segment.c +@@ -136,7 +136,7 @@ static void nilfs_dispose_list(struct the_nilfs *, struct list_head *, int); + + #define nilfs_cnt32_ge(a, b) \ + (typecheck(__u32, a) && typecheck(__u32, b) && \ +- ((__s32)(a) - (__s32)(b) >= 0)) ++ ((__s32)((a) - (b)) >= 0)) + + static int nilfs_prepare_segment_lock(struct super_block *sb, + struct nilfs_transaction_info *ti) +diff --git a/fs/ntfs3/attrib.c b/fs/ntfs3/attrib.c +index 7aadf50109994..fc6cea60044ed 100644 +--- a/fs/ntfs3/attrib.c ++++ b/fs/ntfs3/attrib.c +@@ -231,7 +231,7 @@ int attr_make_nonresident(struct ntfs_inode *ni, struct ATTRIB *attr, + struct ntfs_sb_info *sbi; + struct ATTRIB *attr_s; + struct MFT_REC *rec; +- u32 used, asize, rsize, aoff, align; ++ u32 used, asize, rsize, aoff; + bool is_data; + CLST len, alen; + char *next; +@@ -252,10 +252,13 @@ int attr_make_nonresident(struct ntfs_inode *ni, struct ATTRIB *attr, + rsize = le32_to_cpu(attr->res.data_size); + is_data = attr->type == ATTR_DATA && !attr->name_len; + +- align = sbi->cluster_size; +- if (is_attr_compressed(attr)) +- align <<= COMPRESSION_UNIT; +- len = (rsize + align - 1) >> sbi->cluster_bits; ++ /* len - how many clusters required to store 'rsize' bytes */ ++ if (is_attr_compressed(attr)) { ++ u8 shift = sbi->cluster_bits + NTFS_LZNT_CUNIT; ++ len = ((rsize + (1u << shift) - 1) >> shift) << NTFS_LZNT_CUNIT; ++ } else { ++ len = bytes_to_cluster(sbi, rsize); ++ } + + run_init(run); + +@@ -670,7 +673,8 @@ int attr_set_size(struct ntfs_inode *ni, enum ATTR_TYPE type, + goto undo_2; + } + +- if (!is_mft) ++ /* keep runs for $MFT::$ATTR_DATA and $MFT::$ATTR_BITMAP. */ ++ if (ni->mi.rno != MFT_REC_MFT) + run_truncate_head(run, evcn + 1); + + svcn = le64_to_cpu(attr->nres.svcn); +@@ -972,6 +976,19 @@ int attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn, + if (err) + goto out; + ++ /* Check for compressed frame. */ ++ err = attr_is_frame_compressed(ni, attr, vcn >> NTFS_LZNT_CUNIT, &hint); ++ if (err) ++ goto out; ++ ++ if (hint) { ++ /* if frame is compressed - don't touch it. */ ++ *lcn = COMPRESSED_LCN; ++ *len = hint; ++ err = -EOPNOTSUPP; ++ goto out; ++ } ++ + if (!*len) { + if (run_lookup_entry(run, vcn, lcn, len, NULL)) { + if (*lcn != SPARSE_LCN || !new) +@@ -1722,6 +1739,7 @@ int attr_allocate_frame(struct ntfs_inode *ni, CLST frame, size_t compr_size, + + attr_b->nres.total_size = cpu_to_le64(total_size); + inode_set_bytes(&ni->vfs_inode, total_size); ++ ni->ni_flags |= NI_FLAG_UPDATE_PARENT; + + mi_b->dirty = true; + mark_inode_dirty(&ni->vfs_inode); +diff --git a/fs/ntfs3/bitmap.c b/fs/ntfs3/bitmap.c +index 845f9b22deef0..931a7744d1865 100644 +--- a/fs/ntfs3/bitmap.c ++++ b/fs/ntfs3/bitmap.c +@@ -1382,7 +1382,7 @@ int wnd_extend(struct wnd_bitmap *wnd, size_t new_bits) + + err = ntfs_vbo_to_lbo(sbi, &wnd->run, vbo, &lbo, &bytes); + if (err) +- break; ++ return err; + + bh = ntfs_bread(sb, lbo >> sb->s_blocksize_bits); + if (!bh) +diff --git a/fs/ntfs3/dir.c b/fs/ntfs3/dir.c +index ac8eb8657f1a9..9d0a09f00b384 100644 +--- a/fs/ntfs3/dir.c ++++ b/fs/ntfs3/dir.c +@@ -326,7 +326,8 @@ static inline int ntfs_filldir(struct ntfs_sb_info *sbi, struct ntfs_inode *ni, + * It does additional locks/reads just to get the type of name. + * Should we use additional mount option to enable branch below? + */ +- if ((fname->dup.fa & FILE_ATTRIBUTE_REPARSE_POINT) && ++ if (((fname->dup.fa & FILE_ATTRIBUTE_REPARSE_POINT) || ++ fname->dup.ea_size) && + ino != ni->mi.rno) { + struct inode *inode = ntfs_iget5(sbi->sb, &e->ref, NULL); + if (!IS_ERR_OR_NULL(inode)) { +diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c +index dfd5402a42e44..cd69cbd0aaae7 100644 +--- a/fs/ntfs3/file.c ++++ b/fs/ntfs3/file.c +@@ -299,10 +299,7 @@ static int ntfs_file_mmap(struct file *file, struct vm_area_struct *vma) + } + + if (ni->i_valid < to) { +- if (!inode_trylock(inode)) { +- err = -EAGAIN; +- goto out; +- } ++ inode_lock(inode); + err = ntfs_extend_initialized_size(file, ni, + ni->i_valid, to); + inode_unlock(inode); +diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c +index 22fe7f58ad638..424865dfca74b 100644 +--- a/fs/ntfs3/frecord.c ++++ b/fs/ntfs3/frecord.c +@@ -1501,7 +1501,7 @@ int ni_insert_nonresident(struct ntfs_inode *ni, enum ATTR_TYPE type, + + if (is_ext) { + if (flags & ATTR_FLAG_COMPRESSED) +- attr->nres.c_unit = COMPRESSION_UNIT; ++ attr->nres.c_unit = NTFS_LZNT_CUNIT; + attr->nres.total_size = attr->nres.alloc_size; + } + +diff --git a/fs/ntfs3/fslog.c b/fs/ntfs3/fslog.c +index c14ab9d5cfc70..231b012fb19d3 100644 +--- a/fs/ntfs3/fslog.c ++++ b/fs/ntfs3/fslog.c +@@ -2996,7 +2996,7 @@ static struct ATTRIB *attr_create_nonres_log(struct ntfs_sb_info *sbi, + if (is_ext) { + attr->name_off = SIZEOF_NONRESIDENT_EX_LE; + if (is_attr_compressed(attr)) +- attr->nres.c_unit = COMPRESSION_UNIT; ++ attr->nres.c_unit = NTFS_LZNT_CUNIT; + + attr->nres.run_off = + cpu_to_le16(SIZEOF_NONRESIDENT_EX + name_size); +@@ -3922,6 +3922,9 @@ int log_replay(struct ntfs_inode *ni, bool *initialized) + goto out; + } + ++ log->page_mask = log->page_size - 1; ++ log->page_bits = blksize_bits(log->page_size); ++ + /* If the file size has shrunk then we won't mount it. */ + if (log->l_size < le64_to_cpu(ra2->l_size)) { + err = -EINVAL; +diff --git a/fs/ntfs3/index.c b/fs/ntfs3/index.c +index 14284f0ed46aa..0d8a96136b084 100644 +--- a/fs/ntfs3/index.c ++++ b/fs/ntfs3/index.c +@@ -978,7 +978,7 @@ static struct indx_node *indx_new(struct ntfs_index *indx, + hdr->used = + cpu_to_le32(eo + sizeof(struct NTFS_DE) + sizeof(u64)); + de_set_vbn_le(e, *sub_vbn); +- hdr->flags = 1; ++ hdr->flags = NTFS_INDEX_HDR_HAS_SUBNODES; + } else { + e->size = cpu_to_le16(sizeof(struct NTFS_DE)); + hdr->used = cpu_to_le32(eo + sizeof(struct NTFS_DE)); +@@ -1682,7 +1682,7 @@ static int indx_insert_into_root(struct ntfs_index *indx, struct ntfs_inode *ni, + e->size = cpu_to_le16(sizeof(struct NTFS_DE) + sizeof(u64)); + e->flags = NTFS_IE_HAS_SUBNODES | NTFS_IE_LAST; + +- hdr->flags = 1; ++ hdr->flags = NTFS_INDEX_HDR_HAS_SUBNODES; + hdr->used = hdr->total = + cpu_to_le32(new_root_size - offsetof(struct INDEX_ROOT, ihdr)); + +diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c +index 6af705ccba65a..1545262995da2 100644 +--- a/fs/ntfs3/inode.c ++++ b/fs/ntfs3/inode.c +@@ -1498,7 +1498,7 @@ struct inode *ntfs_create_inode(struct mnt_idmap *idmap, struct inode *dir, + attr->size = cpu_to_le32(SIZEOF_NONRESIDENT_EX + 8); + attr->name_off = SIZEOF_NONRESIDENT_EX_LE; + attr->flags = ATTR_FLAG_COMPRESSED; +- attr->nres.c_unit = COMPRESSION_UNIT; ++ attr->nres.c_unit = NTFS_LZNT_CUNIT; + asize = SIZEOF_NONRESIDENT_EX + 8; + } else { + attr->size = cpu_to_le32(SIZEOF_NONRESIDENT + 8); +@@ -1652,7 +1652,9 @@ struct inode *ntfs_create_inode(struct mnt_idmap *idmap, struct inode *dir, + * The packed size of extended attribute is stored in direntry too. + * 'fname' here points to inside new_de. + */ +- ntfs_save_wsl_perm(inode, &fname->dup.ea_size); ++ err = ntfs_save_wsl_perm(inode, &fname->dup.ea_size); ++ if (err) ++ goto out6; + + /* + * update ea_size in file_name attribute too. +@@ -1694,6 +1696,12 @@ struct inode *ntfs_create_inode(struct mnt_idmap *idmap, struct inode *dir, + goto out2; + + out6: ++ attr = ni_find_attr(ni, NULL, NULL, ATTR_EA, NULL, 0, NULL, NULL); ++ if (attr && attr->non_res) { ++ /* Delete ATTR_EA, if non-resident. */ ++ attr_set_size(ni, ATTR_EA, NULL, 0, NULL, 0, NULL, false, NULL); ++ } ++ + if (rp_inserted) + ntfs_remove_reparse(sbi, IO_REPARSE_TAG_SYMLINK, &new_de->ref); + +@@ -2117,5 +2125,6 @@ const struct address_space_operations ntfs_aops = { + const struct address_space_operations ntfs_aops_cmpr = { + .read_folio = ntfs_read_folio, + .readahead = ntfs_readahead, ++ .dirty_folio = block_dirty_folio, + }; + // clang-format on +diff --git a/fs/ntfs3/ntfs.h b/fs/ntfs3/ntfs.h +index b70288cc5f6fa..964e27c7b9016 100644 +--- a/fs/ntfs3/ntfs.h ++++ b/fs/ntfs3/ntfs.h +@@ -82,9 +82,6 @@ typedef u32 CLST; + #define RESIDENT_LCN ((CLST)-2) + #define COMPRESSED_LCN ((CLST)-3) + +-#define COMPRESSION_UNIT 4 +-#define COMPRESS_MAX_CLUSTER 0x1000 +- + enum RECORD_NUM { + MFT_REC_MFT = 0, + MFT_REC_MIRR = 1, +@@ -696,14 +693,15 @@ static inline bool de_has_vcn_ex(const struct NTFS_DE *e) + offsetof(struct ATTR_FILE_NAME, name) + \ + NTFS_NAME_LEN * sizeof(short), 8) + ++#define NTFS_INDEX_HDR_HAS_SUBNODES cpu_to_le32(1) ++ + struct INDEX_HDR { + __le32 de_off; // 0x00: The offset from the start of this structure + // to the first NTFS_DE. + __le32 used; // 0x04: The size of this structure plus all + // entries (quad-word aligned). + __le32 total; // 0x08: The allocated size of for this structure plus all entries. +- u8 flags; // 0x0C: 0x00 = Small directory, 0x01 = Large directory. +- u8 res[3]; ++ __le32 flags; // 0x0C: 0x00 = Small directory, 0x01 = Large directory. + + // + // de_off + used <= total +@@ -751,7 +749,7 @@ static inline struct NTFS_DE *hdr_next_de(const struct INDEX_HDR *hdr, + + static inline bool hdr_has_subnode(const struct INDEX_HDR *hdr) + { +- return hdr->flags & 1; ++ return hdr->flags & NTFS_INDEX_HDR_HAS_SUBNODES; + } + + struct INDEX_BUFFER { +@@ -771,7 +769,7 @@ static inline bool ib_is_empty(const struct INDEX_BUFFER *ib) + + static inline bool ib_is_leaf(const struct INDEX_BUFFER *ib) + { +- return !(ib->ihdr.flags & 1); ++ return !(ib->ihdr.flags & NTFS_INDEX_HDR_HAS_SUBNODES); + } + + /* Index root structure ( 0x90 ). */ +diff --git a/fs/ntfs3/super.c b/fs/ntfs3/super.c +index 10659817f98c7..d47cfa215a367 100644 +--- a/fs/ntfs3/super.c ++++ b/fs/ntfs3/super.c +@@ -276,7 +276,7 @@ static const struct fs_parameter_spec ntfs_fs_parameters[] = { + fsparam_flag_no("acl", Opt_acl), + fsparam_string("iocharset", Opt_iocharset), + fsparam_flag_no("prealloc", Opt_prealloc), +- fsparam_flag_no("nocase", Opt_nocase), ++ fsparam_flag_no("case", Opt_nocase), + {} + }; + // clang-format on +@@ -463,7 +463,7 @@ static int ntfs3_volinfo(struct seq_file *m, void *o) + struct super_block *sb = m->private; + struct ntfs_sb_info *sbi = sb->s_fs_info; + +- seq_printf(m, "ntfs%d.%d\n%u\n%zu\n\%zu\n%zu\n%s\n%s\n", ++ seq_printf(m, "ntfs%d.%d\n%u\n%zu\n%zu\n%zu\n%s\n%s\n", + sbi->volume.major_ver, sbi->volume.minor_ver, + sbi->cluster_size, sbi->used.bitmap.nbits, + sbi->mft.bitmap.nbits, +diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c +index ac605f143762f..59571737e1677 100644 +--- a/fs/proc/task_mmu.c ++++ b/fs/proc/task_mmu.c +@@ -1358,8 +1358,7 @@ static inline pagemap_entry_t make_pme(u64 frame, u64 flags) + return (pagemap_entry_t) { .pme = (frame & PM_PFRAME_MASK) | flags }; + } + +-static int add_to_pagemap(unsigned long addr, pagemap_entry_t *pme, +- struct pagemapread *pm) ++static int add_to_pagemap(pagemap_entry_t *pme, struct pagemapread *pm) + { + pm->buffer[pm->pos++] = *pme; + if (pm->pos >= pm->len) +@@ -1386,7 +1385,7 @@ static int pagemap_pte_hole(unsigned long start, unsigned long end, + hole_end = end; + + for (; addr < hole_end; addr += PAGE_SIZE) { +- err = add_to_pagemap(addr, &pme, pm); ++ err = add_to_pagemap(&pme, pm); + if (err) + goto out; + } +@@ -1398,7 +1397,7 @@ static int pagemap_pte_hole(unsigned long start, unsigned long end, + if (vma->vm_flags & VM_SOFTDIRTY) + pme = make_pme(0, PM_SOFT_DIRTY); + for (; addr < min(end, vma->vm_end); addr += PAGE_SIZE) { +- err = add_to_pagemap(addr, &pme, pm); ++ err = add_to_pagemap(&pme, pm); + if (err) + goto out; + } +@@ -1412,7 +1411,6 @@ static pagemap_entry_t pte_to_pagemap_entry(struct pagemapread *pm, + { + u64 frame = 0, flags = 0; + struct page *page = NULL; +- bool migration = false; + + if (pte_present(pte)) { + if (pm->show_pfn) +@@ -1444,7 +1442,6 @@ static pagemap_entry_t pte_to_pagemap_entry(struct pagemapread *pm, + (offset << MAX_SWAPFILES_SHIFT); + } + flags |= PM_SWAP; +- migration = is_migration_entry(entry); + if (is_pfn_swap_entry(entry)) + page = pfn_swap_entry_to_page(entry); + if (pte_marker_entry_uffd_wp(entry)) +@@ -1453,7 +1450,7 @@ static pagemap_entry_t pte_to_pagemap_entry(struct pagemapread *pm, + + if (page && !PageAnon(page)) + flags |= PM_FILE; +- if (page && !migration && page_mapcount(page) == 1) ++ if (page && (flags & PM_PRESENT) && page_mapcount(page) == 1) + flags |= PM_MMAP_EXCLUSIVE; + if (vma->vm_flags & VM_SOFTDIRTY) + flags |= PM_SOFT_DIRTY; +@@ -1470,10 +1467,10 @@ static int pagemap_pmd_range(pmd_t *pmdp, unsigned long addr, unsigned long end, + pte_t *pte, *orig_pte; + int err = 0; + #ifdef CONFIG_TRANSPARENT_HUGEPAGE +- bool migration = false; + + ptl = pmd_trans_huge_lock(pmdp, vma); + if (ptl) { ++ unsigned int idx = (addr & ~PMD_MASK) >> PAGE_SHIFT; + u64 flags = 0, frame = 0; + pmd_t pmd = *pmdp; + struct page *page = NULL; +@@ -1490,8 +1487,7 @@ static int pagemap_pmd_range(pmd_t *pmdp, unsigned long addr, unsigned long end, + if (pmd_uffd_wp(pmd)) + flags |= PM_UFFD_WP; + if (pm->show_pfn) +- frame = pmd_pfn(pmd) + +- ((addr & ~PMD_MASK) >> PAGE_SHIFT); ++ frame = pmd_pfn(pmd) + idx; + } + #ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION + else if (is_swap_pmd(pmd)) { +@@ -1500,11 +1496,9 @@ static int pagemap_pmd_range(pmd_t *pmdp, unsigned long addr, unsigned long end, + + if (pm->show_pfn) { + if (is_pfn_swap_entry(entry)) +- offset = swp_offset_pfn(entry); ++ offset = swp_offset_pfn(entry) + idx; + else +- offset = swp_offset(entry); +- offset = offset + +- ((addr & ~PMD_MASK) >> PAGE_SHIFT); ++ offset = swp_offset(entry) + idx; + frame = swp_type(entry) | + (offset << MAX_SWAPFILES_SHIFT); + } +@@ -1514,18 +1508,23 @@ static int pagemap_pmd_range(pmd_t *pmdp, unsigned long addr, unsigned long end, + if (pmd_swp_uffd_wp(pmd)) + flags |= PM_UFFD_WP; + VM_BUG_ON(!is_pmd_migration_entry(pmd)); +- migration = is_migration_entry(entry); + page = pfn_swap_entry_to_page(entry); + } + #endif + +- if (page && !migration && page_mapcount(page) == 1) +- flags |= PM_MMAP_EXCLUSIVE; ++ if (page && !PageAnon(page)) ++ flags |= PM_FILE; ++ ++ for (; addr != end; addr += PAGE_SIZE, idx++) { ++ unsigned long cur_flags = flags; ++ pagemap_entry_t pme; + +- for (; addr != end; addr += PAGE_SIZE) { +- pagemap_entry_t pme = make_pme(frame, flags); ++ if (page && (flags & PM_PRESENT) && ++ page_mapcount(page + idx) == 1) ++ cur_flags |= PM_MMAP_EXCLUSIVE; + +- err = add_to_pagemap(addr, &pme, pm); ++ pme = make_pme(frame, cur_flags); ++ err = add_to_pagemap(&pme, pm); + if (err) + break; + if (pm->show_pfn) { +@@ -1553,7 +1552,7 @@ static int pagemap_pmd_range(pmd_t *pmdp, unsigned long addr, unsigned long end, + pagemap_entry_t pme; + + pme = pte_to_pagemap_entry(pm, vma, addr, ptep_get(pte)); +- err = add_to_pagemap(addr, &pme, pm); ++ err = add_to_pagemap(&pme, pm); + if (err) + break; + } +@@ -1603,7 +1602,7 @@ static int pagemap_hugetlb_range(pte_t *ptep, unsigned long hmask, + for (; addr != end; addr += PAGE_SIZE) { + pagemap_entry_t pme = make_pme(frame, flags); + +- err = add_to_pagemap(addr, &pme, pm); ++ err = add_to_pagemap(&pme, pm); + if (err) + return err; + if (pm->show_pfn && (flags & PM_PRESENT)) +diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c +index 19183b8f26b02..87caeff427a16 100644 +--- a/fs/smb/client/cifsfs.c ++++ b/fs/smb/client/cifsfs.c +@@ -1885,12 +1885,12 @@ init_cifs(void) + WQ_FREEZABLE|WQ_MEM_RECLAIM, 0); + if (!serverclose_wq) { + rc = -ENOMEM; +- goto out_destroy_serverclose_wq; ++ goto out_destroy_deferredclose_wq; + } + + rc = cifs_init_inodecache(); + if (rc) +- goto out_destroy_deferredclose_wq; ++ goto out_destroy_serverclose_wq; + + rc = init_mids(); + if (rc) +@@ -1952,6 +1952,8 @@ init_cifs(void) + destroy_mids(); + out_destroy_inodecache: + cifs_destroy_inodecache(); ++out_destroy_serverclose_wq: ++ destroy_workqueue(serverclose_wq); + out_destroy_deferredclose_wq: + destroy_workqueue(deferredclose_wq); + out_destroy_cifsoplockd_wq: +@@ -1962,8 +1964,6 @@ init_cifs(void) + destroy_workqueue(decrypt_wq); + out_destroy_cifsiod_wq: + destroy_workqueue(cifsiod_wq); +-out_destroy_serverclose_wq: +- destroy_workqueue(serverclose_wq); + out_clean_proc: + cifs_proc_clean(); + return rc; +diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c +index 7a16e12f5da87..d2307162a2de1 100644 +--- a/fs/smb/client/connect.c ++++ b/fs/smb/client/connect.c +@@ -2614,6 +2614,13 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx) + cifs_dbg(VFS, "Server does not support mounting with posix SMB3.11 extensions\n"); + rc = -EOPNOTSUPP; + goto out_fail; ++ } else if (ses->server->vals->protocol_id == SMB10_PROT_ID) ++ if (cap_unix(ses)) ++ cifs_dbg(FYI, "Unix Extensions requested on SMB1 mount\n"); ++ else { ++ cifs_dbg(VFS, "SMB1 Unix Extensions not supported by server\n"); ++ rc = -EOPNOTSUPP; ++ goto out_fail; + } else { + cifs_dbg(VFS, + "Check vers= mount option. SMB3.11 disabled but required for POSIX extensions\n"); +@@ -3686,6 +3693,7 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx) + } + #endif + ++#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY + /* + * Issue a TREE_CONNECT request. + */ +@@ -3807,11 +3815,25 @@ CIFSTCon(const unsigned int xid, struct cifs_ses *ses, + else + tcon->Flags = 0; + cifs_dbg(FYI, "Tcon flags: 0x%x\n", tcon->Flags); +- } + ++ /* ++ * reset_cifs_unix_caps calls QFSInfo which requires ++ * need_reconnect to be false, but we would not need to call ++ * reset_caps if this were not a reconnect case so must check ++ * need_reconnect flag here. The caller will also clear ++ * need_reconnect when tcon was successful but needed to be ++ * cleared earlier in the case of unix extensions reconnect ++ */ ++ if (tcon->need_reconnect && tcon->unix_ext) { ++ cifs_dbg(FYI, "resetting caps for %s\n", tcon->tree_name); ++ tcon->need_reconnect = false; ++ reset_cifs_unix_caps(xid, tcon, NULL, NULL); ++ } ++ } + cifs_buf_release(smb_buffer); + return rc; + } ++#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ + + static void delayed_free(struct rcu_head *p) + { +diff --git a/fs/super.c b/fs/super.c +index 2d762ce67f6e6..576abb1ff0403 100644 +--- a/fs/super.c ++++ b/fs/super.c +@@ -781,6 +781,17 @@ struct super_block *sget_fc(struct fs_context *fc, + struct user_namespace *user_ns = fc->global ? &init_user_ns : fc->user_ns; + int err; + ++ /* ++ * Never allow s_user_ns != &init_user_ns when FS_USERNS_MOUNT is ++ * not set, as the filesystem is likely unprepared to handle it. ++ * This can happen when fsconfig() is called from init_user_ns with ++ * an fs_fd opened in another user namespace. ++ */ ++ if (user_ns != &init_user_ns && !(fc->fs_type->fs_flags & FS_USERNS_MOUNT)) { ++ errorfc(fc, "VFS: Mounting from non-initial user namespace is not allowed"); ++ return ERR_PTR(-EPERM); ++ } ++ + retry: + spin_lock(&sb_lock); + if (test) { +diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c +index ab3ffc355949d..558ad046972ad 100644 +--- a/fs/udf/balloc.c ++++ b/fs/udf/balloc.c +@@ -64,8 +64,12 @@ static int read_block_bitmap(struct super_block *sb, + } + + for (i = 0; i < count; i++) +- if (udf_test_bit(i + off, bh->b_data)) ++ if (udf_test_bit(i + off, bh->b_data)) { ++ bitmap->s_block_bitmap[bitmap_nr] = ++ ERR_PTR(-EFSCORRUPTED); ++ brelse(bh); + return -EFSCORRUPTED; ++ } + return 0; + } + +@@ -81,8 +85,15 @@ static int __load_block_bitmap(struct super_block *sb, + block_group, nr_groups); + } + +- if (bitmap->s_block_bitmap[block_group]) ++ if (bitmap->s_block_bitmap[block_group]) { ++ /* ++ * The bitmap failed verification in the past. No point in ++ * trying again. ++ */ ++ if (IS_ERR(bitmap->s_block_bitmap[block_group])) ++ return PTR_ERR(bitmap->s_block_bitmap[block_group]); + return block_group; ++ } + + retval = read_block_bitmap(sb, bitmap, block_group, block_group); + if (retval < 0) +diff --git a/fs/udf/file.c b/fs/udf/file.c +index 0ceac4b5937c7..94daaaf76f71c 100644 +--- a/fs/udf/file.c ++++ b/fs/udf/file.c +@@ -232,7 +232,9 @@ static int udf_setattr(struct mnt_idmap *idmap, struct dentry *dentry, + + if ((attr->ia_valid & ATTR_SIZE) && + attr->ia_size != i_size_read(inode)) { ++ filemap_invalidate_lock(inode->i_mapping); + error = udf_setsize(inode, attr->ia_size); ++ filemap_invalidate_unlock(inode->i_mapping); + if (error) + return error; + } +diff --git a/fs/udf/inode.c b/fs/udf/inode.c +index 1ff8c1f17f9e6..8db07d1f56bc9 100644 +--- a/fs/udf/inode.c ++++ b/fs/udf/inode.c +@@ -1252,7 +1252,6 @@ int udf_setsize(struct inode *inode, loff_t newsize) + if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) + return -EPERM; + +- filemap_invalidate_lock(inode->i_mapping); + iinfo = UDF_I(inode); + if (newsize > inode->i_size) { + if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { +@@ -1265,11 +1264,11 @@ int udf_setsize(struct inode *inode, loff_t newsize) + } + err = udf_expand_file_adinicb(inode); + if (err) +- goto out_unlock; ++ return err; + } + err = udf_extend_file(inode, newsize); + if (err) +- goto out_unlock; ++ return err; + set_size: + truncate_setsize(inode, newsize); + } else { +@@ -1287,14 +1286,14 @@ int udf_setsize(struct inode *inode, loff_t newsize) + err = block_truncate_page(inode->i_mapping, newsize, + udf_get_block); + if (err) +- goto out_unlock; ++ return err; + truncate_setsize(inode, newsize); + down_write(&iinfo->i_data_sem); + udf_clear_extent_cache(inode); + err = udf_truncate_extents(inode); + up_write(&iinfo->i_data_sem); + if (err) +- goto out_unlock; ++ return err; + } + update_time: + inode->i_mtime = inode_set_ctime_current(inode); +@@ -1302,8 +1301,6 @@ int udf_setsize(struct inode *inode, loff_t newsize) + udf_sync_inode(inode); + else + mark_inode_dirty(inode); +-out_unlock: +- filemap_invalidate_unlock(inode->i_mapping); + return err; + } + +diff --git a/fs/udf/namei.c b/fs/udf/namei.c +index ae55ab8859b6d..605f182da42cb 100644 +--- a/fs/udf/namei.c ++++ b/fs/udf/namei.c +@@ -874,8 +874,6 @@ static int udf_rename(struct mnt_idmap *idmap, struct inode *old_dir, + if (has_diriter) { + diriter.fi.icb.extLocation = + cpu_to_lelb(UDF_I(new_dir)->i_location); +- udf_update_tag((char *)&diriter.fi, +- udf_dir_entry_len(&diriter.fi)); + udf_fiiter_write_fi(&diriter, NULL); + udf_fiiter_release(&diriter); + +diff --git a/fs/udf/super.c b/fs/udf/super.c +index 928a04d9d9e0a..e0080fda2526b 100644 +--- a/fs/udf/super.c ++++ b/fs/udf/super.c +@@ -269,7 +269,8 @@ static void udf_sb_free_bitmap(struct udf_bitmap *bitmap) + int nr_groups = bitmap->s_nr_groups; + + for (i = 0; i < nr_groups; i++) +- brelse(bitmap->s_block_bitmap[i]); ++ if (!IS_ERR_OR_NULL(bitmap->s_block_bitmap[i])) ++ brelse(bitmap->s_block_bitmap[i]); + + kvfree(bitmap); + } +diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h +index bae0fe4d499bc..63029bc7c9dd0 100644 +--- a/include/asm-generic/vmlinux.lds.h ++++ b/include/asm-generic/vmlinux.lds.h +@@ -101,7 +101,7 @@ + #define DATA_MAIN .data .data.[0-9a-zA-Z_]* .data..L* .data..compoundliteral* .data.$__unnamed_* .data.$L* + #define SDATA_MAIN .sdata .sdata.[0-9a-zA-Z_]* + #define RODATA_MAIN .rodata .rodata.[0-9a-zA-Z_]* .rodata..L* +-#define BSS_MAIN .bss .bss.[0-9a-zA-Z_]* .bss..compoundliteral* ++#define BSS_MAIN .bss .bss.[0-9a-zA-Z_]* .bss..L* .bss..compoundliteral* + #define SBSS_MAIN .sbss .sbss.[0-9a-zA-Z_]* + #else + #define TEXT_MAIN .text +diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h +index 3011d33eccbd2..900262f4c2349 100644 +--- a/include/drm/drm_mipi_dsi.h ++++ b/include/drm/drm_mipi_dsi.h +@@ -305,17 +305,17 @@ int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi, + * @dsi: DSI peripheral device + * @seq: buffer containing the payload + */ +-#define mipi_dsi_generic_write_seq(dsi, seq...) \ +- do { \ +- static const u8 d[] = { seq }; \ +- struct device *dev = &dsi->dev; \ +- int ret; \ +- ret = mipi_dsi_generic_write(dsi, d, ARRAY_SIZE(d)); \ +- if (ret < 0) { \ +- dev_err_ratelimited(dev, "transmit data failed: %d\n", \ +- ret); \ +- return ret; \ +- } \ ++#define mipi_dsi_generic_write_seq(dsi, seq...) \ ++ do { \ ++ static const u8 d[] = { seq }; \ ++ struct device *dev = &dsi->dev; \ ++ ssize_t ret; \ ++ ret = mipi_dsi_generic_write(dsi, d, ARRAY_SIZE(d)); \ ++ if (ret < 0) { \ ++ dev_err_ratelimited(dev, "transmit data failed: %zd\n", \ ++ ret); \ ++ return ret; \ ++ } \ + } while (0) + + /** +@@ -324,18 +324,18 @@ int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi, + * @cmd: Command + * @seq: buffer containing data to be transmitted + */ +-#define mipi_dsi_dcs_write_seq(dsi, cmd, seq...) \ +- do { \ +- static const u8 d[] = { cmd, seq }; \ +- struct device *dev = &dsi->dev; \ +- int ret; \ +- ret = mipi_dsi_dcs_write_buffer(dsi, d, ARRAY_SIZE(d)); \ +- if (ret < 0) { \ +- dev_err_ratelimited( \ +- dev, "sending command %#02x failed: %d\n", \ +- cmd, ret); \ +- return ret; \ +- } \ ++#define mipi_dsi_dcs_write_seq(dsi, cmd, seq...) \ ++ do { \ ++ static const u8 d[] = { cmd, seq }; \ ++ struct device *dev = &dsi->dev; \ ++ ssize_t ret; \ ++ ret = mipi_dsi_dcs_write_buffer(dsi, d, ARRAY_SIZE(d)); \ ++ if (ret < 0) { \ ++ dev_err_ratelimited( \ ++ dev, "sending command %#02x failed: %zd\n", \ ++ cmd, ret); \ ++ return ret; \ ++ } \ + } while (0) + + /** +diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h +index 2d84d820a7ba2..b62535fd8de5f 100644 +--- a/include/linux/bpf_verifier.h ++++ b/include/linux/bpf_verifier.h +@@ -760,7 +760,7 @@ static inline u32 type_flag(u32 type) + /* only use after check_attach_btf_id() */ + static inline enum bpf_prog_type resolve_prog_type(const struct bpf_prog *prog) + { +- return prog->type == BPF_PROG_TYPE_EXT ? ++ return (prog->type == BPF_PROG_TYPE_EXT && prog->aux->dst_prog) ? + prog->aux->dst_prog->type : prog->type; + } + +diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h +index 31b2927ada73f..0c50c4fceb95d 100644 +--- a/include/linux/hugetlb.h ++++ b/include/linux/hugetlb.h +@@ -713,6 +713,7 @@ HPAGEFLAG(RawHwpUnreliable, raw_hwp_unreliable) + /* Defines one hugetlb page size */ + struct hstate { + struct mutex resize_lock; ++ struct lock_class_key resize_key; + int next_nid_to_alloc; + int next_nid_to_free; + unsigned int order; +diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h +index 0fc6c1f51262f..8553dc1d0e898 100644 +--- a/include/linux/jbd2.h ++++ b/include/linux/jbd2.h +@@ -1083,6 +1083,13 @@ struct journal_s + */ + int j_revoke_records_per_block; + ++ /** ++ * @j_transaction_overhead: ++ * ++ * Number of blocks each transaction needs for its own bookkeeping ++ */ ++ int j_transaction_overhead_buffers; ++ + /** + * @j_commit_interval: + * +@@ -1666,11 +1673,6 @@ int jbd2_wait_inode_data(journal_t *journal, struct jbd2_inode *jinode); + int jbd2_fc_wait_bufs(journal_t *journal, int num_blks); + int jbd2_fc_release_bufs(journal_t *journal); + +-static inline int jbd2_journal_get_max_txn_bufs(journal_t *journal) +-{ +- return (journal->j_total_len - journal->j_fc_wbufsize) / 4; +-} +- + /* + * is_journal_abort + * +diff --git a/include/linux/mlx5/qp.h b/include/linux/mlx5/qp.h +index f0e55bf3ec8b5..ad1ce650146cb 100644 +--- a/include/linux/mlx5/qp.h ++++ b/include/linux/mlx5/qp.h +@@ -576,9 +576,12 @@ static inline const char *mlx5_qp_state_str(int state) + + static inline int mlx5_get_qp_default_ts(struct mlx5_core_dev *dev) + { +- return !MLX5_CAP_ROCE(dev, qp_ts_format) ? +- MLX5_TIMESTAMP_FORMAT_FREE_RUNNING : +- MLX5_TIMESTAMP_FORMAT_DEFAULT; ++ u8 supported_ts_cap = mlx5_get_roce_state(dev) ? ++ MLX5_CAP_ROCE(dev, qp_ts_format) : ++ MLX5_CAP_GEN(dev, sq_ts_format); ++ ++ return supported_ts_cap ? MLX5_TIMESTAMP_FORMAT_DEFAULT : ++ MLX5_TIMESTAMP_FORMAT_FREE_RUNNING; + } + + #endif /* MLX5_QP_H */ +diff --git a/include/linux/objagg.h b/include/linux/objagg.h +index 78021777df462..6df5b887dc547 100644 +--- a/include/linux/objagg.h ++++ b/include/linux/objagg.h +@@ -8,7 +8,6 @@ struct objagg_ops { + size_t obj_size; + bool (*delta_check)(void *priv, const void *parent_obj, + const void *obj); +- int (*hints_obj_cmp)(const void *obj1, const void *obj2); + void * (*delta_create)(void *priv, void *parent_obj, void *obj); + void (*delta_destroy)(void *priv, void *delta_priv); + void * (*root_create)(void *priv, void *obj, unsigned int root_id); +diff --git a/include/linux/pci.h b/include/linux/pci.h +index 512cb40150dfe..f141300116219 100644 +--- a/include/linux/pci.h ++++ b/include/linux/pci.h +@@ -1146,6 +1146,7 @@ int pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge); + u8 pci_common_swizzle(struct pci_dev *dev, u8 *pinp); + struct pci_dev *pci_dev_get(struct pci_dev *dev); + void pci_dev_put(struct pci_dev *dev); ++DEFINE_FREE(pci_dev_put, struct pci_dev *, if (_T) pci_dev_put(_T)) + void pci_remove_bus(struct pci_bus *b); + void pci_stop_and_remove_bus_device(struct pci_dev *dev); + void pci_stop_and_remove_bus_device_locked(struct pci_dev *dev); +@@ -1851,6 +1852,7 @@ void pci_cfg_access_unlock(struct pci_dev *dev); + void pci_dev_lock(struct pci_dev *dev); + int pci_dev_trylock(struct pci_dev *dev); + void pci_dev_unlock(struct pci_dev *dev); ++DEFINE_GUARD(pci_dev, struct pci_dev *, pci_dev_lock(_T), pci_dev_unlock(_T)) + + /* + * PCI domain support. Sometimes called PCI segment (eg by ACPI), +diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h +index e846f87e2d099..95d4118ee4a91 100644 +--- a/include/linux/perf_event.h ++++ b/include/linux/perf_event.h +@@ -786,6 +786,7 @@ struct perf_event { + struct irq_work pending_irq; + struct callback_head pending_task; + unsigned int pending_work; ++ struct rcuwait pending_work_wait; + + atomic_t event_limit; + +diff --git a/include/linux/sbitmap.h b/include/linux/sbitmap.h +index d662cf136021d..c09cdcc99471e 100644 +--- a/include/linux/sbitmap.h ++++ b/include/linux/sbitmap.h +@@ -36,6 +36,11 @@ struct sbitmap_word { + * @cleared: word holding cleared bits + */ + unsigned long cleared ____cacheline_aligned_in_smp; ++ ++ /** ++ * @swap_lock: serializes simultaneous updates of ->word and ->cleared ++ */ ++ spinlock_t swap_lock; + } ____cacheline_aligned_in_smp; + + /** +diff --git a/include/linux/task_work.h b/include/linux/task_work.h +index 795ef5a684294..26b8a47f41fca 100644 +--- a/include/linux/task_work.h ++++ b/include/linux/task_work.h +@@ -30,7 +30,8 @@ int task_work_add(struct task_struct *task, struct callback_head *twork, + + struct callback_head *task_work_cancel_match(struct task_struct *task, + bool (*match)(struct callback_head *, void *data), void *data); +-struct callback_head *task_work_cancel(struct task_struct *, task_work_func_t); ++struct callback_head *task_work_cancel_func(struct task_struct *, task_work_func_t); ++bool task_work_cancel(struct task_struct *task, struct callback_head *cb); + void task_work_run(void); + + static inline void exit_task_work(struct task_struct *task) +diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h +index 4dfa9b69ca8d9..d1d7825318c32 100644 +--- a/include/linux/virtio_net.h ++++ b/include/linux/virtio_net.h +@@ -56,6 +56,7 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb, + unsigned int thlen = 0; + unsigned int p_off = 0; + unsigned int ip_proto; ++ u64 ret, remainder, gso_size; + + if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) { + switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) { +@@ -98,6 +99,16 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb, + u32 off = __virtio16_to_cpu(little_endian, hdr->csum_offset); + u32 needed = start + max_t(u32, thlen, off + sizeof(__sum16)); + ++ if (hdr->gso_size) { ++ gso_size = __virtio16_to_cpu(little_endian, hdr->gso_size); ++ ret = div64_u64_rem(skb->len, gso_size, &remainder); ++ if (!(ret && (hdr->gso_size > needed) && ++ ((remainder > needed) || (remainder == 0)))) { ++ return -EINVAL; ++ } ++ skb_shinfo(skb)->tx_flags |= SKBFL_SHARED_FRAG; ++ } ++ + if (!pskb_may_pull(skb, needed)) + return -EINVAL; + +diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h +index 15de07d365405..ca1700c2a5733 100644 +--- a/include/net/ip_fib.h ++++ b/include/net/ip_fib.h +@@ -173,6 +173,7 @@ struct fib_result { + unsigned char type; + unsigned char scope; + u32 tclassid; ++ dscp_t dscp; + struct fib_nh_common *nhc; + struct fib_info *fi; + struct fib_table *table; +diff --git a/include/net/tcp.h b/include/net/tcp.h +index 690770321a6e3..71af244104433 100644 +--- a/include/net/tcp.h ++++ b/include/net/tcp.h +@@ -624,6 +624,7 @@ void tcp_skb_collapse_tstamp(struct sk_buff *skb, + /* tcp_input.c */ + void tcp_rearm_rto(struct sock *sk); + void tcp_synack_rtt_meas(struct sock *sk, struct request_sock *req); ++void tcp_done_with_error(struct sock *sk, int err); + void tcp_reset(struct sock *sk, struct sk_buff *skb); + void tcp_fin(struct sock *sk); + void tcp_check_space(struct sock *sk); +diff --git a/include/net/xfrm.h b/include/net/xfrm.h +index a3fd2cfed5e33..b280e7c460116 100644 +--- a/include/net/xfrm.h ++++ b/include/net/xfrm.h +@@ -176,7 +176,10 @@ struct xfrm_state { + struct hlist_node gclist; + struct hlist_node bydst; + }; +- struct hlist_node bysrc; ++ union { ++ struct hlist_node dev_gclist; ++ struct hlist_node bysrc; ++ }; + struct hlist_node byspi; + struct hlist_node byseq; + +@@ -1584,7 +1587,7 @@ int xfrm_state_check_expire(struct xfrm_state *x); + static inline void xfrm_dev_state_update_curlft(struct xfrm_state *x) + { + struct xfrm_dev_offload *xdo = &x->xso; +- struct net_device *dev = xdo->dev; ++ struct net_device *dev = READ_ONCE(xdo->dev); + + if (x->xso.type != XFRM_DEV_OFFLOAD_PACKET) + return; +@@ -1943,13 +1946,16 @@ int xfrm_dev_policy_add(struct net *net, struct xfrm_policy *xp, + struct xfrm_user_offload *xuo, u8 dir, + struct netlink_ext_ack *extack); + bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x); ++void xfrm_dev_state_delete(struct xfrm_state *x); ++void xfrm_dev_state_free(struct xfrm_state *x); + + static inline void xfrm_dev_state_advance_esn(struct xfrm_state *x) + { + struct xfrm_dev_offload *xso = &x->xso; ++ struct net_device *dev = READ_ONCE(xso->dev); + +- if (xso->dev && xso->dev->xfrmdev_ops->xdo_dev_state_advance_esn) +- xso->dev->xfrmdev_ops->xdo_dev_state_advance_esn(x); ++ if (dev && dev->xfrmdev_ops->xdo_dev_state_advance_esn) ++ dev->xfrmdev_ops->xdo_dev_state_advance_esn(x); + } + + static inline bool xfrm_dst_offload_ok(struct dst_entry *dst) +@@ -1970,28 +1976,6 @@ static inline bool xfrm_dst_offload_ok(struct dst_entry *dst) + return false; + } + +-static inline void xfrm_dev_state_delete(struct xfrm_state *x) +-{ +- struct xfrm_dev_offload *xso = &x->xso; +- +- if (xso->dev) +- xso->dev->xfrmdev_ops->xdo_dev_state_delete(x); +-} +- +-static inline void xfrm_dev_state_free(struct xfrm_state *x) +-{ +- struct xfrm_dev_offload *xso = &x->xso; +- struct net_device *dev = xso->dev; +- +- if (dev && dev->xfrmdev_ops) { +- if (dev->xfrmdev_ops->xdo_dev_state_free) +- dev->xfrmdev_ops->xdo_dev_state_free(x); +- xso->dev = NULL; +- xso->type = XFRM_DEV_OFFLOAD_UNSPECIFIED; +- netdev_put(dev, &xso->dev_tracker); +- } +-} +- + static inline void xfrm_dev_policy_delete(struct xfrm_policy *x) + { + struct xfrm_dev_offload *xdo = &x->xdo; +diff --git a/include/sound/tas2781-dsp.h b/include/sound/tas2781-dsp.h +index 4ef0f5c6fe6c0..af3319dab230a 100644 +--- a/include/sound/tas2781-dsp.h ++++ b/include/sound/tas2781-dsp.h +@@ -112,10 +112,17 @@ struct tasdevice_fw { + struct device *dev; + }; + +-enum tasdevice_dsp_fw_state { +- TASDEVICE_DSP_FW_NONE = 0, ++enum tasdevice_fw_state { ++ /* Driver in startup mode, not load any firmware. */ + TASDEVICE_DSP_FW_PENDING, ++ /* DSP firmware in the system, but parsing error. */ + TASDEVICE_DSP_FW_FAIL, ++ /* ++ * Only RCA (Reconfigurable Architecture) firmware load ++ * successfully. ++ */ ++ TASDEVICE_RCA_FW_OK, ++ /* Both RCA and DSP firmware load successfully. */ + TASDEVICE_DSP_FW_ALL_OK, + }; + +diff --git a/include/trace/events/rpcgss.h b/include/trace/events/rpcgss.h +index f50fcafc69de2..78704f1209d3e 100644 +--- a/include/trace/events/rpcgss.h ++++ b/include/trace/events/rpcgss.h +@@ -54,7 +54,7 @@ TRACE_DEFINE_ENUM(GSS_S_UNSEQ_TOKEN); + TRACE_DEFINE_ENUM(GSS_S_GAP_TOKEN); + + #define show_gss_status(x) \ +- __print_flags(x, "|", \ ++ __print_symbolic(x, \ + { GSS_S_BAD_MECH, "GSS_S_BAD_MECH" }, \ + { GSS_S_BAD_NAME, "GSS_S_BAD_NAME" }, \ + { GSS_S_BAD_NAMETYPE, "GSS_S_BAD_NAMETYPE" }, \ +diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h +index 117c6a9b845b1..621e3035145eb 100644 +--- a/include/uapi/linux/netfilter/nf_tables.h ++++ b/include/uapi/linux/netfilter/nf_tables.h +@@ -1372,7 +1372,7 @@ enum nft_secmark_attributes { + #define NFTA_SECMARK_MAX (__NFTA_SECMARK_MAX - 1) + + /* Max security context length */ +-#define NFT_SECMARK_CTX_MAXLEN 256 ++#define NFT_SECMARK_CTX_MAXLEN 4096 + + /** + * enum nft_reject_types - nf_tables reject expression reject types +diff --git a/include/uapi/linux/zorro_ids.h b/include/uapi/linux/zorro_ids.h +index 6e574d7b7d79c..393f2ee9c0422 100644 +--- a/include/uapi/linux/zorro_ids.h ++++ b/include/uapi/linux/zorro_ids.h +@@ -449,6 +449,9 @@ + #define ZORRO_PROD_VMC_ISDN_BLASTER_Z2 ZORRO_ID(VMC, 0x01, 0) + #define ZORRO_PROD_VMC_HYPERCOM_4 ZORRO_ID(VMC, 0x02, 0) + ++#define ZORRO_MANUF_CSLAB 0x1400 ++#define ZORRO_PROD_CSLAB_WARP_1260 ZORRO_ID(CSLAB, 0x65, 0) ++ + #define ZORRO_MANUF_INFORMATION 0x157C + #define ZORRO_PROD_INFORMATION_ISDN_ENGINE_I ZORRO_ID(INFORMATION, 0x64, 0) + +diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h +index 7d07b256e906b..e4da397360682 100644 +--- a/include/ufs/ufshcd.h ++++ b/include/ufs/ufshcd.h +@@ -1117,6 +1117,12 @@ static inline bool is_mcq_enabled(struct ufs_hba *hba) + return hba->mcq_enabled; + } + ++static inline unsigned int ufshcd_mcq_opr_offset(struct ufs_hba *hba, ++ enum ufshcd_mcq_opr opr, int idx) ++{ ++ return hba->mcq_opr[opr].offset + hba->mcq_opr[opr].stride * idx; ++} ++ + #ifdef CONFIG_SCSI_UFS_VARIABLE_SG_ENTRY_SIZE + static inline size_t ufshcd_sg_entry_size(const struct ufs_hba *hba) + { +diff --git a/io_uring/io-wq.c b/io_uring/io-wq.c +index 8a99aabcac2c3..98c9cfb983062 100644 +--- a/io_uring/io-wq.c ++++ b/io_uring/io-wq.c +@@ -23,6 +23,7 @@ + #include "io_uring.h" + + #define WORKER_IDLE_TIMEOUT (5 * HZ) ++#define WORKER_INIT_LIMIT 3 + + enum { + IO_WORKER_F_UP = 0, /* up and active */ +@@ -59,6 +60,7 @@ struct io_worker { + + unsigned long create_state; + struct callback_head create_work; ++ int init_retries; + + union { + struct rcu_head rcu; +@@ -746,7 +748,7 @@ static bool io_wq_work_match_all(struct io_wq_work *work, void *data) + return true; + } + +-static inline bool io_should_retry_thread(long err) ++static inline bool io_should_retry_thread(struct io_worker *worker, long err) + { + /* + * Prevent perpetual task_work retry, if the task (or its group) is +@@ -754,6 +756,8 @@ static inline bool io_should_retry_thread(long err) + */ + if (fatal_signal_pending(current)) + return false; ++ if (worker->init_retries++ >= WORKER_INIT_LIMIT) ++ return false; + + switch (err) { + case -EAGAIN: +@@ -780,7 +784,7 @@ static void create_worker_cont(struct callback_head *cb) + io_init_new_worker(wq, worker, tsk); + io_worker_release(worker); + return; +- } else if (!io_should_retry_thread(PTR_ERR(tsk))) { ++ } else if (!io_should_retry_thread(worker, PTR_ERR(tsk))) { + struct io_wq_acct *acct = io_wq_get_acct(worker); + + atomic_dec(&acct->nr_running); +@@ -847,7 +851,7 @@ static bool create_io_worker(struct io_wq *wq, int index) + tsk = create_io_thread(io_wq_worker, worker, NUMA_NO_NODE); + if (!IS_ERR(tsk)) { + io_init_new_worker(wq, worker, tsk); +- } else if (!io_should_retry_thread(PTR_ERR(tsk))) { ++ } else if (!io_should_retry_thread(worker, PTR_ERR(tsk))) { + kfree(worker); + goto fail; + } else { +diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c +index a5628d29b9b1f..68504709f75cb 100644 +--- a/io_uring/io_uring.c ++++ b/io_uring/io_uring.c +@@ -3350,8 +3350,11 @@ __cold void io_uring_cancel_generic(bool cancel_all, struct io_sq_data *sqd) + bool loop = false; + + io_uring_drop_tctx_refs(current); ++ if (!tctx_inflight(tctx, !cancel_all)) ++ break; ++ + /* read completions before cancelations */ +- inflight = tctx_inflight(tctx, !cancel_all); ++ inflight = tctx_inflight(tctx, false); + if (!inflight) + break; + +diff --git a/io_uring/timeout.c b/io_uring/timeout.c +index 7fd7dbb211d64..4f1f710197d62 100644 +--- a/io_uring/timeout.c ++++ b/io_uring/timeout.c +@@ -644,7 +644,7 @@ void io_queue_linked_timeout(struct io_kiocb *req) + + static bool io_match_task(struct io_kiocb *head, struct task_struct *task, + bool cancel_all) +- __must_hold(&req->ctx->timeout_lock) ++ __must_hold(&head->ctx->timeout_lock) + { + struct io_kiocb *req; + +diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c +index a31704a6bb614..fbf9721ba21b6 100644 +--- a/kernel/bpf/btf.c ++++ b/kernel/bpf/btf.c +@@ -405,7 +405,7 @@ const char *btf_type_str(const struct btf_type *t) + struct btf_show { + u64 flags; + void *target; /* target of show operation (seq file, buffer) */ +- void (*showfn)(struct btf_show *show, const char *fmt, va_list args); ++ __printf(2, 0) void (*showfn)(struct btf_show *show, const char *fmt, va_list args); + const struct btf *btf; + /* below are used during iteration */ + struct { +@@ -7070,8 +7070,8 @@ static void btf_type_show(const struct btf *btf, u32 type_id, void *obj, + btf_type_ops(t)->show(btf, t, type_id, obj, 0, show); + } + +-static void btf_seq_show(struct btf_show *show, const char *fmt, +- va_list args) ++__printf(2, 0) static void btf_seq_show(struct btf_show *show, const char *fmt, ++ va_list args) + { + seq_vprintf((struct seq_file *)show->target, fmt, args); + } +@@ -7104,8 +7104,8 @@ struct btf_show_snprintf { + int len; /* length we would have written */ + }; + +-static void btf_snprintf_show(struct btf_show *show, const char *fmt, +- va_list args) ++__printf(2, 0) static void btf_snprintf_show(struct btf_show *show, const char *fmt, ++ va_list args) + { + struct btf_show_snprintf *ssnprintf = (struct btf_show_snprintf *)show; + int len; +diff --git a/kernel/cgroup/cgroup-v1.c b/kernel/cgroup/cgroup-v1.c +index 76db6c67e39a9..9cb00ebe9ac6d 100644 +--- a/kernel/cgroup/cgroup-v1.c ++++ b/kernel/cgroup/cgroup-v1.c +@@ -802,7 +802,7 @@ void cgroup1_release_agent(struct work_struct *work) + goto out_free; + + ret = cgroup_path_ns(cgrp, pathbuf, PATH_MAX, &init_cgroup_ns); +- if (ret < 0 || ret >= PATH_MAX) ++ if (ret < 0) + goto out_free; + + argv[0] = agentbuf; +diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c +index 518725b57200c..094f513319259 100644 +--- a/kernel/cgroup/cgroup.c ++++ b/kernel/cgroup/cgroup.c +@@ -1887,7 +1887,7 @@ int cgroup_show_path(struct seq_file *sf, struct kernfs_node *kf_node, + len = kernfs_path_from_node(kf_node, ns_cgroup->kn, buf, PATH_MAX); + spin_unlock_irq(&css_set_lock); + +- if (len >= PATH_MAX) ++ if (len == -E2BIG) + len = -ERANGE; + else if (len > 0) { + seq_escape(sf, buf, " \t\n\\"); +@@ -6277,7 +6277,7 @@ int proc_cgroup_show(struct seq_file *m, struct pid_namespace *ns, + if (cgroup_on_dfl(cgrp) || !(tsk->flags & PF_EXITING)) { + retval = cgroup_path_ns_locked(cgrp, buf, PATH_MAX, + current->nsproxy->cgroup_ns); +- if (retval >= PATH_MAX) ++ if (retval == -E2BIG) + retval = -ENAMETOOLONG; + if (retval < 0) + goto out_unlock; +diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c +index 679460ebccfbf..3646426c69e25 100644 +--- a/kernel/cgroup/cpuset.c ++++ b/kernel/cgroup/cpuset.c +@@ -21,6 +21,7 @@ + * License. See the file COPYING in the main directory of the Linux + * distribution for more details. + */ ++#include "cgroup-internal.h" + + #include <linux/cpu.h> + #include <linux/cpumask.h> +@@ -4293,11 +4294,15 @@ int proc_cpuset_show(struct seq_file *m, struct pid_namespace *ns, + if (!buf) + goto out; + +- css = task_get_css(tsk, cpuset_cgrp_id); +- retval = cgroup_path_ns(css->cgroup, buf, PATH_MAX, +- current->nsproxy->cgroup_ns); +- css_put(css); +- if (retval >= PATH_MAX) ++ rcu_read_lock(); ++ spin_lock_irq(&css_set_lock); ++ css = task_css(tsk, cpuset_cgrp_id); ++ retval = cgroup_path_ns_locked(css->cgroup, buf, PATH_MAX, ++ current->nsproxy->cgroup_ns); ++ spin_unlock_irq(&css_set_lock); ++ rcu_read_unlock(); ++ ++ if (retval == -E2BIG) + retval = -ENAMETOOLONG; + if (retval < 0) + goto out_free; +diff --git a/kernel/debug/kdb/kdb_io.c b/kernel/debug/kdb/kdb_io.c +index 2aeaf9765b248..4799f6250bb26 100644 +--- a/kernel/debug/kdb/kdb_io.c ++++ b/kernel/debug/kdb/kdb_io.c +@@ -206,7 +206,7 @@ char kdb_getchar(void) + */ + static void kdb_position_cursor(char *prompt, char *buffer, char *cp) + { +- kdb_printf("\r%s", kdb_prompt_str); ++ kdb_printf("\r%s", prompt); + if (cp > buffer) + kdb_printf("%.*s", (int)(cp - buffer), buffer); + } +@@ -371,7 +371,7 @@ static char *kdb_read(char *buffer, size_t bufsize) + if (i >= dtab_count) + kdb_printf("..."); + kdb_printf("\n"); +- kdb_printf(kdb_prompt_str); ++ kdb_printf("%s", kdb_prompt_str); + kdb_printf("%s", buffer); + if (cp != lastchar) + kdb_position_cursor(kdb_prompt_str, buffer, cp); +@@ -463,7 +463,7 @@ char *kdb_getstr(char *buffer, size_t bufsize, const char *prompt) + { + if (prompt && kdb_prompt_str != prompt) + strscpy(kdb_prompt_str, prompt, CMD_BUFLEN); +- kdb_printf(kdb_prompt_str); ++ kdb_printf("%s", kdb_prompt_str); + kdb_nextline = 1; /* Prompt and input resets line number */ + return kdb_read(buffer, bufsize); + } +diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c +index e323ca48f7f2a..f1d9f01b283d7 100644 +--- a/kernel/dma/mapping.c ++++ b/kernel/dma/mapping.c +@@ -67,8 +67,8 @@ void dmam_free_coherent(struct device *dev, size_t size, void *vaddr, + { + struct dma_devres match_data = { size, vaddr, dma_handle }; + +- dma_free_coherent(dev, size, vaddr, dma_handle); + WARN_ON(devres_destroy(dev, dmam_release, dmam_match, &match_data)); ++ dma_free_coherent(dev, size, vaddr, dma_handle); + } + EXPORT_SYMBOL(dmam_free_coherent); + +diff --git a/kernel/events/core.c b/kernel/events/core.c +index 3e0db5b5a1835..0f2b5610933d7 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -2284,18 +2284,14 @@ event_sched_out(struct perf_event *event, struct perf_event_context *ctx) + } + + if (event->pending_sigtrap) { +- bool dec = true; +- + event->pending_sigtrap = 0; + if (state != PERF_EVENT_STATE_OFF && +- !event->pending_work) { ++ !event->pending_work && ++ !task_work_add(current, &event->pending_task, TWA_RESUME)) { + event->pending_work = 1; +- dec = false; +- WARN_ON_ONCE(!atomic_long_inc_not_zero(&event->refcount)); +- task_work_add(current, &event->pending_task, TWA_RESUME); +- } +- if (dec) ++ } else { + local_dec(&event->ctx->nr_pending); ++ } + } + + perf_event_set_state(event, state); +@@ -5175,9 +5171,35 @@ static bool exclusive_event_installable(struct perf_event *event, + static void perf_addr_filters_splice(struct perf_event *event, + struct list_head *head); + ++static void perf_pending_task_sync(struct perf_event *event) ++{ ++ struct callback_head *head = &event->pending_task; ++ ++ if (!event->pending_work) ++ return; ++ /* ++ * If the task is queued to the current task's queue, we ++ * obviously can't wait for it to complete. Simply cancel it. ++ */ ++ if (task_work_cancel(current, head)) { ++ event->pending_work = 0; ++ local_dec(&event->ctx->nr_pending); ++ return; ++ } ++ ++ /* ++ * All accesses related to the event are within the same ++ * non-preemptible section in perf_pending_task(). The RCU ++ * grace period before the event is freed will make sure all ++ * those accesses are complete by then. ++ */ ++ rcuwait_wait_event(&event->pending_work_wait, !event->pending_work, TASK_UNINTERRUPTIBLE); ++} ++ + static void _free_event(struct perf_event *event) + { + irq_work_sync(&event->pending_irq); ++ perf_pending_task_sync(event); + + unaccount_event(event); + +@@ -6478,6 +6500,8 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma) + return -EINVAL; + + nr_pages = vma_size / PAGE_SIZE; ++ if (nr_pages > INT_MAX) ++ return -ENOMEM; + + mutex_lock(&event->mmap_mutex); + ret = -EINVAL; +@@ -6808,24 +6832,28 @@ static void perf_pending_task(struct callback_head *head) + struct perf_event *event = container_of(head, struct perf_event, pending_task); + int rctx; + ++ /* ++ * All accesses to the event must belong to the same implicit RCU read-side ++ * critical section as the ->pending_work reset. See comment in ++ * perf_pending_task_sync(). ++ */ ++ preempt_disable_notrace(); + /* + * If we 'fail' here, that's OK, it means recursion is already disabled + * and we won't recurse 'further'. + */ +- preempt_disable_notrace(); + rctx = perf_swevent_get_recursion_context(); + + if (event->pending_work) { + event->pending_work = 0; + perf_sigtrap(event); + local_dec(&event->ctx->nr_pending); ++ rcuwait_wake_up(&event->pending_work_wait); + } + + if (rctx >= 0) + perf_swevent_put_recursion_context(rctx); + preempt_enable_notrace(); +- +- put_event(event); + } + + #ifdef CONFIG_GUEST_PERF_EVENTS +@@ -9271,21 +9299,19 @@ static void perf_event_bpf_emit_ksymbols(struct bpf_prog *prog, + bool unregister = type == PERF_BPF_EVENT_PROG_UNLOAD; + int i; + +- if (prog->aux->func_cnt == 0) { +- perf_event_ksymbol(PERF_RECORD_KSYMBOL_TYPE_BPF, +- (u64)(unsigned long)prog->bpf_func, +- prog->jited_len, unregister, +- prog->aux->ksym.name); +- } else { +- for (i = 0; i < prog->aux->func_cnt; i++) { +- struct bpf_prog *subprog = prog->aux->func[i]; +- +- perf_event_ksymbol( +- PERF_RECORD_KSYMBOL_TYPE_BPF, +- (u64)(unsigned long)subprog->bpf_func, +- subprog->jited_len, unregister, +- subprog->aux->ksym.name); +- } ++ perf_event_ksymbol(PERF_RECORD_KSYMBOL_TYPE_BPF, ++ (u64)(unsigned long)prog->bpf_func, ++ prog->jited_len, unregister, ++ prog->aux->ksym.name); ++ ++ for (i = 1; i < prog->aux->func_cnt; i++) { ++ struct bpf_prog *subprog = prog->aux->func[i]; ++ ++ perf_event_ksymbol( ++ PERF_RECORD_KSYMBOL_TYPE_BPF, ++ (u64)(unsigned long)subprog->bpf_func, ++ subprog->jited_len, unregister, ++ subprog->aux->ksym.name); + } + } + +@@ -11929,6 +11955,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, + init_waitqueue_head(&event->waitq); + init_irq_work(&event->pending_irq, perf_pending_irq); + init_task_work(&event->pending_task, perf_pending_task); ++ rcuwait_init(&event->pending_work_wait); + + mutex_init(&event->mmap_mutex); + raw_spin_lock_init(&event->addr_filters.lock); +diff --git a/kernel/events/internal.h b/kernel/events/internal.h +index 5150d5f84c033..386d21c7edfa0 100644 +--- a/kernel/events/internal.h ++++ b/kernel/events/internal.h +@@ -128,7 +128,7 @@ static inline unsigned long perf_data_size(struct perf_buffer *rb) + + static inline unsigned long perf_aux_size(struct perf_buffer *rb) + { +- return rb->aux_nr_pages << PAGE_SHIFT; ++ return (unsigned long)rb->aux_nr_pages << PAGE_SHIFT; + } + + #define __DEFINE_OUTPUT_COPY_BODY(advance_buf, memcpy_func, ...) \ +diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c +index e8d82c2f07d0e..f1f4a627f93db 100644 +--- a/kernel/events/ring_buffer.c ++++ b/kernel/events/ring_buffer.c +@@ -684,7 +684,9 @@ int rb_alloc_aux(struct perf_buffer *rb, struct perf_event *event, + * max_order, to aid PMU drivers in double buffering. + */ + if (!watermark) +- watermark = nr_pages << (PAGE_SHIFT - 1); ++ watermark = min_t(unsigned long, ++ U32_MAX, ++ (unsigned long)nr_pages << (PAGE_SHIFT - 1)); + + /* + * Use aux_watermark as the basis for chunking to +diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c +index 0bdef4fe925bf..ddaaccdc09fae 100644 +--- a/kernel/irq/irqdomain.c ++++ b/kernel/irq/irqdomain.c +@@ -154,7 +154,6 @@ static struct irq_domain *__irq_domain_create(struct fwnode_handle *fwnode, + switch (fwid->type) { + case IRQCHIP_FWNODE_NAMED: + case IRQCHIP_FWNODE_NAMED_ID: +- domain->fwnode = fwnode; + domain->name = kstrdup(fwid->name, GFP_KERNEL); + if (!domain->name) { + kfree(domain); +@@ -163,7 +162,6 @@ static struct irq_domain *__irq_domain_create(struct fwnode_handle *fwnode, + domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED; + break; + default: +- domain->fwnode = fwnode; + domain->name = fwid->name; + break; + } +@@ -183,7 +181,6 @@ static struct irq_domain *__irq_domain_create(struct fwnode_handle *fwnode, + } + + domain->name = strreplace(name, '/', ':'); +- domain->fwnode = fwnode; + domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED; + } + +@@ -199,8 +196,8 @@ static struct irq_domain *__irq_domain_create(struct fwnode_handle *fwnode, + domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED; + } + +- fwnode_handle_get(fwnode); +- fwnode_dev_initialized(fwnode, true); ++ domain->fwnode = fwnode_handle_get(fwnode); ++ fwnode_dev_initialized(domain->fwnode, true); + + /* Fill structure */ + INIT_RADIX_TREE(&domain->revmap_tree, GFP_KERNEL); +diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c +index 1782f90cd8c6c..a054cd5ec08bc 100644 +--- a/kernel/irq/manage.c ++++ b/kernel/irq/manage.c +@@ -1332,7 +1332,7 @@ static int irq_thread(void *data) + * synchronize_hardirq(). So neither IRQTF_RUNTHREAD nor the + * oneshot mask bit can be set. + */ +- task_work_cancel(current, irq_thread_dtor); ++ task_work_cancel_func(current, irq_thread_dtor); + return 0; + } + +diff --git a/kernel/jump_label.c b/kernel/jump_label.c +index d9c822bbffb8d..eec802175ccc6 100644 +--- a/kernel/jump_label.c ++++ b/kernel/jump_label.c +@@ -131,7 +131,7 @@ bool static_key_fast_inc_not_disabled(struct static_key *key) + STATIC_KEY_CHECK_USE(key); + /* + * Negative key->enabled has a special meaning: it sends +- * static_key_slow_inc() down the slow path, and it is non-zero ++ * static_key_slow_inc/dec() down the slow path, and it is non-zero + * so it counts as "enabled" in jump_label_update(). Note that + * atomic_inc_unless_negative() checks >= 0, so roll our own. + */ +@@ -150,7 +150,7 @@ bool static_key_slow_inc_cpuslocked(struct static_key *key) + lockdep_assert_cpus_held(); + + /* +- * Careful if we get concurrent static_key_slow_inc() calls; ++ * Careful if we get concurrent static_key_slow_inc/dec() calls; + * later calls must wait for the first one to _finish_ the + * jump_label_update() process. At the same time, however, + * the jump_label_update() call below wants to see +@@ -247,20 +247,32 @@ EXPORT_SYMBOL_GPL(static_key_disable); + + static bool static_key_slow_try_dec(struct static_key *key) + { +- int val; +- +- val = atomic_fetch_add_unless(&key->enabled, -1, 1); +- if (val == 1) +- return false; ++ int v; + + /* +- * The negative count check is valid even when a negative +- * key->enabled is in use by static_key_slow_inc(); a +- * __static_key_slow_dec() before the first static_key_slow_inc() +- * returns is unbalanced, because all other static_key_slow_inc() +- * instances block while the update is in progress. ++ * Go into the slow path if key::enabled is less than or equal than ++ * one. One is valid to shut down the key, anything less than one ++ * is an imbalance, which is handled at the call site. ++ * ++ * That includes the special case of '-1' which is set in ++ * static_key_slow_inc_cpuslocked(), but that's harmless as it is ++ * fully serialized in the slow path below. By the time this task ++ * acquires the jump label lock the value is back to one and the ++ * retry under the lock must succeed. + */ +- WARN(val < 0, "jump label: negative count!\n"); ++ v = atomic_read(&key->enabled); ++ do { ++ /* ++ * Warn about the '-1' case though; since that means a ++ * decrement is concurrent with a first (0->1) increment. IOW ++ * people are trying to disable something that wasn't yet fully ++ * enabled. This suggests an ordering problem on the user side. ++ */ ++ WARN_ON_ONCE(v < 0); ++ if (v <= 1) ++ return false; ++ } while (!likely(atomic_try_cmpxchg(&key->enabled, &v, v - 1))); ++ + return true; + } + +@@ -271,10 +283,11 @@ static void __static_key_slow_dec_cpuslocked(struct static_key *key) + if (static_key_slow_try_dec(key)) + return; + +- jump_label_lock(); +- if (atomic_dec_and_test(&key->enabled)) ++ guard(mutex)(&jump_label_mutex); ++ if (atomic_cmpxchg(&key->enabled, 1, 0)) + jump_label_update(key); +- jump_label_unlock(); ++ else ++ WARN_ON_ONCE(!static_key_slow_try_dec(key)); + } + + static void __static_key_slow_dec(struct static_key *key) +diff --git a/kernel/locking/rwsem.c b/kernel/locking/rwsem.c +index 9eabd585ce7af..11ed7ce6579e8 100644 +--- a/kernel/locking/rwsem.c ++++ b/kernel/locking/rwsem.c +@@ -1297,7 +1297,7 @@ static inline int __down_read_trylock(struct rw_semaphore *sem) + /* + * lock for writing + */ +-static inline int __down_write_common(struct rw_semaphore *sem, int state) ++static __always_inline int __down_write_common(struct rw_semaphore *sem, int state) + { + int ret = 0; + +@@ -1310,12 +1310,12 @@ static inline int __down_write_common(struct rw_semaphore *sem, int state) + return ret; + } + +-static inline void __down_write(struct rw_semaphore *sem) ++static __always_inline void __down_write(struct rw_semaphore *sem) + { + __down_write_common(sem, TASK_UNINTERRUPTIBLE); + } + +-static inline int __down_write_killable(struct rw_semaphore *sem) ++static __always_inline int __down_write_killable(struct rw_semaphore *sem) + { + return __down_write_common(sem, TASK_KILLABLE); + } +diff --git a/kernel/rcu/tasks.h b/kernel/rcu/tasks.h +index 305e960c08ac5..ff8d539ee22be 100644 +--- a/kernel/rcu/tasks.h ++++ b/kernel/rcu/tasks.h +@@ -1675,6 +1675,16 @@ static void rcu_tasks_trace_pregp_step(struct list_head *hop) + // allow safe access to the hop list. + for_each_online_cpu(cpu) { + rcu_read_lock(); ++ // Note that cpu_curr_snapshot() picks up the target ++ // CPU's current task while its runqueue is locked with ++ // an smp_mb__after_spinlock(). This ensures that either ++ // the grace-period kthread will see that task's read-side ++ // critical section or the task will see the updater's pre-GP ++ // accesses. The trailing smp_mb() in cpu_curr_snapshot() ++ // does not currently play a role other than simplify ++ // that function's ordering semantics. If these simplified ++ // ordering semantics continue to be redundant, that smp_mb() ++ // might be removed. + t = cpu_curr_snapshot(cpu); + if (rcu_tasks_trace_pertask_prep(t, true)) + trc_add_holdout(t, hop); +diff --git a/kernel/sched/core.c b/kernel/sched/core.c +index 820880960513b..92e4afeb71add 100644 +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -1304,27 +1304,24 @@ int tg_nop(struct task_group *tg, void *data) + static void set_load_weight(struct task_struct *p, bool update_load) + { + int prio = p->static_prio - MAX_RT_PRIO; +- struct load_weight *load = &p->se.load; ++ struct load_weight lw; + +- /* +- * SCHED_IDLE tasks get minimal weight: +- */ + if (task_has_idle_policy(p)) { +- load->weight = scale_load(WEIGHT_IDLEPRIO); +- load->inv_weight = WMULT_IDLEPRIO; +- return; ++ lw.weight = scale_load(WEIGHT_IDLEPRIO); ++ lw.inv_weight = WMULT_IDLEPRIO; ++ } else { ++ lw.weight = scale_load(sched_prio_to_weight[prio]); ++ lw.inv_weight = sched_prio_to_wmult[prio]; + } + + /* + * SCHED_OTHER tasks have to update their load when changing their + * weight + */ +- if (update_load && p->sched_class == &fair_sched_class) { +- reweight_task(p, prio); +- } else { +- load->weight = scale_load(sched_prio_to_weight[prio]); +- load->inv_weight = sched_prio_to_wmult[prio]; +- } ++ if (update_load && p->sched_class == &fair_sched_class) ++ reweight_task(p, &lw); ++ else ++ p->se.load = lw; + } + + #ifdef CONFIG_UCLAMP_TASK +@@ -4438,12 +4435,7 @@ int task_call_func(struct task_struct *p, task_call_f func, void *arg) + * @cpu: The CPU on which to snapshot the task. + * + * Returns the task_struct pointer of the task "currently" running on +- * the specified CPU. If the same task is running on that CPU throughout, +- * the return value will be a pointer to that task's task_struct structure. +- * If the CPU did any context switches even vaguely concurrently with the +- * execution of this function, the return value will be a pointer to the +- * task_struct structure of a randomly chosen task that was running on +- * that CPU somewhere around the time that this function was executing. ++ * the specified CPU. + * + * If the specified CPU was offline, the return value is whatever it + * is, perhaps a pointer to the task_struct structure of that CPU's idle +@@ -4457,11 +4449,16 @@ int task_call_func(struct task_struct *p, task_call_f func, void *arg) + */ + struct task_struct *cpu_curr_snapshot(int cpu) + { ++ struct rq *rq = cpu_rq(cpu); + struct task_struct *t; ++ struct rq_flags rf; + +- smp_mb(); /* Pairing determined by caller's synchronization design. */ ++ rq_lock_irqsave(rq, &rf); ++ smp_mb__after_spinlock(); /* Pairing determined by caller's synchronization design. */ + t = rcu_dereference(cpu_curr(cpu)); ++ rq_unlock_irqrestore(rq, &rf); + smp_mb(); /* Pairing determined by caller's synchronization design. */ ++ + return t; + } + +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index d3d0a1c9336be..b2e1009e5706e 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -3791,15 +3791,14 @@ static void reweight_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, + } + } + +-void reweight_task(struct task_struct *p, int prio) ++void reweight_task(struct task_struct *p, const struct load_weight *lw) + { + struct sched_entity *se = &p->se; + struct cfs_rq *cfs_rq = cfs_rq_of(se); + struct load_weight *load = &se->load; +- unsigned long weight = scale_load(sched_prio_to_weight[prio]); + +- reweight_entity(cfs_rq, se, weight); +- load->inv_weight = sched_prio_to_wmult[prio]; ++ reweight_entity(cfs_rq, se, lw->weight); ++ load->inv_weight = lw->inv_weight; + } + + static inline int throttled_hierarchy(struct cfs_rq *cfs_rq); +diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h +index 2e8f26a919edf..8cbbbea7fdbbd 100644 +--- a/kernel/sched/sched.h ++++ b/kernel/sched/sched.h +@@ -2435,7 +2435,7 @@ extern void init_sched_dl_class(void); + extern void init_sched_rt_class(void); + extern void init_sched_fair_class(void); + +-extern void reweight_task(struct task_struct *p, int prio); ++extern void reweight_task(struct task_struct *p, const struct load_weight *lw); + + extern void resched_curr(struct rq *rq); + extern void resched_cpu(int cpu); +diff --git a/kernel/signal.c b/kernel/signal.c +index 09019017d6690..21903f524ef86 100644 +--- a/kernel/signal.c ++++ b/kernel/signal.c +@@ -2587,6 +2587,14 @@ static void do_freezer_trap(void) + spin_unlock_irq(¤t->sighand->siglock); + cgroup_enter_frozen(); + schedule(); ++ ++ /* ++ * We could've been woken by task_work, run it to clear ++ * TIF_NOTIFY_SIGNAL. The caller will retry if necessary. ++ */ ++ clear_notify_signal(); ++ if (unlikely(task_work_pending(current))) ++ task_work_run(); + } + + static int ptrace_signal(int signr, kernel_siginfo_t *info, enum pid_type type) +diff --git a/kernel/task_work.c b/kernel/task_work.c +index 95a7e1b7f1dab..2134ac8057a94 100644 +--- a/kernel/task_work.c ++++ b/kernel/task_work.c +@@ -120,9 +120,9 @@ static bool task_work_func_match(struct callback_head *cb, void *data) + } + + /** +- * task_work_cancel - cancel a pending work added by task_work_add() +- * @task: the task which should execute the work +- * @func: identifies the work to remove ++ * task_work_cancel_func - cancel a pending work matching a function added by task_work_add() ++ * @task: the task which should execute the func's work ++ * @func: identifies the func to match with a work to remove + * + * Find the last queued pending work with ->func == @func and remove + * it from queue. +@@ -131,11 +131,35 @@ static bool task_work_func_match(struct callback_head *cb, void *data) + * The found work or NULL if not found. + */ + struct callback_head * +-task_work_cancel(struct task_struct *task, task_work_func_t func) ++task_work_cancel_func(struct task_struct *task, task_work_func_t func) + { + return task_work_cancel_match(task, task_work_func_match, func); + } + ++static bool task_work_match(struct callback_head *cb, void *data) ++{ ++ return cb == data; ++} ++ ++/** ++ * task_work_cancel - cancel a pending work added by task_work_add() ++ * @task: the task which should execute the work ++ * @cb: the callback to remove if queued ++ * ++ * Remove a callback from a task's queue if queued. ++ * ++ * RETURNS: ++ * True if the callback was queued and got cancelled, false otherwise. ++ */ ++bool task_work_cancel(struct task_struct *task, struct callback_head *cb) ++{ ++ struct callback_head *ret; ++ ++ ret = task_work_cancel_match(task, task_work_match, cb); ++ ++ return ret == cb; ++} ++ + /** + * task_work_run - execute the works added by task_work_add() + * +@@ -168,7 +192,7 @@ void task_work_run(void) + if (!work) + break; + /* +- * Synchronize with task_work_cancel(). It can not remove ++ * Synchronize with task_work_cancel_match(). It can not remove + * the first entry == work, cmpxchg(task_works) must fail. + * But it can remove another entry from the ->next list. + */ +diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c +index 771d1e040303b..b4843099a8da7 100644 +--- a/kernel/time/tick-broadcast.c ++++ b/kernel/time/tick-broadcast.c +@@ -1141,6 +1141,7 @@ void tick_broadcast_switch_to_oneshot(void) + #ifdef CONFIG_HOTPLUG_CPU + void hotplug_cpu__broadcast_tick_pull(int deadcpu) + { ++ struct tick_device *td = this_cpu_ptr(&tick_cpu_device); + struct clock_event_device *bc; + unsigned long flags; + +@@ -1148,6 +1149,28 @@ void hotplug_cpu__broadcast_tick_pull(int deadcpu) + bc = tick_broadcast_device.evtdev; + + if (bc && broadcast_needs_cpu(bc, deadcpu)) { ++ /* ++ * If the broadcast force bit of the current CPU is set, ++ * then the current CPU has not yet reprogrammed the local ++ * timer device to avoid a ping-pong race. See ++ * ___tick_broadcast_oneshot_control(). ++ * ++ * If the broadcast device is hrtimer based then ++ * programming the broadcast event below does not have any ++ * effect because the local clockevent device is not ++ * running and not programmed because the broadcast event ++ * is not earlier than the pending event of the local clock ++ * event device. As a consequence all CPUs waiting for a ++ * broadcast event are stuck forever. ++ * ++ * Detect this condition and reprogram the cpu local timer ++ * device to avoid the starvation. ++ */ ++ if (tick_check_broadcast_expired()) { ++ cpumask_clear_cpu(smp_processor_id(), tick_broadcast_force_mask); ++ tick_program_event(td->evtdev->next_event, 1); ++ } ++ + /* This moves the broadcast assignment to this CPU: */ + clockevents_program_event(bc, bc->next_event, 1); + } +diff --git a/kernel/trace/pid_list.c b/kernel/trace/pid_list.c +index 95106d02b32d8..85de221c0b6f2 100644 +--- a/kernel/trace/pid_list.c ++++ b/kernel/trace/pid_list.c +@@ -354,7 +354,7 @@ static void pid_list_refill_irq(struct irq_work *iwork) + while (upper_count-- > 0) { + union upper_chunk *chunk; + +- chunk = kzalloc(sizeof(*chunk), GFP_KERNEL); ++ chunk = kzalloc(sizeof(*chunk), GFP_NOWAIT); + if (!chunk) + break; + *upper_next = chunk; +@@ -365,7 +365,7 @@ static void pid_list_refill_irq(struct irq_work *iwork) + while (lower_count-- > 0) { + union lower_chunk *chunk; + +- chunk = kzalloc(sizeof(*chunk), GFP_KERNEL); ++ chunk = kzalloc(sizeof(*chunk), GFP_NOWAIT); + if (!chunk) + break; + *lower_next = chunk; +diff --git a/kernel/watchdog_perf.c b/kernel/watchdog_perf.c +index 8ea00c4a24b2d..0052afe18b7fc 100644 +--- a/kernel/watchdog_perf.c ++++ b/kernel/watchdog_perf.c +@@ -75,11 +75,15 @@ static bool watchdog_check_timestamp(void) + __this_cpu_write(last_timestamp, now); + return true; + } +-#else +-static inline bool watchdog_check_timestamp(void) ++ ++static void watchdog_init_timestamp(void) + { +- return true; ++ __this_cpu_write(nmi_rearmed, 0); ++ __this_cpu_write(last_timestamp, ktime_get_mono_fast_ns()); + } ++#else ++static inline bool watchdog_check_timestamp(void) { return true; } ++static inline void watchdog_init_timestamp(void) { } + #endif + + static struct perf_event_attr wd_hw_attr = { +@@ -147,6 +151,7 @@ void watchdog_hardlockup_enable(unsigned int cpu) + if (!atomic_fetch_inc(&watchdog_cpus)) + pr_info("Enabled. Permanently consumes one hw-PMU counter.\n"); + ++ watchdog_init_timestamp(); + perf_event_enable(this_cpu_read(watchdog_ev)); + } + +diff --git a/lib/build_OID_registry b/lib/build_OID_registry +index d7fc32ea8ac22..56d8bafeb848b 100755 +--- a/lib/build_OID_registry ++++ b/lib/build_OID_registry +@@ -8,6 +8,7 @@ + # + + use strict; ++use Cwd qw(abs_path); + + my @names = (); + my @oids = (); +@@ -17,6 +18,8 @@ if ($#ARGV != 1) { + exit(2); + } + ++my $abs_srctree = abs_path($ENV{'srctree'}); ++ + # + # Open the file to read from + # +@@ -35,7 +38,7 @@ close IN_FILE || die; + # + open C_FILE, ">$ARGV[1]" or die; + print C_FILE "/*\n"; +-print C_FILE " * Automatically generated by ", $0, ". Do not edit\n"; ++print C_FILE " * Automatically generated by ", $0 =~ s#^\Q$abs_srctree/\E##r, ". Do not edit\n"; + print C_FILE " */\n"; + + # +diff --git a/lib/decompress_bunzip2.c b/lib/decompress_bunzip2.c +index 3518e7394eca8..ca736166f1000 100644 +--- a/lib/decompress_bunzip2.c ++++ b/lib/decompress_bunzip2.c +@@ -232,7 +232,8 @@ static int INIT get_next_block(struct bunzip_data *bd) + RUNB) */ + symCount = symTotal+2; + for (j = 0; j < groupCount; j++) { +- unsigned char length[MAX_SYMBOLS], temp[MAX_HUFCODE_BITS+1]; ++ unsigned char length[MAX_SYMBOLS]; ++ unsigned short temp[MAX_HUFCODE_BITS+1]; + int minLen, maxLen, pp; + /* Read Huffman code lengths for each symbol. They're + stored in a way similar to mtf; record a starting +diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c +index 7c44b7ae4c5c3..d397b1ad5ccf0 100644 +--- a/lib/kobject_uevent.c ++++ b/lib/kobject_uevent.c +@@ -432,8 +432,23 @@ static void zap_modalias_env(struct kobj_uevent_env *env) + len = strlen(env->envp[i]) + 1; + + if (i != env->envp_idx - 1) { ++ /* @env->envp[] contains pointers to @env->buf[] ++ * with @env->buflen chars, and we are removing ++ * variable MODALIAS here pointed by @env->envp[i] ++ * with length @len as shown below: ++ * ++ * 0 @env->buf[] @env->buflen ++ * --------------------------------------------- ++ * ^ ^ ^ ^ ++ * | |-> @len <-| target block | ++ * @env->envp[0] @env->envp[i] @env->envp[i + 1] ++ * ++ * so the "target block" indicated above is moved ++ * backward by @len, and its right size is ++ * @env->buflen - (@env->envp[i + 1] - @env->envp[0]). ++ */ + memmove(env->envp[i], env->envp[i + 1], +- env->buflen - len); ++ env->buflen - (env->envp[i + 1] - env->envp[0])); + + for (j = i; j < env->envp_idx - 1; j++) + env->envp[j] = env->envp[j + 1] - len; +diff --git a/lib/objagg.c b/lib/objagg.c +index 1e248629ed643..1608895b009c8 100644 +--- a/lib/objagg.c ++++ b/lib/objagg.c +@@ -167,6 +167,9 @@ static int objagg_obj_parent_assign(struct objagg *objagg, + { + void *delta_priv; + ++ if (WARN_ON(!objagg_obj_is_root(parent))) ++ return -EINVAL; ++ + delta_priv = objagg->ops->delta_create(objagg->priv, parent->obj, + objagg_obj->obj); + if (IS_ERR(delta_priv)) +@@ -903,20 +906,6 @@ static const struct objagg_opt_algo *objagg_opt_algos[] = { + [OBJAGG_OPT_ALGO_SIMPLE_GREEDY] = &objagg_opt_simple_greedy, + }; + +-static int objagg_hints_obj_cmp(struct rhashtable_compare_arg *arg, +- const void *obj) +-{ +- struct rhashtable *ht = arg->ht; +- struct objagg_hints *objagg_hints = +- container_of(ht, struct objagg_hints, node_ht); +- const struct objagg_ops *ops = objagg_hints->ops; +- const char *ptr = obj; +- +- ptr += ht->p.key_offset; +- return ops->hints_obj_cmp ? ops->hints_obj_cmp(ptr, arg->key) : +- memcmp(ptr, arg->key, ht->p.key_len); +-} +- + /** + * objagg_hints_get - obtains hints instance + * @objagg: objagg instance +@@ -955,7 +944,6 @@ struct objagg_hints *objagg_hints_get(struct objagg *objagg, + offsetof(struct objagg_hints_node, obj); + objagg_hints->ht_params.head_offset = + offsetof(struct objagg_hints_node, ht_node); +- objagg_hints->ht_params.obj_cmpfn = objagg_hints_obj_cmp; + + err = rhashtable_init(&objagg_hints->node_ht, &objagg_hints->ht_params); + if (err) +diff --git a/lib/sbitmap.c b/lib/sbitmap.c +index d0a5081dfd122..9307bf17a8175 100644 +--- a/lib/sbitmap.c ++++ b/lib/sbitmap.c +@@ -60,12 +60,30 @@ static inline void update_alloc_hint_after_get(struct sbitmap *sb, + /* + * See if we have deferred clears that we can batch move + */ +-static inline bool sbitmap_deferred_clear(struct sbitmap_word *map) ++static inline bool sbitmap_deferred_clear(struct sbitmap_word *map, ++ unsigned int depth, unsigned int alloc_hint, bool wrap) + { +- unsigned long mask; ++ unsigned long mask, word_mask; + +- if (!READ_ONCE(map->cleared)) +- return false; ++ guard(spinlock_irqsave)(&map->swap_lock); ++ ++ if (!map->cleared) { ++ if (depth == 0) ++ return false; ++ ++ word_mask = (~0UL) >> (BITS_PER_LONG - depth); ++ /* ++ * The current behavior is to always retry after moving ++ * ->cleared to word, and we change it to retry in case ++ * of any free bits. To avoid an infinite loop, we need ++ * to take wrap & alloc_hint into account, otherwise a ++ * soft lockup may occur. ++ */ ++ if (!wrap && alloc_hint) ++ word_mask &= ~((1UL << alloc_hint) - 1); ++ ++ return (READ_ONCE(map->word) & word_mask) != word_mask; ++ } + + /* + * First get a stable cleared mask, setting the old mask to 0. +@@ -85,6 +103,7 @@ int sbitmap_init_node(struct sbitmap *sb, unsigned int depth, int shift, + bool alloc_hint) + { + unsigned int bits_per_word; ++ int i; + + if (shift < 0) + shift = sbitmap_calculate_shift(depth); +@@ -116,6 +135,9 @@ int sbitmap_init_node(struct sbitmap *sb, unsigned int depth, int shift, + return -ENOMEM; + } + ++ for (i = 0; i < sb->map_nr; i++) ++ spin_lock_init(&sb->map[i].swap_lock); ++ + return 0; + } + EXPORT_SYMBOL_GPL(sbitmap_init_node); +@@ -126,7 +148,7 @@ void sbitmap_resize(struct sbitmap *sb, unsigned int depth) + unsigned int i; + + for (i = 0; i < sb->map_nr; i++) +- sbitmap_deferred_clear(&sb->map[i]); ++ sbitmap_deferred_clear(&sb->map[i], 0, 0, 0); + + sb->depth = depth; + sb->map_nr = DIV_ROUND_UP(sb->depth, bits_per_word); +@@ -179,7 +201,7 @@ static int sbitmap_find_bit_in_word(struct sbitmap_word *map, + alloc_hint, wrap); + if (nr != -1) + break; +- if (!sbitmap_deferred_clear(map)) ++ if (!sbitmap_deferred_clear(map, depth, alloc_hint, wrap)) + break; + } while (1); + +@@ -499,18 +521,18 @@ unsigned long __sbitmap_queue_get_batch(struct sbitmap_queue *sbq, int nr_tags, + struct sbitmap_word *map = &sb->map[index]; + unsigned long get_mask; + unsigned int map_depth = __map_depth(sb, index); ++ unsigned long val; + +- sbitmap_deferred_clear(map); +- if (map->word == (1UL << (map_depth - 1)) - 1) ++ sbitmap_deferred_clear(map, 0, 0, 0); ++ val = READ_ONCE(map->word); ++ if (val == (1UL << (map_depth - 1)) - 1) + goto next; + +- nr = find_first_zero_bit(&map->word, map_depth); ++ nr = find_first_zero_bit(&val, map_depth); + if (nr + nr_tags <= map_depth) { + atomic_long_t *ptr = (atomic_long_t *) &map->word; +- unsigned long val; + + get_mask = ((1UL << nr_tags) - 1) << nr; +- val = READ_ONCE(map->word); + while (!atomic_long_try_cmpxchg(ptr, &val, + get_mask | val)) + ; +diff --git a/mm/hugetlb.c b/mm/hugetlb.c +index 789decf5d11ba..a480affd475bf 100644 +--- a/mm/hugetlb.c ++++ b/mm/hugetlb.c +@@ -2518,6 +2518,23 @@ struct folio *alloc_hugetlb_folio_vma(struct hstate *h, struct vm_area_struct *v + return folio; + } + ++static nodemask_t *policy_mbind_nodemask(gfp_t gfp) ++{ ++#ifdef CONFIG_NUMA ++ struct mempolicy *mpol = get_task_policy(current); ++ ++ /* ++ * Only enforce MPOL_BIND policy which overlaps with cpuset policy ++ * (from policy_nodemask) specifically for hugetlb case ++ */ ++ if (mpol->mode == MPOL_BIND && ++ (apply_policy_zone(mpol, gfp_zone(gfp)) && ++ cpuset_nodemask_valid_mems_allowed(&mpol->nodes))) ++ return &mpol->nodes; ++#endif ++ return NULL; ++} ++ + /* + * Increase the hugetlb pool such that it can accommodate a reservation + * of size 'delta'. +@@ -2531,6 +2548,8 @@ static int gather_surplus_pages(struct hstate *h, long delta) + long i; + long needed, allocated; + bool alloc_ok = true; ++ int node; ++ nodemask_t *mbind_nodemask = policy_mbind_nodemask(htlb_alloc_mask(h)); + + lockdep_assert_held(&hugetlb_lock); + needed = (h->resv_huge_pages + delta) - h->free_huge_pages; +@@ -2545,8 +2564,15 @@ static int gather_surplus_pages(struct hstate *h, long delta) + retry: + spin_unlock_irq(&hugetlb_lock); + for (i = 0; i < needed; i++) { +- folio = alloc_surplus_hugetlb_folio(h, htlb_alloc_mask(h), +- NUMA_NO_NODE, NULL); ++ folio = NULL; ++ for_each_node_mask(node, cpuset_current_mems_allowed) { ++ if (!mbind_nodemask || node_isset(node, *mbind_nodemask)) { ++ folio = alloc_surplus_hugetlb_folio(h, htlb_alloc_mask(h), ++ node, NULL); ++ if (folio) ++ break; ++ } ++ } + if (!folio) { + alloc_ok = false; + break; +@@ -4308,7 +4334,7 @@ void __init hugetlb_add_hstate(unsigned int order) + BUG_ON(hugetlb_max_hstate >= HUGE_MAX_HSTATE); + BUG_ON(order == 0); + h = &hstates[hugetlb_max_hstate++]; +- mutex_init(&h->resize_lock); ++ __mutex_init(&h->resize_lock, "resize mutex", &h->resize_key); + h->order = order; + h->mask = ~(huge_page_size(h) - 1); + for (i = 0; i < MAX_NUMNODES; ++i) +@@ -4531,23 +4557,6 @@ static int __init default_hugepagesz_setup(char *s) + } + __setup("default_hugepagesz=", default_hugepagesz_setup); + +-static nodemask_t *policy_mbind_nodemask(gfp_t gfp) +-{ +-#ifdef CONFIG_NUMA +- struct mempolicy *mpol = get_task_policy(current); +- +- /* +- * Only enforce MPOL_BIND policy which overlaps with cpuset policy +- * (from policy_nodemask) specifically for hugetlb case +- */ +- if (mpol->mode == MPOL_BIND && +- (apply_policy_zone(mpol, gfp_zone(gfp)) && +- cpuset_nodemask_valid_mems_allowed(&mpol->nodes))) +- return &mpol->nodes; +-#endif +- return NULL; +-} +- + static unsigned int allowed_mems_nr(struct hstate *h) + { + int node; +diff --git a/mm/memory.c b/mm/memory.c +index e44d4d887cf6d..58408bf96e0eb 100644 +--- a/mm/memory.c ++++ b/mm/memory.c +@@ -4353,7 +4353,7 @@ void set_pte_range(struct vm_fault *vmf, struct folio *folio, + struct vm_area_struct *vma = vmf->vma; + bool uffd_wp = vmf_orig_pte_uffd_wp(vmf); + bool write = vmf->flags & FAULT_FLAG_WRITE; +- bool prefault = in_range(vmf->address, addr, nr * PAGE_SIZE); ++ bool prefault = !in_range(vmf->address, addr, nr * PAGE_SIZE); + pte_t entry; + + flush_icache_pages(vma, page, nr); +diff --git a/mm/mempolicy.c b/mm/mempolicy.c +index e52e3a0b8f2e6..4cae854c0f28d 100644 +--- a/mm/mempolicy.c ++++ b/mm/mempolicy.c +@@ -3134,8 +3134,9 @@ int mpol_parse_str(char *str, struct mempolicy **mpol) + * @pol: pointer to mempolicy to be formatted + * + * Convert @pol into a string. If @buffer is too short, truncate the string. +- * Recommend a @maxlen of at least 32 for the longest mode, "interleave", the +- * longest flag, "relative", and to display at least a few node ids. ++ * Recommend a @maxlen of at least 51 for the longest mode, "weighted ++ * interleave", plus the longest flag flags, "relative|balancing", and to ++ * display at least a few node ids. + */ + void mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol) + { +@@ -3144,7 +3145,10 @@ void mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol) + unsigned short mode = MPOL_DEFAULT; + unsigned short flags = 0; + +- if (pol && pol != &default_policy && !(pol->flags & MPOL_F_MORON)) { ++ if (pol && ++ pol != &default_policy && ++ !(pol >= &preferred_node_policy[0] && ++ pol <= &preferred_node_policy[ARRAY_SIZE(preferred_node_policy) - 1])) { + mode = pol->mode; + flags = pol->flags; + } +@@ -3171,12 +3175,18 @@ void mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol) + p += snprintf(p, buffer + maxlen - p, "="); + + /* +- * Currently, the only defined flags are mutually exclusive ++ * Static and relative are mutually exclusive. + */ + if (flags & MPOL_F_STATIC_NODES) + p += snprintf(p, buffer + maxlen - p, "static"); + else if (flags & MPOL_F_RELATIVE_NODES) + p += snprintf(p, buffer + maxlen - p, "relative"); ++ ++ if (flags & MPOL_F_NUMA_BALANCING) { ++ if (!is_power_of_2(flags & MPOL_MODE_FLAGS)) ++ p += snprintf(p, buffer + maxlen - p, "|"); ++ p += snprintf(p, buffer + maxlen - p, "balancing"); ++ } + } + + if (!nodes_empty(nodes)) +diff --git a/mm/mmap_lock.c b/mm/mmap_lock.c +index 1854850b4b897..368b840e75082 100644 +--- a/mm/mmap_lock.c ++++ b/mm/mmap_lock.c +@@ -19,14 +19,7 @@ EXPORT_TRACEPOINT_SYMBOL(mmap_lock_released); + + #ifdef CONFIG_MEMCG + +-/* +- * Our various events all share the same buffer (because we don't want or need +- * to allocate a set of buffers *per event type*), so we need to protect against +- * concurrent _reg() and _unreg() calls, and count how many _reg() calls have +- * been made. +- */ +-static DEFINE_MUTEX(reg_lock); +-static int reg_refcount; /* Protected by reg_lock. */ ++static atomic_t reg_refcount; + + /* + * Size of the buffer for memcg path names. Ignoring stack trace support, +@@ -34,136 +27,22 @@ static int reg_refcount; /* Protected by reg_lock. */ + */ + #define MEMCG_PATH_BUF_SIZE MAX_FILTER_STR_VAL + +-/* +- * How many contexts our trace events might be called in: normal, softirq, irq, +- * and NMI. +- */ +-#define CONTEXT_COUNT 4 +- +-struct memcg_path { +- local_lock_t lock; +- char __rcu *buf; +- local_t buf_idx; +-}; +-static DEFINE_PER_CPU(struct memcg_path, memcg_paths) = { +- .lock = INIT_LOCAL_LOCK(lock), +- .buf_idx = LOCAL_INIT(0), +-}; +- +-static char **tmp_bufs; +- +-/* Called with reg_lock held. */ +-static void free_memcg_path_bufs(void) +-{ +- struct memcg_path *memcg_path; +- int cpu; +- char **old = tmp_bufs; +- +- for_each_possible_cpu(cpu) { +- memcg_path = per_cpu_ptr(&memcg_paths, cpu); +- *(old++) = rcu_dereference_protected(memcg_path->buf, +- lockdep_is_held(®_lock)); +- rcu_assign_pointer(memcg_path->buf, NULL); +- } +- +- /* Wait for inflight memcg_path_buf users to finish. */ +- synchronize_rcu(); +- +- old = tmp_bufs; +- for_each_possible_cpu(cpu) { +- kfree(*(old++)); +- } +- +- kfree(tmp_bufs); +- tmp_bufs = NULL; +-} +- + int trace_mmap_lock_reg(void) + { +- int cpu; +- char *new; +- +- mutex_lock(®_lock); +- +- /* If the refcount is going 0->1, proceed with allocating buffers. */ +- if (reg_refcount++) +- goto out; +- +- tmp_bufs = kmalloc_array(num_possible_cpus(), sizeof(*tmp_bufs), +- GFP_KERNEL); +- if (tmp_bufs == NULL) +- goto out_fail; +- +- for_each_possible_cpu(cpu) { +- new = kmalloc(MEMCG_PATH_BUF_SIZE * CONTEXT_COUNT, GFP_KERNEL); +- if (new == NULL) +- goto out_fail_free; +- rcu_assign_pointer(per_cpu_ptr(&memcg_paths, cpu)->buf, new); +- /* Don't need to wait for inflights, they'd have gotten NULL. */ +- } +- +-out: +- mutex_unlock(®_lock); ++ atomic_inc(®_refcount); + return 0; +- +-out_fail_free: +- free_memcg_path_bufs(); +-out_fail: +- /* Since we failed, undo the earlier ref increment. */ +- --reg_refcount; +- +- mutex_unlock(®_lock); +- return -ENOMEM; + } + + void trace_mmap_lock_unreg(void) + { +- mutex_lock(®_lock); +- +- /* If the refcount is going 1->0, proceed with freeing buffers. */ +- if (--reg_refcount) +- goto out; +- +- free_memcg_path_bufs(); +- +-out: +- mutex_unlock(®_lock); +-} +- +-static inline char *get_memcg_path_buf(void) +-{ +- struct memcg_path *memcg_path = this_cpu_ptr(&memcg_paths); +- char *buf; +- int idx; +- +- rcu_read_lock(); +- buf = rcu_dereference(memcg_path->buf); +- if (buf == NULL) { +- rcu_read_unlock(); +- return NULL; +- } +- idx = local_add_return(MEMCG_PATH_BUF_SIZE, &memcg_path->buf_idx) - +- MEMCG_PATH_BUF_SIZE; +- return &buf[idx]; ++ atomic_dec(®_refcount); + } + +-static inline void put_memcg_path_buf(void) +-{ +- local_sub(MEMCG_PATH_BUF_SIZE, &this_cpu_ptr(&memcg_paths)->buf_idx); +- rcu_read_unlock(); +-} +- +-#define TRACE_MMAP_LOCK_EVENT(type, mm, ...) \ +- do { \ +- const char *memcg_path; \ +- local_lock(&memcg_paths.lock); \ +- memcg_path = get_mm_memcg_path(mm); \ +- trace_mmap_lock_##type(mm, \ +- memcg_path != NULL ? memcg_path : "", \ +- ##__VA_ARGS__); \ +- if (likely(memcg_path != NULL)) \ +- put_memcg_path_buf(); \ +- local_unlock(&memcg_paths.lock); \ ++#define TRACE_MMAP_LOCK_EVENT(type, mm, ...) \ ++ do { \ ++ char buf[MEMCG_PATH_BUF_SIZE]; \ ++ get_mm_memcg_path(mm, buf, sizeof(buf)); \ ++ trace_mmap_lock_##type(mm, buf, ##__VA_ARGS__); \ + } while (0) + + #else /* !CONFIG_MEMCG */ +@@ -185,37 +64,23 @@ void trace_mmap_lock_unreg(void) + #ifdef CONFIG_TRACING + #ifdef CONFIG_MEMCG + /* +- * Write the given mm_struct's memcg path to a percpu buffer, and return a +- * pointer to it. If the path cannot be determined, or no buffer was available +- * (because the trace event is being unregistered), NULL is returned. +- * +- * Note: buffers are allocated per-cpu to avoid locking, so preemption must be +- * disabled by the caller before calling us, and re-enabled only after the +- * caller is done with the pointer. +- * +- * The caller must call put_memcg_path_buf() once the buffer is no longer +- * needed. This must be done while preemption is still disabled. ++ * Write the given mm_struct's memcg path to a buffer. If the path cannot be ++ * determined or the trace event is being unregistered, empty string is written. + */ +-static const char *get_mm_memcg_path(struct mm_struct *mm) ++static void get_mm_memcg_path(struct mm_struct *mm, char *buf, size_t buflen) + { +- char *buf = NULL; +- struct mem_cgroup *memcg = get_mem_cgroup_from_mm(mm); ++ struct mem_cgroup *memcg; + ++ buf[0] = '\0'; ++ /* No need to get path if no trace event is registered. */ ++ if (!atomic_read(®_refcount)) ++ return; ++ memcg = get_mem_cgroup_from_mm(mm); + if (memcg == NULL) +- goto out; +- if (unlikely(memcg->css.cgroup == NULL)) +- goto out_put; +- +- buf = get_memcg_path_buf(); +- if (buf == NULL) +- goto out_put; +- +- cgroup_path(memcg->css.cgroup, buf, MEMCG_PATH_BUF_SIZE); +- +-out_put: ++ return; ++ if (memcg->css.cgroup) ++ cgroup_path(memcg->css.cgroup, buf, buflen); + css_put(&memcg->css); +-out: +- return buf; + } + + #endif /* CONFIG_MEMCG */ +diff --git a/mm/vmscan.c b/mm/vmscan.c +index e9d4c1f6d7bb9..83fa8e924f8ae 100644 +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -4546,6 +4546,32 @@ static bool try_to_inc_max_seq(struct lruvec *lruvec, unsigned long max_seq, + * working set protection + ******************************************************************************/ + ++static void set_initial_priority(struct pglist_data *pgdat, struct scan_control *sc) ++{ ++ int priority; ++ unsigned long reclaimable; ++ ++ if (sc->priority != DEF_PRIORITY || sc->nr_to_reclaim < MIN_LRU_BATCH) ++ return; ++ /* ++ * Determine the initial priority based on ++ * (total >> priority) * reclaimed_to_scanned_ratio = nr_to_reclaim, ++ * where reclaimed_to_scanned_ratio = inactive / total. ++ */ ++ reclaimable = node_page_state(pgdat, NR_INACTIVE_FILE); ++ if (can_reclaim_anon_pages(NULL, pgdat->node_id, sc)) ++ reclaimable += node_page_state(pgdat, NR_INACTIVE_ANON); ++ ++ /* round down reclaimable and round up sc->nr_to_reclaim */ ++ priority = fls_long(reclaimable) - 1 - fls_long(sc->nr_to_reclaim - 1); ++ ++ /* ++ * The estimation is based on LRU pages only, so cap it to prevent ++ * overshoots of shrinker objects by large margins. ++ */ ++ sc->priority = clamp(priority, DEF_PRIORITY / 2, DEF_PRIORITY); ++} ++ + static bool lruvec_is_sizable(struct lruvec *lruvec, struct scan_control *sc) + { + int gen, type, zone; +@@ -4579,19 +4605,17 @@ static bool lruvec_is_reclaimable(struct lruvec *lruvec, struct scan_control *sc + struct mem_cgroup *memcg = lruvec_memcg(lruvec); + DEFINE_MIN_SEQ(lruvec); + +- /* see the comment on lru_gen_folio */ +- gen = lru_gen_from_seq(min_seq[LRU_GEN_FILE]); +- birth = READ_ONCE(lruvec->lrugen.timestamps[gen]); +- +- if (time_is_after_jiffies(birth + min_ttl)) ++ if (mem_cgroup_below_min(NULL, memcg)) + return false; + + if (!lruvec_is_sizable(lruvec, sc)) + return false; + +- mem_cgroup_calculate_protection(NULL, memcg); ++ /* see the comment on lru_gen_folio */ ++ gen = lru_gen_from_seq(min_seq[LRU_GEN_FILE]); ++ birth = READ_ONCE(lruvec->lrugen.timestamps[gen]); + +- return !mem_cgroup_below_min(NULL, memcg); ++ return time_is_before_jiffies(birth + min_ttl); + } + + /* to protect the working set of the last N jiffies */ +@@ -4601,23 +4625,20 @@ static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc) + { + struct mem_cgroup *memcg; + unsigned long min_ttl = READ_ONCE(lru_gen_min_ttl); ++ bool reclaimable = !min_ttl; + + VM_WARN_ON_ONCE(!current_is_kswapd()); + +- /* check the order to exclude compaction-induced reclaim */ +- if (!min_ttl || sc->order || sc->priority == DEF_PRIORITY) +- return; ++ set_initial_priority(pgdat, sc); + + memcg = mem_cgroup_iter(NULL, NULL, NULL); + do { + struct lruvec *lruvec = mem_cgroup_lruvec(memcg, pgdat); + +- if (lruvec_is_reclaimable(lruvec, sc, min_ttl)) { +- mem_cgroup_iter_break(NULL, memcg); +- return; +- } ++ mem_cgroup_calculate_protection(NULL, memcg); + +- cond_resched(); ++ if (!reclaimable) ++ reclaimable = lruvec_is_reclaimable(lruvec, sc, min_ttl); + } while ((memcg = mem_cgroup_iter(NULL, memcg, NULL))); + + /* +@@ -4625,7 +4646,7 @@ static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc) + * younger than min_ttl. However, another possibility is all memcgs are + * either too small or below min. + */ +- if (mutex_trylock(&oom_lock)) { ++ if (!reclaimable && mutex_trylock(&oom_lock)) { + struct oom_control oc = { + .gfp_mask = sc->gfp_mask, + }; +@@ -5226,7 +5247,6 @@ static int evict_folios(struct lruvec *lruvec, struct scan_control *sc, int swap + + /* retry folios that may have missed folio_rotate_reclaimable() */ + list_move(&folio->lru, &clean); +- sc->nr_scanned -= folio_nr_pages(folio); + } + + spin_lock_irq(&lruvec->lru_lock); +@@ -5425,8 +5445,7 @@ static int shrink_one(struct lruvec *lruvec, struct scan_control *sc) + struct mem_cgroup *memcg = lruvec_memcg(lruvec); + struct pglist_data *pgdat = lruvec_pgdat(lruvec); + +- mem_cgroup_calculate_protection(NULL, memcg); +- ++ /* lru_gen_age_node() called mem_cgroup_calculate_protection() */ + if (mem_cgroup_below_min(NULL, memcg)) + return MEMCG_LRU_YOUNG; + +@@ -5566,29 +5585,6 @@ static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc + + #endif + +-static void set_initial_priority(struct pglist_data *pgdat, struct scan_control *sc) +-{ +- int priority; +- unsigned long reclaimable; +- struct lruvec *lruvec = mem_cgroup_lruvec(NULL, pgdat); +- +- if (sc->priority != DEF_PRIORITY || sc->nr_to_reclaim < MIN_LRU_BATCH) +- return; +- /* +- * Determine the initial priority based on +- * (total >> priority) * reclaimed_to_scanned_ratio = nr_to_reclaim, +- * where reclaimed_to_scanned_ratio = inactive / total. +- */ +- reclaimable = node_page_state(pgdat, NR_INACTIVE_FILE); +- if (get_swappiness(lruvec, sc)) +- reclaimable += node_page_state(pgdat, NR_INACTIVE_ANON); +- +- /* round down reclaimable and round up sc->nr_to_reclaim */ +- priority = fls_long(reclaimable) - 1 - fls_long(sc->nr_to_reclaim - 1); +- +- sc->priority = clamp(priority, 0, DEF_PRIORITY); +-} +- + static void lru_gen_shrink_node(struct pglist_data *pgdat, struct scan_control *sc) + { + struct blk_plug plug; +@@ -7351,6 +7347,7 @@ static bool kswapd_shrink_node(pg_data_t *pgdat, + { + struct zone *zone; + int z; ++ unsigned long nr_reclaimed = sc->nr_reclaimed; + + /* Reclaim a number of pages proportional to the number of zones */ + sc->nr_to_reclaim = 0; +@@ -7378,7 +7375,8 @@ static bool kswapd_shrink_node(pg_data_t *pgdat, + if (sc->order && sc->nr_reclaimed >= compact_gap(sc->order)) + sc->order = 0; + +- return sc->nr_scanned >= sc->nr_to_reclaim; ++ /* account for progress from mm_account_reclaimed_pages() */ ++ return max(sc->nr_scanned, sc->nr_reclaimed - nr_reclaimed) >= sc->nr_to_reclaim; + } + + /* Page allocator PCP high watermark is lowered if reclaim is active. */ +diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c +index d97064d460dc7..e19b583ff2c6d 100644 +--- a/net/bridge/br_forward.c ++++ b/net/bridge/br_forward.c +@@ -25,8 +25,8 @@ static inline int should_deliver(const struct net_bridge_port *p, + + vg = nbp_vlan_group_rcu(p); + return ((p->flags & BR_HAIRPIN_MODE) || skb->dev != p->dev) && +- p->state == BR_STATE_FORWARDING && br_allowed_egress(vg, skb) && +- nbp_switchdev_allowed_egress(p, skb) && ++ (br_mst_is_enabled(p->br) || p->state == BR_STATE_FORWARDING) && ++ br_allowed_egress(vg, skb) && nbp_switchdev_allowed_egress(p, skb) && + !br_skb_isolated(p, skb); + } + +diff --git a/net/core/filter.c b/net/core/filter.c +index afe38b8dee024..8cb44cd29967b 100644 +--- a/net/core/filter.c ++++ b/net/core/filter.c +@@ -3530,13 +3530,20 @@ static int bpf_skb_net_grow(struct sk_buff *skb, u32 off, u32 len_diff, + if (skb_is_gso(skb)) { + struct skb_shared_info *shinfo = skb_shinfo(skb); + +- /* Due to header grow, MSS needs to be downgraded. */ +- if (!(flags & BPF_F_ADJ_ROOM_FIXED_GSO)) +- skb_decrease_gso_size(shinfo, len_diff); +- + /* Header must be checked, and gso_segs recomputed. */ + shinfo->gso_type |= gso_type; + shinfo->gso_segs = 0; ++ ++ /* Due to header growth, MSS needs to be downgraded. ++ * There is a BUG_ON() when segmenting the frag_list with ++ * head_frag true, so linearize the skb after downgrading ++ * the MSS. ++ */ ++ if (!(flags & BPF_F_ADJ_ROOM_FIXED_GSO)) { ++ skb_decrease_gso_size(shinfo, len_diff); ++ if (shinfo->frag_list) ++ return skb_linearize(skb); ++ } + } + + return 0; +diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c +index 272f09251343d..b22d20cc417b2 100644 +--- a/net/core/flow_dissector.c ++++ b/net/core/flow_dissector.c +@@ -1093,7 +1093,7 @@ bool __skb_flow_dissect(const struct net *net, + } + } + +- WARN_ON_ONCE(!net); ++ DEBUG_NET_WARN_ON_ONCE(!net); + if (net) { + enum netns_bpf_attach_type type = NETNS_BPF_FLOW_DISSECTOR; + struct bpf_prog_array *run_array; +diff --git a/net/core/xdp.c b/net/core/xdp.c +index 5fe4c099f30a3..5ee3f8f165e5a 100644 +--- a/net/core/xdp.c ++++ b/net/core/xdp.c +@@ -126,10 +126,8 @@ void xdp_unreg_mem_model(struct xdp_mem_info *mem) + return; + + if (type == MEM_TYPE_PAGE_POOL) { +- rcu_read_lock(); +- xa = rhashtable_lookup(mem_id_ht, &id, mem_id_rht_params); ++ xa = rhashtable_lookup_fast(mem_id_ht, &id, mem_id_rht_params); + page_pool_destroy(xa->page_pool); +- rcu_read_unlock(); + } + } + EXPORT_SYMBOL_GPL(xdp_unreg_mem_model); +diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c +index fe501d2186bcf..eeace9b509cec 100644 +--- a/net/ipv4/esp4.c ++++ b/net/ipv4/esp4.c +@@ -238,8 +238,7 @@ static int esp_output_tail_tcp(struct xfrm_state *x, struct sk_buff *skb) + #else + static int esp_output_tail_tcp(struct xfrm_state *x, struct sk_buff *skb) + { +- kfree_skb(skb); +- ++ WARN_ON(1); + return -EOPNOTSUPP; + } + #endif +diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c +index 5eb1b8d302bbd..e3268615a65a1 100644 +--- a/net/ipv4/fib_semantics.c ++++ b/net/ipv4/fib_semantics.c +@@ -2270,6 +2270,15 @@ void fib_select_path(struct net *net, struct fib_result *res, + fib_select_default(fl4, res); + + check_saddr: +- if (!fl4->saddr) +- fl4->saddr = fib_result_prefsrc(net, res); ++ if (!fl4->saddr) { ++ struct net_device *l3mdev; ++ ++ l3mdev = dev_get_by_index_rcu(net, fl4->flowi4_l3mdev); ++ ++ if (!l3mdev || ++ l3mdev_master_dev_rcu(FIB_RES_DEV(*res)) == l3mdev) ++ fl4->saddr = fib_result_prefsrc(net, res); ++ else ++ fl4->saddr = inet_select_addr(l3mdev, 0, RT_SCOPE_LINK); ++ } + } +diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c +index 9bdfdab906fe0..77b97c48da5ea 100644 +--- a/net/ipv4/fib_trie.c ++++ b/net/ipv4/fib_trie.c +@@ -1628,6 +1628,7 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp, + res->nhc = nhc; + res->type = fa->fa_type; + res->scope = fi->fib_scope; ++ res->dscp = fa->fa_dscp; + res->fi = fi; + res->table = tb; + res->fa_head = &n->leaf; +diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c +index bbff68b5b5d4a..8d41b03942197 100644 +--- a/net/ipv4/nexthop.c ++++ b/net/ipv4/nexthop.c +@@ -676,9 +676,10 @@ static int nla_put_nh_group(struct sk_buff *skb, struct nh_group *nhg) + + p = nla_data(nla); + for (i = 0; i < nhg->num_nh; ++i) { +- p->id = nhg->nh_entries[i].nh->id; +- p->weight = nhg->nh_entries[i].weight - 1; +- p += 1; ++ *p++ = (struct nexthop_grp) { ++ .id = nhg->nh_entries[i].nh->id, ++ .weight = nhg->nh_entries[i].weight - 1, ++ }; + } + + if (nhg->resilient && nla_put_nh_group_res(skb, nhg)) +diff --git a/net/ipv4/route.c b/net/ipv4/route.c +index 40b9c579c917e..285482060082f 100644 +--- a/net/ipv4/route.c ++++ b/net/ipv4/route.c +@@ -1275,7 +1275,7 @@ void ip_rt_get_source(u8 *addr, struct sk_buff *skb, struct rtable *rt) + struct flowi4 fl4 = { + .daddr = iph->daddr, + .saddr = iph->saddr, +- .flowi4_tos = RT_TOS(iph->tos), ++ .flowi4_tos = iph->tos & IPTOS_RT_MASK, + .flowi4_oif = rt->dst.dev->ifindex, + .flowi4_iif = skb->dev->ifindex, + .flowi4_mark = skb->mark, +@@ -2930,9 +2930,9 @@ EXPORT_SYMBOL_GPL(ip_route_output_tunnel); + + /* called with rcu_read_lock held */ + static int rt_fill_info(struct net *net, __be32 dst, __be32 src, +- struct rtable *rt, u32 table_id, struct flowi4 *fl4, +- struct sk_buff *skb, u32 portid, u32 seq, +- unsigned int flags) ++ struct rtable *rt, u32 table_id, dscp_t dscp, ++ struct flowi4 *fl4, struct sk_buff *skb, u32 portid, ++ u32 seq, unsigned int flags) + { + struct rtmsg *r; + struct nlmsghdr *nlh; +@@ -2948,7 +2948,7 @@ static int rt_fill_info(struct net *net, __be32 dst, __be32 src, + r->rtm_family = AF_INET; + r->rtm_dst_len = 32; + r->rtm_src_len = 0; +- r->rtm_tos = fl4 ? fl4->flowi4_tos : 0; ++ r->rtm_tos = inet_dscp_to_dsfield(dscp); + r->rtm_table = table_id < 256 ? table_id : RT_TABLE_COMPAT; + if (nla_put_u32(skb, RTA_TABLE, table_id)) + goto nla_put_failure; +@@ -3098,7 +3098,7 @@ static int fnhe_dump_bucket(struct net *net, struct sk_buff *skb, + goto next; + + err = rt_fill_info(net, fnhe->fnhe_daddr, 0, rt, +- table_id, NULL, skb, ++ table_id, 0, NULL, skb, + NETLINK_CB(cb->skb).portid, + cb->nlh->nlmsg_seq, flags); + if (err) +@@ -3394,7 +3394,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, + fri.tb_id = table_id; + fri.dst = res.prefix; + fri.dst_len = res.prefixlen; +- fri.dscp = inet_dsfield_to_dscp(fl4.flowi4_tos); ++ fri.dscp = res.dscp; + fri.type = rt->rt_type; + fri.offload = 0; + fri.trap = 0; +@@ -3421,8 +3421,8 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, + err = fib_dump_info(skb, NETLINK_CB(in_skb).portid, + nlh->nlmsg_seq, RTM_NEWROUTE, &fri, 0); + } else { +- err = rt_fill_info(net, dst, src, rt, table_id, &fl4, skb, +- NETLINK_CB(in_skb).portid, ++ err = rt_fill_info(net, dst, src, rt, table_id, res.dscp, &fl4, ++ skb, NETLINK_CB(in_skb).portid, + nlh->nlmsg_seq, 0); + } + if (err < 0) +diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c +index 2df05ea2e00fe..91c3d8264059d 100644 +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -591,7 +591,7 @@ __poll_t tcp_poll(struct file *file, struct socket *sock, poll_table *wait) + */ + mask |= EPOLLOUT | EPOLLWRNORM; + } +- /* This barrier is coupled with smp_wmb() in tcp_reset() */ ++ /* This barrier is coupled with smp_wmb() in tcp_done_with_error() */ + smp_rmb(); + if (READ_ONCE(sk->sk_err) || + !skb_queue_empty_lockless(&sk->sk_error_queue)) +diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c +index b9133c0972d38..c2e4dac42453b 100644 +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -4367,9 +4367,26 @@ static enum skb_drop_reason tcp_sequence(const struct tcp_sock *tp, + return SKB_NOT_DROPPED_YET; + } + ++ ++void tcp_done_with_error(struct sock *sk, int err) ++{ ++ /* This barrier is coupled with smp_rmb() in tcp_poll() */ ++ WRITE_ONCE(sk->sk_err, err); ++ smp_wmb(); ++ ++ tcp_write_queue_purge(sk); ++ tcp_done(sk); ++ ++ if (!sock_flag(sk, SOCK_DEAD)) ++ sk_error_report(sk); ++} ++EXPORT_SYMBOL(tcp_done_with_error); ++ + /* When we get a reset we do this. */ + void tcp_reset(struct sock *sk, struct sk_buff *skb) + { ++ int err; ++ + trace_tcp_receive_reset(sk); + + /* mptcp can't tell us to ignore reset pkts, +@@ -4381,24 +4398,17 @@ void tcp_reset(struct sock *sk, struct sk_buff *skb) + /* We want the right error as BSD sees it (and indeed as we do). */ + switch (sk->sk_state) { + case TCP_SYN_SENT: +- WRITE_ONCE(sk->sk_err, ECONNREFUSED); ++ err = ECONNREFUSED; + break; + case TCP_CLOSE_WAIT: +- WRITE_ONCE(sk->sk_err, EPIPE); ++ err = EPIPE; + break; + case TCP_CLOSE: + return; + default: +- WRITE_ONCE(sk->sk_err, ECONNRESET); ++ err = ECONNRESET; + } +- /* This barrier is coupled with smp_rmb() in tcp_poll() */ +- smp_wmb(); +- +- tcp_write_queue_purge(sk); +- tcp_done(sk); +- +- if (!sock_flag(sk, SOCK_DEAD)) +- sk_error_report(sk); ++ tcp_done_with_error(sk, err); + } + + /* +diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c +index 7c2ca4df0daa3..48ec2c1777d45 100644 +--- a/net/ipv4/tcp_ipv4.c ++++ b/net/ipv4/tcp_ipv4.c +@@ -602,15 +602,10 @@ int tcp_v4_err(struct sk_buff *skb, u32 info) + + ip_icmp_error(sk, skb, err, th->dest, info, (u8 *)th); + +- if (!sock_owned_by_user(sk)) { +- WRITE_ONCE(sk->sk_err, err); +- +- sk_error_report(sk); +- +- tcp_done(sk); +- } else { ++ if (!sock_owned_by_user(sk)) ++ tcp_done_with_error(sk, err); ++ else + WRITE_ONCE(sk->sk_err_soft, err); +- } + goto out; + } + +diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c +index 87ebe958a642f..64bcf384e9ddc 100644 +--- a/net/ipv4/tcp_timer.c ++++ b/net/ipv4/tcp_timer.c +@@ -69,11 +69,7 @@ u32 tcp_clamp_probe0_to_user_timeout(const struct sock *sk, u32 when) + + static void tcp_write_err(struct sock *sk) + { +- WRITE_ONCE(sk->sk_err, READ_ONCE(sk->sk_err_soft) ? : ETIMEDOUT); +- sk_error_report(sk); +- +- tcp_write_queue_purge(sk); +- tcp_done(sk); ++ tcp_done_with_error(sk, READ_ONCE(sk->sk_err_soft) ? : ETIMEDOUT); + __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONTIMEOUT); + } + +diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c +index 9dfbda164e8c1..a9358c796a815 100644 +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -1839,7 +1839,8 @@ int ipv6_dev_get_saddr(struct net *net, const struct net_device *dst_dev, + master, &dst, + scores, hiscore_idx); + +- if (scores[hiscore_idx].ifa) ++ if (scores[hiscore_idx].ifa && ++ scores[hiscore_idx].scopedist >= 0) + goto out; + } + +diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c +index a3fa3eda388a4..62bb9651133c4 100644 +--- a/net/ipv6/esp6.c ++++ b/net/ipv6/esp6.c +@@ -255,8 +255,7 @@ static int esp_output_tail_tcp(struct xfrm_state *x, struct sk_buff *skb) + #else + static int esp_output_tail_tcp(struct xfrm_state *x, struct sk_buff *skb) + { +- kfree_skb(skb); +- ++ WARN_ON(1); + return -EOPNOTSUPP; + } + #endif +diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c +index 07bcb690932e1..d0034916d386b 100644 +--- a/net/ipv6/tcp_ipv6.c ++++ b/net/ipv6/tcp_ipv6.c +@@ -488,14 +488,10 @@ static int tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, + + ipv6_icmp_error(sk, skb, err, th->dest, ntohl(info), (u8 *)th); + +- if (!sock_owned_by_user(sk)) { +- WRITE_ONCE(sk->sk_err, err); +- sk_error_report(sk); /* Wake people up to see the error (see connect in sock.c) */ +- +- tcp_done(sk); +- } else { ++ if (!sock_owned_by_user(sk)) ++ tcp_done_with_error(sk, err); ++ else + WRITE_ONCE(sk->sk_err_soft, err); +- } + goto out; + case TCP_LISTEN: + break; +diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c +index f3fc0be9d8eac..ca5b111f20e5b 100644 +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -1887,7 +1887,7 @@ static int sta_link_apply_parameters(struct ieee80211_local *local, + sband->band); + } + +- ieee80211_sta_set_rx_nss(link_sta); ++ ieee80211_sta_init_nss(link_sta); + + return ret; + } +diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h +index fb55014c0e898..daea061d0fc13 100644 +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -2150,7 +2150,7 @@ enum ieee80211_sta_rx_bandwidth + ieee80211_sta_cap_rx_bw(struct link_sta_info *link_sta); + enum ieee80211_sta_rx_bandwidth + ieee80211_sta_cur_vht_bw(struct link_sta_info *link_sta); +-void ieee80211_sta_set_rx_nss(struct link_sta_info *link_sta); ++void ieee80211_sta_init_nss(struct link_sta_info *link_sta); + enum ieee80211_sta_rx_bandwidth + ieee80211_chan_width_to_rx_bw(enum nl80211_chan_width width); + enum nl80211_chan_width +diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c +index a2bc9c5d92b8b..3cf252418bd38 100644 +--- a/net/mac80211/rate.c ++++ b/net/mac80211/rate.c +@@ -37,7 +37,7 @@ void rate_control_rate_init(struct sta_info *sta) + struct ieee80211_supported_band *sband; + struct ieee80211_chanctx_conf *chanctx_conf; + +- ieee80211_sta_set_rx_nss(&sta->deflink); ++ ieee80211_sta_init_nss(&sta->deflink); + + if (!ref) + return; +diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h +index 195b563132d6c..f4af851f45ceb 100644 +--- a/net/mac80211/sta_info.h ++++ b/net/mac80211/sta_info.h +@@ -3,7 +3,7 @@ + * Copyright 2002-2005, Devicescape Software, Inc. + * Copyright 2013-2014 Intel Mobile Communications GmbH + * Copyright(c) 2015-2017 Intel Deutschland GmbH +- * Copyright(c) 2020-2022 Intel Corporation ++ * Copyright(c) 2020-2024 Intel Corporation + */ + + #ifndef STA_INFO_H +@@ -485,6 +485,8 @@ struct ieee80211_fragment_cache { + * same for non-MLD STA. This is used as key for searching link STA + * @link_id: Link ID uniquely identifying the link STA. This is 0 for non-MLD + * and set to the corresponding vif LinkId for MLD STA ++ * @op_mode_nss: NSS limit as set by operating mode notification, or 0 ++ * @capa_nss: NSS limit as determined by local and peer capabilities + * @link_hash_node: hash node for rhashtable + * @sta: Points to the STA info + * @gtk: group keys negotiated with this station, if any +@@ -521,6 +523,8 @@ struct link_sta_info { + u8 addr[ETH_ALEN]; + u8 link_id; + ++ u8 op_mode_nss, capa_nss; ++ + struct rhlist_head link_hash_node; + + struct sta_info *sta; +diff --git a/net/mac80211/vht.c b/net/mac80211/vht.c +index b3a5c3e96a720..bc13b1419981a 100644 +--- a/net/mac80211/vht.c ++++ b/net/mac80211/vht.c +@@ -4,7 +4,7 @@ + * + * Portions of this file + * Copyright(c) 2015 - 2016 Intel Deutschland GmbH +- * Copyright (C) 2018 - 2023 Intel Corporation ++ * Copyright (C) 2018 - 2024 Intel Corporation + */ + + #include <linux/ieee80211.h> +@@ -541,15 +541,11 @@ ieee80211_sta_cur_vht_bw(struct link_sta_info *link_sta) + return bw; + } + +-void ieee80211_sta_set_rx_nss(struct link_sta_info *link_sta) ++void ieee80211_sta_init_nss(struct link_sta_info *link_sta) + { + u8 ht_rx_nss = 0, vht_rx_nss = 0, he_rx_nss = 0, eht_rx_nss = 0, rx_nss; + bool support_160; + +- /* if we received a notification already don't overwrite it */ +- if (link_sta->pub->rx_nss) +- return; +- + if (link_sta->pub->eht_cap.has_eht) { + int i; + const u8 *rx_nss_mcs = (void *)&link_sta->pub->eht_cap.eht_mcs_nss_supp; +@@ -627,7 +623,15 @@ void ieee80211_sta_set_rx_nss(struct link_sta_info *link_sta) + rx_nss = max(vht_rx_nss, ht_rx_nss); + rx_nss = max(he_rx_nss, rx_nss); + rx_nss = max(eht_rx_nss, rx_nss); +- link_sta->pub->rx_nss = max_t(u8, 1, rx_nss); ++ rx_nss = max_t(u8, 1, rx_nss); ++ link_sta->capa_nss = rx_nss; ++ ++ /* that shouldn't be set yet, but we can handle it anyway */ ++ if (link_sta->op_mode_nss) ++ link_sta->pub->rx_nss = ++ min_t(u8, rx_nss, link_sta->op_mode_nss); ++ else ++ link_sta->pub->rx_nss = rx_nss; + } + + u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, +@@ -637,7 +641,7 @@ u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, + enum ieee80211_sta_rx_bandwidth new_bw; + struct sta_opmode_info sta_opmode = {}; + u32 changed = 0; +- u8 nss, cur_nss; ++ u8 nss; + + /* ignore - no support for BF yet */ + if (opmode & IEEE80211_OPMODE_NOTIF_RX_NSS_TYPE_BF) +@@ -647,23 +651,17 @@ u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, + nss >>= IEEE80211_OPMODE_NOTIF_RX_NSS_SHIFT; + nss += 1; + +- if (link_sta->pub->rx_nss != nss) { +- cur_nss = link_sta->pub->rx_nss; +- /* Reset rx_nss and call ieee80211_sta_set_rx_nss() which +- * will set the same to max nss value calculated based on capability. +- */ +- link_sta->pub->rx_nss = 0; +- ieee80211_sta_set_rx_nss(link_sta); +- /* Do not allow an nss change to rx_nss greater than max_nss +- * negotiated and capped to APs capability during association. +- */ +- if (nss <= link_sta->pub->rx_nss) { +- link_sta->pub->rx_nss = nss; +- sta_opmode.rx_nss = nss; +- changed |= IEEE80211_RC_NSS_CHANGED; +- sta_opmode.changed |= STA_OPMODE_N_SS_CHANGED; ++ if (link_sta->op_mode_nss != nss) { ++ if (nss <= link_sta->capa_nss) { ++ link_sta->op_mode_nss = nss; ++ ++ if (nss != link_sta->pub->rx_nss) { ++ link_sta->pub->rx_nss = nss; ++ changed |= IEEE80211_RC_NSS_CHANGED; ++ sta_opmode.rx_nss = link_sta->pub->rx_nss; ++ sta_opmode.changed |= STA_OPMODE_N_SS_CHANGED; ++ } + } else { +- link_sta->pub->rx_nss = cur_nss; + pr_warn_ratelimited("Ignoring NSS change in VHT Operating Mode Notification from %pM with invalid nss %d", + link_sta->pub->addr, nss); + } +diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c +index 143a341bbc0a4..dec5309d9f1f5 100644 +--- a/net/netfilter/ipvs/ip_vs_ctl.c ++++ b/net/netfilter/ipvs/ip_vs_ctl.c +@@ -1459,18 +1459,18 @@ ip_vs_add_service(struct netns_ipvs *ipvs, struct ip_vs_service_user_kern *u, + if (ret < 0) + goto out_err; + +- /* Bind the ct retriever */ +- RCU_INIT_POINTER(svc->pe, pe); +- pe = NULL; +- + /* Update the virtual service counters */ + if (svc->port == FTPPORT) + atomic_inc(&ipvs->ftpsvc_counter); + else if (svc->port == 0) + atomic_inc(&ipvs->nullsvc_counter); +- if (svc->pe && svc->pe->conn_out) ++ if (pe && pe->conn_out) + atomic_inc(&ipvs->conn_out_counter); + ++ /* Bind the ct retriever */ ++ RCU_INIT_POINTER(svc->pe, pe); ++ pe = NULL; ++ + /* Count only IPv4 services for old get/setsockopt interface */ + if (svc->af == AF_INET) + ipvs->num_services++; +diff --git a/net/netfilter/ipvs/ip_vs_proto_sctp.c b/net/netfilter/ipvs/ip_vs_proto_sctp.c +index 1e689c7141271..83e452916403d 100644 +--- a/net/netfilter/ipvs/ip_vs_proto_sctp.c ++++ b/net/netfilter/ipvs/ip_vs_proto_sctp.c +@@ -126,7 +126,7 @@ sctp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp, + if (sctph->source != cp->vport || payload_csum || + skb->ip_summed == CHECKSUM_PARTIAL) { + sctph->source = cp->vport; +- if (!skb_is_gso(skb) || !skb_is_gso_sctp(skb)) ++ if (!skb_is_gso(skb)) + sctp_nat_csum(skb, sctph, sctphoff); + } else { + skb->ip_summed = CHECKSUM_UNNECESSARY; +@@ -175,7 +175,7 @@ sctp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp, + (skb->ip_summed == CHECKSUM_PARTIAL && + !(skb_dst(skb)->dev->features & NETIF_F_SCTP_CRC))) { + sctph->dest = cp->dport; +- if (!skb_is_gso(skb) || !skb_is_gso_sctp(skb)) ++ if (!skb_is_gso(skb)) + sctp_nat_csum(skb, sctph, sctphoff); + } else if (skb->ip_summed != CHECKSUM_PARTIAL) { + skb->ip_summed = CHECKSUM_UNNECESSARY; +diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c +index 334db22199c1d..4dab45039f349 100644 +--- a/net/netfilter/nf_conntrack_netlink.c ++++ b/net/netfilter/nf_conntrack_netlink.c +@@ -3411,7 +3411,8 @@ static int ctnetlink_del_expect(struct sk_buff *skb, + + if (cda[CTA_EXPECT_ID]) { + __be32 id = nla_get_be32(cda[CTA_EXPECT_ID]); +- if (ntohl(id) != (u32)(unsigned long)exp) { ++ ++ if (id != nf_expect_get_id(exp)) { + nf_ct_expect_put(exp); + return -ENOENT; + } +diff --git a/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c +index 69b02a3f1ff05..e4dd730930484 100644 +--- a/net/netfilter/nft_set_pipapo.c ++++ b/net/netfilter/nft_set_pipapo.c +@@ -360,7 +360,7 @@ + * Return: -1 on no match, bit position on 'match_only', 0 otherwise. + */ + int pipapo_refill(unsigned long *map, int len, int rules, unsigned long *dst, +- union nft_pipapo_map_bucket *mt, bool match_only) ++ const union nft_pipapo_map_bucket *mt, bool match_only) + { + unsigned long bitset; + int k, ret = -1; +@@ -412,9 +412,9 @@ bool nft_pipapo_lookup(const struct net *net, const struct nft_set *set, + struct nft_pipapo_scratch *scratch; + unsigned long *res_map, *fill_map; + u8 genmask = nft_genmask_cur(net); ++ const struct nft_pipapo_match *m; ++ const struct nft_pipapo_field *f; + const u8 *rp = (const u8 *)key; +- struct nft_pipapo_match *m; +- struct nft_pipapo_field *f; + bool map_index; + int i; + +@@ -432,7 +432,7 @@ bool nft_pipapo_lookup(const struct net *net, const struct nft_set *set, + res_map = scratch->map + (map_index ? m->bsize_max : 0); + fill_map = scratch->map + (map_index ? 0 : m->bsize_max); + +- memset(res_map, 0xff, m->bsize_max * sizeof(*res_map)); ++ pipapo_resmap_init(m, res_map); + + nft_pipapo_for_each_field(f, i, m) { + bool last = i == m->field_count - 1; +@@ -517,11 +517,13 @@ static struct nft_pipapo_elem *pipapo_get(const struct net *net, + { + struct nft_pipapo_elem *ret = ERR_PTR(-ENOENT); + struct nft_pipapo *priv = nft_set_priv(set); +- struct nft_pipapo_match *m = priv->clone; + unsigned long *res_map, *fill_map = NULL; +- struct nft_pipapo_field *f; ++ const struct nft_pipapo_match *m; ++ const struct nft_pipapo_field *f; + int i; + ++ m = priv->clone; ++ + res_map = kmalloc_array(m->bsize_max, sizeof(*res_map), GFP_ATOMIC); + if (!res_map) { + ret = ERR_PTR(-ENOMEM); +@@ -534,7 +536,7 @@ static struct nft_pipapo_elem *pipapo_get(const struct net *net, + goto out; + } + +- memset(res_map, 0xff, m->bsize_max * sizeof(*res_map)); ++ pipapo_resmap_init(m, res_map); + + nft_pipapo_for_each_field(f, i, m) { + bool last = i == m->field_count - 1; +@@ -1590,7 +1592,7 @@ static void pipapo_gc(const struct nft_set *_set, struct nft_pipapo_match *m) + + while ((rules_f0 = pipapo_rules_same_key(m->f, first_rule))) { + union nft_pipapo_map_bucket rulemap[NFT_PIPAPO_MAX_FIELDS]; +- struct nft_pipapo_field *f; ++ const struct nft_pipapo_field *f; + int i, start, rules_fx; + + start = first_rule; +@@ -2036,8 +2038,8 @@ static void nft_pipapo_walk(const struct nft_ctx *ctx, struct nft_set *set, + { + struct nft_pipapo *priv = nft_set_priv(set); + struct net *net = read_pnet(&set->net); +- struct nft_pipapo_match *m; +- struct nft_pipapo_field *f; ++ const struct nft_pipapo_match *m; ++ const struct nft_pipapo_field *f; + int i, r; + + rcu_read_lock(); +diff --git a/net/netfilter/nft_set_pipapo.h b/net/netfilter/nft_set_pipapo.h +index a4a58812c1088..aad9130cc7635 100644 +--- a/net/netfilter/nft_set_pipapo.h ++++ b/net/netfilter/nft_set_pipapo.h +@@ -185,7 +185,7 @@ struct nft_pipapo_elem { + }; + + int pipapo_refill(unsigned long *map, int len, int rules, unsigned long *dst, +- union nft_pipapo_map_bucket *mt, bool match_only); ++ const union nft_pipapo_map_bucket *mt, bool match_only); + + /** + * pipapo_and_field_buckets_4bit() - Intersect 4-bit buckets +@@ -193,7 +193,7 @@ int pipapo_refill(unsigned long *map, int len, int rules, unsigned long *dst, + * @dst: Area to store result + * @data: Input data selecting table buckets + */ +-static inline void pipapo_and_field_buckets_4bit(struct nft_pipapo_field *f, ++static inline void pipapo_and_field_buckets_4bit(const struct nft_pipapo_field *f, + unsigned long *dst, + const u8 *data) + { +@@ -221,7 +221,7 @@ static inline void pipapo_and_field_buckets_4bit(struct nft_pipapo_field *f, + * @dst: Area to store result + * @data: Input data selecting table buckets + */ +-static inline void pipapo_and_field_buckets_8bit(struct nft_pipapo_field *f, ++static inline void pipapo_and_field_buckets_8bit(const struct nft_pipapo_field *f, + unsigned long *dst, + const u8 *data) + { +@@ -285,4 +285,25 @@ static u64 pipapo_estimate_size(const struct nft_set_desc *desc) + return size; + } + ++/** ++ * pipapo_resmap_init() - Initialise result map before first use ++ * @m: Matching data, including mapping table ++ * @res_map: Result map ++ * ++ * Initialize all bits covered by the first field to one, so that after ++ * the first step, only the matching bits of the first bit group remain. ++ * ++ * If other fields have a large bitmap, set remainder of res_map to 0. ++ */ ++static inline void pipapo_resmap_init(const struct nft_pipapo_match *m, unsigned long *res_map) ++{ ++ const struct nft_pipapo_field *f = m->f; ++ int i; ++ ++ for (i = 0; i < f->bsize; i++) ++ res_map[i] = ULONG_MAX; ++ ++ for (i = f->bsize; i < m->bsize_max; i++) ++ res_map[i] = 0ul; ++} + #endif /* _NFT_SET_PIPAPO_H */ +diff --git a/net/netfilter/nft_set_pipapo_avx2.c b/net/netfilter/nft_set_pipapo_avx2.c +index a3a8ddca99189..b8d3c3213efee 100644 +--- a/net/netfilter/nft_set_pipapo_avx2.c ++++ b/net/netfilter/nft_set_pipapo_avx2.c +@@ -212,8 +212,9 @@ static int nft_pipapo_avx2_refill(int offset, unsigned long *map, + * word index to be checked next (i.e. first filled word). + */ + static int nft_pipapo_avx2_lookup_4b_2(unsigned long *map, unsigned long *fill, +- struct nft_pipapo_field *f, int offset, +- const u8 *pkt, bool first, bool last) ++ const struct nft_pipapo_field *f, ++ int offset, const u8 *pkt, ++ bool first, bool last) + { + int i, ret = -1, m256_size = f->bsize / NFT_PIPAPO_LONGS_PER_M256, b; + u8 pg[2] = { pkt[0] >> 4, pkt[0] & 0xf }; +@@ -274,8 +275,9 @@ static int nft_pipapo_avx2_lookup_4b_2(unsigned long *map, unsigned long *fill, + * word index to be checked next (i.e. first filled word). + */ + static int nft_pipapo_avx2_lookup_4b_4(unsigned long *map, unsigned long *fill, +- struct nft_pipapo_field *f, int offset, +- const u8 *pkt, bool first, bool last) ++ const struct nft_pipapo_field *f, ++ int offset, const u8 *pkt, ++ bool first, bool last) + { + int i, ret = -1, m256_size = f->bsize / NFT_PIPAPO_LONGS_PER_M256, b; + u8 pg[4] = { pkt[0] >> 4, pkt[0] & 0xf, pkt[1] >> 4, pkt[1] & 0xf }; +@@ -350,8 +352,9 @@ static int nft_pipapo_avx2_lookup_4b_4(unsigned long *map, unsigned long *fill, + * word index to be checked next (i.e. first filled word). + */ + static int nft_pipapo_avx2_lookup_4b_8(unsigned long *map, unsigned long *fill, +- struct nft_pipapo_field *f, int offset, +- const u8 *pkt, bool first, bool last) ++ const struct nft_pipapo_field *f, ++ int offset, const u8 *pkt, ++ bool first, bool last) + { + u8 pg[8] = { pkt[0] >> 4, pkt[0] & 0xf, pkt[1] >> 4, pkt[1] & 0xf, + pkt[2] >> 4, pkt[2] & 0xf, pkt[3] >> 4, pkt[3] & 0xf, +@@ -445,8 +448,9 @@ static int nft_pipapo_avx2_lookup_4b_8(unsigned long *map, unsigned long *fill, + * word index to be checked next (i.e. first filled word). + */ + static int nft_pipapo_avx2_lookup_4b_12(unsigned long *map, unsigned long *fill, +- struct nft_pipapo_field *f, int offset, +- const u8 *pkt, bool first, bool last) ++ const struct nft_pipapo_field *f, ++ int offset, const u8 *pkt, ++ bool first, bool last) + { + u8 pg[12] = { pkt[0] >> 4, pkt[0] & 0xf, pkt[1] >> 4, pkt[1] & 0xf, + pkt[2] >> 4, pkt[2] & 0xf, pkt[3] >> 4, pkt[3] & 0xf, +@@ -534,8 +538,9 @@ static int nft_pipapo_avx2_lookup_4b_12(unsigned long *map, unsigned long *fill, + * word index to be checked next (i.e. first filled word). + */ + static int nft_pipapo_avx2_lookup_4b_32(unsigned long *map, unsigned long *fill, +- struct nft_pipapo_field *f, int offset, +- const u8 *pkt, bool first, bool last) ++ const struct nft_pipapo_field *f, ++ int offset, const u8 *pkt, ++ bool first, bool last) + { + u8 pg[32] = { pkt[0] >> 4, pkt[0] & 0xf, pkt[1] >> 4, pkt[1] & 0xf, + pkt[2] >> 4, pkt[2] & 0xf, pkt[3] >> 4, pkt[3] & 0xf, +@@ -669,8 +674,9 @@ static int nft_pipapo_avx2_lookup_4b_32(unsigned long *map, unsigned long *fill, + * word index to be checked next (i.e. first filled word). + */ + static int nft_pipapo_avx2_lookup_8b_1(unsigned long *map, unsigned long *fill, +- struct nft_pipapo_field *f, int offset, +- const u8 *pkt, bool first, bool last) ++ const struct nft_pipapo_field *f, ++ int offset, const u8 *pkt, ++ bool first, bool last) + { + int i, ret = -1, m256_size = f->bsize / NFT_PIPAPO_LONGS_PER_M256, b; + unsigned long *lt = f->lt, bsize = f->bsize; +@@ -726,8 +732,9 @@ static int nft_pipapo_avx2_lookup_8b_1(unsigned long *map, unsigned long *fill, + * word index to be checked next (i.e. first filled word). + */ + static int nft_pipapo_avx2_lookup_8b_2(unsigned long *map, unsigned long *fill, +- struct nft_pipapo_field *f, int offset, +- const u8 *pkt, bool first, bool last) ++ const struct nft_pipapo_field *f, ++ int offset, const u8 *pkt, ++ bool first, bool last) + { + int i, ret = -1, m256_size = f->bsize / NFT_PIPAPO_LONGS_PER_M256, b; + unsigned long *lt = f->lt, bsize = f->bsize; +@@ -790,8 +797,9 @@ static int nft_pipapo_avx2_lookup_8b_2(unsigned long *map, unsigned long *fill, + * word index to be checked next (i.e. first filled word). + */ + static int nft_pipapo_avx2_lookup_8b_4(unsigned long *map, unsigned long *fill, +- struct nft_pipapo_field *f, int offset, +- const u8 *pkt, bool first, bool last) ++ const struct nft_pipapo_field *f, ++ int offset, const u8 *pkt, ++ bool first, bool last) + { + int i, ret = -1, m256_size = f->bsize / NFT_PIPAPO_LONGS_PER_M256, b; + unsigned long *lt = f->lt, bsize = f->bsize; +@@ -865,8 +873,9 @@ static int nft_pipapo_avx2_lookup_8b_4(unsigned long *map, unsigned long *fill, + * word index to be checked next (i.e. first filled word). + */ + static int nft_pipapo_avx2_lookup_8b_6(unsigned long *map, unsigned long *fill, +- struct nft_pipapo_field *f, int offset, +- const u8 *pkt, bool first, bool last) ++ const struct nft_pipapo_field *f, ++ int offset, const u8 *pkt, ++ bool first, bool last) + { + int i, ret = -1, m256_size = f->bsize / NFT_PIPAPO_LONGS_PER_M256, b; + unsigned long *lt = f->lt, bsize = f->bsize; +@@ -950,8 +959,9 @@ static int nft_pipapo_avx2_lookup_8b_6(unsigned long *map, unsigned long *fill, + * word index to be checked next (i.e. first filled word). + */ + static int nft_pipapo_avx2_lookup_8b_16(unsigned long *map, unsigned long *fill, +- struct nft_pipapo_field *f, int offset, +- const u8 *pkt, bool first, bool last) ++ const struct nft_pipapo_field *f, ++ int offset, const u8 *pkt, ++ bool first, bool last) + { + int i, ret = -1, m256_size = f->bsize / NFT_PIPAPO_LONGS_PER_M256, b; + unsigned long *lt = f->lt, bsize = f->bsize; +@@ -1026,6 +1036,7 @@ static int nft_pipapo_avx2_lookup_8b_16(unsigned long *map, unsigned long *fill, + + /** + * nft_pipapo_avx2_lookup_slow() - Fallback function for uncommon field sizes ++ * @mdata: Matching data, including mapping table + * @map: Previous match result, used as initial bitmap + * @fill: Destination bitmap to be filled with current match result + * @f: Field, containing lookup and mapping tables +@@ -1041,15 +1052,17 @@ static int nft_pipapo_avx2_lookup_8b_16(unsigned long *map, unsigned long *fill, + * Return: -1 on no match, rule index of match if @last, otherwise first long + * word index to be checked next (i.e. first filled word). + */ +-static int nft_pipapo_avx2_lookup_slow(unsigned long *map, unsigned long *fill, +- struct nft_pipapo_field *f, int offset, +- const u8 *pkt, bool first, bool last) ++static int nft_pipapo_avx2_lookup_slow(const struct nft_pipapo_match *mdata, ++ unsigned long *map, unsigned long *fill, ++ const struct nft_pipapo_field *f, ++ int offset, const u8 *pkt, ++ bool first, bool last) + { + unsigned long bsize = f->bsize; + int i, ret = -1, b; + + if (first) +- memset(map, 0xff, bsize * sizeof(*map)); ++ pipapo_resmap_init(mdata, map); + + for (i = offset; i < bsize; i++) { + if (f->bb == 8) +@@ -1119,15 +1132,21 @@ bool nft_pipapo_avx2_lookup(const struct net *net, const struct nft_set *set, + struct nft_pipapo *priv = nft_set_priv(set); + struct nft_pipapo_scratch *scratch; + u8 genmask = nft_genmask_cur(net); ++ const struct nft_pipapo_match *m; ++ const struct nft_pipapo_field *f; + const u8 *rp = (const u8 *)key; +- struct nft_pipapo_match *m; +- struct nft_pipapo_field *f; + unsigned long *res, *fill; + bool map_index; + int i, ret = 0; + +- if (unlikely(!irq_fpu_usable())) +- return nft_pipapo_lookup(net, set, key, ext); ++ local_bh_disable(); ++ ++ if (unlikely(!irq_fpu_usable())) { ++ bool fallback_res = nft_pipapo_lookup(net, set, key, ext); ++ ++ local_bh_enable(); ++ return fallback_res; ++ } + + m = rcu_dereference(priv->match); + +@@ -1142,6 +1161,7 @@ bool nft_pipapo_avx2_lookup(const struct net *net, const struct nft_set *set, + scratch = *raw_cpu_ptr(m->scratch); + if (unlikely(!scratch)) { + kernel_fpu_end(); ++ local_bh_enable(); + return false; + } + +@@ -1175,7 +1195,7 @@ bool nft_pipapo_avx2_lookup(const struct net *net, const struct nft_set *set, + } else if (f->groups == 16) { + NFT_SET_PIPAPO_AVX2_LOOKUP(8, 16); + } else { +- ret = nft_pipapo_avx2_lookup_slow(res, fill, f, ++ ret = nft_pipapo_avx2_lookup_slow(m, res, fill, f, + ret, rp, + first, last); + } +@@ -1191,7 +1211,7 @@ bool nft_pipapo_avx2_lookup(const struct net *net, const struct nft_set *set, + } else if (f->groups == 32) { + NFT_SET_PIPAPO_AVX2_LOOKUP(4, 32); + } else { +- ret = nft_pipapo_avx2_lookup_slow(res, fill, f, ++ ret = nft_pipapo_avx2_lookup_slow(m, res, fill, f, + ret, rp, + first, last); + } +@@ -1222,6 +1242,7 @@ bool nft_pipapo_avx2_lookup(const struct net *net, const struct nft_set *set, + if (i % 2) + scratch->map_index = !map_index; + kernel_fpu_end(); ++ local_bh_enable(); + + return ret >= 0; + } +diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c +index 10a6ec43efb9f..3e5703537e4eb 100644 +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -538,6 +538,61 @@ static void *packet_current_frame(struct packet_sock *po, + return packet_lookup_frame(po, rb, rb->head, status); + } + ++static u16 vlan_get_tci(struct sk_buff *skb, struct net_device *dev) ++{ ++ u8 *skb_orig_data = skb->data; ++ int skb_orig_len = skb->len; ++ struct vlan_hdr vhdr, *vh; ++ unsigned int header_len; ++ ++ if (!dev) ++ return 0; ++ ++ /* In the SOCK_DGRAM scenario, skb data starts at the network ++ * protocol, which is after the VLAN headers. The outer VLAN ++ * header is at the hard_header_len offset in non-variable ++ * length link layer headers. If it's a VLAN device, the ++ * min_header_len should be used to exclude the VLAN header ++ * size. ++ */ ++ if (dev->min_header_len == dev->hard_header_len) ++ header_len = dev->hard_header_len; ++ else if (is_vlan_dev(dev)) ++ header_len = dev->min_header_len; ++ else ++ return 0; ++ ++ skb_push(skb, skb->data - skb_mac_header(skb)); ++ vh = skb_header_pointer(skb, header_len, sizeof(vhdr), &vhdr); ++ if (skb_orig_data != skb->data) { ++ skb->data = skb_orig_data; ++ skb->len = skb_orig_len; ++ } ++ if (unlikely(!vh)) ++ return 0; ++ ++ return ntohs(vh->h_vlan_TCI); ++} ++ ++static __be16 vlan_get_protocol_dgram(struct sk_buff *skb) ++{ ++ __be16 proto = skb->protocol; ++ ++ if (unlikely(eth_type_vlan(proto))) { ++ u8 *skb_orig_data = skb->data; ++ int skb_orig_len = skb->len; ++ ++ skb_push(skb, skb->data - skb_mac_header(skb)); ++ proto = __vlan_get_protocol(skb, proto, NULL); ++ if (skb_orig_data != skb->data) { ++ skb->data = skb_orig_data; ++ skb->len = skb_orig_len; ++ } ++ } ++ ++ return proto; ++} ++ + static void prb_del_retire_blk_timer(struct tpacket_kbdq_core *pkc) + { + del_timer_sync(&pkc->retire_blk_timer); +@@ -1007,10 +1062,16 @@ static void prb_clear_rxhash(struct tpacket_kbdq_core *pkc, + static void prb_fill_vlan_info(struct tpacket_kbdq_core *pkc, + struct tpacket3_hdr *ppd) + { ++ struct packet_sock *po = container_of(pkc, struct packet_sock, rx_ring.prb_bdqc); ++ + if (skb_vlan_tag_present(pkc->skb)) { + ppd->hv1.tp_vlan_tci = skb_vlan_tag_get(pkc->skb); + ppd->hv1.tp_vlan_tpid = ntohs(pkc->skb->vlan_proto); + ppd->tp_status = TP_STATUS_VLAN_VALID | TP_STATUS_VLAN_TPID_VALID; ++ } else if (unlikely(po->sk.sk_type == SOCK_DGRAM && eth_type_vlan(pkc->skb->protocol))) { ++ ppd->hv1.tp_vlan_tci = vlan_get_tci(pkc->skb, pkc->skb->dev); ++ ppd->hv1.tp_vlan_tpid = ntohs(pkc->skb->protocol); ++ ppd->tp_status = TP_STATUS_VLAN_VALID | TP_STATUS_VLAN_TPID_VALID; + } else { + ppd->hv1.tp_vlan_tci = 0; + ppd->hv1.tp_vlan_tpid = 0; +@@ -2431,6 +2492,10 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, + h.h2->tp_vlan_tci = skb_vlan_tag_get(skb); + h.h2->tp_vlan_tpid = ntohs(skb->vlan_proto); + status |= TP_STATUS_VLAN_VALID | TP_STATUS_VLAN_TPID_VALID; ++ } else if (unlikely(sk->sk_type == SOCK_DGRAM && eth_type_vlan(skb->protocol))) { ++ h.h2->tp_vlan_tci = vlan_get_tci(skb, skb->dev); ++ h.h2->tp_vlan_tpid = ntohs(skb->protocol); ++ status |= TP_STATUS_VLAN_VALID | TP_STATUS_VLAN_TPID_VALID; + } else { + h.h2->tp_vlan_tci = 0; + h.h2->tp_vlan_tpid = 0; +@@ -2460,7 +2525,8 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, + sll->sll_halen = dev_parse_header(skb, sll->sll_addr); + sll->sll_family = AF_PACKET; + sll->sll_hatype = dev->type; +- sll->sll_protocol = skb->protocol; ++ sll->sll_protocol = (sk->sk_type == SOCK_DGRAM) ? ++ vlan_get_protocol_dgram(skb) : skb->protocol; + sll->sll_pkttype = skb->pkt_type; + if (unlikely(packet_sock_flag(po, PACKET_SOCK_ORIGDEV))) + sll->sll_ifindex = orig_dev->ifindex; +@@ -3488,7 +3554,8 @@ static int packet_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, + /* Original length was stored in sockaddr_ll fields */ + origlen = PACKET_SKB_CB(skb)->sa.origlen; + sll->sll_family = AF_PACKET; +- sll->sll_protocol = skb->protocol; ++ sll->sll_protocol = (sock->type == SOCK_DGRAM) ? ++ vlan_get_protocol_dgram(skb) : skb->protocol; + } + + sock_recv_cmsgs(msg, sk, skb); +@@ -3545,6 +3612,21 @@ static int packet_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, + aux.tp_vlan_tci = skb_vlan_tag_get(skb); + aux.tp_vlan_tpid = ntohs(skb->vlan_proto); + aux.tp_status |= TP_STATUS_VLAN_VALID | TP_STATUS_VLAN_TPID_VALID; ++ } else if (unlikely(sock->type == SOCK_DGRAM && eth_type_vlan(skb->protocol))) { ++ struct sockaddr_ll *sll = &PACKET_SKB_CB(skb)->sa.ll; ++ struct net_device *dev; ++ ++ rcu_read_lock(); ++ dev = dev_get_by_index_rcu(sock_net(sk), sll->sll_ifindex); ++ if (dev) { ++ aux.tp_vlan_tci = vlan_get_tci(skb, dev); ++ aux.tp_vlan_tpid = ntohs(skb->protocol); ++ aux.tp_status |= TP_STATUS_VLAN_VALID | TP_STATUS_VLAN_TPID_VALID; ++ } else { ++ aux.tp_vlan_tci = 0; ++ aux.tp_vlan_tpid = 0; ++ } ++ rcu_read_unlock(); + } else { + aux.tp_vlan_tci = 0; + aux.tp_vlan_tpid = 0; +diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c +index d520ee62c8ecd..f99bb9d0adcc6 100644 +--- a/net/smc/smc_core.c ++++ b/net/smc/smc_core.c +@@ -1974,7 +1974,6 @@ int smc_conn_create(struct smc_sock *smc, struct smc_init_info *ini) + */ + static u8 smc_compress_bufsize(int size, bool is_smcd, bool is_rmb) + { +- const unsigned int max_scat = SG_MAX_SINGLE_ALLOC * PAGE_SIZE; + u8 compressed; + + if (size <= SMC_BUF_MIN_SIZE) +@@ -1984,9 +1983,11 @@ static u8 smc_compress_bufsize(int size, bool is_smcd, bool is_rmb) + compressed = min_t(u8, ilog2(size) + 1, + is_smcd ? SMCD_DMBE_SIZES : SMCR_RMBE_SIZES); + ++#ifdef CONFIG_ARCH_NO_SG_CHAIN + if (!is_smcd && is_rmb) + /* RMBs are backed by & limited to max size of scatterlists */ +- compressed = min_t(u8, compressed, ilog2(max_scat >> 14)); ++ compressed = min_t(u8, compressed, ilog2((SG_MAX_SINGLE_ALLOC * PAGE_SIZE) >> 14)); ++#endif + + return compressed; + } +diff --git a/net/sunrpc/auth_gss/gss_krb5_keys.c b/net/sunrpc/auth_gss/gss_krb5_keys.c +index 06d8ee0db000f..4eb19c3a54c70 100644 +--- a/net/sunrpc/auth_gss/gss_krb5_keys.c ++++ b/net/sunrpc/auth_gss/gss_krb5_keys.c +@@ -168,7 +168,7 @@ static int krb5_DK(const struct gss_krb5_enctype *gk5e, + goto err_return; + blocksize = crypto_sync_skcipher_blocksize(cipher); + if (crypto_sync_skcipher_setkey(cipher, inkey->data, inkey->len)) +- goto err_return; ++ goto err_free_cipher; + + ret = -ENOMEM; + inblockdata = kmalloc(blocksize, gfp_mask); +diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c +index d3c917c0c8d59..142ee6554848a 100644 +--- a/net/sunrpc/clnt.c ++++ b/net/sunrpc/clnt.c +@@ -2310,12 +2310,13 @@ call_transmit_status(struct rpc_task *task) + task->tk_action = call_transmit; + task->tk_status = 0; + break; +- case -ECONNREFUSED: + case -EHOSTDOWN: + case -ENETDOWN: + case -EHOSTUNREACH: + case -ENETUNREACH: + case -EPERM: ++ break; ++ case -ECONNREFUSED: + if (RPC_IS_SOFTCONN(task)) { + if (!task->tk_msg.rpc_proc->p_proc) + trace_xprt_ping(task->tk_xprt, +diff --git a/net/sunrpc/xprtrdma/frwr_ops.c b/net/sunrpc/xprtrdma/frwr_ops.c +index ffbf99894970e..47f33bb7bff81 100644 +--- a/net/sunrpc/xprtrdma/frwr_ops.c ++++ b/net/sunrpc/xprtrdma/frwr_ops.c +@@ -92,7 +92,8 @@ static void frwr_mr_put(struct rpcrdma_mr *mr) + rpcrdma_mr_push(mr, &mr->mr_req->rl_free_mrs); + } + +-/* frwr_reset - Place MRs back on the free list ++/** ++ * frwr_reset - Place MRs back on @req's free list + * @req: request to reset + * + * Used after a failed marshal. For FRWR, this means the MRs +diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c +index 4f71627ba39ce..cb909329a5039 100644 +--- a/net/sunrpc/xprtrdma/verbs.c ++++ b/net/sunrpc/xprtrdma/verbs.c +@@ -897,6 +897,8 @@ static int rpcrdma_reqs_setup(struct rpcrdma_xprt *r_xprt) + + static void rpcrdma_req_reset(struct rpcrdma_req *req) + { ++ struct rpcrdma_mr *mr; ++ + /* Credits are valid for only one connection */ + req->rl_slot.rq_cong = 0; + +@@ -906,7 +908,19 @@ static void rpcrdma_req_reset(struct rpcrdma_req *req) + rpcrdma_regbuf_dma_unmap(req->rl_sendbuf); + rpcrdma_regbuf_dma_unmap(req->rl_recvbuf); + +- frwr_reset(req); ++ /* The verbs consumer can't know the state of an MR on the ++ * req->rl_registered list unless a successful completion ++ * has occurred, so they cannot be re-used. ++ */ ++ while ((mr = rpcrdma_mr_pop(&req->rl_registered))) { ++ struct rpcrdma_buffer *buf = &mr->mr_xprt->rx_buf; ++ ++ spin_lock(&buf->rb_lock); ++ list_del(&mr->mr_all); ++ spin_unlock(&buf->rb_lock); ++ ++ frwr_mr_release(mr); ++ } + } + + /* ASSUMPTION: the rb_allreqs list is stable for the duration, +diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c +index f892b0903dbaf..cdc8378261ec3 100644 +--- a/net/tipc/udp_media.c ++++ b/net/tipc/udp_media.c +@@ -135,8 +135,11 @@ static int tipc_udp_addr2str(struct tipc_media_addr *a, char *buf, int size) + snprintf(buf, size, "%pI4:%u", &ua->ipv4, ntohs(ua->port)); + else if (ntohs(ua->proto) == ETH_P_IPV6) + snprintf(buf, size, "%pI6:%u", &ua->ipv6, ntohs(ua->port)); +- else ++ else { + pr_err("Invalid UDP media address\n"); ++ return 1; ++ } ++ + return 0; + } + +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index 5a26e785ce70d..a551be47cb6c6 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -2624,10 +2624,49 @@ static struct sk_buff *manage_oob(struct sk_buff *skb, struct sock *sk, + + static int unix_stream_read_skb(struct sock *sk, skb_read_actor_t recv_actor) + { ++ struct unix_sock *u = unix_sk(sk); ++ struct sk_buff *skb; ++ int err; ++ + if (unlikely(READ_ONCE(sk->sk_state) != TCP_ESTABLISHED)) + return -ENOTCONN; + +- return unix_read_skb(sk, recv_actor); ++ mutex_lock(&u->iolock); ++ skb = skb_recv_datagram(sk, MSG_DONTWAIT, &err); ++ mutex_unlock(&u->iolock); ++ if (!skb) ++ return err; ++ ++#if IS_ENABLED(CONFIG_AF_UNIX_OOB) ++ if (unlikely(skb == READ_ONCE(u->oob_skb))) { ++ bool drop = false; ++ ++ unix_state_lock(sk); ++ ++ if (sock_flag(sk, SOCK_DEAD)) { ++ unix_state_unlock(sk); ++ kfree_skb(skb); ++ return -ECONNRESET; ++ } ++ ++ spin_lock(&sk->sk_receive_queue.lock); ++ if (likely(skb == u->oob_skb)) { ++ WRITE_ONCE(u->oob_skb, NULL); ++ drop = true; ++ } ++ spin_unlock(&sk->sk_receive_queue.lock); ++ ++ unix_state_unlock(sk); ++ ++ if (drop) { ++ WARN_ON_ONCE(skb_unref(skb)); ++ kfree_skb(skb); ++ return -EAGAIN; ++ } ++ } ++#endif ++ ++ return recv_actor(sk, skb); + } + + static int unix_stream_read_generic(struct unix_stream_read_state *state, +diff --git a/net/unix/unix_bpf.c b/net/unix/unix_bpf.c +index bd84785bf8d6c..bca2d86ba97d8 100644 +--- a/net/unix/unix_bpf.c ++++ b/net/unix/unix_bpf.c +@@ -54,6 +54,9 @@ static int unix_bpf_recvmsg(struct sock *sk, struct msghdr *msg, + struct sk_psock *psock; + int copied; + ++ if (flags & MSG_OOB) ++ return -EOPNOTSUPP; ++ + if (!len) + return 0; + +diff --git a/net/wireless/util.c b/net/wireless/util.c +index 57ea6d5b092d4..7acd8d0db61a7 100644 +--- a/net/wireless/util.c ++++ b/net/wireless/util.c +@@ -1460,7 +1460,7 @@ static u32 cfg80211_calculate_bitrate_he(struct rate_info *rate) + 5120, /* 0.833333... */ + }; + u32 rates_160M[3] = { 960777777, 907400000, 816666666 }; +- u32 rates_969[3] = { 480388888, 453700000, 408333333 }; ++ u32 rates_996[3] = { 480388888, 453700000, 408333333 }; + u32 rates_484[3] = { 229411111, 216666666, 195000000 }; + u32 rates_242[3] = { 114711111, 108333333, 97500000 }; + u32 rates_106[3] = { 40000000, 37777777, 34000000 }; +@@ -1480,12 +1480,14 @@ static u32 cfg80211_calculate_bitrate_he(struct rate_info *rate) + if (WARN_ON_ONCE(rate->nss < 1 || rate->nss > 8)) + return 0; + +- if (rate->bw == RATE_INFO_BW_160) ++ if (rate->bw == RATE_INFO_BW_160 || ++ (rate->bw == RATE_INFO_BW_HE_RU && ++ rate->he_ru_alloc == NL80211_RATE_INFO_HE_RU_ALLOC_2x996)) + result = rates_160M[rate->he_gi]; + else if (rate->bw == RATE_INFO_BW_80 || + (rate->bw == RATE_INFO_BW_HE_RU && + rate->he_ru_alloc == NL80211_RATE_INFO_HE_RU_ALLOC_996)) +- result = rates_969[rate->he_gi]; ++ result = rates_996[rate->he_gi]; + else if (rate->bw == RATE_INFO_BW_40 || + (rate->bw == RATE_INFO_BW_HE_RU && + rate->he_ru_alloc == NL80211_RATE_INFO_HE_RU_ALLOC_484)) +diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c +index 0dde08e02887d..b699cc2ec35ac 100644 +--- a/net/xfrm/xfrm_policy.c ++++ b/net/xfrm/xfrm_policy.c +@@ -436,6 +436,8 @@ EXPORT_SYMBOL(xfrm_policy_destroy); + + static void xfrm_policy_kill(struct xfrm_policy *policy) + { ++ xfrm_dev_policy_delete(policy); ++ + write_lock_bh(&policy->lock); + policy->walk.dead = 1; + write_unlock_bh(&policy->lock); +@@ -1834,7 +1836,6 @@ int xfrm_policy_flush(struct net *net, u8 type, bool task_valid) + + __xfrm_policy_unlink(pol, dir); + spin_unlock_bh(&net->xfrm.xfrm_policy_lock); +- xfrm_dev_policy_delete(pol); + cnt++; + xfrm_audit_policy_delete(pol, 1, task_valid); + xfrm_policy_kill(pol); +@@ -1875,7 +1876,6 @@ int xfrm_dev_policy_flush(struct net *net, struct net_device *dev, + + __xfrm_policy_unlink(pol, dir); + spin_unlock_bh(&net->xfrm.xfrm_policy_lock); +- xfrm_dev_policy_delete(pol); + cnt++; + xfrm_audit_policy_delete(pol, 1, task_valid); + xfrm_policy_kill(pol); +@@ -2326,7 +2326,6 @@ int xfrm_policy_delete(struct xfrm_policy *pol, int dir) + pol = __xfrm_policy_unlink(pol, dir); + spin_unlock_bh(&net->xfrm.xfrm_policy_lock); + if (pol) { +- xfrm_dev_policy_delete(pol); + xfrm_policy_kill(pol); + return 0; + } +diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c +index bda5327bf34df..8a6e8656d014f 100644 +--- a/net/xfrm/xfrm_state.c ++++ b/net/xfrm/xfrm_state.c +@@ -49,6 +49,7 @@ static struct kmem_cache *xfrm_state_cache __ro_after_init; + + static DECLARE_WORK(xfrm_state_gc_work, xfrm_state_gc_task); + static HLIST_HEAD(xfrm_state_gc_list); ++static HLIST_HEAD(xfrm_state_dev_gc_list); + + static inline bool xfrm_state_hold_rcu(struct xfrm_state __rcu *x) + { +@@ -214,6 +215,7 @@ static DEFINE_SPINLOCK(xfrm_state_afinfo_lock); + static struct xfrm_state_afinfo __rcu *xfrm_state_afinfo[NPROTO]; + + static DEFINE_SPINLOCK(xfrm_state_gc_lock); ++static DEFINE_SPINLOCK(xfrm_state_dev_gc_lock); + + int __xfrm_state_delete(struct xfrm_state *x); + +@@ -683,6 +685,41 @@ struct xfrm_state *xfrm_state_alloc(struct net *net) + } + EXPORT_SYMBOL(xfrm_state_alloc); + ++#ifdef CONFIG_XFRM_OFFLOAD ++void xfrm_dev_state_delete(struct xfrm_state *x) ++{ ++ struct xfrm_dev_offload *xso = &x->xso; ++ struct net_device *dev = READ_ONCE(xso->dev); ++ ++ if (dev) { ++ dev->xfrmdev_ops->xdo_dev_state_delete(x); ++ spin_lock_bh(&xfrm_state_dev_gc_lock); ++ hlist_add_head(&x->dev_gclist, &xfrm_state_dev_gc_list); ++ spin_unlock_bh(&xfrm_state_dev_gc_lock); ++ } ++} ++EXPORT_SYMBOL_GPL(xfrm_dev_state_delete); ++ ++void xfrm_dev_state_free(struct xfrm_state *x) ++{ ++ struct xfrm_dev_offload *xso = &x->xso; ++ struct net_device *dev = READ_ONCE(xso->dev); ++ ++ if (dev && dev->xfrmdev_ops) { ++ spin_lock_bh(&xfrm_state_dev_gc_lock); ++ if (!hlist_unhashed(&x->dev_gclist)) ++ hlist_del(&x->dev_gclist); ++ spin_unlock_bh(&xfrm_state_dev_gc_lock); ++ ++ if (dev->xfrmdev_ops->xdo_dev_state_free) ++ dev->xfrmdev_ops->xdo_dev_state_free(x); ++ WRITE_ONCE(xso->dev, NULL); ++ xso->type = XFRM_DEV_OFFLOAD_UNSPECIFIED; ++ netdev_put(dev, &xso->dev_tracker); ++ } ++} ++#endif ++ + void __xfrm_state_destroy(struct xfrm_state *x, bool sync) + { + WARN_ON(x->km.state != XFRM_STATE_DEAD); +@@ -848,6 +885,9 @@ EXPORT_SYMBOL(xfrm_state_flush); + + int xfrm_dev_state_flush(struct net *net, struct net_device *dev, bool task_valid) + { ++ struct xfrm_state *x; ++ struct hlist_node *tmp; ++ struct xfrm_dev_offload *xso; + int i, err = 0, cnt = 0; + + spin_lock_bh(&net->xfrm.xfrm_state_lock); +@@ -857,8 +897,6 @@ int xfrm_dev_state_flush(struct net *net, struct net_device *dev, bool task_vali + + err = -ESRCH; + for (i = 0; i <= net->xfrm.state_hmask; i++) { +- struct xfrm_state *x; +- struct xfrm_dev_offload *xso; + restart: + hlist_for_each_entry(x, net->xfrm.state_bydst+i, bydst) { + xso = &x->xso; +@@ -868,6 +906,8 @@ int xfrm_dev_state_flush(struct net *net, struct net_device *dev, bool task_vali + spin_unlock_bh(&net->xfrm.xfrm_state_lock); + + err = xfrm_state_delete(x); ++ xfrm_dev_state_free(x); ++ + xfrm_audit_state_delete(x, err ? 0 : 1, + task_valid); + xfrm_state_put(x); +@@ -884,6 +924,24 @@ int xfrm_dev_state_flush(struct net *net, struct net_device *dev, bool task_vali + + out: + spin_unlock_bh(&net->xfrm.xfrm_state_lock); ++ ++ spin_lock_bh(&xfrm_state_dev_gc_lock); ++restart_gc: ++ hlist_for_each_entry_safe(x, tmp, &xfrm_state_dev_gc_list, dev_gclist) { ++ xso = &x->xso; ++ ++ if (xso->dev == dev) { ++ spin_unlock_bh(&xfrm_state_dev_gc_lock); ++ xfrm_dev_state_free(x); ++ spin_lock_bh(&xfrm_state_dev_gc_lock); ++ goto restart_gc; ++ } ++ ++ } ++ spin_unlock_bh(&xfrm_state_dev_gc_lock); ++ ++ xfrm_flush_gc(); ++ + return err; + } + EXPORT_SYMBOL(xfrm_dev_state_flush); +@@ -1273,8 +1331,7 @@ xfrm_state_find(const xfrm_address_t *daddr, const xfrm_address_t *saddr, + xso->dev = xdo->dev; + xso->real_dev = xdo->real_dev; + xso->flags = XFRM_DEV_OFFLOAD_FLAG_ACQ; +- netdev_tracker_alloc(xso->dev, &xso->dev_tracker, +- GFP_ATOMIC); ++ netdev_hold(xso->dev, &xso->dev_tracker, GFP_ATOMIC); + error = xso->dev->xfrmdev_ops->xdo_dev_state_add(x, NULL); + if (error) { + xso->dir = 0; +diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c +index 444e58bc3f440..979f23cded401 100644 +--- a/net/xfrm/xfrm_user.c ++++ b/net/xfrm/xfrm_user.c +@@ -2348,7 +2348,6 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, + NETLINK_CB(skb).portid); + } + } else { +- xfrm_dev_policy_delete(xp); + xfrm_audit_policy_delete(xp, err ? 0 : 1, true); + + if (err != 0) +diff --git a/scripts/Kconfig.include b/scripts/Kconfig.include +index 3ee8ecfb8c044..3500a3d62f0df 100644 +--- a/scripts/Kconfig.include ++++ b/scripts/Kconfig.include +@@ -33,7 +33,8 @@ ld-option = $(success,$(LD) -v $(1)) + + # $(as-instr,<instr>) + # Return y if the assembler supports <instr>, n otherwise +-as-instr = $(success,printf "%b\n" "$(1)" | $(CC) $(CLANG_FLAGS) -Wa$(comma)--fatal-warnings -c -x assembler-with-cpp -o /dev/null -) ++as-instr = $(success,printf "%b\n" "$(1)" | $(CC) $(CLANG_FLAGS) $(2) -Wa$(comma)--fatal-warnings -c -x assembler-with-cpp -o /dev/null -) ++as-instr64 = $(as-instr,$(1),$(m64-flag)) + + # check if $(CC) and $(LD) exist + $(error-if,$(failure,command -v $(CC)),C compiler '$(CC)' not found) +diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib +index 68d0134bdbf9d..e702552fb131a 100644 +--- a/scripts/Makefile.lib ++++ b/scripts/Makefile.lib +@@ -395,8 +395,12 @@ cmd_dtc = $(HOSTCC) -E $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; + -d $(depfile).dtc.tmp $(dtc-tmp) ; \ + cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile) + ++# NOTE: ++# Do not replace $(filter %.dtb %.dtbo, $^) with $(real-prereqs). When a single ++# DTB is turned into a multi-blob DTB, $^ will contain header file dependencies ++# recorded in the .*.cmd file. + quiet_cmd_fdtoverlay = DTOVL $@ +- cmd_fdtoverlay = $(objtree)/scripts/dtc/fdtoverlay -o $@ -i $(real-prereqs) ++ cmd_fdtoverlay = $(objtree)/scripts/dtc/fdtoverlay -o $@ -i $(filter %.dtb %.dtbo, $^) + + $(multi-dtb-y): FORCE + $(call if_changed,fdtoverlay) +diff --git a/scripts/gcc-x86_32-has-stack-protector.sh b/scripts/gcc-x86_32-has-stack-protector.sh +index 825c75c5b7150..9459ca4f0f11f 100755 +--- a/scripts/gcc-x86_32-has-stack-protector.sh ++++ b/scripts/gcc-x86_32-has-stack-protector.sh +@@ -5,4 +5,4 @@ + # -mstack-protector-guard-reg, added by + # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81708 + +-echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -m32 -O0 -fstack-protector -mstack-protector-guard-reg=fs -mstack-protector-guard-symbol=__stack_chk_guard - -o - 2> /dev/null | grep -q "%fs" ++echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -m32 -O0 -fstack-protector -mstack-protector-guard-reg=fs -mstack-protector-guard-symbol=__stack_chk_guard - -o - 2> /dev/null | grep -q "%fs" +diff --git a/scripts/gcc-x86_64-has-stack-protector.sh b/scripts/gcc-x86_64-has-stack-protector.sh +index 75e4e22b986ad..f680bb01aeeb3 100755 +--- a/scripts/gcc-x86_64-has-stack-protector.sh ++++ b/scripts/gcc-x86_64-has-stack-protector.sh +@@ -1,4 +1,4 @@ + #!/bin/sh + # SPDX-License-Identifier: GPL-2.0 + +-echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -m64 -O0 -mcmodel=kernel -fno-PIE -fstack-protector - -o - 2> /dev/null | grep -q "%gs" ++echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -m64 -O0 -mcmodel=kernel -fno-PIE -fstack-protector - -o - 2> /dev/null | grep -q "%gs" +diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c +index 366cdfd6a7baf..5303a51eff9c1 100644 +--- a/security/apparmor/lsm.c ++++ b/security/apparmor/lsm.c +@@ -1130,6 +1130,13 @@ static int apparmor_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) + if (!skb->secmark) + return 0; + ++ /* ++ * If reach here before socket_post_create hook is called, in which ++ * case label is null, drop the packet. ++ */ ++ if (!ctx->label) ++ return -EACCES; ++ + return apparmor_secmark_check(ctx->label, OP_RECVMSG, AA_MAY_RECEIVE, + skb->secmark, sk); + } +diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c +index 8a07793ce1032..d9d3b3d776e11 100644 +--- a/security/apparmor/policy.c ++++ b/security/apparmor/policy.c +@@ -188,7 +188,7 @@ static void aa_free_data(void *ptr, void *arg) + { + struct aa_data *data = ptr; + +- kfree_sensitive(data->data); ++ kvfree_sensitive(data->data, data->size); + kfree_sensitive(data->key); + kfree_sensitive(data); + } +diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c +index d92788da67045..d752bfa9b3f37 100644 +--- a/security/apparmor/policy_unpack.c ++++ b/security/apparmor/policy_unpack.c +@@ -1081,6 +1081,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) + + if (rhashtable_insert_fast(profile->data, &data->head, + profile->data->p)) { ++ kvfree_sensitive(data->data, data->size); + kfree_sensitive(data->key); + kfree_sensitive(data); + info = "failed to insert data to table"; +diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c +index 19be69fa4d052..aa1dc43b16ddf 100644 +--- a/security/keys/keyctl.c ++++ b/security/keys/keyctl.c +@@ -1694,7 +1694,7 @@ long keyctl_session_to_parent(void) + goto unlock; + + /* cancel an already pending keyring replacement */ +- oldwork = task_work_cancel(parent, key_change_session_keyring); ++ oldwork = task_work_cancel_func(parent, key_change_session_keyring); + + /* the replacement session keyring is applied just prior to userspace + * restarting */ +diff --git a/security/landlock/cred.c b/security/landlock/cred.c +index 13dff2a315451..94f0d03bfd643 100644 +--- a/security/landlock/cred.c ++++ b/security/landlock/cred.c +@@ -14,8 +14,8 @@ + #include "ruleset.h" + #include "setup.h" + +-static int hook_cred_prepare(struct cred *const new, +- const struct cred *const old, const gfp_t gfp) ++static void hook_cred_transfer(struct cred *const new, ++ const struct cred *const old) + { + struct landlock_ruleset *const old_dom = landlock_cred(old)->domain; + +@@ -23,6 +23,12 @@ static int hook_cred_prepare(struct cred *const new, + landlock_get_ruleset(old_dom); + landlock_cred(new)->domain = old_dom; + } ++} ++ ++static int hook_cred_prepare(struct cred *const new, ++ const struct cred *const old, const gfp_t gfp) ++{ ++ hook_cred_transfer(new, old); + return 0; + } + +@@ -36,6 +42,7 @@ static void hook_cred_free(struct cred *const cred) + + static struct security_hook_list landlock_hooks[] __ro_after_init = { + LSM_HOOK_INIT(cred_prepare, hook_cred_prepare), ++ LSM_HOOK_INIT(cred_transfer, hook_cred_transfer), + LSM_HOOK_INIT(cred_free, hook_cred_free), + }; + +diff --git a/sound/core/ump.c b/sound/core/ump.c +index d68d3bda97e42..8a7ecec74b5d6 100644 +--- a/sound/core/ump.c ++++ b/sound/core/ump.c +@@ -733,6 +733,12 @@ static void fill_fb_info(struct snd_ump_endpoint *ump, + info->block_id, info->direction, info->active, + info->first_group, info->num_groups, info->midi_ci_version, + info->sysex8_streams, info->flags); ++ ++ if ((info->flags & SNDRV_UMP_BLOCK_IS_MIDI1) && info->num_groups != 1) { ++ info->num_groups = 1; ++ ump_dbg(ump, "FB %d: corrected groups to 1 for MIDI1\n", ++ info->block_id); ++ } + } + + /* check whether the FB info gets updated by the current message */ +@@ -806,6 +812,13 @@ static int ump_handle_fb_name_msg(struct snd_ump_endpoint *ump, + if (!fb) + return -ENODEV; + ++ if (ump->parsed && ++ (ump->info.flags & SNDRV_UMP_EP_INFO_STATIC_BLOCKS)) { ++ ump_dbg(ump, "Skipping static FB name update (blk#%d)\n", ++ fb->info.block_id); ++ return 0; ++ } ++ + ret = ump_append_string(ump, fb->info.name, sizeof(fb->info.name), + buf->raw, 3); + /* notify the FB name update to sequencer, too */ +diff --git a/sound/soc/amd/acp-es8336.c b/sound/soc/amd/acp-es8336.c +index 5e56d3a53be78..49bffc567e68d 100644 +--- a/sound/soc/amd/acp-es8336.c ++++ b/sound/soc/amd/acp-es8336.c +@@ -203,8 +203,10 @@ static int st_es8336_late_probe(struct snd_soc_card *card) + + codec_dev = acpi_get_first_physical_node(adev); + acpi_dev_put(adev); +- if (!codec_dev) ++ if (!codec_dev) { + dev_err(card->dev, "can not find codec dev\n"); ++ return -ENODEV; ++ } + + ret = devm_acpi_dev_add_driver_gpios(codec_dev, acpi_es8336_gpios); + if (ret) +diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c +index 4e3a8ce690a45..36dddf230c2c4 100644 +--- a/sound/soc/amd/yc/acp6x-mach.c ++++ b/sound/soc/amd/yc/acp6x-mach.c +@@ -220,6 +220,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "21J6"), + } + }, ++ { ++ .driver_data = &acp6x_card, ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "21M5"), ++ } ++ }, + { + .driver_data = &acp6x_card, + .matches = { +diff --git a/sound/soc/codecs/cs35l56-shared.c b/sound/soc/codecs/cs35l56-shared.c +index 12291242362b4..69c951e305842 100644 +--- a/sound/soc/codecs/cs35l56-shared.c ++++ b/sound/soc/codecs/cs35l56-shared.c +@@ -354,7 +354,7 @@ int cs35l56_irq_request(struct cs35l56_base *cs35l56_base, int irq) + { + int ret; + +- if (!irq) ++ if (irq < 1) + return 0; + + ret = devm_request_threaded_irq(cs35l56_base->dev, irq, NULL, cs35l56_irq, +diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c +index 8b56ee550c09e..8b0645c634620 100644 +--- a/sound/soc/codecs/max98088.c ++++ b/sound/soc/codecs/max98088.c +@@ -1318,6 +1318,7 @@ static int max98088_set_bias_level(struct snd_soc_component *component, + enum snd_soc_bias_level level) + { + struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component); ++ int ret; + + switch (level) { + case SND_SOC_BIAS_ON: +@@ -1333,10 +1334,13 @@ static int max98088_set_bias_level(struct snd_soc_component *component, + */ + if (!IS_ERR(max98088->mclk)) { + if (snd_soc_component_get_bias_level(component) == +- SND_SOC_BIAS_ON) ++ SND_SOC_BIAS_ON) { + clk_disable_unprepare(max98088->mclk); +- else +- clk_prepare_enable(max98088->mclk); ++ } else { ++ ret = clk_prepare_enable(max98088->mclk); ++ if (ret) ++ return ret; ++ } + } + break; + +diff --git a/sound/soc/codecs/tas2781-fmwlib.c b/sound/soc/codecs/tas2781-fmwlib.c +index c6c47297a4fe7..41ad82a429163 100644 +--- a/sound/soc/codecs/tas2781-fmwlib.c ++++ b/sound/soc/codecs/tas2781-fmwlib.c +@@ -2193,7 +2193,7 @@ static void tasdev_load_calibrated_data(struct tasdevice_priv *priv, int i) + return; + + cal = cal_fmw->calibrations; +- if (cal) ++ if (!cal) + return; + + load_calib_data(priv, &cal->dev_data); +@@ -2354,14 +2354,21 @@ void tasdevice_tuning_switch(void *context, int state) + struct tasdevice_fw *tas_fmw = tas_priv->fmw; + int profile_cfg_id = tas_priv->rcabin.profile_cfg_id; + +- if (tas_priv->fw_state == TASDEVICE_DSP_FW_FAIL) { +- dev_err(tas_priv->dev, "DSP bin file not loaded\n"); ++ /* ++ * Only RCA-based Playback can still work with no dsp program running ++ * inside the chip. ++ */ ++ switch (tas_priv->fw_state) { ++ case TASDEVICE_RCA_FW_OK: ++ case TASDEVICE_DSP_FW_ALL_OK: ++ break; ++ default: + return; + } + + if (state == 0) { +- if (tas_priv->cur_prog < tas_fmw->nr_programs) { +- /*dsp mode or tuning mode*/ ++ if (tas_fmw && tas_priv->cur_prog < tas_fmw->nr_programs) { ++ /* dsp mode or tuning mode */ + profile_cfg_id = tas_priv->rcabin.profile_cfg_id; + tasdevice_select_tuningprm_cfg(tas_priv, + tas_priv->cur_prog, tas_priv->cur_conf, +@@ -2370,9 +2377,10 @@ void tasdevice_tuning_switch(void *context, int state) + + tasdevice_select_cfg_blk(tas_priv, profile_cfg_id, + TASDEVICE_BIN_BLK_PRE_POWER_UP); +- } else ++ } else { + tasdevice_select_cfg_blk(tas_priv, profile_cfg_id, + TASDEVICE_BIN_BLK_PRE_SHUTDOWN); ++ } + } + EXPORT_SYMBOL_NS_GPL(tasdevice_tuning_switch, + SND_SOC_TAS2781_FMWLIB); +diff --git a/sound/soc/codecs/tas2781-i2c.c b/sound/soc/codecs/tas2781-i2c.c +index 7327e9dcc8c02..a9d179e307739 100644 +--- a/sound/soc/codecs/tas2781-i2c.c ++++ b/sound/soc/codecs/tas2781-i2c.c +@@ -378,23 +378,37 @@ static void tasdevice_fw_ready(const struct firmware *fmw, + mutex_lock(&tas_priv->codec_lock); + + ret = tasdevice_rca_parser(tas_priv, fmw); +- if (ret) ++ if (ret) { ++ tasdevice_config_info_remove(tas_priv); + goto out; ++ } + tasdevice_create_control(tas_priv); + + tasdevice_dsp_remove(tas_priv); + tasdevice_calbin_remove(tas_priv); +- tas_priv->fw_state = TASDEVICE_DSP_FW_PENDING; ++ /* ++ * The baseline is the RCA-only case, and then the code attempts to ++ * load DSP firmware but in case of failures just keep going, i.e. ++ * failing to load DSP firmware is NOT an error. ++ */ ++ tas_priv->fw_state = TASDEVICE_RCA_FW_OK; + scnprintf(tas_priv->coef_binaryname, 64, "%s_coef.bin", + tas_priv->dev_name); + ret = tasdevice_dsp_parser(tas_priv); + if (ret) { + dev_err(tas_priv->dev, "dspfw load %s error\n", + tas_priv->coef_binaryname); +- tas_priv->fw_state = TASDEVICE_DSP_FW_FAIL; + goto out; + } +- tasdevice_dsp_create_ctrls(tas_priv); ++ ++ /* ++ * If no dsp-related kcontrol created, the dsp resource will be freed. ++ */ ++ ret = tasdevice_dsp_create_ctrls(tas_priv); ++ if (ret) { ++ dev_err(tas_priv->dev, "dsp controls error\n"); ++ goto out; ++ } + + tas_priv->fw_state = TASDEVICE_DSP_FW_ALL_OK; + +@@ -415,9 +429,8 @@ static void tasdevice_fw_ready(const struct firmware *fmw, + tasdevice_prmg_load(tas_priv, 0); + tas_priv->cur_prog = 0; + out: +- if (tas_priv->fw_state == TASDEVICE_DSP_FW_FAIL) { +- /*If DSP FW fail, kcontrol won't be created */ +- tasdevice_config_info_remove(tas_priv); ++ if (tas_priv->fw_state == TASDEVICE_RCA_FW_OK) { ++ /* If DSP FW fail, DSP kcontrol won't be created. */ + tasdevice_dsp_remove(tas_priv); + } + mutex_unlock(&tas_priv->codec_lock); +@@ -464,14 +477,14 @@ static int tasdevice_startup(struct snd_pcm_substream *substream, + { + struct snd_soc_component *codec = dai->component; + struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(codec); +- int ret = 0; + +- if (tas_priv->fw_state != TASDEVICE_DSP_FW_ALL_OK) { +- dev_err(tas_priv->dev, "DSP bin file not loaded\n"); +- ret = -EINVAL; ++ switch (tas_priv->fw_state) { ++ case TASDEVICE_RCA_FW_OK: ++ case TASDEVICE_DSP_FW_ALL_OK: ++ return 0; ++ default: ++ return -EINVAL; + } +- +- return ret; + } + + static int tasdevice_hw_params(struct snd_pcm_substream *substream, +diff --git a/sound/soc/fsl/fsl_qmc_audio.c b/sound/soc/fsl/fsl_qmc_audio.c +index 56d6b0b039a2e..df8188159a582 100644 +--- a/sound/soc/fsl/fsl_qmc_audio.c ++++ b/sound/soc/fsl/fsl_qmc_audio.c +@@ -604,6 +604,8 @@ static int qmc_audio_dai_parse(struct qmc_audio *qmc_audio, struct device_node * + + qmc_dai->name = devm_kasprintf(qmc_audio->dev, GFP_KERNEL, "%s.%d", + np->parent->name, qmc_dai->id); ++ if (!qmc_dai->name) ++ return -ENOMEM; + + qmc_dai->qmc_chan = devm_qmc_chan_get_byphandle(qmc_audio->dev, np, + "fsl,qmc-chan"); +diff --git a/sound/soc/intel/common/soc-intel-quirks.h b/sound/soc/intel/common/soc-intel-quirks.h +index de4e550c5b34d..42bd51456b945 100644 +--- a/sound/soc/intel/common/soc-intel-quirks.h ++++ b/sound/soc/intel/common/soc-intel-quirks.h +@@ -11,7 +11,7 @@ + + #include <linux/platform_data/x86/soc.h> + +-#if IS_ENABLED(CONFIG_X86) ++#if IS_REACHABLE(CONFIG_IOSF_MBI) + + #include <linux/dmi.h> + #include <asm/iosf_mbi.h> +diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c +index 39571fed40019..73b42d9ee2447 100644 +--- a/sound/soc/qcom/lpass-cpu.c ++++ b/sound/soc/qcom/lpass-cpu.c +@@ -1170,9 +1170,13 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev) + } + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "lpass-rxtx-cdc-dma-lpm"); ++ if (!res) ++ return -EINVAL; + drvdata->rxtx_cdc_dma_lpm_buf = res->start; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "lpass-va-cdc-dma-lpm"); ++ if (!res) ++ return -EINVAL; + drvdata->va_cdc_dma_lpm_buf = res->start; + } + +diff --git a/sound/soc/sof/amd/pci-vangogh.c b/sound/soc/sof/amd/pci-vangogh.c +index d8be42fbcb6dd..b035e31fadaba 100644 +--- a/sound/soc/sof/amd/pci-vangogh.c ++++ b/sound/soc/sof/amd/pci-vangogh.c +@@ -34,7 +34,6 @@ static const struct sof_amd_acp_desc vangogh_chip_info = { + .dsp_intr_base = ACP5X_DSP_SW_INTR_BASE, + .sram_pte_offset = ACP5X_SRAM_PTE_OFFSET, + .hw_semaphore_offset = ACP5X_AXI2DAGB_SEM_0, +- .acp_clkmux_sel = ACP5X_CLKMUX_SEL, + .probe_reg_offset = ACP5X_FUTURE_REG_ACLK_0, + }; + +diff --git a/sound/soc/sof/imx/imx8m.c b/sound/soc/sof/imx/imx8m.c +index 1243f8a6141ea..186ba4bbb5b26 100644 +--- a/sound/soc/sof/imx/imx8m.c ++++ b/sound/soc/sof/imx/imx8m.c +@@ -243,7 +243,7 @@ static int imx8m_probe(struct snd_sof_dev *sdev) + /* set default mailbox offset for FW ready message */ + sdev->dsp_box.offset = MBOX_OFFSET; + +- priv->regmap = syscon_regmap_lookup_by_compatible("fsl,dsp-ctrl"); ++ priv->regmap = syscon_regmap_lookup_by_phandle(np, "fsl,dsp-ctrl"); + if (IS_ERR(priv->regmap)) { + dev_err(sdev->dev, "cannot find dsp-ctrl registers"); + ret = PTR_ERR(priv->regmap); +diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c +index 78ff129be7728..284efad30f1a0 100644 +--- a/sound/soc/sof/ipc4-topology.c ++++ b/sound/soc/sof/ipc4-topology.c +@@ -1254,7 +1254,13 @@ static void sof_ipc4_unprepare_copier_module(struct snd_sof_widget *swidget) + ipc4_copier = dai->private; + + if (pipeline->use_chain_dma) { +- pipeline->msg.primary = 0; ++ /* ++ * Preserve the DMA Link ID and clear other bits since ++ * the DMA Link ID is only configured once during ++ * dai_config, other fields are expected to be 0 for ++ * re-configuration ++ */ ++ pipeline->msg.primary &= SOF_IPC4_GLB_CHAIN_DMA_LINK_ID_MASK; + pipeline->msg.extension = 0; + } + +diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c +index 409fc11646948..d1bdb0b93bda0 100644 +--- a/sound/usb/mixer.c ++++ b/sound/usb/mixer.c +@@ -1211,6 +1211,13 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval, + cval->res = 16; + } + break; ++ case USB_ID(0x1bcf, 0x2281): /* HD Webcam */ ++ if (!strcmp(kctl->id.name, "Mic Capture Volume")) { ++ usb_audio_info(chip, ++ "set resolution quirk: cval->res = 16\n"); ++ cval->res = 16; ++ } ++ break; + } + } + +diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c +index 09712e61c606e..b437b14d838ac 100644 +--- a/sound/usb/quirks.c ++++ b/sound/usb/quirks.c +@@ -2085,6 +2085,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { + QUIRK_FLAG_CTL_MSG_DELAY_1M), + DEVICE_FLG(0x0b0e, 0x0349, /* Jabra 550a */ + QUIRK_FLAG_CTL_MSG_DELAY_1M), ++ DEVICE_FLG(0x0c45, 0x6340, /* Sonix HD USB Camera */ ++ QUIRK_FLAG_GET_SAMPLE_RATE), + DEVICE_FLG(0x0ecb, 0x205c, /* JBL Quantum610 Wireless */ + QUIRK_FLAG_FIXED_RATE), + DEVICE_FLG(0x0ecb, 0x2069, /* JBL Quantum810 Wireless */ +@@ -2127,6 +2129,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { + QUIRK_FLAG_GET_SAMPLE_RATE), + DEVICE_FLG(0x19f7, 0x0035, /* RODE NT-USB+ */ + QUIRK_FLAG_GET_SAMPLE_RATE), ++ DEVICE_FLG(0x1bcf, 0x2281, /* HD Webcam */ ++ QUIRK_FLAG_GET_SAMPLE_RATE), + DEVICE_FLG(0x1bcf, 0x2283, /* NexiGo N930AF FHD Webcam */ + QUIRK_FLAG_GET_SAMPLE_RATE), + DEVICE_FLG(0x2040, 0x7200, /* Hauppauge HVR-950Q */ +diff --git a/tools/bpf/bpftool/common.c b/tools/bpf/bpftool/common.c +index 958e92acca8e2..9b75639434b81 100644 +--- a/tools/bpf/bpftool/common.c ++++ b/tools/bpf/bpftool/common.c +@@ -410,7 +410,7 @@ void get_prog_full_name(const struct bpf_prog_info *prog_info, int prog_fd, + { + const char *prog_name = prog_info->name; + const struct btf_type *func_type; +- const struct bpf_func_info finfo = {}; ++ struct bpf_func_info finfo = {}; + struct bpf_prog_info info = {}; + __u32 info_len = sizeof(info); + struct btf *prog_btf = NULL; +diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c +index 086b93939ce93..e5e0fe3854a35 100644 +--- a/tools/bpf/bpftool/prog.c ++++ b/tools/bpf/bpftool/prog.c +@@ -1809,6 +1809,10 @@ static int load_with_options(int argc, char **argv, bool first_prog_only) + } + + if (pinmaps) { ++ err = create_and_mount_bpffs_dir(pinmaps); ++ if (err) ++ goto err_unpin; ++ + err = bpf_object__pin_maps(obj, pinmaps); + if (err) { + p_err("failed to pin all maps"); +diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c +index af393c7dee1f1..b3edc239fe562 100644 +--- a/tools/bpf/resolve_btfids/main.c ++++ b/tools/bpf/resolve_btfids/main.c +@@ -696,7 +696,7 @@ static int sets_patch(struct object *obj) + * Make sure id is at the beginning of the pairs + * struct, otherwise the below qsort would not work. + */ +- BUILD_BUG_ON(set8->pairs != &set8->pairs[0].id); ++ BUILD_BUG_ON((u32 *)set8->pairs != &set8->pairs[0].id); + qsort(set8->pairs, set8->cnt, sizeof(set8->pairs[0]), cmp_id); + + /* +diff --git a/tools/lib/bpf/btf_dump.c b/tools/lib/bpf/btf_dump.c +index 4d9f30bf7f014..ebf56d21d08ee 100644 +--- a/tools/lib/bpf/btf_dump.c ++++ b/tools/lib/bpf/btf_dump.c +@@ -1559,10 +1559,12 @@ static void btf_dump_emit_type_chain(struct btf_dump *d, + * Clang for BPF target generates func_proto with no + * args as a func_proto with a single void arg (e.g., + * `int (*f)(void)` vs just `int (*f)()`). We are +- * going to pretend there are no args for such case. ++ * going to emit valid empty args (void) syntax for ++ * such case. Similarly and conveniently, valid ++ * no args case can be special-cased here as well. + */ +- if (vlen == 1 && p->type == 0) { +- btf_dump_printf(d, ")"); ++ if (vlen == 0 || (vlen == 1 && p->type == 0)) { ++ btf_dump_printf(d, "void)"); + return; + } + +diff --git a/tools/lib/bpf/linker.c b/tools/lib/bpf/linker.c +index 5ced96d99f8c5..b311bb91f672e 100644 +--- a/tools/lib/bpf/linker.c ++++ b/tools/lib/bpf/linker.c +@@ -2194,10 +2194,17 @@ static int linker_fixup_btf(struct src_obj *obj) + vi = btf_var_secinfos(t); + for (j = 0, m = btf_vlen(t); j < m; j++, vi++) { + const struct btf_type *vt = btf__type_by_id(obj->btf, vi->type); +- const char *var_name = btf__str_by_offset(obj->btf, vt->name_off); +- int var_linkage = btf_var(vt)->linkage; ++ const char *var_name; ++ int var_linkage; + Elf64_Sym *sym; + ++ /* could be a variable or function */ ++ if (!btf_is_var(vt)) ++ continue; ++ ++ var_name = btf__str_by_offset(obj->btf, vt->name_off); ++ var_linkage = btf_var(vt)->linkage; ++ + /* no need to patch up static or extern vars */ + if (var_linkage != BTF_VAR_GLOBAL_ALLOCATED) + continue; +diff --git a/tools/memory-model/lock.cat b/tools/memory-model/lock.cat +index 53b5a492739d0..21ba650869383 100644 +--- a/tools/memory-model/lock.cat ++++ b/tools/memory-model/lock.cat +@@ -102,19 +102,19 @@ let rf-lf = rfe-lf | rfi-lf + * within one of the lock's critical sections returns False. + *) + +-(* rfi for RU events: an RU may read from the last po-previous UL *) +-let rfi-ru = ([UL] ; po-loc ; [RU]) \ ([UL] ; po-loc ; [LKW] ; po-loc) +- +-(* rfe for RU events: an RU may read from an external UL or the initial write *) +-let all-possible-rfe-ru = +- let possible-rfe-ru r = ++(* ++ * rf for RU events: an RU may read from an external UL or the initial write, ++ * or from the last po-previous UL ++ *) ++let all-possible-rf-ru = ++ let possible-rf-ru r = + let pair-to-relation p = p ++ 0 +- in map pair-to-relation (((UL | IW) * {r}) & loc & ext) +- in map possible-rfe-ru RU ++ in map pair-to-relation ((((UL | IW) * {r}) & loc & ext) | ++ (((UL * {r}) & po-loc) \ ([UL] ; po-loc ; [LKW] ; po-loc))) ++ in map possible-rf-ru RU + + (* Generate all rf relations for RU events *) +-with rfe-ru from cross(all-possible-rfe-ru) +-let rf-ru = rfe-ru | rfi-ru ++with rf-ru from cross(all-possible-rf-ru) + + (* Final rf relation *) + let rf = rf | rf-lf | rf-ru +diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c +index 31807791589ee..aaa2c641e7871 100644 +--- a/tools/perf/arch/x86/util/intel-pt.c ++++ b/tools/perf/arch/x86/util/intel-pt.c +@@ -32,6 +32,7 @@ + #include "../../../util/tsc.h" + #include <internal/lib.h> // page_size + #include "../../../util/intel-pt.h" ++#include <api/fs/fs.h> + + #define KiB(x) ((x) * 1024) + #define MiB(x) ((x) * 1024 * 1024) +@@ -436,6 +437,16 @@ static int intel_pt_track_switches(struct evlist *evlist) + } + #endif + ++static bool intel_pt_exclude_guest(void) ++{ ++ int pt_mode; ++ ++ if (sysfs__read_int("module/kvm_intel/parameters/pt_mode", &pt_mode)) ++ pt_mode = 0; ++ ++ return pt_mode == 1; ++} ++ + static void intel_pt_valid_str(char *str, size_t len, u64 valid) + { + unsigned int val, last = 0, state = 1; +@@ -628,6 +639,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr, + } + evsel->core.attr.freq = 0; + evsel->core.attr.sample_period = 1; ++ evsel->core.attr.exclude_guest = intel_pt_exclude_guest(); + evsel->no_aux_samples = true; + evsel->needs_auxtrace_mmap = true; + intel_pt_evsel = evsel; +@@ -766,7 +778,8 @@ static int intel_pt_recording_options(struct auxtrace_record *itr, + } + + if (!opts->auxtrace_snapshot_mode && !opts->auxtrace_sample_mode) { +- u32 aux_watermark = opts->auxtrace_mmap_pages * page_size / 4; ++ size_t aw = opts->auxtrace_mmap_pages * (size_t)page_size / 4; ++ u32 aux_watermark = aw > UINT_MAX ? UINT_MAX : aw; + + intel_pt_evsel->core.attr.aux_watermark = aux_watermark; + } +diff --git a/tools/perf/tests/shell/test_arm_callgraph_fp.sh b/tools/perf/tests/shell/test_arm_callgraph_fp.sh +index 66dfdfdad553f..60cd35c73e47d 100755 +--- a/tools/perf/tests/shell/test_arm_callgraph_fp.sh ++++ b/tools/perf/tests/shell/test_arm_callgraph_fp.sh +@@ -14,28 +14,21 @@ cleanup_files() + + trap cleanup_files EXIT TERM INT + +-# Add a 1 second delay to skip samples that are not in the leaf() function + # shellcheck disable=SC2086 +-perf record -o "$PERF_DATA" --call-graph fp -e cycles//u -D 1000 --user-callchains -- $TEST_PROGRAM 2> /dev/null & +-PID=$! ++perf record -o "$PERF_DATA" --call-graph fp -e cycles//u --user-callchains -- $TEST_PROGRAM + +-echo " + Recording (PID=$PID)..." +-sleep 2 +-echo " + Stopping perf-record..." +- +-kill $PID +-wait $PID ++# Try opening the file so any immediate errors are visible in the log ++perf script -i "$PERF_DATA" -F comm,ip,sym | head -n4 + +-# expected perf-script output: ++# expected perf-script output if 'leaf' has been inserted correctly: + # +-# program ++# perf + # 728 leaf + # 753 parent + # 76c leafloop +-# ... ++# ... remaining stack to main() ... + +-perf script -i "$PERF_DATA" -F comm,ip,sym | head -n4 +-perf script -i "$PERF_DATA" -F comm,ip,sym | head -n4 | \ +- awk '{ if ($2 != "") sym[i++] = $2 } END { if (sym[0] != "leaf" || +- sym[1] != "parent" || +- sym[2] != "leafloop") exit 1 }' ++# Each frame is separated by a tab, some spaces and an address ++SEP="[[:space:]]+ [[:xdigit:]]+" ++perf script -i "$PERF_DATA" -F comm,ip,sym | tr '\n' ' ' | \ ++ grep -E -q "perf $SEP leaf $SEP parent $SEP leafloop" +diff --git a/tools/perf/tests/workloads/leafloop.c b/tools/perf/tests/workloads/leafloop.c +index 1bf5cc97649b0..f7561767e32cd 100644 +--- a/tools/perf/tests/workloads/leafloop.c ++++ b/tools/perf/tests/workloads/leafloop.c +@@ -1,6 +1,8 @@ + /* SPDX-License-Identifier: GPL-2.0 */ ++#include <signal.h> + #include <stdlib.h> + #include <linux/compiler.h> ++#include <unistd.h> + #include "../tests.h" + + /* We want to check these symbols in perf script */ +@@ -8,10 +10,16 @@ noinline void leaf(volatile int b); + noinline void parent(volatile int b); + + static volatile int a; ++static volatile sig_atomic_t done; ++ ++static void sighandler(int sig __maybe_unused) ++{ ++ done = 1; ++} + + noinline void leaf(volatile int b) + { +- for (;;) ++ while (!done) + a += b; + } + +@@ -22,12 +30,16 @@ noinline void parent(volatile int b) + + static int leafloop(int argc, const char **argv) + { +- int c = 1; ++ int sec = 1; + + if (argc > 0) +- c = atoi(argv[0]); ++ sec = atoi(argv[0]); ++ ++ signal(SIGINT, sighandler); ++ signal(SIGALRM, sighandler); ++ alarm(sec); + +- parent(c); ++ parent(sec); + return 0; + } + +diff --git a/tools/perf/util/pmus.c b/tools/perf/util/pmus.c +index cec869cbe163a..54a237b2b8538 100644 +--- a/tools/perf/util/pmus.c ++++ b/tools/perf/util/pmus.c +@@ -470,8 +470,8 @@ void perf_pmus__print_pmu_events(const struct print_callbacks *print_cb, void *p + qsort(aliases, len, sizeof(struct sevent), cmp_sevent); + for (int j = 0; j < len; j++) { + /* Skip duplicates */ +- if (j > 0 && pmu_alias_is_duplicate(&aliases[j], &aliases[j - 1])) +- continue; ++ if (j < len - 1 && pmu_alias_is_duplicate(&aliases[j], &aliases[j + 1])) ++ goto free; + + print_cb->print_event(print_state, + aliases[j].pmu_name, +@@ -484,6 +484,7 @@ void perf_pmus__print_pmu_events(const struct print_callbacks *print_cb, void *p + aliases[j].desc, + aliases[j].long_desc, + aliases[j].encoding_desc); ++free: + zfree(&aliases[j].name); + zfree(&aliases[j].alias); + zfree(&aliases[j].scale_unit); +diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c +index 6aa1c7f2b4448..6ab8147a3f870 100644 +--- a/tools/perf/util/sort.c ++++ b/tools/perf/util/sort.c +@@ -332,7 +332,7 @@ sort__sym_cmp(struct hist_entry *left, struct hist_entry *right) + * comparing symbol address alone is not enough since it's a + * relative address within a dso. + */ +- if (!hists__has(left->hists, dso) || hists__has(right->hists, dso)) { ++ if (!hists__has(left->hists, dso)) { + ret = sort__dso_cmp(left, right); + if (ret != 0) + return ret; +diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c +index cf573ff3fa84f..2affa4d45aa21 100644 +--- a/tools/perf/util/stat-shadow.c ++++ b/tools/perf/util/stat-shadow.c +@@ -176,6 +176,13 @@ static double find_stat(const struct evsel *evsel, int aggr_idx, enum stat_type + if (type != evsel__stat_type(cur)) + continue; + ++ /* ++ * Except the SW CLOCK events, ++ * ignore if not the PMU we're looking for. ++ */ ++ if ((type != STAT_NSECS) && (evsel->pmu != cur->pmu)) ++ continue; ++ + aggr = &cur->stats->aggr[aggr_idx]; + if (type == STAT_NSECS) + return aggr->counts.val; +diff --git a/tools/testing/selftests/bpf/DENYLIST.aarch64 b/tools/testing/selftests/bpf/DENYLIST.aarch64 +index 3babaf3eee5c4..ec6aa58fb1810 100644 +--- a/tools/testing/selftests/bpf/DENYLIST.aarch64 ++++ b/tools/testing/selftests/bpf/DENYLIST.aarch64 +@@ -1,6 +1,5 @@ + bpf_cookie/multi_kprobe_attach_api # kprobe_multi_link_api_subtest:FAIL:fentry_raw_skel_load unexpected error: -3 + bpf_cookie/multi_kprobe_link_api # kprobe_multi_link_api_subtest:FAIL:fentry_raw_skel_load unexpected error: -3 +-fexit_sleep # The test never returns. The remaining tests cannot start. + kprobe_multi_bench_attach # needs CONFIG_FPROBE + kprobe_multi_test # needs CONFIG_FPROBE + module_attach # prog 'kprobe_multi': failed to auto-attach: -95 +diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c b/tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c +index 4aabeaa525d47..d0d9a02415454 100644 +--- a/tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c ++++ b/tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c +@@ -396,7 +396,8 @@ static void test_update_ca(void) + return; + + link = bpf_map__attach_struct_ops(skel->maps.ca_update_1); +- ASSERT_OK_PTR(link, "attach_struct_ops"); ++ if (!ASSERT_OK_PTR(link, "attach_struct_ops")) ++ goto out; + + do_test("tcp_ca_update", NULL); + saved_ca1_cnt = skel->bss->ca1_cnt; +@@ -410,6 +411,7 @@ static void test_update_ca(void) + ASSERT_GT(skel->bss->ca2_cnt, 0, "ca2_ca2_cnt"); + + bpf_link__destroy(link); ++out: + tcp_ca_update__destroy(skel); + } + +@@ -425,7 +427,8 @@ static void test_update_wrong(void) + return; + + link = bpf_map__attach_struct_ops(skel->maps.ca_update_1); +- ASSERT_OK_PTR(link, "attach_struct_ops"); ++ if (!ASSERT_OK_PTR(link, "attach_struct_ops")) ++ goto out; + + do_test("tcp_ca_update", NULL); + saved_ca1_cnt = skel->bss->ca1_cnt; +@@ -438,6 +441,7 @@ static void test_update_wrong(void) + ASSERT_GT(skel->bss->ca1_cnt, saved_ca1_cnt, "ca2_ca1_cnt"); + + bpf_link__destroy(link); ++out: + tcp_ca_update__destroy(skel); + } + +@@ -452,7 +456,8 @@ static void test_mixed_links(void) + return; + + link_nl = bpf_map__attach_struct_ops(skel->maps.ca_no_link); +- ASSERT_OK_PTR(link_nl, "attach_struct_ops_nl"); ++ if (!ASSERT_OK_PTR(link_nl, "attach_struct_ops_nl")) ++ goto out; + + link = bpf_map__attach_struct_ops(skel->maps.ca_update_1); + ASSERT_OK_PTR(link, "attach_struct_ops"); +@@ -465,6 +470,7 @@ static void test_mixed_links(void) + + bpf_link__destroy(link); + bpf_link__destroy(link_nl); ++out: + tcp_ca_update__destroy(skel); + } + +@@ -507,7 +513,8 @@ static void test_link_replace(void) + bpf_link__destroy(link); + + link = bpf_map__attach_struct_ops(skel->maps.ca_update_2); +- ASSERT_OK_PTR(link, "attach_struct_ops_2nd"); ++ if (!ASSERT_OK_PTR(link, "attach_struct_ops_2nd")) ++ goto out; + + /* BPF_F_REPLACE with a wrong old map Fd. It should fail! + * +@@ -530,6 +537,7 @@ static void test_link_replace(void) + + bpf_link__destroy(link); + ++out: + tcp_ca_update__destroy(skel); + } + +diff --git a/tools/testing/selftests/bpf/prog_tests/fexit_sleep.c b/tools/testing/selftests/bpf/prog_tests/fexit_sleep.c +index f949647dbbc21..552a0875ca6db 100644 +--- a/tools/testing/selftests/bpf/prog_tests/fexit_sleep.c ++++ b/tools/testing/selftests/bpf/prog_tests/fexit_sleep.c +@@ -21,13 +21,13 @@ static int do_sleep(void *skel) + } + + #define STACK_SIZE (1024 * 1024) +-static char child_stack[STACK_SIZE]; + + void test_fexit_sleep(void) + { + struct fexit_sleep_lskel *fexit_skel = NULL; + int wstatus, duration = 0; + pid_t cpid; ++ char *child_stack = NULL; + int err, fexit_cnt; + + fexit_skel = fexit_sleep_lskel__open_and_load(); +@@ -38,6 +38,11 @@ void test_fexit_sleep(void) + if (CHECK(err, "fexit_attach", "fexit attach failed: %d\n", err)) + goto cleanup; + ++ child_stack = mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | ++ MAP_ANONYMOUS | MAP_STACK, -1, 0); ++ if (!ASSERT_NEQ(child_stack, MAP_FAILED, "mmap")) ++ goto cleanup; ++ + cpid = clone(do_sleep, child_stack + STACK_SIZE, CLONE_FILES | SIGCHLD, fexit_skel); + if (CHECK(cpid == -1, "clone", "%s\n", strerror(errno))) + goto cleanup; +@@ -78,5 +83,6 @@ void test_fexit_sleep(void) + goto cleanup; + + cleanup: ++ munmap(child_stack, STACK_SIZE); + fexit_sleep_lskel__destroy(fexit_skel); + } +diff --git a/tools/testing/selftests/bpf/prog_tests/sk_lookup.c b/tools/testing/selftests/bpf/prog_tests/sk_lookup.c +index 597d0467a9267..de2466547efe0 100644 +--- a/tools/testing/selftests/bpf/prog_tests/sk_lookup.c ++++ b/tools/testing/selftests/bpf/prog_tests/sk_lookup.c +@@ -994,7 +994,7 @@ static void drop_on_reuseport(const struct test *t) + + err = update_lookup_map(t->sock_map, SERVER_A, server1); + if (err) +- goto detach; ++ goto close_srv1; + + /* second server on destination address we should never reach */ + server2 = make_server(t->sotype, t->connect_to.ip, t->connect_to.port, +diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c b/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c +index f09505f8b0386..53d6ad8c2257e 100644 +--- a/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c ++++ b/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c +@@ -222,7 +222,7 @@ static void test_xdp_adjust_frags_tail_grow(void) + + prog = bpf_object__next_program(obj, NULL); + if (bpf_object__load(obj)) +- return; ++ goto out; + + prog_fd = bpf_program__fd(prog); + +diff --git a/tools/testing/selftests/bpf/progs/btf_dump_test_case_multidim.c b/tools/testing/selftests/bpf/progs/btf_dump_test_case_multidim.c +index ba97165bdb282..a657651eba523 100644 +--- a/tools/testing/selftests/bpf/progs/btf_dump_test_case_multidim.c ++++ b/tools/testing/selftests/bpf/progs/btf_dump_test_case_multidim.c +@@ -14,9 +14,9 @@ typedef int *ptr_arr_t[6]; + + typedef int *ptr_multiarr_t[7][8][9][10]; + +-typedef int * (*fn_ptr_arr_t[11])(); ++typedef int * (*fn_ptr_arr_t[11])(void); + +-typedef int * (*fn_ptr_multiarr_t[12][13])(); ++typedef int * (*fn_ptr_multiarr_t[12][13])(void); + + struct root_struct { + arr_t _1; +diff --git a/tools/testing/selftests/bpf/progs/btf_dump_test_case_syntax.c b/tools/testing/selftests/bpf/progs/btf_dump_test_case_syntax.c +index ad21ee8c7e234..29d01fff32bd2 100644 +--- a/tools/testing/selftests/bpf/progs/btf_dump_test_case_syntax.c ++++ b/tools/testing/selftests/bpf/progs/btf_dump_test_case_syntax.c +@@ -100,7 +100,7 @@ typedef void (*printf_fn_t)(const char *, ...); + * `int -> char *` function and returns pointer to a char. Equivalent: + * typedef char * (*fn_input_t)(int); + * typedef char * (*fn_output_outer_t)(fn_input_t); +- * typedef const fn_output_outer_t (* fn_output_inner_t)(); ++ * typedef const fn_output_outer_t (* fn_output_inner_t)(void); + * typedef const fn_output_inner_t fn_ptr_arr2_t[5]; + */ + /* ----- START-EXPECTED-OUTPUT ----- */ +@@ -127,7 +127,7 @@ typedef void (* (*signal_t)(int, void (*)(int)))(int); + + typedef char * (*fn_ptr_arr1_t[10])(int **); + +-typedef char * (* (* const fn_ptr_arr2_t[5])())(char * (*)(int)); ++typedef char * (* (* const fn_ptr_arr2_t[5])(void))(char * (*)(int)); + + struct struct_w_typedefs { + int_t a; +diff --git a/tools/testing/selftests/bpf/test_sockmap.c b/tools/testing/selftests/bpf/test_sockmap.c +index 43612de44fbf5..a181c0ccf98b2 100644 +--- a/tools/testing/selftests/bpf/test_sockmap.c ++++ b/tools/testing/selftests/bpf/test_sockmap.c +@@ -63,7 +63,7 @@ int passed; + int failed; + int map_fd[9]; + struct bpf_map *maps[9]; +-int prog_fd[11]; ++int prog_fd[9]; + + int txmsg_pass; + int txmsg_redir; +@@ -680,7 +680,8 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt, + } + } + +- s->bytes_recvd += recv; ++ if (recv > 0) ++ s->bytes_recvd += recv; + + if (opt->check_recved_len && s->bytes_recvd > total_bytes) { + errno = EMSGSIZE; +@@ -1793,8 +1794,6 @@ int prog_attach_type[] = { + BPF_SK_MSG_VERDICT, + BPF_SK_MSG_VERDICT, + BPF_SK_MSG_VERDICT, +- BPF_SK_MSG_VERDICT, +- BPF_SK_MSG_VERDICT, + }; + + int prog_type[] = { +@@ -1807,8 +1806,6 @@ int prog_type[] = { + BPF_PROG_TYPE_SK_MSG, + BPF_PROG_TYPE_SK_MSG, + BPF_PROG_TYPE_SK_MSG, +- BPF_PROG_TYPE_SK_MSG, +- BPF_PROG_TYPE_SK_MSG, + }; + + static int populate_progs(char *bpf_file) +diff --git a/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower.sh b/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower.sh +index 616d3581419ca..21d0f419cc6d7 100755 +--- a/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower.sh ++++ b/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower.sh +@@ -11,7 +11,7 @@ ALL_TESTS="single_mask_test identical_filters_test two_masks_test \ + multiple_masks_test ctcam_edge_cases_test delta_simple_test \ + delta_two_masks_one_key_test delta_simple_rehash_test \ + bloom_simple_test bloom_complex_test bloom_delta_test \ +- max_erp_entries_test max_group_size_test" ++ max_erp_entries_test max_group_size_test collision_test" + NUM_NETIFS=2 + source $lib_dir/lib.sh + source $lib_dir/tc_common.sh +@@ -457,7 +457,7 @@ delta_two_masks_one_key_test() + { + # If 2 keys are the same and only differ in mask in a way that + # they belong under the same ERP (second is delta of the first), +- # there should be no C-TCAM spill. ++ # there should be C-TCAM spill. + + RET=0 + +@@ -474,8 +474,8 @@ delta_two_masks_one_key_test() + tp_record "mlxsw:*" "tc filter add dev $h2 ingress protocol ip \ + pref 2 handle 102 flower $tcflags dst_ip 192.0.2.2 \ + action drop" +- tp_check_hits "mlxsw:mlxsw_sp_acl_atcam_entry_add_ctcam_spill" 0 +- check_err $? "incorrect C-TCAM spill while inserting the second rule" ++ tp_check_hits "mlxsw:mlxsw_sp_acl_atcam_entry_add_ctcam_spill" 1 ++ check_err $? "C-TCAM spill did not happen while inserting the second rule" + + $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ + -t ip -q +@@ -1087,6 +1087,53 @@ max_group_size_test() + log_test "max ACL group size test ($tcflags). max size $max_size" + } + ++collision_test() ++{ ++ # Filters cannot share an eRP if in the common unmasked part (i.e., ++ # without the delta bits) they have the same values. If the driver does ++ # not prevent such configuration (by spilling into the C-TCAM), then ++ # multiple entries will be present in the device with the same key, ++ # leading to collisions and a reduced scale. ++ # ++ # Create such a scenario and make sure all the filters are successfully ++ # added. ++ ++ RET=0 ++ ++ local ret ++ ++ if [[ "$tcflags" != "skip_sw" ]]; then ++ return 0; ++ fi ++ ++ # Add a single dst_ip/24 filter and multiple dst_ip/32 filters that all ++ # have the same values in the common unmasked part (dst_ip/24). ++ ++ tc filter add dev $h2 ingress pref 1 proto ipv4 handle 101 \ ++ flower $tcflags dst_ip 198.51.100.0/24 \ ++ action drop ++ ++ for i in {0..255}; do ++ tc filter add dev $h2 ingress pref 2 proto ipv4 \ ++ handle $((102 + i)) \ ++ flower $tcflags dst_ip 198.51.100.${i}/32 \ ++ action drop ++ ret=$? ++ [[ $ret -ne 0 ]] && break ++ done ++ ++ check_err $ret "failed to add all the filters" ++ ++ for i in {255..0}; do ++ tc filter del dev $h2 ingress pref 2 proto ipv4 \ ++ handle $((102 + i)) flower ++ done ++ ++ tc filter del dev $h2 ingress pref 1 proto ipv4 handle 101 flower ++ ++ log_test "collision test ($tcflags)" ++} ++ + setup_prepare() + { + h1=${NETIFS[p1]} +diff --git a/tools/testing/selftests/landlock/base_test.c b/tools/testing/selftests/landlock/base_test.c +index 792c3f0a59b4f..5aa7d2feab100 100644 +--- a/tools/testing/selftests/landlock/base_test.c ++++ b/tools/testing/selftests/landlock/base_test.c +@@ -9,6 +9,7 @@ + #define _GNU_SOURCE + #include <errno.h> + #include <fcntl.h> ++#include <linux/keyctl.h> + #include <linux/landlock.h> + #include <string.h> + #include <sys/prctl.h> +@@ -326,4 +327,77 @@ TEST(ruleset_fd_transfer) + ASSERT_EQ(EXIT_SUCCESS, WEXITSTATUS(status)); + } + ++TEST(cred_transfer) ++{ ++ struct landlock_ruleset_attr ruleset_attr = { ++ .handled_access_fs = LANDLOCK_ACCESS_FS_READ_DIR, ++ }; ++ int ruleset_fd, dir_fd; ++ pid_t child; ++ int status; ++ ++ drop_caps(_metadata); ++ ++ dir_fd = open("/", O_RDONLY | O_DIRECTORY | O_CLOEXEC); ++ EXPECT_LE(0, dir_fd); ++ EXPECT_EQ(0, close(dir_fd)); ++ ++ /* Denies opening directories. */ ++ ruleset_fd = ++ landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); ++ ASSERT_LE(0, ruleset_fd); ++ EXPECT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)); ++ ASSERT_EQ(0, landlock_restrict_self(ruleset_fd, 0)); ++ EXPECT_EQ(0, close(ruleset_fd)); ++ ++ /* Checks ruleset enforcement. */ ++ EXPECT_EQ(-1, open("/", O_RDONLY | O_DIRECTORY | O_CLOEXEC)); ++ EXPECT_EQ(EACCES, errno); ++ ++ /* Needed for KEYCTL_SESSION_TO_PARENT permission checks */ ++ EXPECT_NE(-1, syscall(__NR_keyctl, KEYCTL_JOIN_SESSION_KEYRING, NULL, 0, ++ 0, 0)) ++ { ++ TH_LOG("Failed to join session keyring: %s", strerror(errno)); ++ } ++ ++ child = fork(); ++ ASSERT_LE(0, child); ++ if (child == 0) { ++ /* Checks ruleset enforcement. */ ++ EXPECT_EQ(-1, open("/", O_RDONLY | O_DIRECTORY | O_CLOEXEC)); ++ EXPECT_EQ(EACCES, errno); ++ ++ /* ++ * KEYCTL_SESSION_TO_PARENT is a no-op unless we have a ++ * different session keyring in the child, so make that happen. ++ */ ++ EXPECT_NE(-1, syscall(__NR_keyctl, KEYCTL_JOIN_SESSION_KEYRING, ++ NULL, 0, 0, 0)); ++ ++ /* ++ * KEYCTL_SESSION_TO_PARENT installs credentials on the parent ++ * that never go through the cred_prepare hook, this path uses ++ * cred_transfer instead. ++ */ ++ EXPECT_EQ(0, syscall(__NR_keyctl, KEYCTL_SESSION_TO_PARENT, 0, ++ 0, 0, 0)); ++ ++ /* Re-checks ruleset enforcement. */ ++ EXPECT_EQ(-1, open("/", O_RDONLY | O_DIRECTORY | O_CLOEXEC)); ++ EXPECT_EQ(EACCES, errno); ++ ++ _exit(_metadata->passed ? EXIT_SUCCESS : EXIT_FAILURE); ++ return; ++ } ++ ++ EXPECT_EQ(child, waitpid(child, &status, 0)); ++ EXPECT_EQ(1, WIFEXITED(status)); ++ EXPECT_EQ(EXIT_SUCCESS, WEXITSTATUS(status)); ++ ++ /* Re-checks ruleset enforcement. */ ++ EXPECT_EQ(-1, open("/", O_RDONLY | O_DIRECTORY | O_CLOEXEC)); ++ EXPECT_EQ(EACCES, errno); ++} ++ + TEST_HARNESS_MAIN +diff --git a/tools/testing/selftests/landlock/config b/tools/testing/selftests/landlock/config +index 3dc9e438eab10..efca1c7333670 100644 +--- a/tools/testing/selftests/landlock/config ++++ b/tools/testing/selftests/landlock/config +@@ -1,5 +1,6 @@ + CONFIG_CGROUPS=y + CONFIG_CGROUP_SCHED=y ++CONFIG_KEYS=y + CONFIG_OVERLAY_FS=y + CONFIG_PROC_FS=y + CONFIG_SECURITY=y +diff --git a/tools/testing/selftests/net/fib_tests.sh b/tools/testing/selftests/net/fib_tests.sh +index 66d0db7a2614d..ede2c0ec2a9dd 100755 +--- a/tools/testing/selftests/net/fib_tests.sh ++++ b/tools/testing/selftests/net/fib_tests.sh +@@ -1643,53 +1643,53 @@ ipv4_rt_dsfield() + + # DSCP 0x10 should match the specific route, no matter the ECN bits + $IP route get fibmatch 172.16.102.1 dsfield 0x10 | \ +- grep -q "via 172.16.103.2" ++ grep -q "172.16.102.0/24 tos 0x10 via 172.16.103.2" + log_test $? 0 "IPv4 route with DSCP and ECN:Not-ECT" + + $IP route get fibmatch 172.16.102.1 dsfield 0x11 | \ +- grep -q "via 172.16.103.2" ++ grep -q "172.16.102.0/24 tos 0x10 via 172.16.103.2" + log_test $? 0 "IPv4 route with DSCP and ECN:ECT(1)" + + $IP route get fibmatch 172.16.102.1 dsfield 0x12 | \ +- grep -q "via 172.16.103.2" ++ grep -q "172.16.102.0/24 tos 0x10 via 172.16.103.2" + log_test $? 0 "IPv4 route with DSCP and ECN:ECT(0)" + + $IP route get fibmatch 172.16.102.1 dsfield 0x13 | \ +- grep -q "via 172.16.103.2" ++ grep -q "172.16.102.0/24 tos 0x10 via 172.16.103.2" + log_test $? 0 "IPv4 route with DSCP and ECN:CE" + + # Unknown DSCP should match the generic route, no matter the ECN bits + $IP route get fibmatch 172.16.102.1 dsfield 0x14 | \ +- grep -q "via 172.16.101.2" ++ grep -q "172.16.102.0/24 via 172.16.101.2" + log_test $? 0 "IPv4 route with unknown DSCP and ECN:Not-ECT" + + $IP route get fibmatch 172.16.102.1 dsfield 0x15 | \ +- grep -q "via 172.16.101.2" ++ grep -q "172.16.102.0/24 via 172.16.101.2" + log_test $? 0 "IPv4 route with unknown DSCP and ECN:ECT(1)" + + $IP route get fibmatch 172.16.102.1 dsfield 0x16 | \ +- grep -q "via 172.16.101.2" ++ grep -q "172.16.102.0/24 via 172.16.101.2" + log_test $? 0 "IPv4 route with unknown DSCP and ECN:ECT(0)" + + $IP route get fibmatch 172.16.102.1 dsfield 0x17 | \ +- grep -q "via 172.16.101.2" ++ grep -q "172.16.102.0/24 via 172.16.101.2" + log_test $? 0 "IPv4 route with unknown DSCP and ECN:CE" + + # Null DSCP should match the generic route, no matter the ECN bits + $IP route get fibmatch 172.16.102.1 dsfield 0x00 | \ +- grep -q "via 172.16.101.2" ++ grep -q "172.16.102.0/24 via 172.16.101.2" + log_test $? 0 "IPv4 route with no DSCP and ECN:Not-ECT" + + $IP route get fibmatch 172.16.102.1 dsfield 0x01 | \ +- grep -q "via 172.16.101.2" ++ grep -q "172.16.102.0/24 via 172.16.101.2" + log_test $? 0 "IPv4 route with no DSCP and ECN:ECT(1)" + + $IP route get fibmatch 172.16.102.1 dsfield 0x02 | \ +- grep -q "via 172.16.101.2" ++ grep -q "172.16.102.0/24 via 172.16.101.2" + log_test $? 0 "IPv4 route with no DSCP and ECN:ECT(0)" + + $IP route get fibmatch 172.16.102.1 dsfield 0x03 | \ +- grep -q "via 172.16.101.2" ++ grep -q "172.16.102.0/24 via 172.16.101.2" + log_test $? 0 "IPv4 route with no DSCP and ECN:CE" + } + +diff --git a/tools/testing/selftests/net/forwarding/devlink_lib.sh b/tools/testing/selftests/net/forwarding/devlink_lib.sh +index f1de525cfa55b..62a05bca1e825 100644 +--- a/tools/testing/selftests/net/forwarding/devlink_lib.sh ++++ b/tools/testing/selftests/net/forwarding/devlink_lib.sh +@@ -122,6 +122,8 @@ devlink_reload() + still_pending=$(devlink resource show "$DEVLINK_DEV" | \ + grep -c "size_new") + check_err $still_pending "Failed reload - There are still unset sizes" ++ ++ udevadm settle + } + + declare -A DEVLINK_ORIG +diff --git a/tools/testing/selftests/resctrl/cache.c b/tools/testing/selftests/resctrl/cache.c +index a0318bd3a63d8..601ab78dbf421 100644 +--- a/tools/testing/selftests/resctrl/cache.c ++++ b/tools/testing/selftests/resctrl/cache.c +@@ -40,7 +40,7 @@ static int perf_event_open_llc_miss(pid_t pid, int cpu_no) + fd_lm = perf_event_open(&pea_llc_miss, pid, cpu_no, -1, + PERF_FLAG_FD_CLOEXEC); + if (fd_lm == -1) { +- perror("Error opening leader"); ++ ksft_perror("Error opening leader"); + ctrlc_handler(0, NULL, NULL); + return -1; + } +@@ -95,7 +95,7 @@ static int get_llc_perf(unsigned long *llc_perf_miss) + + ret = read(fd_lm, &rf_cqm, sizeof(struct read_format)); + if (ret == -1) { +- perror("Could not get llc misses through perf"); ++ ksft_perror("Could not get llc misses through perf"); + return -1; + } + +@@ -124,12 +124,12 @@ static int get_llc_occu_resctrl(unsigned long *llc_occupancy) + + fp = fopen(llc_occup_path, "r"); + if (!fp) { +- perror("Failed to open results file"); ++ ksft_perror("Failed to open results file"); + + return errno; + } + if (fscanf(fp, "%lu", llc_occupancy) <= 0) { +- perror("Could not get llc occupancy"); ++ ksft_perror("Could not get llc occupancy"); + fclose(fp); + + return -1; +@@ -159,7 +159,7 @@ static int print_results_cache(char *filename, int bm_pid, + } else { + fp = fopen(filename, "a"); + if (!fp) { +- perror("Cannot open results file"); ++ ksft_perror("Cannot open results file"); + + return errno; + } +diff --git a/tools/testing/selftests/resctrl/cat_test.c b/tools/testing/selftests/resctrl/cat_test.c +index 224ba8544d8af..9bb8ba93f4335 100644 +--- a/tools/testing/selftests/resctrl/cat_test.c ++++ b/tools/testing/selftests/resctrl/cat_test.c +@@ -51,7 +51,7 @@ static int check_results(struct resctrl_val_param *param, size_t span) + ksft_print_msg("Checking for pass/fail\n"); + fp = fopen(param->filename, "r"); + if (!fp) { +- perror("# Cannot open file"); ++ ksft_perror("Cannot open file"); + + return errno; + } +@@ -149,7 +149,7 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type) + param.num_of_runs = 0; + + if (pipe(pipefd)) { +- perror("# Unable to create pipe"); ++ ksft_perror("Unable to create pipe"); + return errno; + } + +@@ -185,7 +185,7 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type) + * Just print the error message. + * Let while(1) run and wait for itself to be killed. + */ +- perror("# failed signaling parent process"); ++ ksft_perror("Failed signaling parent process"); + + close(pipefd[1]); + while (1) +@@ -197,7 +197,7 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type) + while (pipe_message != 1) { + if (read(pipefd[0], &pipe_message, + sizeof(pipe_message)) < sizeof(pipe_message)) { +- perror("# failed reading from child process"); ++ ksft_perror("Failed reading from child process"); + break; + } + } +diff --git a/tools/testing/selftests/resctrl/cmt_test.c b/tools/testing/selftests/resctrl/cmt_test.c +index 50bdbce9fba95..16fc0488e0a54 100644 +--- a/tools/testing/selftests/resctrl/cmt_test.c ++++ b/tools/testing/selftests/resctrl/cmt_test.c +@@ -37,7 +37,7 @@ static int check_results(struct resctrl_val_param *param, size_t span, int no_of + ksft_print_msg("Checking for pass/fail\n"); + fp = fopen(param->filename, "r"); + if (!fp) { +- perror("# Error in opening file\n"); ++ ksft_perror("Error in opening file"); + + return errno; + } +diff --git a/tools/testing/selftests/resctrl/fill_buf.c b/tools/testing/selftests/resctrl/fill_buf.c +index 0d425f26583a9..0f6cca61ec94b 100644 +--- a/tools/testing/selftests/resctrl/fill_buf.c ++++ b/tools/testing/selftests/resctrl/fill_buf.c +@@ -115,7 +115,7 @@ static int fill_cache_read(unsigned char *buf, size_t buf_size, bool once) + /* Consume read result so that reading memory is not optimized out. */ + fp = fopen("/dev/null", "w"); + if (!fp) { +- perror("Unable to write to /dev/null"); ++ ksft_perror("Unable to write to /dev/null"); + return -1; + } + fprintf(fp, "Sum: %d ", ret); +diff --git a/tools/testing/selftests/resctrl/mba_test.c b/tools/testing/selftests/resctrl/mba_test.c +index d3bf4368341ec..4988b93add6a7 100644 +--- a/tools/testing/selftests/resctrl/mba_test.c ++++ b/tools/testing/selftests/resctrl/mba_test.c +@@ -109,7 +109,7 @@ static int check_results(void) + + fp = fopen(output, "r"); + if (!fp) { +- perror(output); ++ ksft_perror(output); + + return errno; + } +diff --git a/tools/testing/selftests/resctrl/mbm_test.c b/tools/testing/selftests/resctrl/mbm_test.c +index d3c0d30c676a7..eb488aabb9ae6 100644 +--- a/tools/testing/selftests/resctrl/mbm_test.c ++++ b/tools/testing/selftests/resctrl/mbm_test.c +@@ -59,7 +59,7 @@ static int check_results(size_t span) + + fp = fopen(output, "r"); + if (!fp) { +- perror(output); ++ ksft_perror(output); + + return errno; + } +diff --git a/tools/testing/selftests/resctrl/resctrl.h b/tools/testing/selftests/resctrl/resctrl.h +index 8578a8b4e1459..dd3546655657a 100644 +--- a/tools/testing/selftests/resctrl/resctrl.h ++++ b/tools/testing/selftests/resctrl/resctrl.h +@@ -37,9 +37,8 @@ + + #define DEFAULT_SPAN (250 * MB) + +-#define PARENT_EXIT(err_msg) \ ++#define PARENT_EXIT() \ + do { \ +- perror(err_msg); \ + kill(ppid, SIGKILL); \ + umount_resctrlfs(); \ + exit(EXIT_FAILURE); \ +@@ -86,7 +85,6 @@ int validate_bw_report_request(char *bw_report); + bool validate_resctrl_feature_request(const char *resource, const char *feature); + char *fgrep(FILE *inf, const char *str); + int taskset_benchmark(pid_t bm_pid, int cpu_no); +-void run_benchmark(int signum, siginfo_t *info, void *ucontext); + int write_schemata(char *ctrlgrp, char *schemata, int cpu_no, + char *resctrl_val); + int write_bm_pid_to_resctrl(pid_t bm_pid, char *ctrlgrp, char *mongrp, +diff --git a/tools/testing/selftests/resctrl/resctrl_val.c b/tools/testing/selftests/resctrl/resctrl_val.c +index b8ca6fa40b3bf..45439e726e79c 100644 +--- a/tools/testing/selftests/resctrl/resctrl_val.c ++++ b/tools/testing/selftests/resctrl/resctrl_val.c +@@ -156,12 +156,12 @@ static int read_from_imc_dir(char *imc_dir, int count) + sprintf(imc_counter_type, "%s%s", imc_dir, "type"); + fp = fopen(imc_counter_type, "r"); + if (!fp) { +- perror("Failed to open imc counter type file"); ++ ksft_perror("Failed to open iMC counter type file"); + + return -1; + } + if (fscanf(fp, "%u", &imc_counters_config[count][READ].type) <= 0) { +- perror("Could not get imc type"); ++ ksft_perror("Could not get iMC type"); + fclose(fp); + + return -1; +@@ -175,12 +175,12 @@ static int read_from_imc_dir(char *imc_dir, int count) + sprintf(imc_counter_cfg, "%s%s", imc_dir, READ_FILE_NAME); + fp = fopen(imc_counter_cfg, "r"); + if (!fp) { +- perror("Failed to open imc config file"); ++ ksft_perror("Failed to open iMC config file"); + + return -1; + } + if (fscanf(fp, "%s", cas_count_cfg) <= 0) { +- perror("Could not get imc cas count read"); ++ ksft_perror("Could not get iMC cas count read"); + fclose(fp); + + return -1; +@@ -193,12 +193,12 @@ static int read_from_imc_dir(char *imc_dir, int count) + sprintf(imc_counter_cfg, "%s%s", imc_dir, WRITE_FILE_NAME); + fp = fopen(imc_counter_cfg, "r"); + if (!fp) { +- perror("Failed to open imc config file"); ++ ksft_perror("Failed to open iMC config file"); + + return -1; + } + if (fscanf(fp, "%s", cas_count_cfg) <= 0) { +- perror("Could not get imc cas count write"); ++ ksft_perror("Could not get iMC cas count write"); + fclose(fp); + + return -1; +@@ -262,12 +262,12 @@ static int num_of_imcs(void) + } + closedir(dp); + if (count == 0) { +- perror("Unable find iMC counters!\n"); ++ ksft_print_msg("Unable to find iMC counters\n"); + + return -1; + } + } else { +- perror("Unable to open PMU directory!\n"); ++ ksft_perror("Unable to open PMU directory"); + + return -1; + } +@@ -292,6 +292,18 @@ static int initialize_mem_bw_imc(void) + return 0; + } + ++static void perf_close_imc_mem_bw(void) ++{ ++ int mc; ++ ++ for (mc = 0; mc < imcs; mc++) { ++ if (imc_counters_config[mc][READ].fd != -1) ++ close(imc_counters_config[mc][READ].fd); ++ if (imc_counters_config[mc][WRITE].fd != -1) ++ close(imc_counters_config[mc][WRITE].fd); ++ } ++} ++ + /* + * get_mem_bw_imc: Memory band width as reported by iMC counters + * @cpu_no: CPU number that the benchmark PID is binded to +@@ -305,26 +317,33 @@ static int initialize_mem_bw_imc(void) + static int get_mem_bw_imc(int cpu_no, char *bw_report, float *bw_imc) + { + float reads, writes, of_mul_read, of_mul_write; +- int imc, j, ret; ++ int imc, ret; ++ ++ for (imc = 0; imc < imcs; imc++) { ++ imc_counters_config[imc][READ].fd = -1; ++ imc_counters_config[imc][WRITE].fd = -1; ++ } + + /* Start all iMC counters to log values (both read and write) */ + reads = 0, writes = 0, of_mul_read = 1, of_mul_write = 1; + for (imc = 0; imc < imcs; imc++) { +- for (j = 0; j < 2; j++) { +- ret = open_perf_event(imc, cpu_no, j); +- if (ret) +- return -1; +- } +- for (j = 0; j < 2; j++) +- membw_ioctl_perf_event_ioc_reset_enable(imc, j); ++ ret = open_perf_event(imc, cpu_no, READ); ++ if (ret) ++ goto close_fds; ++ ret = open_perf_event(imc, cpu_no, WRITE); ++ if (ret) ++ goto close_fds; ++ ++ membw_ioctl_perf_event_ioc_reset_enable(imc, READ); ++ membw_ioctl_perf_event_ioc_reset_enable(imc, WRITE); + } + + sleep(1); + + /* Stop counters after a second to get results (both read and write) */ + for (imc = 0; imc < imcs; imc++) { +- for (j = 0; j < 2; j++) +- membw_ioctl_perf_event_ioc_disable(imc, j); ++ membw_ioctl_perf_event_ioc_disable(imc, READ); ++ membw_ioctl_perf_event_ioc_disable(imc, WRITE); + } + + /* +@@ -339,16 +358,14 @@ static int get_mem_bw_imc(int cpu_no, char *bw_report, float *bw_imc) + + if (read(r->fd, &r->return_value, + sizeof(struct membw_read_format)) == -1) { +- perror("Couldn't get read b/w through iMC"); +- +- return -1; ++ ksft_perror("Couldn't get read b/w through iMC"); ++ goto close_fds; + } + + if (read(w->fd, &w->return_value, + sizeof(struct membw_read_format)) == -1) { +- perror("Couldn't get write bw through iMC"); +- +- return -1; ++ ksft_perror("Couldn't get write bw through iMC"); ++ goto close_fds; + } + + __u64 r_time_enabled = r->return_value.time_enabled; +@@ -368,10 +385,7 @@ static int get_mem_bw_imc(int cpu_no, char *bw_report, float *bw_imc) + writes += w->return_value.value * of_mul_write * SCALE; + } + +- for (imc = 0; imc < imcs; imc++) { +- close(imc_counters_config[imc][READ].fd); +- close(imc_counters_config[imc][WRITE].fd); +- } ++ perf_close_imc_mem_bw(); + + if (strcmp(bw_report, "reads") == 0) { + *bw_imc = reads; +@@ -385,6 +399,10 @@ static int get_mem_bw_imc(int cpu_no, char *bw_report, float *bw_imc) + + *bw_imc = reads + writes; + return 0; ++ ++close_fds: ++ perf_close_imc_mem_bw(); ++ return -1; + } + + void set_mbm_path(const char *ctrlgrp, const char *mongrp, int resource_id) +@@ -416,7 +434,7 @@ static void initialize_mem_bw_resctrl(const char *ctrlgrp, const char *mongrp, + int resource_id; + + if (get_resource_id(cpu_no, &resource_id) < 0) { +- perror("Could not get resource_id"); ++ ksft_print_msg("Could not get resource_id\n"); + return; + } + +@@ -449,12 +467,12 @@ static int get_mem_bw_resctrl(unsigned long *mbm_total) + + fp = fopen(mbm_total_path, "r"); + if (!fp) { +- perror("Failed to open total bw file"); ++ ksft_perror("Failed to open total bw file"); + + return -1; + } + if (fscanf(fp, "%lu", mbm_total) <= 0) { +- perror("Could not get mbm local bytes"); ++ ksft_perror("Could not get mbm local bytes"); + fclose(fp); + + return -1; +@@ -495,7 +513,7 @@ int signal_handler_register(void) + if (sigaction(SIGINT, &sigact, NULL) || + sigaction(SIGTERM, &sigact, NULL) || + sigaction(SIGHUP, &sigact, NULL)) { +- perror("# sigaction"); ++ ksft_perror("sigaction"); + ret = -1; + } + return ret; +@@ -515,7 +533,7 @@ void signal_handler_unregister(void) + if (sigaction(SIGINT, &sigact, NULL) || + sigaction(SIGTERM, &sigact, NULL) || + sigaction(SIGHUP, &sigact, NULL)) { +- perror("# sigaction"); ++ ksft_perror("sigaction"); + } + } + +@@ -540,14 +558,14 @@ static int print_results_bw(char *filename, int bm_pid, float bw_imc, + } else { + fp = fopen(filename, "a"); + if (!fp) { +- perror("Cannot open results file"); ++ ksft_perror("Cannot open results file"); + + return errno; + } + if (fprintf(fp, "Pid: %d \t Mem_BW_iMC: %f \t Mem_BW_resc: %lu \t Difference: %lu\n", + bm_pid, bw_imc, bw_resc, diff) <= 0) { ++ ksft_print_msg("Could not log results\n"); + fclose(fp); +- perror("Could not log results."); + + return errno; + } +@@ -585,7 +603,7 @@ static void initialize_llc_occu_resctrl(const char *ctrlgrp, const char *mongrp, + int resource_id; + + if (get_resource_id(cpu_no, &resource_id) < 0) { +- perror("# Unable to resource_id"); ++ ksft_print_msg("Could not get resource_id\n"); + return; + } + +@@ -625,6 +643,61 @@ measure_vals(struct resctrl_val_param *param, unsigned long *bw_resc_start) + return 0; + } + ++/* ++ * run_benchmark - Run a specified benchmark or fill_buf (default benchmark) ++ * in specified signal. Direct benchmark stdio to /dev/null. ++ * @signum: signal number ++ * @info: signal info ++ * @ucontext: user context in signal handling ++ */ ++static void run_benchmark(int signum, siginfo_t *info, void *ucontext) ++{ ++ int operation, ret, memflush; ++ char **benchmark_cmd; ++ size_t span; ++ bool once; ++ FILE *fp; ++ ++ benchmark_cmd = info->si_ptr; ++ ++ /* ++ * Direct stdio of child to /dev/null, so that only parent writes to ++ * stdio (console) ++ */ ++ fp = freopen("/dev/null", "w", stdout); ++ if (!fp) { ++ ksft_perror("Unable to direct benchmark status to /dev/null"); ++ PARENT_EXIT(); ++ } ++ ++ if (strcmp(benchmark_cmd[0], "fill_buf") == 0) { ++ /* Execute default fill_buf benchmark */ ++ span = strtoul(benchmark_cmd[1], NULL, 10); ++ memflush = atoi(benchmark_cmd[2]); ++ operation = atoi(benchmark_cmd[3]); ++ if (!strcmp(benchmark_cmd[4], "true")) { ++ once = true; ++ } else if (!strcmp(benchmark_cmd[4], "false")) { ++ once = false; ++ } else { ++ ksft_print_msg("Invalid once parameter\n"); ++ PARENT_EXIT(); ++ } ++ ++ if (run_fill_buf(span, memflush, operation, once)) ++ fprintf(stderr, "Error in running fill buffer\n"); ++ } else { ++ /* Execute specified benchmark */ ++ ret = execvp(benchmark_cmd[0], benchmark_cmd); ++ if (ret) ++ ksft_perror("execvp"); ++ } ++ ++ fclose(stdout); ++ ksft_print_msg("Unable to run specified benchmark\n"); ++ PARENT_EXIT(); ++} ++ + /* + * resctrl_val: execute benchmark and measure memory bandwidth on + * the benchmark +@@ -659,7 +732,7 @@ int resctrl_val(const char * const *benchmark_cmd, struct resctrl_val_param *par + ppid = getpid(); + + if (pipe(pipefd)) { +- perror("# Unable to create pipe"); ++ ksft_perror("Unable to create pipe"); + + return -1; + } +@@ -671,7 +744,7 @@ int resctrl_val(const char * const *benchmark_cmd, struct resctrl_val_param *par + fflush(stdout); + bm_pid = fork(); + if (bm_pid == -1) { +- perror("# Unable to fork"); ++ ksft_perror("Unable to fork"); + + return -1; + } +@@ -688,15 +761,17 @@ int resctrl_val(const char * const *benchmark_cmd, struct resctrl_val_param *par + sigact.sa_flags = SA_SIGINFO; + + /* Register for "SIGUSR1" signal from parent */ +- if (sigaction(SIGUSR1, &sigact, NULL)) +- PARENT_EXIT("Can't register child for signal"); ++ if (sigaction(SIGUSR1, &sigact, NULL)) { ++ ksft_perror("Can't register child for signal"); ++ PARENT_EXIT(); ++ } + + /* Tell parent that child is ready */ + close(pipefd[0]); + pipe_message = 1; + if (write(pipefd[1], &pipe_message, sizeof(pipe_message)) < + sizeof(pipe_message)) { +- perror("# failed signaling parent process"); ++ ksft_perror("Failed signaling parent process"); + close(pipefd[1]); + return -1; + } +@@ -705,7 +780,8 @@ int resctrl_val(const char * const *benchmark_cmd, struct resctrl_val_param *par + /* Suspend child until delivery of "SIGUSR1" from parent */ + sigsuspend(&sigact.sa_mask); + +- PARENT_EXIT("Child is done"); ++ ksft_perror("Child is done"); ++ PARENT_EXIT(); + } + + ksft_print_msg("Benchmark PID: %d\n", bm_pid); +@@ -746,7 +822,7 @@ int resctrl_val(const char * const *benchmark_cmd, struct resctrl_val_param *par + while (pipe_message != 1) { + if (read(pipefd[0], &pipe_message, sizeof(pipe_message)) < + sizeof(pipe_message)) { +- perror("# failed reading message from child process"); ++ ksft_perror("Failed reading message from child process"); + close(pipefd[0]); + goto out; + } +@@ -755,7 +831,7 @@ int resctrl_val(const char * const *benchmark_cmd, struct resctrl_val_param *par + + /* Signal child to start benchmark */ + if (sigqueue(bm_pid, SIGUSR1, value) == -1) { +- perror("# sigqueue SIGUSR1 to child"); ++ ksft_perror("sigqueue SIGUSR1 to child"); + ret = errno; + goto out; + } +diff --git a/tools/testing/selftests/resctrl/resctrlfs.c b/tools/testing/selftests/resctrl/resctrlfs.c +index 3a8111362d262..71ad2b335b83f 100644 +--- a/tools/testing/selftests/resctrl/resctrlfs.c ++++ b/tools/testing/selftests/resctrl/resctrlfs.c +@@ -19,7 +19,7 @@ static int find_resctrl_mount(char *buffer) + + mounts = fopen("/proc/mounts", "r"); + if (!mounts) { +- perror("/proc/mounts"); ++ ksft_perror("/proc/mounts"); + return -ENXIO; + } + while (!feof(mounts)) { +@@ -68,7 +68,7 @@ int mount_resctrlfs(void) + ksft_print_msg("Mounting resctrl to \"%s\"\n", RESCTRL_PATH); + ret = mount("resctrl", RESCTRL_PATH, "resctrl", 0, NULL); + if (ret) +- perror("# mount"); ++ ksft_perror("mount"); + + return ret; + } +@@ -85,7 +85,7 @@ int umount_resctrlfs(void) + return ret; + + if (umount(mountpoint)) { +- perror("# Unable to umount resctrl"); ++ ksft_perror("Unable to umount resctrl"); + + return errno; + } +@@ -114,12 +114,12 @@ int get_resource_id(int cpu_no, int *resource_id) + + fp = fopen(phys_pkg_path, "r"); + if (!fp) { +- perror("Failed to open physical_package_id"); ++ ksft_perror("Failed to open physical_package_id"); + + return -1; + } + if (fscanf(fp, "%d", resource_id) <= 0) { +- perror("Could not get socket number or l3 id"); ++ ksft_perror("Could not get socket number or l3 id"); + fclose(fp); + + return -1; +@@ -148,7 +148,7 @@ int get_cache_size(int cpu_no, char *cache_type, unsigned long *cache_size) + } else if (!strcmp(cache_type, "L2")) { + cache_num = 2; + } else { +- perror("Invalid cache level"); ++ ksft_print_msg("Invalid cache level\n"); + return -1; + } + +@@ -156,12 +156,12 @@ int get_cache_size(int cpu_no, char *cache_type, unsigned long *cache_size) + cpu_no, cache_num); + fp = fopen(cache_path, "r"); + if (!fp) { +- perror("Failed to open cache size"); ++ ksft_perror("Failed to open cache size"); + + return -1; + } + if (fscanf(fp, "%s", cache_str) <= 0) { +- perror("Could not get cache_size"); ++ ksft_perror("Could not get cache_size"); + fclose(fp); + + return -1; +@@ -213,12 +213,12 @@ int get_cbm_mask(char *cache_type, char *cbm_mask) + + fp = fopen(cbm_mask_path, "r"); + if (!fp) { +- perror("Failed to open cache level"); ++ ksft_perror("Failed to open cache level"); + + return -1; + } + if (fscanf(fp, "%s", cbm_mask) <= 0) { +- perror("Could not get max cbm_mask"); ++ ksft_perror("Could not get max cbm_mask"); + fclose(fp); + + return -1; +@@ -245,12 +245,12 @@ int get_core_sibling(int cpu_no) + + fp = fopen(core_siblings_path, "r"); + if (!fp) { +- perror("Failed to open core siblings path"); ++ ksft_perror("Failed to open core siblings path"); + + return -1; + } + if (fscanf(fp, "%s", cpu_list_str) <= 0) { +- perror("Could not get core_siblings list"); ++ ksft_perror("Could not get core_siblings list"); + fclose(fp); + + return -1; +@@ -285,7 +285,7 @@ int taskset_benchmark(pid_t bm_pid, int cpu_no) + CPU_SET(cpu_no, &my_set); + + if (sched_setaffinity(bm_pid, sizeof(cpu_set_t), &my_set)) { +- perror("Unable to taskset benchmark"); ++ ksft_perror("Unable to taskset benchmark"); + + return -1; + } +@@ -293,58 +293,6 @@ int taskset_benchmark(pid_t bm_pid, int cpu_no) + return 0; + } + +-/* +- * run_benchmark - Run a specified benchmark or fill_buf (default benchmark) +- * in specified signal. Direct benchmark stdio to /dev/null. +- * @signum: signal number +- * @info: signal info +- * @ucontext: user context in signal handling +- * +- * Return: void +- */ +-void run_benchmark(int signum, siginfo_t *info, void *ucontext) +-{ +- int operation, ret, memflush; +- char **benchmark_cmd; +- size_t span; +- bool once; +- FILE *fp; +- +- benchmark_cmd = info->si_ptr; +- +- /* +- * Direct stdio of child to /dev/null, so that only parent writes to +- * stdio (console) +- */ +- fp = freopen("/dev/null", "w", stdout); +- if (!fp) +- PARENT_EXIT("Unable to direct benchmark status to /dev/null"); +- +- if (strcmp(benchmark_cmd[0], "fill_buf") == 0) { +- /* Execute default fill_buf benchmark */ +- span = strtoul(benchmark_cmd[1], NULL, 10); +- memflush = atoi(benchmark_cmd[2]); +- operation = atoi(benchmark_cmd[3]); +- if (!strcmp(benchmark_cmd[4], "true")) +- once = true; +- else if (!strcmp(benchmark_cmd[4], "false")) +- once = false; +- else +- PARENT_EXIT("Invalid once parameter"); +- +- if (run_fill_buf(span, memflush, operation, once)) +- fprintf(stderr, "Error in running fill buffer\n"); +- } else { +- /* Execute specified benchmark */ +- ret = execvp(benchmark_cmd[0], benchmark_cmd); +- if (ret) +- perror("wrong\n"); +- } +- +- fclose(stdout); +- PARENT_EXIT("Unable to run specified benchmark"); +-} +- + /* + * create_grp - Create a group only if one doesn't exist + * @grp_name: Name of the group +@@ -376,7 +324,7 @@ static int create_grp(const char *grp_name, char *grp, const char *parent_grp) + } + closedir(dp); + } else { +- perror("Unable to open resctrl for group"); ++ ksft_perror("Unable to open resctrl for group"); + + return -1; + } +@@ -384,7 +332,7 @@ static int create_grp(const char *grp_name, char *grp, const char *parent_grp) + /* Requested grp doesn't exist, hence create it */ + if (found_grp == 0) { + if (mkdir(grp, 0) == -1) { +- perror("Unable to create group"); ++ ksft_perror("Unable to create group"); + + return -1; + } +@@ -399,12 +347,12 @@ static int write_pid_to_tasks(char *tasks, pid_t pid) + + fp = fopen(tasks, "w"); + if (!fp) { +- perror("Failed to open tasks file"); ++ ksft_perror("Failed to open tasks file"); + + return -1; + } + if (fprintf(fp, "%d\n", pid) < 0) { +- perror("Failed to wr pid to tasks file"); ++ ksft_print_msg("Failed to write pid to tasks file\n"); + fclose(fp); + + return -1; +@@ -471,7 +419,7 @@ int write_bm_pid_to_resctrl(pid_t bm_pid, char *ctrlgrp, char *mongrp, + out: + ksft_print_msg("Writing benchmark parameters to resctrl FS\n"); + if (ret) +- perror("# writing to resctrlfs"); ++ ksft_print_msg("Failed writing to resctrlfs\n"); + + return ret; + } +@@ -658,7 +606,7 @@ int filter_dmesg(void) + + ret = pipe(pipefds); + if (ret) { +- perror("pipe"); ++ ksft_perror("pipe"); + return ret; + } + fflush(stdout); +@@ -667,13 +615,13 @@ int filter_dmesg(void) + close(pipefds[0]); + dup2(pipefds[1], STDOUT_FILENO); + execlp("dmesg", "dmesg", NULL); +- perror("executing dmesg"); ++ ksft_perror("Executing dmesg"); + exit(1); + } + close(pipefds[1]); + fp = fdopen(pipefds[0], "r"); + if (!fp) { +- perror("fdopen(pipe)"); ++ ksft_perror("fdopen(pipe)"); + kill(pid, SIGTERM); + + return -1; +diff --git a/tools/testing/selftests/sigaltstack/current_stack_pointer.h b/tools/testing/selftests/sigaltstack/current_stack_pointer.h +index ea9bdf3a90b16..09da8f1011ce4 100644 +--- a/tools/testing/selftests/sigaltstack/current_stack_pointer.h ++++ b/tools/testing/selftests/sigaltstack/current_stack_pointer.h +@@ -8,7 +8,7 @@ register unsigned long sp asm("sp"); + register unsigned long sp asm("esp"); + #elif __loongarch64 + register unsigned long sp asm("$sp"); +-#elif __ppc__ ++#elif __powerpc__ + register unsigned long sp asm("r1"); + #elif __s390x__ + register unsigned long sp asm("%15"); diff --git a/2950_jump-label-fix.patch b/2950_jump-label-fix.patch new file mode 100644 index 00000000..1a5fdf7a --- /dev/null +++ b/2950_jump-label-fix.patch @@ -0,0 +1,57 @@ +From 224fa3552029a3d14bec7acf72ded8171d551b88 Mon Sep 17 00:00:00 2001 +From: Peter Zijlstra <peterz@infradead.org> +Date: Wed, 31 Jul 2024 12:43:21 +0200 +Subject: jump_label: Fix the fix, brown paper bags galore + +Per the example of: + + !atomic_cmpxchg(&key->enabled, 0, 1) + +the inverse was written as: + + atomic_cmpxchg(&key->enabled, 1, 0) + +except of course, that while !old is only true for old == 0, old is +true for everything except old == 0. + +Fix it to read: + + atomic_cmpxchg(&key->enabled, 1, 0) == 1 + +such that only the 1->0 transition returns true and goes on to disable +the keys. + +Fixes: 83ab38ef0a0b ("jump_label: Fix concurrency issues in static_key_slow_dec()") +Reported-by: Darrick J. Wong <djwong@kernel.org> +Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> +Tested-by: Darrick J. Wong <djwong@kernel.org> +Link: https://lkml.kernel.org/r/20240731105557.GY33588@noisy.programming.kicks-ass.net +--- + kernel/jump_label.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/kernel/jump_label.c b/kernel/jump_label.c +index 4ad5ed8adf9691..6dc76b590703ed 100644 +--- a/kernel/jump_label.c ++++ b/kernel/jump_label.c +@@ -236,7 +236,7 @@ void static_key_disable_cpuslocked(struct static_key *key) + } + + jump_label_lock(); +- if (atomic_cmpxchg(&key->enabled, 1, 0)) ++ if (atomic_cmpxchg(&key->enabled, 1, 0) == 1) + jump_label_update(key); + jump_label_unlock(); + } +@@ -289,7 +289,7 @@ static void __static_key_slow_dec_cpuslocked(struct static_key *key) + return; + + guard(mutex)(&jump_label_mutex); +- if (atomic_cmpxchg(&key->enabled, 1, 0)) ++ if (atomic_cmpxchg(&key->enabled, 1, 0) == 1) + jump_label_update(key); + else + WARN_ON_ONCE(!static_key_slow_try_dec(key)); +-- +cgit 1.2.3-korg + |