diff options
author | 2024-01-25 19:09:15 -0500 | |
---|---|---|
committer | 2024-01-25 19:09:15 -0500 | |
commit | 4ff558e4765fc0dcce52c13d5bfca05ae404063e (patch) | |
tree | 797d6d10f076e854792c0606c862a7f4e84ff9e5 | |
parent | Linux patch 6.1 (diff) | |
download | linux-patches-4ff558e4765fc0dcce52c13d5bfca05ae404063e.tar.gz linux-patches-4ff558e4765fc0dcce52c13d5bfca05ae404063e.tar.bz2 linux-patches-4ff558e4765fc0dcce52c13d5bfca05ae404063e.zip |
Linux patch 6.1.756.1-84
Signed-off-by: Mike Pagano <mpagano@gentoo.org>
-rw-r--r-- | 0000_README | 4 | ||||
-rw-r--r-- | 1074_linux-6.1.75.patch | 15017 |
2 files changed, 15021 insertions, 0 deletions
diff --git a/0000_README b/0000_README index 32442528..8ba5f5b4 100644 --- a/0000_README +++ b/0000_README @@ -339,6 +339,10 @@ Patch: 1073_linux-6.1.74.patch From: https://www.kernel.org Desc: Linux 6.1.74 +Patch: 1074_linux-6.1.75.patch +From: https://www.kernel.org +Desc: Linux 6.1.75 + Patch: 1500_XATTR_USER_PREFIX.patch From: https://bugs.gentoo.org/show_bug.cgi?id=470644 Desc: Support for namespace user.pax.* on tmpfs. diff --git a/1074_linux-6.1.75.patch b/1074_linux-6.1.75.patch new file mode 100644 index 00000000..467e3c0a --- /dev/null +++ b/1074_linux-6.1.75.patch @@ -0,0 +1,15017 @@ +diff --git a/Documentation/devicetree/bindings/gpio/xlnx,gpio-xilinx.yaml b/Documentation/devicetree/bindings/gpio/xlnx,gpio-xilinx.yaml +index f333ee2288e76..11ae8ec3c7394 100644 +--- a/Documentation/devicetree/bindings/gpio/xlnx,gpio-xilinx.yaml ++++ b/Documentation/devicetree/bindings/gpio/xlnx,gpio-xilinx.yaml +@@ -126,7 +126,7 @@ examples: + - | + #include <dt-bindings/interrupt-controller/arm-gic.h> + +- gpio@e000a000 { ++ gpio@a0020000 { + compatible = "xlnx,xps-gpio-1.00.a"; + reg = <0xa0020000 0x10000>; + #gpio-cells = <2>; +diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml +index 9cfc0c7d23e06..46730687c6624 100644 +--- a/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml ++++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml +@@ -61,6 +61,9 @@ properties: + - description: used for 1st data pipe from RDMA + - description: used for 2nd data pipe from RDMA + ++ '#dma-cells': ++ const: 1 ++ + required: + - compatible + - reg +@@ -70,6 +73,7 @@ required: + - clocks + - iommus + - mboxes ++ - '#dma-cells' + + additionalProperties: false + +@@ -80,16 +84,17 @@ examples: + #include <dt-bindings/power/mt8183-power.h> + #include <dt-bindings/memory/mt8183-larb-port.h> + +- mdp3_rdma0: mdp3-rdma0@14001000 { +- compatible = "mediatek,mt8183-mdp3-rdma"; +- reg = <0x14001000 0x1000>; +- mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x1000 0x1000>; +- mediatek,gce-events = <CMDQ_EVENT_MDP_RDMA0_SOF>, +- <CMDQ_EVENT_MDP_RDMA0_EOF>; +- power-domains = <&spm MT8183_POWER_DOMAIN_DISP>; +- clocks = <&mmsys CLK_MM_MDP_RDMA0>, +- <&mmsys CLK_MM_MDP_RSZ1>; +- iommus = <&iommu>; +- mboxes = <&gce 20 CMDQ_THR_PRIO_LOWEST>, +- <&gce 21 CMDQ_THR_PRIO_LOWEST>; ++ dma-controller@14001000 { ++ compatible = "mediatek,mt8183-mdp3-rdma"; ++ reg = <0x14001000 0x1000>; ++ mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x1000 0x1000>; ++ mediatek,gce-events = <CMDQ_EVENT_MDP_RDMA0_SOF>, ++ <CMDQ_EVENT_MDP_RDMA0_EOF>; ++ power-domains = <&spm MT8183_POWER_DOMAIN_DISP>; ++ clocks = <&mmsys CLK_MM_MDP_RDMA0>, ++ <&mmsys CLK_MM_MDP_RSZ1>; ++ iommus = <&iommu>; ++ mboxes = <&gce 20 CMDQ_THR_PRIO_LOWEST>, ++ <&gce 21 CMDQ_THR_PRIO_LOWEST>; ++ #dma-cells = <1>; + }; +diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml +index 0baa77198fa21..64ea98aa05928 100644 +--- a/Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml ++++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml +@@ -50,6 +50,9 @@ properties: + iommus: + maxItems: 1 + ++ '#dma-cells': ++ const: 1 ++ + required: + - compatible + - reg +@@ -58,6 +61,7 @@ required: + - power-domains + - clocks + - iommus ++ - '#dma-cells' + + additionalProperties: false + +@@ -68,13 +72,14 @@ examples: + #include <dt-bindings/power/mt8183-power.h> + #include <dt-bindings/memory/mt8183-larb-port.h> + +- mdp3_wrot0: mdp3-wrot0@14005000 { +- compatible = "mediatek,mt8183-mdp3-wrot"; +- reg = <0x14005000 0x1000>; +- mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x5000 0x1000>; +- mediatek,gce-events = <CMDQ_EVENT_MDP_WROT0_SOF>, +- <CMDQ_EVENT_MDP_WROT0_EOF>; +- power-domains = <&spm MT8183_POWER_DOMAIN_DISP>; +- clocks = <&mmsys CLK_MM_MDP_WROT0>; +- iommus = <&iommu>; ++ dma-controller@14005000 { ++ compatible = "mediatek,mt8183-mdp3-wrot"; ++ reg = <0x14005000 0x1000>; ++ mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x5000 0x1000>; ++ mediatek,gce-events = <CMDQ_EVENT_MDP_WROT0_SOF>, ++ <CMDQ_EVENT_MDP_WROT0_EOF>; ++ power-domains = <&spm MT8183_POWER_DOMAIN_DISP>; ++ clocks = <&mmsys CLK_MM_MDP_WROT0>; ++ iommus = <&iommu>; ++ #dma-cells = <1>; + }; +diff --git a/Documentation/devicetree/bindings/media/rockchip-isp1.yaml b/Documentation/devicetree/bindings/media/rockchip-isp1.yaml +index b3661d7d43572..2a0ad332f5ced 100644 +--- a/Documentation/devicetree/bindings/media/rockchip-isp1.yaml ++++ b/Documentation/devicetree/bindings/media/rockchip-isp1.yaml +@@ -90,15 +90,16 @@ properties: + description: connection point for input on the parallel interface + + properties: +- bus-type: +- enum: [5, 6] +- + endpoint: + $ref: video-interfaces.yaml# + unevaluatedProperties: false + +- required: +- - bus-type ++ properties: ++ bus-type: ++ enum: [5, 6] ++ ++ required: ++ - bus-type + + anyOf: + - required: +diff --git a/Documentation/driver-api/pci/p2pdma.rst b/Documentation/driver-api/pci/p2pdma.rst +index 44deb52beeb47..d0b241628cf13 100644 +--- a/Documentation/driver-api/pci/p2pdma.rst ++++ b/Documentation/driver-api/pci/p2pdma.rst +@@ -83,19 +83,9 @@ this to include other types of resources like doorbells. + Client Drivers + -------------- + +-A client driver typically only has to conditionally change its DMA map +-routine to use the mapping function :c:func:`pci_p2pdma_map_sg()` instead +-of the usual :c:func:`dma_map_sg()` function. Memory mapped in this +-way does not need to be unmapped. +- +-The client may also, optionally, make use of +-:c:func:`is_pci_p2pdma_page()` to determine when to use the P2P mapping +-functions and when to use the regular mapping functions. In some +-situations, it may be more appropriate to use a flag to indicate a +-given request is P2P memory and map appropriately. It is important to +-ensure that struct pages that back P2P memory stay out of code that +-does not have support for them as other code may treat the pages as +-regular memory which may not be appropriate. ++A client driver only has to use the mapping API :c:func:`dma_map_sg()` ++and :c:func:`dma_unmap_sg()` functions as usual, and the implementation ++will do the right thing for the P2P capable memory. + + + Orchestrator Drivers +diff --git a/Makefile b/Makefile +index 63125d1ffd9cf..7cd49d9eadbfc 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 6 + PATCHLEVEL = 1 +-SUBLEVEL = 74 ++SUBLEVEL = 75 + EXTRAVERSION = + NAME = Curry Ramen + +diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi +index 4b57e9f5bc648..2b3927a829b70 100644 +--- a/arch/arm/boot/dts/qcom-apq8064.dtsi ++++ b/arch/arm/boot/dts/qcom-apq8064.dtsi +@@ -750,7 +750,7 @@ + + xoadc: xoadc@197 { + compatible = "qcom,pm8921-adc"; +- reg = <197>; ++ reg = <0x197>; + interrupts-extended = <&pmicintc 78 IRQ_TYPE_EDGE_RISING>; + #address-cells = <2>; + #size-cells = <0>; +diff --git a/arch/arm/boot/dts/qcom-sdx65.dtsi b/arch/arm/boot/dts/qcom-sdx65.dtsi +index ecb9171e4da5f..ebb78b489e638 100644 +--- a/arch/arm/boot/dts/qcom-sdx65.dtsi ++++ b/arch/arm/boot/dts/qcom-sdx65.dtsi +@@ -401,7 +401,7 @@ + reg = <0x0c264000 0x1000>; + }; + +- spmi_bus: qcom,spmi@c440000 { ++ spmi_bus: spmi@c440000 { + compatible = "qcom,spmi-pmic-arb"; + reg = <0xc440000 0xd00>, + <0xc600000 0x2000000>, +diff --git a/arch/arm/boot/dts/stm32mp157a-dk1-scmi.dts b/arch/arm/boot/dts/stm32mp157a-dk1-scmi.dts +index e539cc80bef81..942a6ca38d97e 100644 +--- a/arch/arm/boot/dts/stm32mp157a-dk1-scmi.dts ++++ b/arch/arm/boot/dts/stm32mp157a-dk1-scmi.dts +@@ -11,7 +11,7 @@ + + / { + model = "STMicroelectronics STM32MP157A-DK1 SCMI Discovery Board"; +- compatible = "st,stm32mp157a-dk1-scmi", "st,stm32mp157a-dk1", "st,stm32mp157"; ++ compatible = "st,stm32mp157a-dk1-scmi", "st,stm32mp157"; + + reserved-memory { + optee@de000000 { +diff --git a/arch/arm/boot/dts/stm32mp157c-dk2-scmi.dts b/arch/arm/boot/dts/stm32mp157c-dk2-scmi.dts +index 97e4f94b0a24e..99c4ff1f5c214 100644 +--- a/arch/arm/boot/dts/stm32mp157c-dk2-scmi.dts ++++ b/arch/arm/boot/dts/stm32mp157c-dk2-scmi.dts +@@ -11,7 +11,7 @@ + + / { + model = "STMicroelectronics STM32MP157C-DK2 SCMI Discovery Board"; +- compatible = "st,stm32mp157c-dk2-scmi", "st,stm32mp157c-dk2", "st,stm32mp157"; ++ compatible = "st,stm32mp157c-dk2-scmi", "st,stm32mp157"; + + reserved-memory { + optee@de000000 { +diff --git a/arch/arm/boot/dts/stm32mp157c-ed1-scmi.dts b/arch/arm/boot/dts/stm32mp157c-ed1-scmi.dts +index 9cf0a44d2f47e..21010458b36f5 100644 +--- a/arch/arm/boot/dts/stm32mp157c-ed1-scmi.dts ++++ b/arch/arm/boot/dts/stm32mp157c-ed1-scmi.dts +@@ -11,7 +11,7 @@ + + / { + model = "STMicroelectronics STM32MP157C-ED1 SCMI eval daughter"; +- compatible = "st,stm32mp157c-ed1-scmi", "st,stm32mp157c-ed1", "st,stm32mp157"; ++ compatible = "st,stm32mp157c-ed1-scmi", "st,stm32mp157"; + + reserved-memory { + optee@fe000000 { +diff --git a/arch/arm/boot/dts/stm32mp157c-ev1-scmi.dts b/arch/arm/boot/dts/stm32mp157c-ev1-scmi.dts +index 3b9dd6f4ccc96..d376371499193 100644 +--- a/arch/arm/boot/dts/stm32mp157c-ev1-scmi.dts ++++ b/arch/arm/boot/dts/stm32mp157c-ev1-scmi.dts +@@ -11,8 +11,7 @@ + + / { + model = "STMicroelectronics STM32MP157C-EV1 SCMI eval daughter on eval mother"; +- compatible = "st,stm32mp157c-ev1-scmi", "st,stm32mp157c-ev1", "st,stm32mp157c-ed1", +- "st,stm32mp157"; ++ compatible = "st,stm32mp157c-ev1-scmi", "st,stm32mp157c-ed1", "st,stm32mp157"; + + reserved-memory { + optee@fe000000 { +diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig +index c8cbd9a307914..672ffb0b5f3af 100644 +--- a/arch/arm/mach-davinci/Kconfig ++++ b/arch/arm/mach-davinci/Kconfig +@@ -4,12 +4,14 @@ menuconfig ARCH_DAVINCI + bool "TI DaVinci" + depends on ARCH_MULTI_V5 + depends on CPU_LITTLE_ENDIAN ++ select CPU_ARM926T + select DAVINCI_TIMER + select ZONE_DMA + select PM_GENERIC_DOMAINS if PM + select PM_GENERIC_DOMAINS_OF if PM && OF + select REGMAP_MMIO + select RESET_CONTROLLER ++ select PINCTRL + select PINCTRL_SINGLE + + if ARCH_DAVINCI +diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi +index d583db18f74cc..7a410d73600b1 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi +@@ -1303,7 +1303,7 @@ + assigned-clocks = <&clk IMX8MM_CLK_GPU3D_CORE>, + <&clk IMX8MM_GPU_PLL_OUT>; + assigned-clock-parents = <&clk IMX8MM_GPU_PLL_OUT>; +- assigned-clock-rates = <0>, <1000000000>; ++ assigned-clock-rates = <0>, <800000000>; + power-domains = <&pgc_gpu>; + }; + +@@ -1318,7 +1318,7 @@ + assigned-clocks = <&clk IMX8MM_CLK_GPU2D_CORE>, + <&clk IMX8MM_GPU_PLL_OUT>; + assigned-clock-parents = <&clk IMX8MM_GPU_PLL_OUT>; +- assigned-clock-rates = <0>, <1000000000>; ++ assigned-clock-rates = <0>, <800000000>; + power-domains = <&pgc_gpu>; + }; + +diff --git a/arch/arm64/boot/dts/hisilicon/hikey970-pmic.dtsi b/arch/arm64/boot/dts/hisilicon/hikey970-pmic.dtsi +index 970047f2dabd5..c06e011a6c3ff 100644 +--- a/arch/arm64/boot/dts/hisilicon/hikey970-pmic.dtsi ++++ b/arch/arm64/boot/dts/hisilicon/hikey970-pmic.dtsi +@@ -25,9 +25,6 @@ + gpios = <&gpio28 0 0>; + + regulators { +- #address-cells = <1>; +- #size-cells = <0>; +- + ldo3: ldo3 { /* HDMI */ + regulator-name = "ldo3"; + regulator-min-microvolt = <1500000>; +diff --git a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts +index 200f97e1c4c9c..37350e5fa253a 100644 +--- a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts ++++ b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts +@@ -130,7 +130,7 @@ + compatible = "microchip,mcp7940x"; + reg = <0x6f>; + interrupt-parent = <&gpiosb>; +- interrupts = <5 0>; /* GPIO2_5 */ ++ interrupts = <5 IRQ_TYPE_EDGE_FALLING>; /* GPIO2_5 */ + }; + }; + +diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi +index 10779a9947fe2..d5d9b954c449a 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi +@@ -1586,7 +1586,7 @@ + mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0 0x1000>; + }; + +- mdp3-rdma0@14001000 { ++ dma-controller0@14001000 { + compatible = "mediatek,mt8183-mdp3-rdma"; + reg = <0 0x14001000 0 0x1000>; + mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x1000 0x1000>; +@@ -1598,6 +1598,7 @@ + iommus = <&iommu M4U_PORT_MDP_RDMA0>; + mboxes = <&gce 20 CMDQ_THR_PRIO_LOWEST 0>, + <&gce 21 CMDQ_THR_PRIO_LOWEST 0>; ++ #dma-cells = <1>; + }; + + mdp3-rsz0@14003000 { +@@ -1618,7 +1619,7 @@ + clocks = <&mmsys CLK_MM_MDP_RSZ1>; + }; + +- mdp3-wrot0@14005000 { ++ dma-controller@14005000 { + compatible = "mediatek,mt8183-mdp3-wrot"; + reg = <0 0x14005000 0 0x1000>; + mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x5000 0x1000>; +@@ -1627,6 +1628,7 @@ + power-domains = <&spm MT8183_POWER_DOMAIN_DISP>; + clocks = <&mmsys CLK_MM_MDP_WROT0>; + iommus = <&iommu M4U_PORT_MDP_WROT0>; ++ #dma-cells = <1>; + }; + + mdp3-wdma@14006000 { +diff --git a/arch/arm64/boot/dts/qcom/ipq6018.dtsi b/arch/arm64/boot/dts/qcom/ipq6018.dtsi +index 43ff8f1f1475c..1533c61cb106c 100644 +--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi ++++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi +@@ -146,7 +146,7 @@ + ranges; + + rpm_msg_ram: memory@60000 { +- reg = <0x0 0x60000 0x0 0x6000>; ++ reg = <0x0 0x00060000 0x0 0x6000>; + no-map; + }; + +@@ -181,7 +181,7 @@ + + prng: qrng@e1000 { + compatible = "qcom,prng-ee"; +- reg = <0x0 0xe3000 0x0 0x1000>; ++ reg = <0x0 0x000e3000 0x0 0x1000>; + clocks = <&gcc GCC_PRNG_AHB_CLK>; + clock-names = "core"; + }; +@@ -201,8 +201,8 @@ + compatible = "qcom,crypto-v5.1"; + reg = <0x0 0x0073a000 0x0 0x6000>; + clocks = <&gcc GCC_CRYPTO_AHB_CLK>, +- <&gcc GCC_CRYPTO_AXI_CLK>, +- <&gcc GCC_CRYPTO_CLK>; ++ <&gcc GCC_CRYPTO_AXI_CLK>, ++ <&gcc GCC_CRYPTO_CLK>; + clock-names = "iface", "bus", "core"; + dmas = <&cryptobam 2>, <&cryptobam 3>; + dma-names = "rx", "tx"; +@@ -272,7 +272,7 @@ + reg = <0x0 0x078b1000 0x0 0x200>; + interrupts = <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&gcc GCC_BLSP1_UART3_APPS_CLK>, +- <&gcc GCC_BLSP1_AHB_CLK>; ++ <&gcc GCC_BLSP1_AHB_CLK>; + clock-names = "core", "iface"; + status = "disabled"; + }; +@@ -285,7 +285,7 @@ + interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>; + spi-max-frequency = <50000000>; + clocks = <&gcc GCC_BLSP1_QUP1_SPI_APPS_CLK>, +- <&gcc GCC_BLSP1_AHB_CLK>; ++ <&gcc GCC_BLSP1_AHB_CLK>; + clock-names = "core", "iface"; + dmas = <&blsp_dma 12>, <&blsp_dma 13>; + dma-names = "tx", "rx"; +@@ -300,7 +300,7 @@ + interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; + spi-max-frequency = <50000000>; + clocks = <&gcc GCC_BLSP1_QUP2_SPI_APPS_CLK>, +- <&gcc GCC_BLSP1_AHB_CLK>; ++ <&gcc GCC_BLSP1_AHB_CLK>; + clock-names = "core", "iface"; + dmas = <&blsp_dma 14>, <&blsp_dma 15>; + dma-names = "tx", "rx"; +@@ -358,8 +358,8 @@ + clock-names = "core", "aon"; + + dmas = <&qpic_bam 0>, +- <&qpic_bam 1>, +- <&qpic_bam 2>; ++ <&qpic_bam 1>, ++ <&qpic_bam 2>; + dma-names = "tx", "rx", "cmd"; + pinctrl-0 = <&qpic_pins>; + pinctrl-names = "default"; +@@ -372,10 +372,10 @@ + #size-cells = <2>; + interrupt-controller; + #interrupt-cells = <0x3>; +- reg = <0x0 0x0b000000 0x0 0x1000>, /*GICD*/ +- <0x0 0x0b002000 0x0 0x1000>, /*GICC*/ +- <0x0 0x0b001000 0x0 0x1000>, /*GICH*/ +- <0x0 0x0b004000 0x0 0x1000>; /*GICV*/ ++ reg = <0x0 0x0b000000 0x0 0x1000>, /*GICD*/ ++ <0x0 0x0b002000 0x0 0x1000>, /*GICC*/ ++ <0x0 0x0b001000 0x0 0x1000>, /*GICH*/ ++ <0x0 0x0b004000 0x0 0x1000>; /*GICV*/ + interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>; + ranges = <0 0 0 0xb00a000 0 0xffd>; + +@@ -388,7 +388,7 @@ + + pcie_phy: phy@84000 { + compatible = "qcom,ipq6018-qmp-pcie-phy"; +- reg = <0x0 0x84000 0x0 0x1bc>; /* Serdes PLL */ ++ reg = <0x0 0x00084000 0x0 0x1bc>; /* Serdes PLL */ + status = "disabled"; + #address-cells = <2>; + #size-cells = <2>; +@@ -404,9 +404,10 @@ + "common"; + + pcie_phy0: phy@84200 { +- reg = <0x0 0x84200 0x0 0x16c>, /* Serdes Tx */ +- <0x0 0x84400 0x0 0x200>, /* Serdes Rx */ +- <0x0 0x84800 0x0 0x4f4>; /* PCS: Lane0, COM, PCIE */ ++ reg = <0x0 0x00084200 0x0 0x16c>, /* Serdes Tx */ ++ <0x0 0x00084400 0x0 0x200>, /* Serdes Rx */ ++ <0x0 0x00084800 0x0 0x1f0>, /* PCS: Lane0, COM, PCIE */ ++ <0x0 0x00084c00 0x0 0xf4>; /* pcs_misc */ + #phy-cells = <0>; + + clocks = <&gcc GCC_PCIE0_PIPE_CLK>; +@@ -628,7 +629,7 @@ + #address-cells = <1>; + #size-cells = <0>; + compatible = "qcom,ipq6018-mdio", "qcom,ipq4019-mdio"; +- reg = <0x0 0x90000 0x0 0x64>; ++ reg = <0x0 0x00090000 0x0 0x64>; + clocks = <&gcc GCC_MDIO_AHB_CLK>; + clock-names = "gcc_mdio_ahb_clk"; + status = "disabled"; +@@ -636,7 +637,7 @@ + + qusb_phy_1: qusb@59000 { + compatible = "qcom,ipq6018-qusb2-phy"; +- reg = <0x0 0x059000 0x0 0x180>; ++ reg = <0x0 0x00059000 0x0 0x180>; + #phy-cells = <0>; + + clocks = <&gcc GCC_USB1_PHY_CFG_AHB_CLK>, +@@ -668,23 +669,23 @@ + status = "disabled"; + + dwc_1: usb@7000000 { +- compatible = "snps,dwc3"; +- reg = <0x0 0x7000000 0x0 0xcd00>; +- interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>; +- phys = <&qusb_phy_1>; +- phy-names = "usb2-phy"; +- tx-fifo-resize; +- snps,is-utmi-l1-suspend; +- snps,hird-threshold = /bits/ 8 <0x0>; +- snps,dis_u2_susphy_quirk; +- snps,dis_u3_susphy_quirk; +- dr_mode = "host"; ++ compatible = "snps,dwc3"; ++ reg = <0x0 0x07000000 0x0 0xcd00>; ++ interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>; ++ phys = <&qusb_phy_1>; ++ phy-names = "usb2-phy"; ++ tx-fifo-resize; ++ snps,is-utmi-l1-suspend; ++ snps,hird-threshold = /bits/ 8 <0x0>; ++ snps,dis_u2_susphy_quirk; ++ snps,dis_u3_susphy_quirk; ++ dr_mode = "host"; + }; + }; + + ssphy_0: ssphy@78000 { + compatible = "qcom,ipq6018-qmp-usb3-phy"; +- reg = <0x0 0x78000 0x0 0x1C4>; ++ reg = <0x0 0x00078000 0x0 0x1c4>; + #address-cells = <2>; + #size-cells = <2>; + ranges; +@@ -701,7 +702,7 @@ + usb0_ssphy: phy@78200 { + reg = <0x0 0x00078200 0x0 0x130>, /* Tx */ + <0x0 0x00078400 0x0 0x200>, /* Rx */ +- <0x0 0x00078800 0x0 0x1F8>, /* PCS */ ++ <0x0 0x00078800 0x0 0x1f8>, /* PCS */ + <0x0 0x00078600 0x0 0x044>; /* PCS misc */ + #phy-cells = <0>; + #clock-cells = <0>; +@@ -713,7 +714,7 @@ + + qusb_phy_0: qusb@79000 { + compatible = "qcom,ipq6018-qusb2-phy"; +- reg = <0x0 0x079000 0x0 0x180>; ++ reg = <0x0 0x00079000 0x0 0x180>; + #phy-cells = <0>; + + clocks = <&gcc GCC_USB0_PHY_CFG_AHB_CLK>, +@@ -726,7 +727,7 @@ + + usb3: usb@8af8800 { + compatible = "qcom,ipq6018-dwc3", "qcom,dwc3"; +- reg = <0x0 0x8AF8800 0x0 0x400>; ++ reg = <0x0 0x8af8800 0x0 0x400>; + #address-cells = <2>; + #size-cells = <2>; + ranges; +@@ -745,14 +746,14 @@ + <&gcc GCC_USB0_MOCK_UTMI_CLK>; + assigned-clock-rates = <133330000>, + <133330000>, +- <20000000>; ++ <24000000>; + + resets = <&gcc GCC_USB0_BCR>; + status = "disabled"; + + dwc_0: usb@8a00000 { + compatible = "snps,dwc3"; +- reg = <0x0 0x8A00000 0x0 0xcd00>; ++ reg = <0x0 0x8a00000 0x0 0xcd00>; + interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>; + phys = <&qusb_phy_0>, <&usb0_ssphy>; + phy-names = "usb2-phy", "usb3-phy"; +diff --git a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts +index 9731a7c63d53b..1defbe0404e2e 100644 +--- a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts ++++ b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts +@@ -63,8 +63,8 @@ + function = LED_FUNCTION_INDICATOR; + color = <LED_COLOR_ID_GREEN>; + gpios = <&pm8150_gpios 10 GPIO_ACTIVE_HIGH>; +- linux,default-trigger = "panic-indicator"; + default-state = "off"; ++ panic-indicator; + }; + + led-wlan { +diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi +index 6f0ee4e13ef1d..78e537f1d7965 100644 +--- a/arch/arm64/boot/dts/qcom/sc7180.dtsi ++++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi +@@ -3378,7 +3378,7 @@ + compatible = "qcom,apss-wdt-sc7180", "qcom,kpss-wdt"; + reg = <0 0x17c10000 0 0x1000>; + clocks = <&sleep_clk>; +- interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>; ++ interrupts = <GIC_SPI 0 IRQ_TYPE_EDGE_RISING>; + }; + + timer@17c20000{ +diff --git a/arch/arm64/boot/dts/qcom/sc7280-chrome-common.dtsi b/arch/arm64/boot/dts/qcom/sc7280-chrome-common.dtsi +index 25f31c81b2b74..efe6ea538ad21 100644 +--- a/arch/arm64/boot/dts/qcom/sc7280-chrome-common.dtsi ++++ b/arch/arm64/boot/dts/qcom/sc7280-chrome-common.dtsi +@@ -56,6 +56,26 @@ + }; + }; + ++&lpass_aon { ++ status = "okay"; ++}; ++ ++&lpass_core { ++ status = "okay"; ++}; ++ ++&lpass_hm { ++ status = "okay"; ++}; ++ ++&lpasscc { ++ status = "okay"; ++}; ++ ++&pdc_reset { ++ status = "okay"; ++}; ++ + /* The PMIC PON code isn't compatible w/ how Chrome EC/BIOS handle things. */ + &pmk8350_pon { + status = "disabled"; +@@ -93,6 +113,10 @@ + reg = <0x0 0x9c900000 0x0 0x800000>; + }; + ++&watchdog { ++ status = "okay"; ++}; ++ + &wifi { + status = "okay"; + +diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi +index aea356c63b9a3..7fc8c20450223 100644 +--- a/arch/arm64/boot/dts/qcom/sc7280.dtsi ++++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi +@@ -888,6 +888,7 @@ + + bus-width = <8>; + supports-cqe; ++ dma-coherent; + + qcom,dll-config = <0x0007642c>; + qcom,ddr-config = <0x80040868>; +@@ -2187,6 +2188,7 @@ + clocks = <&gcc GCC_CFG_NOC_LPASS_CLK>; + clock-names = "iface"; + #clock-cells = <1>; ++ status = "reserved"; /* Owned by ADSP firmware */ + }; + + lpass_rx_macro: codec@3200000 { +@@ -2339,6 +2341,7 @@ + clock-names = "bi_tcxo", "bi_tcxo_ao", "iface"; + #clock-cells = <1>; + #power-domain-cells = <1>; ++ status = "reserved"; /* Owned by ADSP firmware */ + }; + + lpass_core: clock-controller@3900000 { +@@ -2349,6 +2352,7 @@ + power-domains = <&lpass_hm LPASS_CORE_CC_LPASS_CORE_HM_GDSC>; + #clock-cells = <1>; + #power-domain-cells = <1>; ++ status = "reserved"; /* Owned by ADSP firmware */ + }; + + lpass_cpu: audio@3987000 { +@@ -2419,6 +2423,7 @@ + clock-names = "bi_tcxo"; + #clock-cells = <1>; + #power-domain-cells = <1>; ++ status = "reserved"; /* Owned by ADSP firmware */ + }; + + lpass_ag_noc: interconnect@3c40000 { +@@ -2529,7 +2534,8 @@ + "cx_mem", + "cx_dbgc"; + interrupts = <GIC_SPI 300 IRQ_TYPE_LEVEL_HIGH>; +- iommus = <&adreno_smmu 0 0x401>; ++ iommus = <&adreno_smmu 0 0x400>, ++ <&adreno_smmu 1 0x400>; + operating-points-v2 = <&gpu_opp_table>; + qcom,gmu = <&gmu>; + interconnects = <&gem_noc MASTER_GFX3D 0 &mc_virt SLAVE_EBI1 0>; +@@ -2696,6 +2702,7 @@ + "gpu_cc_hub_aon_clk"; + + power-domains = <&gpucc GPU_CC_CX_GDSC>; ++ dma-coherent; + }; + + remoteproc_mpss: remoteproc@4080000 { +@@ -3265,6 +3272,7 @@ + operating-points-v2 = <&sdhc2_opp_table>; + + bus-width = <4>; ++ dma-coherent; + + qcom,dll-config = <0x0007642c>; + +@@ -3386,8 +3394,8 @@ + assigned-clock-rates = <19200000>, <200000000>; + + interrupts-extended = <&intc GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>, +- <&pdc 12 IRQ_TYPE_EDGE_RISING>, +- <&pdc 13 IRQ_TYPE_EDGE_RISING>; ++ <&pdc 12 IRQ_TYPE_EDGE_BOTH>, ++ <&pdc 13 IRQ_TYPE_EDGE_BOTH>; + interrupt-names = "hs_phy_irq", + "dp_hs_phy_irq", + "dm_hs_phy_irq"; +@@ -4195,6 +4203,7 @@ + compatible = "qcom,sc7280-pdc-global"; + reg = <0 0x0b5e0000 0 0x20000>; + #reset-cells = <1>; ++ status = "reserved"; /* Owned by firmware */ + }; + + tsens0: thermal-sensor@c263000 { +@@ -5186,11 +5195,12 @@ + }; + }; + +- watchdog@17c10000 { ++ watchdog: watchdog@17c10000 { + compatible = "qcom,apss-wdt-sc7280", "qcom,kpss-wdt"; + reg = <0 0x17c10000 0 0x1000>; + clocks = <&sleep_clk>; +- interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>; ++ interrupts = <GIC_SPI 0 IRQ_TYPE_EDGE_RISING>; ++ status = "reserved"; /* Owned by Gunyah hyp */ + }; + + timer@17c20000 { +diff --git a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi +index 405835ad28bcd..7e3aaf5de3f5c 100644 +--- a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi ++++ b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi +@@ -1653,7 +1653,7 @@ + compatible = "qcom,apss-wdt-sc8280xp", "qcom,kpss-wdt"; + reg = <0 0x17c10000 0 0x1000>; + clocks = <&sleep_clk>; +- interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>; ++ interrupts = <GIC_SPI 0 IRQ_TYPE_EDGE_RISING>; + }; + + timer@17c20000 { +diff --git a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts +index 8c9ccf5b4ea41..135ff4368c4a6 100644 +--- a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts ++++ b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts +@@ -66,8 +66,8 @@ + function = LED_FUNCTION_INDICATOR; + color = <LED_COLOR_ID_GREEN>; + gpios = <&pm8998_gpio 13 GPIO_ACTIVE_HIGH>; +- linux,default-trigger = "panic-indicator"; + default-state = "off"; ++ panic-indicator; + }; + + led-1 { +diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi +index 52c9f5639f8a2..1e6841902900c 100644 +--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi ++++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi +@@ -5019,7 +5019,7 @@ + compatible = "qcom,apss-wdt-sdm845", "qcom,kpss-wdt"; + reg = <0 0x17980000 0 0x1000>; + clocks = <&sleep_clk>; +- interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>; ++ interrupts = <GIC_SPI 0 IRQ_TYPE_EDGE_RISING>; + }; + + apss_shared: mailbox@17990000 { +diff --git a/arch/arm64/boot/dts/qcom/sm6350.dtsi b/arch/arm64/boot/dts/qcom/sm6350.dtsi +index cea7ca3f326fc..9da373090593c 100644 +--- a/arch/arm64/boot/dts/qcom/sm6350.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm6350.dtsi +@@ -1462,7 +1462,7 @@ + compatible = "qcom,apss-wdt-sm6350", "qcom,kpss-wdt"; + reg = <0 0x17c10000 0 0x1000>; + clocks = <&sleep_clk>; +- interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>; ++ interrupts = <GIC_SPI 0 IRQ_TYPE_EDGE_RISING>; + }; + + timer@17c20000 { +diff --git a/arch/arm64/boot/dts/qcom/sm8150-hdk.dts b/arch/arm64/boot/dts/qcom/sm8150-hdk.dts +index 3331ee957d648..368da4c7f41be 100644 +--- a/arch/arm64/boot/dts/qcom/sm8150-hdk.dts ++++ b/arch/arm64/boot/dts/qcom/sm8150-hdk.dts +@@ -126,8 +126,6 @@ + vdda_sp_sensor: + vdda_ufs_2ln_core_1: + vdda_ufs_2ln_core_2: +- vdda_usb_ss_dp_core_1: +- vdda_usb_ss_dp_core_2: + vdda_qlink_lv: + vdda_qlink_lv_ck: + vreg_l5a_0p875: ldo5 { +@@ -209,6 +207,12 @@ + regulator-max-microvolt = <3008000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; ++ ++ vreg_l18a_0p8: ldo18 { ++ regulator-min-microvolt = <880000>; ++ regulator-max-microvolt = <880000>; ++ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; ++ }; + }; + + pm8150l-rpmh-regulators { +@@ -439,13 +443,13 @@ + &usb_1_qmpphy { + status = "okay"; + vdda-phy-supply = <&vreg_l3c_1p2>; +- vdda-pll-supply = <&vdda_usb_ss_dp_core_1>; ++ vdda-pll-supply = <&vreg_l18a_0p8>; + }; + + &usb_2_qmpphy { + status = "okay"; + vdda-phy-supply = <&vreg_l3c_1p2>; +- vdda-pll-supply = <&vdda_usb_ss_dp_core_1>; ++ vdda-pll-supply = <&vreg_l5a_0p875>; + }; + + &usb_1 { +diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi +index c586378fc6bc7..c3c12b0cd4168 100644 +--- a/arch/arm64/boot/dts/qcom/sm8150.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi +@@ -3940,7 +3940,7 @@ + compatible = "qcom,apss-wdt-sm8150", "qcom,kpss-wdt"; + reg = <0 0x17c10000 0 0x1000>; + clocks = <&sleep_clk>; +- interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>; ++ interrupts = <GIC_SPI 0 IRQ_TYPE_EDGE_RISING>; + }; + + timer@17c20000 { +diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi +index 4d9b30f0b2841..3d02adbc0b62f 100644 +--- a/arch/arm64/boot/dts/qcom/sm8250.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi +@@ -4879,7 +4879,7 @@ + compatible = "qcom,apss-wdt-sm8250", "qcom,kpss-wdt"; + reg = <0 0x17c10000 0 0x1000>; + clocks = <&sleep_clk>; +- interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>; ++ interrupts = <GIC_SPI 0 IRQ_TYPE_EDGE_RISING>; + }; + + timer@17c20000 { +diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi +index 793768a2c9e1e..888bf4cd73c31 100644 +--- a/arch/arm64/boot/dts/qcom/sm8350.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi +@@ -903,9 +903,9 @@ + }; + }; + +- gpi_dma0: dma-controller@9800000 { ++ gpi_dma0: dma-controller@900000 { + compatible = "qcom,sm8350-gpi-dma", "qcom,sm6350-gpi-dma"; +- reg = <0 0x09800000 0 0x60000>; ++ reg = <0 0x00900000 0 0x60000>; + interrupts = <GIC_SPI 244 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>, +diff --git a/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-cpu.dtsi b/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-cpu.dtsi +index 895f0bd9f7540..541b1e73b65e0 100644 +--- a/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-cpu.dtsi ++++ b/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-cpu.dtsi +@@ -125,6 +125,9 @@ + }; + + &hscif0 { ++ pinctrl-0 = <&hscif0_pins>; ++ pinctrl-names = "default"; ++ + status = "okay"; + }; + +diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi +index bc4b50bcd1773..9301ea3888021 100644 +--- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi ++++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi +@@ -245,7 +245,7 @@ + <193>, <194>, <195>; + interrupt-controller; + #interrupt-cells = <2>; +- ti,ngpio = <87>; ++ ti,ngpio = <92>; + ti,davinci-gpio-unbanked = <0>; + power-domains = <&k3_pds 77 TI_SCI_PD_EXCLUSIVE>; + clocks = <&k3_clks 77 0>; +@@ -263,7 +263,7 @@ + <183>, <184>, <185>; + interrupt-controller; + #interrupt-cells = <2>; +- ti,ngpio = <88>; ++ ti,ngpio = <52>; + ti,davinci-gpio-unbanked = <0>; + power-domains = <&k3_pds 78 TI_SCI_PD_EXCLUSIVE>; + clocks = <&k3_clks 78 0>; +diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi +index ebb1c5ce7aece..83dd8993027ab 100644 +--- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi ++++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi +@@ -856,7 +856,7 @@ + assigned-clocks = <&k3_clks 67 2>; + assigned-clock-parents = <&k3_clks 67 5>; + +- interrupts = <GIC_SPI 166 IRQ_TYPE_EDGE_RISING>; ++ interrupts = <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>; + + dma-coherent; + +diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c +index 00ad6587bee9a..3c344e4cd4cad 100644 +--- a/arch/arm64/kvm/vgic/vgic-its.c ++++ b/arch/arm64/kvm/vgic/vgic-its.c +@@ -584,7 +584,11 @@ static struct vgic_irq *vgic_its_check_cache(struct kvm *kvm, phys_addr_t db, + unsigned long flags; + + raw_spin_lock_irqsave(&dist->lpi_list_lock, flags); ++ + irq = __vgic_its_check_cache(dist, db, devid, eventid); ++ if (irq) ++ vgic_get_irq_kref(irq); ++ + raw_spin_unlock_irqrestore(&dist->lpi_list_lock, flags); + + return irq; +@@ -763,6 +767,7 @@ int vgic_its_inject_cached_translation(struct kvm *kvm, struct kvm_msi *msi) + raw_spin_lock_irqsave(&irq->irq_lock, flags); + irq->pending_latch = true; + vgic_queue_irq_unlock(kvm, irq, flags); ++ vgic_put_irq(kvm, irq); + + return 0; + } +diff --git a/arch/arm64/kvm/vgic/vgic-mmio-v3.c b/arch/arm64/kvm/vgic/vgic-mmio-v3.c +index 871a45d4fc84c..ae5a3a717655e 100644 +--- a/arch/arm64/kvm/vgic/vgic-mmio-v3.c ++++ b/arch/arm64/kvm/vgic/vgic-mmio-v3.c +@@ -365,19 +365,26 @@ static int vgic_v3_uaccess_write_pending(struct kvm_vcpu *vcpu, + struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); + + raw_spin_lock_irqsave(&irq->irq_lock, flags); +- if (test_bit(i, &val)) { +- /* +- * pending_latch is set irrespective of irq type +- * (level or edge) to avoid dependency that VM should +- * restore irq config before pending info. +- */ +- irq->pending_latch = true; +- vgic_queue_irq_unlock(vcpu->kvm, irq, flags); +- } else { ++ ++ /* ++ * pending_latch is set irrespective of irq type ++ * (level or edge) to avoid dependency that VM should ++ * restore irq config before pending info. ++ */ ++ irq->pending_latch = test_bit(i, &val); ++ ++ if (irq->hw && vgic_irq_is_sgi(irq->intid)) { ++ irq_set_irqchip_state(irq->host_irq, ++ IRQCHIP_STATE_PENDING, ++ irq->pending_latch); + irq->pending_latch = false; +- raw_spin_unlock_irqrestore(&irq->irq_lock, flags); + } + ++ if (irq->pending_latch) ++ vgic_queue_irq_unlock(vcpu->kvm, irq, flags); ++ else ++ raw_spin_unlock_irqrestore(&irq->irq_lock, flags); ++ + vgic_put_irq(vcpu->kvm, irq); + } + +diff --git a/arch/csky/include/asm/jump_label.h b/arch/csky/include/asm/jump_label.h +index d488ba6084bc6..98a3f4b168bd2 100644 +--- a/arch/csky/include/asm/jump_label.h ++++ b/arch/csky/include/asm/jump_label.h +@@ -43,5 +43,10 @@ label: + return true; + } + ++enum jump_label_type; ++void arch_jump_label_transform_static(struct jump_entry *entry, ++ enum jump_label_type type); ++#define arch_jump_label_transform_static arch_jump_label_transform_static ++ + #endif /* __ASSEMBLY__ */ + #endif /* __ASM_CSKY_JUMP_LABEL_H */ +diff --git a/arch/loongarch/include/asm/elf.h b/arch/loongarch/include/asm/elf.h +index 9b16a3b8e7060..f16bd42456e4c 100644 +--- a/arch/loongarch/include/asm/elf.h ++++ b/arch/loongarch/include/asm/elf.h +@@ -241,8 +241,6 @@ void loongarch_dump_regs64(u64 *uregs, const struct pt_regs *regs); + do { \ + current->thread.vdso = &vdso_info; \ + \ +- loongarch_set_personality_fcsr(state); \ +- \ + if (personality(current->personality) != PER_LINUX) \ + set_personality(PER_LINUX); \ + } while (0) +@@ -259,7 +257,6 @@ do { \ + clear_thread_flag(TIF_32BIT_ADDR); \ + \ + current->thread.vdso = &vdso_info; \ +- loongarch_set_personality_fcsr(state); \ + \ + p = personality(current->personality); \ + if (p != PER_LINUX32 && p != PER_LINUX) \ +@@ -340,6 +337,4 @@ extern int arch_elf_pt_proc(void *ehdr, void *phdr, struct file *elf, + extern int arch_check_elf(void *ehdr, bool has_interpreter, void *interp_ehdr, + struct arch_elf_state *state); + +-extern void loongarch_set_personality_fcsr(struct arch_elf_state *state); +- + #endif /* _ASM_ELF_H */ +diff --git a/arch/loongarch/kernel/elf.c b/arch/loongarch/kernel/elf.c +index 183e94fc9c69c..0fa81ced28dcd 100644 +--- a/arch/loongarch/kernel/elf.c ++++ b/arch/loongarch/kernel/elf.c +@@ -23,8 +23,3 @@ int arch_check_elf(void *_ehdr, bool has_interpreter, void *_interp_ehdr, + { + return 0; + } +- +-void loongarch_set_personality_fcsr(struct arch_elf_state *state) +-{ +- current->thread.fpu.fcsr = boot_cpu_data.fpu_csr0; +-} +diff --git a/arch/loongarch/kernel/process.c b/arch/loongarch/kernel/process.c +index 90a5de7463326..1259bc3129790 100644 +--- a/arch/loongarch/kernel/process.c ++++ b/arch/loongarch/kernel/process.c +@@ -82,6 +82,7 @@ void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long sp) + euen = regs->csr_euen & ~(CSR_EUEN_FPEN); + regs->csr_euen = euen; + lose_fpu(0); ++ current->thread.fpu.fcsr = boot_cpu_data.fpu_csr0; + + clear_thread_flag(TIF_LSX_CTX_LIVE); + clear_thread_flag(TIF_LASX_CTX_LIVE); +diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c +index 40ed49d9adff5..4e86441e63196 100644 +--- a/arch/loongarch/net/bpf_jit.c ++++ b/arch/loongarch/net/bpf_jit.c +@@ -402,7 +402,6 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext + const u8 dst = regmap[insn->dst_reg]; + const s16 off = insn->off; + const s32 imm = insn->imm; +- const u64 imm64 = (u64)(insn + 1)->imm << 32 | (u32)insn->imm; + const bool is32 = BPF_CLASS(insn->code) == BPF_ALU || BPF_CLASS(insn->code) == BPF_JMP32; + + switch (code) { +@@ -806,8 +805,12 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext + + /* dst = imm64 */ + case BPF_LD | BPF_IMM | BPF_DW: ++ { ++ const u64 imm64 = (u64)(insn + 1)->imm << 32 | (u32)insn->imm; ++ + move_imm(ctx, dst, imm64, is32); + return 1; ++ } + + /* dst = *(size *)(src + off) */ + case BPF_LDX | BPF_MEM | BPF_B: +diff --git a/arch/mips/alchemy/devboards/db1200.c b/arch/mips/alchemy/devboards/db1200.c +index f521874ebb07b..67f067706af27 100644 +--- a/arch/mips/alchemy/devboards/db1200.c ++++ b/arch/mips/alchemy/devboards/db1200.c +@@ -847,7 +847,7 @@ int __init db1200_dev_setup(void) + i2c_register_board_info(0, db1200_i2c_devs, + ARRAY_SIZE(db1200_i2c_devs)); + spi_register_board_info(db1200_spi_devs, +- ARRAY_SIZE(db1200_i2c_devs)); ++ ARRAY_SIZE(db1200_spi_devs)); + + /* SWITCHES: S6.8 I2C/SPI selector (OFF=I2C ON=SPI) + * S6.7 AC97/I2S selector (OFF=AC97 ON=I2S) +diff --git a/arch/mips/alchemy/devboards/db1550.c b/arch/mips/alchemy/devboards/db1550.c +index fd91d9c9a2525..6c6837181f555 100644 +--- a/arch/mips/alchemy/devboards/db1550.c ++++ b/arch/mips/alchemy/devboards/db1550.c +@@ -589,7 +589,7 @@ int __init db1550_dev_setup(void) + i2c_register_board_info(0, db1550_i2c_devs, + ARRAY_SIZE(db1550_i2c_devs)); + spi_register_board_info(db1550_spi_devs, +- ARRAY_SIZE(db1550_i2c_devs)); ++ ARRAY_SIZE(db1550_spi_devs)); + + c = clk_get(NULL, "psc0_intclk"); + if (!IS_ERR(c)) { +diff --git a/arch/mips/include/asm/dmi.h b/arch/mips/include/asm/dmi.h +index 27415a288adf5..dc397f630c660 100644 +--- a/arch/mips/include/asm/dmi.h ++++ b/arch/mips/include/asm/dmi.h +@@ -5,7 +5,7 @@ + #include <linux/io.h> + #include <linux/memblock.h> + +-#define dmi_early_remap(x, l) ioremap_cache(x, l) ++#define dmi_early_remap(x, l) ioremap(x, l) + #define dmi_early_unmap(x, l) iounmap(x) + #define dmi_remap(x, l) ioremap_cache(x, l) + #define dmi_unmap(x) iounmap(x) +diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c +index 7c540572f1f72..e46e7ec76b4f4 100644 +--- a/arch/mips/kernel/setup.c ++++ b/arch/mips/kernel/setup.c +@@ -326,11 +326,11 @@ static void __init bootmem_init(void) + panic("Incorrect memory mapping !!!"); + + if (max_pfn > PFN_DOWN(HIGHMEM_START)) { ++ max_low_pfn = PFN_DOWN(HIGHMEM_START); + #ifdef CONFIG_HIGHMEM +- highstart_pfn = PFN_DOWN(HIGHMEM_START); ++ highstart_pfn = max_low_pfn; + highend_pfn = max_pfn; + #else +- max_low_pfn = PFN_DOWN(HIGHMEM_START); + max_pfn = max_low_pfn; + #endif + } +diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c +index 1d93b85271ba8..002c91fcb842e 100644 +--- a/arch/mips/kernel/smp.c ++++ b/arch/mips/kernel/smp.c +@@ -333,10 +333,11 @@ early_initcall(mips_smp_ipi_init); + */ + asmlinkage void start_secondary(void) + { +- unsigned int cpu; ++ unsigned int cpu = raw_smp_processor_id(); + + cpu_probe(); + per_cpu_trap_init(false); ++ rcu_cpu_starting(cpu); + mips_clockevent_init(); + mp_ops->init_secondary(); + cpu_report(); +@@ -348,7 +349,6 @@ asmlinkage void start_secondary(void) + */ + + calibrate_delay(); +- cpu = smp_processor_id(); + cpu_data[cpu].udelay_val = loops_per_jiffy; + + set_cpu_sibling_map(cpu); +diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig +index 6050e6e10d321..2c94f9cf1ce00 100644 +--- a/arch/powerpc/Kconfig ++++ b/arch/powerpc/Kconfig +@@ -806,6 +806,7 @@ config THREAD_SHIFT + int "Thread shift" if EXPERT + range 13 15 + default "15" if PPC_256K_PAGES ++ default "15" if PPC_PSERIES || PPC_POWERNV + default "14" if PPC64 + default "13" + help +diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile +index 054844153b1fd..487e4967b60d2 100644 +--- a/arch/powerpc/Makefile ++++ b/arch/powerpc/Makefile +@@ -42,18 +42,13 @@ machine-$(CONFIG_PPC64) += 64 + machine-$(CONFIG_CPU_LITTLE_ENDIAN) += le + UTS_MACHINE := $(subst $(space),,$(machine-y)) + +-# XXX This needs to be before we override LD below +-ifdef CONFIG_PPC32 +-KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o +-else +-ifeq ($(call ld-ifversion, -ge, 22500, y),y) ++ifeq ($(CONFIG_PPC64)$(CONFIG_LD_IS_BFD),yy) + # Have the linker provide sfpr if possible. + # There is a corresponding test in arch/powerpc/lib/Makefile + KBUILD_LDFLAGS_MODULE += --save-restore-funcs + else + KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o + endif +-endif + + ifdef CONFIG_CPU_LITTLE_ENDIAN + KBUILD_CFLAGS += -mlittle-endian +@@ -391,17 +386,7 @@ endif + endif + + PHONY += checkbin +-# Check toolchain versions: +-# - gcc-4.6 is the minimum kernel-wide version so nothing required. + checkbin: +- @if test "x${CONFIG_LD_IS_LLD}" != "xy" -a \ +- "x$(call ld-ifversion, -le, 22400, y)" = "xy" ; then \ +- echo -n '*** binutils 2.24 miscompiles weak symbols ' ; \ +- echo 'in some circumstances.' ; \ +- echo '*** binutils 2.23 do not define the TOC symbol ' ; \ +- echo -n '*** Please use a different binutils version.' ; \ +- false ; \ +- fi + @if test "x${CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT}" = "xy" -a \ + "x${CONFIG_LD_IS_BFD}" = "xy" -a \ + "${CONFIG_LD_VERSION}" = "23700" ; then \ +diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile +index 8560c912186df..9b394bab17eba 100644 +--- a/arch/powerpc/lib/Makefile ++++ b/arch/powerpc/lib/Makefile +@@ -42,8 +42,8 @@ obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o + # 64-bit linker creates .sfpr on demand for final link (vmlinux), + # so it is only needed for modules, and only for older linkers which + # do not support --save-restore-funcs +-ifeq ($(call ld-ifversion, -lt, 22500, y),y) +-extra-$(CONFIG_PPC64) += crtsavres.o ++ifndef CONFIG_LD_IS_BFD ++always-$(CONFIG_PPC64) += crtsavres.o + endif + + obj-$(CONFIG_PPC_BOOK3S_64) += copyuser_power7.o copypage_power7.o \ +diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c +index ada817c49b722..56d82f7f9734e 100644 +--- a/arch/powerpc/perf/imc-pmu.c ++++ b/arch/powerpc/perf/imc-pmu.c +@@ -299,6 +299,8 @@ static int update_events_in_group(struct device_node *node, struct imc_pmu *pmu) + attr_group->attrs = attrs; + do { + ev_val_str = kasprintf(GFP_KERNEL, "event=0x%x", pmu->events[i].value); ++ if (!ev_val_str) ++ continue; + dev_str = device_str_attr_create(pmu->events[i].name, ev_val_str); + if (!dev_str) + continue; +@@ -306,6 +308,8 @@ static int update_events_in_group(struct device_node *node, struct imc_pmu *pmu) + attrs[j++] = dev_str; + if (pmu->events[i].scale) { + ev_scale_str = kasprintf(GFP_KERNEL, "%s.scale", pmu->events[i].name); ++ if (!ev_scale_str) ++ continue; + dev_str = device_str_attr_create(ev_scale_str, pmu->events[i].scale); + if (!dev_str) + continue; +@@ -315,6 +319,8 @@ static int update_events_in_group(struct device_node *node, struct imc_pmu *pmu) + + if (pmu->events[i].unit) { + ev_unit_str = kasprintf(GFP_KERNEL, "%s.unit", pmu->events[i].name); ++ if (!ev_unit_str) ++ continue; + dev_str = device_str_attr_create(ev_unit_str, pmu->events[i].unit); + if (!dev_str) + continue; +diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig +index 25b80cd558f8d..fc79f84669335 100644 +--- a/arch/powerpc/platforms/44x/Kconfig ++++ b/arch/powerpc/platforms/44x/Kconfig +@@ -173,6 +173,7 @@ config ISS4xx + config CURRITUCK + bool "IBM Currituck (476fpe) Support" + depends on PPC_47x ++ select I2C + select SWIOTLB + select 476FPE + select FORCE_PCI +diff --git a/arch/powerpc/platforms/powernv/opal-irqchip.c b/arch/powerpc/platforms/powernv/opal-irqchip.c +index d55652b5f6fa4..391f505352007 100644 +--- a/arch/powerpc/platforms/powernv/opal-irqchip.c ++++ b/arch/powerpc/platforms/powernv/opal-irqchip.c +@@ -275,6 +275,8 @@ int __init opal_event_init(void) + else + name = kasprintf(GFP_KERNEL, "opal"); + ++ if (!name) ++ continue; + /* Install interrupt handler */ + rc = request_irq(r->start, opal_interrupt, r->flags & IRQD_TRIGGER_MASK, + name, NULL); +diff --git a/arch/powerpc/platforms/powernv/opal-powercap.c b/arch/powerpc/platforms/powernv/opal-powercap.c +index 7bfe4cbeb35a9..ea917266aa172 100644 +--- a/arch/powerpc/platforms/powernv/opal-powercap.c ++++ b/arch/powerpc/platforms/powernv/opal-powercap.c +@@ -196,6 +196,12 @@ void __init opal_powercap_init(void) + + j = 0; + pcaps[i].pg.name = kasprintf(GFP_KERNEL, "%pOFn", node); ++ if (!pcaps[i].pg.name) { ++ kfree(pcaps[i].pattrs); ++ kfree(pcaps[i].pg.attrs); ++ goto out_pcaps_pattrs; ++ } ++ + if (has_min) { + powercap_add_attr(min, "powercap-min", + &pcaps[i].pattrs[j]); +diff --git a/arch/powerpc/platforms/powernv/opal-xscom.c b/arch/powerpc/platforms/powernv/opal-xscom.c +index 6b4eed2ef4fa9..f67235d1ba2c5 100644 +--- a/arch/powerpc/platforms/powernv/opal-xscom.c ++++ b/arch/powerpc/platforms/powernv/opal-xscom.c +@@ -165,6 +165,11 @@ static int scom_debug_init_one(struct dentry *root, struct device_node *dn, + ent->chip = chip; + snprintf(ent->name, 16, "%08x", chip); + ent->path.data = (void *)kasprintf(GFP_KERNEL, "%pOF", dn); ++ if (!ent->path.data) { ++ kfree(ent); ++ return -ENOMEM; ++ } ++ + ent->path.size = strlen((char *)ent->path.data); + + dir = debugfs_create_dir(ent->name, root); +diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c +index 2e3a317722a81..051a777ba1b27 100644 +--- a/arch/powerpc/platforms/pseries/hotplug-memory.c ++++ b/arch/powerpc/platforms/pseries/hotplug-memory.c +@@ -500,14 +500,15 @@ static int dlpar_memory_remove_by_index(u32 drc_index) + } + } + +- if (!lmb_found) ++ if (!lmb_found) { ++ pr_debug("Failed to look up LMB for drc index %x\n", drc_index); + rc = -EINVAL; +- +- if (rc) ++ } else if (rc) { + pr_debug("Failed to hot-remove memory at %llx\n", + lmb->base_addr); +- else ++ } else { + pr_debug("Memory at %llx was hot-removed\n", lmb->base_addr); ++ } + + return rc; + } +diff --git a/arch/riscv/include/asm/sections.h b/arch/riscv/include/asm/sections.h +index 32336e8a17cb0..a393d5035c543 100644 +--- a/arch/riscv/include/asm/sections.h ++++ b/arch/riscv/include/asm/sections.h +@@ -13,6 +13,7 @@ extern char _start_kernel[]; + extern char __init_data_begin[], __init_data_end[]; + extern char __init_text_begin[], __init_text_end[]; + extern char __alt_start[], __alt_end[]; ++extern char __exittext_begin[], __exittext_end[]; + + static inline bool is_va_kernel_text(uintptr_t va) + { +diff --git a/arch/riscv/include/asm/xip_fixup.h b/arch/riscv/include/asm/xip_fixup.h +index d4ffc3c37649f..b65bf6306f69c 100644 +--- a/arch/riscv/include/asm/xip_fixup.h ++++ b/arch/riscv/include/asm/xip_fixup.h +@@ -13,7 +13,7 @@ + add \reg, \reg, t0 + .endm + .macro XIP_FIXUP_FLASH_OFFSET reg +- la t1, __data_loc ++ la t0, __data_loc + REG_L t1, _xip_phys_offset + sub \reg, \reg, t1 + add \reg, \reg, t0 +diff --git a/arch/riscv/kernel/module.c b/arch/riscv/kernel/module.c +index 91fe16bfaa07c..a331001e33e66 100644 +--- a/arch/riscv/kernel/module.c ++++ b/arch/riscv/kernel/module.c +@@ -424,7 +424,8 @@ void *module_alloc(unsigned long size) + { + return __vmalloc_node_range(size, 1, MODULES_VADDR, + MODULES_END, GFP_KERNEL, +- PAGE_KERNEL, 0, NUMA_NO_NODE, ++ PAGE_KERNEL, VM_FLUSH_RESET_PERMS, ++ NUMA_NO_NODE, + __builtin_return_address(0)); + } + #endif +diff --git a/arch/riscv/kernel/patch.c b/arch/riscv/kernel/patch.c +index e099961453cca..160e5c1caa9c4 100644 +--- a/arch/riscv/kernel/patch.c ++++ b/arch/riscv/kernel/patch.c +@@ -13,6 +13,7 @@ + #include <asm/fixmap.h> + #include <asm/ftrace.h> + #include <asm/patch.h> ++#include <asm/sections.h> + + struct patch_insn { + void *addr; +@@ -23,6 +24,14 @@ struct patch_insn { + int riscv_patch_in_stop_machine = false; + + #ifdef CONFIG_MMU ++ ++static inline bool is_kernel_exittext(uintptr_t addr) ++{ ++ return system_state < SYSTEM_RUNNING && ++ addr >= (uintptr_t)__exittext_begin && ++ addr < (uintptr_t)__exittext_end; ++} ++ + /* + * The fix_to_virt(, idx) needs a const value (not a dynamic variable of + * reg-a0) or BUILD_BUG_ON failed with "idx >= __end_of_fixed_addresses". +@@ -33,7 +42,7 @@ static __always_inline void *patch_map(void *addr, const unsigned int fixmap) + uintptr_t uintaddr = (uintptr_t) addr; + struct page *page; + +- if (core_kernel_text(uintaddr)) ++ if (core_kernel_text(uintaddr) || is_kernel_exittext(uintaddr)) + page = phys_to_page(__pa_symbol(addr)); + else if (IS_ENABLED(CONFIG_STRICT_MODULE_RWX)) + page = vmalloc_to_page(addr); +diff --git a/arch/riscv/kernel/vmlinux-xip.lds.S b/arch/riscv/kernel/vmlinux-xip.lds.S +index 75e0fa8a700ae..24a2fdd3be6a0 100644 +--- a/arch/riscv/kernel/vmlinux-xip.lds.S ++++ b/arch/riscv/kernel/vmlinux-xip.lds.S +@@ -29,10 +29,12 @@ SECTIONS + HEAD_TEXT_SECTION + INIT_TEXT_SECTION(PAGE_SIZE) + /* we have to discard exit text and such at runtime, not link time */ ++ __exittext_begin = .; + .exit.text : + { + EXIT_TEXT + } ++ __exittext_end = .; + + .text : { + _text = .; +diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S +index 4e6c88aa4d870..d478e063b8785 100644 +--- a/arch/riscv/kernel/vmlinux.lds.S ++++ b/arch/riscv/kernel/vmlinux.lds.S +@@ -72,10 +72,12 @@ SECTIONS + __soc_builtin_dtb_table_end = .; + } + /* we have to discard exit text and such at runtime, not link time */ ++ __exittext_begin = .; + .exit.text : + { + EXIT_TEXT + } ++ __exittext_end = .; + + __init_text_end = .; + . = ALIGN(SECTION_ALIGN); +diff --git a/arch/riscv/mm/pageattr.c b/arch/riscv/mm/pageattr.c +index ea3d61de065b3..9587e44874152 100644 +--- a/arch/riscv/mm/pageattr.c ++++ b/arch/riscv/mm/pageattr.c +@@ -5,6 +5,7 @@ + + #include <linux/pagewalk.h> + #include <linux/pgtable.h> ++#include <linux/vmalloc.h> + #include <asm/tlbflush.h> + #include <asm/bitops.h> + #include <asm/set_memory.h> +@@ -25,19 +26,6 @@ static unsigned long set_pageattr_masks(unsigned long val, struct mm_walk *walk) + return new_val; + } + +-static int pageattr_pgd_entry(pgd_t *pgd, unsigned long addr, +- unsigned long next, struct mm_walk *walk) +-{ +- pgd_t val = READ_ONCE(*pgd); +- +- if (pgd_leaf(val)) { +- val = __pgd(set_pageattr_masks(pgd_val(val), walk)); +- set_pgd(pgd, val); +- } +- +- return 0; +-} +- + static int pageattr_p4d_entry(p4d_t *p4d, unsigned long addr, + unsigned long next, struct mm_walk *walk) + { +@@ -96,7 +84,6 @@ static int pageattr_pte_hole(unsigned long addr, unsigned long next, + } + + static const struct mm_walk_ops pageattr_ops = { +- .pgd_entry = pageattr_pgd_entry, + .p4d_entry = pageattr_p4d_entry, + .pud_entry = pageattr_pud_entry, + .pmd_entry = pageattr_pmd_entry, +@@ -104,12 +91,181 @@ static const struct mm_walk_ops pageattr_ops = { + .pte_hole = pageattr_pte_hole, + }; + ++#ifdef CONFIG_64BIT ++static int __split_linear_mapping_pmd(pud_t *pudp, ++ unsigned long vaddr, unsigned long end) ++{ ++ pmd_t *pmdp; ++ unsigned long next; ++ ++ pmdp = pmd_offset(pudp, vaddr); ++ ++ do { ++ next = pmd_addr_end(vaddr, end); ++ ++ if (next - vaddr >= PMD_SIZE && ++ vaddr <= (vaddr & PMD_MASK) && end >= next) ++ continue; ++ ++ if (pmd_leaf(*pmdp)) { ++ struct page *pte_page; ++ unsigned long pfn = _pmd_pfn(*pmdp); ++ pgprot_t prot = __pgprot(pmd_val(*pmdp) & ~_PAGE_PFN_MASK); ++ pte_t *ptep_new; ++ int i; ++ ++ pte_page = alloc_page(GFP_KERNEL); ++ if (!pte_page) ++ return -ENOMEM; ++ ++ ptep_new = (pte_t *)page_address(pte_page); ++ for (i = 0; i < PTRS_PER_PTE; ++i, ++ptep_new) ++ set_pte(ptep_new, pfn_pte(pfn + i, prot)); ++ ++ smp_wmb(); ++ ++ set_pmd(pmdp, pfn_pmd(page_to_pfn(pte_page), PAGE_TABLE)); ++ } ++ } while (pmdp++, vaddr = next, vaddr != end); ++ ++ return 0; ++} ++ ++static int __split_linear_mapping_pud(p4d_t *p4dp, ++ unsigned long vaddr, unsigned long end) ++{ ++ pud_t *pudp; ++ unsigned long next; ++ int ret; ++ ++ pudp = pud_offset(p4dp, vaddr); ++ ++ do { ++ next = pud_addr_end(vaddr, end); ++ ++ if (next - vaddr >= PUD_SIZE && ++ vaddr <= (vaddr & PUD_MASK) && end >= next) ++ continue; ++ ++ if (pud_leaf(*pudp)) { ++ struct page *pmd_page; ++ unsigned long pfn = _pud_pfn(*pudp); ++ pgprot_t prot = __pgprot(pud_val(*pudp) & ~_PAGE_PFN_MASK); ++ pmd_t *pmdp_new; ++ int i; ++ ++ pmd_page = alloc_page(GFP_KERNEL); ++ if (!pmd_page) ++ return -ENOMEM; ++ ++ pmdp_new = (pmd_t *)page_address(pmd_page); ++ for (i = 0; i < PTRS_PER_PMD; ++i, ++pmdp_new) ++ set_pmd(pmdp_new, ++ pfn_pmd(pfn + ((i * PMD_SIZE) >> PAGE_SHIFT), prot)); ++ ++ smp_wmb(); ++ ++ set_pud(pudp, pfn_pud(page_to_pfn(pmd_page), PAGE_TABLE)); ++ } ++ ++ ret = __split_linear_mapping_pmd(pudp, vaddr, next); ++ if (ret) ++ return ret; ++ } while (pudp++, vaddr = next, vaddr != end); ++ ++ return 0; ++} ++ ++static int __split_linear_mapping_p4d(pgd_t *pgdp, ++ unsigned long vaddr, unsigned long end) ++{ ++ p4d_t *p4dp; ++ unsigned long next; ++ int ret; ++ ++ p4dp = p4d_offset(pgdp, vaddr); ++ ++ do { ++ next = p4d_addr_end(vaddr, end); ++ ++ /* ++ * If [vaddr; end] contains [vaddr & P4D_MASK; next], we don't ++ * need to split, we'll change the protections on the whole P4D. ++ */ ++ if (next - vaddr >= P4D_SIZE && ++ vaddr <= (vaddr & P4D_MASK) && end >= next) ++ continue; ++ ++ if (p4d_leaf(*p4dp)) { ++ struct page *pud_page; ++ unsigned long pfn = _p4d_pfn(*p4dp); ++ pgprot_t prot = __pgprot(p4d_val(*p4dp) & ~_PAGE_PFN_MASK); ++ pud_t *pudp_new; ++ int i; ++ ++ pud_page = alloc_page(GFP_KERNEL); ++ if (!pud_page) ++ return -ENOMEM; ++ ++ /* ++ * Fill the pud level with leaf puds that have the same ++ * protections as the leaf p4d. ++ */ ++ pudp_new = (pud_t *)page_address(pud_page); ++ for (i = 0; i < PTRS_PER_PUD; ++i, ++pudp_new) ++ set_pud(pudp_new, ++ pfn_pud(pfn + ((i * PUD_SIZE) >> PAGE_SHIFT), prot)); ++ ++ /* ++ * Make sure the pud filling is not reordered with the ++ * p4d store which could result in seeing a partially ++ * filled pud level. ++ */ ++ smp_wmb(); ++ ++ set_p4d(p4dp, pfn_p4d(page_to_pfn(pud_page), PAGE_TABLE)); ++ } ++ ++ ret = __split_linear_mapping_pud(p4dp, vaddr, next); ++ if (ret) ++ return ret; ++ } while (p4dp++, vaddr = next, vaddr != end); ++ ++ return 0; ++} ++ ++static int __split_linear_mapping_pgd(pgd_t *pgdp, ++ unsigned long vaddr, ++ unsigned long end) ++{ ++ unsigned long next; ++ int ret; ++ ++ do { ++ next = pgd_addr_end(vaddr, end); ++ /* We never use PGD mappings for the linear mapping */ ++ ret = __split_linear_mapping_p4d(pgdp, vaddr, next); ++ if (ret) ++ return ret; ++ } while (pgdp++, vaddr = next, vaddr != end); ++ ++ return 0; ++} ++ ++static int split_linear_mapping(unsigned long start, unsigned long end) ++{ ++ return __split_linear_mapping_pgd(pgd_offset_k(start), start, end); ++} ++#endif /* CONFIG_64BIT */ ++ + static int __set_memory(unsigned long addr, int numpages, pgprot_t set_mask, + pgprot_t clear_mask) + { + int ret; + unsigned long start = addr; + unsigned long end = start + PAGE_SIZE * numpages; ++ unsigned long __maybe_unused lm_start; ++ unsigned long __maybe_unused lm_end; + struct pageattr_masks masks = { + .set_mask = set_mask, + .clear_mask = clear_mask +@@ -119,11 +275,72 @@ static int __set_memory(unsigned long addr, int numpages, pgprot_t set_mask, + return 0; + + mmap_write_lock(&init_mm); ++ ++#ifdef CONFIG_64BIT ++ /* ++ * We are about to change the permissions of a kernel mapping, we must ++ * apply the same changes to its linear mapping alias, which may imply ++ * splitting a huge mapping. ++ */ ++ ++ if (is_vmalloc_or_module_addr((void *)start)) { ++ struct vm_struct *area = NULL; ++ int i, page_start; ++ ++ area = find_vm_area((void *)start); ++ page_start = (start - (unsigned long)area->addr) >> PAGE_SHIFT; ++ ++ for (i = page_start; i < page_start + numpages; ++i) { ++ lm_start = (unsigned long)page_address(area->pages[i]); ++ lm_end = lm_start + PAGE_SIZE; ++ ++ ret = split_linear_mapping(lm_start, lm_end); ++ if (ret) ++ goto unlock; ++ ++ ret = walk_page_range_novma(&init_mm, lm_start, lm_end, ++ &pageattr_ops, NULL, &masks); ++ if (ret) ++ goto unlock; ++ } ++ } else if (is_kernel_mapping(start) || is_linear_mapping(start)) { ++ if (is_kernel_mapping(start)) { ++ lm_start = (unsigned long)lm_alias(start); ++ lm_end = (unsigned long)lm_alias(end); ++ } else { ++ lm_start = start; ++ lm_end = end; ++ } ++ ++ ret = split_linear_mapping(lm_start, lm_end); ++ if (ret) ++ goto unlock; ++ ++ ret = walk_page_range_novma(&init_mm, lm_start, lm_end, ++ &pageattr_ops, NULL, &masks); ++ if (ret) ++ goto unlock; ++ } ++ + ret = walk_page_range_novma(&init_mm, start, end, &pageattr_ops, NULL, + &masks); ++ ++unlock: ++ mmap_write_unlock(&init_mm); ++ ++ /* ++ * We can't use flush_tlb_kernel_range() here as we may have split a ++ * hugepage that is larger than that, so let's flush everything. ++ */ ++ flush_tlb_all(); ++#else ++ ret = walk_page_range_novma(&init_mm, start, end, &pageattr_ops, NULL, ++ &masks); ++ + mmap_write_unlock(&init_mm); + + flush_tlb_kernel_range(start, end); ++#endif + + return ret; + } +@@ -158,36 +375,14 @@ int set_memory_nx(unsigned long addr, int numpages) + + int set_direct_map_invalid_noflush(struct page *page) + { +- int ret; +- unsigned long start = (unsigned long)page_address(page); +- unsigned long end = start + PAGE_SIZE; +- struct pageattr_masks masks = { +- .set_mask = __pgprot(0), +- .clear_mask = __pgprot(_PAGE_PRESENT) +- }; +- +- mmap_read_lock(&init_mm); +- ret = walk_page_range(&init_mm, start, end, &pageattr_ops, &masks); +- mmap_read_unlock(&init_mm); +- +- return ret; ++ return __set_memory((unsigned long)page_address(page), 1, ++ __pgprot(0), __pgprot(_PAGE_PRESENT)); + } + + int set_direct_map_default_noflush(struct page *page) + { +- int ret; +- unsigned long start = (unsigned long)page_address(page); +- unsigned long end = start + PAGE_SIZE; +- struct pageattr_masks masks = { +- .set_mask = PAGE_KERNEL, +- .clear_mask = __pgprot(0) +- }; +- +- mmap_read_lock(&init_mm); +- ret = walk_page_range(&init_mm, start, end, &pageattr_ops, &masks); +- mmap_read_unlock(&init_mm); +- +- return ret; ++ return __set_memory((unsigned long)page_address(page), 1, ++ PAGE_KERNEL, __pgprot(_PAGE_EXEC)); + } + + #ifdef CONFIG_DEBUG_PAGEALLOC +diff --git a/arch/s390/include/asm/pci_io.h b/arch/s390/include/asm/pci_io.h +index 287bb88f76986..2686bee800e3d 100644 +--- a/arch/s390/include/asm/pci_io.h ++++ b/arch/s390/include/asm/pci_io.h +@@ -11,6 +11,8 @@ + /* I/O size constraints */ + #define ZPCI_MAX_READ_SIZE 8 + #define ZPCI_MAX_WRITE_SIZE 128 ++#define ZPCI_BOUNDARY_SIZE (1 << 12) ++#define ZPCI_BOUNDARY_MASK (ZPCI_BOUNDARY_SIZE - 1) + + /* I/O Map */ + #define ZPCI_IOMAP_SHIFT 48 +@@ -125,16 +127,18 @@ out: + int zpci_write_block(volatile void __iomem *dst, const void *src, + unsigned long len); + +-static inline u8 zpci_get_max_write_size(u64 src, u64 dst, int len, int max) ++static inline int zpci_get_max_io_size(u64 src, u64 dst, int len, int max) + { +- int count = len > max ? max : len, size = 1; ++ int offset = dst & ZPCI_BOUNDARY_MASK; ++ int size; + +- while (!(src & 0x1) && !(dst & 0x1) && ((size << 1) <= count)) { +- dst = dst >> 1; +- src = src >> 1; +- size = size << 1; +- } +- return size; ++ size = min3(len, ZPCI_BOUNDARY_SIZE - offset, max); ++ if (IS_ALIGNED(src, 8) && IS_ALIGNED(dst, 8) && IS_ALIGNED(size, 8)) ++ return size; ++ ++ if (size >= 8) ++ return 8; ++ return rounddown_pow_of_two(size); + } + + static inline int zpci_memcpy_fromio(void *dst, +@@ -144,9 +148,9 @@ static inline int zpci_memcpy_fromio(void *dst, + int size, rc = 0; + + while (n > 0) { +- size = zpci_get_max_write_size((u64 __force) src, +- (u64) dst, n, +- ZPCI_MAX_READ_SIZE); ++ size = zpci_get_max_io_size((u64 __force) src, ++ (u64) dst, n, ++ ZPCI_MAX_READ_SIZE); + rc = zpci_read_single(dst, src, size); + if (rc) + break; +@@ -166,9 +170,9 @@ static inline int zpci_memcpy_toio(volatile void __iomem *dst, + return -EINVAL; + + while (n > 0) { +- size = zpci_get_max_write_size((u64 __force) dst, +- (u64) src, n, +- ZPCI_MAX_WRITE_SIZE); ++ size = zpci_get_max_io_size((u64 __force) dst, ++ (u64) src, n, ++ ZPCI_MAX_WRITE_SIZE); + if (size > 8) /* main path */ + rc = zpci_write_block(dst, src, size); + else +diff --git a/arch/s390/pci/pci_mmio.c b/arch/s390/pci/pci_mmio.c +index 5880893329310..a90499c087f0c 100644 +--- a/arch/s390/pci/pci_mmio.c ++++ b/arch/s390/pci/pci_mmio.c +@@ -97,9 +97,9 @@ static inline int __memcpy_toio_inuser(void __iomem *dst, + return -EINVAL; + + while (n > 0) { +- size = zpci_get_max_write_size((u64 __force) dst, +- (u64 __force) src, n, +- ZPCI_MAX_WRITE_SIZE); ++ size = zpci_get_max_io_size((u64 __force) dst, ++ (u64 __force) src, n, ++ ZPCI_MAX_WRITE_SIZE); + if (size > 8) /* main path */ + rc = __pcistb_mio_inuser(dst, src, size, &status); + else +@@ -242,9 +242,9 @@ static inline int __memcpy_fromio_inuser(void __user *dst, + u8 status; + + while (n > 0) { +- size = zpci_get_max_write_size((u64 __force) src, +- (u64 __force) dst, n, +- ZPCI_MAX_READ_SIZE); ++ size = zpci_get_max_io_size((u64 __force) src, ++ (u64 __force) dst, n, ++ ZPCI_MAX_READ_SIZE); + rc = __pcilg_mio_inuser(dst, src, size, &status); + if (rc) + break; +diff --git a/arch/x86/kernel/cpu/mce/inject.c b/arch/x86/kernel/cpu/mce/inject.c +index 12cf2e7ca33cc..87c15ab896517 100644 +--- a/arch/x86/kernel/cpu/mce/inject.c ++++ b/arch/x86/kernel/cpu/mce/inject.c +@@ -747,6 +747,7 @@ static void check_hw_inj_possible(void) + + wrmsrl_safe(mca_msr_reg(bank, MCA_STATUS), status); + rdmsrl_safe(mca_msr_reg(bank, MCA_STATUS), &status); ++ wrmsrl_safe(mca_msr_reg(bank, MCA_STATUS), 0); + + if (!status) { + hw_injection_possible = false; +diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c +index 16333ba1904ba..c067887d42df5 100644 +--- a/arch/x86/kernel/kvmclock.c ++++ b/arch/x86/kernel/kvmclock.c +@@ -24,8 +24,8 @@ + + static int kvmclock __initdata = 1; + static int kvmclock_vsyscall __initdata = 1; +-static int msr_kvm_system_time __ro_after_init = MSR_KVM_SYSTEM_TIME; +-static int msr_kvm_wall_clock __ro_after_init = MSR_KVM_WALL_CLOCK; ++static int msr_kvm_system_time __ro_after_init; ++static int msr_kvm_wall_clock __ro_after_init; + static u64 kvm_sched_clock_offset __ro_after_init; + + static int __init parse_no_kvmclock(char *arg) +@@ -195,7 +195,8 @@ static void kvm_setup_secondary_clock(void) + + void kvmclock_disable(void) + { +- native_write_msr(msr_kvm_system_time, 0, 0); ++ if (msr_kvm_system_time) ++ native_write_msr(msr_kvm_system_time, 0, 0); + } + + static void __init kvmclock_init_mem(void) +@@ -294,7 +295,10 @@ void __init kvmclock_init(void) + if (kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE2)) { + msr_kvm_system_time = MSR_KVM_SYSTEM_TIME_NEW; + msr_kvm_wall_clock = MSR_KVM_WALL_CLOCK_NEW; +- } else if (!kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE)) { ++ } else if (kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE)) { ++ msr_kvm_system_time = MSR_KVM_SYSTEM_TIME; ++ msr_kvm_wall_clock = MSR_KVM_WALL_CLOCK; ++ } else { + return; + } + +diff --git a/arch/x86/lib/misc.c b/arch/x86/lib/misc.c +index a018ec4fba53e..c97be9a1430a0 100644 +--- a/arch/x86/lib/misc.c ++++ b/arch/x86/lib/misc.c +@@ -6,7 +6,7 @@ + */ + int num_digits(int val) + { +- int m = 10; ++ long long m = 10; + int d = 1; + + if (val < 0) { +diff --git a/block/bio.c b/block/bio.c +index 9ec72a78f1149..6c22dd7b6f278 100644 +--- a/block/bio.c ++++ b/block/bio.c +@@ -1109,13 +1109,22 @@ bool bio_add_folio(struct bio *bio, struct folio *folio, size_t len, + + void __bio_release_pages(struct bio *bio, bool mark_dirty) + { +- struct bvec_iter_all iter_all; +- struct bio_vec *bvec; ++ struct folio_iter fi; + +- bio_for_each_segment_all(bvec, bio, iter_all) { +- if (mark_dirty && !PageCompound(bvec->bv_page)) +- set_page_dirty_lock(bvec->bv_page); +- put_page(bvec->bv_page); ++ bio_for_each_folio_all(fi, bio) { ++ struct page *page; ++ size_t done = 0; ++ ++ if (mark_dirty) { ++ folio_lock(fi.folio); ++ folio_mark_dirty(fi.folio); ++ folio_unlock(fi.folio); ++ } ++ page = folio_page(fi.folio, fi.offset / PAGE_SIZE); ++ do { ++ folio_put(fi.folio); ++ done += PAGE_SIZE; ++ } while (done < fi.length); + } + } + EXPORT_SYMBOL_GPL(__bio_release_pages); +@@ -1414,12 +1423,12 @@ EXPORT_SYMBOL(bio_free_pages); + */ + void bio_set_pages_dirty(struct bio *bio) + { +- struct bio_vec *bvec; +- struct bvec_iter_all iter_all; ++ struct folio_iter fi; + +- bio_for_each_segment_all(bvec, bio, iter_all) { +- if (!PageCompound(bvec->bv_page)) +- set_page_dirty_lock(bvec->bv_page); ++ bio_for_each_folio_all(fi, bio) { ++ folio_lock(fi.folio); ++ folio_mark_dirty(fi.folio); ++ folio_unlock(fi.folio); + } + } + +@@ -1462,12 +1471,11 @@ static void bio_dirty_fn(struct work_struct *work) + + void bio_check_pages_dirty(struct bio *bio) + { +- struct bio_vec *bvec; ++ struct folio_iter fi; + unsigned long flags; +- struct bvec_iter_all iter_all; + +- bio_for_each_segment_all(bvec, bio, iter_all) { +- if (!PageDirty(bvec->bv_page) && !PageCompound(bvec->bv_page)) ++ bio_for_each_folio_all(fi, bio) { ++ if (!folio_test_dirty(fi.folio)) + goto defer; + } + +diff --git a/block/blk-mq.c b/block/blk-mq.c +index 368f1947c8956..b3f99dda45300 100644 +--- a/block/blk-mq.c ++++ b/block/blk-mq.c +@@ -2946,12 +2946,6 @@ void blk_mq_submit_bio(struct bio *bio) + blk_status_t ret; + + bio = blk_queue_bounce(bio, q); +- if (bio_may_exceed_limits(bio, &q->limits)) { +- bio = __bio_split_to_limits(bio, &q->limits, &nr_segs); +- if (!bio) +- return; +- } +- + bio_set_ioprio(bio); + + if (plug) { +@@ -2960,6 +2954,11 @@ void blk_mq_submit_bio(struct bio *bio) + rq = NULL; + } + if (rq) { ++ if (unlikely(bio_may_exceed_limits(bio, &q->limits))) { ++ bio = __bio_split_to_limits(bio, &q->limits, &nr_segs); ++ if (!bio) ++ return; ++ } + if (!bio_integrity_prep(bio)) + return; + if (blk_mq_attempt_bio_merge(q, bio, nr_segs)) +@@ -2970,6 +2969,11 @@ void blk_mq_submit_bio(struct bio *bio) + } else { + if (unlikely(bio_queue_enter(bio))) + return; ++ if (unlikely(bio_may_exceed_limits(bio, &q->limits))) { ++ bio = __bio_split_to_limits(bio, &q->limits, &nr_segs); ++ if (!bio) ++ goto fail; ++ } + if (!bio_integrity_prep(bio)) + goto fail; + } +diff --git a/block/blk-settings.c b/block/blk-settings.c +index 86ff375c00ce4..bbca4ce77a2d3 100644 +--- a/block/blk-settings.c ++++ b/block/blk-settings.c +@@ -135,7 +135,7 @@ void blk_queue_max_hw_sectors(struct request_queue *q, unsigned int max_hw_secto + limits->max_hw_sectors = max_hw_sectors; + + max_sectors = min_not_zero(max_hw_sectors, limits->max_dev_sectors); +- max_sectors = min_t(unsigned int, max_sectors, BLK_DEF_MAX_SECTORS); ++ max_sectors = min(max_sectors, BLK_DEF_MAX_SECTORS); + max_sectors = round_down(max_sectors, + limits->logical_block_size >> SECTOR_SHIFT); + limits->max_sectors = max_sectors; +diff --git a/block/genhd.c b/block/genhd.c +index afab646d12c85..ddb17c4adc8a2 100644 +--- a/block/genhd.c ++++ b/block/genhd.c +@@ -444,7 +444,9 @@ int __must_check device_add_disk(struct device *parent, struct gendisk *disk, + DISK_MAX_PARTS); + disk->minors = DISK_MAX_PARTS; + } +- if (disk->first_minor + disk->minors > MINORMASK + 1) ++ if (disk->first_minor > MINORMASK || ++ disk->minors > MINORMASK + 1 || ++ disk->first_minor + disk->minors > MINORMASK + 1) + goto out_exit_elevator; + } else { + if (WARN_ON(disk->minors)) +@@ -567,6 +569,7 @@ out_del_integrity: + out_del_block_link: + if (!sysfs_deprecated) + sysfs_remove_link(block_depr, dev_name(ddev)); ++ pm_runtime_set_memalloc_noio(ddev, false); + out_device_del: + device_del(ddev); + out_free_ext_minor: +diff --git a/block/ioctl.c b/block/ioctl.c +index 3c475e4166e9f..ebe4a2653622b 100644 +--- a/block/ioctl.c ++++ b/block/ioctl.c +@@ -18,7 +18,7 @@ static int blkpg_do_ioctl(struct block_device *bdev, + { + struct gendisk *disk = bdev->bd_disk; + struct blkpg_partition p; +- long long start, length; ++ sector_t start, length; + + if (disk->flags & GENHD_FL_NO_PART) + return -EINVAL; +@@ -35,14 +35,17 @@ static int blkpg_do_ioctl(struct block_device *bdev, + if (op == BLKPG_DEL_PARTITION) + return bdev_del_partition(disk, p.pno); + ++ if (p.start < 0 || p.length <= 0 || p.start + p.length < 0) ++ return -EINVAL; ++ /* Check that the partition is aligned to the block size */ ++ if (!IS_ALIGNED(p.start | p.length, bdev_logical_block_size(bdev))) ++ return -EINVAL; ++ + start = p.start >> SECTOR_SHIFT; + length = p.length >> SECTOR_SHIFT; + + switch (op) { + case BLKPG_ADD_PARTITION: +- /* check if partition is aligned to blocksize */ +- if (p.start & (bdev_logical_block_size(bdev) - 1)) +- return -EINVAL; + return bdev_add_partition(disk, p.pno, start, length); + case BLKPG_RESIZE_PARTITION: + return bdev_resize_partition(disk, p.pno, start, length); +diff --git a/crypto/af_alg.c b/crypto/af_alg.c +index e893c0f6c8799..fef69d2a6b183 100644 +--- a/crypto/af_alg.c ++++ b/crypto/af_alg.c +@@ -1045,9 +1045,13 @@ EXPORT_SYMBOL_GPL(af_alg_sendpage); + void af_alg_free_resources(struct af_alg_async_req *areq) + { + struct sock *sk = areq->sk; ++ struct af_alg_ctx *ctx; + + af_alg_free_areq_sgls(areq); + sock_kfree_s(sk, areq, areq->areqlen); ++ ++ ctx = alg_sk(sk)->private; ++ ctx->inflight = false; + } + EXPORT_SYMBOL_GPL(af_alg_free_resources); + +@@ -1117,11 +1121,19 @@ EXPORT_SYMBOL_GPL(af_alg_poll); + struct af_alg_async_req *af_alg_alloc_areq(struct sock *sk, + unsigned int areqlen) + { +- struct af_alg_async_req *areq = sock_kmalloc(sk, areqlen, GFP_KERNEL); ++ struct af_alg_ctx *ctx = alg_sk(sk)->private; ++ struct af_alg_async_req *areq; ++ ++ /* Only one AIO request can be in flight. */ ++ if (ctx->inflight) ++ return ERR_PTR(-EBUSY); + ++ areq = sock_kmalloc(sk, areqlen, GFP_KERNEL); + if (unlikely(!areq)) + return ERR_PTR(-ENOMEM); + ++ ctx->inflight = true; ++ + areq->areqlen = areqlen; + areq->sk = sk; + areq->last_rsgl = NULL; +diff --git a/crypto/scompress.c b/crypto/scompress.c +index 738f4f8f0f41a..4d6366a444007 100644 +--- a/crypto/scompress.c ++++ b/crypto/scompress.c +@@ -124,6 +124,7 @@ static int scomp_acomp_comp_decomp(struct acomp_req *req, int dir) + struct crypto_scomp *scomp = *tfm_ctx; + void **ctx = acomp_request_ctx(req); + struct scomp_scratch *scratch; ++ unsigned int dlen; + int ret; + + if (!req->src || !req->slen || req->slen > SCOMP_SCRATCH_SIZE) +@@ -135,6 +136,8 @@ static int scomp_acomp_comp_decomp(struct acomp_req *req, int dir) + if (!req->dlen || req->dlen > SCOMP_SCRATCH_SIZE) + req->dlen = SCOMP_SCRATCH_SIZE; + ++ dlen = req->dlen; ++ + scratch = raw_cpu_ptr(&scomp_scratch); + spin_lock(&scratch->lock); + +@@ -152,6 +155,9 @@ static int scomp_acomp_comp_decomp(struct acomp_req *req, int dir) + ret = -ENOMEM; + goto out; + } ++ } else if (req->dlen > dlen) { ++ ret = -ENOSPC; ++ goto out; + } + scatterwalk_map_and_copy(scratch->dst, req->dst, 0, req->dlen, + 1); +diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c +index e648158368a7d..088db2356998f 100644 +--- a/drivers/acpi/acpi_extlog.c ++++ b/drivers/acpi/acpi_extlog.c +@@ -145,9 +145,14 @@ static int extlog_print(struct notifier_block *nb, unsigned long val, + static u32 err_seq; + + estatus = extlog_elog_entry_check(cpu, bank); +- if (estatus == NULL || (mce->kflags & MCE_HANDLED_CEC)) ++ if (!estatus) + return NOTIFY_DONE; + ++ if (mce->kflags & MCE_HANDLED_CEC) { ++ estatus->block_status = 0; ++ return NOTIFY_DONE; ++ } ++ + memcpy(elog_buf, (void *)estatus, ELOG_ENTRY_LEN); + /* clear record status to enable BIOS to update it again */ + estatus->block_status = 0; +diff --git a/drivers/acpi/acpi_lpit.c b/drivers/acpi/acpi_lpit.c +index 50540d4d4948e..2c015ecf71853 100644 +--- a/drivers/acpi/acpi_lpit.c ++++ b/drivers/acpi/acpi_lpit.c +@@ -98,7 +98,7 @@ static void lpit_update_residency(struct lpit_residency_info *info, + struct acpi_lpit_native *lpit_native) + { + info->frequency = lpit_native->counter_frequency ? +- lpit_native->counter_frequency : tsc_khz * 1000; ++ lpit_native->counter_frequency : mul_u32_u32(tsc_khz, 1000U); + if (!info->frequency) + info->frequency = 1; + +diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c +index f08ffa75f4a76..8b44743945c8b 100644 +--- a/drivers/acpi/acpi_lpss.c ++++ b/drivers/acpi/acpi_lpss.c +@@ -450,8 +450,9 @@ static int register_device_clock(struct acpi_device *adev, + if (!clk_name) + return -ENOMEM; + clk = clk_register_fractional_divider(NULL, clk_name, parent, ++ 0, prv_base, 1, 15, 16, 15, + CLK_FRAC_DIVIDER_POWER_OF_TWO_PS, +- prv_base, 1, 15, 16, 15, 0, NULL); ++ NULL); + parent = clk_name; + + clk_name = kasprintf(GFP_KERNEL, "%s-update", devname); +diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c +index ed318485eb192..f7852fb75ab39 100644 +--- a/drivers/acpi/acpi_video.c ++++ b/drivers/acpi/acpi_video.c +@@ -1726,12 +1726,12 @@ static void acpi_video_dev_register_backlight(struct acpi_video_device *device) + return; + count++; + +- acpi_get_parent(device->dev->handle, &acpi_parent); +- +- pdev = acpi_get_pci_dev(acpi_parent); +- if (pdev) { +- parent = &pdev->dev; +- pci_dev_put(pdev); ++ if (ACPI_SUCCESS(acpi_get_parent(device->dev->handle, &acpi_parent))) { ++ pdev = acpi_get_pci_dev(acpi_parent); ++ if (pdev) { ++ parent = &pdev->dev; ++ pci_dev_put(pdev); ++ } + } + + memset(&props, 0, sizeof(struct backlight_properties)); +diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c +index 0565c18c2ee31..62aee900af3df 100644 +--- a/drivers/acpi/property.c ++++ b/drivers/acpi/property.c +@@ -851,6 +851,7 @@ static int acpi_get_ref_args(struct fwnode_reference_args *args, + * @index: Index of the reference to return + * @num_args: Maximum number of arguments after each reference + * @args: Location to store the returned reference with optional arguments ++ * (may be NULL) + * + * Find property with @name, verifify that it is a package containing at least + * one object reference and if so, store the ACPI device object pointer to the +@@ -907,6 +908,9 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode, + if (!device) + return -EINVAL; + ++ if (!args) ++ return 0; ++ + args->fwnode = acpi_fwnode_handle(device); + args->nargs = 0; + return 0; +diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c +index ed607850f87fb..fcbb750b1ccc3 100644 +--- a/drivers/android/binder_alloc.c ++++ b/drivers/android/binder_alloc.c +@@ -271,7 +271,7 @@ static int binder_update_page_range(struct binder_alloc *alloc, int allocate, + } + if (mm) { + mmap_write_unlock(mm); +- mmput(mm); ++ mmput_async(mm); + } + return 0; + +@@ -304,7 +304,7 @@ err_page_ptr_cleared: + err_no_vma: + if (mm) { + mmap_write_unlock(mm); +- mmput(mm); ++ mmput_async(mm); + } + return vma ? -ENOMEM : -ESRCH; + } +@@ -344,8 +344,7 @@ static bool debug_low_async_space_locked(struct binder_alloc *alloc, int pid) + continue; + if (!buffer->async_transaction) + continue; +- total_alloc_size += binder_alloc_buffer_size(alloc, buffer) +- + sizeof(struct binder_buffer); ++ total_alloc_size += binder_alloc_buffer_size(alloc, buffer); + num_buffers++; + } + +@@ -407,17 +406,17 @@ static struct binder_buffer *binder_alloc_new_buf_locked( + alloc->pid, extra_buffers_size); + return ERR_PTR(-EINVAL); + } +- if (is_async && +- alloc->free_async_space < size + sizeof(struct binder_buffer)) { ++ ++ /* Pad 0-size buffers so they get assigned unique addresses */ ++ size = max(size, sizeof(void *)); ++ ++ if (is_async && alloc->free_async_space < size) { + binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC, + "%d: binder_alloc_buf size %zd failed, no async space left\n", + alloc->pid, size); + return ERR_PTR(-ENOSPC); + } + +- /* Pad 0-size buffers so they get assigned unique addresses */ +- size = max(size, sizeof(void *)); +- + while (n) { + buffer = rb_entry(n, struct binder_buffer, rb_node); + BUG_ON(!buffer->free); +@@ -519,7 +518,7 @@ static struct binder_buffer *binder_alloc_new_buf_locked( + buffer->pid = pid; + buffer->oneway_spam_suspect = false; + if (is_async) { +- alloc->free_async_space -= size + sizeof(struct binder_buffer); ++ alloc->free_async_space -= size; + binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC_ASYNC, + "%d: binder_alloc_buf size %zd async free %zd\n", + alloc->pid, size, alloc->free_async_space); +@@ -657,8 +656,7 @@ static void binder_free_buf_locked(struct binder_alloc *alloc, + BUG_ON(buffer->user_data > alloc->buffer + alloc->buffer_size); + + if (buffer->async_transaction) { +- alloc->free_async_space += buffer_size + sizeof(struct binder_buffer); +- ++ alloc->free_async_space += buffer_size; + binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC_ASYNC, + "%d: binder_free_buf size %zd async free %zd\n", + alloc->pid, size, alloc->free_async_space); +diff --git a/drivers/base/node.c b/drivers/base/node.c +index faf3597a96da9..a4141b57b1478 100644 +--- a/drivers/base/node.c ++++ b/drivers/base/node.c +@@ -859,11 +859,15 @@ int __register_one_node(int nid) + { + int error; + int cpu; ++ struct node *node; + +- node_devices[nid] = kzalloc(sizeof(struct node), GFP_KERNEL); +- if (!node_devices[nid]) ++ node = kzalloc(sizeof(struct node), GFP_KERNEL); ++ if (!node) + return -ENOMEM; + ++ INIT_LIST_HEAD(&node->access_list); ++ node_devices[nid] = node; ++ + error = register_node(node_devices[nid], nid); + + /* link cpu under this node */ +@@ -872,7 +876,6 @@ int __register_one_node(int nid) + register_cpu_under_node(cpu, nid); + } + +- INIT_LIST_HEAD(&node_devices[nid]->access_list); + node_init_caches(nid); + + return error; +diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c +index 0a482212c7e8e..44153caa893ad 100644 +--- a/drivers/base/swnode.c ++++ b/drivers/base/swnode.c +@@ -541,6 +541,9 @@ software_node_get_reference_args(const struct fwnode_handle *fwnode, + if (nargs > NR_FWNODE_REFERENCE_ARGS) + return -EINVAL; + ++ if (!args) ++ return 0; ++ + args->fwnode = software_node_get(refnode); + args->nargs = nargs; + +diff --git a/drivers/block/loop.c b/drivers/block/loop.c +index 127e3ceb59799..12ff6f58b8a90 100644 +--- a/drivers/block/loop.c ++++ b/drivers/block/loop.c +@@ -165,39 +165,37 @@ static loff_t get_loop_size(struct loop_device *lo, struct file *file) + return get_size(lo->lo_offset, lo->lo_sizelimit, file); + } + ++/* ++ * We support direct I/O only if lo_offset is aligned with the logical I/O size ++ * of backing device, and the logical block size of loop is bigger than that of ++ * the backing device. ++ */ ++static bool lo_bdev_can_use_dio(struct loop_device *lo, ++ struct block_device *backing_bdev) ++{ ++ unsigned short sb_bsize = bdev_logical_block_size(backing_bdev); ++ ++ if (queue_logical_block_size(lo->lo_queue) < sb_bsize) ++ return false; ++ if (lo->lo_offset & (sb_bsize - 1)) ++ return false; ++ return true; ++} ++ + static void __loop_update_dio(struct loop_device *lo, bool dio) + { + struct file *file = lo->lo_backing_file; +- struct address_space *mapping = file->f_mapping; +- struct inode *inode = mapping->host; +- unsigned short sb_bsize = 0; +- unsigned dio_align = 0; ++ struct inode *inode = file->f_mapping->host; ++ struct block_device *backing_bdev = NULL; + bool use_dio; + +- if (inode->i_sb->s_bdev) { +- sb_bsize = bdev_logical_block_size(inode->i_sb->s_bdev); +- dio_align = sb_bsize - 1; +- } ++ if (S_ISBLK(inode->i_mode)) ++ backing_bdev = I_BDEV(inode); ++ else if (inode->i_sb->s_bdev) ++ backing_bdev = inode->i_sb->s_bdev; + +- /* +- * We support direct I/O only if lo_offset is aligned with the +- * logical I/O size of backing device, and the logical block +- * size of loop is bigger than the backing device's. +- * +- * TODO: the above condition may be loosed in the future, and +- * direct I/O may be switched runtime at that time because most +- * of requests in sane applications should be PAGE_SIZE aligned +- */ +- if (dio) { +- if (queue_logical_block_size(lo->lo_queue) >= sb_bsize && +- !(lo->lo_offset & dio_align) && +- (file->f_mode & FMODE_CAN_ODIRECT)) +- use_dio = true; +- else +- use_dio = false; +- } else { +- use_dio = false; +- } ++ use_dio = dio && (file->f_mode & FMODE_CAN_ODIRECT) && ++ (!backing_bdev || lo_bdev_can_use_dio(lo, backing_bdev)); + + if (lo->use_dio == use_dio) + return; +diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c +index e9f38eba2f133..959952e8ede38 100644 +--- a/drivers/block/null_blk/main.c ++++ b/drivers/block/null_blk/main.c +@@ -2114,11 +2114,8 @@ static int null_add_dev(struct nullb_device *dev) + + blk_queue_logical_block_size(nullb->q, dev->blocksize); + blk_queue_physical_block_size(nullb->q, dev->blocksize); +- if (!dev->max_sectors) +- dev->max_sectors = queue_max_hw_sectors(nullb->q); +- dev->max_sectors = min_t(unsigned int, dev->max_sectors, +- BLK_DEF_MAX_SECTORS); +- blk_queue_max_hw_sectors(nullb->q, dev->max_sectors); ++ if (dev->max_sectors) ++ blk_queue_max_hw_sectors(nullb->q, dev->max_sectors); + + if (dev->virt_boundary) + blk_queue_virt_boundary(nullb->q, PAGE_SIZE - 1); +@@ -2218,12 +2215,6 @@ static int __init null_init(void) + g_bs = PAGE_SIZE; + } + +- if (g_max_sectors > BLK_DEF_MAX_SECTORS) { +- pr_warn("invalid max sectors\n"); +- pr_warn("defaults max sectors to %u\n", BLK_DEF_MAX_SECTORS); +- g_max_sectors = BLK_DEF_MAX_SECTORS; +- } +- + if (g_home_node != NUMA_NO_NODE && g_home_node >= nr_online_nodes) { + pr_err("invalid home_node value\n"); + g_home_node = NUMA_NO_NODE; +diff --git a/drivers/bluetooth/btmtkuart.c b/drivers/bluetooth/btmtkuart.c +index c98691cdbbd55..04b72394dda5b 100644 +--- a/drivers/bluetooth/btmtkuart.c ++++ b/drivers/bluetooth/btmtkuart.c +@@ -337,7 +337,7 @@ mtk_stp_split(struct btmtkuart_dev *bdev, const unsigned char *data, int count, + return data; + } + +-static int btmtkuart_recv(struct hci_dev *hdev, const u8 *data, size_t count) ++static void btmtkuart_recv(struct hci_dev *hdev, const u8 *data, size_t count) + { + struct btmtkuart_dev *bdev = hci_get_drvdata(hdev); + const unsigned char *p_left = data, *p_h4; +@@ -376,25 +376,20 @@ static int btmtkuart_recv(struct hci_dev *hdev, const u8 *data, size_t count) + bt_dev_err(bdev->hdev, + "Frame reassembly failed (%d)", err); + bdev->rx_skb = NULL; +- return err; ++ return; + } + + sz_left -= sz_h4; + p_left += sz_h4; + } +- +- return 0; + } + + static int btmtkuart_receive_buf(struct serdev_device *serdev, const u8 *data, + size_t count) + { + struct btmtkuart_dev *bdev = serdev_device_get_drvdata(serdev); +- int err; + +- err = btmtkuart_recv(bdev->hdev, data, count); +- if (err < 0) +- return err; ++ btmtkuart_recv(bdev->hdev, data, count); + + bdev->hdev->stat.byte_rx += count; + +diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c +index c7d8cbd22bacc..5acb35236c58d 100644 +--- a/drivers/clk/clk-si5341.c ++++ b/drivers/clk/clk-si5341.c +@@ -892,10 +892,8 @@ static int si5341_output_clk_set_rate(struct clk_hw *hw, unsigned long rate, + r[0] = r_div ? (r_div & 0xff) : 1; + r[1] = (r_div >> 8) & 0xff; + r[2] = (r_div >> 16) & 0xff; +- err = regmap_bulk_write(output->data->regmap, ++ return regmap_bulk_write(output->data->regmap, + SI5341_OUT_R_REG(output), r, 3); +- +- return 0; + } + + static int si5341_output_reparent(struct clk_si5341_output *output, u8 index) +diff --git a/drivers/clk/qcom/gpucc-sm8150.c b/drivers/clk/qcom/gpucc-sm8150.c +index 8422fd0474932..c89a5b59ddb7c 100644 +--- a/drivers/clk/qcom/gpucc-sm8150.c ++++ b/drivers/clk/qcom/gpucc-sm8150.c +@@ -37,8 +37,8 @@ static struct alpha_pll_config gpu_cc_pll1_config = { + .config_ctl_hi_val = 0x00002267, + .config_ctl_hi1_val = 0x00000024, + .test_ctl_val = 0x00000000, +- .test_ctl_hi_val = 0x00000002, +- .test_ctl_hi1_val = 0x00000000, ++ .test_ctl_hi_val = 0x00000000, ++ .test_ctl_hi1_val = 0x00000020, + .user_ctl_val = 0x00000000, + .user_ctl_hi_val = 0x00000805, + .user_ctl_hi1_val = 0x000000d0, +diff --git a/drivers/clk/qcom/videocc-sm8150.c b/drivers/clk/qcom/videocc-sm8150.c +index 1afdbe4a249d6..52a9a453a1432 100644 +--- a/drivers/clk/qcom/videocc-sm8150.c ++++ b/drivers/clk/qcom/videocc-sm8150.c +@@ -33,6 +33,7 @@ static struct alpha_pll_config video_pll0_config = { + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x00002267, + .config_ctl_hi1_val = 0x00000024, ++ .test_ctl_hi1_val = 0x00000020, + .user_ctl_val = 0x00000000, + .user_ctl_hi_val = 0x00000805, + .user_ctl_hi1_val = 0x000000D0, +@@ -214,6 +215,10 @@ static const struct regmap_config video_cc_sm8150_regmap_config = { + + static const struct qcom_reset_map video_cc_sm8150_resets[] = { + [VIDEO_CC_MVSC_CORE_CLK_BCR] = { 0x850, 2 }, ++ [VIDEO_CC_INTERFACE_BCR] = { 0x8f0 }, ++ [VIDEO_CC_MVS0_BCR] = { 0x870 }, ++ [VIDEO_CC_MVS1_BCR] = { 0x8b0 }, ++ [VIDEO_CC_MVSC_BCR] = { 0x810 }, + }; + + static const struct qcom_cc_desc video_cc_sm8150_desc = { +diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c +index 84767cfc1e739..473feb36a38f2 100644 +--- a/drivers/clk/renesas/rzg2l-cpg.c ++++ b/drivers/clk/renesas/rzg2l-cpg.c +@@ -1115,41 +1115,33 @@ fail: + + #define rcdev_to_priv(x) container_of(x, struct rzg2l_cpg_priv, rcdev) + +-static int rzg2l_cpg_reset(struct reset_controller_dev *rcdev, +- unsigned long id) +-{ +- struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); +- const struct rzg2l_cpg_info *info = priv->info; +- unsigned int reg = info->resets[id].off; +- u32 dis = BIT(info->resets[id].bit); +- u32 we = dis << 16; +- +- dev_dbg(rcdev->dev, "reset id:%ld offset:0x%x\n", id, CLK_RST_R(reg)); +- +- /* Reset module */ +- writel(we, priv->base + CLK_RST_R(reg)); +- +- /* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */ +- udelay(35); +- +- /* Release module from reset state */ +- writel(we | dis, priv->base + CLK_RST_R(reg)); +- +- return 0; +-} +- + static int rzg2l_cpg_assert(struct reset_controller_dev *rcdev, + unsigned long id) + { + struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); + const struct rzg2l_cpg_info *info = priv->info; + unsigned int reg = info->resets[id].off; +- u32 value = BIT(info->resets[id].bit) << 16; ++ u32 mask = BIT(info->resets[id].bit); ++ s8 monbit = info->resets[id].monbit; ++ u32 value = mask << 16; + + dev_dbg(rcdev->dev, "assert id:%ld offset:0x%x\n", id, CLK_RST_R(reg)); + + writel(value, priv->base + CLK_RST_R(reg)); +- return 0; ++ ++ if (info->has_clk_mon_regs) { ++ reg = CLK_MRST_R(reg); ++ } else if (monbit >= 0) { ++ reg = CPG_RST_MON; ++ mask = BIT(monbit); ++ } else { ++ /* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */ ++ udelay(35); ++ return 0; ++ } ++ ++ return readl_poll_timeout_atomic(priv->base + reg, value, ++ value & mask, 10, 200); + } + + static int rzg2l_cpg_deassert(struct reset_controller_dev *rcdev, +@@ -1158,14 +1150,40 @@ static int rzg2l_cpg_deassert(struct reset_controller_dev *rcdev, + struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); + const struct rzg2l_cpg_info *info = priv->info; + unsigned int reg = info->resets[id].off; +- u32 dis = BIT(info->resets[id].bit); +- u32 value = (dis << 16) | dis; ++ u32 mask = BIT(info->resets[id].bit); ++ s8 monbit = info->resets[id].monbit; ++ u32 value = (mask << 16) | mask; + + dev_dbg(rcdev->dev, "deassert id:%ld offset:0x%x\n", id, + CLK_RST_R(reg)); + + writel(value, priv->base + CLK_RST_R(reg)); +- return 0; ++ ++ if (info->has_clk_mon_regs) { ++ reg = CLK_MRST_R(reg); ++ } else if (monbit >= 0) { ++ reg = CPG_RST_MON; ++ mask = BIT(monbit); ++ } else { ++ /* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */ ++ udelay(35); ++ return 0; ++ } ++ ++ return readl_poll_timeout_atomic(priv->base + reg, value, ++ !(value & mask), 10, 200); ++} ++ ++static int rzg2l_cpg_reset(struct reset_controller_dev *rcdev, ++ unsigned long id) ++{ ++ int ret; ++ ++ ret = rzg2l_cpg_assert(rcdev, id); ++ if (ret) ++ return ret; ++ ++ return rzg2l_cpg_deassert(rcdev, id); + } + + static int rzg2l_cpg_status(struct reset_controller_dev *rcdev, +@@ -1173,18 +1191,21 @@ static int rzg2l_cpg_status(struct reset_controller_dev *rcdev, + { + struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); + const struct rzg2l_cpg_info *info = priv->info; +- unsigned int reg = info->resets[id].off; +- u32 bitmask = BIT(info->resets[id].bit); + s8 monbit = info->resets[id].monbit; ++ unsigned int reg; ++ u32 bitmask; + + if (info->has_clk_mon_regs) { +- return !!(readl(priv->base + CLK_MRST_R(reg)) & bitmask); ++ reg = CLK_MRST_R(info->resets[id].off); ++ bitmask = BIT(info->resets[id].bit); + } else if (monbit >= 0) { +- u32 monbitmask = BIT(monbit); +- +- return !!(readl(priv->base + CPG_RST_MON) & monbitmask); ++ reg = CPG_RST_MON; ++ bitmask = BIT(monbit); ++ } else { ++ return -ENOTSUPP; + } +- return -ENOTSUPP; ++ ++ return !!(readl(priv->base + reg) & bitmask); + } + + static const struct reset_control_ops rzg2l_cpg_reset_ops = { +diff --git a/drivers/clk/zynqmp/clk-mux-zynqmp.c b/drivers/clk/zynqmp/clk-mux-zynqmp.c +index 60359333f26db..9b5d3050b7422 100644 +--- a/drivers/clk/zynqmp/clk-mux-zynqmp.c ++++ b/drivers/clk/zynqmp/clk-mux-zynqmp.c +@@ -89,7 +89,7 @@ static int zynqmp_clk_mux_set_parent(struct clk_hw *hw, u8 index) + static const struct clk_ops zynqmp_clk_mux_ops = { + .get_parent = zynqmp_clk_mux_get_parent, + .set_parent = zynqmp_clk_mux_set_parent, +- .determine_rate = __clk_mux_determine_rate, ++ .determine_rate = __clk_mux_determine_rate_closest, + }; + + static const struct clk_ops zynqmp_clk_mux_ro_ops = { +diff --git a/drivers/clk/zynqmp/divider.c b/drivers/clk/zynqmp/divider.c +index 33a3b2a226595..5a00487ae408b 100644 +--- a/drivers/clk/zynqmp/divider.c ++++ b/drivers/clk/zynqmp/divider.c +@@ -110,52 +110,6 @@ static unsigned long zynqmp_clk_divider_recalc_rate(struct clk_hw *hw, + return DIV_ROUND_UP_ULL(parent_rate, value); + } + +-static void zynqmp_get_divider2_val(struct clk_hw *hw, +- unsigned long rate, +- struct zynqmp_clk_divider *divider, +- u32 *bestdiv) +-{ +- int div1; +- int div2; +- long error = LONG_MAX; +- unsigned long div1_prate; +- struct clk_hw *div1_parent_hw; +- struct zynqmp_clk_divider *pdivider; +- struct clk_hw *div2_parent_hw = clk_hw_get_parent(hw); +- +- if (!div2_parent_hw) +- return; +- +- pdivider = to_zynqmp_clk_divider(div2_parent_hw); +- if (!pdivider) +- return; +- +- div1_parent_hw = clk_hw_get_parent(div2_parent_hw); +- if (!div1_parent_hw) +- return; +- +- div1_prate = clk_hw_get_rate(div1_parent_hw); +- *bestdiv = 1; +- for (div1 = 1; div1 <= pdivider->max_div;) { +- for (div2 = 1; div2 <= divider->max_div;) { +- long new_error = ((div1_prate / div1) / div2) - rate; +- +- if (abs(new_error) < abs(error)) { +- *bestdiv = div2; +- error = new_error; +- } +- if (divider->flags & CLK_DIVIDER_POWER_OF_TWO) +- div2 = div2 << 1; +- else +- div2++; +- } +- if (pdivider->flags & CLK_DIVIDER_POWER_OF_TWO) +- div1 = div1 << 1; +- else +- div1++; +- } +-} +- + /** + * zynqmp_clk_divider_round_rate() - Round rate of divider clock + * @hw: handle between common and hardware-specific interfaces +@@ -174,6 +128,7 @@ static long zynqmp_clk_divider_round_rate(struct clk_hw *hw, + u32 div_type = divider->div_type; + u32 bestdiv; + int ret; ++ u8 width; + + /* if read only, just return current value */ + if (divider->flags & CLK_DIVIDER_READ_ONLY) { +@@ -193,23 +148,12 @@ static long zynqmp_clk_divider_round_rate(struct clk_hw *hw, + return DIV_ROUND_UP_ULL((u64)*prate, bestdiv); + } + +- bestdiv = zynqmp_divider_get_val(*prate, rate, divider->flags); +- +- /* +- * In case of two divisors, compute best divider values and return +- * divider2 value based on compute value. div1 will be automatically +- * set to optimum based on required total divider value. +- */ +- if (div_type == TYPE_DIV2 && +- (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) { +- zynqmp_get_divider2_val(hw, rate, divider, &bestdiv); +- } ++ width = fls(divider->max_div); + +- if ((clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) && divider->is_frac) +- bestdiv = rate % *prate ? 1 : bestdiv; ++ rate = divider_round_rate(hw, rate, prate, NULL, width, divider->flags); + +- bestdiv = min_t(u32, bestdiv, divider->max_div); +- *prate = rate * bestdiv; ++ if (divider->is_frac && (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) && (rate % *prate)) ++ *prate = rate; + + return rate; + } +diff --git a/drivers/clocksource/timer-ti-dm.c b/drivers/clocksource/timer-ti-dm.c +index ec86aecb748f1..7f9c1f58a9477 100644 +--- a/drivers/clocksource/timer-ti-dm.c ++++ b/drivers/clocksource/timer-ti-dm.c +@@ -184,7 +184,7 @@ static inline u32 dmtimer_read(struct dmtimer *timer, u32 reg) + * dmtimer_write - write timer registers in posted and non-posted mode + * @timer: timer pointer over which write operation is to perform + * @reg: lowest byte holds the register offset +- * @value: data to write into the register ++ * @val: data to write into the register + * + * The posted mode bit is encoded in reg. Note that in posted mode, the write + * pending bit must be checked. Otherwise a write on a register which has a +@@ -937,7 +937,7 @@ static int omap_dm_timer_set_int_enable(struct omap_dm_timer *cookie, + + /** + * omap_dm_timer_set_int_disable - disable timer interrupts +- * @timer: pointer to timer handle ++ * @cookie: pointer to timer cookie + * @mask: bit mask of interrupts to be disabled + * + * Disables the specified timer interrupts for a timer. +diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c +index 69a8742c0a7a3..8514bb62dd10b 100644 +--- a/drivers/cpufreq/cpufreq-dt-platdev.c ++++ b/drivers/cpufreq/cpufreq-dt-platdev.c +@@ -176,7 +176,7 @@ static bool __init cpu0_node_has_opp_v2_prop(void) + struct device_node *np = of_cpu_device_node_get(0); + bool ret = false; + +- if (of_get_property(np, "operating-points-v2", NULL)) ++ if (of_property_present(np, "operating-points-v2")) + ret = true; + + of_node_put(np); +diff --git a/drivers/cpufreq/imx-cpufreq-dt.c b/drivers/cpufreq/imx-cpufreq-dt.c +index 76e553af20711..535867a7dfdde 100644 +--- a/drivers/cpufreq/imx-cpufreq-dt.c ++++ b/drivers/cpufreq/imx-cpufreq-dt.c +@@ -89,7 +89,7 @@ static int imx_cpufreq_dt_probe(struct platform_device *pdev) + + cpu_dev = get_cpu_device(0); + +- if (!of_find_property(cpu_dev->of_node, "cpu-supply", NULL)) ++ if (!of_property_present(cpu_dev->of_node, "cpu-supply")) + return -ENODEV; + + if (of_machine_is_compatible("fsl,imx7ulp")) { +diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c +index 925fc17eaacb2..39b0362a3b9ac 100644 +--- a/drivers/cpufreq/imx6q-cpufreq.c ++++ b/drivers/cpufreq/imx6q-cpufreq.c +@@ -230,7 +230,7 @@ static int imx6q_opp_check_speed_grading(struct device *dev) + u32 val; + int ret; + +- if (of_find_property(dev->of_node, "nvmem-cells", NULL)) { ++ if (of_property_present(dev->of_node, "nvmem-cells")) { + ret = nvmem_cell_read_u32(dev, "speed_grade", &val); + if (ret) + return ret; +@@ -285,7 +285,7 @@ static int imx6ul_opp_check_speed_grading(struct device *dev) + u32 val; + int ret = 0; + +- if (of_find_property(dev->of_node, "nvmem-cells", NULL)) { ++ if (of_property_present(dev->of_node, "nvmem-cells")) { + ret = nvmem_cell_read_u32(dev, "speed_grade", &val); + if (ret) + return ret; +diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c +index 513a071845c26..028df8a5f537a 100644 +--- a/drivers/cpufreq/scmi-cpufreq.c ++++ b/drivers/cpufreq/scmi-cpufreq.c +@@ -310,8 +310,11 @@ static int scmi_cpufreq_probe(struct scmi_device *sdev) + + #ifdef CONFIG_COMMON_CLK + /* dummy clock provider as needed by OPP if clocks property is used */ +- if (of_find_property(dev->of_node, "#clock-cells", NULL)) +- devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, NULL); ++ if (of_property_present(dev->of_node, "#clock-cells")) { ++ ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, NULL); ++ if (ret) ++ return dev_err_probe(dev, ret, "%s: registering clock provider failed\n", __func__); ++ } + #endif + + ret = cpufreq_register_driver(&scmi_cpufreq_driver); +diff --git a/drivers/cpufreq/tegra20-cpufreq.c b/drivers/cpufreq/tegra20-cpufreq.c +index ab7ac7df9e62e..dfd2de4f8e07e 100644 +--- a/drivers/cpufreq/tegra20-cpufreq.c ++++ b/drivers/cpufreq/tegra20-cpufreq.c +@@ -25,7 +25,7 @@ static bool cpu0_node_has_opp_v2_prop(void) + struct device_node *np = of_cpu_device_node_get(0); + bool ret = false; + +- if (of_get_property(np, "operating-points-v2", NULL)) ++ if (of_property_present(np, "operating-points-v2")) + ret = true; + + of_node_put(np); +diff --git a/drivers/crypto/ccp/ccp-ops.c b/drivers/crypto/ccp/ccp-ops.c +index aa4e1a5006919..cb8e99936abb7 100644 +--- a/drivers/crypto/ccp/ccp-ops.c ++++ b/drivers/crypto/ccp/ccp-ops.c +@@ -179,8 +179,11 @@ static int ccp_init_dm_workarea(struct ccp_dm_workarea *wa, + + wa->dma.address = dma_map_single(wa->dev, wa->address, len, + dir); +- if (dma_mapping_error(wa->dev, wa->dma.address)) ++ if (dma_mapping_error(wa->dev, wa->dma.address)) { ++ kfree(wa->address); ++ wa->address = NULL; + return -ENOMEM; ++ } + + wa->dma.length = len; + } +diff --git a/drivers/crypto/hisilicon/hpre/hpre_main.c b/drivers/crypto/hisilicon/hpre/hpre_main.c +index ff8a5f20a5df0..269df4ec148ba 100644 +--- a/drivers/crypto/hisilicon/hpre/hpre_main.c ++++ b/drivers/crypto/hisilicon/hpre/hpre_main.c +@@ -118,8 +118,6 @@ + #define HPRE_DFX_COMMON2_LEN 0xE + #define HPRE_DFX_CORE_LEN 0x43 + +-#define HPRE_DEV_ALG_MAX_LEN 256 +- + static const char hpre_name[] = "hisi_hpre"; + static struct dentry *hpre_debugfs_root; + static const struct pci_device_id hpre_dev_ids[] = { +@@ -135,12 +133,7 @@ struct hpre_hw_error { + const char *msg; + }; + +-struct hpre_dev_alg { +- u32 alg_msk; +- const char *alg; +-}; +- +-static const struct hpre_dev_alg hpre_dev_algs[] = { ++static const struct qm_dev_alg hpre_dev_algs[] = { + { + .alg_msk = BIT(0), + .alg = "rsa\n" +@@ -233,6 +226,20 @@ static const struct hisi_qm_cap_info hpre_basic_info[] = { + {HPRE_CORE10_ALG_BITMAP_CAP, 0x3170, 0, GENMASK(31, 0), 0x0, 0x10, 0x10} + }; + ++enum hpre_pre_store_cap_idx { ++ HPRE_CLUSTER_NUM_CAP_IDX = 0x0, ++ HPRE_CORE_ENABLE_BITMAP_CAP_IDX, ++ HPRE_DRV_ALG_BITMAP_CAP_IDX, ++ HPRE_DEV_ALG_BITMAP_CAP_IDX, ++}; ++ ++static const u32 hpre_pre_store_caps[] = { ++ HPRE_CLUSTER_NUM_CAP, ++ HPRE_CORE_ENABLE_BITMAP_CAP, ++ HPRE_DRV_ALG_BITMAP_CAP, ++ HPRE_DEV_ALG_BITMAP_CAP, ++}; ++ + static const struct hpre_hw_error hpre_hw_errors[] = { + { + .int_msk = BIT(0), +@@ -352,42 +359,13 @@ bool hpre_check_alg_support(struct hisi_qm *qm, u32 alg) + { + u32 cap_val; + +- cap_val = hisi_qm_get_hw_info(qm, hpre_basic_info, HPRE_DRV_ALG_BITMAP_CAP, qm->cap_ver); ++ cap_val = qm->cap_tables.dev_cap_table[HPRE_DRV_ALG_BITMAP_CAP_IDX].cap_val; + if (alg & cap_val) + return true; + + return false; + } + +-static int hpre_set_qm_algs(struct hisi_qm *qm) +-{ +- struct device *dev = &qm->pdev->dev; +- char *algs, *ptr; +- u32 alg_msk; +- int i; +- +- if (!qm->use_sva) +- return 0; +- +- algs = devm_kzalloc(dev, HPRE_DEV_ALG_MAX_LEN * sizeof(char), GFP_KERNEL); +- if (!algs) +- return -ENOMEM; +- +- alg_msk = hisi_qm_get_hw_info(qm, hpre_basic_info, HPRE_DEV_ALG_BITMAP_CAP, qm->cap_ver); +- +- for (i = 0; i < ARRAY_SIZE(hpre_dev_algs); i++) +- if (alg_msk & hpre_dev_algs[i].alg_msk) +- strcat(algs, hpre_dev_algs[i].alg); +- +- ptr = strrchr(algs, '\n'); +- if (ptr) +- *ptr = '\0'; +- +- qm->uacce->algs = algs; +- +- return 0; +-} +- + static int hpre_diff_regs_show(struct seq_file *s, void *unused) + { + struct hisi_qm *qm = s->private; +@@ -457,16 +435,6 @@ static u32 vfs_num; + module_param_cb(vfs_num, &vfs_num_ops, &vfs_num, 0444); + MODULE_PARM_DESC(vfs_num, "Number of VFs to enable(1-63), 0(default)"); + +-static inline int hpre_cluster_num(struct hisi_qm *qm) +-{ +- return hisi_qm_get_hw_info(qm, hpre_basic_info, HPRE_CLUSTER_NUM_CAP, qm->cap_ver); +-} +- +-static inline int hpre_cluster_core_mask(struct hisi_qm *qm) +-{ +- return hisi_qm_get_hw_info(qm, hpre_basic_info, HPRE_CORE_ENABLE_BITMAP_CAP, qm->cap_ver); +-} +- + struct hisi_qp *hpre_create_qp(u8 type) + { + int node = cpu_to_node(smp_processor_id()); +@@ -533,13 +501,15 @@ static int hpre_cfg_by_dsm(struct hisi_qm *qm) + + static int hpre_set_cluster(struct hisi_qm *qm) + { +- u32 cluster_core_mask = hpre_cluster_core_mask(qm); +- u8 clusters_num = hpre_cluster_num(qm); + struct device *dev = &qm->pdev->dev; + unsigned long offset; ++ u32 cluster_core_mask; ++ u8 clusters_num; + u32 val = 0; + int ret, i; + ++ cluster_core_mask = qm->cap_tables.dev_cap_table[HPRE_CORE_ENABLE_BITMAP_CAP_IDX].cap_val; ++ clusters_num = qm->cap_tables.dev_cap_table[HPRE_CLUSTER_NUM_CAP_IDX].cap_val; + for (i = 0; i < clusters_num; i++) { + offset = i * HPRE_CLSTR_ADDR_INTRVL; + +@@ -734,11 +704,12 @@ static int hpre_set_user_domain_and_cache(struct hisi_qm *qm) + + static void hpre_cnt_regs_clear(struct hisi_qm *qm) + { +- u8 clusters_num = hpre_cluster_num(qm); + unsigned long offset; ++ u8 clusters_num; + int i; + + /* clear clusterX/cluster_ctrl */ ++ clusters_num = qm->cap_tables.dev_cap_table[HPRE_CLUSTER_NUM_CAP_IDX].cap_val; + for (i = 0; i < clusters_num; i++) { + offset = HPRE_CLSTR_BASE + i * HPRE_CLSTR_ADDR_INTRVL; + writel(0x0, qm->io_base + offset + HPRE_CLUSTER_INQURY); +@@ -1025,13 +996,14 @@ static int hpre_pf_comm_regs_debugfs_init(struct hisi_qm *qm) + + static int hpre_cluster_debugfs_init(struct hisi_qm *qm) + { +- u8 clusters_num = hpre_cluster_num(qm); + struct device *dev = &qm->pdev->dev; + char buf[HPRE_DBGFS_VAL_MAX_LEN]; + struct debugfs_regset32 *regset; + struct dentry *tmp_d; ++ u8 clusters_num; + int i, ret; + ++ clusters_num = qm->cap_tables.dev_cap_table[HPRE_CLUSTER_NUM_CAP_IDX].cap_val; + for (i = 0; i < clusters_num; i++) { + ret = snprintf(buf, HPRE_DBGFS_VAL_MAX_LEN, "cluster%d", i); + if (ret >= HPRE_DBGFS_VAL_MAX_LEN) +@@ -1136,8 +1108,37 @@ static void hpre_debugfs_exit(struct hisi_qm *qm) + debugfs_remove_recursive(qm->debug.debug_root); + } + ++static int hpre_pre_store_cap_reg(struct hisi_qm *qm) ++{ ++ struct hisi_qm_cap_record *hpre_cap; ++ struct device *dev = &qm->pdev->dev; ++ size_t i, size; ++ ++ size = ARRAY_SIZE(hpre_pre_store_caps); ++ hpre_cap = devm_kzalloc(dev, sizeof(*hpre_cap) * size, GFP_KERNEL); ++ if (!hpre_cap) ++ return -ENOMEM; ++ ++ for (i = 0; i < size; i++) { ++ hpre_cap[i].type = hpre_pre_store_caps[i]; ++ hpre_cap[i].cap_val = hisi_qm_get_hw_info(qm, hpre_basic_info, ++ hpre_pre_store_caps[i], qm->cap_ver); ++ } ++ ++ if (hpre_cap[HPRE_CLUSTER_NUM_CAP_IDX].cap_val > HPRE_CLUSTERS_NUM_MAX) { ++ dev_err(dev, "Device cluster num %u is out of range for driver supports %d!\n", ++ hpre_cap[HPRE_CLUSTER_NUM_CAP_IDX].cap_val, HPRE_CLUSTERS_NUM_MAX); ++ return -EINVAL; ++ } ++ ++ qm->cap_tables.dev_cap_table = hpre_cap; ++ ++ return 0; ++} ++ + static int hpre_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) + { ++ u64 alg_msk; + int ret; + + if (pdev->revision == QM_HW_V1) { +@@ -1168,7 +1169,16 @@ static int hpre_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) + return ret; + } + +- ret = hpre_set_qm_algs(qm); ++ /* Fetch and save the value of capability registers */ ++ ret = hpre_pre_store_cap_reg(qm); ++ if (ret) { ++ pci_err(pdev, "Failed to pre-store capability registers!\n"); ++ hisi_qm_uninit(qm); ++ return ret; ++ } ++ ++ alg_msk = qm->cap_tables.dev_cap_table[HPRE_DEV_ALG_BITMAP_CAP_IDX].cap_val; ++ ret = hisi_qm_set_algs(qm, alg_msk, hpre_dev_algs, ARRAY_SIZE(hpre_dev_algs)); + if (ret) { + pci_err(pdev, "Failed to set hpre algs!\n"); + hisi_qm_uninit(qm); +@@ -1181,11 +1191,12 @@ static int hpre_show_last_regs_init(struct hisi_qm *qm) + { + int cluster_dfx_regs_num = ARRAY_SIZE(hpre_cluster_dfx_regs); + int com_dfx_regs_num = ARRAY_SIZE(hpre_com_dfx_regs); +- u8 clusters_num = hpre_cluster_num(qm); + struct qm_debug *debug = &qm->debug; + void __iomem *io_base; ++ u8 clusters_num; + int i, j, idx; + ++ clusters_num = qm->cap_tables.dev_cap_table[HPRE_CLUSTER_NUM_CAP_IDX].cap_val; + debug->last_words = kcalloc(cluster_dfx_regs_num * clusters_num + + com_dfx_regs_num, sizeof(unsigned int), GFP_KERNEL); + if (!debug->last_words) +@@ -1222,10 +1233,10 @@ static void hpre_show_last_dfx_regs(struct hisi_qm *qm) + { + int cluster_dfx_regs_num = ARRAY_SIZE(hpre_cluster_dfx_regs); + int com_dfx_regs_num = ARRAY_SIZE(hpre_com_dfx_regs); +- u8 clusters_num = hpre_cluster_num(qm); + struct qm_debug *debug = &qm->debug; + struct pci_dev *pdev = qm->pdev; + void __iomem *io_base; ++ u8 clusters_num; + int i, j, idx; + u32 val; + +@@ -1240,6 +1251,7 @@ static void hpre_show_last_dfx_regs(struct hisi_qm *qm) + hpre_com_dfx_regs[i].name, debug->last_words[i], val); + } + ++ clusters_num = qm->cap_tables.dev_cap_table[HPRE_CLUSTER_NUM_CAP_IDX].cap_val; + for (i = 0; i < clusters_num; i++) { + io_base = qm->io_base + hpre_cluster_offsets[i]; + for (j = 0; j < cluster_dfx_regs_num; j++) { +diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c +index f9acf7ecc41be..5539be1bfb402 100644 +--- a/drivers/crypto/hisilicon/qm.c ++++ b/drivers/crypto/hisilicon/qm.c +@@ -237,6 +237,8 @@ + #define QM_QOS_MAX_CIR_S 11 + #define QM_AUTOSUSPEND_DELAY 3000 + ++#define QM_DEV_ALG_MAX_LEN 256 ++ + #define QM_MK_CQC_DW3_V1(hop_num, pg_sz, buf_sz, cqe_sz) \ + (((hop_num) << QM_CQ_HOP_NUM_SHIFT) | \ + ((pg_sz) << QM_CQ_PAGE_SIZE_SHIFT) | \ +@@ -315,6 +317,13 @@ enum qm_basic_type { + QM_VF_IRQ_NUM_CAP, + }; + ++enum qm_pre_store_cap_idx { ++ QM_EQ_IRQ_TYPE_CAP_IDX = 0x0, ++ QM_AEQ_IRQ_TYPE_CAP_IDX, ++ QM_ABN_IRQ_TYPE_CAP_IDX, ++ QM_PF2VF_IRQ_TYPE_CAP_IDX, ++}; ++ + static const struct hisi_qm_cap_info qm_cap_info_comm[] = { + {QM_SUPPORT_DB_ISOLATION, 0x30, 0, BIT(0), 0x0, 0x0, 0x0}, + {QM_SUPPORT_FUNC_QOS, 0x3100, 0, BIT(8), 0x0, 0x0, 0x1}, +@@ -344,6 +353,13 @@ static const struct hisi_qm_cap_info qm_basic_info[] = { + {QM_VF_IRQ_NUM_CAP, 0x311c, 0, GENMASK(15, 0), 0x1, 0x2, 0x3}, + }; + ++static const u32 qm_pre_store_caps[] = { ++ QM_EQ_IRQ_TYPE_CAP, ++ QM_AEQ_IRQ_TYPE_CAP, ++ QM_ABN_IRQ_TYPE_CAP, ++ QM_PF2VF_IRQ_TYPE_CAP, ++}; ++ + struct qm_mailbox { + __le16 w0; + __le16 queue_num; +@@ -781,6 +797,40 @@ static void qm_get_xqc_depth(struct hisi_qm *qm, u16 *low_bits, + *high_bits = (depth >> QM_XQ_DEPTH_SHIFT) & QM_XQ_DEPTH_MASK; + } + ++int hisi_qm_set_algs(struct hisi_qm *qm, u64 alg_msk, const struct qm_dev_alg *dev_algs, ++ u32 dev_algs_size) ++{ ++ struct device *dev = &qm->pdev->dev; ++ char *algs, *ptr; ++ int i; ++ ++ if (!qm->uacce) ++ return 0; ++ ++ if (dev_algs_size >= QM_DEV_ALG_MAX_LEN) { ++ dev_err(dev, "algs size %u is equal or larger than %d.\n", ++ dev_algs_size, QM_DEV_ALG_MAX_LEN); ++ return -EINVAL; ++ } ++ ++ algs = devm_kzalloc(dev, QM_DEV_ALG_MAX_LEN * sizeof(char), GFP_KERNEL); ++ if (!algs) ++ return -ENOMEM; ++ ++ for (i = 0; i < dev_algs_size; i++) ++ if (alg_msk & dev_algs[i].alg_msk) ++ strcat(algs, dev_algs[i].alg); ++ ++ ptr = strrchr(algs, '\n'); ++ if (ptr) { ++ *ptr = '\0'; ++ qm->uacce->algs = algs; ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(hisi_qm_set_algs); ++ + static u32 qm_get_irq_num(struct hisi_qm *qm) + { + if (qm->fun_type == QM_HW_PF) +@@ -4804,7 +4854,7 @@ static void qm_unregister_abnormal_irq(struct hisi_qm *qm) + if (qm->fun_type == QM_HW_VF) + return; + +- val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_ABN_IRQ_TYPE_CAP, qm->cap_ver); ++ val = qm->cap_tables.qm_cap_table[QM_ABN_IRQ_TYPE_CAP_IDX].cap_val; + if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_ABN_IRQ_TYPE_MASK)) + return; + +@@ -4821,7 +4871,7 @@ static int qm_register_abnormal_irq(struct hisi_qm *qm) + if (qm->fun_type == QM_HW_VF) + return 0; + +- val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_ABN_IRQ_TYPE_CAP, qm->cap_ver); ++ val = qm->cap_tables.qm_cap_table[QM_ABN_IRQ_TYPE_CAP_IDX].cap_val; + if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_ABN_IRQ_TYPE_MASK)) + return 0; + +@@ -4838,7 +4888,7 @@ static void qm_unregister_mb_cmd_irq(struct hisi_qm *qm) + struct pci_dev *pdev = qm->pdev; + u32 irq_vector, val; + +- val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_PF2VF_IRQ_TYPE_CAP, qm->cap_ver); ++ val = qm->cap_tables.qm_cap_table[QM_PF2VF_IRQ_TYPE_CAP_IDX].cap_val; + if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK)) + return; + +@@ -4852,7 +4902,7 @@ static int qm_register_mb_cmd_irq(struct hisi_qm *qm) + u32 irq_vector, val; + int ret; + +- val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_PF2VF_IRQ_TYPE_CAP, qm->cap_ver); ++ val = qm->cap_tables.qm_cap_table[QM_PF2VF_IRQ_TYPE_CAP_IDX].cap_val; + if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK)) + return 0; + +@@ -4869,7 +4919,7 @@ static void qm_unregister_aeq_irq(struct hisi_qm *qm) + struct pci_dev *pdev = qm->pdev; + u32 irq_vector, val; + +- val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_AEQ_IRQ_TYPE_CAP, qm->cap_ver); ++ val = qm->cap_tables.qm_cap_table[QM_AEQ_IRQ_TYPE_CAP_IDX].cap_val; + if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK)) + return; + +@@ -4883,7 +4933,7 @@ static int qm_register_aeq_irq(struct hisi_qm *qm) + u32 irq_vector, val; + int ret; + +- val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_AEQ_IRQ_TYPE_CAP, qm->cap_ver); ++ val = qm->cap_tables.qm_cap_table[QM_AEQ_IRQ_TYPE_CAP_IDX].cap_val; + if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK)) + return 0; + +@@ -4901,7 +4951,7 @@ static void qm_unregister_eq_irq(struct hisi_qm *qm) + struct pci_dev *pdev = qm->pdev; + u32 irq_vector, val; + +- val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_EQ_IRQ_TYPE_CAP, qm->cap_ver); ++ val = qm->cap_tables.qm_cap_table[QM_EQ_IRQ_TYPE_CAP_IDX].cap_val; + if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK)) + return; + +@@ -4915,7 +4965,7 @@ static int qm_register_eq_irq(struct hisi_qm *qm) + u32 irq_vector, val; + int ret; + +- val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_EQ_IRQ_TYPE_CAP, qm->cap_ver); ++ val = qm->cap_tables.qm_cap_table[QM_EQ_IRQ_TYPE_CAP_IDX].cap_val; + if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK)) + return 0; + +@@ -5003,7 +5053,29 @@ static int qm_get_qp_num(struct hisi_qm *qm) + return 0; + } + +-static void qm_get_hw_caps(struct hisi_qm *qm) ++static int qm_pre_store_irq_type_caps(struct hisi_qm *qm) ++{ ++ struct hisi_qm_cap_record *qm_cap; ++ struct pci_dev *pdev = qm->pdev; ++ size_t i, size; ++ ++ size = ARRAY_SIZE(qm_pre_store_caps); ++ qm_cap = devm_kzalloc(&pdev->dev, sizeof(*qm_cap) * size, GFP_KERNEL); ++ if (!qm_cap) ++ return -ENOMEM; ++ ++ for (i = 0; i < size; i++) { ++ qm_cap[i].type = qm_pre_store_caps[i]; ++ qm_cap[i].cap_val = hisi_qm_get_hw_info(qm, qm_basic_info, ++ qm_pre_store_caps[i], qm->cap_ver); ++ } ++ ++ qm->cap_tables.qm_cap_table = qm_cap; ++ ++ return 0; ++} ++ ++static int qm_get_hw_caps(struct hisi_qm *qm) + { + const struct hisi_qm_cap_info *cap_info = qm->fun_type == QM_HW_PF ? + qm_cap_info_pf : qm_cap_info_vf; +@@ -5034,6 +5106,9 @@ static void qm_get_hw_caps(struct hisi_qm *qm) + if (val) + set_bit(cap_info[i].type, &qm->caps); + } ++ ++ /* Fetch and save the value of irq type related capability registers */ ++ return qm_pre_store_irq_type_caps(qm); + } + + static int qm_get_pci_res(struct hisi_qm *qm) +@@ -5055,7 +5130,10 @@ static int qm_get_pci_res(struct hisi_qm *qm) + goto err_request_mem_regions; + } + +- qm_get_hw_caps(qm); ++ ret = qm_get_hw_caps(qm); ++ if (ret) ++ goto err_ioremap; ++ + if (test_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps)) { + qm->db_interval = QM_QP_DB_INTERVAL; + qm->db_phys_base = pci_resource_start(pdev, PCI_BAR_4); +diff --git a/drivers/crypto/hisilicon/sec2/sec.h b/drivers/crypto/hisilicon/sec2/sec.h +index 3e57fc04b3770..410c83712e285 100644 +--- a/drivers/crypto/hisilicon/sec2/sec.h ++++ b/drivers/crypto/hisilicon/sec2/sec.h +@@ -220,6 +220,13 @@ enum sec_cap_type { + SEC_CORE4_ALG_BITMAP_HIGH, + }; + ++enum sec_cap_reg_record_idx { ++ SEC_DRV_ALG_BITMAP_LOW_IDX = 0x0, ++ SEC_DRV_ALG_BITMAP_HIGH_IDX, ++ SEC_DEV_ALG_BITMAP_LOW_IDX, ++ SEC_DEV_ALG_BITMAP_HIGH_IDX, ++}; ++ + void sec_destroy_qps(struct hisi_qp **qps, int qp_num); + struct hisi_qp **sec_create_qps(void); + int sec_register_to_crypto(struct hisi_qm *qm); +diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.c b/drivers/crypto/hisilicon/sec2/sec_crypto.c +index 84ae8ddd1a131..cae7c414bdaf4 100644 +--- a/drivers/crypto/hisilicon/sec2/sec_crypto.c ++++ b/drivers/crypto/hisilicon/sec2/sec_crypto.c +@@ -2546,8 +2546,12 @@ err: + + int sec_register_to_crypto(struct hisi_qm *qm) + { +- u64 alg_mask = sec_get_alg_bitmap(qm, SEC_DRV_ALG_BITMAP_HIGH, SEC_DRV_ALG_BITMAP_LOW); +- int ret; ++ u64 alg_mask; ++ int ret = 0; ++ ++ alg_mask = sec_get_alg_bitmap(qm, SEC_DRV_ALG_BITMAP_HIGH_IDX, ++ SEC_DRV_ALG_BITMAP_LOW_IDX); ++ + + ret = sec_register_skcipher(alg_mask); + if (ret) +@@ -2562,7 +2566,10 @@ int sec_register_to_crypto(struct hisi_qm *qm) + + void sec_unregister_from_crypto(struct hisi_qm *qm) + { +- u64 alg_mask = sec_get_alg_bitmap(qm, SEC_DRV_ALG_BITMAP_HIGH, SEC_DRV_ALG_BITMAP_LOW); ++ u64 alg_mask; ++ ++ alg_mask = sec_get_alg_bitmap(qm, SEC_DRV_ALG_BITMAP_HIGH_IDX, ++ SEC_DRV_ALG_BITMAP_LOW_IDX); + + sec_unregister_aead(alg_mask, ARRAY_SIZE(sec_aeads)); + sec_unregister_skcipher(alg_mask, ARRAY_SIZE(sec_skciphers)); +diff --git a/drivers/crypto/hisilicon/sec2/sec_main.c b/drivers/crypto/hisilicon/sec2/sec_main.c +index e384988bda917..4bab5000a13e5 100644 +--- a/drivers/crypto/hisilicon/sec2/sec_main.c ++++ b/drivers/crypto/hisilicon/sec2/sec_main.c +@@ -121,7 +121,6 @@ + GENMASK_ULL(42, 25)) + #define SEC_AEAD_BITMAP (GENMASK_ULL(7, 6) | GENMASK_ULL(18, 17) | \ + GENMASK_ULL(45, 43)) +-#define SEC_DEV_ALG_MAX_LEN 256 + + struct sec_hw_error { + u32 int_msk; +@@ -133,11 +132,6 @@ struct sec_dfx_item { + u32 offset; + }; + +-struct sec_dev_alg { +- u64 alg_msk; +- const char *algs; +-}; +- + static const char sec_name[] = "hisi_sec2"; + static struct dentry *sec_debugfs_root; + +@@ -174,15 +168,22 @@ static const struct hisi_qm_cap_info sec_basic_info[] = { + {SEC_CORE4_ALG_BITMAP_HIGH, 0x3170, 0, GENMASK(31, 0), 0x3FFF, 0x3FFF, 0x3FFF}, + }; + +-static const struct sec_dev_alg sec_dev_algs[] = { { ++static const u32 sec_pre_store_caps[] = { ++ SEC_DRV_ALG_BITMAP_LOW, ++ SEC_DRV_ALG_BITMAP_HIGH, ++ SEC_DEV_ALG_BITMAP_LOW, ++ SEC_DEV_ALG_BITMAP_HIGH, ++}; ++ ++static const struct qm_dev_alg sec_dev_algs[] = { { + .alg_msk = SEC_CIPHER_BITMAP, +- .algs = "cipher\n", ++ .alg = "cipher\n", + }, { + .alg_msk = SEC_DIGEST_BITMAP, +- .algs = "digest\n", ++ .alg = "digest\n", + }, { + .alg_msk = SEC_AEAD_BITMAP, +- .algs = "aead\n", ++ .alg = "aead\n", + }, + }; + +@@ -395,8 +396,8 @@ u64 sec_get_alg_bitmap(struct hisi_qm *qm, u32 high, u32 low) + { + u32 cap_val_h, cap_val_l; + +- cap_val_h = hisi_qm_get_hw_info(qm, sec_basic_info, high, qm->cap_ver); +- cap_val_l = hisi_qm_get_hw_info(qm, sec_basic_info, low, qm->cap_ver); ++ cap_val_h = qm->cap_tables.dev_cap_table[high].cap_val; ++ cap_val_l = qm->cap_tables.dev_cap_table[low].cap_val; + + return ((u64)cap_val_h << SEC_ALG_BITMAP_SHIFT) | (u64)cap_val_l; + } +@@ -1079,37 +1080,31 @@ static int sec_pf_probe_init(struct sec_dev *sec) + return ret; + } + +-static int sec_set_qm_algs(struct hisi_qm *qm) ++static int sec_pre_store_cap_reg(struct hisi_qm *qm) + { +- struct device *dev = &qm->pdev->dev; +- char *algs, *ptr; +- u64 alg_mask; +- int i; +- +- if (!qm->use_sva) +- return 0; ++ struct hisi_qm_cap_record *sec_cap; ++ struct pci_dev *pdev = qm->pdev; ++ size_t i, size; + +- algs = devm_kzalloc(dev, SEC_DEV_ALG_MAX_LEN * sizeof(char), GFP_KERNEL); +- if (!algs) ++ size = ARRAY_SIZE(sec_pre_store_caps); ++ sec_cap = devm_kzalloc(&pdev->dev, sizeof(*sec_cap) * size, GFP_KERNEL); ++ if (!sec_cap) + return -ENOMEM; + +- alg_mask = sec_get_alg_bitmap(qm, SEC_DEV_ALG_BITMAP_HIGH, SEC_DEV_ALG_BITMAP_LOW); +- +- for (i = 0; i < ARRAY_SIZE(sec_dev_algs); i++) +- if (alg_mask & sec_dev_algs[i].alg_msk) +- strcat(algs, sec_dev_algs[i].algs); +- +- ptr = strrchr(algs, '\n'); +- if (ptr) +- *ptr = '\0'; ++ for (i = 0; i < size; i++) { ++ sec_cap[i].type = sec_pre_store_caps[i]; ++ sec_cap[i].cap_val = hisi_qm_get_hw_info(qm, sec_basic_info, ++ sec_pre_store_caps[i], qm->cap_ver); ++ } + +- qm->uacce->algs = algs; ++ qm->cap_tables.dev_cap_table = sec_cap; + + return 0; + } + + static int sec_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) + { ++ u64 alg_msk; + int ret; + + qm->pdev = pdev; +@@ -1144,7 +1139,16 @@ static int sec_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) + return ret; + } + +- ret = sec_set_qm_algs(qm); ++ /* Fetch and save the value of capability registers */ ++ ret = sec_pre_store_cap_reg(qm); ++ if (ret) { ++ pci_err(qm->pdev, "Failed to pre-store capability registers!\n"); ++ hisi_qm_uninit(qm); ++ return ret; ++ } ++ ++ alg_msk = sec_get_alg_bitmap(qm, SEC_DEV_ALG_BITMAP_HIGH_IDX, SEC_DEV_ALG_BITMAP_LOW_IDX); ++ ret = hisi_qm_set_algs(qm, alg_msk, sec_dev_algs, ARRAY_SIZE(sec_dev_algs)); + if (ret) { + pci_err(qm->pdev, "Failed to set sec algs!\n"); + hisi_qm_uninit(qm); +diff --git a/drivers/crypto/hisilicon/zip/zip_main.c b/drivers/crypto/hisilicon/zip/zip_main.c +index 190b4fecfc747..9e3f5bca27dee 100644 +--- a/drivers/crypto/hisilicon/zip/zip_main.c ++++ b/drivers/crypto/hisilicon/zip/zip_main.c +@@ -74,7 +74,6 @@ + #define HZIP_AXI_SHUTDOWN_ENABLE BIT(14) + #define HZIP_WR_PORT BIT(11) + +-#define HZIP_DEV_ALG_MAX_LEN 256 + #define HZIP_ALG_ZLIB_BIT GENMASK(1, 0) + #define HZIP_ALG_GZIP_BIT GENMASK(3, 2) + #define HZIP_ALG_DEFLATE_BIT GENMASK(5, 4) +@@ -107,6 +106,14 @@ + #define HZIP_CLOCK_GATED_EN (HZIP_CORE_GATED_EN | \ + HZIP_CORE_GATED_OOO_EN) + ++/* zip comp high performance */ ++#define HZIP_HIGH_PERF_OFFSET 0x301208 ++ ++enum { ++ HZIP_HIGH_COMP_RATE, ++ HZIP_HIGH_COMP_PERF, ++}; ++ + static const char hisi_zip_name[] = "hisi_zip"; + static struct dentry *hzip_debugfs_root; + +@@ -120,23 +127,18 @@ struct zip_dfx_item { + u32 offset; + }; + +-struct zip_dev_alg { +- u32 alg_msk; +- const char *algs; +-}; +- +-static const struct zip_dev_alg zip_dev_algs[] = { { ++static const struct qm_dev_alg zip_dev_algs[] = { { + .alg_msk = HZIP_ALG_ZLIB_BIT, +- .algs = "zlib\n", ++ .alg = "zlib\n", + }, { + .alg_msk = HZIP_ALG_GZIP_BIT, +- .algs = "gzip\n", ++ .alg = "gzip\n", + }, { + .alg_msk = HZIP_ALG_DEFLATE_BIT, +- .algs = "deflate\n", ++ .alg = "deflate\n", + }, { + .alg_msk = HZIP_ALG_LZ77_BIT, +- .algs = "lz77_zstd\n", ++ .alg = "lz77_zstd\n", + }, + }; + +@@ -247,6 +249,26 @@ static struct hisi_qm_cap_info zip_basic_cap_info[] = { + {ZIP_CAP_MAX, 0x317c, 0, GENMASK(0, 0), 0x0, 0x0, 0x0} + }; + ++enum zip_pre_store_cap_idx { ++ ZIP_CORE_NUM_CAP_IDX = 0x0, ++ ZIP_CLUSTER_COMP_NUM_CAP_IDX, ++ ZIP_CLUSTER_DECOMP_NUM_CAP_IDX, ++ ZIP_DECOMP_ENABLE_BITMAP_IDX, ++ ZIP_COMP_ENABLE_BITMAP_IDX, ++ ZIP_DRV_ALG_BITMAP_IDX, ++ ZIP_DEV_ALG_BITMAP_IDX, ++}; ++ ++static const u32 zip_pre_store_caps[] = { ++ ZIP_CORE_NUM_CAP, ++ ZIP_CLUSTER_COMP_NUM_CAP, ++ ZIP_CLUSTER_DECOMP_NUM_CAP, ++ ZIP_DECOMP_ENABLE_BITMAP, ++ ZIP_COMP_ENABLE_BITMAP, ++ ZIP_DRV_ALG_BITMAP, ++ ZIP_DEV_ALG_BITMAP, ++}; ++ + enum { + HZIP_COMP_CORE0, + HZIP_COMP_CORE1, +@@ -352,6 +374,37 @@ static int hzip_diff_regs_show(struct seq_file *s, void *unused) + return 0; + } + DEFINE_SHOW_ATTRIBUTE(hzip_diff_regs); ++ ++static int perf_mode_set(const char *val, const struct kernel_param *kp) ++{ ++ int ret; ++ u32 n; ++ ++ if (!val) ++ return -EINVAL; ++ ++ ret = kstrtou32(val, 10, &n); ++ if (ret != 0 || (n != HZIP_HIGH_COMP_PERF && ++ n != HZIP_HIGH_COMP_RATE)) ++ return -EINVAL; ++ ++ return param_set_int(val, kp); ++} ++ ++static const struct kernel_param_ops zip_com_perf_ops = { ++ .set = perf_mode_set, ++ .get = param_get_int, ++}; ++ ++/* ++ * perf_mode = 0 means enable high compression rate mode, ++ * perf_mode = 1 means enable high compression performance mode. ++ * These two modes only apply to the compression direction. ++ */ ++static u32 perf_mode = HZIP_HIGH_COMP_RATE; ++module_param_cb(perf_mode, &zip_com_perf_ops, &perf_mode, 0444); ++MODULE_PARM_DESC(perf_mode, "ZIP high perf mode 0(default), 1(enable)"); ++ + static const struct kernel_param_ops zip_uacce_mode_ops = { + .set = uacce_mode_set, + .get = param_get_int, +@@ -410,40 +463,33 @@ bool hisi_zip_alg_support(struct hisi_qm *qm, u32 alg) + { + u32 cap_val; + +- cap_val = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_DRV_ALG_BITMAP, qm->cap_ver); ++ cap_val = qm->cap_tables.dev_cap_table[ZIP_DRV_ALG_BITMAP_IDX].cap_val; + if ((alg & cap_val) == alg) + return true; + + return false; + } + +-static int hisi_zip_set_qm_algs(struct hisi_qm *qm) ++static int hisi_zip_set_high_perf(struct hisi_qm *qm) + { +- struct device *dev = &qm->pdev->dev; +- char *algs, *ptr; +- u32 alg_mask; +- int i; +- +- if (!qm->use_sva) +- return 0; +- +- algs = devm_kzalloc(dev, HZIP_DEV_ALG_MAX_LEN * sizeof(char), GFP_KERNEL); +- if (!algs) +- return -ENOMEM; +- +- alg_mask = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_DEV_ALG_BITMAP, qm->cap_ver); +- +- for (i = 0; i < ARRAY_SIZE(zip_dev_algs); i++) +- if (alg_mask & zip_dev_algs[i].alg_msk) +- strcat(algs, zip_dev_algs[i].algs); +- +- ptr = strrchr(algs, '\n'); +- if (ptr) +- *ptr = '\0'; ++ u32 val; ++ int ret; + +- qm->uacce->algs = algs; ++ val = readl_relaxed(qm->io_base + HZIP_HIGH_PERF_OFFSET); ++ if (perf_mode == HZIP_HIGH_COMP_PERF) ++ val |= HZIP_HIGH_COMP_PERF; ++ else ++ val &= ~HZIP_HIGH_COMP_PERF; ++ ++ /* Set perf mode */ ++ writel(val, qm->io_base + HZIP_HIGH_PERF_OFFSET); ++ ret = readl_relaxed_poll_timeout(qm->io_base + HZIP_HIGH_PERF_OFFSET, ++ val, val == perf_mode, HZIP_DELAY_1_US, ++ HZIP_POLL_TIMEOUT_US); ++ if (ret) ++ pci_err(qm->pdev, "failed to set perf mode\n"); + +- return 0; ++ return ret; + } + + static void hisi_zip_open_sva_prefetch(struct hisi_qm *qm) +@@ -542,10 +588,8 @@ static int hisi_zip_set_user_domain_and_cache(struct hisi_qm *qm) + } + + /* let's open all compression/decompression cores */ +- dcomp_bm = hisi_qm_get_hw_info(qm, zip_basic_cap_info, +- ZIP_DECOMP_ENABLE_BITMAP, qm->cap_ver); +- comp_bm = hisi_qm_get_hw_info(qm, zip_basic_cap_info, +- ZIP_COMP_ENABLE_BITMAP, qm->cap_ver); ++ dcomp_bm = qm->cap_tables.dev_cap_table[ZIP_DECOMP_ENABLE_BITMAP_IDX].cap_val; ++ comp_bm = qm->cap_tables.dev_cap_table[ZIP_COMP_ENABLE_BITMAP_IDX].cap_val; + writel(HZIP_DECOMP_CHECK_ENABLE | dcomp_bm | comp_bm, base + HZIP_CLOCK_GATE_CTRL); + + /* enable sqc,cqc writeback */ +@@ -772,9 +816,8 @@ static int hisi_zip_core_debug_init(struct hisi_qm *qm) + char buf[HZIP_BUF_SIZE]; + int i; + +- zip_core_num = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_CORE_NUM_CAP, qm->cap_ver); +- zip_comp_core_num = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_CLUSTER_COMP_NUM_CAP, +- qm->cap_ver); ++ zip_core_num = qm->cap_tables.dev_cap_table[ZIP_CORE_NUM_CAP_IDX].cap_val; ++ zip_comp_core_num = qm->cap_tables.dev_cap_table[ZIP_CLUSTER_COMP_NUM_CAP_IDX].cap_val; + + for (i = 0; i < zip_core_num; i++) { + if (i < zip_comp_core_num) +@@ -916,7 +959,7 @@ static int hisi_zip_show_last_regs_init(struct hisi_qm *qm) + u32 zip_core_num; + int i, j, idx; + +- zip_core_num = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_CORE_NUM_CAP, qm->cap_ver); ++ zip_core_num = qm->cap_tables.dev_cap_table[ZIP_CORE_NUM_CAP_IDX].cap_val; + + debug->last_words = kcalloc(core_dfx_regs_num * zip_core_num + com_dfx_regs_num, + sizeof(unsigned int), GFP_KERNEL); +@@ -972,9 +1015,9 @@ static void hisi_zip_show_last_dfx_regs(struct hisi_qm *qm) + hzip_com_dfx_regs[i].name, debug->last_words[i], val); + } + +- zip_core_num = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_CORE_NUM_CAP, qm->cap_ver); +- zip_comp_core_num = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_CLUSTER_COMP_NUM_CAP, +- qm->cap_ver); ++ zip_core_num = qm->cap_tables.dev_cap_table[ZIP_CORE_NUM_CAP_IDX].cap_val; ++ zip_comp_core_num = qm->cap_tables.dev_cap_table[ZIP_CLUSTER_COMP_NUM_CAP_IDX].cap_val; ++ + for (i = 0; i < zip_core_num; i++) { + if (i < zip_comp_core_num) + scnprintf(buf, sizeof(buf), "Comp_core-%d", i); +@@ -1115,6 +1158,10 @@ static int hisi_zip_pf_probe_init(struct hisi_zip *hisi_zip) + if (ret) + return ret; + ++ ret = hisi_zip_set_high_perf(qm); ++ if (ret) ++ return ret; ++ + hisi_zip_open_sva_prefetch(qm); + hisi_qm_dev_err_init(qm); + hisi_zip_debug_regs_clear(qm); +@@ -1126,8 +1173,31 @@ static int hisi_zip_pf_probe_init(struct hisi_zip *hisi_zip) + return ret; + } + ++static int zip_pre_store_cap_reg(struct hisi_qm *qm) ++{ ++ struct hisi_qm_cap_record *zip_cap; ++ struct pci_dev *pdev = qm->pdev; ++ size_t i, size; ++ ++ size = ARRAY_SIZE(zip_pre_store_caps); ++ zip_cap = devm_kzalloc(&pdev->dev, sizeof(*zip_cap) * size, GFP_KERNEL); ++ if (!zip_cap) ++ return -ENOMEM; ++ ++ for (i = 0; i < size; i++) { ++ zip_cap[i].type = zip_pre_store_caps[i]; ++ zip_cap[i].cap_val = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ++ zip_pre_store_caps[i], qm->cap_ver); ++ } ++ ++ qm->cap_tables.dev_cap_table = zip_cap; ++ ++ return 0; ++} ++ + static int hisi_zip_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) + { ++ u64 alg_msk; + int ret; + + qm->pdev = pdev; +@@ -1163,7 +1233,16 @@ static int hisi_zip_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) + return ret; + } + +- ret = hisi_zip_set_qm_algs(qm); ++ /* Fetch and save the value of capability registers */ ++ ret = zip_pre_store_cap_reg(qm); ++ if (ret) { ++ pci_err(qm->pdev, "Failed to pre-store capability registers!\n"); ++ hisi_qm_uninit(qm); ++ return ret; ++ } ++ ++ alg_msk = qm->cap_tables.dev_cap_table[ZIP_DEV_ALG_BITMAP_IDX].cap_val; ++ ret = hisi_qm_set_algs(qm, alg_msk, zip_dev_algs, ARRAY_SIZE(zip_dev_algs)); + if (ret) { + pci_err(qm->pdev, "Failed to set zip algs!\n"); + hisi_qm_uninit(qm); +diff --git a/drivers/crypto/inside-secure/safexcel_cipher.c b/drivers/crypto/inside-secure/safexcel_cipher.c +index 32a37e3850c58..f59e32115268b 100644 +--- a/drivers/crypto/inside-secure/safexcel_cipher.c ++++ b/drivers/crypto/inside-secure/safexcel_cipher.c +@@ -742,9 +742,9 @@ static int safexcel_send_req(struct crypto_async_request *base, int ring, + max(totlen_src, totlen_dst)); + return -EINVAL; + } +- if (sreq->nr_src > 0) +- dma_map_sg(priv->dev, src, sreq->nr_src, +- DMA_BIDIRECTIONAL); ++ if (sreq->nr_src > 0 && ++ !dma_map_sg(priv->dev, src, sreq->nr_src, DMA_BIDIRECTIONAL)) ++ return -EIO; + } else { + if (unlikely(totlen_src && (sreq->nr_src <= 0))) { + dev_err(priv->dev, "Source buffer not large enough (need %d bytes)!", +@@ -752,8 +752,9 @@ static int safexcel_send_req(struct crypto_async_request *base, int ring, + return -EINVAL; + } + +- if (sreq->nr_src > 0) +- dma_map_sg(priv->dev, src, sreq->nr_src, DMA_TO_DEVICE); ++ if (sreq->nr_src > 0 && ++ !dma_map_sg(priv->dev, src, sreq->nr_src, DMA_TO_DEVICE)) ++ return -EIO; + + if (unlikely(totlen_dst && (sreq->nr_dst <= 0))) { + dev_err(priv->dev, "Dest buffer not large enough (need %d bytes)!", +@@ -762,9 +763,11 @@ static int safexcel_send_req(struct crypto_async_request *base, int ring, + goto unmap; + } + +- if (sreq->nr_dst > 0) +- dma_map_sg(priv->dev, dst, sreq->nr_dst, +- DMA_FROM_DEVICE); ++ if (sreq->nr_dst > 0 && ++ !dma_map_sg(priv->dev, dst, sreq->nr_dst, DMA_FROM_DEVICE)) { ++ ret = -EIO; ++ goto unmap; ++ } + } + + memcpy(ctx->base.ctxr->data, ctx->key, ctx->key_len); +diff --git a/drivers/crypto/sa2ul.c b/drivers/crypto/sa2ul.c +index f4bc06c24ad8f..e7efebf8127f0 100644 +--- a/drivers/crypto/sa2ul.c ++++ b/drivers/crypto/sa2ul.c +@@ -1868,9 +1868,8 @@ static int sa_aead_setkey(struct crypto_aead *authenc, + crypto_aead_set_flags(ctx->fallback.aead, + crypto_aead_get_flags(authenc) & + CRYPTO_TFM_REQ_MASK); +- crypto_aead_setkey(ctx->fallback.aead, key, keylen); + +- return 0; ++ return crypto_aead_setkey(ctx->fallback.aead, key, keylen); + } + + static int sa_aead_setauthsize(struct crypto_aead *tfm, unsigned int authsize) +diff --git a/drivers/crypto/sahara.c b/drivers/crypto/sahara.c +index 7ab20fb95166e..3b946f1313ed7 100644 +--- a/drivers/crypto/sahara.c ++++ b/drivers/crypto/sahara.c +@@ -44,7 +44,6 @@ + #define FLAGS_MODE_MASK 0x000f + #define FLAGS_ENCRYPT BIT(0) + #define FLAGS_CBC BIT(1) +-#define FLAGS_NEW_KEY BIT(3) + + #define SAHARA_HDR_BASE 0x00800000 + #define SAHARA_HDR_SKHA_ALG_AES 0 +@@ -142,8 +141,6 @@ struct sahara_hw_link { + }; + + struct sahara_ctx { +- unsigned long flags; +- + /* AES-specific context */ + int keylen; + u8 key[AES_KEYSIZE_128]; +@@ -152,6 +149,7 @@ struct sahara_ctx { + + struct sahara_aes_reqctx { + unsigned long mode; ++ u8 iv_out[AES_BLOCK_SIZE]; + struct skcipher_request fallback_req; // keep at the end + }; + +@@ -447,27 +445,24 @@ static int sahara_hw_descriptor_create(struct sahara_dev *dev) + int ret; + int i, j; + int idx = 0; ++ u32 len; + +- /* Copy new key if necessary */ +- if (ctx->flags & FLAGS_NEW_KEY) { +- memcpy(dev->key_base, ctx->key, ctx->keylen); +- ctx->flags &= ~FLAGS_NEW_KEY; ++ memcpy(dev->key_base, ctx->key, ctx->keylen); + +- if (dev->flags & FLAGS_CBC) { +- dev->hw_desc[idx]->len1 = AES_BLOCK_SIZE; +- dev->hw_desc[idx]->p1 = dev->iv_phys_base; +- } else { +- dev->hw_desc[idx]->len1 = 0; +- dev->hw_desc[idx]->p1 = 0; +- } +- dev->hw_desc[idx]->len2 = ctx->keylen; +- dev->hw_desc[idx]->p2 = dev->key_phys_base; +- dev->hw_desc[idx]->next = dev->hw_phys_desc[1]; ++ if (dev->flags & FLAGS_CBC) { ++ dev->hw_desc[idx]->len1 = AES_BLOCK_SIZE; ++ dev->hw_desc[idx]->p1 = dev->iv_phys_base; ++ } else { ++ dev->hw_desc[idx]->len1 = 0; ++ dev->hw_desc[idx]->p1 = 0; ++ } ++ dev->hw_desc[idx]->len2 = ctx->keylen; ++ dev->hw_desc[idx]->p2 = dev->key_phys_base; ++ dev->hw_desc[idx]->next = dev->hw_phys_desc[1]; ++ dev->hw_desc[idx]->hdr = sahara_aes_key_hdr(dev); + +- dev->hw_desc[idx]->hdr = sahara_aes_key_hdr(dev); ++ idx++; + +- idx++; +- } + + dev->nb_in_sg = sg_nents_for_len(dev->in_sg, dev->total); + if (dev->nb_in_sg < 0) { +@@ -489,24 +484,27 @@ static int sahara_hw_descriptor_create(struct sahara_dev *dev) + DMA_TO_DEVICE); + if (!ret) { + dev_err(dev->device, "couldn't map in sg\n"); +- goto unmap_in; ++ return -EINVAL; + } ++ + ret = dma_map_sg(dev->device, dev->out_sg, dev->nb_out_sg, + DMA_FROM_DEVICE); + if (!ret) { + dev_err(dev->device, "couldn't map out sg\n"); +- goto unmap_out; ++ goto unmap_in; + } + + /* Create input links */ + dev->hw_desc[idx]->p1 = dev->hw_phys_link[0]; + sg = dev->in_sg; ++ len = dev->total; + for (i = 0; i < dev->nb_in_sg; i++) { +- dev->hw_link[i]->len = sg->length; ++ dev->hw_link[i]->len = min(len, sg->length); + dev->hw_link[i]->p = sg->dma_address; + if (i == (dev->nb_in_sg - 1)) { + dev->hw_link[i]->next = 0; + } else { ++ len -= min(len, sg->length); + dev->hw_link[i]->next = dev->hw_phys_link[i + 1]; + sg = sg_next(sg); + } +@@ -515,12 +513,14 @@ static int sahara_hw_descriptor_create(struct sahara_dev *dev) + /* Create output links */ + dev->hw_desc[idx]->p2 = dev->hw_phys_link[i]; + sg = dev->out_sg; ++ len = dev->total; + for (j = i; j < dev->nb_out_sg + i; j++) { +- dev->hw_link[j]->len = sg->length; ++ dev->hw_link[j]->len = min(len, sg->length); + dev->hw_link[j]->p = sg->dma_address; + if (j == (dev->nb_out_sg + i - 1)) { + dev->hw_link[j]->next = 0; + } else { ++ len -= min(len, sg->length); + dev->hw_link[j]->next = dev->hw_phys_link[j + 1]; + sg = sg_next(sg); + } +@@ -539,9 +539,6 @@ static int sahara_hw_descriptor_create(struct sahara_dev *dev) + + return 0; + +-unmap_out: +- dma_unmap_sg(dev->device, dev->out_sg, dev->nb_out_sg, +- DMA_FROM_DEVICE); + unmap_in: + dma_unmap_sg(dev->device, dev->in_sg, dev->nb_in_sg, + DMA_TO_DEVICE); +@@ -549,8 +546,24 @@ unmap_in: + return -EINVAL; + } + ++static void sahara_aes_cbc_update_iv(struct skcipher_request *req) ++{ ++ struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req); ++ struct sahara_aes_reqctx *rctx = skcipher_request_ctx(req); ++ unsigned int ivsize = crypto_skcipher_ivsize(skcipher); ++ ++ /* Update IV buffer to contain the last ciphertext block */ ++ if (rctx->mode & FLAGS_ENCRYPT) { ++ sg_pcopy_to_buffer(req->dst, sg_nents(req->dst), req->iv, ++ ivsize, req->cryptlen - ivsize); ++ } else { ++ memcpy(req->iv, rctx->iv_out, ivsize); ++ } ++} ++ + static int sahara_aes_process(struct skcipher_request *req) + { ++ struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req); + struct sahara_dev *dev = dev_ptr; + struct sahara_ctx *ctx; + struct sahara_aes_reqctx *rctx; +@@ -572,8 +585,17 @@ static int sahara_aes_process(struct skcipher_request *req) + rctx->mode &= FLAGS_MODE_MASK; + dev->flags = (dev->flags & ~FLAGS_MODE_MASK) | rctx->mode; + +- if ((dev->flags & FLAGS_CBC) && req->iv) +- memcpy(dev->iv_base, req->iv, AES_KEYSIZE_128); ++ if ((dev->flags & FLAGS_CBC) && req->iv) { ++ unsigned int ivsize = crypto_skcipher_ivsize(skcipher); ++ ++ memcpy(dev->iv_base, req->iv, ivsize); ++ ++ if (!(dev->flags & FLAGS_ENCRYPT)) { ++ sg_pcopy_to_buffer(req->src, sg_nents(req->src), ++ rctx->iv_out, ivsize, ++ req->cryptlen - ivsize); ++ } ++ } + + /* assign new context to device */ + dev->ctx = ctx; +@@ -586,16 +608,20 @@ static int sahara_aes_process(struct skcipher_request *req) + + timeout = wait_for_completion_timeout(&dev->dma_completion, + msecs_to_jiffies(SAHARA_TIMEOUT_MS)); +- if (!timeout) { +- dev_err(dev->device, "AES timeout\n"); +- return -ETIMEDOUT; +- } + + dma_unmap_sg(dev->device, dev->out_sg, dev->nb_out_sg, + DMA_FROM_DEVICE); + dma_unmap_sg(dev->device, dev->in_sg, dev->nb_in_sg, + DMA_TO_DEVICE); + ++ if (!timeout) { ++ dev_err(dev->device, "AES timeout\n"); ++ return -ETIMEDOUT; ++ } ++ ++ if ((dev->flags & FLAGS_CBC) && req->iv) ++ sahara_aes_cbc_update_iv(req); ++ + return 0; + } + +@@ -609,7 +635,6 @@ static int sahara_aes_setkey(struct crypto_skcipher *tfm, const u8 *key, + /* SAHARA only supports 128bit keys */ + if (keylen == AES_KEYSIZE_128) { + memcpy(ctx->key, key, keylen); +- ctx->flags |= FLAGS_NEW_KEY; + return 0; + } + +@@ -625,12 +650,40 @@ static int sahara_aes_setkey(struct crypto_skcipher *tfm, const u8 *key, + return crypto_skcipher_setkey(ctx->fallback, key, keylen); + } + ++static int sahara_aes_fallback(struct skcipher_request *req, unsigned long mode) ++{ ++ struct sahara_aes_reqctx *rctx = skcipher_request_ctx(req); ++ struct sahara_ctx *ctx = crypto_skcipher_ctx( ++ crypto_skcipher_reqtfm(req)); ++ ++ skcipher_request_set_tfm(&rctx->fallback_req, ctx->fallback); ++ skcipher_request_set_callback(&rctx->fallback_req, ++ req->base.flags, ++ req->base.complete, ++ req->base.data); ++ skcipher_request_set_crypt(&rctx->fallback_req, req->src, ++ req->dst, req->cryptlen, req->iv); ++ ++ if (mode & FLAGS_ENCRYPT) ++ return crypto_skcipher_encrypt(&rctx->fallback_req); ++ ++ return crypto_skcipher_decrypt(&rctx->fallback_req); ++} ++ + static int sahara_aes_crypt(struct skcipher_request *req, unsigned long mode) + { + struct sahara_aes_reqctx *rctx = skcipher_request_ctx(req); ++ struct sahara_ctx *ctx = crypto_skcipher_ctx( ++ crypto_skcipher_reqtfm(req)); + struct sahara_dev *dev = dev_ptr; + int err = 0; + ++ if (!req->cryptlen) ++ return 0; ++ ++ if (unlikely(ctx->keylen != AES_KEYSIZE_128)) ++ return sahara_aes_fallback(req, mode); ++ + dev_dbg(dev->device, "nbytes: %d, enc: %d, cbc: %d\n", + req->cryptlen, !!(mode & FLAGS_ENCRYPT), !!(mode & FLAGS_CBC)); + +@@ -653,81 +706,21 @@ static int sahara_aes_crypt(struct skcipher_request *req, unsigned long mode) + + static int sahara_aes_ecb_encrypt(struct skcipher_request *req) + { +- struct sahara_aes_reqctx *rctx = skcipher_request_ctx(req); +- struct sahara_ctx *ctx = crypto_skcipher_ctx( +- crypto_skcipher_reqtfm(req)); +- +- if (unlikely(ctx->keylen != AES_KEYSIZE_128)) { +- skcipher_request_set_tfm(&rctx->fallback_req, ctx->fallback); +- skcipher_request_set_callback(&rctx->fallback_req, +- req->base.flags, +- req->base.complete, +- req->base.data); +- skcipher_request_set_crypt(&rctx->fallback_req, req->src, +- req->dst, req->cryptlen, req->iv); +- return crypto_skcipher_encrypt(&rctx->fallback_req); +- } +- + return sahara_aes_crypt(req, FLAGS_ENCRYPT); + } + + static int sahara_aes_ecb_decrypt(struct skcipher_request *req) + { +- struct sahara_aes_reqctx *rctx = skcipher_request_ctx(req); +- struct sahara_ctx *ctx = crypto_skcipher_ctx( +- crypto_skcipher_reqtfm(req)); +- +- if (unlikely(ctx->keylen != AES_KEYSIZE_128)) { +- skcipher_request_set_tfm(&rctx->fallback_req, ctx->fallback); +- skcipher_request_set_callback(&rctx->fallback_req, +- req->base.flags, +- req->base.complete, +- req->base.data); +- skcipher_request_set_crypt(&rctx->fallback_req, req->src, +- req->dst, req->cryptlen, req->iv); +- return crypto_skcipher_decrypt(&rctx->fallback_req); +- } +- + return sahara_aes_crypt(req, 0); + } + + static int sahara_aes_cbc_encrypt(struct skcipher_request *req) + { +- struct sahara_aes_reqctx *rctx = skcipher_request_ctx(req); +- struct sahara_ctx *ctx = crypto_skcipher_ctx( +- crypto_skcipher_reqtfm(req)); +- +- if (unlikely(ctx->keylen != AES_KEYSIZE_128)) { +- skcipher_request_set_tfm(&rctx->fallback_req, ctx->fallback); +- skcipher_request_set_callback(&rctx->fallback_req, +- req->base.flags, +- req->base.complete, +- req->base.data); +- skcipher_request_set_crypt(&rctx->fallback_req, req->src, +- req->dst, req->cryptlen, req->iv); +- return crypto_skcipher_encrypt(&rctx->fallback_req); +- } +- + return sahara_aes_crypt(req, FLAGS_ENCRYPT | FLAGS_CBC); + } + + static int sahara_aes_cbc_decrypt(struct skcipher_request *req) + { +- struct sahara_aes_reqctx *rctx = skcipher_request_ctx(req); +- struct sahara_ctx *ctx = crypto_skcipher_ctx( +- crypto_skcipher_reqtfm(req)); +- +- if (unlikely(ctx->keylen != AES_KEYSIZE_128)) { +- skcipher_request_set_tfm(&rctx->fallback_req, ctx->fallback); +- skcipher_request_set_callback(&rctx->fallback_req, +- req->base.flags, +- req->base.complete, +- req->base.data); +- skcipher_request_set_crypt(&rctx->fallback_req, req->src, +- req->dst, req->cryptlen, req->iv); +- return crypto_skcipher_decrypt(&rctx->fallback_req); +- } +- + return sahara_aes_crypt(req, FLAGS_CBC); + } + +@@ -784,6 +777,7 @@ static int sahara_sha_hw_links_create(struct sahara_dev *dev, + int start) + { + struct scatterlist *sg; ++ unsigned int len; + unsigned int i; + int ret; + +@@ -805,12 +799,14 @@ static int sahara_sha_hw_links_create(struct sahara_dev *dev, + if (!ret) + return -EFAULT; + ++ len = rctx->total; + for (i = start; i < dev->nb_in_sg + start; i++) { +- dev->hw_link[i]->len = sg->length; ++ dev->hw_link[i]->len = min(len, sg->length); + dev->hw_link[i]->p = sg->dma_address; + if (i == (dev->nb_in_sg + start - 1)) { + dev->hw_link[i]->next = 0; + } else { ++ len -= min(len, sg->length); + dev->hw_link[i]->next = dev->hw_phys_link[i + 1]; + sg = sg_next(sg); + } +@@ -891,24 +887,6 @@ static int sahara_sha_hw_context_descriptor_create(struct sahara_dev *dev, + return 0; + } + +-static int sahara_walk_and_recalc(struct scatterlist *sg, unsigned int nbytes) +-{ +- if (!sg || !sg->length) +- return nbytes; +- +- while (nbytes && sg) { +- if (nbytes <= sg->length) { +- sg->length = nbytes; +- sg_mark_end(sg); +- break; +- } +- nbytes -= sg->length; +- sg = sg_next(sg); +- } +- +- return nbytes; +-} +- + static int sahara_sha_prepare_request(struct ahash_request *req) + { + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); +@@ -945,36 +923,20 @@ static int sahara_sha_prepare_request(struct ahash_request *req) + hash_later, 0); + } + +- /* nbytes should now be multiple of blocksize */ +- req->nbytes = req->nbytes - hash_later; +- +- sahara_walk_and_recalc(req->src, req->nbytes); +- ++ rctx->total = len - hash_later; + /* have data from previous operation and current */ + if (rctx->buf_cnt && req->nbytes) { + sg_init_table(rctx->in_sg_chain, 2); + sg_set_buf(rctx->in_sg_chain, rctx->rembuf, rctx->buf_cnt); +- + sg_chain(rctx->in_sg_chain, 2, req->src); +- +- rctx->total = req->nbytes + rctx->buf_cnt; + rctx->in_sg = rctx->in_sg_chain; +- +- req->src = rctx->in_sg_chain; + /* only data from previous operation */ + } else if (rctx->buf_cnt) { +- if (req->src) +- rctx->in_sg = req->src; +- else +- rctx->in_sg = rctx->in_sg_chain; +- /* buf was copied into rembuf above */ ++ rctx->in_sg = rctx->in_sg_chain; + sg_init_one(rctx->in_sg, rctx->rembuf, rctx->buf_cnt); +- rctx->total = rctx->buf_cnt; + /* no data from previous operation */ + } else { + rctx->in_sg = req->src; +- rctx->total = req->nbytes; +- req->src = rctx->in_sg; + } + + /* on next call, we only have the remaining data in the buffer */ +@@ -995,7 +957,10 @@ static int sahara_sha_process(struct ahash_request *req) + return ret; + + if (rctx->first) { +- sahara_sha_hw_data_descriptor_create(dev, rctx, req, 0); ++ ret = sahara_sha_hw_data_descriptor_create(dev, rctx, req, 0); ++ if (ret) ++ return ret; ++ + dev->hw_desc[0]->next = 0; + rctx->first = 0; + } else { +@@ -1003,7 +968,10 @@ static int sahara_sha_process(struct ahash_request *req) + + sahara_sha_hw_context_descriptor_create(dev, rctx, req, 0); + dev->hw_desc[0]->next = dev->hw_phys_desc[1]; +- sahara_sha_hw_data_descriptor_create(dev, rctx, req, 1); ++ ret = sahara_sha_hw_data_descriptor_create(dev, rctx, req, 1); ++ if (ret) ++ return ret; ++ + dev->hw_desc[1]->next = 0; + } + +@@ -1016,18 +984,19 @@ static int sahara_sha_process(struct ahash_request *req) + + timeout = wait_for_completion_timeout(&dev->dma_completion, + msecs_to_jiffies(SAHARA_TIMEOUT_MS)); +- if (!timeout) { +- dev_err(dev->device, "SHA timeout\n"); +- return -ETIMEDOUT; +- } + + if (rctx->sg_in_idx) + dma_unmap_sg(dev->device, dev->in_sg, dev->nb_in_sg, + DMA_TO_DEVICE); + ++ if (!timeout) { ++ dev_err(dev->device, "SHA timeout\n"); ++ return -ETIMEDOUT; ++ } ++ + memcpy(rctx->context, dev->context_base, rctx->context_size); + +- if (req->result) ++ if (req->result && rctx->last) + memcpy(req->result, rctx->context, rctx->digest_size); + + return 0; +@@ -1171,8 +1140,7 @@ static int sahara_sha_import(struct ahash_request *req, const void *in) + static int sahara_sha_cra_init(struct crypto_tfm *tfm) + { + crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm), +- sizeof(struct sahara_sha_reqctx) + +- SHA_BUFFER_LEN + SHA256_BLOCK_SIZE); ++ sizeof(struct sahara_sha_reqctx)); + + return 0; + } +diff --git a/drivers/crypto/virtio/virtio_crypto_common.h b/drivers/crypto/virtio/virtio_crypto_common.h +index 154590e1f7643..7059bbe5a2eba 100644 +--- a/drivers/crypto/virtio/virtio_crypto_common.h ++++ b/drivers/crypto/virtio/virtio_crypto_common.h +@@ -10,6 +10,7 @@ + #include <linux/virtio.h> + #include <linux/crypto.h> + #include <linux/spinlock.h> ++#include <linux/interrupt.h> + #include <crypto/aead.h> + #include <crypto/aes.h> + #include <crypto/engine.h> +@@ -28,6 +29,7 @@ struct data_queue { + char name[32]; + + struct crypto_engine *engine; ++ struct tasklet_struct done_task; + }; + + struct virtio_crypto { +diff --git a/drivers/crypto/virtio/virtio_crypto_core.c b/drivers/crypto/virtio/virtio_crypto_core.c +index 3842915ea7437..56dc0935c774a 100644 +--- a/drivers/crypto/virtio/virtio_crypto_core.c ++++ b/drivers/crypto/virtio/virtio_crypto_core.c +@@ -72,27 +72,28 @@ int virtio_crypto_ctrl_vq_request(struct virtio_crypto *vcrypto, struct scatterl + return 0; + } + +-static void virtcrypto_dataq_callback(struct virtqueue *vq) ++static void virtcrypto_done_task(unsigned long data) + { +- struct virtio_crypto *vcrypto = vq->vdev->priv; ++ struct data_queue *data_vq = (struct data_queue *)data; ++ struct virtqueue *vq = data_vq->vq; + struct virtio_crypto_request *vc_req; +- unsigned long flags; + unsigned int len; +- unsigned int qid = vq->index; + +- spin_lock_irqsave(&vcrypto->data_vq[qid].lock, flags); + do { + virtqueue_disable_cb(vq); + while ((vc_req = virtqueue_get_buf(vq, &len)) != NULL) { +- spin_unlock_irqrestore( +- &vcrypto->data_vq[qid].lock, flags); + if (vc_req->alg_cb) + vc_req->alg_cb(vc_req, len); +- spin_lock_irqsave( +- &vcrypto->data_vq[qid].lock, flags); + } + } while (!virtqueue_enable_cb(vq)); +- spin_unlock_irqrestore(&vcrypto->data_vq[qid].lock, flags); ++} ++ ++static void virtcrypto_dataq_callback(struct virtqueue *vq) ++{ ++ struct virtio_crypto *vcrypto = vq->vdev->priv; ++ struct data_queue *dq = &vcrypto->data_vq[vq->index]; ++ ++ tasklet_schedule(&dq->done_task); + } + + static int virtcrypto_find_vqs(struct virtio_crypto *vi) +@@ -150,6 +151,8 @@ static int virtcrypto_find_vqs(struct virtio_crypto *vi) + ret = -ENOMEM; + goto err_engine; + } ++ tasklet_init(&vi->data_vq[i].done_task, virtcrypto_done_task, ++ (unsigned long)&vi->data_vq[i]); + } + + kfree(names); +@@ -496,12 +499,15 @@ static void virtcrypto_free_unused_reqs(struct virtio_crypto *vcrypto) + static void virtcrypto_remove(struct virtio_device *vdev) + { + struct virtio_crypto *vcrypto = vdev->priv; ++ int i; + + dev_info(&vdev->dev, "Start virtcrypto_remove.\n"); + + flush_work(&vcrypto->config_work); + if (virtcrypto_dev_started(vcrypto)) + virtcrypto_dev_stop(vcrypto); ++ for (i = 0; i < vcrypto->max_data_queues; i++) ++ tasklet_kill(&vcrypto->data_vq[i].done_task); + virtio_reset_device(vdev); + virtcrypto_free_unused_reqs(vcrypto); + virtcrypto_clear_crypto_engines(vcrypto); +diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c +index bd41424319807..1f1483a9e5252 100644 +--- a/drivers/cxl/core/port.c ++++ b/drivers/cxl/core/port.c +@@ -1403,7 +1403,7 @@ static int decoder_populate_targets(struct cxl_switch_decoder *cxlsd, + return -EINVAL; + + write_seqlock(&cxlsd->target_lock); +- for (i = 0; i < cxlsd->nr_targets; i++) { ++ for (i = 0; i < cxlsd->cxld.interleave_ways; i++) { + struct cxl_dport *dport = find_dport(port, target_map[i]); + + if (!dport) { +diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c +index ebc1b028555ca..2f7187dbfa2d9 100644 +--- a/drivers/cxl/core/region.c ++++ b/drivers/cxl/core/region.c +@@ -331,7 +331,7 @@ static ssize_t interleave_ways_store(struct device *dev, + return rc; + + /* +- * Even for x3, x9, and x12 interleaves the region interleave must be a ++ * Even for x3, x6, and x12 interleaves the region interleave must be a + * power of 2 multiple of the host bridge interleave. + */ + if (!is_power_of_2(val / cxld->interleave_ways) || +diff --git a/drivers/edac/thunderx_edac.c b/drivers/edac/thunderx_edac.c +index f13674081cb6b..4dca21b39bf73 100644 +--- a/drivers/edac/thunderx_edac.c ++++ b/drivers/edac/thunderx_edac.c +@@ -1133,7 +1133,7 @@ static irqreturn_t thunderx_ocx_com_threaded_isr(int irq, void *irq_id) + decode_register(other, OCX_OTHER_SIZE, + ocx_com_errors, ctx->reg_com_int); + +- strncat(msg, other, OCX_MESSAGE_SIZE); ++ strlcat(msg, other, OCX_MESSAGE_SIZE); + + for (lane = 0; lane < OCX_RX_LANES; lane++) + if (ctx->reg_com_int & BIT(lane)) { +@@ -1142,12 +1142,12 @@ static irqreturn_t thunderx_ocx_com_threaded_isr(int irq, void *irq_id) + lane, ctx->reg_lane_int[lane], + lane, ctx->reg_lane_stat11[lane]); + +- strncat(msg, other, OCX_MESSAGE_SIZE); ++ strlcat(msg, other, OCX_MESSAGE_SIZE); + + decode_register(other, OCX_OTHER_SIZE, + ocx_lane_errors, + ctx->reg_lane_int[lane]); +- strncat(msg, other, OCX_MESSAGE_SIZE); ++ strlcat(msg, other, OCX_MESSAGE_SIZE); + } + + if (ctx->reg_com_int & OCX_COM_INT_CE) +@@ -1217,7 +1217,7 @@ static irqreturn_t thunderx_ocx_lnk_threaded_isr(int irq, void *irq_id) + decode_register(other, OCX_OTHER_SIZE, + ocx_com_link_errors, ctx->reg_com_link_int); + +- strncat(msg, other, OCX_MESSAGE_SIZE); ++ strlcat(msg, other, OCX_MESSAGE_SIZE); + + if (ctx->reg_com_link_int & OCX_COM_LINK_INT_UE) + edac_device_handle_ue(ocx->edac_dev, 0, 0, msg); +@@ -1896,7 +1896,7 @@ static irqreturn_t thunderx_l2c_threaded_isr(int irq, void *irq_id) + + decode_register(other, L2C_OTHER_SIZE, l2_errors, ctx->reg_int); + +- strncat(msg, other, L2C_MESSAGE_SIZE); ++ strlcat(msg, other, L2C_MESSAGE_SIZE); + + if (ctx->reg_int & mask_ue) + edac_device_handle_ue(l2c->edac_dev, 0, 0, msg); +diff --git a/drivers/firmware/meson/meson_sm.c b/drivers/firmware/meson/meson_sm.c +index d081a6312627b..bf19dd66c2137 100644 +--- a/drivers/firmware/meson/meson_sm.c ++++ b/drivers/firmware/meson/meson_sm.c +@@ -313,11 +313,14 @@ static int __init meson_sm_probe(struct platform_device *pdev) + + platform_set_drvdata(pdev, fw); + +- pr_info("secure-monitor enabled\n"); ++ if (devm_of_platform_populate(dev)) ++ goto out_in_base; + + if (sysfs_create_group(&pdev->dev.kobj, &meson_sm_sysfs_attr_group)) + goto out_in_base; + ++ pr_info("secure-monitor enabled\n"); ++ + return 0; + + out_in_base: +diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c +index 597d1a367d96d..6231c98ba291a 100644 +--- a/drivers/firmware/ti_sci.c ++++ b/drivers/firmware/ti_sci.c +@@ -161,7 +161,7 @@ static int ti_sci_debugfs_create(struct platform_device *pdev, + { + struct device *dev = &pdev->dev; + struct resource *res; +- char debug_name[50] = "ti_sci_debug@"; ++ char debug_name[50]; + + /* Debug region is optional */ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, +@@ -178,10 +178,10 @@ static int ti_sci_debugfs_create(struct platform_device *pdev, + /* Setup NULL termination */ + info->debug_buffer[info->debug_region_size] = 0; + +- info->d = debugfs_create_file(strncat(debug_name, dev_name(dev), +- sizeof(debug_name) - +- sizeof("ti_sci_debug@")), +- 0444, NULL, info, &ti_sci_debug_fops); ++ snprintf(debug_name, sizeof(debug_name), "ti_sci_debug@%s", ++ dev_name(dev)); ++ info->d = debugfs_create_file(debug_name, 0444, NULL, info, ++ &ti_sci_debug_fops); + if (IS_ERR(info->d)) + return PTR_ERR(info->d); + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +index 8123feb1a1161..06ab6066da61a 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +@@ -596,7 +596,7 @@ static ssize_t amdgpu_debugfs_regs_smc_read(struct file *f, char __user *buf, + int r; + + if (!adev->smc_rreg) +- return -EPERM; ++ return -EOPNOTSUPP; + + if (size & 0x3 || *pos & 0x3) + return -EINVAL; +@@ -655,7 +655,7 @@ static ssize_t amdgpu_debugfs_regs_smc_write(struct file *f, const char __user * + int r; + + if (!adev->smc_wreg) +- return -EPERM; ++ return -EOPNOTSUPP; + + if (size & 0x3 || *pos & 0x3) + return -EINVAL; +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +index b9983ca99eb7d..a8e1f2cfe12dc 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +@@ -2202,6 +2202,8 @@ retry_init: + + pci_wake_from_d3(pdev, TRUE); + ++ pci_wake_from_d3(pdev, TRUE); ++ + /* + * For runpm implemented via BACO, PMFW will handle the + * timing for BACO in and out: +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c +index 88bf6221d4bef..8a7705db0b9a6 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c +@@ -1019,7 +1019,7 @@ int svm_migrate_init(struct amdgpu_device *adev) + } else { + res = devm_request_free_mem_region(adev->dev, &iomem_resource, size); + if (IS_ERR(res)) +- return -ENOMEM; ++ return PTR_ERR(res); + pgmap->range.start = res->start; + pgmap->range.end = res->end; + pgmap->type = MEMORY_DEVICE_PRIVATE; +@@ -1035,11 +1035,10 @@ int svm_migrate_init(struct amdgpu_device *adev) + r = devm_memremap_pages(adev->dev, pgmap); + if (IS_ERR(r)) { + pr_err("failed to register HMM device memory\n"); ++ if (pgmap->type == MEMORY_DEVICE_PRIVATE) ++ devm_release_mem_region(adev->dev, res->start, resource_size(res)); + /* Disable SVM support capability */ + pgmap->type = 0; +- if (pgmap->type == MEMORY_DEVICE_PRIVATE) +- devm_release_mem_region(adev->dev, res->start, +- res->end - res->start + 1); + return PTR_ERR(r); + } + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +index 713f893d25302..705d9e91b5aa3 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +@@ -1403,10 +1403,11 @@ static int kfd_create_indirect_link_prop(struct kfd_topology_device *kdev, int g + num_cpu++; + } + ++ if (list_empty(&kdev->io_link_props)) ++ return -ENODATA; ++ + gpu_link = list_first_entry(&kdev->io_link_props, +- struct kfd_iolink_properties, list); +- if (!gpu_link) +- return -ENOMEM; ++ struct kfd_iolink_properties, list); + + for (i = 0; i < num_cpu; i++) { + /* CPU <--> GPU */ +@@ -1484,15 +1485,17 @@ static int kfd_add_peer_prop(struct kfd_topology_device *kdev, + peer->gpu->adev)) + return ret; + ++ if (list_empty(&kdev->io_link_props)) ++ return -ENODATA; ++ + iolink1 = list_first_entry(&kdev->io_link_props, +- struct kfd_iolink_properties, list); +- if (!iolink1) +- return -ENOMEM; ++ struct kfd_iolink_properties, list); ++ ++ if (list_empty(&peer->io_link_props)) ++ return -ENODATA; + + iolink2 = list_first_entry(&peer->io_link_props, +- struct kfd_iolink_properties, list); +- if (!iolink2) +- return -ENOMEM; ++ struct kfd_iolink_properties, list); + + props = kfd_alloc_struct(props); + if (!props) +diff --git a/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c b/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c +index f5e08b60f66ef..d17bfa111aa74 100644 +--- a/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c ++++ b/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c +@@ -2748,10 +2748,8 @@ static int kv_parse_power_table(struct amdgpu_device *adev) + non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) + &non_clock_info_array->nonClockInfo[non_clock_array_index]; + ps = kzalloc(sizeof(struct kv_ps), GFP_KERNEL); +- if (ps == NULL) { +- kfree(adev->pm.dpm.ps); ++ if (ps == NULL) + return -ENOMEM; +- } + adev->pm.dpm.ps[i].ps_priv = ps; + k = 0; + idx = (u8 *)&power_state->v2.clockInfoIndex[0]; +diff --git a/drivers/gpu/drm/amd/pm/legacy-dpm/legacy_dpm.c b/drivers/gpu/drm/amd/pm/legacy-dpm/legacy_dpm.c +index d3fe149d84765..291223ea7ba7d 100644 +--- a/drivers/gpu/drm/amd/pm/legacy-dpm/legacy_dpm.c ++++ b/drivers/gpu/drm/amd/pm/legacy-dpm/legacy_dpm.c +@@ -272,10 +272,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) + le16_to_cpu(power_info->pplib4.usVddcDependencyOnSCLKOffset)); + ret = amdgpu_parse_clk_voltage_dep_table(&adev->pm.dpm.dyn_state.vddc_dependency_on_sclk, + dep_table); +- if (ret) { +- amdgpu_free_extended_power_table(adev); ++ if (ret) + return ret; +- } + } + if (power_info->pplib4.usVddciDependencyOnMCLKOffset) { + dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *) +@@ -283,10 +281,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) + le16_to_cpu(power_info->pplib4.usVddciDependencyOnMCLKOffset)); + ret = amdgpu_parse_clk_voltage_dep_table(&adev->pm.dpm.dyn_state.vddci_dependency_on_mclk, + dep_table); +- if (ret) { +- amdgpu_free_extended_power_table(adev); ++ if (ret) + return ret; +- } + } + if (power_info->pplib4.usVddcDependencyOnMCLKOffset) { + dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *) +@@ -294,10 +290,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) + le16_to_cpu(power_info->pplib4.usVddcDependencyOnMCLKOffset)); + ret = amdgpu_parse_clk_voltage_dep_table(&adev->pm.dpm.dyn_state.vddc_dependency_on_mclk, + dep_table); +- if (ret) { +- amdgpu_free_extended_power_table(adev); ++ if (ret) + return ret; +- } + } + if (power_info->pplib4.usMvddDependencyOnMCLKOffset) { + dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *) +@@ -305,10 +299,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) + le16_to_cpu(power_info->pplib4.usMvddDependencyOnMCLKOffset)); + ret = amdgpu_parse_clk_voltage_dep_table(&adev->pm.dpm.dyn_state.mvdd_dependency_on_mclk, + dep_table); +- if (ret) { +- amdgpu_free_extended_power_table(adev); ++ if (ret) + return ret; +- } + } + if (power_info->pplib4.usMaxClockVoltageOnDCOffset) { + ATOM_PPLIB_Clock_Voltage_Limit_Table *clk_v = +@@ -339,10 +331,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) + kcalloc(psl->ucNumEntries, + sizeof(struct amdgpu_phase_shedding_limits_entry), + GFP_KERNEL); +- if (!adev->pm.dpm.dyn_state.phase_shedding_limits_table.entries) { +- amdgpu_free_extended_power_table(adev); ++ if (!adev->pm.dpm.dyn_state.phase_shedding_limits_table.entries) + return -ENOMEM; +- } + + entry = &psl->entries[0]; + for (i = 0; i < psl->ucNumEntries; i++) { +@@ -383,10 +373,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) + ATOM_PPLIB_CAC_Leakage_Record *entry; + u32 size = cac_table->ucNumEntries * sizeof(struct amdgpu_cac_leakage_table); + adev->pm.dpm.dyn_state.cac_leakage_table.entries = kzalloc(size, GFP_KERNEL); +- if (!adev->pm.dpm.dyn_state.cac_leakage_table.entries) { +- amdgpu_free_extended_power_table(adev); ++ if (!adev->pm.dpm.dyn_state.cac_leakage_table.entries) + return -ENOMEM; +- } + entry = &cac_table->entries[0]; + for (i = 0; i < cac_table->ucNumEntries; i++) { + if (adev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_EVV) { +@@ -438,10 +426,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) + sizeof(struct amdgpu_vce_clock_voltage_dependency_entry); + adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries = + kzalloc(size, GFP_KERNEL); +- if (!adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries) { +- amdgpu_free_extended_power_table(adev); ++ if (!adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries) + return -ENOMEM; +- } + adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.count = + limits->numEntries; + entry = &limits->entries[0]; +@@ -493,10 +479,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) + sizeof(struct amdgpu_uvd_clock_voltage_dependency_entry); + adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.entries = + kzalloc(size, GFP_KERNEL); +- if (!adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.entries) { +- amdgpu_free_extended_power_table(adev); ++ if (!adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.entries) + return -ENOMEM; +- } + adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.count = + limits->numEntries; + entry = &limits->entries[0]; +@@ -525,10 +509,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) + sizeof(struct amdgpu_clock_voltage_dependency_entry); + adev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.entries = + kzalloc(size, GFP_KERNEL); +- if (!adev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.entries) { +- amdgpu_free_extended_power_table(adev); ++ if (!adev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.entries) + return -ENOMEM; +- } + adev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.count = + limits->numEntries; + entry = &limits->entries[0]; +@@ -548,10 +530,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) + le16_to_cpu(ext_hdr->usPPMTableOffset)); + adev->pm.dpm.dyn_state.ppm_table = + kzalloc(sizeof(struct amdgpu_ppm_table), GFP_KERNEL); +- if (!adev->pm.dpm.dyn_state.ppm_table) { +- amdgpu_free_extended_power_table(adev); ++ if (!adev->pm.dpm.dyn_state.ppm_table) + return -ENOMEM; +- } + adev->pm.dpm.dyn_state.ppm_table->ppm_design = ppm->ucPpmDesign; + adev->pm.dpm.dyn_state.ppm_table->cpu_core_number = + le16_to_cpu(ppm->usCpuCoreNumber); +@@ -583,10 +563,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) + sizeof(struct amdgpu_clock_voltage_dependency_entry); + adev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.entries = + kzalloc(size, GFP_KERNEL); +- if (!adev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.entries) { +- amdgpu_free_extended_power_table(adev); ++ if (!adev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.entries) + return -ENOMEM; +- } + adev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.count = + limits->numEntries; + entry = &limits->entries[0]; +@@ -606,10 +584,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) + ATOM_PowerTune_Table *pt; + adev->pm.dpm.dyn_state.cac_tdp_table = + kzalloc(sizeof(struct amdgpu_cac_tdp_table), GFP_KERNEL); +- if (!adev->pm.dpm.dyn_state.cac_tdp_table) { +- amdgpu_free_extended_power_table(adev); ++ if (!adev->pm.dpm.dyn_state.cac_tdp_table) + return -ENOMEM; +- } + if (rev > 0) { + ATOM_PPLIB_POWERTUNE_Table_V1 *ppt = (ATOM_PPLIB_POWERTUNE_Table_V1 *) + (mode_info->atom_context->bios + data_offset + +@@ -645,10 +621,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) + ret = amdgpu_parse_clk_voltage_dep_table( + &adev->pm.dpm.dyn_state.vddgfx_dependency_on_sclk, + dep_table); +- if (ret) { +- kfree(adev->pm.dpm.dyn_state.vddgfx_dependency_on_sclk.entries); ++ if (ret) + return ret; +- } + } + } + +diff --git a/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c b/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c +index c89cfef7cafa1..dc0a6fba7050f 100644 +--- a/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c ++++ b/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c +@@ -7379,10 +7379,9 @@ static int si_dpm_init(struct amdgpu_device *adev) + kcalloc(4, + sizeof(struct amdgpu_clock_voltage_dependency_entry), + GFP_KERNEL); +- if (!adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries) { +- amdgpu_free_extended_power_table(adev); ++ if (!adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries) + return -ENOMEM; +- } ++ + adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.count = 4; + adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].clk = 0; + adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].v = 0; +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c +index a31a62a1ce0b2..5e9410117712c 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c +@@ -2987,6 +2987,8 @@ static int smu7_hwmgr_backend_init(struct pp_hwmgr *hwmgr) + result = smu7_get_evv_voltages(hwmgr); + if (result) { + pr_info("Get EVV Voltage Failed. Abort Driver loading!\n"); ++ kfree(hwmgr->backend); ++ hwmgr->backend = NULL; + return -EINVAL; + } + } else { +@@ -3032,8 +3034,10 @@ static int smu7_hwmgr_backend_init(struct pp_hwmgr *hwmgr) + } + + result = smu7_update_edc_leakage_table(hwmgr); +- if (result) ++ if (result) { ++ smu7_hwmgr_backend_fini(hwmgr); + return result; ++ } + + return 0; + } +diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c +index 946212a955981..5e3b8edcf7948 100644 +--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c ++++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c +@@ -403,7 +403,8 @@ static int _cdns_mhdp_hdcp_disable(struct cdns_mhdp_device *mhdp) + + static int _cdns_mhdp_hdcp_enable(struct cdns_mhdp_device *mhdp, u8 content_type) + { +- int ret, tries = 3; ++ int ret = -EINVAL; ++ int tries = 3; + u32 i; + + for (i = 0; i < tries; i++) { +diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c +index 7ef78283e3d3e..926ab5c3c31ab 100644 +--- a/drivers/gpu/drm/bridge/tc358767.c ++++ b/drivers/gpu/drm/bridge/tc358767.c +@@ -2097,7 +2097,7 @@ static int tc_probe(struct i2c_client *client, const struct i2c_device_id *id) + } else { + if (tc->hpd_pin < 0 || tc->hpd_pin > 1) { + dev_err(dev, "failed to parse HPD number\n"); +- return ret; ++ return -EINVAL; + } + } + +diff --git a/drivers/gpu/drm/bridge/ti-tpd12s015.c b/drivers/gpu/drm/bridge/ti-tpd12s015.c +index e0e015243a602..b588fea12502d 100644 +--- a/drivers/gpu/drm/bridge/ti-tpd12s015.c ++++ b/drivers/gpu/drm/bridge/ti-tpd12s015.c +@@ -179,7 +179,7 @@ static int tpd12s015_probe(struct platform_device *pdev) + return 0; + } + +-static int __exit tpd12s015_remove(struct platform_device *pdev) ++static int tpd12s015_remove(struct platform_device *pdev) + { + struct tpd12s015_device *tpd = platform_get_drvdata(pdev); + +@@ -197,7 +197,7 @@ MODULE_DEVICE_TABLE(of, tpd12s015_of_match); + + static struct platform_driver tpd12s015_driver = { + .probe = tpd12s015_probe, +- .remove = __exit_p(tpd12s015_remove), ++ .remove = tpd12s015_remove, + .driver = { + .name = "tpd12s015", + .of_match_table = tpd12s015_of_match, +diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c +index 203bf8d6c34c4..d41a5eaa3e892 100644 +--- a/drivers/gpu/drm/drm_drv.c ++++ b/drivers/gpu/drm/drm_drv.c +@@ -895,8 +895,11 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags) + goto err_minors; + } + +- if (drm_core_check_feature(dev, DRIVER_MODESET)) +- drm_modeset_register_all(dev); ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) { ++ ret = drm_modeset_register_all(dev); ++ if (ret) ++ goto err_unload; ++ } + + DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n", + driver->name, driver->major, driver->minor, +@@ -906,6 +909,9 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags) + + goto out_unlock; + ++err_unload: ++ if (dev->driver->unload) ++ dev->driver->unload(dev); + err_minors: + remove_compat_control_link(dev); + drm_minor_unregister(dev, DRM_MINOR_PRIMARY); +diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c b/drivers/gpu/drm/mediatek/mtk_disp_merge.c +index 6428b6203ffe8..211140e87568d 100644 +--- a/drivers/gpu/drm/mediatek/mtk_disp_merge.c ++++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c +@@ -104,7 +104,7 @@ void mtk_merge_stop_cmdq(struct device *dev, struct cmdq_pkt *cmdq_pkt) + mtk_ddp_write(cmdq_pkt, 0, &priv->cmdq_reg, priv->regs, + DISP_REG_MERGE_CTRL); + +- if (priv->async_clk) ++ if (!cmdq_pkt && priv->async_clk) + reset_control_reset(priv->reset_ctl); + } + +diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c +index 2c850b6d945bc..519e23a2a017c 100644 +--- a/drivers/gpu/drm/mediatek/mtk_dp.c ++++ b/drivers/gpu/drm/mediatek/mtk_dp.c +@@ -2669,3 +2669,4 @@ MODULE_AUTHOR("Markus Schneider-Pargmann <msp@baylibre.com>"); + MODULE_AUTHOR("Bo-Chen Chen <rex-bc.chen@mediatek.com>"); + MODULE_DESCRIPTION("MediaTek DisplayPort Driver"); + MODULE_LICENSE("GPL"); ++MODULE_SOFTDEP("pre: phy_mtk_dp"); +diff --git a/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c +index eecfa98ff52e8..b288bb6eeecc7 100644 +--- a/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c ++++ b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c +@@ -223,8 +223,7 @@ int mtk_mdp_rdma_clk_enable(struct device *dev) + { + struct mtk_mdp_rdma *rdma = dev_get_drvdata(dev); + +- clk_prepare_enable(rdma->clk); +- return 0; ++ return clk_prepare_enable(rdma->clk); + } + + void mtk_mdp_rdma_clk_disable(struct device *dev) +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +index 6c0ffe8e4adbd..5a5821e59dc15 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +@@ -1,6 +1,6 @@ + // SPDX-License-Identifier: GPL-2.0-only + /* +- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. + * Copyright (C) 2013 Red Hat + * Author: Rob Clark <robdclark@gmail.com> +@@ -124,7 +124,7 @@ static void dpu_crtc_setup_lm_misr(struct dpu_crtc_state *crtc_state) + continue; + + /* Calculate MISR over 1 frame */ +- m->hw_lm->ops.setup_misr(m->hw_lm, true, 1); ++ m->hw_lm->ops.setup_misr(m->hw_lm); + } + } + +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +index 547f9f2b9fcb5..b0eb881f8af13 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +@@ -2,7 +2,7 @@ + /* + * Copyright (C) 2013 Red Hat + * Copyright (c) 2014-2018, 2020-2021 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. + * + * Author: Rob Clark <robdclark@gmail.com> + */ +@@ -257,7 +257,7 @@ void dpu_encoder_setup_misr(const struct drm_encoder *drm_enc) + if (!phys->hw_intf || !phys->hw_intf->ops.setup_misr) + continue; + +- phys->hw_intf->ops.setup_misr(phys->hw_intf, true, 1); ++ phys->hw_intf->ops.setup_misr(phys->hw_intf); + } + } + +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c +index b9dddf576c029..384558d2f9602 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c +@@ -1,6 +1,6 @@ + // SPDX-License-Identifier: GPL-2.0-only + /* +- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + */ + +@@ -322,9 +322,9 @@ static u32 dpu_hw_intf_get_line_count(struct dpu_hw_intf *intf) + return DPU_REG_READ(c, INTF_LINE_COUNT); + } + +-static void dpu_hw_intf_setup_misr(struct dpu_hw_intf *intf, bool enable, u32 frame_count) ++static void dpu_hw_intf_setup_misr(struct dpu_hw_intf *intf) + { +- dpu_hw_setup_misr(&intf->hw, INTF_MISR_CTRL, enable, frame_count); ++ dpu_hw_setup_misr(&intf->hw, INTF_MISR_CTRL, 0x1); + } + + static int dpu_hw_intf_collect_misr(struct dpu_hw_intf *intf, u32 *misr_value) +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h +index 643dd10bc0306..e75339b96a1d2 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h +@@ -1,6 +1,6 @@ + /* SPDX-License-Identifier: GPL-2.0-only */ + /* +- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + */ + +@@ -80,7 +80,7 @@ struct dpu_hw_intf_ops { + void (*bind_pingpong_blk)(struct dpu_hw_intf *intf, + bool enable, + const enum dpu_pingpong pp); +- void (*setup_misr)(struct dpu_hw_intf *intf, bool enable, u32 frame_count); ++ void (*setup_misr)(struct dpu_hw_intf *intf); + int (*collect_misr)(struct dpu_hw_intf *intf, u32 *misr_value); + }; + +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c +index f5120ea91edee..cc04fb979fb5c 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c +@@ -1,6 +1,6 @@ + // SPDX-License-Identifier: GPL-2.0-only + /* +- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. + */ + +@@ -99,9 +99,9 @@ static void dpu_hw_lm_setup_border_color(struct dpu_hw_mixer *ctx, + } + } + +-static void dpu_hw_lm_setup_misr(struct dpu_hw_mixer *ctx, bool enable, u32 frame_count) ++static void dpu_hw_lm_setup_misr(struct dpu_hw_mixer *ctx) + { +- dpu_hw_setup_misr(&ctx->hw, LM_MISR_CTRL, enable, frame_count); ++ dpu_hw_setup_misr(&ctx->hw, LM_MISR_CTRL, 0x0); + } + + static int dpu_hw_lm_collect_misr(struct dpu_hw_mixer *ctx, u32 *misr_value) +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h +index 652ddfdedec37..0a050eb247b99 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h +@@ -1,5 +1,6 @@ + /* SPDX-License-Identifier: GPL-2.0-only */ + /* ++ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. + */ + +@@ -57,7 +58,7 @@ struct dpu_hw_lm_ops { + /** + * setup_misr: Enable/disable MISR + */ +- void (*setup_misr)(struct dpu_hw_mixer *ctx, bool enable, u32 frame_count); ++ void (*setup_misr)(struct dpu_hw_mixer *ctx); + + /** + * collect_misr: Read MISR signature +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c +index 8062228eada68..1b7439ae686a7 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c +@@ -1,6 +1,6 @@ + // SPDX-License-Identifier: GPL-2.0-only + /* +- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + */ + #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__ +@@ -450,9 +450,11 @@ u64 _dpu_hw_get_qos_lut(const struct dpu_qos_lut_tbl *tbl, + return 0; + } + ++/* ++ * note: Aside from encoders, input_sel should be set to 0x0 by default ++ */ + void dpu_hw_setup_misr(struct dpu_hw_blk_reg_map *c, +- u32 misr_ctrl_offset, +- bool enable, u32 frame_count) ++ u32 misr_ctrl_offset, u8 input_sel) + { + u32 config = 0; + +@@ -461,15 +463,9 @@ void dpu_hw_setup_misr(struct dpu_hw_blk_reg_map *c, + /* Clear old MISR value (in case it's read before a new value is calculated)*/ + wmb(); + +- if (enable) { +- config = (frame_count & MISR_FRAME_COUNT_MASK) | +- MISR_CTRL_ENABLE | MISR_CTRL_FREE_RUN_MASK; +- +- DPU_REG_WRITE(c, misr_ctrl_offset, config); +- } else { +- DPU_REG_WRITE(c, misr_ctrl_offset, 0); +- } +- ++ config = MISR_FRAME_COUNT | MISR_CTRL_ENABLE | MISR_CTRL_FREE_RUN_MASK | ++ ((input_sel & 0xF) << 24); ++ DPU_REG_WRITE(c, misr_ctrl_offset, config); + } + + int dpu_hw_collect_misr(struct dpu_hw_blk_reg_map *c, +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h +index 27f4c39e35ab3..4ae2a434372cf 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h +@@ -1,6 +1,6 @@ + /* SPDX-License-Identifier: GPL-2.0-only */ + /* +- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. + */ + +@@ -13,7 +13,7 @@ + #include "dpu_hw_catalog.h" + + #define REG_MASK(n) ((BIT(n)) - 1) +-#define MISR_FRAME_COUNT_MASK 0xFF ++#define MISR_FRAME_COUNT 0x1 + #define MISR_CTRL_ENABLE BIT(8) + #define MISR_CTRL_STATUS BIT(9) + #define MISR_CTRL_STATUS_CLEAR BIT(10) +@@ -350,9 +350,7 @@ u64 _dpu_hw_get_qos_lut(const struct dpu_qos_lut_tbl *tbl, + u32 total_fl); + + void dpu_hw_setup_misr(struct dpu_hw_blk_reg_map *c, +- u32 misr_ctrl_offset, +- bool enable, +- u32 frame_count); ++ u32 misr_ctrl_offset, u8 input_sel); + + int dpu_hw_collect_misr(struct dpu_hw_blk_reg_map *c, + u32 misr_ctrl_offset, +diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c +index 169f9de4a12a7..3100957225a70 100644 +--- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c ++++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c +@@ -269,6 +269,7 @@ static void mdp4_crtc_atomic_disable(struct drm_crtc *crtc, + { + struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); + struct mdp4_kms *mdp4_kms = get_kms(crtc); ++ unsigned long flags; + + DBG("%s", mdp4_crtc->name); + +@@ -281,6 +282,14 @@ static void mdp4_crtc_atomic_disable(struct drm_crtc *crtc, + mdp_irq_unregister(&mdp4_kms->base, &mdp4_crtc->err); + mdp4_disable(mdp4_kms); + ++ if (crtc->state->event && !crtc->state->active) { ++ WARN_ON(mdp4_crtc->event); ++ spin_lock_irqsave(&mdp4_kms->dev->event_lock, flags); ++ drm_crtc_send_vblank_event(crtc, crtc->state->event); ++ crtc->state->event = NULL; ++ spin_unlock_irqrestore(&mdp4_kms->dev->event_lock, flags); ++ } ++ + mdp4_crtc->enabled = false; + } + +diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c +index 7fc0975cb8693..62bc3756f2e2b 100644 +--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c ++++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c +@@ -512,7 +512,9 @@ static int dsi_phy_enable_resource(struct msm_dsi_phy *phy) + struct device *dev = &phy->pdev->dev; + int ret; + +- pm_runtime_get_sync(dev); ++ ret = pm_runtime_resume_and_get(dev); ++ if (ret) ++ return ret; + + ret = clk_prepare_enable(phy->ahb_clk); + if (ret) { +diff --git a/drivers/gpu/drm/nouveau/nv04_fence.c b/drivers/gpu/drm/nouveau/nv04_fence.c +index 5b71a5a5cd85c..cdbc75e3d1f66 100644 +--- a/drivers/gpu/drm/nouveau/nv04_fence.c ++++ b/drivers/gpu/drm/nouveau/nv04_fence.c +@@ -39,7 +39,7 @@ struct nv04_fence_priv { + static int + nv04_fence_emit(struct nouveau_fence *fence) + { +- struct nvif_push *push = fence->channel->chan.push; ++ struct nvif_push *push = unrcu_pointer(fence->channel)->chan.push; + int ret = PUSH_WAIT(push, 2); + if (ret == 0) { + PUSH_NVSQ(push, NV_SW, 0x0150, fence->base.seqno); +diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c +index eaf67b9e5f12b..5b6d1668f405c 100644 +--- a/drivers/gpu/drm/omapdrm/omap_drv.c ++++ b/drivers/gpu/drm/omapdrm/omap_drv.c +@@ -68,7 +68,6 @@ static void omap_atomic_commit_tail(struct drm_atomic_state *old_state) + { + struct drm_device *dev = old_state->dev; + struct omap_drm_private *priv = dev->dev_private; +- bool fence_cookie = dma_fence_begin_signalling(); + + dispc_runtime_get(priv->dispc); + +@@ -91,6 +90,8 @@ static void omap_atomic_commit_tail(struct drm_atomic_state *old_state) + omap_atomic_wait_for_completion(dev, old_state); + + drm_atomic_helper_commit_planes(dev, old_state, 0); ++ ++ drm_atomic_helper_commit_hw_done(old_state); + } else { + /* + * OMAP3 DSS seems to have issues with the work-around above, +@@ -100,11 +101,9 @@ static void omap_atomic_commit_tail(struct drm_atomic_state *old_state) + drm_atomic_helper_commit_planes(dev, old_state, 0); + + drm_atomic_helper_commit_modeset_enables(dev, old_state); +- } + +- drm_atomic_helper_commit_hw_done(old_state); +- +- dma_fence_end_signalling(fence_cookie); ++ drm_atomic_helper_commit_hw_done(old_state); ++ } + + /* + * Wait for completion of the page flips to ensure that old buffers +diff --git a/drivers/gpu/drm/panel/panel-elida-kd35t133.c b/drivers/gpu/drm/panel/panel-elida-kd35t133.c +index eee714cf3f490..3a7fc3ca6a6fe 100644 +--- a/drivers/gpu/drm/panel/panel-elida-kd35t133.c ++++ b/drivers/gpu/drm/panel/panel-elida-kd35t133.c +@@ -112,6 +112,8 @@ static int kd35t133_unprepare(struct drm_panel *panel) + return ret; + } + ++ gpiod_set_value_cansleep(ctx->reset_gpio, 1); ++ + regulator_disable(ctx->iovcc); + regulator_disable(ctx->vdd); + +diff --git a/drivers/gpu/drm/panel/panel-sitronix-st7701.c b/drivers/gpu/drm/panel/panel-sitronix-st7701.c +index 225b9884f61a9..54b28992db5d8 100644 +--- a/drivers/gpu/drm/panel/panel-sitronix-st7701.c ++++ b/drivers/gpu/drm/panel/panel-sitronix-st7701.c +@@ -288,7 +288,7 @@ static void st7701_init_sequence(struct st7701 *st7701) + FIELD_PREP(DSI_CMD2_BK1_PWRCTRL2_AVDD_MASK, + DIV_ROUND_CLOSEST(desc->avdd_mv - 6200, 200)) | + FIELD_PREP(DSI_CMD2_BK1_PWRCTRL2_AVCL_MASK, +- DIV_ROUND_CLOSEST(-4400 + desc->avcl_mv, 200))); ++ DIV_ROUND_CLOSEST(-4400 - desc->avcl_mv, 200))); + + /* T2D = 0.2us * T2D[3:0] */ + ST7701_DSI(st7701, DSI_CMD2_BK1_SPD1, +diff --git a/drivers/gpu/drm/panfrost/panfrost_gpu.c b/drivers/gpu/drm/panfrost/panfrost_gpu.c +index 6452e4e900dd7..55d2430485168 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_gpu.c ++++ b/drivers/gpu/drm/panfrost/panfrost_gpu.c +@@ -71,7 +71,12 @@ int panfrost_gpu_soft_reset(struct panfrost_device *pfdev) + } + + gpu_write(pfdev, GPU_INT_CLEAR, GPU_IRQ_MASK_ALL); +- gpu_write(pfdev, GPU_INT_MASK, GPU_IRQ_MASK_ALL); ++ ++ /* Only enable the interrupts we care about */ ++ gpu_write(pfdev, GPU_INT_MASK, ++ GPU_IRQ_MASK_ERROR | ++ GPU_IRQ_PERFCNT_SAMPLE_COMPLETED | ++ GPU_IRQ_CLEAN_CACHES_COMPLETED); + + return 0; + } +@@ -313,28 +318,38 @@ static void panfrost_gpu_init_features(struct panfrost_device *pfdev) + pfdev->features.shader_present, pfdev->features.l2_present); + } + ++static u64 panfrost_get_core_mask(struct panfrost_device *pfdev) ++{ ++ u64 core_mask; ++ ++ if (pfdev->features.l2_present == 1) ++ return U64_MAX; ++ ++ /* ++ * Only support one core group now. ++ * ~(l2_present - 1) unsets all bits in l2_present except ++ * the bottom bit. (l2_present - 2) has all the bits in ++ * the first core group set. AND them together to generate ++ * a mask of cores in the first core group. ++ */ ++ core_mask = ~(pfdev->features.l2_present - 1) & ++ (pfdev->features.l2_present - 2); ++ dev_info_once(pfdev->dev, "using only 1st core group (%lu cores from %lu)\n", ++ hweight64(core_mask), ++ hweight64(pfdev->features.shader_present)); ++ ++ return core_mask; ++} ++ + void panfrost_gpu_power_on(struct panfrost_device *pfdev) + { + int ret; + u32 val; +- u64 core_mask = U64_MAX; ++ u64 core_mask; + + panfrost_gpu_init_quirks(pfdev); ++ core_mask = panfrost_get_core_mask(pfdev); + +- if (pfdev->features.l2_present != 1) { +- /* +- * Only support one core group now. +- * ~(l2_present - 1) unsets all bits in l2_present except +- * the bottom bit. (l2_present - 2) has all the bits in +- * the first core group set. AND them together to generate +- * a mask of cores in the first core group. +- */ +- core_mask = ~(pfdev->features.l2_present - 1) & +- (pfdev->features.l2_present - 2); +- dev_info_once(pfdev->dev, "using only 1st core group (%lu cores from %lu)\n", +- hweight64(core_mask), +- hweight64(pfdev->features.shader_present)); +- } + gpu_write(pfdev, L2_PWRON_LO, pfdev->features.l2_present & core_mask); + ret = readl_relaxed_poll_timeout(pfdev->iomem + L2_READY_LO, + val, val == (pfdev->features.l2_present & core_mask), +@@ -359,9 +374,26 @@ void panfrost_gpu_power_on(struct panfrost_device *pfdev) + + void panfrost_gpu_power_off(struct panfrost_device *pfdev) + { +- gpu_write(pfdev, TILER_PWROFF_LO, 0); +- gpu_write(pfdev, SHADER_PWROFF_LO, 0); +- gpu_write(pfdev, L2_PWROFF_LO, 0); ++ int ret; ++ u32 val; ++ ++ gpu_write(pfdev, SHADER_PWROFF_LO, pfdev->features.shader_present); ++ ret = readl_relaxed_poll_timeout(pfdev->iomem + SHADER_PWRTRANS_LO, ++ val, !val, 1, 1000); ++ if (ret) ++ dev_err(pfdev->dev, "shader power transition timeout"); ++ ++ gpu_write(pfdev, TILER_PWROFF_LO, pfdev->features.tiler_present); ++ ret = readl_relaxed_poll_timeout(pfdev->iomem + TILER_PWRTRANS_LO, ++ val, !val, 1, 1000); ++ if (ret) ++ dev_err(pfdev->dev, "tiler power transition timeout"); ++ ++ gpu_write(pfdev, L2_PWROFF_LO, pfdev->features.l2_present); ++ ret = readl_poll_timeout(pfdev->iomem + L2_PWRTRANS_LO, ++ val, !val, 0, 1000); ++ if (ret) ++ dev_err(pfdev->dev, "l2 power transition timeout"); + } + + int panfrost_gpu_init(struct panfrost_device *pfdev) +diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c +index d4f09ecc3d221..f336b5b3b11f4 100644 +--- a/drivers/gpu/drm/radeon/r100.c ++++ b/drivers/gpu/drm/radeon/r100.c +@@ -2321,7 +2321,7 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) + switch (prim_walk) { + case 1: + for (i = 0; i < track->num_arrays; i++) { +- size = track->arrays[i].esize * track->max_indx * 4; ++ size = track->arrays[i].esize * track->max_indx * 4UL; + if (track->arrays[i].robj == NULL) { + DRM_ERROR("(PW %u) Vertex array %u no buffer " + "bound\n", prim_walk, i); +@@ -2340,7 +2340,7 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) + break; + case 2: + for (i = 0; i < track->num_arrays; i++) { +- size = track->arrays[i].esize * (nverts - 1) * 4; ++ size = track->arrays[i].esize * (nverts - 1) * 4UL; + if (track->arrays[i].robj == NULL) { + DRM_ERROR("(PW %u) Vertex array %u no buffer " + "bound\n", prim_walk, i); +diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c +index 638f861af80fa..6cf54a747749d 100644 +--- a/drivers/gpu/drm/radeon/r600_cs.c ++++ b/drivers/gpu/drm/radeon/r600_cs.c +@@ -1275,7 +1275,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) + return -EINVAL; + } + tmp = (reg - CB_COLOR0_BASE) / 4; +- track->cb_color_bo_offset[tmp] = radeon_get_ib_value(p, idx) << 8; ++ track->cb_color_bo_offset[tmp] = (u64)radeon_get_ib_value(p, idx) << 8; + ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff); + track->cb_color_base_last[tmp] = ib[idx]; + track->cb_color_bo[tmp] = reloc->robj; +@@ -1302,7 +1302,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) + "0x%04X\n", reg); + return -EINVAL; + } +- track->htile_offset = radeon_get_ib_value(p, idx) << 8; ++ track->htile_offset = (u64)radeon_get_ib_value(p, idx) << 8; + ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff); + track->htile_bo = reloc->robj; + track->db_dirty = true; +diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c +index ca5598ae8bfcf..1814bb8e14f10 100644 +--- a/drivers/gpu/drm/radeon/radeon_display.c ++++ b/drivers/gpu/drm/radeon/radeon_display.c +@@ -687,11 +687,16 @@ static void radeon_crtc_init(struct drm_device *dev, int index) + if (radeon_crtc == NULL) + return; + ++ radeon_crtc->flip_queue = alloc_workqueue("radeon-crtc", WQ_HIGHPRI, 0); ++ if (!radeon_crtc->flip_queue) { ++ kfree(radeon_crtc); ++ return; ++ } ++ + drm_crtc_init(dev, &radeon_crtc->base, &radeon_crtc_funcs); + + drm_mode_crtc_set_gamma_size(&radeon_crtc->base, 256); + radeon_crtc->crtc_id = index; +- radeon_crtc->flip_queue = alloc_workqueue("radeon-crtc", WQ_HIGHPRI, 0); + rdev->mode_info.crtcs[index] = radeon_crtc; + + if (rdev->family >= CHIP_BONAIRE) { +diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c +index 987cabbf1318e..c38b4d5d6a14f 100644 +--- a/drivers/gpu/drm/radeon/radeon_vm.c ++++ b/drivers/gpu/drm/radeon/radeon_vm.c +@@ -1204,13 +1204,17 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) + r = radeon_bo_create(rdev, pd_size, align, true, + RADEON_GEM_DOMAIN_VRAM, 0, NULL, + NULL, &vm->page_directory); +- if (r) ++ if (r) { ++ kfree(vm->page_tables); ++ vm->page_tables = NULL; + return r; +- ++ } + r = radeon_vm_clear_bo(rdev, vm->page_directory); + if (r) { + radeon_bo_unref(&vm->page_directory); + vm->page_directory = NULL; ++ kfree(vm->page_tables); ++ vm->page_tables = NULL; + return r; + } + +diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c +index a91012447b56e..85e9cba49cecb 100644 +--- a/drivers/gpu/drm/radeon/si.c ++++ b/drivers/gpu/drm/radeon/si.c +@@ -3611,6 +3611,10 @@ static int si_cp_start(struct radeon_device *rdev) + for (i = RADEON_RING_TYPE_GFX_INDEX; i <= CAYMAN_RING_TYPE_CP2_INDEX; ++i) { + ring = &rdev->ring[i]; + r = radeon_ring_lock(rdev, ring, 2); ++ if (r) { ++ DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); ++ return r; ++ } + + /* clear the compute context state */ + radeon_ring_write(ring, PACKET3_COMPUTE(PACKET3_CLEAR_STATE, 0)); +diff --git a/drivers/gpu/drm/radeon/sumo_dpm.c b/drivers/gpu/drm/radeon/sumo_dpm.c +index f74f381af05fd..d49c145db4370 100644 +--- a/drivers/gpu/drm/radeon/sumo_dpm.c ++++ b/drivers/gpu/drm/radeon/sumo_dpm.c +@@ -1493,8 +1493,10 @@ static int sumo_parse_power_table(struct radeon_device *rdev) + non_clock_array_index = power_state->v2.nonClockInfoIndex; + non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) + &non_clock_info_array->nonClockInfo[non_clock_array_index]; +- if (!rdev->pm.power_state[i].clock_info) ++ if (!rdev->pm.power_state[i].clock_info) { ++ kfree(rdev->pm.dpm.ps); + return -EINVAL; ++ } + ps = kzalloc(sizeof(struct sumo_ps), GFP_KERNEL); + if (ps == NULL) { + kfree(rdev->pm.dpm.ps); +diff --git a/drivers/gpu/drm/radeon/trinity_dpm.c b/drivers/gpu/drm/radeon/trinity_dpm.c +index 08ea1c864cb23..ef1cc7bad20a7 100644 +--- a/drivers/gpu/drm/radeon/trinity_dpm.c ++++ b/drivers/gpu/drm/radeon/trinity_dpm.c +@@ -1726,8 +1726,10 @@ static int trinity_parse_power_table(struct radeon_device *rdev) + non_clock_array_index = power_state->v2.nonClockInfoIndex; + non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) + &non_clock_info_array->nonClockInfo[non_clock_array_index]; +- if (!rdev->pm.power_state[i].clock_info) ++ if (!rdev->pm.power_state[i].clock_info) { ++ kfree(rdev->pm.dpm.ps); + return -EINVAL; ++ } + ps = kzalloc(sizeof(struct sumo_ps), GFP_KERNEL); + if (ps == NULL) { + kfree(rdev->pm.dpm.ps); +diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/tidss_dispc.c +index 16301bdfead12..95b75236fe5e8 100644 +--- a/drivers/gpu/drm/tidss/tidss_dispc.c ++++ b/drivers/gpu/drm/tidss/tidss_dispc.c +@@ -2653,18 +2653,69 @@ static void dispc_init_errata(struct dispc_device *dispc) + } + } + +-static void dispc_softreset(struct dispc_device *dispc) ++static int dispc_softreset(struct dispc_device *dispc) + { + u32 val; + int ret = 0; + ++ /* K2G display controller does not support soft reset */ ++ if (dispc->feat->subrev == DISPC_K2G) ++ return 0; ++ + /* Soft reset */ + REG_FLD_MOD(dispc, DSS_SYSCONFIG, 1, 1, 1); + /* Wait for reset to complete */ + ret = readl_poll_timeout(dispc->base_common + DSS_SYSSTATUS, + val, val & 1, 100, 5000); ++ if (ret) { ++ dev_err(dispc->dev, "failed to reset dispc\n"); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int dispc_init_hw(struct dispc_device *dispc) ++{ ++ struct device *dev = dispc->dev; ++ int ret; ++ ++ ret = pm_runtime_set_active(dev); ++ if (ret) { ++ dev_err(dev, "Failed to set DSS PM to active\n"); ++ return ret; ++ } ++ ++ ret = clk_prepare_enable(dispc->fclk); ++ if (ret) { ++ dev_err(dev, "Failed to enable DSS fclk\n"); ++ goto err_runtime_suspend; ++ } ++ ++ ret = dispc_softreset(dispc); + if (ret) +- dev_warn(dispc->dev, "failed to reset dispc\n"); ++ goto err_clk_disable; ++ ++ clk_disable_unprepare(dispc->fclk); ++ ret = pm_runtime_set_suspended(dev); ++ if (ret) { ++ dev_err(dev, "Failed to set DSS PM to suspended\n"); ++ return ret; ++ } ++ ++ return 0; ++ ++err_clk_disable: ++ clk_disable_unprepare(dispc->fclk); ++ ++err_runtime_suspend: ++ ret = pm_runtime_set_suspended(dev); ++ if (ret) { ++ dev_err(dev, "Failed to set DSS PM to suspended\n"); ++ return ret; ++ } ++ ++ return ret; + } + + int dispc_init(struct tidss_device *tidss) +@@ -2726,10 +2777,6 @@ int dispc_init(struct tidss_device *tidss) + return r; + } + +- /* K2G display controller does not support soft reset */ +- if (feat->subrev != DISPC_K2G) +- dispc_softreset(dispc); +- + for (i = 0; i < dispc->feat->num_vps; i++) { + u32 gamma_size = dispc->feat->vp_feat.color.gamma_size; + u32 *gamma_table; +@@ -2778,6 +2825,10 @@ int dispc_init(struct tidss_device *tidss) + of_property_read_u32(dispc->dev->of_node, "max-memory-bandwidth", + &dispc->memory_bandwidth_limit); + ++ r = dispc_init_hw(dispc); ++ if (r) ++ return r; ++ + tidss->dispc = dispc; + + return 0; +diff --git a/drivers/gpu/drm/tidss/tidss_kms.c b/drivers/gpu/drm/tidss/tidss_kms.c +index afb2879980c6c..995bac488392a 100644 +--- a/drivers/gpu/drm/tidss/tidss_kms.c ++++ b/drivers/gpu/drm/tidss/tidss_kms.c +@@ -4,8 +4,6 @@ + * Author: Tomi Valkeinen <tomi.valkeinen@ti.com> + */ + +-#include <linux/dma-fence.h> +- + #include <drm/drm_atomic.h> + #include <drm/drm_atomic_helper.h> + #include <drm/drm_bridge.h> +@@ -27,7 +25,6 @@ static void tidss_atomic_commit_tail(struct drm_atomic_state *old_state) + { + struct drm_device *ddev = old_state->dev; + struct tidss_device *tidss = to_tidss(ddev); +- bool fence_cookie = dma_fence_begin_signalling(); + + dev_dbg(ddev->dev, "%s\n", __func__); + +@@ -38,7 +35,6 @@ static void tidss_atomic_commit_tail(struct drm_atomic_state *old_state) + drm_atomic_helper_commit_modeset_enables(ddev, old_state); + + drm_atomic_helper_commit_hw_done(old_state); +- dma_fence_end_signalling(fence_cookie); + drm_atomic_helper_wait_for_flip_done(ddev, old_state); + + drm_atomic_helper_cleanup_planes(ddev, old_state); +diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c +index f72755b8ea14c..86d34b77b37db 100644 +--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c ++++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c +@@ -138,7 +138,7 @@ static int tilcdc_irq_install(struct drm_device *dev, unsigned int irq) + if (ret) + return ret; + +- priv->irq_enabled = false; ++ priv->irq_enabled = true; + + return 0; + } +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c +index ae01d22b8f840..c46f380d91499 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c +@@ -595,10 +595,9 @@ static int vmw_user_bo_synccpu_release(struct drm_file *filp, + if (!(flags & drm_vmw_synccpu_allow_cs)) { + atomic_dec(&vmw_bo->cpu_writers); + } +- ttm_bo_put(&vmw_bo->base); ++ vmw_user_bo_unref(&vmw_bo); + } + +- drm_gem_object_put(&vmw_bo->base.base); + return ret; + } + +@@ -638,8 +637,7 @@ int vmw_user_bo_synccpu_ioctl(struct drm_device *dev, void *data, + return ret; + + ret = vmw_user_bo_synccpu_grab(vbo, arg->flags); +- vmw_bo_unreference(&vbo); +- drm_gem_object_put(&vbo->base.base); ++ vmw_user_bo_unref(&vbo); + if (unlikely(ret != 0)) { + if (ret == -ERESTARTSYS || ret == -EBUSY) + return -EBUSY; +@@ -713,7 +711,6 @@ int vmw_user_bo_lookup(struct drm_file *filp, + } + + *out = gem_to_vmw_bo(gobj); +- ttm_bo_get(&(*out)->base); + + return 0; + } +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c +index 79b30dc9d8253..97e56a94eaf80 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c +@@ -407,8 +407,8 @@ static int vmw_cotable_resize(struct vmw_resource *res, size_t new_size) + * for the new COTable. Initially pin the buffer object to make sure + * we can use tryreserve without failure. + */ +- ret = vmw_bo_create(dev_priv, new_size, &vmw_mob_placement, +- true, true, vmw_bo_bo_free, &buf); ++ ret = vmw_gem_object_create(dev_priv, new_size, &vmw_mob_placement, ++ true, true, vmw_bo_bo_free, &buf); + if (ret) { + DRM_ERROR("Failed initializing new cotable MOB.\n"); + return ret; +@@ -475,7 +475,7 @@ static int vmw_cotable_resize(struct vmw_resource *res, size_t new_size) + + vmw_resource_mob_attach(res); + /* Let go of the old mob. */ +- vmw_bo_unreference(&old_buf); ++ vmw_user_bo_unref(&old_buf); + res->id = vcotbl->type; + + ret = dma_resv_reserve_fences(bo->base.resv, 1); +@@ -492,7 +492,7 @@ out_map_new: + out_wait: + ttm_bo_unpin(bo); + ttm_bo_unreserve(bo); +- vmw_bo_unreference(&buf); ++ vmw_user_bo_unref(&buf); + + return ret; + } +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +index 8459fab9d9797..136f1cdcf8cdf 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +@@ -969,6 +969,11 @@ static inline void vmw_bo_prio_del(struct vmw_buffer_object *vbo, int prio) + /** + * GEM related functionality - vmwgfx_gem.c + */ ++extern int vmw_gem_object_create(struct vmw_private *dev_priv, ++ size_t size, struct ttm_placement *placement, ++ bool interruptible, bool pin, ++ void (*bo_free)(struct ttm_buffer_object *bo), ++ struct vmw_buffer_object **p_bo); + extern int vmw_gem_object_create_with_handle(struct vmw_private *dev_priv, + struct drm_file *filp, + uint32_t size, +@@ -1600,6 +1605,21 @@ vmw_bo_reference(struct vmw_buffer_object *buf) + return buf; + } + ++static inline struct vmw_buffer_object *vmw_user_bo_ref(struct vmw_buffer_object *vbo) ++{ ++ drm_gem_object_get(&vbo->base.base); ++ return vbo; ++} ++ ++static inline void vmw_user_bo_unref(struct vmw_buffer_object **buf) ++{ ++ struct vmw_buffer_object *tmp_buf = *buf; ++ ++ *buf = NULL; ++ if (tmp_buf) ++ drm_gem_object_put(&tmp_buf->base.base); ++} ++ + static inline void vmw_fifo_resource_inc(struct vmw_private *dev_priv) + { + atomic_inc(&dev_priv->num_fifo_resources); +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +index 7e59469e1cb9f..bc7f02e4ecebb 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +@@ -1147,7 +1147,7 @@ static int vmw_translate_mob_ptr(struct vmw_private *dev_priv, + SVGAMobId *id, + struct vmw_buffer_object **vmw_bo_p) + { +- struct vmw_buffer_object *vmw_bo; ++ struct vmw_buffer_object *vmw_bo, *tmp_bo; + uint32_t handle = *id; + struct vmw_relocation *reloc; + int ret; +@@ -1159,8 +1159,8 @@ static int vmw_translate_mob_ptr(struct vmw_private *dev_priv, + return PTR_ERR(vmw_bo); + } + ret = vmw_validation_add_bo(sw_context->ctx, vmw_bo, true, false); +- ttm_bo_put(&vmw_bo->base); +- drm_gem_object_put(&vmw_bo->base.base); ++ tmp_bo = vmw_bo; ++ vmw_user_bo_unref(&tmp_bo); + if (unlikely(ret != 0)) + return ret; + +@@ -1202,7 +1202,7 @@ static int vmw_translate_guest_ptr(struct vmw_private *dev_priv, + SVGAGuestPtr *ptr, + struct vmw_buffer_object **vmw_bo_p) + { +- struct vmw_buffer_object *vmw_bo; ++ struct vmw_buffer_object *vmw_bo, *tmp_bo; + uint32_t handle = ptr->gmrId; + struct vmw_relocation *reloc; + int ret; +@@ -1214,8 +1214,8 @@ static int vmw_translate_guest_ptr(struct vmw_private *dev_priv, + return PTR_ERR(vmw_bo); + } + ret = vmw_validation_add_bo(sw_context->ctx, vmw_bo, false, false); +- ttm_bo_put(&vmw_bo->base); +- drm_gem_object_put(&vmw_bo->base.base); ++ tmp_bo = vmw_bo; ++ vmw_user_bo_unref(&tmp_bo); + if (unlikely(ret != 0)) + return ret; + +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c b/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c +index 4d2c28e39f4e0..e7a533e39155c 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c +@@ -133,6 +133,22 @@ void vmw_gem_destroy(struct ttm_buffer_object *bo) + kfree(vbo); + } + ++int vmw_gem_object_create(struct vmw_private *vmw, ++ size_t size, struct ttm_placement *placement, ++ bool interruptible, bool pin, ++ void (*bo_free)(struct ttm_buffer_object *bo), ++ struct vmw_buffer_object **p_bo) ++{ ++ int ret = vmw_bo_create(vmw, size, placement, interruptible, pin, bo_free, p_bo); ++ ++ if (ret != 0) ++ goto out_no_bo; ++ ++ (*p_bo)->base.base.funcs = &vmw_gem_object_funcs; ++out_no_bo: ++ return ret; ++} ++ + int vmw_gem_object_create_with_handle(struct vmw_private *dev_priv, + struct drm_file *filp, + uint32_t size, +@@ -141,16 +157,14 @@ int vmw_gem_object_create_with_handle(struct vmw_private *dev_priv, + { + int ret; + +- ret = vmw_bo_create(dev_priv, size, +- (dev_priv->has_mob) ? ++ ret = vmw_gem_object_create(dev_priv, size, ++ (dev_priv->has_mob) ? + &vmw_sys_placement : + &vmw_vram_sys_placement, +- true, false, &vmw_gem_destroy, p_vbo); ++ true, false, &vmw_gem_destroy, p_vbo); + if (ret != 0) + goto out_no_bo; + +- (*p_vbo)->base.base.funcs = &vmw_gem_object_funcs; +- + ret = drm_gem_handle_create(filp, &(*p_vbo)->base.base, handle); + out_no_bo: + return ret; +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +index aab6389cb4aab..aa571b75cd07f 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +@@ -1402,8 +1402,8 @@ static int vmw_create_bo_proxy(struct drm_device *dev, + /* Reserve and switch the backing mob. */ + mutex_lock(&res->dev_priv->cmdbuf_mutex); + (void) vmw_resource_reserve(res, false, true); +- vmw_bo_unreference(&res->backup); +- res->backup = vmw_bo_reference(bo_mob); ++ vmw_user_bo_unref(&res->backup); ++ res->backup = vmw_user_bo_ref(bo_mob); + res->backup_offset = 0; + vmw_resource_unreserve(res, false, false, false, NULL, 0); + mutex_unlock(&res->dev_priv->cmdbuf_mutex); +@@ -1599,10 +1599,8 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev, + + err_out: + /* vmw_user_lookup_handle takes one ref so does new_fb */ +- if (bo) { +- vmw_bo_unreference(&bo); +- drm_gem_object_put(&bo->base.base); +- } ++ if (bo) ++ vmw_user_bo_unref(&bo); + if (surface) + vmw_surface_unreference(&surface); + +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c b/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c +index b5b311f2a91a4..abc354ead4e8b 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c +@@ -457,8 +457,7 @@ int vmw_overlay_ioctl(struct drm_device *dev, void *data, + + ret = vmw_overlay_update_stream(dev_priv, buf, arg, true); + +- vmw_bo_unreference(&buf); +- drm_gem_object_put(&buf->base.base); ++ vmw_user_bo_unref(&buf); + + out_unlock: + mutex_unlock(&overlay->mutex); +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +index c7d645e5ec7bf..30d1c1918bb48 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +@@ -140,7 +140,7 @@ static void vmw_resource_release(struct kref *kref) + if (res->coherent) + vmw_bo_dirty_release(res->backup); + ttm_bo_unreserve(bo); +- vmw_bo_unreference(&res->backup); ++ vmw_user_bo_unref(&res->backup); + } + + if (likely(res->hw_destroy != NULL)) { +@@ -330,10 +330,10 @@ static int vmw_resource_buf_alloc(struct vmw_resource *res, + return 0; + } + +- ret = vmw_bo_create(res->dev_priv, res->backup_size, +- res->func->backup_placement, +- interruptible, false, +- &vmw_bo_bo_free, &backup); ++ ret = vmw_gem_object_create(res->dev_priv, res->backup_size, ++ res->func->backup_placement, ++ interruptible, false, ++ &vmw_bo_bo_free, &backup); + if (unlikely(ret != 0)) + goto out_no_bo; + +@@ -452,11 +452,11 @@ void vmw_resource_unreserve(struct vmw_resource *res, + vmw_resource_mob_detach(res); + if (res->coherent) + vmw_bo_dirty_release(res->backup); +- vmw_bo_unreference(&res->backup); ++ vmw_user_bo_unref(&res->backup); + } + + if (new_backup) { +- res->backup = vmw_bo_reference(new_backup); ++ res->backup = vmw_user_bo_ref(new_backup); + + /* + * The validation code should already have added a +@@ -544,7 +544,7 @@ out_no_reserve: + ttm_bo_put(val_buf->bo); + val_buf->bo = NULL; + if (backup_dirty) +- vmw_bo_unreference(&res->backup); ++ vmw_user_bo_unref(&res->backup); + + return ret; + } +@@ -719,7 +719,7 @@ int vmw_resource_validate(struct vmw_resource *res, bool intr, + goto out_no_validate; + else if (!res->func->needs_backup && res->backup) { + WARN_ON_ONCE(vmw_resource_mob_attached(res)); +- vmw_bo_unreference(&res->backup); ++ vmw_user_bo_unref(&res->backup); + } + + return 0; +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c +index 51e83dfa1cace..303f7a82f3509 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c +@@ -177,7 +177,7 @@ static int vmw_gb_shader_init(struct vmw_private *dev_priv, + + res->backup_size = size; + if (byte_code) { +- res->backup = vmw_bo_reference(byte_code); ++ res->backup = vmw_user_bo_ref(byte_code); + res->backup_offset = offset; + } + shader->size = size; +@@ -806,8 +806,7 @@ static int vmw_shader_define(struct drm_device *dev, struct drm_file *file_priv, + shader_type, num_input_sig, + num_output_sig, tfile, shader_handle); + out_bad_arg: +- vmw_bo_unreference(&buffer); +- drm_gem_object_put(&buffer->base.base); ++ vmw_user_bo_unref(&buffer); + return ret; + } + +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +index 1a1a286bc749f..50769528c3f3c 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +@@ -683,9 +683,6 @@ static void vmw_user_surface_base_release(struct ttm_base_object **p_base) + container_of(base, struct vmw_user_surface, prime.base); + struct vmw_resource *res = &user_srf->srf.res; + +- if (res && res->backup) +- drm_gem_object_put(&res->backup->base.base); +- + *p_base = NULL; + vmw_resource_unreference(&res); + } +@@ -848,23 +845,17 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, + * expect a backup buffer to be present. + */ + if (dev_priv->has_mob && req->shareable) { +- uint32_t backup_handle; +- +- ret = vmw_gem_object_create_with_handle(dev_priv, +- file_priv, +- res->backup_size, +- &backup_handle, +- &res->backup); ++ ret = vmw_gem_object_create(dev_priv, ++ res->backup_size, ++ &vmw_sys_placement, ++ true, ++ false, ++ &vmw_gem_destroy, ++ &res->backup); + if (unlikely(ret != 0)) { + vmw_resource_unreference(&res); + goto out_unlock; + } +- vmw_bo_reference(res->backup); +- /* +- * We don't expose the handle to the userspace and surface +- * already holds a gem reference +- */ +- drm_gem_handle_delete(file_priv, backup_handle); + } + + tmp = vmw_resource_reference(&srf->res); +@@ -1505,7 +1496,7 @@ vmw_gb_surface_define_internal(struct drm_device *dev, + if (ret == 0) { + if (res->backup->base.base.size < res->backup_size) { + VMW_DEBUG_USER("Surface backup buffer too small.\n"); +- vmw_bo_unreference(&res->backup); ++ vmw_user_bo_unref(&res->backup); + ret = -EINVAL; + goto out_unlock; + } else { +@@ -1519,8 +1510,6 @@ vmw_gb_surface_define_internal(struct drm_device *dev, + res->backup_size, + &backup_handle, + &res->backup); +- if (ret == 0) +- vmw_bo_reference(res->backup); + } + + if (unlikely(ret != 0)) { +diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c +index c1270db121784..165ed872fa4e7 100644 +--- a/drivers/hid/wacom_wac.c ++++ b/drivers/hid/wacom_wac.c +@@ -2646,8 +2646,8 @@ static void wacom_wac_finger_slot(struct wacom_wac *wacom_wac, + { + struct hid_data *hid_data = &wacom_wac->hid_data; + bool mt = wacom_wac->features.touch_max > 1; +- bool prox = hid_data->tipswitch && +- report_touch_events(wacom_wac); ++ bool touch_down = hid_data->tipswitch && hid_data->confidence; ++ bool prox = touch_down && report_touch_events(wacom_wac); + + if (touch_is_muted(wacom_wac)) { + if (!wacom_wac->shared->touch_down) +@@ -2697,24 +2697,6 @@ static void wacom_wac_finger_slot(struct wacom_wac *wacom_wac, + } + } + +-static bool wacom_wac_slot_is_active(struct input_dev *dev, int key) +-{ +- struct input_mt *mt = dev->mt; +- struct input_mt_slot *s; +- +- if (!mt) +- return false; +- +- for (s = mt->slots; s != mt->slots + mt->num_slots; s++) { +- if (s->key == key && +- input_mt_get_value(s, ABS_MT_TRACKING_ID) >= 0) { +- return true; +- } +- } +- +- return false; +-} +- + static void wacom_wac_finger_event(struct hid_device *hdev, + struct hid_field *field, struct hid_usage *usage, __s32 value) + { +@@ -2765,14 +2747,8 @@ static void wacom_wac_finger_event(struct hid_device *hdev, + } + + if (usage->usage_index + 1 == field->report_count) { +- if (equivalent_usage == wacom_wac->hid_data.last_slot_field) { +- bool touch_removed = wacom_wac_slot_is_active(wacom_wac->touch_input, +- wacom_wac->hid_data.id) && !wacom_wac->hid_data.tipswitch; +- +- if (wacom_wac->hid_data.confidence || touch_removed) { +- wacom_wac_finger_slot(wacom_wac, wacom_wac->touch_input); +- } +- } ++ if (equivalent_usage == wacom_wac->hid_data.last_slot_field) ++ wacom_wac_finger_slot(wacom_wac, wacom_wac->touch_input); + } + } + +diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c +index 36dab9cd208cf..8e3838c42a8c2 100644 +--- a/drivers/i2c/busses/i2c-s3c2410.c ++++ b/drivers/i2c/busses/i2c-s3c2410.c +@@ -220,8 +220,17 @@ static bool is_ack(struct s3c24xx_i2c *i2c) + int tries; + + for (tries = 50; tries; --tries) { +- if (readl(i2c->regs + S3C2410_IICCON) +- & S3C2410_IICCON_IRQPEND) { ++ unsigned long tmp = readl(i2c->regs + S3C2410_IICCON); ++ ++ if (!(tmp & S3C2410_IICCON_ACKEN)) { ++ /* ++ * Wait a bit for the bus to stabilize, ++ * delay estimated experimentally. ++ */ ++ usleep_range(100, 200); ++ return true; ++ } ++ if (tmp & S3C2410_IICCON_IRQPEND) { + if (!(readl(i2c->regs + S3C2410_IICSTAT) + & S3C2410_IICSTAT_LASTBIT)) + return true; +@@ -274,16 +283,6 @@ static void s3c24xx_i2c_message_start(struct s3c24xx_i2c *i2c, + + stat |= S3C2410_IICSTAT_START; + writel(stat, i2c->regs + S3C2410_IICSTAT); +- +- if (i2c->quirks & QUIRK_POLL) { +- while ((i2c->msg_num != 0) && is_ack(i2c)) { +- i2c_s3c_irq_nextbyte(i2c, stat); +- stat = readl(i2c->regs + S3C2410_IICSTAT); +- +- if (stat & S3C2410_IICSTAT_ARBITR) +- dev_err(i2c->dev, "deal with arbitration loss\n"); +- } +- } + } + + static inline void s3c24xx_i2c_stop(struct s3c24xx_i2c *i2c, int ret) +@@ -690,7 +689,7 @@ static void s3c24xx_i2c_wait_idle(struct s3c24xx_i2c *i2c) + static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c, + struct i2c_msg *msgs, int num) + { +- unsigned long timeout; ++ unsigned long timeout = 0; + int ret; + + ret = s3c24xx_i2c_set_master(i2c); +@@ -710,16 +709,19 @@ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c, + s3c24xx_i2c_message_start(i2c, msgs); + + if (i2c->quirks & QUIRK_POLL) { +- ret = i2c->msg_idx; ++ while ((i2c->msg_num != 0) && is_ack(i2c)) { ++ unsigned long stat = readl(i2c->regs + S3C2410_IICSTAT); + +- if (ret != num) +- dev_dbg(i2c->dev, "incomplete xfer (%d)\n", ret); ++ i2c_s3c_irq_nextbyte(i2c, stat); + +- goto out; ++ stat = readl(i2c->regs + S3C2410_IICSTAT); ++ if (stat & S3C2410_IICSTAT_ARBITR) ++ dev_err(i2c->dev, "deal with arbitration loss\n"); ++ } ++ } else { ++ timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5); + } + +- timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5); +- + ret = i2c->msg_idx; + + /* +diff --git a/drivers/iio/adc/ad7091r-base.c b/drivers/iio/adc/ad7091r-base.c +index 8e252cde735b9..0e5d3d2e9c985 100644 +--- a/drivers/iio/adc/ad7091r-base.c ++++ b/drivers/iio/adc/ad7091r-base.c +@@ -174,8 +174,8 @@ static const struct iio_info ad7091r_info = { + + static irqreturn_t ad7091r_event_handler(int irq, void *private) + { +- struct ad7091r_state *st = (struct ad7091r_state *) private; +- struct iio_dev *iio_dev = dev_get_drvdata(st->dev); ++ struct iio_dev *iio_dev = private; ++ struct ad7091r_state *st = iio_priv(iio_dev); + unsigned int i, read_val; + int ret; + s64 timestamp = iio_get_time_ns(iio_dev); +@@ -234,7 +234,7 @@ int ad7091r_probe(struct device *dev, const char *name, + if (irq) { + ret = devm_request_threaded_irq(dev, irq, NULL, + ad7091r_event_handler, +- IRQF_TRIGGER_FALLING | IRQF_ONESHOT, name, st); ++ IRQF_TRIGGER_FALLING | IRQF_ONESHOT, name, iio_dev); + if (ret) + return ret; + } +diff --git a/drivers/iio/adc/ad9467.c b/drivers/iio/adc/ad9467.c +index 7534572f74757..811525857d29f 100644 +--- a/drivers/iio/adc/ad9467.c ++++ b/drivers/iio/adc/ad9467.c +@@ -119,9 +119,9 @@ struct ad9467_state { + struct spi_device *spi; + struct clk *clk; + unsigned int output_mode; ++ unsigned int (*scales)[2]; + + struct gpio_desc *pwrdown_gpio; +- struct gpio_desc *reset_gpio; + }; + + static int ad9467_spi_read(struct spi_device *spi, unsigned int reg) +@@ -163,9 +163,10 @@ static int ad9467_reg_access(struct adi_axi_adc_conv *conv, unsigned int reg, + + if (readval == NULL) { + ret = ad9467_spi_write(spi, reg, writeval); +- ad9467_spi_write(spi, AN877_ADC_REG_TRANSFER, +- AN877_ADC_TRANSFER_SYNC); +- return ret; ++ if (ret) ++ return ret; ++ return ad9467_spi_write(spi, AN877_ADC_REG_TRANSFER, ++ AN877_ADC_TRANSFER_SYNC); + } + + ret = ad9467_spi_read(spi, reg); +@@ -212,6 +213,7 @@ static void __ad9467_get_scale(struct adi_axi_adc_conv *conv, int index, + .channel = _chan, \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ ++ .info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_SCALE), \ + .scan_index = _si, \ + .scan_type = { \ + .sign = _sign, \ +@@ -273,10 +275,13 @@ static int ad9467_get_scale(struct adi_axi_adc_conv *conv, int *val, int *val2) + const struct ad9467_chip_info *info1 = to_ad9467_chip_info(info); + struct ad9467_state *st = adi_axi_adc_conv_priv(conv); + unsigned int i, vref_val; ++ int ret; + +- vref_val = ad9467_spi_read(st->spi, AN877_ADC_REG_VREF); ++ ret = ad9467_spi_read(st->spi, AN877_ADC_REG_VREF); ++ if (ret < 0) ++ return ret; + +- vref_val &= info1->vref_mask; ++ vref_val = ret & info1->vref_mask; + + for (i = 0; i < info->num_scales; i++) { + if (vref_val == info->scale_table[i][1]) +@@ -297,6 +302,7 @@ static int ad9467_set_scale(struct adi_axi_adc_conv *conv, int val, int val2) + struct ad9467_state *st = adi_axi_adc_conv_priv(conv); + unsigned int scale_val[2]; + unsigned int i; ++ int ret; + + if (val != 0) + return -EINVAL; +@@ -306,11 +312,13 @@ static int ad9467_set_scale(struct adi_axi_adc_conv *conv, int val, int val2) + if (scale_val[0] != val || scale_val[1] != val2) + continue; + +- ad9467_spi_write(st->spi, AN877_ADC_REG_VREF, +- info->scale_table[i][1]); +- ad9467_spi_write(st->spi, AN877_ADC_REG_TRANSFER, +- AN877_ADC_TRANSFER_SYNC); +- return 0; ++ ret = ad9467_spi_write(st->spi, AN877_ADC_REG_VREF, ++ info->scale_table[i][1]); ++ if (ret < 0) ++ return ret; ++ ++ return ad9467_spi_write(st->spi, AN877_ADC_REG_TRANSFER, ++ AN877_ADC_TRANSFER_SYNC); + } + + return -EINVAL; +@@ -359,6 +367,26 @@ static int ad9467_write_raw(struct adi_axi_adc_conv *conv, + } + } + ++static int ad9467_read_avail(struct adi_axi_adc_conv *conv, ++ struct iio_chan_spec const *chan, ++ const int **vals, int *type, int *length, ++ long mask) ++{ ++ const struct adi_axi_adc_chip_info *info = conv->chip_info; ++ struct ad9467_state *st = adi_axi_adc_conv_priv(conv); ++ ++ switch (mask) { ++ case IIO_CHAN_INFO_SCALE: ++ *vals = (const int *)st->scales; ++ *type = IIO_VAL_INT_PLUS_MICRO; ++ /* Values are stored in a 2D matrix */ ++ *length = info->num_scales * 2; ++ return IIO_AVAIL_LIST; ++ default: ++ return -EINVAL; ++ } ++} ++ + static int ad9467_outputmode_set(struct spi_device *spi, unsigned int mode) + { + int ret; +@@ -371,6 +399,26 @@ static int ad9467_outputmode_set(struct spi_device *spi, unsigned int mode) + AN877_ADC_TRANSFER_SYNC); + } + ++static int ad9467_scale_fill(struct adi_axi_adc_conv *conv) ++{ ++ const struct adi_axi_adc_chip_info *info = conv->chip_info; ++ struct ad9467_state *st = adi_axi_adc_conv_priv(conv); ++ unsigned int i, val1, val2; ++ ++ st->scales = devm_kmalloc_array(&st->spi->dev, info->num_scales, ++ sizeof(*st->scales), GFP_KERNEL); ++ if (!st->scales) ++ return -ENOMEM; ++ ++ for (i = 0; i < info->num_scales; i++) { ++ __ad9467_get_scale(conv, i, &val1, &val2); ++ st->scales[i][0] = val1; ++ st->scales[i][1] = val2; ++ } ++ ++ return 0; ++} ++ + static int ad9467_preenable_setup(struct adi_axi_adc_conv *conv) + { + struct ad9467_state *st = adi_axi_adc_conv_priv(conv); +@@ -378,6 +426,21 @@ static int ad9467_preenable_setup(struct adi_axi_adc_conv *conv) + return ad9467_outputmode_set(st->spi, st->output_mode); + } + ++static int ad9467_reset(struct device *dev) ++{ ++ struct gpio_desc *gpio; ++ ++ gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); ++ if (IS_ERR_OR_NULL(gpio)) ++ return PTR_ERR_OR_ZERO(gpio); ++ ++ fsleep(1); ++ gpiod_set_value_cansleep(gpio, 0); ++ fsleep(10 * USEC_PER_MSEC); ++ ++ return 0; ++} ++ + static int ad9467_probe(struct spi_device *spi) + { + const struct ad9467_chip_info *info; +@@ -406,21 +469,16 @@ static int ad9467_probe(struct spi_device *spi) + if (IS_ERR(st->pwrdown_gpio)) + return PTR_ERR(st->pwrdown_gpio); + +- st->reset_gpio = devm_gpiod_get_optional(&spi->dev, "reset", +- GPIOD_OUT_LOW); +- if (IS_ERR(st->reset_gpio)) +- return PTR_ERR(st->reset_gpio); +- +- if (st->reset_gpio) { +- udelay(1); +- ret = gpiod_direction_output(st->reset_gpio, 1); +- if (ret) +- return ret; +- mdelay(10); +- } ++ ret = ad9467_reset(&spi->dev); ++ if (ret) ++ return ret; + + conv->chip_info = &info->axi_adc_info; + ++ ret = ad9467_scale_fill(conv); ++ if (ret) ++ return ret; ++ + id = ad9467_spi_read(spi, AN877_ADC_REG_CHIP_ID); + if (id != conv->chip_info->id) { + dev_err(&spi->dev, "Mismatch CHIP_ID, got 0x%X, expected 0x%X\n", +@@ -431,6 +489,7 @@ static int ad9467_probe(struct spi_device *spi) + conv->reg_access = ad9467_reg_access; + conv->write_raw = ad9467_write_raw; + conv->read_raw = ad9467_read_raw; ++ conv->read_avail = ad9467_read_avail; + conv->preenable_setup = ad9467_preenable_setup; + + st->output_mode = info->default_output_mode | +diff --git a/drivers/iio/adc/adi-axi-adc.c b/drivers/iio/adc/adi-axi-adc.c +index e8a8ea4140f16..ad386ac7f03cb 100644 +--- a/drivers/iio/adc/adi-axi-adc.c ++++ b/drivers/iio/adc/adi-axi-adc.c +@@ -143,6 +143,20 @@ static int adi_axi_adc_write_raw(struct iio_dev *indio_dev, + return conv->write_raw(conv, chan, val, val2, mask); + } + ++static int adi_axi_adc_read_avail(struct iio_dev *indio_dev, ++ struct iio_chan_spec const *chan, ++ const int **vals, int *type, int *length, ++ long mask) ++{ ++ struct adi_axi_adc_state *st = iio_priv(indio_dev); ++ struct adi_axi_adc_conv *conv = &st->client->conv; ++ ++ if (!conv->read_avail) ++ return -EOPNOTSUPP; ++ ++ return conv->read_avail(conv, chan, vals, type, length, mask); ++} ++ + static int adi_axi_adc_update_scan_mode(struct iio_dev *indio_dev, + const unsigned long *scan_mask) + { +@@ -227,69 +241,11 @@ struct adi_axi_adc_conv *devm_adi_axi_adc_conv_register(struct device *dev, + } + EXPORT_SYMBOL_NS_GPL(devm_adi_axi_adc_conv_register, IIO_ADI_AXI); + +-static ssize_t in_voltage_scale_available_show(struct device *dev, +- struct device_attribute *attr, +- char *buf) +-{ +- struct iio_dev *indio_dev = dev_to_iio_dev(dev); +- struct adi_axi_adc_state *st = iio_priv(indio_dev); +- struct adi_axi_adc_conv *conv = &st->client->conv; +- size_t len = 0; +- int i; +- +- for (i = 0; i < conv->chip_info->num_scales; i++) { +- const unsigned int *s = conv->chip_info->scale_table[i]; +- +- len += scnprintf(buf + len, PAGE_SIZE - len, +- "%u.%06u ", s[0], s[1]); +- } +- buf[len - 1] = '\n'; +- +- return len; +-} +- +-static IIO_DEVICE_ATTR_RO(in_voltage_scale_available, 0); +- +-enum { +- ADI_AXI_ATTR_SCALE_AVAIL, +-}; +- +-#define ADI_AXI_ATTR(_en_, _file_) \ +- [ADI_AXI_ATTR_##_en_] = &iio_dev_attr_##_file_.dev_attr.attr +- +-static struct attribute *adi_axi_adc_attributes[] = { +- ADI_AXI_ATTR(SCALE_AVAIL, in_voltage_scale_available), +- NULL +-}; +- +-static umode_t axi_adc_attr_is_visible(struct kobject *kobj, +- struct attribute *attr, int n) +-{ +- struct device *dev = kobj_to_dev(kobj); +- struct iio_dev *indio_dev = dev_to_iio_dev(dev); +- struct adi_axi_adc_state *st = iio_priv(indio_dev); +- struct adi_axi_adc_conv *conv = &st->client->conv; +- +- switch (n) { +- case ADI_AXI_ATTR_SCALE_AVAIL: +- if (!conv->chip_info->num_scales) +- return 0; +- return attr->mode; +- default: +- return attr->mode; +- } +-} +- +-static const struct attribute_group adi_axi_adc_attribute_group = { +- .attrs = adi_axi_adc_attributes, +- .is_visible = axi_adc_attr_is_visible, +-}; +- + static const struct iio_info adi_axi_adc_info = { + .read_raw = &adi_axi_adc_read_raw, + .write_raw = &adi_axi_adc_write_raw, +- .attrs = &adi_axi_adc_attribute_group, + .update_scan_mode = &adi_axi_adc_update_scan_mode, ++ .read_avail = &adi_axi_adc_read_avail, + }; + + static const struct adi_axi_adc_core_info adi_axi_adc_10_0_a_info = { +diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +index c2ee80546d120..58fbb1d3b7f41 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c ++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +@@ -2819,6 +2819,10 @@ static int free_mr_alloc_res(struct hns_roce_dev *hr_dev) + return 0; + + create_failed_qp: ++ for (i--; i >= 0; i--) { ++ hns_roce_v2_destroy_qp(&free_mr->rsv_qp[i]->ibqp, NULL); ++ kfree(free_mr->rsv_qp[i]); ++ } + hns_roce_destroy_cq(cq, NULL); + kfree(cq); + +@@ -5791,7 +5795,7 @@ static int hns_roce_v2_modify_srq(struct ib_srq *ibsrq, + + /* Resizing SRQs is not supported yet */ + if (srq_attr_mask & IB_SRQ_MAX_WR) +- return -EINVAL; ++ return -EOPNOTSUPP; + + if (srq_attr_mask & IB_SRQ_LIMIT) { + if (srq_attr->srq_limit > srq->wqe_cnt) +diff --git a/drivers/infiniband/hw/hns/hns_roce_pd.c b/drivers/infiniband/hw/hns/hns_roce_pd.c +index 783e71852c503..bd1fe89ca205e 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_pd.c ++++ b/drivers/infiniband/hw/hns/hns_roce_pd.c +@@ -150,7 +150,7 @@ int hns_roce_alloc_xrcd(struct ib_xrcd *ib_xrcd, struct ib_udata *udata) + int ret; + + if (!(hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_XRC)) +- return -EINVAL; ++ return -EOPNOTSUPP; + + ret = hns_roce_xrcd_alloc(hr_dev, &xrcd->xrcdn); + if (ret) +diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c +index f330ce895d884..8fe0cef7e2be6 100644 +--- a/drivers/infiniband/hw/mthca/mthca_cmd.c ++++ b/drivers/infiniband/hw/mthca/mthca_cmd.c +@@ -635,7 +635,7 @@ void mthca_free_mailbox(struct mthca_dev *dev, struct mthca_mailbox *mailbox) + + int mthca_SYS_EN(struct mthca_dev *dev) + { +- u64 out; ++ u64 out = 0; + int ret; + + ret = mthca_cmd_imm(dev, 0, &out, 0, 0, CMD_SYS_EN, CMD_TIME_CLASS_D); +@@ -1955,7 +1955,7 @@ int mthca_WRITE_MGM(struct mthca_dev *dev, int index, + int mthca_MGID_HASH(struct mthca_dev *dev, struct mthca_mailbox *mailbox, + u16 *hash) + { +- u64 imm; ++ u64 imm = 0; + int err; + + err = mthca_cmd_imm(dev, mailbox->dma, &imm, 0, 0, CMD_MGID_HASH, +diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c +index b54bc8865daec..1ab268b770968 100644 +--- a/drivers/infiniband/hw/mthca/mthca_main.c ++++ b/drivers/infiniband/hw/mthca/mthca_main.c +@@ -382,7 +382,7 @@ static int mthca_init_icm(struct mthca_dev *mdev, + struct mthca_init_hca_param *init_hca, + u64 icm_size) + { +- u64 aux_pages; ++ u64 aux_pages = 0; + int err; + + err = mthca_SET_ICM_SIZE(mdev, icm_size, &aux_pages); +diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h +index dee8c97ff0568..d967d55324596 100644 +--- a/drivers/infiniband/ulp/iser/iscsi_iser.h ++++ b/drivers/infiniband/ulp/iser/iscsi_iser.h +@@ -317,12 +317,10 @@ struct iser_device { + * + * @mr: memory region + * @sig_mr: signature memory region +- * @mr_valid: is mr valid indicator + */ + struct iser_reg_resources { + struct ib_mr *mr; + struct ib_mr *sig_mr; +- u8 mr_valid:1; + }; + + /** +diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c +index 7b83f48f60c5e..8ec470c519e82 100644 +--- a/drivers/infiniband/ulp/iser/iser_initiator.c ++++ b/drivers/infiniband/ulp/iser/iser_initiator.c +@@ -580,7 +580,10 @@ static inline int iser_inv_desc(struct iser_fr_desc *desc, u32 rkey) + return -EINVAL; + } + +- desc->rsc.mr_valid = 0; ++ if (desc->sig_protected) ++ desc->rsc.sig_mr->need_inval = false; ++ else ++ desc->rsc.mr->need_inval = false; + + return 0; + } +diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c +index 29ae2c6a250a3..6efcb79c8efe3 100644 +--- a/drivers/infiniband/ulp/iser/iser_memory.c ++++ b/drivers/infiniband/ulp/iser/iser_memory.c +@@ -264,7 +264,7 @@ static int iser_reg_sig_mr(struct iscsi_iser_task *iser_task, + + iser_set_prot_checks(iser_task->sc, &sig_attrs->check_mask); + +- if (rsc->mr_valid) ++ if (rsc->sig_mr->need_inval) + iser_inv_rkey(&tx_desc->inv_wr, mr, cqe, &wr->wr); + + ib_update_fast_reg_key(mr, ib_inc_rkey(mr->rkey)); +@@ -288,7 +288,7 @@ static int iser_reg_sig_mr(struct iscsi_iser_task *iser_task, + wr->access = IB_ACCESS_LOCAL_WRITE | + IB_ACCESS_REMOTE_READ | + IB_ACCESS_REMOTE_WRITE; +- rsc->mr_valid = 1; ++ rsc->sig_mr->need_inval = true; + + sig_reg->sge.lkey = mr->lkey; + sig_reg->rkey = mr->rkey; +@@ -313,7 +313,7 @@ static int iser_fast_reg_mr(struct iscsi_iser_task *iser_task, + struct ib_reg_wr *wr = &tx_desc->reg_wr; + int n; + +- if (rsc->mr_valid) ++ if (rsc->mr->need_inval) + iser_inv_rkey(&tx_desc->inv_wr, mr, cqe, &wr->wr); + + ib_update_fast_reg_key(mr, ib_inc_rkey(mr->rkey)); +@@ -336,7 +336,7 @@ static int iser_fast_reg_mr(struct iscsi_iser_task *iser_task, + IB_ACCESS_REMOTE_WRITE | + IB_ACCESS_REMOTE_READ; + +- rsc->mr_valid = 1; ++ rsc->mr->need_inval = true; + + reg->sge.lkey = mr->lkey; + reg->rkey = mr->rkey; +diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c +index a00ca117303a9..057e69164e6d7 100644 +--- a/drivers/infiniband/ulp/iser/iser_verbs.c ++++ b/drivers/infiniband/ulp/iser/iser_verbs.c +@@ -135,7 +135,6 @@ iser_create_fastreg_desc(struct iser_device *device, + goto err_alloc_mr_integrity; + } + } +- desc->rsc.mr_valid = 0; + + return desc; + +diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c +index e1e4f1133296a..c4d8caadec59e 100644 +--- a/drivers/input/keyboard/atkbd.c ++++ b/drivers/input/keyboard/atkbd.c +@@ -772,9 +772,9 @@ static bool atkbd_is_portable_device(void) + * not work. So in this case simply assume a keyboard is connected to avoid + * confusing some laptop keyboards. + * +- * Skipping ATKBD_CMD_GETID ends up using a fake keyboard id. Using a fake id is +- * ok in translated mode, only atkbd_select_set() checks atkbd->id and in +- * translated mode that is a no-op. ++ * Skipping ATKBD_CMD_GETID ends up using a fake keyboard id. Using the standard ++ * 0xab83 id is ok in translated mode, only atkbd_select_set() checks atkbd->id ++ * and in translated mode that is a no-op. + */ + static bool atkbd_skip_getid(struct atkbd *atkbd) + { +@@ -792,6 +792,7 @@ static int atkbd_probe(struct atkbd *atkbd) + { + struct ps2dev *ps2dev = &atkbd->ps2dev; + unsigned char param[2]; ++ bool skip_getid; + + /* + * Some systems, where the bit-twiddling when testing the io-lines of the +@@ -813,7 +814,8 @@ static int atkbd_probe(struct atkbd *atkbd) + */ + + param[0] = param[1] = 0xa5; /* initialize with invalid values */ +- if (atkbd_skip_getid(atkbd) || ps2_command(ps2dev, param, ATKBD_CMD_GETID)) { ++ skip_getid = atkbd_skip_getid(atkbd); ++ if (skip_getid || ps2_command(ps2dev, param, ATKBD_CMD_GETID)) { + + /* + * If the get ID command was skipped or failed, we check if we can at least set +@@ -823,7 +825,7 @@ static int atkbd_probe(struct atkbd *atkbd) + param[0] = 0; + if (ps2_command(ps2dev, param, ATKBD_CMD_SETLEDS)) + return -1; +- atkbd->id = 0xabba; ++ atkbd->id = skip_getid ? 0xab83 : 0xabba; + return 0; + } + +diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +index b2708de25ea34..d80065c8105af 100644 +--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c ++++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +@@ -243,6 +243,7 @@ static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain, + + static const struct of_device_id qcom_smmu_client_of_match[] __maybe_unused = { + { .compatible = "qcom,adreno" }, ++ { .compatible = "qcom,adreno-gmu" }, + { .compatible = "qcom,mdp4" }, + { .compatible = "qcom,mdss" }, + { .compatible = "qcom,sc7180-mdss" }, +diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c +index 9297b741f5e80..aa6d62cc567ae 100644 +--- a/drivers/iommu/dma-iommu.c ++++ b/drivers/iommu/dma-iommu.c +@@ -28,6 +28,7 @@ + #include <linux/spinlock.h> + #include <linux/swiotlb.h> + #include <linux/vmalloc.h> ++#include <trace/events/swiotlb.h> + + #include "dma-iommu.h" + +@@ -999,6 +1000,8 @@ static dma_addr_t iommu_dma_map_page(struct device *dev, struct page *page, + return DMA_MAPPING_ERROR; + } + ++ trace_swiotlb_bounced(dev, phys, size); ++ + aligned_size = iova_align(iovad, size); + phys = swiotlb_tbl_map_single(dev, phys, size, aligned_size, + iova_mask(iovad), dir, attrs); +diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig +index 2378cfb7443e4..509d03eb3e8d6 100644 +--- a/drivers/leds/Kconfig ++++ b/drivers/leds/Kconfig +@@ -97,6 +97,7 @@ config LEDS_ARIEL + config LEDS_AW2013 + tristate "LED support for Awinic AW2013" + depends on LEDS_CLASS && I2C && OF ++ select REGMAP_I2C + help + This option enables support for the AW2013 3-channel + LED driver. +diff --git a/drivers/md/md.c b/drivers/md/md.c +index 0c2801d770901..6120f26a79696 100644 +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -528,6 +528,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); ++ + /* The pre-request flush has finished */ + queue_work(md_wq, &mddev->flush_work); + } +@@ -547,12 +550,8 @@ static void submit_flushes(struct work_struct *ws) + rdev_for_each_rcu(rdev, mddev) + if (rdev->raid_disk >= 0 && + !test_bit(Faulty, &rdev->flags)) { +- /* Take two references, one is dropped +- * when request finishes, one after +- * we reclaim rcu_read_lock +- */ + struct bio *bi; +- atomic_inc(&rdev->nr_pending); ++ + atomic_inc(&rdev->nr_pending); + rcu_read_unlock(); + bi = bio_alloc_bioset(rdev->bdev, 0, +@@ -563,7 +562,6 @@ static void submit_flushes(struct work_struct *ws) + atomic_inc(&mddev->flush_pending); + submit_bio(bi); + rcu_read_lock(); +- rdev_dec_pending(rdev, mddev); + } + rcu_read_unlock(); + if (atomic_dec_and_test(&mddev->flush_pending)) +@@ -616,6 +614,18 @@ bool md_flush_request(struct mddev *mddev, struct bio *bio) + /* new request after previous flush is completed */ + if (ktime_after(req_start, mddev->prev_flush_start)) { + WARN_ON(mddev->flush_bio); ++ /* ++ * Grab a reference to make sure mddev_suspend() will wait for ++ * this flush to be done. ++ * ++ * md_flush_reqeust() is called under md_handle_request() and ++ * 'active_io' is already grabbed, hence percpu_ref_is_zero() ++ * won't pass, percpu_ref_tryget_live() can't be used because ++ * percpu_ref_kill() can be called by mddev_suspend() ++ * concurrently. ++ */ ++ WARN_ON(percpu_ref_is_zero(&mddev->active_io)); ++ percpu_ref_get(&mddev->active_io); + mddev->flush_bio = bio; + bio = NULL; + } +diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c +index 30f906a67def4..76f7ca53d8123 100644 +--- a/drivers/md/raid1.c ++++ b/drivers/md/raid1.c +@@ -1972,12 +1972,12 @@ static void end_sync_write(struct bio *bio) + } + + static int r1_sync_page_io(struct md_rdev *rdev, sector_t sector, +- int sectors, struct page *page, int rw) ++ int sectors, struct page *page, blk_opf_t rw) + { + if (sync_page_io(rdev, sector, sectors << 9, page, rw, false)) + /* success */ + return 1; +- if (rw == WRITE) { ++ if (rw == REQ_OP_WRITE) { + set_bit(WriteErrorSeen, &rdev->flags); + if (!test_and_set_bit(WantReplacement, + &rdev->flags)) +@@ -2094,7 +2094,7 @@ static int fix_sync_read_error(struct r1bio *r1_bio) + rdev = conf->mirrors[d].rdev; + if (r1_sync_page_io(rdev, sect, s, + pages[idx], +- WRITE) == 0) { ++ REQ_OP_WRITE) == 0) { + r1_bio->bios[d]->bi_end_io = NULL; + rdev_dec_pending(rdev, mddev); + } +@@ -2109,7 +2109,7 @@ static int fix_sync_read_error(struct r1bio *r1_bio) + rdev = conf->mirrors[d].rdev; + if (r1_sync_page_io(rdev, sect, s, + pages[idx], +- READ) != 0) ++ REQ_OP_READ) != 0) + atomic_add(s, &rdev->corrected_errors); + } + sectors -= s; +@@ -2321,7 +2321,7 @@ static void fix_read_error(struct r1conf *conf, int read_disk, + atomic_inc(&rdev->nr_pending); + rcu_read_unlock(); + r1_sync_page_io(rdev, sect, s, +- conf->tmppage, WRITE); ++ conf->tmppage, REQ_OP_WRITE); + rdev_dec_pending(rdev, mddev); + } else + rcu_read_unlock(); +@@ -2338,7 +2338,7 @@ static void fix_read_error(struct r1conf *conf, int read_disk, + atomic_inc(&rdev->nr_pending); + rcu_read_unlock(); + if (r1_sync_page_io(rdev, sect, s, +- conf->tmppage, READ)) { ++ conf->tmppage, REQ_OP_READ)) { + atomic_add(s, &rdev->corrected_errors); + pr_info("md/raid1:%s: read error corrected (%d sectors at %llu on %pg)\n", + mdname(mddev), s, +diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c +index f7783199f81d4..e4564ca1f2434 100644 +--- a/drivers/md/raid5.c ++++ b/drivers/md/raid5.c +@@ -36,6 +36,7 @@ + */ + + #include <linux/blkdev.h> ++#include <linux/delay.h> + #include <linux/kthread.h> + #include <linux/raid/pq.h> + #include <linux/async_tx.h> +@@ -6832,7 +6833,18 @@ static void raid5d(struct md_thread *thread) + spin_unlock_irq(&conf->device_lock); + md_check_recovery(mddev); + spin_lock_irq(&conf->device_lock); ++ ++ /* ++ * Waiting on MD_SB_CHANGE_PENDING below may deadlock ++ * seeing md_check_recovery() is needed to clear ++ * the flag when using mdmon. ++ */ ++ continue; + } ++ ++ wait_event_lock_irq(mddev->sb_wait, ++ !test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags), ++ conf->device_lock); + } + pr_debug("%d stripes handled\n", handled); + +diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c +index 9f9a976527080..d352e028491aa 100644 +--- a/drivers/media/dvb-core/dvbdev.c ++++ b/drivers/media/dvb-core/dvbdev.c +@@ -104,6 +104,8 @@ static int dvb_device_open(struct inode *inode, struct file *file) + err = file->f_op->open(inode, file); + up_read(&minor_rwsem); + mutex_unlock(&dvbdev_mutex); ++ if (err) ++ dvb_device_put(dvbdev); + return err; + } + fail: +diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c +index 9a0d43c7ba9e0..ce99f7dfb5a5e 100644 +--- a/drivers/media/dvb-frontends/m88ds3103.c ++++ b/drivers/media/dvb-frontends/m88ds3103.c +@@ -1894,7 +1894,7 @@ static int m88ds3103_probe(struct i2c_client *client, + /* get frontend address */ + ret = regmap_read(dev->regmap, 0x29, &utmp); + if (ret) +- goto err_kfree; ++ goto err_del_adapters; + dev->dt_addr = ((utmp & 0x80) == 0) ? 0x42 >> 1 : 0x40 >> 1; + dev_dbg(&client->dev, "dt addr is 0x%02x\n", dev->dt_addr); + +@@ -1902,11 +1902,14 @@ static int m88ds3103_probe(struct i2c_client *client, + dev->dt_addr); + if (IS_ERR(dev->dt_client)) { + ret = PTR_ERR(dev->dt_client); +- goto err_kfree; ++ goto err_del_adapters; + } + } + + return 0; ++ ++err_del_adapters: ++ i2c_mux_del_adapters(dev->muxc); + err_kfree: + kfree(dev); + err: +diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c +index e9a4f8abd21c5..3071b61946c3b 100644 +--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c ++++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c +@@ -1412,7 +1412,6 @@ static int mtk_jpeg_remove(struct platform_device *pdev) + { + struct mtk_jpeg_dev *jpeg = platform_get_drvdata(pdev); + +- cancel_delayed_work_sync(&jpeg->job_timeout_work); + pm_runtime_disable(&pdev->dev); + video_unregister_device(jpeg->vdev); + v4l2_m2m_release(jpeg->m2m_dev); +diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c +index afbbfd5d02bcc..6d200e23754e8 100644 +--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c ++++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c +@@ -188,6 +188,7 @@ int mtk_jpeg_dec_fill_param(struct mtk_jpeg_dec_param *param) + + return 0; + } ++EXPORT_SYMBOL_GPL(mtk_jpeg_dec_fill_param); + + u32 mtk_jpeg_dec_get_int_status(void __iomem *base) + { +@@ -199,6 +200,7 @@ u32 mtk_jpeg_dec_get_int_status(void __iomem *base) + + return ret; + } ++EXPORT_SYMBOL_GPL(mtk_jpeg_dec_get_int_status); + + u32 mtk_jpeg_dec_enum_result(u32 irq_result) + { +@@ -215,11 +217,13 @@ u32 mtk_jpeg_dec_enum_result(u32 irq_result) + + return MTK_JPEG_DEC_RESULT_ERROR_UNKNOWN; + } ++EXPORT_SYMBOL_GPL(mtk_jpeg_dec_enum_result); + + void mtk_jpeg_dec_start(void __iomem *base) + { + writel(0, base + JPGDEC_REG_TRIG); + } ++EXPORT_SYMBOL_GPL(mtk_jpeg_dec_start); + + static void mtk_jpeg_dec_soft_reset(void __iomem *base) + { +@@ -239,6 +243,7 @@ void mtk_jpeg_dec_reset(void __iomem *base) + mtk_jpeg_dec_soft_reset(base); + mtk_jpeg_dec_hard_reset(base); + } ++EXPORT_SYMBOL_GPL(mtk_jpeg_dec_reset); + + static void mtk_jpeg_dec_set_brz_factor(void __iomem *base, u8 yscale_w, + u8 yscale_h, u8 uvscale_w, u8 uvscale_h) +@@ -407,3 +412,4 @@ void mtk_jpeg_dec_set_config(void __iomem *base, + config->dma_last_mcu); + mtk_jpeg_dec_set_pause_mcu_idx(base, config->total_mcu); + } ++EXPORT_SYMBOL_GPL(mtk_jpeg_dec_set_config); +diff --git a/drivers/media/platform/nxp/imx-mipi-csis.c b/drivers/media/platform/nxp/imx-mipi-csis.c +index 905072871ed2e..196f2bba419f9 100644 +--- a/drivers/media/platform/nxp/imx-mipi-csis.c ++++ b/drivers/media/platform/nxp/imx-mipi-csis.c +@@ -1553,8 +1553,10 @@ static int mipi_csis_remove(struct platform_device *pdev) + v4l2_async_nf_cleanup(&csis->notifier); + v4l2_async_unregister_subdev(&csis->sd); + ++ if (!pm_runtime_enabled(&pdev->dev)) ++ mipi_csis_runtime_suspend(&pdev->dev); ++ + pm_runtime_disable(&pdev->dev); +- mipi_csis_runtime_suspend(&pdev->dev); + mipi_csis_clk_disable(csis); + media_entity_cleanup(&csis->sd.entity); + fwnode_handle_put(csis->sd.fwnode); +diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c +index f2475c6235ea7..2b76339f9381c 100644 +--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c ++++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c +@@ -582,7 +582,7 @@ static int rkisp1_probe(struct platform_device *pdev) + + ret = v4l2_device_register(rkisp1->dev, &rkisp1->v4l2_dev); + if (ret) +- goto err_pm_runtime_disable; ++ goto err_media_dev_cleanup; + + ret = media_device_register(&rkisp1->media_dev); + if (ret) { +@@ -617,6 +617,8 @@ err_unreg_media_dev: + media_device_unregister(&rkisp1->media_dev); + err_unreg_v4l2_dev: + v4l2_device_unregister(&rkisp1->v4l2_dev); ++err_media_dev_cleanup: ++ media_device_cleanup(&rkisp1->media_dev); + err_pm_runtime_disable: + pm_runtime_disable(&pdev->dev); + return ret; +@@ -637,6 +639,8 @@ static int rkisp1_remove(struct platform_device *pdev) + media_device_unregister(&rkisp1->media_dev); + v4l2_device_unregister(&rkisp1->v4l2_dev); + ++ media_device_cleanup(&rkisp1->media_dev); ++ + pm_runtime_disable(&pdev->dev); + + return 0; +diff --git a/drivers/media/platform/verisilicon/hantro_drv.c b/drivers/media/platform/verisilicon/hantro_drv.c +index 08840ba313e7a..69a2442f31223 100644 +--- a/drivers/media/platform/verisilicon/hantro_drv.c ++++ b/drivers/media/platform/verisilicon/hantro_drv.c +@@ -813,6 +813,8 @@ static int hantro_add_func(struct hantro_dev *vpu, unsigned int funcid) + + if (funcid == MEDIA_ENT_F_PROC_VIDEO_ENCODER) { + vpu->encoder = func; ++ v4l2_disable_ioctl(vfd, VIDIOC_TRY_DECODER_CMD); ++ v4l2_disable_ioctl(vfd, VIDIOC_DECODER_CMD); + } else { + vpu->decoder = func; + v4l2_disable_ioctl(vfd, VIDIOC_TRY_ENCODER_CMD); +diff --git a/drivers/media/platform/verisilicon/hantro_v4l2.c b/drivers/media/platform/verisilicon/hantro_v4l2.c +index 30e650edaea8a..b2da48936e3f1 100644 +--- a/drivers/media/platform/verisilicon/hantro_v4l2.c ++++ b/drivers/media/platform/verisilicon/hantro_v4l2.c +@@ -759,6 +759,9 @@ const struct v4l2_ioctl_ops hantro_ioctl_ops = { + .vidioc_g_selection = vidioc_g_selection, + .vidioc_s_selection = vidioc_s_selection, + ++ .vidioc_decoder_cmd = v4l2_m2m_ioctl_stateless_decoder_cmd, ++ .vidioc_try_decoder_cmd = v4l2_m2m_ioctl_stateless_try_decoder_cmd, ++ + .vidioc_try_encoder_cmd = v4l2_m2m_ioctl_try_encoder_cmd, + .vidioc_encoder_cmd = vidioc_encoder_cmd, + }; +diff --git a/drivers/media/usb/cx231xx/cx231xx-core.c b/drivers/media/usb/cx231xx/cx231xx-core.c +index 727e6268567f7..f1feccc28bf05 100644 +--- a/drivers/media/usb/cx231xx/cx231xx-core.c ++++ b/drivers/media/usb/cx231xx/cx231xx-core.c +@@ -1024,6 +1024,7 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, + if (!dev->video_mode.isoc_ctl.urb) { + dev_err(dev->dev, + "cannot alloc memory for usb buffers\n"); ++ kfree(dma_q->p_left_data); + return -ENOMEM; + } + +@@ -1033,6 +1034,7 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, + dev_err(dev->dev, + "cannot allocate memory for usbtransfer\n"); + kfree(dev->video_mode.isoc_ctl.urb); ++ kfree(dma_q->p_left_data); + return -ENOMEM; + } + +diff --git a/drivers/media/usb/pvrusb2/pvrusb2-context.c b/drivers/media/usb/pvrusb2/pvrusb2-context.c +index 14170a5d72b35..1764674de98bc 100644 +--- a/drivers/media/usb/pvrusb2/pvrusb2-context.c ++++ b/drivers/media/usb/pvrusb2/pvrusb2-context.c +@@ -268,7 +268,8 @@ void pvr2_context_disconnect(struct pvr2_context *mp) + { + pvr2_hdw_disconnect(mp->hdw); + mp->disconnect_flag = !0; +- pvr2_context_notify(mp); ++ if (!pvr2_context_shutok()) ++ pvr2_context_notify(mp); + } + + +diff --git a/drivers/mfd/intel-lpss.c b/drivers/mfd/intel-lpss.c +index cfbee2cfba6b0..c50387600b819 100644 +--- a/drivers/mfd/intel-lpss.c ++++ b/drivers/mfd/intel-lpss.c +@@ -301,8 +301,8 @@ static int intel_lpss_register_clock_divider(struct intel_lpss *lpss, + + snprintf(name, sizeof(name), "%s-div", devname); + tmp = clk_register_fractional_divider(NULL, name, __clk_get_name(tmp), ++ 0, lpss->priv, 1, 15, 16, 15, + CLK_FRAC_DIVIDER_POWER_OF_TWO_PS, +- lpss->priv, 1, 15, 16, 15, 0, + NULL); + if (IS_ERR(tmp)) + return PTR_ERR(tmp); +diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c +index bdb2ce7ff03b9..6196724ef39bb 100644 +--- a/drivers/mfd/syscon.c ++++ b/drivers/mfd/syscon.c +@@ -102,6 +102,10 @@ static struct syscon *of_syscon_register(struct device_node *np, bool check_clk) + } + + syscon_config.name = kasprintf(GFP_KERNEL, "%pOFn@%pa", np, &res.start); ++ if (!syscon_config.name) { ++ ret = -ENOMEM; ++ goto err_regmap; ++ } + syscon_config.reg_stride = reg_io_width; + syscon_config.val_bits = reg_io_width * 8; + syscon_config.max_register = resource_size(&res) - reg_io_width; +diff --git a/drivers/misc/habanalabs/common/habanalabs_ioctl.c b/drivers/misc/habanalabs/common/habanalabs_ioctl.c +index 43afe40966e50..1ea1ae34b7a74 100644 +--- a/drivers/misc/habanalabs/common/habanalabs_ioctl.c ++++ b/drivers/misc/habanalabs/common/habanalabs_ioctl.c +@@ -677,7 +677,7 @@ static int sec_attest_info(struct hl_fpriv *hpriv, struct hl_info_args *args) + if (!sec_attest_info) + return -ENOMEM; + +- info = kmalloc(sizeof(*info), GFP_KERNEL); ++ info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) { + rc = -ENOMEM; + goto free_sec_attest_info; +diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig +index 9b5a2cb110b3e..d84bdb69f56b0 100644 +--- a/drivers/mmc/host/Kconfig ++++ b/drivers/mmc/host/Kconfig +@@ -1061,14 +1061,15 @@ config MMC_SDHCI_XENON + + config MMC_SDHCI_OMAP + tristate "TI SDHCI Controller Support" ++ depends on ARCH_OMAP2PLUS || ARCH_KEYSTONE || COMPILE_TEST + depends on MMC_SDHCI_PLTFM && OF + select THERMAL + imply TI_SOC_THERMAL + select MMC_SDHCI_EXTERNAL_DMA if DMA_ENGINE + help + This selects the Secure Digital Host Controller Interface (SDHCI) +- support present in TI's DRA7 SOCs. The controller supports +- SD/MMC/SDIO devices. ++ support present in TI's Keystone/OMAP2+/DRA7 SOCs. The controller ++ supports SD/MMC/SDIO devices. + + If you have a controller with this interface, say Y or M here. + +@@ -1076,14 +1077,15 @@ config MMC_SDHCI_OMAP + + config MMC_SDHCI_AM654 + tristate "Support for the SDHCI Controller in TI's AM654 SOCs" ++ depends on ARCH_K3 || COMPILE_TEST + depends on MMC_SDHCI_PLTFM && OF + select MMC_SDHCI_IO_ACCESSORS + select MMC_CQHCI + select REGMAP_MMIO + help + This selects the Secure Digital Host Controller Interface (SDHCI) +- support present in TI's AM654 SOCs. The controller supports +- SD/MMC/SDIO devices. ++ support present in TI's AM65x/AM64x/AM62x/J721E SOCs. The controller ++ supports SD/MMC/SDIO devices. + + If you have a controller with this interface, say Y or M here. + +diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c +index 60b222799871e..8ee60605a6dcc 100644 +--- a/drivers/mtd/mtd_blkdevs.c ++++ b/drivers/mtd/mtd_blkdevs.c +@@ -463,7 +463,7 @@ static void blktrans_notify_add(struct mtd_info *mtd) + { + struct mtd_blktrans_ops *tr; + +- if (mtd->type == MTD_ABSENT) ++ if (mtd->type == MTD_ABSENT || mtd->type == MTD_UBIVOLUME) + return; + + list_for_each_entry(tr, &blktrans_majors, list) +@@ -503,7 +503,7 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr) + mutex_lock(&mtd_table_mutex); + list_add(&tr->list, &blktrans_majors); + mtd_for_each_device(mtd) +- if (mtd->type != MTD_ABSENT) ++ if (mtd->type != MTD_ABSENT && mtd->type != MTD_UBIVOLUME) + tr->add_mtd(tr, mtd); + mutex_unlock(&mtd_table_mutex); + return 0; +diff --git a/drivers/mtd/nand/raw/fsl_ifc_nand.c b/drivers/mtd/nand/raw/fsl_ifc_nand.c +index 02d5001768382..bea1a7d3edd78 100644 +--- a/drivers/mtd/nand/raw/fsl_ifc_nand.c ++++ b/drivers/mtd/nand/raw/fsl_ifc_nand.c +@@ -20,7 +20,7 @@ + + #define ERR_BYTE 0xFF /* Value returned for read + bytes when read failed */ +-#define IFC_TIMEOUT_MSECS 500 /* Maximum number of mSecs to wait ++#define IFC_TIMEOUT_MSECS 1000 /* Maximum timeout to wait + for IFC NAND Machine */ + + struct fsl_ifc_ctrl; +diff --git a/drivers/net/amt.c b/drivers/net/amt.c +index 2d20be6ffb7e5..ddd087c2c3ed4 100644 +--- a/drivers/net/amt.c ++++ b/drivers/net/amt.c +@@ -11,7 +11,7 @@ + #include <linux/net.h> + #include <linux/igmp.h> + #include <linux/workqueue.h> +-#include <net/sch_generic.h> ++#include <net/pkt_sched.h> + #include <net/net_namespace.h> + #include <net/ip.h> + #include <net/udp.h> +@@ -80,11 +80,11 @@ static struct mld2_grec mldv2_zero_grec; + + static struct amt_skb_cb *amt_skb_cb(struct sk_buff *skb) + { +- BUILD_BUG_ON(sizeof(struct amt_skb_cb) + sizeof(struct qdisc_skb_cb) > ++ BUILD_BUG_ON(sizeof(struct amt_skb_cb) + sizeof(struct tc_skb_cb) > + sizeof_field(struct sk_buff, cb)); + + return (struct amt_skb_cb *)((void *)skb->cb + +- sizeof(struct qdisc_skb_cb)); ++ sizeof(struct tc_skb_cb)); + } + + static void __amt_source_gc_work(void) +diff --git a/drivers/net/dsa/vitesse-vsc73xx-core.c b/drivers/net/dsa/vitesse-vsc73xx-core.c +index ef1a4a7c47b23..3efd556690563 100644 +--- a/drivers/net/dsa/vitesse-vsc73xx-core.c ++++ b/drivers/net/dsa/vitesse-vsc73xx-core.c +@@ -1119,6 +1119,8 @@ static int vsc73xx_gpio_probe(struct vsc73xx *vsc) + + vsc->gc.label = devm_kasprintf(vsc->dev, GFP_KERNEL, "VSC%04x", + vsc->chipid); ++ if (!vsc->gc.label) ++ return -ENOMEM; + vsc->gc.ngpio = 4; + vsc->gc.owner = THIS_MODULE; + vsc->gc.parent = vsc->dev; +diff --git a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c +index 2292d63a279c1..83c4659390fd5 100644 +--- a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c ++++ b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c +@@ -130,9 +130,15 @@ static int mlxbf_gige_open(struct net_device *netdev) + { + struct mlxbf_gige *priv = netdev_priv(netdev); + struct phy_device *phydev = netdev->phydev; ++ u64 control; + u64 int_en; + int err; + ++ /* Perform general init of GigE block */ ++ control = readq(priv->base + MLXBF_GIGE_CONTROL); ++ control |= MLXBF_GIGE_CONTROL_PORT_EN; ++ writeq(control, priv->base + MLXBF_GIGE_CONTROL); ++ + err = mlxbf_gige_request_irqs(priv); + if (err) + return err; +@@ -147,14 +153,14 @@ static int mlxbf_gige_open(struct net_device *netdev) + */ + priv->valid_polarity = 0; + +- err = mlxbf_gige_rx_init(priv); ++ phy_start(phydev); ++ ++ err = mlxbf_gige_tx_init(priv); + if (err) + goto free_irqs; +- err = mlxbf_gige_tx_init(priv); ++ err = mlxbf_gige_rx_init(priv); + if (err) +- goto rx_deinit; +- +- phy_start(phydev); ++ goto tx_deinit; + + netif_napi_add(netdev, &priv->napi, mlxbf_gige_poll); + napi_enable(&priv->napi); +@@ -176,8 +182,8 @@ static int mlxbf_gige_open(struct net_device *netdev) + + return 0; + +-rx_deinit: +- mlxbf_gige_rx_deinit(priv); ++tx_deinit: ++ mlxbf_gige_tx_deinit(priv); + + free_irqs: + mlxbf_gige_free_irqs(priv); +@@ -279,7 +285,6 @@ static int mlxbf_gige_probe(struct platform_device *pdev) + void __iomem *plu_base; + void __iomem *base; + int addr, phy_irq; +- u64 control; + int err; + + base = devm_platform_ioremap_resource(pdev, MLXBF_GIGE_RES_MAC); +@@ -294,11 +299,6 @@ static int mlxbf_gige_probe(struct platform_device *pdev) + if (IS_ERR(plu_base)) + return PTR_ERR(plu_base); + +- /* Perform general init of GigE block */ +- control = readq(base + MLXBF_GIGE_CONTROL); +- control |= MLXBF_GIGE_CONTROL_PORT_EN; +- writeq(control, base + MLXBF_GIGE_CONTROL); +- + netdev = devm_alloc_etherdev(&pdev->dev, sizeof(*priv)); + if (!netdev) + return -ENOMEM; +diff --git a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_rx.c b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_rx.c +index 227d01cace3f0..6999843584934 100644 +--- a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_rx.c ++++ b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_rx.c +@@ -142,6 +142,9 @@ int mlxbf_gige_rx_init(struct mlxbf_gige *priv) + writeq(MLXBF_GIGE_RX_MAC_FILTER_COUNT_PASS_EN, + priv->base + MLXBF_GIGE_RX_MAC_FILTER_COUNT_PASS); + ++ writeq(ilog2(priv->rx_q_entries), ++ priv->base + MLXBF_GIGE_RX_WQE_SIZE_LOG2); ++ + /* Clear MLXBF_GIGE_INT_MASK 'receive pkt' bit to + * indicate readiness to receive interrupts + */ +@@ -154,9 +157,6 @@ int mlxbf_gige_rx_init(struct mlxbf_gige *priv) + data |= MLXBF_GIGE_RX_DMA_EN; + writeq(data, priv->base + MLXBF_GIGE_RX_DMA); + +- writeq(ilog2(priv->rx_q_entries), +- priv->base + MLXBF_GIGE_RX_WQE_SIZE_LOG2); +- + return 0; + + free_wqe_and_skb: +diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c +index 4c98950380d53..d231f4d2888be 100644 +--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c +@@ -301,6 +301,7 @@ mlxsw_sp_acl_erp_table_alloc(struct mlxsw_sp_acl_erp_core *erp_core, + unsigned long *p_index) + { + unsigned int num_rows, entry_size; ++ unsigned long index; + + /* We only allow allocations of entire rows */ + if (num_erps % erp_core->num_erp_banks != 0) +@@ -309,10 +310,11 @@ mlxsw_sp_acl_erp_table_alloc(struct mlxsw_sp_acl_erp_core *erp_core, + entry_size = erp_core->erpt_entries_size[region_type]; + num_rows = num_erps / erp_core->num_erp_banks; + +- *p_index = gen_pool_alloc(erp_core->erp_tables, num_rows * entry_size); +- if (*p_index == 0) ++ index = gen_pool_alloc(erp_core->erp_tables, num_rows * entry_size); ++ if (!index) + return -ENOBUFS; +- *p_index -= MLXSW_SP_ACL_ERP_GENALLOC_OFFSET; ++ ++ *p_index = index - MLXSW_SP_ACL_ERP_GENALLOC_OFFSET; + + return 0; + } +diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c +index 27b1663c476e7..64b209a0ad219 100644 +--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c ++++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c +@@ -391,7 +391,7 @@ nla_put_failure: + + struct rtnl_link_ops rmnet_link_ops __read_mostly = { + .kind = "rmnet", +- .maxtype = __IFLA_RMNET_MAX, ++ .maxtype = IFLA_RMNET_MAX, + .priv_size = sizeof(struct rmnet_priv), + .setup = rmnet_vnd_setup, + .validate = rmnet_rtnl_validate, +diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c +index c2c56a5289caf..e7b70006261f7 100644 +--- a/drivers/net/ethernet/renesas/ravb_main.c ++++ b/drivers/net/ethernet/renesas/ravb_main.c +@@ -1965,7 +1965,7 @@ static netdev_tx_t ravb_start_xmit(struct sk_buff *skb, struct net_device *ndev) + struct ravb_tstamp_skb *ts_skb; + struct ravb_tx_desc *desc; + unsigned long flags; +- u32 dma_addr; ++ dma_addr_t dma_addr; + void *buffer; + u32 entry; + u32 len; +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h +index bdbf86cb102af..46944c02b45ed 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h +@@ -247,6 +247,7 @@ struct stmmac_priv { + u32 msg_enable; + int wolopts; + int wol_irq; ++ bool wol_irq_disabled; + int clk_csr; + struct timer_list eee_ctrl_timer; + int lpi_irq; +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +index 35c8dd92d3692..f03aa8a0b8954 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +@@ -761,10 +761,16 @@ static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) + if (wol->wolopts) { + pr_info("stmmac: wakeup enable\n"); + device_set_wakeup_enable(priv->device, 1); +- enable_irq_wake(priv->wol_irq); ++ /* Avoid unbalanced enable_irq_wake calls */ ++ if (priv->wol_irq_disabled) ++ enable_irq_wake(priv->wol_irq); ++ priv->wol_irq_disabled = false; + } else { + device_set_wakeup_enable(priv->device, 0); +- disable_irq_wake(priv->wol_irq); ++ /* Avoid unbalanced disable_irq_wake calls */ ++ if (!priv->wol_irq_disabled) ++ disable_irq_wake(priv->wol_irq); ++ priv->wol_irq_disabled = true; + } + + mutex_lock(&priv->lock); +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index deb6e95a1bca6..8f8de14347a94 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -3519,6 +3519,7 @@ static int stmmac_request_irq_multi_msi(struct net_device *dev) + /* Request the Wake IRQ in case of another line + * is used for WoL + */ ++ priv->wol_irq_disabled = true; + if (priv->wol_irq > 0 && priv->wol_irq != dev->irq) { + int_name = priv->int_name_wol; + sprintf(int_name, "%s:%s", dev->name, "wol"); +diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c +index 9f2553799895d..76fabeae512db 100644 +--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c ++++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c +@@ -54,7 +54,7 @@ + #define AM65_CPSW_MAX_PORTS 8 + + #define AM65_CPSW_MIN_PACKET_SIZE VLAN_ETH_ZLEN +-#define AM65_CPSW_MAX_PACKET_SIZE (VLAN_ETH_FRAME_LEN + ETH_FCS_LEN) ++#define AM65_CPSW_MAX_PACKET_SIZE 2024 + + #define AM65_CPSW_REG_CTL 0x004 + #define AM65_CPSW_REG_STAT_PORT_EN 0x014 +@@ -1990,7 +1990,8 @@ am65_cpsw_nuss_init_port_ndev(struct am65_cpsw_common *common, u32 port_idx) + eth_hw_addr_set(port->ndev, port->slave.mac_addr); + + port->ndev->min_mtu = AM65_CPSW_MIN_PACKET_SIZE; +- port->ndev->max_mtu = AM65_CPSW_MAX_PACKET_SIZE; ++ port->ndev->max_mtu = AM65_CPSW_MAX_PACKET_SIZE - ++ (VLAN_ETH_HLEN + ETH_FCS_LEN); + port->ndev->hw_features = NETIF_F_SG | + NETIF_F_RXCSUM | + NETIF_F_HW_CSUM | +diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c +index 54a17b576eac0..7cbcf51bae924 100644 +--- a/drivers/net/phy/micrel.c ++++ b/drivers/net/phy/micrel.c +@@ -3302,6 +3302,7 @@ static struct phy_driver ksphy_driver[] = { + .flags = PHY_POLL_CABLE_TEST, + .driver_data = &ksz9021_type, + .probe = kszphy_probe, ++ .soft_reset = genphy_soft_reset, + .config_init = ksz9131_config_init, + .config_intr = kszphy_config_intr, + .handle_interrupt = kszphy_handle_interrupt, +diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c +index 76f275ca53e9c..70d468f013383 100644 +--- a/drivers/net/wireless/ath/ath11k/ahb.c ++++ b/drivers/net/wireless/ath/ath11k/ahb.c +@@ -813,8 +813,8 @@ static int ath11k_core_get_rproc(struct ath11k_base *ab) + + prproc = rproc_get_by_phandle(rproc_phandle); + if (!prproc) { +- ath11k_err(ab, "failed to get rproc\n"); +- return -EINVAL; ++ ath11k_dbg(ab, ATH11K_DBG_AHB, "failed to get rproc, deferring\n"); ++ return -EPROBE_DEFER; + } + ab_ahb->tgt_rproc = prproc; + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c +index a3cefbc43e80d..2c14188f34bbc 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c +@@ -99,17 +99,6 @@ static void iwl_mvm_phy_ctxt_set_rxchain(struct iwl_mvm *mvm, + active_cnt = 2; + } + +- /* +- * If the firmware requested it, then we know that it supports +- * getting zero for the values to indicate "use one, but pick +- * which one yourself", which means it can dynamically pick one +- * that e.g. has better RSSI. +- */ +- if (mvm->fw_static_smps_request && active_cnt == 1 && idle_cnt == 1) { +- idle_cnt = 0; +- active_cnt = 0; +- } +- + *rxchain_info = cpu_to_le32(iwl_mvm_get_valid_rx_ant(mvm) << + PHY_RX_CHAIN_VALID_POS); + *rxchain_info |= cpu_to_le32(idle_cnt << PHY_RX_CHAIN_CNT_POS); +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +index caaf4d52e2c64..76219486b9c2e 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +@@ -2200,7 +2200,7 @@ int iwl_mvm_flush_sta_tids(struct iwl_mvm *mvm, u32 sta_id, u16 tids) + WARN_ON(!iwl_mvm_has_new_tx_api(mvm)); + + if (iwl_fw_lookup_notif_ver(mvm->fw, LONG_GROUP, TXPATH_FLUSH, 0) > 0) +- cmd.flags |= CMD_WANT_SKB; ++ cmd.flags |= CMD_WANT_SKB | CMD_SEND_IN_RFKILL; + + IWL_DEBUG_TX_QUEUES(mvm, "flush for sta id %d tid mask 0x%x\n", + sta_id, tids); +diff --git a/drivers/net/wireless/marvell/libertas/Kconfig b/drivers/net/wireless/marvell/libertas/Kconfig +index 6d62ab49aa8d4..c7d02adb3eead 100644 +--- a/drivers/net/wireless/marvell/libertas/Kconfig ++++ b/drivers/net/wireless/marvell/libertas/Kconfig +@@ -2,8 +2,6 @@ + config LIBERTAS + tristate "Marvell 8xxx Libertas WLAN driver support" + depends on CFG80211 +- select WIRELESS_EXT +- select WEXT_SPY + select LIB80211 + select FW_LOADER + help +diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c +index bcd564dc3554a..c907da2a4789a 100644 +--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c ++++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c +@@ -2046,6 +2046,8 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, + + mwifiex_set_sys_config_invalid_data(bss_cfg); + ++ memcpy(bss_cfg->mac_addr, priv->curr_addr, ETH_ALEN); ++ + if (params->beacon_interval) + bss_cfg->beacon_period = params->beacon_interval; + if (params->dtim_period) +diff --git a/drivers/net/wireless/marvell/mwifiex/fw.h b/drivers/net/wireless/marvell/mwifiex/fw.h +index b4f945a549f71..863f5f2247a08 100644 +--- a/drivers/net/wireless/marvell/mwifiex/fw.h ++++ b/drivers/net/wireless/marvell/mwifiex/fw.h +@@ -165,6 +165,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { + #define TLV_TYPE_STA_MAC_ADDR (PROPRIETARY_TLV_BASE_ID + 32) + #define TLV_TYPE_BSSID (PROPRIETARY_TLV_BASE_ID + 35) + #define TLV_TYPE_CHANNELBANDLIST (PROPRIETARY_TLV_BASE_ID + 42) ++#define TLV_TYPE_UAP_MAC_ADDRESS (PROPRIETARY_TLV_BASE_ID + 43) + #define TLV_TYPE_UAP_BEACON_PERIOD (PROPRIETARY_TLV_BASE_ID + 44) + #define TLV_TYPE_UAP_DTIM_PERIOD (PROPRIETARY_TLV_BASE_ID + 45) + #define TLV_TYPE_UAP_BCAST_SSID (PROPRIETARY_TLV_BASE_ID + 48) +diff --git a/drivers/net/wireless/marvell/mwifiex/ioctl.h b/drivers/net/wireless/marvell/mwifiex/ioctl.h +index 091e7ca793762..e8825f302de8a 100644 +--- a/drivers/net/wireless/marvell/mwifiex/ioctl.h ++++ b/drivers/net/wireless/marvell/mwifiex/ioctl.h +@@ -107,6 +107,7 @@ struct mwifiex_uap_bss_param { + u8 qos_info; + u8 power_constraint; + struct mwifiex_types_wmm_info wmm_info; ++ u8 mac_addr[ETH_ALEN]; + }; + + enum { +diff --git a/drivers/net/wireless/marvell/mwifiex/uap_cmd.c b/drivers/net/wireless/marvell/mwifiex/uap_cmd.c +index e78a201cd1507..491e366119096 100644 +--- a/drivers/net/wireless/marvell/mwifiex/uap_cmd.c ++++ b/drivers/net/wireless/marvell/mwifiex/uap_cmd.c +@@ -468,6 +468,7 @@ void mwifiex_config_uap_11d(struct mwifiex_private *priv, + static int + mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size) + { ++ struct host_cmd_tlv_mac_addr *mac_tlv; + struct host_cmd_tlv_dtim_period *dtim_period; + struct host_cmd_tlv_beacon_period *beacon_period; + struct host_cmd_tlv_ssid *ssid; +@@ -487,6 +488,13 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size) + int i; + u16 cmd_size = *param_size; + ++ mac_tlv = (struct host_cmd_tlv_mac_addr *)tlv; ++ mac_tlv->header.type = cpu_to_le16(TLV_TYPE_UAP_MAC_ADDRESS); ++ mac_tlv->header.len = cpu_to_le16(ETH_ALEN); ++ memcpy(mac_tlv->mac_addr, bss_cfg->mac_addr, ETH_ALEN); ++ cmd_size += sizeof(struct host_cmd_tlv_mac_addr); ++ tlv += sizeof(struct host_cmd_tlv_mac_addr); ++ + if (bss_cfg->ssid.ssid_len) { + ssid = (struct host_cmd_tlv_ssid *)tlv; + ssid->header.type = cpu_to_le16(TLV_TYPE_UAP_SSID); +diff --git a/drivers/net/wireless/mediatek/mt76/eeprom.c b/drivers/net/wireless/mediatek/mt76/eeprom.c +index 9bc8758573fcc..0a88048b89768 100644 +--- a/drivers/net/wireless/mediatek/mt76/eeprom.c ++++ b/drivers/net/wireless/mediatek/mt76/eeprom.c +@@ -62,7 +62,7 @@ int mt76_get_of_eeprom(struct mt76_dev *dev, void *eep, int offset, int len) + goto out_put_node; + } + +- offset = be32_to_cpup(list); ++ offset += be32_to_cpup(list); + ret = mtd_read(mtd, offset, len, &retlen, eep); + put_mtd_device(mtd); + if (mtd_is_bitflip(ret)) +diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h +index 9c753c6aabeff..60c9f9c56a4f5 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt76.h ++++ b/drivers/net/wireless/mediatek/mt76/mt76.h +@@ -564,8 +564,7 @@ struct mt76_sdio { + struct mt76_worker txrx_worker; + struct mt76_worker status_worker; + struct mt76_worker net_worker; +- +- struct work_struct stat_work; ++ struct mt76_worker stat_worker; + + u8 *xmit_buf; + u32 xmit_buf_sz; +diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c +index 304212f5f8da7..d742b22428f0c 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c +@@ -205,8 +205,8 @@ static int mt7663s_suspend(struct device *dev) + mt76_worker_disable(&mdev->mt76.sdio.txrx_worker); + mt76_worker_disable(&mdev->mt76.sdio.status_worker); + mt76_worker_disable(&mdev->mt76.sdio.net_worker); ++ mt76_worker_disable(&mdev->mt76.sdio.stat_worker); + +- cancel_work_sync(&mdev->mt76.sdio.stat_work); + clear_bit(MT76_READING_STATS, &mdev->mphy.state); + + mt76_tx_status_check(&mdev->mt76, true); +diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +index 10dda1693d7db..19640ff76bdcf 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +@@ -1036,21 +1036,26 @@ int __mt7921_mcu_set_clc(struct mt7921_dev *dev, u8 *alpha2, + u8 type[2]; + u8 rsvd[64]; + } __packed req = { ++ .ver = 1, + .idx = idx, + .env = env_cap, + }; + int ret, valid_cnt = 0; +- u8 i, *pos; ++ u16 buf_len = 0; ++ u8 *pos; + + if (!clc) + return 0; + ++ buf_len = le16_to_cpu(clc->len) - sizeof(*clc); + pos = clc->data; +- for (i = 0; i < clc->nr_country; i++) { ++ while (buf_len > 16) { + struct mt7921_clc_rule *rule = (struct mt7921_clc_rule *)pos; + u16 len = le16_to_cpu(rule->len); ++ u16 offset = len + sizeof(*rule); + +- pos += len + sizeof(*rule); ++ pos += offset; ++ buf_len -= offset; + if (rule->alpha2[0] != alpha2[0] || + rule->alpha2[1] != alpha2[1]) + continue; +diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c b/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c +index 3b25a06fd9466..8898ba69b8e97 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c +@@ -222,7 +222,7 @@ static int mt7921s_suspend(struct device *__dev) + mt76_txq_schedule_all(&dev->mphy); + mt76_worker_disable(&mdev->tx_worker); + mt76_worker_disable(&mdev->sdio.status_worker); +- cancel_work_sync(&mdev->sdio.stat_work); ++ mt76_worker_disable(&mdev->sdio.stat_worker); + clear_bit(MT76_READING_STATS, &dev->mphy.state); + mt76_tx_status_check(mdev, true); + +@@ -254,6 +254,7 @@ restore_txrx_worker: + restore_worker: + mt76_worker_enable(&mdev->tx_worker); + mt76_worker_enable(&mdev->sdio.status_worker); ++ mt76_worker_enable(&mdev->sdio.stat_worker); + + if (!pm->ds_enable) + mt76_connac_mcu_set_deep_sleep(mdev, false); +@@ -286,6 +287,7 @@ static int mt7921s_resume(struct device *__dev) + mt76_worker_enable(&mdev->sdio.txrx_worker); + mt76_worker_enable(&mdev->sdio.status_worker); + mt76_worker_enable(&mdev->sdio.net_worker); ++ mt76_worker_enable(&mdev->sdio.stat_worker); + + /* restore previous ds setting */ + if (!pm->ds_enable) +diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c +index 1b3adb3d91e86..fd07b66233920 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c +@@ -107,7 +107,7 @@ int mt7921s_mac_reset(struct mt7921_dev *dev) + mt76_worker_disable(&dev->mt76.sdio.txrx_worker); + mt76_worker_disable(&dev->mt76.sdio.status_worker); + mt76_worker_disable(&dev->mt76.sdio.net_worker); +- cancel_work_sync(&dev->mt76.sdio.stat_work); ++ mt76_worker_disable(&dev->mt76.sdio.stat_worker); + + mt7921s_disable_irq(&dev->mt76); + mt7921s_wfsys_reset(dev); +@@ -115,6 +115,7 @@ int mt7921s_mac_reset(struct mt7921_dev *dev) + mt76_worker_enable(&dev->mt76.sdio.txrx_worker); + mt76_worker_enable(&dev->mt76.sdio.status_worker); + mt76_worker_enable(&dev->mt76.sdio.net_worker); ++ mt76_worker_enable(&dev->mt76.sdio.stat_worker); + + dev->fw_assert = false; + clear_bit(MT76_MCU_RESET, &dev->mphy.state); +diff --git a/drivers/net/wireless/mediatek/mt76/sdio.c b/drivers/net/wireless/mediatek/mt76/sdio.c +index 176207f3177c4..fc4fb94635645 100644 +--- a/drivers/net/wireless/mediatek/mt76/sdio.c ++++ b/drivers/net/wireless/mediatek/mt76/sdio.c +@@ -481,21 +481,21 @@ static void mt76s_status_worker(struct mt76_worker *w) + if (dev->drv->tx_status_data && ndata_frames > 0 && + !test_and_set_bit(MT76_READING_STATS, &dev->phy.state) && + !test_bit(MT76_STATE_SUSPEND, &dev->phy.state)) +- ieee80211_queue_work(dev->hw, &dev->sdio.stat_work); ++ mt76_worker_schedule(&sdio->stat_worker); + } while (nframes > 0); + + if (resched) + mt76_worker_schedule(&dev->tx_worker); + } + +-static void mt76s_tx_status_data(struct work_struct *work) ++static void mt76s_tx_status_data(struct mt76_worker *worker) + { + struct mt76_sdio *sdio; + struct mt76_dev *dev; + u8 update = 1; + u16 count = 0; + +- sdio = container_of(work, struct mt76_sdio, stat_work); ++ sdio = container_of(worker, struct mt76_sdio, stat_worker); + dev = container_of(sdio, struct mt76_dev, sdio); + + while (true) { +@@ -508,7 +508,7 @@ static void mt76s_tx_status_data(struct work_struct *work) + } + + if (count && test_bit(MT76_STATE_RUNNING, &dev->phy.state)) +- ieee80211_queue_work(dev->hw, &sdio->stat_work); ++ mt76_worker_schedule(&sdio->status_worker); + else + clear_bit(MT76_READING_STATS, &dev->phy.state); + } +@@ -600,8 +600,8 @@ void mt76s_deinit(struct mt76_dev *dev) + mt76_worker_teardown(&sdio->txrx_worker); + mt76_worker_teardown(&sdio->status_worker); + mt76_worker_teardown(&sdio->net_worker); ++ mt76_worker_teardown(&sdio->stat_worker); + +- cancel_work_sync(&sdio->stat_work); + clear_bit(MT76_READING_STATS, &dev->phy.state); + + mt76_tx_status_check(dev, true); +@@ -644,10 +644,14 @@ int mt76s_init(struct mt76_dev *dev, struct sdio_func *func, + if (err) + return err; + ++ err = mt76_worker_setup(dev->hw, &sdio->stat_worker, mt76s_tx_status_data, ++ "sdio-sta"); ++ if (err) ++ return err; ++ + sched_set_fifo_low(sdio->status_worker.task); + sched_set_fifo_low(sdio->net_worker.task); +- +- INIT_WORK(&sdio->stat_work, mt76s_tx_status_data); ++ sched_set_fifo_low(sdio->stat_worker.task); + + dev->queue_ops = &sdio_queue_ops; + dev->bus = bus_ops; +diff --git a/drivers/net/wireless/purelifi/plfxlc/usb.c b/drivers/net/wireless/purelifi/plfxlc/usb.c +index 76d0a778636a4..311676c1ece0a 100644 +--- a/drivers/net/wireless/purelifi/plfxlc/usb.c ++++ b/drivers/net/wireless/purelifi/plfxlc/usb.c +@@ -493,9 +493,12 @@ int plfxlc_usb_wreq_async(struct plfxlc_usb *usb, const u8 *buffer, + void *context) + { + struct usb_device *udev = interface_to_usbdev(usb->ez_usb); +- struct urb *urb = usb_alloc_urb(0, GFP_ATOMIC); ++ struct urb *urb; + int r; + ++ urb = usb_alloc_urb(0, GFP_ATOMIC); ++ if (!urb) ++ return -ENOMEM; + usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, EP_DATA_OUT), + (void *)buffer, buffer_len, complete_fn, context); + +diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.c b/drivers/net/wireless/realtek/rtlwifi/pci.c +index ca79f652fef3c..6116c1bec1558 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/pci.c ++++ b/drivers/net/wireless/realtek/rtlwifi/pci.c +@@ -164,21 +164,29 @@ static bool _rtl_pci_platform_switch_device_pci_aspm( + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + ++ value &= PCI_EXP_LNKCTL_ASPMC; ++ + if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192SE) +- value |= 0x40; ++ value |= PCI_EXP_LNKCTL_CCC; + +- pci_write_config_byte(rtlpci->pdev, 0x80, value); ++ pcie_capability_clear_and_set_word(rtlpci->pdev, PCI_EXP_LNKCTL, ++ PCI_EXP_LNKCTL_ASPMC | value, ++ value); + + return false; + } + +-/*When we set 0x01 to enable clk request. Set 0x0 to disable clk req.*/ +-static void _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u8 value) ++/* @value is PCI_EXP_LNKCTL_CLKREQ_EN or 0 to enable/disable clk request. */ ++static void _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u16 value) + { + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + +- pci_write_config_byte(rtlpci->pdev, 0x81, value); ++ value &= PCI_EXP_LNKCTL_CLKREQ_EN; ++ ++ pcie_capability_clear_and_set_word(rtlpci->pdev, PCI_EXP_LNKCTL, ++ PCI_EXP_LNKCTL_CLKREQ_EN, ++ value); + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) + udelay(100); +@@ -192,11 +200,8 @@ static void rtl_pci_disable_aspm(struct ieee80211_hw *hw) + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor; +- u8 num4bytes = pcipriv->ndis_adapter.num4bytes; + /*Retrieve original configuration settings. */ + u8 linkctrl_reg = pcipriv->ndis_adapter.linkctrl_reg; +- u16 pcibridge_linkctrlreg = pcipriv->ndis_adapter. +- pcibridge_linkctrlreg; + u16 aspmlevel = 0; + u8 tmp_u1b = 0; + +@@ -221,16 +226,8 @@ static void rtl_pci_disable_aspm(struct ieee80211_hw *hw) + /*Set corresponding value. */ + aspmlevel |= BIT(0) | BIT(1); + linkctrl_reg &= ~aspmlevel; +- pcibridge_linkctrlreg &= ~(BIT(0) | BIT(1)); + + _rtl_pci_platform_switch_device_pci_aspm(hw, linkctrl_reg); +- udelay(50); +- +- /*4 Disable Pci Bridge ASPM */ +- pci_write_config_byte(rtlpci->pdev, (num4bytes << 2), +- pcibridge_linkctrlreg); +- +- udelay(50); + } + + /*Enable RTL8192SE ASPM & Enable Pci Bridge ASPM for +@@ -245,9 +242,7 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw) + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor; +- u8 num4bytes = pcipriv->ndis_adapter.num4bytes; + u16 aspmlevel; +- u8 u_pcibridge_aspmsetting; + u8 u_device_aspmsetting; + + if (!ppsc->support_aspm) +@@ -259,25 +254,6 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw) + return; + } + +- /*4 Enable Pci Bridge ASPM */ +- +- u_pcibridge_aspmsetting = +- pcipriv->ndis_adapter.pcibridge_linkctrlreg | +- rtlpci->const_hostpci_aspm_setting; +- +- if (pcibridge_vendor == PCI_BRIDGE_VENDOR_INTEL) +- u_pcibridge_aspmsetting &= ~BIT(0); +- +- pci_write_config_byte(rtlpci->pdev, (num4bytes << 2), +- u_pcibridge_aspmsetting); +- +- rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, +- "PlatformEnableASPM(): Write reg[%x] = %x\n", +- (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10), +- u_pcibridge_aspmsetting); +- +- udelay(50); +- + /*Get ASPM level (with/without Clock Req) */ + aspmlevel = rtlpci->const_devicepci_aspm_setting; + u_device_aspmsetting = pcipriv->ndis_adapter.linkctrl_reg; +@@ -291,7 +267,8 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw) + + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_CLK_REQ) { + _rtl_pci_switch_clk_req(hw, (ppsc->reg_rfps_level & +- RT_RF_OFF_LEVL_CLK_REQ) ? 1 : 0); ++ RT_RF_OFF_LEVL_CLK_REQ) ? ++ PCI_EXP_LNKCTL_CLKREQ_EN : 0); + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_CLK_REQ); + } + udelay(100); +@@ -358,22 +335,6 @@ static bool rtl_pci_check_buddy_priv(struct ieee80211_hw *hw, + return tpriv != NULL; + } + +-static void rtl_pci_get_linkcontrol_field(struct ieee80211_hw *hw) +-{ +- struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); +- struct rtl_pci *rtlpci = rtl_pcidev(pcipriv); +- u8 capabilityoffset = pcipriv->ndis_adapter.pcibridge_pciehdr_offset; +- u8 linkctrl_reg; +- u8 num4bbytes; +- +- num4bbytes = (capabilityoffset + 0x10) / 4; +- +- /*Read Link Control Register */ +- pci_read_config_byte(rtlpci->pdev, (num4bbytes << 2), &linkctrl_reg); +- +- pcipriv->ndis_adapter.pcibridge_linkctrlreg = linkctrl_reg; +-} +- + static void rtl_pci_parse_configuration(struct pci_dev *pdev, + struct ieee80211_hw *hw) + { +@@ -2033,12 +1994,6 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, + PCI_SLOT(bridge_pdev->devfn); + pcipriv->ndis_adapter.pcibridge_funcnum = + PCI_FUNC(bridge_pdev->devfn); +- pcipriv->ndis_adapter.pcibridge_pciehdr_offset = +- pci_pcie_cap(bridge_pdev); +- pcipriv->ndis_adapter.num4bytes = +- (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10) / 4; +- +- rtl_pci_get_linkcontrol_field(hw); + + if (pcipriv->ndis_adapter.pcibridge_vendor == + PCI_BRIDGE_VENDOR_AMD) { +@@ -2055,13 +2010,11 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, + pdev->vendor, pcipriv->ndis_adapter.linkctrl_reg); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, +- "pci_bridge busnumber:devnumber:funcnumber:vendor:pcie_cap:link_ctl_reg:amd %d:%d:%d:%x:%x:%x:%x\n", ++ "pci_bridge busnumber:devnumber:funcnumber:vendor:amd %d:%d:%d:%x:%x\n", + pcipriv->ndis_adapter.pcibridge_busnum, + pcipriv->ndis_adapter.pcibridge_devnum, + pcipriv->ndis_adapter.pcibridge_funcnum, + pcibridge_vendors[pcipriv->ndis_adapter.pcibridge_vendor], +- pcipriv->ndis_adapter.pcibridge_pciehdr_offset, +- pcipriv->ndis_adapter.pcibridge_linkctrlreg, + pcipriv->ndis_adapter.amd_l1_patch); + + rtl_pci_parse_configuration(pdev, hw); +diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.h b/drivers/net/wireless/realtek/rtlwifi/pci.h +index 866861626a0a1..d6307197dfea0 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/pci.h ++++ b/drivers/net/wireless/realtek/rtlwifi/pci.h +@@ -236,11 +236,6 @@ struct mp_adapter { + u16 pcibridge_vendorid; + u16 pcibridge_deviceid; + +- u8 num4bytes; +- +- u8 pcibridge_pciehdr_offset; +- u8 pcibridge_linkctrlreg; +- + bool amd_l1_patch; + }; + +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/phy.c +index 12d0b3a87af7c..0fab3a0c7d49d 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/phy.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/phy.c +@@ -16,12 +16,6 @@ static u32 _rtl88e_phy_rf_serial_read(struct ieee80211_hw *hw, + static void _rtl88e_phy_rf_serial_write(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset, + u32 data); +-static u32 _rtl88e_phy_calculate_bit_shift(u32 bitmask) +-{ +- u32 i = ffs(bitmask); +- +- return i ? i - 1 : 32; +-} + static bool _rtl88e_phy_bb8188e_config_parafile(struct ieee80211_hw *hw); + static bool _rtl88e_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); + static bool phy_config_bb_with_headerfile(struct ieee80211_hw *hw, +@@ -51,7 +45,7 @@ u32 rtl88e_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x)\n", regaddr, bitmask); + originalvalue = rtl_read_dword(rtlpriv, regaddr); +- bitshift = _rtl88e_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + returnvalue = (originalvalue & bitmask) >> bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, +@@ -74,7 +68,7 @@ void rtl88e_phy_set_bb_reg(struct ieee80211_hw *hw, + + if (bitmask != MASKDWORD) { + originalvalue = rtl_read_dword(rtlpriv, regaddr); +- bitshift = _rtl88e_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + data = ((originalvalue & (~bitmask)) | (data << bitshift)); + } + +@@ -99,7 +93,7 @@ u32 rtl88e_phy_query_rf_reg(struct ieee80211_hw *hw, + + + original_value = _rtl88e_phy_rf_serial_read(hw, rfpath, regaddr); +- bitshift = _rtl88e_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + readback_value = (original_value & bitmask) >> bitshift; + + spin_unlock(&rtlpriv->locks.rf_lock); +@@ -127,7 +121,7 @@ void rtl88e_phy_set_rf_reg(struct ieee80211_hw *hw, + original_value = _rtl88e_phy_rf_serial_read(hw, + rfpath, + regaddr); +- bitshift = _rtl88e_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + data = + ((original_value & (~bitmask)) | + (data << bitshift)); +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.c +index 3d29c8dbb2559..144ee780e1b6a 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.c +@@ -17,7 +17,7 @@ u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n", + regaddr, bitmask); + originalvalue = rtl_read_dword(rtlpriv, regaddr); +- bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + returnvalue = (originalvalue & bitmask) >> bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, +@@ -40,7 +40,7 @@ void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, + + if (bitmask != MASKDWORD) { + originalvalue = rtl_read_dword(rtlpriv, regaddr); +- bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + data = ((originalvalue & (~bitmask)) | (data << bitshift)); + } + +@@ -143,14 +143,6 @@ void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, + } + EXPORT_SYMBOL(_rtl92c_phy_rf_serial_write); + +-u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask) +-{ +- u32 i = ffs(bitmask); +- +- return i ? i - 1 : 32; +-} +-EXPORT_SYMBOL(_rtl92c_phy_calculate_bit_shift); +- + static void _rtl92c_phy_bb_config_1t(struct ieee80211_hw *hw) + { + rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2); +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.h +index 75afa6253ad02..e64d377dfe9e2 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.h ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.h +@@ -196,7 +196,6 @@ bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw, + void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw); + void rtl92c_phy_set_io(struct ieee80211_hw *hw); + void rtl92c_bb_block_on(struct ieee80211_hw *hw); +-u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask); + long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + u8 txpwridx); +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.c +index da54e51badd3a..fa70a7d5539fd 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.c +@@ -39,7 +39,7 @@ u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, + rfpath, regaddr); + } + +- bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + readback_value = (original_value & bitmask) >> bitshift; + + spin_unlock(&rtlpriv->locks.rf_lock); +@@ -110,7 +110,7 @@ void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw, + original_value = _rtl92c_phy_rf_serial_read(hw, + rfpath, + regaddr); +- bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + data = + ((original_value & (~bitmask)) | + (data << bitshift)); +@@ -122,7 +122,7 @@ void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw, + original_value = _rtl92c_phy_fw_rf_serial_read(hw, + rfpath, + regaddr); +- bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + data = + ((original_value & (~bitmask)) | + (data << bitshift)); +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.h +index 7582a162bd112..c7a0d4c776f0a 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.h ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.h +@@ -94,7 +94,6 @@ u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, enum radio_path rfpath, + u32 offset); + u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset); +-u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask); + void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset, u32 data); + void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/phy.c +index a8d9fe269f313..0b8cb7e61fd80 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/phy.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/phy.c +@@ -32,7 +32,7 @@ u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw, + original_value = _rtl92c_phy_fw_rf_serial_read(hw, + rfpath, regaddr); + } +- bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + readback_value = (original_value & bitmask) >> bitshift; + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", +@@ -56,7 +56,7 @@ void rtl92cu_phy_set_rf_reg(struct ieee80211_hw *hw, + original_value = _rtl92c_phy_rf_serial_read(hw, + rfpath, + regaddr); +- bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + data = + ((original_value & (~bitmask)) | + (data << bitshift)); +@@ -67,7 +67,7 @@ void rtl92cu_phy_set_rf_reg(struct ieee80211_hw *hw, + original_value = _rtl92c_phy_fw_rf_serial_read(hw, + rfpath, + regaddr); +- bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + data = + ((original_value & (~bitmask)) | + (data << bitshift)); +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c +index d18c092b61426..d835a27429f0f 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c +@@ -169,13 +169,6 @@ static const u8 channel_all[59] = { + 157, 159, 161, 163, 165 + }; + +-static u32 _rtl92d_phy_calculate_bit_shift(u32 bitmask) +-{ +- u32 i = ffs(bitmask); +- +- return i ? i - 1 : 32; +-} +- + u32 rtl92d_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) + { + struct rtl_priv *rtlpriv = rtl_priv(hw); +@@ -198,7 +191,7 @@ u32 rtl92d_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) + } else { + originalvalue = rtl_read_dword(rtlpriv, regaddr); + } +- bitshift = _rtl92d_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + returnvalue = (originalvalue & bitmask) >> bitshift; + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "BBR MASK=0x%x Addr[0x%x]=0x%x\n", +@@ -230,7 +223,7 @@ void rtl92d_phy_set_bb_reg(struct ieee80211_hw *hw, + dbi_direct); + else + originalvalue = rtl_read_dword(rtlpriv, regaddr); +- bitshift = _rtl92d_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + data = ((originalvalue & (~bitmask)) | (data << bitshift)); + } + if (rtlhal->during_mac1init_radioa || rtlhal->during_mac0init_radiob) +@@ -317,7 +310,7 @@ u32 rtl92d_phy_query_rf_reg(struct ieee80211_hw *hw, + regaddr, rfpath, bitmask); + spin_lock(&rtlpriv->locks.rf_lock); + original_value = _rtl92d_phy_rf_serial_read(hw, rfpath, regaddr); +- bitshift = _rtl92d_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + readback_value = (original_value & bitmask) >> bitshift; + spin_unlock(&rtlpriv->locks.rf_lock); + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, +@@ -343,7 +336,7 @@ void rtl92d_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, + if (bitmask != RFREG_OFFSET_MASK) { + original_value = _rtl92d_phy_rf_serial_read(hw, + rfpath, regaddr); +- bitshift = _rtl92d_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + data = ((original_value & (~bitmask)) | + (data << bitshift)); + } +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/phy.c +index cc0bcaf13e96e..73ef602bfb01a 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/phy.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/phy.c +@@ -16,7 +16,6 @@ static u32 _rtl92ee_phy_rf_serial_read(struct ieee80211_hw *hw, + static void _rtl92ee_phy_rf_serial_write(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset, + u32 data); +-static u32 _rtl92ee_phy_calculate_bit_shift(u32 bitmask); + static bool _rtl92ee_phy_bb8192ee_config_parafile(struct ieee80211_hw *hw); + static bool _rtl92ee_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); + static bool phy_config_bb_with_hdr_file(struct ieee80211_hw *hw, +@@ -46,7 +45,7 @@ u32 rtl92ee_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x)\n", regaddr, bitmask); + originalvalue = rtl_read_dword(rtlpriv, regaddr); +- bitshift = _rtl92ee_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + returnvalue = (originalvalue & bitmask) >> bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, +@@ -68,7 +67,7 @@ void rtl92ee_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, + + if (bitmask != MASKDWORD) { + originalvalue = rtl_read_dword(rtlpriv, regaddr); +- bitshift = _rtl92ee_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + data = ((originalvalue & (~bitmask)) | (data << bitshift)); + } + +@@ -92,7 +91,7 @@ u32 rtl92ee_phy_query_rf_reg(struct ieee80211_hw *hw, + spin_lock(&rtlpriv->locks.rf_lock); + + original_value = _rtl92ee_phy_rf_serial_read(hw , rfpath, regaddr); +- bitshift = _rtl92ee_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + readback_value = (original_value & bitmask) >> bitshift; + + spin_unlock(&rtlpriv->locks.rf_lock); +@@ -119,7 +118,7 @@ void rtl92ee_phy_set_rf_reg(struct ieee80211_hw *hw, + + if (bitmask != RFREG_OFFSET_MASK) { + original_value = _rtl92ee_phy_rf_serial_read(hw, rfpath, addr); +- bitshift = _rtl92ee_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + data = (original_value & (~bitmask)) | (data << bitshift); + } + +@@ -201,13 +200,6 @@ static void _rtl92ee_phy_rf_serial_write(struct ieee80211_hw *hw, + pphyreg->rf3wire_offset, data_and_addr); + } + +-static u32 _rtl92ee_phy_calculate_bit_shift(u32 bitmask) +-{ +- u32 i = ffs(bitmask); +- +- return i ? i - 1 : 32; +-} +- + bool rtl92ee_phy_mac_config(struct ieee80211_hw *hw) + { + return _rtl92ee_phy_config_mac_with_headerfile(hw); +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/phy.c +index aaa004d4d6d0a..0e2b9698088bb 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/phy.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/phy.c +@@ -14,13 +14,6 @@ + #include "hw.h" + #include "table.h" + +-static u32 _rtl92s_phy_calculate_bit_shift(u32 bitmask) +-{ +- u32 i = ffs(bitmask); +- +- return i ? i - 1 : 32; +-} +- + u32 rtl92s_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) + { + struct rtl_priv *rtlpriv = rtl_priv(hw); +@@ -30,7 +23,7 @@ u32 rtl92s_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) + regaddr, bitmask); + + originalvalue = rtl_read_dword(rtlpriv, regaddr); +- bitshift = _rtl92s_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + returnvalue = (originalvalue & bitmask) >> bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "BBR MASK=0x%x Addr[0x%x]=0x%x\n", +@@ -52,7 +45,7 @@ void rtl92s_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask, + + if (bitmask != MASKDWORD) { + originalvalue = rtl_read_dword(rtlpriv, regaddr); +- bitshift = _rtl92s_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + data = ((originalvalue & (~bitmask)) | (data << bitshift)); + } + +@@ -160,7 +153,7 @@ u32 rtl92s_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, + + original_value = _rtl92s_phy_rf_serial_read(hw, rfpath, regaddr); + +- bitshift = _rtl92s_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + readback_value = (original_value & bitmask) >> bitshift; + + spin_unlock(&rtlpriv->locks.rf_lock); +@@ -191,7 +184,7 @@ void rtl92s_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, + if (bitmask != RFREG_OFFSET_MASK) { + original_value = _rtl92s_phy_rf_serial_read(hw, rfpath, + regaddr); +- bitshift = _rtl92s_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + data = ((original_value & (~bitmask)) | (data << bitshift)); + } + +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c +index 5323ead30db03..fa1839d8ee55f 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c +@@ -29,9 +29,10 @@ static void _rtl8821ae_phy_rf_serial_write(struct ieee80211_hw *hw, + u32 data); + static u32 _rtl8821ae_phy_calculate_bit_shift(u32 bitmask) + { +- u32 i = ffs(bitmask); ++ if (WARN_ON_ONCE(!bitmask)) ++ return 0; + +- return i ? i - 1 : 32; ++ return __ffs(bitmask); + } + static bool _rtl8821ae_phy_bb8821a_config_parafile(struct ieee80211_hw *hw); + /*static bool _rtl8812ae_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);*/ +diff --git a/drivers/net/wireless/realtek/rtlwifi/wifi.h b/drivers/net/wireless/realtek/rtlwifi/wifi.h +index 31f9e9e5c6804..0bac788ccd6e3 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/wifi.h ++++ b/drivers/net/wireless/realtek/rtlwifi/wifi.h +@@ -3105,4 +3105,11 @@ static inline struct ieee80211_sta *rtl_find_sta(struct ieee80211_hw *hw, + return ieee80211_find_sta(mac->vif, mac_addr); + } + ++static inline u32 calculate_bit_shift(u32 bitmask) ++{ ++ if (WARN_ON_ONCE(!bitmask)) ++ return 0; ++ ++ return __ffs(bitmask); ++} + #endif +diff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireless/realtek/rtw88/mac80211.c +index fabca307867a0..0970d6bcba439 100644 +--- a/drivers/net/wireless/realtek/rtw88/mac80211.c ++++ b/drivers/net/wireless/realtek/rtw88/mac80211.c +@@ -266,9 +266,9 @@ static void rtw_ops_configure_filter(struct ieee80211_hw *hw, + + if (changed_flags & FIF_ALLMULTI) { + if (*new_flags & FIF_ALLMULTI) +- rtwdev->hal.rcr |= BIT_AM | BIT_AB; ++ rtwdev->hal.rcr |= BIT_AM; + else +- rtwdev->hal.rcr &= ~(BIT_AM | BIT_AB); ++ rtwdev->hal.rcr &= ~(BIT_AM); + } + if (changed_flags & FIF_FCSFAIL) { + if (*new_flags & FIF_FCSFAIL) +diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c +index c3a8d78a41a7b..2716040985748 100644 +--- a/drivers/net/xen-netback/netback.c ++++ b/drivers/net/xen-netback/netback.c +@@ -463,12 +463,25 @@ static void xenvif_get_requests(struct xenvif_queue *queue, + } + + for (shinfo->nr_frags = 0; nr_slots > 0 && shinfo->nr_frags < MAX_SKB_FRAGS; +- shinfo->nr_frags++, gop++, nr_slots--) { ++ nr_slots--) { ++ if (unlikely(!txp->size)) { ++ unsigned long flags; ++ ++ spin_lock_irqsave(&queue->response_lock, flags); ++ make_tx_response(queue, txp, 0, XEN_NETIF_RSP_OKAY); ++ push_tx_responses(queue); ++ spin_unlock_irqrestore(&queue->response_lock, flags); ++ ++txp; ++ continue; ++ } ++ + index = pending_index(queue->pending_cons++); + pending_idx = queue->pending_ring[index]; + xenvif_tx_create_map_op(queue, pending_idx, txp, + txp == first ? extra_count : 0, gop); + frag_set_pending_idx(&frags[shinfo->nr_frags], pending_idx); ++ ++shinfo->nr_frags; ++ ++gop; + + if (txp == first) + txp = txfrags; +@@ -481,20 +494,39 @@ static void xenvif_get_requests(struct xenvif_queue *queue, + shinfo = skb_shinfo(nskb); + frags = shinfo->frags; + +- for (shinfo->nr_frags = 0; shinfo->nr_frags < nr_slots; +- shinfo->nr_frags++, txp++, gop++) { ++ for (shinfo->nr_frags = 0; shinfo->nr_frags < nr_slots; ++txp) { ++ if (unlikely(!txp->size)) { ++ unsigned long flags; ++ ++ spin_lock_irqsave(&queue->response_lock, flags); ++ make_tx_response(queue, txp, 0, ++ XEN_NETIF_RSP_OKAY); ++ push_tx_responses(queue); ++ spin_unlock_irqrestore(&queue->response_lock, ++ flags); ++ continue; ++ } ++ + index = pending_index(queue->pending_cons++); + pending_idx = queue->pending_ring[index]; + xenvif_tx_create_map_op(queue, pending_idx, txp, 0, + gop); + frag_set_pending_idx(&frags[shinfo->nr_frags], + pending_idx); ++ ++shinfo->nr_frags; ++ ++gop; + } + +- skb_shinfo(skb)->frag_list = nskb; +- } else if (nskb) { ++ if (shinfo->nr_frags) { ++ skb_shinfo(skb)->frag_list = nskb; ++ nskb = NULL; ++ } ++ } ++ ++ if (nskb) { + /* A frag_list skb was allocated but it is no longer needed +- * because enough slots were converted to copy ops above. ++ * because enough slots were converted to copy ops above or some ++ * were empty. + */ + kfree_skb(nskb); + } +diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c +index 355d80323b836..ce42afe8f64ef 100644 +--- a/drivers/nvme/target/tcp.c ++++ b/drivers/nvme/target/tcp.c +@@ -18,6 +18,7 @@ + #include "nvmet.h" + + #define NVMET_TCP_DEF_INLINE_DATA_SIZE (4 * PAGE_SIZE) ++#define NVMET_TCP_MAXH2CDATA 0x400000 /* 16M arbitrary limit */ + + /* Define the socket priority to use for connections were it is desirable + * that the NIC consider performing optimized packet processing or filtering. +@@ -861,7 +862,7 @@ static int nvmet_tcp_handle_icreq(struct nvmet_tcp_queue *queue) + icresp->hdr.pdo = 0; + icresp->hdr.plen = cpu_to_le32(icresp->hdr.hlen); + icresp->pfv = cpu_to_le16(NVME_TCP_PFV_1_0); +- icresp->maxdata = cpu_to_le32(0x400000); /* 16M arbitrary limit */ ++ icresp->maxdata = cpu_to_le32(NVMET_TCP_MAXH2CDATA); + icresp->cpda = 0; + if (queue->hdr_digest) + icresp->digest |= NVME_TCP_HDR_DIGEST_ENABLE; +@@ -914,6 +915,7 @@ static int nvmet_tcp_handle_h2c_data_pdu(struct nvmet_tcp_queue *queue) + { + struct nvme_tcp_data_pdu *data = &queue->pdu.data; + struct nvmet_tcp_cmd *cmd; ++ unsigned int exp_data_len; + + if (likely(queue->nr_cmds)) { + if (unlikely(data->ttag >= queue->nr_cmds)) { +@@ -932,12 +934,24 @@ static int nvmet_tcp_handle_h2c_data_pdu(struct nvmet_tcp_queue *queue) + data->ttag, le32_to_cpu(data->data_offset), + cmd->rbytes_done); + /* FIXME: use path and transport errors */ +- nvmet_req_complete(&cmd->req, +- NVME_SC_INVALID_FIELD | NVME_SC_DNR); ++ nvmet_tcp_fatal_error(queue); + return -EPROTO; + } + ++ exp_data_len = le32_to_cpu(data->hdr.plen) - ++ nvmet_tcp_hdgst_len(queue) - ++ nvmet_tcp_ddgst_len(queue) - ++ sizeof(*data); ++ + cmd->pdu_len = le32_to_cpu(data->data_length); ++ if (unlikely(cmd->pdu_len != exp_data_len || ++ cmd->pdu_len == 0 || ++ cmd->pdu_len > NVMET_TCP_MAXH2CDATA)) { ++ pr_err("H2CData PDU len %u is invalid\n", cmd->pdu_len); ++ /* FIXME: use proper transport errors */ ++ nvmet_tcp_fatal_error(queue); ++ return -EPROTO; ++ } + cmd->pdu_recv = 0; + nvmet_tcp_build_pdu_iovec(cmd); + queue->cmd = cmd; +diff --git a/drivers/nvme/target/trace.h b/drivers/nvme/target/trace.h +index 6109b3806b12b..974d99d47f514 100644 +--- a/drivers/nvme/target/trace.h ++++ b/drivers/nvme/target/trace.h +@@ -53,8 +53,7 @@ static inline void __assign_req_name(char *name, struct nvmet_req *req) + return; + } + +- strncpy(name, req->ns->device_path, +- min_t(size_t, DISK_NAME_LEN, strlen(req->ns->device_path))); ++ strscpy_pad(name, req->ns->device_path, DISK_NAME_LEN); + } + #endif + +@@ -85,7 +84,7 @@ TRACE_EVENT(nvmet_req_init, + __entry->flags = cmd->common.flags; + __entry->nsid = le32_to_cpu(cmd->common.nsid); + __entry->metadata = le64_to_cpu(cmd->common.metadata); +- memcpy(__entry->cdw10, &cmd->common.cdw10, ++ memcpy(__entry->cdw10, &cmd->common.cdws, + sizeof(__entry->cdw10)); + ), + TP_printk("nvmet%s: %sqid=%d, cmdid=%u, nsid=%u, flags=%#x, " +diff --git a/drivers/of/base.c b/drivers/of/base.c +index d5a5c35eba72a..f849bbb9ef8c7 100644 +--- a/drivers/of/base.c ++++ b/drivers/of/base.c +@@ -1646,6 +1646,7 @@ int of_parse_phandle_with_args_map(const struct device_node *np, + out_args->np = new; + of_node_put(cur); + cur = new; ++ new = NULL; + } + put: + of_node_put(cur); +diff --git a/drivers/of/unittest-data/tests-phandle.dtsi b/drivers/of/unittest-data/tests-phandle.dtsi +index 6b33be4c4416c..aa0d7027ffa68 100644 +--- a/drivers/of/unittest-data/tests-phandle.dtsi ++++ b/drivers/of/unittest-data/tests-phandle.dtsi +@@ -38,6 +38,13 @@ + phandle-map-pass-thru = <0x0 0xf0>; + }; + ++ provider5: provider5 { ++ #phandle-cells = <2>; ++ phandle-map = <2 7 &provider4 2 3>; ++ phandle-map-mask = <0xff 0xf>; ++ phandle-map-pass-thru = <0x0 0xf0>; ++ }; ++ + consumer-a { + phandle-list = <&provider1 1>, + <&provider2 2 0>, +@@ -64,7 +71,8 @@ + <&provider4 4 0x100>, + <&provider4 0 0x61>, + <&provider0>, +- <&provider4 19 0x20>; ++ <&provider4 19 0x20>, ++ <&provider5 2 7>; + phandle-list-bad-phandle = <12345678 0 0>; + phandle-list-bad-args = <&provider2 1 0>, + <&provider4 0>; +diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c +index edd2342598e49..e541a8960f1de 100644 +--- a/drivers/of/unittest.c ++++ b/drivers/of/unittest.c +@@ -448,6 +448,9 @@ static void __init of_unittest_parse_phandle_with_args(void) + + unittest(passed, "index %i - data error on node %pOF rc=%i\n", + i, args.np, rc); ++ ++ if (rc == 0) ++ of_node_put(args.np); + } + + /* Check for missing list property */ +@@ -537,8 +540,9 @@ static void __init of_unittest_parse_phandle_with_args(void) + + static void __init of_unittest_parse_phandle_with_args_map(void) + { +- struct device_node *np, *p0, *p1, *p2, *p3; ++ struct device_node *np, *p[6] = {}; + struct of_phandle_args args; ++ unsigned int prefs[6]; + int i, rc; + + np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-b"); +@@ -547,34 +551,24 @@ static void __init of_unittest_parse_phandle_with_args_map(void) + return; + } + +- p0 = of_find_node_by_path("/testcase-data/phandle-tests/provider0"); +- if (!p0) { +- pr_err("missing testcase data\n"); +- return; +- } +- +- p1 = of_find_node_by_path("/testcase-data/phandle-tests/provider1"); +- if (!p1) { +- pr_err("missing testcase data\n"); +- return; +- } +- +- p2 = of_find_node_by_path("/testcase-data/phandle-tests/provider2"); +- if (!p2) { +- pr_err("missing testcase data\n"); +- return; +- } +- +- p3 = of_find_node_by_path("/testcase-data/phandle-tests/provider3"); +- if (!p3) { +- pr_err("missing testcase data\n"); +- return; ++ p[0] = of_find_node_by_path("/testcase-data/phandle-tests/provider0"); ++ p[1] = of_find_node_by_path("/testcase-data/phandle-tests/provider1"); ++ p[2] = of_find_node_by_path("/testcase-data/phandle-tests/provider2"); ++ p[3] = of_find_node_by_path("/testcase-data/phandle-tests/provider3"); ++ p[4] = of_find_node_by_path("/testcase-data/phandle-tests/provider4"); ++ p[5] = of_find_node_by_path("/testcase-data/phandle-tests/provider5"); ++ for (i = 0; i < ARRAY_SIZE(p); ++i) { ++ if (!p[i]) { ++ pr_err("missing testcase data\n"); ++ return; ++ } ++ prefs[i] = kref_read(&p[i]->kobj.kref); + } + + rc = of_count_phandle_with_args(np, "phandle-list", "#phandle-cells"); +- unittest(rc == 7, "of_count_phandle_with_args() returned %i, expected 7\n", rc); ++ unittest(rc == 8, "of_count_phandle_with_args() returned %i, expected 8\n", rc); + +- for (i = 0; i < 8; i++) { ++ for (i = 0; i < 9; i++) { + bool passed = true; + + memset(&args, 0, sizeof(args)); +@@ -585,13 +579,13 @@ static void __init of_unittest_parse_phandle_with_args_map(void) + switch (i) { + case 0: + passed &= !rc; +- passed &= (args.np == p1); ++ passed &= (args.np == p[1]); + passed &= (args.args_count == 1); + passed &= (args.args[0] == 1); + break; + case 1: + passed &= !rc; +- passed &= (args.np == p3); ++ passed &= (args.np == p[3]); + passed &= (args.args_count == 3); + passed &= (args.args[0] == 2); + passed &= (args.args[1] == 5); +@@ -602,28 +596,36 @@ static void __init of_unittest_parse_phandle_with_args_map(void) + break; + case 3: + passed &= !rc; +- passed &= (args.np == p0); ++ passed &= (args.np == p[0]); + passed &= (args.args_count == 0); + break; + case 4: + passed &= !rc; +- passed &= (args.np == p1); ++ passed &= (args.np == p[1]); + passed &= (args.args_count == 1); + passed &= (args.args[0] == 3); + break; + case 5: + passed &= !rc; +- passed &= (args.np == p0); ++ passed &= (args.np == p[0]); + passed &= (args.args_count == 0); + break; + case 6: + passed &= !rc; +- passed &= (args.np == p2); ++ passed &= (args.np == p[2]); + passed &= (args.args_count == 2); + passed &= (args.args[0] == 15); + passed &= (args.args[1] == 0x20); + break; + case 7: ++ passed &= !rc; ++ passed &= (args.np == p[3]); ++ passed &= (args.args_count == 3); ++ passed &= (args.args[0] == 2); ++ passed &= (args.args[1] == 5); ++ passed &= (args.args[2] == 3); ++ break; ++ case 8: + passed &= (rc == -ENOENT); + break; + default: +@@ -632,6 +634,9 @@ static void __init of_unittest_parse_phandle_with_args_map(void) + + unittest(passed, "index %i - data error on node %s rc=%i\n", + i, args.np->full_name, rc); ++ ++ if (rc == 0) ++ of_node_put(args.np); + } + + /* Check for missing list property */ +@@ -678,6 +683,13 @@ static void __init of_unittest_parse_phandle_with_args_map(void) + "OF: /testcase-data/phandle-tests/consumer-b: #phandle-cells = 2 found 1"); + + unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc); ++ ++ for (i = 0; i < ARRAY_SIZE(p); ++i) { ++ unittest(prefs[i] == kref_read(&p[i]->kobj.kref), ++ "provider%d: expected:%d got:%d\n", ++ i, prefs[i], kref_read(&p[i]->kobj.kref)); ++ of_node_put(p[i]); ++ } + } + + static void __init of_unittest_property_string(void) +diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c +index d2634dafb68e5..7ecad72cff7e7 100644 +--- a/drivers/pci/controller/dwc/pci-keystone.c ++++ b/drivers/pci/controller/dwc/pci-keystone.c +@@ -1219,7 +1219,16 @@ static int ks_pcie_probe(struct platform_device *pdev) + goto err_link; + } + ++ /* Obtain references to the PHYs */ ++ for (i = 0; i < num_lanes; i++) ++ phy_pm_runtime_get_sync(ks_pcie->phy[i]); ++ + ret = ks_pcie_enable_phy(ks_pcie); ++ ++ /* Release references to the PHYs */ ++ for (i = 0; i < num_lanes; i++) ++ phy_pm_runtime_put_sync(ks_pcie->phy[i]); ++ + if (ret) { + dev_err(dev, "failed to enable phy\n"); + goto err_link; +diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c +index 83ddb190292e4..59c164b5c64aa 100644 +--- a/drivers/pci/controller/dwc/pcie-designware-ep.c ++++ b/drivers/pci/controller/dwc/pcie-designware-ep.c +@@ -600,6 +600,7 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no, + } + + aligned_offset = msg_addr & (epc->mem->window.page_size - 1); ++ msg_addr &= ~aligned_offset; + ret = dw_pcie_ep_map_addr(epc, func_no, 0, ep->msi_mem_phys, msg_addr, + epc->mem->window.page_size); + if (ret) +diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c +index b8612ce5f4d0c..40c38ca5a42e2 100644 +--- a/drivers/pci/controller/pcie-mediatek-gen3.c ++++ b/drivers/pci/controller/pcie-mediatek-gen3.c +@@ -245,35 +245,60 @@ static int mtk_pcie_set_trans_table(struct mtk_gen3_pcie *pcie, + resource_size_t cpu_addr, + resource_size_t pci_addr, + resource_size_t size, +- unsigned long type, int num) ++ unsigned long type, int *num) + { ++ resource_size_t remaining = size; ++ resource_size_t table_size; ++ resource_size_t addr_align; ++ const char *range_type; + void __iomem *table; + u32 val; + +- if (num >= PCIE_MAX_TRANS_TABLES) { +- dev_err(pcie->dev, "not enough translate table for addr: %#llx, limited to [%d]\n", +- (unsigned long long)cpu_addr, PCIE_MAX_TRANS_TABLES); +- return -ENODEV; +- } ++ while (remaining && (*num < PCIE_MAX_TRANS_TABLES)) { ++ /* Table size needs to be a power of 2 */ ++ table_size = BIT(fls(remaining) - 1); ++ ++ if (cpu_addr > 0) { ++ addr_align = BIT(ffs(cpu_addr) - 1); ++ table_size = min(table_size, addr_align); ++ } ++ ++ /* Minimum size of translate table is 4KiB */ ++ if (table_size < 0x1000) { ++ dev_err(pcie->dev, "illegal table size %#llx\n", ++ (unsigned long long)table_size); ++ return -EINVAL; ++ } + +- table = pcie->base + PCIE_TRANS_TABLE_BASE_REG + +- num * PCIE_ATR_TLB_SET_OFFSET; ++ table = pcie->base + PCIE_TRANS_TABLE_BASE_REG + *num * PCIE_ATR_TLB_SET_OFFSET; ++ writel_relaxed(lower_32_bits(cpu_addr) | PCIE_ATR_SIZE(fls(table_size) - 1), table); ++ writel_relaxed(upper_32_bits(cpu_addr), table + PCIE_ATR_SRC_ADDR_MSB_OFFSET); ++ writel_relaxed(lower_32_bits(pci_addr), table + PCIE_ATR_TRSL_ADDR_LSB_OFFSET); ++ writel_relaxed(upper_32_bits(pci_addr), table + PCIE_ATR_TRSL_ADDR_MSB_OFFSET); + +- writel_relaxed(lower_32_bits(cpu_addr) | PCIE_ATR_SIZE(fls(size) - 1), +- table); +- writel_relaxed(upper_32_bits(cpu_addr), +- table + PCIE_ATR_SRC_ADDR_MSB_OFFSET); +- writel_relaxed(lower_32_bits(pci_addr), +- table + PCIE_ATR_TRSL_ADDR_LSB_OFFSET); +- writel_relaxed(upper_32_bits(pci_addr), +- table + PCIE_ATR_TRSL_ADDR_MSB_OFFSET); ++ if (type == IORESOURCE_IO) { ++ val = PCIE_ATR_TYPE_IO | PCIE_ATR_TLP_TYPE_IO; ++ range_type = "IO"; ++ } else { ++ val = PCIE_ATR_TYPE_MEM | PCIE_ATR_TLP_TYPE_MEM; ++ range_type = "MEM"; ++ } + +- if (type == IORESOURCE_IO) +- val = PCIE_ATR_TYPE_IO | PCIE_ATR_TLP_TYPE_IO; +- else +- val = PCIE_ATR_TYPE_MEM | PCIE_ATR_TLP_TYPE_MEM; ++ writel_relaxed(val, table + PCIE_ATR_TRSL_PARAM_OFFSET); + +- writel_relaxed(val, table + PCIE_ATR_TRSL_PARAM_OFFSET); ++ dev_dbg(pcie->dev, "set %s trans window[%d]: cpu_addr = %#llx, pci_addr = %#llx, size = %#llx\n", ++ range_type, *num, (unsigned long long)cpu_addr, ++ (unsigned long long)pci_addr, (unsigned long long)table_size); ++ ++ cpu_addr += table_size; ++ pci_addr += table_size; ++ remaining -= table_size; ++ (*num)++; ++ } ++ ++ if (remaining) ++ dev_warn(pcie->dev, "not enough translate table for addr: %#llx, limited to [%d]\n", ++ (unsigned long long)cpu_addr, PCIE_MAX_TRANS_TABLES); + + return 0; + } +@@ -380,30 +405,20 @@ static int mtk_pcie_startup_port(struct mtk_gen3_pcie *pcie) + resource_size_t cpu_addr; + resource_size_t pci_addr; + resource_size_t size; +- const char *range_type; + +- if (type == IORESOURCE_IO) { ++ if (type == IORESOURCE_IO) + cpu_addr = pci_pio_to_address(res->start); +- range_type = "IO"; +- } else if (type == IORESOURCE_MEM) { ++ else if (type == IORESOURCE_MEM) + cpu_addr = res->start; +- range_type = "MEM"; +- } else { ++ else + continue; +- } + + pci_addr = res->start - entry->offset; + size = resource_size(res); + err = mtk_pcie_set_trans_table(pcie, cpu_addr, pci_addr, size, +- type, table_index); ++ type, &table_index); + if (err) + return err; +- +- dev_dbg(pcie->dev, "set %s trans window[%d]: cpu_addr = %#llx, pci_addr = %#llx, size = %#llx\n", +- range_type, table_index, (unsigned long long)cpu_addr, +- (unsigned long long)pci_addr, (unsigned long long)size); +- +- table_index++; + } + + return 0; +diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c +index ae5ad05ddc1d4..11bdef206d120 100644 +--- a/drivers/pci/controller/pcie-mediatek.c ++++ b/drivers/pci/controller/pcie-mediatek.c +@@ -617,12 +617,18 @@ static void mtk_pcie_intr_handler(struct irq_desc *desc) + if (status & MSI_STATUS){ + unsigned long imsi_status; + ++ /* ++ * The interrupt status can be cleared even if the ++ * MSI status remains pending. As such, given the ++ * edge-triggered interrupt type, its status should ++ * be cleared before being dispatched to the ++ * handler of the underlying device. ++ */ ++ writel(MSI_STATUS, port->base + PCIE_INT_STATUS); + while ((imsi_status = readl(port->base + PCIE_IMSI_STATUS))) { + for_each_set_bit(bit, &imsi_status, MTK_MSI_IRQS_NUM) + generic_handle_domain_irq(port->inner_domain, bit); + } +- /* Clear MSI interrupt status */ +- writel(MSI_STATUS, port->base + PCIE_INT_STATUS); + } + } + +diff --git a/drivers/platform/x86/intel/vsec.c b/drivers/platform/x86/intel/vsec.c +index 483bb65651665..40477d1d41b59 100644 +--- a/drivers/platform/x86/intel/vsec.c ++++ b/drivers/platform/x86/intel/vsec.c +@@ -124,36 +124,60 @@ static void intel_vsec_remove_aux(void *data) + auxiliary_device_uninit(data); + } + ++static DEFINE_MUTEX(vsec_ida_lock); ++ + static void intel_vsec_dev_release(struct device *dev) + { + struct intel_vsec_device *intel_vsec_dev = dev_to_ivdev(dev); + ++ xa_erase(&auxdev_array, intel_vsec_dev->id); ++ ++ mutex_lock(&vsec_ida_lock); + ida_free(intel_vsec_dev->ida, intel_vsec_dev->auxdev.id); ++ mutex_unlock(&vsec_ida_lock); ++ + kfree(intel_vsec_dev->resource); + kfree(intel_vsec_dev); + } + +-static int intel_vsec_add_aux(struct pci_dev *pdev, struct intel_vsec_device *intel_vsec_dev, +- const char *name) ++int intel_vsec_add_aux(struct pci_dev *pdev, struct device *parent, ++ struct intel_vsec_device *intel_vsec_dev, ++ const char *name) + { + struct auxiliary_device *auxdev = &intel_vsec_dev->auxdev; + int ret, id; + +- ret = ida_alloc(intel_vsec_dev->ida, GFP_KERNEL); ++ ret = xa_alloc(&auxdev_array, &intel_vsec_dev->id, intel_vsec_dev, ++ PMT_XA_LIMIT, GFP_KERNEL); + if (ret < 0) { + kfree(intel_vsec_dev->resource); + kfree(intel_vsec_dev); + return ret; + } + +- auxdev->id = ret; ++ mutex_lock(&vsec_ida_lock); ++ id = ida_alloc(intel_vsec_dev->ida, GFP_KERNEL); ++ mutex_unlock(&vsec_ida_lock); ++ if (id < 0) { ++ xa_erase(&auxdev_array, intel_vsec_dev->id); ++ kfree(intel_vsec_dev->resource); ++ kfree(intel_vsec_dev); ++ return id; ++ } ++ ++ if (!parent) ++ parent = &pdev->dev; ++ ++ auxdev->id = id; + auxdev->name = name; +- auxdev->dev.parent = &pdev->dev; ++ auxdev->dev.parent = parent; + auxdev->dev.release = intel_vsec_dev_release; + + ret = auxiliary_device_init(auxdev); + if (ret < 0) { ++ mutex_lock(&vsec_ida_lock); + ida_free(intel_vsec_dev->ida, auxdev->id); ++ mutex_unlock(&vsec_ida_lock); + kfree(intel_vsec_dev->resource); + kfree(intel_vsec_dev); + return ret; +@@ -165,19 +189,14 @@ static int intel_vsec_add_aux(struct pci_dev *pdev, struct intel_vsec_device *in + return ret; + } + +- ret = devm_add_action_or_reset(&pdev->dev, intel_vsec_remove_aux, ++ ret = devm_add_action_or_reset(parent, intel_vsec_remove_aux, + auxdev); + if (ret < 0) + return ret; + +- /* Add auxdev to list */ +- ret = xa_alloc(&auxdev_array, &id, intel_vsec_dev, PMT_XA_LIMIT, +- GFP_KERNEL); +- if (ret) +- return ret; +- + return 0; + } ++EXPORT_SYMBOL_NS_GPL(intel_vsec_add_aux, INTEL_VSEC); + + static int intel_vsec_add_dev(struct pci_dev *pdev, struct intel_vsec_header *header, + struct intel_vsec_platform_info *info) +@@ -235,7 +254,8 @@ static int intel_vsec_add_dev(struct pci_dev *pdev, struct intel_vsec_header *he + else + intel_vsec_dev->ida = &intel_vsec_ida; + +- return intel_vsec_add_aux(pdev, intel_vsec_dev, intel_vsec_name(header->id)); ++ return intel_vsec_add_aux(pdev, NULL, intel_vsec_dev, ++ intel_vsec_name(header->id)); + } + + static bool intel_vsec_walk_header(struct pci_dev *pdev, +diff --git a/drivers/platform/x86/intel/vsec.h b/drivers/platform/x86/intel/vsec.h +index 3deeb05cf394d..330672588868d 100644 +--- a/drivers/platform/x86/intel/vsec.h ++++ b/drivers/platform/x86/intel/vsec.h +@@ -38,8 +38,15 @@ struct intel_vsec_device { + struct ida *ida; + struct intel_vsec_platform_info *info; + int num_resources; ++ int id; /* xa */ ++ void *priv_data; ++ size_t priv_data_size; + }; + ++int intel_vsec_add_aux(struct pci_dev *pdev, struct device *parent, ++ struct intel_vsec_device *intel_vsec_dev, ++ const char *name); ++ + static inline struct intel_vsec_device *dev_to_ivdev(struct device *dev) + { + return container_of(dev, struct intel_vsec_device, auxdev.dev); +diff --git a/drivers/power/supply/bq256xx_charger.c b/drivers/power/supply/bq256xx_charger.c +index 01ad84fd147c8..686eb8d86e221 100644 +--- a/drivers/power/supply/bq256xx_charger.c ++++ b/drivers/power/supply/bq256xx_charger.c +@@ -1514,13 +1514,16 @@ static int bq256xx_hw_init(struct bq256xx_device *bq) + wd_reg_val = i; + break; + } +- if (bq->watchdog_timer > bq256xx_watchdog_time[i] && ++ if (i + 1 < BQ256XX_NUM_WD_VAL && ++ bq->watchdog_timer > bq256xx_watchdog_time[i] && + bq->watchdog_timer < bq256xx_watchdog_time[i + 1]) + wd_reg_val = i; + } + ret = regmap_update_bits(bq->regmap, BQ256XX_CHARGER_CONTROL_1, + BQ256XX_WATCHDOG_MASK, wd_reg_val << + BQ256XX_WDT_BIT_SHIFT); ++ if (ret) ++ return ret; + + ret = power_supply_get_battery_info(bq->charger, &bat_info); + if (ret == -ENOMEM) +diff --git a/drivers/power/supply/cw2015_battery.c b/drivers/power/supply/cw2015_battery.c +index 473522b4326ad..9d957cf8edf07 100644 +--- a/drivers/power/supply/cw2015_battery.c ++++ b/drivers/power/supply/cw2015_battery.c +@@ -491,7 +491,7 @@ static int cw_battery_get_property(struct power_supply *psy, + + case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW: + if (cw_battery_valid_time_to_empty(cw_bat)) +- val->intval = cw_bat->time_to_empty; ++ val->intval = cw_bat->time_to_empty * 60; + else + val->intval = 0; + break; +diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c +index d333e7422f4a9..9726f96bf7635 100644 +--- a/drivers/pwm/core.c ++++ b/drivers/pwm/core.c +@@ -171,7 +171,7 @@ of_pwm_single_xlate(struct pwm_chip *pc, const struct of_phandle_args *args) + pwm->args.period = args->args[0]; + pwm->args.polarity = PWM_POLARITY_NORMAL; + +- if (args->args_count == 2 && args->args[2] & PWM_POLARITY_INVERTED) ++ if (args->args_count == 2 && args->args[1] & PWM_POLARITY_INVERTED) + pwm->args.polarity = PWM_POLARITY_INVERSED; + + return pwm; +diff --git a/drivers/pwm/pwm-jz4740.c b/drivers/pwm/pwm-jz4740.c +index a5fdf97c0d2ec..246499128142c 100644 +--- a/drivers/pwm/pwm-jz4740.c ++++ b/drivers/pwm/pwm-jz4740.c +@@ -60,9 +60,10 @@ static int jz4740_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) + snprintf(name, sizeof(name), "timer%u", pwm->hwpwm); + + clk = clk_get(chip->dev, name); +- if (IS_ERR(clk)) +- return dev_err_probe(chip->dev, PTR_ERR(clk), +- "Failed to get clock\n"); ++ if (IS_ERR(clk)) { ++ dev_err(chip->dev, "error %pe: Failed to get clock\n", clk); ++ return PTR_ERR(clk); ++ } + + err = clk_prepare_enable(clk); + if (err < 0) { +diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c +index 794ca5b029681..bdcdb7f38312b 100644 +--- a/drivers/pwm/pwm-stm32.c ++++ b/drivers/pwm/pwm-stm32.c +@@ -115,14 +115,14 @@ static int stm32_pwm_raw_capture(struct stm32_pwm *priv, struct pwm_device *pwm, + int ret; + + /* Ensure registers have been updated, enable counter and capture */ +- regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG); +- regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, TIM_CR1_CEN); ++ regmap_set_bits(priv->regmap, TIM_EGR, TIM_EGR_UG); ++ regmap_set_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN); + + /* Use cc1 or cc3 DMA resp for PWM input channels 1 & 2 or 3 & 4 */ + dma_id = pwm->hwpwm < 2 ? STM32_TIMERS_DMA_CH1 : STM32_TIMERS_DMA_CH3; + ccen = pwm->hwpwm < 2 ? TIM_CCER_CC12E : TIM_CCER_CC34E; + ccr = pwm->hwpwm < 2 ? TIM_CCR1 : TIM_CCR3; +- regmap_update_bits(priv->regmap, TIM_CCER, ccen, ccen); ++ regmap_set_bits(priv->regmap, TIM_CCER, ccen); + + /* + * Timer DMA burst mode. Request 2 registers, 2 bursts, to get both +@@ -160,8 +160,8 @@ static int stm32_pwm_raw_capture(struct stm32_pwm *priv, struct pwm_device *pwm, + } + + stop: +- regmap_update_bits(priv->regmap, TIM_CCER, ccen, 0); +- regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0); ++ regmap_clear_bits(priv->regmap, TIM_CCER, ccen); ++ regmap_clear_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN); + + return ret; + } +@@ -359,7 +359,7 @@ static int stm32_pwm_config(struct stm32_pwm *priv, int ch, + + regmap_write(priv->regmap, TIM_PSC, prescaler); + regmap_write(priv->regmap, TIM_ARR, prd - 1); +- regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, TIM_CR1_ARPE); ++ regmap_set_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE); + + /* Calculate the duty cycles */ + dty = prd * duty_ns; +@@ -377,7 +377,7 @@ static int stm32_pwm_config(struct stm32_pwm *priv, int ch, + else + regmap_update_bits(priv->regmap, TIM_CCMR2, mask, ccmr); + +- regmap_update_bits(priv->regmap, TIM_BDTR, TIM_BDTR_MOE, TIM_BDTR_MOE); ++ regmap_set_bits(priv->regmap, TIM_BDTR, TIM_BDTR_MOE); + + return 0; + } +@@ -411,13 +411,13 @@ static int stm32_pwm_enable(struct stm32_pwm *priv, int ch) + if (priv->have_complementary_output) + mask |= TIM_CCER_CC1NE << (ch * 4); + +- regmap_update_bits(priv->regmap, TIM_CCER, mask, mask); ++ regmap_set_bits(priv->regmap, TIM_CCER, mask); + + /* Make sure that registers are updated */ +- regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG); ++ regmap_set_bits(priv->regmap, TIM_EGR, TIM_EGR_UG); + + /* Enable controller */ +- regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, TIM_CR1_CEN); ++ regmap_set_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN); + + return 0; + } +@@ -431,11 +431,11 @@ static void stm32_pwm_disable(struct stm32_pwm *priv, int ch) + if (priv->have_complementary_output) + mask |= TIM_CCER_CC1NE << (ch * 4); + +- regmap_update_bits(priv->regmap, TIM_CCER, mask, 0); ++ regmap_clear_bits(priv->regmap, TIM_CCER, mask); + + /* When all channels are disabled, we can disable the controller */ + if (!active_channels(priv)) +- regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0); ++ regmap_clear_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN); + + clk_disable(priv->clk); + } +@@ -568,41 +568,30 @@ static void stm32_pwm_detect_complementary(struct stm32_pwm *priv) + * If complementary bit doesn't exist writing 1 will have no + * effect so we can detect it. + */ +- regmap_update_bits(priv->regmap, +- TIM_CCER, TIM_CCER_CC1NE, TIM_CCER_CC1NE); ++ regmap_set_bits(priv->regmap, TIM_CCER, TIM_CCER_CC1NE); + regmap_read(priv->regmap, TIM_CCER, &ccer); +- regmap_update_bits(priv->regmap, TIM_CCER, TIM_CCER_CC1NE, 0); ++ regmap_clear_bits(priv->regmap, TIM_CCER, TIM_CCER_CC1NE); + + priv->have_complementary_output = (ccer != 0); + } + +-static int stm32_pwm_detect_channels(struct stm32_pwm *priv) ++static unsigned int stm32_pwm_detect_channels(struct stm32_pwm *priv, ++ unsigned int *num_enabled) + { +- u32 ccer; +- int npwm = 0; ++ u32 ccer, ccer_backup; + + /* + * If channels enable bits don't exist writing 1 will have no + * effect so we can detect and count them. + */ +- regmap_update_bits(priv->regmap, +- TIM_CCER, TIM_CCER_CCXE, TIM_CCER_CCXE); ++ regmap_read(priv->regmap, TIM_CCER, &ccer_backup); ++ regmap_set_bits(priv->regmap, TIM_CCER, TIM_CCER_CCXE); + regmap_read(priv->regmap, TIM_CCER, &ccer); +- regmap_update_bits(priv->regmap, TIM_CCER, TIM_CCER_CCXE, 0); +- +- if (ccer & TIM_CCER_CC1E) +- npwm++; ++ regmap_write(priv->regmap, TIM_CCER, ccer_backup); + +- if (ccer & TIM_CCER_CC2E) +- npwm++; ++ *num_enabled = hweight32(ccer_backup & TIM_CCER_CCXE); + +- if (ccer & TIM_CCER_CC3E) +- npwm++; +- +- if (ccer & TIM_CCER_CC4E) +- npwm++; +- +- return npwm; ++ return hweight32(ccer & TIM_CCER_CCXE); + } + + static int stm32_pwm_probe(struct platform_device *pdev) +@@ -611,6 +600,8 @@ static int stm32_pwm_probe(struct platform_device *pdev) + struct device_node *np = dev->of_node; + struct stm32_timers *ddata = dev_get_drvdata(pdev->dev.parent); + struct stm32_pwm *priv; ++ unsigned int num_enabled; ++ unsigned int i; + int ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); +@@ -633,7 +624,11 @@ static int stm32_pwm_probe(struct platform_device *pdev) + + priv->chip.dev = dev; + priv->chip.ops = &stm32pwm_ops; +- priv->chip.npwm = stm32_pwm_detect_channels(priv); ++ priv->chip.npwm = stm32_pwm_detect_channels(priv, &num_enabled); ++ ++ /* Initialize clock refcount to number of enabled PWM channels. */ ++ for (i = 0; i < num_enabled; i++) ++ clk_enable(priv->clk); + + ret = pwmchip_add(&priv->chip); + if (ret < 0) +diff --git a/drivers/scsi/fnic/fnic_debugfs.c b/drivers/scsi/fnic/fnic_debugfs.c +index 6fedc3b7d1ab2..eb895a65ea8fc 100644 +--- a/drivers/scsi/fnic/fnic_debugfs.c ++++ b/drivers/scsi/fnic/fnic_debugfs.c +@@ -52,9 +52,10 @@ int fnic_debugfs_init(void) + fc_trc_flag->fnic_trace = 2; + fc_trc_flag->fc_trace = 3; + fc_trc_flag->fc_clear = 4; ++ return 0; + } + +- return 0; ++ return -ENOMEM; + } + + /* +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index a8142e2b96435..450a8578157cb 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -1502,12 +1502,12 @@ EXPORT_SYMBOL_GPL(hisi_sas_controller_reset_done); + static int hisi_sas_controller_prereset(struct hisi_hba *hisi_hba) + { + if (!hisi_hba->hw->soft_reset) +- return -1; ++ return -ENOENT; + + down(&hisi_hba->sem); + if (test_and_set_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags)) { + up(&hisi_hba->sem); +- return -1; ++ return -EPERM; + } + + if (hisi_sas_debugfs_enable && hisi_hba->debugfs_itct[0].itct) +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index c4305ec38ebf3..0c80ff9affa39 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -3330,7 +3330,7 @@ static void debugfs_snapshot_global_reg_v3_hw(struct hisi_hba *hisi_hba) + u32 *databuf = hisi_hba->debugfs_regs[dump_index][DEBUGFS_GLOBAL].data; + int i; + +- for (i = 0; i < debugfs_axi_reg.count; i++, databuf++) ++ for (i = 0; i < debugfs_global_reg.count; i++, databuf++) + *databuf = hisi_sas_read32(hisi_hba, 4 * i); + } + +@@ -4946,6 +4946,7 @@ static void hisi_sas_reset_done_v3_hw(struct pci_dev *pdev) + { + struct sas_ha_struct *sha = pci_get_drvdata(pdev); + struct hisi_hba *hisi_hba = sha->lldd_ha; ++ struct Scsi_Host *shost = hisi_hba->shost; + struct device *dev = hisi_hba->dev; + int rc; + +@@ -4954,6 +4955,10 @@ static void hisi_sas_reset_done_v3_hw(struct pci_dev *pdev) + rc = hw_init_v3_hw(hisi_hba); + if (rc) { + dev_err(dev, "FLR: hw init failed rc=%d\n", rc); ++ clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags); ++ scsi_unblock_requests(shost); ++ clear_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags); ++ up(&hisi_hba->sem); + return; + } + +@@ -4981,7 +4986,7 @@ static int _suspend_v3_hw(struct device *device) + } + + if (test_and_set_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags)) +- return -1; ++ return -EPERM; + + dev_warn(dev, "entering suspend state\n"); + +diff --git a/drivers/scsi/mpi3mr/mpi3mr_app.c b/drivers/scsi/mpi3mr/mpi3mr_app.c +index d10c6afb7f9cd..8c662d08706f1 100644 +--- a/drivers/scsi/mpi3mr/mpi3mr_app.c ++++ b/drivers/scsi/mpi3mr/mpi3mr_app.c +@@ -223,6 +223,22 @@ static long mpi3mr_bsg_pel_enable(struct mpi3mr_ioc *mrioc, + return rval; + } + ++ if (mrioc->unrecoverable) { ++ dprint_bsg_err(mrioc, "%s: unrecoverable controller\n", ++ __func__); ++ return -EFAULT; ++ } ++ ++ if (mrioc->reset_in_progress) { ++ dprint_bsg_err(mrioc, "%s: reset in progress\n", __func__); ++ return -EAGAIN; ++ } ++ ++ if (mrioc->stop_bsgs) { ++ dprint_bsg_err(mrioc, "%s: bsgs are blocked\n", __func__); ++ return -EAGAIN; ++ } ++ + sg_copy_to_buffer(job->request_payload.sg_list, + job->request_payload.sg_cnt, + &pel_enable, sizeof(pel_enable)); +diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c +index 6d55698ea4d16..85f5b349c7e43 100644 +--- a/drivers/scsi/mpi3mr/mpi3mr_os.c ++++ b/drivers/scsi/mpi3mr/mpi3mr_os.c +@@ -1044,8 +1044,14 @@ void mpi3mr_rfresh_tgtdevs(struct mpi3mr_ioc *mrioc) + tgtdev = NULL; + list_for_each_entry(tgtdev, &mrioc->tgtdev_list, list) { + if ((tgtdev->dev_handle != MPI3MR_INVALID_DEV_HANDLE) && +- !tgtdev->is_hidden && !tgtdev->host_exposed) +- mpi3mr_report_tgtdev_to_host(mrioc, tgtdev->perst_id); ++ !tgtdev->is_hidden) { ++ if (!tgtdev->host_exposed) ++ mpi3mr_report_tgtdev_to_host(mrioc, ++ tgtdev->perst_id); ++ else if (tgtdev->starget) ++ starget_for_each_device(tgtdev->starget, ++ (void *)tgtdev, mpi3mr_update_sdev); ++ } + } + } + +diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c +index bc400669ee022..16a05143d0d62 100644 +--- a/drivers/soc/qcom/llcc-qcom.c ++++ b/drivers/soc/qcom/llcc-qcom.c +@@ -680,14 +680,14 @@ static int _qcom_llcc_cfg_program(const struct llcc_slice_config *config, + u32 disable_cap_alloc, retain_pc; + + disable_cap_alloc = config->dis_cap_alloc << config->slice_id; +- ret = regmap_write(drv_data->bcast_regmap, +- LLCC_TRP_SCID_DIS_CAP_ALLOC, disable_cap_alloc); ++ ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_SCID_DIS_CAP_ALLOC, ++ BIT(config->slice_id), disable_cap_alloc); + if (ret) + return ret; + + retain_pc = config->retain_on_pc << config->slice_id; +- ret = regmap_write(drv_data->bcast_regmap, +- LLCC_TRP_PCB_ACT, retain_pc); ++ ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_PCB_ACT, ++ BIT(config->slice_id), retain_pc); + if (ret) + return ret; + } +diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig +index 946e2186d2448..15ea11ebcbe09 100644 +--- a/drivers/spi/Kconfig ++++ b/drivers/spi/Kconfig +@@ -1101,9 +1101,10 @@ config SPI_ZYNQ_QSPI + + config SPI_ZYNQMP_GQSPI + tristate "Xilinx ZynqMP GQSPI controller" +- depends on (SPI_MASTER && HAS_DMA) || COMPILE_TEST ++ depends on (SPI_MEM && HAS_DMA) || COMPILE_TEST + help + Enables Xilinx GQSPI controller driver for Zynq UltraScale+ MPSoC. ++ This controller only supports SPI memory interface. + + config SPI_AMD + tristate "AMD SPI controller" +diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c +index 9bca3d076f053..51ceaa4857249 100644 +--- a/drivers/spi/spi-sh-msiof.c ++++ b/drivers/spi/spi-sh-msiof.c +@@ -30,12 +30,15 @@ + + #include <asm/unaligned.h> + ++#define SH_MSIOF_FLAG_FIXED_DTDL_200 BIT(0) ++ + struct sh_msiof_chipdata { + u32 bits_per_word_mask; + u16 tx_fifo_size; + u16 rx_fifo_size; + u16 ctlr_flags; + u16 min_div_pow; ++ u32 flags; + }; + + struct sh_msiof_spi_priv { +@@ -1073,6 +1076,16 @@ static const struct sh_msiof_chipdata rcar_gen3_data = { + .min_div_pow = 1, + }; + ++static const struct sh_msiof_chipdata rcar_r8a7795_data = { ++ .bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16) | ++ SPI_BPW_MASK(24) | SPI_BPW_MASK(32), ++ .tx_fifo_size = 64, ++ .rx_fifo_size = 64, ++ .ctlr_flags = SPI_CONTROLLER_MUST_TX, ++ .min_div_pow = 1, ++ .flags = SH_MSIOF_FLAG_FIXED_DTDL_200, ++}; ++ + static const struct of_device_id sh_msiof_match[] = { + { .compatible = "renesas,sh-mobile-msiof", .data = &sh_data }, + { .compatible = "renesas,msiof-r8a7743", .data = &rcar_gen2_data }, +@@ -1083,6 +1096,7 @@ static const struct of_device_id sh_msiof_match[] = { + { .compatible = "renesas,msiof-r8a7793", .data = &rcar_gen2_data }, + { .compatible = "renesas,msiof-r8a7794", .data = &rcar_gen2_data }, + { .compatible = "renesas,rcar-gen2-msiof", .data = &rcar_gen2_data }, ++ { .compatible = "renesas,msiof-r8a7795", .data = &rcar_r8a7795_data }, + { .compatible = "renesas,msiof-r8a7796", .data = &rcar_gen3_data }, + { .compatible = "renesas,rcar-gen3-msiof", .data = &rcar_gen3_data }, + { .compatible = "renesas,rcar-gen4-msiof", .data = &rcar_gen3_data }, +@@ -1280,6 +1294,9 @@ static int sh_msiof_spi_probe(struct platform_device *pdev) + return -ENXIO; + } + ++ if (chipdata->flags & SH_MSIOF_FLAG_FIXED_DTDL_200) ++ info->dtdl = 200; ++ + if (info->mode == MSIOF_SPI_SLAVE) + ctlr = spi_alloc_slave(&pdev->dev, + sizeof(struct sh_msiof_spi_priv)); +diff --git a/drivers/spmi/spmi-mtk-pmif.c b/drivers/spmi/spmi-mtk-pmif.c +index ad511f2c3324e..01e8851e639d5 100644 +--- a/drivers/spmi/spmi-mtk-pmif.c ++++ b/drivers/spmi/spmi-mtk-pmif.c +@@ -50,6 +50,7 @@ struct pmif { + struct clk_bulk_data clks[PMIF_MAX_CLKS]; + size_t nclks; + const struct pmif_data *data; ++ raw_spinlock_t lock; + }; + + static const char * const pmif_clock_names[] = { +@@ -314,6 +315,7 @@ static int pmif_spmi_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, + struct ch_reg *inf_reg; + int ret; + u32 data, cmd; ++ unsigned long flags; + + /* Check for argument validation. */ + if (sid & ~0xf) { +@@ -334,6 +336,7 @@ static int pmif_spmi_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, + else + return -EINVAL; + ++ raw_spin_lock_irqsave(&arb->lock, flags); + /* Wait for Software Interface FSM state to be IDLE. */ + inf_reg = &arb->chan; + ret = readl_poll_timeout_atomic(arb->base + arb->data->regs[inf_reg->ch_sta], +@@ -343,6 +346,7 @@ static int pmif_spmi_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, + /* set channel ready if the data has transferred */ + if (pmif_is_fsm_vldclr(arb)) + pmif_writel(arb, 1, inf_reg->ch_rdy); ++ raw_spin_unlock_irqrestore(&arb->lock, flags); + dev_err(&ctrl->dev, "failed to wait for SWINF_IDLE\n"); + return ret; + } +@@ -350,6 +354,7 @@ static int pmif_spmi_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, + /* Send the command. */ + cmd = (opc << 30) | (sid << 24) | ((len - 1) << 16) | addr; + pmif_writel(arb, cmd, inf_reg->ch_send); ++ raw_spin_unlock_irqrestore(&arb->lock, flags); + + /* + * Wait for Software Interface FSM state to be WFVLDCLR, +@@ -376,7 +381,8 @@ static int pmif_spmi_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, + struct pmif *arb = spmi_controller_get_drvdata(ctrl); + struct ch_reg *inf_reg; + int ret; +- u32 data, cmd; ++ u32 data, wdata, cmd; ++ unsigned long flags; + + if (len > 4) { + dev_err(&ctrl->dev, "pmif supports 1..4 bytes per trans, but:%zu requested", len); +@@ -394,6 +400,10 @@ static int pmif_spmi_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, + else + return -EINVAL; + ++ /* Set the write data. */ ++ memcpy(&wdata, buf, len); ++ ++ raw_spin_lock_irqsave(&arb->lock, flags); + /* Wait for Software Interface FSM state to be IDLE. */ + inf_reg = &arb->chan; + ret = readl_poll_timeout_atomic(arb->base + arb->data->regs[inf_reg->ch_sta], +@@ -403,17 +413,17 @@ static int pmif_spmi_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, + /* set channel ready if the data has transferred */ + if (pmif_is_fsm_vldclr(arb)) + pmif_writel(arb, 1, inf_reg->ch_rdy); ++ raw_spin_unlock_irqrestore(&arb->lock, flags); + dev_err(&ctrl->dev, "failed to wait for SWINF_IDLE\n"); + return ret; + } + +- /* Set the write data. */ +- memcpy(&data, buf, len); +- pmif_writel(arb, data, inf_reg->wdata); ++ pmif_writel(arb, wdata, inf_reg->wdata); + + /* Send the command. */ + cmd = (opc << 30) | BIT(29) | (sid << 24) | ((len - 1) << 16) | addr; + pmif_writel(arb, cmd, inf_reg->ch_send); ++ raw_spin_unlock_irqrestore(&arb->lock, flags); + + return 0; + } +@@ -488,6 +498,8 @@ static int mtk_spmi_probe(struct platform_device *pdev) + arb->chan.ch_send = PMIF_SWINF_0_ACC + chan_offset; + arb->chan.ch_rdy = PMIF_SWINF_0_VLD_CLR + chan_offset; + ++ raw_spin_lock_init(&arb->lock); ++ + platform_set_drvdata(pdev, ctrl); + + err = spmi_controller_add(ctrl); +diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c +index a9bd1e71ea487..d16cf4115d03a 100644 +--- a/drivers/staging/media/rkvdec/rkvdec.c ++++ b/drivers/staging/media/rkvdec/rkvdec.c +@@ -461,6 +461,9 @@ static const struct v4l2_ioctl_ops rkvdec_ioctl_ops = { + + .vidioc_streamon = v4l2_m2m_ioctl_streamon, + .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, ++ ++ .vidioc_decoder_cmd = v4l2_m2m_ioctl_stateless_decoder_cmd, ++ .vidioc_try_decoder_cmd = v4l2_m2m_ioctl_stateless_try_decoder_cmd, + }; + + static int rkvdec_queue_setup(struct vb2_queue *vq, unsigned int *num_buffers, +diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c +index 7e81a53dbf3ca..8d74e97c98748 100644 +--- a/drivers/target/target_core_file.c ++++ b/drivers/target/target_core_file.c +@@ -338,11 +338,13 @@ static int fd_do_rw(struct se_cmd *cmd, struct file *fd, + } + + iov_iter_bvec(&iter, is_write, bvec, sgl_nents, len); +- if (is_write) ++ if (is_write) { ++ file_start_write(fd); + ret = vfs_iter_write(fd, &iter, &pos, 0); +- else ++ file_end_write(fd); ++ } else { + ret = vfs_iter_read(fd, &iter, &pos, 0); +- ++ } + if (is_write) { + if (ret < 0 || ret != data_length) { + pr_err("%s() write returned %d\n", __func__, ret); +@@ -474,7 +476,9 @@ fd_execute_write_same(struct se_cmd *cmd) + } + + iov_iter_bvec(&iter, ITER_SOURCE, bvec, nolb, len); ++ file_start_write(fd_dev->fd_file); + ret = vfs_iter_write(fd_dev->fd_file, &iter, &pos, 0); ++ file_end_write(fd_dev->fd_file); + + kfree(bvec); + if (ret < 0 || ret != len) { +diff --git a/drivers/tty/serial/8250/8250_bcm2835aux.c b/drivers/tty/serial/8250/8250_bcm2835aux.c +index 15a2387a5b258..4f4502fb5454c 100644 +--- a/drivers/tty/serial/8250/8250_bcm2835aux.c ++++ b/drivers/tty/serial/8250/8250_bcm2835aux.c +@@ -119,6 +119,8 @@ static int bcm2835aux_serial_probe(struct platform_device *pdev) + + /* get the clock - this also enables the HW */ + data->clk = devm_clk_get_optional(&pdev->dev, NULL); ++ if (IS_ERR(data->clk)) ++ return dev_err_probe(&pdev->dev, PTR_ERR(data->clk), "could not get clk\n"); + + /* get the interrupt */ + ret = platform_get_irq(pdev, 0); +diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c +index b406cba10b0eb..dca1abe363248 100644 +--- a/drivers/tty/serial/8250/8250_exar.c ++++ b/drivers/tty/serial/8250/8250_exar.c +@@ -442,7 +442,7 @@ static int generic_rs485_config(struct uart_port *port, struct ktermios *termios + } + + static const struct serial_rs485 generic_rs485_supported = { +- .flags = SER_RS485_ENABLED, ++ .flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND, + }; + + static const struct exar8250_platform exar8250_default_platform = { +@@ -486,7 +486,8 @@ static int iot2040_rs485_config(struct uart_port *port, struct ktermios *termios + } + + static const struct serial_rs485 iot2040_rs485_supported = { +- .flags = SER_RS485_ENABLED | SER_RS485_RX_DURING_TX | SER_RS485_TERMINATE_BUS, ++ .flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND | ++ SER_RS485_RX_DURING_TX | SER_RS485_TERMINATE_BUS, + }; + + static const struct property_entry iot2040_gpio_properties[] = { +diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c +index 0b04d810b3e61..037d613006f56 100644 +--- a/drivers/tty/serial/8250/8250_omap.c ++++ b/drivers/tty/serial/8250/8250_omap.c +@@ -1476,7 +1476,7 @@ static int omap8250_remove(struct platform_device *pdev) + + err = pm_runtime_resume_and_get(&pdev->dev); + if (err) +- return err; ++ dev_err(&pdev->dev, "Failed to resume hardware\n"); + + serial8250_unregister_port(priv->line); + priv->line = -ENODEV; +diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c +index d2137f6eff327..f8962a3d44216 100644 +--- a/drivers/tty/serial/imx.c ++++ b/drivers/tty/serial/imx.c +@@ -450,13 +450,13 @@ static void imx_uart_stop_tx(struct uart_port *port) + ucr1 = imx_uart_readl(sport, UCR1); + imx_uart_writel(sport, ucr1 & ~UCR1_TRDYEN, UCR1); + ++ ucr4 = imx_uart_readl(sport, UCR4); + usr2 = imx_uart_readl(sport, USR2); +- if (!(usr2 & USR2_TXDC)) { ++ if ((!(usr2 & USR2_TXDC)) && (ucr4 & UCR4_TCEN)) { + /* The shifter is still busy, so retry once TC triggers */ + return; + } + +- ucr4 = imx_uart_readl(sport, UCR4); + ucr4 &= ~UCR4_TCEN; + imx_uart_writel(sport, ucr4, UCR4); + +@@ -2229,7 +2229,6 @@ static enum hrtimer_restart imx_trigger_stop_tx(struct hrtimer *t) + return HRTIMER_NORESTART; + } + +-static const struct serial_rs485 imx_no_rs485 = {}; /* No RS485 if no RTS */ + static const struct serial_rs485 imx_rs485_supported = { + .flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND | SER_RS485_RTS_AFTER_SEND | + SER_RS485_RX_DURING_TX, +@@ -2319,8 +2318,6 @@ static int imx_uart_probe(struct platform_device *pdev) + /* RTS is required to control the RS485 transmitter */ + if (sport->have_rtscts || sport->have_rtsgpio) + sport->port.rs485_supported = imx_rs485_supported; +- else +- sport->port.rs485_supported = imx_no_rs485; + sport->port.flags = UPF_BOOT_AUTOCONF; + timer_setup(&sport->timer, imx_uart_timeout, 0); + +@@ -2347,7 +2344,7 @@ static int imx_uart_probe(struct platform_device *pdev) + /* For register access, we only need to enable the ipg clock. */ + ret = clk_prepare_enable(sport->clk_ipg); + if (ret) { +- dev_err(&pdev->dev, "failed to enable per clk: %d\n", ret); ++ dev_err(&pdev->dev, "failed to enable ipg clk: %d\n", ret); + return ret; + } + +@@ -2359,14 +2356,8 @@ static int imx_uart_probe(struct platform_device *pdev) + sport->ufcr = readl(sport->port.membase + UFCR); + + ret = uart_get_rs485_mode(&sport->port); +- if (ret) { +- clk_disable_unprepare(sport->clk_ipg); +- return ret; +- } +- +- if (sport->port.rs485.flags & SER_RS485_ENABLED && +- (!sport->have_rtscts && !sport->have_rtsgpio)) +- dev_err(&pdev->dev, "no RTS control, disabling rs485\n"); ++ if (ret) ++ goto err_clk; + + /* + * If using the i.MX UART RTS/CTS control then the RTS (CTS_B) +@@ -2446,8 +2437,6 @@ static int imx_uart_probe(struct platform_device *pdev) + imx_uart_writel(sport, ucr3, UCR3); + } + +- clk_disable_unprepare(sport->clk_ipg); +- + hrtimer_init(&sport->trigger_start_tx, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + hrtimer_init(&sport->trigger_stop_tx, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + sport->trigger_start_tx.function = imx_trigger_start_tx; +@@ -2463,7 +2452,7 @@ static int imx_uart_probe(struct platform_device *pdev) + if (ret) { + dev_err(&pdev->dev, "failed to request rx irq: %d\n", + ret); +- return ret; ++ goto err_clk; + } + + ret = devm_request_irq(&pdev->dev, txirq, imx_uart_txint, 0, +@@ -2471,7 +2460,7 @@ static int imx_uart_probe(struct platform_device *pdev) + if (ret) { + dev_err(&pdev->dev, "failed to request tx irq: %d\n", + ret); +- return ret; ++ goto err_clk; + } + + ret = devm_request_irq(&pdev->dev, rtsirq, imx_uart_rtsint, 0, +@@ -2479,14 +2468,14 @@ static int imx_uart_probe(struct platform_device *pdev) + if (ret) { + dev_err(&pdev->dev, "failed to request rts irq: %d\n", + ret); +- return ret; ++ goto err_clk; + } + } else { + ret = devm_request_irq(&pdev->dev, rxirq, imx_uart_int, 0, + dev_name(&pdev->dev), sport); + if (ret) { + dev_err(&pdev->dev, "failed to request irq: %d\n", ret); +- return ret; ++ goto err_clk; + } + } + +@@ -2494,7 +2483,12 @@ static int imx_uart_probe(struct platform_device *pdev) + + platform_set_drvdata(pdev, sport); + +- return uart_add_one_port(&imx_uart_uart_driver, &sport->port); ++ ret = uart_add_one_port(&imx_uart_uart_driver, &sport->port); ++ ++err_clk: ++ clk_disable_unprepare(sport->clk_ipg); ++ ++ return ret; + } + + static int imx_uart_remove(struct platform_device *pdev) +diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c +index 7d0d2718ef595..beb7896ebf8ae 100644 +--- a/drivers/tty/serial/omap-serial.c ++++ b/drivers/tty/serial/omap-serial.c +@@ -1512,6 +1512,13 @@ static struct omap_uart_port_info *of_get_uart_port_info(struct device *dev) + return omap_up_info; + } + ++static const struct serial_rs485 serial_omap_rs485_supported = { ++ .flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND | SER_RS485_RTS_AFTER_SEND | ++ SER_RS485_RX_DURING_TX, ++ .delay_rts_before_send = 1, ++ .delay_rts_after_send = 1, ++}; ++ + static int serial_omap_probe_rs485(struct uart_omap_port *up, + struct device *dev) + { +@@ -1526,6 +1533,9 @@ static int serial_omap_probe_rs485(struct uart_omap_port *up, + if (!np) + return 0; + ++ up->port.rs485_config = serial_omap_config_rs485; ++ up->port.rs485_supported = serial_omap_rs485_supported; ++ + ret = uart_get_rs485_mode(&up->port); + if (ret) + return ret; +@@ -1560,13 +1570,6 @@ static int serial_omap_probe_rs485(struct uart_omap_port *up, + return 0; + } + +-static const struct serial_rs485 serial_omap_rs485_supported = { +- .flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND | SER_RS485_RTS_AFTER_SEND | +- SER_RS485_RX_DURING_TX, +- .delay_rts_before_send = 1, +- .delay_rts_after_send = 1, +-}; +- + static int serial_omap_probe(struct platform_device *pdev) + { + struct omap_uart_port_info *omap_up_info = dev_get_platdata(&pdev->dev); +@@ -1634,17 +1637,11 @@ static int serial_omap_probe(struct platform_device *pdev) + dev_info(up->port.dev, "no wakeirq for uart%d\n", + up->port.line); + +- ret = serial_omap_probe_rs485(up, &pdev->dev); +- if (ret < 0) +- goto err_rs485; +- + sprintf(up->name, "OMAP UART%d", up->port.line); + up->port.mapbase = mem->start; + up->port.membase = base; + up->port.flags = omap_up_info->flags; + up->port.uartclk = omap_up_info->uartclk; +- up->port.rs485_config = serial_omap_config_rs485; +- up->port.rs485_supported = serial_omap_rs485_supported; + if (!up->port.uartclk) { + up->port.uartclk = DEFAULT_CLK_SPEED; + dev_warn(&pdev->dev, +@@ -1652,6 +1649,10 @@ static int serial_omap_probe(struct platform_device *pdev) + DEFAULT_CLK_SPEED); + } + ++ ret = serial_omap_probe_rs485(up, &pdev->dev); ++ if (ret < 0) ++ goto err_rs485; ++ + up->latency = PM_QOS_CPU_LATENCY_DEFAULT_VALUE; + up->calc_latency = PM_QOS_CPU_LATENCY_DEFAULT_VALUE; + cpu_latency_qos_add_request(&up->pm_qos_request, up->latency); +diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c +index b4b849415c503..db33790e66754 100644 +--- a/drivers/tty/serial/sc16is7xx.c ++++ b/drivers/tty/serial/sc16is7xx.c +@@ -24,6 +24,7 @@ + #include <linux/tty_flip.h> + #include <linux/spi/spi.h> + #include <linux/uaccess.h> ++#include <linux/units.h> + #include <uapi/linux/sched/types.h> + + #define SC16IS7XX_NAME "sc16is7xx" +@@ -1716,9 +1717,12 @@ static int sc16is7xx_spi_probe(struct spi_device *spi) + + /* Setup SPI bus */ + spi->bits_per_word = 8; +- /* only supports mode 0 on SC16IS762 */ ++ /* For all variants, only mode 0 is supported */ ++ if ((spi->mode & SPI_MODE_X_MASK) != SPI_MODE_0) ++ return dev_err_probe(&spi->dev, -EINVAL, "Unsupported SPI mode\n"); ++ + spi->mode = spi->mode ? : SPI_MODE_0; +- spi->max_speed_hz = spi->max_speed_hz ? : 15000000; ++ spi->max_speed_hz = spi->max_speed_hz ? : 4 * HZ_PER_MHZ; + ret = spi_setup(spi); + if (ret) + return ret; +diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c +index d4e57f9017db9..f0ed30d0a697c 100644 +--- a/drivers/tty/serial/serial_core.c ++++ b/drivers/tty/serial/serial_core.c +@@ -1353,19 +1353,27 @@ static void uart_sanitize_serial_rs485(struct uart_port *port, struct serial_rs4 + return; + } + ++ rs485->flags &= supported_flags; ++ + /* Pick sane settings if the user hasn't */ +- if ((supported_flags & (SER_RS485_RTS_ON_SEND|SER_RS485_RTS_AFTER_SEND)) && +- !(rs485->flags & SER_RS485_RTS_ON_SEND) == ++ if (!(rs485->flags & SER_RS485_RTS_ON_SEND) == + !(rs485->flags & SER_RS485_RTS_AFTER_SEND)) { +- dev_warn_ratelimited(port->dev, +- "%s (%d): invalid RTS setting, using RTS_ON_SEND instead\n", +- port->name, port->line); +- rs485->flags |= SER_RS485_RTS_ON_SEND; +- rs485->flags &= ~SER_RS485_RTS_AFTER_SEND; +- supported_flags |= SER_RS485_RTS_ON_SEND|SER_RS485_RTS_AFTER_SEND; +- } ++ if (supported_flags & SER_RS485_RTS_ON_SEND) { ++ rs485->flags |= SER_RS485_RTS_ON_SEND; ++ rs485->flags &= ~SER_RS485_RTS_AFTER_SEND; + +- rs485->flags &= supported_flags; ++ dev_warn_ratelimited(port->dev, ++ "%s (%d): invalid RTS setting, using RTS_ON_SEND instead\n", ++ port->name, port->line); ++ } else { ++ rs485->flags |= SER_RS485_RTS_AFTER_SEND; ++ rs485->flags &= ~SER_RS485_RTS_ON_SEND; ++ ++ dev_warn_ratelimited(port->dev, ++ "%s (%d): invalid RTS setting, using RTS_AFTER_SEND instead\n", ++ port->name, port->line); ++ } ++ } + + uart_sanitize_serial_rs485_delays(port, rs485); + +@@ -1428,7 +1436,7 @@ static int uart_set_rs485_config(struct tty_struct *tty, struct uart_port *port, + int ret; + unsigned long flags; + +- if (!port->rs485_config) ++ if (!(port->rs485_supported.flags & SER_RS485_ENABLED)) + return -ENOTTY; + + if (copy_from_user(&rs485, rs485_user, sizeof(*rs485_user))) +@@ -3420,6 +3428,9 @@ int uart_get_rs485_mode(struct uart_port *port) + u32 rs485_delay[2]; + int ret; + ++ if (!(port->rs485_supported.flags & SER_RS485_ENABLED)) ++ return 0; ++ + ret = device_property_read_u32_array(dev, "rs485-rts-delay", + rs485_delay, 2); + if (!ret) { +diff --git a/drivers/tty/tty.h b/drivers/tty/tty.h +index c5ee219127555..91515e1ebc8d3 100644 +--- a/drivers/tty/tty.h ++++ b/drivers/tty/tty.h +@@ -63,7 +63,7 @@ int tty_check_change(struct tty_struct *tty); + void __stop_tty(struct tty_struct *tty); + void __start_tty(struct tty_struct *tty); + void tty_write_unlock(struct tty_struct *tty); +-int tty_write_lock(struct tty_struct *tty, int ndelay); ++int tty_write_lock(struct tty_struct *tty, bool ndelay); + void tty_vhangup_session(struct tty_struct *tty); + void tty_open_proc_set_tty(struct file *filp, struct tty_struct *tty); + int tty_signal_session_leader(struct tty_struct *tty, int exit_session); +diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c +index 8fb6c6853556a..aaf77a5616ff1 100644 +--- a/drivers/tty/tty_io.c ++++ b/drivers/tty/tty_io.c +@@ -939,7 +939,7 @@ void tty_write_unlock(struct tty_struct *tty) + wake_up_interruptible_poll(&tty->write_wait, EPOLLOUT); + } + +-int tty_write_lock(struct tty_struct *tty, int ndelay) ++int tty_write_lock(struct tty_struct *tty, bool ndelay) + { + if (!mutex_trylock(&tty->atomic_write_lock)) { + if (ndelay) +@@ -1153,7 +1153,7 @@ int tty_send_xchar(struct tty_struct *tty, char ch) + return 0; + } + +- if (tty_write_lock(tty, 0) < 0) ++ if (tty_write_lock(tty, false) < 0) + return -ERESTARTSYS; + + down_read(&tty->termios_rwsem); +@@ -2472,22 +2472,25 @@ static int send_break(struct tty_struct *tty, unsigned int duration) + return 0; + + if (tty->driver->flags & TTY_DRIVER_HARDWARE_BREAK) +- retval = tty->ops->break_ctl(tty, duration); +- else { +- /* Do the work ourselves */ +- if (tty_write_lock(tty, 0) < 0) +- return -EINTR; +- retval = tty->ops->break_ctl(tty, -1); +- if (retval) +- goto out; +- if (!signal_pending(current)) +- msleep_interruptible(duration); ++ return tty->ops->break_ctl(tty, duration); ++ ++ /* Do the work ourselves */ ++ if (tty_write_lock(tty, false) < 0) ++ return -EINTR; ++ ++ retval = tty->ops->break_ctl(tty, -1); ++ if (!retval) { ++ msleep_interruptible(duration); + retval = tty->ops->break_ctl(tty, 0); +-out: +- tty_write_unlock(tty); +- if (signal_pending(current)) +- retval = -EINTR; ++ } else if (retval == -EOPNOTSUPP) { ++ /* some drivers can tell only dynamically */ ++ retval = 0; + } ++ tty_write_unlock(tty); ++ ++ if (signal_pending(current)) ++ retval = -EINTR; ++ + return retval; + } + +diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c +index ad1cf51ecd11d..8767c504b95dd 100644 +--- a/drivers/tty/tty_ioctl.c ++++ b/drivers/tty/tty_ioctl.c +@@ -506,7 +506,7 @@ retry_write_wait: + if (retval < 0) + return retval; + +- if (tty_write_lock(tty, 0) < 0) ++ if (tty_write_lock(tty, false) < 0) + goto retry_write_wait; + + /* Racing writer? */ +diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c +index dc38d1fa77874..474e94a69b185 100644 +--- a/drivers/ufs/core/ufshcd.c ++++ b/drivers/ufs/core/ufshcd.c +@@ -8204,7 +8204,6 @@ static int ufshcd_add_lus(struct ufs_hba *hba) + ufs_bsg_probe(hba); + ufshpb_init(hba); + scsi_scan_host(hba->host); +- pm_runtime_put_sync(hba->dev); + + out: + return ret; +@@ -8331,15 +8330,15 @@ static void ufshcd_async_scan(void *data, async_cookie_t cookie) + + /* Probe and add UFS logical units */ + ret = ufshcd_add_lus(hba); ++ + out: ++ pm_runtime_put_sync(hba->dev); + /* + * If we failed to initialize the device or the device is not + * present, turn off the power/clocks etc. + */ +- if (ret) { +- pm_runtime_put_sync(hba->dev); ++ if (ret) + ufshcd_hba_exit(hba); +- } + } + + static const struct attribute_group *ufshcd_driver_groups[] = { +diff --git a/drivers/usb/cdns3/cdns3-gadget.c b/drivers/usb/cdns3/cdns3-gadget.c +index 69a44bd7e5d02..ccdd525bd7c80 100644 +--- a/drivers/usb/cdns3/cdns3-gadget.c ++++ b/drivers/usb/cdns3/cdns3-gadget.c +@@ -1117,6 +1117,8 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep, + dma_addr_t trb_dma; + u32 togle_pcs = 1; + int sg_iter = 0; ++ int num_trb_req; ++ int trb_burst; + int num_trb; + int address; + u32 control; +@@ -1125,15 +1127,13 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep, + struct scatterlist *s = NULL; + bool sg_supported = !!(request->num_mapped_sgs); + ++ num_trb_req = sg_supported ? request->num_mapped_sgs : 1; ++ ++ /* ISO transfer require each SOF have a TD, each TD include some TRBs */ + if (priv_ep->type == USB_ENDPOINT_XFER_ISOC) +- num_trb = priv_ep->interval; ++ num_trb = priv_ep->interval * num_trb_req; + else +- num_trb = sg_supported ? request->num_mapped_sgs : 1; +- +- if (num_trb > priv_ep->free_trbs) { +- priv_ep->flags |= EP_RING_FULL; +- return -ENOBUFS; +- } ++ num_trb = num_trb_req; + + priv_req = to_cdns3_request(request); + address = priv_ep->endpoint.desc->bEndpointAddress; +@@ -1182,14 +1182,31 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep, + + link_trb->control = cpu_to_le32(((priv_ep->pcs) ? TRB_CYCLE : 0) | + TRB_TYPE(TRB_LINK) | TRB_TOGGLE | ch_bit); ++ ++ if (priv_ep->type == USB_ENDPOINT_XFER_ISOC) { ++ /* ++ * ISO require LINK TRB must be first one of TD. ++ * Fill LINK TRBs for left trb space to simply software process logic. ++ */ ++ while (priv_ep->enqueue) { ++ *trb = *link_trb; ++ trace_cdns3_prepare_trb(priv_ep, trb); ++ ++ cdns3_ep_inc_enq(priv_ep); ++ trb = priv_ep->trb_pool + priv_ep->enqueue; ++ priv_req->trb = trb; ++ } ++ } ++ } ++ ++ if (num_trb > priv_ep->free_trbs) { ++ priv_ep->flags |= EP_RING_FULL; ++ return -ENOBUFS; + } + + if (priv_dev->dev_ver <= DEV_VER_V2) + togle_pcs = cdns3_wa1_update_guard(priv_ep, trb); + +- if (sg_supported) +- s = request->sg; +- + /* set incorrect Cycle Bit for first trb*/ + control = priv_ep->pcs ? 0 : TRB_CYCLE; + trb->length = 0; +@@ -1207,6 +1224,9 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep, + do { + u32 length; + ++ if (!(sg_iter % num_trb_req) && sg_supported) ++ s = request->sg; ++ + /* fill TRB */ + control |= TRB_TYPE(TRB_NORMAL); + if (sg_supported) { +@@ -1221,7 +1241,36 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep, + total_tdl += DIV_ROUND_UP(length, + priv_ep->endpoint.maxpacket); + +- trb->length |= cpu_to_le32(TRB_BURST_LEN(priv_ep->trb_burst_size) | ++ trb_burst = priv_ep->trb_burst_size; ++ ++ /* ++ * Supposed DMA cross 4k bounder problem should be fixed at DEV_VER_V2, but still ++ * met problem when do ISO transfer if sg enabled. ++ * ++ * Data pattern likes below when sg enabled, package size is 1k and mult is 2 ++ * [UVC Header(8B) ] [data(3k - 8)] ... ++ * ++ * The received data at offset 0xd000 will get 0xc000 data, len 0x70. Error happen ++ * as below pattern: ++ * 0xd000: wrong ++ * 0xe000: wrong ++ * 0xf000: correct ++ * 0x10000: wrong ++ * 0x11000: wrong ++ * 0x12000: correct ++ * ... ++ * ++ * But it is still unclear about why error have not happen below 0xd000, it should ++ * cross 4k bounder. But anyway, the below code can fix this problem. ++ * ++ * To avoid DMA cross 4k bounder at ISO transfer, reduce burst len according to 16. ++ */ ++ if (priv_ep->type == USB_ENDPOINT_XFER_ISOC && priv_dev->dev_ver <= DEV_VER_V2) ++ if (ALIGN_DOWN(trb->buffer, SZ_4K) != ++ ALIGN_DOWN(trb->buffer + length, SZ_4K)) ++ trb_burst = 16; ++ ++ trb->length |= cpu_to_le32(TRB_BURST_LEN(trb_burst) | + TRB_LEN(length)); + pcs = priv_ep->pcs ? TRB_CYCLE : 0; + +@@ -1248,7 +1297,7 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep, + if (sg_supported) { + trb->control |= cpu_to_le32(TRB_ISP); + /* Don't set chain bit for last TRB */ +- if (sg_iter < num_trb - 1) ++ if ((sg_iter % num_trb_req) < num_trb_req - 1) + trb->control |= cpu_to_le32(TRB_CHAIN); + + s = sg_next(s); +@@ -1506,6 +1555,12 @@ static void cdns3_transfer_completed(struct cdns3_device *priv_dev, + + /* The TRB was changed as link TRB, and the request was handled at ep_dequeue */ + while (TRB_FIELD_TO_TYPE(le32_to_cpu(trb->control)) == TRB_LINK) { ++ ++ /* ISO ep_traddr may stop at LINK TRB */ ++ if (priv_ep->dequeue == cdns3_get_dma_pos(priv_dev, priv_ep) && ++ priv_ep->type == USB_ENDPOINT_XFER_ISOC) ++ break; ++ + trace_cdns3_complete_trb(priv_ep, trb); + cdns3_ep_inc_deq(priv_ep); + trb = priv_ep->trb_pool + priv_ep->dequeue; +@@ -1538,6 +1593,10 @@ static void cdns3_transfer_completed(struct cdns3_device *priv_dev, + } + + if (request_handled) { ++ /* TRBs are duplicated by priv_ep->interval time for ISO IN */ ++ if (priv_ep->type == USB_ENDPOINT_XFER_ISOC && priv_ep->dir) ++ request->actual /= priv_ep->interval; ++ + cdns3_gadget_giveback(priv_ep, priv_req, 0); + request_handled = false; + transfer_end = false; +@@ -2033,11 +2092,10 @@ int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable) + bool is_iso_ep = (priv_ep->type == USB_ENDPOINT_XFER_ISOC); + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; + u32 bEndpointAddress = priv_ep->num | priv_ep->dir; +- u32 max_packet_size = 0; +- u8 maxburst = 0; ++ u32 max_packet_size = priv_ep->wMaxPacketSize; ++ u8 maxburst = priv_ep->bMaxBurst; + u32 ep_cfg = 0; + u8 buffering; +- u8 mult = 0; + int ret; + + buffering = priv_dev->ep_buf_size - 1; +@@ -2059,8 +2117,7 @@ int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable) + break; + default: + ep_cfg = EP_CFG_EPTYPE(USB_ENDPOINT_XFER_ISOC); +- mult = priv_dev->ep_iso_burst - 1; +- buffering = mult + 1; ++ buffering = (priv_ep->bMaxBurst + 1) * (priv_ep->mult + 1) - 1; + } + + switch (priv_dev->gadget.speed) { +@@ -2071,17 +2128,8 @@ int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable) + max_packet_size = is_iso_ep ? 1024 : 512; + break; + case USB_SPEED_SUPER: +- /* It's limitation that driver assumes in driver. */ +- mult = 0; +- max_packet_size = 1024; +- if (priv_ep->type == USB_ENDPOINT_XFER_ISOC) { +- maxburst = priv_dev->ep_iso_burst - 1; +- buffering = (mult + 1) * +- (maxburst + 1); +- +- if (priv_ep->interval > 1) +- buffering++; +- } else { ++ if (priv_ep->type != USB_ENDPOINT_XFER_ISOC) { ++ max_packet_size = 1024; + maxburst = priv_dev->ep_buf_size - 1; + } + break; +@@ -2110,7 +2158,6 @@ int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable) + if (priv_dev->dev_ver < DEV_VER_V2) + priv_ep->trb_burst_size = 16; + +- mult = min_t(u8, mult, EP_CFG_MULT_MAX); + buffering = min_t(u8, buffering, EP_CFG_BUFFERING_MAX); + maxburst = min_t(u8, maxburst, EP_CFG_MAXBURST_MAX); + +@@ -2144,7 +2191,7 @@ int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable) + } + + ep_cfg |= EP_CFG_MAXPKTSIZE(max_packet_size) | +- EP_CFG_MULT(mult) | ++ EP_CFG_MULT(priv_ep->mult) | /* must match EP setting */ + EP_CFG_BUFFERING(buffering) | + EP_CFG_MAXBURST(maxburst); + +@@ -2234,6 +2281,13 @@ usb_ep *cdns3_gadget_match_ep(struct usb_gadget *gadget, + priv_ep->type = usb_endpoint_type(desc); + priv_ep->flags |= EP_CLAIMED; + priv_ep->interval = desc->bInterval ? BIT(desc->bInterval - 1) : 0; ++ priv_ep->wMaxPacketSize = usb_endpoint_maxp(desc); ++ priv_ep->mult = USB_EP_MAXP_MULT(priv_ep->wMaxPacketSize); ++ priv_ep->wMaxPacketSize &= USB_ENDPOINT_MAXP_MASK; ++ if (priv_ep->type == USB_ENDPOINT_XFER_ISOC && comp_desc) { ++ priv_ep->mult = USB_SS_MULT(comp_desc->bmAttributes) - 1; ++ priv_ep->bMaxBurst = comp_desc->bMaxBurst; ++ } + + spin_unlock_irqrestore(&priv_dev->lock, flags); + return &priv_ep->endpoint; +@@ -3015,22 +3069,40 @@ static int cdns3_gadget_check_config(struct usb_gadget *gadget) + struct cdns3_endpoint *priv_ep; + struct usb_ep *ep; + int n_in = 0; ++ int iso = 0; ++ int out = 1; + int total; ++ int n; + + list_for_each_entry(ep, &gadget->ep_list, ep_list) { + priv_ep = ep_to_cdns3_ep(ep); +- if ((priv_ep->flags & EP_CLAIMED) && (ep->address & USB_DIR_IN)) +- n_in++; ++ if (!(priv_ep->flags & EP_CLAIMED)) ++ continue; ++ ++ n = (priv_ep->mult + 1) * (priv_ep->bMaxBurst + 1); ++ if (ep->address & USB_DIR_IN) { ++ /* ++ * ISO transfer: DMA start move data when get ISO, only transfer ++ * data as min(TD size, iso). No benefit for allocate bigger ++ * internal memory than 'iso'. ++ */ ++ if (priv_ep->type == USB_ENDPOINT_XFER_ISOC) ++ iso += n; ++ else ++ n_in++; ++ } else { ++ if (priv_ep->type == USB_ENDPOINT_XFER_ISOC) ++ out = max_t(int, out, n); ++ } + } + + /* 2KB are reserved for EP0, 1KB for out*/ +- total = 2 + n_in + 1; ++ total = 2 + n_in + out + iso; + + if (total > priv_dev->onchip_buffers) + return -ENOMEM; + +- priv_dev->ep_buf_size = priv_dev->ep_iso_burst = +- (priv_dev->onchip_buffers - 2) / (n_in + 1); ++ priv_dev->ep_buf_size = (priv_dev->onchip_buffers - 2 - iso) / (n_in + out); + + return 0; + } +diff --git a/drivers/usb/cdns3/cdns3-gadget.h b/drivers/usb/cdns3/cdns3-gadget.h +index fbe4a8e3aa897..086a7bb838975 100644 +--- a/drivers/usb/cdns3/cdns3-gadget.h ++++ b/drivers/usb/cdns3/cdns3-gadget.h +@@ -1168,6 +1168,9 @@ struct cdns3_endpoint { + u8 dir; + u8 num; + u8 type; ++ u8 mult; ++ u8 bMaxBurst; ++ u16 wMaxPacketSize; + int interval; + + int free_trbs; +diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c +index b9227f41cf1c0..763d6858a8e6f 100644 +--- a/drivers/usb/chipidea/core.c ++++ b/drivers/usb/chipidea/core.c +@@ -523,6 +523,13 @@ static irqreturn_t ci_irq_handler(int irq, void *data) + u32 otgsc = 0; + + if (ci->in_lpm) { ++ /* ++ * If we already have a wakeup irq pending there, ++ * let's just return to wait resume finished firstly. ++ */ ++ if (ci->wakeup_int) ++ return IRQ_HANDLED; ++ + disable_irq_nosync(irq); + ci->wakeup_int = true; + pm_runtime_get(ci->dev); +diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c +index 36bf051b345b8..2a7eea4e251a1 100644 +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -892,6 +892,9 @@ static int acm_tty_break_ctl(struct tty_struct *tty, int state) + struct acm *acm = tty->driver_data; + int retval; + ++ if (!(acm->ctrl_caps & USB_CDC_CAP_BRK)) ++ return -EOPNOTSUPP; ++ + retval = acm_send_break(acm, state ? 0xffff : 0); + if (retval < 0) + dev_dbg(&acm->control->dev, +diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c +index 1f23c96fa94f8..011a3909f9ad1 100644 +--- a/drivers/usb/dwc3/core.c ++++ b/drivers/usb/dwc3/core.c +@@ -277,48 +277,11 @@ int dwc3_core_soft_reset(struct dwc3 *dwc) + /* + * We're resetting only the device side because, if we're in host mode, + * XHCI driver will reset the host block. If dwc3 was configured for +- * host-only mode or current role is host, then we can return early. ++ * host-only mode, then we can return early. + */ + if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST) + return 0; + +- /* +- * If the dr_mode is host and the dwc->current_dr_role is not the +- * corresponding DWC3_GCTL_PRTCAP_HOST, then the dwc3_core_init_mode +- * isn't executed yet. Ensure the phy is ready before the controller +- * updates the GCTL.PRTCAPDIR or other settings by soft-resetting +- * the phy. +- * +- * Note: GUSB3PIPECTL[n] and GUSB2PHYCFG[n] are port settings where n +- * is port index. If this is a multiport host, then we need to reset +- * all active ports. +- */ +- if (dwc->dr_mode == USB_DR_MODE_HOST) { +- u32 usb3_port; +- u32 usb2_port; +- +- usb3_port = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); +- usb3_port |= DWC3_GUSB3PIPECTL_PHYSOFTRST; +- dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), usb3_port); +- +- usb2_port = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); +- usb2_port |= DWC3_GUSB2PHYCFG_PHYSOFTRST; +- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), usb2_port); +- +- /* Small delay for phy reset assertion */ +- usleep_range(1000, 2000); +- +- usb3_port &= ~DWC3_GUSB3PIPECTL_PHYSOFTRST; +- dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), usb3_port); +- +- usb2_port &= ~DWC3_GUSB2PHYCFG_PHYSOFTRST; +- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), usb2_port); +- +- /* Wait for clock synchronization */ +- msleep(50); +- return 0; +- } +- + reg = dwc3_readl(dwc->regs, DWC3_DCTL); + reg |= DWC3_DCTL_CSFTRST; + reg &= ~DWC3_DCTL_RUN_STOP; +diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c +index 61de693461da4..ec3c33266547c 100644 +--- a/drivers/usb/dwc3/ep0.c ++++ b/drivers/usb/dwc3/ep0.c +@@ -236,7 +236,10 @@ void dwc3_ep0_stall_and_restart(struct dwc3 *dwc) + struct dwc3_request *req; + + req = next_request(&dep->pending_list); +- dwc3_gadget_giveback(dep, req, -ECONNRESET); ++ if (!dwc->connected) ++ dwc3_gadget_giveback(dep, req, -ESHUTDOWN); ++ else ++ dwc3_gadget_giveback(dep, req, -ECONNRESET); + } + + dwc->eps[0]->trb_enqueue = 0; +diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c +index a0921687444b1..bb4f80627cdc3 100644 +--- a/drivers/usb/host/xhci-mtk.c ++++ b/drivers/usb/host/xhci-mtk.c +@@ -7,6 +7,7 @@ + * Chunfeng Yun <chunfeng.yun@mediatek.com> + */ + ++#include <linux/bitfield.h> + #include <linux/dma-mapping.h> + #include <linux/iopoll.h> + #include <linux/kernel.h> +@@ -73,6 +74,9 @@ + #define FRMCNT_LEV1_RANG (0x12b << 8) + #define FRMCNT_LEV1_RANG_MASK GENMASK(19, 8) + ++#define HSCH_CFG1 0x960 ++#define SCH3_RXFIFO_DEPTH_MASK GENMASK(21, 20) ++ + #define SS_GEN2_EOF_CFG 0x990 + #define SSG2EOF_OFFSET 0x3c + +@@ -114,6 +118,8 @@ + #define SSC_IP_SLEEP_EN BIT(4) + #define SSC_SPM_INT_EN BIT(1) + ++#define SCH_FIFO_TO_KB(x) ((x) >> 10) ++ + enum ssusb_uwk_vers { + SSUSB_UWK_V1 = 1, + SSUSB_UWK_V2, +@@ -165,6 +171,35 @@ static void xhci_mtk_set_frame_interval(struct xhci_hcd_mtk *mtk) + writel(value, hcd->regs + SS_GEN2_EOF_CFG); + } + ++/* ++ * workaround: usb3.2 gen1 isoc rx hw issue ++ * host send out unexpected ACK afer device fininsh a burst transfer with ++ * a short packet. ++ */ ++static void xhci_mtk_rxfifo_depth_set(struct xhci_hcd_mtk *mtk) ++{ ++ struct usb_hcd *hcd = mtk->hcd; ++ u32 value; ++ ++ if (!mtk->rxfifo_depth) ++ return; ++ ++ value = readl(hcd->regs + HSCH_CFG1); ++ value &= ~SCH3_RXFIFO_DEPTH_MASK; ++ value |= FIELD_PREP(SCH3_RXFIFO_DEPTH_MASK, ++ SCH_FIFO_TO_KB(mtk->rxfifo_depth) - 1); ++ writel(value, hcd->regs + HSCH_CFG1); ++} ++ ++static void xhci_mtk_init_quirk(struct xhci_hcd_mtk *mtk) ++{ ++ /* workaround only for mt8195 */ ++ xhci_mtk_set_frame_interval(mtk); ++ ++ /* workaround for SoCs using SSUSB about before IPM v1.6.0 */ ++ xhci_mtk_rxfifo_depth_set(mtk); ++} ++ + static int xhci_mtk_host_enable(struct xhci_hcd_mtk *mtk) + { + struct mu3c_ippc_regs __iomem *ippc = mtk->ippc_regs; +@@ -453,8 +488,7 @@ static int xhci_mtk_setup(struct usb_hcd *hcd) + if (ret) + return ret; + +- /* workaround only for mt8195 */ +- xhci_mtk_set_frame_interval(mtk); ++ xhci_mtk_init_quirk(mtk); + } + + ret = xhci_gen_setup(hcd, xhci_mtk_quirks); +@@ -531,6 +565,8 @@ static int xhci_mtk_probe(struct platform_device *pdev) + of_property_read_u32(node, "mediatek,u2p-dis-msk", + &mtk->u2p_dis_msk); + ++ of_property_read_u32(node, "rx-fifo-depth", &mtk->rxfifo_depth); ++ + ret = usb_wakeup_of_property_parse(mtk, node); + if (ret) { + dev_err(dev, "failed to parse uwk property\n"); +diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h +index 1174a510dd388..2a6a47d0f09a4 100644 +--- a/drivers/usb/host/xhci-mtk.h ++++ b/drivers/usb/host/xhci-mtk.h +@@ -160,6 +160,8 @@ struct xhci_hcd_mtk { + struct regmap *uwk; + u32 uwk_reg_base; + u32 uwk_vers; ++ /* quirk */ ++ u32 rxfifo_depth; + }; + + static inline struct xhci_hcd_mtk *hcd_to_mtk(struct usb_hcd *hcd) +diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c +index 094e812e9e692..35483217b1f6c 100644 +--- a/drivers/usb/mon/mon_bin.c ++++ b/drivers/usb/mon/mon_bin.c +@@ -1247,14 +1247,19 @@ static vm_fault_t mon_bin_vma_fault(struct vm_fault *vmf) + struct mon_reader_bin *rp = vmf->vma->vm_private_data; + unsigned long offset, chunk_idx; + struct page *pageptr; ++ unsigned long flags; + ++ spin_lock_irqsave(&rp->b_lock, flags); + offset = vmf->pgoff << PAGE_SHIFT; +- if (offset >= rp->b_size) ++ if (offset >= rp->b_size) { ++ spin_unlock_irqrestore(&rp->b_lock, flags); + return VM_FAULT_SIGBUS; ++ } + chunk_idx = offset / CHUNK_SIZE; + pageptr = rp->b_vec[chunk_idx].pg; + get_page(pageptr); + vmf->page = pageptr; ++ spin_unlock_irqrestore(&rp->b_lock, flags); + return 0; + } + +diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c +index 9299df53eb9df..160c9264339f0 100644 +--- a/drivers/usb/phy/phy-mxs-usb.c ++++ b/drivers/usb/phy/phy-mxs-usb.c +@@ -388,8 +388,7 @@ static void __mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool disconnect) + + static bool mxs_phy_is_otg_host(struct mxs_phy *mxs_phy) + { +- return IS_ENABLED(CONFIG_USB_OTG) && +- mxs_phy->phy.last_event == USB_EVENT_ID; ++ return mxs_phy->phy.last_event == USB_EVENT_ID; + } + + static void mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool on) +diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c +index 49d6b2388b874..3da404d5178d3 100644 +--- a/drivers/usb/typec/class.c ++++ b/drivers/usb/typec/class.c +@@ -263,11 +263,13 @@ static void typec_altmode_put_partner(struct altmode *altmode) + { + struct altmode *partner = altmode->partner; + struct typec_altmode *adev; ++ struct typec_altmode *partner_adev; + + if (!partner) + return; + + adev = &altmode->adev; ++ partner_adev = &partner->adev; + + if (is_typec_plug(adev->dev.parent)) { + struct typec_plug *plug = to_typec_plug(adev->dev.parent); +@@ -276,7 +278,7 @@ static void typec_altmode_put_partner(struct altmode *altmode) + } else { + partner->partner = NULL; + } +- put_device(&adev->dev); ++ put_device(&partner_adev->dev); + } + + /** +diff --git a/drivers/vdpa/alibaba/eni_vdpa.c b/drivers/vdpa/alibaba/eni_vdpa.c +index 5a09a09cca709..cce3d1837104c 100644 +--- a/drivers/vdpa/alibaba/eni_vdpa.c ++++ b/drivers/vdpa/alibaba/eni_vdpa.c +@@ -497,7 +497,7 @@ static int eni_vdpa_probe(struct pci_dev *pdev, const struct pci_device_id *id) + if (!eni_vdpa->vring) { + ret = -ENOMEM; + ENI_ERR(pdev, "failed to allocate virtqueues\n"); +- goto err; ++ goto err_remove_vp_legacy; + } + + for (i = 0; i < eni_vdpa->queues; i++) { +@@ -509,11 +509,13 @@ static int eni_vdpa_probe(struct pci_dev *pdev, const struct pci_device_id *id) + ret = vdpa_register_device(&eni_vdpa->vdpa, eni_vdpa->queues); + if (ret) { + ENI_ERR(pdev, "failed to register to vdpa bus\n"); +- goto err; ++ goto err_remove_vp_legacy; + } + + return 0; + ++err_remove_vp_legacy: ++ vp_legacy_remove(&eni_vdpa->ldev); + err: + put_device(&eni_vdpa->vdpa.dev); + return ret; +diff --git a/drivers/video/fbdev/core/fb_defio.c b/drivers/video/fbdev/core/fb_defio.c +index a3cf1f764f29b..49883c8012e60 100644 +--- a/drivers/video/fbdev/core/fb_defio.c ++++ b/drivers/video/fbdev/core/fb_defio.c +@@ -132,11 +132,7 @@ int fb_deferred_io_fsync(struct file *file, loff_t start, loff_t end, int datasy + return 0; + + inode_lock(inode); +- /* Kill off the delayed work */ +- cancel_delayed_work_sync(&info->deferred_work); +- +- /* Run it immediately */ +- schedule_delayed_work(&info->deferred_work, 0); ++ flush_delayed_work(&info->deferred_work); + inode_unlock(inode); + + return 0; +@@ -321,7 +317,7 @@ static void fb_deferred_io_lastclose(struct fb_info *info) + struct page *page; + int i; + +- cancel_delayed_work_sync(&info->deferred_work); ++ flush_delayed_work(&info->deferred_work); + + /* clear out the mapping that we setup */ + for (i = 0 ; i < info->fix.smem_len; i += PAGE_SIZE) { +diff --git a/drivers/video/fbdev/imxfb.c b/drivers/video/fbdev/imxfb.c +index 36ada87b49a49..32b8374abeca5 100644 +--- a/drivers/video/fbdev/imxfb.c ++++ b/drivers/video/fbdev/imxfb.c +@@ -42,6 +42,7 @@ + #include <video/videomode.h> + + #define PCR_TFT (1 << 31) ++#define PCR_COLOR (1 << 30) + #define PCR_BPIX_8 (3 << 25) + #define PCR_BPIX_12 (4 << 25) + #define PCR_BPIX_16 (5 << 25) +@@ -150,6 +151,12 @@ enum imxfb_type { + IMX21_FB, + }; + ++enum imxfb_panel_type { ++ PANEL_TYPE_MONOCHROME, ++ PANEL_TYPE_CSTN, ++ PANEL_TYPE_TFT, ++}; ++ + struct imxfb_info { + struct platform_device *pdev; + void __iomem *regs; +@@ -157,6 +164,7 @@ struct imxfb_info { + struct clk *clk_ahb; + struct clk *clk_per; + enum imxfb_type devtype; ++ enum imxfb_panel_type panel_type; + bool enabled; + + /* +@@ -444,6 +452,13 @@ static int imxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) + if (!is_imx1_fb(fbi) && imxfb_mode->aus_mode) + fbi->lauscr = LAUSCR_AUS_MODE; + ++ if (imxfb_mode->pcr & PCR_TFT) ++ fbi->panel_type = PANEL_TYPE_TFT; ++ else if (imxfb_mode->pcr & PCR_COLOR) ++ fbi->panel_type = PANEL_TYPE_CSTN; ++ else ++ fbi->panel_type = PANEL_TYPE_MONOCHROME; ++ + /* + * Copy the RGB parameters for this display + * from the machine specific parameters. +@@ -598,6 +613,7 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf + { + struct imxfb_info *fbi = info->par; + u32 ymax_mask = is_imx1_fb(fbi) ? YMAX_MASK_IMX1 : YMAX_MASK_IMX21; ++ u8 left_margin_low; + + pr_debug("var: xres=%d hslen=%d lm=%d rm=%d\n", + var->xres, var->hsync_len, +@@ -606,6 +622,13 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf + var->yres, var->vsync_len, + var->upper_margin, var->lower_margin); + ++ if (fbi->panel_type == PANEL_TYPE_TFT) ++ left_margin_low = 3; ++ else if (fbi->panel_type == PANEL_TYPE_CSTN) ++ left_margin_low = 2; ++ else ++ left_margin_low = 0; ++ + #if DEBUG_VAR + if (var->xres < 16 || var->xres > 1024) + printk(KERN_ERR "%s: invalid xres %d\n", +@@ -613,7 +636,7 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf + if (var->hsync_len < 1 || var->hsync_len > 64) + printk(KERN_ERR "%s: invalid hsync_len %d\n", + info->fix.id, var->hsync_len); +- if (var->left_margin < 3 || var->left_margin > 255) ++ if (var->left_margin < left_margin_low || var->left_margin > 255) + printk(KERN_ERR "%s: invalid left_margin %d\n", + info->fix.id, var->left_margin); + if (var->right_margin < 1 || var->right_margin > 255) +@@ -639,7 +662,7 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf + + writel(HCR_H_WIDTH(var->hsync_len - 1) | + HCR_H_WAIT_1(var->right_margin - 1) | +- HCR_H_WAIT_2(var->left_margin - 3), ++ HCR_H_WAIT_2(var->left_margin - left_margin_low), + fbi->regs + LCDC_HCR); + + writel(VCR_V_WIDTH(var->vsync_len) | +diff --git a/drivers/watchdog/bcm2835_wdt.c b/drivers/watchdog/bcm2835_wdt.c +index 94907176a0e4f..55c0f7b0e8fba 100644 +--- a/drivers/watchdog/bcm2835_wdt.c ++++ b/drivers/watchdog/bcm2835_wdt.c +@@ -42,6 +42,7 @@ + + #define SECS_TO_WDOG_TICKS(x) ((x) << 16) + #define WDOG_TICKS_TO_SECS(x) ((x) >> 16) ++#define WDOG_TICKS_TO_MSECS(x) ((x) * 1000 >> 16) + + struct bcm2835_wdt { + void __iomem *base; +@@ -140,7 +141,7 @@ static struct watchdog_device bcm2835_wdt_wdd = { + .info = &bcm2835_wdt_info, + .ops = &bcm2835_wdt_ops, + .min_timeout = 1, +- .max_timeout = WDOG_TICKS_TO_SECS(PM_WDOG_TIME_SET), ++ .max_hw_heartbeat_ms = WDOG_TICKS_TO_MSECS(PM_WDOG_TIME_SET), + .timeout = WDOG_TICKS_TO_SECS(PM_WDOG_TIME_SET), + }; + +diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c +index f79f932bca148..79ed1626d8ea1 100644 +--- a/drivers/watchdog/hpwdt.c ++++ b/drivers/watchdog/hpwdt.c +@@ -178,7 +178,7 @@ static int hpwdt_pretimeout(unsigned int ulReason, struct pt_regs *regs) + "3. OA Forward Progress Log\n" + "4. iLO Event Log"; + +- if (ilo5 && ulReason == NMI_UNKNOWN && !mynmi) ++ if (ulReason == NMI_UNKNOWN && !mynmi) + return NMI_DONE; + + if (ilo5 && !pretimeout && !mynmi) +diff --git a/drivers/watchdog/rti_wdt.c b/drivers/watchdog/rti_wdt.c +index 6e9253761fc10..ea617c0f97470 100644 +--- a/drivers/watchdog/rti_wdt.c ++++ b/drivers/watchdog/rti_wdt.c +@@ -70,6 +70,11 @@ static int rti_wdt_start(struct watchdog_device *wdd) + { + u32 timer_margin; + struct rti_wdt_device *wdt = watchdog_get_drvdata(wdd); ++ int ret; ++ ++ ret = pm_runtime_resume_and_get(wdd->parent); ++ if (ret) ++ return ret; + + /* set timeout period */ + timer_margin = (u64)wdd->timeout * wdt->freq; +@@ -295,6 +300,9 @@ static int rti_wdt_probe(struct platform_device *pdev) + if (last_ping) + watchdog_set_last_hw_keepalive(wdd, last_ping); + ++ if (!watchdog_hw_running(wdd)) ++ pm_runtime_put_sync(&pdev->dev); ++ + return 0; + + err_iomap: +@@ -309,7 +317,10 @@ static int rti_wdt_remove(struct platform_device *pdev) + struct rti_wdt_device *wdt = platform_get_drvdata(pdev); + + watchdog_unregister_device(&wdt->wdd); +- pm_runtime_put(&pdev->dev); ++ ++ if (!pm_runtime_suspended(&pdev->dev)) ++ pm_runtime_put(&pdev->dev); ++ + pm_runtime_disable(&pdev->dev); + + return 0; +diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c +index fdffa6859dde3..81684d89dc98f 100644 +--- a/drivers/watchdog/watchdog_dev.c ++++ b/drivers/watchdog/watchdog_dev.c +@@ -1052,6 +1052,7 @@ static int watchdog_cdev_register(struct watchdog_device *wdd) + + /* Fill in the data structures */ + cdev_init(&wd_data->cdev, &watchdog_fops); ++ wd_data->cdev.owner = wdd->ops->owner; + + /* Add the device */ + err = cdev_device_add(&wd_data->cdev, &wd_data->dev); +@@ -1066,8 +1067,6 @@ static int watchdog_cdev_register(struct watchdog_device *wdd) + return err; + } + +- wd_data->cdev.owner = wdd->ops->owner; +- + /* Record time of most recent heartbeat as 'just before now'. */ + wd_data->last_hw_keepalive = ktime_sub(ktime_get(), 1); + watchdog_set_open_deadline(wd_data); +diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c +index 6780fc81cc11f..77c7615bba5e1 100644 +--- a/fs/efivarfs/super.c ++++ b/fs/efivarfs/super.c +@@ -13,6 +13,7 @@ + #include <linux/ucs2_string.h> + #include <linux/slab.h> + #include <linux/magic.h> ++#include <linux/printk.h> + + #include "internal.h" + +@@ -226,8 +227,19 @@ static int efivarfs_get_tree(struct fs_context *fc) + return get_tree_single(fc, efivarfs_fill_super); + } + ++static int efivarfs_reconfigure(struct fs_context *fc) ++{ ++ if (!efivar_supports_writes() && !(fc->sb_flags & SB_RDONLY)) { ++ pr_err("Firmware does not support SetVariableRT. Can not remount with rw\n"); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ + static const struct fs_context_operations efivarfs_context_ops = { + .get_tree = efivarfs_get_tree, ++ .reconfigure = efivarfs_reconfigure, + }; + + static int efivarfs_init_fs_context(struct fs_context *fc) +@@ -238,10 +250,13 @@ static int efivarfs_init_fs_context(struct fs_context *fc) + + static void efivarfs_kill_sb(struct super_block *sb) + { ++ struct efivarfs_fs_info *sfi = sb->s_fs_info; ++ + kill_litter_super(sb); + + /* Remove all entries and destroy */ + efivar_entry_iter(efivarfs_destroy, &efivarfs_list, NULL); ++ kfree(sfi); + } + + static struct file_system_type efivarfs_type = { +diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c +index 1b91ac5be9610..cf9a2fa7f55d2 100644 +--- a/fs/erofs/zdata.c ++++ b/fs/erofs/zdata.c +@@ -1192,12 +1192,11 @@ out: + put_page(page); + } else { + for (i = 0; i < pclusterpages; ++i) { +- page = pcl->compressed_bvecs[i].page; ++ /* consider shortlived pages added when decompressing */ ++ page = be->compressed_pages[i]; + + if (erofs_page_is_managed(sbi, page)) + continue; +- +- /* recycle all individual short-lived pages */ + (void)z_erofs_put_shortlivedpage(be->pagepool, page); + WRITE_ONCE(pcl->compressed_bvecs[i].page, NULL); + } +diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c +index 3666c1fd77a64..8b561af379743 100644 +--- a/fs/f2fs/data.c ++++ b/fs/f2fs/data.c +@@ -2490,9 +2490,6 @@ int f2fs_encrypt_one_page(struct f2fs_io_info *fio) + + page = fio->compressed_page ? fio->compressed_page : fio->page; + +- /* wait for GCed page writeback via META_MAPPING */ +- f2fs_wait_on_block_writeback(inode, fio->old_blkaddr); +- + if (fscrypt_inode_uses_inline_crypto(inode)) + return 0; + +@@ -2681,6 +2678,10 @@ got_it: + goto out_writepage; + } + ++ /* wait for GCed page writeback via META_MAPPING */ ++ if (fio->post_read) ++ f2fs_wait_on_block_writeback(inode, fio->old_blkaddr); ++ + /* + * If current allocation needs SSR, + * it had better in-place writes for updated data. +diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c +index 9b9fb3c57ec6c..fd22854dbeaea 100644 +--- a/fs/f2fs/file.c ++++ b/fs/f2fs/file.c +@@ -42,7 +42,7 @@ static vm_fault_t f2fs_filemap_fault(struct vm_fault *vmf) + vm_fault_t ret; + + ret = filemap_fault(vmf); +- if (!ret) ++ if (ret & VM_FAULT_LOCKED) + f2fs_update_iostat(F2FS_I_SB(inode), inode, + APP_MAPPED_READ_IO, F2FS_BLKSIZE); + +@@ -2821,6 +2821,11 @@ static int f2fs_move_file_range(struct file *file_in, loff_t pos_in, + goto out; + } + ++ if (f2fs_compressed_file(src) || f2fs_compressed_file(dst)) { ++ ret = -EOPNOTSUPP; ++ goto out_unlock; ++ } ++ + ret = -EINVAL; + if (pos_in + len > src->i_size || pos_in + len < pos_in) + goto out_unlock; +diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c +index bd020a992c2e7..328cd20b16a54 100644 +--- a/fs/f2fs/namei.c ++++ b/fs/f2fs/namei.c +@@ -1099,7 +1099,7 @@ static int f2fs_rename(struct user_namespace *mnt_userns, struct inode *old_dir, + } + + if (old_dir_entry) { +- if (old_dir != new_dir && !whiteout) ++ if (old_dir != new_dir) + f2fs_set_link(old_inode, old_dir_entry, + old_dir_page, new_dir); + else +diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c +index 6efccd7ccfe1b..c6d0e07096326 100644 +--- a/fs/f2fs/node.c ++++ b/fs/f2fs/node.c +@@ -2738,11 +2738,11 @@ recover_xnid: + f2fs_update_inode_page(inode); + + /* 3: update and set xattr node page dirty */ +- if (page) ++ if (page) { + memcpy(F2FS_NODE(xpage), F2FS_NODE(page), + VALID_XATTR_BLOCK_SIZE); +- +- set_page_dirty(xpage); ++ set_page_dirty(xpage); ++ } + f2fs_put_page(xpage, 1); + + return 0; +diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c +index 8816e13ca7c9e..0631b383e21f4 100644 +--- a/fs/f2fs/xattr.c ++++ b/fs/f2fs/xattr.c +@@ -660,11 +660,14 @@ retry: + here = __find_xattr(base_addr, last_base_addr, NULL, index, len, name); + if (!here) { + if (!F2FS_I(inode)->i_xattr_nid) { ++ error = f2fs_recover_xattr_data(inode, NULL); + f2fs_notice(F2FS_I_SB(inode), +- "recover xattr in inode (%lu)", inode->i_ino); +- f2fs_recover_xattr_data(inode, NULL); +- kfree(base_addr); +- goto retry; ++ "recover xattr in inode (%lu), error(%d)", ++ inode->i_ino, error); ++ if (!error) { ++ kfree(base_addr); ++ goto retry; ++ } + } + f2fs_err(F2FS_I_SB(inode), "set inode (%lu) has corrupted xattr", + inode->i_ino); +diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c +index f602fb8449519..dcaaa32efc4a0 100644 +--- a/fs/gfs2/rgrp.c ++++ b/fs/gfs2/rgrp.c +@@ -2306,7 +2306,7 @@ void gfs2_rgrp_dump(struct seq_file *seq, struct gfs2_rgrpd *rgd, + (unsigned long long)rgd->rd_addr, rgd->rd_flags, + rgd->rd_free, rgd->rd_free_clone, rgd->rd_dinodes, + rgd->rd_requested, rgd->rd_reserved, rgd->rd_extfail_pt); +- if (rgd->rd_sbd->sd_args.ar_rgrplvb) { ++ if (rgd->rd_sbd->sd_args.ar_rgrplvb && rgd->rd_rgl) { + struct gfs2_rgrp_lvb *rgl = rgd->rd_rgl; + + gfs2_print_dbg(seq, "%s L: f:%02x b:%u i:%u\n", fs_id_buf, +diff --git a/fs/namespace.c b/fs/namespace.c +index e04a9e9e3f14f..29a8d90dd1072 100644 +--- a/fs/namespace.c ++++ b/fs/namespace.c +@@ -2693,7 +2693,12 @@ static int do_remount(struct path *path, int ms_flags, int sb_flags, + if (IS_ERR(fc)) + return PTR_ERR(fc); + ++ /* ++ * Indicate to the filesystem that the remount request is coming ++ * from the legacy mount system call. ++ */ + fc->oldapi = true; ++ + err = parse_monolithic_mount_data(fc, data); + if (!err) { + down_write(&sb->s_umount); +@@ -3027,6 +3032,12 @@ static int do_new_mount(struct path *path, const char *fstype, int sb_flags, + if (IS_ERR(fc)) + return PTR_ERR(fc); + ++ /* ++ * Indicate to the filesystem that the mount request is coming ++ * from the legacy mount system call. ++ */ ++ fc->oldapi = true; ++ + if (subtype) + err = vfs_parse_fs_string(fc, "subtype", + subtype, strlen(subtype)); +diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c +index 943aeea1eb160..6be13e0ec170d 100644 +--- a/fs/nfs/blocklayout/blocklayout.c ++++ b/fs/nfs/blocklayout/blocklayout.c +@@ -580,6 +580,8 @@ retry: + nfs4_delete_deviceid(node->ld, node->nfs_client, id); + goto retry; + } ++ ++ nfs4_put_deviceid_node(node); + return ERR_PTR(-ENODEV); + } + +@@ -893,10 +895,9 @@ bl_pg_init_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *req) + } + + if (pgio->pg_dreq == NULL) +- wb_size = pnfs_num_cont_bytes(pgio->pg_inode, +- req->wb_index); ++ wb_size = pnfs_num_cont_bytes(pgio->pg_inode, req->wb_index); + else +- wb_size = nfs_dreq_bytes_left(pgio->pg_dreq); ++ wb_size = nfs_dreq_bytes_left(pgio->pg_dreq, req_offset(req)); + + pnfs_generic_pg_init_write(pgio, req, wb_size); + +diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c +index 3bb530d4bb5ce..8fdb65e1b14a3 100644 +--- a/fs/nfs/direct.c ++++ b/fs/nfs/direct.c +@@ -195,9 +195,10 @@ static void nfs_direct_req_release(struct nfs_direct_req *dreq) + kref_put(&dreq->kref, nfs_direct_req_free); + } + +-ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq) ++ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq, loff_t offset) + { +- return dreq->bytes_left; ++ loff_t start = offset - dreq->io_start; ++ return dreq->max_count - start; + } + EXPORT_SYMBOL_GPL(nfs_dreq_bytes_left); + +diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h +index 4b07a0508f9d8..35a8ae46b6c34 100644 +--- a/fs/nfs/internal.h ++++ b/fs/nfs/internal.h +@@ -640,7 +640,7 @@ extern int nfs_sillyrename(struct inode *dir, struct dentry *dentry); + /* direct.c */ + void nfs_init_cinfo_from_dreq(struct nfs_commit_info *cinfo, + struct nfs_direct_req *dreq); +-extern ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq); ++extern ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq, loff_t offset); + + /* nfs4proc.c */ + extern struct nfs_client *nfs4_init_client(struct nfs_client *clp, +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index 85a952143e9fb..ec3f0103e1a7f 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -170,6 +170,7 @@ static int nfs4_map_errors(int err) + case -NFS4ERR_RESOURCE: + case -NFS4ERR_LAYOUTTRYLATER: + case -NFS4ERR_RECALLCONFLICT: ++ case -NFS4ERR_RETURNCONFLICT: + return -EREMOTEIO; + case -NFS4ERR_WRONGSEC: + case -NFS4ERR_WRONG_CRED: +@@ -558,6 +559,7 @@ static int nfs4_do_handle_exception(struct nfs_server *server, + case -NFS4ERR_GRACE: + case -NFS4ERR_LAYOUTTRYLATER: + case -NFS4ERR_RECALLCONFLICT: ++ case -NFS4ERR_RETURNCONFLICT: + exception->delay = 1; + return 0; + +@@ -9667,6 +9669,7 @@ nfs4_layoutget_handle_exception(struct rpc_task *task, + status = -EBUSY; + break; + case -NFS4ERR_RECALLCONFLICT: ++ case -NFS4ERR_RETURNCONFLICT: + status = -ERECALLCONFLICT; + break; + case -NFS4ERR_DELEG_REVOKED: +diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c +index 1ffb1068216b6..4448ff829cbb9 100644 +--- a/fs/nfs/pnfs.c ++++ b/fs/nfs/pnfs.c +@@ -2729,7 +2729,8 @@ pnfs_generic_pg_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *r + if (pgio->pg_dreq == NULL) + rd_size = i_size_read(pgio->pg_inode) - req_offset(req); + else +- rd_size = nfs_dreq_bytes_left(pgio->pg_dreq); ++ rd_size = nfs_dreq_bytes_left(pgio->pg_dreq, ++ req_offset(req)); + + pgio->pg_lseg = + pnfs_update_layout(pgio->pg_inode, nfs_req_openctx(req), +diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c +index 1e755d093d921..f479e0755a247 100644 +--- a/fs/pstore/ram_core.c ++++ b/fs/pstore/ram_core.c +@@ -190,7 +190,7 @@ static int persistent_ram_init_ecc(struct persistent_ram_zone *prz, + { + int numerr; + struct persistent_ram_buffer *buffer = prz->buffer; +- int ecc_blocks; ++ size_t ecc_blocks; + size_t ecc_total; + + if (!ecc_info || !ecc_info->ecc_size) +diff --git a/fs/smb/server/asn1.c b/fs/smb/server/asn1.c +index 4a4b2b03ff33d..b931a99ab9c85 100644 +--- a/fs/smb/server/asn1.c ++++ b/fs/smb/server/asn1.c +@@ -214,10 +214,15 @@ static int ksmbd_neg_token_alloc(void *context, size_t hdrlen, + { + struct ksmbd_conn *conn = context; + ++ if (!vlen) ++ return -EINVAL; ++ + conn->mechToken = kmemdup_nul(value, vlen, GFP_KERNEL); + if (!conn->mechToken) + return -ENOMEM; + ++ conn->mechTokenLen = (unsigned int)vlen; ++ + return 0; + } + +diff --git a/fs/smb/server/connection.c b/fs/smb/server/connection.c +index b6fa1e285c401..7977827c65410 100644 +--- a/fs/smb/server/connection.c ++++ b/fs/smb/server/connection.c +@@ -415,13 +415,7 @@ static void stop_sessions(void) + again: + down_read(&conn_list_lock); + list_for_each_entry(conn, &conn_list, conns_list) { +- struct task_struct *task; +- + t = conn->transport; +- task = t->handler; +- if (task) +- ksmbd_debug(CONN, "Stop session handler %s/%d\n", +- task->comm, task_pid_nr(task)); + ksmbd_conn_set_exiting(conn); + if (t->ops->shutdown) { + up_read(&conn_list_lock); +diff --git a/fs/smb/server/connection.h b/fs/smb/server/connection.h +index 3c005246a32e8..0e04cf8b1d896 100644 +--- a/fs/smb/server/connection.h ++++ b/fs/smb/server/connection.h +@@ -88,6 +88,7 @@ struct ksmbd_conn { + __u16 dialect; + + char *mechToken; ++ unsigned int mechTokenLen; + + struct ksmbd_conn_ops *conn_ops; + +@@ -134,7 +135,6 @@ struct ksmbd_transport_ops { + struct ksmbd_transport { + struct ksmbd_conn *conn; + struct ksmbd_transport_ops *ops; +- struct task_struct *handler; + }; + + #define KSMBD_TCP_RECV_TIMEOUT (7 * HZ) +diff --git a/fs/smb/server/oplock.c b/fs/smb/server/oplock.c +index af0f6914eca45..f1831e26adad9 100644 +--- a/fs/smb/server/oplock.c ++++ b/fs/smb/server/oplock.c +@@ -1191,6 +1191,12 @@ int smb_grant_oplock(struct ksmbd_work *work, int req_op_level, u64 pid, + bool prev_op_has_lease; + __le32 prev_op_state = 0; + ++ /* Only v2 leases handle the directory */ ++ if (S_ISDIR(file_inode(fp->filp)->i_mode)) { ++ if (!lctx || lctx->version != 2) ++ return 0; ++ } ++ + opinfo = alloc_opinfo(work, pid, tid); + if (!opinfo) + return -ENOMEM; +diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c +index 46070951d163a..6826b562073e0 100644 +--- a/fs/smb/server/smb2pdu.c ++++ b/fs/smb/server/smb2pdu.c +@@ -1412,7 +1412,10 @@ static struct ksmbd_user *session_user(struct ksmbd_conn *conn, + char *name; + unsigned int name_off, name_len, secbuf_len; + +- secbuf_len = le16_to_cpu(req->SecurityBufferLength); ++ if (conn->use_spnego && conn->mechToken) ++ secbuf_len = conn->mechTokenLen; ++ else ++ secbuf_len = le16_to_cpu(req->SecurityBufferLength); + if (secbuf_len < sizeof(struct authenticate_message)) { + ksmbd_debug(SMB, "blob len %d too small\n", secbuf_len); + return NULL; +@@ -1503,7 +1506,10 @@ static int ntlm_authenticate(struct ksmbd_work *work, + struct authenticate_message *authblob; + + authblob = user_authblob(conn, req); +- sz = le16_to_cpu(req->SecurityBufferLength); ++ if (conn->use_spnego && conn->mechToken) ++ sz = conn->mechTokenLen; ++ else ++ sz = le16_to_cpu(req->SecurityBufferLength); + rc = ksmbd_decode_ntlmssp_auth_blob(authblob, sz, conn, sess); + if (rc) { + set_user_flag(sess->user, KSMBD_USER_FLAG_BAD_PASSWORD); +@@ -1776,8 +1782,7 @@ int smb2_sess_setup(struct ksmbd_work *work) + + negblob_off = le16_to_cpu(req->SecurityBufferOffset); + negblob_len = le16_to_cpu(req->SecurityBufferLength); +- if (negblob_off < offsetof(struct smb2_sess_setup_req, Buffer) || +- negblob_len < offsetof(struct negotiate_message, NegotiateFlags)) { ++ if (negblob_off < offsetof(struct smb2_sess_setup_req, Buffer)) { + rc = -EINVAL; + goto out_err; + } +@@ -1786,8 +1791,15 @@ int smb2_sess_setup(struct ksmbd_work *work) + negblob_off); + + if (decode_negotiation_token(conn, negblob, negblob_len) == 0) { +- if (conn->mechToken) ++ if (conn->mechToken) { + negblob = (struct negotiate_message *)conn->mechToken; ++ negblob_len = conn->mechTokenLen; ++ } ++ } ++ ++ if (negblob_len < offsetof(struct negotiate_message, NegotiateFlags)) { ++ rc = -EINVAL; ++ goto out_err; + } + + if (server_conf.auth_mechs & conn->auth_mechs) { +diff --git a/fs/smb/server/smb_common.c b/fs/smb/server/smb_common.c +index d160363c09ebc..e90a1e8c1951d 100644 +--- a/fs/smb/server/smb_common.c ++++ b/fs/smb/server/smb_common.c +@@ -158,8 +158,12 @@ int ksmbd_verify_smb_message(struct ksmbd_work *work) + */ + bool ksmbd_smb_request(struct ksmbd_conn *conn) + { +- __le32 *proto = (__le32 *)smb2_get_msg(conn->request_buf); ++ __le32 *proto; + ++ if (conn->request_buf[0] != 0) ++ return false; ++ ++ proto = (__le32 *)smb2_get_msg(conn->request_buf); + if (*proto == SMB2_COMPRESSION_TRANSFORM_ID) { + pr_err_ratelimited("smb2 compression not support yet"); + return false; +diff --git a/fs/smb/server/transport_rdma.c b/fs/smb/server/transport_rdma.c +index c5629a68c8b73..8faa25c6e129b 100644 +--- a/fs/smb/server/transport_rdma.c ++++ b/fs/smb/server/transport_rdma.c +@@ -2039,6 +2039,7 @@ static bool rdma_frwr_is_supported(struct ib_device_attr *attrs) + static int smb_direct_handle_connect_request(struct rdma_cm_id *new_cm_id) + { + struct smb_direct_transport *t; ++ struct task_struct *handler; + int ret; + + if (!rdma_frwr_is_supported(&new_cm_id->device->attrs)) { +@@ -2056,11 +2057,11 @@ static int smb_direct_handle_connect_request(struct rdma_cm_id *new_cm_id) + if (ret) + goto out_err; + +- KSMBD_TRANS(t)->handler = kthread_run(ksmbd_conn_handler_loop, +- KSMBD_TRANS(t)->conn, "ksmbd:r%u", +- smb_direct_port); +- if (IS_ERR(KSMBD_TRANS(t)->handler)) { +- ret = PTR_ERR(KSMBD_TRANS(t)->handler); ++ handler = kthread_run(ksmbd_conn_handler_loop, ++ KSMBD_TRANS(t)->conn, "ksmbd:r%u", ++ smb_direct_port); ++ if (IS_ERR(handler)) { ++ ret = PTR_ERR(handler); + pr_err("Can't start thread\n"); + goto out_err; + } +diff --git a/fs/smb/server/transport_tcp.c b/fs/smb/server/transport_tcp.c +index eff7a1d793f00..9d4222154dcc0 100644 +--- a/fs/smb/server/transport_tcp.c ++++ b/fs/smb/server/transport_tcp.c +@@ -185,6 +185,7 @@ static int ksmbd_tcp_new_connection(struct socket *client_sk) + struct sockaddr *csin; + int rc = 0; + struct tcp_transport *t; ++ struct task_struct *handler; + + t = alloc_transport(client_sk); + if (!t) { +@@ -199,13 +200,13 @@ static int ksmbd_tcp_new_connection(struct socket *client_sk) + goto out_error; + } + +- KSMBD_TRANS(t)->handler = kthread_run(ksmbd_conn_handler_loop, +- KSMBD_TRANS(t)->conn, +- "ksmbd:%u", +- ksmbd_tcp_get_port(csin)); +- if (IS_ERR(KSMBD_TRANS(t)->handler)) { ++ handler = kthread_run(ksmbd_conn_handler_loop, ++ KSMBD_TRANS(t)->conn, ++ "ksmbd:%u", ++ ksmbd_tcp_get_port(csin)); ++ if (IS_ERR(handler)) { + pr_err("cannot start conn thread\n"); +- rc = PTR_ERR(KSMBD_TRANS(t)->handler); ++ rc = PTR_ERR(handler); + free_transport(t); + } + return rc; +diff --git a/include/crypto/if_alg.h b/include/crypto/if_alg.h +index a5db86670bdfa..a406e281ae571 100644 +--- a/include/crypto/if_alg.h ++++ b/include/crypto/if_alg.h +@@ -138,6 +138,7 @@ struct af_alg_async_req { + * recvmsg is invoked. + * @init: True if metadata has been sent. + * @len: Length of memory allocated for this data structure. ++ * @inflight: Non-zero when AIO requests are in flight. + */ + struct af_alg_ctx { + struct list_head tsgl_list; +@@ -156,6 +157,8 @@ struct af_alg_ctx { + bool init; + + unsigned int len; ++ ++ unsigned int inflight; + }; + + int af_alg_register_type(const struct af_alg_type *type); +diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h +index 6b656ea23b964..a76f4103d48bd 100644 +--- a/include/drm/drm_bridge.h ++++ b/include/drm/drm_bridge.h +@@ -191,7 +191,7 @@ struct drm_bridge_funcs { + * or &drm_encoder_helper_funcs.dpms hook. + * + * The bridge must assume that the display pipe (i.e. clocks and timing +- * singals) feeding it is no longer running when this callback is ++ * signals) feeding it is no longer running when this callback is + * called. + * + * The @post_disable callback is optional. +diff --git a/include/dt-bindings/clock/qcom,videocc-sm8150.h b/include/dt-bindings/clock/qcom,videocc-sm8150.h +index e24ee840cfdb8..c557b78dc572f 100644 +--- a/include/dt-bindings/clock/qcom,videocc-sm8150.h ++++ b/include/dt-bindings/clock/qcom,videocc-sm8150.h +@@ -16,6 +16,10 @@ + + /* VIDEO_CC Resets */ + #define VIDEO_CC_MVSC_CORE_CLK_BCR 0 ++#define VIDEO_CC_INTERFACE_BCR 1 ++#define VIDEO_CC_MVS0_BCR 2 ++#define VIDEO_CC_MVS1_BCR 3 ++#define VIDEO_CC_MVSC_BCR 4 + + /* VIDEO_CC GDSCRs */ + #define VENUS_GDSC 0 +diff --git a/include/linux/bio.h b/include/linux/bio.h +index 2c5806997bbf7..2b9fc5edf49d6 100644 +--- a/include/linux/bio.h ++++ b/include/linux/bio.h +@@ -279,6 +279,11 @@ static inline void bio_first_folio(struct folio_iter *fi, struct bio *bio, + { + struct bio_vec *bvec = bio_first_bvec_all(bio) + i; + ++ if (unlikely(i >= bio->bi_vcnt)) { ++ fi->folio = NULL; ++ return; ++ } ++ + fi->folio = page_folio(bvec->bv_page); + fi->offset = bvec->bv_offset + + PAGE_SIZE * (bvec->bv_page - &fi->folio->page); +@@ -296,10 +301,8 @@ static inline void bio_next_folio(struct folio_iter *fi, struct bio *bio) + fi->offset = 0; + fi->length = min(folio_size(fi->folio), fi->_seg_count); + fi->_next = folio_next(fi->folio); +- } else if (fi->_i + 1 < bio->bi_vcnt) { +- bio_first_folio(fi, bio, fi->_i + 1); + } else { +- fi->folio = NULL; ++ bio_first_folio(fi, bio, fi->_i + 1); + } + } + +diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h +index 07a7eeef47d39..e255674a9ee72 100644 +--- a/include/linux/blkdev.h ++++ b/include/linux/blkdev.h +@@ -1109,11 +1109,12 @@ static inline bool bdev_is_partition(struct block_device *bdev) + enum blk_default_limits { + BLK_MAX_SEGMENTS = 128, + BLK_SAFE_MAX_SECTORS = 255, +- BLK_DEF_MAX_SECTORS = 2560, + BLK_MAX_SEGMENT_SIZE = 65536, + BLK_SEG_BOUNDARY_MASK = 0xFFFFFFFFUL, + }; + ++#define BLK_DEF_MAX_SECTORS 2560u ++ + static inline unsigned long queue_segment_boundary(const struct request_queue *q) + { + return q->limits.seg_boundary_mask; +diff --git a/include/linux/bpf.h b/include/linux/bpf.h +index ba22cf4f5fc0e..c04a61ffac8ae 100644 +--- a/include/linux/bpf.h ++++ b/include/linux/bpf.h +@@ -102,7 +102,11 @@ struct bpf_map_ops { + /* funcs called by prog_array and perf_event_array map */ + void *(*map_fd_get_ptr)(struct bpf_map *map, struct file *map_file, + int fd); +- void (*map_fd_put_ptr)(void *ptr); ++ /* If need_defer is true, the implementation should guarantee that ++ * the to-be-put element is still alive before the bpf program, which ++ * may manipulate it, exists. ++ */ ++ void (*map_fd_put_ptr)(struct bpf_map *map, void *ptr, bool need_defer); + int (*map_gen_lookup)(struct bpf_map *map, struct bpf_insn *insn_buf); + u32 (*map_fd_sys_lookup_elem)(void *ptr); + void (*map_seq_show_elem)(struct bpf_map *map, void *key, +@@ -233,7 +237,11 @@ struct bpf_map { + */ + atomic64_t refcnt ____cacheline_aligned; + atomic64_t usercnt; +- struct work_struct work; ++ /* rcu is used before freeing and work is only used during freeing */ ++ union { ++ struct work_struct work; ++ struct rcu_head rcu; ++ }; + struct mutex freeze_mutex; + atomic64_t writecnt; + /* 'Ownership' of program-containing map is claimed by the first program +@@ -249,6 +257,8 @@ struct bpf_map { + } owner; + bool bypass_spec_v1; + bool frozen; /* write-once; write-protected by freeze_mutex */ ++ bool free_after_mult_rcu_gp; ++ s64 __percpu *elem_count; + }; + + static inline bool map_value_has_spin_lock(const struct bpf_map *map) +@@ -1791,6 +1801,35 @@ bpf_map_alloc_percpu(const struct bpf_map *map, size_t size, size_t align, + } + #endif + ++static inline int ++bpf_map_init_elem_count(struct bpf_map *map) ++{ ++ size_t size = sizeof(*map->elem_count), align = size; ++ gfp_t flags = GFP_USER | __GFP_NOWARN; ++ ++ map->elem_count = bpf_map_alloc_percpu(map, size, align, flags); ++ if (!map->elem_count) ++ return -ENOMEM; ++ ++ return 0; ++} ++ ++static inline void ++bpf_map_free_elem_count(struct bpf_map *map) ++{ ++ free_percpu(map->elem_count); ++} ++ ++static inline void bpf_map_inc_elem_count(struct bpf_map *map) ++{ ++ this_cpu_inc(*map->elem_count); ++} ++ ++static inline void bpf_map_dec_elem_count(struct bpf_map *map) ++{ ++ this_cpu_dec(*map->elem_count); ++} ++ + extern int sysctl_unprivileged_bpf_disabled; + + static inline bool bpf_allow_ptr_leaks(void) +diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h +index 15e336281d1f4..94fcfefb52f3c 100644 +--- a/include/linux/clk-provider.h ++++ b/include/linux/clk-provider.h +@@ -446,8 +446,8 @@ struct clk *clk_register_fixed_rate(struct device *dev, const char *name, + */ + #define clk_hw_register_fixed_rate_with_accuracy_parent_hw(dev, name, \ + parent_hw, flags, fixed_rate, fixed_accuracy) \ +- __clk_hw_register_fixed_rate((dev), NULL, (name), NULL, (parent_hw) \ +- NULL, NULL, (flags), (fixed_rate), \ ++ __clk_hw_register_fixed_rate((dev), NULL, (name), NULL, (parent_hw), \ ++ NULL, (flags), (fixed_rate), \ + (fixed_accuracy), 0, false) + /** + * clk_hw_register_fixed_rate_with_accuracy_parent_data - register fixed-rate +diff --git a/include/linux/hisi_acc_qm.h b/include/linux/hisi_acc_qm.h +index 41203ce27d64c..b566ae420449c 100644 +--- a/include/linux/hisi_acc_qm.h ++++ b/include/linux/hisi_acc_qm.h +@@ -161,6 +161,11 @@ enum qm_cap_bits { + QM_SUPPORT_RPM, + }; + ++struct qm_dev_alg { ++ u64 alg_msk; ++ const char *alg; ++}; ++ + struct dfx_diff_registers { + u32 *regs; + u32 reg_offset; +@@ -266,6 +271,16 @@ struct hisi_qm_cap_info { + u32 v3_val; + }; + ++struct hisi_qm_cap_record { ++ u32 type; ++ u32 cap_val; ++}; ++ ++struct hisi_qm_cap_tables { ++ struct hisi_qm_cap_record *qm_cap_table; ++ struct hisi_qm_cap_record *dev_cap_table; ++}; ++ + struct hisi_qm_list { + struct mutex lock; + struct list_head list; +@@ -337,7 +352,6 @@ struct hisi_qm { + struct work_struct rst_work; + struct work_struct cmd_process; + +- const char *algs; + bool use_sva; + bool is_frozen; + +@@ -348,6 +362,8 @@ struct hisi_qm { + struct qm_shaper_factor *factor; + u32 mb_qos; + u32 type_rate; ++ ++ struct hisi_qm_cap_tables cap_tables; + }; + + struct hisi_qp_status { +@@ -521,6 +537,8 @@ void hisi_qm_regs_dump(struct seq_file *s, struct debugfs_regset32 *regset); + u32 hisi_qm_get_hw_info(struct hisi_qm *qm, + const struct hisi_qm_cap_info *info_table, + u32 index, bool is_read); ++int hisi_qm_set_algs(struct hisi_qm *qm, u64 alg_msk, const struct qm_dev_alg *dev_algs, ++ u32 dev_algs_size); + + /* Used by VFIO ACC live migration driver */ + struct pci_driver *hisi_sec_get_pf_driver(void); +diff --git a/include/linux/iio/adc/adi-axi-adc.h b/include/linux/iio/adc/adi-axi-adc.h +index 52620e5b80522..b7904992d5619 100644 +--- a/include/linux/iio/adc/adi-axi-adc.h ++++ b/include/linux/iio/adc/adi-axi-adc.h +@@ -41,6 +41,7 @@ struct adi_axi_adc_chip_info { + * @reg_access IIO debugfs_reg_access hook for the client ADC + * @read_raw IIO read_raw hook for the client ADC + * @write_raw IIO write_raw hook for the client ADC ++ * @read_avail IIO read_avail hook for the client ADC + */ + struct adi_axi_adc_conv { + const struct adi_axi_adc_chip_info *chip_info; +@@ -54,6 +55,9 @@ struct adi_axi_adc_conv { + int (*write_raw)(struct adi_axi_adc_conv *conv, + struct iio_chan_spec const *chan, + int val, int val2, long mask); ++ int (*read_avail)(struct adi_axi_adc_conv *conv, ++ struct iio_chan_spec const *chan, ++ const int **val, int *type, int *length, long mask); + }; + + struct adi_axi_adc_conv *devm_adi_axi_adc_conv_register(struct device *dev, +diff --git a/include/linux/netfilter_bridge.h b/include/linux/netfilter_bridge.h +index f980edfdd2783..743475ca7e9d5 100644 +--- a/include/linux/netfilter_bridge.h ++++ b/include/linux/netfilter_bridge.h +@@ -42,7 +42,7 @@ static inline int nf_bridge_get_physinif(const struct sk_buff *skb) + if (!nf_bridge) + return 0; + +- return nf_bridge->physindev ? nf_bridge->physindev->ifindex : 0; ++ return nf_bridge->physinif; + } + + static inline int nf_bridge_get_physoutif(const struct sk_buff *skb) +@@ -56,11 +56,11 @@ static inline int nf_bridge_get_physoutif(const struct sk_buff *skb) + } + + static inline struct net_device * +-nf_bridge_get_physindev(const struct sk_buff *skb) ++nf_bridge_get_physindev(const struct sk_buff *skb, struct net *net) + { + const struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb); + +- return nf_bridge ? nf_bridge->physindev : NULL; ++ return nf_bridge ? dev_get_by_index_rcu(net, nf_bridge->physinif) : NULL; + } + + static inline struct net_device * +diff --git a/include/linux/of.h b/include/linux/of.h +index 6b79ef9a6541f..1c5301e10442f 100644 +--- a/include/linux/of.h ++++ b/include/linux/of.h +@@ -1155,7 +1155,8 @@ static inline int of_property_read_string_index(const struct device_node *np, + * @np: device node from which the property value is to be read. + * @propname: name of the property to be searched. + * +- * Search for a property in a device node. ++ * Search for a boolean property in a device node. Usage on non-boolean ++ * property types is deprecated. + * + * Return: true if the property exists false otherwise. + */ +@@ -1167,6 +1168,20 @@ static inline bool of_property_read_bool(const struct device_node *np, + return prop ? true : false; + } + ++/** ++ * of_property_present - Test if a property is present in a node ++ * @np: device node to search for the property. ++ * @propname: name of the property to be searched. ++ * ++ * Test for a property present in a device node. ++ * ++ * Return: true if the property exists false otherwise. ++ */ ++static inline bool of_property_present(const struct device_node *np, const char *propname) ++{ ++ return of_property_read_bool(np, propname); ++} ++ + /** + * of_property_read_u8_array - Find and read an array of u8 from a property. + * +diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h +index e9e61cd27ef63..46bd9a331fd5d 100644 +--- a/include/linux/rcupdate.h ++++ b/include/linux/rcupdate.h +@@ -242,6 +242,18 @@ static inline void exit_tasks_rcu_stop(void) { } + static inline void exit_tasks_rcu_finish(void) { } + #endif /* #else #ifdef CONFIG_TASKS_RCU_GENERIC */ + ++/** ++ * rcu_trace_implies_rcu_gp - does an RCU Tasks Trace grace period imply an RCU grace period? ++ * ++ * As an accident of implementation, an RCU Tasks Trace grace period also ++ * acts as an RCU grace period. However, this could change at any time. ++ * Code relying on this accident must call this function to verify that ++ * this accident is still happening. ++ * ++ * You have been warned! ++ */ ++static inline bool rcu_trace_implies_rcu_gp(void) { return true; } ++ + /** + * cond_resched_tasks_rcu_qs - Report potential quiescent states to RCU + * +diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h +index 2feee144fc0ef..c30d419ebf545 100644 +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -301,7 +301,7 @@ struct nf_bridge_info { + u8 bridged_dnat:1; + u8 sabotage_in_done:1; + __u16 frag_max_size; +- struct net_device *physindev; ++ int physinif; + + /* always valid & non-NULL from FORWARD on, for physdev match */ + struct net_device *physoutdev; +diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h +index 5f8a534b65746..09c978f3d95dc 100644 +--- a/include/net/bluetooth/hci_core.h ++++ b/include/net/bluetooth/hci_core.h +@@ -942,7 +942,6 @@ void hci_inquiry_cache_flush(struct hci_dev *hdev); + /* ----- HCI Connections ----- */ + enum { + HCI_CONN_AUTH_PEND, +- HCI_CONN_REAUTH_PEND, + HCI_CONN_ENCRYPT_PEND, + HCI_CONN_RSWITCH_PEND, + HCI_CONN_MODE_CHANGE_PEND, +diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h +index 92dbe89dafbf5..201dc77ebbd77 100644 +--- a/include/uapi/linux/bpf.h ++++ b/include/uapi/linux/bpf.h +@@ -4353,6 +4353,8 @@ union bpf_attr { + * long bpf_get_task_stack(struct task_struct *task, void *buf, u32 size, u64 flags) + * Description + * Return a user or a kernel stack in bpf program provided buffer. ++ * Note: the user stack will only be populated if the *task* is ++ * the current task; all other tasks will return -EOPNOTSUPP. + * To achieve this, the helper needs *task*, which is a valid + * pointer to **struct task_struct**. To store the stacktrace, the + * bpf program provides *buf* with a nonnegative *size*. +@@ -4364,6 +4366,7 @@ union bpf_attr { + * + * **BPF_F_USER_STACK** + * Collect a user space stack instead of a kernel stack. ++ * The *task* must be the current task. + * **BPF_F_USER_BUILD_ID** + * Collect buildid+offset instead of ips for user stack, + * only valid if **BPF_F_USER_STACK** is also specified. +diff --git a/init/do_mounts.c b/init/do_mounts.c +index 811e94daf0a84..2d705b9c84007 100644 +--- a/init/do_mounts.c ++++ b/init/do_mounts.c +@@ -665,7 +665,10 @@ struct file_system_type rootfs_fs_type = { + + void __init init_rootfs(void) + { +- if (IS_ENABLED(CONFIG_TMPFS) && !saved_root_name[0] && +- (!root_fs_names || strstr(root_fs_names, "tmpfs"))) +- is_tmpfs = true; ++ if (IS_ENABLED(CONFIG_TMPFS)) { ++ if (!saved_root_name[0] && !root_fs_names) ++ is_tmpfs = true; ++ else if (root_fs_names && !!strstr(root_fs_names, "tmpfs")) ++ is_tmpfs = true; ++ } + } +diff --git a/io_uring/rw.c b/io_uring/rw.c +index 0133db648d8e9..038e6b13a7496 100644 +--- a/io_uring/rw.c ++++ b/io_uring/rw.c +@@ -534,15 +534,19 @@ static inline int io_rw_prep_async(struct io_kiocb *req, int rw) + struct iovec *iov; + int ret; + ++ iorw->bytes_done = 0; ++ iorw->free_iovec = NULL; ++ + /* submission path, ->uring_lock should already be taken */ + ret = io_import_iovec(rw, req, &iov, &iorw->s, 0); + if (unlikely(ret < 0)) + return ret; + +- iorw->bytes_done = 0; +- iorw->free_iovec = iov; +- if (iov) ++ if (iov) { ++ iorw->free_iovec = iov; + req->flags |= REQ_F_NEED_CLEANUP; ++ } ++ + return 0; + } + +diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c +index 00f23febb9a7d..c04e69f34e4d5 100644 +--- a/kernel/bpf/arraymap.c ++++ b/kernel/bpf/arraymap.c +@@ -852,7 +852,7 @@ int bpf_fd_array_map_update_elem(struct bpf_map *map, struct file *map_file, + } + + if (old_ptr) +- map->ops->map_fd_put_ptr(old_ptr); ++ map->ops->map_fd_put_ptr(map, old_ptr, true); + return 0; + } + +@@ -875,7 +875,7 @@ static int fd_array_map_delete_elem(struct bpf_map *map, void *key) + } + + if (old_ptr) { +- map->ops->map_fd_put_ptr(old_ptr); ++ map->ops->map_fd_put_ptr(map, old_ptr, true); + return 0; + } else { + return -ENOENT; +@@ -898,8 +898,9 @@ static void *prog_fd_array_get_ptr(struct bpf_map *map, + return prog; + } + +-static void prog_fd_array_put_ptr(void *ptr) ++static void prog_fd_array_put_ptr(struct bpf_map *map, void *ptr, bool need_defer) + { ++ /* bpf_prog is freed after one RCU or tasks trace grace period */ + bpf_prog_put(ptr); + } + +@@ -1185,8 +1186,9 @@ err_out: + return ee; + } + +-static void perf_event_fd_array_put_ptr(void *ptr) ++static void perf_event_fd_array_put_ptr(struct bpf_map *map, void *ptr, bool need_defer) + { ++ /* bpf_perf_event is freed after one RCU grace period */ + bpf_event_entry_free_rcu(ptr); + } + +@@ -1239,7 +1241,7 @@ static void *cgroup_fd_array_get_ptr(struct bpf_map *map, + return cgroup_get_from_fd(fd); + } + +-static void cgroup_fd_array_put_ptr(void *ptr) ++static void cgroup_fd_array_put_ptr(struct bpf_map *map, void *ptr, bool need_defer) + { + /* cgroup_put free cgrp after a rcu grace period */ + cgroup_put(ptr); +diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c +index ce0051eee746e..88c71de0a0a95 100644 +--- a/kernel/bpf/hashtab.c ++++ b/kernel/bpf/hashtab.c +@@ -880,7 +880,7 @@ static void htab_put_fd_value(struct bpf_htab *htab, struct htab_elem *l) + + if (map->ops->map_fd_put_ptr) { + ptr = fd_htab_map_get_ptr(map, l); +- map->ops->map_fd_put_ptr(ptr); ++ map->ops->map_fd_put_ptr(map, ptr, true); + } + } + +@@ -2424,7 +2424,7 @@ static void fd_htab_map_free(struct bpf_map *map) + hlist_nulls_for_each_entry_safe(l, n, head, hash_node) { + void *ptr = fd_htab_map_get_ptr(map, l); + +- map->ops->map_fd_put_ptr(ptr); ++ map->ops->map_fd_put_ptr(map, ptr, false); + } + } + +@@ -2465,7 +2465,7 @@ int bpf_fd_htab_map_update_elem(struct bpf_map *map, struct file *map_file, + + ret = htab_map_update_elem(map, key, &ptr, map_flags); + if (ret) +- map->ops->map_fd_put_ptr(ptr); ++ map->ops->map_fd_put_ptr(map, ptr, false); + + return ret; + } +diff --git a/kernel/bpf/lpm_trie.c b/kernel/bpf/lpm_trie.c +index d833496e9e426..ce3a091d52e89 100644 +--- a/kernel/bpf/lpm_trie.c ++++ b/kernel/bpf/lpm_trie.c +@@ -231,6 +231,9 @@ static void *trie_lookup_elem(struct bpf_map *map, void *_key) + struct lpm_trie_node *node, *found = NULL; + struct bpf_lpm_trie_key *key = _key; + ++ if (key->prefixlen > trie->max_prefixlen) ++ return NULL; ++ + /* Start walking the trie from the root node ... */ + + for (node = rcu_dereference_check(trie->root, rcu_read_lock_bh_held()); +diff --git a/kernel/bpf/map_in_map.c b/kernel/bpf/map_in_map.c +index 8e87f69aae60d..141f3332038c7 100644 +--- a/kernel/bpf/map_in_map.c ++++ b/kernel/bpf/map_in_map.c +@@ -115,12 +115,17 @@ void *bpf_map_fd_get_ptr(struct bpf_map *map, + return inner_map; + } + +-void bpf_map_fd_put_ptr(void *ptr) ++void bpf_map_fd_put_ptr(struct bpf_map *map, void *ptr, bool need_defer) + { +- /* ptr->ops->map_free() has to go through one +- * rcu grace period by itself. ++ struct bpf_map *inner_map = ptr; ++ ++ /* The inner map may still be used by both non-sleepable and sleepable ++ * bpf program, so free it after one RCU grace period and one tasks ++ * trace RCU grace period. + */ +- bpf_map_put(ptr); ++ if (need_defer) ++ WRITE_ONCE(inner_map->free_after_mult_rcu_gp, true); ++ bpf_map_put(inner_map); + } + + u32 bpf_map_fd_sys_lookup_elem(void *ptr) +diff --git a/kernel/bpf/map_in_map.h b/kernel/bpf/map_in_map.h +index bcb7534afb3c0..7d61602354de8 100644 +--- a/kernel/bpf/map_in_map.h ++++ b/kernel/bpf/map_in_map.h +@@ -13,7 +13,7 @@ struct bpf_map *bpf_map_meta_alloc(int inner_map_ufd); + void bpf_map_meta_free(struct bpf_map *map_meta); + void *bpf_map_fd_get_ptr(struct bpf_map *map, struct file *map_file, + int ufd); +-void bpf_map_fd_put_ptr(void *ptr); ++void bpf_map_fd_put_ptr(struct bpf_map *map, void *ptr, bool need_defer); + u32 bpf_map_fd_sys_lookup_elem(void *ptr); + + #endif +diff --git a/kernel/bpf/stackmap.c b/kernel/bpf/stackmap.c +index aecea7451b610..f86db3cf72123 100644 +--- a/kernel/bpf/stackmap.c ++++ b/kernel/bpf/stackmap.c +@@ -391,6 +391,7 @@ static long __bpf_get_stack(struct pt_regs *regs, struct task_struct *task, + { + u32 trace_nr, copy_len, elem_size, num_elem, max_depth; + bool user_build_id = flags & BPF_F_USER_BUILD_ID; ++ bool crosstask = task && task != current; + u32 skip = flags & BPF_F_SKIP_FIELD_MASK; + bool user = flags & BPF_F_USER_STACK; + struct perf_callchain_entry *trace; +@@ -413,6 +414,14 @@ static long __bpf_get_stack(struct pt_regs *regs, struct task_struct *task, + if (task && user && !user_mode(regs)) + goto err_fault; + ++ /* get_perf_callchain does not support crosstask user stack walking ++ * but returns an empty stack instead of NULL. ++ */ ++ if (crosstask && user) { ++ err = -EOPNOTSUPP; ++ goto clear; ++ } ++ + num_elem = size / elem_size; + max_depth = num_elem + skip; + if (sysctl_perf_event_max_stack < max_depth) +@@ -424,7 +433,7 @@ static long __bpf_get_stack(struct pt_regs *regs, struct task_struct *task, + trace = get_callchain_entry_for_task(task, max_depth); + else + trace = get_perf_callchain(regs, 0, kernel, user, max_depth, +- false, false); ++ crosstask, false); + if (unlikely(!trace)) + goto err_fault; + +diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c +index 0c8b7733573ee..8d0c38a8dcf2d 100644 +--- a/kernel/bpf/syscall.c ++++ b/kernel/bpf/syscall.c +@@ -628,6 +628,28 @@ static void bpf_map_put_uref(struct bpf_map *map) + } + } + ++static void bpf_map_free_in_work(struct bpf_map *map) ++{ ++ INIT_WORK(&map->work, bpf_map_free_deferred); ++ /* Avoid spawning kworkers, since they all might contend ++ * for the same mutex like slab_mutex. ++ */ ++ queue_work(system_unbound_wq, &map->work); ++} ++ ++static void bpf_map_free_rcu_gp(struct rcu_head *rcu) ++{ ++ bpf_map_free_in_work(container_of(rcu, struct bpf_map, rcu)); ++} ++ ++static void bpf_map_free_mult_rcu_gp(struct rcu_head *rcu) ++{ ++ if (rcu_trace_implies_rcu_gp()) ++ bpf_map_free_rcu_gp(rcu); ++ else ++ call_rcu(rcu, bpf_map_free_rcu_gp); ++} ++ + /* decrement map refcnt and schedule it for freeing via workqueue + * (unrelying map implementation ops->map_free() might sleep) + */ +@@ -637,11 +659,11 @@ static void __bpf_map_put(struct bpf_map *map, bool do_idr_lock) + /* bpf_map_free_id() must be called first */ + bpf_map_free_id(map, do_idr_lock); + btf_put(map->btf); +- INIT_WORK(&map->work, bpf_map_free_deferred); +- /* Avoid spawning kworkers, since they all might contend +- * for the same mutex like slab_mutex. +- */ +- queue_work(system_unbound_wq, &map->work); ++ ++ if (READ_ONCE(map->free_after_mult_rcu_gp)) ++ call_rcu_tasks_trace(&map->rcu, bpf_map_free_mult_rcu_gp); ++ else ++ bpf_map_free_in_work(map); + } + } + +@@ -3036,6 +3058,10 @@ static int bpf_tracing_prog_attach(struct bpf_prog *prog, + * + * - if prog->aux->dst_trampoline and tgt_prog is NULL, the program + * was detached and is going for re-attachment. ++ * ++ * - if prog->aux->dst_trampoline is NULL and tgt_prog and prog->aux->attach_btf ++ * are NULL, then program was already attached and user did not provide ++ * tgt_prog_fd so we have no way to find out or create trampoline + */ + if (!prog->aux->dst_trampoline && !tgt_prog) { + /* +@@ -3049,6 +3075,11 @@ static int bpf_tracing_prog_attach(struct bpf_prog *prog, + err = -EINVAL; + goto out_unlock; + } ++ /* We can allow re-attach only if we have valid attach_btf. */ ++ if (!prog->aux->attach_btf) { ++ err = -EINVAL; ++ goto out_unlock; ++ } + btf_id = prog->aux->attach_btf_id; + key = bpf_trampoline_compute_key(NULL, prog->aux->attach_btf, btf_id); + } +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index 142e10d49fd81..23b6d57b5eef2 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -3284,7 +3284,7 @@ static int check_stack_write_fixed_off(struct bpf_verifier_env *env, + * so it's aligned access and [off, off + size) are within stack limits + */ + if (!env->allow_ptr_leaks && +- state->stack[spi].slot_type[0] == STACK_SPILL && ++ is_spilled_reg(&state->stack[spi]) && + size != BPF_REG_SIZE) { + verbose(env, "attempt to corrupt spilled pointer on stack\n"); + return -EACCES; +@@ -4950,10 +4950,7 @@ static int check_stack_access_within_bounds( + + if (tnum_is_const(reg->var_off)) { + min_off = reg->var_off.value + off; +- if (access_size > 0) +- max_off = min_off + access_size - 1; +- else +- max_off = min_off; ++ max_off = min_off + access_size; + } else { + if (reg->smax_value >= BPF_MAX_VAR_OFF || + reg->smin_value <= -BPF_MAX_VAR_OFF) { +@@ -4962,15 +4959,12 @@ static int check_stack_access_within_bounds( + return -EACCES; + } + min_off = reg->smin_value + off; +- if (access_size > 0) +- max_off = reg->smax_value + off + access_size - 1; +- else +- max_off = min_off; ++ max_off = reg->smax_value + off + access_size; + } + + err = check_stack_slot_within_bounds(min_off, state, type); +- if (!err) +- err = check_stack_slot_within_bounds(max_off, state, type); ++ if (!err && max_off > 0) ++ err = -EINVAL; /* out of stack access into non-negative offsets */ + + if (err) { + if (tnum_is_const(reg->var_off)) { +@@ -7284,6 +7278,13 @@ static int prepare_func_exit(struct bpf_verifier_env *env, int *insn_idx) + verbose(env, "R0 not a scalar value\n"); + return -EACCES; + } ++ ++ /* we are going to rely on register's precise value */ ++ err = mark_reg_read(env, r0, r0->parent, REG_LIVE_READ64); ++ err = err ?: mark_chain_precision(env, BPF_REG_0); ++ if (err) ++ return err; ++ + if (!tnum_in(range, r0->var_off)) { + verbose_invalid_scalar(env, r0, &range, "callback return", "R0"); + return -EINVAL; +@@ -8540,6 +8541,10 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env, + } + + switch (base_type(ptr_reg->type)) { ++ case PTR_TO_FLOW_KEYS: ++ if (known) ++ break; ++ fallthrough; + case CONST_PTR_TO_MAP: + /* smin_val represents the known value */ + if (known && smin_val == 0 && opcode == BPF_ADD) +diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c +index 438b868cbfa92..35aa2e98a92a9 100644 +--- a/kernel/debug/kdb/kdb_main.c ++++ b/kernel/debug/kdb/kdb_main.c +@@ -1349,8 +1349,6 @@ do_full_getstr: + /* PROMPT can only be set if we have MEM_READ permission. */ + snprintf(kdb_prompt_str, CMD_BUFLEN, kdbgetenv("PROMPT"), + raw_smp_processor_id()); +- if (defcmd_in_progress) +- strncat(kdb_prompt_str, "[defcmd]", CMD_BUFLEN); + + /* + * Fetch command from keyboard +diff --git a/kernel/dma/coherent.c b/kernel/dma/coherent.c +index c21abc77c53e9..ff5683a57f771 100644 +--- a/kernel/dma/coherent.c ++++ b/kernel/dma/coherent.c +@@ -132,8 +132,10 @@ int dma_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr, + + void dma_release_coherent_memory(struct device *dev) + { +- if (dev) ++ if (dev) { + _dma_release_coherent_memory(dev->dma_mem); ++ dev->dma_mem = NULL; ++ } + } + + static void *__dma_alloc_from_coherent(struct device *dev, +diff --git a/kernel/rcu/tasks.h b/kernel/rcu/tasks.h +index c1f18c63b9b14..b5d5b6cf093a7 100644 +--- a/kernel/rcu/tasks.h ++++ b/kernel/rcu/tasks.h +@@ -1570,6 +1570,8 @@ static void rcu_tasks_trace_postscan(struct list_head *hop) + { + // Wait for late-stage exiting tasks to finish exiting. + // These might have passed the call to exit_tasks_rcu_finish(). ++ ++ // If you remove the following line, update rcu_trace_implies_rcu_gp()!!! + synchronize_rcu(); + // Any tasks that exit after this point will set + // TRC_NEED_QS_CHECKED in ->trc_reader_special.b.need_qs. +diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c +index 798e1841d2863..1a5d02224d465 100644 +--- a/kernel/time/tick-sched.c ++++ b/kernel/time/tick-sched.c +@@ -1556,13 +1556,18 @@ void tick_setup_sched_timer(void) + void tick_cancel_sched_timer(int cpu) + { + struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); ++ ktime_t idle_sleeptime, iowait_sleeptime; + + # ifdef CONFIG_HIGH_RES_TIMERS + if (ts->sched_timer.base) + hrtimer_cancel(&ts->sched_timer); + # endif + ++ idle_sleeptime = ts->idle_sleeptime; ++ iowait_sleeptime = ts->iowait_sleeptime; + memset(ts, 0, sizeof(*ts)); ++ ts->idle_sleeptime = idle_sleeptime; ++ ts->iowait_sleeptime = iowait_sleeptime; + } + #endif + +diff --git a/lib/kunit/debugfs.c b/lib/kunit/debugfs.c +index b08bb1fba106d..de5e71458358e 100644 +--- a/lib/kunit/debugfs.c ++++ b/lib/kunit/debugfs.c +@@ -52,12 +52,14 @@ static void debugfs_print_result(struct seq_file *seq, + static int debugfs_print_results(struct seq_file *seq, void *v) + { + struct kunit_suite *suite = (struct kunit_suite *)seq->private; +- enum kunit_status success = kunit_suite_has_succeeded(suite); ++ enum kunit_status success; + struct kunit_case *test_case; + + if (!suite) + return 0; + ++ success = kunit_suite_has_succeeded(suite); ++ + /* Print KTAP header so the debugfs log can be parsed as valid KTAP. */ + seq_puts(seq, "KTAP version 1\n"); + seq_puts(seq, "1..1\n"); +diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c +index 55e0ecd88543e..12d36875358b9 100644 +--- a/net/bluetooth/hci_conn.c ++++ b/net/bluetooth/hci_conn.c +@@ -2314,12 +2314,10 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) + hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED, + sizeof(cp), &cp); + +- /* If we're already encrypted set the REAUTH_PEND flag, +- * otherwise set the ENCRYPT_PEND. ++ /* Set the ENCRYPT_PEND to trigger encryption after ++ * authentication. + */ +- if (test_bit(HCI_CONN_ENCRYPT, &conn->flags)) +- set_bit(HCI_CONN_REAUTH_PEND, &conn->flags); +- else ++ if (!test_bit(HCI_CONN_ENCRYPT, &conn->flags)) + set_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); + } + +diff --git a/net/bluetooth/hci_debugfs.c b/net/bluetooth/hci_debugfs.c +index 3f401ec5bb0c6..6124b3425f351 100644 +--- a/net/bluetooth/hci_debugfs.c ++++ b/net/bluetooth/hci_debugfs.c +@@ -1045,10 +1045,12 @@ static int min_key_size_set(void *data, u64 val) + { + struct hci_dev *hdev = data; + +- if (val > hdev->le_max_key_size || val < SMP_MIN_ENC_KEY_SIZE) ++ hci_dev_lock(hdev); ++ if (val > hdev->le_max_key_size || val < SMP_MIN_ENC_KEY_SIZE) { ++ hci_dev_unlock(hdev); + return -EINVAL; ++ } + +- hci_dev_lock(hdev); + hdev->le_min_key_size = val; + hci_dev_unlock(hdev); + +@@ -1073,10 +1075,12 @@ static int max_key_size_set(void *data, u64 val) + { + struct hci_dev *hdev = data; + +- if (val > SMP_MAX_ENC_KEY_SIZE || val < hdev->le_min_key_size) ++ hci_dev_lock(hdev); ++ if (val > SMP_MAX_ENC_KEY_SIZE || val < hdev->le_min_key_size) { ++ hci_dev_unlock(hdev); + return -EINVAL; ++ } + +- hci_dev_lock(hdev); + hdev->le_max_key_size = val; + hci_dev_unlock(hdev); + +diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c +index dcb13c64e8e7c..56ecc5f97b916 100644 +--- a/net/bluetooth/hci_event.c ++++ b/net/bluetooth/hci_event.c +@@ -3511,14 +3511,8 @@ static void hci_auth_complete_evt(struct hci_dev *hdev, void *data, + + if (!ev->status) { + clear_bit(HCI_CONN_AUTH_FAILURE, &conn->flags); +- +- if (!hci_conn_ssp_enabled(conn) && +- test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) { +- bt_dev_info(hdev, "re-auth of legacy device is not possible."); +- } else { +- set_bit(HCI_CONN_AUTH, &conn->flags); +- conn->sec_level = conn->pending_sec_level; +- } ++ set_bit(HCI_CONN_AUTH, &conn->flags); ++ conn->sec_level = conn->pending_sec_level; + } else { + if (ev->status == HCI_ERROR_PIN_OR_KEY_MISSING) + set_bit(HCI_CONN_AUTH_FAILURE, &conn->flags); +@@ -3527,7 +3521,6 @@ static void hci_auth_complete_evt(struct hci_dev *hdev, void *data, + } + + clear_bit(HCI_CONN_AUTH_PEND, &conn->flags); +- clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags); + + if (conn->state == BT_CONFIG) { + if (!ev->status && hci_conn_ssp_enabled(conn)) { +diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c +index 01d690d9fe5f8..202ad43e35d6b 100644 +--- a/net/bridge/br_netfilter_hooks.c ++++ b/net/bridge/br_netfilter_hooks.c +@@ -279,8 +279,17 @@ int br_nf_pre_routing_finish_bridge(struct net *net, struct sock *sk, struct sk_ + + if ((READ_ONCE(neigh->nud_state) & NUD_CONNECTED) && + READ_ONCE(neigh->hh.hh_len)) { ++ struct net_device *br_indev; ++ ++ br_indev = nf_bridge_get_physindev(skb, net); ++ if (!br_indev) { ++ neigh_release(neigh); ++ goto free_skb; ++ } ++ + neigh_hh_bridge(&neigh->hh, skb); +- skb->dev = nf_bridge->physindev; ++ skb->dev = br_indev; ++ + ret = br_handle_frame_finish(net, sk, skb); + } else { + /* the neighbour function below overwrites the complete +@@ -352,12 +361,18 @@ br_nf_ipv4_daddr_was_changed(const struct sk_buff *skb, + */ + static int br_nf_pre_routing_finish(struct net *net, struct sock *sk, struct sk_buff *skb) + { +- struct net_device *dev = skb->dev; ++ struct net_device *dev = skb->dev, *br_indev; + struct iphdr *iph = ip_hdr(skb); + struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb); + struct rtable *rt; + int err; + ++ br_indev = nf_bridge_get_physindev(skb, net); ++ if (!br_indev) { ++ kfree_skb(skb); ++ return 0; ++ } ++ + nf_bridge->frag_max_size = IPCB(skb)->frag_max_size; + + if (nf_bridge->pkt_otherhost) { +@@ -397,7 +412,7 @@ free_skb: + } else { + if (skb_dst(skb)->dev == dev) { + bridged_dnat: +- skb->dev = nf_bridge->physindev; ++ skb->dev = br_indev; + nf_bridge_update_protocol(skb); + nf_bridge_push_encap_header(skb); + br_nf_hook_thresh(NF_BR_PRE_ROUTING, +@@ -410,7 +425,7 @@ bridged_dnat: + skb->pkt_type = PACKET_HOST; + } + } else { +- rt = bridge_parent_rtable(nf_bridge->physindev); ++ rt = bridge_parent_rtable(br_indev); + if (!rt) { + kfree_skb(skb); + return 0; +@@ -419,7 +434,7 @@ bridged_dnat: + skb_dst_set_noref(skb, &rt->dst); + } + +- skb->dev = nf_bridge->physindev; ++ skb->dev = br_indev; + nf_bridge_update_protocol(skb); + nf_bridge_push_encap_header(skb); + br_nf_hook_thresh(NF_BR_PRE_ROUTING, net, sk, skb, skb->dev, NULL, +@@ -456,7 +471,7 @@ struct net_device *setup_pre_routing(struct sk_buff *skb, const struct net *net) + } + + nf_bridge->in_prerouting = 1; +- nf_bridge->physindev = skb->dev; ++ nf_bridge->physinif = skb->dev->ifindex; + skb->dev = brnf_get_logical_dev(skb, skb->dev, net); + + if (skb->protocol == htons(ETH_P_8021Q)) +@@ -553,7 +568,11 @@ static int br_nf_forward_finish(struct net *net, struct sock *sk, struct sk_buff + if (skb->protocol == htons(ETH_P_IPV6)) + nf_bridge->frag_max_size = IP6CB(skb)->frag_max_size; + +- in = nf_bridge->physindev; ++ in = nf_bridge_get_physindev(skb, net); ++ if (!in) { ++ kfree_skb(skb); ++ return 0; ++ } + if (nf_bridge->pkt_otherhost) { + skb->pkt_type = PACKET_OTHERHOST; + nf_bridge->pkt_otherhost = false; +@@ -897,6 +916,13 @@ static unsigned int ip_sabotage_in(void *priv, + static void br_nf_pre_routing_finish_bridge_slow(struct sk_buff *skb) + { + struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb); ++ struct net_device *br_indev; ++ ++ br_indev = nf_bridge_get_physindev(skb, dev_net(skb->dev)); ++ if (!br_indev) { ++ kfree_skb(skb); ++ return; ++ } + + skb_pull(skb, ETH_HLEN); + nf_bridge->bridged_dnat = 0; +@@ -906,7 +932,7 @@ static void br_nf_pre_routing_finish_bridge_slow(struct sk_buff *skb) + skb_copy_to_linear_data_offset(skb, -(ETH_HLEN - ETH_ALEN), + nf_bridge->neigh_header, + ETH_HLEN - ETH_ALEN); +- skb->dev = nf_bridge->physindev; ++ skb->dev = br_indev; + + nf_bridge->physoutdev = NULL; + br_handle_frame_finish(dev_net(skb->dev), NULL, skb); +diff --git a/net/bridge/br_netfilter_ipv6.c b/net/bridge/br_netfilter_ipv6.c +index 6b07f30675bb0..cd24ab9bb136f 100644 +--- a/net/bridge/br_netfilter_ipv6.c ++++ b/net/bridge/br_netfilter_ipv6.c +@@ -161,9 +161,15 @@ static int br_nf_pre_routing_finish_ipv6(struct net *net, struct sock *sk, struc + { + struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb); + struct rtable *rt; +- struct net_device *dev = skb->dev; ++ struct net_device *dev = skb->dev, *br_indev; + const struct nf_ipv6_ops *v6ops = nf_get_ipv6_ops(); + ++ br_indev = nf_bridge_get_physindev(skb, net); ++ if (!br_indev) { ++ kfree_skb(skb); ++ return 0; ++ } ++ + nf_bridge->frag_max_size = IP6CB(skb)->frag_max_size; + + if (nf_bridge->pkt_otherhost) { +@@ -181,7 +187,7 @@ static int br_nf_pre_routing_finish_ipv6(struct net *net, struct sock *sk, struc + } + + if (skb_dst(skb)->dev == dev) { +- skb->dev = nf_bridge->physindev; ++ skb->dev = br_indev; + nf_bridge_update_protocol(skb); + nf_bridge_push_encap_header(skb); + br_nf_hook_thresh(NF_BR_PRE_ROUTING, +@@ -192,7 +198,7 @@ static int br_nf_pre_routing_finish_ipv6(struct net *net, struct sock *sk, struc + ether_addr_copy(eth_hdr(skb)->h_dest, dev->dev_addr); + skb->pkt_type = PACKET_HOST; + } else { +- rt = bridge_parent_rtable(nf_bridge->physindev); ++ rt = bridge_parent_rtable(br_indev); + if (!rt) { + kfree_skb(skb); + return 0; +@@ -201,7 +207,7 @@ static int br_nf_pre_routing_finish_ipv6(struct net *net, struct sock *sk, struc + skb_dst_set_noref(skb, &rt->dst); + } + +- skb->dev = nf_bridge->physindev; ++ skb->dev = br_indev; + nf_bridge_update_protocol(skb); + nf_bridge_push_encap_header(skb); + br_nf_hook_thresh(NF_BR_PRE_ROUTING, net, sk, skb, +diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c +index 854b3fd66b1be..7cf1e42d7f93b 100644 +--- a/net/core/rtnetlink.c ++++ b/net/core/rtnetlink.c +@@ -2797,13 +2797,6 @@ static int do_setlink(const struct sk_buff *skb, + call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); + } + +- if (tb[IFLA_MASTER]) { +- err = do_set_master(dev, nla_get_u32(tb[IFLA_MASTER]), extack); +- if (err) +- goto errout; +- status |= DO_SETLINK_MODIFIED; +- } +- + if (ifm->ifi_flags || ifm->ifi_change) { + err = dev_change_flags(dev, rtnl_dev_combine_flags(dev, ifm), + extack); +@@ -2811,6 +2804,13 @@ static int do_setlink(const struct sk_buff *skb, + goto errout; + } + ++ if (tb[IFLA_MASTER]) { ++ err = do_set_master(dev, nla_get_u32(tb[IFLA_MASTER]), extack); ++ if (err) ++ goto errout; ++ status |= DO_SETLINK_MODIFIED; ++ } ++ + if (tb[IFLA_CARRIER]) { + err = dev_change_carrier(dev, nla_get_u8(tb[IFLA_CARRIER])); + if (err) +diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c +index 8324e9f970668..26a9d8434c234 100644 +--- a/net/dns_resolver/dns_key.c ++++ b/net/dns_resolver/dns_key.c +@@ -104,7 +104,7 @@ dns_resolver_preparse(struct key_preparsed_payload *prep) + const struct dns_server_list_v1_header *v1; + + /* It may be a server list. */ +- if (datalen <= sizeof(*v1)) ++ if (datalen < sizeof(*v1)) + return -EINVAL; + + v1 = (const struct dns_server_list_v1_header *)data; +diff --git a/net/ethtool/features.c b/net/ethtool/features.c +index 55d449a2d3fcb..090e493f592ef 100644 +--- a/net/ethtool/features.c ++++ b/net/ethtool/features.c +@@ -234,17 +234,20 @@ int ethnl_set_features(struct sk_buff *skb, struct genl_info *info) + dev = req_info.dev; + + rtnl_lock(); ++ ret = ethnl_ops_begin(dev); ++ if (ret < 0) ++ goto out_rtnl; + ethnl_features_to_bitmap(old_active, dev->features); + ethnl_features_to_bitmap(old_wanted, dev->wanted_features); + ret = ethnl_parse_bitset(req_wanted, req_mask, NETDEV_FEATURE_COUNT, + tb[ETHTOOL_A_FEATURES_WANTED], + netdev_features_strings, info->extack); + if (ret < 0) +- goto out_rtnl; ++ goto out_ops; + if (ethnl_bitmap_to_features(req_mask) & ~NETIF_F_ETHTOOL_BITS) { + GENL_SET_ERR_MSG(info, "attempt to change non-ethtool features"); + ret = -EINVAL; +- goto out_rtnl; ++ goto out_ops; + } + + /* set req_wanted bits not in req_mask from old_wanted */ +@@ -281,6 +284,8 @@ int ethnl_set_features(struct sk_buff *skb, struct genl_info *info) + if (mod) + netdev_features_change(dev); + ++out_ops: ++ ethnl_ops_complete(dev); + out_rtnl: + rtnl_unlock(); + ethnl_parse_header_dev_put(&req_info); +diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c +index 347c3768df6e8..c13b8ed63f87e 100644 +--- a/net/ipv4/af_inet.c ++++ b/net/ipv4/af_inet.c +@@ -1642,6 +1642,7 @@ int inet_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) + #endif + return -EINVAL; + } ++EXPORT_SYMBOL(inet_recv_error); + + int inet_gro_complete(struct sk_buff *skb, int nhoff) + { +diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c +index e04544ac4b454..b807197475a57 100644 +--- a/net/ipv4/ipmr.c ++++ b/net/ipv4/ipmr.c +@@ -1025,6 +1025,10 @@ static int ipmr_cache_report(const struct mr_table *mrt, + struct sk_buff *skb; + int ret; + ++ mroute_sk = rcu_dereference(mrt->mroute_sk); ++ if (!mroute_sk) ++ return -EINVAL; ++ + if (assert == IGMPMSG_WHOLEPKT || assert == IGMPMSG_WRVIFWHOLE) + skb = skb_realloc_headroom(pkt, sizeof(struct iphdr)); + else +@@ -1069,7 +1073,8 @@ static int ipmr_cache_report(const struct mr_table *mrt, + msg = (struct igmpmsg *)skb_network_header(skb); + msg->im_vif = vifi; + msg->im_vif_hi = vifi >> 8; +- skb_dst_set(skb, dst_clone(skb_dst(pkt))); ++ ipv4_pktinfo_prepare(mroute_sk, pkt); ++ memcpy(skb->cb, pkt->cb, sizeof(skb->cb)); + /* Add our header */ + igmp = skb_put(skb, sizeof(struct igmphdr)); + igmp->type = assert; +@@ -1079,12 +1084,6 @@ static int ipmr_cache_report(const struct mr_table *mrt, + skb->transport_header = skb->network_header; + } + +- mroute_sk = rcu_dereference(mrt->mroute_sk); +- if (!mroute_sk) { +- kfree_skb(skb); +- return -EINVAL; +- } +- + igmpmsg_netlink_event(mrt, skb); + + /* Deliver to mrouted */ +diff --git a/net/ipv4/netfilter/nf_reject_ipv4.c b/net/ipv4/netfilter/nf_reject_ipv4.c +index d640adcaf1b12..4073762996e22 100644 +--- a/net/ipv4/netfilter/nf_reject_ipv4.c ++++ b/net/ipv4/netfilter/nf_reject_ipv4.c +@@ -239,7 +239,6 @@ static int nf_reject_fill_skb_dst(struct sk_buff *skb_in) + void nf_send_reset(struct net *net, struct sock *sk, struct sk_buff *oldskb, + int hook) + { +- struct net_device *br_indev __maybe_unused; + struct sk_buff *nskb; + struct iphdr *niph; + const struct tcphdr *oth; +@@ -288,9 +287,13 @@ void nf_send_reset(struct net *net, struct sock *sk, struct sk_buff *oldskb, + * build the eth header using the original destination's MAC as the + * source, and send the RST packet directly. + */ +- br_indev = nf_bridge_get_physindev(oldskb); +- if (br_indev) { ++ if (nf_bridge_info_exists(oldskb)) { + struct ethhdr *oeth = eth_hdr(oldskb); ++ struct net_device *br_indev; ++ ++ br_indev = nf_bridge_get_physindev(oldskb, net); ++ if (!br_indev) ++ goto free_nskb; + + nskb->dev = br_indev; + niph->tot_len = htons(nskb->len); +diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c +index 5672d9a86c5d2..11c0e1c666429 100644 +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -823,7 +823,7 @@ void udp_flush_pending_frames(struct sock *sk) + + if (up->pending) { + up->len = 0; +- up->pending = 0; ++ WRITE_ONCE(up->pending, 0); + ip_flush_pending_frames(sk); + } + } +@@ -1010,7 +1010,7 @@ int udp_push_pending_frames(struct sock *sk) + + out: + up->len = 0; +- up->pending = 0; ++ WRITE_ONCE(up->pending, 0); + return err; + } + EXPORT_SYMBOL(udp_push_pending_frames); +@@ -1086,7 +1086,7 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) + getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag; + + fl4 = &inet->cork.fl.u.ip4; +- if (up->pending) { ++ if (READ_ONCE(up->pending)) { + /* + * There are pending frames. + * The socket lock must be held while it's corked. +@@ -1287,7 +1287,7 @@ back_from_confirm: + fl4->saddr = saddr; + fl4->fl4_dport = dport; + fl4->fl4_sport = inet->inet_sport; +- up->pending = AF_INET; ++ WRITE_ONCE(up->pending, AF_INET); + + do_append_data: + up->len += ulen; +@@ -1299,7 +1299,7 @@ do_append_data: + else if (!corkreq) + err = udp_push_pending_frames(sk); + else if (unlikely(skb_queue_empty(&sk->sk_write_queue))) +- up->pending = 0; ++ WRITE_ONCE(up->pending, 0); + release_sock(sk); + + out: +@@ -1337,7 +1337,7 @@ void udp_splice_eof(struct socket *sock) + struct sock *sk = sock->sk; + struct udp_sock *up = udp_sk(sk); + +- if (!up->pending || udp_test_bit(CORK, sk)) ++ if (!READ_ONCE(up->pending) || udp_test_bit(CORK, sk)) + return; + + lock_sock(sk); +diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c +index afc922c88d179..9125e92d9917e 100644 +--- a/net/ipv6/ip6_tunnel.c ++++ b/net/ipv6/ip6_tunnel.c +@@ -399,7 +399,7 @@ __u16 ip6_tnl_parse_tlv_enc_lim(struct sk_buff *skb, __u8 *raw) + const struct ipv6hdr *ipv6h = (const struct ipv6hdr *)raw; + unsigned int nhoff = raw - skb->data; + unsigned int off = nhoff + sizeof(*ipv6h); +- u8 next, nexthdr = ipv6h->nexthdr; ++ u8 nexthdr = ipv6h->nexthdr; + + while (ipv6_ext_hdr(nexthdr) && nexthdr != NEXTHDR_NONE) { + struct ipv6_opt_hdr *hdr; +@@ -410,25 +410,25 @@ __u16 ip6_tnl_parse_tlv_enc_lim(struct sk_buff *skb, __u8 *raw) + + hdr = (struct ipv6_opt_hdr *)(skb->data + off); + if (nexthdr == NEXTHDR_FRAGMENT) { +- struct frag_hdr *frag_hdr = (struct frag_hdr *) hdr; +- if (frag_hdr->frag_off) +- break; + optlen = 8; + } else if (nexthdr == NEXTHDR_AUTH) { + optlen = ipv6_authlen(hdr); + } else { + optlen = ipv6_optlen(hdr); + } +- /* cache hdr->nexthdr, since pskb_may_pull() might +- * invalidate hdr +- */ +- next = hdr->nexthdr; +- if (nexthdr == NEXTHDR_DEST) { +- u16 i = 2; + +- /* Remember : hdr is no longer valid at this point. */ +- if (!pskb_may_pull(skb, off + optlen)) ++ if (!pskb_may_pull(skb, off + optlen)) ++ break; ++ ++ hdr = (struct ipv6_opt_hdr *)(skb->data + off); ++ if (nexthdr == NEXTHDR_FRAGMENT) { ++ struct frag_hdr *frag_hdr = (struct frag_hdr *)hdr; ++ ++ if (frag_hdr->frag_off) + break; ++ } ++ if (nexthdr == NEXTHDR_DEST) { ++ u16 i = 2; + + while (1) { + struct ipv6_tlv_tnl_enc_lim *tel; +@@ -449,7 +449,7 @@ __u16 ip6_tnl_parse_tlv_enc_lim(struct sk_buff *skb, __u8 *raw) + i++; + } + } +- nexthdr = next; ++ nexthdr = hdr->nexthdr; + off += optlen; + } + return 0; +diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c +index 7860383295d84..566f3b7b957e9 100644 +--- a/net/ipv6/mcast.c ++++ b/net/ipv6/mcast.c +@@ -2725,8 +2725,12 @@ void ipv6_mc_down(struct inet6_dev *idev) + synchronize_net(); + mld_query_stop_work(idev); + mld_report_stop_work(idev); ++ ++ mutex_lock(&idev->mc_lock); + mld_ifc_stop_work(idev); + mld_gq_stop_work(idev); ++ mutex_unlock(&idev->mc_lock); ++ + mld_dad_stop_work(idev); + } + +diff --git a/net/ipv6/netfilter/nf_reject_ipv6.c b/net/ipv6/netfilter/nf_reject_ipv6.c +index f61d4f18e1cf5..433d98bbe33f7 100644 +--- a/net/ipv6/netfilter/nf_reject_ipv6.c ++++ b/net/ipv6/netfilter/nf_reject_ipv6.c +@@ -278,7 +278,6 @@ static int nf_reject6_fill_skb_dst(struct sk_buff *skb_in) + void nf_send_reset6(struct net *net, struct sock *sk, struct sk_buff *oldskb, + int hook) + { +- struct net_device *br_indev __maybe_unused; + struct sk_buff *nskb; + struct tcphdr _otcph; + const struct tcphdr *otcph; +@@ -353,9 +352,15 @@ void nf_send_reset6(struct net *net, struct sock *sk, struct sk_buff *oldskb, + * build the eth header using the original destination's MAC as the + * source, and send the RST packet directly. + */ +- br_indev = nf_bridge_get_physindev(oldskb); +- if (br_indev) { ++ if (nf_bridge_info_exists(oldskb)) { + struct ethhdr *oeth = eth_hdr(oldskb); ++ struct net_device *br_indev; ++ ++ br_indev = nf_bridge_get_physindev(oldskb, net); ++ if (!br_indev) { ++ kfree_skb(nskb); ++ return; ++ } + + nskb->dev = br_indev; + nskb->protocol = htons(ETH_P_IPV6); +diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c +index 961106eda69d0..c2c02dea6c386 100644 +--- a/net/ipv6/udp.c ++++ b/net/ipv6/udp.c +@@ -1152,7 +1152,7 @@ static void udp_v6_flush_pending_frames(struct sock *sk) + udp_flush_pending_frames(sk); + else if (up->pending) { + up->len = 0; +- up->pending = 0; ++ WRITE_ONCE(up->pending, 0); + ip6_flush_pending_frames(sk); + } + } +@@ -1330,7 +1330,7 @@ static int udp_v6_push_pending_frames(struct sock *sk) + &inet_sk(sk)->cork.base); + out: + up->len = 0; +- up->pending = 0; ++ WRITE_ONCE(up->pending, 0); + return err; + } + +@@ -1387,7 +1387,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) + default: + return -EINVAL; + } +- } else if (!up->pending) { ++ } else if (!READ_ONCE(up->pending)) { + if (sk->sk_state != TCP_ESTABLISHED) + return -EDESTADDRREQ; + daddr = &sk->sk_v6_daddr; +@@ -1418,8 +1418,8 @@ do_udp_sendmsg: + return -EMSGSIZE; + + getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag; +- if (up->pending) { +- if (up->pending == AF_INET) ++ if (READ_ONCE(up->pending)) { ++ if (READ_ONCE(up->pending) == AF_INET) + return udp_sendmsg(sk, msg, len); + /* + * There are pending frames. +@@ -1609,7 +1609,7 @@ back_from_confirm: + goto out; + } + +- up->pending = AF_INET6; ++ WRITE_ONCE(up->pending, AF_INET6); + + do_append_data: + if (ipc6.dontfrag < 0) +@@ -1623,7 +1623,7 @@ do_append_data: + else if (!corkreq) + err = udp_v6_push_pending_frames(sk); + else if (unlikely(skb_queue_empty(&sk->sk_write_queue))) +- up->pending = 0; ++ WRITE_ONCE(up->pending, 0); + + if (err > 0) + err = np->recverr ? net_xmit_errno(err) : 0; +@@ -1663,7 +1663,7 @@ static void udpv6_splice_eof(struct socket *sock) + struct sock *sk = sock->sk; + struct udp_sock *up = udp_sk(sk); + +- if (!up->pending || udp_test_bit(CORK, sk)) ++ if (!READ_ONCE(up->pending) || udp_test_bit(CORK, sk)) + return; + + lock_sock(sk); +diff --git a/net/mptcp/options.c b/net/mptcp/options.c +index 74027bb5b4296..a718ebcb5bc63 100644 +--- a/net/mptcp/options.c ++++ b/net/mptcp/options.c +@@ -118,8 +118,8 @@ static void mptcp_parse_option(const struct sk_buff *skb, + break; + + case MPTCPOPT_MP_JOIN: +- mp_opt->suboptions |= OPTIONS_MPTCP_MPJ; + if (opsize == TCPOLEN_MPTCP_MPJ_SYN) { ++ mp_opt->suboptions |= OPTION_MPTCP_MPJ_SYN; + mp_opt->backup = *ptr++ & MPTCPOPT_BACKUP; + mp_opt->join_id = *ptr++; + mp_opt->token = get_unaligned_be32(ptr); +@@ -130,6 +130,7 @@ static void mptcp_parse_option(const struct sk_buff *skb, + mp_opt->backup, mp_opt->join_id, + mp_opt->token, mp_opt->nonce); + } else if (opsize == TCPOLEN_MPTCP_MPJ_SYNACK) { ++ mp_opt->suboptions |= OPTION_MPTCP_MPJ_SYNACK; + mp_opt->backup = *ptr++ & MPTCPOPT_BACKUP; + mp_opt->join_id = *ptr++; + mp_opt->thmac = get_unaligned_be64(ptr); +@@ -140,11 +141,10 @@ static void mptcp_parse_option(const struct sk_buff *skb, + mp_opt->backup, mp_opt->join_id, + mp_opt->thmac, mp_opt->nonce); + } else if (opsize == TCPOLEN_MPTCP_MPJ_ACK) { ++ mp_opt->suboptions |= OPTION_MPTCP_MPJ_ACK; + ptr += 2; + memcpy(mp_opt->hmac, ptr, MPTCPOPT_HMAC_LEN); + pr_debug("MP_JOIN hmac"); +- } else { +- mp_opt->suboptions &= ~OPTIONS_MPTCP_MPJ; + } + break; + +diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c +index 8ed7769cae836..45d20e20cfc00 100644 +--- a/net/mptcp/subflow.c ++++ b/net/mptcp/subflow.c +@@ -156,8 +156,8 @@ static int subflow_check_req(struct request_sock *req, + + mptcp_get_options(skb, &mp_opt); + +- opt_mp_capable = !!(mp_opt.suboptions & OPTIONS_MPTCP_MPC); +- opt_mp_join = !!(mp_opt.suboptions & OPTIONS_MPTCP_MPJ); ++ opt_mp_capable = !!(mp_opt.suboptions & OPTION_MPTCP_MPC_SYN); ++ opt_mp_join = !!(mp_opt.suboptions & OPTION_MPTCP_MPJ_SYN); + if (opt_mp_capable) { + SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_MPCAPABLEPASSIVE); + +@@ -253,8 +253,8 @@ int mptcp_subflow_init_cookie_req(struct request_sock *req, + subflow_init_req(req, sk_listener); + mptcp_get_options(skb, &mp_opt); + +- opt_mp_capable = !!(mp_opt.suboptions & OPTIONS_MPTCP_MPC); +- opt_mp_join = !!(mp_opt.suboptions & OPTIONS_MPTCP_MPJ); ++ opt_mp_capable = !!(mp_opt.suboptions & OPTION_MPTCP_MPC_ACK); ++ opt_mp_join = !!(mp_opt.suboptions & OPTION_MPTCP_MPJ_ACK); + if (opt_mp_capable && opt_mp_join) + return -EINVAL; + +@@ -415,7 +415,7 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb) + + mptcp_get_options(skb, &mp_opt); + if (subflow->request_mptcp) { +- if (!(mp_opt.suboptions & OPTIONS_MPTCP_MPC)) { ++ if (!(mp_opt.suboptions & OPTION_MPTCP_MPC_SYNACK)) { + MPTCP_INC_STATS(sock_net(sk), + MPTCP_MIB_MPCAPABLEACTIVEFALLBACK); + mptcp_do_fallback(sk); +@@ -438,7 +438,7 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb) + } else if (subflow->request_join) { + u8 hmac[SHA256_DIGEST_SIZE]; + +- if (!(mp_opt.suboptions & OPTIONS_MPTCP_MPJ)) { ++ if (!(mp_opt.suboptions & OPTION_MPTCP_MPJ_SYNACK)) { + subflow->reset_reason = MPTCP_RST_EMPTCP; + goto do_reset; + } +@@ -713,12 +713,13 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk, + * options. + */ + mptcp_get_options(skb, &mp_opt); +- if (!(mp_opt.suboptions & OPTIONS_MPTCP_MPC)) ++ if (!(mp_opt.suboptions & ++ (OPTION_MPTCP_MPC_SYN | OPTION_MPTCP_MPC_ACK))) + fallback = true; + + } else if (subflow_req->mp_join) { + mptcp_get_options(skb, &mp_opt); +- if (!(mp_opt.suboptions & OPTIONS_MPTCP_MPJ) || ++ if (!(mp_opt.suboptions & OPTION_MPTCP_MPJ_ACK) || + !subflow_hmac_valid(req, &mp_opt) || + !mptcp_can_accept_new_subflow(subflow_req->msk)) { + SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINACKMAC); +diff --git a/net/ncsi/internal.h b/net/ncsi/internal.h +index 03757e76bb6b9..374412ed780b6 100644 +--- a/net/ncsi/internal.h ++++ b/net/ncsi/internal.h +@@ -105,8 +105,11 @@ enum { + + + struct ncsi_channel_version { +- u32 version; /* Supported BCD encoded NCSI version */ +- u32 alpha2; /* Supported BCD encoded NCSI version */ ++ u8 major; /* NCSI version major */ ++ u8 minor; /* NCSI version minor */ ++ u8 update; /* NCSI version update */ ++ char alpha1; /* NCSI version alpha1 */ ++ char alpha2; /* NCSI version alpha2 */ + u8 fw_name[12]; /* Firmware name string */ + u32 fw_version; /* Firmware version */ + u16 pci_ids[4]; /* PCI identification */ +diff --git a/net/ncsi/ncsi-netlink.c b/net/ncsi/ncsi-netlink.c +index d27f4eccce6d7..fe681680b5d91 100644 +--- a/net/ncsi/ncsi-netlink.c ++++ b/net/ncsi/ncsi-netlink.c +@@ -71,8 +71,8 @@ static int ncsi_write_channel_info(struct sk_buff *skb, + if (nc == nc->package->preferred_channel) + nla_put_flag(skb, NCSI_CHANNEL_ATTR_FORCED); + +- nla_put_u32(skb, NCSI_CHANNEL_ATTR_VERSION_MAJOR, nc->version.version); +- nla_put_u32(skb, NCSI_CHANNEL_ATTR_VERSION_MINOR, nc->version.alpha2); ++ nla_put_u32(skb, NCSI_CHANNEL_ATTR_VERSION_MAJOR, nc->version.major); ++ nla_put_u32(skb, NCSI_CHANNEL_ATTR_VERSION_MINOR, nc->version.minor); + nla_put_string(skb, NCSI_CHANNEL_ATTR_VERSION_STR, nc->version.fw_name); + + vid_nest = nla_nest_start_noflag(skb, NCSI_CHANNEL_ATTR_VLAN_LIST); +diff --git a/net/ncsi/ncsi-pkt.h b/net/ncsi/ncsi-pkt.h +index ba66c7dc3a216..c9d1da34dc4dc 100644 +--- a/net/ncsi/ncsi-pkt.h ++++ b/net/ncsi/ncsi-pkt.h +@@ -197,9 +197,12 @@ struct ncsi_rsp_gls_pkt { + /* Get Version ID */ + struct ncsi_rsp_gvi_pkt { + struct ncsi_rsp_pkt_hdr rsp; /* Response header */ +- __be32 ncsi_version; /* NCSI version */ ++ unsigned char major; /* NCSI version major */ ++ unsigned char minor; /* NCSI version minor */ ++ unsigned char update; /* NCSI version update */ ++ unsigned char alpha1; /* NCSI version alpha1 */ + unsigned char reserved[3]; /* Reserved */ +- unsigned char alpha2; /* NCSI version */ ++ unsigned char alpha2; /* NCSI version alpha2 */ + unsigned char fw_name[12]; /* f/w name string */ + __be32 fw_version; /* f/w version */ + __be16 pci_ids[4]; /* PCI IDs */ +diff --git a/net/ncsi/ncsi-rsp.c b/net/ncsi/ncsi-rsp.c +index 069c2659074bc..480e80e3c2836 100644 +--- a/net/ncsi/ncsi-rsp.c ++++ b/net/ncsi/ncsi-rsp.c +@@ -19,6 +19,19 @@ + #include "ncsi-pkt.h" + #include "ncsi-netlink.h" + ++/* Nibbles within [0xA, 0xF] add zero "0" to the returned value. ++ * Optional fields (encoded as 0xFF) will default to zero. ++ */ ++static u8 decode_bcd_u8(u8 x) ++{ ++ int lo = x & 0xF; ++ int hi = x >> 4; ++ ++ lo = lo < 0xA ? lo : 0; ++ hi = hi < 0xA ? hi : 0; ++ return lo + hi * 10; ++} ++ + static int ncsi_validate_rsp_pkt(struct ncsi_request *nr, + unsigned short payload) + { +@@ -755,9 +768,18 @@ static int ncsi_rsp_handler_gvi(struct ncsi_request *nr) + if (!nc) + return -ENODEV; + +- /* Update to channel's version info */ ++ /* Update channel's version info ++ * ++ * Major, minor, and update fields are supposed to be ++ * unsigned integers encoded as packed BCD. ++ * ++ * Alpha1 and alpha2 are ISO/IEC 8859-1 characters. ++ */ + ncv = &nc->version; +- ncv->version = ntohl(rsp->ncsi_version); ++ ncv->major = decode_bcd_u8(rsp->major); ++ ncv->minor = decode_bcd_u8(rsp->minor); ++ ncv->update = decode_bcd_u8(rsp->update); ++ ncv->alpha1 = rsp->alpha1; + ncv->alpha2 = rsp->alpha2; + memcpy(ncv->fw_name, rsp->fw_name, 12); + ncv->fw_version = ntohl(rsp->fw_version); +diff --git a/net/netfilter/ipset/ip_set_hash_netiface.c b/net/netfilter/ipset/ip_set_hash_netiface.c +index 0310732862362..bf1a3851ba5a7 100644 +--- a/net/netfilter/ipset/ip_set_hash_netiface.c ++++ b/net/netfilter/ipset/ip_set_hash_netiface.c +@@ -138,9 +138,9 @@ hash_netiface4_data_next(struct hash_netiface4_elem *next, + #include "ip_set_hash_gen.h" + + #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) +-static const char *get_physindev_name(const struct sk_buff *skb) ++static const char *get_physindev_name(const struct sk_buff *skb, struct net *net) + { +- struct net_device *dev = nf_bridge_get_physindev(skb); ++ struct net_device *dev = nf_bridge_get_physindev(skb, net); + + return dev ? dev->name : NULL; + } +@@ -177,7 +177,7 @@ hash_netiface4_kadt(struct ip_set *set, const struct sk_buff *skb, + + if (opt->cmdflags & IPSET_FLAG_PHYSDEV) { + #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) +- const char *eiface = SRCDIR ? get_physindev_name(skb) : ++ const char *eiface = SRCDIR ? get_physindev_name(skb, xt_net(par)) : + get_physoutdev_name(skb); + + if (!eiface) +@@ -395,7 +395,7 @@ hash_netiface6_kadt(struct ip_set *set, const struct sk_buff *skb, + + if (opt->cmdflags & IPSET_FLAG_PHYSDEV) { + #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) +- const char *eiface = SRCDIR ? get_physindev_name(skb) : ++ const char *eiface = SRCDIR ? get_physindev_name(skb, xt_net(par)) : + get_physoutdev_name(skb); + + if (!eiface) +diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c +index b452eb3ddcecb..d40a4ca2b27f5 100644 +--- a/net/netfilter/ipvs/ip_vs_xmit.c ++++ b/net/netfilter/ipvs/ip_vs_xmit.c +@@ -271,7 +271,7 @@ static inline bool decrement_ttl(struct netns_ipvs *ipvs, + skb->dev = dst->dev; + icmpv6_send(skb, ICMPV6_TIME_EXCEED, + ICMPV6_EXC_HOPLIMIT, 0); +- __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS); ++ IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS); + + return false; + } +@@ -286,7 +286,7 @@ static inline bool decrement_ttl(struct netns_ipvs *ipvs, + { + if (ip_hdr(skb)->ttl <= 1) { + /* Tell the sender its packet died... */ +- __IP_INC_STATS(net, IPSTATS_MIB_INHDRERRORS); ++ IP_INC_STATS(net, IPSTATS_MIB_INHDRERRORS); + icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0); + return false; + } +diff --git a/net/netfilter/nf_log_syslog.c b/net/netfilter/nf_log_syslog.c +index c66689ad2b491..58402226045e8 100644 +--- a/net/netfilter/nf_log_syslog.c ++++ b/net/netfilter/nf_log_syslog.c +@@ -111,7 +111,8 @@ nf_log_dump_packet_common(struct nf_log_buf *m, u8 pf, + unsigned int hooknum, const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, +- const struct nf_loginfo *loginfo, const char *prefix) ++ const struct nf_loginfo *loginfo, const char *prefix, ++ struct net *net) + { + const struct net_device *physoutdev __maybe_unused; + const struct net_device *physindev __maybe_unused; +@@ -121,7 +122,7 @@ nf_log_dump_packet_common(struct nf_log_buf *m, u8 pf, + in ? in->name : "", + out ? out->name : ""); + #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) +- physindev = nf_bridge_get_physindev(skb); ++ physindev = nf_bridge_get_physindev(skb, net); + if (physindev && in != physindev) + nf_log_buf_add(m, "PHYSIN=%s ", physindev->name); + physoutdev = nf_bridge_get_physoutdev(skb); +@@ -148,7 +149,7 @@ static void nf_log_arp_packet(struct net *net, u_int8_t pf, + loginfo = &default_loginfo; + + nf_log_dump_packet_common(m, pf, hooknum, skb, in, out, loginfo, +- prefix); ++ prefix, net); + dump_arp_packet(m, loginfo, skb, skb_network_offset(skb)); + + nf_log_buf_close(m); +@@ -845,7 +846,7 @@ static void nf_log_ip_packet(struct net *net, u_int8_t pf, + loginfo = &default_loginfo; + + nf_log_dump_packet_common(m, pf, hooknum, skb, in, +- out, loginfo, prefix); ++ out, loginfo, prefix, net); + + if (in) + dump_mac_header(m, loginfo, skb); +@@ -880,7 +881,7 @@ static void nf_log_ip6_packet(struct net *net, u_int8_t pf, + loginfo = &default_loginfo; + + nf_log_dump_packet_common(m, pf, hooknum, skb, in, out, +- loginfo, prefix); ++ loginfo, prefix, net); + + if (in) + dump_mac_header(m, loginfo, skb); +@@ -916,7 +917,7 @@ static void nf_log_unknown_packet(struct net *net, u_int8_t pf, + loginfo = &default_loginfo; + + nf_log_dump_packet_common(m, pf, hooknum, skb, in, out, loginfo, +- prefix); ++ prefix, net); + + dump_mac_header(m, loginfo, skb); + +diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c +index 63d1516816b1f..e2f334f70281f 100644 +--- a/net/netfilter/nf_queue.c ++++ b/net/netfilter/nf_queue.c +@@ -82,11 +82,9 @@ static void __nf_queue_entry_init_physdevs(struct nf_queue_entry *entry) + { + #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) + const struct sk_buff *skb = entry->skb; +- struct nf_bridge_info *nf_bridge; + +- nf_bridge = nf_bridge_info_get(skb); +- if (nf_bridge) { +- entry->physin = nf_bridge_get_physindev(skb); ++ if (nf_bridge_info_exists(skb)) { ++ entry->physin = nf_bridge_get_physindev(skb, entry->state.net); + entry->physout = nf_bridge_get_physoutdev(skb); + } else { + entry->physin = NULL; +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index 3d6ebb9877a4e..2702294ac46c6 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -4523,8 +4523,8 @@ static int nft_set_desc_concat_parse(const struct nlattr *attr, + static int nft_set_desc_concat(struct nft_set_desc *desc, + const struct nlattr *nla) + { ++ u32 num_regs = 0, key_num_regs = 0; + struct nlattr *attr; +- u32 num_regs = 0; + int rem, err, i; + + nla_for_each_nested(attr, nla, rem) { +@@ -4539,6 +4539,10 @@ static int nft_set_desc_concat(struct nft_set_desc *desc, + for (i = 0; i < desc->field_count; i++) + num_regs += DIV_ROUND_UP(desc->field_len[i], sizeof(u32)); + ++ key_num_regs = DIV_ROUND_UP(desc->klen, sizeof(u32)); ++ if (key_num_regs != num_regs) ++ return -EINVAL; ++ + if (num_regs > NFT_REG32_COUNT) + return -E2BIG; + +@@ -4753,16 +4757,28 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info, + } + + desc.policy = NFT_SET_POL_PERFORMANCE; +- if (nla[NFTA_SET_POLICY] != NULL) ++ if (nla[NFTA_SET_POLICY] != NULL) { + desc.policy = ntohl(nla_get_be32(nla[NFTA_SET_POLICY])); ++ switch (desc.policy) { ++ case NFT_SET_POL_PERFORMANCE: ++ case NFT_SET_POL_MEMORY: ++ break; ++ default: ++ return -EOPNOTSUPP; ++ } ++ } + + if (nla[NFTA_SET_DESC] != NULL) { + err = nf_tables_set_desc_parse(&desc, nla[NFTA_SET_DESC]); + if (err < 0) + return err; + +- if (desc.field_count > 1 && !(flags & NFT_SET_CONCAT)) ++ if (desc.field_count > 1) { ++ if (!(flags & NFT_SET_CONCAT)) ++ return -EINVAL; ++ } else if (flags & NFT_SET_CONCAT) { + return -EINVAL; ++ } + } else if (flags & NFT_SET_CONCAT) { + return -EINVAL; + } +@@ -5406,7 +5422,7 @@ static int nf_tables_dump_setelem(const struct nft_ctx *ctx, + const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv); + struct nft_set_dump_args *args; + +- if (nft_set_elem_expired(ext)) ++ if (nft_set_elem_expired(ext) || nft_set_elem_is_dead(ext)) + return 0; + + args = container_of(iter, struct nft_set_dump_args, iter); +@@ -6152,7 +6168,7 @@ static int nft_setelem_catchall_deactivate(const struct net *net, + + list_for_each_entry(catchall, &set->catchall_list, list) { + ext = nft_set_elem_ext(set, catchall->elem); +- if (!nft_is_active(net, ext)) ++ if (!nft_is_active_next(net, ext)) + continue; + + kfree(elem->priv); +@@ -9937,6 +9953,7 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action) + nft_trans_destroy(trans); + break; + } ++ nft_trans_set(trans)->dead = 1; + list_del_rcu(&nft_trans_set(trans)->list); + break; + case NFT_MSG_DELSET: +diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c +index c5ff699e30469..200a82a8f943d 100644 +--- a/net/netfilter/nfnetlink_log.c ++++ b/net/netfilter/nfnetlink_log.c +@@ -499,7 +499,7 @@ __build_packet_message(struct nfnl_log_net *log, + htonl(br_port_get_rcu(indev)->br->dev->ifindex))) + goto nla_put_failure; + } else { +- struct net_device *physindev; ++ int physinif; + + /* Case 2: indev is bridge group, we need to look for + * physical device (when called from ipv4) */ +@@ -507,10 +507,10 @@ __build_packet_message(struct nfnl_log_net *log, + htonl(indev->ifindex))) + goto nla_put_failure; + +- physindev = nf_bridge_get_physindev(skb); +- if (physindev && ++ physinif = nf_bridge_get_physinif(skb); ++ if (physinif && + nla_put_be32(inst->skb, NFULA_IFINDEX_PHYSINDEV, +- htonl(physindev->ifindex))) ++ htonl(physinif))) + goto nla_put_failure; + } + #endif +diff --git a/net/netfilter/nft_limit.c b/net/netfilter/nft_limit.c +index 981addb2d0515..75c05ef885a91 100644 +--- a/net/netfilter/nft_limit.c ++++ b/net/netfilter/nft_limit.c +@@ -58,6 +58,7 @@ static inline bool nft_limit_eval(struct nft_limit_priv *priv, u64 cost) + static int nft_limit_init(struct nft_limit_priv *priv, + const struct nlattr * const tb[], bool pkts) + { ++ bool invert = false; + u64 unit, tokens; + + if (tb[NFTA_LIMIT_RATE] == NULL || +@@ -90,19 +91,23 @@ static int nft_limit_init(struct nft_limit_priv *priv, + priv->rate); + } + ++ if (tb[NFTA_LIMIT_FLAGS]) { ++ u32 flags = ntohl(nla_get_be32(tb[NFTA_LIMIT_FLAGS])); ++ ++ if (flags & ~NFT_LIMIT_F_INV) ++ return -EOPNOTSUPP; ++ ++ if (flags & NFT_LIMIT_F_INV) ++ invert = true; ++ } ++ + priv->limit = kmalloc(sizeof(*priv->limit), GFP_KERNEL_ACCOUNT); + if (!priv->limit) + return -ENOMEM; + + priv->limit->tokens = tokens; + priv->tokens_max = priv->limit->tokens; +- +- if (tb[NFTA_LIMIT_FLAGS]) { +- u32 flags = ntohl(nla_get_be32(tb[NFTA_LIMIT_FLAGS])); +- +- if (flags & NFT_LIMIT_F_INV) +- priv->invert = true; +- } ++ priv->invert = invert; + priv->limit->last = ktime_get_ns(); + spin_lock_init(&priv->limit->lock); + +diff --git a/net/netfilter/xt_physdev.c b/net/netfilter/xt_physdev.c +index ec6ed6fda96c5..343e65f377d44 100644 +--- a/net/netfilter/xt_physdev.c ++++ b/net/netfilter/xt_physdev.c +@@ -59,7 +59,7 @@ physdev_mt(const struct sk_buff *skb, struct xt_action_param *par) + (!!outdev ^ !(info->invert & XT_PHYSDEV_OP_BRIDGED))) + return false; + +- physdev = nf_bridge_get_physindev(skb); ++ physdev = nf_bridge_get_physindev(skb, xt_net(par)); + indev = physdev ? physdev->name : NULL; + + if ((info->bitmask & XT_PHYSDEV_OP_ISIN && +diff --git a/net/netlabel/netlabel_calipso.c b/net/netlabel/netlabel_calipso.c +index f1d5b84652178..a07c2216d28b6 100644 +--- a/net/netlabel/netlabel_calipso.c ++++ b/net/netlabel/netlabel_calipso.c +@@ -54,6 +54,28 @@ static const struct nla_policy calipso_genl_policy[NLBL_CALIPSO_A_MAX + 1] = { + [NLBL_CALIPSO_A_MTYPE] = { .type = NLA_U32 }, + }; + ++static const struct netlbl_calipso_ops *calipso_ops; ++ ++/** ++ * netlbl_calipso_ops_register - Register the CALIPSO operations ++ * @ops: ops to register ++ * ++ * Description: ++ * Register the CALIPSO packet engine operations. ++ * ++ */ ++const struct netlbl_calipso_ops * ++netlbl_calipso_ops_register(const struct netlbl_calipso_ops *ops) ++{ ++ return xchg(&calipso_ops, ops); ++} ++EXPORT_SYMBOL(netlbl_calipso_ops_register); ++ ++static const struct netlbl_calipso_ops *netlbl_calipso_ops_get(void) ++{ ++ return READ_ONCE(calipso_ops); ++} ++ + /* NetLabel Command Handlers + */ + /** +@@ -96,15 +118,18 @@ static int netlbl_calipso_add_pass(struct genl_info *info, + * + */ + static int netlbl_calipso_add(struct sk_buff *skb, struct genl_info *info) +- + { + int ret_val = -EINVAL; + struct netlbl_audit audit_info; ++ const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get(); + + if (!info->attrs[NLBL_CALIPSO_A_DOI] || + !info->attrs[NLBL_CALIPSO_A_MTYPE]) + return -EINVAL; + ++ if (!ops) ++ return -EOPNOTSUPP; ++ + netlbl_netlink_auditinfo(&audit_info); + switch (nla_get_u32(info->attrs[NLBL_CALIPSO_A_MTYPE])) { + case CALIPSO_MAP_PASS: +@@ -363,28 +388,6 @@ int __init netlbl_calipso_genl_init(void) + return genl_register_family(&netlbl_calipso_gnl_family); + } + +-static const struct netlbl_calipso_ops *calipso_ops; +- +-/** +- * netlbl_calipso_ops_register - Register the CALIPSO operations +- * @ops: ops to register +- * +- * Description: +- * Register the CALIPSO packet engine operations. +- * +- */ +-const struct netlbl_calipso_ops * +-netlbl_calipso_ops_register(const struct netlbl_calipso_ops *ops) +-{ +- return xchg(&calipso_ops, ops); +-} +-EXPORT_SYMBOL(netlbl_calipso_ops_register); +- +-static const struct netlbl_calipso_ops *netlbl_calipso_ops_get(void) +-{ +- return READ_ONCE(calipso_ops); +-} +- + /** + * calipso_doi_add - Add a new DOI to the CALIPSO protocol engine + * @doi_def: the DOI structure +diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c +index d6d33f854050a..84e15116f18c2 100644 +--- a/net/sched/act_ct.c ++++ b/net/sched/act_ct.c +@@ -863,7 +863,6 @@ static int tcf_ct_handle_fragments(struct net *net, struct sk_buff *skb, + if (err || !frag) + return err; + +- skb_get(skb); + mru = tc_skb_cb(skb)->mru; + + if (family == NFPROTO_IPV4) { +@@ -1150,12 +1149,8 @@ static int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a, + nh_ofs = skb_network_offset(skb); + skb_pull_rcsum(skb, nh_ofs); + err = tcf_ct_handle_fragments(net, skb, family, p->zone, &defrag); +- if (err == -EINPROGRESS) { +- retval = TC_ACT_STOLEN; +- goto out_clear; +- } + if (err) +- goto drop; ++ goto out_frag; + + err = tcf_ct_skb_network_trim(skb, family); + if (err) +@@ -1226,6 +1221,11 @@ out_clear: + qdisc_skb_cb(skb)->pkt_len = skb->len; + return retval; + ++out_frag: ++ if (err != -EINPROGRESS) ++ tcf_action_inc_drop_qstats(&c->common); ++ return TC_ACT_CONSUMED; ++ + drop: + tcf_action_inc_drop_qstats(&c->common); + return TC_ACT_SHOT; +diff --git a/net/sctp/socket.c b/net/sctp/socket.c +index e25dc17091311..237a6b04adf6f 100644 +--- a/net/sctp/socket.c ++++ b/net/sctp/socket.c +@@ -2098,6 +2098,13 @@ static int sctp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, + pr_debug("%s: sk:%p, msghdr:%p, len:%zd, flags:0x%x, addr_len:%p)\n", + __func__, sk, msg, len, flags, addr_len); + ++ if (unlikely(flags & MSG_ERRQUEUE)) ++ return inet_recv_error(sk, msg, len, addr_len); ++ ++ if (sk_can_busy_loop(sk) && ++ skb_queue_empty_lockless(&sk->sk_receive_queue)) ++ sk_busy_loop(sk, flags & MSG_DONTWAIT); ++ + lock_sock(sk); + + if (sctp_style(sk, TCP) && !sctp_sstate(sk, ESTABLISHED) && +@@ -9038,12 +9045,6 @@ struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags, int *err) + if (sk->sk_shutdown & RCV_SHUTDOWN) + break; + +- if (sk_can_busy_loop(sk)) { +- sk_busy_loop(sk, flags & MSG_DONTWAIT); +- +- if (!skb_queue_empty_lockless(&sk->sk_receive_queue)) +- continue; +- } + + /* User doesn't want to wait. */ + error = -EAGAIN; +diff --git a/net/sunrpc/xprtmultipath.c b/net/sunrpc/xprtmultipath.c +index 701250b305dba..74ee2271251e3 100644 +--- a/net/sunrpc/xprtmultipath.c ++++ b/net/sunrpc/xprtmultipath.c +@@ -284,7 +284,7 @@ struct rpc_xprt *_xprt_switch_find_current_entry(struct list_head *head, + if (cur == pos) + found = true; + if (found && ((find_active && xprt_is_active(pos)) || +- (!find_active && xprt_is_active(pos)))) ++ (!find_active && !xprt_is_active(pos)))) + return pos; + } + return NULL; +diff --git a/net/unix/unix_bpf.c b/net/unix/unix_bpf.c +index 7ea7c3a0d0d06..bd84785bf8d6c 100644 +--- a/net/unix/unix_bpf.c ++++ b/net/unix/unix_bpf.c +@@ -161,15 +161,30 @@ int unix_stream_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool r + { + struct sock *sk_pair; + ++ /* Restore does not decrement the sk_pair reference yet because we must ++ * keep the a reference to the socket until after an RCU grace period ++ * and any pending sends have completed. ++ */ + if (restore) { + sk->sk_write_space = psock->saved_write_space; + sock_replace_proto(sk, psock->sk_proto); + return 0; + } + +- sk_pair = unix_peer(sk); +- sock_hold(sk_pair); +- psock->sk_pair = sk_pair; ++ /* psock_update_sk_prot can be called multiple times if psock is ++ * added to multiple maps and/or slots in the same map. There is ++ * also an edge case where replacing a psock with itself can trigger ++ * an extra psock_update_sk_prot during the insert process. So it ++ * must be safe to do multiple calls. Here we need to ensure we don't ++ * increment the refcnt through sock_hold many times. There will only ++ * be a single matching destroy operation. ++ */ ++ if (!psock->sk_pair) { ++ sk_pair = unix_peer(sk); ++ sock_hold(sk_pair); ++ psock->sk_pair = sk_pair; ++ } ++ + unix_stream_bpf_check_needs_rebuild(psock->sk_proto); + sock_replace_proto(sk, &unix_stream_bpf_prot); + return 0; +diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c +index 2e25890ca52d1..9983b833b55d8 100644 +--- a/net/vmw_vsock/virtio_transport_common.c ++++ b/net/vmw_vsock/virtio_transport_common.c +@@ -366,6 +366,8 @@ virtio_transport_stream_do_dequeue(struct vsock_sock *vsk, + struct virtio_vsock_sock *vvs = vsk->trans; + size_t bytes, total = 0; + struct sk_buff *skb; ++ u32 fwd_cnt_delta; ++ bool low_rx_bytes; + int err = -EFAULT; + u32 free_space; + +@@ -400,7 +402,10 @@ virtio_transport_stream_do_dequeue(struct vsock_sock *vsk, + } + } + +- free_space = vvs->buf_alloc - (vvs->fwd_cnt - vvs->last_fwd_cnt); ++ fwd_cnt_delta = vvs->fwd_cnt - vvs->last_fwd_cnt; ++ free_space = vvs->buf_alloc - fwd_cnt_delta; ++ low_rx_bytes = (vvs->rx_bytes < ++ sock_rcvlowat(sk_vsock(vsk), 0, INT_MAX)); + + spin_unlock_bh(&vvs->rx_lock); + +@@ -410,9 +415,11 @@ virtio_transport_stream_do_dequeue(struct vsock_sock *vsk, + * too high causes extra messages. Too low causes transmitter + * stalls. As stalls are in theory more expensive than extra + * messages, we set the limit to a high value. TODO: experiment +- * with different values. ++ * with different values. Also send credit update message when ++ * number of bytes in rx queue is not enough to wake up reader. + */ +- if (free_space < VIRTIO_VSOCK_MAX_PKT_BUF_SIZE) ++ if (fwd_cnt_delta && ++ (free_space < VIRTIO_VSOCK_MAX_PKT_BUF_SIZE || low_rx_bytes)) + virtio_transport_send_credit_update(vsk); + + return total; +diff --git a/scripts/Makefile.compiler b/scripts/Makefile.compiler +index 158c57f2acfde..87589a7ba27f3 100644 +--- a/scripts/Makefile.compiler ++++ b/scripts/Makefile.compiler +@@ -72,7 +72,3 @@ clang-min-version = $(shell [ $(CONFIG_CLANG_VERSION)0 -ge $(1)0 ] && echo y) + # ld-option + # Usage: KBUILD_LDFLAGS += $(call ld-option, -X, -Y) + ld-option = $(call try-run, $(LD) $(KBUILD_LDFLAGS) $(1) -v,$(1),$(2),$(3)) +- +-# ld-ifversion +-# Usage: $(call ld-ifversion, -ge, 22252, y) +-ld-ifversion = $(shell [ $(CONFIG_LD_VERSION)0 $(1) $(2)0 ] && echo $(3) || echo $(4)) +diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c +index 7012fd82f1bb1..633e778ec3692 100644 +--- a/security/apparmor/policy_unpack.c ++++ b/security/apparmor/policy_unpack.c +@@ -674,6 +674,10 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) + + tmpname = aa_splitn_fqname(name, strlen(name), &tmpns, &ns_len); + if (tmpns) { ++ if (!tmpname) { ++ info = "empty profile name"; ++ goto fail; ++ } + *ns_name = kstrndup(tmpns, ns_len, GFP_KERNEL); + if (!*ns_name) { + info = "out of memory"; +diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c +index d88c399b0e86b..d45e9fa74e62d 100644 +--- a/security/selinux/hooks.c ++++ b/security/selinux/hooks.c +@@ -4690,6 +4690,13 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in + return -EINVAL; + addr4 = (struct sockaddr_in *)address; + if (family_sa == AF_UNSPEC) { ++ if (family == PF_INET6) { ++ /* Length check from inet6_bind_sk() */ ++ if (addrlen < SIN6_LEN_RFC2133) ++ return -EINVAL; ++ /* Family check from __inet6_bind() */ ++ goto err_af; ++ } + /* see __inet_bind(), we only want to allow + * AF_UNSPEC if the address is INADDR_ANY + */ +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 5efb3adee48d9..62f2137044923 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -9626,6 +9626,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x103c, 0x87f5, "HP", ALC287_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x87f6, "HP Spectre x360 14", ALC245_FIXUP_HP_X360_AMP), + SND_PCI_QUIRK(0x103c, 0x87f7, "HP Spectre x360 14", ALC245_FIXUP_HP_X360_AMP), ++ SND_PCI_QUIRK(0x103c, 0x87fe, "HP Laptop 15s-fq2xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), + SND_PCI_QUIRK(0x103c, 0x8805, "HP ProBook 650 G8 Notebook PC", ALC236_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x880d, "HP EliteBook 830 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8811, "HP Spectre x360 15-eb1xxx", ALC285_FIXUP_HP_SPECTRE_X360_EB1), +@@ -9720,6 +9721,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x103c, 0x8c71, "HP EliteBook 845 G11", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8c72, "HP EliteBook 865 G11", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8c96, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), ++ SND_PCI_QUIRK(0x103c, 0x8c97, "HP ZBook", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), + SND_PCI_QUIRK(0x103c, 0x8ca4, "HP ZBook Fury", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8ca7, "HP ZBook Fury", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8cf5, "HP ZBook Studio 16", ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED), +@@ -9978,6 +9980,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x17aa, 0x3176, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC), + SND_PCI_QUIRK(0x17aa, 0x3178, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC), + SND_PCI_QUIRK(0x17aa, 0x31af, "ThinkCentre Station", ALC623_FIXUP_LENOVO_THINKSTATION_P340), ++ SND_PCI_QUIRK(0x17aa, 0x334b, "Lenovo ThinkCentre M70 Gen5", ALC283_FIXUP_HEADSET_MIC), + SND_PCI_QUIRK(0x17aa, 0x3801, "Lenovo Yoga9 14IAP7", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN), + SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo Yoga DuetITL 2021", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS), + SND_PCI_QUIRK(0x17aa, 0x3813, "Legion 7i 15IMHG05", ALC287_FIXUP_LEGION_15IMHG05_SPEAKERS), +diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c +index 46705ec77b481..eb3aca16359c5 100644 +--- a/sound/pci/oxygen/oxygen_mixer.c ++++ b/sound/pci/oxygen/oxygen_mixer.c +@@ -718,7 +718,7 @@ static int ac97_fp_rec_volume_put(struct snd_kcontrol *ctl, + oldreg = oxygen_read_ac97(chip, 1, AC97_REC_GAIN); + newreg = oldreg & ~0x0707; + newreg = newreg | (value->value.integer.value[0] & 7); +- newreg = newreg | ((value->value.integer.value[0] & 7) << 8); ++ newreg = newreg | ((value->value.integer.value[1] & 7) << 8); + change = newreg != oldreg; + if (change) + oxygen_write_ac97(chip, 1, AC97_REC_GAIN, newreg); +diff --git a/sound/soc/codecs/cs35l33.c b/sound/soc/codecs/cs35l33.c +index 15e79168d256e..c3b7046fd29ba 100644 +--- a/sound/soc/codecs/cs35l33.c ++++ b/sound/soc/codecs/cs35l33.c +@@ -22,13 +22,11 @@ + #include <sound/soc-dapm.h> + #include <sound/initval.h> + #include <sound/tlv.h> +-#include <linux/gpio.h> + #include <linux/gpio/consumer.h> + #include <sound/cs35l33.h> + #include <linux/pm_runtime.h> + #include <linux/regulator/consumer.h> + #include <linux/regulator/machine.h> +-#include <linux/of_gpio.h> + #include <linux/of.h> + #include <linux/of_device.h> + #include <linux/of_irq.h> +@@ -1167,7 +1165,7 @@ static int cs35l33_i2c_probe(struct i2c_client *i2c_client) + + /* We could issue !RST or skip it based on AMP topology */ + cs35l33->reset_gpio = devm_gpiod_get_optional(&i2c_client->dev, +- "reset-gpios", GPIOD_OUT_HIGH); ++ "reset", GPIOD_OUT_HIGH); + if (IS_ERR(cs35l33->reset_gpio)) { + dev_err(&i2c_client->dev, "%s ERROR: Can't get reset GPIO\n", + __func__); +diff --git a/sound/soc/codecs/cs35l34.c b/sound/soc/codecs/cs35l34.c +index b3f98023e6a75..57d125c03fad0 100644 +--- a/sound/soc/codecs/cs35l34.c ++++ b/sound/soc/codecs/cs35l34.c +@@ -20,14 +20,12 @@ + #include <linux/regulator/machine.h> + #include <linux/pm_runtime.h> + #include <linux/of_device.h> +-#include <linux/of_gpio.h> + #include <linux/of_irq.h> + #include <sound/core.h> + #include <sound/pcm.h> + #include <sound/pcm_params.h> + #include <sound/soc.h> + #include <sound/soc-dapm.h> +-#include <linux/gpio.h> + #include <linux/gpio/consumer.h> + #include <sound/initval.h> + #include <sound/tlv.h> +@@ -1061,7 +1059,7 @@ static int cs35l34_i2c_probe(struct i2c_client *i2c_client) + dev_err(&i2c_client->dev, "Failed to request IRQ: %d\n", ret); + + cs35l34->reset_gpio = devm_gpiod_get_optional(&i2c_client->dev, +- "reset-gpios", GPIOD_OUT_LOW); ++ "reset", GPIOD_OUT_LOW); + if (IS_ERR(cs35l34->reset_gpio)) { + ret = PTR_ERR(cs35l34->reset_gpio); + goto err_regulator; +diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c +index 60518ee5a86e7..fd3dca08460ba 100644 +--- a/sound/soc/codecs/rt5645.c ++++ b/sound/soc/codecs/rt5645.c +@@ -3827,14 +3827,6 @@ static const struct dmi_system_id dmi_platform_data[] = { + }, + .driver_data = (void *)&ecs_ef20_platform_data, + }, +- { +- .ident = "EF20EA", +- .callback = cht_rt5645_ef20_quirk_cb, +- .matches = { +- DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"), +- }, +- .driver_data = (void *)&ecs_ef20_platform_data, +- }, + { } + }; + +diff --git a/sound/soc/intel/common/soc-acpi-intel-glk-match.c b/sound/soc/intel/common/soc-acpi-intel-glk-match.c +index 387e731008841..8911c90bbaf68 100644 +--- a/sound/soc/intel/common/soc-acpi-intel-glk-match.c ++++ b/sound/soc/intel/common/soc-acpi-intel-glk-match.c +@@ -19,6 +19,11 @@ static const struct snd_soc_acpi_codecs glk_codecs = { + .codecs = {"MX98357A"} + }; + ++static const struct snd_soc_acpi_codecs glk_rt5682_rt5682s_hp = { ++ .num_codecs = 2, ++ .codecs = {"10EC5682", "RTL5682"}, ++}; ++ + struct snd_soc_acpi_mach snd_soc_acpi_intel_glk_machines[] = { + { + .id = "INT343A", +@@ -35,20 +40,13 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_glk_machines[] = { + .sof_tplg_filename = "sof-glk-da7219.tplg", + }, + { +- .id = "10EC5682", ++ .comp_ids = &glk_rt5682_rt5682s_hp, + .drv_name = "glk_rt5682_mx98357a", + .fw_filename = "intel/dsp_fw_glk.bin", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &glk_codecs, + .sof_tplg_filename = "sof-glk-rt5682.tplg", + }, +- { +- .id = "RTL5682", +- .drv_name = "glk_rt5682_max98357a", +- .machine_quirk = snd_soc_acpi_codec_list, +- .quirk_data = &glk_codecs, +- .sof_tplg_filename = "sof-glk-rt5682.tplg", +- }, + { + .id = "10134242", + .drv_name = "glk_cs4242_mx98357a", +diff --git a/sound/soc/mediatek/common/mtk-dsp-sof-common.c b/sound/soc/mediatek/common/mtk-dsp-sof-common.c +index 8b1b623207bee..d4d1d3b9572a7 100644 +--- a/sound/soc/mediatek/common/mtk-dsp-sof-common.c ++++ b/sound/soc/mediatek/common/mtk-dsp-sof-common.c +@@ -24,7 +24,7 @@ int mtk_sof_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_soc_dai_link *sof_dai_link = NULL; + const struct sof_conn_stream *conn = &sof_priv->conn_streams[i]; + +- if (strcmp(rtd->dai_link->name, conn->normal_link)) ++ if (conn->normal_link && strcmp(rtd->dai_link->name, conn->normal_link)) + continue; + + for_each_card_rtds(card, runtime) { +diff --git a/sound/usb/mixer_scarlett_gen2.c b/sound/usb/mixer_scarlett_gen2.c +index 9d11bb08667e7..1bcb05c73e0ad 100644 +--- a/sound/usb/mixer_scarlett_gen2.c ++++ b/sound/usb/mixer_scarlett_gen2.c +@@ -1337,9 +1337,11 @@ static void scarlett2_config_save(struct usb_mixer_interface *mixer) + { + __le32 req = cpu_to_le32(SCARLETT2_USB_CONFIG_SAVE); + +- scarlett2_usb(mixer, SCARLETT2_USB_DATA_CMD, +- &req, sizeof(u32), +- NULL, 0); ++ int err = scarlett2_usb(mixer, SCARLETT2_USB_DATA_CMD, ++ &req, sizeof(u32), ++ NULL, 0); ++ if (err < 0) ++ usb_audio_err(mixer->chip, "config save failed: %d\n", err); + } + + /* Delayed work to save config */ +@@ -1388,7 +1390,10 @@ static int scarlett2_usb_set_config( + size = 1; + offset = config_item->offset; + +- scarlett2_usb_get(mixer, offset, &tmp, 1); ++ err = scarlett2_usb_get(mixer, offset, &tmp, 1); ++ if (err < 0) ++ return err; ++ + if (value) + tmp |= (1 << index); + else +@@ -1793,14 +1798,20 @@ static int scarlett2_sync_ctl_get(struct snd_kcontrol *kctl, + struct usb_mixer_elem_info *elem = kctl->private_data; + struct usb_mixer_interface *mixer = elem->head.mixer; + struct scarlett2_data *private = mixer->private_data; ++ int err = 0; + + mutex_lock(&private->data_mutex); +- if (private->sync_updated) +- scarlett2_update_sync(mixer); ++ ++ if (private->sync_updated) { ++ err = scarlett2_update_sync(mixer); ++ if (err < 0) ++ goto unlock; ++ } + ucontrol->value.enumerated.item[0] = private->sync; +- mutex_unlock(&private->data_mutex); + +- return 0; ++unlock: ++ mutex_unlock(&private->data_mutex); ++ return err; + } + + static const struct snd_kcontrol_new scarlett2_sync_ctl = { +@@ -1883,22 +1894,35 @@ static int scarlett2_master_volume_ctl_get(struct snd_kcontrol *kctl, + struct usb_mixer_elem_info *elem = kctl->private_data; + struct usb_mixer_interface *mixer = elem->head.mixer; + struct scarlett2_data *private = mixer->private_data; ++ int err = 0; + + mutex_lock(&private->data_mutex); +- if (private->vol_updated) +- scarlett2_update_volumes(mixer); +- mutex_unlock(&private->data_mutex); + ++ if (private->vol_updated) { ++ err = scarlett2_update_volumes(mixer); ++ if (err < 0) ++ goto unlock; ++ } + ucontrol->value.integer.value[0] = private->master_vol; +- return 0; ++ ++unlock: ++ mutex_unlock(&private->data_mutex); ++ return err; + } + + static int line_out_remap(struct scarlett2_data *private, int index) + { + const struct scarlett2_device_info *info = private->info; ++ const int (*port_count)[SCARLETT2_PORT_DIRNS] = info->port_count; ++ int line_out_count = ++ port_count[SCARLETT2_PORT_TYPE_ANALOGUE][SCARLETT2_PORT_OUT]; + + if (!info->line_out_remap_enable) + return index; ++ ++ if (index >= line_out_count) ++ return index; ++ + return info->line_out_remap[index]; + } + +@@ -1909,14 +1933,20 @@ static int scarlett2_volume_ctl_get(struct snd_kcontrol *kctl, + struct usb_mixer_interface *mixer = elem->head.mixer; + struct scarlett2_data *private = mixer->private_data; + int index = line_out_remap(private, elem->control); ++ int err = 0; + + mutex_lock(&private->data_mutex); +- if (private->vol_updated) +- scarlett2_update_volumes(mixer); +- mutex_unlock(&private->data_mutex); + ++ if (private->vol_updated) { ++ err = scarlett2_update_volumes(mixer); ++ if (err < 0) ++ goto unlock; ++ } + ucontrol->value.integer.value[0] = private->vol[index]; +- return 0; ++ ++unlock: ++ mutex_unlock(&private->data_mutex); ++ return err; + } + + static int scarlett2_volume_ctl_put(struct snd_kcontrol *kctl, +@@ -1983,14 +2013,20 @@ static int scarlett2_mute_ctl_get(struct snd_kcontrol *kctl, + struct usb_mixer_interface *mixer = elem->head.mixer; + struct scarlett2_data *private = mixer->private_data; + int index = line_out_remap(private, elem->control); ++ int err = 0; + + mutex_lock(&private->data_mutex); +- if (private->vol_updated) +- scarlett2_update_volumes(mixer); +- mutex_unlock(&private->data_mutex); + ++ if (private->vol_updated) { ++ err = scarlett2_update_volumes(mixer); ++ if (err < 0) ++ goto unlock; ++ } + ucontrol->value.integer.value[0] = private->mute_switch[index]; +- return 0; ++ ++unlock: ++ mutex_unlock(&private->data_mutex); ++ return err; + } + + static int scarlett2_mute_ctl_put(struct snd_kcontrol *kctl, +@@ -2236,14 +2272,20 @@ static int scarlett2_level_enum_ctl_get(struct snd_kcontrol *kctl, + const struct scarlett2_device_info *info = private->info; + + int index = elem->control + info->level_input_first; ++ int err = 0; + + mutex_lock(&private->data_mutex); +- if (private->input_other_updated) +- scarlett2_update_input_other(mixer); ++ ++ if (private->input_other_updated) { ++ err = scarlett2_update_input_other(mixer); ++ if (err < 0) ++ goto unlock; ++ } + ucontrol->value.enumerated.item[0] = private->level_switch[index]; +- mutex_unlock(&private->data_mutex); + +- return 0; ++unlock: ++ mutex_unlock(&private->data_mutex); ++ return err; + } + + static int scarlett2_level_enum_ctl_put(struct snd_kcontrol *kctl, +@@ -2294,15 +2336,21 @@ static int scarlett2_pad_ctl_get(struct snd_kcontrol *kctl, + struct usb_mixer_elem_info *elem = kctl->private_data; + struct usb_mixer_interface *mixer = elem->head.mixer; + struct scarlett2_data *private = mixer->private_data; ++ int err = 0; + + mutex_lock(&private->data_mutex); +- if (private->input_other_updated) +- scarlett2_update_input_other(mixer); ++ ++ if (private->input_other_updated) { ++ err = scarlett2_update_input_other(mixer); ++ if (err < 0) ++ goto unlock; ++ } + ucontrol->value.integer.value[0] = + private->pad_switch[elem->control]; +- mutex_unlock(&private->data_mutex); + +- return 0; ++unlock: ++ mutex_unlock(&private->data_mutex); ++ return err; + } + + static int scarlett2_pad_ctl_put(struct snd_kcontrol *kctl, +@@ -2352,14 +2400,20 @@ static int scarlett2_air_ctl_get(struct snd_kcontrol *kctl, + struct usb_mixer_elem_info *elem = kctl->private_data; + struct usb_mixer_interface *mixer = elem->head.mixer; + struct scarlett2_data *private = mixer->private_data; ++ int err = 0; + + mutex_lock(&private->data_mutex); +- if (private->input_other_updated) +- scarlett2_update_input_other(mixer); ++ ++ if (private->input_other_updated) { ++ err = scarlett2_update_input_other(mixer); ++ if (err < 0) ++ goto unlock; ++ } + ucontrol->value.integer.value[0] = private->air_switch[elem->control]; +- mutex_unlock(&private->data_mutex); + +- return 0; ++unlock: ++ mutex_unlock(&private->data_mutex); ++ return err; + } + + static int scarlett2_air_ctl_put(struct snd_kcontrol *kctl, +@@ -2409,15 +2463,21 @@ static int scarlett2_phantom_ctl_get(struct snd_kcontrol *kctl, + struct usb_mixer_elem_info *elem = kctl->private_data; + struct usb_mixer_interface *mixer = elem->head.mixer; + struct scarlett2_data *private = mixer->private_data; ++ int err = 0; + + mutex_lock(&private->data_mutex); +- if (private->input_other_updated) +- scarlett2_update_input_other(mixer); ++ ++ if (private->input_other_updated) { ++ err = scarlett2_update_input_other(mixer); ++ if (err < 0) ++ goto unlock; ++ } + ucontrol->value.integer.value[0] = + private->phantom_switch[elem->control]; +- mutex_unlock(&private->data_mutex); + +- return 0; ++unlock: ++ mutex_unlock(&private->data_mutex); ++ return err; + } + + static int scarlett2_phantom_ctl_put(struct snd_kcontrol *kctl, +@@ -2589,14 +2649,20 @@ static int scarlett2_direct_monitor_ctl_get( + struct usb_mixer_elem_info *elem = kctl->private_data; + struct usb_mixer_interface *mixer = elem->head.mixer; + struct scarlett2_data *private = elem->head.mixer->private_data; ++ int err = 0; + + mutex_lock(&private->data_mutex); +- if (private->monitor_other_updated) +- scarlett2_update_monitor_other(mixer); ++ ++ if (private->monitor_other_updated) { ++ err = scarlett2_update_monitor_other(mixer); ++ if (err < 0) ++ goto unlock; ++ } + ucontrol->value.enumerated.item[0] = private->direct_monitor_switch; +- mutex_unlock(&private->data_mutex); + +- return 0; ++unlock: ++ mutex_unlock(&private->data_mutex); ++ return err; + } + + static int scarlett2_direct_monitor_ctl_put( +@@ -2696,14 +2762,20 @@ static int scarlett2_speaker_switch_enum_ctl_get( + struct usb_mixer_elem_info *elem = kctl->private_data; + struct usb_mixer_interface *mixer = elem->head.mixer; + struct scarlett2_data *private = mixer->private_data; ++ int err = 0; + + mutex_lock(&private->data_mutex); +- if (private->monitor_other_updated) +- scarlett2_update_monitor_other(mixer); ++ ++ if (private->monitor_other_updated) { ++ err = scarlett2_update_monitor_other(mixer); ++ if (err < 0) ++ goto unlock; ++ } + ucontrol->value.enumerated.item[0] = private->speaker_switching_switch; +- mutex_unlock(&private->data_mutex); + +- return 0; ++unlock: ++ mutex_unlock(&private->data_mutex); ++ return err; + } + + /* when speaker switching gets enabled, switch the main/alt speakers +@@ -2851,14 +2923,20 @@ static int scarlett2_talkback_enum_ctl_get( + struct usb_mixer_elem_info *elem = kctl->private_data; + struct usb_mixer_interface *mixer = elem->head.mixer; + struct scarlett2_data *private = mixer->private_data; ++ int err = 0; + + mutex_lock(&private->data_mutex); +- if (private->monitor_other_updated) +- scarlett2_update_monitor_other(mixer); ++ ++ if (private->monitor_other_updated) { ++ err = scarlett2_update_monitor_other(mixer); ++ if (err < 0) ++ goto unlock; ++ } + ucontrol->value.enumerated.item[0] = private->talkback_switch; +- mutex_unlock(&private->data_mutex); + +- return 0; ++unlock: ++ mutex_unlock(&private->data_mutex); ++ return err; + } + + static int scarlett2_talkback_enum_ctl_put( +@@ -3006,14 +3084,20 @@ static int scarlett2_dim_mute_ctl_get(struct snd_kcontrol *kctl, + struct usb_mixer_elem_info *elem = kctl->private_data; + struct usb_mixer_interface *mixer = elem->head.mixer; + struct scarlett2_data *private = mixer->private_data; ++ int err = 0; + + mutex_lock(&private->data_mutex); +- if (private->vol_updated) +- scarlett2_update_volumes(mixer); +- mutex_unlock(&private->data_mutex); + ++ if (private->vol_updated) { ++ err = scarlett2_update_volumes(mixer); ++ if (err < 0) ++ goto unlock; ++ } + ucontrol->value.integer.value[0] = private->dim_mute[elem->control]; +- return 0; ++ ++unlock: ++ mutex_unlock(&private->data_mutex); ++ return err; + } + + static int scarlett2_dim_mute_ctl_put(struct snd_kcontrol *kctl, +@@ -3277,7 +3361,8 @@ static int scarlett2_mixer_ctl_put(struct snd_kcontrol *kctl, + mutex_lock(&private->data_mutex); + + oval = private->mix[index]; +- val = ucontrol->value.integer.value[0]; ++ val = clamp(ucontrol->value.integer.value[0], ++ 0L, (long)SCARLETT2_MIXER_MAX_VALUE); + num_mixer_in = port_count[SCARLETT2_PORT_TYPE_MIX][SCARLETT2_PORT_OUT]; + mix_num = index / num_mixer_in; + +@@ -3383,22 +3468,21 @@ static int scarlett2_mux_src_enum_ctl_get(struct snd_kcontrol *kctl, + struct usb_mixer_elem_info *elem = kctl->private_data; + struct usb_mixer_interface *mixer = elem->head.mixer; + struct scarlett2_data *private = mixer->private_data; +- const struct scarlett2_device_info *info = private->info; +- const int (*port_count)[SCARLETT2_PORT_DIRNS] = info->port_count; +- int line_out_count = +- port_count[SCARLETT2_PORT_TYPE_ANALOGUE][SCARLETT2_PORT_OUT]; +- int index = elem->control; +- +- if (index < line_out_count) +- index = line_out_remap(private, index); ++ int index = line_out_remap(private, elem->control); ++ int err = 0; + + mutex_lock(&private->data_mutex); +- if (private->mux_updated) +- scarlett2_usb_get_mux(mixer); ++ ++ if (private->mux_updated) { ++ err = scarlett2_usb_get_mux(mixer); ++ if (err < 0) ++ goto unlock; ++ } + ucontrol->value.enumerated.item[0] = private->mux[index]; +- mutex_unlock(&private->data_mutex); + +- return 0; ++unlock: ++ mutex_unlock(&private->data_mutex); ++ return err; + } + + static int scarlett2_mux_src_enum_ctl_put(struct snd_kcontrol *kctl, +@@ -3407,16 +3491,9 @@ static int scarlett2_mux_src_enum_ctl_put(struct snd_kcontrol *kctl, + struct usb_mixer_elem_info *elem = kctl->private_data; + struct usb_mixer_interface *mixer = elem->head.mixer; + struct scarlett2_data *private = mixer->private_data; +- const struct scarlett2_device_info *info = private->info; +- const int (*port_count)[SCARLETT2_PORT_DIRNS] = info->port_count; +- int line_out_count = +- port_count[SCARLETT2_PORT_TYPE_ANALOGUE][SCARLETT2_PORT_OUT]; +- int index = elem->control; ++ int index = line_out_remap(private, elem->control); + int oval, val, err = 0; + +- if (index < line_out_count) +- index = line_out_remap(private, index); +- + mutex_lock(&private->data_mutex); + + oval = private->mux[index]; +diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h +index 92dbe89dafbf5..201dc77ebbd77 100644 +--- a/tools/include/uapi/linux/bpf.h ++++ b/tools/include/uapi/linux/bpf.h +@@ -4353,6 +4353,8 @@ union bpf_attr { + * long bpf_get_task_stack(struct task_struct *task, void *buf, u32 size, u64 flags) + * Description + * Return a user or a kernel stack in bpf program provided buffer. ++ * Note: the user stack will only be populated if the *task* is ++ * the current task; all other tasks will return -EOPNOTSUPP. + * To achieve this, the helper needs *task*, which is a valid + * pointer to **struct task_struct**. To store the stacktrace, the + * bpf program provides *buf* with a nonnegative *size*. +@@ -4364,6 +4366,7 @@ union bpf_attr { + * + * **BPF_F_USER_STACK** + * Collect a user space stack instead of a kernel stack. ++ * The *task* must be the current task. + * **BPF_F_USER_BUILD_ID** + * Collect buildid+offset instead of ips for user stack, + * only valid if **BPF_F_USER_STACK** is also specified. +diff --git a/tools/lib/api/io.h b/tools/lib/api/io.h +index 777c20f6b6047..458acd294237d 100644 +--- a/tools/lib/api/io.h ++++ b/tools/lib/api/io.h +@@ -9,6 +9,7 @@ + + #include <stdlib.h> + #include <unistd.h> ++#include <linux/types.h> + + struct io { + /* File descriptor being read/ */ +diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c +index cc7c1f90cf629..91c7bfa82a50a 100644 +--- a/tools/perf/util/bpf-event.c ++++ b/tools/perf/util/bpf-event.c +@@ -606,9 +606,9 @@ int evlist__add_bpf_sb_event(struct evlist *evlist, struct perf_env *env) + return evlist__add_sb_event(evlist, &attr, bpf_event__sb_cb, env); + } + +-void bpf_event__print_bpf_prog_info(struct bpf_prog_info *info, +- struct perf_env *env, +- FILE *fp) ++void __bpf_event__print_bpf_prog_info(struct bpf_prog_info *info, ++ struct perf_env *env, ++ FILE *fp) + { + __u32 *prog_lens = (__u32 *)(uintptr_t)(info->jited_func_lens); + __u64 *prog_addrs = (__u64 *)(uintptr_t)(info->jited_ksyms); +@@ -624,7 +624,7 @@ void bpf_event__print_bpf_prog_info(struct bpf_prog_info *info, + if (info->btf_id) { + struct btf_node *node; + +- node = perf_env__find_btf(env, info->btf_id); ++ node = __perf_env__find_btf(env, info->btf_id); + if (node) + btf = btf__new((__u8 *)(node->data), + node->data_size); +diff --git a/tools/perf/util/bpf-event.h b/tools/perf/util/bpf-event.h +index 1bcbd4fb6c669..e2f0420905f59 100644 +--- a/tools/perf/util/bpf-event.h ++++ b/tools/perf/util/bpf-event.h +@@ -33,9 +33,9 @@ struct btf_node { + int machine__process_bpf(struct machine *machine, union perf_event *event, + struct perf_sample *sample); + int evlist__add_bpf_sb_event(struct evlist *evlist, struct perf_env *env); +-void bpf_event__print_bpf_prog_info(struct bpf_prog_info *info, +- struct perf_env *env, +- FILE *fp); ++void __bpf_event__print_bpf_prog_info(struct bpf_prog_info *info, ++ struct perf_env *env, ++ FILE *fp); + #else + static inline int machine__process_bpf(struct machine *machine __maybe_unused, + union perf_event *event __maybe_unused, +@@ -50,9 +50,9 @@ static inline int evlist__add_bpf_sb_event(struct evlist *evlist __maybe_unused, + return 0; + } + +-static inline void bpf_event__print_bpf_prog_info(struct bpf_prog_info *info __maybe_unused, +- struct perf_env *env __maybe_unused, +- FILE *fp __maybe_unused) ++static inline void __bpf_event__print_bpf_prog_info(struct bpf_prog_info *info __maybe_unused, ++ struct perf_env *env __maybe_unused, ++ FILE *fp __maybe_unused) + { + + } +diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c +index 5b8cf6a421a49..5d878bae7d9a5 100644 +--- a/tools/perf/util/env.c ++++ b/tools/perf/util/env.c +@@ -21,13 +21,19 @@ struct perf_env perf_env; + + void perf_env__insert_bpf_prog_info(struct perf_env *env, + struct bpf_prog_info_node *info_node) ++{ ++ down_write(&env->bpf_progs.lock); ++ __perf_env__insert_bpf_prog_info(env, info_node); ++ up_write(&env->bpf_progs.lock); ++} ++ ++void __perf_env__insert_bpf_prog_info(struct perf_env *env, struct bpf_prog_info_node *info_node) + { + __u32 prog_id = info_node->info_linear->info.id; + struct bpf_prog_info_node *node; + struct rb_node *parent = NULL; + struct rb_node **p; + +- down_write(&env->bpf_progs.lock); + p = &env->bpf_progs.infos.rb_node; + + while (*p != NULL) { +@@ -39,15 +45,13 @@ void perf_env__insert_bpf_prog_info(struct perf_env *env, + p = &(*p)->rb_right; + } else { + pr_debug("duplicated bpf prog info %u\n", prog_id); +- goto out; ++ return; + } + } + + rb_link_node(&info_node->rb_node, parent, p); + rb_insert_color(&info_node->rb_node, &env->bpf_progs.infos); + env->bpf_progs.infos_cnt++; +-out: +- up_write(&env->bpf_progs.lock); + } + + struct bpf_prog_info_node *perf_env__find_bpf_prog_info(struct perf_env *env, +@@ -76,14 +80,22 @@ out: + } + + bool perf_env__insert_btf(struct perf_env *env, struct btf_node *btf_node) ++{ ++ bool ret; ++ ++ down_write(&env->bpf_progs.lock); ++ ret = __perf_env__insert_btf(env, btf_node); ++ up_write(&env->bpf_progs.lock); ++ return ret; ++} ++ ++bool __perf_env__insert_btf(struct perf_env *env, struct btf_node *btf_node) + { + struct rb_node *parent = NULL; + __u32 btf_id = btf_node->id; + struct btf_node *node; + struct rb_node **p; +- bool ret = true; + +- down_write(&env->bpf_progs.lock); + p = &env->bpf_progs.btfs.rb_node; + + while (*p != NULL) { +@@ -95,25 +107,31 @@ bool perf_env__insert_btf(struct perf_env *env, struct btf_node *btf_node) + p = &(*p)->rb_right; + } else { + pr_debug("duplicated btf %u\n", btf_id); +- ret = false; +- goto out; ++ return false; + } + } + + rb_link_node(&btf_node->rb_node, parent, p); + rb_insert_color(&btf_node->rb_node, &env->bpf_progs.btfs); + env->bpf_progs.btfs_cnt++; +-out: +- up_write(&env->bpf_progs.lock); +- return ret; ++ return true; + } + + struct btf_node *perf_env__find_btf(struct perf_env *env, __u32 btf_id) ++{ ++ struct btf_node *res; ++ ++ down_read(&env->bpf_progs.lock); ++ res = __perf_env__find_btf(env, btf_id); ++ up_read(&env->bpf_progs.lock); ++ return res; ++} ++ ++struct btf_node *__perf_env__find_btf(struct perf_env *env, __u32 btf_id) + { + struct btf_node *node = NULL; + struct rb_node *n; + +- down_read(&env->bpf_progs.lock); + n = env->bpf_progs.btfs.rb_node; + + while (n) { +@@ -123,13 +141,9 @@ struct btf_node *perf_env__find_btf(struct perf_env *env, __u32 btf_id) + else if (btf_id > node->id) + n = n->rb_right; + else +- goto out; ++ return node; + } +- node = NULL; +- +-out: +- up_read(&env->bpf_progs.lock); +- return node; ++ return NULL; + } + + /* purge data in bpf_progs.infos tree */ +diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h +index 4566c51f2fd95..359eff51cb85b 100644 +--- a/tools/perf/util/env.h ++++ b/tools/perf/util/env.h +@@ -164,12 +164,16 @@ const char *perf_env__raw_arch(struct perf_env *env); + int perf_env__nr_cpus_avail(struct perf_env *env); + + void perf_env__init(struct perf_env *env); ++void __perf_env__insert_bpf_prog_info(struct perf_env *env, ++ struct bpf_prog_info_node *info_node); + void perf_env__insert_bpf_prog_info(struct perf_env *env, + struct bpf_prog_info_node *info_node); + struct bpf_prog_info_node *perf_env__find_bpf_prog_info(struct perf_env *env, + __u32 prog_id); + bool perf_env__insert_btf(struct perf_env *env, struct btf_node *btf_node); ++bool __perf_env__insert_btf(struct perf_env *env, struct btf_node *btf_node); + struct btf_node *perf_env__find_btf(struct perf_env *env, __u32 btf_id); ++struct btf_node *__perf_env__find_btf(struct perf_env *env, __u32 btf_id); + + int perf_env__numa_node(struct perf_env *env, struct perf_cpu cpu); + char *perf_env__find_pmu_cap(struct perf_env *env, const char *pmu_name, +diff --git a/tools/perf/util/genelf.c b/tools/perf/util/genelf.c +index fefc72066c4e8..ac17a3cb59dc0 100644 +--- a/tools/perf/util/genelf.c ++++ b/tools/perf/util/genelf.c +@@ -293,9 +293,9 @@ jit_write_elf(int fd, uint64_t load_addr, const char *sym, + */ + phdr = elf_newphdr(e, 1); + phdr[0].p_type = PT_LOAD; +- phdr[0].p_offset = 0; +- phdr[0].p_vaddr = 0; +- phdr[0].p_paddr = 0; ++ phdr[0].p_offset = GEN_ELF_TEXT_OFFSET; ++ phdr[0].p_vaddr = GEN_ELF_TEXT_OFFSET; ++ phdr[0].p_paddr = GEN_ELF_TEXT_OFFSET; + phdr[0].p_filesz = csize; + phdr[0].p_memsz = csize; + phdr[0].p_flags = PF_X | PF_R; +diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c +index 9e2dce70b1300..b2b0293567f07 100644 +--- a/tools/perf/util/header.c ++++ b/tools/perf/util/header.c +@@ -1809,8 +1809,8 @@ static void print_bpf_prog_info(struct feat_fd *ff, FILE *fp) + node = rb_entry(next, struct bpf_prog_info_node, rb_node); + next = rb_next(&node->rb_node); + +- bpf_event__print_bpf_prog_info(&node->info_linear->info, +- env, fp); ++ __bpf_event__print_bpf_prog_info(&node->info_linear->info, ++ env, fp); + } + + up_read(&env->bpf_progs.lock); +@@ -3136,7 +3136,7 @@ static int process_bpf_prog_info(struct feat_fd *ff, void *data __maybe_unused) + /* after reading from file, translate offset to address */ + bpil_offs_to_addr(info_linear); + info_node->info_linear = info_linear; +- perf_env__insert_bpf_prog_info(env, info_node); ++ __perf_env__insert_bpf_prog_info(env, info_node); + } + + up_write(&env->bpf_progs.lock); +@@ -3183,7 +3183,7 @@ static int process_bpf_btf(struct feat_fd *ff, void *data __maybe_unused) + if (__do_read(ff, node->data, data_size)) + goto out; + +- perf_env__insert_btf(env, node); ++ __perf_env__insert_btf(env, node); + node = NULL; + } + +@@ -4314,9 +4314,10 @@ size_t perf_event__fprintf_event_update(union perf_event *event, FILE *fp) + ret += fprintf(fp, "... "); + + map = cpu_map__new_data(&ev->cpus.cpus); +- if (map) ++ if (map) { + ret += cpu_map__fprintf(map, fp); +- else ++ perf_cpu_map__put(map); ++ } else + ret += fprintf(fp, "failed to get cpus\n"); + break; + default: +diff --git a/tools/perf/util/hisi-ptt.c b/tools/perf/util/hisi-ptt.c +index 45b614bb73bfa..764d660d30e2f 100644 +--- a/tools/perf/util/hisi-ptt.c ++++ b/tools/perf/util/hisi-ptt.c +@@ -121,6 +121,7 @@ static int hisi_ptt_process_auxtrace_event(struct perf_session *session, + if (dump_trace) + hisi_ptt_dump_event(ptt, data, size); + ++ free(data); + return 0; + } + +diff --git a/tools/testing/selftests/alsa/mixer-test.c b/tools/testing/selftests/alsa/mixer-test.c +index 37da902545a41..9ad39db32d144 100644 +--- a/tools/testing/selftests/alsa/mixer-test.c ++++ b/tools/testing/selftests/alsa/mixer-test.c +@@ -205,7 +205,7 @@ static void find_controls(void) + err = snd_ctl_poll_descriptors(card_data->handle, + &card_data->pollfd, 1); + if (err != 1) { +- ksft_exit_fail_msg("snd_ctl_poll_descriptors() failed for %d\n", ++ ksft_exit_fail_msg("snd_ctl_poll_descriptors() failed for card %d: %d\n", + card, err); + } + +@@ -358,7 +358,7 @@ static bool ctl_value_index_valid(struct ctl_data *ctl, + } + + if (int64_val > snd_ctl_elem_info_get_max64(ctl->info)) { +- ksft_print_msg("%s.%d value %lld more than maximum %lld\n", ++ ksft_print_msg("%s.%d value %lld more than maximum %ld\n", + ctl->name, index, int64_val, + snd_ctl_elem_info_get_max(ctl->info)); + return false; +diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_iter.c b/tools/testing/selftests/bpf/prog_tests/bpf_iter.c +index ecde236047fe1..0c67a4e28effa 100644 +--- a/tools/testing/selftests/bpf/prog_tests/bpf_iter.c ++++ b/tools/testing/selftests/bpf/prog_tests/bpf_iter.c +@@ -338,6 +338,8 @@ static void test_task_stack(void) + do_dummy_read(skel->progs.dump_task_stack); + do_dummy_read(skel->progs.get_task_user_stacks); + ++ ASSERT_EQ(skel->bss->num_user_stacks, 1, "num_user_stacks"); ++ + bpf_iter_task_stack__destroy(skel); + } + +diff --git a/tools/testing/selftests/bpf/prog_tests/time_tai.c b/tools/testing/selftests/bpf/prog_tests/time_tai.c +index a311198236661..f45af1b0ef2c4 100644 +--- a/tools/testing/selftests/bpf/prog_tests/time_tai.c ++++ b/tools/testing/selftests/bpf/prog_tests/time_tai.c +@@ -56,7 +56,7 @@ void test_time_tai(void) + ASSERT_NEQ(ts2, 0, "tai_ts2"); + + /* TAI is moving forward only */ +- ASSERT_GT(ts2, ts1, "tai_forward"); ++ ASSERT_GE(ts2, ts1, "tai_forward"); + + /* Check for future */ + ret = clock_gettime(CLOCK_TAI, &now_tai); +diff --git a/tools/testing/selftests/bpf/progs/bpf_iter_task_stack.c b/tools/testing/selftests/bpf/progs/bpf_iter_task_stack.c +index f2b8167b72a84..442f4ca39fd76 100644 +--- a/tools/testing/selftests/bpf/progs/bpf_iter_task_stack.c ++++ b/tools/testing/selftests/bpf/progs/bpf_iter_task_stack.c +@@ -35,6 +35,8 @@ int dump_task_stack(struct bpf_iter__task *ctx) + return 0; + } + ++int num_user_stacks = 0; ++ + SEC("iter/task") + int get_task_user_stacks(struct bpf_iter__task *ctx) + { +@@ -51,6 +53,9 @@ int get_task_user_stacks(struct bpf_iter__task *ctx) + if (res <= 0) + return 0; + ++ /* Only one task, the current one, should succeed */ ++ ++num_user_stacks; ++ + buf_sz += res; + + /* If the verifier doesn't refine bpf_get_task_stack res, and instead +diff --git a/tools/testing/selftests/bpf/progs/xdp_synproxy_kern.c b/tools/testing/selftests/bpf/progs/xdp_synproxy_kern.c +index 736686e903f6a..26bfbc73d1298 100644 +--- a/tools/testing/selftests/bpf/progs/xdp_synproxy_kern.c ++++ b/tools/testing/selftests/bpf/progs/xdp_synproxy_kern.c +@@ -447,13 +447,13 @@ static __always_inline int tcp_lookup(void *ctx, struct header_pointers *hdr, bo + unsigned long status = ct->status; + + bpf_ct_release(ct); +- if (status & IPS_CONFIRMED_BIT) ++ if (status & IPS_CONFIRMED) + return XDP_PASS; + } else if (ct_lookup_opts.error != -ENOENT) { + return XDP_ABORTED; + } + +- /* error == -ENOENT || !(status & IPS_CONFIRMED_BIT) */ ++ /* error == -ENOENT || !(status & IPS_CONFIRMED) */ + return XDP_TX; + } + +diff --git a/tools/testing/selftests/drivers/net/mlxsw/qos_pfc.sh b/tools/testing/selftests/drivers/net/mlxsw/qos_pfc.sh +index f9858e221996c..6a3002fbcf43a 100755 +--- a/tools/testing/selftests/drivers/net/mlxsw/qos_pfc.sh ++++ b/tools/testing/selftests/drivers/net/mlxsw/qos_pfc.sh +@@ -121,6 +121,9 @@ h2_destroy() + + switch_create() + { ++ local lanes_swp4 ++ local pg1_size ++ + # pools + # ----- + +@@ -230,7 +233,20 @@ switch_create() + dcb pfc set dev $swp4 prio-pfc all:off 1:on + # PG0 will get autoconfigured to Xoff, give PG1 arbitrarily 100K, which + # is (-2*MTU) about 80K of delay provision. +- dcb buffer set dev $swp4 buffer-size all:0 1:$_100KB ++ pg1_size=$_100KB ++ ++ setup_wait_dev_with_timeout $swp4 ++ ++ lanes_swp4=$(ethtool $swp4 | grep 'Lanes:') ++ lanes_swp4=${lanes_swp4#*"Lanes: "} ++ ++ # 8-lane ports use two buffers among which the configured buffer ++ # is split, so double the size to get twice (20K + 80K). ++ if [[ $lanes_swp4 -eq 8 ]]; then ++ pg1_size=$((pg1_size * 2)) ++ fi ++ ++ dcb buffer set dev $swp4 buffer-size all:0 1:$pg1_size + + # bridges + # ------- +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 fb850e0ec8375..7bf56ea161e35 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 +@@ -10,7 +10,8 @@ lib_dir=$(dirname $0)/../../../../net/forwarding + 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" ++ bloom_simple_test bloom_complex_test bloom_delta_test \ ++ max_erp_entries_test" + NUM_NETIFS=2 + source $lib_dir/lib.sh + source $lib_dir/tc_common.sh +@@ -983,6 +984,55 @@ bloom_delta_test() + log_test "bloom delta test ($tcflags)" + } + ++max_erp_entries_test() ++{ ++ # The number of eRP entries is limited. Once the maximum number of eRPs ++ # has been reached, filters cannot be added. This test verifies that ++ # when this limit is reached, inserstion fails without crashing. ++ ++ RET=0 ++ ++ local num_masks=32 ++ local num_regions=15 ++ local chain_failed ++ local mask_failed ++ local ret ++ ++ if [[ "$tcflags" != "skip_sw" ]]; then ++ return 0; ++ fi ++ ++ for ((i=1; i < $num_regions; i++)); do ++ for ((j=$num_masks; j >= 0; j--)); do ++ tc filter add dev $h2 ingress chain $i protocol ip \ ++ pref $i handle $j flower $tcflags \ ++ dst_ip 192.1.0.0/$j &> /dev/null ++ ret=$? ++ ++ if [ $ret -ne 0 ]; then ++ chain_failed=$i ++ mask_failed=$j ++ break 2 ++ fi ++ done ++ done ++ ++ # We expect to exceed the maximum number of eRP entries, so that ++ # insertion eventually fails. Otherwise, the test should be adjusted to ++ # add more filters. ++ check_fail $ret "expected to exceed number of eRP entries" ++ ++ for ((; i >= 1; i--)); do ++ for ((j=0; j <= $num_masks; j++)); do ++ tc filter del dev $h2 ingress chain $i protocol ip \ ++ pref $i handle $j flower &> /dev/null ++ done ++ done ++ ++ log_test "max eRP entries test ($tcflags). " \ ++ "max chain $chain_failed, mask $mask_failed" ++} ++ + setup_prepare() + { + h1=${NETIFS[p1]} +diff --git a/tools/testing/selftests/net/arp_ndisc_untracked_subnets.sh b/tools/testing/selftests/net/arp_ndisc_untracked_subnets.sh +index c899b446acb62..327427ec10f56 100755 +--- a/tools/testing/selftests/net/arp_ndisc_untracked_subnets.sh ++++ b/tools/testing/selftests/net/arp_ndisc_untracked_subnets.sh +@@ -150,7 +150,7 @@ arp_test_gratuitous() { + fi + # Supply arp_accept option to set up which sets it in sysctl + setup ${arp_accept} +- ip netns exec ${HOST_NS} arping -A -U ${HOST_ADDR} -c1 2>&1 >/dev/null ++ ip netns exec ${HOST_NS} arping -A -I ${HOST_INTF} -U ${HOST_ADDR} -c1 2>&1 >/dev/null + + if verify_arp $1 $2; then + printf " TEST: %-60s [ OK ]\n" "${test_msg[*]}" +diff --git a/tools/testing/selftests/net/fib_nexthop_multiprefix.sh b/tools/testing/selftests/net/fib_nexthop_multiprefix.sh +index 51df5e305855a..b52d59547fc59 100755 +--- a/tools/testing/selftests/net/fib_nexthop_multiprefix.sh ++++ b/tools/testing/selftests/net/fib_nexthop_multiprefix.sh +@@ -209,12 +209,12 @@ validate_v6_exception() + echo "Route get" + ip -netns h0 -6 ro get ${dst} + echo "Searching for:" +- echo " ${dst} from :: via ${r1} dev eth0 src ${h0} .* mtu ${mtu}" ++ echo " ${dst}.* via ${r1} dev eth0 src ${h0} .* mtu ${mtu}" + echo + fi + + ip -netns h0 -6 ro get ${dst} | \ +- grep -q "${dst} from :: via ${r1} dev eth0 src ${h0} .* mtu ${mtu}" ++ grep -q "${dst}.* via ${r1} dev eth0 src ${h0} .* mtu ${mtu}" + rc=$? + + log_test $rc 0 "IPv6: host 0 to host ${i}, mtu ${mtu}" +diff --git a/tools/testing/selftests/powerpc/math/fpu_preempt.c b/tools/testing/selftests/powerpc/math/fpu_preempt.c +index 5235bdc8c0b11..3e5b5663d2449 100644 +--- a/tools/testing/selftests/powerpc/math/fpu_preempt.c ++++ b/tools/testing/selftests/powerpc/math/fpu_preempt.c +@@ -37,19 +37,20 @@ __thread double darray[] = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, + int threads_starting; + int running; + +-extern void preempt_fpu(double *darray, int *threads_starting, int *running); ++extern int preempt_fpu(double *darray, int *threads_starting, int *running); + + void *preempt_fpu_c(void *p) + { ++ long rc; + int i; ++ + srand(pthread_self()); + for (i = 0; i < 21; i++) + darray[i] = rand(); + +- /* Test failed if it ever returns */ +- preempt_fpu(darray, &threads_starting, &running); ++ rc = preempt_fpu(darray, &threads_starting, &running); + +- return p; ++ return (void *)rc; + } + + int test_preempt_fpu(void) +diff --git a/tools/testing/selftests/powerpc/math/vmx_preempt.c b/tools/testing/selftests/powerpc/math/vmx_preempt.c +index 6761d6ce30eca..6f7cf400c6875 100644 +--- a/tools/testing/selftests/powerpc/math/vmx_preempt.c ++++ b/tools/testing/selftests/powerpc/math/vmx_preempt.c +@@ -37,19 +37,21 @@ __thread vector int varray[] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10,11,12}, + int threads_starting; + int running; + +-extern void preempt_vmx(vector int *varray, int *threads_starting, int *running); ++extern int preempt_vmx(vector int *varray, int *threads_starting, int *running); + + void *preempt_vmx_c(void *p) + { + int i, j; ++ long rc; ++ + srand(pthread_self()); + for (i = 0; i < 12; i++) + for (j = 0; j < 4; j++) + varray[i][j] = rand(); + +- /* Test fails if it ever returns */ +- preempt_vmx(varray, &threads_starting, &running); +- return p; ++ rc = preempt_vmx(varray, &threads_starting, &running); ++ ++ return (void *)rc; + } + + int test_preempt_vmx(void) +diff --git a/tools/testing/selftests/sgx/Makefile b/tools/testing/selftests/sgx/Makefile +index 75af864e07b65..04ee17d3d3947 100644 +--- a/tools/testing/selftests/sgx/Makefile ++++ b/tools/testing/selftests/sgx/Makefile +@@ -16,9 +16,9 @@ HOST_CFLAGS := -Wall -Werror -g $(INCLUDES) -fPIC -z noexecstack + ENCL_CFLAGS := -Wall -Werror -static -nostdlib -nostartfiles -fPIC \ + -fno-stack-protector -mrdrnd $(INCLUDES) + ++ifeq ($(CAN_BUILD_X86_64), 1) + TEST_CUSTOM_PROGS := $(OUTPUT)/test_sgx + +-ifeq ($(CAN_BUILD_X86_64), 1) + all: $(TEST_CUSTOM_PROGS) $(OUTPUT)/test_encl.elf + endif + +diff --git a/tools/testing/selftests/sgx/load.c b/tools/testing/selftests/sgx/load.c +index 94bdeac1cf041..c9f658e44de6c 100644 +--- a/tools/testing/selftests/sgx/load.c ++++ b/tools/testing/selftests/sgx/load.c +@@ -136,11 +136,11 @@ static bool encl_ioc_add_pages(struct encl *encl, struct encl_segment *seg) + */ + uint64_t encl_get_entry(struct encl *encl, const char *symbol) + { ++ Elf64_Sym *symtab = NULL; ++ char *sym_names = NULL; + Elf64_Shdr *sections; +- Elf64_Sym *symtab; + Elf64_Ehdr *ehdr; +- char *sym_names; +- int num_sym; ++ int num_sym = 0; + int i; + + ehdr = encl->bin; +@@ -161,6 +161,9 @@ uint64_t encl_get_entry(struct encl *encl, const char *symbol) + } + } + ++ if (!symtab || !sym_names) ++ return 0; ++ + for (i = 0; i < num_sym; i++) { + Elf64_Sym *sym = &symtab[i]; + +diff --git a/tools/testing/selftests/sgx/sigstruct.c b/tools/testing/selftests/sgx/sigstruct.c +index a07896a463643..d73b29becf5b0 100644 +--- a/tools/testing/selftests/sgx/sigstruct.c ++++ b/tools/testing/selftests/sgx/sigstruct.c +@@ -318,9 +318,9 @@ bool encl_measure(struct encl *encl) + struct sgx_sigstruct *sigstruct = &encl->sigstruct; + struct sgx_sigstruct_payload payload; + uint8_t digest[SHA256_DIGEST_LENGTH]; ++ EVP_MD_CTX *ctx = NULL; + unsigned int siglen; + RSA *key = NULL; +- EVP_MD_CTX *ctx; + int i; + + memset(sigstruct, 0, sizeof(*sigstruct)); +@@ -384,7 +384,8 @@ bool encl_measure(struct encl *encl) + return true; + + err: +- EVP_MD_CTX_destroy(ctx); ++ if (ctx) ++ EVP_MD_CTX_destroy(ctx); + RSA_free(key); + return false; + } +diff --git a/tools/testing/selftests/sgx/test_encl.c b/tools/testing/selftests/sgx/test_encl.c +index c0d6397295e31..ae791df3e5a57 100644 +--- a/tools/testing/selftests/sgx/test_encl.c ++++ b/tools/testing/selftests/sgx/test_encl.c +@@ -24,10 +24,11 @@ static void do_encl_emodpe(void *_op) + secinfo.flags = op->flags; + + asm volatile(".byte 0x0f, 0x01, 0xd7" +- : ++ : /* no outputs */ + : "a" (EMODPE), + "b" (&secinfo), +- "c" (op->epc_addr)); ++ "c" (op->epc_addr) ++ : "memory" /* read from secinfo pointer */); + } + + static void do_encl_eaccept(void *_op) +@@ -42,7 +43,8 @@ static void do_encl_eaccept(void *_op) + : "=a" (rax) + : "a" (EACCEPT), + "b" (&secinfo), +- "c" (op->epc_addr)); ++ "c" (op->epc_addr) ++ : "memory" /* read from secinfo pointer */); + + op->ret = rax; + } |