diff options
author | Mike Pagano <mpagano@gentoo.org> | 2024-02-05 15:59:47 -0500 |
---|---|---|
committer | Mike Pagano <mpagano@gentoo.org> | 2024-02-05 15:59:47 -0500 |
commit | f6b094e72946ad3e6ee62d9980742069bcc28041 (patch) | |
tree | ef8789b6aea9666190d2af84f016a5a946f99b06 | |
parent | Add BMQ Fix.sched/topology: Introduce sched_numa_hop_mask (diff) | |
download | linux-patches-f6b094e72946ad3e6ee62d9980742069bcc28041.tar.gz linux-patches-f6b094e72946ad3e6ee62d9980742069bcc28041.tar.bz2 linux-patches-f6b094e72946ad3e6ee62d9980742069bcc28041.zip |
Linux patch 6.7.46.7-7
Signed-off-by: Mike Pagano <mpagano@gentoo.org>
-rw-r--r-- | 0000_README | 4 | ||||
-rw-r--r-- | 1003_linux-6.7.4.patch | 21813 |
2 files changed, 21817 insertions, 0 deletions
diff --git a/0000_README b/0000_README index 8b508855..9c8bcf02 100644 --- a/0000_README +++ b/0000_README @@ -55,6 +55,10 @@ Patch: 1002_linux-6.7.3.patch From: https://www.kernel.org Desc: Linux 6.7.3 +Patch: 1003_linux-6.7.4.patch +From: https://www.kernel.org +Desc: Linux 6.7.4 + Patch: 1510_fs-enable-link-security-restrictions-by-default.patch From: http://sources.debian.net/src/linux/3.16.7-ckt4-3/debian/patches/debian/fs-enable-link-security-restrictions-by-default.patch/ Desc: Enable link security restrictions by default. diff --git a/1003_linux-6.7.4.patch b/1003_linux-6.7.4.patch new file mode 100644 index 00000000..18a490a6 --- /dev/null +++ b/1003_linux-6.7.4.patch @@ -0,0 +1,21813 @@ +diff --git a/Documentation/ABI/testing/sysfs-class-net-queues b/Documentation/ABI/testing/sysfs-class-net-queues +index 906ff3ca928ac..5bff64d256c20 100644 +--- a/Documentation/ABI/testing/sysfs-class-net-queues ++++ b/Documentation/ABI/testing/sysfs-class-net-queues +@@ -1,4 +1,4 @@ +-What: /sys/class/<iface>/queues/rx-<queue>/rps_cpus ++What: /sys/class/net/<iface>/queues/rx-<queue>/rps_cpus + Date: March 2010 + KernelVersion: 2.6.35 + Contact: netdev@vger.kernel.org +@@ -8,7 +8,7 @@ Description: + network device queue. Possible values depend on the number + of available CPU(s) in the system. + +-What: /sys/class/<iface>/queues/rx-<queue>/rps_flow_cnt ++What: /sys/class/net/<iface>/queues/rx-<queue>/rps_flow_cnt + Date: April 2010 + KernelVersion: 2.6.35 + Contact: netdev@vger.kernel.org +@@ -16,7 +16,7 @@ Description: + Number of Receive Packet Steering flows being currently + processed by this particular network device receive queue. + +-What: /sys/class/<iface>/queues/tx-<queue>/tx_timeout ++What: /sys/class/net/<iface>/queues/tx-<queue>/tx_timeout + Date: November 2011 + KernelVersion: 3.3 + Contact: netdev@vger.kernel.org +@@ -24,7 +24,7 @@ Description: + Indicates the number of transmit timeout events seen by this + network interface transmit queue. + +-What: /sys/class/<iface>/queues/tx-<queue>/tx_maxrate ++What: /sys/class/net/<iface>/queues/tx-<queue>/tx_maxrate + Date: March 2015 + KernelVersion: 4.1 + Contact: netdev@vger.kernel.org +@@ -32,7 +32,7 @@ Description: + A Mbps max-rate set for the queue, a value of zero means disabled, + default is disabled. + +-What: /sys/class/<iface>/queues/tx-<queue>/xps_cpus ++What: /sys/class/net/<iface>/queues/tx-<queue>/xps_cpus + Date: November 2010 + KernelVersion: 2.6.38 + Contact: netdev@vger.kernel.org +@@ -42,7 +42,7 @@ Description: + network device transmit queue. Possible values depend on the + number of available CPU(s) in the system. + +-What: /sys/class/<iface>/queues/tx-<queue>/xps_rxqs ++What: /sys/class/net/<iface>/queues/tx-<queue>/xps_rxqs + Date: June 2018 + KernelVersion: 4.18.0 + Contact: netdev@vger.kernel.org +@@ -53,7 +53,7 @@ Description: + number of available receive queue(s) in the network device. + Default is disabled. + +-What: /sys/class/<iface>/queues/tx-<queue>/byte_queue_limits/hold_time ++What: /sys/class/net/<iface>/queues/tx-<queue>/byte_queue_limits/hold_time + Date: November 2011 + KernelVersion: 3.3 + Contact: netdev@vger.kernel.org +@@ -62,7 +62,7 @@ Description: + of this particular network device transmit queue. + Default value is 1000. + +-What: /sys/class/<iface>/queues/tx-<queue>/byte_queue_limits/inflight ++What: /sys/class/net/<iface>/queues/tx-<queue>/byte_queue_limits/inflight + Date: November 2011 + KernelVersion: 3.3 + Contact: netdev@vger.kernel.org +@@ -70,7 +70,7 @@ Description: + Indicates the number of bytes (objects) in flight on this + network device transmit queue. + +-What: /sys/class/<iface>/queues/tx-<queue>/byte_queue_limits/limit ++What: /sys/class/net/<iface>/queues/tx-<queue>/byte_queue_limits/limit + Date: November 2011 + KernelVersion: 3.3 + Contact: netdev@vger.kernel.org +@@ -79,7 +79,7 @@ Description: + on this network device transmit queue. This value is clamped + to be within the bounds defined by limit_max and limit_min. + +-What: /sys/class/<iface>/queues/tx-<queue>/byte_queue_limits/limit_max ++What: /sys/class/net/<iface>/queues/tx-<queue>/byte_queue_limits/limit_max + Date: November 2011 + KernelVersion: 3.3 + Contact: netdev@vger.kernel.org +@@ -88,7 +88,7 @@ Description: + queued on this network device transmit queue. See + include/linux/dynamic_queue_limits.h for the default value. + +-What: /sys/class/<iface>/queues/tx-<queue>/byte_queue_limits/limit_min ++What: /sys/class/net/<iface>/queues/tx-<queue>/byte_queue_limits/limit_min + Date: November 2011 + KernelVersion: 3.3 + Contact: netdev@vger.kernel.org +diff --git a/Documentation/sound/soc/dapm.rst b/Documentation/sound/soc/dapm.rst +index 8e44107933abf..c3154ce6e1b27 100644 +--- a/Documentation/sound/soc/dapm.rst ++++ b/Documentation/sound/soc/dapm.rst +@@ -234,7 +234,7 @@ corresponding soft power control. In this case it is necessary to create + a virtual widget - a widget with no control bits e.g. + :: + +- SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_DAPM_NOPM, 0, 0, NULL, 0), ++ SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), + + This can be used to merge to signal paths together in software. + +diff --git a/Makefile b/Makefile +index 96a08c9f0faa1..73a208d9d4c48 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 6 + PATCHLEVEL = 7 +-SUBLEVEL = 3 ++SUBLEVEL = 4 + EXTRAVERSION = + NAME = Hurr durr I'ma ninja sloth + +diff --git a/arch/alpha/kernel/asm-offsets.c b/arch/alpha/kernel/asm-offsets.c +index b121294bee266..bf1eedd27cf75 100644 +--- a/arch/alpha/kernel/asm-offsets.c ++++ b/arch/alpha/kernel/asm-offsets.c +@@ -12,7 +12,7 @@ + #include <linux/kbuild.h> + #include <asm/io.h> + +-void foo(void) ++static void __used foo(void) + { + DEFINE(TI_TASK, offsetof(struct thread_info, task)); + DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); +diff --git a/arch/arm/boot/dts/intel/ixp/intel-ixp42x-usrobotics-usr8200.dts b/arch/arm/boot/dts/intel/ixp/intel-ixp42x-usrobotics-usr8200.dts +index 90fd51b36e7da..2c89db34c8d88 100644 +--- a/arch/arm/boot/dts/intel/ixp/intel-ixp42x-usrobotics-usr8200.dts ++++ b/arch/arm/boot/dts/intel/ixp/intel-ixp42x-usrobotics-usr8200.dts +@@ -165,6 +165,24 @@ + #address-cells = <1>; + #size-cells = <0>; + ++ /* ++ * PHY 0..4 are internal to the MV88E6060 switch but appear ++ * as independent devices. ++ */ ++ phy0: ethernet-phy@0 { ++ reg = <0>; ++ }; ++ phy1: ethernet-phy@1 { ++ reg = <1>; ++ }; ++ phy2: ethernet-phy@2 { ++ reg = <2>; ++ }; ++ phy3: ethernet-phy@3 { ++ reg = <3>; ++ }; ++ ++ /* Altima AMI101L used by the WAN port */ + phy9: ethernet-phy@9 { + reg = <9>; + }; +@@ -181,21 +199,25 @@ + port@0 { + reg = <0>; + label = "lan1"; ++ phy-handle = <&phy0>; + }; + + port@1 { + reg = <1>; + label = "lan2"; ++ phy-handle = <&phy1>; + }; + + port@2 { + reg = <2>; + label = "lan3"; ++ phy-handle = <&phy2>; + }; + + port@3 { + reg = <3>; + label = "lan4"; ++ phy-handle = <&phy3>; + }; + + port@5 { +diff --git a/arch/arm/boot/dts/marvell/armada-370-rd.dts b/arch/arm/boot/dts/marvell/armada-370-rd.dts +index b459a670f6158..1b241da11e942 100644 +--- a/arch/arm/boot/dts/marvell/armada-370-rd.dts ++++ b/arch/arm/boot/dts/marvell/armada-370-rd.dts +@@ -149,39 +149,37 @@ + }; + }; + +- switch: switch@10 { ++ switch: ethernet-switch@10 { + compatible = "marvell,mv88e6085"; +- #address-cells = <1>; +- #size-cells = <0>; + reg = <0x10>; + interrupt-controller; + #interrupt-cells = <2>; + +- ports { ++ ethernet-ports { + #address-cells = <1>; + #size-cells = <0>; + +- port@0 { ++ ethernet-port@0 { + reg = <0>; + label = "lan0"; + }; + +- port@1 { ++ ethernet-port@1 { + reg = <1>; + label = "lan1"; + }; + +- port@2 { ++ ethernet-port@2 { + reg = <2>; + label = "lan2"; + }; + +- port@3 { ++ ethernet-port@3 { + reg = <3>; + label = "lan3"; + }; + +- port@5 { ++ ethernet-port@5 { + reg = <5>; + ethernet = <ð1>; + phy-mode = "rgmii-id"; +@@ -196,25 +194,25 @@ + #address-cells = <1>; + #size-cells = <0>; + +- switchphy0: switchphy@0 { ++ switchphy0: ethernet-phy@0 { + reg = <0>; + interrupt-parent = <&switch>; + interrupts = <0 IRQ_TYPE_LEVEL_HIGH>; + }; + +- switchphy1: switchphy@1 { ++ switchphy1: ethernet-phy@1 { + reg = <1>; + interrupt-parent = <&switch>; + interrupts = <1 IRQ_TYPE_LEVEL_HIGH>; + }; + +- switchphy2: switchphy@2 { ++ switchphy2: ethernet-phy@2 { + reg = <2>; + interrupt-parent = <&switch>; + interrupts = <2 IRQ_TYPE_LEVEL_HIGH>; + }; + +- switchphy3: switchphy@3 { ++ switchphy3: ethernet-phy@3 { + reg = <3>; + interrupt-parent = <&switch>; + interrupts = <3 IRQ_TYPE_LEVEL_HIGH>; +diff --git a/arch/arm/boot/dts/marvell/armada-381-netgear-gs110emx.dts b/arch/arm/boot/dts/marvell/armada-381-netgear-gs110emx.dts +index f4c4b213ef4ed..5baf83e5253d8 100644 +--- a/arch/arm/boot/dts/marvell/armada-381-netgear-gs110emx.dts ++++ b/arch/arm/boot/dts/marvell/armada-381-netgear-gs110emx.dts +@@ -77,51 +77,49 @@ + pinctrl-0 = <&mdio_pins>; + status = "okay"; + +- switch@0 { ++ ethernet-switch@0 { + compatible = "marvell,mv88e6190"; +- #address-cells = <1>; + #interrupt-cells = <2>; + interrupt-controller; + interrupt-parent = <&gpio1>; + interrupts = <7 IRQ_TYPE_LEVEL_LOW>; + pinctrl-0 = <&switch_interrupt_pins>; + pinctrl-names = "default"; +- #size-cells = <0>; + reg = <0>; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + +- switch0phy1: switch0phy1@1 { ++ switch0phy1: ethernet-phy@1 { + reg = <0x1>; + }; + +- switch0phy2: switch0phy2@2 { ++ switch0phy2: ethernet-phy@2 { + reg = <0x2>; + }; + +- switch0phy3: switch0phy3@3 { ++ switch0phy3: ethernet-phy@3 { + reg = <0x3>; + }; + +- switch0phy4: switch0phy4@4 { ++ switch0phy4: ethernet-phy@4 { + reg = <0x4>; + }; + +- switch0phy5: switch0phy5@5 { ++ switch0phy5: ethernet-phy@5 { + reg = <0x5>; + }; + +- switch0phy6: switch0phy6@6 { ++ switch0phy6: ethernet-phy@6 { + reg = <0x6>; + }; + +- switch0phy7: switch0phy7@7 { ++ switch0phy7: ethernet-phy@7 { + reg = <0x7>; + }; + +- switch0phy8: switch0phy8@8 { ++ switch0phy8: ethernet-phy@8 { + reg = <0x8>; + }; + }; +@@ -142,11 +140,11 @@ + }; + }; + +- ports { ++ ethernet-ports { + #address-cells = <1>; + #size-cells = <0>; + +- port@0 { ++ ethernet-port@0 { + ethernet = <ð0>; + phy-mode = "rgmii"; + reg = <0>; +@@ -158,55 +156,55 @@ + }; + }; + +- port@1 { ++ ethernet-port@1 { + label = "lan1"; + phy-handle = <&switch0phy1>; + reg = <1>; + }; + +- port@2 { ++ ethernet-port@2 { + label = "lan2"; + phy-handle = <&switch0phy2>; + reg = <2>; + }; + +- port@3 { ++ ethernet-port@3 { + label = "lan3"; + phy-handle = <&switch0phy3>; + reg = <3>; + }; + +- port@4 { ++ ethernet-port@4 { + label = "lan4"; + phy-handle = <&switch0phy4>; + reg = <4>; + }; + +- port@5 { ++ ethernet-port@5 { + label = "lan5"; + phy-handle = <&switch0phy5>; + reg = <5>; + }; + +- port@6 { ++ ethernet-port@6 { + label = "lan6"; + phy-handle = <&switch0phy6>; + reg = <6>; + }; + +- port@7 { ++ ethernet-port@7 { + label = "lan7"; + phy-handle = <&switch0phy7>; + reg = <7>; + }; + +- port@8 { ++ ethernet-port@8 { + label = "lan8"; + phy-handle = <&switch0phy8>; + reg = <8>; + }; + +- port@9 { ++ ethernet-port@9 { + /* 88X3310P external phy */ + label = "lan9"; + phy-handle = <&phy1>; +@@ -214,7 +212,7 @@ + reg = <9>; + }; + +- port@a { ++ ethernet-port@a { + /* 88X3310P external phy */ + label = "lan10"; + phy-handle = <&phy2>; +diff --git a/arch/arm/boot/dts/marvell/armada-385-clearfog-gtr-l8.dts b/arch/arm/boot/dts/marvell/armada-385-clearfog-gtr-l8.dts +index 1990f7d0cc79a..1707d1b015452 100644 +--- a/arch/arm/boot/dts/marvell/armada-385-clearfog-gtr-l8.dts ++++ b/arch/arm/boot/dts/marvell/armada-385-clearfog-gtr-l8.dts +@@ -7,66 +7,66 @@ + }; + + &mdio { +- switch0: switch0@4 { ++ switch0: ethernet-switch@4 { + compatible = "marvell,mv88e6190"; + reg = <4>; + pinctrl-names = "default"; + pinctrl-0 = <&cf_gtr_switch_reset_pins>; + reset-gpios = <&gpio0 18 GPIO_ACTIVE_LOW>; + +- ports { ++ ethernet-ports { + #address-cells = <1>; + #size-cells = <0>; + +- port@1 { ++ ethernet-port@1 { + reg = <1>; + label = "lan8"; + phy-handle = <&switch0phy0>; + }; + +- port@2 { ++ ethernet-port@2 { + reg = <2>; + label = "lan7"; + phy-handle = <&switch0phy1>; + }; + +- port@3 { ++ ethernet-port@3 { + reg = <3>; + label = "lan6"; + phy-handle = <&switch0phy2>; + }; + +- port@4 { ++ ethernet-port@4 { + reg = <4>; + label = "lan5"; + phy-handle = <&switch0phy3>; + }; + +- port@5 { ++ ethernet-port@5 { + reg = <5>; + label = "lan4"; + phy-handle = <&switch0phy4>; + }; + +- port@6 { ++ ethernet-port@6 { + reg = <6>; + label = "lan3"; + phy-handle = <&switch0phy5>; + }; + +- port@7 { ++ ethernet-port@7 { + reg = <7>; + label = "lan2"; + phy-handle = <&switch0phy6>; + }; + +- port@8 { ++ ethernet-port@8 { + reg = <8>; + label = "lan1"; + phy-handle = <&switch0phy7>; + }; + +- port@10 { ++ ethernet-port@10 { + reg = <10>; + phy-mode = "2500base-x"; + +@@ -83,35 +83,35 @@ + #address-cells = <1>; + #size-cells = <0>; + +- switch0phy0: switch0phy0@1 { ++ switch0phy0: ethernet-phy@1 { + reg = <0x1>; + }; + +- switch0phy1: switch0phy1@2 { ++ switch0phy1: ethernet-phy@2 { + reg = <0x2>; + }; + +- switch0phy2: switch0phy2@3 { ++ switch0phy2: ethernet-phy@3 { + reg = <0x3>; + }; + +- switch0phy3: switch0phy3@4 { ++ switch0phy3: ethernet-phy@4 { + reg = <0x4>; + }; + +- switch0phy4: switch0phy4@5 { ++ switch0phy4: ethernet-phy@5 { + reg = <0x5>; + }; + +- switch0phy5: switch0phy5@6 { ++ switch0phy5: ethernet-phy@6 { + reg = <0x6>; + }; + +- switch0phy6: switch0phy6@7 { ++ switch0phy6: ethernet-phy@7 { + reg = <0x7>; + }; + +- switch0phy7: switch0phy7@8 { ++ switch0phy7: ethernet-phy@8 { + reg = <0x8>; + }; + }; +diff --git a/arch/arm/boot/dts/marvell/armada-385-clearfog-gtr-s4.dts b/arch/arm/boot/dts/marvell/armada-385-clearfog-gtr-s4.dts +index b795ad573891e..a7678a784c180 100644 +--- a/arch/arm/boot/dts/marvell/armada-385-clearfog-gtr-s4.dts ++++ b/arch/arm/boot/dts/marvell/armada-385-clearfog-gtr-s4.dts +@@ -11,42 +11,42 @@ + }; + + &mdio { +- switch0: switch0@4 { ++ switch0: ethernet-switch@4 { + compatible = "marvell,mv88e6085"; + reg = <4>; + pinctrl-names = "default"; + pinctrl-0 = <&cf_gtr_switch_reset_pins>; + reset-gpios = <&gpio0 18 GPIO_ACTIVE_LOW>; + +- ports { ++ ethernet-ports { + #address-cells = <1>; + #size-cells = <0>; + +- port@1 { ++ ethernet-port@1 { + reg = <1>; + label = "lan2"; + phy-handle = <&switch0phy0>; + }; + +- port@2 { ++ ethernet-port@2 { + reg = <2>; + label = "lan1"; + phy-handle = <&switch0phy1>; + }; + +- port@3 { ++ ethernet-port@3 { + reg = <3>; + label = "lan4"; + phy-handle = <&switch0phy2>; + }; + +- port@4 { ++ ethernet-port@4 { + reg = <4>; + label = "lan3"; + phy-handle = <&switch0phy3>; + }; + +- port@5 { ++ ethernet-port@5 { + reg = <5>; + phy-mode = "2500base-x"; + ethernet = <ð1>; +@@ -63,19 +63,19 @@ + #address-cells = <1>; + #size-cells = <0>; + +- switch0phy0: switch0phy0@11 { ++ switch0phy0: ethernet-phy@11 { + reg = <0x11>; + }; + +- switch0phy1: switch0phy1@12 { ++ switch0phy1: ethernet-phy@12 { + reg = <0x12>; + }; + +- switch0phy2: switch0phy2@13 { ++ switch0phy2: ethernet-phy@13 { + reg = <0x13>; + }; + +- switch0phy3: switch0phy3@14 { ++ switch0phy3: ethernet-phy@14 { + reg = <0x14>; + }; + }; +diff --git a/arch/arm/boot/dts/marvell/armada-385-linksys.dtsi b/arch/arm/boot/dts/marvell/armada-385-linksys.dtsi +index fc8216fd9f600..4116ed60f7092 100644 +--- a/arch/arm/boot/dts/marvell/armada-385-linksys.dtsi ++++ b/arch/arm/boot/dts/marvell/armada-385-linksys.dtsi +@@ -158,42 +158,40 @@ + &mdio { + status = "okay"; + +- switch@0 { ++ ethernet-switch@0 { + compatible = "marvell,mv88e6085"; +- #address-cells = <1>; +- #size-cells = <0>; + reg = <0>; + +- ports { ++ ethernet-ports { + #address-cells = <1>; + #size-cells = <0>; + +- port@0 { ++ ethernet-port@0 { + reg = <0>; + label = "lan4"; + }; + +- port@1 { ++ ethernet-port@1 { + reg = <1>; + label = "lan3"; + }; + +- port@2 { ++ ethernet-port@2 { + reg = <2>; + label = "lan2"; + }; + +- port@3 { ++ ethernet-port@3 { + reg = <3>; + label = "lan1"; + }; + +- port@4 { ++ ethernet-port@4 { + reg = <4>; + label = "wan"; + }; + +- port@5 { ++ ethernet-port@5 { + reg = <5>; + phy-mode = "sgmii"; + ethernet = <ð2>; +diff --git a/arch/arm/boot/dts/marvell/armada-385-turris-omnia.dts b/arch/arm/boot/dts/marvell/armada-385-turris-omnia.dts +index 2d8d319bec830..7b755bb4e4e75 100644 +--- a/arch/arm/boot/dts/marvell/armada-385-turris-omnia.dts ++++ b/arch/arm/boot/dts/marvell/armada-385-turris-omnia.dts +@@ -435,12 +435,10 @@ + }; + + /* Switch MV88E6176 at address 0x10 */ +- switch@10 { ++ ethernet-switch@10 { + pinctrl-names = "default"; + pinctrl-0 = <&swint_pins>; + compatible = "marvell,mv88e6085"; +- #address-cells = <1>; +- #size-cells = <0>; + + dsa,member = <0 0>; + reg = <0x10>; +@@ -448,36 +446,36 @@ + interrupt-parent = <&gpio1>; + interrupts = <13 IRQ_TYPE_LEVEL_LOW>; + +- ports { ++ ethernet-ports { + #address-cells = <1>; + #size-cells = <0>; + +- ports@0 { ++ ethernet-port@0 { + reg = <0>; + label = "lan0"; + }; + +- ports@1 { ++ ethernet-port@1 { + reg = <1>; + label = "lan1"; + }; + +- ports@2 { ++ ethernet-port@2 { + reg = <2>; + label = "lan2"; + }; + +- ports@3 { ++ ethernet-port@3 { + reg = <3>; + label = "lan3"; + }; + +- ports@4 { ++ ethernet-port@4 { + reg = <4>; + label = "lan4"; + }; + +- ports@5 { ++ ethernet-port@5 { + reg = <5>; + ethernet = <ð1>; + phy-mode = "rgmii-id"; +@@ -488,7 +486,7 @@ + }; + }; + +- ports@6 { ++ ethernet-port@6 { + reg = <6>; + ethernet = <ð0>; + phy-mode = "rgmii-id"; +diff --git a/arch/arm/boot/dts/marvell/armada-388-clearfog.dts b/arch/arm/boot/dts/marvell/armada-388-clearfog.dts +index 32c569df142ff..3290ccad23745 100644 +--- a/arch/arm/boot/dts/marvell/armada-388-clearfog.dts ++++ b/arch/arm/boot/dts/marvell/armada-388-clearfog.dts +@@ -92,44 +92,42 @@ + &mdio { + status = "okay"; + +- switch@4 { ++ ethernet-switch@4 { + compatible = "marvell,mv88e6085"; +- #address-cells = <1>; +- #size-cells = <0>; + reg = <4>; + pinctrl-0 = <&clearfog_dsa0_clk_pins &clearfog_dsa0_pins>; + pinctrl-names = "default"; + +- ports { ++ ethernet-ports { + #address-cells = <1>; + #size-cells = <0>; + +- port@0 { ++ ethernet-port@0 { + reg = <0>; + label = "lan5"; + }; + +- port@1 { ++ ethernet-port@1 { + reg = <1>; + label = "lan4"; + }; + +- port@2 { ++ ethernet-port@2 { + reg = <2>; + label = "lan3"; + }; + +- port@3 { ++ ethernet-port@3 { + reg = <3>; + label = "lan2"; + }; + +- port@4 { ++ ethernet-port@4 { + reg = <4>; + label = "lan1"; + }; + +- port@5 { ++ ethernet-port@5 { + reg = <5>; + ethernet = <ð1>; + phy-mode = "1000base-x"; +@@ -140,7 +138,7 @@ + }; + }; + +- port@6 { ++ ethernet-port@6 { + /* 88E1512 external phy */ + reg = <6>; + label = "lan6"; +diff --git a/arch/arm/boot/dts/marvell/armada-xp-linksys-mamba.dts b/arch/arm/boot/dts/marvell/armada-xp-linksys-mamba.dts +index 7a0614fd0c93a..ea859f7ea0422 100644 +--- a/arch/arm/boot/dts/marvell/armada-xp-linksys-mamba.dts ++++ b/arch/arm/boot/dts/marvell/armada-xp-linksys-mamba.dts +@@ -265,42 +265,40 @@ + &mdio { + status = "okay"; + +- switch@0 { ++ ethernet-switch@0 { + compatible = "marvell,mv88e6085"; +- #address-cells = <1>; +- #size-cells = <0>; + reg = <0>; + +- ports { ++ ethernet-ports { + #address-cells = <1>; + #size-cells = <0>; + +- port@0 { ++ ethernet-port@0 { + reg = <0>; + label = "lan4"; + }; + +- port@1 { ++ ethernet-port@1 { + reg = <1>; + label = "lan3"; + }; + +- port@2 { ++ ethernet-port@2 { + reg = <2>; + label = "lan2"; + }; + +- port@3 { ++ ethernet-port@3 { + reg = <3>; + label = "lan1"; + }; + +- port@4 { ++ ethernet-port@4 { + reg = <4>; + label = "internet"; + }; + +- port@5 { ++ ethernet-port@5 { + reg = <5>; + phy-mode = "rgmii-id"; + ethernet = <ð0>; +diff --git a/arch/arm/boot/dts/nxp/imx/imx1-ads.dts b/arch/arm/boot/dts/nxp/imx/imx1-ads.dts +index 5833fb6f15d88..2c817c4a4c68f 100644 +--- a/arch/arm/boot/dts/nxp/imx/imx1-ads.dts ++++ b/arch/arm/boot/dts/nxp/imx/imx1-ads.dts +@@ -65,7 +65,7 @@ + pinctrl-0 = <&pinctrl_weim>; + status = "okay"; + +- nor: nor@0,0 { ++ nor: flash@0,0 { + compatible = "cfi-flash"; + reg = <0 0x00000000 0x02000000>; + bank-width = <4>; +diff --git a/arch/arm/boot/dts/nxp/imx/imx1-apf9328.dts b/arch/arm/boot/dts/nxp/imx/imx1-apf9328.dts +index 1f11e9542a72d..e66eef87a7a4f 100644 +--- a/arch/arm/boot/dts/nxp/imx/imx1-apf9328.dts ++++ b/arch/arm/boot/dts/nxp/imx/imx1-apf9328.dts +@@ -45,7 +45,7 @@ + pinctrl-0 = <&pinctrl_weim>; + status = "okay"; + +- nor: nor@0,0 { ++ nor: flash@0,0 { + compatible = "cfi-flash"; + reg = <0 0x00000000 0x02000000>; + bank-width = <2>; +diff --git a/arch/arm/boot/dts/nxp/imx/imx1.dtsi b/arch/arm/boot/dts/nxp/imx/imx1.dtsi +index e312f1e74e2fe..4aeb74479f44e 100644 +--- a/arch/arm/boot/dts/nxp/imx/imx1.dtsi ++++ b/arch/arm/boot/dts/nxp/imx/imx1.dtsi +@@ -268,9 +268,12 @@ + status = "disabled"; + }; + +- esram: esram@300000 { ++ esram: sram@300000 { + compatible = "mmio-sram"; + reg = <0x00300000 0x20000>; ++ ranges = <0 0x00300000 0x20000>; ++ #address-cells = <1>; ++ #size-cells = <1>; + }; + }; + }; +diff --git a/arch/arm/boot/dts/nxp/imx/imx25-eukrea-cpuimx25.dtsi b/arch/arm/boot/dts/nxp/imx/imx25-eukrea-cpuimx25.dtsi +index 0703f62d10d1c..93a6e4e680b45 100644 +--- a/arch/arm/boot/dts/nxp/imx/imx25-eukrea-cpuimx25.dtsi ++++ b/arch/arm/boot/dts/nxp/imx/imx25-eukrea-cpuimx25.dtsi +@@ -27,7 +27,7 @@ + pinctrl-0 = <&pinctrl_i2c1>; + status = "okay"; + +- pcf8563@51 { ++ rtc@51 { + compatible = "nxp,pcf8563"; + reg = <0x51>; + }; +diff --git a/arch/arm/boot/dts/nxp/imx/imx25-eukrea-mbimxsd25-baseboard-cmo-qvga.dts b/arch/arm/boot/dts/nxp/imx/imx25-eukrea-mbimxsd25-baseboard-cmo-qvga.dts +index fc8a502fc957f..6cddb2cc36fe2 100644 +--- a/arch/arm/boot/dts/nxp/imx/imx25-eukrea-mbimxsd25-baseboard-cmo-qvga.dts ++++ b/arch/arm/boot/dts/nxp/imx/imx25-eukrea-mbimxsd25-baseboard-cmo-qvga.dts +@@ -16,7 +16,7 @@ + bus-width = <18>; + display-timings { + native-mode = <&qvga_timings>; +- qvga_timings: 320x240 { ++ qvga_timings: timing0 { + clock-frequency = <6500000>; + hactive = <320>; + vactive = <240>; +diff --git a/arch/arm/boot/dts/nxp/imx/imx25-eukrea-mbimxsd25-baseboard-dvi-svga.dts b/arch/arm/boot/dts/nxp/imx/imx25-eukrea-mbimxsd25-baseboard-dvi-svga.dts +index 80a7f96de4c6a..64b2ffac463b2 100644 +--- a/arch/arm/boot/dts/nxp/imx/imx25-eukrea-mbimxsd25-baseboard-dvi-svga.dts ++++ b/arch/arm/boot/dts/nxp/imx/imx25-eukrea-mbimxsd25-baseboard-dvi-svga.dts +@@ -16,7 +16,7 @@ + bus-width = <18>; + display-timings { + native-mode = <&dvi_svga_timings>; +- dvi_svga_timings: 800x600 { ++ dvi_svga_timings: timing0 { + clock-frequency = <40000000>; + hactive = <800>; + vactive = <600>; +diff --git a/arch/arm/boot/dts/nxp/imx/imx25-eukrea-mbimxsd25-baseboard-dvi-vga.dts b/arch/arm/boot/dts/nxp/imx/imx25-eukrea-mbimxsd25-baseboard-dvi-vga.dts +index 24027a1fb46d1..fb074bfdaa8dc 100644 +--- a/arch/arm/boot/dts/nxp/imx/imx25-eukrea-mbimxsd25-baseboard-dvi-vga.dts ++++ b/arch/arm/boot/dts/nxp/imx/imx25-eukrea-mbimxsd25-baseboard-dvi-vga.dts +@@ -16,7 +16,7 @@ + bus-width = <18>; + display-timings { + native-mode = <&dvi_vga_timings>; +- dvi_vga_timings: 640x480 { ++ dvi_vga_timings: timing0 { + clock-frequency = <31250000>; + hactive = <640>; + vactive = <480>; +diff --git a/arch/arm/boot/dts/nxp/imx/imx25-pdk.dts b/arch/arm/boot/dts/nxp/imx/imx25-pdk.dts +index 04f4b127a1725..e93bf3b7115fa 100644 +--- a/arch/arm/boot/dts/nxp/imx/imx25-pdk.dts ++++ b/arch/arm/boot/dts/nxp/imx/imx25-pdk.dts +@@ -68,7 +68,7 @@ + bus-width = <18>; + display-timings { + native-mode = <&wvga_timings>; +- wvga_timings: 640x480 { ++ wvga_timings: timing0 { + hactive = <640>; + vactive = <480>; + hback-porch = <45>; +diff --git a/arch/arm/boot/dts/nxp/imx/imx25.dtsi b/arch/arm/boot/dts/nxp/imx/imx25.dtsi +index 534c70b8d79df..f65c7234f9e7f 100644 +--- a/arch/arm/boot/dts/nxp/imx/imx25.dtsi ++++ b/arch/arm/boot/dts/nxp/imx/imx25.dtsi +@@ -542,7 +542,7 @@ + }; + + iim: efuse@53ff0000 { +- compatible = "fsl,imx25-iim", "fsl,imx27-iim"; ++ compatible = "fsl,imx25-iim"; + reg = <0x53ff0000 0x4000>; + interrupts = <19>; + clocks = <&clks 99>; +diff --git a/arch/arm/boot/dts/nxp/imx/imx27-apf27dev.dts b/arch/arm/boot/dts/nxp/imx/imx27-apf27dev.dts +index a21f1f7c24b88..849306cb4532d 100644 +--- a/arch/arm/boot/dts/nxp/imx/imx27-apf27dev.dts ++++ b/arch/arm/boot/dts/nxp/imx/imx27-apf27dev.dts +@@ -16,7 +16,7 @@ + fsl,pcr = <0xfae80083>; /* non-standard but required */ + display-timings { + native-mode = <&timing0>; +- timing0: 800x480 { ++ timing0: timing0 { + clock-frequency = <33000033>; + hactive = <800>; + vactive = <480>; +@@ -47,7 +47,7 @@ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_leds>; + +- user { ++ led-user { + label = "Heartbeat"; + gpios = <&gpio6 14 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; +diff --git a/arch/arm/boot/dts/nxp/imx/imx27-eukrea-cpuimx27.dtsi b/arch/arm/boot/dts/nxp/imx/imx27-eukrea-cpuimx27.dtsi +index 74110bbcd9d4f..c7e9235848782 100644 +--- a/arch/arm/boot/dts/nxp/imx/imx27-eukrea-cpuimx27.dtsi ++++ b/arch/arm/boot/dts/nxp/imx/imx27-eukrea-cpuimx27.dtsi +@@ -33,7 +33,7 @@ + pinctrl-0 = <&pinctrl_i2c1>; + status = "okay"; + +- pcf8563@51 { ++ rtc@51 { + compatible = "nxp,pcf8563"; + reg = <0x51>; + }; +@@ -90,7 +90,7 @@ + &weim { + status = "okay"; + +- nor: nor@0,0 { ++ nor: flash@0,0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "cfi-flash"; +diff --git a/arch/arm/boot/dts/nxp/imx/imx27-eukrea-mbimxsd27-baseboard.dts b/arch/arm/boot/dts/nxp/imx/imx27-eukrea-mbimxsd27-baseboard.dts +index 145e459625b32..d78793601306c 100644 +--- a/arch/arm/boot/dts/nxp/imx/imx27-eukrea-mbimxsd27-baseboard.dts ++++ b/arch/arm/boot/dts/nxp/imx/imx27-eukrea-mbimxsd27-baseboard.dts +@@ -16,7 +16,7 @@ + + display-timings { + native-mode = <&timing0>; +- timing0: 320x240 { ++ timing0: timing0 { + clock-frequency = <6500000>; + hactive = <320>; + vactive = <240>; +diff --git a/arch/arm/boot/dts/nxp/imx/imx27-phytec-phycard-s-rdk.dts b/arch/arm/boot/dts/nxp/imx/imx27-phytec-phycard-s-rdk.dts +index 25442eba21c1e..27c93b9fe0499 100644 +--- a/arch/arm/boot/dts/nxp/imx/imx27-phytec-phycard-s-rdk.dts ++++ b/arch/arm/boot/dts/nxp/imx/imx27-phytec-phycard-s-rdk.dts +@@ -19,7 +19,7 @@ + fsl,pcr = <0xf0c88080>; /* non-standard but required */ + display-timings { + native-mode = <&timing0>; +- timing0: 640x480 { ++ timing0: timing0 { + hactive = <640>; + vactive = <480>; + hback-porch = <112>; +diff --git a/arch/arm/boot/dts/nxp/imx/imx27-phytec-phycore-rdk.dts b/arch/arm/boot/dts/nxp/imx/imx27-phytec-phycore-rdk.dts +index 7f0cd4d3ec2de..67b235044b708 100644 +--- a/arch/arm/boot/dts/nxp/imx/imx27-phytec-phycore-rdk.dts ++++ b/arch/arm/boot/dts/nxp/imx/imx27-phytec-phycore-rdk.dts +@@ -19,7 +19,7 @@ + + display-timings { + native-mode = <&timing0>; +- timing0: 240x320 { ++ timing0: timing0 { + clock-frequency = <5500000>; + hactive = <240>; + vactive = <320>; +diff --git a/arch/arm/boot/dts/nxp/imx/imx27-phytec-phycore-som.dtsi b/arch/arm/boot/dts/nxp/imx/imx27-phytec-phycore-som.dtsi +index 7b2ea4cdae58c..8d428c8446665 100644 +--- a/arch/arm/boot/dts/nxp/imx/imx27-phytec-phycore-som.dtsi ++++ b/arch/arm/boot/dts/nxp/imx/imx27-phytec-phycore-som.dtsi +@@ -314,7 +314,7 @@ + &weim { + status = "okay"; + +- nor: nor@0,0 { ++ nor: flash@0,0 { + compatible = "cfi-flash"; + reg = <0 0x00000000 0x02000000>; + bank-width = <2>; +diff --git a/arch/arm/boot/dts/nxp/imx/imx27.dtsi b/arch/arm/boot/dts/nxp/imx/imx27.dtsi +index faba12ee7465e..cac4b3d68986a 100644 +--- a/arch/arm/boot/dts/nxp/imx/imx27.dtsi ++++ b/arch/arm/boot/dts/nxp/imx/imx27.dtsi +@@ -588,6 +588,9 @@ + iram: sram@ffff4c00 { + compatible = "mmio-sram"; + reg = <0xffff4c00 0xb400>; ++ ranges = <0 0xffff4c00 0xb400>; ++ #address-cells = <1>; ++ #size-cells = <1>; + }; + }; + }; +diff --git a/arch/arm/boot/dts/nxp/imx/imx7d.dtsi b/arch/arm/boot/dts/nxp/imx/imx7d.dtsi +index 4b94b8afb55d9..0484e349e064e 100644 +--- a/arch/arm/boot/dts/nxp/imx/imx7d.dtsi ++++ b/arch/arm/boot/dts/nxp/imx/imx7d.dtsi +@@ -217,9 +217,6 @@ + }; + + &ca_funnel_in_ports { +- #address-cells = <1>; +- #size-cells = <0>; +- + port@1 { + reg = <1>; + ca_funnel_in_port1: endpoint { +diff --git a/arch/arm/boot/dts/nxp/imx/imx7s.dtsi b/arch/arm/boot/dts/nxp/imx/imx7s.dtsi +index 5387da8a2a0a3..4569d2b8edef9 100644 +--- a/arch/arm/boot/dts/nxp/imx/imx7s.dtsi ++++ b/arch/arm/boot/dts/nxp/imx/imx7s.dtsi +@@ -190,7 +190,11 @@ + clock-names = "apb_pclk"; + + ca_funnel_in_ports: in-ports { +- port { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ reg = <0>; + ca_funnel_in_port0: endpoint { + remote-endpoint = <&etm0_out_port>; + }; +@@ -811,7 +815,7 @@ + }; + + lcdif: lcdif@30730000 { +- compatible = "fsl,imx7d-lcdif", "fsl,imx28-lcdif"; ++ compatible = "fsl,imx7d-lcdif", "fsl,imx6sx-lcdif"; + reg = <0x30730000 0x10000>; + interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clks IMX7D_LCDIF_PIXEL_ROOT_CLK>, +@@ -1275,7 +1279,7 @@ + gpmi: nand-controller@33002000 { + compatible = "fsl,imx7d-gpmi-nand"; + #address-cells = <1>; +- #size-cells = <1>; ++ #size-cells = <0>; + reg = <0x33002000 0x2000>, <0x33004000 0x4000>; + reg-names = "gpmi-nand", "bch"; + interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; +diff --git a/arch/arm/boot/dts/nxp/mxs/imx23-sansa.dts b/arch/arm/boot/dts/nxp/mxs/imx23-sansa.dts +index 636cf09a2b375..b23e7ada9c804 100644 +--- a/arch/arm/boot/dts/nxp/mxs/imx23-sansa.dts ++++ b/arch/arm/boot/dts/nxp/mxs/imx23-sansa.dts +@@ -175,10 +175,8 @@ + #address-cells = <1>; + #size-cells = <0>; + compatible = "i2c-gpio"; +- gpios = < +- &gpio1 24 0 /* SDA */ +- &gpio1 22 0 /* SCL */ +- >; ++ sda-gpios = <&gpio1 24 0>; ++ scl-gpios = <&gpio1 22 0>; + i2c-gpio,delay-us = <2>; /* ~100 kHz */ + }; + +@@ -186,10 +184,8 @@ + #address-cells = <1>; + #size-cells = <0>; + compatible = "i2c-gpio"; +- gpios = < +- &gpio0 31 0 /* SDA */ +- &gpio0 30 0 /* SCL */ +- >; ++ sda-gpios = <&gpio0 31 0>; ++ scl-gpios = <&gpio0 30 0>; + i2c-gpio,delay-us = <2>; /* ~100 kHz */ + + touch: touch@20 { +diff --git a/arch/arm/boot/dts/nxp/mxs/imx23.dtsi b/arch/arm/boot/dts/nxp/mxs/imx23.dtsi +index fdf18b7cb2f6a..9cba1d0224f49 100644 +--- a/arch/arm/boot/dts/nxp/mxs/imx23.dtsi ++++ b/arch/arm/boot/dts/nxp/mxs/imx23.dtsi +@@ -412,7 +412,7 @@ + status = "disabled"; + }; + +- dma_apbx: dma-apbx@80024000 { ++ dma_apbx: dma-controller@80024000 { + compatible = "fsl,imx23-dma-apbx"; + reg = <0x80024000 0x2000>; + interrupts = <7>, <5>, <9>, <26>, +diff --git a/arch/arm/boot/dts/nxp/mxs/imx28.dtsi b/arch/arm/boot/dts/nxp/mxs/imx28.dtsi +index 6932d23fb29de..37b9d409a5cd7 100644 +--- a/arch/arm/boot/dts/nxp/mxs/imx28.dtsi ++++ b/arch/arm/boot/dts/nxp/mxs/imx28.dtsi +@@ -990,7 +990,7 @@ + status = "disabled"; + }; + +- dma_apbx: dma-apbx@80024000 { ++ dma_apbx: dma-controller@80024000 { + compatible = "fsl,imx28-dma-apbx"; + reg = <0x80024000 0x2000>; + interrupts = <78>, <79>, <66>, <0>, +diff --git a/arch/arm/boot/dts/qcom/pm8226.dtsi b/arch/arm/boot/dts/qcom/pm8226.dtsi +new file mode 100644 +index 0000000000000..2413778f37150 +--- /dev/null ++++ b/arch/arm/boot/dts/qcom/pm8226.dtsi +@@ -0,0 +1,180 @@ ++// SPDX-License-Identifier: BSD-3-Clause ++#include <dt-bindings/iio/qcom,spmi-vadc.h> ++#include <dt-bindings/input/linux-event-codes.h> ++#include <dt-bindings/interrupt-controller/irq.h> ++#include <dt-bindings/spmi/spmi.h> ++ ++/ { ++ thermal-zones { ++ pm8226-thermal { ++ polling-delay-passive = <100>; ++ polling-delay = <0>; ++ thermal-sensors = <&pm8226_temp>; ++ ++ trips { ++ trip0 { ++ temperature = <105000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ ++ trip1 { ++ temperature = <125000>; ++ hysteresis = <2000>; ++ type = "hot"; ++ }; ++ ++ crit { ++ temperature = <145000>; ++ hysteresis = <2000>; ++ type = "critical"; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&spmi_bus { ++ pm8226_0: pm8226@0 { ++ compatible = "qcom,pm8226", "qcom,spmi-pmic"; ++ reg = <0x0 SPMI_USID>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ pon@800 { ++ compatible = "qcom,pm8916-pon"; ++ reg = <0x800>; ++ ++ pwrkey { ++ compatible = "qcom,pm8941-pwrkey"; ++ interrupts = <0x0 0x8 0 IRQ_TYPE_EDGE_BOTH>; ++ debounce = <15625>; ++ bias-pull-up; ++ linux,code = <KEY_POWER>; ++ }; ++ ++ pm8226_resin: resin { ++ compatible = "qcom,pm8941-resin"; ++ interrupts = <0x0 0x8 1 IRQ_TYPE_EDGE_BOTH>; ++ debounce = <15625>; ++ bias-pull-up; ++ status = "disabled"; ++ }; ++ }; ++ ++ smbb: charger@1000 { ++ compatible = "qcom,pm8226-charger"; ++ reg = <0x1000>; ++ interrupts = <0x0 0x10 7 IRQ_TYPE_EDGE_BOTH>, ++ <0x0 0x10 5 IRQ_TYPE_EDGE_BOTH>, ++ <0x0 0x10 4 IRQ_TYPE_EDGE_BOTH>, ++ <0x0 0x12 1 IRQ_TYPE_EDGE_BOTH>, ++ <0x0 0x12 0 IRQ_TYPE_EDGE_BOTH>, ++ <0x0 0x13 2 IRQ_TYPE_EDGE_BOTH>, ++ <0x0 0x13 1 IRQ_TYPE_EDGE_BOTH>, ++ <0x0 0x14 1 IRQ_TYPE_EDGE_BOTH>; ++ interrupt-names = "chg-done", ++ "chg-fast", ++ "chg-trkl", ++ "bat-temp-ok", ++ "bat-present", ++ "chg-gone", ++ "usb-valid", ++ "dc-valid"; ++ ++ chg_otg: otg-vbus { }; ++ }; ++ ++ pm8226_temp: temp-alarm@2400 { ++ compatible = "qcom,spmi-temp-alarm"; ++ reg = <0x2400>; ++ interrupts = <0 0x24 0 IRQ_TYPE_EDGE_RISING>; ++ io-channels = <&pm8226_vadc VADC_DIE_TEMP>; ++ io-channel-names = "thermal"; ++ #thermal-sensor-cells = <0>; ++ }; ++ ++ pm8226_vadc: adc@3100 { ++ compatible = "qcom,spmi-vadc"; ++ reg = <0x3100>; ++ interrupts = <0x0 0x31 0x0 IRQ_TYPE_EDGE_RISING>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #io-channel-cells = <1>; ++ ++ channel@7 { ++ reg = <VADC_VSYS>; ++ qcom,pre-scaling = <1 3>; ++ label = "vph_pwr"; ++ }; ++ channel@8 { ++ reg = <VADC_DIE_TEMP>; ++ label = "die_temp"; ++ }; ++ channel@9 { ++ reg = <VADC_REF_625MV>; ++ label = "ref_625mv"; ++ }; ++ channel@a { ++ reg = <VADC_REF_1250MV>; ++ label = "ref_1250mv"; ++ }; ++ channel@e { ++ reg = <VADC_GND_REF>; ++ }; ++ channel@f { ++ reg = <VADC_VDD_VADC>; ++ }; ++ }; ++ ++ pm8226_iadc: adc@3600 { ++ compatible = "qcom,pm8226-iadc", "qcom,spmi-iadc"; ++ reg = <0x3600>; ++ interrupts = <0x0 0x36 0x0 IRQ_TYPE_EDGE_RISING>; ++ }; ++ ++ rtc@6000 { ++ compatible = "qcom,pm8941-rtc"; ++ reg = <0x6000>, <0x6100>; ++ reg-names = "rtc", "alarm"; ++ interrupts = <0x0 0x61 0x1 IRQ_TYPE_EDGE_RISING>; ++ }; ++ ++ pm8226_mpps: mpps@a000 { ++ compatible = "qcom,pm8226-mpp", "qcom,spmi-mpp"; ++ reg = <0xa000>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ gpio-ranges = <&pm8226_mpps 0 0 8>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ }; ++ ++ pm8226_gpios: gpio@c000 { ++ compatible = "qcom,pm8226-gpio", "qcom,spmi-gpio"; ++ reg = <0xc000>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ gpio-ranges = <&pm8226_gpios 0 0 8>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ }; ++ }; ++ ++ pm8226_1: pm8226@1 { ++ compatible = "qcom,pm8226", "qcom,spmi-pmic"; ++ reg = <0x1 SPMI_USID>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ pm8226_spmi_regulators: regulators { ++ compatible = "qcom,pm8226-regulators"; ++ }; ++ ++ pm8226_vib: vibrator@c000 { ++ compatible = "qcom,pm8916-vib"; ++ reg = <0xc000>; ++ status = "disabled"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/qcom/pm8841.dtsi b/arch/arm/boot/dts/qcom/pm8841.dtsi +new file mode 100644 +index 0000000000000..3bf2ce5c86a64 +--- /dev/null ++++ b/arch/arm/boot/dts/qcom/pm8841.dtsi +@@ -0,0 +1,68 @@ ++// SPDX-License-Identifier: GPL-2.0 ++#include <dt-bindings/interrupt-controller/irq.h> ++#include <dt-bindings/spmi/spmi.h> ++ ++ ++/ { ++ thermal-zones { ++ pm8841-thermal { ++ polling-delay-passive = <100>; ++ polling-delay = <0>; ++ thermal-sensors = <&pm8841_temp>; ++ ++ trips { ++ trip0 { ++ temperature = <105000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ ++ trip1 { ++ temperature = <125000>; ++ hysteresis = <2000>; ++ type = "hot"; ++ }; ++ ++ crit { ++ temperature = <140000>; ++ hysteresis = <2000>; ++ type = "critical"; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&spmi_bus { ++ ++ pm8841_0: pm8841@4 { ++ compatible = "qcom,pm8841", "qcom,spmi-pmic"; ++ reg = <0x4 SPMI_USID>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ pm8841_mpps: mpps@a000 { ++ compatible = "qcom,pm8841-mpp", "qcom,spmi-mpp"; ++ reg = <0xa000>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ gpio-ranges = <&pm8841_mpps 0 0 4>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ }; ++ ++ pm8841_temp: temp-alarm@2400 { ++ compatible = "qcom,spmi-temp-alarm"; ++ reg = <0x2400>; ++ interrupts = <4 0x24 0 IRQ_TYPE_EDGE_RISING>; ++ #thermal-sensor-cells = <0>; ++ }; ++ }; ++ ++ pm8841_1: pm8841@5 { ++ compatible = "qcom,pm8841", "qcom,spmi-pmic"; ++ reg = <0x5 SPMI_USID>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++}; +diff --git a/arch/arm/boot/dts/qcom/pm8941.dtsi b/arch/arm/boot/dts/qcom/pm8941.dtsi +new file mode 100644 +index 0000000000000..ed0ba591c7558 +--- /dev/null ++++ b/arch/arm/boot/dts/qcom/pm8941.dtsi +@@ -0,0 +1,254 @@ ++// SPDX-License-Identifier: GPL-2.0 ++#include <dt-bindings/iio/qcom,spmi-vadc.h> ++#include <dt-bindings/interrupt-controller/irq.h> ++#include <dt-bindings/spmi/spmi.h> ++ ++ ++/ { ++ thermal-zones { ++ pm8941-thermal { ++ polling-delay-passive = <100>; ++ polling-delay = <0>; ++ thermal-sensors = <&pm8941_temp>; ++ ++ trips { ++ trip0 { ++ temperature = <105000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ ++ trip1 { ++ temperature = <125000>; ++ hysteresis = <2000>; ++ type = "hot"; ++ }; ++ ++ crit { ++ temperature = <145000>; ++ hysteresis = <2000>; ++ type = "critical"; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&spmi_bus { ++ ++ pm8941_0: pm8941@0 { ++ compatible = "qcom,pm8941", "qcom,spmi-pmic"; ++ reg = <0x0 SPMI_USID>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ rtc@6000 { ++ compatible = "qcom,pm8941-rtc"; ++ reg = <0x6000>, ++ <0x6100>; ++ reg-names = "rtc", "alarm"; ++ interrupts = <0x0 0x61 0x1 IRQ_TYPE_EDGE_RISING>; ++ }; ++ ++ pon@800 { ++ compatible = "qcom,pm8941-pon"; ++ reg = <0x800>; ++ ++ pwrkey { ++ compatible = "qcom,pm8941-pwrkey"; ++ interrupts = <0x0 0x8 0 IRQ_TYPE_EDGE_BOTH>; ++ debounce = <15625>; ++ bias-pull-up; ++ }; ++ ++ pm8941_resin: resin { ++ compatible = "qcom,pm8941-resin"; ++ interrupts = <0x0 0x8 1 IRQ_TYPE_EDGE_BOTH>; ++ debounce = <15625>; ++ bias-pull-up; ++ status = "disabled"; ++ }; ++ }; ++ ++ usb_id: usb-detect@900 { ++ compatible = "qcom,pm8941-misc"; ++ reg = <0x900>; ++ interrupts = <0x0 0x9 0 IRQ_TYPE_EDGE_BOTH>; ++ interrupt-names = "usb_id"; ++ }; ++ ++ smbb: charger@1000 { ++ compatible = "qcom,pm8941-charger"; ++ reg = <0x1000>; ++ interrupts = <0x0 0x10 7 IRQ_TYPE_EDGE_BOTH>, ++ <0x0 0x10 5 IRQ_TYPE_EDGE_BOTH>, ++ <0x0 0x10 4 IRQ_TYPE_EDGE_BOTH>, ++ <0x0 0x12 1 IRQ_TYPE_EDGE_BOTH>, ++ <0x0 0x12 0 IRQ_TYPE_EDGE_BOTH>, ++ <0x0 0x13 2 IRQ_TYPE_EDGE_BOTH>, ++ <0x0 0x13 1 IRQ_TYPE_EDGE_BOTH>, ++ <0x0 0x14 1 IRQ_TYPE_EDGE_BOTH>; ++ interrupt-names = "chg-done", ++ "chg-fast", ++ "chg-trkl", ++ "bat-temp-ok", ++ "bat-present", ++ "chg-gone", ++ "usb-valid", ++ "dc-valid"; ++ ++ usb-otg-in-supply = <&pm8941_5vs1>; ++ ++ chg_otg: otg-vbus { }; ++ }; ++ ++ pm8941_gpios: gpio@c000 { ++ compatible = "qcom,pm8941-gpio", "qcom,spmi-gpio"; ++ reg = <0xc000>; ++ gpio-controller; ++ gpio-ranges = <&pm8941_gpios 0 0 36>; ++ #gpio-cells = <2>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ ++ boost_bypass_n_pin: boost-bypass-state { ++ pins = "gpio21"; ++ function = "normal"; ++ }; ++ }; ++ ++ pm8941_mpps: mpps@a000 { ++ compatible = "qcom,pm8941-mpp", "qcom,spmi-mpp"; ++ reg = <0xa000>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ gpio-ranges = <&pm8941_mpps 0 0 8>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ }; ++ ++ pm8941_temp: temp-alarm@2400 { ++ compatible = "qcom,spmi-temp-alarm"; ++ reg = <0x2400>; ++ interrupts = <0 0x24 0 IRQ_TYPE_EDGE_RISING>; ++ io-channels = <&pm8941_vadc VADC_DIE_TEMP>; ++ io-channel-names = "thermal"; ++ #thermal-sensor-cells = <0>; ++ }; ++ ++ pm8941_vadc: adc@3100 { ++ compatible = "qcom,spmi-vadc"; ++ reg = <0x3100>; ++ interrupts = <0x0 0x31 0x0 IRQ_TYPE_EDGE_RISING>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #io-channel-cells = <1>; ++ ++ ++ channel@6 { ++ reg = <VADC_VBAT_SNS>; ++ }; ++ ++ channel@8 { ++ reg = <VADC_DIE_TEMP>; ++ }; ++ ++ channel@9 { ++ reg = <VADC_REF_625MV>; ++ }; ++ ++ channel@a { ++ reg = <VADC_REF_1250MV>; ++ }; ++ ++ channel@e { ++ reg = <VADC_GND_REF>; ++ }; ++ ++ channel@f { ++ reg = <VADC_VDD_VADC>; ++ }; ++ ++ channel@30 { ++ reg = <VADC_LR_MUX1_BAT_THERM>; ++ }; ++ }; ++ ++ pm8941_iadc: adc@3600 { ++ compatible = "qcom,pm8941-iadc", "qcom,spmi-iadc"; ++ reg = <0x3600>; ++ interrupts = <0x0 0x36 0x0 IRQ_TYPE_EDGE_RISING>; ++ qcom,external-resistor-micro-ohms = <10000>; ++ }; ++ ++ pm8941_coincell: charger@2800 { ++ compatible = "qcom,pm8941-coincell"; ++ reg = <0x2800>; ++ status = "disabled"; ++ }; ++ }; ++ ++ pm8941_1: pm8941@1 { ++ compatible = "qcom,pm8941", "qcom,spmi-pmic"; ++ reg = <0x1 SPMI_USID>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ pm8941_lpg: pwm { ++ compatible = "qcom,pm8941-lpg"; ++ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #pwm-cells = <2>; ++ ++ status = "disabled"; ++ }; ++ ++ pm8941_vib: vibrator@c000 { ++ compatible = "qcom,pm8916-vib"; ++ reg = <0xc000>; ++ status = "disabled"; ++ }; ++ ++ pm8941_wled: wled@d800 { ++ compatible = "qcom,pm8941-wled"; ++ reg = <0xd800>; ++ label = "backlight"; ++ ++ status = "disabled"; ++ }; ++ ++ regulators { ++ compatible = "qcom,pm8941-regulators"; ++ interrupts = <0x1 0x83 0x2 0>, <0x1 0x84 0x2 0>; ++ interrupt-names = "ocp-5vs1", "ocp-5vs2"; ++ vin_5vs-supply = <&pm8941_5v>; ++ ++ pm8941_5v: s4 { ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-enable-ramp-delay = <500>; ++ }; ++ ++ pm8941_5vs1: 5vs1 { ++ regulator-enable-ramp-delay = <1000>; ++ regulator-pull-down; ++ regulator-over-current-protection; ++ qcom,ocp-max-retries = <10>; ++ qcom,ocp-retry-delay = <30>; ++ qcom,vs-soft-start-strength = <0>; ++ regulator-initial-mode = <1>; ++ }; ++ ++ pm8941_5vs2: 5vs2 { ++ regulator-enable-ramp-delay = <1000>; ++ regulator-pull-down; ++ regulator-over-current-protection; ++ qcom,ocp-max-retries = <10>; ++ qcom,ocp-retry-delay = <30>; ++ qcom,vs-soft-start-strength = <0>; ++ regulator-initial-mode = <1>; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/qcom/pma8084.dtsi b/arch/arm/boot/dts/qcom/pma8084.dtsi +new file mode 100644 +index 0000000000000..2985f4805b93e +--- /dev/null ++++ b/arch/arm/boot/dts/qcom/pma8084.dtsi +@@ -0,0 +1,99 @@ ++// SPDX-License-Identifier: GPL-2.0 ++#include <dt-bindings/iio/qcom,spmi-vadc.h> ++#include <dt-bindings/interrupt-controller/irq.h> ++#include <dt-bindings/spmi/spmi.h> ++ ++&spmi_bus { ++ ++ pma8084_0: pma8084@0 { ++ compatible = "qcom,pma8084", "qcom,spmi-pmic"; ++ reg = <0x0 SPMI_USID>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ rtc@6000 { ++ compatible = "qcom,pm8941-rtc"; ++ reg = <0x6000>, ++ <0x6100>; ++ reg-names = "rtc", "alarm"; ++ interrupts = <0x0 0x61 0x1 IRQ_TYPE_EDGE_RISING>; ++ }; ++ ++ pwrkey@800 { ++ compatible = "qcom,pm8941-pwrkey"; ++ reg = <0x800>; ++ interrupts = <0x0 0x8 0 IRQ_TYPE_EDGE_BOTH>; ++ debounce = <15625>; ++ bias-pull-up; ++ }; ++ ++ pma8084_gpios: gpio@c000 { ++ compatible = "qcom,pma8084-gpio", "qcom,spmi-gpio"; ++ reg = <0xc000>; ++ gpio-controller; ++ gpio-ranges = <&pma8084_gpios 0 0 22>; ++ #gpio-cells = <2>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ }; ++ ++ pma8084_mpps: mpps@a000 { ++ compatible = "qcom,pma8084-mpp", "qcom,spmi-mpp"; ++ reg = <0xa000>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ gpio-ranges = <&pma8084_mpps 0 0 8>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ }; ++ ++ pma8084_temp: temp-alarm@2400 { ++ compatible = "qcom,spmi-temp-alarm"; ++ reg = <0x2400>; ++ interrupts = <0 0x24 0 IRQ_TYPE_EDGE_RISING>; ++ #thermal-sensor-cells = <0>; ++ io-channels = <&pma8084_vadc VADC_DIE_TEMP>; ++ io-channel-names = "thermal"; ++ }; ++ ++ pma8084_vadc: adc@3100 { ++ compatible = "qcom,spmi-vadc"; ++ reg = <0x3100>; ++ interrupts = <0x0 0x31 0x0 IRQ_TYPE_EDGE_RISING>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #io-channel-cells = <1>; ++ ++ channel@8 { ++ reg = <VADC_DIE_TEMP>; ++ }; ++ ++ channel@9 { ++ reg = <VADC_REF_625MV>; ++ }; ++ ++ channel@a { ++ reg = <VADC_REF_1250MV>; ++ }; ++ ++ channel@c { ++ reg = <VADC_SPARE1>; ++ }; ++ ++ channel@e { ++ reg = <VADC_GND_REF>; ++ }; ++ ++ channel@f { ++ reg = <VADC_VDD_VADC>; ++ }; ++ }; ++ }; ++ ++ pma8084_1: pma8084@1 { ++ compatible = "qcom,pma8084", "qcom,spmi-pmic"; ++ reg = <0x1 SPMI_USID>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++}; +diff --git a/arch/arm/boot/dts/qcom/pmx55.dtsi b/arch/arm/boot/dts/qcom/pmx55.dtsi +new file mode 100644 +index 0000000000000..da0851173c699 +--- /dev/null ++++ b/arch/arm/boot/dts/qcom/pmx55.dtsi +@@ -0,0 +1,85 @@ ++// SPDX-License-Identifier: BSD-3-Clause ++ ++/* ++ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. ++ * Copyright (c) 2020, Linaro Limited ++ */ ++ ++#include <dt-bindings/iio/qcom,spmi-vadc.h> ++#include <dt-bindings/interrupt-controller/irq.h> ++#include <dt-bindings/spmi/spmi.h> ++ ++&spmi_bus { ++ pmic@8 { ++ compatible = "qcom,pmx55", "qcom,spmi-pmic"; ++ reg = <0x8 SPMI_USID>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ pon@800 { ++ compatible = "qcom,pm8916-pon"; ++ reg = <0x0800>; ++ ++ status = "disabled"; ++ }; ++ ++ pmx55_temp: temp-alarm@2400 { ++ compatible = "qcom,spmi-temp-alarm"; ++ reg = <0x2400>; ++ interrupts = <0x8 0x24 0x0 IRQ_TYPE_EDGE_BOTH>; ++ io-channels = <&pmx55_adc ADC5_DIE_TEMP>; ++ io-channel-names = "thermal"; ++ #thermal-sensor-cells = <0>; ++ }; ++ ++ pmx55_adc: adc@3100 { ++ compatible = "qcom,spmi-adc5"; ++ reg = <0x3100>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #io-channel-cells = <1>; ++ interrupts = <0x8 0x31 0x0 IRQ_TYPE_EDGE_RISING>; ++ ++ channel@0 { ++ reg = <ADC5_REF_GND>; ++ qcom,pre-scaling = <1 1>; ++ label = "ref_gnd"; ++ }; ++ ++ channel@1 { ++ reg = <ADC5_1P25VREF>; ++ qcom,pre-scaling = <1 1>; ++ label = "vref_1p25"; ++ }; ++ ++ channel@6 { ++ reg = <ADC5_DIE_TEMP>; ++ qcom,pre-scaling = <1 1>; ++ label = "die_temp"; ++ }; ++ ++ channel@9 { ++ reg = <ADC5_CHG_TEMP>; ++ qcom,pre-scaling = <1 1>; ++ label = "chg_temp"; ++ }; ++ }; ++ ++ pmx55_gpios: gpio@c000 { ++ compatible = "qcom,pmx55-gpio", "qcom,spmi-gpio"; ++ reg = <0xc000>; ++ gpio-controller; ++ gpio-ranges = <&pmx55_gpios 0 0 11>; ++ #gpio-cells = <2>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ }; ++ }; ++ ++ pmic@9 { ++ compatible = "qcom,pmx55", "qcom,spmi-pmic"; ++ reg = <0x9 SPMI_USID>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++}; +diff --git a/arch/arm/boot/dts/qcom/pmx65.dtsi b/arch/arm/boot/dts/qcom/pmx65.dtsi +new file mode 100644 +index 0000000000000..1c7fdf59c1f56 +--- /dev/null ++++ b/arch/arm/boot/dts/qcom/pmx65.dtsi +@@ -0,0 +1,33 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. ++ */ ++ ++#include <dt-bindings/interrupt-controller/irq.h> ++#include <dt-bindings/spmi/spmi.h> ++ ++&spmi_bus { ++ pmic@1 { ++ compatible = "qcom,pmx65", "qcom,spmi-pmic"; ++ reg = <1 SPMI_USID>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ pmx65_temp: temp-alarm@a00 { ++ compatible = "qcom,spmi-temp-alarm"; ++ reg = <0xa00>; ++ interrupts = <0x1 0xa 0x0 IRQ_TYPE_EDGE_BOTH>; ++ #thermal-sensor-cells = <0>; ++ }; ++ ++ pmx65_gpios: gpio@8800 { ++ compatible = "qcom,pmx65-gpio", "qcom,spmi-gpio"; ++ reg = <0x8800>; ++ gpio-controller; ++ gpio-ranges = <&pmx65_gpios 0 0 16>; ++ #gpio-cells = <2>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/qcom/qcom-apq8026-asus-sparrow.dts b/arch/arm/boot/dts/qcom/qcom-apq8026-asus-sparrow.dts +index aa0e0e8d2a973..a39f5a161b03b 100644 +--- a/arch/arm/boot/dts/qcom/qcom-apq8026-asus-sparrow.dts ++++ b/arch/arm/boot/dts/qcom/qcom-apq8026-asus-sparrow.dts +@@ -6,7 +6,7 @@ + /dts-v1/; + + #include "qcom-msm8226.dtsi" +-#include "qcom-pm8226.dtsi" ++#include "pm8226.dtsi" + + /delete-node/ &adsp_region; + +diff --git a/arch/arm/boot/dts/qcom/qcom-apq8026-huawei-sturgeon.dts b/arch/arm/boot/dts/qcom/qcom-apq8026-huawei-sturgeon.dts +index de19640efe553..59b218042d32d 100644 +--- a/arch/arm/boot/dts/qcom/qcom-apq8026-huawei-sturgeon.dts ++++ b/arch/arm/boot/dts/qcom/qcom-apq8026-huawei-sturgeon.dts +@@ -6,7 +6,7 @@ + /dts-v1/; + + #include "qcom-msm8226.dtsi" +-#include "qcom-pm8226.dtsi" ++#include "pm8226.dtsi" + #include <dt-bindings/input/ti-drv260x.h> + + /delete-node/ &adsp_region; +diff --git a/arch/arm/boot/dts/qcom/qcom-apq8026-lg-lenok.dts b/arch/arm/boot/dts/qcom/qcom-apq8026-lg-lenok.dts +index b887e5361ec3a..feb78afef3a6e 100644 +--- a/arch/arm/boot/dts/qcom/qcom-apq8026-lg-lenok.dts ++++ b/arch/arm/boot/dts/qcom/qcom-apq8026-lg-lenok.dts +@@ -6,7 +6,7 @@ + /dts-v1/; + + #include "qcom-msm8226.dtsi" +-#include "qcom-pm8226.dtsi" ++#include "pm8226.dtsi" + + /delete-node/ &adsp_region; + +diff --git a/arch/arm/boot/dts/qcom/qcom-apq8026-samsung-matisse-wifi.dts b/arch/arm/boot/dts/qcom/qcom-apq8026-samsung-matisse-wifi.dts +index f516e0426bb9e..cffc069712b2f 100644 +--- a/arch/arm/boot/dts/qcom/qcom-apq8026-samsung-matisse-wifi.dts ++++ b/arch/arm/boot/dts/qcom/qcom-apq8026-samsung-matisse-wifi.dts +@@ -7,7 +7,7 @@ + + #include <dt-bindings/input/input.h> + #include "qcom-msm8226.dtsi" +-#include "qcom-pm8226.dtsi" ++#include "pm8226.dtsi" + + /delete-node/ &adsp_region; + /delete-node/ &smem_region; +diff --git a/arch/arm/boot/dts/qcom/qcom-apq8060-dragonboard.dts b/arch/arm/boot/dts/qcom/qcom-apq8060-dragonboard.dts +index 569cbf0d8df87..94351c9bf94b9 100644 +--- a/arch/arm/boot/dts/qcom/qcom-apq8060-dragonboard.dts ++++ b/arch/arm/boot/dts/qcom/qcom-apq8060-dragonboard.dts +@@ -71,7 +71,7 @@ + /* Trig on both edges - getting close or far away */ + interrupts-extended = <&pm8058_gpio 34 IRQ_TYPE_EDGE_BOTH>; + /* MPP05 analog input to the XOADC */ +- io-channels = <&xoadc 0x00 0x05>; ++ io-channels = <&pm8058_xoadc 0x00 0x05>; + io-channel-names = "aout"; + pinctrl-names = "default"; + pinctrl-0 = <&dragon_cm3605_gpios>, <&dragon_cm3605_mpps>; +@@ -944,7 +944,7 @@ + }; + }; + +-&xoadc { ++&pm8058_xoadc { + /* Reference voltage 2.2 V */ + xoadc-ref-supply = <&pm8058_l18>; + +diff --git a/arch/arm/boot/dts/qcom/qcom-apq8074-dragonboard.dts b/arch/arm/boot/dts/qcom/qcom-apq8074-dragonboard.dts +index 6d1b2439ae3ac..950fa652f9856 100644 +--- a/arch/arm/boot/dts/qcom/qcom-apq8074-dragonboard.dts ++++ b/arch/arm/boot/dts/qcom/qcom-apq8074-dragonboard.dts +@@ -4,8 +4,8 @@ + #include <dt-bindings/leds/common.h> + #include <dt-bindings/pinctrl/qcom,pmic-gpio.h> + #include "qcom-msm8974.dtsi" +-#include "qcom-pm8841.dtsi" +-#include "qcom-pm8941.dtsi" ++#include "pm8841.dtsi" ++#include "pm8941.dtsi" + + /delete-node/ &mpss_region; + +diff --git a/arch/arm/boot/dts/qcom/qcom-apq8084-ifc6540.dts b/arch/arm/boot/dts/qcom/qcom-apq8084-ifc6540.dts +index 116e59a3b76d0..1df24c922be9f 100644 +--- a/arch/arm/boot/dts/qcom/qcom-apq8084-ifc6540.dts ++++ b/arch/arm/boot/dts/qcom/qcom-apq8084-ifc6540.dts +@@ -1,6 +1,6 @@ + // SPDX-License-Identifier: GPL-2.0 + #include "qcom-apq8084.dtsi" +-#include "qcom-pma8084.dtsi" ++#include "pma8084.dtsi" + + / { + model = "Qualcomm APQ8084/IFC6540"; +diff --git a/arch/arm/boot/dts/qcom/qcom-apq8084-mtp.dts b/arch/arm/boot/dts/qcom/qcom-apq8084-mtp.dts +index c6b6680248a69..d4e6aee034afd 100644 +--- a/arch/arm/boot/dts/qcom/qcom-apq8084-mtp.dts ++++ b/arch/arm/boot/dts/qcom/qcom-apq8084-mtp.dts +@@ -1,6 +1,6 @@ + // SPDX-License-Identifier: GPL-2.0 + #include "qcom-apq8084.dtsi" +-#include "qcom-pma8084.dtsi" ++#include "pma8084.dtsi" + + / { + model = "Qualcomm APQ 8084-MTP"; +diff --git a/arch/arm/boot/dts/qcom/qcom-mdm9615-wp8548.dtsi b/arch/arm/boot/dts/qcom/qcom-mdm9615-wp8548.dtsi +index 92c8003dac252..dac3aa793f711 100644 +--- a/arch/arm/boot/dts/qcom/qcom-mdm9615-wp8548.dtsi ++++ b/arch/arm/boot/dts/qcom/qcom-mdm9615-wp8548.dtsi +@@ -76,7 +76,7 @@ + }; + }; + +-&pmicgpio { ++&pm8018_gpio { + usb_vbus_5v_pins: usb-vbus-5v-state { + pins = "gpio4"; + function = "normal"; +diff --git a/arch/arm/boot/dts/qcom/qcom-mdm9615.dtsi b/arch/arm/boot/dts/qcom/qcom-mdm9615.dtsi +index 63e21aa236429..c0a60bae703b1 100644 +--- a/arch/arm/boot/dts/qcom/qcom-mdm9615.dtsi ++++ b/arch/arm/boot/dts/qcom/qcom-mdm9615.dtsi +@@ -261,7 +261,7 @@ + reg = <0x500000 0x1000>; + qcom,controller-type = "pmic-arbiter"; + +- pmicintc: pmic { ++ pm8018: pmic { + compatible = "qcom,pm8018", "qcom,pm8921"; + interrupts = <GIC_PPI 226 IRQ_TYPE_LEVEL_HIGH>; + #interrupt-cells = <2>; +@@ -272,38 +272,38 @@ + pwrkey@1c { + compatible = "qcom,pm8018-pwrkey", "qcom,pm8921-pwrkey"; + reg = <0x1c>; +- interrupt-parent = <&pmicintc>; ++ interrupt-parent = <&pm8018>; + interrupts = <50 IRQ_TYPE_EDGE_RISING>, + <51 IRQ_TYPE_EDGE_RISING>; + debounce = <15625>; + pull-up; + }; + +- pmicmpp: mpps@50 { ++ pm8018_mpps: mpps@50 { + compatible = "qcom,pm8018-mpp", "qcom,ssbi-mpp"; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x50>; + gpio-controller; + #gpio-cells = <2>; +- gpio-ranges = <&pmicmpp 0 0 6>; ++ gpio-ranges = <&pm8018_mpps 0 0 6>; + }; + + rtc@11d { + compatible = "qcom,pm8018-rtc", "qcom,pm8921-rtc"; +- interrupt-parent = <&pmicintc>; ++ interrupt-parent = <&pm8018>; + interrupts = <39 IRQ_TYPE_EDGE_RISING>; + reg = <0x11d>; + allow-set-time; + }; + +- pmicgpio: gpio@150 { ++ pm8018_gpio: gpio@150 { + compatible = "qcom,pm8018-gpio", "qcom,ssbi-gpio"; + reg = <0x150>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-controller; +- gpio-ranges = <&pmicgpio 0 0 6>; ++ gpio-ranges = <&pm8018_gpio 0 0 6>; + #gpio-cells = <2>; + }; + }; +diff --git a/arch/arm/boot/dts/qcom/qcom-msm8660.dtsi b/arch/arm/boot/dts/qcom/qcom-msm8660.dtsi +index 78023ed2fdf71..9217ced108c42 100644 +--- a/arch/arm/boot/dts/qcom/qcom-msm8660.dtsi ++++ b/arch/arm/boot/dts/qcom/qcom-msm8660.dtsi +@@ -80,13 +80,13 @@ + */ + iio-hwmon { + compatible = "iio-hwmon"; +- io-channels = <&xoadc 0x00 0x01>, /* Battery */ +- <&xoadc 0x00 0x02>, /* DC in (charger) */ +- <&xoadc 0x00 0x04>, /* VPH the main system voltage */ +- <&xoadc 0x00 0x0b>, /* Die temperature */ +- <&xoadc 0x00 0x0c>, /* Reference voltage 1.25V */ +- <&xoadc 0x00 0x0d>, /* Reference voltage 0.625V */ +- <&xoadc 0x00 0x0e>; /* Reference voltage 0.325V */ ++ io-channels = <&pm8058_xoadc 0x00 0x01>, /* Battery */ ++ <&pm8058_xoadc 0x00 0x02>, /* DC in (charger) */ ++ <&pm8058_xoadc 0x00 0x04>, /* VPH the main system voltage */ ++ <&pm8058_xoadc 0x00 0x0b>, /* Die temperature */ ++ <&pm8058_xoadc 0x00 0x0c>, /* Reference voltage 1.25V */ ++ <&pm8058_xoadc 0x00 0x0d>, /* Reference voltage 0.625V */ ++ <&pm8058_xoadc 0x00 0x0e>; /* Reference voltage 0.325V */ + }; + + soc: soc { +@@ -390,7 +390,7 @@ + row-hold = <91500>; + }; + +- xoadc: xoadc@197 { ++ pm8058_xoadc: xoadc@197 { + compatible = "qcom,pm8058-adc"; + reg = <0x197>; + interrupts-extended = <&pm8058 76 IRQ_TYPE_EDGE_RISING>; +diff --git a/arch/arm/boot/dts/qcom/qcom-msm8974-lge-nexus5-hammerhead.dts b/arch/arm/boot/dts/qcom/qcom-msm8974-lge-nexus5-hammerhead.dts +index 60bdfddeae69e..da99f770d4f57 100644 +--- a/arch/arm/boot/dts/qcom/qcom-msm8974-lge-nexus5-hammerhead.dts ++++ b/arch/arm/boot/dts/qcom/qcom-msm8974-lge-nexus5-hammerhead.dts +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0 + #include "qcom-msm8974.dtsi" +-#include "qcom-pm8841.dtsi" +-#include "qcom-pm8941.dtsi" ++#include "pm8841.dtsi" ++#include "pm8941.dtsi" + #include <dt-bindings/input/input.h> + #include <dt-bindings/leds/common.h> + #include <dt-bindings/pinctrl/qcom,pmic-gpio.h> +diff --git a/arch/arm/boot/dts/qcom/qcom-msm8974-sony-xperia-rhine.dtsi b/arch/arm/boot/dts/qcom/qcom-msm8974-sony-xperia-rhine.dtsi +index 68a2f9094e536..23ae474698aa7 100644 +--- a/arch/arm/boot/dts/qcom/qcom-msm8974-sony-xperia-rhine.dtsi ++++ b/arch/arm/boot/dts/qcom/qcom-msm8974-sony-xperia-rhine.dtsi +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0 + #include "qcom-msm8974.dtsi" +-#include "qcom-pm8841.dtsi" +-#include "qcom-pm8941.dtsi" ++#include "pm8841.dtsi" ++#include "pm8941.dtsi" + #include <dt-bindings/input/input.h> + #include <dt-bindings/leds/common.h> + #include <dt-bindings/pinctrl/qcom,pmic-gpio.h> +diff --git a/arch/arm/boot/dts/qcom/qcom-msm8974pro-fairphone-fp2.dts b/arch/arm/boot/dts/qcom/qcom-msm8974pro-fairphone-fp2.dts +index 42d253b75dad0..6c4153689b39e 100644 +--- a/arch/arm/boot/dts/qcom/qcom-msm8974pro-fairphone-fp2.dts ++++ b/arch/arm/boot/dts/qcom/qcom-msm8974pro-fairphone-fp2.dts +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0 + #include "qcom-msm8974pro.dtsi" +-#include "qcom-pm8841.dtsi" +-#include "qcom-pm8941.dtsi" ++#include "pm8841.dtsi" ++#include "pm8941.dtsi" + #include <dt-bindings/input/input.h> + #include <dt-bindings/leds/common.h> + #include <dt-bindings/pinctrl/qcom,pmic-gpio.h> +diff --git a/arch/arm/boot/dts/qcom/qcom-msm8974pro-oneplus-bacon.dts b/arch/arm/boot/dts/qcom/qcom-msm8974pro-oneplus-bacon.dts +index 8230d0e1d95d1..c0ca264d8140d 100644 +--- a/arch/arm/boot/dts/qcom/qcom-msm8974pro-oneplus-bacon.dts ++++ b/arch/arm/boot/dts/qcom/qcom-msm8974pro-oneplus-bacon.dts +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0 + #include "qcom-msm8974pro.dtsi" +-#include "qcom-pm8841.dtsi" +-#include "qcom-pm8941.dtsi" ++#include "pm8841.dtsi" ++#include "pm8941.dtsi" + #include <dt-bindings/input/input.h> + #include <dt-bindings/pinctrl/qcom,pmic-gpio.h> + +diff --git a/arch/arm/boot/dts/qcom/qcom-msm8974pro-samsung-klte.dts b/arch/arm/boot/dts/qcom/qcom-msm8974pro-samsung-klte.dts +index 3e2c86591ee2f..325feb89b343a 100644 +--- a/arch/arm/boot/dts/qcom/qcom-msm8974pro-samsung-klte.dts ++++ b/arch/arm/boot/dts/qcom/qcom-msm8974pro-samsung-klte.dts +@@ -1,6 +1,6 @@ + // SPDX-License-Identifier: GPL-2.0 + #include "qcom-msm8974pro.dtsi" +-#include "qcom-pma8084.dtsi" ++#include "pma8084.dtsi" + #include <dt-bindings/input/input.h> + #include <dt-bindings/pinctrl/qcom,pmic-gpio.h> + #include <dt-bindings/leds/common.h> +diff --git a/arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-castor.dts b/arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-castor.dts +index 11468d1409f72..0798cce3dbea0 100644 +--- a/arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-castor.dts ++++ b/arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-castor.dts +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0 + #include "qcom-msm8974pro.dtsi" +-#include "qcom-pm8841.dtsi" +-#include "qcom-pm8941.dtsi" ++#include "pm8841.dtsi" ++#include "pm8941.dtsi" + #include <dt-bindings/input/input.h> + #include <dt-bindings/leds/common.h> + #include <dt-bindings/pinctrl/qcom,pmic-gpio.h> +diff --git a/arch/arm/boot/dts/qcom/qcom-pm8226.dtsi b/arch/arm/boot/dts/qcom/qcom-pm8226.dtsi +deleted file mode 100644 +index 2413778f37150..0000000000000 +--- a/arch/arm/boot/dts/qcom/qcom-pm8226.dtsi ++++ /dev/null +@@ -1,180 +0,0 @@ +-// SPDX-License-Identifier: BSD-3-Clause +-#include <dt-bindings/iio/qcom,spmi-vadc.h> +-#include <dt-bindings/input/linux-event-codes.h> +-#include <dt-bindings/interrupt-controller/irq.h> +-#include <dt-bindings/spmi/spmi.h> +- +-/ { +- thermal-zones { +- pm8226-thermal { +- polling-delay-passive = <100>; +- polling-delay = <0>; +- thermal-sensors = <&pm8226_temp>; +- +- trips { +- trip0 { +- temperature = <105000>; +- hysteresis = <2000>; +- type = "passive"; +- }; +- +- trip1 { +- temperature = <125000>; +- hysteresis = <2000>; +- type = "hot"; +- }; +- +- crit { +- temperature = <145000>; +- hysteresis = <2000>; +- type = "critical"; +- }; +- }; +- }; +- }; +-}; +- +-&spmi_bus { +- pm8226_0: pm8226@0 { +- compatible = "qcom,pm8226", "qcom,spmi-pmic"; +- reg = <0x0 SPMI_USID>; +- #address-cells = <1>; +- #size-cells = <0>; +- +- pon@800 { +- compatible = "qcom,pm8916-pon"; +- reg = <0x800>; +- +- pwrkey { +- compatible = "qcom,pm8941-pwrkey"; +- interrupts = <0x0 0x8 0 IRQ_TYPE_EDGE_BOTH>; +- debounce = <15625>; +- bias-pull-up; +- linux,code = <KEY_POWER>; +- }; +- +- pm8226_resin: resin { +- compatible = "qcom,pm8941-resin"; +- interrupts = <0x0 0x8 1 IRQ_TYPE_EDGE_BOTH>; +- debounce = <15625>; +- bias-pull-up; +- status = "disabled"; +- }; +- }; +- +- smbb: charger@1000 { +- compatible = "qcom,pm8226-charger"; +- reg = <0x1000>; +- interrupts = <0x0 0x10 7 IRQ_TYPE_EDGE_BOTH>, +- <0x0 0x10 5 IRQ_TYPE_EDGE_BOTH>, +- <0x0 0x10 4 IRQ_TYPE_EDGE_BOTH>, +- <0x0 0x12 1 IRQ_TYPE_EDGE_BOTH>, +- <0x0 0x12 0 IRQ_TYPE_EDGE_BOTH>, +- <0x0 0x13 2 IRQ_TYPE_EDGE_BOTH>, +- <0x0 0x13 1 IRQ_TYPE_EDGE_BOTH>, +- <0x0 0x14 1 IRQ_TYPE_EDGE_BOTH>; +- interrupt-names = "chg-done", +- "chg-fast", +- "chg-trkl", +- "bat-temp-ok", +- "bat-present", +- "chg-gone", +- "usb-valid", +- "dc-valid"; +- +- chg_otg: otg-vbus { }; +- }; +- +- pm8226_temp: temp-alarm@2400 { +- compatible = "qcom,spmi-temp-alarm"; +- reg = <0x2400>; +- interrupts = <0 0x24 0 IRQ_TYPE_EDGE_RISING>; +- io-channels = <&pm8226_vadc VADC_DIE_TEMP>; +- io-channel-names = "thermal"; +- #thermal-sensor-cells = <0>; +- }; +- +- pm8226_vadc: adc@3100 { +- compatible = "qcom,spmi-vadc"; +- reg = <0x3100>; +- interrupts = <0x0 0x31 0x0 IRQ_TYPE_EDGE_RISING>; +- #address-cells = <1>; +- #size-cells = <0>; +- #io-channel-cells = <1>; +- +- channel@7 { +- reg = <VADC_VSYS>; +- qcom,pre-scaling = <1 3>; +- label = "vph_pwr"; +- }; +- channel@8 { +- reg = <VADC_DIE_TEMP>; +- label = "die_temp"; +- }; +- channel@9 { +- reg = <VADC_REF_625MV>; +- label = "ref_625mv"; +- }; +- channel@a { +- reg = <VADC_REF_1250MV>; +- label = "ref_1250mv"; +- }; +- channel@e { +- reg = <VADC_GND_REF>; +- }; +- channel@f { +- reg = <VADC_VDD_VADC>; +- }; +- }; +- +- pm8226_iadc: adc@3600 { +- compatible = "qcom,pm8226-iadc", "qcom,spmi-iadc"; +- reg = <0x3600>; +- interrupts = <0x0 0x36 0x0 IRQ_TYPE_EDGE_RISING>; +- }; +- +- rtc@6000 { +- compatible = "qcom,pm8941-rtc"; +- reg = <0x6000>, <0x6100>; +- reg-names = "rtc", "alarm"; +- interrupts = <0x0 0x61 0x1 IRQ_TYPE_EDGE_RISING>; +- }; +- +- pm8226_mpps: mpps@a000 { +- compatible = "qcom,pm8226-mpp", "qcom,spmi-mpp"; +- reg = <0xa000>; +- gpio-controller; +- #gpio-cells = <2>; +- gpio-ranges = <&pm8226_mpps 0 0 8>; +- interrupt-controller; +- #interrupt-cells = <2>; +- }; +- +- pm8226_gpios: gpio@c000 { +- compatible = "qcom,pm8226-gpio", "qcom,spmi-gpio"; +- reg = <0xc000>; +- gpio-controller; +- #gpio-cells = <2>; +- gpio-ranges = <&pm8226_gpios 0 0 8>; +- interrupt-controller; +- #interrupt-cells = <2>; +- }; +- }; +- +- pm8226_1: pm8226@1 { +- compatible = "qcom,pm8226", "qcom,spmi-pmic"; +- reg = <0x1 SPMI_USID>; +- #address-cells = <1>; +- #size-cells = <0>; +- +- pm8226_spmi_regulators: regulators { +- compatible = "qcom,pm8226-regulators"; +- }; +- +- pm8226_vib: vibrator@c000 { +- compatible = "qcom,pm8916-vib"; +- reg = <0xc000>; +- status = "disabled"; +- }; +- }; +-}; +diff --git a/arch/arm/boot/dts/qcom/qcom-pm8841.dtsi b/arch/arm/boot/dts/qcom/qcom-pm8841.dtsi +deleted file mode 100644 +index 3bf2ce5c86a64..0000000000000 +--- a/arch/arm/boot/dts/qcom/qcom-pm8841.dtsi ++++ /dev/null +@@ -1,68 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0 +-#include <dt-bindings/interrupt-controller/irq.h> +-#include <dt-bindings/spmi/spmi.h> +- +- +-/ { +- thermal-zones { +- pm8841-thermal { +- polling-delay-passive = <100>; +- polling-delay = <0>; +- thermal-sensors = <&pm8841_temp>; +- +- trips { +- trip0 { +- temperature = <105000>; +- hysteresis = <2000>; +- type = "passive"; +- }; +- +- trip1 { +- temperature = <125000>; +- hysteresis = <2000>; +- type = "hot"; +- }; +- +- crit { +- temperature = <140000>; +- hysteresis = <2000>; +- type = "critical"; +- }; +- }; +- }; +- }; +-}; +- +-&spmi_bus { +- +- pm8841_0: pm8841@4 { +- compatible = "qcom,pm8841", "qcom,spmi-pmic"; +- reg = <0x4 SPMI_USID>; +- #address-cells = <1>; +- #size-cells = <0>; +- +- pm8841_mpps: mpps@a000 { +- compatible = "qcom,pm8841-mpp", "qcom,spmi-mpp"; +- reg = <0xa000>; +- gpio-controller; +- #gpio-cells = <2>; +- gpio-ranges = <&pm8841_mpps 0 0 4>; +- interrupt-controller; +- #interrupt-cells = <2>; +- }; +- +- pm8841_temp: temp-alarm@2400 { +- compatible = "qcom,spmi-temp-alarm"; +- reg = <0x2400>; +- interrupts = <4 0x24 0 IRQ_TYPE_EDGE_RISING>; +- #thermal-sensor-cells = <0>; +- }; +- }; +- +- pm8841_1: pm8841@5 { +- compatible = "qcom,pm8841", "qcom,spmi-pmic"; +- reg = <0x5 SPMI_USID>; +- #address-cells = <1>; +- #size-cells = <0>; +- }; +-}; +diff --git a/arch/arm/boot/dts/qcom/qcom-pm8941.dtsi b/arch/arm/boot/dts/qcom/qcom-pm8941.dtsi +deleted file mode 100644 +index ed0ba591c7558..0000000000000 +--- a/arch/arm/boot/dts/qcom/qcom-pm8941.dtsi ++++ /dev/null +@@ -1,254 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0 +-#include <dt-bindings/iio/qcom,spmi-vadc.h> +-#include <dt-bindings/interrupt-controller/irq.h> +-#include <dt-bindings/spmi/spmi.h> +- +- +-/ { +- thermal-zones { +- pm8941-thermal { +- polling-delay-passive = <100>; +- polling-delay = <0>; +- thermal-sensors = <&pm8941_temp>; +- +- trips { +- trip0 { +- temperature = <105000>; +- hysteresis = <2000>; +- type = "passive"; +- }; +- +- trip1 { +- temperature = <125000>; +- hysteresis = <2000>; +- type = "hot"; +- }; +- +- crit { +- temperature = <145000>; +- hysteresis = <2000>; +- type = "critical"; +- }; +- }; +- }; +- }; +-}; +- +-&spmi_bus { +- +- pm8941_0: pm8941@0 { +- compatible = "qcom,pm8941", "qcom,spmi-pmic"; +- reg = <0x0 SPMI_USID>; +- #address-cells = <1>; +- #size-cells = <0>; +- +- rtc@6000 { +- compatible = "qcom,pm8941-rtc"; +- reg = <0x6000>, +- <0x6100>; +- reg-names = "rtc", "alarm"; +- interrupts = <0x0 0x61 0x1 IRQ_TYPE_EDGE_RISING>; +- }; +- +- pon@800 { +- compatible = "qcom,pm8941-pon"; +- reg = <0x800>; +- +- pwrkey { +- compatible = "qcom,pm8941-pwrkey"; +- interrupts = <0x0 0x8 0 IRQ_TYPE_EDGE_BOTH>; +- debounce = <15625>; +- bias-pull-up; +- }; +- +- pm8941_resin: resin { +- compatible = "qcom,pm8941-resin"; +- interrupts = <0x0 0x8 1 IRQ_TYPE_EDGE_BOTH>; +- debounce = <15625>; +- bias-pull-up; +- status = "disabled"; +- }; +- }; +- +- usb_id: usb-detect@900 { +- compatible = "qcom,pm8941-misc"; +- reg = <0x900>; +- interrupts = <0x0 0x9 0 IRQ_TYPE_EDGE_BOTH>; +- interrupt-names = "usb_id"; +- }; +- +- smbb: charger@1000 { +- compatible = "qcom,pm8941-charger"; +- reg = <0x1000>; +- interrupts = <0x0 0x10 7 IRQ_TYPE_EDGE_BOTH>, +- <0x0 0x10 5 IRQ_TYPE_EDGE_BOTH>, +- <0x0 0x10 4 IRQ_TYPE_EDGE_BOTH>, +- <0x0 0x12 1 IRQ_TYPE_EDGE_BOTH>, +- <0x0 0x12 0 IRQ_TYPE_EDGE_BOTH>, +- <0x0 0x13 2 IRQ_TYPE_EDGE_BOTH>, +- <0x0 0x13 1 IRQ_TYPE_EDGE_BOTH>, +- <0x0 0x14 1 IRQ_TYPE_EDGE_BOTH>; +- interrupt-names = "chg-done", +- "chg-fast", +- "chg-trkl", +- "bat-temp-ok", +- "bat-present", +- "chg-gone", +- "usb-valid", +- "dc-valid"; +- +- usb-otg-in-supply = <&pm8941_5vs1>; +- +- chg_otg: otg-vbus { }; +- }; +- +- pm8941_gpios: gpio@c000 { +- compatible = "qcom,pm8941-gpio", "qcom,spmi-gpio"; +- reg = <0xc000>; +- gpio-controller; +- gpio-ranges = <&pm8941_gpios 0 0 36>; +- #gpio-cells = <2>; +- interrupt-controller; +- #interrupt-cells = <2>; +- +- boost_bypass_n_pin: boost-bypass-state { +- pins = "gpio21"; +- function = "normal"; +- }; +- }; +- +- pm8941_mpps: mpps@a000 { +- compatible = "qcom,pm8941-mpp", "qcom,spmi-mpp"; +- reg = <0xa000>; +- gpio-controller; +- #gpio-cells = <2>; +- gpio-ranges = <&pm8941_mpps 0 0 8>; +- interrupt-controller; +- #interrupt-cells = <2>; +- }; +- +- pm8941_temp: temp-alarm@2400 { +- compatible = "qcom,spmi-temp-alarm"; +- reg = <0x2400>; +- interrupts = <0 0x24 0 IRQ_TYPE_EDGE_RISING>; +- io-channels = <&pm8941_vadc VADC_DIE_TEMP>; +- io-channel-names = "thermal"; +- #thermal-sensor-cells = <0>; +- }; +- +- pm8941_vadc: adc@3100 { +- compatible = "qcom,spmi-vadc"; +- reg = <0x3100>; +- interrupts = <0x0 0x31 0x0 IRQ_TYPE_EDGE_RISING>; +- #address-cells = <1>; +- #size-cells = <0>; +- #io-channel-cells = <1>; +- +- +- channel@6 { +- reg = <VADC_VBAT_SNS>; +- }; +- +- channel@8 { +- reg = <VADC_DIE_TEMP>; +- }; +- +- channel@9 { +- reg = <VADC_REF_625MV>; +- }; +- +- channel@a { +- reg = <VADC_REF_1250MV>; +- }; +- +- channel@e { +- reg = <VADC_GND_REF>; +- }; +- +- channel@f { +- reg = <VADC_VDD_VADC>; +- }; +- +- channel@30 { +- reg = <VADC_LR_MUX1_BAT_THERM>; +- }; +- }; +- +- pm8941_iadc: adc@3600 { +- compatible = "qcom,pm8941-iadc", "qcom,spmi-iadc"; +- reg = <0x3600>; +- interrupts = <0x0 0x36 0x0 IRQ_TYPE_EDGE_RISING>; +- qcom,external-resistor-micro-ohms = <10000>; +- }; +- +- pm8941_coincell: charger@2800 { +- compatible = "qcom,pm8941-coincell"; +- reg = <0x2800>; +- status = "disabled"; +- }; +- }; +- +- pm8941_1: pm8941@1 { +- compatible = "qcom,pm8941", "qcom,spmi-pmic"; +- reg = <0x1 SPMI_USID>; +- #address-cells = <1>; +- #size-cells = <0>; +- +- pm8941_lpg: pwm { +- compatible = "qcom,pm8941-lpg"; +- +- #address-cells = <1>; +- #size-cells = <0>; +- #pwm-cells = <2>; +- +- status = "disabled"; +- }; +- +- pm8941_vib: vibrator@c000 { +- compatible = "qcom,pm8916-vib"; +- reg = <0xc000>; +- status = "disabled"; +- }; +- +- pm8941_wled: wled@d800 { +- compatible = "qcom,pm8941-wled"; +- reg = <0xd800>; +- label = "backlight"; +- +- status = "disabled"; +- }; +- +- regulators { +- compatible = "qcom,pm8941-regulators"; +- interrupts = <0x1 0x83 0x2 0>, <0x1 0x84 0x2 0>; +- interrupt-names = "ocp-5vs1", "ocp-5vs2"; +- vin_5vs-supply = <&pm8941_5v>; +- +- pm8941_5v: s4 { +- regulator-min-microvolt = <5000000>; +- regulator-max-microvolt = <5000000>; +- regulator-enable-ramp-delay = <500>; +- }; +- +- pm8941_5vs1: 5vs1 { +- regulator-enable-ramp-delay = <1000>; +- regulator-pull-down; +- regulator-over-current-protection; +- qcom,ocp-max-retries = <10>; +- qcom,ocp-retry-delay = <30>; +- qcom,vs-soft-start-strength = <0>; +- regulator-initial-mode = <1>; +- }; +- +- pm8941_5vs2: 5vs2 { +- regulator-enable-ramp-delay = <1000>; +- regulator-pull-down; +- regulator-over-current-protection; +- qcom,ocp-max-retries = <10>; +- qcom,ocp-retry-delay = <30>; +- qcom,vs-soft-start-strength = <0>; +- regulator-initial-mode = <1>; +- }; +- }; +- }; +-}; +diff --git a/arch/arm/boot/dts/qcom/qcom-pma8084.dtsi b/arch/arm/boot/dts/qcom/qcom-pma8084.dtsi +deleted file mode 100644 +index 2985f4805b93e..0000000000000 +--- a/arch/arm/boot/dts/qcom/qcom-pma8084.dtsi ++++ /dev/null +@@ -1,99 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0 +-#include <dt-bindings/iio/qcom,spmi-vadc.h> +-#include <dt-bindings/interrupt-controller/irq.h> +-#include <dt-bindings/spmi/spmi.h> +- +-&spmi_bus { +- +- pma8084_0: pma8084@0 { +- compatible = "qcom,pma8084", "qcom,spmi-pmic"; +- reg = <0x0 SPMI_USID>; +- #address-cells = <1>; +- #size-cells = <0>; +- +- rtc@6000 { +- compatible = "qcom,pm8941-rtc"; +- reg = <0x6000>, +- <0x6100>; +- reg-names = "rtc", "alarm"; +- interrupts = <0x0 0x61 0x1 IRQ_TYPE_EDGE_RISING>; +- }; +- +- pwrkey@800 { +- compatible = "qcom,pm8941-pwrkey"; +- reg = <0x800>; +- interrupts = <0x0 0x8 0 IRQ_TYPE_EDGE_BOTH>; +- debounce = <15625>; +- bias-pull-up; +- }; +- +- pma8084_gpios: gpio@c000 { +- compatible = "qcom,pma8084-gpio", "qcom,spmi-gpio"; +- reg = <0xc000>; +- gpio-controller; +- gpio-ranges = <&pma8084_gpios 0 0 22>; +- #gpio-cells = <2>; +- interrupt-controller; +- #interrupt-cells = <2>; +- }; +- +- pma8084_mpps: mpps@a000 { +- compatible = "qcom,pma8084-mpp", "qcom,spmi-mpp"; +- reg = <0xa000>; +- gpio-controller; +- #gpio-cells = <2>; +- gpio-ranges = <&pma8084_mpps 0 0 8>; +- interrupt-controller; +- #interrupt-cells = <2>; +- }; +- +- pma8084_temp: temp-alarm@2400 { +- compatible = "qcom,spmi-temp-alarm"; +- reg = <0x2400>; +- interrupts = <0 0x24 0 IRQ_TYPE_EDGE_RISING>; +- #thermal-sensor-cells = <0>; +- io-channels = <&pma8084_vadc VADC_DIE_TEMP>; +- io-channel-names = "thermal"; +- }; +- +- pma8084_vadc: adc@3100 { +- compatible = "qcom,spmi-vadc"; +- reg = <0x3100>; +- interrupts = <0x0 0x31 0x0 IRQ_TYPE_EDGE_RISING>; +- #address-cells = <1>; +- #size-cells = <0>; +- #io-channel-cells = <1>; +- +- channel@8 { +- reg = <VADC_DIE_TEMP>; +- }; +- +- channel@9 { +- reg = <VADC_REF_625MV>; +- }; +- +- channel@a { +- reg = <VADC_REF_1250MV>; +- }; +- +- channel@c { +- reg = <VADC_SPARE1>; +- }; +- +- channel@e { +- reg = <VADC_GND_REF>; +- }; +- +- channel@f { +- reg = <VADC_VDD_VADC>; +- }; +- }; +- }; +- +- pma8084_1: pma8084@1 { +- compatible = "qcom,pma8084", "qcom,spmi-pmic"; +- reg = <0x1 SPMI_USID>; +- #address-cells = <1>; +- #size-cells = <0>; +- }; +-}; +diff --git a/arch/arm/boot/dts/qcom/qcom-pmx55.dtsi b/arch/arm/boot/dts/qcom/qcom-pmx55.dtsi +deleted file mode 100644 +index da0851173c699..0000000000000 +--- a/arch/arm/boot/dts/qcom/qcom-pmx55.dtsi ++++ /dev/null +@@ -1,85 +0,0 @@ +-// SPDX-License-Identifier: BSD-3-Clause +- +-/* +- * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. +- * Copyright (c) 2020, Linaro Limited +- */ +- +-#include <dt-bindings/iio/qcom,spmi-vadc.h> +-#include <dt-bindings/interrupt-controller/irq.h> +-#include <dt-bindings/spmi/spmi.h> +- +-&spmi_bus { +- pmic@8 { +- compatible = "qcom,pmx55", "qcom,spmi-pmic"; +- reg = <0x8 SPMI_USID>; +- #address-cells = <1>; +- #size-cells = <0>; +- +- pon@800 { +- compatible = "qcom,pm8916-pon"; +- reg = <0x0800>; +- +- status = "disabled"; +- }; +- +- pmx55_temp: temp-alarm@2400 { +- compatible = "qcom,spmi-temp-alarm"; +- reg = <0x2400>; +- interrupts = <0x8 0x24 0x0 IRQ_TYPE_EDGE_BOTH>; +- io-channels = <&pmx55_adc ADC5_DIE_TEMP>; +- io-channel-names = "thermal"; +- #thermal-sensor-cells = <0>; +- }; +- +- pmx55_adc: adc@3100 { +- compatible = "qcom,spmi-adc5"; +- reg = <0x3100>; +- #address-cells = <1>; +- #size-cells = <0>; +- #io-channel-cells = <1>; +- interrupts = <0x8 0x31 0x0 IRQ_TYPE_EDGE_RISING>; +- +- channel@0 { +- reg = <ADC5_REF_GND>; +- qcom,pre-scaling = <1 1>; +- label = "ref_gnd"; +- }; +- +- channel@1 { +- reg = <ADC5_1P25VREF>; +- qcom,pre-scaling = <1 1>; +- label = "vref_1p25"; +- }; +- +- channel@6 { +- reg = <ADC5_DIE_TEMP>; +- qcom,pre-scaling = <1 1>; +- label = "die_temp"; +- }; +- +- channel@9 { +- reg = <ADC5_CHG_TEMP>; +- qcom,pre-scaling = <1 1>; +- label = "chg_temp"; +- }; +- }; +- +- pmx55_gpios: gpio@c000 { +- compatible = "qcom,pmx55-gpio", "qcom,spmi-gpio"; +- reg = <0xc000>; +- gpio-controller; +- gpio-ranges = <&pmx55_gpios 0 0 11>; +- #gpio-cells = <2>; +- interrupt-controller; +- #interrupt-cells = <2>; +- }; +- }; +- +- pmic@9 { +- compatible = "qcom,pmx55", "qcom,spmi-pmic"; +- reg = <0x9 SPMI_USID>; +- #address-cells = <1>; +- #size-cells = <0>; +- }; +-}; +diff --git a/arch/arm/boot/dts/qcom/qcom-pmx65.dtsi b/arch/arm/boot/dts/qcom/qcom-pmx65.dtsi +deleted file mode 100644 +index 1c7fdf59c1f56..0000000000000 +--- a/arch/arm/boot/dts/qcom/qcom-pmx65.dtsi ++++ /dev/null +@@ -1,33 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0-only +-/* +- * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. +- */ +- +-#include <dt-bindings/interrupt-controller/irq.h> +-#include <dt-bindings/spmi/spmi.h> +- +-&spmi_bus { +- pmic@1 { +- compatible = "qcom,pmx65", "qcom,spmi-pmic"; +- reg = <1 SPMI_USID>; +- #address-cells = <1>; +- #size-cells = <0>; +- +- pmx65_temp: temp-alarm@a00 { +- compatible = "qcom,spmi-temp-alarm"; +- reg = <0xa00>; +- interrupts = <0x1 0xa 0x0 IRQ_TYPE_EDGE_BOTH>; +- #thermal-sensor-cells = <0>; +- }; +- +- pmx65_gpios: gpio@8800 { +- compatible = "qcom,pmx65-gpio", "qcom,spmi-gpio"; +- reg = <0x8800>; +- gpio-controller; +- gpio-ranges = <&pmx65_gpios 0 0 16>; +- #gpio-cells = <2>; +- interrupt-controller; +- #interrupt-cells = <2>; +- }; +- }; +-}; +diff --git a/arch/arm/boot/dts/qcom/qcom-sdx55-mtp.dts b/arch/arm/boot/dts/qcom/qcom-sdx55-mtp.dts +index 7e97ad5803d87..2470693619090 100644 +--- a/arch/arm/boot/dts/qcom/qcom-sdx55-mtp.dts ++++ b/arch/arm/boot/dts/qcom/qcom-sdx55-mtp.dts +@@ -9,7 +9,7 @@ + #include "qcom-sdx55.dtsi" + #include <dt-bindings/regulator/qcom,rpmh-regulator.h> + #include <arm64/qcom/pm8150b.dtsi> +-#include "qcom-pmx55.dtsi" ++#include "pmx55.dtsi" + + / { + model = "Qualcomm Technologies, Inc. SDX55 MTP"; +diff --git a/arch/arm/boot/dts/qcom/qcom-sdx55-t55.dts b/arch/arm/boot/dts/qcom/qcom-sdx55-t55.dts +index 51058b0652797..082f7ed1a01fb 100644 +--- a/arch/arm/boot/dts/qcom/qcom-sdx55-t55.dts ++++ b/arch/arm/boot/dts/qcom/qcom-sdx55-t55.dts +@@ -8,7 +8,7 @@ + #include <dt-bindings/gpio/gpio.h> + #include <dt-bindings/regulator/qcom,rpmh-regulator.h> + #include "qcom-sdx55.dtsi" +-#include "qcom-pmx55.dtsi" ++#include "pmx55.dtsi" + + / { + model = "Thundercomm T55 Development Kit"; +diff --git a/arch/arm/boot/dts/qcom/qcom-sdx55-telit-fn980-tlb.dts b/arch/arm/boot/dts/qcom/qcom-sdx55-telit-fn980-tlb.dts +index 8fadc6e70692a..e336a15b45c4c 100644 +--- a/arch/arm/boot/dts/qcom/qcom-sdx55-telit-fn980-tlb.dts ++++ b/arch/arm/boot/dts/qcom/qcom-sdx55-telit-fn980-tlb.dts +@@ -8,7 +8,7 @@ + #include <dt-bindings/gpio/gpio.h> + #include <dt-bindings/regulator/qcom,rpmh-regulator.h> + #include "qcom-sdx55.dtsi" +-#include "qcom-pmx55.dtsi" ++#include "pmx55.dtsi" + + / { + model = "Telit FN980 TLB"; +diff --git a/arch/arm/boot/dts/qcom/qcom-sdx65-mtp.dts b/arch/arm/boot/dts/qcom/qcom-sdx65-mtp.dts +index 9649c859a2c36..07c10c84eefa1 100644 +--- a/arch/arm/boot/dts/qcom/qcom-sdx65-mtp.dts ++++ b/arch/arm/boot/dts/qcom/qcom-sdx65-mtp.dts +@@ -12,7 +12,7 @@ + #include <dt-bindings/regulator/qcom,rpmh-regulator.h> + #include <arm64/qcom/pmk8350.dtsi> + #include <arm64/qcom/pm7250b.dtsi> +-#include "qcom-pmx65.dtsi" ++#include "pmx65.dtsi" + + / { + model = "Qualcomm Technologies, Inc. SDX65 MTP"; +diff --git a/arch/arm/boot/dts/rockchip/rk3036.dtsi b/arch/arm/boot/dts/rockchip/rk3036.dtsi +index 78686fc72ce69..c420c7c642cb0 100644 +--- a/arch/arm/boot/dts/rockchip/rk3036.dtsi ++++ b/arch/arm/boot/dts/rockchip/rk3036.dtsi +@@ -402,12 +402,20 @@ + pinctrl-0 = <&hdmi_ctl>; + status = "disabled"; + +- hdmi_in: port { ++ ports { + #address-cells = <1>; + #size-cells = <0>; +- hdmi_in_vop: endpoint@0 { ++ ++ hdmi_in: port@0 { + reg = <0>; +- remote-endpoint = <&vop_out_hdmi>; ++ ++ hdmi_in_vop: endpoint { ++ remote-endpoint = <&vop_out_hdmi>; ++ }; ++ }; ++ ++ hdmi_out: port@1 { ++ reg = <1>; + }; + }; + }; +diff --git a/arch/arm/boot/dts/samsung/exynos4.dtsi b/arch/arm/boot/dts/samsung/exynos4.dtsi +index f775b9377a38b..7f981b5c0d64b 100644 +--- a/arch/arm/boot/dts/samsung/exynos4.dtsi ++++ b/arch/arm/boot/dts/samsung/exynos4.dtsi +@@ -203,16 +203,16 @@ + + camera: camera@11800000 { + compatible = "samsung,fimc"; ++ ranges = <0x0 0x11800000 0xa0000>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <1>; + #clock-cells = <1>; + clock-output-names = "cam_a_clkout", "cam_b_clkout"; +- ranges; + +- fimc_0: fimc@11800000 { ++ fimc_0: fimc@0 { + compatible = "samsung,exynos4210-fimc"; +- reg = <0x11800000 0x1000>; ++ reg = <0x0 0x1000>; + interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clock CLK_FIMC0>, + <&clock CLK_SCLK_FIMC0>; +@@ -223,9 +223,9 @@ + status = "disabled"; + }; + +- fimc_1: fimc@11810000 { ++ fimc_1: fimc@10000 { + compatible = "samsung,exynos4210-fimc"; +- reg = <0x11810000 0x1000>; ++ reg = <0x00010000 0x1000>; + interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clock CLK_FIMC1>, + <&clock CLK_SCLK_FIMC1>; +@@ -236,9 +236,9 @@ + status = "disabled"; + }; + +- fimc_2: fimc@11820000 { ++ fimc_2: fimc@20000 { + compatible = "samsung,exynos4210-fimc"; +- reg = <0x11820000 0x1000>; ++ reg = <0x00020000 0x1000>; + interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clock CLK_FIMC2>, + <&clock CLK_SCLK_FIMC2>; +@@ -249,9 +249,9 @@ + status = "disabled"; + }; + +- fimc_3: fimc@11830000 { ++ fimc_3: fimc@30000 { + compatible = "samsung,exynos4210-fimc"; +- reg = <0x11830000 0x1000>; ++ reg = <0x00030000 0x1000>; + interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clock CLK_FIMC3>, + <&clock CLK_SCLK_FIMC3>; +@@ -262,9 +262,9 @@ + status = "disabled"; + }; + +- csis_0: csis@11880000 { ++ csis_0: csis@80000 { + compatible = "samsung,exynos4210-csis"; +- reg = <0x11880000 0x4000>; ++ reg = <0x00080000 0x4000>; + interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clock CLK_CSIS0>, + <&clock CLK_SCLK_CSIS0>; +@@ -278,9 +278,9 @@ + #size-cells = <0>; + }; + +- csis_1: csis@11890000 { ++ csis_1: csis@90000 { + compatible = "samsung,exynos4210-csis"; +- reg = <0x11890000 0x4000>; ++ reg = <0x00090000 0x4000>; + interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clock CLK_CSIS1>, + <&clock CLK_SCLK_CSIS1>; +diff --git a/arch/arm/boot/dts/samsung/exynos4x12.dtsi b/arch/arm/boot/dts/samsung/exynos4x12.dtsi +index 84c1db221c984..83d9d0a0a6175 100644 +--- a/arch/arm/boot/dts/samsung/exynos4x12.dtsi ++++ b/arch/arm/boot/dts/samsung/exynos4x12.dtsi +@@ -451,14 +451,15 @@ + }; + + &camera { ++ ranges = <0x0 0x11800000 0xba1000>; + clocks = <&clock CLK_SCLK_CAM0>, <&clock CLK_SCLK_CAM1>, + <&clock CLK_PIXELASYNCM0>, <&clock CLK_PIXELASYNCM1>; + clock-names = "sclk_cam0", "sclk_cam1", "pxl_async0", "pxl_async1"; + + /* fimc_[0-3] are configured outside, under phandles */ +- fimc_lite_0: fimc-lite@12390000 { ++ fimc_lite_0: fimc-lite@b90000 { + compatible = "samsung,exynos4212-fimc-lite"; +- reg = <0x12390000 0x1000>; ++ reg = <0x00b90000 0x1000>; + interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>; + power-domains = <&pd_isp>; + clocks = <&isp_clock CLK_ISP_FIMC_LITE0>; +@@ -467,9 +468,9 @@ + status = "disabled"; + }; + +- fimc_lite_1: fimc-lite@123a0000 { ++ fimc_lite_1: fimc-lite@ba0000 { + compatible = "samsung,exynos4212-fimc-lite"; +- reg = <0x123a0000 0x1000>; ++ reg = <0x00ba0000 0x1000>; + interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>; + power-domains = <&pd_isp>; + clocks = <&isp_clock CLK_ISP_FIMC_LITE1>; +@@ -478,9 +479,9 @@ + status = "disabled"; + }; + +- fimc_is: fimc-is@12000000 { ++ fimc_is: fimc-is@800000 { + compatible = "samsung,exynos4212-fimc-is"; +- reg = <0x12000000 0x260000>; ++ reg = <0x00800000 0x260000>; + interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>; + power-domains = <&pd_isp>; +@@ -525,9 +526,9 @@ + reg = <0x10020000 0x3000>; + }; + +- i2c1_isp: i2c-isp@12140000 { ++ i2c1_isp: i2c-isp@940000 { + compatible = "samsung,exynos4212-i2c-isp"; +- reg = <0x12140000 0x100>; ++ reg = <0x00940000 0x100>; + clocks = <&isp_clock CLK_ISP_I2C1_ISP>; + clock-names = "i2c_isp"; + #address-cells = <1>; +diff --git a/arch/arm/boot/dts/samsung/s5pv210.dtsi b/arch/arm/boot/dts/samsung/s5pv210.dtsi +index f7de5b5f2f383..ed560c9a3aa1e 100644 +--- a/arch/arm/boot/dts/samsung/s5pv210.dtsi ++++ b/arch/arm/boot/dts/samsung/s5pv210.dtsi +@@ -549,17 +549,17 @@ + + camera: camera@fa600000 { + compatible = "samsung,fimc"; ++ ranges = <0x0 0xfa600000 0xe01000>; + clocks = <&clocks SCLK_CAM0>, <&clocks SCLK_CAM1>; + clock-names = "sclk_cam0", "sclk_cam1"; + #address-cells = <1>; + #size-cells = <1>; + #clock-cells = <1>; + clock-output-names = "cam_a_clkout", "cam_b_clkout"; +- ranges; + +- csis0: csis@fa600000 { ++ csis0: csis@0 { + compatible = "samsung,s5pv210-csis"; +- reg = <0xfa600000 0x4000>; ++ reg = <0x00000000 0x4000>; + interrupt-parent = <&vic2>; + interrupts = <29>; + clocks = <&clocks CLK_CSIS>, +@@ -572,9 +572,9 @@ + #size-cells = <0>; + }; + +- fimc0: fimc@fb200000 { ++ fimc0: fimc@c00000 { + compatible = "samsung,s5pv210-fimc"; +- reg = <0xfb200000 0x1000>; ++ reg = <0x00c00000 0x1000>; + interrupts = <5>; + interrupt-parent = <&vic2>; + clocks = <&clocks CLK_FIMC0>, +@@ -586,9 +586,9 @@ + samsung,cam-if; + }; + +- fimc1: fimc@fb300000 { ++ fimc1: fimc@d00000 { + compatible = "samsung,s5pv210-fimc"; +- reg = <0xfb300000 0x1000>; ++ reg = <0x00d00000 0x1000>; + interrupt-parent = <&vic2>; + interrupts = <6>; + clocks = <&clocks CLK_FIMC1>, +@@ -602,9 +602,9 @@ + samsung,lcd-wb; + }; + +- fimc2: fimc@fb400000 { ++ fimc2: fimc@e00000 { + compatible = "samsung,s5pv210-fimc"; +- reg = <0xfb400000 0x1000>; ++ reg = <0x00e00000 0x1000>; + interrupt-parent = <&vic2>; + interrupts = <7>; + clocks = <&clocks CLK_FIMC2>, +diff --git a/arch/arm/include/asm/irq_work.h b/arch/arm/include/asm/irq_work.h +index 3149e4dc1b540..8895999834cc0 100644 +--- a/arch/arm/include/asm/irq_work.h ++++ b/arch/arm/include/asm/irq_work.h +@@ -9,6 +9,4 @@ static inline bool arch_irq_work_has_interrupt(void) + return is_smp(); + } + +-extern void arch_irq_work_raise(void); +- + #endif /* _ASM_ARM_IRQ_WORK_H */ +diff --git a/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts b/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts +index c1f322c739826..b1b81ac032009 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts +@@ -15,7 +15,7 @@ + #size-cells = <2>; + + aliases { +- serial0 = &uart_B; ++ serial0 = &uart_b; + }; + + memory@0 { +@@ -25,7 +25,7 @@ + + }; + +-&uart_B { ++&uart_b { + status = "okay"; + }; + +diff --git a/arch/arm64/boot/dts/amlogic/meson-s4.dtsi b/arch/arm64/boot/dts/amlogic/meson-s4.dtsi +index e0cfc54ebccb1..dac18eb634d7b 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-s4.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-s4.dtsi +@@ -126,14 +126,14 @@ + <10 11 12 13 14 15 16 17 18 19 20 21>; + }; + +- uart_B: serial@7a000 { ++ uart_b: serial@7a000 { + compatible = "amlogic,meson-s4-uart", + "amlogic,meson-ao-uart"; + reg = <0x0 0x7a000 0x0 0x18>; + interrupts = <GIC_SPI 169 IRQ_TYPE_EDGE_RISING>; +- status = "disabled"; + clocks = <&xtal>, <&xtal>, <&xtal>; + clock-names = "xtal", "pclk", "baud"; ++ status = "disabled"; + }; + + reset: reset-controller@2000 { +diff --git a/arch/arm64/boot/dts/marvell/armada-3720-espressobin-ultra.dts b/arch/arm64/boot/dts/marvell/armada-3720-espressobin-ultra.dts +index f9abef8dcc948..870bb380a40a6 100644 +--- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin-ultra.dts ++++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin-ultra.dts +@@ -126,32 +126,32 @@ + + reset-gpios = <&gpiosb 23 GPIO_ACTIVE_LOW>; + +- ports { +- switch0port1: port@1 { ++ ethernet-ports { ++ switch0port1: ethernet-port@1 { + reg = <1>; + label = "lan0"; + phy-handle = <&switch0phy0>; + }; + +- switch0port2: port@2 { ++ switch0port2: ethernet-port@2 { + reg = <2>; + label = "lan1"; + phy-handle = <&switch0phy1>; + }; + +- switch0port3: port@3 { ++ switch0port3: ethernet-port@3 { + reg = <3>; + label = "lan2"; + phy-handle = <&switch0phy2>; + }; + +- switch0port4: port@4 { ++ switch0port4: ethernet-port@4 { + reg = <4>; + label = "lan3"; + phy-handle = <&switch0phy3>; + }; + +- switch0port5: port@5 { ++ switch0port5: ethernet-port@5 { + reg = <5>; + label = "wan"; + phy-handle = <&extphy>; +@@ -160,7 +160,7 @@ + }; + + mdio { +- switch0phy3: switch0phy3@14 { ++ switch0phy3: ethernet-phy@14 { + reg = <0x14>; + }; + }; +diff --git a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dtsi b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dtsi +index 49cbdb55b4b36..fed2dcecb323f 100644 +--- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dtsi ++++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dtsi +@@ -145,19 +145,17 @@ + }; + + &mdio { +- switch0: switch0@1 { ++ switch0: ethernet-switch@1 { + compatible = "marvell,mv88e6085"; +- #address-cells = <1>; +- #size-cells = <0>; + reg = <1>; + + dsa,member = <0 0>; + +- ports { ++ ethernet-ports { + #address-cells = <1>; + #size-cells = <0>; + +- switch0port0: port@0 { ++ switch0port0: ethernet-port@0 { + reg = <0>; + label = "cpu"; + ethernet = <ð0>; +@@ -168,19 +166,19 @@ + }; + }; + +- switch0port1: port@1 { ++ switch0port1: ethernet-port@1 { + reg = <1>; + label = "wan"; + phy-handle = <&switch0phy0>; + }; + +- switch0port2: port@2 { ++ switch0port2: ethernet-port@2 { + reg = <2>; + label = "lan0"; + phy-handle = <&switch0phy1>; + }; + +- switch0port3: port@3 { ++ switch0port3: ethernet-port@3 { + reg = <3>; + label = "lan1"; + phy-handle = <&switch0phy2>; +@@ -192,13 +190,13 @@ + #address-cells = <1>; + #size-cells = <0>; + +- switch0phy0: switch0phy0@11 { ++ switch0phy0: ethernet-phy@11 { + reg = <0x11>; + }; +- switch0phy1: switch0phy1@12 { ++ switch0phy1: ethernet-phy@12 { + reg = <0x12>; + }; +- switch0phy2: switch0phy2@13 { ++ switch0phy2: ethernet-phy@13 { + reg = <0x13>; + }; + }; +diff --git a/arch/arm64/boot/dts/marvell/armada-3720-gl-mv1000.dts b/arch/arm64/boot/dts/marvell/armada-3720-gl-mv1000.dts +index b1b45b4fa9d4a..63fbc83521616 100644 +--- a/arch/arm64/boot/dts/marvell/armada-3720-gl-mv1000.dts ++++ b/arch/arm64/boot/dts/marvell/armada-3720-gl-mv1000.dts +@@ -152,31 +152,29 @@ + }; + + &mdio { +- switch0: switch0@1 { ++ switch0: ethernet-switch@1 { + compatible = "marvell,mv88e6085"; +- #address-cells = <1>; +- #size-cells = <0>; + reg = <1>; + + dsa,member = <0 0>; + +- ports: ports { ++ ports: ethernet-ports { + #address-cells = <1>; + #size-cells = <0>; + +- port@0 { ++ ethernet-port@0 { + reg = <0>; + label = "cpu"; + ethernet = <ð0>; + }; + +- port@1 { ++ ethernet-port@1 { + reg = <1>; + label = "wan"; + phy-handle = <&switch0phy0>; + }; + +- port@2 { ++ ethernet-port@2 { + reg = <2>; + label = "lan0"; + phy-handle = <&switch0phy1>; +@@ -185,7 +183,7 @@ + nvmem-cell-names = "mac-address"; + }; + +- port@3 { ++ ethernet-port@3 { + reg = <3>; + label = "lan1"; + phy-handle = <&switch0phy2>; +@@ -199,13 +197,13 @@ + #address-cells = <1>; + #size-cells = <0>; + +- switch0phy0: switch0phy0@11 { ++ switch0phy0: ethernet-phy@11 { + reg = <0x11>; + }; +- switch0phy1: switch0phy1@12 { ++ switch0phy1: ethernet-phy@12 { + reg = <0x12>; + }; +- switch0phy2: switch0phy2@13 { ++ switch0phy2: ethernet-phy@13 { + reg = <0x13>; + }; + }; +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 805ef2d79b401..4249acdec5ae2 100644 +--- a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts ++++ b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts +@@ -304,7 +304,13 @@ + reg = <1>; + }; + +- /* switch nodes are enabled by U-Boot if modules are present */ ++ /* ++ * NOTE: switch nodes are enabled by U-Boot if modules are present ++ * DO NOT change this node name (switch0@10) even if it is not following ++ * conventions! Deployed U-Boot binaries are explicitly looking for ++ * this node in order to augment the device tree! ++ * Also do not touch the "ports" or "port@n" nodes. These are also ABI. ++ */ + switch0@10 { + compatible = "marvell,mv88e6190"; + reg = <0x10>; +@@ -317,35 +323,35 @@ + #address-cells = <1>; + #size-cells = <0>; + +- switch0phy1: switch0phy1@1 { ++ switch0phy1: ethernet-phy@1 { + reg = <0x1>; + }; + +- switch0phy2: switch0phy2@2 { ++ switch0phy2: ethernet-phy@2 { + reg = <0x2>; + }; + +- switch0phy3: switch0phy3@3 { ++ switch0phy3: ethernet-phy@3 { + reg = <0x3>; + }; + +- switch0phy4: switch0phy4@4 { ++ switch0phy4: ethernet-phy@4 { + reg = <0x4>; + }; + +- switch0phy5: switch0phy5@5 { ++ switch0phy5: ethernet-phy@5 { + reg = <0x5>; + }; + +- switch0phy6: switch0phy6@6 { ++ switch0phy6: ethernet-phy@6 { + reg = <0x6>; + }; + +- switch0phy7: switch0phy7@7 { ++ switch0phy7: ethernet-phy@7 { + reg = <0x7>; + }; + +- switch0phy8: switch0phy8@8 { ++ switch0phy8: ethernet-phy@8 { + reg = <0x8>; + }; + }; +@@ -430,6 +436,7 @@ + }; + }; + ++ /* NOTE: this node name is ABI, don't change it! */ + switch0@2 { + compatible = "marvell,mv88e6085"; + reg = <0x2>; +@@ -442,19 +449,19 @@ + #address-cells = <1>; + #size-cells = <0>; + +- switch0phy1_topaz: switch0phy1@11 { ++ switch0phy1_topaz: ethernet-phy@11 { + reg = <0x11>; + }; + +- switch0phy2_topaz: switch0phy2@12 { ++ switch0phy2_topaz: ethernet-phy@12 { + reg = <0x12>; + }; + +- switch0phy3_topaz: switch0phy3@13 { ++ switch0phy3_topaz: ethernet-phy@13 { + reg = <0x13>; + }; + +- switch0phy4_topaz: switch0phy4@14 { ++ switch0phy4_topaz: ethernet-phy@14 { + reg = <0x14>; + }; + }; +@@ -497,6 +504,7 @@ + }; + }; + ++ /* NOTE: this node name is ABI, don't change it! */ + switch1@11 { + compatible = "marvell,mv88e6190"; + reg = <0x11>; +@@ -509,35 +517,35 @@ + #address-cells = <1>; + #size-cells = <0>; + +- switch1phy1: switch1phy1@1 { ++ switch1phy1: ethernet-phy@1 { + reg = <0x1>; + }; + +- switch1phy2: switch1phy2@2 { ++ switch1phy2: ethernet-phy@2 { + reg = <0x2>; + }; + +- switch1phy3: switch1phy3@3 { ++ switch1phy3: ethernet-phy@3 { + reg = <0x3>; + }; + +- switch1phy4: switch1phy4@4 { ++ switch1phy4: ethernet-phy@4 { + reg = <0x4>; + }; + +- switch1phy5: switch1phy5@5 { ++ switch1phy5: ethernet-phy@5 { + reg = <0x5>; + }; + +- switch1phy6: switch1phy6@6 { ++ switch1phy6: ethernet-phy@6 { + reg = <0x6>; + }; + +- switch1phy7: switch1phy7@7 { ++ switch1phy7: ethernet-phy@7 { + reg = <0x7>; + }; + +- switch1phy8: switch1phy8@8 { ++ switch1phy8: ethernet-phy@8 { + reg = <0x8>; + }; + }; +@@ -622,6 +630,7 @@ + }; + }; + ++ /* NOTE: this node name is ABI, don't change it! */ + switch1@2 { + compatible = "marvell,mv88e6085"; + reg = <0x2>; +@@ -634,19 +643,19 @@ + #address-cells = <1>; + #size-cells = <0>; + +- switch1phy1_topaz: switch1phy1@11 { ++ switch1phy1_topaz: ethernet-phy@11 { + reg = <0x11>; + }; + +- switch1phy2_topaz: switch1phy2@12 { ++ switch1phy2_topaz: ethernet-phy@12 { + reg = <0x12>; + }; + +- switch1phy3_topaz: switch1phy3@13 { ++ switch1phy3_topaz: ethernet-phy@13 { + reg = <0x13>; + }; + +- switch1phy4_topaz: switch1phy4@14 { ++ switch1phy4_topaz: ethernet-phy@14 { + reg = <0x14>; + }; + }; +@@ -689,6 +698,7 @@ + }; + }; + ++ /* NOTE: this node name is ABI, don't change it! */ + switch2@12 { + compatible = "marvell,mv88e6190"; + reg = <0x12>; +@@ -701,35 +711,35 @@ + #address-cells = <1>; + #size-cells = <0>; + +- switch2phy1: switch2phy1@1 { ++ switch2phy1: ethernet-phy@1 { + reg = <0x1>; + }; + +- switch2phy2: switch2phy2@2 { ++ switch2phy2: ethernet-phy@2 { + reg = <0x2>; + }; + +- switch2phy3: switch2phy3@3 { ++ switch2phy3: ethernet-phy@3 { + reg = <0x3>; + }; + +- switch2phy4: switch2phy4@4 { ++ switch2phy4: ethernet-phy@4 { + reg = <0x4>; + }; + +- switch2phy5: switch2phy5@5 { ++ switch2phy5: ethernet-phy@5 { + reg = <0x5>; + }; + +- switch2phy6: switch2phy6@6 { ++ switch2phy6: ethernet-phy@6 { + reg = <0x6>; + }; + +- switch2phy7: switch2phy7@7 { ++ switch2phy7: ethernet-phy@7 { + reg = <0x7>; + }; + +- switch2phy8: switch2phy8@8 { ++ switch2phy8: ethernet-phy@8 { + reg = <0x8>; + }; + }; +@@ -805,6 +815,7 @@ + }; + }; + ++ /* NOTE: this node name is ABI, don't change it! */ + switch2@2 { + compatible = "marvell,mv88e6085"; + reg = <0x2>; +@@ -817,19 +828,19 @@ + #address-cells = <1>; + #size-cells = <0>; + +- switch2phy1_topaz: switch2phy1@11 { ++ switch2phy1_topaz: ethernet-phy@11 { + reg = <0x11>; + }; + +- switch2phy2_topaz: switch2phy2@12 { ++ switch2phy2_topaz: ethernet-phy@12 { + reg = <0x12>; + }; + +- switch2phy3_topaz: switch2phy3@13 { ++ switch2phy3_topaz: ethernet-phy@13 { + reg = <0x13>; + }; + +- switch2phy4_topaz: switch2phy4@14 { ++ switch2phy4_topaz: ethernet-phy@14 { + reg = <0x14>; + }; + }; +diff --git a/arch/arm64/boot/dts/marvell/armada-7040-mochabin.dts b/arch/arm64/boot/dts/marvell/armada-7040-mochabin.dts +index 48202810bf786..40b7ee7ead72e 100644 +--- a/arch/arm64/boot/dts/marvell/armada-7040-mochabin.dts ++++ b/arch/arm64/boot/dts/marvell/armada-7040-mochabin.dts +@@ -301,10 +301,8 @@ + }; + + /* 88E6141 Topaz switch */ +- switch: switch@3 { ++ switch: ethernet-switch@3 { + compatible = "marvell,mv88e6085"; +- #address-cells = <1>; +- #size-cells = <0>; + reg = <3>; + + pinctrl-names = "default"; +@@ -314,35 +312,35 @@ + interrupt-parent = <&cp0_gpio1>; + interrupts = <1 IRQ_TYPE_LEVEL_LOW>; + +- ports { ++ ethernet-ports { + #address-cells = <1>; + #size-cells = <0>; + +- swport1: port@1 { ++ swport1: ethernet-port@1 { + reg = <1>; + label = "lan0"; + phy-handle = <&swphy1>; + }; + +- swport2: port@2 { ++ swport2: ethernet-port@2 { + reg = <2>; + label = "lan1"; + phy-handle = <&swphy2>; + }; + +- swport3: port@3 { ++ swport3: ethernet-port@3 { + reg = <3>; + label = "lan2"; + phy-handle = <&swphy3>; + }; + +- swport4: port@4 { ++ swport4: ethernet-port@4 { + reg = <4>; + label = "lan3"; + phy-handle = <&swphy4>; + }; + +- port@5 { ++ ethernet-port@5 { + reg = <5>; + label = "cpu"; + ethernet = <&cp0_eth1>; +@@ -355,19 +353,19 @@ + #address-cells = <1>; + #size-cells = <0>; + +- swphy1: swphy1@17 { ++ swphy1: ethernet-phy@17 { + reg = <17>; + }; + +- swphy2: swphy2@18 { ++ swphy2: ethernet-phy@18 { + reg = <18>; + }; + +- swphy3: swphy3@19 { ++ swphy3: ethernet-phy@19 { + reg = <19>; + }; + +- swphy4: swphy4@20 { ++ swphy4: ethernet-phy@20 { + reg = <20>; + }; + }; +diff --git a/arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts b/arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts +index 4125202028c85..67892f0d28633 100644 +--- a/arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts ++++ b/arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts +@@ -497,42 +497,42 @@ + reset-deassert-us = <10000>; + }; + +- switch0: switch0@4 { ++ switch0: ethernet-switch@4 { + compatible = "marvell,mv88e6085"; + reg = <4>; + pinctrl-names = "default"; + pinctrl-0 = <&cp1_switch_reset_pins>; + reset-gpios = <&cp1_gpio1 24 GPIO_ACTIVE_LOW>; + +- ports { ++ ethernet-ports { + #address-cells = <1>; + #size-cells = <0>; + +- port@1 { ++ ethernet-port@1 { + reg = <1>; + label = "lan2"; + phy-handle = <&switch0phy0>; + }; + +- port@2 { ++ ethernet-port@2 { + reg = <2>; + label = "lan1"; + phy-handle = <&switch0phy1>; + }; + +- port@3 { ++ ethernet-port@3 { + reg = <3>; + label = "lan4"; + phy-handle = <&switch0phy2>; + }; + +- port@4 { ++ ethernet-port@4 { + reg = <4>; + label = "lan3"; + phy-handle = <&switch0phy3>; + }; + +- port@5 { ++ ethernet-port@5 { + reg = <5>; + label = "cpu"; + ethernet = <&cp1_eth2>; +@@ -545,19 +545,19 @@ + #address-cells = <1>; + #size-cells = <0>; + +- switch0phy0: switch0phy0@11 { ++ switch0phy0: ethernet-phy@11 { + reg = <0x11>; + }; + +- switch0phy1: switch0phy1@12 { ++ switch0phy1: ethernet-phy@12 { + reg = <0x12>; + }; + +- switch0phy2: switch0phy2@13 { ++ switch0phy2: ethernet-phy@13 { + reg = <0x13>; + }; + +- switch0phy3: switch0phy3@14 { ++ switch0phy3: ethernet-phy@14 { + reg = <0x14>; + }; + }; +diff --git a/arch/arm64/boot/dts/marvell/cn9130-crb.dtsi b/arch/arm64/boot/dts/marvell/cn9130-crb.dtsi +index 47d45ff3d6f57..6fcc34f7b4647 100644 +--- a/arch/arm64/boot/dts/marvell/cn9130-crb.dtsi ++++ b/arch/arm64/boot/dts/marvell/cn9130-crb.dtsi +@@ -207,11 +207,9 @@ + reg = <0>; + }; + +- switch6: switch0@6 { ++ switch6: ethernet-switch@6 { + /* Actual device is MV88E6393X */ + compatible = "marvell,mv88e6190"; +- #address-cells = <1>; +- #size-cells = <0>; + reg = <6>; + interrupt-parent = <&cp0_gpio1>; + interrupts = <28 IRQ_TYPE_LEVEL_LOW>; +@@ -220,59 +218,59 @@ + + dsa,member = <0 0>; + +- ports { ++ ethernet-ports { + #address-cells = <1>; + #size-cells = <0>; + +- port@1 { ++ ethernet-port@1 { + reg = <1>; + label = "p1"; + phy-handle = <&switch0phy1>; + }; + +- port@2 { ++ ethernet-port@2 { + reg = <2>; + label = "p2"; + phy-handle = <&switch0phy2>; + }; + +- port@3 { ++ ethernet-port@3 { + reg = <3>; + label = "p3"; + phy-handle = <&switch0phy3>; + }; + +- port@4 { ++ ethernet-port@4 { + reg = <4>; + label = "p4"; + phy-handle = <&switch0phy4>; + }; + +- port@5 { ++ ethernet-port@5 { + reg = <5>; + label = "p5"; + phy-handle = <&switch0phy5>; + }; + +- port@6 { ++ ethernet-port@6 { + reg = <6>; + label = "p6"; + phy-handle = <&switch0phy6>; + }; + +- port@7 { ++ ethernet-port@7 { + reg = <7>; + label = "p7"; + phy-handle = <&switch0phy7>; + }; + +- port@8 { ++ ethernet-port@8 { + reg = <8>; + label = "p8"; + phy-handle = <&switch0phy8>; + }; + +- port@9 { ++ ethernet-port@9 { + reg = <9>; + label = "p9"; + phy-mode = "10gbase-r"; +@@ -280,7 +278,7 @@ + managed = "in-band-status"; + }; + +- port@a { ++ ethernet-port@a { + reg = <10>; + ethernet = <&cp0_eth0>; + phy-mode = "10gbase-r"; +@@ -293,35 +291,35 @@ + #address-cells = <1>; + #size-cells = <0>; + +- switch0phy1: switch0phy1@1 { ++ switch0phy1: ethernet-phy@1 { + reg = <0x1>; + }; + +- switch0phy2: switch0phy2@2 { ++ switch0phy2: ethernet-phy@2 { + reg = <0x2>; + }; + +- switch0phy3: switch0phy3@3 { ++ switch0phy3: ethernet-phy@3 { + reg = <0x3>; + }; + +- switch0phy4: switch0phy4@4 { ++ switch0phy4: ethernet-phy@4 { + reg = <0x4>; + }; + +- switch0phy5: switch0phy5@5 { ++ switch0phy5: ethernet-phy@5 { + reg = <0x5>; + }; + +- switch0phy6: switch0phy6@6 { ++ switch0phy6: ethernet-phy@6 { + reg = <0x6>; + }; + +- switch0phy7: switch0phy7@7 { ++ switch0phy7: ethernet-phy@7 { + reg = <0x7>; + }; + +- switch0phy8: switch0phy8@8 { ++ switch0phy8: ethernet-phy@8 { + reg = <0x8>; + }; + }; +diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi +index 6ba9da9e6a8b9..fa8ec92ce4904 100644 +--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi ++++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi +@@ -444,6 +444,19 @@ + reg = <0x0 0x80000000 0x0 0x0>; + }; + ++ etm { ++ compatible = "qcom,coresight-remote-etm"; ++ ++ out-ports { ++ port { ++ modem_etm_out_funnel_in2: endpoint { ++ remote-endpoint = ++ <&funnel_in2_in_modem_etm>; ++ }; ++ }; ++ }; ++ }; ++ + psci { + compatible = "arm,psci-1.0"; + method = "smc"; +@@ -2644,6 +2657,14 @@ + clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>; + clock-names = "apb_pclk", "atclk"; + ++ in-ports { ++ port { ++ funnel_in2_in_modem_etm: endpoint { ++ remote-endpoint = ++ <&modem_etm_out_funnel_in2>; ++ }; ++ }; ++ }; + + out-ports { + port { +diff --git a/arch/arm64/boot/dts/qcom/msm8998.dtsi b/arch/arm64/boot/dts/qcom/msm8998.dtsi +index b485bf925ce61..ebc5ba1b369e9 100644 +--- a/arch/arm64/boot/dts/qcom/msm8998.dtsi ++++ b/arch/arm64/boot/dts/qcom/msm8998.dtsi +@@ -2031,9 +2031,11 @@ + + cpu = <&CPU4>; + +- port { +- etm4_out: endpoint { +- remote-endpoint = <&apss_funnel_in4>; ++ out-ports { ++ port { ++ etm4_out: endpoint { ++ remote-endpoint = <&apss_funnel_in4>; ++ }; + }; + }; + }; +@@ -2048,9 +2050,11 @@ + + cpu = <&CPU5>; + +- port { +- etm5_out: endpoint { +- remote-endpoint = <&apss_funnel_in5>; ++ out-ports { ++ port { ++ etm5_out: endpoint { ++ remote-endpoint = <&apss_funnel_in5>; ++ }; + }; + }; + }; +@@ -2065,9 +2069,11 @@ + + cpu = <&CPU6>; + +- port { +- etm6_out: endpoint { +- remote-endpoint = <&apss_funnel_in6>; ++ out-ports { ++ port { ++ etm6_out: endpoint { ++ remote-endpoint = <&apss_funnel_in6>; ++ }; + }; + }; + }; +@@ -2082,9 +2088,11 @@ + + cpu = <&CPU7>; + +- port { +- etm7_out: endpoint { +- remote-endpoint = <&apss_funnel_in7>; ++ out-ports { ++ port { ++ etm7_out: endpoint { ++ remote-endpoint = <&apss_funnel_in7>; ++ }; + }; + }; + }; +diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi +index 91169e438b463..9e594d21ecd80 100644 +--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi ++++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi +@@ -3545,11 +3545,8 @@ + }; + + in-ports { +- #address-cells = <1>; +- #size-cells = <0>; + +- port@1 { +- reg = <1>; ++ port { + etf_in: endpoint { + remote-endpoint = + <&merge_funnel_out>; +diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi +index e302eb7821af0..3221478663ac6 100644 +--- a/arch/arm64/boot/dts/qcom/sm8150.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi +@@ -2957,11 +2957,8 @@ + }; + + in-ports { +- #address-cells = <1>; +- #size-cells = <0>; + +- port@1 { +- reg = <1>; ++ port { + replicator1_in: endpoint { + remote-endpoint = <&replicator_out1>; + }; +diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi +index 72db75ca77310..d59a99ca872c0 100644 +--- a/arch/arm64/boot/dts/qcom/sm8250.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi +@@ -3095,11 +3095,8 @@ + clock-names = "apb_pclk"; + + out-ports { +- #address-cells = <1>; +- #size-cells = <0>; + +- port@0 { +- reg = <0>; ++ port { + tpda_out_funnel_qatb: endpoint { + remote-endpoint = <&funnel_qatb_in_tpda>; + }; +@@ -3142,11 +3139,7 @@ + }; + + in-ports { +- #address-cells = <1>; +- #size-cells = <0>; +- +- port@0 { +- reg = <0>; ++ port { + funnel_qatb_in_tpda: endpoint { + remote-endpoint = <&tpda_out_funnel_qatb>; + }; +@@ -3355,11 +3348,8 @@ + }; + + in-ports { +- #address-cells = <1>; +- #size-cells = <0>; + +- port@0 { +- reg = <0>; ++ port { + etf_in_funnel_swao_out: endpoint { + remote-endpoint = <&funnel_swao_out_etf>; + }; +@@ -3443,8 +3433,6 @@ + clock-names = "apb_pclk"; + + out-ports { +- #address-cells = <1>; +- #size-cells = <0>; + port { + tpdm_mm_out_tpda9: endpoint { + remote-endpoint = <&tpda_9_in_tpdm_mm>; +@@ -3710,11 +3698,7 @@ + }; + + in-ports { +- #address-cells = <1>; +- #size-cells = <0>; +- +- port@0 { +- reg = <0>; ++ port { + funnel_apss_merg_in_funnel_apss: endpoint { + remote-endpoint = <&funnel_apss_out_funnel_apss_merg>; + }; +diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi +index 1d597af15bb3e..a72f3c470089b 100644 +--- a/arch/arm64/boot/dts/qcom/sm8350.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi +@@ -2021,7 +2021,7 @@ + compatible = "qcom,sm8350-mpss-pas"; + reg = <0x0 0x04080000 0x0 0x4040>; + +- interrupts-extended = <&intc GIC_SPI 264 IRQ_TYPE_LEVEL_HIGH>, ++ interrupts-extended = <&intc GIC_SPI 264 IRQ_TYPE_EDGE_RISING>, + <&smp2p_modem_in 0 IRQ_TYPE_EDGE_RISING>, + <&smp2p_modem_in 1 IRQ_TYPE_EDGE_RISING>, + <&smp2p_modem_in 2 IRQ_TYPE_EDGE_RISING>, +@@ -2063,7 +2063,7 @@ + compatible = "qcom,sm8350-slpi-pas"; + reg = <0 0x05c00000 0 0x4000>; + +- interrupts-extended = <&pdc 9 IRQ_TYPE_LEVEL_HIGH>, ++ interrupts-extended = <&pdc 9 IRQ_TYPE_EDGE_RISING>, + <&smp2p_slpi_in 0 IRQ_TYPE_EDGE_RISING>, + <&smp2p_slpi_in 1 IRQ_TYPE_EDGE_RISING>, + <&smp2p_slpi_in 2 IRQ_TYPE_EDGE_RISING>, +@@ -3207,7 +3207,7 @@ + compatible = "qcom,sm8350-adsp-pas"; + reg = <0 0x17300000 0 0x100>; + +- interrupts-extended = <&pdc 6 IRQ_TYPE_LEVEL_HIGH>, ++ interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>, + <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>, + <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>, + <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>, +@@ -3512,7 +3512,7 @@ + compatible = "qcom,sm8350-cdsp-pas"; + reg = <0 0x98900000 0 0x1400000>; + +- interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_LEVEL_HIGH>, ++ interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>, + <&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>, + <&smp2p_cdsp_in 1 IRQ_TYPE_EDGE_RISING>, + <&smp2p_cdsp_in 2 IRQ_TYPE_EDGE_RISING>, +diff --git a/arch/arm64/boot/dts/qcom/sm8450.dtsi b/arch/arm64/boot/dts/qcom/sm8450.dtsi +index dc904ccb3d6c2..f82480570d4b6 100644 +--- a/arch/arm64/boot/dts/qcom/sm8450.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8450.dtsi +@@ -2160,7 +2160,7 @@ + #sound-dai-cells = <1>; + }; + +- swr4: soundwire-controller@31f0000 { ++ swr4: soundwire@31f0000 { + compatible = "qcom,soundwire-v1.7.0"; + reg = <0 0x031f0000 0 0x2000>; + interrupts = <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>; +@@ -2208,7 +2208,7 @@ + #sound-dai-cells = <1>; + }; + +- swr1: soundwire-controller@3210000 { ++ swr1: soundwire@3210000 { + compatible = "qcom,soundwire-v1.7.0"; + reg = <0 0x03210000 0 0x2000>; + interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>; +@@ -2275,7 +2275,7 @@ + #sound-dai-cells = <1>; + }; + +- swr0: soundwire-controller@3250000 { ++ swr0: soundwire@3250000 { + compatible = "qcom,soundwire-v1.7.0"; + reg = <0 0x03250000 0 0x2000>; + interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>; +@@ -2302,7 +2302,7 @@ + status = "disabled"; + }; + +- swr2: soundwire-controller@33b0000 { ++ swr2: soundwire@33b0000 { + compatible = "qcom,soundwire-v1.7.0"; + reg = <0 0x033b0000 0 0x2000>; + interrupts = <GIC_SPI 496 IRQ_TYPE_LEVEL_HIGH>, +diff --git a/arch/arm64/boot/dts/qcom/sm8550.dtsi b/arch/arm64/boot/dts/qcom/sm8550.dtsi +index 5cf813a579d58..e15564ed54cef 100644 +--- a/arch/arm64/boot/dts/qcom/sm8550.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8550.dtsi +@@ -2060,7 +2060,7 @@ + #sound-dai-cells = <1>; + }; + +- swr3: soundwire-controller@6ab0000 { ++ swr3: soundwire@6ab0000 { + compatible = "qcom,soundwire-v2.0.0"; + reg = <0 0x06ab0000 0 0x10000>; + interrupts = <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>; +@@ -2106,7 +2106,7 @@ + #sound-dai-cells = <1>; + }; + +- swr1: soundwire-controller@6ad0000 { ++ swr1: soundwire@6ad0000 { + compatible = "qcom,soundwire-v2.0.0"; + reg = <0 0x06ad0000 0 0x10000>; + interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>; +@@ -2171,7 +2171,7 @@ + #sound-dai-cells = <1>; + }; + +- swr0: soundwire-controller@6b10000 { ++ swr0: soundwire@6b10000 { + compatible = "qcom,soundwire-v2.0.0"; + reg = <0 0x06b10000 0 0x10000>; + interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>; +@@ -2198,7 +2198,7 @@ + status = "disabled"; + }; + +- swr2: soundwire-controller@6d30000 { ++ swr2: soundwire@6d30000 { + compatible = "qcom,soundwire-v2.0.0"; + reg = <0 0x06d30000 0 0x10000>; + interrupts = <GIC_SPI 496 IRQ_TYPE_LEVEL_HIGH>, +diff --git a/arch/arm64/boot/dts/sprd/ums512.dtsi b/arch/arm64/boot/dts/sprd/ums512.dtsi +index 97ac550af2f11..cc4459551e05e 100644 +--- a/arch/arm64/boot/dts/sprd/ums512.dtsi ++++ b/arch/arm64/boot/dts/sprd/ums512.dtsi +@@ -113,7 +113,7 @@ + + idle-states { + entry-method = "psci"; +- CORE_PD: core-pd { ++ CORE_PD: cpu-pd { + compatible = "arm,idle-state"; + entry-latency-us = <4000>; + exit-latency-us = <4000>; +@@ -291,6 +291,7 @@ + pll2: clock-controller@0 { + compatible = "sprd,ums512-gc-pll"; + reg = <0x0 0x100>; ++ clocks = <&ext_26m>; + clock-names = "ext-26m"; + #clock-cells = <1>; + }; +diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revA.dtso b/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revA.dtso +index ae1b9b2bdbee2..92f4190d564db 100644 +--- a/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revA.dtso ++++ b/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revA.dtso +@@ -21,57 +21,57 @@ + /dts-v1/; + /plugin/; + +-&i2c1 { /* I2C_SCK C23/C24 - MIO from SOM */ +- #address-cells = <1>; +- #size-cells = <0>; +- pinctrl-names = "default", "gpio"; +- pinctrl-0 = <&pinctrl_i2c1_default>; +- pinctrl-1 = <&pinctrl_i2c1_gpio>; +- scl-gpios = <&gpio 24 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; +- sda-gpios = <&gpio 25 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; +- +- /* u14 - 0x40 - ina260 */ +- /* u27 - 0xe0 - STDP4320 DP/HDMI splitter */ +-}; +- +-&amba { +- si5332_0: si5332_0 { /* u17 */ ++&{/} { ++ si5332_0: si5332-0 { /* u17 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <125000000>; + }; + +- si5332_1: si5332_1 { /* u17 */ ++ si5332_1: si5332-1 { /* u17 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + }; + +- si5332_2: si5332_2 { /* u17 */ ++ si5332_2: si5332-2 { /* u17 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <48000000>; + }; + +- si5332_3: si5332_3 { /* u17 */ ++ si5332_3: si5332-3 { /* u17 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24000000>; + }; + +- si5332_4: si5332_4 { /* u17 */ ++ si5332_4: si5332-4 { /* u17 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <26000000>; + }; + +- si5332_5: si5332_5 { /* u17 */ ++ si5332_5: si5332-5 { /* u17 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; + }; + }; + ++&i2c1 { /* I2C_SCK C23/C24 - MIO from SOM */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default", "gpio"; ++ pinctrl-0 = <&pinctrl_i2c1_default>; ++ pinctrl-1 = <&pinctrl_i2c1_gpio>; ++ scl-gpios = <&gpio 24 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; ++ sda-gpios = <&gpio 25 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; ++ ++ /* u14 - 0x40 - ina260 */ ++ /* u27 - 0xe0 - STDP4320 DP/HDMI splitter */ ++}; ++ + /* DP/USB 3.0 and SATA */ + &psgtr { + status = "okay"; +diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revB.dtso b/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revB.dtso +index b59e48be6465a..f88b71f5b07a6 100644 +--- a/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revB.dtso ++++ b/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revB.dtso +@@ -16,58 +16,58 @@ + /dts-v1/; + /plugin/; + +-&i2c1 { /* I2C_SCK C23/C24 - MIO from SOM */ +- #address-cells = <1>; +- #size-cells = <0>; +- pinctrl-names = "default", "gpio"; +- pinctrl-0 = <&pinctrl_i2c1_default>; +- pinctrl-1 = <&pinctrl_i2c1_gpio>; +- scl-gpios = <&gpio 24 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; +- sda-gpios = <&gpio 25 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; +- +- /* u14 - 0x40 - ina260 */ +- /* u43 - 0x2d - usb5744 */ +- /* u27 - 0xe0 - STDP4320 DP/HDMI splitter */ +-}; +- +-&amba { +- si5332_0: si5332_0 { /* u17 */ ++&{/} { ++ si5332_0: si5332-0 { /* u17 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <125000000>; + }; + +- si5332_1: si5332_1 { /* u17 */ ++ si5332_1: si5332-1 { /* u17 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + }; + +- si5332_2: si5332_2 { /* u17 */ ++ si5332_2: si5332-2 { /* u17 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <48000000>; + }; + +- si5332_3: si5332_3 { /* u17 */ ++ si5332_3: si5332-3 { /* u17 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24000000>; + }; + +- si5332_4: si5332_4 { /* u17 */ ++ si5332_4: si5332-4 { /* u17 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <26000000>; + }; + +- si5332_5: si5332_5 { /* u17 */ ++ si5332_5: si5332-5 { /* u17 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; + }; + }; + ++&i2c1 { /* I2C_SCK C23/C24 - MIO from SOM */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default", "gpio"; ++ pinctrl-0 = <&pinctrl_i2c1_default>; ++ pinctrl-1 = <&pinctrl_i2c1_gpio>; ++ scl-gpios = <&gpio 24 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; ++ sda-gpios = <&gpio 25 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; ++ ++ /* u14 - 0x40 - ina260 */ ++ /* u43 - 0x2d - usb5744 */ ++ /* u27 - 0xe0 - STDP4320 DP/HDMI splitter */ ++}; ++ + /* DP/USB 3.0 */ + &psgtr { + status = "okay"; +diff --git a/arch/arm64/include/asm/irq_work.h b/arch/arm64/include/asm/irq_work.h +index 81bbfa3a035bd..a1020285ea750 100644 +--- a/arch/arm64/include/asm/irq_work.h ++++ b/arch/arm64/include/asm/irq_work.h +@@ -2,8 +2,6 @@ + #ifndef __ASM_IRQ_WORK_H + #define __ASM_IRQ_WORK_H + +-extern void arch_irq_work_raise(void); +- + static inline bool arch_irq_work_has_interrupt(void) + { + return true; +diff --git a/arch/arm64/kernel/irq.c b/arch/arm64/kernel/irq.c +index 6ad5c6ef53296..85087e2df5649 100644 +--- a/arch/arm64/kernel/irq.c ++++ b/arch/arm64/kernel/irq.c +@@ -22,6 +22,7 @@ + #include <linux/vmalloc.h> + #include <asm/daifflags.h> + #include <asm/exception.h> ++#include <asm/numa.h> + #include <asm/softirq_stack.h> + #include <asm/stacktrace.h> + #include <asm/vmap_stack.h> +@@ -47,17 +48,17 @@ static void init_irq_scs(void) + + for_each_possible_cpu(cpu) + per_cpu(irq_shadow_call_stack_ptr, cpu) = +- scs_alloc(cpu_to_node(cpu)); ++ scs_alloc(early_cpu_to_node(cpu)); + } + + #ifdef CONFIG_VMAP_STACK +-static void init_irq_stacks(void) ++static void __init init_irq_stacks(void) + { + int cpu; + unsigned long *p; + + for_each_possible_cpu(cpu) { +- p = arch_alloc_vmap_stack(IRQ_STACK_SIZE, cpu_to_node(cpu)); ++ p = arch_alloc_vmap_stack(IRQ_STACK_SIZE, early_cpu_to_node(cpu)); + per_cpu(irq_stack_ptr, cpu) = p; + } + } +diff --git a/arch/csky/include/asm/irq_work.h b/arch/csky/include/asm/irq_work.h +index 33aaf39d6f94f..d39fcc1f5395f 100644 +--- a/arch/csky/include/asm/irq_work.h ++++ b/arch/csky/include/asm/irq_work.h +@@ -7,5 +7,5 @@ static inline bool arch_irq_work_has_interrupt(void) + { + return true; + } +-extern void arch_irq_work_raise(void); ++ + #endif /* __ASM_CSKY_IRQ_WORK_H */ +diff --git a/arch/loongarch/kernel/asm-offsets.c b/arch/loongarch/kernel/asm-offsets.c +index 173fe514fc9ec..bee9f7a3108f0 100644 +--- a/arch/loongarch/kernel/asm-offsets.c ++++ b/arch/loongarch/kernel/asm-offsets.c +@@ -15,7 +15,7 @@ + #include <asm/processor.h> + #include <asm/ftrace.h> + +-void output_ptreg_defines(void) ++static void __used output_ptreg_defines(void) + { + COMMENT("LoongArch pt_regs offsets."); + OFFSET(PT_R0, pt_regs, regs[0]); +@@ -62,7 +62,7 @@ void output_ptreg_defines(void) + BLANK(); + } + +-void output_task_defines(void) ++static void __used output_task_defines(void) + { + COMMENT("LoongArch task_struct offsets."); + OFFSET(TASK_STATE, task_struct, __state); +@@ -77,7 +77,7 @@ void output_task_defines(void) + BLANK(); + } + +-void output_thread_info_defines(void) ++static void __used output_thread_info_defines(void) + { + COMMENT("LoongArch thread_info offsets."); + OFFSET(TI_TASK, thread_info, task); +@@ -93,7 +93,7 @@ void output_thread_info_defines(void) + BLANK(); + } + +-void output_thread_defines(void) ++static void __used output_thread_defines(void) + { + COMMENT("LoongArch specific thread_struct offsets."); + OFFSET(THREAD_REG01, task_struct, thread.reg01); +@@ -129,7 +129,7 @@ void output_thread_defines(void) + BLANK(); + } + +-void output_thread_fpu_defines(void) ++static void __used output_thread_fpu_defines(void) + { + OFFSET(THREAD_FPR0, loongarch_fpu, fpr[0]); + OFFSET(THREAD_FPR1, loongarch_fpu, fpr[1]); +@@ -170,7 +170,7 @@ void output_thread_fpu_defines(void) + BLANK(); + } + +-void output_thread_lbt_defines(void) ++static void __used output_thread_lbt_defines(void) + { + OFFSET(THREAD_SCR0, loongarch_lbt, scr0); + OFFSET(THREAD_SCR1, loongarch_lbt, scr1); +@@ -180,7 +180,7 @@ void output_thread_lbt_defines(void) + BLANK(); + } + +-void output_mm_defines(void) ++static void __used output_mm_defines(void) + { + COMMENT("Size of struct page"); + DEFINE(STRUCT_PAGE_SIZE, sizeof(struct page)); +@@ -212,7 +212,7 @@ void output_mm_defines(void) + BLANK(); + } + +-void output_sc_defines(void) ++static void __used output_sc_defines(void) + { + COMMENT("Linux sigcontext offsets."); + OFFSET(SC_REGS, sigcontext, sc_regs); +@@ -220,7 +220,7 @@ void output_sc_defines(void) + BLANK(); + } + +-void output_signal_defines(void) ++static void __used output_signal_defines(void) + { + COMMENT("Linux signal numbers."); + DEFINE(_SIGHUP, SIGHUP); +@@ -258,7 +258,7 @@ void output_signal_defines(void) + } + + #ifdef CONFIG_SMP +-void output_smpboot_defines(void) ++static void __used output_smpboot_defines(void) + { + COMMENT("Linux smp cpu boot offsets."); + OFFSET(CPU_BOOT_STACK, secondary_data, stack); +@@ -268,7 +268,7 @@ void output_smpboot_defines(void) + #endif + + #ifdef CONFIG_HIBERNATION +-void output_pbe_defines(void) ++static void __used output_pbe_defines(void) + { + COMMENT("Linux struct pbe offsets."); + OFFSET(PBE_ADDRESS, pbe, address); +@@ -280,7 +280,7 @@ void output_pbe_defines(void) + #endif + + #ifdef CONFIG_FUNCTION_GRAPH_TRACER +-void output_fgraph_ret_regs_defines(void) ++static void __used output_fgraph_ret_regs_defines(void) + { + COMMENT("LoongArch fgraph_ret_regs offsets."); + OFFSET(FGRET_REGS_A0, fgraph_ret_regs, regs[0]); +@@ -291,7 +291,7 @@ void output_fgraph_ret_regs_defines(void) + } + #endif + +-void output_kvm_defines(void) ++static void __used output_kvm_defines(void) + { + COMMENT("KVM/LoongArch Specific offsets."); + +diff --git a/arch/powerpc/crypto/aes-gcm-p10-glue.c b/arch/powerpc/crypto/aes-gcm-p10-glue.c +index 4b6e899895e7b..f62ee54076c06 100644 +--- a/arch/powerpc/crypto/aes-gcm-p10-glue.c ++++ b/arch/powerpc/crypto/aes-gcm-p10-glue.c +@@ -37,7 +37,7 @@ asmlinkage void aes_p10_gcm_encrypt(u8 *in, u8 *out, size_t len, + void *rkey, u8 *iv, void *Xi); + asmlinkage void aes_p10_gcm_decrypt(u8 *in, u8 *out, size_t len, + void *rkey, u8 *iv, void *Xi); +-asmlinkage void gcm_init_htable(unsigned char htable[256], unsigned char Xi[16]); ++asmlinkage void gcm_init_htable(unsigned char htable[], unsigned char Xi[]); + asmlinkage void gcm_ghash_p10(unsigned char *Xi, unsigned char *Htable, + unsigned char *aad, unsigned int alen); + +diff --git a/arch/powerpc/include/asm/irq_work.h b/arch/powerpc/include/asm/irq_work.h +index b8b0be8f1a07e..c6d3078bd8c3b 100644 +--- a/arch/powerpc/include/asm/irq_work.h ++++ b/arch/powerpc/include/asm/irq_work.h +@@ -6,6 +6,5 @@ static inline bool arch_irq_work_has_interrupt(void) + { + return true; + } +-extern void arch_irq_work_raise(void); + + #endif /* _ASM_POWERPC_IRQ_WORK_H */ +diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h +index 52cc25864a1be..d8b7e246a32f5 100644 +--- a/arch/powerpc/include/asm/mmu.h ++++ b/arch/powerpc/include/asm/mmu.h +@@ -412,5 +412,9 @@ extern void *abatron_pteptrs[2]; + #include <asm/nohash/mmu.h> + #endif + ++#if defined(CONFIG_FA_DUMP) || defined(CONFIG_PRESERVE_FA_DUMP) ++#define __HAVE_ARCH_RESERVED_KERNEL_PAGES ++#endif ++ + #endif /* __KERNEL__ */ + #endif /* _ASM_POWERPC_MMU_H_ */ +diff --git a/arch/powerpc/include/asm/mmzone.h b/arch/powerpc/include/asm/mmzone.h +index 4c6c6dbd182f4..da827d2d08666 100644 +--- a/arch/powerpc/include/asm/mmzone.h ++++ b/arch/powerpc/include/asm/mmzone.h +@@ -42,14 +42,6 @@ u64 memory_hotplug_max(void); + #else + #define memory_hotplug_max() memblock_end_of_DRAM() + #endif /* CONFIG_NUMA */ +-#ifdef CONFIG_FA_DUMP +-#define __HAVE_ARCH_RESERVED_KERNEL_PAGES +-#endif +- +-#ifdef CONFIG_MEMORY_HOTPLUG +-extern int create_section_mapping(unsigned long start, unsigned long end, +- int nid, pgprot_t prot); +-#endif + + #endif /* __KERNEL__ */ + #endif /* _ASM_MMZONE_H_ */ +diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c +index 5ea2014aff90d..11e062b47d3f8 100644 +--- a/arch/powerpc/kernel/traps.c ++++ b/arch/powerpc/kernel/traps.c +@@ -1439,10 +1439,12 @@ static int emulate_instruction(struct pt_regs *regs) + return -EINVAL; + } + ++#ifdef CONFIG_GENERIC_BUG + int is_valid_bugaddr(unsigned long addr) + { + return is_kernel_addr(addr); + } ++#endif + + #ifdef CONFIG_MATH_EMULATION + static int emulate_math(struct pt_regs *regs) +diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c +index a4ab8625061a6..6af97dc0f6d5a 100644 +--- a/arch/powerpc/lib/sstep.c ++++ b/arch/powerpc/lib/sstep.c +@@ -586,6 +586,8 @@ static int do_fp_load(struct instruction_op *op, unsigned long ea, + } u; + + nb = GETSIZE(op->type); ++ if (nb > sizeof(u)) ++ return -EINVAL; + if (!address_ok(regs, ea, nb)) + return -EFAULT; + rn = op->reg; +@@ -636,6 +638,8 @@ static int do_fp_store(struct instruction_op *op, unsigned long ea, + } u; + + nb = GETSIZE(op->type); ++ if (nb > sizeof(u)) ++ return -EINVAL; + if (!address_ok(regs, ea, nb)) + return -EFAULT; + rn = op->reg; +@@ -680,6 +684,9 @@ static nokprobe_inline int do_vec_load(int rn, unsigned long ea, + u8 b[sizeof(__vector128)]; + } u = {}; + ++ if (size > sizeof(u)) ++ return -EINVAL; ++ + if (!address_ok(regs, ea & ~0xfUL, 16)) + return -EFAULT; + /* align to multiple of size */ +@@ -707,6 +714,9 @@ static nokprobe_inline int do_vec_store(int rn, unsigned long ea, + u8 b[sizeof(__vector128)]; + } u; + ++ if (size > sizeof(u)) ++ return -EINVAL; ++ + if (!address_ok(regs, ea & ~0xfUL, 16)) + return -EFAULT; + /* align to multiple of size */ +diff --git a/arch/powerpc/mm/book3s64/pgtable.c b/arch/powerpc/mm/book3s64/pgtable.c +index be229290a6a77..3438ab72c346b 100644 +--- a/arch/powerpc/mm/book3s64/pgtable.c ++++ b/arch/powerpc/mm/book3s64/pgtable.c +@@ -542,6 +542,7 @@ void ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned long addr, + set_pte_at(vma->vm_mm, addr, ptep, pte); + } + ++#ifdef CONFIG_TRANSPARENT_HUGEPAGE + /* + * For hash translation mode, we use the deposited table to store hash slot + * information and they are stored at PTRS_PER_PMD offset from related pmd +@@ -563,6 +564,7 @@ int pmd_move_must_withdraw(struct spinlock *new_pmd_ptl, + + return true; + } ++#endif + + /* + * Does the CPU support tlbie? +diff --git a/arch/powerpc/mm/init-common.c b/arch/powerpc/mm/init-common.c +index 119ef491f7976..d3a7726ecf512 100644 +--- a/arch/powerpc/mm/init-common.c ++++ b/arch/powerpc/mm/init-common.c +@@ -126,7 +126,7 @@ void pgtable_cache_add(unsigned int shift) + * as to leave enough 0 bits in the address to contain it. */ + unsigned long minalign = max(MAX_PGTABLE_INDEX_SIZE + 1, + HUGEPD_SHIFT_MASK + 1); +- struct kmem_cache *new; ++ struct kmem_cache *new = NULL; + + /* It would be nice if this was a BUILD_BUG_ON(), but at the + * moment, gcc doesn't seem to recognize is_power_of_2 as a +@@ -139,7 +139,8 @@ void pgtable_cache_add(unsigned int shift) + + align = max_t(unsigned long, align, minalign); + name = kasprintf(GFP_KERNEL, "pgtable-2^%d", shift); +- new = kmem_cache_create(name, table_size, align, 0, ctor(shift)); ++ if (name) ++ new = kmem_cache_create(name, table_size, align, 0, ctor(shift)); + if (!new) + panic("Could not allocate pgtable cache for order %d", shift); + +diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h +index 7f9ff0640124a..72341b9fb5521 100644 +--- a/arch/powerpc/mm/mmu_decl.h ++++ b/arch/powerpc/mm/mmu_decl.h +@@ -181,3 +181,8 @@ static inline bool debug_pagealloc_enabled_or_kfence(void) + { + return IS_ENABLED(CONFIG_KFENCE) || debug_pagealloc_enabled(); + } ++ ++#ifdef CONFIG_MEMORY_HOTPLUG ++int create_section_mapping(unsigned long start, unsigned long end, ++ int nid, pgprot_t prot); ++#endif +diff --git a/arch/riscv/include/asm/irq_work.h b/arch/riscv/include/asm/irq_work.h +index b53891964ae03..b27a4d64fc6a0 100644 +--- a/arch/riscv/include/asm/irq_work.h ++++ b/arch/riscv/include/asm/irq_work.h +@@ -6,5 +6,5 @@ static inline bool arch_irq_work_has_interrupt(void) + { + return IS_ENABLED(CONFIG_SMP); + } +-extern void arch_irq_work_raise(void); ++ + #endif /* _ASM_RISCV_IRQ_WORK_H */ +diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S +index 76ace1e0b46f6..663881785b2b4 100644 +--- a/arch/riscv/kernel/head.S ++++ b/arch/riscv/kernel/head.S +@@ -89,6 +89,7 @@ relocate_enable_mmu: + /* Compute satp for kernel page tables, but don't load it yet */ + srl a2, a0, PAGE_SHIFT + la a1, satp_mode ++ XIP_FIXUP_OFFSET a1 + REG_L a1, 0(a1) + or a2, a2, a1 + +diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c +index 2e011cbddf3af..ad77ed410d4dd 100644 +--- a/arch/riscv/mm/init.c ++++ b/arch/riscv/mm/init.c +@@ -174,6 +174,9 @@ void __init mem_init(void) + + /* Limit the memory size via mem. */ + static phys_addr_t memory_limit; ++#ifdef CONFIG_XIP_KERNEL ++#define memory_limit (*(phys_addr_t *)XIP_FIXUP(&memory_limit)) ++#endif /* CONFIG_XIP_KERNEL */ + + static int __init early_mem(char *p) + { +@@ -952,7 +955,7 @@ static void __init create_fdt_early_page_table(uintptr_t fix_fdt_va, + * setup_vm_final installs the linear mapping. For 32-bit kernel, as the + * kernel is mapped in the linear mapping, that makes no difference. + */ +- dtb_early_va = kernel_mapping_pa_to_va(XIP_FIXUP(dtb_pa)); ++ dtb_early_va = kernel_mapping_pa_to_va(dtb_pa); + #endif + + dtb_early_pa = dtb_pa; +@@ -1055,9 +1058,13 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa) + #endif + + kernel_map.virt_addr = KERNEL_LINK_ADDR + kernel_map.virt_offset; +- kernel_map.page_offset = _AC(CONFIG_PAGE_OFFSET, UL); + + #ifdef CONFIG_XIP_KERNEL ++#ifdef CONFIG_64BIT ++ kernel_map.page_offset = PAGE_OFFSET_L3; ++#else ++ kernel_map.page_offset = _AC(CONFIG_PAGE_OFFSET, UL); ++#endif + kernel_map.xiprom = (uintptr_t)CONFIG_XIP_PHYS_ADDR; + kernel_map.xiprom_sz = (uintptr_t)(&_exiprom) - (uintptr_t)(&_xiprom); + +@@ -1067,6 +1074,7 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa) + + kernel_map.va_kernel_xip_pa_offset = kernel_map.virt_addr - kernel_map.xiprom; + #else ++ kernel_map.page_offset = _AC(CONFIG_PAGE_OFFSET, UL); + kernel_map.phys_addr = (uintptr_t)(&_start); + kernel_map.size = (uintptr_t)(&_end) - kernel_map.phys_addr; + #endif +diff --git a/arch/s390/boot/ipl_parm.c b/arch/s390/boot/ipl_parm.c +index 2ab4872fbee1c..b24de9aabf7d8 100644 +--- a/arch/s390/boot/ipl_parm.c ++++ b/arch/s390/boot/ipl_parm.c +@@ -274,7 +274,7 @@ void parse_boot_command_line(void) + memory_limit = round_down(memparse(val, NULL), PAGE_SIZE); + + if (!strcmp(param, "vmalloc") && val) { +- vmalloc_size = round_up(memparse(val, NULL), PAGE_SIZE); ++ vmalloc_size = round_up(memparse(val, NULL), _SEGMENT_SIZE); + vmalloc_size_set = 1; + } + +diff --git a/arch/s390/boot/startup.c b/arch/s390/boot/startup.c +index 8104e0e3d188d..9cc76e631759b 100644 +--- a/arch/s390/boot/startup.c ++++ b/arch/s390/boot/startup.c +@@ -255,7 +255,8 @@ static unsigned long setup_kernel_memory_layout(void) + VMALLOC_END = MODULES_VADDR; + + /* allow vmalloc area to occupy up to about 1/2 of the rest virtual space left */ +- vmalloc_size = min(vmalloc_size, round_down(VMALLOC_END / 2, _REGION3_SIZE)); ++ vsize = round_down(VMALLOC_END / 2, _SEGMENT_SIZE); ++ vmalloc_size = min(vmalloc_size, vsize); + VMALLOC_START = VMALLOC_END - vmalloc_size; + + /* split remaining virtual space between 1:1 mapping & vmemmap array */ +diff --git a/arch/s390/include/asm/irq_work.h b/arch/s390/include/asm/irq_work.h +index 603783766d0ab..f00c9f610d5a8 100644 +--- a/arch/s390/include/asm/irq_work.h ++++ b/arch/s390/include/asm/irq_work.h +@@ -7,6 +7,4 @@ static inline bool arch_irq_work_has_interrupt(void) + return true; + } + +-void arch_irq_work_raise(void); +- + #endif /* _ASM_S390_IRQ_WORK_H */ +diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c +index 046403471c5d7..c7ed302a6b59e 100644 +--- a/arch/s390/kernel/ptrace.c ++++ b/arch/s390/kernel/ptrace.c +@@ -392,6 +392,7 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data) + /* + * floating point control reg. is in the thread structure + */ ++ save_fpu_regs(); + if ((unsigned int) data != 0 || + test_fp_ctl(data >> (BITS_PER_LONG - 32))) + return -EINVAL; +@@ -748,6 +749,7 @@ static int __poke_user_compat(struct task_struct *child, + /* + * floating point control reg. is in the thread structure + */ ++ save_fpu_regs(); + if (test_fp_ctl(tmp)) + return -EINVAL; + child->thread.fpu.fpc = data; +@@ -911,9 +913,7 @@ static int s390_fpregs_set(struct task_struct *target, + int rc = 0; + freg_t fprs[__NUM_FPRS]; + +- if (target == current) +- save_fpu_regs(); +- ++ save_fpu_regs(); + if (MACHINE_HAS_VX) + convert_vx_to_fp(fprs, target->thread.fpu.vxrs); + else +diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c +index 7aa0e668488f0..16e32174807f7 100644 +--- a/arch/s390/kvm/kvm-s390.c ++++ b/arch/s390/kvm/kvm-s390.c +@@ -4316,10 +4316,6 @@ int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) + + vcpu_load(vcpu); + +- if (test_fp_ctl(fpu->fpc)) { +- ret = -EINVAL; +- goto out; +- } + vcpu->run->s.regs.fpc = fpu->fpc; + if (MACHINE_HAS_VX) + convert_fp_to_vx((__vector128 *) vcpu->run->s.regs.vrs, +@@ -4327,7 +4323,6 @@ int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) + else + memcpy(vcpu->run->s.regs.fprs, &fpu->fprs, sizeof(fpu->fprs)); + +-out: + vcpu_put(vcpu); + return ret; + } +diff --git a/arch/sparc/kernel/asm-offsets.c b/arch/sparc/kernel/asm-offsets.c +index 5784f2df489a4..3d9b9855dce91 100644 +--- a/arch/sparc/kernel/asm-offsets.c ++++ b/arch/sparc/kernel/asm-offsets.c +@@ -19,14 +19,14 @@ + #include <asm/hibernate.h> + + #ifdef CONFIG_SPARC32 +-int sparc32_foo(void) ++static int __used sparc32_foo(void) + { + DEFINE(AOFF_thread_fork_kpsr, + offsetof(struct thread_struct, fork_kpsr)); + return 0; + } + #else +-int sparc64_foo(void) ++static int __used sparc64_foo(void) + { + #ifdef CONFIG_HIBERNATION + BLANK(); +@@ -45,7 +45,7 @@ int sparc64_foo(void) + } + #endif + +-int foo(void) ++static int __used foo(void) + { + BLANK(); + DEFINE(AOFF_task_thread, offsetof(struct task_struct, thread)); +diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c +index 3d7836c465070..cabcc501b448a 100644 +--- a/arch/um/drivers/net_kern.c ++++ b/arch/um/drivers/net_kern.c +@@ -204,7 +204,7 @@ static int uml_net_close(struct net_device *dev) + return 0; + } + +-static int uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev) ++static netdev_tx_t uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev) + { + struct uml_net_private *lp = netdev_priv(dev); + unsigned long flags; +diff --git a/arch/um/include/shared/kern_util.h b/arch/um/include/shared/kern_util.h +index d8b8b4f07e429..444bae755b16a 100644 +--- a/arch/um/include/shared/kern_util.h ++++ b/arch/um/include/shared/kern_util.h +@@ -50,7 +50,7 @@ extern void do_uml_exitcalls(void); + * Are we disallowed to sleep? Used to choose between GFP_KERNEL and + * GFP_ATOMIC. + */ +-extern int __cant_sleep(void); ++extern int __uml_cant_sleep(void); + extern int get_current_pid(void); + extern int copy_from_user_proc(void *to, void *from, int size); + extern char *uml_strdup(const char *string); +diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c +index 106b7da2f8d6f..6daffb9d8a8d7 100644 +--- a/arch/um/kernel/process.c ++++ b/arch/um/kernel/process.c +@@ -220,7 +220,7 @@ void arch_cpu_idle(void) + um_idle_sleep(); + } + +-int __cant_sleep(void) { ++int __uml_cant_sleep(void) { + return in_atomic() || irqs_disabled() || in_interrupt(); + /* Is in_interrupt() really needed? */ + } +diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c +index fddd1dec27e6d..3e270da6b6f67 100644 +--- a/arch/um/kernel/time.c ++++ b/arch/um/kernel/time.c +@@ -432,9 +432,29 @@ static void time_travel_update_time(unsigned long long next, bool idle) + time_travel_del_event(&ne); + } + ++static void time_travel_update_time_rel(unsigned long long offs) ++{ ++ unsigned long flags; ++ ++ /* ++ * Disable interrupts before calculating the new time so ++ * that a real timer interrupt (signal) can't happen at ++ * a bad time e.g. after we read time_travel_time but ++ * before we've completed updating the time. ++ */ ++ local_irq_save(flags); ++ time_travel_update_time(time_travel_time + offs, false); ++ local_irq_restore(flags); ++} ++ + void time_travel_ndelay(unsigned long nsec) + { +- time_travel_update_time(time_travel_time + nsec, false); ++ /* ++ * Not strictly needed to use _rel() version since this is ++ * only used in INFCPU/EXT modes, but it doesn't hurt and ++ * is more readable too. ++ */ ++ time_travel_update_time_rel(nsec); + } + EXPORT_SYMBOL(time_travel_ndelay); + +@@ -568,7 +588,11 @@ static void time_travel_set_start(void) + #define time_travel_time 0 + #define time_travel_ext_waiting 0 + +-static inline void time_travel_update_time(unsigned long long ns, bool retearly) ++static inline void time_travel_update_time(unsigned long long ns, bool idle) ++{ ++} ++ ++static inline void time_travel_update_time_rel(unsigned long long offs) + { + } + +@@ -720,9 +744,7 @@ static u64 timer_read(struct clocksource *cs) + */ + if (!irqs_disabled() && !in_interrupt() && !in_softirq() && + !time_travel_ext_waiting) +- time_travel_update_time(time_travel_time + +- TIMER_MULTIPLIER, +- false); ++ time_travel_update_time_rel(TIMER_MULTIPLIER); + return time_travel_time / TIMER_MULTIPLIER; + } + +diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c +index b459745f52e24..3cb8ac63be6ed 100644 +--- a/arch/um/os-Linux/helper.c ++++ b/arch/um/os-Linux/helper.c +@@ -46,7 +46,7 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv) + unsigned long stack, sp; + int pid, fds[2], ret, n; + +- stack = alloc_stack(0, __cant_sleep()); ++ stack = alloc_stack(0, __uml_cant_sleep()); + if (stack == 0) + return -ENOMEM; + +@@ -70,7 +70,7 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv) + data.pre_data = pre_data; + data.argv = argv; + data.fd = fds[1]; +- data.buf = __cant_sleep() ? uml_kmalloc(PATH_MAX, UM_GFP_ATOMIC) : ++ data.buf = __uml_cant_sleep() ? uml_kmalloc(PATH_MAX, UM_GFP_ATOMIC) : + uml_kmalloc(PATH_MAX, UM_GFP_KERNEL); + pid = clone(helper_child, (void *) sp, CLONE_VM, &data); + if (pid < 0) { +@@ -121,7 +121,7 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, + unsigned long stack, sp; + int pid, status, err; + +- stack = alloc_stack(0, __cant_sleep()); ++ stack = alloc_stack(0, __uml_cant_sleep()); + if (stack == 0) + return -ENOMEM; + +diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c +index fc0f2a9dee5af..1dca4ffbd572f 100644 +--- a/arch/um/os-Linux/util.c ++++ b/arch/um/os-Linux/util.c +@@ -173,23 +173,38 @@ __uml_setup("quiet", quiet_cmd_param, + "quiet\n" + " Turns off information messages during boot.\n\n"); + ++/* ++ * The os_info/os_warn functions will be called by helper threads. These ++ * have a very limited stack size and using the libc formatting functions ++ * may overflow the stack. ++ * So pull in the kernel vscnprintf and use that instead with a fixed ++ * on-stack buffer. ++ */ ++int vscnprintf(char *buf, size_t size, const char *fmt, va_list args); ++ + void os_info(const char *fmt, ...) + { ++ char buf[256]; + va_list list; ++ int len; + + if (quiet_info) + return; + + va_start(list, fmt); +- vfprintf(stderr, fmt, list); ++ len = vscnprintf(buf, sizeof(buf), fmt, list); ++ fwrite(buf, len, 1, stderr); + va_end(list); + } + + void os_warn(const char *fmt, ...) + { ++ char buf[256]; + va_list list; ++ int len; + + va_start(list, fmt); +- vfprintf(stderr, fmt, list); ++ len = vscnprintf(buf, sizeof(buf), fmt, list); ++ fwrite(buf, len, 1, stderr); + va_end(list); + } +diff --git a/arch/x86/boot/compressed/ident_map_64.c b/arch/x86/boot/compressed/ident_map_64.c +index 473ba59b82a81..d040080d7edbd 100644 +--- a/arch/x86/boot/compressed/ident_map_64.c ++++ b/arch/x86/boot/compressed/ident_map_64.c +@@ -386,3 +386,8 @@ void do_boot_page_fault(struct pt_regs *regs, unsigned long error_code) + */ + kernel_add_identity_map(address, end); + } ++ ++void do_boot_nmi_trap(struct pt_regs *regs, unsigned long error_code) ++{ ++ /* Empty handler to ignore NMI during early boot */ ++} +diff --git a/arch/x86/boot/compressed/idt_64.c b/arch/x86/boot/compressed/idt_64.c +index 3cdf94b414567..d100284bbef47 100644 +--- a/arch/x86/boot/compressed/idt_64.c ++++ b/arch/x86/boot/compressed/idt_64.c +@@ -61,6 +61,7 @@ void load_stage2_idt(void) + boot_idt_desc.address = (unsigned long)boot_idt; + + set_idt_entry(X86_TRAP_PF, boot_page_fault); ++ set_idt_entry(X86_TRAP_NMI, boot_nmi_trap); + + #ifdef CONFIG_AMD_MEM_ENCRYPT + /* +diff --git a/arch/x86/boot/compressed/idt_handlers_64.S b/arch/x86/boot/compressed/idt_handlers_64.S +index 22890e199f5b4..4d03c8562f637 100644 +--- a/arch/x86/boot/compressed/idt_handlers_64.S ++++ b/arch/x86/boot/compressed/idt_handlers_64.S +@@ -70,6 +70,7 @@ SYM_FUNC_END(\name) + .code64 + + EXCEPTION_HANDLER boot_page_fault do_boot_page_fault error_code=1 ++EXCEPTION_HANDLER boot_nmi_trap do_boot_nmi_trap error_code=0 + + #ifdef CONFIG_AMD_MEM_ENCRYPT + EXCEPTION_HANDLER boot_stage1_vc do_vc_no_ghcb error_code=1 +diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h +index c0d502bd87161..bc2f0f17fb90e 100644 +--- a/arch/x86/boot/compressed/misc.h ++++ b/arch/x86/boot/compressed/misc.h +@@ -196,6 +196,7 @@ static inline void cleanup_exception_handling(void) { } + + /* IDT Entry Points */ + void boot_page_fault(void); ++void boot_nmi_trap(void); + void boot_stage1_vc(void); + void boot_stage2_vc(void); + +diff --git a/arch/x86/include/asm/irq_work.h b/arch/x86/include/asm/irq_work.h +index 800ffce0db29e..6b4d36c951655 100644 +--- a/arch/x86/include/asm/irq_work.h ++++ b/arch/x86/include/asm/irq_work.h +@@ -9,7 +9,6 @@ static inline bool arch_irq_work_has_interrupt(void) + { + return boot_cpu_has(X86_FEATURE_APIC); + } +-extern void arch_irq_work_raise(void); + #else + static inline bool arch_irq_work_has_interrupt(void) + { +diff --git a/arch/x86/include/asm/kmsan.h b/arch/x86/include/asm/kmsan.h +index 8fa6ac0e2d766..d91b37f5b4bb4 100644 +--- a/arch/x86/include/asm/kmsan.h ++++ b/arch/x86/include/asm/kmsan.h +@@ -64,6 +64,7 @@ static inline bool kmsan_virt_addr_valid(void *addr) + { + unsigned long x = (unsigned long)addr; + unsigned long y = x - __START_KERNEL_map; ++ bool ret; + + /* use the carry flag to determine if x was < __START_KERNEL_map */ + if (unlikely(x > y)) { +@@ -79,7 +80,21 @@ static inline bool kmsan_virt_addr_valid(void *addr) + return false; + } + +- return pfn_valid(x >> PAGE_SHIFT); ++ /* ++ * pfn_valid() relies on RCU, and may call into the scheduler on exiting ++ * the critical section. However, this would result in recursion with ++ * KMSAN. Therefore, disable preemption here, and re-enable preemption ++ * below while suppressing reschedules to avoid recursion. ++ * ++ * Note, this sacrifices occasionally breaking scheduling guarantees. ++ * Although, a kernel compiled with KMSAN has already given up on any ++ * performance guarantees due to being heavily instrumented. ++ */ ++ preempt_disable(); ++ ret = pfn_valid(x >> PAGE_SHIFT); ++ preempt_enable_no_resched(); ++ ++ return ret; + } + + #endif /* !MODULE */ +diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c +index 7b397370b4d64..df8d25e744d10 100644 +--- a/arch/x86/kernel/cpu/mce/core.c ++++ b/arch/x86/kernel/cpu/mce/core.c +@@ -44,6 +44,7 @@ + #include <linux/sync_core.h> + #include <linux/task_work.h> + #include <linux/hardirq.h> ++#include <linux/kexec.h> + + #include <asm/intel-family.h> + #include <asm/processor.h> +@@ -233,6 +234,7 @@ static noinstr void mce_panic(const char *msg, struct mce *final, char *exp) + struct llist_node *pending; + struct mce_evt_llist *l; + int apei_err = 0; ++ struct page *p; + + /* + * Allow instrumentation around external facilities usage. Not that it +@@ -286,6 +288,20 @@ static noinstr void mce_panic(const char *msg, struct mce *final, char *exp) + if (!fake_panic) { + if (panic_timeout == 0) + panic_timeout = mca_cfg.panic_timeout; ++ ++ /* ++ * Kdump skips the poisoned page in order to avoid ++ * touching the error bits again. Poison the page even ++ * if the error is fatal and the machine is about to ++ * panic. ++ */ ++ if (kexec_crash_loaded()) { ++ if (final && (final->status & MCI_STATUS_ADDRV)) { ++ p = pfn_to_online_page(final->addr >> PAGE_SHIFT); ++ if (p) ++ SetPageHWPoison(p); ++ } ++ } + panic(msg); + } else + pr_emerg(HW_ERR "Fake kernel panic: %s\n", msg); +diff --git a/block/bio.c b/block/bio.c +index 5eba53ca953b4..270f6b99926ea 100644 +--- a/block/bio.c ++++ b/block/bio.c +@@ -944,7 +944,7 @@ bool bvec_try_merge_hw_page(struct request_queue *q, struct bio_vec *bv, + + if ((addr1 | mask) != (addr2 | mask)) + return false; +- if (bv->bv_len + len > queue_max_segment_size(q)) ++ if (len > queue_max_segment_size(q) - bv->bv_len) + return false; + return bvec_try_merge_page(bv, page, len, offset, same_page); + } +diff --git a/block/blk-mq.c b/block/blk-mq.c +index 7e743ac58c31d..a71974a5e57cd 100644 +--- a/block/blk-mq.c ++++ b/block/blk-mq.c +@@ -1858,6 +1858,22 @@ static bool blk_mq_mark_tag_wait(struct blk_mq_hw_ctx *hctx, + wait->flags &= ~WQ_FLAG_EXCLUSIVE; + __add_wait_queue(wq, wait); + ++ /* ++ * Add one explicit barrier since blk_mq_get_driver_tag() may ++ * not imply barrier in case of failure. ++ * ++ * Order adding us to wait queue and allocating driver tag. ++ * ++ * The pair is the one implied in sbitmap_queue_wake_up() which ++ * orders clearing sbitmap tag bits and waitqueue_active() in ++ * __sbitmap_queue_wake_up(), since waitqueue_active() is lockless ++ * ++ * Otherwise, re-order of adding wait queue and getting driver tag ++ * may cause __sbitmap_queue_wake_up() to wake up nothing because ++ * the waitqueue_active() may not observe us in wait queue. ++ */ ++ smp_mb(); ++ + /* + * It's possible that a tag was freed in the window between the + * allocation failure and adding the hardware queue to the wait +diff --git a/drivers/accel/habanalabs/common/device.c b/drivers/accel/habanalabs/common/device.c +index 9711e8fc979d9..9290d43745519 100644 +--- a/drivers/accel/habanalabs/common/device.c ++++ b/drivers/accel/habanalabs/common/device.c +@@ -853,6 +853,9 @@ static int device_early_init(struct hl_device *hdev) + gaudi2_set_asic_funcs(hdev); + strscpy(hdev->asic_name, "GAUDI2B", sizeof(hdev->asic_name)); + break; ++ case ASIC_GAUDI2C: ++ gaudi2_set_asic_funcs(hdev); ++ strscpy(hdev->asic_name, "GAUDI2C", sizeof(hdev->asic_name)); + break; + default: + dev_err(hdev->dev, "Unrecognized ASIC type %d\n", +@@ -1041,18 +1044,19 @@ static bool is_pci_link_healthy(struct hl_device *hdev) + return (vendor_id == PCI_VENDOR_ID_HABANALABS); + } + +-static void hl_device_eq_heartbeat(struct hl_device *hdev) ++static int hl_device_eq_heartbeat_check(struct hl_device *hdev) + { +- u64 event_mask = HL_NOTIFIER_EVENT_DEVICE_RESET | HL_NOTIFIER_EVENT_DEVICE_UNAVAILABLE; + struct asic_fixed_properties *prop = &hdev->asic_prop; + + if (!prop->cpucp_info.eq_health_check_supported) +- return; ++ return 0; + + if (hdev->eq_heartbeat_received) + hdev->eq_heartbeat_received = false; + else +- hl_device_cond_reset(hdev, HL_DRV_RESET_HARD, event_mask); ++ return -EIO; ++ ++ return 0; + } + + static void hl_device_heartbeat(struct work_struct *work) +@@ -1069,10 +1073,9 @@ static void hl_device_heartbeat(struct work_struct *work) + /* + * For EQ health check need to check if driver received the heartbeat eq event + * in order to validate the eq is working. ++ * Only if both the EQ is healthy and we managed to send the next heartbeat reschedule. + */ +- hl_device_eq_heartbeat(hdev); +- +- if (!hdev->asic_funcs->send_heartbeat(hdev)) ++ if ((!hl_device_eq_heartbeat_check(hdev)) && (!hdev->asic_funcs->send_heartbeat(hdev))) + goto reschedule; + + if (hl_device_operational(hdev, NULL)) +diff --git a/drivers/accel/habanalabs/common/habanalabs.h b/drivers/accel/habanalabs/common/habanalabs.h +index 1655c101c7052..d0fd77bb6a749 100644 +--- a/drivers/accel/habanalabs/common/habanalabs.h ++++ b/drivers/accel/habanalabs/common/habanalabs.h +@@ -1262,6 +1262,7 @@ struct hl_dec { + * @ASIC_GAUDI_SEC: Gaudi secured device (HL-2000). + * @ASIC_GAUDI2: Gaudi2 device. + * @ASIC_GAUDI2B: Gaudi2B device. ++ * @ASIC_GAUDI2C: Gaudi2C device. + */ + enum hl_asic_type { + ASIC_INVALID, +@@ -1270,6 +1271,7 @@ enum hl_asic_type { + ASIC_GAUDI_SEC, + ASIC_GAUDI2, + ASIC_GAUDI2B, ++ ASIC_GAUDI2C, + }; + + struct hl_cs_parser; +diff --git a/drivers/accel/habanalabs/common/habanalabs_drv.c b/drivers/accel/habanalabs/common/habanalabs_drv.c +index 306a5bc9bf894..51fb04bbe376f 100644 +--- a/drivers/accel/habanalabs/common/habanalabs_drv.c ++++ b/drivers/accel/habanalabs/common/habanalabs_drv.c +@@ -141,6 +141,9 @@ static enum hl_asic_type get_asic_type(struct hl_device *hdev) + case REV_ID_B: + asic_type = ASIC_GAUDI2B; + break; ++ case REV_ID_C: ++ asic_type = ASIC_GAUDI2C; ++ break; + default: + break; + } +diff --git a/drivers/accel/habanalabs/common/mmu/mmu.c b/drivers/accel/habanalabs/common/mmu/mmu.c +index b2145716c6053..b654302a68fc0 100644 +--- a/drivers/accel/habanalabs/common/mmu/mmu.c ++++ b/drivers/accel/habanalabs/common/mmu/mmu.c +@@ -596,6 +596,7 @@ int hl_mmu_if_set_funcs(struct hl_device *hdev) + break; + case ASIC_GAUDI2: + case ASIC_GAUDI2B: ++ case ASIC_GAUDI2C: + /* MMUs in Gaudi2 are always host resident */ + hl_mmu_v2_hr_set_funcs(hdev, &hdev->mmu_func[MMU_HR_PGT]); + break; +diff --git a/drivers/accel/habanalabs/common/sysfs.c b/drivers/accel/habanalabs/common/sysfs.c +index 01f89f029355e..2786063730555 100644 +--- a/drivers/accel/habanalabs/common/sysfs.c ++++ b/drivers/accel/habanalabs/common/sysfs.c +@@ -251,6 +251,9 @@ static ssize_t device_type_show(struct device *dev, + case ASIC_GAUDI2B: + str = "GAUDI2B"; + break; ++ case ASIC_GAUDI2C: ++ str = "GAUDI2C"; ++ break; + default: + dev_err(hdev->dev, "Unrecognized ASIC type %d\n", + hdev->asic_type); +diff --git a/drivers/accel/habanalabs/gaudi2/gaudi2.c b/drivers/accel/habanalabs/gaudi2/gaudi2.c +index 819660c684cfc..bc6e338ef2fd6 100644 +--- a/drivers/accel/habanalabs/gaudi2/gaudi2.c ++++ b/drivers/accel/habanalabs/gaudi2/gaudi2.c +@@ -7929,21 +7929,19 @@ static int gaudi2_handle_qman_err_generic(struct hl_device *hdev, u16 event_type + error_count++; + } + +- if (i == QMAN_STREAMS && error_count) { +- /* check for undefined opcode */ +- if (glbl_sts_val & PDMA0_QM_GLBL_ERR_STS_CP_UNDEF_CMD_ERR_MASK && +- hdev->captured_err_info.undef_opcode.write_enable) { ++ /* check for undefined opcode */ ++ if (glbl_sts_val & PDMA0_QM_GLBL_ERR_STS_CP_UNDEF_CMD_ERR_MASK) { ++ *event_mask |= HL_NOTIFIER_EVENT_UNDEFINED_OPCODE; ++ if (hdev->captured_err_info.undef_opcode.write_enable) { + memset(&hdev->captured_err_info.undef_opcode, 0, + sizeof(hdev->captured_err_info.undef_opcode)); +- +- hdev->captured_err_info.undef_opcode.write_enable = false; + hdev->captured_err_info.undef_opcode.timestamp = ktime_get(); + hdev->captured_err_info.undef_opcode.engine_id = + gaudi2_queue_id_to_engine_id[qid_base]; +- *event_mask |= HL_NOTIFIER_EVENT_UNDEFINED_OPCODE; + } + +- handle_lower_qman_data_on_err(hdev, qman_base, *event_mask); ++ if (i == QMAN_STREAMS) ++ handle_lower_qman_data_on_err(hdev, qman_base, *event_mask); + } + } + +diff --git a/drivers/accel/habanalabs/include/hw_ip/pci/pci_general.h b/drivers/accel/habanalabs/include/hw_ip/pci/pci_general.h +index f5d497dc9bdc1..4f951cada0776 100644 +--- a/drivers/accel/habanalabs/include/hw_ip/pci/pci_general.h ++++ b/drivers/accel/habanalabs/include/hw_ip/pci/pci_general.h +@@ -25,6 +25,7 @@ enum hl_revision_id { + REV_ID_INVALID = 0x00, + REV_ID_A = 0x01, + REV_ID_B = 0x02, ++ REV_ID_C = 0x03 + }; + + #endif /* INCLUDE_PCI_GENERAL_H_ */ +diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c +index 71e8d4e7a36cc..ca87a09391359 100644 +--- a/drivers/acpi/acpi_extlog.c ++++ b/drivers/acpi/acpi_extlog.c +@@ -308,9 +308,10 @@ err: + static void __exit extlog_exit(void) + { + mce_unregister_decode_chain(&extlog_mce_dec); +- ((struct extlog_l1_head *)extlog_l1_addr)->flags &= ~FLAG_OS_OPTIN; +- if (extlog_l1_addr) ++ if (extlog_l1_addr) { ++ ((struct extlog_l1_head *)extlog_l1_addr)->flags &= ~FLAG_OS_OPTIN; + acpi_os_unmap_iomem(extlog_l1_addr, l1_size); ++ } + if (elog_addr) + acpi_os_unmap_iomem(elog_addr, elog_size); + release_mem_region(elog_base, elog_size); +diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c +index 375010e575d0e..33ddb447747ea 100644 +--- a/drivers/acpi/acpi_video.c ++++ b/drivers/acpi/acpi_video.c +@@ -500,6 +500,15 @@ static const struct dmi_system_id video_dmi_table[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3350"), + }, + }, ++ { ++ .callback = video_set_report_key_events, ++ .driver_data = (void *)((uintptr_t)REPORT_BRIGHTNESS_KEY_EVENTS), ++ .ident = "COLORFUL X15 AT 23", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "COLORFUL"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "X15 AT 23"), ++ }, ++ }, + /* + * Some machines change the brightness themselves when a brightness + * hotkey gets pressed, despite us telling them not to. In this case +diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c +index 63ad0541db381..ab2a82cb1b0b4 100644 +--- a/drivers/acpi/apei/ghes.c ++++ b/drivers/acpi/apei/ghes.c +@@ -101,6 +101,20 @@ static inline bool is_hest_type_generic_v2(struct ghes *ghes) + return ghes->generic->header.type == ACPI_HEST_TYPE_GENERIC_ERROR_V2; + } + ++/* ++ * A platform may describe one error source for the handling of synchronous ++ * errors (e.g. MCE or SEA), or for handling asynchronous errors (e.g. SCI ++ * or External Interrupt). On x86, the HEST notifications are always ++ * asynchronous, so only SEA on ARM is delivered as a synchronous ++ * notification. ++ */ ++static inline bool is_hest_sync_notify(struct ghes *ghes) ++{ ++ u8 notify_type = ghes->generic->notify.type; ++ ++ return notify_type == ACPI_HEST_NOTIFY_SEA; ++} ++ + /* + * This driver isn't really modular, however for the time being, + * continuing to use module_param is the easiest way to remain +@@ -489,7 +503,7 @@ static bool ghes_do_memory_failure(u64 physical_addr, int flags) + } + + static bool ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, +- int sev) ++ int sev, bool sync) + { + int flags = -1; + int sec_sev = ghes_severity(gdata->error_severity); +@@ -503,7 +517,7 @@ static bool ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, + (gdata->flags & CPER_SEC_ERROR_THRESHOLD_EXCEEDED)) + flags = MF_SOFT_OFFLINE; + if (sev == GHES_SEV_RECOVERABLE && sec_sev == GHES_SEV_RECOVERABLE) +- flags = 0; ++ flags = sync ? MF_ACTION_REQUIRED : 0; + + if (flags != -1) + return ghes_do_memory_failure(mem_err->physical_addr, flags); +@@ -511,9 +525,11 @@ static bool ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, + return false; + } + +-static bool ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata, int sev) ++static bool ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata, ++ int sev, bool sync) + { + struct cper_sec_proc_arm *err = acpi_hest_get_payload(gdata); ++ int flags = sync ? MF_ACTION_REQUIRED : 0; + bool queued = false; + int sec_sev, i; + char *p; +@@ -538,7 +554,7 @@ static bool ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata, int s + * and don't filter out 'corrected' error here. + */ + if (is_cache && has_pa) { +- queued = ghes_do_memory_failure(err_info->physical_fault_addr, 0); ++ queued = ghes_do_memory_failure(err_info->physical_fault_addr, flags); + p += err_info->length; + continue; + } +@@ -666,6 +682,7 @@ static bool ghes_do_proc(struct ghes *ghes, + const guid_t *fru_id = &guid_null; + char *fru_text = ""; + bool queued = false; ++ bool sync = is_hest_sync_notify(ghes); + + sev = ghes_severity(estatus->error_severity); + apei_estatus_for_each_section(estatus, gdata) { +@@ -683,13 +700,13 @@ static bool ghes_do_proc(struct ghes *ghes, + atomic_notifier_call_chain(&ghes_report_chain, sev, mem_err); + + arch_apei_report_mem_error(sev, mem_err); +- queued = ghes_handle_memory_failure(gdata, sev); ++ queued = ghes_handle_memory_failure(gdata, sev, sync); + } + else if (guid_equal(sec_type, &CPER_SEC_PCIE)) { + ghes_handle_aer(gdata); + } + else if (guid_equal(sec_type, &CPER_SEC_PROC_ARM)) { +- queued = ghes_handle_arm_hw_error(gdata, sev); ++ queued = ghes_handle_arm_hw_error(gdata, sev, sync); + } else { + void *err = acpi_hest_get_payload(gdata); + +diff --git a/drivers/acpi/numa/srat.c b/drivers/acpi/numa/srat.c +index 12f330b0eac01..b57de78fbf14f 100644 +--- a/drivers/acpi/numa/srat.c ++++ b/drivers/acpi/numa/srat.c +@@ -183,7 +183,7 @@ static int __init slit_valid(struct acpi_table_slit *slit) + int i, j; + int d = slit->locality_count; + for (i = 0; i < d; i++) { +- for (j = 0; j < d; j++) { ++ for (j = 0; j < d; j++) { + u8 val = slit->entry[d*i + j]; + if (i == j) { + if (val != LOCAL_DISTANCE) +@@ -532,7 +532,7 @@ int __init acpi_numa_init(void) + */ + + /* fake_pxm is the next unused PXM value after SRAT parsing */ +- for (i = 0, fake_pxm = -1; i < MAX_NUMNODES - 1; i++) { ++ for (i = 0, fake_pxm = -1; i < MAX_NUMNODES; i++) { + if (node_to_pxm_map[i] > fake_pxm) + fake_pxm = node_to_pxm_map[i]; + } +diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c +index c3536c236be99..03b52d31a3e3f 100644 +--- a/drivers/acpi/resource.c ++++ b/drivers/acpi/resource.c +@@ -461,6 +461,13 @@ static const struct dmi_system_id irq1_level_low_skip_override[] = { + DMI_MATCH(DMI_BOARD_NAME, "B1502CBA"), + }, + }, ++ { ++ /* Asus ExpertBook B1502CGA */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), ++ DMI_MATCH(DMI_BOARD_NAME, "B1502CGA"), ++ }, ++ }, + { + /* Asus ExpertBook B2402CBA */ + .matches = { +@@ -482,6 +489,20 @@ static const struct dmi_system_id irq1_level_low_skip_override[] = { + DMI_MATCH(DMI_BOARD_NAME, "B2502CBA"), + }, + }, ++ { ++ /* Asus Vivobook E1504GA */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), ++ DMI_MATCH(DMI_BOARD_NAME, "E1504GA"), ++ }, ++ }, ++ { ++ /* Asus Vivobook E1504GAB */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), ++ DMI_MATCH(DMI_BOARD_NAME, "E1504GAB"), ++ }, ++ }, + { + /* LG Electronics 17U70P */ + .matches = { +diff --git a/drivers/base/arch_numa.c b/drivers/base/arch_numa.c +index eaa31e567d1ec..5b59d133b6af4 100644 +--- a/drivers/base/arch_numa.c ++++ b/drivers/base/arch_numa.c +@@ -144,7 +144,7 @@ void __init early_map_cpu_to_node(unsigned int cpu, int nid) + unsigned long __per_cpu_offset[NR_CPUS] __read_mostly; + EXPORT_SYMBOL(__per_cpu_offset); + +-static int __init early_cpu_to_node(int cpu) ++int __init early_cpu_to_node(int cpu) + { + return cpu_to_node_map[cpu]; + } +diff --git a/drivers/block/rnbd/rnbd-srv.c b/drivers/block/rnbd/rnbd-srv.c +index 65de51f3dfd9a..ab78eab97d982 100644 +--- a/drivers/block/rnbd/rnbd-srv.c ++++ b/drivers/block/rnbd/rnbd-srv.c +@@ -585,6 +585,7 @@ static char *rnbd_srv_get_full_path(struct rnbd_srv_session *srv_sess, + { + char *full_path; + char *a, *b; ++ int len; + + full_path = kmalloc(PATH_MAX, GFP_KERNEL); + if (!full_path) +@@ -596,19 +597,19 @@ static char *rnbd_srv_get_full_path(struct rnbd_srv_session *srv_sess, + */ + a = strnstr(dev_search_path, "%SESSNAME%", sizeof(dev_search_path)); + if (a) { +- int len = a - dev_search_path; ++ len = a - dev_search_path; + + len = snprintf(full_path, PATH_MAX, "%.*s/%s/%s", len, + dev_search_path, srv_sess->sessname, dev_name); +- if (len >= PATH_MAX) { +- pr_err("Too long path: %s, %s, %s\n", +- dev_search_path, srv_sess->sessname, dev_name); +- kfree(full_path); +- return ERR_PTR(-EINVAL); +- } + } else { +- snprintf(full_path, PATH_MAX, "%s/%s", +- dev_search_path, dev_name); ++ len = snprintf(full_path, PATH_MAX, "%s/%s", ++ dev_search_path, dev_name); ++ } ++ if (len >= PATH_MAX) { ++ pr_err("Too long path: %s, %s, %s\n", ++ dev_search_path, srv_sess->sessname, dev_name); ++ kfree(full_path); ++ return ERR_PTR(-EINVAL); + } + + /* eliminitate duplicated slashes */ +diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c +index 067e248e35993..35f74f209d1fc 100644 +--- a/drivers/bluetooth/hci_qca.c ++++ b/drivers/bluetooth/hci_qca.c +@@ -2039,6 +2039,7 @@ static const struct qca_device_data qca_soc_data_wcn3998 __maybe_unused = { + static const struct qca_device_data qca_soc_data_qca2066 __maybe_unused = { + .soc_type = QCA_QCA2066, + .num_vregs = 0, ++ .capabilities = QCA_CAP_WIDEBAND_SPEECH | QCA_CAP_VALID_LE_STATES, + }; + + static const struct qca_device_data qca_soc_data_qca6390 __maybe_unused = { +diff --git a/drivers/char/hw_random/jh7110-trng.c b/drivers/char/hw_random/jh7110-trng.c +index 38474d48a25e1..b1f94e3c0c6a4 100644 +--- a/drivers/char/hw_random/jh7110-trng.c ++++ b/drivers/char/hw_random/jh7110-trng.c +@@ -300,7 +300,7 @@ static int starfive_trng_probe(struct platform_device *pdev) + ret = devm_request_irq(&pdev->dev, irq, starfive_trng_irq, 0, pdev->name, + (void *)trng); + if (ret) +- return dev_err_probe(&pdev->dev, irq, ++ return dev_err_probe(&pdev->dev, ret, + "Failed to register interrupt handler\n"); + + trng->hclk = devm_clk_get(&pdev->dev, "hclk"); +diff --git a/drivers/clk/hisilicon/clk-hi3620.c b/drivers/clk/hisilicon/clk-hi3620.c +index 2d7186905abdc..5d0226530fdb2 100644 +--- a/drivers/clk/hisilicon/clk-hi3620.c ++++ b/drivers/clk/hisilicon/clk-hi3620.c +@@ -466,8 +466,10 @@ static void __init hi3620_mmc_clk_init(struct device_node *node) + return; + + clk_data->clks = kcalloc(num, sizeof(*clk_data->clks), GFP_KERNEL); +- if (!clk_data->clks) ++ if (!clk_data->clks) { ++ kfree(clk_data); + return; ++ } + + for (i = 0; i < num; i++) { + struct hisi_mmc_clock *mmc_clk = &hi3620_mmc_clks[i]; +diff --git a/drivers/clk/imx/clk-imx8qxp.c b/drivers/clk/imx/clk-imx8qxp.c +index 41f0a45aa162e..7d8883916cacd 100644 +--- a/drivers/clk/imx/clk-imx8qxp.c ++++ b/drivers/clk/imx/clk-imx8qxp.c +@@ -66,6 +66,22 @@ static const char * const lcd_pxl_sels[] = { + "lcd_pxl_bypass_div_clk", + }; + ++static const char *const lvds0_sels[] = { ++ "clk_dummy", ++ "clk_dummy", ++ "clk_dummy", ++ "clk_dummy", ++ "mipi0_lvds_bypass_clk", ++}; ++ ++static const char *const lvds1_sels[] = { ++ "clk_dummy", ++ "clk_dummy", ++ "clk_dummy", ++ "clk_dummy", ++ "mipi1_lvds_bypass_clk", ++}; ++ + static const char * const mipi_sels[] = { + "clk_dummy", + "clk_dummy", +@@ -207,9 +223,9 @@ static int imx8qxp_clk_probe(struct platform_device *pdev) + /* MIPI-LVDS SS */ + imx_clk_scu("mipi0_bypass_clk", IMX_SC_R_MIPI_0, IMX_SC_PM_CLK_BYPASS); + imx_clk_scu("mipi0_pixel_clk", IMX_SC_R_MIPI_0, IMX_SC_PM_CLK_PER); +- imx_clk_scu("mipi0_lvds_pixel_clk", IMX_SC_R_LVDS_0, IMX_SC_PM_CLK_MISC2); + imx_clk_scu("mipi0_lvds_bypass_clk", IMX_SC_R_LVDS_0, IMX_SC_PM_CLK_BYPASS); +- imx_clk_scu("mipi0_lvds_phy_clk", IMX_SC_R_LVDS_0, IMX_SC_PM_CLK_MISC3); ++ imx_clk_scu2("mipi0_lvds_pixel_clk", lvds0_sels, ARRAY_SIZE(lvds0_sels), IMX_SC_R_LVDS_0, IMX_SC_PM_CLK_MISC2); ++ imx_clk_scu2("mipi0_lvds_phy_clk", lvds0_sels, ARRAY_SIZE(lvds0_sels), IMX_SC_R_LVDS_0, IMX_SC_PM_CLK_MISC3); + imx_clk_scu2("mipi0_dsi_tx_esc_clk", mipi_sels, ARRAY_SIZE(mipi_sels), IMX_SC_R_MIPI_0, IMX_SC_PM_CLK_MST_BUS); + imx_clk_scu2("mipi0_dsi_rx_esc_clk", mipi_sels, ARRAY_SIZE(mipi_sels), IMX_SC_R_MIPI_0, IMX_SC_PM_CLK_SLV_BUS); + imx_clk_scu2("mipi0_dsi_phy_clk", mipi_sels, ARRAY_SIZE(mipi_sels), IMX_SC_R_MIPI_0, IMX_SC_PM_CLK_PHY); +@@ -219,9 +235,9 @@ static int imx8qxp_clk_probe(struct platform_device *pdev) + + imx_clk_scu("mipi1_bypass_clk", IMX_SC_R_MIPI_1, IMX_SC_PM_CLK_BYPASS); + imx_clk_scu("mipi1_pixel_clk", IMX_SC_R_MIPI_1, IMX_SC_PM_CLK_PER); +- imx_clk_scu("mipi1_lvds_pixel_clk", IMX_SC_R_LVDS_1, IMX_SC_PM_CLK_MISC2); + imx_clk_scu("mipi1_lvds_bypass_clk", IMX_SC_R_LVDS_1, IMX_SC_PM_CLK_BYPASS); +- imx_clk_scu("mipi1_lvds_phy_clk", IMX_SC_R_LVDS_1, IMX_SC_PM_CLK_MISC3); ++ imx_clk_scu2("mipi1_lvds_pixel_clk", lvds1_sels, ARRAY_SIZE(lvds1_sels), IMX_SC_R_LVDS_1, IMX_SC_PM_CLK_MISC2); ++ imx_clk_scu2("mipi1_lvds_phy_clk", lvds1_sels, ARRAY_SIZE(lvds1_sels), IMX_SC_R_LVDS_1, IMX_SC_PM_CLK_MISC3); + + imx_clk_scu2("mipi1_dsi_tx_esc_clk", mipi_sels, ARRAY_SIZE(mipi_sels), IMX_SC_R_MIPI_1, IMX_SC_PM_CLK_MST_BUS); + imx_clk_scu2("mipi1_dsi_rx_esc_clk", mipi_sels, ARRAY_SIZE(mipi_sels), IMX_SC_R_MIPI_1, IMX_SC_PM_CLK_SLV_BUS); +diff --git a/drivers/clk/imx/clk-scu.c b/drivers/clk/imx/clk-scu.c +index be89180dd19c1..e48a904c00133 100644 +--- a/drivers/clk/imx/clk-scu.c ++++ b/drivers/clk/imx/clk-scu.c +@@ -886,8 +886,10 @@ struct clk_hw *__imx_clk_gpr_scu(const char *name, const char * const *parent_na + return ERR_PTR(-EINVAL); + } + +- if (!imx_clk_is_resource_owned(rsrc_id)) ++ if (!imx_clk_is_resource_owned(rsrc_id)) { ++ kfree(clk_node); + return NULL; ++ } + + clk = kzalloc(sizeof(*clk), GFP_KERNEL); + if (!clk) { +diff --git a/drivers/clk/mmp/clk-of-pxa168.c b/drivers/clk/mmp/clk-of-pxa168.c +index fb0df64cf053c..c5a7ba1deaa3a 100644 +--- a/drivers/clk/mmp/clk-of-pxa168.c ++++ b/drivers/clk/mmp/clk-of-pxa168.c +@@ -308,18 +308,21 @@ static void __init pxa168_clk_init(struct device_node *np) + pxa_unit->mpmu_base = of_iomap(np, 0); + if (!pxa_unit->mpmu_base) { + pr_err("failed to map mpmu registers\n"); ++ kfree(pxa_unit); + return; + } + + pxa_unit->apmu_base = of_iomap(np, 1); + if (!pxa_unit->apmu_base) { + pr_err("failed to map apmu registers\n"); ++ kfree(pxa_unit); + return; + } + + pxa_unit->apbc_base = of_iomap(np, 2); + if (!pxa_unit->apbc_base) { + pr_err("failed to map apbc registers\n"); ++ kfree(pxa_unit); + return; + } + +diff --git a/drivers/crypto/caam/caamalg_qi2.c b/drivers/crypto/caam/caamalg_qi2.c +index a148ff1f0872c..a4f6884416a04 100644 +--- a/drivers/crypto/caam/caamalg_qi2.c ++++ b/drivers/crypto/caam/caamalg_qi2.c +@@ -4545,6 +4545,7 @@ struct caam_hash_alg { + struct list_head entry; + struct device *dev; + int alg_type; ++ bool is_hmac; + struct ahash_alg ahash_alg; + }; + +@@ -4571,7 +4572,7 @@ static int caam_hash_cra_init(struct crypto_tfm *tfm) + + ctx->dev = caam_hash->dev; + +- if (alg->setkey) { ++ if (caam_hash->is_hmac) { + ctx->adata.key_dma = dma_map_single_attrs(ctx->dev, ctx->key, + ARRAY_SIZE(ctx->key), + DMA_TO_DEVICE, +@@ -4611,7 +4612,7 @@ static int caam_hash_cra_init(struct crypto_tfm *tfm) + * For keyed hash algorithms shared descriptors + * will be created later in setkey() callback + */ +- return alg->setkey ? 0 : ahash_set_sh_desc(ahash); ++ return caam_hash->is_hmac ? 0 : ahash_set_sh_desc(ahash); + } + + static void caam_hash_cra_exit(struct crypto_tfm *tfm) +@@ -4646,12 +4647,14 @@ static struct caam_hash_alg *caam_hash_alloc(struct device *dev, + template->hmac_name); + snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s", + template->hmac_driver_name); ++ t_alg->is_hmac = true; + } else { + snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s", + template->name); + snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s", + template->driver_name); + t_alg->ahash_alg.setkey = NULL; ++ t_alg->is_hmac = false; + } + alg->cra_module = THIS_MODULE; + alg->cra_init = caam_hash_cra_init; +diff --git a/drivers/crypto/caam/caamhash.c b/drivers/crypto/caam/caamhash.c +index 290c8500c247f..fdd724228c2fa 100644 +--- a/drivers/crypto/caam/caamhash.c ++++ b/drivers/crypto/caam/caamhash.c +@@ -1753,6 +1753,7 @@ static struct caam_hash_template driver_hash[] = { + struct caam_hash_alg { + struct list_head entry; + int alg_type; ++ bool is_hmac; + struct ahash_engine_alg ahash_alg; + }; + +@@ -1804,7 +1805,7 @@ static int caam_hash_cra_init(struct crypto_tfm *tfm) + } else { + if (priv->era >= 6) { + ctx->dir = DMA_BIDIRECTIONAL; +- ctx->key_dir = alg->setkey ? DMA_TO_DEVICE : DMA_NONE; ++ ctx->key_dir = caam_hash->is_hmac ? DMA_TO_DEVICE : DMA_NONE; + } else { + ctx->dir = DMA_TO_DEVICE; + ctx->key_dir = DMA_NONE; +@@ -1862,7 +1863,7 @@ static int caam_hash_cra_init(struct crypto_tfm *tfm) + * For keyed hash algorithms shared descriptors + * will be created later in setkey() callback + */ +- return alg->setkey ? 0 : ahash_set_sh_desc(ahash); ++ return caam_hash->is_hmac ? 0 : ahash_set_sh_desc(ahash); + } + + static void caam_hash_cra_exit(struct crypto_tfm *tfm) +@@ -1915,12 +1916,14 @@ caam_hash_alloc(struct caam_hash_template *template, + template->hmac_name); + snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s", + template->hmac_driver_name); ++ t_alg->is_hmac = true; + } else { + snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s", + template->name); + snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s", + template->driver_name); + halg->setkey = NULL; ++ t_alg->is_hmac = false; + } + alg->cra_module = THIS_MODULE; + alg->cra_init = caam_hash_cra_init; +diff --git a/drivers/crypto/marvell/octeontx2/otx2_cptlf.c b/drivers/crypto/marvell/octeontx2/otx2_cptlf.c +index 6edd27ff8c4e3..e4bd3f030ceca 100644 +--- a/drivers/crypto/marvell/octeontx2/otx2_cptlf.c ++++ b/drivers/crypto/marvell/octeontx2/otx2_cptlf.c +@@ -419,8 +419,8 @@ int otx2_cptlf_init(struct otx2_cptlfs_info *lfs, u8 eng_grp_mask, int pri, + return 0; + + free_iq: +- otx2_cpt_free_instruction_queues(lfs); + cptlf_hw_cleanup(lfs); ++ otx2_cpt_free_instruction_queues(lfs); + detach_rsrcs: + otx2_cpt_detach_rsrcs_msg(lfs); + clear_lfs_num: +@@ -431,11 +431,13 @@ EXPORT_SYMBOL_NS_GPL(otx2_cptlf_init, CRYPTO_DEV_OCTEONTX2_CPT); + + void otx2_cptlf_shutdown(struct otx2_cptlfs_info *lfs) + { +- lfs->lfs_num = 0; + /* Cleanup LFs hardware side */ + cptlf_hw_cleanup(lfs); ++ /* Free instruction queues */ ++ otx2_cpt_free_instruction_queues(lfs); + /* Send request to detach LFs */ + otx2_cpt_detach_rsrcs_msg(lfs); ++ lfs->lfs_num = 0; + } + EXPORT_SYMBOL_NS_GPL(otx2_cptlf_shutdown, CRYPTO_DEV_OCTEONTX2_CPT); + +diff --git a/drivers/crypto/marvell/octeontx2/otx2_cptvf_main.c b/drivers/crypto/marvell/octeontx2/otx2_cptvf_main.c +index bac729c885f96..215a1b17b6ce0 100644 +--- a/drivers/crypto/marvell/octeontx2/otx2_cptvf_main.c ++++ b/drivers/crypto/marvell/octeontx2/otx2_cptvf_main.c +@@ -249,8 +249,11 @@ static void cptvf_lf_shutdown(struct otx2_cptlfs_info *lfs) + otx2_cptlf_unregister_interrupts(lfs); + /* Cleanup LFs software side */ + lf_sw_cleanup(lfs); ++ /* Free instruction queues */ ++ otx2_cpt_free_instruction_queues(lfs); + /* Send request to detach LFs */ + otx2_cpt_detach_rsrcs_msg(lfs); ++ lfs->lfs_num = 0; + } + + static int cptvf_lf_init(struct otx2_cptvf_dev *cptvf) +diff --git a/drivers/crypto/starfive/jh7110-cryp.c b/drivers/crypto/starfive/jh7110-cryp.c +index 3a67ddc4d9367..4f5b6818208dc 100644 +--- a/drivers/crypto/starfive/jh7110-cryp.c ++++ b/drivers/crypto/starfive/jh7110-cryp.c +@@ -168,7 +168,7 @@ static int starfive_cryp_probe(struct platform_device *pdev) + ret = devm_request_irq(&pdev->dev, irq, starfive_cryp_irq, 0, pdev->name, + (void *)cryp); + if (ret) +- return dev_err_probe(&pdev->dev, irq, ++ return dev_err_probe(&pdev->dev, ret, + "Failed to register interrupt handler\n"); + + clk_prepare_enable(cryp->hclk); +diff --git a/drivers/crypto/stm32/stm32-crc32.c b/drivers/crypto/stm32/stm32-crc32.c +index b2d5c8921ab36..b0cf6d2fd352f 100644 +--- a/drivers/crypto/stm32/stm32-crc32.c ++++ b/drivers/crypto/stm32/stm32-crc32.c +@@ -104,7 +104,7 @@ static struct stm32_crc *stm32_crc_get_next_crc(void) + struct stm32_crc *crc; + + spin_lock_bh(&crc_list.lock); +- crc = list_first_entry(&crc_list.dev_list, struct stm32_crc, list); ++ crc = list_first_entry_or_null(&crc_list.dev_list, struct stm32_crc, list); + if (crc) + list_move_tail(&crc->list, &crc_list.dev_list); + spin_unlock_bh(&crc_list.lock); +diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c +index 907f50ab70ed9..7162d2bad4465 100644 +--- a/drivers/devfreq/devfreq.c ++++ b/drivers/devfreq/devfreq.c +@@ -461,10 +461,14 @@ static void devfreq_monitor(struct work_struct *work) + if (err) + dev_err(&devfreq->dev, "dvfs failed with (%d) error\n", err); + ++ if (devfreq->stop_polling) ++ goto out; ++ + queue_delayed_work(devfreq_wq, &devfreq->work, + msecs_to_jiffies(devfreq->profile->polling_ms)); +- mutex_unlock(&devfreq->lock); + ++out: ++ mutex_unlock(&devfreq->lock); + trace_devfreq_monitor(devfreq); + } + +@@ -483,6 +487,10 @@ void devfreq_monitor_start(struct devfreq *devfreq) + if (IS_SUPPORTED_FLAG(devfreq->governor->flags, IRQ_DRIVEN)) + return; + ++ mutex_lock(&devfreq->lock); ++ if (delayed_work_pending(&devfreq->work)) ++ goto out; ++ + switch (devfreq->profile->timer) { + case DEVFREQ_TIMER_DEFERRABLE: + INIT_DEFERRABLE_WORK(&devfreq->work, devfreq_monitor); +@@ -491,12 +499,16 @@ void devfreq_monitor_start(struct devfreq *devfreq) + INIT_DELAYED_WORK(&devfreq->work, devfreq_monitor); + break; + default: +- return; ++ goto out; + } + + if (devfreq->profile->polling_ms) + queue_delayed_work(devfreq_wq, &devfreq->work, + msecs_to_jiffies(devfreq->profile->polling_ms)); ++ ++out: ++ devfreq->stop_polling = false; ++ mutex_unlock(&devfreq->lock); + } + EXPORT_SYMBOL(devfreq_monitor_start); + +@@ -513,6 +525,14 @@ void devfreq_monitor_stop(struct devfreq *devfreq) + if (IS_SUPPORTED_FLAG(devfreq->governor->flags, IRQ_DRIVEN)) + return; + ++ mutex_lock(&devfreq->lock); ++ if (devfreq->stop_polling) { ++ mutex_unlock(&devfreq->lock); ++ return; ++ } ++ ++ devfreq->stop_polling = true; ++ mutex_unlock(&devfreq->lock); + cancel_delayed_work_sync(&devfreq->work); + } + EXPORT_SYMBOL(devfreq_monitor_stop); +diff --git a/drivers/extcon/extcon.c b/drivers/extcon/extcon.c +index 6f7a60d2ed916..e7f55c021e562 100644 +--- a/drivers/extcon/extcon.c ++++ b/drivers/extcon/extcon.c +@@ -1280,8 +1280,6 @@ int extcon_dev_register(struct extcon_dev *edev) + + edev->id = ret; + +- dev_set_name(&edev->dev, "extcon%d", edev->id); +- + ret = extcon_alloc_cables(edev); + if (ret < 0) + goto err_alloc_cables; +@@ -1310,6 +1308,7 @@ int extcon_dev_register(struct extcon_dev *edev) + RAW_INIT_NOTIFIER_HEAD(&edev->nh_all); + + dev_set_drvdata(&edev->dev, edev); ++ dev_set_name(&edev->dev, "extcon%d", edev->id); + edev->state = 0; + + ret = device_register(&edev->dev); +diff --git a/drivers/gpu/drm/amd/amdgpu/aldebaran.c b/drivers/gpu/drm/amd/amdgpu/aldebaran.c +index 02f4c6f9d4f68..576067d66bb9a 100644 +--- a/drivers/gpu/drm/amd/amdgpu/aldebaran.c ++++ b/drivers/gpu/drm/amd/amdgpu/aldebaran.c +@@ -330,6 +330,7 @@ aldebaran_mode2_restore_hwcontext(struct amdgpu_reset_control *reset_ctl, + { + struct list_head *reset_device_list = reset_context->reset_device_list; + struct amdgpu_device *tmp_adev = NULL; ++ struct amdgpu_ras *con; + int r; + + if (reset_device_list == NULL) +@@ -355,7 +356,30 @@ aldebaran_mode2_restore_hwcontext(struct amdgpu_reset_control *reset_ctl, + */ + amdgpu_register_gpu_instance(tmp_adev); + +- /* Resume RAS */ ++ /* Resume RAS, ecc_irq */ ++ con = amdgpu_ras_get_context(tmp_adev); ++ if (!amdgpu_sriov_vf(tmp_adev) && con) { ++ if (tmp_adev->sdma.ras && ++ tmp_adev->sdma.ras->ras_block.ras_late_init) { ++ r = tmp_adev->sdma.ras->ras_block.ras_late_init(tmp_adev, ++ &tmp_adev->sdma.ras->ras_block.ras_comm); ++ if (r) { ++ dev_err(tmp_adev->dev, "SDMA failed to execute ras_late_init! ret:%d\n", r); ++ goto end; ++ } ++ } ++ ++ if (tmp_adev->gfx.ras && ++ tmp_adev->gfx.ras->ras_block.ras_late_init) { ++ r = tmp_adev->gfx.ras->ras_block.ras_late_init(tmp_adev, ++ &tmp_adev->gfx.ras->ras_block.ras_comm); ++ if (r) { ++ dev_err(tmp_adev->dev, "GFX failed to execute ras_late_init! ret:%d\n", r); ++ goto end; ++ } ++ } ++ } ++ + amdgpu_ras_resume(tmp_adev); + + /* Update PSP FW topology after reset */ +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_fence.c +index 469785d337911..1ef758ac5076e 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_fence.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_fence.c +@@ -90,7 +90,7 @@ struct amdgpu_amdkfd_fence *to_amdgpu_amdkfd_fence(struct dma_fence *f) + return NULL; + + fence = container_of(f, struct amdgpu_amdkfd_fence, base); +- if (fence && f->ops == &amdkfd_fence_ops) ++ if (f->ops == &amdkfd_fence_ops) + return fence; + + return NULL; +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +index 3677d644183b8..9257c9af3fee6 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +@@ -1485,6 +1485,7 @@ bool amdgpu_device_need_post(struct amdgpu_device *adev) + return true; + + fw_ver = *((uint32_t *)adev->pm.fw->data + 69); ++ release_firmware(adev->pm.fw); + if (fw_ver < 0x00160e00) + return true; + } +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c +index d2f273d77e595..55784a9f26c4c 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c +@@ -1045,21 +1045,28 @@ int amdgpu_gmc_vram_checking(struct amdgpu_device *adev) + * seconds, so here, we just pick up three parts for emulation. + */ + ret = memcmp(vram_ptr, cptr, 10); +- if (ret) +- return ret; ++ if (ret) { ++ ret = -EIO; ++ goto release_buffer; ++ } + + ret = memcmp(vram_ptr + (size / 2), cptr, 10); +- if (ret) +- return ret; ++ if (ret) { ++ ret = -EIO; ++ goto release_buffer; ++ } + + ret = memcmp(vram_ptr + size - 10, cptr, 10); +- if (ret) +- return ret; ++ if (ret) { ++ ret = -EIO; ++ goto release_buffer; ++ } + ++release_buffer: + amdgpu_bo_free_kernel(&vram_bo, &vram_gpu, + &vram_ptr); + +- return 0; ++ return ret; + } + + static ssize_t current_memory_partition_show( +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c +index cf33eb219e257..061d88f4480d7 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c +@@ -351,6 +351,9 @@ int amdgpu_mca_smu_get_mca_entry(struct amdgpu_device *adev, enum amdgpu_mca_err + const struct amdgpu_mca_smu_funcs *mca_funcs = adev->mca.mca_funcs; + int count; + ++ if (!mca_funcs || !mca_funcs->mca_get_mca_entry) ++ return -EOPNOTSUPP; ++ + switch (type) { + case AMDGPU_MCA_ERROR_TYPE_UE: + count = mca_funcs->max_ue_count; +@@ -365,10 +368,7 @@ int amdgpu_mca_smu_get_mca_entry(struct amdgpu_device *adev, enum amdgpu_mca_err + if (idx >= count) + return -EINVAL; + +- if (mca_funcs && mca_funcs->mca_get_mca_entry) +- return mca_funcs->mca_get_mca_entry(adev, type, idx, entry); +- +- return -EOPNOTSUPP; ++ return mca_funcs->mca_get_mca_entry(adev, type, idx, entry); + } + + #if defined(CONFIG_DEBUG_FS) +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c +index 9ddbf1494326a..30c0108366587 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c +@@ -886,6 +886,11 @@ int amdgpu_mes_set_shader_debugger(struct amdgpu_device *adev, + op_input.op = MES_MISC_OP_SET_SHADER_DEBUGGER; + op_input.set_shader_debugger.process_context_addr = process_context_addr; + op_input.set_shader_debugger.flags.u32all = flags; ++ ++ /* use amdgpu mes_flush_shader_debugger instead */ ++ if (op_input.set_shader_debugger.flags.process_ctx_flush) ++ return -EINVAL; ++ + op_input.set_shader_debugger.spi_gdbg_per_vmid_cntl = spi_gdbg_per_vmid_cntl; + memcpy(op_input.set_shader_debugger.tcp_watch_cntl, tcp_watch_cntl, + sizeof(op_input.set_shader_debugger.tcp_watch_cntl)); +@@ -905,6 +910,32 @@ int amdgpu_mes_set_shader_debugger(struct amdgpu_device *adev, + return r; + } + ++int amdgpu_mes_flush_shader_debugger(struct amdgpu_device *adev, ++ uint64_t process_context_addr) ++{ ++ struct mes_misc_op_input op_input = {0}; ++ int r; ++ ++ if (!adev->mes.funcs->misc_op) { ++ DRM_ERROR("mes flush shader debugger is not supported!\n"); ++ return -EINVAL; ++ } ++ ++ op_input.op = MES_MISC_OP_SET_SHADER_DEBUGGER; ++ op_input.set_shader_debugger.process_context_addr = process_context_addr; ++ op_input.set_shader_debugger.flags.process_ctx_flush = true; ++ ++ amdgpu_mes_lock(&adev->mes); ++ ++ r = adev->mes.funcs->misc_op(&adev->mes, &op_input); ++ if (r) ++ DRM_ERROR("failed to set_shader_debugger\n"); ++ ++ amdgpu_mes_unlock(&adev->mes); ++ ++ return r; ++} ++ + static void + amdgpu_mes_ring_to_queue_props(struct amdgpu_device *adev, + struct amdgpu_ring *ring, +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h +index a27b424ffe005..c2c88b772361d 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h +@@ -291,9 +291,10 @@ struct mes_misc_op_input { + uint64_t process_context_addr; + union { + struct { +- uint64_t single_memop : 1; +- uint64_t single_alu_op : 1; +- uint64_t reserved: 30; ++ uint32_t single_memop : 1; ++ uint32_t single_alu_op : 1; ++ uint32_t reserved: 29; ++ uint32_t process_ctx_flush: 1; + }; + uint32_t u32all; + } flags; +@@ -369,7 +370,8 @@ int amdgpu_mes_set_shader_debugger(struct amdgpu_device *adev, + const uint32_t *tcp_watch_cntl, + uint32_t flags, + bool trap_en); +- ++int amdgpu_mes_flush_shader_debugger(struct amdgpu_device *adev, ++ uint64_t process_context_addr); + int amdgpu_mes_add_ring(struct amdgpu_device *adev, int gang_id, + int queue_type, int idx, + struct amdgpu_mes_ctx_data *ctx_data, +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +index 5ad03f2afdb45..425cebcc5cbff 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +@@ -1245,19 +1245,15 @@ int amdgpu_bo_get_metadata(struct amdgpu_bo *bo, void *buffer, + * amdgpu_bo_move_notify - notification about a memory move + * @bo: pointer to a buffer object + * @evict: if this move is evicting the buffer from the graphics address space +- * @new_mem: new information of the bufer object + * + * Marks the corresponding &amdgpu_bo buffer object as invalid, also performs + * bookkeeping. + * TTM driver callback which is called when ttm moves a buffer. + */ +-void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, +- bool evict, +- struct ttm_resource *new_mem) ++void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, bool evict) + { + struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev); + struct amdgpu_bo *abo; +- struct ttm_resource *old_mem = bo->resource; + + if (!amdgpu_bo_is_amdgpu_bo(bo)) + return; +@@ -1274,13 +1270,6 @@ void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, + /* remember the eviction */ + if (evict) + atomic64_inc(&adev->num_evictions); +- +- /* update statistics */ +- if (!new_mem) +- return; +- +- /* move_notify is called before move happens */ +- trace_amdgpu_bo_move(abo, new_mem->mem_type, old_mem->mem_type); + } + + void amdgpu_bo_get_memory(struct amdgpu_bo *bo, +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h +index d28e21baef16e..a3ea8a82db23a 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h +@@ -344,9 +344,7 @@ int amdgpu_bo_set_metadata (struct amdgpu_bo *bo, void *metadata, + int amdgpu_bo_get_metadata(struct amdgpu_bo *bo, void *buffer, + size_t buffer_size, uint32_t *metadata_size, + uint64_t *flags); +-void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, +- bool evict, +- struct ttm_resource *new_mem); ++void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, bool evict); + void amdgpu_bo_release_notify(struct ttm_buffer_object *bo); + vm_fault_t amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo); + void amdgpu_bo_fence(struct amdgpu_bo *bo, struct dma_fence *fence, +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +index 63fb4cd85e53b..4a3726bb6da1b 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +@@ -1174,6 +1174,9 @@ static int amdgpu_ras_query_error_status_helper(struct amdgpu_device *adev, + enum amdgpu_ras_block blk = info ? info->head.block : AMDGPU_RAS_BLOCK_COUNT; + struct amdgpu_ras_block_object *block_obj = NULL; + ++ if (blk == AMDGPU_RAS_BLOCK_COUNT) ++ return -EINVAL; ++ + if (error_query_mode == AMDGPU_RAS_INVALID_ERROR_QUERY) + return -EINVAL; + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c +index dcd8c066bc1f5..1b013a44ca99a 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c +@@ -191,7 +191,8 @@ static bool amdgpu_sync_test_fence(struct amdgpu_device *adev, + + /* Never sync to VM updates either. */ + if (fence_owner == AMDGPU_FENCE_OWNER_VM && +- owner != AMDGPU_FENCE_OWNER_UNDEFINED) ++ owner != AMDGPU_FENCE_OWNER_UNDEFINED && ++ owner != AMDGPU_FENCE_OWNER_KFD) + return false; + + /* Ignore fences depending on the sync mode */ +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +index ab4a762aed5bd..75c9fd2c6c2a1 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +@@ -545,10 +545,11 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict, + return r; + } + ++ trace_amdgpu_bo_move(abo, new_mem->mem_type, old_mem->mem_type); + out: + /* update statistics */ + atomic64_add(bo->base.size, &adev->num_bytes_moved); +- amdgpu_bo_move_notify(bo, evict, new_mem); ++ amdgpu_bo_move_notify(bo, evict); + return 0; + } + +@@ -1553,7 +1554,7 @@ static int amdgpu_ttm_access_memory(struct ttm_buffer_object *bo, + static void + amdgpu_bo_delete_mem_notify(struct ttm_buffer_object *bo) + { +- amdgpu_bo_move_notify(bo, false, NULL); ++ amdgpu_bo_move_notify(bo, false); + } + + static struct ttm_device_funcs amdgpu_bo_driver = { +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c +index b14127429f303..0efb2568cb65f 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c +@@ -1397,9 +1397,13 @@ int amdgpu_ucode_request(struct amdgpu_device *adev, const struct firmware **fw, + + if (err) + return -ENODEV; ++ + err = amdgpu_ucode_validate(*fw); +- if (err) ++ if (err) { + dev_dbg(adev->dev, "\"%s\" failed to validate\n", fw_name); ++ release_firmware(*fw); ++ *fw = NULL; ++ } + + return err; + } +diff --git a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c +index 53a2ba5fcf4ba..22175da0e16af 100644 +--- a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c +@@ -102,7 +102,9 @@ static void gfxhub_v1_0_init_system_aperture_regs(struct amdgpu_device *adev) + WREG32_SOC15_RLC(GC, 0, mmMC_VM_SYSTEM_APERTURE_LOW_ADDR, + min(adev->gmc.fb_start, adev->gmc.agp_start) >> 18); + +- if (adev->apu_flags & AMD_APU_IS_RAVEN2) ++ if (adev->apu_flags & (AMD_APU_IS_RAVEN2 | ++ AMD_APU_IS_RENOIR | ++ AMD_APU_IS_GREEN_SARDINE)) + /* + * Raven2 has a HW issue that it is unable to use the + * vram which is out of MC_VM_SYSTEM_APERTURE_HIGH_ADDR. +diff --git a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_2.c b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_2.c +index 55423ff1bb492..95d06da544e2a 100644 +--- a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_2.c ++++ b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_2.c +@@ -139,7 +139,9 @@ gfxhub_v1_2_xcc_init_system_aperture_regs(struct amdgpu_device *adev, + WREG32_SOC15_RLC(GC, GET_INST(GC, i), regMC_VM_SYSTEM_APERTURE_LOW_ADDR, + min(adev->gmc.fb_start, adev->gmc.agp_start) >> 18); + +- if (adev->apu_flags & AMD_APU_IS_RAVEN2) ++ if (adev->apu_flags & (AMD_APU_IS_RAVEN2 | ++ AMD_APU_IS_RENOIR | ++ AMD_APU_IS_GREEN_SARDINE)) + /* + * Raven2 has a HW issue that it is unable to use the + * vram which is out of MC_VM_SYSTEM_APERTURE_HIGH_ADDR. +diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c +index a5a05c16c10d7..6c51856088546 100644 +--- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c +@@ -1041,6 +1041,10 @@ static int gmc_v10_0_hw_fini(void *handle) + + amdgpu_irq_put(adev, &adev->gmc.vm_fault, 0); + ++ if (adev->gmc.ecc_irq.funcs && ++ amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__UMC)) ++ amdgpu_irq_put(adev, &adev->gmc.ecc_irq, 0); ++ + return 0; + } + +diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c +index 23d7b548d13f4..c9c653cfc765b 100644 +--- a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c +@@ -941,6 +941,11 @@ static int gmc_v11_0_hw_fini(void *handle) + } + + amdgpu_irq_put(adev, &adev->gmc.vm_fault, 0); ++ ++ if (adev->gmc.ecc_irq.funcs && ++ amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__UMC)) ++ amdgpu_irq_put(adev, &adev->gmc.ecc_irq, 0); ++ + gmc_v11_0_gart_disable(adev); + + return 0; +diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c +index 42e103d7077d5..59d9215e55562 100644 +--- a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c +@@ -915,8 +915,8 @@ static int gmc_v6_0_hw_init(void *handle) + + if (amdgpu_emu_mode == 1) + return amdgpu_gmc_vram_checking(adev); +- else +- return r; ++ ++ return 0; + } + + static int gmc_v6_0_hw_fini(void *handle) +diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c +index efc16e580f1e2..45a2f8e031a2c 100644 +--- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c +@@ -1099,8 +1099,8 @@ static int gmc_v7_0_hw_init(void *handle) + + if (amdgpu_emu_mode == 1) + return amdgpu_gmc_vram_checking(adev); +- else +- return r; ++ ++ return 0; + } + + static int gmc_v7_0_hw_fini(void *handle) +diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c +index ff4ae73d27ecd..4422b27a3cc2f 100644 +--- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c +@@ -1219,8 +1219,8 @@ static int gmc_v8_0_hw_init(void *handle) + + if (amdgpu_emu_mode == 1) + return amdgpu_gmc_vram_checking(adev); +- else +- return r; ++ ++ return 0; + } + + static int gmc_v8_0_hw_fini(void *handle) +diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +index 77e625f24cd07..ad91329f227df 100644 +--- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +@@ -2341,8 +2341,8 @@ static int gmc_v9_0_hw_init(void *handle) + + if (amdgpu_emu_mode == 1) + return amdgpu_gmc_vram_checking(adev); +- else +- return r; ++ ++ return 0; + } + + /** +@@ -2381,6 +2381,10 @@ static int gmc_v9_0_hw_fini(void *handle) + + amdgpu_irq_put(adev, &adev->gmc.vm_fault, 0); + ++ if (adev->gmc.ecc_irq.funcs && ++ amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__UMC)) ++ amdgpu_irq_put(adev, &adev->gmc.ecc_irq, 0); ++ + return 0; + } + +diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c +index 843219a917360..e3ddd22aa1728 100644 +--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c +@@ -96,7 +96,9 @@ static void mmhub_v1_0_init_system_aperture_regs(struct amdgpu_device *adev) + WREG32_SOC15(MMHUB, 0, mmMC_VM_SYSTEM_APERTURE_LOW_ADDR, + min(adev->gmc.fb_start, adev->gmc.agp_start) >> 18); + +- if (adev->apu_flags & AMD_APU_IS_RAVEN2) ++ if (adev->apu_flags & (AMD_APU_IS_RAVEN2 | ++ AMD_APU_IS_RENOIR | ++ AMD_APU_IS_GREEN_SARDINE)) + /* + * Raven2 has a HW issue that it is unable to use the vram which + * is out of MC_VM_SYSTEM_APERTURE_HIGH_ADDR. So here is the +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c +index 77f493262e058..43eff221eae58 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c +@@ -87,6 +87,8 @@ void kfd_process_dequeue_from_device(struct kfd_process_device *pdd) + return; + + dev->dqm->ops.process_termination(dev->dqm, &pdd->qpd); ++ if (dev->kfd->shared_resources.enable_mes) ++ amdgpu_mes_flush_shader_debugger(dev->adev, pdd->proc_ctx_gpu_addr); + pdd->already_dequeued = true; + } + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +index a15bfb5223e8f..9af1d094385af 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +@@ -400,14 +400,9 @@ static void svm_range_bo_release(struct kref *kref) + spin_lock(&svm_bo->list_lock); + } + spin_unlock(&svm_bo->list_lock); +- if (!dma_fence_is_signaled(&svm_bo->eviction_fence->base)) { +- /* We're not in the eviction worker. +- * Signal the fence and synchronize with any +- * pending eviction work. +- */ ++ if (!dma_fence_is_signaled(&svm_bo->eviction_fence->base)) ++ /* We're not in the eviction worker. Signal the fence. */ + dma_fence_signal(&svm_bo->eviction_fence->base); +- cancel_work_sync(&svm_bo->eviction_work); +- } + dma_fence_put(&svm_bo->eviction_fence->base); + amdgpu_bo_unref(&svm_bo->bo); + kfree(svm_bo); +@@ -2371,8 +2366,10 @@ retry: + mutex_unlock(&svms->lock); + mmap_write_unlock(mm); + +- /* Pairs with mmget in svm_range_add_list_work */ +- mmput(mm); ++ /* Pairs with mmget in svm_range_add_list_work. If dropping the ++ * last mm refcount, schedule release work to avoid circular locking ++ */ ++ mmput_async(mm); + + spin_lock(&svms->deferred_list_lock); + } +@@ -2683,6 +2680,7 @@ svm_range_get_range_boundaries(struct kfd_process *p, int64_t addr, + { + struct vm_area_struct *vma; + struct interval_tree_node *node; ++ struct rb_node *rb_node; + unsigned long start_limit, end_limit; + + vma = vma_lookup(p->mm, addr << PAGE_SHIFT); +@@ -2702,16 +2700,15 @@ svm_range_get_range_boundaries(struct kfd_process *p, int64_t addr, + if (node) { + end_limit = min(end_limit, node->start); + /* Last range that ends before the fault address */ +- node = container_of(rb_prev(&node->rb), +- struct interval_tree_node, rb); ++ rb_node = rb_prev(&node->rb); + } else { + /* Last range must end before addr because + * there was no range after addr + */ +- node = container_of(rb_last(&p->svms.objects.rb_root), +- struct interval_tree_node, rb); ++ rb_node = rb_last(&p->svms.objects.rb_root); + } +- if (node) { ++ if (rb_node) { ++ node = container_of(rb_node, struct interval_tree_node, rb); + if (node->last >= addr) { + WARN(1, "Overlap with prev node and page fault addr\n"); + return -EFAULT; +@@ -3447,13 +3444,14 @@ svm_range_trigger_migration(struct mm_struct *mm, struct svm_range *prange, + + int svm_range_schedule_evict_svm_bo(struct amdgpu_amdkfd_fence *fence) + { +- if (!fence) +- return -EINVAL; +- +- if (dma_fence_is_signaled(&fence->base)) +- return 0; +- +- if (fence->svm_bo) { ++ /* Dereferencing fence->svm_bo is safe here because the fence hasn't ++ * signaled yet and we're under the protection of the fence->lock. ++ * After the fence is signaled in svm_range_bo_release, we cannot get ++ * here any more. ++ * ++ * Reference is dropped in svm_range_evict_svm_bo_worker. ++ */ ++ if (svm_bo_ref_unless_zero(fence->svm_bo)) { + WRITE_ONCE(fence->svm_bo->evicting, 1); + schedule_work(&fence->svm_bo->eviction_work); + } +@@ -3468,8 +3466,6 @@ static void svm_range_evict_svm_bo_worker(struct work_struct *work) + int r = 0; + + svm_bo = container_of(work, struct svm_range_bo, eviction_work); +- if (!svm_bo_ref_unless_zero(svm_bo)) +- return; /* svm_bo was freed while eviction was pending */ + + if (mmget_not_zero(svm_bo->eviction_fence->mm)) { + mm = svm_bo->eviction_fence->mm; +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +index 58d775a0668db..e5f7c92eebcbb 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +@@ -1452,17 +1452,19 @@ static int kfd_add_peer_prop(struct kfd_topology_device *kdev, + /* CPU->CPU link*/ + cpu_dev = kfd_topology_device_by_proximity_domain(iolink1->node_to); + if (cpu_dev) { +- list_for_each_entry(iolink3, &cpu_dev->io_link_props, list) +- if (iolink3->node_to == iolink2->node_to) +- break; +- +- props->weight += iolink3->weight; +- props->min_latency += iolink3->min_latency; +- props->max_latency += iolink3->max_latency; +- props->min_bandwidth = min(props->min_bandwidth, +- iolink3->min_bandwidth); +- props->max_bandwidth = min(props->max_bandwidth, +- iolink3->max_bandwidth); ++ list_for_each_entry(iolink3, &cpu_dev->io_link_props, list) { ++ if (iolink3->node_to != iolink2->node_to) ++ continue; ++ ++ props->weight += iolink3->weight; ++ props->min_latency += iolink3->min_latency; ++ props->max_latency += iolink3->max_latency; ++ props->min_bandwidth = min(props->min_bandwidth, ++ iolink3->min_bandwidth); ++ props->max_bandwidth = min(props->max_bandwidth, ++ iolink3->max_bandwidth); ++ break; ++ } + } else { + WARN(1, "CPU node not found"); + } +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +index 9dbbaeb8c6cf1..affc628004ffb 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -65,7 +65,6 @@ + #include "amdgpu_dm_debugfs.h" + #endif + #include "amdgpu_dm_psr.h" +-#include "amdgpu_dm_replay.h" + + #include "ivsrcid/ivsrcid_vislands30.h" + +@@ -1258,7 +1257,9 @@ static void mmhub_read_system_context(struct amdgpu_device *adev, struct dc_phy_ + /* AGP aperture is disabled */ + if (agp_bot > agp_top) { + logical_addr_low = adev->gmc.fb_start >> 18; +- if (adev->apu_flags & AMD_APU_IS_RAVEN2) ++ if (adev->apu_flags & (AMD_APU_IS_RAVEN2 | ++ AMD_APU_IS_RENOIR | ++ AMD_APU_IS_GREEN_SARDINE)) + /* + * Raven2 has a HW issue that it is unable to use the vram which + * is out of MC_VM_SYSTEM_APERTURE_HIGH_ADDR. So here is the +@@ -1270,7 +1271,9 @@ static void mmhub_read_system_context(struct amdgpu_device *adev, struct dc_phy_ + logical_addr_high = adev->gmc.fb_end >> 18; + } else { + logical_addr_low = min(adev->gmc.fb_start, adev->gmc.agp_start) >> 18; +- if (adev->apu_flags & AMD_APU_IS_RAVEN2) ++ if (adev->apu_flags & (AMD_APU_IS_RAVEN2 | ++ AMD_APU_IS_RENOIR | ++ AMD_APU_IS_GREEN_SARDINE)) + /* + * Raven2 has a HW issue that it is unable to use the vram which + * is out of MC_VM_SYSTEM_APERTURE_HIGH_ADDR. So here is the +@@ -4348,7 +4351,6 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) + enum dc_connection_type new_connection_type = dc_connection_none; + const struct dc_plane_cap *plane; + bool psr_feature_enabled = false; +- bool replay_feature_enabled = false; + int max_overlay = dm->dc->caps.max_slave_planes; + + dm->display_indexes_num = dm->dc->caps.max_streams; +@@ -4460,20 +4462,6 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) + } + } + +- if (!(amdgpu_dc_debug_mask & DC_DISABLE_REPLAY)) { +- switch (adev->ip_versions[DCE_HWIP][0]) { +- case IP_VERSION(3, 1, 4): +- case IP_VERSION(3, 1, 5): +- case IP_VERSION(3, 1, 6): +- case IP_VERSION(3, 2, 0): +- case IP_VERSION(3, 2, 1): +- replay_feature_enabled = true; +- break; +- default: +- replay_feature_enabled = amdgpu_dc_feature_mask & DC_REPLAY_MASK; +- break; +- } +- } + /* loops over all connectors on the board */ + for (i = 0; i < link_cnt; i++) { + struct dc_link *link = NULL; +@@ -4522,12 +4510,6 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) + amdgpu_dm_update_connector_after_detect(aconnector); + setup_backlight_device(dm, aconnector); + +- /* +- * Disable psr if replay can be enabled +- */ +- if (replay_feature_enabled && amdgpu_dm_setup_replay(link, aconnector)) +- psr_feature_enabled = false; +- + if (psr_feature_enabled) + amdgpu_dm_set_psr_caps(link); + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c +index cb0b48bb2a7dc..d2834ad85a544 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c +@@ -29,7 +29,6 @@ + #include "dc.h" + #include "amdgpu.h" + #include "amdgpu_dm_psr.h" +-#include "amdgpu_dm_replay.h" + #include "amdgpu_dm_crtc.h" + #include "amdgpu_dm_plane.h" + #include "amdgpu_dm_trace.h" +@@ -124,12 +123,7 @@ static void amdgpu_dm_crtc_vblank_control_worker(struct work_struct *work) + * fill_dc_dirty_rects(). + */ + if (vblank_work->stream && vblank_work->stream->link) { +- /* +- * Prioritize replay, instead of psr +- */ +- if (vblank_work->stream->link->replay_settings.replay_feature_enabled) +- amdgpu_dm_replay_enable(vblank_work->stream, false); +- else if (vblank_work->enable) { ++ if (vblank_work->enable) { + if (vblank_work->stream->link->psr_settings.psr_version < DC_PSR_VERSION_SU_1 && + vblank_work->stream->link->psr_settings.psr_allow_active) + amdgpu_dm_psr_disable(vblank_work->stream); +@@ -138,7 +132,6 @@ static void amdgpu_dm_crtc_vblank_control_worker(struct work_struct *work) + #ifdef CONFIG_DRM_AMD_SECURE_DISPLAY + !amdgpu_dm_crc_window_is_activated(&vblank_work->acrtc->base) && + #endif +- vblank_work->stream->link->panel_config.psr.disallow_replay && + vblank_work->acrtc->dm_irq_params.allow_psr_entry) { + amdgpu_dm_psr_enable(vblank_work->stream); + } +diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c +index 59c2a3545db34..a84f1e376dee4 100644 +--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c ++++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c +@@ -87,6 +87,20 @@ static const struct IP_BASE CLK_BASE = { { { { 0x00016C00, 0x02401800, 0, 0, 0, + #define CLK1_CLK_PLL_REQ__PllSpineDiv_MASK 0x0000F000L + #define CLK1_CLK_PLL_REQ__FbMult_frac_MASK 0xFFFF0000L + ++#define regCLK1_CLK2_BYPASS_CNTL 0x029c ++#define regCLK1_CLK2_BYPASS_CNTL_BASE_IDX 0 ++ ++#define CLK1_CLK2_BYPASS_CNTL__CLK2_BYPASS_SEL__SHIFT 0x0 ++#define CLK1_CLK2_BYPASS_CNTL__CLK2_BYPASS_DIV__SHIFT 0x10 ++#define CLK1_CLK2_BYPASS_CNTL__CLK2_BYPASS_SEL_MASK 0x00000007L ++#define CLK1_CLK2_BYPASS_CNTL__CLK2_BYPASS_DIV_MASK 0x000F0000L ++ ++#define regCLK6_0_CLK6_spll_field_8 0x464b ++#define regCLK6_0_CLK6_spll_field_8_BASE_IDX 0 ++ ++#define CLK6_0_CLK6_spll_field_8__spll_ssc_en__SHIFT 0xd ++#define CLK6_0_CLK6_spll_field_8__spll_ssc_en_MASK 0x00002000L ++ + #define REG(reg_name) \ + (CLK_BASE.instance[0].segment[reg ## reg_name ## _BASE_IDX] + reg ## reg_name) + +@@ -157,6 +171,37 @@ static void dcn314_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state + } + } + ++bool dcn314_is_spll_ssc_enabled(struct clk_mgr *clk_mgr_base) ++{ ++ struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); ++ uint32_t ssc_enable; ++ ++ REG_GET(CLK6_0_CLK6_spll_field_8, spll_ssc_en, &ssc_enable); ++ ++ return ssc_enable == 1; ++} ++ ++void dcn314_init_clocks(struct clk_mgr *clk_mgr) ++{ ++ struct clk_mgr_internal *clk_mgr_int = TO_CLK_MGR_INTERNAL(clk_mgr); ++ uint32_t ref_dtbclk = clk_mgr->clks.ref_dtbclk_khz; ++ ++ memset(&(clk_mgr->clks), 0, sizeof(struct dc_clocks)); ++ // Assumption is that boot state always supports pstate ++ clk_mgr->clks.ref_dtbclk_khz = ref_dtbclk; // restore ref_dtbclk ++ clk_mgr->clks.p_state_change_support = true; ++ clk_mgr->clks.prev_p_state_change_support = true; ++ clk_mgr->clks.pwr_state = DCN_PWR_STATE_UNKNOWN; ++ clk_mgr->clks.zstate_support = DCN_ZSTATE_SUPPORT_UNKNOWN; ++ ++ // to adjust dp_dto reference clock if ssc is enable otherwise to apply dprefclk ++ if (dcn314_is_spll_ssc_enabled(clk_mgr)) ++ clk_mgr->dp_dto_source_clock_in_khz = ++ dce_adjust_dp_ref_freq_for_ss(clk_mgr_int, clk_mgr->dprefclk_khz); ++ else ++ clk_mgr->dp_dto_source_clock_in_khz = clk_mgr->dprefclk_khz; ++} ++ + void dcn314_update_clocks(struct clk_mgr *clk_mgr_base, + struct dc_state *context, + bool safe_to_lower) +@@ -433,6 +478,11 @@ static DpmClocks314_t dummy_clocks; + + static struct dcn314_watermarks dummy_wms = { 0 }; + ++static struct dcn314_ss_info_table ss_info_table = { ++ .ss_divider = 1000, ++ .ss_percentage = {0, 0, 375, 375, 375} ++}; ++ + static void dcn314_build_watermark_ranges(struct clk_bw_params *bw_params, struct dcn314_watermarks *table) + { + int i, num_valid_sets; +@@ -705,13 +755,31 @@ static struct clk_mgr_funcs dcn314_funcs = { + .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz, + .get_dtb_ref_clk_frequency = dcn31_get_dtb_ref_freq_khz, + .update_clocks = dcn314_update_clocks, +- .init_clocks = dcn31_init_clocks, ++ .init_clocks = dcn314_init_clocks, + .enable_pme_wa = dcn314_enable_pme_wa, + .are_clock_states_equal = dcn314_are_clock_states_equal, + .notify_wm_ranges = dcn314_notify_wm_ranges + }; + extern struct clk_mgr_funcs dcn3_fpga_funcs; + ++static void dcn314_read_ss_info_from_lut(struct clk_mgr_internal *clk_mgr) ++{ ++ uint32_t clock_source; ++ //uint32_t ssc_enable; ++ ++ REG_GET(CLK1_CLK2_BYPASS_CNTL, CLK2_BYPASS_SEL, &clock_source); ++ //REG_GET(CLK6_0_CLK6_spll_field_8, spll_ssc_en, &ssc_enable); ++ ++ if (dcn314_is_spll_ssc_enabled(&clk_mgr->base) && (clock_source < ARRAY_SIZE(ss_info_table.ss_percentage))) { ++ clk_mgr->dprefclk_ss_percentage = ss_info_table.ss_percentage[clock_source]; ++ ++ if (clk_mgr->dprefclk_ss_percentage != 0) { ++ clk_mgr->ss_on_dprefclk = true; ++ clk_mgr->dprefclk_ss_divider = ss_info_table.ss_divider; ++ } ++ } ++} ++ + void dcn314_clk_mgr_construct( + struct dc_context *ctx, + struct clk_mgr_dcn314 *clk_mgr, +@@ -779,6 +847,7 @@ void dcn314_clk_mgr_construct( + clk_mgr->base.base.dprefclk_khz = 600000; + clk_mgr->base.base.clks.ref_dtbclk_khz = 600000; + dce_clock_read_ss_info(&clk_mgr->base); ++ dcn314_read_ss_info_from_lut(&clk_mgr->base); + /*if bios enabled SS, driver needs to adjust dtb clock, only enable with correct bios*/ + + clk_mgr->base.base.bw_params = &dcn314_bw_params; +diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.h b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.h +index 171f84340eb2f..002c28e807208 100644 +--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.h ++++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.h +@@ -28,6 +28,8 @@ + #define __DCN314_CLK_MGR_H__ + #include "clk_mgr_internal.h" + ++#define DCN314_NUM_CLOCK_SOURCES 5 ++ + struct dcn314_watermarks; + + struct dcn314_smu_watermark_set { +@@ -40,9 +42,18 @@ struct clk_mgr_dcn314 { + struct dcn314_smu_watermark_set smu_wm_set; + }; + ++struct dcn314_ss_info_table { ++ uint32_t ss_divider; ++ uint32_t ss_percentage[DCN314_NUM_CLOCK_SOURCES]; ++}; ++ + bool dcn314_are_clock_states_equal(struct dc_clocks *a, + struct dc_clocks *b); + ++bool dcn314_is_spll_ssc_enabled(struct clk_mgr *clk_mgr_base); ++ ++void dcn314_init_clocks(struct clk_mgr *clk_mgr); ++ + void dcn314_update_clocks(struct clk_mgr *clk_mgr_base, + struct dc_state *context, + bool safe_to_lower); +diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c +index 45ede6440a79f..4ef90a3add1c9 100644 +--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c ++++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c +@@ -126,21 +126,13 @@ static void dcn35_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state * + continue; + if (pipe->stream && (pipe->stream->dpms_off || dc_is_virtual_signal(pipe->stream->signal) || + !pipe->stream->link_enc)) { +- struct stream_encoder *stream_enc = pipe->stream_res.stream_enc; +- + if (disable) { +- if (stream_enc && stream_enc->funcs->disable_fifo) +- pipe->stream_res.stream_enc->funcs->disable_fifo(stream_enc); +- + if (pipe->stream_res.tg && pipe->stream_res.tg->funcs->immediate_disable_crtc) + pipe->stream_res.tg->funcs->immediate_disable_crtc(pipe->stream_res.tg); + + reset_sync_context_for_pipe(dc, context, i); + } else { + pipe->stream_res.tg->funcs->enable_crtc(pipe->stream_res.tg); +- +- if (stream_enc && stream_enc->funcs->enable_fifo) +- pipe->stream_res.stream_enc->funcs->enable_fifo(stream_enc); + } + } + } +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c +index bc098098345cf..bbdeda489768b 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c +@@ -1964,6 +1964,10 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c + wait_for_no_pipes_pending(dc, context); + /* pplib is notified if disp_num changed */ + dc->hwss.optimize_bandwidth(dc, context); ++ /* Need to do otg sync again as otg could be out of sync due to otg ++ * workaround applied during clock update ++ */ ++ dc_trigger_sync(dc, context); + } + + if (dc->hwss.update_dsc_pg) +diff --git a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h +index e2a3aa8812df4..811474f4419bd 100644 +--- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h ++++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h +@@ -244,7 +244,7 @@ enum pixel_format { + #define DC_MAX_DIRTY_RECTS 3 + struct dc_flip_addrs { + struct dc_plane_address address; +- unsigned int flip_timestamp_in_us; ++ unsigned long long flip_timestamp_in_us; + bool flip_immediate; + /* TODO: add flip duration for FreeSync */ + bool triplebuffer_flips; +diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c +index 140598f18bbdd..f0458b8f00af8 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c ++++ b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c +@@ -782,7 +782,7 @@ static void get_azalia_clock_info_dp( + /*audio_dto_module = dpDtoSourceClockInkhz * 10,000; + * [khz] ->[100Hz] */ + azalia_clock_info->audio_dto_module = +- pll_info->dp_dto_source_clock_in_khz * 10; ++ pll_info->audio_dto_source_clock_in_khz * 10; + } + + void dce_aud_wall_dto_setup( +diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c +index 5d3f6fa1011e8..970644b695cd4 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c ++++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c +@@ -975,6 +975,9 @@ static bool dcn31_program_pix_clk( + look_up_in_video_optimized_rate_tlb(pix_clk_params->requested_pix_clk_100hz / 10); + struct bp_pixel_clock_parameters bp_pc_params = {0}; + enum transmitter_color_depth bp_pc_colour_depth = TRANSMITTER_COLOR_DEPTH_24; ++ ++ if (clock_source->ctx->dc->clk_mgr->dp_dto_source_clock_in_khz != 0) ++ dp_dto_ref_khz = clock_source->ctx->dc->clk_mgr->dp_dto_source_clock_in_khz; + // For these signal types Driver to program DP_DTO without calling VBIOS Command table + if (dc_is_dp_signal(pix_clk_params->signal_type) || dc_is_virtual_signal(pix_clk_params->signal_type)) { + if (e) { +@@ -1088,6 +1091,10 @@ static bool get_pixel_clk_frequency_100hz( + struct dce110_clk_src *clk_src = TO_DCE110_CLK_SRC(clock_source); + unsigned int clock_hz = 0; + unsigned int modulo_hz = 0; ++ unsigned int dp_dto_ref_khz = clock_source->ctx->dc->clk_mgr->dprefclk_khz; ++ ++ if (clock_source->ctx->dc->clk_mgr->dp_dto_source_clock_in_khz != 0) ++ dp_dto_ref_khz = clock_source->ctx->dc->clk_mgr->dp_dto_source_clock_in_khz; + + if (clock_source->id == CLOCK_SOURCE_ID_DP_DTO) { + clock_hz = REG_READ(PHASE[inst]); +@@ -1100,7 +1107,7 @@ static bool get_pixel_clk_frequency_100hz( + modulo_hz = REG_READ(MODULO[inst]); + if (modulo_hz) + *pixel_clk_khz = div_u64((uint64_t)clock_hz* +- clock_source->ctx->dc->clk_mgr->dprefclk_khz*10, ++ dp_dto_ref_khz*10, + modulo_hz); + else + *pixel_clk_khz = 0; +diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dio_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dio_link_encoder.c +index f91e088952755..da94e5309fbaf 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dio_link_encoder.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dio_link_encoder.c +@@ -256,6 +256,10 @@ void dcn35_link_encoder_construct( + enc10->base.features.flags.bits.IS_UHBR10_CAPABLE = bp_cap_info.DP_UHBR10_EN; + enc10->base.features.flags.bits.IS_UHBR13_5_CAPABLE = bp_cap_info.DP_UHBR13_5_EN; + enc10->base.features.flags.bits.IS_UHBR20_CAPABLE = bp_cap_info.DP_UHBR20_EN; ++ if (bp_cap_info.DP_IS_USB_C) { ++ /*BIOS not switch to use CONNECTOR_ID_USBC = 24 yet*/ ++ enc10->base.features.flags.bits.DP_IS_USB_C = 1; ++ } + + } else { + DC_LOG_WARNING("%s: Failed to get encoder_cap_info from VBIOS with error code %d!\n", +@@ -264,4 +268,5 @@ void dcn35_link_encoder_construct( + } + if (enc10->base.ctx->dc->debug.hdmi20_disable) + enc10->base.features.flags.bits.HDMI_6GB_EN = 0; ++ + } +diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c +index cbdfb762c10c5..6c84b0fa40f44 100644 +--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c ++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c +@@ -813,6 +813,8 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman + (v->DRAMSpeedPerState[mode_lib->vba.VoltageLevel] <= MEM_STROBE_FREQ_MHZ || + v->DCFCLKPerState[mode_lib->vba.VoltageLevel] <= DCFCLK_FREQ_EXTRA_PREFETCH_REQ_MHZ) ? + mode_lib->vba.ip.min_prefetch_in_strobe_us : 0, ++ mode_lib->vba.PrefetchModePerState[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb] > 0 || mode_lib->vba.DRAMClockChangeRequirementFinal == false, ++ + /* Output */ + &v->DSTXAfterScaler[k], + &v->DSTYAfterScaler[k], +@@ -3317,6 +3319,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l + v->SwathHeightCThisState[k], v->TWait, + (v->DRAMSpeedPerState[i] <= MEM_STROBE_FREQ_MHZ || v->DCFCLKState[i][j] <= DCFCLK_FREQ_EXTRA_PREFETCH_REQ_MHZ) ? + mode_lib->vba.ip.min_prefetch_in_strobe_us : 0, ++ mode_lib->vba.PrefetchModePerState[i][j] > 0 || mode_lib->vba.DRAMClockChangeRequirementFinal == false, + + /* Output */ + &v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.DSTXAfterScaler[k], +diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c +index d940dfa5ae43e..80fccd4999a58 100644 +--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c ++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c +@@ -3423,6 +3423,7 @@ bool dml32_CalculatePrefetchSchedule( + unsigned int SwathHeightC, + double TWait, + double TPreReq, ++ bool ExtendPrefetchIfPossible, + /* Output */ + double *DSTXAfterScaler, + double *DSTYAfterScaler, +@@ -3892,12 +3893,32 @@ bool dml32_CalculatePrefetchSchedule( + /* Clamp to oto for bandwidth calculation */ + LinesForPrefetchBandwidth = dst_y_prefetch_oto; + } else { +- *DestinationLinesForPrefetch = dst_y_prefetch_equ; +- TimeForFetchingMetaPTE = Tvm_equ; +- TimeForFetchingRowInVBlank = Tr0_equ; +- *PrefetchBandwidth = prefetch_bw_equ; +- /* Clamp to equ for bandwidth calculation */ +- LinesForPrefetchBandwidth = dst_y_prefetch_equ; ++ /* For mode programming we want to extend the prefetch as much as possible ++ * (up to oto, or as long as we can for equ) if we're not already applying ++ * the 60us prefetch requirement. This is to avoid intermittent underflow ++ * issues during prefetch. ++ * ++ * The prefetch extension is applied under the following scenarios: ++ * 1. We're in prefetch mode > 0 (i.e. we don't support MCLK switch in blank) ++ * 2. We're using subvp or drr methods of p-state switch, in which case we ++ * we don't care if prefetch takes up more of the blanking time ++ * ++ * Mode programming typically chooses the smallest prefetch time possible ++ * (i.e. highest bandwidth during prefetch) presumably to create margin between ++ * p-states / c-states that happen in vblank and prefetch. Therefore we only ++ * apply this prefetch extension when p-state in vblank is not required (UCLK ++ * p-states take up the most vblank time). ++ */ ++ if (ExtendPrefetchIfPossible && TPreReq == 0 && VStartup < MaxVStartup) { ++ MyError = true; ++ } else { ++ *DestinationLinesForPrefetch = dst_y_prefetch_equ; ++ TimeForFetchingMetaPTE = Tvm_equ; ++ TimeForFetchingRowInVBlank = Tr0_equ; ++ *PrefetchBandwidth = prefetch_bw_equ; ++ /* Clamp to equ for bandwidth calculation */ ++ LinesForPrefetchBandwidth = dst_y_prefetch_equ; ++ } + } + + *DestinationLinesToRequestVMInVBlank = dml_ceil(4.0 * TimeForFetchingMetaPTE / LineTime, 1.0) / 4.0; +diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h +index 592d174df6c62..5d34735df83db 100644 +--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h ++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h +@@ -747,6 +747,7 @@ bool dml32_CalculatePrefetchSchedule( + unsigned int SwathHeightC, + double TWait, + double TPreReq, ++ bool ExtendPrefetchIfPossible, + /* Output */ + double *DSTXAfterScaler, + double *DSTYAfterScaler, +diff --git a/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c b/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c +index 62ce95bac8f2b..9be5ebf3a8c0b 100644 +--- a/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c ++++ b/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c +@@ -6229,7 +6229,7 @@ static void set_calculate_prefetch_schedule_params(struct display_mode_lib_st *m + CalculatePrefetchSchedule_params->GPUVMEnable = mode_lib->ms.cache_display_cfg.plane.GPUVMEnable; + CalculatePrefetchSchedule_params->HostVMEnable = mode_lib->ms.cache_display_cfg.plane.HostVMEnable; + CalculatePrefetchSchedule_params->HostVMMaxNonCachedPageTableLevels = mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels; +- CalculatePrefetchSchedule_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes; ++ CalculatePrefetchSchedule_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024; + CalculatePrefetchSchedule_params->DynamicMetadataEnable = mode_lib->ms.cache_display_cfg.plane.DynamicMetadataEnable[k]; + CalculatePrefetchSchedule_params->DynamicMetadataVMEnabled = mode_lib->ms.ip.dynamic_metadata_vm_enabled; + CalculatePrefetchSchedule_params->DynamicMetadataLinesBeforeActiveRequired = mode_lib->ms.cache_display_cfg.plane.DynamicMetadataLinesBeforeActiveRequired[k]; +diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_utils.c b/drivers/gpu/drm/amd/display/dc/dml2/dml2_utils.c +index 2498b8341199b..d6a68484153c7 100644 +--- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_utils.c ++++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_utils.c +@@ -157,6 +157,14 @@ bool is_dp2p0_output_encoder(const struct pipe_ctx *pipe_ctx) + { + /* If this assert is hit then we have a link encoder dynamic management issue */ + ASSERT(pipe_ctx->stream_res.hpo_dp_stream_enc ? pipe_ctx->link_res.hpo_dp_link_enc != NULL : true); ++ /* Count MST hubs once by treating only 1st remote sink in topology as an encoder */ ++ if (pipe_ctx->stream->link && pipe_ctx->stream->link->remote_sinks[0]) { ++ return (pipe_ctx->stream_res.hpo_dp_stream_enc && ++ pipe_ctx->link_res.hpo_dp_link_enc && ++ dc_is_dp_signal(pipe_ctx->stream->signal) && ++ (pipe_ctx->stream->link->remote_sinks[0]->sink_id == pipe_ctx->stream->sink->sink_id)); ++ } ++ + return (pipe_ctx->stream_res.hpo_dp_stream_enc && + pipe_ctx->link_res.hpo_dp_link_enc && + dc_is_dp_signal(pipe_ctx->stream->signal)); +diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c +index 9b8299d97e400..9fedf99475695 100644 +--- a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c ++++ b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c +@@ -1353,7 +1353,7 @@ static void build_audio_output( + if (state->clk_mgr && + (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT || + pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)) { +- audio_output->pll_info.dp_dto_source_clock_in_khz = ++ audio_output->pll_info.audio_dto_source_clock_in_khz = + state->clk_mgr->funcs->get_dp_ref_clk_frequency( + state->clk_mgr); + } +@@ -2124,7 +2124,8 @@ static void dce110_reset_hw_ctx_wrap( + BREAK_TO_DEBUGGER(); + } + pipe_ctx_old->stream_res.tg->funcs->disable_crtc(pipe_ctx_old->stream_res.tg); +- pipe_ctx_old->stream->link->phy_state.symclk_ref_cnts.otg = 0; ++ if (dc_is_hdmi_tmds_signal(pipe_ctx_old->stream->signal)) ++ pipe_ctx_old->stream->link->phy_state.symclk_ref_cnts.otg = 0; + pipe_ctx_old->plane_res.mi->funcs->free_mem_input( + pipe_ctx_old->plane_res.mi, dc->current_state->stream_count); + +diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c +index cdb903116eb7c..1fc8436c8130e 100644 +--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c ++++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c +@@ -1057,7 +1057,8 @@ static void dcn10_reset_back_end_for_pipe( + if (pipe_ctx->stream_res.tg->funcs->set_drr) + pipe_ctx->stream_res.tg->funcs->set_drr( + pipe_ctx->stream_res.tg, NULL); +- pipe_ctx->stream->link->phy_state.symclk_ref_cnts.otg = 0; ++ if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal)) ++ pipe_ctx->stream->link->phy_state.symclk_ref_cnts.otg = 0; + } + + for (i = 0; i < dc->res_pool->pipe_count; i++) +diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c +index 608221b0dd5dc..da0181fef411f 100644 +--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c ++++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c +@@ -1877,6 +1877,8 @@ void dcn20_program_front_end_for_ctx( + int i; + struct dce_hwseq *hws = dc->hwseq; + DC_LOGGER_INIT(dc->ctx->logger); ++ unsigned int prev_hubp_count = 0; ++ unsigned int hubp_count = 0; + + if (resource_is_pipe_topology_changed(dc->current_state, context)) + resource_log_pipe_topology_update(dc, context); +@@ -1894,6 +1896,20 @@ void dcn20_program_front_end_for_ctx( + } + } + ++ for (i = 0; i < dc->res_pool->pipe_count; i++) { ++ if (dc->current_state->res_ctx.pipe_ctx[i].plane_state) ++ prev_hubp_count++; ++ if (context->res_ctx.pipe_ctx[i].plane_state) ++ hubp_count++; ++ } ++ ++ if (prev_hubp_count == 0 && hubp_count > 0) { ++ if (dc->res_pool->hubbub->funcs->force_pstate_change_control) ++ dc->res_pool->hubbub->funcs->force_pstate_change_control( ++ dc->res_pool->hubbub, true, false); ++ udelay(500); ++ } ++ + /* Set pipe update flags and lock pipes */ + for (i = 0; i < dc->res_pool->pipe_count; i++) + dcn20_detect_pipe_changes(&dc->current_state->res_ctx.pipe_ctx[i], +@@ -2039,6 +2055,10 @@ void dcn20_post_unlock_program_front_end( + } + } + ++ if (dc->res_pool->hubbub->funcs->force_pstate_change_control) ++ dc->res_pool->hubbub->funcs->force_pstate_change_control( ++ dc->res_pool->hubbub, false, false); ++ + for (i = 0; i < dc->res_pool->pipe_count; i++) { + struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; + +@@ -2590,7 +2610,8 @@ static void dcn20_reset_back_end_for_pipe( + * the case where the same symclk is shared across multiple otg + * instances + */ +- link->phy_state.symclk_ref_cnts.otg = 0; ++ if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal)) ++ link->phy_state.symclk_ref_cnts.otg = 0; + if (link->phy_state.symclk_state == SYMCLK_ON_TX_OFF) { + link_hwss->disable_link_output(link, + &pipe_ctx->link_res, pipe_ctx->stream->signal); +diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c +index 52656691ae484..3a70a3cbc274c 100644 +--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c ++++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c +@@ -523,7 +523,8 @@ static void dcn31_reset_back_end_for_pipe( + if (pipe_ctx->stream_res.tg->funcs->set_odm_bypass) + pipe_ctx->stream_res.tg->funcs->set_odm_bypass( + pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing); +- pipe_ctx->stream->link->phy_state.symclk_ref_cnts.otg = 0; ++ if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal)) ++ pipe_ctx->stream->link->phy_state.symclk_ref_cnts.otg = 0; + + if (pipe_ctx->stream_res.tg->funcs->set_drr) + pipe_ctx->stream_res.tg->funcs->set_drr( +diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c +index 5bf9e7c1e052f..cb9d8389329ff 100644 +--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c ++++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c +@@ -995,9 +995,22 @@ static int calc_mpc_flow_ctrl_cnt(const struct dc_stream_state *stream, + static void update_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable) + { + struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc; ++ struct dc *dc = pipe_ctx->stream->ctx->dc; + struct dc_stream_state *stream = pipe_ctx->stream; + struct pipe_ctx *odm_pipe; + int opp_cnt = 1; ++ struct dccg *dccg = dc->res_pool->dccg; ++ /* It has been found that when DSCCLK is lower than 16Mhz, we will get DCN ++ * register access hung. When DSCCLk is based on refclk, DSCCLk is always a ++ * fixed value higher than 16Mhz so the issue doesn't occur. When DSCCLK is ++ * generated by DTO, DSCCLK would be based on 1/3 dispclk. For small timings ++ * with DSC such as 480p60Hz, the dispclk could be low enough to trigger ++ * this problem. We are implementing a workaround here to keep using dscclk ++ * based on fixed value refclk when timing is smaller than 3x16Mhz (i.e ++ * 48Mhz) pixel clock to avoid hitting this problem. ++ */ ++ bool should_use_dto_dscclk = (dccg->funcs->set_dto_dscclk != NULL) && ++ stream->timing.pix_clk_100hz > 480000; + + ASSERT(dsc); + for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) +@@ -1020,12 +1033,16 @@ static void update_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable) + + dsc->funcs->dsc_set_config(dsc, &dsc_cfg, &dsc_optc_cfg); + dsc->funcs->dsc_enable(dsc, pipe_ctx->stream_res.opp->inst); ++ if (should_use_dto_dscclk) ++ dccg->funcs->set_dto_dscclk(dccg, dsc->inst); + for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) { + struct display_stream_compressor *odm_dsc = odm_pipe->stream_res.dsc; + + ASSERT(odm_dsc); + odm_dsc->funcs->dsc_set_config(odm_dsc, &dsc_cfg, &dsc_optc_cfg); + odm_dsc->funcs->dsc_enable(odm_dsc, odm_pipe->stream_res.opp->inst); ++ if (should_use_dto_dscclk) ++ dccg->funcs->set_dto_dscclk(dccg, odm_dsc->inst); + } + dsc_cfg.dc_dsc_cfg.num_slices_h *= opp_cnt; + dsc_cfg.pic_width *= opp_cnt; +@@ -1045,9 +1062,13 @@ static void update_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable) + OPTC_DSC_DISABLED, 0, 0); + + /* disable DSC block */ ++ if (dccg->funcs->set_ref_dscclk) ++ dccg->funcs->set_ref_dscclk(dccg, pipe_ctx->stream_res.dsc->inst); + dsc->funcs->dsc_disable(pipe_ctx->stream_res.dsc); + for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) { + ASSERT(odm_pipe->stream_res.dsc); ++ if (dccg->funcs->set_ref_dscclk) ++ dccg->funcs->set_ref_dscclk(dccg, odm_pipe->stream_res.dsc->inst); + odm_pipe->stream_res.dsc->funcs->dsc_disable(odm_pipe->stream_res.dsc); + } + } +@@ -1130,6 +1151,10 @@ void dcn32_update_odm(struct dc *dc, struct dc_state *context, struct pipe_ctx * + if (!pipe_ctx->next_odm_pipe && current_pipe_ctx->next_odm_pipe && + current_pipe_ctx->next_odm_pipe->stream_res.dsc) { + struct display_stream_compressor *dsc = current_pipe_ctx->next_odm_pipe->stream_res.dsc; ++ struct dccg *dccg = dc->res_pool->dccg; ++ ++ if (dccg->funcs->set_ref_dscclk) ++ dccg->funcs->set_ref_dscclk(dccg, dsc->inst); + /* disconnect DSC block from stream */ + dsc->funcs->dsc_disconnect(dsc); + } +diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h +index fa9614bcb1605..55ded5fb8a38f 100644 +--- a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h ++++ b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h +@@ -314,6 +314,7 @@ struct clk_mgr { + bool force_smu_not_present; + bool dc_mode_softmax_enabled; + int dprefclk_khz; // Used by program pixel clock in clock source funcs, need to figureout where this goes ++ int dp_dto_source_clock_in_khz; // Used to program DP DTO with ss adjustment on DCN314 + int dentist_vco_freq_khz; + struct clk_state_registers_and_bypass boot_snapshot; + struct clk_bw_params *bw_params; +diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h +index ce2f0c0e82bd6..6b44557fcb1a8 100644 +--- a/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h ++++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h +@@ -201,6 +201,10 @@ struct dccg_funcs { + struct dccg *dccg, + enum streamclk_source src, + uint32_t otg_inst); ++ void (*set_dto_dscclk)( ++ struct dccg *dccg, ++ uint32_t dsc_inst); ++ void (*set_ref_dscclk)(struct dccg *dccg, uint32_t dsc_inst); + }; + + #endif //__DAL_DCCG_H__ +diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c +index 04d1ecd6e5934..a08ae59c1ea9f 100644 +--- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c ++++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c +@@ -776,10 +776,26 @@ static bool dp_set_dsc_on_rx(struct pipe_ctx *pipe_ctx, bool enable) + */ + void link_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable) + { ++ /* TODO: Move this to HWSS as this is hardware programming sequence not a ++ * link layer sequence ++ */ + struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc; ++ struct dc *dc = pipe_ctx->stream->ctx->dc; + struct dc_stream_state *stream = pipe_ctx->stream; + struct pipe_ctx *odm_pipe; + int opp_cnt = 1; ++ struct dccg *dccg = dc->res_pool->dccg; ++ /* It has been found that when DSCCLK is lower than 16Mhz, we will get DCN ++ * register access hung. When DSCCLk is based on refclk, DSCCLk is always a ++ * fixed value higher than 16Mhz so the issue doesn't occur. When DSCCLK is ++ * generated by DTO, DSCCLK would be based on 1/3 dispclk. For small timings ++ * with DSC such as 480p60Hz, the dispclk could be low enough to trigger ++ * this problem. We are implementing a workaround here to keep using dscclk ++ * based on fixed value refclk when timing is smaller than 3x16Mhz (i.e ++ * 48Mhz) pixel clock to avoid hitting this problem. ++ */ ++ bool should_use_dto_dscclk = (dccg->funcs->set_dto_dscclk != NULL) && ++ stream->timing.pix_clk_100hz > 480000; + DC_LOGGER_INIT(dsc->ctx->logger); + + for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) +@@ -802,11 +818,15 @@ void link_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable) + + dsc->funcs->dsc_set_config(dsc, &dsc_cfg, &dsc_optc_cfg); + dsc->funcs->dsc_enable(dsc, pipe_ctx->stream_res.opp->inst); ++ if (should_use_dto_dscclk) ++ dccg->funcs->set_dto_dscclk(dccg, dsc->inst); + for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) { + struct display_stream_compressor *odm_dsc = odm_pipe->stream_res.dsc; + + odm_dsc->funcs->dsc_set_config(odm_dsc, &dsc_cfg, &dsc_optc_cfg); + odm_dsc->funcs->dsc_enable(odm_dsc, odm_pipe->stream_res.opp->inst); ++ if (should_use_dto_dscclk) ++ dccg->funcs->set_dto_dscclk(dccg, odm_dsc->inst); + } + dsc_cfg.dc_dsc_cfg.num_slices_h *= opp_cnt; + dsc_cfg.pic_width *= opp_cnt; +@@ -856,9 +876,14 @@ void link_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable) + } + + /* disable DSC block */ ++ if (dccg->funcs->set_ref_dscclk) ++ dccg->funcs->set_ref_dscclk(dccg, pipe_ctx->stream_res.dsc->inst); + pipe_ctx->stream_res.dsc->funcs->dsc_disable(pipe_ctx->stream_res.dsc); +- for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) ++ for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) { ++ if (dccg->funcs->set_ref_dscclk) ++ dccg->funcs->set_ref_dscclk(dccg, odm_pipe->stream_res.dsc->inst); + odm_pipe->stream_res.dsc->funcs->dsc_disable(odm_pipe->stream_res.dsc); ++ } + } + } + +@@ -1061,18 +1086,21 @@ static struct fixed31_32 get_pbn_from_bw_in_kbps(uint64_t kbps) + uint32_t denominator = 1; + + /* +- * margin 5300ppm + 300ppm ~ 0.6% as per spec, factor is 1.006 ++ * The 1.006 factor (margin 5300ppm + 300ppm ~ 0.6% as per spec) is not ++ * required when determining PBN/time slot utilization on the link between ++ * us and the branch, since that overhead is already accounted for in ++ * the get_pbn_per_slot function. ++ * + * The unit of 54/64Mbytes/sec is an arbitrary unit chosen based on + * common multiplier to render an integer PBN for all link rate/lane + * counts combinations + * calculate +- * peak_kbps *= (1006/1000) + * peak_kbps *= (64/54) +- * peak_kbps *= 8 convert to bytes ++ * peak_kbps /= (8 * 1000) convert to bytes + */ + +- numerator = 64 * PEAK_FACTOR_X1000; +- denominator = 54 * 8 * 1000 * 1000; ++ numerator = 64; ++ denominator = 54 * 8 * 1000; + kbps *= numerator; + peak_kbps = dc_fixpt_from_fraction(kbps, denominator); + +diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c +index 7581023daa478..d6e1f969bfd52 100644 +--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c ++++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c +@@ -50,6 +50,7 @@ static bool get_bw_alloc_proceed_flag(struct dc_link *tmp) + && tmp->hpd_status + && tmp->dpia_bw_alloc_config.bw_alloc_enabled); + } ++ + static void reset_bw_alloc_struct(struct dc_link *link) + { + link->dpia_bw_alloc_config.bw_alloc_enabled = false; +@@ -59,6 +60,11 @@ static void reset_bw_alloc_struct(struct dc_link *link) + link->dpia_bw_alloc_config.bw_granularity = 0; + link->dpia_bw_alloc_config.response_ready = false; + } ++ ++#define BW_GRANULARITY_0 4 // 0.25 Gbps ++#define BW_GRANULARITY_1 2 // 0.5 Gbps ++#define BW_GRANULARITY_2 1 // 1 Gbps ++ + static uint8_t get_bw_granularity(struct dc_link *link) + { + uint8_t bw_granularity = 0; +@@ -71,16 +77,20 @@ static uint8_t get_bw_granularity(struct dc_link *link) + + switch (bw_granularity & 0x3) { + case 0: +- bw_granularity = 4; ++ bw_granularity = BW_GRANULARITY_0; + break; + case 1: ++ bw_granularity = BW_GRANULARITY_1; ++ break; ++ case 2: + default: +- bw_granularity = 2; ++ bw_granularity = BW_GRANULARITY_2; + break; + } + + return bw_granularity; + } ++ + static int get_estimated_bw(struct dc_link *link) + { + uint8_t bw_estimated_bw = 0; +@@ -93,31 +103,7 @@ static int get_estimated_bw(struct dc_link *link) + + return bw_estimated_bw * (Kbps_TO_Gbps / link->dpia_bw_alloc_config.bw_granularity); + } +-static bool allocate_usb4_bw(int *stream_allocated_bw, int bw_needed, struct dc_link *link) +-{ +- if (bw_needed > 0) +- *stream_allocated_bw += bw_needed; +- +- return true; +-} +-static bool deallocate_usb4_bw(int *stream_allocated_bw, int bw_to_dealloc, struct dc_link *link) +-{ +- bool ret = false; +- +- if (*stream_allocated_bw > 0) { +- *stream_allocated_bw -= bw_to_dealloc; +- ret = true; +- } else { +- //Do nothing for now +- ret = true; +- } + +- // Unplug so reset values +- if (!link->hpd_status) +- reset_bw_alloc_struct(link); +- +- return ret; +-} + /* + * Read all New BW alloc configuration ex: estimated_bw, allocated_bw, + * granuality, Driver_ID, CM_Group, & populate the BW allocation structs +@@ -128,7 +114,12 @@ static void init_usb4_bw_struct(struct dc_link *link) + // Init the known values + link->dpia_bw_alloc_config.bw_granularity = get_bw_granularity(link); + link->dpia_bw_alloc_config.estimated_bw = get_estimated_bw(link); ++ ++ DC_LOG_DEBUG("%s: bw_granularity(%d), estimated_bw(%d)\n", ++ __func__, link->dpia_bw_alloc_config.bw_granularity, ++ link->dpia_bw_alloc_config.estimated_bw); + } ++ + static uint8_t get_lowest_dpia_index(struct dc_link *link) + { + const struct dc *dc_struct = link->dc; +@@ -141,12 +132,15 @@ static uint8_t get_lowest_dpia_index(struct dc_link *link) + dc_struct->links[i]->ep_type != DISPLAY_ENDPOINT_USB4_DPIA) + continue; + +- if (idx > dc_struct->links[i]->link_index) ++ if (idx > dc_struct->links[i]->link_index) { + idx = dc_struct->links[i]->link_index; ++ break; ++ } + } + + return idx; + } ++ + /* + * Get the Max Available BW or Max Estimated BW for each Host Router + * +@@ -186,6 +180,7 @@ static int get_host_router_total_bw(struct dc_link *link, uint8_t type) + + return total_bw; + } ++ + /* + * Cleanup function for when the dpia is unplugged to reset struct + * and perform any required clean up +@@ -194,42 +189,50 @@ static int get_host_router_total_bw(struct dc_link *link, uint8_t type) + * + * return: none + */ +-static bool dpia_bw_alloc_unplug(struct dc_link *link) ++static void dpia_bw_alloc_unplug(struct dc_link *link) + { +- if (!link) +- return true; +- +- return deallocate_usb4_bw(&link->dpia_bw_alloc_config.sink_allocated_bw, +- link->dpia_bw_alloc_config.sink_allocated_bw, link); ++ if (link) { ++ DC_LOG_DEBUG("%s: resetting bw alloc config for link(%d)\n", ++ __func__, link->link_index); ++ link->dpia_bw_alloc_config.sink_allocated_bw = 0; ++ reset_bw_alloc_struct(link); ++ } + } ++ + static void set_usb4_req_bw_req(struct dc_link *link, int req_bw) + { + uint8_t requested_bw; + uint32_t temp; + +- // 1. Add check for this corner case #1 +- if (req_bw > link->dpia_bw_alloc_config.estimated_bw) ++ /* Error check whether request bw greater than allocated */ ++ if (req_bw > link->dpia_bw_alloc_config.estimated_bw) { ++ DC_LOG_ERROR("%s: Request bw greater than estimated bw for link(%d)\n", ++ __func__, link->link_index); + req_bw = link->dpia_bw_alloc_config.estimated_bw; ++ } + + temp = req_bw * link->dpia_bw_alloc_config.bw_granularity; + requested_bw = temp / Kbps_TO_Gbps; + +- // Always make sure to add more to account for floating points ++ /* Always make sure to add more to account for floating points */ + if (temp % Kbps_TO_Gbps) + ++requested_bw; + +- // 2. Add check for this corner case #2 ++ /* Error check whether requested and allocated are equal */ + req_bw = requested_bw * (Kbps_TO_Gbps / link->dpia_bw_alloc_config.bw_granularity); +- if (req_bw == link->dpia_bw_alloc_config.sink_allocated_bw) +- return; ++ if (req_bw == link->dpia_bw_alloc_config.sink_allocated_bw) { ++ DC_LOG_ERROR("%s: Request bw equals to allocated bw for link(%d)\n", ++ __func__, link->link_index); ++ } + +- if (core_link_write_dpcd( ++ link->dpia_bw_alloc_config.response_ready = false; // Reset flag ++ core_link_write_dpcd( + link, + REQUESTED_BW, + &requested_bw, +- sizeof(uint8_t)) == DC_OK) +- link->dpia_bw_alloc_config.response_ready = false; // Reset flag ++ sizeof(uint8_t)); + } ++ + /* + * Return the response_ready flag from dc_link struct + * +@@ -241,6 +244,7 @@ static bool get_cm_response_ready_flag(struct dc_link *link) + { + return link->dpia_bw_alloc_config.response_ready; + } ++ + // ------------------------------------------------------------------ + // PUBLIC FUNCTIONS + // ------------------------------------------------------------------ +@@ -277,27 +281,27 @@ bool link_dp_dpia_set_dptx_usb4_bw_alloc_support(struct dc_link *link) + DPTX_BW_ALLOCATION_MODE_CONTROL, + &response, + sizeof(uint8_t)) != DC_OK) { +- DC_LOG_DEBUG("%s: **** FAILURE Enabling DPtx BW Allocation Mode Support ***\n", +- __func__); ++ DC_LOG_DEBUG("%s: FAILURE Enabling DPtx BW Allocation Mode Support for link(%d)\n", ++ __func__, link->link_index); + } else { + // SUCCESS Enabled DPtx BW Allocation Mode Support +- link->dpia_bw_alloc_config.bw_alloc_enabled = true; +- DC_LOG_DEBUG("%s: **** SUCCESS Enabling DPtx BW Allocation Mode Support ***\n", +- __func__); ++ DC_LOG_DEBUG("%s: SUCCESS Enabling DPtx BW Allocation Mode Support for link(%d)\n", ++ __func__, link->link_index); + + ret = true; + init_usb4_bw_struct(link); ++ link->dpia_bw_alloc_config.bw_alloc_enabled = true; + } + } + + out: + return ret; + } ++ + void dpia_handle_bw_alloc_response(struct dc_link *link, uint8_t bw, uint8_t result) + { + int bw_needed = 0; + int estimated = 0; +- int host_router_total_estimated_bw = 0; + + if (!get_bw_alloc_proceed_flag((link))) + return; +@@ -306,14 +310,22 @@ void dpia_handle_bw_alloc_response(struct dc_link *link, uint8_t bw, uint8_t res + + case DPIA_BW_REQ_FAILED: + +- DC_LOG_DEBUG("%s: *** *** BW REQ FAILURE for DP-TX Request *** ***\n", __func__); ++ /* ++ * Ideally, we shouldn't run into this case as we always validate available ++ * bandwidth and request within that limit ++ */ ++ estimated = bw * (Kbps_TO_Gbps / link->dpia_bw_alloc_config.bw_granularity); + +- // Update the new Estimated BW value updated by CM +- link->dpia_bw_alloc_config.estimated_bw = +- bw * (Kbps_TO_Gbps / link->dpia_bw_alloc_config.bw_granularity); ++ DC_LOG_ERROR("%s: BW REQ FAILURE for DP-TX Request for link(%d)\n", ++ __func__, link->link_index); ++ DC_LOG_ERROR("%s: current estimated_bw(%d), new estimated_bw(%d)\n", ++ __func__, link->dpia_bw_alloc_config.estimated_bw, estimated); + ++ /* Update the new Estimated BW value updated by CM */ ++ link->dpia_bw_alloc_config.estimated_bw = estimated; ++ ++ /* Allocate the previously requested bandwidth */ + set_usb4_req_bw_req(link, link->dpia_bw_alloc_config.estimated_bw); +- link->dpia_bw_alloc_config.response_ready = false; + + /* + * If FAIL then it is either: +@@ -326,68 +338,34 @@ void dpia_handle_bw_alloc_response(struct dc_link *link, uint8_t bw, uint8_t res + + case DPIA_BW_REQ_SUCCESS: + +- DC_LOG_DEBUG("%s: *** BW REQ SUCCESS for DP-TX Request ***\n", __func__); +- +- // 1. SUCCESS 1st time before any Pruning is done +- // 2. SUCCESS after prev. FAIL before any Pruning is done +- // 3. SUCCESS after Pruning is done but before enabling link +- + bw_needed = bw * (Kbps_TO_Gbps / link->dpia_bw_alloc_config.bw_granularity); + +- // 1. +- if (!link->dpia_bw_alloc_config.sink_allocated_bw) { +- +- allocate_usb4_bw(&link->dpia_bw_alloc_config.sink_allocated_bw, bw_needed, link); +- link->dpia_bw_alloc_config.sink_verified_bw = +- link->dpia_bw_alloc_config.sink_allocated_bw; ++ DC_LOG_DEBUG("%s: BW REQ SUCCESS for DP-TX Request for link(%d)\n", ++ __func__, link->link_index); ++ DC_LOG_DEBUG("%s: current allocated_bw(%d), new allocated_bw(%d)\n", ++ __func__, link->dpia_bw_alloc_config.sink_allocated_bw, bw_needed); + +- // SUCCESS from first attempt +- if (link->dpia_bw_alloc_config.sink_allocated_bw > +- link->dpia_bw_alloc_config.sink_max_bw) +- link->dpia_bw_alloc_config.sink_verified_bw = +- link->dpia_bw_alloc_config.sink_max_bw; +- } +- // 3. +- else if (link->dpia_bw_alloc_config.sink_allocated_bw) { +- +- // Find out how much do we need to de-alloc +- if (link->dpia_bw_alloc_config.sink_allocated_bw > bw_needed) +- deallocate_usb4_bw(&link->dpia_bw_alloc_config.sink_allocated_bw, +- link->dpia_bw_alloc_config.sink_allocated_bw - bw_needed, link); +- else +- allocate_usb4_bw(&link->dpia_bw_alloc_config.sink_allocated_bw, +- bw_needed - link->dpia_bw_alloc_config.sink_allocated_bw, link); +- } +- +- // 4. If this is the 2nd sink then any unused bw will be reallocated to master DPIA +- // => check if estimated_bw changed ++ link->dpia_bw_alloc_config.sink_allocated_bw = bw_needed; + + link->dpia_bw_alloc_config.response_ready = true; + break; + + case DPIA_EST_BW_CHANGED: + +- DC_LOG_DEBUG("%s: *** ESTIMATED BW CHANGED for DP-TX Request ***\n", __func__); +- + estimated = bw * (Kbps_TO_Gbps / link->dpia_bw_alloc_config.bw_granularity); +- host_router_total_estimated_bw = get_host_router_total_bw(link, HOST_ROUTER_BW_ESTIMATED); + +- // 1. If due to unplug of other sink +- if (estimated == host_router_total_estimated_bw) { +- // First update the estimated & max_bw fields +- if (link->dpia_bw_alloc_config.estimated_bw < estimated) +- link->dpia_bw_alloc_config.estimated_bw = estimated; +- } +- // 2. If due to realloc bw btw 2 dpia due to plug OR realloc unused Bw +- else { +- // We lost estimated bw usually due to plug event of other dpia +- link->dpia_bw_alloc_config.estimated_bw = estimated; +- } ++ DC_LOG_DEBUG("%s: ESTIMATED BW CHANGED for link(%d)\n", ++ __func__, link->link_index); ++ DC_LOG_DEBUG("%s: current estimated_bw(%d), new estimated_bw(%d)\n", ++ __func__, link->dpia_bw_alloc_config.estimated_bw, estimated); ++ ++ link->dpia_bw_alloc_config.estimated_bw = estimated; + break; + + case DPIA_BW_ALLOC_CAPS_CHANGED: + +- DC_LOG_DEBUG("%s: *** BW ALLOC CAPABILITY CHANGED for DP-TX Request ***\n", __func__); ++ DC_LOG_ERROR("%s: BW ALLOC CAPABILITY CHANGED to Disabled for link(%d)\n", ++ __func__, link->link_index); + link->dpia_bw_alloc_config.bw_alloc_enabled = false; + break; + } +@@ -409,11 +387,11 @@ int dpia_handle_usb4_bandwidth_allocation_for_link(struct dc_link *link, int pea + set_usb4_req_bw_req(link, link->dpia_bw_alloc_config.sink_max_bw); + + do { +- if (!(timeout > 0)) ++ if (timeout > 0) + timeout--; + else + break; +- fsleep(10 * 1000); ++ msleep(10); + } while (!get_cm_response_ready_flag(link)); + + if (!timeout) +@@ -428,37 +406,36 @@ int dpia_handle_usb4_bandwidth_allocation_for_link(struct dc_link *link, int pea + out: + return ret; + } +-int link_dp_dpia_allocate_usb4_bandwidth_for_stream(struct dc_link *link, int req_bw) ++ ++bool link_dp_dpia_allocate_usb4_bandwidth_for_stream(struct dc_link *link, int req_bw) + { +- int ret = 0; ++ bool ret = false; + uint8_t timeout = 10; + ++ DC_LOG_DEBUG("%s: ENTER: link(%d), hpd_status(%d), current allocated_bw(%d), req_bw(%d)\n", ++ __func__, link->link_index, link->hpd_status, ++ link->dpia_bw_alloc_config.sink_allocated_bw, req_bw); ++ + if (!get_bw_alloc_proceed_flag(link)) + goto out; + +- /* +- * Sometimes stream uses same timing parameters as the already +- * allocated max sink bw so no need to re-alloc +- */ +- if (req_bw != link->dpia_bw_alloc_config.sink_allocated_bw) { +- set_usb4_req_bw_req(link, req_bw); +- do { +- if (!(timeout > 0)) +- timeout--; +- else +- break; +- udelay(10 * 1000); +- } while (!get_cm_response_ready_flag(link)); ++ set_usb4_req_bw_req(link, req_bw); ++ do { ++ if (timeout > 0) ++ timeout--; ++ else ++ break; ++ msleep(10); ++ } while (!get_cm_response_ready_flag(link)); + +- if (!timeout) +- ret = 0;// ERROR TIMEOUT waiting for response for allocating bw +- else if (link->dpia_bw_alloc_config.sink_allocated_bw > 0) +- ret = get_host_router_total_bw(link, HOST_ROUTER_BW_ALLOCATED); +- } ++ if (timeout) ++ ret = true; + + out: ++ DC_LOG_DEBUG("%s: EXIT: timeout(%d), ret(%d)\n", __func__, timeout, ret); + return ret; + } ++ + bool dpia_validate_usb4_bw(struct dc_link **link, int *bw_needed_per_dpia, const unsigned int num_dpias) + { + bool ret = true; +diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.h b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.h +index 7292690383ae1..981bc4eb6120e 100644 +--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.h ++++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.h +@@ -59,9 +59,9 @@ bool link_dp_dpia_set_dptx_usb4_bw_alloc_support(struct dc_link *link); + * @link: pointer to the dc_link struct instance + * @req_bw: Bw requested by the stream + * +- * return: allocated bw else return 0 ++ * return: true if allocated successfully + */ +-int link_dp_dpia_allocate_usb4_bandwidth_for_stream(struct dc_link *link, int req_bw); ++bool link_dp_dpia_allocate_usb4_bandwidth_for_stream(struct dc_link *link, int req_bw); + + /* + * Handle the USB4 BW Allocation related functionality here: +diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c +index 0c00e94e90b1d..9eadc2c7f221e 100644 +--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c ++++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c +@@ -190,9 +190,6 @@ static void handle_hpd_irq_replay_sink(struct dc_link *link) + /*AMD Replay version reuse DP_PSR_ERROR_STATUS for REPLAY_ERROR status.*/ + union psr_error_status replay_error_status; + +- if (link->replay_settings.config.force_disable_desync_error_check) +- return; +- + if (!link->replay_settings.replay_feature_enabled) + return; + +@@ -210,9 +207,6 @@ static void handle_hpd_irq_replay_sink(struct dc_link *link) + &replay_error_status.raw, + sizeof(replay_error_status.raw)); + +- if (replay_configuration.bits.DESYNC_ERROR_STATUS) +- link->replay_settings.config.received_desync_error_hpd = 1; +- + link->replay_settings.config.replay_error_status.bits.LINK_CRC_ERROR = + replay_error_status.bits.LINK_CRC_ERROR; + link->replay_settings.config.replay_error_status.bits.DESYNC_ERROR = +@@ -225,6 +219,12 @@ static void handle_hpd_irq_replay_sink(struct dc_link *link) + link->replay_settings.config.replay_error_status.bits.STATE_TRANSITION_ERROR) { + bool allow_active; + ++ if (link->replay_settings.config.replay_error_status.bits.DESYNC_ERROR) ++ link->replay_settings.config.received_desync_error_hpd = 1; ++ ++ if (link->replay_settings.config.force_disable_desync_error_check) ++ return; ++ + /* Acknowledge and clear configuration bits */ + dm_helpers_dp_write_dpcd( + link->ctx, +diff --git a/drivers/gpu/drm/amd/display/include/audio_types.h b/drivers/gpu/drm/amd/display/include/audio_types.h +index 66a54da0641ce..915a031a43cb2 100644 +--- a/drivers/gpu/drm/amd/display/include/audio_types.h ++++ b/drivers/gpu/drm/amd/display/include/audio_types.h +@@ -64,7 +64,7 @@ enum audio_dto_source { + /* PLL information required for AZALIA DTO calculation */ + + struct audio_pll_info { +- uint32_t dp_dto_source_clock_in_khz; ++ uint32_t audio_dto_source_clock_in_khz; + uint32_t feed_back_divider; + enum audio_dto_source dto_source; + bool ss_enabled; +diff --git a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c +index 7806056ca1dd1..1675314a3ff20 100644 +--- a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c ++++ b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c +@@ -841,8 +841,6 @@ bool is_psr_su_specific_panel(struct dc_link *link) + isPSRSUSupported = false; + else if (dpcd_caps->sink_dev_id_str[1] == 0x08 && dpcd_caps->sink_dev_id_str[0] == 0x03) + isPSRSUSupported = false; +- else if (dpcd_caps->sink_dev_id_str[1] == 0x08 && dpcd_caps->sink_dev_id_str[0] == 0x03) +- isPSRSUSupported = false; + else if (dpcd_caps->psr_info.force_psrsu_cap == 0x1) + isPSRSUSupported = true; + } +diff --git a/drivers/gpu/drm/amd/include/amd_shared.h b/drivers/gpu/drm/amd/include/amd_shared.h +index 7f98394338c26..579977f6ad524 100644 +--- a/drivers/gpu/drm/amd/include/amd_shared.h ++++ b/drivers/gpu/drm/amd/include/amd_shared.h +@@ -244,7 +244,6 @@ enum DC_FEATURE_MASK { + DC_DISABLE_LTTPR_DP2_0 = (1 << 6), //0x40, disabled by default + DC_PSR_ALLOW_SMU_OPT = (1 << 7), //0x80, disabled by default + DC_PSR_ALLOW_MULTI_DISP_OPT = (1 << 8), //0x100, disabled by default +- DC_REPLAY_MASK = (1 << 9), //0x200, disabled by default for dcn < 3.1.4 + }; + + enum DC_DEBUG_MASK { +@@ -255,7 +254,6 @@ enum DC_DEBUG_MASK { + DC_DISABLE_PSR = 0x10, + DC_FORCE_SUBVP_MCLK_SWITCH = 0x20, + DC_DISABLE_MPO = 0x40, +- DC_DISABLE_REPLAY = 0x50, + DC_ENABLE_DPIA_TRACE = 0x80, + }; + +diff --git a/drivers/gpu/drm/amd/include/mes_v11_api_def.h b/drivers/gpu/drm/amd/include/mes_v11_api_def.h +index b1db2b1901874..e07e93167a82c 100644 +--- a/drivers/gpu/drm/amd/include/mes_v11_api_def.h ++++ b/drivers/gpu/drm/amd/include/mes_v11_api_def.h +@@ -571,7 +571,8 @@ struct SET_SHADER_DEBUGGER { + struct { + uint32_t single_memop : 1; /* SQ_DEBUG.single_memop */ + uint32_t single_alu_op : 1; /* SQ_DEBUG.single_alu_op */ +- uint32_t reserved : 30; ++ uint32_t reserved : 29; ++ uint32_t process_ctx_flush : 1; + }; + uint32_t u32all; + } flags; +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/process_pptables_v1_0.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/process_pptables_v1_0.c +index f2a55c1413f59..17882f8dfdd34 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/process_pptables_v1_0.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/process_pptables_v1_0.c +@@ -200,7 +200,7 @@ static int get_platform_power_management_table( + struct pp_hwmgr *hwmgr, + ATOM_Tonga_PPM_Table *atom_ppm_table) + { +- struct phm_ppm_table *ptr = kzalloc(sizeof(ATOM_Tonga_PPM_Table), GFP_KERNEL); ++ struct phm_ppm_table *ptr = kzalloc(sizeof(*ptr), GFP_KERNEL); + struct phm_ppt_v1_information *pp_table_information = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + +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 b1a8799e2dee3..aa91730e4eaff 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c +@@ -3999,6 +3999,7 @@ static int smu7_read_sensor(struct pp_hwmgr *hwmgr, int idx, + uint32_t sclk, mclk, activity_percent; + uint32_t offset, val_vid; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); ++ struct amdgpu_device *adev = hwmgr->adev; + + /* size must be at least 4 bytes for all sensors */ + if (*size < 4) +@@ -4042,7 +4043,21 @@ static int smu7_read_sensor(struct pp_hwmgr *hwmgr, int idx, + *size = 4; + return 0; + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: +- return smu7_get_gpu_power(hwmgr, (uint32_t *)value); ++ if ((adev->asic_type != CHIP_HAWAII) && ++ (adev->asic_type != CHIP_BONAIRE) && ++ (adev->asic_type != CHIP_FIJI) && ++ (adev->asic_type != CHIP_TONGA)) ++ return smu7_get_gpu_power(hwmgr, (uint32_t *)value); ++ else ++ return -EOPNOTSUPP; ++ case AMDGPU_PP_SENSOR_GPU_AVG_POWER: ++ if ((adev->asic_type != CHIP_HAWAII) && ++ (adev->asic_type != CHIP_BONAIRE) && ++ (adev->asic_type != CHIP_FIJI) && ++ (adev->asic_type != CHIP_TONGA)) ++ return -EOPNOTSUPP; ++ else ++ return smu7_get_gpu_power(hwmgr, (uint32_t *)value); + case AMDGPU_PP_SENSOR_VDDGFX: + if ((data->vr_config & VRCONF_VDDGFX_MASK) == + (VR_SVI2_PLANE_2 << VRCONF_VDDGFX_SHIFT)) +diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c +index 5168628f11cff..29d91493b101a 100644 +--- a/drivers/gpu/drm/bridge/analogix/anx7625.c ++++ b/drivers/gpu/drm/bridge/analogix/anx7625.c +@@ -1298,10 +1298,32 @@ static void anx7625_config(struct anx7625_data *ctx) + XTAL_FRQ_SEL, XTAL_FRQ_27M); + } + ++static int anx7625_hpd_timer_config(struct anx7625_data *ctx) ++{ ++ int ret; ++ ++ /* Set irq detect window to 2ms */ ++ ret = anx7625_reg_write(ctx, ctx->i2c.tx_p2_client, ++ HPD_DET_TIMER_BIT0_7, HPD_TIME & 0xFF); ++ ret |= anx7625_reg_write(ctx, ctx->i2c.tx_p2_client, ++ HPD_DET_TIMER_BIT8_15, ++ (HPD_TIME >> 8) & 0xFF); ++ ret |= anx7625_reg_write(ctx, ctx->i2c.tx_p2_client, ++ HPD_DET_TIMER_BIT16_23, ++ (HPD_TIME >> 16) & 0xFF); ++ ++ return ret; ++} ++ ++static int anx7625_read_hpd_gpio_config_status(struct anx7625_data *ctx) ++{ ++ return anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, GPIO_CTRL_2); ++} ++ + static void anx7625_disable_pd_protocol(struct anx7625_data *ctx) + { + struct device *dev = ctx->dev; +- int ret; ++ int ret, val; + + /* Reset main ocm */ + ret = anx7625_reg_write(ctx, ctx->i2c.rx_p0_client, 0x88, 0x40); +@@ -1315,6 +1337,19 @@ static void anx7625_disable_pd_protocol(struct anx7625_data *ctx) + DRM_DEV_DEBUG_DRIVER(dev, "disable PD feature fail.\n"); + else + DRM_DEV_DEBUG_DRIVER(dev, "disable PD feature succeeded.\n"); ++ ++ /* ++ * Make sure the HPD GPIO already be configured after OCM release before ++ * setting HPD detect window register. Here we poll the status register ++ * at maximum 40ms, then config HPD irq detect window register ++ */ ++ readx_poll_timeout(anx7625_read_hpd_gpio_config_status, ++ ctx, val, ++ ((val & HPD_SOURCE) || (val < 0)), ++ 2000, 2000 * 20); ++ ++ /* Set HPD irq detect window to 2ms */ ++ anx7625_hpd_timer_config(ctx); + } + + static int anx7625_ocm_loading_check(struct anx7625_data *ctx) +@@ -1437,20 +1472,6 @@ static void anx7625_start_dp_work(struct anx7625_data *ctx) + + static int anx7625_read_hpd_status_p0(struct anx7625_data *ctx) + { +- int ret; +- +- /* Set irq detect window to 2ms */ +- ret = anx7625_reg_write(ctx, ctx->i2c.tx_p2_client, +- HPD_DET_TIMER_BIT0_7, HPD_TIME & 0xFF); +- ret |= anx7625_reg_write(ctx, ctx->i2c.tx_p2_client, +- HPD_DET_TIMER_BIT8_15, +- (HPD_TIME >> 8) & 0xFF); +- ret |= anx7625_reg_write(ctx, ctx->i2c.tx_p2_client, +- HPD_DET_TIMER_BIT16_23, +- (HPD_TIME >> 16) & 0xFF); +- if (ret < 0) +- return ret; +- + return anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, SYSTEM_STSTUS); + } + +diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.h b/drivers/gpu/drm/bridge/analogix/anx7625.h +index 80d3fb4e985f1..39ed35d338363 100644 +--- a/drivers/gpu/drm/bridge/analogix/anx7625.h ++++ b/drivers/gpu/drm/bridge/analogix/anx7625.h +@@ -259,6 +259,10 @@ + #define AP_MIPI_RX_EN BIT(5) /* 1: MIPI RX input in 0: no RX in */ + #define AP_DISABLE_PD BIT(6) + #define AP_DISABLE_DISPLAY BIT(7) ++ ++#define GPIO_CTRL_2 0x49 ++#define HPD_SOURCE BIT(6) ++ + /***************************************************************/ + /* Register definition of device address 0x84 */ + #define MIPI_PHY_CONTROL_3 0x03 +diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c +index 446458aca8e99..54a7103c1c0f5 100644 +--- a/drivers/gpu/drm/drm_file.c ++++ b/drivers/gpu/drm/drm_file.c +@@ -958,7 +958,7 @@ void drm_show_memory_stats(struct drm_printer *p, struct drm_file *file) + { + struct drm_gem_object *obj; + struct drm_memory_stats status = {}; +- enum drm_gem_object_status supported_status; ++ enum drm_gem_object_status supported_status = 0; + int id; + + spin_lock(&file->table_lock); +diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c +index d3ba0698b84b4..36c5629af7d8e 100644 +--- a/drivers/gpu/drm/drm_framebuffer.c ++++ b/drivers/gpu/drm/drm_framebuffer.c +@@ -552,7 +552,7 @@ int drm_mode_getfb2_ioctl(struct drm_device *dev, + struct drm_mode_fb_cmd2 *r = data; + struct drm_framebuffer *fb; + unsigned int i; +- int ret; ++ int ret = 0; + + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + return -EINVAL; +diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c +index 14201f73aab13..843a6dbda93a0 100644 +--- a/drivers/gpu/drm/drm_mipi_dsi.c ++++ b/drivers/gpu/drm/drm_mipi_dsi.c +@@ -347,7 +347,8 @@ static int mipi_dsi_remove_device_fn(struct device *dev, void *priv) + { + struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); + +- mipi_dsi_detach(dsi); ++ if (dsi->attached) ++ mipi_dsi_detach(dsi); + mipi_dsi_device_unregister(dsi); + + return 0; +@@ -370,11 +371,18 @@ EXPORT_SYMBOL(mipi_dsi_host_unregister); + int mipi_dsi_attach(struct mipi_dsi_device *dsi) + { + const struct mipi_dsi_host_ops *ops = dsi->host->ops; ++ int ret; + + if (!ops || !ops->attach) + return -ENOSYS; + +- return ops->attach(dsi->host, dsi); ++ ret = ops->attach(dsi->host, dsi); ++ if (ret) ++ return ret; ++ ++ dsi->attached = true; ++ ++ return 0; + } + EXPORT_SYMBOL(mipi_dsi_attach); + +@@ -386,9 +394,14 @@ int mipi_dsi_detach(struct mipi_dsi_device *dsi) + { + const struct mipi_dsi_host_ops *ops = dsi->host->ops; + ++ if (WARN_ON(!dsi->attached)) ++ return -EINVAL; ++ + if (!ops || !ops->detach) + return -ENOSYS; + ++ dsi->attached = false; ++ + return ops->detach(dsi->host, dsi); + } + EXPORT_SYMBOL(mipi_dsi_detach); +diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c +index 8399256cb5c9d..5380fb6c55ae1 100644 +--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c ++++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c +@@ -300,6 +300,7 @@ err_mode_config_cleanup: + drm_mode_config_cleanup(drm); + exynos_drm_cleanup_dma(drm); + kfree(private); ++ dev_set_drvdata(dev, NULL); + err_free_drm: + drm_dev_put(drm); + +@@ -313,6 +314,7 @@ static void exynos_drm_unbind(struct device *dev) + drm_dev_unregister(drm); + + drm_kms_helper_poll_fini(drm); ++ drm_atomic_helper_shutdown(drm); + + component_unbind_all(drm->dev, drm); + drm_mode_config_cleanup(drm); +@@ -350,9 +352,18 @@ static int exynos_drm_platform_remove(struct platform_device *pdev) + return 0; + } + ++static void exynos_drm_platform_shutdown(struct platform_device *pdev) ++{ ++ struct drm_device *drm = platform_get_drvdata(pdev); ++ ++ if (drm) ++ drm_atomic_helper_shutdown(drm); ++} ++ + static struct platform_driver exynos_drm_platform_driver = { + .probe = exynos_drm_platform_probe, + .remove = exynos_drm_platform_remove, ++ .shutdown = exynos_drm_platform_shutdown, + .driver = { + .name = "exynos-drm", + .pm = &exynos_drm_pm_ops, +diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +index 7a0220d29a235..500ed2d183fcc 100644 +--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c ++++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +@@ -1312,6 +1312,7 @@ static void a6xx_set_ubwc_config(struct msm_gpu *gpu) + + if (adreno_is_a650(adreno_gpu) || + adreno_is_a660(adreno_gpu) || ++ adreno_is_a690(adreno_gpu) || + adreno_is_a730(adreno_gpu) || + adreno_is_a740_family(adreno_gpu)) { + /* TODO: get ddr type from bootloader and use 2 for LPDDR4 */ +@@ -1321,13 +1322,6 @@ static void a6xx_set_ubwc_config(struct msm_gpu *gpu) + uavflagprd_inv = 2; + } + +- if (adreno_is_a690(adreno_gpu)) { +- hbb_lo = 2; +- amsbc = 1; +- rgb565_predicator = 1; +- uavflagprd_inv = 2; +- } +- + if (adreno_is_7c3(adreno_gpu)) { + hbb_lo = 1; + amsbc = 1; +@@ -1741,7 +1735,9 @@ static int hw_init(struct msm_gpu *gpu) + /* Setting the primFifo thresholds default values, + * and vccCacheSkipDis=1 bit (0x200) for A640 and newer + */ +- if (adreno_is_a650(adreno_gpu) || adreno_is_a660(adreno_gpu) || adreno_is_a690(adreno_gpu)) ++ if (adreno_is_a690(adreno_gpu)) ++ gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00800200); ++ else if (adreno_is_a650(adreno_gpu) || adreno_is_a660(adreno_gpu)) + gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00300200); + else if (adreno_is_a640_family(adreno_gpu) || adreno_is_7c3(adreno_gpu)) + gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00200200); +@@ -1775,6 +1771,8 @@ static int hw_init(struct msm_gpu *gpu) + if (adreno_is_a730(adreno_gpu) || + adreno_is_a740_family(adreno_gpu)) + gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0xcfffff); ++ else if (adreno_is_a690(adreno_gpu)) ++ gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x4fffff); + else if (adreno_is_a619(adreno_gpu)) + gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x3fffff); + else if (adreno_is_a610(adreno_gpu)) +@@ -1808,12 +1806,17 @@ static int hw_init(struct msm_gpu *gpu) + a6xx_set_cp_protect(gpu); + + if (adreno_is_a660_family(adreno_gpu)) { +- gpu_write(gpu, REG_A6XX_CP_CHICKEN_DBG, 0x1); ++ if (adreno_is_a690(adreno_gpu)) ++ gpu_write(gpu, REG_A6XX_CP_CHICKEN_DBG, 0x00028801); ++ else ++ gpu_write(gpu, REG_A6XX_CP_CHICKEN_DBG, 0x1); + gpu_write(gpu, REG_A6XX_RBBM_GBIF_CLIENT_QOS_CNTL, 0x0); + } + ++ if (adreno_is_a690(adreno_gpu)) ++ gpu_write(gpu, REG_A6XX_UCHE_CMDQ_CONFIG, 0x90); + /* Set dualQ + disable afull for A660 GPU */ +- if (adreno_is_a660(adreno_gpu)) ++ else if (adreno_is_a660(adreno_gpu)) + gpu_write(gpu, REG_A6XX_UCHE_CMDQ_CONFIG, 0x66906); + else if (adreno_is_a7xx(adreno_gpu)) + gpu_write(gpu, REG_A6XX_UCHE_CMDQ_CONFIG, +diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h +index 1709ba57f3840..022b0408c24d5 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h ++++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h +@@ -31,6 +31,7 @@ static const struct dpu_mdp_cfg sm8350_mdp = { + [DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, + [DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 }, + [DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 }, ++ [DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 }, + [DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 }, + }, + }; +@@ -298,6 +299,21 @@ static const struct dpu_dsc_cfg sm8350_dsc[] = { + }, + }; + ++static const struct dpu_wb_cfg sm8350_wb[] = { ++ { ++ .name = "wb_2", .id = WB_2, ++ .base = 0x65000, .len = 0x2c8, ++ .features = WB_SM8250_MASK, ++ .format_list = wb2_formats, ++ .num_formats = ARRAY_SIZE(wb2_formats), ++ .clk_ctrl = DPU_CLK_CTRL_WB2, ++ .xin_id = 6, ++ .vbif_idx = VBIF_RT, ++ .maxlinewidth = 4096, ++ .intr_wb_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 4), ++ }, ++}; ++ + static const struct dpu_intf_cfg sm8350_intf[] = { + { + .name = "intf_0", .id = INTF_0, +@@ -393,6 +409,8 @@ const struct dpu_mdss_cfg dpu_sm8350_cfg = { + .dsc = sm8350_dsc, + .merge_3d_count = ARRAY_SIZE(sm8350_merge_3d), + .merge_3d = sm8350_merge_3d, ++ .wb_count = ARRAY_SIZE(sm8350_wb), ++ .wb = sm8350_wb, + .intf_count = ARRAY_SIZE(sm8350_intf), + .intf = sm8350_intf, + .vbif_count = ARRAY_SIZE(sdm845_vbif), +diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h +index 72b0f547242fe..7adc42257e1ea 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h ++++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h +@@ -32,6 +32,7 @@ static const struct dpu_mdp_cfg sm8450_mdp = { + [DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, + [DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 }, + [DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 }, ++ [DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 }, + [DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 }, + }, + }; +@@ -316,6 +317,21 @@ static const struct dpu_dsc_cfg sm8450_dsc[] = { + }, + }; + ++static const struct dpu_wb_cfg sm8450_wb[] = { ++ { ++ .name = "wb_2", .id = WB_2, ++ .base = 0x65000, .len = 0x2c8, ++ .features = WB_SM8250_MASK, ++ .format_list = wb2_formats, ++ .num_formats = ARRAY_SIZE(wb2_formats), ++ .clk_ctrl = DPU_CLK_CTRL_WB2, ++ .xin_id = 6, ++ .vbif_idx = VBIF_RT, ++ .maxlinewidth = 4096, ++ .intr_wb_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 4), ++ }, ++}; ++ + static const struct dpu_intf_cfg sm8450_intf[] = { + { + .name = "intf_0", .id = INTF_0, +@@ -411,6 +427,8 @@ const struct dpu_mdss_cfg dpu_sm8450_cfg = { + .dsc = sm8450_dsc, + .merge_3d_count = ARRAY_SIZE(sm8450_merge_3d), + .merge_3d = sm8450_merge_3d, ++ .wb_count = ARRAY_SIZE(sm8450_wb), ++ .wb = sm8450_wb, + .intf_count = ARRAY_SIZE(sm8450_intf), + .intf = sm8450_intf, + .vbif_count = ARRAY_SIZE(sdm845_vbif), +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +index 5dbb5d27bbea0..b9f0093389a82 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +@@ -39,6 +39,9 @@ + #define DPU_ERROR_ENC(e, fmt, ...) DPU_ERROR("enc%d " fmt,\ + (e) ? (e)->base.base.id : -1, ##__VA_ARGS__) + ++#define DPU_ERROR_ENC_RATELIMITED(e, fmt, ...) DPU_ERROR_RATELIMITED("enc%d " fmt,\ ++ (e) ? (e)->base.base.id : -1, ##__VA_ARGS__) ++ + /* + * Two to anticipate panels that can do cmd/vid dynamic switching + * plan is to create all possible physical encoder types, and switch between +@@ -2339,7 +2342,7 @@ static void dpu_encoder_frame_done_timeout(struct timer_list *t) + return; + } + +- DPU_ERROR_ENC(dpu_enc, "frame done timeout\n"); ++ DPU_ERROR_ENC_RATELIMITED(dpu_enc, "frame done timeout\n"); + + event = DPU_ENCODER_FRAME_EVENT_ERROR; + trace_dpu_enc_frame_done_timeout(DRMID(drm_enc), event); +@@ -2497,7 +2500,6 @@ void dpu_encoder_phys_init(struct dpu_encoder_phys *phys_enc, + phys_enc->enc_spinlock = p->enc_spinlock; + phys_enc->enable_state = DPU_ENC_DISABLED; + +- atomic_set(&phys_enc->vblank_refcount, 0); + atomic_set(&phys_enc->pending_kickoff_cnt, 0); + atomic_set(&phys_enc->pending_ctlstart_cnt, 0); + +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h +index 6f04c3d56e77c..96bda57b69596 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h +@@ -155,6 +155,7 @@ enum dpu_intr_idx { + * @hw_wb: Hardware interface to the wb registers + * @dpu_kms: Pointer to the dpu_kms top level + * @cached_mode: DRM mode cached at mode_set time, acted on in enable ++ * @vblank_ctl_lock: Vblank ctl mutex lock to protect vblank_refcount + * @enabled: Whether the encoder has enabled and running a mode + * @split_role: Role to play in a split-panel configuration + * @intf_mode: Interface mode +@@ -183,11 +184,12 @@ struct dpu_encoder_phys { + struct dpu_hw_wb *hw_wb; + struct dpu_kms *dpu_kms; + struct drm_display_mode cached_mode; ++ struct mutex vblank_ctl_lock; + enum dpu_enc_split_role split_role; + enum dpu_intf_mode intf_mode; + spinlock_t *enc_spinlock; + enum dpu_enc_enable_state enable_state; +- atomic_t vblank_refcount; ++ int vblank_refcount; + atomic_t vsync_cnt; + atomic_t underrun_cnt; + atomic_t pending_ctlstart_cnt; +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c +index be185fe69793b..2d788c5e26a83 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c +@@ -244,7 +244,8 @@ static int dpu_encoder_phys_cmd_control_vblank_irq( + return -EINVAL; + } + +- refcount = atomic_read(&phys_enc->vblank_refcount); ++ mutex_lock(&phys_enc->vblank_ctl_lock); ++ refcount = phys_enc->vblank_refcount; + + /* Slave encoders don't report vblank */ + if (!dpu_encoder_phys_cmd_is_master(phys_enc)) +@@ -260,16 +261,24 @@ static int dpu_encoder_phys_cmd_control_vblank_irq( + phys_enc->hw_pp->idx - PINGPONG_0, + enable ? "true" : "false", refcount); + +- if (enable && atomic_inc_return(&phys_enc->vblank_refcount) == 1) +- ret = dpu_core_irq_register_callback(phys_enc->dpu_kms, +- phys_enc->irq[INTR_IDX_RDPTR], +- dpu_encoder_phys_cmd_te_rd_ptr_irq, +- phys_enc); +- else if (!enable && atomic_dec_return(&phys_enc->vblank_refcount) == 0) +- ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms, +- phys_enc->irq[INTR_IDX_RDPTR]); ++ if (enable) { ++ if (phys_enc->vblank_refcount == 0) ++ ret = dpu_core_irq_register_callback(phys_enc->dpu_kms, ++ phys_enc->irq[INTR_IDX_RDPTR], ++ dpu_encoder_phys_cmd_te_rd_ptr_irq, ++ phys_enc); ++ if (!ret) ++ phys_enc->vblank_refcount++; ++ } else if (!enable) { ++ if (phys_enc->vblank_refcount == 1) ++ ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms, ++ phys_enc->irq[INTR_IDX_RDPTR]); ++ if (!ret) ++ phys_enc->vblank_refcount--; ++ } + + end: ++ mutex_unlock(&phys_enc->vblank_ctl_lock); + if (ret) { + DRM_ERROR("vblank irq err id:%u pp:%d ret:%d, enable %s/%d\n", + DRMID(phys_enc->parent), +@@ -285,7 +294,7 @@ static void dpu_encoder_phys_cmd_irq_control(struct dpu_encoder_phys *phys_enc, + { + trace_dpu_enc_phys_cmd_irq_ctrl(DRMID(phys_enc->parent), + phys_enc->hw_pp->idx - PINGPONG_0, +- enable, atomic_read(&phys_enc->vblank_refcount)); ++ enable, phys_enc->vblank_refcount); + + if (enable) { + dpu_core_irq_register_callback(phys_enc->dpu_kms, +@@ -763,6 +772,9 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init( + + dpu_encoder_phys_init(phys_enc, p); + ++ mutex_init(&phys_enc->vblank_ctl_lock); ++ phys_enc->vblank_refcount = 0; ++ + dpu_encoder_phys_cmd_init_ops(&phys_enc->ops); + phys_enc->intf_mode = INTF_MODE_CMD; + cmd_enc->stream_sel = 0; +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c +index a01fda7118835..eeb0acf9665e8 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c +@@ -364,7 +364,8 @@ static int dpu_encoder_phys_vid_control_vblank_irq( + int ret = 0; + int refcount; + +- refcount = atomic_read(&phys_enc->vblank_refcount); ++ mutex_lock(&phys_enc->vblank_ctl_lock); ++ refcount = phys_enc->vblank_refcount; + + /* Slave encoders don't report vblank */ + if (!dpu_encoder_phys_vid_is_master(phys_enc)) +@@ -377,18 +378,26 @@ static int dpu_encoder_phys_vid_control_vblank_irq( + } + + DRM_DEBUG_VBL("id:%u enable=%d/%d\n", DRMID(phys_enc->parent), enable, +- atomic_read(&phys_enc->vblank_refcount)); ++ refcount); + +- if (enable && atomic_inc_return(&phys_enc->vblank_refcount) == 1) +- ret = dpu_core_irq_register_callback(phys_enc->dpu_kms, +- phys_enc->irq[INTR_IDX_VSYNC], +- dpu_encoder_phys_vid_vblank_irq, +- phys_enc); +- else if (!enable && atomic_dec_return(&phys_enc->vblank_refcount) == 0) +- ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms, +- phys_enc->irq[INTR_IDX_VSYNC]); ++ if (enable) { ++ if (phys_enc->vblank_refcount == 0) ++ ret = dpu_core_irq_register_callback(phys_enc->dpu_kms, ++ phys_enc->irq[INTR_IDX_VSYNC], ++ dpu_encoder_phys_vid_vblank_irq, ++ phys_enc); ++ if (!ret) ++ phys_enc->vblank_refcount++; ++ } else if (!enable) { ++ if (phys_enc->vblank_refcount == 1) ++ ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms, ++ phys_enc->irq[INTR_IDX_VSYNC]); ++ if (!ret) ++ phys_enc->vblank_refcount--; ++ } + + end: ++ mutex_unlock(&phys_enc->vblank_ctl_lock); + if (ret) { + DRM_ERROR("failed: id:%u intf:%d ret:%d enable:%d refcnt:%d\n", + DRMID(phys_enc->parent), +@@ -618,7 +627,7 @@ static void dpu_encoder_phys_vid_irq_control(struct dpu_encoder_phys *phys_enc, + trace_dpu_enc_phys_vid_irq_ctrl(DRMID(phys_enc->parent), + phys_enc->hw_intf->idx - INTF_0, + enable, +- atomic_read(&phys_enc->vblank_refcount)); ++ phys_enc->vblank_refcount); + + if (enable) { + ret = dpu_encoder_phys_vid_control_vblank_irq(phys_enc, true); +@@ -713,6 +722,8 @@ struct dpu_encoder_phys *dpu_encoder_phys_vid_init( + DPU_DEBUG_VIDENC(phys_enc, "\n"); + + dpu_encoder_phys_init(phys_enc, p); ++ mutex_init(&phys_enc->vblank_ctl_lock); ++ phys_enc->vblank_refcount = 0; + + dpu_encoder_phys_vid_init_ops(&phys_enc->ops); + phys_enc->intf_mode = INTF_MODE_VIDEO; +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c +index 9668fb97c0478..d49b3ef7689eb 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c +@@ -87,6 +87,9 @@ static void dpu_hw_wb_setup_format(struct dpu_hw_wb *ctx, + dst_format |= BIT(14); /* DST_ALPHA_X */ + } + ++ if (DPU_FORMAT_IS_YUV(fmt)) ++ dst_format |= BIT(15); ++ + pattern = (fmt->element[3] << 24) | + (fmt->element[2] << 16) | + (fmt->element[1] << 8) | +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h +index b6f53ca6e9628..f5473d4dea92f 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h +@@ -51,6 +51,7 @@ + } while (0) + + #define DPU_ERROR(fmt, ...) pr_err("[dpu error]" fmt, ##__VA_ARGS__) ++#define DPU_ERROR_RATELIMITED(fmt, ...) pr_err_ratelimited("[dpu error]" fmt, ##__VA_ARGS__) + + /** + * ktime_compare_safe - compare two ktime structures +diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c +index 1b88fb52726f2..4f89c99395017 100644 +--- a/drivers/gpu/drm/msm/dp/dp_display.c ++++ b/drivers/gpu/drm/msm/dp/dp_display.c +@@ -170,6 +170,11 @@ static const struct msm_dp_desc sm8350_dp_descs[] = { + {} + }; + ++static const struct msm_dp_desc sm8650_dp_descs[] = { ++ { .io_start = 0x0af54000, .id = MSM_DP_CONTROLLER_0, .connector_type = DRM_MODE_CONNECTOR_DisplayPort }, ++ {} ++}; ++ + static const struct of_device_id dp_dt_match[] = { + { .compatible = "qcom,sc7180-dp", .data = &sc7180_dp_descs }, + { .compatible = "qcom,sc7280-dp", .data = &sc7280_dp_descs }, +@@ -180,6 +185,7 @@ static const struct of_device_id dp_dt_match[] = { + { .compatible = "qcom,sc8280xp-edp", .data = &sc8280xp_edp_descs }, + { .compatible = "qcom,sdm845-dp", .data = &sc7180_dp_descs }, + { .compatible = "qcom,sm8350-dp", .data = &sm8350_dp_descs }, ++ { .compatible = "qcom,sm8650-dp", .data = &sm8650_dp_descs }, + {} + }; + +diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c +index b6314bb66d2fd..e49ebd9f6326f 100644 +--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c ++++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c +@@ -691,6 +691,10 @@ static int dsi_phy_driver_probe(struct platform_device *pdev) + return dev_err_probe(dev, PTR_ERR(phy->ahb_clk), + "Unable to get ahb clk\n"); + ++ ret = devm_pm_runtime_enable(&pdev->dev); ++ if (ret) ++ return ret; ++ + /* PLL init will call into clk_register which requires + * register access, so we need to enable power and ahb clock. + */ +diff --git a/drivers/gpu/drm/msm/msm_mdss.c b/drivers/gpu/drm/msm/msm_mdss.c +index 6865db1e3ce89..29bb38f0bb2ce 100644 +--- a/drivers/gpu/drm/msm/msm_mdss.c ++++ b/drivers/gpu/drm/msm/msm_mdss.c +@@ -545,7 +545,7 @@ static const struct msm_mdss_data sc8280xp_data = { + .ubwc_dec_version = UBWC_4_0, + .ubwc_swizzle = 6, + .ubwc_static = 1, +- .highest_bank_bit = 2, ++ .highest_bank_bit = 3, + .macrotile_mode = 1, + }; + +diff --git a/drivers/gpu/drm/panel/panel-edp.c b/drivers/gpu/drm/panel/panel-edp.c +index 7dc6fb7308ce3..cba5a93e60822 100644 +--- a/drivers/gpu/drm/panel/panel-edp.c ++++ b/drivers/gpu/drm/panel/panel-edp.c +@@ -203,6 +203,9 @@ struct edp_panel_entry { + + /** @name: Name of this panel (for printing to logs). */ + const char *name; ++ ++ /** @override_edid_mode: Override the mode obtained by edid. */ ++ const struct drm_display_mode *override_edid_mode; + }; + + struct panel_edp { +@@ -301,6 +304,24 @@ static unsigned int panel_edp_get_display_modes(struct panel_edp *panel, + return num; + } + ++static int panel_edp_override_edid_mode(struct panel_edp *panel, ++ struct drm_connector *connector, ++ const struct drm_display_mode *override_mode) ++{ ++ struct drm_display_mode *mode; ++ ++ mode = drm_mode_duplicate(connector->dev, override_mode); ++ if (!mode) { ++ dev_err(panel->base.dev, "failed to add additional mode\n"); ++ return 0; ++ } ++ ++ mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; ++ drm_mode_set_name(mode); ++ drm_mode_probed_add(connector, mode); ++ return 1; ++} ++ + static int panel_edp_get_non_edid_modes(struct panel_edp *panel, + struct drm_connector *connector) + { +@@ -568,6 +589,9 @@ static int panel_edp_get_modes(struct drm_panel *panel, + { + struct panel_edp *p = to_panel_edp(panel); + int num = 0; ++ bool has_override_edid_mode = p->detected_panel && ++ p->detected_panel != ERR_PTR(-EINVAL) && ++ p->detected_panel->override_edid_mode; + + /* probe EDID if a DDC bus is available */ + if (p->ddc) { +@@ -575,9 +599,18 @@ static int panel_edp_get_modes(struct drm_panel *panel, + + if (!p->edid) + p->edid = drm_get_edid(connector, p->ddc); +- +- if (p->edid) +- num += drm_add_edid_modes(connector, p->edid); ++ if (p->edid) { ++ if (has_override_edid_mode) { ++ /* ++ * override_edid_mode is specified. Use ++ * override_edid_mode instead of from edid. ++ */ ++ num += panel_edp_override_edid_mode(p, connector, ++ p->detected_panel->override_edid_mode); ++ } else { ++ num += drm_add_edid_modes(connector, p->edid); ++ } ++ } + + pm_runtime_mark_last_busy(panel->dev); + pm_runtime_put_autosuspend(panel->dev); +@@ -1830,6 +1863,15 @@ static const struct panel_delay delay_200_500_e200 = { + .delay = _delay \ + } + ++#define EDP_PANEL_ENTRY2(vend_chr_0, vend_chr_1, vend_chr_2, product_id, _delay, _name, _mode) \ ++{ \ ++ .name = _name, \ ++ .panel_id = drm_edid_encode_panel_id(vend_chr_0, vend_chr_1, vend_chr_2, \ ++ product_id), \ ++ .delay = _delay, \ ++ .override_edid_mode = _mode \ ++} ++ + /* + * This table is used to figure out power sequencing delays for panels that + * are detected by EDID. Entries here may point to entries in the +diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c +index 13c8dd8cd3506..2bc762d31ac70 100644 +--- a/drivers/hid/hidraw.c ++++ b/drivers/hid/hidraw.c +@@ -357,8 +357,11 @@ static int hidraw_release(struct inode * inode, struct file * file) + down_write(&minors_rwsem); + + spin_lock_irqsave(&hidraw_table[minor]->list_lock, flags); +- for (int i = list->tail; i < list->head; i++) +- kfree(list->buffer[i].value); ++ while (list->tail != list->head) { ++ kfree(list->buffer[list->tail].value); ++ list->buffer[list->tail].value = NULL; ++ list->tail = (list->tail + 1) & (HIDRAW_BUFFER_SIZE - 1); ++ } + list_del(&list->node); + spin_unlock_irqrestore(&hidraw_table[minor]->list_lock, flags); + kfree(list); +diff --git a/drivers/hwmon/hp-wmi-sensors.c b/drivers/hwmon/hp-wmi-sensors.c +index 17ae62f88bbf4..b5325d0e72b9c 100644 +--- a/drivers/hwmon/hp-wmi-sensors.c ++++ b/drivers/hwmon/hp-wmi-sensors.c +@@ -17,6 +17,8 @@ + * Available: https://github.com/linuxhw/ACPI + * [4] P. Rohár, "bmfdec - Decompile binary MOF file (BMF) from WMI buffer", + * 2017. [Online]. Available: https://github.com/pali/bmfdec ++ * [5] Microsoft Corporation, "Driver-Defined WMI Data Items", 2017. [Online]. ++ * Available: https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/driver-defined-wmi-data-items + */ + + #include <linux/acpi.h> +@@ -24,6 +26,7 @@ + #include <linux/hwmon.h> + #include <linux/jiffies.h> + #include <linux/mutex.h> ++#include <linux/nls.h> + #include <linux/units.h> + #include <linux/wmi.h> + +@@ -395,6 +398,50 @@ struct hp_wmi_sensors { + struct mutex lock; /* Lock polling WMI and driver state changes. */ + }; + ++static bool is_raw_wmi_string(const u8 *pointer, u32 length) ++{ ++ const u16 *ptr; ++ u16 len; ++ ++ /* WMI strings are length-prefixed UTF-16 [5]. */ ++ if (length <= sizeof(*ptr)) ++ return false; ++ ++ length -= sizeof(*ptr); ++ ptr = (const u16 *)pointer; ++ len = *ptr; ++ ++ return len <= length && !(len & 1); ++} ++ ++static char *convert_raw_wmi_string(const u8 *buf) ++{ ++ const wchar_t *src; ++ unsigned int cps; ++ unsigned int len; ++ char *dst; ++ int i; ++ ++ src = (const wchar_t *)buf; ++ ++ /* Count UTF-16 code points. Exclude trailing null padding. */ ++ cps = *src / sizeof(*src); ++ while (cps && !src[cps]) ++ cps--; ++ ++ /* Each code point becomes up to 3 UTF-8 characters. */ ++ len = min(cps * 3, HP_WMI_MAX_STR_SIZE - 1); ++ ++ dst = kmalloc((len + 1) * sizeof(*dst), GFP_KERNEL); ++ if (!dst) ++ return NULL; ++ ++ i = utf16s_to_utf8s(++src, cps, UTF16_LITTLE_ENDIAN, dst, len); ++ dst[i] = '\0'; ++ ++ return dst; ++} ++ + /* hp_wmi_strdup - devm_kstrdup, but length-limited */ + static char *hp_wmi_strdup(struct device *dev, const char *src) + { +@@ -412,6 +459,23 @@ static char *hp_wmi_strdup(struct device *dev, const char *src) + return dst; + } + ++/* hp_wmi_wstrdup - hp_wmi_strdup, but for a raw WMI string */ ++static char *hp_wmi_wstrdup(struct device *dev, const u8 *buf) ++{ ++ char *src; ++ char *dst; ++ ++ src = convert_raw_wmi_string(buf); ++ if (!src) ++ return NULL; ++ ++ dst = hp_wmi_strdup(dev, strim(src)); /* Note: Copy is trimmed. */ ++ ++ kfree(src); ++ ++ return dst; ++} ++ + /* + * hp_wmi_get_wobj - poll WMI for a WMI object instance + * @guid: WMI object GUID +@@ -462,8 +526,14 @@ static int check_wobj(const union acpi_object *wobj, + for (prop = 0; prop <= last_prop; prop++) { + type = elements[prop].type; + valid_type = property_map[prop]; +- if (type != valid_type) ++ if (type != valid_type) { ++ if (type == ACPI_TYPE_BUFFER && ++ valid_type == ACPI_TYPE_STRING && ++ is_raw_wmi_string(elements[prop].buffer.pointer, ++ elements[prop].buffer.length)) ++ continue; + return -EINVAL; ++ } + } + + return 0; +@@ -480,7 +550,9 @@ static int extract_acpi_value(struct device *dev, + break; + + case ACPI_TYPE_STRING: +- *out_string = hp_wmi_strdup(dev, strim(element->string.pointer)); ++ *out_string = element->type == ACPI_TYPE_BUFFER ? ++ hp_wmi_wstrdup(dev, element->buffer.pointer) : ++ hp_wmi_strdup(dev, strim(element->string.pointer)); + if (!*out_string) + return -ENOMEM; + break; +@@ -861,7 +933,9 @@ update_numeric_sensor_from_wobj(struct device *dev, + { + const union acpi_object *elements; + const union acpi_object *element; +- const char *string; ++ const char *new_string; ++ char *trimmed; ++ char *string; + bool is_new; + int offset; + u8 size; +@@ -885,11 +959,21 @@ update_numeric_sensor_from_wobj(struct device *dev, + offset = is_new ? size - 1 : -2; + + element = &elements[HP_WMI_PROPERTY_CURRENT_STATE + offset]; +- string = strim(element->string.pointer); +- +- if (strcmp(string, nsensor->current_state)) { +- devm_kfree(dev, nsensor->current_state); +- nsensor->current_state = hp_wmi_strdup(dev, string); ++ string = element->type == ACPI_TYPE_BUFFER ? ++ convert_raw_wmi_string(element->buffer.pointer) : ++ element->string.pointer; ++ ++ if (string) { ++ trimmed = strim(string); ++ if (strcmp(trimmed, nsensor->current_state)) { ++ new_string = hp_wmi_strdup(dev, trimmed); ++ if (new_string) { ++ devm_kfree(dev, nsensor->current_state); ++ nsensor->current_state = new_string; ++ } ++ } ++ if (element->type == ACPI_TYPE_BUFFER) ++ kfree(string); + } + + /* Old variant: -2 (not -1) because it lacks the Size property. */ +@@ -996,11 +1080,15 @@ static int check_event_wobj(const union acpi_object *wobj) + HP_WMI_EVENT_PROPERTY_STATUS); + } + +-static int populate_event_from_wobj(struct hp_wmi_event *event, ++static int populate_event_from_wobj(struct device *dev, ++ struct hp_wmi_event *event, + union acpi_object *wobj) + { + int prop = HP_WMI_EVENT_PROPERTY_NAME; + union acpi_object *element; ++ acpi_object_type type; ++ char *string; ++ u32 value; + int err; + + err = check_event_wobj(wobj); +@@ -1009,20 +1097,24 @@ static int populate_event_from_wobj(struct hp_wmi_event *event, + + element = wobj->package.elements; + +- /* Extracted strings are NOT device-managed copies. */ +- + for (; prop <= HP_WMI_EVENT_PROPERTY_CATEGORY; prop++, element++) { ++ type = hp_wmi_event_property_map[prop]; ++ ++ err = extract_acpi_value(dev, element, type, &value, &string); ++ if (err) ++ return err; ++ + switch (prop) { + case HP_WMI_EVENT_PROPERTY_NAME: +- event->name = strim(element->string.pointer); ++ event->name = string; + break; + + case HP_WMI_EVENT_PROPERTY_DESCRIPTION: +- event->description = strim(element->string.pointer); ++ event->description = string; + break; + + case HP_WMI_EVENT_PROPERTY_CATEGORY: +- event->category = element->integer.value; ++ event->category = value; + break; + + default: +@@ -1511,8 +1603,8 @@ static void hp_wmi_notify(u32 value, void *context) + struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL }; + struct hp_wmi_sensors *state = context; + struct device *dev = &state->wdev->dev; ++ struct hp_wmi_event event = {}; + struct hp_wmi_info *fan_info; +- struct hp_wmi_event event; + union acpi_object *wobj; + acpi_status err; + int event_type; +@@ -1546,7 +1638,7 @@ static void hp_wmi_notify(u32 value, void *context) + + wobj = out.pointer; + +- err = populate_event_from_wobj(&event, wobj); ++ err = populate_event_from_wobj(dev, &event, wobj); + if (err) { + dev_warn(dev, "Bad event data (ACPI type %d)\n", wobj->type); + goto out_free_wobj; +@@ -1577,6 +1669,9 @@ static void hp_wmi_notify(u32 value, void *context) + out_free_wobj: + kfree(wobj); + ++ devm_kfree(dev, event.name); ++ devm_kfree(dev, event.description); ++ + out_unlock: + mutex_unlock(&state->lock); + } +diff --git a/drivers/hwmon/nct6775-core.c b/drivers/hwmon/nct6775-core.c +index d928eb8ae5a37..92a49fafe2c02 100644 +--- a/drivers/hwmon/nct6775-core.c ++++ b/drivers/hwmon/nct6775-core.c +@@ -2553,6 +2553,13 @@ store_pwm(struct device *dev, struct device_attribute *attr, const char *buf, + int err; + u16 reg; + ++ /* ++ * The fan control mode should be set to manual if the user wants to adjust ++ * the fan speed. Otherwise, it will fail to set. ++ */ ++ if (index == 0 && data->pwm_enable[nr] > manual) ++ return -EBUSY; ++ + err = kstrtoul(buf, 10, &val); + if (err < 0) + return err; +diff --git a/drivers/i2c/busses/i2c-rk3x.c b/drivers/i2c/busses/i2c-rk3x.c +index 4362db7c57892..086fdf262e7b6 100644 +--- a/drivers/i2c/busses/i2c-rk3x.c ++++ b/drivers/i2c/busses/i2c-rk3x.c +@@ -1295,8 +1295,12 @@ static int rk3x_i2c_probe(struct platform_device *pdev) + return -EINVAL; + } + +- /* 27+i: write mask, 11+i: value */ +- value = BIT(27 + bus_nr) | BIT(11 + bus_nr); ++ /* rv1126 i2c2 uses non-sequential write mask 20, value 4 */ ++ if (i2c->soc_data == &rv1126_soc_data && bus_nr == 2) ++ value = BIT(20) | BIT(4); ++ else ++ /* 27+i: write mask, 11+i: value */ ++ value = BIT(27 + bus_nr) | BIT(11 + bus_nr); + + ret = regmap_write(grf, i2c->soc_data->grf_offset, value); + if (ret != 0) { +diff --git a/drivers/i3c/master/i3c-master-cdns.c b/drivers/i3c/master/i3c-master-cdns.c +index bcbe8f914149b..c1627f3552ce3 100644 +--- a/drivers/i3c/master/i3c-master-cdns.c ++++ b/drivers/i3c/master/i3c-master-cdns.c +@@ -76,7 +76,8 @@ + #define PRESCL_CTRL0 0x14 + #define PRESCL_CTRL0_I2C(x) ((x) << 16) + #define PRESCL_CTRL0_I3C(x) (x) +-#define PRESCL_CTRL0_MAX GENMASK(9, 0) ++#define PRESCL_CTRL0_I3C_MAX GENMASK(9, 0) ++#define PRESCL_CTRL0_I2C_MAX GENMASK(15, 0) + + #define PRESCL_CTRL1 0x18 + #define PRESCL_CTRL1_PP_LOW_MASK GENMASK(15, 8) +@@ -1233,7 +1234,7 @@ static int cdns_i3c_master_bus_init(struct i3c_master_controller *m) + return -EINVAL; + + pres = DIV_ROUND_UP(sysclk_rate, (bus->scl_rate.i3c * 4)) - 1; +- if (pres > PRESCL_CTRL0_MAX) ++ if (pres > PRESCL_CTRL0_I3C_MAX) + return -ERANGE; + + bus->scl_rate.i3c = sysclk_rate / ((pres + 1) * 4); +@@ -1246,7 +1247,7 @@ static int cdns_i3c_master_bus_init(struct i3c_master_controller *m) + max_i2cfreq = bus->scl_rate.i2c; + + pres = (sysclk_rate / (max_i2cfreq * 5)) - 1; +- if (pres > PRESCL_CTRL0_MAX) ++ if (pres > PRESCL_CTRL0_I2C_MAX) + return -ERANGE; + + bus->scl_rate.i2c = sysclk_rate / ((pres + 1) * 5); +diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +index 5b3154503bf49..319d4288eddde 100644 +--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c ++++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +@@ -531,21 +531,18 @@ static int ipoib_mcast_join(struct net_device *dev, struct ipoib_mcast *mcast) + if (test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)) + rec.join_state = SENDONLY_FULLMEMBER_JOIN; + } +- spin_unlock_irq(&priv->lock); + + multicast = ib_sa_join_multicast(&ipoib_sa_client, priv->ca, priv->port, +- &rec, comp_mask, GFP_KERNEL, ++ &rec, comp_mask, GFP_ATOMIC, + ipoib_mcast_join_complete, mcast); +- spin_lock_irq(&priv->lock); + if (IS_ERR(multicast)) { + ret = PTR_ERR(multicast); + ipoib_warn(priv, "ib_sa_join_multicast failed, status %d\n", ret); + /* Requeue this join task with a backoff delay */ + __ipoib_mcast_schedule_join_thread(priv, mcast, 1); + clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags); +- spin_unlock_irq(&priv->lock); + complete(&mcast->done); +- spin_lock_irq(&priv->lock); ++ return ret; + } + return 0; + } +diff --git a/drivers/leds/trigger/ledtrig-panic.c b/drivers/leds/trigger/ledtrig-panic.c +index 64abf2e91608a..5a6b21bfeb9af 100644 +--- a/drivers/leds/trigger/ledtrig-panic.c ++++ b/drivers/leds/trigger/ledtrig-panic.c +@@ -64,10 +64,13 @@ static long led_panic_blink(int state) + + static int __init ledtrig_panic_init(void) + { ++ led_trigger_register_simple("panic", &trigger); ++ if (!trigger) ++ return -ENOMEM; ++ + atomic_notifier_chain_register(&panic_notifier_list, + &led_trigger_panic_nb); + +- led_trigger_register_simple("panic", &trigger); + panic_blink = led_panic_blink; + return 0; + } +diff --git a/drivers/mailbox/arm_mhuv2.c b/drivers/mailbox/arm_mhuv2.c +index c6d4957c4da83..0ec21dcdbde72 100644 +--- a/drivers/mailbox/arm_mhuv2.c ++++ b/drivers/mailbox/arm_mhuv2.c +@@ -553,7 +553,8 @@ static irqreturn_t mhuv2_sender_interrupt(int irq, void *data) + priv = chan->con_priv; + + if (!IS_PROTOCOL_DOORBELL(priv)) { +- writel_relaxed(1, &mhu->send->ch_wn[priv->ch_wn_idx + priv->windows - 1].int_clr); ++ for (i = 0; i < priv->windows; i++) ++ writel_relaxed(1, &mhu->send->ch_wn[priv->ch_wn_idx + i].int_clr); + + if (chan->cl) { + mbox_chan_txdone(chan, 0); +diff --git a/drivers/md/md.c b/drivers/md/md.c +index 22b54788bceab..21b04607d53a9 100644 +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -1219,6 +1219,7 @@ struct super_type { + struct md_rdev *refdev, + int minor_version); + int (*validate_super)(struct mddev *mddev, ++ struct md_rdev *freshest, + struct md_rdev *rdev); + void (*sync_super)(struct mddev *mddev, + struct md_rdev *rdev); +@@ -1356,8 +1357,9 @@ static int super_90_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor + + /* + * validate_super for 0.90.0 ++ * note: we are not using "freshest" for 0.9 superblock + */ +-static int super_90_validate(struct mddev *mddev, struct md_rdev *rdev) ++static int super_90_validate(struct mddev *mddev, struct md_rdev *freshest, struct md_rdev *rdev) + { + mdp_disk_t *desc; + mdp_super_t *sb = page_address(rdev->sb_page); +@@ -1869,7 +1871,7 @@ static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_ + return ret; + } + +-static int super_1_validate(struct mddev *mddev, struct md_rdev *rdev) ++static int super_1_validate(struct mddev *mddev, struct md_rdev *freshest, struct md_rdev *rdev) + { + struct mdp_superblock_1 *sb = page_address(rdev->sb_page); + __u64 ev1 = le64_to_cpu(sb->events); +@@ -1965,13 +1967,15 @@ static int super_1_validate(struct mddev *mddev, struct md_rdev *rdev) + } + } else if (mddev->pers == NULL) { + /* Insist of good event counter while assembling, except for +- * spares (which don't need an event count) */ +- ++ev1; ++ * spares (which don't need an event count). ++ * Similar to mdadm, we allow event counter difference of 1 ++ * from the freshest device. ++ */ + if (rdev->desc_nr >= 0 && + rdev->desc_nr < le32_to_cpu(sb->max_dev) && + (le16_to_cpu(sb->dev_roles[rdev->desc_nr]) < MD_DISK_ROLE_MAX || + le16_to_cpu(sb->dev_roles[rdev->desc_nr]) == MD_DISK_ROLE_JOURNAL)) +- if (ev1 < mddev->events) ++ if (ev1 + 1 < mddev->events) + return -EINVAL; + } else if (mddev->bitmap) { + /* If adding to array with a bitmap, then we can accept an +@@ -1992,8 +1996,38 @@ static int super_1_validate(struct mddev *mddev, struct md_rdev *rdev) + rdev->desc_nr >= le32_to_cpu(sb->max_dev)) { + role = MD_DISK_ROLE_SPARE; + rdev->desc_nr = -1; +- } else ++ } else if (mddev->pers == NULL && freshest && ev1 < mddev->events) { ++ /* ++ * If we are assembling, and our event counter is smaller than the ++ * highest event counter, we cannot trust our superblock about the role. ++ * It could happen that our rdev was marked as Faulty, and all other ++ * superblocks were updated with +1 event counter. ++ * Then, before the next superblock update, which typically happens when ++ * remove_and_add_spares() removes the device from the array, there was ++ * a crash or reboot. ++ * If we allow current rdev without consulting the freshest superblock, ++ * we could cause data corruption. ++ * Note that in this case our event counter is smaller by 1 than the ++ * highest, otherwise, this rdev would not be allowed into array; ++ * both kernel and mdadm allow event counter difference of 1. ++ */ ++ struct mdp_superblock_1 *freshest_sb = page_address(freshest->sb_page); ++ u32 freshest_max_dev = le32_to_cpu(freshest_sb->max_dev); ++ ++ if (rdev->desc_nr >= freshest_max_dev) { ++ /* this is unexpected, better not proceed */ ++ pr_warn("md: %s: rdev[%pg]: desc_nr(%d) >= freshest(%pg)->sb->max_dev(%u)\n", ++ mdname(mddev), rdev->bdev, rdev->desc_nr, ++ freshest->bdev, freshest_max_dev); ++ return -EUCLEAN; ++ } ++ ++ role = le16_to_cpu(freshest_sb->dev_roles[rdev->desc_nr]); ++ pr_debug("md: %s: rdev[%pg]: role=%d(0x%x) according to freshest %pg\n", ++ mdname(mddev), rdev->bdev, role, role, freshest->bdev); ++ } else { + role = le16_to_cpu(sb->dev_roles[rdev->desc_nr]); ++ } + switch(role) { + case MD_DISK_ROLE_SPARE: /* spare */ + break; +@@ -2900,7 +2934,7 @@ static int add_bound_rdev(struct md_rdev *rdev) + * and should be added immediately. + */ + super_types[mddev->major_version]. +- validate_super(mddev, rdev); ++ validate_super(mddev, NULL/*freshest*/, rdev); + err = mddev->pers->hot_add_disk(mddev, rdev); + if (err) { + md_kick_rdev_from_array(rdev); +@@ -3837,7 +3871,7 @@ static int analyze_sbs(struct mddev *mddev) + } + + super_types[mddev->major_version]. +- validate_super(mddev, freshest); ++ validate_super(mddev, NULL/*freshest*/, freshest); + + i = 0; + rdev_for_each_safe(rdev, tmp, mddev) { +@@ -3852,7 +3886,7 @@ static int analyze_sbs(struct mddev *mddev) + } + if (rdev != freshest) { + if (super_types[mddev->major_version]. +- validate_super(mddev, rdev)) { ++ validate_super(mddev, freshest, rdev)) { + pr_warn("md: kicking non-fresh %pg from array!\n", + rdev->bdev); + md_kick_rdev_from_array(rdev); +@@ -6843,7 +6877,7 @@ int md_add_new_disk(struct mddev *mddev, struct mdu_disk_info_s *info) + rdev->saved_raid_disk = rdev->raid_disk; + } else + super_types[mddev->major_version]. +- validate_super(mddev, rdev); ++ validate_super(mddev, NULL/*freshest*/, rdev); + if ((info->state & (1<<MD_DISK_SYNC)) && + rdev->raid_disk != info->raid_disk) { + /* This was a hot-add request, but events doesn't +diff --git a/drivers/media/i2c/imx335.c b/drivers/media/i2c/imx335.c +index ec729126274b2..964a81bec5a4c 100644 +--- a/drivers/media/i2c/imx335.c ++++ b/drivers/media/i2c/imx335.c +@@ -962,8 +962,8 @@ static int imx335_init_controls(struct imx335 *imx335) + imx335->hblank_ctrl = v4l2_ctrl_new_std(ctrl_hdlr, + &imx335_ctrl_ops, + V4L2_CID_HBLANK, +- IMX335_REG_MIN, +- IMX335_REG_MAX, ++ mode->hblank, ++ mode->hblank, + 1, mode->hblank); + if (imx335->hblank_ctrl) + imx335->hblank_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; +diff --git a/drivers/media/i2c/ov2740.c b/drivers/media/i2c/ov2740.c +index 24e468485fbf0..6be22586c3d2e 100644 +--- a/drivers/media/i2c/ov2740.c ++++ b/drivers/media/i2c/ov2740.c +@@ -310,7 +310,7 @@ static const struct ov2740_mode supported_modes[] = { + { + .width = 1932, + .height = 1092, +- .hts = 1080, ++ .hts = 2160, + .vts_def = OV2740_VTS_DEF, + .vts_min = OV2740_VTS_MIN, + .reg_list = { +@@ -357,15 +357,6 @@ static u64 to_pixel_rate(u32 f_index) + return pixel_rate; + } + +-static u64 to_pixels_per_line(u32 hts, u32 f_index) +-{ +- u64 ppl = hts * to_pixel_rate(f_index); +- +- do_div(ppl, OV2740_SCLK); +- +- return ppl; +-} +- + static int ov2740_read_reg(struct ov2740 *ov2740, u16 reg, u16 len, u32 *val) + { + struct i2c_client *client = v4l2_get_subdevdata(&ov2740->sd); +@@ -598,8 +589,7 @@ static int ov2740_init_controls(struct ov2740 *ov2740) + V4L2_CID_VBLANK, vblank_min, + vblank_max, 1, vblank_default); + +- h_blank = to_pixels_per_line(cur_mode->hts, cur_mode->link_freq_index); +- h_blank -= cur_mode->width; ++ h_blank = cur_mode->hts - cur_mode->width; + ov2740->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov2740_ctrl_ops, + V4L2_CID_HBLANK, h_blank, h_blank, 1, + h_blank); +@@ -842,8 +832,7 @@ static int ov2740_set_format(struct v4l2_subdev *sd, + mode->vts_min - mode->height, + OV2740_VTS_MAX - mode->height, 1, vblank_def); + __v4l2_ctrl_s_ctrl(ov2740->vblank, vblank_def); +- h_blank = to_pixels_per_line(mode->hts, mode->link_freq_index) - +- mode->width; ++ h_blank = mode->hts - mode->width; + __v4l2_ctrl_modify_range(ov2740->hblank, h_blank, h_blank, 1, h_blank); + + return 0; +diff --git a/drivers/media/pci/ddbridge/ddbridge-main.c b/drivers/media/pci/ddbridge/ddbridge-main.c +index 91733ab9f58c3..363badab7cf07 100644 +--- a/drivers/media/pci/ddbridge/ddbridge-main.c ++++ b/drivers/media/pci/ddbridge/ddbridge-main.c +@@ -238,7 +238,7 @@ fail: + ddb_unmap(dev); + pci_set_drvdata(pdev, NULL); + pci_disable_device(pdev); +- return -1; ++ return stat; + } + + /****************************************************************************/ +diff --git a/drivers/media/platform/amphion/vpu.h b/drivers/media/platform/amphion/vpu.h +index 5a701f64289ef..0246cf0ac3a8b 100644 +--- a/drivers/media/platform/amphion/vpu.h ++++ b/drivers/media/platform/amphion/vpu.h +@@ -154,7 +154,6 @@ struct vpu_core { + struct vpu_mbox tx_type; + struct vpu_mbox tx_data; + struct vpu_mbox rx; +- unsigned long cmd_seq; + + wait_queue_head_t ack_wq; + struct completion cmp; +@@ -253,6 +252,8 @@ struct vpu_inst { + + struct list_head cmd_q; + void *pending; ++ unsigned long cmd_seq; ++ atomic_long_t last_response_cmd; + + struct vpu_inst_ops *ops; + const struct vpu_format *formats; +diff --git a/drivers/media/platform/amphion/vpu_cmds.c b/drivers/media/platform/amphion/vpu_cmds.c +index c2337812573ef..5695f5c1cb3e8 100644 +--- a/drivers/media/platform/amphion/vpu_cmds.c ++++ b/drivers/media/platform/amphion/vpu_cmds.c +@@ -32,6 +32,7 @@ struct vpu_cmd_t { + struct vpu_cmd_request *request; + struct vpu_rpc_event *pkt; + unsigned long key; ++ atomic_long_t *last_response_cmd; + }; + + static struct vpu_cmd_request vpu_cmd_requests[] = { +@@ -115,6 +116,8 @@ static void vpu_free_cmd(struct vpu_cmd_t *cmd) + { + if (!cmd) + return; ++ if (cmd->last_response_cmd) ++ atomic_long_set(cmd->last_response_cmd, cmd->key); + vfree(cmd->pkt); + vfree(cmd); + } +@@ -172,7 +175,8 @@ static int vpu_request_cmd(struct vpu_inst *inst, u32 id, void *data, + return -ENOMEM; + + mutex_lock(&core->cmd_lock); +- cmd->key = core->cmd_seq++; ++ cmd->key = ++inst->cmd_seq; ++ cmd->last_response_cmd = &inst->last_response_cmd; + if (key) + *key = cmd->key; + if (sync) +@@ -246,26 +250,12 @@ void vpu_clear_request(struct vpu_inst *inst) + + static bool check_is_responsed(struct vpu_inst *inst, unsigned long key) + { +- struct vpu_core *core = inst->core; +- struct vpu_cmd_t *cmd; +- bool flag = true; ++ unsigned long last_response = atomic_long_read(&inst->last_response_cmd); + +- mutex_lock(&core->cmd_lock); +- cmd = inst->pending; +- if (cmd && key == cmd->key) { +- flag = false; +- goto exit; +- } +- list_for_each_entry(cmd, &inst->cmd_q, list) { +- if (key == cmd->key) { +- flag = false; +- break; +- } +- } +-exit: +- mutex_unlock(&core->cmd_lock); ++ if (key <= last_response && (last_response - key) < (ULONG_MAX >> 1)) ++ return true; + +- return flag; ++ return false; + } + + static int sync_session_response(struct vpu_inst *inst, unsigned long key, long timeout, int try) +diff --git a/drivers/media/platform/amphion/vpu_v4l2.c b/drivers/media/platform/amphion/vpu_v4l2.c +index 0f6e4c666440e..d7e0de49b3dce 100644 +--- a/drivers/media/platform/amphion/vpu_v4l2.c ++++ b/drivers/media/platform/amphion/vpu_v4l2.c +@@ -716,6 +716,7 @@ int vpu_v4l2_open(struct file *file, struct vpu_inst *inst) + func = &vpu->decoder; + + atomic_set(&inst->ref_count, 0); ++ atomic_long_set(&inst->last_response_cmd, 0); + vpu_inst_get(inst); + inst->vpu = vpu; + inst->core = vpu_request_core(vpu, inst->type); +diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/platform/rockchip/rga/rga.c +index f1c532a5802ac..25f5b5eebf13f 100644 +--- a/drivers/media/platform/rockchip/rga/rga.c ++++ b/drivers/media/platform/rockchip/rga/rga.c +@@ -184,25 +184,16 @@ static int rga_setup_ctrls(struct rga_ctx *ctx) + static struct rga_fmt formats[] = { + { + .fourcc = V4L2_PIX_FMT_ARGB32, +- .color_swap = RGA_COLOR_RB_SWAP, ++ .color_swap = RGA_COLOR_ALPHA_SWAP, + .hw_format = RGA_COLOR_FMT_ABGR8888, + .depth = 32, + .uv_factor = 1, + .y_div = 1, + .x_div = 1, + }, +- { +- .fourcc = V4L2_PIX_FMT_XRGB32, +- .color_swap = RGA_COLOR_RB_SWAP, +- .hw_format = RGA_COLOR_FMT_XBGR8888, +- .depth = 32, +- .uv_factor = 1, +- .y_div = 1, +- .x_div = 1, +- }, + { + .fourcc = V4L2_PIX_FMT_ABGR32, +- .color_swap = RGA_COLOR_ALPHA_SWAP, ++ .color_swap = RGA_COLOR_RB_SWAP, + .hw_format = RGA_COLOR_FMT_ABGR8888, + .depth = 32, + .uv_factor = 1, +@@ -211,7 +202,7 @@ static struct rga_fmt formats[] = { + }, + { + .fourcc = V4L2_PIX_FMT_XBGR32, +- .color_swap = RGA_COLOR_ALPHA_SWAP, ++ .color_swap = RGA_COLOR_RB_SWAP, + .hw_format = RGA_COLOR_FMT_XBGR8888, + .depth = 32, + .uv_factor = 1, +diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h +index 1e7cea1bea5ea..2d7f06281c390 100644 +--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h ++++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h +@@ -61,6 +61,14 @@ struct dentry; + RKISP1_CIF_ISP_EXP_END | \ + RKISP1_CIF_ISP_HIST_MEASURE_RDY) + ++/* IRQ lines */ ++enum rkisp1_irq_line { ++ RKISP1_IRQ_ISP = 0, ++ RKISP1_IRQ_MI, ++ RKISP1_IRQ_MIPI, ++ RKISP1_NUM_IRQS, ++}; ++ + /* enum for the resizer pads */ + enum rkisp1_rsz_pad { + RKISP1_RSZ_PAD_SINK, +@@ -423,7 +431,6 @@ struct rkisp1_debug { + * struct rkisp1_device - ISP platform device + * + * @base_addr: base register address +- * @irq: the irq number + * @dev: a pointer to the struct device + * @clk_size: number of clocks + * @clks: array of clocks +@@ -441,6 +448,7 @@ struct rkisp1_debug { + * @stream_lock: serializes {start/stop}_streaming callbacks between the capture devices. + * @debug: debug params to be exposed on debugfs + * @info: version-specific ISP information ++ * @irqs: IRQ line numbers + */ + struct rkisp1_device { + void __iomem *base_addr; +@@ -461,6 +469,7 @@ struct rkisp1_device { + struct mutex stream_lock; /* serialize {start/stop}_streaming cb between capture devices */ + struct rkisp1_debug debug; + const struct rkisp1_info *info; ++ int irqs[RKISP1_NUM_IRQS]; + }; + + /* +diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-csi.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-csi.c +index 6e17b2817e610..702adee83322b 100644 +--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-csi.c ++++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-csi.c +@@ -125,8 +125,20 @@ static void rkisp1_csi_disable(struct rkisp1_csi *csi) + struct rkisp1_device *rkisp1 = csi->rkisp1; + u32 val; + +- /* Mask and clear interrupts. */ ++ /* Mask MIPI interrupts. */ + rkisp1_write(rkisp1, RKISP1_CIF_MIPI_IMSC, 0); ++ ++ /* Flush posted writes */ ++ rkisp1_read(rkisp1, RKISP1_CIF_MIPI_IMSC); ++ ++ /* ++ * Wait until the IRQ handler has ended. The IRQ handler may get called ++ * even after this, but it will return immediately as the MIPI ++ * interrupts have been masked. ++ */ ++ synchronize_irq(rkisp1->irqs[RKISP1_IRQ_MIPI]); ++ ++ /* Clear MIPI interrupt status */ + rkisp1_write(rkisp1, RKISP1_CIF_MIPI_ICR, ~0); + + val = rkisp1_read(rkisp1, RKISP1_CIF_MIPI_CTRL); +diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c +index 894d5afaff4e1..f96f821a7b50d 100644 +--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c ++++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c +@@ -114,6 +114,7 @@ + struct rkisp1_isr_data { + const char *name; + irqreturn_t (*isr)(int irq, void *ctx); ++ u32 line_mask; + }; + + /* ---------------------------------------------------------------------------- +@@ -442,17 +443,25 @@ error: + + static irqreturn_t rkisp1_isr(int irq, void *ctx) + { ++ irqreturn_t ret = IRQ_NONE; ++ + /* + * Call rkisp1_capture_isr() first to handle the frame that + * potentially completed using the current frame_sequence number before + * it is potentially incremented by rkisp1_isp_isr() in the vertical + * sync. + */ +- rkisp1_capture_isr(irq, ctx); +- rkisp1_isp_isr(irq, ctx); +- rkisp1_csi_isr(irq, ctx); + +- return IRQ_HANDLED; ++ if (rkisp1_capture_isr(irq, ctx) == IRQ_HANDLED) ++ ret = IRQ_HANDLED; ++ ++ if (rkisp1_isp_isr(irq, ctx) == IRQ_HANDLED) ++ ret = IRQ_HANDLED; ++ ++ if (rkisp1_csi_isr(irq, ctx) == IRQ_HANDLED) ++ ret = IRQ_HANDLED; ++ ++ return ret; + } + + static const char * const px30_isp_clks[] = { +@@ -463,9 +472,9 @@ static const char * const px30_isp_clks[] = { + }; + + static const struct rkisp1_isr_data px30_isp_isrs[] = { +- { "isp", rkisp1_isp_isr }, +- { "mi", rkisp1_capture_isr }, +- { "mipi", rkisp1_csi_isr }, ++ { "isp", rkisp1_isp_isr, BIT(RKISP1_IRQ_ISP) }, ++ { "mi", rkisp1_capture_isr, BIT(RKISP1_IRQ_MI) }, ++ { "mipi", rkisp1_csi_isr, BIT(RKISP1_IRQ_MIPI) }, + }; + + static const struct rkisp1_info px30_isp_info = { +@@ -484,7 +493,7 @@ static const char * const rk3399_isp_clks[] = { + }; + + static const struct rkisp1_isr_data rk3399_isp_isrs[] = { +- { NULL, rkisp1_isr }, ++ { NULL, rkisp1_isr, BIT(RKISP1_IRQ_ISP) | BIT(RKISP1_IRQ_MI) | BIT(RKISP1_IRQ_MIPI) }, + }; + + static const struct rkisp1_info rk3399_isp_info = { +@@ -535,6 +544,9 @@ static int rkisp1_probe(struct platform_device *pdev) + if (IS_ERR(rkisp1->base_addr)) + return PTR_ERR(rkisp1->base_addr); + ++ for (unsigned int il = 0; il < ARRAY_SIZE(rkisp1->irqs); ++il) ++ rkisp1->irqs[il] = -1; ++ + for (i = 0; i < info->isr_size; i++) { + irq = info->isrs[i].name + ? platform_get_irq_byname(pdev, info->isrs[i].name) +@@ -542,7 +554,12 @@ static int rkisp1_probe(struct platform_device *pdev) + if (irq < 0) + return irq; + +- ret = devm_request_irq(dev, irq, info->isrs[i].isr, IRQF_SHARED, ++ for (unsigned int il = 0; il < ARRAY_SIZE(rkisp1->irqs); ++il) { ++ if (info->isrs[i].line_mask & BIT(il)) ++ rkisp1->irqs[il] = irq; ++ } ++ ++ ret = devm_request_irq(dev, irq, info->isrs[i].isr, 0, + dev_driver_string(dev), dev); + if (ret) { + dev_err(dev, "request irq failed: %d\n", ret); +diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c +index 45d1ab96fc6e7..5fbc47bda6831 100644 +--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c ++++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c +@@ -254,11 +254,25 @@ static void rkisp1_isp_stop(struct rkisp1_isp *isp) + * ISP(mi) stop in mi frame end -> Stop ISP(mipi) -> + * Stop ISP(isp) ->wait for ISP isp off + */ +- /* stop and clear MI and ISP interrupts */ +- rkisp1_write(rkisp1, RKISP1_CIF_ISP_IMSC, 0); +- rkisp1_write(rkisp1, RKISP1_CIF_ISP_ICR, ~0); + ++ /* Mask MI and ISP interrupts */ ++ rkisp1_write(rkisp1, RKISP1_CIF_ISP_IMSC, 0); + rkisp1_write(rkisp1, RKISP1_CIF_MI_IMSC, 0); ++ ++ /* Flush posted writes */ ++ rkisp1_read(rkisp1, RKISP1_CIF_MI_IMSC); ++ ++ /* ++ * Wait until the IRQ handler has ended. The IRQ handler may get called ++ * even after this, but it will return immediately as the MI and ISP ++ * interrupts have been masked. ++ */ ++ synchronize_irq(rkisp1->irqs[RKISP1_IRQ_ISP]); ++ if (rkisp1->irqs[RKISP1_IRQ_ISP] != rkisp1->irqs[RKISP1_IRQ_MI]) ++ synchronize_irq(rkisp1->irqs[RKISP1_IRQ_MI]); ++ ++ /* Clear MI and ISP interrupt status */ ++ rkisp1_write(rkisp1, RKISP1_CIF_ISP_ICR, ~0); + rkisp1_write(rkisp1, RKISP1_CIF_MI_ICR, ~0); + + /* stop ISP */ +diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c +index 28ecc7347d543..6297870ee9e9e 100644 +--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c ++++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c +@@ -335,12 +335,8 @@ static int rkisp1_rsz_enum_mbus_code(struct v4l2_subdev *sd, + { + struct rkisp1_resizer *rsz = + container_of(sd, struct rkisp1_resizer, sd); +- struct v4l2_subdev_pad_config dummy_cfg; +- struct v4l2_subdev_state pad_state = { +- .pads = &dummy_cfg +- }; +- u32 pad = code->pad; +- int ret; ++ unsigned int index = code->index; ++ unsigned int i; + + if (code->pad == RKISP1_RSZ_PAD_SRC) { + /* supported mbus codes on the src are the same as in the capture */ +@@ -360,15 +356,29 @@ static int rkisp1_rsz_enum_mbus_code(struct v4l2_subdev *sd, + return 0; + } + +- /* supported mbus codes on the sink pad are the same as isp src pad */ +- code->pad = RKISP1_ISP_PAD_SOURCE_VIDEO; +- ret = v4l2_subdev_call(&rsz->rkisp1->isp.sd, pad, enum_mbus_code, +- &pad_state, code); ++ /* ++ * Supported mbus codes on the sink pad are the same as on the ISP ++ * source pad. ++ */ ++ for (i = 0; ; i++) { ++ const struct rkisp1_mbus_info *fmt = ++ rkisp1_mbus_info_get_by_index(i); + +- /* restore pad */ +- code->pad = pad; +- code->flags = 0; +- return ret; ++ if (!fmt) ++ break; ++ ++ if (!(fmt->direction & RKISP1_ISP_SD_SRC)) ++ continue; ++ ++ if (!index) { ++ code->code = fmt->mbus_code; ++ return 0; ++ } ++ ++ index--; ++ } ++ ++ return -EINVAL; + } + + static int rkisp1_rsz_init_config(struct v4l2_subdev *sd, +diff --git a/drivers/media/usb/stk1160/stk1160-video.c b/drivers/media/usb/stk1160/stk1160-video.c +index 4e966f6bf608d..366f0e4a5dc0d 100644 +--- a/drivers/media/usb/stk1160/stk1160-video.c ++++ b/drivers/media/usb/stk1160/stk1160-video.c +@@ -107,8 +107,7 @@ void stk1160_copy_video(struct stk1160 *dev, u8 *src, int len) + + /* + * TODO: These stk1160_dbg are very spammy! +- * We should 1) check why we are getting them +- * and 2) add ratelimit. ++ * We should check why we are getting them. + * + * UPDATE: One of the reasons (the only one?) for getting these + * is incorrect standard (mismatch between expected and configured). +@@ -151,7 +150,7 @@ void stk1160_copy_video(struct stk1160 *dev, u8 *src, int len) + + /* Let the bug hunt begin! sanity checks! */ + if (lencopy < 0) { +- stk1160_dbg("copy skipped: negative lencopy\n"); ++ printk_ratelimited(KERN_DEBUG "copy skipped: negative lencopy\n"); + return; + } + +diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c +index 08fcd2ffa727b..bbd90123a4e76 100644 +--- a/drivers/media/usb/uvc/uvc_driver.c ++++ b/drivers/media/usb/uvc/uvc_driver.c +@@ -2592,6 +2592,15 @@ static const struct usb_device_id uvc_ids[] = { + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = (kernel_ulong_t)&uvc_ctrl_power_line_limited }, ++ /* Chicony Electronics Co., Ltd Integrated Camera */ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x04f2, ++ .idProduct = 0xb67c, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = UVC_PC_PROTOCOL_15, ++ .driver_info = (kernel_ulong_t)&uvc_ctrl_power_line_uvc11 }, + /* Chicony EasyCamera */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, +@@ -2994,6 +3003,15 @@ static const struct usb_device_id uvc_ids[] = { + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_FORCE_BPP) }, ++ /* SunplusIT Inc HD Camera */ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x2b7e, ++ .idProduct = 0xb752, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = UVC_PC_PROTOCOL_15, ++ .driver_info = (kernel_ulong_t)&uvc_ctrl_power_line_uvc11 }, + /* Lenovo Integrated Camera */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, +diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig +index 90ce58fd629e5..68d71b4b55bd3 100644 +--- a/drivers/mfd/Kconfig ++++ b/drivers/mfd/Kconfig +@@ -1483,6 +1483,7 @@ config MFD_SYSCON + + config MFD_TI_AM335X_TSCADC + tristate "TI ADC / Touch Screen chip support" ++ depends on ARCH_OMAP2PLUS || ARCH_K3 || COMPILE_TEST + select MFD_CORE + select REGMAP + select REGMAP_MMIO +diff --git a/drivers/misc/lis3lv02d/lis3lv02d_i2c.c b/drivers/misc/lis3lv02d/lis3lv02d_i2c.c +index 3882e97e96a70..c6eb27d46cb06 100644 +--- a/drivers/misc/lis3lv02d/lis3lv02d_i2c.c ++++ b/drivers/misc/lis3lv02d/lis3lv02d_i2c.c +@@ -150,6 +150,7 @@ static int lis3lv02d_i2c_probe(struct i2c_client *client) + lis3_dev.init = lis3_i2c_init; + lis3_dev.read = lis3_i2c_read; + lis3_dev.write = lis3_i2c_write; ++ lis3_dev.reg_ctrl = lis3_reg_ctrl; + lis3_dev.irq = client->irq; + lis3_dev.ac = lis3lv02d_axis_map; + lis3_dev.pm_dev = &client->dev; +diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c +index dc2c7b9796563..7edf0fd58c346 100644 +--- a/drivers/net/bonding/bond_alb.c ++++ b/drivers/net/bonding/bond_alb.c +@@ -985,7 +985,8 @@ static int alb_upper_dev_walk(struct net_device *upper, + if (netif_is_macvlan(upper) && !strict_match) { + tags = bond_verify_device_path(bond->dev, upper, 0); + if (IS_ERR_OR_NULL(tags)) +- BUG(); ++ return -ENOMEM; ++ + alb_send_lp_vid(slave, upper->dev_addr, + tags[0].vlan_proto, tags[0].vlan_id); + kfree(tags); +diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c +index d27c6b70a2f67..2333f6383b542 100644 +--- a/drivers/net/dsa/mt7530.c ++++ b/drivers/net/dsa/mt7530.c +@@ -2838,8 +2838,7 @@ static void mt753x_phylink_mac_link_up(struct dsa_switch *ds, int port, + /* MT753x MAC works in 1G full duplex mode for all up-clocked + * variants. + */ +- if (interface == PHY_INTERFACE_MODE_INTERNAL || +- interface == PHY_INTERFACE_MODE_TRGMII || ++ if (interface == PHY_INTERFACE_MODE_TRGMII || + (phy_interface_mode_is_8023z(interface))) { + speed = SPEED_1000; + duplex = DUPLEX_FULL; +diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h +index 44383a03ef2ff..c54d305a1d831 100644 +--- a/drivers/net/dsa/mv88e6xxx/chip.h ++++ b/drivers/net/dsa/mv88e6xxx/chip.h +@@ -601,8 +601,8 @@ struct mv88e6xxx_ops { + int (*serdes_get_sset_count)(struct mv88e6xxx_chip *chip, int port); + int (*serdes_get_strings)(struct mv88e6xxx_chip *chip, int port, + uint8_t *data); +- int (*serdes_get_stats)(struct mv88e6xxx_chip *chip, int port, +- uint64_t *data); ++ size_t (*serdes_get_stats)(struct mv88e6xxx_chip *chip, int port, ++ uint64_t *data); + + /* SERDES registers for ethtool */ + int (*serdes_get_regs_len)(struct mv88e6xxx_chip *chip, int port); +diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c +index 3b4b42651fa3d..01ea53940786d 100644 +--- a/drivers/net/dsa/mv88e6xxx/serdes.c ++++ b/drivers/net/dsa/mv88e6xxx/serdes.c +@@ -177,8 +177,8 @@ static uint64_t mv88e6352_serdes_get_stat(struct mv88e6xxx_chip *chip, + return val; + } + +-int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port, +- uint64_t *data) ++size_t mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port, ++ uint64_t *data) + { + struct mv88e6xxx_port *mv88e6xxx_port = &chip->ports[port]; + struct mv88e6352_serdes_hw_stat *stat; +@@ -187,7 +187,7 @@ int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port, + + err = mv88e6352_g2_scratch_port_has_serdes(chip, port); + if (err <= 0) +- return err; ++ return 0; + + BUILD_BUG_ON(ARRAY_SIZE(mv88e6352_serdes_hw_stats) > + ARRAY_SIZE(mv88e6xxx_port->serdes_stats)); +@@ -429,8 +429,8 @@ static uint64_t mv88e6390_serdes_get_stat(struct mv88e6xxx_chip *chip, int lane, + return reg[0] | ((u64)reg[1] << 16) | ((u64)reg[2] << 32); + } + +-int mv88e6390_serdes_get_stats(struct mv88e6xxx_chip *chip, int port, +- uint64_t *data) ++size_t mv88e6390_serdes_get_stats(struct mv88e6xxx_chip *chip, int port, ++ uint64_t *data) + { + struct mv88e6390_serdes_hw_stat *stat; + int lane; +diff --git a/drivers/net/dsa/mv88e6xxx/serdes.h b/drivers/net/dsa/mv88e6xxx/serdes.h +index aac95cab46e3d..ff5c3ab31e155 100644 +--- a/drivers/net/dsa/mv88e6xxx/serdes.h ++++ b/drivers/net/dsa/mv88e6xxx/serdes.h +@@ -127,13 +127,13 @@ unsigned int mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip *chip, + int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port); + int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip, + int port, uint8_t *data); +-int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port, +- uint64_t *data); ++size_t mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port, ++ uint64_t *data); + int mv88e6390_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port); + int mv88e6390_serdes_get_strings(struct mv88e6xxx_chip *chip, + int port, uint8_t *data); +-int mv88e6390_serdes_get_stats(struct mv88e6xxx_chip *chip, int port, +- uint64_t *data); ++size_t mv88e6390_serdes_get_stats(struct mv88e6xxx_chip *chip, int port, ++ uint64_t *data); + + int mv88e6352_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port); + void mv88e6352_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p); +diff --git a/drivers/net/dsa/qca/qca8k-8xxx.c b/drivers/net/dsa/qca/qca8k-8xxx.c +index ec57d9d52072f..6f2a7aee7e5ad 100644 +--- a/drivers/net/dsa/qca/qca8k-8xxx.c ++++ b/drivers/net/dsa/qca/qca8k-8xxx.c +@@ -949,10 +949,15 @@ qca8k_mdio_register(struct qca8k_priv *priv) + struct dsa_switch *ds = priv->ds; + struct device_node *mdio; + struct mii_bus *bus; ++ int err; ++ ++ mdio = of_get_child_by_name(priv->dev->of_node, "mdio"); + + bus = devm_mdiobus_alloc(ds->dev); +- if (!bus) +- return -ENOMEM; ++ if (!bus) { ++ err = -ENOMEM; ++ goto out_put_node; ++ } + + bus->priv = (void *)priv; + snprintf(bus->id, MII_BUS_ID_SIZE, "qca8k-%d.%d", +@@ -962,12 +967,12 @@ qca8k_mdio_register(struct qca8k_priv *priv) + ds->user_mii_bus = bus; + + /* Check if the devicetree declare the port:phy mapping */ +- mdio = of_get_child_by_name(priv->dev->of_node, "mdio"); + if (of_device_is_available(mdio)) { + bus->name = "qca8k user mii"; + bus->read = qca8k_internal_mdio_read; + bus->write = qca8k_internal_mdio_write; +- return devm_of_mdiobus_register(priv->dev, bus, mdio); ++ err = devm_of_mdiobus_register(priv->dev, bus, mdio); ++ goto out_put_node; + } + + /* If a mapping can't be found the legacy mapping is used, +@@ -976,7 +981,13 @@ qca8k_mdio_register(struct qca8k_priv *priv) + bus->name = "qca8k-legacy user mii"; + bus->read = qca8k_legacy_mdio_read; + bus->write = qca8k_legacy_mdio_write; +- return devm_mdiobus_register(priv->dev, bus); ++ ++ err = devm_mdiobus_register(priv->dev, bus); ++ ++out_put_node: ++ of_node_put(mdio); ++ ++ return err; + } + + static int +@@ -2038,12 +2049,11 @@ qca8k_sw_probe(struct mdio_device *mdiodev) + priv->info = of_device_get_match_data(priv->dev); + + priv->reset_gpio = devm_gpiod_get_optional(priv->dev, "reset", +- GPIOD_ASIS); ++ GPIOD_OUT_HIGH); + if (IS_ERR(priv->reset_gpio)) + return PTR_ERR(priv->reset_gpio); + + if (priv->reset_gpio) { +- gpiod_set_value_cansleep(priv->reset_gpio, 1); + /* The active low duration must be greater than 10 ms + * and checkpatch.pl wants 20 ms. + */ +diff --git a/drivers/net/ethernet/amd/pds_core/adminq.c b/drivers/net/ethernet/amd/pds_core/adminq.c +index 5beadabc21361..ea773cfa0af67 100644 +--- a/drivers/net/ethernet/amd/pds_core/adminq.c ++++ b/drivers/net/ethernet/amd/pds_core/adminq.c +@@ -63,6 +63,15 @@ static int pdsc_process_notifyq(struct pdsc_qcq *qcq) + return nq_work; + } + ++static bool pdsc_adminq_inc_if_up(struct pdsc *pdsc) ++{ ++ if (pdsc->state & BIT_ULL(PDSC_S_STOPPING_DRIVER) || ++ pdsc->state & BIT_ULL(PDSC_S_FW_DEAD)) ++ return false; ++ ++ return refcount_inc_not_zero(&pdsc->adminq_refcnt); ++} ++ + void pdsc_process_adminq(struct pdsc_qcq *qcq) + { + union pds_core_adminq_comp *comp; +@@ -75,9 +84,9 @@ void pdsc_process_adminq(struct pdsc_qcq *qcq) + int aq_work = 0; + int credits; + +- /* Don't process AdminQ when shutting down */ +- if (pdsc->state & BIT_ULL(PDSC_S_STOPPING_DRIVER)) { +- dev_err(pdsc->dev, "%s: called while PDSC_S_STOPPING_DRIVER\n", ++ /* Don't process AdminQ when it's not up */ ++ if (!pdsc_adminq_inc_if_up(pdsc)) { ++ dev_err(pdsc->dev, "%s: called while adminq is unavailable\n", + __func__); + return; + } +@@ -124,6 +133,7 @@ credits: + pds_core_intr_credits(&pdsc->intr_ctrl[qcq->intx], + credits, + PDS_CORE_INTR_CRED_REARM); ++ refcount_dec(&pdsc->adminq_refcnt); + } + + void pdsc_work_thread(struct work_struct *work) +@@ -135,18 +145,20 @@ void pdsc_work_thread(struct work_struct *work) + + irqreturn_t pdsc_adminq_isr(int irq, void *data) + { +- struct pdsc_qcq *qcq = data; +- struct pdsc *pdsc = qcq->pdsc; ++ struct pdsc *pdsc = data; ++ struct pdsc_qcq *qcq; + +- /* Don't process AdminQ when shutting down */ +- if (pdsc->state & BIT_ULL(PDSC_S_STOPPING_DRIVER)) { +- dev_err(pdsc->dev, "%s: called while PDSC_S_STOPPING_DRIVER\n", ++ /* Don't process AdminQ when it's not up */ ++ if (!pdsc_adminq_inc_if_up(pdsc)) { ++ dev_err(pdsc->dev, "%s: called while adminq is unavailable\n", + __func__); + return IRQ_HANDLED; + } + ++ qcq = &pdsc->adminqcq; + queue_work(pdsc->wq, &qcq->work); + pds_core_intr_mask(&pdsc->intr_ctrl[qcq->intx], PDS_CORE_INTR_MASK_CLEAR); ++ refcount_dec(&pdsc->adminq_refcnt); + + return IRQ_HANDLED; + } +@@ -179,10 +191,16 @@ static int __pdsc_adminq_post(struct pdsc *pdsc, + + /* Check that the FW is running */ + if (!pdsc_is_fw_running(pdsc)) { +- u8 fw_status = ioread8(&pdsc->info_regs->fw_status); +- +- dev_info(pdsc->dev, "%s: post failed - fw not running %#02x:\n", +- __func__, fw_status); ++ if (pdsc->info_regs) { ++ u8 fw_status = ++ ioread8(&pdsc->info_regs->fw_status); ++ ++ dev_info(pdsc->dev, "%s: post failed - fw not running %#02x:\n", ++ __func__, fw_status); ++ } else { ++ dev_info(pdsc->dev, "%s: post failed - BARs not setup\n", ++ __func__); ++ } + ret = -ENXIO; + + goto err_out_unlock; +@@ -230,6 +248,12 @@ int pdsc_adminq_post(struct pdsc *pdsc, + int err = 0; + int index; + ++ if (!pdsc_adminq_inc_if_up(pdsc)) { ++ dev_dbg(pdsc->dev, "%s: preventing adminq cmd %u\n", ++ __func__, cmd->opcode); ++ return -ENXIO; ++ } ++ + wc.qcq = &pdsc->adminqcq; + index = __pdsc_adminq_post(pdsc, &pdsc->adminqcq, cmd, comp, &wc); + if (index < 0) { +@@ -248,10 +272,16 @@ int pdsc_adminq_post(struct pdsc *pdsc, + break; + + if (!pdsc_is_fw_running(pdsc)) { +- u8 fw_status = ioread8(&pdsc->info_regs->fw_status); +- +- dev_dbg(pdsc->dev, "%s: post wait failed - fw not running %#02x:\n", +- __func__, fw_status); ++ if (pdsc->info_regs) { ++ u8 fw_status = ++ ioread8(&pdsc->info_regs->fw_status); ++ ++ dev_dbg(pdsc->dev, "%s: post wait failed - fw not running %#02x:\n", ++ __func__, fw_status); ++ } else { ++ dev_dbg(pdsc->dev, "%s: post wait failed - BARs not setup\n", ++ __func__); ++ } + err = -ENXIO; + break; + } +@@ -285,6 +315,8 @@ err_out: + queue_work(pdsc->wq, &pdsc->health_work); + } + ++ refcount_dec(&pdsc->adminq_refcnt); ++ + return err; + } + EXPORT_SYMBOL_GPL(pdsc_adminq_post); +diff --git a/drivers/net/ethernet/amd/pds_core/core.c b/drivers/net/ethernet/amd/pds_core/core.c +index 0d2091e9eb283..7658a72867675 100644 +--- a/drivers/net/ethernet/amd/pds_core/core.c ++++ b/drivers/net/ethernet/amd/pds_core/core.c +@@ -125,7 +125,7 @@ static int pdsc_qcq_intr_alloc(struct pdsc *pdsc, struct pdsc_qcq *qcq) + + snprintf(name, sizeof(name), "%s-%d-%s", + PDS_CORE_DRV_NAME, pdsc->pdev->bus->number, qcq->q.name); +- index = pdsc_intr_alloc(pdsc, name, pdsc_adminq_isr, qcq); ++ index = pdsc_intr_alloc(pdsc, name, pdsc_adminq_isr, pdsc); + if (index < 0) + return index; + qcq->intx = index; +@@ -404,10 +404,7 @@ int pdsc_setup(struct pdsc *pdsc, bool init) + int numdescs; + int err; + +- if (init) +- err = pdsc_dev_init(pdsc); +- else +- err = pdsc_dev_reinit(pdsc); ++ err = pdsc_dev_init(pdsc); + if (err) + return err; + +@@ -450,6 +447,7 @@ int pdsc_setup(struct pdsc *pdsc, bool init) + pdsc_debugfs_add_viftype(pdsc); + } + ++ refcount_set(&pdsc->adminq_refcnt, 1); + clear_bit(PDSC_S_FW_DEAD, &pdsc->state); + return 0; + +@@ -464,6 +462,8 @@ void pdsc_teardown(struct pdsc *pdsc, bool removing) + + if (!pdsc->pdev->is_virtfn) + pdsc_devcmd_reset(pdsc); ++ if (pdsc->adminqcq.work.func) ++ cancel_work_sync(&pdsc->adminqcq.work); + pdsc_qcq_free(pdsc, &pdsc->notifyqcq); + pdsc_qcq_free(pdsc, &pdsc->adminqcq); + +@@ -476,10 +476,9 @@ void pdsc_teardown(struct pdsc *pdsc, bool removing) + for (i = 0; i < pdsc->nintrs; i++) + pdsc_intr_free(pdsc, i); + +- if (removing) { +- kfree(pdsc->intr_info); +- pdsc->intr_info = NULL; +- } ++ kfree(pdsc->intr_info); ++ pdsc->intr_info = NULL; ++ pdsc->nintrs = 0; + } + + if (pdsc->kern_dbpage) { +@@ -487,6 +486,7 @@ void pdsc_teardown(struct pdsc *pdsc, bool removing) + pdsc->kern_dbpage = NULL; + } + ++ pci_free_irq_vectors(pdsc->pdev); + set_bit(PDSC_S_FW_DEAD, &pdsc->state); + } + +@@ -512,6 +512,24 @@ void pdsc_stop(struct pdsc *pdsc) + PDS_CORE_INTR_MASK_SET); + } + ++static void pdsc_adminq_wait_and_dec_once_unused(struct pdsc *pdsc) ++{ ++ /* The driver initializes the adminq_refcnt to 1 when the adminq is ++ * allocated and ready for use. Other users/requesters will increment ++ * the refcnt while in use. If the refcnt is down to 1 then the adminq ++ * is not in use and the refcnt can be cleared and adminq freed. Before ++ * calling this function the driver will set PDSC_S_FW_DEAD, which ++ * prevent subsequent attempts to use the adminq and increment the ++ * refcnt to fail. This guarantees that this function will eventually ++ * exit. ++ */ ++ while (!refcount_dec_if_one(&pdsc->adminq_refcnt)) { ++ dev_dbg_ratelimited(pdsc->dev, "%s: adminq in use\n", ++ __func__); ++ cpu_relax(); ++ } ++} ++ + void pdsc_fw_down(struct pdsc *pdsc) + { + union pds_core_notifyq_comp reset_event = { +@@ -527,6 +545,8 @@ void pdsc_fw_down(struct pdsc *pdsc) + if (pdsc->pdev->is_virtfn) + return; + ++ pdsc_adminq_wait_and_dec_once_unused(pdsc); ++ + /* Notify clients of fw_down */ + if (pdsc->fw_reporter) + devlink_health_report(pdsc->fw_reporter, "FW down reported", pdsc); +@@ -577,7 +597,13 @@ err_out: + + static void pdsc_check_pci_health(struct pdsc *pdsc) + { +- u8 fw_status = ioread8(&pdsc->info_regs->fw_status); ++ u8 fw_status; ++ ++ /* some sort of teardown already in progress */ ++ if (!pdsc->info_regs) ++ return; ++ ++ fw_status = ioread8(&pdsc->info_regs->fw_status); + + /* is PCI broken? */ + if (fw_status != PDS_RC_BAD_PCI) +diff --git a/drivers/net/ethernet/amd/pds_core/core.h b/drivers/net/ethernet/amd/pds_core/core.h +index e35d3e7006bfc..110c4b826b22d 100644 +--- a/drivers/net/ethernet/amd/pds_core/core.h ++++ b/drivers/net/ethernet/amd/pds_core/core.h +@@ -184,6 +184,7 @@ struct pdsc { + struct mutex devcmd_lock; /* lock for dev_cmd operations */ + struct mutex config_lock; /* lock for configuration operations */ + spinlock_t adminq_lock; /* lock for adminq operations */ ++ refcount_t adminq_refcnt; + struct pds_core_dev_info_regs __iomem *info_regs; + struct pds_core_dev_cmd_regs __iomem *cmd_regs; + struct pds_core_intr __iomem *intr_ctrl; +@@ -280,7 +281,6 @@ int pdsc_devcmd_locked(struct pdsc *pdsc, union pds_core_dev_cmd *cmd, + union pds_core_dev_comp *comp, int max_seconds); + int pdsc_devcmd_init(struct pdsc *pdsc); + int pdsc_devcmd_reset(struct pdsc *pdsc); +-int pdsc_dev_reinit(struct pdsc *pdsc); + int pdsc_dev_init(struct pdsc *pdsc); + + void pdsc_reset_prepare(struct pci_dev *pdev); +diff --git a/drivers/net/ethernet/amd/pds_core/debugfs.c b/drivers/net/ethernet/amd/pds_core/debugfs.c +index 8ec392299b7dc..4e8579ca1c8c7 100644 +--- a/drivers/net/ethernet/amd/pds_core/debugfs.c ++++ b/drivers/net/ethernet/amd/pds_core/debugfs.c +@@ -64,6 +64,10 @@ DEFINE_SHOW_ATTRIBUTE(identity); + + void pdsc_debugfs_add_ident(struct pdsc *pdsc) + { ++ /* This file will already exist in the reset flow */ ++ if (debugfs_lookup("identity", pdsc->dentry)) ++ return; ++ + debugfs_create_file("identity", 0400, pdsc->dentry, + pdsc, &identity_fops); + } +diff --git a/drivers/net/ethernet/amd/pds_core/dev.c b/drivers/net/ethernet/amd/pds_core/dev.c +index 31940b857e0e5..e65a1632df505 100644 +--- a/drivers/net/ethernet/amd/pds_core/dev.c ++++ b/drivers/net/ethernet/amd/pds_core/dev.c +@@ -57,6 +57,9 @@ int pdsc_err_to_errno(enum pds_core_status_code code) + + bool pdsc_is_fw_running(struct pdsc *pdsc) + { ++ if (!pdsc->info_regs) ++ return false; ++ + pdsc->fw_status = ioread8(&pdsc->info_regs->fw_status); + pdsc->last_fw_time = jiffies; + pdsc->last_hb = ioread32(&pdsc->info_regs->fw_heartbeat); +@@ -182,13 +185,17 @@ int pdsc_devcmd_locked(struct pdsc *pdsc, union pds_core_dev_cmd *cmd, + { + int err; + ++ if (!pdsc->cmd_regs) ++ return -ENXIO; ++ + memcpy_toio(&pdsc->cmd_regs->cmd, cmd, sizeof(*cmd)); + pdsc_devcmd_dbell(pdsc); + err = pdsc_devcmd_wait(pdsc, cmd->opcode, max_seconds); +- memcpy_fromio(comp, &pdsc->cmd_regs->comp, sizeof(*comp)); + + if ((err == -ENXIO || err == -ETIMEDOUT) && pdsc->wq) + queue_work(pdsc->wq, &pdsc->health_work); ++ else ++ memcpy_fromio(comp, &pdsc->cmd_regs->comp, sizeof(*comp)); + + return err; + } +@@ -309,13 +316,6 @@ static int pdsc_identify(struct pdsc *pdsc) + return 0; + } + +-int pdsc_dev_reinit(struct pdsc *pdsc) +-{ +- pdsc_init_devinfo(pdsc); +- +- return pdsc_identify(pdsc); +-} +- + int pdsc_dev_init(struct pdsc *pdsc) + { + unsigned int nintrs; +diff --git a/drivers/net/ethernet/amd/pds_core/devlink.c b/drivers/net/ethernet/amd/pds_core/devlink.c +index e9948ea5bbcdb..54864f27c87a9 100644 +--- a/drivers/net/ethernet/amd/pds_core/devlink.c ++++ b/drivers/net/ethernet/amd/pds_core/devlink.c +@@ -111,7 +111,8 @@ int pdsc_dl_info_get(struct devlink *dl, struct devlink_info_req *req, + + mutex_lock(&pdsc->devcmd_lock); + err = pdsc_devcmd_locked(pdsc, &cmd, &comp, pdsc->devcmd_timeout * 2); +- memcpy_fromio(&fw_list, pdsc->cmd_regs->data, sizeof(fw_list)); ++ if (!err) ++ memcpy_fromio(&fw_list, pdsc->cmd_regs->data, sizeof(fw_list)); + mutex_unlock(&pdsc->devcmd_lock); + if (err && err != -EIO) + return err; +diff --git a/drivers/net/ethernet/amd/pds_core/fw.c b/drivers/net/ethernet/amd/pds_core/fw.c +index 90a811f3878ae..fa626719e68d1 100644 +--- a/drivers/net/ethernet/amd/pds_core/fw.c ++++ b/drivers/net/ethernet/amd/pds_core/fw.c +@@ -107,6 +107,9 @@ int pdsc_firmware_update(struct pdsc *pdsc, const struct firmware *fw, + + dev_info(pdsc->dev, "Installing firmware\n"); + ++ if (!pdsc->cmd_regs) ++ return -ENXIO; ++ + dl = priv_to_devlink(pdsc); + devlink_flash_update_status_notify(dl, "Preparing to flash", + NULL, 0, 0); +diff --git a/drivers/net/ethernet/amd/pds_core/main.c b/drivers/net/ethernet/amd/pds_core/main.c +index 3080898d7b95b..cdbf053b5376c 100644 +--- a/drivers/net/ethernet/amd/pds_core/main.c ++++ b/drivers/net/ethernet/amd/pds_core/main.c +@@ -37,6 +37,11 @@ static void pdsc_unmap_bars(struct pdsc *pdsc) + struct pdsc_dev_bar *bars = pdsc->bars; + unsigned int i; + ++ pdsc->info_regs = NULL; ++ pdsc->cmd_regs = NULL; ++ pdsc->intr_status = NULL; ++ pdsc->intr_ctrl = NULL; ++ + for (i = 0; i < PDS_CORE_BARS_MAX; i++) { + if (bars[i].vaddr) + pci_iounmap(pdsc->pdev, bars[i].vaddr); +@@ -293,7 +298,7 @@ err_out_stop: + err_out_teardown: + pdsc_teardown(pdsc, PDSC_TEARDOWN_REMOVING); + err_out_unmap_bars: +- del_timer_sync(&pdsc->wdtimer); ++ timer_shutdown_sync(&pdsc->wdtimer); + if (pdsc->wq) + destroy_workqueue(pdsc->wq); + mutex_destroy(&pdsc->config_lock); +@@ -420,7 +425,7 @@ static void pdsc_remove(struct pci_dev *pdev) + */ + pdsc_sriov_configure(pdev, 0); + +- del_timer_sync(&pdsc->wdtimer); ++ timer_shutdown_sync(&pdsc->wdtimer); + if (pdsc->wq) + destroy_workqueue(pdsc->wq); + +@@ -433,7 +438,6 @@ static void pdsc_remove(struct pci_dev *pdev) + mutex_destroy(&pdsc->config_lock); + mutex_destroy(&pdsc->devcmd_lock); + +- pci_free_irq_vectors(pdev); + pdsc_unmap_bars(pdsc); + pci_release_regions(pdev); + } +@@ -445,13 +449,26 @@ static void pdsc_remove(struct pci_dev *pdev) + devlink_free(dl); + } + ++static void pdsc_stop_health_thread(struct pdsc *pdsc) ++{ ++ timer_shutdown_sync(&pdsc->wdtimer); ++ if (pdsc->health_work.func) ++ cancel_work_sync(&pdsc->health_work); ++} ++ ++static void pdsc_restart_health_thread(struct pdsc *pdsc) ++{ ++ timer_setup(&pdsc->wdtimer, pdsc_wdtimer_cb, 0); ++ mod_timer(&pdsc->wdtimer, jiffies + 1); ++} ++ + void pdsc_reset_prepare(struct pci_dev *pdev) + { + struct pdsc *pdsc = pci_get_drvdata(pdev); + ++ pdsc_stop_health_thread(pdsc); + pdsc_fw_down(pdsc); + +- pci_free_irq_vectors(pdev); + pdsc_unmap_bars(pdsc); + pci_release_regions(pdev); + pci_disable_device(pdev); +@@ -486,6 +503,7 @@ void pdsc_reset_done(struct pci_dev *pdev) + } + + pdsc_fw_up(pdsc); ++ pdsc_restart_health_thread(pdsc); + } + + static const struct pci_error_handlers pdsc_err_handler = { +diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ptp.c b/drivers/net/ethernet/aquantia/atlantic/aq_ptp.c +index 28c9b6f1a54f1..abd4832e4ed21 100644 +--- a/drivers/net/ethernet/aquantia/atlantic/aq_ptp.c ++++ b/drivers/net/ethernet/aquantia/atlantic/aq_ptp.c +@@ -953,8 +953,6 @@ int aq_ptp_ring_alloc(struct aq_nic_s *aq_nic) + { + struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp; + unsigned int tx_ring_idx, rx_ring_idx; +- struct aq_ring_s *hwts; +- struct aq_ring_s *ring; + int err; + + if (!aq_ptp) +@@ -962,29 +960,23 @@ int aq_ptp_ring_alloc(struct aq_nic_s *aq_nic) + + tx_ring_idx = aq_ptp_ring_idx(aq_nic->aq_nic_cfg.tc_mode); + +- ring = aq_ring_tx_alloc(&aq_ptp->ptp_tx, aq_nic, +- tx_ring_idx, &aq_nic->aq_nic_cfg); +- if (!ring) { +- err = -ENOMEM; ++ err = aq_ring_tx_alloc(&aq_ptp->ptp_tx, aq_nic, ++ tx_ring_idx, &aq_nic->aq_nic_cfg); ++ if (err) + goto err_exit; +- } + + rx_ring_idx = aq_ptp_ring_idx(aq_nic->aq_nic_cfg.tc_mode); + +- ring = aq_ring_rx_alloc(&aq_ptp->ptp_rx, aq_nic, +- rx_ring_idx, &aq_nic->aq_nic_cfg); +- if (!ring) { +- err = -ENOMEM; ++ err = aq_ring_rx_alloc(&aq_ptp->ptp_rx, aq_nic, ++ rx_ring_idx, &aq_nic->aq_nic_cfg); ++ if (err) + goto err_exit_ptp_tx; +- } + +- hwts = aq_ring_hwts_rx_alloc(&aq_ptp->hwts_rx, aq_nic, PTP_HWST_RING_IDX, +- aq_nic->aq_nic_cfg.rxds, +- aq_nic->aq_nic_cfg.aq_hw_caps->rxd_size); +- if (!hwts) { +- err = -ENOMEM; ++ err = aq_ring_hwts_rx_alloc(&aq_ptp->hwts_rx, aq_nic, PTP_HWST_RING_IDX, ++ aq_nic->aq_nic_cfg.rxds, ++ aq_nic->aq_nic_cfg.aq_hw_caps->rxd_size); ++ if (err) + goto err_exit_ptp_rx; +- } + + err = aq_ptp_skb_ring_init(&aq_ptp->skb_ring, aq_nic->aq_nic_cfg.rxds); + if (err != 0) { +diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c +index e1885c1eb100a..cda8597b4e146 100644 +--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c ++++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c +@@ -132,8 +132,8 @@ static int aq_get_rxpages(struct aq_ring_s *self, struct aq_ring_buff_s *rxbuf) + return 0; + } + +-static struct aq_ring_s *aq_ring_alloc(struct aq_ring_s *self, +- struct aq_nic_s *aq_nic) ++static int aq_ring_alloc(struct aq_ring_s *self, ++ struct aq_nic_s *aq_nic) + { + int err = 0; + +@@ -156,46 +156,29 @@ static struct aq_ring_s *aq_ring_alloc(struct aq_ring_s *self, + err_exit: + if (err < 0) { + aq_ring_free(self); +- self = NULL; + } + +- return self; ++ return err; + } + +-struct aq_ring_s *aq_ring_tx_alloc(struct aq_ring_s *self, +- struct aq_nic_s *aq_nic, +- unsigned int idx, +- struct aq_nic_cfg_s *aq_nic_cfg) ++int aq_ring_tx_alloc(struct aq_ring_s *self, ++ struct aq_nic_s *aq_nic, ++ unsigned int idx, ++ struct aq_nic_cfg_s *aq_nic_cfg) + { +- int err = 0; +- + self->aq_nic = aq_nic; + self->idx = idx; + self->size = aq_nic_cfg->txds; + self->dx_size = aq_nic_cfg->aq_hw_caps->txd_size; + +- self = aq_ring_alloc(self, aq_nic); +- if (!self) { +- err = -ENOMEM; +- goto err_exit; +- } +- +-err_exit: +- if (err < 0) { +- aq_ring_free(self); +- self = NULL; +- } +- +- return self; ++ return aq_ring_alloc(self, aq_nic); + } + +-struct aq_ring_s *aq_ring_rx_alloc(struct aq_ring_s *self, +- struct aq_nic_s *aq_nic, +- unsigned int idx, +- struct aq_nic_cfg_s *aq_nic_cfg) ++int aq_ring_rx_alloc(struct aq_ring_s *self, ++ struct aq_nic_s *aq_nic, ++ unsigned int idx, ++ struct aq_nic_cfg_s *aq_nic_cfg) + { +- int err = 0; +- + self->aq_nic = aq_nic; + self->idx = idx; + self->size = aq_nic_cfg->rxds; +@@ -217,22 +200,10 @@ struct aq_ring_s *aq_ring_rx_alloc(struct aq_ring_s *self, + self->tail_size = 0; + } + +- self = aq_ring_alloc(self, aq_nic); +- if (!self) { +- err = -ENOMEM; +- goto err_exit; +- } +- +-err_exit: +- if (err < 0) { +- aq_ring_free(self); +- self = NULL; +- } +- +- return self; ++ return aq_ring_alloc(self, aq_nic); + } + +-struct aq_ring_s * ++int + aq_ring_hwts_rx_alloc(struct aq_ring_s *self, struct aq_nic_s *aq_nic, + unsigned int idx, unsigned int size, unsigned int dx_size) + { +@@ -250,10 +221,10 @@ aq_ring_hwts_rx_alloc(struct aq_ring_s *self, struct aq_nic_s *aq_nic, + GFP_KERNEL); + if (!self->dx_ring) { + aq_ring_free(self); +- return NULL; ++ return -ENOMEM; + } + +- return self; ++ return 0; + } + + int aq_ring_init(struct aq_ring_s *self, const enum atl_ring_type ring_type) +diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.h b/drivers/net/ethernet/aquantia/atlantic/aq_ring.h +index 0a6c34438c1d0..52847310740a2 100644 +--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.h ++++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.h +@@ -183,14 +183,14 @@ static inline unsigned int aq_ring_avail_dx(struct aq_ring_s *self) + self->sw_head - self->sw_tail - 1); + } + +-struct aq_ring_s *aq_ring_tx_alloc(struct aq_ring_s *self, +- struct aq_nic_s *aq_nic, +- unsigned int idx, +- struct aq_nic_cfg_s *aq_nic_cfg); +-struct aq_ring_s *aq_ring_rx_alloc(struct aq_ring_s *self, +- struct aq_nic_s *aq_nic, +- unsigned int idx, +- struct aq_nic_cfg_s *aq_nic_cfg); ++int aq_ring_tx_alloc(struct aq_ring_s *self, ++ struct aq_nic_s *aq_nic, ++ unsigned int idx, ++ struct aq_nic_cfg_s *aq_nic_cfg); ++int aq_ring_rx_alloc(struct aq_ring_s *self, ++ struct aq_nic_s *aq_nic, ++ unsigned int idx, ++ struct aq_nic_cfg_s *aq_nic_cfg); + + int aq_ring_init(struct aq_ring_s *self, const enum atl_ring_type ring_type); + void aq_ring_rx_deinit(struct aq_ring_s *self); +@@ -207,9 +207,9 @@ int aq_ring_rx_clean(struct aq_ring_s *self, + int budget); + int aq_ring_rx_fill(struct aq_ring_s *self); + +-struct aq_ring_s *aq_ring_hwts_rx_alloc(struct aq_ring_s *self, +- struct aq_nic_s *aq_nic, unsigned int idx, +- unsigned int size, unsigned int dx_size); ++int aq_ring_hwts_rx_alloc(struct aq_ring_s *self, ++ struct aq_nic_s *aq_nic, unsigned int idx, ++ unsigned int size, unsigned int dx_size); + void aq_ring_hwts_rx_clean(struct aq_ring_s *self, struct aq_nic_s *aq_nic); + + unsigned int aq_ring_fill_stats_data(struct aq_ring_s *self, u64 *data); +diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_vec.c b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c +index f5db1c44e9b91..9769ab4f9bef0 100644 +--- a/drivers/net/ethernet/aquantia/atlantic/aq_vec.c ++++ b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c +@@ -136,35 +136,32 @@ int aq_vec_ring_alloc(struct aq_vec_s *self, struct aq_nic_s *aq_nic, + const unsigned int idx_ring = AQ_NIC_CFG_TCVEC2RING(aq_nic_cfg, + i, idx); + +- ring = aq_ring_tx_alloc(&self->ring[i][AQ_VEC_TX_ID], aq_nic, +- idx_ring, aq_nic_cfg); +- if (!ring) { +- err = -ENOMEM; ++ ring = &self->ring[i][AQ_VEC_TX_ID]; ++ err = aq_ring_tx_alloc(ring, aq_nic, idx_ring, aq_nic_cfg); ++ if (err) + goto err_exit; +- } + + ++self->tx_rings; + + aq_nic_set_tx_ring(aq_nic, idx_ring, ring); + +- if (xdp_rxq_info_reg(&self->ring[i][AQ_VEC_RX_ID].xdp_rxq, ++ ring = &self->ring[i][AQ_VEC_RX_ID]; ++ if (xdp_rxq_info_reg(&ring->xdp_rxq, + aq_nic->ndev, idx, + self->napi.napi_id) < 0) { + err = -ENOMEM; + goto err_exit; + } +- if (xdp_rxq_info_reg_mem_model(&self->ring[i][AQ_VEC_RX_ID].xdp_rxq, ++ if (xdp_rxq_info_reg_mem_model(&ring->xdp_rxq, + MEM_TYPE_PAGE_SHARED, NULL) < 0) { +- xdp_rxq_info_unreg(&self->ring[i][AQ_VEC_RX_ID].xdp_rxq); ++ xdp_rxq_info_unreg(&ring->xdp_rxq); + err = -ENOMEM; + goto err_exit; + } + +- ring = aq_ring_rx_alloc(&self->ring[i][AQ_VEC_RX_ID], aq_nic, +- idx_ring, aq_nic_cfg); +- if (!ring) { +- xdp_rxq_info_unreg(&self->ring[i][AQ_VEC_RX_ID].xdp_rxq); +- err = -ENOMEM; ++ err = aq_ring_rx_alloc(ring, aq_nic, idx_ring, aq_nic_cfg); ++ if (err) { ++ xdp_rxq_info_unreg(&ring->xdp_rxq); + goto err_exit; + } + +diff --git a/drivers/net/ethernet/google/gve/gve_rx.c b/drivers/net/ethernet/google/gve/gve_rx.c +index 73655347902d2..93ff7c8ec9051 100644 +--- a/drivers/net/ethernet/google/gve/gve_rx.c ++++ b/drivers/net/ethernet/google/gve/gve_rx.c +@@ -362,7 +362,7 @@ static enum pkt_hash_types gve_rss_type(__be16 pkt_flags) + + static struct sk_buff *gve_rx_add_frags(struct napi_struct *napi, + struct gve_rx_slot_page_info *page_info, +- u16 packet_buffer_size, u16 len, ++ unsigned int truesize, u16 len, + struct gve_rx_ctx *ctx) + { + u32 offset = page_info->page_offset + page_info->pad; +@@ -395,10 +395,10 @@ static struct sk_buff *gve_rx_add_frags(struct napi_struct *napi, + if (skb != ctx->skb_head) { + ctx->skb_head->len += len; + ctx->skb_head->data_len += len; +- ctx->skb_head->truesize += packet_buffer_size; ++ ctx->skb_head->truesize += truesize; + } + skb_add_rx_frag(skb, num_frags, page_info->page, +- offset, len, packet_buffer_size); ++ offset, len, truesize); + + return ctx->skb_head; + } +@@ -492,7 +492,7 @@ static struct sk_buff *gve_rx_copy_to_pool(struct gve_rx_ring *rx, + + memcpy(alloc_page_info.page_address, src, page_info->pad + len); + skb = gve_rx_add_frags(napi, &alloc_page_info, +- rx->packet_buffer_size, ++ PAGE_SIZE, + len, ctx); + + u64_stats_update_begin(&rx->statss); +diff --git a/drivers/net/ethernet/intel/e1000/e1000_hw.c b/drivers/net/ethernet/intel/e1000/e1000_hw.c +index 4542e2bc28e8d..4576511c99f56 100644 +--- a/drivers/net/ethernet/intel/e1000/e1000_hw.c ++++ b/drivers/net/ethernet/intel/e1000/e1000_hw.c +@@ -5,6 +5,7 @@ + * Shared functions for accessing and configuring the MAC + */ + ++#include <linux/bitfield.h> + #include "e1000.h" + + static s32 e1000_check_downshift(struct e1000_hw *hw); +diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h +index a187582d22994..ba9c19e6994c9 100644 +--- a/drivers/net/ethernet/intel/e1000e/e1000.h ++++ b/drivers/net/ethernet/intel/e1000e/e1000.h +@@ -360,23 +360,43 @@ s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca); + * As a result, a shift of INCVALUE_SHIFT_n is used to fit a value of + * INCVALUE_n into the TIMINCA register allowing 32+8+(24-INCVALUE_SHIFT_n) + * bits to count nanoseconds leaving the rest for fractional nonseconds. ++ * ++ * Any given INCVALUE also has an associated maximum adjustment value. This ++ * maximum adjustment value is the largest increase (or decrease) which can be ++ * safely applied without overflowing the INCVALUE. Since INCVALUE has ++ * a maximum range of 24 bits, its largest value is 0xFFFFFF. ++ * ++ * To understand where the maximum value comes from, consider the following ++ * equation: ++ * ++ * new_incval = base_incval + (base_incval * adjustment) / 1billion ++ * ++ * To avoid overflow that means: ++ * max_incval = base_incval + (base_incval * max_adj) / billion ++ * ++ * Re-arranging: ++ * max_adj = floor(((max_incval - base_incval) * 1billion) / 1billion) + */ + #define INCVALUE_96MHZ 125 + #define INCVALUE_SHIFT_96MHZ 17 + #define INCPERIOD_SHIFT_96MHZ 2 + #define INCPERIOD_96MHZ (12 >> INCPERIOD_SHIFT_96MHZ) ++#define MAX_PPB_96MHZ 23999900 /* 23,999,900 ppb */ + + #define INCVALUE_25MHZ 40 + #define INCVALUE_SHIFT_25MHZ 18 + #define INCPERIOD_25MHZ 1 ++#define MAX_PPB_25MHZ 599999900 /* 599,999,900 ppb */ + + #define INCVALUE_24MHZ 125 + #define INCVALUE_SHIFT_24MHZ 14 + #define INCPERIOD_24MHZ 3 ++#define MAX_PPB_24MHZ 999999999 /* 999,999,999 ppb */ + + #define INCVALUE_38400KHZ 26 + #define INCVALUE_SHIFT_38400KHZ 19 + #define INCPERIOD_38400KHZ 1 ++#define MAX_PPB_38400KHZ 230769100 /* 230,769,100 ppb */ + + /* Another drawback of scaling the incvalue by a large factor is the + * 64-bit SYSTIM register overflows more quickly. This is dealt with +diff --git a/drivers/net/ethernet/intel/e1000e/ptp.c b/drivers/net/ethernet/intel/e1000e/ptp.c +index 02d871bc112a7..bbcfd529399b0 100644 +--- a/drivers/net/ethernet/intel/e1000e/ptp.c ++++ b/drivers/net/ethernet/intel/e1000e/ptp.c +@@ -280,8 +280,17 @@ void e1000e_ptp_init(struct e1000_adapter *adapter) + + switch (hw->mac.type) { + case e1000_pch2lan: ++ adapter->ptp_clock_info.max_adj = MAX_PPB_96MHZ; ++ break; + case e1000_pch_lpt: ++ if (er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_SYSCFI) ++ adapter->ptp_clock_info.max_adj = MAX_PPB_96MHZ; ++ else ++ adapter->ptp_clock_info.max_adj = MAX_PPB_25MHZ; ++ break; + case e1000_pch_spt: ++ adapter->ptp_clock_info.max_adj = MAX_PPB_24MHZ; ++ break; + case e1000_pch_cnp: + case e1000_pch_tgp: + case e1000_pch_adp: +@@ -289,15 +298,14 @@ void e1000e_ptp_init(struct e1000_adapter *adapter) + case e1000_pch_lnp: + case e1000_pch_ptp: + case e1000_pch_nvp: +- if ((hw->mac.type < e1000_pch_lpt) || +- (er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_SYSCFI)) { +- adapter->ptp_clock_info.max_adj = 24000000 - 1; +- break; +- } +- fallthrough; ++ if (er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_SYSCFI) ++ adapter->ptp_clock_info.max_adj = MAX_PPB_24MHZ; ++ else ++ adapter->ptp_clock_info.max_adj = MAX_PPB_38400KHZ; ++ break; + case e1000_82574: + case e1000_82583: +- adapter->ptp_clock_info.max_adj = 600000000 - 1; ++ adapter->ptp_clock_info.max_adj = MAX_PPB_25MHZ; + break; + default: + break; +diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_pf.c b/drivers/net/ethernet/intel/fm10k/fm10k_pf.c +index af1b0cde36703..ae700a1807c65 100644 +--- a/drivers/net/ethernet/intel/fm10k/fm10k_pf.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_pf.c +@@ -1,6 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0 + /* Copyright(c) 2013 - 2019 Intel Corporation. */ + ++#include <linux/bitfield.h> + #include "fm10k_pf.h" + #include "fm10k_vf.h" + +diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_vf.c b/drivers/net/ethernet/intel/fm10k/fm10k_vf.c +index dc8ccd378ec92..c50928ec14fff 100644 +--- a/drivers/net/ethernet/intel/fm10k/fm10k_vf.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_vf.c +@@ -1,6 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0 + /* Copyright(c) 2013 - 2019 Intel Corporation. */ + ++#include <linux/bitfield.h> + #include "fm10k_vf.h" + + /** +diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c +index d7e24d661724a..3eb6564c1cbce 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_common.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_common.c +@@ -2,6 +2,7 @@ + /* Copyright(c) 2013 - 2021 Intel Corporation. */ + + #include <linux/avf/virtchnl.h> ++#include <linux/bitfield.h> + #include <linux/delay.h> + #include <linux/etherdevice.h> + #include <linux/pci.h> +diff --git a/drivers/net/ethernet/intel/i40e/i40e_dcb.c b/drivers/net/ethernet/intel/i40e/i40e_dcb.c +index 68602fc375f62..d57dd30b024fa 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_dcb.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_dcb.c +@@ -1,6 +1,8 @@ + // SPDX-License-Identifier: GPL-2.0 + /* Copyright(c) 2013 - 2021 Intel Corporation. */ + ++#include <linux/bitfield.h> ++#include "i40e_adminq.h" + #include "i40e_alloc.h" + #include "i40e_dcb.h" + #include "i40e_prototype.h" +diff --git a/drivers/net/ethernet/intel/i40e/i40e_nvm.c b/drivers/net/ethernet/intel/i40e/i40e_nvm.c +index 77cdbfc19d477..e5aec09d58e27 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_nvm.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_nvm.c +@@ -1,6 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0 + /* Copyright(c) 2013 - 2018 Intel Corporation. */ + ++#include <linux/bitfield.h> + #include <linux/delay.h> + #include "i40e_alloc.h" + #include "i40e_prototype.h" +diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +index de5ec4e6bedfb..7db89b2945107 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +@@ -2607,6 +2607,14 @@ static int i40e_vc_enable_queues_msg(struct i40e_vf *vf, u8 *msg) + int aq_ret = 0; + int i; + ++ if (vf->is_disabled_from_host) { ++ aq_ret = -EPERM; ++ dev_info(&pf->pdev->dev, ++ "Admin has disabled VF %d, will not enable queues\n", ++ vf->vf_id); ++ goto error_param; ++ } ++ + if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { + aq_ret = -EINVAL; + goto error_param; +@@ -4734,9 +4742,12 @@ int i40e_ndo_set_vf_link_state(struct net_device *netdev, int vf_id, int link) + struct i40e_link_status *ls = &pf->hw.phy.link_info; + struct virtchnl_pf_event pfe; + struct i40e_hw *hw = &pf->hw; ++ struct i40e_vsi *vsi; ++ unsigned long q_map; + struct i40e_vf *vf; + int abs_vf_id; + int ret = 0; ++ int tmp; + + if (test_and_set_bit(__I40E_VIRTCHNL_OP_PENDING, pf->state)) { + dev_warn(&pf->pdev->dev, "Unable to configure VFs, other operation is pending.\n"); +@@ -4759,17 +4770,38 @@ int i40e_ndo_set_vf_link_state(struct net_device *netdev, int vf_id, int link) + switch (link) { + case IFLA_VF_LINK_STATE_AUTO: + vf->link_forced = false; ++ vf->is_disabled_from_host = false; ++ /* reset needed to reinit VF resources */ ++ i40e_vc_reset_vf(vf, true); + i40e_set_vf_link_state(vf, &pfe, ls); + break; + case IFLA_VF_LINK_STATE_ENABLE: + vf->link_forced = true; + vf->link_up = true; ++ vf->is_disabled_from_host = false; ++ /* reset needed to reinit VF resources */ ++ i40e_vc_reset_vf(vf, true); + i40e_set_vf_link_state(vf, &pfe, ls); + break; + case IFLA_VF_LINK_STATE_DISABLE: + vf->link_forced = true; + vf->link_up = false; + i40e_set_vf_link_state(vf, &pfe, ls); ++ ++ vsi = pf->vsi[vf->lan_vsi_idx]; ++ q_map = BIT(vsi->num_queue_pairs) - 1; ++ ++ vf->is_disabled_from_host = true; ++ ++ /* Try to stop both Tx&Rx rings even if one of the calls fails ++ * to ensure we stop the rings even in case of errors. ++ * If any of them returns with an error then the first ++ * error that occurred will be returned. ++ */ ++ tmp = i40e_ctrl_vf_tx_rings(vsi, q_map, false); ++ ret = i40e_ctrl_vf_rx_rings(vsi, q_map, false); ++ ++ ret = tmp ? tmp : ret; + break; + default: + ret = -EINVAL; +diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h +index 5fd607c0de0a6..66f95e2f3146a 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h ++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h +@@ -100,6 +100,7 @@ struct i40e_vf { + bool link_forced; + bool link_up; /* only valid if VF link is forced */ + bool spoofchk; ++ bool is_disabled_from_host; /* PF ctrl of VF enable/disable */ + u16 num_vlan; + + /* ADq related variables */ +diff --git a/drivers/net/ethernet/intel/iavf/iavf_common.c b/drivers/net/ethernet/intel/iavf/iavf_common.c +index 8091e6feca014..6a10c0ecf2b5f 100644 +--- a/drivers/net/ethernet/intel/iavf/iavf_common.c ++++ b/drivers/net/ethernet/intel/iavf/iavf_common.c +@@ -1,10 +1,11 @@ + // SPDX-License-Identifier: GPL-2.0 + /* Copyright(c) 2013 - 2018 Intel Corporation. */ + ++#include <linux/avf/virtchnl.h> ++#include <linux/bitfield.h> + #include "iavf_type.h" + #include "iavf_adminq.h" + #include "iavf_prototype.h" +-#include <linux/avf/virtchnl.h> + + /** + * iavf_aq_str - convert AQ err code to a string +diff --git a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c +index dc499fe7734ec..25ba5653ac6bf 100644 +--- a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c ++++ b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c +@@ -1,11 +1,12 @@ + // SPDX-License-Identifier: GPL-2.0 + /* Copyright(c) 2013 - 2018 Intel Corporation. */ + ++#include <linux/bitfield.h> ++#include <linux/uaccess.h> ++ + /* ethtool support for iavf */ + #include "iavf.h" + +-#include <linux/uaccess.h> +- + /* ethtool statistics helpers */ + + /** +diff --git a/drivers/net/ethernet/intel/iavf/iavf_fdir.c b/drivers/net/ethernet/intel/iavf/iavf_fdir.c +index 03e774bd2a5b4..65ddcd81c993e 100644 +--- a/drivers/net/ethernet/intel/iavf/iavf_fdir.c ++++ b/drivers/net/ethernet/intel/iavf/iavf_fdir.c +@@ -3,6 +3,7 @@ + + /* flow director ethtool support for iavf */ + ++#include <linux/bitfield.h> + #include "iavf.h" + + #define GTPU_PORT 2152 +diff --git a/drivers/net/ethernet/intel/iavf/iavf_txrx.c b/drivers/net/ethernet/intel/iavf/iavf_txrx.c +index d64c4997136b1..fb7edba9c2f8b 100644 +--- a/drivers/net/ethernet/intel/iavf/iavf_txrx.c ++++ b/drivers/net/ethernet/intel/iavf/iavf_txrx.c +@@ -1,6 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0 + /* Copyright(c) 2013 - 2018 Intel Corporation. */ + ++#include <linux/bitfield.h> + #include <linux/prefetch.h> + + #include "iavf.h" +diff --git a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h +index fbd5d92182d37..b8437c36ff382 100644 +--- a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h ++++ b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h +@@ -421,10 +421,10 @@ struct ice_aqc_vsi_props { + #define ICE_AQ_VSI_INNER_VLAN_INSERT_PVID BIT(2) + #define ICE_AQ_VSI_INNER_VLAN_EMODE_S 3 + #define ICE_AQ_VSI_INNER_VLAN_EMODE_M (0x3 << ICE_AQ_VSI_INNER_VLAN_EMODE_S) +-#define ICE_AQ_VSI_INNER_VLAN_EMODE_STR_BOTH (0x0 << ICE_AQ_VSI_INNER_VLAN_EMODE_S) +-#define ICE_AQ_VSI_INNER_VLAN_EMODE_STR_UP (0x1 << ICE_AQ_VSI_INNER_VLAN_EMODE_S) +-#define ICE_AQ_VSI_INNER_VLAN_EMODE_STR (0x2 << ICE_AQ_VSI_INNER_VLAN_EMODE_S) +-#define ICE_AQ_VSI_INNER_VLAN_EMODE_NOTHING (0x3 << ICE_AQ_VSI_INNER_VLAN_EMODE_S) ++#define ICE_AQ_VSI_INNER_VLAN_EMODE_STR_BOTH 0x0U ++#define ICE_AQ_VSI_INNER_VLAN_EMODE_STR_UP 0x1U ++#define ICE_AQ_VSI_INNER_VLAN_EMODE_STR 0x2U ++#define ICE_AQ_VSI_INNER_VLAN_EMODE_NOTHING 0x3U + u8 inner_vlan_reserved2[3]; + /* ingress egress up sections */ + __le32 ingress_table; /* bitmap, 3 bits per up */ +@@ -490,11 +490,11 @@ struct ice_aqc_vsi_props { + #define ICE_AQ_VSI_Q_OPT_RSS_GBL_LUT_S 2 + #define ICE_AQ_VSI_Q_OPT_RSS_GBL_LUT_M (0xF << ICE_AQ_VSI_Q_OPT_RSS_GBL_LUT_S) + #define ICE_AQ_VSI_Q_OPT_RSS_HASH_S 6 +-#define ICE_AQ_VSI_Q_OPT_RSS_HASH_M (0x3 << ICE_AQ_VSI_Q_OPT_RSS_HASH_S) +-#define ICE_AQ_VSI_Q_OPT_RSS_TPLZ (0x0 << ICE_AQ_VSI_Q_OPT_RSS_HASH_S) +-#define ICE_AQ_VSI_Q_OPT_RSS_SYM_TPLZ (0x1 << ICE_AQ_VSI_Q_OPT_RSS_HASH_S) +-#define ICE_AQ_VSI_Q_OPT_RSS_XOR (0x2 << ICE_AQ_VSI_Q_OPT_RSS_HASH_S) +-#define ICE_AQ_VSI_Q_OPT_RSS_JHASH (0x3 << ICE_AQ_VSI_Q_OPT_RSS_HASH_S) ++#define ICE_AQ_VSI_Q_OPT_RSS_HASH_M GENMASK(7, 6) ++#define ICE_AQ_VSI_Q_OPT_RSS_HASH_TPLZ 0x0U ++#define ICE_AQ_VSI_Q_OPT_RSS_HASH_SYM_TPLZ 0x1U ++#define ICE_AQ_VSI_Q_OPT_RSS_HASH_XOR 0x2U ++#define ICE_AQ_VSI_Q_OPT_RSS_HASH_JHASH 0x3U + u8 q_opt_tc; + #define ICE_AQ_VSI_Q_OPT_TC_OVR_S 0 + #define ICE_AQ_VSI_Q_OPT_TC_OVR_M (0x1F << ICE_AQ_VSI_Q_OPT_TC_OVR_S) +diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c +index 1bad6e17f9bef..c01950de44ced 100644 +--- a/drivers/net/ethernet/intel/ice/ice_lib.c ++++ b/drivers/net/ethernet/intel/ice/ice_lib.c +@@ -979,7 +979,8 @@ static void ice_set_dflt_vsi_ctx(struct ice_hw *hw, struct ice_vsi_ctx *ctxt) + */ + if (ice_is_dvm_ena(hw)) { + ctxt->info.inner_vlan_flags |= +- ICE_AQ_VSI_INNER_VLAN_EMODE_NOTHING; ++ FIELD_PREP(ICE_AQ_VSI_INNER_VLAN_EMODE_M, ++ ICE_AQ_VSI_INNER_VLAN_EMODE_NOTHING); + ctxt->info.outer_vlan_flags = + (ICE_AQ_VSI_OUTER_VLAN_TX_MODE_ALL << + ICE_AQ_VSI_OUTER_VLAN_TX_MODE_S) & +@@ -1186,12 +1187,12 @@ static void ice_set_rss_vsi_ctx(struct ice_vsi_ctx *ctxt, struct ice_vsi *vsi) + case ICE_VSI_PF: + /* PF VSI will inherit RSS instance of PF */ + lut_type = ICE_AQ_VSI_Q_OPT_RSS_LUT_PF; +- hash_type = ICE_AQ_VSI_Q_OPT_RSS_TPLZ; ++ hash_type = ICE_AQ_VSI_Q_OPT_RSS_HASH_TPLZ; + break; + case ICE_VSI_VF: + /* VF VSI will gets a small RSS table which is a VSI LUT type */ + lut_type = ICE_AQ_VSI_Q_OPT_RSS_LUT_VSI; +- hash_type = ICE_AQ_VSI_Q_OPT_RSS_TPLZ; ++ hash_type = ICE_AQ_VSI_Q_OPT_RSS_HASH_TPLZ; + break; + default: + dev_dbg(dev, "Unsupported VSI type %s\n", +diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl.c b/drivers/net/ethernet/intel/ice/ice_virtchnl.c +index 1c7b4ded948b6..8872f7a4f4320 100644 +--- a/drivers/net/ethernet/intel/ice/ice_virtchnl.c ++++ b/drivers/net/ethernet/intel/ice/ice_virtchnl.c +@@ -823,8 +823,8 @@ static int ice_vc_handle_rss_cfg(struct ice_vf *vf, u8 *msg, bool add) + int status; + + lut_type = ICE_AQ_VSI_Q_OPT_RSS_LUT_VSI; +- hash_type = add ? ICE_AQ_VSI_Q_OPT_RSS_XOR : +- ICE_AQ_VSI_Q_OPT_RSS_TPLZ; ++ hash_type = add ? ICE_AQ_VSI_Q_OPT_RSS_HASH_XOR : ++ ICE_AQ_VSI_Q_OPT_RSS_HASH_TPLZ; + + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + if (!ctx) { +@@ -832,11 +832,9 @@ static int ice_vc_handle_rss_cfg(struct ice_vf *vf, u8 *msg, bool add) + goto error_param; + } + +- ctx->info.q_opt_rss = ((lut_type << +- ICE_AQ_VSI_Q_OPT_RSS_LUT_S) & +- ICE_AQ_VSI_Q_OPT_RSS_LUT_M) | +- (hash_type & +- ICE_AQ_VSI_Q_OPT_RSS_HASH_M); ++ ctx->info.q_opt_rss = ++ FIELD_PREP(ICE_AQ_VSI_Q_OPT_RSS_LUT_M, lut_type) | ++ FIELD_PREP(ICE_AQ_VSI_Q_OPT_RSS_HASH_M, hash_type); + + /* Preserve existing queueing option setting */ + ctx->info.q_opt_rss |= (vsi->info.q_opt_rss & +diff --git a/drivers/net/ethernet/intel/ice/ice_vsi_vlan_lib.c b/drivers/net/ethernet/intel/ice/ice_vsi_vlan_lib.c +index 76266e709a392..8307902115ff2 100644 +--- a/drivers/net/ethernet/intel/ice/ice_vsi_vlan_lib.c ++++ b/drivers/net/ethernet/intel/ice/ice_vsi_vlan_lib.c +@@ -131,6 +131,7 @@ static int ice_vsi_manage_vlan_stripping(struct ice_vsi *vsi, bool ena) + { + struct ice_hw *hw = &vsi->back->hw; + struct ice_vsi_ctx *ctxt; ++ u8 *ivf; + int err; + + /* do not allow modifying VLAN stripping when a port VLAN is configured +@@ -143,19 +144,24 @@ static int ice_vsi_manage_vlan_stripping(struct ice_vsi *vsi, bool ena) + if (!ctxt) + return -ENOMEM; + ++ ivf = &ctxt->info.inner_vlan_flags; ++ + /* Here we are configuring what the VSI should do with the VLAN tag in + * the Rx packet. We can either leave the tag in the packet or put it in + * the Rx descriptor. + */ +- if (ena) ++ if (ena) { + /* Strip VLAN tag from Rx packet and put it in the desc */ +- ctxt->info.inner_vlan_flags = ICE_AQ_VSI_INNER_VLAN_EMODE_STR_BOTH; +- else ++ *ivf = FIELD_PREP(ICE_AQ_VSI_INNER_VLAN_EMODE_M, ++ ICE_AQ_VSI_INNER_VLAN_EMODE_STR_BOTH); ++ } else { + /* Disable stripping. Leave tag in packet */ +- ctxt->info.inner_vlan_flags = ICE_AQ_VSI_INNER_VLAN_EMODE_NOTHING; ++ *ivf = FIELD_PREP(ICE_AQ_VSI_INNER_VLAN_EMODE_M, ++ ICE_AQ_VSI_INNER_VLAN_EMODE_NOTHING); ++ } + + /* Allow all packets untagged/tagged */ +- ctxt->info.inner_vlan_flags |= ICE_AQ_VSI_INNER_VLAN_TX_MODE_ALL; ++ *ivf |= ICE_AQ_VSI_INNER_VLAN_TX_MODE_ALL; + + ctxt->info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_VLAN_VALID); + +diff --git a/drivers/net/ethernet/intel/idpf/virtchnl2.h b/drivers/net/ethernet/intel/idpf/virtchnl2.h +index 8dc837889723c..4a3c4454d25ab 100644 +--- a/drivers/net/ethernet/intel/idpf/virtchnl2.h ++++ b/drivers/net/ethernet/intel/idpf/virtchnl2.h +@@ -978,7 +978,7 @@ struct virtchnl2_ptype { + u8 proto_id_count; + __le16 pad; + __le16 proto_id[]; +-}; ++} __packed __aligned(2); + VIRTCHNL2_CHECK_STRUCT_LEN(6, virtchnl2_ptype); + + /** +diff --git a/drivers/net/ethernet/intel/igb/e1000_i210.c b/drivers/net/ethernet/intel/igb/e1000_i210.c +index b9b9d35494d27..53b396fd194a3 100644 +--- a/drivers/net/ethernet/intel/igb/e1000_i210.c ++++ b/drivers/net/ethernet/intel/igb/e1000_i210.c +@@ -5,9 +5,9 @@ + * e1000_i211 + */ + +-#include <linux/types.h> ++#include <linux/bitfield.h> + #include <linux/if_ether.h> +- ++#include <linux/types.h> + #include "e1000_hw.h" + #include "e1000_i210.h" + +diff --git a/drivers/net/ethernet/intel/igb/e1000_nvm.c b/drivers/net/ethernet/intel/igb/e1000_nvm.c +index fa136e6e93285..0da57e89593a0 100644 +--- a/drivers/net/ethernet/intel/igb/e1000_nvm.c ++++ b/drivers/net/ethernet/intel/igb/e1000_nvm.c +@@ -1,9 +1,9 @@ + // SPDX-License-Identifier: GPL-2.0 + /* Copyright(c) 2007 - 2018 Intel Corporation. */ + +-#include <linux/if_ether.h> ++#include <linux/bitfield.h> + #include <linux/delay.h> +- ++#include <linux/if_ether.h> + #include "e1000_mac.h" + #include "e1000_nvm.h" + +diff --git a/drivers/net/ethernet/intel/igb/e1000_phy.c b/drivers/net/ethernet/intel/igb/e1000_phy.c +index a018000f7db92..3c1b562a3271c 100644 +--- a/drivers/net/ethernet/intel/igb/e1000_phy.c ++++ b/drivers/net/ethernet/intel/igb/e1000_phy.c +@@ -1,9 +1,9 @@ + // SPDX-License-Identifier: GPL-2.0 + /* Copyright(c) 2007 - 2018 Intel Corporation. */ + +-#include <linux/if_ether.h> ++#include <linux/bitfield.h> + #include <linux/delay.h> +- ++#include <linux/if_ether.h> + #include "e1000_mac.h" + #include "e1000_phy.h" + +diff --git a/drivers/net/ethernet/intel/igbvf/netdev.c b/drivers/net/ethernet/intel/igbvf/netdev.c +index fd712585af27f..e6c1fbee049ef 100644 +--- a/drivers/net/ethernet/intel/igbvf/netdev.c ++++ b/drivers/net/ethernet/intel/igbvf/netdev.c +@@ -3,25 +3,25 @@ + + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +-#include <linux/module.h> +-#include <linux/types.h> +-#include <linux/init.h> +-#include <linux/pci.h> +-#include <linux/vmalloc.h> +-#include <linux/pagemap.h> ++#include <linux/bitfield.h> + #include <linux/delay.h> +-#include <linux/netdevice.h> +-#include <linux/tcp.h> +-#include <linux/ipv6.h> +-#include <linux/slab.h> +-#include <net/checksum.h> +-#include <net/ip6_checksum.h> +-#include <linux/mii.h> + #include <linux/ethtool.h> + #include <linux/if_vlan.h> ++#include <linux/init.h> ++#include <linux/ipv6.h> ++#include <linux/mii.h> ++#include <linux/module.h> ++#include <linux/netdevice.h> ++#include <linux/pagemap.h> ++#include <linux/pci.h> + #include <linux/prefetch.h> + #include <linux/sctp.h> +- ++#include <linux/slab.h> ++#include <linux/tcp.h> ++#include <linux/types.h> ++#include <linux/vmalloc.h> ++#include <net/checksum.h> ++#include <net/ip6_checksum.h> + #include "igbvf.h" + + char igbvf_driver_name[] = "igbvf"; +diff --git a/drivers/net/ethernet/intel/igc/igc_i225.c b/drivers/net/ethernet/intel/igc/igc_i225.c +index 17546a035ab19..d2562c8e8015e 100644 +--- a/drivers/net/ethernet/intel/igc/igc_i225.c ++++ b/drivers/net/ethernet/intel/igc/igc_i225.c +@@ -1,6 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0 + /* Copyright (c) 2018 Intel Corporation */ + ++#include <linux/bitfield.h> + #include <linux/delay.h> + + #include "igc_hw.h" +diff --git a/drivers/net/ethernet/intel/igc/igc_phy.c b/drivers/net/ethernet/intel/igc/igc_phy.c +index 53b77c969c857..d0d9e7170154c 100644 +--- a/drivers/net/ethernet/intel/igc/igc_phy.c ++++ b/drivers/net/ethernet/intel/igc/igc_phy.c +@@ -1,6 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0 + /* Copyright (c) 2018 Intel Corporation */ + ++#include <linux/bitfield.h> + #include "igc_phy.h" + + /** +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c +index 100388968e4db..3d56481e16bc9 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c +@@ -123,14 +123,14 @@ static s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw) + if (ret_val) + return ret_val; + if (hw->phy.sfp_type == ixgbe_sfp_type_unknown) +- return IXGBE_ERR_SFP_NOT_SUPPORTED; ++ return -EOPNOTSUPP; + + /* Check to see if SFP+ module is supported */ + ret_val = ixgbe_get_sfp_init_sequence_offsets(hw, + &list_offset, + &data_offset); + if (ret_val) +- return IXGBE_ERR_SFP_NOT_SUPPORTED; ++ return -EOPNOTSUPP; + break; + default: + break; +@@ -213,7 +213,7 @@ static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw, + break; + + default: +- return IXGBE_ERR_LINK_SETUP; ++ return -EIO; + } + + return 0; +@@ -283,7 +283,7 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw) + + /* Validate the water mark configuration */ + if (!hw->fc.pause_time) +- return IXGBE_ERR_INVALID_LINK_SETTINGS; ++ return -EINVAL; + + /* Low water mark of zero causes XOFF floods */ + for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { +@@ -292,7 +292,7 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw) + if (!hw->fc.low_water[i] || + hw->fc.low_water[i] >= hw->fc.high_water[i]) { + hw_dbg(hw, "Invalid water mark configuration\n"); +- return IXGBE_ERR_INVALID_LINK_SETTINGS; ++ return -EINVAL; + } + } + } +@@ -369,7 +369,7 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw) + break; + default: + hw_dbg(hw, "Flow control param set incorrectly\n"); +- return IXGBE_ERR_CONFIG; ++ return -EIO; + } + + /* Set 802.3x based flow control settings. */ +@@ -438,7 +438,7 @@ static s32 ixgbe_start_mac_link_82598(struct ixgbe_hw *hw, + msleep(100); + } + if (!(links_reg & IXGBE_LINKS_KX_AN_COMP)) { +- status = IXGBE_ERR_AUTONEG_NOT_COMPLETE; ++ status = -EIO; + hw_dbg(hw, "Autonegotiation did not complete.\n"); + } + } +@@ -478,7 +478,7 @@ static s32 ixgbe_validate_link_ready(struct ixgbe_hw *hw) + + if (timeout == IXGBE_VALIDATE_LINK_READY_TIMEOUT) { + hw_dbg(hw, "Link was indicated but link is down\n"); +- return IXGBE_ERR_LINK_SETUP; ++ return -EIO; + } + + return 0; +@@ -594,7 +594,7 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw, + speed &= link_capabilities; + + if (speed == IXGBE_LINK_SPEED_UNKNOWN) +- return IXGBE_ERR_LINK_SETUP; ++ return -EINVAL; + + /* Set KX4/KX support according to speed requested */ + else if (link_mode == IXGBE_AUTOC_LMS_KX4_AN || +@@ -701,9 +701,9 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw) + + /* Init PHY and function pointers, perform SFP setup */ + phy_status = hw->phy.ops.init(hw); +- if (phy_status == IXGBE_ERR_SFP_NOT_SUPPORTED) ++ if (phy_status == -EOPNOTSUPP) + return phy_status; +- if (phy_status == IXGBE_ERR_SFP_NOT_PRESENT) ++ if (phy_status == -ENOENT) + goto mac_reset_top; + + hw->phy.ops.reset(hw); +@@ -727,7 +727,7 @@ mac_reset_top: + udelay(1); + } + if (ctrl & IXGBE_CTRL_RST) { +- status = IXGBE_ERR_RESET_FAILED; ++ status = -EIO; + hw_dbg(hw, "Reset polling failed to complete.\n"); + } + +@@ -789,7 +789,7 @@ static s32 ixgbe_set_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq) + /* Make sure we are using a valid rar index range */ + if (rar >= rar_entries) { + hw_dbg(hw, "RAR index %d is out of range.\n", rar); +- return IXGBE_ERR_INVALID_ARGUMENT; ++ return -EINVAL; + } + + rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar)); +@@ -814,7 +814,7 @@ static s32 ixgbe_clear_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq) + /* Make sure we are using a valid rar index range */ + if (rar >= rar_entries) { + hw_dbg(hw, "RAR index %d is out of range.\n", rar); +- return IXGBE_ERR_INVALID_ARGUMENT; ++ return -EINVAL; + } + + rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar)); +@@ -845,7 +845,7 @@ static s32 ixgbe_set_vfta_82598(struct ixgbe_hw *hw, u32 vlan, u32 vind, + u32 vftabyte; + + if (vlan > 4095) +- return IXGBE_ERR_PARAM; ++ return -EINVAL; + + /* Determine 32-bit word position in array */ + regindex = (vlan >> 5) & 0x7F; /* upper seven bits */ +@@ -964,7 +964,7 @@ static s32 ixgbe_read_i2c_phy_82598(struct ixgbe_hw *hw, u8 dev_addr, + gssr = IXGBE_GSSR_PHY0_SM; + + if (hw->mac.ops.acquire_swfw_sync(hw, gssr) != 0) +- return IXGBE_ERR_SWFW_SYNC; ++ return -EBUSY; + + if (hw->phy.type == ixgbe_phy_nl) { + /* +@@ -993,7 +993,7 @@ static s32 ixgbe_read_i2c_phy_82598(struct ixgbe_hw *hw, u8 dev_addr, + + if (sfp_stat != IXGBE_I2C_EEPROM_STATUS_PASS) { + hw_dbg(hw, "EEPROM read did not pass.\n"); +- status = IXGBE_ERR_SFP_NOT_PRESENT; ++ status = -ENOENT; + goto out; + } + +@@ -1003,7 +1003,7 @@ static s32 ixgbe_read_i2c_phy_82598(struct ixgbe_hw *hw, u8 dev_addr, + + *eeprom_data = (u8)(sfp_data >> 8); + } else { +- status = IXGBE_ERR_PHY; ++ status = -EIO; + } + + out: +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c +index 58ea959a44822..339e106a5732d 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c +@@ -117,7 +117,7 @@ static s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw) + ret_val = hw->mac.ops.acquire_swfw_sync(hw, + IXGBE_GSSR_MAC_CSR_SM); + if (ret_val) +- return IXGBE_ERR_SWFW_SYNC; ++ return -EBUSY; + + if (hw->eeprom.ops.read(hw, ++data_offset, &data_value)) + goto setup_sfp_err; +@@ -144,7 +144,7 @@ static s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw) + + if (ret_val) { + hw_dbg(hw, " sfp module setup not complete\n"); +- return IXGBE_ERR_SFP_SETUP_NOT_COMPLETE; ++ return -EIO; + } + } + +@@ -159,7 +159,7 @@ setup_sfp_err: + usleep_range(hw->eeprom.semaphore_delay * 1000, + hw->eeprom.semaphore_delay * 2000); + hw_err(hw, "eeprom read at offset %d failed\n", data_offset); +- return IXGBE_ERR_SFP_SETUP_NOT_COMPLETE; ++ return -EIO; + } + + /** +@@ -184,7 +184,7 @@ static s32 prot_autoc_read_82599(struct ixgbe_hw *hw, bool *locked, + ret_val = hw->mac.ops.acquire_swfw_sync(hw, + IXGBE_GSSR_MAC_CSR_SM); + if (ret_val) +- return IXGBE_ERR_SWFW_SYNC; ++ return -EBUSY; + + *locked = true; + } +@@ -219,7 +219,7 @@ static s32 prot_autoc_write_82599(struct ixgbe_hw *hw, u32 autoc, bool locked) + ret_val = hw->mac.ops.acquire_swfw_sync(hw, + IXGBE_GSSR_MAC_CSR_SM); + if (ret_val) +- return IXGBE_ERR_SWFW_SYNC; ++ return -EBUSY; + + locked = true; + } +@@ -400,7 +400,7 @@ static s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw, + break; + + default: +- return IXGBE_ERR_LINK_SETUP; ++ return -EIO; + } + + if (hw->phy.multispeed_fiber) { +@@ -541,7 +541,7 @@ static s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw, + msleep(100); + } + if (!(links_reg & IXGBE_LINKS_KX_AN_COMP)) { +- status = IXGBE_ERR_AUTONEG_NOT_COMPLETE; ++ status = -EIO; + hw_dbg(hw, "Autoneg did not complete.\n"); + } + } +@@ -794,7 +794,7 @@ static s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw, + speed &= link_capabilities; + + if (speed == IXGBE_LINK_SPEED_UNKNOWN) +- return IXGBE_ERR_LINK_SETUP; ++ return -EINVAL; + + /* Use stored value (EEPROM defaults) of AUTOC to find KR/KX4 support*/ + if (hw->mac.orig_link_settings_stored) +@@ -861,8 +861,7 @@ static s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw, + msleep(100); + } + if (!(links_reg & IXGBE_LINKS_KX_AN_COMP)) { +- status = +- IXGBE_ERR_AUTONEG_NOT_COMPLETE; ++ status = -EIO; + hw_dbg(hw, "Autoneg did not complete.\n"); + } + } +@@ -927,7 +926,7 @@ static s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw) + /* Identify PHY and related function pointers */ + status = hw->phy.ops.init(hw); + +- if (status == IXGBE_ERR_SFP_NOT_SUPPORTED) ++ if (status == -EOPNOTSUPP) + return status; + + /* Setup SFP module if there is one present. */ +@@ -936,7 +935,7 @@ static s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw) + hw->phy.sfp_setup_needed = false; + } + +- if (status == IXGBE_ERR_SFP_NOT_SUPPORTED) ++ if (status == -EOPNOTSUPP) + return status; + + /* Reset PHY */ +@@ -974,7 +973,7 @@ mac_reset_top: + } + + if (ctrl & IXGBE_CTRL_RST_MASK) { +- status = IXGBE_ERR_RESET_FAILED; ++ status = -EIO; + hw_dbg(hw, "Reset polling failed to complete.\n"); + } + +@@ -1093,7 +1092,7 @@ static s32 ixgbe_fdir_check_cmd_complete(struct ixgbe_hw *hw, u32 *fdircmd) + udelay(10); + } + +- return IXGBE_ERR_FDIR_CMD_INCOMPLETE; ++ return -EIO; + } + + /** +@@ -1155,7 +1154,7 @@ s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw) + } + if (i >= IXGBE_FDIR_INIT_DONE_POLL) { + hw_dbg(hw, "Flow Director Signature poll time exceeded!\n"); +- return IXGBE_ERR_FDIR_REINIT_FAILED; ++ return -EIO; + } + + /* Clear FDIR statistics registers (read to clear) */ +@@ -1387,7 +1386,7 @@ s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw, + break; + default: + hw_dbg(hw, " Error on flow type input\n"); +- return IXGBE_ERR_CONFIG; ++ return -EIO; + } + + /* configure FDIRCMD register */ +@@ -1546,7 +1545,7 @@ s32 ixgbe_fdir_set_input_mask_82599(struct ixgbe_hw *hw, + break; + default: + hw_dbg(hw, " Error on vm pool mask\n"); +- return IXGBE_ERR_CONFIG; ++ return -EIO; + } + + switch (input_mask->formatted.flow_type & IXGBE_ATR_L4TYPE_MASK) { +@@ -1555,14 +1554,14 @@ s32 ixgbe_fdir_set_input_mask_82599(struct ixgbe_hw *hw, + if (input_mask->formatted.dst_port || + input_mask->formatted.src_port) { + hw_dbg(hw, " Error on src/dst port mask\n"); +- return IXGBE_ERR_CONFIG; ++ return -EIO; + } + break; + case IXGBE_ATR_L4TYPE_MASK: + break; + default: + hw_dbg(hw, " Error on flow type mask\n"); +- return IXGBE_ERR_CONFIG; ++ return -EIO; + } + + switch (ntohs(input_mask->formatted.vlan_id) & 0xEFFF) { +@@ -1583,7 +1582,7 @@ s32 ixgbe_fdir_set_input_mask_82599(struct ixgbe_hw *hw, + break; + default: + hw_dbg(hw, " Error on VLAN mask\n"); +- return IXGBE_ERR_CONFIG; ++ return -EIO; + } + + switch ((__force u16)input_mask->formatted.flex_bytes & 0xFFFF) { +@@ -1595,7 +1594,7 @@ s32 ixgbe_fdir_set_input_mask_82599(struct ixgbe_hw *hw, + break; + default: + hw_dbg(hw, " Error on flexible byte mask\n"); +- return IXGBE_ERR_CONFIG; ++ return -EIO; + } + + /* Now mask VM pool and destination IPv6 - bits 5 and 2 */ +@@ -1824,7 +1823,7 @@ static s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw) + + /* Return error if SFP module has been detected but is not supported */ + if (hw->phy.type == ixgbe_phy_sfp_unsupported) +- return IXGBE_ERR_SFP_NOT_SUPPORTED; ++ return -EOPNOTSUPP; + + return status; + } +@@ -1863,13 +1862,13 @@ static s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval) + * Verifies that installed the firmware version is 0.6 or higher + * for SFI devices. All 82599 SFI devices should have version 0.6 or higher. + * +- * Returns IXGBE_ERR_EEPROM_VERSION if the FW is not present or +- * if the FW version is not supported. ++ * Return: -EACCES if the FW is not present or if the FW version is ++ * not supported. + **/ + static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw) + { +- s32 status = IXGBE_ERR_EEPROM_VERSION; + u16 fw_offset, fw_ptp_cfg_offset; ++ s32 status = -EACCES; + u16 offset; + u16 fw_version = 0; + +@@ -1883,7 +1882,7 @@ static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw) + goto fw_version_err; + + if (fw_offset == 0 || fw_offset == 0xFFFF) +- return IXGBE_ERR_EEPROM_VERSION; ++ return -EACCES; + + /* get the offset to the Pass Through Patch Configuration block */ + offset = fw_offset + IXGBE_FW_PASSTHROUGH_PATCH_CONFIG_PTR; +@@ -1891,7 +1890,7 @@ static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw) + goto fw_version_err; + + if (fw_ptp_cfg_offset == 0 || fw_ptp_cfg_offset == 0xFFFF) +- return IXGBE_ERR_EEPROM_VERSION; ++ return -EACCES; + + /* get the firmware version */ + offset = fw_ptp_cfg_offset + IXGBE_FW_PATCH_VERSION_4; +@@ -1905,7 +1904,7 @@ static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw) + + fw_version_err: + hw_err(hw, "eeprom read at offset %d failed\n", offset); +- return IXGBE_ERR_EEPROM_VERSION; ++ return -EACCES; + } + + /** +@@ -2038,7 +2037,7 @@ static s32 ixgbe_reset_pipeline_82599(struct ixgbe_hw *hw) + + if (!(anlp1_reg & IXGBE_ANLP1_AN_STATE_MASK)) { + hw_dbg(hw, "auto negotiation not completed\n"); +- ret_val = IXGBE_ERR_RESET_FAILED; ++ ret_val = -EIO; + goto reset_pipeline_out; + } + +@@ -2087,7 +2086,7 @@ static s32 ixgbe_read_i2c_byte_82599(struct ixgbe_hw *hw, u8 byte_offset, + + if (!timeout) { + hw_dbg(hw, "Driver can't access resource, acquiring I2C bus timeout.\n"); +- status = IXGBE_ERR_I2C; ++ status = -EIO; + goto release_i2c_access; + } + } +@@ -2141,7 +2140,7 @@ static s32 ixgbe_write_i2c_byte_82599(struct ixgbe_hw *hw, u8 byte_offset, + + if (!timeout) { + hw_dbg(hw, "Driver can't access resource, acquiring I2C bus timeout.\n"); +- status = IXGBE_ERR_I2C; ++ status = -EIO; + goto release_i2c_access; + } + } +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c +index 878dd8dff5285..b2a0f2aaa05be 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c +@@ -124,7 +124,7 @@ s32 ixgbe_setup_fc_generic(struct ixgbe_hw *hw) + */ + if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) { + hw_dbg(hw, "ixgbe_fc_rx_pause not valid in strict IEEE mode\n"); +- return IXGBE_ERR_INVALID_LINK_SETTINGS; ++ return -EINVAL; + } + + /* +@@ -215,7 +215,7 @@ s32 ixgbe_setup_fc_generic(struct ixgbe_hw *hw) + break; + default: + hw_dbg(hw, "Flow control param set incorrectly\n"); +- return IXGBE_ERR_CONFIG; ++ return -EIO; + } + + if (hw->mac.type != ixgbe_mac_X540) { +@@ -500,7 +500,7 @@ s32 ixgbe_read_pba_string_generic(struct ixgbe_hw *hw, u8 *pba_num, + + if (pba_num == NULL) { + hw_dbg(hw, "PBA string buffer was null\n"); +- return IXGBE_ERR_INVALID_ARGUMENT; ++ return -EINVAL; + } + + ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM0_PTR, &data); +@@ -526,7 +526,7 @@ s32 ixgbe_read_pba_string_generic(struct ixgbe_hw *hw, u8 *pba_num, + /* we will need 11 characters to store the PBA */ + if (pba_num_size < 11) { + hw_dbg(hw, "PBA string buffer too small\n"); +- return IXGBE_ERR_NO_SPACE; ++ return -ENOSPC; + } + + /* extract hex string from data and pba_ptr */ +@@ -563,13 +563,13 @@ s32 ixgbe_read_pba_string_generic(struct ixgbe_hw *hw, u8 *pba_num, + + if (length == 0xFFFF || length == 0) { + hw_dbg(hw, "NVM PBA number section invalid length\n"); +- return IXGBE_ERR_PBA_SECTION; ++ return -EIO; + } + + /* check if pba_num buffer is big enough */ + if (pba_num_size < (((u32)length * 2) - 1)) { + hw_dbg(hw, "PBA string buffer too small\n"); +- return IXGBE_ERR_NO_SPACE; ++ return -ENOSPC; + } + + /* trim pba length from start of string */ +@@ -805,7 +805,7 @@ s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index) + u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); + + if (index > 3) +- return IXGBE_ERR_PARAM; ++ return -EINVAL; + + /* To turn on the LED, set mode to ON. */ + led_reg &= ~IXGBE_LED_MODE_MASK(index); +@@ -826,7 +826,7 @@ s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index) + u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); + + if (index > 3) +- return IXGBE_ERR_PARAM; ++ return -EINVAL; + + /* To turn off the LED, set mode to OFF. */ + led_reg &= ~IXGBE_LED_MODE_MASK(index); +@@ -904,11 +904,8 @@ s32 ixgbe_write_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset, + + hw->eeprom.ops.init_params(hw); + +- if (words == 0) +- return IXGBE_ERR_INVALID_ARGUMENT; +- +- if (offset + words > hw->eeprom.word_size) +- return IXGBE_ERR_EEPROM; ++ if (words == 0 || (offset + words > hw->eeprom.word_size)) ++ return -EINVAL; + + /* + * The EEPROM page size cannot be queried from the chip. We do lazy +@@ -962,7 +959,7 @@ static s32 ixgbe_write_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset, + + if (ixgbe_ready_eeprom(hw) != 0) { + ixgbe_release_eeprom(hw); +- return IXGBE_ERR_EEPROM; ++ return -EIO; + } + + for (i = 0; i < words; i++) { +@@ -1028,7 +1025,7 @@ s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data) + hw->eeprom.ops.init_params(hw); + + if (offset >= hw->eeprom.word_size) +- return IXGBE_ERR_EEPROM; ++ return -EINVAL; + + return ixgbe_write_eeprom_buffer_bit_bang(hw, offset, 1, &data); + } +@@ -1050,11 +1047,8 @@ s32 ixgbe_read_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset, + + hw->eeprom.ops.init_params(hw); + +- if (words == 0) +- return IXGBE_ERR_INVALID_ARGUMENT; +- +- if (offset + words > hw->eeprom.word_size) +- return IXGBE_ERR_EEPROM; ++ if (words == 0 || (offset + words > hw->eeprom.word_size)) ++ return -EINVAL; + + /* + * We cannot hold synchronization semaphores for too long +@@ -1099,7 +1093,7 @@ static s32 ixgbe_read_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset, + + if (ixgbe_ready_eeprom(hw) != 0) { + ixgbe_release_eeprom(hw); +- return IXGBE_ERR_EEPROM; ++ return -EIO; + } + + for (i = 0; i < words; i++) { +@@ -1142,7 +1136,7 @@ s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset, + hw->eeprom.ops.init_params(hw); + + if (offset >= hw->eeprom.word_size) +- return IXGBE_ERR_EEPROM; ++ return -EINVAL; + + return ixgbe_read_eeprom_buffer_bit_bang(hw, offset, 1, data); + } +@@ -1165,11 +1159,8 @@ s32 ixgbe_read_eerd_buffer_generic(struct ixgbe_hw *hw, u16 offset, + + hw->eeprom.ops.init_params(hw); + +- if (words == 0) +- return IXGBE_ERR_INVALID_ARGUMENT; +- +- if (offset >= hw->eeprom.word_size) +- return IXGBE_ERR_EEPROM; ++ if (words == 0 || offset >= hw->eeprom.word_size) ++ return -EINVAL; + + for (i = 0; i < words; i++) { + eerd = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) | +@@ -1262,11 +1253,8 @@ s32 ixgbe_write_eewr_buffer_generic(struct ixgbe_hw *hw, u16 offset, + + hw->eeprom.ops.init_params(hw); + +- if (words == 0) +- return IXGBE_ERR_INVALID_ARGUMENT; +- +- if (offset >= hw->eeprom.word_size) +- return IXGBE_ERR_EEPROM; ++ if (words == 0 || offset >= hw->eeprom.word_size) ++ return -EINVAL; + + for (i = 0; i < words; i++) { + eewr = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) | +@@ -1328,7 +1316,7 @@ static s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg) + } + udelay(5); + } +- return IXGBE_ERR_EEPROM; ++ return -EIO; + } + + /** +@@ -1344,7 +1332,7 @@ static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw) + u32 i; + + if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) != 0) +- return IXGBE_ERR_SWFW_SYNC; ++ return -EBUSY; + + eec = IXGBE_READ_REG(hw, IXGBE_EEC(hw)); + +@@ -1366,7 +1354,7 @@ static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw) + hw_dbg(hw, "Could not acquire EEPROM grant\n"); + + hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); +- return IXGBE_ERR_EEPROM; ++ return -EIO; + } + + /* Setup EEPROM for Read/Write */ +@@ -1419,7 +1407,7 @@ static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw) + swsm = IXGBE_READ_REG(hw, IXGBE_SWSM(hw)); + if (swsm & IXGBE_SWSM_SMBI) { + hw_dbg(hw, "Software semaphore SMBI between device drivers not granted.\n"); +- return IXGBE_ERR_EEPROM; ++ return -EIO; + } + } + +@@ -1447,7 +1435,7 @@ static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw) + if (i >= timeout) { + hw_dbg(hw, "SWESMBI Software EEPROM semaphore not granted.\n"); + ixgbe_release_eeprom_semaphore(hw); +- return IXGBE_ERR_EEPROM; ++ return -EIO; + } + + return 0; +@@ -1503,7 +1491,7 @@ static s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw) + */ + if (i >= IXGBE_EEPROM_MAX_RETRY_SPI) { + hw_dbg(hw, "SPI EEPROM Status error\n"); +- return IXGBE_ERR_EEPROM; ++ return -EIO; + } + + return 0; +@@ -1715,7 +1703,7 @@ s32 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw) + for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) { + if (hw->eeprom.ops.read(hw, i, &pointer)) { + hw_dbg(hw, "EEPROM read failed\n"); +- return IXGBE_ERR_EEPROM; ++ return -EIO; + } + + /* If the pointer seems invalid */ +@@ -1724,7 +1712,7 @@ s32 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw) + + if (hw->eeprom.ops.read(hw, pointer, &length)) { + hw_dbg(hw, "EEPROM read failed\n"); +- return IXGBE_ERR_EEPROM; ++ return -EIO; + } + + if (length == 0xFFFF || length == 0) +@@ -1733,7 +1721,7 @@ s32 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw) + for (j = pointer + 1; j <= pointer + length; j++) { + if (hw->eeprom.ops.read(hw, j, &word)) { + hw_dbg(hw, "EEPROM read failed\n"); +- return IXGBE_ERR_EEPROM; ++ return -EIO; + } + checksum += word; + } +@@ -1786,7 +1774,7 @@ s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw, + * calculated checksum + */ + if (read_checksum != checksum) +- status = IXGBE_ERR_EEPROM_CHECKSUM; ++ status = -EIO; + + /* If the user cares, return the calculated checksum */ + if (checksum_val) +@@ -1845,7 +1833,7 @@ s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq, + /* Make sure we are using a valid rar index range */ + if (index >= rar_entries) { + hw_dbg(hw, "RAR index %d is out of range.\n", index); +- return IXGBE_ERR_INVALID_ARGUMENT; ++ return -EINVAL; + } + + /* setup VMDq pool selection before this RAR gets enabled */ +@@ -1897,7 +1885,7 @@ s32 ixgbe_clear_rar_generic(struct ixgbe_hw *hw, u32 index) + /* Make sure we are using a valid rar index range */ + if (index >= rar_entries) { + hw_dbg(hw, "RAR index %d is out of range.\n", index); +- return IXGBE_ERR_INVALID_ARGUMENT; ++ return -EINVAL; + } + + /* +@@ -2146,7 +2134,7 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw) + + /* Validate the water mark configuration. */ + if (!hw->fc.pause_time) +- return IXGBE_ERR_INVALID_LINK_SETTINGS; ++ return -EINVAL; + + /* Low water mark of zero causes XOFF floods */ + for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { +@@ -2155,7 +2143,7 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw) + if (!hw->fc.low_water[i] || + hw->fc.low_water[i] >= hw->fc.high_water[i]) { + hw_dbg(hw, "Invalid water mark configuration\n"); +- return IXGBE_ERR_INVALID_LINK_SETTINGS; ++ return -EINVAL; + } + } + } +@@ -2212,7 +2200,7 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw) + break; + default: + hw_dbg(hw, "Flow control param set incorrectly\n"); +- return IXGBE_ERR_CONFIG; ++ return -EIO; + } + + /* Set 802.3x based flow control settings. */ +@@ -2269,7 +2257,7 @@ s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg, + u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm) + { + if ((!(adv_reg)) || (!(lp_reg))) +- return IXGBE_ERR_FC_NOT_NEGOTIATED; ++ return -EINVAL; + + if ((adv_reg & adv_sym) && (lp_reg & lp_sym)) { + /* +@@ -2321,7 +2309,7 @@ static s32 ixgbe_fc_autoneg_fiber(struct ixgbe_hw *hw) + linkstat = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA); + if ((!!(linkstat & IXGBE_PCS1GLSTA_AN_COMPLETE) == 0) || + (!!(linkstat & IXGBE_PCS1GLSTA_AN_TIMED_OUT) == 1)) +- return IXGBE_ERR_FC_NOT_NEGOTIATED; ++ return -EIO; + + pcs_anadv_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA); + pcs_lpab_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANLP); +@@ -2353,12 +2341,12 @@ static s32 ixgbe_fc_autoneg_backplane(struct ixgbe_hw *hw) + */ + links = IXGBE_READ_REG(hw, IXGBE_LINKS); + if ((links & IXGBE_LINKS_KX_AN_COMP) == 0) +- return IXGBE_ERR_FC_NOT_NEGOTIATED; ++ return -EIO; + + if (hw->mac.type == ixgbe_mac_82599EB) { + links2 = IXGBE_READ_REG(hw, IXGBE_LINKS2); + if ((links2 & IXGBE_LINKS2_AN_SUPPORTED) == 0) +- return IXGBE_ERR_FC_NOT_NEGOTIATED; ++ return -EIO; + } + /* + * Read the 10g AN autoc and LP ability registers and resolve +@@ -2407,8 +2395,8 @@ static s32 ixgbe_fc_autoneg_copper(struct ixgbe_hw *hw) + **/ + void ixgbe_fc_autoneg(struct ixgbe_hw *hw) + { +- s32 ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED; + ixgbe_link_speed speed; ++ s32 ret_val = -EIO; + bool link_up; + + /* +@@ -2510,7 +2498,7 @@ static u32 ixgbe_pcie_timeout_poll(struct ixgbe_hw *hw) + * @hw: pointer to hardware structure + * + * Disables PCI-Express primary access and verifies there are no pending +- * requests. IXGBE_ERR_PRIMARY_REQUESTS_PENDING is returned if primary disable ++ * requests. -EALREADY is returned if primary disable + * bit hasn't caused the primary requests to be disabled, else 0 + * is returned signifying primary requests disabled. + **/ +@@ -2575,7 +2563,7 @@ gio_disable_fail: + } + + hw_dbg(hw, "PCIe transaction pending bit also did not clear.\n"); +- return IXGBE_ERR_PRIMARY_REQUESTS_PENDING; ++ return -EALREADY; + } + + /** +@@ -2600,7 +2588,7 @@ s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u32 mask) + * SW_FW_SYNC bits (not just NVM) + */ + if (ixgbe_get_eeprom_semaphore(hw)) +- return IXGBE_ERR_SWFW_SYNC; ++ return -EBUSY; + + gssr = IXGBE_READ_REG(hw, IXGBE_GSSR); + if (!(gssr & (fwmask | swmask))) { +@@ -2620,7 +2608,7 @@ s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u32 mask) + ixgbe_release_swfw_sync(hw, gssr & (fwmask | swmask)); + + usleep_range(5000, 10000); +- return IXGBE_ERR_SWFW_SYNC; ++ return -EBUSY; + } + + /** +@@ -2757,7 +2745,7 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index) + s32 ret_val; + + if (index > 3) +- return IXGBE_ERR_PARAM; ++ return -EINVAL; + + /* + * Link must be up to auto-blink the LEDs; +@@ -2803,7 +2791,7 @@ s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index) + s32 ret_val; + + if (index > 3) +- return IXGBE_ERR_PARAM; ++ return -EINVAL; + + ret_val = hw->mac.ops.prot_autoc_read(hw, &locked, &autoc_reg); + if (ret_val) +@@ -2963,7 +2951,7 @@ s32 ixgbe_clear_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq) + /* Make sure we are using a valid rar index range */ + if (rar >= rar_entries) { + hw_dbg(hw, "RAR index %d is out of range.\n", rar); +- return IXGBE_ERR_INVALID_ARGUMENT; ++ return -EINVAL; + } + + mpsar_lo = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar)); +@@ -3014,7 +3002,7 @@ s32 ixgbe_set_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq) + /* Make sure we are using a valid rar index range */ + if (rar >= rar_entries) { + hw_dbg(hw, "RAR index %d is out of range.\n", rar); +- return IXGBE_ERR_INVALID_ARGUMENT; ++ return -EINVAL; + } + + if (vmdq < 32) { +@@ -3091,7 +3079,7 @@ static s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan, bool vlvf_bypass) + * will simply bypass the VLVF if there are no entries present in the + * VLVF that contain our VLAN + */ +- first_empty_slot = vlvf_bypass ? IXGBE_ERR_NO_SPACE : 0; ++ first_empty_slot = vlvf_bypass ? -ENOSPC : 0; + + /* add VLAN enable bit for comparison */ + vlan |= IXGBE_VLVF_VIEN; +@@ -3115,7 +3103,7 @@ static s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan, bool vlvf_bypass) + if (!first_empty_slot) + hw_dbg(hw, "No space in VLVF.\n"); + +- return first_empty_slot ? : IXGBE_ERR_NO_SPACE; ++ return first_empty_slot ? : -ENOSPC; + } + + /** +@@ -3135,7 +3123,7 @@ s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind, + s32 vlvf_index; + + if ((vlan > 4095) || (vind > 63)) +- return IXGBE_ERR_PARAM; ++ return -EINVAL; + + /* + * this is a 2 part operation - first the VFTA, then the +@@ -3611,7 +3599,8 @@ u8 ixgbe_calculate_checksum(u8 *buffer, u32 length) + * + * Communicates with the manageability block. On success return 0 + * else returns semaphore error when encountering an error acquiring +- * semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails. ++ * semaphore, -EINVAL when incorrect parameters passed or -EIO when ++ * command fails. + * + * This function assumes that the IXGBE_GSSR_SW_MNG_SM semaphore is held + * by the caller. +@@ -3624,7 +3613,7 @@ s32 ixgbe_hic_unlocked(struct ixgbe_hw *hw, u32 *buffer, u32 length, + + if (!length || length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) { + hw_dbg(hw, "Buffer length failure buffersize-%d.\n", length); +- return IXGBE_ERR_HOST_INTERFACE_COMMAND; ++ return -EINVAL; + } + + /* Set bit 9 of FWSTS clearing FW reset indication */ +@@ -3635,13 +3624,13 @@ s32 ixgbe_hic_unlocked(struct ixgbe_hw *hw, u32 *buffer, u32 length, + hicr = IXGBE_READ_REG(hw, IXGBE_HICR); + if (!(hicr & IXGBE_HICR_EN)) { + hw_dbg(hw, "IXGBE_HOST_EN bit disabled.\n"); +- return IXGBE_ERR_HOST_INTERFACE_COMMAND; ++ return -EIO; + } + + /* Calculate length in DWORDs. We must be DWORD aligned */ + if (length % sizeof(u32)) { + hw_dbg(hw, "Buffer length failure, not aligned to dword"); +- return IXGBE_ERR_INVALID_ARGUMENT; ++ return -EINVAL; + } + + dword_len = length >> 2; +@@ -3666,7 +3655,7 @@ s32 ixgbe_hic_unlocked(struct ixgbe_hw *hw, u32 *buffer, u32 length, + /* Check command successful completion. */ + if ((timeout && i == timeout) || + !(IXGBE_READ_REG(hw, IXGBE_HICR) & IXGBE_HICR_SV)) +- return IXGBE_ERR_HOST_INTERFACE_COMMAND; ++ return -EIO; + + return 0; + } +@@ -3686,7 +3675,7 @@ s32 ixgbe_hic_unlocked(struct ixgbe_hw *hw, u32 *buffer, u32 length, + * in these cases. + * + * Communicates with the manageability block. On success return 0 +- * else return IXGBE_ERR_HOST_INTERFACE_COMMAND. ++ * else return -EIO or -EINVAL. + **/ + s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, void *buffer, + u32 length, u32 timeout, +@@ -3701,7 +3690,7 @@ s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, void *buffer, + + if (!length || length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) { + hw_dbg(hw, "Buffer length failure buffersize-%d.\n", length); +- return IXGBE_ERR_HOST_INTERFACE_COMMAND; ++ return -EINVAL; + } + /* Take management host interface semaphore */ + status = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM); +@@ -3731,7 +3720,7 @@ s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, void *buffer, + + if (length < round_up(buf_len, 4) + hdr_size) { + hw_dbg(hw, "Buffer not large enough for reply message.\n"); +- status = IXGBE_ERR_HOST_INTERFACE_COMMAND; ++ status = -EIO; + goto rel_out; + } + +@@ -3762,8 +3751,8 @@ rel_out: + * + * Sends driver version number to firmware through the manageability + * block. On success return 0 +- * else returns IXGBE_ERR_SWFW_SYNC when encountering an error acquiring +- * semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails. ++ * else returns -EBUSY when encountering an error acquiring ++ * semaphore or -EIO when command fails. + **/ + s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min, + u8 build, u8 sub, __always_unused u16 len, +@@ -3799,7 +3788,7 @@ s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min, + FW_CEM_RESP_STATUS_SUCCESS) + ret_val = 0; + else +- ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND; ++ ret_val = -EIO; + + break; + } +@@ -3897,14 +3886,14 @@ static s32 ixgbe_get_ets_data(struct ixgbe_hw *hw, u16 *ets_cfg, + return status; + + if ((*ets_offset == 0x0000) || (*ets_offset == 0xFFFF)) +- return IXGBE_NOT_IMPLEMENTED; ++ return -EOPNOTSUPP; + + status = hw->eeprom.ops.read(hw, *ets_offset, ets_cfg); + if (status) + return status; + + if ((*ets_cfg & IXGBE_ETS_TYPE_MASK) != IXGBE_ETS_TYPE_EMC_SHIFTED) +- return IXGBE_NOT_IMPLEMENTED; ++ return -EOPNOTSUPP; + + return 0; + } +@@ -3927,7 +3916,7 @@ s32 ixgbe_get_thermal_sensor_data_generic(struct ixgbe_hw *hw) + + /* Only support thermal sensors attached to physical port 0 */ + if ((IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)) +- return IXGBE_NOT_IMPLEMENTED; ++ return -EOPNOTSUPP; + + status = ixgbe_get_ets_data(hw, &ets_cfg, &ets_offset); + if (status) +@@ -3987,7 +3976,7 @@ s32 ixgbe_init_thermal_sensor_thresh_generic(struct ixgbe_hw *hw) + + /* Only support thermal sensors attached to physical port 0 */ + if ((IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)) +- return IXGBE_NOT_IMPLEMENTED; ++ return -EOPNOTSUPP; + + status = ixgbe_get_ets_data(hw, &ets_cfg, &ets_offset); + if (status) +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +index 4dd897806fa5a..e47461f3eaef0 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +@@ -3370,7 +3370,7 @@ static int ixgbe_get_module_eeprom(struct net_device *dev, + { + struct ixgbe_adapter *adapter = netdev_priv(dev); + struct ixgbe_hw *hw = &adapter->hw; +- s32 status = IXGBE_ERR_PHY_ADDR_INVALID; ++ s32 status = -EFAULT; + u8 databyte = 0xFF; + int i = 0; + +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +index 94bde2cad0f47..6a3f633406c4b 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +@@ -2756,7 +2756,6 @@ static void ixgbe_check_overtemp_subtask(struct ixgbe_adapter *adapter) + { + struct ixgbe_hw *hw = &adapter->hw; + u32 eicr = adapter->interrupt_event; +- s32 rc; + + if (test_bit(__IXGBE_DOWN, &adapter->state)) + return; +@@ -2790,14 +2789,13 @@ static void ixgbe_check_overtemp_subtask(struct ixgbe_adapter *adapter) + } + + /* Check if this is not due to overtemp */ +- if (hw->phy.ops.check_overtemp(hw) != IXGBE_ERR_OVERTEMP) ++ if (!hw->phy.ops.check_overtemp(hw)) + return; + + break; + case IXGBE_DEV_ID_X550EM_A_1G_T: + case IXGBE_DEV_ID_X550EM_A_1G_T_L: +- rc = hw->phy.ops.check_overtemp(hw); +- if (rc != IXGBE_ERR_OVERTEMP) ++ if (!hw->phy.ops.check_overtemp(hw)) + return; + break; + default: +@@ -5512,7 +5510,7 @@ static int ixgbe_non_sfp_link_config(struct ixgbe_hw *hw) + { + u32 speed; + bool autoneg, link_up = false; +- int ret = IXGBE_ERR_LINK_SETUP; ++ int ret = -EIO; + + if (hw->mac.ops.check_link) + ret = hw->mac.ops.check_link(hw, &speed, &link_up, false); +@@ -5983,13 +5981,13 @@ void ixgbe_reset(struct ixgbe_adapter *adapter) + err = hw->mac.ops.init_hw(hw); + switch (err) { + case 0: +- case IXGBE_ERR_SFP_NOT_PRESENT: +- case IXGBE_ERR_SFP_NOT_SUPPORTED: ++ case -ENOENT: ++ case -EOPNOTSUPP: + break; +- case IXGBE_ERR_PRIMARY_REQUESTS_PENDING: ++ case -EALREADY: + e_dev_err("primary disable timed out\n"); + break; +- case IXGBE_ERR_EEPROM_VERSION: ++ case -EACCES: + /* We are running on a pre-production device, log a warning */ + e_dev_warn("This device is a pre-production adapter/LOM. " + "Please be aware there may be issues associated with " +@@ -7829,10 +7827,10 @@ static void ixgbe_sfp_detection_subtask(struct ixgbe_adapter *adapter) + adapter->sfp_poll_time = jiffies + IXGBE_SFP_POLL_JIFFIES - 1; + + err = hw->phy.ops.identify_sfp(hw); +- if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) ++ if (err == -EOPNOTSUPP) + goto sfp_out; + +- if (err == IXGBE_ERR_SFP_NOT_PRESENT) { ++ if (err == -ENOENT) { + /* If no cable is present, then we need to reset + * the next time we find a good cable. */ + adapter->flags2 |= IXGBE_FLAG2_SFP_NEEDS_RESET; +@@ -7858,7 +7856,7 @@ static void ixgbe_sfp_detection_subtask(struct ixgbe_adapter *adapter) + else + err = hw->mac.ops.setup_sfp(hw); + +- if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) ++ if (err == -EOPNOTSUPP) + goto sfp_out; + + adapter->flags |= IXGBE_FLAG_NEED_LINK_CONFIG; +@@ -7867,8 +7865,8 @@ static void ixgbe_sfp_detection_subtask(struct ixgbe_adapter *adapter) + sfp_out: + clear_bit(__IXGBE_IN_SFP_INIT, &adapter->state); + +- if ((err == IXGBE_ERR_SFP_NOT_SUPPORTED) && +- (adapter->netdev->reg_state == NETREG_REGISTERED)) { ++ if (err == -EOPNOTSUPP && ++ adapter->netdev->reg_state == NETREG_REGISTERED) { + e_dev_err("failed to initialize because an unsupported " + "SFP+ module type was detected.\n"); + e_dev_err("Reload the driver after installing a " +@@ -7938,7 +7936,7 @@ static void ixgbe_service_timer(struct timer_list *t) + static void ixgbe_phy_interrupt_subtask(struct ixgbe_adapter *adapter) + { + struct ixgbe_hw *hw = &adapter->hw; +- u32 status; ++ bool overtemp; + + if (!(adapter->flags2 & IXGBE_FLAG2_PHY_INTERRUPT)) + return; +@@ -7948,11 +7946,9 @@ static void ixgbe_phy_interrupt_subtask(struct ixgbe_adapter *adapter) + if (!hw->phy.ops.handle_lasi) + return; + +- status = hw->phy.ops.handle_lasi(&adapter->hw); +- if (status != IXGBE_ERR_OVERTEMP) +- return; +- +- e_crit(drv, "%s\n", ixgbe_overheat_msg); ++ hw->phy.ops.handle_lasi(&adapter->hw, &overtemp); ++ if (overtemp) ++ e_crit(drv, "%s\n", ixgbe_overheat_msg); + } + + static void ixgbe_reset_subtask(struct ixgbe_adapter *adapter) +@@ -10922,9 +10918,9 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + err = hw->mac.ops.reset_hw(hw); + hw->phy.reset_if_overtemp = false; + ixgbe_set_eee_capable(adapter); +- if (err == IXGBE_ERR_SFP_NOT_PRESENT) { ++ if (err == -ENOENT) { + err = 0; +- } else if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { ++ } else if (err == -EOPNOTSUPP) { + e_dev_err("failed to load because an unsupported SFP+ or QSFP module type was detected.\n"); + e_dev_err("Reload the driver after installing a supported module.\n"); + goto err_sw_init; +@@ -11143,7 +11139,7 @@ skip_sriov: + + /* reset the hardware with the new settings */ + err = hw->mac.ops.start_hw(hw); +- if (err == IXGBE_ERR_EEPROM_VERSION) { ++ if (err == -EACCES) { + /* We are running on a pre-production device, log a warning */ + e_dev_warn("This device is a pre-production adapter/LOM. " + "Please be aware there may be issues associated " +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.c +index 5679293e53f7a..fe7ef5773369a 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.c ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.c +@@ -24,7 +24,7 @@ s32 ixgbe_read_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id) + size = mbx->size; + + if (!mbx->ops) +- return IXGBE_ERR_MBX; ++ return -EIO; + + return mbx->ops->read(hw, msg, size, mbx_id); + } +@@ -43,10 +43,10 @@ s32 ixgbe_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id) + struct ixgbe_mbx_info *mbx = &hw->mbx; + + if (size > mbx->size) +- return IXGBE_ERR_MBX; ++ return -EINVAL; + + if (!mbx->ops) +- return IXGBE_ERR_MBX; ++ return -EIO; + + return mbx->ops->write(hw, msg, size, mbx_id); + } +@@ -63,7 +63,7 @@ s32 ixgbe_check_for_msg(struct ixgbe_hw *hw, u16 mbx_id) + struct ixgbe_mbx_info *mbx = &hw->mbx; + + if (!mbx->ops) +- return IXGBE_ERR_MBX; ++ return -EIO; + + return mbx->ops->check_for_msg(hw, mbx_id); + } +@@ -80,7 +80,7 @@ s32 ixgbe_check_for_ack(struct ixgbe_hw *hw, u16 mbx_id) + struct ixgbe_mbx_info *mbx = &hw->mbx; + + if (!mbx->ops) +- return IXGBE_ERR_MBX; ++ return -EIO; + + return mbx->ops->check_for_ack(hw, mbx_id); + } +@@ -97,7 +97,7 @@ s32 ixgbe_check_for_rst(struct ixgbe_hw *hw, u16 mbx_id) + struct ixgbe_mbx_info *mbx = &hw->mbx; + + if (!mbx->ops) +- return IXGBE_ERR_MBX; ++ return -EIO; + + return mbx->ops->check_for_rst(hw, mbx_id); + } +@@ -115,12 +115,12 @@ static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id) + int countdown = mbx->timeout; + + if (!countdown || !mbx->ops) +- return IXGBE_ERR_MBX; ++ return -EIO; + + while (mbx->ops->check_for_msg(hw, mbx_id)) { + countdown--; + if (!countdown) +- return IXGBE_ERR_MBX; ++ return -EIO; + udelay(mbx->usec_delay); + } + +@@ -140,12 +140,12 @@ static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id) + int countdown = mbx->timeout; + + if (!countdown || !mbx->ops) +- return IXGBE_ERR_MBX; ++ return -EIO; + + while (mbx->ops->check_for_ack(hw, mbx_id)) { + countdown--; + if (!countdown) +- return IXGBE_ERR_MBX; ++ return -EIO; + udelay(mbx->usec_delay); + } + +@@ -169,7 +169,7 @@ static s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, + s32 ret_val; + + if (!mbx->ops) +- return IXGBE_ERR_MBX; ++ return -EIO; + + ret_val = ixgbe_poll_for_msg(hw, mbx_id); + if (ret_val) +@@ -197,7 +197,7 @@ static s32 ixgbe_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, + + /* exit if either we can't write or there isn't a defined timeout */ + if (!mbx->ops || !mbx->timeout) +- return IXGBE_ERR_MBX; ++ return -EIO; + + /* send msg */ + ret_val = mbx->ops->write(hw, msg, size, mbx_id); +@@ -217,7 +217,7 @@ static s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index) + return 0; + } + +- return IXGBE_ERR_MBX; ++ return -EIO; + } + + /** +@@ -238,7 +238,7 @@ static s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_number) + return 0; + } + +- return IXGBE_ERR_MBX; ++ return -EIO; + } + + /** +@@ -259,7 +259,7 @@ static s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_number) + return 0; + } + +- return IXGBE_ERR_MBX; ++ return -EIO; + } + + /** +@@ -295,7 +295,7 @@ static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number) + return 0; + } + +- return IXGBE_ERR_MBX; ++ return -EIO; + } + + /** +@@ -317,7 +317,7 @@ static s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_number) + if (p2v_mailbox & IXGBE_PFMAILBOX_PFU) + return 0; + +- return IXGBE_ERR_MBX; ++ return -EIO; + } + + /** +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h +index 8f4316b19278c..6434c190e7a4c 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h +@@ -7,7 +7,6 @@ + #include "ixgbe_type.h" + + #define IXGBE_VFMAILBOX_SIZE 16 /* 16 32 bit words - 64 bytes */ +-#define IXGBE_ERR_MBX -100 + + #define IXGBE_VFMAILBOX 0x002FC + #define IXGBE_VFMBMEM 0x00200 +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c +index 689470c1e8ad5..930dc50719364 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c +@@ -102,7 +102,7 @@ s32 ixgbe_read_i2c_combined_generic_int(struct ixgbe_hw *hw, u8 addr, + csum = ~csum; + do { + if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask)) +- return IXGBE_ERR_SWFW_SYNC; ++ return -EBUSY; + ixgbe_i2c_start(hw); + /* Device Address and write indication */ + if (ixgbe_out_i2c_byte_ack(hw, addr)) +@@ -150,7 +150,7 @@ fail: + hw_dbg(hw, "I2C byte read combined error.\n"); + } while (retry < max_retry); + +- return IXGBE_ERR_I2C; ++ return -EIO; + } + + /** +@@ -179,7 +179,7 @@ s32 ixgbe_write_i2c_combined_generic_int(struct ixgbe_hw *hw, u8 addr, + csum = ~csum; + do { + if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask)) +- return IXGBE_ERR_SWFW_SYNC; ++ return -EBUSY; + ixgbe_i2c_start(hw); + /* Device Address and write indication */ + if (ixgbe_out_i2c_byte_ack(hw, addr)) +@@ -215,7 +215,7 @@ fail: + hw_dbg(hw, "I2C byte write combined error.\n"); + } while (retry < max_retry); + +- return IXGBE_ERR_I2C; ++ return -EIO; + } + + /** +@@ -262,8 +262,8 @@ static bool ixgbe_probe_phy(struct ixgbe_hw *hw, u16 phy_addr) + **/ + s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw) + { ++ u32 status = -EFAULT; + u32 phy_addr; +- u32 status = IXGBE_ERR_PHY_ADDR_INVALID; + + if (!hw->phy.phy_semaphore_mask) { + if (hw->bus.lan_id) +@@ -282,7 +282,7 @@ s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw) + if (ixgbe_probe_phy(hw, phy_addr)) + return 0; + else +- return IXGBE_ERR_PHY_ADDR_INVALID; ++ return -EFAULT; + } + + for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) { +@@ -408,8 +408,7 @@ s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw) + return status; + + /* Don't reset PHY if it's shut down due to overtemp. */ +- if (!hw->phy.reset_if_overtemp && +- (IXGBE_ERR_OVERTEMP == hw->phy.ops.check_overtemp(hw))) ++ if (!hw->phy.reset_if_overtemp && hw->phy.ops.check_overtemp(hw)) + return 0; + + /* Blocked by MNG FW so bail */ +@@ -457,7 +456,7 @@ s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw) + + if (ctrl & MDIO_CTRL1_RESET) { + hw_dbg(hw, "PHY reset polling failed to complete.\n"); +- return IXGBE_ERR_RESET_FAILED; ++ return -EIO; + } + + return 0; +@@ -500,7 +499,7 @@ s32 ixgbe_read_phy_reg_mdi(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type, + + if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) { + hw_dbg(hw, "PHY address command did not complete.\n"); +- return IXGBE_ERR_PHY; ++ return -EIO; + } + + /* Address cycle complete, setup and write the read +@@ -527,7 +526,7 @@ s32 ixgbe_read_phy_reg_mdi(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type, + + if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) { + hw_dbg(hw, "PHY read command didn't complete\n"); +- return IXGBE_ERR_PHY; ++ return -EIO; + } + + /* Read operation is complete. Get the data +@@ -559,7 +558,7 @@ s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, + phy_data); + hw->mac.ops.release_swfw_sync(hw, gssr); + } else { +- return IXGBE_ERR_SWFW_SYNC; ++ return -EBUSY; + } + + return status; +@@ -604,7 +603,7 @@ s32 ixgbe_write_phy_reg_mdi(struct ixgbe_hw *hw, u32 reg_addr, + + if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) { + hw_dbg(hw, "PHY address cmd didn't complete\n"); +- return IXGBE_ERR_PHY; ++ return -EIO; + } + + /* +@@ -632,7 +631,7 @@ s32 ixgbe_write_phy_reg_mdi(struct ixgbe_hw *hw, u32 reg_addr, + + if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) { + hw_dbg(hw, "PHY write cmd didn't complete\n"); +- return IXGBE_ERR_PHY; ++ return -EIO; + } + + return 0; +@@ -657,7 +656,7 @@ s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, + phy_data); + hw->mac.ops.release_swfw_sync(hw, gssr); + } else { +- return IXGBE_ERR_SWFW_SYNC; ++ return -EBUSY; + } + + return status; +@@ -1430,7 +1429,7 @@ s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw) + + if ((phy_data & MDIO_CTRL1_RESET) != 0) { + hw_dbg(hw, "PHY reset did not complete.\n"); +- return IXGBE_ERR_PHY; ++ return -EIO; + } + + /* Get init offsets */ +@@ -1487,12 +1486,12 @@ s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw) + hw_dbg(hw, "SOL\n"); + } else { + hw_dbg(hw, "Bad control value\n"); +- return IXGBE_ERR_PHY; ++ return -EIO; + } + break; + default: + hw_dbg(hw, "Bad control type\n"); +- return IXGBE_ERR_PHY; ++ return -EIO; + } + } + +@@ -1500,7 +1499,7 @@ s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw) + + err_eeprom: + hw_err(hw, "eeprom read at offset %d failed\n", data_offset); +- return IXGBE_ERR_PHY; ++ return -EIO; + } + + /** +@@ -1518,10 +1517,10 @@ s32 ixgbe_identify_module_generic(struct ixgbe_hw *hw) + return ixgbe_identify_qsfp_module_generic(hw); + default: + hw->phy.sfp_type = ixgbe_sfp_type_not_present; +- return IXGBE_ERR_SFP_NOT_PRESENT; ++ return -ENOENT; + } + +- return IXGBE_ERR_SFP_NOT_PRESENT; ++ return -ENOENT; + } + + /** +@@ -1546,7 +1545,7 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) + + if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_fiber) { + hw->phy.sfp_type = ixgbe_sfp_type_not_present; +- return IXGBE_ERR_SFP_NOT_PRESENT; ++ return -ENOENT; + } + + /* LAN ID is needed for sfp_type determination */ +@@ -1561,7 +1560,7 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) + + if (identifier != IXGBE_SFF_IDENTIFIER_SFP) { + hw->phy.type = ixgbe_phy_sfp_unsupported; +- return IXGBE_ERR_SFP_NOT_SUPPORTED; ++ return -EOPNOTSUPP; + } + status = hw->phy.ops.read_i2c_eeprom(hw, + IXGBE_SFF_1GBE_COMP_CODES, +@@ -1752,7 +1751,7 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) + hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1)) { + hw->phy.type = ixgbe_phy_sfp_unsupported; +- return IXGBE_ERR_SFP_NOT_SUPPORTED; ++ return -EOPNOTSUPP; + } + + /* Anything else 82598-based is supported */ +@@ -1776,7 +1775,7 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) + } + hw_dbg(hw, "SFP+ module not supported\n"); + hw->phy.type = ixgbe_phy_sfp_unsupported; +- return IXGBE_ERR_SFP_NOT_SUPPORTED; ++ return -EOPNOTSUPP; + } + return 0; + +@@ -1786,7 +1785,7 @@ err_read_i2c_eeprom: + hw->phy.id = 0; + hw->phy.type = ixgbe_phy_unknown; + } +- return IXGBE_ERR_SFP_NOT_PRESENT; ++ return -ENOENT; + } + + /** +@@ -1813,7 +1812,7 @@ static s32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw) + + if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_fiber_qsfp) { + hw->phy.sfp_type = ixgbe_sfp_type_not_present; +- return IXGBE_ERR_SFP_NOT_PRESENT; ++ return -ENOENT; + } + + /* LAN ID is needed for sfp_type determination */ +@@ -1827,7 +1826,7 @@ static s32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw) + + if (identifier != IXGBE_SFF_IDENTIFIER_QSFP_PLUS) { + hw->phy.type = ixgbe_phy_sfp_unsupported; +- return IXGBE_ERR_SFP_NOT_SUPPORTED; ++ return -EOPNOTSUPP; + } + + hw->phy.id = identifier; +@@ -1895,7 +1894,7 @@ static s32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw) + } else { + /* unsupported module type */ + hw->phy.type = ixgbe_phy_sfp_unsupported; +- return IXGBE_ERR_SFP_NOT_SUPPORTED; ++ return -EOPNOTSUPP; + } + } + +@@ -1955,7 +1954,7 @@ static s32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw) + } + hw_dbg(hw, "QSFP module not supported\n"); + hw->phy.type = ixgbe_phy_sfp_unsupported; +- return IXGBE_ERR_SFP_NOT_SUPPORTED; ++ return -EOPNOTSUPP; + } + return 0; + } +@@ -1966,7 +1965,7 @@ err_read_i2c_eeprom: + hw->phy.id = 0; + hw->phy.type = ixgbe_phy_unknown; + +- return IXGBE_ERR_SFP_NOT_PRESENT; ++ return -ENOENT; + } + + /** +@@ -1986,14 +1985,14 @@ s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw, + u16 sfp_type = hw->phy.sfp_type; + + if (hw->phy.sfp_type == ixgbe_sfp_type_unknown) +- return IXGBE_ERR_SFP_NOT_SUPPORTED; ++ return -EOPNOTSUPP; + + if (hw->phy.sfp_type == ixgbe_sfp_type_not_present) +- return IXGBE_ERR_SFP_NOT_PRESENT; ++ return -ENOENT; + + if ((hw->device_id == IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM) && + (hw->phy.sfp_type == ixgbe_sfp_type_da_cu)) +- return IXGBE_ERR_SFP_NOT_SUPPORTED; ++ return -EOPNOTSUPP; + + /* + * Limiting active cables and 1G Phys must be initialized as +@@ -2014,11 +2013,11 @@ s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw, + if (hw->eeprom.ops.read(hw, IXGBE_PHY_INIT_OFFSET_NL, list_offset)) { + hw_err(hw, "eeprom read at %d failed\n", + IXGBE_PHY_INIT_OFFSET_NL); +- return IXGBE_ERR_SFP_NO_INIT_SEQ_PRESENT; ++ return -EIO; + } + + if ((!*list_offset) || (*list_offset == 0xFFFF)) +- return IXGBE_ERR_SFP_NO_INIT_SEQ_PRESENT; ++ return -EIO; + + /* Shift offset to first ID word */ + (*list_offset)++; +@@ -2037,7 +2036,7 @@ s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw, + goto err_phy; + if ((!*data_offset) || (*data_offset == 0xFFFF)) { + hw_dbg(hw, "SFP+ module not supported\n"); +- return IXGBE_ERR_SFP_NOT_SUPPORTED; ++ return -EOPNOTSUPP; + } else { + break; + } +@@ -2050,14 +2049,14 @@ s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw, + + if (sfp_id == IXGBE_PHY_INIT_END_NL) { + hw_dbg(hw, "No matching SFP+ module found\n"); +- return IXGBE_ERR_SFP_NOT_SUPPORTED; ++ return -EOPNOTSUPP; + } + + return 0; + + err_phy: + hw_err(hw, "eeprom read at offset %d failed\n", *list_offset); +- return IXGBE_ERR_PHY; ++ return -EIO; + } + + /** +@@ -2152,7 +2151,7 @@ static s32 ixgbe_read_i2c_byte_generic_int(struct ixgbe_hw *hw, u8 byte_offset, + + do { + if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask)) +- return IXGBE_ERR_SWFW_SYNC; ++ return -EBUSY; + + ixgbe_i2c_start(hw); + +@@ -2268,7 +2267,7 @@ static s32 ixgbe_write_i2c_byte_generic_int(struct ixgbe_hw *hw, u8 byte_offset, + u32 swfw_mask = hw->phy.phy_semaphore_mask; + + if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask)) +- return IXGBE_ERR_SWFW_SYNC; ++ return -EBUSY; + + do { + ixgbe_i2c_start(hw); +@@ -2510,7 +2509,7 @@ static s32 ixgbe_get_i2c_ack(struct ixgbe_hw *hw) + + if (ack == 1) { + hw_dbg(hw, "I2C ack was not received.\n"); +- status = IXGBE_ERR_I2C; ++ status = -EIO; + } + + ixgbe_lower_i2c_clk(hw, &i2cctl); +@@ -2582,7 +2581,7 @@ static s32 ixgbe_clock_out_i2c_bit(struct ixgbe_hw *hw, bool data) + udelay(IXGBE_I2C_T_LOW); + } else { + hw_dbg(hw, "I2C data was not set to %X\n", data); +- return IXGBE_ERR_I2C; ++ return -EIO; + } + + return 0; +@@ -2678,7 +2677,7 @@ static s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data) + *i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL(hw)); + if (data != ixgbe_get_i2c_data(hw, i2cctl)) { + hw_dbg(hw, "Error - I2C data was not set to %X.\n", data); +- return IXGBE_ERR_I2C; ++ return -EIO; + } + + return 0; +@@ -2748,22 +2747,24 @@ static void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw) + * @hw: pointer to hardware structure + * + * Checks if the LASI temp alarm status was triggered due to overtemp ++ * ++ * Return true when an overtemp event detected, otherwise false. + **/ +-s32 ixgbe_tn_check_overtemp(struct ixgbe_hw *hw) ++bool ixgbe_tn_check_overtemp(struct ixgbe_hw *hw) + { + u16 phy_data = 0; ++ u32 status; + + if (hw->device_id != IXGBE_DEV_ID_82599_T3_LOM) +- return 0; ++ return false; + + /* Check that the LASI temp alarm status was triggered */ +- hw->phy.ops.read_reg(hw, IXGBE_TN_LASI_STATUS_REG, +- MDIO_MMD_PMAPMD, &phy_data); +- +- if (!(phy_data & IXGBE_TN_LASI_STATUS_TEMP_ALARM)) +- return 0; ++ status = hw->phy.ops.read_reg(hw, IXGBE_TN_LASI_STATUS_REG, ++ MDIO_MMD_PMAPMD, &phy_data); ++ if (status) ++ return false; + +- return IXGBE_ERR_OVERTEMP; ++ return !!(phy_data & IXGBE_TN_LASI_STATUS_TEMP_ALARM); + } + + /** ixgbe_set_copper_phy_power - Control power for copper phy +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h +index 6544c4539c0de..ef72729d7c933 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h +@@ -155,7 +155,7 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw); + s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw, + u16 *list_offset, + u16 *data_offset); +-s32 ixgbe_tn_check_overtemp(struct ixgbe_hw *hw); ++bool ixgbe_tn_check_overtemp(struct ixgbe_hw *hw); + s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset, + u8 dev_addr, u8 *data); + s32 ixgbe_read_i2c_byte_generic_unlocked(struct ixgbe_hw *hw, u8 byte_offset, +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c +index 9cfdfa8a4355c..9379069c55c82 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c +@@ -1327,7 +1327,7 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf) + break; + default: + e_err(drv, "Unhandled Msg %8.8x\n", msgbuf[0]); +- retval = IXGBE_ERR_MBX; ++ retval = -EIO; + break; + } + +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h +index 2b00db92b08f5..61b9774b3d31e 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h +@@ -3509,10 +3509,10 @@ struct ixgbe_phy_operations { + s32 (*read_i2c_sff8472)(struct ixgbe_hw *, u8 , u8 *); + s32 (*read_i2c_eeprom)(struct ixgbe_hw *, u8 , u8 *); + s32 (*write_i2c_eeprom)(struct ixgbe_hw *, u8, u8); +- s32 (*check_overtemp)(struct ixgbe_hw *); ++ bool (*check_overtemp)(struct ixgbe_hw *); + s32 (*set_phy_power)(struct ixgbe_hw *, bool on); + s32 (*enter_lplu)(struct ixgbe_hw *); +- s32 (*handle_lasi)(struct ixgbe_hw *hw); ++ s32 (*handle_lasi)(struct ixgbe_hw *hw, bool *); + s32 (*read_i2c_byte_unlocked)(struct ixgbe_hw *, u8 offset, u8 addr, + u8 *value); + s32 (*write_i2c_byte_unlocked)(struct ixgbe_hw *, u8 offset, u8 addr, +@@ -3665,45 +3665,6 @@ struct ixgbe_info { + const u32 *mvals; + }; + +- +-/* Error Codes */ +-#define IXGBE_ERR_EEPROM -1 +-#define IXGBE_ERR_EEPROM_CHECKSUM -2 +-#define IXGBE_ERR_PHY -3 +-#define IXGBE_ERR_CONFIG -4 +-#define IXGBE_ERR_PARAM -5 +-#define IXGBE_ERR_MAC_TYPE -6 +-#define IXGBE_ERR_UNKNOWN_PHY -7 +-#define IXGBE_ERR_LINK_SETUP -8 +-#define IXGBE_ERR_ADAPTER_STOPPED -9 +-#define IXGBE_ERR_INVALID_MAC_ADDR -10 +-#define IXGBE_ERR_DEVICE_NOT_SUPPORTED -11 +-#define IXGBE_ERR_PRIMARY_REQUESTS_PENDING -12 +-#define IXGBE_ERR_INVALID_LINK_SETTINGS -13 +-#define IXGBE_ERR_AUTONEG_NOT_COMPLETE -14 +-#define IXGBE_ERR_RESET_FAILED -15 +-#define IXGBE_ERR_SWFW_SYNC -16 +-#define IXGBE_ERR_PHY_ADDR_INVALID -17 +-#define IXGBE_ERR_I2C -18 +-#define IXGBE_ERR_SFP_NOT_SUPPORTED -19 +-#define IXGBE_ERR_SFP_NOT_PRESENT -20 +-#define IXGBE_ERR_SFP_NO_INIT_SEQ_PRESENT -21 +-#define IXGBE_ERR_NO_SAN_ADDR_PTR -22 +-#define IXGBE_ERR_FDIR_REINIT_FAILED -23 +-#define IXGBE_ERR_EEPROM_VERSION -24 +-#define IXGBE_ERR_NO_SPACE -25 +-#define IXGBE_ERR_OVERTEMP -26 +-#define IXGBE_ERR_FC_NOT_NEGOTIATED -27 +-#define IXGBE_ERR_FC_NOT_SUPPORTED -28 +-#define IXGBE_ERR_SFP_SETUP_NOT_COMPLETE -30 +-#define IXGBE_ERR_PBA_SECTION -31 +-#define IXGBE_ERR_INVALID_ARGUMENT -32 +-#define IXGBE_ERR_HOST_INTERFACE_COMMAND -33 +-#define IXGBE_ERR_FDIR_CMD_INCOMPLETE -38 +-#define IXGBE_ERR_FW_RESP_INVALID -39 +-#define IXGBE_ERR_TOKEN_RETRY -40 +-#define IXGBE_NOT_IMPLEMENTED 0x7FFFFFFF +- + #define IXGBE_FUSES0_GROUP(_i) (0x11158 + ((_i) * 4)) + #define IXGBE_FUSES0_300MHZ BIT(5) + #define IXGBE_FUSES0_REV_MASK (3u << 6) +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c +index d5cfb51ff648d..15325c549d9b5 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c +@@ -84,7 +84,7 @@ mac_reset_top: + status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask); + if (status) { + hw_dbg(hw, "semaphore failed with %d", status); +- return IXGBE_ERR_SWFW_SYNC; ++ return -EBUSY; + } + + ctrl = IXGBE_CTRL_RST; +@@ -103,7 +103,7 @@ mac_reset_top: + } + + if (ctrl & IXGBE_CTRL_RST_MASK) { +- status = IXGBE_ERR_RESET_FAILED; ++ status = -EIO; + hw_dbg(hw, "Reset polling failed to complete.\n"); + } + msleep(100); +@@ -220,7 +220,7 @@ static s32 ixgbe_read_eerd_X540(struct ixgbe_hw *hw, u16 offset, u16 *data) + s32 status; + + if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM)) +- return IXGBE_ERR_SWFW_SYNC; ++ return -EBUSY; + + status = ixgbe_read_eerd_generic(hw, offset, data); + +@@ -243,7 +243,7 @@ static s32 ixgbe_read_eerd_buffer_X540(struct ixgbe_hw *hw, + s32 status; + + if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM)) +- return IXGBE_ERR_SWFW_SYNC; ++ return -EBUSY; + + status = ixgbe_read_eerd_buffer_generic(hw, offset, words, data); + +@@ -264,7 +264,7 @@ static s32 ixgbe_write_eewr_X540(struct ixgbe_hw *hw, u16 offset, u16 data) + s32 status; + + if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM)) +- return IXGBE_ERR_SWFW_SYNC; ++ return -EBUSY; + + status = ixgbe_write_eewr_generic(hw, offset, data); + +@@ -287,7 +287,7 @@ static s32 ixgbe_write_eewr_buffer_X540(struct ixgbe_hw *hw, + s32 status; + + if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM)) +- return IXGBE_ERR_SWFW_SYNC; ++ return -EBUSY; + + status = ixgbe_write_eewr_buffer_generic(hw, offset, words, data); + +@@ -324,7 +324,7 @@ static s32 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw) + for (i = 0; i < checksum_last_word; i++) { + if (ixgbe_read_eerd_generic(hw, i, &word)) { + hw_dbg(hw, "EEPROM read failed\n"); +- return IXGBE_ERR_EEPROM; ++ return -EIO; + } + checksum += word; + } +@@ -349,7 +349,7 @@ static s32 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw) + + if (ixgbe_read_eerd_generic(hw, pointer, &length)) { + hw_dbg(hw, "EEPROM read failed\n"); +- return IXGBE_ERR_EEPROM; ++ return -EIO; + } + + /* Skip pointer section if length is invalid. */ +@@ -360,7 +360,7 @@ static s32 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw) + for (j = pointer + 1; j <= pointer + length; j++) { + if (ixgbe_read_eerd_generic(hw, j, &word)) { + hw_dbg(hw, "EEPROM read failed\n"); +- return IXGBE_ERR_EEPROM; ++ return -EIO; + } + checksum += word; + } +@@ -397,7 +397,7 @@ static s32 ixgbe_validate_eeprom_checksum_X540(struct ixgbe_hw *hw, + } + + if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM)) +- return IXGBE_ERR_SWFW_SYNC; ++ return -EBUSY; + + status = hw->eeprom.ops.calc_checksum(hw); + if (status < 0) +@@ -418,7 +418,7 @@ static s32 ixgbe_validate_eeprom_checksum_X540(struct ixgbe_hw *hw, + */ + if (read_checksum != checksum) { + hw_dbg(hw, "Invalid EEPROM checksum"); +- status = IXGBE_ERR_EEPROM_CHECKSUM; ++ status = -EIO; + } + + /* If the user cares, return the calculated checksum */ +@@ -455,7 +455,7 @@ static s32 ixgbe_update_eeprom_checksum_X540(struct ixgbe_hw *hw) + } + + if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM)) +- return IXGBE_ERR_SWFW_SYNC; ++ return -EBUSY; + + status = hw->eeprom.ops.calc_checksum(hw); + if (status < 0) +@@ -490,7 +490,7 @@ static s32 ixgbe_update_flash_X540(struct ixgbe_hw *hw) + s32 status; + + status = ixgbe_poll_flash_update_done_X540(hw); +- if (status == IXGBE_ERR_EEPROM) { ++ if (status == -EIO) { + hw_dbg(hw, "Flash update time out\n"); + return status; + } +@@ -540,7 +540,7 @@ static s32 ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw) + return 0; + udelay(5); + } +- return IXGBE_ERR_EEPROM; ++ return -EIO; + } + + /** +@@ -575,7 +575,7 @@ s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask) + * SW_FW_SYNC bits (not just NVM) + */ + if (ixgbe_get_swfw_sync_semaphore(hw)) +- return IXGBE_ERR_SWFW_SYNC; ++ return -EBUSY; + + swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC(hw)); + if (!(swfw_sync & (fwmask | swmask | hwmask))) { +@@ -599,7 +599,7 @@ s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask) + * bits in the SW_FW_SYNC register. + */ + if (ixgbe_get_swfw_sync_semaphore(hw)) +- return IXGBE_ERR_SWFW_SYNC; ++ return -EBUSY; + swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC(hw)); + if (swfw_sync & (fwmask | hwmask)) { + swfw_sync |= swmask; +@@ -622,11 +622,11 @@ s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask) + rmask |= IXGBE_GSSR_I2C_MASK; + ixgbe_release_swfw_sync_X540(hw, rmask); + ixgbe_release_swfw_sync_semaphore(hw); +- return IXGBE_ERR_SWFW_SYNC; ++ return -EBUSY; + } + ixgbe_release_swfw_sync_semaphore(hw); + +- return IXGBE_ERR_SWFW_SYNC; ++ return -EBUSY; + } + + /** +@@ -680,7 +680,7 @@ static s32 ixgbe_get_swfw_sync_semaphore(struct ixgbe_hw *hw) + if (i == timeout) { + hw_dbg(hw, + "Software semaphore SMBI between device drivers not granted.\n"); +- return IXGBE_ERR_EEPROM; ++ return -EIO; + } + + /* Now get the semaphore between SW/FW through the REGSMP bit */ +@@ -697,7 +697,7 @@ static s32 ixgbe_get_swfw_sync_semaphore(struct ixgbe_hw *hw) + */ + hw_dbg(hw, "REGSMP Software NVM semaphore not granted\n"); + ixgbe_release_swfw_sync_semaphore(hw); +- return IXGBE_ERR_EEPROM; ++ return -EIO; + } + + /** +@@ -768,7 +768,7 @@ s32 ixgbe_blink_led_start_X540(struct ixgbe_hw *hw, u32 index) + bool link_up; + + if (index > 3) +- return IXGBE_ERR_PARAM; ++ return -EINVAL; + + /* Link should be up in order for the blink bit in the LED control + * register to work. Force link and speed in the MAC if link is down. +@@ -804,7 +804,7 @@ s32 ixgbe_blink_led_stop_X540(struct ixgbe_hw *hw, u32 index) + u32 ledctl_reg; + + if (index > 3) +- return IXGBE_ERR_PARAM; ++ return -EINVAL; + + /* Restore the LED to its default value. */ + ledctl_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c +index aa4bf6c9a2f7c..cdc912bba8089 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c +@@ -206,13 +206,13 @@ static s32 ixgbe_reset_cs4227(struct ixgbe_hw *hw) + } + if (retry == IXGBE_CS4227_RETRIES) { + hw_err(hw, "CS4227 reset did not complete\n"); +- return IXGBE_ERR_PHY; ++ return -EIO; + } + + status = ixgbe_read_cs4227(hw, IXGBE_CS4227_EEPROM_STATUS, &value); + if (status || !(value & IXGBE_CS4227_EEPROM_LOAD_OK)) { + hw_err(hw, "CS4227 EEPROM did not load successfully\n"); +- return IXGBE_ERR_PHY; ++ return -EIO; + } + + return 0; +@@ -350,13 +350,13 @@ static s32 ixgbe_identify_phy_x550em(struct ixgbe_hw *hw) + static s32 ixgbe_read_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u16 *phy_data) + { +- return IXGBE_NOT_IMPLEMENTED; ++ return -EOPNOTSUPP; + } + + static s32 ixgbe_write_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u16 phy_data) + { +- return IXGBE_NOT_IMPLEMENTED; ++ return -EOPNOTSUPP; + } + + /** +@@ -463,7 +463,7 @@ s32 ixgbe_fw_phy_activity(struct ixgbe_hw *hw, u16 activity, + --retries; + } while (retries > 0); + +- return IXGBE_ERR_HOST_INTERFACE_COMMAND; ++ return -EIO; + } + + static const struct { +@@ -511,7 +511,7 @@ static s32 ixgbe_get_phy_id_fw(struct ixgbe_hw *hw) + hw->phy.id |= phy_id_lo & IXGBE_PHY_REVISION_MASK; + hw->phy.revision = phy_id_lo & ~IXGBE_PHY_REVISION_MASK; + if (!hw->phy.id || hw->phy.id == IXGBE_PHY_REVISION_MASK) +- return IXGBE_ERR_PHY_ADDR_INVALID; ++ return -EFAULT; + + hw->phy.autoneg_advertised = hw->phy.speeds_supported; + hw->phy.eee_speeds_supported = IXGBE_LINK_SPEED_100_FULL | +@@ -568,7 +568,7 @@ static s32 ixgbe_setup_fw_link(struct ixgbe_hw *hw) + + if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) { + hw_err(hw, "rx_pause not valid in strict IEEE mode\n"); +- return IXGBE_ERR_INVALID_LINK_SETTINGS; ++ return -EINVAL; + } + + switch (hw->fc.requested_mode) { +@@ -600,8 +600,10 @@ static s32 ixgbe_setup_fw_link(struct ixgbe_hw *hw) + rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_SETUP_LINK, &setup); + if (rc) + return rc; ++ + if (setup[0] == FW_PHY_ACT_SETUP_LINK_RSP_DOWN) +- return IXGBE_ERR_OVERTEMP; ++ return -EIO; ++ + return 0; + } + +@@ -675,7 +677,7 @@ static s32 ixgbe_iosf_wait(struct ixgbe_hw *hw, u32 *ctrl) + *ctrl = command; + if (i == IXGBE_MDIO_COMMAND_TIMEOUT) { + hw_dbg(hw, "IOSF wait timed out\n"); +- return IXGBE_ERR_PHY; ++ return -EIO; + } + + return 0; +@@ -715,7 +717,8 @@ static s32 ixgbe_read_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr, + error = (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >> + IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT; + hw_dbg(hw, "Failed to read, error %x\n", error); +- return IXGBE_ERR_PHY; ++ ret = -EIO; ++ goto out; + } + + if (!ret) +@@ -750,9 +753,9 @@ static s32 ixgbe_get_phy_token(struct ixgbe_hw *hw) + if (token_cmd.hdr.cmd_or_resp.ret_status == FW_PHY_TOKEN_OK) + return 0; + if (token_cmd.hdr.cmd_or_resp.ret_status != FW_PHY_TOKEN_RETRY) +- return IXGBE_ERR_FW_RESP_INVALID; ++ return -EIO; + +- return IXGBE_ERR_TOKEN_RETRY; ++ return -EAGAIN; + } + + /** +@@ -778,7 +781,7 @@ static s32 ixgbe_put_phy_token(struct ixgbe_hw *hw) + return status; + if (token_cmd.hdr.cmd_or_resp.ret_status == FW_PHY_TOKEN_OK) + return 0; +- return IXGBE_ERR_FW_RESP_INVALID; ++ return -EIO; + } + + /** +@@ -942,7 +945,7 @@ static s32 ixgbe_checksum_ptr_x550(struct ixgbe_hw *hw, u16 ptr, + local_buffer = buf; + } else { + if (buffer_size < ptr) +- return IXGBE_ERR_PARAM; ++ return -EINVAL; + local_buffer = &buffer[ptr]; + } + +@@ -960,7 +963,7 @@ static s32 ixgbe_checksum_ptr_x550(struct ixgbe_hw *hw, u16 ptr, + } + + if (buffer && ((u32)start + (u32)length > buffer_size)) +- return IXGBE_ERR_PARAM; ++ return -EINVAL; + + for (i = start; length; i++, length--) { + if (i == bufsz && !buffer) { +@@ -1012,7 +1015,7 @@ static s32 ixgbe_calc_checksum_X550(struct ixgbe_hw *hw, u16 *buffer, + local_buffer = eeprom_ptrs; + } else { + if (buffer_size < IXGBE_EEPROM_LAST_WORD) +- return IXGBE_ERR_PARAM; ++ return -EINVAL; + local_buffer = buffer; + } + +@@ -1148,7 +1151,7 @@ static s32 ixgbe_validate_eeprom_checksum_X550(struct ixgbe_hw *hw, + * calculated checksum + */ + if (read_checksum != checksum) { +- status = IXGBE_ERR_EEPROM_CHECKSUM; ++ status = -EIO; + hw_dbg(hw, "Invalid EEPROM checksum"); + } + +@@ -1203,7 +1206,7 @@ static s32 ixgbe_write_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset, u16 data) + hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); + } else { + hw_dbg(hw, "write ee hostif failed to get semaphore"); +- status = IXGBE_ERR_SWFW_SYNC; ++ status = -EBUSY; + } + + return status; +@@ -1415,7 +1418,7 @@ static s32 ixgbe_write_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr, + error = (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >> + IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT; + hw_dbg(hw, "Failed to write, error %x\n", error); +- return IXGBE_ERR_PHY; ++ return -EIO; + } + + out: +@@ -1558,7 +1561,7 @@ static s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed) + + /* iXFI is only supported with X552 */ + if (mac->type != ixgbe_mac_X550EM_x) +- return IXGBE_ERR_LINK_SETUP; ++ return -EIO; + + /* Disable AN and force speed to 10G Serial. */ + status = ixgbe_read_iosf_sb_reg_x550(hw, +@@ -1580,7 +1583,7 @@ static s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed) + break; + default: + /* Other link speeds are not supported by internal KR PHY. */ +- return IXGBE_ERR_LINK_SETUP; ++ return -EINVAL; + } + + status = ixgbe_write_iosf_sb_reg_x550(hw, +@@ -1611,7 +1614,7 @@ static s32 ixgbe_supported_sfp_modules_X550em(struct ixgbe_hw *hw, bool *linear) + { + switch (hw->phy.sfp_type) { + case ixgbe_sfp_type_not_present: +- return IXGBE_ERR_SFP_NOT_PRESENT; ++ return -ENOENT; + case ixgbe_sfp_type_da_cu_core0: + case ixgbe_sfp_type_da_cu_core1: + *linear = true; +@@ -1630,7 +1633,7 @@ static s32 ixgbe_supported_sfp_modules_X550em(struct ixgbe_hw *hw, bool *linear) + case ixgbe_sfp_type_1g_cu_core0: + case ixgbe_sfp_type_1g_cu_core1: + default: +- return IXGBE_ERR_SFP_NOT_SUPPORTED; ++ return -EOPNOTSUPP; + } + + return 0; +@@ -1660,7 +1663,7 @@ ixgbe_setup_mac_link_sfp_x550em(struct ixgbe_hw *hw, + * there is no reason to configure CS4227 and SFP not present error is + * not accepted in the setup MAC link flow. + */ +- if (status == IXGBE_ERR_SFP_NOT_PRESENT) ++ if (status == -ENOENT) + return 0; + + if (status) +@@ -1718,7 +1721,7 @@ static s32 ixgbe_setup_sfi_x550a(struct ixgbe_hw *hw, ixgbe_link_speed *speed) + break; + default: + /* Other link speeds are not supported by internal PHY. */ +- return IXGBE_ERR_LINK_SETUP; ++ return -EINVAL; + } + + (void)mac->ops.write_iosf_sb_reg(hw, +@@ -1803,7 +1806,7 @@ ixgbe_setup_mac_link_sfp_n(struct ixgbe_hw *hw, ixgbe_link_speed speed, + /* If no SFP module present, then return success. Return success since + * SFP not present error is not excepted in the setup MAC link flow. + */ +- if (ret_val == IXGBE_ERR_SFP_NOT_PRESENT) ++ if (ret_val == -ENOENT) + return 0; + + if (ret_val) +@@ -1853,7 +1856,7 @@ ixgbe_setup_mac_link_sfp_x550a(struct ixgbe_hw *hw, ixgbe_link_speed speed, + /* If no SFP module present, then return success. Return success since + * SFP not present error is not excepted in the setup MAC link flow. + */ +- if (ret_val == IXGBE_ERR_SFP_NOT_PRESENT) ++ if (ret_val == -ENOENT) + return 0; + + if (ret_val) +@@ -1863,7 +1866,7 @@ ixgbe_setup_mac_link_sfp_x550a(struct ixgbe_hw *hw, ixgbe_link_speed speed, + ixgbe_setup_kr_speed_x550em(hw, speed); + + if (hw->phy.mdio.prtad == MDIO_PRTAD_NONE) +- return IXGBE_ERR_PHY_ADDR_INVALID; ++ return -EFAULT; + + /* Get external PHY SKU id */ + ret_val = hw->phy.ops.read_reg(hw, IXGBE_CS4227_EFUSE_PDF_SKU, +@@ -1962,7 +1965,7 @@ static s32 ixgbe_check_link_t_X550em(struct ixgbe_hw *hw, + u16 i, autoneg_status; + + if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper) +- return IXGBE_ERR_CONFIG; ++ return -EIO; + + status = ixgbe_check_mac_link_generic(hw, speed, link_up, + link_up_wait_to_complete); +@@ -2145,9 +2148,9 @@ static s32 ixgbe_setup_sgmii_fw(struct ixgbe_hw *hw, ixgbe_link_speed speed, + */ + static void ixgbe_fc_autoneg_sgmii_x550em_a(struct ixgbe_hw *hw) + { +- s32 status = IXGBE_ERR_FC_NOT_NEGOTIATED; + u32 info[FW_PHY_ACT_DATA_COUNT] = { 0 }; + ixgbe_link_speed speed; ++ s32 status = -EIO; + bool link_up; + + /* AN should have completed when the cable was plugged in. +@@ -2165,7 +2168,7 @@ static void ixgbe_fc_autoneg_sgmii_x550em_a(struct ixgbe_hw *hw) + /* Check if auto-negotiation has completed */ + status = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_LINK_INFO, &info); + if (status || !(info[0] & FW_PHY_ACT_GET_LINK_INFO_AN_COMPLETE)) { +- status = IXGBE_ERR_FC_NOT_NEGOTIATED; ++ status = -EIO; + goto out; + } + +@@ -2369,18 +2372,18 @@ static s32 ixgbe_get_link_capabilities_X550em(struct ixgbe_hw *hw, + * @hw: pointer to hardware structure + * @lsc: pointer to boolean flag which indicates whether external Base T + * PHY interrupt is lsc ++ * @is_overtemp: indicate whether an overtemp event encountered + * + * Determime if external Base T PHY interrupt cause is high temperature + * failure alarm or link status change. +- * +- * Return IXGBE_ERR_OVERTEMP if interrupt is high temperature +- * failure alarm, else return PHY access status. + **/ +-static s32 ixgbe_get_lasi_ext_t_x550em(struct ixgbe_hw *hw, bool *lsc) ++static s32 ixgbe_get_lasi_ext_t_x550em(struct ixgbe_hw *hw, bool *lsc, ++ bool *is_overtemp) + { + u32 status; + u16 reg; + ++ *is_overtemp = false; + *lsc = false; + + /* Vendor alarm triggered */ +@@ -2412,7 +2415,8 @@ static s32 ixgbe_get_lasi_ext_t_x550em(struct ixgbe_hw *hw, bool *lsc) + if (reg & IXGBE_MDIO_GLOBAL_ALM_1_HI_TMP_FAIL) { + /* power down the PHY in case the PHY FW didn't already */ + ixgbe_set_copper_phy_power(hw, false); +- return IXGBE_ERR_OVERTEMP; ++ *is_overtemp = true; ++ return -EIO; + } + if (reg & IXGBE_MDIO_GLOBAL_ALM_1_DEV_FAULT) { + /* device fault alarm triggered */ +@@ -2426,7 +2430,8 @@ static s32 ixgbe_get_lasi_ext_t_x550em(struct ixgbe_hw *hw, bool *lsc) + if (reg == IXGBE_MDIO_GLOBAL_FAULT_MSG_HI_TMP) { + /* power down the PHY in case the PHY FW didn't */ + ixgbe_set_copper_phy_power(hw, false); +- return IXGBE_ERR_OVERTEMP; ++ *is_overtemp = true; ++ return -EIO; + } + } + +@@ -2462,12 +2467,12 @@ static s32 ixgbe_get_lasi_ext_t_x550em(struct ixgbe_hw *hw, bool *lsc) + **/ + static s32 ixgbe_enable_lasi_ext_t_x550em(struct ixgbe_hw *hw) + { ++ bool lsc, overtemp; + u32 status; + u16 reg; +- bool lsc; + + /* Clear interrupt flags */ +- status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc); ++ status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc, &overtemp); + + /* Enable link status change alarm */ + +@@ -2546,21 +2551,20 @@ static s32 ixgbe_enable_lasi_ext_t_x550em(struct ixgbe_hw *hw) + /** + * ixgbe_handle_lasi_ext_t_x550em - Handle external Base T PHY interrupt + * @hw: pointer to hardware structure ++ * @is_overtemp: indicate whether an overtemp event encountered + * + * Handle external Base T PHY interrupt. If high temperature + * failure alarm then return error, else if link status change + * then setup internal/external PHY link +- * +- * Return IXGBE_ERR_OVERTEMP if interrupt is high temperature +- * failure alarm, else return PHY access status. + **/ +-static s32 ixgbe_handle_lasi_ext_t_x550em(struct ixgbe_hw *hw) ++static s32 ixgbe_handle_lasi_ext_t_x550em(struct ixgbe_hw *hw, ++ bool *is_overtemp) + { + struct ixgbe_phy_info *phy = &hw->phy; + bool lsc; + u32 status; + +- status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc); ++ status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc, is_overtemp); + if (status) + return status; + +@@ -2692,7 +2696,7 @@ static s32 ixgbe_setup_internal_phy_t_x550em(struct ixgbe_hw *hw) + u16 speed; + + if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper) +- return IXGBE_ERR_CONFIG; ++ return -EIO; + + if (!(hw->mac.type == ixgbe_mac_X550EM_x && + !(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE))) { +@@ -2735,7 +2739,7 @@ static s32 ixgbe_setup_internal_phy_t_x550em(struct ixgbe_hw *hw) + break; + default: + /* Internal PHY does not support anything else */ +- return IXGBE_ERR_INVALID_LINK_SETTINGS; ++ return -EINVAL; + } + + return ixgbe_setup_ixfi_x550em(hw, &force_speed); +@@ -2767,7 +2771,7 @@ static s32 ixgbe_led_on_t_x550em(struct ixgbe_hw *hw, u32 led_idx) + u16 phy_data; + + if (led_idx >= IXGBE_X557_MAX_LED_INDEX) +- return IXGBE_ERR_PARAM; ++ return -EINVAL; + + /* To turn on the LED, set mode to ON. */ + hw->phy.ops.read_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx, +@@ -2789,7 +2793,7 @@ static s32 ixgbe_led_off_t_x550em(struct ixgbe_hw *hw, u32 led_idx) + u16 phy_data; + + if (led_idx >= IXGBE_X557_MAX_LED_INDEX) +- return IXGBE_ERR_PARAM; ++ return -EINVAL; + + /* To turn on the LED, set mode to ON. */ + hw->phy.ops.read_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx, +@@ -2813,8 +2817,9 @@ static s32 ixgbe_led_off_t_x550em(struct ixgbe_hw *hw, u32 led_idx) + * + * Sends driver version number to firmware through the manageability + * block. On success return 0 +- * else returns IXGBE_ERR_SWFW_SYNC when encountering an error acquiring +- * semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails. ++ * else returns -EBUSY when encountering an error acquiring ++ * semaphore, -EIO when command fails or -ENIVAL when incorrect ++ * params passed. + **/ + static s32 ixgbe_set_fw_drv_ver_x550(struct ixgbe_hw *hw, u8 maj, u8 min, + u8 build, u8 sub, u16 len, +@@ -2825,7 +2830,7 @@ static s32 ixgbe_set_fw_drv_ver_x550(struct ixgbe_hw *hw, u8 maj, u8 min, + int i; + + if (!len || !driver_ver || (len > sizeof(fw_cmd.driver_string))) +- return IXGBE_ERR_INVALID_ARGUMENT; ++ return -EINVAL; + + fw_cmd.hdr.cmd = FW_CEM_CMD_DRIVER_INFO; + fw_cmd.hdr.buf_len = FW_CEM_CMD_DRIVER_INFO_LEN + len; +@@ -2850,7 +2855,7 @@ static s32 ixgbe_set_fw_drv_ver_x550(struct ixgbe_hw *hw, u8 maj, u8 min, + + if (fw_cmd.hdr.cmd_or_resp.ret_status != + FW_CEM_RESP_STATUS_SUCCESS) +- return IXGBE_ERR_HOST_INTERFACE_COMMAND; ++ return -EIO; + return 0; + } + +@@ -2907,7 +2912,7 @@ static s32 ixgbe_setup_fc_x550em(struct ixgbe_hw *hw) + /* Validate the requested mode */ + if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) { + hw_err(hw, "ixgbe_fc_rx_pause not valid in strict IEEE mode\n"); +- return IXGBE_ERR_INVALID_LINK_SETTINGS; ++ return -EINVAL; + } + + /* 10gig parts do not have a word in the EEPROM to determine the +@@ -2942,7 +2947,7 @@ static s32 ixgbe_setup_fc_x550em(struct ixgbe_hw *hw) + break; + default: + hw_err(hw, "Flow control param set incorrectly\n"); +- return IXGBE_ERR_CONFIG; ++ return -EIO; + } + + switch (hw->device_id) { +@@ -2986,8 +2991,8 @@ static s32 ixgbe_setup_fc_x550em(struct ixgbe_hw *hw) + static void ixgbe_fc_autoneg_backplane_x550em_a(struct ixgbe_hw *hw) + { + u32 link_s1, lp_an_page_low, an_cntl_1; +- s32 status = IXGBE_ERR_FC_NOT_NEGOTIATED; + ixgbe_link_speed speed; ++ s32 status = -EIO; + bool link_up; + + /* AN should have completed when the cable was plugged in. +@@ -3013,7 +3018,7 @@ static void ixgbe_fc_autoneg_backplane_x550em_a(struct ixgbe_hw *hw) + + if (status || (link_s1 & IXGBE_KRM_LINK_S1_MAC_AN_COMPLETE) == 0) { + hw_dbg(hw, "Auto-Negotiation did not complete\n"); +- status = IXGBE_ERR_FC_NOT_NEGOTIATED; ++ status = -EIO; + goto out; + } + +@@ -3187,21 +3192,23 @@ static s32 ixgbe_reset_phy_fw(struct ixgbe_hw *hw) + /** + * ixgbe_check_overtemp_fw - Check firmware-controlled PHYs for overtemp + * @hw: pointer to hardware structure ++ * ++ * Return true when an overtemp event detected, otherwise false. + */ +-static s32 ixgbe_check_overtemp_fw(struct ixgbe_hw *hw) ++static bool ixgbe_check_overtemp_fw(struct ixgbe_hw *hw) + { + u32 store[FW_PHY_ACT_DATA_COUNT] = { 0 }; + s32 rc; + + rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_LINK_INFO, &store); + if (rc) +- return rc; ++ return false; + + if (store[0] & FW_PHY_ACT_GET_LINK_INFO_TEMP) { + ixgbe_shutdown_fw_phy(hw); +- return IXGBE_ERR_OVERTEMP; ++ return true; + } +- return 0; ++ return false; + } + + /** +@@ -3251,8 +3258,7 @@ static s32 ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw) + + /* Identify the PHY or SFP module */ + ret_val = phy->ops.identify(hw); +- if (ret_val == IXGBE_ERR_SFP_NOT_SUPPORTED || +- ret_val == IXGBE_ERR_PHY_ADDR_INVALID) ++ if (ret_val == -EOPNOTSUPP || ret_val == -EFAULT) + return ret_val; + + /* Setup function pointers based on detected hardware */ +@@ -3460,8 +3466,7 @@ static s32 ixgbe_reset_hw_X550em(struct ixgbe_hw *hw) + + /* PHY ops must be identified and initialized prior to reset */ + status = hw->phy.ops.init(hw); +- if (status == IXGBE_ERR_SFP_NOT_SUPPORTED || +- status == IXGBE_ERR_PHY_ADDR_INVALID) ++ if (status == -EOPNOTSUPP || status == -EFAULT) + return status; + + /* start the external PHY */ +@@ -3477,7 +3482,7 @@ static s32 ixgbe_reset_hw_X550em(struct ixgbe_hw *hw) + hw->phy.sfp_setup_needed = false; + } + +- if (status == IXGBE_ERR_SFP_NOT_SUPPORTED) ++ if (status == -EOPNOTSUPP) + return status; + + /* Reset PHY */ +@@ -3501,7 +3506,7 @@ mac_reset_top: + status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask); + if (status) { + hw_dbg(hw, "semaphore failed with %d", status); +- return IXGBE_ERR_SWFW_SYNC; ++ return -EBUSY; + } + + ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL); +@@ -3519,7 +3524,7 @@ mac_reset_top: + } + + if (ctrl & IXGBE_CTRL_RST_MASK) { +- status = IXGBE_ERR_RESET_FAILED; ++ status = -EIO; + hw_dbg(hw, "Reset polling failed to complete.\n"); + } + +@@ -3615,7 +3620,7 @@ static s32 ixgbe_setup_fc_backplane_x550em_a(struct ixgbe_hw *hw) + /* Validate the requested mode */ + if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) { + hw_err(hw, "ixgbe_fc_rx_pause not valid in strict IEEE mode\n"); +- return IXGBE_ERR_INVALID_LINK_SETTINGS; ++ return -EINVAL; + } + + if (hw->fc.requested_mode == ixgbe_fc_default) +@@ -3672,7 +3677,7 @@ static s32 ixgbe_setup_fc_backplane_x550em_a(struct ixgbe_hw *hw) + break; + default: + hw_err(hw, "Flow control param set incorrectly\n"); +- return IXGBE_ERR_CONFIG; ++ return -EIO; + } + + status = hw->mac.ops.write_iosf_sb_reg(hw, +@@ -3768,7 +3773,7 @@ static s32 ixgbe_acquire_swfw_sync_x550em_a(struct ixgbe_hw *hw, u32 mask) + return 0; + if (hmask) + ixgbe_release_swfw_sync_X540(hw, hmask); +- if (status != IXGBE_ERR_TOKEN_RETRY) ++ if (status != -EAGAIN) + return status; + msleep(FW_PHY_TOKEN_DELAY); + } +@@ -3812,7 +3817,7 @@ static s32 ixgbe_read_phy_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr, + s32 status; + + if (hw->mac.ops.acquire_swfw_sync(hw, mask)) +- return IXGBE_ERR_SWFW_SYNC; ++ return -EBUSY; + + status = hw->phy.ops.read_reg_mdi(hw, reg_addr, device_type, phy_data); + +@@ -3838,7 +3843,7 @@ static s32 ixgbe_write_phy_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr, + s32 status; + + if (hw->mac.ops.acquire_swfw_sync(hw, mask)) +- return IXGBE_ERR_SWFW_SYNC; ++ return -EBUSY; + + status = ixgbe_write_phy_reg_mdi(hw, reg_addr, device_type, phy_data); + hw->mac.ops.release_swfw_sync(hw, mask); +diff --git a/drivers/net/ethernet/marvell/mvmdio.c b/drivers/net/ethernet/marvell/mvmdio.c +index 89f26402f8fb8..5f66f779e56fc 100644 +--- a/drivers/net/ethernet/marvell/mvmdio.c ++++ b/drivers/net/ethernet/marvell/mvmdio.c +@@ -23,6 +23,7 @@ + #include <linux/delay.h> + #include <linux/interrupt.h> + #include <linux/io.h> ++#include <linux/iopoll.h> + #include <linux/kernel.h> + #include <linux/mod_devicetable.h> + #include <linux/module.h> +@@ -58,11 +59,6 @@ + * - Armada 370 (Globalscale Mirabox): 41us to 43us (Polled) + */ + #define MVMDIO_SMI_TIMEOUT 1000 /* 1000us = 1ms */ +-#define MVMDIO_SMI_POLL_INTERVAL_MIN 45 +-#define MVMDIO_SMI_POLL_INTERVAL_MAX 55 +- +-#define MVMDIO_XSMI_POLL_INTERVAL_MIN 150 +-#define MVMDIO_XSMI_POLL_INTERVAL_MAX 160 + + struct orion_mdio_dev { + void __iomem *regs; +@@ -84,8 +80,6 @@ enum orion_mdio_bus_type { + + struct orion_mdio_ops { + int (*is_done)(struct orion_mdio_dev *); +- unsigned int poll_interval_min; +- unsigned int poll_interval_max; + }; + + /* Wait for the SMI unit to be ready for another operation +@@ -94,34 +88,23 @@ static int orion_mdio_wait_ready(const struct orion_mdio_ops *ops, + struct mii_bus *bus) + { + struct orion_mdio_dev *dev = bus->priv; +- unsigned long timeout = usecs_to_jiffies(MVMDIO_SMI_TIMEOUT); +- unsigned long end = jiffies + timeout; +- int timedout = 0; ++ unsigned long timeout; ++ int done; + +- while (1) { +- if (ops->is_done(dev)) ++ if (dev->err_interrupt <= 0) { ++ if (!read_poll_timeout_atomic(ops->is_done, done, done, 2, ++ MVMDIO_SMI_TIMEOUT, false, dev)) ++ return 0; ++ } else { ++ /* wait_event_timeout does not guarantee a delay of at ++ * least one whole jiffie, so timeout must be no less ++ * than two. ++ */ ++ timeout = max(usecs_to_jiffies(MVMDIO_SMI_TIMEOUT), 2); ++ ++ if (wait_event_timeout(dev->smi_busy_wait, ++ ops->is_done(dev), timeout)) + return 0; +- else if (timedout) +- break; +- +- if (dev->err_interrupt <= 0) { +- usleep_range(ops->poll_interval_min, +- ops->poll_interval_max); +- +- if (time_is_before_jiffies(end)) +- ++timedout; +- } else { +- /* wait_event_timeout does not guarantee a delay of at +- * least one whole jiffie, so timeout must be no less +- * than two. +- */ +- if (timeout < 2) +- timeout = 2; +- wait_event_timeout(dev->smi_busy_wait, +- ops->is_done(dev), timeout); +- +- ++timedout; +- } + } + + dev_err(bus->parent, "Timeout: SMI busy for too long\n"); +@@ -135,8 +118,6 @@ static int orion_mdio_smi_is_done(struct orion_mdio_dev *dev) + + static const struct orion_mdio_ops orion_mdio_smi_ops = { + .is_done = orion_mdio_smi_is_done, +- .poll_interval_min = MVMDIO_SMI_POLL_INTERVAL_MIN, +- .poll_interval_max = MVMDIO_SMI_POLL_INTERVAL_MAX, + }; + + static int orion_mdio_smi_read(struct mii_bus *bus, int mii_id, +@@ -194,8 +175,6 @@ static int orion_mdio_xsmi_is_done(struct orion_mdio_dev *dev) + + static const struct orion_mdio_ops orion_mdio_xsmi_ops = { + .is_done = orion_mdio_xsmi_is_done, +- .poll_interval_min = MVMDIO_XSMI_POLL_INTERVAL_MIN, +- .poll_interval_max = MVMDIO_XSMI_POLL_INTERVAL_MAX, + }; + + static int orion_mdio_xsmi_read_c45(struct mii_bus *bus, int mii_id, +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c +index 0bcf3e5592806..3784347b6fd88 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c +@@ -2678,18 +2678,17 @@ int rvu_mbox_handler_npc_mcam_alloc_entry(struct rvu *rvu, + rsp->entry = NPC_MCAM_ENTRY_INVALID; + rsp->free_count = 0; + +- /* Check if ref_entry is within range */ +- if (req->priority && req->ref_entry >= mcam->bmap_entries) { +- dev_err(rvu->dev, "%s: reference entry %d is out of range\n", +- __func__, req->ref_entry); +- return NPC_MCAM_INVALID_REQ; +- } ++ /* Check if ref_entry is greater that the range ++ * then set it to max value. ++ */ ++ if (req->ref_entry > mcam->bmap_entries) ++ req->ref_entry = mcam->bmap_entries; + + /* ref_entry can't be '0' if requested priority is high. + * Can't be last entry if requested priority is low. + */ + if ((!req->ref_entry && req->priority == NPC_MCAM_HIGHER_PRIO) || +- ((req->ref_entry == (mcam->bmap_entries - 1)) && ++ ((req->ref_entry == mcam->bmap_entries) && + req->priority == NPC_MCAM_LOWER_PRIO)) + return NPC_MCAM_INVALID_REQ; + +diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c +index 53f6258a973c2..8b7fc0af91ced 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c ++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c +@@ -314,7 +314,6 @@ static int otx2_set_channels(struct net_device *dev, + pfvf->hw.tx_queues = channel->tx_count; + if (pfvf->xdp_prog) + pfvf->hw.xdp_queues = channel->rx_count; +- pfvf->hw.non_qos_queues = pfvf->hw.tx_queues + pfvf->hw.xdp_queues; + + if (if_up) + err = dev->netdev_ops->ndo_open(dev); +diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c +index a57455aebff6f..e5fe67e738655 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c ++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c +@@ -1744,6 +1744,7 @@ int otx2_open(struct net_device *netdev) + /* RQ and SQs are mapped to different CQs, + * so find out max CQ IRQs (i.e CINTs) needed. + */ ++ pf->hw.non_qos_queues = pf->hw.tx_queues + pf->hw.xdp_queues; + pf->hw.cint_cnt = max3(pf->hw.rx_queues, pf->hw.tx_queues, + pf->hw.tc_tx_queues); + +@@ -2643,8 +2644,6 @@ static int otx2_xdp_setup(struct otx2_nic *pf, struct bpf_prog *prog) + xdp_features_clear_redirect_target(dev); + } + +- pf->hw.non_qos_queues += pf->hw.xdp_queues; +- + if (if_up) + otx2_open(pf->netdev); + +diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c +index 4d519ea833b2c..f828d32737af0 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c ++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c +@@ -1403,7 +1403,7 @@ static bool otx2_xdp_rcv_pkt_handler(struct otx2_nic *pfvf, + struct otx2_cq_queue *cq, + bool *need_xdp_flush) + { +- unsigned char *hard_start, *data; ++ unsigned char *hard_start; + int qidx = cq->cq_idx; + struct xdp_buff xdp; + struct page *page; +@@ -1417,9 +1417,8 @@ static bool otx2_xdp_rcv_pkt_handler(struct otx2_nic *pfvf, + + xdp_init_buff(&xdp, pfvf->rbsize, &cq->xdp_rxq); + +- data = (unsigned char *)phys_to_virt(pa); +- hard_start = page_address(page); +- xdp_prepare_buff(&xdp, hard_start, data - hard_start, ++ hard_start = (unsigned char *)phys_to_virt(pa); ++ xdp_prepare_buff(&xdp, hard_start, OTX2_HEAD_ROOM, + cqe->sg.seg_size, false); + + act = bpf_prog_run_xdp(prog, &xdp); +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +index 3cf6589cfdacf..d2c039f830195 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -4758,7 +4758,10 @@ static int mtk_probe(struct platform_device *pdev) + } + + if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) { +- err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(36)); ++ err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(36)); ++ if (!err) ++ err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); ++ + if (err) { + dev_err(&pdev->dev, "Wrong DMA config\n"); + return -EINVAL; +diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_port.c b/drivers/net/ethernet/microchip/lan966x/lan966x_port.c +index 92108d354051c..2e83bbb9477e0 100644 +--- a/drivers/net/ethernet/microchip/lan966x/lan966x_port.c ++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_port.c +@@ -168,9 +168,10 @@ static void lan966x_port_link_up(struct lan966x_port *port) + lan966x_taprio_speed_set(port, config->speed); + + /* Also the GIGA_MODE_ENA(1) needs to be set regardless of the +- * port speed for QSGMII ports. ++ * port speed for QSGMII or SGMII ports. + */ +- if (phy_interface_num_ports(config->portmode) == 4) ++ if (phy_interface_num_ports(config->portmode) == 4 || ++ config->portmode == PHY_INTERFACE_MODE_SGMII) + mode = DEV_MAC_MODE_CFG_GIGA_MODE_ENA_SET(1); + + lan_wr(config->duplex | mode, +diff --git a/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c b/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c +index d6ce113a4210b..fa4237c27e061 100644 +--- a/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c ++++ b/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c +@@ -392,6 +392,10 @@ static void ionic_remove(struct pci_dev *pdev) + del_timer_sync(&ionic->watchdog_timer); + + if (ionic->lif) { ++ /* prevent adminq cmds if already known as down */ ++ if (test_and_clear_bit(IONIC_LIF_F_FW_RESET, ionic->lif->state)) ++ set_bit(IONIC_LIF_F_FW_STOPPING, ionic->lif->state); ++ + ionic_lif_unregister(ionic->lif); + ionic_devlink_unregister(ionic); + ionic_lif_deinit(ionic->lif); +diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.c b/drivers/net/ethernet/pensando/ionic/ionic_dev.c +index c06576f439161..22ab0a44fa8c7 100644 +--- a/drivers/net/ethernet/pensando/ionic/ionic_dev.c ++++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.c +@@ -321,6 +321,7 @@ void ionic_dev_cmd_comp(struct ionic_dev *idev, union ionic_dev_cmd_comp *comp) + + void ionic_dev_cmd_go(struct ionic_dev *idev, union ionic_dev_cmd *cmd) + { ++ idev->opcode = cmd->cmd.opcode; + memcpy_toio(&idev->dev_cmd_regs->cmd, cmd, sizeof(*cmd)); + iowrite32(0, &idev->dev_cmd_regs->done); + iowrite32(1, &idev->dev_cmd_regs->doorbell); +diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.h b/drivers/net/ethernet/pensando/ionic/ionic_dev.h +index 9b54630400752..fd112bee4dcf6 100644 +--- a/drivers/net/ethernet/pensando/ionic/ionic_dev.h ++++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.h +@@ -153,6 +153,7 @@ struct ionic_dev { + bool fw_hb_ready; + bool fw_status_ready; + u8 fw_generation; ++ u8 opcode; + + u64 __iomem *db_pages; + dma_addr_t phy_db_pages; +diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c +index bad919343180e..075e0e3fc2ea4 100644 +--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c ++++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c +@@ -3238,6 +3238,9 @@ static void ionic_lif_reset(struct ionic_lif *lif) + { + struct ionic_dev *idev = &lif->ionic->idev; + ++ if (!ionic_is_fw_running(idev)) ++ return; ++ + mutex_lock(&lif->ionic->dev_cmd_lock); + ionic_dev_cmd_lif_reset(idev, lif->index); + ionic_dev_cmd_wait(lif->ionic, DEVCMD_TIMEOUT); +diff --git a/drivers/net/ethernet/pensando/ionic/ionic_main.c b/drivers/net/ethernet/pensando/ionic/ionic_main.c +index 8355773921789..83c413a10f79a 100644 +--- a/drivers/net/ethernet/pensando/ionic/ionic_main.c ++++ b/drivers/net/ethernet/pensando/ionic/ionic_main.c +@@ -410,22 +410,28 @@ int ionic_adminq_wait(struct ionic_lif *lif, struct ionic_admin_ctx *ctx, + do_msg); + } + +-int ionic_adminq_post_wait(struct ionic_lif *lif, struct ionic_admin_ctx *ctx) ++static int __ionic_adminq_post_wait(struct ionic_lif *lif, ++ struct ionic_admin_ctx *ctx, ++ const bool do_msg) + { + int err; + ++ if (!ionic_is_fw_running(&lif->ionic->idev)) ++ return 0; ++ + err = ionic_adminq_post(lif, ctx); + +- return ionic_adminq_wait(lif, ctx, err, true); ++ return ionic_adminq_wait(lif, ctx, err, do_msg); + } + +-int ionic_adminq_post_wait_nomsg(struct ionic_lif *lif, struct ionic_admin_ctx *ctx) ++int ionic_adminq_post_wait(struct ionic_lif *lif, struct ionic_admin_ctx *ctx) + { +- int err; +- +- err = ionic_adminq_post(lif, ctx); ++ return __ionic_adminq_post_wait(lif, ctx, true); ++} + +- return ionic_adminq_wait(lif, ctx, err, false); ++int ionic_adminq_post_wait_nomsg(struct ionic_lif *lif, struct ionic_admin_ctx *ctx) ++{ ++ return __ionic_adminq_post_wait(lif, ctx, false); + } + + static void ionic_dev_cmd_clean(struct ionic *ionic) +@@ -465,7 +471,7 @@ static int __ionic_dev_cmd_wait(struct ionic *ionic, unsigned long max_seconds, + */ + max_wait = jiffies + (max_seconds * HZ); + try_again: +- opcode = readb(&idev->dev_cmd_regs->cmd.cmd.opcode); ++ opcode = idev->opcode; + start_time = jiffies; + for (fw_up = ionic_is_fw_running(idev); + !done && fw_up && time_before(jiffies, max_wait); +diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c +index 37fb033e1c29e..ef203b0807e58 100644 +--- a/drivers/net/phy/at803x.c ++++ b/drivers/net/phy/at803x.c +@@ -2104,7 +2104,7 @@ static struct phy_driver at803x_driver[] = { + .write_page = at803x_write_page, + .get_features = at803x_get_features, + .read_status = at803x_read_status, +- .config_intr = &at803x_config_intr, ++ .config_intr = at803x_config_intr, + .handle_interrupt = at803x_handle_interrupt, + .get_tunable = at803x_get_tunable, + .set_tunable = at803x_set_tunable, +@@ -2134,7 +2134,7 @@ static struct phy_driver at803x_driver[] = { + .resume = at803x_resume, + .flags = PHY_POLL_CABLE_TEST, + /* PHY_BASIC_FEATURES */ +- .config_intr = &at803x_config_intr, ++ .config_intr = at803x_config_intr, + .handle_interrupt = at803x_handle_interrupt, + .cable_test_start = at803x_cable_test_start, + .cable_test_get_status = at803x_cable_test_get_status, +@@ -2150,7 +2150,7 @@ static struct phy_driver at803x_driver[] = { + .resume = at803x_resume, + .flags = PHY_POLL_CABLE_TEST, + /* PHY_BASIC_FEATURES */ +- .config_intr = &at803x_config_intr, ++ .config_intr = at803x_config_intr, + .handle_interrupt = at803x_handle_interrupt, + .cable_test_start = at803x_cable_test_start, + .cable_test_get_status = at803x_cable_test_get_status, +diff --git a/drivers/net/phy/mediatek-ge-soc.c b/drivers/net/phy/mediatek-ge-soc.c +index 8a20d9889f105..0f3a1538a8b8e 100644 +--- a/drivers/net/phy/mediatek-ge-soc.c ++++ b/drivers/net/phy/mediatek-ge-soc.c +@@ -489,7 +489,7 @@ static int tx_r50_fill_result(struct phy_device *phydev, u16 tx_r50_cal_val, + u16 reg, val; + + if (phydev->drv->phy_id == MTK_GPHY_ID_MT7988) +- bias = -2; ++ bias = -1; + + val = clamp_val(bias + tx_r50_cal_val, 0, 63); + +@@ -705,6 +705,11 @@ restore: + static void mt798x_phy_common_finetune(struct phy_device *phydev) + { + phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); ++ /* SlvDSPreadyTime = 24, MasDSPreadyTime = 24 */ ++ __phy_write(phydev, 0x11, 0xc71); ++ __phy_write(phydev, 0x12, 0xc); ++ __phy_write(phydev, 0x10, 0x8fae); ++ + /* EnabRandUpdTrig = 1 */ + __phy_write(phydev, 0x11, 0x2f00); + __phy_write(phydev, 0x12, 0xe); +@@ -715,15 +720,56 @@ static void mt798x_phy_common_finetune(struct phy_device *phydev) + __phy_write(phydev, 0x12, 0x0); + __phy_write(phydev, 0x10, 0x83aa); + +- /* TrFreeze = 0 */ ++ /* FfeUpdGainForce = 1(Enable), FfeUpdGainForceVal = 4 */ ++ __phy_write(phydev, 0x11, 0x240); ++ __phy_write(phydev, 0x12, 0x0); ++ __phy_write(phydev, 0x10, 0x9680); ++ ++ /* TrFreeze = 0 (mt7988 default) */ + __phy_write(phydev, 0x11, 0x0); + __phy_write(phydev, 0x12, 0x0); + __phy_write(phydev, 0x10, 0x9686); + ++ /* SSTrKp100 = 5 */ ++ /* SSTrKf100 = 6 */ ++ /* SSTrKp1000Mas = 5 */ ++ /* SSTrKf1000Mas = 6 */ + /* SSTrKp1000Slv = 5 */ ++ /* SSTrKf1000Slv = 6 */ + __phy_write(phydev, 0x11, 0xbaef); + __phy_write(phydev, 0x12, 0x2e); + __phy_write(phydev, 0x10, 0x968c); ++ phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); ++} ++ ++static void mt7981_phy_finetune(struct phy_device *phydev) ++{ ++ u16 val[8] = { 0x01ce, 0x01c1, ++ 0x020f, 0x0202, ++ 0x03d0, 0x03c0, ++ 0x0013, 0x0005 }; ++ int i, k; ++ ++ /* 100M eye finetune: ++ * Keep middle level of TX MLT3 shapper as default. ++ * Only change TX MLT3 overshoot level here. ++ */ ++ for (k = 0, i = 1; i < 12; i++) { ++ if (i % 3 == 0) ++ continue; ++ phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[k++]); ++ } ++ ++ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); ++ /* ResetSyncOffset = 6 */ ++ __phy_write(phydev, 0x11, 0x600); ++ __phy_write(phydev, 0x12, 0x0); ++ __phy_write(phydev, 0x10, 0x8fc0); ++ ++ /* VgaDecRate = 1 */ ++ __phy_write(phydev, 0x11, 0x4c2a); ++ __phy_write(phydev, 0x12, 0x3e); ++ __phy_write(phydev, 0x10, 0x8fa4); + + /* MrvlTrFix100Kp = 3, MrvlTrFix100Kf = 2, + * MrvlTrFix1000Kp = 3, MrvlTrFix1000Kf = 2 +@@ -738,7 +784,7 @@ static void mt798x_phy_common_finetune(struct phy_device *phydev) + __phy_write(phydev, 0x10, 0x8ec0); + phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); + +- /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9*/ ++ /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9 */ + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234, + MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK, + BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0x9)); +@@ -771,48 +817,6 @@ static void mt798x_phy_common_finetune(struct phy_device *phydev) + phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_OUTPUT_V, 0x2222); + } + +-static void mt7981_phy_finetune(struct phy_device *phydev) +-{ +- u16 val[8] = { 0x01ce, 0x01c1, +- 0x020f, 0x0202, +- 0x03d0, 0x03c0, +- 0x0013, 0x0005 }; +- int i, k; +- +- /* 100M eye finetune: +- * Keep middle level of TX MLT3 shapper as default. +- * Only change TX MLT3 overshoot level here. +- */ +- for (k = 0, i = 1; i < 12; i++) { +- if (i % 3 == 0) +- continue; +- phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[k++]); +- } +- +- phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); +- /* SlvDSPreadyTime = 24, MasDSPreadyTime = 24 */ +- __phy_write(phydev, 0x11, 0xc71); +- __phy_write(phydev, 0x12, 0xc); +- __phy_write(phydev, 0x10, 0x8fae); +- +- /* ResetSyncOffset = 6 */ +- __phy_write(phydev, 0x11, 0x600); +- __phy_write(phydev, 0x12, 0x0); +- __phy_write(phydev, 0x10, 0x8fc0); +- +- /* VgaDecRate = 1 */ +- __phy_write(phydev, 0x11, 0x4c2a); +- __phy_write(phydev, 0x12, 0x3e); +- __phy_write(phydev, 0x10, 0x8fa4); +- +- /* FfeUpdGainForce = 4 */ +- __phy_write(phydev, 0x11, 0x240); +- __phy_write(phydev, 0x12, 0x0); +- __phy_write(phydev, 0x10, 0x9680); +- +- phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); +-} +- + static void mt7988_phy_finetune(struct phy_device *phydev) + { + u16 val[12] = { 0x0187, 0x01cd, 0x01c8, 0x0182, +@@ -827,17 +831,7 @@ static void mt7988_phy_finetune(struct phy_device *phydev) + /* TCT finetune */ + phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_TX_FILTER, 0x5); + +- /* Disable TX power saving */ +- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7, +- MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8); +- + phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); +- +- /* SlvDSPreadyTime = 24, MasDSPreadyTime = 12 */ +- __phy_write(phydev, 0x11, 0x671); +- __phy_write(phydev, 0x12, 0xc); +- __phy_write(phydev, 0x10, 0x8fae); +- + /* ResetSyncOffset = 5 */ + __phy_write(phydev, 0x11, 0x500); + __phy_write(phydev, 0x12, 0x0); +@@ -845,13 +839,27 @@ static void mt7988_phy_finetune(struct phy_device *phydev) + + /* VgaDecRate is 1 at default on mt7988 */ + +- phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); ++ /* MrvlTrFix100Kp = 6, MrvlTrFix100Kf = 7, ++ * MrvlTrFix1000Kp = 6, MrvlTrFix1000Kf = 7 ++ */ ++ __phy_write(phydev, 0x11, 0xb90a); ++ __phy_write(phydev, 0x12, 0x6f); ++ __phy_write(phydev, 0x10, 0x8f82); ++ ++ /* RemAckCntLimitCtrl = 1 */ ++ __phy_write(phydev, 0x11, 0xfbba); ++ __phy_write(phydev, 0x12, 0xc3); ++ __phy_write(phydev, 0x10, 0x87f8); + +- phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_2A30); +- /* TxClkOffset = 2 */ +- __phy_modify(phydev, MTK_PHY_ANARG_RG, MTK_PHY_TCLKOFFSET_MASK, +- FIELD_PREP(MTK_PHY_TCLKOFFSET_MASK, 0x2)); + phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); ++ ++ /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 10 */ ++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234, ++ MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK, ++ BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0xa)); ++ ++ /* rg_tr_lpf_cnt_val = 1023 */ ++ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x3ff); + } + + static void mt798x_phy_eee(struct phy_device *phydev) +@@ -884,11 +892,11 @@ static void mt798x_phy_eee(struct phy_device *phydev) + MTK_PHY_LPI_SLV_SEND_TX_EN, + FIELD_PREP(MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK, 0x120)); + +- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG239, +- MTK_PHY_LPI_SEND_LOC_TIMER_MASK | +- MTK_PHY_LPI_TXPCS_LOC_RCV, +- FIELD_PREP(MTK_PHY_LPI_SEND_LOC_TIMER_MASK, 0x117)); ++ /* Keep MTK_PHY_LPI_SEND_LOC_TIMER as 375 */ ++ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG239, ++ MTK_PHY_LPI_TXPCS_LOC_RCV); + ++ /* This also fixes some IoT issues, such as CH340 */ + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG2C7, + MTK_PHY_MAX_GAIN_MASK | MTK_PHY_MIN_GAIN_MASK, + FIELD_PREP(MTK_PHY_MAX_GAIN_MASK, 0x8) | +@@ -922,7 +930,7 @@ static void mt798x_phy_eee(struct phy_device *phydev) + __phy_write(phydev, 0x12, 0x0); + __phy_write(phydev, 0x10, 0x9690); + +- /* REG_EEE_st2TrKf1000 = 3 */ ++ /* REG_EEE_st2TrKf1000 = 2 */ + __phy_write(phydev, 0x11, 0x114f); + __phy_write(phydev, 0x12, 0x2); + __phy_write(phydev, 0x10, 0x969a); +@@ -947,7 +955,7 @@ static void mt798x_phy_eee(struct phy_device *phydev) + __phy_write(phydev, 0x12, 0x0); + __phy_write(phydev, 0x10, 0x96b8); + +- /* REGEEE_wake_slv_tr_wait_dfesigdet_en = 1 */ ++ /* REGEEE_wake_slv_tr_wait_dfesigdet_en = 0 */ + __phy_write(phydev, 0x11, 0x1463); + __phy_write(phydev, 0x12, 0x0); + __phy_write(phydev, 0x10, 0x96ca); +@@ -1459,6 +1467,13 @@ static int mt7988_phy_probe(struct phy_device *phydev) + if (err) + return err; + ++ /* Disable TX power saving at probing to: ++ * 1. Meet common mode compliance test criteria ++ * 2. Make sure that TX-VCM calibration works fine ++ */ ++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7, ++ MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8); ++ + return mt798x_phy_calibration(phydev); + } + +diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c +index 858175ca58cd8..ca2db4adcb35c 100644 +--- a/drivers/net/phy/micrel.c ++++ b/drivers/net/phy/micrel.c +@@ -3650,12 +3650,8 @@ static int lan8841_ts_info(struct mii_timestamper *mii_ts, + + info->phc_index = ptp_priv->ptp_clock ? + ptp_clock_index(ptp_priv->ptp_clock) : -1; +- if (info->phc_index == -1) { +- info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE | +- SOF_TIMESTAMPING_RX_SOFTWARE | +- SOF_TIMESTAMPING_SOFTWARE; ++ if (info->phc_index == -1) + return 0; +- } + + info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE | + SOF_TIMESTAMPING_RX_HARDWARE | +diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c +index 5a1bf42ce1566..d837c18874161 100644 +--- a/drivers/net/usb/ax88179_178a.c ++++ b/drivers/net/usb/ax88179_178a.c +@@ -1315,8 +1315,6 @@ static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf) + + netif_set_tso_max_size(dev->net, 16384); + +- ax88179_reset(dev); +- + return 0; + } + +diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c +index 51b1868d2f220..1caf21fd5032c 100644 +--- a/drivers/net/virtio_net.c ++++ b/drivers/net/virtio_net.c +@@ -4096,10 +4096,11 @@ static int virtnet_find_vqs(struct virtnet_info *vi) + { + vq_callback_t **callbacks; + struct virtqueue **vqs; +- int ret = -ENOMEM; +- int i, total_vqs; + const char **names; ++ int ret = -ENOMEM; ++ int total_vqs; + bool *ctx; ++ u16 i; + + /* We expect 1 RX virtqueue followed by 1 TX virtqueue, followed by + * possible N-1 RX/TX queue pairs used in multiqueue mode, followed by +@@ -4136,8 +4137,8 @@ static int virtnet_find_vqs(struct virtnet_info *vi) + for (i = 0; i < vi->max_queue_pairs; i++) { + callbacks[rxq2vq(i)] = skb_recv_done; + callbacks[txq2vq(i)] = skb_xmit_done; +- sprintf(vi->rq[i].name, "input.%d", i); +- sprintf(vi->sq[i].name, "output.%d", i); ++ sprintf(vi->rq[i].name, "input.%u", i); ++ sprintf(vi->sq[i].name, "output.%u", i); + names[rxq2vq(i)] = vi->rq[i].name; + names[txq2vq(i)] = vi->sq[i].name; + if (ctx) +diff --git a/drivers/net/wireless/ath/ath11k/pcic.c b/drivers/net/wireless/ath/ath11k/pcic.c +index 16d1e332193f0..e602d4130105f 100644 +--- a/drivers/net/wireless/ath/ath11k/pcic.c ++++ b/drivers/net/wireless/ath/ath11k/pcic.c +@@ -460,8 +460,6 @@ void ath11k_pcic_ext_irq_enable(struct ath11k_base *ab) + { + int i; + +- set_bit(ATH11K_FLAG_EXT_IRQ_ENABLED, &ab->dev_flags); +- + for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) { + struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; + +@@ -471,6 +469,8 @@ void ath11k_pcic_ext_irq_enable(struct ath11k_base *ab) + } + ath11k_pcic_ext_grp_enable(irq_grp); + } ++ ++ set_bit(ATH11K_FLAG_EXT_IRQ_ENABLED, &ab->dev_flags); + } + EXPORT_SYMBOL(ath11k_pcic_ext_irq_enable); + +diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c +index eca86fc25a608..b896dfe66dad3 100644 +--- a/drivers/net/wireless/ath/ath12k/hal.c ++++ b/drivers/net/wireless/ath/ath12k/hal.c +@@ -889,8 +889,8 @@ static u8 *ath12k_hw_wcn7850_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) + + static bool ath12k_hw_wcn7850_rx_desc_is_da_mcbc(struct hal_rx_desc *desc) + { +- return __le16_to_cpu(desc->u.wcn7850.msdu_end.info5) & +- RX_MSDU_END_INFO5_DA_IS_MCBC; ++ return __le32_to_cpu(desc->u.wcn7850.msdu_end.info13) & ++ RX_MSDU_END_INFO13_MCAST_BCAST; + } + + static void ath12k_hw_wcn7850_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc, +diff --git a/drivers/net/wireless/ath/ath12k/hw.c b/drivers/net/wireless/ath/ath12k/hw.c +index 2245fb510ba2c..b55cf33e37bd8 100644 +--- a/drivers/net/wireless/ath/ath12k/hw.c ++++ b/drivers/net/wireless/ath/ath12k/hw.c +@@ -949,7 +949,8 @@ static const struct ath12k_hw_params ath12k_hw_params[] = { + .rx_mac_buf_ring = true, + .vdev_start_delay = true, + +- .interface_modes = BIT(NL80211_IFTYPE_STATION), ++ .interface_modes = BIT(NL80211_IFTYPE_STATION) | ++ BIT(NL80211_IFTYPE_AP), + .supports_monitor = false, + + .idle_ps = true, +diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c +index fc0d14ea328e6..b698e55a5b7bf 100644 +--- a/drivers/net/wireless/ath/ath12k/mac.c ++++ b/drivers/net/wireless/ath/ath12k/mac.c +@@ -6380,8 +6380,8 @@ ath12k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, + } + + if (ab->hw_params->vdev_start_delay && +- (arvif->vdev_type == WMI_VDEV_TYPE_AP || +- arvif->vdev_type == WMI_VDEV_TYPE_MONITOR)) { ++ arvif->vdev_type != WMI_VDEV_TYPE_AP && ++ arvif->vdev_type != WMI_VDEV_TYPE_MONITOR) { + param.vdev_id = arvif->vdev_id; + param.peer_type = WMI_PEER_TYPE_DEFAULT; + param.peer_addr = ar->mac_addr; +diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +index 800177021baff..efcaeccb055aa 100644 +--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c ++++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +@@ -652,9 +652,10 @@ void ath9k_htc_txstatus(struct ath9k_htc_priv *priv, void *wmi_event) + struct ath9k_htc_tx_event *tx_pend; + int i; + +- for (i = 0; i < txs->cnt; i++) { +- WARN_ON(txs->cnt > HTC_MAX_TX_STATUS); ++ if (WARN_ON_ONCE(txs->cnt > HTC_MAX_TX_STATUS)) ++ return; + ++ for (i = 0; i < txs->cnt; i++) { + __txs = &txs->txstatus[i]; + + skb = ath9k_htc_tx_get_packet(priv, __txs); +diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c +index ae6bf3c968dfb..b475555097ff2 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c +@@ -1359,7 +1359,7 @@ u8 mt76_connac_get_phy_mode_ext(struct mt76_phy *phy, struct ieee80211_vif *vif, + sband = phy->hw->wiphy->bands[band]; + eht_cap = ieee80211_get_eht_iftype_cap(sband, vif->type); + +- if (!eht_cap || !eht_cap->has_eht) ++ if (!eht_cap || !eht_cap->has_eht || !vif->bss_conf.eht_support) + return mode; + + switch (band) { +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/pci.c b/drivers/net/wireless/mediatek/mt76/mt7996/pci.c +index c5301050ff8b3..67c015896243f 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/pci.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/pci.c +@@ -17,11 +17,13 @@ static u32 hif_idx; + + static const struct pci_device_id mt7996_pci_device_table[] = { + { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7990) }, ++ { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7992) }, + { }, + }; + + static const struct pci_device_id mt7996_hif_device_table[] = { + { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7991) }, ++ { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x799a) }, + { }, + }; + +@@ -60,7 +62,9 @@ static void mt7996_put_hif2(struct mt7996_hif *hif) + static struct mt7996_hif *mt7996_pci_init_hif2(struct pci_dev *pdev) + { + hif_idx++; +- if (!pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x7991, NULL)) ++ ++ if (!pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x7991, NULL) && ++ !pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x799a, NULL)) + return NULL; + + writel(hif_idx | MT_PCIE_RECOG_ID_SEM, +@@ -113,7 +117,7 @@ static int mt7996_pci_probe(struct pci_dev *pdev, + + mt76_pci_disable_aspm(pdev); + +- if (id->device == 0x7991) ++ if (id->device == 0x7991 || id->device == 0x799a) + return mt7996_pci_hif2_probe(pdev); + + dev = mt7996_mmio_probe(&pdev->dev, pcim_iomap_table(pdev)[0], +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +index ee880f749b3c6..1926ffdffb4f0 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -8659,7 +8659,7 @@ static void rt2800_rxdcoc_calibration(struct rt2x00_dev *rt2x00dev) + rt2800_rfcsr_write_bank(rt2x00dev, 5, 4, saverfb5r4); + rt2800_rfcsr_write_bank(rt2x00dev, 7, 4, saverfb7r4); + +- rt2800_bbp_write(rt2x00dev, 158, 141); ++ rt2800_bbp_write(rt2x00dev, 158, 140); + bbpreg = rt2800_bbp_read(rt2x00dev, 159); + bbpreg = bbpreg & (~0x40); + rt2800_bbp_write(rt2x00dev, 159, bbpreg); +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +index c88ce446e1175..9e7d9dbe954cf 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +@@ -101,6 +101,7 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev) + rt2x00link_stop_tuner(rt2x00dev); + rt2x00queue_stop_queues(rt2x00dev); + rt2x00queue_flush_queues(rt2x00dev, true); ++ rt2x00queue_stop_queue(rt2x00dev->bcn); + + /* + * Disable radio. +@@ -1286,6 +1287,7 @@ int rt2x00lib_start(struct rt2x00_dev *rt2x00dev) + rt2x00dev->intf_ap_count = 0; + rt2x00dev->intf_sta_count = 0; + rt2x00dev->intf_associated = 0; ++ rt2x00dev->intf_beaconing = 0; + + /* Enable the radio */ + retval = rt2x00lib_enable_radio(rt2x00dev); +@@ -1312,6 +1314,7 @@ void rt2x00lib_stop(struct rt2x00_dev *rt2x00dev) + rt2x00dev->intf_ap_count = 0; + rt2x00dev->intf_sta_count = 0; + rt2x00dev->intf_associated = 0; ++ rt2x00dev->intf_beaconing = 0; + } + + static inline void rt2x00lib_set_if_combinations(struct rt2x00_dev *rt2x00dev) +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c b/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c +index 4202c65177839..75fda72c14ca9 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c +@@ -598,6 +598,17 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, + */ + if (changes & BSS_CHANGED_BEACON_ENABLED) { + mutex_lock(&intf->beacon_skb_mutex); ++ ++ /* ++ * Clear the 'enable_beacon' flag and clear beacon because ++ * the beacon queue has been stopped after hardware reset. ++ */ ++ if (test_bit(DEVICE_STATE_RESET, &rt2x00dev->flags) && ++ intf->enable_beacon) { ++ intf->enable_beacon = false; ++ rt2x00queue_clear_beacon(rt2x00dev, vif); ++ } ++ + if (!bss_conf->enable_beacon && intf->enable_beacon) { + rt2x00dev->intf_beaconing--; + intf->enable_beacon = false; +diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +index 43ee7592bc6e1..180907319e8cd 100644 +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +@@ -7961,6 +7961,18 @@ static const struct usb_device_id dev_table[] = { + .driver_info = (unsigned long)&rtl8192eu_fops}, + {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x818c, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192eu_fops}, ++/* D-Link DWA-131 rev C1 */ ++{USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3312, 0xff, 0xff, 0xff), ++ .driver_info = (unsigned long)&rtl8192eu_fops}, ++/* TP-Link TL-WN8200ND V2 */ ++{USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0126, 0xff, 0xff, 0xff), ++ .driver_info = (unsigned long)&rtl8192eu_fops}, ++/* Mercusys MW300UM */ ++{USB_DEVICE_AND_INTERFACE_INFO(0x2c4e, 0x0100, 0xff, 0xff, 0xff), ++ .driver_info = (unsigned long)&rtl8192eu_fops}, ++/* Mercusys MW300UH */ ++{USB_DEVICE_AND_INTERFACE_INFO(0x2c4e, 0x0104, 0xff, 0xff, 0xff), ++ .driver_info = (unsigned long)&rtl8192eu_fops}, + #endif + { } + }; +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/phy.c +index fe9b407dc2aff..71e29b103da5a 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/phy.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/phy.c +@@ -49,7 +49,7 @@ u32 rtl8723e_phy_query_rf_reg(struct ieee80211_hw *hw, + rfpath, regaddr); + } + +- bitshift = rtl8723_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + readback_value = (original_value & bitmask) >> bitshift; + + spin_unlock(&rtlpriv->locks.rf_lock); +@@ -80,7 +80,7 @@ void rtl8723e_phy_set_rf_reg(struct ieee80211_hw *hw, + original_value = rtl8723_phy_rf_serial_read(hw, + rfpath, + regaddr); +- bitshift = rtl8723_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + data = + ((original_value & (~bitmask)) | + (data << bitshift)); +@@ -89,7 +89,7 @@ void rtl8723e_phy_set_rf_reg(struct ieee80211_hw *hw, + rtl8723_phy_rf_serial_write(hw, rfpath, regaddr, data); + } else { + if (bitmask != RFREG_OFFSET_MASK) { +- bitshift = rtl8723_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + data = + ((original_value & (~bitmask)) | + (data << bitshift)); +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/phy.c +index 2b9313cb93dbd..094cb36153f5a 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/phy.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/phy.c +@@ -41,7 +41,7 @@ u32 rtl8723be_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, + spin_lock(&rtlpriv->locks.rf_lock); + + original_value = rtl8723_phy_rf_serial_read(hw, rfpath, regaddr); +- bitshift = rtl8723_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + readback_value = (original_value & bitmask) >> bitshift; + + spin_unlock(&rtlpriv->locks.rf_lock); +@@ -68,7 +68,7 @@ void rtl8723be_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path path, + if (bitmask != RFREG_OFFSET_MASK) { + original_value = rtl8723_phy_rf_serial_read(hw, path, + regaddr); +- bitshift = rtl8723_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + data = ((original_value & (~bitmask)) | + (data << bitshift)); + } +diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c +index bdcc172639e4e..ace7bbf2cf943 100644 +--- a/drivers/net/wireless/realtek/rtw89/coex.c ++++ b/drivers/net/wireless/realtek/rtw89/coex.c +@@ -131,7 +131,7 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = { + .fcxbtcrpt = 105, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 5, + .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 2, .fcxgpiodbg = 1, + .fcxbtver = 1, .fcxbtscan = 2, .fcxbtafh = 2, .fcxbtdevinfo = 1, +- .fwlrole = 1, .frptmap = 3, .fcxctrl = 1, ++ .fwlrole = 2, .frptmap = 3, .fcxctrl = 1, + .info_buf = 1800, .max_role_num = 6, + }, + {RTL8852C, RTW89_FW_VER_CODE(0, 27, 57, 0), +@@ -159,7 +159,7 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = { + .fcxbtcrpt = 105, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 5, + .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 2, .fcxgpiodbg = 1, + .fcxbtver = 1, .fcxbtscan = 2, .fcxbtafh = 2, .fcxbtdevinfo = 1, +- .fwlrole = 1, .frptmap = 3, .fcxctrl = 1, ++ .fwlrole = 2, .frptmap = 3, .fcxctrl = 1, + .info_buf = 1800, .max_role_num = 6, + }, + {RTL8852B, RTW89_FW_VER_CODE(0, 29, 14, 0), +diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c +index 3d75165e48bea..a3624ebf01b78 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.c ++++ b/drivers/net/wireless/realtek/rtw89/core.c +@@ -2886,7 +2886,7 @@ void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) + + if (hw->conf.flags & IEEE80211_CONF_IDLE) + ieee80211_queue_delayed_work(hw, &roc->roc_work, +- RTW89_ROC_IDLE_TIMEOUT); ++ msecs_to_jiffies(RTW89_ROC_IDLE_TIMEOUT)); + } + + void rtw89_roc_work(struct work_struct *work) +diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h +index 91e4d4e79eeaf..8f59461e58f23 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.h ++++ b/drivers/net/wireless/realtek/rtw89/core.h +@@ -2294,12 +2294,6 @@ struct rtw89_btc_fbtc_fddt_cell_status { + u8 state_phase; /* [0:3] train state, [4:7] train phase */ + } __packed; + +-struct rtw89_btc_fbtc_fddt_cell_status_v5 { +- s8 wl_tx_pwr; +- s8 bt_tx_pwr; +- s8 bt_rx_gain; +-} __packed; +- + struct rtw89_btc_fbtc_cysta_v3 { /* statistics for cycles */ + u8 fver; + u8 rsvd; +@@ -2363,9 +2357,9 @@ struct rtw89_btc_fbtc_cysta_v5 { /* statistics for cycles */ + struct rtw89_btc_fbtc_cycle_a2dp_empty_info a2dp_ept; + struct rtw89_btc_fbtc_a2dp_trx_stat_v4 a2dp_trx[BTC_CYCLE_SLOT_MAX]; + struct rtw89_btc_fbtc_cycle_fddt_info_v5 fddt_trx[BTC_CYCLE_SLOT_MAX]; +- struct rtw89_btc_fbtc_fddt_cell_status_v5 fddt_cells[FDD_TRAIN_WL_DIRECTION] +- [FDD_TRAIN_WL_RSSI_LEVEL] +- [FDD_TRAIN_BT_RSSI_LEVEL]; ++ struct rtw89_btc_fbtc_fddt_cell_status fddt_cells[FDD_TRAIN_WL_DIRECTION] ++ [FDD_TRAIN_WL_RSSI_LEVEL] ++ [FDD_TRAIN_BT_RSSI_LEVEL]; + __le32 except_map; + } __packed; + +diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c +index a732c22a2d549..313ed4c45464b 100644 +--- a/drivers/net/wireless/realtek/rtw89/fw.c ++++ b/drivers/net/wireless/realtek/rtw89/fw.c +@@ -4043,6 +4043,7 @@ void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, + rtw89_core_scan_complete(rtwdev, vif, true); + ieee80211_scan_completed(rtwdev->hw, &info); + ieee80211_wake_queues(rtwdev->hw); ++ rtw89_mac_enable_beacon_for_ap_vifs(rtwdev, true); + + rtw89_release_pkt_list(rtwdev); + rtwvif = (struct rtw89_vif *)vif->drv_priv; +@@ -4060,6 +4061,19 @@ void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif) + rtw89_hw_scan_complete(rtwdev, vif, true); + } + ++static bool rtw89_is_any_vif_connected_or_connecting(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_vif *rtwvif; ++ ++ rtw89_for_each_rtwvif(rtwdev, rtwvif) { ++ /* This variable implies connected or during attempt to connect */ ++ if (!is_zero_ether_addr(rtwvif->bssid)) ++ return true; ++ } ++ ++ return false; ++} ++ + int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, + bool enable) + { +@@ -4072,8 +4086,7 @@ int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, + if (!rtwvif) + return -EINVAL; + +- /* This variable implies connected or during attempt to connect */ +- connected = !is_zero_ether_addr(rtwvif->bssid); ++ connected = rtw89_is_any_vif_connected_or_connecting(rtwdev); + opt.enable = enable; + opt.target_ch_mode = connected; + if (enable) { +diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c +index 0c5768f41d55d..d0c7de4e80dcf 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac.c ++++ b/drivers/net/wireless/realtek/rtw89/mac.c +@@ -3747,6 +3747,50 @@ static const struct rtw89_port_reg rtw89_port_base_ax = { + R_AX_PORT_HGQ_WINDOW_CFG + 3}, + }; + ++static void rtw89_mac_check_packet_ctrl(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif, u8 type) ++{ ++ u8 mask = B_AX_PTCL_DBG_INFO_MASK_BY_PORT(rtwvif->port); ++ u32 reg_info, reg_ctrl; ++ u32 val; ++ int ret; ++ ++ reg_info = rtw89_mac_reg_by_idx(rtwdev, R_AX_PTCL_DBG_INFO, rtwvif->mac_idx); ++ reg_ctrl = rtw89_mac_reg_by_idx(rtwdev, R_AX_PTCL_DBG, rtwvif->mac_idx); ++ ++ rtw89_write32_mask(rtwdev, reg_ctrl, B_AX_PTCL_DBG_SEL_MASK, type); ++ rtw89_write32_set(rtwdev, reg_ctrl, B_AX_PTCL_DBG_EN); ++ fsleep(100); ++ ++ ret = read_poll_timeout(rtw89_read32_mask, val, val == 0, 1000, 100000, ++ true, rtwdev, reg_info, mask); ++ if (ret) ++ rtw89_warn(rtwdev, "Polling beacon packet empty fail\n"); ++} ++ ++static void rtw89_mac_bcn_drop(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) ++{ ++ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; ++ const struct rtw89_port_reg *p = mac->port_base; ++ ++ rtw89_write32_set(rtwdev, R_AX_BCN_DROP_ALL0, BIT(rtwvif->port)); ++ rtw89_write32_port_mask(rtwdev, rtwvif, p->tbtt_prohib, B_AX_TBTT_SETUP_MASK, 1); ++ rtw89_write32_port_mask(rtwdev, rtwvif, p->bcn_area, B_AX_BCN_MSK_AREA_MASK, 0); ++ rtw89_write32_port_mask(rtwdev, rtwvif, p->tbtt_prohib, B_AX_TBTT_HOLD_MASK, 0); ++ rtw89_write32_port_mask(rtwdev, rtwvif, p->bcn_early, B_AX_BCNERLY_MASK, 2); ++ rtw89_write16_port_mask(rtwdev, rtwvif, p->tbtt_early, B_AX_TBTTERLY_MASK, 1); ++ rtw89_write32_port_mask(rtwdev, rtwvif, p->bcn_space, B_AX_BCN_SPACE_MASK, 1); ++ rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_BCNTX_EN); ++ ++ rtw89_mac_check_packet_ctrl(rtwdev, rtwvif, AX_PTCL_DBG_BCNQ_NUM0); ++ if (rtwvif->port == RTW89_PORT_0) ++ rtw89_mac_check_packet_ctrl(rtwdev, rtwvif, AX_PTCL_DBG_BCNQ_NUM1); ++ ++ rtw89_write32_clr(rtwdev, R_AX_BCN_DROP_ALL0, BIT(rtwvif->port)); ++ rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_TBTT_PROHIB_EN); ++ fsleep(2); ++} ++ + #define BCN_INTERVAL 100 + #define BCN_ERLY_DEF 160 + #define BCN_SETUP_DEF 2 +@@ -3762,21 +3806,36 @@ static void rtw89_mac_port_cfg_func_sw(struct rtw89_dev *rtwdev, + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_port_reg *p = mac->port_base; + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ bool need_backup = false; ++ u32 backup_val; + + if (!rtw89_read32_port_mask(rtwdev, rtwvif, p->port_cfg, B_AX_PORT_FUNC_EN)) + return; + +- rtw89_write32_port_clr(rtwdev, rtwvif, p->tbtt_prohib, B_AX_TBTT_SETUP_MASK); +- rtw89_write32_port_mask(rtwdev, rtwvif, p->tbtt_prohib, B_AX_TBTT_HOLD_MASK, 1); +- rtw89_write16_port_clr(rtwdev, rtwvif, p->tbtt_early, B_AX_TBTTERLY_MASK); +- rtw89_write16_port_clr(rtwdev, rtwvif, p->bcn_early, B_AX_BCNERLY_MASK); ++ if (chip->chip_id == RTL8852A && rtwvif->port != RTW89_PORT_0) { ++ need_backup = true; ++ backup_val = rtw89_read32_port(rtwdev, rtwvif, p->tbtt_prohib); ++ } + +- msleep(vif->bss_conf.beacon_int + 1); ++ if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE) ++ rtw89_mac_bcn_drop(rtwdev, rtwvif); + ++ if (chip->chip_id == RTL8852A) { ++ rtw89_write32_port_clr(rtwdev, rtwvif, p->tbtt_prohib, B_AX_TBTT_SETUP_MASK); ++ rtw89_write32_port_mask(rtwdev, rtwvif, p->tbtt_prohib, B_AX_TBTT_HOLD_MASK, 1); ++ rtw89_write16_port_clr(rtwdev, rtwvif, p->tbtt_early, B_AX_TBTTERLY_MASK); ++ rtw89_write16_port_clr(rtwdev, rtwvif, p->bcn_early, B_AX_BCNERLY_MASK); ++ } ++ ++ msleep(vif->bss_conf.beacon_int + 1); + rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_PORT_FUNC_EN | + B_AX_BRK_SETUP); + rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_TSFTR_RST); + rtw89_write32_port(rtwdev, rtwvif, p->bcn_cnt_tmr, 0); ++ ++ if (need_backup) ++ rtw89_write32_port(rtwdev, rtwvif, p->tbtt_prohib, backup_val); + } + + static void rtw89_mac_port_cfg_tx_rpt(struct rtw89_dev *rtwdev, +@@ -3857,12 +3916,10 @@ static void rtw89_mac_port_cfg_rx_sync(struct rtw89_dev *rtwdev, + } + + static void rtw89_mac_port_cfg_tx_sw(struct rtw89_dev *rtwdev, +- struct rtw89_vif *rtwvif) ++ struct rtw89_vif *rtwvif, bool en) + { + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_port_reg *p = mac->port_base; +- bool en = rtwvif->net_type == RTW89_NET_TYPE_AP_MODE || +- rtwvif->net_type == RTW89_NET_TYPE_AD_HOC; + + if (en) + rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_BCNTX_EN); +@@ -3870,6 +3927,24 @@ static void rtw89_mac_port_cfg_tx_sw(struct rtw89_dev *rtwdev, + rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_BCNTX_EN); + } + ++static void rtw89_mac_port_cfg_tx_sw_by_nettype(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif) ++{ ++ bool en = rtwvif->net_type == RTW89_NET_TYPE_AP_MODE || ++ rtwvif->net_type == RTW89_NET_TYPE_AD_HOC; ++ ++ rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif, en); ++} ++ ++void rtw89_mac_enable_beacon_for_ap_vifs(struct rtw89_dev *rtwdev, bool en) ++{ ++ struct rtw89_vif *rtwvif; ++ ++ rtw89_for_each_rtwvif(rtwdev, rtwvif) ++ if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE) ++ rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif, en); ++} ++ + static void rtw89_mac_port_cfg_bcn_intv(struct rtw89_dev *rtwdev, + struct rtw89_vif *rtwvif) + { +@@ -4176,7 +4251,7 @@ int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) + rtw89_mac_port_cfg_bcn_prct(rtwdev, rtwvif); + rtw89_mac_port_cfg_rx_sw(rtwdev, rtwvif); + rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif); +- rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif); ++ rtw89_mac_port_cfg_tx_sw_by_nettype(rtwdev, rtwvif); + rtw89_mac_port_cfg_bcn_intv(rtwdev, rtwvif); + rtw89_mac_port_cfg_hiq_win(rtwdev, rtwvif); + rtw89_mac_port_cfg_hiq_dtim(rtwdev, rtwvif); +@@ -4261,7 +4336,7 @@ void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev, + + void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) + { +- rtw89_mac_port_cfg_func_en(rtwdev, rtwvif, false); ++ rtw89_mac_port_cfg_func_sw(rtwdev, rtwvif); + } + + int rtw89_mac_add_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) +@@ -4338,8 +4413,10 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *c2h, + + switch (reason) { + case RTW89_SCAN_LEAVE_CH_NOTIFY: +- if (rtw89_is_op_chan(rtwdev, band, chan)) ++ if (rtw89_is_op_chan(rtwdev, band, chan)) { ++ rtw89_mac_enable_beacon_for_ap_vifs(rtwdev, false); + ieee80211_stop_queues(rtwdev->hw); ++ } + return; + case RTW89_SCAN_END_SCAN_NOTIFY: + if (rtwvif && rtwvif->scan_req && +@@ -4357,6 +4434,7 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *c2h, + if (rtw89_is_op_chan(rtwdev, band, chan)) { + rtw89_assign_entity_chan(rtwdev, rtwvif->sub_entity_idx, + &rtwdev->scan_info.op_chan); ++ rtw89_mac_enable_beacon_for_ap_vifs(rtwdev, true); + ieee80211_wake_queues(rtwdev->hw); + } else { + rtw89_chan_create(&new, chan, chan, band, +diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h +index c11c904f87fe2..f9fef678f314d 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac.h ++++ b/drivers/net/wireless/realtek/rtw89/mac.h +@@ -992,6 +992,7 @@ int rtw89_mac_port_get_tsf(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, + void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev, + struct ieee80211_vif *vif); + void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); ++void rtw89_mac_enable_beacon_for_ap_vifs(struct rtw89_dev *rtwdev, bool en); + int rtw89_mac_remove_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *vif); + int rtw89_mac_enable_bb_rf(struct rtw89_dev *rtwdev); + int rtw89_mac_disable_bb_rf(struct rtw89_dev *rtwdev); +diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c +index 31d1f78916751..b7ceaf5595ebe 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac80211.c ++++ b/drivers/net/wireless/realtek/rtw89/mac80211.c +@@ -477,6 +477,9 @@ static int rtw89_ops_start_ap(struct ieee80211_hw *hw, + return -EOPNOTSUPP; + } + ++ if (rtwdev->scanning) ++ rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif); ++ + ether_addr_copy(rtwvif->bssid, vif->bss_conf.bssid); + rtw89_cam_bssid_changed(rtwdev, rtwvif); + rtw89_mac_port_update(rtwdev, rtwvif); +diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h +index ccd5481e8a3dc..672010b9e026b 100644 +--- a/drivers/net/wireless/realtek/rtw89/reg.h ++++ b/drivers/net/wireless/realtek/rtw89/reg.h +@@ -2375,6 +2375,14 @@ + #define R_AX_TSFTR_HIGH_P4 0xC53C + #define B_AX_TSFTR_HIGH_MASK GENMASK(31, 0) + ++#define R_AX_BCN_DROP_ALL0 0xC560 ++#define R_AX_BCN_DROP_ALL0_C1 0xE560 ++#define B_AX_BCN_DROP_ALL_P4 BIT(4) ++#define B_AX_BCN_DROP_ALL_P3 BIT(3) ++#define B_AX_BCN_DROP_ALL_P2 BIT(2) ++#define B_AX_BCN_DROP_ALL_P1 BIT(1) ++#define B_AX_BCN_DROP_ALL_P0 BIT(0) ++ + #define R_AX_MBSSID_CTRL 0xC568 + #define R_AX_MBSSID_CTRL_C1 0xE568 + #define B_AX_P0MB_ALL_MASK GENMASK(23, 1) +@@ -2554,11 +2562,20 @@ + + #define R_AX_PTCL_DBG_INFO 0xC6F0 + #define R_AX_PTCL_DBG_INFO_C1 0xE6F0 ++#define B_AX_PTCL_DBG_INFO_MASK_BY_PORT(port) \ ++({\ ++ typeof(port) _port = (port); \ ++ GENMASK((_port) * 2 + 1, (_port) * 2); \ ++}) ++ + #define B_AX_PTCL_DBG_INFO_MASK GENMASK(31, 0) + #define R_AX_PTCL_DBG 0xC6F4 + #define R_AX_PTCL_DBG_C1 0xE6F4 + #define B_AX_PTCL_DBG_EN BIT(8) + #define B_AX_PTCL_DBG_SEL_MASK GENMASK(7, 0) ++#define AX_PTCL_DBG_BCNQ_NUM0 8 ++#define AX_PTCL_DBG_BCNQ_NUM1 9 ++ + + #define R_AX_DLE_CTRL 0xC800 + #define R_AX_DLE_CTRL_C1 0xE800 +diff --git a/drivers/net/wireless/silabs/wfx/sta.c b/drivers/net/wireless/silabs/wfx/sta.c +index 1b6c158457b42..537caf9d914a7 100644 +--- a/drivers/net/wireless/silabs/wfx/sta.c ++++ b/drivers/net/wireless/silabs/wfx/sta.c +@@ -336,29 +336,38 @@ static int wfx_upload_ap_templates(struct wfx_vif *wvif) + return 0; + } + +-static void wfx_set_mfp_ap(struct wfx_vif *wvif) ++static int wfx_set_mfp_ap(struct wfx_vif *wvif) + { + struct ieee80211_vif *vif = wvif_to_vif(wvif); + struct sk_buff *skb = ieee80211_beacon_get(wvif->wdev->hw, vif, 0); + const int ieoffset = offsetof(struct ieee80211_mgmt, u.beacon.variable); +- const u16 *ptr = (u16 *)cfg80211_find_ie(WLAN_EID_RSN, skb->data + ieoffset, +- skb->len - ieoffset); + const int pairwise_cipher_suite_count_offset = 8 / sizeof(u16); + const int pairwise_cipher_suite_size = 4 / sizeof(u16); + const int akm_suite_size = 4 / sizeof(u16); ++ const u16 *ptr; + +- if (ptr) { +- ptr += pairwise_cipher_suite_count_offset; +- if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb))) +- return; +- ptr += 1 + pairwise_cipher_suite_size * *ptr; +- if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb))) +- return; +- ptr += 1 + akm_suite_size * *ptr; +- if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb))) +- return; +- wfx_hif_set_mfp(wvif, *ptr & BIT(7), *ptr & BIT(6)); +- } ++ if (unlikely(!skb)) ++ return -ENOMEM; ++ ++ ptr = (u16 *)cfg80211_find_ie(WLAN_EID_RSN, skb->data + ieoffset, ++ skb->len - ieoffset); ++ if (unlikely(!ptr)) ++ return -EINVAL; ++ ++ ptr += pairwise_cipher_suite_count_offset; ++ if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb))) ++ return -EINVAL; ++ ++ ptr += 1 + pairwise_cipher_suite_size * *ptr; ++ if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb))) ++ return -EINVAL; ++ ++ ptr += 1 + akm_suite_size * *ptr; ++ if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb))) ++ return -EINVAL; ++ ++ wfx_hif_set_mfp(wvif, *ptr & BIT(7), *ptr & BIT(6)); ++ return 0; + } + + int wfx_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif, +@@ -376,8 +385,7 @@ int wfx_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + ret = wfx_hif_start(wvif, &vif->bss_conf, wvif->channel); + if (ret > 0) + return -EIO; +- wfx_set_mfp_ap(wvif); +- return ret; ++ return wfx_set_mfp_ap(wvif); + } + + void wfx_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif, +diff --git a/drivers/opp/core.c b/drivers/opp/core.c +index b2971dd953358..f1e54a3a15c71 100644 +--- a/drivers/opp/core.c ++++ b/drivers/opp/core.c +@@ -832,9 +832,14 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_find_level_ceil); + * use. + */ + struct dev_pm_opp *dev_pm_opp_find_level_floor(struct device *dev, +- unsigned long *level) ++ unsigned int *level) + { +- return _find_key_floor(dev, level, 0, true, _read_level, NULL); ++ unsigned long temp = *level; ++ struct dev_pm_opp *opp; ++ ++ opp = _find_key_floor(dev, &temp, 0, true, _read_level, NULL); ++ *level = temp; ++ return opp; + } + EXPORT_SYMBOL_GPL(dev_pm_opp_find_level_floor); + +diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h +index f43873049d52c..c6283ba781979 100644 +--- a/drivers/pci/pci.h ++++ b/drivers/pci/pci.h +@@ -272,7 +272,7 @@ void pci_bus_put(struct pci_bus *bus); + + /* PCIe speed to Mb/s reduced by encoding overhead */ + #define PCIE_SPEED2MBS_ENC(speed) \ +- ((speed) == PCIE_SPEED_64_0GT ? 64000*128/130 : \ ++ ((speed) == PCIE_SPEED_64_0GT ? 64000*1/1 : \ + (speed) == PCIE_SPEED_32_0GT ? 32000*128/130 : \ + (speed) == PCIE_SPEED_16_0GT ? 16000*128/130 : \ + (speed) == PCIE_SPEED_8_0GT ? 8000*128/130 : \ +diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c +index 42a3bd35a3e11..38e3346772cc7 100644 +--- a/drivers/pci/pcie/aer.c ++++ b/drivers/pci/pcie/aer.c +@@ -740,7 +740,7 @@ static void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info) + u8 bus = info->id >> 8; + u8 devfn = info->id & 0xff; + +- pci_info(dev, "%s%s error received: %04x:%02x:%02x.%d\n", ++ pci_info(dev, "%s%s error message received from %04x:%02x:%02x.%d\n", + info->multi_error_valid ? "Multiple " : "", + aer_error_severity_string[info->severity], + pci_domain_nr(dev->bus), bus, PCI_SLOT(devfn), +@@ -929,7 +929,12 @@ static bool find_source_device(struct pci_dev *parent, + pci_walk_bus(parent->subordinate, find_device_iter, e_info); + + if (!e_info->error_dev_num) { +- pci_info(parent, "can't find device of ID%04x\n", e_info->id); ++ u8 bus = e_info->id >> 8; ++ u8 devfn = e_info->id & 0xff; ++ ++ pci_info(parent, "found no error details for %04x:%02x:%02x.%d\n", ++ pci_domain_nr(parent->bus), bus, PCI_SLOT(devfn), ++ PCI_FUNC(devfn)); + return false; + } + return true; +diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c +index d55a3ffae4b8b..a2bf6de11462f 100644 +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -702,10 +702,13 @@ static void quirk_amd_dwc_class(struct pci_dev *pdev) + { + u32 class = pdev->class; + +- /* Use "USB Device (not host controller)" class */ +- pdev->class = PCI_CLASS_SERIAL_USB_DEVICE; +- pci_info(pdev, "PCI class overridden (%#08x -> %#08x) so dwc3 driver can claim this instead of xhci\n", +- class, pdev->class); ++ if (class != PCI_CLASS_SERIAL_USB_DEVICE) { ++ /* Use "USB Device (not host controller)" class */ ++ pdev->class = PCI_CLASS_SERIAL_USB_DEVICE; ++ pci_info(pdev, ++ "PCI class overridden (%#08x -> %#08x) so dwc3 driver can claim this instead of xhci\n", ++ class, pdev->class); ++ } + } + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_NL_USB, + quirk_amd_dwc_class); +@@ -3786,6 +3789,19 @@ static void quirk_no_pm_reset(struct pci_dev *dev) + DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_ATI, PCI_ANY_ID, + PCI_CLASS_DISPLAY_VGA, 8, quirk_no_pm_reset); + ++/* ++ * Spectrum-{1,2,3,4} devices report that a D3hot->D0 transition causes a reset ++ * (i.e., they advertise NoSoftRst-). However, this transition does not have ++ * any effect on the device: It continues to be operational and network ports ++ * remain up. Advertising this support makes it seem as if a PM reset is viable ++ * for these devices. Mark it as unavailable to skip it when testing reset ++ * methods. ++ */ ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MELLANOX, 0xcb84, quirk_no_pm_reset); ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MELLANOX, 0xcf6c, quirk_no_pm_reset); ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MELLANOX, 0xcf70, quirk_no_pm_reset); ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MELLANOX, 0xcf80, quirk_no_pm_reset); ++ + /* + * Thunderbolt controllers with broken MSI hotplug signaling: + * Entire 1st generation (Light Ridge, Eagle Ridge, Light Peak) and part +diff --git a/drivers/pci/switch/switchtec.c b/drivers/pci/switch/switchtec.c +index 5b921387eca61..1804794d0e686 100644 +--- a/drivers/pci/switch/switchtec.c ++++ b/drivers/pci/switch/switchtec.c +@@ -1308,13 +1308,6 @@ static void stdev_release(struct device *dev) + { + struct switchtec_dev *stdev = to_stdev(dev); + +- if (stdev->dma_mrpc) { +- iowrite32(0, &stdev->mmio_mrpc->dma_en); +- flush_wc_buf(stdev); +- writeq(0, &stdev->mmio_mrpc->dma_addr); +- dma_free_coherent(&stdev->pdev->dev, sizeof(*stdev->dma_mrpc), +- stdev->dma_mrpc, stdev->dma_mrpc_dma_addr); +- } + kfree(stdev); + } + +@@ -1358,7 +1351,7 @@ static struct switchtec_dev *stdev_create(struct pci_dev *pdev) + return ERR_PTR(-ENOMEM); + + stdev->alive = true; +- stdev->pdev = pdev; ++ stdev->pdev = pci_dev_get(pdev); + INIT_LIST_HEAD(&stdev->mrpc_queue); + mutex_init(&stdev->mrpc_mutex); + stdev->mrpc_busy = 0; +@@ -1391,6 +1384,7 @@ static struct switchtec_dev *stdev_create(struct pci_dev *pdev) + return stdev; + + err_put: ++ pci_dev_put(stdev->pdev); + put_device(&stdev->dev); + return ERR_PTR(rc); + } +@@ -1644,6 +1638,18 @@ static int switchtec_init_pci(struct switchtec_dev *stdev, + return 0; + } + ++static void switchtec_exit_pci(struct switchtec_dev *stdev) ++{ ++ if (stdev->dma_mrpc) { ++ iowrite32(0, &stdev->mmio_mrpc->dma_en); ++ flush_wc_buf(stdev); ++ writeq(0, &stdev->mmio_mrpc->dma_addr); ++ dma_free_coherent(&stdev->pdev->dev, sizeof(*stdev->dma_mrpc), ++ stdev->dma_mrpc, stdev->dma_mrpc_dma_addr); ++ stdev->dma_mrpc = NULL; ++ } ++} ++ + static int switchtec_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *id) + { +@@ -1703,6 +1709,9 @@ static void switchtec_pci_remove(struct pci_dev *pdev) + ida_free(&switchtec_minor_ida, MINOR(stdev->dev.devt)); + dev_info(&stdev->dev, "unregistered.\n"); + stdev_kill(stdev); ++ switchtec_exit_pci(stdev); ++ pci_dev_put(stdev->pdev); ++ stdev->pdev = NULL; + put_device(&stdev->dev); + } + +diff --git a/drivers/perf/arm_pmuv3.c b/drivers/perf/arm_pmuv3.c +index 6ca7be05229c1..0e80fdc9f9cad 100644 +--- a/drivers/perf/arm_pmuv3.c ++++ b/drivers/perf/arm_pmuv3.c +@@ -169,7 +169,11 @@ armv8pmu_events_sysfs_show(struct device *dev, + PMU_EVENT_ATTR_ID(name, armv8pmu_events_sysfs_show, config) + + static struct attribute *armv8_pmuv3_event_attrs[] = { +- ARMV8_EVENT_ATTR(sw_incr, ARMV8_PMUV3_PERFCTR_SW_INCR), ++ /* ++ * Don't expose the sw_incr event in /sys. It's not usable as writes to ++ * PMSWINC_EL0 will trap as PMUSERENR.{SW,EN}=={0,0} and event rotation ++ * means we don't have a fixed event<->counter relationship regardless. ++ */ + ARMV8_EVENT_ATTR(l1i_cache_refill, ARMV8_PMUV3_PERFCTR_L1I_CACHE_REFILL), + ARMV8_EVENT_ATTR(l1i_tlb_refill, ARMV8_PMUV3_PERFCTR_L1I_TLB_REFILL), + ARMV8_EVENT_ATTR(l1d_cache_refill, ARMV8_PMUV3_PERFCTR_L1D_CACHE_REFILL), +diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c +index 3cd0798ee6313..f1af21dbd5fb2 100644 +--- a/drivers/pinctrl/intel/pinctrl-baytrail.c ++++ b/drivers/pinctrl/intel/pinctrl-baytrail.c +@@ -918,13 +918,14 @@ static int byt_pin_config_set(struct pinctrl_dev *pctl_dev, + unsigned int num_configs) + { + struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev); +- unsigned int param, arg; + void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); + void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); + void __iomem *db_reg = byt_gpio_reg(vg, offset, BYT_DEBOUNCE_REG); + u32 conf, val, db_pulse, debounce; ++ enum pin_config_param param; + unsigned long flags; + int i, ret = 0; ++ u32 arg; + + raw_spin_lock_irqsave(&byt_lock, flags); + +diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c +index 4f05f610391b0..c02ce0834c2cd 100644 +--- a/drivers/pnp/pnpacpi/rsparser.c ++++ b/drivers/pnp/pnpacpi/rsparser.c +@@ -151,13 +151,13 @@ static int vendor_resource_matches(struct pnp_dev *dev, + static void pnpacpi_parse_allocated_vendor(struct pnp_dev *dev, + struct acpi_resource_vendor_typed *vendor) + { +- if (vendor_resource_matches(dev, vendor, &hp_ccsr_uuid, 16)) { +- u64 start, length; ++ struct { u64 start, length; } range; + +- memcpy(&start, vendor->byte_data, sizeof(start)); +- memcpy(&length, vendor->byte_data + 8, sizeof(length)); +- +- pnp_add_mem_resource(dev, start, start + length - 1, 0); ++ if (vendor_resource_matches(dev, vendor, &hp_ccsr_uuid, ++ sizeof(range))) { ++ memcpy(&range, vendor->byte_data, sizeof(range)); ++ pnp_add_mem_resource(dev, range.start, range.start + ++ range.length - 1, 0); + } + } + +diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c +index 3137e40fcd3e0..a7b3e548ea5ac 100644 +--- a/drivers/regulator/core.c ++++ b/drivers/regulator/core.c +@@ -2918,7 +2918,8 @@ static int _regulator_enable(struct regulator *regulator) + /* Fallthrough on positive return values - already enabled */ + } + +- rdev->use_count++; ++ if (regulator->enable_count == 1) ++ rdev->use_count++; + + return 0; + +@@ -2993,37 +2994,40 @@ static int _regulator_disable(struct regulator *regulator) + + lockdep_assert_held_once(&rdev->mutex.base); + +- if (WARN(rdev->use_count <= 0, ++ if (WARN(regulator->enable_count == 0, + "unbalanced disables for %s\n", rdev_get_name(rdev))) + return -EIO; + +- /* are we the last user and permitted to disable ? */ +- if (rdev->use_count == 1 && +- (rdev->constraints && !rdev->constraints->always_on)) { +- +- /* we are last user */ +- if (regulator_ops_is_valid(rdev, REGULATOR_CHANGE_STATUS)) { +- ret = _notifier_call_chain(rdev, +- REGULATOR_EVENT_PRE_DISABLE, +- NULL); +- if (ret & NOTIFY_STOP_MASK) +- return -EINVAL; +- +- ret = _regulator_do_disable(rdev); +- if (ret < 0) { +- rdev_err(rdev, "failed to disable: %pe\n", ERR_PTR(ret)); +- _notifier_call_chain(rdev, +- REGULATOR_EVENT_ABORT_DISABLE, ++ if (regulator->enable_count == 1) { ++ /* disabling last enable_count from this regulator */ ++ /* are we the last user and permitted to disable ? */ ++ if (rdev->use_count == 1 && ++ (rdev->constraints && !rdev->constraints->always_on)) { ++ ++ /* we are last user */ ++ if (regulator_ops_is_valid(rdev, REGULATOR_CHANGE_STATUS)) { ++ ret = _notifier_call_chain(rdev, ++ REGULATOR_EVENT_PRE_DISABLE, ++ NULL); ++ if (ret & NOTIFY_STOP_MASK) ++ return -EINVAL; ++ ++ ret = _regulator_do_disable(rdev); ++ if (ret < 0) { ++ rdev_err(rdev, "failed to disable: %pe\n", ERR_PTR(ret)); ++ _notifier_call_chain(rdev, ++ REGULATOR_EVENT_ABORT_DISABLE, ++ NULL); ++ return ret; ++ } ++ _notifier_call_chain(rdev, REGULATOR_EVENT_DISABLE, + NULL); +- return ret; + } +- _notifier_call_chain(rdev, REGULATOR_EVENT_DISABLE, +- NULL); +- } + +- rdev->use_count = 0; +- } else if (rdev->use_count > 1) { +- rdev->use_count--; ++ rdev->use_count = 0; ++ } else if (rdev->use_count > 1) { ++ rdev->use_count--; ++ } + } + + if (ret == 0) +diff --git a/drivers/regulator/ti-abb-regulator.c b/drivers/regulator/ti-abb-regulator.c +index f48214e2c3b46..04133510e5af7 100644 +--- a/drivers/regulator/ti-abb-regulator.c ++++ b/drivers/regulator/ti-abb-regulator.c +@@ -726,9 +726,25 @@ static int ti_abb_probe(struct platform_device *pdev) + return PTR_ERR(abb->setup_reg); + } + +- abb->int_base = devm_platform_ioremap_resource_byname(pdev, "int-address"); +- if (IS_ERR(abb->int_base)) +- return PTR_ERR(abb->int_base); ++ pname = "int-address"; ++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname); ++ if (!res) { ++ dev_err(dev, "Missing '%s' IO resource\n", pname); ++ return -ENODEV; ++ } ++ /* ++ * The MPU interrupt status register (PRM_IRQSTATUS_MPU) is ++ * shared between regulator-abb-{ivahd,dspeve,gpu} driver ++ * instances. Therefore use devm_ioremap() rather than ++ * devm_platform_ioremap_resource_byname() to avoid busy ++ * resource region conflicts. ++ */ ++ abb->int_base = devm_ioremap(dev, res->start, ++ resource_size(res)); ++ if (!abb->int_base) { ++ dev_err(dev, "Unable to map '%s'\n", pname); ++ return -ENOMEM; ++ } + + /* Map Optional resources */ + pname = "efuse-address"; +diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c +index 88f41f95cc94d..d6ea2fd4c2a02 100644 +--- a/drivers/s390/crypto/vfio_ap_ops.c ++++ b/drivers/s390/crypto/vfio_ap_ops.c +@@ -2044,6 +2044,7 @@ static ssize_t status_show(struct device *dev, + { + ssize_t nchars = 0; + struct vfio_ap_queue *q; ++ unsigned long apid, apqi; + struct ap_matrix_mdev *matrix_mdev; + struct ap_device *apdev = to_ap_dev(dev); + +@@ -2051,8 +2052,21 @@ static ssize_t status_show(struct device *dev, + q = dev_get_drvdata(&apdev->device); + matrix_mdev = vfio_ap_mdev_for_queue(q); + ++ /* If the queue is assigned to the matrix mediated device, then ++ * determine whether it is passed through to a guest; otherwise, ++ * indicate that it is unassigned. ++ */ + if (matrix_mdev) { +- if (matrix_mdev->kvm) ++ apid = AP_QID_CARD(q->apqn); ++ apqi = AP_QID_QUEUE(q->apqn); ++ /* ++ * If the queue is passed through to the guest, then indicate ++ * that it is in use; otherwise, indicate that it is ++ * merely assigned to a matrix mediated device. ++ */ ++ if (matrix_mdev->kvm && ++ test_bit_inv(apid, matrix_mdev->shadow_apcb.apm) && ++ test_bit_inv(apqi, matrix_mdev->shadow_apcb.aqm)) + nchars = scnprintf(buf, PAGE_SIZE, "%s\n", + AP_QUEUE_IN_USE); + else +diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h +index ed8d9319862a5..3819d559ebbb4 100644 +--- a/drivers/scsi/arcmsr/arcmsr.h ++++ b/drivers/scsi/arcmsr/arcmsr.h +@@ -78,9 +78,13 @@ struct device_attribute; + #ifndef PCI_DEVICE_ID_ARECA_1203 + #define PCI_DEVICE_ID_ARECA_1203 0x1203 + #endif ++#ifndef PCI_DEVICE_ID_ARECA_1883 ++#define PCI_DEVICE_ID_ARECA_1883 0x1883 ++#endif + #ifndef PCI_DEVICE_ID_ARECA_1884 + #define PCI_DEVICE_ID_ARECA_1884 0x1884 + #endif ++#define PCI_DEVICE_ID_ARECA_1886_0 0x1886 + #define PCI_DEVICE_ID_ARECA_1886 0x188A + #define ARCMSR_HOURS (1000 * 60 * 60 * 4) + #define ARCMSR_MINUTES (1000 * 60 * 60) +diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c +index a66221c3b72f8..01fb1396e1a92 100644 +--- a/drivers/scsi/arcmsr/arcmsr_hba.c ++++ b/drivers/scsi/arcmsr/arcmsr_hba.c +@@ -214,8 +214,12 @@ static struct pci_device_id arcmsr_device_id_table[] = { + .driver_data = ACB_ADAPTER_TYPE_A}, + {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1880), + .driver_data = ACB_ADAPTER_TYPE_C}, ++ {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1883), ++ .driver_data = ACB_ADAPTER_TYPE_C}, + {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1884), + .driver_data = ACB_ADAPTER_TYPE_E}, ++ {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1886_0), ++ .driver_data = ACB_ADAPTER_TYPE_F}, + {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1886), + .driver_data = ACB_ADAPTER_TYPE_F}, + {0, 0}, /* Terminating entry */ +@@ -4706,9 +4710,11 @@ static const char *arcmsr_info(struct Scsi_Host *host) + case PCI_DEVICE_ID_ARECA_1680: + case PCI_DEVICE_ID_ARECA_1681: + case PCI_DEVICE_ID_ARECA_1880: ++ case PCI_DEVICE_ID_ARECA_1883: + case PCI_DEVICE_ID_ARECA_1884: + type = "SAS/SATA"; + break; ++ case PCI_DEVICE_ID_ARECA_1886_0: + case PCI_DEVICE_ID_ARECA_1886: + type = "NVMe/SAS/SATA"; + break; +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 6d8577423d32b..b56fbc61a15ae 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -1605,6 +1605,11 @@ static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba) + } + + phy->port_id = port_id; ++ spin_lock(&phy->lock); ++ /* Delete timer and set phy_attached atomically */ ++ del_timer(&phy->timer); ++ phy->phy_attached = 1; ++ spin_unlock(&phy->lock); + + /* + * Call pm_runtime_get_noresume() which pairs with +@@ -1618,11 +1623,6 @@ static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba) + + res = IRQ_HANDLED; + +- spin_lock(&phy->lock); +- /* Delete timer and set phy_attached atomically */ +- del_timer(&phy->timer); +- phy->phy_attached = 1; +- spin_unlock(&phy->lock); + end: + if (phy->reset_completion) + complete(phy->reset_completion); +diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c +index a7b3243b471d5..7162a5029b37a 100644 +--- a/drivers/scsi/isci/request.c ++++ b/drivers/scsi/isci/request.c +@@ -3390,7 +3390,7 @@ static enum sci_status isci_io_request_build(struct isci_host *ihost, + return SCI_FAILURE; + } + +- return SCI_SUCCESS; ++ return status; + } + + static struct isci_request *isci_request_from_tag(struct isci_host *ihost, u16 tag) +diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c +index 945adca5e72fd..05be0810b5e31 100644 +--- a/drivers/scsi/libfc/fc_fcp.c ++++ b/drivers/scsi/libfc/fc_fcp.c +@@ -265,6 +265,11 @@ static int fc_fcp_send_abort(struct fc_fcp_pkt *fsp) + if (!fsp->seq_ptr) + return -EINVAL; + ++ if (fsp->state & FC_SRB_ABORT_PENDING) { ++ FC_FCP_DBG(fsp, "abort already pending\n"); ++ return -EBUSY; ++ } ++ + this_cpu_inc(fsp->lp->stats->FcpPktAborts); + + fsp->state |= FC_SRB_ABORT_PENDING; +@@ -1671,7 +1676,7 @@ static void fc_fcp_rec_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp) + if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY) + fc_fcp_rec(fsp); + else +- fc_fcp_recovery(fsp, FC_ERROR); ++ fc_fcp_recovery(fsp, FC_TIMED_OUT); + break; + } + fc_fcp_unlock_pkt(fsp); +@@ -1690,11 +1695,12 @@ static void fc_fcp_recovery(struct fc_fcp_pkt *fsp, u8 code) + fsp->status_code = code; + fsp->cdb_status = 0; + fsp->io_status = 0; +- /* +- * if this fails then we let the scsi command timer fire and +- * scsi-ml escalate. +- */ +- fc_fcp_send_abort(fsp); ++ if (!fsp->cmd) ++ /* ++ * Only abort non-scsi commands; otherwise let the ++ * scsi command timer fire and scsi-ml escalate. ++ */ ++ fc_fcp_send_abort(fsp); + } + + /** +diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h +index af15f7a22d258..04d608ea91060 100644 +--- a/drivers/scsi/lpfc/lpfc.h ++++ b/drivers/scsi/lpfc/lpfc.h +@@ -33,6 +33,7 @@ + struct lpfc_sli2_slim; + + #define ELX_MODEL_NAME_SIZE 80 ++#define ELX_FW_NAME_SIZE 84 + + #define LPFC_PCI_DEV_LP 0x1 + #define LPFC_PCI_DEV_OC 0x2 +diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c +index 0829fe6ddff88..385e1636f139b 100644 +--- a/drivers/scsi/lpfc/lpfc_els.c ++++ b/drivers/scsi/lpfc/lpfc_els.c +@@ -1130,12 +1130,12 @@ stop_rr_fcf_flogi: + vport->port_state, vport->fc_flag, + sp->cmn.priority_tagging, kref_read(&ndlp->kref)); + +- if (sp->cmn.priority_tagging) +- vport->phba->pport->vmid_flag |= (LPFC_VMID_ISSUE_QFPA | +- LPFC_VMID_TYPE_PRIO); + /* reinitialize the VMID datastructure before returning */ + if (lpfc_is_vmid_enabled(phba)) + lpfc_reinit_vmid(vport); ++ if (sp->cmn.priority_tagging) ++ vport->phba->pport->vmid_flag |= (LPFC_VMID_ISSUE_QFPA | ++ LPFC_VMID_TYPE_PRIO); + + /* + * Address a timing race with dev_loss. If dev_loss is active on +@@ -11130,6 +11130,14 @@ mbox_err_exit: + lpfc_nlp_put(ndlp); + + mempool_free(pmb, phba->mbox_mem_pool); ++ ++ /* reinitialize the VMID datastructure before returning. ++ * this is specifically for vport ++ */ ++ if (lpfc_is_vmid_enabled(phba)) ++ lpfc_reinit_vmid(vport); ++ vport->vmid_flag = vport->phba->pport->vmid_flag; ++ + return; + } + +diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c +index e7c47ee185a49..70bcee64bc8c6 100644 +--- a/drivers/scsi/lpfc/lpfc_init.c ++++ b/drivers/scsi/lpfc/lpfc_init.c +@@ -14721,7 +14721,7 @@ out: + int + lpfc_sli4_request_firmware_update(struct lpfc_hba *phba, uint8_t fw_upgrade) + { +- uint8_t file_name[ELX_MODEL_NAME_SIZE]; ++ char file_name[ELX_FW_NAME_SIZE] = {0}; + int ret; + const struct firmware *fw; + +@@ -14730,7 +14730,7 @@ lpfc_sli4_request_firmware_update(struct lpfc_hba *phba, uint8_t fw_upgrade) + LPFC_SLI_INTF_IF_TYPE_2) + return -EPERM; + +- snprintf(file_name, ELX_MODEL_NAME_SIZE, "%s.grp", phba->ModelName); ++ scnprintf(file_name, sizeof(file_name), "%s.grp", phba->ModelName); + + if (fw_upgrade == INT_FW_UPGRADE) { + ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_UEVENT, +diff --git a/drivers/scsi/lpfc/lpfc_vmid.c b/drivers/scsi/lpfc/lpfc_vmid.c +index cf8ba840d0eab..773e02ae20c37 100644 +--- a/drivers/scsi/lpfc/lpfc_vmid.c ++++ b/drivers/scsi/lpfc/lpfc_vmid.c +@@ -321,5 +321,6 @@ lpfc_reinit_vmid(struct lpfc_vport *vport) + if (!hash_empty(vport->hash_table)) + hash_for_each_safe(vport->hash_table, bucket, tmp, cur, hnode) + hash_del(&cur->hnode); ++ vport->vmid_flag = 0; + write_unlock(&vport->vmid_lock); + } +diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c +index f039f1d986477..0d148c39ebcc9 100644 +--- a/drivers/scsi/mpi3mr/mpi3mr_fw.c ++++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c +@@ -1892,7 +1892,8 @@ static int mpi3mr_create_op_reply_q(struct mpi3mr_ioc *mrioc, u16 qidx) + + reply_qid = qidx + 1; + op_reply_q->num_replies = MPI3MR_OP_REP_Q_QD; +- if (!mrioc->pdev->revision) ++ if ((mrioc->pdev->device == MPI3_MFGPAGE_DEVID_SAS4116) && ++ !mrioc->pdev->revision) + op_reply_q->num_replies = MPI3MR_OP_REP_Q_QD4K; + op_reply_q->ci = 0; + op_reply_q->ephase = 1; +diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c +index e2f2c205df71a..872d4b809d083 100644 +--- a/drivers/scsi/mpi3mr/mpi3mr_os.c ++++ b/drivers/scsi/mpi3mr/mpi3mr_os.c +@@ -5112,7 +5112,10 @@ mpi3mr_probe(struct pci_dev *pdev, const struct pci_device_id *id) + mpi3mr_init_drv_cmd(&mrioc->evtack_cmds[i], + MPI3MR_HOSTTAG_EVTACKCMD_MIN + i); + +- if (pdev->revision) ++ if ((pdev->device == MPI3_MFGPAGE_DEVID_SAS4116) && ++ !pdev->revision) ++ mrioc->enable_segqueue = false; ++ else + mrioc->enable_segqueue = true; + + init_waitqueue_head(&mrioc->reset_waitq); +@@ -5441,6 +5444,14 @@ static const struct pci_device_id mpi3mr_pci_id_table[] = { + PCI_DEVICE_SUB(MPI3_MFGPAGE_VENDORID_BROADCOM, + MPI3_MFGPAGE_DEVID_SAS4116, PCI_ANY_ID, PCI_ANY_ID) + }, ++ { ++ PCI_DEVICE_SUB(MPI3_MFGPAGE_VENDORID_BROADCOM, ++ MPI3_MFGPAGE_DEVID_SAS5116_MPI, PCI_ANY_ID, PCI_ANY_ID) ++ }, ++ { ++ PCI_DEVICE_SUB(MPI3_MFGPAGE_VENDORID_BROADCOM, ++ MPI3_MFGPAGE_DEVID_SAS5116_MPI_MGMT, PCI_ANY_ID, PCI_ANY_ID) ++ }, + { 0 } + }; + MODULE_DEVICE_TABLE(pci, mpi3mr_pci_id_table); +diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c +index d983f4a0e9f14..3328b175a8326 100644 +--- a/drivers/scsi/scsi_error.c ++++ b/drivers/scsi/scsi_error.c +@@ -61,11 +61,11 @@ static int scsi_eh_try_stu(struct scsi_cmnd *scmd); + static enum scsi_disposition scsi_try_to_abort_cmd(const struct scsi_host_template *, + struct scsi_cmnd *); + +-void scsi_eh_wakeup(struct Scsi_Host *shost) ++void scsi_eh_wakeup(struct Scsi_Host *shost, unsigned int busy) + { + lockdep_assert_held(shost->host_lock); + +- if (scsi_host_busy(shost) == shost->host_failed) { ++ if (busy == shost->host_failed) { + trace_scsi_eh_wakeup(shost); + wake_up_process(shost->ehandler); + SCSI_LOG_ERROR_RECOVERY(5, shost_printk(KERN_INFO, shost, +@@ -88,7 +88,7 @@ void scsi_schedule_eh(struct Scsi_Host *shost) + if (scsi_host_set_state(shost, SHOST_RECOVERY) == 0 || + scsi_host_set_state(shost, SHOST_CANCEL_RECOVERY) == 0) { + shost->host_eh_scheduled++; +- scsi_eh_wakeup(shost); ++ scsi_eh_wakeup(shost, scsi_host_busy(shost)); + } + + spin_unlock_irqrestore(shost->host_lock, flags); +@@ -286,7 +286,7 @@ static void scsi_eh_inc_host_failed(struct rcu_head *head) + + spin_lock_irqsave(shost->host_lock, flags); + shost->host_failed++; +- scsi_eh_wakeup(shost); ++ scsi_eh_wakeup(shost, scsi_host_busy(shost)); + spin_unlock_irqrestore(shost->host_lock, flags); + } + +diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c +index cf3864f720930..1fb80eae9a63a 100644 +--- a/drivers/scsi/scsi_lib.c ++++ b/drivers/scsi/scsi_lib.c +@@ -280,7 +280,7 @@ static void scsi_dec_host_busy(struct Scsi_Host *shost, struct scsi_cmnd *cmd) + if (unlikely(scsi_host_in_recovery(shost))) { + spin_lock_irqsave(shost->host_lock, flags); + if (shost->host_failed || shost->host_eh_scheduled) +- scsi_eh_wakeup(shost); ++ scsi_eh_wakeup(shost, scsi_host_busy(shost)); + spin_unlock_irqrestore(shost->host_lock, flags); + } + rcu_read_unlock(); +diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h +index 3f0dfb97db6bd..1fbfe1b52c9f1 100644 +--- a/drivers/scsi/scsi_priv.h ++++ b/drivers/scsi/scsi_priv.h +@@ -92,7 +92,7 @@ extern void scmd_eh_abort_handler(struct work_struct *work); + extern enum blk_eh_timer_return scsi_timeout(struct request *req); + extern int scsi_error_handler(void *host); + extern enum scsi_disposition scsi_decide_disposition(struct scsi_cmnd *cmd); +-extern void scsi_eh_wakeup(struct Scsi_Host *shost); ++extern void scsi_eh_wakeup(struct Scsi_Host *shost, unsigned int busy); + extern void scsi_eh_scmd_add(struct scsi_cmnd *); + void scsi_eh_ready_devs(struct Scsi_Host *shost, + struct list_head *work_q, +diff --git a/drivers/soc/xilinx/xlnx_event_manager.c b/drivers/soc/xilinx/xlnx_event_manager.c +index 86a048a10a13f..042553abe1bf8 100644 +--- a/drivers/soc/xilinx/xlnx_event_manager.c ++++ b/drivers/soc/xilinx/xlnx_event_manager.c +@@ -477,7 +477,7 @@ static void xlnx_call_notify_cb_handler(const u32 *payload) + } + } + if (!is_callback_found) +- pr_warn("Didn't find any registered callback for 0x%x 0x%x\n", ++ pr_warn("Unhandled SGI node 0x%x event 0x%x. Expected with Xen hypervisor\n", + payload[1], payload[2]); + } + +@@ -555,7 +555,7 @@ static void xlnx_disable_percpu_irq(void *data) + static int xlnx_event_init_sgi(struct platform_device *pdev) + { + int ret = 0; +- int cpu = smp_processor_id(); ++ int cpu; + /* + * IRQ related structures are used for the following: + * for each SGI interrupt ensure its mapped by GIC IRQ domain +@@ -592,9 +592,12 @@ static int xlnx_event_init_sgi(struct platform_device *pdev) + sgi_fwspec.param[0] = sgi_num; + virq_sgi = irq_create_fwspec_mapping(&sgi_fwspec); + ++ cpu = get_cpu(); + per_cpu(cpu_number1, cpu) = cpu; + ret = request_percpu_irq(virq_sgi, xlnx_event_handler, "xlnx_event_mgmt", + &cpu_number1); ++ put_cpu(); ++ + WARN_ON(ret); + if (ret) { + irq_dispose_mapping(virq_sgi); +diff --git a/drivers/spmi/spmi-mtk-pmif.c b/drivers/spmi/spmi-mtk-pmif.c +index 54c35f5535cbe..1261f381cae6c 100644 +--- a/drivers/spmi/spmi-mtk-pmif.c ++++ b/drivers/spmi/spmi-mtk-pmif.c +@@ -475,7 +475,7 @@ static int mtk_spmi_probe(struct platform_device *pdev) + for (i = 0; i < arb->nclks; i++) + arb->clks[i].id = pmif_clock_names[i]; + +- err = devm_clk_bulk_get(&pdev->dev, arb->nclks, arb->clks); ++ err = clk_bulk_get(&pdev->dev, arb->nclks, arb->clks); + if (err) { + dev_err(&pdev->dev, "Failed to get clocks: %d\n", err); + goto err_put_ctrl; +@@ -484,7 +484,7 @@ static int mtk_spmi_probe(struct platform_device *pdev) + err = clk_bulk_prepare_enable(arb->nclks, arb->clks); + if (err) { + dev_err(&pdev->dev, "Failed to enable clocks: %d\n", err); +- goto err_put_ctrl; ++ goto err_put_clks; + } + + ctrl->cmd = pmif_arb_cmd; +@@ -510,6 +510,8 @@ static int mtk_spmi_probe(struct platform_device *pdev) + + err_domain_remove: + clk_bulk_disable_unprepare(arb->nclks, arb->clks); ++err_put_clks: ++ clk_bulk_put(arb->nclks, arb->clks); + err_put_ctrl: + spmi_controller_put(ctrl); + return err; +@@ -521,6 +523,7 @@ static void mtk_spmi_remove(struct platform_device *pdev) + struct pmif *arb = spmi_controller_get_drvdata(ctrl); + + clk_bulk_disable_unprepare(arb->nclks, arb->clks); ++ clk_bulk_put(arb->nclks, arb->clks); + spmi_controller_remove(ctrl); + spmi_controller_put(ctrl); + } +diff --git a/drivers/staging/vme_user/vme.c b/drivers/staging/vme_user/vme.c +index 5c416c31ec576..9bc2d35405af6 100644 +--- a/drivers/staging/vme_user/vme.c ++++ b/drivers/staging/vme_user/vme.c +@@ -341,7 +341,7 @@ int vme_slave_set(struct vme_resource *resource, int enabled, + + if (!bridge->slave_set) { + dev_err(bridge->parent, "Function not supported\n"); +- return -ENOSYS; ++ return -EINVAL; + } + + if (!(((image->address_attr & aspace) == aspace) && +diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c +index 1bc7ba4594063..45f51727410cc 100644 +--- a/drivers/thermal/thermal_core.c ++++ b/drivers/thermal/thermal_core.c +@@ -37,8 +37,6 @@ static LIST_HEAD(thermal_governor_list); + static DEFINE_MUTEX(thermal_list_lock); + static DEFINE_MUTEX(thermal_governor_lock); + +-static atomic_t in_suspend; +- + static struct thermal_governor *def_governor; + + /* +@@ -405,7 +403,7 @@ void __thermal_zone_device_update(struct thermal_zone_device *tz, + { + const struct thermal_trip *trip; + +- if (atomic_read(&in_suspend)) ++ if (tz->suspended) + return; + + if (WARN_ONCE(!tz->ops->get_temp, +@@ -1514,17 +1512,35 @@ static int thermal_pm_notify(struct notifier_block *nb, + case PM_HIBERNATION_PREPARE: + case PM_RESTORE_PREPARE: + case PM_SUSPEND_PREPARE: +- atomic_set(&in_suspend, 1); ++ mutex_lock(&thermal_list_lock); ++ ++ list_for_each_entry(tz, &thermal_tz_list, node) { ++ mutex_lock(&tz->lock); ++ ++ tz->suspended = true; ++ ++ mutex_unlock(&tz->lock); ++ } ++ ++ mutex_unlock(&thermal_list_lock); + break; + case PM_POST_HIBERNATION: + case PM_POST_RESTORE: + case PM_POST_SUSPEND: +- atomic_set(&in_suspend, 0); ++ mutex_lock(&thermal_list_lock); ++ + list_for_each_entry(tz, &thermal_tz_list, node) { ++ mutex_lock(&tz->lock); ++ ++ tz->suspended = false; ++ + thermal_zone_device_init(tz); +- thermal_zone_device_update(tz, +- THERMAL_EVENT_UNSPECIFIED); ++ __thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED); ++ ++ mutex_unlock(&tz->lock); + } ++ ++ mutex_unlock(&thermal_list_lock); + break; + default: + break; +diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c +index 614be0f13a313..8ccf691935b75 100644 +--- a/drivers/tty/serial/8250/8250_pci.c ++++ b/drivers/tty/serial/8250/8250_pci.c +@@ -19,6 +19,7 @@ + #include <linux/serial_core.h> + #include <linux/8250_pci.h> + #include <linux/bitops.h> ++#include <linux/bitfield.h> + + #include <asm/byteorder.h> + #include <asm/io.h> +@@ -1970,6 +1971,20 @@ pci_sunix_setup(struct serial_private *priv, + + #define MOXA_GPIO_PIN2 BIT(2) + ++#define MOXA_RS232 0x00 ++#define MOXA_RS422 0x01 ++#define MOXA_RS485_4W 0x0B ++#define MOXA_RS485_2W 0x0F ++#define MOXA_UIR_OFFSET 0x04 ++#define MOXA_EVEN_RS_MASK GENMASK(3, 0) ++#define MOXA_ODD_RS_MASK GENMASK(7, 4) ++ ++enum { ++ MOXA_SUPP_RS232 = BIT(0), ++ MOXA_SUPP_RS422 = BIT(1), ++ MOXA_SUPP_RS485 = BIT(2), ++}; ++ + static bool pci_moxa_is_mini_pcie(unsigned short device) + { + if (device == PCI_DEVICE_ID_MOXA_CP102N || +@@ -1983,13 +1998,54 @@ static bool pci_moxa_is_mini_pcie(unsigned short device) + return false; + } + ++static unsigned int pci_moxa_supported_rs(struct pci_dev *dev) ++{ ++ switch (dev->device & 0x0F00) { ++ case 0x0000: ++ case 0x0600: ++ return MOXA_SUPP_RS232; ++ case 0x0100: ++ return MOXA_SUPP_RS232 | MOXA_SUPP_RS422 | MOXA_SUPP_RS485; ++ case 0x0300: ++ return MOXA_SUPP_RS422 | MOXA_SUPP_RS485; ++ } ++ return 0; ++} ++ ++static int pci_moxa_set_interface(const struct pci_dev *dev, ++ unsigned int port_idx, ++ u8 mode) ++{ ++ resource_size_t iobar_addr = pci_resource_start(dev, 2); ++ resource_size_t UIR_addr = iobar_addr + MOXA_UIR_OFFSET + port_idx / 2; ++ u8 val; ++ ++ val = inb(UIR_addr); ++ ++ if (port_idx % 2) { ++ val &= ~MOXA_ODD_RS_MASK; ++ val |= FIELD_PREP(MOXA_ODD_RS_MASK, mode); ++ } else { ++ val &= ~MOXA_EVEN_RS_MASK; ++ val |= FIELD_PREP(MOXA_EVEN_RS_MASK, mode); ++ } ++ outb(val, UIR_addr); ++ ++ return 0; ++} ++ + static int pci_moxa_init(struct pci_dev *dev) + { + unsigned short device = dev->device; + resource_size_t iobar_addr = pci_resource_start(dev, 2); +- unsigned int num_ports = (device & 0x00F0) >> 4; ++ unsigned int num_ports = (device & 0x00F0) >> 4, i; + u8 val; + ++ if (!(pci_moxa_supported_rs(dev) & MOXA_SUPP_RS232)) { ++ for (i = 0; i < num_ports; ++i) ++ pci_moxa_set_interface(dev, i, MOXA_RS422); ++ } ++ + /* + * Enable hardware buffer to prevent break signal output when system boots up. + * This hardware buffer is only supported on Mini PCIe series. +diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c +index 4b499301a3db1..85de90eebc7bb 100644 +--- a/drivers/tty/tty_ioctl.c ++++ b/drivers/tty/tty_ioctl.c +@@ -844,7 +844,7 @@ int tty_mode_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) + ret = -EFAULT; + return ret; + case TIOCSLCKTRMIOS: +- if (!capable(CAP_SYS_ADMIN)) ++ if (!checkpoint_restore_ns_capable(&init_user_ns)) + return -EPERM; + copy_termios_locked(real_tty, &kterm); + if (user_termios_to_kernel_termios(&kterm, +@@ -861,7 +861,7 @@ int tty_mode_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) + ret = -EFAULT; + return ret; + case TIOCSLCKTRMIOS: +- if (!capable(CAP_SYS_ADMIN)) ++ if (!checkpoint_restore_ns_capable(&init_user_ns)) + return -EPERM; + copy_termios_locked(real_tty, &kterm); + if (user_termios_to_kernel_termios_1(&kterm, +diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c +index 87480a6e6d934..ef8d9bda94ac1 100644 +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -47,12 +47,18 @@ + #define USB_VENDOR_TEXAS_INSTRUMENTS 0x0451 + #define USB_PRODUCT_TUSB8041_USB3 0x8140 + #define USB_PRODUCT_TUSB8041_USB2 0x8142 +-#define HUB_QUIRK_CHECK_PORT_AUTOSUSPEND 0x01 +-#define HUB_QUIRK_DISABLE_AUTOSUSPEND 0x02 ++#define USB_VENDOR_MICROCHIP 0x0424 ++#define USB_PRODUCT_USB4913 0x4913 ++#define USB_PRODUCT_USB4914 0x4914 ++#define USB_PRODUCT_USB4915 0x4915 ++#define HUB_QUIRK_CHECK_PORT_AUTOSUSPEND BIT(0) ++#define HUB_QUIRK_DISABLE_AUTOSUSPEND BIT(1) ++#define HUB_QUIRK_REDUCE_FRAME_INTR_BINTERVAL BIT(2) + + #define USB_TP_TRANSMISSION_DELAY 40 /* ns */ + #define USB_TP_TRANSMISSION_DELAY_MAX 65535 /* ns */ + #define USB_PING_RESPONSE_TIME 400 /* ns */ ++#define USB_REDUCE_FRAME_INTR_BINTERVAL 9 + + /* Protect struct usb_device->state and ->children members + * Note: Both are also protected by ->dev.sem, except that ->state can +@@ -1904,6 +1910,14 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) + usb_autopm_get_interface_no_resume(intf); + } + ++ if ((id->driver_info & HUB_QUIRK_REDUCE_FRAME_INTR_BINTERVAL) && ++ desc->endpoint[0].desc.bInterval > USB_REDUCE_FRAME_INTR_BINTERVAL) { ++ desc->endpoint[0].desc.bInterval = ++ USB_REDUCE_FRAME_INTR_BINTERVAL; ++ /* Tell the HCD about the interrupt ep's new bInterval */ ++ usb_set_interface(hdev, 0, 0); ++ } ++ + if (hub_configure(hub, &desc->endpoint[0].desc) >= 0) { + onboard_hub_create_pdevs(hdev, &hub->onboard_hub_devs); + +@@ -5895,6 +5909,21 @@ static const struct usb_device_id hub_id_table[] = { + .idVendor = USB_VENDOR_TEXAS_INSTRUMENTS, + .idProduct = USB_PRODUCT_TUSB8041_USB3, + .driver_info = HUB_QUIRK_DISABLE_AUTOSUSPEND}, ++ { .match_flags = USB_DEVICE_ID_MATCH_VENDOR ++ | USB_DEVICE_ID_MATCH_PRODUCT, ++ .idVendor = USB_VENDOR_MICROCHIP, ++ .idProduct = USB_PRODUCT_USB4913, ++ .driver_info = HUB_QUIRK_REDUCE_FRAME_INTR_BINTERVAL}, ++ { .match_flags = USB_DEVICE_ID_MATCH_VENDOR ++ | USB_DEVICE_ID_MATCH_PRODUCT, ++ .idVendor = USB_VENDOR_MICROCHIP, ++ .idProduct = USB_PRODUCT_USB4914, ++ .driver_info = HUB_QUIRK_REDUCE_FRAME_INTR_BINTERVAL}, ++ { .match_flags = USB_DEVICE_ID_MATCH_VENDOR ++ | USB_DEVICE_ID_MATCH_PRODUCT, ++ .idVendor = USB_VENDOR_MICROCHIP, ++ .idProduct = USB_PRODUCT_USB4915, ++ .driver_info = HUB_QUIRK_REDUCE_FRAME_INTR_BINTERVAL}, + { .match_flags = USB_DEVICE_ID_MATCH_DEV_CLASS, + .bDeviceClass = USB_CLASS_HUB}, + { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS, +diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c +index 732cdeb739202..f0853c4478f57 100644 +--- a/drivers/usb/host/xhci-plat.c ++++ b/drivers/usb/host/xhci-plat.c +@@ -433,7 +433,7 @@ void xhci_plat_remove(struct platform_device *dev) + } + EXPORT_SYMBOL_GPL(xhci_plat_remove); + +-static int __maybe_unused xhci_plat_suspend(struct device *dev) ++static int xhci_plat_suspend(struct device *dev) + { + struct usb_hcd *hcd = dev_get_drvdata(dev); + struct xhci_hcd *xhci = hcd_to_xhci(hcd); +@@ -461,7 +461,7 @@ static int __maybe_unused xhci_plat_suspend(struct device *dev) + return 0; + } + +-static int __maybe_unused xhci_plat_resume(struct device *dev) ++static int xhci_plat_resume_common(struct device *dev, struct pm_message pmsg) + { + struct usb_hcd *hcd = dev_get_drvdata(dev); + struct xhci_hcd *xhci = hcd_to_xhci(hcd); +@@ -483,7 +483,7 @@ static int __maybe_unused xhci_plat_resume(struct device *dev) + if (ret) + goto disable_clks; + +- ret = xhci_resume(xhci, PMSG_RESUME); ++ ret = xhci_resume(xhci, pmsg); + if (ret) + goto disable_clks; + +@@ -502,6 +502,16 @@ disable_clks: + return ret; + } + ++static int xhci_plat_resume(struct device *dev) ++{ ++ return xhci_plat_resume_common(dev, PMSG_RESUME); ++} ++ ++static int xhci_plat_restore(struct device *dev) ++{ ++ return xhci_plat_resume_common(dev, PMSG_RESTORE); ++} ++ + static int __maybe_unused xhci_plat_runtime_suspend(struct device *dev) + { + struct usb_hcd *hcd = dev_get_drvdata(dev); +@@ -524,7 +534,12 @@ static int __maybe_unused xhci_plat_runtime_resume(struct device *dev) + } + + const struct dev_pm_ops xhci_plat_pm_ops = { +- SET_SYSTEM_SLEEP_PM_OPS(xhci_plat_suspend, xhci_plat_resume) ++ .suspend = pm_sleep_ptr(xhci_plat_suspend), ++ .resume = pm_sleep_ptr(xhci_plat_resume), ++ .freeze = pm_sleep_ptr(xhci_plat_suspend), ++ .thaw = pm_sleep_ptr(xhci_plat_resume), ++ .poweroff = pm_sleep_ptr(xhci_plat_suspend), ++ .restore = pm_sleep_ptr(xhci_plat_restore), + + SET_RUNTIME_PM_OPS(xhci_plat_runtime_suspend, + xhci_plat_runtime_resume, +diff --git a/drivers/watchdog/it87_wdt.c b/drivers/watchdog/it87_wdt.c +index e888b1bdd1f2f..8c1ee072f48b8 100644 +--- a/drivers/watchdog/it87_wdt.c ++++ b/drivers/watchdog/it87_wdt.c +@@ -256,6 +256,7 @@ static struct watchdog_device wdt_dev = { + static int __init it87_wdt_init(void) + { + u8 chip_rev; ++ u8 ctrl; + int rc; + + rc = superio_enter(); +@@ -315,7 +316,18 @@ static int __init it87_wdt_init(void) + + superio_select(GPIO); + superio_outb(WDT_TOV1, WDTCFG); +- superio_outb(0x00, WDTCTRL); ++ ++ switch (chip_type) { ++ case IT8784_ID: ++ case IT8786_ID: ++ ctrl = superio_inb(WDTCTRL); ++ ctrl &= 0x08; ++ superio_outb(ctrl, WDTCTRL); ++ break; ++ default: ++ superio_outb(0x00, WDTCTRL); ++ } ++ + superio_exit(); + + if (timeout < 1 || timeout > max_units * 60) { +diff --git a/drivers/watchdog/starfive-wdt.c b/drivers/watchdog/starfive-wdt.c +index 5f501b41faf9d..49b38ecc092dd 100644 +--- a/drivers/watchdog/starfive-wdt.c ++++ b/drivers/watchdog/starfive-wdt.c +@@ -202,12 +202,14 @@ static u32 starfive_wdt_ticks_to_sec(struct starfive_wdt *wdt, u32 ticks) + + /* Write unlock-key to unlock. Write other value to lock. */ + static void starfive_wdt_unlock(struct starfive_wdt *wdt) ++ __acquires(&wdt->lock) + { + spin_lock(&wdt->lock); + writel(wdt->variant->unlock_key, wdt->base + wdt->variant->unlock); + } + + static void starfive_wdt_lock(struct starfive_wdt *wdt) ++ __releases(&wdt->lock) + { + writel(~wdt->variant->unlock_key, wdt->base + wdt->variant->unlock); + spin_unlock(&wdt->lock); +diff --git a/drivers/xen/gntdev-dmabuf.c b/drivers/xen/gntdev-dmabuf.c +index 4440e626b7975..42adc2c1e06b3 100644 +--- a/drivers/xen/gntdev-dmabuf.c ++++ b/drivers/xen/gntdev-dmabuf.c +@@ -11,6 +11,7 @@ + #include <linux/kernel.h> + #include <linux/errno.h> + #include <linux/dma-buf.h> ++#include <linux/dma-direct.h> + #include <linux/slab.h> + #include <linux/types.h> + #include <linux/uaccess.h> +@@ -50,7 +51,7 @@ struct gntdev_dmabuf { + + /* Number of pages this buffer has. */ + int nr_pages; +- /* Pages of this buffer. */ ++ /* Pages of this buffer (only for dma-buf export). */ + struct page **pages; + }; + +@@ -484,7 +485,7 @@ out: + /* DMA buffer import support. */ + + static int +-dmabuf_imp_grant_foreign_access(struct page **pages, u32 *refs, ++dmabuf_imp_grant_foreign_access(unsigned long *gfns, u32 *refs, + int count, int domid) + { + grant_ref_t priv_gref_head; +@@ -507,7 +508,7 @@ dmabuf_imp_grant_foreign_access(struct page **pages, u32 *refs, + } + + gnttab_grant_foreign_access_ref(cur_ref, domid, +- xen_page_to_gfn(pages[i]), 0); ++ gfns[i], 0); + refs[i] = cur_ref; + } + +@@ -529,7 +530,6 @@ static void dmabuf_imp_end_foreign_access(u32 *refs, int count) + + static void dmabuf_imp_free_storage(struct gntdev_dmabuf *gntdev_dmabuf) + { +- kfree(gntdev_dmabuf->pages); + kfree(gntdev_dmabuf->u.imp.refs); + kfree(gntdev_dmabuf); + } +@@ -549,12 +549,6 @@ static struct gntdev_dmabuf *dmabuf_imp_alloc_storage(int count) + if (!gntdev_dmabuf->u.imp.refs) + goto fail; + +- gntdev_dmabuf->pages = kcalloc(count, +- sizeof(gntdev_dmabuf->pages[0]), +- GFP_KERNEL); +- if (!gntdev_dmabuf->pages) +- goto fail; +- + gntdev_dmabuf->nr_pages = count; + + for (i = 0; i < count; i++) +@@ -576,7 +570,8 @@ dmabuf_imp_to_refs(struct gntdev_dmabuf_priv *priv, struct device *dev, + struct dma_buf *dma_buf; + struct dma_buf_attachment *attach; + struct sg_table *sgt; +- struct sg_page_iter sg_iter; ++ struct sg_dma_page_iter sg_iter; ++ unsigned long *gfns; + int i; + + dma_buf = dma_buf_get(fd); +@@ -624,26 +619,31 @@ dmabuf_imp_to_refs(struct gntdev_dmabuf_priv *priv, struct device *dev, + + gntdev_dmabuf->u.imp.sgt = sgt; + +- /* Now convert sgt to array of pages and check for page validity. */ ++ gfns = kcalloc(count, sizeof(*gfns), GFP_KERNEL); ++ if (!gfns) { ++ ret = ERR_PTR(-ENOMEM); ++ goto fail_unmap; ++ } ++ ++ /* ++ * Now convert sgt to array of gfns without accessing underlying pages. ++ * It is not allowed to access the underlying struct page of an sg table ++ * exported by DMA-buf, but since we deal with special Xen dma device here ++ * (not a normal physical one) look at the dma addresses in the sg table ++ * and then calculate gfns directly from them. ++ */ + i = 0; +- for_each_sgtable_page(sgt, &sg_iter, 0) { +- struct page *page = sg_page_iter_page(&sg_iter); +- /* +- * Check if page is valid: this can happen if we are given +- * a page from VRAM or other resources which are not backed +- * by a struct page. +- */ +- if (!pfn_valid(page_to_pfn(page))) { +- ret = ERR_PTR(-EINVAL); +- goto fail_unmap; +- } ++ for_each_sgtable_dma_page(sgt, &sg_iter, 0) { ++ dma_addr_t addr = sg_page_iter_dma_address(&sg_iter); ++ unsigned long pfn = bfn_to_pfn(XEN_PFN_DOWN(dma_to_phys(dev, addr))); + +- gntdev_dmabuf->pages[i++] = page; ++ gfns[i++] = pfn_to_gfn(pfn); + } + +- ret = ERR_PTR(dmabuf_imp_grant_foreign_access(gntdev_dmabuf->pages, ++ ret = ERR_PTR(dmabuf_imp_grant_foreign_access(gfns, + gntdev_dmabuf->u.imp.refs, + count, domid)); ++ kfree(gfns); + if (IS_ERR(ret)) + goto fail_end_access; + +diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h +index 731e3d14b67d3..0e8418066a482 100644 +--- a/fs/9p/v9fs_vfs.h ++++ b/fs/9p/v9fs_vfs.h +@@ -42,6 +42,7 @@ struct inode *v9fs_alloc_inode(struct super_block *sb); + void v9fs_free_inode(struct inode *inode); + struct inode *v9fs_get_inode(struct super_block *sb, umode_t mode, + dev_t rdev); ++void v9fs_set_netfs_context(struct inode *inode); + int v9fs_init_inode(struct v9fs_session_info *v9ses, + struct inode *inode, umode_t mode, dev_t rdev); + void v9fs_evict_inode(struct inode *inode); +diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c +index b845ee18a80be..90dc5ef755160 100644 +--- a/fs/9p/vfs_inode.c ++++ b/fs/9p/vfs_inode.c +@@ -246,7 +246,7 @@ void v9fs_free_inode(struct inode *inode) + /* + * Set parameters for the netfs library + */ +-static void v9fs_set_netfs_context(struct inode *inode) ++void v9fs_set_netfs_context(struct inode *inode) + { + struct v9fs_inode *v9inode = V9FS_I(inode); + netfs_inode_init(&v9inode->netfs, &v9fs_req_ops); +@@ -326,8 +326,6 @@ int v9fs_init_inode(struct v9fs_session_info *v9ses, + err = -EINVAL; + goto error; + } +- +- v9fs_set_netfs_context(inode); + error: + return err; + +@@ -359,6 +357,7 @@ struct inode *v9fs_get_inode(struct super_block *sb, umode_t mode, dev_t rdev) + iput(inode); + return ERR_PTR(err); + } ++ v9fs_set_netfs_context(inode); + return inode; + } + +@@ -464,6 +463,7 @@ static struct inode *v9fs_qid_iget(struct super_block *sb, + goto error; + + v9fs_stat2inode(st, inode, sb, 0); ++ v9fs_set_netfs_context(inode); + v9fs_cache_inode_get_cookie(inode); + unlock_new_inode(inode); + return inode; +diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c +index c7319af2f4711..d0636b99f05b9 100644 +--- a/fs/9p/vfs_inode_dotl.c ++++ b/fs/9p/vfs_inode_dotl.c +@@ -128,6 +128,7 @@ static struct inode *v9fs_qid_iget_dotl(struct super_block *sb, + goto error; + + v9fs_stat2inode_dotl(st, inode, 0); ++ v9fs_set_netfs_context(inode); + v9fs_cache_inode_get_cookie(inode); + retval = v9fs_get_acl(inode, fid); + if (retval) +diff --git a/fs/afs/callback.c b/fs/afs/callback.c +index a484fa6428081..90f9b2a46ff48 100644 +--- a/fs/afs/callback.c ++++ b/fs/afs/callback.c +@@ -110,13 +110,14 @@ static struct afs_volume *afs_lookup_volume_rcu(struct afs_cell *cell, + { + struct afs_volume *volume = NULL; + struct rb_node *p; +- int seq = 0; ++ int seq = 1; + + do { + /* Unfortunately, rbtree walking doesn't give reliable results + * under just the RCU read lock, so we have to check for + * changes. + */ ++ seq++; /* 2 on the 1st/lockless path, otherwise odd */ + read_seqbegin_or_lock(&cell->volume_lock, &seq); + + p = rcu_dereference_raw(cell->volumes.rb_node); +diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c +index 2c0b8dc3dd0d8..9c02f328c966c 100644 +--- a/fs/ceph/caps.c ++++ b/fs/ceph/caps.c +@@ -4887,13 +4887,15 @@ int ceph_encode_dentry_release(void **p, struct dentry *dentry, + struct inode *dir, + int mds, int drop, int unless) + { +- struct dentry *parent = NULL; + struct ceph_mds_request_release *rel = *p; + struct ceph_dentry_info *di = ceph_dentry(dentry); + struct ceph_client *cl; + int force = 0; + int ret; + ++ /* This shouldn't happen */ ++ BUG_ON(!dir); ++ + /* + * force an record for the directory caps if we have a dentry lease. + * this is racy (can't take i_ceph_lock and d_lock together), but it +@@ -4903,14 +4905,9 @@ int ceph_encode_dentry_release(void **p, struct dentry *dentry, + spin_lock(&dentry->d_lock); + if (di->lease_session && di->lease_session->s_mds == mds) + force = 1; +- if (!dir) { +- parent = dget(dentry->d_parent); +- dir = d_inode(parent); +- } + spin_unlock(&dentry->d_lock); + + ret = ceph_encode_inode_release(p, dir, mds, drop, unless, force); +- dput(parent); + + cl = ceph_inode_to_client(dir); + spin_lock(&dentry->d_lock); +diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c +index d95eb525519a6..558c3af44449c 100644 +--- a/fs/ceph/mds_client.c ++++ b/fs/ceph/mds_client.c +@@ -4128,12 +4128,12 @@ static void handle_session(struct ceph_mds_session *session, + pr_info_client(cl, "mds%d reconnect success\n", + session->s_mds); + ++ session->s_features = features; + if (session->s_state == CEPH_MDS_SESSION_OPEN) { + pr_notice_client(cl, "mds%d is already opened\n", + session->s_mds); + } else { + session->s_state = CEPH_MDS_SESSION_OPEN; +- session->s_features = features; + renewed_caps(mdsc, session, 0); + if (test_bit(CEPHFS_FEATURE_METRIC_COLLECT, + &session->s_features)) +diff --git a/fs/ceph/quota.c b/fs/ceph/quota.c +index 9d36c3532de14..06ee397e0c3a6 100644 +--- a/fs/ceph/quota.c ++++ b/fs/ceph/quota.c +@@ -197,10 +197,10 @@ void ceph_cleanup_quotarealms_inodes(struct ceph_mds_client *mdsc) + } + + /* +- * This function walks through the snaprealm for an inode and returns the +- * ceph_snap_realm for the first snaprealm that has quotas set (max_files, ++ * This function walks through the snaprealm for an inode and set the ++ * realmp with the first snaprealm that has quotas set (max_files, + * max_bytes, or any, depending on the 'which_quota' argument). If the root is +- * reached, return the root ceph_snap_realm instead. ++ * reached, set the realmp with the root ceph_snap_realm instead. + * + * Note that the caller is responsible for calling ceph_put_snap_realm() on the + * returned realm. +@@ -211,10 +211,9 @@ void ceph_cleanup_quotarealms_inodes(struct ceph_mds_client *mdsc) + * this function will return -EAGAIN; otherwise, the snaprealms walk-through + * will be restarted. + */ +-static struct ceph_snap_realm *get_quota_realm(struct ceph_mds_client *mdsc, +- struct inode *inode, +- enum quota_get_realm which_quota, +- bool retry) ++static int get_quota_realm(struct ceph_mds_client *mdsc, struct inode *inode, ++ enum quota_get_realm which_quota, ++ struct ceph_snap_realm **realmp, bool retry) + { + struct ceph_client *cl = mdsc->fsc->client; + struct ceph_inode_info *ci = NULL; +@@ -222,8 +221,10 @@ static struct ceph_snap_realm *get_quota_realm(struct ceph_mds_client *mdsc, + struct inode *in; + bool has_quota; + ++ if (realmp) ++ *realmp = NULL; + if (ceph_snap(inode) != CEPH_NOSNAP) +- return NULL; ++ return 0; + + restart: + realm = ceph_inode(inode)->i_snap_realm; +@@ -250,7 +251,7 @@ restart: + break; + ceph_put_snap_realm(mdsc, realm); + if (!retry) +- return ERR_PTR(-EAGAIN); ++ return -EAGAIN; + goto restart; + } + +@@ -259,8 +260,11 @@ restart: + iput(in); + + next = realm->parent; +- if (has_quota || !next) +- return realm; ++ if (has_quota || !next) { ++ if (realmp) ++ *realmp = realm; ++ return 0; ++ } + + ceph_get_snap_realm(mdsc, next); + ceph_put_snap_realm(mdsc, realm); +@@ -269,7 +273,7 @@ restart: + if (realm) + ceph_put_snap_realm(mdsc, realm); + +- return NULL; ++ return 0; + } + + bool ceph_quota_is_same_realm(struct inode *old, struct inode *new) +@@ -277,6 +281,7 @@ bool ceph_quota_is_same_realm(struct inode *old, struct inode *new) + struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(old->i_sb); + struct ceph_snap_realm *old_realm, *new_realm; + bool is_same; ++ int ret; + + restart: + /* +@@ -286,9 +291,9 @@ restart: + * dropped and we can then restart the whole operation. + */ + down_read(&mdsc->snap_rwsem); +- old_realm = get_quota_realm(mdsc, old, QUOTA_GET_ANY, true); +- new_realm = get_quota_realm(mdsc, new, QUOTA_GET_ANY, false); +- if (PTR_ERR(new_realm) == -EAGAIN) { ++ get_quota_realm(mdsc, old, QUOTA_GET_ANY, &old_realm, true); ++ ret = get_quota_realm(mdsc, new, QUOTA_GET_ANY, &new_realm, false); ++ if (ret == -EAGAIN) { + up_read(&mdsc->snap_rwsem); + if (old_realm) + ceph_put_snap_realm(mdsc, old_realm); +@@ -492,8 +497,8 @@ bool ceph_quota_update_statfs(struct ceph_fs_client *fsc, struct kstatfs *buf) + bool is_updated = false; + + down_read(&mdsc->snap_rwsem); +- realm = get_quota_realm(mdsc, d_inode(fsc->sb->s_root), +- QUOTA_GET_MAX_BYTES, true); ++ get_quota_realm(mdsc, d_inode(fsc->sb->s_root), QUOTA_GET_MAX_BYTES, ++ &realm, true); + up_read(&mdsc->snap_rwsem); + if (!realm) + return false; +diff --git a/fs/dcache.c b/fs/dcache.c +index c82ae731df9af..d1ab857a69cae 100644 +--- a/fs/dcache.c ++++ b/fs/dcache.c +@@ -787,12 +787,12 @@ static inline bool fast_dput(struct dentry *dentry) + */ + if (unlikely(ret < 0)) { + spin_lock(&dentry->d_lock); +- if (dentry->d_lockref.count > 1) { +- dentry->d_lockref.count--; ++ if (WARN_ON_ONCE(dentry->d_lockref.count <= 0)) { + spin_unlock(&dentry->d_lock); + return true; + } +- return false; ++ dentry->d_lockref.count--; ++ goto locked; + } + + /* +@@ -850,6 +850,7 @@ static inline bool fast_dput(struct dentry *dentry) + * else could have killed it and marked it dead. Either way, we + * don't need to do anything else. + */ ++locked: + if (dentry->d_lockref.count) { + spin_unlock(&dentry->d_lock); + return true; +diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c +index b0e8774c435a4..d7193687b9b4c 100644 +--- a/fs/ecryptfs/inode.c ++++ b/fs/ecryptfs/inode.c +@@ -78,6 +78,14 @@ static struct inode *__ecryptfs_get_inode(struct inode *lower_inode, + + if (lower_inode->i_sb != ecryptfs_superblock_to_lower(sb)) + return ERR_PTR(-EXDEV); ++ ++ /* Reject dealing with casefold directories. */ ++ if (IS_CASEFOLDED(lower_inode)) { ++ pr_err_ratelimited("%s: Can't handle casefolded directory.\n", ++ __func__); ++ return ERR_PTR(-EREMOTE); ++ } ++ + if (!igrab(lower_inode)) + return ERR_PTR(-ESTALE); + inode = iget5_locked(sb, (unsigned long)lower_inode, +diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c +index a33cd6757f984..1c0e6167d8e73 100644 +--- a/fs/erofs/zdata.c ++++ b/fs/erofs/zdata.c +@@ -815,7 +815,6 @@ static int z_erofs_register_pcluster(struct z_erofs_decompress_frontend *fe) + + if (ztailpacking) { + pcl->obj.index = 0; /* which indicates ztailpacking */ +- pcl->pageofs_in = erofs_blkoff(fe->inode->i_sb, map->m_pa); + pcl->tailpacking_size = map->m_plen; + } else { + pcl->obj.index = map->m_pa >> PAGE_SHIFT; +@@ -893,6 +892,7 @@ static int z_erofs_pcluster_begin(struct z_erofs_decompress_frontend *fe) + } + get_page(map->buf.page); + WRITE_ONCE(fe->pcl->compressed_bvecs[0].page, map->buf.page); ++ fe->pcl->pageofs_in = map->m_pa & ~PAGE_MASK; + fe->mode = Z_EROFS_PCLUSTER_FOLLOWED_NOINPLACE; + } + /* file-backed inplace I/O pages are traversed in reverse order */ +diff --git a/fs/erofs/zmap.c b/fs/erofs/zmap.c +index 7a1a24ae4a2d8..e313c936351d5 100644 +--- a/fs/erofs/zmap.c ++++ b/fs/erofs/zmap.c +@@ -82,29 +82,26 @@ static int z_erofs_load_full_lcluster(struct z_erofs_maprecorder *m, + } + + static unsigned int decode_compactedbits(unsigned int lobits, +- unsigned int lomask, + u8 *in, unsigned int pos, u8 *type) + { + const unsigned int v = get_unaligned_le32(in + pos / 8) >> (pos & 7); +- const unsigned int lo = v & lomask; ++ const unsigned int lo = v & ((1 << lobits) - 1); + + *type = (v >> lobits) & 3; + return lo; + } + +-static int get_compacted_la_distance(unsigned int lclusterbits, ++static int get_compacted_la_distance(unsigned int lobits, + unsigned int encodebits, + unsigned int vcnt, u8 *in, int i) + { +- const unsigned int lomask = (1 << lclusterbits) - 1; + unsigned int lo, d1 = 0; + u8 type; + + DBG_BUGON(i >= vcnt); + + do { +- lo = decode_compactedbits(lclusterbits, lomask, +- in, encodebits * i, &type); ++ lo = decode_compactedbits(lobits, in, encodebits * i, &type); + + if (type != Z_EROFS_LCLUSTER_TYPE_NONHEAD) + return d1; +@@ -123,15 +120,14 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m, + { + struct erofs_inode *const vi = EROFS_I(m->inode); + const unsigned int lclusterbits = vi->z_logical_clusterbits; +- const unsigned int lomask = (1 << lclusterbits) - 1; +- unsigned int vcnt, base, lo, encodebits, nblk, eofs; ++ unsigned int vcnt, base, lo, lobits, encodebits, nblk, eofs; + int i; + u8 *in, type; + bool big_pcluster; + + if (1 << amortizedshift == 4 && lclusterbits <= 14) + vcnt = 2; +- else if (1 << amortizedshift == 2 && lclusterbits == 12) ++ else if (1 << amortizedshift == 2 && lclusterbits <= 12) + vcnt = 16; + else + return -EOPNOTSUPP; +@@ -140,6 +136,7 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m, + m->nextpackoff = round_down(pos, vcnt << amortizedshift) + + (vcnt << amortizedshift); + big_pcluster = vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1; ++ lobits = max(lclusterbits, ilog2(Z_EROFS_LI_D0_CBLKCNT) + 1U); + encodebits = ((vcnt << amortizedshift) - sizeof(__le32)) * 8 / vcnt; + eofs = erofs_blkoff(m->inode->i_sb, pos); + base = round_down(eofs, vcnt << amortizedshift); +@@ -147,15 +144,14 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m, + + i = (eofs - base) >> amortizedshift; + +- lo = decode_compactedbits(lclusterbits, lomask, +- in, encodebits * i, &type); ++ lo = decode_compactedbits(lobits, in, encodebits * i, &type); + m->type = type; + if (type == Z_EROFS_LCLUSTER_TYPE_NONHEAD) { + m->clusterofs = 1 << lclusterbits; + + /* figure out lookahead_distance: delta[1] if needed */ + if (lookahead) +- m->delta[1] = get_compacted_la_distance(lclusterbits, ++ m->delta[1] = get_compacted_la_distance(lobits, + encodebits, vcnt, in, i); + if (lo & Z_EROFS_LI_D0_CBLKCNT) { + if (!big_pcluster) { +@@ -174,8 +170,8 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m, + * of which lo saves delta[1] rather than delta[0]. + * Hence, get delta[0] by the previous lcluster indirectly. + */ +- lo = decode_compactedbits(lclusterbits, lomask, +- in, encodebits * (i - 1), &type); ++ lo = decode_compactedbits(lobits, in, ++ encodebits * (i - 1), &type); + if (type != Z_EROFS_LCLUSTER_TYPE_NONHEAD) + lo = 0; + else if (lo & Z_EROFS_LI_D0_CBLKCNT) +@@ -190,8 +186,8 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m, + nblk = 1; + while (i > 0) { + --i; +- lo = decode_compactedbits(lclusterbits, lomask, +- in, encodebits * i, &type); ++ lo = decode_compactedbits(lobits, in, ++ encodebits * i, &type); + if (type == Z_EROFS_LCLUSTER_TYPE_NONHEAD) + i -= lo; + +@@ -202,8 +198,8 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m, + nblk = 0; + while (i > 0) { + --i; +- lo = decode_compactedbits(lclusterbits, lomask, +- in, encodebits * i, &type); ++ lo = decode_compactedbits(lobits, in, ++ encodebits * i, &type); + if (type == Z_EROFS_LCLUSTER_TYPE_NONHEAD) { + if (lo & Z_EROFS_LI_D0_CBLKCNT) { + --i; +diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c +index d5efe076d3d3f..01299b55a567a 100644 +--- a/fs/ext4/extents.c ++++ b/fs/ext4/extents.c +@@ -4523,7 +4523,8 @@ static long ext4_zero_range(struct file *file, loff_t offset, + * Round up offset. This is not fallocate, we need to zero out + * blocks, so convert interior block aligned part of the range to + * unwritten and possibly manually zero out unaligned parts of the +- * range. ++ * range. Here, start and partial_begin are inclusive, end and ++ * partial_end are exclusive. + */ + start = round_up(offset, 1 << blkbits); + end = round_down((offset + len), 1 << blkbits); +@@ -4609,7 +4610,8 @@ static long ext4_zero_range(struct file *file, loff_t offset, + * disk in case of crash before zeroing trans is committed. + */ + if (ext4_should_journal_data(inode)) { +- ret = filemap_write_and_wait_range(mapping, start, end); ++ ret = filemap_write_and_wait_range(mapping, start, ++ end - 1); + if (ret) { + filemap_invalidate_unlock(mapping); + goto out_mutex; +diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c +index ab023d709f72b..8408318e1d32e 100644 +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -6758,13 +6758,15 @@ static int ext4_try_to_trim_range(struct super_block *sb, + __acquires(ext4_group_lock_ptr(sb, e4b->bd_group)) + __releases(ext4_group_lock_ptr(sb, e4b->bd_group)) + { +- ext4_grpblk_t next, count, free_count; ++ ext4_grpblk_t next, count, free_count, last, origin_start; + bool set_trimmed = false; + void *bitmap; + ++ last = ext4_last_grp_cluster(sb, e4b->bd_group); + bitmap = e4b->bd_bitmap; +- if (start == 0 && max >= ext4_last_grp_cluster(sb, e4b->bd_group)) ++ if (start == 0 && max >= last) + set_trimmed = true; ++ origin_start = start; + start = max(e4b->bd_info->bb_first_free, start); + count = 0; + free_count = 0; +@@ -6773,7 +6775,10 @@ __releases(ext4_group_lock_ptr(sb, e4b->bd_group)) + start = mb_find_next_zero_bit(bitmap, max + 1, start); + if (start > max) + break; +- next = mb_find_next_bit(bitmap, max + 1, start); ++ ++ next = mb_find_next_bit(bitmap, last + 1, start); ++ if (origin_start == 0 && next >= last) ++ set_trimmed = true; + + if ((next - start) >= minblocks) { + int ret = ext4_trim_extent(sb, start, next - start, e4b); +diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c +index 4fe061edefdde..e168a9f596001 100644 +--- a/fs/ext4/resize.c ++++ b/fs/ext4/resize.c +@@ -218,17 +218,24 @@ struct ext4_new_flex_group_data { + in the flex group */ + __u16 *bg_flags; /* block group flags of groups + in @groups */ ++ ext4_group_t resize_bg; /* number of allocated ++ new_group_data */ + ext4_group_t count; /* number of groups in @groups + */ + }; + ++/* ++ * Avoiding memory allocation failures due to too many groups added each time. ++ */ ++#define MAX_RESIZE_BG 16384 ++ + /* + * alloc_flex_gd() allocates a ext4_new_flex_group_data with size of + * @flexbg_size. + * + * Returns NULL on failure otherwise address of the allocated structure. + */ +-static struct ext4_new_flex_group_data *alloc_flex_gd(unsigned long flexbg_size) ++static struct ext4_new_flex_group_data *alloc_flex_gd(unsigned int flexbg_size) + { + struct ext4_new_flex_group_data *flex_gd; + +@@ -236,17 +243,18 @@ static struct ext4_new_flex_group_data *alloc_flex_gd(unsigned long flexbg_size) + if (flex_gd == NULL) + goto out3; + +- if (flexbg_size >= UINT_MAX / sizeof(struct ext4_new_group_data)) +- goto out2; +- flex_gd->count = flexbg_size; ++ if (unlikely(flexbg_size > MAX_RESIZE_BG)) ++ flex_gd->resize_bg = MAX_RESIZE_BG; ++ else ++ flex_gd->resize_bg = flexbg_size; + +- flex_gd->groups = kmalloc_array(flexbg_size, ++ flex_gd->groups = kmalloc_array(flex_gd->resize_bg, + sizeof(struct ext4_new_group_data), + GFP_NOFS); + if (flex_gd->groups == NULL) + goto out2; + +- flex_gd->bg_flags = kmalloc_array(flexbg_size, sizeof(__u16), ++ flex_gd->bg_flags = kmalloc_array(flex_gd->resize_bg, sizeof(__u16), + GFP_NOFS); + if (flex_gd->bg_flags == NULL) + goto out1; +@@ -283,7 +291,7 @@ static void free_flex_gd(struct ext4_new_flex_group_data *flex_gd) + */ + static int ext4_alloc_group_tables(struct super_block *sb, + struct ext4_new_flex_group_data *flex_gd, +- int flexbg_size) ++ unsigned int flexbg_size) + { + struct ext4_new_group_data *group_data = flex_gd->groups; + ext4_fsblk_t start_blk; +@@ -384,12 +392,12 @@ next_group: + group = group_data[0].group; + + printk(KERN_DEBUG "EXT4-fs: adding a flex group with " +- "%d groups, flexbg size is %d:\n", flex_gd->count, ++ "%u groups, flexbg size is %u:\n", flex_gd->count, + flexbg_size); + + for (i = 0; i < flex_gd->count; i++) { + ext4_debug( +- "adding %s group %u: %u blocks (%d free, %d mdata blocks)\n", ++ "adding %s group %u: %u blocks (%u free, %u mdata blocks)\n", + ext4_bg_has_super(sb, group + i) ? "normal" : + "no-super", group + i, + group_data[i].blocks_count, +@@ -1605,8 +1613,7 @@ exit: + + static int ext4_setup_next_flex_gd(struct super_block *sb, + struct ext4_new_flex_group_data *flex_gd, +- ext4_fsblk_t n_blocks_count, +- unsigned long flexbg_size) ++ ext4_fsblk_t n_blocks_count) + { + struct ext4_sb_info *sbi = EXT4_SB(sb); + struct ext4_super_block *es = sbi->s_es; +@@ -1630,7 +1637,7 @@ static int ext4_setup_next_flex_gd(struct super_block *sb, + BUG_ON(last); + ext4_get_group_no_and_offset(sb, n_blocks_count - 1, &n_group, &last); + +- last_group = group | (flexbg_size - 1); ++ last_group = group | (flex_gd->resize_bg - 1); + if (last_group > n_group) + last_group = n_group; + +@@ -1990,8 +1997,9 @@ int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count) + ext4_fsblk_t o_blocks_count; + ext4_fsblk_t n_blocks_count_retry = 0; + unsigned long last_update_time = 0; +- int err = 0, flexbg_size = 1 << sbi->s_log_groups_per_flex; ++ int err = 0; + int meta_bg; ++ unsigned int flexbg_size = ext4_flex_bg_size(sbi); + + /* See if the device is actually as big as what was requested */ + bh = ext4_sb_bread(sb, n_blocks_count - 1, 0); +@@ -2132,8 +2140,7 @@ retry: + /* Add flex groups. Note that a regular group is a + * flex group with 1 group. + */ +- while (ext4_setup_next_flex_gd(sb, flex_gd, n_blocks_count, +- flexbg_size)) { ++ while (ext4_setup_next_flex_gd(sb, flex_gd, n_blocks_count)) { + if (time_is_before_jiffies(last_update_time + HZ * 10)) { + if (last_update_time) + ext4_msg(sb, KERN_INFO, +diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c +index 36e5dab6baaee..62119f3f7206d 100644 +--- a/fs/f2fs/compress.c ++++ b/fs/f2fs/compress.c +@@ -1036,8 +1036,10 @@ static void set_cluster_dirty(struct compress_ctx *cc) + int i; + + for (i = 0; i < cc->cluster_size; i++) +- if (cc->rpages[i]) ++ if (cc->rpages[i]) { + set_page_dirty(cc->rpages[i]); ++ set_page_private_gcing(cc->rpages[i]); ++ } + } + + static int prepare_compress_overwrite(struct compress_ctx *cc, +diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c +index 8912511980ae2..a05781e708d66 100644 +--- a/fs/f2fs/file.c ++++ b/fs/f2fs/file.c +@@ -1317,6 +1317,7 @@ static int __clone_blkaddrs(struct inode *src_inode, struct inode *dst_inode, + } + memcpy_page(pdst, 0, psrc, 0, PAGE_SIZE); + set_page_dirty(pdst); ++ set_page_private_gcing(pdst); + f2fs_put_page(pdst, 1); + f2fs_put_page(psrc, 1); + +@@ -4059,6 +4060,7 @@ static int redirty_blocks(struct inode *inode, pgoff_t page_idx, int len) + f2fs_bug_on(F2FS_I_SB(inode), !page); + + set_page_dirty(page); ++ set_page_private_gcing(page); + f2fs_put_page(page, 1); + f2fs_put_page(page, 0); + } +diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c +index b56d0f1078a76..d0f24ccbd1ac6 100644 +--- a/fs/f2fs/recovery.c ++++ b/fs/f2fs/recovery.c +@@ -712,7 +712,16 @@ retry_dn: + */ + if (dest == NEW_ADDR) { + f2fs_truncate_data_blocks_range(&dn, 1); +- f2fs_reserve_new_block(&dn); ++ do { ++ err = f2fs_reserve_new_block(&dn); ++ if (err == -ENOSPC) { ++ f2fs_bug_on(sbi, 1); ++ break; ++ } ++ } while (err && ++ IS_ENABLED(CONFIG_F2FS_FAULT_INJECTION)); ++ if (err) ++ goto err; + continue; + } + +@@ -720,12 +729,14 @@ retry_dn: + if (f2fs_is_valid_blkaddr(sbi, dest, META_POR)) { + + if (src == NULL_ADDR) { +- err = f2fs_reserve_new_block(&dn); +- while (err && +- IS_ENABLED(CONFIG_F2FS_FAULT_INJECTION)) ++ do { + err = f2fs_reserve_new_block(&dn); +- /* We should not get -ENOSPC */ +- f2fs_bug_on(sbi, err); ++ if (err == -ENOSPC) { ++ f2fs_bug_on(sbi, 1); ++ break; ++ } ++ } while (err && ++ IS_ENABLED(CONFIG_F2FS_FAULT_INJECTION)); + if (err) + goto err; + } +@@ -906,6 +917,8 @@ skip: + if (!err && fix_curseg_write_pointer && !f2fs_readonly(sbi->sb) && + f2fs_sb_has_blkzoned(sbi)) { + err = f2fs_fix_curseg_write_pointer(sbi); ++ if (!err) ++ err = f2fs_check_write_pointer(sbi); + ret = err; + } + +diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c +index 11c77757ead9e..cb3cda1390adb 100644 +--- a/fs/jfs/jfs_dmap.c ++++ b/fs/jfs/jfs_dmap.c +@@ -63,10 +63,10 @@ + */ + static void dbAllocBits(struct bmap * bmp, struct dmap * dp, s64 blkno, + int nblocks); +-static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval); +-static int dbBackSplit(dmtree_t * tp, int leafno); +-static int dbJoin(dmtree_t * tp, int leafno, int newval); +-static void dbAdjTree(dmtree_t * tp, int leafno, int newval); ++static void dbSplit(dmtree_t *tp, int leafno, int splitsz, int newval, bool is_ctl); ++static int dbBackSplit(dmtree_t *tp, int leafno, bool is_ctl); ++static int dbJoin(dmtree_t *tp, int leafno, int newval, bool is_ctl); ++static void dbAdjTree(dmtree_t *tp, int leafno, int newval, bool is_ctl); + static int dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc, + int level); + static int dbAllocAny(struct bmap * bmp, s64 nblocks, int l2nb, s64 * results); +@@ -2103,7 +2103,7 @@ static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno, + * system. + */ + if (dp->tree.stree[word] == NOFREE) +- dbBackSplit((dmtree_t *) & dp->tree, word); ++ dbBackSplit((dmtree_t *)&dp->tree, word, false); + + dbAllocBits(bmp, dp, blkno, nblocks); + } +@@ -2189,7 +2189,7 @@ static void dbAllocBits(struct bmap * bmp, struct dmap * dp, s64 blkno, + * the binary system of the leaves if need be. + */ + dbSplit(tp, word, BUDMIN, +- dbMaxBud((u8 *) & dp->wmap[word])); ++ dbMaxBud((u8 *)&dp->wmap[word]), false); + + word += 1; + } else { +@@ -2229,7 +2229,7 @@ static void dbAllocBits(struct bmap * bmp, struct dmap * dp, s64 blkno, + * system of the leaves to reflect the current + * allocation (size). + */ +- dbSplit(tp, word, size, NOFREE); ++ dbSplit(tp, word, size, NOFREE, false); + + /* get the number of dmap words handled */ + nw = BUDSIZE(size, BUDMIN); +@@ -2336,7 +2336,7 @@ static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno, + /* update the leaf for this dmap word. + */ + rc = dbJoin(tp, word, +- dbMaxBud((u8 *) & dp->wmap[word])); ++ dbMaxBud((u8 *)&dp->wmap[word]), false); + if (rc) + return rc; + +@@ -2369,7 +2369,7 @@ static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno, + + /* update the leaf. + */ +- rc = dbJoin(tp, word, size); ++ rc = dbJoin(tp, word, size, false); + if (rc) + return rc; + +@@ -2521,16 +2521,16 @@ dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc, int level) + * that it is at the front of a binary buddy system. + */ + if (oldval == NOFREE) { +- rc = dbBackSplit((dmtree_t *) dcp, leafno); ++ rc = dbBackSplit((dmtree_t *)dcp, leafno, true); + if (rc) { + release_metapage(mp); + return rc; + } + oldval = dcp->stree[ti]; + } +- dbSplit((dmtree_t *) dcp, leafno, dcp->budmin, newval); ++ dbSplit((dmtree_t *) dcp, leafno, dcp->budmin, newval, true); + } else { +- rc = dbJoin((dmtree_t *) dcp, leafno, newval); ++ rc = dbJoin((dmtree_t *) dcp, leafno, newval, true); + if (rc) { + release_metapage(mp); + return rc; +@@ -2561,7 +2561,7 @@ dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc, int level) + */ + if (alloc) { + dbJoin((dmtree_t *) dcp, leafno, +- oldval); ++ oldval, true); + } else { + /* the dbJoin() above might have + * caused a larger binary buddy system +@@ -2571,9 +2571,9 @@ dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc, int level) + */ + if (dcp->stree[ti] == NOFREE) + dbBackSplit((dmtree_t *) +- dcp, leafno); ++ dcp, leafno, true); + dbSplit((dmtree_t *) dcp, leafno, +- dcp->budmin, oldval); ++ dcp->budmin, oldval, true); + } + + /* release the buffer and return the error. +@@ -2621,7 +2621,7 @@ dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc, int level) + * + * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit; + */ +-static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval) ++static void dbSplit(dmtree_t *tp, int leafno, int splitsz, int newval, bool is_ctl) + { + int budsz; + int cursz; +@@ -2643,7 +2643,7 @@ static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval) + while (cursz >= splitsz) { + /* update the buddy's leaf with its new value. + */ +- dbAdjTree(tp, leafno ^ budsz, cursz); ++ dbAdjTree(tp, leafno ^ budsz, cursz, is_ctl); + + /* on to the next size and buddy. + */ +@@ -2655,7 +2655,7 @@ static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval) + /* adjust the dmap tree to reflect the specified leaf's new + * value. + */ +- dbAdjTree(tp, leafno, newval); ++ dbAdjTree(tp, leafno, newval, is_ctl); + } + + +@@ -2686,7 +2686,7 @@ static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval) + * + * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit; + */ +-static int dbBackSplit(dmtree_t * tp, int leafno) ++static int dbBackSplit(dmtree_t *tp, int leafno, bool is_ctl) + { + int budsz, bud, w, bsz, size; + int cursz; +@@ -2737,7 +2737,7 @@ static int dbBackSplit(dmtree_t * tp, int leafno) + * system in two. + */ + cursz = leaf[bud] - 1; +- dbSplit(tp, bud, cursz, cursz); ++ dbSplit(tp, bud, cursz, cursz, is_ctl); + break; + } + } +@@ -2765,7 +2765,7 @@ static int dbBackSplit(dmtree_t * tp, int leafno) + * + * RETURN VALUES: none + */ +-static int dbJoin(dmtree_t * tp, int leafno, int newval) ++static int dbJoin(dmtree_t *tp, int leafno, int newval, bool is_ctl) + { + int budsz, buddy; + s8 *leaf; +@@ -2820,12 +2820,12 @@ static int dbJoin(dmtree_t * tp, int leafno, int newval) + if (leafno < buddy) { + /* leafno is the left buddy. + */ +- dbAdjTree(tp, buddy, NOFREE); ++ dbAdjTree(tp, buddy, NOFREE, is_ctl); + } else { + /* buddy is the left buddy and becomes + * leafno. + */ +- dbAdjTree(tp, leafno, NOFREE); ++ dbAdjTree(tp, leafno, NOFREE, is_ctl); + leafno = buddy; + } + +@@ -2838,7 +2838,7 @@ static int dbJoin(dmtree_t * tp, int leafno, int newval) + + /* update the leaf value. + */ +- dbAdjTree(tp, leafno, newval); ++ dbAdjTree(tp, leafno, newval, is_ctl); + + return 0; + } +@@ -2859,15 +2859,20 @@ static int dbJoin(dmtree_t * tp, int leafno, int newval) + * + * RETURN VALUES: none + */ +-static void dbAdjTree(dmtree_t * tp, int leafno, int newval) ++static void dbAdjTree(dmtree_t *tp, int leafno, int newval, bool is_ctl) + { + int lp, pp, k; +- int max; ++ int max, size; ++ ++ size = is_ctl ? CTLTREESIZE : TREESIZE; + + /* pick up the index of the leaf for this leafno. + */ + lp = leafno + le32_to_cpu(tp->dmt_leafidx); + ++ if (WARN_ON_ONCE(lp >= size || lp < 0)) ++ return; ++ + /* is the current value the same as the old value ? if so, + * there is nothing to do. + */ +diff --git a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c +index 92b7c533407c1..031d8f570f581 100644 +--- a/fs/jfs/jfs_dtree.c ++++ b/fs/jfs/jfs_dtree.c +@@ -633,6 +633,11 @@ int dtSearch(struct inode *ip, struct component_name * key, ino_t * data, + for (base = 0, lim = p->header.nextindex; lim; lim >>= 1) { + index = base + (lim >> 1); + ++ if (stbl[index] < 0) { ++ rc = -EIO; ++ goto out; ++ } ++ + if (p->header.flag & BT_LEAF) { + /* uppercase leaf name to compare */ + cmp = +@@ -1970,7 +1975,7 @@ static int dtSplitRoot(tid_t tid, + do { + f = &rp->slot[fsi]; + fsi = f->next; +- } while (fsi != -1); ++ } while (fsi >= 0); + + f->next = n; + } +diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c +index a037ee59e3985..2ec35889ad24e 100644 +--- a/fs/jfs/jfs_imap.c ++++ b/fs/jfs/jfs_imap.c +@@ -2179,6 +2179,9 @@ static int diNewExt(struct inomap * imap, struct iag * iagp, int extno) + /* get the ag and iag numbers for this iag. + */ + agno = BLKTOAG(le64_to_cpu(iagp->agstart), sbi); ++ if (agno >= MAXAG || agno < 0) ++ return -EIO; ++ + iagno = le32_to_cpu(iagp->iagnum); + + /* check if this is the last free extent within the +diff --git a/fs/jfs/jfs_mount.c b/fs/jfs/jfs_mount.c +index 415eb65a36ffc..9b5c6a20b30c8 100644 +--- a/fs/jfs/jfs_mount.c ++++ b/fs/jfs/jfs_mount.c +@@ -172,15 +172,15 @@ int jfs_mount(struct super_block *sb) + } + jfs_info("jfs_mount: ipimap:0x%p", ipimap); + +- /* map further access of per fileset inodes by the fileset inode */ +- sbi->ipimap = ipimap; +- + /* initialize fileset inode allocation map */ + if ((rc = diMount(ipimap))) { + jfs_err("jfs_mount: diMount failed w/rc = %d", rc); + goto err_ipimap; + } + ++ /* map further access of per fileset inodes by the fileset inode */ ++ sbi->ipimap = ipimap; ++ + return rc; + + /* +diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c +index 8b2bd65d70e72..62d39ecf0a466 100644 +--- a/fs/kernfs/dir.c ++++ b/fs/kernfs/dir.c +@@ -676,6 +676,18 @@ struct kernfs_node *kernfs_new_node(struct kernfs_node *parent, + { + struct kernfs_node *kn; + ++ if (parent->mode & S_ISGID) { ++ /* this code block imitates inode_init_owner() for ++ * kernfs ++ */ ++ ++ if (parent->iattr) ++ gid = parent->iattr->ia_gid; ++ ++ if (flags & KERNFS_DIR) ++ mode |= S_ISGID; ++ } ++ + kn = __kernfs_new_node(kernfs_root(parent), parent, + name, mode, uid, gid, flags); + if (kn) { +diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c +index 814733ba2f4ba..9221a33f917b8 100644 +--- a/fs/ocfs2/namei.c ++++ b/fs/ocfs2/namei.c +@@ -1336,7 +1336,7 @@ static int ocfs2_rename(struct mnt_idmap *idmap, + goto bail; + } + +- if (S_ISDIR(old_inode->i_mode)) { ++ if (S_ISDIR(old_inode->i_mode) && new_dir != old_dir) { + u64 old_inode_parent; + + update_dot_dot = 1; +@@ -1353,8 +1353,7 @@ static int ocfs2_rename(struct mnt_idmap *idmap, + goto bail; + } + +- if (!new_inode && new_dir != old_dir && +- new_dir->i_nlink >= ocfs2_link_max(osb)) { ++ if (!new_inode && new_dir->i_nlink >= ocfs2_link_max(osb)) { + status = -EMLINK; + goto bail; + } +@@ -1601,6 +1600,9 @@ static int ocfs2_rename(struct mnt_idmap *idmap, + mlog_errno(status); + goto bail; + } ++ } ++ ++ if (S_ISDIR(old_inode->i_mode)) { + drop_nlink(old_dir); + if (new_inode) { + drop_nlink(new_inode); +diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c +index 8064ea76f80b5..84abf98340a04 100644 +--- a/fs/proc/proc_sysctl.c ++++ b/fs/proc/proc_sysctl.c +@@ -44,7 +44,7 @@ static struct ctl_table sysctl_mount_point[] = { + */ + struct ctl_table_header *register_sysctl_mount_point(const char *path) + { +- return register_sysctl_sz(path, sysctl_mount_point, 0); ++ return register_sysctl(path, sysctl_mount_point); + } + EXPORT_SYMBOL(register_sysctl_mount_point); + +@@ -233,7 +233,8 @@ static int insert_header(struct ctl_dir *dir, struct ctl_table_header *header) + return -EROFS; + + /* Am I creating a permanently empty directory? */ +- if (sysctl_is_perm_empty_ctl_table(header->ctl_table)) { ++ if (header->ctl_table_size > 0 && ++ sysctl_is_perm_empty_ctl_table(header->ctl_table)) { + if (!RB_EMPTY_ROOT(&dir->root)) + return -EINVAL; + sysctl_set_perm_empty_ctl_header(dir_h); +@@ -1213,6 +1214,10 @@ static bool get_links(struct ctl_dir *dir, + struct ctl_table_header *tmp_head; + struct ctl_table *entry, *link; + ++ if (header->ctl_table_size == 0 || ++ sysctl_is_perm_empty_ctl_table(header->ctl_table)) ++ return true; ++ + /* Are there links available for every entry in table? */ + list_for_each_table_entry(entry, header) { + const char *procname = entry->procname; +diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c +index d36702c7ab3c4..88b34fdbf7592 100644 +--- a/fs/pstore/ram.c ++++ b/fs/pstore/ram.c +@@ -529,6 +529,7 @@ static int ramoops_init_przs(const char *name, + } + + zone_sz = mem_sz / *cnt; ++ zone_sz = ALIGN_DOWN(zone_sz, 2); + if (!zone_sz) { + dev_err(dev, "%s zone size == 0\n", name); + goto fail; +diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c +index 994d6e6995ab1..5996197ba40ca 100644 +--- a/fs/reiserfs/namei.c ++++ b/fs/reiserfs/namei.c +@@ -1324,8 +1324,8 @@ static int reiserfs_rename(struct mnt_idmap *idmap, + struct inode *old_inode, *new_dentry_inode; + struct reiserfs_transaction_handle th; + int jbegin_count; +- umode_t old_inode_mode; + unsigned long savelink = 1; ++ bool update_dir_parent = false; + + if (flags & ~RENAME_NOREPLACE) + return -EINVAL; +@@ -1375,8 +1375,7 @@ static int reiserfs_rename(struct mnt_idmap *idmap, + return -ENOENT; + } + +- old_inode_mode = old_inode->i_mode; +- if (S_ISDIR(old_inode_mode)) { ++ if (S_ISDIR(old_inode->i_mode)) { + /* + * make sure that directory being renamed has correct ".." + * and that its new parent directory has not too many links +@@ -1389,24 +1388,28 @@ static int reiserfs_rename(struct mnt_idmap *idmap, + } + } + +- /* +- * directory is renamed, its parent directory will be changed, +- * so find ".." entry +- */ +- dot_dot_de.de_gen_number_bit_string = NULL; +- retval = +- reiserfs_find_entry(old_inode, "..", 2, &dot_dot_entry_path, ++ if (old_dir != new_dir) { ++ /* ++ * directory is renamed, its parent directory will be ++ * changed, so find ".." entry ++ */ ++ dot_dot_de.de_gen_number_bit_string = NULL; ++ retval = ++ reiserfs_find_entry(old_inode, "..", 2, ++ &dot_dot_entry_path, + &dot_dot_de); +- pathrelse(&dot_dot_entry_path); +- if (retval != NAME_FOUND) { +- reiserfs_write_unlock(old_dir->i_sb); +- return -EIO; +- } ++ pathrelse(&dot_dot_entry_path); ++ if (retval != NAME_FOUND) { ++ reiserfs_write_unlock(old_dir->i_sb); ++ return -EIO; ++ } + +- /* inode number of .. must equal old_dir->i_ino */ +- if (dot_dot_de.de_objectid != old_dir->i_ino) { +- reiserfs_write_unlock(old_dir->i_sb); +- return -EIO; ++ /* inode number of .. must equal old_dir->i_ino */ ++ if (dot_dot_de.de_objectid != old_dir->i_ino) { ++ reiserfs_write_unlock(old_dir->i_sb); ++ return -EIO; ++ } ++ update_dir_parent = true; + } + } + +@@ -1486,7 +1489,7 @@ static int reiserfs_rename(struct mnt_idmap *idmap, + + reiserfs_prepare_for_journal(old_inode->i_sb, new_de.de_bh, 1); + +- if (S_ISDIR(old_inode->i_mode)) { ++ if (update_dir_parent) { + if ((retval = + search_by_entry_key(new_dir->i_sb, + &dot_dot_de.de_entry_key, +@@ -1534,14 +1537,14 @@ static int reiserfs_rename(struct mnt_idmap *idmap, + new_de.de_bh); + reiserfs_restore_prepared_buffer(old_inode->i_sb, + old_de.de_bh); +- if (S_ISDIR(old_inode_mode)) ++ if (update_dir_parent) + reiserfs_restore_prepared_buffer(old_inode-> + i_sb, + dot_dot_de. + de_bh); + continue; + } +- if (S_ISDIR(old_inode_mode)) { ++ if (update_dir_parent) { + if (item_moved(&dot_dot_ih, &dot_dot_entry_path) || + !entry_points_to_object("..", 2, &dot_dot_de, + old_dir)) { +@@ -1559,7 +1562,7 @@ static int reiserfs_rename(struct mnt_idmap *idmap, + } + } + +- RFALSE(S_ISDIR(old_inode_mode) && ++ RFALSE(update_dir_parent && + !buffer_journal_prepared(dot_dot_de.de_bh), ""); + + break; +@@ -1592,11 +1595,12 @@ static int reiserfs_rename(struct mnt_idmap *idmap, + savelink = new_dentry_inode->i_nlink; + } + +- if (S_ISDIR(old_inode_mode)) { ++ if (update_dir_parent) { + /* adjust ".." of renamed directory */ + set_ino_in_dir_entry(&dot_dot_de, INODE_PKEY(new_dir)); + journal_mark_dirty(&th, dot_dot_de.de_bh); +- ++ } ++ if (S_ISDIR(old_inode->i_mode)) { + /* + * there (in new_dir) was no directory, so it got new link + * (".." of renamed directory) +diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h +index 5e32c79f03a74..942e6ece56b1a 100644 +--- a/fs/smb/client/cifsglob.h ++++ b/fs/smb/client/cifsglob.h +@@ -205,9 +205,18 @@ struct cifs_open_info_data { + }; + }; + +-#define cifs_open_data_reparse(d) \ +- ((d)->reparse_point || \ +- (le32_to_cpu((d)->fi.Attributes) & ATTR_REPARSE)) ++static inline bool cifs_open_data_reparse(struct cifs_open_info_data *data) ++{ ++ struct smb2_file_all_info *fi = &data->fi; ++ u32 attrs = le32_to_cpu(fi->Attributes); ++ bool ret; ++ ++ ret = data->reparse_point || (attrs & ATTR_REPARSE); ++ if (ret) ++ attrs |= ATTR_REPARSE; ++ fi->Attributes = cpu_to_le32(attrs); ++ return ret; ++} + + static inline void cifs_free_open_info(struct cifs_open_info_data *data) + { +@@ -390,12 +399,17 @@ struct smb_version_operations { + int (*rename_pending_delete)(const char *, struct dentry *, + const unsigned int); + /* send rename request */ +- int (*rename)(const unsigned int, struct cifs_tcon *, const char *, +- const char *, struct cifs_sb_info *); ++ int (*rename)(const unsigned int xid, ++ struct cifs_tcon *tcon, ++ struct dentry *source_dentry, ++ const char *from_name, const char *to_name, ++ struct cifs_sb_info *cifs_sb); + /* send create hardlink request */ +- int (*create_hardlink)(const unsigned int, struct cifs_tcon *, +- const char *, const char *, +- struct cifs_sb_info *); ++ int (*create_hardlink)(const unsigned int xid, ++ struct cifs_tcon *tcon, ++ struct dentry *source_dentry, ++ const char *from_name, const char *to_name, ++ struct cifs_sb_info *cifs_sb); + /* query symlink target */ + int (*query_symlink)(const unsigned int xid, + struct cifs_tcon *tcon, +diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h +index 46feaa0880bdf..9516f57323246 100644 +--- a/fs/smb/client/cifsproto.h ++++ b/fs/smb/client/cifsproto.h +@@ -435,16 +435,19 @@ extern int CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon, + int remap_special_chars); + extern int CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, + const char *name, struct cifs_sb_info *cifs_sb); +-extern int CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon, +- const char *from_name, const char *to_name, +- struct cifs_sb_info *cifs_sb); ++int CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon, ++ struct dentry *source_dentry, ++ const char *from_name, const char *to_name, ++ struct cifs_sb_info *cifs_sb); + extern int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *tcon, + int netfid, const char *target_name, + const struct nls_table *nls_codepage, + int remap_special_chars); +-extern int CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon, +- const char *from_name, const char *to_name, +- struct cifs_sb_info *cifs_sb); ++int CIFSCreateHardLink(const unsigned int xid, ++ struct cifs_tcon *tcon, ++ struct dentry *source_dentry, ++ const char *from_name, const char *to_name, ++ struct cifs_sb_info *cifs_sb); + extern int CIFSUnixCreateHardLink(const unsigned int xid, + struct cifs_tcon *tcon, + const char *fromName, const char *toName, +diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c +index 9ee348e6d1069..e9e33b0b3ac47 100644 +--- a/fs/smb/client/cifssmb.c ++++ b/fs/smb/client/cifssmb.c +@@ -2149,10 +2149,10 @@ CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id) + return rc; + } + +-int +-CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon, +- const char *from_name, const char *to_name, +- struct cifs_sb_info *cifs_sb) ++int CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon, ++ struct dentry *source_dentry, ++ const char *from_name, const char *to_name, ++ struct cifs_sb_info *cifs_sb) + { + int rc = 0; + RENAME_REQ *pSMB = NULL; +@@ -2530,10 +2530,11 @@ createHardLinkRetry: + return rc; + } + +-int +-CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon, +- const char *from_name, const char *to_name, +- struct cifs_sb_info *cifs_sb) ++int CIFSCreateHardLink(const unsigned int xid, ++ struct cifs_tcon *tcon, ++ struct dentry *source_dentry, ++ const char *from_name, const char *to_name, ++ struct cifs_sb_info *cifs_sb) + { + int rc = 0; + NT_RENAME_REQ *pSMB = NULL; +diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c +index 09c5c0f5c96e2..eb54e48937771 100644 +--- a/fs/smb/client/inode.c ++++ b/fs/smb/client/inode.c +@@ -2219,7 +2219,8 @@ cifs_do_rename(const unsigned int xid, struct dentry *from_dentry, + return -ENOSYS; + + /* try path-based rename first */ +- rc = server->ops->rename(xid, tcon, from_path, to_path, cifs_sb); ++ rc = server->ops->rename(xid, tcon, from_dentry, ++ from_path, to_path, cifs_sb); + + /* + * Don't bother with rename by filehandle unless file is busy and +diff --git a/fs/smb/client/link.c b/fs/smb/client/link.c +index a1da50e66fbb6..3ef34218a790d 100644 +--- a/fs/smb/client/link.c ++++ b/fs/smb/client/link.c +@@ -510,8 +510,8 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode, + rc = -ENOSYS; + goto cifs_hl_exit; + } +- rc = server->ops->create_hardlink(xid, tcon, from_name, to_name, +- cifs_sb); ++ rc = server->ops->create_hardlink(xid, tcon, old_file, ++ from_name, to_name, cifs_sb); + if ((rc == -EIO) || (rc == -EINVAL)) + rc = -EOPNOTSUPP; + } +diff --git a/fs/smb/client/sess.c b/fs/smb/client/sess.c +index 2d3b332a79a16..a16e175731eb3 100644 +--- a/fs/smb/client/sess.c ++++ b/fs/smb/client/sess.c +@@ -440,8 +440,14 @@ cifs_chan_update_iface(struct cifs_ses *ses, struct TCP_Server_Info *server) + } + + if (!iface) { +- cifs_dbg(FYI, "unable to get the interface matching: %pIS\n", +- &ss); ++ if (!chan_index) ++ cifs_dbg(FYI, "unable to get the interface matching: %pIS\n", ++ &ss); ++ else { ++ cifs_dbg(FYI, "unable to find another interface to replace: %pIS\n", ++ &old_iface->sockaddr); ++ } ++ + spin_unlock(&ses->iface_lock); + return 0; + } +@@ -459,10 +465,6 @@ cifs_chan_update_iface(struct cifs_ses *ses, struct TCP_Server_Info *server) + iface->weight_fulfilled++; + + kref_put(&old_iface->refcount, release_iface); +- } else if (old_iface) { +- /* if a new candidate is not found, keep things as is */ +- cifs_dbg(FYI, "could not replace iface: %pIS\n", +- &old_iface->sockaddr); + } else if (!chan_index) { + /* special case: update interface for primary channel */ + if (iface) { +diff --git a/fs/smb/client/smb2inode.c b/fs/smb/client/smb2inode.c +index c94940af5d4b8..6cac0b107a2d0 100644 +--- a/fs/smb/client/smb2inode.c ++++ b/fs/smb/client/smb2inode.c +@@ -35,6 +35,18 @@ free_set_inf_compound(struct smb_rqst *rqst) + SMB2_close_free(&rqst[2]); + } + ++static inline __u32 file_create_options(struct dentry *dentry) ++{ ++ struct cifsInodeInfo *ci; ++ ++ if (dentry) { ++ ci = CIFS_I(d_inode(dentry)); ++ if (ci->cifsAttrs & ATTR_REPARSE) ++ return OPEN_REPARSE_POINT; ++ } ++ return 0; ++} ++ + /* + * note: If cfile is passed, the reference to it is dropped here. + * So make sure that you do not reuse cfile after return from this func. +@@ -781,11 +793,11 @@ smb2_unlink(const unsigned int xid, struct cifs_tcon *tcon, const char *name, + ACL_NO_MODE, NULL, SMB2_OP_DELETE, NULL, NULL, NULL, NULL, NULL); + } + +-static int +-smb2_set_path_attr(const unsigned int xid, struct cifs_tcon *tcon, +- const char *from_name, const char *to_name, +- struct cifs_sb_info *cifs_sb, __u32 access, int command, +- struct cifsFileInfo *cfile) ++static int smb2_set_path_attr(const unsigned int xid, struct cifs_tcon *tcon, ++ const char *from_name, const char *to_name, ++ struct cifs_sb_info *cifs_sb, ++ __u32 create_options, __u32 access, ++ int command, struct cifsFileInfo *cfile) + { + __le16 *smb2_to_name = NULL; + int rc; +@@ -796,35 +808,40 @@ smb2_set_path_attr(const unsigned int xid, struct cifs_tcon *tcon, + goto smb2_rename_path; + } + rc = smb2_compound_op(xid, tcon, cifs_sb, from_name, access, +- FILE_OPEN, 0, ACL_NO_MODE, smb2_to_name, ++ FILE_OPEN, create_options, ACL_NO_MODE, smb2_to_name, + command, cfile, NULL, NULL, NULL, NULL); + smb2_rename_path: + kfree(smb2_to_name); + return rc; + } + +-int +-smb2_rename_path(const unsigned int xid, struct cifs_tcon *tcon, +- const char *from_name, const char *to_name, +- struct cifs_sb_info *cifs_sb) ++int smb2_rename_path(const unsigned int xid, ++ struct cifs_tcon *tcon, ++ struct dentry *source_dentry, ++ const char *from_name, const char *to_name, ++ struct cifs_sb_info *cifs_sb) + { + struct cifsFileInfo *cfile; ++ __u32 co = file_create_options(source_dentry); + + drop_cached_dir_by_name(xid, tcon, from_name, cifs_sb); + cifs_get_writable_path(tcon, from_name, FIND_WR_WITH_DELETE, &cfile); + +- return smb2_set_path_attr(xid, tcon, from_name, to_name, +- cifs_sb, DELETE, SMB2_OP_RENAME, cfile); ++ return smb2_set_path_attr(xid, tcon, from_name, to_name, cifs_sb, ++ co, DELETE, SMB2_OP_RENAME, cfile); + } + +-int +-smb2_create_hardlink(const unsigned int xid, struct cifs_tcon *tcon, +- const char *from_name, const char *to_name, +- struct cifs_sb_info *cifs_sb) ++int smb2_create_hardlink(const unsigned int xid, ++ struct cifs_tcon *tcon, ++ struct dentry *source_dentry, ++ const char *from_name, const char *to_name, ++ struct cifs_sb_info *cifs_sb) + { +- return smb2_set_path_attr(xid, tcon, from_name, to_name, cifs_sb, +- FILE_READ_ATTRIBUTES, SMB2_OP_HARDLINK, +- NULL); ++ __u32 co = file_create_options(source_dentry); ++ ++ return smb2_set_path_attr(xid, tcon, from_name, to_name, ++ cifs_sb, co, FILE_READ_ATTRIBUTES, ++ SMB2_OP_HARDLINK, NULL); + } + + int +diff --git a/fs/smb/client/smb2proto.h b/fs/smb/client/smb2proto.h +index 0e371f7e2854b..a8084ce7fcbd2 100644 +--- a/fs/smb/client/smb2proto.h ++++ b/fs/smb/client/smb2proto.h +@@ -80,12 +80,16 @@ extern int smb2_rmdir(const unsigned int xid, struct cifs_tcon *tcon, + const char *name, struct cifs_sb_info *cifs_sb); + extern int smb2_unlink(const unsigned int xid, struct cifs_tcon *tcon, + const char *name, struct cifs_sb_info *cifs_sb); +-extern int smb2_rename_path(const unsigned int xid, struct cifs_tcon *tcon, +- const char *from_name, const char *to_name, +- struct cifs_sb_info *cifs_sb); +-extern int smb2_create_hardlink(const unsigned int xid, struct cifs_tcon *tcon, +- const char *from_name, const char *to_name, +- struct cifs_sb_info *cifs_sb); ++int smb2_rename_path(const unsigned int xid, ++ struct cifs_tcon *tcon, ++ struct dentry *source_dentry, ++ const char *from_name, const char *to_name, ++ struct cifs_sb_info *cifs_sb); ++int smb2_create_hardlink(const unsigned int xid, ++ struct cifs_tcon *tcon, ++ struct dentry *source_dentry, ++ const char *from_name, const char *to_name, ++ struct cifs_sb_info *cifs_sb); + extern int smb3_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, + struct cifs_sb_info *cifs_sb, const unsigned char *path, + char *pbuf, unsigned int *pbytes_written); +diff --git a/fs/tracefs/event_inode.c b/fs/tracefs/event_inode.c +index f0677ea0ec24e..f2d7ad155c00f 100644 +--- a/fs/tracefs/event_inode.c ++++ b/fs/tracefs/event_inode.c +@@ -45,6 +45,7 @@ enum { + EVENTFS_SAVE_MODE = BIT(16), + EVENTFS_SAVE_UID = BIT(17), + EVENTFS_SAVE_GID = BIT(18), ++ EVENTFS_TOPLEVEL = BIT(19), + }; + + #define EVENTFS_MODE_MASK (EVENTFS_SAVE_MODE - 1) +@@ -117,10 +118,17 @@ static int eventfs_set_attr(struct mnt_idmap *idmap, struct dentry *dentry, + * The events directory dentry is never freed, unless its + * part of an instance that is deleted. It's attr is the + * default for its child files and directories. +- * Do not update it. It's not used for its own mode or ownership ++ * Do not update it. It's not used for its own mode or ownership. + */ +- if (!ei->is_events) ++ if (ei->is_events) { ++ /* But it still needs to know if it was modified */ ++ if (iattr->ia_valid & ATTR_UID) ++ ei->attr.mode |= EVENTFS_SAVE_UID; ++ if (iattr->ia_valid & ATTR_GID) ++ ei->attr.mode |= EVENTFS_SAVE_GID; ++ } else { + update_attr(&ei->attr, iattr); ++ } + + } else { + name = dentry->d_name.name; +@@ -138,9 +146,66 @@ static int eventfs_set_attr(struct mnt_idmap *idmap, struct dentry *dentry, + return ret; + } + ++static void update_top_events_attr(struct eventfs_inode *ei, struct dentry *dentry) ++{ ++ struct inode *inode; ++ ++ /* Only update if the "events" was on the top level */ ++ if (!ei || !(ei->attr.mode & EVENTFS_TOPLEVEL)) ++ return; ++ ++ /* Get the tracefs root inode. */ ++ inode = d_inode(dentry->d_sb->s_root); ++ ei->attr.uid = inode->i_uid; ++ ei->attr.gid = inode->i_gid; ++} ++ ++static void set_top_events_ownership(struct inode *inode) ++{ ++ struct tracefs_inode *ti = get_tracefs(inode); ++ struct eventfs_inode *ei = ti->private; ++ struct dentry *dentry; ++ ++ /* The top events directory doesn't get automatically updated */ ++ if (!ei || !ei->is_events || !(ei->attr.mode & EVENTFS_TOPLEVEL)) ++ return; ++ ++ dentry = ei->dentry; ++ ++ update_top_events_attr(ei, dentry); ++ ++ if (!(ei->attr.mode & EVENTFS_SAVE_UID)) ++ inode->i_uid = ei->attr.uid; ++ ++ if (!(ei->attr.mode & EVENTFS_SAVE_GID)) ++ inode->i_gid = ei->attr.gid; ++} ++ ++static int eventfs_get_attr(struct mnt_idmap *idmap, ++ const struct path *path, struct kstat *stat, ++ u32 request_mask, unsigned int flags) ++{ ++ struct dentry *dentry = path->dentry; ++ struct inode *inode = d_backing_inode(dentry); ++ ++ set_top_events_ownership(inode); ++ ++ generic_fillattr(idmap, request_mask, inode, stat); ++ return 0; ++} ++ ++static int eventfs_permission(struct mnt_idmap *idmap, ++ struct inode *inode, int mask) ++{ ++ set_top_events_ownership(inode); ++ return generic_permission(idmap, inode, mask); ++} ++ + static const struct inode_operations eventfs_root_dir_inode_operations = { + .lookup = eventfs_root_lookup, + .setattr = eventfs_set_attr, ++ .getattr = eventfs_get_attr, ++ .permission = eventfs_permission, + }; + + static const struct inode_operations eventfs_file_inode_operations = { +@@ -178,6 +243,8 @@ static struct eventfs_inode *eventfs_find_events(struct dentry *dentry) + } while (!ei->is_events); + mutex_unlock(&eventfs_mutex); + ++ update_top_events_attr(ei, dentry); ++ + return ei; + } + +@@ -206,44 +273,6 @@ static void update_inode_attr(struct dentry *dentry, struct inode *inode, + inode->i_gid = attr->gid; + } + +-static void update_gid(struct eventfs_inode *ei, kgid_t gid, int level) +-{ +- struct eventfs_inode *ei_child; +- +- /* at most we have events/system/event */ +- if (WARN_ON_ONCE(level > 3)) +- return; +- +- ei->attr.gid = gid; +- +- if (ei->entry_attrs) { +- for (int i = 0; i < ei->nr_entries; i++) { +- ei->entry_attrs[i].gid = gid; +- } +- } +- +- /* +- * Only eventfs_inode with dentries are updated, make sure +- * all eventfs_inodes are updated. If one of the children +- * do not have a dentry, this function must traverse it. +- */ +- list_for_each_entry_srcu(ei_child, &ei->children, list, +- srcu_read_lock_held(&eventfs_srcu)) { +- if (!ei_child->dentry) +- update_gid(ei_child, gid, level + 1); +- } +-} +- +-void eventfs_update_gid(struct dentry *dentry, kgid_t gid) +-{ +- struct eventfs_inode *ei = dentry->d_fsdata; +- int idx; +- +- idx = srcu_read_lock(&eventfs_srcu); +- update_gid(ei, gid, 0); +- srcu_read_unlock(&eventfs_srcu, idx); +-} +- + /** + * create_file - create a file in the tracefs filesystem + * @name: the name of the file to create. +@@ -968,6 +997,14 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry + uid = d_inode(dentry->d_parent)->i_uid; + gid = d_inode(dentry->d_parent)->i_gid; + ++ /* ++ * If the events directory is of the top instance, then parent ++ * is NULL. Set the attr.mode to reflect this and its permissions will ++ * default to the tracefs root dentry. ++ */ ++ if (!parent) ++ ei->attr.mode = EVENTFS_TOPLEVEL; ++ + /* This is used as the default ownership of the files and directories */ + ei->attr.uid = uid; + ei->attr.gid = gid; +diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c +index bc86ffdb103bc..e1b172c0e091a 100644 +--- a/fs/tracefs/inode.c ++++ b/fs/tracefs/inode.c +@@ -91,6 +91,7 @@ static int tracefs_syscall_mkdir(struct mnt_idmap *idmap, + struct inode *inode, struct dentry *dentry, + umode_t mode) + { ++ struct tracefs_inode *ti; + char *name; + int ret; + +@@ -98,6 +99,15 @@ static int tracefs_syscall_mkdir(struct mnt_idmap *idmap, + if (!name) + return -ENOMEM; + ++ /* ++ * This is a new directory that does not take the default of ++ * the rootfs. It becomes the default permissions for all the ++ * files and directories underneath it. ++ */ ++ ti = get_tracefs(inode); ++ ti->flags |= TRACEFS_INSTANCE_INODE; ++ ti->private = inode; ++ + /* + * The mkdir call can call the generic functions that create + * the files within the tracefs system. It is up to the individual +@@ -141,10 +151,76 @@ static int tracefs_syscall_rmdir(struct inode *inode, struct dentry *dentry) + return ret; + } + +-static const struct inode_operations tracefs_dir_inode_operations = { ++static void set_tracefs_inode_owner(struct inode *inode) ++{ ++ struct tracefs_inode *ti = get_tracefs(inode); ++ struct inode *root_inode = ti->private; ++ ++ /* ++ * If this inode has never been referenced, then update ++ * the permissions to the superblock. ++ */ ++ if (!(ti->flags & TRACEFS_UID_PERM_SET)) ++ inode->i_uid = root_inode->i_uid; ++ ++ if (!(ti->flags & TRACEFS_GID_PERM_SET)) ++ inode->i_gid = root_inode->i_gid; ++} ++ ++static int tracefs_permission(struct mnt_idmap *idmap, ++ struct inode *inode, int mask) ++{ ++ set_tracefs_inode_owner(inode); ++ return generic_permission(idmap, inode, mask); ++} ++ ++static int tracefs_getattr(struct mnt_idmap *idmap, ++ const struct path *path, struct kstat *stat, ++ u32 request_mask, unsigned int flags) ++{ ++ struct inode *inode = d_backing_inode(path->dentry); ++ ++ set_tracefs_inode_owner(inode); ++ generic_fillattr(idmap, request_mask, inode, stat); ++ return 0; ++} ++ ++static int tracefs_setattr(struct mnt_idmap *idmap, struct dentry *dentry, ++ struct iattr *attr) ++{ ++ unsigned int ia_valid = attr->ia_valid; ++ struct inode *inode = d_inode(dentry); ++ struct tracefs_inode *ti = get_tracefs(inode); ++ ++ if (ia_valid & ATTR_UID) ++ ti->flags |= TRACEFS_UID_PERM_SET; ++ ++ if (ia_valid & ATTR_GID) ++ ti->flags |= TRACEFS_GID_PERM_SET; ++ ++ return simple_setattr(idmap, dentry, attr); ++} ++ ++static const struct inode_operations tracefs_instance_dir_inode_operations = { + .lookup = simple_lookup, + .mkdir = tracefs_syscall_mkdir, + .rmdir = tracefs_syscall_rmdir, ++ .permission = tracefs_permission, ++ .getattr = tracefs_getattr, ++ .setattr = tracefs_setattr, ++}; ++ ++static const struct inode_operations tracefs_dir_inode_operations = { ++ .lookup = simple_lookup, ++ .permission = tracefs_permission, ++ .getattr = tracefs_getattr, ++ .setattr = tracefs_setattr, ++}; ++ ++static const struct inode_operations tracefs_file_inode_operations = { ++ .permission = tracefs_permission, ++ .getattr = tracefs_getattr, ++ .setattr = tracefs_setattr, + }; + + struct inode *tracefs_get_inode(struct super_block *sb) +@@ -183,87 +259,6 @@ struct tracefs_fs_info { + struct tracefs_mount_opts mount_opts; + }; + +-static void change_gid(struct dentry *dentry, kgid_t gid) +-{ +- if (!dentry->d_inode) +- return; +- dentry->d_inode->i_gid = gid; +-} +- +-/* +- * Taken from d_walk, but without he need for handling renames. +- * Nothing can be renamed while walking the list, as tracefs +- * does not support renames. This is only called when mounting +- * or remounting the file system, to set all the files to +- * the given gid. +- */ +-static void set_gid(struct dentry *parent, kgid_t gid) +-{ +- struct dentry *this_parent; +- struct list_head *next; +- +- this_parent = parent; +- spin_lock(&this_parent->d_lock); +- +- change_gid(this_parent, gid); +-repeat: +- next = this_parent->d_subdirs.next; +-resume: +- while (next != &this_parent->d_subdirs) { +- struct tracefs_inode *ti; +- struct list_head *tmp = next; +- struct dentry *dentry = list_entry(tmp, struct dentry, d_child); +- next = tmp->next; +- +- /* Note, getdents() can add a cursor dentry with no inode */ +- if (!dentry->d_inode) +- continue; +- +- spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); +- +- change_gid(dentry, gid); +- +- /* If this is the events directory, update that too */ +- ti = get_tracefs(dentry->d_inode); +- if (ti && (ti->flags & TRACEFS_EVENT_INODE)) +- eventfs_update_gid(dentry, gid); +- +- if (!list_empty(&dentry->d_subdirs)) { +- spin_unlock(&this_parent->d_lock); +- spin_release(&dentry->d_lock.dep_map, _RET_IP_); +- this_parent = dentry; +- spin_acquire(&this_parent->d_lock.dep_map, 0, 1, _RET_IP_); +- goto repeat; +- } +- spin_unlock(&dentry->d_lock); +- } +- /* +- * All done at this level ... ascend and resume the search. +- */ +- rcu_read_lock(); +-ascend: +- if (this_parent != parent) { +- struct dentry *child = this_parent; +- this_parent = child->d_parent; +- +- spin_unlock(&child->d_lock); +- spin_lock(&this_parent->d_lock); +- +- /* go into the first sibling still alive */ +- do { +- next = child->d_child.next; +- if (next == &this_parent->d_subdirs) +- goto ascend; +- child = list_entry(next, struct dentry, d_child); +- } while (unlikely(child->d_flags & DCACHE_DENTRY_KILLED)); +- rcu_read_unlock(); +- goto resume; +- } +- rcu_read_unlock(); +- spin_unlock(&this_parent->d_lock); +- return; +-} +- + static int tracefs_parse_options(char *data, struct tracefs_mount_opts *opts) + { + substring_t args[MAX_OPT_ARGS]; +@@ -336,10 +331,8 @@ static int tracefs_apply_options(struct super_block *sb, bool remount) + if (!remount || opts->opts & BIT(Opt_uid)) + inode->i_uid = opts->uid; + +- if (!remount || opts->opts & BIT(Opt_gid)) { +- /* Set all the group ids to the mount option */ +- set_gid(sb->s_root, opts->gid); +- } ++ if (!remount || opts->opts & BIT(Opt_gid)) ++ inode->i_gid = opts->gid; + + return 0; + } +@@ -573,6 +566,26 @@ struct dentry *eventfs_end_creating(struct dentry *dentry) + return dentry; + } + ++/* Find the inode that this will use for default */ ++static struct inode *instance_inode(struct dentry *parent, struct inode *inode) ++{ ++ struct tracefs_inode *ti; ++ ++ /* If parent is NULL then use root inode */ ++ if (!parent) ++ return d_inode(inode->i_sb->s_root); ++ ++ /* Find the inode that is flagged as an instance or the root inode */ ++ while (!IS_ROOT(parent)) { ++ ti = get_tracefs(d_inode(parent)); ++ if (ti->flags & TRACEFS_INSTANCE_INODE) ++ break; ++ parent = parent->d_parent; ++ } ++ ++ return d_inode(parent); ++} ++ + /** + * tracefs_create_file - create a file in the tracefs filesystem + * @name: a pointer to a string containing the name of the file to create. +@@ -603,6 +616,7 @@ struct dentry *tracefs_create_file(const char *name, umode_t mode, + struct dentry *parent, void *data, + const struct file_operations *fops) + { ++ struct tracefs_inode *ti; + struct dentry *dentry; + struct inode *inode; + +@@ -621,7 +635,11 @@ struct dentry *tracefs_create_file(const char *name, umode_t mode, + if (unlikely(!inode)) + return tracefs_failed_creating(dentry); + ++ ti = get_tracefs(inode); ++ ti->private = instance_inode(parent, inode); ++ + inode->i_mode = mode; ++ inode->i_op = &tracefs_file_inode_operations; + inode->i_fop = fops ? fops : &tracefs_file_operations; + inode->i_private = data; + inode->i_uid = d_inode(dentry->d_parent)->i_uid; +@@ -634,6 +652,7 @@ struct dentry *tracefs_create_file(const char *name, umode_t mode, + static struct dentry *__create_dir(const char *name, struct dentry *parent, + const struct inode_operations *ops) + { ++ struct tracefs_inode *ti; + struct dentry *dentry = tracefs_start_creating(name, parent); + struct inode *inode; + +@@ -651,6 +670,9 @@ static struct dentry *__create_dir(const char *name, struct dentry *parent, + inode->i_uid = d_inode(dentry->d_parent)->i_uid; + inode->i_gid = d_inode(dentry->d_parent)->i_gid; + ++ ti = get_tracefs(inode); ++ ti->private = instance_inode(parent, inode); ++ + /* directory inodes start off with i_nlink == 2 (for "." entry) */ + inc_nlink(inode); + d_instantiate(dentry, inode); +@@ -681,7 +703,7 @@ struct dentry *tracefs_create_dir(const char *name, struct dentry *parent) + if (security_locked_down(LOCKDOWN_TRACEFS)) + return NULL; + +- return __create_dir(name, parent, &simple_dir_inode_operations); ++ return __create_dir(name, parent, &tracefs_dir_inode_operations); + } + + /** +@@ -712,7 +734,7 @@ __init struct dentry *tracefs_create_instance_dir(const char *name, + if (WARN_ON(tracefs_ops.mkdir || tracefs_ops.rmdir)) + return NULL; + +- dentry = __create_dir(name, parent, &tracefs_dir_inode_operations); ++ dentry = __create_dir(name, parent, &tracefs_instance_dir_inode_operations); + if (!dentry) + return NULL; + +diff --git a/fs/tracefs/internal.h b/fs/tracefs/internal.h +index 42bdeb471a072..af3b43fa75cdb 100644 +--- a/fs/tracefs/internal.h ++++ b/fs/tracefs/internal.h +@@ -5,6 +5,9 @@ + enum { + TRACEFS_EVENT_INODE = BIT(1), + TRACEFS_EVENT_TOP_INODE = BIT(2), ++ TRACEFS_GID_PERM_SET = BIT(3), ++ TRACEFS_UID_PERM_SET = BIT(4), ++ TRACEFS_INSTANCE_INODE = BIT(5), + }; + + struct tracefs_inode { +@@ -78,7 +81,6 @@ struct inode *tracefs_get_inode(struct super_block *sb); + struct dentry *eventfs_start_creating(const char *name, struct dentry *parent); + struct dentry *eventfs_failed_creating(struct dentry *dentry); + struct dentry *eventfs_end_creating(struct dentry *dentry); +-void eventfs_update_gid(struct dentry *dentry, kgid_t gid); + void eventfs_set_ei_status_free(struct tracefs_inode *ti, struct dentry *dentry); + + #endif /* _TRACEFS_INTERNAL_H */ +diff --git a/include/asm-generic/numa.h b/include/asm-generic/numa.h +index 1a3ad6d298330..c32e0cf23c909 100644 +--- a/include/asm-generic/numa.h ++++ b/include/asm-generic/numa.h +@@ -35,6 +35,7 @@ int __init numa_add_memblk(int nodeid, u64 start, u64 end); + void __init numa_set_distance(int from, int to, int distance); + void __init numa_free_distance(void); + void __init early_map_cpu_to_node(unsigned int cpu, int nid); ++int __init early_cpu_to_node(int cpu); + void numa_store_cpu_info(unsigned int cpu); + void numa_add_cpu(unsigned int cpu); + void numa_remove_cpu(unsigned int cpu); +@@ -46,6 +47,7 @@ static inline void numa_add_cpu(unsigned int cpu) { } + static inline void numa_remove_cpu(unsigned int cpu) { } + static inline void arch_numa_init(void) { } + static inline void early_map_cpu_to_node(unsigned int cpu, int nid) { } ++static inline int early_cpu_to_node(int cpu) { return 0; } + + #endif /* CONFIG_NUMA */ + +diff --git a/include/asm-generic/unaligned.h b/include/asm-generic/unaligned.h +index 699650f819706..a84c64e5f11ec 100644 +--- a/include/asm-generic/unaligned.h ++++ b/include/asm-generic/unaligned.h +@@ -104,9 +104,9 @@ static inline u32 get_unaligned_le24(const void *p) + + static inline void __put_unaligned_be24(const u32 val, u8 *p) + { +- *p++ = val >> 16; +- *p++ = val >> 8; +- *p++ = val; ++ *p++ = (val >> 16) & 0xff; ++ *p++ = (val >> 8) & 0xff; ++ *p++ = val & 0xff; + } + + static inline void put_unaligned_be24(const u32 val, void *p) +@@ -116,9 +116,9 @@ static inline void put_unaligned_be24(const u32 val, void *p) + + static inline void __put_unaligned_le24(const u32 val, u8 *p) + { +- *p++ = val; +- *p++ = val >> 8; +- *p++ = val >> 16; ++ *p++ = val & 0xff; ++ *p++ = (val >> 8) & 0xff; ++ *p++ = (val >> 16) & 0xff; + } + + static inline void put_unaligned_le24(const u32 val, void *p) +@@ -128,12 +128,12 @@ static inline void put_unaligned_le24(const u32 val, void *p) + + static inline void __put_unaligned_be48(const u64 val, u8 *p) + { +- *p++ = val >> 40; +- *p++ = val >> 32; +- *p++ = val >> 24; +- *p++ = val >> 16; +- *p++ = val >> 8; +- *p++ = val; ++ *p++ = (val >> 40) & 0xff; ++ *p++ = (val >> 32) & 0xff; ++ *p++ = (val >> 24) & 0xff; ++ *p++ = (val >> 16) & 0xff; ++ *p++ = (val >> 8) & 0xff; ++ *p++ = val & 0xff; + } + + static inline void put_unaligned_be48(const u64 val, void *p) +diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h +index 81c298488b0c8..6b5eec10c3db3 100644 +--- a/include/drm/drm_color_mgmt.h ++++ b/include/drm/drm_color_mgmt.h +@@ -24,6 +24,7 @@ + #define __DRM_COLOR_MGMT_H__ + + #include <linux/ctype.h> ++#include <linux/math64.h> + #include <drm/drm_property.h> + + struct drm_crtc; +diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h +index c9df0407980c9..c0aec0d4d664e 100644 +--- a/include/drm/drm_mipi_dsi.h ++++ b/include/drm/drm_mipi_dsi.h +@@ -168,6 +168,7 @@ struct mipi_dsi_device_info { + * struct mipi_dsi_device - DSI peripheral device + * @host: DSI host for this peripheral + * @dev: driver model device node for this peripheral ++ * @attached: the DSI device has been successfully attached + * @name: DSI peripheral chip type + * @channel: virtual channel assigned to the peripheral + * @format: pixel format for video mode +@@ -184,6 +185,7 @@ struct mipi_dsi_device_info { + struct mipi_dsi_device { + struct mipi_dsi_host *host; + struct device dev; ++ bool attached; + + char name[DSI_DEV_NAME_SIZE]; + unsigned int channel; +diff --git a/include/linux/avf/virtchnl.h b/include/linux/avf/virtchnl.h +index 6b3acf15be5c2..99ae7960a8d13 100644 +--- a/include/linux/avf/virtchnl.h ++++ b/include/linux/avf/virtchnl.h +@@ -5,6 +5,7 @@ + #define _VIRTCHNL_H_ + + #include <linux/bitops.h> ++#include <linux/bits.h> + #include <linux/overflow.h> + #include <uapi/linux/if_ether.h> + +diff --git a/include/linux/bpf.h b/include/linux/bpf.h +index 7a7859a5cce42..cfc6d2f98058d 100644 +--- a/include/linux/bpf.h ++++ b/include/linux/bpf.h +@@ -1447,7 +1447,7 @@ struct bpf_prog_aux { + int cgroup_atype; /* enum cgroup_bpf_attach_type */ + struct bpf_map *cgroup_storage[MAX_BPF_CGROUP_STORAGE_TYPE]; + char name[BPF_OBJ_NAME_LEN]; +- unsigned int (*bpf_exception_cb)(u64 cookie, u64 sp, u64 bp); ++ u64 (*bpf_exception_cb)(u64 cookie, u64 sp, u64 bp, u64, u64); + #ifdef CONFIG_SECURITY + void *security; + #endif +diff --git a/include/linux/irq_work.h b/include/linux/irq_work.h +index 8cd11a2232605..136f2980cba30 100644 +--- a/include/linux/irq_work.h ++++ b/include/linux/irq_work.h +@@ -66,6 +66,9 @@ void irq_work_sync(struct irq_work *work); + void irq_work_run(void); + bool irq_work_needs_cpu(void); + void irq_work_single(void *arg); ++ ++void arch_irq_work_raise(void); ++ + #else + static inline bool irq_work_needs_cpu(void) { return false; } + static inline void irq_work_run(void) { } +diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h +index 957ce38768b2a..950df415d7de9 100644 +--- a/include/linux/mm_types.h ++++ b/include/linux/mm_types.h +@@ -600,6 +600,9 @@ struct vma_numab_state { + */ + unsigned long pids_active[2]; + ++ /* MM scan sequence ID when scan first started after VMA creation */ ++ int start_scan_seq; ++ + /* + * MM scan sequence ID when the VMA was last completely scanned. + * A VMA is not eligible for scanning if prev_scan_seq == numa_scan_seq +diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h +index a7c32324c2639..2c34e9325c9b9 100644 +--- a/include/linux/mmzone.h ++++ b/include/linux/mmzone.h +@@ -2025,9 +2025,9 @@ static inline int pfn_valid(unsigned long pfn) + if (pfn_to_section_nr(pfn) >= NR_MEM_SECTIONS) + return 0; + ms = __pfn_to_section(pfn); +- rcu_read_lock(); ++ rcu_read_lock_sched(); + if (!valid_section(ms)) { +- rcu_read_unlock(); ++ rcu_read_unlock_sched(); + return 0; + } + /* +@@ -2035,7 +2035,7 @@ static inline int pfn_valid(unsigned long pfn) + * the entire section-sized span. + */ + ret = early_section(ms) || pfn_section_valid(ms, pfn); +- rcu_read_unlock(); ++ rcu_read_unlock_sched(); + + return ret; + } +diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h +index 275799b5f535c..97cc0baad0f4b 100644 +--- a/include/linux/pci_ids.h ++++ b/include/linux/pci_ids.h +@@ -3065,6 +3065,7 @@ + #define PCI_DEVICE_ID_INTEL_82443GX_0 0x71a0 + #define PCI_DEVICE_ID_INTEL_82443GX_2 0x71a2 + #define PCI_DEVICE_ID_INTEL_82372FB_1 0x7601 ++#define PCI_DEVICE_ID_INTEL_HDA_ARL 0x7728 + #define PCI_DEVICE_ID_INTEL_HDA_RPL_S 0x7a50 + #define PCI_DEVICE_ID_INTEL_HDA_ADL_S 0x7ad0 + #define PCI_DEVICE_ID_INTEL_HDA_MTL 0x7e28 +diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h +index ccd97bcef2694..18a102174c4f2 100644 +--- a/include/linux/pm_opp.h ++++ b/include/linux/pm_opp.h +@@ -157,7 +157,7 @@ struct dev_pm_opp *dev_pm_opp_find_level_ceil(struct device *dev, + unsigned int *level); + + struct dev_pm_opp *dev_pm_opp_find_level_floor(struct device *dev, +- unsigned long *level); ++ unsigned int *level); + + struct dev_pm_opp *dev_pm_opp_find_bw_ceil(struct device *dev, + unsigned int *bw, int index); +@@ -324,7 +324,7 @@ static inline struct dev_pm_opp *dev_pm_opp_find_level_ceil(struct device *dev, + } + + static inline struct dev_pm_opp *dev_pm_opp_find_level_floor(struct device *dev, +- unsigned long *level) ++ unsigned int *level) + { + return ERR_PTR(-EOPNOTSUPP); + } +diff --git a/include/linux/thermal.h b/include/linux/thermal.h +index cee814d5d1acc..1da1739d75d98 100644 +--- a/include/linux/thermal.h ++++ b/include/linux/thermal.h +@@ -149,6 +149,7 @@ struct thermal_cooling_device { + * @node: node in thermal_tz_list (in thermal_core.c) + * @poll_queue: delayed work for polling + * @notify_event: Last notification event ++ * @suspended: thermal zone suspend indicator + */ + struct thermal_zone_device { + int id; +@@ -181,6 +182,7 @@ struct thermal_zone_device { + struct list_head node; + struct delayed_work poll_queue; + enum thermal_notify_event notify_event; ++ bool suspended; + }; + + /** +diff --git a/include/net/af_unix.h b/include/net/af_unix.h +index 49c4640027d8a..afd40dce40f3d 100644 +--- a/include/net/af_unix.h ++++ b/include/net/af_unix.h +@@ -46,12 +46,6 @@ struct scm_stat { + + #define UNIXCB(skb) (*(struct unix_skb_parms *)&((skb)->cb)) + +-#define unix_state_lock(s) spin_lock(&unix_sk(s)->lock) +-#define unix_state_unlock(s) spin_unlock(&unix_sk(s)->lock) +-#define unix_state_lock_nested(s) \ +- spin_lock_nested(&unix_sk(s)->lock, \ +- SINGLE_DEPTH_NESTING) +- + /* The AF_UNIX socket */ + struct unix_sock { + /* WARNING: sk has to be the first member */ +@@ -77,6 +71,20 @@ struct unix_sock { + #define unix_sk(ptr) container_of_const(ptr, struct unix_sock, sk) + #define unix_peer(sk) (unix_sk(sk)->peer) + ++#define unix_state_lock(s) spin_lock(&unix_sk(s)->lock) ++#define unix_state_unlock(s) spin_unlock(&unix_sk(s)->lock) ++enum unix_socket_lock_class { ++ U_LOCK_NORMAL, ++ U_LOCK_SECOND, /* for double locking, see unix_state_double_lock(). */ ++ U_LOCK_DIAG, /* used while dumping icons, see sk_diag_dump_icons(). */ ++}; ++ ++static inline void unix_state_lock_nested(struct sock *sk, ++ enum unix_socket_lock_class subclass) ++{ ++ spin_lock_nested(&unix_sk(sk)->lock, subclass); ++} ++ + #define peer_wait peer_wq.wait + + long unix_inq_len(struct sock *sk); +diff --git a/include/net/ip.h b/include/net/ip.h +index 1fc4c8d69e333..6390dd08da8cd 100644 +--- a/include/net/ip.h ++++ b/include/net/ip.h +@@ -761,7 +761,7 @@ int ip_options_rcv_srr(struct sk_buff *skb, struct net_device *dev); + * Functions provided by ip_sockglue.c + */ + +-void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb); ++void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb, bool drop_dst); + void ip_cmsg_recv_offset(struct msghdr *msg, struct sock *sk, + struct sk_buff *skb, int tlen, int offset); + int ip_cmsg_send(struct sock *sk, struct msghdr *msg, +diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h +index b157c5cafd14c..4e8ecabc5f25c 100644 +--- a/include/net/netfilter/nf_tables.h ++++ b/include/net/netfilter/nf_tables.h +@@ -1322,6 +1322,7 @@ void nft_obj_notify(struct net *net, const struct nft_table *table, + * @type: stateful object numeric type + * @owner: module owner + * @maxattr: maximum netlink attribute ++ * @family: address family for AF-specific object types + * @policy: netlink attribute policy + */ + struct nft_object_type { +@@ -1331,6 +1332,7 @@ struct nft_object_type { + struct list_head list; + u32 type; + unsigned int maxattr; ++ u8 family; + struct module *owner; + const struct nla_policy *policy; + }; +diff --git a/kernel/audit.c b/kernel/audit.c +index 16205dd29843b..9c8e5f732c4c7 100644 +--- a/kernel/audit.c ++++ b/kernel/audit.c +@@ -487,15 +487,19 @@ static void auditd_conn_free(struct rcu_head *rcu) + * @pid: auditd PID + * @portid: auditd netlink portid + * @net: auditd network namespace pointer ++ * @skb: the netlink command from the audit daemon ++ * @ack: netlink ack flag, cleared if ack'd here + * + * Description: + * This function will obtain and drop network namespace references as + * necessary. Returns zero on success, negative values on failure. + */ +-static int auditd_set(struct pid *pid, u32 portid, struct net *net) ++static int auditd_set(struct pid *pid, u32 portid, struct net *net, ++ struct sk_buff *skb, bool *ack) + { + unsigned long flags; + struct auditd_connection *ac_old, *ac_new; ++ struct nlmsghdr *nlh; + + if (!pid || !net) + return -EINVAL; +@@ -507,6 +511,13 @@ static int auditd_set(struct pid *pid, u32 portid, struct net *net) + ac_new->portid = portid; + ac_new->net = get_net(net); + ++ /* send the ack now to avoid a race with the queue backlog */ ++ if (*ack) { ++ nlh = nlmsg_hdr(skb); ++ netlink_ack(skb, nlh, 0, NULL); ++ *ack = false; ++ } ++ + spin_lock_irqsave(&auditd_conn_lock, flags); + ac_old = rcu_dereference_protected(auditd_conn, + lockdep_is_held(&auditd_conn_lock)); +@@ -1200,7 +1211,8 @@ static int audit_replace(struct pid *pid) + return auditd_send_unicast_skb(skb); + } + +-static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) ++static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh, ++ bool *ack) + { + u32 seq; + void *data; +@@ -1293,7 +1305,8 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) + /* register a new auditd connection */ + err = auditd_set(req_pid, + NETLINK_CB(skb).portid, +- sock_net(NETLINK_CB(skb).sk)); ++ sock_net(NETLINK_CB(skb).sk), ++ skb, ack); + if (audit_enabled != AUDIT_OFF) + audit_log_config_change("audit_pid", + new_pid, +@@ -1538,9 +1551,10 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) + * Parse the provided skb and deal with any messages that may be present, + * malformed skbs are discarded. + */ +-static void audit_receive(struct sk_buff *skb) ++static void audit_receive(struct sk_buff *skb) + { + struct nlmsghdr *nlh; ++ bool ack; + /* + * len MUST be signed for nlmsg_next to be able to dec it below 0 + * if the nlmsg_len was not aligned +@@ -1553,9 +1567,12 @@ static void audit_receive(struct sk_buff *skb) + + audit_ctl_lock(); + while (nlmsg_ok(nlh, len)) { +- err = audit_receive_msg(skb, nlh); +- /* if err or if this message says it wants a response */ +- if (err || (nlh->nlmsg_flags & NLM_F_ACK)) ++ ack = nlh->nlmsg_flags & NLM_F_ACK; ++ err = audit_receive_msg(skb, nlh, &ack); ++ ++ /* send an ack if the user asked for one and audit_receive_msg ++ * didn't already do it, or if there was an error. */ ++ if (ack || err) + netlink_ack(skb, nlh, err, NULL); + + nlh = nlmsg_next(nlh, &len); +diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c +index 9bfad7e969131..c9843dde69081 100644 +--- a/kernel/bpf/arraymap.c ++++ b/kernel/bpf/arraymap.c +@@ -871,7 +871,7 @@ int bpf_fd_array_map_update_elem(struct bpf_map *map, struct file *map_file, + return 0; + } + +-static long fd_array_map_delete_elem(struct bpf_map *map, void *key) ++static long __fd_array_map_delete_elem(struct bpf_map *map, void *key, bool need_defer) + { + struct bpf_array *array = container_of(map, struct bpf_array, map); + void *old_ptr; +@@ -890,13 +890,18 @@ static long fd_array_map_delete_elem(struct bpf_map *map, void *key) + } + + if (old_ptr) { +- map->ops->map_fd_put_ptr(map, old_ptr, true); ++ map->ops->map_fd_put_ptr(map, old_ptr, need_defer); + return 0; + } else { + return -ENOENT; + } + } + ++static long fd_array_map_delete_elem(struct bpf_map *map, void *key) ++{ ++ return __fd_array_map_delete_elem(map, key, true); ++} ++ + static void *prog_fd_array_get_ptr(struct bpf_map *map, + struct file *map_file, int fd) + { +@@ -925,13 +930,13 @@ static u32 prog_fd_array_sys_lookup_elem(void *ptr) + } + + /* decrement refcnt of all bpf_progs that are stored in this map */ +-static void bpf_fd_array_map_clear(struct bpf_map *map) ++static void bpf_fd_array_map_clear(struct bpf_map *map, bool need_defer) + { + struct bpf_array *array = container_of(map, struct bpf_array, map); + int i; + + for (i = 0; i < array->map.max_entries; i++) +- fd_array_map_delete_elem(map, &i); ++ __fd_array_map_delete_elem(map, &i, need_defer); + } + + static void prog_array_map_seq_show_elem(struct bpf_map *map, void *key, +@@ -1072,7 +1077,7 @@ static void prog_array_map_clear_deferred(struct work_struct *work) + { + struct bpf_map *map = container_of(work, struct bpf_array_aux, + work)->map; +- bpf_fd_array_map_clear(map); ++ bpf_fd_array_map_clear(map, true); + bpf_map_put(map); + } + +@@ -1222,7 +1227,7 @@ static void perf_event_fd_array_release(struct bpf_map *map, + for (i = 0; i < array->map.max_entries; i++) { + ee = READ_ONCE(array->ptrs[i]); + if (ee && ee->map_file == map_file) +- fd_array_map_delete_elem(map, &i); ++ __fd_array_map_delete_elem(map, &i, true); + } + rcu_read_unlock(); + } +@@ -1230,7 +1235,7 @@ static void perf_event_fd_array_release(struct bpf_map *map, + static void perf_event_fd_array_map_free(struct bpf_map *map) + { + if (map->map_flags & BPF_F_PRESERVE_ELEMS) +- bpf_fd_array_map_clear(map); ++ bpf_fd_array_map_clear(map, false); + fd_array_map_free(map); + } + +@@ -1266,7 +1271,7 @@ static void cgroup_fd_array_put_ptr(struct bpf_map *map, void *ptr, bool need_de + + static void cgroup_fd_array_free(struct bpf_map *map) + { +- bpf_fd_array_map_clear(map); ++ bpf_fd_array_map_clear(map, false); + fd_array_map_free(map); + } + +@@ -1311,7 +1316,7 @@ static void array_of_map_free(struct bpf_map *map) + * is protected by fdget/fdput. + */ + bpf_map_meta_free(map->inner_map_meta); +- bpf_fd_array_map_clear(map); ++ bpf_fd_array_map_clear(map, false); + fd_array_map_free(map); + } + +diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c +index 6950f04616349..b3053af6427d2 100644 +--- a/kernel/bpf/helpers.c ++++ b/kernel/bpf/helpers.c +@@ -32,12 +32,13 @@ + * + * Different map implementations will rely on rcu in map methods + * lookup/update/delete, therefore eBPF programs must run under rcu lock +- * if program is allowed to access maps, so check rcu_read_lock_held in +- * all three functions. ++ * if program is allowed to access maps, so check rcu_read_lock_held() or ++ * rcu_read_lock_trace_held() in all three functions. + */ + BPF_CALL_2(bpf_map_lookup_elem, struct bpf_map *, map, void *, key) + { +- WARN_ON_ONCE(!rcu_read_lock_held() && !rcu_read_lock_bh_held()); ++ WARN_ON_ONCE(!rcu_read_lock_held() && !rcu_read_lock_trace_held() && ++ !rcu_read_lock_bh_held()); + return (unsigned long) map->ops->map_lookup_elem(map, key); + } + +@@ -53,7 +54,8 @@ const struct bpf_func_proto bpf_map_lookup_elem_proto = { + BPF_CALL_4(bpf_map_update_elem, struct bpf_map *, map, void *, key, + void *, value, u64, flags) + { +- WARN_ON_ONCE(!rcu_read_lock_held() && !rcu_read_lock_bh_held()); ++ WARN_ON_ONCE(!rcu_read_lock_held() && !rcu_read_lock_trace_held() && ++ !rcu_read_lock_bh_held()); + return map->ops->map_update_elem(map, key, value, flags); + } + +@@ -70,7 +72,8 @@ const struct bpf_func_proto bpf_map_update_elem_proto = { + + BPF_CALL_2(bpf_map_delete_elem, struct bpf_map *, map, void *, key) + { +- WARN_ON_ONCE(!rcu_read_lock_held() && !rcu_read_lock_bh_held()); ++ WARN_ON_ONCE(!rcu_read_lock_held() && !rcu_read_lock_trace_held() && ++ !rcu_read_lock_bh_held()); + return map->ops->map_delete_elem(map, key); + } + +@@ -2506,7 +2509,7 @@ __bpf_kfunc void bpf_throw(u64 cookie) + * which skips compiler generated instrumentation to do the same. + */ + kasan_unpoison_task_stack_below((void *)(long)ctx.sp); +- ctx.aux->bpf_exception_cb(cookie, ctx.sp, ctx.bp); ++ ctx.aux->bpf_exception_cb(cookie, ctx.sp, ctx.bp, 0, 0); + WARN(1, "A call to BPF exception callback should never return\n"); + } + +diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c +index 58e34ff811971..349d735b4e1d6 100644 +--- a/kernel/bpf/syscall.c ++++ b/kernel/bpf/syscall.c +@@ -1702,6 +1702,9 @@ int generic_map_delete_batch(struct bpf_map *map, + if (!max_count) + return 0; + ++ if (put_user(0, &uattr->batch.count)) ++ return -EFAULT; ++ + key = kvmalloc(map->key_size, GFP_USER | __GFP_NOWARN); + if (!key) + return -ENOMEM; +@@ -1759,6 +1762,9 @@ int generic_map_update_batch(struct bpf_map *map, struct file *map_file, + if (!max_count) + return 0; + ++ if (put_user(0, &uattr->batch.count)) ++ return -EFAULT; ++ + key = kvmalloc(map->key_size, GFP_USER | __GFP_NOWARN); + if (!key) + return -ENOMEM; +diff --git a/kernel/events/core.c b/kernel/events/core.c +index 9efd0d7775e7c..7c03305797184 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -11425,9 +11425,30 @@ static DEVICE_ATTR_RW(perf_event_mux_interval_ms); + static struct attribute *pmu_dev_attrs[] = { + &dev_attr_type.attr, + &dev_attr_perf_event_mux_interval_ms.attr, ++ &dev_attr_nr_addr_filters.attr, ++ NULL, ++}; ++ ++static umode_t pmu_dev_is_visible(struct kobject *kobj, struct attribute *a, int n) ++{ ++ struct device *dev = kobj_to_dev(kobj); ++ struct pmu *pmu = dev_get_drvdata(dev); ++ ++ if (n == 2 && !pmu->nr_addr_filters) ++ return 0; ++ ++ return a->mode; ++} ++ ++static struct attribute_group pmu_dev_attr_group = { ++ .is_visible = pmu_dev_is_visible, ++ .attrs = pmu_dev_attrs, ++}; ++ ++static const struct attribute_group *pmu_dev_groups[] = { ++ &pmu_dev_attr_group, + NULL, + }; +-ATTRIBUTE_GROUPS(pmu_dev); + + static int pmu_bus_running; + static struct bus_type pmu_bus = { +@@ -11464,18 +11485,11 @@ static int pmu_dev_alloc(struct pmu *pmu) + if (ret) + goto free_dev; + +- /* For PMUs with address filters, throw in an extra attribute: */ +- if (pmu->nr_addr_filters) +- ret = device_create_file(pmu->dev, &dev_attr_nr_addr_filters); +- +- if (ret) +- goto del_dev; +- +- if (pmu->attr_update) ++ if (pmu->attr_update) { + ret = sysfs_update_groups(&pmu->dev->kobj, pmu->attr_update); +- +- if (ret) +- goto del_dev; ++ if (ret) ++ goto del_dev; ++ } + + out: + return ret; +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index 4182fb118ce95..7ac9f4b1d955c 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -3164,7 +3164,7 @@ static bool vma_is_accessed(struct mm_struct *mm, struct vm_area_struct *vma) + * This is also done to avoid any side effect of task scanning + * amplifying the unfairness of disjoint set of VMAs' access. + */ +- if (READ_ONCE(current->mm->numa_scan_seq) < 2) ++ if ((READ_ONCE(current->mm->numa_scan_seq) - vma->numab_state->start_scan_seq) < 2) + return true; + + pids = vma->numab_state->pids_active[0] | vma->numab_state->pids_active[1]; +@@ -3307,6 +3307,8 @@ retry_pids: + if (!vma->numab_state) + continue; + ++ vma->numab_state->start_scan_seq = mm->numa_scan_seq; ++ + vma->numab_state->next_scan = now + + msecs_to_jiffies(sysctl_numa_balancing_scan_delay); + +@@ -4096,6 +4098,10 @@ static inline void update_tg_load_avg(struct cfs_rq *cfs_rq) + if (cfs_rq->tg == &root_task_group) + return; + ++ /* rq has been offline and doesn't contribute to the share anymore: */ ++ if (!cpu_active(cpu_of(rq_of(cfs_rq)))) ++ return; ++ + /* + * For migration heavy workloads, access to tg->load_avg can be + * unbound. Limit the update rate to at most once per ms. +@@ -4112,6 +4118,49 @@ static inline void update_tg_load_avg(struct cfs_rq *cfs_rq) + } + } + ++static inline void clear_tg_load_avg(struct cfs_rq *cfs_rq) ++{ ++ long delta; ++ u64 now; ++ ++ /* ++ * No need to update load_avg for root_task_group, as it is not used. ++ */ ++ if (cfs_rq->tg == &root_task_group) ++ return; ++ ++ now = sched_clock_cpu(cpu_of(rq_of(cfs_rq))); ++ delta = 0 - cfs_rq->tg_load_avg_contrib; ++ atomic_long_add(delta, &cfs_rq->tg->load_avg); ++ cfs_rq->tg_load_avg_contrib = 0; ++ cfs_rq->last_update_tg_load_avg = now; ++} ++ ++/* CPU offline callback: */ ++static void __maybe_unused clear_tg_offline_cfs_rqs(struct rq *rq) ++{ ++ struct task_group *tg; ++ ++ lockdep_assert_rq_held(rq); ++ ++ /* ++ * The rq clock has already been updated in ++ * set_rq_offline(), so we should skip updating ++ * the rq clock again in unthrottle_cfs_rq(). ++ */ ++ rq_clock_start_loop_update(rq); ++ ++ rcu_read_lock(); ++ list_for_each_entry_rcu(tg, &task_groups, list) { ++ struct cfs_rq *cfs_rq = tg->cfs_rq[cpu_of(rq)]; ++ ++ clear_tg_load_avg(cfs_rq); ++ } ++ rcu_read_unlock(); ++ ++ rq_clock_stop_loop_update(rq); ++} ++ + /* + * Called within set_task_rq() right before setting a task's CPU. The + * caller only guarantees p->pi_lock is held; no other assumptions, +@@ -4408,6 +4457,8 @@ static inline bool skip_blocked_update(struct sched_entity *se) + + static inline void update_tg_load_avg(struct cfs_rq *cfs_rq) {} + ++static inline void clear_tg_offline_cfs_rqs(struct rq *rq) {} ++ + static inline int propagate_entity_load_avg(struct sched_entity *se) + { + return 0; +@@ -12413,6 +12464,9 @@ static void rq_offline_fair(struct rq *rq) + + /* Ensure any throttled groups are reachable by pick_next_task */ + unthrottle_offline_cfs_rqs(rq); ++ ++ /* Ensure that we remove rq contribution to group share: */ ++ clear_tg_offline_cfs_rqs(rq); + } + + #endif /* CONFIG_SMP */ +diff --git a/lib/debugobjects.c b/lib/debugobjects.c +index 2a8e9d63fbe38..fb12a9bacd2fa 100644 +--- a/lib/debugobjects.c ++++ b/lib/debugobjects.c +@@ -620,9 +620,8 @@ static void debug_objects_fill_pool(void) + static void + __debug_object_init(void *addr, const struct debug_obj_descr *descr, int onstack) + { +- enum debug_obj_state state; ++ struct debug_obj *obj, o; + struct debug_bucket *db; +- struct debug_obj *obj; + unsigned long flags; + + debug_objects_fill_pool(); +@@ -643,24 +642,18 @@ __debug_object_init(void *addr, const struct debug_obj_descr *descr, int onstack + case ODEBUG_STATE_INIT: + case ODEBUG_STATE_INACTIVE: + obj->state = ODEBUG_STATE_INIT; +- break; +- +- case ODEBUG_STATE_ACTIVE: +- state = obj->state; +- raw_spin_unlock_irqrestore(&db->lock, flags); +- debug_print_object(obj, "init"); +- debug_object_fixup(descr->fixup_init, addr, state); +- return; +- +- case ODEBUG_STATE_DESTROYED: + raw_spin_unlock_irqrestore(&db->lock, flags); +- debug_print_object(obj, "init"); + return; + default: + break; + } + ++ o = *obj; + raw_spin_unlock_irqrestore(&db->lock, flags); ++ debug_print_object(&o, "init"); ++ ++ if (o.state == ODEBUG_STATE_ACTIVE) ++ debug_object_fixup(descr->fixup_init, addr, o.state); + } + + /** +@@ -701,11 +694,9 @@ EXPORT_SYMBOL_GPL(debug_object_init_on_stack); + int debug_object_activate(void *addr, const struct debug_obj_descr *descr) + { + struct debug_obj o = { .object = addr, .state = ODEBUG_STATE_NOTAVAILABLE, .descr = descr }; +- enum debug_obj_state state; + struct debug_bucket *db; + struct debug_obj *obj; + unsigned long flags; +- int ret; + + if (!debug_objects_enabled) + return 0; +@@ -717,49 +708,38 @@ int debug_object_activate(void *addr, const struct debug_obj_descr *descr) + raw_spin_lock_irqsave(&db->lock, flags); + + obj = lookup_object_or_alloc(addr, db, descr, false, true); +- if (likely(!IS_ERR_OR_NULL(obj))) { +- bool print_object = false; +- ++ if (unlikely(!obj)) { ++ raw_spin_unlock_irqrestore(&db->lock, flags); ++ debug_objects_oom(); ++ return 0; ++ } else if (likely(!IS_ERR(obj))) { + switch (obj->state) { +- case ODEBUG_STATE_INIT: +- case ODEBUG_STATE_INACTIVE: +- obj->state = ODEBUG_STATE_ACTIVE; +- ret = 0; +- break; +- + case ODEBUG_STATE_ACTIVE: +- state = obj->state; +- raw_spin_unlock_irqrestore(&db->lock, flags); +- debug_print_object(obj, "activate"); +- ret = debug_object_fixup(descr->fixup_activate, addr, state); +- return ret ? 0 : -EINVAL; +- + case ODEBUG_STATE_DESTROYED: +- print_object = true; +- ret = -EINVAL; ++ o = *obj; + break; ++ case ODEBUG_STATE_INIT: ++ case ODEBUG_STATE_INACTIVE: ++ obj->state = ODEBUG_STATE_ACTIVE; ++ fallthrough; + default: +- ret = 0; +- break; ++ raw_spin_unlock_irqrestore(&db->lock, flags); ++ return 0; + } +- raw_spin_unlock_irqrestore(&db->lock, flags); +- if (print_object) +- debug_print_object(obj, "activate"); +- return ret; + } + + raw_spin_unlock_irqrestore(&db->lock, flags); ++ debug_print_object(&o, "activate"); + +- /* If NULL the allocation has hit OOM */ +- if (!obj) { +- debug_objects_oom(); +- return 0; ++ switch (o.state) { ++ case ODEBUG_STATE_ACTIVE: ++ case ODEBUG_STATE_NOTAVAILABLE: ++ if (debug_object_fixup(descr->fixup_activate, addr, o.state)) ++ return 0; ++ fallthrough; ++ default: ++ return -EINVAL; + } +- +- /* Object is neither static nor tracked. It's not initialized */ +- debug_print_object(&o, "activate"); +- ret = debug_object_fixup(descr->fixup_activate, addr, ODEBUG_STATE_NOTAVAILABLE); +- return ret ? 0 : -EINVAL; + } + EXPORT_SYMBOL_GPL(debug_object_activate); + +@@ -770,10 +750,10 @@ EXPORT_SYMBOL_GPL(debug_object_activate); + */ + void debug_object_deactivate(void *addr, const struct debug_obj_descr *descr) + { ++ struct debug_obj o = { .object = addr, .state = ODEBUG_STATE_NOTAVAILABLE, .descr = descr }; + struct debug_bucket *db; + struct debug_obj *obj; + unsigned long flags; +- bool print_object = false; + + if (!debug_objects_enabled) + return; +@@ -785,33 +765,24 @@ void debug_object_deactivate(void *addr, const struct debug_obj_descr *descr) + obj = lookup_object(addr, db); + if (obj) { + switch (obj->state) { ++ case ODEBUG_STATE_DESTROYED: ++ break; + case ODEBUG_STATE_INIT: + case ODEBUG_STATE_INACTIVE: + case ODEBUG_STATE_ACTIVE: +- if (!obj->astate) +- obj->state = ODEBUG_STATE_INACTIVE; +- else +- print_object = true; +- break; +- +- case ODEBUG_STATE_DESTROYED: +- print_object = true; +- break; ++ if (obj->astate) ++ break; ++ obj->state = ODEBUG_STATE_INACTIVE; ++ fallthrough; + default: +- break; ++ raw_spin_unlock_irqrestore(&db->lock, flags); ++ return; + } ++ o = *obj; + } + + raw_spin_unlock_irqrestore(&db->lock, flags); +- if (!obj) { +- struct debug_obj o = { .object = addr, +- .state = ODEBUG_STATE_NOTAVAILABLE, +- .descr = descr }; +- +- debug_print_object(&o, "deactivate"); +- } else if (print_object) { +- debug_print_object(obj, "deactivate"); +- } ++ debug_print_object(&o, "deactivate"); + } + EXPORT_SYMBOL_GPL(debug_object_deactivate); + +@@ -822,11 +793,9 @@ EXPORT_SYMBOL_GPL(debug_object_deactivate); + */ + void debug_object_destroy(void *addr, const struct debug_obj_descr *descr) + { +- enum debug_obj_state state; ++ struct debug_obj *obj, o; + struct debug_bucket *db; +- struct debug_obj *obj; + unsigned long flags; +- bool print_object = false; + + if (!debug_objects_enabled) + return; +@@ -836,32 +805,31 @@ void debug_object_destroy(void *addr, const struct debug_obj_descr *descr) + raw_spin_lock_irqsave(&db->lock, flags); + + obj = lookup_object(addr, db); +- if (!obj) +- goto out_unlock; ++ if (!obj) { ++ raw_spin_unlock_irqrestore(&db->lock, flags); ++ return; ++ } + + switch (obj->state) { ++ case ODEBUG_STATE_ACTIVE: ++ case ODEBUG_STATE_DESTROYED: ++ break; + case ODEBUG_STATE_NONE: + case ODEBUG_STATE_INIT: + case ODEBUG_STATE_INACTIVE: + obj->state = ODEBUG_STATE_DESTROYED; +- break; +- case ODEBUG_STATE_ACTIVE: +- state = obj->state; ++ fallthrough; ++ default: + raw_spin_unlock_irqrestore(&db->lock, flags); +- debug_print_object(obj, "destroy"); +- debug_object_fixup(descr->fixup_destroy, addr, state); + return; +- +- case ODEBUG_STATE_DESTROYED: +- print_object = true; +- break; +- default: +- break; + } +-out_unlock: ++ ++ o = *obj; + raw_spin_unlock_irqrestore(&db->lock, flags); +- if (print_object) +- debug_print_object(obj, "destroy"); ++ debug_print_object(&o, "destroy"); ++ ++ if (o.state == ODEBUG_STATE_ACTIVE) ++ debug_object_fixup(descr->fixup_destroy, addr, o.state); + } + EXPORT_SYMBOL_GPL(debug_object_destroy); + +@@ -872,9 +840,8 @@ EXPORT_SYMBOL_GPL(debug_object_destroy); + */ + void debug_object_free(void *addr, const struct debug_obj_descr *descr) + { +- enum debug_obj_state state; ++ struct debug_obj *obj, o; + struct debug_bucket *db; +- struct debug_obj *obj; + unsigned long flags; + + if (!debug_objects_enabled) +@@ -885,24 +852,26 @@ void debug_object_free(void *addr, const struct debug_obj_descr *descr) + raw_spin_lock_irqsave(&db->lock, flags); + + obj = lookup_object(addr, db); +- if (!obj) +- goto out_unlock; ++ if (!obj) { ++ raw_spin_unlock_irqrestore(&db->lock, flags); ++ return; ++ } + + switch (obj->state) { + case ODEBUG_STATE_ACTIVE: +- state = obj->state; +- raw_spin_unlock_irqrestore(&db->lock, flags); +- debug_print_object(obj, "free"); +- debug_object_fixup(descr->fixup_free, addr, state); +- return; ++ break; + default: + hlist_del(&obj->node); + raw_spin_unlock_irqrestore(&db->lock, flags); + free_object(obj); + return; + } +-out_unlock: ++ ++ o = *obj; + raw_spin_unlock_irqrestore(&db->lock, flags); ++ debug_print_object(&o, "free"); ++ ++ debug_object_fixup(descr->fixup_free, addr, o.state); + } + EXPORT_SYMBOL_GPL(debug_object_free); + +@@ -954,10 +923,10 @@ void + debug_object_active_state(void *addr, const struct debug_obj_descr *descr, + unsigned int expect, unsigned int next) + { ++ struct debug_obj o = { .object = addr, .state = ODEBUG_STATE_NOTAVAILABLE, .descr = descr }; + struct debug_bucket *db; + struct debug_obj *obj; + unsigned long flags; +- bool print_object = false; + + if (!debug_objects_enabled) + return; +@@ -970,28 +939,19 @@ debug_object_active_state(void *addr, const struct debug_obj_descr *descr, + if (obj) { + switch (obj->state) { + case ODEBUG_STATE_ACTIVE: +- if (obj->astate == expect) +- obj->astate = next; +- else +- print_object = true; +- break; +- ++ if (obj->astate != expect) ++ break; ++ obj->astate = next; ++ raw_spin_unlock_irqrestore(&db->lock, flags); ++ return; + default: +- print_object = true; + break; + } ++ o = *obj; + } + + raw_spin_unlock_irqrestore(&db->lock, flags); +- if (!obj) { +- struct debug_obj o = { .object = addr, +- .state = ODEBUG_STATE_NOTAVAILABLE, +- .descr = descr }; +- +- debug_print_object(&o, "active_state"); +- } else if (print_object) { +- debug_print_object(obj, "active_state"); +- } ++ debug_print_object(&o, "active_state"); + } + EXPORT_SYMBOL_GPL(debug_object_active_state); + +@@ -999,12 +959,10 @@ EXPORT_SYMBOL_GPL(debug_object_active_state); + static void __debug_check_no_obj_freed(const void *address, unsigned long size) + { + unsigned long flags, oaddr, saddr, eaddr, paddr, chunks; +- const struct debug_obj_descr *descr; +- enum debug_obj_state state; ++ int cnt, objs_checked = 0; ++ struct debug_obj *obj, o; + struct debug_bucket *db; + struct hlist_node *tmp; +- struct debug_obj *obj; +- int cnt, objs_checked = 0; + + saddr = (unsigned long) address; + eaddr = saddr + size; +@@ -1026,12 +984,10 @@ repeat: + + switch (obj->state) { + case ODEBUG_STATE_ACTIVE: +- descr = obj->descr; +- state = obj->state; ++ o = *obj; + raw_spin_unlock_irqrestore(&db->lock, flags); +- debug_print_object(obj, "free"); +- debug_object_fixup(descr->fixup_free, +- (void *) oaddr, state); ++ debug_print_object(&o, "free"); ++ debug_object_fixup(o.descr->fixup_free, (void *)oaddr, o.state); + goto repeat; + default: + hlist_del(&obj->node); +diff --git a/lib/fw_table.c b/lib/fw_table.c +index 294df54e33b6f..c49a09ee3853c 100644 +--- a/lib/fw_table.c ++++ b/lib/fw_table.c +@@ -85,11 +85,6 @@ acpi_get_subtable_type(char *id) + return ACPI_SUBTABLE_COMMON; + } + +-static __init_or_acpilib bool has_handler(struct acpi_subtable_proc *proc) +-{ +- return proc->handler || proc->handler_arg; +-} +- + static __init_or_acpilib int call_handler(struct acpi_subtable_proc *proc, + union acpi_subtable_headers *hdr, + unsigned long end) +@@ -133,7 +128,6 @@ acpi_parse_entries_array(char *id, unsigned long table_size, + unsigned long table_end, subtable_len, entry_len; + struct acpi_subtable_entry entry; + int count = 0; +- int errs = 0; + int i; + + table_end = (unsigned long)table_header + table_header->length; +@@ -145,25 +139,19 @@ acpi_parse_entries_array(char *id, unsigned long table_size, + ((unsigned long)table_header + table_size); + subtable_len = acpi_get_subtable_header_length(&entry); + +- while (((unsigned long)entry.hdr) + subtable_len < table_end) { +- if (max_entries && count >= max_entries) +- break; +- ++ while (((unsigned long)entry.hdr) + subtable_len < table_end) { + for (i = 0; i < proc_num; i++) { + if (acpi_get_entry_type(&entry) != proc[i].id) + continue; +- if (!has_handler(&proc[i]) || +- (!errs && +- call_handler(&proc[i], entry.hdr, table_end))) { +- errs++; +- continue; +- } ++ ++ if (!max_entries || count < max_entries) ++ if (call_handler(&proc[i], entry.hdr, table_end)) ++ return -EINVAL; + + proc[i].count++; ++ count++; + break; + } +- if (i != proc_num) +- count++; + + /* + * If entry->length is 0, break from this loop to avoid +@@ -180,9 +168,9 @@ acpi_parse_entries_array(char *id, unsigned long table_size, + } + + if (max_entries && count > max_entries) { +- pr_warn("[%4.4s:0x%02x] found the maximum %i entries\n", +- id, proc->id, count); ++ pr_warn("[%4.4s:0x%02x] ignored %i entries of %i found\n", ++ id, proc->id, count - max_entries, count); + } + +- return errs ? -EINVAL : count; ++ return count; + } +diff --git a/lib/kunit/executor.c b/lib/kunit/executor.c +index 1236b3cd2fbb2..51013feba58b1 100644 +--- a/lib/kunit/executor.c ++++ b/lib/kunit/executor.c +@@ -144,6 +144,10 @@ void kunit_free_suite_set(struct kunit_suite_set suite_set) + kfree(suite_set.start); + } + ++/* ++ * Filter and reallocate test suites. Must return the filtered test suites set ++ * allocated at a valid virtual address or NULL in case of error. ++ */ + struct kunit_suite_set + kunit_filter_suites(const struct kunit_suite_set *suite_set, + const char *filter_glob, +diff --git a/lib/kunit/test.c b/lib/kunit/test.c +index 7aceb07a1af9f..3dc9d66eca494 100644 +--- a/lib/kunit/test.c ++++ b/lib/kunit/test.c +@@ -16,6 +16,7 @@ + #include <linux/panic.h> + #include <linux/sched/debug.h> + #include <linux/sched.h> ++#include <linux/mm.h> + + #include "debugfs.h" + #include "hooks-impl.h" +@@ -660,6 +661,7 @@ int kunit_run_tests(struct kunit_suite *suite) + test.param_index++; + test.status = KUNIT_SUCCESS; + test.status_comment[0] = '\0'; ++ test.priv = NULL; + } + } + +@@ -775,12 +777,19 @@ static void kunit_module_exit(struct module *mod) + }; + const char *action = kunit_action(); + ++ /* ++ * Check if the start address is a valid virtual address to detect ++ * if the module load sequence has failed and the suite set has not ++ * been initialized and filtered. ++ */ ++ if (!suite_set.start || !virt_addr_valid(suite_set.start)) ++ return; ++ + if (!action) + __kunit_test_suites_exit(mod->kunit_suites, + mod->num_kunit_suites); + +- if (suite_set.start) +- kunit_free_suite_set(suite_set); ++ kunit_free_suite_set(suite_set); + } + + static int kunit_module_notify(struct notifier_block *nb, unsigned long val, +@@ -790,12 +799,12 @@ static int kunit_module_notify(struct notifier_block *nb, unsigned long val, + + switch (val) { + case MODULE_STATE_LIVE: ++ kunit_module_init(mod); + break; + case MODULE_STATE_GOING: + kunit_module_exit(mod); + break; + case MODULE_STATE_COMING: +- kunit_module_init(mod); + break; + case MODULE_STATE_UNFORMED: + break; +diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c +index d85a7091a1169..97284d9b2a2e3 100644 +--- a/net/bluetooth/hci_sync.c ++++ b/net/bluetooth/hci_sync.c +@@ -3800,12 +3800,14 @@ static int hci_set_event_mask_sync(struct hci_dev *hdev) + if (lmp_bredr_capable(hdev)) { + events[4] |= 0x01; /* Flow Specification Complete */ + +- /* Don't set Disconnect Complete when suspended as that +- * would wakeup the host when disconnecting due to +- * suspend. ++ /* Don't set Disconnect Complete and mode change when ++ * suspended as that would wakeup the host when disconnecting ++ * due to suspend. + */ +- if (hdev->suspended) ++ if (hdev->suspended) { + events[0] &= 0xef; ++ events[2] &= 0xf7; ++ } + } else { + /* Use a different default for LE-only devices */ + memset(events, 0, sizeof(events)); +diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c +index 07b80e97aead5..fd81289fd3e57 100644 +--- a/net/bluetooth/iso.c ++++ b/net/bluetooth/iso.c +@@ -54,6 +54,7 @@ static void iso_sock_kill(struct sock *sk); + enum { + BT_SK_BIG_SYNC, + BT_SK_PA_SYNC, ++ BT_SK_PA_SYNC_TERM, + }; + + struct iso_pinfo { +@@ -82,6 +83,11 @@ static bool iso_match_sid(struct sock *sk, void *data); + static bool iso_match_sync_handle(struct sock *sk, void *data); + static void iso_sock_disconn(struct sock *sk); + ++typedef bool (*iso_sock_match_t)(struct sock *sk, void *data); ++ ++static struct sock *iso_get_sock_listen(bdaddr_t *src, bdaddr_t *dst, ++ iso_sock_match_t match, void *data); ++ + /* ---- ISO timers ---- */ + #define ISO_CONN_TIMEOUT (HZ * 40) + #define ISO_DISCONN_TIMEOUT (HZ * 2) +@@ -190,10 +196,21 @@ static void iso_chan_del(struct sock *sk, int err) + sock_set_flag(sk, SOCK_ZAPPED); + } + ++static bool iso_match_conn_sync_handle(struct sock *sk, void *data) ++{ ++ struct hci_conn *hcon = data; ++ ++ if (test_bit(BT_SK_PA_SYNC, &iso_pi(sk)->flags)) ++ return false; ++ ++ return hcon->sync_handle == iso_pi(sk)->sync_handle; ++} ++ + static void iso_conn_del(struct hci_conn *hcon, int err) + { + struct iso_conn *conn = hcon->iso_data; + struct sock *sk; ++ struct sock *parent; + + if (!conn) + return; +@@ -209,6 +226,25 @@ static void iso_conn_del(struct hci_conn *hcon, int err) + + if (sk) { + lock_sock(sk); ++ ++ /* While a PA sync hcon is in the process of closing, ++ * mark parent socket with a flag, so that any residual ++ * BIGInfo adv reports that arrive before PA sync is ++ * terminated are not processed anymore. ++ */ ++ if (test_bit(BT_SK_PA_SYNC, &iso_pi(sk)->flags)) { ++ parent = iso_get_sock_listen(&hcon->src, ++ &hcon->dst, ++ iso_match_conn_sync_handle, ++ hcon); ++ ++ if (parent) { ++ set_bit(BT_SK_PA_SYNC_TERM, ++ &iso_pi(parent)->flags); ++ sock_put(parent); ++ } ++ } ++ + iso_sock_clear_timer(sk); + iso_chan_del(sk, err); + release_sock(sk); +@@ -545,8 +581,6 @@ static struct sock *__iso_get_sock_listen_by_sid(bdaddr_t *ba, bdaddr_t *bc, + return NULL; + } + +-typedef bool (*iso_sock_match_t)(struct sock *sk, void *data); +- + /* Find socket listening: + * source bdaddr (Unicast) + * destination bdaddr (Broadcast only) +@@ -1759,9 +1793,20 @@ int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags) + /* Try to get PA sync listening socket, if it exists */ + sk = iso_get_sock_listen(&hdev->bdaddr, bdaddr, + iso_match_pa_sync_flag, NULL); +- if (!sk) ++ ++ if (!sk) { + sk = iso_get_sock_listen(&hdev->bdaddr, bdaddr, + iso_match_sync_handle, ev2); ++ ++ /* If PA Sync is in process of terminating, ++ * do not handle any more BIGInfo adv reports. ++ */ ++ ++ if (sk && test_bit(BT_SK_PA_SYNC_TERM, ++ &iso_pi(sk)->flags)) ++ return lm; ++ } ++ + if (sk) { + int err; + +diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c +index baeebee41cd9e..60298975d5c45 100644 +--- a/net/bluetooth/l2cap_core.c ++++ b/net/bluetooth/l2cap_core.c +@@ -6526,7 +6526,8 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn, + if (len > skb->len || !cmd->ident) { + BT_DBG("corrupted command"); + l2cap_sig_send_rej(conn, cmd->ident); +- break; ++ skb_pull(skb, len > skb->len ? skb->len : len); ++ continue; + } + + err = l2cap_bredr_sig_cmd(conn, cmd, len, skb->data); +diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c +index c9fdcc5cdce10..711cf5d59816b 100644 +--- a/net/bpf/test_run.c ++++ b/net/bpf/test_run.c +@@ -542,7 +542,7 @@ struct bpf_fentry_test_t { + + int noinline bpf_fentry_test7(struct bpf_fentry_test_t *arg) + { +- asm volatile (""); ++ asm volatile ("": "+r"(arg)); + return (long)arg; + } + +diff --git a/net/bridge/br_cfm_netlink.c b/net/bridge/br_cfm_netlink.c +index 5c4c369f8536e..2faab44652e7c 100644 +--- a/net/bridge/br_cfm_netlink.c ++++ b/net/bridge/br_cfm_netlink.c +@@ -362,7 +362,7 @@ static int br_cc_ccm_tx_parse(struct net_bridge *br, struct nlattr *attr, + + memset(&tx_info, 0, sizeof(tx_info)); + +- instance = nla_get_u32(tb[IFLA_BRIDGE_CFM_CC_RDI_INSTANCE]); ++ instance = nla_get_u32(tb[IFLA_BRIDGE_CFM_CC_CCM_TX_INSTANCE]); + nla_memcpy(&tx_info.dmac.addr, + tb[IFLA_BRIDGE_CFM_CC_CCM_TX_DMAC], + sizeof(tx_info.dmac.addr)); +diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c +index d7d021af10298..2d7b732429588 100644 +--- a/net/bridge/br_multicast.c ++++ b/net/bridge/br_multicast.c +@@ -1762,6 +1762,10 @@ static void br_ip6_multicast_querier_expired(struct timer_list *t) + } + #endif + ++static void br_multicast_query_delay_expired(struct timer_list *t) ++{ ++} ++ + static void br_multicast_select_own_querier(struct net_bridge_mcast *brmctx, + struct br_ip *ip, + struct sk_buff *skb) +@@ -3198,7 +3202,7 @@ br_multicast_update_query_timer(struct net_bridge_mcast *brmctx, + unsigned long max_delay) + { + if (!timer_pending(&query->timer)) +- query->delay_time = jiffies + max_delay; ++ mod_timer(&query->delay_timer, jiffies + max_delay); + + mod_timer(&query->timer, jiffies + brmctx->multicast_querier_interval); + } +@@ -4041,13 +4045,11 @@ void br_multicast_ctx_init(struct net_bridge *br, + brmctx->multicast_querier_interval = 255 * HZ; + brmctx->multicast_membership_interval = 260 * HZ; + +- brmctx->ip4_other_query.delay_time = 0; + brmctx->ip4_querier.port_ifidx = 0; + seqcount_spinlock_init(&brmctx->ip4_querier.seq, &br->multicast_lock); + brmctx->multicast_igmp_version = 2; + #if IS_ENABLED(CONFIG_IPV6) + brmctx->multicast_mld_version = 1; +- brmctx->ip6_other_query.delay_time = 0; + brmctx->ip6_querier.port_ifidx = 0; + seqcount_spinlock_init(&brmctx->ip6_querier.seq, &br->multicast_lock); + #endif +@@ -4056,6 +4058,8 @@ void br_multicast_ctx_init(struct net_bridge *br, + br_ip4_multicast_local_router_expired, 0); + timer_setup(&brmctx->ip4_other_query.timer, + br_ip4_multicast_querier_expired, 0); ++ timer_setup(&brmctx->ip4_other_query.delay_timer, ++ br_multicast_query_delay_expired, 0); + timer_setup(&brmctx->ip4_own_query.timer, + br_ip4_multicast_query_expired, 0); + #if IS_ENABLED(CONFIG_IPV6) +@@ -4063,6 +4067,8 @@ void br_multicast_ctx_init(struct net_bridge *br, + br_ip6_multicast_local_router_expired, 0); + timer_setup(&brmctx->ip6_other_query.timer, + br_ip6_multicast_querier_expired, 0); ++ timer_setup(&brmctx->ip6_other_query.delay_timer, ++ br_multicast_query_delay_expired, 0); + timer_setup(&brmctx->ip6_own_query.timer, + br_ip6_multicast_query_expired, 0); + #endif +@@ -4197,10 +4203,12 @@ static void __br_multicast_stop(struct net_bridge_mcast *brmctx) + { + del_timer_sync(&brmctx->ip4_mc_router_timer); + del_timer_sync(&brmctx->ip4_other_query.timer); ++ del_timer_sync(&brmctx->ip4_other_query.delay_timer); + del_timer_sync(&brmctx->ip4_own_query.timer); + #if IS_ENABLED(CONFIG_IPV6) + del_timer_sync(&brmctx->ip6_mc_router_timer); + del_timer_sync(&brmctx->ip6_other_query.timer); ++ del_timer_sync(&brmctx->ip6_other_query.delay_timer); + del_timer_sync(&brmctx->ip6_own_query.timer); + #endif + } +@@ -4643,13 +4651,15 @@ int br_multicast_set_querier(struct net_bridge_mcast *brmctx, unsigned long val) + max_delay = brmctx->multicast_query_response_interval; + + if (!timer_pending(&brmctx->ip4_other_query.timer)) +- brmctx->ip4_other_query.delay_time = jiffies + max_delay; ++ mod_timer(&brmctx->ip4_other_query.delay_timer, ++ jiffies + max_delay); + + br_multicast_start_querier(brmctx, &brmctx->ip4_own_query); + + #if IS_ENABLED(CONFIG_IPV6) + if (!timer_pending(&brmctx->ip6_other_query.timer)) +- brmctx->ip6_other_query.delay_time = jiffies + max_delay; ++ mod_timer(&brmctx->ip6_other_query.delay_timer, ++ jiffies + max_delay); + + br_multicast_start_querier(brmctx, &brmctx->ip6_own_query); + #endif +diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h +index 6b7f36769d032..f317d8295bf41 100644 +--- a/net/bridge/br_private.h ++++ b/net/bridge/br_private.h +@@ -78,7 +78,7 @@ struct bridge_mcast_own_query { + /* other querier */ + struct bridge_mcast_other_query { + struct timer_list timer; +- unsigned long delay_time; ++ struct timer_list delay_timer; + }; + + /* selected querier */ +@@ -1155,7 +1155,7 @@ __br_multicast_querier_exists(struct net_bridge_mcast *brmctx, + own_querier_enabled = false; + } + +- return time_is_before_jiffies(querier->delay_time) && ++ return !timer_pending(&querier->delay_timer) && + (own_querier_enabled || timer_pending(&querier->timer)); + } + +diff --git a/net/devlink/port.c b/net/devlink/port.c +index 7634f187fa505..841a3eafa328e 100644 +--- a/net/devlink/port.c ++++ b/net/devlink/port.c +@@ -672,7 +672,7 @@ static int devlink_port_function_validate(struct devlink_port *devlink_port, + return -EOPNOTSUPP; + } + if (tb[DEVLINK_PORT_FN_ATTR_STATE] && !ops->port_fn_state_set) { +- NL_SET_ERR_MSG_ATTR(extack, tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR], ++ NL_SET_ERR_MSG_ATTR(extack, tb[DEVLINK_PORT_FN_ATTR_STATE], + "Function does not support state setting"); + return -EOPNOTSUPP; + } +diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c +index b06f678b03a19..41537d18eecfd 100644 +--- a/net/ipv4/ip_output.c ++++ b/net/ipv4/ip_output.c +@@ -1287,6 +1287,12 @@ static int ip_setup_cork(struct sock *sk, struct inet_cork *cork, + if (unlikely(!rt)) + return -EFAULT; + ++ cork->fragsize = ip_sk_use_pmtu(sk) ? ++ dst_mtu(&rt->dst) : READ_ONCE(rt->dst.dev->mtu); ++ ++ if (!inetdev_valid_mtu(cork->fragsize)) ++ return -ENETUNREACH; ++ + /* + * setup for corking. + */ +@@ -1303,12 +1309,6 @@ static int ip_setup_cork(struct sock *sk, struct inet_cork *cork, + cork->addr = ipc->addr; + } + +- cork->fragsize = ip_sk_use_pmtu(sk) ? +- dst_mtu(&rt->dst) : READ_ONCE(rt->dst.dev->mtu); +- +- if (!inetdev_valid_mtu(cork->fragsize)) +- return -ENETUNREACH; +- + cork->gso_size = ipc->gso_size; + + cork->dst = &rt->dst; +diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c +index 2efc53526a382..8a88e705d8271 100644 +--- a/net/ipv4/ip_sockglue.c ++++ b/net/ipv4/ip_sockglue.c +@@ -1366,12 +1366,13 @@ e_inval: + * ipv4_pktinfo_prepare - transfer some info from rtable to skb + * @sk: socket + * @skb: buffer ++ * @drop_dst: if true, drops skb dst + * + * To support IP_CMSG_PKTINFO option, we store rt_iif and specific + * destination in skb->cb[] before dst drop. + * This way, receiver doesn't make cache line misses to read rtable. + */ +-void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb) ++void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb, bool drop_dst) + { + struct in_pktinfo *pktinfo = PKTINFO_SKB_CB(skb); + bool prepare = inet_test_bit(PKTINFO, sk) || +@@ -1400,7 +1401,8 @@ void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb) + pktinfo->ipi_ifindex = 0; + pktinfo->ipi_spec_dst.s_addr = 0; + } +- skb_dst_drop(skb); ++ if (drop_dst) ++ skb_dst_drop(skb); + } + + int ip_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval, +diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c +index 0063a237253bf..e49242706b5f5 100644 +--- a/net/ipv4/ipmr.c ++++ b/net/ipv4/ipmr.c +@@ -1073,7 +1073,7 @@ 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; +- ipv4_pktinfo_prepare(mroute_sk, pkt); ++ ipv4_pktinfo_prepare(mroute_sk, pkt, false); + memcpy(skb->cb, pkt->cb, sizeof(skb->cb)); + /* Add our header */ + igmp = skb_put(skb, sizeof(struct igmphdr)); +diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c +index 27da9d7294c0b..aea89326c6979 100644 +--- a/net/ipv4/raw.c ++++ b/net/ipv4/raw.c +@@ -292,7 +292,7 @@ static int raw_rcv_skb(struct sock *sk, struct sk_buff *skb) + + /* Charge it to the socket. */ + +- ipv4_pktinfo_prepare(sk, skb); ++ ipv4_pktinfo_prepare(sk, skb, true); + if (sock_queue_rcv_skb_reason(sk, skb, &reason) < 0) { + kfree_skb_reason(skb, reason); + return NET_RX_DROP; +diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c +index 7bce79beca2b9..b30ef770a6cca 100644 +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -1786,7 +1786,17 @@ static skb_frag_t *skb_advance_to_frag(struct sk_buff *skb, u32 offset_skb, + + static bool can_map_frag(const skb_frag_t *frag) + { +- return skb_frag_size(frag) == PAGE_SIZE && !skb_frag_off(frag); ++ struct page *page; ++ ++ if (skb_frag_size(frag) != PAGE_SIZE || skb_frag_off(frag)) ++ return false; ++ ++ page = skb_frag_page(frag); ++ ++ if (PageCompound(page) || page->mapping) ++ return false; ++ ++ return true; + } + + static int find_next_mappable_frag(const skb_frag_t *frag, +diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c +index 148ffb007969f..f631b0a21af4c 100644 +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -2169,7 +2169,7 @@ static int udp_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb) + + udp_csum_pull_header(skb); + +- ipv4_pktinfo_prepare(sk, skb); ++ ipv4_pktinfo_prepare(sk, skb, true); + return __udp_queue_rcv_skb(sk, skb); + + csum_error: +diff --git a/net/ipv6/addrconf_core.c b/net/ipv6/addrconf_core.c +index 507a8353a6bdb..c008d21925d7f 100644 +--- a/net/ipv6/addrconf_core.c ++++ b/net/ipv6/addrconf_core.c +@@ -220,19 +220,26 @@ const struct ipv6_stub *ipv6_stub __read_mostly = &(struct ipv6_stub) { + EXPORT_SYMBOL_GPL(ipv6_stub); + + /* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */ +-const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT; ++const struct in6_addr in6addr_loopback __aligned(BITS_PER_LONG/8) ++ = IN6ADDR_LOOPBACK_INIT; + EXPORT_SYMBOL(in6addr_loopback); +-const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT; ++const struct in6_addr in6addr_any __aligned(BITS_PER_LONG/8) ++ = IN6ADDR_ANY_INIT; + EXPORT_SYMBOL(in6addr_any); +-const struct in6_addr in6addr_linklocal_allnodes = IN6ADDR_LINKLOCAL_ALLNODES_INIT; ++const struct in6_addr in6addr_linklocal_allnodes __aligned(BITS_PER_LONG/8) ++ = IN6ADDR_LINKLOCAL_ALLNODES_INIT; + EXPORT_SYMBOL(in6addr_linklocal_allnodes); +-const struct in6_addr in6addr_linklocal_allrouters = IN6ADDR_LINKLOCAL_ALLROUTERS_INIT; ++const struct in6_addr in6addr_linklocal_allrouters __aligned(BITS_PER_LONG/8) ++ = IN6ADDR_LINKLOCAL_ALLROUTERS_INIT; + EXPORT_SYMBOL(in6addr_linklocal_allrouters); +-const struct in6_addr in6addr_interfacelocal_allnodes = IN6ADDR_INTERFACELOCAL_ALLNODES_INIT; ++const struct in6_addr in6addr_interfacelocal_allnodes __aligned(BITS_PER_LONG/8) ++ = IN6ADDR_INTERFACELOCAL_ALLNODES_INIT; + EXPORT_SYMBOL(in6addr_interfacelocal_allnodes); +-const struct in6_addr in6addr_interfacelocal_allrouters = IN6ADDR_INTERFACELOCAL_ALLROUTERS_INIT; ++const struct in6_addr in6addr_interfacelocal_allrouters __aligned(BITS_PER_LONG/8) ++ = IN6ADDR_INTERFACELOCAL_ALLROUTERS_INIT; + EXPORT_SYMBOL(in6addr_interfacelocal_allrouters); +-const struct in6_addr in6addr_sitelocal_allrouters = IN6ADDR_SITELOCAL_ALLROUTERS_INIT; ++const struct in6_addr in6addr_sitelocal_allrouters __aligned(BITS_PER_LONG/8) ++ = IN6ADDR_SITELOCAL_ALLROUTERS_INIT; + EXPORT_SYMBOL(in6addr_sitelocal_allrouters); + + static void snmp6_free_dev(struct inet6_dev *idev) +diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c +index 46c19bd489901..9bbabf750a21e 100644 +--- a/net/ipv6/ip6_tunnel.c ++++ b/net/ipv6/ip6_tunnel.c +@@ -796,8 +796,8 @@ static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff *skb, + struct sk_buff *skb), + bool log_ecn_err) + { +- const struct ipv6hdr *ipv6h = ipv6_hdr(skb); +- int err; ++ const struct ipv6hdr *ipv6h; ++ int nh, err; + + if ((!(tpi->flags & TUNNEL_CSUM) && + (tunnel->parms.i_flags & TUNNEL_CSUM)) || +@@ -829,7 +829,6 @@ static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff *skb, + goto drop; + } + +- ipv6h = ipv6_hdr(skb); + skb->protocol = eth_type_trans(skb, tunnel->dev); + skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN); + } else { +@@ -837,7 +836,23 @@ static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff *skb, + skb_reset_mac_header(skb); + } + ++ /* Save offset of outer header relative to skb->head, ++ * because we are going to reset the network header to the inner header ++ * and might change skb->head. ++ */ ++ nh = skb_network_header(skb) - skb->head; ++ + skb_reset_network_header(skb); ++ ++ if (!pskb_inet_may_pull(skb)) { ++ DEV_STATS_INC(tunnel->dev, rx_length_errors); ++ DEV_STATS_INC(tunnel->dev, rx_errors); ++ goto drop; ++ } ++ ++ /* Get the outer header. */ ++ ipv6h = (struct ipv6hdr *)(skb->head + nh); ++ + memset(skb->cb, 0, sizeof(struct inet6_skb_parm)); + + __skb_tunnel_rx(skb, tunnel->dev, tunnel->net); +diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c +index 65d1f6755f98f..1184d40167b86 100644 +--- a/net/kcm/kcmsock.c ++++ b/net/kcm/kcmsock.c +@@ -634,7 +634,7 @@ retry: + + msize = 0; + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) +- msize += skb_shinfo(skb)->frags[i].bv_len; ++ msize += skb_frag_size(&skb_shinfo(skb)->frags[i]); + + iov_iter_bvec(&msg.msg_iter, ITER_SOURCE, + skb_shinfo(skb)->frags, skb_shinfo(skb)->nr_frags, +diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c +index 20551cfb7da6d..fde1140d899ef 100644 +--- a/net/llc/af_llc.c ++++ b/net/llc/af_llc.c +@@ -226,6 +226,8 @@ static int llc_ui_release(struct socket *sock) + } + netdev_put(llc->dev, &llc->dev_tracker); + sock_put(sk); ++ sock_orphan(sk); ++ sock->sk = NULL; + llc_sk_free(sk); + out: + return 0; +diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c +index e573be5afde7a..ae493599a3ef0 100644 +--- a/net/netfilter/nf_conntrack_proto_tcp.c ++++ b/net/netfilter/nf_conntrack_proto_tcp.c +@@ -457,7 +457,8 @@ static void tcp_init_sender(struct ip_ct_tcp_state *sender, + const struct sk_buff *skb, + unsigned int dataoff, + const struct tcphdr *tcph, +- u32 end, u32 win) ++ u32 end, u32 win, ++ enum ip_conntrack_dir dir) + { + /* SYN-ACK in reply to a SYN + * or SYN from reply direction in simultaneous open. +@@ -471,7 +472,8 @@ static void tcp_init_sender(struct ip_ct_tcp_state *sender, + * Both sides must send the Window Scale option + * to enable window scaling in either direction. + */ +- if (!(sender->flags & IP_CT_TCP_FLAG_WINDOW_SCALE && ++ if (dir == IP_CT_DIR_REPLY && ++ !(sender->flags & IP_CT_TCP_FLAG_WINDOW_SCALE && + receiver->flags & IP_CT_TCP_FLAG_WINDOW_SCALE)) { + sender->td_scale = 0; + receiver->td_scale = 0; +@@ -542,7 +544,7 @@ tcp_in_window(struct nf_conn *ct, enum ip_conntrack_dir dir, + if (tcph->syn) { + tcp_init_sender(sender, receiver, + skb, dataoff, tcph, +- end, win); ++ end, win, dir); + if (!tcph->ack) + /* Simultaneous open */ + return NFCT_TCP_ACCEPT; +@@ -585,7 +587,7 @@ tcp_in_window(struct nf_conn *ct, enum ip_conntrack_dir dir, + */ + tcp_init_sender(sender, receiver, + skb, dataoff, tcph, +- end, win); ++ end, win, dir); + + if (dir == IP_CT_DIR_REPLY && !tcph->ack) + return NFCT_TCP_ACCEPT; +diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c +index 8cc52d2bd31be..e16f158388bbe 100644 +--- a/net/netfilter/nf_log.c ++++ b/net/netfilter/nf_log.c +@@ -193,11 +193,12 @@ void nf_logger_put(int pf, enum nf_log_type type) + return; + } + +- BUG_ON(loggers[pf][type] == NULL); +- + rcu_read_lock(); + logger = rcu_dereference(loggers[pf][type]); +- module_put(logger->me); ++ if (!logger) ++ WARN_ON_ONCE(1); ++ else ++ module_put(logger->me); + rcu_read_unlock(); + } + EXPORT_SYMBOL_GPL(nf_logger_put); +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index 6a987b36d0bb0..0e07f110a539b 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -7468,11 +7468,15 @@ nla_put_failure: + return -1; + } + +-static const struct nft_object_type *__nft_obj_type_get(u32 objtype) ++static const struct nft_object_type *__nft_obj_type_get(u32 objtype, u8 family) + { + const struct nft_object_type *type; + + list_for_each_entry(type, &nf_tables_objects, list) { ++ if (type->family != NFPROTO_UNSPEC && ++ type->family != family) ++ continue; ++ + if (objtype == type->type) + return type; + } +@@ -7480,11 +7484,11 @@ static const struct nft_object_type *__nft_obj_type_get(u32 objtype) + } + + static const struct nft_object_type * +-nft_obj_type_get(struct net *net, u32 objtype) ++nft_obj_type_get(struct net *net, u32 objtype, u8 family) + { + const struct nft_object_type *type; + +- type = __nft_obj_type_get(objtype); ++ type = __nft_obj_type_get(objtype, family); + if (type != NULL && try_module_get(type->owner)) + return type; + +@@ -7577,7 +7581,7 @@ static int nf_tables_newobj(struct sk_buff *skb, const struct nfnl_info *info, + if (info->nlh->nlmsg_flags & NLM_F_REPLACE) + return -EOPNOTSUPP; + +- type = __nft_obj_type_get(objtype); ++ type = __nft_obj_type_get(objtype, family); + if (WARN_ON_ONCE(!type)) + return -ENOENT; + +@@ -7591,7 +7595,7 @@ static int nf_tables_newobj(struct sk_buff *skb, const struct nfnl_info *info, + if (!nft_use_inc(&table->use)) + return -EMFILE; + +- type = nft_obj_type_get(net, objtype); ++ type = nft_obj_type_get(net, objtype, family); + if (IS_ERR(type)) { + err = PTR_ERR(type); + goto err_type; +diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c +index 86bb9d7797d9e..aac98a3c966e9 100644 +--- a/net/netfilter/nft_ct.c ++++ b/net/netfilter/nft_ct.c +@@ -1250,7 +1250,31 @@ static int nft_ct_expect_obj_init(const struct nft_ctx *ctx, + if (tb[NFTA_CT_EXPECT_L3PROTO]) + priv->l3num = ntohs(nla_get_be16(tb[NFTA_CT_EXPECT_L3PROTO])); + ++ switch (priv->l3num) { ++ case NFPROTO_IPV4: ++ case NFPROTO_IPV6: ++ if (priv->l3num != ctx->family) ++ return -EINVAL; ++ ++ fallthrough; ++ case NFPROTO_INET: ++ break; ++ default: ++ return -EOPNOTSUPP; ++ } ++ + priv->l4proto = nla_get_u8(tb[NFTA_CT_EXPECT_L4PROTO]); ++ switch (priv->l4proto) { ++ case IPPROTO_TCP: ++ case IPPROTO_UDP: ++ case IPPROTO_UDPLITE: ++ case IPPROTO_DCCP: ++ case IPPROTO_SCTP: ++ break; ++ default: ++ return -EOPNOTSUPP; ++ } ++ + priv->dport = nla_get_be16(tb[NFTA_CT_EXPECT_DPORT]); + priv->timeout = nla_get_u32(tb[NFTA_CT_EXPECT_TIMEOUT]); + priv->size = nla_get_u8(tb[NFTA_CT_EXPECT_SIZE]); +diff --git a/net/netfilter/nft_tunnel.c b/net/netfilter/nft_tunnel.c +index 9f21953c7433f..f735d79d8be57 100644 +--- a/net/netfilter/nft_tunnel.c ++++ b/net/netfilter/nft_tunnel.c +@@ -713,6 +713,7 @@ static const struct nft_object_ops nft_tunnel_obj_ops = { + + static struct nft_object_type nft_tunnel_obj_type __read_mostly = { + .type = NFT_OBJECT_TUNNEL, ++ .family = NFPROTO_NETDEV, + .ops = &nft_tunnel_obj_ops, + .maxattr = NFTA_TUNNEL_KEY_MAX, + .policy = nft_tunnel_key_policy, +diff --git a/net/rxrpc/conn_service.c b/net/rxrpc/conn_service.c +index 89ac05a711a42..39c908a3ca6e8 100644 +--- a/net/rxrpc/conn_service.c ++++ b/net/rxrpc/conn_service.c +@@ -25,7 +25,7 @@ struct rxrpc_connection *rxrpc_find_service_conn_rcu(struct rxrpc_peer *peer, + struct rxrpc_conn_proto k; + struct rxrpc_skb_priv *sp = rxrpc_skb(skb); + struct rb_node *p; +- unsigned int seq = 0; ++ unsigned int seq = 1; + + k.epoch = sp->hdr.epoch; + k.cid = sp->hdr.cid & RXRPC_CIDMASK; +@@ -35,6 +35,7 @@ struct rxrpc_connection *rxrpc_find_service_conn_rcu(struct rxrpc_peer *peer, + * under just the RCU read lock, so we have to check for + * changes. + */ ++ seq++; /* 2 on the 1st/lockless path, otherwise odd */ + read_seqbegin_or_lock(&peer->service_conn_lock, &seq); + + p = rcu_dereference_raw(peer->service_conns.rb_node); +diff --git a/net/smc/smc_clc.c b/net/smc/smc_clc.c +index 72f4d81a3f41f..1489a8421d786 100644 +--- a/net/smc/smc_clc.c ++++ b/net/smc/smc_clc.c +@@ -155,10 +155,12 @@ static int smc_clc_ueid_remove(char *ueid) + rc = 0; + } + } ++#if IS_ENABLED(CONFIG_S390) + if (!rc && !smc_clc_eid_table.ueid_cnt) { + smc_clc_eid_table.seid_enabled = 1; + rc = -EAGAIN; /* indicate success and enabling of seid */ + } ++#endif + write_unlock(&smc_clc_eid_table.lock); + return rc; + } +@@ -273,22 +275,30 @@ err: + + int smc_nl_enable_seid(struct sk_buff *skb, struct genl_info *info) + { ++#if IS_ENABLED(CONFIG_S390) + write_lock(&smc_clc_eid_table.lock); + smc_clc_eid_table.seid_enabled = 1; + write_unlock(&smc_clc_eid_table.lock); + return 0; ++#else ++ return -EOPNOTSUPP; ++#endif + } + + int smc_nl_disable_seid(struct sk_buff *skb, struct genl_info *info) + { + int rc = 0; + ++#if IS_ENABLED(CONFIG_S390) + write_lock(&smc_clc_eid_table.lock); + if (!smc_clc_eid_table.ueid_cnt) + rc = -ENOENT; + else + smc_clc_eid_table.seid_enabled = 0; + write_unlock(&smc_clc_eid_table.lock); ++#else ++ rc = -EOPNOTSUPP; ++#endif + return rc; + } + +@@ -1269,7 +1279,11 @@ void __init smc_clc_init(void) + INIT_LIST_HEAD(&smc_clc_eid_table.list); + rwlock_init(&smc_clc_eid_table.lock); + smc_clc_eid_table.ueid_cnt = 0; ++#if IS_ENABLED(CONFIG_S390) + smc_clc_eid_table.seid_enabled = 1; ++#else ++ smc_clc_eid_table.seid_enabled = 0; ++#endif + } + + void smc_clc_exit(void) +diff --git a/net/sunrpc/xprtmultipath.c b/net/sunrpc/xprtmultipath.c +index 74ee2271251e3..720d3ba742ec0 100644 +--- a/net/sunrpc/xprtmultipath.c ++++ b/net/sunrpc/xprtmultipath.c +@@ -336,8 +336,9 @@ struct rpc_xprt *xprt_iter_current_entry_offline(struct rpc_xprt_iter *xpi) + xprt_switch_find_current_entry_offline); + } + +-bool rpc_xprt_switch_has_addr(struct rpc_xprt_switch *xps, +- const struct sockaddr *sap) ++static ++bool __rpc_xprt_switch_has_addr(struct rpc_xprt_switch *xps, ++ const struct sockaddr *sap) + { + struct list_head *head; + struct rpc_xprt *pos; +@@ -356,6 +357,18 @@ bool rpc_xprt_switch_has_addr(struct rpc_xprt_switch *xps, + return false; + } + ++bool rpc_xprt_switch_has_addr(struct rpc_xprt_switch *xps, ++ const struct sockaddr *sap) ++{ ++ bool res; ++ ++ rcu_read_lock(); ++ res = __rpc_xprt_switch_has_addr(xps, sap); ++ rcu_read_unlock(); ++ ++ return res; ++} ++ + static + struct rpc_xprt *xprt_switch_find_next_entry(struct list_head *head, + const struct rpc_xprt *cur, bool check_active) +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index ac1f2bc18fc96..30b178ebba60a 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -1344,13 +1344,11 @@ static void unix_state_double_lock(struct sock *sk1, struct sock *sk2) + unix_state_lock(sk1); + return; + } +- if (sk1 < sk2) { +- unix_state_lock(sk1); +- unix_state_lock_nested(sk2); +- } else { +- unix_state_lock(sk2); +- unix_state_lock_nested(sk1); +- } ++ if (sk1 > sk2) ++ swap(sk1, sk2); ++ ++ unix_state_lock(sk1); ++ unix_state_lock_nested(sk2, U_LOCK_SECOND); + } + + static void unix_state_double_unlock(struct sock *sk1, struct sock *sk2) +@@ -1591,7 +1589,7 @@ restart: + goto out_unlock; + } + +- unix_state_lock_nested(sk); ++ unix_state_lock_nested(sk, U_LOCK_SECOND); + + if (sk->sk_state != st) { + unix_state_unlock(sk); +diff --git a/net/unix/diag.c b/net/unix/diag.c +index bec09a3a1d44c..be19827eca36d 100644 +--- a/net/unix/diag.c ++++ b/net/unix/diag.c +@@ -84,7 +84,7 @@ static int sk_diag_dump_icons(struct sock *sk, struct sk_buff *nlskb) + * queue lock. With the other's queue locked it's + * OK to lock the state. + */ +- unix_state_lock_nested(req); ++ unix_state_lock_nested(req, U_LOCK_DIAG); + peer = unix_sk(req)->peer; + buf[i++] = (peer ? sock_i_ino(peer) : 0); + unix_state_unlock(req); +diff --git a/net/wireless/scan.c b/net/wireless/scan.c +index 0d6c3fc1238ab..b9da6f5152cbc 100644 +--- a/net/wireless/scan.c ++++ b/net/wireless/scan.c +@@ -1864,8 +1864,12 @@ __cfg80211_bss_update(struct cfg80211_registered_device *rdev, + list_add(&new->hidden_list, + &hidden->hidden_list); + hidden->refcount++; ++ ++ ies = (void *)rcu_access_pointer(new->pub.beacon_ies); + rcu_assign_pointer(new->pub.beacon_ies, + hidden->pub.beacon_ies); ++ if (ies) ++ kfree_rcu(ies, rcu_head); + } + } else { + /* +diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c +index 6ce24e248f8e0..610ea7a33cd85 100644 +--- a/sound/hda/hdac_stream.c ++++ b/sound/hda/hdac_stream.c +@@ -671,17 +671,15 @@ void snd_hdac_stream_timecounter_init(struct hdac_stream *azx_dev, + struct hdac_stream *s; + bool inited = false; + u64 cycle_last = 0; +- int i = 0; + + list_for_each_entry(s, &bus->stream_list, list) { +- if (streams & (1 << i)) { ++ if ((streams & (1 << s->index))) { + azx_timecounter_init(s, inited, cycle_last); + if (!inited) { + inited = true; + cycle_last = s->tc.cycle_last; + } + } +- i++; + } + + snd_pcm_gettime(runtime, &runtime->trigger_tstamp); +@@ -726,14 +724,13 @@ void snd_hdac_stream_sync(struct hdac_stream *azx_dev, bool start, + unsigned int streams) + { + struct hdac_bus *bus = azx_dev->bus; +- int i, nwait, timeout; ++ int nwait, timeout; + struct hdac_stream *s; + + for (timeout = 5000; timeout; timeout--) { + nwait = 0; +- i = 0; + list_for_each_entry(s, &bus->stream_list, list) { +- if (!(streams & (1 << i++))) ++ if (!(streams & (1 << s->index))) + continue; + + if (start) { +diff --git a/sound/hda/intel-dsp-config.c b/sound/hda/intel-dsp-config.c +index 756fa0aa69bba..6a384b922e4fa 100644 +--- a/sound/hda/intel-dsp-config.c ++++ b/sound/hda/intel-dsp-config.c +@@ -521,6 +521,16 @@ static const struct config_entry config_table[] = { + .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, + .device = PCI_DEVICE_ID_INTEL_HDA_MTL, + }, ++ /* ArrowLake-S */ ++ { ++ .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, ++ .device = PCI_DEVICE_ID_INTEL_HDA_ARL_S, ++ }, ++ /* ArrowLake */ ++ { ++ .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, ++ .device = PCI_DEVICE_ID_INTEL_HDA_ARL, ++ }, + #endif + + /* Lunar Lake */ +diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c +index 2d1df3654424c..2276adc844784 100644 +--- a/sound/pci/hda/hda_intel.c ++++ b/sound/pci/hda/hda_intel.c +@@ -2504,6 +2504,8 @@ static const struct pci_device_id azx_ids[] = { + { PCI_DEVICE_DATA(INTEL, HDA_LNL_P, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) }, + /* Arrow Lake-S */ + { PCI_DEVICE_DATA(INTEL, HDA_ARL_S, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) }, ++ /* Arrow Lake */ ++ { PCI_DEVICE_DATA(INTEL, HDA_ARL, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) }, + /* Apollolake (Broxton-P) */ + { PCI_DEVICE_DATA(INTEL, HDA_APL, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_BROXTON) }, + /* Gemini-Lake */ +diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c +index a889cccdd607c..e8819e8a98763 100644 +--- a/sound/pci/hda/patch_conexant.c ++++ b/sound/pci/hda/patch_conexant.c +@@ -21,6 +21,12 @@ + #include "hda_jack.h" + #include "hda_generic.h" + ++enum { ++ CX_HEADSET_NOPRESENT = 0, ++ CX_HEADSET_PARTPRESENT, ++ CX_HEADSET_ALLPRESENT, ++}; ++ + struct conexant_spec { + struct hda_gen_spec gen; + +@@ -42,7 +48,8 @@ struct conexant_spec { + unsigned int gpio_led; + unsigned int gpio_mute_led_mask; + unsigned int gpio_mic_led_mask; +- ++ unsigned int headset_present_flag; ++ bool is_cx8070_sn6140; + }; + + +@@ -164,6 +171,27 @@ static void cxt_init_gpio_led(struct hda_codec *codec) + } + } + ++static void cx_fixup_headset_recog(struct hda_codec *codec) ++{ ++ unsigned int mic_persent; ++ ++ /* fix some headset type recognize fail issue, such as EDIFIER headset */ ++ /* set micbiasd output current comparator threshold from 66% to 55%. */ ++ snd_hda_codec_write(codec, 0x1c, 0, 0x320, 0x010); ++ /* set OFF voltage for DFET from -1.2V to -0.8V, set headset micbias registor ++ * value adjustment trim from 2.2K ohms to 2.0K ohms. ++ */ ++ snd_hda_codec_write(codec, 0x1c, 0, 0x3b0, 0xe10); ++ /* fix reboot headset type recognize fail issue */ ++ mic_persent = snd_hda_codec_read(codec, 0x19, 0, AC_VERB_GET_PIN_SENSE, 0x0); ++ if (mic_persent & AC_PINSENSE_PRESENCE) ++ /* enable headset mic VREF */ ++ snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24); ++ else ++ /* disable headset mic VREF */ ++ snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20); ++} ++ + static int cx_auto_init(struct hda_codec *codec) + { + struct conexant_spec *spec = codec->spec; +@@ -174,6 +202,9 @@ static int cx_auto_init(struct hda_codec *codec) + cxt_init_gpio_led(codec); + snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT); + ++ if (spec->is_cx8070_sn6140) ++ cx_fixup_headset_recog(codec); ++ + return 0; + } + +@@ -192,6 +223,77 @@ static void cx_auto_free(struct hda_codec *codec) + snd_hda_gen_free(codec); + } + ++static void cx_process_headset_plugin(struct hda_codec *codec) ++{ ++ unsigned int val; ++ unsigned int count = 0; ++ ++ /* Wait headset detect done. */ ++ do { ++ val = snd_hda_codec_read(codec, 0x1c, 0, 0xca0, 0x0); ++ if (val & 0x080) { ++ codec_dbg(codec, "headset type detect done!\n"); ++ break; ++ } ++ msleep(20); ++ count++; ++ } while (count < 3); ++ val = snd_hda_codec_read(codec, 0x1c, 0, 0xcb0, 0x0); ++ if (val & 0x800) { ++ codec_dbg(codec, "headset plugin, type is CTIA\n"); ++ snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24); ++ } else if (val & 0x400) { ++ codec_dbg(codec, "headset plugin, type is OMTP\n"); ++ snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24); ++ } else { ++ codec_dbg(codec, "headphone plugin\n"); ++ } ++} ++ ++static void cx_update_headset_mic_vref(struct hda_codec *codec, unsigned int res) ++{ ++ unsigned int phone_present, mic_persent, phone_tag, mic_tag; ++ struct conexant_spec *spec = codec->spec; ++ ++ /* In cx8070 and sn6140, the node 16 can only be config to headphone or disabled, ++ * the node 19 can only be config to microphone or disabled. ++ * Check hp&mic tag to process headset pulgin&plugout. ++ */ ++ phone_tag = snd_hda_codec_read(codec, 0x16, 0, AC_VERB_GET_UNSOLICITED_RESPONSE, 0x0); ++ mic_tag = snd_hda_codec_read(codec, 0x19, 0, AC_VERB_GET_UNSOLICITED_RESPONSE, 0x0); ++ if ((phone_tag & (res >> AC_UNSOL_RES_TAG_SHIFT)) || ++ (mic_tag & (res >> AC_UNSOL_RES_TAG_SHIFT))) { ++ phone_present = snd_hda_codec_read(codec, 0x16, 0, AC_VERB_GET_PIN_SENSE, 0x0); ++ if (!(phone_present & AC_PINSENSE_PRESENCE)) {/* headphone plugout */ ++ spec->headset_present_flag = CX_HEADSET_NOPRESENT; ++ snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20); ++ return; ++ } ++ if (spec->headset_present_flag == CX_HEADSET_NOPRESENT) { ++ spec->headset_present_flag = CX_HEADSET_PARTPRESENT; ++ } else if (spec->headset_present_flag == CX_HEADSET_PARTPRESENT) { ++ mic_persent = snd_hda_codec_read(codec, 0x19, 0, ++ AC_VERB_GET_PIN_SENSE, 0x0); ++ /* headset is present */ ++ if ((phone_present & AC_PINSENSE_PRESENCE) && ++ (mic_persent & AC_PINSENSE_PRESENCE)) { ++ cx_process_headset_plugin(codec); ++ spec->headset_present_flag = CX_HEADSET_ALLPRESENT; ++ } ++ } ++ } ++} ++ ++static void cx_jack_unsol_event(struct hda_codec *codec, unsigned int res) ++{ ++ struct conexant_spec *spec = codec->spec; ++ ++ if (spec->is_cx8070_sn6140) ++ cx_update_headset_mic_vref(codec, res); ++ ++ snd_hda_jack_unsol_event(codec, res); ++} ++ + #ifdef CONFIG_PM + static int cx_auto_suspend(struct hda_codec *codec) + { +@@ -205,7 +307,7 @@ static const struct hda_codec_ops cx_auto_patch_ops = { + .build_pcms = snd_hda_gen_build_pcms, + .init = cx_auto_init, + .free = cx_auto_free, +- .unsol_event = snd_hda_jack_unsol_event, ++ .unsol_event = cx_jack_unsol_event, + #ifdef CONFIG_PM + .suspend = cx_auto_suspend, + .check_power_status = snd_hda_gen_check_power_status, +@@ -1042,6 +1144,15 @@ static int patch_conexant_auto(struct hda_codec *codec) + codec->spec = spec; + codec->patch_ops = cx_auto_patch_ops; + ++ /* init cx8070/sn6140 flag and reset headset_present_flag */ ++ switch (codec->core.vendor_id) { ++ case 0x14f11f86: ++ case 0x14f11f87: ++ spec->is_cx8070_sn6140 = true; ++ spec->headset_present_flag = CX_HEADSET_NOPRESENT; ++ break; ++ } ++ + cx_auto_parse_eapd(codec); + spec->gen.own_eapd_ctl = 1; + +diff --git a/sound/soc/amd/acp-config.c b/sound/soc/amd/acp-config.c +index 3bc4b2e41650e..dea6d367b9e82 100644 +--- a/sound/soc/amd/acp-config.c ++++ b/sound/soc/amd/acp-config.c +@@ -3,7 +3,7 @@ + // This file is provided under a dual BSD/GPLv2 license. When using or + // redistributing this file, you may do so under either license. + // +-// Copyright(c) 2021 Advanced Micro Devices, Inc. ++// Copyright(c) 2021, 2023 Advanced Micro Devices, Inc. + // + // Authors: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com> + // +@@ -47,6 +47,19 @@ static const struct config_entry config_table[] = { + {} + }, + }, ++ { ++ .flags = FLAG_AMD_LEGACY, ++ .device = ACP_PCI_DEV_ID, ++ .dmi_table = (const struct dmi_system_id []) { ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Valve"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Jupiter"), ++ }, ++ }, ++ {} ++ }, ++ }, + { + .flags = FLAG_AMD_SOF, + .device = ACP_PCI_DEV_ID, +diff --git a/sound/soc/codecs/lpass-wsa-macro.c b/sound/soc/codecs/lpass-wsa-macro.c +index 7e21cec3c2fb9..6ce309980cd10 100644 +--- a/sound/soc/codecs/lpass-wsa-macro.c ++++ b/sound/soc/codecs/lpass-wsa-macro.c +@@ -1584,7 +1584,6 @@ static int wsa_macro_enable_interpolator(struct snd_soc_dapm_widget *w, + u16 gain_reg; + u16 reg; + int val; +- int offset_val = 0; + struct wsa_macro *wsa = snd_soc_component_get_drvdata(component); + + if (w->shift == WSA_MACRO_COMP1) { +@@ -1623,10 +1622,8 @@ static int wsa_macro_enable_interpolator(struct snd_soc_dapm_widget *w, + CDC_WSA_RX1_RX_PATH_MIX_SEC0, + CDC_WSA_RX_PGA_HALF_DB_MASK, + CDC_WSA_RX_PGA_HALF_DB_ENABLE); +- offset_val = -2; + } + val = snd_soc_component_read(component, gain_reg); +- val += offset_val; + snd_soc_component_write(component, gain_reg, val); + wsa_macro_config_ear_spkr_gain(component, wsa, + event, gain_reg); +@@ -1654,10 +1651,6 @@ static int wsa_macro_enable_interpolator(struct snd_soc_dapm_widget *w, + CDC_WSA_RX1_RX_PATH_MIX_SEC0, + CDC_WSA_RX_PGA_HALF_DB_MASK, + CDC_WSA_RX_PGA_HALF_DB_DISABLE); +- offset_val = 2; +- val = snd_soc_component_read(component, gain_reg); +- val += offset_val; +- snd_soc_component_write(component, gain_reg, val); + } + wsa_macro_config_ear_spkr_gain(component, wsa, + event, gain_reg); +diff --git a/sound/soc/codecs/rtq9128.c b/sound/soc/codecs/rtq9128.c +index c22b047115cc4..aa3eadecd9746 100644 +--- a/sound/soc/codecs/rtq9128.c ++++ b/sound/soc/codecs/rtq9128.c +@@ -59,6 +59,7 @@ + + struct rtq9128_data { + struct gpio_desc *enable; ++ unsigned int daifmt; + int tdm_slots; + int tdm_slot_width; + bool tdm_input_data2_select; +@@ -391,7 +392,11 @@ static int rtq9128_component_probe(struct snd_soc_component *comp) + unsigned int val; + int i, ret; + +- pm_runtime_resume_and_get(comp->dev); ++ ret = pm_runtime_resume_and_get(comp->dev); ++ if (ret < 0) { ++ dev_err(comp->dev, "Failed to resume device (%d)\n", ret); ++ return ret; ++ } + + val = snd_soc_component_read(comp, RTQ9128_REG_EFUSE_DATA); + +@@ -437,10 +442,7 @@ static const struct snd_soc_component_driver rtq9128_comp_driver = { + static int rtq9128_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) + { + struct rtq9128_data *data = snd_soc_dai_get_drvdata(dai); +- struct snd_soc_component *comp = dai->component; + struct device *dev = dai->dev; +- unsigned int audfmt, fmtval; +- int ret; + + dev_dbg(dev, "%s: fmt 0x%8x\n", __func__, fmt); + +@@ -450,35 +452,10 @@ static int rtq9128_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) + return -EINVAL; + } + +- fmtval = fmt & SND_SOC_DAIFMT_FORMAT_MASK; +- if (data->tdm_slots && fmtval != SND_SOC_DAIFMT_DSP_A && fmtval != SND_SOC_DAIFMT_DSP_B) { +- dev_err(dev, "TDM is used, format only support DSP_A or DSP_B\n"); +- return -EINVAL; +- } ++ /* Store here and will be used in runtime hw_params for DAI format setting */ ++ data->daifmt = fmt; + +- switch (fmtval) { +- case SND_SOC_DAIFMT_I2S: +- audfmt = 8; +- break; +- case SND_SOC_DAIFMT_LEFT_J: +- audfmt = 9; +- break; +- case SND_SOC_DAIFMT_RIGHT_J: +- audfmt = 10; +- break; +- case SND_SOC_DAIFMT_DSP_A: +- audfmt = data->tdm_slots ? 12 : 11; +- break; +- case SND_SOC_DAIFMT_DSP_B: +- audfmt = data->tdm_slots ? 4 : 3; +- break; +- default: +- dev_err(dev, "Unsupported format 0x%8x\n", fmt); +- return -EINVAL; +- } +- +- ret = snd_soc_component_write_field(comp, RTQ9128_REG_I2S_OPT, RTQ9128_AUDFMT_MASK, audfmt); +- return ret < 0 ? ret : 0; ++ return 0; + } + + static int rtq9128_dai_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, +@@ -554,10 +531,38 @@ static int rtq9128_dai_hw_params(struct snd_pcm_substream *stream, struct snd_pc + unsigned int width, slot_width, bitrate, audbit, dolen; + struct snd_soc_component *comp = dai->component; + struct device *dev = dai->dev; ++ unsigned int fmtval, audfmt; + int ret; + + dev_dbg(dev, "%s: width %d\n", __func__, params_width(param)); + ++ fmtval = FIELD_GET(SND_SOC_DAIFMT_FORMAT_MASK, data->daifmt); ++ if (data->tdm_slots && fmtval != SND_SOC_DAIFMT_DSP_A && fmtval != SND_SOC_DAIFMT_DSP_B) { ++ dev_err(dev, "TDM is used, format only support DSP_A or DSP_B\n"); ++ return -EINVAL; ++ } ++ ++ switch (fmtval) { ++ case SND_SOC_DAIFMT_I2S: ++ audfmt = 8; ++ break; ++ case SND_SOC_DAIFMT_LEFT_J: ++ audfmt = 9; ++ break; ++ case SND_SOC_DAIFMT_RIGHT_J: ++ audfmt = 10; ++ break; ++ case SND_SOC_DAIFMT_DSP_A: ++ audfmt = data->tdm_slots ? 12 : 11; ++ break; ++ case SND_SOC_DAIFMT_DSP_B: ++ audfmt = data->tdm_slots ? 4 : 3; ++ break; ++ default: ++ dev_err(dev, "Unsupported format 0x%8x\n", fmtval); ++ return -EINVAL; ++ } ++ + switch (width = params_width(param)) { + case 16: + audbit = 0; +@@ -611,6 +616,10 @@ static int rtq9128_dai_hw_params(struct snd_pcm_substream *stream, struct snd_pc + return -EINVAL; + } + ++ ret = snd_soc_component_write_field(comp, RTQ9128_REG_I2S_OPT, RTQ9128_AUDFMT_MASK, audfmt); ++ if (ret < 0) ++ return ret; ++ + ret = snd_soc_component_write_field(comp, RTQ9128_REG_I2S_OPT, RTQ9128_AUDBIT_MASK, audbit); + if (ret < 0) + return ret; +diff --git a/sound/soc/codecs/wcd938x.c b/sound/soc/codecs/wcd938x.c +index faf8d3f9b3c5d..98055dd39b782 100644 +--- a/sound/soc/codecs/wcd938x.c ++++ b/sound/soc/codecs/wcd938x.c +@@ -210,7 +210,7 @@ struct wcd938x_priv { + }; + + static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(ear_pa_gain, 600, -1800); +-static const DECLARE_TLV_DB_SCALE(line_gain, -3000, 150, -3000); ++static const DECLARE_TLV_DB_SCALE(line_gain, -3000, 150, 0); + static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(analog_gain, 0, 3000); + + struct wcd938x_mbhc_zdet_param { +diff --git a/sound/soc/codecs/wsa883x.c b/sound/soc/codecs/wsa883x.c +index cb83c569e18d6..a2e86ef7d18f5 100644 +--- a/sound/soc/codecs/wsa883x.c ++++ b/sound/soc/codecs/wsa883x.c +@@ -1098,7 +1098,11 @@ static int wsa_dev_mode_put(struct snd_kcontrol *kcontrol, + return 1; + } + +-static const DECLARE_TLV_DB_SCALE(pa_gain, -300, 150, -300); ++static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(pa_gain, ++ 0, 14, TLV_DB_SCALE_ITEM(-300, 0, 0), ++ 15, 29, TLV_DB_SCALE_ITEM(-300, 150, 0), ++ 30, 31, TLV_DB_SCALE_ITEM(1800, 0, 0), ++); + + static int wsa883x_get_swr_port(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +diff --git a/sound/soc/qcom/sc8280xp.c b/sound/soc/qcom/sc8280xp.c +index 39cb0b889aff9..e6efc2d10bbef 100644 +--- a/sound/soc/qcom/sc8280xp.c ++++ b/sound/soc/qcom/sc8280xp.c +@@ -34,12 +34,14 @@ static int sc8280xp_snd_init(struct snd_soc_pcm_runtime *rtd) + case WSA_CODEC_DMA_RX_0: + case WSA_CODEC_DMA_RX_1: + /* +- * set limit of 0dB on Digital Volume for Speakers, +- * this can prevent damage of speakers to some extent without +- * active speaker protection ++ * Set limit of -3 dB on Digital Volume and 0 dB on PA Volume ++ * to reduce the risk of speaker damage until we have active ++ * speaker protection in place. + */ +- snd_soc_limit_volume(card, "WSA_RX0 Digital Volume", 84); +- snd_soc_limit_volume(card, "WSA_RX1 Digital Volume", 84); ++ snd_soc_limit_volume(card, "WSA_RX0 Digital Volume", 81); ++ snd_soc_limit_volume(card, "WSA_RX1 Digital Volume", 81); ++ snd_soc_limit_volume(card, "SpkrLeft PA Volume", 17); ++ snd_soc_limit_volume(card, "SpkrRight PA Volume", 17); + break; + default: + break; +diff --git a/tools/build/feature/test-libopencsd.c b/tools/build/feature/test-libopencsd.c +index eb6303ff446ed..4cfcef9da3e43 100644 +--- a/tools/build/feature/test-libopencsd.c ++++ b/tools/build/feature/test-libopencsd.c +@@ -4,9 +4,9 @@ + /* + * Check OpenCSD library version is sufficient to provide required features + */ +-#define OCSD_MIN_VER ((1 << 16) | (1 << 8) | (1)) ++#define OCSD_MIN_VER ((1 << 16) | (2 << 8) | (1)) + #if !defined(OCSD_VER_NUM) || (OCSD_VER_NUM < OCSD_MIN_VER) +-#error "OpenCSD >= 1.1.1 is required" ++#error "OpenCSD >= 1.2.1 is required" + #endif + + int main(void) +diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c +index e067be95da3c0..df1b550f7460a 100644 +--- a/tools/lib/bpf/libbpf.c ++++ b/tools/lib/bpf/libbpf.c +@@ -4344,6 +4344,8 @@ bpf_object__collect_prog_relos(struct bpf_object *obj, Elf64_Shdr *shdr, Elf_Dat + + scn = elf_sec_by_idx(obj, sec_idx); + scn_data = elf_sec_data(obj, scn); ++ if (!scn_data) ++ return -LIBBPF_ERRNO__FORMAT; + + relo_sec_name = elf_sec_str(obj, shdr->sh_name); + sec_name = elf_sec_name(obj, scn); +diff --git a/tools/lib/bpf/libbpf_common.h b/tools/lib/bpf/libbpf_common.h +index b7060f2544861..8fe248e14eb63 100644 +--- a/tools/lib/bpf/libbpf_common.h ++++ b/tools/lib/bpf/libbpf_common.h +@@ -79,11 +79,14 @@ + */ + #define LIBBPF_OPTS_RESET(NAME, ...) \ + do { \ +- memset(&NAME, 0, sizeof(NAME)); \ +- NAME = (typeof(NAME)) { \ +- .sz = sizeof(NAME), \ +- __VA_ARGS__ \ +- }; \ ++ typeof(NAME) ___##NAME = ({ \ ++ memset(&___##NAME, 0, sizeof(NAME)); \ ++ (typeof(NAME)) { \ ++ .sz = sizeof(NAME), \ ++ __VA_ARGS__ \ ++ }; \ ++ }); \ ++ memcpy(&NAME, &___##NAME, sizeof(NAME)); \ + } while (0) + + #endif /* __LIBBPF_LIBBPF_COMMON_H */ +diff --git a/tools/lib/subcmd/help.c b/tools/lib/subcmd/help.c +index adfbae27dc369..8561b0f01a247 100644 +--- a/tools/lib/subcmd/help.c ++++ b/tools/lib/subcmd/help.c +@@ -52,11 +52,21 @@ void uniq(struct cmdnames *cmds) + if (!cmds->cnt) + return; + +- for (i = j = 1; i < cmds->cnt; i++) +- if (strcmp(cmds->names[i]->name, cmds->names[i-1]->name)) +- cmds->names[j++] = cmds->names[i]; +- ++ for (i = 1; i < cmds->cnt; i++) { ++ if (!strcmp(cmds->names[i]->name, cmds->names[i-1]->name)) ++ zfree(&cmds->names[i - 1]); ++ } ++ for (i = 0, j = 0; i < cmds->cnt; i++) { ++ if (cmds->names[i]) { ++ if (i == j) ++ j++; ++ else ++ cmds->names[j++] = cmds->names[i]; ++ } ++ } + cmds->cnt = j; ++ while (j < i) ++ cmds->names[j++] = NULL; + } + + void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes) +diff --git a/tools/testing/kunit/kunit_parser.py b/tools/testing/kunit/kunit_parser.py +index 79d8832c862aa..ce34be15c929e 100644 +--- a/tools/testing/kunit/kunit_parser.py ++++ b/tools/testing/kunit/kunit_parser.py +@@ -450,7 +450,7 @@ def parse_diagnostic(lines: LineStream) -> List[str]: + Log of diagnostic lines + """ + log = [] # type: List[str] +- non_diagnostic_lines = [TEST_RESULT, TEST_HEADER, KTAP_START, TAP_START] ++ non_diagnostic_lines = [TEST_RESULT, TEST_HEADER, KTAP_START, TAP_START, TEST_PLAN] + while lines and not any(re.match(lines.peek()) + for re in non_diagnostic_lines): + log.append(lines.pop()) +@@ -726,6 +726,7 @@ def parse_test(lines: LineStream, expected_num: int, log: List[str], is_subtest: + # test plan + test.name = "main" + ktap_line = parse_ktap_header(lines, test) ++ test.log.extend(parse_diagnostic(lines)) + parse_test_plan(lines, test) + parent_test = True + else: +@@ -737,6 +738,7 @@ def parse_test(lines: LineStream, expected_num: int, log: List[str], is_subtest: + if parent_test: + # If KTAP version line and/or subtest header is found, attempt + # to parse test plan and print test header ++ test.log.extend(parse_diagnostic(lines)) + parse_test_plan(lines, test) + print_test_header(test) + expected_count = test.expected_count +diff --git a/tools/testing/selftests/bpf/cgroup_helpers.c b/tools/testing/selftests/bpf/cgroup_helpers.c +index 5b1da2a32ea72..10b5f42e65e78 100644 +--- a/tools/testing/selftests/bpf/cgroup_helpers.c ++++ b/tools/testing/selftests/bpf/cgroup_helpers.c +@@ -523,10 +523,20 @@ int setup_classid_environment(void) + return 1; + } + +- if (mount("net_cls", NETCLS_MOUNT_PATH, "cgroup", 0, "net_cls") && +- errno != EBUSY) { +- log_err("mount cgroup net_cls"); +- return 1; ++ if (mount("net_cls", NETCLS_MOUNT_PATH, "cgroup", 0, "net_cls")) { ++ if (errno != EBUSY) { ++ log_err("mount cgroup net_cls"); ++ return 1; ++ } ++ ++ if (rmdir(NETCLS_MOUNT_PATH)) { ++ log_err("rmdir cgroup net_cls"); ++ return 1; ++ } ++ if (umount(CGROUP_MOUNT_DFLT)) { ++ log_err("umount cgroup base"); ++ return 1; ++ } + } + + cleanup_classid_environment(); +diff --git a/tools/testing/selftests/bpf/prog_tests/btf.c b/tools/testing/selftests/bpf/prog_tests/btf.c +index 92d51f377fe59..816145bcb6476 100644 +--- a/tools/testing/selftests/bpf/prog_tests/btf.c ++++ b/tools/testing/selftests/bpf/prog_tests/btf.c +@@ -4630,11 +4630,6 @@ static int test_btf_id(unsigned int test_num) + /* The map holds the last ref to BTF and its btf_id */ + close(map_fd); + map_fd = -1; +- btf_fd[0] = bpf_btf_get_fd_by_id(map_info.btf_id); +- if (CHECK(btf_fd[0] >= 0, "BTF lingers")) { +- err = -1; +- goto done; +- } + + fprintf(stderr, "OK"); + +@@ -5265,6 +5260,7 @@ static size_t get_pprint_mapv_size(enum pprint_mapv_kind_t mapv_kind) + #endif + + assert(0); ++ return 0; + } + + static void set_pprint_mapv(enum pprint_mapv_kind_t mapv_kind, +diff --git a/tools/testing/selftests/bpf/prog_tests/tc_opts.c b/tools/testing/selftests/bpf/prog_tests/tc_opts.c +index 51883ccb80206..196abf2234656 100644 +--- a/tools/testing/selftests/bpf/prog_tests/tc_opts.c ++++ b/tools/testing/selftests/bpf/prog_tests/tc_opts.c +@@ -2387,12 +2387,9 @@ static int generate_dummy_prog(void) + const size_t prog_insn_cnt = sizeof(prog_insns) / sizeof(struct bpf_insn); + LIBBPF_OPTS(bpf_prog_load_opts, opts); + const size_t log_buf_sz = 256; +- char *log_buf; ++ char log_buf[log_buf_sz]; + int fd = -1; + +- log_buf = malloc(log_buf_sz); +- if (!ASSERT_OK_PTR(log_buf, "log_buf_alloc")) +- return fd; + opts.log_buf = log_buf; + opts.log_size = log_buf_sz; + +@@ -2402,7 +2399,6 @@ static int generate_dummy_prog(void) + prog_insns, prog_insn_cnt, &opts); + ASSERT_STREQ(log_buf, "", "log_0"); + ASSERT_GE(fd, 0, "prog_fd"); +- free(log_buf); + return fd; + } + +diff --git a/tools/testing/selftests/bpf/progs/pyperf180.c b/tools/testing/selftests/bpf/progs/pyperf180.c +index c39f559d3100e..42c4a8b62e360 100644 +--- a/tools/testing/selftests/bpf/progs/pyperf180.c ++++ b/tools/testing/selftests/bpf/progs/pyperf180.c +@@ -1,4 +1,26 @@ + // SPDX-License-Identifier: GPL-2.0 + // Copyright (c) 2019 Facebook + #define STACK_MAX_LEN 180 ++ ++/* llvm upstream commit at clang18 ++ * https://github.com/llvm/llvm-project/commit/1a2e77cf9e11dbf56b5720c607313a566eebb16e ++ * changed inlining behavior and caused compilation failure as some branch ++ * target distance exceeded 16bit representation which is the maximum for ++ * cpu v1/v2/v3. Macro __BPF_CPU_VERSION__ is later implemented in clang18 ++ * to specify which cpu version is used for compilation. So a smaller ++ * unroll_count can be set if __BPF_CPU_VERSION__ is less than 4, which ++ * reduced some branch target distances and resolved the compilation failure. ++ * ++ * To capture the case where a developer/ci uses clang18 but the corresponding ++ * repo checkpoint does not have __BPF_CPU_VERSION__, a smaller unroll_count ++ * will be set as well to prevent potential compilation failures. ++ */ ++#ifdef __BPF_CPU_VERSION__ ++#if __BPF_CPU_VERSION__ < 4 ++#define UNROLL_COUNT 90 ++#endif ++#elif __clang_major__ == 18 ++#define UNROLL_COUNT 90 ++#endif ++ + #include "pyperf.h" +diff --git a/tools/testing/selftests/bpf/progs/test_global_func17.c b/tools/testing/selftests/bpf/progs/test_global_func17.c +index a32e11c7d933e..5de44b09e8ec1 100644 +--- a/tools/testing/selftests/bpf/progs/test_global_func17.c ++++ b/tools/testing/selftests/bpf/progs/test_global_func17.c +@@ -5,6 +5,7 @@ + + __noinline int foo(int *p) + { ++ barrier_var(p); + return p ? (*p = 42) : 0; + } + +diff --git a/tools/testing/selftests/bpf/veristat.c b/tools/testing/selftests/bpf/veristat.c +index 655095810d4a1..0ad98b6a8e6ef 100644 +--- a/tools/testing/selftests/bpf/veristat.c ++++ b/tools/testing/selftests/bpf/veristat.c +@@ -1214,7 +1214,7 @@ static int cmp_join_stat(const struct verif_stats_join *s1, + enum stat_id id, enum stat_variant var, bool asc) + { + const char *str1 = NULL, *str2 = NULL; +- double v1, v2; ++ double v1 = 0.0, v2 = 0.0; + int cmp = 0; + + fetch_join_stat_value(s1, id, var, &str1, &v1); +diff --git a/tools/testing/selftests/bpf/xdp_hw_metadata.c b/tools/testing/selftests/bpf/xdp_hw_metadata.c +index c3ba40d0b9de4..c5e7937d7f631 100644 +--- a/tools/testing/selftests/bpf/xdp_hw_metadata.c ++++ b/tools/testing/selftests/bpf/xdp_hw_metadata.c +@@ -70,7 +70,7 @@ static int open_xsk(int ifindex, struct xsk *xsk, __u32 queue_id) + .frame_size = XSK_UMEM__DEFAULT_FRAME_SIZE, + .flags = XDP_UMEM_UNALIGNED_CHUNK_FLAG, + }; +- __u32 idx; ++ __u32 idx = 0; + u64 addr; + int ret; + int i; +diff --git a/tools/testing/selftests/drivers/net/bonding/lag_lib.sh b/tools/testing/selftests/drivers/net/bonding/lag_lib.sh +index 2a268b17b61f5..dbdd736a41d39 100644 +--- a/tools/testing/selftests/drivers/net/bonding/lag_lib.sh ++++ b/tools/testing/selftests/drivers/net/bonding/lag_lib.sh +@@ -48,6 +48,17 @@ test_LAG_cleanup() + ip link add mv0 link "$name" up address "$ucaddr" type macvlan + # Used to test dev->mc handling + ip address add "$addr6" dev "$name" ++ ++ # Check that addresses were added as expected ++ (grep_bridge_fdb "$ucaddr" bridge fdb show dev dummy1 || ++ grep_bridge_fdb "$ucaddr" bridge fdb show dev dummy2) >/dev/null ++ check_err $? "macvlan unicast address not found on a slave" ++ ++ # mcaddr is added asynchronously by addrconf_dad_work(), use busywait ++ (busywait 10000 grep_bridge_fdb "$mcaddr" bridge fdb show dev dummy1 || ++ grep_bridge_fdb "$mcaddr" bridge fdb show dev dummy2) >/dev/null ++ check_err $? "IPv6 solicited-node multicast mac address not found on a slave" ++ + ip link set dev "$name" down + ip link del "$name" + +diff --git a/tools/testing/selftests/drivers/net/team/config b/tools/testing/selftests/drivers/net/team/config +index 265b6882cc21e..b5e3a3aad4bfb 100644 +--- a/tools/testing/selftests/drivers/net/team/config ++++ b/tools/testing/selftests/drivers/net/team/config +@@ -1,3 +1,5 @@ ++CONFIG_DUMMY=y ++CONFIG_IPV6=y ++CONFIG_MACVLAN=y + CONFIG_NET_TEAM=y + CONFIG_NET_TEAM_MODE_LOADBALANCE=y +-CONFIG_MACVLAN=y +diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile +index 9e5bf59a20bff..c1ae90c785654 100644 +--- a/tools/testing/selftests/net/Makefile ++++ b/tools/testing/selftests/net/Makefile +@@ -84,6 +84,7 @@ TEST_PROGS += sctp_vrf.sh + TEST_GEN_FILES += sctp_hello + TEST_GEN_FILES += csum + TEST_GEN_FILES += nat6to4.o ++TEST_GEN_FILES += xdp_dummy.o + TEST_GEN_FILES += ip_local_port_range + TEST_GEN_FILES += bind_wildcard + TEST_PROGS += test_vxlan_mdb.sh +@@ -103,7 +104,7 @@ $(OUTPUT)/tcp_inq: LDLIBS += -lpthread + $(OUTPUT)/bind_bhash: LDLIBS += -lpthread + $(OUTPUT)/io_uring_zerocopy_tx: CFLAGS += -I../../../include/ + +-# Rules to generate bpf obj nat6to4.o ++# Rules to generate bpf objs + CLANG ?= clang + SCRATCH_DIR := $(OUTPUT)/tools + BUILD_DIR := $(SCRATCH_DIR)/build +@@ -138,7 +139,7 @@ endif + + CLANG_SYS_INCLUDES = $(call get_sys_includes,$(CLANG),$(CLANG_TARGET_ARCH)) + +-$(OUTPUT)/nat6to4.o: nat6to4.c $(BPFOBJ) | $(MAKE_DIRS) ++$(OUTPUT)/nat6to4.o $(OUTPUT)/xdp_dummy.o: $(OUTPUT)/%.o : %.c $(BPFOBJ) | $(MAKE_DIRS) + $(CLANG) -O2 --target=bpf -c $< $(CCINCLUDE) $(CLANG_SYS_INCLUDES) -o $@ + + $(BPFOBJ): $(wildcard $(BPFDIR)/*.[ch] $(BPFDIR)/Makefile) \ +diff --git a/tools/testing/selftests/net/config b/tools/testing/selftests/net/config +index 19ff750516609..3b749addd3640 100644 +--- a/tools/testing/selftests/net/config ++++ b/tools/testing/selftests/net/config +@@ -19,8 +19,11 @@ CONFIG_BRIDGE_VLAN_FILTERING=y + CONFIG_BRIDGE=y + CONFIG_CRYPTO_CHACHA20POLY1305=m + CONFIG_VLAN_8021Q=y ++CONFIG_GENEVE=m + CONFIG_IFB=y + CONFIG_INET_DIAG=y ++CONFIG_INET_ESP=y ++CONFIG_INET_ESP_OFFLOAD=y + CONFIG_IP_GRE=m + CONFIG_NETFILTER=y + CONFIG_NETFILTER_ADVANCED=y +@@ -29,7 +32,10 @@ CONFIG_NF_NAT=m + CONFIG_IP6_NF_IPTABLES=m + CONFIG_IP_NF_IPTABLES=m + CONFIG_IP6_NF_NAT=m ++CONFIG_IP6_NF_RAW=m + CONFIG_IP_NF_NAT=m ++CONFIG_IP_NF_RAW=m ++CONFIG_IP_NF_TARGET_TTL=m + CONFIG_IPV6_GRE=m + CONFIG_IPV6_SEG6_LWTUNNEL=y + CONFIG_L2TP_ETH=m +@@ -45,8 +51,14 @@ CONFIG_NF_TABLES=m + CONFIG_NF_TABLES_IPV6=y + CONFIG_NF_TABLES_IPV4=y + CONFIG_NFT_NAT=m ++CONFIG_NETFILTER_XT_MATCH_LENGTH=m ++CONFIG_NET_ACT_CSUM=m ++CONFIG_NET_ACT_CT=m + CONFIG_NET_ACT_GACT=m ++CONFIG_NET_ACT_PEDIT=m + CONFIG_NET_CLS_BASIC=m ++CONFIG_NET_CLS_BPF=m ++CONFIG_NET_CLS_MATCHALL=m + CONFIG_NET_CLS_U32=m + CONFIG_NET_IPGRE_DEMUX=m + CONFIG_NET_IPGRE=m +@@ -55,6 +67,9 @@ CONFIG_NET_SCH_HTB=m + CONFIG_NET_SCH_FQ=m + CONFIG_NET_SCH_ETF=m + CONFIG_NET_SCH_NETEM=y ++CONFIG_NET_SCH_PRIO=m ++CONFIG_NFT_COMPAT=m ++CONFIG_NF_FLOW_TABLE=m + CONFIG_PSAMPLE=m + CONFIG_TCP_MD5SIG=y + CONFIG_TEST_BLACKHOLE_DEV=m +@@ -80,3 +95,4 @@ CONFIG_IP_SCTP=m + CONFIG_NETFILTER_XT_MATCH_POLICY=m + CONFIG_CRYPTO_ARIA=y + CONFIG_XFRM_INTERFACE=m ++CONFIG_XFRM_USER=m +diff --git a/tools/testing/selftests/net/pmtu.sh b/tools/testing/selftests/net/pmtu.sh +index b3b2dc5a630cf..4a5f031be2324 100755 +--- a/tools/testing/selftests/net/pmtu.sh ++++ b/tools/testing/selftests/net/pmtu.sh +@@ -714,23 +714,23 @@ setup_xfrm6() { + } + + setup_xfrm4udp() { +- setup_xfrm 4 ${veth4_a_addr} ${veth4_b_addr} "encap espinudp 4500 4500 0.0.0.0" +- setup_nettest_xfrm 4 4500 ++ setup_xfrm 4 ${veth4_a_addr} ${veth4_b_addr} "encap espinudp 4500 4500 0.0.0.0" && \ ++ setup_nettest_xfrm 4 4500 + } + + setup_xfrm6udp() { +- setup_xfrm 6 ${veth6_a_addr} ${veth6_b_addr} "encap espinudp 4500 4500 0.0.0.0" +- setup_nettest_xfrm 6 4500 ++ setup_xfrm 6 ${veth6_a_addr} ${veth6_b_addr} "encap espinudp 4500 4500 0.0.0.0" && \ ++ setup_nettest_xfrm 6 4500 + } + + setup_xfrm4udprouted() { +- setup_xfrm 4 ${prefix4}.${a_r1}.1 ${prefix4}.${b_r1}.1 "encap espinudp 4500 4500 0.0.0.0" +- setup_nettest_xfrm 4 4500 ++ setup_xfrm 4 ${prefix4}.${a_r1}.1 ${prefix4}.${b_r1}.1 "encap espinudp 4500 4500 0.0.0.0" && \ ++ setup_nettest_xfrm 4 4500 + } + + setup_xfrm6udprouted() { +- setup_xfrm 6 ${prefix6}:${a_r1}::1 ${prefix6}:${b_r1}::1 "encap espinudp 4500 4500 0.0.0.0" +- setup_nettest_xfrm 6 4500 ++ setup_xfrm 6 ${prefix6}:${a_r1}::1 ${prefix6}:${b_r1}::1 "encap espinudp 4500 4500 0.0.0.0" && \ ++ setup_nettest_xfrm 6 4500 + } + + setup_routing_old() { +@@ -1348,7 +1348,7 @@ test_pmtu_ipvX_over_bridged_vxlanY_or_geneveY_exception() { + + sleep 1 + +- dd if=/dev/zero of=/dev/stdout status=none bs=1M count=1 | ${target} socat -T 3 -u STDIN $TCPDST,connect-timeout=3 ++ dd if=/dev/zero status=none bs=1M count=1 | ${target} socat -T 3 -u STDIN $TCPDST,connect-timeout=3 + + size=$(du -sb $tmpoutfile) + size=${size%%/tmp/*} +diff --git a/tools/testing/selftests/net/setup_veth.sh b/tools/testing/selftests/net/setup_veth.sh +index 1003ddf7b3b26..227fd1076f213 100644 +--- a/tools/testing/selftests/net/setup_veth.sh ++++ b/tools/testing/selftests/net/setup_veth.sh +@@ -8,7 +8,7 @@ setup_veth_ns() { + local -r ns_mac="$4" + + [[ -e /var/run/netns/"${ns_name}" ]] || ip netns add "${ns_name}" +- echo 100000 > "/sys/class/net/${ns_dev}/gro_flush_timeout" ++ echo 1000000 > "/sys/class/net/${ns_dev}/gro_flush_timeout" + ip link set dev "${ns_dev}" netns "${ns_name}" mtu 65535 + ip -netns "${ns_name}" link set dev "${ns_dev}" up + +diff --git a/tools/testing/selftests/net/udpgro.sh b/tools/testing/selftests/net/udpgro.sh +index 0c743752669af..3f09ac78f4452 100755 +--- a/tools/testing/selftests/net/udpgro.sh ++++ b/tools/testing/selftests/net/udpgro.sh +@@ -5,7 +5,7 @@ + + readonly PEER_NS="ns-peer-$(mktemp -u XXXXXX)" + +-BPF_FILE="../bpf/xdp_dummy.bpf.o" ++BPF_FILE="xdp_dummy.o" + + # set global exit status, but never reset nonzero one. + check_err() +@@ -198,7 +198,7 @@ run_all() { + } + + if [ ! -f ${BPF_FILE} ]; then +- echo "Missing ${BPF_FILE}. Build bpf selftest first" ++ echo "Missing ${BPF_FILE}. Run 'make' first" + exit -1 + fi + +diff --git a/tools/testing/selftests/net/udpgro_bench.sh b/tools/testing/selftests/net/udpgro_bench.sh +index 894972877e8b0..65ff1d4240086 100755 +--- a/tools/testing/selftests/net/udpgro_bench.sh ++++ b/tools/testing/selftests/net/udpgro_bench.sh +@@ -5,7 +5,7 @@ + + readonly PEER_NS="ns-peer-$(mktemp -u XXXXXX)" + +-BPF_FILE="../bpf/xdp_dummy.bpf.o" ++BPF_FILE="xdp_dummy.o" + + cleanup() { + local -r jobs="$(jobs -p)" +@@ -83,7 +83,7 @@ run_all() { + } + + if [ ! -f ${BPF_FILE} ]; then +- echo "Missing ${BPF_FILE}. Build bpf selftest first" ++ echo "Missing ${BPF_FILE}. Run 'make' first" + exit -1 + fi + +diff --git a/tools/testing/selftests/net/udpgro_frglist.sh b/tools/testing/selftests/net/udpgro_frglist.sh +index 0a6359bed0b92..bd51d386b52eb 100755 +--- a/tools/testing/selftests/net/udpgro_frglist.sh ++++ b/tools/testing/selftests/net/udpgro_frglist.sh +@@ -5,7 +5,7 @@ + + readonly PEER_NS="ns-peer-$(mktemp -u XXXXXX)" + +-BPF_FILE="../bpf/xdp_dummy.bpf.o" ++BPF_FILE="xdp_dummy.o" + + cleanup() { + local -r jobs="$(jobs -p)" +@@ -84,12 +84,12 @@ run_all() { + } + + if [ ! -f ${BPF_FILE} ]; then +- echo "Missing ${BPF_FILE}. Build bpf selftest first" ++ echo "Missing ${BPF_FILE}. Run 'make' first" + exit -1 + fi + + if [ ! -f nat6to4.o ]; then +- echo "Missing nat6to4 helper. Build bpf nat6to4.o selftest first" ++ echo "Missing nat6to4 helper. Run 'make' first" + exit -1 + fi + +diff --git a/tools/testing/selftests/net/udpgro_fwd.sh b/tools/testing/selftests/net/udpgro_fwd.sh +index c079565add392..d6b9c759043ca 100755 +--- a/tools/testing/selftests/net/udpgro_fwd.sh ++++ b/tools/testing/selftests/net/udpgro_fwd.sh +@@ -1,7 +1,9 @@ + #!/bin/bash + # SPDX-License-Identifier: GPL-2.0 + +-BPF_FILE="../bpf/xdp_dummy.bpf.o" ++source net_helper.sh ++ ++BPF_FILE="xdp_dummy.o" + readonly BASE="ns-$(mktemp -u XXXXXX)" + readonly SRC=2 + readonly DST=1 +@@ -119,7 +121,7 @@ run_test() { + ip netns exec $NS_DST $ipt -A INPUT -p udp --dport 8000 + ip netns exec $NS_DST ./udpgso_bench_rx -C 1000 -R 10 -n 10 -l 1300 $rx_args & + local spid=$! +- sleep 0.1 ++ wait_local_port_listen "$NS_DST" 8000 udp + ip netns exec $NS_SRC ./udpgso_bench_tx $family -M 1 -s 13000 -S 1300 -D $dst + local retc=$? + wait $spid +@@ -168,7 +170,7 @@ run_bench() { + ip netns exec $NS_DST bash -c "echo 2 > /sys/class/net/veth$DST/queues/rx-0/rps_cpus" + ip netns exec $NS_DST taskset 0x2 ./udpgso_bench_rx -C 1000 -R 10 & + local spid=$! +- sleep 0.1 ++ wait_local_port_listen "$NS_DST" 8000 udp + ip netns exec $NS_SRC taskset 0x1 ./udpgso_bench_tx $family -l 3 -S 1300 -D $dst + local retc=$? + wait $spid +diff --git a/tools/testing/selftests/net/veth.sh b/tools/testing/selftests/net/veth.sh +index 2d073595c6202..27574bbf2d638 100755 +--- a/tools/testing/selftests/net/veth.sh ++++ b/tools/testing/selftests/net/veth.sh +@@ -1,7 +1,7 @@ + #!/bin/sh + # SPDX-License-Identifier: GPL-2.0 + +-BPF_FILE="../bpf/xdp_dummy.bpf.o" ++BPF_FILE="xdp_dummy.o" + readonly STATS="$(mktemp -p /tmp ns-XXXXXX)" + readonly BASE=`basename $STATS` + readonly SRC=2 +@@ -218,7 +218,7 @@ while getopts "hs:" option; do + done + + if [ ! -f ${BPF_FILE} ]; then +- echo "Missing ${BPF_FILE}. Build bpf selftest first" ++ echo "Missing ${BPF_FILE}. Run 'make' first" + exit 1 + fi + +diff --git a/tools/testing/selftests/net/xdp_dummy.c b/tools/testing/selftests/net/xdp_dummy.c +new file mode 100644 +index 0000000000000..d988b2e0cee84 +--- /dev/null ++++ b/tools/testing/selftests/net/xdp_dummy.c +@@ -0,0 +1,13 @@ ++// SPDX-License-Identifier: GPL-2.0 ++ ++#define KBUILD_MODNAME "xdp_dummy" ++#include <linux/bpf.h> ++#include <bpf/bpf_helpers.h> ++ ++SEC("xdp") ++int xdp_dummy_prog(struct xdp_md *ctx) ++{ ++ return XDP_PASS; ++} ++ ++char _license[] SEC("license") = "GPL"; +diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c +index 2f10541e6f381..e173014f6b667 100644 +--- a/tools/testing/selftests/nolibc/nolibc-test.c ++++ b/tools/testing/selftests/nolibc/nolibc-test.c +@@ -150,11 +150,11 @@ static void result(int llen, enum RESULT r) + const char *msg; + + if (r == OK) +- msg = " [OK]"; ++ msg = " [OK]"; + else if (r == SKIPPED) + msg = "[SKIPPED]"; + else +- msg = "[FAIL]"; ++ msg = " [FAIL]"; + + if (llen < 64) + putcharn(' ', 64 - llen); +diff --git a/tools/testing/selftests/sgx/test_encl.lds b/tools/testing/selftests/sgx/test_encl.lds +index a1ec64f7d91fc..108bc11d1d8c5 100644 +--- a/tools/testing/selftests/sgx/test_encl.lds ++++ b/tools/testing/selftests/sgx/test_encl.lds +@@ -34,8 +34,4 @@ SECTIONS + } + } + +-ASSERT(!DEFINED(.altinstructions), "ALTERNATIVES are not supported in enclaves") +-ASSERT(!DEFINED(.altinstr_replacement), "ALTERNATIVES are not supported in enclaves") +-ASSERT(!DEFINED(.discard.retpoline_safe), "RETPOLINE ALTERNATIVES are not supported in enclaves") +-ASSERT(!DEFINED(.discard.nospec), "RETPOLINE ALTERNATIVES are not supported in enclaves") +-ASSERT(!DEFINED(.got.plt), "Libcalls are not supported in enclaves") ++ASSERT(!DEFINED(_GLOBAL_OFFSET_TABLE_), "Libcalls through GOT are not supported in enclaves") |