--- /dev/null
+From ec7c10b0667b4ba82594da29977fb60a812baad0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Aug 2023 14:40:04 -0500
+Subject: ACPI: x86: s2idle: Fix a logic error parsing AMD constraints table
+
+From: Mario Limonciello <mario.limonciello@amd.com>
+
+[ Upstream commit 9cc8cd086f05d9a01026c65c98da88561e9c619e ]
+
+The constraints table should be resetting the `list` object
+after running through all of `info_obj` iterations.
+
+This adjusts whitespace as well as less code will now be included
+with each loop. This fixes a functional problem is fixed where a
+badly formed package in the inner loop may have incorrect data.
+
+Fixes: 146f1ed852a8 ("ACPI: PM: s2idle: Add AMD support to handle _DSM")
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/x86/s2idle.c | 31 ++++++++++++-------------------
+ 1 file changed, 12 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c
+index 3a9195df1aab3..ec84da6cc1bff 100644
+--- a/drivers/acpi/x86/s2idle.c
++++ b/drivers/acpi/x86/s2idle.c
+@@ -128,12 +128,11 @@ static void lpi_device_get_constraints_amd(void)
+ struct lpi_constraints *list;
+ acpi_status status;
+
++ list = &lpi_constraints_table[lpi_constraints_table_size];
++
+ for (k = 0; k < info_obj->package.count; k++) {
+ union acpi_object *obj = &info_obj->package.elements[k];
+
+- list = &lpi_constraints_table[lpi_constraints_table_size];
+- list->min_dstate = -1;
+-
+ switch (k) {
+ case 0:
+ dev_info.enabled = obj->integer.value;
+@@ -148,27 +147,21 @@ static void lpi_device_get_constraints_amd(void)
+ dev_info.min_dstate = obj->integer.value;
+ break;
+ }
++ }
+
+- if (!dev_info.enabled || !dev_info.name ||
+- !dev_info.min_dstate)
+- continue;
++ if (!dev_info.enabled || !dev_info.name ||
++ !dev_info.min_dstate)
++ continue;
+
+- status = acpi_get_handle(NULL, dev_info.name,
+- &list->handle);
+- if (ACPI_FAILURE(status))
+- continue;
++ status = acpi_get_handle(NULL, dev_info.name, &list->handle);
++ if (ACPI_FAILURE(status))
++ continue;
+
+- acpi_handle_debug(lps0_device_handle,
+- "Name:%s\n", dev_info.name);
++ acpi_handle_debug(lps0_device_handle,
++ "Name:%s\n", dev_info.name);
+
+- list->min_dstate = dev_info.min_dstate;
++ list->min_dstate = dev_info.min_dstate;
+
+- if (list->min_dstate < 0) {
+- acpi_handle_debug(lps0_device_handle,
+- "Incomplete constraint defined\n");
+- continue;
+- }
+- }
+ lpi_constraints_table_size++;
+ }
+ }
+--
+2.40.1
+
--- /dev/null
+From 22b80f834c77173af982ba68d88138a02218b648 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Aug 2023 14:40:02 -0500
+Subject: ACPI: x86: s2idle: Post-increment variables when getting constraints
+
+From: Mario Limonciello <mario.limonciello@amd.com>
+
+[ Upstream commit 3c6b1212d20bbbffcad5709ab0f2d5ed9b5859a8 ]
+
+When code uses a pre-increment it makes the reader question "why".
+In the constraint fetching code there is no reason for the variables
+to be pre-incremented so adjust to post-increment.
+No intended functional changes.
+
+Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
+Suggested-by: Bjorn Helgaas <helgaas@kernel.org>
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Stable-dep-of: 9cc8cd086f05 ("ACPI: x86: s2idle: Fix a logic error parsing AMD constraints table")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/x86/s2idle.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c
+index e499c60c45791..3a9195df1aab3 100644
+--- a/drivers/acpi/x86/s2idle.c
++++ b/drivers/acpi/x86/s2idle.c
+@@ -122,13 +122,13 @@ static void lpi_device_get_constraints_amd(void)
+ acpi_handle_debug(lps0_device_handle,
+ "LPI: constraints list begin:\n");
+
+- for (j = 0; j < package->package.count; ++j) {
++ for (j = 0; j < package->package.count; j++) {
+ union acpi_object *info_obj = &package->package.elements[j];
+ struct lpi_device_constraint_amd dev_info = {};
+ struct lpi_constraints *list;
+ acpi_status status;
+
+- for (k = 0; k < info_obj->package.count; ++k) {
++ for (k = 0; k < info_obj->package.count; k++) {
+ union acpi_object *obj = &info_obj->package.elements[k];
+
+ list = &lpi_constraints_table[lpi_constraints_table_size];
+@@ -213,7 +213,7 @@ static void lpi_device_get_constraints(void)
+ if (!package)
+ continue;
+
+- for (j = 0; j < package->package.count; ++j) {
++ for (j = 0; j < package->package.count; j++) {
+ union acpi_object *element =
+ &(package->package.elements[j]);
+
+@@ -245,7 +245,7 @@ static void lpi_device_get_constraints(void)
+
+ constraint->min_dstate = -1;
+
+- for (j = 0; j < package_count; ++j) {
++ for (j = 0; j < package_count; j++) {
+ union acpi_object *info_obj = &info.package[j];
+ union acpi_object *cnstr_pkg;
+ union acpi_object *obj;
+--
+2.40.1
+
--- /dev/null
+From 8f325065a6d4ca5cb97c36b04f6322faffc9f57c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Aug 2023 10:52:13 +0800
+Subject: ALSA: ac97: Fix possible error value of *rac97
+
+From: Su Hui <suhui@nfschina.com>
+
+[ Upstream commit 67de40c9df94037769967ba28c7d951afb45b7fb ]
+
+Before committing 79597c8bf64c, *rac97 always be NULL if there is
+an error. When error happens, make sure *rac97 is NULL is safer.
+
+For examble, in snd_vortex_mixer():
+ err = snd_ac97_mixer(pbus, &ac97, &vortex->codec);
+ vortex->isquad = ((vortex->codec == NULL) ?
+ 0 : (vortex->codec->ext_id&0x80));
+If error happened but vortex->codec isn't NULL, this may cause some
+problems.
+
+Move the judgement order to be clearer and better.
+
+Fixes: 79597c8bf64c ("ALSA: ac97: Fix possible NULL dereference in snd_ac97_mixer")
+Suggested-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Acked-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Su Hui <suhui@nfschina.com>
+Link: https://lore.kernel.org/r/20230823025212.1000961-1-suhui@nfschina.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/ac97/ac97_codec.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
+index 80a65b8ad7b9b..25f93e56cfc7a 100644
+--- a/sound/pci/ac97/ac97_codec.c
++++ b/sound/pci/ac97/ac97_codec.c
+@@ -2069,10 +2069,9 @@ int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template,
+ .dev_disconnect = snd_ac97_dev_disconnect,
+ };
+
+- if (!rac97)
+- return -EINVAL;
+- if (snd_BUG_ON(!bus || !template))
++ if (snd_BUG_ON(!bus || !template || !rac97))
+ return -EINVAL;
++ *rac97 = NULL;
+ if (snd_BUG_ON(template->num >= 4))
+ return -EINVAL;
+ if (bus->codec[template->num])
+--
+2.40.1
+
--- /dev/null
+From 2f604e2dbfb6f3e430ca031d0eb252c59cb72e4b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Aug 2023 10:39:27 +0800
+Subject: amba: bus: fix refcount leak
+
+From: Peng Fan <peng.fan@nxp.com>
+
+[ Upstream commit e312cbdc11305568554a9e18a2ea5c2492c183f3 ]
+
+commit 5de1540b7bc4 ("drivers/amba: create devices from device tree")
+increases the refcount of of_node, but not releases it in
+amba_device_release, so there is refcount leak. By using of_node_put
+to avoid refcount leak.
+
+Fixes: 5de1540b7bc4 ("drivers/amba: create devices from device tree")
+Signed-off-by: Peng Fan <peng.fan@nxp.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://lore.kernel.org/r/20230821023928.3324283-1-peng.fan@oss.nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/amba/bus.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
+index ce88af9eb562f..09e72967b8abf 100644
+--- a/drivers/amba/bus.c
++++ b/drivers/amba/bus.c
+@@ -528,6 +528,7 @@ static void amba_device_release(struct device *dev)
+ {
+ struct amba_device *d = to_amba_device(dev);
+
++ of_node_put(d->dev.of_node);
+ if (d->res.parent)
+ release_resource(&d->res);
+ mutex_destroy(&d->periphid_lock);
+--
+2.40.1
+
--- /dev/null
+From 9b274ec30d338b39fd9f36dc717a1724c73a5ca4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 May 2023 12:25:29 -0500
+Subject: ARM: dts: Add .dts files missing from the build
+
+From: Rob Herring <robh@kernel.org>
+
+[ Upstream commit 86684c2481b6e6a46c2282acee13554e34e66071 ]
+
+Comparing .dts files to built .dtb files yielded a few .dts files which
+are never built. Add them to the build.
+
+Signed-off-by: Rob Herring <robh@kernel.org>
+Stable-dep-of: 92632115fb57 ("samples/bpf: fix bio latency check with tracepoint")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/Makefile | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
+index 59829fc903152..3cf1bf724e8ed 100644
+--- a/arch/arm/boot/dts/Makefile
++++ b/arch/arm/boot/dts/Makefile
+@@ -335,6 +335,7 @@ dtb-$(CONFIG_MACH_KIRKWOOD) += \
+ kirkwood-iconnect.dtb \
+ kirkwood-iomega_ix2_200.dtb \
+ kirkwood-is2.dtb \
++ kirkwood-km_fixedeth.dtb \
+ kirkwood-km_kirkwood.dtb \
+ kirkwood-l-50.dtb \
+ kirkwood-laplug.dtb \
+@@ -880,7 +881,10 @@ dtb-$(CONFIG_ARCH_OMAP3) += \
+ am3517-craneboard.dtb \
+ am3517-evm.dtb \
+ am3517_mt_ventoux.dtb \
++ logicpd-torpedo-35xx-devkit.dtb \
+ logicpd-torpedo-37xx-devkit.dtb \
++ logicpd-torpedo-37xx-devkit-28.dtb \
++ logicpd-som-lv-35xx-devkit.dtb \
+ logicpd-som-lv-37xx-devkit.dtb \
+ omap3430-sdp.dtb \
+ omap3-beagle.dtb \
+@@ -1561,6 +1565,8 @@ dtb-$(CONFIG_MACH_ARMADA_38X) += \
+ armada-388-helios4.dtb \
+ armada-388-rd.dtb
+ dtb-$(CONFIG_MACH_ARMADA_39X) += \
++ armada-390-db.dtb \
++ armada-395-gp.dtb \
+ armada-398-db.dtb
+ dtb-$(CONFIG_MACH_ARMADA_XP) += \
+ armada-xp-axpwifiap.dtb \
+@@ -1590,6 +1596,7 @@ dtb-$(CONFIG_MACH_DOVE) += \
+ dtb-$(CONFIG_ARCH_MEDIATEK) += \
+ mt2701-evb.dtb \
+ mt6580-evbp1.dtb \
++ mt6582-prestigio-pmt5008-3g.dtb \
+ mt6589-aquaris5.dtb \
+ mt6589-fairphone-fp1.dtb \
+ mt6592-evb.dtb \
+@@ -1645,6 +1652,7 @@ dtb-$(CONFIG_ARCH_ASPEED) += \
+ aspeed-bmc-intel-s2600wf.dtb \
+ aspeed-bmc-inspur-fp5280g2.dtb \
+ aspeed-bmc-inspur-nf5280m6.dtb \
++ aspeed-bmc-inspur-on5263m5.dtb \
+ aspeed-bmc-lenovo-hr630.dtb \
+ aspeed-bmc-lenovo-hr855xg2.dtb \
+ aspeed-bmc-microsoft-olympus.dtb \
+--
+2.40.1
+
--- /dev/null
+From abbcce4dbb5f2b5e5f476b0a93dbd3fc51ed332e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Jul 2023 13:40:03 +0200
+Subject: ARM: dts: BCM53573: Add cells sizes to PCIe node
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Rafał Miłecki <rafal@milecki.pl>
+
+[ Upstream commit 3392ef368d9b04622fe758b1079b512664b6110a ]
+
+This fixes:
+arch/arm/boot/dts/broadcom/bcm47189-luxul-xap-1440.dtb: pcie@2000: '#address-cells' is a required property
+ From schema: /lib/python3.10/site-packages/dtschema/schemas/pci/pci-bus.yaml
+arch/arm/boot/dts/broadcom/bcm47189-luxul-xap-1440.dtb: pcie@2000: '#size-cells' is a required property
+ From schema: /lib/python3.10/site-packages/dtschema/schemas/pci/pci-bus.yaml
+
+Two properties that need to be added later are "device_type" and
+"ranges". Adding "device_type" on its own causes a new warning and the
+value of "ranges" needs to be determined yet.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Link: https://lore.kernel.org/r/20230707114004.2740-3-zajec5@gmail.com
+Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/bcm53573.dtsi | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/arch/arm/boot/dts/bcm53573.dtsi b/arch/arm/boot/dts/bcm53573.dtsi
+index 3cb71829e8597..eed1a6147f0bf 100644
+--- a/arch/arm/boot/dts/bcm53573.dtsi
++++ b/arch/arm/boot/dts/bcm53573.dtsi
+@@ -127,6 +127,9 @@ uart0: serial@300 {
+
+ pcie0: pcie@2000 {
+ reg = <0x00002000 0x1000>;
++
++ #address-cells = <3>;
++ #size-cells = <2>;
+ };
+
+ usb2: usb2@4000 {
+--
+2.40.1
+
--- /dev/null
+From 777707ef30405e22751d314f77269cdeaf5f34d1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Jul 2023 13:40:01 +0200
+Subject: ARM: dts: BCM53573: Drop nonexistent "default-off" LED trigger
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Rafał Miłecki <rafal@milecki.pl>
+
+[ Upstream commit be7e1e5b0f67c58ec4be0a54db23b6a4fa6e2116 ]
+
+There is no such trigger documented or implemented in Linux. It was a
+copy & paste mistake.
+
+This fixes:
+arch/arm/boot/dts/broadcom/bcm47189-luxul-xap-1440.dtb: leds: led-wlan:linux,default-trigger: 'oneOf' conditional failed, one must be fixed:
+ 'default-off' is not one of ['backlight', 'default-on', 'heartbeat', 'disk-activity', 'disk-read', 'disk-write', 'timer', 'pattern', 'audio-micmute', 'audio-mute', 'bluetooth-power', 'flash', 'kbd-capslock', 'mtd', 'nand-disk', 'none', 'torch', 'usb-gadget', 'usb-host', 'usbport']
+ 'default-off' does not match '^cpu[0-9]*$'
+ 'default-off' does not match '^hci[0-9]+-power$'
+ 'default-off' does not match '^mmc[0-9]+$'
+ 'default-off' does not match '^phy[0-9]+tx$'
+ From schema: Documentation/devicetree/bindings/leds/leds-gpio.yaml
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Link: https://lore.kernel.org/r/20230707114004.2740-1-zajec5@gmail.com
+Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts | 1 -
+ arch/arm/boot/dts/bcm47189-luxul-xap-810.dts | 2 --
+ 2 files changed, 3 deletions(-)
+
+diff --git a/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts b/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
+index 0734aa249b8e0..b9dd508444198 100644
+--- a/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
++++ b/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
+@@ -26,7 +26,6 @@ leds {
+ led-wlan {
+ label = "bcm53xx:blue:wlan";
+ gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>;
+- linux,default-trigger = "default-off";
+ };
+
+ led-system {
+diff --git a/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts b/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
+index e6fb6cbe69633..cb22ae2a02e54 100644
+--- a/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
++++ b/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
+@@ -26,7 +26,6 @@ leds-0 {
+ led-5ghz {
+ label = "bcm53xx:blue:5ghz";
+ gpios = <&chipcommon 11 GPIO_ACTIVE_HIGH>;
+- linux,default-trigger = "default-off";
+ };
+
+ led-system {
+@@ -42,7 +41,6 @@ leds-1 {
+ led-2ghz {
+ label = "bcm53xx:blue:2ghz";
+ gpios = <&pcie0_chipcommon 3 GPIO_ACTIVE_HIGH>;
+- linux,default-trigger = "default-off";
+ };
+ };
+
+--
+2.40.1
+
--- /dev/null
+From 69372a0ddb2977a0ba07686c12481d9437963324 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Jul 2023 13:40:02 +0200
+Subject: ARM: dts: BCM53573: Drop nonexistent #usb-cells
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Rafał Miłecki <rafal@milecki.pl>
+
+[ Upstream commit 05d2c3d552b8c92fc397377d9d1112fc58e2cd59 ]
+
+Such property simply doesn't exist (is not documented or used anywhere).
+
+This fixes:
+arch/arm/boot/dts/broadcom/bcm47189-luxul-xap-1440.dtb: usb@d000: Unevaluated properties are not allowed ('#usb-cells' was unexpected)
+ From schema: Documentation/devicetree/bindings/usb/generic-ohci.yaml
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Link: https://lore.kernel.org/r/20230707114004.2740-2-zajec5@gmail.com
+Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/bcm53573.dtsi | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/bcm53573.dtsi b/arch/arm/boot/dts/bcm53573.dtsi
+index 3f03a381db0f2..3cb71829e8597 100644
+--- a/arch/arm/boot/dts/bcm53573.dtsi
++++ b/arch/arm/boot/dts/bcm53573.dtsi
+@@ -156,8 +156,6 @@ ehci_port2: port@2 {
+ };
+
+ ohci: usb@d000 {
+- #usb-cells = <0>;
+-
+ compatible = "generic-ohci";
+ reg = <0xd000 0x1000>;
+ interrupt-parent = <&gic>;
+--
+2.40.1
+
--- /dev/null
+From 09ab2b403ca4824990c0bde6432b9f57622fcdce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Jul 2023 13:11:45 +0200
+Subject: ARM: dts: BCM53573: Fix Ethernet info for Luxul devices
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Rafał Miłecki <rafal@milecki.pl>
+
+[ Upstream commit 44ad8207806973f4e4f7d870fff36cc01f494250 ]
+
+Both Luxul's XAP devices (XAP-810 and XAP-1440) are access points that
+use a non-default design. They don't include switch but have a single
+Ethernet port and BCM54210E PHY connected to the Ethernet controller's
+MDIO bus.
+
+Support for those devices regressed due to two changes:
+
+1. Describing MDIO bus with switch
+After commit 9fb90ae6cae7 ("ARM: dts: BCM53573: Describe on-SoC BCM53125
+rev 4 switch") Linux stopped probing for MDIO devices.
+
+2. Dropping hardcoded BCM54210E delays
+In commit fea7fda7f50a ("net: phy: broadcom: Fix RGMII delays
+configuration for BCM54210E") support for other PHY modes was added but
+that requires a proper "phy-mode" value in DT.
+
+Both above changes are correct (they don't need to be reverted or
+anything) but they need this fix for DT data to be correct and for Linux
+to work properly.
+
+Fixes: 9fb90ae6cae7 ("ARM: dts: BCM53573: Describe on-SoC BCM53125 rev 4 switch")
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Link: https://lore.kernel.org/r/20230713111145.14864-1-zajec5@gmail.com
+Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts | 13 +++++++++++++
+ arch/arm/boot/dts/bcm47189-luxul-xap-810.dts | 13 +++++++++++++
+ 2 files changed, 26 insertions(+)
+
+diff --git a/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts b/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
+index b9dd508444198..0f6d7fe30068f 100644
+--- a/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
++++ b/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
+@@ -45,3 +45,16 @@ button-restart {
+ };
+ };
+ };
++
++&gmac0 {
++ phy-mode = "rgmii";
++ phy-handle = <&bcm54210e>;
++
++ mdio {
++ /delete-node/ switch@1e;
++
++ bcm54210e: ethernet-phy@0 {
++ reg = <0>;
++ };
++ };
++};
+diff --git a/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts b/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
+index cb22ae2a02e54..4e0ef0af726f5 100644
+--- a/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
++++ b/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
+@@ -81,3 +81,16 @@ pcie0_chipcommon: chipcommon@0 {
+ };
+ };
+ };
++
++&gmac0 {
++ phy-mode = "rgmii";
++ phy-handle = <&bcm54210e>;
++
++ mdio {
++ /delete-node/ switch@1e;
++
++ bcm54210e: ethernet-phy@0 {
++ reg = <0>;
++ };
++ };
++};
+--
+2.40.1
+
--- /dev/null
+From 2bbb3c2ff23b31f74981cfc1a6a5f66a878db0dd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 23 Jul 2023 21:54:14 +0200
+Subject: ARM: dts: BCM53573: Fix Tenda AC9 switch CPU port
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Rafał Miłecki <rafal@milecki.pl>
+
+[ Upstream commit 7141209db9c335ab261a17933809a3e660ebdc12 ]
+
+Primary Ethernet interface is connected to the port 8 (not 5).
+
+Fixes: 64612828628c ("ARM: dts: BCM53573: Add Tenda AC9 switch ports")
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Link: https://lore.kernel.org/r/20230723195416.7831-1-zajec5@gmail.com
+Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/bcm47189-tenda-ac9.dts | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/bcm47189-tenda-ac9.dts b/arch/arm/boot/dts/bcm47189-tenda-ac9.dts
+index dab2e5f63a727..06b1a582809ca 100644
+--- a/arch/arm/boot/dts/bcm47189-tenda-ac9.dts
++++ b/arch/arm/boot/dts/bcm47189-tenda-ac9.dts
+@@ -135,8 +135,8 @@ port@4 {
+ label = "lan4";
+ };
+
+- port@5 {
+- reg = <5>;
++ port@8 {
++ reg = <8>;
+ label = "cpu";
+ ethernet = <&gmac0>;
+ };
+--
+2.40.1
+
--- /dev/null
+From fae2e39a372444ae54d94982dcf76ee9f4543f33 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Jul 2023 13:40:04 +0200
+Subject: ARM: dts: BCM53573: Use updated "spi-gpio" binding properties
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Rafał Miłecki <rafal@milecki.pl>
+
+[ Upstream commit 2c0fd6b3d0778ceab40205315ccef74568490f17 ]
+
+Switch away from deprecated properties.
+
+This fixes:
+arch/arm/boot/dts/broadcom/bcm947189acdbmr.dtb: spi: gpio-sck: False schema does not allow [[3, 21, 0]]
+ From schema: Documentation/devicetree/bindings/spi/spi-gpio.yaml
+arch/arm/boot/dts/broadcom/bcm947189acdbmr.dtb: spi: gpio-miso: False schema does not allow [[3, 22, 0]]
+ From schema: Documentation/devicetree/bindings/spi/spi-gpio.yaml
+arch/arm/boot/dts/broadcom/bcm947189acdbmr.dtb: spi: gpio-mosi: False schema does not allow [[3, 23, 0]]
+ From schema: Documentation/devicetree/bindings/spi/spi-gpio.yaml
+arch/arm/boot/dts/broadcom/bcm947189acdbmr.dtb: spi: 'sck-gpios' is a required property
+ From schema: Documentation/devicetree/bindings/spi/spi-gpio.yaml
+arch/arm/boot/dts/broadcom/bcm947189acdbmr.dtb: spi: Unevaluated properties are not allowed ('gpio-miso', 'gpio-mosi', 'gpio-sck' were unexpected)
+ From schema: Documentation/devicetree/bindings/spi/spi-gpio.yaml
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Link: https://lore.kernel.org/r/20230707114004.2740-4-zajec5@gmail.com
+Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/bcm947189acdbmr.dts | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm/boot/dts/bcm947189acdbmr.dts b/arch/arm/boot/dts/bcm947189acdbmr.dts
+index 3709baa2376f5..0b8727ae6f16d 100644
+--- a/arch/arm/boot/dts/bcm947189acdbmr.dts
++++ b/arch/arm/boot/dts/bcm947189acdbmr.dts
+@@ -60,9 +60,9 @@ button-wps {
+ spi {
+ compatible = "spi-gpio";
+ num-chipselects = <1>;
+- gpio-sck = <&chipcommon 21 0>;
+- gpio-miso = <&chipcommon 22 0>;
+- gpio-mosi = <&chipcommon 23 0>;
++ sck-gpios = <&chipcommon 21 0>;
++ miso-gpios = <&chipcommon 22 0>;
++ mosi-gpios = <&chipcommon 23 0>;
+ cs-gpios = <&chipcommon 24 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+--
+2.40.1
+
--- /dev/null
+From cdb261d67de45cfd1cd755aaf0306a1f0439fcf7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Aug 2023 13:01:16 +0200
+Subject: ARM: dts: qcom: ipq4019: correct SDHCI XO clock
+
+From: Robert Marko <robert.marko@sartura.hr>
+
+[ Upstream commit b5ed7a5c1fdb3981713f7b637b72aa390c3db036 ]
+
+Using GCC_DCD_XO_CLK as the XO clock for SDHCI controller is not correct,
+it seems that I somehow made a mistake of passing it instead of the fixed
+XO clock.
+
+Fixes: 04b3b72b5b8f ("ARM: dts: qcom: ipq4019: Add SDHCI controller node")
+Signed-off-by: Robert Marko <robert.marko@sartura.hr>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230811110150.229966-1-robert.marko@sartura.hr
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/qcom-ipq4019.dtsi | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm/boot/dts/qcom-ipq4019.dtsi b/arch/arm/boot/dts/qcom-ipq4019.dtsi
+index f0ef86fadc9d9..e328216443135 100644
+--- a/arch/arm/boot/dts/qcom-ipq4019.dtsi
++++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi
+@@ -230,9 +230,12 @@ sdhci: mmc@7824900 {
+ interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "hc_irq", "pwr_irq";
+ bus-width = <8>;
+- clocks = <&gcc GCC_SDCC1_AHB_CLK>, <&gcc GCC_SDCC1_APPS_CLK>,
+- <&gcc GCC_DCD_XO_CLK>;
+- clock-names = "iface", "core", "xo";
++ clocks = <&gcc GCC_SDCC1_AHB_CLK>,
++ <&gcc GCC_SDCC1_APPS_CLK>,
++ <&xo>;
++ clock-names = "iface",
++ "core",
++ "xo";
+ status = "disabled";
+ };
+
+--
+2.40.1
+
--- /dev/null
+From 3bedf07bc3e55d503650a3aa091c67786a9735f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Aug 2023 19:08:51 +0530
+Subject: ARM: dts: qcom: sdx65-mtp: Update the pmic used in sdx65
+
+From: Rohit Agarwal <quic_rohiagar@quicinc.com>
+
+[ Upstream commit f636d6c356b339b0d29eed025f8bf9efcb6eb274 ]
+
+Update the pmic used in sdx65 platform to pm7250b.
+
+Fixes: 26380f298b2b (ARM: dts: qcom: sdx65-mtp: Add pmk8350b and pm8150b pmic)
+Signed-off-by: Rohit Agarwal <quic_rohiagar@quicinc.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/1691415534-31820-7-git-send-email-quic_rohiagar@quicinc.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/qcom-sdx65-mtp.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/qcom-sdx65-mtp.dts b/arch/arm/boot/dts/qcom-sdx65-mtp.dts
+index 57bc3b03d3aac..4264ace66b295 100644
+--- a/arch/arm/boot/dts/qcom-sdx65-mtp.dts
++++ b/arch/arm/boot/dts/qcom-sdx65-mtp.dts
+@@ -7,7 +7,7 @@
+ #include "qcom-sdx65.dtsi"
+ #include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+ #include <arm64/qcom/pmk8350.dtsi>
+-#include <arm64/qcom/pm8150b.dtsi>
++#include <arm64/qcom/pm7250b.dtsi>
+ #include "qcom-pmx65.dtsi"
+
+ / {
+--
+2.40.1
+
--- /dev/null
+From ad6cb01a10f755f6f45ea302a181b16434f51364 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Apr 2023 11:57:21 +0200
+Subject: ARM: dts: s5pv210: add dummy 5V regulator for backlight on SMDKv210
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit b77904ba177a9c67b6dbc3637fdf1faa22df6e5c ]
+
+Backlight is supplied by DC5V regulator. The DTS has no PMIC node, so
+just add a regulator-fixed to solve it and fix dtbs_check warning:
+
+ s5pv210-smdkv210.dtb: backlight: 'power-supply' is a required property
+
+Link: https://lore.kernel.org/r/20230421095721.31857-4-krzysztof.kozlowski@linaro.org
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Stable-dep-of: 982655cb0e7f ("ARM: dts: samsung: s5pv210-smdkv210: correct ethernet reg addresses (split)")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/s5pv210-smdkv210.dts | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/arch/arm/boot/dts/s5pv210-smdkv210.dts b/arch/arm/boot/dts/s5pv210-smdkv210.dts
+index fbae768d65e27..6e26c67e0a26e 100644
+--- a/arch/arm/boot/dts/s5pv210-smdkv210.dts
++++ b/arch/arm/boot/dts/s5pv210-smdkv210.dts
+@@ -55,6 +55,14 @@ backlight {
+ default-brightness-level = <6>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm3_out>;
++ power-supply = <&dc5v_reg>;
++ };
++
++ dc5v_reg: regulator-0 {
++ compatible = "regulator-fixed";
++ regulator-name = "DC5V";
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
+ };
+ };
+
+--
+2.40.1
+
--- /dev/null
+From d8616d496602b2f11da70d5432d4b240d8216806 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Jul 2023 17:29:25 +0200
+Subject: ARM: dts: samsung: s3c6410-mini6410: correct ethernet reg addresses
+ (split)
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit cf0cb2af6a18f28b84f9f1416bff50ca60d6e98a ]
+
+The davicom,dm9000 Ethernet Controller accepts two reg addresses.
+
+Fixes: a43736deb47d ("ARM: dts: Add dts file for S3C6410-based Mini6410 board")
+Reviewed-by: Alim Akhtar <alim.akhtar@samsung.com>
+Link: https://lore.kernel.org/r/20230713152926.82884-1-krzysztof.kozlowski@linaro.org
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/s3c6410-mini6410.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/s3c6410-mini6410.dts b/arch/arm/boot/dts/s3c6410-mini6410.dts
+index 17097da36f5ed..0b07b3c319604 100644
+--- a/arch/arm/boot/dts/s3c6410-mini6410.dts
++++ b/arch/arm/boot/dts/s3c6410-mini6410.dts
+@@ -51,7 +51,7 @@ srom-cs1-bus@18000000 {
+
+ ethernet@18000000 {
+ compatible = "davicom,dm9000";
+- reg = <0x18000000 0x2 0x18000004 0x2>;
++ reg = <0x18000000 0x2>, <0x18000004 0x2>;
+ interrupt-parent = <&gpn>;
+ interrupts = <7 IRQ_TYPE_LEVEL_HIGH>;
+ davicom,no-eeprom;
+--
+2.40.1
+
--- /dev/null
+From 8f400d4abded223e7d328a7831f45ef780f9e55f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Jul 2023 17:29:26 +0200
+Subject: ARM: dts: samsung: s5pv210-smdkv210: correct ethernet reg addresses
+ (split)
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 982655cb0e7f18934d7532c32366e574ad61dbd7 ]
+
+The davicom,dm9000 Ethernet Controller accepts two reg addresses.
+
+Fixes: b672b27d232e ("ARM: dts: Add Device tree for s5pc110/s5pv210 boards")
+Reviewed-by: Alim Akhtar <alim.akhtar@samsung.com>
+Link: https://lore.kernel.org/r/20230713152926.82884-2-krzysztof.kozlowski@linaro.org
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/s5pv210-smdkv210.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/s5pv210-smdkv210.dts b/arch/arm/boot/dts/s5pv210-smdkv210.dts
+index 6e26c67e0a26e..901e7197b1368 100644
+--- a/arch/arm/boot/dts/s5pv210-smdkv210.dts
++++ b/arch/arm/boot/dts/s5pv210-smdkv210.dts
+@@ -41,7 +41,7 @@ pmic_ap_clk: clock-0 {
+
+ ethernet@a8000000 {
+ compatible = "davicom,dm9000";
+- reg = <0xA8000000 0x2 0xA8000002 0x2>;
++ reg = <0xa8000000 0x2>, <0xa8000002 0x2>;
+ interrupt-parent = <&gph1>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH>;
+ local-mac-address = [00 00 de ad be ef];
+--
+2.40.1
+
--- /dev/null
+From a697d381f66458f2f34dfd9d52aadc11223e2b10 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Jul 2023 15:09:07 +0200
+Subject: ARM: dts: stm32: Add missing detach mailbox for DHCOM SoM
+
+From: Marek Vasut <marex@denx.de>
+
+[ Upstream commit deb7edbc27a6ec4d8f5edfd8519b7ed13cbd2a52 ]
+
+Add missing "detach" mailbox to this board to permit the CPU to inform
+the remote processor on a detach. This signal allows the remote processor
+firmware to stop IPC communication and to reinitialize the resources for
+a re-attach.
+
+Without this mailbox, detach is not possible and kernel log contains the
+following warning to, so make sure all the STM32MP15xx platform DTs are
+in sync regarding the mailboxes to fix the detach issue and the warning:
+"
+stm32-rproc 10000000.m4: mbox_request_channel_byname() could not locate channel named "detach"
+"
+
+Fixes: 6257dfc1c412 ("ARM: dts: stm32: Add coprocessor detach mbox on stm32mp15x-dkx boards")
+Signed-off-by: Marek Vasut <marex@denx.de>
+Signed-off-by: Alexandre Torgue <alexandre.torgue@foss.st.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi
+index e61df23d361a7..74a11ccc5333f 100644
+--- a/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi
++++ b/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi
+@@ -416,8 +416,8 @@ &iwdg2 {
+ &m4_rproc {
+ memory-region = <&retram>, <&mcuram>, <&mcuram2>, <&vdev0vring0>,
+ <&vdev0vring1>, <&vdev0buffer>;
+- mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>;
+- mbox-names = "vq0", "vq1", "shutdown";
++ mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>, <&ipcc 3>;
++ mbox-names = "vq0", "vq1", "shutdown", "detach";
+ interrupt-parent = <&exti>;
+ interrupts = <68 1>;
+ status = "okay";
+--
+2.40.1
+
--- /dev/null
+From 7a2e4dc1c2b939fca9483c6e7ba66d99e7fcd3a2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Jul 2023 15:11:21 +0200
+Subject: ARM: dts: stm32: Add missing detach mailbox for DHCOR SoM
+
+From: Marek Vasut <marex@denx.de>
+
+[ Upstream commit 2f38de940f072db369edd3e6e8d82bb8f42c5c9b ]
+
+Add missing "detach" mailbox to this board to permit the CPU to inform
+the remote processor on a detach. This signal allows the remote processor
+firmware to stop IPC communication and to reinitialize the resources for
+a re-attach.
+
+Without this mailbox, detach is not possible and kernel log contains the
+following warning to, so make sure all the STM32MP15xx platform DTs are
+in sync regarding the mailboxes to fix the detach issue and the warning:
+"
+stm32-rproc 10000000.m4: mbox_request_channel_byname() could not locate channel named "detach"
+"
+
+Fixes: 6257dfc1c412 ("ARM: dts: stm32: Add coprocessor detach mbox on stm32mp15x-dkx boards")
+Signed-off-by: Marek Vasut <marex@denx.de>
+Signed-off-by: Alexandre Torgue <alexandre.torgue@foss.st.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi
+index bba19f21e5277..89881a26c6141 100644
+--- a/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi
++++ b/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi
+@@ -227,8 +227,8 @@ &iwdg2 {
+ &m4_rproc {
+ memory-region = <&retram>, <&mcuram>, <&mcuram2>, <&vdev0vring0>,
+ <&vdev0vring1>, <&vdev0buffer>;
+- mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>;
+- mbox-names = "vq0", "vq1", "shutdown";
++ mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>, <&ipcc 3>;
++ mbox-names = "vq0", "vq1", "shutdown", "detach";
+ interrupt-parent = <&exti>;
+ interrupts = <68 1>;
+ status = "okay";
+--
+2.40.1
+
--- /dev/null
+From b09393bcf8be328e8eef1625dbafd09a9f95c02d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 May 2023 03:12:42 +0200
+Subject: ARM: dts: stm32: Add missing detach mailbox for emtrion emSBC-Argon
+
+From: Marek Vasut <marex@denx.de>
+
+[ Upstream commit 0ee0ef38aa9f75f21b51f729dd42b2e932515188 ]
+
+Add missing "detach" mailbox to this board to permit the CPU to inform
+the remote processor on a detach. This signal allows the remote processor
+firmware to stop IPC communication and to reinitialize the resources for
+a re-attach.
+
+Without this mailbox, detach is not possible and kernel log contains the
+following warning to, so make sure all the STM32MP15xx platform DTs are
+in sync regarding the mailboxes to fix the detach issue and the warning:
+"
+stm32-rproc 10000000.m4: mbox_request_channel_byname() could not locate channel named "detach"
+"
+
+Fixes: 6257dfc1c412 ("ARM: dts: stm32: Add coprocessor detach mbox on stm32mp15x-dkx boards")
+Signed-off-by: Marek Vasut <marex@denx.de>
+Signed-off-by: Alexandre Torgue <alexandre.torgue@foss.st.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/stm32mp157c-emstamp-argon.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/stm32mp157c-emstamp-argon.dtsi b/arch/arm/boot/dts/stm32mp157c-emstamp-argon.dtsi
+index 94e38141af672..fd89542c69c93 100644
+--- a/arch/arm/boot/dts/stm32mp157c-emstamp-argon.dtsi
++++ b/arch/arm/boot/dts/stm32mp157c-emstamp-argon.dtsi
+@@ -368,8 +368,8 @@ &iwdg2 {
+ &m4_rproc {
+ memory-region = <&retram>, <&mcuram>, <&mcuram2>, <&vdev0vring0>,
+ <&vdev0vring1>, <&vdev0buffer>;
+- mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>;
+- mbox-names = "vq0", "vq1", "shutdown";
++ mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>, <&ipcc 3>;
++ mbox-names = "vq0", "vq1", "shutdown", "detach";
+ interrupt-parent = <&exti>;
+ interrupts = <68 1>;
+ interrupt-names = "wdg";
+--
+2.40.1
+
--- /dev/null
+From 89c85cb546255c67721d6005950a4e59e9b7f73b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 May 2023 03:12:43 +0200
+Subject: ARM: dts: stm32: Add missing detach mailbox for Odyssey SoM
+
+From: Marek Vasut <marex@denx.de>
+
+[ Upstream commit 966f04a89d77548e673de2c400abe0b2cf5c15db ]
+
+Add missing "detach" mailbox to this board to permit the CPU to inform
+the remote processor on a detach. This signal allows the remote processor
+firmware to stop IPC communication and to reinitialize the resources for
+a re-attach.
+
+Without this mailbox, detach is not possible and kernel log contains the
+following warning to, so make sure all the STM32MP15xx platform DTs are
+in sync regarding the mailboxes to fix the detach issue and the warning:
+"
+stm32-rproc 10000000.m4: mbox_request_channel_byname() could not locate channel named "detach"
+"
+
+Fixes: 6257dfc1c412 ("ARM: dts: stm32: Add coprocessor detach mbox on stm32mp15x-dkx boards")
+Signed-off-by: Marek Vasut <marex@denx.de>
+Signed-off-by: Alexandre Torgue <alexandre.torgue@foss.st.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/stm32mp157c-odyssey-som.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/stm32mp157c-odyssey-som.dtsi b/arch/arm/boot/dts/stm32mp157c-odyssey-som.dtsi
+index e22871dc580c8..cf74852514906 100644
+--- a/arch/arm/boot/dts/stm32mp157c-odyssey-som.dtsi
++++ b/arch/arm/boot/dts/stm32mp157c-odyssey-som.dtsi
+@@ -230,8 +230,8 @@ &iwdg2 {
+ &m4_rproc {
+ memory-region = <&retram>, <&mcuram>, <&mcuram2>, <&vdev0vring0>,
+ <&vdev0vring1>, <&vdev0buffer>;
+- mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>;
+- mbox-names = "vq0", "vq1", "shutdown";
++ mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>, <&ipcc 3>;
++ mbox-names = "vq0", "vq1", "shutdown", "detach";
+ interrupt-parent = <&exti>;
+ interrupts = <68 1>;
+ status = "okay";
+--
+2.40.1
+
--- /dev/null
+From 9222297c534340a389ab4ef0bd81b66e2d548e59 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 May 2023 14:45:34 +0200
+Subject: ARM: dts: stm32: adopt generic iio bindings for adc channels on
+ emstamp-argon
+
+From: Olivier Moysan <olivier.moysan@foss.st.com>
+
+[ Upstream commit c46e9b6cc98245f7264a8d15394d1f95d433abec ]
+
+Use STM32 ADC generic bindings instead of legacy bindings on
+emtrion GmbH Argon boards.
+
+The STM32 ADC specific binding to declare channels has been deprecated,
+hence adopt the generic IIO channels bindings, instead.
+The STM32MP151 device tree now exposes internal channels using the
+generic binding. This makes the change mandatory here to avoid a mixed
+use of legacy and generic binding, which is not supported by the driver.
+
+Signed-off-by: Olivier Moysan <olivier.moysan@foss.st.com>
+Signed-off-by: Alexandre Torgue <alexandre.torgue@foss.st.com>
+Stable-dep-of: 0ee0ef38aa9f ("ARM: dts: stm32: Add missing detach mailbox for emtrion emSBC-Argon")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/stm32mp157c-emstamp-argon.dtsi | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/stm32mp157c-emstamp-argon.dtsi b/arch/arm/boot/dts/stm32mp157c-emstamp-argon.dtsi
+index b01470a9a3d53..94e38141af672 100644
+--- a/arch/arm/boot/dts/stm32mp157c-emstamp-argon.dtsi
++++ b/arch/arm/boot/dts/stm32mp157c-emstamp-argon.dtsi
+@@ -97,9 +97,11 @@ &adc {
+ adc1: adc@0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&adc1_in6_pins_a>;
+- st,min-sample-time-nsecs = <5000>;
+- st,adc-channels = <6>;
+ status = "disabled";
++ channel@6 {
++ reg = <6>;
++ st,min-sample-time-ns = <5000>;
++ };
+ };
+
+ adc2: adc@100 {
+--
+2.40.1
+
--- /dev/null
+From be3cf171633d3f54a9e653b776ce7bc8c796b419 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 May 2023 14:45:37 +0200
+Subject: ARM: dts: stm32: Update to generic ADC channel binding on DHSOM
+ systems
+
+From: Marek Vasut <marex@denx.de>
+
+[ Upstream commit 9bcfc3cdc903485a52c6f471f4ae96a41fa51803 ]
+
+The generic ADC channel binding is recommended over legacy one, update the
+DT to the modern binding. No functional change. For further details, see
+commit which adds the generic binding to STM32 ADC binding document:
+'664b9879f56e ("dt-bindings: iio: stm32-adc: add generic channel binding")'
+
+Signed-off-by: Marek Vasut <marex@denx.de>
+Signed-off-by: Alexandre Torgue <alexandre.torgue@foss.st.com>
+Stable-dep-of: deb7edbc27a6 ("ARM: dts: stm32: Add missing detach mailbox for DHCOM SoM")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi | 18 +++++----
+ .../boot/dts/stm32mp15xx-dhcor-avenger96.dtsi | 38 +++++++++++++++----
+ 2 files changed, 40 insertions(+), 16 deletions(-)
+
+diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi
+index c06edd2eacb0c..e61df23d361a7 100644
+--- a/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi
++++ b/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi
+@@ -80,17 +80,19 @@ &adc {
+ vdda-supply = <&vdda>;
+ vref-supply = <&vdda>;
+ status = "okay";
++};
+
+- adc1: adc@0 {
+- st,min-sample-time-nsecs = <5000>;
+- st,adc-channels = <0>;
+- status = "okay";
++&adc1 {
++ channel@0 {
++ reg = <0>;
++ st,min-sample-time-ns = <5000>;
+ };
++};
+
+- adc2: adc@100 {
+- st,adc-channels = <1>;
+- st,min-sample-time-nsecs = <5000>;
+- status = "okay";
++&adc2 {
++ channel@1 {
++ reg = <1>;
++ st,min-sample-time-ns = <5000>;
+ };
+ };
+
+diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi
+index 7d5d6d4360385..c792dff433fc5 100644
+--- a/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi
++++ b/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi
+@@ -111,17 +111,39 @@ &adc {
+ vdda-supply = <&vdda>;
+ vref-supply = <&vdda>;
+ status = "okay";
++};
+
+- adc1: adc@0 {
+- st,adc-channels = <0 1 6>;
+- st,min-sample-time-nsecs = <5000>;
+- status = "okay";
++&adc1 {
++ channel@0 {
++ reg = <0>;
++ st,min-sample-time-ns = <5000>;
+ };
+
+- adc2: adc@100 {
+- st,adc-channels = <0 1 2>;
+- st,min-sample-time-nsecs = <5000>;
+- status = "okay";
++ channel@1 {
++ reg = <1>;
++ st,min-sample-time-ns = <5000>;
++ };
++
++ channel@6 {
++ reg = <6>;
++ st,min-sample-time-ns = <5000>;
++ };
++};
++
++&adc2 {
++ channel@0 {
++ reg = <0>;
++ st,min-sample-time-ns = <5000>;
++ };
++
++ channel@1 {
++ reg = <1>;
++ st,min-sample-time-ns = <5000>;
++ };
++
++ channel@2 {
++ reg = <2>;
++ st,min-sample-time-ns = <5000>;
+ };
+ };
+
+--
+2.40.1
+
--- /dev/null
+From 282f6ef5cd147681c0f43668866780a0d95a62e7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Aug 2023 12:54:18 -0700
+Subject: ARM: ptrace: Restore syscall restart tracing
+
+From: Kees Cook <keescook@chromium.org>
+
+[ Upstream commit cf007647475b5090819c5fe8da771073145c7334 ]
+
+Since commit 4e57a4ddf6b0 ("ARM: 9107/1: syscall: always store
+thread_info->abi_syscall"), the seccomp selftests "syscall_restart" has
+been broken. This was caused by the restart syscall not being stored to
+"abi_syscall" during restart setup before branching to the "local_restart"
+label. Tracers would see the wrong syscall, and scno would get overwritten
+while returning from the TIF_WORK path. Add the missing store.
+
+Cc: Russell King <linux@armlinux.org.uk>
+Cc: Arnd Bergmann <arnd@kernel.org>
+Cc: Lecopzer Chen <lecopzer.chen@mediatek.com>
+Cc: Oleg Nesterov <oleg@redhat.com>
+Cc: linux-arm-kernel@lists.infradead.org
+Fixes: 4e57a4ddf6b0 ("ARM: 9107/1: syscall: always store thread_info->abi_syscall")
+Reviewed-by: Arnd Bergmann <arnd@arndb.de>
+Link: https://lore.kernel.org/r/20230810195422.2304827-1-keescook@chromium.org
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/kernel/entry-common.S | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
+index 03d4c5578c5c9..b60bba3c1d516 100644
+--- a/arch/arm/kernel/entry-common.S
++++ b/arch/arm/kernel/entry-common.S
+@@ -90,6 +90,7 @@ slow_work_pending:
+ cmp r0, #0
+ beq no_work_pending
+ movlt scno, #(__NR_restart_syscall - __NR_SYSCALL_BASE)
++ str scno, [tsk, #TI_ABI_SYSCALL] @ make sure tracers see update
+ ldmia sp, {r0 - r6} @ have to reload r0 - r6
+ b local_restart @ ... and off we go
+ ENDPROC(ret_fast_syscall)
+--
+2.40.1
+
--- /dev/null
+From a605f0b49fbd521349da18fc16fb71322a3ea3bc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Aug 2023 12:54:19 -0700
+Subject: ARM: ptrace: Restore syscall skipping for tracers
+
+From: Kees Cook <keescook@chromium.org>
+
+[ Upstream commit 4697b5848bd933f68ebd04836362c8de0cacaf71 ]
+
+Since commit 4e57a4ddf6b0 ("ARM: 9107/1: syscall: always store
+thread_info->abi_syscall"), the seccomp selftests "syscall_errno"
+and "syscall_faked" have been broken. Both seccomp and PTRACE depend
+on using the special value of "-1" for skipping syscalls. This value
+wasn't working because it was getting masked by __NR_SYSCALL_MASK in
+both PTRACE_SET_SYSCALL and get_syscall_nr().
+
+Explicitly test for -1 in PTRACE_SET_SYSCALL and get_syscall_nr(),
+leaving it exposed when present, allowing tracers to skip syscalls
+again.
+
+Cc: Russell King <linux@armlinux.org.uk>
+Cc: Arnd Bergmann <arnd@kernel.org>
+Cc: Lecopzer Chen <lecopzer.chen@mediatek.com>
+Cc: Oleg Nesterov <oleg@redhat.com>
+Cc: linux-arm-kernel@lists.infradead.org
+Fixes: 4e57a4ddf6b0 ("ARM: 9107/1: syscall: always store thread_info->abi_syscall")
+Reviewed-by: Arnd Bergmann <arnd@arndb.de>
+Link: https://lore.kernel.org/r/20230810195422.2304827-2-keescook@chromium.org
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/include/asm/syscall.h | 3 +++
+ arch/arm/kernel/ptrace.c | 5 +++--
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/include/asm/syscall.h b/arch/arm/include/asm/syscall.h
+index dfeed440254a8..fe4326d938c18 100644
+--- a/arch/arm/include/asm/syscall.h
++++ b/arch/arm/include/asm/syscall.h
+@@ -25,6 +25,9 @@ static inline int syscall_get_nr(struct task_struct *task,
+ if (IS_ENABLED(CONFIG_AEABI) && !IS_ENABLED(CONFIG_OABI_COMPAT))
+ return task_thread_info(task)->abi_syscall;
+
++ if (task_thread_info(task)->abi_syscall == -1)
++ return -1;
++
+ return task_thread_info(task)->abi_syscall & __NR_SYSCALL_MASK;
+ }
+
+diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
+index 2d8e2516906b6..fef32d73f9120 100644
+--- a/arch/arm/kernel/ptrace.c
++++ b/arch/arm/kernel/ptrace.c
+@@ -783,8 +783,9 @@ long arch_ptrace(struct task_struct *child, long request,
+ break;
+
+ case PTRACE_SET_SYSCALL:
+- task_thread_info(child)->abi_syscall = data &
+- __NR_SYSCALL_MASK;
++ if (data != -1)
++ data &= __NR_SYSCALL_MASK;
++ task_thread_info(child)->abi_syscall = data;
+ ret = 0;
+ break;
+
+--
+2.40.1
+
--- /dev/null
+From 0924ed21ac05d325910a01117d7ce825d639d80e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Apr 2023 12:51:24 +0300
+Subject: arm64: defconfig: Drop CONFIG_VIDEO_IMX_MEDIA
+
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+
+[ Upstream commit 0ca2fbab99b12bb81fceaafe5495c00d76789a37 ]
+
+CONFIG_VIDEO_IMX_MEDIA isn't needed on arm64 platforms since commit
+9f257f502c2e ("media: imx: Unstage the imx7-media-csi driver") which
+moved the last arm64 driver depending on that Kconfig symbol out of
+staging. Drop it from the arm64 defconfig.
+
+Fixes: 9f257f502c2e ("media: imx: Unstage the imx7-media-csi driver")
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/configs/defconfig | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
+index d3cea343a4c3d..fdfe54f35cf8e 100644
+--- a/arch/arm64/configs/defconfig
++++ b/arch/arm64/configs/defconfig
+@@ -1107,7 +1107,6 @@ CONFIG_XEN_GNTDEV=y
+ CONFIG_XEN_GRANT_DEV_ALLOC=y
+ CONFIG_STAGING=y
+ CONFIG_STAGING_MEDIA=y
+-CONFIG_VIDEO_IMX_MEDIA=m
+ CONFIG_VIDEO_MAX96712=m
+ CONFIG_CHROME_PLATFORMS=y
+ CONFIG_CROS_EC=y
+--
+2.40.1
+
--- /dev/null
+From 699ecd77f7c12f4e61d482182d472adf754539ab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Jun 2023 15:54:04 +0300
+Subject: arm64: defconfig: enable Qualcomm MSM8996 Global Clock Controller as
+ built-in
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit dc015a3a6d6986c41a7bd12fb205a282f685e328 ]
+
+The commit 8f680c287445 ("arm64: defconfig: Switch msm8996 clk drivers
+to module") switched CONFIG_MSM_MMCC_8996 to module, which also resulted
+in CONFIG_MSM_GCC_8996 being switched to module. This breaks useful
+bootflow for Qualcomm MSM8996 / APQ8096 platforms, because the serial is
+not enabled anymore until the GCC module is loaded.
+
+Reported-by: Rob Clark <robdclark@gmail.com>
+Fixes: 8f680c287445 ("arm64: defconfig: Switch msm8996 clk drivers to module")
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230619125404.562137-1-dmitry.baryshkov@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/configs/defconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
+index a24609e14d50e..d3cea343a4c3d 100644
+--- a/arch/arm64/configs/defconfig
++++ b/arch/arm64/configs/defconfig
+@@ -1159,6 +1159,7 @@ CONFIG_IPQ_GCC_8074=y
+ CONFIG_IPQ_GCC_9574=y
+ CONFIG_MSM_GCC_8916=y
+ CONFIG_MSM_GCC_8994=y
++CONFIG_MSM_GCC_8996=y
+ CONFIG_MSM_MMCC_8994=m
+ CONFIG_MSM_MMCC_8996=m
+ CONFIG_MSM_MMCC_8998=m
+--
+2.40.1
+
--- /dev/null
+From a72ea28450be827039e50d50ad51595592340560 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Aug 2023 09:10:23 +0200
+Subject: arm64: dts: imx8mp-debix: remove unused fec pinctrl node
+
+From: Marco Felsch <m.felsch@pengutronix.de>
+
+[ Upstream commit 574e4099d787c2eb41a43f14c453e422515bf658 ]
+
+The SoM A uses the EQOS ethernet interface and not the FEC, so drop the
+interface pinctrl node from the device tree.
+
+Fixes: c86d350aae68 ("arm64: dts: Add device tree for the Debix Model A Board")
+Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../dts/freescale/imx8mp-debix-model-a.dts | 22 -------------------
+ 1 file changed, 22 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/freescale/imx8mp-debix-model-a.dts b/arch/arm64/boot/dts/freescale/imx8mp-debix-model-a.dts
+index b4409349eb3f6..1004ab0abb131 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mp-debix-model-a.dts
++++ b/arch/arm64/boot/dts/freescale/imx8mp-debix-model-a.dts
+@@ -355,28 +355,6 @@ MX8MP_IOMUXC_SAI1_TXD6__GPIO4_IO18 0x19
+ >;
+ };
+
+- pinctrl_fec: fecgrp {
+- fsl,pins = <
+- MX8MP_IOMUXC_SAI1_RXD2__ENET1_MDC 0x3
+- MX8MP_IOMUXC_SAI1_RXD3__ENET1_MDIO 0x3
+- MX8MP_IOMUXC_SAI1_RXD4__ENET1_RGMII_RD0 0x91
+- MX8MP_IOMUXC_SAI1_RXD5__ENET1_RGMII_RD1 0x91
+- MX8MP_IOMUXC_SAI1_RXD6__ENET1_RGMII_RD2 0x91
+- MX8MP_IOMUXC_SAI1_RXD7__ENET1_RGMII_RD3 0x91
+- MX8MP_IOMUXC_SAI1_TXC__ENET1_RGMII_RXC 0x91
+- MX8MP_IOMUXC_SAI1_TXFS__ENET1_RGMII_RX_CTL 0x91
+- MX8MP_IOMUXC_SAI1_TXD0__ENET1_RGMII_TD0 0x1f
+- MX8MP_IOMUXC_SAI1_TXD1__ENET1_RGMII_TD1 0x1f
+- MX8MP_IOMUXC_SAI1_TXD2__ENET1_RGMII_TD2 0x1f
+- MX8MP_IOMUXC_SAI1_TXD3__ENET1_RGMII_TD3 0x1f
+- MX8MP_IOMUXC_SAI1_TXD4__ENET1_RGMII_TX_CTL 0x1f
+- MX8MP_IOMUXC_SAI1_TXD5__ENET1_RGMII_TXC 0x1f
+- MX8MP_IOMUXC_SAI1_RXD1__ENET1_1588_EVENT1_OUT 0x1f
+- MX8MP_IOMUXC_SAI1_RXD0__ENET1_1588_EVENT1_IN 0x1f
+- MX8MP_IOMUXC_SAI1_TXD7__GPIO4_IO19 0x19
+- >;
+- };
+-
+ pinctrl_gpio_led: gpioledgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_NAND_READY_B__GPIO3_IO16 0x19
+--
+2.40.1
+
--- /dev/null
+From 44baa348fcee1ff10eefe58aadb3df822822b2c2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 12 Aug 2023 00:47:33 +0100
+Subject: arm64: dts: qcom: apq8016-sbc: Fix ov5640 regulator supply names
+
+From: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+
+[ Upstream commit 43a684580819e7f35b6cb38236be63c4cba26ef4 ]
+
+The ov5640 driver expects DOVDD, AVDD and DVDD as regulator supply names.
+
+The ov5640 has depended on these names since the driver was committed
+upstream in 2017. Similarly apq8016-sbc.dtsi has had completely different
+regulator names since its own initial commit in 2020.
+
+Perhaps the regulators were left on in previous 410c bootloaders. In any
+case today on 6.5 we won't switch on the ov5640 without correctly naming
+the regulators.
+
+Fixes: 39e0ce6cd1bf ("arm64: dts: qcom: apq8016-sbc: Add CCI/Sensor nodes")
+Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230811234738.2859417-3-bryan.odonoghue@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/apq8016-sbc.dts | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts
+index 3ec449f5cab78..7261cfc99f9fa 100644
+--- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts
++++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts
+@@ -285,9 +285,9 @@ camera_rear@3b {
+ clock-names = "xclk";
+ clock-frequency = <23880000>;
+
+- vdddo-supply = <&camera_vdddo_1v8>;
+- vdda-supply = <&camera_vdda_2v8>;
+- vddd-supply = <&camera_vddd_1v5>;
++ DOVDD-supply = <&camera_vdddo_1v8>;
++ AVDD-supply = <&camera_vdda_2v8>;
++ DVDD-supply = <&camera_vddd_1v5>;
+
+ /* No camera mezzanine by default */
+ status = "disabled";
+--
+2.40.1
+
--- /dev/null
+From 2c6dbb19c7889da495ff69e270dfe6bbca1016fa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 12 Aug 2023 00:47:36 +0100
+Subject: arm64: dts: qcom: apq8016-sbc: Rename ov5640 enable-gpios to
+ powerdown-gpios
+
+From: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+
+[ Upstream commit 4facccb44a82129195878750eed8f9890091c1b8 ]
+
+There are two control lines controlled by GPIO going into ov5640
+
+- Reset
+- Powerdown
+
+The driver and yaml expect "reset-gpios" and "powerdown-gpios" there has
+never been an "enable-gpios".
+
+Fixes: 39e0ce6cd1bf ("arm64: dts: qcom: apq8016-sbc: Add CCI/Sensor nodes")
+Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230811234738.2859417-6-bryan.odonoghue@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/apq8016-sbc.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts
+index 80a6526779849..fa92a870cfc40 100644
+--- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts
++++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts
+@@ -276,7 +276,7 @@ camera_rear@3b {
+ compatible = "ovti,ov5640";
+ reg = <0x3b>;
+
+- enable-gpios = <&tlmm 34 GPIO_ACTIVE_HIGH>;
++ powerdown-gpios = <&tlmm 34 GPIO_ACTIVE_HIGH>;
+ reset-gpios = <&tlmm 35 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&camera_rear_default>;
+--
+2.40.1
+
--- /dev/null
+From fbdcd838bcaf781e5f0d916cbaf10fb941e8cf99 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 May 2023 20:48:46 +0200
+Subject: arm64: dts: qcom: msm8916: Define regulator constraints next to usage
+
+From: Stephan Gerhold <stephan@gerhold.net>
+
+[ Upstream commit b0a8f16ae4a0eb423122256691849b3ebc64efc2 ]
+
+Right now each MSM8916 device has a huge block of regulator constraints
+with allowed voltages for each regulator. For lack of better
+documentation these voltages are often copied as-is from the vendor
+device tree, without much extra thought.
+
+Unfortunately, the voltages in the vendor device trees are often
+misleading or even wrong, e.g. because:
+
+ - There is a large voltage range allowed and the actual voltage is
+ only set somewhere hidden in some messy vendor driver. This is often
+ the case for pm8916_{l14,l15,l16} because they have a broad range of
+ 1.8-3.3V by default.
+
+ - The voltage is actually wrong but thanks to the voltage constraints
+ in the RPM firmware it still ends up applying the correct voltage.
+
+To have proper regulator constraints it is important to review them in
+context of the usage. The current setup in the MSM8916 device trees
+makes this quite hard because each device duplicates the standard
+voltages for components of the SoC and mixes those with minor
+device-specific additions and dummy voltages for completely unused
+regulators.
+
+The actual usage of the regulators for the SoC components is in
+msm8916-pm8916.dtsi, so it can and should also define the related
+voltage constraints. These are not board-specific but defined in the
+APQ8016E/PM8916 Device Specification. The board DT can then focus on
+describing the actual board-specific regulators, which makes it much
+easier to review and spot potential mistakes there.
+
+Note that this commit does not make any functional change. All used
+regulators still have the same regulator constraints as before. Unused
+regulators do not have regulator constraints anymore because most of
+these were too broad or even entirely wrong. They should be added back
+with proper voltage constraints when there is an actual usage.
+
+Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230510-msm8916-regulators-v1-7-54d4960a05fc@gerhold.net
+Stable-dep-of: 4facccb44a82 ("arm64: dts: qcom: apq8016-sbc: Rename ov5640 enable-gpios to powerdown-gpios")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/apq8016-sbc.dts | 153 ++++--------------
+ .../boot/dts/qcom/msm8916-acer-a1-724.dts | 115 ++-----------
+ .../boot/dts/qcom/msm8916-alcatel-idol347.dts | 110 +------------
+ .../arm64/boot/dts/qcom/msm8916-asus-z00l.dts | 110 +------------
+ .../boot/dts/qcom/msm8916-gplus-fl8005a.dts | 110 +------------
+ .../arm64/boot/dts/qcom/msm8916-huawei-g7.dts | 120 ++------------
+ .../boot/dts/qcom/msm8916-longcheer-l8150.dts | 110 +------------
+ .../boot/dts/qcom/msm8916-longcheer-l8910.dts | 110 +------------
+ arch/arm64/boot/dts/qcom/msm8916-pm8916.dtsi | 102 +++++++++---
+ .../qcom/msm8916-samsung-a2015-common.dtsi | 110 +------------
+ .../dts/qcom/msm8916-samsung-gt5-common.dtsi | 110 +------------
+ .../dts/qcom/msm8916-samsung-j5-common.dtsi | 103 ------------
+ .../dts/qcom/msm8916-samsung-serranove.dts | 103 ------------
+ arch/arm64/boot/dts/qcom/msm8916-ufi.dtsi | 103 ------------
+ .../dts/qcom/msm8916-wingtech-wt88047.dts | 119 ++------------
+ 15 files changed, 210 insertions(+), 1478 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts
+index 73c51fa101c8b..b3de394c01510 100644
+--- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts
++++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts
+@@ -329,6 +329,40 @@ &pm8916_resin {
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+
++&pm8916_rpm_regulators {
++ /*
++ * The 96Boards specification expects a 1.8V power rail on the low-speed
++ * expansion connector that is able to provide at least 0.18W / 100 mA.
++ * L15/L16 are connected in parallel to provide 55 mA each. A minimum load
++ * must be specified to ensure the regulators are not put in LPM where they
++ * would only provide 5 mA.
++ */
++ pm8916_l15: l15 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-system-load = <50000>;
++ regulator-allow-set-load;
++ regulator-always-on;
++ };
++ pm8916_l16: l16 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-system-load = <50000>;
++ regulator-allow-set-load;
++ regulator-always-on;
++ };
++
++ pm8916_l17: l17 {
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ };
++};
++
++&pm8916_s4 {
++ regulator-always-on;
++ regulator-boot-on;
++};
++
+ &sdhc_1 {
+ status = "okay";
+
+@@ -446,125 +480,6 @@ &wcnss_iris {
+ &stm { status = "okay"; };
+ &tpiu { status = "okay"; };
+
+-&smd_rpm_regulators {
+- vdd_l1_l2_l3-supply = <&pm8916_s3>;
+- vdd_l4_l5_l6-supply = <&pm8916_s4>;
+- vdd_l7-supply = <&pm8916_s4>;
+-
+- s3 {
+- regulator-min-microvolt = <1250000>;
+- regulator-max-microvolt = <1350000>;
+- };
+-
+- s4 {
+- regulator-min-microvolt = <1850000>;
+- regulator-max-microvolt = <2150000>;
+-
+- regulator-always-on;
+- regulator-boot-on;
+- };
+-
+- l1 {
+- regulator-min-microvolt = <1225000>;
+- regulator-max-microvolt = <1225000>;
+- };
+-
+- l2 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1200000>;
+- };
+-
+- l4 {
+- regulator-min-microvolt = <2050000>;
+- regulator-max-microvolt = <2050000>;
+- };
+-
+- l5 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l6 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l7 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l8 {
+- regulator-min-microvolt = <2900000>;
+- regulator-max-microvolt = <2900000>;
+- };
+-
+- l9 {
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l10 {
+- regulator-min-microvolt = <2800000>;
+- regulator-max-microvolt = <2800000>;
+- };
+-
+- l11 {
+- regulator-min-microvolt = <2950000>;
+- regulator-max-microvolt = <2950000>;
+- regulator-allow-set-load;
+- regulator-system-load = <200000>;
+- };
+-
+- l12 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2950000>;
+- };
+-
+- l13 {
+- regulator-min-microvolt = <3075000>;
+- regulator-max-microvolt = <3075000>;
+- };
+-
+- l14 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- /*
+- * The 96Boards specification expects a 1.8V power rail on the low-speed
+- * expansion connector that is able to provide at least 0.18W / 100 mA.
+- * L15/L16 are connected in parallel to provide 55 mA each. A minimum load
+- * must be specified to ensure the regulators are not put in LPM where they
+- * would only provide 5 mA.
+- */
+- l15 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- regulator-system-load = <50000>;
+- regulator-allow-set-load;
+- regulator-always-on;
+- };
+-
+- l16 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- regulator-system-load = <50000>;
+- regulator-allow-set-load;
+- regulator-always-on;
+- };
+-
+- l17 {
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l18 {
+- regulator-min-microvolt = <2700000>;
+- regulator-max-microvolt = <2700000>;
+- };
+-};
+-
+ /*
+ * 2mA drive strength is not enough when connecting multiple
+ * I2C devices with different pull up resistors.
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-acer-a1-724.dts b/arch/arm64/boot/dts/qcom/msm8916-acer-a1-724.dts
+index 0d517804e44ed..753413b48751a 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-acer-a1-724.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-acer-a1-724.dts
+@@ -114,6 +114,18 @@ &pm8916_resin {
+ status = "okay";
+ };
+
++&pm8916_rpm_regulators {
++ pm8916_l16: l16 {
++ regulator-min-microvolt = <2900000>;
++ regulator-max-microvolt = <2900000>;
++ };
++
++ pm8916_l17: l17 {
++ regulator-min-microvolt = <2850000>;
++ regulator-max-microvolt = <2850000>;
++ };
++};
++
+ &pm8916_vib {
+ status = "okay";
+ };
+@@ -153,109 +165,6 @@ &wcnss_iris {
+ compatible = "qcom,wcn3620";
+ };
+
+-&smd_rpm_regulators {
+- vdd_l1_l2_l3-supply = <&pm8916_s3>;
+- vdd_l4_l5_l6-supply = <&pm8916_s4>;
+- vdd_l7-supply = <&pm8916_s4>;
+-
+- s3 {
+- regulator-min-microvolt = <1250000>;
+- regulator-max-microvolt = <1350000>;
+- };
+-
+- s4 {
+- regulator-min-microvolt = <1850000>;
+- regulator-max-microvolt = <2150000>;
+- };
+-
+- l1 {
+- regulator-min-microvolt = <1225000>;
+- regulator-max-microvolt = <1225000>;
+- };
+-
+- l2 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1200000>;
+- };
+-
+- l4 {
+- regulator-min-microvolt = <2050000>;
+- regulator-max-microvolt = <2050000>;
+- };
+-
+- l5 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l6 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l7 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l8 {
+- regulator-min-microvolt = <2900000>;
+- regulator-max-microvolt = <2900000>;
+- };
+-
+- l9 {
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l10 {
+- regulator-min-microvolt = <2800000>;
+- regulator-max-microvolt = <2800000>;
+- };
+-
+- l11 {
+- regulator-min-microvolt = <2950000>;
+- regulator-max-microvolt = <2950000>;
+- regulator-system-load = <200000>;
+- regulator-allow-set-load;
+- };
+-
+- l12 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2950000>;
+- };
+-
+- l13 {
+- regulator-min-microvolt = <3075000>;
+- regulator-max-microvolt = <3075000>;
+- };
+-
+- l14 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l15 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l16 {
+- regulator-min-microvolt = <2900000>;
+- regulator-max-microvolt = <2900000>;
+- };
+-
+- l17 {
+- regulator-min-microvolt = <2850000>;
+- regulator-max-microvolt = <2850000>;
+- };
+-
+- l18 {
+- regulator-min-microvolt = <2700000>;
+- regulator-max-microvolt = <2700000>;
+- };
+-};
+-
+ &msmgpio {
+ accel_int_default: accel-int-default-state {
+ pins = "gpio115";
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-alcatel-idol347.dts b/arch/arm64/boot/dts/qcom/msm8916-alcatel-idol347.dts
+index ddd64cc469983..4bfbad669b1ea 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-alcatel-idol347.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-alcatel-idol347.dts
+@@ -156,6 +156,13 @@ &pm8916_resin {
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+
++&pm8916_rpm_regulators {
++ pm8916_l17: l17 {
++ regulator-min-microvolt = <2850000>;
++ regulator-max-microvolt = <2850000>;
++ };
++};
++
+ &pm8916_vib {
+ status = "okay";
+ };
+@@ -195,109 +202,6 @@ &wcnss_iris {
+ compatible = "qcom,wcn3620";
+ };
+
+-&smd_rpm_regulators {
+- vdd_l1_l2_l3-supply = <&pm8916_s3>;
+- vdd_l4_l5_l6-supply = <&pm8916_s4>;
+- vdd_l7-supply = <&pm8916_s4>;
+-
+- s3 {
+- regulator-min-microvolt = <1250000>;
+- regulator-max-microvolt = <1350000>;
+- };
+-
+- s4 {
+- regulator-min-microvolt = <1850000>;
+- regulator-max-microvolt = <2150000>;
+- };
+-
+- l1 {
+- regulator-min-microvolt = <1225000>;
+- regulator-max-microvolt = <1225000>;
+- };
+-
+- l2 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1200000>;
+- };
+-
+- l4 {
+- regulator-min-microvolt = <2050000>;
+- regulator-max-microvolt = <2050000>;
+- };
+-
+- l5 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l6 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l7 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l8 {
+- regulator-min-microvolt = <2900000>;
+- regulator-max-microvolt = <2900000>;
+- };
+-
+- l9 {
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l10 {
+- regulator-min-microvolt = <2800000>;
+- regulator-max-microvolt = <2800000>;
+- };
+-
+- l11 {
+- regulator-min-microvolt = <2950000>;
+- regulator-max-microvolt = <2950000>;
+- regulator-allow-set-load;
+- regulator-system-load = <200000>;
+- };
+-
+- l12 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2950000>;
+- };
+-
+- l13 {
+- regulator-min-microvolt = <3075000>;
+- regulator-max-microvolt = <3075000>;
+- };
+-
+- l14 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l15 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l16 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l17 {
+- regulator-min-microvolt = <2850000>;
+- regulator-max-microvolt = <2850000>;
+- };
+-
+- l18 {
+- regulator-min-microvolt = <2700000>;
+- regulator-max-microvolt = <2700000>;
+- };
+-};
+-
+ &msmgpio {
+ accel_int_default: accel-int-default-state {
+ pins = "gpio31";
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-asus-z00l.dts b/arch/arm64/boot/dts/qcom/msm8916-asus-z00l.dts
+index 982457503a3cc..37755e8853958 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-asus-z00l.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-asus-z00l.dts
+@@ -128,6 +128,13 @@ &blsp1_uart2 {
+ status = "okay";
+ };
+
++&pm8916_rpm_regulators {
++ pm8916_l17: l17 {
++ regulator-min-microvolt = <2850000>;
++ regulator-max-microvolt = <2850000>;
++ };
++};
++
+ &sdhc_1 {
+ status = "okay";
+
+@@ -163,109 +170,6 @@ &wcnss_iris {
+ compatible = "qcom,wcn3620";
+ };
+
+-&smd_rpm_regulators {
+- vdd_l1_l2_l3-supply = <&pm8916_s3>;
+- vdd_l4_l5_l6-supply = <&pm8916_s4>;
+- vdd_l7-supply = <&pm8916_s4>;
+-
+- s3 {
+- regulator-min-microvolt = <1250000>;
+- regulator-max-microvolt = <1350000>;
+- };
+-
+- s4 {
+- regulator-min-microvolt = <1850000>;
+- regulator-max-microvolt = <2150000>;
+- };
+-
+- l1 {
+- regulator-min-microvolt = <1225000>;
+- regulator-max-microvolt = <1225000>;
+- };
+-
+- l2 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1200000>;
+- };
+-
+- l4 {
+- regulator-min-microvolt = <2050000>;
+- regulator-max-microvolt = <2050000>;
+- };
+-
+- l5 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l6 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l7 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l8 {
+- regulator-min-microvolt = <2900000>;
+- regulator-max-microvolt = <2900000>;
+- };
+-
+- l9 {
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l10 {
+- regulator-min-microvolt = <2800000>;
+- regulator-max-microvolt = <2800000>;
+- };
+-
+- l11 {
+- regulator-min-microvolt = <2950000>;
+- regulator-max-microvolt = <2950000>;
+- regulator-allow-set-load;
+- regulator-system-load = <200000>;
+- };
+-
+- l12 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2950000>;
+- };
+-
+- l13 {
+- regulator-min-microvolt = <3075000>;
+- regulator-max-microvolt = <3075000>;
+- };
+-
+- l14 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l15 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l16 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l17 {
+- regulator-min-microvolt = <2850000>;
+- regulator-max-microvolt = <2850000>;
+- };
+-
+- l18 {
+- regulator-min-microvolt = <2700000>;
+- regulator-max-microvolt = <2700000>;
+- };
+-};
+-
+ &msmgpio {
+ gpio_keys_default: gpio-keys-default-state {
+ pins = "gpio107", "gpio117";
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-gplus-fl8005a.dts b/arch/arm64/boot/dts/qcom/msm8916-gplus-fl8005a.dts
+index 9584d271c5260..4a6bf99c755fd 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-gplus-fl8005a.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-gplus-fl8005a.dts
+@@ -114,6 +114,13 @@ &pm8916_resin {
+ status = "okay";
+ };
+
++&pm8916_rpm_regulators {
++ pm8916_l17: l17 {
++ regulator-min-microvolt = <2850000>;
++ regulator-max-microvolt = <2850000>;
++ };
++};
++
+ &pm8916_vib {
+ status = "okay";
+ };
+@@ -153,109 +160,6 @@ &wcnss_iris {
+ compatible = "qcom,wcn3620";
+ };
+
+-&smd_rpm_regulators {
+- vdd_l1_l2_l3-supply = <&pm8916_s3>;
+- vdd_l4_l5_l6-supply = <&pm8916_s4>;
+- vdd_l7-supply = <&pm8916_s4>;
+-
+- s3 {
+- regulator-min-microvolt = <1250000>;
+- regulator-max-microvolt = <1350000>;
+- };
+-
+- s4 {
+- regulator-min-microvolt = <1850000>;
+- regulator-max-microvolt = <2150000>;
+- };
+-
+- l1 {
+- regulator-min-microvolt = <1225000>;
+- regulator-max-microvolt = <1225000>;
+- };
+-
+- l2 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1200000>;
+- };
+-
+- l4 {
+- regulator-min-microvolt = <2050000>;
+- regulator-max-microvolt = <2050000>;
+- };
+-
+- l5 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l6 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l7 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l8 {
+- regulator-min-microvolt = <2900000>;
+- regulator-max-microvolt = <2900000>;
+- };
+-
+- l9 {
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l10 {
+- regulator-min-microvolt = <2800000>;
+- regulator-max-microvolt = <2800000>;
+- };
+-
+- l11 {
+- regulator-min-microvolt = <2950000>;
+- regulator-max-microvolt = <2950000>;
+- regulator-system-load = <200000>;
+- regulator-allow-set-load;
+- };
+-
+- l12 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2950000>;
+- };
+-
+- l13 {
+- regulator-min-microvolt = <3075000>;
+- regulator-max-microvolt = <3075000>;
+- };
+-
+- l14 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l15 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l16 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l17 {
+- regulator-min-microvolt = <2850000>;
+- regulator-max-microvolt = <2850000>;
+- };
+-
+- l18 {
+- regulator-min-microvolt = <2700000>;
+- regulator-max-microvolt = <2700000>;
+- };
+-};
+-
+ &msmgpio {
+ camera_flash_default: camera-flash-default-state {
+ pins = "gpio31", "gpio32";
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-huawei-g7.dts b/arch/arm64/boot/dts/qcom/msm8916-huawei-g7.dts
+index 8197710372ad1..29aaa35438a36 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-huawei-g7.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-huawei-g7.dts
+@@ -222,11 +222,28 @@ &lpass_codec {
+ status = "okay";
+ };
+
++&pm8916_l8 {
++ regulator-min-microvolt = <2950000>;
++ regulator-max-microvolt = <2950000>;
++};
++
+ &pm8916_resin {
+ status = "okay";
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+
++&pm8916_rpm_regulators {
++ pm8916_l16: l16 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ };
++
++ pm8916_l17: l17 {
++ regulator-min-microvolt = <2850000>;
++ regulator-max-microvolt = <2850000>;
++ };
++};
++
+ &pm8916_vib {
+ status = "okay";
+ };
+@@ -321,109 +338,6 @@ &wcnss_iris {
+ compatible = "qcom,wcn3620";
+ };
+
+-&smd_rpm_regulators {
+- vdd_l1_l2_l3-supply = <&pm8916_s3>;
+- vdd_l4_l5_l6-supply = <&pm8916_s4>;
+- vdd_l7-supply = <&pm8916_s4>;
+-
+- s3 {
+- regulator-min-microvolt = <1250000>;
+- regulator-max-microvolt = <1350000>;
+- };
+-
+- s4 {
+- regulator-min-microvolt = <1850000>;
+- regulator-max-microvolt = <2150000>;
+- };
+-
+- l1 {
+- regulator-min-microvolt = <1225000>;
+- regulator-max-microvolt = <1225000>;
+- };
+-
+- l2 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1200000>;
+- };
+-
+- l4 {
+- regulator-min-microvolt = <2050000>;
+- regulator-max-microvolt = <2050000>;
+- };
+-
+- l5 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l6 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l7 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l8 {
+- regulator-min-microvolt = <2950000>;
+- regulator-max-microvolt = <2950000>;
+- };
+-
+- l9 {
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l10 {
+- regulator-min-microvolt = <2800000>;
+- regulator-max-microvolt = <2800000>;
+- };
+-
+- l11 {
+- regulator-min-microvolt = <2950000>;
+- regulator-max-microvolt = <2950000>;
+- regulator-allow-set-load;
+- regulator-system-load = <200000>;
+- };
+-
+- l12 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2950000>;
+- };
+-
+- l13 {
+- regulator-min-microvolt = <3075000>;
+- regulator-max-microvolt = <3075000>;
+- };
+-
+- l14 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l15 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l16 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l17 {
+- regulator-min-microvolt = <2850000>;
+- regulator-max-microvolt = <2850000>;
+- };
+-
+- l18 {
+- regulator-min-microvolt = <2700000>;
+- regulator-max-microvolt = <2700000>;
+- };
+-};
+-
+ &msmgpio {
+ accel_irq_default: accel-irq-default-state {
+ pins = "gpio115";
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts
+index 66e7ba00633f7..e1c352e1da1fe 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts
+@@ -223,6 +223,13 @@ &pm8916_resin {
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+
++&pm8916_rpm_regulators {
++ pm8916_l17: l17 {
++ regulator-min-microvolt = <2850000>;
++ regulator-max-microvolt = <2850000>;
++ };
++};
++
+ &pm8916_usbin {
+ status = "okay";
+ };
+@@ -267,109 +274,6 @@ &wcnss_iris {
+ compatible = "qcom,wcn3620";
+ };
+
+-&smd_rpm_regulators {
+- vdd_l1_l2_l3-supply = <&pm8916_s3>;
+- vdd_l4_l5_l6-supply = <&pm8916_s4>;
+- vdd_l7-supply = <&pm8916_s4>;
+-
+- s3 {
+- regulator-min-microvolt = <1250000>;
+- regulator-max-microvolt = <1350000>;
+- };
+-
+- s4 {
+- regulator-min-microvolt = <1850000>;
+- regulator-max-microvolt = <2150000>;
+- };
+-
+- l1 {
+- regulator-min-microvolt = <1225000>;
+- regulator-max-microvolt = <1225000>;
+- };
+-
+- l2 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1200000>;
+- };
+-
+- l4 {
+- regulator-min-microvolt = <2050000>;
+- regulator-max-microvolt = <2050000>;
+- };
+-
+- l5 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l6 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l7 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l8 {
+- regulator-min-microvolt = <2900000>;
+- regulator-max-microvolt = <2900000>;
+- };
+-
+- l9 {
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l10 {
+- regulator-min-microvolt = <2800000>;
+- regulator-max-microvolt = <2800000>;
+- };
+-
+- l11 {
+- regulator-min-microvolt = <2950000>;
+- regulator-max-microvolt = <2950000>;
+- regulator-allow-set-load;
+- regulator-system-load = <200000>;
+- };
+-
+- l12 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2950000>;
+- };
+-
+- l13 {
+- regulator-min-microvolt = <3075000>;
+- regulator-max-microvolt = <3075000>;
+- };
+-
+- l14 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l15 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l16 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l17 {
+- regulator-min-microvolt = <2850000>;
+- regulator-max-microvolt = <2850000>;
+- };
+-
+- l18 {
+- regulator-min-microvolt = <2700000>;
+- regulator-max-microvolt = <2700000>;
+- };
+-};
+-
+ &msmgpio {
+ accel_int_default: accel-int-default-state {
+ pins = "gpio116";
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8910.dts b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8910.dts
+index 1e0c08770371a..630727ed1ed5a 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8910.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8910.dts
+@@ -110,6 +110,13 @@ &pm8916_resin {
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+
++&pm8916_rpm_regulators {
++ pm8916_l17: l17 {
++ regulator-min-microvolt = <2850000>;
++ regulator-max-microvolt = <2850000>;
++ };
++};
++
+ &pm8916_vib {
+ status = "okay";
+ };
+@@ -149,109 +156,6 @@ &wcnss_iris {
+ compatible = "qcom,wcn3620";
+ };
+
+-&smd_rpm_regulators {
+- vdd_l1_l2_l3-supply = <&pm8916_s3>;
+- vdd_l4_l5_l6-supply = <&pm8916_s4>;
+- vdd_l7-supply = <&pm8916_s4>;
+-
+- s3 {
+- regulator-min-microvolt = <1250000>;
+- regulator-max-microvolt = <1350000>;
+- };
+-
+- s4 {
+- regulator-min-microvolt = <1850000>;
+- regulator-max-microvolt = <2150000>;
+- };
+-
+- l1 {
+- regulator-min-microvolt = <1225000>;
+- regulator-max-microvolt = <1225000>;
+- };
+-
+- l2 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1200000>;
+- };
+-
+- l4 {
+- regulator-min-microvolt = <2050000>;
+- regulator-max-microvolt = <2050000>;
+- };
+-
+- l5 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l6 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l7 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l8 {
+- regulator-min-microvolt = <2900000>;
+- regulator-max-microvolt = <2900000>;
+- };
+-
+- l9 {
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l10 {
+- regulator-min-microvolt = <2800000>;
+- regulator-max-microvolt = <2800000>;
+- };
+-
+- l11 {
+- regulator-min-microvolt = <2950000>;
+- regulator-max-microvolt = <2950000>;
+- regulator-allow-set-load;
+- regulator-system-load = <200000>;
+- };
+-
+- l12 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2950000>;
+- };
+-
+- l13 {
+- regulator-min-microvolt = <3075000>;
+- regulator-max-microvolt = <3075000>;
+- };
+-
+- l14 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l15 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l16 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l17 {
+- regulator-min-microvolt = <2850000>;
+- regulator-max-microvolt = <2850000>;
+- };
+-
+- l18 {
+- regulator-min-microvolt = <2700000>;
+- regulator-max-microvolt = <2700000>;
+- };
+-};
+-
+ &msmgpio {
+ button_backlight_default: button-backlight-default-state {
+ pins = "gpio17";
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-pm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916-pm8916.dtsi
+index 6eb5e0a395100..d83f767ac5bf4 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-pm8916.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8916-pm8916.dtsi
+@@ -47,30 +47,92 @@ &wcnss_iris {
+ };
+
+ &rpm_requests {
+- smd_rpm_regulators: regulators {
++ pm8916_rpm_regulators: regulators {
+ compatible = "qcom,rpm-pm8916-regulators";
++ vdd_l1_l2_l3-supply = <&pm8916_s3>;
++ vdd_l4_l5_l6-supply = <&pm8916_s4>;
++ vdd_l7-supply = <&pm8916_s4>;
+
+ /* pm8916_s1 is managed by rpmpd (MSM8916_VDDCX) */
+- pm8916_s3: s3 {};
+- pm8916_s4: s4 {};
+
+- pm8916_l1: l1 {};
+- pm8916_l2: l2 {};
++ pm8916_s3: s3 {
++ regulator-min-microvolt = <1250000>;
++ regulator-max-microvolt = <1350000>;
++ };
++
++ pm8916_s4: s4 {
++ regulator-min-microvolt = <1850000>;
++ regulator-max-microvolt = <2150000>;
++ };
++
++ /*
++ * Some of the regulators are unused or managed by another
++ * processor (e.g. the modem). We should still define nodes for
++ * them to ensure the vote from the application processor can be
++ * dropped in case the regulators are already on during boot.
++ *
++ * The labels for these nodes are omitted on purpose because
++ * boards should configure a proper voltage before using them.
++ */
++ l1 {};
++
++ pm8916_l2: l2 {
++ regulator-min-microvolt = <1200000>;
++ regulator-max-microvolt = <1200000>;
++ };
++
+ /* pm8916_l3 is managed by rpmpd (MSM8916_VDDMX) */
+- pm8916_l4: l4 {};
+- pm8916_l5: l5 {};
+- pm8916_l6: l6 {};
+- pm8916_l7: l7 {};
+- pm8916_l8: l8 {};
+- pm8916_l9: l9 {};
+- pm8916_l10: l10 {};
+- pm8916_l11: l11 {};
+- pm8916_l12: l12 {};
+- pm8916_l13: l13 {};
+- pm8916_l14: l14 {};
+- pm8916_l15: l15 {};
+- pm8916_l16: l16 {};
+- pm8916_l17: l17 {};
+- pm8916_l18: l18 {};
++
++ l4 {};
++
++ pm8916_l5: l5 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ };
++
++ pm8916_l6: l6 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ };
++
++ pm8916_l7: l7 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ };
++
++ pm8916_l8: l8 {
++ regulator-min-microvolt = <2900000>;
++ regulator-max-microvolt = <2900000>;
++ };
++
++ pm8916_l9: l9 {
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ };
++
++ l10 {};
++
++ pm8916_l11: l11 {
++ regulator-min-microvolt = <2950000>;
++ regulator-max-microvolt = <2950000>;
++ regulator-allow-set-load;
++ regulator-system-load = <200000>;
++ };
++
++ pm8916_l12: l12 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <2950000>;
++ };
++
++ pm8916_l13: l13 {
++ regulator-min-microvolt = <3075000>;
++ regulator-max-microvolt = <3075000>;
++ };
++
++ l14 {};
++ l15 {};
++ l16 {};
++ l17 {};
++ l18 {};
+ };
+ };
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi b/arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi
+index b362a76eebc94..37a872949851b 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi
+@@ -252,6 +252,13 @@ &pm8916_resin {
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+
++&pm8916_rpm_regulators {
++ pm8916_l17: l17 {
++ regulator-min-microvolt = <2850000>;
++ regulator-max-microvolt = <2850000>;
++ };
++};
++
+ &sdhc_1 {
+ status = "okay";
+
+@@ -279,109 +286,6 @@ &usb_hs_phy {
+ extcon = <&muic>;
+ };
+
+-&smd_rpm_regulators {
+- vdd_l1_l2_l3-supply = <&pm8916_s3>;
+- vdd_l4_l5_l6-supply = <&pm8916_s4>;
+- vdd_l7-supply = <&pm8916_s4>;
+-
+- s3 {
+- regulator-min-microvolt = <1250000>;
+- regulator-max-microvolt = <1350000>;
+- };
+-
+- s4 {
+- regulator-min-microvolt = <1850000>;
+- regulator-max-microvolt = <2150000>;
+- };
+-
+- l1 {
+- regulator-min-microvolt = <1225000>;
+- regulator-max-microvolt = <1225000>;
+- };
+-
+- l2 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1200000>;
+- };
+-
+- l4 {
+- regulator-min-microvolt = <2050000>;
+- regulator-max-microvolt = <2050000>;
+- };
+-
+- l5 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l6 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l7 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l8 {
+- regulator-min-microvolt = <2900000>;
+- regulator-max-microvolt = <2900000>;
+- };
+-
+- l9 {
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l10 {
+- regulator-min-microvolt = <2800000>;
+- regulator-max-microvolt = <2800000>;
+- };
+-
+- l11 {
+- regulator-min-microvolt = <2950000>;
+- regulator-max-microvolt = <2950000>;
+- regulator-allow-set-load;
+- regulator-system-load = <200000>;
+- };
+-
+- l12 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2950000>;
+- };
+-
+- l13 {
+- regulator-min-microvolt = <3075000>;
+- regulator-max-microvolt = <3075000>;
+- };
+-
+- l14 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l15 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l16 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l17 {
+- regulator-min-microvolt = <2850000>;
+- regulator-max-microvolt = <2850000>;
+- };
+-
+- l18 {
+- regulator-min-microvolt = <2700000>;
+- regulator-max-microvolt = <2700000>;
+- };
+-};
+-
+ &msmgpio {
+ accel_int_default: accel-int-default-state {
+ pins = "gpio115";
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-gt5-common.dtsi b/arch/arm64/boot/dts/qcom/msm8916-samsung-gt5-common.dtsi
+index 4464beeeaab12..a49e1641e59b8 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-gt5-common.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-gt5-common.dtsi
+@@ -120,6 +120,13 @@ &pm8916_resin {
+ status = "okay";
+ };
+
++&pm8916_rpm_regulators {
++ pm8916_l17: l17 {
++ regulator-min-microvolt = <2850000>;
++ regulator-max-microvolt = <2850000>;
++ };
++};
++
+ /* FIXME: Replace with MAX77849 MUIC when driver is available */
+ &pm8916_usbin {
+ status = "okay";
+@@ -162,109 +169,6 @@ &wcnss_iris {
+ compatible = "qcom,wcn3660b";
+ };
+
+-&smd_rpm_regulators {
+- vdd_l1_l2_l3-supply = <&pm8916_s3>;
+- vdd_l4_l5_l6-supply = <&pm8916_s4>;
+- vdd_l7-supply = <&pm8916_s4>;
+-
+- s3 {
+- regulator-min-microvolt = <1250000>;
+- regulator-max-microvolt = <1350000>;
+- };
+-
+- s4 {
+- regulator-min-microvolt = <1850000>;
+- regulator-max-microvolt = <2150000>;
+- };
+-
+- l1 {
+- regulator-min-microvolt = <1225000>;
+- regulator-max-microvolt = <1225000>;
+- };
+-
+- l2 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1200000>;
+- };
+-
+- l4 {
+- regulator-min-microvolt = <2050000>;
+- regulator-max-microvolt = <2050000>;
+- };
+-
+- l5 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l6 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l7 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l8 {
+- regulator-min-microvolt = <2900000>;
+- regulator-max-microvolt = <2900000>;
+- };
+-
+- l9 {
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l10 {
+- regulator-min-microvolt = <2800000>;
+- regulator-max-microvolt = <2800000>;
+- };
+-
+- l11 {
+- regulator-min-microvolt = <2950000>;
+- regulator-max-microvolt = <2950000>;
+- regulator-system-load = <200000>;
+- regulator-allow-set-load;
+- };
+-
+- l12 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2950000>;
+- };
+-
+- l13 {
+- regulator-min-microvolt = <3075000>;
+- regulator-max-microvolt = <3075000>;
+- };
+-
+- l14 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l15 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l16 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l17 {
+- regulator-min-microvolt = <2850000>;
+- regulator-max-microvolt = <2850000>;
+- };
+-
+- l18 {
+- regulator-min-microvolt = <2700000>;
+- regulator-max-microvolt = <2700000>;
+- };
+-};
+-
+ &msmgpio {
+ accel_int_default: accel-int-default-state {
+ pins = "gpio115";
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-j5-common.dtsi b/arch/arm64/boot/dts/qcom/msm8916-samsung-j5-common.dtsi
+index 6e231e92e6756..6192d04a58ae4 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-j5-common.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-j5-common.dtsi
+@@ -128,109 +128,6 @@ &wcnss_iris {
+ compatible = "qcom,wcn3620";
+ };
+
+-&smd_rpm_regulators {
+- vdd_l1_l2_l3-supply = <&pm8916_s3>;
+- vdd_l4_l5_l6-supply = <&pm8916_s4>;
+- vdd_l7-supply = <&pm8916_s4>;
+-
+- s3 {
+- regulator-min-microvolt = <1250000>;
+- regulator-max-microvolt = <1350000>;
+- };
+-
+- s4 {
+- regulator-min-microvolt = <1850000>;
+- regulator-max-microvolt = <2150000>;
+- };
+-
+- l1 {
+- regulator-min-microvolt = <1225000>;
+- regulator-max-microvolt = <1225000>;
+- };
+-
+- l2 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1200000>;
+- };
+-
+- l4 {
+- regulator-min-microvolt = <2050000>;
+- regulator-max-microvolt = <2050000>;
+- };
+-
+- l5 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l6 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l7 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l8 {
+- regulator-min-microvolt = <2900000>;
+- regulator-max-microvolt = <2900000>;
+- };
+-
+- l9 {
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l10 {
+- regulator-min-microvolt = <2800000>;
+- regulator-max-microvolt = <2800000>;
+- };
+-
+- l11 {
+- regulator-min-microvolt = <2950000>;
+- regulator-max-microvolt = <2950000>;
+- regulator-allow-set-load;
+- regulator-system-load = <200000>;
+- };
+-
+- l12 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2950000>;
+- };
+-
+- l13 {
+- regulator-min-microvolt = <3075000>;
+- regulator-max-microvolt = <3075000>;
+- };
+-
+- l14 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l15 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l16 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l17 {
+- regulator-min-microvolt = <3000000>;
+- regulator-max-microvolt = <3000000>;
+- };
+-
+- l18 {
+- regulator-min-microvolt = <2700000>;
+- regulator-max-microvolt = <2700000>;
+- };
+-};
+-
+ &msmgpio {
+ gpio_hall_sensor_default: gpio-hall-sensor-default-state {
+ pins = "gpio52";
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-serranove.dts b/arch/arm64/boot/dts/qcom/msm8916-samsung-serranove.dts
+index fa5b330aaeaee..fc4c61c4e1e6c 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-serranove.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-serranove.dts
+@@ -320,109 +320,6 @@ &wcnss_iris {
+ compatible = "qcom,wcn3660b";
+ };
+
+-&smd_rpm_regulators {
+- vdd_l1_l2_l3-supply = <&pm8916_s3>;
+- vdd_l4_l5_l6-supply = <&pm8916_s4>;
+- vdd_l7-supply = <&pm8916_s4>;
+-
+- s3 {
+- regulator-min-microvolt = <1250000>;
+- regulator-max-microvolt = <1350000>;
+- };
+-
+- s4 {
+- regulator-min-microvolt = <1850000>;
+- regulator-max-microvolt = <2150000>;
+- };
+-
+- l1 {
+- regulator-min-microvolt = <1225000>;
+- regulator-max-microvolt = <1225000>;
+- };
+-
+- l2 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1200000>;
+- };
+-
+- l4 {
+- regulator-min-microvolt = <2050000>;
+- regulator-max-microvolt = <2050000>;
+- };
+-
+- l5 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l6 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l7 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l8 {
+- regulator-min-microvolt = <2900000>;
+- regulator-max-microvolt = <2900000>;
+- };
+-
+- l9 {
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l10 {
+- regulator-min-microvolt = <2800000>;
+- regulator-max-microvolt = <2800000>;
+- };
+-
+- l11 {
+- regulator-min-microvolt = <2950000>;
+- regulator-max-microvolt = <2950000>;
+- regulator-allow-set-load;
+- regulator-system-load = <200000>;
+- };
+-
+- l12 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2950000>;
+- };
+-
+- l13 {
+- regulator-min-microvolt = <3075000>;
+- regulator-max-microvolt = <3075000>;
+- };
+-
+- l14 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l15 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l16 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l17 {
+- regulator-min-microvolt = <2850000>;
+- regulator-max-microvolt = <2850000>;
+- };
+-
+- l18 {
+- regulator-min-microvolt = <2700000>;
+- regulator-max-microvolt = <2700000>;
+- };
+-};
+-
+ &msmgpio {
+ fg_alert_default: fg-alert-default-state {
+ pins = "gpio121";
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-ufi.dtsi b/arch/arm64/boot/dts/qcom/msm8916-ufi.dtsi
+index b27896e83a0e2..c8ea2f6f6b3d2 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-ufi.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8916-ufi.dtsi
+@@ -126,109 +126,6 @@ &wcnss_iris {
+ compatible = "qcom,wcn3620";
+ };
+
+-&smd_rpm_regulators {
+- vdd_l1_l2_l3-supply = <&pm8916_s3>;
+- vdd_l4_l5_l6-supply = <&pm8916_s4>;
+- vdd_l7-supply = <&pm8916_s4>;
+-
+- s3 {
+- regulator-min-microvolt = <1250000>;
+- regulator-max-microvolt = <1350000>;
+- };
+-
+- s4 {
+- regulator-min-microvolt = <1850000>;
+- regulator-max-microvolt = <2150000>;
+- };
+-
+- l1 {
+- regulator-min-microvolt = <1225000>;
+- regulator-max-microvolt = <1225000>;
+- };
+-
+- l2 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1200000>;
+- };
+-
+- l4 {
+- regulator-min-microvolt = <2050000>;
+- regulator-max-microvolt = <2050000>;
+- };
+-
+- l5 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l6 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l7 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l8 {
+- regulator-min-microvolt = <2900000>;
+- regulator-max-microvolt = <2900000>;
+- };
+-
+- l9 {
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l10 {
+- regulator-min-microvolt = <2800000>;
+- regulator-max-microvolt = <2800000>;
+- };
+-
+- l11 {
+- regulator-min-microvolt = <2950000>;
+- regulator-max-microvolt = <2950000>;
+- regulator-system-load = <200000>;
+- regulator-allow-set-load;
+- };
+-
+- l12 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2950000>;
+- };
+-
+- l13 {
+- regulator-min-microvolt = <3075000>;
+- regulator-max-microvolt = <3075000>;
+- };
+-
+- l14 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l15 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l16 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l17 {
+- regulator-min-microvolt = <2850000>;
+- regulator-max-microvolt = <2850000>;
+- };
+-
+- l18 {
+- regulator-min-microvolt = <2700000>;
+- regulator-max-microvolt = <2700000>;
+- };
+-};
+-
+ &msmgpio {
+ /* pins are board-specific */
+ button_default: button-default-state {
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-wingtech-wt88047.dts b/arch/arm64/boot/dts/qcom/msm8916-wingtech-wt88047.dts
+index 78020a0db4e48..323590598113b 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-wingtech-wt88047.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-wingtech-wt88047.dts
+@@ -149,6 +149,22 @@ &pm8916_resin {
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+
++&pm8916_rpm_regulators {
++ pm8916_l16: l16 {
++ /*
++ * L16 is only used for AW2013 which is fine with 2.5-3.3V.
++ * Use the recommended typical voltage of 2.8V as minimum.
++ */
++ regulator-min-microvolt = <2800000>;
++ regulator-max-microvolt = <3300000>;
++ };
++
++ pm8916_l17: l17 {
++ regulator-min-microvolt = <2850000>;
++ regulator-max-microvolt = <2850000>;
++ };
++};
++
+ &pm8916_vib {
+ status = "okay";
+ };
+@@ -188,109 +204,6 @@ &wcnss_iris {
+ compatible = "qcom,wcn3620";
+ };
+
+-&smd_rpm_regulators {
+- vdd_l1_l2_l3-supply = <&pm8916_s3>;
+- vdd_l4_l5_l6-supply = <&pm8916_s4>;
+- vdd_l7-supply = <&pm8916_s4>;
+-
+- s3 {
+- regulator-min-microvolt = <1250000>;
+- regulator-max-microvolt = <1350000>;
+- };
+-
+- s4 {
+- regulator-min-microvolt = <1850000>;
+- regulator-max-microvolt = <2150000>;
+- };
+-
+- l1 {
+- regulator-min-microvolt = <1225000>;
+- regulator-max-microvolt = <1225000>;
+- };
+-
+- l2 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1200000>;
+- };
+-
+- l4 {
+- regulator-min-microvolt = <2050000>;
+- regulator-max-microvolt = <2050000>;
+- };
+-
+- l5 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l6 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l7 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l8 {
+- regulator-min-microvolt = <2900000>;
+- regulator-max-microvolt = <2900000>;
+- };
+-
+- l9 {
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l10 {
+- regulator-min-microvolt = <2800000>;
+- regulator-max-microvolt = <2800000>;
+- };
+-
+- l11 {
+- regulator-min-microvolt = <2950000>;
+- regulator-max-microvolt = <2950000>;
+- regulator-allow-set-load;
+- regulator-system-load = <200000>;
+- };
+-
+- l12 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2950000>;
+- };
+-
+- l13 {
+- regulator-min-microvolt = <3075000>;
+- regulator-max-microvolt = <3075000>;
+- };
+-
+- l14 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l15 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l16 {
+- regulator-min-microvolt = <2800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l17 {
+- regulator-min-microvolt = <2850000>;
+- regulator-max-microvolt = <2850000>;
+- };
+-
+- l18 {
+- regulator-min-microvolt = <2700000>;
+- regulator-max-microvolt = <2700000>;
+- };
+-};
+-
+ &msmgpio {
+ camera_flash_default: camera-flash-default-state {
+ pins = "gpio31", "gpio32";
+--
+2.40.1
+
--- /dev/null
+From 1188e48fa9291ba482ca141967ed54f2fc6a1558 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 May 2023 20:48:43 +0200
+Subject: arm64: dts: qcom: msm8916: Disable audio codecs by default
+
+From: Stephan Gerhold <stephan@gerhold.net>
+
+[ Upstream commit a5cf21b14666c42912327c7bece38711f6e0d708 ]
+
+Not every device has something connected to the digital audio codec
+in MSM8916 and/or the analog audio codec in PM8916. Disable those by
+default so the hardware is only powered up when necessary.
+
+Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230510-msm8916-regulators-v1-4-54d4960a05fc@gerhold.net
+Stable-dep-of: 4facccb44a82 ("arm64: dts: qcom: apq8016-sbc: Rename ov5640 enable-gpios to powerdown-gpios")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/apq8016-sbc.dts | 5 +++++
+ arch/arm64/boot/dts/qcom/msm8916-huawei-g7.dts | 5 +++++
+ arch/arm64/boot/dts/qcom/msm8916.dtsi | 1 +
+ arch/arm64/boot/dts/qcom/pm8916.dtsi | 1 +
+ 4 files changed, 12 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts
+index 7261cfc99f9fa..73c51fa101c8b 100644
+--- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts
++++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts
+@@ -310,6 +310,10 @@ &lpass {
+ status = "okay";
+ };
+
++&lpass_codec {
++ status = "okay";
++};
++
+ &mdss {
+ status = "okay";
+ };
+@@ -399,6 +403,7 @@ &usb_hs_phy {
+ };
+
+ &wcd_codec {
++ status = "okay";
+ clocks = <&gcc GCC_CODEC_DIGCODEC_CLK>;
+ clock-names = "mclk";
+ qcom,mbhc-vthreshold-low = <75 150 237 450 500>;
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-huawei-g7.dts b/arch/arm64/boot/dts/qcom/msm8916-huawei-g7.dts
+index baa7bb86cdd5b..8197710372ad1 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-huawei-g7.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-huawei-g7.dts
+@@ -218,6 +218,10 @@ &lpass {
+ status = "okay";
+ };
+
++&lpass_codec {
++ status = "okay";
++};
++
+ &pm8916_resin {
+ status = "okay";
+ linux,code = <KEY_VOLUMEDOWN>;
+@@ -302,6 +306,7 @@ &usb_hs_phy {
+ };
+
+ &wcd_codec {
++ status = "okay";
+ qcom,micbias-lvl = <2800>;
+ qcom,mbhc-vthreshold-low = <75 150 237 450 500>;
+ qcom,mbhc-vthreshold-high = <75 150 237 450 500>;
+diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi
+index bf88c10ff55b0..9ab55e723aa6c 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
+@@ -1552,6 +1552,7 @@ lpass_codec: audio-codec@771c000 {
+ <&gcc GCC_CODEC_DIGCODEC_CLK>;
+ clock-names = "ahbix-clk", "mclk";
+ #sound-dai-cells = <1>;
++ status = "disabled";
+ };
+
+ sdhc_1: mmc@7824900 {
+diff --git a/arch/arm64/boot/dts/qcom/pm8916.dtsi b/arch/arm64/boot/dts/qcom/pm8916.dtsi
+index f4fb1a92ab55a..33ca1002fb754 100644
+--- a/arch/arm64/boot/dts/qcom/pm8916.dtsi
++++ b/arch/arm64/boot/dts/qcom/pm8916.dtsi
+@@ -178,6 +178,7 @@ wcd_codec: audio-codec@f000 {
+ vdd-cdc-tx-rx-cx-supply = <&pm8916_l5>;
+ vdd-micbias-supply = <&pm8916_l13>;
+ #sound-dai-cells = <1>;
++ status = "disabled";
+ };
+ };
+ };
+--
+2.40.1
+
--- /dev/null
+From fdf861a36e80f6b9e8a350dcf021cef9086559e4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 May 2023 20:48:42 +0200
+Subject: arm64: dts: qcom: msm8916: Fix regulator constraints
+
+From: Stephan Gerhold <stephan@gerhold.net>
+
+[ Upstream commit 355750828c5519c88de6ac0d09202d2a7e5892c5 ]
+
+The regulator constraints for most MSM8916 devices (except DB410c) were
+originally taken from Qualcomm's msm-3.10 vendor device tree (for lack
+of better documentation). Unfortunately it turns out that Qualcomm's
+voltages are slightly off as well and do not match the voltage
+constraints applied by the RPM firmware.
+
+This means that we sometimes request a specific voltage but the RPM
+firmware actually applies a much lower or higher voltage. This is
+particularly critical for pm8916_l11 which is used as SD card VMMC
+regulator: The SD card can choose a voltage from the current range of
+1.8 - 2.95V. If it chooses to run at 1.8V we pretend that this is fine
+but the RPM firmware will still silently end up configuring 2.95V.
+This can be easily reproduced with a multimeter or by checking the
+SPMI hardware registers of the regulator.
+
+Fix this by making the voltages match the actual "specified range" in
+the PM8916 Device Specification which is enforced by the RPM firmware.
+
+Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230510-msm8916-regulators-v1-3-54d4960a05fc@gerhold.net
+Stable-dep-of: 4facccb44a82 ("arm64: dts: qcom: apq8016-sbc: Rename ov5640 enable-gpios to powerdown-gpios")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/msm8916-acer-a1-724.dts | 14 +++++++-------
+ .../boot/dts/qcom/msm8916-alcatel-idol347.dts | 14 +++++++-------
+ arch/arm64/boot/dts/qcom/msm8916-asus-z00l.dts | 14 +++++++-------
+ arch/arm64/boot/dts/qcom/msm8916-gplus-fl8005a.dts | 14 +++++++-------
+ arch/arm64/boot/dts/qcom/msm8916-huawei-g7.dts | 12 ++++++------
+ .../boot/dts/qcom/msm8916-longcheer-l8150.dts | 14 +++++++-------
+ .../boot/dts/qcom/msm8916-longcheer-l8910.dts | 14 +++++++-------
+ .../dts/qcom/msm8916-samsung-a2015-common.dtsi | 14 +++++++-------
+ .../boot/dts/qcom/msm8916-samsung-gt5-common.dtsi | 14 +++++++-------
+ .../boot/dts/qcom/msm8916-samsung-j5-common.dtsi | 14 +++++++-------
+ .../boot/dts/qcom/msm8916-samsung-serranove.dts | 14 +++++++-------
+ arch/arm64/boot/dts/qcom/msm8916-ufi.dtsi | 14 +++++++-------
+ .../boot/dts/qcom/msm8916-wingtech-wt88047.dts | 12 ++++++------
+ 13 files changed, 89 insertions(+), 89 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-acer-a1-724.dts b/arch/arm64/boot/dts/qcom/msm8916-acer-a1-724.dts
+index 13cd9ad167df7..0d517804e44ed 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-acer-a1-724.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-acer-a1-724.dts
+@@ -159,13 +159,13 @@ &smd_rpm_regulators {
+ vdd_l7-supply = <&pm8916_s4>;
+
+ s3 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1300000>;
++ regulator-min-microvolt = <1250000>;
++ regulator-max-microvolt = <1350000>;
+ };
+
+ s4 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2100000>;
++ regulator-min-microvolt = <1850000>;
++ regulator-max-microvolt = <2150000>;
+ };
+
+ l1 {
+@@ -199,7 +199,7 @@ l7 {
+ };
+
+ l8 {
+- regulator-min-microvolt = <2850000>;
++ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <2900000>;
+ };
+
+@@ -209,12 +209,12 @@ l9 {
+ };
+
+ l10 {
+- regulator-min-microvolt = <2700000>;
++ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ l11 {
+- regulator-min-microvolt = <1800000>;
++ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+ regulator-system-load = <200000>;
+ regulator-allow-set-load;
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-alcatel-idol347.dts b/arch/arm64/boot/dts/qcom/msm8916-alcatel-idol347.dts
+index fecb69944cfa3..ddd64cc469983 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-alcatel-idol347.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-alcatel-idol347.dts
+@@ -201,13 +201,13 @@ &smd_rpm_regulators {
+ vdd_l7-supply = <&pm8916_s4>;
+
+ s3 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1300000>;
++ regulator-min-microvolt = <1250000>;
++ regulator-max-microvolt = <1350000>;
+ };
+
+ s4 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2100000>;
++ regulator-min-microvolt = <1850000>;
++ regulator-max-microvolt = <2150000>;
+ };
+
+ l1 {
+@@ -241,7 +241,7 @@ l7 {
+ };
+
+ l8 {
+- regulator-min-microvolt = <2850000>;
++ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <2900000>;
+ };
+
+@@ -251,12 +251,12 @@ l9 {
+ };
+
+ l10 {
+- regulator-min-microvolt = <2700000>;
++ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ l11 {
+- regulator-min-microvolt = <1800000>;
++ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+ regulator-allow-set-load;
+ regulator-system-load = <200000>;
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-asus-z00l.dts b/arch/arm64/boot/dts/qcom/msm8916-asus-z00l.dts
+index 91284a1d0966f..982457503a3cc 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-asus-z00l.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-asus-z00l.dts
+@@ -169,13 +169,13 @@ &smd_rpm_regulators {
+ vdd_l7-supply = <&pm8916_s4>;
+
+ s3 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1300000>;
++ regulator-min-microvolt = <1250000>;
++ regulator-max-microvolt = <1350000>;
+ };
+
+ s4 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2100000>;
++ regulator-min-microvolt = <1850000>;
++ regulator-max-microvolt = <2150000>;
+ };
+
+ l1 {
+@@ -209,7 +209,7 @@ l7 {
+ };
+
+ l8 {
+- regulator-min-microvolt = <2850000>;
++ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <2900000>;
+ };
+
+@@ -219,12 +219,12 @@ l9 {
+ };
+
+ l10 {
+- regulator-min-microvolt = <2700000>;
++ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ l11 {
+- regulator-min-microvolt = <1800000>;
++ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+ regulator-allow-set-load;
+ regulator-system-load = <200000>;
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-gplus-fl8005a.dts b/arch/arm64/boot/dts/qcom/msm8916-gplus-fl8005a.dts
+index 525ec76efeeb7..9584d271c5260 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-gplus-fl8005a.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-gplus-fl8005a.dts
+@@ -159,13 +159,13 @@ &smd_rpm_regulators {
+ vdd_l7-supply = <&pm8916_s4>;
+
+ s3 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1300000>;
++ regulator-min-microvolt = <1250000>;
++ regulator-max-microvolt = <1350000>;
+ };
+
+ s4 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2100000>;
++ regulator-min-microvolt = <1850000>;
++ regulator-max-microvolt = <2150000>;
+ };
+
+ l1 {
+@@ -199,7 +199,7 @@ l7 {
+ };
+
+ l8 {
+- regulator-min-microvolt = <2850000>;
++ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <2900000>;
+ };
+
+@@ -209,12 +209,12 @@ l9 {
+ };
+
+ l10 {
+- regulator-min-microvolt = <2700000>;
++ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ l11 {
+- regulator-min-microvolt = <1800000>;
++ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+ regulator-system-load = <200000>;
+ regulator-allow-set-load;
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-huawei-g7.dts b/arch/arm64/boot/dts/qcom/msm8916-huawei-g7.dts
+index 5b1bac8f51220..baa7bb86cdd5b 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-huawei-g7.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-huawei-g7.dts
+@@ -322,13 +322,13 @@ &smd_rpm_regulators {
+ vdd_l7-supply = <&pm8916_s4>;
+
+ s3 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1300000>;
++ regulator-min-microvolt = <1250000>;
++ regulator-max-microvolt = <1350000>;
+ };
+
+ s4 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2100000>;
++ regulator-min-microvolt = <1850000>;
++ regulator-max-microvolt = <2150000>;
+ };
+
+ l1 {
+@@ -372,12 +372,12 @@ l9 {
+ };
+
+ l10 {
+- regulator-min-microvolt = <2700000>;
++ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ l11 {
+- regulator-min-microvolt = <1800000>;
++ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+ regulator-allow-set-load;
+ regulator-system-load = <200000>;
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts
+index 1bcff702e7e57..66e7ba00633f7 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts
+@@ -273,13 +273,13 @@ &smd_rpm_regulators {
+ vdd_l7-supply = <&pm8916_s4>;
+
+ s3 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1300000>;
++ regulator-min-microvolt = <1250000>;
++ regulator-max-microvolt = <1350000>;
+ };
+
+ s4 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2100000>;
++ regulator-min-microvolt = <1850000>;
++ regulator-max-microvolt = <2150000>;
+ };
+
+ l1 {
+@@ -313,7 +313,7 @@ l7 {
+ };
+
+ l8 {
+- regulator-min-microvolt = <2850000>;
++ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <2900000>;
+ };
+
+@@ -323,12 +323,12 @@ l9 {
+ };
+
+ l10 {
+- regulator-min-microvolt = <2700000>;
++ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ l11 {
+- regulator-min-microvolt = <1800000>;
++ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+ regulator-allow-set-load;
+ regulator-system-load = <200000>;
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8910.dts b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8910.dts
+index 6046e2c1f1586..1e0c08770371a 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8910.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8910.dts
+@@ -155,13 +155,13 @@ &smd_rpm_regulators {
+ vdd_l7-supply = <&pm8916_s4>;
+
+ s3 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1300000>;
++ regulator-min-microvolt = <1250000>;
++ regulator-max-microvolt = <1350000>;
+ };
+
+ s4 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2100000>;
++ regulator-min-microvolt = <1850000>;
++ regulator-max-microvolt = <2150000>;
+ };
+
+ l1 {
+@@ -195,7 +195,7 @@ l7 {
+ };
+
+ l8 {
+- regulator-min-microvolt = <2850000>;
++ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <2900000>;
+ };
+
+@@ -205,12 +205,12 @@ l9 {
+ };
+
+ l10 {
+- regulator-min-microvolt = <2700000>;
++ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ l11 {
+- regulator-min-microvolt = <1800000>;
++ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+ regulator-allow-set-load;
+ regulator-system-load = <200000>;
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi b/arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi
+index 16d67749960e0..b362a76eebc94 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi
+@@ -285,13 +285,13 @@ &smd_rpm_regulators {
+ vdd_l7-supply = <&pm8916_s4>;
+
+ s3 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1300000>;
++ regulator-min-microvolt = <1250000>;
++ regulator-max-microvolt = <1350000>;
+ };
+
+ s4 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2100000>;
++ regulator-min-microvolt = <1850000>;
++ regulator-max-microvolt = <2150000>;
+ };
+
+ l1 {
+@@ -325,7 +325,7 @@ l7 {
+ };
+
+ l8 {
+- regulator-min-microvolt = <2850000>;
++ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <2900000>;
+ };
+
+@@ -335,12 +335,12 @@ l9 {
+ };
+
+ l10 {
+- regulator-min-microvolt = <2700000>;
++ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ l11 {
+- regulator-min-microvolt = <1800000>;
++ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+ regulator-allow-set-load;
+ regulator-system-load = <200000>;
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-gt5-common.dtsi b/arch/arm64/boot/dts/qcom/msm8916-samsung-gt5-common.dtsi
+index 74ffd04db8d84..4464beeeaab12 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-gt5-common.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-gt5-common.dtsi
+@@ -168,13 +168,13 @@ &smd_rpm_regulators {
+ vdd_l7-supply = <&pm8916_s4>;
+
+ s3 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1300000>;
++ regulator-min-microvolt = <1250000>;
++ regulator-max-microvolt = <1350000>;
+ };
+
+ s4 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2100000>;
++ regulator-min-microvolt = <1850000>;
++ regulator-max-microvolt = <2150000>;
+ };
+
+ l1 {
+@@ -208,7 +208,7 @@ l7 {
+ };
+
+ l8 {
+- regulator-min-microvolt = <2850000>;
++ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <2900000>;
+ };
+
+@@ -218,12 +218,12 @@ l9 {
+ };
+
+ l10 {
+- regulator-min-microvolt = <2700000>;
++ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ l11 {
+- regulator-min-microvolt = <1800000>;
++ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+ regulator-system-load = <200000>;
+ regulator-allow-set-load;
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-j5-common.dtsi b/arch/arm64/boot/dts/qcom/msm8916-samsung-j5-common.dtsi
+index adeee0830e768..6e231e92e6756 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-j5-common.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-j5-common.dtsi
+@@ -134,13 +134,13 @@ &smd_rpm_regulators {
+ vdd_l7-supply = <&pm8916_s4>;
+
+ s3 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1300000>;
++ regulator-min-microvolt = <1250000>;
++ regulator-max-microvolt = <1350000>;
+ };
+
+ s4 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2100000>;
++ regulator-min-microvolt = <1850000>;
++ regulator-max-microvolt = <2150000>;
+ };
+
+ l1 {
+@@ -174,7 +174,7 @@ l7 {
+ };
+
+ l8 {
+- regulator-min-microvolt = <2850000>;
++ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <2900000>;
+ };
+
+@@ -184,12 +184,12 @@ l9 {
+ };
+
+ l10 {
+- regulator-min-microvolt = <2700000>;
++ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ l11 {
+- regulator-min-microvolt = <1800000>;
++ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+ regulator-allow-set-load;
+ regulator-system-load = <200000>;
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-serranove.dts b/arch/arm64/boot/dts/qcom/msm8916-samsung-serranove.dts
+index 1a41a4db874da..fa5b330aaeaee 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-serranove.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-serranove.dts
+@@ -326,13 +326,13 @@ &smd_rpm_regulators {
+ vdd_l7-supply = <&pm8916_s4>;
+
+ s3 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1300000>;
++ regulator-min-microvolt = <1250000>;
++ regulator-max-microvolt = <1350000>;
+ };
+
+ s4 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2100000>;
++ regulator-min-microvolt = <1850000>;
++ regulator-max-microvolt = <2150000>;
+ };
+
+ l1 {
+@@ -366,7 +366,7 @@ l7 {
+ };
+
+ l8 {
+- regulator-min-microvolt = <2850000>;
++ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <2900000>;
+ };
+
+@@ -376,12 +376,12 @@ l9 {
+ };
+
+ l10 {
+- regulator-min-microvolt = <2700000>;
++ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ l11 {
+- regulator-min-microvolt = <1800000>;
++ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+ regulator-allow-set-load;
+ regulator-system-load = <200000>;
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-ufi.dtsi b/arch/arm64/boot/dts/qcom/msm8916-ufi.dtsi
+index 50bae6f214f1f..b27896e83a0e2 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-ufi.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8916-ufi.dtsi
+@@ -132,13 +132,13 @@ &smd_rpm_regulators {
+ vdd_l7-supply = <&pm8916_s4>;
+
+ s3 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1300000>;
++ regulator-min-microvolt = <1250000>;
++ regulator-max-microvolt = <1350000>;
+ };
+
+ s4 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2100000>;
++ regulator-min-microvolt = <1850000>;
++ regulator-max-microvolt = <2150000>;
+ };
+
+ l1 {
+@@ -172,7 +172,7 @@ l7 {
+ };
+
+ l8 {
+- regulator-min-microvolt = <2850000>;
++ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <2900000>;
+ };
+
+@@ -182,12 +182,12 @@ l9 {
+ };
+
+ l10 {
+- regulator-min-microvolt = <2700000>;
++ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ l11 {
+- regulator-min-microvolt = <1800000>;
++ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+ regulator-system-load = <200000>;
+ regulator-allow-set-load;
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-wingtech-wt88047.dts b/arch/arm64/boot/dts/qcom/msm8916-wingtech-wt88047.dts
+index ac56c7595f78a..78020a0db4e48 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-wingtech-wt88047.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-wingtech-wt88047.dts
+@@ -194,13 +194,13 @@ &smd_rpm_regulators {
+ vdd_l7-supply = <&pm8916_s4>;
+
+ s3 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1300000>;
++ regulator-min-microvolt = <1250000>;
++ regulator-max-microvolt = <1350000>;
+ };
+
+ s4 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2100000>;
++ regulator-min-microvolt = <1850000>;
++ regulator-max-microvolt = <2150000>;
+ };
+
+ l1 {
+@@ -234,7 +234,7 @@ l7 {
+ };
+
+ l8 {
+- regulator-min-microvolt = <2850000>;
++ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <2900000>;
+ };
+
+@@ -244,7 +244,7 @@ l9 {
+ };
+
+ l10 {
+- regulator-min-microvolt = <2700000>;
++ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+--
+2.40.1
+
--- /dev/null
+From a267b9e67b6cceb1ca2502c1b10114cc32b9550d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 17 Jun 2023 19:15:28 +0200
+Subject: arm64: dts: qcom: msm8916-l8150: correct light sensor VDDIO supply
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 6a541eaa6e8e5283efb993ae7a947bede8d01fa5 ]
+
+liteon,ltr559 light sensor takes VDDIO, not VIO, supply:
+
+ msm8916-longcheer-l8150.dtb: light-sensor@23: 'vio-supply' does not match any of the regexes: 'pinctrl-[0-9]+'
+
+Fixes: 3016af34ef8d ("arm64: dts: qcom: msm8916-longcheer-l8150: Add light and proximity sensor")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Nikita Travkin <nikita@trvn.ru>
+Link: https://lore.kernel.org/r/20230617171541.286957-2-krzysztof.kozlowski@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts
+index f1dd625e18227..1bcff702e7e57 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts
+@@ -163,7 +163,7 @@ light-sensor@23 {
+ pinctrl-0 = <&light_int_default>;
+
+ vdd-supply = <&pm8916_l17>;
+- vio-supply = <&pm8916_l6>;
++ vddio-supply = <&pm8916_l6>;
+ };
+
+ gyroscope@68 {
+--
+2.40.1
+
--- /dev/null
+From 625a96f71e32d99a4eb626bf898c1e064b1c6fde Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 May 2023 08:32:31 +0200
+Subject: arm64: dts: qcom: msm8916-longcheer-l8910: Add front flash LED
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: André Apitzsch <git@apitzsch.eu>
+
+[ Upstream commit 5d8d9330921770fb953e8e749bbd049ac0fae988 ]
+
+l8910 uses OCP8110 flash LED driver. Add it to the device tree.
+
+Tested-by: Stephan Gerhold <stephan@gerhold.net>
+Signed-off-by: André Apitzsch <git@apitzsch.eu>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230514-x5_front_flash-v2-1-845a8bb0483b@apitzsch.eu
+Stable-dep-of: 4facccb44a82 ("arm64: dts: qcom: apq8016-sbc: Rename ov5640 enable-gpios to powerdown-gpios")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../boot/dts/qcom/msm8916-longcheer-l8910.dts | 22 +++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8910.dts b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8910.dts
+index b79e80913af9f..6046e2c1f1586 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8910.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8910.dts
+@@ -20,6 +20,21 @@ chosen {
+ stdout-path = "serial0";
+ };
+
++ flash-led-controller {
++ compatible = "ocs,ocp8110";
++ enable-gpios = <&msmgpio 49 GPIO_ACTIVE_HIGH>;
++ flash-gpios = <&msmgpio 119 GPIO_ACTIVE_HIGH>;
++
++ pinctrl-0 = <&camera_front_flash_default>;
++ pinctrl-names = "default";
++
++ flash_led: led {
++ function = LED_FUNCTION_FLASH;
++ color = <LED_COLOR_ID_WHITE>;
++ flash-max-timeout-us = <250000>;
++ };
++ };
++
+ gpio-keys {
+ compatible = "gpio-keys";
+
+@@ -246,6 +261,13 @@ button_backlight_default: button-backlight-default-state {
+ bias-disable;
+ };
+
++ camera_front_flash_default: camera-front-flash-default-state {
++ pins = "gpio49", "gpio119";
++ function = "gpio";
++ drive-strength = <2>;
++ bias-disable;
++ };
++
+ gpio_keys_default: gpio-keys-default-state {
+ pins = "gpio107";
+ function = "gpio";
+--
+2.40.1
+
--- /dev/null
+From e02a7f08a778d05168c58d967d49911b291411e5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 May 2023 14:46:58 +0200
+Subject: arm64: dts: qcom: msm8916: Rename &msmgpio -> &tlmm
+
+From: Stephan Gerhold <stephan@gerhold.net>
+
+[ Upstream commit 41e22c2ff38eaea777f1158071539e659aa7980d ]
+
+MSM8916 is the only ARM64 Qualcomm SoC that is still using the old
+&msmgpio name. Change this to &tlmm to avoid confusion.
+
+Note that the node ordering does not change because the MSM8916 device
+trees have pinctrl separated at the bottom (similar to sc7180).
+
+Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
+Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230525-msm8916-labels-v1-1-bec0f5fb46fb@gerhold.net
+Stable-dep-of: 4facccb44a82 ("arm64: dts: qcom: apq8016-sbc: Rename ov5640 enable-gpios to powerdown-gpios")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/apq8016-sbc.dts | 24 +++++------
+ .../boot/dts/qcom/msm8916-acer-a1-724.dts | 14 +++----
+ .../boot/dts/qcom/msm8916-alcatel-idol347.dts | 24 +++++------
+ .../arm64/boot/dts/qcom/msm8916-asus-z00l.dts | 20 ++++-----
+ .../boot/dts/qcom/msm8916-gplus-fl8005a.dts | 20 ++++-----
+ .../arm64/boot/dts/qcom/msm8916-huawei-g7.dts | 34 +++++++--------
+ .../boot/dts/qcom/msm8916-longcheer-l8150.dts | 20 ++++-----
+ .../boot/dts/qcom/msm8916-longcheer-l8910.dts | 16 +++----
+ arch/arm64/boot/dts/qcom/msm8916-pins.dtsi | 2 +-
+ .../qcom/msm8916-samsung-a2015-common.dtsi | 40 +++++++++---------
+ .../boot/dts/qcom/msm8916-samsung-a3u-eur.dts | 12 +++---
+ .../boot/dts/qcom/msm8916-samsung-a5u-eur.dts | 6 +--
+ .../qcom/msm8916-samsung-e2015-common.dtsi | 6 +--
+ .../dts/qcom/msm8916-samsung-grandmax.dts | 6 +--
+ .../dts/qcom/msm8916-samsung-gt5-common.dtsi | 14 +++----
+ .../boot/dts/qcom/msm8916-samsung-gt510.dts | 12 +++---
+ .../boot/dts/qcom/msm8916-samsung-gt58.dts | 8 ++--
+ .../dts/qcom/msm8916-samsung-j5-common.dtsi | 16 +++----
+ .../dts/qcom/msm8916-samsung-serranove.dts | 42 +++++++++----------
+ .../boot/dts/qcom/msm8916-thwc-uf896.dts | 8 ++--
+ .../boot/dts/qcom/msm8916-thwc-ufi001c.dts | 10 ++---
+ arch/arm64/boot/dts/qcom/msm8916-ufi.dtsi | 2 +-
+ .../dts/qcom/msm8916-wingtech-wt88047.dts | 16 +++----
+ .../boot/dts/qcom/msm8916-yiming-uz801v3.dts | 8 ++--
+ arch/arm64/boot/dts/qcom/msm8916.dtsi | 4 +-
+ 25 files changed, 192 insertions(+), 192 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts
+index b3de394c01510..80a6526779849 100644
+--- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts
++++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts
+@@ -75,7 +75,7 @@ usb2513 {
+
+ usb_id: usb-id {
+ compatible = "linux,extcon-usb-gpio";
+- id-gpio = <&msmgpio 121 GPIO_ACTIVE_HIGH>;
++ id-gpio = <&tlmm 121 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb_id_default>;
+ };
+@@ -101,13 +101,13 @@ gpio-keys {
+ button {
+ label = "Volume Up";
+ linux,code = <KEY_VOLUMEUP>;
+- gpios = <&msmgpio 107 GPIO_ACTIVE_LOW>;
++ gpios = <&tlmm 107 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ leds {
+ pinctrl-names = "default";
+- pinctrl-0 = <&msmgpio_leds>,
++ pinctrl-0 = <&tlmm_leds>,
+ <&pm8916_gpios_leds>,
+ <&pm8916_mpps_leds>;
+
+@@ -117,7 +117,7 @@ led@1 {
+ label = "apq8016-sbc:green:user1";
+ function = LED_FUNCTION_HEARTBEAT;
+ color = <LED_COLOR_ID_GREEN>;
+- gpios = <&msmgpio 21 GPIO_ACTIVE_HIGH>;
++ gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ default-state = "off";
+ };
+@@ -126,7 +126,7 @@ led@2 {
+ label = "apq8016-sbc:green:user2";
+ function = LED_FUNCTION_DISK_ACTIVITY;
+ color = <LED_COLOR_ID_GREEN>;
+- gpios = <&msmgpio 120 GPIO_ACTIVE_HIGH>;
++ gpios = <&tlmm 120 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "mmc0";
+ default-state = "off";
+ };
+@@ -186,14 +186,14 @@ adv_bridge: bridge@39 {
+ compatible = "adi,adv7533";
+ reg = <0x39>;
+
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <31 IRQ_TYPE_EDGE_FALLING>;
+
+ adi,dsi-lanes = <4>;
+ clocks = <&rpmcc RPM_SMD_BB_CLK2>;
+ clock-names = "cec";
+
+- pd-gpios = <&msmgpio 32 GPIO_ACTIVE_HIGH>;
++ pd-gpios = <&tlmm 32 GPIO_ACTIVE_HIGH>;
+
+ avdd-supply = <&pm8916_l6>;
+ v1p2-supply = <&pm8916_l6>;
+@@ -276,8 +276,8 @@ camera_rear@3b {
+ compatible = "ovti,ov5640";
+ reg = <0x3b>;
+
+- enable-gpios = <&msmgpio 34 GPIO_ACTIVE_HIGH>;
+- reset-gpios = <&msmgpio 35 GPIO_ACTIVE_LOW>;
++ enable-gpios = <&tlmm 34 GPIO_ACTIVE_HIGH>;
++ reset-gpios = <&tlmm 35 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&camera_rear_default>;
+
+@@ -378,7 +378,7 @@ &sdhc_2 {
+ pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>;
+ pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>;
+
+- cd-gpios = <&msmgpio 38 GPIO_ACTIVE_LOW>;
++ cd-gpios = <&tlmm 38 GPIO_ACTIVE_LOW>;
+ };
+
+ &sound {
+@@ -520,7 +520,7 @@ &i2c6_default {
+ * ones actually used for GPIO.
+ */
+
+-&msmgpio {
++&tlmm {
+ gpio-line-names =
+ "[UART0_TX]", /* GPIO_0, LSEC pin 5 */
+ "[UART0_RX]", /* GPIO_1, LSEC pin 7 */
+@@ -645,7 +645,7 @@ &msmgpio {
+ "USR_LED_2_CTRL", /* GPIO 120 */
+ "SB_HS_ID";
+
+- msmgpio_leds: msmgpio-leds-state {
++ tlmm_leds: tlmm-leds-state {
+ pins = "gpio21", "gpio120";
+ function = "gpio";
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-acer-a1-724.dts b/arch/arm64/boot/dts/qcom/msm8916-acer-a1-724.dts
+index 753413b48751a..7b77a80f049c6 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-acer-a1-724.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-acer-a1-724.dts
+@@ -39,14 +39,14 @@ gpio-keys {
+
+ button-volume-up {
+ label = "Volume Up";
+- gpios = <&msmgpio 107 GPIO_ACTIVE_LOW>;
++ gpios = <&tlmm 107 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ };
+ };
+
+ usb_id: usb-id {
+ compatible = "linux,extcon-usb-gpio";
+- id-gpio = <&msmgpio 110 GPIO_ACTIVE_HIGH>;
++ id-gpio = <&tlmm 110 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb_id_default>;
+ };
+@@ -58,7 +58,7 @@ &blsp_i2c2 {
+ accelerometer@10 {
+ compatible = "bosch,bmc150_accel";
+ reg = <0x10>;
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <115 IRQ_TYPE_EDGE_RISING>;
+
+ vdd-supply = <&pm8916_l17>;
+@@ -89,10 +89,10 @@ touchscreen@38 {
+ compatible = "edt,edt-ft5406";
+ reg = <0x38>;
+
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <13 IRQ_TYPE_LEVEL_LOW>;
+
+- reset-gpios = <&msmgpio 12 GPIO_ACTIVE_LOW>;
++ reset-gpios = <&tlmm 12 GPIO_ACTIVE_LOW>;
+
+ vcc-supply = <&pm8916_l16>;
+ iovcc-supply = <&pm8916_l6>;
+@@ -143,7 +143,7 @@ &sdhc_2 {
+ pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on>;
+ pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off>;
+
+- cd-gpios = <&msmgpio 38 GPIO_ACTIVE_HIGH>;
++ cd-gpios = <&tlmm 38 GPIO_ACTIVE_HIGH>;
+
+ status = "okay";
+ };
+@@ -165,7 +165,7 @@ &wcnss_iris {
+ compatible = "qcom,wcn3620";
+ };
+
+-&msmgpio {
++&tlmm {
+ accel_int_default: accel-int-default-state {
+ pins = "gpio115";
+ function = "gpio";
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-alcatel-idol347.dts b/arch/arm64/boot/dts/qcom/msm8916-alcatel-idol347.dts
+index 4bfbad669b1ea..d2abbdec5fe68 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-alcatel-idol347.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-alcatel-idol347.dts
+@@ -30,7 +30,7 @@ gpio-keys {
+
+ button-volume-up {
+ label = "Volume Up";
+- gpios = <&msmgpio 107 GPIO_ACTIVE_LOW>;
++ gpios = <&tlmm 107 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ };
+ };
+@@ -42,7 +42,7 @@ gpio-leds {
+ pinctrl-0 = <&gpio_leds_default>;
+
+ led-0 {
+- gpios = <&msmgpio 32 GPIO_ACTIVE_HIGH>;
++ gpios = <&tlmm 32 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "torch";
+ function = LED_FUNCTION_TORCH;
+ };
+@@ -50,7 +50,7 @@ led-0 {
+
+ usb_id: usb-id {
+ compatible = "linux,extcon-usb-gpio";
+- id-gpio = <&msmgpio 69 GPIO_ACTIVE_HIGH>;
++ id-gpio = <&tlmm 69 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb_id_default>;
+ };
+@@ -66,9 +66,9 @@ &blsp_i2c4 {
+ touchscreen@26 {
+ compatible = "mstar,msg2638";
+ reg = <0x26>;
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <13 IRQ_TYPE_EDGE_FALLING>;
+- reset-gpios = <&msmgpio 100 GPIO_ACTIVE_LOW>;
++ reset-gpios = <&tlmm 100 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&ts_int_reset_default>;
+ vdd-supply = <&pm8916_l17>;
+@@ -86,7 +86,7 @@ magnetometer@c {
+ reg = <0x0c>;
+ vdd-supply = <&pm8916_l17>;
+ vid-supply = <&pm8916_l6>;
+- reset-gpios = <&msmgpio 8 GPIO_ACTIVE_LOW>;
++ reset-gpios = <&tlmm 8 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mag_reset_default>;
+ mount-matrix = "0", "1", "0",
+@@ -99,7 +99,7 @@ accelerometer@f {
+ reg = <0x0f>;
+ vdd-supply = <&pm8916_l17>;
+ vddio-supply = <&pm8916_l6>;
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <31 IRQ_TYPE_EDGE_RISING>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&accel_int_default>;
+@@ -111,7 +111,7 @@ accelerometer@f {
+ proximity@48 {
+ compatible = "sensortek,stk3310";
+ reg = <0x48>;
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <12 IRQ_TYPE_EDGE_FALLING>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&proximity_int_default>;
+@@ -122,7 +122,7 @@ gyroscope@68 {
+ reg = <0x68>;
+ vdd-supply = <&pm8916_l17>;
+ vddio-supply = <&pm8916_l6>;
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <97 IRQ_TYPE_EDGE_RISING>,
+ <98 IRQ_TYPE_EDGE_RISING>;
+ pinctrl-names = "default";
+@@ -136,7 +136,7 @@ &blsp_i2c6 {
+ led-controller@68 {
+ compatible = "si-en,sn3190";
+ reg = <0x68>;
+- shutdown-gpios = <&msmgpio 89 GPIO_ACTIVE_HIGH>;
++ shutdown-gpios = <&tlmm 89 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_enable_default &led_shutdown_default>;
+ #address-cells = <1>;
+@@ -182,7 +182,7 @@ &sdhc_2 {
+ pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>;
+ pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>;
+
+- cd-gpios = <&msmgpio 38 GPIO_ACTIVE_LOW>;
++ cd-gpios = <&tlmm 38 GPIO_ACTIVE_LOW>;
+ };
+
+ &usb {
+@@ -202,7 +202,7 @@ &wcnss_iris {
+ compatible = "qcom,wcn3620";
+ };
+
+-&msmgpio {
++&tlmm {
+ accel_int_default: accel-int-default-state {
+ pins = "gpio31";
+ function = "gpio";
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-asus-z00l.dts b/arch/arm64/boot/dts/qcom/msm8916-asus-z00l.dts
+index 37755e8853958..c58a70fdf36fb 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-asus-z00l.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-asus-z00l.dts
+@@ -30,14 +30,14 @@ gpio-keys {
+
+ button-volume-up {
+ label = "Volume Up";
+- gpios = <&msmgpio 107 GPIO_ACTIVE_LOW>;
++ gpios = <&tlmm 107 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ debounce-interval = <15>;
+ };
+
+ button-volume-down {
+ label = "Volume Down";
+- gpios = <&msmgpio 117 GPIO_ACTIVE_LOW>;
++ gpios = <&tlmm 117 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEDOWN>;
+ debounce-interval = <15>;
+ };
+@@ -49,7 +49,7 @@ reg_sd_vmmc: regulator-sdcard-vmmc {
+ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+
+- gpio = <&msmgpio 87 GPIO_ACTIVE_HIGH>;
++ gpio = <&tlmm 87 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ startup-delay-us = <200>;
+@@ -60,7 +60,7 @@ reg_sd_vmmc: regulator-sdcard-vmmc {
+
+ usb_id: usb-id {
+ compatible = "linux,extcon-usb-gpio";
+- id-gpios = <&msmgpio 110 GPIO_ACTIVE_HIGH>;
++ id-gpios = <&tlmm 110 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb_id_default>;
+ };
+@@ -76,7 +76,7 @@ magnetometer@c {
+ vdd-supply = <&pm8916_l8>;
+ vid-supply = <&pm8916_l6>;
+
+- reset-gpios = <&msmgpio 112 GPIO_ACTIVE_LOW>;
++ reset-gpios = <&tlmm 112 GPIO_ACTIVE_LOW>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&mag_reset_default>;
+@@ -86,7 +86,7 @@ imu@68 {
+ compatible = "invensense,mpu6515";
+ reg = <0x68>;
+
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <36 IRQ_TYPE_EDGE_RISING>;
+
+ vdd-supply = <&pm8916_l17>;
+@@ -108,10 +108,10 @@ touchscreen@38 {
+ compatible = "edt,edt-ft5306";
+ reg = <0x38>;
+
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <13 IRQ_TYPE_EDGE_FALLING>;
+
+- reset-gpios = <&msmgpio 12 GPIO_ACTIVE_LOW>;
++ reset-gpios = <&tlmm 12 GPIO_ACTIVE_LOW>;
+
+ vcc-supply = <&pm8916_l11>;
+ iovcc-supply = <&pm8916_l6>;
+@@ -150,7 +150,7 @@ &sdhc_2 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>;
+ pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>;
+- cd-gpios = <&msmgpio 38 GPIO_ACTIVE_LOW>;
++ cd-gpios = <&tlmm 38 GPIO_ACTIVE_LOW>;
+ };
+
+ &usb {
+@@ -170,7 +170,7 @@ &wcnss_iris {
+ compatible = "qcom,wcn3620";
+ };
+
+-&msmgpio {
++&tlmm {
+ gpio_keys_default: gpio-keys-default-state {
+ pins = "gpio107", "gpio117";
+ function = "gpio";
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-gplus-fl8005a.dts b/arch/arm64/boot/dts/qcom/msm8916-gplus-fl8005a.dts
+index 4a6bf99c755fd..221db7edec5ef 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-gplus-fl8005a.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-gplus-fl8005a.dts
+@@ -24,8 +24,8 @@ chosen {
+ flash-led-controller {
+ /* Actually qcom,leds-gpio-flash */
+ compatible = "sgmicro,sgm3140";
+- enable-gpios = <&msmgpio 31 GPIO_ACTIVE_HIGH>;
+- flash-gpios = <&msmgpio 32 GPIO_ACTIVE_HIGH>;
++ enable-gpios = <&tlmm 31 GPIO_ACTIVE_HIGH>;
++ flash-gpios = <&tlmm 32 GPIO_ACTIVE_HIGH>;
+
+ pinctrl-0 = <&camera_flash_default>;
+ pinctrl-names = "default";
+@@ -45,7 +45,7 @@ gpio-keys {
+
+ button-volume-up {
+ label = "Volume Up";
+- gpios = <&msmgpio 107 GPIO_ACTIVE_LOW>;
++ gpios = <&tlmm 107 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ };
+ };
+@@ -59,21 +59,21 @@ gpio-leds {
+ led-red {
+ function = LED_FUNCTION_CHARGING;
+ color = <LED_COLOR_ID_RED>;
+- gpios = <&msmgpio 117 GPIO_ACTIVE_HIGH>;
++ gpios = <&tlmm 117 GPIO_ACTIVE_HIGH>;
+ retain-state-suspended;
+ };
+
+ led-green {
+ function = LED_FUNCTION_CHARGING;
+ color = <LED_COLOR_ID_GREEN>;
+- gpios = <&msmgpio 118 GPIO_ACTIVE_HIGH>;
++ gpios = <&tlmm 118 GPIO_ACTIVE_HIGH>;
+ retain-state-suspended;
+ };
+ };
+
+ usb_id: usb-id {
+ compatible = "linux,extcon-usb-gpio";
+- id-gpio = <&msmgpio 110 GPIO_ACTIVE_HIGH>;
++ id-gpio = <&tlmm 110 GPIO_ACTIVE_HIGH>;
+ pinctrl-0 = <&usb_id_default>;
+ pinctrl-names = "default";
+ };
+@@ -87,10 +87,10 @@ touchscreen@38 {
+ compatible = "edt,edt-ft5406";
+ reg = <0x38>;
+
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <13 IRQ_TYPE_EDGE_FALLING>;
+
+- reset-gpios = <&msmgpio 12 GPIO_ACTIVE_LOW>;
++ reset-gpios = <&tlmm 12 GPIO_ACTIVE_LOW>;
+
+ vcc-supply = <&pm8916_l17>;
+ iovcc-supply = <&pm8916_l6>;
+@@ -138,7 +138,7 @@ &sdhc_2 {
+ pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off>;
+ pinctrl-names = "default", "sleep";
+
+- cd-gpios = <&msmgpio 38 GPIO_ACTIVE_LOW>;
++ cd-gpios = <&tlmm 38 GPIO_ACTIVE_LOW>;
+
+ status = "okay";
+ };
+@@ -160,7 +160,7 @@ &wcnss_iris {
+ compatible = "qcom,wcn3620";
+ };
+
+-&msmgpio {
++&tlmm {
+ camera_flash_default: camera-flash-default-state {
+ pins = "gpio31", "gpio32";
+ function = "gpio";
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-huawei-g7.dts b/arch/arm64/boot/dts/qcom/msm8916-huawei-g7.dts
+index 29aaa35438a36..b02e8f9a8ca0d 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-huawei-g7.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-huawei-g7.dts
+@@ -43,7 +43,7 @@ gpio-keys {
+
+ button-volume-up {
+ label = "Volume Up";
+- gpios = <&msmgpio 107 GPIO_ACTIVE_LOW>;
++ gpios = <&tlmm 107 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ };
+ };
+@@ -55,21 +55,21 @@ leds {
+ pinctrl-0 = <&gpio_leds_default>;
+
+ led-0 {
+- gpios = <&msmgpio 8 GPIO_ACTIVE_HIGH>;
++ gpios = <&tlmm 8 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_RED>;
+ default-state = "off";
+ function = LED_FUNCTION_INDICATOR;
+ };
+
+ led-1 {
+- gpios = <&msmgpio 9 GPIO_ACTIVE_HIGH>;
++ gpios = <&tlmm 9 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_GREEN>;
+ default-state = "off";
+ function = LED_FUNCTION_INDICATOR;
+ };
+
+ led-2 {
+- gpios = <&msmgpio 10 GPIO_ACTIVE_HIGH>;
++ gpios = <&tlmm 10 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_BLUE>;
+ default-state = "off";
+ function = LED_FUNCTION_INDICATOR;
+@@ -78,7 +78,7 @@ led-2 {
+
+ usb_id: usb-id {
+ compatible = "linux,extcon-usb-gpio";
+- id-gpio = <&msmgpio 117 GPIO_ACTIVE_HIGH>;
++ id-gpio = <&tlmm 117 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb_id_default>;
+ };
+@@ -94,7 +94,7 @@ magnetometer@c {
+ vdd-supply = <&pm8916_l17>;
+ vid-supply = <&pm8916_l6>;
+
+- reset-gpios = <&msmgpio 36 GPIO_ACTIVE_LOW>;
++ reset-gpios = <&tlmm 36 GPIO_ACTIVE_LOW>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&mag_reset_default>;
+@@ -104,7 +104,7 @@ accelerometer@1e {
+ compatible = "kionix,kx023-1025";
+ reg = <0x1e>;
+
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <115 IRQ_TYPE_EDGE_RISING>;
+
+ vdd-supply = <&pm8916_l17>;
+@@ -122,7 +122,7 @@ proximity@39 {
+ compatible = "avago,apds9930";
+ reg = <0x39>;
+
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <113 IRQ_TYPE_EDGE_FALLING>;
+
+ vdd-supply = <&pm8916_l17>;
+@@ -146,7 +146,7 @@ reg_lcd_pos: outp {
+ regulator-name = "outp";
+ regulator-min-microvolt = <5400000>;
+ regulator-max-microvolt = <5400000>;
+- enable-gpios = <&msmgpio 97 GPIO_ACTIVE_HIGH>;
++ enable-gpios = <&tlmm 97 GPIO_ACTIVE_HIGH>;
+ regulator-active-discharge = <1>;
+ };
+
+@@ -154,7 +154,7 @@ reg_lcd_neg: outn {
+ regulator-name = "outn";
+ regulator-min-microvolt = <5400000>;
+ regulator-max-microvolt = <5400000>;
+- enable-gpios = <&msmgpio 32 GPIO_ACTIVE_HIGH>;
++ enable-gpios = <&tlmm 32 GPIO_ACTIVE_HIGH>;
+ regulator-active-discharge = <1>;
+ };
+ };
+@@ -169,7 +169,7 @@ rmi4@70 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <13 IRQ_TYPE_EDGE_FALLING>;
+
+ vdd-supply = <&pm8916_l17>;
+@@ -199,11 +199,11 @@ nfc@28 {
+ compatible = "nxp,pn547", "nxp,nxp-nci-i2c";
+ reg = <0x28>;
+
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <21 IRQ_TYPE_EDGE_RISING>;
+
+- enable-gpios = <&msmgpio 20 GPIO_ACTIVE_HIGH>;
+- firmware-gpios = <&msmgpio 2 GPIO_ACTIVE_HIGH>;
++ enable-gpios = <&tlmm 20 GPIO_ACTIVE_HIGH>;
++ firmware-gpios = <&tlmm 2 GPIO_ACTIVE_HIGH>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&nfc_default>;
+@@ -264,7 +264,7 @@ &sdhc_2 {
+ pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdhc2_cd_default>;
+
+ /*
+- * The Huawei device tree sets cd-gpios = <&msmgpio 38 GPIO_ACTIVE_HIGH>.
++ * The Huawei device tree sets cd-gpios = <&tlmm 38 GPIO_ACTIVE_HIGH>.
+ * However, gpio38 does not change its state when inserting/removing the
+ * SD card, it's just low all the time. The Huawei kernel seems to use
+ * polling for SD card detection instead.
+@@ -276,7 +276,7 @@ &sdhc_2 {
+ * Maybe Huawei decided to replace the second SIM card slot with the
+ * SD card slot and forgot to re-route to gpio38.
+ */
+- cd-gpios = <&msmgpio 56 GPIO_ACTIVE_LOW>;
++ cd-gpios = <&tlmm 56 GPIO_ACTIVE_LOW>;
+ };
+
+ &sound {
+@@ -338,7 +338,7 @@ &wcnss_iris {
+ compatible = "qcom,wcn3620";
+ };
+
+-&msmgpio {
++&tlmm {
+ accel_irq_default: accel-irq-default-state {
+ pins = "gpio115";
+ function = "gpio";
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts
+index e1c352e1da1fe..4aa2281bdbcaa 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts
+@@ -41,7 +41,7 @@ gpio-keys {
+
+ button-volume-up {
+ label = "Volume Up";
+- gpios = <&msmgpio 107 GPIO_ACTIVE_LOW>;
++ gpios = <&tlmm 107 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ };
+ };
+@@ -53,7 +53,7 @@ reg_ctp: regulator-ctp {
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+
+- gpio = <&msmgpio 17 GPIO_ACTIVE_HIGH>;
++ gpio = <&tlmm 17 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-names = "default";
+@@ -62,8 +62,8 @@ reg_ctp: regulator-ctp {
+
+ flash-led-controller {
+ compatible = "sgmicro,sgm3140";
+- flash-gpios = <&msmgpio 31 GPIO_ACTIVE_HIGH>;
+- enable-gpios = <&msmgpio 32 GPIO_ACTIVE_HIGH>;
++ flash-gpios = <&tlmm 31 GPIO_ACTIVE_HIGH>;
++ enable-gpios = <&tlmm 32 GPIO_ACTIVE_HIGH>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&camera_flash_default>;
+@@ -122,7 +122,7 @@ accelerometer@10 {
+ * to the BMC156. However, there are two pads next to the chip
+ * that can be shorted to make it work if needed.
+ *
+- * interrupt-parent = <&msmgpio>;
++ * interrupt-parent = <&tlmm>;
+ * interrupts = <116 IRQ_TYPE_EDGE_RISING>;
+ */
+
+@@ -141,7 +141,7 @@ magnetometer@12 {
+ compatible = "bosch,bmc156_magn";
+ reg = <0x12>;
+
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <113 IRQ_TYPE_EDGE_RISING>;
+
+ pinctrl-names = "default";
+@@ -156,7 +156,7 @@ light-sensor@23 {
+ reg = <0x23>;
+ proximity-near-level = <75>;
+
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <115 IRQ_TYPE_EDGE_FALLING>;
+
+ pinctrl-names = "default";
+@@ -170,7 +170,7 @@ gyroscope@68 {
+ compatible = "bosch,bmg160";
+ reg = <0x68>;
+
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <23 IRQ_TYPE_EDGE_RISING>,
+ <22 IRQ_TYPE_EDGE_RISING>;
+
+@@ -191,7 +191,7 @@ rmi4@20 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <13 IRQ_TYPE_EDGE_FALLING>;
+
+ vdd-supply = <®_ctp>;
+@@ -274,7 +274,7 @@ &wcnss_iris {
+ compatible = "qcom,wcn3620";
+ };
+
+-&msmgpio {
++&tlmm {
+ accel_int_default: accel-int-default-state {
+ pins = "gpio116";
+ function = "gpio";
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8910.dts b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8910.dts
+index 630727ed1ed5a..a1208c8e06203 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8910.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8910.dts
+@@ -22,8 +22,8 @@ chosen {
+
+ flash-led-controller {
+ compatible = "ocs,ocp8110";
+- enable-gpios = <&msmgpio 49 GPIO_ACTIVE_HIGH>;
+- flash-gpios = <&msmgpio 119 GPIO_ACTIVE_HIGH>;
++ enable-gpios = <&tlmm 49 GPIO_ACTIVE_HIGH>;
++ flash-gpios = <&tlmm 119 GPIO_ACTIVE_HIGH>;
+
+ pinctrl-0 = <&camera_front_flash_default>;
+ pinctrl-names = "default";
+@@ -45,7 +45,7 @@ gpio-keys {
+
+ button-volume-up {
+ label = "Volume Up";
+- gpios = <&msmgpio 107 GPIO_ACTIVE_LOW>;
++ gpios = <&tlmm 107 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ };
+ };
+@@ -54,7 +54,7 @@ leds {
+ compatible = "gpio-leds";
+
+ led-0 {
+- gpios = <&msmgpio 17 GPIO_ACTIVE_HIGH>;
++ gpios = <&tlmm 17 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_WHITE>;
+ default-state = "off";
+ function = LED_FUNCTION_KBD_BACKLIGHT;
+@@ -66,7 +66,7 @@ led-0 {
+
+ usb_id: usb-id {
+ compatible = "linux,extcon-usb-gpio";
+- id-gpio = <&msmgpio 110 GPIO_ACTIVE_HIGH>;
++ id-gpio = <&tlmm 110 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb_id_default>;
+ };
+@@ -82,7 +82,7 @@ magnetometer@d {
+ vdd-supply = <&pm8916_l17>;
+ vid-supply = <&pm8916_l6>;
+
+- reset-gpios = <&msmgpio 111 GPIO_ACTIVE_LOW>;
++ reset-gpios = <&tlmm 111 GPIO_ACTIVE_LOW>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&mag_reset_default>;
+@@ -136,7 +136,7 @@ &sdhc_2 {
+ pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>;
+ pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>;
+
+- cd-gpios = <&msmgpio 38 GPIO_ACTIVE_LOW>;
++ cd-gpios = <&tlmm 38 GPIO_ACTIVE_LOW>;
+ };
+
+ &usb {
+@@ -156,7 +156,7 @@ &wcnss_iris {
+ compatible = "qcom,wcn3620";
+ };
+
+-&msmgpio {
++&tlmm {
+ button_backlight_default: button-backlight-default-state {
+ pins = "gpio17";
+ function = "gpio";
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi b/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi
+index 33dfcf318a81b..1e07f70768f41 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi
+@@ -3,7 +3,7 @@
+ * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+ */
+
+-&msmgpio {
++&tlmm {
+
+ blsp1_uart1_default: blsp1-uart1-default-state {
+ /* TX, RX, CTS_N, RTS_N */
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi b/arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi
+index 37a872949851b..550ba6b9d4cd8 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi
+@@ -44,13 +44,13 @@ gpio-keys {
+
+ button-volume-up {
+ label = "Volume Up";
+- gpios = <&msmgpio 107 GPIO_ACTIVE_LOW>;
++ gpios = <&tlmm 107 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ };
+
+ button-home {
+ label = "Home";
+- gpios = <&msmgpio 109 GPIO_ACTIVE_LOW>;
++ gpios = <&tlmm 109 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_HOMEPAGE>;
+ };
+ };
+@@ -65,7 +65,7 @@ gpio-hall-sensor {
+
+ event-hall-sensor {
+ label = "Hall Effect Sensor";
+- gpios = <&msmgpio 52 GPIO_ACTIVE_LOW>;
++ gpios = <&tlmm 52 GPIO_ACTIVE_LOW>;
+ linux,input-type = <EV_SW>;
+ linux,code = <SW_LID>;
+ linux,can-disable;
+@@ -83,7 +83,7 @@ reg_motor_vdd: regulator-motor-vdd {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+
+- gpio = <&msmgpio 76 GPIO_ACTIVE_HIGH>;
++ gpio = <&tlmm 76 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-names = "default";
+@@ -96,7 +96,7 @@ reg_vdd_tsp_a: regulator-vdd-tsp-a {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+- gpio = <&msmgpio 73 GPIO_ACTIVE_HIGH>;
++ gpio = <&tlmm 73 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-names = "default";
+@@ -105,8 +105,8 @@ reg_vdd_tsp_a: regulator-vdd-tsp-a {
+
+ i2c-muic {
+ compatible = "i2c-gpio";
+- sda-gpios = <&msmgpio 105 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
+- scl-gpios = <&msmgpio 106 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
++ sda-gpios = <&tlmm 105 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
++ scl-gpios = <&tlmm 106 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&muic_i2c_default>;
+@@ -118,7 +118,7 @@ muic: extcon@25 {
+ compatible = "siliconmitus,sm5502-muic";
+
+ reg = <0x25>;
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <12 IRQ_TYPE_EDGE_FALLING>;
+
+ pinctrl-names = "default";
+@@ -128,8 +128,8 @@ muic: extcon@25 {
+
+ i2c-tkey {
+ compatible = "i2c-gpio";
+- sda-gpios = <&msmgpio 16 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
+- scl-gpios = <&msmgpio 17 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
++ sda-gpios = <&tlmm 16 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
++ scl-gpios = <&tlmm 17 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&tkey_i2c_default>;
+@@ -142,7 +142,7 @@ touchkey: touchkey@20 {
+ compatible = "coreriver,tc360-touchkey";
+ reg = <0x20>;
+
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <98 IRQ_TYPE_EDGE_FALLING>;
+
+ /* vcc/vdd-supply are board-specific */
+@@ -157,8 +157,8 @@ touchkey: touchkey@20 {
+
+ i2c-nfc {
+ compatible = "i2c-gpio";
+- sda-gpios = <&msmgpio 0 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
+- scl-gpios = <&msmgpio 1 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
++ sda-gpios = <&tlmm 0 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
++ scl-gpios = <&tlmm 1 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&nfc_i2c_default>;
+@@ -170,11 +170,11 @@ nfc@27 {
+ compatible = "samsung,s3fwrn5-i2c";
+ reg = <0x27>;
+
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <21 IRQ_TYPE_EDGE_RISING>;
+
+- en-gpios = <&msmgpio 20 GPIO_ACTIVE_LOW>;
+- wake-gpios = <&msmgpio 49 GPIO_ACTIVE_HIGH>;
++ en-gpios = <&tlmm 20 GPIO_ACTIVE_LOW>;
++ wake-gpios = <&tlmm 49 GPIO_ACTIVE_HIGH>;
+
+ clocks = <&rpmcc RPM_SMD_BB_CLK2_PIN>;
+
+@@ -200,7 +200,7 @@ &blsp_i2c2 {
+ accelerometer: accelerometer@10 {
+ compatible = "bosch,bmc150_accel";
+ reg = <0x10>;
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <115 IRQ_TYPE_EDGE_RISING>;
+
+ vdd-supply = <&pm8916_l17>;
+@@ -225,7 +225,7 @@ &blsp_i2c4 {
+ battery@35 {
+ compatible = "richtek,rt5033-battery";
+ reg = <0x35>;
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <121 IRQ_TYPE_EDGE_BOTH>;
+
+ pinctrl-names = "default";
+@@ -274,7 +274,7 @@ &sdhc_2 {
+ pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>;
+ pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>;
+
+- cd-gpios = <&msmgpio 38 GPIO_ACTIVE_LOW>;
++ cd-gpios = <&tlmm 38 GPIO_ACTIVE_LOW>;
+ };
+
+ &usb {
+@@ -286,7 +286,7 @@ &usb_hs_phy {
+ extcon = <&muic>;
+ };
+
+-&msmgpio {
++&tlmm {
+ accel_int_default: accel-int-default-state {
+ pins = "gpio115";
+ function = "gpio";
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-a3u-eur.dts b/arch/arm64/boot/dts/qcom/msm8916-samsung-a3u-eur.dts
+index a1ca4d8834201..9068aa6f7b293 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-a3u-eur.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-a3u-eur.dts
+@@ -15,7 +15,7 @@ reg_panel_vdd3: regulator-panel-vdd3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+- gpio = <&msmgpio 9 GPIO_ACTIVE_HIGH>;
++ gpio = <&tlmm 9 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-names = "default";
+@@ -28,7 +28,7 @@ reg_touch_key: regulator-touch-key {
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+
+- gpio = <&msmgpio 86 GPIO_ACTIVE_HIGH>;
++ gpio = <&tlmm 86 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-names = "default";
+@@ -41,7 +41,7 @@ reg_key_led: regulator-key-led {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+- gpio = <&msmgpio 60 GPIO_ACTIVE_HIGH>;
++ gpio = <&tlmm 60 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-names = "default";
+@@ -67,7 +67,7 @@ touchscreen@20 {
+ compatible = "zinitix,bt541";
+
+ reg = <0x20>;
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <13 IRQ_TYPE_EDGE_FALLING>;
+
+ touchscreen-size-x = <540>;
+@@ -93,7 +93,7 @@ panel@0 {
+
+ vdd3-supply = <®_panel_vdd3>;
+ vci-supply = <&pm8916_l17>;
+- reset-gpios = <&msmgpio 25 GPIO_ACTIVE_HIGH>;
++ reset-gpios = <&tlmm 25 GPIO_ACTIVE_HIGH>;
+
+ port {
+ panel_in: endpoint {
+@@ -120,7 +120,7 @@ &wcnss_iris {
+ compatible = "qcom,wcn3620";
+ };
+
+-&msmgpio {
++&tlmm {
+ panel_vdd3_default: panel-vdd3-default-state {
+ pins = "gpio9";
+ function = "gpio";
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-a5u-eur.dts b/arch/arm64/boot/dts/qcom/msm8916-samsung-a5u-eur.dts
+index 4e10b8a5e9f9c..388482a1e3d9f 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-a5u-eur.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-a5u-eur.dts
+@@ -15,7 +15,7 @@ reg_touch_key: regulator-touch-key {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+- gpio = <&msmgpio 97 GPIO_ACTIVE_HIGH>;
++ gpio = <&tlmm 97 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-names = "default";
+@@ -36,7 +36,7 @@ touchscreen@48 {
+ compatible = "melfas,mms345l";
+
+ reg = <0x48>;
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <13 IRQ_TYPE_EDGE_FALLING>;
+
+ touchscreen-size-x = <720>;
+@@ -71,7 +71,7 @@ &wcnss_iris {
+ compatible = "qcom,wcn3660b";
+ };
+
+-&msmgpio {
++&tlmm {
+ tkey_en_default: tkey-en-default-state {
+ pins = "gpio97";
+ function = "gpio";
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-e2015-common.dtsi b/arch/arm64/boot/dts/qcom/msm8916-samsung-e2015-common.dtsi
+index f6c4a011fdfd2..0cdd6af7817f4 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-e2015-common.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-e2015-common.dtsi
+@@ -18,7 +18,7 @@ muic: extcon@14 {
+ compatible = "siliconmitus,sm5504-muic";
+ reg = <0x14>;
+
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <12 IRQ_TYPE_EDGE_FALLING>;
+
+ pinctrl-names = "default";
+@@ -32,7 +32,7 @@ reg_touch_key: regulator-touch-key {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+- gpio = <&msmgpio 97 GPIO_ACTIVE_HIGH>;
++ gpio = <&tlmm 97 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-names = "default";
+@@ -66,7 +66,7 @@ &wcnss_iris {
+ compatible = "qcom,wcn3620";
+ };
+
+-&msmgpio {
++&tlmm {
+ tkey_en_default: tkey-en-default-state {
+ pins = "gpio97";
+ function = "gpio";
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-grandmax.dts b/arch/arm64/boot/dts/qcom/msm8916-samsung-grandmax.dts
+index 4cbd68b894481..3f145dde4059f 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-grandmax.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-grandmax.dts
+@@ -33,7 +33,7 @@ led-keyled {
+ function = LED_FUNCTION_KBD_BACKLIGHT;
+ color = <LED_COLOR_ID_WHITE>;
+
+- gpios = <&msmgpio 60 GPIO_ACTIVE_HIGH>;
++ gpios = <&tlmm 60 GPIO_ACTIVE_HIGH>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio_leds_default>;
+@@ -42,14 +42,14 @@ led-keyled {
+ };
+
+ ®_motor_vdd {
+- gpio = <&msmgpio 72 GPIO_ACTIVE_HIGH>;
++ gpio = <&tlmm 72 GPIO_ACTIVE_HIGH>;
+ };
+
+ ®_touch_key {
+ status = "disabled";
+ };
+
+-&msmgpio {
++&tlmm {
+ gpio_leds_default: gpio-led-default-state {
+ pins = "gpio60";
+ function = "gpio";
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-gt5-common.dtsi b/arch/arm64/boot/dts/qcom/msm8916-samsung-gt5-common.dtsi
+index a49e1641e59b8..cb1b6318a246d 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-gt5-common.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-gt5-common.dtsi
+@@ -34,13 +34,13 @@ gpio-keys {
+
+ volume-up-button {
+ label = "Volume Up";
+- gpios = <&msmgpio 107 GPIO_ACTIVE_LOW>;
++ gpios = <&tlmm 107 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ };
+
+ home-button {
+ label = "Home";
+- gpios = <&msmgpio 109 GPIO_ACTIVE_LOW>;
++ gpios = <&tlmm 109 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_HOMEPAGE>;
+ };
+ };
+@@ -55,7 +55,7 @@ gpio-hall-sensor {
+
+ hall-sensor-switch {
+ label = "Hall Effect Sensor";
+- gpios = <&msmgpio 52 GPIO_ACTIVE_LOW>;
++ gpios = <&tlmm 52 GPIO_ACTIVE_LOW>;
+ linux,input-type = <EV_SW>;
+ linux,code = <SW_LID>;
+ linux,can-disable;
+@@ -74,7 +74,7 @@ fuelgauge@36 {
+ maxim,over-heat-temp = <600>;
+ maxim,over-volt = <4400>;
+
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <121 IRQ_TYPE_EDGE_FALLING>;
+
+ pinctrl-0 = <&fuelgauge_int_default>;
+@@ -97,7 +97,7 @@ accelerometer@1d {
+ vdd-supply = <&pm8916_l17>;
+ vddio-supply = <&pm8916_l5>;
+
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <115 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "INT1";
+
+@@ -145,7 +145,7 @@ &sdhc_2 {
+ pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>;
+ pinctrl-names = "default", "sleep";
+
+- cd-gpios = <&msmgpio 38 GPIO_ACTIVE_LOW>;
++ cd-gpios = <&tlmm 38 GPIO_ACTIVE_LOW>;
+
+ status = "okay";
+ };
+@@ -169,7 +169,7 @@ &wcnss_iris {
+ compatible = "qcom,wcn3660b";
+ };
+
+-&msmgpio {
++&tlmm {
+ accel_int_default: accel-int-default-state {
+ pins = "gpio115";
+ function = "gpio";
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-gt510.dts b/arch/arm64/boot/dts/qcom/msm8916-samsung-gt510.dts
+index 607a5dc8a5341..48111c6a2c78f 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-gt510.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-gt510.dts
+@@ -25,7 +25,7 @@ reg_motor_vdd: regulator-motor-vdd {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+
+- gpio = <&msmgpio 76 GPIO_ACTIVE_HIGH>;
++ gpio = <&tlmm 76 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&motor_en_default>;
+@@ -38,7 +38,7 @@ reg_tsp_1p8v: regulator-tsp-1p8v {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+- gpio = <&msmgpio 73 GPIO_ACTIVE_HIGH>;
++ gpio = <&tlmm 73 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&tsp_en_default>;
+@@ -51,7 +51,7 @@ reg_tsp_3p3v: regulator-tsp-3p3v {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+- gpio = <&msmgpio 73 GPIO_ACTIVE_HIGH>;
++ gpio = <&tlmm 73 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+@@ -71,20 +71,20 @@ &blsp_i2c5 {
+ touchscreen@4a {
+ compatible = "atmel,maxtouch";
+ reg = <0x4a>;
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <13 IRQ_TYPE_LEVEL_LOW>;
+
+ vdd-supply = <®_tsp_1p8v>;
+ vdda-supply = <®_tsp_3p3v>;
+
+- reset-gpios = <&msmgpio 114 GPIO_ACTIVE_LOW>;
++ reset-gpios = <&tlmm 114 GPIO_ACTIVE_LOW>;
+
+ pinctrl-0 = <&tsp_int_rst_default>;
+ pinctrl-names = "default";
+ };
+ };
+
+-&msmgpio {
++&tlmm {
+ motor_en_default: motor-en-default-state {
+ pins = "gpio76";
+ function = "gpio";
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-gt58.dts b/arch/arm64/boot/dts/qcom/msm8916-samsung-gt58.dts
+index 5d6f8383306bb..98ceaad7fcea9 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-gt58.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-gt58.dts
+@@ -15,7 +15,7 @@ reg_vdd_tsp: regulator-vdd-tsp {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+- gpio = <&msmgpio 73 GPIO_ACTIVE_HIGH>;
++ gpio = <&tlmm 73 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <®_tsp_en_default>;
+@@ -24,7 +24,7 @@ reg_vdd_tsp: regulator-vdd-tsp {
+
+ vibrator {
+ compatible = "gpio-vibrator";
+- enable-gpios = <&msmgpio 76 GPIO_ACTIVE_HIGH>;
++ enable-gpios = <&tlmm 76 GPIO_ACTIVE_HIGH>;
+
+ pinctrl-0 = <&vibrator_en_default>;
+ pinctrl-names = "default";
+@@ -37,7 +37,7 @@ &blsp_i2c5 {
+ touchscreen@20 {
+ compatible = "zinitix,bt532";
+ reg = <0x20>;
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <13 IRQ_TYPE_EDGE_FALLING>;
+
+ touchscreen-size-x = <768>;
+@@ -51,7 +51,7 @@ touchscreen@20 {
+ };
+ };
+
+-&msmgpio {
++&tlmm {
+ reg_tsp_en_default: reg-tsp-en-default-state {
+ pins = "gpio73";
+ function = "gpio";
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-j5-common.dtsi b/arch/arm64/boot/dts/qcom/msm8916-samsung-j5-common.dtsi
+index 6192d04a58ae4..b2d2bc205ef27 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-j5-common.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-j5-common.dtsi
+@@ -32,7 +32,7 @@ gpio_hall_sensor: gpio-hall-sensor {
+
+ event-hall-sensor {
+ label = "Hall Effect Sensor";
+- gpios = <&msmgpio 52 GPIO_ACTIVE_LOW>;
++ gpios = <&tlmm 52 GPIO_ACTIVE_LOW>;
+ linux,input-type = <EV_SW>;
+ linux,code = <SW_LID>;
+ linux,can-disable;
+@@ -49,21 +49,21 @@ gpio-keys {
+
+ button-volume-up {
+ label = "Volume Up";
+- gpios = <&msmgpio 107 GPIO_ACTIVE_LOW>;
++ gpios = <&tlmm 107 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ };
+
+ button-home {
+ label = "Home Key";
+- gpios = <&msmgpio 109 GPIO_ACTIVE_LOW>;
++ gpios = <&tlmm 109 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_HOMEPAGE>;
+ };
+ };
+
+ i2c_muic: i2c-muic {
+ compatible = "i2c-gpio";
+- sda-gpios = <&msmgpio 105 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
+- scl-gpios = <&msmgpio 106 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
++ sda-gpios = <&tlmm 105 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
++ scl-gpios = <&tlmm 106 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&muic_i2c_default>;
+@@ -75,7 +75,7 @@ muic: extcon@25 {
+ compatible = "siliconmitus,sm5703-muic";
+ reg = <0x25>;
+
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <12 IRQ_TYPE_EDGE_FALLING>;
+
+ pinctrl-names = "default";
+@@ -108,7 +108,7 @@ &sdhc_2 {
+ pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>;
+ pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>;
+
+- cd-gpios = <&msmgpio 38 GPIO_ACTIVE_LOW>;
++ cd-gpios = <&tlmm 38 GPIO_ACTIVE_LOW>;
+ };
+
+ &usb {
+@@ -128,7 +128,7 @@ &wcnss_iris {
+ compatible = "qcom,wcn3620";
+ };
+
+-&msmgpio {
++&tlmm {
+ gpio_hall_sensor_default: gpio-hall-sensor-default-state {
+ pins = "gpio52";
+ function = "gpio";
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-serranove.dts b/arch/arm64/boot/dts/qcom/msm8916-samsung-serranove.dts
+index fc4c61c4e1e6c..13a1d8828447b 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-serranove.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-serranove.dts
+@@ -53,13 +53,13 @@ gpio-keys {
+
+ button-volume-up {
+ label = "Volume Up";
+- gpios = <&msmgpio 107 GPIO_ACTIVE_LOW>;
++ gpios = <&tlmm 107 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ };
+
+ button-home {
+ label = "Home";
+- gpios = <&msmgpio 109 GPIO_ACTIVE_LOW>;
++ gpios = <&tlmm 109 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_HOMEPAGE>;
+ };
+ };
+@@ -74,7 +74,7 @@ gpio-hall-sensor {
+
+ event-hall-sensor {
+ label = "Hall Effect Sensor";
+- gpios = <&msmgpio 52 GPIO_ACTIVE_LOW>;
++ gpios = <&tlmm 52 GPIO_ACTIVE_LOW>;
+ linux,input-type = <EV_SW>;
+ linux,code = <SW_LID>;
+ linux,can-disable;
+@@ -87,7 +87,7 @@ reg_vdd_tsp: regulator-vdd-tsp {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+- gpio = <&msmgpio 73 GPIO_ACTIVE_HIGH>;
++ gpio = <&tlmm 73 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-names = "default";
+@@ -100,7 +100,7 @@ reg_touch_key: regulator-touch-key {
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+
+- gpio = <&msmgpio 86 GPIO_ACTIVE_HIGH>;
++ gpio = <&tlmm 86 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-names = "default";
+@@ -113,7 +113,7 @@ reg_key_led: regulator-key-led {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+- gpio = <&msmgpio 60 GPIO_ACTIVE_HIGH>;
++ gpio = <&tlmm 60 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-names = "default";
+@@ -122,8 +122,8 @@ reg_key_led: regulator-key-led {
+
+ i2c-muic {
+ compatible = "i2c-gpio";
+- sda-gpios = <&msmgpio 105 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
+- scl-gpios = <&msmgpio 106 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
++ sda-gpios = <&tlmm 105 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
++ scl-gpios = <&tlmm 106 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&muic_i2c_default>;
+@@ -135,7 +135,7 @@ muic: extcon@14 {
+ compatible = "siliconmitus,sm5504-muic";
+ reg = <0x14>;
+
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <12 IRQ_TYPE_EDGE_FALLING>;
+
+ pinctrl-names = "default";
+@@ -145,8 +145,8 @@ muic: extcon@14 {
+
+ i2c-tkey {
+ compatible = "i2c-gpio";
+- sda-gpios = <&msmgpio 16 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
+- scl-gpios = <&msmgpio 17 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
++ sda-gpios = <&tlmm 16 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
++ scl-gpios = <&tlmm 17 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&tkey_i2c_default>;
+@@ -158,7 +158,7 @@ touchkey@20 {
+ compatible = "coreriver,tc360-touchkey";
+ reg = <0x20>;
+
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <98 IRQ_TYPE_EDGE_FALLING>;
+
+ vcc-supply = <®_touch_key>;
+@@ -174,8 +174,8 @@ touchkey@20 {
+
+ i2c-nfc {
+ compatible = "i2c-gpio";
+- sda-gpios = <&msmgpio 0 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
+- scl-gpios = <&msmgpio 1 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
++ sda-gpios = <&tlmm 0 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
++ scl-gpios = <&tlmm 1 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&nfc_i2c_default>;
+@@ -187,11 +187,11 @@ nfc@2b {
+ compatible = "nxp,pn547", "nxp,nxp-nci-i2c";
+ reg = <0x2b>;
+
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <21 IRQ_TYPE_EDGE_RISING>;
+
+- enable-gpios = <&msmgpio 20 GPIO_ACTIVE_HIGH>;
+- firmware-gpios = <&msmgpio 49 GPIO_ACTIVE_HIGH>;
++ enable-gpios = <&tlmm 20 GPIO_ACTIVE_HIGH>;
++ firmware-gpios = <&tlmm 49 GPIO_ACTIVE_HIGH>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&nfc_default>;
+@@ -206,7 +206,7 @@ imu@6b {
+ compatible = "st,lsm6ds3";
+ reg = <0x6b>;
+
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <115 IRQ_TYPE_EDGE_RISING>;
+
+ pinctrl-names = "default";
+@@ -230,7 +230,7 @@ battery@35 {
+ compatible = "richtek,rt5033-battery";
+ reg = <0x35>;
+
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <121 IRQ_TYPE_EDGE_FALLING>;
+
+ pinctrl-names = "default";
+@@ -245,7 +245,7 @@ touchscreen@20 {
+ compatible = "zinitix,bt541";
+ reg = <0x20>;
+
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <13 IRQ_TYPE_EDGE_FALLING>;
+
+ touchscreen-size-x = <540>;
+@@ -320,7 +320,7 @@ &wcnss_iris {
+ compatible = "qcom,wcn3660b";
+ };
+
+-&msmgpio {
++&tlmm {
+ fg_alert_default: fg-alert-default-state {
+ pins = "gpio121";
+ function = "gpio";
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-thwc-uf896.dts b/arch/arm64/boot/dts/qcom/msm8916-thwc-uf896.dts
+index 82e260375174d..6fe1850ba20e9 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-thwc-uf896.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-thwc-uf896.dts
+@@ -10,19 +10,19 @@ / {
+ };
+
+ &button_restart {
+- gpios = <&msmgpio 35 GPIO_ACTIVE_LOW>;
++ gpios = <&tlmm 35 GPIO_ACTIVE_LOW>;
+ };
+
+ &led_r {
+- gpios = <&msmgpio 82 GPIO_ACTIVE_HIGH>;
++ gpios = <&tlmm 82 GPIO_ACTIVE_HIGH>;
+ };
+
+ &led_g {
+- gpios = <&msmgpio 83 GPIO_ACTIVE_HIGH>;
++ gpios = <&tlmm 83 GPIO_ACTIVE_HIGH>;
+ };
+
+ &led_b {
+- gpios = <&msmgpio 81 GPIO_ACTIVE_HIGH>;
++ gpios = <&tlmm 81 GPIO_ACTIVE_HIGH>;
+ };
+
+ &button_default {
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-thwc-ufi001c.dts b/arch/arm64/boot/dts/qcom/msm8916-thwc-ufi001c.dts
+index 978f0abcdf8ff..16d4a91022be6 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-thwc-ufi001c.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-thwc-ufi001c.dts
+@@ -10,19 +10,19 @@ / {
+ };
+
+ &button_restart {
+- gpios = <&msmgpio 37 GPIO_ACTIVE_HIGH>;
++ gpios = <&tlmm 37 GPIO_ACTIVE_HIGH>;
+ };
+
+ &led_r {
+- gpios = <&msmgpio 22 GPIO_ACTIVE_HIGH>;
++ gpios = <&tlmm 22 GPIO_ACTIVE_HIGH>;
+ };
+
+ &led_g {
+- gpios = <&msmgpio 21 GPIO_ACTIVE_HIGH>;
++ gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>;
+ };
+
+ &led_b {
+- gpios = <&msmgpio 20 GPIO_ACTIVE_HIGH>;
++ gpios = <&tlmm 20 GPIO_ACTIVE_HIGH>;
+ };
+
+ &mpss {
+@@ -40,7 +40,7 @@ &gpio_leds_default {
+ };
+
+ /* This selects the external SIM card slot by default */
+-&msmgpio {
++&tlmm {
+ sim_ctrl_default: sim-ctrl-default-state {
+ esim-sel-pins {
+ pins = "gpio0", "gpio3";
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-ufi.dtsi b/arch/arm64/boot/dts/qcom/msm8916-ufi.dtsi
+index c8ea2f6f6b3d2..cb5c228ba9f6b 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-ufi.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8916-ufi.dtsi
+@@ -126,7 +126,7 @@ &wcnss_iris {
+ compatible = "qcom,wcn3620";
+ };
+
+-&msmgpio {
++&tlmm {
+ /* pins are board-specific */
+ button_default: button-default-state {
+ function = "gpio";
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-wingtech-wt88047.dts b/arch/arm64/boot/dts/qcom/msm8916-wingtech-wt88047.dts
+index 323590598113b..12ce4dc236c63 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-wingtech-wt88047.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-wingtech-wt88047.dts
+@@ -25,8 +25,8 @@ chosen {
+
+ flash-led-controller {
+ compatible = "ocs,ocp8110";
+- enable-gpios = <&msmgpio 31 GPIO_ACTIVE_HIGH>;
+- flash-gpios = <&msmgpio 32 GPIO_ACTIVE_HIGH>;
++ enable-gpios = <&tlmm 31 GPIO_ACTIVE_HIGH>;
++ flash-gpios = <&tlmm 32 GPIO_ACTIVE_HIGH>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&camera_flash_default>;
+@@ -47,14 +47,14 @@ gpio-keys {
+
+ button-volume-up {
+ label = "Volume Up";
+- gpios = <&msmgpio 107 GPIO_ACTIVE_LOW>;
++ gpios = <&tlmm 107 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ };
+ };
+
+ usb_id: usb-id {
+ compatible = "linux,extcon-usb-gpio";
+- id-gpio = <&msmgpio 110 GPIO_ACTIVE_HIGH>;
++ id-gpio = <&tlmm 110 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb_id_default>;
+ };
+@@ -67,7 +67,7 @@ imu@68 {
+ compatible = "invensense,mpu6880";
+ reg = <0x68>;
+
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <115 IRQ_TYPE_EDGE_RISING>;
+
+ vdd-supply = <&pm8916_l17>;
+@@ -90,10 +90,10 @@ touchscreen@38 {
+ compatible = "edt,edt-ft5506";
+ reg = <0x38>;
+
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <13 IRQ_TYPE_EDGE_FALLING>;
+
+- reset-gpios = <&msmgpio 12 GPIO_ACTIVE_LOW>;
++ reset-gpios = <&tlmm 12 GPIO_ACTIVE_LOW>;
+
+ vcc-supply = <&pm8916_l17>;
+ iovcc-supply = <&pm8916_l6>;
+@@ -204,7 +204,7 @@ &wcnss_iris {
+ compatible = "qcom,wcn3620";
+ };
+
+-&msmgpio {
++&tlmm {
+ camera_flash_default: camera-flash-default-state {
+ pins = "gpio31", "gpio32";
+ function = "gpio";
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-yiming-uz801v3.dts b/arch/arm64/boot/dts/qcom/msm8916-yiming-uz801v3.dts
+index 74ce6563be183..5e6ba8c58bb57 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-yiming-uz801v3.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-yiming-uz801v3.dts
+@@ -10,19 +10,19 @@ / {
+ };
+
+ &button_restart {
+- gpios = <&msmgpio 23 GPIO_ACTIVE_LOW>;
++ gpios = <&tlmm 23 GPIO_ACTIVE_LOW>;
+ };
+
+ &led_r {
+- gpios = <&msmgpio 7 GPIO_ACTIVE_HIGH>;
++ gpios = <&tlmm 7 GPIO_ACTIVE_HIGH>;
+ };
+
+ &led_g {
+- gpios = <&msmgpio 8 GPIO_ACTIVE_HIGH>;
++ gpios = <&tlmm 8 GPIO_ACTIVE_HIGH>;
+ };
+
+ &led_b {
+- gpios = <&msmgpio 6 GPIO_ACTIVE_HIGH>;
++ gpios = <&tlmm 6 GPIO_ACTIVE_HIGH>;
+ };
+
+ &button_default {
+diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi
+index 9ab55e723aa6c..309ed76ec2d87 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
+@@ -993,12 +993,12 @@ etm3_out: endpoint {
+ };
+ };
+
+- msmgpio: pinctrl@1000000 {
++ tlmm: pinctrl@1000000 {
+ compatible = "qcom,msm8916-pinctrl";
+ reg = <0x01000000 0x300000>;
+ interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+- gpio-ranges = <&msmgpio 0 0 122>;
++ gpio-ranges = <&tlmm 0 0 122>;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+--
+2.40.1
+
--- /dev/null
+From 0ed4269ddc14efcc145fa0ffb8870bc7983d3dbd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Jun 2023 18:24:27 +0200
+Subject: arm64: dts: qcom: msm8996: Add missing interrupt to the USB2
+ controller
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit 36541089c4733355ed844c67eebd0c3936953454 ]
+
+The interrupt line was previously not described. Take care of that.
+
+Fixes: 1e39255ed29d ("arm64: dts: msm8996: Add device node for qcom,dwc3")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230627-topic-more_bindings-v1-11-6b4b6cd081e5@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/msm8996.dtsi | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
+index 25fe2b8552fc7..157d2a2ec32ad 100644
+--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
+@@ -3336,6 +3336,9 @@ usb2: usb@76f8800 {
+ #size-cells = <1>;
+ ranges;
+
++ interrupts = <GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-names = "hs_phy_irq";
++
+ clocks = <&gcc GCC_PERIPH_NOC_USB20_AHB_CLK>,
+ <&gcc GCC_USB20_MASTER_CLK>,
+ <&gcc GCC_USB20_MOCK_UTMI_CLK>,
+--
+2.40.1
+
--- /dev/null
+From 1b55db1b41dde015a2944dc2a0e275f5535e7b0a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 5 Aug 2023 15:09:37 +0200
+Subject: arm64: dts: qcom: msm8996: Fix dsi1 interrupts
+
+From: David Wronek <davidwronek@gmail.com>
+
+[ Upstream commit bd3b4ac11845b428996cfd2c7b8302ba6a07340d ]
+
+Fix IRQ flags mismatch which was keeping dsi1 from probing by changing
+interrupts = <4> to interrupts = <5>.
+
+Fixes: 2752bb7d9b58 ("arm64: dts: qcom: msm8996: add second DSI interface")
+Signed-off-by: David Wronek <davidwronek@gmail.com>
+Acked-by: Yassine Oudjana <y.oudjana@protonmail.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230805130936.359860-2-davidwronek@gmail.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/msm8996.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
+index 157d2a2ec32ad..61da7fc281b32 100644
+--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
+@@ -1075,7 +1075,7 @@ dsi1: dsi@996000 {
+ reg-names = "dsi_ctrl";
+
+ interrupt-parent = <&mdss>;
+- interrupts = <4>;
++ interrupts = <5>;
+
+ clocks = <&mmcc MDSS_MDP_CLK>,
+ <&mmcc MDSS_BYTE1_CLK>,
+--
+2.40.1
+
--- /dev/null
+From 846a25132906bfc5f6a5b9709f7fc76e8aef89ba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Jul 2023 13:53:31 +0200
+Subject: arm64: dts: qcom: msm8996-gemini: fix touchscreen VIO supply
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 21fc24ee9c5943732c9ae538766c9be93d70d936 ]
+
+According to bindings and Linux driver, there is no VDDA but VIO supply.
+
+Fixes: 4ac46b3682c5 ("arm64: dts: qcom: msm8996: xiaomi-gemini: Add support for Xiaomi Mi 5")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20230720115335.137354-2-krzysztof.kozlowski@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/msm8996-xiaomi-gemini.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8996-xiaomi-gemini.dts b/arch/arm64/boot/dts/qcom/msm8996-xiaomi-gemini.dts
+index 100123d514944..f1d990dd7f7c9 100644
+--- a/arch/arm64/boot/dts/qcom/msm8996-xiaomi-gemini.dts
++++ b/arch/arm64/boot/dts/qcom/msm8996-xiaomi-gemini.dts
+@@ -82,7 +82,7 @@ synaptics@20 {
+ #size-cells = <0>;
+ interrupt-parent = <&tlmm>;
+ interrupts = <125 IRQ_TYPE_LEVEL_LOW>;
+- vdda-supply = <&vreg_l6a_1p8>;
++ vio-supply = <&vreg_l6a_1p8>;
+ vdd-supply = <&vdd_3v2_tp>;
+ reset-gpios = <&tlmm 89 GPIO_ACTIVE_LOW>;
+
+--
+2.40.1
+
--- /dev/null
+From c6b6de8619900910ded9caea9586fa3b91c6eb8e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Aug 2023 21:20:25 +0200
+Subject: arm64: dts: qcom: msm8998: Add missing power domain to MMSS SMMU
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit 7f828f3207142351750e9545527341425187de7b ]
+
+The MMSS SMMU has its own power domain. Attach it so that we can drop
+the "keep it always-on" hack.
+
+Fixes: 05ce21b54423 ("arm64: dts: qcom: msm8998: Configure the multimedia subsystem iommu")
+Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com>
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230531-topic-8998_mmssclk-v3-2-ba1b1fd9ee75@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/msm8998.dtsi | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8998.dtsi b/arch/arm64/boot/dts/qcom/msm8998.dtsi
+index 0bc98d3602340..f7c2820b1aacb 100644
+--- a/arch/arm64/boot/dts/qcom/msm8998.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8998.dtsi
+@@ -2455,6 +2455,8 @@ mmss_smmu: iommu@cd00000 {
+ <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>;
++
++ power-domains = <&mmcc BIMC_SMMU_GDSC>;
+ };
+
+ remoteproc_adsp: remoteproc@17300000 {
+--
+2.40.1
+
--- /dev/null
+From 8dad881f67a0481b2c276ef3d1c9155b5e2ec505 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Aug 2023 21:20:24 +0200
+Subject: arm64: dts: qcom: msm8998: Drop bus clock reference from MMSS SMMU
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit a3ce236364b82688ca4c7605f63c4efd68e9589c ]
+
+The MMSS SMMU has been abusingly consuming the exposed RPM interconnect
+clock. Drop it.
+
+Fixes: 05ce21b54423 ("arm64: dts: qcom: msm8998: Configure the multimedia subsystem iommu")
+Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com>
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230531-topic-8998_mmssclk-v3-1-ba1b1fd9ee75@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/msm8998.dtsi | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8998.dtsi b/arch/arm64/boot/dts/qcom/msm8998.dtsi
+index 3ec941fed14fe..0bc98d3602340 100644
+--- a/arch/arm64/boot/dts/qcom/msm8998.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8998.dtsi
+@@ -2428,10 +2428,10 @@ mmss_smmu: iommu@cd00000 {
+
+ clocks = <&mmcc MNOC_AHB_CLK>,
+ <&mmcc BIMC_SMMU_AHB_CLK>,
+- <&rpmcc RPM_SMD_MMAXI_CLK>,
+ <&mmcc BIMC_SMMU_AXI_CLK>;
+- clock-names = "iface-mm", "iface-smmu",
+- "bus-mm", "bus-smmu";
++ clock-names = "iface-mm",
++ "iface-smmu",
++ "bus-smmu";
+
+ #global-interrupts = <0>;
+ interrupts =
+--
+2.40.1
+
--- /dev/null
+From bd9254bd63e62581fe9e926fe3e943ce7643af30 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Jun 2023 22:00:25 +0200
+Subject: arm64: dts: qcom: pm6150l: Add missing short interrupt
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit 7e1f024ef0d1da456f61d00f01dc3287ede915b3 ]
+
+Add the missing short interrupt. This fixes the schema warning:
+
+wled@d800: interrupt-names: ['ovp'] is too short
+
+Fixes: fe508ced49dd ("arm64: dts: qcom: pm6150l: Add wled node")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Reviewed-by: Luca Weiss <luca@z3ntu.xyz>
+Link: https://lore.kernel.org/r/20230626-topic-bindingsfixups-v1-3-254ae8642e69@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/pm6150l.dtsi | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/pm6150l.dtsi b/arch/arm64/boot/dts/qcom/pm6150l.dtsi
+index 6f7aa67501e27..0fdf440596c01 100644
+--- a/arch/arm64/boot/dts/qcom/pm6150l.dtsi
++++ b/arch/arm64/boot/dts/qcom/pm6150l.dtsi
+@@ -121,8 +121,9 @@ pm6150l_flash: led-controller@d300 {
+ pm6150l_wled: leds@d800 {
+ compatible = "qcom,pm6150l-wled";
+ reg = <0xd800>, <0xd900>;
+- interrupts = <0x5 0xd8 0x1 IRQ_TYPE_EDGE_RISING>;
+- interrupt-names = "ovp";
++ interrupts = <0x5 0xd8 0x1 IRQ_TYPE_EDGE_RISING>,
++ <0x5 0xd8 0x2 IRQ_TYPE_EDGE_RISING>;
++ interrupt-names = "ovp", "short";
+ label = "backlight";
+
+ status = "disabled";
+--
+2.40.1
+
--- /dev/null
+From 468e0332a16c724c9256abdeba6badb409caac40 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Jun 2023 22:00:26 +0200
+Subject: arm64: dts: qcom: pm660l: Add missing short interrupt
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit 9a4ac09db3c7413e334b4abd6b2f6de8930dd781 ]
+
+Add the missing short interrupt. This fixes the schema warning:
+
+wled@d800: interrupt-names: ['ovp'] is too short
+
+Fixes: 7b56a804e58b ("arm64: dts: qcom: pm660l: Add WLED support")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230626-topic-bindingsfixups-v1-4-254ae8642e69@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/pm660l.dtsi | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/pm660l.dtsi b/arch/arm64/boot/dts/qcom/pm660l.dtsi
+index 87b71b7205b85..6fdbf507c262a 100644
+--- a/arch/arm64/boot/dts/qcom/pm660l.dtsi
++++ b/arch/arm64/boot/dts/qcom/pm660l.dtsi
+@@ -74,8 +74,9 @@ pm660l_lpg: pwm {
+ pm660l_wled: leds@d800 {
+ compatible = "qcom,pm660l-wled";
+ reg = <0xd800>, <0xd900>;
+- interrupts = <0x3 0xd8 0x1 IRQ_TYPE_EDGE_RISING>;
+- interrupt-names = "ovp";
++ interrupts = <0x3 0xd8 0x1 IRQ_TYPE_EDGE_RISING>,
++ <0x3 0xd8 0x2 IRQ_TYPE_EDGE_RISING>;
++ interrupt-names = "ovp", "short";
+ label = "backlight";
+
+ status = "disabled";
+--
+2.40.1
+
--- /dev/null
+From 21fabbf2be55c624b358444913a726424e196186 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Jul 2023 15:30:21 +0300
+Subject: arm64: dts: qcom: pm8350: fix thermal zone name
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 64f19c06f704846db5e4885ca63c689d9bef5723 ]
+
+The name of the thermal zone in pm8350.dtsi (pm8350c-thermal) conflicts
+with the thermal zone in pm8350c.dtsi. Rename the thermal zone according
+to the chip name.
+
+Fixes: 7a79b95f4288 ("arm64: dts: qcom: pm8350: add temp sensor and thermal zone config")
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://lore.kernel.org/r/20230707123027.1510723-3-dmitry.baryshkov@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/pm8350.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/pm8350.dtsi b/arch/arm64/boot/dts/qcom/pm8350.dtsi
+index 2dfeb99300d74..9ed9ba23e81e4 100644
+--- a/arch/arm64/boot/dts/qcom/pm8350.dtsi
++++ b/arch/arm64/boot/dts/qcom/pm8350.dtsi
+@@ -8,7 +8,7 @@
+
+ / {
+ thermal-zones {
+- pm8350_thermal: pm8350c-thermal {
++ pm8350_thermal: pm8350-thermal {
+ polling-delay-passive = <100>;
+ polling-delay = <0>;
+ thermal-sensors = <&pm8350_temp_alarm>;
+--
+2.40.1
+
--- /dev/null
+From 7074f58f6ee0014cb4afdbad03be56da4669ddb4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Jul 2023 15:30:22 +0300
+Subject: arm64: dts: qcom: pm8350b: fix thermal zone name
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit aad41d9e6c44dfe299cddab97528a5333f17bdfe ]
+
+The name of the thermal zone in pm8350b.dtsi (pm8350c-thermal) conflicts
+with the thermal zone in pm8350c.dtsi. Rename the thermal zone according
+to the chip name.
+
+Fixes: 5c1399299d9d ("arm64: dts: qcom: pm8350b: add temp sensor and thermal zone config")
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://lore.kernel.org/r/20230707123027.1510723-4-dmitry.baryshkov@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/pm8350b.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/pm8350b.dtsi b/arch/arm64/boot/dts/qcom/pm8350b.dtsi
+index f1c7bd9d079c2..05c1058988927 100644
+--- a/arch/arm64/boot/dts/qcom/pm8350b.dtsi
++++ b/arch/arm64/boot/dts/qcom/pm8350b.dtsi
+@@ -8,7 +8,7 @@
+
+ / {
+ thermal-zones {
+- pm8350b_thermal: pm8350c-thermal {
++ pm8350b_thermal: pm8350b-thermal {
+ polling-delay-passive = <100>;
+ polling-delay = <0>;
+ thermal-sensors = <&pm8350b_temp_alarm>;
+--
+2.40.1
+
--- /dev/null
+From a17404c34c7ce4a84dc64955ad26806324a5351b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Jun 2023 22:00:27 +0200
+Subject: arm64: dts: qcom: pmi8950: Add missing OVP interrupt
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit 4d77b639531fd85b84a7079c3369908dfaddf8b2 ]
+
+Add the missing OVP interrupt. This fixes the schema warning:
+
+wled@d800: interrupt-names: ['short'] is too short
+
+Fixes: 0d97fdf380b4 ("arm64: dts: qcom: Add configuration for PMI8950 peripheral")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230626-topic-bindingsfixups-v1-5-254ae8642e69@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/pmi8950.dtsi | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/pmi8950.dtsi b/arch/arm64/boot/dts/qcom/pmi8950.dtsi
+index 4891be3cd68a3..c16adca4e93a9 100644
+--- a/arch/arm64/boot/dts/qcom/pmi8950.dtsi
++++ b/arch/arm64/boot/dts/qcom/pmi8950.dtsi
+@@ -87,8 +87,9 @@ pmic@3 {
+ pmi8950_wled: leds@d800 {
+ compatible = "qcom,pmi8950-wled";
+ reg = <0xd800>, <0xd900>;
+- interrupts = <0x3 0xd8 0x02 IRQ_TYPE_EDGE_RISING>;
+- interrupt-names = "short";
++ interrupts = <0x3 0xd8 0x1 IRQ_TYPE_EDGE_RISING>,
++ <0x3 0xd8 0x2 IRQ_TYPE_EDGE_RISING>;
++ interrupt-names = "ovp", "short";
+ label = "backlight";
+
+ status = "disabled";
+--
+2.40.1
+
--- /dev/null
+From 7b91b93585ffc6da1ebed232c37c23da52322eda Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Jun 2023 22:00:28 +0200
+Subject: arm64: dts: qcom: pmi8994: Add missing OVP interrupt
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit 8db94432690371b1736e9a2566a9b3d8a73d5a97 ]
+
+Add the missing OVP interrupt. This fixes the schema warning:
+
+wled@d800: interrupt-names: ['short'] is too short
+
+Fixes: 37aa540cbd30 ("arm64: dts: qcom: pmi8994: Add WLED node")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230626-topic-bindingsfixups-v1-6-254ae8642e69@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/pmi8994.dtsi | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/pmi8994.dtsi b/arch/arm64/boot/dts/qcom/pmi8994.dtsi
+index 0192968f4d9b3..36d6a1fb553ac 100644
+--- a/arch/arm64/boot/dts/qcom/pmi8994.dtsi
++++ b/arch/arm64/boot/dts/qcom/pmi8994.dtsi
+@@ -54,8 +54,9 @@ pmi8994_spmi_regulators: regulators {
+ pmi8994_wled: wled@d800 {
+ compatible = "qcom,pmi8994-wled";
+ reg = <0xd800>, <0xd900>;
+- interrupts = <3 0xd8 0x02 IRQ_TYPE_EDGE_RISING>;
+- interrupt-names = "short";
++ interrupts = <0x3 0xd8 0x1 IRQ_TYPE_EDGE_RISING>,
++ <0x3 0xd8 0x2 IRQ_TYPE_EDGE_RISING>;
++ interrupt-names = "ovp", "short";
+ qcom,cabc;
+ qcom,external-pfet;
+ status = "disabled";
+--
+2.40.1
+
--- /dev/null
+From 333d16b4351958cc60f5ddc17138db7915414000 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Jul 2023 15:30:24 +0300
+Subject: arm64: dts: qcom: pmk8350: fix ADC-TM compatible string
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 435a73d7377ceb29c1a22d2711dd85c831b40c45 ]
+
+The commit b2de43136058 ("arm64: dts: qcom: pmk8350: Add peripherals for
+pmk8350") for the ADC TM (thermal monitoring device) have used the
+compatible string from the vendor kernel ("qcom,adc-tm7"). Use the
+proper compatible string that is defined in the upstream kernel
+("qcom,spmi-adc-tm5-gen2").
+
+Fixes: b2de43136058 ("arm64: dts: qcom: pmk8350: Add peripherals for pmk8350")
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://lore.kernel.org/r/20230707123027.1510723-6-dmitry.baryshkov@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/pmk8350.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/pmk8350.dtsi b/arch/arm64/boot/dts/qcom/pmk8350.dtsi
+index f26fb7d32faf2..767ab7f284608 100644
+--- a/arch/arm64/boot/dts/qcom/pmk8350.dtsi
++++ b/arch/arm64/boot/dts/qcom/pmk8350.dtsi
+@@ -49,7 +49,7 @@ pmk8350_vadc: adc@3100 {
+ };
+
+ pmk8350_adc_tm: adc-tm@3400 {
+- compatible = "qcom,adc-tm7";
++ compatible = "qcom,spmi-adc-tm5-gen2";
+ reg = <0x3400>;
+ interrupts = <PMK8350_SID 0x34 0x0 IRQ_TYPE_EDGE_RISING>;
+ #address-cells = <1>;
+--
+2.40.1
+
--- /dev/null
+From 243f8c73f8d5e3724a986473d2eaede0f63eb279 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Jul 2023 15:30:23 +0300
+Subject: arm64: dts: qcom: pmr735b: fix thermal zone name
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 99f8cf491d546cd668236f573c7d846d3e94f2d6 ]
+
+The name of the thermal zone in pmr735b.dtsi (pmr735a-thermal) conflicts
+with the thermal zone in pmr735a.dtsi. Rename the thermal zone according
+to the chip name.
+
+Fixes: 6f3426b3dea4 ("arm64: dts: qcom: pmr735b: add temp sensor and thermal zone config")
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://lore.kernel.org/r/20230707123027.1510723-5-dmitry.baryshkov@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/pmr735b.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/pmr735b.dtsi b/arch/arm64/boot/dts/qcom/pmr735b.dtsi
+index ec24c4478005a..f7473e2473224 100644
+--- a/arch/arm64/boot/dts/qcom/pmr735b.dtsi
++++ b/arch/arm64/boot/dts/qcom/pmr735b.dtsi
+@@ -8,7 +8,7 @@
+
+ / {
+ thermal-zones {
+- pmr735a_thermal: pmr735a-thermal {
++ pmr735b_thermal: pmr735b-thermal {
+ polling-delay-passive = <100>;
+ polling-delay = <0>;
+ thermal-sensors = <&pmr735b_temp_alarm>;
+--
+2.40.1
+
--- /dev/null
+From 8d9237d9725d9e0f127fd70fa99b9634cad605a7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Jun 2023 17:56:16 +0200
+Subject: arm64: dts: qcom: sc8280xp: Add missing SCM interconnect
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit 0a69ccf20b0837db857abfc94d7e3bacf1cb771b ]
+
+The SCM interconnect path was missing. Add it.
+
+Fixes: 152d1faf1e2f ("arm64: dts: qcom: add SC8280XP platform")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Reviewed-by: Johan Hovold <johan+linaro@kernel.org>
+Tested-by: Johan Hovold <johan+linaro@kernel.org>
+Link: https://lore.kernel.org/r/20230622-topic-8280scmicc-v1-2-6ef318919ea5@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sc8280xp.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
+index cc4aef21e6172..9c3fb75e06005 100644
+--- a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
+@@ -296,6 +296,7 @@ CLUSTER_SLEEP_0: cluster-sleep-0 {
+ firmware {
+ scm: scm {
+ compatible = "qcom,scm-sc8280xp", "qcom,scm";
++ interconnects = <&aggre2_noc MASTER_CRYPTO 0 &mc_virt SLAVE_EBI1 0>;
+ };
+ };
+
+--
+2.40.1
+
--- /dev/null
+From 02b0a0f28b714743eef8378745f61d35cb9cfbc9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Jun 2023 13:39:14 -0700
+Subject: arm64: dts: qcom: sc8280xp-crd: Correct vreg_misc_3p3 GPIO
+
+From: Bjorn Andersson <quic_bjorande@quicinc.com>
+
+[ Upstream commit 9566b5271f68bdf6e69b7c511850e3fb75cd18be ]
+
+The vreg_misc_3p3 regulator is controlled by PMC8280_1 GPIO 2, not 1, on
+the CRD.
+
+Fixes: ccd3517faf18 ("arm64: dts: qcom: sc8280xp: Add reference device")
+Signed-off-by: Bjorn Andersson <quic_bjorande@quicinc.com>
+Reviewed-by: Johan Hovold <johan+linaro@kernel.org>
+Tested-by: Johan Hovold <johan+linaro@kernel.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230620203915.141337-1-quic_bjorande@quicinc.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sc8280xp-crd.dts | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts b/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts
+index 5b25d54b95911..4fa9a4f242273 100644
+--- a/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts
++++ b/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts
+@@ -167,7 +167,7 @@ vreg_misc_3p3: regulator-misc-3p3 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+- gpio = <&pmc8280_1_gpios 1 GPIO_ACTIVE_HIGH>;
++ gpio = <&pmc8280_1_gpios 2 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-names = "default";
+@@ -696,7 +696,7 @@ edp_bl_reg_en: edp-bl-reg-en-state {
+ };
+
+ misc_3p3_reg_en: misc-3p3-reg-en-state {
+- pins = "gpio1";
++ pins = "gpio2";
+ function = "normal";
+ };
+ };
+--
+2.40.1
+
--- /dev/null
+From 89e3dcf548e72461c86f188d669a9307fa84b843 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Aug 2023 15:05:26 +0200
+Subject: arm64: dts: qcom: sc8280xp-x13s: Unreserve NC pins
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit 7868ed0144b33903e16a50485775f669c109e41a ]
+
+Pins 83-86 and 158-160 are NC, so there's no point in keeping them
+reserved. Take care of that.
+
+Fixes: 32c231385ed4 ("arm64: dts: qcom: sc8280xp: add Lenovo Thinkpad X13s devicetree")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230803-topic-x13s_pin-v1-1-fae792274e89@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts b/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts
+index bdcba719fc385..9fa9b40b41b49 100644
+--- a/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts
++++ b/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts
+@@ -1212,7 +1212,7 @@ hastings_reg_en: hastings-reg-en-state {
+ };
+
+ &tlmm {
+- gpio-reserved-ranges = <70 2>, <74 6>, <83 4>, <125 2>, <128 2>, <154 7>;
++ gpio-reserved-ranges = <70 2>, <74 6>, <125 2>, <128 2>, <154 4>;
+
+ bt_default: bt-default-state {
+ hstp-bt-en-pins {
+--
+2.40.1
+
--- /dev/null
+From 00602e79115a16bdb96aa49b498a9e309acec7dd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Jul 2023 11:10:48 +0530
+Subject: arm64: dts: qcom: sdm845: Add missing RPMh power domain to GCC
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+[ Upstream commit 4b6ea15c0a1122422b44bf6c47a3c22fc8d46777 ]
+
+GCC and it's GDSCs are under the RPMh CX power domain. So let's add the
+missing RPMh power domain to the GCC node.
+
+Fixes: 6d4cf750d03a ("arm64: dts: sdm845: Add minimal dts/dtsi files for sdm845 SoC and MTP")
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Co-developed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/r/20230720054100.9940-4-manivannan.sadhasivam@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sdm845.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
+index 1bfb938e284fb..43b1471f5826d 100644
+--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
++++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
+@@ -1207,6 +1207,7 @@ gcc: clock-controller@100000 {
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ #power-domain-cells = <1>;
++ power-domains = <&rpmhpd SDM845_CX>;
+ };
+
+ qfprom@784000 {
+--
+2.40.1
+
--- /dev/null
+From 2653df885307d6bf5a32c574e900abd575aecd76 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Jul 2023 11:10:49 +0530
+Subject: arm64: dts: qcom: sdm845: Fix the min frequency of "ice_core_clk"
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+[ Upstream commit bbbef6e24bc4493602df68b052f6f48d48e3184a ]
+
+Minimum frequency of the "ice_core_clk" should be 75MHz as specified in the
+downstream vendor devicetree. So fix it!
+
+https://git.codelinaro.org/clo/la/kernel/msm-4.9/-/blob/LA.UM.7.3.r1-09300-sdm845.0/arch/arm64/boot/dts/qcom/sdm845.dtsi
+
+Fixes: 433f9a57298f ("arm64: dts: sdm845: add Inline Crypto Engine registers and clock")
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/r/20230720054100.9940-5-manivannan.sadhasivam@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sdm845.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
+index 43b1471f5826d..b73ce14ababd1 100644
+--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
++++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
+@@ -2614,7 +2614,7 @@ ufs_mem_hc: ufshc@1d84000 {
+ <0 0>,
+ <0 0>,
+ <0 0>,
+- <0 300000000>;
++ <75000000 300000000>;
+
+ status = "disabled";
+ };
+--
+2.40.1
+
--- /dev/null
+From 856bb08f4ff4cafa050d714882bf4b5427615904 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Jun 2023 19:27:50 +0200
+Subject: arm64: dts: qcom: sdm845-tama: Set serial indices and stdout-path
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit 9acc60c3e2d449243e4c2126e3b56f1c4f7fd3bc ]
+
+UART6 is used for debug (routed via uSD pins) and UART9 is connected
+to the bluetooth chip.
+
+Set indexed aliases to make the GENI UART driver happy and route serial
+traffic through the debug uart by default.
+
+Fixes: 30a7f99befc6 ("arm64: dts: qcom: Add support for SONY Xperia XZ2 / XZ2C / XZ3 (Tama platform)")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Reviewed-by: Marijn Suijten <marijn.suijten@somainline.org>
+Link: https://lore.kernel.org/r/20230627-topic-tama_uart-v1-1-0fa790248db8@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama.dtsi | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama.dtsi b/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama.dtsi
+index 420ffede3e804..25e06add95652 100644
+--- a/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama.dtsi
++++ b/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama.dtsi
+@@ -15,6 +15,15 @@ / {
+ qcom,msm-id = <321 0x20001>; /* SDM845 v2.1 */
+ qcom,board-id = <8 0>;
+
++ aliases {
++ serial0 = &uart6;
++ serial1 = &uart9;
++ };
++
++ chosen {
++ stdout-path = "serial0:115200n8";
++ };
++
+ gpio-keys {
+ compatible = "gpio-keys";
+
+--
+2.40.1
+
--- /dev/null
+From 288da051ad298332c060b265406b56dc7f20ef82 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Jun 2023 13:35:37 +0200
+Subject: arm64: dts: qcom: sm6350: Fix ZAP region
+
+From: Konrad Dybcio <konrad.dybcio@somainline.org>
+
+[ Upstream commit 44bcded2be4fe9b9d0b6e48075c9947b75c0af63 ]
+
+The previous ZAP region definition was wrong. Fix it.
+Note this is not a device-specific fixup, but a fixup to the generic
+PIL load address.
+
+Fixes: 5f82b9cda61e ("arm64: dts: qcom: Add SM6350 device tree")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@somainline.org>
+Reviewed-by: Luca Weiss <luca.weiss@fairphone.com>
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230315-topic-lagoon_gpu-v2-6-afcdfb18bb13@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm6350.dtsi | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm6350.dtsi b/arch/arm64/boot/dts/qcom/sm6350.dtsi
+index ad34301f6cddf..18dc3119eea10 100644
+--- a/arch/arm64/boot/dts/qcom/sm6350.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm6350.dtsi
+@@ -473,11 +473,6 @@ pil_ipa_gsi_mem: memory@8b710000 {
+ no-map;
+ };
+
+- pil_gpu_mem: memory@8b715400 {
+- reg = <0 0x8b715400 0 0x2000>;
+- no-map;
+- };
+-
+ pil_modem_mem: memory@8b800000 {
+ reg = <0 0x8b800000 0 0xf800000>;
+ no-map;
+@@ -498,6 +493,11 @@ removed_region: memory@c0000000 {
+ no-map;
+ };
+
++ pil_gpu_mem: memory@f0d00000 {
++ reg = <0 0xf0d00000 0 0x1000>;
++ no-map;
++ };
++
+ debug_region: memory@ffb00000 {
+ reg = <0 0xffb00000 0 0xc0000>;
+ no-map;
+--
+2.40.1
+
--- /dev/null
+From 88feafb9eb82ca14d1ec2654f743f7139a9015c8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Jul 2023 10:53:21 +0800
+Subject: arm64: dts: qcom: sm8150: Fix the I2C7 interrupt
+
+From: Zeyan Li <qaz6750@outlook.com>
+
+[ Upstream commit f9568d22ce06192a7e14bda3a29dc216659554ff ]
+
+I2C6 and I2C7 use the same interrupts, which is incorrect.
+In the downstream kernel, I2C7 has interrupts of 608 instead of 607.
+
+Fixes: 81bee6953b58 ("arm64: dts: qcom: sm8150: add i2c nodes")
+Signed-off-by: Zeyan Li <qaz6750@outlook.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/SY7P282MB378712225CBCEA95FE71554DB201A@SY7P282MB3787.AUSP282.PROD.OUTLOOK.COM
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8150.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi
+index fe2d401a858a7..c4d87092e6d9c 100644
+--- a/arch/arm64/boot/dts/qcom/sm8150.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi
+@@ -1231,7 +1231,7 @@ i2c7: i2c@89c000 {
+ dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&qup_i2c7_default>;
+- interrupts = <GIC_SPI 607 IRQ_TYPE_LEVEL_HIGH>;
++ interrupts = <GIC_SPI 608 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+--
+2.40.1
+
--- /dev/null
+From 700ca5adf637821c113bdefc28e5d978f407dc65 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 Jun 2023 06:16:23 +0300
+Subject: arm64: dts: qcom: sm8150: use proper DSI PHY compatible
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 3091e5820a367f3368132f57e0a9ba6d545da15d ]
+
+The DSI PHY on the Qualcomm SM8150 platform requires platform-specific
+handling. Use the proper SoC-specific compatible string for the DSI
+PHYs.
+
+Reported-by: Degdag Mohamed <degdagmohamed@gmail.com>
+Fixes: 2ef3bb17c45c ("arm64: dts: qcom: sm8150: Add DISPCC node")
+Cc: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Marijn Suijten <marijn.suijten@somainline.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230612031623.3620155-1-dmitry.baryshkov@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8150.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi
+index 27dcda0d4288f..fe2d401a858a7 100644
+--- a/arch/arm64/boot/dts/qcom/sm8150.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi
+@@ -3805,7 +3805,7 @@ opp-358000000 {
+ };
+
+ mdss_dsi0_phy: phy@ae94400 {
+- compatible = "qcom,dsi-phy-7nm";
++ compatible = "qcom,dsi-phy-7nm-8150";
+ reg = <0 0x0ae94400 0 0x200>,
+ <0 0x0ae94600 0 0x280>,
+ <0 0x0ae94900 0 0x260>;
+@@ -3879,7 +3879,7 @@ mdss_dsi1_out: endpoint {
+ };
+
+ mdss_dsi1_phy: phy@ae96400 {
+- compatible = "qcom,dsi-phy-7nm";
++ compatible = "qcom,dsi-phy-7nm-8150";
+ reg = <0 0x0ae96400 0 0x200>,
+ <0 0x0ae96600 0 0x280>,
+ <0 0x0ae96900 0 0x260>;
+--
+2.40.1
+
--- /dev/null
+From 0805b2629347c2f8c7b69f8f370bc4bdaeaa7bf3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Jun 2023 17:48:52 +0200
+Subject: arm64: dts: qcom: sm8250: correct dynamic power coefficients
+
+From: Vincent Guittot <vincent.guittot@linaro.org>
+
+[ Upstream commit 775a5283c25d160b2a1359018c447bc518096547 ]
+
+sm8250 faces the same problem with its Energy Model as sdm845. The energy
+cost of LITTLE cores is reported to be higher than medium or big cores
+
+EM computes the energy with formula:
+
+energy = OPP's cost / maximum cpu capacity * utilization
+
+On v6.4-rc6 we have:
+max capacity of CPU0 = 284
+capacity of CPU0's OPP(1612800 Hz) = 253
+cost of CPU0's OPP(1612800 Hz) = 191704
+
+max capacity of CPU4 = 871
+capacity of CPU4's OPP(710400 Hz) = 255
+cost of CPU4's OPP(710400 Hz) = 343217
+
+Both OPPs have almost the same compute capacity but the estimated energy
+per unit of utilization will be estimated to:
+
+energy CPU0 = 191704 / 284 * 1 = 675
+energy CPU4 = 343217 / 871 * 1 = 394
+
+EM estimates that little CPU0 will consume 71% more than medium CPU4 for
+the same compute capacity. According to [1], little consumes 25% less than
+medium core for Coremark benchmark at those OPPs for the same duration.
+
+Set the dynamic-power-coefficient of CPU0-3 to 105 to fix the energy model
+for little CPUs.
+
+[1] https://github.com/kdrag0n/freqbench/tree/master/results/sm8250/k30s
+
+Fixes: 6aabed5526ee ("arm64: dts: qcom: sm8250: Add CPU capacities and energy model")
+Signed-off-by: Vincent Guittot <vincent.guittot@linaro.org>
+Link: https://lore.kernel.org/r/20230615154852.130076-1-vincent.guittot@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8250.dtsi | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi
+index 7bea916900e29..4b0835109b01e 100644
+--- a/arch/arm64/boot/dts/qcom/sm8250.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi
+@@ -100,7 +100,7 @@ CPU0: cpu@0 {
+ clocks = <&cpufreq_hw 0>;
+ enable-method = "psci";
+ capacity-dmips-mhz = <448>;
+- dynamic-power-coefficient = <205>;
++ dynamic-power-coefficient = <105>;
+ next-level-cache = <&L2_0>;
+ power-domains = <&CPU_PD0>;
+ power-domain-names = "psci";
+@@ -131,7 +131,7 @@ CPU1: cpu@100 {
+ clocks = <&cpufreq_hw 0>;
+ enable-method = "psci";
+ capacity-dmips-mhz = <448>;
+- dynamic-power-coefficient = <205>;
++ dynamic-power-coefficient = <105>;
+ next-level-cache = <&L2_100>;
+ power-domains = <&CPU_PD1>;
+ power-domain-names = "psci";
+@@ -156,7 +156,7 @@ CPU2: cpu@200 {
+ clocks = <&cpufreq_hw 0>;
+ enable-method = "psci";
+ capacity-dmips-mhz = <448>;
+- dynamic-power-coefficient = <205>;
++ dynamic-power-coefficient = <105>;
+ next-level-cache = <&L2_200>;
+ power-domains = <&CPU_PD2>;
+ power-domain-names = "psci";
+@@ -181,7 +181,7 @@ CPU3: cpu@300 {
+ clocks = <&cpufreq_hw 0>;
+ enable-method = "psci";
+ capacity-dmips-mhz = <448>;
+- dynamic-power-coefficient = <205>;
++ dynamic-power-coefficient = <105>;
+ next-level-cache = <&L2_300>;
+ power-domains = <&CPU_PD3>;
+ power-domain-names = "psci";
+--
+2.40.1
+
--- /dev/null
+From 2e35388dbfef639f48ad4b7fa8735ee7b9520e45 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Jun 2023 13:05:35 +0200
+Subject: arm64: dts: qcom: sm8250-edo: Add GPIO line names for PMIC GPIOs
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit 6b8a63350752c6a5e4b54f2de6174084652cd3cd ]
+
+Sony ever so graciously provides GPIO line names in their downstream
+kernel (though sometimes they are not 100% accurate and you can judge
+that by simply looking at them and with what drivers they are used).
+
+Add these to the PDX203&206 DTSIs to better document the hardware.
+
+Diff between 203 and 206:
+pm8009_gpios
+< "CAM_PWR_LD_EN",
+> "NC",
+
+pm8150_gpios
+< "NC",
+> "G_ASSIST_N",
+< "WLC_EN_N", /* GPIO_10 */
+> "NC", /* GPIO_10 */
+Which is due to 5 II having an additional Google Assistant hardware
+button and 1 II having a wireless charger & different camera wiring
+to accommodate the additional 3D iToF sensor.
+
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230614-topic-edo_pinsgpiopmic-v2-2-6f90bba54c53@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Stable-dep-of: a422c6a91a66 ("arm64: dts: qcom: sm8250-edo: Rectify gpio-keys")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../qcom/sm8250-sony-xperia-edo-pdx203.dts | 50 +++++++++++++++++++
+ .../qcom/sm8250-sony-xperia-edo-pdx206.dts | 50 +++++++++++++++++++
+ 2 files changed, 100 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo-pdx203.dts b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo-pdx203.dts
+index 84104d2b20101..62590c6bd3067 100644
+--- a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo-pdx203.dts
++++ b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo-pdx203.dts
+@@ -15,6 +15,56 @@ / {
+
+ /delete-node/ &vreg_l7f_1p8;
+
++&pm8009_gpios {
++ gpio-line-names = "NC", /* GPIO_1 */
++ "CAM_PWR_LD_EN",
++ "WIDEC_PWR_EN",
++ "NC";
++};
++
++&pm8150_gpios {
++ gpio-line-names = "VOL_DOWN_N", /* GPIO_1 */
++ "OPTION_2",
++ "NC",
++ "PM_SLP_CLK_IN",
++ "OPTION_1",
++ "NC",
++ "NC",
++ "SP_ARI_PWR_ALARM",
++ "NC",
++ "NC"; /* GPIO_10 */
++};
++
++&pm8150b_gpios {
++ gpio-line-names = "SNAPSHOT_N", /* GPIO_1 */
++ "FOCUS_N",
++ "NC",
++ "NC",
++ "RF_LCD_ID_EN",
++ "NC",
++ "NC",
++ "LCD_ID",
++ "NC",
++ "WLC_EN_N", /* GPIO_10 */
++ "NC",
++ "RF_ID";
++};
++
++&pm8150l_gpios {
++ gpio-line-names = "NC", /* GPIO_1 */
++ "PM3003A_EN",
++ "NC",
++ "NC",
++ "NC",
++ "AUX2_THERM",
++ "BB_HP_EN",
++ "FP_LDO_EN",
++ "PMX_RESET_N",
++ "AUX3_THERM", /* GPIO_10 */
++ "DTV_PWR_EN",
++ "PM3003A_MODE";
++};
++
+ &tlmm {
+ gpio-line-names = "AP_CTI_IN", /* GPIO_0 */
+ "MDM2AP_ERR_FATAL",
+diff --git a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo-pdx206.dts b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo-pdx206.dts
+index fae6568cb79e4..ea4571bf4fbf0 100644
+--- a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo-pdx206.dts
++++ b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo-pdx206.dts
+@@ -30,6 +30,56 @@ g-assist-key {
+ };
+ };
+
++&pm8009_gpios {
++ gpio-line-names = "NC", /* GPIO_1 */
++ "NC",
++ "WIDEC_PWR_EN",
++ "NC";
++};
++
++&pm8150_gpios {
++ gpio-line-names = "VOL_DOWN_N", /* GPIO_1 */
++ "OPTION_2",
++ "NC",
++ "PM_SLP_CLK_IN",
++ "OPTION_1",
++ "G_ASSIST_N",
++ "NC",
++ "SP_ARI_PWR_ALARM",
++ "NC",
++ "NC"; /* GPIO_10 */
++};
++
++&pm8150b_gpios {
++ gpio-line-names = "SNAPSHOT_N", /* GPIO_1 */
++ "FOCUS_N",
++ "NC",
++ "NC",
++ "RF_LCD_ID_EN",
++ "NC",
++ "NC",
++ "LCD_ID",
++ "NC",
++ "NC", /* GPIO_10 */
++ "NC",
++ "RF_ID";
++};
++
++&pm8150l_gpios {
++ gpio-line-names = "NC", /* GPIO_1 */
++ "PM3003A_EN",
++ "NC",
++ "NC",
++ "NC",
++ "AUX2_THERM",
++ "BB_HP_EN",
++ "FP_LDO_EN",
++ "PMX_RESET_N",
++ "NC", /* GPIO_10 */
++ "NC",
++ "PM3003A_MODE";
++};
++
+ &tlmm {
+ gpio-line-names = "AP_CTI_IN", /* GPIO_0 */
+ "MDM2AP_ERR_FATAL",
+--
+2.40.1
+
--- /dev/null
+From 0202c4c865cc9629b463fc97591210ce93ed71db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Jun 2023 13:05:34 +0200
+Subject: arm64: dts: qcom: sm8250-edo: Add gpio line names for TLMM
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit 40b398beabdfe0e9088b13976e56b1dc706fe851 ]
+
+Sony ever so graciously provides GPIO line names in their downstream
+kernel (though sometimes they are not 100% accurate and you can judge
+that by simply looking at them and with what drivers they are used).
+
+Add these to the PDX203&206 DTSIs to better document the hardware.
+
+Diff between 203 and 206:
+< "CAM_PWR_A_CS",
+> "FRONTC_PWR_EN",
+< "CAM4_MCLK",
+< "TOF_RST_N",
+> "NC",
+> "NC",
+< "WLC_I2C_SDA",
+< "WLC_I2C_SCL", /* GPIO_120 */
+> "NC",
+> "NC",
+< "WLC_INT_N",
+> "NC",
+
+Which makes sense, as 203 has a 3D iToF, slightly different camera
+power wiring and WLC (WireLess Charging).
+
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230614-topic-edo_pinsgpiopmic-v2-1-6f90bba54c53@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Stable-dep-of: a422c6a91a66 ("arm64: dts: qcom: sm8250-edo: Rectify gpio-keys")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../qcom/sm8250-sony-xperia-edo-pdx203.dts | 183 ++++++++++++++++++
+ .../qcom/sm8250-sony-xperia-edo-pdx206.dts | 183 ++++++++++++++++++
+ 2 files changed, 366 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo-pdx203.dts b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo-pdx203.dts
+index 356a81698731a..84104d2b20101 100644
+--- a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo-pdx203.dts
++++ b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo-pdx203.dts
+@@ -14,3 +14,186 @@ / {
+ };
+
+ /delete-node/ &vreg_l7f_1p8;
++
++&tlmm {
++ gpio-line-names = "AP_CTI_IN", /* GPIO_0 */
++ "MDM2AP_ERR_FATAL",
++ "AP_CTI_OUT",
++ "MDM2AP_STATUS",
++ "NFC_I2C_SDA",
++ "NFC_I2C_SCL",
++ "NFC_EN",
++ "NFC_CLK_REQ",
++ "NFC_ESE_PWR_REQ",
++ "DVDT_WRT_DET_AND",
++ "SPK_AMP_RESET_N", /* GPIO_10 */
++ "SPK_AMP_INT_N",
++ "APPS_I2C_1_SDA",
++ "APPS_I2C_1_SCL",
++ "NC",
++ "TX_GTR_THRES_IN",
++ "HST_BT_UART_CTS",
++ "HST_BT_UART_RFR",
++ "HST_BT_UART_TX",
++ "HST_BT_UART_RX",
++ "HST_WLAN_EN", /* GPIO_20 */
++ "HST_BT_EN",
++ "RGBC_IR_PWR_EN",
++ "FP_INT_N",
++ "NC",
++ "NC",
++ "NC",
++ "NC",
++ "NFC_ESE_SPI_MISO",
++ "NFC_ESE_SPI_MOSI",
++ "NFC_ESE_SPI_SCLK", /* GPIO_30 */
++ "NFC_ESE_SPI_CS_N",
++ "WCD_RST_N",
++ "NC",
++ "SDM_DEBUG_UART_TX",
++ "SDM_DEBUG_UART_RX",
++ "TS_I2C_SDA",
++ "TS_I2C_SCL",
++ "TS_INT_N",
++ "FP_SPI_MISO", /* GPIO_40 */
++ "FP_SPI_MOSI",
++ "FP_SPI_SCLK",
++ "FP_SPI_CS_N",
++ "APPS_I2C_0_SDA",
++ "APPS_I2C_0_SCL",
++ "DISP_ERR_FG",
++ "UIM2_DETECT_EN",
++ "NC",
++ "NC",
++ "NC", /* GPIO_50 */
++ "NC",
++ "MDM_UART_CTS",
++ "MDM_UART_RFR",
++ "MDM_UART_TX",
++ "MDM_UART_RX",
++ "AP2MDM_STATUS",
++ "AP2MDM_ERR_FATAL",
++ "MDM_IPC_HS_UART_TX",
++ "MDM_IPC_HS_UART_RX",
++ "NC", /* GPIO_60 */
++ "NC",
++ "NC",
++ "NC",
++ "NC",
++ "USB_CC_DIR",
++ "DISP_VSYNC",
++ "NC",
++ "NC",
++ "CAM_PWR_B_CS",
++ "NC", /* GPIO_70 */
++ "CAM_PWR_A_CS",
++ "SBU_SW_SEL",
++ "SBU_SW_OE",
++ "FP_RESET_N",
++ "FP_RESET_N",
++ "DISP_RESET_N",
++ "DEBUG_GPIO0",
++ "TRAY_DET",
++ "CAM2_RST_N",
++ "PCIE0_RST_N",
++ "PCIE0_CLK_REQ_N", /* GPIO_80 */
++ "PCIE0_WAKE_N",
++ "DVDT_ENABLE",
++ "DVDT_WRT_DET_OR",
++ "NC",
++ "PCIE2_RST_N",
++ "PCIE2_CLK_REQ_N",
++ "PCIE2_WAKE_N",
++ "MDM_VFR_IRQ0",
++ "MDM_VFR_IRQ1",
++ "SW_SERVICE", /* GPIO_90 */
++ "CAM_SOF",
++ "CAM1_RST_N",
++ "CAM0_RST_N",
++ "CAM0_MCLK",
++ "CAM1_MCLK",
++ "CAM2_MCLK",
++ "CAM3_MCLK",
++ "CAM4_MCLK",
++ "TOF_RST_N",
++ "NC", /* GPIO_100 */
++ "CCI0_I2C_SDA",
++ "CCI0_I2C_SCL",
++ "CCI1_I2C_SDA",
++ "CCI1_I2C_SCL_",
++ "CCI2_I2C_SDA",
++ "CCI2_I2C_SCL",
++ "CCI3_I2C_SDA",
++ "CCI3_I2C_SCL",
++ "CAM3_RST_N",
++ "NFC_DWL_REQ", /* GPIO_110 */
++ "NFC_IRQ",
++ "XVS",
++ "NC",
++ "RF_ID_EXTENSION",
++ "SPK_AMP_I2C_SDA",
++ "SPK_AMP_I2C_SCL",
++ "NC",
++ "NC",
++ "WLC_I2C_SDA",
++ "WLC_I2C_SCL", /* GPIO_120 */
++ "ACC_COVER_OPEN",
++ "ALS_PROX_INT_N",
++ "ACCEL_INT",
++ "WLAN_SW_CTRL",
++ "CAMSENSOR_I2C_SDA",
++ "CAMSENSOR_I2C_SCL",
++ "UDON_SWITCH_SEL",
++ "WDOG_DISABLE",
++ "BAROMETER_INT",
++ "NC", /* GPIO_130 */
++ "NC",
++ "FORCED_USB_BOOT",
++ "NC",
++ "NC",
++ "WLC_INT_N",
++ "NC",
++ "NC",
++ "RGBC_IR_INT",
++ "NC",
++ "NC", /* GPIO_140 */
++ "NC",
++ "BT_SLIMBUS_CLK",
++ "BT_SLIMBUS_DATA",
++ "HW_ID_0",
++ "HW_ID_1",
++ "WCD_SWR_TX_CLK",
++ "WCD_SWR_TX_DATA0",
++ "WCD_SWR_TX_DATA1",
++ "WCD_SWR_RX_CLK",
++ "WCD_SWR_RX_DATA0", /* GPIO_150 */
++ "WCD_SWR_RX_DATA1",
++ "SDM_DMIC_CLK1",
++ "SDM_DMIC_DATA1",
++ "SDM_DMIC_CLK2",
++ "SDM_DMIC_DATA2",
++ "SPK_AMP_I2S_CLK",
++ "SPK_AMP_I2S_WS",
++ "SPK_AMP_I2S_ASP_DIN",
++ "SPK_AMP_I2S_ASP_DOUT",
++ "COMPASS_I2C_SDA", /* GPIO_160 */
++ "COMPASS_I2C_SCL",
++ "NC",
++ "NC",
++ "SSC_SPI_1_MISO",
++ "SSC_SPI_1_MOSI",
++ "SSC_SPI_1_CLK",
++ "SSC_SPI_1_CS_N",
++ "NC",
++ "NC",
++ "SSC_SENSOR_I2C_SDA", /* GPIO_170 */
++ "SSC_SENSOR_I2C_SCL",
++ "NC",
++ "NC",
++ "NC",
++ "NC",
++ "HST_BLE_SNS_UART6_TX",
++ "HST_BLE_SNS_UART6_RX",
++ "HST_WLAN_UART_TX",
++ "HST_WLAN_UART_RX";
++};
+diff --git a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo-pdx206.dts b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo-pdx206.dts
+index 01fe3974ee720..fae6568cb79e4 100644
+--- a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo-pdx206.dts
++++ b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo-pdx206.dts
+@@ -30,6 +30,189 @@ g-assist-key {
+ };
+ };
+
++&tlmm {
++ gpio-line-names = "AP_CTI_IN", /* GPIO_0 */
++ "MDM2AP_ERR_FATAL",
++ "AP_CTI_OUT",
++ "MDM2AP_STATUS",
++ "NFC_I2C_SDA",
++ "NFC_I2C_SCL",
++ "NFC_EN",
++ "NFC_CLK_REQ",
++ "NFC_ESE_PWR_REQ",
++ "DVDT_WRT_DET_AND",
++ "SPK_AMP_RESET_N", /* GPIO_10 */
++ "SPK_AMP_INT_N",
++ "APPS_I2C_1_SDA",
++ "APPS_I2C_1_SCL",
++ "NC",
++ "TX_GTR_THRES_IN",
++ "HST_BT_UART_CTS",
++ "HST_BT_UART_RFR",
++ "HST_BT_UART_TX",
++ "HST_BT_UART_RX",
++ "HST_WLAN_EN", /* GPIO_20 */
++ "HST_BT_EN",
++ "RGBC_IR_PWR_EN",
++ "FP_INT_N",
++ "NC",
++ "NC",
++ "NC",
++ "NC",
++ "NFC_ESE_SPI_MISO",
++ "NFC_ESE_SPI_MOSI",
++ "NFC_ESE_SPI_SCLK", /* GPIO_30 */
++ "NFC_ESE_SPI_CS_N",
++ "WCD_RST_N",
++ "NC",
++ "SDM_DEBUG_UART_TX",
++ "SDM_DEBUG_UART_RX",
++ "TS_I2C_SDA",
++ "TS_I2C_SCL",
++ "TS_INT_N",
++ "FP_SPI_MISO", /* GPIO_40 */
++ "FP_SPI_MOSI",
++ "FP_SPI_SCLK",
++ "FP_SPI_CS_N",
++ "APPS_I2C_0_SDA",
++ "APPS_I2C_0_SCL",
++ "DISP_ERR_FG",
++ "UIM2_DETECT_EN",
++ "NC",
++ "NC",
++ "NC", /* GPIO_50 */
++ "NC",
++ "MDM_UART_CTS",
++ "MDM_UART_RFR",
++ "MDM_UART_TX",
++ "MDM_UART_RX",
++ "AP2MDM_STATUS",
++ "AP2MDM_ERR_FATAL",
++ "MDM_IPC_HS_UART_TX",
++ "MDM_IPC_HS_UART_RX",
++ "NC", /* GPIO_60 */
++ "NC",
++ "NC",
++ "NC",
++ "NC",
++ "USB_CC_DIR",
++ "DISP_VSYNC",
++ "NC",
++ "NC",
++ "CAM_PWR_B_CS",
++ "NC", /* GPIO_70 */
++ "FRONTC_PWR_EN",
++ "SBU_SW_SEL",
++ "SBU_SW_OE",
++ "FP_RESET_N",
++ "FP_RESET_N",
++ "DISP_RESET_N",
++ "DEBUG_GPIO0",
++ "TRAY_DET",
++ "CAM2_RST_N",
++ "PCIE0_RST_N",
++ "PCIE0_CLK_REQ_N", /* GPIO_80 */
++ "PCIE0_WAKE_N",
++ "DVDT_ENABLE",
++ "DVDT_WRT_DET_OR",
++ "NC",
++ "PCIE2_RST_N",
++ "PCIE2_CLK_REQ_N",
++ "PCIE2_WAKE_N",
++ "MDM_VFR_IRQ0",
++ "MDM_VFR_IRQ1",
++ "SW_SERVICE", /* GPIO_90 */
++ "CAM_SOF",
++ "CAM1_RST_N",
++ "CAM0_RST_N",
++ "CAM0_MCLK",
++ "CAM1_MCLK",
++ "CAM2_MCLK",
++ "CAM3_MCLK",
++ "NC",
++ "NC",
++ "NC", /* GPIO_100 */
++ "CCI0_I2C_SDA",
++ "CCI0_I2C_SCL",
++ "CCI1_I2C_SDA",
++ "CCI1_I2C_SCL_",
++ "CCI2_I2C_SDA",
++ "CCI2_I2C_SCL",
++ "CCI3_I2C_SDA",
++ "CCI3_I2C_SCL",
++ "CAM3_RST_N",
++ "NFC_DWL_REQ", /* GPIO_110 */
++ "NFC_IRQ",
++ "XVS",
++ "NC",
++ "RF_ID_EXTENSION",
++ "SPK_AMP_I2C_SDA",
++ "SPK_AMP_I2C_SCL",
++ "NC",
++ "NC",
++ "NC",
++ "NC",
++ "ACC_COVER_OPEN",
++ "ALS_PROX_INT_N",
++ "ACCEL_INT",
++ "WLAN_SW_CTRL",
++ "CAMSENSOR_I2C_SDA",
++ "CAMSENSOR_I2C_SCL",
++ "UDON_SWITCH_SEL",
++ "WDOG_DISABLE",
++ "BAROMETER_INT",
++ "NC", /* GPIO_130 */
++ "NC",
++ "FORCED_USB_BOOT",
++ "NC",
++ "NC",
++ "NC",
++ "NC",
++ "NC",
++ "RGBC_IR_INT",
++ "NC",
++ "NC", /* GPIO_140 */
++ "NC",
++ "BT_SLIMBUS_CLK",
++ "BT_SLIMBUS_DATA",
++ "HW_ID_0",
++ "HW_ID_1",
++ "WCD_SWR_TX_CLK",
++ "WCD_SWR_TX_DATA0",
++ "WCD_SWR_TX_DATA1",
++ "WCD_SWR_RX_CLK",
++ "WCD_SWR_RX_DATA0", /* GPIO_150 */
++ "WCD_SWR_RX_DATA1",
++ "SDM_DMIC_CLK1",
++ "SDM_DMIC_DATA1",
++ "SDM_DMIC_CLK2",
++ "SDM_DMIC_DATA2",
++ "SPK_AMP_I2S_CLK",
++ "SPK_AMP_I2S_WS",
++ "SPK_AMP_I2S_ASP_DIN",
++ "SPK_AMP_I2S_ASP_DOUT",
++ "COMPASS_I2C_SDA", /* GPIO_160 */
++ "COMPASS_I2C_SCL",
++ "NC",
++ "NC",
++ "SSC_SPI_1_MISO",
++ "SSC_SPI_1_MOSI",
++ "SSC_SPI_1_CLK",
++ "SSC_SPI_1_CS_N",
++ "NC",
++ "NC",
++ "SSC_SENSOR_I2C_SDA", /* GPIO_170 */
++ "SSC_SENSOR_I2C_SCL",
++ "NC",
++ "NC",
++ "NC",
++ "NC",
++ "HST_BLE_SNS_UART6_TX",
++ "HST_BLE_SNS_UART6_RX",
++ "HST_WLAN_UART_TX",
++ "HST_WLAN_UART_RX";
++};
++
+ &vreg_l2f_1p3 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+--
+2.40.1
+
--- /dev/null
+From 330bd70911b12b358a52cb4c47476d7f1f98b31e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Jun 2023 13:05:37 +0200
+Subject: arm64: dts: qcom: sm8250-edo: Rectify gpio-keys
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit a422c6a91a667b309ca1a6c08b30dbfcf7d4e866 ]
+
+Set up the corresponding GPIOs properly and add the leftover hardware
+buttons to mark this piece of the puzzle complete.
+
+Fixes: 46e14907c716 ("arm64: dts: qcom: sm8250-edo: Add hardware keys")
+Reviewed-by: Marijn Suijten <marijn.suijten@somainline.org>
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230614-topic-edo_pinsgpiopmic-v2-4-6f90bba54c53@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../qcom/sm8250-sony-xperia-edo-pdx206.dts | 10 ++++
+ .../boot/dts/qcom/sm8250-sony-xperia-edo.dtsi | 54 ++++++++++++++++---
+ 2 files changed, 58 insertions(+), 6 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo-pdx206.dts b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo-pdx206.dts
+index ea4571bf4fbf0..58a521046f5f5 100644
+--- a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo-pdx206.dts
++++ b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo-pdx206.dts
+@@ -20,6 +20,8 @@ &framebuffer {
+ };
+
+ &gpio_keys {
++ pinctrl-0 = <&focus_n &snapshot_n &vol_down_n &g_assist_n>;
++
+ g-assist-key {
+ label = "Google Assistant Key";
+ linux,code = <KEY_LEFTMETA>;
+@@ -48,6 +50,14 @@ &pm8150_gpios {
+ "SP_ARI_PWR_ALARM",
+ "NC",
+ "NC"; /* GPIO_10 */
++
++ g_assist_n: g-assist-n-state {
++ pins = "gpio6";
++ function = "normal";
++ power-source = <1>;
++ bias-pull-up;
++ input-enable;
++ };
+ };
+
+ &pm8150b_gpios {
+diff --git a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi
+index dcabb714f0f35..eb82247131c10 100644
+--- a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi
+@@ -51,12 +51,26 @@ framebuffer: framebuffer@9c000000 {
+ gpio_keys: gpio-keys {
+ compatible = "gpio-keys";
+
+- /*
+- * Camera focus (light press) and camera snapshot (full press)
+- * seem not to work properly.. Adding the former one stalls the CPU
+- * and the latter kills the volume down key for whatever reason. In any
+- * case, they are both on &pm8150b_gpios: camera focus(2), camera snapshot(1).
+- */
++ pinctrl-0 = <&focus_n &snapshot_n &vol_down_n>;
++ pinctrl-names = "default";
++
++ key-camera-focus {
++ label = "Camera Focus";
++ linux,code = <KEY_CAMERA_FOCUS>;
++ gpios = <&pm8150b_gpios 2 GPIO_ACTIVE_LOW>;
++ debounce-interval = <15>;
++ linux,can-disable;
++ gpio-key,wakeup;
++ };
++
++ key-camera-snapshot {
++ label = "Camera Snapshot";
++ linux,code = <KEY_CAMERA>;
++ gpios = <&pm8150b_gpios 1 GPIO_ACTIVE_LOW>;
++ debounce-interval = <15>;
++ linux,can-disable;
++ gpio-key,wakeup;
++ };
+
+ key-vol-down {
+ label = "Volume Down";
+@@ -551,6 +565,34 @@ &pcie2_phy {
+ vdda-pll-supply = <&vreg_l9a_1p2>;
+ };
+
++&pm8150_gpios {
++ vol_down_n: vol-down-n-state {
++ pins = "gpio1";
++ function = "normal";
++ power-source = <0>;
++ bias-pull-up;
++ input-enable;
++ };
++};
++
++&pm8150b_gpios {
++ snapshot_n: snapshot-n-state {
++ pins = "gpio1";
++ function = "normal";
++ power-source = <0>;
++ bias-pull-up;
++ input-enable;
++ };
++
++ focus_n: focus-n-state {
++ pins = "gpio2";
++ function = "normal";
++ power-source = <0>;
++ bias-pull-up;
++ input-enable;
++ };
++};
++
+ &pon_pwrkey {
+ status = "okay";
+ };
+--
+2.40.1
+
--- /dev/null
+From 710158962b071e486f21f4f6aa9ab24fca488a13 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Jul 2023 14:23:17 +0200
+Subject: arm64: dts: qcom: sm8250: Mark PCIe hosts as DMA coherent
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit 339d38a436f30d0f874815eafc7de2257346bf26 ]
+
+The PCIe hosts on SM8250 are cache-coherent. Mark them as such.
+
+Fixes: e53bdfc00977 ("arm64: dts: qcom: sm8250: Add PCIe support")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230704-topic-8250_pcie_dmac-v1-1-799603a980b0@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8250.dtsi | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi
+index 4b0835109b01e..29f0b0381b278 100644
+--- a/arch/arm64/boot/dts/qcom/sm8250.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi
+@@ -1905,6 +1905,7 @@ pcie0: pci@1c00000 {
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie0_default_state>;
++ dma-coherent;
+
+ status = "disabled";
+ };
+@@ -2011,6 +2012,7 @@ pcie1: pci@1c08000 {
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie1_default_state>;
++ dma-coherent;
+
+ status = "disabled";
+ };
+@@ -2119,6 +2121,7 @@ pcie2: pci@1c10000 {
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie2_default_state>;
++ dma-coherent;
+
+ status = "disabled";
+ };
+--
+2.40.1
+
--- /dev/null
+From 433493ae277893d61dfb023ab5b3b76969297f13 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Jul 2023 08:30:11 +0200
+Subject: arm64: dts: qcom: sm8250-sony-xperia: correct GPIO keys wakeup again
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit b8fbeea0253211d97c579eae787274633d3eaf0d ]
+
+gpio-keys,wakeup is a deprecated property:
+
+ m8250-sony-xperia-edo-pdx206.dtb: gpio-keys: key-camera-focus: Unevaluated properties are not allowed ('gpio-key,wakeup' was unexpected)
+
+Fixes: a422c6a91a66 ("arm64: dts: qcom: sm8250-edo: Rectify gpio-keys")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230711063011.16222-1-krzysztof.kozlowski@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi
+index eb82247131c10..0268d80248e5c 100644
+--- a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi
+@@ -60,7 +60,7 @@ key-camera-focus {
+ gpios = <&pm8150b_gpios 2 GPIO_ACTIVE_LOW>;
+ debounce-interval = <15>;
+ linux,can-disable;
+- gpio-key,wakeup;
++ wakeup-source;
+ };
+
+ key-camera-snapshot {
+@@ -69,7 +69,7 @@ key-camera-snapshot {
+ gpios = <&pm8150b_gpios 1 GPIO_ACTIVE_LOW>;
+ debounce-interval = <15>;
+ linux,can-disable;
+- gpio-key,wakeup;
++ wakeup-source;
+ };
+
+ key-vol-down {
+--
+2.40.1
+
--- /dev/null
+From 539333cf31cf431cdafb408177fc348e284875cd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Jul 2023 15:36:23 +0200
+Subject: arm64: dts: qcom: sm8350: Add missing LMH interrupts to cpufreq
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit 951151c2bb548e0f6b2c40ab4c48675f5342c914 ]
+
+Add the missing interrupts that communicate the hardware-managed
+throttling to Linux.
+
+Fixes: ccbb3abb23a5 ("arm64: dts: qcom: sm8350: Add cpufreq node")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230705-topic-sm8350_fixes-v1-3-0f69f70ccb6a@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8350.dtsi | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi
+index 24eec0eacc3d5..1aede15ec1a5b 100644
+--- a/arch/arm64/boot/dts/qcom/sm8350.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi
+@@ -3339,6 +3339,13 @@ cpufreq_hw: cpufreq@18591000 {
+ <0 0x18593000 0 0x1000>;
+ reg-names = "freq-domain0", "freq-domain1", "freq-domain2";
+
++ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-names = "dcvsh-irq-0",
++ "dcvsh-irq-1",
++ "dcvsh-irq-2";
++
+ clocks = <&rpmhcc RPMH_CXO_CLK>, <&gcc GCC_GPLL0>;
+ clock-names = "xo", "alternate";
+
+--
+2.40.1
+
--- /dev/null
+From b754f61ae45187d7560b5868610ee7703e53e6af Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Jul 2023 15:36:22 +0200
+Subject: arm64: dts: qcom: sm8350: Fix CPU idle state residency times
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit 91ce3693e2fb685f31d39605a5ad1fbd940804da ]
+
+The present values look to have been copypasted from 8150 or 8180.
+Fix that.
+
+Fixes: 07ddb302811e ("arm64: dts: qcom: sm8350: Add CPU topology and idle-states")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230705-topic-sm8350_fixes-v1-2-0f69f70ccb6a@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8350.dtsi | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi
+index 425af2c38a37f..24eec0eacc3d5 100644
+--- a/arch/arm64/boot/dts/qcom/sm8350.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi
+@@ -246,8 +246,8 @@ LITTLE_CPU_SLEEP_0: cpu-sleep-0-0 {
+ compatible = "arm,idle-state";
+ idle-state-name = "silver-rail-power-collapse";
+ arm,psci-suspend-param = <0x40000004>;
+- entry-latency-us = <355>;
+- exit-latency-us = <909>;
++ entry-latency-us = <360>;
++ exit-latency-us = <531>;
+ min-residency-us = <3934>;
+ local-timer-stop;
+ };
+@@ -256,8 +256,8 @@ BIG_CPU_SLEEP_0: cpu-sleep-1-0 {
+ compatible = "arm,idle-state";
+ idle-state-name = "gold-rail-power-collapse";
+ arm,psci-suspend-param = <0x40000004>;
+- entry-latency-us = <241>;
+- exit-latency-us = <1461>;
++ entry-latency-us = <702>;
++ exit-latency-us = <1061>;
+ min-residency-us = <4488>;
+ local-timer-stop;
+ };
+--
+2.40.1
+
--- /dev/null
+From d1d2b0c9f5735a64a7fadd46d39097d5fb949cc3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Jul 2023 18:35:37 +0200
+Subject: arm64: dts: qcom: sm8350: Use proper CPU compatibles
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit 4390730cc12af25f7c997f477795f5f4200149c0 ]
+
+The Kryo names (once again) turned out to be fake. The CPUs report:
+
+0x412fd050 (CA55 r2p0) (0 - 3)
+0x411fd410 (CA78 r1p1) (4 - 6)
+0x411fd440 (CX1 r1p1) (7)
+
+Use the compatibles that reflect that.
+
+Fixes: b7e8f433a673 ("arm64: dts: qcom: Add basic devicetree support for SM8350 SoC")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230706-topic-sm8350-cpu-compat-v1-1-f8d6a1869781@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8350.dtsi | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi
+index 1aede15ec1a5b..f375d960ba85c 100644
+--- a/arch/arm64/boot/dts/qcom/sm8350.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi
+@@ -48,7 +48,7 @@ cpus {
+
+ CPU0: cpu@0 {
+ device_type = "cpu";
+- compatible = "qcom,kryo685";
++ compatible = "arm,cortex-a55";
+ reg = <0x0 0x0>;
+ clocks = <&cpufreq_hw 0>;
+ enable-method = "psci";
+@@ -72,7 +72,7 @@ L3_0: l3-cache {
+
+ CPU1: cpu@100 {
+ device_type = "cpu";
+- compatible = "qcom,kryo685";
++ compatible = "arm,cortex-a55";
+ reg = <0x0 0x100>;
+ clocks = <&cpufreq_hw 0>;
+ enable-method = "psci";
+@@ -91,7 +91,7 @@ L2_100: l2-cache {
+
+ CPU2: cpu@200 {
+ device_type = "cpu";
+- compatible = "qcom,kryo685";
++ compatible = "arm,cortex-a55";
+ reg = <0x0 0x200>;
+ clocks = <&cpufreq_hw 0>;
+ enable-method = "psci";
+@@ -110,7 +110,7 @@ L2_200: l2-cache {
+
+ CPU3: cpu@300 {
+ device_type = "cpu";
+- compatible = "qcom,kryo685";
++ compatible = "arm,cortex-a55";
+ reg = <0x0 0x300>;
+ clocks = <&cpufreq_hw 0>;
+ enable-method = "psci";
+@@ -129,7 +129,7 @@ L2_300: l2-cache {
+
+ CPU4: cpu@400 {
+ device_type = "cpu";
+- compatible = "qcom,kryo685";
++ compatible = "arm,cortex-a78";
+ reg = <0x0 0x400>;
+ clocks = <&cpufreq_hw 1>;
+ enable-method = "psci";
+@@ -148,7 +148,7 @@ L2_400: l2-cache {
+
+ CPU5: cpu@500 {
+ device_type = "cpu";
+- compatible = "qcom,kryo685";
++ compatible = "arm,cortex-a78";
+ reg = <0x0 0x500>;
+ clocks = <&cpufreq_hw 1>;
+ enable-method = "psci";
+@@ -167,7 +167,7 @@ L2_500: l2-cache {
+
+ CPU6: cpu@600 {
+ device_type = "cpu";
+- compatible = "qcom,kryo685";
++ compatible = "arm,cortex-a78";
+ reg = <0x0 0x600>;
+ clocks = <&cpufreq_hw 1>;
+ enable-method = "psci";
+@@ -186,7 +186,7 @@ L2_600: l2-cache {
+
+ CPU7: cpu@700 {
+ device_type = "cpu";
+- compatible = "qcom,kryo685";
++ compatible = "arm,cortex-x1";
+ reg = <0x0 0x700>;
+ clocks = <&cpufreq_hw 2>;
+ enable-method = "psci";
+--
+2.40.1
+
--- /dev/null
+From 3e2a7ef40171750d704a2bf3925f88baef54afcf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Jul 2023 15:30:25 +0300
+Subject: arm64: dts: qcom: sm8450-hdk: remove pmr735b PMIC inclusion
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 701b59db773730a914f1778cf2dd05e3a05c2c69 ]
+
+The 8450-HDK doesn't use PMR735B PMIC. Drop its inclusion to remove the
+warning during the HDK bootup.
+
+Fixes: 30464456a1ea ("arm64: dts: qcom: sm8450-hdk: add pmic files")
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://lore.kernel.org/r/20230707123027.1510723-7-dmitry.baryshkov@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8450-hdk.dts | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8450-hdk.dts b/arch/arm64/boot/dts/qcom/sm8450-hdk.dts
+index e931545a2cac4..50306d070883d 100644
+--- a/arch/arm64/boot/dts/qcom/sm8450-hdk.dts
++++ b/arch/arm64/boot/dts/qcom/sm8450-hdk.dts
+@@ -14,7 +14,6 @@
+ #include "pm8450.dtsi"
+ #include "pmk8350.dtsi"
+ #include "pmr735a.dtsi"
+-#include "pmr735b.dtsi"
+
+ / {
+ model = "Qualcomm Technologies, Inc. SM8450 HDK";
+--
+2.40.1
+
--- /dev/null
+From 928c7340204fa50d268fef4e8bd4adfab59edc35 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Aug 2023 12:52:46 +0300
+Subject: arm64: dts: qcom: sm8550-mtp: Add missing supply for L1B regulator
+
+From: Abel Vesa <abel.vesa@linaro.org>
+
+[ Upstream commit 2c9e45dfeed126488aa73e7b82b3576c4c6f1036 ]
+
+Even though currently there is no consumer for L1B, add the supply
+for it anyway.
+
+Fixes: 71342fb91eae ("arm64: dts: qcom: Add base SM8550 MTP dts")
+Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://lore.kernel.org/r/20230801095246.2884770-1-abel.vesa@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8550-mtp.dts | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8550-mtp.dts b/arch/arm64/boot/dts/qcom/sm8550-mtp.dts
+index e2b9bb6b1e279..ea304d1e6f8f6 100644
+--- a/arch/arm64/boot/dts/qcom/sm8550-mtp.dts
++++ b/arch/arm64/boot/dts/qcom/sm8550-mtp.dts
+@@ -79,6 +79,7 @@ regulators-0 {
+
+ vdd-bob1-supply = <&vph_pwr>;
+ vdd-bob2-supply = <&vph_pwr>;
++ vdd-l1-l4-l10-supply = <&vreg_s6g_1p8>;
+ vdd-l2-l13-l14-supply = <&vreg_bob1>;
+ vdd-l3-supply = <&vreg_s4g_1p3>;
+ vdd-l5-l16-supply = <&vreg_bob1>;
+--
+2.40.1
+
--- /dev/null
+From baaede074265594d609124232d230fe05935e609 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Jul 2023 14:52:16 +0000
+Subject: arm64: dts: rockchip: Enable SATA on Radxa E25
+
+From: Jonas Karlman <jonas@kwiboo.se>
+
+[ Upstream commit 2bdfe84fbd57a4ed9fd65a67210442559ce078f0 ]
+
+The M.2 KEY B port can be used for WWAN USB2 modules or SATA drives.
+
+Enable sata1 node to fix use of SATA drives on the M.2 slot.
+
+Fixes: 2bf2f4d9f673 ("arm64: dts: rockchip: Add Radxa CM3I E25")
+Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
+Link: https://lore.kernel.org/r/20230724145213.3833099-1-jonas@kwiboo.se
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts b/arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts
+index f0e4884438e39..72ad74c38a2b4 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts
+@@ -99,6 +99,10 @@ vcc3v3_pi6c_05: vcc3v3-pi6c-05-regulator {
+ };
+ };
+
++&combphy1 {
++ phy-supply = <&vcc3v3_pcie30x1>;
++};
++
+ &pcie2x1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie20_reset_h>;
+@@ -178,6 +182,10 @@ &pwm12 {
+ status = "okay";
+ };
+
++&sata1 {
++ status = "okay";
++};
++
+ &sdmmc0 {
+ bus-width = <4>;
+ cap-sd-highspeed;
+--
+2.40.1
+
--- /dev/null
+From ea6370d55ffb2b4a79a824620b36d7bd6d1fb21e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Jul 2023 14:52:16 +0000
+Subject: arm64: dts: rockchip: Fix PCIe regulators on Radxa E25
+
+From: Jonas Karlman <jonas@kwiboo.se>
+
+[ Upstream commit a87852e37f782257ebc57cc44a0d3fbf806471f6 ]
+
+Despite its name, the regulator vcc3v3_pcie30x1 has nothing to do with
+pcie30x1. Instead, it supply power to VBAT1-5 on the M.2 KEY B port as
+seen on page 8 of the schematic [1].
+
+pcie30x1 is used for the mini PCIe slot, and as seen on page 9 the
+vcc3v3_minipcie regulator is instead related to pcie30x1.
+
+The M.2 KEY B port can be used for WWAN USB2 modules or SATA drives.
+
+Use correct regulator vcc3v3_minipcie for pcie30x1.
+
+[1] https://dl.radxa.com/cm3p/e25/radxa-e25-v1.4-sch.pdf
+
+Fixes: 2bf2f4d9f673 ("arm64: dts: rockchip: Add Radxa CM3I E25")
+Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
+Link: https://lore.kernel.org/r/20230724145213.3833099-1-jonas@kwiboo.se
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../arm64/boot/dts/rockchip/rk3568-radxa-e25.dts | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts b/arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts
+index 63c4bd873188e..f0e4884438e39 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts
+@@ -47,6 +47,9 @@ vbus_typec: vbus-typec-regulator {
+ vin-supply = <&vcc5v0_sys>;
+ };
+
++ /* actually fed by vcc5v0_sys, dependent
++ * on pi6c clock generator
++ */
+ vcc3v3_minipcie: vcc3v3-minipcie-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+@@ -54,9 +57,9 @@ vcc3v3_minipcie: vcc3v3-minipcie-regulator {
+ pinctrl-names = "default";
+ pinctrl-0 = <&minipcie_enable_h>;
+ regulator-name = "vcc3v3_minipcie";
+- regulator-min-microvolt = <5000000>;
+- regulator-max-microvolt = <5000000>;
+- vin-supply = <&vcc5v0_sys>;
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ vin-supply = <&vcc3v3_pi6c_05>;
+ };
+
+ vcc3v3_ngff: vcc3v3-ngff-regulator {
+@@ -71,9 +74,6 @@ vcc3v3_ngff: vcc3v3-ngff-regulator {
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+- /* actually fed by vcc5v0_sys, dependent
+- * on pi6c clock generator
+- */
+ vcc3v3_pcie30x1: vcc3v3-pcie30x1-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+@@ -83,7 +83,7 @@ vcc3v3_pcie30x1: vcc3v3-pcie30x1-regulator {
+ regulator-name = "vcc3v3_pcie30x1";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+- vin-supply = <&vcc3v3_pi6c_05>;
++ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc3v3_pi6c_05: vcc3v3-pi6c-05-regulator {
+@@ -117,7 +117,7 @@ &pcie3x1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie30x1m0_pins>;
+ reset-gpios = <&gpio0 RK_PC3 GPIO_ACTIVE_HIGH>;
+- vpcie3v3-supply = <&vcc3v3_pcie30x1>;
++ vpcie3v3-supply = <&vcc3v3_minipcie>;
+ status = "okay";
+ };
+
+--
+2.40.1
+
--- /dev/null
+From c08df4e8b3755621b433a8635bd108babfc71a37 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Aug 2023 14:15:54 +0530
+Subject: arm64: dts: ti: k3-am62x-sk-common: Update main-i2c1 frequency
+
+From: Aradhya Bhatia <a-bhatia1@ti.com>
+
+[ Upstream commit 73387da70f9c26b6fba4f62371d013cce14663d9 ]
+
+The Display Data Channel (DDC) transactions between an HDMI transmitter
+(SIL9022A in this case) and an HDMI monitor, occur at a maximum of
+100KHz. That's the maximum supported frequency within DDC standards.
+
+While the SIL9022A can transact with the core at 400KHz, it needs to
+drop the frequency to 100KHz when communicating with the monitor,
+otherwise, the i2c controller times out and shows warning like this.
+
+[ 985.773431] omap_i2c 20010000.i2c: controller timed out
+
+That feature, however, has not been enabled in the SIL9022 driver.
+
+Since, dropping the frequency doesn't affect any other devices on the
+bus, drop the main-i2c1 frequency from 400KHz to 100KHz.
+
+Fixes: a841581451af ("arm64: dts: ti: Refractor AM625 SK dts")
+Signed-off-by: Aradhya Bhatia <a-bhatia1@ti.com>
+Link: https://lore.kernel.org/r/20230809084559.17322-2-a-bhatia1@ti.com
+Signed-off-by: Nishanth Menon <nm@ti.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi b/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
+index 976f8303c84f4..5629a13d9fc43 100644
+--- a/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
++++ b/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
+@@ -248,7 +248,7 @@ &main_i2c1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_i2c1_pins_default>;
+- clock-frequency = <400000>;
++ clock-frequency = <100000>;
+
+ tlv320aic3106: audio-codec@1b {
+ #sound-dai-cells = <0>;
+--
+2.40.1
+
--- /dev/null
+From 7a4fc17dc74f0b7b036523c8fed4dd1412deb9a0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Aug 2023 01:16:22 +0530
+Subject: arm64: dts: ti: k3-j784s4: Fix interrupt ranges for wkup & main gpio
+
+From: Apelete Seketeli <aseketeli@baylibre.com>
+
+[ Upstream commit 05a1f130101e7a49ff1e8734939facd43596ea26 ]
+
+This patch fixes the interrupt range for wakeup and main domain gpio
+interrupt routers. They were wrongly subtracted by 32 instead of
+following what is defined in the interrupt map in the TRM (Table 9-35).
+
+Link: http://www.ti.com/lit/pdf/spruj52
+Fixes: 4664ebd8346a ("arm64: dts: ti: Add initial support for J784S4 SoC")
+Signed-off-by: Apelete Seketeli <aseketeli@baylibre.com>
+Signed-off-by: Esteban Blanc <eblanc@baylibre.com>
+Signed-off-by: Jai Luthra <j-luthra@ti.com>
+Link: https://lore.kernel.org/r/20230810-tps6594-v6-4-2b2e2399e2ef@ti.com
+Signed-off-by: Nishanth Menon <nm@ti.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi | 2 +-
+ arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi b/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
+index e9169eb358c16..320c31cba0a43 100644
+--- a/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
++++ b/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
+@@ -60,7 +60,7 @@ main_gpio_intr: interrupt-controller@a00000 {
+ #interrupt-cells = <1>;
+ ti,sci = <&sms>;
+ ti,sci-dev-id = <10>;
+- ti,interrupt-ranges = <8 360 56>;
++ ti,interrupt-ranges = <8 392 56>;
+ };
+
+ main_pmx0: pinctrl@11c000 {
+diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi
+index ed2b40369c59a..77208349eb22b 100644
+--- a/arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi
++++ b/arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi
+@@ -92,7 +92,7 @@ wkup_gpio_intr: interrupt-controller@42200000 {
+ #interrupt-cells = <1>;
+ ti,sci = <&sms>;
+ ti,sci-dev-id = <177>;
+- ti,interrupt-ranges = <16 928 16>;
++ ti,interrupt-ranges = <16 960 16>;
+ };
+
+ mcu_conf: syscon@40f00000 {
+--
+2.40.1
+
--- /dev/null
+From 44740be2638143d1fbc51759642f78ceeb7d0eff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Jul 2023 14:58:48 +0100
+Subject: arm64/fpsimd: Only provide the length to cpufeature for xCR registers
+
+From: Mark Brown <broonie@kernel.org>
+
+[ Upstream commit 01948b09edc3fecf8486c57c2d2fb8b80886f3d0 ]
+
+For both SVE and SME we abuse the generic register field comparison
+support in the cpufeature code as part of our detection of unsupported
+variations in the vector lengths available to PEs, reporting the maximum
+vector lengths via ZCR_EL1.LEN and SMCR_EL1.LEN. Since these are
+configuration registers rather than identification registers the
+assumptions the cpufeature code makes about how unknown bitfields behave
+are invalid, leading to warnings when SME features like FA64 are enabled
+and we hotplug a CPU:
+
+ CPU features: SANITY CHECK: Unexpected variation in SYS_SMCR_EL1. Boot CPU: 0x0000000000000f, CPU3: 0x0000008000000f
+ CPU features: Unsupported CPU feature variation detected.
+
+SVE has no controls other than the vector length so is not yet impacted
+but the same issue will apply there if any are defined.
+
+Since the only field we are interested in having the cpufeature code
+handle is the length field and we use a custom read function to obtain
+the value we can avoid these warnings by filtering out all other bits
+when we return the register value, if we're doing that we don't need to
+bother reading the register at all and can simply use the RDVL/RDSVL
+value we were filling in instead.
+
+Fixes: 2e0f2478ea37 ("arm64/sve: Probe SVE capabilities and usable vector lengths")
+FixeS: b42990d3bf77 ("arm64/sme: Identify supported SME vector lengths at boot")
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
+Link: https://lore.kernel.org/r/20230731-arm64-sme-fa64-hotplug-v2-1-7714c00dd902@kernel.org
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/kernel/fpsimd.c | 22 ++++------------------
+ 1 file changed, 4 insertions(+), 18 deletions(-)
+
+diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
+index 087c05aa960ea..91e44ac7150f9 100644
+--- a/arch/arm64/kernel/fpsimd.c
++++ b/arch/arm64/kernel/fpsimd.c
+@@ -1179,9 +1179,6 @@ void sve_kernel_enable(const struct arm64_cpu_capabilities *__always_unused p)
+ */
+ u64 read_zcr_features(void)
+ {
+- u64 zcr;
+- unsigned int vq_max;
+-
+ /*
+ * Set the maximum possible VL, and write zeroes to all other
+ * bits to see if they stick.
+@@ -1189,12 +1186,8 @@ u64 read_zcr_features(void)
+ sve_kernel_enable(NULL);
+ write_sysreg_s(ZCR_ELx_LEN_MASK, SYS_ZCR_EL1);
+
+- zcr = read_sysreg_s(SYS_ZCR_EL1);
+- zcr &= ~(u64)ZCR_ELx_LEN_MASK; /* find sticky 1s outside LEN field */
+- vq_max = sve_vq_from_vl(sve_get_vl());
+- zcr |= vq_max - 1; /* set LEN field to maximum effective value */
+-
+- return zcr;
++ /* Return LEN value that would be written to get the maximum VL */
++ return sve_vq_from_vl(sve_get_vl()) - 1;
+ }
+
+ void __init sve_setup(void)
+@@ -1349,9 +1342,6 @@ void fa64_kernel_enable(const struct arm64_cpu_capabilities *__always_unused p)
+ */
+ u64 read_smcr_features(void)
+ {
+- u64 smcr;
+- unsigned int vq_max;
+-
+ sme_kernel_enable(NULL);
+
+ /*
+@@ -1360,12 +1350,8 @@ u64 read_smcr_features(void)
+ write_sysreg_s(read_sysreg_s(SYS_SMCR_EL1) | SMCR_ELx_LEN_MASK,
+ SYS_SMCR_EL1);
+
+- smcr = read_sysreg_s(SYS_SMCR_EL1);
+- smcr &= ~(u64)SMCR_ELx_LEN_MASK; /* Only the LEN field */
+- vq_max = sve_vq_from_vl(sme_get_vl());
+- smcr |= vq_max - 1; /* set LEN field to maximum effective value */
+-
+- return smcr;
++ /* Return LEN value that would be written to get the maximum VL */
++ return sve_vq_from_vl(sme_get_vl()) - 1;
+ }
+
+ void __init sme_setup(void)
+--
+2.40.1
+
--- /dev/null
+From fbae9801b7a4da2940c0e1fd997d3a12ed79ed89 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Aug 2023 09:32:41 +0000
+Subject: arm64: mm: use ptep_clear() instead of pte_clear() in clear_flush()
+
+From: Qi Zheng <zhengqi.arch@bytedance.com>
+
+[ Upstream commit 00de2c9f26b15f1a6f2af516dd8ec5f8d28189b7 ]
+
+In clear_flush(), the original pte may be a present entry, so we should
+use ptep_clear() to let page_table_check track the pte clearing operation,
+otherwise it may cause false positive in subsequent set_pte_at().
+
+Link: https://lkml.kernel.org/r/20230810093241.1181142-1-qi.zheng@linux.dev
+Fixes: 42b2547137f5 ("arm64/mm: enable ARCH_SUPPORTS_PAGE_TABLE_CHECK")
+Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com>
+Acked-by: Will Deacon <will@kernel.org>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Kefeng Wang <wangkefeng.wang@huawei.com>
+Cc: Muchun Song <muchun.song@linux.dev>
+Cc: Pasha Tatashin <pasha.tatashin@soleen.com>
+Cc: Qi Zheng <zhengqi.arch@bytedance.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/mm/hugetlbpage.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
+index 95364e8bdc194..50a8e7ab5fa94 100644
+--- a/arch/arm64/mm/hugetlbpage.c
++++ b/arch/arm64/mm/hugetlbpage.c
+@@ -236,7 +236,7 @@ static void clear_flush(struct mm_struct *mm,
+ unsigned long i, saddr = addr;
+
+ for (i = 0; i < ncontig; i++, addr += pgsize, ptep++)
+- pte_clear(mm, addr, ptep);
++ ptep_clear(mm, addr, ptep);
+
+ flush_tlb_range(&vma, saddr, addr);
+ }
+--
+2.40.1
+
--- /dev/null
+From 9bad7bc13ef62d4e3fcfcf40faff114f56a2823c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Jul 2023 19:55:05 +0200
+Subject: arm64/ptrace: Clean up error handling path in sve_set_common()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 5f69ca4229c7d8e23f238174827ee7aa49b0bcb2 ]
+
+All error handling paths go to 'out', except this one. Be consistent and
+also branch to 'out' here.
+
+Fixes: e12310a0d30f ("arm64/sme: Implement ptrace support for streaming mode SVE registers")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Reviewed-by: Mark Brown <broonie@kernel.org>
+Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
+Link: https://lore.kernel.org/r/aa61301ed2dfd079b74b37f7fede5f179ac3087a.1689616473.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/kernel/ptrace.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
+index 187aa2b175b4f..20d7ef82de90a 100644
+--- a/arch/arm64/kernel/ptrace.c
++++ b/arch/arm64/kernel/ptrace.c
+@@ -891,7 +891,8 @@ static int sve_set_common(struct task_struct *target,
+ break;
+ default:
+ WARN_ON_ONCE(1);
+- return -EINVAL;
++ ret = -EINVAL;
++ goto out;
+ }
+
+ /*
+--
+2.40.1
+
--- /dev/null
+From 9f3a13e23141fc34bd8be34992ba7afb1f6799b7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Jul 2023 12:36:17 +0100
+Subject: arm64: tegra: Fix HSUART for Jetson AGX Orin
+
+From: Jon Hunter <jonathanh@nvidia.com>
+
+[ Upstream commit 861dbb2b15b1049113887fb95e856f7123eea0cc ]
+
+After commit 71de0a054d0e ("arm64: tegra: Drop serial clock-names and
+reset-names") was applied, the HSUART failed to probe and the following
+error is seen:
+
+ serial-tegra 3100000.serial: Couldn't get the reset
+ serial-tegra: probe of 3100000.serial failed with error -2
+
+Commit 71de0a054d0e ("arm64: tegra: Drop serial clock-names and
+reset-names") is correct because the "reset-names" property is not
+needed for 8250 UARTs. However, the "reset-names" is required for the
+HSUART and should have been populated as part of commit ff578db7b693
+("arm64: tegra: Enable UART instance on 40-pin header") that
+enabled the HSUART for Jetson AGX Orin. Fix this by populating the
+"reset-names" property for the HSUART on Jetson AGX Orin.
+
+Fixes: ff578db7b693 ("arm64: tegra: Enable UART instance on 40-pin header")
+Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts b/arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts
+index caa9e952a149c..a1194c4e15f0e 100644
+--- a/arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts
++++ b/arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts
+@@ -2010,6 +2010,7 @@ interrupt-controller@2a40000 {
+
+ serial@3100000 {
+ compatible = "nvidia,tegra194-hsuart";
++ reset-names = "serial";
+ status = "okay";
+ };
+
+--
+2.40.1
+
--- /dev/null
+From 3a478b1b6685f3d02ef13aa50be8158ae1a21ab2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Jul 2023 11:10:17 +0100
+Subject: arm64: tegra: Fix HSUART for Smaug
+
+From: Diogo Ivo <diogo.ivo@tecnico.ulisboa.pt>
+
+[ Upstream commit 590bfe51838f6345a6a3288507661dc9b7208464 ]
+
+After commit 71de0a054d0e ("arm64: tegra: Drop serial clock-names and
+reset-names") was applied, the HSUART failed to probe and the following
+error is seen:
+
+ serial-tegra 70006300.serial: Couldn't get the reset
+ serial-tegra: probe of 70006300.serial failed with error -2
+
+Commit 71de0a054d0e ("arm64: tegra: Drop serial clock-names and
+reset-names") is correct because the "reset-names" property is not
+needed for 8250 UARTs. However, the "reset-names" is required for the
+HSUART and should have been populated as part of commit a63c0cd83720c
+("arm64: dts: tegra: smaug: Add Bluetooth node") that enabled the HSUART
+for the Pixel C. Fix this by populating the "reset-names" property for
+the HSUART on the Pixel C.
+
+Fixes: a63c0cd83720 ("arm64: dts: tegra: smaug: Add Bluetooth node")
+Signed-off-by: Diogo Ivo <diogo.ivo@tecnico.ulisboa.pt>
+Reviewed-by: Jon Hunter <jonathanh@nvidia.com>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/nvidia/tegra210-smaug.dts | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts b/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts
+index d7d7c63e62e25..79d294c2ee199 100644
+--- a/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts
++++ b/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts
+@@ -1312,6 +1312,7 @@ serial@70006000 {
+
+ uartd: serial@70006300 {
+ compatible = "nvidia,tegra30-hsuart";
++ reset-names = "serial";
+ status = "okay";
+
+ bluetooth {
+--
+2.40.1
+
--- /dev/null
+From 7fafb414d2761cab15225511056536c1375148df Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Jun 2023 16:32:29 +0100
+Subject: ASoC: cs43130: Fix numerator/denominator mixup
+
+From: Phil Elwell <phil@raspberrypi.com>
+
+[ Upstream commit a9e7c964cea4fb1541cc81a11d1b2fd135f4cf38 ]
+
+In converting to using the standard u16_fract type, commit [1] made the
+obvious mistake and failed to take account of the difference in
+numerator and denominator ordering, breaking all uses of the cs43130
+codec.
+
+Fix it.
+
+[1] commit e14bd35ef446 ("ASoC: cs43130: Re-use generic struct u16_fract")
+
+Fixes: e14bd35ef446 ("ASoC: cs43130: Re-use generic struct u16_fract")
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Acked-by: Charles Keepax <ckeepax@opensource.cirrus.com>
+Link: https://lore.kernel.org/r/20230621153229.1944132-1-phil@raspberrypi.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/cs43130.h | 138 ++++++++++++++++++-------------------
+ 1 file changed, 69 insertions(+), 69 deletions(-)
+
+diff --git a/sound/soc/codecs/cs43130.h b/sound/soc/codecs/cs43130.h
+index 1dd8936743132..90e8895275e77 100644
+--- a/sound/soc/codecs/cs43130.h
++++ b/sound/soc/codecs/cs43130.h
+@@ -381,88 +381,88 @@ struct cs43130_clk_gen {
+
+ /* frm_size = 16 */
+ static const struct cs43130_clk_gen cs43130_16_clk_gen[] = {
+- { 22579200, 32000, .v = { 441, 10, }, },
+- { 22579200, 44100, .v = { 32, 1, }, },
+- { 22579200, 48000, .v = { 147, 5, }, },
+- { 22579200, 88200, .v = { 16, 1, }, },
+- { 22579200, 96000, .v = { 147, 10, }, },
+- { 22579200, 176400, .v = { 8, 1, }, },
+- { 22579200, 192000, .v = { 147, 20, }, },
+- { 22579200, 352800, .v = { 4, 1, }, },
+- { 22579200, 384000, .v = { 147, 40, }, },
+- { 24576000, 32000, .v = { 48, 1, }, },
+- { 24576000, 44100, .v = { 5120, 147, }, },
+- { 24576000, 48000, .v = { 32, 1, }, },
+- { 24576000, 88200, .v = { 2560, 147, }, },
+- { 24576000, 96000, .v = { 16, 1, }, },
+- { 24576000, 176400, .v = { 1280, 147, }, },
+- { 24576000, 192000, .v = { 8, 1, }, },
+- { 24576000, 352800, .v = { 640, 147, }, },
+- { 24576000, 384000, .v = { 4, 1, }, },
++ { 22579200, 32000, .v = { 10, 441, }, },
++ { 22579200, 44100, .v = { 1, 32, }, },
++ { 22579200, 48000, .v = { 5, 147, }, },
++ { 22579200, 88200, .v = { 1, 16, }, },
++ { 22579200, 96000, .v = { 10, 147, }, },
++ { 22579200, 176400, .v = { 1, 8, }, },
++ { 22579200, 192000, .v = { 20, 147, }, },
++ { 22579200, 352800, .v = { 1, 4, }, },
++ { 22579200, 384000, .v = { 40, 147, }, },
++ { 24576000, 32000, .v = { 1, 48, }, },
++ { 24576000, 44100, .v = { 147, 5120, }, },
++ { 24576000, 48000, .v = { 1, 32, }, },
++ { 24576000, 88200, .v = { 147, 2560, }, },
++ { 24576000, 96000, .v = { 1, 16, }, },
++ { 24576000, 176400, .v = { 147, 1280, }, },
++ { 24576000, 192000, .v = { 1, 8, }, },
++ { 24576000, 352800, .v = { 147, 640, }, },
++ { 24576000, 384000, .v = { 1, 4, }, },
+ };
+
+ /* frm_size = 32 */
+ static const struct cs43130_clk_gen cs43130_32_clk_gen[] = {
+- { 22579200, 32000, .v = { 441, 20, }, },
+- { 22579200, 44100, .v = { 16, 1, }, },
+- { 22579200, 48000, .v = { 147, 10, }, },
+- { 22579200, 88200, .v = { 8, 1, }, },
+- { 22579200, 96000, .v = { 147, 20, }, },
+- { 22579200, 176400, .v = { 4, 1, }, },
+- { 22579200, 192000, .v = { 147, 40, }, },
+- { 22579200, 352800, .v = { 2, 1, }, },
+- { 22579200, 384000, .v = { 147, 80, }, },
+- { 24576000, 32000, .v = { 24, 1, }, },
+- { 24576000, 44100, .v = { 2560, 147, }, },
+- { 24576000, 48000, .v = { 16, 1, }, },
+- { 24576000, 88200, .v = { 1280, 147, }, },
+- { 24576000, 96000, .v = { 8, 1, }, },
+- { 24576000, 176400, .v = { 640, 147, }, },
+- { 24576000, 192000, .v = { 4, 1, }, },
+- { 24576000, 352800, .v = { 320, 147, }, },
+- { 24576000, 384000, .v = { 2, 1, }, },
++ { 22579200, 32000, .v = { 20, 441, }, },
++ { 22579200, 44100, .v = { 1, 16, }, },
++ { 22579200, 48000, .v = { 10, 147, }, },
++ { 22579200, 88200, .v = { 1, 8, }, },
++ { 22579200, 96000, .v = { 20, 147, }, },
++ { 22579200, 176400, .v = { 1, 4, }, },
++ { 22579200, 192000, .v = { 40, 147, }, },
++ { 22579200, 352800, .v = { 1, 2, }, },
++ { 22579200, 384000, .v = { 80, 147, }, },
++ { 24576000, 32000, .v = { 1, 24, }, },
++ { 24576000, 44100, .v = { 147, 2560, }, },
++ { 24576000, 48000, .v = { 1, 16, }, },
++ { 24576000, 88200, .v = { 147, 1280, }, },
++ { 24576000, 96000, .v = { 1, 8, }, },
++ { 24576000, 176400, .v = { 147, 640, }, },
++ { 24576000, 192000, .v = { 1, 4, }, },
++ { 24576000, 352800, .v = { 147, 320, }, },
++ { 24576000, 384000, .v = { 1, 2, }, },
+ };
+
+ /* frm_size = 48 */
+ static const struct cs43130_clk_gen cs43130_48_clk_gen[] = {
+- { 22579200, 32000, .v = { 147, 100, }, },
+- { 22579200, 44100, .v = { 32, 3, }, },
+- { 22579200, 48000, .v = { 49, 5, }, },
+- { 22579200, 88200, .v = { 16, 3, }, },
+- { 22579200, 96000, .v = { 49, 10, }, },
+- { 22579200, 176400, .v = { 8, 3, }, },
+- { 22579200, 192000, .v = { 49, 20, }, },
+- { 22579200, 352800, .v = { 4, 3, }, },
+- { 22579200, 384000, .v = { 49, 40, }, },
+- { 24576000, 32000, .v = { 16, 1, }, },
+- { 24576000, 44100, .v = { 5120, 441, }, },
+- { 24576000, 48000, .v = { 32, 3, }, },
+- { 24576000, 88200, .v = { 2560, 441, }, },
+- { 24576000, 96000, .v = { 16, 3, }, },
+- { 24576000, 176400, .v = { 1280, 441, }, },
+- { 24576000, 192000, .v = { 8, 3, }, },
+- { 24576000, 352800, .v = { 640, 441, }, },
+- { 24576000, 384000, .v = { 4, 3, }, },
++ { 22579200, 32000, .v = { 100, 147, }, },
++ { 22579200, 44100, .v = { 3, 32, }, },
++ { 22579200, 48000, .v = { 5, 49, }, },
++ { 22579200, 88200, .v = { 3, 16, }, },
++ { 22579200, 96000, .v = { 10, 49, }, },
++ { 22579200, 176400, .v = { 3, 8, }, },
++ { 22579200, 192000, .v = { 20, 49, }, },
++ { 22579200, 352800, .v = { 3, 4, }, },
++ { 22579200, 384000, .v = { 40, 49, }, },
++ { 24576000, 32000, .v = { 1, 16, }, },
++ { 24576000, 44100, .v = { 441, 5120, }, },
++ { 24576000, 48000, .v = { 3, 32, }, },
++ { 24576000, 88200, .v = { 441, 2560, }, },
++ { 24576000, 96000, .v = { 3, 16, }, },
++ { 24576000, 176400, .v = { 441, 1280, }, },
++ { 24576000, 192000, .v = { 3, 8, }, },
++ { 24576000, 352800, .v = { 441, 640, }, },
++ { 24576000, 384000, .v = { 3, 4, }, },
+ };
+
+ /* frm_size = 64 */
+ static const struct cs43130_clk_gen cs43130_64_clk_gen[] = {
+- { 22579200, 32000, .v = { 441, 40, }, },
+- { 22579200, 44100, .v = { 8, 1, }, },
+- { 22579200, 48000, .v = { 147, 20, }, },
+- { 22579200, 88200, .v = { 4, 1, }, },
+- { 22579200, 96000, .v = { 147, 40, }, },
+- { 22579200, 176400, .v = { 2, 1, }, },
+- { 22579200, 192000, .v = { 147, 80, }, },
++ { 22579200, 32000, .v = { 40, 441, }, },
++ { 22579200, 44100, .v = { 1, 8, }, },
++ { 22579200, 48000, .v = { 20, 147, }, },
++ { 22579200, 88200, .v = { 1, 4, }, },
++ { 22579200, 96000, .v = { 40, 147, }, },
++ { 22579200, 176400, .v = { 1, 2, }, },
++ { 22579200, 192000, .v = { 80, 147, }, },
+ { 22579200, 352800, .v = { 1, 1, }, },
+- { 24576000, 32000, .v = { 12, 1, }, },
+- { 24576000, 44100, .v = { 1280, 147, }, },
+- { 24576000, 48000, .v = { 8, 1, }, },
+- { 24576000, 88200, .v = { 640, 147, }, },
+- { 24576000, 96000, .v = { 4, 1, }, },
+- { 24576000, 176400, .v = { 320, 147, }, },
+- { 24576000, 192000, .v = { 2, 1, }, },
+- { 24576000, 352800, .v = { 160, 147, }, },
++ { 24576000, 32000, .v = { 1, 12, }, },
++ { 24576000, 44100, .v = { 147, 1280, }, },
++ { 24576000, 48000, .v = { 1, 8, }, },
++ { 24576000, 88200, .v = { 147, 640, }, },
++ { 24576000, 96000, .v = { 1, 4, }, },
++ { 24576000, 176400, .v = { 147, 320, }, },
++ { 24576000, 192000, .v = { 1, 2, }, },
++ { 24576000, 352800, .v = { 147, 160, }, },
+ { 24576000, 384000, .v = { 1, 1, }, },
+ };
+
+--
+2.40.1
+
--- /dev/null
+From 00c11b87536fcba253ae48a65c9964c5714aa320 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Jul 2023 18:16:20 +0200
+Subject: ASoC: fsl: fsl_qmc_audio: Fix snd_pcm_format_t values handling
+
+From: Herve Codina <herve.codina@bootlin.com>
+
+[ Upstream commit 5befe22b3eebd07b334b2917f6d14ce7ee4c8404 ]
+
+Running sparse on fsl_qmc_audio (make C=1) raises the following warnings:
+ fsl_qmc_audio.c:387:26: warning: restricted snd_pcm_format_t degrades to integer
+ fsl_qmc_audio.c:389:59: warning: incorrect type in argument 1 (different base types)
+ fsl_qmc_audio.c:389:59: expected restricted snd_pcm_format_t [usertype] format
+ fsl_qmc_audio.c:389:59: got unsigned int [assigned] i
+ fsl_qmc_audio.c:564:26: warning: restricted snd_pcm_format_t degrades to integer
+ fsl_qmc_audio.c:569:50: warning: incorrect type in argument 1 (different base types)
+ fsl_qmc_audio.c:569:50: expected restricted snd_pcm_format_t [usertype] format
+ fsl_qmc_audio.c:569:50: got int [assigned] i
+ fsl_qmc_audio.c:573:62: warning: incorrect type in argument 1 (different base types)
+ fsl_qmc_audio.c:573:62: expected restricted snd_pcm_format_t [usertype] format
+ fsl_qmc_audio.c:573:62: got int [assigned] i
+
+These warnings are due to snd_pcm_format_t values handling done in the
+driver. Some macros and functions exist to handle safely these values.
+
+Use dedicated macros and functions to remove these warnings.
+
+Fixes: 075c7125b11c ("ASoC: fsl: Add support for QMC audio")
+Signed-off-by: Herve Codina <herve.codina@bootlin.com>
+Link: https://lore.kernel.org/r/20230726161620.495298-1-herve.codina@bootlin.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/fsl/fsl_qmc_audio.c | 28 ++++++++++++++--------------
+ 1 file changed, 14 insertions(+), 14 deletions(-)
+
+diff --git a/sound/soc/fsl/fsl_qmc_audio.c b/sound/soc/fsl/fsl_qmc_audio.c
+index 7cbb8e4758ccc..56d6b0b039a2e 100644
+--- a/sound/soc/fsl/fsl_qmc_audio.c
++++ b/sound/soc/fsl/fsl_qmc_audio.c
+@@ -372,8 +372,8 @@ static int qmc_dai_hw_rule_format_by_channels(struct qmc_dai *qmc_dai,
+ struct snd_mask *f_old = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+ unsigned int channels = params_channels(params);
+ unsigned int slot_width;
++ snd_pcm_format_t format;
+ struct snd_mask f_new;
+- unsigned int i;
+
+ if (!channels || channels > nb_ts) {
+ dev_err(qmc_dai->dev, "channels %u not supported\n",
+@@ -384,10 +384,10 @@ static int qmc_dai_hw_rule_format_by_channels(struct qmc_dai *qmc_dai,
+ slot_width = (nb_ts / channels) * 8;
+
+ snd_mask_none(&f_new);
+- for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) {
+- if (snd_mask_test(f_old, i)) {
+- if (snd_pcm_format_physical_width(i) <= slot_width)
+- snd_mask_set(&f_new, i);
++ pcm_for_each_format(format) {
++ if (snd_mask_test_format(f_old, format)) {
++ if (snd_pcm_format_physical_width(format) <= slot_width)
++ snd_mask_set_format(&f_new, format);
+ }
+ }
+
+@@ -551,26 +551,26 @@ static const struct snd_soc_dai_ops qmc_dai_ops = {
+
+ static u64 qmc_audio_formats(u8 nb_ts)
+ {
+- u64 formats;
+- unsigned int chan_width;
+ unsigned int format_width;
+- int i;
++ unsigned int chan_width;
++ snd_pcm_format_t format;
++ u64 formats_mask;
+
+ if (!nb_ts)
+ return 0;
+
+- formats = 0;
++ formats_mask = 0;
+ chan_width = nb_ts * 8;
+- for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) {
++ pcm_for_each_format(format) {
+ /*
+ * Support format other than little-endian (ie big-endian or
+ * without endianness such as 8bit formats)
+ */
+- if (snd_pcm_format_little_endian(i) == 1)
++ if (snd_pcm_format_little_endian(format) == 1)
+ continue;
+
+ /* Support physical width multiple of 8bit */
+- format_width = snd_pcm_format_physical_width(i);
++ format_width = snd_pcm_format_physical_width(format);
+ if (format_width == 0 || format_width % 8)
+ continue;
+
+@@ -581,9 +581,9 @@ static u64 qmc_audio_formats(u8 nb_ts)
+ if (format_width > chan_width || chan_width % format_width)
+ continue;
+
+- formats |= (1ULL << i);
++ formats_mask |= pcm_format_to_bits(format);
+ }
+- return formats;
++ return formats_mask;
+ }
+
+ static int qmc_audio_dai_parse(struct qmc_audio *qmc_audio, struct device_node *np,
+--
+2.40.1
+
--- /dev/null
+From 96c745f72882e4694b7588b864b2c70703375594 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Jun 2023 11:31:27 +0800
+Subject: ASoC: soc-compress: Fix deadlock in soc_compr_open_fe
+
+From: yixuanjiang <yixuanjiang@google.com>
+
+[ Upstream commit 2222214749a9969e09454b9ba7febfdfb09c1c8d ]
+
+Modify the error handling flow by release lock.
+The require mutex will keep holding if open fail.
+
+Fixes: aa9ff6a4955f ("ASoC: soc-compress: Reposition and add pcm_mutex")
+Signed-off-by: yixuanjiang <yixuanjiang@google.com>
+Link: https://lore.kernel.org/r/20230619033127.2522477-1-yixuanjiang@google.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/soc-compress.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
+index d8715db5e415e..2117fd61cf8f3 100644
+--- a/sound/soc/soc-compress.c
++++ b/sound/soc/soc-compress.c
+@@ -194,6 +194,7 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
+ snd_soc_dai_compr_shutdown(cpu_dai, cstream, 1);
+ out:
+ dpcm_path_put(&list);
++ snd_soc_dpcm_mutex_unlock(fe);
+ be_err:
+ fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
+ snd_soc_card_mutex_unlock(fe->card);
+--
+2.40.1
+
--- /dev/null
+From 7d2cf9d69e13425488bc2a5ea3a5b4cdeb24d979 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Aug 2023 13:03:39 +0530
+Subject: ASoC: SOF: amd: clear dsp to host interrupt status
+
+From: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+
+[ Upstream commit 38592ae6dc9f84b7a994c43de2136b8115ca30f6 ]
+
+DSP_SW_INTR_STAT_OFFSET is a common interrupt register which will be
+accessed by both ACP firmware and driver. This register contains register
+bits corresponds to host to dsp interrupts and vice versa.
+
+when dsp to host interrupt is reported, only clear dsp to host
+interrupt bit in DSP_SW_INTR_STAT_OFFSET.
+
+Fixes: 2e7c6652f9b8 ("ASoC: SOF: amd: Fix for handling spurious interrupts from DSP")
+
+Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+Link: https://lore.kernel.org/r/20230823073340.2829821-7-Vijendar.Mukunda@amd.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/sof/amd/acp.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/sound/soc/sof/amd/acp.c b/sound/soc/sof/amd/acp.c
+index 2ae76bcd3590c..973bd81059852 100644
+--- a/sound/soc/sof/amd/acp.c
++++ b/sound/soc/sof/amd/acp.c
+@@ -351,9 +351,9 @@ static irqreturn_t acp_irq_handler(int irq, void *dev_id)
+ unsigned int val;
+
+ val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, base + DSP_SW_INTR_STAT_OFFSET);
+- if (val) {
+- val |= ACP_DSP_TO_HOST_IRQ;
+- snd_sof_dsp_write(sdev, ACP_DSP_BAR, base + DSP_SW_INTR_STAT_OFFSET, val);
++ if (val & ACP_DSP_TO_HOST_IRQ) {
++ snd_sof_dsp_write(sdev, ACP_DSP_BAR, base + DSP_SW_INTR_STAT_OFFSET,
++ ACP_DSP_TO_HOST_IRQ);
+ return IRQ_WAKE_THREAD;
+ }
+
+--
+2.40.1
+
--- /dev/null
+From 3ddf4e8a3aecb1024427fb0256bd6716d83960b7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Aug 2023 16:09:41 -0500
+Subject: ASoC: SOF: Intel: fix u16/32 confusion in LSDIID
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+[ Upstream commit 7a52d7062e02af4a479da24b40cfd76b54c0cd6c ]
+
+Likely a combination of copy-paste and test coverage problem. Oops.
+
+Fixes: 87a6ddc0cf1c ("ASoC: SOF: Intel: hda-mlink: program SoundWire LSDIID registers")
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
+Reviewed-by: Rander Wang <rander.wang@intel.com>
+Link: https://lore.kernel.org/r/20230807210959.506849-3-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/sof/intel/hda-mlink.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/sound/soc/sof/intel/hda-mlink.c b/sound/soc/sof/intel/hda-mlink.c
+index acad3ea2f4710..df87b3791c23e 100644
+--- a/sound/soc/sof/intel/hda-mlink.c
++++ b/sound/soc/sof/intel/hda-mlink.c
+@@ -331,14 +331,14 @@ static bool hdaml_link_check_cmdsync(u32 __iomem *lsync, u32 cmdsync_mask)
+ return !!(val & cmdsync_mask);
+ }
+
+-static void hdaml_link_set_lsdiid(u32 __iomem *lsdiid, int dev_num)
++static void hdaml_link_set_lsdiid(u16 __iomem *lsdiid, int dev_num)
+ {
+- u32 val;
++ u16 val;
+
+- val = readl(lsdiid);
++ val = readw(lsdiid);
+ val |= BIT(dev_num);
+
+- writel(val, lsdiid);
++ writew(val, lsdiid);
+ }
+
+ static void hdaml_shim_map_stream_ch(u16 __iomem *pcmsycm, int lchan, int hchan,
+--
+2.40.1
+
--- /dev/null
+From b4d214b4c8e3407ab39ac765c5bec8fb9f0d5cea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Aug 2023 16:09:40 -0500
+Subject: ASoC: SOF: Intel: hda-mlink: fix off-by-one error
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+[ Upstream commit 7075b0c91b3cd5d32b4ac7403f771a3253d3fbf6 ]
+
+The HCHAN parameter should be the highest channel number, not the
+channel count.
+
+While we're at it, handle LCHAN with the dual __ffs helper.
+
+Fixes: ccc2f0c1b6b6 ("ASoC: SOF: Intel: hda-mlink: add helper to program SoundWire PCMSyCM registers")
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
+Reviewed-by: Rander Wang <rander.wang@intel.com>
+Link: https://lore.kernel.org/r/20230807210959.506849-2-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/sof/intel/hda-mlink.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/sound/soc/sof/intel/hda-mlink.c b/sound/soc/sof/intel/hda-mlink.c
+index b7cbf66badf5b..acad3ea2f4710 100644
+--- a/sound/soc/sof/intel/hda-mlink.c
++++ b/sound/soc/sof/intel/hda-mlink.c
+@@ -781,6 +781,8 @@ int hdac_bus_eml_sdw_map_stream_ch(struct hdac_bus *bus, int sublink, int y,
+ {
+ struct hdac_ext2_link *h2link;
+ u16 __iomem *pcmsycm;
++ int hchan;
++ int lchan;
+ u16 val;
+
+ h2link = find_ext2_link(bus, true, AZX_REG_ML_LEPTR_ID_SDW);
+@@ -791,9 +793,17 @@ int hdac_bus_eml_sdw_map_stream_ch(struct hdac_bus *bus, int sublink, int y,
+ h2link->instance_offset * sublink +
+ AZX_REG_SDW_SHIM_PCMSyCM(y);
+
++ if (channel_mask) {
++ hchan = __fls(channel_mask);
++ lchan = __ffs(channel_mask);
++ } else {
++ hchan = 0;
++ lchan = 0;
++ }
++
+ mutex_lock(&h2link->eml_lock);
+
+- hdaml_shim_map_stream_ch(pcmsycm, 0, hweight32(channel_mask),
++ hdaml_shim_map_stream_ch(pcmsycm, lchan, hchan,
+ stream_id, dir);
+
+ mutex_unlock(&h2link->eml_lock);
+--
+2.40.1
+
--- /dev/null
+From 9b649b7a1bcaa8149bb50f14fe6b9870bef95ffc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Jun 2023 21:48:36 -0700
+Subject: ASoC: stac9766: fix build errors with REGMAP_AC97
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit c70064b96f509daa78f57992aeabcf274fb2fed4 ]
+
+Select REGMAP_AC97 to fix these build errors:
+
+ERROR: modpost: "regmap_ac97_default_volatile" [sound/soc/codecs/snd-soc-stac9766.ko] undefined!
+ERROR: modpost: "__regmap_init_ac97" [sound/soc/codecs/snd-soc-stac9766.ko] undefined!
+
+Fixes: 6bbf787bb70c ("ASoC: stac9766: Convert to regmap")
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Cc: Lars-Peter Clausen <lars@metafoo.de>
+Cc: Mark Brown <broonie@kernel.org>
+Cc: Liam Girdwood <lgirdwood@gmail.com>
+Cc: alsa-devel@alsa-project.org
+Link: https://lore.kernel.org/r/20230701044836.18789-1-rdunlap@infradead.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
+index 1b50b2d66beb2..3840dd6844974 100644
+--- a/sound/soc/codecs/Kconfig
++++ b/sound/soc/codecs/Kconfig
+@@ -1673,6 +1673,7 @@ config SND_SOC_STA529
+ config SND_SOC_STAC9766
+ tristate
+ depends on SND_SOC_AC97_BUS
++ select REGMAP_AC97
+
+ config SND_SOC_STI_SAS
+ tristate "codec Audio support for STI SAS codec"
+--
+2.40.1
+
--- /dev/null
+From 76350aa8143c00c65764b9398dac4d9e4b2f0d7d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Aug 2023 20:14:35 +0800
+Subject: audit: fix possible soft lockup in __audit_inode_child()
+
+From: Gaosheng Cui <cuigaosheng1@huawei.com>
+
+[ Upstream commit b59bc6e37237e37eadf50cd5de369e913f524463 ]
+
+Tracefs or debugfs maybe cause hundreds to thousands of PATH records,
+too many PATH records maybe cause soft lockup.
+
+For example:
+ 1. CONFIG_KASAN=y && CONFIG_PREEMPTION=n
+ 2. auditctl -a exit,always -S open -k key
+ 3. sysctl -w kernel.watchdog_thresh=5
+ 4. mkdir /sys/kernel/debug/tracing/instances/test
+
+There may be a soft lockup as follows:
+ watchdog: BUG: soft lockup - CPU#45 stuck for 7s! [mkdir:15498]
+ Kernel panic - not syncing: softlockup: hung tasks
+ Call trace:
+ dump_backtrace+0x0/0x30c
+ show_stack+0x20/0x30
+ dump_stack+0x11c/0x174
+ panic+0x27c/0x494
+ watchdog_timer_fn+0x2bc/0x390
+ __run_hrtimer+0x148/0x4fc
+ __hrtimer_run_queues+0x154/0x210
+ hrtimer_interrupt+0x2c4/0x760
+ arch_timer_handler_phys+0x48/0x60
+ handle_percpu_devid_irq+0xe0/0x340
+ __handle_domain_irq+0xbc/0x130
+ gic_handle_irq+0x78/0x460
+ el1_irq+0xb8/0x140
+ __audit_inode_child+0x240/0x7bc
+ tracefs_create_file+0x1b8/0x2a0
+ trace_create_file+0x18/0x50
+ event_create_dir+0x204/0x30c
+ __trace_add_new_event+0xac/0x100
+ event_trace_add_tracer+0xa0/0x130
+ trace_array_create_dir+0x60/0x140
+ trace_array_create+0x1e0/0x370
+ instance_mkdir+0x90/0xd0
+ tracefs_syscall_mkdir+0x68/0xa0
+ vfs_mkdir+0x21c/0x34c
+ do_mkdirat+0x1b4/0x1d4
+ __arm64_sys_mkdirat+0x4c/0x60
+ el0_svc_common.constprop.0+0xa8/0x240
+ do_el0_svc+0x8c/0xc0
+ el0_svc+0x20/0x30
+ el0_sync_handler+0xb0/0xb4
+ el0_sync+0x160/0x180
+
+Therefore, we add cond_resched() to __audit_inode_child() to fix it.
+
+Fixes: 5195d8e217a7 ("audit: dynamically allocate audit_names when not enough space is in the names array")
+Signed-off-by: Gaosheng Cui <cuigaosheng1@huawei.com>
+Signed-off-by: Paul Moore <paul@paul-moore.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/auditsc.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/kernel/auditsc.c b/kernel/auditsc.c
+index addeed3df15d3..8dfd581cd5543 100644
+--- a/kernel/auditsc.c
++++ b/kernel/auditsc.c
+@@ -2456,6 +2456,8 @@ void __audit_inode_child(struct inode *parent,
+ }
+ }
+
++ cond_resched();
++
+ /* is there a matching child entry? */
+ list_for_each_entry(n, &context->names_list, list) {
+ /* can only match entries that have a name */
+--
+2.40.1
+
--- /dev/null
+From 958c2b3e32ff933167671b8942462f1c49a2a7a4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Aug 2023 09:56:23 -1000
+Subject: blk-cgroup: Fix NULL deref caused by blkg_policy_data being installed
+ before init
+
+From: Tejun Heo <tj@kernel.org>
+
+[ Upstream commit ec14a87ee1999b19d8b7ed0fa95fea80644624ae ]
+
+blk-iocost sometimes causes the following crash:
+
+ BUG: kernel NULL pointer dereference, address: 00000000000000e0
+ ...
+ RIP: 0010:_raw_spin_lock+0x17/0x30
+ Code: be 01 02 00 00 e8 79 38 39 ff 31 d2 89 d0 5d c3 0f 1f 00 0f 1f 44 00 00 55 48 89 e5 65 ff 05 48 d0 34 7e b9 01 00 00 00 31 c0 <f0> 0f b1 0f 75 02 5d c3 89 c6 e8 ea 04 00 00 5d c3 0f 1f 84 00 00
+ RSP: 0018:ffffc900023b3d40 EFLAGS: 00010046
+ RAX: 0000000000000000 RBX: 00000000000000e0 RCX: 0000000000000001
+ RDX: ffffc900023b3d20 RSI: ffffc900023b3cf0 RDI: 00000000000000e0
+ RBP: ffffc900023b3d40 R08: ffffc900023b3c10 R09: 0000000000000003
+ R10: 0000000000000064 R11: 000000000000000a R12: ffff888102337000
+ R13: fffffffffffffff2 R14: ffff88810af408c8 R15: ffff8881070c3600
+ FS: 00007faaaf364fc0(0000) GS:ffff88842fdc0000(0000) knlGS:0000000000000000
+ CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ CR2: 00000000000000e0 CR3: 00000001097b1000 CR4: 0000000000350ea0
+ Call Trace:
+ <TASK>
+ ioc_weight_write+0x13d/0x410
+ cgroup_file_write+0x7a/0x130
+ kernfs_fop_write_iter+0xf5/0x170
+ vfs_write+0x298/0x370
+ ksys_write+0x5f/0xb0
+ __x64_sys_write+0x1b/0x20
+ do_syscall_64+0x3d/0x80
+ entry_SYSCALL_64_after_hwframe+0x46/0xb0
+
+This happens because iocg->ioc is NULL. The field is initialized by
+ioc_pd_init() and never cleared. The NULL deref is caused by
+blkcg_activate_policy() installing blkg_policy_data before initializing it.
+
+blkcg_activate_policy() was doing the following:
+
+1. Allocate pd's for all existing blkg's and install them in blkg->pd[].
+2. Initialize all pd's.
+3. Online all pd's.
+
+blkcg_activate_policy() only grabs the queue_lock and may release and
+re-acquire the lock as allocation may need to sleep. ioc_weight_write()
+grabs blkcg->lock and iterates all its blkg's. The two can race and if
+ioc_weight_write() runs during #1 or between #1 and #2, it can encounter a
+pd which is not initialized yet, leading to crash.
+
+The crash can be reproduced with the following script:
+
+ #!/bin/bash
+
+ echo +io > /sys/fs/cgroup/cgroup.subtree_control
+ systemd-run --unit touch-sda --scope dd if=/dev/sda of=/dev/null bs=1M count=1 iflag=direct
+ echo 100 > /sys/fs/cgroup/system.slice/io.weight
+ bash -c "echo '8:0 enable=1' > /sys/fs/cgroup/io.cost.qos" &
+ sleep .2
+ echo 100 > /sys/fs/cgroup/system.slice/io.weight
+
+with the following patch applied:
+
+> diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
+> index fc49be622e05..38d671d5e10c 100644
+> --- a/block/blk-cgroup.c
+> +++ b/block/blk-cgroup.c
+> @@ -1553,6 +1553,12 @@ int blkcg_activate_policy(struct gendisk *disk, const struct blkcg_policy *pol)
+> pd->online = false;
+> }
+>
+> + if (system_state == SYSTEM_RUNNING) {
+> + spin_unlock_irq(&q->queue_lock);
+> + ssleep(1);
+> + spin_lock_irq(&q->queue_lock);
+> + }
+> +
+> /* all allocated, init in the same order */
+> if (pol->pd_init_fn)
+> list_for_each_entry_reverse(blkg, &q->blkg_list, q_node)
+
+I don't see a reason why all pd's should be allocated, initialized and
+onlined together. The only ordering requirement is that parent blkgs to be
+initialized and onlined before children, which is guaranteed from the
+walking order. Let's fix the bug by allocating, initializing and onlining pd
+for each blkg and holding blkcg->lock over initialization and onlining. This
+ensures that an installed blkg is always fully initialized and onlined
+removing the the race window.
+
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Reported-by: Breno Leitao <leitao@debian.org>
+Fixes: 9d179b865449 ("blkcg: Fix multiple bugs in blkcg_activate_policy()")
+Link: https://lore.kernel.org/r/ZN0p5_W-Q9mAHBVY@slm.duckdns.org
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-cgroup.c | 32 ++++++++++++++++++--------------
+ 1 file changed, 18 insertions(+), 14 deletions(-)
+
+diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
+index 9faafcd10e177..4a42ea2972ad8 100644
+--- a/block/blk-cgroup.c
++++ b/block/blk-cgroup.c
+@@ -1511,7 +1511,7 @@ int blkcg_activate_policy(struct gendisk *disk, const struct blkcg_policy *pol)
+ retry:
+ spin_lock_irq(&q->queue_lock);
+
+- /* blkg_list is pushed at the head, reverse walk to allocate parents first */
++ /* blkg_list is pushed at the head, reverse walk to initialize parents first */
+ list_for_each_entry_reverse(blkg, &q->blkg_list, q_node) {
+ struct blkg_policy_data *pd;
+
+@@ -1549,21 +1549,20 @@ int blkcg_activate_policy(struct gendisk *disk, const struct blkcg_policy *pol)
+ goto enomem;
+ }
+
+- blkg->pd[pol->plid] = pd;
++ spin_lock(&blkg->blkcg->lock);
++
+ pd->blkg = blkg;
+ pd->plid = pol->plid;
+- pd->online = false;
+- }
++ blkg->pd[pol->plid] = pd;
+
+- /* all allocated, init in the same order */
+- if (pol->pd_init_fn)
+- list_for_each_entry_reverse(blkg, &q->blkg_list, q_node)
+- pol->pd_init_fn(blkg->pd[pol->plid]);
++ if (pol->pd_init_fn)
++ pol->pd_init_fn(pd);
+
+- list_for_each_entry_reverse(blkg, &q->blkg_list, q_node) {
+ if (pol->pd_online_fn)
+- pol->pd_online_fn(blkg->pd[pol->plid]);
+- blkg->pd[pol->plid]->online = true;
++ pol->pd_online_fn(pd);
++ pd->online = true;
++
++ spin_unlock(&blkg->blkcg->lock);
+ }
+
+ __set_bit(pol->plid, q->blkcg_pols);
+@@ -1580,14 +1579,19 @@ int blkcg_activate_policy(struct gendisk *disk, const struct blkcg_policy *pol)
+ return ret;
+
+ enomem:
+- /* alloc failed, nothing's initialized yet, free everything */
++ /* alloc failed, take down everything */
+ spin_lock_irq(&q->queue_lock);
+ list_for_each_entry(blkg, &q->blkg_list, q_node) {
+ struct blkcg *blkcg = blkg->blkcg;
++ struct blkg_policy_data *pd;
+
+ spin_lock(&blkcg->lock);
+- if (blkg->pd[pol->plid]) {
+- pol->pd_free_fn(blkg->pd[pol->plid]);
++ pd = blkg->pd[pol->plid];
++ if (pd) {
++ if (pd->online && pol->pd_offline_fn)
++ pol->pd_offline_fn(pd);
++ pd->online = false;
++ pol->pd_free_fn(pd);
+ blkg->pd[pol->plid] = NULL;
+ }
+ spin_unlock(&blkcg->lock);
+--
+2.40.1
+
--- /dev/null
+From 969cece4098abce51c7dd2f66e5f2c7616e436a4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Jul 2023 11:42:38 +0200
+Subject: block: cleanup queue_wc_store
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit c4e21bcd0f9d01f9c5d6c52007f5541871a5b1de ]
+
+Get rid of the local queue_wc_store variable and handling setting and
+clearing the QUEUE_FLAG_WC flag diretly instead the if / else if.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Link: https://lore.kernel.org/r/20230707094239.107968-2-hch@lst.de
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Stable-dep-of: 43c9835b144c ("block: don't allow enabling a cache on devices that don't support it")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-sysfs.c | 14 +++-----------
+ 1 file changed, 3 insertions(+), 11 deletions(-)
+
+diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
+index a642085838531..50a0094300f2d 100644
+--- a/block/blk-sysfs.c
++++ b/block/blk-sysfs.c
+@@ -517,21 +517,13 @@ static ssize_t queue_wc_show(struct request_queue *q, char *page)
+ static ssize_t queue_wc_store(struct request_queue *q, const char *page,
+ size_t count)
+ {
+- int set = -1;
+-
+ if (!strncmp(page, "write back", 10))
+- set = 1;
++ blk_queue_flag_set(QUEUE_FLAG_WC, q);
+ else if (!strncmp(page, "write through", 13) ||
+ !strncmp(page, "none", 4))
+- set = 0;
+-
+- if (set == -1)
+- return -EINVAL;
+-
+- if (set)
+- blk_queue_flag_set(QUEUE_FLAG_WC, q);
+- else
+ blk_queue_flag_clear(QUEUE_FLAG_WC, q);
++ else
++ return -EINVAL;
+
+ return count;
+ }
+--
+2.40.1
+
--- /dev/null
+From 2f064dfdeef799188c67584242968773374f2405 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Jul 2023 11:42:39 +0200
+Subject: block: don't allow enabling a cache on devices that don't support it
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit 43c9835b144c7ce29efe142d662529662a9eb376 ]
+
+Currently the write_cache attribute allows enabling the QUEUE_FLAG_WC
+flag on devices that never claimed the capability.
+
+Fix that by adding a QUEUE_FLAG_HW_WC flag that is set by
+blk_queue_write_cache and guards re-enabling the cache through sysfs.
+
+Note that any rescan that calls blk_queue_write_cache will still
+re-enable the write cache as in the current code.
+
+Fixes: 93e9d8e836cb ("block: add ability to flag write back caching on a device")
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Link: https://lore.kernel.org/r/20230707094239.107968-3-hch@lst.de
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-settings.c | 7 +++++--
+ block/blk-sysfs.c | 11 +++++++----
+ include/linux/blkdev.h | 1 +
+ 3 files changed, 13 insertions(+), 6 deletions(-)
+
+diff --git a/block/blk-settings.c b/block/blk-settings.c
+index 4dd59059b788e..0046b447268f9 100644
+--- a/block/blk-settings.c
++++ b/block/blk-settings.c
+@@ -830,10 +830,13 @@ EXPORT_SYMBOL(blk_set_queue_depth);
+ */
+ void blk_queue_write_cache(struct request_queue *q, bool wc, bool fua)
+ {
+- if (wc)
++ if (wc) {
++ blk_queue_flag_set(QUEUE_FLAG_HW_WC, q);
+ blk_queue_flag_set(QUEUE_FLAG_WC, q);
+- else
++ } else {
++ blk_queue_flag_clear(QUEUE_FLAG_HW_WC, q);
+ blk_queue_flag_clear(QUEUE_FLAG_WC, q);
++ }
+ if (fua)
+ blk_queue_flag_set(QUEUE_FLAG_FUA, q);
+ else
+diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
+index 50a0094300f2d..b7fc4cf3f992c 100644
+--- a/block/blk-sysfs.c
++++ b/block/blk-sysfs.c
+@@ -517,13 +517,16 @@ static ssize_t queue_wc_show(struct request_queue *q, char *page)
+ static ssize_t queue_wc_store(struct request_queue *q, const char *page,
+ size_t count)
+ {
+- if (!strncmp(page, "write back", 10))
++ if (!strncmp(page, "write back", 10)) {
++ if (!test_bit(QUEUE_FLAG_HW_WC, &q->queue_flags))
++ return -EINVAL;
+ blk_queue_flag_set(QUEUE_FLAG_WC, q);
+- else if (!strncmp(page, "write through", 13) ||
+- !strncmp(page, "none", 4))
++ } else if (!strncmp(page, "write through", 13) ||
++ !strncmp(page, "none", 4)) {
+ blk_queue_flag_clear(QUEUE_FLAG_WC, q);
+- else
++ } else {
+ return -EINVAL;
++ }
+
+ return count;
+ }
+diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
+index 67e942d776bd8..2e2cd4b824e7f 100644
+--- a/include/linux/blkdev.h
++++ b/include/linux/blkdev.h
+@@ -546,6 +546,7 @@ struct request_queue {
+ #define QUEUE_FLAG_ADD_RANDOM 10 /* Contributes to random pool */
+ #define QUEUE_FLAG_SYNCHRONOUS 11 /* always completes in submit context */
+ #define QUEUE_FLAG_SAME_FORCE 12 /* force complete on same CPU */
++#define QUEUE_FLAG_HW_WC 18 /* Write back caching supported */
+ #define QUEUE_FLAG_INIT_DONE 14 /* queue is initialized */
+ #define QUEUE_FLAG_STABLE_WRITES 15 /* don't modify blks until WB is done */
+ #define QUEUE_FLAG_POLL 16 /* IO polling enabled if set */
+--
+2.40.1
+
--- /dev/null
+From d0e6c6c5f52623a232ebcf657c9e44a3d38304f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Aug 2023 19:12:42 +0800
+Subject: block/mq-deadline: use correct way to throttling write requests
+
+From: Zhiguo Niu <zhiguo.niu@unisoc.com>
+
+[ Upstream commit d47f9717e5cfd0dd8c0ba2ecfa47c38d140f1bb6 ]
+
+The original formula was inaccurate:
+dd->async_depth = max(1UL, 3 * q->nr_requests / 4);
+
+For write requests, when we assign a tags from sched_tags,
+data->shallow_depth will be passed to sbitmap_find_bit,
+see the following code:
+
+nr = sbitmap_find_bit_in_word(&sb->map[index],
+ min_t (unsigned int,
+ __map_depth(sb, index),
+ depth),
+ alloc_hint, wrap);
+
+The smaller of data->shallow_depth and __map_depth(sb, index)
+will be used as the maximum range when allocating bits.
+
+For a mmc device (one hw queue, deadline I/O scheduler):
+q->nr_requests = sched_tags = 128, so according to the previous
+calculation method, dd->async_depth = data->shallow_depth = 96,
+and the platform is 64bits with 8 cpus, sched_tags.bitmap_tags.sb.shift=5,
+sb.maps[]=32/32/32/32, 32 is smaller than 96, whether it is a read or
+a write I/O, tags can be allocated to the maximum range each time,
+which has not throttling effect.
+
+In addition, refer to the methods of bfg/kyber I/O scheduler,
+limit ratiois are calculated base on sched_tags.bitmap_tags.sb.shift.
+
+This patch can throttle write requests really.
+
+Fixes: 07757588e507 ("block/mq-deadline: Reserve 25% of scheduler tags for synchronous requests")
+
+Signed-off-by: Zhiguo Niu <zhiguo.niu@unisoc.com>
+Reviewed-by: Bart Van Assche <bvanassche@acm.org>
+Link: https://lore.kernel.org/r/1691061162-22898-1-git-send-email-zhiguo.niu@unisoc.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/mq-deadline.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/block/mq-deadline.c b/block/mq-deadline.c
+index 5839a027e0f05..7e043d4a78f84 100644
+--- a/block/mq-deadline.c
++++ b/block/mq-deadline.c
+@@ -620,8 +620,9 @@ static void dd_depth_updated(struct blk_mq_hw_ctx *hctx)
+ struct request_queue *q = hctx->queue;
+ struct deadline_data *dd = q->elevator->elevator_data;
+ struct blk_mq_tags *tags = hctx->sched_tags;
++ unsigned int shift = tags->bitmap_tags.sb.shift;
+
+- dd->async_depth = max(1UL, 3 * q->nr_requests / 4);
++ dd->async_depth = max(1U, 3 * (1U << shift) / 4);
+
+ sbitmap_queue_min_shallow_depth(&tags->bitmap_tags, dd->async_depth);
+ }
+--
+2.40.1
+
--- /dev/null
+From 21aa2497d6f7fadd77ef055545de95eded6d470a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Aug 2023 11:46:37 +0800
+Subject: Bluetooth: btusb: Do not call kfree_skb() under spin_lock_irqsave()
+
+From: Jinjie Ruan <ruanjinjie@huawei.com>
+
+[ Upstream commit 2a05334d7f91ff189692089c05fc48cc1d8204de ]
+
+It is not allowed to call kfree_skb() from hardware interrupt
+context or with hardware interrupts being disabled.
+So replace kfree_skb() with dev_kfree_skb_irq() under
+spin_lock_irqsave(). Compile tested only.
+
+Fixes: baac6276c0a9 ("Bluetooth: btusb: handle mSBC audio over USB Endpoints")
+Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btusb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 025e803ba55c2..5559d6d8ae8b2 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -2077,7 +2077,7 @@ static int btusb_switch_alt_setting(struct hci_dev *hdev, int new_alts)
+ * alternate setting.
+ */
+ spin_lock_irqsave(&data->rxlock, flags);
+- kfree_skb(data->sco_skb);
++ dev_kfree_skb_irq(data->sco_skb);
+ data->sco_skb = NULL;
+ spin_unlock_irqrestore(&data->rxlock, flags);
+
+--
+2.40.1
+
--- /dev/null
+From 2b47e60ee163de506d22a81ab1587ec8646ab8d3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Aug 2023 19:07:41 +0800
+Subject: Bluetooth: Fix potential use-after-free when clear keys
+
+From: Min Li <lm0963hack@gmail.com>
+
+[ Upstream commit 3673952cf0c6cf81b06c66a0b788abeeb02ff3ae ]
+
+Similar to commit c5d2b6fa26b5 ("Bluetooth: Fix use-after-free in
+hci_remove_ltk/hci_remove_irk"). We can not access k after kfree_rcu()
+call.
+
+Fixes: d7d41682efc2 ("Bluetooth: Fix Suspicious RCU usage warnings")
+Signed-off-by: Min Li <lm0963hack@gmail.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_core.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
+index 1ec83985f1ab0..793b66da22653 100644
+--- a/net/bluetooth/hci_core.c
++++ b/net/bluetooth/hci_core.c
+@@ -1074,9 +1074,9 @@ void hci_uuids_clear(struct hci_dev *hdev)
+
+ void hci_link_keys_clear(struct hci_dev *hdev)
+ {
+- struct link_key *key;
++ struct link_key *key, *tmp;
+
+- list_for_each_entry(key, &hdev->link_keys, list) {
++ list_for_each_entry_safe(key, tmp, &hdev->link_keys, list) {
+ list_del_rcu(&key->list);
+ kfree_rcu(key, rcu);
+ }
+@@ -1084,9 +1084,9 @@ void hci_link_keys_clear(struct hci_dev *hdev)
+
+ void hci_smp_ltks_clear(struct hci_dev *hdev)
+ {
+- struct smp_ltk *k;
++ struct smp_ltk *k, *tmp;
+
+- list_for_each_entry(k, &hdev->long_term_keys, list) {
++ list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
+ list_del_rcu(&k->list);
+ kfree_rcu(k, rcu);
+ }
+@@ -1094,9 +1094,9 @@ void hci_smp_ltks_clear(struct hci_dev *hdev)
+
+ void hci_smp_irks_clear(struct hci_dev *hdev)
+ {
+- struct smp_irk *k;
++ struct smp_irk *k, *tmp;
+
+- list_for_each_entry(k, &hdev->identity_resolving_keys, list) {
++ list_for_each_entry_safe(k, tmp, &hdev->identity_resolving_keys, list) {
+ list_del_rcu(&k->list);
+ kfree_rcu(k, rcu);
+ }
+@@ -1104,9 +1104,9 @@ void hci_smp_irks_clear(struct hci_dev *hdev)
+
+ void hci_blocked_keys_clear(struct hci_dev *hdev)
+ {
+- struct blocked_key *b;
++ struct blocked_key *b, *tmp;
+
+- list_for_each_entry(b, &hdev->blocked_keys, list) {
++ list_for_each_entry_safe(b, tmp, &hdev->blocked_keys, list) {
+ list_del_rcu(&b->list);
+ kfree_rcu(b, rcu);
+ }
+--
+2.40.1
+
--- /dev/null
+From 9fdbcd14d146318b0b1004e92569c3a68bba35b9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 Jun 2023 12:15:53 -0700
+Subject: Bluetooth: hci_conn: Always allocate unique handles
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 9f78191cc9f1b34c2e2afd7b554a83bf034092dd ]
+
+This attempts to always allocate a unique handle for connections so they
+can be properly aborted by the likes of hci_abort_conn, so this uses the
+invalid range as a pool of unset handles that way if userspace is trying
+to create multiple connections at once each will be given a unique
+handle which will be considered unset.
+
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Stable-dep-of: 66dee21524d9 ("Bluetooth: hci_event: drop only unbound CIS if Set CIG Parameters fails")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/bluetooth/hci_core.h | 2 +-
+ net/bluetooth/hci_conn.c | 25 ++++++++++++++++++++++---
+ net/bluetooth/hci_event.c | 6 +++---
+ 3 files changed, 26 insertions(+), 7 deletions(-)
+
+diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
+index e30e091ef728e..2db826cdf76fa 100644
+--- a/include/net/bluetooth/hci_core.h
++++ b/include/net/bluetooth/hci_core.h
+@@ -321,8 +321,8 @@ struct adv_monitor {
+
+ #define HCI_MAX_SHORT_NAME_LENGTH 10
+
+-#define HCI_CONN_HANDLE_UNSET 0xffff
+ #define HCI_CONN_HANDLE_MAX 0x0eff
++#define HCI_CONN_HANDLE_UNSET(_handle) (_handle > HCI_CONN_HANDLE_MAX)
+
+ /* Min encryption key size to match with SMP */
+ #define HCI_MIN_ENC_KEY_SIZE 7
+diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
+index 7762161a3fc8b..7ced6077488f7 100644
+--- a/net/bluetooth/hci_conn.c
++++ b/net/bluetooth/hci_conn.c
+@@ -991,6 +991,25 @@ static void cis_cleanup(struct hci_conn *conn)
+ hci_le_remove_cig(hdev, conn->iso_qos.ucast.cig);
+ }
+
++static u16 hci_conn_hash_alloc_unset(struct hci_dev *hdev)
++{
++ struct hci_conn_hash *h = &hdev->conn_hash;
++ struct hci_conn *c;
++ u16 handle = HCI_CONN_HANDLE_MAX + 1;
++
++ rcu_read_lock();
++
++ list_for_each_entry_rcu(c, &h->list, list) {
++ /* Find the first unused handle */
++ if (handle == 0xffff || c->handle != handle)
++ break;
++ handle++;
++ }
++ rcu_read_unlock();
++
++ return handle;
++}
++
+ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst,
+ u8 role)
+ {
+@@ -1004,7 +1023,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst,
+
+ bacpy(&conn->dst, dst);
+ bacpy(&conn->src, &hdev->bdaddr);
+- conn->handle = HCI_CONN_HANDLE_UNSET;
++ conn->handle = hci_conn_hash_alloc_unset(hdev);
+ conn->hdev = hdev;
+ conn->type = type;
+ conn->role = role;
+@@ -1117,7 +1136,7 @@ static void hci_conn_unlink(struct hci_conn *conn)
+ */
+ if ((child->type == SCO_LINK ||
+ child->type == ESCO_LINK) &&
+- child->handle == HCI_CONN_HANDLE_UNSET)
++ HCI_CONN_HANDLE_UNSET(child->handle))
+ hci_conn_del(child);
+ }
+
+@@ -1968,7 +1987,7 @@ int hci_conn_check_create_cis(struct hci_conn *conn)
+ return -EINVAL;
+
+ if (!conn->parent || conn->parent->state != BT_CONNECTED ||
+- conn->state != BT_CONNECT || conn->handle == HCI_CONN_HANDLE_UNSET)
++ conn->state != BT_CONNECT || HCI_CONN_HANDLE_UNSET(conn->handle))
+ return 1;
+
+ return 0;
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index e3675d8a23e44..22fb9f9da866b 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -3173,7 +3173,7 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
+ * As the connection handle is set here for the first time, it indicates
+ * whether the connection is already set up.
+ */
+- if (conn->handle != HCI_CONN_HANDLE_UNSET) {
++ if (!HCI_CONN_HANDLE_UNSET(conn->handle)) {
+ bt_dev_err(hdev, "Ignoring HCI_Connection_Complete for existing connection");
+ goto unlock;
+ }
+@@ -5008,7 +5008,7 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev, void *data,
+ * As the connection handle is set here for the first time, it indicates
+ * whether the connection is already set up.
+ */
+- if (conn->handle != HCI_CONN_HANDLE_UNSET) {
++ if (!HCI_CONN_HANDLE_UNSET(conn->handle)) {
+ bt_dev_err(hdev, "Ignoring HCI_Sync_Conn_Complete event for existing connection");
+ goto unlock;
+ }
+@@ -5872,7 +5872,7 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
+ * As the connection handle is set here for the first time, it indicates
+ * whether the connection is already set up.
+ */
+- if (conn->handle != HCI_CONN_HANDLE_UNSET) {
++ if (!HCI_CONN_HANDLE_UNSET(conn->handle)) {
+ bt_dev_err(hdev, "Ignoring HCI_Connection_Complete for existing connection");
+ goto unlock;
+ }
+--
+2.40.1
+
--- /dev/null
+From 85e0c5ae055a9ad3bd9a40003b6ef5f6801f5452 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Jun 2023 17:25:06 -0700
+Subject: Bluetooth: hci_conn: Consolidate code for aborting connections
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit a13f316e90fdb1fb6df6582e845aa9b3270f3581 ]
+
+This consolidates code for aborting connections using
+hci_cmd_sync_queue so it is synchronized with other threads, but
+because of the fact that some commands may block the cmd_sync_queue
+while waiting specific events this attempt to cancel those requests by
+using hci_cmd_sync_cancel.
+
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Stable-dep-of: 94d9ba9f9888 ("Bluetooth: hci_sync: Fix UAF in hci_disconnect_all_sync")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/bluetooth/hci_core.h | 2 +-
+ net/bluetooth/hci_conn.c | 154 ++++++-------------------------
+ net/bluetooth/hci_sync.c | 23 +++--
+ net/bluetooth/mgmt.c | 15 +--
+ 4 files changed, 47 insertions(+), 147 deletions(-)
+
+diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
+index 2db826cdf76fa..e4c1e503415b6 100644
+--- a/include/net/bluetooth/hci_core.h
++++ b/include/net/bluetooth/hci_core.h
+@@ -741,6 +741,7 @@ struct hci_conn {
+ unsigned long flags;
+
+ enum conn_reasons conn_reason;
++ __u8 abort_reason;
+
+ __u32 clock;
+ __u16 clock_accuracy;
+@@ -760,7 +761,6 @@ struct hci_conn {
+ struct delayed_work auto_accept_work;
+ struct delayed_work idle_work;
+ struct delayed_work le_conn_timeout;
+- struct work_struct le_scan_cleanup;
+
+ struct device dev;
+ struct dentry *debugfs;
+diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
+index 7ced6077488f7..f05b99437e280 100644
+--- a/net/bluetooth/hci_conn.c
++++ b/net/bluetooth/hci_conn.c
+@@ -178,57 +178,6 @@ static void hci_conn_cleanup(struct hci_conn *conn)
+ hci_conn_put(conn);
+ }
+
+-static void le_scan_cleanup(struct work_struct *work)
+-{
+- struct hci_conn *conn = container_of(work, struct hci_conn,
+- le_scan_cleanup);
+- struct hci_dev *hdev = conn->hdev;
+- struct hci_conn *c = NULL;
+-
+- BT_DBG("%s hcon %p", hdev->name, conn);
+-
+- hci_dev_lock(hdev);
+-
+- /* Check that the hci_conn is still around */
+- rcu_read_lock();
+- list_for_each_entry_rcu(c, &hdev->conn_hash.list, list) {
+- if (c == conn)
+- break;
+- }
+- rcu_read_unlock();
+-
+- if (c == conn) {
+- hci_connect_le_scan_cleanup(conn, 0x00);
+- hci_conn_cleanup(conn);
+- }
+-
+- hci_dev_unlock(hdev);
+- hci_dev_put(hdev);
+- hci_conn_put(conn);
+-}
+-
+-static void hci_connect_le_scan_remove(struct hci_conn *conn)
+-{
+- BT_DBG("%s hcon %p", conn->hdev->name, conn);
+-
+- /* We can't call hci_conn_del/hci_conn_cleanup here since that
+- * could deadlock with another hci_conn_del() call that's holding
+- * hci_dev_lock and doing cancel_delayed_work_sync(&conn->disc_work).
+- * Instead, grab temporary extra references to the hci_dev and
+- * hci_conn and perform the necessary cleanup in a separate work
+- * callback.
+- */
+-
+- hci_dev_hold(conn->hdev);
+- hci_conn_get(conn);
+-
+- /* Even though we hold a reference to the hdev, many other
+- * things might get cleaned up meanwhile, including the hdev's
+- * own workqueue, so we can't use that for scheduling.
+- */
+- schedule_work(&conn->le_scan_cleanup);
+-}
+-
+ static void hci_acl_create_connection(struct hci_conn *conn)
+ {
+ struct hci_dev *hdev = conn->hdev;
+@@ -679,13 +628,6 @@ static void hci_conn_timeout(struct work_struct *work)
+ if (refcnt > 0)
+ return;
+
+- /* LE connections in scanning state need special handling */
+- if (conn->state == BT_CONNECT && conn->type == LE_LINK &&
+- test_bit(HCI_CONN_SCANNING, &conn->flags)) {
+- hci_connect_le_scan_remove(conn);
+- return;
+- }
+-
+ hci_abort_conn(conn, hci_proto_disconn_ind(conn));
+ }
+
+@@ -1086,7 +1028,6 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst,
+ INIT_DELAYED_WORK(&conn->auto_accept_work, hci_conn_auto_accept);
+ INIT_DELAYED_WORK(&conn->idle_work, hci_conn_idle);
+ INIT_DELAYED_WORK(&conn->le_conn_timeout, le_conn_timeout);
+- INIT_WORK(&conn->le_scan_cleanup, le_scan_cleanup);
+
+ atomic_set(&conn->refcnt, 0);
+
+@@ -2885,81 +2826,46 @@ u32 hci_conn_get_phy(struct hci_conn *conn)
+ return phys;
+ }
+
+-int hci_abort_conn(struct hci_conn *conn, u8 reason)
++static int abort_conn_sync(struct hci_dev *hdev, void *data)
+ {
+- int r = 0;
++ struct hci_conn *conn;
++ u16 handle = PTR_ERR(data);
+
+- if (test_and_set_bit(HCI_CONN_CANCEL, &conn->flags))
++ conn = hci_conn_hash_lookup_handle(hdev, handle);
++ if (!conn)
+ return 0;
+
+- switch (conn->state) {
+- case BT_CONNECTED:
+- case BT_CONFIG:
+- if (conn->type == AMP_LINK) {
+- struct hci_cp_disconn_phy_link cp;
++ return hci_abort_conn_sync(hdev, conn, conn->abort_reason);
++}
+
+- cp.phy_handle = HCI_PHY_HANDLE(conn->handle);
+- cp.reason = reason;
+- r = hci_send_cmd(conn->hdev, HCI_OP_DISCONN_PHY_LINK,
+- sizeof(cp), &cp);
+- } else {
+- struct hci_cp_disconnect dc;
++int hci_abort_conn(struct hci_conn *conn, u8 reason)
++{
++ struct hci_dev *hdev = conn->hdev;
+
+- dc.handle = cpu_to_le16(conn->handle);
+- dc.reason = reason;
+- r = hci_send_cmd(conn->hdev, HCI_OP_DISCONNECT,
+- sizeof(dc), &dc);
+- }
++ /* If abort_reason has already been set it means the connection is
++ * already being aborted so don't attempt to overwrite it.
++ */
++ if (conn->abort_reason)
++ return 0;
+
+- conn->state = BT_DISCONN;
++ bt_dev_dbg(hdev, "handle 0x%2.2x reason 0x%2.2x", conn->handle, reason);
+
+- break;
+- case BT_CONNECT:
+- if (conn->type == LE_LINK) {
+- if (test_bit(HCI_CONN_SCANNING, &conn->flags))
+- break;
+- r = hci_send_cmd(conn->hdev,
+- HCI_OP_LE_CREATE_CONN_CANCEL, 0, NULL);
+- } else if (conn->type == ACL_LINK) {
+- if (conn->hdev->hci_ver < BLUETOOTH_VER_1_2)
+- break;
+- r = hci_send_cmd(conn->hdev,
+- HCI_OP_CREATE_CONN_CANCEL,
+- 6, &conn->dst);
+- }
+- break;
+- case BT_CONNECT2:
+- if (conn->type == ACL_LINK) {
+- struct hci_cp_reject_conn_req rej;
+-
+- bacpy(&rej.bdaddr, &conn->dst);
+- rej.reason = reason;
+-
+- r = hci_send_cmd(conn->hdev,
+- HCI_OP_REJECT_CONN_REQ,
+- sizeof(rej), &rej);
+- } else if (conn->type == SCO_LINK || conn->type == ESCO_LINK) {
+- struct hci_cp_reject_sync_conn_req rej;
+-
+- bacpy(&rej.bdaddr, &conn->dst);
+-
+- /* SCO rejection has its own limited set of
+- * allowed error values (0x0D-0x0F) which isn't
+- * compatible with most values passed to this
+- * function. To be safe hard-code one of the
+- * values that's suitable for SCO.
+- */
+- rej.reason = HCI_ERROR_REJ_LIMITED_RESOURCES;
++ conn->abort_reason = reason;
+
+- r = hci_send_cmd(conn->hdev,
+- HCI_OP_REJECT_SYNC_CONN_REQ,
+- sizeof(rej), &rej);
++ /* If the connection is pending check the command opcode since that
++ * might be blocking on hci_cmd_sync_work while waiting its respective
++ * event so we need to hci_cmd_sync_cancel to cancel it.
++ */
++ if (conn->state == BT_CONNECT && hdev->req_status == HCI_REQ_PEND) {
++ switch (hci_skb_event(hdev->sent_cmd)) {
++ case HCI_EV_LE_CONN_COMPLETE:
++ case HCI_EV_LE_ENHANCED_CONN_COMPLETE:
++ case HCI_EVT_LE_CIS_ESTABLISHED:
++ hci_cmd_sync_cancel(hdev, -ECANCELED);
++ break;
+ }
+- break;
+- default:
+- conn->state = BT_CLOSED;
+- break;
+ }
+
+- return r;
++ return hci_cmd_sync_queue(hdev, abort_conn_sync, ERR_PTR(conn->handle),
++ NULL);
+ }
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index 50f34c812cccd..e3b7f21046dbc 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -5271,22 +5271,27 @@ static int hci_disconnect_sync(struct hci_dev *hdev, struct hci_conn *conn,
+ }
+
+ static int hci_le_connect_cancel_sync(struct hci_dev *hdev,
+- struct hci_conn *conn)
++ struct hci_conn *conn, u8 reason)
+ {
++ /* Return reason if scanning since the connection shall probably be
++ * cleanup directly.
++ */
+ if (test_bit(HCI_CONN_SCANNING, &conn->flags))
+- return 0;
++ return reason;
+
+- if (test_and_set_bit(HCI_CONN_CANCEL, &conn->flags))
++ if (conn->role == HCI_ROLE_SLAVE ||
++ test_and_set_bit(HCI_CONN_CANCEL, &conn->flags))
+ return 0;
+
+ return __hci_cmd_sync_status(hdev, HCI_OP_LE_CREATE_CONN_CANCEL,
+ 0, NULL, HCI_CMD_TIMEOUT);
+ }
+
+-static int hci_connect_cancel_sync(struct hci_dev *hdev, struct hci_conn *conn)
++static int hci_connect_cancel_sync(struct hci_dev *hdev, struct hci_conn *conn,
++ u8 reason)
+ {
+ if (conn->type == LE_LINK)
+- return hci_le_connect_cancel_sync(hdev, conn);
++ return hci_le_connect_cancel_sync(hdev, conn, reason);
+
+ if (hdev->hci_ver < BLUETOOTH_VER_1_2)
+ return 0;
+@@ -5339,9 +5344,11 @@ int hci_abort_conn_sync(struct hci_dev *hdev, struct hci_conn *conn, u8 reason)
+ case BT_CONFIG:
+ return hci_disconnect_sync(hdev, conn, reason);
+ case BT_CONNECT:
+- err = hci_connect_cancel_sync(hdev, conn);
++ err = hci_connect_cancel_sync(hdev, conn, reason);
+ /* Cleanup hci_conn object if it cannot be cancelled as it
+- * likelly means the controller and host stack are out of sync.
++ * likelly means the controller and host stack are out of sync
++ * or in case of LE it was still scanning so it can be cleanup
++ * safely.
+ */
+ if (err) {
+ hci_dev_lock(hdev);
+@@ -6255,7 +6262,7 @@ int hci_le_create_conn_sync(struct hci_dev *hdev, struct hci_conn *conn)
+
+ done:
+ if (err == -ETIMEDOUT)
+- hci_le_connect_cancel_sync(hdev, conn);
++ hci_le_connect_cancel_sync(hdev, conn, 0x00);
+
+ /* Re-enable advertising after the connection attempt is finished. */
+ hci_resume_advertising_sync(hdev);
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index d4498037fadc6..6240b20f020a8 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -3580,18 +3580,6 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
+ return err;
+ }
+
+-static int abort_conn_sync(struct hci_dev *hdev, void *data)
+-{
+- struct hci_conn *conn;
+- u16 handle = PTR_ERR(data);
+-
+- conn = hci_conn_hash_lookup_handle(hdev, handle);
+- if (!conn)
+- return 0;
+-
+- return hci_abort_conn_sync(hdev, conn, HCI_ERROR_REMOTE_USER_TERM);
+-}
+-
+ static int cancel_pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
+ u16 len)
+ {
+@@ -3642,8 +3630,7 @@ static int cancel_pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
+ le_addr_type(addr->type));
+
+ if (conn->conn_reason == CONN_REASON_PAIR_DEVICE)
+- hci_cmd_sync_queue(hdev, abort_conn_sync, ERR_PTR(conn->handle),
+- NULL);
++ hci_abort_conn(conn, HCI_ERROR_REMOTE_USER_TERM);
+
+ unlock:
+ hci_dev_unlock(hdev);
+--
+2.40.1
+
--- /dev/null
+From fc5d3aaa18ee62a1209030767146e22979e11617 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 19 Aug 2023 16:33:36 +0300
+Subject: Bluetooth: hci_conn: fail SCO/ISO via hci_conn_failed if ACL gone
+ early
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit 3344d318337d9dca928fd448e966557ec5063f85 ]
+
+Not calling hci_(dis)connect_cfm before deleting conn referred to by a
+socket generally results to use-after-free.
+
+When cleaning up SCO connections when the parent ACL is deleted too
+early, use hci_conn_failed to do the connection cleanup properly.
+
+We also need to clean up ISO connections in a similar situation when
+connecting has started but LE Create CIS is not yet sent, so do it too
+here.
+
+Fixes: ca1fd42e7dbf ("Bluetooth: Fix potential double free caused by hci_conn_unlink")
+Reported-by: syzbot+cf54c1da6574b6c1b049@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/linux-bluetooth/00000000000013b93805fbbadc50@google.com/
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_conn.c | 32 ++++++++++++++++++++++++--------
+ 1 file changed, 24 insertions(+), 8 deletions(-)
+
+diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
+index 4f31340c2c932..eb2802ef34bfe 100644
+--- a/net/bluetooth/hci_conn.c
++++ b/net/bluetooth/hci_conn.c
+@@ -1040,6 +1040,29 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst,
+ return conn;
+ }
+
++static void hci_conn_cleanup_child(struct hci_conn *conn, u8 reason)
++{
++ if (!reason)
++ reason = HCI_ERROR_REMOTE_USER_TERM;
++
++ /* Due to race, SCO/ISO conn might be not established yet at this point,
++ * and nothing else will clean it up. In other cases it is done via HCI
++ * events.
++ */
++ switch (conn->type) {
++ case SCO_LINK:
++ case ESCO_LINK:
++ if (HCI_CONN_HANDLE_UNSET(conn->handle))
++ hci_conn_failed(conn, reason);
++ break;
++ case ISO_LINK:
++ if (conn->state != BT_CONNECTED &&
++ !test_bit(HCI_CONN_CREATE_CIS, &conn->flags))
++ hci_conn_failed(conn, reason);
++ break;
++ }
++}
++
+ static void hci_conn_unlink(struct hci_conn *conn)
+ {
+ struct hci_dev *hdev = conn->hdev;
+@@ -1062,14 +1085,7 @@ static void hci_conn_unlink(struct hci_conn *conn)
+ if (!test_bit(HCI_UP, &hdev->flags))
+ continue;
+
+- /* Due to race, SCO connection might be not established
+- * yet at this point. Delete it now, otherwise it is
+- * possible for it to be stuck and can't be deleted.
+- */
+- if ((child->type == SCO_LINK ||
+- child->type == ESCO_LINK) &&
+- HCI_CONN_HANDLE_UNSET(child->handle))
+- hci_conn_del(child);
++ hci_conn_cleanup_child(child, conn->abort_reason);
+ }
+
+ return;
+--
+2.40.1
+
--- /dev/null
+From c497aa99da37b4370383770018e83c7a2b27cd8c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Aug 2023 14:54:09 -0700
+Subject: Bluetooth: hci_conn: Fix hci_le_set_cig_params
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit a091289218202bc09d9b9caa8afcde1018584aec ]
+
+When running with concurrent task only one CIS was being assigned so
+this attempts to rework the way the PDU is constructed so it is handled
+later at the callback instead of in place.
+
+Fixes: 26afbd826ee3 ("Bluetooth: Add initial implementation of CIS connections")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_conn.c | 157 ++++++++++++++++-----------------------
+ 1 file changed, 63 insertions(+), 94 deletions(-)
+
+diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
+index 7516166652a08..7762161a3fc8b 100644
+--- a/net/bluetooth/hci_conn.c
++++ b/net/bluetooth/hci_conn.c
+@@ -791,7 +791,6 @@ struct iso_list_data {
+ u16 sync_handle;
+ };
+ int count;
+- struct iso_cig_params pdu;
+ bool big_term;
+ };
+
+@@ -1719,42 +1718,6 @@ struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst,
+ return sco;
+ }
+
+-static void cis_add(struct iso_list_data *d, struct bt_iso_qos *qos)
+-{
+- struct hci_cis_params *cis = &d->pdu.cis[d->pdu.cp.num_cis];
+-
+- cis->cis_id = qos->ucast.cis;
+- cis->c_sdu = cpu_to_le16(qos->ucast.out.sdu);
+- cis->p_sdu = cpu_to_le16(qos->ucast.in.sdu);
+- cis->c_phy = qos->ucast.out.phy ? qos->ucast.out.phy : qos->ucast.in.phy;
+- cis->p_phy = qos->ucast.in.phy ? qos->ucast.in.phy : qos->ucast.out.phy;
+- cis->c_rtn = qos->ucast.out.rtn;
+- cis->p_rtn = qos->ucast.in.rtn;
+-
+- d->pdu.cp.num_cis++;
+-}
+-
+-static void cis_list(struct hci_conn *conn, void *data)
+-{
+- struct iso_list_data *d = data;
+-
+- /* Skip if broadcast/ANY address */
+- if (!bacmp(&conn->dst, BDADDR_ANY))
+- return;
+-
+- if (d->cig != conn->iso_qos.ucast.cig || d->cis == BT_ISO_QOS_CIS_UNSET ||
+- d->cis != conn->iso_qos.ucast.cis)
+- return;
+-
+- d->count++;
+-
+- if (d->pdu.cp.cig_id == BT_ISO_QOS_CIG_UNSET ||
+- d->count >= ARRAY_SIZE(d->pdu.cis))
+- return;
+-
+- cis_add(d, &conn->iso_qos);
+-}
+-
+ static int hci_le_create_big(struct hci_conn *conn, struct bt_iso_qos *qos)
+ {
+ struct hci_dev *hdev = conn->hdev;
+@@ -1787,25 +1750,62 @@ static int hci_le_create_big(struct hci_conn *conn, struct bt_iso_qos *qos)
+ return hci_send_cmd(hdev, HCI_OP_LE_CREATE_BIG, sizeof(cp), &cp);
+ }
+
+-static void set_cig_params_complete(struct hci_dev *hdev, void *data, int err)
++static int set_cig_params_sync(struct hci_dev *hdev, void *data)
+ {
+- struct iso_cig_params *pdu = data;
++ u8 cig_id = PTR_ERR(data);
++ struct hci_conn *conn;
++ struct bt_iso_qos *qos;
++ struct iso_cig_params pdu;
++ u8 cis_id;
+
+- bt_dev_dbg(hdev, "");
++ conn = hci_conn_hash_lookup_cig(hdev, cig_id);
++ if (!conn)
++ return 0;
+
+- if (err)
+- bt_dev_err(hdev, "Unable to set CIG parameters: %d", err);
++ memset(&pdu, 0, sizeof(pdu));
+
+- kfree(pdu);
+-}
++ qos = &conn->iso_qos;
++ pdu.cp.cig_id = cig_id;
++ hci_cpu_to_le24(qos->ucast.out.interval, pdu.cp.c_interval);
++ hci_cpu_to_le24(qos->ucast.in.interval, pdu.cp.p_interval);
++ pdu.cp.sca = qos->ucast.sca;
++ pdu.cp.packing = qos->ucast.packing;
++ pdu.cp.framing = qos->ucast.framing;
++ pdu.cp.c_latency = cpu_to_le16(qos->ucast.out.latency);
++ pdu.cp.p_latency = cpu_to_le16(qos->ucast.in.latency);
+
+-static int set_cig_params_sync(struct hci_dev *hdev, void *data)
+-{
+- struct iso_cig_params *pdu = data;
+- u32 plen;
++ /* Reprogram all CIS(s) with the same CIG, valid range are:
++ * num_cis: 0x00 to 0x1F
++ * cis_id: 0x00 to 0xEF
++ */
++ for (cis_id = 0x00; cis_id < 0xf0 &&
++ pdu.cp.num_cis < ARRAY_SIZE(pdu.cis); cis_id++) {
++ struct hci_cis_params *cis;
++
++ conn = hci_conn_hash_lookup_cis(hdev, NULL, 0, cig_id, cis_id);
++ if (!conn)
++ continue;
+
+- plen = sizeof(pdu->cp) + pdu->cp.num_cis * sizeof(pdu->cis[0]);
+- return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_CIG_PARAMS, plen, pdu,
++ qos = &conn->iso_qos;
++
++ cis = &pdu.cis[pdu.cp.num_cis++];
++ cis->cis_id = cis_id;
++ cis->c_sdu = cpu_to_le16(conn->iso_qos.ucast.out.sdu);
++ cis->p_sdu = cpu_to_le16(conn->iso_qos.ucast.in.sdu);
++ cis->c_phy = qos->ucast.out.phy ? qos->ucast.out.phy :
++ qos->ucast.in.phy;
++ cis->p_phy = qos->ucast.in.phy ? qos->ucast.in.phy :
++ qos->ucast.out.phy;
++ cis->c_rtn = qos->ucast.out.rtn;
++ cis->p_rtn = qos->ucast.in.rtn;
++ }
++
++ if (!pdu.cp.num_cis)
++ return 0;
++
++ return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_CIG_PARAMS,
++ sizeof(pdu.cp) +
++ pdu.cp.num_cis * sizeof(pdu.cis[0]), &pdu,
+ HCI_CMD_TIMEOUT);
+ }
+
+@@ -1813,7 +1813,6 @@ static bool hci_le_set_cig_params(struct hci_conn *conn, struct bt_iso_qos *qos)
+ {
+ struct hci_dev *hdev = conn->hdev;
+ struct iso_list_data data;
+- struct iso_cig_params *pdu;
+
+ memset(&data, 0, sizeof(data));
+
+@@ -1840,61 +1839,31 @@ static bool hci_le_set_cig_params(struct hci_conn *conn, struct bt_iso_qos *qos)
+ qos->ucast.cig = data.cig;
+ }
+
+- data.pdu.cp.cig_id = qos->ucast.cig;
+- hci_cpu_to_le24(qos->ucast.out.interval, data.pdu.cp.c_interval);
+- hci_cpu_to_le24(qos->ucast.in.interval, data.pdu.cp.p_interval);
+- data.pdu.cp.sca = qos->ucast.sca;
+- data.pdu.cp.packing = qos->ucast.packing;
+- data.pdu.cp.framing = qos->ucast.framing;
+- data.pdu.cp.c_latency = cpu_to_le16(qos->ucast.out.latency);
+- data.pdu.cp.p_latency = cpu_to_le16(qos->ucast.in.latency);
+-
+ if (qos->ucast.cis != BT_ISO_QOS_CIS_UNSET) {
+- data.count = 0;
+- data.cig = qos->ucast.cig;
+- data.cis = qos->ucast.cis;
+-
+- hci_conn_hash_list_state(hdev, cis_list, ISO_LINK, BT_BOUND,
+- &data);
+- if (data.count)
++ if (hci_conn_hash_lookup_cis(hdev, NULL, 0, qos->ucast.cig,
++ qos->ucast.cis))
+ return false;
+-
+- cis_add(&data, qos);
++ goto done;
+ }
+
+- /* Reprogram all CIS(s) with the same CIG, valid range are:
+- * num_cis: 0x00 to 0x1F
+- * cis_id: 0x00 to 0xEF
+- */
+- for (data.cig = qos->ucast.cig, data.cis = 0x00; data.cis < 0xf0 &&
+- data.pdu.cp.num_cis < ARRAY_SIZE(data.pdu.cis); data.cis++) {
+- data.count = 0;
+-
+- hci_conn_hash_list_state(hdev, cis_list, ISO_LINK, BT_BOUND,
+- &data);
+- if (data.count)
+- continue;
+-
+- /* Allocate a CIS if not set */
+- if (qos->ucast.cis == BT_ISO_QOS_CIS_UNSET) {
++ /* Allocate first available CIS if not set */
++ for (data.cig = qos->ucast.cig, data.cis = 0x00; data.cis < 0xf0;
++ data.cis++) {
++ if (!hci_conn_hash_lookup_cis(hdev, NULL, 0, data.cig,
++ data.cis)) {
+ /* Update CIS */
+ qos->ucast.cis = data.cis;
+- cis_add(&data, qos);
++ break;
+ }
+ }
+
+- if (qos->ucast.cis == BT_ISO_QOS_CIS_UNSET || !data.pdu.cp.num_cis)
++ if (qos->ucast.cis == BT_ISO_QOS_CIS_UNSET)
+ return false;
+
+- pdu = kmemdup(&data.pdu, sizeof(*pdu), GFP_KERNEL);
+- if (!pdu)
+- return false;
+-
+- if (hci_cmd_sync_queue(hdev, set_cig_params_sync, pdu,
+- set_cig_params_complete) < 0) {
+- kfree(pdu);
++done:
++ if (hci_cmd_sync_queue(hdev, set_cig_params_sync,
++ ERR_PTR(qos->ucast.cig), NULL) < 0)
+ return false;
+- }
+
+ return true;
+ }
+--
+2.40.1
+
--- /dev/null
+From 4104faa39b5299a011bacff1a7d48c2af77a151f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Aug 2023 16:41:34 -0700
+Subject: Bluetooth: hci_conn: Fix not allowing valid CIS ID
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit f2f84a70f9d0c9a3263194ca9d82e7bc6027d356 ]
+
+Only the number of CIS shall be limited to 0x1f, the CIS ID in the
+other hand is up to 0xef.
+
+Fixes: 26afbd826ee3 ("Bluetooth: Add initial implementation of CIS connections")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_conn.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
+index d481a1d2c0a28..ee9d6ff75246f 100644
+--- a/net/bluetooth/hci_conn.c
++++ b/net/bluetooth/hci_conn.c
+@@ -1862,9 +1862,12 @@ static bool hci_le_set_cig_params(struct hci_conn *conn, struct bt_iso_qos *qos)
+ cis_add(&data, qos);
+ }
+
+- /* Reprogram all CIS(s) with the same CIG */
+- for (data.cig = qos->ucast.cig, data.cis = 0x00; data.cis < 0x11;
+- data.cis++) {
++ /* Reprogram all CIS(s) with the same CIG, valid range are:
++ * num_cis: 0x00 to 0x1F
++ * cis_id: 0x00 to 0xEF
++ */
++ for (data.cig = qos->ucast.cig, data.cis = 0x00; data.cis < 0xf0 &&
++ data.pdu.cp.num_cis < ARRAY_SIZE(data.pdu.cis); data.cis++) {
+ data.count = 0;
+
+ hci_conn_hash_list_state(hdev, cis_list, ISO_LINK, BT_BOUND,
+--
+2.40.1
+
--- /dev/null
+From ee5f754034255f105be39a825cfccb83d7d60e6f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 25 Jun 2023 16:45:13 +0800
+Subject: Bluetooth: hci_conn: Use kmemdup() to replace kzalloc + memcpy
+
+From: Jiapeng Chong <jiapeng.chong@linux.alibaba.com>
+
+[ Upstream commit 5b6d345d1b65d67624349e5de22227492c637576 ]
+
+Use kmemdup rather than duplicating its implementation.
+
+./net/bluetooth/hci_conn.c:1880:7-14: WARNING opportunity for kmemdup.
+
+Reported-by: Abaci Robot <abaci@linux.alibaba.com>
+Closes: https://bugzilla.openanolis.cn/show_bug.cgi?id=5597
+Signed-off-by: Jiapeng Chong <jiapeng.chong@linux.alibaba.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: a09128921820 ("Bluetooth: hci_conn: Fix hci_le_set_cig_params")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_conn.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
+index ee9d6ff75246f..7516166652a08 100644
+--- a/net/bluetooth/hci_conn.c
++++ b/net/bluetooth/hci_conn.c
+@@ -1886,12 +1886,10 @@ static bool hci_le_set_cig_params(struct hci_conn *conn, struct bt_iso_qos *qos)
+ if (qos->ucast.cis == BT_ISO_QOS_CIS_UNSET || !data.pdu.cp.num_cis)
+ return false;
+
+- pdu = kzalloc(sizeof(*pdu), GFP_KERNEL);
++ pdu = kmemdup(&data.pdu, sizeof(*pdu), GFP_KERNEL);
+ if (!pdu)
+ return false;
+
+- memcpy(pdu, &data.pdu, sizeof(*pdu));
+-
+ if (hci_cmd_sync_queue(hdev, set_cig_params_sync, pdu,
+ set_cig_params_complete) < 0) {
+ kfree(pdu);
+--
+2.40.1
+
--- /dev/null
+From ec51ec6b7a2c426396cfe8de2d093678ca8b2fa1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 5 Aug 2023 19:08:41 +0300
+Subject: Bluetooth: hci_event: drop only unbound CIS if Set CIG Parameters
+ fails
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit 66dee21524d9ac6461ec3052652b7bc0603ee0c5 ]
+
+When user tries to connect a new CIS when its CIG is not configurable,
+that connection shall fail, but pre-existing connections shall not be
+affected. However, currently hci_cc_le_set_cig_params deletes all CIS
+of the CIG on error so it doesn't work, even though controller shall not
+change CIG/CIS configuration if the command fails.
+
+Fix by failing on command error only the connections that are not yet
+bound, so that we keep the previous CIS configuration like the
+controller does.
+
+Fixes: 26afbd826ee3 ("Bluetooth: Add initial implementation of CIS connections")
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 29 ++++++++++++++++++++++++-----
+ 1 file changed, 24 insertions(+), 5 deletions(-)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 22fb9f9da866b..866d2cd43bf78 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -3803,6 +3803,22 @@ static u8 hci_cc_le_read_buffer_size_v2(struct hci_dev *hdev, void *data,
+ return rp->status;
+ }
+
++static void hci_unbound_cis_failed(struct hci_dev *hdev, u8 cig, u8 status)
++{
++ struct hci_conn *conn, *tmp;
++
++ lockdep_assert_held(&hdev->lock);
++
++ list_for_each_entry_safe(conn, tmp, &hdev->conn_hash.list, list) {
++ if (conn->type != ISO_LINK || !bacmp(&conn->dst, BDADDR_ANY) ||
++ conn->state == BT_OPEN || conn->iso_qos.ucast.cig != cig)
++ continue;
++
++ if (HCI_CONN_HANDLE_UNSET(conn->handle))
++ hci_conn_failed(conn, status);
++ }
++}
++
+ static u8 hci_cc_le_set_cig_params(struct hci_dev *hdev, void *data,
+ struct sk_buff *skb)
+ {
+@@ -3823,12 +3839,15 @@ static u8 hci_cc_le_set_cig_params(struct hci_dev *hdev, void *data,
+
+ hci_dev_lock(hdev);
+
++ /* BLUETOOTH CORE SPECIFICATION Version 5.4 | Vol 4, Part E page 2554
++ *
++ * If the Status return parameter is non-zero, then the state of the CIG
++ * and its CIS configurations shall not be changed by the command. If
++ * the CIG did not already exist, it shall not be created.
++ */
+ if (status) {
+- while ((conn = hci_conn_hash_lookup_cig(hdev, rp->cig_id))) {
+- conn->state = BT_CLOSED;
+- hci_connect_cfm(conn, status);
+- hci_conn_del(conn);
+- }
++ /* Keep current configuration, fail only the unbound CIS */
++ hci_unbound_cis_failed(hdev, rp->cig_id, status);
+ goto unlock;
+ }
+
+--
+2.40.1
+
--- /dev/null
+From 7dd7f64afecd2320729465b7d1f396b262865aa3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Jun 2023 15:41:11 -0700
+Subject: Bluetooth: hci_event: Fix parsing of CIS Established Event
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 2be22f1941d5f661aa8043261d1bae5b6696c749 ]
+
+The ISO Interval on CIS Established Event uses 1.25 ms slots:
+
+ BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E
+ page 2304:
+
+ Time = N * 1.25 ms
+
+In addition to that this always update the QoS settings based on CIS
+Established Event.
+
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 7f74563e6140 ("Bluetooth: ISO: do not emit new LE Create CIS if previous is pending")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 49 +++++++++++++++++++++++++++------------
+ 1 file changed, 34 insertions(+), 15 deletions(-)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index cb0b5fe7a6f8c..b2b38d5014e7f 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -6788,6 +6788,7 @@ static void hci_le_cis_estabilished_evt(struct hci_dev *hdev, void *data,
+ {
+ struct hci_evt_le_cis_established *ev = data;
+ struct hci_conn *conn;
++ struct bt_iso_qos *qos;
+ u16 handle = __le16_to_cpu(ev->handle);
+
+ bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
+@@ -6809,21 +6810,39 @@ static void hci_le_cis_estabilished_evt(struct hci_dev *hdev, void *data,
+ goto unlock;
+ }
+
+- if (conn->role == HCI_ROLE_SLAVE) {
+- __le32 interval;
+-
+- memset(&interval, 0, sizeof(interval));
+-
+- memcpy(&interval, ev->c_latency, sizeof(ev->c_latency));
+- conn->iso_qos.ucast.in.interval = le32_to_cpu(interval);
+- memcpy(&interval, ev->p_latency, sizeof(ev->p_latency));
+- conn->iso_qos.ucast.out.interval = le32_to_cpu(interval);
+- conn->iso_qos.ucast.in.latency = le16_to_cpu(ev->interval);
+- conn->iso_qos.ucast.out.latency = le16_to_cpu(ev->interval);
+- conn->iso_qos.ucast.in.sdu = le16_to_cpu(ev->c_mtu);
+- conn->iso_qos.ucast.out.sdu = le16_to_cpu(ev->p_mtu);
+- conn->iso_qos.ucast.in.phy = ev->c_phy;
+- conn->iso_qos.ucast.out.phy = ev->p_phy;
++ qos = &conn->iso_qos;
++
++ /* Convert ISO Interval (1.25 ms slots) to SDU Interval (us) */
++ qos->ucast.in.interval = le16_to_cpu(ev->interval) * 1250;
++ qos->ucast.out.interval = qos->ucast.in.interval;
++
++ switch (conn->role) {
++ case HCI_ROLE_SLAVE:
++ /* Convert Transport Latency (us) to Latency (msec) */
++ qos->ucast.in.latency =
++ DIV_ROUND_CLOSEST(get_unaligned_le24(ev->c_latency),
++ 1000);
++ qos->ucast.out.latency =
++ DIV_ROUND_CLOSEST(get_unaligned_le24(ev->p_latency),
++ 1000);
++ qos->ucast.in.sdu = le16_to_cpu(ev->c_mtu);
++ qos->ucast.out.sdu = le16_to_cpu(ev->p_mtu);
++ qos->ucast.in.phy = ev->c_phy;
++ qos->ucast.out.phy = ev->p_phy;
++ break;
++ case HCI_ROLE_MASTER:
++ /* Convert Transport Latency (us) to Latency (msec) */
++ qos->ucast.out.latency =
++ DIV_ROUND_CLOSEST(get_unaligned_le24(ev->c_latency),
++ 1000);
++ qos->ucast.in.latency =
++ DIV_ROUND_CLOSEST(get_unaligned_le24(ev->p_latency),
++ 1000);
++ qos->ucast.out.sdu = le16_to_cpu(ev->c_mtu);
++ qos->ucast.in.sdu = le16_to_cpu(ev->p_mtu);
++ qos->ucast.out.phy = ev->c_phy;
++ qos->ucast.in.phy = ev->p_phy;
++ break;
+ }
+
+ if (!ev->status) {
+--
+2.40.1
+
--- /dev/null
+From 8ea2717de893761aae2c71f4e328eead2d66b956 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Aug 2023 11:14:45 -0700
+Subject: Bluetooth: hci_sync: Avoid use-after-free in dbg for
+ hci_add_adv_monitor()
+
+From: Manish Mandlik <mmandlik@google.com>
+
+[ Upstream commit a2bcd2b63271a93a695fabbfbf459c603d956d48 ]
+
+KSAN reports use-after-free in hci_add_adv_monitor().
+
+While adding an adv monitor,
+ hci_add_adv_monitor() calls ->
+ msft_add_monitor_pattern() calls ->
+ msft_add_monitor_sync() calls ->
+ msft_le_monitor_advertisement_cb() calls in an error case ->
+ hci_free_adv_monitor() which frees the *moniter.
+
+This is referenced by bt_dev_dbg() in hci_add_adv_monitor().
+
+Fix the bt_dev_dbg() by using handle instead of monitor->handle.
+
+Fixes: b747a83690c8 ("Bluetooth: hci_sync: Refactor add Adv Monitor")
+Signed-off-by: Manish Mandlik <mmandlik@google.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
+index 04b51ffd946b7..2c845c9a26be0 100644
+--- a/net/bluetooth/hci_core.c
++++ b/net/bluetooth/hci_core.c
+@@ -1957,7 +1957,7 @@ int hci_add_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor)
+ case HCI_ADV_MONITOR_EXT_MSFT:
+ status = msft_add_monitor_pattern(hdev, monitor);
+ bt_dev_dbg(hdev, "add monitor %d msft status %d",
+- monitor->handle, status);
++ handle, status);
+ break;
+ }
+
+--
+2.40.1
+
--- /dev/null
+From 1c1d0ed87e8b5e9de5899940d34f1ba4d704a157 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Jun 2023 15:33:15 -0700
+Subject: Bluetooth: hci_sync: Don't double print name in add/remove
+ adv_monitor
+
+From: Douglas Anderson <dianders@chromium.org>
+
+[ Upstream commit 6f55eea116ba3646fb5fbb31de703f8cf79d8214 ]
+
+The hci_add_adv_monitor() hci_remove_adv_monitor() functions call
+bt_dev_dbg() to print some debug statements. The bt_dev_dbg() macro
+automatically adds in the device's name. That means that we shouldn't
+include the name in the bt_dev_dbg() calls.
+
+Suggested-by: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Stable-dep-of: a2bcd2b63271 ("Bluetooth: hci_sync: Avoid use-after-free in dbg for hci_add_adv_monitor()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_core.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
+index 793b66da22653..04b51ffd946b7 100644
+--- a/net/bluetooth/hci_core.c
++++ b/net/bluetooth/hci_core.c
+@@ -1949,14 +1949,14 @@ int hci_add_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor)
+
+ switch (hci_get_adv_monitor_offload_ext(hdev)) {
+ case HCI_ADV_MONITOR_EXT_NONE:
+- bt_dev_dbg(hdev, "%s add monitor %d status %d", hdev->name,
++ bt_dev_dbg(hdev, "add monitor %d status %d",
+ monitor->handle, status);
+ /* Message was not forwarded to controller - not an error */
+ break;
+
+ case HCI_ADV_MONITOR_EXT_MSFT:
+ status = msft_add_monitor_pattern(hdev, monitor);
+- bt_dev_dbg(hdev, "%s add monitor %d msft status %d", hdev->name,
++ bt_dev_dbg(hdev, "add monitor %d msft status %d",
+ monitor->handle, status);
+ break;
+ }
+@@ -1976,15 +1976,15 @@ static int hci_remove_adv_monitor(struct hci_dev *hdev,
+
+ switch (hci_get_adv_monitor_offload_ext(hdev)) {
+ case HCI_ADV_MONITOR_EXT_NONE: /* also goes here when powered off */
+- bt_dev_dbg(hdev, "%s remove monitor %d status %d", hdev->name,
++ bt_dev_dbg(hdev, "remove monitor %d status %d",
+ monitor->handle, status);
+ goto free_monitor;
+
+ case HCI_ADV_MONITOR_EXT_MSFT:
+ handle = monitor->handle;
+ status = msft_remove_monitor(hdev, monitor);
+- bt_dev_dbg(hdev, "%s remove monitor %d msft status %d",
+- hdev->name, handle, status);
++ bt_dev_dbg(hdev, "remove monitor %d msft status %d",
++ handle, status);
+ break;
+ }
+
+--
+2.40.1
+
--- /dev/null
+From 7aa2bba26fda35a8f41158ef6c70960001905b22 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Aug 2023 16:49:33 -0700
+Subject: Bluetooth: hci_sync: Fix UAF in hci_disconnect_all_sync
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 94d9ba9f9888b748d4abd2aa1547af56ae85f772 ]
+
+Use-after-free can occur in hci_disconnect_all_sync if a connection is
+deleted by concurrent processing of a controller event.
+
+To prevent this the code now tries to iterate over the list backwards
+to ensure the links are cleanup before its parents, also it no longer
+relies on a cursor, instead it always uses the last element since
+hci_abort_conn_sync is guaranteed to call hci_conn_del.
+
+UAF crash log:
+==================================================================
+BUG: KASAN: slab-use-after-free in hci_set_powered_sync
+(net/bluetooth/hci_sync.c:5424) [bluetooth]
+Read of size 8 at addr ffff888009d9c000 by task kworker/u9:0/124
+
+CPU: 0 PID: 124 Comm: kworker/u9:0 Tainted: G W
+6.5.0-rc1+ #10
+Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS
+1.16.2-1.fc38 04/01/2014
+Workqueue: hci0 hci_cmd_sync_work [bluetooth]
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0x5b/0x90
+ print_report+0xcf/0x670
+ ? __virt_addr_valid+0xdd/0x160
+ ? hci_set_powered_sync+0x2c9/0x4a0 [bluetooth]
+ kasan_report+0xa6/0xe0
+ ? hci_set_powered_sync+0x2c9/0x4a0 [bluetooth]
+ ? __pfx_set_powered_sync+0x10/0x10 [bluetooth]
+ hci_set_powered_sync+0x2c9/0x4a0 [bluetooth]
+ ? __pfx_hci_set_powered_sync+0x10/0x10 [bluetooth]
+ ? __pfx_lock_release+0x10/0x10
+ ? __pfx_set_powered_sync+0x10/0x10 [bluetooth]
+ hci_cmd_sync_work+0x137/0x220 [bluetooth]
+ process_one_work+0x526/0x9d0
+ ? __pfx_process_one_work+0x10/0x10
+ ? __pfx_do_raw_spin_lock+0x10/0x10
+ ? mark_held_locks+0x1a/0x90
+ worker_thread+0x92/0x630
+ ? __pfx_worker_thread+0x10/0x10
+ kthread+0x196/0x1e0
+ ? __pfx_kthread+0x10/0x10
+ ret_from_fork+0x2c/0x50
+ </TASK>
+
+Allocated by task 1782:
+ kasan_save_stack+0x33/0x60
+ kasan_set_track+0x25/0x30
+ __kasan_kmalloc+0x8f/0xa0
+ hci_conn_add+0xa5/0xa80 [bluetooth]
+ hci_bind_cis+0x881/0x9b0 [bluetooth]
+ iso_connect_cis+0x121/0x520 [bluetooth]
+ iso_sock_connect+0x3f6/0x790 [bluetooth]
+ __sys_connect+0x109/0x130
+ __x64_sys_connect+0x40/0x50
+ do_syscall_64+0x60/0x90
+ entry_SYSCALL_64_after_hwframe+0x6e/0xd8
+
+Freed by task 695:
+ kasan_save_stack+0x33/0x60
+ kasan_set_track+0x25/0x30
+ kasan_save_free_info+0x2b/0x50
+ __kasan_slab_free+0x10a/0x180
+ __kmem_cache_free+0x14d/0x2e0
+ device_release+0x5d/0xf0
+ kobject_put+0xdf/0x270
+ hci_disconn_complete_evt+0x274/0x3a0 [bluetooth]
+ hci_event_packet+0x579/0x7e0 [bluetooth]
+ hci_rx_work+0x287/0xaa0 [bluetooth]
+ process_one_work+0x526/0x9d0
+ worker_thread+0x92/0x630
+ kthread+0x196/0x1e0
+ ret_from_fork+0x2c/0x50
+==================================================================
+
+Fixes: 182ee45da083 ("Bluetooth: hci_sync: Rework hci_suspend_notifier")
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_sync.c | 55 +++++++++++++++++++++++++---------------
+ 1 file changed, 35 insertions(+), 20 deletions(-)
+
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index 60e213982635c..570909425618d 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -5339,6 +5339,7 @@ int hci_abort_conn_sync(struct hci_dev *hdev, struct hci_conn *conn, u8 reason)
+ {
+ int err = 0;
+ u16 handle = conn->handle;
++ struct hci_conn *c;
+
+ switch (conn->state) {
+ case BT_CONNECTED:
+@@ -5360,43 +5361,57 @@ int hci_abort_conn_sync(struct hci_dev *hdev, struct hci_conn *conn, u8 reason)
+ }
+ break;
+ default:
++ hci_dev_lock(hdev);
+ conn->state = BT_CLOSED;
++ hci_disconn_cfm(conn, reason);
++ hci_conn_del(conn);
++ hci_dev_unlock(hdev);
+ return 0;
+ }
+
++ hci_dev_lock(hdev);
++
++ /* Check if the connection hasn't been cleanup while waiting
++ * commands to complete.
++ */
++ c = hci_conn_hash_lookup_handle(hdev, handle);
++ if (!c || c != conn) {
++ err = 0;
++ goto unlock;
++ }
++
+ /* Cleanup hci_conn object if it cannot be cancelled as it
+ * likelly means the controller and host stack are out of sync
+ * or in case of LE it was still scanning so it can be cleanup
+ * safely.
+ */
+- if (err) {
+- struct hci_conn *c;
+-
+- /* Check if the connection hasn't been cleanup while waiting
+- * commands to complete.
+- */
+- c = hci_conn_hash_lookup_handle(hdev, handle);
+- if (!c || c != conn)
+- return 0;
+-
+- hci_dev_lock(hdev);
+- hci_conn_failed(conn, err);
+- hci_dev_unlock(hdev);
+- }
++ hci_conn_failed(conn, reason);
+
++unlock:
++ hci_dev_unlock(hdev);
+ return err;
+ }
+
+ static int hci_disconnect_all_sync(struct hci_dev *hdev, u8 reason)
+ {
+- struct hci_conn *conn, *tmp;
+- int err;
++ struct list_head *head = &hdev->conn_hash.list;
++ struct hci_conn *conn;
+
+- list_for_each_entry_safe(conn, tmp, &hdev->conn_hash.list, list) {
+- err = hci_abort_conn_sync(hdev, conn, reason);
+- if (err)
+- return err;
++ rcu_read_lock();
++ while ((conn = list_first_or_null_rcu(head, struct hci_conn, list))) {
++ /* Make sure the connection is not freed while unlocking */
++ conn = hci_conn_get(conn);
++ rcu_read_unlock();
++ /* Disregard possible errors since hci_conn_del shall have been
++ * called even in case of errors had occurred since it would
++ * then cause hci_conn_failed to be called which calls
++ * hci_conn_del internally.
++ */
++ hci_abort_conn_sync(hdev, conn, reason);
++ hci_conn_put(conn);
++ rcu_read_lock();
+ }
++ rcu_read_unlock();
+
+ return 0;
+ }
+--
+2.40.1
+
--- /dev/null
+From 2f22e064bc2404da9ed9c2b3ef344e31e0ad02ae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Aug 2023 11:04:51 -0700
+Subject: Bluetooth: hci_sync: Fix UAF on hci_abort_conn_sync
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 5af1f84ed13a416297ab9ced7537f4d5ae7f329a ]
+
+Connections may be cleanup while waiting for the commands to complete so
+this attempts to check if the connection handle remains valid in case of
+errors that would lead to call hci_conn_failed:
+
+BUG: KASAN: slab-use-after-free in hci_conn_failed+0x1f/0x160
+Read of size 8 at addr ffff888001376958 by task kworker/u3:0/52
+
+CPU: 0 PID: 52 Comm: kworker/u3:0 Not tainted
+6.5.0-rc1-00527-g2dfe76d58d3a #5615
+Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS
+1.16.2-1.fc38 04/01/2014
+Workqueue: hci0 hci_cmd_sync_work
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0x1d/0x70
+ print_report+0xce/0x620
+ ? __virt_addr_valid+0xd4/0x150
+ ? hci_conn_failed+0x1f/0x160
+ kasan_report+0xd1/0x100
+ ? hci_conn_failed+0x1f/0x160
+ hci_conn_failed+0x1f/0x160
+ hci_abort_conn_sync+0x237/0x360
+
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Stable-dep-of: 94d9ba9f9888 ("Bluetooth: hci_sync: Fix UAF in hci_disconnect_all_sync")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_sync.c | 45 ++++++++++++++++++++++++++--------------
+ 1 file changed, 29 insertions(+), 16 deletions(-)
+
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index ae5d5193d9ba7..60e213982635c 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -5337,27 +5337,20 @@ static int hci_reject_conn_sync(struct hci_dev *hdev, struct hci_conn *conn,
+
+ int hci_abort_conn_sync(struct hci_dev *hdev, struct hci_conn *conn, u8 reason)
+ {
+- int err;
++ int err = 0;
++ u16 handle = conn->handle;
+
+ switch (conn->state) {
+ case BT_CONNECTED:
+ case BT_CONFIG:
+- return hci_disconnect_sync(hdev, conn, reason);
++ err = hci_disconnect_sync(hdev, conn, reason);
++ break;
+ case BT_CONNECT:
+ err = hci_connect_cancel_sync(hdev, conn, reason);
+- /* Cleanup hci_conn object if it cannot be cancelled as it
+- * likelly means the controller and host stack are out of sync
+- * or in case of LE it was still scanning so it can be cleanup
+- * safely.
+- */
+- if (err) {
+- hci_dev_lock(hdev);
+- hci_conn_failed(conn, err);
+- hci_dev_unlock(hdev);
+- }
+- return err;
++ break;
+ case BT_CONNECT2:
+- return hci_reject_conn_sync(hdev, conn, reason);
++ err = hci_reject_conn_sync(hdev, conn, reason);
++ break;
+ case BT_OPEN:
+ /* Cleanup bises that failed to be established */
+ if (test_and_clear_bit(HCI_CONN_BIG_SYNC_FAILED, &conn->flags)) {
+@@ -5368,10 +5361,30 @@ int hci_abort_conn_sync(struct hci_dev *hdev, struct hci_conn *conn, u8 reason)
+ break;
+ default:
+ conn->state = BT_CLOSED;
+- break;
++ return 0;
+ }
+
+- return 0;
++ /* Cleanup hci_conn object if it cannot be cancelled as it
++ * likelly means the controller and host stack are out of sync
++ * or in case of LE it was still scanning so it can be cleanup
++ * safely.
++ */
++ if (err) {
++ struct hci_conn *c;
++
++ /* Check if the connection hasn't been cleanup while waiting
++ * commands to complete.
++ */
++ c = hci_conn_hash_lookup_handle(hdev, handle);
++ if (!c || c != conn)
++ return 0;
++
++ hci_dev_lock(hdev);
++ hci_conn_failed(conn, err);
++ hci_dev_unlock(hdev);
++ }
++
++ return err;
+ }
+
+ static int hci_disconnect_all_sync(struct hci_dev *hdev, u8 reason)
+--
+2.40.1
+
--- /dev/null
+From f6c910e392ad7f1dd4dc9f425ba3d186b7f74537 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 May 2023 17:21:59 +0300
+Subject: Bluetooth: ISO: Add support for connecting multiple BISes
+
+From: Iulia Tanasescu <iulia.tanasescu@nxp.com>
+
+[ Upstream commit a0bfde167b506423111ddb8cd71930497a40fc54 ]
+
+It is required for some configurations to have multiple BISes as part
+of the same BIG.
+
+Similar to the flow implemented for unicast, DEFER_SETUP will also be
+used to bind multiple BISes for the same BIG, before starting Periodic
+Advertising and creating the BIG.
+
+The user will have to open a new socket for each BIS. By setting the
+BT_DEFER_SETUP socket option and calling connect, a new connection
+will be added for the BIG and advertising handle set by the socket
+QoS parameters. Since all BISes will be bound for the same BIG and
+advertising handle, the socket QoS options and base parameters should
+match for all connections.
+
+By calling connect on a socket that does not have the BT_DEFER_SETUP
+option set, periodic advertising will be started and the BIG will
+be created, with a BIS for each previously bound connection. Since
+a BIG cannot be reconfigured with additional BISes after creation,
+no more connections can be bound for the BIG after the start periodic
+advertising and create BIG commands have been queued.
+
+The bis_cleanup function has also been updated, so that the advertising
+set and the BIG will not be terminated unless there are no more
+bound or connected BISes.
+
+The HCI_CONN_BIG_CREATED connection flag has been added to indicate
+that the BIG has been successfully created. This flag is checked at
+bis_cleanup, so that the BIG is only terminated if the
+HCI_LE_Create_BIG_Complete has been received.
+
+This implementation has been tested on hardware, using the "isotest"
+tool with an additional command line option, to specify the number of
+BISes to create as part of the desired BIG:
+
+ tools/isotest -i hci0 -s 00:00:00:00:00:00 -N 2 -G 1 -T 1
+
+The btmon log shows that a BIG containing 2 BISes has been created:
+
+< HCI Command: LE Create Broadcast Isochronous Group (0x08|0x0068) plen 31
+ Handle: 0x01
+ Advertising Handle: 0x01
+ Number of BIS: 2
+ SDU Interval: 10000 us (0x002710)
+ Maximum SDU size: 40
+ Maximum Latency: 10 ms (0x000a)
+ RTN: 0x02
+ PHY: LE 2M (0x02)
+ Packing: Sequential (0x00)
+ Framing: Unframed (0x00)
+ Encryption: 0x00
+ Broadcast Code: 00000000000000000000000000000000
+
+> HCI Event: Command Status (0x0f) plen 4
+ LE Create Broadcast Isochronous Group (0x08|0x0068) ncmd 1
+ Status: Success (0x00)
+
+> HCI Event: LE Meta Event (0x3e) plen 23
+ LE Broadcast Isochronous Group Complete (0x1b)
+ Status: Success (0x00)
+ Handle: 0x01
+ BIG Synchronization Delay: 1974 us (0x0007b6)
+ Transport Latency: 1974 us (0x0007b6)
+ PHY: LE 2M (0x02)
+ NSE: 3
+ BN: 1
+ PTO: 1
+ IRC: 3
+ Maximum PDU: 40
+ ISO Interval: 10.00 msec (0x0008)
+ Connection Handle #0: 10
+ Connection Handle #1: 11
+
+< HCI Command: LE Setup Isochronous Data Path (0x08|0x006e) plen 13
+ Handle: 10
+ Data Path Direction: Input (Host to Controller) (0x00)
+ Data Path: HCI (0x00)
+ Coding Format: Transparent (0x03)
+ Company Codec ID: Ericsson Technology Licensing (0)
+ Vendor Codec ID: 0
+ Controller Delay: 0 us (0x000000)
+ Codec Configuration Length: 0
+ Codec Configuration:
+
+> HCI Event: Command Complete (0x0e) plen 6
+ LE Setup Isochronous Data Path (0x08|0x006e) ncmd 1
+ Status: Success (0x00)
+ Handle: 10
+
+< HCI Command: LE Setup Isochronous Data Path (0x08|0x006e) plen 13
+ Handle: 11
+ Data Path Direction: Input (Host to Controller) (0x00)
+ Data Path: HCI (0x00)
+ Coding Format: Transparent (0x03)
+ Company Codec ID: Ericsson Technology Licensing (0)
+ Vendor Codec ID: 0
+ Controller Delay: 0 us (0x000000)
+ Codec Configuration Length: 0
+ Codec Configuration:
+
+> HCI Event: Command Complete (0x0e) plen 6
+ LE Setup Isochronous Data Path (0x08|0x006e) ncmd 1
+ Status: Success (0x00)
+ Handle: 11
+
+< ISO Data TX: Handle 10 flags 0x02 dlen 44
+
+< ISO Data TX: Handle 11 flags 0x02 dlen 44
+
+> HCI Event: Number of Completed Packets (0x13) plen 5
+ Num handles: 1
+ Handle: 10
+ Count: 1
+
+> HCI Event: Number of Completed Packets (0x13) plen 5
+ Num handles: 1
+ Handle: 11
+ Count: 1
+
+Signed-off-by: Iulia Tanasescu <iulia.tanasescu@nxp.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Stable-dep-of: 7f74563e6140 ("Bluetooth: ISO: do not emit new LE Create CIS if previous is pending")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/bluetooth/hci_core.h | 30 ++++++
+ net/bluetooth/hci_conn.c | 152 +++++++++++++++++++++----------
+ net/bluetooth/hci_event.c | 52 +++++++----
+ net/bluetooth/iso.c | 28 ++++--
+ 4 files changed, 189 insertions(+), 73 deletions(-)
+
+diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
+index 870b6d3c5146b..c45c40c7c3b80 100644
+--- a/include/net/bluetooth/hci_core.h
++++ b/include/net/bluetooth/hci_core.h
+@@ -976,6 +976,7 @@ enum {
+ HCI_CONN_SCANNING,
+ HCI_CONN_AUTH_FAILURE,
+ HCI_CONN_PER_ADV,
++ HCI_CONN_BIG_CREATED,
+ };
+
+ static inline bool hci_conn_ssp_enabled(struct hci_conn *conn)
+@@ -1117,6 +1118,32 @@ static inline struct hci_conn *hci_conn_hash_lookup_bis(struct hci_dev *hdev,
+ return NULL;
+ }
+
++static inline struct hci_conn *
++hci_conn_hash_lookup_per_adv_bis(struct hci_dev *hdev,
++ bdaddr_t *ba,
++ __u8 big, __u8 bis)
++{
++ struct hci_conn_hash *h = &hdev->conn_hash;
++ struct hci_conn *c;
++
++ rcu_read_lock();
++
++ list_for_each_entry_rcu(c, &h->list, list) {
++ if (bacmp(&c->dst, ba) || c->type != ISO_LINK ||
++ !test_bit(HCI_CONN_PER_ADV, &c->flags))
++ continue;
++
++ if (c->iso_qos.bcast.big == big &&
++ c->iso_qos.bcast.bis == bis) {
++ rcu_read_unlock();
++ return c;
++ }
++ }
++ rcu_read_unlock();
++
++ return NULL;
++}
++
+ static inline struct hci_conn *hci_conn_hash_lookup_handle(struct hci_dev *hdev,
+ __u16 handle)
+ {
+@@ -1353,6 +1380,9 @@ struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst,
+ __u16 setting, struct bt_codec *codec);
+ struct hci_conn *hci_bind_cis(struct hci_dev *hdev, bdaddr_t *dst,
+ __u8 dst_type, struct bt_iso_qos *qos);
++struct hci_conn *hci_bind_bis(struct hci_dev *hdev, bdaddr_t *dst,
++ struct bt_iso_qos *qos,
++ __u8 base_len, __u8 *base);
+ struct hci_conn *hci_connect_cis(struct hci_dev *hdev, bdaddr_t *dst,
+ __u8 dst_type, struct bt_iso_qos *qos);
+ struct hci_conn *hci_connect_bis(struct hci_dev *hdev, bdaddr_t *dst,
+diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
+index 31c115b225e7e..d9197916564f3 100644
+--- a/net/bluetooth/hci_conn.c
++++ b/net/bluetooth/hci_conn.c
+@@ -792,6 +792,7 @@ struct iso_list_data {
+ };
+ int count;
+ struct iso_cig_params pdu;
++ bool big_term;
+ };
+
+ static void bis_list(struct hci_conn *conn, void *data)
+@@ -828,11 +829,8 @@ static int terminate_big_sync(struct hci_dev *hdev, void *data)
+
+ hci_remove_ext_adv_instance_sync(hdev, d->bis, NULL);
+
+- /* Check if ISO connection is a BIS and terminate BIG if there are
+- * no other connections using it.
+- */
+- hci_conn_hash_list_state(hdev, find_bis, ISO_LINK, BT_CONNECTED, d);
+- if (d->count)
++ /* Only terminate BIG if it has been created */
++ if (!d->big_term)
+ return 0;
+
+ return hci_le_terminate_big_sync(hdev, d->big,
+@@ -844,19 +842,21 @@ static void terminate_big_destroy(struct hci_dev *hdev, void *data, int err)
+ kfree(data);
+ }
+
+-static int hci_le_terminate_big(struct hci_dev *hdev, u8 big, u8 bis)
++static int hci_le_terminate_big(struct hci_dev *hdev, struct hci_conn *conn)
+ {
+ struct iso_list_data *d;
+ int ret;
+
+- bt_dev_dbg(hdev, "big 0x%2.2x bis 0x%2.2x", big, bis);
++ bt_dev_dbg(hdev, "big 0x%2.2x bis 0x%2.2x", conn->iso_qos.bcast.big,
++ conn->iso_qos.bcast.bis);
+
+ d = kzalloc(sizeof(*d), GFP_KERNEL);
+ if (!d)
+ return -ENOMEM;
+
+- d->big = big;
+- d->bis = bis;
++ d->big = conn->iso_qos.bcast.big;
++ d->bis = conn->iso_qos.bcast.bis;
++ d->big_term = test_and_clear_bit(HCI_CONN_BIG_CREATED, &conn->flags);
+
+ ret = hci_cmd_sync_queue(hdev, terminate_big_sync, d,
+ terminate_big_destroy);
+@@ -916,6 +916,7 @@ static int hci_le_big_terminate(struct hci_dev *hdev, u8 big, u16 sync_handle)
+ static void bis_cleanup(struct hci_conn *conn)
+ {
+ struct hci_dev *hdev = conn->hdev;
++ struct hci_conn *bis;
+
+ bt_dev_dbg(hdev, "conn %p", conn);
+
+@@ -923,8 +924,16 @@ static void bis_cleanup(struct hci_conn *conn)
+ if (!test_and_clear_bit(HCI_CONN_PER_ADV, &conn->flags))
+ return;
+
+- hci_le_terminate_big(hdev, conn->iso_qos.bcast.big,
+- conn->iso_qos.bcast.bis);
++ /* Check if ISO connection is a BIS and terminate advertising
++ * set and BIG if there are no other connections using it.
++ */
++ bis = hci_conn_hash_lookup_bis(hdev, BDADDR_ANY,
++ conn->iso_qos.bcast.big,
++ conn->iso_qos.bcast.bis);
++ if (bis)
++ return;
++
++ hci_le_terminate_big(hdev, conn);
+ } else {
+ hci_le_big_terminate(hdev, conn->iso_qos.bcast.big,
+ conn->sync_handle);
+@@ -1495,10 +1504,10 @@ static int qos_set_bis(struct hci_dev *hdev, struct bt_iso_qos *qos)
+
+ /* This function requires the caller holds hdev->lock */
+ static struct hci_conn *hci_add_bis(struct hci_dev *hdev, bdaddr_t *dst,
+- struct bt_iso_qos *qos)
++ struct bt_iso_qos *qos, __u8 base_len,
++ __u8 *base)
+ {
+ struct hci_conn *conn;
+- struct iso_list_data data;
+ int err;
+
+ /* Let's make sure that le is enabled.*/
+@@ -1516,24 +1525,27 @@ static struct hci_conn *hci_add_bis(struct hci_dev *hdev, bdaddr_t *dst,
+ if (err)
+ return ERR_PTR(err);
+
+- data.big = qos->bcast.big;
+- data.bis = qos->bcast.bis;
+- data.count = 0;
+-
+- /* Check if there is already a matching BIG/BIS */
+- hci_conn_hash_list_state(hdev, bis_list, ISO_LINK, BT_BOUND, &data);
+- if (data.count)
++ /* Check if the LE Create BIG command has already been sent */
++ conn = hci_conn_hash_lookup_per_adv_bis(hdev, dst, qos->bcast.big,
++ qos->bcast.big);
++ if (conn)
+ return ERR_PTR(-EADDRINUSE);
+
+- conn = hci_conn_hash_lookup_bis(hdev, dst, qos->bcast.big, qos->bcast.bis);
+- if (conn)
++ /* Check BIS settings against other bound BISes, since all
++ * BISes in a BIG must have the same value for all parameters
++ */
++ conn = hci_conn_hash_lookup_bis(hdev, dst, qos->bcast.big,
++ qos->bcast.bis);
++
++ if (conn && (memcmp(qos, &conn->iso_qos, sizeof(*qos)) ||
++ base_len != conn->le_per_adv_data_len ||
++ memcmp(conn->le_per_adv_data, base, base_len)))
+ return ERR_PTR(-EADDRINUSE);
+
+ conn = hci_conn_add(hdev, ISO_LINK, dst, HCI_ROLE_MASTER);
+ if (!conn)
+ return ERR_PTR(-ENOMEM);
+
+- set_bit(HCI_CONN_PER_ADV, &conn->flags);
+ conn->state = BT_CONNECT;
+
+ hci_conn_hold(conn);
+@@ -1747,12 +1759,21 @@ static int hci_le_create_big(struct hci_conn *conn, struct bt_iso_qos *qos)
+ {
+ struct hci_dev *hdev = conn->hdev;
+ struct hci_cp_le_create_big cp;
++ struct iso_list_data data;
+
+ memset(&cp, 0, sizeof(cp));
+
++ data.big = qos->bcast.big;
++ data.bis = qos->bcast.bis;
++ data.count = 0;
++
++ /* Create a BIS for each bound connection */
++ hci_conn_hash_list_state(hdev, bis_list, ISO_LINK,
++ BT_BOUND, &data);
++
+ cp.handle = qos->bcast.big;
+ cp.adv_handle = qos->bcast.bis;
+- cp.num_bis = 0x01;
++ cp.num_bis = data.count;
+ hci_cpu_to_le24(qos->bcast.out.interval, cp.bis.sdu_interval);
+ cp.bis.sdu = cpu_to_le16(qos->bcast.out.sdu);
+ cp.bis.latency = cpu_to_le16(qos->bcast.out.latency);
+@@ -2053,16 +2074,6 @@ static void hci_iso_qos_setup(struct hci_dev *hdev, struct hci_conn *conn,
+ qos->latency = conn->le_conn_latency;
+ }
+
+-static void hci_bind_bis(struct hci_conn *conn,
+- struct bt_iso_qos *qos)
+-{
+- /* Update LINK PHYs according to QoS preference */
+- conn->le_tx_phy = qos->bcast.out.phy;
+- conn->le_tx_phy = qos->bcast.out.phy;
+- conn->iso_qos = *qos;
+- conn->state = BT_BOUND;
+-}
+-
+ static int create_big_sync(struct hci_dev *hdev, void *data)
+ {
+ struct hci_conn *conn = data;
+@@ -2185,27 +2196,80 @@ static void create_big_complete(struct hci_dev *hdev, void *data, int err)
+ }
+ }
+
+-struct hci_conn *hci_connect_bis(struct hci_dev *hdev, bdaddr_t *dst,
+- __u8 dst_type, struct bt_iso_qos *qos,
+- __u8 base_len, __u8 *base)
++struct hci_conn *hci_bind_bis(struct hci_dev *hdev, bdaddr_t *dst,
++ struct bt_iso_qos *qos,
++ __u8 base_len, __u8 *base)
+ {
+ struct hci_conn *conn;
+- int err;
++ __u8 eir[HCI_MAX_PER_AD_LENGTH];
++
++ if (base_len && base)
++ base_len = eir_append_service_data(eir, 0, 0x1851,
++ base, base_len);
+
+ /* We need hci_conn object using the BDADDR_ANY as dst */
+- conn = hci_add_bis(hdev, dst, qos);
++ conn = hci_add_bis(hdev, dst, qos, base_len, eir);
+ if (IS_ERR(conn))
+ return conn;
+
+- hci_bind_bis(conn, qos);
++ /* Update LINK PHYs according to QoS preference */
++ conn->le_tx_phy = qos->bcast.out.phy;
++ conn->le_tx_phy = qos->bcast.out.phy;
+
+ /* Add Basic Announcement into Peridic Adv Data if BASE is set */
+ if (base_len && base) {
+- base_len = eir_append_service_data(conn->le_per_adv_data, 0,
+- 0x1851, base, base_len);
++ memcpy(conn->le_per_adv_data, eir, sizeof(eir));
+ conn->le_per_adv_data_len = base_len;
+ }
+
++ hci_iso_qos_setup(hdev, conn, &qos->bcast.out,
++ conn->le_tx_phy ? conn->le_tx_phy :
++ hdev->le_tx_def_phys);
++
++ conn->iso_qos = *qos;
++ conn->state = BT_BOUND;
++
++ return conn;
++}
++
++static void bis_mark_per_adv(struct hci_conn *conn, void *data)
++{
++ struct iso_list_data *d = data;
++
++ /* Skip if not broadcast/ANY address */
++ if (bacmp(&conn->dst, BDADDR_ANY))
++ return;
++
++ if (d->big != conn->iso_qos.bcast.big ||
++ d->bis == BT_ISO_QOS_BIS_UNSET ||
++ d->bis != conn->iso_qos.bcast.bis)
++ return;
++
++ set_bit(HCI_CONN_PER_ADV, &conn->flags);
++}
++
++struct hci_conn *hci_connect_bis(struct hci_dev *hdev, bdaddr_t *dst,
++ __u8 dst_type, struct bt_iso_qos *qos,
++ __u8 base_len, __u8 *base)
++{
++ struct hci_conn *conn;
++ int err;
++ struct iso_list_data data;
++
++ conn = hci_bind_bis(hdev, dst, qos, base_len, base);
++ if (IS_ERR(conn))
++ return conn;
++
++ data.big = qos->bcast.big;
++ data.bis = qos->bcast.bis;
++
++ /* Set HCI_CONN_PER_ADV for all bound connections, to mark that
++ * the start periodic advertising and create BIG commands have
++ * been queued
++ */
++ hci_conn_hash_list_state(hdev, bis_mark_per_adv, ISO_LINK,
++ BT_BOUND, &data);
++
+ /* Queue start periodic advertising and create BIG */
+ err = hci_cmd_sync_queue(hdev, create_big_sync, conn,
+ create_big_complete);
+@@ -2214,10 +2278,6 @@ struct hci_conn *hci_connect_bis(struct hci_dev *hdev, bdaddr_t *dst,
+ return ERR_PTR(err);
+ }
+
+- hci_iso_qos_setup(hdev, conn, &qos->bcast.out,
+- conn->le_tx_phy ? conn->le_tx_phy :
+- hdev->le_tx_def_phys);
+-
+ return conn;
+ }
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index b2b38d5014e7f..ac0fcdeaba0c8 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -6935,6 +6935,7 @@ static void hci_le_create_big_complete_evt(struct hci_dev *hdev, void *data,
+ {
+ struct hci_evt_le_create_big_complete *ev = data;
+ struct hci_conn *conn;
++ __u8 bis_idx = 0;
+
+ BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
+
+@@ -6943,33 +6944,44 @@ static void hci_le_create_big_complete_evt(struct hci_dev *hdev, void *data,
+ return;
+
+ hci_dev_lock(hdev);
++ rcu_read_lock();
+
+- conn = hci_conn_hash_lookup_big(hdev, ev->handle);
+- if (!conn)
+- goto unlock;
++ /* Connect all BISes that are bound to the BIG */
++ list_for_each_entry_rcu(conn, &hdev->conn_hash.list, list) {
++ if (bacmp(&conn->dst, BDADDR_ANY) ||
++ conn->type != ISO_LINK ||
++ conn->iso_qos.bcast.big != ev->handle)
++ continue;
+
+- if (conn->type != ISO_LINK) {
+- bt_dev_err(hdev,
+- "Invalid connection link type handle 0x%2.2x",
+- ev->handle);
+- goto unlock;
+- }
++ conn->handle = __le16_to_cpu(ev->bis_handle[bis_idx++]);
+
+- if (ev->num_bis)
+- conn->handle = __le16_to_cpu(ev->bis_handle[0]);
++ if (!ev->status) {
++ conn->state = BT_CONNECTED;
++ set_bit(HCI_CONN_BIG_CREATED, &conn->flags);
++ rcu_read_unlock();
++ hci_debugfs_create_conn(conn);
++ hci_conn_add_sysfs(conn);
++ hci_iso_setup_path(conn);
++ rcu_read_lock();
++ continue;
++ }
+
+- if (!ev->status) {
+- conn->state = BT_CONNECTED;
+- hci_debugfs_create_conn(conn);
+- hci_conn_add_sysfs(conn);
+- hci_iso_setup_path(conn);
+- goto unlock;
++ hci_connect_cfm(conn, ev->status);
++ rcu_read_unlock();
++ hci_conn_del(conn);
++ rcu_read_lock();
+ }
+
+- hci_connect_cfm(conn, ev->status);
+- hci_conn_del(conn);
++ if (!ev->status && !bis_idx)
++ /* If no BISes have been connected for the BIG,
++ * terminate. This is in case all bound connections
++ * have been closed before the BIG creation
++ * has completed.
++ */
++ hci_le_terminate_big_sync(hdev, ev->handle,
++ HCI_ERROR_LOCAL_HOST_TERM);
+
+-unlock:
++ rcu_read_unlock();
+ hci_dev_unlock(hdev);
+ }
+
+diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
+index 94d5bc104fede..8221f9ecb17f9 100644
+--- a/net/bluetooth/iso.c
++++ b/net/bluetooth/iso.c
+@@ -287,13 +287,24 @@ static int iso_connect_bis(struct sock *sk)
+ goto unlock;
+ }
+
+- hcon = hci_connect_bis(hdev, &iso_pi(sk)->dst,
+- le_addr_type(iso_pi(sk)->dst_type),
+- &iso_pi(sk)->qos, iso_pi(sk)->base_len,
+- iso_pi(sk)->base);
+- if (IS_ERR(hcon)) {
+- err = PTR_ERR(hcon);
+- goto unlock;
++ /* Just bind if DEFER_SETUP has been set */
++ if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
++ hcon = hci_bind_bis(hdev, &iso_pi(sk)->dst,
++ &iso_pi(sk)->qos, iso_pi(sk)->base_len,
++ iso_pi(sk)->base);
++ if (IS_ERR(hcon)) {
++ err = PTR_ERR(hcon);
++ goto unlock;
++ }
++ } else {
++ hcon = hci_connect_bis(hdev, &iso_pi(sk)->dst,
++ le_addr_type(iso_pi(sk)->dst_type),
++ &iso_pi(sk)->qos, iso_pi(sk)->base_len,
++ iso_pi(sk)->base);
++ if (IS_ERR(hcon)) {
++ err = PTR_ERR(hcon);
++ goto unlock;
++ }
+ }
+
+ conn = iso_conn_add(hcon);
+@@ -317,6 +328,9 @@ static int iso_connect_bis(struct sock *sk)
+ if (hcon->state == BT_CONNECTED) {
+ iso_sock_clear_timer(sk);
+ sk->sk_state = BT_CONNECTED;
++ } else if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
++ iso_sock_clear_timer(sk);
++ sk->sk_state = BT_CONNECT;
+ } else {
+ sk->sk_state = BT_CONNECT;
+ iso_sock_set_timer(sk, sk->sk_sndtimeo);
+--
+2.40.1
+
--- /dev/null
+From 1575cd0b8526d9d682725d71c77c92e853b3ecc5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Jun 2023 09:34:46 +0300
+Subject: Bluetooth: ISO: do not emit new LE Create CIS if previous is pending
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit 7f74563e6140e42b4ffae62adbef7a65967a3f98 ]
+
+LE Create CIS command shall not be sent before all CIS Established
+events from its previous invocation have been processed. Currently it is
+sent via hci_sync but that only waits for the first event, but there can
+be multiple.
+
+Make it wait for all events, and simplify the CIS creation as follows:
+
+Add new flag HCI_CONN_CREATE_CIS, which is set if Create CIS has been
+sent for the connection but it is not yet completed.
+
+Make BT_CONNECT state to mean the connection wants Create CIS.
+
+On events after which new Create CIS may need to be sent, send it if
+possible and some connections need it. These events are:
+hci_connect_cis, iso_connect_cfm, hci_cs_le_create_cis,
+hci_le_cis_estabilished_evt.
+
+The Create CIS status/completion events shall queue new Create CIS only
+if at least one of the connections transitions away from BT_CONNECT, so
+that we don't loop if controller is sending bogus events.
+
+This fixes sending multiple CIS Create for the same CIS in the
+"ISO AC 6(i) - Success" BlueZ test case:
+
+< HCI Command: LE Create Co.. (0x08|0x0064) plen 9 #129 [hci0]
+ Number of CIS: 2
+ CIS Handle: 257
+ ACL Handle: 42
+ CIS Handle: 258
+ ACL Handle: 42
+> HCI Event: Command Status (0x0f) plen 4 #130 [hci0]
+ LE Create Connected Isochronous Stream (0x08|0x0064) ncmd 1
+ Status: Success (0x00)
+> HCI Event: LE Meta Event (0x3e) plen 29 #131 [hci0]
+ LE Connected Isochronous Stream Established (0x19)
+ Status: Success (0x00)
+ Connection Handle: 257
+ ...
+< HCI Command: LE Setup Is.. (0x08|0x006e) plen 13 #132 [hci0]
+ ...
+> HCI Event: Command Complete (0x0e) plen 6 #133 [hci0]
+ LE Setup Isochronous Data Path (0x08|0x006e) ncmd 1
+ ...
+< HCI Command: LE Create Co.. (0x08|0x0064) plen 5 #134 [hci0]
+ Number of CIS: 1
+ CIS Handle: 258
+ ACL Handle: 42
+> HCI Event: Command Status (0x0f) plen 4 #135 [hci0]
+ LE Create Connected Isochronous Stream (0x08|0x0064) ncmd 1
+ Status: ACL Connection Already Exists (0x0b)
+> HCI Event: LE Meta Event (0x3e) plen 29 #136 [hci0]
+ LE Connected Isochronous Stream Established (0x19)
+ Status: Success (0x00)
+ Connection Handle: 258
+ ...
+
+Fixes: c09b80be6ffc ("Bluetooth: hci_conn: Fix not waiting for HCI_EVT_LE_CIS_ESTABLISHED")
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/bluetooth/hci_core.h | 4 +-
+ include/net/bluetooth/hci_sync.h | 2 +-
+ net/bluetooth/hci_conn.c | 74 +++++++++++---------------
+ net/bluetooth/hci_event.c | 25 +++++++--
+ net/bluetooth/hci_sync.c | 90 ++++++++++++++++++++++----------
+ net/bluetooth/iso.c | 2 +-
+ 6 files changed, 119 insertions(+), 78 deletions(-)
+
+diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
+index c45c40c7c3b80..e30e091ef728e 100644
+--- a/include/net/bluetooth/hci_core.h
++++ b/include/net/bluetooth/hci_core.h
+@@ -977,6 +977,7 @@ enum {
+ HCI_CONN_AUTH_FAILURE,
+ HCI_CONN_PER_ADV,
+ HCI_CONN_BIG_CREATED,
++ HCI_CONN_CREATE_CIS,
+ };
+
+ static inline bool hci_conn_ssp_enabled(struct hci_conn *conn)
+@@ -1353,7 +1354,8 @@ int hci_disconnect(struct hci_conn *conn, __u8 reason);
+ bool hci_setup_sync(struct hci_conn *conn, __u16 handle);
+ void hci_sco_setup(struct hci_conn *conn, __u8 status);
+ bool hci_iso_setup_path(struct hci_conn *conn);
+-int hci_le_create_cis(struct hci_conn *conn);
++int hci_le_create_cis_pending(struct hci_dev *hdev);
++int hci_conn_check_create_cis(struct hci_conn *conn);
+
+ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst,
+ u8 role);
+diff --git a/include/net/bluetooth/hci_sync.h b/include/net/bluetooth/hci_sync.h
+index 2495be4d8b828..b516a0f4a55b8 100644
+--- a/include/net/bluetooth/hci_sync.h
++++ b/include/net/bluetooth/hci_sync.h
+@@ -124,7 +124,7 @@ int hci_abort_conn_sync(struct hci_dev *hdev, struct hci_conn *conn, u8 reason);
+
+ int hci_le_create_conn_sync(struct hci_dev *hdev, struct hci_conn *conn);
+
+-int hci_le_create_cis_sync(struct hci_dev *hdev, struct hci_conn *conn);
++int hci_le_create_cis_sync(struct hci_dev *hdev);
+
+ int hci_le_remove_cig_sync(struct hci_dev *hdev, u8 handle);
+
+diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
+index d9197916564f3..d481a1d2c0a28 100644
+--- a/net/bluetooth/hci_conn.c
++++ b/net/bluetooth/hci_conn.c
+@@ -1992,59 +1992,47 @@ bool hci_iso_setup_path(struct hci_conn *conn)
+ return true;
+ }
+
+-static int hci_create_cis_sync(struct hci_dev *hdev, void *data)
++int hci_conn_check_create_cis(struct hci_conn *conn)
+ {
+- return hci_le_create_cis_sync(hdev, data);
+-}
++ if (conn->type != ISO_LINK || !bacmp(&conn->dst, BDADDR_ANY))
++ return -EINVAL;
+
+-int hci_le_create_cis(struct hci_conn *conn)
+-{
+- struct hci_conn *cis;
+- struct hci_link *link, *t;
+- struct hci_dev *hdev = conn->hdev;
+- int err;
++ if (!conn->parent || conn->parent->state != BT_CONNECTED ||
++ conn->state != BT_CONNECT || conn->handle == HCI_CONN_HANDLE_UNSET)
++ return 1;
+
+- bt_dev_dbg(hdev, "hcon %p", conn);
++ return 0;
++}
+
+- switch (conn->type) {
+- case LE_LINK:
+- if (conn->state != BT_CONNECTED || list_empty(&conn->link_list))
+- return -EINVAL;
++static int hci_create_cis_sync(struct hci_dev *hdev, void *data)
++{
++ return hci_le_create_cis_sync(hdev);
++}
+
+- cis = NULL;
++int hci_le_create_cis_pending(struct hci_dev *hdev)
++{
++ struct hci_conn *conn;
++ bool pending = false;
+
+- /* hci_conn_link uses list_add_tail_rcu so the list is in
+- * the same order as the connections are requested.
+- */
+- list_for_each_entry_safe(link, t, &conn->link_list, list) {
+- if (link->conn->state == BT_BOUND) {
+- err = hci_le_create_cis(link->conn);
+- if (err)
+- return err;
++ rcu_read_lock();
+
+- cis = link->conn;
+- }
++ list_for_each_entry_rcu(conn, &hdev->conn_hash.list, list) {
++ if (test_bit(HCI_CONN_CREATE_CIS, &conn->flags)) {
++ rcu_read_unlock();
++ return -EBUSY;
+ }
+
+- return cis ? 0 : -EINVAL;
+- case ISO_LINK:
+- cis = conn;
+- break;
+- default:
+- return -EINVAL;
++ if (!hci_conn_check_create_cis(conn))
++ pending = true;
+ }
+
+- if (cis->state == BT_CONNECT)
++ rcu_read_unlock();
++
++ if (!pending)
+ return 0;
+
+ /* Queue Create CIS */
+- err = hci_cmd_sync_queue(hdev, hci_create_cis_sync, cis, NULL);
+- if (err)
+- return err;
+-
+- cis->state = BT_CONNECT;
+-
+- return 0;
++ return hci_cmd_sync_queue(hdev, hci_create_cis_sync, NULL, NULL);
+ }
+
+ static void hci_iso_qos_setup(struct hci_dev *hdev, struct hci_conn *conn,
+@@ -2319,11 +2307,9 @@ struct hci_conn *hci_connect_cis(struct hci_dev *hdev, bdaddr_t *dst,
+ return ERR_PTR(-ENOLINK);
+ }
+
+- /* If LE is already connected and CIS handle is already set proceed to
+- * Create CIS immediately.
+- */
+- if (le->state == BT_CONNECTED && cis->handle != HCI_CONN_HANDLE_UNSET)
+- hci_le_create_cis(cis);
++ cis->state = BT_CONNECT;
++
++ hci_le_create_cis_pending(hdev);
+
+ return cis;
+ }
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index ac0fcdeaba0c8..e3675d8a23e44 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -3810,6 +3810,7 @@ static u8 hci_cc_le_set_cig_params(struct hci_dev *hdev, void *data,
+ struct hci_cp_le_set_cig_params *cp;
+ struct hci_conn *conn;
+ u8 status = rp->status;
++ bool pending = false;
+ int i;
+
+ bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
+@@ -3851,13 +3852,15 @@ static u8 hci_cc_le_set_cig_params(struct hci_dev *hdev, void *data,
+
+ bt_dev_dbg(hdev, "%p handle 0x%4.4x parent %p", conn,
+ conn->handle, conn->parent);
+-
+- /* Create CIS if LE is already connected */
+- if (conn->parent && conn->parent->state == BT_CONNECTED)
+- hci_le_create_cis(conn);
++
++ if (conn->state == BT_CONNECT)
++ pending = true;
+ }
+
+ unlock:
++ if (pending)
++ hci_le_create_cis_pending(hdev);
++
+ hci_dev_unlock(hdev);
+
+ return rp->status;
+@@ -4223,6 +4226,7 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, void *data,
+ static void hci_cs_le_create_cis(struct hci_dev *hdev, u8 status)
+ {
+ struct hci_cp_le_create_cis *cp;
++ bool pending = false;
+ int i;
+
+ bt_dev_dbg(hdev, "status 0x%2.2x", status);
+@@ -4245,12 +4249,18 @@ static void hci_cs_le_create_cis(struct hci_dev *hdev, u8 status)
+
+ conn = hci_conn_hash_lookup_handle(hdev, handle);
+ if (conn) {
++ if (test_and_clear_bit(HCI_CONN_CREATE_CIS,
++ &conn->flags))
++ pending = true;
+ conn->state = BT_CLOSED;
+ hci_connect_cfm(conn, status);
+ hci_conn_del(conn);
+ }
+ }
+
++ if (pending)
++ hci_le_create_cis_pending(hdev);
++
+ hci_dev_unlock(hdev);
+ }
+
+@@ -6789,6 +6799,7 @@ static void hci_le_cis_estabilished_evt(struct hci_dev *hdev, void *data,
+ struct hci_evt_le_cis_established *ev = data;
+ struct hci_conn *conn;
+ struct bt_iso_qos *qos;
++ bool pending = false;
+ u16 handle = __le16_to_cpu(ev->handle);
+
+ bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
+@@ -6812,6 +6823,8 @@ static void hci_le_cis_estabilished_evt(struct hci_dev *hdev, void *data,
+
+ qos = &conn->iso_qos;
+
++ pending = test_and_clear_bit(HCI_CONN_CREATE_CIS, &conn->flags);
++
+ /* Convert ISO Interval (1.25 ms slots) to SDU Interval (us) */
+ qos->ucast.in.interval = le16_to_cpu(ev->interval) * 1250;
+ qos->ucast.out.interval = qos->ucast.in.interval;
+@@ -6853,10 +6866,14 @@ static void hci_le_cis_estabilished_evt(struct hci_dev *hdev, void *data,
+ goto unlock;
+ }
+
++ conn->state = BT_CLOSED;
+ hci_connect_cfm(conn, ev->status);
+ hci_conn_del(conn);
+
+ unlock:
++ if (pending)
++ hci_le_create_cis_pending(hdev);
++
+ hci_dev_unlock(hdev);
+ }
+
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index 1bcb54272dc67..50f34c812cccd 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -6262,56 +6262,92 @@ int hci_le_create_conn_sync(struct hci_dev *hdev, struct hci_conn *conn)
+ return err;
+ }
+
+-int hci_le_create_cis_sync(struct hci_dev *hdev, struct hci_conn *conn)
++int hci_le_create_cis_sync(struct hci_dev *hdev)
+ {
+ struct {
+ struct hci_cp_le_create_cis cp;
+ struct hci_cis cis[0x1f];
+ } cmd;
+- u8 cig;
+- struct hci_conn *hcon = conn;
++ struct hci_conn *conn;
++ u8 cig = BT_ISO_QOS_CIG_UNSET;
++
++ /* The spec allows only one pending LE Create CIS command at a time. If
++ * the command is pending now, don't do anything. We check for pending
++ * connections after each CIS Established event.
++ *
++ * BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E
++ * page 2566:
++ *
++ * If the Host issues this command before all the
++ * HCI_LE_CIS_Established events from the previous use of the
++ * command have been generated, the Controller shall return the
++ * error code Command Disallowed (0x0C).
++ *
++ * BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E
++ * page 2567:
++ *
++ * When the Controller receives the HCI_LE_Create_CIS command, the
++ * Controller sends the HCI_Command_Status event to the Host. An
++ * HCI_LE_CIS_Established event will be generated for each CIS when it
++ * is established or if it is disconnected or considered lost before
++ * being established; until all the events are generated, the command
++ * remains pending.
++ */
+
+ memset(&cmd, 0, sizeof(cmd));
+- cmd.cis[0].acl_handle = cpu_to_le16(conn->parent->handle);
+- cmd.cis[0].cis_handle = cpu_to_le16(conn->handle);
+- cmd.cp.num_cis++;
+- cig = conn->iso_qos.ucast.cig;
+
+ hci_dev_lock(hdev);
+
+ rcu_read_lock();
+
++ /* Wait until previous Create CIS has completed */
+ list_for_each_entry_rcu(conn, &hdev->conn_hash.list, list) {
+- struct hci_cis *cis = &cmd.cis[cmd.cp.num_cis];
++ if (test_bit(HCI_CONN_CREATE_CIS, &conn->flags))
++ goto done;
++ }
+
+- if (conn == hcon || conn->type != ISO_LINK ||
+- conn->state == BT_CONNECTED ||
+- conn->iso_qos.ucast.cig != cig)
++ /* Find CIG with all CIS ready */
++ list_for_each_entry_rcu(conn, &hdev->conn_hash.list, list) {
++ struct hci_conn *link;
++
++ if (hci_conn_check_create_cis(conn))
+ continue;
+
+- /* Check if all CIS(s) belonging to a CIG are ready */
+- if (!conn->parent || conn->parent->state != BT_CONNECTED ||
+- conn->state != BT_CONNECT) {
+- cmd.cp.num_cis = 0;
+- break;
++ cig = conn->iso_qos.ucast.cig;
++
++ list_for_each_entry_rcu(link, &hdev->conn_hash.list, list) {
++ if (hci_conn_check_create_cis(link) > 0 &&
++ link->iso_qos.ucast.cig == cig &&
++ link->state != BT_CONNECTED) {
++ cig = BT_ISO_QOS_CIG_UNSET;
++ break;
++ }
+ }
+
+- /* Group all CIS with state BT_CONNECT since the spec don't
+- * allow to send them individually:
+- *
+- * BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E
+- * page 2566:
+- *
+- * If the Host issues this command before all the
+- * HCI_LE_CIS_Established events from the previous use of the
+- * command have been generated, the Controller shall return the
+- * error code Command Disallowed (0x0C).
+- */
++ if (cig != BT_ISO_QOS_CIG_UNSET)
++ break;
++ }
++
++ if (cig == BT_ISO_QOS_CIG_UNSET)
++ goto done;
++
++ list_for_each_entry_rcu(conn, &hdev->conn_hash.list, list) {
++ struct hci_cis *cis = &cmd.cis[cmd.cp.num_cis];
++
++ if (hci_conn_check_create_cis(conn) ||
++ conn->iso_qos.ucast.cig != cig)
++ continue;
++
++ set_bit(HCI_CONN_CREATE_CIS, &conn->flags);
+ cis->acl_handle = cpu_to_le16(conn->parent->handle);
+ cis->cis_handle = cpu_to_le16(conn->handle);
+ cmd.cp.num_cis++;
++
++ if (cmd.cp.num_cis >= ARRAY_SIZE(cmd.cis))
++ break;
+ }
+
++done:
+ rcu_read_unlock();
+
+ hci_dev_unlock(hdev);
+diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
+index 8221f9ecb17f9..dfa45dfb69480 100644
+--- a/net/bluetooth/iso.c
++++ b/net/bluetooth/iso.c
+@@ -1690,7 +1690,7 @@ static void iso_connect_cfm(struct hci_conn *hcon, __u8 status)
+ }
+
+ /* Create CIS if pending */
+- hci_le_create_cis(hcon);
++ hci_le_create_cis_pending(hcon->hdev);
+ return;
+ }
+
+--
+2.40.1
+
--- /dev/null
+From bd5b00318380ed6e246b8e81e7043e1c2411a7f7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Aug 2023 14:41:46 -0700
+Subject: Bluetooth: ISO: Fix not checking for valid CIG/CIS IDs
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit b7f923b1ef6a2e76013089d30c9552257056360a ]
+
+Valid range of CIG/CIS are 0x00 to 0xEF, so this checks they are
+properly checked before attempting to use HCI_OP_LE_SET_CIG_PARAMS.
+
+Fixes: ccf74f2390d6 ("Bluetooth: Add BTPROTO_ISO socket type")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/iso.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
+index dfa45dfb69480..cd07836850758 100644
+--- a/net/bluetooth/iso.c
++++ b/net/bluetooth/iso.c
+@@ -1216,6 +1216,12 @@ static bool check_io_qos(struct bt_iso_io_qos *qos)
+
+ static bool check_ucast_qos(struct bt_iso_qos *qos)
+ {
++ if (qos->ucast.cig > 0xef && qos->ucast.cig != BT_ISO_QOS_CIG_UNSET)
++ return false;
++
++ if (qos->ucast.cis > 0xef && qos->ucast.cis != BT_ISO_QOS_CIS_UNSET)
++ return false;
++
+ if (qos->ucast.sca > 0x07)
+ return false;
+
+--
+2.40.1
+
--- /dev/null
+From 8edae15ba0aef5eec3eeeb5c3662e26431b937da Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Jul 2023 10:02:38 +0300
+Subject: Bluetooth: ISO: Notify user space about failed bis connections
+
+From: Iulia Tanasescu <iulia.tanasescu@nxp.com>
+
+[ Upstream commit f777d88278170410b06a1f6633f3b9375a4ddd6b ]
+
+Some use cases require the user to be informed if BIG synchronization
+fails. This commit makes it so that even if the BIG sync established
+event arrives with error status, a new hconn is added for each BIS,
+and the iso layer is notified about the failed connections.
+
+Unsuccesful bis connections will be marked using the
+HCI_CONN_BIG_SYNC_FAILED flag. From the iso layer, the POLLERR event
+is triggered on the newly allocated bis sockets, before adding them
+to the accept list of the parent socket.
+
+From user space, a new fd for each failed bis connection will be
+obtained by calling accept. The user should check for the POLLERR
+event on the new socket, to determine if the connection was successful
+or not.
+
+The HCI_CONN_BIG_SYNC flag has been added to mark whether the BIG sync
+has been successfully established. This flag is checked at bis cleanup,
+so the HCI LE BIG Terminate Sync command is only issued if needed.
+
+The BT_SK_BIG_SYNC flag indicates if BIG create sync has been called
+for a listening socket, to avoid issuing the command everytime a BIGInfo
+advertising report is received.
+
+Signed-off-by: Iulia Tanasescu <iulia.tanasescu@nxp.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Stable-dep-of: 94d9ba9f9888 ("Bluetooth: hci_sync: Fix UAF in hci_disconnect_all_sync")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/bluetooth/hci_core.h | 25 ++++++++++++++++++++
+ net/bluetooth/hci_conn.c | 37 +++++++++++------------------
+ net/bluetooth/hci_event.c | 21 +++++++++++++----
+ net/bluetooth/hci_sync.c | 8 +++++++
+ net/bluetooth/iso.c | 40 +++++++++++++++++++++++---------
+ 5 files changed, 93 insertions(+), 38 deletions(-)
+
+diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
+index e4c1e503415b6..a4b3a95e531a4 100644
+--- a/include/net/bluetooth/hci_core.h
++++ b/include/net/bluetooth/hci_core.h
+@@ -978,6 +978,8 @@ enum {
+ HCI_CONN_PER_ADV,
+ HCI_CONN_BIG_CREATED,
+ HCI_CONN_CREATE_CIS,
++ HCI_CONN_BIG_SYNC,
++ HCI_CONN_BIG_SYNC_FAILED,
+ };
+
+ static inline bool hci_conn_ssp_enabled(struct hci_conn *conn)
+@@ -1289,6 +1291,29 @@ static inline struct hci_conn *hci_conn_hash_lookup_big(struct hci_dev *hdev,
+ return NULL;
+ }
+
++static inline struct hci_conn *hci_conn_hash_lookup_big_any_dst(struct hci_dev *hdev,
++ __u8 handle)
++{
++ struct hci_conn_hash *h = &hdev->conn_hash;
++ struct hci_conn *c;
++
++ rcu_read_lock();
++
++ list_for_each_entry_rcu(c, &h->list, list) {
++ if (c->type != ISO_LINK)
++ continue;
++
++ if (handle == c->iso_qos.bcast.big) {
++ rcu_read_unlock();
++ return c;
++ }
++ }
++
++ rcu_read_unlock();
++
++ return NULL;
++}
++
+ static inline struct hci_conn *hci_conn_hash_lookup_state(struct hci_dev *hdev,
+ __u8 type, __u16 state)
+ {
+diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
+index f05b99437e280..4f31340c2c932 100644
+--- a/net/bluetooth/hci_conn.c
++++ b/net/bluetooth/hci_conn.c
+@@ -734,6 +734,7 @@ struct iso_list_data {
+ };
+ int count;
+ bool big_term;
++ bool big_sync_term;
+ };
+
+ static void bis_list(struct hci_conn *conn, void *data)
+@@ -751,17 +752,6 @@ static void bis_list(struct hci_conn *conn, void *data)
+ d->count++;
+ }
+
+-static void find_bis(struct hci_conn *conn, void *data)
+-{
+- struct iso_list_data *d = data;
+-
+- /* Ignore unicast */
+- if (bacmp(&conn->dst, BDADDR_ANY))
+- return;
+-
+- d->count++;
+-}
+-
+ static int terminate_big_sync(struct hci_dev *hdev, void *data)
+ {
+ struct iso_list_data *d = data;
+@@ -814,31 +804,26 @@ static int big_terminate_sync(struct hci_dev *hdev, void *data)
+ bt_dev_dbg(hdev, "big 0x%2.2x sync_handle 0x%4.4x", d->big,
+ d->sync_handle);
+
+- /* Check if ISO connection is a BIS and terminate BIG if there are
+- * no other connections using it.
+- */
+- hci_conn_hash_list_state(hdev, find_bis, ISO_LINK, BT_CONNECTED, d);
+- if (d->count)
+- return 0;
+-
+- hci_le_big_terminate_sync(hdev, d->big);
++ if (d->big_sync_term)
++ hci_le_big_terminate_sync(hdev, d->big);
+
+ return hci_le_pa_terminate_sync(hdev, d->sync_handle);
+ }
+
+-static int hci_le_big_terminate(struct hci_dev *hdev, u8 big, u16 sync_handle)
++static int hci_le_big_terminate(struct hci_dev *hdev, u8 big, struct hci_conn *conn)
+ {
+ struct iso_list_data *d;
+ int ret;
+
+- bt_dev_dbg(hdev, "big 0x%2.2x sync_handle 0x%4.4x", big, sync_handle);
++ bt_dev_dbg(hdev, "big 0x%2.2x sync_handle 0x%4.4x", big, conn->sync_handle);
+
+ d = kzalloc(sizeof(*d), GFP_KERNEL);
+ if (!d)
+ return -ENOMEM;
+
+ d->big = big;
+- d->sync_handle = sync_handle;
++ d->sync_handle = conn->sync_handle;
++ d->big_sync_term = test_and_clear_bit(HCI_CONN_BIG_SYNC, &conn->flags);
+
+ ret = hci_cmd_sync_queue(hdev, big_terminate_sync, d,
+ terminate_big_destroy);
+@@ -876,8 +861,14 @@ static void bis_cleanup(struct hci_conn *conn)
+
+ hci_le_terminate_big(hdev, conn);
+ } else {
++ bis = hci_conn_hash_lookup_big_any_dst(hdev,
++ conn->iso_qos.bcast.big);
++
++ if (bis)
++ return;
++
+ hci_le_big_terminate(hdev, conn->iso_qos.bcast.big,
+- conn->sync_handle);
++ conn);
+ }
+ }
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 866d2cd43bf78..5f4af2cfd21d8 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -7034,9 +7034,6 @@ static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data,
+ flex_array_size(ev, bis, ev->num_bis)))
+ return;
+
+- if (ev->status)
+- return;
+-
+ hci_dev_lock(hdev);
+
+ for (i = 0; i < ev->num_bis; i++) {
+@@ -7060,9 +7057,25 @@ static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data,
+ bis->iso_qos.bcast.in.latency = le16_to_cpu(ev->interval) * 125 / 100;
+ bis->iso_qos.bcast.in.sdu = le16_to_cpu(ev->max_pdu);
+
+- hci_iso_setup_path(bis);
++ if (!ev->status) {
++ set_bit(HCI_CONN_BIG_SYNC, &bis->flags);
++ hci_iso_setup_path(bis);
++ }
+ }
+
++ /* In case BIG sync failed, notify each failed connection to
++ * the user after all hci connections have been added
++ */
++ if (ev->status)
++ for (i = 0; i < ev->num_bis; i++) {
++ u16 handle = le16_to_cpu(ev->bis[i]);
++
++ bis = hci_conn_hash_lookup_handle(hdev, handle);
++
++ set_bit(HCI_CONN_BIG_SYNC_FAILED, &bis->flags);
++ hci_connect_cfm(bis, ev->status);
++ }
++
+ hci_dev_unlock(hdev);
+ }
+
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index e3b7f21046dbc..ae5d5193d9ba7 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -5358,6 +5358,14 @@ int hci_abort_conn_sync(struct hci_dev *hdev, struct hci_conn *conn, u8 reason)
+ return err;
+ case BT_CONNECT2:
+ return hci_reject_conn_sync(hdev, conn, reason);
++ case BT_OPEN:
++ /* Cleanup bises that failed to be established */
++ if (test_and_clear_bit(HCI_CONN_BIG_SYNC_FAILED, &conn->flags)) {
++ hci_dev_lock(hdev);
++ hci_conn_failed(conn, reason);
++ hci_dev_unlock(hdev);
++ }
++ break;
+ default:
+ conn->state = BT_CLOSED;
+ break;
+diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
+index 00e93ae6373da..4f2443e1aab3c 100644
+--- a/net/bluetooth/iso.c
++++ b/net/bluetooth/iso.c
+@@ -48,6 +48,11 @@ static void iso_sock_kill(struct sock *sk);
+ #define EIR_SERVICE_DATA_LENGTH 4
+ #define BASE_MAX_LENGTH (HCI_MAX_PER_AD_LENGTH - EIR_SERVICE_DATA_LENGTH)
+
++/* iso_pinfo flags values */
++enum {
++ BT_SK_BIG_SYNC,
++};
++
+ struct iso_pinfo {
+ struct bt_sock bt;
+ bdaddr_t src;
+@@ -58,7 +63,7 @@ struct iso_pinfo {
+ __u8 bc_num_bis;
+ __u8 bc_bis[ISO_MAX_NUM_BIS];
+ __u16 sync_handle;
+- __u32 flags;
++ unsigned long flags;
+ struct bt_iso_qos qos;
+ bool qos_user_set;
+ __u8 base_len;
+@@ -1583,6 +1588,12 @@ static void iso_conn_ready(struct iso_conn *conn)
+ hci_conn_hold(hcon);
+ iso_chan_add(conn, sk, parent);
+
++ if (ev && ((struct hci_evt_le_big_sync_estabilished *)ev)->status) {
++ /* Trigger error signal on child socket */
++ sk->sk_err = ECONNREFUSED;
++ sk->sk_error_report(sk);
++ }
++
+ if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags))
+ sk->sk_state = BT_CONNECT2;
+ else
+@@ -1651,15 +1662,17 @@ int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)
+ if (ev2->num_bis < iso_pi(sk)->bc_num_bis)
+ iso_pi(sk)->bc_num_bis = ev2->num_bis;
+
+- err = hci_le_big_create_sync(hdev,
+- &iso_pi(sk)->qos,
+- iso_pi(sk)->sync_handle,
+- iso_pi(sk)->bc_num_bis,
+- iso_pi(sk)->bc_bis);
+- if (err) {
+- bt_dev_err(hdev, "hci_le_big_create_sync: %d",
+- err);
+- sk = NULL;
++ if (!test_and_set_bit(BT_SK_BIG_SYNC, &iso_pi(sk)->flags)) {
++ err = hci_le_big_create_sync(hdev,
++ &iso_pi(sk)->qos,
++ iso_pi(sk)->sync_handle,
++ iso_pi(sk)->bc_num_bis,
++ iso_pi(sk)->bc_bis);
++ if (err) {
++ bt_dev_err(hdev, "hci_le_big_create_sync: %d",
++ err);
++ sk = NULL;
++ }
+ }
+ }
+ } else {
+@@ -1702,7 +1715,12 @@ static void iso_connect_cfm(struct hci_conn *hcon, __u8 status)
+
+ BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
+
+- if (!status) {
++ /* Similar to the success case, if HCI_CONN_BIG_SYNC_FAILED is set,
++ * queue the failed bis connection into the accept queue of the
++ * listening socket and wake up userspace, to inform the user about
++ * the BIG sync failed event.
++ */
++ if (!status || test_bit(HCI_CONN_BIG_SYNC_FAILED, &hcon->flags)) {
+ struct iso_conn *conn;
+
+ conn = iso_conn_add(hcon);
+--
+2.40.1
+
--- /dev/null
+From fa974dbe6aaa6b12466350b9ea2fb28b9cbd8370 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Jul 2023 21:30:00 +0800
+Subject: Bluetooth: nokia: fix value check in nokia_bluetooth_serdev_probe()
+
+From: Yuanjun Gong <ruc_gongyuanjun@163.com>
+
+[ Upstream commit e8b5aed31355072faac8092ead4938ddec3111fd ]
+
+in nokia_bluetooth_serdev_probe(), check the return value of
+clk_prepare_enable() and return the error code if
+clk_prepare_enable() returns an unexpected value.
+
+Fixes: 7bb318680e86 ("Bluetooth: add nokia driver")
+Signed-off-by: Yuanjun Gong <ruc_gongyuanjun@163.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/hci_nokia.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/bluetooth/hci_nokia.c b/drivers/bluetooth/hci_nokia.c
+index 05f7f6de6863d..97da0b2bfd17e 100644
+--- a/drivers/bluetooth/hci_nokia.c
++++ b/drivers/bluetooth/hci_nokia.c
+@@ -734,7 +734,11 @@ static int nokia_bluetooth_serdev_probe(struct serdev_device *serdev)
+ return err;
+ }
+
+- clk_prepare_enable(sysclk);
++ err = clk_prepare_enable(sysclk);
++ if (err) {
++ dev_err(dev, "could not enable sysclk: %d", err);
++ return err;
++ }
+ btdev->sysclk_speed = clk_get_rate(sysclk);
+ clk_disable_unprepare(sysclk);
+
+--
+2.40.1
+
--- /dev/null
+From a9740c382ae40d5e193df750980f2b5c7b4f5f75 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Jul 2023 02:56:25 +0000
+Subject: bpf: Clear the probe_addr for uprobe
+
+From: Yafang Shao <laoar.shao@gmail.com>
+
+[ Upstream commit 5125e757e62f6c1d5478db4c2b61a744060ddf3f ]
+
+To avoid returning uninitialized or random values when querying the file
+descriptor (fd) and accessing probe_addr, it is necessary to clear the
+variable prior to its use.
+
+Fixes: 41bdc4b40ed6 ("bpf: introduce bpf subcommand BPF_TASK_FD_QUERY")
+Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
+Acked-by: Yonghong Song <yhs@fb.com>
+Acked-by: Jiri Olsa <jolsa@kernel.org>
+Link: https://lore.kernel.org/r/20230709025630.3735-6-laoar.shao@gmail.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/trace_events.h | 3 ++-
+ kernel/trace/bpf_trace.c | 2 +-
+ kernel/trace/trace_uprobe.c | 3 ++-
+ 3 files changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h
+index c55fc453e33b5..6a41ad2ca84cc 100644
+--- a/include/linux/trace_events.h
++++ b/include/linux/trace_events.h
+@@ -875,7 +875,8 @@ extern int perf_uprobe_init(struct perf_event *event,
+ extern void perf_uprobe_destroy(struct perf_event *event);
+ extern int bpf_get_uprobe_info(const struct perf_event *event,
+ u32 *fd_type, const char **filename,
+- u64 *probe_offset, bool perf_type_tracepoint);
++ u64 *probe_offset, u64 *probe_addr,
++ bool perf_type_tracepoint);
+ #endif
+ extern int ftrace_profile_set_filter(struct perf_event *event, int event_id,
+ char *filter_str);
+diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
+index a53524f3f7d82..3d8d5c383dfe5 100644
+--- a/kernel/trace/bpf_trace.c
++++ b/kernel/trace/bpf_trace.c
+@@ -2391,7 +2391,7 @@ int bpf_get_perf_event_info(const struct perf_event *event, u32 *prog_id,
+ #ifdef CONFIG_UPROBE_EVENTS
+ if (flags & TRACE_EVENT_FL_UPROBE)
+ err = bpf_get_uprobe_info(event, fd_type, buf,
+- probe_offset,
++ probe_offset, probe_addr,
+ event->attr.type == PERF_TYPE_TRACEPOINT);
+ #endif
+ }
+diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c
+index 7b47e9a2c0102..9173fcfc03820 100644
+--- a/kernel/trace/trace_uprobe.c
++++ b/kernel/trace/trace_uprobe.c
+@@ -1416,7 +1416,7 @@ static void uretprobe_perf_func(struct trace_uprobe *tu, unsigned long func,
+
+ int bpf_get_uprobe_info(const struct perf_event *event, u32 *fd_type,
+ const char **filename, u64 *probe_offset,
+- bool perf_type_tracepoint)
++ u64 *probe_addr, bool perf_type_tracepoint)
+ {
+ const char *pevent = trace_event_name(event->tp_event);
+ const char *group = event->tp_event->class->system;
+@@ -1433,6 +1433,7 @@ int bpf_get_uprobe_info(const struct perf_event *event, u32 *fd_type,
+ : BPF_FD_TYPE_UPROBE;
+ *filename = tu->filename;
+ *probe_offset = tu->offset;
++ *probe_addr = 0;
+ return 0;
+ }
+ #endif /* CONFIG_PERF_EVENTS */
+--
+2.40.1
+
--- /dev/null
+From 3627ac76397cb95a2deb30e3c5083ccfbf1691e1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Aug 2023 22:00:53 -0700
+Subject: bpf: Fix a bpf_kptr_xchg() issue with local kptr
+
+From: Yonghong Song <yonghong.song@linux.dev>
+
+[ Upstream commit ab6c637ad0276e42f8acabcbc64932a6d346dab3 ]
+
+When reviewing local percpu kptr support, Alexei discovered a bug
+wherea bpf_kptr_xchg() may succeed even if the map value kptr type and
+locally allocated obj type do not match ([1]). Missed struct btf_id
+comparison is the reason for the bug. This patch added such struct btf_id
+comparison and will flag verification failure if types do not match.
+
+ [1] https://lore.kernel.org/bpf/20230819002907.io3iphmnuk43xblu@macbook-pro-8.dhcp.thefacebook.com/#t
+
+Reported-by: Alexei Starovoitov <ast@kernel.org>
+Fixes: 738c96d5e2e3 ("bpf: Allow local kptrs to be exchanged via bpf_kptr_xchg")
+Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
+Acked-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+Link: https://lore.kernel.org/r/20230822050053.2886960-1-yonghong.song@linux.dev
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/verifier.c | 25 +++++++++++++++----------
+ 1 file changed, 15 insertions(+), 10 deletions(-)
+
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index cef173614fc8f..b9e4dbdfa296a 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -4790,20 +4790,22 @@ static int map_kptr_match_type(struct bpf_verifier_env *env,
+ struct bpf_reg_state *reg, u32 regno)
+ {
+ const char *targ_name = btf_type_name(kptr_field->kptr.btf, kptr_field->kptr.btf_id);
+- int perm_flags = PTR_MAYBE_NULL | PTR_TRUSTED | MEM_RCU;
++ int perm_flags;
+ const char *reg_name = "";
+
+- /* Only unreferenced case accepts untrusted pointers */
+- if (kptr_field->type == BPF_KPTR_UNREF)
+- perm_flags |= PTR_UNTRUSTED;
++ if (btf_is_kernel(reg->btf)) {
++ perm_flags = PTR_MAYBE_NULL | PTR_TRUSTED | MEM_RCU;
++
++ /* Only unreferenced case accepts untrusted pointers */
++ if (kptr_field->type == BPF_KPTR_UNREF)
++ perm_flags |= PTR_UNTRUSTED;
++ } else {
++ perm_flags = PTR_MAYBE_NULL | MEM_ALLOC;
++ }
+
+ if (base_type(reg->type) != PTR_TO_BTF_ID || (type_flag(reg->type) & ~perm_flags))
+ goto bad_type;
+
+- if (!btf_is_kernel(reg->btf)) {
+- verbose(env, "R%d must point to kernel BTF\n", regno);
+- return -EINVAL;
+- }
+ /* We need to verify reg->type and reg->btf, before accessing reg->btf */
+ reg_name = btf_type_name(reg->btf, reg->btf_id);
+
+@@ -4816,7 +4818,7 @@ static int map_kptr_match_type(struct bpf_verifier_env *env,
+ if (__check_ptr_off_reg(env, reg, regno, true))
+ return -EACCES;
+
+- /* A full type match is needed, as BTF can be vmlinux or module BTF, and
++ /* A full type match is needed, as BTF can be vmlinux, module or prog BTF, and
+ * we also need to take into account the reg->off.
+ *
+ * We want to support cases like:
+@@ -7554,7 +7556,10 @@ static int check_reg_type(struct bpf_verifier_env *env, u32 regno,
+ verbose(env, "verifier internal error: unimplemented handling of MEM_ALLOC\n");
+ return -EFAULT;
+ }
+- /* Handled by helper specific checks */
++ if (meta->func_id == BPF_FUNC_kptr_xchg) {
++ if (map_kptr_match_type(env, meta->kptr_field, reg, regno))
++ return -EACCES;
++ }
+ break;
+ case PTR_TO_BTF_ID | MEM_PERCPU:
+ case PTR_TO_BTF_ID | MEM_PERCPU | PTR_TRUSTED:
+--
+2.40.1
+
--- /dev/null
+From 3c60426aa5f95771a58512541d6cf6e23da7043f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Jul 2023 02:56:39 +0000
+Subject: bpf: Fix an error around PTR_UNTRUSTED
+
+From: Yafang Shao <laoar.shao@gmail.com>
+
+[ Upstream commit 7ce4dc3e4a9d954c8a1fb483c7a527e9b060b860 ]
+
+Per discussion with Alexei, the PTR_UNTRUSTED flag should not been
+cleared when we start to walk a new struct, because the struct in
+question may be a struct nested in a union. We should also check and set
+this flag before we walk its each member, in case itself is a union.
+We will clear this flag if the field is BTF_TYPE_SAFE_RCU_OR_NULL.
+
+Fixes: 6fcd486b3a0a ("bpf: Refactor RCU enforcement in the verifier.")
+Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
+Link: https://lore.kernel.org/r/20230713025642.27477-2-laoar.shao@gmail.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/btf.c | 20 +++++++++-----------
+ kernel/bpf/verifier.c | 5 +++++
+ 2 files changed, 14 insertions(+), 11 deletions(-)
+
+diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
+index 8b4e92439d1d6..5dd8534b778d1 100644
+--- a/kernel/bpf/btf.c
++++ b/kernel/bpf/btf.c
+@@ -6126,7 +6126,6 @@ static int btf_struct_walk(struct bpf_verifier_log *log, const struct btf *btf,
+ const char *tname, *mname, *tag_value;
+ u32 vlen, elem_id, mid;
+
+- *flag = 0;
+ again:
+ tname = __btf_name_by_offset(btf, t->name_off);
+ if (!btf_type_is_struct(t)) {
+@@ -6135,6 +6134,14 @@ static int btf_struct_walk(struct bpf_verifier_log *log, const struct btf *btf,
+ }
+
+ vlen = btf_type_vlen(t);
++ if (BTF_INFO_KIND(t->info) == BTF_KIND_UNION && vlen != 1 && !(*flag & PTR_UNTRUSTED))
++ /*
++ * walking unions yields untrusted pointers
++ * with exception of __bpf_md_ptr and other
++ * unions with a single member
++ */
++ *flag |= PTR_UNTRUSTED;
++
+ if (off + size > t->size) {
+ /* If the last element is a variable size array, we may
+ * need to relax the rule.
+@@ -6295,15 +6302,6 @@ static int btf_struct_walk(struct bpf_verifier_log *log, const struct btf *btf,
+ * of this field or inside of this struct
+ */
+ if (btf_type_is_struct(mtype)) {
+- if (BTF_INFO_KIND(mtype->info) == BTF_KIND_UNION &&
+- btf_type_vlen(mtype) != 1)
+- /*
+- * walking unions yields untrusted pointers
+- * with exception of __bpf_md_ptr and other
+- * unions with a single member
+- */
+- *flag |= PTR_UNTRUSTED;
+-
+ /* our field must be inside that union or struct */
+ t = mtype;
+
+@@ -6469,7 +6467,7 @@ bool btf_struct_ids_match(struct bpf_verifier_log *log,
+ bool strict)
+ {
+ const struct btf_type *type;
+- enum bpf_type_flag flag;
++ enum bpf_type_flag flag = 0;
+ int err;
+
+ /* Are we already done? */
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index 4fbfe1d086467..cef173614fc8f 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -5893,6 +5893,11 @@ static int check_ptr_to_btf_access(struct bpf_verifier_env *env,
+ type_is_rcu_or_null(env, reg, field_name, btf_id)) {
+ /* __rcu tagged pointers can be NULL */
+ flag |= MEM_RCU | PTR_MAYBE_NULL;
++
++ /* We always trust them */
++ if (type_is_rcu_or_null(env, reg, field_name, btf_id) &&
++ flag & PTR_UNTRUSTED)
++ flag &= ~PTR_UNTRUSTED;
+ } else if (flag & (MEM_PERCPU | MEM_USER)) {
+ /* keep as-is */
+ } else {
+--
+2.40.1
+
--- /dev/null
+From eeb3a09925755dce410a604c7445704adc2c4d39 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Jul 2023 02:56:41 +0000
+Subject: bpf: Fix an error in verifying a field in a union
+
+From: Yafang Shao <laoar.shao@gmail.com>
+
+[ Upstream commit 33937607efa050d9e237e0c4ac4ada02d961c466 ]
+
+We are utilizing BPF LSM to monitor BPF operations within our container
+environment. When we add support for raw_tracepoint, it hits below
+error.
+
+; (const void *)attr->raw_tracepoint.name);
+27: (79) r3 = *(u64 *)(r2 +0)
+access beyond the end of member map_type (mend:4) in struct (anon) with off 0 size 8
+
+It can be reproduced with below BPF prog.
+
+SEC("lsm/bpf")
+int BPF_PROG(bpf_audit, int cmd, union bpf_attr *attr, unsigned int size)
+{
+ switch (cmd) {
+ case BPF_RAW_TRACEPOINT_OPEN:
+ bpf_printk("raw_tracepoint is %s", attr->raw_tracepoint.name);
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+The reason is that when accessing a field in a union, such as bpf_attr,
+if the field is located within a nested struct that is not the first
+member of the union, it can result in incorrect field verification.
+
+ union bpf_attr {
+ struct {
+ __u32 map_type; <<<< Actually it will find that field.
+ __u32 key_size;
+ __u32 value_size;
+ ...
+ };
+ ...
+ struct {
+ __u64 name; <<<< We want to verify this field.
+ __u32 prog_fd;
+ } raw_tracepoint;
+ };
+
+Considering the potential deep nesting levels, finding a perfect
+solution to address this issue has proven challenging. Therefore, I
+propose a solution where we simply skip the verification process if the
+field in question is located within a union.
+
+Fixes: 7e3617a72df3 ("bpf: Add array support to btf_struct_access")
+Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
+Link: https://lore.kernel.org/r/20230713025642.27477-4-laoar.shao@gmail.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/btf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
+index 5dd8534b778d1..9976149ec42f0 100644
+--- a/kernel/bpf/btf.c
++++ b/kernel/bpf/btf.c
+@@ -6359,7 +6359,7 @@ static int btf_struct_walk(struct bpf_verifier_log *log, const struct btf *btf,
+ * that also allows using an array of int as a scratch
+ * space. e.g. skb->cb[].
+ */
+- if (off + size > mtrue_end) {
++ if (off + size > mtrue_end && !(*flag & PTR_UNTRUSTED)) {
+ bpf_log(log,
+ "access beyond the end of member %s (mend:%u) in struct %s with off %u size %u\n",
+ mname, mtrue_end, tname, off, size);
+--
+2.40.1
+
--- /dev/null
+From 673d4c819b0c4f534b32d5111d8799a42db53e99 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Aug 2023 16:12:06 -0700
+Subject: bpf: fix bpf_dynptr_slice() to stop return an ERR_PTR.
+
+From: Kui-Feng Lee <thinker.li@gmail.com>
+
+[ Upstream commit 5426700e6841bf72e652e34b5cec68eadf442435 ]
+
+Verify if the pointer obtained from bpf_xdp_pointer() is either an error or
+NULL before returning it.
+
+The function bpf_dynptr_slice() mistakenly returned an ERR_PTR. Instead of
+solely checking for NULL, it should also verify if the pointer returned by
+bpf_xdp_pointer() is an error or NULL.
+
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Closes: https://lore.kernel.org/bpf/d1360219-85c3-4a03-9449-253ea905f9d1@moroto.mountain/
+Fixes: 66e3a13e7c2c ("bpf: Add bpf_dynptr_slice and bpf_dynptr_slice_rdwr")
+Suggested-by: Alexei Starovoitov <alexei.starovoitov@gmail.com>
+Signed-off-by: Kui-Feng Lee <thinker.li@gmail.com>
+Acked-by: Yonghong Song <yonghong.song@linux.dev>
+Link: https://lore.kernel.org/r/20230803231206.1060485-1-thinker.li@gmail.com
+Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/helpers.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
+index f12565ba136b0..8c5daa841704b 100644
+--- a/kernel/bpf/helpers.c
++++ b/kernel/bpf/helpers.c
+@@ -2218,7 +2218,7 @@ __bpf_kfunc void *bpf_dynptr_slice(const struct bpf_dynptr_kern *ptr, u32 offset
+ case BPF_DYNPTR_TYPE_XDP:
+ {
+ void *xdp_ptr = bpf_xdp_pointer(ptr->data, ptr->offset + offset, len);
+- if (xdp_ptr)
++ if (!IS_ERR_OR_NULL(xdp_ptr))
+ return xdp_ptr;
+
+ bpf_xdp_copy_buf(ptr->data, ptr->offset + offset, buffer, len, false);
+--
+2.40.1
+
--- /dev/null
+From d854c8309ffcf579dc94708b603ca0f9ec6fc954 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Aug 2023 23:21:39 +0530
+Subject: bpf: Fix check_func_arg_reg_off bug for graph root/node
+
+From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+
+[ Upstream commit 6785b2edf48c6b1c3ea61fe3b0d2e02b8fbf90c0 ]
+
+The commit being fixed introduced a hunk into check_func_arg_reg_off
+that bypasses reg->off == 0 enforcement when offset points to a graph
+node or root. This might possibly be done for treating bpf_rbtree_remove
+and others as KF_RELEASE and then later check correct reg->off in helper
+argument checks.
+
+But this is not the case, those helpers are already not KF_RELEASE and
+permit non-zero reg->off and verify it later to match the subobject in
+BTF type.
+
+However, this logic leads to bpf_obj_drop permitting free of register
+arguments with non-zero offset when they point to a graph root or node
+within them, which is not ok.
+
+For instance:
+
+struct foo {
+ int i;
+ int j;
+ struct bpf_rb_node node;
+};
+
+struct foo *f = bpf_obj_new(typeof(*f));
+if (!f) ...
+bpf_obj_drop(f); // OK
+bpf_obj_drop(&f->i); // still ok from verifier PoV
+bpf_obj_drop(&f->node); // Not OK, but permitted right now
+
+Fix this by dropping the whole part of code altogether.
+
+Fixes: 6a3cd3318ff6 ("bpf: Migrate release_on_unlock logic to non-owning ref semantics")
+Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+Link: https://lore.kernel.org/r/20230822175140.1317749-2-memxor@gmail.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/verifier.c | 11 -----------
+ 1 file changed, 11 deletions(-)
+
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index b9e4dbdfa296a..d4a6120edbb86 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -7611,17 +7611,6 @@ int check_func_arg_reg_off(struct bpf_verifier_env *env,
+ if (arg_type_is_dynptr(arg_type) && type == PTR_TO_STACK)
+ return 0;
+
+- if ((type_is_ptr_alloc_obj(type) || type_is_non_owning_ref(type)) && reg->off) {
+- if (reg_find_field_offset(reg, reg->off, BPF_GRAPH_NODE_OR_ROOT))
+- return __check_ptr_off_reg(env, reg, regno, true);
+-
+- verbose(env, "R%d must have zero offset when passed to release func\n",
+- regno);
+- verbose(env, "No graph node or root found at R%d type:%s off:%d\n", regno,
+- btf_type_name(reg->btf, reg->btf_id), reg->off);
+- return -EINVAL;
+- }
+-
+ /* Doing check_ptr_off_reg check for the offset will catch this
+ * because fixed_off_ok is false, but checking here allows us
+ * to give the user a better error message.
+--
+2.40.1
+
--- /dev/null
+From 1c53f65cde5209d48cab6bec7b2592fa2b7e7f0f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Jul 2023 17:30:11 +0200
+Subject: bpf, net: Support SO_REUSEPORT sockets with bpf_sk_assign
+
+From: Lorenz Bauer <lmb@isovalent.com>
+
+[ Upstream commit 9c02bec95954252c3c01bfbb3f7560e0b95ca955 ]
+
+Currently the bpf_sk_assign helper in tc BPF context refuses SO_REUSEPORT
+sockets. This means we can't use the helper to steer traffic to Envoy,
+which configures SO_REUSEPORT on its sockets. In turn, we're blocked
+from removing TPROXY from our setup.
+
+The reason that bpf_sk_assign refuses such sockets is that the
+bpf_sk_lookup helpers don't execute SK_REUSEPORT programs. Instead,
+one of the reuseport sockets is selected by hash. This could cause
+dispatch to the "wrong" socket:
+
+ sk = bpf_sk_lookup_tcp(...) // select SO_REUSEPORT by hash
+ bpf_sk_assign(skb, sk) // SK_REUSEPORT wasn't executed
+
+Fixing this isn't as simple as invoking SK_REUSEPORT from the lookup
+helpers unfortunately. In the tc context, L2 headers are at the start
+of the skb, while SK_REUSEPORT expects L3 headers instead.
+
+Instead, we execute the SK_REUSEPORT program when the assigned socket
+is pulled out of the skb, further up the stack. This creates some
+trickiness with regards to refcounting as bpf_sk_assign will put both
+refcounted and RCU freed sockets in skb->sk. reuseport sockets are RCU
+freed. We can infer that the sk_assigned socket is RCU freed if the
+reuseport lookup succeeds, but convincing yourself of this fact isn't
+straight forward. Therefore we defensively check refcounting on the
+sk_assign sock even though it's probably not required in practice.
+
+Fixes: 8e368dc72e86 ("bpf: Fix use of sk->sk_reuseport from sk_assign")
+Fixes: cf7fbe660f2d ("bpf: Add socket assign support")
+Co-developed-by: Daniel Borkmann <daniel@iogearbox.net>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Cc: Joe Stringer <joe@cilium.io>
+Link: https://lore.kernel.org/bpf/CACAyw98+qycmpQzKupquhkxbvWK4OFyDuuLMBNROnfWMZxUWeA@mail.gmail.com/
+Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: Lorenz Bauer <lmb@isovalent.com>
+Link: https://lore.kernel.org/r/20230720-so-reuseport-v6-7-7021b683cdae@isovalent.com
+Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/inet6_hashtables.h | 56 +++++++++++++++++++++++++++++++---
+ include/net/inet_hashtables.h | 49 +++++++++++++++++++++++++++--
+ include/net/sock.h | 7 +++--
+ include/uapi/linux/bpf.h | 3 --
+ net/core/filter.c | 2 --
+ net/ipv4/udp.c | 8 +++--
+ net/ipv6/udp.c | 8 +++--
+ tools/include/uapi/linux/bpf.h | 3 --
+ 8 files changed, 115 insertions(+), 21 deletions(-)
+
+diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h
+index f89320b6fee31..475e672b4facc 100644
+--- a/include/net/inet6_hashtables.h
++++ b/include/net/inet6_hashtables.h
+@@ -94,6 +94,46 @@ static inline struct sock *__inet6_lookup(struct net *net,
+ daddr, hnum, dif, sdif);
+ }
+
++static inline
++struct sock *inet6_steal_sock(struct net *net, struct sk_buff *skb, int doff,
++ const struct in6_addr *saddr, const __be16 sport,
++ const struct in6_addr *daddr, const __be16 dport,
++ bool *refcounted, inet6_ehashfn_t *ehashfn)
++{
++ struct sock *sk, *reuse_sk;
++ bool prefetched;
++
++ sk = skb_steal_sock(skb, refcounted, &prefetched);
++ if (!sk)
++ return NULL;
++
++ if (!prefetched)
++ return sk;
++
++ if (sk->sk_protocol == IPPROTO_TCP) {
++ if (sk->sk_state != TCP_LISTEN)
++ return sk;
++ } else if (sk->sk_protocol == IPPROTO_UDP) {
++ if (sk->sk_state != TCP_CLOSE)
++ return sk;
++ } else {
++ return sk;
++ }
++
++ reuse_sk = inet6_lookup_reuseport(net, sk, skb, doff,
++ saddr, sport, daddr, ntohs(dport),
++ ehashfn);
++ if (!reuse_sk)
++ return sk;
++
++ /* We've chosen a new reuseport sock which is never refcounted. This
++ * implies that sk also isn't refcounted.
++ */
++ WARN_ON_ONCE(*refcounted);
++
++ return reuse_sk;
++}
++
+ static inline struct sock *__inet6_lookup_skb(struct inet_hashinfo *hashinfo,
+ struct sk_buff *skb, int doff,
+ const __be16 sport,
+@@ -101,14 +141,20 @@ static inline struct sock *__inet6_lookup_skb(struct inet_hashinfo *hashinfo,
+ int iif, int sdif,
+ bool *refcounted)
+ {
+- struct sock *sk = skb_steal_sock(skb, refcounted);
+-
++ struct net *net = dev_net(skb_dst(skb)->dev);
++ const struct ipv6hdr *ip6h = ipv6_hdr(skb);
++ struct sock *sk;
++
++ sk = inet6_steal_sock(net, skb, doff, &ip6h->saddr, sport, &ip6h->daddr, dport,
++ refcounted, inet6_ehashfn);
++ if (IS_ERR(sk))
++ return NULL;
+ if (sk)
+ return sk;
+
+- return __inet6_lookup(dev_net(skb_dst(skb)->dev), hashinfo, skb,
+- doff, &ipv6_hdr(skb)->saddr, sport,
+- &ipv6_hdr(skb)->daddr, ntohs(dport),
++ return __inet6_lookup(net, hashinfo, skb,
++ doff, &ip6h->saddr, sport,
++ &ip6h->daddr, ntohs(dport),
+ iif, sdif, refcounted);
+ }
+
+diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
+index ddfa2e67fdb51..a1b8eb147ce73 100644
+--- a/include/net/inet_hashtables.h
++++ b/include/net/inet_hashtables.h
+@@ -442,6 +442,46 @@ static inline struct sock *inet_lookup(struct net *net,
+ return sk;
+ }
+
++static inline
++struct sock *inet_steal_sock(struct net *net, struct sk_buff *skb, int doff,
++ const __be32 saddr, const __be16 sport,
++ const __be32 daddr, const __be16 dport,
++ bool *refcounted, inet_ehashfn_t *ehashfn)
++{
++ struct sock *sk, *reuse_sk;
++ bool prefetched;
++
++ sk = skb_steal_sock(skb, refcounted, &prefetched);
++ if (!sk)
++ return NULL;
++
++ if (!prefetched)
++ return sk;
++
++ if (sk->sk_protocol == IPPROTO_TCP) {
++ if (sk->sk_state != TCP_LISTEN)
++ return sk;
++ } else if (sk->sk_protocol == IPPROTO_UDP) {
++ if (sk->sk_state != TCP_CLOSE)
++ return sk;
++ } else {
++ return sk;
++ }
++
++ reuse_sk = inet_lookup_reuseport(net, sk, skb, doff,
++ saddr, sport, daddr, ntohs(dport),
++ ehashfn);
++ if (!reuse_sk)
++ return sk;
++
++ /* We've chosen a new reuseport sock which is never refcounted. This
++ * implies that sk also isn't refcounted.
++ */
++ WARN_ON_ONCE(*refcounted);
++
++ return reuse_sk;
++}
++
+ static inline struct sock *__inet_lookup_skb(struct inet_hashinfo *hashinfo,
+ struct sk_buff *skb,
+ int doff,
+@@ -450,13 +490,18 @@ static inline struct sock *__inet_lookup_skb(struct inet_hashinfo *hashinfo,
+ const int sdif,
+ bool *refcounted)
+ {
+- struct sock *sk = skb_steal_sock(skb, refcounted);
++ struct net *net = dev_net(skb_dst(skb)->dev);
+ const struct iphdr *iph = ip_hdr(skb);
++ struct sock *sk;
+
++ sk = inet_steal_sock(net, skb, doff, iph->saddr, sport, iph->daddr, dport,
++ refcounted, inet_ehashfn);
++ if (IS_ERR(sk))
++ return NULL;
+ if (sk)
+ return sk;
+
+- return __inet_lookup(dev_net(skb_dst(skb)->dev), hashinfo, skb,
++ return __inet_lookup(net, hashinfo, skb,
+ doff, iph->saddr, sport,
+ iph->daddr, dport, inet_iif(skb), sdif,
+ refcounted);
+diff --git a/include/net/sock.h b/include/net/sock.h
+index d0d796d51a504..299c484bd4035 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -2826,20 +2826,23 @@ sk_is_refcounted(struct sock *sk)
+ * skb_steal_sock - steal a socket from an sk_buff
+ * @skb: sk_buff to steal the socket from
+ * @refcounted: is set to true if the socket is reference-counted
++ * @prefetched: is set to true if the socket was assigned from bpf
+ */
+ static inline struct sock *
+-skb_steal_sock(struct sk_buff *skb, bool *refcounted)
++skb_steal_sock(struct sk_buff *skb, bool *refcounted, bool *prefetched)
+ {
+ if (skb->sk) {
+ struct sock *sk = skb->sk;
+
+ *refcounted = true;
+- if (skb_sk_is_prefetched(skb))
++ *prefetched = skb_sk_is_prefetched(skb);
++ if (*prefetched)
+ *refcounted = sk_is_refcounted(sk);
+ skb->destructor = NULL;
+ skb->sk = NULL;
+ return sk;
+ }
++ *prefetched = false;
+ *refcounted = false;
+ return NULL;
+ }
+diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
+index c994ff5b157cd..dc6db5c246dbe 100644
+--- a/include/uapi/linux/bpf.h
++++ b/include/uapi/linux/bpf.h
+@@ -4145,9 +4145,6 @@ union bpf_attr {
+ * **-EOPNOTSUPP** if the operation is not supported, for example
+ * a call from outside of TC ingress.
+ *
+- * **-ESOCKTNOSUPPORT** if the socket type is not supported
+- * (reuseport).
+- *
+ * long bpf_sk_assign(struct bpf_sk_lookup *ctx, struct bpf_sock *sk, u64 flags)
+ * Description
+ * Helper is overloaded depending on BPF program type. This
+diff --git a/net/core/filter.c b/net/core/filter.c
+index a9e93d528869f..d5ca1f4c75b3e 100644
+--- a/net/core/filter.c
++++ b/net/core/filter.c
+@@ -7335,8 +7335,6 @@ BPF_CALL_3(bpf_sk_assign, struct sk_buff *, skb, struct sock *, sk, u64, flags)
+ return -EOPNOTSUPP;
+ if (unlikely(dev_net(skb->dev) != sock_net(sk)))
+ return -ENETUNREACH;
+- if (unlikely(sk_fullsock(sk) && sk->sk_reuseport))
+- return -ESOCKTNOSUPPORT;
+ if (sk_unhashed(sk))
+ return -EOPNOTSUPP;
+ if (sk_is_refcounted(sk) &&
+diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
+index aaba742f6d103..dd4259d998fc9 100644
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -2459,7 +2459,11 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
+ if (udp4_csum_init(skb, uh, proto))
+ goto csum_error;
+
+- sk = skb_steal_sock(skb, &refcounted);
++ sk = inet_steal_sock(net, skb, sizeof(struct udphdr), saddr, uh->source, daddr, uh->dest,
++ &refcounted, udp_ehashfn);
++ if (IS_ERR(sk))
++ goto no_sk;
++
+ if (sk) {
+ struct dst_entry *dst = skb_dst(skb);
+ int ret;
+@@ -2480,7 +2484,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
+ sk = __udp4_lib_lookup_skb(skb, uh->source, uh->dest, udptable);
+ if (sk)
+ return udp_unicast_rcv_skb(sk, skb, uh);
+-
++no_sk:
+ if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
+ goto drop;
+ nf_reset_ct(skb);
+diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
+index 19f5a2fc8f378..3a36cc48353f2 100644
+--- a/net/ipv6/udp.c
++++ b/net/ipv6/udp.c
+@@ -992,7 +992,11 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
+ goto csum_error;
+
+ /* Check if the socket is already available, e.g. due to early demux */
+- sk = skb_steal_sock(skb, &refcounted);
++ sk = inet6_steal_sock(net, skb, sizeof(struct udphdr), saddr, uh->source, daddr, uh->dest,
++ &refcounted, udp6_ehashfn);
++ if (IS_ERR(sk))
++ goto no_sk;
++
+ if (sk) {
+ struct dst_entry *dst = skb_dst(skb);
+ int ret;
+@@ -1026,7 +1030,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
+ goto report_csum_error;
+ return udp6_unicast_rcv_skb(sk, skb, uh);
+ }
+-
++no_sk:
+ reason = SKB_DROP_REASON_NO_SOCKET;
+
+ if (!uh->check)
+diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
+index c994ff5b157cd..dc6db5c246dbe 100644
+--- a/tools/include/uapi/linux/bpf.h
++++ b/tools/include/uapi/linux/bpf.h
+@@ -4145,9 +4145,6 @@ union bpf_attr {
+ * **-EOPNOTSUPP** if the operation is not supported, for example
+ * a call from outside of TC ingress.
+ *
+- * **-ESOCKTNOSUPPORT** if the socket type is not supported
+- * (reuseport).
+- *
+ * long bpf_sk_assign(struct bpf_sk_lookup *ctx, struct bpf_sock *sk, u64 flags)
+ * Description
+ * Helper is overloaded depending on BPF program type. This
+--
+2.40.1
+
--- /dev/null
+From 19c36f4d0fe385f3a123a9d01069eb2667d5bf8a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Jul 2023 17:30:06 +0200
+Subject: bpf: reject unhashed sockets in bpf_sk_assign
+
+From: Lorenz Bauer <lmb@isovalent.com>
+
+[ Upstream commit 67312adc96b5a585970d03b62412847afe2c6b01 ]
+
+The semantics for bpf_sk_assign are as follows:
+
+ sk = some_lookup_func()
+ bpf_sk_assign(skb, sk)
+ bpf_sk_release(sk)
+
+That is, the sk is not consumed by bpf_sk_assign. The function
+therefore needs to make sure that sk lives long enough to be
+consumed from __inet_lookup_skb. The path through the stack for a
+TCPv4 packet is roughly:
+
+ netif_receive_skb_core: takes RCU read lock
+ __netif_receive_skb_core:
+ sch_handle_ingress:
+ tcf_classify:
+ bpf_sk_assign()
+ deliver_ptype_list_skb:
+ deliver_skb:
+ ip_packet_type->func == ip_rcv:
+ ip_rcv_core:
+ ip_rcv_finish_core:
+ dst_input:
+ ip_local_deliver:
+ ip_local_deliver_finish:
+ ip_protocol_deliver_rcu:
+ tcp_v4_rcv:
+ __inet_lookup_skb:
+ skb_steal_sock
+
+The existing helper takes advantage of the fact that everything
+happens in the same RCU critical section: for sockets with
+SOCK_RCU_FREE set bpf_sk_assign never takes a reference.
+skb_steal_sock then checks SOCK_RCU_FREE again and does sock_put
+if necessary.
+
+This approach assumes that SOCK_RCU_FREE is never set on a sk
+between bpf_sk_assign and skb_steal_sock, but this invariant is
+violated by unhashed UDP sockets. A new UDP socket is created
+in TCP_CLOSE state but without SOCK_RCU_FREE set. That flag is only
+added in udp_lib_get_port() which happens when a socket is bound.
+
+When bpf_sk_assign was added it wasn't possible to access unhashed
+UDP sockets from BPF, so this wasn't a problem. This changed
+in commit 0c48eefae712 ("sock_map: Lift socket state restriction
+for datagram sockets"), but the helper wasn't adjusted accordingly.
+The following sequence of events will therefore lead to a refcount
+leak:
+
+1. Add socket(AF_INET, SOCK_DGRAM) to a sockmap.
+2. Pull socket out of sockmap and bpf_sk_assign it. Since
+ SOCK_RCU_FREE is not set we increment the refcount.
+3. bind() or connect() the socket, setting SOCK_RCU_FREE.
+4. skb_steal_sock will now set refcounted = false due to
+ SOCK_RCU_FREE.
+5. tcp_v4_rcv() skips sock_put().
+
+Fix the problem by rejecting unhashed sockets in bpf_sk_assign().
+This matches the behaviour of __inet_lookup_skb which is ultimately
+the goal of bpf_sk_assign().
+
+Fixes: cf7fbe660f2d ("bpf: Add socket assign support")
+Cc: Joe Stringer <joe@cilium.io>
+Signed-off-by: Lorenz Bauer <lmb@isovalent.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Link: https://lore.kernel.org/r/20230720-so-reuseport-v6-2-7021b683cdae@isovalent.com
+Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/filter.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/core/filter.c b/net/core/filter.c
+index f15ae393c2767..a9e93d528869f 100644
+--- a/net/core/filter.c
++++ b/net/core/filter.c
+@@ -7337,6 +7337,8 @@ BPF_CALL_3(bpf_sk_assign, struct sk_buff *, skb, struct sock *, sk, u64, flags)
+ return -ENETUNREACH;
+ if (unlikely(sk_fullsock(sk) && sk->sk_reuseport))
+ return -ESOCKTNOSUPPORT;
++ if (sk_unhashed(sk))
++ return -EOPNOTSUPP;
+ if (sk_is_refcounted(sk) &&
+ unlikely(!refcount_inc_not_zero(&sk->sk_refcnt)))
+ return -ENOENT;
+--
+2.40.1
+
--- /dev/null
+From 17969d02c9e731b6ce8355f3a67e5304b6c3a4e5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Jul 2023 10:54:23 +0100
+Subject: bpftool: Define a local bpf_perf_link to fix accessing its fields
+
+From: Alexander Lobakin <alobakin@pm.me>
+
+[ Upstream commit 67a43462ee2405c94e985a747bdcb8e3a0d66203 ]
+
+When building bpftool with !CONFIG_PERF_EVENTS:
+
+skeleton/pid_iter.bpf.c:47:14: error: incomplete definition of type 'struct bpf_perf_link'
+ perf_link = container_of(link, struct bpf_perf_link, link);
+ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+tools/bpf/bpftool/bootstrap/libbpf/include/bpf/bpf_helpers.h:74:22: note: expanded from macro 'container_of'
+ ((type *)(__mptr - offsetof(type, member))); \
+ ^~~~~~~~~~~~~~~~~~~~~~
+tools/bpf/bpftool/bootstrap/libbpf/include/bpf/bpf_helpers.h:68:60: note: expanded from macro 'offsetof'
+ #define offsetof(TYPE, MEMBER) ((unsigned long)&((TYPE *)0)->MEMBER)
+ ~~~~~~~~~~~^
+skeleton/pid_iter.bpf.c:44:9: note: forward declaration of 'struct bpf_perf_link'
+ struct bpf_perf_link *perf_link;
+ ^
+
+&bpf_perf_link is being defined and used only under the ifdef.
+Define struct bpf_perf_link___local with the `preserve_access_index`
+attribute inside the pid_iter BPF prog to allow compiling on any
+configs. CO-RE will substitute it with the real struct bpf_perf_link
+accesses later on.
+container_of() uses offsetof(), which does the necessary CO-RE
+relocation if the field is specified with `preserve_access_index` - as
+is the case for struct bpf_perf_link___local.
+
+Fixes: cbdaf71f7e65 ("bpftool: Add bpf_cookie to link output")
+Suggested-by: Andrii Nakryiko <andrii@kernel.org>
+Signed-off-by: Alexander Lobakin <alobakin@pm.me>
+Signed-off-by: Quentin Monnet <quentin@isovalent.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/20230707095425.168126-3-quentin@isovalent.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/bpf/bpftool/skeleton/pid_iter.bpf.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/tools/bpf/bpftool/skeleton/pid_iter.bpf.c b/tools/bpf/bpftool/skeleton/pid_iter.bpf.c
+index e2af8e5fb29ec..3a4c4f7d83d86 100644
+--- a/tools/bpf/bpftool/skeleton/pid_iter.bpf.c
++++ b/tools/bpf/bpftool/skeleton/pid_iter.bpf.c
+@@ -15,6 +15,11 @@ enum bpf_obj_type {
+ BPF_OBJ_BTF,
+ };
+
++struct bpf_perf_link___local {
++ struct bpf_link link;
++ struct file *perf_file;
++} __attribute__((preserve_access_index));
++
+ struct perf_event___local {
+ u64 bpf_cookie;
+ } __attribute__((preserve_access_index));
+@@ -45,10 +50,10 @@ static __always_inline __u32 get_obj_id(void *ent, enum bpf_obj_type type)
+ /* could be used only with BPF_LINK_TYPE_PERF_EVENT links */
+ static __u64 get_bpf_cookie(struct bpf_link *link)
+ {
++ struct bpf_perf_link___local *perf_link;
+ struct perf_event___local *event;
+- struct bpf_perf_link *perf_link;
+
+- perf_link = container_of(link, struct bpf_perf_link, link);
++ perf_link = container_of(link, struct bpf_perf_link___local, link);
+ event = BPF_CORE_READ(perf_link, perf_file, private_data);
+ return BPF_CORE_READ(event, bpf_cookie);
+ }
+--
+2.40.1
+
--- /dev/null
+From d34e253c9379fe886741ae3dd572adbcc1ef2e60 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Jul 2023 10:54:25 +0100
+Subject: bpftool: Use a local bpf_perf_event_value to fix accessing its fields
+
+From: Alexander Lobakin <alobakin@pm.me>
+
+[ Upstream commit 658ac06801315b739774a15796ff06913ef5cad5 ]
+
+Fix the following error when building bpftool:
+
+ CLANG profiler.bpf.o
+ CLANG pid_iter.bpf.o
+skeleton/profiler.bpf.c:18:21: error: invalid application of 'sizeof' to an incomplete type 'struct bpf_perf_event_value'
+ __uint(value_size, sizeof(struct bpf_perf_event_value));
+ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+tools/bpf/bpftool/bootstrap/libbpf/include/bpf/bpf_helpers.h:13:39: note: expanded from macro '__uint'
+tools/bpf/bpftool/bootstrap/libbpf/include/bpf/bpf_helper_defs.h:7:8: note: forward declaration of 'struct bpf_perf_event_value'
+struct bpf_perf_event_value;
+ ^
+
+struct bpf_perf_event_value is being used in the kernel only when
+CONFIG_BPF_EVENTS is enabled, so it misses a BTF entry then.
+Define struct bpf_perf_event_value___local with the
+`preserve_access_index` attribute inside the pid_iter BPF prog to
+allow compiling on any configs. It is a full mirror of a UAPI
+structure, so is compatible both with and w/o CO-RE.
+bpf_perf_event_read_value() requires a pointer of the original type,
+so a cast is needed.
+
+Fixes: 47c09d6a9f67 ("bpftool: Introduce "prog profile" command")
+Suggested-by: Andrii Nakryiko <andrii@kernel.org>
+Signed-off-by: Alexander Lobakin <alobakin@pm.me>
+Signed-off-by: Quentin Monnet <quentin@isovalent.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/20230707095425.168126-5-quentin@isovalent.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/bpf/bpftool/skeleton/profiler.bpf.c | 27 ++++++++++++++---------
+ 1 file changed, 17 insertions(+), 10 deletions(-)
+
+diff --git a/tools/bpf/bpftool/skeleton/profiler.bpf.c b/tools/bpf/bpftool/skeleton/profiler.bpf.c
+index ce5b65e07ab10..2f80edc682f11 100644
+--- a/tools/bpf/bpftool/skeleton/profiler.bpf.c
++++ b/tools/bpf/bpftool/skeleton/profiler.bpf.c
+@@ -4,6 +4,12 @@
+ #include <bpf/bpf_helpers.h>
+ #include <bpf/bpf_tracing.h>
+
++struct bpf_perf_event_value___local {
++ __u64 counter;
++ __u64 enabled;
++ __u64 running;
++} __attribute__((preserve_access_index));
++
+ /* map of perf event fds, num_cpu * num_metric entries */
+ struct {
+ __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
+@@ -15,14 +21,14 @@ struct {
+ struct {
+ __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
+ __uint(key_size, sizeof(u32));
+- __uint(value_size, sizeof(struct bpf_perf_event_value));
++ __uint(value_size, sizeof(struct bpf_perf_event_value___local));
+ } fentry_readings SEC(".maps");
+
+ /* accumulated readings */
+ struct {
+ __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
+ __uint(key_size, sizeof(u32));
+- __uint(value_size, sizeof(struct bpf_perf_event_value));
++ __uint(value_size, sizeof(struct bpf_perf_event_value___local));
+ } accum_readings SEC(".maps");
+
+ /* sample counts, one per cpu */
+@@ -39,7 +45,7 @@ const volatile __u32 num_metric = 1;
+ SEC("fentry/XXX")
+ int BPF_PROG(fentry_XXX)
+ {
+- struct bpf_perf_event_value *ptrs[MAX_NUM_MATRICS];
++ struct bpf_perf_event_value___local *ptrs[MAX_NUM_MATRICS];
+ u32 key = bpf_get_smp_processor_id();
+ u32 i;
+
+@@ -53,10 +59,10 @@ int BPF_PROG(fentry_XXX)
+ }
+
+ for (i = 0; i < num_metric && i < MAX_NUM_MATRICS; i++) {
+- struct bpf_perf_event_value reading;
++ struct bpf_perf_event_value___local reading;
+ int err;
+
+- err = bpf_perf_event_read_value(&events, key, &reading,
++ err = bpf_perf_event_read_value(&events, key, (void *)&reading,
+ sizeof(reading));
+ if (err)
+ return 0;
+@@ -68,14 +74,14 @@ int BPF_PROG(fentry_XXX)
+ }
+
+ static inline void
+-fexit_update_maps(u32 id, struct bpf_perf_event_value *after)
++fexit_update_maps(u32 id, struct bpf_perf_event_value___local *after)
+ {
+- struct bpf_perf_event_value *before, diff;
++ struct bpf_perf_event_value___local *before, diff;
+
+ before = bpf_map_lookup_elem(&fentry_readings, &id);
+ /* only account samples with a valid fentry_reading */
+ if (before && before->counter) {
+- struct bpf_perf_event_value *accum;
++ struct bpf_perf_event_value___local *accum;
+
+ diff.counter = after->counter - before->counter;
+ diff.enabled = after->enabled - before->enabled;
+@@ -93,7 +99,7 @@ fexit_update_maps(u32 id, struct bpf_perf_event_value *after)
+ SEC("fexit/XXX")
+ int BPF_PROG(fexit_XXX)
+ {
+- struct bpf_perf_event_value readings[MAX_NUM_MATRICS];
++ struct bpf_perf_event_value___local readings[MAX_NUM_MATRICS];
+ u32 cpu = bpf_get_smp_processor_id();
+ u32 i, zero = 0;
+ int err;
+@@ -102,7 +108,8 @@ int BPF_PROG(fexit_XXX)
+ /* read all events before updating the maps, to reduce error */
+ for (i = 0; i < num_metric && i < MAX_NUM_MATRICS; i++) {
+ err = bpf_perf_event_read_value(&events, cpu + i * num_cpu,
+- readings + i, sizeof(*readings));
++ (void *)(readings + i),
++ sizeof(*readings));
+ if (err)
+ return 0;
+ }
+--
+2.40.1
+
--- /dev/null
+From f6fc39439c4c7baf6241e16f91fe18657ba26352 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Jul 2023 10:54:24 +0100
+Subject: bpftool: Use a local copy of BPF_LINK_TYPE_PERF_EVENT in
+ pid_iter.bpf.c
+
+From: Quentin Monnet <quentin@isovalent.com>
+
+[ Upstream commit 44ba7b30e84fb40da2295e85a6d209e199fdc977 ]
+
+In order to allow the BPF program in bpftool's pid_iter.bpf.c to compile
+correctly on hosts where vmlinux.h does not define
+BPF_LINK_TYPE_PERF_EVENT (running kernel versions lower than 5.15, for
+example), define and use a local copy of the enum value. This requires
+LLVM 12 or newer to build the BPF program.
+
+Fixes: cbdaf71f7e65 ("bpftool: Add bpf_cookie to link output")
+Signed-off-by: Quentin Monnet <quentin@isovalent.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/20230707095425.168126-4-quentin@isovalent.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/bpf/bpftool/skeleton/pid_iter.bpf.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/tools/bpf/bpftool/skeleton/pid_iter.bpf.c b/tools/bpf/bpftool/skeleton/pid_iter.bpf.c
+index 3a4c4f7d83d86..26004f0c5a6ae 100644
+--- a/tools/bpf/bpftool/skeleton/pid_iter.bpf.c
++++ b/tools/bpf/bpftool/skeleton/pid_iter.bpf.c
+@@ -24,6 +24,10 @@ struct perf_event___local {
+ u64 bpf_cookie;
+ } __attribute__((preserve_access_index));
+
++enum bpf_link_type___local {
++ BPF_LINK_TYPE_PERF_EVENT___local = 7,
++};
++
+ extern const void bpf_link_fops __ksym;
+ extern const void bpf_map_fops __ksym;
+ extern const void bpf_prog_fops __ksym;
+@@ -93,10 +97,13 @@ int iter(struct bpf_iter__task_file *ctx)
+ e.pid = task->tgid;
+ e.id = get_obj_id(file->private_data, obj_type);
+
+- if (obj_type == BPF_OBJ_LINK) {
++ if (obj_type == BPF_OBJ_LINK &&
++ bpf_core_enum_value_exists(enum bpf_link_type___local,
++ BPF_LINK_TYPE_PERF_EVENT___local)) {
+ struct bpf_link *link = (struct bpf_link *) file->private_data;
+
+- if (BPF_CORE_READ(link, type) == BPF_LINK_TYPE_PERF_EVENT) {
++ if (link->type == bpf_core_enum_value(enum bpf_link_type___local,
++ BPF_LINK_TYPE_PERF_EVENT___local)) {
+ e.has_bpf_cookie = true;
+ e.bpf_cookie = get_bpf_cookie(link);
+ }
+--
+2.40.1
+
--- /dev/null
+From 82504667ede030ac52b55ddd8a75134d1d7847ea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Jul 2023 10:54:22 +0100
+Subject: bpftool: use a local copy of perf_event to fix accessing ::
+ Bpf_cookie
+
+From: Alexander Lobakin <alobakin@pm.me>
+
+[ Upstream commit 4cbeeb0dc02f8ac7b975b2ab0080ace53d43d62a ]
+
+When CONFIG_PERF_EVENTS is not set, struct perf_event remains empty.
+However, the structure is being used by bpftool indirectly via BTF.
+This leads to:
+
+skeleton/pid_iter.bpf.c:49:30: error: no member named 'bpf_cookie' in 'struct perf_event'
+ return BPF_CORE_READ(event, bpf_cookie);
+ ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~
+
+...
+
+skeleton/pid_iter.bpf.c:49:9: error: returning 'void' from a function with incompatible result type '__u64' (aka 'unsigned long long')
+ return BPF_CORE_READ(event, bpf_cookie);
+ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Tools and samples can't use any CONFIG_ definitions, so the fields
+used there should always be present.
+Define struct perf_event___local with the `preserve_access_index`
+attribute inside the pid_iter BPF prog to allow compiling on any
+configs. CO-RE will substitute it with the real struct perf_event
+accesses later on.
+
+Fixes: cbdaf71f7e65 ("bpftool: Add bpf_cookie to link output")
+Suggested-by: Andrii Nakryiko <andrii@kernel.org>
+Signed-off-by: Alexander Lobakin <alobakin@pm.me>
+Signed-off-by: Quentin Monnet <quentin@isovalent.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/20230707095425.168126-2-quentin@isovalent.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/bpf/bpftool/skeleton/pid_iter.bpf.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/tools/bpf/bpftool/skeleton/pid_iter.bpf.c b/tools/bpf/bpftool/skeleton/pid_iter.bpf.c
+index eb05ea53afb12..e2af8e5fb29ec 100644
+--- a/tools/bpf/bpftool/skeleton/pid_iter.bpf.c
++++ b/tools/bpf/bpftool/skeleton/pid_iter.bpf.c
+@@ -15,6 +15,10 @@ enum bpf_obj_type {
+ BPF_OBJ_BTF,
+ };
+
++struct perf_event___local {
++ u64 bpf_cookie;
++} __attribute__((preserve_access_index));
++
+ extern const void bpf_link_fops __ksym;
+ extern const void bpf_map_fops __ksym;
+ extern const void bpf_prog_fops __ksym;
+@@ -41,8 +45,8 @@ static __always_inline __u32 get_obj_id(void *ent, enum bpf_obj_type type)
+ /* could be used only with BPF_LINK_TYPE_PERF_EVENT links */
+ static __u64 get_bpf_cookie(struct bpf_link *link)
+ {
++ struct perf_event___local *event;
+ struct bpf_perf_link *perf_link;
+- struct perf_event *event;
+
+ perf_link = container_of(link, struct bpf_perf_link, link);
+ event = BPF_CORE_READ(perf_link, perf_file, private_data);
+--
+2.40.1
+
--- /dev/null
+From 1f942044385f4109ae54f00a8b6c7883fb88a705 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Aug 2023 13:38:01 +0300
+Subject: bus: ti-sysc: Fix build warning for 64-bit build
+
+From: Tony Lindgren <tony@atomide.com>
+
+[ Upstream commit e1e1e9bb9d943ec690670a609a5f660ca10eaf85 ]
+
+Fix "warning: cast from pointer to integer of different size" on 64-bit
+builds.
+
+Note that this is a cosmetic fix at this point as the driver is not yet
+used for 64-bit systems.
+
+Fixes: feaa8baee82a ("bus: ti-sysc: Implement SoC revision handling")
+Reviewed-by: Dhruva Gole <d-gole@ti.com>
+Reviewed-by: Nishanth Menon <nm@ti.com>
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bus/ti-sysc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c
+index 4cb23b9e06ea4..dbc37b3b84a8d 100644
+--- a/drivers/bus/ti-sysc.c
++++ b/drivers/bus/ti-sysc.c
+@@ -3106,7 +3106,7 @@ static int sysc_init_static_data(struct sysc *ddata)
+
+ match = soc_device_match(sysc_soc_match);
+ if (match && match->data)
+- sysc_soc->soc = (int)match->data;
++ sysc_soc->soc = (enum sysc_soc)match->data;
+
+ /*
+ * Check and warn about possible old incomplete dtb. We now want to see
+--
+2.40.1
+
--- /dev/null
+From 84809ce947fae9076eb9c9275e93029437fcb022 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Aug 2023 08:49:05 +0300
+Subject: bus: ti-sysc: Fix cast to enum warning
+
+From: Tony Lindgren <tony@atomide.com>
+
+[ Upstream commit de44bf2f7683347f75690ef6cf61a1d5ba8f0891 ]
+
+Fix warning for "cast to smaller integer type 'enum sysc_soc' from 'const
+void *'".
+
+Cc: Nishanth Menon <nm@ti.com>
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202308150723.ziuGCdM3-lkp@intel.com/
+Fixes: e1e1e9bb9d94 ("bus: ti-sysc: Fix build warning for 64-bit build")
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bus/ti-sysc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c
+index dbc37b3b84a8d..c95fa4335fee2 100644
+--- a/drivers/bus/ti-sysc.c
++++ b/drivers/bus/ti-sysc.c
+@@ -3106,7 +3106,7 @@ static int sysc_init_static_data(struct sysc *ddata)
+
+ match = soc_device_match(sysc_soc_match);
+ if (match && match->data)
+- sysc_soc->soc = (enum sysc_soc)match->data;
++ sysc_soc->soc = (enum sysc_soc)(uintptr_t)match->data;
+
+ /*
+ * Check and warn about possible old incomplete dtb. We now want to see
+--
+2.40.1
+
--- /dev/null
+From 81917a5e8506f87fd050049744faab1797ee1f60 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Jul 2023 11:23:37 +0200
+Subject: can: gs_usb: gs_usb_receive_bulk_callback(): count RX overflow errors
+ also in case of OOM
+
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+
+[ Upstream commit 6c8bc15f02b85bc8f47074110d8fd8caf7a1e42d ]
+
+In case of an RX overflow error from the CAN controller and an OOM
+where no skb can be allocated, the error counters are not incremented.
+
+Fix this by first incrementing the error counters and then allocate
+the skb.
+
+Fixes: d08e973a77d1 ("can: gs_usb: Added support for the GS_USB CAN devices")
+Link: https://lore.kernel.org/all/20230718-gs_usb-cleanups-v1-7-c3b9154ec605@pengutronix.de
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/usb/gs_usb.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c
+index bd9eb066ecf15..129ef60a577c8 100644
+--- a/drivers/net/can/usb/gs_usb.c
++++ b/drivers/net/can/usb/gs_usb.c
+@@ -633,6 +633,9 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
+ }
+
+ if (hf->flags & GS_CAN_FLAG_OVERFLOW) {
++ stats->rx_over_errors++;
++ stats->rx_errors++;
++
+ skb = alloc_can_err_skb(netdev, &cf);
+ if (!skb)
+ goto resubmit_urb;
+@@ -640,8 +643,6 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
+ cf->can_id |= CAN_ERR_CRTL;
+ cf->len = CAN_ERR_DLC;
+ cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
+- stats->rx_over_errors++;
+- stats->rx_errors++;
+ netif_rx(skb);
+ }
+
+--
+2.40.1
+
--- /dev/null
+From 6058b4ec1c3ba721fc1bae84ab5dfce21b62b69f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Jul 2023 16:19:19 +0200
+Subject: can: tcan4x5x: Remove reserved register 0x814 from writable table
+
+From: Markus Schneider-Pargmann <msp@baylibre.com>
+
+[ Upstream commit fbe534f7bf213d485b0ed5362b24a41bf3e18803 ]
+
+The mentioned register is not writable. It is reserved and should not be
+written.
+
+Fixes: 39dbb21b6a29 ("can: tcan4x5x: Specify separate read/write ranges")
+Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
+Reviewed-by: Michal Kubiak <michal.kubiak@intel.com>
+Link: https://lore.kernel.org/all/20230728141923.162477-3-msp@baylibre.com
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/m_can/tcan4x5x-regmap.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/net/can/m_can/tcan4x5x-regmap.c b/drivers/net/can/m_can/tcan4x5x-regmap.c
+index 2b218ce04e9f2..fafa6daa67e69 100644
+--- a/drivers/net/can/m_can/tcan4x5x-regmap.c
++++ b/drivers/net/can/m_can/tcan4x5x-regmap.c
+@@ -95,7 +95,6 @@ static const struct regmap_range tcan4x5x_reg_table_wr_range[] = {
+ regmap_reg_range(0x000c, 0x0010),
+ /* Device configuration registers and Interrupt Flags*/
+ regmap_reg_range(0x0800, 0x080c),
+- regmap_reg_range(0x0814, 0x0814),
+ regmap_reg_range(0x0820, 0x0820),
+ regmap_reg_range(0x0830, 0x0830),
+ /* M_CAN */
+--
+2.40.1
+
--- /dev/null
+From ca242ff701ca149b4f318614d1a0105865c3c637 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Jun 2023 10:35:00 -0400
+Subject: cgroup/cpuset: Inherit parent's load balance state in v2
+
+From: Waiman Long <longman@redhat.com>
+
+[ Upstream commit c8c926200c55454101f072a4b16c9ff5b8c9e56f ]
+
+Since commit f28e22441f35 ("cgroup/cpuset: Add a new isolated
+cpus.partition type"), the CS_SCHED_LOAD_BALANCE bit of a v2 cpuset
+can be on or off. The child cpusets of a partition root must have the
+same setting as its parent or it may screw up the rebuilding of sched
+domains. Fix this problem by making sure the a child v2 cpuset will
+follows its parent cpuset load balance state unless the child cpuset
+is a new partition root itself.
+
+Fixes: f28e22441f35 ("cgroup/cpuset: Add a new isolated cpus.partition type")
+Signed-off-by: Waiman Long <longman@redhat.com>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/cgroup/cpuset.c | 33 ++++++++++++++++++++++++++++++---
+ 1 file changed, 30 insertions(+), 3 deletions(-)
+
+diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
+index 2c76fcd9f0bcb..7c5153273c1a8 100644
+--- a/kernel/cgroup/cpuset.c
++++ b/kernel/cgroup/cpuset.c
+@@ -1611,11 +1611,16 @@ static void update_cpumasks_hier(struct cpuset *cs, struct tmpmasks *tmp,
+ }
+
+ /*
+- * Skip the whole subtree if the cpumask remains the same
+- * and has no partition root state and force flag not set.
++ * Skip the whole subtree if
++ * 1) the cpumask remains the same,
++ * 2) has no partition root state,
++ * 3) force flag not set, and
++ * 4) for v2 load balance state same as its parent.
+ */
+ if (!cp->partition_root_state && !force &&
+- cpumask_equal(tmp->new_cpus, cp->effective_cpus)) {
++ cpumask_equal(tmp->new_cpus, cp->effective_cpus) &&
++ (!cgroup_subsys_on_dfl(cpuset_cgrp_subsys) ||
++ (is_sched_load_balance(parent) == is_sched_load_balance(cp)))) {
+ pos_css = css_rightmost_descendant(pos_css);
+ continue;
+ }
+@@ -1698,6 +1703,20 @@ static void update_cpumasks_hier(struct cpuset *cs, struct tmpmasks *tmp,
+
+ update_tasks_cpumask(cp, tmp->new_cpus);
+
++ /*
++ * On default hierarchy, inherit the CS_SCHED_LOAD_BALANCE
++ * from parent if current cpuset isn't a valid partition root
++ * and their load balance states differ.
++ */
++ if (cgroup_subsys_on_dfl(cpuset_cgrp_subsys) &&
++ !is_partition_valid(cp) &&
++ (is_sched_load_balance(parent) != is_sched_load_balance(cp))) {
++ if (is_sched_load_balance(parent))
++ set_bit(CS_SCHED_LOAD_BALANCE, &cp->flags);
++ else
++ clear_bit(CS_SCHED_LOAD_BALANCE, &cp->flags);
++ }
++
+ /*
+ * On legacy hierarchy, if the effective cpumask of any non-
+ * empty cpuset is changed, we need to rebuild sched domains.
+@@ -3245,6 +3264,14 @@ static int cpuset_css_online(struct cgroup_subsys_state *css)
+ cs->use_parent_ecpus = true;
+ parent->child_ecpus_count++;
+ }
++
++ /*
++ * For v2, clear CS_SCHED_LOAD_BALANCE if parent is isolated
++ */
++ if (cgroup_subsys_on_dfl(cpuset_cgrp_subsys) &&
++ !is_sched_load_balance(parent))
++ clear_bit(CS_SCHED_LOAD_BALANCE, &cs->flags);
++
+ spin_unlock_irq(&callback_lock);
+
+ if (!test_bit(CGRP_CPUSET_CLONE_CHILDREN, &css->cgroup->flags))
+--
+2.40.1
+
--- /dev/null
+From afe1882508b1b05fd0503354360dc038ba702ea2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Aug 2023 10:22:00 +0200
+Subject: clk: imx: composite-8m: fix clock pauses when set_rate would be a
+ no-op
+
+From: Ahmad Fatoum <a.fatoum@pengutronix.de>
+
+[ Upstream commit 4dd432d985ef258e3bc436e568fba4b987b59171 ]
+
+Reconfiguring the clock divider to the exact same value is observed
+on an i.MX8MN to often cause a longer than usual clock pause, probably
+because the divider restarts counting whenever the register is rewritten.
+
+This issue doesn't show up normally, because the clock framework will
+take care to not call set_rate when the clock rate is the same.
+However, when we reconfigure an upstream clock, the common code will
+call set_rate with the newly calculated rate on all children, e.g.:
+
+ - sai5 is running normally and divides Audio PLL out by 16.
+ - Audio PLL rate is increased by 32Hz (glitch-free kdiv change)
+ - rates for children are recalculated and rates are set recursively
+ - imx8m_clk_composite_divider_set_rate(sai5) is called with
+ 32/16 = 2Hz more
+ - imx8m_clk_composite_divider_set_rate computes same divider as before
+ - divider register is written, so it restarts counting from zero and
+ MCLK is briefly paused, so instead of e.g. 40ns, MCLK is low for 120ns.
+
+Some external clock consumers can be upset by such unexpected clock pauses,
+so let's make sure we only rewrite the divider value when the value to be
+written is actually different.
+
+Fixes: d3ff9728134e ("clk: imx: Add imx composite clock")
+Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
+Reviewed-by: Peng Fan <peng.fan@nxp.com>
+Link: https://lore.kernel.org/r/20230807082201.2332746-1-a.fatoum@pengutronix.de
+Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/imx/clk-composite-8m.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/clk/imx/clk-composite-8m.c b/drivers/clk/imx/clk-composite-8m.c
+index 7a6e3ce97133b..27a08c50ac1d8 100644
+--- a/drivers/clk/imx/clk-composite-8m.c
++++ b/drivers/clk/imx/clk-composite-8m.c
+@@ -97,7 +97,7 @@ static int imx8m_clk_composite_divider_set_rate(struct clk_hw *hw,
+ int prediv_value;
+ int div_value;
+ int ret;
+- u32 val;
++ u32 orig, val;
+
+ ret = imx8m_clk_composite_compute_dividers(rate, parent_rate,
+ &prediv_value, &div_value);
+@@ -106,13 +106,15 @@ static int imx8m_clk_composite_divider_set_rate(struct clk_hw *hw,
+
+ spin_lock_irqsave(divider->lock, flags);
+
+- val = readl(divider->reg);
+- val &= ~((clk_div_mask(divider->width) << divider->shift) |
+- (clk_div_mask(PCG_DIV_WIDTH) << PCG_DIV_SHIFT));
++ orig = readl(divider->reg);
++ val = orig & ~((clk_div_mask(divider->width) << divider->shift) |
++ (clk_div_mask(PCG_DIV_WIDTH) << PCG_DIV_SHIFT));
+
+ val |= (u32)(prediv_value - 1) << divider->shift;
+ val |= (u32)(div_value - 1) << PCG_DIV_SHIFT;
+- writel(val, divider->reg);
++
++ if (val != orig)
++ writel(val, divider->reg);
+
+ spin_unlock_irqrestore(divider->lock, flags);
+
+--
+2.40.1
+
--- /dev/null
+From ba72b34a91e3610cdbb966ef4718f09583f63628 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 25 Jun 2023 20:33:40 +0800
+Subject: clk: imx: imx8ulp: update SPLL2 type
+
+From: Peng Fan <peng.fan@nxp.com>
+
+[ Upstream commit 7653a59be8af043adc4c09473975a860e6055ff9 ]
+
+The SPLL2 on iMX8ULP is different with other frac PLLs, it can
+support VCO from 650Mhz to 1Ghz. Following the changes to pllv4,
+use the new type IMX_PLLV4_IMX8ULP_1GHZ.
+
+Fixes: c43a801a5789 ("clk: imx: Add clock driver for imx8ulp")
+Signed-off-by: Peng Fan <peng.fan@nxp.com>
+Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
+Link: https://lore.kernel.org/r/20230625123340.4067536-2-peng.fan@oss.nxp.com
+Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/imx/clk-imx8ulp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/imx/clk-imx8ulp.c b/drivers/clk/imx/clk-imx8ulp.c
+index e308c88cb801c..1b04e2fc78ad5 100644
+--- a/drivers/clk/imx/clk-imx8ulp.c
++++ b/drivers/clk/imx/clk-imx8ulp.c
+@@ -167,7 +167,7 @@ static int imx8ulp_clk_cgc1_init(struct platform_device *pdev)
+ clks[IMX8ULP_CLK_SPLL2_PRE_SEL] = imx_clk_hw_mux_flags("spll2_pre_sel", base + 0x510, 0, 1, pll_pre_sels, ARRAY_SIZE(pll_pre_sels), CLK_SET_PARENT_GATE);
+ clks[IMX8ULP_CLK_SPLL3_PRE_SEL] = imx_clk_hw_mux_flags("spll3_pre_sel", base + 0x610, 0, 1, pll_pre_sels, ARRAY_SIZE(pll_pre_sels), CLK_SET_PARENT_GATE);
+
+- clks[IMX8ULP_CLK_SPLL2] = imx_clk_hw_pllv4(IMX_PLLV4_IMX8ULP, "spll2", "spll2_pre_sel", base + 0x500);
++ clks[IMX8ULP_CLK_SPLL2] = imx_clk_hw_pllv4(IMX_PLLV4_IMX8ULP_1GHZ, "spll2", "spll2_pre_sel", base + 0x500);
+ clks[IMX8ULP_CLK_SPLL3] = imx_clk_hw_pllv4(IMX_PLLV4_IMX8ULP, "spll3", "spll3_pre_sel", base + 0x600);
+ clks[IMX8ULP_CLK_SPLL3_VCODIV] = imx_clk_hw_divider("spll3_vcodiv", "spll3", base + 0x604, 0, 6);
+
+--
+2.40.1
+
--- /dev/null
+From 685b48679c563d002b1c3de2869ce0c72e6f562b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 25 Jun 2023 20:33:39 +0800
+Subject: clk: imx: pllv4: Fix SPLL2 MULT range
+
+From: Ye Li <ye.li@nxp.com>
+
+[ Upstream commit 3f0cdb945471f1abd1cf4d172190e9c489c5052a ]
+
+The SPLL2 on iMX8ULP is different with other frac PLLs, it can
+support VCO from 650Mhz to 1Ghz. According to RM, the MULT is
+using a range from 27 to 54, not some fixed values. If using
+current PLL implementation, some clock rate can't be supported.
+
+Fix the issue by adding new type for the SPLL2 and use MULT range
+to replace MULT table
+
+Fixes: 5f0601c47c33 ("clk: imx: Update the pllv4 to support imx8ulp")
+Reviewed-by: Peng Fan <peng.fan@nxp.com>
+Reviewed-by: Jacky Bai <ping.bai@nxp.com>
+Signed-off-by: Ye Li <ye.li@nxp.com>
+Signed-off-by: Peng Fan <peng.fan@nxp.com>
+Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
+Link: https://lore.kernel.org/r/20230625123340.4067536-1-peng.fan@oss.nxp.com
+Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/imx/clk-pllv4.c | 46 +++++++++++++++++++++++++++++--------
+ drivers/clk/imx/clk.h | 1 +
+ 2 files changed, 37 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/clk/imx/clk-pllv4.c b/drivers/clk/imx/clk-pllv4.c
+index 6e7e34571fc8d..9b136c951762c 100644
+--- a/drivers/clk/imx/clk-pllv4.c
++++ b/drivers/clk/imx/clk-pllv4.c
+@@ -44,11 +44,15 @@ struct clk_pllv4 {
+ u32 cfg_offset;
+ u32 num_offset;
+ u32 denom_offset;
++ bool use_mult_range;
+ };
+
+ /* Valid PLL MULT Table */
+ static const int pllv4_mult_table[] = {33, 27, 22, 20, 17, 16};
+
++/* Valid PLL MULT range, (max, min) */
++static const int pllv4_mult_range[] = {54, 27};
++
+ #define to_clk_pllv4(__hw) container_of(__hw, struct clk_pllv4, hw)
+
+ #define LOCK_TIMEOUT_US USEC_PER_MSEC
+@@ -94,17 +98,30 @@ static unsigned long clk_pllv4_recalc_rate(struct clk_hw *hw,
+ static long clk_pllv4_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+ {
++ struct clk_pllv4 *pll = to_clk_pllv4(hw);
+ unsigned long parent_rate = *prate;
+ unsigned long round_rate, i;
+ u32 mfn, mfd = DEFAULT_MFD;
+ bool found = false;
+ u64 temp64;
+-
+- for (i = 0; i < ARRAY_SIZE(pllv4_mult_table); i++) {
+- round_rate = parent_rate * pllv4_mult_table[i];
+- if (rate >= round_rate) {
++ u32 mult;
++
++ if (pll->use_mult_range) {
++ temp64 = (u64)rate;
++ do_div(temp64, parent_rate);
++ mult = temp64;
++ if (mult >= pllv4_mult_range[1] &&
++ mult <= pllv4_mult_range[0]) {
++ round_rate = parent_rate * mult;
+ found = true;
+- break;
++ }
++ } else {
++ for (i = 0; i < ARRAY_SIZE(pllv4_mult_table); i++) {
++ round_rate = parent_rate * pllv4_mult_table[i];
++ if (rate >= round_rate) {
++ found = true;
++ break;
++ }
+ }
+ }
+
+@@ -138,14 +155,20 @@ static long clk_pllv4_round_rate(struct clk_hw *hw, unsigned long rate,
+ return round_rate + (u32)temp64;
+ }
+
+-static bool clk_pllv4_is_valid_mult(unsigned int mult)
++static bool clk_pllv4_is_valid_mult(struct clk_pllv4 *pll, unsigned int mult)
+ {
+ int i;
+
+ /* check if mult is in valid MULT table */
+- for (i = 0; i < ARRAY_SIZE(pllv4_mult_table); i++) {
+- if (pllv4_mult_table[i] == mult)
++ if (pll->use_mult_range) {
++ if (mult >= pllv4_mult_range[1] &&
++ mult <= pllv4_mult_range[0])
+ return true;
++ } else {
++ for (i = 0; i < ARRAY_SIZE(pllv4_mult_table); i++) {
++ if (pllv4_mult_table[i] == mult)
++ return true;
++ }
+ }
+
+ return false;
+@@ -160,7 +183,7 @@ static int clk_pllv4_set_rate(struct clk_hw *hw, unsigned long rate,
+
+ mult = rate / parent_rate;
+
+- if (!clk_pllv4_is_valid_mult(mult))
++ if (!clk_pllv4_is_valid_mult(pll, mult))
+ return -EINVAL;
+
+ if (parent_rate <= MAX_MFD)
+@@ -227,10 +250,13 @@ struct clk_hw *imx_clk_hw_pllv4(enum imx_pllv4_type type, const char *name,
+
+ pll->base = base;
+
+- if (type == IMX_PLLV4_IMX8ULP) {
++ if (type == IMX_PLLV4_IMX8ULP ||
++ type == IMX_PLLV4_IMX8ULP_1GHZ) {
+ pll->cfg_offset = IMX8ULP_PLL_CFG_OFFSET;
+ pll->num_offset = IMX8ULP_PLL_NUM_OFFSET;
+ pll->denom_offset = IMX8ULP_PLL_DENOM_OFFSET;
++ if (type == IMX_PLLV4_IMX8ULP_1GHZ)
++ pll->use_mult_range = true;
+ } else {
+ pll->cfg_offset = PLL_CFG_OFFSET;
+ pll->num_offset = PLL_NUM_OFFSET;
+diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
+index 1031468701d7f..6f752f07d125d 100644
+--- a/drivers/clk/imx/clk.h
++++ b/drivers/clk/imx/clk.h
+@@ -46,6 +46,7 @@ enum imx_pll14xx_type {
+ enum imx_pllv4_type {
+ IMX_PLLV4_IMX7ULP,
+ IMX_PLLV4_IMX8ULP,
++ IMX_PLLV4_IMX8ULP_1GHZ,
+ };
+
+ enum imx_pfdv2_type {
+--
+2.40.1
+
--- /dev/null
+From 8ee41f2498e78e5cb301e9ebd47d33cead334d6e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Jul 2023 16:21:49 +0200
+Subject: clk: imx8mp: fix sai4 clock
+
+From: Marco Felsch <m.felsch@pengutronix.de>
+
+[ Upstream commit c30f600f1f41dcf5ef0fb02e9a201f9b2e8f31bd ]
+
+The reference manual don't mention a SAI4 hardware block. This would be
+clock slice 78 which is skipped (TRM, page 237). Remove any reference to
+this clock to align the driver with the reality.
+
+Fixes: 9c140d992676 ("clk: imx: Add support for i.MX8MP clock driver")
+Acked-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
+Link: https://lore.kernel.org/r/20230731142150.3186650-1-m.felsch@pengutronix.de
+Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/imx/clk-imx8mp.c | 5 -----
+ 1 file changed, 5 deletions(-)
+
+diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c
+index 1469249386dd8..670aa2bab3017 100644
+--- a/drivers/clk/imx/clk-imx8mp.c
++++ b/drivers/clk/imx/clk-imx8mp.c
+@@ -178,10 +178,6 @@ static const char * const imx8mp_sai3_sels[] = {"osc_24m", "audio_pll1_out", "au
+ "video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+ "clk_ext3", "clk_ext4", };
+
+-static const char * const imx8mp_sai4_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
+- "video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+- "clk_ext1", "clk_ext2", };
+-
+ static const char * const imx8mp_sai5_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
+ "video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+ "clk_ext2", "clk_ext3", };
+@@ -567,7 +563,6 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
+ hws[IMX8MP_CLK_SAI1] = imx8m_clk_hw_composite("sai1", imx8mp_sai1_sels, ccm_base + 0xa580);
+ hws[IMX8MP_CLK_SAI2] = imx8m_clk_hw_composite("sai2", imx8mp_sai2_sels, ccm_base + 0xa600);
+ hws[IMX8MP_CLK_SAI3] = imx8m_clk_hw_composite("sai3", imx8mp_sai3_sels, ccm_base + 0xa680);
+- hws[IMX8MP_CLK_SAI4] = imx8m_clk_hw_composite("sai4", imx8mp_sai4_sels, ccm_base + 0xa700);
+ hws[IMX8MP_CLK_SAI5] = imx8m_clk_hw_composite("sai5", imx8mp_sai5_sels, ccm_base + 0xa780);
+ hws[IMX8MP_CLK_SAI6] = imx8m_clk_hw_composite("sai6", imx8mp_sai6_sels, ccm_base + 0xa800);
+ hws[IMX8MP_CLK_ENET_QOS] = imx8m_clk_hw_composite("enet_qos", imx8mp_enet_qos_sels, ccm_base + 0xa880);
+--
+2.40.1
+
--- /dev/null
+From 8600692f68de451499104999ccaa4fe056086e04 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Jul 2023 10:51:56 +0200
+Subject: clk: qcom: dispcc-sc8280xp: Use ret registers on GDSCs
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit 20e1d75bc043c5ec1fd8f5169fde17db89eb11c3 ]
+
+The DISP_CC GDSCs have not been instructed to use the ret registers.
+Fix that.
+
+Fixes: 4a66e76fdb6d ("clk: qcom: Add SC8280XP display clock controller")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230725-topic-8280_dispcc_gdsc-v1-1-236590060531@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/dispcc-sc8280xp.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/clk/qcom/dispcc-sc8280xp.c b/drivers/clk/qcom/dispcc-sc8280xp.c
+index 167470beb3691..30f636b9f0ec8 100644
+--- a/drivers/clk/qcom/dispcc-sc8280xp.c
++++ b/drivers/clk/qcom/dispcc-sc8280xp.c
+@@ -3057,7 +3057,7 @@ static struct gdsc disp0_mdss_gdsc = {
+ .name = "disp0_mdss_gdsc",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+- .flags = HW_CTRL,
++ .flags = HW_CTRL | RETAIN_FF_ENABLE,
+ };
+
+ static struct gdsc disp1_mdss_gdsc = {
+@@ -3069,7 +3069,7 @@ static struct gdsc disp1_mdss_gdsc = {
+ .name = "disp1_mdss_gdsc",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+- .flags = HW_CTRL,
++ .flags = HW_CTRL | RETAIN_FF_ENABLE,
+ };
+
+ static struct gdsc disp0_mdss_int2_gdsc = {
+@@ -3081,7 +3081,7 @@ static struct gdsc disp0_mdss_int2_gdsc = {
+ .name = "disp0_mdss_int2_gdsc",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+- .flags = HW_CTRL,
++ .flags = HW_CTRL | RETAIN_FF_ENABLE,
+ };
+
+ static struct gdsc disp1_mdss_int2_gdsc = {
+@@ -3093,7 +3093,7 @@ static struct gdsc disp1_mdss_int2_gdsc = {
+ .name = "disp1_mdss_int2_gdsc",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+- .flags = HW_CTRL,
++ .flags = HW_CTRL | RETAIN_FF_ENABLE,
+ };
+
+ static struct gdsc *disp0_cc_sc8280xp_gdscs[] = {
+--
+2.40.1
+
--- /dev/null
+From d8465519d3f846d8d1dcb16ce80ac35ea6155a08 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Aug 2023 16:27:36 +0530
+Subject: clk: qcom: gcc-qdu1000: Fix clkref clocks handling
+
+From: Imran Shaik <quic_imrashai@quicinc.com>
+
+[ Upstream commit 2524dae5cd453ca39e8ba1b95c2755a8a2d94059 ]
+
+Update the GCC clkref clock's halt_check to BRANCH_HALT, as it's
+status bit is not inverted in the latest hardware version of QDU1000
+and QRU1000 SoCs. While at it, fix the gcc clkref clock ops as well.
+
+Fixes: 1c9efb0bc040 ("clk: qcom: Add QDU1000 and QRU1000 GCC support")
+Signed-off-by: Imran Shaik <quic_imrashai@quicinc.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230803105741.2292309-4-quic_imrashai@quicinc.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-qdu1000.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/clk/qcom/gcc-qdu1000.c b/drivers/clk/qcom/gcc-qdu1000.c
+index c00d26a3e6df5..8df7b79839680 100644
+--- a/drivers/clk/qcom/gcc-qdu1000.c
++++ b/drivers/clk/qcom/gcc-qdu1000.c
+@@ -1447,14 +1447,13 @@ static struct clk_branch gcc_pcie_0_cfg_ahb_clk = {
+
+ static struct clk_branch gcc_pcie_0_clkref_en = {
+ .halt_reg = 0x9c004,
+- .halt_bit = 31,
+- .halt_check = BRANCH_HALT_ENABLE,
++ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x9c004,
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "gcc_pcie_0_clkref_en",
+- .ops = &clk_branch_ops,
++ .ops = &clk_branch2_ops,
+ },
+ },
+ };
+@@ -2274,14 +2273,13 @@ static struct clk_branch gcc_tsc_etu_clk = {
+
+ static struct clk_branch gcc_usb2_clkref_en = {
+ .halt_reg = 0x9c008,
+- .halt_bit = 31,
+- .halt_check = BRANCH_HALT_ENABLE,
++ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x9c008,
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "gcc_usb2_clkref_en",
+- .ops = &clk_branch_ops,
++ .ops = &clk_branch2_ops,
+ },
+ },
+ };
+--
+2.40.1
+
--- /dev/null
+From 8ab93bab63b303a07afa8a668b52b7fc40ac1e4e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Aug 2023 16:27:35 +0530
+Subject: clk: qcom: gcc-qdu1000: Fix gcc_pcie_0_pipe_clk_src clock handling
+
+From: Imran Shaik <quic_imrashai@quicinc.com>
+
+[ Upstream commit b311f5d3c4749259043a9a458a8db07915210142 ]
+
+Fix the gcc pcie pipe clock handling as per the clk_regmap_phy_mux_ops
+implementation to let the clock framework automatically park the clock
+at XO when the clock is switched off and restore the parent when the
+clock is switched on.
+
+Fixes: 1c9efb0bc040 ("clk: qcom: Add QDU1000 and QRU1000 GCC support")
+Co-developed-by: Taniya Das <quic_tdas@quicinc.com>
+Signed-off-by: Taniya Das <quic_tdas@quicinc.com>
+Signed-off-by: Imran Shaik <quic_imrashai@quicinc.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230803105741.2292309-3-quic_imrashai@quicinc.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-qdu1000.c | 23 ++++++-----------------
+ 1 file changed, 6 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/clk/qcom/gcc-qdu1000.c b/drivers/clk/qcom/gcc-qdu1000.c
+index 5051769ad90c7..c00d26a3e6df5 100644
+--- a/drivers/clk/qcom/gcc-qdu1000.c
++++ b/drivers/clk/qcom/gcc-qdu1000.c
+@@ -1,6 +1,6 @@
+ // SPDX-License-Identifier: GPL-2.0-only
+ /*
+- * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
++ * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+ #include <linux/clk-provider.h>
+@@ -370,16 +370,6 @@ static const struct clk_parent_data gcc_parent_data_6[] = {
+ { .index = DT_TCXO_IDX },
+ };
+
+-static const struct parent_map gcc_parent_map_7[] = {
+- { P_PCIE_0_PIPE_CLK, 0 },
+- { P_BI_TCXO, 2 },
+-};
+-
+-static const struct clk_parent_data gcc_parent_data_7[] = {
+- { .index = DT_PCIE_0_PIPE_CLK_IDX },
+- { .index = DT_TCXO_IDX },
+-};
+-
+ static const struct parent_map gcc_parent_map_8[] = {
+ { P_BI_TCXO, 0 },
+ { P_GCC_GPLL0_OUT_MAIN, 1 },
+@@ -439,16 +429,15 @@ static struct clk_regmap_mux gcc_pcie_0_phy_aux_clk_src = {
+ },
+ };
+
+-static struct clk_regmap_mux gcc_pcie_0_pipe_clk_src = {
++static struct clk_regmap_phy_mux gcc_pcie_0_pipe_clk_src = {
+ .reg = 0x9d064,
+- .shift = 0,
+- .width = 2,
+- .parent_map = gcc_parent_map_7,
+ .clkr = {
+ .hw.init = &(const struct clk_init_data) {
+ .name = "gcc_pcie_0_pipe_clk_src",
+- .parent_data = gcc_parent_data_7,
+- .num_parents = ARRAY_SIZE(gcc_parent_data_7),
++ .parent_data = &(const struct clk_parent_data){
++ .index = DT_PCIE_0_PIPE_CLK_IDX,
++ },
++ .num_parents = 1,
+ .ops = &clk_regmap_phy_mux_ops,
+ },
+ },
+--
+2.40.1
+
--- /dev/null
+From de0fbeb2e3f8ea832b591b4f5eb5ecbafe1c0f75 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Aug 2023 16:27:37 +0530
+Subject: clk: qcom: gcc-qdu1000: Register gcc_gpll1_out_even clock
+
+From: Imran Shaik <quic_imrashai@quicinc.com>
+
+[ Upstream commit 06d71fa10f2e507444c6759328a6c19d38eab788 ]
+
+gcc_gpll1_out_even clock is referenced as a parent, but not registered
+with the clock framework. Hence add support to register the same.
+
+Fixes: 1c9efb0bc040 ("clk: qcom: Add QDU1000 and QRU1000 GCC support")
+Signed-off-by: Imran Shaik <quic_imrashai@quicinc.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230803105741.2292309-5-quic_imrashai@quicinc.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-qdu1000.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/clk/qcom/gcc-qdu1000.c b/drivers/clk/qcom/gcc-qdu1000.c
+index 8df7b79839680..626c5afed7806 100644
+--- a/drivers/clk/qcom/gcc-qdu1000.c
++++ b/drivers/clk/qcom/gcc-qdu1000.c
+@@ -2521,6 +2521,7 @@ static struct clk_regmap *gcc_qdu1000_clocks[] = {
+ [GCC_AGGRE_NOC_ECPRI_GSI_CLK] = &gcc_aggre_noc_ecpri_gsi_clk.clkr,
+ [GCC_PCIE_0_PHY_AUX_CLK_SRC] = &gcc_pcie_0_phy_aux_clk_src.clkr,
+ [GCC_PCIE_0_PIPE_CLK_SRC] = &gcc_pcie_0_pipe_clk_src.clkr,
++ [GCC_GPLL1_OUT_EVEN] = &gcc_gpll1_out_even.clkr,
+ };
+
+ static const struct qcom_reset_map gcc_qdu1000_resets[] = {
+--
+2.40.1
+
--- /dev/null
+From dc546eea2b621dabbb86a1ce755cdeec540273fa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 23 Jul 2023 21:05:02 +0200
+Subject: clk: qcom: gcc-sc7180: Fix up gcc_sdcc2_apps_clk_src
+
+From: David Wronek <davidwronek@gmail.com>
+
+[ Upstream commit fd0b5ba87ad5709f0fd3d2bc4b7870494a75f96a ]
+
+Set .flags = CLK_OPS_PARENT_ENABLE to fix "gcc_sdcc2_apps_clk_src: rcg
+didn't update its configuration" error.
+
+Fixes: 17269568f726 ("clk: qcom: Add Global Clock controller (GCC) driver for SC7180")
+Signed-off-by: David Wronek <davidwronek@gmail.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230723190725.1619193-2-davidwronek@gmail.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-sc7180.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/clk/qcom/gcc-sc7180.c b/drivers/clk/qcom/gcc-sc7180.c
+index cef3c77564cfd..49f36e1df4fa8 100644
+--- a/drivers/clk/qcom/gcc-sc7180.c
++++ b/drivers/clk/qcom/gcc-sc7180.c
+@@ -651,6 +651,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = {
+ .name = "gcc_sdcc2_apps_clk_src",
+ .parent_data = gcc_parent_data_5,
+ .num_parents = ARRAY_SIZE(gcc_parent_data_5),
++ .flags = CLK_OPS_PARENT_ENABLE,
+ .ops = &clk_rcg2_floor_ops,
+ },
+ };
+--
+2.40.1
+
--- /dev/null
+From c4945f27fc653b1b79c0a03e036961d7397376bb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Jun 2023 19:48:06 +0200
+Subject: clk: qcom: gcc-sc8280xp: Add missing GDSC flags
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit 2fd02de27054576a4a8c89302e2f77122c55e957 ]
+
+All of the 8280's GCC GDSCs can and should use the retain registers so
+as not to lose their state when entering lower power modes.
+
+Fixes: d65d005f9a6c ("clk: qcom: add sc8280xp GCC driver")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Acked-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/r/20230620-topic-sc8280_gccgdsc-v2-1-562c1428c10d@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-sc8280xp.c | 21 ++++++++++++++-------
+ 1 file changed, 14 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/clk/qcom/gcc-sc8280xp.c b/drivers/clk/qcom/gcc-sc8280xp.c
+index 04a99dbaa57e0..43c518e5c986b 100644
+--- a/drivers/clk/qcom/gcc-sc8280xp.c
++++ b/drivers/clk/qcom/gcc-sc8280xp.c
+@@ -6760,7 +6760,7 @@ static struct gdsc pcie_0_tunnel_gdsc = {
+ .name = "pcie_0_tunnel_gdsc",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+- .flags = VOTABLE,
++ .flags = VOTABLE | RETAIN_FF_ENABLE,
+ };
+
+ static struct gdsc pcie_1_tunnel_gdsc = {
+@@ -6771,7 +6771,7 @@ static struct gdsc pcie_1_tunnel_gdsc = {
+ .name = "pcie_1_tunnel_gdsc",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+- .flags = VOTABLE,
++ .flags = VOTABLE | RETAIN_FF_ENABLE,
+ };
+
+ /*
+@@ -6786,7 +6786,7 @@ static struct gdsc pcie_2a_gdsc = {
+ .name = "pcie_2a_gdsc",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+- .flags = VOTABLE | ALWAYS_ON,
++ .flags = VOTABLE | RETAIN_FF_ENABLE | ALWAYS_ON,
+ };
+
+ static struct gdsc pcie_2b_gdsc = {
+@@ -6797,7 +6797,7 @@ static struct gdsc pcie_2b_gdsc = {
+ .name = "pcie_2b_gdsc",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+- .flags = VOTABLE | ALWAYS_ON,
++ .flags = VOTABLE | RETAIN_FF_ENABLE | ALWAYS_ON,
+ };
+
+ static struct gdsc pcie_3a_gdsc = {
+@@ -6808,7 +6808,7 @@ static struct gdsc pcie_3a_gdsc = {
+ .name = "pcie_3a_gdsc",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+- .flags = VOTABLE | ALWAYS_ON,
++ .flags = VOTABLE | RETAIN_FF_ENABLE | ALWAYS_ON,
+ };
+
+ static struct gdsc pcie_3b_gdsc = {
+@@ -6819,7 +6819,7 @@ static struct gdsc pcie_3b_gdsc = {
+ .name = "pcie_3b_gdsc",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+- .flags = VOTABLE | ALWAYS_ON,
++ .flags = VOTABLE | RETAIN_FF_ENABLE | ALWAYS_ON,
+ };
+
+ static struct gdsc pcie_4_gdsc = {
+@@ -6830,7 +6830,7 @@ static struct gdsc pcie_4_gdsc = {
+ .name = "pcie_4_gdsc",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+- .flags = VOTABLE | ALWAYS_ON,
++ .flags = VOTABLE | RETAIN_FF_ENABLE | ALWAYS_ON,
+ };
+
+ static struct gdsc ufs_card_gdsc = {
+@@ -6839,6 +6839,7 @@ static struct gdsc ufs_card_gdsc = {
+ .name = "ufs_card_gdsc",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
++ .flags = RETAIN_FF_ENABLE,
+ };
+
+ static struct gdsc ufs_phy_gdsc = {
+@@ -6847,6 +6848,7 @@ static struct gdsc ufs_phy_gdsc = {
+ .name = "ufs_phy_gdsc",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
++ .flags = RETAIN_FF_ENABLE,
+ };
+
+ static struct gdsc usb30_mp_gdsc = {
+@@ -6855,6 +6857,7 @@ static struct gdsc usb30_mp_gdsc = {
+ .name = "usb30_mp_gdsc",
+ },
+ .pwrsts = PWRSTS_RET_ON,
++ .flags = RETAIN_FF_ENABLE,
+ };
+
+ static struct gdsc usb30_prim_gdsc = {
+@@ -6863,6 +6866,7 @@ static struct gdsc usb30_prim_gdsc = {
+ .name = "usb30_prim_gdsc",
+ },
+ .pwrsts = PWRSTS_RET_ON,
++ .flags = RETAIN_FF_ENABLE,
+ };
+
+ static struct gdsc usb30_sec_gdsc = {
+@@ -6871,6 +6875,7 @@ static struct gdsc usb30_sec_gdsc = {
+ .name = "usb30_sec_gdsc",
+ },
+ .pwrsts = PWRSTS_RET_ON,
++ .flags = RETAIN_FF_ENABLE,
+ };
+
+ static struct gdsc emac_0_gdsc = {
+@@ -6879,6 +6884,7 @@ static struct gdsc emac_0_gdsc = {
+ .name = "emac_0_gdsc",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
++ .flags = RETAIN_FF_ENABLE,
+ };
+
+ static struct gdsc emac_1_gdsc = {
+@@ -6887,6 +6893,7 @@ static struct gdsc emac_1_gdsc = {
+ .name = "emac_1_gdsc",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
++ .flags = RETAIN_FF_ENABLE,
+ };
+
+ static struct clk_regmap *gcc_sc8280xp_clocks[] = {
+--
+2.40.1
+
--- /dev/null
+From 456a47e272bf4ae87d619fdbe724a321f90c81e3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Jun 2023 19:48:08 +0200
+Subject: clk: qcom: gcc-sc8280xp: Add missing GDSCs
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit 4712eb7ff85bd3dd09c6668b8de4080e02b3eea9 ]
+
+There are 10 more GDSCs that we've not been caring about, and by extension
+(and perhaps even more importantly), not putting to sleep. Add them.
+
+Fixes: d65d005f9a6c ("clk: qcom: add sc8280xp GCC driver")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Acked-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/r/20230620-topic-sc8280_gccgdsc-v2-3-562c1428c10d@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-sc8280xp.c | 100 ++++++++++++++++++++++++++++++++
+ 1 file changed, 100 insertions(+)
+
+diff --git a/drivers/clk/qcom/gcc-sc8280xp.c b/drivers/clk/qcom/gcc-sc8280xp.c
+index 43c518e5c986b..57bbd609151cd 100644
+--- a/drivers/clk/qcom/gcc-sc8280xp.c
++++ b/drivers/clk/qcom/gcc-sc8280xp.c
+@@ -6896,6 +6896,96 @@ static struct gdsc emac_1_gdsc = {
+ .flags = RETAIN_FF_ENABLE,
+ };
+
++static struct gdsc usb4_1_gdsc = {
++ .gdscr = 0xb8004,
++ .pd = {
++ .name = "usb4_1_gdsc",
++ },
++ .pwrsts = PWRSTS_OFF_ON,
++ .flags = RETAIN_FF_ENABLE,
++};
++
++static struct gdsc usb4_gdsc = {
++ .gdscr = 0x2a004,
++ .pd = {
++ .name = "usb4_gdsc",
++ },
++ .pwrsts = PWRSTS_OFF_ON,
++ .flags = RETAIN_FF_ENABLE,
++};
++
++static struct gdsc hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc = {
++ .gdscr = 0x7d050,
++ .pd = {
++ .name = "hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc",
++ },
++ .pwrsts = PWRSTS_OFF_ON,
++ .flags = VOTABLE,
++};
++
++static struct gdsc hlos1_vote_mmnoc_mmu_tbu_hf1_gdsc = {
++ .gdscr = 0x7d058,
++ .pd = {
++ .name = "hlos1_vote_mmnoc_mmu_tbu_hf1_gdsc",
++ },
++ .pwrsts = PWRSTS_OFF_ON,
++ .flags = VOTABLE,
++};
++
++static struct gdsc hlos1_vote_mmnoc_mmu_tbu_sf0_gdsc = {
++ .gdscr = 0x7d054,
++ .pd = {
++ .name = "hlos1_vote_mmnoc_mmu_tbu_sf0_gdsc",
++ },
++ .pwrsts = PWRSTS_OFF_ON,
++ .flags = VOTABLE,
++};
++
++static struct gdsc hlos1_vote_mmnoc_mmu_tbu_sf1_gdsc = {
++ .gdscr = 0x7d06c,
++ .pd = {
++ .name = "hlos1_vote_mmnoc_mmu_tbu_sf1_gdsc",
++ },
++ .pwrsts = PWRSTS_OFF_ON,
++ .flags = VOTABLE,
++};
++
++static struct gdsc hlos1_vote_turing_mmu_tbu0_gdsc = {
++ .gdscr = 0x7d05c,
++ .pd = {
++ .name = "hlos1_vote_turing_mmu_tbu0_gdsc",
++ },
++ .pwrsts = PWRSTS_OFF_ON,
++ .flags = VOTABLE,
++};
++
++static struct gdsc hlos1_vote_turing_mmu_tbu1_gdsc = {
++ .gdscr = 0x7d060,
++ .pd = {
++ .name = "hlos1_vote_turing_mmu_tbu1_gdsc",
++ },
++ .pwrsts = PWRSTS_OFF_ON,
++ .flags = VOTABLE,
++};
++
++static struct gdsc hlos1_vote_turing_mmu_tbu2_gdsc = {
++ .gdscr = 0x7d0a0,
++ .pd = {
++ .name = "hlos1_vote_turing_mmu_tbu2_gdsc",
++ },
++ .pwrsts = PWRSTS_OFF_ON,
++ .flags = VOTABLE,
++};
++
++static struct gdsc hlos1_vote_turing_mmu_tbu3_gdsc = {
++ .gdscr = 0x7d0a4,
++ .pd = {
++ .name = "hlos1_vote_turing_mmu_tbu3_gdsc",
++ },
++ .pwrsts = PWRSTS_OFF_ON,
++ .flags = VOTABLE,
++};
++
+ static struct clk_regmap *gcc_sc8280xp_clocks[] = {
+ [GCC_AGGRE_NOC_PCIE0_TUNNEL_AXI_CLK] = &gcc_aggre_noc_pcie0_tunnel_axi_clk.clkr,
+ [GCC_AGGRE_NOC_PCIE1_TUNNEL_AXI_CLK] = &gcc_aggre_noc_pcie1_tunnel_axi_clk.clkr,
+@@ -7376,6 +7466,16 @@ static struct gdsc *gcc_sc8280xp_gdscs[] = {
+ [USB30_SEC_GDSC] = &usb30_sec_gdsc,
+ [EMAC_0_GDSC] = &emac_0_gdsc,
+ [EMAC_1_GDSC] = &emac_1_gdsc,
++ [USB4_1_GDSC] = &usb4_1_gdsc,
++ [USB4_GDSC] = &usb4_gdsc,
++ [HLOS1_VOTE_MMNOC_MMU_TBU_HF0_GDSC] = &hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc,
++ [HLOS1_VOTE_MMNOC_MMU_TBU_HF1_GDSC] = &hlos1_vote_mmnoc_mmu_tbu_hf1_gdsc,
++ [HLOS1_VOTE_MMNOC_MMU_TBU_SF0_GDSC] = &hlos1_vote_mmnoc_mmu_tbu_sf0_gdsc,
++ [HLOS1_VOTE_MMNOC_MMU_TBU_SF1_GDSC] = &hlos1_vote_mmnoc_mmu_tbu_sf1_gdsc,
++ [HLOS1_VOTE_TURING_MMU_TBU0_GDSC] = &hlos1_vote_turing_mmu_tbu0_gdsc,
++ [HLOS1_VOTE_TURING_MMU_TBU1_GDSC] = &hlos1_vote_turing_mmu_tbu1_gdsc,
++ [HLOS1_VOTE_TURING_MMU_TBU2_GDSC] = &hlos1_vote_turing_mmu_tbu2_gdsc,
++ [HLOS1_VOTE_TURING_MMU_TBU3_GDSC] = &hlos1_vote_turing_mmu_tbu3_gdsc,
+ };
+
+ static const struct clk_rcg_dfs_data gcc_dfs_clocks[] = {
+--
+2.40.1
+
--- /dev/null
+From 2aeae681c5143f01a0413fb105615d0c4c121774 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Aug 2023 16:09:30 +0200
+Subject: clk: qcom: gcc-sm6350: Fix gcc_sdcc2_apps_clk_src
+
+From: Luca Weiss <luca.weiss@fairphone.com>
+
+[ Upstream commit df04d166d1f346dbf740bbea64a3bed3e7f14c8d ]
+
+GPLL7 is not on by default, which causes a "gcc_sdcc2_apps_clk_src: rcg
+didn't update its configuration" error when booting. Set .flags =
+CLK_OPS_PARENT_ENABLE to fix the error.
+
+Fixes: 131abae905df ("clk: qcom: Add SM6350 GCC driver")
+Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230804-sm6350-sdcc2-v1-1-3d946927d37d@fairphone.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-sm6350.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/clk/qcom/gcc-sm6350.c b/drivers/clk/qcom/gcc-sm6350.c
+index 9b4e4bb059635..cf4a7b6e0b23a 100644
+--- a/drivers/clk/qcom/gcc-sm6350.c
++++ b/drivers/clk/qcom/gcc-sm6350.c
+@@ -641,6 +641,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = {
+ .name = "gcc_sdcc2_apps_clk_src",
+ .parent_data = gcc_parent_data_8,
+ .num_parents = ARRAY_SIZE(gcc_parent_data_8),
++ .flags = CLK_OPS_PARENT_ENABLE,
+ .ops = &clk_rcg2_floor_ops,
+ },
+ };
+--
+2.40.1
+
--- /dev/null
+From 602f911ec97e5c85d09addccb9887fbe0198f2c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Jun 2023 22:19:44 +0300
+Subject: clk: qcom: gcc-sm7150: Add CLK_OPS_PARENT_ENABLE to sdcc2 rcg
+
+From: Danila Tikhonov <danila@jiaxyga.com>
+
+[ Upstream commit ff19022b9112d6bbd7c117c83e944cb21b438e91 ]
+
+Set .flags = CLK_OPS_PARENT_ENABLE to fix "gcc_sdcc2_apps_clk_src: rcg
+didn't update its configuration" error.
+
+Fixes: a808d58ddf29 ("clk: qcom: Add Global Clock Controller (GCC) driver for SM7150")
+Signed-off-by: Danila Tikhonov <danila@jiaxyga.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230630191944.20282-1-danila@jiaxyga.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-sm7150.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/clk/qcom/gcc-sm7150.c b/drivers/clk/qcom/gcc-sm7150.c
+index 6b628178f62c4..6da87f0436d0c 100644
+--- a/drivers/clk/qcom/gcc-sm7150.c
++++ b/drivers/clk/qcom/gcc-sm7150.c
+@@ -739,6 +739,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = {
+ .parent_data = gcc_parent_data_6,
+ .num_parents = ARRAY_SIZE(gcc_parent_data_6),
+ .ops = &clk_rcg2_floor_ops,
++ .flags = CLK_OPS_PARENT_ENABLE,
+ },
+ };
+
+--
+2.40.1
+
--- /dev/null
+From 052e8c7c0a34d4016dfde52541813b51a96a8c9d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Aug 2023 14:04:00 -0700
+Subject: clk: qcom: gcc-sm8250: Fix gcc_sdcc2_apps_clk_src
+
+From: Patrick Whewell <patrick.whewell@sightlineapplications.com>
+
+[ Upstream commit 783cb693828ce487cf0bc6ad16cbcf2caae6f8d9 ]
+
+GPLL9 is not on by default, which causes a "gcc_sdcc2_apps_clk_src: rcg
+didn't update its configuration" error when booting. Set .flags =
+CLK_OPS_PARENT_ENABLE to fix the error.
+
+Fixes: 3e5770921a88 ("clk: qcom: gcc: Add global clock controller driver for SM8250")
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Signed-off-by: Patrick Whewell <patrick.whewell@sightlineapplications.com>
+Reviewed-by: Vinod Koul <vkoul@kernel.org>
+Link: https://lore.kernel.org/r/20230802210359.408-1-patrick.whewell@sightlineapplications.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-sm8250.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/clk/qcom/gcc-sm8250.c b/drivers/clk/qcom/gcc-sm8250.c
+index b6cf4bc88d4d4..d3c75bb55946a 100644
+--- a/drivers/clk/qcom/gcc-sm8250.c
++++ b/drivers/clk/qcom/gcc-sm8250.c
+@@ -721,6 +721,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = {
+ .name = "gcc_sdcc2_apps_clk_src",
+ .parent_data = gcc_parent_data_4,
+ .num_parents = ARRAY_SIZE(gcc_parent_data_4),
++ .flags = CLK_OPS_PARENT_ENABLE,
+ .ops = &clk_rcg2_floor_ops,
+ },
+ };
+--
+2.40.1
+
--- /dev/null
+From a604b9d0af0834b61d83c321123c5217fc3e22dd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Aug 2023 19:35:53 +0200
+Subject: clk: qcom: gcc-sm8450: Use floor ops for SDCC RCGs
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit a27ac3806b0a0e6954fb5967223b8635242e5b8f ]
+
+Use the floor ops to prevent warnings like this at suspend exit and boot:
+
+mmc0: Card appears overclocked; req 800000 Hz, actual 25000000 Hz
+
+Fixes: db0c944ee92b ("clk: qcom: Add clock driver for SM8450")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Reviewed-by: Vinod Koul <vkoul@kernel.org>
+Link: https://lore.kernel.org/r/20230811-topic-8450_clk-v1-1-88031478d548@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-sm8450.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/clk/qcom/gcc-sm8450.c b/drivers/clk/qcom/gcc-sm8450.c
+index 84764cc3db4ff..1d912f8a7243c 100644
+--- a/drivers/clk/qcom/gcc-sm8450.c
++++ b/drivers/clk/qcom/gcc-sm8450.c
+@@ -904,7 +904,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = {
+ .parent_data = gcc_parent_data_7,
+ .num_parents = ARRAY_SIZE(gcc_parent_data_7),
+ .flags = CLK_SET_RATE_PARENT,
+- .ops = &clk_rcg2_ops,
++ .ops = &clk_rcg2_floor_ops,
+ },
+ };
+
+@@ -926,7 +926,7 @@ static struct clk_rcg2 gcc_sdcc4_apps_clk_src = {
+ .parent_data = gcc_parent_data_0,
+ .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+ .flags = CLK_SET_RATE_PARENT,
+- .ops = &clk_rcg2_ops,
++ .ops = &clk_rcg2_floor_ops,
+ },
+ };
+
+--
+2.40.1
+
--- /dev/null
+From 26b6eb741ab34e86af011c9f63dfc08e9e64cfdf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Jun 2023 13:35:33 +0200
+Subject: clk: qcom: gpucc-sm6350: Fix clock source names
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit 743913b343a3ec2510fe3c0dfaff03d049659922 ]
+
+fw_name for GCC inputs didn't match the bindings. Fix it.
+
+Fixes: 013804a727a0 ("clk: qcom: Add GPU clock controller driver for SM6350")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230315-topic-lagoon_gpu-v2-2-afcdfb18bb13@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gpucc-sm6350.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/clk/qcom/gpucc-sm6350.c b/drivers/clk/qcom/gpucc-sm6350.c
+index a9887d1f0ed71..0bcbba2a29436 100644
+--- a/drivers/clk/qcom/gpucc-sm6350.c
++++ b/drivers/clk/qcom/gpucc-sm6350.c
+@@ -132,8 +132,8 @@ static const struct clk_parent_data gpu_cc_parent_data_0[] = {
+ { .index = DT_BI_TCXO, .fw_name = "bi_tcxo" },
+ { .hw = &gpu_cc_pll0.clkr.hw },
+ { .hw = &gpu_cc_pll1.clkr.hw },
+- { .index = DT_GPLL0_OUT_MAIN, .fw_name = "gcc_gpu_gpll0_clk" },
+- { .index = DT_GPLL0_OUT_MAIN_DIV, .fw_name = "gcc_gpu_gpll0_div_clk" },
++ { .index = DT_GPLL0_OUT_MAIN, .fw_name = "gcc_gpu_gpll0_clk_src" },
++ { .index = DT_GPLL0_OUT_MAIN_DIV, .fw_name = "gcc_gpu_gpll0_div_clk_src" },
+ };
+
+ static const struct parent_map gpu_cc_parent_map_1[] = {
+@@ -151,7 +151,7 @@ static const struct clk_parent_data gpu_cc_parent_data_1[] = {
+ { .hw = &gpu_cc_pll0.clkr.hw },
+ { .hw = &gpu_cc_pll1.clkr.hw },
+ { .hw = &gpu_cc_pll1.clkr.hw },
+- { .index = DT_GPLL0_OUT_MAIN, .fw_name = "gcc_gpu_gpll0_clk" },
++ { .index = DT_GPLL0_OUT_MAIN, .fw_name = "gcc_gpu_gpll0_clk_src" },
+ };
+
+ static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = {
+--
+2.40.1
+
--- /dev/null
+From 287cc0465d243923cb7c9785dc99050e1a618fc7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Jun 2023 13:35:32 +0200
+Subject: clk: qcom: gpucc-sm6350: Introduce index-based clk lookup
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit f6f89d194e4ddcfe197ac8a05ed4161f642a5c68 ]
+
+Add the nowadays-prefered and marginally faster way of looking up parent
+clocks in the device tree. It also allows for clock-names-independent
+operation, so long as the order (which is enforced by schema) is kept.
+
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230315-topic-lagoon_gpu-v2-1-afcdfb18bb13@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Stable-dep-of: 743913b343a3 ("clk: qcom: gpucc-sm6350: Fix clock source names")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gpucc-sm6350.c | 18 +++++++++++++-----
+ 1 file changed, 13 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/clk/qcom/gpucc-sm6350.c b/drivers/clk/qcom/gpucc-sm6350.c
+index ef15185a99c31..a9887d1f0ed71 100644
+--- a/drivers/clk/qcom/gpucc-sm6350.c
++++ b/drivers/clk/qcom/gpucc-sm6350.c
+@@ -24,6 +24,12 @@
+ #define CX_GMU_CBCR_WAKE_MASK 0xF
+ #define CX_GMU_CBCR_WAKE_SHIFT 8
+
++enum {
++ DT_BI_TCXO,
++ DT_GPLL0_OUT_MAIN,
++ DT_GPLL0_OUT_MAIN_DIV,
++};
++
+ enum {
+ P_BI_TCXO,
+ P_GPLL0_OUT_MAIN,
+@@ -61,6 +67,7 @@ static struct clk_alpha_pll gpu_cc_pll0 = {
+ .hw.init = &(struct clk_init_data){
+ .name = "gpu_cc_pll0",
+ .parent_data = &(const struct clk_parent_data){
++ .index = DT_BI_TCXO,
+ .fw_name = "bi_tcxo",
+ },
+ .num_parents = 1,
+@@ -104,6 +111,7 @@ static struct clk_alpha_pll gpu_cc_pll1 = {
+ .hw.init = &(struct clk_init_data){
+ .name = "gpu_cc_pll1",
+ .parent_data = &(const struct clk_parent_data){
++ .index = DT_BI_TCXO,
+ .fw_name = "bi_tcxo",
+ },
+ .num_parents = 1,
+@@ -121,11 +129,11 @@ static const struct parent_map gpu_cc_parent_map_0[] = {
+ };
+
+ static const struct clk_parent_data gpu_cc_parent_data_0[] = {
+- { .fw_name = "bi_tcxo" },
++ { .index = DT_BI_TCXO, .fw_name = "bi_tcxo" },
+ { .hw = &gpu_cc_pll0.clkr.hw },
+ { .hw = &gpu_cc_pll1.clkr.hw },
+- { .fw_name = "gcc_gpu_gpll0_clk" },
+- { .fw_name = "gcc_gpu_gpll0_div_clk" },
++ { .index = DT_GPLL0_OUT_MAIN, .fw_name = "gcc_gpu_gpll0_clk" },
++ { .index = DT_GPLL0_OUT_MAIN_DIV, .fw_name = "gcc_gpu_gpll0_div_clk" },
+ };
+
+ static const struct parent_map gpu_cc_parent_map_1[] = {
+@@ -138,12 +146,12 @@ static const struct parent_map gpu_cc_parent_map_1[] = {
+ };
+
+ static const struct clk_parent_data gpu_cc_parent_data_1[] = {
+- { .fw_name = "bi_tcxo" },
++ { .index = DT_BI_TCXO, .fw_name = "bi_tcxo" },
+ { .hw = &crc_div.hw },
+ { .hw = &gpu_cc_pll0.clkr.hw },
+ { .hw = &gpu_cc_pll1.clkr.hw },
+ { .hw = &gpu_cc_pll1.clkr.hw },
+- { .fw_name = "gcc_gpu_gpll0_clk" },
++ { .index = DT_GPLL0_OUT_MAIN, .fw_name = "gcc_gpu_gpll0_clk" },
+ };
+
+ static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = {
+--
+2.40.1
+
--- /dev/null
+From 3c1d9fa97f5b135a8cd7ed158be9b337de7d8a9c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Jul 2023 09:57:38 +0200
+Subject: clk: qcom: reset: Use the correct type of sleep/delay based on length
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit 181b66ee7cdd824797fc99b53bec29cf5630a04f ]
+
+Use the fsleep() helper that (based on the length of the delay, see: [1])
+chooses the correct sleep/delay functions.
+
+[1] https://www.kernel.org/doc/Documentation/timers/timers-howto.txt
+
+Fixes: 2cb8a39b6781 ("clk: qcom: reset: Allow specifying custom reset delay")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230726-topic-qcom_reset-v3-1-5958facd5db2@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/reset.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/clk/qcom/reset.c b/drivers/clk/qcom/reset.c
+index 0e914ec7aeae1..e45e32804d2c7 100644
+--- a/drivers/clk/qcom/reset.c
++++ b/drivers/clk/qcom/reset.c
+@@ -16,7 +16,8 @@ static int qcom_reset(struct reset_controller_dev *rcdev, unsigned long id)
+ struct qcom_reset_controller *rst = to_qcom_reset_controller(rcdev);
+
+ rcdev->ops->assert(rcdev, id);
+- udelay(rst->reset_map[id].udelay ?: 1); /* use 1 us as default */
++ fsleep(rst->reset_map[id].udelay ?: 1); /* use 1 us as default */
++
+ rcdev->ops->deassert(rcdev, id);
+ return 0;
+ }
+--
+2.40.1
+
--- /dev/null
+From cc6d2567523d6d3149605a298e024ec683e437fb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Jun 2023 16:47:50 +0300
+Subject: clk: rockchip: rk3568: Fix PLL rate setting for 78.75MHz
+
+From: Alibek Omarov <a1ba.omarov@gmail.com>
+
+[ Upstream commit dafebd0f9a4f56b10d7fbda0bff1f540d16a2ea4 ]
+
+PLL rate on RK356x is calculated through the simple formula:
+((24000000 / _refdiv) * _fbdiv) / (_postdiv1 * _postdiv2)
+
+The PLL rate setting for 78.75MHz seems to be copied from 96MHz
+so this patch fixes it and configures it properly.
+
+Signed-off-by: Alibek Omarov <a1ba.omarov@gmail.com>
+Fixes: 842f4cb72639 ("clk: rockchip: Add more PLL rates for rk3568")
+Reviewed-by: Sascha Hauer <s.hauer@pengutronix.de>
+Link: https://lore.kernel.org/r/20230614134750.1056293-1-a1ba.omarov@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/rockchip/clk-rk3568.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/rockchip/clk-rk3568.c b/drivers/clk/rockchip/clk-rk3568.c
+index f85902e2590c7..2f54f630c8b65 100644
+--- a/drivers/clk/rockchip/clk-rk3568.c
++++ b/drivers/clk/rockchip/clk-rk3568.c
+@@ -81,7 +81,7 @@ static struct rockchip_pll_rate_table rk3568_pll_rates[] = {
+ RK3036_PLL_RATE(108000000, 2, 45, 5, 1, 1, 0),
+ RK3036_PLL_RATE(100000000, 1, 150, 6, 6, 1, 0),
+ RK3036_PLL_RATE(96000000, 1, 96, 6, 4, 1, 0),
+- RK3036_PLL_RATE(78750000, 1, 96, 6, 4, 1, 0),
++ RK3036_PLL_RATE(78750000, 4, 315, 6, 4, 1, 0),
+ RK3036_PLL_RATE(74250000, 2, 99, 4, 4, 1, 0),
+ { /* sentinel */ },
+ };
+--
+2.40.1
+
--- /dev/null
+From 6bed85349672e00f629ccc5d0c2d2293c36773ea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 22 Jul 2023 15:31:07 +0000
+Subject: clk: sunxi-ng: Modify mismatched function name
+
+From: Zhang Jianhua <chris.zjh@huawei.com>
+
+[ Upstream commit 075d9ca5b4e17f84fd1c744a405e69ec743be7f0 ]
+
+No functional modification involved.
+
+drivers/clk/sunxi-ng/ccu_mmc_timing.c:54: warning: expecting prototype for sunxi_ccu_set_mmc_timing_mode(). Prototype was for sunxi_ccu_get_mmc_timing_mode() instead
+
+Fixes: f6f64ed868d3 ("clk: sunxi-ng: Add interface to query or configure MMC timing modes.")
+Signed-off-by: Zhang Jianhua <chris.zjh@huawei.com>
+Reviewed-by: Randy Dunlap <rdunlap@infradead.org>
+Link: https://lore.kernel.org/r/20230722153107.2078179-1-chris.zjh@huawei.com
+Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/sunxi-ng/ccu_mmc_timing.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/sunxi-ng/ccu_mmc_timing.c b/drivers/clk/sunxi-ng/ccu_mmc_timing.c
+index 23a8d44e2449b..78919d7843bec 100644
+--- a/drivers/clk/sunxi-ng/ccu_mmc_timing.c
++++ b/drivers/clk/sunxi-ng/ccu_mmc_timing.c
+@@ -43,7 +43,7 @@ int sunxi_ccu_set_mmc_timing_mode(struct clk *clk, bool new_mode)
+ EXPORT_SYMBOL_GPL(sunxi_ccu_set_mmc_timing_mode);
+
+ /**
+- * sunxi_ccu_set_mmc_timing_mode: Get the current MMC clock timing mode
++ * sunxi_ccu_get_mmc_timing_mode: Get the current MMC clock timing mode
+ * @clk: clock to query
+ *
+ * Return: %0 if the clock is in old timing mode, > %0 if it is in
+--
+2.40.1
+
--- /dev/null
+From 67383f579d119da2d2d84791b1d5458d81b10312 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Jun 2023 11:59:49 -0700
+Subject: clocksource: Handle negative skews in "skew is too large" messages
+
+From: Paul E. McKenney <paulmck@kernel.org>
+
+[ Upstream commit e40806e9bcf8aaa86dbf0d484e7cf3cfa09cb86c ]
+
+The nanosecond-to-millisecond skew computation uses unsigned arithmetic,
+which produces user-unfriendly large positive numbers for negative skews.
+Therefore, use signed arithmetic for this computation in order to preserve
+the negativity.
+
+Reported-by: Chris Bainbridge <chris.bainbridge@gmail.com>
+Reported-by: Feng Tang <feng.tang@intel.com>
+Fixes: dd029269947a ("clocksource: Improve "skew is too large" messages")
+Reviewed-by: Feng Tang <feng.tang@intel.com>
+Tested-by: Chris Bainbridge <chris.bainbridge@gmail.com>
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/time/clocksource.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
+index 91836b727cef5..0600e16dbafef 100644
+--- a/kernel/time/clocksource.c
++++ b/kernel/time/clocksource.c
+@@ -473,8 +473,8 @@ static void clocksource_watchdog(struct timer_list *unused)
+ /* Check the deviation from the watchdog clocksource. */
+ md = cs->uncertainty_margin + watchdog->uncertainty_margin;
+ if (abs(cs_nsec - wd_nsec) > md) {
+- u64 cs_wd_msec;
+- u64 wd_msec;
++ s64 cs_wd_msec;
++ s64 wd_msec;
+ u32 wd_rem;
+
+ pr_warn("timekeeping watchdog on CPU%d: Marking clocksource '%s' as unstable because the skew is too large:\n",
+@@ -483,8 +483,8 @@ static void clocksource_watchdog(struct timer_list *unused)
+ watchdog->name, wd_nsec, wdnow, wdlast, watchdog->mask);
+ pr_warn(" '%s' cs_nsec: %lld cs_now: %llx cs_last: %llx mask: %llx\n",
+ cs->name, cs_nsec, csnow, cslast, cs->mask);
+- cs_wd_msec = div_u64_rem(cs_nsec - wd_nsec, 1000U * 1000U, &wd_rem);
+- wd_msec = div_u64_rem(wd_nsec, 1000U * 1000U, &wd_rem);
++ cs_wd_msec = div_s64_rem(cs_nsec - wd_nsec, 1000 * 1000, &wd_rem);
++ wd_msec = div_s64_rem(wd_nsec, 1000 * 1000, &wd_rem);
+ pr_warn(" Clocksource '%s' skewed %lld ns (%lld ms) over watchdog '%s' interval of %lld ns (%lld ms)\n",
+ cs->name, cs_nsec - wd_nsec, cs_wd_msec, watchdog->name, wd_nsec, wd_msec);
+ if (curr_clocksource == cs)
+--
+2.40.1
+
--- /dev/null
+From 9061de5910968fcfac33cdf55d674c02bae241aa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Aug 2023 16:15:14 +0800
+Subject: coresight: tmc: Explicit type conversions to prevent integer overflow
+
+From: Ruidong Tian <tianruidong@linux.alibaba.com>
+
+[ Upstream commit fd380097cdb305582b7a1f9476391330299d2c59 ]
+
+Perf cs_etm session executed unexpectedly when AUX buffer > 1G.
+
+ perf record -C 0 -m ,2G -e cs_etm// -- <workload>
+ [ perf record: Captured and wrote 2.615 MB perf.data ]
+
+Perf only collect about 2M perf data rather than 2G. This is becasuse
+the operation, "nr_pages << PAGE_SHIFT", in coresight tmc driver, will
+overflow when nr_pages >= 0x80000(correspond to 1G AUX buffer). The
+overflow cause buffer allocation to fail, and TMC driver will alloc
+minimal buffer size(1M). You can just get about 2M perf data(1M AUX
+buffer + perf data header) at least.
+
+Explicit convert nr_pages to 64 bit to avoid overflow.
+
+Fixes: 22f429f19c41 ("coresight: etm-perf: Add support for ETR backend")
+Fixes: 99443ea19e8b ("coresight: Add generic TMC sg table framework")
+Fixes: 2e499bbc1a92 ("coresight: tmc: implementing TMC-ETF AUX space API")
+Signed-off-by: Ruidong Tian <tianruidong@linux.alibaba.com>
+Reviewed-by: James Clark <james.clark@arm.com>
+Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
+Link: https://lore.kernel.org/r/20230804081514.120171-2-tianruidong@linux.alibaba.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwtracing/coresight/coresight-tmc-etf.c | 2 +-
+ drivers/hwtracing/coresight/coresight-tmc-etr.c | 5 +++--
+ drivers/hwtracing/coresight/coresight-tmc.h | 2 +-
+ 3 files changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c
+index 0ab1f73c2d06a..e374b02d98be3 100644
+--- a/drivers/hwtracing/coresight/coresight-tmc-etf.c
++++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c
+@@ -450,7 +450,7 @@ static int tmc_set_etf_buffer(struct coresight_device *csdev,
+ return -EINVAL;
+
+ /* wrap head around to the amount of space we have */
+- head = handle->head & ((buf->nr_pages << PAGE_SHIFT) - 1);
++ head = handle->head & (((unsigned long)buf->nr_pages << PAGE_SHIFT) - 1);
+
+ /* find the page to write to */
+ buf->cur = head / PAGE_SIZE;
+diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
+index eaa296ced1678..8ef4a2a13427e 100644
+--- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
++++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
+@@ -45,7 +45,8 @@ struct etr_perf_buffer {
+ };
+
+ /* Convert the perf index to an offset within the ETR buffer */
+-#define PERF_IDX2OFF(idx, buf) ((idx) % ((buf)->nr_pages << PAGE_SHIFT))
++#define PERF_IDX2OFF(idx, buf) \
++ ((idx) % ((unsigned long)(buf)->nr_pages << PAGE_SHIFT))
+
+ /* Lower limit for ETR hardware buffer */
+ #define TMC_ETR_PERF_MIN_BUF_SIZE SZ_1M
+@@ -1262,7 +1263,7 @@ alloc_etr_buf(struct tmc_drvdata *drvdata, struct perf_event *event,
+ * than the size requested via sysfs.
+ */
+ if ((nr_pages << PAGE_SHIFT) > drvdata->size) {
+- etr_buf = tmc_alloc_etr_buf(drvdata, (nr_pages << PAGE_SHIFT),
++ etr_buf = tmc_alloc_etr_buf(drvdata, ((ssize_t)nr_pages << PAGE_SHIFT),
+ 0, node, NULL);
+ if (!IS_ERR(etr_buf))
+ goto done;
+diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
+index 01c0382a29c0a..26e6356261c11 100644
+--- a/drivers/hwtracing/coresight/coresight-tmc.h
++++ b/drivers/hwtracing/coresight/coresight-tmc.h
+@@ -325,7 +325,7 @@ ssize_t tmc_sg_table_get_data(struct tmc_sg_table *sg_table,
+ static inline unsigned long
+ tmc_sg_table_buf_size(struct tmc_sg_table *sg_table)
+ {
+- return sg_table->data_pages.nr_pages << PAGE_SHIFT;
++ return (unsigned long)sg_table->data_pages.nr_pages << PAGE_SHIFT;
+ }
+
+ struct coresight_device *tmc_etr_get_catu_device(struct tmc_drvdata *drvdata);
+--
+2.40.1
+
--- /dev/null
+From 008fd7a855d86ebc0d50df577d9b6be299c26a98 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Aug 2023 16:40:52 +0800
+Subject: coresight: trbe: Fix TRBE potential sleep in atomic context
+
+From: Junhao He <hejunhao3@huawei.com>
+
+[ Upstream commit c0a232f1e19e378c5c4e5973a996392942c80090 ]
+
+smp_call_function_single() will allocate an IPI interrupt vector to
+the target processor and send a function call request to the interrupt
+vector. After the target processor receives the IPI interrupt, it will
+execute arm_trbe_remove_coresight_cpu() call request in the interrupt
+handler.
+
+According to the device_unregister() stack information, if other process
+is useing the device, the down_write() may sleep, and trigger deadlocks
+or unexpected errors.
+
+ arm_trbe_remove_coresight_cpu
+ coresight_unregister
+ device_unregister
+ device_del
+ kobject_del
+ __kobject_del
+ sysfs_remove_dir
+ kernfs_remove
+ down_write ---------> it may sleep
+
+Add a helper arm_trbe_disable_cpu() to disable TRBE precpu irq and reset
+per TRBE.
+Simply call arm_trbe_remove_coresight_cpu() directly without useing the
+smp_call_function_single(), which is the same as registering the TRBE
+coresight device.
+
+Fixes: 3fbf7f011f24 ("coresight: sink: Add TRBE driver")
+Signed-off-by: Junhao He <hejunhao3@huawei.com>
+Link: https://lore.kernel.org/r/20230814093813.19152-2-hejunhao3@huawei.com
+[ Remove duplicate cpumask checks during removal ]
+Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
+[ v3 - Remove the operation of assigning NULL to cpudata->drvdata ]
+Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
+Link: https://lore.kernel.org/r/20230818084052.10116-1-hejunhao3@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwtracing/coresight/coresight-trbe.c | 32 +++++++++++---------
+ 1 file changed, 17 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
+index 1fc4fd79a1c69..925f6c9cecff4 100644
+--- a/drivers/hwtracing/coresight/coresight-trbe.c
++++ b/drivers/hwtracing/coresight/coresight-trbe.c
+@@ -1223,6 +1223,16 @@ static void arm_trbe_enable_cpu(void *info)
+ enable_percpu_irq(drvdata->irq, IRQ_TYPE_NONE);
+ }
+
++static void arm_trbe_disable_cpu(void *info)
++{
++ struct trbe_drvdata *drvdata = info;
++ struct trbe_cpudata *cpudata = this_cpu_ptr(drvdata->cpudata);
++
++ disable_percpu_irq(drvdata->irq);
++ trbe_reset_local(cpudata);
++}
++
++
+ static void arm_trbe_register_coresight_cpu(struct trbe_drvdata *drvdata, int cpu)
+ {
+ struct trbe_cpudata *cpudata = per_cpu_ptr(drvdata->cpudata, cpu);
+@@ -1324,18 +1334,12 @@ static void arm_trbe_probe_cpu(void *info)
+ cpumask_clear_cpu(cpu, &drvdata->supported_cpus);
+ }
+
+-static void arm_trbe_remove_coresight_cpu(void *info)
++static void arm_trbe_remove_coresight_cpu(struct trbe_drvdata *drvdata, int cpu)
+ {
+- int cpu = smp_processor_id();
+- struct trbe_drvdata *drvdata = info;
+- struct trbe_cpudata *cpudata = per_cpu_ptr(drvdata->cpudata, cpu);
+ struct coresight_device *trbe_csdev = coresight_get_percpu_sink(cpu);
+
+- disable_percpu_irq(drvdata->irq);
+- trbe_reset_local(cpudata);
+ if (trbe_csdev) {
+ coresight_unregister(trbe_csdev);
+- cpudata->drvdata = NULL;
+ coresight_set_percpu_sink(cpu, NULL);
+ }
+ }
+@@ -1364,8 +1368,10 @@ static int arm_trbe_remove_coresight(struct trbe_drvdata *drvdata)
+ {
+ int cpu;
+
+- for_each_cpu(cpu, &drvdata->supported_cpus)
+- smp_call_function_single(cpu, arm_trbe_remove_coresight_cpu, drvdata, 1);
++ for_each_cpu(cpu, &drvdata->supported_cpus) {
++ smp_call_function_single(cpu, arm_trbe_disable_cpu, drvdata, 1);
++ arm_trbe_remove_coresight_cpu(drvdata, cpu);
++ }
+ free_percpu(drvdata->cpudata);
+ return 0;
+ }
+@@ -1404,12 +1410,8 @@ static int arm_trbe_cpu_teardown(unsigned int cpu, struct hlist_node *node)
+ {
+ struct trbe_drvdata *drvdata = hlist_entry_safe(node, struct trbe_drvdata, hotplug_node);
+
+- if (cpumask_test_cpu(cpu, &drvdata->supported_cpus)) {
+- struct trbe_cpudata *cpudata = per_cpu_ptr(drvdata->cpudata, cpu);
+-
+- disable_percpu_irq(drvdata->irq);
+- trbe_reset_local(cpudata);
+- }
++ if (cpumask_test_cpu(cpu, &drvdata->supported_cpus))
++ arm_trbe_disable_cpu(drvdata);
+ return 0;
+ }
+
+--
+2.40.1
+
--- /dev/null
+From b6ab6625532afc26ba897e48690d6dc1c7488642 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Aug 2023 11:44:52 +0000
+Subject: cpufreq: amd-pstate-ut: Fix kernel panic when loading the driver
+
+From: Swapnil Sapkal <swapnil.sapkal@amd.com>
+
+[ Upstream commit 60dd283804479c4a52f995b713f448e2cd65b8c8 ]
+
+After loading the amd-pstate-ut driver, amd_pstate_ut_check_perf()
+and amd_pstate_ut_check_freq() use cpufreq_cpu_get() to get the policy
+of the CPU and mark it as busy.
+
+In these functions, cpufreq_cpu_put() should be used to release the
+policy, but it is not, so any other entity trying to access the policy
+is blocked indefinitely.
+
+One such scenario is when amd_pstate mode is changed, leading to the
+following splat:
+
+[ 1332.103727] INFO: task bash:2929 blocked for more than 120 seconds.
+[ 1332.110001] Not tainted 6.5.0-rc2-amd-pstate-ut #5
+[ 1332.115315] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
+[ 1332.123140] task:bash state:D stack:0 pid:2929 ppid:2873 flags:0x00004006
+[ 1332.123143] Call Trace:
+[ 1332.123145] <TASK>
+[ 1332.123148] __schedule+0x3c1/0x16a0
+[ 1332.123154] ? _raw_read_lock_irqsave+0x2d/0x70
+[ 1332.123157] schedule+0x6f/0x110
+[ 1332.123160] schedule_timeout+0x14f/0x160
+[ 1332.123162] ? preempt_count_add+0x86/0xd0
+[ 1332.123165] __wait_for_common+0x92/0x190
+[ 1332.123168] ? __pfx_schedule_timeout+0x10/0x10
+[ 1332.123170] wait_for_completion+0x28/0x30
+[ 1332.123173] cpufreq_policy_put_kobj+0x4d/0x90
+[ 1332.123177] cpufreq_policy_free+0x157/0x1d0
+[ 1332.123178] ? preempt_count_add+0x58/0xd0
+[ 1332.123180] cpufreq_remove_dev+0xb6/0x100
+[ 1332.123182] subsys_interface_unregister+0x114/0x120
+[ 1332.123185] ? preempt_count_add+0x58/0xd0
+[ 1332.123187] ? __pfx_amd_pstate_change_driver_mode+0x10/0x10
+[ 1332.123190] cpufreq_unregister_driver+0x3b/0xd0
+[ 1332.123192] amd_pstate_change_driver_mode+0x1e/0x50
+[ 1332.123194] store_status+0xe9/0x180
+[ 1332.123197] dev_attr_store+0x1b/0x30
+[ 1332.123199] sysfs_kf_write+0x42/0x50
+[ 1332.123202] kernfs_fop_write_iter+0x143/0x1d0
+[ 1332.123204] vfs_write+0x2df/0x400
+[ 1332.123208] ksys_write+0x6b/0xf0
+[ 1332.123210] __x64_sys_write+0x1d/0x30
+[ 1332.123213] do_syscall_64+0x60/0x90
+[ 1332.123216] ? fpregs_assert_state_consistent+0x2e/0x50
+[ 1332.123219] ? exit_to_user_mode_prepare+0x49/0x1a0
+[ 1332.123223] ? irqentry_exit_to_user_mode+0xd/0x20
+[ 1332.123225] ? irqentry_exit+0x3f/0x50
+[ 1332.123226] ? exc_page_fault+0x8e/0x190
+[ 1332.123228] entry_SYSCALL_64_after_hwframe+0x6e/0xd8
+[ 1332.123232] RIP: 0033:0x7fa74c514a37
+[ 1332.123234] RSP: 002b:00007ffe31dd0788 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
+[ 1332.123238] RAX: ffffffffffffffda RBX: 0000000000000008 RCX: 00007fa74c514a37
+[ 1332.123239] RDX: 0000000000000008 RSI: 000055e27c447aa0 RDI: 0000000000000001
+[ 1332.123241] RBP: 000055e27c447aa0 R08: 00007fa74c5d1460 R09: 000000007fffffff
+[ 1332.123242] R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000008
+[ 1332.123244] R13: 00007fa74c61a780 R14: 00007fa74c616600 R15: 00007fa74c615a00
+[ 1332.123247] </TASK>
+
+Fix this by calling cpufreq_cpu_put() wherever necessary.
+
+Fixes: 14eb1c96e3a3 ("cpufreq: amd-pstate: Add test module for amd-pstate driver")
+Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
+Reviewed-by: Meng Li <li.meng@amd.com>
+Reviewed-by: Wyes Karny <wyes.karny@amd.com>
+Suggested-by: Wyes Karny <wyes.karny@amd.com>
+Signed-off-by: Swapnil Sapkal <swapnil.sapkal@amd.com>
+[ rjw: Subject and changelog edits ]
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/amd-pstate-ut.c | 24 ++++++++++++++++--------
+ 1 file changed, 16 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/cpufreq/amd-pstate-ut.c b/drivers/cpufreq/amd-pstate-ut.c
+index cf07ee77d3ccf..502d494499ae8 100644
+--- a/drivers/cpufreq/amd-pstate-ut.c
++++ b/drivers/cpufreq/amd-pstate-ut.c
+@@ -140,7 +140,7 @@ static void amd_pstate_ut_check_perf(u32 index)
+ if (ret) {
+ amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL;
+ pr_err("%s cppc_get_perf_caps ret=%d error!\n", __func__, ret);
+- return;
++ goto skip_test;
+ }
+
+ nominal_perf = cppc_perf.nominal_perf;
+@@ -151,7 +151,7 @@ static void amd_pstate_ut_check_perf(u32 index)
+ if (ret) {
+ amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL;
+ pr_err("%s read CPPC_CAP1 ret=%d error!\n", __func__, ret);
+- return;
++ goto skip_test;
+ }
+
+ nominal_perf = AMD_CPPC_NOMINAL_PERF(cap1);
+@@ -169,7 +169,7 @@ static void amd_pstate_ut_check_perf(u32 index)
+ nominal_perf, cpudata->nominal_perf,
+ lowest_nonlinear_perf, cpudata->lowest_nonlinear_perf,
+ lowest_perf, cpudata->lowest_perf);
+- return;
++ goto skip_test;
+ }
+
+ if (!((highest_perf >= nominal_perf) &&
+@@ -180,11 +180,15 @@ static void amd_pstate_ut_check_perf(u32 index)
+ pr_err("%s cpu%d highest=%d >= nominal=%d > lowest_nonlinear=%d > lowest=%d > 0, the formula is incorrect!\n",
+ __func__, cpu, highest_perf, nominal_perf,
+ lowest_nonlinear_perf, lowest_perf);
+- return;
++ goto skip_test;
+ }
++ cpufreq_cpu_put(policy);
+ }
+
+ amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_PASS;
++ return;
++skip_test:
++ cpufreq_cpu_put(policy);
+ }
+
+ /*
+@@ -212,14 +216,14 @@ static void amd_pstate_ut_check_freq(u32 index)
+ pr_err("%s cpu%d max=%d >= nominal=%d > lowest_nonlinear=%d > min=%d > 0, the formula is incorrect!\n",
+ __func__, cpu, cpudata->max_freq, cpudata->nominal_freq,
+ cpudata->lowest_nonlinear_freq, cpudata->min_freq);
+- return;
++ goto skip_test;
+ }
+
+ if (cpudata->min_freq != policy->min) {
+ amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL;
+ pr_err("%s cpu%d cpudata_min_freq=%d policy_min=%d, they should be equal!\n",
+ __func__, cpu, cpudata->min_freq, policy->min);
+- return;
++ goto skip_test;
+ }
+
+ if (cpudata->boost_supported) {
+@@ -231,16 +235,20 @@ static void amd_pstate_ut_check_freq(u32 index)
+ pr_err("%s cpu%d policy_max=%d should be equal cpu_max=%d or cpu_nominal=%d !\n",
+ __func__, cpu, policy->max, cpudata->max_freq,
+ cpudata->nominal_freq);
+- return;
++ goto skip_test;
+ }
+ } else {
+ amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL;
+ pr_err("%s cpu%d must support boost!\n", __func__, cpu);
+- return;
++ goto skip_test;
+ }
++ cpufreq_cpu_put(policy);
+ }
+
+ amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_PASS;
++ return;
++skip_test:
++ cpufreq_cpu_put(policy);
+ }
+
+ static int __init amd_pstate_ut_init(void)
+--
+2.40.1
+
--- /dev/null
+From 2f10a7eaa8ea58992c015a0bb0dc1c644adc6194 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Aug 2023 11:44:51 +0000
+Subject: cpufreq: amd-pstate-ut: Remove module parameter access
+
+From: Swapnil Sapkal <swapnil.sapkal@amd.com>
+
+[ Upstream commit 8d6e5e8268e89979d86501dbb8385ce2e6154de1 ]
+
+In amd-pstate-ut, shared memory-based systems call
+get_shared_mem() as part of amd_pstate_ut_check_enabled()
+function. This function was written when CONFIG_X86_AMD_PSTATE
+was tristate config and amd_pstate can be built as a module.
+
+Currently CONFIG_X86_AMD_PSTATE is a boolean config and module
+parameter shared_mem is removed. But amd-pstate-ut code still
+accesses this module parameter. Remove those accesses.
+
+Fixes: 456ca88d8a52 ("cpufreq: amd-pstate: change amd-pstate driver to be built-in type")
+Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
+Reviewed-by: Meng Li <li.meng@amd.com>
+Reviewed-by: Wyes Karny <wyes.karny@amd.com>
+Suggested-by: Wyes Karny <wyes.karny@amd.com>
+Signed-off-by: Swapnil Sapkal <swapnil.sapkal@amd.com>
+[ rjw: Subject edits ]
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/amd-pstate-ut.c | 22 ++--------------------
+ 1 file changed, 2 insertions(+), 20 deletions(-)
+
+diff --git a/drivers/cpufreq/amd-pstate-ut.c b/drivers/cpufreq/amd-pstate-ut.c
+index 7f3fe20489818..cf07ee77d3ccf 100644
+--- a/drivers/cpufreq/amd-pstate-ut.c
++++ b/drivers/cpufreq/amd-pstate-ut.c
+@@ -64,27 +64,9 @@ static struct amd_pstate_ut_struct amd_pstate_ut_cases[] = {
+ static bool get_shared_mem(void)
+ {
+ bool result = false;
+- char path[] = "/sys/module/amd_pstate/parameters/shared_mem";
+- char buf[5] = {0};
+- struct file *filp = NULL;
+- loff_t pos = 0;
+- ssize_t ret;
+-
+- if (!boot_cpu_has(X86_FEATURE_CPPC)) {
+- filp = filp_open(path, O_RDONLY, 0);
+- if (IS_ERR(filp))
+- pr_err("%s unable to open %s file!\n", __func__, path);
+- else {
+- ret = kernel_read(filp, &buf, sizeof(buf), &pos);
+- if (ret < 0)
+- pr_err("%s read %s file fail ret=%ld!\n",
+- __func__, path, (long)ret);
+- filp_close(filp, NULL);
+- }
+
+- if ('Y' == *buf)
+- result = true;
+- }
++ if (!boot_cpu_has(X86_FEATURE_CPPC))
++ result = true;
+
+ return result;
+ }
+--
+2.40.1
+
--- /dev/null
+From 99851e433df5e81ffd1cf958c33460845f8779d9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Aug 2023 07:03:18 +0000
+Subject: cpufreq: Fix the race condition while updating the transition_task of
+ policy
+
+From: Liao Chang <liaochang1@huawei.com>
+
+[ Upstream commit 61bfbf7951ba561dcbdd5357702d3cbc2d447812 ]
+
+The field 'transition_task' of policy structure is used to track the
+task which is performing the frequency transition. Using this field to
+print a warning once detect a case where the same task is calling
+_begin() again before completing the preivous frequency transition via
+the _end().
+
+However, there is a potential race condition in _end() and _begin() APIs
+while updating the field 'transition_task' of policy, the scenario is
+depicted below:
+
+ Task A Task B
+
+ /* 1st freq transition */
+ Invoke _begin() {
+ ...
+ ...
+ }
+ /* 2nd freq transition */
+ Invoke _begin() {
+ ... //waiting for A to
+ ... //clear
+ ... //transition_ongoing
+ ... //in _end() for
+ ... //the 1st transition
+ |
+ Change the frequency |
+ |
+ Invoke _end() { |
+ ... |
+ ... |
+ transition_ongoing = false; V
+ transition_ongoing = true;
+ transition_task = current;
+ transition_task = NULL;
+ ... //A overwrites the task
+ ... //performing the transition
+ ... //result in error warning.
+ }
+
+To fix this race condition, the transition_lock of policy structure is
+now acquired before updating policy structure in _end() API. Which ensure
+that only one task can update the 'transition_task' field at a time.
+
+Link: https://lore.kernel.org/all/b3c61d8a-d52d-3136-fbf0-d1de9f1ba411@huawei.com/
+Fixes: ca654dc3a93d ("cpufreq: Catch double invocations of cpufreq_freq_transition_begin/end")
+Signed-off-by: Liao Chang <liaochang1@huawei.com>
+Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/cpufreq.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
+index 6b52ebe5a8904..f11b01b25e8d5 100644
+--- a/drivers/cpufreq/cpufreq.c
++++ b/drivers/cpufreq/cpufreq.c
+@@ -455,8 +455,10 @@ void cpufreq_freq_transition_end(struct cpufreq_policy *policy,
+ policy->cur,
+ policy->cpuinfo.max_freq);
+
++ spin_lock(&policy->transition_lock);
+ policy->transition_ongoing = false;
+ policy->transition_task = NULL;
++ spin_unlock(&policy->transition_lock);
+
+ wake_up(&policy->transition_wait);
+ }
+--
+2.40.1
+
--- /dev/null
+From 0c150a14e41d6075658e96afe5b1a165bf8737c8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 26 Aug 2023 09:51:13 +0000
+Subject: cpufreq: powernow-k8: Use related_cpus instead of cpus in
+ driver.exit()
+
+From: Liao Chang <liaochang1@huawei.com>
+
+[ Upstream commit 03997da042dac73c69e60d91942c727c76828b65 ]
+
+Since the 'cpus' field of policy structure will become empty in the
+cpufreq core API, it is better to use 'related_cpus' in the exit()
+callback of driver.
+
+Fixes: c3274763bfc3 ("cpufreq: powernow-k8: Initialize per-cpu data-structures properly")
+Signed-off-by: Liao Chang <liaochang1@huawei.com>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/powernow-k8.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c
+index d289036beff23..b10f7a1b77f11 100644
+--- a/drivers/cpufreq/powernow-k8.c
++++ b/drivers/cpufreq/powernow-k8.c
+@@ -1101,7 +1101,8 @@ static int powernowk8_cpu_exit(struct cpufreq_policy *pol)
+
+ kfree(data->powernow_table);
+ kfree(data);
+- for_each_cpu(cpu, pol->cpus)
++ /* pol->cpus will be empty here, use related_cpus instead. */
++ for_each_cpu(cpu, pol->related_cpus)
+ per_cpu(powernow_data, cpu) = NULL;
+
+ return 0;
+--
+2.40.1
+
--- /dev/null
+From e9a3bb3952076fd2ddb51d830838cac6f8d62fb5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Aug 2023 16:49:20 +0530
+Subject: cpufreq: tegra194: add online/offline hooks
+
+From: Sumit Gupta <sumitg@nvidia.com>
+
+[ Upstream commit a3aa97be69a7cc14ddc2bb0add0b9c51cb74bf83 ]
+
+Implement the light-weight tear down and bring up helpers to reduce the
+amount of work to do on CPU offline/online operation.
+This change helps to make the hotplugging paths much faster.
+
+Suggested-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Sumit Gupta <sumitg@nvidia.com>
+Link: https://lore.kernel.org/lkml/20230816033402.3abmugb5goypvllm@vireshk-i7/
+[ Viresh: Fixed rebase conflict ]
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Stable-dep-of: de0e85b29edf ("cpufreq: tegra194: remove opp table in exit hook")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/tegra194-cpufreq.c | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+diff --git a/drivers/cpufreq/tegra194-cpufreq.c b/drivers/cpufreq/tegra194-cpufreq.c
+index 36dad5ea59475..4f572eb7842f5 100644
+--- a/drivers/cpufreq/tegra194-cpufreq.c
++++ b/drivers/cpufreq/tegra194-cpufreq.c
+@@ -508,6 +508,21 @@ static int tegra194_cpufreq_init(struct cpufreq_policy *policy)
+ return 0;
+ }
+
++static int tegra194_cpufreq_online(struct cpufreq_policy *policy)
++{
++ /* We did light-weight tear down earlier, nothing to do here */
++ return 0;
++}
++
++static int tegra194_cpufreq_offline(struct cpufreq_policy *policy)
++{
++ /*
++ * Preserve policy->driver_data and don't free resources on light-weight
++ * tear down.
++ */
++ return 0;
++}
++
+ static int tegra194_cpufreq_set_target(struct cpufreq_policy *policy,
+ unsigned int index)
+ {
+@@ -535,6 +550,8 @@ static struct cpufreq_driver tegra194_cpufreq_driver = {
+ .target_index = tegra194_cpufreq_set_target,
+ .get = tegra194_get_speed,
+ .init = tegra194_cpufreq_init,
++ .online = tegra194_cpufreq_online,
++ .offline = tegra194_cpufreq_offline,
+ .attr = cpufreq_generic_attr,
+ };
+
+--
+2.40.1
+
--- /dev/null
+From 4858b3e689e17c63805703ffc626a1a3cca80828 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Aug 2023 16:46:17 +0530
+Subject: cpufreq: tegra194: remove opp table in exit hook
+
+From: Sumit Gupta <sumitg@nvidia.com>
+
+[ Upstream commit de0e85b29edfc68046d587c7d67bbd2bdc31b73f ]
+
+Add exit hook and remove OPP table when the device gets unregistered.
+This will fix the error messages when the CPU FREQ driver module is
+removed and then re-inserted. It also fixes these messages while
+onlining the first CPU from a policy whose all CPU's were previously
+offlined.
+
+ debugfs: File 'cpu5' in directory 'opp' already present!
+ debugfs: File 'cpu6' in directory 'opp' already present!
+ debugfs: File 'cpu7' in directory 'opp' already present!
+
+Fixes: f41e1442ac5b ("cpufreq: tegra194: add OPP support and set bandwidth")
+Signed-off-by: Sumit Gupta <sumitg@nvidia.com>
+[ Viresh: Dropped irrelevant change from it ]
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/tegra194-cpufreq.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/drivers/cpufreq/tegra194-cpufreq.c b/drivers/cpufreq/tegra194-cpufreq.c
+index 4f572eb7842f5..75f1e611d0aab 100644
+--- a/drivers/cpufreq/tegra194-cpufreq.c
++++ b/drivers/cpufreq/tegra194-cpufreq.c
+@@ -520,6 +520,17 @@ static int tegra194_cpufreq_offline(struct cpufreq_policy *policy)
+ * Preserve policy->driver_data and don't free resources on light-weight
+ * tear down.
+ */
++
++ return 0;
++}
++
++static int tegra194_cpufreq_exit(struct cpufreq_policy *policy)
++{
++ struct device *cpu_dev = get_cpu_device(policy->cpu);
++
++ dev_pm_opp_remove_all_dynamic(cpu_dev);
++ dev_pm_opp_of_cpumask_remove_table(policy->related_cpus);
++
+ return 0;
+ }
+
+@@ -550,6 +561,7 @@ static struct cpufreq_driver tegra194_cpufreq_driver = {
+ .target_index = tegra194_cpufreq_set_target,
+ .get = tegra194_get_speed,
+ .init = tegra194_cpufreq_init,
++ .exit = tegra194_cpufreq_exit,
+ .online = tegra194_cpufreq_online,
+ .offline = tegra194_cpufreq_offline,
+ .attr = cpufreq_generic_attr,
+--
+2.40.1
+
--- /dev/null
+From a5dedbd6734867b233739abde0e853ad9c717ae7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Jul 2023 20:56:35 +0200
+Subject: cpuidle: teo: Update idle duration estimate when choosing shallower
+ state
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 3f0b0966b30982e843950b170b7a9ddfd8094428 ]
+
+The TEO governor takes CPU utilization into account by refining idle state
+selection when the utilization is above a certain threshold. This is done by
+choosing an idle state shallower than the previously selected one.
+
+However, when doing this, the idle duration estimate needs to be
+adjusted so as to prevent the scheduler tick from being stopped when the
+candidate idle state is shallow, which may lead to excessive energy
+usage if the CPU is not woken up quickly enough going forward.
+Moreover, if the scheduler tick has been stopped already and the new
+idle duration estimate is too small, the replacement candidate state
+cannot be used.
+
+Modify the relevant code to take the above observations into account.
+
+Fixes: 9ce0f7c4bc64 ("cpuidle: teo: Introduce util-awareness")
+Link: https://lore.kernel.org/linux-pm/CAJZ5v0jJxHj65r2HXBTd3wfbZtsg=_StzwO1kA5STDnaPe_dWA@mail.gmail.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Reviewed-and-tested-by: Kajetan Puchalski <kajetan.puchalski@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpuidle/governors/teo.c | 40 ++++++++++++++++++++++++---------
+ 1 file changed, 30 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/cpuidle/governors/teo.c b/drivers/cpuidle/governors/teo.c
+index 987fc5f3997dc..2cdc711679a5f 100644
+--- a/drivers/cpuidle/governors/teo.c
++++ b/drivers/cpuidle/governors/teo.c
+@@ -397,13 +397,23 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
+ * the shallowest non-polling state and exit.
+ */
+ if (drv->state_count < 3 && cpu_data->utilized) {
+- for (i = 0; i < drv->state_count; ++i) {
+- if (!dev->states_usage[i].disable &&
+- !(drv->states[i].flags & CPUIDLE_FLAG_POLLING)) {
+- idx = i;
+- goto end;
+- }
+- }
++ /* The CPU is utilized, so assume a short idle duration. */
++ duration_ns = teo_middle_of_bin(0, drv);
++ /*
++ * If state 0 is enabled and it is not a polling one, select it
++ * right away unless the scheduler tick has been stopped, in
++ * which case care needs to be taken to leave the CPU in a deep
++ * enough state in case it is not woken up any time soon after
++ * all. If state 1 is disabled, though, state 0 must be used
++ * anyway.
++ */
++ if ((!idx && !(drv->states[0].flags & CPUIDLE_FLAG_POLLING) &&
++ teo_time_ok(duration_ns)) || dev->states_usage[1].disable)
++ idx = 0;
++ else /* Assume that state 1 is not a polling one and use it. */
++ idx = 1;
++
++ goto end;
+ }
+
+ /*
+@@ -539,10 +549,20 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
+
+ /*
+ * If the CPU is being utilized over the threshold, choose a shallower
+- * non-polling state to improve latency
++ * non-polling state to improve latency, unless the scheduler tick has
++ * been stopped already and the shallower state's target residency is
++ * not sufficiently large.
+ */
+- if (cpu_data->utilized)
+- idx = teo_find_shallower_state(drv, dev, idx, duration_ns, true);
++ if (cpu_data->utilized) {
++ s64 span_ns;
++
++ i = teo_find_shallower_state(drv, dev, idx, duration_ns, true);
++ span_ns = teo_middle_of_bin(i, drv);
++ if (teo_time_ok(span_ns)) {
++ idx = i;
++ duration_ns = span_ns;
++ }
++ }
+
+ end:
+ /*
+--
+2.40.1
+
--- /dev/null
+From ee8a8911d70b881aa9f7948019849ab33bd94fd5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Aug 2023 17:59:28 +0800
+Subject: crypto: api - Use work queue in crypto_destroy_instance
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+[ Upstream commit 9ae4577bc077a7e32c3c7d442c95bc76865c0f17 ]
+
+The function crypto_drop_spawn expects to be called in process
+context. However, when an instance is unregistered while it still
+has active users, the last user may cause the instance to be freed
+in atomic context.
+
+Fix this by delaying the freeing to a work queue.
+
+Fixes: 6bfd48096ff8 ("[CRYPTO] api: Added spawns")
+Reported-by: Florent Revest <revest@chromium.org>
+Reported-by: syzbot+d769eed29cc42d75e2a3@syzkaller.appspotmail.com
+Reported-by: syzbot+610ec0671f51e838436e@syzkaller.appspotmail.com
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Tested-by: Florent Revest <revest@chromium.org>
+Acked-by: Florent Revest <revest@chromium.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ crypto/algapi.c | 16 ++++++++++++++--
+ include/crypto/algapi.h | 3 +++
+ 2 files changed, 17 insertions(+), 2 deletions(-)
+
+diff --git a/crypto/algapi.c b/crypto/algapi.c
+index 5e7cd603d489c..4fe95c4480473 100644
+--- a/crypto/algapi.c
++++ b/crypto/algapi.c
+@@ -17,6 +17,7 @@
+ #include <linux/rtnetlink.h>
+ #include <linux/slab.h>
+ #include <linux/string.h>
++#include <linux/workqueue.h>
+
+ #include "internal.h"
+
+@@ -74,15 +75,26 @@ static void crypto_free_instance(struct crypto_instance *inst)
+ inst->alg.cra_type->free(inst);
+ }
+
+-static void crypto_destroy_instance(struct crypto_alg *alg)
++static void crypto_destroy_instance_workfn(struct work_struct *w)
+ {
+- struct crypto_instance *inst = (void *)alg;
++ struct crypto_instance *inst = container_of(w, struct crypto_instance,
++ free_work);
+ struct crypto_template *tmpl = inst->tmpl;
+
+ crypto_free_instance(inst);
+ crypto_tmpl_put(tmpl);
+ }
+
++static void crypto_destroy_instance(struct crypto_alg *alg)
++{
++ struct crypto_instance *inst = container_of(alg,
++ struct crypto_instance,
++ alg);
++
++ INIT_WORK(&inst->free_work, crypto_destroy_instance_workfn);
++ schedule_work(&inst->free_work);
++}
++
+ /*
+ * This function adds a spawn to the list secondary_spawns which
+ * will be used at the end of crypto_remove_spawns to unregister
+diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h
+index 016d5a302b84a..bd3a99b0106bf 100644
+--- a/include/crypto/algapi.h
++++ b/include/crypto/algapi.h
+@@ -12,6 +12,7 @@
+ #include <linux/cache.h>
+ #include <linux/crypto.h>
+ #include <linux/types.h>
++#include <linux/workqueue.h>
+
+ /*
+ * Maximum values for blocksize and alignmask, used to allocate
+@@ -83,6 +84,8 @@ struct crypto_instance {
+ struct crypto_spawn *spawns;
+ };
+
++ struct work_struct free_work;
++
+ void *__ctx[] CRYPTO_MINALIGN_ATTR;
+ };
+
+--
+2.40.1
+
--- /dev/null
+From ba87474d43339470f315c29aeee48b53de067352 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Aug 2023 12:55:25 +0200
+Subject: crypto: caam - fix unchecked return value error
+
+From: Gaurav Jain <gaurav.jain@nxp.com>
+
+[ Upstream commit e30685204711a6be40dec2622606950ccd37dafe ]
+
+error:
+Unchecked return value (CHECKED_RETURN)
+check_return: Calling sg_miter_next without checking return value
+
+fix:
+added check if(!sg_miter_next)
+
+Fixes: 8a2a0dd35f2e ("crypto: caam - strip input zeros from RSA input buffer")
+Signed-off-by: Gaurav Jain <gaurav.jain@nxp.com>
+Signed-off-by: Meenakshi Aggarwal <meenakshi.aggarwal@nxp.com>
+Reviewed-by: Gaurav Jain <gaurav.jain@nxp.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/caam/caampkc.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/crypto/caam/caampkc.c b/drivers/crypto/caam/caampkc.c
+index 72afc249d42fb..7e08af751e4ea 100644
+--- a/drivers/crypto/caam/caampkc.c
++++ b/drivers/crypto/caam/caampkc.c
+@@ -225,7 +225,9 @@ static int caam_rsa_count_leading_zeros(struct scatterlist *sgl,
+ if (len && *buff)
+ break;
+
+- sg_miter_next(&miter);
++ if (!sg_miter_next(&miter))
++ break;
++
+ buff = miter.addr;
+ len = miter.length;
+
+--
+2.40.1
+
--- /dev/null
+From b57c48a5f11b0dd74c3f1072794d89345dc930a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Jun 2023 10:26:35 +0100
+Subject: crypto: qat - change value of default idle filter
+
+From: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
+
+[ Upstream commit 0f942bdfe9d463be3073301519492f8d53c6b2d5 ]
+
+The power management configuration of 4xxx devices is too aggressive
+and in some conditions the device might be prematurely put to a low
+power state.
+Increase the idle filter value to prevent that.
+In future, this will be set by firmware.
+
+Fixes: e5745f34113b ("crypto: qat - enable power management for QAT GEN4")
+Signed-off-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
+Reviewed-by: Damian Muszynski <damian.muszynski@intel.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/intel/qat/qat_common/adf_gen4_pm.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/crypto/intel/qat/qat_common/adf_gen4_pm.h b/drivers/crypto/intel/qat/qat_common/adf_gen4_pm.h
+index f8f8a9ee29e5b..db4326933d1c0 100644
+--- a/drivers/crypto/intel/qat/qat_common/adf_gen4_pm.h
++++ b/drivers/crypto/intel/qat/qat_common/adf_gen4_pm.h
+@@ -35,7 +35,7 @@
+ #define ADF_GEN4_PM_MSG_PENDING BIT(0)
+ #define ADF_GEN4_PM_MSG_PAYLOAD_BIT_MASK GENMASK(28, 1)
+
+-#define ADF_GEN4_PM_DEFAULT_IDLE_FILTER (0x0)
++#define ADF_GEN4_PM_DEFAULT_IDLE_FILTER (0x6)
+ #define ADF_GEN4_PM_MAX_IDLE_FILTER (0x7)
+
+ int adf_gen4_enable_pm(struct adf_accel_dev *accel_dev);
+--
+2.40.1
+
--- /dev/null
+From 9d4442da3f8d4240a32cbc8311766f04e958010a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Jul 2023 18:54:54 +0200
+Subject: crypto: stm32 - Properly handle pm_runtime_get failing
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit aec48805163338f8413118796c1dd035661b9140 ]
+
+If pm_runtime_get() (disguised as pm_runtime_resume_and_get()) fails, this
+means the clk wasn't prepared and enabled. Returning early in this case
+however is wrong as then the following resource frees are skipped and this
+is never catched up. So do all the cleanups but clk_disable_unprepare().
+
+Also don't emit a warning, as stm32_hash_runtime_resume() already emitted
+one.
+
+Note that the return value of stm32_hash_remove() is mostly ignored by
+the device core. The only effect of returning zero instead of an error
+value is to suppress another warning in platform_remove(). So return 0
+even if pm_runtime_resume_and_get() failed.
+
+Fixes: 8b4d566de6a5 ("crypto: stm32/hash - Add power management support")
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/stm32/stm32-hash.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/crypto/stm32/stm32-hash.c b/drivers/crypto/stm32/stm32-hash.c
+index f0df32382719c..342ed46ddf882 100644
+--- a/drivers/crypto/stm32/stm32-hash.c
++++ b/drivers/crypto/stm32/stm32-hash.c
+@@ -1705,9 +1705,7 @@ static int stm32_hash_remove(struct platform_device *pdev)
+ if (!hdev)
+ return -ENODEV;
+
+- ret = pm_runtime_resume_and_get(hdev->dev);
+- if (ret < 0)
+- return ret;
++ ret = pm_runtime_get_sync(hdev->dev);
+
+ stm32_hash_unregister_algs(hdev);
+
+@@ -1723,7 +1721,8 @@ static int stm32_hash_remove(struct platform_device *pdev)
+ pm_runtime_disable(hdev->dev);
+ pm_runtime_put_noidle(hdev->dev);
+
+- clk_disable_unprepare(hdev->clk);
++ if (ret >= 0)
++ clk_disable_unprepare(hdev->clk);
+
+ return 0;
+ }
+--
+2.40.1
+
--- /dev/null
+From 255c82d969333ae68db0108c7d0d2e67f8bde34a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Aug 2023 13:40:32 +0530
+Subject: cteonxt2-pf: Fix backpressure config for multiple PFC priorities to
+ work simultaneously
+
+From: Suman Ghosh <sumang@marvell.com>
+
+[ Upstream commit 597d0ec0e4ca6a912affea4cc94df08959e9ec74 ]
+
+MAC (CGX or RPM) asserts backpressure at TL3 or TL2 node of the egress
+hierarchical scheduler tree depending on link level config done. If
+there are multiple PFC priorities enabled at a time and for all such
+flows to backoff, each priority will have to assert backpressure at
+different TL3/TL2 scheduler nodes and these flows will need to submit
+egress pkts to these nodes.
+
+Current PFC configuration has an issue where in only one backpressure
+scheduler node is being allocated which is resulting in only one PFC
+priority to work. This patch fixes this issue.
+
+Fixes: 99c969a83d82 ("octeontx2-pf: Add egress PFC support")
+Signed-off-by: Suman Ghosh <sumang@marvell.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://lore.kernel.org/r/20230824081032.436432-4-sumang@marvell.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/octeontx2/nic/otx2_dcbnl.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_dcbnl.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_dcbnl.c
+index 6492749dd7c89..bfddbff7bcdfb 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_dcbnl.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_dcbnl.c
+@@ -70,7 +70,7 @@ static int otx2_pfc_txschq_alloc_one(struct otx2_nic *pfvf, u8 prio)
+ * link config level. These rest of the scheduler can be
+ * same as hw.txschq_list.
+ */
+- for (lvl = 0; lvl < pfvf->hw.txschq_link_cfg_lvl; lvl++)
++ for (lvl = 0; lvl <= pfvf->hw.txschq_link_cfg_lvl; lvl++)
+ req->schq[lvl] = 1;
+
+ rc = otx2_sync_mbox_msg(&pfvf->mbox);
+@@ -83,7 +83,7 @@ static int otx2_pfc_txschq_alloc_one(struct otx2_nic *pfvf, u8 prio)
+ return PTR_ERR(rsp);
+
+ /* Setup transmit scheduler list */
+- for (lvl = 0; lvl < pfvf->hw.txschq_link_cfg_lvl; lvl++) {
++ for (lvl = 0; lvl <= pfvf->hw.txschq_link_cfg_lvl; lvl++) {
+ if (!rsp->schq[lvl])
+ return -ENOSPC;
+
+@@ -128,7 +128,7 @@ static int otx2_pfc_txschq_stop_one(struct otx2_nic *pfvf, u8 prio)
+ int lvl;
+
+ /* free PFC TLx nodes */
+- for (lvl = 0; lvl < pfvf->hw.txschq_link_cfg_lvl; lvl++)
++ for (lvl = 0; lvl <= pfvf->hw.txschq_link_cfg_lvl; lvl++)
+ otx2_txschq_free_one(pfvf, lvl,
+ pfvf->pfc_schq_list[lvl][prio]);
+
+--
+2.40.1
+
--- /dev/null
+From dd3c25964309a7855cf857c1a5b22427c3a0f2f0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Jul 2023 07:49:41 -0700
+Subject: dma-buf/sync_file: Fix docs syntax
+
+From: Rob Clark <robdclark@chromium.org>
+
+[ Upstream commit 05d56d8079d510a2994039470f65bea85f0075ee ]
+
+Fixes the warning:
+
+ include/uapi/linux/sync_file.h:77: warning: Function parameter or member 'num_fences' not described in 'sync_file_info'
+
+Fixes: 2d75c88fefb2 ("staging/android: refactor SYNC IOCTLs")
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Reviewed-by: Randy Dunlap <rdunlap@infradead.org>
+Link: https://lore.kernel.org/r/20230724145000.125880-1-robdclark@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/uapi/linux/sync_file.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/uapi/linux/sync_file.h b/include/uapi/linux/sync_file.h
+index 7e42a5b7558bf..ff0a931833e25 100644
+--- a/include/uapi/linux/sync_file.h
++++ b/include/uapi/linux/sync_file.h
+@@ -56,7 +56,7 @@ struct sync_fence_info {
+ * @name: name of fence
+ * @status: status of fence. 1: signaled 0:active <0:error
+ * @flags: sync_file_info flags
+- * @num_fences number of fences in the sync_file
++ * @num_fences: number of fences in the sync_file
+ * @pad: padding for 64-bit alignment, should always be zero
+ * @sync_fence_info: pointer to array of struct &sync_fence_info with all
+ * fences in the sync_file
+--
+2.40.1
+
--- /dev/null
+From f0ea25ed236dc64eb29197f406973770c42e087e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Aug 2023 18:26:34 -0700
+Subject: dmaengine: idxd: Allow ATS disable update only for configurable
+ devices
+
+From: Fenghua Yu <fenghua.yu@intel.com>
+
+[ Upstream commit 0056a7f07b0a63e6cee815a789eabba6f3a710f0 ]
+
+ATS disable status in a WQ is read-only if the device is not configurable.
+This change ensures that the ATS disable attribute can be modified via
+sysfs only on configurable devices.
+
+Fixes: 92de5fa2dc39 ("dmaengine: idxd: add ATS disable knob for work queues")
+Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Link: https://lore.kernel.org/r/20230811012635.535413-1-fenghua.yu@intel.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/idxd/sysfs.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c
+index d16c16445c4f9..66c89b07b3f7b 100644
+--- a/drivers/dma/idxd/sysfs.c
++++ b/drivers/dma/idxd/sysfs.c
+@@ -1088,12 +1088,16 @@ static ssize_t wq_ats_disable_store(struct device *dev, struct device_attribute
+ const char *buf, size_t count)
+ {
+ struct idxd_wq *wq = confdev_to_wq(dev);
++ struct idxd_device *idxd = wq->idxd;
+ bool ats_dis;
+ int rc;
+
+ if (wq->state != IDXD_WQ_DISABLED)
+ return -EPERM;
+
++ if (!test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags))
++ return -EPERM;
++
+ rc = kstrtobool(buf, &ats_dis);
+ if (rc < 0)
+ return rc;
+--
+2.40.1
+
--- /dev/null
+From 44125d85cabe34d6f2d75721ae18be2c71ccb768 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Jul 2023 10:44:36 -0700
+Subject: dmaengine: idxd: Expose ATS disable knob only when WQ ATS is
+ supported
+
+From: Fenghua Yu <fenghua.yu@intel.com>
+
+[ Upstream commit 62b41b656666d2d35890124df5ef0881fe6d6769 ]
+
+WQ Advanced Translation Service (ATS) can be controlled only when
+WQ ATS is supported. The sysfs ATS disable knob should be visible only
+when the features is supported.
+
+Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Link: https://lore.kernel.org/r/20230712174436.3435088-2-fenghua.yu@intel.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Stable-dep-of: 0056a7f07b0a ("dmaengine: idxd: Allow ATS disable update only for configurable devices")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/idxd/sysfs.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c
+index 36a30957ac9a3..d16c16445c4f9 100644
+--- a/drivers/dma/idxd/sysfs.c
++++ b/drivers/dma/idxd/sysfs.c
+@@ -1088,16 +1088,12 @@ static ssize_t wq_ats_disable_store(struct device *dev, struct device_attribute
+ const char *buf, size_t count)
+ {
+ struct idxd_wq *wq = confdev_to_wq(dev);
+- struct idxd_device *idxd = wq->idxd;
+ bool ats_dis;
+ int rc;
+
+ if (wq->state != IDXD_WQ_DISABLED)
+ return -EPERM;
+
+- if (!idxd->hw.wq_cap.wq_ats_support)
+- return -EOPNOTSUPP;
+-
+ rc = kstrtobool(buf, &ats_dis);
+ if (rc < 0)
+ return rc;
+@@ -1316,6 +1312,9 @@ static umode_t idxd_wq_attr_visible(struct kobject *kobj,
+ if (idxd_wq_attr_invisible(prs_disable, wq_prs_support, attr, idxd))
+ return 0;
+
++ if (idxd_wq_attr_invisible(ats_disable, wq_ats_support, attr, idxd))
++ return 0;
++
+ return attr->mode;
+ }
+
+--
+2.40.1
+
--- /dev/null
+From 0abc6409ffba65f0caf8d456db1f09e430240940 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Aug 2023 18:26:35 -0700
+Subject: dmaengine: idxd: Fix issues with PRS disable sysfs knob
+
+From: Fenghua Yu <fenghua.yu@intel.com>
+
+[ Upstream commit 8cae66574398326134a41513b419e00ad4e380ca ]
+
+There are two issues in the current PRS disable sysfs store function
+wq_prs_disable_store():
+
+1. Since PRS disable knob is invisible if PRS disable is not supported
+ in WQ, it's redundant to check PRS support again in the store function
+ again. Remove the redundant PRS support check.
+2. Since PRS disable is read-only when the device is not configurable,
+ PRS disable cannot be changed on the device. Add device configurable
+ check in the store function.
+
+Fixes: f2dc327131b5 ("dmaengine: idxd: add per wq PRS disable")
+Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Link: https://lore.kernel.org/r/20230811012635.535413-2-fenghua.yu@intel.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/idxd/sysfs.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c
+index 66c89b07b3f7b..a5c3eb4348325 100644
+--- a/drivers/dma/idxd/sysfs.c
++++ b/drivers/dma/idxd/sysfs.c
+@@ -1131,8 +1131,8 @@ static ssize_t wq_prs_disable_store(struct device *dev, struct device_attribute
+ if (wq->state != IDXD_WQ_DISABLED)
+ return -EPERM;
+
+- if (!idxd->hw.wq_cap.wq_prs_support)
+- return -EOPNOTSUPP;
++ if (!test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags))
++ return -EPERM;
+
+ rc = kstrtobool(buf, &prs_dis);
+ if (rc < 0)
+--
+2.40.1
+
--- /dev/null
+From 3a64eaef3f52dec77c854c670be653eb25071ddb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Jun 2023 14:27:06 +0800
+Subject: dmaengine: idxd: Modify the dependence of attribute pasid_enabled
+
+From: Rex Zhang <rex.zhang@intel.com>
+
+[ Upstream commit 50c5e6f41d5ad7c731c31135a30d0e4f0e4fea26 ]
+
+Kernel PASID and user PASID are separately enabled. User needs to know the
+user PASID enabling status to decide how to use IDXD device in user space.
+This is done via the attribute /sys/bus/dsa/devices/dsa0/pasid_enabled.
+It's unnecessary for user to know the kernel PASID enabling status because
+user won't use the kernel PASID. But instead of showing the user PASID
+enabling status, the attribute shows the kernel PASID enabling status. Fix
+the issue by showing the user PASID enabling status in the attribute.
+
+Fixes: 42a1b73852c4 ("dmaengine: idxd: Separate user and kernel pasid enabling")
+Signed-off-by: Rex Zhang <rex.zhang@intel.com>
+Acked-by: Fenghua Yu <fenghua.yu@intel.com>
+Acked-by: Dave Jiang <dave.jiang@intel.com>
+Link: https://lore.kernel.org/r/20230614062706.1743078-1-rex.zhang@intel.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/idxd/sysfs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c
+index 293739ac55969..b6a0a12412afd 100644
+--- a/drivers/dma/idxd/sysfs.c
++++ b/drivers/dma/idxd/sysfs.c
+@@ -1480,7 +1480,7 @@ static ssize_t pasid_enabled_show(struct device *dev,
+ {
+ struct idxd_device *idxd = confdev_to_idxd(dev);
+
+- return sysfs_emit(buf, "%u\n", device_pasid_enabled(idxd));
++ return sysfs_emit(buf, "%u\n", device_user_pasid_enabled(idxd));
+ }
+ static DEVICE_ATTR_RO(pasid_enabled);
+
+--
+2.40.1
+
--- /dev/null
+From d2646921a84e1cf6c828e731043580b404c68d72 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Jul 2023 10:44:35 -0700
+Subject: dmaengine: idxd: Simplify WQ attribute visibility checks
+
+From: Fenghua Yu <fenghua.yu@intel.com>
+
+[ Upstream commit 97b1185fe54c8ce94104e3c7fa4ee0bbedd85920 ]
+
+The functions that check if WQ attributes are invisible are almost
+duplicate. Define a helper to simplify these functions and future
+WQ attribute visibility checks as well.
+
+Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Link: https://lore.kernel.org/r/20230712174436.3435088-1-fenghua.yu@intel.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Stable-dep-of: 0056a7f07b0a ("dmaengine: idxd: Allow ATS disable update only for configurable devices")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/idxd/sysfs.c | 20 +++++---------------
+ 1 file changed, 5 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c
+index b6a0a12412afd..36a30957ac9a3 100644
+--- a/drivers/dma/idxd/sysfs.c
++++ b/drivers/dma/idxd/sysfs.c
+@@ -1288,12 +1288,9 @@ static struct attribute *idxd_wq_attributes[] = {
+ NULL,
+ };
+
+-static bool idxd_wq_attr_op_config_invisible(struct attribute *attr,
+- struct idxd_device *idxd)
+-{
+- return attr == &dev_attr_wq_op_config.attr &&
+- !idxd->hw.wq_cap.op_config;
+-}
++/* A WQ attr is invisible if the feature is not supported in WQCAP. */
++#define idxd_wq_attr_invisible(name, cap_field, a, idxd) \
++ ((a) == &dev_attr_wq_##name.attr && !(idxd)->hw.wq_cap.cap_field)
+
+ static bool idxd_wq_attr_max_batch_size_invisible(struct attribute *attr,
+ struct idxd_device *idxd)
+@@ -1303,13 +1300,6 @@ static bool idxd_wq_attr_max_batch_size_invisible(struct attribute *attr,
+ idxd->data->type == IDXD_TYPE_IAX;
+ }
+
+-static bool idxd_wq_attr_wq_prs_disable_invisible(struct attribute *attr,
+- struct idxd_device *idxd)
+-{
+- return attr == &dev_attr_wq_prs_disable.attr &&
+- !idxd->hw.wq_cap.wq_prs_support;
+-}
+-
+ static umode_t idxd_wq_attr_visible(struct kobject *kobj,
+ struct attribute *attr, int n)
+ {
+@@ -1317,13 +1307,13 @@ static umode_t idxd_wq_attr_visible(struct kobject *kobj,
+ struct idxd_wq *wq = confdev_to_wq(dev);
+ struct idxd_device *idxd = wq->idxd;
+
+- if (idxd_wq_attr_op_config_invisible(attr, idxd))
++ if (idxd_wq_attr_invisible(op_config, op_config, attr, idxd))
+ return 0;
+
+ if (idxd_wq_attr_max_batch_size_invisible(attr, idxd))
+ return 0;
+
+- if (idxd_wq_attr_wq_prs_disable_invisible(attr, idxd))
++ if (idxd_wq_attr_invisible(prs_disable, wq_prs_support, attr, idxd))
+ return 0;
+
+ return attr->mode;
+--
+2.40.1
+
--- /dev/null
+From d0acfc72032804658f5a148ececc0e6ae9344331 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Jul 2023 14:41:08 +0000
+Subject: dmaengine: ste_dma40: Add missing IRQ check in d40_probe
+
+From: ruanjinjie <ruanjinjie@huawei.com>
+
+[ Upstream commit c05ce6907b3d6e148b70f0bb5eafd61dcef1ddc1 ]
+
+Check for the return value of platform_get_irq(): if no interrupt
+is specified, it wouldn't make sense to call request_irq().
+
+Fixes: 8d318a50b3d7 ("DMAENGINE: Support for ST-Ericssons DMA40 block v3")
+Signed-off-by: Ruan Jinjie <ruanjinjie@huawei.com>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Link: https://lore.kernel.org/r/20230724144108.2582917-1-ruanjinjie@huawei.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/ste_dma40.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
+index f093e08c23b16..3b09fdc507e04 100644
+--- a/drivers/dma/ste_dma40.c
++++ b/drivers/dma/ste_dma40.c
+@@ -3597,6 +3597,10 @@ static int __init d40_probe(struct platform_device *pdev)
+ spin_lock_init(&base->lcla_pool.lock);
+
+ base->irq = platform_get_irq(pdev, 0);
++ if (base->irq < 0) {
++ ret = base->irq;
++ goto destroy_cache;
++ }
+
+ ret = request_irq(base->irq, d40_handle_interrupt, 0, D40_NAME, base);
+ if (ret) {
+--
+2.40.1
+
--- /dev/null
+From 144d783eae48302b8106fdadfb3c59ee5f48ae5c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Jul 2023 22:23:05 -0700
+Subject: docs: ABI: fix spelling/grammar in SBEFIFO timeout interface
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit 2cd9ec2a51474d4c0b4d2a061f2de7da34eff476 ]
+
+Correct spelling problems as identified by codespell.
+Correct one grammar error.
+
+Fixes: 9a93de620e0a ("docs: ABI: testing: Document the SBEFIFO timeout interface")
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Cc: Eddie James <eajames@linux.ibm.com>
+Cc: Joel Stanley <joel@jms.id.au>
+Link: https://lore.kernel.org/r/20230710052305.29611-1-rdunlap@infradead.org
+Signed-off-by: Joel Stanley <joel@jms.id.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/ABI/testing/sysfs-bus-fsi-devices-sbefifo | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/Documentation/ABI/testing/sysfs-bus-fsi-devices-sbefifo b/Documentation/ABI/testing/sysfs-bus-fsi-devices-sbefifo
+index 531fe9d6b40aa..c7393b4dd2d88 100644
+--- a/Documentation/ABI/testing/sysfs-bus-fsi-devices-sbefifo
++++ b/Documentation/ABI/testing/sysfs-bus-fsi-devices-sbefifo
+@@ -5,6 +5,6 @@ Description:
+ Indicates whether or not this SBE device has experienced a
+ timeout; i.e. the SBE did not respond within the time allotted
+ by the driver. A value of 1 indicates that a timeout has
+- ocurred and no transfers have completed since the timeout. A
+- value of 0 indicates that no timeout has ocurred, or if one
+- has, more recent transfers have completed successful.
++ occurred and no transfers have completed since the timeout. A
++ value of 0 indicates that no timeout has occurred, or if one
++ has, more recent transfers have completed successfully.
+--
+2.40.1
+
--- /dev/null
+From d49a753d2eb4cd0d0c936dfbc5184d9df5ea8016 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Jul 2023 14:40:46 -0300
+Subject: driver core: Call dma_cleanup() on the test_remove path
+
+From: Jason Gunthorpe <jgg@nvidia.com>
+
+[ Upstream commit f429378a9bf84d79a7e2cae05d2e3384cf7d68ba ]
+
+When test_remove is enabled really_probe() does not properly pair
+dma_configure() with dma_remove(), it will end up calling dma_configure()
+twice. This corrupts the owner_cnt and renders the group unusable with
+VFIO/etc.
+
+Add the missing cleanup before going back to re_probe.
+
+Fixes: 25f3bcfc54bc ("driver core: Add dma_cleanup callback in bus_type")
+Reported-by: Zenghui Yu <yuzenghui@huawei.com>
+Tested-by: Zenghui Yu <yuzenghui@huawei.com>
+Closes: https://lore.kernel.org/all/6472f254-c3c4-8610-4a37-8d9dfdd54ce8@huawei.com/
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Reviewed-by: Kevin Tian <kevin.tian@intel.com>
+Link: https://lore.kernel.org/r/0-v2-4deed94e283e+40948-really_probe_dma_cleanup_jgg@nvidia.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/dd.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/base/dd.c b/drivers/base/dd.c
+index 9c09ca5c4ab68..7145d9b940b14 100644
+--- a/drivers/base/dd.c
++++ b/drivers/base/dd.c
+@@ -693,6 +693,8 @@ static int really_probe(struct device *dev, struct device_driver *drv)
+
+ device_remove(dev);
+ driver_sysfs_remove(dev);
++ if (dev->bus && dev->bus->dma_cleanup)
++ dev->bus->dma_cleanup(dev);
+ device_unbind_cleanup(dev);
+
+ goto re_probe;
+--
+2.40.1
+
--- /dev/null
+From 54ced63f31c9dace6b30b71f4a6507e77f98f72d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Jul 2023 10:03:49 +0300
+Subject: driver core: test_async: fix an error code
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 22d2381bbd70a5853c2ee77522f4965139672db9 ]
+
+The test_platform_device_register_node() function should return error
+pointers instead of NULL. That is what the callers are expecting.
+
+Fixes: 57ea974fb871 ("driver core: Rewrite test_async_driver_probe to cover serialization and NUMA affinity")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Link: https://lore.kernel.org/r/1e11ed19-e1f6-43d8-b352-474134b7c008@moroto.mountain
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/test/test_async_driver_probe.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/base/test/test_async_driver_probe.c b/drivers/base/test/test_async_driver_probe.c
+index 929410d0dd6fe..3465800baa6c8 100644
+--- a/drivers/base/test/test_async_driver_probe.c
++++ b/drivers/base/test/test_async_driver_probe.c
+@@ -84,7 +84,7 @@ test_platform_device_register_node(char *name, int id, int nid)
+
+ pdev = platform_device_alloc(name, id);
+ if (!pdev)
+- return NULL;
++ return ERR_PTR(-ENOMEM);
+
+ if (nid != NUMA_NO_NODE)
+ set_dev_node(&pdev->dev, nid);
+--
+2.40.1
+
--- /dev/null
+From 450dc3a98010f9afa2116c37edfd1c1a884bd5d1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Jul 2023 14:45:09 +0200
+Subject: drivers: base: Free devm resources when unregistering a device
+
+From: David Gow <davidgow@google.com>
+
+[ Upstream commit 699fb50d99039a50e7494de644f96c889279aca3 ]
+
+In the current code, devres_release_all() only gets called if the device
+has a bus and has been probed.
+
+This leads to issues when using bus-less or driver-less devices where
+the device might never get freed if a managed resource holds a reference
+to the device. This is happening in the DRM framework for example.
+
+We should thus call devres_release_all() in the device_del() function to
+make sure that the device-managed actions are properly executed when the
+device is unregistered, even if it has neither a bus nor a driver.
+
+This is effectively the same change than commit 2f8d16a996da ("devres:
+release resources on device_del()") that got reverted by commit
+a525a3ddeaca ("driver core: free devres in device_release") over
+memory leaks concerns.
+
+This patch effectively combines the two commits mentioned above to
+release the resources both on device_del() and device_release() and get
+the best of both worlds.
+
+Fixes: a525a3ddeaca ("driver core: free devres in device_release")
+Signed-off-by: David Gow <davidgow@google.com>
+Signed-off-by: Maxime Ripard <mripard@kernel.org>
+Link: https://lore.kernel.org/r/20230720-kunit-devm-inconsistencies-test-v3-3-6aa7e074f373@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/core.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/drivers/base/core.c b/drivers/base/core.c
+index 3dff5037943e0..6ceaf50f5a671 100644
+--- a/drivers/base/core.c
++++ b/drivers/base/core.c
+@@ -3817,6 +3817,17 @@ void device_del(struct device *dev)
+ device_platform_notify_remove(dev);
+ device_links_purge(dev);
+
++ /*
++ * If a device does not have a driver attached, we need to clean
++ * up any managed resources. We do this in device_release(), but
++ * it's never called (and we leak the device) if a managed
++ * resource holds a reference to the device. So release all
++ * managed resources here, like we do in driver_detach(). We
++ * still need to do so again in device_release() in case someone
++ * adds a new resource after this point, though.
++ */
++ devres_release_all(dev);
++
+ bus_notify(dev, BUS_NOTIFY_REMOVED_DEVICE);
+ kobject_uevent(&dev->kobj, KOBJ_REMOVE);
+ glue_dir = get_glue_dir(dev);
+--
+2.40.1
+
--- /dev/null
+From 458e1bd4be273c57e5d8579bb2f75f957b5e2a32 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Jul 2023 18:22:46 +0800
+Subject: drivers: clk: keystone: Fix parameter judgment in _of_pll_clk_init()
+
+From: Minjie Du <duminjie@vivo.com>
+
+[ Upstream commit a995c50db887ef97f3160775aef7d772635a6f6e ]
+
+The function clk_register_pll() may return NULL or an ERR_PTR. Don't
+treat an ERR_PTR as valid.
+
+Signed-off-by: Minjie Du <duminjie@vivo.com>
+Link: https://lore.kernel.org/r/20230712102246.10348-1-duminjie@vivo.com
+Fixes: b9e0d40c0d83 ("clk: keystone: add Keystone PLL clock driver")
+[sboyd@kernel.org: Reword commit text]
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/keystone/pll.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/keystone/pll.c b/drivers/clk/keystone/pll.c
+index d59a7621bb204..ee5c72369334f 100644
+--- a/drivers/clk/keystone/pll.c
++++ b/drivers/clk/keystone/pll.c
+@@ -209,7 +209,7 @@ static void __init _of_pll_clk_init(struct device_node *node, bool pllctrl)
+ }
+
+ clk = clk_register_pll(NULL, node->name, parent_name, pll_data);
+- if (clk) {
++ if (!IS_ERR_OR_NULL(clk)) {
+ of_clk_add_provider(node, of_clk_src_simple_get, clk);
+ return;
+ }
+--
+2.40.1
+
--- /dev/null
+From 22df9154cb0f00de4ac4b6088cd0c58411b551f5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Aug 2023 20:40:18 +0200
+Subject: Drivers: hv: vmbus: Don't dereference ACPI root object handle
+
+From: Maciej S. Szmigiero <maciej.szmigiero@oracle.com>
+
+[ Upstream commit 78e04bbff849b51b56f5925b1945db2c6e128b61 ]
+
+Since the commit referenced in the Fixes: tag below the VMBus client driver
+is walking the ACPI namespace up from the VMBus ACPI device to the ACPI
+namespace root object trying to find Hyper-V MMIO ranges.
+
+However, if it is not able to find them it ends trying to walk resources of
+the ACPI namespace root object itself.
+This object has all-ones handle, which causes a NULL pointer dereference
+in the ACPI code (from dereferencing this pointer with an offset).
+
+This in turn causes an oops on boot with VMBus host implementations that do
+not provide Hyper-V MMIO ranges in their VMBus ACPI device or its
+ancestors.
+The QEMU VMBus implementation is an example of such implementation.
+
+I guess providing these ranges is optional, since all tested Windows
+versions seem to be able to use VMBus devices without them.
+
+Fix this by explicitly terminating the lookup at the ACPI namespace root
+object.
+
+Note that Linux guests under KVM/QEMU do not use the Hyper-V PV interface
+by default - they only do so if the KVM PV interface is missing or
+disabled.
+
+Example stack trace of such oops:
+[ 3.710827] ? __die+0x1f/0x60
+[ 3.715030] ? page_fault_oops+0x159/0x460
+[ 3.716008] ? exc_page_fault+0x73/0x170
+[ 3.716959] ? asm_exc_page_fault+0x22/0x30
+[ 3.717957] ? acpi_ns_lookup+0x7a/0x4b0
+[ 3.718898] ? acpi_ns_internalize_name+0x79/0xc0
+[ 3.720018] acpi_ns_get_node_unlocked+0xb5/0xe0
+[ 3.721120] ? acpi_ns_check_object_type+0xfe/0x200
+[ 3.722285] ? acpi_rs_convert_aml_to_resource+0x37/0x6e0
+[ 3.723559] ? down_timeout+0x3a/0x60
+[ 3.724455] ? acpi_ns_get_node+0x3a/0x60
+[ 3.725412] acpi_ns_get_node+0x3a/0x60
+[ 3.726335] acpi_ns_evaluate+0x1c3/0x2c0
+[ 3.727295] acpi_ut_evaluate_object+0x64/0x1b0
+[ 3.728400] acpi_rs_get_method_data+0x2b/0x70
+[ 3.729476] ? vmbus_platform_driver_probe+0x1d0/0x1d0 [hv_vmbus]
+[ 3.730940] ? vmbus_platform_driver_probe+0x1d0/0x1d0 [hv_vmbus]
+[ 3.732411] acpi_walk_resources+0x78/0xd0
+[ 3.733398] vmbus_platform_driver_probe+0x9f/0x1d0 [hv_vmbus]
+[ 3.734802] platform_probe+0x3d/0x90
+[ 3.735684] really_probe+0x19b/0x400
+[ 3.736570] ? __device_attach_driver+0x100/0x100
+[ 3.737697] __driver_probe_device+0x78/0x160
+[ 3.738746] driver_probe_device+0x1f/0x90
+[ 3.739743] __driver_attach+0xc2/0x1b0
+[ 3.740671] bus_for_each_dev+0x70/0xc0
+[ 3.741601] bus_add_driver+0x10e/0x210
+[ 3.742527] driver_register+0x55/0xf0
+[ 3.744412] ? 0xffffffffc039a000
+[ 3.745207] hv_acpi_init+0x3c/0x1000 [hv_vmbus]
+
+Fixes: 7f163a6fd957 ("drivers:hv: Modify hv_vmbus to search for all MMIO ranges available.")
+Signed-off-by: Maciej S. Szmigiero <maciej.szmigiero@oracle.com>
+Reviewed-by: Michael Kelley <mikelley@microsoft.com>
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Link: https://lore.kernel.org/r/fd8e64ceeecfd1d95ff49021080cf699e88dbbde.1691606267.git.maciej.szmigiero@oracle.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hv/vmbus_drv.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
+index 67f95a29aeca5..edbb38f6956b9 100644
+--- a/drivers/hv/vmbus_drv.c
++++ b/drivers/hv/vmbus_drv.c
+@@ -2287,7 +2287,8 @@ static int vmbus_acpi_add(struct platform_device *pdev)
+ * Some ancestor of the vmbus acpi device (Gen1 or Gen2
+ * firmware) is the VMOD that has the mmio ranges. Get that.
+ */
+- for (ancestor = acpi_dev_parent(device); ancestor;
++ for (ancestor = acpi_dev_parent(device);
++ ancestor && ancestor->handle != ACPI_ROOT_OBJECT;
+ ancestor = acpi_dev_parent(ancestor)) {
+ result = acpi_walk_resources(ancestor->handle, METHOD_NAME__CRS,
+ vmbus_walk_resources, NULL);
+--
+2.40.1
+
--- /dev/null
+From 0703520e987af866b13741a70f0c6512743057bc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 27 Feb 2023 18:24:08 +0800
+Subject: drivers: usb: smsusb: fix error handling code in smsusb_init_device
+
+From: Dongliang Mu <dzm91@hust.edu.cn>
+
+[ Upstream commit b9c7141f384097fa4fa67d2f72e5731d628aef7c ]
+
+The previous commit 4b208f8b561f ("[media] siano: register media controller
+earlier")moves siano_media_device_register before smscore_register_device,
+and adds corresponding error handling code if smscore_register_device
+fails. However, it misses the following error handling code of
+smsusb_init_device.
+
+Fix this by moving error handling code at the end of smsusb_init_device
+and adding a goto statement in the following error handling parts.
+
+Fixes: 4b208f8b561f ("[media] siano: register media controller earlier")
+Signed-off-by: Dongliang Mu <dzm91@hust.edu.cn>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/siano/smsusb.c | 21 +++++++++++----------
+ 1 file changed, 11 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/media/usb/siano/smsusb.c b/drivers/media/usb/siano/smsusb.c
+index 640737d3b8aeb..8a39cac76c585 100644
+--- a/drivers/media/usb/siano/smsusb.c
++++ b/drivers/media/usb/siano/smsusb.c
+@@ -455,12 +455,7 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id)
+ rc = smscore_register_device(¶ms, &dev->coredev, 0, mdev);
+ if (rc < 0) {
+ pr_err("smscore_register_device(...) failed, rc %d\n", rc);
+- smsusb_term_device(intf);
+-#ifdef CONFIG_MEDIA_CONTROLLER_DVB
+- media_device_unregister(mdev);
+-#endif
+- kfree(mdev);
+- return rc;
++ goto err_unregister_device;
+ }
+
+ smscore_set_board_id(dev->coredev, board_id);
+@@ -477,8 +472,7 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id)
+ rc = smsusb_start_streaming(dev);
+ if (rc < 0) {
+ pr_err("smsusb_start_streaming(...) failed\n");
+- smsusb_term_device(intf);
+- return rc;
++ goto err_unregister_device;
+ }
+
+ dev->state = SMSUSB_ACTIVE;
+@@ -486,13 +480,20 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id)
+ rc = smscore_start_device(dev->coredev);
+ if (rc < 0) {
+ pr_err("smscore_start_device(...) failed\n");
+- smsusb_term_device(intf);
+- return rc;
++ goto err_unregister_device;
+ }
+
+ pr_debug("device 0x%p created\n", dev);
+
+ return rc;
++
++err_unregister_device:
++ smsusb_term_device(intf);
++#ifdef CONFIG_MEDIA_CONTROLLER_DVB
++ media_device_unregister(mdev);
++#endif
++ kfree(mdev);
++ return rc;
+ }
+
+ static int smsusb_probe(struct usb_interface *intf,
+--
+2.40.1
+
--- /dev/null
+From 77439850c5298d53df9a166be906e9fd9a84e815 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Jul 2023 09:01:43 +0300
+Subject: drm: adv7511: Fix low refresh rate register for ADV7533/5
+
+From: Bogdan Togorean <bogdan.togorean@analog.com>
+
+[ Upstream commit d281eeaa4de2636ff0c8e6ae387bb07b50e5fcbb ]
+
+For ADV7533 and ADV7535 low refresh rate is selected using
+bits [3:2] of 0x4a main register.
+So depending on ADV model write 0xfb or 0x4a register.
+
+Fixes: 2437e7cd88e8 ("drm/bridge: adv7533: Initial support for ADV7533")
+Reviewed-by: Robert Foss <rfoss@kernel.org>
+Reviewed-by: Nuno Sa <nuno.sa@analog.com>
+Signed-off-by: Bogdan Togorean <bogdan.togorean@analog.com>
+Signed-off-by: Alexandru Ardelean <alex@shruggie.ro>
+Reviewed-by: Frieder Schrempf <frieder.schrempf@kontron.de>
+Signed-off-by: Robert Foss <rfoss@kernel.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230719060143.63649-1-alex@shruggie.ro
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+index ddceafa7b6374..8d6c93296503e 100644
+--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
++++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+@@ -786,8 +786,13 @@ static void adv7511_mode_set(struct adv7511 *adv7511,
+ else
+ low_refresh_rate = ADV7511_LOW_REFRESH_RATE_NONE;
+
+- regmap_update_bits(adv7511->regmap, 0xfb,
+- 0x6, low_refresh_rate << 1);
++ if (adv7511->type == ADV7511)
++ regmap_update_bits(adv7511->regmap, 0xfb,
++ 0x6, low_refresh_rate << 1);
++ else
++ regmap_update_bits(adv7511->regmap, 0x4a,
++ 0xc, low_refresh_rate << 2);
++
+ regmap_update_bits(adv7511->regmap, 0x17,
+ 0x60, (vsync_polarity << 6) | (hsync_polarity << 5));
+
+--
+2.40.1
+
--- /dev/null
+From 7bb8e4d3f15621da9814a92e5781b56afab4cd3e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Nov 2022 22:29:31 -0400
+Subject: drm/amd/display: Do not set drr on pipe commit
+
+From: Wesley Chalmers <Wesley.Chalmers@amd.com>
+
+[ Upstream commit e101bf95ea87ccc03ac2f48dfc0757c6364ff3c7 ]
+
+[WHY]
+Writing to DRR registers such as OTG_V_TOTAL_MIN on the same frame as a
+pipe commit can cause underflow.
+
+[HOW]
+Move DMUB p-state delegate into optimze_bandwidth; enabling FAMS sets
+optimized_required.
+
+This change expects that Freesync requests are blocked when
+optimized_required is true.
+
+Reviewed-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
+Signed-off-by: Wesley Chalmers <Wesley.Chalmers@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 6 ++++++
+ drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c | 7 +++++++
+ 2 files changed, 13 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+index a621b6a27c1fc..1ed30eba152e1 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+@@ -2124,6 +2124,12 @@ void dcn20_optimize_bandwidth(
+ if (hubbub->funcs->program_compbuf_size)
+ hubbub->funcs->program_compbuf_size(hubbub, context->bw_ctx.bw.dcn.compbuf_size_kb, true);
+
++ if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) {
++ dc_dmub_srv_p_state_delegate(dc,
++ true, context);
++ context->bw_ctx.bw.dcn.clk.p_state_change_support = true;
++ }
++
+ dc->clk_mgr->funcs->update_clocks(
+ dc->clk_mgr,
+ context,
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
+index 32121db2851e6..f923224e85fc6 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
+@@ -985,11 +985,18 @@ void dcn30_set_disp_pattern_generator(const struct dc *dc,
+ void dcn30_prepare_bandwidth(struct dc *dc,
+ struct dc_state *context)
+ {
++ if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) {
++ dc->optimized_required = true;
++ context->bw_ctx.bw.dcn.clk.p_state_change_support = false;
++ }
++
+ if (dc->clk_mgr->dc_mode_softmax_enabled)
+ if (dc->clk_mgr->clks.dramclk_khz <= dc->clk_mgr->bw_params->dc_mode_softmax_memclk * 1000 &&
+ context->bw_ctx.bw.dcn.clk.dramclk_khz > dc->clk_mgr->bw_params->dc_mode_softmax_memclk * 1000)
+ dc->clk_mgr->funcs->set_max_memclk(dc->clk_mgr, dc->clk_mgr->bw_params->clk_table.entries[dc->clk_mgr->bw_params->clk_table.num_entries - 1].memclk_mhz);
+
+ dcn20_prepare_bandwidth(dc, context);
++
++ dc_dmub_srv_p_state_delegate(dc, false, context);
+ }
+
+--
+2.40.1
+
--- /dev/null
+From a2f9e757c09e7be94a5f55de420e7c0448e06e68 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Aug 2023 16:53:23 +0800
+Subject: drm/amd/pm: fix variable dereferenced issue in
+ amdgpu_device_attr_create()
+
+From: Yang Wang <kevinyang.wang@amd.com>
+
+[ Upstream commit 25e6373a5b8efc623443f2699d2b929bf3067d76 ]
+
+- fix variable ('attr') dereferenced issue.
+- using condition check instead of BUG_ON().
+
+Fixes: 4e01847c38f7 ("drm/amdgpu: optimize amdgpu device attribute code")
+Cc: Dan Carpenter <dan.carpenter@linaro.org>
+Signed-off-by: Yang Wang <kevinyang.wang@amd.com>
+Reviewed-by: Kenneth Feng <kenneth.feng@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/pm/amdgpu_pm.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
+index f4f40459f22b9..a5b2a7d943f71 100644
+--- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c
++++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
+@@ -2195,15 +2195,19 @@ static int amdgpu_device_attr_create(struct amdgpu_device *adev,
+ uint32_t mask, struct list_head *attr_list)
+ {
+ int ret = 0;
+- struct device_attribute *dev_attr = &attr->dev_attr;
+- const char *name = dev_attr->attr.name;
+ enum amdgpu_device_attr_states attr_states = ATTR_STATE_SUPPORTED;
+ struct amdgpu_device_attr_entry *attr_entry;
++ struct device_attribute *dev_attr;
++ const char *name;
+
+ int (*attr_update)(struct amdgpu_device *adev, struct amdgpu_device_attr *attr,
+ uint32_t mask, enum amdgpu_device_attr_states *states) = default_attr_update;
+
+- BUG_ON(!attr);
++ if (!attr)
++ return -EINVAL;
++
++ dev_attr = &attr->dev_attr;
++ name = dev_attr->attr.name;
+
+ attr_update = attr->attr_update ? attr->attr_update : default_attr_update;
+
+--
+2.40.1
+
--- /dev/null
+From 316df071619f24040d04902013ba51926cffb787 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Jul 2023 13:11:51 +0200
+Subject: drm/amdgpu: avoid integer overflow warning in
+ amdgpu_device_resize_fb_bar()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 822130b5e8834ab30ad410cf19a582e5014b9a85 ]
+
+On 32-bit architectures comparing a resource against a value larger than
+U32_MAX can cause a warning:
+
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1344:18: error: result of comparison of constant 4294967296 with expression of type 'resource_size_t' (aka 'unsigned int') is always false [-Werror,-Wtautological-constant-out-of-range-compare]
+ res->start > 0x100000000ull)
+ ~~~~~~~~~~ ^ ~~~~~~~~~~~~~~
+
+As gcc does not warn about this in dead code, add an IS_ENABLED() check at
+the start of the function. This will always return success but not actually resize
+the BAR on 32-bit architectures without high memory, which is exactly what
+we want here, as the driver can fall back to bank switching the VRAM
+access.
+
+Fixes: 31b8adab3247 ("drm/amdgpu: require a root bus window above 4GB for BAR resize")
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+index 3108f5219cf3b..f7770e9c9aaca 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+@@ -1231,6 +1231,9 @@ int amdgpu_device_resize_fb_bar(struct amdgpu_device *adev)
+ u16 cmd;
+ int r;
+
++ if (!IS_ENABLED(CONFIG_PHYS_ADDR_T_64BIT))
++ return 0;
++
+ /* Bypass for VF */
+ if (amdgpu_sriov_vf(adev))
+ return 0;
+--
+2.40.1
+
--- /dev/null
+From 8c3175e4aabae47fd86649894abde9e08a7768d8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 23 Jul 2023 12:29:14 +0530
+Subject: drm/amdgpu: Update min() to min_t() in 'amdgpu_info_ioctl'
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+
+[ Upstream commit a0cc8e1512ad72c9f97cdcb76d42715730adaf62 ]
+
+Fixes the following:
+
+WARNING: min() should probably be min_t(size_t, size, sizeof(ip))
++ ret = copy_to_user(out, &ip, min((size_t)size, sizeof(ip)));
+
+And other style fixes:
+
+WARNING: Prefer 'unsigned int' to bare use of 'unsigned'
+WARNING: Missing a blank line after declarations
+
+Cc: Christian König <christian.koenig@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+index 724e80c192973..cecae6c1e8935 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+@@ -556,6 +556,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
+ crtc = (struct drm_crtc *)minfo->crtcs[i];
+ if (crtc && crtc->base.id == info->mode_crtc.id) {
+ struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
++
+ ui32 = amdgpu_crtc->crtc_id;
+ found = 1;
+ break;
+@@ -574,7 +575,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
+ if (ret)
+ return ret;
+
+- ret = copy_to_user(out, &ip, min((size_t)size, sizeof(ip)));
++ ret = copy_to_user(out, &ip, min_t(size_t, size, sizeof(ip)));
+ return ret ? -EFAULT : 0;
+ }
+ case AMDGPU_INFO_HW_IP_COUNT: {
+@@ -720,17 +721,18 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
+ ? -EFAULT : 0;
+ }
+ case AMDGPU_INFO_READ_MMR_REG: {
+- unsigned n, alloc_size;
++ unsigned int n, alloc_size;
+ uint32_t *regs;
+- unsigned se_num = (info->read_mmr_reg.instance >>
++ unsigned int se_num = (info->read_mmr_reg.instance >>
+ AMDGPU_INFO_MMR_SE_INDEX_SHIFT) &
+ AMDGPU_INFO_MMR_SE_INDEX_MASK;
+- unsigned sh_num = (info->read_mmr_reg.instance >>
++ unsigned int sh_num = (info->read_mmr_reg.instance >>
+ AMDGPU_INFO_MMR_SH_INDEX_SHIFT) &
+ AMDGPU_INFO_MMR_SH_INDEX_MASK;
+
+ /* set full masks if the userspace set all bits
+- * in the bitfields */
++ * in the bitfields
++ */
+ if (se_num == AMDGPU_INFO_MMR_SE_INDEX_MASK)
+ se_num = 0xffffffff;
+ else if (se_num >= AMDGPU_GFX_MAX_SE)
+@@ -882,7 +884,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
+ return ret;
+ }
+ case AMDGPU_INFO_VCE_CLOCK_TABLE: {
+- unsigned i;
++ unsigned int i;
+ struct drm_amdgpu_info_vce_clock_table vce_clk_table = {};
+ struct amd_vce_state *vce_state;
+
+--
+2.40.1
+
--- /dev/null
+From 6c5848042987e2328e66d716690bdda9b0cc2267 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Jul 2023 15:04:57 +0300
+Subject: drm/amdgpu: Use RMW accessors for changing LNKCTL
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit ce7d88110b9ed5f33fe79ea6d4ed049fb0e57bce ]
+
+Don't assume that only the driver would be accessing LNKCTL. ASPM policy
+changes can trigger write to LNKCTL outside of driver's control. And in
+the case of upstream bridge, the driver does not even own the device it's
+changing the registers for.
+
+Use RMW capability accessors which do proper locking to avoid losing
+concurrent updates to the register value.
+
+Suggested-by: Lukas Wunner <lukas@wunner.de>
+Fixes: a2e73f56fa62 ("drm/amdgpu: Add support for CIK parts")
+Fixes: 62a37553414a ("drm/amdgpu: add si implementation v10")
+Link: https://lore.kernel.org/r/20230717120503.15276-6-ilpo.jarvinen@linux.intel.com
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Acked-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/cik.c | 36 +++++++++-----------------------
+ drivers/gpu/drm/amd/amdgpu/si.c | 36 +++++++++-----------------------
+ 2 files changed, 20 insertions(+), 52 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/cik.c b/drivers/gpu/drm/amd/amdgpu/cik.c
+index de6d10390ab2f..9be6da37032a7 100644
+--- a/drivers/gpu/drm/amd/amdgpu/cik.c
++++ b/drivers/gpu/drm/amd/amdgpu/cik.c
+@@ -1574,17 +1574,8 @@ static void cik_pcie_gen3_enable(struct amdgpu_device *adev)
+ u16 bridge_cfg2, gpu_cfg2;
+ u32 max_lw, current_lw, tmp;
+
+- pcie_capability_read_word(root, PCI_EXP_LNKCTL,
+- &bridge_cfg);
+- pcie_capability_read_word(adev->pdev, PCI_EXP_LNKCTL,
+- &gpu_cfg);
+-
+- tmp16 = bridge_cfg | PCI_EXP_LNKCTL_HAWD;
+- pcie_capability_write_word(root, PCI_EXP_LNKCTL, tmp16);
+-
+- tmp16 = gpu_cfg | PCI_EXP_LNKCTL_HAWD;
+- pcie_capability_write_word(adev->pdev, PCI_EXP_LNKCTL,
+- tmp16);
++ pcie_capability_set_word(root, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD);
++ pcie_capability_set_word(adev->pdev, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD);
+
+ tmp = RREG32_PCIE(ixPCIE_LC_STATUS1);
+ max_lw = (tmp & PCIE_LC_STATUS1__LC_DETECTED_LINK_WIDTH_MASK) >>
+@@ -1637,21 +1628,14 @@ static void cik_pcie_gen3_enable(struct amdgpu_device *adev)
+ msleep(100);
+
+ /* linkctl */
+- pcie_capability_read_word(root, PCI_EXP_LNKCTL,
+- &tmp16);
+- tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
+- tmp16 |= (bridge_cfg & PCI_EXP_LNKCTL_HAWD);
+- pcie_capability_write_word(root, PCI_EXP_LNKCTL,
+- tmp16);
+-
+- pcie_capability_read_word(adev->pdev,
+- PCI_EXP_LNKCTL,
+- &tmp16);
+- tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
+- tmp16 |= (gpu_cfg & PCI_EXP_LNKCTL_HAWD);
+- pcie_capability_write_word(adev->pdev,
+- PCI_EXP_LNKCTL,
+- tmp16);
++ pcie_capability_clear_and_set_word(root, PCI_EXP_LNKCTL,
++ PCI_EXP_LNKCTL_HAWD,
++ bridge_cfg &
++ PCI_EXP_LNKCTL_HAWD);
++ pcie_capability_clear_and_set_word(adev->pdev, PCI_EXP_LNKCTL,
++ PCI_EXP_LNKCTL_HAWD,
++ gpu_cfg &
++ PCI_EXP_LNKCTL_HAWD);
+
+ /* linkctl2 */
+ pcie_capability_read_word(root, PCI_EXP_LNKCTL2,
+diff --git a/drivers/gpu/drm/amd/amdgpu/si.c b/drivers/gpu/drm/amd/amdgpu/si.c
+index 7f99e130acd06..fd34c2100bd96 100644
+--- a/drivers/gpu/drm/amd/amdgpu/si.c
++++ b/drivers/gpu/drm/amd/amdgpu/si.c
+@@ -2276,17 +2276,8 @@ static void si_pcie_gen3_enable(struct amdgpu_device *adev)
+ u16 bridge_cfg2, gpu_cfg2;
+ u32 max_lw, current_lw, tmp;
+
+- pcie_capability_read_word(root, PCI_EXP_LNKCTL,
+- &bridge_cfg);
+- pcie_capability_read_word(adev->pdev, PCI_EXP_LNKCTL,
+- &gpu_cfg);
+-
+- tmp16 = bridge_cfg | PCI_EXP_LNKCTL_HAWD;
+- pcie_capability_write_word(root, PCI_EXP_LNKCTL, tmp16);
+-
+- tmp16 = gpu_cfg | PCI_EXP_LNKCTL_HAWD;
+- pcie_capability_write_word(adev->pdev, PCI_EXP_LNKCTL,
+- tmp16);
++ pcie_capability_set_word(root, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD);
++ pcie_capability_set_word(adev->pdev, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD);
+
+ tmp = RREG32_PCIE(PCIE_LC_STATUS1);
+ max_lw = (tmp & LC_DETECTED_LINK_WIDTH_MASK) >> LC_DETECTED_LINK_WIDTH_SHIFT;
+@@ -2331,21 +2322,14 @@ static void si_pcie_gen3_enable(struct amdgpu_device *adev)
+
+ mdelay(100);
+
+- pcie_capability_read_word(root, PCI_EXP_LNKCTL,
+- &tmp16);
+- tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
+- tmp16 |= (bridge_cfg & PCI_EXP_LNKCTL_HAWD);
+- pcie_capability_write_word(root, PCI_EXP_LNKCTL,
+- tmp16);
+-
+- pcie_capability_read_word(adev->pdev,
+- PCI_EXP_LNKCTL,
+- &tmp16);
+- tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
+- tmp16 |= (gpu_cfg & PCI_EXP_LNKCTL_HAWD);
+- pcie_capability_write_word(adev->pdev,
+- PCI_EXP_LNKCTL,
+- tmp16);
++ pcie_capability_clear_and_set_word(root, PCI_EXP_LNKCTL,
++ PCI_EXP_LNKCTL_HAWD,
++ bridge_cfg &
++ PCI_EXP_LNKCTL_HAWD);
++ pcie_capability_clear_and_set_word(adev->pdev, PCI_EXP_LNKCTL,
++ PCI_EXP_LNKCTL_HAWD,
++ gpu_cfg &
++ PCI_EXP_LNKCTL_HAWD);
+
+ pcie_capability_read_word(root, PCI_EXP_LNKCTL2,
+ &tmp16);
+--
+2.40.1
+
--- /dev/null
+From 7450ca61465e9de1a35e8be1fd652b65eb2757b7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Jul 2023 15:25:40 +0200
+Subject: drm/armada: Fix off-by-one error in armada_overlay_get_property()
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit 5f0d984053f74983a287100a9519b2fabb785fb5 ]
+
+As ffs() returns one more than the index of the first bit set (zero
+means no bits set), the color key mode value is shifted one position too
+much.
+
+Fix this by using FIELD_GET() instead.
+
+Fixes: c96103b6c49ff9a8 ("drm/armada: move colorkey properties into overlay plane state")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/a4d779d954a7515ddbbf31cb0f0d8184c0e7c879.1689600265.git.geert+renesas@glider.be
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/armada/armada_overlay.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c
+index f21eb8fb76d87..3b9bd8ecda137 100644
+--- a/drivers/gpu/drm/armada/armada_overlay.c
++++ b/drivers/gpu/drm/armada/armada_overlay.c
+@@ -4,6 +4,8 @@
+ * Rewritten from the dovefb driver, and Armada510 manuals.
+ */
+
++#include <linux/bitfield.h>
++
+ #include <drm/armada_drm.h>
+ #include <drm/drm_atomic.h>
+ #include <drm/drm_atomic_helper.h>
+@@ -445,8 +447,8 @@ static int armada_overlay_get_property(struct drm_plane *plane,
+ drm_to_overlay_state(state)->colorkey_ug,
+ drm_to_overlay_state(state)->colorkey_vb, 0);
+ } else if (property == priv->colorkey_mode_prop) {
+- *val = (drm_to_overlay_state(state)->colorkey_mode &
+- CFG_CKMODE_MASK) >> ffs(CFG_CKMODE_MASK);
++ *val = FIELD_GET(CFG_CKMODE_MASK,
++ drm_to_overlay_state(state)->colorkey_mode);
+ } else if (property == priv->brightness_prop) {
+ *val = drm_to_overlay_state(state)->brightness + 256;
+ } else if (property == priv->contrast_prop) {
+--
+2.40.1
+
--- /dev/null
+From ef144764033f77fd6af5b2ef76d30f1c4b5fdb88 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Jul 2023 15:41:31 +0200
+Subject: drm/ast: report connection status on Display Port.
+
+From: Jocelyn Falempe <jfalempe@redhat.com>
+
+[ Upstream commit f81bb0ac7872893241319ea82504956676ef02fd ]
+
+Aspeed always report the display port as "connected", because it
+doesn't set a .detect_ctx callback.
+Fix this by providing the proper detect callback for astdp and dp501.
+
+This also fixes the following regression:
+Since commit fae7d186403e ("drm/probe-helper: Default to 640x480 if no
+EDID on DP") The default resolution is now 640x480 when no monitor is
+connected. But Aspeed graphics is mostly used in servers, where no monitor
+is attached. This also affects the remote BMC resolution to 640x480, which
+is inconvenient, and breaks the anaconda installer.
+
+v2: Add .detect callback to the dp/dp501 connector (Jani Nikula)
+v3: Use .detect_ctx callback, and refactors (Thomas Zimmermann)
+ Add a BMC virtual connector
+v4: Better indent detect_ctx() functions (Thomas Zimmermann)
+v5: Enable polling of the dp and dp501 connector status
+ (Thomas Zimmermann)
+v6: Change check order in ast_astdp_is_connected (Jammy Huang)
+
+Fixes: fae7d186403e ("drm/probe-helper: Default to 640x480 if no EDID on DP")
+Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
+Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230713134316.332502-2-jfalempe@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/ast/ast_dp.c | 11 ++++++++++
+ drivers/gpu/drm/ast/ast_dp501.c | 37 ++++++++++++++++++++++-----------
+ drivers/gpu/drm/ast/ast_drv.h | 2 ++
+ drivers/gpu/drm/ast/ast_mode.c | 30 ++++++++++++++++++++++++--
+ 4 files changed, 66 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/gpu/drm/ast/ast_dp.c b/drivers/gpu/drm/ast/ast_dp.c
+index 6dc1a09504e13..fdd9a493aa9c0 100644
+--- a/drivers/gpu/drm/ast/ast_dp.c
++++ b/drivers/gpu/drm/ast/ast_dp.c
+@@ -7,6 +7,17 @@
+ #include <drm/drm_print.h>
+ #include "ast_drv.h"
+
++bool ast_astdp_is_connected(struct ast_device *ast)
++{
++ if (!ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, ASTDP_MCU_FW_EXECUTING))
++ return false;
++ if (!ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDF, ASTDP_HPD))
++ return false;
++ if (!ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDC, ASTDP_LINK_SUCCESS))
++ return false;
++ return true;
++}
++
+ int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata)
+ {
+ struct ast_device *ast = to_ast_device(dev);
+diff --git a/drivers/gpu/drm/ast/ast_dp501.c b/drivers/gpu/drm/ast/ast_dp501.c
+index 1bc35a992369d..fa7442b0c2612 100644
+--- a/drivers/gpu/drm/ast/ast_dp501.c
++++ b/drivers/gpu/drm/ast/ast_dp501.c
+@@ -272,11 +272,9 @@ static bool ast_launch_m68k(struct drm_device *dev)
+ return true;
+ }
+
+-bool ast_dp501_read_edid(struct drm_device *dev, u8 *ediddata)
++bool ast_dp501_is_connected(struct ast_device *ast)
+ {
+- struct ast_device *ast = to_ast_device(dev);
+- u32 i, boot_address, offset, data;
+- u32 *pEDIDidx;
++ u32 boot_address, offset, data;
+
+ if (ast->config_mode == ast_use_p2a) {
+ boot_address = get_fw_base(ast);
+@@ -292,14 +290,6 @@ bool ast_dp501_read_edid(struct drm_device *dev, u8 *ediddata)
+ data = ast_mindwm(ast, boot_address + offset);
+ if (!(data & AST_DP501_PNP_CONNECTED))
+ return false;
+-
+- /* Read EDID */
+- offset = AST_DP501_EDID_DATA;
+- for (i = 0; i < 128; i += 4) {
+- data = ast_mindwm(ast, boot_address + offset + i);
+- pEDIDidx = (u32 *)(ediddata + i);
+- *pEDIDidx = data;
+- }
+ } else {
+ if (!ast->dp501_fw_buf)
+ return false;
+@@ -319,7 +309,30 @@ bool ast_dp501_read_edid(struct drm_device *dev, u8 *ediddata)
+ data = readl(ast->dp501_fw_buf + offset);
+ if (!(data & AST_DP501_PNP_CONNECTED))
+ return false;
++ }
++ return true;
++}
++
++bool ast_dp501_read_edid(struct drm_device *dev, u8 *ediddata)
++{
++ struct ast_device *ast = to_ast_device(dev);
++ u32 i, boot_address, offset, data;
++ u32 *pEDIDidx;
++
++ if (!ast_dp501_is_connected(ast))
++ return false;
++
++ if (ast->config_mode == ast_use_p2a) {
++ boot_address = get_fw_base(ast);
+
++ /* Read EDID */
++ offset = AST_DP501_EDID_DATA;
++ for (i = 0; i < 128; i += 4) {
++ data = ast_mindwm(ast, boot_address + offset + i);
++ pEDIDidx = (u32 *)(ediddata + i);
++ *pEDIDidx = data;
++ }
++ } else {
+ /* Read EDID */
+ offset = AST_DP501_EDID_DATA;
+ for (i = 0; i < 128; i += 4) {
+diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h
+index 5498a6676f2e8..8a0ffa8b5939b 100644
+--- a/drivers/gpu/drm/ast/ast_drv.h
++++ b/drivers/gpu/drm/ast/ast_drv.h
+@@ -468,6 +468,7 @@ void ast_patch_ahb_2500(struct ast_device *ast);
+ /* ast dp501 */
+ void ast_set_dp501_video_output(struct drm_device *dev, u8 mode);
+ bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size);
++bool ast_dp501_is_connected(struct ast_device *ast);
+ bool ast_dp501_read_edid(struct drm_device *dev, u8 *ediddata);
+ u8 ast_get_dp501_max_clk(struct drm_device *dev);
+ void ast_init_3rdtx(struct drm_device *dev);
+@@ -476,6 +477,7 @@ void ast_init_3rdtx(struct drm_device *dev);
+ struct ast_i2c_chan *ast_i2c_create(struct drm_device *dev);
+
+ /* aspeed DP */
++bool ast_astdp_is_connected(struct ast_device *ast);
+ int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata);
+ void ast_dp_launch(struct drm_device *dev);
+ void ast_dp_power_on_off(struct drm_device *dev, bool no);
+diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
+index b3c670af6ef2b..0724516f29737 100644
+--- a/drivers/gpu/drm/ast/ast_mode.c
++++ b/drivers/gpu/drm/ast/ast_mode.c
+@@ -1585,8 +1585,20 @@ static int ast_dp501_connector_helper_get_modes(struct drm_connector *connector)
+ return 0;
+ }
+
++static int ast_dp501_connector_helper_detect_ctx(struct drm_connector *connector,
++ struct drm_modeset_acquire_ctx *ctx,
++ bool force)
++{
++ struct ast_device *ast = to_ast_device(connector->dev);
++
++ if (ast_dp501_is_connected(ast))
++ return connector_status_connected;
++ return connector_status_disconnected;
++}
++
+ static const struct drm_connector_helper_funcs ast_dp501_connector_helper_funcs = {
+ .get_modes = ast_dp501_connector_helper_get_modes,
++ .detect_ctx = ast_dp501_connector_helper_detect_ctx,
+ };
+
+ static const struct drm_connector_funcs ast_dp501_connector_funcs = {
+@@ -1611,7 +1623,7 @@ static int ast_dp501_connector_init(struct drm_device *dev, struct drm_connector
+ connector->interlace_allowed = 0;
+ connector->doublescan_allowed = 0;
+
+- connector->polled = DRM_CONNECTOR_POLL_CONNECT;
++ connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
+
+ return 0;
+ }
+@@ -1683,8 +1695,20 @@ static int ast_astdp_connector_helper_get_modes(struct drm_connector *connector)
+ return 0;
+ }
+
++static int ast_astdp_connector_helper_detect_ctx(struct drm_connector *connector,
++ struct drm_modeset_acquire_ctx *ctx,
++ bool force)
++{
++ struct ast_device *ast = to_ast_device(connector->dev);
++
++ if (ast_astdp_is_connected(ast))
++ return connector_status_connected;
++ return connector_status_disconnected;
++}
++
+ static const struct drm_connector_helper_funcs ast_astdp_connector_helper_funcs = {
+ .get_modes = ast_astdp_connector_helper_get_modes,
++ .detect_ctx = ast_astdp_connector_helper_detect_ctx,
+ };
+
+ static const struct drm_connector_funcs ast_astdp_connector_funcs = {
+@@ -1709,7 +1733,7 @@ static int ast_astdp_connector_init(struct drm_device *dev, struct drm_connector
+ connector->interlace_allowed = 0;
+ connector->doublescan_allowed = 0;
+
+- connector->polled = DRM_CONNECTOR_POLL_CONNECT;
++ connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
+
+ return 0;
+ }
+@@ -1848,5 +1872,7 @@ int ast_mode_config_init(struct ast_device *ast)
+
+ drm_mode_config_reset(dev);
+
++ drm_kms_helper_poll_init(dev);
++
+ return 0;
+ }
+--
+2.40.1
+
--- /dev/null
+From 9476b457cbf3f8b43750405e650439bcf7989394 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Jul 2023 17:09:27 +0800
+Subject: drm/bridge: anx7625: Use common macros for DP power sequencing
+ commands
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Chen-Yu Tsai <wenst@chromium.org>
+
+[ Upstream commit 2ba776f903cb7157e80b5f314fb0b4faf6ea6958 ]
+
+The DRM DP code has macros for the DP power sequencing commands. Use
+them in the anx7625 driver instead of raw numbers.
+
+Fixes: 548b512e144f ("drm/bridge: anx7625: send DPCD command to downstream")
+Fixes: 27f26359de9b ("drm/bridge: anx7625: Set downstream sink into normal status")
+Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
+Reviewed-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Signed-off-by: Robert Foss <rfoss@kernel.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230710090929.1873646-1-wenst@chromium.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/analogix/anx7625.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c
+index 9e387c3e9b696..4f1286d948bde 100644
+--- a/drivers/gpu/drm/bridge/analogix/anx7625.c
++++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
+@@ -932,8 +932,8 @@ static void anx7625_dp_start(struct anx7625_data *ctx)
+
+ dev_dbg(dev, "set downstream sink into normal\n");
+ /* Downstream sink enter into normal mode */
+- data = 1;
+- ret = anx7625_aux_trans(ctx, DP_AUX_NATIVE_WRITE, 0x000600, 1, &data);
++ data = DP_SET_POWER_D0;
++ ret = anx7625_aux_trans(ctx, DP_AUX_NATIVE_WRITE, DP_SET_POWER, 1, &data);
+ if (ret < 0)
+ dev_err(dev, "IO error : set sink into normal mode fail\n");
+
+@@ -972,8 +972,8 @@ static void anx7625_dp_stop(struct anx7625_data *ctx)
+
+ dev_dbg(dev, "notify downstream enter into standby\n");
+ /* Downstream monitor enter into standby mode */
+- data = 2;
+- ret |= anx7625_aux_trans(ctx, DP_AUX_NATIVE_WRITE, 0x000600, 1, &data);
++ data = DP_SET_POWER_D3;
++ ret |= anx7625_aux_trans(ctx, DP_AUX_NATIVE_WRITE, DP_SET_POWER, 1, &data);
+ if (ret < 0)
+ DRM_DEV_ERROR(dev, "IO error : mute video fail\n");
+
+--
+2.40.1
+
--- /dev/null
+From c38d1196786525d939efa0dbf5e1e6ba3003f998 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Jul 2023 17:12:01 +0800
+Subject: drm/bridge: anx7625: Use common macros for HDCP capabilities
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Chen-Yu Tsai <wenst@chromium.org>
+
+[ Upstream commit 41639b3a8b0f1f194dfe0577d99db70613f78626 ]
+
+The DRM DP code has macros for the DP HDCP capabilities. Use them in the
+anx7625 driver instead of raw numbers.
+
+Fixes: cd1637c7e480 ("drm/bridge: anx7625: add HDCP support")
+Suggested-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
+Reviewed-by: Robert Foss <rfoss@kernel.org>
+Signed-off-by: Robert Foss <rfoss@kernel.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230710091203.1874317-1-wenst@chromium.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/analogix/anx7625.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c
+index 4f1286d948bde..666a2b5c0c5c0 100644
+--- a/drivers/gpu/drm/bridge/analogix/anx7625.c
++++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
+@@ -873,11 +873,11 @@ static int anx7625_hdcp_enable(struct anx7625_data *ctx)
+ }
+
+ /* Read downstream capability */
+- ret = anx7625_aux_trans(ctx, DP_AUX_NATIVE_READ, 0x68028, 1, &bcap);
++ ret = anx7625_aux_trans(ctx, DP_AUX_NATIVE_READ, DP_AUX_HDCP_BCAPS, 1, &bcap);
+ if (ret < 0)
+ return ret;
+
+- if (!(bcap & 0x01)) {
++ if (!(bcap & DP_BCAPS_HDCP_CAPABLE)) {
+ pr_warn("downstream not support HDCP 1.4, cap(%x).\n", bcap);
+ return 0;
+ }
+--
+2.40.1
+
--- /dev/null
+From 5c902b07a73d29fb4659ce6335a207e047f87ebb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 18 Jun 2023 00:48:25 +0200
+Subject: drm: bridge: dw-mipi-dsi: Fix enable/disable of DSI controller
+
+From: Ondrej Jirman <megi@xff.cz>
+
+[ Upstream commit 05aa61334592adb230749ff465b103ee10e63936 ]
+
+Before this patch, booting to Linux VT and doing a simple:
+
+ echo 2 > /sys/class/graphics/fb0/blank
+ echo 0 > /sys/class/graphics/fb0/blank
+
+would result in failures to re-enable the panel. Mode set callback is
+called only once during boot in this scenario, while calls to
+enable/disable callbacks are balanced afterwards. The driver doesn't
+work unless userspace calls modeset before enabling the CRTC/connector.
+
+This patch moves enabling of the DSI host from mode_set into pre_enable
+callback, and removes some old hacks where this bridge driver is
+directly calling into other bridge driver's callbacks.
+
+pre_enable_prev_first flag is set on the panel's bridge so that panel
+drivers will get their prepare function called between DSI host's
+pre_enable and enable callbacks, so that they get a chance to
+perform panel setup while DSI host is already enabled in command
+mode. Otherwise panel's prepare would be called before DSI host
+is enabled, and any DSI communication used in prepare callback
+would fail.
+
+With all these changes, the enable/disable sequence is now well
+balanced, and host's and panel's callbacks are called in proper order
+documented in the drm_panel API documentation without needing the old
+hacks. (Mainly that panel->prepare is called when DSI host is ready to
+allow the panel driver to send DSI commands and vice versa during
+disable.)
+
+Tested on Pinephone Pro. Trace of the callbacks follows.
+
+Before:
+
+[ 1.253882] dw-mipi-dsi-rockchip ff960000.dsi: mode_set
+[ 1.290732] panel-himax-hx8394 ff960000.dsi.0: prepare
+[ 1.475576] dw-mipi-dsi-rockchip ff960000.dsi: enable
+[ 1.475593] panel-himax-hx8394 ff960000.dsi.0: enable
+
+echo 2 > /sys/class/graphics/fb0/blank
+
+[ 13.722799] panel-himax-hx8394 ff960000.dsi.0: disable
+[ 13.774502] dw-mipi-dsi-rockchip ff960000.dsi: post_disable
+[ 13.774526] panel-himax-hx8394 ff960000.dsi.0: unprepare
+
+echo 0 > /sys/class/graphics/fb0/blank
+
+[ 17.735796] panel-himax-hx8394 ff960000.dsi.0: prepare
+[ 17.923522] dw-mipi-dsi-rockchip ff960000.dsi: enable
+[ 17.923540] panel-himax-hx8394 ff960000.dsi.0: enable
+[ 17.944330] dw-mipi-dsi-rockchip ff960000.dsi: failed to write command FIFO
+[ 17.944335] panel-himax-hx8394 ff960000.dsi.0: sending command 0xb9 failed: -110
+[ 17.944340] panel-himax-hx8394 ff960000.dsi.0: Panel init sequence failed: -110
+
+echo 2 > /sys/class/graphics/fb0/blank
+
+[ 431.148583] panel-himax-hx8394 ff960000.dsi.0: disable
+[ 431.169259] dw-mipi-dsi-rockchip ff960000.dsi: failed to write command FIFO
+[ 431.169268] panel-himax-hx8394 ff960000.dsi.0: Failed to enter sleep mode: -110
+[ 431.169282] dw-mipi-dsi-rockchip ff960000.dsi: post_disable
+[ 431.169316] panel-himax-hx8394 ff960000.dsi.0: unprepare
+[ 431.169357] pclk_mipi_dsi0 already disabled
+
+echo 0 > /sys/class/graphics/fb0/blank
+
+[ 432.796851] panel-himax-hx8394 ff960000.dsi.0: prepare
+[ 432.981537] dw-mipi-dsi-rockchip ff960000.dsi: enable
+[ 432.981568] panel-himax-hx8394 ff960000.dsi.0: enable
+[ 433.002290] dw-mipi-dsi-rockchip ff960000.dsi: failed to write command FIFO
+[ 433.002299] panel-himax-hx8394 ff960000.dsi.0: sending command 0xb9 failed: -110
+[ 433.002312] panel-himax-hx8394 ff960000.dsi.0: Panel init sequence failed: -110
+
+-----------------------------------------------------------------------
+
+After:
+
+[ 1.248372] dw-mipi-dsi-rockchip ff960000.dsi: mode_set
+[ 1.248704] dw-mipi-dsi-rockchip ff960000.dsi: pre_enable
+[ 1.285377] panel-himax-hx8394 ff960000.dsi.0: prepare
+[ 1.468392] dw-mipi-dsi-rockchip ff960000.dsi: enable
+[ 1.468421] panel-himax-hx8394 ff960000.dsi.0: enable
+
+echo 2 > /sys/class/graphics/fb0/blank
+
+[ 16.210357] panel-himax-hx8394 ff960000.dsi.0: disable
+[ 16.261315] dw-mipi-dsi-rockchip ff960000.dsi: post_disable
+[ 16.261339] panel-himax-hx8394 ff960000.dsi.0: unprepare
+
+echo 0 > /sys/class/graphics/fb0/blank
+
+[ 19.161453] dw-mipi-dsi-rockchip ff960000.dsi: pre_enable
+[ 19.197869] panel-himax-hx8394 ff960000.dsi.0: prepare
+[ 19.382141] dw-mipi-dsi-rockchip ff960000.dsi: enable
+[ 19.382158] panel-himax-hx8394 ff960000.dsi.0: enable
+
+ (But depends on functionality intorduced in Linux 6.3, so this patch will
+ not build on older kernels when applied to older stable branches.)
+
+Fixes: 46fc51546d44 ("drm/bridge/synopsys: Add MIPI DSI host controller bridge")
+Signed-off-by: Ondrej Jirman <megi@xff.cz>
+Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
+Signed-off-by: Robert Foss <rfoss@kernel.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230617224915.1923630-1-megi@xff.cz
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 28 +++++++++++--------
+ 1 file changed, 16 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+index b2efecf7d1603..4291798bd70f5 100644
+--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
++++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+@@ -265,6 +265,7 @@ struct dw_mipi_dsi {
+ struct dw_mipi_dsi *master; /* dual-dsi master ptr */
+ struct dw_mipi_dsi *slave; /* dual-dsi slave ptr */
+
++ struct drm_display_mode mode;
+ const struct dw_mipi_dsi_plat_data *plat_data;
+ };
+
+@@ -332,6 +333,7 @@ static int dw_mipi_dsi_host_attach(struct mipi_dsi_host *host,
+ if (IS_ERR(bridge))
+ return PTR_ERR(bridge);
+
++ bridge->pre_enable_prev_first = true;
+ dsi->panel_bridge = bridge;
+
+ drm_bridge_add(&dsi->bridge);
+@@ -859,15 +861,6 @@ static void dw_mipi_dsi_bridge_post_atomic_disable(struct drm_bridge *bridge,
+ */
+ dw_mipi_dsi_set_mode(dsi, 0);
+
+- /*
+- * TODO Only way found to call panel-bridge post_disable &
+- * panel unprepare before the dsi "final" disable...
+- * This needs to be fixed in the drm_bridge framework and the API
+- * needs to be updated to manage our own call chains...
+- */
+- if (dsi->panel_bridge->funcs->post_disable)
+- dsi->panel_bridge->funcs->post_disable(dsi->panel_bridge);
+-
+ if (phy_ops->power_off)
+ phy_ops->power_off(dsi->plat_data->priv_data);
+
+@@ -942,15 +935,25 @@ static void dw_mipi_dsi_mode_set(struct dw_mipi_dsi *dsi,
+ phy_ops->power_on(dsi->plat_data->priv_data);
+ }
+
++static void dw_mipi_dsi_bridge_atomic_pre_enable(struct drm_bridge *bridge,
++ struct drm_bridge_state *old_bridge_state)
++{
++ struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge);
++
++ /* Power up the dsi ctl into a command mode */
++ dw_mipi_dsi_mode_set(dsi, &dsi->mode);
++ if (dsi->slave)
++ dw_mipi_dsi_mode_set(dsi->slave, &dsi->mode);
++}
++
+ static void dw_mipi_dsi_bridge_mode_set(struct drm_bridge *bridge,
+ const struct drm_display_mode *mode,
+ const struct drm_display_mode *adjusted_mode)
+ {
+ struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge);
+
+- dw_mipi_dsi_mode_set(dsi, adjusted_mode);
+- if (dsi->slave)
+- dw_mipi_dsi_mode_set(dsi->slave, adjusted_mode);
++ /* Store the display mode for later use in pre_enable callback */
++ drm_mode_copy(&dsi->mode, adjusted_mode);
+ }
+
+ static void dw_mipi_dsi_bridge_atomic_enable(struct drm_bridge *bridge,
+@@ -1004,6 +1007,7 @@ static const struct drm_bridge_funcs dw_mipi_dsi_bridge_funcs = {
+ .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
+ .atomic_reset = drm_atomic_helper_bridge_reset,
++ .atomic_pre_enable = dw_mipi_dsi_bridge_atomic_pre_enable,
+ .atomic_enable = dw_mipi_dsi_bridge_atomic_enable,
+ .atomic_post_disable = dw_mipi_dsi_bridge_post_atomic_disable,
+ .mode_set = dw_mipi_dsi_bridge_mode_set,
+--
+2.40.1
+
--- /dev/null
+From 8ee992945ed086b46aaa3f9f7806f43b5f529013 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Jun 2023 17:28:17 +0200
+Subject: drm/bridge: tc358764: Fix debug print parameter order
+
+From: Marek Vasut <marex@denx.de>
+
+[ Upstream commit 7f947be02aab5b154427cb5b0fffe858fc387b02 ]
+
+The debug print parameters were swapped in the output and they were
+printed as decimal values, both the hardware address and the value.
+Update the debug print to print the parameters in correct order, and
+use hexadecimal print for both address and value.
+
+Fixes: f38b7cca6d0e ("drm/bridge: tc358764: Add DSI to LVDS bridge driver")
+Signed-off-by: Marek Vasut <marex@denx.de>
+Reviewed-by: Robert Foss <rfoss@kernel.org>
+Signed-off-by: Robert Foss <rfoss@kernel.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230615152817.359420-1-marex@denx.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/tc358764.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/bridge/tc358764.c b/drivers/gpu/drm/bridge/tc358764.c
+index f85654f1b1045..8e938a7480f37 100644
+--- a/drivers/gpu/drm/bridge/tc358764.c
++++ b/drivers/gpu/drm/bridge/tc358764.c
+@@ -176,7 +176,7 @@ static void tc358764_read(struct tc358764 *ctx, u16 addr, u32 *val)
+ if (ret >= 0)
+ le32_to_cpus(val);
+
+- dev_dbg(ctx->dev, "read: %d, addr: %d\n", addr, *val);
++ dev_dbg(ctx->dev, "read: addr=0x%04x data=0x%08x\n", addr, *val);
+ }
+
+ static void tc358764_write(struct tc358764 *ctx, u16 addr, u32 val)
+--
+2.40.1
+
--- /dev/null
+From 2f9201d554db5bc6282434fe10ed0f73fa4b03cf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Apr 2023 16:38:10 +0200
+Subject: drm/etnaviv: fix dumping of active MMU context
+
+From: Lucas Stach <l.stach@pengutronix.de>
+
+[ Upstream commit 20faf2005ec85fa1a6acc9a74ff27de667f90576 ]
+
+gpu->mmu_context is the MMU context of the last job in the HW queue, which
+isn't necessarily the same as the context from the bad job. Dump the MMU
+context from the scheduler determined bad submit to make it work as intended.
+
+Fixes: 17e4660ae3d7 ("drm/etnaviv: implement per-process address spaces on MMUv2")
+Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
+Reviewed-by: Christian Gmeiner <christian.gmeiner@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/etnaviv/etnaviv_dump.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/gpu/drm/etnaviv/etnaviv_dump.c b/drivers/gpu/drm/etnaviv/etnaviv_dump.c
+index 44b5f3c35aabe..898f84a0fc30c 100644
+--- a/drivers/gpu/drm/etnaviv/etnaviv_dump.c
++++ b/drivers/gpu/drm/etnaviv/etnaviv_dump.c
+@@ -130,9 +130,9 @@ void etnaviv_core_dump(struct etnaviv_gem_submit *submit)
+ return;
+ etnaviv_dump_core = false;
+
+- mutex_lock(&gpu->mmu_context->lock);
++ mutex_lock(&submit->mmu_context->lock);
+
+- mmu_size = etnaviv_iommu_dump_size(gpu->mmu_context);
++ mmu_size = etnaviv_iommu_dump_size(submit->mmu_context);
+
+ /* We always dump registers, mmu, ring, hanging cmdbuf and end marker */
+ n_obj = 5;
+@@ -162,7 +162,7 @@ void etnaviv_core_dump(struct etnaviv_gem_submit *submit)
+ iter.start = __vmalloc(file_size, GFP_KERNEL | __GFP_NOWARN |
+ __GFP_NORETRY);
+ if (!iter.start) {
+- mutex_unlock(&gpu->mmu_context->lock);
++ mutex_unlock(&submit->mmu_context->lock);
+ dev_warn(gpu->dev, "failed to allocate devcoredump file\n");
+ return;
+ }
+@@ -174,18 +174,18 @@ void etnaviv_core_dump(struct etnaviv_gem_submit *submit)
+ memset(iter.hdr, 0, iter.data - iter.start);
+
+ etnaviv_core_dump_registers(&iter, gpu);
+- etnaviv_core_dump_mmu(&iter, gpu->mmu_context, mmu_size);
++ etnaviv_core_dump_mmu(&iter, submit->mmu_context, mmu_size);
+ etnaviv_core_dump_mem(&iter, ETDUMP_BUF_RING, gpu->buffer.vaddr,
+ gpu->buffer.size,
+ etnaviv_cmdbuf_get_va(&gpu->buffer,
+- &gpu->mmu_context->cmdbuf_mapping));
++ &submit->mmu_context->cmdbuf_mapping));
+
+ etnaviv_core_dump_mem(&iter, ETDUMP_BUF_CMD,
+ submit->cmdbuf.vaddr, submit->cmdbuf.size,
+ etnaviv_cmdbuf_get_va(&submit->cmdbuf,
+- &gpu->mmu_context->cmdbuf_mapping));
++ &submit->mmu_context->cmdbuf_mapping));
+
+- mutex_unlock(&gpu->mmu_context->lock);
++ mutex_unlock(&submit->mmu_context->lock);
+
+ /* Reserve space for the bomap */
+ if (n_bomap_pages) {
+--
+2.40.1
+
--- /dev/null
+From b88041c9d85760ff0d93d1258c35141ba265e496 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Jul 2023 18:05:14 +0800
+Subject: drm/hyperv: Fix a compilation issue because of not including
+ screen_info.h
+
+From: Sui Jingfeng <suijingfeng@loongson.cn>
+
+[ Upstream commit 8d1077cf2e43b15fefd76ebec2b71541eb27ef2c ]
+
+Fixes the following build errors on arm64:
+
+drivers/video/fbdev/hyperv_fb.c: In function 'hvfb_getmem':
+>> drivers/video/fbdev/hyperv_fb.c:1033:24: error: 'screen_info' undeclared (first use in this function)
+ 1033 | base = screen_info.lfb_base;
+ | ^~~~~~~~~~~
+drivers/video/fbdev/hyperv_fb.c:1033:24: note: each undeclared identifier is reported only once for each function it appears in
+
+>> drivers/gpu/drm/hyperv/hyperv_drm_drv.c:75:54: error: 'screen_info' undeclared (first use in this function)
+ 75 | drm_aperture_remove_conflicting_framebuffers(screen_info.lfb_base,
+ | ^~~~~~~~~~~
+drivers/gpu/drm/hyperv/hyperv_drm_drv.c:75:54: note: each undeclared identifier is reported only once for each function it appears in
+
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202307090823.nxnT8Kk5-lkp@intel.com/
+Fixes: 81d2393485f0 ("fbdev/hyperv-fb: Do not set struct fb_info.apertures")
+Fixes: 8b0d13545b09 ("efi: Do not include <linux/screen_info.h> from EFI header")
+Signed-off-by: Sui Jingfeng <suijingfeng@loongson.cn>
+Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
+Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230709100514.703759-1-suijingfeng@loongson.cn
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/hyperv/hyperv_drm_drv.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c
+index f830d62a5ce60..559ce242919df 100644
+--- a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c
++++ b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c
+@@ -7,6 +7,7 @@
+ #include <linux/hyperv.h>
+ #include <linux/module.h>
+ #include <linux/pci.h>
++#include <linux/screen_info.h>
+
+ #include <drm/drm_aperture.h>
+ #include <drm/drm_atomic_helper.h>
+--
+2.40.1
+
--- /dev/null
+From b94a4158d92b3f96b71c40bbda295ed02de50e72 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Jul 2023 17:49:06 +0800
+Subject: drm/mediatek: Add cnt checking for coverity issue
+
+From: Jason-JH.Lin <jason-jh.lin@mediatek.com>
+
+[ Upstream commit d761b9450e31e5abd212f0085d424ed32760de5a ]
+
+CERT-C Characters and Strings (CERT STR31-C)
+all_drm_priv[cnt] evaluates to an address that could be at negative
+offset of an array.
+
+In mtk_drm_get_all_drm_priv():
+Guarantee that storage for strings has sufficient space for character
+data and the null terminator.
+
+So change cnt to unsigned int and check its max value.
+
+Fixes: 1ef7ed48356c ("drm/mediatek: Modify mediatek-drm for mt8195 multi mmsys support")
+Signed-off-by: Jason-JH.Lin <jason-jh.lin@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: CK Hu <ck.hu@mediatek.com>
+Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
+Link: https://patchwork.kernel.org/project/dri-devel/patch/20230714094908.13087-3-jason-jh.lin@mediatek.com/
+Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/mediatek/mtk_drm_drv.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+index 6dcb4ba2466c0..fc217e0acd45d 100644
+--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
++++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+@@ -354,7 +354,7 @@ static bool mtk_drm_get_all_drm_priv(struct device *dev)
+ const struct of_device_id *of_id;
+ struct device_node *node;
+ struct device *drm_dev;
+- int cnt = 0;
++ unsigned int cnt = 0;
+ int i, j;
+
+ for_each_child_of_node(phandle->parent, node) {
+@@ -375,6 +375,9 @@ static bool mtk_drm_get_all_drm_priv(struct device *dev)
+ all_drm_priv[cnt] = dev_get_drvdata(drm_dev);
+ if (all_drm_priv[cnt] && all_drm_priv[cnt]->mtk_drm_bound)
+ cnt++;
++
++ if (cnt == MAX_CRTC)
++ break;
+ }
+
+ if (drm_priv->data->mmsys_dev_num == cnt) {
+--
+2.40.1
+
--- /dev/null
+From 8219bd74625a1710577e0268dc9d0159e5a1bb2b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Jul 2023 09:32:24 +0200
+Subject: drm/mediatek: dp: Add missing error checks in
+ mtk_dp_parse_capabilities
+
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+
+[ Upstream commit cfc146137a9f12e883ba64bc496b6da4d23f26d5 ]
+
+If reading the RX capabilities fails the training pattern will be set
+wrongly: add error checking for drm_dp_read_dpcd_caps() and return if
+anything went wrong with it.
+
+While at it, also add a less critical error check when writing to
+clear the ESI0 IRQ vector.
+
+Fixes: f70ac097a2cf ("drm/mediatek: Add MT8195 Embedded DisplayPort driver")
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Tested-by: Chen-Yu Tsai <wenst@chromium.org>
+Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
+Reviewed-by: CK Hu <ck.hu@mediatek.com>
+Link: https://patchwork.kernel.org/project/dri-devel/patch/20230725073234.55892-2-angelogioacchino.delregno@collabora.com/
+Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/mediatek/mtk_dp.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
+index 64eee77452c04..c58b775877a31 100644
+--- a/drivers/gpu/drm/mediatek/mtk_dp.c
++++ b/drivers/gpu/drm/mediatek/mtk_dp.c
+@@ -1588,7 +1588,9 @@ static int mtk_dp_parse_capabilities(struct mtk_dp *mtk_dp)
+ u8 val;
+ ssize_t ret;
+
+- drm_dp_read_dpcd_caps(&mtk_dp->aux, mtk_dp->rx_cap);
++ ret = drm_dp_read_dpcd_caps(&mtk_dp->aux, mtk_dp->rx_cap);
++ if (ret < 0)
++ return ret;
+
+ if (drm_dp_tps4_supported(mtk_dp->rx_cap))
+ mtk_dp->train_info.channel_eq_pattern = DP_TRAINING_PATTERN_4;
+@@ -1615,10 +1617,13 @@ static int mtk_dp_parse_capabilities(struct mtk_dp *mtk_dp)
+ return ret == 0 ? -EIO : ret;
+ }
+
+- if (val)
+- drm_dp_dpcd_writeb(&mtk_dp->aux,
+- DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0,
+- val);
++ if (val) {
++ ret = drm_dp_dpcd_writeb(&mtk_dp->aux,
++ DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0,
++ val);
++ if (ret < 0)
++ return ret;
++ }
+ }
+
+ return 0;
+--
+2.40.1
+
--- /dev/null
+From d8913c4f75dac9606ddc88c17dab92866e32b7f6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Jul 2023 21:40:00 +0800
+Subject: drm/mediatek: Fix potential memory leak if vmap() fail
+
+From: Sui Jingfeng <suijingfeng@loongson.cn>
+
+[ Upstream commit 379091e0f6d179d1a084c65de90fa44583b14a70 ]
+
+Also return -ENOMEM if such a failure happens, the implement should take
+responsibility for the error handling.
+
+Fixes: 3df64d7b0a4f ("drm/mediatek: Implement gem prime vmap/vunmap function")
+Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
+Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
+Signed-off-by: Sui Jingfeng <suijingfeng@loongson.cn>
+Reviewed-by: CK Hu <ck.hu@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://patchwork.kernel.org/project/dri-devel/patch/20230706134000.130098-1-suijingfeng@loongson.cn/
+Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/mediatek/mtk_drm_gem.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.c b/drivers/gpu/drm/mediatek/mtk_drm_gem.c
+index a25b28d3ee902..9f364df52478d 100644
+--- a/drivers/gpu/drm/mediatek/mtk_drm_gem.c
++++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.c
+@@ -247,7 +247,11 @@ int mtk_drm_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map)
+
+ mtk_gem->kvaddr = vmap(mtk_gem->pages, npages, VM_MAP,
+ pgprot_writecombine(PAGE_KERNEL));
+-
++ if (!mtk_gem->kvaddr) {
++ kfree(sgt);
++ kfree(mtk_gem->pages);
++ return -ENOMEM;
++ }
+ out:
+ kfree(sgt);
+ iosys_map_set_vaddr(map, mtk_gem->kvaddr);
+--
+2.40.1
+
--- /dev/null
+From e43f0018c0cc3fec70c4a953c316188751794e8a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Aug 2023 17:48:43 +0800
+Subject: drm/mediatek: Fix uninitialized symbol
+
+From: Nancy.Lin <nancy.lin@mediatek.com>
+
+[ Upstream commit 63ee9438f2aeffb2d1b2df2599c168ca08d35025 ]
+
+Fix Smatch static checker warning
+ -Fix uninitialized symbol comp_pdev in mtk_ddp_comp_init.
+
+Fixes: 0d9eee9118b7 ("drm/mediatek: Add drm ovl_adaptor sub driver for MT8195")
+Signed-off-by: Nancy.Lin <nancy.lin@mediatek.com>
+Link: https://patchwork.kernel.org/project/dri-devel/patch/20230803094843.4439-1-nancy.lin@mediatek.com/
+Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+index f114da4d36a96..771f4e1733539 100644
+--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
++++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+@@ -563,14 +563,15 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
+ /* Not all drm components have a DTS device node, such as ovl_adaptor,
+ * which is the drm bring up sub driver
+ */
+- if (node) {
+- comp_pdev = of_find_device_by_node(node);
+- if (!comp_pdev) {
+- DRM_INFO("Waiting for device %s\n", node->full_name);
+- return -EPROBE_DEFER;
+- }
+- comp->dev = &comp_pdev->dev;
++ if (!node)
++ return 0;
++
++ comp_pdev = of_find_device_by_node(node);
++ if (!comp_pdev) {
++ DRM_INFO("Waiting for device %s\n", node->full_name);
++ return -EPROBE_DEFER;
+ }
++ comp->dev = &comp_pdev->dev;
+
+ if (type == MTK_DISP_AAL ||
+ type == MTK_DISP_BLS ||
+@@ -580,7 +581,6 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
+ type == MTK_DISP_MERGE ||
+ type == MTK_DISP_OVL ||
+ type == MTK_DISP_OVL_2L ||
+- type == MTK_DISP_OVL_ADAPTOR ||
+ type == MTK_DISP_PWM ||
+ type == MTK_DISP_RDMA ||
+ type == MTK_DPI ||
+--
+2.40.1
+
--- /dev/null
+From 99aec05f5ea8dac1d0df5b3d31d7c705409789e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Jun 2023 15:54:21 +0800
+Subject: drm/mediatek: Fix void-pointer-to-enum-cast warning
+
+From: Jason-JH.Lin <jason-jh.lin@mediatek.com>
+
+[ Upstream commit 89cba955f879b1c6a9a71f67c8fb92ea8f5dfdc4 ]
+
+1. Fix build warning message in mtk_disp_ovl_adaptor.c
+>> drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c:415:10:
+ warning: cast to smaller integer type 'enum mtk_ovl_adaptor_comp_type'
+ from 'const void *' [-Wvoid-pointer-to-enum-cast]
+
+ type = (enum mtk_ovl_adaptor_comp_type)of_id->data;
+
+ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ 1 warning generated.
+
+2. Also fix the same warning message in mtk_drm_drv.c
+>> drivers/gpu/drm/mediatek/mtk_drm_drv.c:832:15:
+ warning: cast to smaller integer type 'enum mtk_ddp_comp_type'
+ from 'const void *' [-Wvoid-pointer-to-enum-cast]
+
+ comp_type = (enum mtk_ddp_comp_type)of_id->data;
+
+ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ 1 warning generated.
+
+Signed-off-by: Jason-JH.Lin <jason-jh.lin@mediatek.com>
+Fixes: 453c3364632a ("drm/mediatek: Add ovl_adaptor support for MT8195")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202305042054.ZtWME9OU-lkp@intel.com/
+Reviewed-by: CK Hu <ck.hu@mediatek.com>
+Link: https://patchwork.kernel.org/project/dri-devel/patch/20230621075421.1982-1-jason-jh.lin@mediatek.com/
+Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c | 2 +-
+ drivers/gpu/drm/mediatek/mtk_drm_drv.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
+index c0a38f5217eee..f2f6a5c01a6d2 100644
+--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
++++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
+@@ -426,7 +426,7 @@ static int ovl_adaptor_comp_init(struct device *dev, struct component_match **ma
+ continue;
+ }
+
+- type = (enum mtk_ovl_adaptor_comp_type)of_id->data;
++ type = (enum mtk_ovl_adaptor_comp_type)(uintptr_t)of_id->data;
+ id = ovl_adaptor_comp_get_id(dev, node, type);
+ if (id < 0) {
+ dev_warn(dev, "Skipping unknown component %pOF\n",
+diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+index fc217e0acd45d..30d10f21562f4 100644
+--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
++++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+@@ -832,7 +832,7 @@ static int mtk_drm_probe(struct platform_device *pdev)
+ continue;
+ }
+
+- comp_type = (enum mtk_ddp_comp_type)of_id->data;
++ comp_type = (enum mtk_ddp_comp_type)(uintptr_t)of_id->data;
+
+ if (comp_type == MTK_DISP_MUTEX) {
+ int id;
+--
+2.40.1
+
--- /dev/null
+From 1ad999cf8e0cf39acd5ff104e320cbfc8ca1658e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Jul 2023 17:49:05 +0800
+Subject: drm/mediatek: Remove freeing not dynamic allocated memory
+
+From: Jason-JH.Lin <jason-jh.lin@mediatek.com>
+
+[ Upstream commit 27b9e2ea3f2757da26bb8280e46f7fdbb1acb219 ]
+
+Fixing the coverity issue of:
+mtk_drm_cmdq_pkt_destroy frees address of mtk_crtc->cmdq_handle
+
+So remove the free function.
+
+Fixes: 7627122fd1c0 ("drm/mediatek: Add cmdq_handle in mtk_crtc")
+Signed-off-by: Jason-JH.Lin <jason-jh.lin@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: CK Hu <ck.hu@mediatek.com>
+Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
+Link: https://patchwork.kernel.org/project/dri-devel/patch/20230714094908.13087-2-jason-jh.lin@mediatek.com/
+Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+index d40142842f85c..8d44f3df116fa 100644
+--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
++++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+@@ -116,10 +116,9 @@ static int mtk_drm_cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt *
+ dma_addr_t dma_addr;
+
+ pkt->va_base = kzalloc(size, GFP_KERNEL);
+- if (!pkt->va_base) {
+- kfree(pkt);
++ if (!pkt->va_base)
+ return -ENOMEM;
+- }
++
+ pkt->buf_size = size;
+ pkt->cl = (void *)client;
+
+@@ -129,7 +128,6 @@ static int mtk_drm_cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt *
+ if (dma_mapping_error(dev, dma_addr)) {
+ dev_err(dev, "dma map failed, size=%u\n", (u32)(u64)size);
+ kfree(pkt->va_base);
+- kfree(pkt);
+ return -ENOMEM;
+ }
+
+@@ -145,7 +143,6 @@ static void mtk_drm_cmdq_pkt_destroy(struct cmdq_pkt *pkt)
+ dma_unmap_single(client->chan->mbox->dev, pkt->pa_base, pkt->buf_size,
+ DMA_TO_DEVICE);
+ kfree(pkt->va_base);
+- kfree(pkt);
+ }
+ #endif
+
+--
+2.40.1
+
--- /dev/null
+From 1d2b1db5de4043a3fcc8d391d811e7280b43ccbf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Jun 2023 20:23:19 -0300
+Subject: drm/msm/a2xx: Call adreno_gpu_init() earlier
+
+From: Fabio Estevam <festevam@denx.de>
+
+[ Upstream commit db07ce5da8b26bfeaf437a676ae49bd3bb1eace6 ]
+
+The adreno_is_a20x() and adreno_is_a225() functions rely on the
+GPU revision, but such information is retrieved inside adreno_gpu_init(),
+which is called afterwards.
+
+Fix this problem by caling adreno_gpu_init() earlier, so that
+the GPU information revision is available when adreno_is_a20x()
+and adreno_is_a225() run.
+
+Tested on a imx53-qsb board.
+
+Fixes: 21af872cd8c6 ("drm/msm/adreno: add a2xx")
+Signed-off-by: Fabio Estevam <festevam@denx.de>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Patchwork: https://patchwork.freedesktop.org/patch/543456/
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/adreno/a2xx_gpu.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/adreno/a2xx_gpu.c b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c
+index c67089a7ebc10..ad4570d60abf2 100644
+--- a/drivers/gpu/drm/msm/adreno/a2xx_gpu.c
++++ b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c
+@@ -540,6 +540,10 @@ struct msm_gpu *a2xx_gpu_init(struct drm_device *dev)
+ gpu->perfcntrs = perfcntrs;
+ gpu->num_perfcntrs = ARRAY_SIZE(perfcntrs);
+
++ ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1);
++ if (ret)
++ goto fail;
++
+ if (adreno_is_a20x(adreno_gpu))
+ adreno_gpu->registers = a200_registers;
+ else if (adreno_is_a225(adreno_gpu))
+@@ -547,10 +551,6 @@ struct msm_gpu *a2xx_gpu_init(struct drm_device *dev)
+ else
+ adreno_gpu->registers = a220_registers;
+
+- ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1);
+- if (ret)
+- goto fail;
+-
+ if (!gpu->aspace) {
+ dev_err(dev->dev, "No memory protection without MMU\n");
+ if (!allow_vram_carveout) {
+--
+2.40.1
+
--- /dev/null
+From 676574ad64147d8cd3cd4b1f8d0f8479f43e0375 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Aug 2023 10:34:28 -0700
+Subject: drm/msm/a6xx: Fix GMU lockdep splat
+
+From: Rob Clark <robdclark@chromium.org>
+
+[ Upstream commit 3136a0f83519076edfbc14be65f286785434189a ]
+
+For normal GPU devfreq, we need to acquire the GMU lock while already
+holding devfreq locks. But in the teardown path, we were calling
+dev_pm_domain_detach() while already holding the GMU lock, resulting in
+this lockdep splat:
+
+ ======================================================
+ WARNING: possible circular locking dependency detected
+ 6.4.3-debug+ #3 Not tainted
+ ------------------------------------------------------
+ ring0/391 is trying to acquire lock:
+ ffffff80a025c078 (&devfreq->lock){+.+.}-{3:3}, at: qos_notifier_call+0x30/0x74
+
+ but task is already holding lock:
+ ffffff809b8c1ce8 (&(c->notifiers)->rwsem){++++}-{3:3}, at: blocking_notifier_call_chain+0x34/0x78
+
+ which lock already depends on the new lock.
+
+ the existing dependency chain (in reverse order) is:
+
+ -> #4 (&(c->notifiers)->rwsem){++++}-{3:3}:
+ down_write+0x58/0x74
+ __blocking_notifier_chain_register+0x64/0x84
+ blocking_notifier_chain_register+0x1c/0x28
+ freq_qos_add_notifier+0x5c/0x7c
+ dev_pm_qos_add_notifier+0xd4/0xf0
+ devfreq_add_device+0x42c/0x560
+ devm_devfreq_add_device+0x6c/0xb8
+ msm_devfreq_init+0xa8/0x16c [msm]
+ msm_gpu_init+0x368/0x54c [msm]
+ adreno_gpu_init+0x248/0x2b0 [msm]
+ a6xx_gpu_init+0x2d0/0x384 [msm]
+ adreno_bind+0x264/0x2bc [msm]
+ component_bind_all+0x124/0x1f4
+ msm_drm_bind+0x2d0/0x5f4 [msm]
+ try_to_bring_up_aggregate_device+0x88/0x1a4
+ __component_add+0xd4/0x128
+ component_add+0x1c/0x28
+ dp_display_probe+0x37c/0x3c0 [msm]
+ platform_probe+0x70/0xc0
+ really_probe+0x148/0x280
+ __driver_probe_device+0xfc/0x114
+ driver_probe_device+0x44/0x100
+ __device_attach_driver+0x64/0xdc
+ bus_for_each_drv+0xb0/0xd8
+ __device_attach+0xe4/0x140
+ device_initial_probe+0x1c/0x28
+ bus_probe_device+0x44/0xb0
+ deferred_probe_work_func+0xb0/0xc8
+ process_one_work+0x288/0x3d8
+ worker_thread+0x1f0/0x260
+ kthread+0xf0/0x100
+ ret_from_fork+0x10/0x20
+
+ -> #3 (dev_pm_qos_mtx){+.+.}-{3:3}:
+ __mutex_lock+0xc8/0x388
+ mutex_lock_nested+0x2c/0x38
+ dev_pm_qos_remove_notifier+0x3c/0xc8
+ genpd_remove_device+0x40/0x11c
+ genpd_dev_pm_detach+0x88/0x130
+ dev_pm_domain_detach+0x2c/0x3c
+ a6xx_gmu_remove+0x44/0xdc [msm]
+ a6xx_destroy+0x7c/0xa4 [msm]
+ adreno_unbind+0x50/0x64 [msm]
+ component_unbind+0x44/0x64
+ component_unbind_all+0xb4/0xbc
+ msm_drm_uninit.isra.0+0x124/0x17c [msm]
+ msm_drm_bind+0x340/0x5f4 [msm]
+ try_to_bring_up_aggregate_device+0x88/0x1a4
+ __component_add+0xd4/0x128
+ component_add+0x1c/0x28
+ dp_display_probe+0x37c/0x3c0 [msm]
+ platform_probe+0x70/0xc0
+ really_probe+0x148/0x280
+ __driver_probe_device+0xfc/0x114
+ driver_probe_device+0x44/0x100
+ __device_attach_driver+0x64/0xdc
+ bus_for_each_drv+0xb0/0xd8
+ __device_attach+0xe4/0x140
+ device_initial_probe+0x1c/0x28
+ bus_probe_device+0x44/0xb0
+ deferred_probe_work_func+0xb0/0xc8
+ process_one_work+0x288/0x3d8
+ worker_thread+0x1f0/0x260
+ kthread+0xf0/0x100
+ ret_from_fork+0x10/0x20
+
+ -> #2 (&a6xx_gpu->gmu.lock){+.+.}-{3:3}:
+ __mutex_lock+0xc8/0x388
+ mutex_lock_nested+0x2c/0x38
+ a6xx_gpu_set_freq+0x38/0x64 [msm]
+ msm_devfreq_target+0x170/0x18c [msm]
+ devfreq_set_target+0x90/0x1e4
+ devfreq_update_target+0xb4/0xf0
+ update_devfreq+0x1c/0x28
+ devfreq_monitor+0x3c/0x10c
+ process_one_work+0x288/0x3d8
+ worker_thread+0x1f0/0x260
+ kthread+0xf0/0x100
+ ret_from_fork+0x10/0x20
+
+ -> #1 (&df->lock){+.+.}-{3:3}:
+ __mutex_lock+0xc8/0x388
+ mutex_lock_nested+0x2c/0x38
+ msm_devfreq_get_dev_status+0x4c/0x104 [msm]
+ devfreq_simple_ondemand_func+0x5c/0x128
+ devfreq_update_target+0x68/0xf0
+ update_devfreq+0x1c/0x28
+ devfreq_monitor+0x3c/0x10c
+ process_one_work+0x288/0x3d8
+ worker_thread+0x1f0/0x260
+ kthread+0xf0/0x100
+ ret_from_fork+0x10/0x20
+
+ -> #0 (&devfreq->lock){+.+.}-{3:3}:
+ __lock_acquire+0xdf8/0x109c
+ lock_acquire+0x234/0x284
+ __mutex_lock+0xc8/0x388
+ mutex_lock_nested+0x2c/0x38
+ qos_notifier_call+0x30/0x74
+ qos_min_notifier_call+0x1c/0x28
+ notifier_call_chain+0xf4/0x114
+ blocking_notifier_call_chain+0x4c/0x78
+ pm_qos_update_target+0x184/0x190
+ freq_qos_apply+0x4c/0x64
+ apply_constraint+0xf8/0xfc
+ __dev_pm_qos_update_request+0x138/0x164
+ dev_pm_qos_update_request+0x44/0x68
+ msm_devfreq_boost+0x40/0x70 [msm]
+ msm_devfreq_active+0xc0/0xf0 [msm]
+ msm_gpu_submit+0xc8/0x12c [msm]
+ msm_job_run+0x88/0x128 [msm]
+ drm_sched_main+0x240/0x324 [gpu_sched]
+ kthread+0xf0/0x100
+ ret_from_fork+0x10/0x20
+
+ other info that might help us debug this:
+ Chain exists of:
+ &devfreq->lock --> dev_pm_qos_mtx --> &(c->notifiers)->rwsem
+ Possible unsafe locking scenario:
+ CPU0 CPU1
+ ---- ----
+ rlock(&(c->notifiers)->rwsem);
+ lock(dev_pm_qos_mtx);
+ lock(&(c->notifiers)->rwsem);
+ lock(&devfreq->lock);
+
+ *** DEADLOCK ***
+ 4 locks held by ring0/391:
+ #0: ffffff809c811170 (&gpu->lock){+.+.}-{3:3}, at: msm_job_run+0x7c/0x128 [msm]
+ #1: ffffff809c811208 (&gpu->active_lock){+.+.}-{3:3}, at: msm_gpu_submit+0xa8/0x12c [msm]
+ #2: ffffffecbbb46600 (dev_pm_qos_mtx){+.+.}-{3:3}, at: dev_pm_qos_update_request+0x38/0x68
+ #3: ffffff809b8c1ce8 (&(c->notifiers)->rwsem){++++}-{3:3}, at: blocking_notifier_call_chain+0x34/0x78
+
+ stack backtrace:
+ CPU: 6 PID: 391 Comm: ring0 Not tainted 6.4.3debug+ #3
+ Hardware name: Google Villager (rev1+) with LTE (DT)
+ Call trace:
+ dump_backtrace+0xb4/0xf0
+ show_stack+0x20/0x30
+ dump_stack_lvl+0x60/0x84
+ dump_stack+0x18/0x24
+ print_circular_bug+0x1cc/0x234
+ check_noncircular+0x78/0xac
+ __lock_acquire+0xdf8/0x109c
+ lock_acquire+0x234/0x284
+ __mutex_lock+0xc8/0x388
+ mutex_lock_nested+0x2c/0x38
+ qos_notifier_call+0x30/0x74
+ qos_min_notifier_call+0x1c/0x28
+ notifier_call_chain+0xf4/0x114
+ blocking_notifier_call_chain+0x4c/0x78
+ pm_qos_update_target+0x184/0x190
+ freq_qos_apply+0x4c/0x64
+ apply_constraint+0xf8/0xfc
+ __dev_pm_qos_update_request+0x138/0x164
+ dev_pm_qos_update_request+0x44/0x68
+ msm_devfreq_boost+0x40/0x70 [msm]
+ msm_devfreq_active+0xc0/0xf0 [msm]
+ msm_gpu_submit+0xc8/0x12c [msm]
+ msm_job_run+0x88/0x128 [msm]
+ drm_sched_main+0x240/0x324 [gpu_sched]
+ kthread+0xf0/0x100
+ ret_from_fork+0x10/0x20
+
+Fix this by only synchronizing access to gmu->initialized.
+
+Fixes: 4cd15a3e8b36 ("drm/msm/a6xx: Make GPU destroy a bit safer")
+Cc: Douglas Anderson <dianders@chromium.org>
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Patchwork: https://patchwork.freedesktop.org/patch/551171/
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 11 ++++++++---
+ drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 2 --
+ 2 files changed, 8 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+index 8914992378f21..1ff2a71e1aea5 100644
+--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
++++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+@@ -1472,8 +1472,15 @@ void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu)
+ struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
+ struct platform_device *pdev = to_platform_device(gmu->dev);
+
+- if (!gmu->initialized)
++ mutex_lock(&gmu->lock);
++ if (!gmu->initialized) {
++ mutex_unlock(&gmu->lock);
+ return;
++ }
++
++ gmu->initialized = false;
++
++ mutex_unlock(&gmu->lock);
+
+ pm_runtime_force_suspend(gmu->dev);
+
+@@ -1501,8 +1508,6 @@ void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu)
+
+ /* Drop reference taken in of_find_device_by_node */
+ put_device(gmu->dev);
+-
+- gmu->initialized = false;
+ }
+
+ static int cxpd_notifier_cb(struct notifier_block *nb,
+diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+index 411b7a5fa2f32..bdda1a6336543 100644
+--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
++++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+@@ -1697,9 +1697,7 @@ static void a6xx_destroy(struct msm_gpu *gpu)
+
+ a6xx_llc_slices_destroy(a6xx_gpu);
+
+- mutex_lock(&a6xx_gpu->gmu.lock);
+ a6xx_gmu_remove(a6xx_gpu);
+- mutex_unlock(&a6xx_gpu->gmu.lock);
+
+ adreno_gpu_cleanup(adreno_gpu);
+
+--
+2.40.1
+
--- /dev/null
+From d0b7a396f1ac0cd19a9db5a95e0414961c94fd32 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Apr 2023 01:25:57 +0300
+Subject: drm/msm/dpu: drop the regdma configuration
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 078f766e165097c03629cc1a8f7e1a7b7ec0e79b ]
+
+The regdma is currently not used by the current driver. We have no way
+to practically verify that the regdma is described correctly. Drop it
+now.
+
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Marijn Suijten <marijn.suijten@somainline.org>
+Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Patchwork: https://patchwork.freedesktop.org/patch/533148/
+Link: https://lore.kernel.org/r/20230420222558.1208887-1-dmitry.baryshkov@linaro.org
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Stable-dep-of: 42d0d253ed03 ("drm/msm/dpu: increase memtype count to 16 for sm8550")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 1 -
+ .../msm/disp/dpu1/catalog/dpu_4_0_sdm845.h | 2 -
+ .../msm/disp/dpu1/catalog/dpu_5_0_sm8150.h | 2 -
+ .../msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 2 -
+ .../msm/disp/dpu1/catalog/dpu_6_0_sm8250.h | 2 -
+ .../msm/disp/dpu1/catalog/dpu_6_2_sc7180.h | 2 -
+ .../msm/disp/dpu1/catalog/dpu_7_0_sm8350.h | 2 -
+ .../msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 2 -
+ .../msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 2 -
+ .../msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 2 -
+ .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 40 -------------------
+ .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 18 ---------
+ 12 files changed, 77 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
+index ff9ccf72a4bf9..6560eeef00143 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
++++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
+@@ -195,7 +195,6 @@ const struct dpu_mdss_cfg dpu_msm8998_cfg = {
+ .intf = msm8998_intf,
+ .vbif_count = ARRAY_SIZE(msm8998_vbif),
+ .vbif = msm8998_vbif,
+- .reg_dma_count = 0,
+ .perf = &msm8998_perf_data,
+ .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \
+ BIT(MDP_SSPP_TOP0_INTR2) | \
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
+index 5b9b3b99f1b5f..84159f8cbdaeb 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
++++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
+@@ -193,8 +193,6 @@ const struct dpu_mdss_cfg dpu_sdm845_cfg = {
+ .intf = sdm845_intf,
+ .vbif_count = ARRAY_SIZE(sdm845_vbif),
+ .vbif = sdm845_vbif,
+- .reg_dma_count = 1,
+- .dma_cfg = &sdm845_regdma,
+ .perf = &sdm845_perf_data,
+ .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \
+ BIT(MDP_SSPP_TOP0_INTR2) | \
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
+index 074ba54d420f4..266c525f8daaf 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
++++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
+@@ -220,8 +220,6 @@ const struct dpu_mdss_cfg dpu_sm8150_cfg = {
+ .intf = sm8150_intf,
+ .vbif_count = ARRAY_SIZE(sdm845_vbif),
+ .vbif = sdm845_vbif,
+- .reg_dma_count = 1,
+- .dma_cfg = &sm8150_regdma,
+ .perf = &sm8150_perf_data,
+ .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \
+ BIT(MDP_SSPP_TOP0_INTR2) | \
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
+index 0540d21810857..76c5745c2fa1f 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
++++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
+@@ -198,8 +198,6 @@ const struct dpu_mdss_cfg dpu_sc8180x_cfg = {
+ .intf = sc8180x_intf,
+ .vbif_count = ARRAY_SIZE(sdm845_vbif),
+ .vbif = sdm845_vbif,
+- .reg_dma_count = 1,
+- .dma_cfg = &sm8150_regdma,
+ .perf = &sc8180x_perf_data,
+ .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \
+ BIT(MDP_SSPP_TOP0_INTR2) | \
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
+index b3284de35b8fa..8660d04d0f589 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
++++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
+@@ -228,8 +228,6 @@ const struct dpu_mdss_cfg dpu_sm8250_cfg = {
+ .vbif = sdm845_vbif,
+ .wb_count = ARRAY_SIZE(sm8250_wb),
+ .wb = sm8250_wb,
+- .reg_dma_count = 1,
+- .dma_cfg = &sm8250_regdma,
+ .perf = &sm8250_perf_data,
+ .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \
+ BIT(MDP_SSPP_TOP0_INTR2) | \
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
+index 88c211876516a..9631116f99e9b 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
++++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
+@@ -147,8 +147,6 @@ const struct dpu_mdss_cfg dpu_sc7180_cfg = {
+ .wb = sc7180_wb,
+ .vbif_count = ARRAY_SIZE(sdm845_vbif),
+ .vbif = sdm845_vbif,
+- .reg_dma_count = 1,
+- .dma_cfg = &sdm845_regdma,
+ .perf = &sc7180_perf_data,
+ .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \
+ BIT(MDP_SSPP_TOP0_INTR2) | \
+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 4f6a965bcd90b..9e8d6632a1927 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
+@@ -211,8 +211,6 @@ const struct dpu_mdss_cfg dpu_sm8350_cfg = {
+ .intf = sm8350_intf,
+ .vbif_count = ARRAY_SIZE(sdm845_vbif),
+ .vbif = sdm845_vbif,
+- .reg_dma_count = 1,
+- .dma_cfg = &sm8350_regdma,
+ .perf = &sm8350_perf_data,
+ .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \
+ BIT(MDP_SSPP_TOP0_INTR2) | \
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h
+index 706d0f13b598e..cb58b4ec97db4 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h
++++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h
+@@ -202,8 +202,6 @@ const struct dpu_mdss_cfg dpu_sc8280xp_cfg = {
+ .intf = sc8280xp_intf,
+ .vbif_count = ARRAY_SIZE(sdm845_vbif),
+ .vbif = sdm845_vbif,
+- .reg_dma_count = 1,
+- .dma_cfg = &sc8280xp_regdma,
+ .perf = &sc8280xp_perf_data,
+ .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \
+ BIT(MDP_SSPP_TOP0_INTR2) | \
+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 8bd4bb97e639c..905b403ffb0fb 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
+@@ -219,8 +219,6 @@ const struct dpu_mdss_cfg dpu_sm8450_cfg = {
+ .intf = sm8450_intf,
+ .vbif_count = ARRAY_SIZE(sdm845_vbif),
+ .vbif = sdm845_vbif,
+- .reg_dma_count = 1,
+- .dma_cfg = &sm8450_regdma,
+ .perf = &sm8450_perf_data,
+ .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \
+ BIT(MDP_SSPP_TOP0_INTR2) | \
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h
+index d0ab351b6a8b9..be2f37728aa0c 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h
++++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h
+@@ -224,8 +224,6 @@ const struct dpu_mdss_cfg dpu_sm8550_cfg = {
+ .intf = sm8550_intf,
+ .vbif_count = ARRAY_SIZE(sdm845_vbif),
+ .vbif = sdm845_vbif,
+- .reg_dma_count = 1,
+- .dma_cfg = &sm8450_regdma,
+ .perf = &sm8550_perf_data,
+ .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \
+ BIT(MDP_SSPP_TOP0_INTR2) | \
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+index 0b604f31197bb..fc9d2c56d0e11 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+@@ -642,46 +642,6 @@ static const struct dpu_vbif_cfg sdm845_vbif[] = {
+ },
+ };
+
+-static const struct dpu_reg_dma_cfg sc8280xp_regdma = {
+- .base = 0x0,
+- .version = 0x00020000,
+- .trigger_sel_off = 0x119c,
+- .xin_id = 7,
+- .clk_ctrl = DPU_CLK_CTRL_REG_DMA,
+-};
+-
+-static const struct dpu_reg_dma_cfg sdm845_regdma = {
+- .base = 0x0, .version = 0x1, .trigger_sel_off = 0x119c
+-};
+-
+-static const struct dpu_reg_dma_cfg sm8150_regdma = {
+- .base = 0x0, .version = 0x00010001, .trigger_sel_off = 0x119c
+-};
+-
+-static const struct dpu_reg_dma_cfg sm8250_regdma = {
+- .base = 0x0,
+- .version = 0x00010002,
+- .trigger_sel_off = 0x119c,
+- .xin_id = 7,
+- .clk_ctrl = DPU_CLK_CTRL_REG_DMA,
+-};
+-
+-static const struct dpu_reg_dma_cfg sm8350_regdma = {
+- .base = 0x400,
+- .version = 0x00020000,
+- .trigger_sel_off = 0x119c,
+- .xin_id = 7,
+- .clk_ctrl = DPU_CLK_CTRL_REG_DMA,
+-};
+-
+-static const struct dpu_reg_dma_cfg sm8450_regdma = {
+- .base = 0x0,
+- .version = 0x00020000,
+- .trigger_sel_off = 0x119c,
+- .xin_id = 7,
+- .clk_ctrl = DPU_CLK_CTRL_REG_DMA,
+-};
+-
+ /*************************************************************
+ * PERF data config
+ *************************************************************/
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+index 71584cd56fd75..8d62c21b051a8 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+@@ -720,21 +720,6 @@ struct dpu_vbif_cfg {
+ u32 memtype_count;
+ u32 memtype[MAX_XIN_COUNT];
+ };
+-/**
+- * struct dpu_reg_dma_cfg - information of lut dma blocks
+- * @id enum identifying this block
+- * @base register offset of this block
+- * @features bit mask identifying sub-blocks/features
+- * @version version of lutdma hw block
+- * @trigger_sel_off offset to trigger select registers of lutdma
+- */
+-struct dpu_reg_dma_cfg {
+- DPU_HW_BLK_INFO;
+- u32 version;
+- u32 trigger_sel_off;
+- u32 xin_id;
+- enum dpu_clk_ctrl_type clk_ctrl;
+-};
+
+ /**
+ * Define CDP use cases
+@@ -850,9 +835,6 @@ struct dpu_mdss_cfg {
+ u32 wb_count;
+ const struct dpu_wb_cfg *wb;
+
+- u32 reg_dma_count;
+- const struct dpu_reg_dma_cfg *dma_cfg;
+-
+ u32 ad_count;
+
+ u32 dspp_count;
+--
+2.40.1
+
--- /dev/null
+From 7c3af212a285111f6cb1020cced1b9ea355167ae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Aug 2023 13:04:19 +0300
+Subject: drm/msm/dpu: fix the irq index in
+ dpu_encoder_phys_wb_wait_for_commit_done
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit d93cf453f51da168f4410ba73656f1e862096973 ]
+
+Since commit 1e7ac595fa46 ("drm/msm/dpu: pass irq to
+dpu_encoder_helper_wait_for_irq()") the
+dpu_encoder_phys_wb_wait_for_commit_done expects the IRQ index rather
+than the IRQ index in phys_enc->intr table, however writeback got the
+older invocation in place. This was unnoticed for several releases, but
+now it's time to fix it.
+
+Fixes: d7d0e73f7de3 ("drm/msm/dpu: introduce the dpu_encoder_phys_* for writeback")
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Patchwork: https://patchwork.freedesktop.org/patch/550924/
+Link: https://lore.kernel.org/r/20230802100426.4184892-2-dmitry.baryshkov@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
+index bac4aa807b4bc..2553d6374482b 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
+@@ -455,7 +455,8 @@ static int dpu_encoder_phys_wb_wait_for_commit_done(
+ wait_info.atomic_cnt = &phys_enc->pending_kickoff_cnt;
+ wait_info.timeout_ms = KICKOFF_TIMEOUT_MS;
+
+- ret = dpu_encoder_helper_wait_for_irq(phys_enc, INTR_IDX_WB_DONE,
++ ret = dpu_encoder_helper_wait_for_irq(phys_enc,
++ phys_enc->irq[INTR_IDX_WB_DONE],
+ dpu_encoder_phys_wb_done_irq, &wait_info);
+ if (ret == -ETIMEDOUT)
+ _dpu_encoder_phys_wb_handle_wbdone_timeout(phys_enc);
+--
+2.40.1
+
--- /dev/null
+From bbde44ce880d55101d40fa60099dbbdb4a91f8b5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Aug 2023 09:48:53 -0400
+Subject: drm/msm/dpu: increase memtype count to 16 for sm8550
+
+From: Jonathan Marek <jonathan@marek.ca>
+
+[ Upstream commit 42d0d253ed03b961c325ff756eec0480cb4adc6b ]
+
+sm8550 has 16 vbif clients.
+
+This fixes the extra 2 clients (DMA4/DMA5) not having their memtype
+initialized. This fixes DMA4/DMA5 planes not displaying correctly.
+
+Fixes: efcd0107727c ("drm/msm/dpu: add support for SM8550")
+Signed-off-by: Jonathan Marek <jonathan@marek.ca>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD
+Patchwork: https://patchwork.freedesktop.org/patch/550968/
+Link: https://lore.kernel.org/r/20230802134900.30435-1-jonathan@marek.ca
+[DB: fixed the Fixes tag]
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 4 ++--
+ .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 20 +++++++++++++++++++
+ 2 files changed, 22 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h
+index be2f37728aa0c..a6e4763660bb0 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h
++++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h
+@@ -222,8 +222,8 @@ const struct dpu_mdss_cfg dpu_sm8550_cfg = {
+ .merge_3d = sm8550_merge_3d,
+ .intf_count = ARRAY_SIZE(sm8550_intf),
+ .intf = sm8550_intf,
+- .vbif_count = ARRAY_SIZE(sdm845_vbif),
+- .vbif = sdm845_vbif,
++ .vbif_count = ARRAY_SIZE(sm8550_vbif),
++ .vbif = sm8550_vbif,
+ .perf = &sm8550_perf_data,
+ .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \
+ BIT(MDP_SSPP_TOP0_INTR2) | \
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+index fc9d2c56d0e11..23c16d25b62f5 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+@@ -642,6 +642,26 @@ static const struct dpu_vbif_cfg sdm845_vbif[] = {
+ },
+ };
+
++static const struct dpu_vbif_cfg sm8550_vbif[] = {
++ {
++ .name = "vbif_rt", .id = VBIF_RT,
++ .base = 0, .len = 0x1040,
++ .features = BIT(DPU_VBIF_QOS_REMAP),
++ .xin_halt_timeout = 0x4000,
++ .qos_rp_remap_size = 0x40,
++ .qos_rt_tbl = {
++ .npriority_lvl = ARRAY_SIZE(sdm845_rt_pri_lvl),
++ .priority_lvl = sdm845_rt_pri_lvl,
++ },
++ .qos_nrt_tbl = {
++ .npriority_lvl = ARRAY_SIZE(sdm845_nrt_pri_lvl),
++ .priority_lvl = sdm845_nrt_pri_lvl,
++ },
++ .memtype_count = 16,
++ .memtype = {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
++ },
++};
++
+ /*************************************************************
+ * PERF data config
+ *************************************************************/
+--
+2.40.1
+
--- /dev/null
+From d783f71f1d0d545f1e56db56c6318aaaccc39208 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Aug 2023 22:45:21 +0200
+Subject: drm/msm/mdp5: Don't leak some plane state
+
+From: Daniel Vetter <daniel.vetter@ffwll.ch>
+
+[ Upstream commit fd0ad3b2365c1c58aa5a761c18efc4817193beb6 ]
+
+Apparently no one noticed that mdp5 plane states leak like a sieve
+ever since we introduced plane_state->commit refcount a few years ago
+in 21a01abbe32a ("drm/atomic: Fix freeing connector/plane state too
+early by tracking commits, v3.")
+
+Fix it by using the right helpers.
+
+Fixes: 21a01abbe32a ("drm/atomic: Fix freeing connector/plane state too early by tracking commits, v3.")
+Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
+Cc: Rob Clark <robdclark@gmail.com>
+Cc: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Cc: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Cc: linux-arm-msm@vger.kernel.org
+Cc: freedreno@lists.freedesktop.org
+Reported-and-tested-by: dorum@noisolation.com
+Cc: dorum@noisolation.com
+Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
+Reviewed-by: Rob Clark <robdclark@gmail.com>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Patchwork: https://patchwork.freedesktop.org/patch/551236/
+Link: https://lore.kernel.org/r/20230803204521.928582-1-daniel.vetter@ffwll.ch
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
+index bd2c4ac456017..0d5ff03cb0910 100644
+--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
++++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
+@@ -130,8 +130,7 @@ static void mdp5_plane_destroy_state(struct drm_plane *plane,
+ {
+ struct mdp5_plane_state *pstate = to_mdp5_plane_state(state);
+
+- if (state->fb)
+- drm_framebuffer_put(state->fb);
++ __drm_atomic_helper_plane_destroy_state(state);
+
+ kfree(pstate);
+ }
+--
+2.40.1
+
--- /dev/null
+From 433f1654f4ec371644b2bb14e22c19fa0439a3c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Jul 2023 18:24:40 -0700
+Subject: drm/msm: Update dev core dump to not print backwards
+
+From: Ryan McCann <quic_rmccann@quicinc.com>
+
+[ Upstream commit 903705111d863ed8ccf73465da77d232fc422ec1 ]
+
+Device core dump add block method adds hardware blocks to dumping queue
+with stack behavior which causes the hardware blocks to be printed in
+reverse order. Change the addition to dumping queue data structure
+from "list_add" to "list_add_tail" for FIFO queue behavior.
+
+Fixes: 98659487b845 ("drm/msm: add support to take dpu snapshot")
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Signed-off-by: Ryan McCann <quic_rmccann@quicinc.com>
+Patchwork: https://patchwork.freedesktop.org/patch/546200/
+Link: https://lore.kernel.org/r/20230622-devcoredump_patch-v5-1-67e8b66c4723@quicinc.com
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/msm_disp_snapshot_util.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/msm/disp/msm_disp_snapshot_util.c b/drivers/gpu/drm/msm/disp/msm_disp_snapshot_util.c
+index acfe1b31e0792..add72bbc28b17 100644
+--- a/drivers/gpu/drm/msm/disp/msm_disp_snapshot_util.c
++++ b/drivers/gpu/drm/msm/disp/msm_disp_snapshot_util.c
+@@ -192,5 +192,5 @@ void msm_disp_snapshot_add_block(struct msm_disp_state *disp_state, u32 len,
+ new_blk->base_addr = base_addr;
+
+ msm_disp_state_dump_regs(&new_blk->state, new_blk->size, base_addr);
+- list_add(&new_blk->node, &disp_state->blocks);
++ list_add_tail(&new_blk->node, &disp_state->blocks);
+ }
+--
+2.40.1
+
--- /dev/null
+From 044ee5ee0dec46b5ad95d08c30523293850f43a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Jul 2023 15:49:14 +0200
+Subject: drm/panel: simple: Add missing connector type and pixel format for
+ AUO T215HVN01
+
+From: Marek Vasut <marex@denx.de>
+
+[ Upstream commit 7a675a8fa598edb29a664a91adb80f0340649f6f ]
+
+The connector type and pixel format are missing for this panel,
+add them to prevent various drivers from failing to determine
+either of those parameters.
+
+Fixes: 7ee933a1d5c4 ("drm/panel: simple: Add support for AUO T215HVN01")
+Signed-off-by: Marek Vasut <marex@denx.de>
+Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230709134914.449328-1-marex@denx.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/panel/panel-simple.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
+index cf6b146acc323..23c1b1a96df64 100644
+--- a/drivers/gpu/drm/panel/panel-simple.c
++++ b/drivers/gpu/drm/panel/panel-simple.c
+@@ -1159,7 +1159,9 @@ static const struct panel_desc auo_t215hvn01 = {
+ .delay = {
+ .disable = 5,
+ .unprepare = 1000,
+- }
++ },
++ .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
++ .connector_type = DRM_MODE_CONNECTOR_LVDS,
+ };
+
+ static const struct drm_display_mode avic_tm070ddh03_mode = {
+--
+2.40.1
+
--- /dev/null
+From ec826693d3cbe89eb7a68e9bf134a8e0de2f8736 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Jul 2023 15:04:58 +0300
+Subject: drm/radeon: Use RMW accessors for changing LNKCTL
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit 7189576e8a829130192b33c5b64e8a475369c776 ]
+
+Don't assume that only the driver would be accessing LNKCTL. ASPM policy
+changes can trigger write to LNKCTL outside of driver's control. And in
+the case of upstream bridge, the driver does not even own the device it's
+changing the registers for.
+
+Use RMW capability accessors which do proper locking to avoid losing
+concurrent updates to the register value.
+
+Suggested-by: Lukas Wunner <lukas@wunner.de>
+Fixes: 8a7cd27679d0 ("drm/radeon/cik: add support for pcie gen1/2/3 switching")
+Fixes: b9d305dfb66c ("drm/radeon: implement pcie gen2/3 support for SI")
+Link: https://lore.kernel.org/r/20230717120503.15276-7-ilpo.jarvinen@linux.intel.com
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Acked-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/radeon/cik.c | 36 ++++++++++-------------------------
+ drivers/gpu/drm/radeon/si.c | 37 ++++++++++--------------------------
+ 2 files changed, 20 insertions(+), 53 deletions(-)
+
+diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
+index 5819737c21c67..a6f3c811ceb8e 100644
+--- a/drivers/gpu/drm/radeon/cik.c
++++ b/drivers/gpu/drm/radeon/cik.c
+@@ -9534,17 +9534,8 @@ static void cik_pcie_gen3_enable(struct radeon_device *rdev)
+ u16 bridge_cfg2, gpu_cfg2;
+ u32 max_lw, current_lw, tmp;
+
+- pcie_capability_read_word(root, PCI_EXP_LNKCTL,
+- &bridge_cfg);
+- pcie_capability_read_word(rdev->pdev, PCI_EXP_LNKCTL,
+- &gpu_cfg);
+-
+- tmp16 = bridge_cfg | PCI_EXP_LNKCTL_HAWD;
+- pcie_capability_write_word(root, PCI_EXP_LNKCTL, tmp16);
+-
+- tmp16 = gpu_cfg | PCI_EXP_LNKCTL_HAWD;
+- pcie_capability_write_word(rdev->pdev, PCI_EXP_LNKCTL,
+- tmp16);
++ pcie_capability_set_word(root, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD);
++ pcie_capability_set_word(rdev->pdev, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD);
+
+ tmp = RREG32_PCIE_PORT(PCIE_LC_STATUS1);
+ max_lw = (tmp & LC_DETECTED_LINK_WIDTH_MASK) >> LC_DETECTED_LINK_WIDTH_SHIFT;
+@@ -9591,21 +9582,14 @@ static void cik_pcie_gen3_enable(struct radeon_device *rdev)
+ msleep(100);
+
+ /* linkctl */
+- pcie_capability_read_word(root, PCI_EXP_LNKCTL,
+- &tmp16);
+- tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
+- tmp16 |= (bridge_cfg & PCI_EXP_LNKCTL_HAWD);
+- pcie_capability_write_word(root, PCI_EXP_LNKCTL,
+- tmp16);
+-
+- pcie_capability_read_word(rdev->pdev,
+- PCI_EXP_LNKCTL,
+- &tmp16);
+- tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
+- tmp16 |= (gpu_cfg & PCI_EXP_LNKCTL_HAWD);
+- pcie_capability_write_word(rdev->pdev,
+- PCI_EXP_LNKCTL,
+- tmp16);
++ pcie_capability_clear_and_set_word(root, PCI_EXP_LNKCTL,
++ PCI_EXP_LNKCTL_HAWD,
++ bridge_cfg &
++ PCI_EXP_LNKCTL_HAWD);
++ pcie_capability_clear_and_set_word(rdev->pdev, PCI_EXP_LNKCTL,
++ PCI_EXP_LNKCTL_HAWD,
++ gpu_cfg &
++ PCI_EXP_LNKCTL_HAWD);
+
+ /* linkctl2 */
+ pcie_capability_read_word(root, PCI_EXP_LNKCTL2,
+diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
+index 8d5e4b25609d5..a91012447b56e 100644
+--- a/drivers/gpu/drm/radeon/si.c
++++ b/drivers/gpu/drm/radeon/si.c
+@@ -7131,17 +7131,8 @@ static void si_pcie_gen3_enable(struct radeon_device *rdev)
+ u16 bridge_cfg2, gpu_cfg2;
+ u32 max_lw, current_lw, tmp;
+
+- pcie_capability_read_word(root, PCI_EXP_LNKCTL,
+- &bridge_cfg);
+- pcie_capability_read_word(rdev->pdev, PCI_EXP_LNKCTL,
+- &gpu_cfg);
+-
+- tmp16 = bridge_cfg | PCI_EXP_LNKCTL_HAWD;
+- pcie_capability_write_word(root, PCI_EXP_LNKCTL, tmp16);
+-
+- tmp16 = gpu_cfg | PCI_EXP_LNKCTL_HAWD;
+- pcie_capability_write_word(rdev->pdev, PCI_EXP_LNKCTL,
+- tmp16);
++ pcie_capability_set_word(root, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD);
++ pcie_capability_set_word(rdev->pdev, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD);
+
+ tmp = RREG32_PCIE(PCIE_LC_STATUS1);
+ max_lw = (tmp & LC_DETECTED_LINK_WIDTH_MASK) >> LC_DETECTED_LINK_WIDTH_SHIFT;
+@@ -7188,22 +7179,14 @@ static void si_pcie_gen3_enable(struct radeon_device *rdev)
+ msleep(100);
+
+ /* linkctl */
+- pcie_capability_read_word(root, PCI_EXP_LNKCTL,
+- &tmp16);
+- tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
+- tmp16 |= (bridge_cfg & PCI_EXP_LNKCTL_HAWD);
+- pcie_capability_write_word(root,
+- PCI_EXP_LNKCTL,
+- tmp16);
+-
+- pcie_capability_read_word(rdev->pdev,
+- PCI_EXP_LNKCTL,
+- &tmp16);
+- tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
+- tmp16 |= (gpu_cfg & PCI_EXP_LNKCTL_HAWD);
+- pcie_capability_write_word(rdev->pdev,
+- PCI_EXP_LNKCTL,
+- tmp16);
++ pcie_capability_clear_and_set_word(root, PCI_EXP_LNKCTL,
++ PCI_EXP_LNKCTL_HAWD,
++ bridge_cfg &
++ PCI_EXP_LNKCTL_HAWD);
++ pcie_capability_clear_and_set_word(rdev->pdev, PCI_EXP_LNKCTL,
++ PCI_EXP_LNKCTL_HAWD,
++ gpu_cfg &
++ PCI_EXP_LNKCTL_HAWD);
+
+ /* linkctl2 */
+ pcie_capability_read_word(root, PCI_EXP_LNKCTL2,
+--
+2.40.1
+
--- /dev/null
+From 763e2732ae25ea80e308215e555f5e05a3960e90 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Mar 2022 09:18:30 +0100
+Subject: drm/repaper: Reduce temporary buffer size in repaper_fb_dirty()
+
+From: Geert Uytterhoeven <geert@linux-m68k.org>
+
+[ Upstream commit fedf429e071f6dbbe7a69dfc342492e037692018 ]
+
+As the temporary buffer is no longer used to store 8-bit grayscale data,
+its size can be reduced to the size needed to store the monochrome
+bitmap data.
+
+Fixes: 24c6bedefbe71de9 ("drm/repaper: Use format helper for xrgb8888 to monochrome conversion")
+Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
+Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220317081830.1211400-6-geert@linux-m68k.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/tiny/repaper.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/tiny/repaper.c b/drivers/gpu/drm/tiny/repaper.c
+index c2677d081a7b6..13ae148f59b9b 100644
+--- a/drivers/gpu/drm/tiny/repaper.c
++++ b/drivers/gpu/drm/tiny/repaper.c
+@@ -533,7 +533,7 @@ static int repaper_fb_dirty(struct drm_framebuffer *fb)
+ DRM_DEBUG("Flushing [FB:%d] st=%ums\n", fb->base.id,
+ epd->factored_stage_time);
+
+- buf = kmalloc_array(fb->width, fb->height, GFP_KERNEL);
++ buf = kmalloc(fb->width * fb->height / 8, GFP_KERNEL);
+ if (!buf) {
+ ret = -ENOMEM;
+ goto out_exit;
+--
+2.40.1
+
--- /dev/null
+From 5da0090af7de7b5bec4e634939981812266d5652 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Jul 2023 11:23:49 +0800
+Subject: drm/tegra: dpaux: Fix incorrect return value of platform_get_irq
+
+From: Yangtao Li <frank.li@vivo.com>
+
+[ Upstream commit 2a1ca44b654346cadfc538c4fb32eecd8daf3140 ]
+
+When platform_get_irq fails, we should return dpaux->irq
+instead of -ENXIO.
+
+Fixes: 6b6b604215c6 ("drm/tegra: Add eDP support")
+Signed-off-by: Yangtao Li <frank.li@vivo.com>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230710032355.72914-13-frank.li@vivo.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/tegra/dpaux.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/tegra/dpaux.c b/drivers/gpu/drm/tegra/dpaux.c
+index 4d2677dcd8315..68ded2e34e1cf 100644
+--- a/drivers/gpu/drm/tegra/dpaux.c
++++ b/drivers/gpu/drm/tegra/dpaux.c
+@@ -468,7 +468,7 @@ static int tegra_dpaux_probe(struct platform_device *pdev)
+
+ dpaux->irq = platform_get_irq(pdev, 0);
+ if (dpaux->irq < 0)
+- return -ENXIO;
++ return dpaux->irq;
+
+ if (!pdev->dev.pm_domain) {
+ dpaux->rst = devm_reset_control_get(&pdev->dev, "dpaux");
+--
+2.40.1
+
--- /dev/null
+From cc5097a247cfac50d816661342cbcef0616c83c1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Jun 2023 10:05:29 +0800
+Subject: drm: xlnx: zynqmp_dpsub: Add missing check for dma_set_mask
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit 1832fba7f9780aff67c96ad30f397c2d76141833 ]
+
+Add check for dma_set_mask() and return the error if it fails.
+
+Fixes: d76271d22694 ("drm: xlnx: DRM/KMS driver for Xilinx ZynqMP DisplayPort Subsystem")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xlnx/zynqmp_dpsub.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/xlnx/zynqmp_dpsub.c b/drivers/gpu/drm/xlnx/zynqmp_dpsub.c
+index bab862484d429..068413be65275 100644
+--- a/drivers/gpu/drm/xlnx/zynqmp_dpsub.c
++++ b/drivers/gpu/drm/xlnx/zynqmp_dpsub.c
+@@ -227,7 +227,9 @@ static int zynqmp_dpsub_probe(struct platform_device *pdev)
+ dpsub->dev = &pdev->dev;
+ platform_set_drvdata(pdev, dpsub);
+
+- dma_set_mask(dpsub->dev, DMA_BIT_MASK(ZYNQMP_DISP_MAX_DMA_BIT));
++ ret = dma_set_mask(dpsub->dev, DMA_BIT_MASK(ZYNQMP_DISP_MAX_DMA_BIT));
++ if (ret)
++ return ret;
+
+ /* Try the reserved memory. Proceed if there's none. */
+ of_reserved_mem_device_init(&pdev->dev);
+--
+2.40.1
+
--- /dev/null
+From 8748522c60eb33616426a0268f813648ce6872f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Jun 2023 19:48:07 +0200
+Subject: dt-bindings: clock: qcom,gcc-sc8280xp: Add missing GDSCs
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit 9eba4db02a88e7a810aabd70f7a6960f184f391f ]
+
+There are 10 more GDSCs that we've not been caring about, and by extension
+(and perhaps even more importantly), not putting to sleep. Add them.
+
+Fixes: a66a82f2a55e ("dt-bindings: clock: Add Qualcomm SC8280XP GCC bindings")
+Acked-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Acked-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/r/20230620-topic-sc8280_gccgdsc-v2-2-562c1428c10d@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/dt-bindings/clock/qcom,gcc-sc8280xp.h | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/include/dt-bindings/clock/qcom,gcc-sc8280xp.h b/include/dt-bindings/clock/qcom,gcc-sc8280xp.h
+index 721105ea4fad8..8454915917849 100644
+--- a/include/dt-bindings/clock/qcom,gcc-sc8280xp.h
++++ b/include/dt-bindings/clock/qcom,gcc-sc8280xp.h
+@@ -494,5 +494,15 @@
+ #define USB30_SEC_GDSC 11
+ #define EMAC_0_GDSC 12
+ #define EMAC_1_GDSC 13
++#define USB4_1_GDSC 14
++#define USB4_GDSC 15
++#define HLOS1_VOTE_MMNOC_MMU_TBU_HF0_GDSC 16
++#define HLOS1_VOTE_MMNOC_MMU_TBU_HF1_GDSC 17
++#define HLOS1_VOTE_MMNOC_MMU_TBU_SF0_GDSC 18
++#define HLOS1_VOTE_MMNOC_MMU_TBU_SF1_GDSC 19
++#define HLOS1_VOTE_TURING_MMU_TBU0_GDSC 20
++#define HLOS1_VOTE_TURING_MMU_TBU1_GDSC 21
++#define HLOS1_VOTE_TURING_MMU_TBU2_GDSC 22
++#define HLOS1_VOTE_TURING_MMU_TBU3_GDSC 23
+
+ #endif
+--
+2.40.1
+
--- /dev/null
+From 329b1ea41f5622d999b052385c5660a2f815b722 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Aug 2023 16:27:34 +0530
+Subject: dt-bindings: clock: Update GCC clocks for QDU1000 and QRU1000 SoCs
+
+From: Imran Shaik <quic_imrashai@quicinc.com>
+
+[ Upstream commit df873243b2398a082d34a006bebe0e0ed7538f5c ]
+
+Add support for GCC_GPLL1_OUT_EVEN and GCC_DDRSS_ECPRI_GSI_CLK clock
+bindings for QDU1000 and QRU1000 SoCs. While at it, update the
+maintainers list.
+
+Signed-off-by: Imran Shaik <quic_imrashai@quicinc.com>
+Acked-by: Rob Herring <robh@kernel.org>
+Link: https://lore.kernel.org/r/20230803105741.2292309-2-quic_imrashai@quicinc.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Stable-dep-of: 06d71fa10f2e ("clk: qcom: gcc-qdu1000: Register gcc_gpll1_out_even clock")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/devicetree/bindings/clock/qcom,qdu1000-gcc.yaml | 3 ++-
+ include/dt-bindings/clock/qcom,qdu1000-gcc.h | 4 +++-
+ 2 files changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/clock/qcom,qdu1000-gcc.yaml b/Documentation/devicetree/bindings/clock/qcom,qdu1000-gcc.yaml
+index 767a9d03aa327..d712b1a87e25f 100644
+--- a/Documentation/devicetree/bindings/clock/qcom,qdu1000-gcc.yaml
++++ b/Documentation/devicetree/bindings/clock/qcom,qdu1000-gcc.yaml
+@@ -7,7 +7,8 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
+ title: Qualcomm Global Clock & Reset Controller for QDU1000 and QRU1000
+
+ maintainers:
+- - Melody Olvera <quic_molvera@quicinc.com>
++ - Taniya Das <quic_tdas@quicinc.com>
++ - Imran Shaik <quic_imrashai@quicinc.com>
+
+ description: |
+ Qualcomm global clock control module which supports the clocks, resets and
+diff --git a/include/dt-bindings/clock/qcom,qdu1000-gcc.h b/include/dt-bindings/clock/qcom,qdu1000-gcc.h
+index ddbc6b825e80c..2fd36cbfddbb2 100644
+--- a/include/dt-bindings/clock/qcom,qdu1000-gcc.h
++++ b/include/dt-bindings/clock/qcom,qdu1000-gcc.h
+@@ -1,6 +1,6 @@
+ /* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
+ /*
+- * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved.
++ * Copyright (c) 2021-2023, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+ #ifndef _DT_BINDINGS_CLK_QCOM_GCC_QDU1000_H
+@@ -138,6 +138,8 @@
+ #define GCC_AGGRE_NOC_ECPRI_GSI_CLK 128
+ #define GCC_PCIE_0_PIPE_CLK_SRC 129
+ #define GCC_PCIE_0_PHY_AUX_CLK_SRC 130
++#define GCC_GPLL1_OUT_EVEN 131
++#define GCC_DDRSS_ECPRI_GSI_CLK 132
+
+ /* GCC resets */
+ #define GCC_ECPRI_CC_BCR 0
+--
+2.40.1
+
--- /dev/null
+From 4f159aa477e9616c53d7493d5a67154f064abdcf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Jul 2023 10:01:40 +0200
+Subject: dt-bindings: extcon: maxim,max77843: restrict connector properties
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit fb2c3f72e819254d8c76de95917e5f9ff232586c ]
+
+Do not allow any other properties in connector child, except what
+usb-connector.yaml evaluates.
+
+Fixes: 9729cad0278b ("dt-bindings: extcon: maxim,max77843: Add MAX77843 bindings")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/devicetree/bindings/extcon/maxim,max77843.yaml | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/Documentation/devicetree/bindings/extcon/maxim,max77843.yaml b/Documentation/devicetree/bindings/extcon/maxim,max77843.yaml
+index 1289605456408..55800fb0221d0 100644
+--- a/Documentation/devicetree/bindings/extcon/maxim,max77843.yaml
++++ b/Documentation/devicetree/bindings/extcon/maxim,max77843.yaml
+@@ -23,6 +23,7 @@ properties:
+
+ connector:
+ $ref: /schemas/connector/usb-connector.yaml#
++ unevaluatedProperties: false
+
+ ports:
+ $ref: /schemas/graph.yaml#/properties/ports
+--
+2.40.1
+
--- /dev/null
+From e1262f2fc18b1c7f05722c8c63aa17e194866a6c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Jul 2023 09:32:32 +0800
+Subject: EDAC/i10nm: Skip the absent memory controllers
+
+From: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
+
+[ Upstream commit c545f5e412250555bd4e717d062b117f20bab418 ]
+
+Some Sapphire Rapids workstations' absent memory controllers
+still appear as PCIe devices that fool the i10nm_edac driver
+and result in "shift exponent -66 is negative" call traces
+from skx_get_dimm_info().
+
+Skip the absent memory controllers to avoid the call traces.
+
+Reported-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Closes: https://lore.kernel.org/linux-edac/CAAd53p41Ku1m1rapeqb1xtD+kKuk+BaUW=dumuoF0ZO3GhFjFA@mail.gmail.com/T/#m5de16dce60a8c836ec235868c7c16e3fefad0cc2
+Tested-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Reported-by: Koba Ko <koba.ko@canonical.com>
+Closes: https://lore.kernel.org/linux-edac/SA1PR11MB71305B71CCCC3D9305835202892AA@SA1PR11MB7130.namprd11.prod.outlook.com/T/#t
+Tested-by: Koba Ko <koba.ko@canonical.com>
+Fixes: d4dc89d069aa ("EDAC, i10nm: Add a driver for Intel 10nm server processors")
+Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
+Signed-off-by: Tony Luck <tony.luck@intel.com>
+Link: https://lore.kernel.org/r/20230710013232.59712-1-qiuxu.zhuo@intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/edac/i10nm_base.c | 54 +++++++++++++++++++++++++++++++++++----
+ 1 file changed, 49 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/edac/i10nm_base.c b/drivers/edac/i10nm_base.c
+index a897b6aff3686..349ff6cfb3796 100644
+--- a/drivers/edac/i10nm_base.c
++++ b/drivers/edac/i10nm_base.c
+@@ -658,13 +658,49 @@ static struct pci_dev *get_ddr_munit(struct skx_dev *d, int i, u32 *offset, unsi
+ return mdev;
+ }
+
++/**
++ * i10nm_imc_absent() - Check whether the memory controller @imc is absent
++ *
++ * @imc : The pointer to the structure of memory controller EDAC device.
++ *
++ * RETURNS : true if the memory controller EDAC device is absent, false otherwise.
++ */
++static bool i10nm_imc_absent(struct skx_imc *imc)
++{
++ u32 mcmtr;
++ int i;
++
++ switch (res_cfg->type) {
++ case SPR:
++ for (i = 0; i < res_cfg->ddr_chan_num; i++) {
++ mcmtr = I10NM_GET_MCMTR(imc, i);
++ edac_dbg(1, "ch%d mcmtr reg %x\n", i, mcmtr);
++ if (mcmtr != ~0)
++ return false;
++ }
++
++ /*
++ * Some workstations' absent memory controllers still
++ * appear as PCIe devices, misleading the EDAC driver.
++ * By observing that the MMIO registers of these absent
++ * memory controllers consistently hold the value of ~0.
++ *
++ * We identify a memory controller as absent by checking
++ * if its MMIO register "mcmtr" == ~0 in all its channels.
++ */
++ return true;
++ default:
++ return false;
++ }
++}
++
+ static int i10nm_get_ddr_munits(void)
+ {
+ struct pci_dev *mdev;
+ void __iomem *mbase;
+ unsigned long size;
+ struct skx_dev *d;
+- int i, j = 0;
++ int i, lmc, j = 0;
+ u32 reg, off;
+ u64 base;
+
+@@ -690,7 +726,7 @@ static int i10nm_get_ddr_munits(void)
+ edac_dbg(2, "socket%d mmio base 0x%llx (reg 0x%x)\n",
+ j++, base, reg);
+
+- for (i = 0; i < res_cfg->ddr_imc_num; i++) {
++ for (lmc = 0, i = 0; i < res_cfg->ddr_imc_num; i++) {
+ mdev = get_ddr_munit(d, i, &off, &size);
+
+ if (i == 0 && !mdev) {
+@@ -700,8 +736,6 @@ static int i10nm_get_ddr_munits(void)
+ if (!mdev)
+ continue;
+
+- d->imc[i].mdev = mdev;
+-
+ edac_dbg(2, "mc%d mmio base 0x%llx size 0x%lx (reg 0x%x)\n",
+ i, base + off, size, reg);
+
+@@ -712,7 +746,17 @@ static int i10nm_get_ddr_munits(void)
+ return -ENODEV;
+ }
+
+- d->imc[i].mbase = mbase;
++ d->imc[lmc].mbase = mbase;
++ if (i10nm_imc_absent(&d->imc[lmc])) {
++ pci_dev_put(mdev);
++ iounmap(mbase);
++ d->imc[lmc].mbase = NULL;
++ edac_dbg(2, "Skip absent mc%d\n", i);
++ continue;
++ } else {
++ d->imc[lmc].mdev = mdev;
++ lmc++;
++ }
+ }
+ }
+
+--
+2.40.1
+
--- /dev/null
+From 74cbf2eb04446711bd731fb01cbec140e5df4efb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Jul 2023 16:04:27 +0800
+Subject: EDAC/igen6: Fix the issue of no error events
+
+From: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
+
+[ Upstream commit ce53ad81ed36c24aff075f94474adecfabfcf239 ]
+
+Current igen6_edac checks for pending errors before the registration
+of the error handler. However, there is a possibility that the error
+occurs during the registration process, leading to unhandled pending
+errors and no future error events. This issue can be reproduced by
+repeatedly injecting errors during the loading of the igen6_edac.
+
+Fix this issue by moving the pending error handler after the registration
+of the error handler, ensuring that no pending errors are left unhandled.
+
+Fixes: 10590a9d4f23 ("EDAC/igen6: Add EDAC driver for Intel client SoCs using IBECC")
+Reported-by: Ee Wey Lim <ee.wey.lim@intel.com>
+Tested-by: Ee Wey Lim <ee.wey.lim@intel.com>
+Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
+Signed-off-by: Tony Luck <tony.luck@intel.com>
+Link: https://lore.kernel.org/r/20230725080427.23883-1-qiuxu.zhuo@intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/edac/igen6_edac.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/edac/igen6_edac.c b/drivers/edac/igen6_edac.c
+index 544dd19072eab..1a18693294db4 100644
+--- a/drivers/edac/igen6_edac.c
++++ b/drivers/edac/igen6_edac.c
+@@ -27,7 +27,7 @@
+ #include "edac_mc.h"
+ #include "edac_module.h"
+
+-#define IGEN6_REVISION "v2.5"
++#define IGEN6_REVISION "v2.5.1"
+
+ #define EDAC_MOD_STR "igen6_edac"
+ #define IGEN6_NMI_NAME "igen6_ibecc"
+@@ -1216,9 +1216,6 @@ static int igen6_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ INIT_WORK(&ecclog_work, ecclog_work_cb);
+ init_irq_work(&ecclog_irq_work, ecclog_irq_work_cb);
+
+- /* Check if any pending errors before registering the NMI handler */
+- ecclog_handler();
+-
+ rc = register_err_handler();
+ if (rc)
+ goto fail3;
+@@ -1230,6 +1227,9 @@ static int igen6_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ goto fail4;
+ }
+
++ /* Check if any pending errors before/during the registration of the error handler */
++ ecclog_handler();
++
+ igen6_debug_setup();
+ return 0;
+ fail4:
+--
+2.40.1
+
--- /dev/null
+From 827736383a76d5a2973b985f6cf4f83994e26755 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Jul 2023 14:54:51 +0800
+Subject: eventfd: prevent underflow for eventfd semaphores
+
+From: Wen Yang <wenyang.linux@foxmail.com>
+
+[ Upstream commit 758b492047816a3158d027e9fca660bc5bcf20bf ]
+
+For eventfd with flag EFD_SEMAPHORE, when its ctx->count is 0, calling
+eventfd_ctx_do_read will cause ctx->count to overflow to ULLONG_MAX.
+
+An underflow can happen with EFD_SEMAPHORE eventfds in at least the
+following three subsystems:
+
+(1) virt/kvm/eventfd.c
+(2) drivers/vfio/virqfd.c
+(3) drivers/virt/acrn/irqfd.c
+
+where (2) and (3) are just modeled after (1). An eventfd must be
+specified for use with the KVM_IRQFD ioctl(). This can also be an
+EFD_SEMAPHORE eventfd. When the eventfd count is zero or has been
+decremented to zero an underflow can be triggered when the irqfd is shut
+down by raising the KVM_IRQFD_FLAG_DEASSIGN flag in the KVM_IRQFD
+ioctl():
+
+ // ctx->count == 0
+ kvm_vm_ioctl()
+ -> kvm_irqfd()
+ -> kvm_irqfd_deassign()
+ -> irqfd_deactivate()
+ -> irqfd_shutdown()
+ -> eventfd_ctx_remove_wait_queue(&cnt)
+ -> eventfd_ctx_do_read(&cnt)
+
+Userspace polling on the eventfd wouldn't notice the underflow because 1
+is always returned as the value from eventfd_read() while ctx->count
+would've underflowed. It's not a huge deal because this should only be
+happening when the irqfd is shutdown but we should still fix it and
+avoid the spurious wakeup.
+
+Fixes: cb289d6244a3 ("eventfd - allow atomic read and waitqueue remove")
+Signed-off-by: Wen Yang <wenyang.linux@foxmail.com>
+Cc: Alexander Viro <viro@zeniv.linux.org.uk>
+Cc: Jens Axboe <axboe@kernel.dk>
+Cc: Christian Brauner <brauner@kernel.org>
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: Dylan Yudaken <dylany@fb.com>
+Cc: David Woodhouse <dwmw@amazon.co.uk>
+Cc: Matthew Wilcox <willy@infradead.org>
+Cc: linux-fsdevel@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org
+Message-Id: <tencent_7588DFD1F365950A757310D764517A14B306@qq.com>
+[brauner: rewrite commit message and add explanation how this underflow can happen]
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/eventfd.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/eventfd.c b/fs/eventfd.c
+index 95850a13ce8d0..1ffbf7c1cd16d 100644
+--- a/fs/eventfd.c
++++ b/fs/eventfd.c
+@@ -189,7 +189,7 @@ void eventfd_ctx_do_read(struct eventfd_ctx *ctx, __u64 *cnt)
+ {
+ lockdep_assert_held(&ctx->wqh.lock);
+
+- *cnt = (ctx->flags & EFD_SEMAPHORE) ? 1 : ctx->count;
++ *cnt = ((ctx->flags & EFD_SEMAPHORE) && ctx->count) ? 1 : ctx->count;
+ ctx->count -= *cnt;
+ }
+ EXPORT_SYMBOL_GPL(eventfd_ctx_do_read);
+--
+2.40.1
+
--- /dev/null
+From edd1da5da1fcb33da1225cce7e35b9744b0d2d08 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Aug 2023 22:31:56 +0800
+Subject: ext4: avoid potential data overflow in next_linear_group
+
+From: Kemeng Shi <shikemeng@huaweicloud.com>
+
+[ Upstream commit 60c672b7f2d1e5dd1774f2399b355c9314e709f8 ]
+
+ngroups is ext4_group_t (unsigned int) while next_linear_group treat it
+in int. If ngroups is bigger than max number described by int, it will
+be treat as a negative number. Then "return group + 1 >= ngroups ? 0 :
+group + 1;" may keep returning 0.
+Switch int to ext4_group_t in next_linear_group to fix the overflow.
+
+Fixes: 196e402adf2e ("ext4: improve cr 0 / cr 1 group scanning")
+Signed-off-by: Kemeng Shi <shikemeng@huaweicloud.com>
+Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
+Link: https://lore.kernel.org/r/20230801143204.2284343-3-shikemeng@huaweicloud.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/mballoc.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
+index 98e12326b0d6a..333439b3ac146 100644
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -966,8 +966,9 @@ static inline int should_optimize_scan(struct ext4_allocation_context *ac)
+ * Return next linear group for allocation. If linear traversal should not be
+ * performed, this function just returns the same group
+ */
+-static int
+-next_linear_group(struct ext4_allocation_context *ac, int group, int ngroups)
++static ext4_group_t
++next_linear_group(struct ext4_allocation_context *ac, ext4_group_t group,
++ ext4_group_t ngroups)
+ {
+ if (!should_optimize_scan(ac))
+ goto inc_and_return;
+--
+2.40.1
+
--- /dev/null
+From cf719be06893ad5c23f5d7a4806f8c718ec7fe68 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Aug 2023 22:31:55 +0800
+Subject: ext4: correct grp validation in ext4_mb_good_group
+
+From: Kemeng Shi <shikemeng@huaweicloud.com>
+
+[ Upstream commit a9ce5993a0f5c0887c8a1b4ffa3b8046fbcfdc93 ]
+
+Group corruption check will access memory of grp and will trigger kernel
+crash if grp is NULL. So do NULL check before corruption check.
+
+Fixes: 5354b2af3406 ("ext4: allow ext4_get_group_info() to fail")
+Signed-off-by: Kemeng Shi <shikemeng@huaweicloud.com>
+Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
+Link: https://lore.kernel.org/r/20230801143204.2284343-2-shikemeng@huaweicloud.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/mballoc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
+index 3fa5de892d89d..98e12326b0d6a 100644
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -2414,7 +2414,7 @@ static bool ext4_mb_good_group(struct ext4_allocation_context *ac,
+
+ BUG_ON(cr < 0 || cr >= 4);
+
+- if (unlikely(EXT4_MB_GRP_BBITMAP_CORRUPT(grp) || !grp))
++ if (unlikely(!grp || EXT4_MB_GRP_BBITMAP_CORRUPT(grp)))
+ return false;
+
+ free = grp->bb_free;
+--
+2.40.1
+
--- /dev/null
+From 8d881983e22f26c7120c8beadb592d5f87e203f3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 Jun 2023 21:20:11 +0800
+Subject: ext4: fix unttached inode after power cut with orphan file feature
+ enabled
+
+From: Zhihao Cheng <chengzhihao1@huawei.com>
+
+[ Upstream commit 1524773425ae8113b0b782886366e68656b34e53 ]
+
+Running generic/475(filesystem consistent tests after power cut) could
+easily trigger unattached inode error while doing fsck:
+ Unattached zero-length inode 39405. Clear? no
+
+ Unattached inode 39405
+ Connect to /lost+found? no
+
+Above inconsistence is caused by following process:
+ P1 P2
+ext4_create
+ inode = ext4_new_inode_start_handle // itable records nlink=1
+ ext4_add_nondir
+ err = ext4_add_entry // ENOSPC
+ ext4_append
+ ext4_bread
+ ext4_getblk
+ ext4_map_blocks // returns ENOSPC
+ drop_nlink(inode) // won't be updated into disk inode
+ ext4_orphan_add(handle, inode)
+ ext4_orphan_file_add
+ ext4_journal_stop(handle)
+ jbd2_journal_commit_transaction // commit success
+ >> power cut <<
+ext4_fill_super
+ ext4_load_and_init_journal // itable records nlink=1
+ ext4_orphan_cleanup
+ ext4_process_orphan
+ if (inode->i_nlink) // true, inode won't be deleted
+
+Then, allocated inode will be reserved on disk and corresponds to no
+dentries, so e2fsck reports 'unattached inode' problem.
+
+The problem won't happen if orphan file feature is disabled, because
+ext4_orphan_add() will update disk inode in orphan list mode. There
+are several places not updating disk inode while putting inode into
+orphan area, such as ext4_add_nondir(), ext4_symlink() and whiteout
+in ext4_rename(). Fix it by updating inode into disk in all error
+branches of these places.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=217605
+Fixes: 02f310fcf47f ("ext4: Speedup ext4 orphan inode handling")
+Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20230628132011.650383-1-chengzhihao1@huawei.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/namei.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
+index 0caf6c730ce34..6bcc3770ee19f 100644
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -2799,6 +2799,7 @@ static int ext4_add_nondir(handle_t *handle,
+ return err;
+ }
+ drop_nlink(inode);
++ ext4_mark_inode_dirty(handle, inode);
+ ext4_orphan_add(handle, inode);
+ unlock_new_inode(inode);
+ return err;
+@@ -3436,6 +3437,7 @@ static int ext4_symlink(struct mnt_idmap *idmap, struct inode *dir,
+
+ err_drop_inode:
+ clear_nlink(inode);
++ ext4_mark_inode_dirty(handle, inode);
+ ext4_orphan_add(handle, inode);
+ unlock_new_inode(inode);
+ if (handle)
+@@ -4021,6 +4023,7 @@ static int ext4_rename(struct mnt_idmap *idmap, struct inode *old_dir,
+ ext4_resetent(handle, &old,
+ old.inode->i_ino, old_file_type);
+ drop_nlink(whiteout);
++ ext4_mark_inode_dirty(handle, whiteout);
+ ext4_orphan_add(handle, whiteout);
+ }
+ unlock_new_inode(whiteout);
+--
+2.40.1
+
--- /dev/null
+From 140368b4200a05d253efa6fc7e323c0404db8937 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Aug 2023 15:28:49 +0200
+Subject: extcon: cht_wc: add POWER_SUPPLY dependency
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit d20a3a8a32e3fa564ff25da860c5fc1a97642dfe ]
+
+The driver fails to link when CONFIG_POWER_SUPPLY is disabled:
+
+x86_64-linux-ld: vmlinux.o: in function `cht_wc_extcon_psy_get_prop':
+extcon-intel-cht-wc.c:(.text+0x15ccda7): undefined reference to `power_supply_get_drvdata'
+x86_64-linux-ld: vmlinux.o: in function `cht_wc_extcon_pwrsrc_event':
+extcon-intel-cht-wc.c:(.text+0x15cd3e9): undefined reference to `power_supply_changed'
+x86_64-linux-ld: vmlinux.o: in function `cht_wc_extcon_probe':
+extcon-intel-cht-wc.c:(.text+0x15cd596): undefined reference to `devm_power_supply_register'
+
+It should be possible to change the driver to not require this at
+compile time and still provide other functions, but adding a hard
+Kconfig dependency does not seem to have any practical downsides
+and is simpler since the option is normally enabled anyway.
+
+Fixes: 66e31186cd2aa ("extcon: intel-cht-wc: Add support for registering a power_supply class-device")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/extcon/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig
+index 290186e44e6bd..4dd52a6a5b48d 100644
+--- a/drivers/extcon/Kconfig
++++ b/drivers/extcon/Kconfig
+@@ -62,6 +62,7 @@ config EXTCON_INTEL_CHT_WC
+ tristate "Intel Cherrytrail Whiskey Cove PMIC extcon driver"
+ depends on INTEL_SOC_PMIC_CHTWC
+ depends on USB_SUPPORT
++ depends on POWER_SUPPLY
+ select USB_ROLE_SWITCH
+ help
+ Say Y here to enable extcon support for charger detection / control
+--
+2.40.1
+
--- /dev/null
+From f44ee973b37f455bbcbe905bd06d7c78edf11ee1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Jul 2023 22:23:24 -0700
+Subject: f2fs: fix spelling in ABI documentation
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit c709d099a0d2befa2b16c249ef8df722b43e6c28 ]
+
+Correct spelling problems as identified by codespell.
+
+Fixes: 9e615dbba41e ("f2fs: add missing description for ipu_policy node")
+Fixes: b2e4a2b300e5 ("f2fs: expose discard related parameters in sysfs")
+Fixes: 846ae671ad36 ("f2fs: expose extension_list sysfs entry")
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Cc: Jaegeuk Kim <jaegeuk@kernel.org>
+Cc: Chao Yu <chao@kernel.org>
+Cc: linux-f2fs-devel@lists.sourceforge.net
+Cc: Yangtao Li <frank.li@vivo.com>
+Cc: Konstantin Vyshetsky <vkon@google.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/ABI/testing/sysfs-fs-f2fs | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs
+index 8140fc98f5aee..ad3d76d37c8ba 100644
+--- a/Documentation/ABI/testing/sysfs-fs-f2fs
++++ b/Documentation/ABI/testing/sysfs-fs-f2fs
+@@ -54,9 +54,9 @@ Description: Controls the in-place-update policy.
+ 0x00 DISABLE disable IPU(=default option in LFS mode)
+ 0x01 FORCE all the time
+ 0x02 SSR if SSR mode is activated
+- 0x04 UTIL if FS utilization is over threashold
++ 0x04 UTIL if FS utilization is over threshold
+ 0x08 SSR_UTIL if SSR mode is activated and FS utilization is over
+- threashold
++ threshold
+ 0x10 FSYNC activated in fsync path only for high performance
+ flash storages. IPU will be triggered only if the
+ # of dirty pages over min_fsync_blocks.
+@@ -117,7 +117,7 @@ Date: December 2021
+ Contact: "Konstantin Vyshetsky" <vkon@google.com>
+ Description: Controls the number of discards a thread will issue at a time.
+ Higher number will allow the discard thread to finish its work
+- faster, at the cost of higher latency for incomming I/O.
++ faster, at the cost of higher latency for incoming I/O.
+
+ What: /sys/fs/f2fs/<disk>/min_discard_issue_time
+ Date: December 2021
+@@ -334,7 +334,7 @@ Description: This indicates how many GC can be failed for the pinned
+ state. 2048 trials is set by default.
+
+ What: /sys/fs/f2fs/<disk>/extension_list
+-Date: Feburary 2018
++Date: February 2018
+ Contact: "Chao Yu" <yuchao0@huawei.com>
+ Description: Used to control configure extension list:
+ - Query: cat /sys/fs/f2fs/<disk>/extension_list
+--
+2.40.1
+
--- /dev/null
+From e75d1ea8ed4e71636de6f76845324d2865f829d0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Aug 2023 08:59:49 +0800
+Subject: f2fs: fix to account cp stats correctly
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit eb61c2cca2eb2110cc7b61a7bc15b3850977a778 ]
+
+cp_foreground_calls sysfs entry shows total CP call count rather than
+foreground CP call count, fix it.
+
+Fixes: fc7100ea2a52 ("f2fs: Add f2fs stats to sysfs")
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/checkpoint.c | 2 +-
+ fs/f2fs/debug.c | 9 ++++++++-
+ fs/f2fs/f2fs.h | 25 ++++++++++++++-----------
+ fs/f2fs/gc.c | 5 +++++
+ fs/f2fs/recovery.c | 1 +
+ fs/f2fs/segment.c | 3 ++-
+ fs/f2fs/super.c | 8 +++++++-
+ fs/f2fs/sysfs.c | 14 ++++++++++++--
+ 8 files changed, 50 insertions(+), 17 deletions(-)
+
+diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
+index 8fd3b7f9fb88e..b0597a539fc54 100644
+--- a/fs/f2fs/checkpoint.c
++++ b/fs/f2fs/checkpoint.c
+@@ -1701,9 +1701,9 @@ int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
+ }
+
+ f2fs_restore_inmem_curseg(sbi);
++ stat_inc_cp_count(sbi);
+ stop:
+ unblock_operations(sbi);
+- stat_inc_cp_count(sbi->stat_info);
+
+ if (cpc->reason & CP_RECOVERY)
+ f2fs_notice(sbi, "checkpoint: version = %llx", ckpt_ver);
+diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c
+index c7cf453dce838..fdbf994f12718 100644
+--- a/fs/f2fs/debug.c
++++ b/fs/f2fs/debug.c
+@@ -215,6 +215,9 @@ static void update_general_status(struct f2fs_sb_info *sbi)
+ si->valid_blks[type] += blks;
+ }
+
++ for (i = 0; i < MAX_CALL_TYPE; i++)
++ si->cp_call_count[i] = atomic_read(&sbi->cp_call_count[i]);
++
+ for (i = 0; i < 2; i++) {
+ si->segment_count[i] = sbi->segment_count[i];
+ si->block_count[i] = sbi->block_count[i];
+@@ -497,7 +500,9 @@ static int stat_show(struct seq_file *s, void *v)
+ seq_printf(s, " - Prefree: %d\n - Free: %d (%d)\n\n",
+ si->prefree_count, si->free_segs, si->free_secs);
+ seq_printf(s, "CP calls: %d (BG: %d)\n",
+- si->cp_count, si->bg_cp_count);
++ si->cp_call_count[TOTAL_CALL],
++ si->cp_call_count[BACKGROUND]);
++ seq_printf(s, "CP count: %d\n", si->cp_count);
+ seq_printf(s, " - cp blocks : %u\n", si->meta_count[META_CP]);
+ seq_printf(s, " - sit blocks : %u\n",
+ si->meta_count[META_SIT]);
+@@ -699,6 +704,8 @@ int f2fs_build_stats(struct f2fs_sb_info *sbi)
+ atomic_set(&sbi->inplace_count, 0);
+ for (i = META_CP; i < META_MAX; i++)
+ atomic_set(&sbi->meta_count[i], 0);
++ for (i = 0; i < MAX_CALL_TYPE; i++)
++ atomic_set(&sbi->cp_call_count[i], 0);
+
+ atomic_set(&sbi->max_aw_cnt, 0);
+
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 278a401e32cf3..cfb8e274c0699 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -1377,6 +1377,13 @@ enum errors_option {
+ MOUNT_ERRORS_PANIC, /* panic on errors */
+ };
+
++enum {
++ BACKGROUND,
++ FOREGROUND,
++ MAX_CALL_TYPE,
++ TOTAL_CALL = FOREGROUND,
++};
++
+ static inline int f2fs_test_bit(unsigned int nr, char *addr);
+ static inline void f2fs_set_bit(unsigned int nr, char *addr);
+ static inline void f2fs_clear_bit(unsigned int nr, char *addr);
+@@ -1687,6 +1694,7 @@ struct f2fs_sb_info {
+ unsigned int io_skip_bggc; /* skip background gc for in-flight IO */
+ unsigned int other_skip_bggc; /* skip background gc for other reasons */
+ unsigned int ndirty_inode[NR_INODE_TYPE]; /* # of dirty inodes */
++ atomic_t cp_call_count[MAX_CALL_TYPE]; /* # of cp call */
+ #endif
+ spinlock_t stat_lock; /* lock for stat operations */
+
+@@ -3848,12 +3856,6 @@ void f2fs_destroy_recovery_cache(void);
+ /*
+ * debug.c
+ */
+-enum {
+- BACKGROUND,
+- FOREGROUND,
+- MAX_CALL_TYPE
+-};
+-
+ #ifdef CONFIG_F2FS_STAT_FS
+ struct f2fs_stat_info {
+ struct list_head stat_list;
+@@ -3900,7 +3902,7 @@ struct f2fs_stat_info {
+ int dirty_count, node_pages, meta_pages, compress_pages;
+ int compress_page_hit;
+ int prefree_count, free_segs, free_secs;
+- int cp_count, bg_cp_count;
++ int cp_call_count[MAX_CALL_TYPE], cp_count;
+ int gc_call_count[MAX_CALL_TYPE];
+ int gc_segs[2][2];
+ int gc_secs[2][2];
+@@ -3925,8 +3927,9 @@ static inline struct f2fs_stat_info *F2FS_STAT(struct f2fs_sb_info *sbi)
+ return (struct f2fs_stat_info *)sbi->stat_info;
+ }
+
+-#define stat_inc_cp_count(si) ((si)->cp_count++)
+-#define stat_inc_bg_cp_count(si) ((si)->bg_cp_count++)
++#define stat_inc_cp_call_count(sbi, foreground) \
++ atomic_inc(&sbi->cp_call_count[(foreground)])
++#define stat_inc_cp_count(si) (F2FS_STAT(sbi)->cp_count++)
+ #define stat_io_skip_bggc_count(sbi) ((sbi)->io_skip_bggc++)
+ #define stat_other_skip_bggc_count(sbi) ((sbi)->other_skip_bggc++)
+ #define stat_inc_dirty_inode(sbi, type) ((sbi)->ndirty_inode[type]++)
+@@ -4043,8 +4046,8 @@ void __init f2fs_create_root_stats(void);
+ void f2fs_destroy_root_stats(void);
+ void f2fs_update_sit_info(struct f2fs_sb_info *sbi);
+ #else
+-#define stat_inc_cp_count(si) do { } while (0)
+-#define stat_inc_bg_cp_count(si) do { } while (0)
++#define stat_inc_cp_call_count(sbi, foreground) do { } while (0)
++#define stat_inc_cp_count(sbi) do { } while (0)
+ #define stat_io_skip_bggc_count(sbi) do { } while (0)
+ #define stat_other_skip_bggc_count(sbi) do { } while (0)
+ #define stat_inc_dirty_inode(sbi, type) do { } while (0)
+diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
+index 2addd7c95c7eb..7d2736b66c702 100644
+--- a/fs/f2fs/gc.c
++++ b/fs/f2fs/gc.c
+@@ -1840,6 +1840,7 @@ int f2fs_gc(struct f2fs_sb_info *sbi, struct f2fs_gc_control *gc_control)
+ * secure free segments which doesn't need fggc any more.
+ */
+ if (prefree_segments(sbi)) {
++ stat_inc_cp_call_count(sbi, TOTAL_CALL);
+ ret = f2fs_write_checkpoint(sbi, &cpc);
+ if (ret)
+ goto stop;
+@@ -1884,6 +1885,7 @@ int f2fs_gc(struct f2fs_sb_info *sbi, struct f2fs_gc_control *gc_control)
+ round++;
+ if (skipped_round > MAX_SKIP_GC_COUNT &&
+ skipped_round * 2 >= round) {
++ stat_inc_cp_call_count(sbi, TOTAL_CALL);
+ ret = f2fs_write_checkpoint(sbi, &cpc);
+ goto stop;
+ }
+@@ -1899,6 +1901,7 @@ int f2fs_gc(struct f2fs_sb_info *sbi, struct f2fs_gc_control *gc_control)
+ */
+ if (free_sections(sbi) <= upper_secs + NR_GC_CHECKPOINT_SECS &&
+ prefree_segments(sbi)) {
++ stat_inc_cp_call_count(sbi, TOTAL_CALL);
+ ret = f2fs_write_checkpoint(sbi, &cpc);
+ if (ret)
+ goto stop;
+@@ -2024,6 +2027,7 @@ static int free_segment_range(struct f2fs_sb_info *sbi,
+ if (gc_only)
+ goto out;
+
++ stat_inc_cp_call_count(sbi, TOTAL_CALL);
+ err = f2fs_write_checkpoint(sbi, &cpc);
+ if (err)
+ goto out;
+@@ -2216,6 +2220,7 @@ int f2fs_resize_fs(struct file *filp, __u64 block_count)
+ clear_sbi_flag(sbi, SBI_IS_RESIZEFS);
+ set_sbi_flag(sbi, SBI_IS_DIRTY);
+
++ stat_inc_cp_call_count(sbi, TOTAL_CALL);
+ err = f2fs_write_checkpoint(sbi, &cpc);
+ if (err) {
+ update_fs_metadata(sbi, secs);
+diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
+index 58c1a0096f7de..5b632d2641d49 100644
+--- a/fs/f2fs/recovery.c
++++ b/fs/f2fs/recovery.c
+@@ -895,6 +895,7 @@ int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only)
+ struct cp_control cpc = {
+ .reason = CP_RECOVERY,
+ };
++ stat_inc_cp_call_count(sbi, TOTAL_CALL);
+ err = f2fs_write_checkpoint(sbi, &cpc);
+ }
+ }
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index aa126597b8be5..37196d7a9685c 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -511,8 +511,8 @@ void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi, bool from_bg)
+
+ mutex_unlock(&sbi->flush_lock);
+ }
++ stat_inc_cp_call_count(sbi, BACKGROUND);
+ f2fs_sync_fs(sbi->sb, 1);
+- stat_inc_bg_cp_count(sbi->stat_info);
+ }
+
+ static int __submit_flush_wait(struct f2fs_sb_info *sbi,
+@@ -3151,6 +3151,7 @@ int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range)
+ goto out;
+
+ f2fs_down_write(&sbi->gc_lock);
++ stat_inc_cp_call_count(sbi, TOTAL_CALL);
+ err = f2fs_write_checkpoint(sbi, &cpc);
+ f2fs_up_write(&sbi->gc_lock);
+ if (err)
+diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
+index 20f1bda0e1a17..a6f283d34cd49 100644
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -1598,6 +1598,7 @@ static void f2fs_put_super(struct super_block *sb)
+ struct cp_control cpc = {
+ .reason = CP_UMOUNT,
+ };
++ stat_inc_cp_call_count(sbi, TOTAL_CALL);
+ err = f2fs_write_checkpoint(sbi, &cpc);
+ }
+
+@@ -1607,6 +1608,7 @@ static void f2fs_put_super(struct super_block *sb)
+ struct cp_control cpc = {
+ .reason = CP_UMOUNT | CP_TRIMMED,
+ };
++ stat_inc_cp_call_count(sbi, TOTAL_CALL);
+ err = f2fs_write_checkpoint(sbi, &cpc);
+ }
+
+@@ -1703,8 +1705,10 @@ int f2fs_sync_fs(struct super_block *sb, int sync)
+ if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING)))
+ return -EAGAIN;
+
+- if (sync)
++ if (sync) {
++ stat_inc_cp_call_count(sbi, TOTAL_CALL);
+ err = f2fs_issue_checkpoint(sbi);
++ }
+
+ return err;
+ }
+@@ -2229,6 +2233,7 @@ static int f2fs_disable_checkpoint(struct f2fs_sb_info *sbi)
+ f2fs_down_write(&sbi->gc_lock);
+ cpc.reason = CP_PAUSE;
+ set_sbi_flag(sbi, SBI_CP_DISABLED);
++ stat_inc_cp_call_count(sbi, TOTAL_CALL);
+ err = f2fs_write_checkpoint(sbi, &cpc);
+ if (err)
+ goto out_unlock;
+@@ -4848,6 +4853,7 @@ static void kill_f2fs_super(struct super_block *sb)
+ struct cp_control cpc = {
+ .reason = CP_UMOUNT,
+ };
++ stat_inc_cp_call_count(sbi, TOTAL_CALL);
+ f2fs_write_checkpoint(sbi, &cpc);
+ }
+
+diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
+index 52a0b7878e718..8e18c2d742ca9 100644
+--- a/fs/f2fs/sysfs.c
++++ b/fs/f2fs/sysfs.c
+@@ -356,6 +356,16 @@ static ssize_t f2fs_sbi_show(struct f2fs_attr *a,
+ if (!strcmp(a->attr.name, "revoked_atomic_block"))
+ return sysfs_emit(buf, "%llu\n", sbi->revoked_atomic_block);
+
++#ifdef CONFIG_F2FS_STAT_FS
++ if (!strcmp(a->attr.name, "cp_foreground_calls"))
++ return sysfs_emit(buf, "%d\n",
++ atomic_read(&sbi->cp_call_count[TOTAL_CALL]) -
++ atomic_read(&sbi->cp_call_count[BACKGROUND]));
++ if (!strcmp(a->attr.name, "cp_background_calls"))
++ return sysfs_emit(buf, "%d\n",
++ atomic_read(&sbi->cp_call_count[BACKGROUND]));
++#endif
++
+ ui = (unsigned int *)(ptr + a->offset);
+
+ return sysfs_emit(buf, "%u\n", *ui);
+@@ -972,8 +982,8 @@ F2FS_SBI_GENERAL_RO_ATTR(unusable_blocks_per_sec);
+
+ /* STAT_INFO ATTR */
+ #ifdef CONFIG_F2FS_STAT_FS
+-STAT_INFO_RO_ATTR(cp_foreground_calls, cp_count);
+-STAT_INFO_RO_ATTR(cp_background_calls, bg_cp_count);
++STAT_INFO_RO_ATTR(cp_foreground_calls, cp_call_count[FOREGROUND]);
++STAT_INFO_RO_ATTR(cp_background_calls, cp_call_count[BACKGROUND]);
+ STAT_INFO_RO_ATTR(gc_foreground_calls, gc_call_count[FOREGROUND]);
+ STAT_INFO_RO_ATTR(gc_background_calls, gc_call_count[BACKGROUND]);
+ #endif
+--
+2.40.1
+
--- /dev/null
+From 8b6421a1b98823252e678605c5e46347f8c32729 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Aug 2023 08:59:48 +0800
+Subject: f2fs: fix to account gc stats correctly
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 9bf1dcbdfdc8892d9cfeaeab02519c0ecf17fe51 ]
+
+As reported, status debugfs entry shows inconsistent GC stats as below:
+
+GC calls: 6008 (BG: 6161)
+ - data segments : 3053 (BG: 3053)
+ - node segments : 2955 (BG: 2955)
+
+Total GC calls is larger than BGGC calls, the reason is:
+- f2fs_stat_info.call_count accounts total migrated section count
+by f2fs_gc()
+- f2fs_stat_info.bg_gc accounts total call times of f2fs_gc() from
+background gc_thread
+
+Another issue is gc_foreground_calls sysfs entry shows total GC call
+count rather than FGGC call count.
+
+This patch changes as below for fix:
+- account GC calls and migrated segment count separately
+- support to account migrated section count if it enables large section
+mode
+- fix to show correct value in gc_foreground_calls sysfs entry
+
+Fixes: fc7100ea2a52 ("f2fs: Add f2fs stats to sysfs")
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/debug.c | 24 ++++++++++++++++++------
+ fs/f2fs/f2fs.h | 42 +++++++++++++++++++++---------------------
+ fs/f2fs/file.c | 4 ++++
+ fs/f2fs/gc.c | 13 +++++++------
+ fs/f2fs/segment.c | 1 +
+ fs/f2fs/super.c | 1 +
+ fs/f2fs/sysfs.c | 4 ++--
+ 7 files changed, 54 insertions(+), 35 deletions(-)
+
+diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c
+index 61c35b59126ec..c7cf453dce838 100644
+--- a/fs/f2fs/debug.c
++++ b/fs/f2fs/debug.c
+@@ -511,12 +511,24 @@ static int stat_show(struct seq_file *s, void *v)
+ seq_printf(s, " - Total : %4d\n", si->nr_total_ckpt);
+ seq_printf(s, " - Cur time : %4d(ms)\n", si->cur_ckpt_time);
+ seq_printf(s, " - Peak time : %4d(ms)\n", si->peak_ckpt_time);
+- seq_printf(s, "GC calls: %d (BG: %d)\n",
+- si->call_count, si->bg_gc);
+- seq_printf(s, " - data segments : %d (%d)\n",
+- si->data_segs, si->bg_data_segs);
+- seq_printf(s, " - node segments : %d (%d)\n",
+- si->node_segs, si->bg_node_segs);
++ seq_printf(s, "GC calls: %d (gc_thread: %d)\n",
++ si->gc_call_count[BACKGROUND] +
++ si->gc_call_count[FOREGROUND],
++ si->gc_call_count[BACKGROUND]);
++ if (__is_large_section(sbi)) {
++ seq_printf(s, " - data sections : %d (BG: %d)\n",
++ si->gc_secs[DATA][BG_GC] + si->gc_secs[DATA][FG_GC],
++ si->gc_secs[DATA][BG_GC]);
++ seq_printf(s, " - node sections : %d (BG: %d)\n",
++ si->gc_secs[NODE][BG_GC] + si->gc_secs[NODE][FG_GC],
++ si->gc_secs[NODE][BG_GC]);
++ }
++ seq_printf(s, " - data segments : %d (BG: %d)\n",
++ si->gc_segs[DATA][BG_GC] + si->gc_segs[DATA][FG_GC],
++ si->gc_segs[DATA][BG_GC]);
++ seq_printf(s, " - node segments : %d (BG: %d)\n",
++ si->gc_segs[NODE][BG_GC] + si->gc_segs[NODE][FG_GC],
++ si->gc_segs[NODE][BG_GC]);
+ seq_puts(s, " - Reclaimed segs :\n");
+ seq_printf(s, " - Normal : %d\n", sbi->gc_reclaimed_segs[GC_NORMAL]);
+ seq_printf(s, " - Idle CB : %d\n", sbi->gc_reclaimed_segs[GC_IDLE_CB]);
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 395d23ab149da..278a401e32cf3 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -3848,6 +3848,12 @@ void f2fs_destroy_recovery_cache(void);
+ /*
+ * debug.c
+ */
++enum {
++ BACKGROUND,
++ FOREGROUND,
++ MAX_CALL_TYPE
++};
++
+ #ifdef CONFIG_F2FS_STAT_FS
+ struct f2fs_stat_info {
+ struct list_head stat_list;
+@@ -3873,7 +3879,7 @@ struct f2fs_stat_info {
+ int nats, dirty_nats, sits, dirty_sits;
+ int free_nids, avail_nids, alloc_nids;
+ int total_count, utilization;
+- int bg_gc, nr_wb_cp_data, nr_wb_data;
++ int nr_wb_cp_data, nr_wb_data;
+ int nr_rd_data, nr_rd_node, nr_rd_meta;
+ int nr_dio_read, nr_dio_write;
+ unsigned int io_skip_bggc, other_skip_bggc;
+@@ -3893,9 +3899,11 @@ struct f2fs_stat_info {
+ int rsvd_segs, overp_segs;
+ int dirty_count, node_pages, meta_pages, compress_pages;
+ int compress_page_hit;
+- int prefree_count, call_count, cp_count, bg_cp_count;
+- int tot_segs, node_segs, data_segs, free_segs, free_secs;
+- int bg_node_segs, bg_data_segs;
++ int prefree_count, free_segs, free_secs;
++ int cp_count, bg_cp_count;
++ int gc_call_count[MAX_CALL_TYPE];
++ int gc_segs[2][2];
++ int gc_secs[2][2];
+ int tot_blks, data_blks, node_blks;
+ int bg_data_blks, bg_node_blks;
+ int curseg[NR_CURSEG_TYPE];
+@@ -3919,8 +3927,6 @@ static inline struct f2fs_stat_info *F2FS_STAT(struct f2fs_sb_info *sbi)
+
+ #define stat_inc_cp_count(si) ((si)->cp_count++)
+ #define stat_inc_bg_cp_count(si) ((si)->bg_cp_count++)
+-#define stat_inc_call_count(si) ((si)->call_count++)
+-#define stat_inc_bggc_count(si) ((si)->bg_gc++)
+ #define stat_io_skip_bggc_count(sbi) ((sbi)->io_skip_bggc++)
+ #define stat_other_skip_bggc_count(sbi) ((sbi)->other_skip_bggc++)
+ #define stat_inc_dirty_inode(sbi, type) ((sbi)->ndirty_inode[type]++)
+@@ -4005,18 +4011,12 @@ static inline struct f2fs_stat_info *F2FS_STAT(struct f2fs_sb_info *sbi)
+ if (cur > max) \
+ atomic_set(&F2FS_I_SB(inode)->max_aw_cnt, cur); \
+ } while (0)
+-#define stat_inc_seg_count(sbi, type, gc_type) \
+- do { \
+- struct f2fs_stat_info *si = F2FS_STAT(sbi); \
+- si->tot_segs++; \
+- if ((type) == SUM_TYPE_DATA) { \
+- si->data_segs++; \
+- si->bg_data_segs += (gc_type == BG_GC) ? 1 : 0; \
+- } else { \
+- si->node_segs++; \
+- si->bg_node_segs += (gc_type == BG_GC) ? 1 : 0; \
+- } \
+- } while (0)
++#define stat_inc_gc_call_count(sbi, foreground) \
++ (F2FS_STAT(sbi)->gc_call_count[(foreground)]++)
++#define stat_inc_gc_sec_count(sbi, type, gc_type) \
++ (F2FS_STAT(sbi)->gc_secs[(type)][(gc_type)]++)
++#define stat_inc_gc_seg_count(sbi, type, gc_type) \
++ (F2FS_STAT(sbi)->gc_segs[(type)][(gc_type)]++)
+
+ #define stat_inc_tot_blk_count(si, blks) \
+ ((si)->tot_blks += (blks))
+@@ -4045,8 +4045,6 @@ void f2fs_update_sit_info(struct f2fs_sb_info *sbi);
+ #else
+ #define stat_inc_cp_count(si) do { } while (0)
+ #define stat_inc_bg_cp_count(si) do { } while (0)
+-#define stat_inc_call_count(si) do { } while (0)
+-#define stat_inc_bggc_count(si) do { } while (0)
+ #define stat_io_skip_bggc_count(sbi) do { } while (0)
+ #define stat_other_skip_bggc_count(sbi) do { } while (0)
+ #define stat_inc_dirty_inode(sbi, type) do { } while (0)
+@@ -4074,7 +4072,9 @@ void f2fs_update_sit_info(struct f2fs_sb_info *sbi);
+ #define stat_inc_seg_type(sbi, curseg) do { } while (0)
+ #define stat_inc_block_count(sbi, curseg) do { } while (0)
+ #define stat_inc_inplace_blocks(sbi) do { } while (0)
+-#define stat_inc_seg_count(sbi, type, gc_type) do { } while (0)
++#define stat_inc_gc_call_count(sbi, foreground) do { } while (0)
++#define stat_inc_gc_sec_count(sbi, type, gc_type) do { } while (0)
++#define stat_inc_gc_seg_count(sbi, type, gc_type) do { } while (0)
+ #define stat_inc_tot_blk_count(si, blks) do { } while (0)
+ #define stat_inc_data_blk_count(sbi, blks, gc_type) do { } while (0)
+ #define stat_inc_node_blk_count(sbi, blks, gc_type) do { } while (0)
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index f1be41014180a..094b047d246c9 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -1729,6 +1729,7 @@ static int f2fs_expand_inode_data(struct inode *inode, loff_t offset,
+ if (has_not_enough_free_secs(sbi, 0,
+ GET_SEC_FROM_SEG(sbi, overprovision_segments(sbi)))) {
+ f2fs_down_write(&sbi->gc_lock);
++ stat_inc_gc_call_count(sbi, FOREGROUND);
+ err = f2fs_gc(sbi, &gc_control);
+ if (err && err != -ENODATA)
+ goto out_err;
+@@ -2477,6 +2478,7 @@ static int f2fs_ioc_gc(struct file *filp, unsigned long arg)
+
+ gc_control.init_gc_type = sync ? FG_GC : BG_GC;
+ gc_control.err_gc_skipped = sync;
++ stat_inc_gc_call_count(sbi, FOREGROUND);
+ ret = f2fs_gc(sbi, &gc_control);
+ out:
+ mnt_drop_write_file(filp);
+@@ -2520,6 +2522,7 @@ static int __f2fs_ioc_gc_range(struct file *filp, struct f2fs_gc_range *range)
+ }
+
+ gc_control.victim_segno = GET_SEGNO(sbi, range->start);
++ stat_inc_gc_call_count(sbi, FOREGROUND);
+ ret = f2fs_gc(sbi, &gc_control);
+ if (ret) {
+ if (ret == -EBUSY)
+@@ -2991,6 +2994,7 @@ static int f2fs_ioc_flush_device(struct file *filp, unsigned long arg)
+ sm->last_victim[ALLOC_NEXT] = end_segno + 1;
+
+ gc_control.victim_segno = start_segno;
++ stat_inc_gc_call_count(sbi, FOREGROUND);
+ ret = f2fs_gc(sbi, &gc_control);
+ if (ret == -EAGAIN)
+ ret = 0;
+diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
+index 719b1ba32a78b..2addd7c95c7eb 100644
+--- a/fs/f2fs/gc.c
++++ b/fs/f2fs/gc.c
+@@ -121,8 +121,8 @@ static int gc_thread_func(void *data)
+ else
+ increase_sleep_time(gc_th, &wait_ms);
+ do_gc:
+- if (!foreground)
+- stat_inc_bggc_count(sbi->stat_info);
++ stat_inc_gc_call_count(sbi, foreground ?
++ FOREGROUND : BACKGROUND);
+
+ sync_mode = F2FS_OPTION(sbi).bggc_mode == BGGC_MODE_SYNC;
+
+@@ -1685,6 +1685,7 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
+ int seg_freed = 0, migrated = 0;
+ unsigned char type = IS_DATASEG(get_seg_entry(sbi, segno)->type) ?
+ SUM_TYPE_DATA : SUM_TYPE_NODE;
++ unsigned char data_type = (type == SUM_TYPE_DATA) ? DATA : NODE;
+ int submitted = 0;
+
+ if (__is_large_section(sbi))
+@@ -1766,7 +1767,7 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
+ segno, gc_type,
+ force_migrate);
+
+- stat_inc_seg_count(sbi, type, gc_type);
++ stat_inc_gc_seg_count(sbi, data_type, gc_type);
+ sbi->gc_reclaimed_segs[sbi->gc_mode]++;
+ migrated++;
+
+@@ -1783,12 +1784,12 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
+ }
+
+ if (submitted)
+- f2fs_submit_merged_write(sbi,
+- (type == SUM_TYPE_NODE) ? NODE : DATA);
++ f2fs_submit_merged_write(sbi, data_type);
+
+ blk_finish_plug(&plug);
+
+- stat_inc_call_count(sbi->stat_info);
++ if (migrated)
++ stat_inc_gc_sec_count(sbi, data_type, gc_type);
+
+ return seg_freed;
+ }
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index 6db410f1bb8ce..aa126597b8be5 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -433,6 +433,7 @@ void f2fs_balance_fs(struct f2fs_sb_info *sbi, bool need)
+ .err_gc_skipped = false,
+ .nr_free_secs = 1 };
+ f2fs_down_write(&sbi->gc_lock);
++ stat_inc_gc_call_count(sbi, FOREGROUND);
+ f2fs_gc(sbi, &gc_control);
+ }
+ }
+diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
+index 72b7ea71f55df..751ac088bc19e 100644
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -2189,6 +2189,7 @@ static int f2fs_disable_checkpoint(struct f2fs_sb_info *sbi)
+ .nr_free_secs = 1 };
+
+ f2fs_down_write(&sbi->gc_lock);
++ stat_inc_gc_call_count(sbi, FOREGROUND);
+ err = f2fs_gc(sbi, &gc_control);
+ if (err == -ENODATA) {
+ err = 0;
+diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
+index 99b028db80a1d..52a0b7878e718 100644
+--- a/fs/f2fs/sysfs.c
++++ b/fs/f2fs/sysfs.c
+@@ -974,8 +974,8 @@ F2FS_SBI_GENERAL_RO_ATTR(unusable_blocks_per_sec);
+ #ifdef CONFIG_F2FS_STAT_FS
+ STAT_INFO_RO_ATTR(cp_foreground_calls, cp_count);
+ STAT_INFO_RO_ATTR(cp_background_calls, bg_cp_count);
+-STAT_INFO_RO_ATTR(gc_foreground_calls, call_count);
+-STAT_INFO_RO_ATTR(gc_background_calls, bg_gc);
++STAT_INFO_RO_ATTR(gc_foreground_calls, gc_call_count[FOREGROUND]);
++STAT_INFO_RO_ATTR(gc_background_calls, gc_call_count[BACKGROUND]);
+ #endif
+
+ /* FAULT_INFO ATTR */
+--
+2.40.1
+
--- /dev/null
+From 51bc57325eef46ad4fa1f5b3c6ee5d5287e72fc0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Jul 2023 10:06:14 +0800
+Subject: f2fs: fix to avoid mmap vs set_compress_option case
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit b5ab3276eb69cacf44ecfb11b2bfab73096ff4e4 ]
+
+Compression option in inode should not be changed after they have
+been used, however, it may happen in below race case:
+
+Thread A Thread B
+- f2fs_ioc_set_compress_option
+ - check f2fs_is_mmap_file()
+ - check get_dirty_pages()
+ - check F2FS_HAS_BLOCKS()
+ - f2fs_file_mmap
+ - set_inode_flag(FI_MMAP_FILE)
+ - fault
+ - do_page_mkwrite
+ - f2fs_vm_page_mkwrite
+ - f2fs_get_block_locked
+ - fault_dirty_shared_page
+ - set_page_dirty
+ - update i_compress_algorithm
+ - update i_log_cluster_size
+ - update i_cluster_size
+
+Avoid such race condition by covering f2fs_file_mmap() w/ i_sem lock,
+meanwhile add mmap file check condition in f2fs_may_compress() as well.
+
+Fixes: e1e8debec656 ("f2fs: add F2FS_IOC_SET_COMPRESS_OPTION ioctl")
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/f2fs.h | 3 ++-
+ fs/f2fs/file.c | 23 ++++++++++++++++++-----
+ 2 files changed, 20 insertions(+), 6 deletions(-)
+
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 271d4e7b22c91..395d23ab149da 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -4469,7 +4469,8 @@ static inline bool f2fs_low_mem_mode(struct f2fs_sb_info *sbi)
+ static inline bool f2fs_may_compress(struct inode *inode)
+ {
+ if (IS_SWAPFILE(inode) || f2fs_is_pinned_file(inode) ||
+- f2fs_is_atomic_file(inode) || f2fs_has_inline_data(inode))
++ f2fs_is_atomic_file(inode) || f2fs_has_inline_data(inode) ||
++ f2fs_is_mmap_file(inode))
+ return false;
+ return S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode);
+ }
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index ead75c4e833d2..f1be41014180a 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -528,7 +528,11 @@ static int f2fs_file_mmap(struct file *file, struct vm_area_struct *vma)
+
+ file_accessed(file);
+ vma->vm_ops = &f2fs_file_vm_ops;
++
++ f2fs_down_read(&F2FS_I(inode)->i_sem);
+ set_inode_flag(inode, FI_MMAP_FILE);
++ f2fs_up_read(&F2FS_I(inode)->i_sem);
++
+ return 0;
+ }
+
+@@ -1920,12 +1924,19 @@ static int f2fs_setflags_common(struct inode *inode, u32 iflags, u32 mask)
+ int err = f2fs_convert_inline_inode(inode);
+ if (err)
+ return err;
+- if (!f2fs_may_compress(inode))
+- return -EINVAL;
+- if (S_ISREG(inode->i_mode) && F2FS_HAS_BLOCKS(inode))
++
++ f2fs_down_write(&F2FS_I(inode)->i_sem);
++ if (!f2fs_may_compress(inode) ||
++ (S_ISREG(inode->i_mode) &&
++ F2FS_HAS_BLOCKS(inode))) {
++ f2fs_up_write(&F2FS_I(inode)->i_sem);
+ return -EINVAL;
+- if (set_compress_context(inode))
+- return -EOPNOTSUPP;
++ }
++ err = set_compress_context(inode);
++ f2fs_up_write(&F2FS_I(inode)->i_sem);
++
++ if (err)
++ return err;
+ }
+ }
+
+@@ -3953,6 +3964,7 @@ static int f2fs_ioc_set_compress_option(struct file *filp, unsigned long arg)
+ file_start_write(filp);
+ inode_lock(inode);
+
++ f2fs_down_write(&F2FS_I(inode)->i_sem);
+ if (f2fs_is_mmap_file(inode) || get_dirty_pages(inode)) {
+ ret = -EBUSY;
+ goto out;
+@@ -3972,6 +3984,7 @@ static int f2fs_ioc_set_compress_option(struct file *filp, unsigned long arg)
+ f2fs_warn(sbi, "compression algorithm is successfully set, "
+ "but current kernel doesn't support this algorithm.");
+ out:
++ f2fs_up_write(&F2FS_I(inode)->i_sem);
+ inode_unlock(inode);
+ file_end_write(filp);
+
+--
+2.40.1
+
--- /dev/null
+From 5f3c1e6eb5ee0ec4c75123234dafdf8fd9e2422e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 28 May 2023 15:47:12 +0800
+Subject: f2fs: fix to drop all dirty meta/node pages during umount()
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 20872584b8c0b006c007da9588a272c9e28d2e18 ]
+
+For cp error case, there will be dirty meta/node pages remained after
+f2fs_write_checkpoint() in f2fs_put_super(), drop them explicitly, and
+do sanity check on reference count of dirty pages and inflight IOs.
+
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Stable-dep-of: eb61c2cca2eb ("f2fs: fix to account cp stats correctly")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/super.c | 18 ++++++++++++++++--
+ 1 file changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
+index 751ac088bc19e..20f1bda0e1a17 100644
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -1571,6 +1571,7 @@ static void f2fs_put_super(struct super_block *sb)
+ {
+ struct f2fs_sb_info *sbi = F2FS_SB(sb);
+ int i;
++ int err = 0;
+ bool done;
+
+ /* unregister procfs/sysfs entries in advance to avoid race case */
+@@ -1597,7 +1598,7 @@ static void f2fs_put_super(struct super_block *sb)
+ struct cp_control cpc = {
+ .reason = CP_UMOUNT,
+ };
+- f2fs_write_checkpoint(sbi, &cpc);
++ err = f2fs_write_checkpoint(sbi, &cpc);
+ }
+
+ /* be sure to wait for any on-going discard commands */
+@@ -1606,7 +1607,7 @@ static void f2fs_put_super(struct super_block *sb)
+ struct cp_control cpc = {
+ .reason = CP_UMOUNT | CP_TRIMMED,
+ };
+- f2fs_write_checkpoint(sbi, &cpc);
++ err = f2fs_write_checkpoint(sbi, &cpc);
+ }
+
+ /*
+@@ -1623,6 +1624,19 @@ static void f2fs_put_super(struct super_block *sb)
+
+ f2fs_wait_on_all_pages(sbi, F2FS_WB_CP_DATA);
+
++ if (err) {
++ truncate_inode_pages_final(NODE_MAPPING(sbi));
++ truncate_inode_pages_final(META_MAPPING(sbi));
++ }
++
++ for (i = 0; i < NR_COUNT_TYPE; i++) {
++ if (!get_pages(sbi, i))
++ continue;
++ f2fs_err(sbi, "detect filesystem reference count leak during "
++ "umount, type: %d, count: %lld", i, get_pages(sbi, i));
++ f2fs_bug_on(sbi, 1);
++ }
++
+ f2fs_bug_on(sbi, sbi->fsync_node_num);
+
+ f2fs_destroy_compress_inode(sbi);
+--
+2.40.1
+
--- /dev/null
+From 8091cf755d8ce0ee1d4f66b1b7e7e25afb8fd5fb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Aug 2023 22:28:42 +0800
+Subject: f2fs: Only lfs mode is allowed with zoned block device feature
+
+From: Chunhai Guo <guochunhai@vivo.com>
+
+[ Upstream commit 2bd4df8fcbc72f58ce3c62ed021ab291ca42de0b ]
+
+Now f2fs support four block allocation modes: lfs, adaptive,
+fragment:segment, fragment:block. Only lfs mode is allowed with zoned block
+device feature.
+
+Fixes: 6691d940b0e0 ("f2fs: introduce fragment allocation mode mount option")
+Signed-off-by: Chunhai Guo <guochunhai@vivo.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/super.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
+index 3d91b5313947f..72b7ea71f55df 100644
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -860,11 +860,6 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount)
+ if (!name)
+ return -ENOMEM;
+ if (!strcmp(name, "adaptive")) {
+- if (f2fs_sb_has_blkzoned(sbi)) {
+- f2fs_warn(sbi, "adaptive mode is not allowed with zoned block device feature");
+- kfree(name);
+- return -EINVAL;
+- }
+ F2FS_OPTION(sbi).fs_mode = FS_MODE_ADAPTIVE;
+ } else if (!strcmp(name, "lfs")) {
+ F2FS_OPTION(sbi).fs_mode = FS_MODE_LFS;
+@@ -1329,6 +1324,11 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount)
+ F2FS_OPTION(sbi).discard_unit =
+ DISCARD_UNIT_SECTION;
+ }
++
++ if (F2FS_OPTION(sbi).fs_mode != FS_MODE_LFS) {
++ f2fs_info(sbi, "Only lfs mode is allowed with zoned block device feature");
++ return -EINVAL;
++ }
+ #else
+ f2fs_err(sbi, "Zoned block device support is not enabled");
+ return -EINVAL;
+--
+2.40.1
+
--- /dev/null
+From 3ad465bb00f4ca6271c18d180b729c4b0dc0d681 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 May 2023 23:16:03 +0800
+Subject: f2fs: refactor struct f2fs_attr macro
+
+From: Yangtao Li <frank.li@vivo.com>
+
+[ Upstream commit 6201c478dedcf7c50361b23b5c4d4f41a68921ac ]
+
+This patch provides a large number of variants of F2FS_RW_ATTR
+and F2FS_RO_ATTR macros, reducing the number of parameters required
+to initialize the f2fs_attr structure.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Link: https://lore.kernel.org/oe-kbuild-all/202304152234.wjaY3IYm-lkp@intel.com/
+Signed-off-by: Yangtao Li <frank.li@vivo.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Stable-dep-of: 9bf1dcbdfdc8 ("f2fs: fix to account gc stats correctly")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/sysfs.c | 240 ++++++++++++++++++++++++++++++------------------
+ 1 file changed, 149 insertions(+), 91 deletions(-)
+
+diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
+index 8ea05340bad90..99b028db80a1d 100644
+--- a/fs/f2fs/sysfs.c
++++ b/fs/f2fs/sysfs.c
+@@ -842,68 +842,160 @@ static struct f2fs_attr f2fs_attr_##_name = { \
+ #define F2FS_GENERAL_RO_ATTR(name) \
+ static struct f2fs_attr f2fs_attr_##name = __ATTR(name, 0444, name##_show, NULL)
+
+-#define F2FS_STAT_ATTR(_struct_type, _struct_name, _name, _elname) \
+-static struct f2fs_attr f2fs_attr_##_name = { \
+- .attr = {.name = __stringify(_name), .mode = 0444 }, \
+- .show = f2fs_sbi_show, \
+- .struct_type = _struct_type, \
+- .offset = offsetof(struct _struct_name, _elname), \
+-}
++#ifdef CONFIG_F2FS_STAT_FS
++#define STAT_INFO_RO_ATTR(name, elname) \
++ F2FS_RO_ATTR(STAT_INFO, f2fs_stat_info, name, elname)
++#endif
+
+-F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_urgent_sleep_time,
+- urgent_sleep_time);
+-F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_min_sleep_time, min_sleep_time);
+-F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_max_sleep_time, max_sleep_time);
+-F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_no_gc_sleep_time, no_gc_sleep_time);
+-F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_idle, gc_mode);
+-F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_urgent, gc_mode);
+-F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, reclaim_segments, rec_prefree_segments);
+-F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, max_small_discards, max_discards);
+-F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, max_discard_request, max_discard_request);
+-F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, min_discard_issue_time, min_discard_issue_time);
+-F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, mid_discard_issue_time, mid_discard_issue_time);
+-F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, max_discard_issue_time, max_discard_issue_time);
+-F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, discard_io_aware_gran, discard_io_aware_gran);
+-F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, discard_urgent_util, discard_urgent_util);
+-F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, discard_granularity, discard_granularity);
+-F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, max_ordered_discard, max_ordered_discard);
+-F2FS_RW_ATTR(RESERVED_BLOCKS, f2fs_sb_info, reserved_blocks, reserved_blocks);
+-F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, ipu_policy, ipu_policy);
+-F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_ipu_util, min_ipu_util);
+-F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_fsync_blocks, min_fsync_blocks);
+-F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_seq_blocks, min_seq_blocks);
+-F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_hot_blocks, min_hot_blocks);
+-F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_ssr_sections, min_ssr_sections);
+-F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ram_thresh, ram_thresh);
+-F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ra_nid_pages, ra_nid_pages);
+-F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, dirty_nats_ratio, dirty_nats_ratio);
+-F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, max_roll_forward_node_blocks, max_rf_node_blocks);
+-F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_victim_search, max_victim_search);
+-F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, migration_granularity, migration_granularity);
+-F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, dir_level, dir_level);
+-F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, cp_interval, interval_time[CP_TIME]);
+-F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, idle_interval, interval_time[REQ_TIME]);
+-F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, discard_idle_interval,
+- interval_time[DISCARD_TIME]);
+-F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_idle_interval, interval_time[GC_TIME]);
+-F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info,
+- umount_discard_timeout, interval_time[UMOUNT_DISCARD_TIMEOUT]);
+-#ifdef CONFIG_F2FS_IOSTAT
+-F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, iostat_enable, iostat_enable);
+-F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, iostat_period_ms, iostat_period_ms);
++#define GC_THREAD_RW_ATTR(name, elname) \
++ F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, name, elname)
++
++#define SM_INFO_RW_ATTR(name, elname) \
++ F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, name, elname)
++
++#define SM_INFO_GENERAL_RW_ATTR(elname) \
++ SM_INFO_RW_ATTR(elname, elname)
++
++#define DCC_INFO_RW_ATTR(name, elname) \
++ F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, name, elname)
++
++#define DCC_INFO_GENERAL_RW_ATTR(elname) \
++ DCC_INFO_RW_ATTR(elname, elname)
++
++#define NM_INFO_RW_ATTR(name, elname) \
++ F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, name, elname)
++
++#define NM_INFO_GENERAL_RW_ATTR(elname) \
++ NM_INFO_RW_ATTR(elname, elname)
++
++#define F2FS_SBI_RW_ATTR(name, elname) \
++ F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, name, elname)
++
++#define F2FS_SBI_GENERAL_RW_ATTR(elname) \
++ F2FS_SBI_RW_ATTR(elname, elname)
++
++#define F2FS_SBI_GENERAL_RO_ATTR(elname) \
++ F2FS_RO_ATTR(F2FS_SBI, f2fs_sb_info, elname, elname)
++
++#ifdef CONFIG_F2FS_FAULT_INJECTION
++#define FAULT_INFO_GENERAL_RW_ATTR(type, elname) \
++ F2FS_RW_ATTR(type, f2fs_fault_info, elname, elname)
+ #endif
+-F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, readdir_ra, readdir_ra);
+-F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_io_bytes, max_io_bytes);
+-F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_pin_file_thresh, gc_pin_file_threshold);
++
++#define RESERVED_BLOCKS_GENERAL_RW_ATTR(elname) \
++ F2FS_RW_ATTR(RESERVED_BLOCKS, f2fs_sb_info, elname, elname)
++
++#define CPRC_INFO_GENERAL_RW_ATTR(elname) \
++ F2FS_RW_ATTR(CPRC_INFO, ckpt_req_control, elname, elname)
++
++#define ATGC_INFO_RW_ATTR(name, elname) \
++ F2FS_RW_ATTR(ATGC_INFO, atgc_management, name, elname)
++
++/* GC_THREAD ATTR */
++GC_THREAD_RW_ATTR(gc_urgent_sleep_time, urgent_sleep_time);
++GC_THREAD_RW_ATTR(gc_min_sleep_time, min_sleep_time);
++GC_THREAD_RW_ATTR(gc_max_sleep_time, max_sleep_time);
++GC_THREAD_RW_ATTR(gc_no_gc_sleep_time, no_gc_sleep_time);
++
++/* SM_INFO ATTR */
++SM_INFO_RW_ATTR(reclaim_segments, rec_prefree_segments);
++SM_INFO_GENERAL_RW_ATTR(ipu_policy);
++SM_INFO_GENERAL_RW_ATTR(min_ipu_util);
++SM_INFO_GENERAL_RW_ATTR(min_fsync_blocks);
++SM_INFO_GENERAL_RW_ATTR(min_seq_blocks);
++SM_INFO_GENERAL_RW_ATTR(min_hot_blocks);
++SM_INFO_GENERAL_RW_ATTR(min_ssr_sections);
++
++/* DCC_INFO ATTR */
++DCC_INFO_RW_ATTR(max_small_discards, max_discards);
++DCC_INFO_GENERAL_RW_ATTR(max_discard_request);
++DCC_INFO_GENERAL_RW_ATTR(min_discard_issue_time);
++DCC_INFO_GENERAL_RW_ATTR(mid_discard_issue_time);
++DCC_INFO_GENERAL_RW_ATTR(max_discard_issue_time);
++DCC_INFO_GENERAL_RW_ATTR(discard_io_aware_gran);
++DCC_INFO_GENERAL_RW_ATTR(discard_urgent_util);
++DCC_INFO_GENERAL_RW_ATTR(discard_granularity);
++DCC_INFO_GENERAL_RW_ATTR(max_ordered_discard);
++
++/* NM_INFO ATTR */
++NM_INFO_RW_ATTR(max_roll_forward_node_blocks, max_rf_node_blocks);
++NM_INFO_GENERAL_RW_ATTR(ram_thresh);
++NM_INFO_GENERAL_RW_ATTR(ra_nid_pages);
++NM_INFO_GENERAL_RW_ATTR(dirty_nats_ratio);
++
++/* F2FS_SBI ATTR */
+ F2FS_RW_ATTR(F2FS_SBI, f2fs_super_block, extension_list, extension_list);
++F2FS_SBI_RW_ATTR(gc_idle, gc_mode);
++F2FS_SBI_RW_ATTR(gc_urgent, gc_mode);
++F2FS_SBI_RW_ATTR(cp_interval, interval_time[CP_TIME]);
++F2FS_SBI_RW_ATTR(idle_interval, interval_time[REQ_TIME]);
++F2FS_SBI_RW_ATTR(discard_idle_interval, interval_time[DISCARD_TIME]);
++F2FS_SBI_RW_ATTR(gc_idle_interval, interval_time[GC_TIME]);
++F2FS_SBI_RW_ATTR(umount_discard_timeout, interval_time[UMOUNT_DISCARD_TIMEOUT]);
++F2FS_SBI_RW_ATTR(gc_pin_file_thresh, gc_pin_file_threshold);
++F2FS_SBI_RW_ATTR(gc_reclaimed_segments, gc_reclaimed_segs);
++F2FS_SBI_GENERAL_RW_ATTR(max_victim_search);
++F2FS_SBI_GENERAL_RW_ATTR(migration_granularity);
++F2FS_SBI_GENERAL_RW_ATTR(dir_level);
++#ifdef CONFIG_F2FS_IOSTAT
++F2FS_SBI_GENERAL_RW_ATTR(iostat_enable);
++F2FS_SBI_GENERAL_RW_ATTR(iostat_period_ms);
++#endif
++F2FS_SBI_GENERAL_RW_ATTR(readdir_ra);
++F2FS_SBI_GENERAL_RW_ATTR(max_io_bytes);
++F2FS_SBI_GENERAL_RW_ATTR(data_io_flag);
++F2FS_SBI_GENERAL_RW_ATTR(node_io_flag);
++F2FS_SBI_GENERAL_RW_ATTR(gc_remaining_trials);
++F2FS_SBI_GENERAL_RW_ATTR(seq_file_ra_mul);
++F2FS_SBI_GENERAL_RW_ATTR(gc_segment_mode);
++F2FS_SBI_GENERAL_RW_ATTR(max_fragment_chunk);
++F2FS_SBI_GENERAL_RW_ATTR(max_fragment_hole);
++#ifdef CONFIG_F2FS_FS_COMPRESSION
++F2FS_SBI_GENERAL_RW_ATTR(compr_written_block);
++F2FS_SBI_GENERAL_RW_ATTR(compr_saved_block);
++F2FS_SBI_GENERAL_RW_ATTR(compr_new_inode);
++F2FS_SBI_GENERAL_RW_ATTR(compress_percent);
++F2FS_SBI_GENERAL_RW_ATTR(compress_watermark);
++#endif
++/* atomic write */
++F2FS_SBI_GENERAL_RO_ATTR(current_atomic_write);
++F2FS_SBI_GENERAL_RW_ATTR(peak_atomic_write);
++F2FS_SBI_GENERAL_RW_ATTR(committed_atomic_block);
++F2FS_SBI_GENERAL_RW_ATTR(revoked_atomic_block);
++/* block age extent cache */
++F2FS_SBI_GENERAL_RW_ATTR(hot_data_age_threshold);
++F2FS_SBI_GENERAL_RW_ATTR(warm_data_age_threshold);
++F2FS_SBI_GENERAL_RW_ATTR(last_age_weight);
++#ifdef CONFIG_BLK_DEV_ZONED
++F2FS_SBI_GENERAL_RO_ATTR(unusable_blocks_per_sec);
++#endif
++
++/* STAT_INFO ATTR */
++#ifdef CONFIG_F2FS_STAT_FS
++STAT_INFO_RO_ATTR(cp_foreground_calls, cp_count);
++STAT_INFO_RO_ATTR(cp_background_calls, bg_cp_count);
++STAT_INFO_RO_ATTR(gc_foreground_calls, call_count);
++STAT_INFO_RO_ATTR(gc_background_calls, bg_gc);
++#endif
++
++/* FAULT_INFO ATTR */
+ #ifdef CONFIG_F2FS_FAULT_INJECTION
+-F2FS_RW_ATTR(FAULT_INFO_RATE, f2fs_fault_info, inject_rate, inject_rate);
+-F2FS_RW_ATTR(FAULT_INFO_TYPE, f2fs_fault_info, inject_type, inject_type);
++FAULT_INFO_GENERAL_RW_ATTR(FAULT_INFO_RATE, inject_rate);
++FAULT_INFO_GENERAL_RW_ATTR(FAULT_INFO_TYPE, inject_type);
+ #endif
+-F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, data_io_flag, data_io_flag);
+-F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, node_io_flag, node_io_flag);
+-F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_remaining_trials, gc_remaining_trials);
+-F2FS_RW_ATTR(CPRC_INFO, ckpt_req_control, ckpt_thread_ioprio, ckpt_thread_ioprio);
++
++/* RESERVED_BLOCKS ATTR */
++RESERVED_BLOCKS_GENERAL_RW_ATTR(reserved_blocks);
++
++/* CPRC_INFO ATTR */
++CPRC_INFO_GENERAL_RW_ATTR(ckpt_thread_ioprio);
++
++/* ATGC_INFO ATTR */
++ATGC_INFO_RW_ATTR(atgc_candidate_ratio, candidate_ratio);
++ATGC_INFO_RW_ATTR(atgc_candidate_count, max_candidate_count);
++ATGC_INFO_RW_ATTR(atgc_age_weight, age_weight);
++ATGC_INFO_RW_ATTR(atgc_age_threshold, age_threshold);
++
+ F2FS_GENERAL_RO_ATTR(dirty_segments);
+ F2FS_GENERAL_RO_ATTR(free_segments);
+ F2FS_GENERAL_RO_ATTR(ovp_segments);
+@@ -917,10 +1009,6 @@ F2FS_GENERAL_RO_ATTR(main_blkaddr);
+ F2FS_GENERAL_RO_ATTR(pending_discard);
+ F2FS_GENERAL_RO_ATTR(gc_mode);
+ #ifdef CONFIG_F2FS_STAT_FS
+-F2FS_STAT_ATTR(STAT_INFO, f2fs_stat_info, cp_foreground_calls, cp_count);
+-F2FS_STAT_ATTR(STAT_INFO, f2fs_stat_info, cp_background_calls, bg_cp_count);
+-F2FS_STAT_ATTR(STAT_INFO, f2fs_stat_info, gc_foreground_calls, call_count);
+-F2FS_STAT_ATTR(STAT_INFO, f2fs_stat_info, gc_background_calls, bg_gc);
+ F2FS_GENERAL_RO_ATTR(moved_blocks_background);
+ F2FS_GENERAL_RO_ATTR(moved_blocks_foreground);
+ F2FS_GENERAL_RO_ATTR(avg_vblocks);
+@@ -935,8 +1023,6 @@ F2FS_FEATURE_RO_ATTR(encrypted_casefold);
+ #endif /* CONFIG_FS_ENCRYPTION */
+ #ifdef CONFIG_BLK_DEV_ZONED
+ F2FS_FEATURE_RO_ATTR(block_zoned);
+-F2FS_RO_ATTR(F2FS_SBI, f2fs_sb_info, unusable_blocks_per_sec,
+- unusable_blocks_per_sec);
+ #endif
+ F2FS_FEATURE_RO_ATTR(atomic_write);
+ F2FS_FEATURE_RO_ATTR(extra_attr);
+@@ -956,37 +1042,9 @@ F2FS_FEATURE_RO_ATTR(casefold);
+ F2FS_FEATURE_RO_ATTR(readonly);
+ #ifdef CONFIG_F2FS_FS_COMPRESSION
+ F2FS_FEATURE_RO_ATTR(compression);
+-F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, compr_written_block, compr_written_block);
+-F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, compr_saved_block, compr_saved_block);
+-F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, compr_new_inode, compr_new_inode);
+-F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, compress_percent, compress_percent);
+-F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, compress_watermark, compress_watermark);
+ #endif
+ F2FS_FEATURE_RO_ATTR(pin_file);
+
+-/* For ATGC */
+-F2FS_RW_ATTR(ATGC_INFO, atgc_management, atgc_candidate_ratio, candidate_ratio);
+-F2FS_RW_ATTR(ATGC_INFO, atgc_management, atgc_candidate_count, max_candidate_count);
+-F2FS_RW_ATTR(ATGC_INFO, atgc_management, atgc_age_weight, age_weight);
+-F2FS_RW_ATTR(ATGC_INFO, atgc_management, atgc_age_threshold, age_threshold);
+-
+-F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, seq_file_ra_mul, seq_file_ra_mul);
+-F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_segment_mode, gc_segment_mode);
+-F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_reclaimed_segments, gc_reclaimed_segs);
+-F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_fragment_chunk, max_fragment_chunk);
+-F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_fragment_hole, max_fragment_hole);
+-
+-/* For atomic write */
+-F2FS_RO_ATTR(F2FS_SBI, f2fs_sb_info, current_atomic_write, current_atomic_write);
+-F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, peak_atomic_write, peak_atomic_write);
+-F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, committed_atomic_block, committed_atomic_block);
+-F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, revoked_atomic_block, revoked_atomic_block);
+-
+-/* For block age extent cache */
+-F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, hot_data_age_threshold, hot_data_age_threshold);
+-F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, warm_data_age_threshold, warm_data_age_threshold);
+-F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, last_age_weight, last_age_weight);
+-
+ #define ATTR_LIST(name) (&f2fs_attr_##name.attr)
+ static struct attribute *f2fs_attrs[] = {
+ ATTR_LIST(gc_urgent_sleep_time),
+--
+2.40.1
+
--- /dev/null
+From 0f218bf566ec3f1e642abefac226f464665099b3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Aug 2023 12:29:08 -0500
+Subject: firmware: cs_dsp: Fix new control name check
+
+From: Vlad Karpovich <vkarpovi@opensource.cirrus.com>
+
+[ Upstream commit 7ac1102b227b36550452b663fd39ab1c09378a95 ]
+
+Before adding a new FW control, its name is checked against
+existing controls list. But the string length in strncmp used
+to compare controls names is taken from the list, so if beginnings
+of the controls are matching, then the new control is not created.
+For example, if CAL_R control already exists, CAL_R_SELECTED
+is not created.
+The fix is to compare string lengths as well.
+
+Fixes: 6477960755fb ("ASoC: wm_adsp: Move check for control existence")
+Signed-off-by: Vlad Karpovich <vkarpovi@opensource.cirrus.com>
+Link: https://lore.kernel.org/r/20230815172908.3454056-1-vkarpovi@opensource.cirrus.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/cirrus/cs_dsp.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c
+index ec056f6f40ce8..cc3a28f386a77 100644
+--- a/drivers/firmware/cirrus/cs_dsp.c
++++ b/drivers/firmware/cirrus/cs_dsp.c
+@@ -978,7 +978,8 @@ static int cs_dsp_create_control(struct cs_dsp *dsp,
+ ctl->alg_region.alg == alg_region->alg &&
+ ctl->alg_region.type == alg_region->type) {
+ if ((!subname && !ctl->subname) ||
+- (subname && !strncmp(ctl->subname, subname, ctl->subname_len))) {
++ (subname && (ctl->subname_len == subname_len) &&
++ !strncmp(ctl->subname, subname, ctl->subname_len))) {
+ if (!ctl->enabled)
+ ctl->enabled = 1;
+ return 0;
+--
+2.40.1
+
--- /dev/null
+From 115129c14528d4c2372d8b45c18b51acc6e0cd09 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 15 Jul 2023 22:13:38 +0800
+Subject: firmware: meson_sm: fix to avoid potential NULL pointer dereference
+
+From: Zhang Shurong <zhang_shurong@foxmail.com>
+
+[ Upstream commit f2ed165619c16577c02b703a114a1f6b52026df4 ]
+
+of_match_device() may fail and returns a NULL pointer.
+
+Fix this by checking the return value of of_match_device.
+
+Fixes: 8cde3c2153e8 ("firmware: meson_sm: Rework driver as a proper platform driver")
+Signed-off-by: Zhang Shurong <zhang_shurong@foxmail.com>
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://lore.kernel.org/r/tencent_AA08AAA6C4F34D53ADCE962E188A879B8206@qq.com
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/meson/meson_sm.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/firmware/meson/meson_sm.c b/drivers/firmware/meson/meson_sm.c
+index 798bcdb05d84e..9a2656d73600b 100644
+--- a/drivers/firmware/meson/meson_sm.c
++++ b/drivers/firmware/meson/meson_sm.c
+@@ -292,6 +292,8 @@ static int __init meson_sm_probe(struct platform_device *pdev)
+ return -ENOMEM;
+
+ chip = of_match_device(meson_sm_ids, dev)->data;
++ if (!chip)
++ return -EINVAL;
+
+ if (chip->cmd_shmem_in_base) {
+ fw->sm_shmem_in_base = meson_sm_map_shmem(chip->cmd_shmem_in_base,
+--
+2.40.1
+
--- /dev/null
+From 2f6c592aeddca3a08f9743a5468c4d1f70e054f5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Jun 2023 08:03:29 -0500
+Subject: firmware: ti_sci: Use system_state to determine polling
+
+From: Nishanth Menon <nm@ti.com>
+
+[ Upstream commit 9225bcdedf16297a346082e7d23b0e8434aa98ed ]
+
+Commit b9e8a7d950ff ("firmware: ti_sci: Switch transport to polled
+mode during system suspend") aims to resolve issues with tisci
+operations during system suspend operation. However, the system may
+enter a no_irq stage in various other usage modes, including power-off
+and restart. To determine if polling mode is appropriate, use the
+system_state instead.
+
+While at this, drop the unused is_suspending state variable and
+related helpers.
+
+Fixes: b9e8a7d950ff ("firmware: ti_sci: Switch transport to polled mode during system suspend")
+Reported-by: Francesco Dolcini <francesco@dolcini.it>
+Reported-by: Wadim Egorov <w.egorov@phytec.de>
+Tested-by: Francesco Dolcini <francesco.dolcini@toradex.com> # Toradex Verdin AM62
+Link: https://lore.kernel.org/r/20230620130329.4120443-1-nm@ti.com
+Closes: https://lore.kernel.org/all/ZGeHMjlnob2GFyHF@francesco-nb.int.toradex.com/
+Signed-off-by: Nishanth Menon <nm@ti.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/ti_sci.c | 36 ++----------------------------------
+ 1 file changed, 2 insertions(+), 34 deletions(-)
+
+diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
+index 039d92a595ec6..91aaa0ca9bde8 100644
+--- a/drivers/firmware/ti_sci.c
++++ b/drivers/firmware/ti_sci.c
+@@ -97,7 +97,6 @@ struct ti_sci_desc {
+ * @node: list head
+ * @host_id: Host ID
+ * @users: Number of users of this instance
+- * @is_suspending: Flag set to indicate in suspend path.
+ */
+ struct ti_sci_info {
+ struct device *dev;
+@@ -116,7 +115,6 @@ struct ti_sci_info {
+ u8 host_id;
+ /* protected by ti_sci_list_mutex */
+ int users;
+- bool is_suspending;
+ };
+
+ #define cl_to_ti_sci_info(c) container_of(c, struct ti_sci_info, cl)
+@@ -418,14 +416,14 @@ static inline int ti_sci_do_xfer(struct ti_sci_info *info,
+
+ ret = 0;
+
+- if (!info->is_suspending) {
++ if (system_state <= SYSTEM_RUNNING) {
+ /* And we wait for the response. */
+ timeout = msecs_to_jiffies(info->desc->max_rx_timeout_ms);
+ if (!wait_for_completion_timeout(&xfer->done, timeout))
+ ret = -ETIMEDOUT;
+ } else {
+ /*
+- * If we are suspending, we cannot use wait_for_completion_timeout
++ * If we are !running, we cannot use wait_for_completion_timeout
+ * during noirq phase, so we must manually poll the completion.
+ */
+ ret = read_poll_timeout_atomic(try_wait_for_completion, done_state,
+@@ -3281,35 +3279,6 @@ static int tisci_reboot_handler(struct notifier_block *nb, unsigned long mode,
+ return NOTIFY_BAD;
+ }
+
+-static void ti_sci_set_is_suspending(struct ti_sci_info *info, bool is_suspending)
+-{
+- info->is_suspending = is_suspending;
+-}
+-
+-static int ti_sci_suspend(struct device *dev)
+-{
+- struct ti_sci_info *info = dev_get_drvdata(dev);
+- /*
+- * We must switch operation to polled mode now as drivers and the genpd
+- * layer may make late TI SCI calls to change clock and device states
+- * from the noirq phase of suspend.
+- */
+- ti_sci_set_is_suspending(info, true);
+-
+- return 0;
+-}
+-
+-static int ti_sci_resume(struct device *dev)
+-{
+- struct ti_sci_info *info = dev_get_drvdata(dev);
+-
+- ti_sci_set_is_suspending(info, false);
+-
+- return 0;
+-}
+-
+-static DEFINE_SIMPLE_DEV_PM_OPS(ti_sci_pm_ops, ti_sci_suspend, ti_sci_resume);
+-
+ /* Description for K2G */
+ static const struct ti_sci_desc ti_sci_pmmc_k2g_desc = {
+ .default_host_id = 2,
+@@ -3516,7 +3485,6 @@ static struct platform_driver ti_sci_driver = {
+ .driver = {
+ .name = "ti-sci",
+ .of_match_table = of_match_ptr(ti_sci_of_match),
+- .pm = &ti_sci_pm_ops,
+ },
+ };
+ module_platform_driver(ti_sci_driver);
+--
+2.40.1
+
--- /dev/null
+From 6746736753ac97e2acde5f4e25fadb7e81208d3f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Jul 2023 20:05:42 +0800
+Subject: fs: Fix error checking for d_hash_and_lookup()
+
+From: Wang Ming <machel@vivo.com>
+
+[ Upstream commit 0d5a4f8f775ff990142cdc810a84eae078589d27 ]
+
+The d_hash_and_lookup() function returns error pointers or NULL.
+Most incorrect error checks were fixed, but the one in int path_pts()
+was forgotten.
+
+Fixes: eedf265aa003 ("devpts: Make each mount of devpts an independent filesystem.")
+Signed-off-by: Wang Ming <machel@vivo.com>
+Message-Id: <20230713120555.7025-1-machel@vivo.com>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/namei.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/namei.c b/fs/namei.c
+index 7e5cb92feab3f..e18c8c9f1d9c6 100644
+--- a/fs/namei.c
++++ b/fs/namei.c
+@@ -2890,7 +2890,7 @@ int path_pts(struct path *path)
+ dput(path->dentry);
+ path->dentry = parent;
+ child = d_hash_and_lookup(parent, &this);
+- if (!child)
++ if (IS_ERR_OR_NULL(child))
+ return -ENOENT;
+
+ path->dentry = child;
+--
+2.40.1
+
--- /dev/null
+From 2a3caa2e5523577cee6fb6df49c4f7025727c788 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Aug 2023 09:26:57 +0800
+Subject: fs: lockd: avoid possible wrong NULL parameter
+
+From: Su Hui <suhui@nfschina.com>
+
+[ Upstream commit de8d38cf44bac43e83bad28357ba84784c412752 ]
+
+clang's static analysis warning: fs/lockd/mon.c: line 293, column 2:
+Null pointer passed as 2nd argument to memory copy function.
+
+Assuming 'hostname' is NULL and calling 'nsm_create_handle()', this will
+pass NULL as 2nd argument to memory copy function 'memcpy()'. So return
+NULL if 'hostname' is invalid.
+
+Fixes: 77a3ef33e2de ("NSM: More clean up of nsm_get_handle()")
+Signed-off-by: Su Hui <suhui@nfschina.com>
+Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/lockd/mon.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
+index 1d9488cf05348..87a0f207df0b9 100644
+--- a/fs/lockd/mon.c
++++ b/fs/lockd/mon.c
+@@ -276,6 +276,9 @@ static struct nsm_handle *nsm_create_handle(const struct sockaddr *sap,
+ {
+ struct nsm_handle *new;
+
++ if (!hostname)
++ return NULL;
++
+ new = kzalloc(sizeof(*new) + hostname_len + 1, GFP_KERNEL);
+ if (unlikely(new == NULL))
+ return NULL;
+--
+2.40.1
+
--- /dev/null
+From 968f14a418cbd35d920a442bd4541511454769ce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Aug 2023 17:54:17 +0300
+Subject: fs: ocfs2: namei: check return value of ocfs2_add_entry()
+
+From: Artem Chernyshev <artem.chernyshev@red-soft.ru>
+
+[ Upstream commit 6b72e5f9e79360fce4f2be7fe81159fbdf4256a5 ]
+
+Process result of ocfs2_add_entry() in case we have an error
+value.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Link: https://lkml.kernel.org/r/20230803145417.177649-1-artem.chernyshev@red-soft.ru
+Fixes: ccd979bdbce9 ("[PATCH] OCFS2: The Second Oracle Cluster Filesystem")
+Signed-off-by: Artem Chernyshev <artem.chernyshev@red-soft.ru>
+Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
+Cc: Artem Chernyshev <artem.chernyshev@red-soft.ru>
+Cc: Joel Becker <jlbec@evilplan.org>
+Cc: Kurt Hackel <kurt.hackel@oracle.com>
+Cc: Mark Fasheh <mark@fasheh.com>
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Changwei Ge <gechangwei@live.cn>
+Cc: Gang He <ghe@suse.com>
+Cc: Jun Piao <piaojun@huawei.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ocfs2/namei.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
+index 17c52225b87d4..03bccfd183f3c 100644
+--- a/fs/ocfs2/namei.c
++++ b/fs/ocfs2/namei.c
+@@ -1535,6 +1535,10 @@ static int ocfs2_rename(struct mnt_idmap *idmap,
+ status = ocfs2_add_entry(handle, new_dentry, old_inode,
+ OCFS2_I(old_inode)->ip_blkno,
+ new_dir_bh, &target_insert);
++ if (status < 0) {
++ mlog_errno(status);
++ goto bail;
++ }
+ }
+
+ old_inode->i_ctime = current_time(old_inode);
+--
+2.40.1
+
--- /dev/null
+From b98f57d0ecae1030f8486de41b97327b4e9c8758 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 Jun 2023 14:56:50 -0500
+Subject: fsi: aspeed: Reset master errors after CFAM reset
+
+From: Eddie James <eajames@linux.ibm.com>
+
+[ Upstream commit 52300909f4670ac552bfeb33c1355b896eac8c06 ]
+
+It has been observed that sometimes the FSI master will return all 0xffs
+after a CFAM has been taken out of reset, without presenting any error.
+Resetting the FSI master errors resolves the issue.
+
+Fixes: 4a851d714ead ("fsi: aspeed: Support CFAM reset GPIO")
+Signed-off-by: Eddie James <eajames@linux.ibm.com>
+Link: https://lore.kernel.org/r/20230612195657.245125-8-eajames@linux.ibm.com
+Signed-off-by: Joel Stanley <joel@jms.id.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/fsi/fsi-master-aspeed.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/fsi/fsi-master-aspeed.c b/drivers/fsi/fsi-master-aspeed.c
+index 7cec1772820d3..5eccab175e86b 100644
+--- a/drivers/fsi/fsi-master-aspeed.c
++++ b/drivers/fsi/fsi-master-aspeed.c
+@@ -454,6 +454,8 @@ static ssize_t cfam_reset_store(struct device *dev, struct device_attribute *att
+ gpiod_set_value(aspeed->cfam_reset_gpio, 1);
+ usleep_range(900, 1000);
+ gpiod_set_value(aspeed->cfam_reset_gpio, 0);
++ usleep_range(900, 1000);
++ opb_writel(aspeed, ctrl_base + FSI_MRESP0, cpu_to_be32(FSI_MRESP_RST_ALL_MASTER));
+ mutex_unlock(&aspeed->lock);
+ trace_fsi_master_aspeed_cfam_reset(false);
+
+--
+2.40.1
+
--- /dev/null
+From fe85fd48c6bebcf692aa34af0945959edeaa053c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Jun 2023 17:26:00 +0200
+Subject: HID: input: Support devices sending Eraser without Invert
+
+From: Illia Ostapyshyn <ostapyshyn@sra.uni-hannover.de>
+
+[ Upstream commit 276e14e6c3993317257e1787e93b7166fbc30905 ]
+
+Some digitizers (notably XP-Pen Artist 24) do not report the Invert
+usage when erasing. This causes the device to be permanently stuck with
+the BTN_TOOL_RUBBER tool after sending Eraser, as Invert is the only
+usage that can release the tool. In this state, Touch and Inrange are
+no longer reported to userspace, rendering the pen unusable.
+
+Prior to commit 87562fcd1342 ("HID: input: remove the need for
+HID_QUIRK_INVERT"), BTN_TOOL_RUBBER was never set and Eraser events were
+simply translated into BTN_TOUCH without causing an inconsistent state.
+
+Introduce HID_QUIRK_NOINVERT for such digitizers and detect them during
+hidinput_configure_usage(). This quirk causes the tool to be released
+as soon as Eraser is reported as not set. Set BTN_TOOL_RUBBER in
+input->keybit when mapping Eraser.
+
+Fixes: 87562fcd1342 ("HID: input: remove the need for HID_QUIRK_INVERT")
+Co-developed-by: Nils Fuhler <nils@nilsfuhler.de>
+Signed-off-by: Nils Fuhler <nils@nilsfuhler.de>
+Signed-off-by: Illia Ostapyshyn <ostapyshyn@sra.uni-hannover.de>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-input.c | 18 ++++++++++++++++--
+ include/linux/hid.h | 1 +
+ 2 files changed, 17 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
+index 851ee86eff32a..40a5645f8fe81 100644
+--- a/drivers/hid/hid-input.c
++++ b/drivers/hid/hid-input.c
+@@ -988,6 +988,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
+ return;
+
+ case 0x3c: /* Invert */
++ device->quirks &= ~HID_QUIRK_NOINVERT;
+ map_key_clear(BTN_TOOL_RUBBER);
+ break;
+
+@@ -1013,9 +1014,13 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
+ case 0x45: /* ERASER */
+ /*
+ * This event is reported when eraser tip touches the surface.
+- * Actual eraser (BTN_TOOL_RUBBER) is set by Invert usage when
+- * tool gets in proximity.
++ * Actual eraser (BTN_TOOL_RUBBER) is set and released either
++ * by Invert if tool reports proximity or by Eraser directly.
+ */
++ if (!test_bit(BTN_TOOL_RUBBER, input->keybit)) {
++ device->quirks |= HID_QUIRK_NOINVERT;
++ set_bit(BTN_TOOL_RUBBER, input->keybit);
++ }
+ map_key_clear(BTN_TOUCH);
+ break;
+
+@@ -1580,6 +1585,15 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
+ else if (report->tool != BTN_TOOL_RUBBER)
+ /* value is off, tool is not rubber, ignore */
+ return;
++ else if (*quirks & HID_QUIRK_NOINVERT &&
++ !test_bit(BTN_TOUCH, input->key)) {
++ /*
++ * There is no invert to release the tool, let hid_input
++ * send BTN_TOUCH with scancode and release the tool after.
++ */
++ hid_report_release_tool(report, input, BTN_TOOL_RUBBER);
++ return;
++ }
+
+ /* let hid-input set BTN_TOUCH */
+ break;
+diff --git a/include/linux/hid.h b/include/linux/hid.h
+index 4e4c4fe369118..7cbc10073a1fe 100644
+--- a/include/linux/hid.h
++++ b/include/linux/hid.h
+@@ -360,6 +360,7 @@ struct hid_item {
+ #define HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP BIT(18)
+ #define HID_QUIRK_HAVE_SPECIAL_DRIVER BIT(19)
+ #define HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE BIT(20)
++#define HID_QUIRK_NOINVERT BIT(21)
+ #define HID_QUIRK_FULLSPEED_INTERVAL BIT(28)
+ #define HID_QUIRK_NO_INIT_REPORTS BIT(29)
+ #define HID_QUIRK_NO_IGNORE BIT(30)
+--
+2.40.1
+
--- /dev/null
+From 3822091e0faaf0893874499ba636f60bda297366 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Jun 2023 03:16:35 -0700
+Subject: HID: logitech-dj: Fix error handling in
+ logi_dj_recv_switch_to_dj_mode()
+
+From: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
+
+[ Upstream commit 6f20d3261265885f6a6be4cda49d7019728760e0 ]
+
+Presently, if a call to logi_dj_recv_send_report() fails, we do
+not learn about the error until after sending short
+HID_OUTPUT_REPORT with hid_hw_raw_request().
+To handle this somewhat unlikely issue, return on error in
+logi_dj_recv_send_report() (minding ugly sleep workaround) and
+take into account the result of hid_hw_raw_request().
+
+Found by Linux Verification Center (linuxtesting.org) with static
+analysis tool SVACE.
+
+Fixes: 6a9ddc897883 ("HID: logitech-dj: enable notifications on connect/disconnect")
+Signed-off-by: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
+Link: https://lore.kernel.org/r/20230613101635.77820-1-n.zhandarovich@fintech.ru
+Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-logitech-dj.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
+index 62180414efccd..e6a8b6d8eab70 100644
+--- a/drivers/hid/hid-logitech-dj.c
++++ b/drivers/hid/hid-logitech-dj.c
+@@ -1285,6 +1285,9 @@ static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev,
+ * 50 msec should gives enough time to the receiver to be ready.
+ */
+ msleep(50);
++
++ if (retval)
++ return retval;
+ }
+
+ /*
+@@ -1306,7 +1309,7 @@ static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev,
+ buf[5] = 0x09;
+ buf[6] = 0x00;
+
+- hid_hw_raw_request(hdev, REPORT_ID_HIDPP_SHORT, buf,
++ retval = hid_hw_raw_request(hdev, REPORT_ID_HIDPP_SHORT, buf,
+ HIDPP_REPORT_SHORT_LENGTH, HID_OUTPUT_REPORT,
+ HID_REQ_SET_REPORT);
+
+--
+2.40.1
+
--- /dev/null
+From ad5909189a22ac695996ca8b1888ba316756698f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Aug 2023 06:14:33 +0000
+Subject: HID: multitouch: Correct devm device reference for hidinput input_dev
+ name
+
+From: Rahul Rameshbabu <sergeantsagara@protonmail.com>
+
+[ Upstream commit 4794394635293a3e74591351fff469cea7ad15a2 ]
+
+Reference the HID device rather than the input device for the devm
+allocation of the input_dev name. Referencing the input_dev would lead to a
+use-after-free when the input_dev was unregistered and subsequently fires a
+uevent that depends on the name. At the point of firing the uevent, the
+name would be freed by devres management.
+
+Use devm_kasprintf to simplify the logic for allocating memory and
+formatting the input_dev name string.
+
+Reported-by: Maxime Ripard <mripard@kernel.org>
+Closes: https://lore.kernel.org/linux-input/ZOZIZCND+L0P1wJc@penguin/T/#m443f3dce92520f74b6cf6ffa8653f9c92643d4ae
+Fixes: c08d46aa805b ("HID: multitouch: devm conversion")
+Suggested-by: Maxime Ripard <mripard@kernel.org>
+Suggested-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Rahul Rameshbabu <sergeantsagara@protonmail.com>
+Reviewed-by: Maxime Ripard <mripard@kernel.org>
+Link: https://lore.kernel.org/r/20230824061308.222021-3-sergeantsagara@protonmail.com
+Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-multitouch.c | 13 +++----------
+ 1 file changed, 3 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
+index e31be0cb8b850..521b2ffb42449 100644
+--- a/drivers/hid/hid-multitouch.c
++++ b/drivers/hid/hid-multitouch.c
+@@ -1594,7 +1594,6 @@ static void mt_post_parse(struct mt_device *td, struct mt_application *app)
+ static int mt_input_configured(struct hid_device *hdev, struct hid_input *hi)
+ {
+ struct mt_device *td = hid_get_drvdata(hdev);
+- char *name;
+ const char *suffix = NULL;
+ struct mt_report_data *rdata;
+ struct mt_application *mt_application = NULL;
+@@ -1645,15 +1644,9 @@ static int mt_input_configured(struct hid_device *hdev, struct hid_input *hi)
+ break;
+ }
+
+- if (suffix) {
+- name = devm_kzalloc(&hi->input->dev,
+- strlen(hdev->name) + strlen(suffix) + 2,
+- GFP_KERNEL);
+- if (name) {
+- sprintf(name, "%s %s", hdev->name, suffix);
+- hi->input->name = name;
+- }
+- }
++ if (suffix)
++ hi->input->name = devm_kasprintf(&hdev->dev, GFP_KERNEL,
++ "%s %s", hdev->name, suffix);
+
+ return 0;
+ }
+--
+2.40.1
+
--- /dev/null
+From 4b7866c44865b0173c0e896e26c805c9c3f8ec02 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Aug 2023 06:14:17 +0000
+Subject: HID: uclogic: Correct devm device reference for hidinput input_dev
+ name
+
+From: Rahul Rameshbabu <sergeantsagara@protonmail.com>
+
+[ Upstream commit dd613a4e45f8d35f49a63a2064e5308fa5619e29 ]
+
+Reference the HID device rather than the input device for the devm
+allocation of the input_dev name. Referencing the input_dev would lead to a
+use-after-free when the input_dev was unregistered and subsequently fires a
+uevent that depends on the name. At the point of firing the uevent, the
+name would be freed by devres management.
+
+Use devm_kasprintf to simplify the logic for allocating memory and
+formatting the input_dev name string.
+
+Reported-by: syzbot+3a0ebe8a52b89c63739d@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/linux-input/ZOZIZCND+L0P1wJc@penguin/T/
+Reported-by: Maxime Ripard <mripard@kernel.org>
+Closes: https://lore.kernel.org/linux-input/ZOZIZCND+L0P1wJc@penguin/T/#m443f3dce92520f74b6cf6ffa8653f9c92643d4ae
+Fixes: cce2dbdf258e ("HID: uclogic: name the input nodes based on their tool")
+Suggested-by: Maxime Ripard <mripard@kernel.org>
+Suggested-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Rahul Rameshbabu <sergeantsagara@protonmail.com>
+Reviewed-by: Maxime Ripard <mripard@kernel.org>
+Link: https://lore.kernel.org/r/20230824061308.222021-2-sergeantsagara@protonmail.com
+Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-uclogic-core.c | 13 +++----------
+ 1 file changed, 3 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/hid/hid-uclogic-core.c b/drivers/hid/hid-uclogic-core.c
+index f67835f9ed4cc..ad74cbc9a0aa5 100644
+--- a/drivers/hid/hid-uclogic-core.c
++++ b/drivers/hid/hid-uclogic-core.c
+@@ -85,10 +85,8 @@ static int uclogic_input_configured(struct hid_device *hdev,
+ {
+ struct uclogic_drvdata *drvdata = hid_get_drvdata(hdev);
+ struct uclogic_params *params = &drvdata->params;
+- char *name;
+ const char *suffix = NULL;
+ struct hid_field *field;
+- size_t len;
+ size_t i;
+ const struct uclogic_params_frame *frame;
+
+@@ -146,14 +144,9 @@ static int uclogic_input_configured(struct hid_device *hdev,
+ }
+ }
+
+- if (suffix) {
+- len = strlen(hdev->name) + 2 + strlen(suffix);
+- name = devm_kzalloc(&hi->input->dev, len, GFP_KERNEL);
+- if (name) {
+- snprintf(name, len, "%s %s", hdev->name, suffix);
+- hi->input->name = name;
+- }
+- }
++ if (suffix)
++ hi->input->name = devm_kasprintf(&hdev->dev, GFP_KERNEL,
++ "%s %s", hdev->name, suffix);
+
+ return 0;
+ }
+--
+2.40.1
+
--- /dev/null
+From 803e508d125c7c849efdbc52e8972055aeb147b6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Aug 2023 21:44:54 +0100
+Subject: hwmon: (tmp513) Fix the channel number in tmp51x_is_visible()
+
+From: Biju Das <biju.das.jz@bp.renesas.com>
+
+[ Upstream commit d103337e38e7e64c3d915029e947b1cb0b512737 ]
+
+The supported channels for this driver are {0..3}. Fix the incorrect
+channel in tmp51x_is_visible().
+
+Reported-by: Guenter Roeck <linux@roeck-us.net>
+Closes: https://lore.kernel.org/all/ea0eccc0-a29f-41e4-9049-a1a13f8b16f1@roeck-us.net/
+Fixes: 59dfa75e5d82 ("hwmon: Add driver for Texas Instruments TMP512/513 sensor chips.")
+Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
+Link: https://lore.kernel.org/r/20230824204456.401580-2-biju.das.jz@bp.renesas.com
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/tmp513.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/hwmon/tmp513.c b/drivers/hwmon/tmp513.c
+index 0693eaee054ff..a8167a48f824c 100644
+--- a/drivers/hwmon/tmp513.c
++++ b/drivers/hwmon/tmp513.c
+@@ -434,7 +434,7 @@ static umode_t tmp51x_is_visible(const void *_data,
+
+ switch (type) {
+ case hwmon_temp:
+- if (data->id == tmp512 && channel == 4)
++ if (data->id == tmp512 && channel == 3)
+ return 0;
+ switch (attr) {
+ case hwmon_temp_input:
+--
+2.40.1
+
--- /dev/null
+From 1da5e461a4959e1ace5a41d30557cd2cbe5c1769 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Aug 2023 12:22:08 -0700
+Subject: hwrng: iproc-rng200 - Implement suspend and resume calls
+
+From: Florian Fainelli <florian.fainelli@broadcom.com>
+
+[ Upstream commit 8e03dd62e5be811efbf0cbeba47e79e793519105 ]
+
+Chips such as BCM7278 support system wide suspend/resume which will
+cause the HWRNG block to lose its state and reset to its power on reset
+register values. We need to cleanup and re-initialize the HWRNG for it
+to be functional coming out of a system suspend cycle.
+
+Fixes: c3577f6100ca ("hwrng: iproc-rng200 - Add support for BCM7278")
+Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/char/hw_random/iproc-rng200.c | 25 +++++++++++++++++++++++++
+ 1 file changed, 25 insertions(+)
+
+diff --git a/drivers/char/hw_random/iproc-rng200.c b/drivers/char/hw_random/iproc-rng200.c
+index 06bc060534d81..c0df053cbe4b2 100644
+--- a/drivers/char/hw_random/iproc-rng200.c
++++ b/drivers/char/hw_random/iproc-rng200.c
+@@ -182,6 +182,8 @@ static int iproc_rng200_probe(struct platform_device *pdev)
+ return PTR_ERR(priv->base);
+ }
+
++ dev_set_drvdata(dev, priv);
++
+ priv->rng.name = "iproc-rng200";
+ priv->rng.read = iproc_rng200_read;
+ priv->rng.init = iproc_rng200_init;
+@@ -199,6 +201,28 @@ static int iproc_rng200_probe(struct platform_device *pdev)
+ return 0;
+ }
+
++static int __maybe_unused iproc_rng200_suspend(struct device *dev)
++{
++ struct iproc_rng200_dev *priv = dev_get_drvdata(dev);
++
++ iproc_rng200_cleanup(&priv->rng);
++
++ return 0;
++}
++
++static int __maybe_unused iproc_rng200_resume(struct device *dev)
++{
++ struct iproc_rng200_dev *priv = dev_get_drvdata(dev);
++
++ iproc_rng200_init(&priv->rng);
++
++ return 0;
++}
++
++static const struct dev_pm_ops iproc_rng200_pm_ops = {
++ SET_SYSTEM_SLEEP_PM_OPS(iproc_rng200_suspend, iproc_rng200_resume)
++};
++
+ static const struct of_device_id iproc_rng200_of_match[] = {
+ { .compatible = "brcm,bcm2711-rng200", },
+ { .compatible = "brcm,bcm7211-rng200", },
+@@ -212,6 +236,7 @@ static struct platform_driver iproc_rng200_driver = {
+ .driver = {
+ .name = "iproc-rng200",
+ .of_match_table = iproc_rng200_of_match,
++ .pm = &iproc_rng200_pm_ops,
+ },
+ .probe = iproc_rng200_probe,
+ };
+--
+2.40.1
+
--- /dev/null
+From 60653123aca8f27ada4956b28b20b45815ee871b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 2 Jul 2023 19:35:02 +0200
+Subject: hwrng: nomadik - keep clock enabled while hwrng is registered
+
+From: Martin Kaiser <martin@kaiser.cx>
+
+[ Upstream commit 039980de89dc9dd757418d6f296e4126cc3f86c3 ]
+
+The nomadik driver uses devres to register itself with the hwrng core,
+the driver will be unregistered from hwrng when its device goes out of
+scope. This happens after the driver's remove function is called.
+
+However, nomadik's clock is disabled in the remove function. There's a
+short timeframe where nomadik is still registered with the hwrng core
+although its clock is disabled. I suppose the clock must be active to
+access the hardware and serve requests from the hwrng core.
+
+Switch to devm_clk_get_enabled and let devres disable the clock and
+unregister the hwrng. This avoids the race condition.
+
+Fixes: 3e75241be808 ("hwrng: drivers - Use device-managed registration API")
+Signed-off-by: Martin Kaiser <martin@kaiser.cx>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/char/hw_random/nomadik-rng.c | 12 +++---------
+ 1 file changed, 3 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/char/hw_random/nomadik-rng.c b/drivers/char/hw_random/nomadik-rng.c
+index e8f9621e79541..3774adf903a83 100644
+--- a/drivers/char/hw_random/nomadik-rng.c
++++ b/drivers/char/hw_random/nomadik-rng.c
+@@ -13,8 +13,6 @@
+ #include <linux/clk.h>
+ #include <linux/err.h>
+
+-static struct clk *rng_clk;
+-
+ static int nmk_rng_read(struct hwrng *rng, void *data, size_t max, bool wait)
+ {
+ void __iomem *base = (void __iomem *)rng->priv;
+@@ -36,21 +34,20 @@ static struct hwrng nmk_rng = {
+
+ static int nmk_rng_probe(struct amba_device *dev, const struct amba_id *id)
+ {
++ struct clk *rng_clk;
+ void __iomem *base;
+ int ret;
+
+- rng_clk = devm_clk_get(&dev->dev, NULL);
++ rng_clk = devm_clk_get_enabled(&dev->dev, NULL);
+ if (IS_ERR(rng_clk)) {
+ dev_err(&dev->dev, "could not get rng clock\n");
+ ret = PTR_ERR(rng_clk);
+ return ret;
+ }
+
+- clk_prepare_enable(rng_clk);
+-
+ ret = amba_request_regions(dev, dev->dev.init_name);
+ if (ret)
+- goto out_clk;
++ return ret;
+ ret = -ENOMEM;
+ base = devm_ioremap(&dev->dev, dev->res.start,
+ resource_size(&dev->res));
+@@ -64,15 +61,12 @@ static int nmk_rng_probe(struct amba_device *dev, const struct amba_id *id)
+
+ out_release:
+ amba_release_regions(dev);
+-out_clk:
+- clk_disable_unprepare(rng_clk);
+ return ret;
+ }
+
+ static void nmk_rng_remove(struct amba_device *dev)
+ {
+ amba_release_regions(dev);
+- clk_disable_unprepare(rng_clk);
+ }
+
+ static const struct amba_id nmk_rng_ids[] = {
+--
+2.40.1
+
--- /dev/null
+From 33cf6f83e90a216321cb2c7e67c7871635c503d0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Jul 2023 19:32:01 +0200
+Subject: hwrng: pic32 - use devm_clk_get_enabled
+
+From: Martin Kaiser <martin@kaiser.cx>
+
+[ Upstream commit 6755ad74aac0fb1c79b14724feb81b2f6ff25847 ]
+
+Use devm_clk_get_enabled in the pic32 driver. Ensure that the clock is
+enabled as long as the driver is registered with the hwrng core.
+
+Fixes: 7ea39973d1e5 ("hwrng: pic32 - Use device-managed registration API")
+Signed-off-by: Martin Kaiser <martin@kaiser.cx>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/char/hw_random/pic32-rng.c | 19 +++++--------------
+ 1 file changed, 5 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/char/hw_random/pic32-rng.c b/drivers/char/hw_random/pic32-rng.c
+index 99c8bd0859a14..e04a054e89307 100644
+--- a/drivers/char/hw_random/pic32-rng.c
++++ b/drivers/char/hw_random/pic32-rng.c
+@@ -36,7 +36,6 @@
+ struct pic32_rng {
+ void __iomem *base;
+ struct hwrng rng;
+- struct clk *clk;
+ };
+
+ /*
+@@ -70,6 +69,7 @@ static int pic32_rng_read(struct hwrng *rng, void *buf, size_t max,
+ static int pic32_rng_probe(struct platform_device *pdev)
+ {
+ struct pic32_rng *priv;
++ struct clk *clk;
+ u32 v;
+ int ret;
+
+@@ -81,13 +81,9 @@ static int pic32_rng_probe(struct platform_device *pdev)
+ if (IS_ERR(priv->base))
+ return PTR_ERR(priv->base);
+
+- priv->clk = devm_clk_get(&pdev->dev, NULL);
+- if (IS_ERR(priv->clk))
+- return PTR_ERR(priv->clk);
+-
+- ret = clk_prepare_enable(priv->clk);
+- if (ret)
+- return ret;
++ clk = devm_clk_get_enabled(&pdev->dev, NULL);
++ if (IS_ERR(clk))
++ return PTR_ERR(clk);
+
+ /* enable TRNG in enhanced mode */
+ v = TRNGEN | TRNGMOD;
+@@ -98,15 +94,11 @@ static int pic32_rng_probe(struct platform_device *pdev)
+
+ ret = devm_hwrng_register(&pdev->dev, &priv->rng);
+ if (ret)
+- goto err_register;
++ return ret;
+
+ platform_set_drvdata(pdev, priv);
+
+ return 0;
+-
+-err_register:
+- clk_disable_unprepare(priv->clk);
+- return ret;
+ }
+
+ static int pic32_rng_remove(struct platform_device *pdev)
+@@ -114,7 +106,6 @@ static int pic32_rng_remove(struct platform_device *pdev)
+ struct pic32_rng *rng = platform_get_drvdata(pdev);
+
+ writel(0, rng->base + RNGCON);
+- clk_disable_unprepare(rng->clk);
+ return 0;
+ }
+
+--
+2.40.1
+
--- /dev/null
+From 963e2ecd362725ae09b7c85cd372151f927b67b9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Aug 2023 10:25:25 +0800
+Subject: IB/uverbs: Fix an potential error pointer dereference
+
+From: Xiang Yang <xiangyang3@huawei.com>
+
+[ Upstream commit 26b7d1a27167e7adf75b150755e05d2bc123ce55 ]
+
+smatch reports the warning below:
+drivers/infiniband/core/uverbs_std_types_counters.c:110
+ib_uverbs_handler_UVERBS_METHOD_COUNTERS_READ() error: 'uattr'
+dereferencing possible ERR_PTR()
+
+The return value of uattr maybe ERR_PTR(-ENOENT), fix this by checking
+the value of uattr before using it.
+
+Fixes: ebb6796bd397 ("IB/uverbs: Add read counters support")
+Signed-off-by: Xiang Yang <xiangyang3@huawei.com>
+Link: https://lore.kernel.org/r/20230804022525.1916766-1-xiangyang3@huawei.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/uverbs_std_types_counters.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/infiniband/core/uverbs_std_types_counters.c b/drivers/infiniband/core/uverbs_std_types_counters.c
+index 999da9c798668..381aa57976417 100644
+--- a/drivers/infiniband/core/uverbs_std_types_counters.c
++++ b/drivers/infiniband/core/uverbs_std_types_counters.c
+@@ -107,6 +107,8 @@ static int UVERBS_HANDLER(UVERBS_METHOD_COUNTERS_READ)(
+ return ret;
+
+ uattr = uverbs_attr_get(attrs, UVERBS_ATTR_READ_COUNTERS_BUFF);
++ if (IS_ERR(uattr))
++ return PTR_ERR(uattr);
+ read_attr.ncounters = uattr->ptr_attr.len / sizeof(u64);
+ read_attr.counters_buff = uverbs_zalloc(
+ attrs, array_size(read_attr.ncounters, sizeof(u64)));
+--
+2.40.1
+
--- /dev/null
+From 63b4dcd72a32651474e0d2483abdbfa7df659386 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Aug 2023 08:18:14 -0700
+Subject: ice: avoid executing commands on other ports when driving sync
+
+From: Jacob Keller <jacob.e.keller@intel.com>
+
+[ Upstream commit 0aacec49c29e7c5b1487e859b0c0a42388c34092 ]
+
+The ice hardware has a synchronization mechanism used to drive the
+simultaneous application of commands on both PHY ports and the source timer
+in the MAC.
+
+When issuing a sync via ice_ptp_exec_tmr_cmd(), the hardware will
+simultaneously apply the commands programmed for the main timer and each
+PHY port. Neither the main timer command register, nor the PHY port command
+registers auto clear on command execution.
+
+During the execution of a timer command intended for a single port on E822
+devices, such as those used to configure a PHY during link up, the driver
+is not correctly clearing the previous commands.
+
+This results in unintentionally executing the last programmed command on
+the main timer and other PHY ports whenever performing reconfiguration on
+E822 ports after link up. This results in unintended side effects on other
+timers, depending on what command was previously programmed.
+
+To fix this, the driver must ensure that the main timer and all other PHY
+ports are properly initialized to perform no action.
+
+The enumeration for timer commands does not include an enumeration value
+for doing nothing. Introduce ICE_PTP_NOP for this purpose. When writing a
+timer command to hardware, leave the command bits set to zero which
+indicates that no operation should be performed on that port.
+
+Modify ice_ptp_one_port_cmd() to always initialize all ports. For all ports
+other than the one being configured, write their timer command register to
+ICE_PTP_NOP. This ensures that no side effect happens on the timer command.
+
+To fix this for the PHY ports, modify ice_ptp_one_port_cmd() to always
+initialize all other ports to ICE_PTP_NOP. This ensures that no side
+effects happen on the other ports.
+
+Call ice_ptp_src_cmd() with a command value if ICE_PTP_NOP in
+ice_sync_phy_timer_e822() and ice_start_phy_timer_e822().
+
+With both of these changes, the driver should no longer execute a stale
+command on the main timer or another PHY port when reconfiguring one of the
+PHY ports after link up.
+
+Fixes: 3a7496234d17 ("ice: implement basic E822 PTP support")
+Signed-off-by: Siddaraju DH <siddaraju.dh@intel.com>
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Tested-by: Sunitha Mekala <sunithax.d.mekala@intel.com> (A Contingent worker at Intel)
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 55 +++++++++++++++++++--
+ drivers/net/ethernet/intel/ice/ice_ptp_hw.h | 3 +-
+ 2 files changed, 52 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
+index a38614d21ea8f..de1d83300481d 100644
+--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
++++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
+@@ -131,6 +131,8 @@ static void ice_ptp_src_cmd(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd)
+ case READ_TIME:
+ cmd_val |= GLTSYN_CMD_READ_TIME;
+ break;
++ case ICE_PTP_NOP:
++ break;
+ }
+
+ wr32(hw, GLTSYN_CMD, cmd_val);
+@@ -1226,18 +1228,18 @@ ice_ptp_read_port_capture(struct ice_hw *hw, u8 port, u64 *tx_ts, u64 *rx_ts)
+ }
+
+ /**
+- * ice_ptp_one_port_cmd - Prepare a single PHY port for a timer command
++ * ice_ptp_write_port_cmd_e822 - Prepare a single PHY port for a timer command
+ * @hw: pointer to HW struct
+ * @port: Port to which cmd has to be sent
+ * @cmd: Command to be sent to the port
+ *
+ * Prepare the requested port for an upcoming timer sync command.
+ *
+- * Note there is no equivalent of this operation on E810, as that device
+- * always handles all external PHYs internally.
++ * Do not use this function directly. If you want to configure exactly one
++ * port, use ice_ptp_one_port_cmd() instead.
+ */
+ static int
+-ice_ptp_one_port_cmd(struct ice_hw *hw, u8 port, enum ice_ptp_tmr_cmd cmd)
++ice_ptp_write_port_cmd_e822(struct ice_hw *hw, u8 port, enum ice_ptp_tmr_cmd cmd)
+ {
+ u32 cmd_val, val;
+ u8 tmr_idx;
+@@ -1261,6 +1263,8 @@ ice_ptp_one_port_cmd(struct ice_hw *hw, u8 port, enum ice_ptp_tmr_cmd cmd)
+ case ADJ_TIME_AT_TIME:
+ cmd_val |= PHY_CMD_ADJ_TIME_AT_TIME;
+ break;
++ case ICE_PTP_NOP:
++ break;
+ }
+
+ /* Tx case */
+@@ -1306,6 +1310,39 @@ ice_ptp_one_port_cmd(struct ice_hw *hw, u8 port, enum ice_ptp_tmr_cmd cmd)
+ return 0;
+ }
+
++/**
++ * ice_ptp_one_port_cmd - Prepare one port for a timer command
++ * @hw: pointer to the HW struct
++ * @configured_port: the port to configure with configured_cmd
++ * @configured_cmd: timer command to prepare on the configured_port
++ *
++ * Prepare the configured_port for the configured_cmd, and prepare all other
++ * ports for ICE_PTP_NOP. This causes the configured_port to execute the
++ * desired command while all other ports perform no operation.
++ */
++static int
++ice_ptp_one_port_cmd(struct ice_hw *hw, u8 configured_port,
++ enum ice_ptp_tmr_cmd configured_cmd)
++{
++ u8 port;
++
++ for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
++ enum ice_ptp_tmr_cmd cmd;
++ int err;
++
++ if (port == configured_port)
++ cmd = configured_cmd;
++ else
++ cmd = ICE_PTP_NOP;
++
++ err = ice_ptp_write_port_cmd_e822(hw, port, cmd);
++ if (err)
++ return err;
++ }
++
++ return 0;
++}
++
+ /**
+ * ice_ptp_port_cmd_e822 - Prepare all ports for a timer command
+ * @hw: pointer to the HW struct
+@@ -1322,7 +1359,7 @@ ice_ptp_port_cmd_e822(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd)
+ for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
+ int err;
+
+- err = ice_ptp_one_port_cmd(hw, port, cmd);
++ err = ice_ptp_write_port_cmd_e822(hw, port, cmd);
+ if (err)
+ return err;
+ }
+@@ -2252,6 +2289,9 @@ static int ice_sync_phy_timer_e822(struct ice_hw *hw, u8 port)
+ if (err)
+ goto err_unlock;
+
++ /* Do not perform any action on the main timer */
++ ice_ptp_src_cmd(hw, ICE_PTP_NOP);
++
+ /* Issue the sync to activate the time adjustment */
+ ice_ptp_exec_tmr_cmd(hw);
+
+@@ -2372,6 +2412,9 @@ int ice_start_phy_timer_e822(struct ice_hw *hw, u8 port)
+ if (err)
+ return err;
+
++ /* Do not perform any action on the main timer */
++ ice_ptp_src_cmd(hw, ICE_PTP_NOP);
++
+ ice_ptp_exec_tmr_cmd(hw);
+
+ err = ice_read_phy_reg_e822(hw, port, P_REG_PS, &val);
+@@ -2847,6 +2890,8 @@ static int ice_ptp_port_cmd_e810(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd)
+ case ADJ_TIME_AT_TIME:
+ cmd_val = GLTSYN_CMD_ADJ_INIT_TIME;
+ break;
++ case ICE_PTP_NOP:
++ return 0;
+ }
+
+ /* Read, modify, write */
+diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
+index 3b68cb91bd819..096685237ca61 100644
+--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
++++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
+@@ -9,7 +9,8 @@ enum ice_ptp_tmr_cmd {
+ INIT_INCVAL,
+ ADJ_TIME,
+ ADJ_TIME_AT_TIME,
+- READ_TIME
++ READ_TIME,
++ ICE_PTP_NOP,
+ };
+
+ enum ice_ptp_serdes {
+--
+2.40.1
+
--- /dev/null
+From 987111e4bd7d44620d3ccf6cf98db46cea91b818 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Aug 2023 17:54:15 -0400
+Subject: ice: ice_aq_check_events: fix off-by-one check when filling buffer
+
+From: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+
+[ Upstream commit e1e8a142c43336e3d25bfa1cb3a4ae7d00875c48 ]
+
+Allow task's event buffer to be filled also in the case that it's size
+is exactly the size of the message.
+
+Fixes: d69ea414c9b4 ("ice: implement device flash update via devlink")
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_main.c | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
+index cfb76612bd2f9..66bd06ea0a703 100644
+--- a/drivers/net/ethernet/intel/ice/ice_main.c
++++ b/drivers/net/ethernet/intel/ice/ice_main.c
+@@ -1346,6 +1346,7 @@ int ice_aq_wait_for_event(struct ice_pf *pf, u16 opcode, unsigned long timeout,
+ static void ice_aq_check_events(struct ice_pf *pf, u16 opcode,
+ struct ice_rq_event_info *event)
+ {
++ struct ice_rq_event_info *task_ev;
+ struct ice_aq_task *task;
+ bool found = false;
+
+@@ -1354,15 +1355,15 @@ static void ice_aq_check_events(struct ice_pf *pf, u16 opcode,
+ if (task->state || task->opcode != opcode)
+ continue;
+
+- memcpy(&task->event->desc, &event->desc, sizeof(event->desc));
+- task->event->msg_len = event->msg_len;
++ task_ev = task->event;
++ memcpy(&task_ev->desc, &event->desc, sizeof(event->desc));
++ task_ev->msg_len = event->msg_len;
+
+ /* Only copy the data buffer if a destination was set */
+- if (task->event->msg_buf &&
+- task->event->buf_len > event->buf_len) {
+- memcpy(task->event->msg_buf, event->msg_buf,
++ if (task_ev->msg_buf && task_ev->buf_len >= event->buf_len) {
++ memcpy(task_ev->msg_buf, event->msg_buf,
+ event->buf_len);
+- task->event->buf_len = event->buf_len;
++ task_ev->buf_len = event->buf_len;
+ }
+
+ task->state = ICE_AQ_TASK_COMPLETE;
+--
+2.40.1
+
--- /dev/null
+From 17f222be404b981c403b3896efb4e43c64896827 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Jul 2023 18:16:23 +0100
+Subject: iio: accel: adxl313: Fix adxl313_i2c_id[] table
+
+From: Biju Das <biju.das.jz@bp.renesas.com>
+
+[ Upstream commit f636554c4cd1c644109cc525900a056495b86cc9 ]
+
+The .driver_data in adxl313_i2c_id[] for adxl312 and adxl314 is
+wrong. Fix this issue by adding corresponding adxl31x_chip_info
+data.
+
+Reported-by: Jonathan Cameron <jic23@kernel.org>
+Closes: https://lore.kernel.org/all/20230722172832.04ad7738@jic23-huawei
+Fixes: a7a1c60bc4c9 ("drivers: iio: accel: adxl312 and adxl314 support")
+Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/20230725171624.331283-2-biju.das.jz@bp.renesas.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/accel/adxl313_i2c.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/accel/adxl313_i2c.c b/drivers/iio/accel/adxl313_i2c.c
+index 99cc7fc294882..68785bd3ef2f0 100644
+--- a/drivers/iio/accel/adxl313_i2c.c
++++ b/drivers/iio/accel/adxl313_i2c.c
+@@ -40,8 +40,8 @@ static const struct regmap_config adxl31x_i2c_regmap_config[] = {
+
+ static const struct i2c_device_id adxl313_i2c_id[] = {
+ { .name = "adxl312", .driver_data = (kernel_ulong_t)&adxl31x_chip_info[ADXL312] },
+- { .name = "adxl313", .driver_data = (kernel_ulong_t)&adxl31x_chip_info[ADXL312] },
+- { .name = "adxl314", .driver_data = (kernel_ulong_t)&adxl31x_chip_info[ADXL312] },
++ { .name = "adxl313", .driver_data = (kernel_ulong_t)&adxl31x_chip_info[ADXL313] },
++ { .name = "adxl314", .driver_data = (kernel_ulong_t)&adxl31x_chip_info[ADXL314] },
+ { }
+ };
+
+--
+2.40.1
+
--- /dev/null
+From bd0f5d1f2cc350bc1436430ce3e176263f064084 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Jul 2023 12:44:47 -0400
+Subject: ima: Remove deprecated IMA_TRUSTED_KEYRING Kconfig
+
+From: Nayna Jain <nayna@linux.ibm.com>
+
+[ Upstream commit 5087fd9e80e539d2163accd045b73da64de7de95 ]
+
+Time to remove "IMA_TRUSTED_KEYRING".
+
+Fixes: f4dc37785e9b ("integrity: define '.evm' as a builtin 'trusted' keyring") # v4.5+
+Signed-off-by: Nayna Jain <nayna@linux.ibm.com>
+Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/integrity/ima/Kconfig | 12 ------------
+ 1 file changed, 12 deletions(-)
+
+diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
+index 60a511c6b583e..c17660bf5f347 100644
+--- a/security/integrity/ima/Kconfig
++++ b/security/integrity/ima/Kconfig
+@@ -248,18 +248,6 @@ config IMA_APPRAISE_MODSIG
+ The modsig keyword can be used in the IMA policy to allow a hook
+ to accept such signatures.
+
+-config IMA_TRUSTED_KEYRING
+- bool "Require all keys on the .ima keyring be signed (deprecated)"
+- depends on IMA_APPRAISE && SYSTEM_TRUSTED_KEYRING
+- depends on INTEGRITY_ASYMMETRIC_KEYS
+- select INTEGRITY_TRUSTED_KEYRING
+- default y
+- help
+- This option requires that all keys added to the .ima
+- keyring be signed by a key on the system trusted keyring.
+-
+- This option is deprecated in favor of INTEGRITY_TRUSTED_KEYRING
+-
+ config IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY
+ bool "Permit keys validly signed by a built-in or secondary CA cert (EXPERIMENTAL)"
+ depends on SYSTEM_TRUSTED_KEYRING
+--
+2.40.1
+
--- /dev/null
+From 8b5afc14cbc5fd149a81f8424c690c85d1019461 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 12 Aug 2023 01:16:15 +0200
+Subject: interconnect: qcom: bcm-voter: Improve enable_mask handling
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit a1f4170dec440f023601d57e49227b784074d218 ]
+
+We don't need all the complex arithmetic for BCMs utilizing enable_mask,
+as all we need to do is to determine whether there's any user (or
+keepalive) asking for it to be on.
+
+Separate the logic for such BCMs for a small speed boost.
+
+Suggested-by: Bjorn Andersson <quic_bjorande@quicinc.com>
+Reviewed-by: Bjorn Andersson <quic_bjorande@quicinc.com>
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230811-topic-icc_fix_1he-v2-1-0620af8ac133@linaro.org
+Signed-off-by: Georgi Djakov <djakov@kernel.org>
+Stable-dep-of: 1a70ca71547b ("interconnect: qcom: bcm-voter: Use enable_maks for keepalive voting")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/interconnect/qcom/bcm-voter.c | 43 ++++++++++++++++++++++-----
+ 1 file changed, 36 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/interconnect/qcom/bcm-voter.c b/drivers/interconnect/qcom/bcm-voter.c
+index d5f2a6b5376bd..d857eb8838b95 100644
+--- a/drivers/interconnect/qcom/bcm-voter.c
++++ b/drivers/interconnect/qcom/bcm-voter.c
+@@ -58,6 +58,36 @@ static u64 bcm_div(u64 num, u32 base)
+ return num;
+ }
+
++/* BCMs with enable_mask use one-hot-encoding for on/off signaling */
++static void bcm_aggregate_mask(struct qcom_icc_bcm *bcm)
++{
++ struct qcom_icc_node *node;
++ int bucket, i;
++
++ for (bucket = 0; bucket < QCOM_ICC_NUM_BUCKETS; bucket++) {
++ bcm->vote_x[bucket] = 0;
++ bcm->vote_y[bucket] = 0;
++
++ for (i = 0; i < bcm->num_nodes; i++) {
++ node = bcm->nodes[i];
++
++ /* If any vote in this bucket exists, keep the BCM enabled */
++ if (node->sum_avg[bucket] || node->max_peak[bucket]) {
++ bcm->vote_x[bucket] = 0;
++ bcm->vote_y[bucket] = bcm->enable_mask;
++ break;
++ }
++ }
++ }
++
++ if (bcm->keepalive) {
++ bcm->vote_x[QCOM_ICC_BUCKET_AMC] = 1;
++ bcm->vote_x[QCOM_ICC_BUCKET_WAKE] = 1;
++ bcm->vote_y[QCOM_ICC_BUCKET_AMC] = 1;
++ bcm->vote_y[QCOM_ICC_BUCKET_WAKE] = 1;
++ }
++}
++
+ static void bcm_aggregate(struct qcom_icc_bcm *bcm)
+ {
+ struct qcom_icc_node *node;
+@@ -83,11 +113,6 @@ static void bcm_aggregate(struct qcom_icc_bcm *bcm)
+
+ temp = agg_peak[bucket] * bcm->vote_scale;
+ bcm->vote_y[bucket] = bcm_div(temp, bcm->aux_data.unit);
+-
+- if (bcm->enable_mask && (bcm->vote_x[bucket] || bcm->vote_y[bucket])) {
+- bcm->vote_x[bucket] = 0;
+- bcm->vote_y[bucket] = bcm->enable_mask;
+- }
+ }
+
+ if (bcm->keepalive && bcm->vote_x[QCOM_ICC_BUCKET_AMC] == 0 &&
+@@ -260,8 +285,12 @@ int qcom_icc_bcm_voter_commit(struct bcm_voter *voter)
+ return 0;
+
+ mutex_lock(&voter->lock);
+- list_for_each_entry(bcm, &voter->commit_list, list)
+- bcm_aggregate(bcm);
++ list_for_each_entry(bcm, &voter->commit_list, list) {
++ if (bcm->enable_mask)
++ bcm_aggregate_mask(bcm);
++ else
++ bcm_aggregate(bcm);
++ }
+
+ /*
+ * Pre sort the BCMs based on VCD for ease of generating a command list
+--
+2.40.1
+
--- /dev/null
+From 0c79fd4c17515b6ed8095326a131f482dc11ebed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 12 Aug 2023 01:16:16 +0200
+Subject: interconnect: qcom: bcm-voter: Use enable_maks for keepalive voting
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit 1a70ca71547be051769f0628aa09717694f508f0 ]
+
+BCMs with an enable_mask expect to only have that specific value written
+to them. The current implementation only works by miracle for BCMs with
+enable mask == BIT(0), as the minimal vote we've been using so far just
+so happens to be equal to that.
+
+Use the correct value with keepalive voting.
+
+Fixes: d8630f050d3f ("interconnect: qcom: Add support for mask-based BCMs")
+Reported-by: Bjorn Andersson <quic_bjorande@quicinc.com>
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230811-topic-icc_fix_1he-v2-2-0620af8ac133@linaro.org
+Signed-off-by: Georgi Djakov <djakov@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/interconnect/qcom/bcm-voter.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/interconnect/qcom/bcm-voter.c b/drivers/interconnect/qcom/bcm-voter.c
+index d857eb8838b95..a2d437a05a11f 100644
+--- a/drivers/interconnect/qcom/bcm-voter.c
++++ b/drivers/interconnect/qcom/bcm-voter.c
+@@ -81,10 +81,10 @@ static void bcm_aggregate_mask(struct qcom_icc_bcm *bcm)
+ }
+
+ if (bcm->keepalive) {
+- bcm->vote_x[QCOM_ICC_BUCKET_AMC] = 1;
+- bcm->vote_x[QCOM_ICC_BUCKET_WAKE] = 1;
+- bcm->vote_y[QCOM_ICC_BUCKET_AMC] = 1;
+- bcm->vote_y[QCOM_ICC_BUCKET_WAKE] = 1;
++ bcm->vote_x[QCOM_ICC_BUCKET_AMC] = bcm->enable_mask;
++ bcm->vote_x[QCOM_ICC_BUCKET_WAKE] = bcm->enable_mask;
++ bcm->vote_y[QCOM_ICC_BUCKET_AMC] = bcm->enable_mask;
++ bcm->vote_y[QCOM_ICC_BUCKET_WAKE] = bcm->enable_mask;
+ }
+ }
+
+--
+2.40.1
+
--- /dev/null
+From 14bc9e11f315f543c029a7329882a148510e60c4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Jul 2023 12:49:22 +0200
+Subject: interconnect: qcom: qcm2290: Enable sync state
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit 4e048e9b7a160f7112069c0ec2947be15f3e8154 ]
+
+Enable the generic .sync_state callback to ensure there are no
+outstanding votes that would waste power.
+
+Generally one would need a bunch of interface clocks to access the QoS
+registers when trying to go over all possible nodes during sync_state,
+but QCM2290 surprisingly does not seem to require any such handling.
+
+Fixes: 1a14b1ac3935 ("interconnect: qcom: Add QCM2290 driver support")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230720-topic-qcm2290_icc-v2-2-a2ceb9d3e713@linaro.org
+Signed-off-by: Georgi Djakov <djakov@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/interconnect/qcom/qcm2290.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/interconnect/qcom/qcm2290.c b/drivers/interconnect/qcom/qcm2290.c
+index a29cdb4fac03f..82a2698ad66b1 100644
+--- a/drivers/interconnect/qcom/qcm2290.c
++++ b/drivers/interconnect/qcom/qcm2290.c
+@@ -1355,6 +1355,7 @@ static struct platform_driver qcm2290_noc_driver = {
+ .driver = {
+ .name = "qnoc-qcm2290",
+ .of_match_table = qcm2290_noc_of_match,
++ .sync_state = icc_sync_state,
+ },
+ };
+ module_platform_driver(qcm2290_noc_driver);
+--
+2.40.1
+
--- /dev/null
+From 4c555f579dbaf576a590c5e6eb1e1d06628742a2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Aug 2023 19:34:57 +0200
+Subject: interconnect: qcom: sm8450: Enable sync_state
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit 16862f1b2110eca6330e5be6d804e1a08e06a202 ]
+
+Enable sync_state on sm8450 so that the interconnect votes actually mean
+anything and aren't just pinned to INT_MAX.
+
+Fixes: fafc114a468e ("interconnect: qcom: Add SM8450 interconnect provider driver")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Reviewed-by: Vinod Koul <vkoul@kernel.org>
+Link: https://lore.kernel.org/r/20230811-topic-8450_syncstate-v1-1-69ae5552a18b@linaro.org
+Signed-off-by: Georgi Djakov <djakov@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/interconnect/qcom/sm8450.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/interconnect/qcom/sm8450.c b/drivers/interconnect/qcom/sm8450.c
+index e64c214b40209..d6e582a02e628 100644
+--- a/drivers/interconnect/qcom/sm8450.c
++++ b/drivers/interconnect/qcom/sm8450.c
+@@ -1886,6 +1886,7 @@ static struct platform_driver qnoc_driver = {
+ .driver = {
+ .name = "qnoc-sm8450",
+ .of_match_table = qnoc_of_match,
++ .sync_state = icc_sync_state,
+ },
+ };
+
+--
+2.40.1
+
--- /dev/null
+From a712fb9552f0983f426d8efedeb5d015fe60cbb2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Aug 2023 13:21:41 +0100
+Subject: io_uring: fix drain stalls by invalid SQE
+
+From: Pavel Begunkov <asml.silence@gmail.com>
+
+[ Upstream commit cfdbaa3a291d6fd2cb4a1a70d74e63b4abc2f5ec ]
+
+cq_extra is protected by ->completion_lock, which io_get_sqe() misses.
+The bug is harmless as it doesn't happen in real life, requires invalid
+SQ index array and racing with submission, and only messes up the
+userspace, i.e. stall requests execution but will be cleaned up on
+ring destruction.
+
+Fixes: 15641e427070f ("io_uring: don't cache number of dropped SQEs")
+Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
+Link: https://lore.kernel.org/r/66096d54651b1a60534bb2023f2947f09f50ef73.1691538547.git.asml.silence@gmail.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ io_uring/io_uring.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c
+index a57bdf336ca8a..d029e578bdfe1 100644
+--- a/io_uring/io_uring.c
++++ b/io_uring/io_uring.c
+@@ -2468,7 +2468,9 @@ static bool io_get_sqe(struct io_ring_ctx *ctx, const struct io_uring_sqe **sqe)
+ }
+
+ /* drop invalid entries */
++ spin_lock(&ctx->completion_lock);
+ ctx->cq_extra--;
++ spin_unlock(&ctx->completion_lock);
+ WRITE_ONCE(ctx->rings->sq_dropped,
+ READ_ONCE(ctx->rings->sq_dropped) + 1);
+ return false;
+--
+2.40.1
+
--- /dev/null
+From 9460e50500d739a77effd659b69c4a5a486aad13 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Jun 2023 18:09:11 -0400
+Subject: iomap: Remove large folio handling in iomap_invalidate_folio()
+
+From: Matthew Wilcox (Oracle) <willy@infradead.org>
+
+[ Upstream commit a221ab717c43147f728d93513923ba3528f861bf ]
+
+We do not need to release the iomap_page in iomap_invalidate_folio()
+to allow the folio to be split. The splitting code will call
+->release_folio() if there is still per-fs private data attached to
+the folio. At that point, we will check if the folio is still dirty
+and decline to release the iomap_page. It is possible to trigger the
+warning in perfectly legitimate circumstances (eg if a disk read fails,
+we do a partial write to the folio, then we truncate the folio), which
+will cause those writes to be lost.
+
+Fixes: 60d8231089f0 ("iomap: Support large folios in invalidatepage")
+Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
+Reviewed-by: Darrick J. Wong <djwong@kernel.org>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/iomap/buffered-io.c | 5 -----
+ 1 file changed, 5 deletions(-)
+
+diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c
+index 063133ec77f49..08ee293c4117c 100644
+--- a/fs/iomap/buffered-io.c
++++ b/fs/iomap/buffered-io.c
+@@ -508,11 +508,6 @@ void iomap_invalidate_folio(struct folio *folio, size_t offset, size_t len)
+ WARN_ON_ONCE(folio_test_writeback(folio));
+ folio_cancel_dirty(folio);
+ iomap_page_release(folio);
+- } else if (folio_test_large(folio)) {
+- /* Must release the iop so the page can be split */
+- WARN_ON_ONCE(!folio_test_uptodate(folio) &&
+- folio_test_dirty(folio));
+- iomap_page_release(folio);
+ }
+ }
+ EXPORT_SYMBOL_GPL(iomap_invalidate_folio);
+--
+2.40.1
+
--- /dev/null
+From e02e5d4a3ff1a1ba085d84a327348d81a4f845df Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Jun 2023 10:51:45 +0000
+Subject: iommu/amd/iommu_v2: Fix pasid_state refcount dec hit 0 warning on
+ pasid unbind
+
+From: Daniel Marcovitch <dmarcovitch@nvidia.com>
+
+[ Upstream commit 534103bcd52ca9c1fecbc70e717b4a538dc4ded8 ]
+
+When unbinding pasid - a race condition exists vs outstanding page faults.
+
+To prevent this, the pasid_state object contains a refcount.
+ * set to 1 on pasid bind
+ * incremented on each ppr notification start
+ * decremented on each ppr notification done
+ * decremented on pasid unbind
+
+Since refcount_dec assumes that refcount will never reach 0:
+ the current implementation causes the following to be invoked on
+ pasid unbind:
+ REFCOUNT_WARN("decrement hit 0; leaking memory")
+
+Fix this issue by changing refcount_dec to refcount_dec_and_test
+to explicitly handle refcount=1.
+
+Fixes: 8bc54824da4e ("iommu/amd: Convert from atomic_t to refcount_t on pasid_state->count")
+Signed-off-by: Daniel Marcovitch <dmarcovitch@nvidia.com>
+Signed-off-by: Vasant Hegde <vasant.hegde@amd.com>
+Link: https://lore.kernel.org/r/20230609105146.7773-2-vasant.hegde@amd.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/amd/iommu_v2.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iommu/amd/iommu_v2.c b/drivers/iommu/amd/iommu_v2.c
+index 261352a232716..65d78d7e04408 100644
+--- a/drivers/iommu/amd/iommu_v2.c
++++ b/drivers/iommu/amd/iommu_v2.c
+@@ -262,8 +262,8 @@ static void put_pasid_state(struct pasid_state *pasid_state)
+
+ static void put_pasid_state_wait(struct pasid_state *pasid_state)
+ {
+- refcount_dec(&pasid_state->count);
+- wait_event(pasid_state->wq, !refcount_read(&pasid_state->count));
++ if (!refcount_dec_and_test(&pasid_state->count))
++ wait_event(pasid_state->wq, !refcount_read(&pasid_state->count));
+ free_pasid_state(pasid_state);
+ }
+
+--
+2.40.1
+
--- /dev/null
+From a60b1e79871d2d077e81e36d444a6648e3cf76b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Jun 2023 17:02:22 +0800
+Subject: iommu/mediatek: Fix two IOMMU share pagetable issue
+
+From: Chengci.Xu <chengci.xu@mediatek.com>
+
+[ Upstream commit cf69ef46dbd980a0b1c956d668e066a73e0acd0f ]
+
+Prepare for mt8188 to fix a two IOMMU HWs share pagetable issue.
+
+We have two MM IOMMU HWs in mt8188, one is VPP-IOMMU, the other is
+VDO-IOMMU. The 2 MM IOMMU HWs share pagetable don't work in this case:
+ a) VPP-IOMMU probe firstly.
+ b) VDO-IOMMU probe.
+ c) The master for VDO-IOMMU probe (means frstdata is vpp-iommu).
+ d) The master in another domain probe. No matter it is vdo or vpp.
+Then it still create a new pagetable in step d). The problem is
+"frstdata->bank[0]->m4u_dom" was not initialized. Then when d) enter, it
+still create a new one.
+
+In this patch, we create a new variable "share_dom" for this share
+pgtable case, it should be helpful for readable. and put all the share
+pgtable logic in the mtk_iommu_domain_finalise.
+
+In mt8195, the master of VPP-IOMMU probes before than VDO-IOMMU
+from its dtsi node sequence, we don't see this issue in it. Prepare for
+mt8188.
+
+Fixes: 645b87c190c9 ("iommu/mediatek: Fix 2 HW sharing pgtable issue")
+Signed-off-by: Chengci.Xu <chengci.xu@mediatek.com>
+Signed-off-by: Yong Wu <yong.wu@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
+Link: https://lore.kernel.org/r/20230602090227.7264-3-yong.wu@mediatek.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/mtk_iommu.c | 22 ++++++++++++++--------
+ 1 file changed, 14 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
+index e93906d6e112e..c2764891a779c 100644
+--- a/drivers/iommu/mtk_iommu.c
++++ b/drivers/iommu/mtk_iommu.c
+@@ -258,6 +258,8 @@ struct mtk_iommu_data {
+ struct device *smicomm_dev;
+
+ struct mtk_iommu_bank_data *bank;
++ struct mtk_iommu_domain *share_dom; /* For 2 HWs share pgtable */
++
+ struct regmap *pericfg;
+ struct mutex mutex; /* Protect m4u_group/m4u_dom above */
+
+@@ -620,15 +622,14 @@ static int mtk_iommu_domain_finalise(struct mtk_iommu_domain *dom,
+ struct mtk_iommu_data *data,
+ unsigned int region_id)
+ {
++ struct mtk_iommu_domain *share_dom = data->share_dom;
+ const struct mtk_iommu_iova_region *region;
+- struct mtk_iommu_domain *m4u_dom;
+-
+- /* Always use bank0 in sharing pgtable case */
+- m4u_dom = data->bank[0].m4u_dom;
+- if (m4u_dom) {
+- dom->iop = m4u_dom->iop;
+- dom->cfg = m4u_dom->cfg;
+- dom->domain.pgsize_bitmap = m4u_dom->cfg.pgsize_bitmap;
++
++ /* Always use share domain in sharing pgtable case */
++ if (MTK_IOMMU_HAS_FLAG(data->plat_data, SHARE_PGTABLE) && share_dom) {
++ dom->iop = share_dom->iop;
++ dom->cfg = share_dom->cfg;
++ dom->domain.pgsize_bitmap = share_dom->cfg.pgsize_bitmap;
+ goto update_iova_region;
+ }
+
+@@ -658,6 +659,9 @@ static int mtk_iommu_domain_finalise(struct mtk_iommu_domain *dom,
+ /* Update our support page sizes bitmap */
+ dom->domain.pgsize_bitmap = dom->cfg.pgsize_bitmap;
+
++ if (MTK_IOMMU_HAS_FLAG(data->plat_data, SHARE_PGTABLE))
++ data->share_dom = dom;
++
+ update_iova_region:
+ /* Update the iova region for this domain */
+ region = data->plat_data->iova_region + region_id;
+@@ -708,7 +712,9 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
+ /* Data is in the frstdata in sharing pgtable case. */
+ frstdata = mtk_iommu_get_frst_data(hw_list);
+
++ mutex_lock(&frstdata->mutex);
+ ret = mtk_iommu_domain_finalise(dom, frstdata, region_id);
++ mutex_unlock(&frstdata->mutex);
+ if (ret) {
+ mutex_unlock(&dom->mutex);
+ return ret;
+--
+2.40.1
+
--- /dev/null
+From c83a4584dd07d217631ede21e23748f0f65e909f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Jun 2023 11:27:39 +0200
+Subject: iommu/qcom: Disable and reset context bank before programming
+
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+
+[ Upstream commit 9f3fef23d9b5a858a6e6d5f478bb1b6b76265e76 ]
+
+Writing the new TTBRs, TCRs and MAIRs on a previously enabled
+context bank may trigger a context fault, resulting in firmware
+driven AP resets: change the domain initialization programming
+sequence to disable the context bank(s) and to also clear the
+related fault address (CB_FAR) and fault status (CB_FSR)
+registers before writing new values to TTBR0/1, TCR/TCR2, MAIR0/1.
+
+Fixes: 0ae349a0f33f ("iommu/qcom: Add qcom_iommu")
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230622092742.74819-4-angelogioacchino.delregno@collabora.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/arm/arm-smmu/qcom_iommu.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+index a503ed758ec30..3e551ca6afdb9 100644
+--- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
++++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+@@ -273,6 +273,13 @@ static int qcom_iommu_init_domain(struct iommu_domain *domain,
+ ctx->secure_init = true;
+ }
+
++ /* Disable context bank before programming */
++ iommu_writel(ctx, ARM_SMMU_CB_SCTLR, 0);
++
++ /* Clear context bank fault address fault status registers */
++ iommu_writel(ctx, ARM_SMMU_CB_FAR, 0);
++ iommu_writel(ctx, ARM_SMMU_CB_FSR, ARM_SMMU_FSR_FAULT);
++
+ /* TTBRs */
+ iommu_writeq(ctx, ARM_SMMU_CB_TTBR0,
+ pgtbl_cfg.arm_lpae_s1_cfg.ttbr |
+--
+2.40.1
+
--- /dev/null
+From 2442b625aed07af94d9dbd2166ccbcdeed6ad119 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Jul 2023 19:27:58 +0800
+Subject: iommu: Remove kernel-doc warnings
+
+From: Zhu Wang <wangzhu9@huawei.com>
+
+[ Upstream commit 6b7867b5b8a6b14c487bf04a693ab424c7a8718d ]
+
+Remove kernel-doc warnings:
+
+drivers/iommu/iommu.c:3261: warning: Function parameter or member 'group'
+not described in 'iommu_group_release_dma_owner'
+drivers/iommu/iommu.c:3261: warning: Excess function parameter 'dev'
+description in 'iommu_group_release_dma_owner'
+drivers/iommu/iommu.c:3275: warning: Function parameter or member 'dev'
+not described in 'iommu_device_release_dma_owner'
+drivers/iommu/iommu.c:3275: warning: Excess function parameter 'group'
+description in 'iommu_device_release_dma_owner'
+
+Signed-off-by: Zhu Wang <wangzhu9@huawei.com>
+Fixes: 89395ccedbc1 ("iommu: Add device-centric DMA ownership interfaces")
+Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
+Link: https://lore.kernel.org/r/20230731112758.214775-1-wangzhu9@huawei.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/iommu.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
+index f1dcfa3f1a1b4..88e7154f846d3 100644
+--- a/drivers/iommu/iommu.c
++++ b/drivers/iommu/iommu.c
+@@ -3196,7 +3196,7 @@ static void __iommu_release_dma_ownership(struct iommu_group *group)
+
+ /**
+ * iommu_group_release_dma_owner() - Release DMA ownership of a group
+- * @dev: The device
++ * @group: The group
+ *
+ * Release the DMA ownership claimed by iommu_group_claim_dma_owner().
+ */
+@@ -3210,7 +3210,7 @@ EXPORT_SYMBOL_GPL(iommu_group_release_dma_owner);
+
+ /**
+ * iommu_device_release_dma_owner() - Release DMA ownership of a device
+- * @group: The device.
++ * @dev: The device.
+ *
+ * Release the DMA ownership claimed by iommu_device_claim_dma_owner().
+ */
+--
+2.40.1
+
--- /dev/null
+From ff6ccd4d119ac7f3d55690d299f48554b65bd3af Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 17 Jun 2023 18:25:45 +0000
+Subject: iommu: rockchip: Fix directory table address encoding
+
+From: Jonas Karlman <jonas@kwiboo.se>
+
+[ Upstream commit 6df63b7ebdaf5fcd75dceedf6967d0761e56eca1 ]
+
+The physical address to the directory table is currently encoded using
+the following bit layout for IOMMU v2.
+
+ 31:12 - Address bit 31:0
+ 11: 4 - Address bit 39:32
+
+This is also the bit layout used by the vendor kernel.
+
+However, testing has shown that addresses to the directory/page tables
+and memory pages are all encoded using the same bit layout.
+
+IOMMU v1:
+ 31:12 - Address bit 31:0
+
+IOMMU v2:
+ 31:12 - Address bit 31:0
+ 11: 8 - Address bit 35:32
+ 7: 4 - Address bit 39:36
+
+Change to use the mk_dtentries ops to encode the directory table address
+correctly. The value written to DTE_ADDR may include the valid bit set,
+a bit that is ignored and DTE_ADDR reg read it back as 0.
+
+This also update the bit layout comment for the page address and the
+number of nybbles that are read back for DTE_ADDR comment.
+
+These changes render the dte_addr_phys and dma_addr_dte ops unused and
+is removed.
+
+Fixes: 227014b33f62 ("iommu: rockchip: Add internal ops to handle variants")
+Fixes: c55356c534aa ("iommu: rockchip: Add support for iommu v2")
+Fixes: c987b65a574f ("iommu/rockchip: Fix physical address decoding")
+Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
+Reviewed-by: Robin Murphy <robin.murphy@arm.com>
+Link: https://lore.kernel.org/r/20230617182540.3091374-2-jonas@kwiboo.se
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/rockchip-iommu.c | 43 ++++------------------------------
+ 1 file changed, 5 insertions(+), 38 deletions(-)
+
+diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
+index 4054030c32379..ae42959bc4905 100644
+--- a/drivers/iommu/rockchip-iommu.c
++++ b/drivers/iommu/rockchip-iommu.c
+@@ -98,8 +98,6 @@ struct rk_iommu_ops {
+ phys_addr_t (*pt_address)(u32 dte);
+ u32 (*mk_dtentries)(dma_addr_t pt_dma);
+ u32 (*mk_ptentries)(phys_addr_t page, int prot);
+- phys_addr_t (*dte_addr_phys)(u32 addr);
+- u32 (*dma_addr_dte)(dma_addr_t dt_dma);
+ u64 dma_bit_mask;
+ };
+
+@@ -278,8 +276,8 @@ static u32 rk_mk_pte(phys_addr_t page, int prot)
+ /*
+ * In v2:
+ * 31:12 - Page address bit 31:0
+- * 11:9 - Page address bit 34:32
+- * 8:4 - Page address bit 39:35
++ * 11: 8 - Page address bit 35:32
++ * 7: 4 - Page address bit 39:36
+ * 3 - Security
+ * 2 - Writable
+ * 1 - Readable
+@@ -506,7 +504,7 @@ static int rk_iommu_force_reset(struct rk_iommu *iommu)
+
+ /*
+ * Check if register DTE_ADDR is working by writing DTE_ADDR_DUMMY
+- * and verifying that upper 5 nybbles are read back.
++ * and verifying that upper 5 (v1) or 7 (v2) nybbles are read back.
+ */
+ for (i = 0; i < iommu->num_mmu; i++) {
+ dte_addr = rk_ops->pt_address(DTE_ADDR_DUMMY);
+@@ -531,33 +529,6 @@ static int rk_iommu_force_reset(struct rk_iommu *iommu)
+ return 0;
+ }
+
+-static inline phys_addr_t rk_dte_addr_phys(u32 addr)
+-{
+- return (phys_addr_t)addr;
+-}
+-
+-static inline u32 rk_dma_addr_dte(dma_addr_t dt_dma)
+-{
+- return dt_dma;
+-}
+-
+-#define DT_HI_MASK GENMASK_ULL(39, 32)
+-#define DTE_BASE_HI_MASK GENMASK(11, 4)
+-#define DT_SHIFT 28
+-
+-static inline phys_addr_t rk_dte_addr_phys_v2(u32 addr)
+-{
+- u64 addr64 = addr;
+- return (phys_addr_t)(addr64 & RK_DTE_PT_ADDRESS_MASK) |
+- ((addr64 & DTE_BASE_HI_MASK) << DT_SHIFT);
+-}
+-
+-static inline u32 rk_dma_addr_dte_v2(dma_addr_t dt_dma)
+-{
+- return (dt_dma & RK_DTE_PT_ADDRESS_MASK) |
+- ((dt_dma & DT_HI_MASK) >> DT_SHIFT);
+-}
+-
+ static void log_iova(struct rk_iommu *iommu, int index, dma_addr_t iova)
+ {
+ void __iomem *base = iommu->bases[index];
+@@ -577,7 +548,7 @@ static void log_iova(struct rk_iommu *iommu, int index, dma_addr_t iova)
+ page_offset = rk_iova_page_offset(iova);
+
+ mmu_dte_addr = rk_iommu_read(base, RK_MMU_DTE_ADDR);
+- mmu_dte_addr_phys = rk_ops->dte_addr_phys(mmu_dte_addr);
++ mmu_dte_addr_phys = rk_ops->pt_address(mmu_dte_addr);
+
+ dte_addr_phys = mmu_dte_addr_phys + (4 * dte_index);
+ dte_addr = phys_to_virt(dte_addr_phys);
+@@ -967,7 +938,7 @@ static int rk_iommu_enable(struct rk_iommu *iommu)
+
+ for (i = 0; i < iommu->num_mmu; i++) {
+ rk_iommu_write(iommu->bases[i], RK_MMU_DTE_ADDR,
+- rk_ops->dma_addr_dte(rk_domain->dt_dma));
++ rk_ops->mk_dtentries(rk_domain->dt_dma));
+ rk_iommu_base_command(iommu->bases[i], RK_MMU_CMD_ZAP_CACHE);
+ rk_iommu_write(iommu->bases[i], RK_MMU_INT_MASK, RK_MMU_IRQ_MASK);
+ }
+@@ -1405,8 +1376,6 @@ static struct rk_iommu_ops iommu_data_ops_v1 = {
+ .pt_address = &rk_dte_pt_address,
+ .mk_dtentries = &rk_mk_dte,
+ .mk_ptentries = &rk_mk_pte,
+- .dte_addr_phys = &rk_dte_addr_phys,
+- .dma_addr_dte = &rk_dma_addr_dte,
+ .dma_bit_mask = DMA_BIT_MASK(32),
+ };
+
+@@ -1414,8 +1383,6 @@ static struct rk_iommu_ops iommu_data_ops_v2 = {
+ .pt_address = &rk_dte_pt_address_v2,
+ .mk_dtentries = &rk_mk_dte_v2,
+ .mk_ptentries = &rk_mk_pte_v2,
+- .dte_addr_phys = &rk_dte_addr_phys_v2,
+- .dma_addr_dte = &rk_dma_addr_dte_v2,
+ .dma_bit_mask = DMA_BIT_MASK(40),
+ };
+
+--
+2.40.1
+
--- /dev/null
+From 9e1876bb837b55e2eb0ba39a328751558e190665 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Jul 2023 14:36:05 -0300
+Subject: iommu/sprd: Add missing force_aperture
+
+From: Jason Gunthorpe <jgg@nvidia.com>
+
+[ Upstream commit d48a51286c698f7fe8efc688f23a532f4fe9a904 ]
+
+force_aperture was intended to false only by GART drivers that have an
+identity translation outside the aperture. This does not describe sprd, so
+add the missing 'force_aperture = true'.
+
+Fixes: b23e4fc4e3fa ("iommu: add Unisoc IOMMU basic driver")
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Acked-by: Chunyan Zhang <zhang.lyra@gmail.com>
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/sprd-iommu.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/iommu/sprd-iommu.c b/drivers/iommu/sprd-iommu.c
+index 39e34fdeccda7..eb684d8807cab 100644
+--- a/drivers/iommu/sprd-iommu.c
++++ b/drivers/iommu/sprd-iommu.c
+@@ -148,6 +148,7 @@ static struct iommu_domain *sprd_iommu_domain_alloc(unsigned int domain_type)
+
+ dom->domain.geometry.aperture_start = 0;
+ dom->domain.geometry.aperture_end = SZ_256M - 1;
++ dom->domain.geometry.force_aperture = true;
+
+ return &dom->domain;
+ }
+--
+2.40.1
+
--- /dev/null
+From dbb93d79005614af6d5eb14d038b17d1723db5c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Aug 2023 20:48:04 +0800
+Subject: iommu/vt-d: Fix to flush cache of PASID directory table
+
+From: Yanfei Xu <yanfei.xu@intel.com>
+
+[ Upstream commit 8a3b8e63f8371c1247b7aa24ff9c5312f1a6948b ]
+
+Even the PCI devices don't support pasid capability, PASID table is
+mandatory for a PCI device in scalable mode. However flushing cache
+of pasid directory table for these devices are not taken after pasid
+table is allocated as the "size" of table is zero. Fix it by
+calculating the size by page order.
+
+Found this when reading the code, no real problem encountered for now.
+
+Fixes: 194b3348bdbb ("iommu/vt-d: Fix PASID directory pointer coherency")
+Suggested-by: Lu Baolu <baolu.lu@linux.intel.com>
+Signed-off-by: Yanfei Xu <yanfei.xu@intel.com>
+Link: https://lore.kernel.org/r/20230616081045.721873-1-yanfei.xu@intel.com
+Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/intel/pasid.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iommu/intel/pasid.c b/drivers/iommu/intel/pasid.c
+index c5d479770e12e..49fc5a038a145 100644
+--- a/drivers/iommu/intel/pasid.c
++++ b/drivers/iommu/intel/pasid.c
+@@ -129,7 +129,7 @@ int intel_pasid_alloc_table(struct device *dev)
+ info->pasid_table = pasid_table;
+
+ if (!ecap_coherent(info->iommu->ecap))
+- clflush_cache_range(pasid_table->table, size);
++ clflush_cache_range(pasid_table->table, (1 << order) * PAGE_SIZE);
+
+ return 0;
+ }
+--
+2.40.1
+
--- /dev/null
+From ece01f584b5c50b8b187a17b7cf786fcba2184c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Jul 2023 15:12:07 -0300
+Subject: iommufd: Fix locking around hwpt allocation
+
+From: Jason Gunthorpe <jgg@nvidia.com>
+
+[ Upstream commit 31422dff187b243c58f3a97d16bbe9e9ada639fe ]
+
+Due to the auto_domains mechanism the ioas->mutex must be held until
+the hwpt is completely setup by iommufd_object_abort_and_destroy() or
+iommufd_object_finalize().
+
+This prevents a concurrent iommufd_device_auto_get_domain() from seeing
+an incompletely initialized object through the ioas->hwpt_list.
+
+To make this more consistent move the unlock until after finalize.
+
+Fixes: e8d57210035b ("iommufd: Add kAPI toward external drivers for physical devices")
+Link: https://lore.kernel.org/r/11-v8-6659224517ea+532-iommufd_alloc_jgg@nvidia.com
+Reviewed-by: Kevin Tian <kevin.tian@intel.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/iommufd/device.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iommu/iommufd/device.c b/drivers/iommu/iommufd/device.c
+index ed2937a4e196f..2e43ebf1a2b5c 100644
+--- a/drivers/iommu/iommufd/device.c
++++ b/drivers/iommu/iommufd/device.c
+@@ -298,8 +298,8 @@ static int iommufd_device_auto_get_domain(struct iommufd_device *idev,
+ }
+ hwpt->auto_domain = true;
+
+- mutex_unlock(&ioas->mutex);
+ iommufd_object_finalize(idev->ictx, &hwpt->obj);
++ mutex_unlock(&ioas->mutex);
+ return 0;
+ out_unlock:
+ mutex_unlock(&ioas->mutex);
+--
+2.40.1
+
--- /dev/null
+From ad257963d289e1c8841f04a6ded30eda0cabec3e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Jun 2023 17:28:02 +0800
+Subject: ipmi:ssif: Add check for kstrdup
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit c5586d0f711e9744d0cade39b0c4a2d116a333ca ]
+
+Add check for the return value of kstrdup() and return the error
+if it fails in order to avoid NULL pointer dereference.
+
+Fixes: c4436c9149c5 ("ipmi_ssif: avoid registering duplicate ssif interface")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Message-Id: <20230619092802.35384-1-jiasheng@iscas.ac.cn>
+Signed-off-by: Corey Minyard <minyard@acm.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/char/ipmi/ipmi_ssif.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c
+index 3b921c78ba083..3b87a2726e994 100644
+--- a/drivers/char/ipmi/ipmi_ssif.c
++++ b/drivers/char/ipmi/ipmi_ssif.c
+@@ -1600,6 +1600,11 @@ static int ssif_add_infos(struct i2c_client *client)
+ info->addr_src = SI_ACPI;
+ info->client = client;
+ info->adapter_name = kstrdup(client->adapter->name, GFP_KERNEL);
++ if (!info->adapter_name) {
++ kfree(info);
++ return -ENOMEM;
++ }
++
+ info->binfo.addr = client->addr;
+ list_add_tail(&info->link, &ssif_infos);
+ return 0;
+--
+2.40.1
+
--- /dev/null
+From 5f616948611f6ea3f54d934fecc8000cf02fb82d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Jun 2023 11:43:33 -0500
+Subject: ipmi:ssif: Fix a memory leak when scanning for an adapter
+
+From: Corey Minyard <minyard@acm.org>
+
+[ Upstream commit b8d72e32e1453d37ee5c8a219f24e7eeadc471ef ]
+
+The adapter scan ssif_info_find() sets info->adapter_name if the adapter
+info came from SMBIOS, as it's not set in that case. However, this
+function can be called more than once, and it will leak the adapter name
+if it had already been set. So check for NULL before setting it.
+
+Fixes: c4436c9149c5 ("ipmi_ssif: avoid registering duplicate ssif interface")
+Signed-off-by: Corey Minyard <minyard@acm.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/char/ipmi/ipmi_ssif.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c
+index 3b87a2726e994..faf1f2ad584bf 100644
+--- a/drivers/char/ipmi/ipmi_ssif.c
++++ b/drivers/char/ipmi/ipmi_ssif.c
+@@ -1400,7 +1400,7 @@ static struct ssif_addr_info *ssif_info_find(unsigned short addr,
+ restart:
+ list_for_each_entry(info, &ssif_infos, link) {
+ if (info->binfo.addr == addr) {
+- if (info->addr_src == SI_SMBIOS)
++ if (info->addr_src == SI_SMBIOS && !info->adapter_name)
+ info->adapter_name = kstrdup(adapter_name,
+ GFP_KERNEL);
+
+--
+2.40.1
+
--- /dev/null
+From 4db1955d890db95b838c0dad9cb734dc54106a24 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Aug 2023 17:58:04 +0800
+Subject: irqchip/loongson-eiointc: Fix return value checking of eiointc_index
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Bibo Mao <maobibo@loongson.cn>
+
+[ Upstream commit 2e99b73afde18853754c5fae8e8d1a66fe5e3f64 ]
+
+Return value of function eiointc_index is int, however it is converted
+into uint32_t and then compared smaller than zero, this will cause logic
+problem.
+
+Fixes: dd281e1a1a93 ("irqchip: Add Loongson Extended I/O interrupt controller support")
+Signed-off-by: Bibo Mao <maobibo@loongson.cn>
+Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20230811095805.2974722-2-maobibo@loongson.cn
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/irqchip/irq-loongson-eiointc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/irqchip/irq-loongson-eiointc.c b/drivers/irqchip/irq-loongson-eiointc.c
+index a7fcde3e3ecc7..ae28918df5c59 100644
+--- a/drivers/irqchip/irq-loongson-eiointc.c
++++ b/drivers/irqchip/irq-loongson-eiointc.c
+@@ -143,7 +143,7 @@ static int eiointc_router_init(unsigned int cpu)
+ int i, bit;
+ uint32_t data;
+ uint32_t node = cpu_to_eio_node(cpu);
+- uint32_t index = eiointc_index(node);
++ int index = eiointc_index(node);
+
+ if (index < 0) {
+ pr_err("Error: invalid nodemap!\n");
+--
+2.40.1
+
--- /dev/null
+From 40d7edfb76b9172138e54135b11142c93cda5f67 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 19 Aug 2023 20:32:16 +0300
+Subject: jfs: validate max amount of blocks before allocation.
+
+From: Alexei Filippov <halip0503@gmail.com>
+
+[ Upstream commit 0225e10972fa809728b8d4c1bd2772b3ec3fdb57 ]
+
+The lack of checking bmp->db_max_freebud in extBalloc() can lead to
+shift out of bounds, so this patch prevents undefined behavior, because
+bmp->db_max_freebud == -1 only if there is no free space.
+
+Signed-off-by: Aleksei Filippov <halip0503@gmail.com>
+Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com>
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-and-tested-by: syzbot+5f088f29593e6b4c8db8@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?id=01abadbd6ae6a08b1f1987aa61554c6b3ac19ff2
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/jfs/jfs_extent.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/fs/jfs/jfs_extent.c b/fs/jfs/jfs_extent.c
+index ae99a7e232eeb..a82751e6c47f9 100644
+--- a/fs/jfs/jfs_extent.c
++++ b/fs/jfs/jfs_extent.c
+@@ -311,6 +311,11 @@ extBalloc(struct inode *ip, s64 hint, s64 * nblocks, s64 * blkno)
+ * blocks in the map. in that case, we'll start off with the
+ * maximum free.
+ */
++
++ /* give up if no space left */
++ if (bmp->db_maxfreebud == -1)
++ return -ENOSPC;
++
+ max = (s64) 1 << bmp->db_maxfreebud;
+ if (*nblocks >= max && *nblocks > nbperpage)
+ nb = nblks = (max > nbperpage) ? max : nbperpage;
+--
+2.40.1
+
--- /dev/null
+From b73fd8672847b15c4c31bcbd8d5ee3d7b367f235 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Jun 2023 02:16:25 +0200
+Subject: kbuild: rust_is_available: add check for `bindgen` invocation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Miguel Ojeda <ojeda@kernel.org>
+
+[ Upstream commit 52cae7f28ed6c3992489f16bb355f5b623f0912e ]
+
+`scripts/rust_is_available.sh` calls `bindgen` with a special
+header in order to check whether the `libclang` version in use
+is suitable.
+
+However, the invocation itself may fail if, for instance, `bindgen`
+cannot locate `libclang`. This is fine for Kconfig (since the
+script will still fail and therefore disable Rust as it should),
+but it is pretty confusing for users of the `rustavailable` target
+given the error will be unrelated:
+
+ ./scripts/rust_is_available.sh: 21: arithmetic expression: expecting primary: "100000 * + 100 * + "
+ make: *** [Makefile:1816: rustavailable] Error 2
+
+Instead, run the `bindgen` invocation independently in a previous
+step, saving its output and return code. If it fails, then show
+the user a proper error message. Otherwise, continue as usual
+with the saved output.
+
+Since the previous patch we show a reference to the docs, and
+the docs now explain how `bindgen` looks for `libclang`,
+thus the error message can leverage the documentation, avoiding
+duplication here (and making users aware of the setup guide in
+the documentation).
+
+Reported-by: Nick Desaulniers <ndesaulniers@google.com>
+Link: https://lore.kernel.org/rust-for-linux/CAKwvOdm5JT4wbdQQYuW+RT07rCi6whGBM2iUAyg8A1CmLXG6Nw@mail.gmail.com/
+Reported-by: François Valenduc <francoisvalenduc@gmail.com>
+Closes: https://github.com/Rust-for-Linux/linux/issues/934
+Reported-by: Alexandru Radovici <msg4alex@gmail.com>
+Closes: https://github.com/Rust-for-Linux/linux/pull/921
+Reported-by: Matthew Leach <dev@mattleach.net>
+Closes: https://lore.kernel.org/rust-for-linux/20230507084116.1099067-1-dev@mattleach.net/
+Fixes: 78521f3399ab ("scripts: add `rust_is_available.sh`")
+Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
+Reviewed-by: Masahiro Yamada <masahiroy@kernel.org>
+Reviewed-by: Nathan Chancellor <nathan@kernel.org>
+Link: https://lore.kernel.org/r/20230616001631.463536-6-ojeda@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/rust_is_available.sh | 22 +++++++++++++++++++++-
+ 1 file changed, 21 insertions(+), 1 deletion(-)
+
+diff --git a/scripts/rust_is_available.sh b/scripts/rust_is_available.sh
+index 0c9be438e4cd3..c965895d80b97 100755
+--- a/scripts/rust_is_available.sh
++++ b/scripts/rust_is_available.sh
+@@ -90,8 +90,28 @@ if [ "$rust_bindings_generator_cversion" -gt "$rust_bindings_generator_min_cvers
+ fi
+
+ # Check that the `libclang` used by the Rust bindings generator is suitable.
++#
++# In order to do that, first invoke `bindgen` to get the `libclang` version
++# found by `bindgen`. This step may already fail if, for instance, `libclang`
++# is not found, thus inform the user in such a case.
++bindgen_libclang_output=$( \
++ LC_ALL=C "$BINDGEN" $(dirname $0)/rust_is_available_bindgen_libclang.h 2>&1 >/dev/null
++) || bindgen_libclang_code=$?
++if [ -n "$bindgen_libclang_code" ]; then
++ echo >&2 "***"
++ echo >&2 "*** Running '$BINDGEN' to check the libclang version (used by the Rust"
++ echo >&2 "*** bindings generator) failed with code $bindgen_libclang_code. This may be caused by"
++ echo >&2 "*** a failure to locate libclang. See output and docs below for details:"
++ echo >&2 "***"
++ echo >&2 "$bindgen_libclang_output"
++ echo >&2 "***"
++ exit 1
++fi
++
++# `bindgen` returned successfully, thus use the output to check that the version
++# of the `libclang` found by the Rust bindings generator is suitable.
+ bindgen_libclang_version=$( \
+- LC_ALL=C "$BINDGEN" $(dirname $0)/rust_is_available_bindgen_libclang.h 2>&1 >/dev/null \
++ echo "$bindgen_libclang_output" \
+ | grep -F 'clang version ' \
+ | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' \
+ | head -n 1 \
+--
+2.40.1
+
--- /dev/null
+From b5bc478f39836d70f330bef15bf0217d0393fb21 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Jun 2023 02:16:27 +0200
+Subject: kbuild: rust_is_available: fix confusion when a version appears in
+ the path
+
+From: Miguel Ojeda <ojeda@kernel.org>
+
+[ Upstream commit 9eb7e20e0c5cd069457845f965b3e8a7d736ecb7 ]
+
+`bindgen`'s output for `libclang`'s version check contains paths, which
+in turn may contain strings that look like version numbers [1][2]:
+
+ .../6.1.0-dev/.../rust_is_available_bindgen_libclang.h:2:9: warning: clang version 11.1.0 [-W#pragma-messages], err: false
+
+which the script will pick up as the version instead of the latter.
+
+It is also the case that versions may appear after the actual version
+(e.g. distribution's version text), which was the reason behind `head` [3]:
+
+ .../rust-is-available-bindgen-libclang.h:2:9: warning: clang version 13.0.0 (Fedora 13.0.0-3.fc35) [-W#pragma-messages], err: false
+
+Thus instead ask for a match after the `clang version` string.
+
+Reported-by: Jordan Isaacs <mail@jdisaacs.com>
+Closes: https://github.com/Rust-for-Linux/linux/issues/942 [1]
+Reported-by: "Ethan D. Twardy" <ethan.twardy@gmail.com>
+Closes: https://lore.kernel.org/rust-for-linux/20230528131802.6390-2-ethan.twardy@gmail.com/ [2]
+Reported-by: Tiago Lam <tiagolam@gmail.com>
+Closes: https://github.com/Rust-for-Linux/linux/pull/789 [3]
+Fixes: 78521f3399ab ("scripts: add `rust_is_available.sh`")
+Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
+Reviewed-by: Ethan Twardy <ethan.twardy@gmail.com>
+Tested-by: Ethan Twardy <ethan.twardy@gmail.com>
+Reviewed-by: Nathan Chancellor <nathan@kernel.org>
+Link: https://lore.kernel.org/r/20230616001631.463536-8-ojeda@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/rust_is_available.sh | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/scripts/rust_is_available.sh b/scripts/rust_is_available.sh
+index c965895d80b97..7a925d2b20fc7 100755
+--- a/scripts/rust_is_available.sh
++++ b/scripts/rust_is_available.sh
+@@ -112,9 +112,7 @@ fi
+ # of the `libclang` found by the Rust bindings generator is suitable.
+ bindgen_libclang_version=$( \
+ echo "$bindgen_libclang_output" \
+- | grep -F 'clang version ' \
+- | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' \
+- | head -n 1 \
++ | sed -nE 's:.*clang version ([0-9]+\.[0-9]+\.[0-9]+).*:\1:p'
+ )
+ bindgen_libclang_min_version=$($min_tool_version llvm)
+ bindgen_libclang_cversion=$(get_canonical_version $bindgen_libclang_version)
+--
+2.40.1
+
--- /dev/null
+From 9c5679664dafbd3c8c8886947616310e97b65b3b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Jun 2023 02:16:22 +0200
+Subject: kbuild: rust_is_available: fix version check when CC has multiple
+ arguments
+
+From: Russell Currey <ruscur@russell.cc>
+
+[ Upstream commit dee3a6b819c96fc8b1907577f585fd66f5c0fefe ]
+
+rust_is_available.sh uses cc-version.sh to identify which C compiler is
+in use, as scripts/Kconfig.include does. cc-version.sh isn't designed to
+be able to handle multiple arguments in one variable, i.e. "ccache clang".
+Its invocation in rust_is_available.sh quotes "$CC", which makes
+$1 == "ccache clang" instead of the intended $1 == ccache & $2 == clang.
+
+cc-version.sh could also be changed to handle having "ccache clang" as one
+argument, but it only has the one consumer upstream, making it simpler to
+fix the caller here.
+
+Signed-off-by: Russell Currey <ruscur@russell.cc>
+Fixes: 78521f3399ab ("scripts: add `rust_is_available.sh`")
+Link: https://github.com/Rust-for-Linux/linux/pull/873
+[ Reworded title prefix and reflow line to 75 columns. ]
+Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
+Reviewed-by: Nathan Chancellor <nathan@kernel.org>
+Link: https://lore.kernel.org/r/20230616001631.463536-3-ojeda@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/rust_is_available.sh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/scripts/rust_is_available.sh b/scripts/rust_is_available.sh
+index f43a010eaf305..0c9be438e4cd3 100755
+--- a/scripts/rust_is_available.sh
++++ b/scripts/rust_is_available.sh
+@@ -113,10 +113,10 @@ fi
+ #
+ # In the future, we might be able to perform a full version check, see
+ # https://github.com/rust-lang/rust-bindgen/issues/2138.
+-cc_name=$($(dirname $0)/cc-version.sh "$CC" | cut -f1 -d' ')
++cc_name=$($(dirname $0)/cc-version.sh $CC | cut -f1 -d' ')
+ if [ "$cc_name" = Clang ]; then
+ clang_version=$( \
+- LC_ALL=C "$CC" --version 2>/dev/null \
++ LC_ALL=C $CC --version 2>/dev/null \
+ | sed -nE '1s:.*version ([0-9]+\.[0-9]+\.[0-9]+).*:\1:p'
+ )
+ if [ "$clang_version" != "$bindgen_libclang_version" ]; then
+--
+2.40.1
+
--- /dev/null
+From f0a14015fc35f04feea07714ac268c9a65bfc222 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Jun 2023 02:16:21 +0200
+Subject: kbuild: rust_is_available: remove -v option
+
+From: Masahiro Yamada <masahiroy@kernel.org>
+
+[ Upstream commit d824d2f98565e7c4cb1b862c230198fbe1a968be ]
+
+The -v option is passed when this script is invoked from Makefile,
+but not when invoked from Kconfig.
+
+As you can see in scripts/Kconfig.include, the 'success' macro suppresses
+stdout and stderr anyway, so this script does not need to be quiet.
+
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Reviewed-by: Miguel Ojeda <ojeda@kernel.org>
+Tested-by: Miguel Ojeda <ojeda@kernel.org>
+Reviewed-by: Nathan Chancellor <nathan@kernel.org>
+Link: https://lore.kernel.org/r/20230109061436.3146442-1-masahiroy@kernel.org
+[ Reworded prefix to match the others in the patch series. ]
+Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
+Link: https://lore.kernel.org/r/20230616001631.463536-2-ojeda@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Stable-dep-of: dee3a6b819c9 ("kbuild: rust_is_available: fix version check when CC has multiple arguments")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Makefile | 4 +-
+ scripts/rust_is_available.sh | 96 +++++++++++++++---------------------
+ 2 files changed, 42 insertions(+), 58 deletions(-)
+
+diff --git a/Makefile b/Makefile
+index 212d1c7e4a1a3..41ac4ce7f8e58 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1289,7 +1289,7 @@ prepare0: archprepare
+ # All the preparing..
+ prepare: prepare0
+ ifdef CONFIG_RUST
+- $(Q)$(CONFIG_SHELL) $(srctree)/scripts/rust_is_available.sh -v
++ $(Q)$(CONFIG_SHELL) $(srctree)/scripts/rust_is_available.sh
+ $(Q)$(MAKE) $(build)=rust
+ endif
+
+@@ -1825,7 +1825,7 @@ $(DOC_TARGETS):
+ # "Is Rust available?" target
+ PHONY += rustavailable
+ rustavailable:
+- $(Q)$(CONFIG_SHELL) $(srctree)/scripts/rust_is_available.sh -v && echo "Rust is available!"
++ $(Q)$(CONFIG_SHELL) $(srctree)/scripts/rust_is_available.sh && echo "Rust is available!"
+
+ # Documentation target
+ #
+diff --git a/scripts/rust_is_available.sh b/scripts/rust_is_available.sh
+index aebbf19139709..f43a010eaf305 100755
+--- a/scripts/rust_is_available.sh
++++ b/scripts/rust_is_available.sh
+@@ -2,8 +2,6 @@
+ # SPDX-License-Identifier: GPL-2.0
+ #
+ # Tests whether a suitable Rust toolchain is available.
+-#
+-# Pass `-v` for human output and more checks (as warnings).
+
+ set -e
+
+@@ -23,21 +21,17 @@ get_canonical_version()
+
+ # Check that the Rust compiler exists.
+ if ! command -v "$RUSTC" >/dev/null; then
+- if [ "$1" = -v ]; then
+- echo >&2 "***"
+- echo >&2 "*** Rust compiler '$RUSTC' could not be found."
+- echo >&2 "***"
+- fi
++ echo >&2 "***"
++ echo >&2 "*** Rust compiler '$RUSTC' could not be found."
++ echo >&2 "***"
+ exit 1
+ fi
+
+ # Check that the Rust bindings generator exists.
+ if ! command -v "$BINDGEN" >/dev/null; then
+- if [ "$1" = -v ]; then
+- echo >&2 "***"
+- echo >&2 "*** Rust bindings generator '$BINDGEN' could not be found."
+- echo >&2 "***"
+- fi
++ echo >&2 "***"
++ echo >&2 "*** Rust bindings generator '$BINDGEN' could not be found."
++ echo >&2 "***"
+ exit 1
+ fi
+
+@@ -53,16 +47,14 @@ rust_compiler_min_version=$($min_tool_version rustc)
+ rust_compiler_cversion=$(get_canonical_version $rust_compiler_version)
+ rust_compiler_min_cversion=$(get_canonical_version $rust_compiler_min_version)
+ if [ "$rust_compiler_cversion" -lt "$rust_compiler_min_cversion" ]; then
+- if [ "$1" = -v ]; then
+- echo >&2 "***"
+- echo >&2 "*** Rust compiler '$RUSTC' is too old."
+- echo >&2 "*** Your version: $rust_compiler_version"
+- echo >&2 "*** Minimum version: $rust_compiler_min_version"
+- echo >&2 "***"
+- fi
++ echo >&2 "***"
++ echo >&2 "*** Rust compiler '$RUSTC' is too old."
++ echo >&2 "*** Your version: $rust_compiler_version"
++ echo >&2 "*** Minimum version: $rust_compiler_min_version"
++ echo >&2 "***"
+ exit 1
+ fi
+-if [ "$1" = -v ] && [ "$rust_compiler_cversion" -gt "$rust_compiler_min_cversion" ]; then
++if [ "$rust_compiler_cversion" -gt "$rust_compiler_min_cversion" ]; then
+ echo >&2 "***"
+ echo >&2 "*** Rust compiler '$RUSTC' is too new. This may or may not work."
+ echo >&2 "*** Your version: $rust_compiler_version"
+@@ -82,16 +74,14 @@ rust_bindings_generator_min_version=$($min_tool_version bindgen)
+ rust_bindings_generator_cversion=$(get_canonical_version $rust_bindings_generator_version)
+ rust_bindings_generator_min_cversion=$(get_canonical_version $rust_bindings_generator_min_version)
+ if [ "$rust_bindings_generator_cversion" -lt "$rust_bindings_generator_min_cversion" ]; then
+- if [ "$1" = -v ]; then
+- echo >&2 "***"
+- echo >&2 "*** Rust bindings generator '$BINDGEN' is too old."
+- echo >&2 "*** Your version: $rust_bindings_generator_version"
+- echo >&2 "*** Minimum version: $rust_bindings_generator_min_version"
+- echo >&2 "***"
+- fi
++ echo >&2 "***"
++ echo >&2 "*** Rust bindings generator '$BINDGEN' is too old."
++ echo >&2 "*** Your version: $rust_bindings_generator_version"
++ echo >&2 "*** Minimum version: $rust_bindings_generator_min_version"
++ echo >&2 "***"
+ exit 1
+ fi
+-if [ "$1" = -v ] && [ "$rust_bindings_generator_cversion" -gt "$rust_bindings_generator_min_cversion" ]; then
++if [ "$rust_bindings_generator_cversion" -gt "$rust_bindings_generator_min_cversion" ]; then
+ echo >&2 "***"
+ echo >&2 "*** Rust bindings generator '$BINDGEN' is too new. This may or may not work."
+ echo >&2 "*** Your version: $rust_bindings_generator_version"
+@@ -110,13 +100,11 @@ bindgen_libclang_min_version=$($min_tool_version llvm)
+ bindgen_libclang_cversion=$(get_canonical_version $bindgen_libclang_version)
+ bindgen_libclang_min_cversion=$(get_canonical_version $bindgen_libclang_min_version)
+ if [ "$bindgen_libclang_cversion" -lt "$bindgen_libclang_min_cversion" ]; then
+- if [ "$1" = -v ]; then
+- echo >&2 "***"
+- echo >&2 "*** libclang (used by the Rust bindings generator '$BINDGEN') is too old."
+- echo >&2 "*** Your version: $bindgen_libclang_version"
+- echo >&2 "*** Minimum version: $bindgen_libclang_min_version"
+- echo >&2 "***"
+- fi
++ echo >&2 "***"
++ echo >&2 "*** libclang (used by the Rust bindings generator '$BINDGEN') is too old."
++ echo >&2 "*** Your version: $bindgen_libclang_version"
++ echo >&2 "*** Minimum version: $bindgen_libclang_min_version"
++ echo >&2 "***"
+ exit 1
+ fi
+
+@@ -125,21 +113,19 @@ fi
+ #
+ # In the future, we might be able to perform a full version check, see
+ # https://github.com/rust-lang/rust-bindgen/issues/2138.
+-if [ "$1" = -v ]; then
+- cc_name=$($(dirname $0)/cc-version.sh "$CC" | cut -f1 -d' ')
+- if [ "$cc_name" = Clang ]; then
+- clang_version=$( \
+- LC_ALL=C "$CC" --version 2>/dev/null \
+- | sed -nE '1s:.*version ([0-9]+\.[0-9]+\.[0-9]+).*:\1:p'
+- )
+- if [ "$clang_version" != "$bindgen_libclang_version" ]; then
+- echo >&2 "***"
+- echo >&2 "*** libclang (used by the Rust bindings generator '$BINDGEN')"
+- echo >&2 "*** version does not match Clang's. This may be a problem."
+- echo >&2 "*** libclang version: $bindgen_libclang_version"
+- echo >&2 "*** Clang version: $clang_version"
+- echo >&2 "***"
+- fi
++cc_name=$($(dirname $0)/cc-version.sh "$CC" | cut -f1 -d' ')
++if [ "$cc_name" = Clang ]; then
++ clang_version=$( \
++ LC_ALL=C "$CC" --version 2>/dev/null \
++ | sed -nE '1s:.*version ([0-9]+\.[0-9]+\.[0-9]+).*:\1:p'
++ )
++ if [ "$clang_version" != "$bindgen_libclang_version" ]; then
++ echo >&2 "***"
++ echo >&2 "*** libclang (used by the Rust bindings generator '$BINDGEN')"
++ echo >&2 "*** version does not match Clang's. This may be a problem."
++ echo >&2 "*** libclang version: $bindgen_libclang_version"
++ echo >&2 "*** Clang version: $clang_version"
++ echo >&2 "***"
+ fi
+ fi
+
+@@ -150,11 +136,9 @@ rustc_sysroot=$("$RUSTC" $KRUSTFLAGS --print sysroot)
+ rustc_src=${RUST_LIB_SRC:-"$rustc_sysroot/lib/rustlib/src/rust/library"}
+ rustc_src_core="$rustc_src/core/src/lib.rs"
+ if [ ! -e "$rustc_src_core" ]; then
+- if [ "$1" = -v ]; then
+- echo >&2 "***"
+- echo >&2 "*** Source code for the 'core' standard library could not be found"
+- echo >&2 "*** at '$rustc_src_core'."
+- echo >&2 "***"
+- fi
++ echo >&2 "***"
++ echo >&2 "*** Source code for the 'core' standard library could not be found"
++ echo >&2 "*** at '$rustc_src_core'."
++ echo >&2 "***"
+ exit 1
+ fi
+--
+2.40.1
+
--- /dev/null
+From a2a46db78590048e3d849e50196ec7c8d4e93a65 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Jul 2023 14:18:16 +0200
+Subject: kernfs: add stub helper for kernfs_generic_poll()
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 79038a99445f69c5d28494dd4f8c6f0509f65b2e ]
+
+In some randconfig builds, kernfs ends up being disabled, so there is no prototype
+for kernfs_generic_poll()
+
+In file included from kernel/sched/build_utility.c:97:
+kernel/sched/psi.c:1479:3: error: implicit declaration of function 'kernfs_generic_poll' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
+ kernfs_generic_poll(t->of, wait);
+ ^
+
+Add a stub helper for it, as we have it for other kernfs functions.
+
+Fixes: aff037078ecae ("sched/psi: use kernfs polling functions for PSI trigger polling")
+Fixes: 147e1a97c4a0b ("fs: kernfs: add poll file operation")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Chengming Zhou <zhouchengming@bytedance.com>
+Link: https://lore.kernel.org/r/20230724121823.1357562-1-arnd@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/kernfs.h | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h
+index 73f5c120def88..2a36f3218b510 100644
+--- a/include/linux/kernfs.h
++++ b/include/linux/kernfs.h
+@@ -550,6 +550,10 @@ static inline int kernfs_setattr(struct kernfs_node *kn,
+ const struct iattr *iattr)
+ { return -ENOSYS; }
+
++static inline __poll_t kernfs_generic_poll(struct kernfs_open_file *of,
++ struct poll_table_struct *pt)
++{ return -ENOSYS; }
++
+ static inline void kernfs_notify(struct kernfs_node *kn) { }
+
+ static inline int kernfs_xattr_get(struct kernfs_node *kn, const char *name,
+--
+2.40.1
+
--- /dev/null
+From 4fd8debbca3bd0c262024c018f913f792b57a9ae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Jul 2023 15:45:32 -0700
+Subject: kvm/vfio: ensure kvg instance stays around in kvm_vfio_group_add()
+
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+
+[ Upstream commit 9e0f4f2918c2ff145d3dedee862d9919a6ed5812 ]
+
+kvm_vfio_group_add() creates kvg instance, links it to kv->group_list,
+and calls kvm_vfio_file_set_kvm() with kvg->file as an argument after
+dropping kv->lock. If we race group addition and deletion calls, kvg
+instance may get freed by the time we get around to calling
+kvm_vfio_file_set_kvm().
+
+Previous iterations of the code did not reference kvg->file outside of
+the critical section, but used a temporary variable. Still, they had
+similar problem of the file reference being owned by kvg structure and
+potential for kvm_vfio_group_del() dropping it before
+kvm_vfio_group_add() had a chance to complete.
+
+Fix this by moving call to kvm_vfio_file_set_kvm() under the protection
+of kv->lock. We already call it while holding the same lock when vfio
+group is being deleted, so it should be safe here as well.
+
+Fixes: 2fc1bec15883 ("kvm: set/clear kvm to/from vfio_group when group add/delete")
+Reviewed-by: Alex Williamson <alex.williamson@redhat.com>
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Reviewed-by: Kevin Tian <kevin.tian@intel.com>
+Link: https://lore.kernel.org/r/20230714224538.404793-1-dmitry.torokhov@gmail.com
+Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ virt/kvm/vfio.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/virt/kvm/vfio.c b/virt/kvm/vfio.c
+index af3d0cf06e4c6..365d30779768a 100644
+--- a/virt/kvm/vfio.c
++++ b/virt/kvm/vfio.c
+@@ -180,10 +180,10 @@ static int kvm_vfio_file_add(struct kvm_device *dev, unsigned int fd)
+ list_add_tail(&kvf->node, &kv->file_list);
+
+ kvm_arch_start_assignment(dev->kvm);
++ kvm_vfio_file_set_kvm(kvf->file, dev->kvm);
+
+ mutex_unlock(&kv->lock);
+
+- kvm_vfio_file_set_kvm(kvf->file, dev->kvm);
+ kvm_vfio_update_coherency(dev);
+
+ return 0;
+--
+2.40.1
+
--- /dev/null
+From 835c66b6250cfc95cf7785eabbcebde376c5e612 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Jul 2023 06:55:29 -0700
+Subject: kvm/vfio: Prepare for accepting vfio device fd
+
+From: Yi Liu <yi.l.liu@intel.com>
+
+[ Upstream commit 2f99073a722beef5f74f3b0f32bda227ba3df1e0 ]
+
+This renames kvm_vfio_group related helpers to prepare for accepting
+vfio device fd. No functional change is intended.
+
+Reviewed-by: Kevin Tian <kevin.tian@intel.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
+Tested-by: Terrence Xu <terrence.xu@intel.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Tested-by: Matthew Rosato <mjrosato@linux.ibm.com>
+Tested-by: Yanting Jiang <yanting.jiang@intel.com>
+Tested-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
+Tested-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
+Signed-off-by: Yi Liu <yi.l.liu@intel.com>
+Link: https://lore.kernel.org/r/20230718135551.6592-5-yi.l.liu@intel.com
+Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
+Stable-dep-of: 9e0f4f2918c2 ("kvm/vfio: ensure kvg instance stays around in kvm_vfio_group_add()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ virt/kvm/vfio.c | 115 ++++++++++++++++++++++++------------------------
+ 1 file changed, 58 insertions(+), 57 deletions(-)
+
+diff --git a/virt/kvm/vfio.c b/virt/kvm/vfio.c
+index 9584eb57e0eda..af3d0cf06e4c6 100644
+--- a/virt/kvm/vfio.c
++++ b/virt/kvm/vfio.c
+@@ -21,7 +21,7 @@
+ #include <asm/kvm_ppc.h>
+ #endif
+
+-struct kvm_vfio_group {
++struct kvm_vfio_file {
+ struct list_head node;
+ struct file *file;
+ #ifdef CONFIG_SPAPR_TCE_IOMMU
+@@ -30,7 +30,7 @@ struct kvm_vfio_group {
+ };
+
+ struct kvm_vfio {
+- struct list_head group_list;
++ struct list_head file_list;
+ struct mutex lock;
+ bool noncoherent;
+ };
+@@ -98,34 +98,35 @@ static struct iommu_group *kvm_vfio_file_iommu_group(struct file *file)
+ }
+
+ static void kvm_spapr_tce_release_vfio_group(struct kvm *kvm,
+- struct kvm_vfio_group *kvg)
++ struct kvm_vfio_file *kvf)
+ {
+- if (WARN_ON_ONCE(!kvg->iommu_group))
++ if (WARN_ON_ONCE(!kvf->iommu_group))
+ return;
+
+- kvm_spapr_tce_release_iommu_group(kvm, kvg->iommu_group);
+- iommu_group_put(kvg->iommu_group);
+- kvg->iommu_group = NULL;
++ kvm_spapr_tce_release_iommu_group(kvm, kvf->iommu_group);
++ iommu_group_put(kvf->iommu_group);
++ kvf->iommu_group = NULL;
+ }
+ #endif
+
+ /*
+- * Groups can use the same or different IOMMU domains. If the same then
+- * adding a new group may change the coherency of groups we've previously
+- * been told about. We don't want to care about any of that so we retest
+- * each group and bail as soon as we find one that's noncoherent. This
+- * means we only ever [un]register_noncoherent_dma once for the whole device.
++ * Groups/devices can use the same or different IOMMU domains. If the same
++ * then adding a new group/device may change the coherency of groups/devices
++ * we've previously been told about. We don't want to care about any of
++ * that so we retest each group/device and bail as soon as we find one that's
++ * noncoherent. This means we only ever [un]register_noncoherent_dma once
++ * for the whole device.
+ */
+ static void kvm_vfio_update_coherency(struct kvm_device *dev)
+ {
+ struct kvm_vfio *kv = dev->private;
+ bool noncoherent = false;
+- struct kvm_vfio_group *kvg;
++ struct kvm_vfio_file *kvf;
+
+ mutex_lock(&kv->lock);
+
+- list_for_each_entry(kvg, &kv->group_list, node) {
+- if (!kvm_vfio_file_enforced_coherent(kvg->file)) {
++ list_for_each_entry(kvf, &kv->file_list, node) {
++ if (!kvm_vfio_file_enforced_coherent(kvf->file)) {
+ noncoherent = true;
+ break;
+ }
+@@ -143,10 +144,10 @@ static void kvm_vfio_update_coherency(struct kvm_device *dev)
+ mutex_unlock(&kv->lock);
+ }
+
+-static int kvm_vfio_group_add(struct kvm_device *dev, unsigned int fd)
++static int kvm_vfio_file_add(struct kvm_device *dev, unsigned int fd)
+ {
+ struct kvm_vfio *kv = dev->private;
+- struct kvm_vfio_group *kvg;
++ struct kvm_vfio_file *kvf;
+ struct file *filp;
+ int ret;
+
+@@ -162,27 +163,27 @@ static int kvm_vfio_group_add(struct kvm_device *dev, unsigned int fd)
+
+ mutex_lock(&kv->lock);
+
+- list_for_each_entry(kvg, &kv->group_list, node) {
+- if (kvg->file == filp) {
++ list_for_each_entry(kvf, &kv->file_list, node) {
++ if (kvf->file == filp) {
+ ret = -EEXIST;
+ goto err_unlock;
+ }
+ }
+
+- kvg = kzalloc(sizeof(*kvg), GFP_KERNEL_ACCOUNT);
+- if (!kvg) {
++ kvf = kzalloc(sizeof(*kvf), GFP_KERNEL_ACCOUNT);
++ if (!kvf) {
+ ret = -ENOMEM;
+ goto err_unlock;
+ }
+
+- kvg->file = filp;
+- list_add_tail(&kvg->node, &kv->group_list);
++ kvf->file = filp;
++ list_add_tail(&kvf->node, &kv->file_list);
+
+ kvm_arch_start_assignment(dev->kvm);
+
+ mutex_unlock(&kv->lock);
+
+- kvm_vfio_file_set_kvm(kvg->file, dev->kvm);
++ kvm_vfio_file_set_kvm(kvf->file, dev->kvm);
+ kvm_vfio_update_coherency(dev);
+
+ return 0;
+@@ -193,10 +194,10 @@ static int kvm_vfio_group_add(struct kvm_device *dev, unsigned int fd)
+ return ret;
+ }
+
+-static int kvm_vfio_group_del(struct kvm_device *dev, unsigned int fd)
++static int kvm_vfio_file_del(struct kvm_device *dev, unsigned int fd)
+ {
+ struct kvm_vfio *kv = dev->private;
+- struct kvm_vfio_group *kvg;
++ struct kvm_vfio_file *kvf;
+ struct fd f;
+ int ret;
+
+@@ -208,18 +209,18 @@ static int kvm_vfio_group_del(struct kvm_device *dev, unsigned int fd)
+
+ mutex_lock(&kv->lock);
+
+- list_for_each_entry(kvg, &kv->group_list, node) {
+- if (kvg->file != f.file)
++ list_for_each_entry(kvf, &kv->file_list, node) {
++ if (kvf->file != f.file)
+ continue;
+
+- list_del(&kvg->node);
++ list_del(&kvf->node);
+ kvm_arch_end_assignment(dev->kvm);
+ #ifdef CONFIG_SPAPR_TCE_IOMMU
+- kvm_spapr_tce_release_vfio_group(dev->kvm, kvg);
++ kvm_spapr_tce_release_vfio_group(dev->kvm, kvf);
+ #endif
+- kvm_vfio_file_set_kvm(kvg->file, NULL);
+- fput(kvg->file);
+- kfree(kvg);
++ kvm_vfio_file_set_kvm(kvf->file, NULL);
++ fput(kvf->file);
++ kfree(kvf);
+ ret = 0;
+ break;
+ }
+@@ -234,12 +235,12 @@ static int kvm_vfio_group_del(struct kvm_device *dev, unsigned int fd)
+ }
+
+ #ifdef CONFIG_SPAPR_TCE_IOMMU
+-static int kvm_vfio_group_set_spapr_tce(struct kvm_device *dev,
+- void __user *arg)
++static int kvm_vfio_file_set_spapr_tce(struct kvm_device *dev,
++ void __user *arg)
+ {
+ struct kvm_vfio_spapr_tce param;
+ struct kvm_vfio *kv = dev->private;
+- struct kvm_vfio_group *kvg;
++ struct kvm_vfio_file *kvf;
+ struct fd f;
+ int ret;
+
+@@ -254,20 +255,20 @@ static int kvm_vfio_group_set_spapr_tce(struct kvm_device *dev,
+
+ mutex_lock(&kv->lock);
+
+- list_for_each_entry(kvg, &kv->group_list, node) {
+- if (kvg->file != f.file)
++ list_for_each_entry(kvf, &kv->file_list, node) {
++ if (kvf->file != f.file)
+ continue;
+
+- if (!kvg->iommu_group) {
+- kvg->iommu_group = kvm_vfio_file_iommu_group(kvg->file);
+- if (WARN_ON_ONCE(!kvg->iommu_group)) {
++ if (!kvf->iommu_group) {
++ kvf->iommu_group = kvm_vfio_file_iommu_group(kvf->file);
++ if (WARN_ON_ONCE(!kvf->iommu_group)) {
+ ret = -EIO;
+ goto err_fdput;
+ }
+ }
+
+ ret = kvm_spapr_tce_attach_iommu_group(dev->kvm, param.tablefd,
+- kvg->iommu_group);
++ kvf->iommu_group);
+ break;
+ }
+
+@@ -278,8 +279,8 @@ static int kvm_vfio_group_set_spapr_tce(struct kvm_device *dev,
+ }
+ #endif
+
+-static int kvm_vfio_set_group(struct kvm_device *dev, long attr,
+- void __user *arg)
++static int kvm_vfio_set_file(struct kvm_device *dev, long attr,
++ void __user *arg)
+ {
+ int32_t __user *argp = arg;
+ int32_t fd;
+@@ -288,16 +289,16 @@ static int kvm_vfio_set_group(struct kvm_device *dev, long attr,
+ case KVM_DEV_VFIO_GROUP_ADD:
+ if (get_user(fd, argp))
+ return -EFAULT;
+- return kvm_vfio_group_add(dev, fd);
++ return kvm_vfio_file_add(dev, fd);
+
+ case KVM_DEV_VFIO_GROUP_DEL:
+ if (get_user(fd, argp))
+ return -EFAULT;
+- return kvm_vfio_group_del(dev, fd);
++ return kvm_vfio_file_del(dev, fd);
+
+ #ifdef CONFIG_SPAPR_TCE_IOMMU
+ case KVM_DEV_VFIO_GROUP_SET_SPAPR_TCE:
+- return kvm_vfio_group_set_spapr_tce(dev, arg);
++ return kvm_vfio_file_set_spapr_tce(dev, arg);
+ #endif
+ }
+
+@@ -309,8 +310,8 @@ static int kvm_vfio_set_attr(struct kvm_device *dev,
+ {
+ switch (attr->group) {
+ case KVM_DEV_VFIO_GROUP:
+- return kvm_vfio_set_group(dev, attr->attr,
+- u64_to_user_ptr(attr->addr));
++ return kvm_vfio_set_file(dev, attr->attr,
++ u64_to_user_ptr(attr->addr));
+ }
+
+ return -ENXIO;
+@@ -339,16 +340,16 @@ static int kvm_vfio_has_attr(struct kvm_device *dev,
+ static void kvm_vfio_release(struct kvm_device *dev)
+ {
+ struct kvm_vfio *kv = dev->private;
+- struct kvm_vfio_group *kvg, *tmp;
++ struct kvm_vfio_file *kvf, *tmp;
+
+- list_for_each_entry_safe(kvg, tmp, &kv->group_list, node) {
++ list_for_each_entry_safe(kvf, tmp, &kv->file_list, node) {
+ #ifdef CONFIG_SPAPR_TCE_IOMMU
+- kvm_spapr_tce_release_vfio_group(dev->kvm, kvg);
++ kvm_spapr_tce_release_vfio_group(dev->kvm, kvf);
+ #endif
+- kvm_vfio_file_set_kvm(kvg->file, NULL);
+- fput(kvg->file);
+- list_del(&kvg->node);
+- kfree(kvg);
++ kvm_vfio_file_set_kvm(kvf->file, NULL);
++ fput(kvf->file);
++ list_del(&kvf->node);
++ kfree(kvf);
+ kvm_arch_end_assignment(dev->kvm);
+ }
+
+@@ -382,7 +383,7 @@ static int kvm_vfio_create(struct kvm_device *dev, u32 type)
+ if (!kv)
+ return -ENOMEM;
+
+- INIT_LIST_HEAD(&kv->group_list);
++ INIT_LIST_HEAD(&kv->file_list);
+ mutex_init(&kv->lock);
+
+ dev->private = kv;
+--
+2.40.1
+
--- /dev/null
+From 19d72358703646c22ccde0d4d4b347d9b571f9b0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Aug 2023 17:16:23 +0200
+Subject: leds: Fix BUG_ON check for LED_COLOR_ID_MULTI that is always false
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Marek Behún <kabel@kernel.org>
+
+[ Upstream commit c3f853184bed04105682383c2971798c572226b5 ]
+
+At the time we call
+ BUG_ON(props.color == LED_COLOR_ID_MULTI);
+the props variable is still initialized to zero.
+
+Call the BUG_ON only after we parse fwnode into props.
+
+Fixes: 77dce3a22e89 ("leds: disallow /sys/class/leds/*:multi:* for now")
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Link: https://lore.kernel.org/r/20230801151623.30387-1-kabel@kernel.org
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/leds/led-core.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c
+index 4a97cb7457888..aad8bc44459fe 100644
+--- a/drivers/leds/led-core.c
++++ b/drivers/leds/led-core.c
+@@ -419,15 +419,15 @@ int led_compose_name(struct device *dev, struct led_init_data *init_data,
+ struct fwnode_handle *fwnode = init_data->fwnode;
+ const char *devicename = init_data->devicename;
+
+- /* We want to label LEDs that can produce full range of colors
+- * as RGB, not multicolor */
+- BUG_ON(props.color == LED_COLOR_ID_MULTI);
+-
+ if (!led_classdev_name)
+ return -EINVAL;
+
+ led_parse_fwnode_props(dev, fwnode, &props);
+
++ /* We want to label LEDs that can produce full range of colors
++ * as RGB, not multicolor */
++ BUG_ON(props.color == LED_COLOR_ID_MULTI);
++
+ if (props.label) {
+ /*
+ * If init_data.devicename is NULL, then it indicates that
+--
+2.40.1
+
--- /dev/null
+From 4269672b5a47c3d1e6b84f8fb65a364ad001cae9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Aug 2023 14:49:31 +0200
+Subject: leds: multicolor: Use rounded division when calculating color
+ components
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Marek Behún <kabel@kernel.org>
+
+[ Upstream commit 065d099f1be58187e6629273c50b948a02b7e1bf ]
+
+Given channel intensity, LED brightness and max LED brightness, the
+multicolor LED framework helper led_mc_calc_color_components() computes
+the color channel brightness as
+
+ chan_brightness = brightness * chan_intensity / max_brightness
+
+Consider the situation when (brightness, intensity, max_brightness) is
+for example (16, 15, 255), then chan_brightness is computed to 0
+although the fractional divison would give 0.94, which should be rounded
+to 1.
+
+Use DIV_ROUND_CLOSEST here for the division to give more realistic
+component computation:
+
+ chan_brightness = DIV_ROUND_CLOSEST(brightness * chan_intensity,
+ max_brightness)
+
+Fixes: 55d5d3b46b08 ("leds: multicolor: Introduce a multicolor class definition")
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Link: https://lore.kernel.org/r/20230801124931.8661-1-kabel@kernel.org
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/leds/led-class-multicolor.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/leds/led-class-multicolor.c b/drivers/leds/led-class-multicolor.c
+index e317408583df9..ec62a48116135 100644
+--- a/drivers/leds/led-class-multicolor.c
++++ b/drivers/leds/led-class-multicolor.c
+@@ -6,6 +6,7 @@
+ #include <linux/device.h>
+ #include <linux/init.h>
+ #include <linux/led-class-multicolor.h>
++#include <linux/math.h>
+ #include <linux/module.h>
+ #include <linux/slab.h>
+ #include <linux/uaccess.h>
+@@ -19,9 +20,10 @@ int led_mc_calc_color_components(struct led_classdev_mc *mcled_cdev,
+ int i;
+
+ for (i = 0; i < mcled_cdev->num_colors; i++)
+- mcled_cdev->subled_info[i].brightness = brightness *
+- mcled_cdev->subled_info[i].intensity /
+- led_cdev->max_brightness;
++ mcled_cdev->subled_info[i].brightness =
++ DIV_ROUND_CLOSEST(brightness *
++ mcled_cdev->subled_info[i].intensity,
++ led_cdev->max_brightness);
+
+ return 0;
+ }
+--
+2.40.1
+
--- /dev/null
+From fbba6b10a7b6d1d183640811299e92cb7fc1e96e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Jul 2023 09:13:34 +0300
+Subject: leds: pwm: Fix error code in led_pwm_create_fwnode()
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit cadb2de2a7fd9e955381307de3eddfcc386c208e ]
+
+Negative -EINVAL was intended, not positive EINVAL. Fix it.
+
+Fixes: 95138e01275e ("leds: pwm: Make error handling more robust")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/a33b981a-b2c4-4dc2-b00a-626a090d2f11@moroto.mountain
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/leds/leds-pwm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c
+index 29194cc382afb..87c199242f3c8 100644
+--- a/drivers/leds/leds-pwm.c
++++ b/drivers/leds/leds-pwm.c
+@@ -146,7 +146,7 @@ static int led_pwm_create_fwnode(struct device *dev, struct led_pwm_priv *priv)
+ led.name = to_of_node(fwnode)->name;
+
+ if (!led.name) {
+- ret = EINVAL;
++ ret = -EINVAL;
+ goto err_child_out;
+ }
+
+--
+2.40.1
+
--- /dev/null
+From b805cd6c738ed6b1ccfd8a1c0d46cd4e54a685ae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Aug 2023 11:07:53 +0200
+Subject: leds: trigger: tty: Do not use LED_ON/OFF constants, use
+ led_blink_set_oneshot instead
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Marek Behún <kabel@kernel.org>
+
+[ Upstream commit 730094577e0c37e1bc40be37cbd41f71b0a8a2a4 ]
+
+The tty LED trigger uses the obsolete LED_ON & LED_OFF constants when
+setting LED brightness. This is bad because the LED_ON constant is equal
+to 1, and so when activating the tty LED trigger on a LED class device
+with max_brightness greater than 1, the LED is dimmer than it can be
+(when max_brightness is 255, the LED is very dimm indeed; some devices
+translate 1/255 to 0, so the LED is OFF all the time).
+
+Instead of directly setting brightness to a specific value, use the
+led_blink_set_oneshot() function from LED core to configure the blink.
+This function takes the current configured brightness as blink
+brightness if not zero, and max brightness otherwise.
+
+This also changes the behavior of the TTY LED trigger. Previously if
+rx/tx stats kept changing, the LED was ON all the time they kept
+changing. With this patch the LED will blink on TTY activity.
+
+Fixes: fd4a641ac88f ("leds: trigger: implement a tty trigger")
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Link: https://lore.kernel.org/r/20230802090753.13611-1-kabel@kernel.org
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/leds/trigger/ledtrig-tty.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/leds/trigger/ledtrig-tty.c b/drivers/leds/trigger/ledtrig-tty.c
+index f62db7e520b52..8ae0d2d284aff 100644
+--- a/drivers/leds/trigger/ledtrig-tty.c
++++ b/drivers/leds/trigger/ledtrig-tty.c
+@@ -7,6 +7,8 @@
+ #include <linux/tty.h>
+ #include <uapi/linux/serial.h>
+
++#define LEDTRIG_TTY_INTERVAL 50
++
+ struct ledtrig_tty_data {
+ struct led_classdev *led_cdev;
+ struct delayed_work dwork;
+@@ -122,17 +124,19 @@ static void ledtrig_tty_work(struct work_struct *work)
+
+ if (icount.rx != trigger_data->rx ||
+ icount.tx != trigger_data->tx) {
+- led_set_brightness_sync(trigger_data->led_cdev, LED_ON);
++ unsigned long interval = LEDTRIG_TTY_INTERVAL;
++
++ led_blink_set_oneshot(trigger_data->led_cdev, &interval,
++ &interval, 0);
+
+ trigger_data->rx = icount.rx;
+ trigger_data->tx = icount.tx;
+- } else {
+- led_set_brightness_sync(trigger_data->led_cdev, LED_OFF);
+ }
+
+ out:
+ mutex_unlock(&trigger_data->mutex);
+- schedule_delayed_work(&trigger_data->dwork, msecs_to_jiffies(100));
++ schedule_delayed_work(&trigger_data->dwork,
++ msecs_to_jiffies(LEDTRIG_TTY_INTERVAL * 2));
+ }
+
+ static struct attribute *ledtrig_tty_attrs[] = {
+--
+2.40.1
+
--- /dev/null
+From a855ce58027086dcdaf9f514d5cde6ca2da838a0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Jul 2023 19:41:50 -0700
+Subject: libbpf: Fix realloc API handling in zero-sized edge cases
+
+From: Andrii Nakryiko <andrii@kernel.org>
+
+[ Upstream commit 8a0260dbf6553c969248b6530cafadac46562f47 ]
+
+realloc() and reallocarray() can either return NULL or a special
+non-NULL pointer, if their size argument is zero. This requires a bit
+more care to handle NULL-as-valid-result situation differently from
+NULL-as-error case. This has caused real issues before ([0]), and just
+recently bit again in production when performing bpf_program__attach_usdt().
+
+This patch fixes 4 places that do or potentially could suffer from this
+mishandling of NULL, including the reported USDT-related one.
+
+There are many other places where realloc()/reallocarray() is used and
+NULL is always treated as an error value, but all those have guarantees
+that their size is always non-zero, so those spot don't need any extra
+handling.
+
+ [0] d08ab82f59d5 ("libbpf: Fix double-free when linker processes empty sections")
+
+Fixes: 999783c8bbda ("libbpf: Wire up spec management and other arch-independent USDT logic")
+Fixes: b63b3c490eee ("libbpf: Add bpf_program__set_insns function")
+Fixes: 697f104db8a6 ("libbpf: Support custom SEC() handlers")
+Fixes: b12688267280 ("libbpf: Change the order of data and text relocations.")
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Link: https://lore.kernel.org/bpf/20230711024150.1566433-1-andrii@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/libbpf.c | 15 ++++++++++++---
+ tools/lib/bpf/usdt.c | 5 ++++-
+ 2 files changed, 16 insertions(+), 4 deletions(-)
+
+diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
+index 57c040a9c3705..2a4dbe7d9b3d4 100644
+--- a/tools/lib/bpf/libbpf.c
++++ b/tools/lib/bpf/libbpf.c
+@@ -6136,7 +6136,11 @@ static int append_subprog_relos(struct bpf_program *main_prog, struct bpf_progra
+ if (main_prog == subprog)
+ return 0;
+ relos = libbpf_reallocarray(main_prog->reloc_desc, new_cnt, sizeof(*relos));
+- if (!relos)
++ /* if new count is zero, reallocarray can return a valid NULL result;
++ * in this case the previous pointer will be freed, so we *have to*
++ * reassign old pointer to the new value (even if it's NULL)
++ */
++ if (!relos && new_cnt)
+ return -ENOMEM;
+ if (subprog->nr_reloc)
+ memcpy(relos + main_prog->nr_reloc, subprog->reloc_desc,
+@@ -8504,7 +8508,8 @@ int bpf_program__set_insns(struct bpf_program *prog,
+ return -EBUSY;
+
+ insns = libbpf_reallocarray(prog->insns, new_insn_cnt, sizeof(*insns));
+- if (!insns) {
++ /* NULL is a valid return from reallocarray if the new count is zero */
++ if (!insns && new_insn_cnt) {
+ pr_warn("prog '%s': failed to realloc prog code\n", prog->name);
+ return -ENOMEM;
+ }
+@@ -8813,7 +8818,11 @@ int libbpf_unregister_prog_handler(int handler_id)
+
+ /* try to shrink the array, but it's ok if we couldn't */
+ sec_defs = libbpf_reallocarray(custom_sec_defs, custom_sec_def_cnt, sizeof(*sec_defs));
+- if (sec_defs)
++ /* if new count is zero, reallocarray can return a valid NULL result;
++ * in this case the previous pointer will be freed, so we *have to*
++ * reassign old pointer to the new value (even if it's NULL)
++ */
++ if (sec_defs || custom_sec_def_cnt == 0)
+ custom_sec_defs = sec_defs;
+
+ return 0;
+diff --git a/tools/lib/bpf/usdt.c b/tools/lib/bpf/usdt.c
+index 086eef355ab3d..1af77f9935833 100644
+--- a/tools/lib/bpf/usdt.c
++++ b/tools/lib/bpf/usdt.c
+@@ -852,8 +852,11 @@ static int bpf_link_usdt_detach(struct bpf_link *link)
+ * system is so exhausted on memory, it's the least of user's
+ * concerns, probably.
+ * So just do our best here to return those IDs to usdt_manager.
++ * Another edge case when we can legitimately get NULL is when
++ * new_cnt is zero, which can happen in some edge cases, so we
++ * need to be careful about that.
+ */
+- if (new_free_ids) {
++ if (new_free_ids || new_cnt == 0) {
+ memcpy(new_free_ids + man->free_spec_cnt, usdt_link->spec_ids,
+ usdt_link->spec_cnt * sizeof(*usdt_link->spec_ids));
+ man->free_spec_ids = new_free_ids;
+--
+2.40.1
+
--- /dev/null
+From ee9a803a5a3f4af7baaac8ffb5afb96abdb53d71 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Jul 2023 16:11:56 -0700
+Subject: libbpf: only reset sec_def handler when necessary
+
+From: Andrii Nakryiko <andrii@kernel.org>
+
+[ Upstream commit c628747cc8800cf6d33d09f7f42c8b6f91e64dc7 ]
+
+Don't reset recorded sec_def handler unconditionally on
+bpf_program__set_type(). There are two situations where this is wrong.
+
+First, if the program type didn't actually change. In that case original
+SEC handler should work just fine.
+
+Second, catch-all custom SEC handler is supposed to work with any BPF
+program type and SEC() annotation, so it also doesn't make sense to
+reset that.
+
+This patch fixes both issues. This was reported recently in the context
+of breaking perf tool, which uses custom catch-all handler for fancy BPF
+prologue generation logic. This patch should fix the issue.
+
+ [0] https://lore.kernel.org/linux-perf-users/ab865e6d-06c5-078e-e404-7f90686db50d@amd.com/
+
+Fixes: d6e6286a12e7 ("libbpf: disassociate section handler on explicit bpf_program__set_type() call")
+Reported-by: Ravi Bangoria <ravi.bangoria@amd.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Acked-by: Stanislav Fomichev <sdf@google.com>
+Link: https://lore.kernel.org/r/20230707231156.1711948-1-andrii@kernel.org
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/libbpf.c | 27 +++++++++++++++++++--------
+ 1 file changed, 19 insertions(+), 8 deletions(-)
+
+diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
+index a27f6e9ccce75..57c040a9c3705 100644
+--- a/tools/lib/bpf/libbpf.c
++++ b/tools/lib/bpf/libbpf.c
+@@ -8534,13 +8534,31 @@ enum bpf_prog_type bpf_program__type(const struct bpf_program *prog)
+ return prog->type;
+ }
+
++static size_t custom_sec_def_cnt;
++static struct bpf_sec_def *custom_sec_defs;
++static struct bpf_sec_def custom_fallback_def;
++static bool has_custom_fallback_def;
++static int last_custom_sec_def_handler_id;
++
+ int bpf_program__set_type(struct bpf_program *prog, enum bpf_prog_type type)
+ {
+ if (prog->obj->loaded)
+ return libbpf_err(-EBUSY);
+
++ /* if type is not changed, do nothing */
++ if (prog->type == type)
++ return 0;
++
+ prog->type = type;
+- prog->sec_def = NULL;
++
++ /* If a program type was changed, we need to reset associated SEC()
++ * handler, as it will be invalid now. The only exception is a generic
++ * fallback handler, which by definition is program type-agnostic and
++ * is a catch-all custom handler, optionally set by the application,
++ * so should be able to handle any type of BPF program.
++ */
++ if (prog->sec_def != &custom_fallback_def)
++ prog->sec_def = NULL;
+ return 0;
+ }
+
+@@ -8716,13 +8734,6 @@ static const struct bpf_sec_def section_defs[] = {
+ SEC_DEF("netfilter", NETFILTER, BPF_NETFILTER, SEC_NONE),
+ };
+
+-static size_t custom_sec_def_cnt;
+-static struct bpf_sec_def *custom_sec_defs;
+-static struct bpf_sec_def custom_fallback_def;
+-static bool has_custom_fallback_def;
+-
+-static int last_custom_sec_def_handler_id;
+-
+ int libbpf_register_prog_handler(const char *sec,
+ enum bpf_prog_type prog_type,
+ enum bpf_attach_type exp_attach_type,
+--
+2.40.1
+
--- /dev/null
+From 4715c90c25fd6f056c8d952e2332be60e08aaf92 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Jul 2023 11:00:36 +0200
+Subject: locking/arch: Avoid variable shadowing in local_try_cmpxchg()
+
+From: Uros Bizjak <ubizjak@gmail.com>
+
+[ Upstream commit d6b45484c130f4095313ae3edeb4aae662c12fb1 ]
+
+Several architectures define arch_try_local_cmpxchg macro using
+internal temporary variables named ___old, __old or _old. Remove
+temporary varible in local_try_cmpxchg to avoid variable shadowing.
+
+No functional change intended.
+
+Fixes: d994f2c8e241 ("locking/arch: Wire up local_try_cmpxchg()")
+Closes: https://lore.kernel.org/lkml/CAFGhKbyxtuk=LoW-E3yLXgcmR93m+Dfo5-u9oQA_YC5Fcy_t9g@mail.gmail.com/
+Reported-by: Charlemagne Lasse <charlemagnelasse@gmail.com>
+Signed-off-by: Uros Bizjak <ubizjak@gmail.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lkml.kernel.org/r/20230708090048.63046-1-ubizjak@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/loongarch/include/asm/local.h | 4 ++--
+ arch/mips/include/asm/local.h | 4 ++--
+ arch/x86/include/asm/local.h | 4 ++--
+ 3 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/arch/loongarch/include/asm/local.h b/arch/loongarch/include/asm/local.h
+index 83e995b30e472..c49675852bdcd 100644
+--- a/arch/loongarch/include/asm/local.h
++++ b/arch/loongarch/include/asm/local.h
+@@ -63,8 +63,8 @@ static inline long local_cmpxchg(local_t *l, long old, long new)
+
+ static inline bool local_try_cmpxchg(local_t *l, long *old, long new)
+ {
+- typeof(l->a.counter) *__old = (typeof(l->a.counter) *) old;
+- return try_cmpxchg_local(&l->a.counter, __old, new);
++ return try_cmpxchg_local(&l->a.counter,
++ (typeof(l->a.counter) *) old, new);
+ }
+
+ #define local_xchg(l, n) (atomic_long_xchg((&(l)->a), (n)))
+diff --git a/arch/mips/include/asm/local.h b/arch/mips/include/asm/local.h
+index 5daf6fe8e3e9a..e6ae3df0349d2 100644
+--- a/arch/mips/include/asm/local.h
++++ b/arch/mips/include/asm/local.h
+@@ -101,8 +101,8 @@ static __inline__ long local_cmpxchg(local_t *l, long old, long new)
+
+ static __inline__ bool local_try_cmpxchg(local_t *l, long *old, long new)
+ {
+- typeof(l->a.counter) *__old = (typeof(l->a.counter) *) old;
+- return try_cmpxchg_local(&l->a.counter, __old, new);
++ return try_cmpxchg_local(&l->a.counter,
++ (typeof(l->a.counter) *) old, new);
+ }
+
+ #define local_xchg(l, n) (atomic_long_xchg((&(l)->a), (n)))
+diff --git a/arch/x86/include/asm/local.h b/arch/x86/include/asm/local.h
+index 56d4ef604b919..635132a127782 100644
+--- a/arch/x86/include/asm/local.h
++++ b/arch/x86/include/asm/local.h
+@@ -127,8 +127,8 @@ static inline long local_cmpxchg(local_t *l, long old, long new)
+
+ static inline bool local_try_cmpxchg(local_t *l, long *old, long new)
+ {
+- typeof(l->a.counter) *__old = (typeof(l->a.counter) *) old;
+- return try_cmpxchg_local(&l->a.counter, __old, new);
++ return try_cmpxchg_local(&l->a.counter,
++ (typeof(l->a.counter) *) old, new);
+ }
+
+ /* Always has a lock prefix */
+--
+2.40.1
+
--- /dev/null
+From 89940680f032e7eabc1201abac4ff915f2d2b8fb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Aug 2023 19:58:14 -0700
+Subject: lwt: Check LWTUNNEL_XMIT_CONTINUE strictly
+
+From: Yan Zhai <yan@cloudflare.com>
+
+[ Upstream commit a171fbec88a2c730b108c7147ac5e7b2f5a02b47 ]
+
+LWTUNNEL_XMIT_CONTINUE is implicitly assumed in ip(6)_finish_output2,
+such that any positive return value from a xmit hook could cause
+unexpected continue behavior, despite that related skb may have been
+freed. This could be error-prone for future xmit hook ops. One of the
+possible errors is to return statuses of dst_output directly.
+
+To make the code safer, redefine LWTUNNEL_XMIT_CONTINUE value to
+distinguish from dst_output statuses and check the continue
+condition explicitly.
+
+Fixes: 3a0af8fd61f9 ("bpf: BPF for lightweight tunnel infrastructure")
+Suggested-by: Dan Carpenter <dan.carpenter@linaro.org>
+Signed-off-by: Yan Zhai <yan@cloudflare.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Link: https://lore.kernel.org/bpf/96b939b85eda00e8df4f7c080f770970a4c5f698.1692326837.git.yan@cloudflare.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/lwtunnel.h | 5 ++++-
+ net/ipv4/ip_output.c | 2 +-
+ net/ipv6/ip6_output.c | 2 +-
+ 3 files changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/include/net/lwtunnel.h b/include/net/lwtunnel.h
+index 6f15e6fa154e6..53bd2d02a4f0d 100644
+--- a/include/net/lwtunnel.h
++++ b/include/net/lwtunnel.h
+@@ -16,9 +16,12 @@
+ #define LWTUNNEL_STATE_INPUT_REDIRECT BIT(1)
+ #define LWTUNNEL_STATE_XMIT_REDIRECT BIT(2)
+
++/* LWTUNNEL_XMIT_CONTINUE should be distinguishable from dst_output return
++ * values (NET_XMIT_xxx and NETDEV_TX_xxx in linux/netdevice.h) for safety.
++ */
+ enum {
+ LWTUNNEL_XMIT_DONE,
+- LWTUNNEL_XMIT_CONTINUE,
++ LWTUNNEL_XMIT_CONTINUE = 0x100,
+ };
+
+
+diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
+index 6f6f63cf9224f..625da48741a4f 100644
+--- a/net/ipv4/ip_output.c
++++ b/net/ipv4/ip_output.c
+@@ -216,7 +216,7 @@ static int ip_finish_output2(struct net *net, struct sock *sk, struct sk_buff *s
+ if (lwtunnel_xmit_redirect(dst->lwtstate)) {
+ int res = lwtunnel_xmit(skb);
+
+- if (res < 0 || res == LWTUNNEL_XMIT_DONE)
++ if (res != LWTUNNEL_XMIT_CONTINUE)
+ return res;
+ }
+
+diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
+index 4a27fab1d09a3..50f8d2ac4e246 100644
+--- a/net/ipv6/ip6_output.c
++++ b/net/ipv6/ip6_output.c
+@@ -113,7 +113,7 @@ static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff *
+ if (lwtunnel_xmit_redirect(dst->lwtstate)) {
+ int res = lwtunnel_xmit(skb);
+
+- if (res < 0 || res == LWTUNNEL_XMIT_DONE)
++ if (res != LWTUNNEL_XMIT_CONTINUE)
+ return res;
+ }
+
+--
+2.40.1
+
--- /dev/null
+From c41c64dbe8f19aba2c791bb7dc275e53b7876ebd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Aug 2023 19:58:11 -0700
+Subject: lwt: Fix return values of BPF xmit ops
+
+From: Yan Zhai <yan@cloudflare.com>
+
+[ Upstream commit 29b22badb7a84b783e3a4fffca16f7768fb31205 ]
+
+BPF encap ops can return different types of positive values, such like
+NET_RX_DROP, NET_XMIT_CN, NETDEV_TX_BUSY, and so on, from function
+skb_do_redirect and bpf_lwt_xmit_reroute. At the xmit hook, such return
+values would be treated implicitly as LWTUNNEL_XMIT_CONTINUE in
+ip(6)_finish_output2. When this happens, skbs that have been freed would
+continue to the neighbor subsystem, causing use-after-free bug and
+kernel crashes.
+
+To fix the incorrect behavior, skb_do_redirect return values can be
+simply discarded, the same as tc-egress behavior. On the other hand,
+bpf_lwt_xmit_reroute returns useful errors to local senders, e.g. PMTU
+information. Thus convert its return values to avoid the conflict with
+LWTUNNEL_XMIT_CONTINUE.
+
+Fixes: 3a0af8fd61f9 ("bpf: BPF for lightweight tunnel infrastructure")
+Reported-by: Jordan Griege <jgriege@cloudflare.com>
+Suggested-by: Martin KaFai Lau <martin.lau@linux.dev>
+Suggested-by: Stanislav Fomichev <sdf@google.com>
+Signed-off-by: Yan Zhai <yan@cloudflare.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Link: https://lore.kernel.org/bpf/0d2b878186cfe215fec6b45769c1cd0591d3628d.1692326837.git.yan@cloudflare.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/lwt_bpf.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/net/core/lwt_bpf.c b/net/core/lwt_bpf.c
+index 8b6b5e72b2179..4a0797f0a154b 100644
+--- a/net/core/lwt_bpf.c
++++ b/net/core/lwt_bpf.c
+@@ -60,9 +60,8 @@ static int run_lwt_bpf(struct sk_buff *skb, struct bpf_lwt_prog *lwt,
+ ret = BPF_OK;
+ } else {
+ skb_reset_mac_header(skb);
+- ret = skb_do_redirect(skb);
+- if (ret == 0)
+- ret = BPF_REDIRECT;
++ skb_do_redirect(skb);
++ ret = BPF_REDIRECT;
+ }
+ break;
+
+@@ -255,7 +254,7 @@ static int bpf_lwt_xmit_reroute(struct sk_buff *skb)
+
+ err = dst_output(dev_net(skb_dst(skb)->dev), skb->sk, skb);
+ if (unlikely(err))
+- return err;
++ return net_xmit_errno(err);
+
+ /* ip[6]_finish_output2 understand LWTUNNEL_XMIT_DONE */
+ return LWTUNNEL_XMIT_DONE;
+--
+2.40.1
+
--- /dev/null
+From 915f96a75ef660cc9bf4dbbca8e35b8a8d7a87d9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Jun 2023 17:24:00 +0200
+Subject: mac80211: make ieee80211_tx_info padding explicit
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit a7a2ef0c4b3efbd7d6f3fabd87dbbc0b3f2de5af ]
+
+While looking at a bug, I got rather confused by the layout of the
+'status' field in ieee80211_tx_info. Apparently, the intention is that
+status_driver_data[] is used for driver specific data, and fills up the
+size of the union to 40 bytes, just like the other ones.
+
+This is indeed what actually happens, but only because of the
+combination of two mistakes:
+
+ - "void *status_driver_data[18 / sizeof(void *)];" is intended
+ to be 18 bytes long but is actually two bytes shorter because of
+ rounding-down in the division, to a multiple of the pointer
+ size (4 bytes or 8 bytes).
+
+ - The other fields combined are intended to be 22 bytes long, but
+ are actually 24 bytes because of padding in front of the
+ unaligned tx_time member, and in front of the pointer array.
+
+The two mistakes cancel out. so the size ends up fine, but it seems
+more helpful to make this explicit, by having a multiple of 8 bytes
+in the size calculation and explicitly describing the padding.
+
+Fixes: ea5907db2a9cc ("mac80211: fix struct ieee80211_tx_info size")
+Fixes: 02219b3abca59 ("mac80211: add WMM admission control support")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Link: https://lore.kernel.org/r/20230623152443.2296825-2-arnd@kernel.org
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/mac80211.h | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/include/net/mac80211.h b/include/net/mac80211.h
+index 67d81f7186660..52b336ada480c 100644
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -1192,9 +1192,11 @@ struct ieee80211_tx_info {
+ u8 ampdu_ack_len;
+ u8 ampdu_len;
+ u8 antenna;
++ u8 pad;
+ u16 tx_time;
+ u8 flags;
+- void *status_driver_data[18 / sizeof(void *)];
++ u8 pad2;
++ void *status_driver_data[16 / sizeof(void *)];
+ } status;
+ struct {
+ struct ieee80211_tx_rate driver_rates[
+--
+2.40.1
+
--- /dev/null
+From aec05416961ee4fbef08172410dc7fea14dbc43f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Jul 2023 16:37:27 +0800
+Subject: md/md-bitmap: hold 'reconfig_mutex' in backlog_store()
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+[ Upstream commit 44abfa6a95df425c0660d56043020b67e6d93ab8 ]
+
+Several reasons why 'reconfig_mutex' should be held:
+
+1) rdev_for_each() is not safe to be called without the lock, because
+ rdev can be removed concurrently.
+2) mddev_destroy_serial_pool() and mddev_create_serial_pool() should not
+ be called concurrently.
+3) mddev_suspend() from mddev_destroy/create_serial_pool() should be
+ protected by the lock.
+
+Fixes: 10c92fca636e ("md-bitmap: create and destroy wb_info_pool with the change of backlog")
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Link: https://lore.kernel.org/r/20230706083727.608914-3-yukuai1@huaweicloud.com
+Signed-off-by: Song Liu <song@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/md-bitmap.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
+index 4934d8f0cf11a..ba6b4819d37e4 100644
+--- a/drivers/md/md-bitmap.c
++++ b/drivers/md/md-bitmap.c
+@@ -2504,6 +2504,10 @@ backlog_store(struct mddev *mddev, const char *buf, size_t len)
+ if (backlog > COUNTER_MAX)
+ return -EINVAL;
+
++ rv = mddev_lock(mddev);
++ if (rv)
++ return rv;
++
+ /*
+ * Without write mostly device, it doesn't make sense to set
+ * backlog for max_write_behind.
+@@ -2517,6 +2521,7 @@ backlog_store(struct mddev *mddev, const char *buf, size_t len)
+ if (!has_write_mostly) {
+ pr_warn_ratelimited("%s: can't set backlog, no write mostly device available\n",
+ mdname(mddev));
++ mddev_unlock(mddev);
+ return -EINVAL;
+ }
+
+@@ -2532,6 +2537,8 @@ backlog_store(struct mddev *mddev, const char *buf, size_t len)
+ }
+ if (old_mwb != backlog)
+ md_bitmap_update_sb(mddev->bitmap);
++
++ mddev_unlock(mddev);
+ return len;
+ }
+
+--
+2.40.1
+
--- /dev/null
+From de0f50fbeae5cb1d279b74eba348285f397de2e4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Jul 2023 16:37:26 +0800
+Subject: md/md-bitmap: remove unnecessary local variable in backlog_store()
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+[ Upstream commit b4d129640f194ffc4cc64c3e97f98ae944c072e8 ]
+
+Local variable is definied first in the beginning of backlog_store(),
+there is no need to define it again.
+
+Fixes: 8c13ab115b57 ("md/bitmap: don't set max_write_behind if there is no write mostly device")
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Link: https://lore.kernel.org/r/20230706083727.608914-2-yukuai1@huaweicloud.com
+Signed-off-by: Song Liu <song@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/md-bitmap.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
+index ea226a37b110a..4934d8f0cf11a 100644
+--- a/drivers/md/md-bitmap.c
++++ b/drivers/md/md-bitmap.c
+@@ -2527,8 +2527,6 @@ backlog_store(struct mddev *mddev, const char *buf, size_t len)
+ mddev_destroy_serial_pool(mddev, NULL, false);
+ } else if (backlog && !mddev->serial_info_pool) {
+ /* serial_info_pool is needed since backlog is not zero */
+- struct md_rdev *rdev;
+-
+ rdev_for_each(rdev, mddev)
+ mddev_create_serial_pool(mddev, rdev, false);
+ }
+--
+2.40.1
+
--- /dev/null
+From 03eaa14a6821412916cdf38c54c81f9824973220 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Aug 2023 14:13:55 -0400
+Subject: md: raid0: account for split bio in iostat accounting
+
+From: David Jeffery <djeffery@redhat.com>
+
+[ Upstream commit cc22b5407e9ca76adb7efeed843146510b1b72a5 ]
+
+When a bio is split by md raid0, the newly created bio will not be tracked
+by md for I/O accounting. Only the portion of I/O still assigned to the
+original bio which was reduced by the split will be accounted for. This
+results in md iostat data sometimes showing I/O values far below the actual
+amount of data being sent through md.
+
+md_account_bio() needs to be called for all bio generated by the bio split.
+
+A simple example of the issue was generated using a raid0 device on partitions
+to the same device. Since all raid0 I/O then goes to one device, it makes it
+easy to see a gap between the md device and its sd storage. Reading an lvm
+device on top of the md device, the iostat output (some 0 columns and extra
+devices removed to make the data more compact) was:
+
+Device tps kB_read/s kB_wrtn/s kB_dscd/s kB_read
+md2 0.00 0.00 0.00 0.00 0
+sde 0.00 0.00 0.00 0.00 0
+md2 1364.00 411496.00 0.00 0.00 411496
+sde 1734.00 646144.00 0.00 0.00 646144
+md2 1699.00 510680.00 0.00 0.00 510680
+sde 2155.00 802784.00 0.00 0.00 802784
+md2 803.00 241480.00 0.00 0.00 241480
+sde 1016.00 377888.00 0.00 0.00 377888
+md2 0.00 0.00 0.00 0.00 0
+sde 0.00 0.00 0.00 0.00 0
+
+I/O was generated doing large direct I/O reads (12M) with dd to a linear
+lvm volume on top of the 4 leg raid0 device.
+
+The md2 reads were showing as roughly 2/3 of the reads to the sde device
+containing all of md2's raid partitions. The sum of reads to sde was
+1826816 kB, which was the expected amount as it was the amount read by
+dd. With the patch, the total reads from md will match the reads from
+sde and be consistent with the amount of I/O generated.
+
+Fixes: 10764815ff47 ("md: add io accounting for raid0 and raid5")
+Signed-off-by: David Jeffery <djeffery@redhat.com>
+Tested-by: Laurence Oberman <loberman@redhat.com>
+Reviewed-by: Laurence Oberman <loberman@redhat.com>
+Reviewed-by: Yu Kuai <yukuai3@huawei.com>
+Signed-off-by: Song Liu <song@kernel.org>
+Link: https://lore.kernel.org/r/20230816181433.13289-1-djeffery@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/raid0.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
+index 595856948dff8..7c6a0b4437d8f 100644
+--- a/drivers/md/raid0.c
++++ b/drivers/md/raid0.c
+@@ -565,8 +565,7 @@ static void raid0_map_submit_bio(struct mddev *mddev, struct bio *bio)
+ sector_t bio_sector = bio->bi_iter.bi_sector;
+ sector_t sector = bio_sector;
+
+- if (bio->bi_pool != &mddev->bio_set)
+- md_account_bio(mddev, &bio);
++ md_account_bio(mddev, &bio);
+
+ zone = find_zone(mddev->private, §or);
+ switch (conf->layout) {
+--
+2.40.1
+
--- /dev/null
+From 3e458c6849525d20dfc70dd7e324997878a2d8cc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Aug 2023 11:27:07 +0200
+Subject: md/raid0: Factor out helper for mapping and submitting a bio
+
+From: Jan Kara <jack@suse.cz>
+
+[ Upstream commit af50e20afb401cc203bd2a9ff62ece0ae4976103 ]
+
+Factor out helper function for mapping and submitting a bio out of
+raid0_make_request(). We will use it later for submitting both parts of
+a split bio.
+
+Signed-off-by: Jan Kara <jack@suse.cz>
+Reviewed-by: Yu Kuai <yukuai3@huawei.com>
+Link: https://lore.kernel.org/r/20230814092720.3931-1-jack@suse.cz
+Signed-off-by: Song Liu <song@kernel.org>
+Stable-dep-of: 319ff40a5427 ("md/raid0: Fix performance regression for large sequential writes")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/raid0.c | 79 +++++++++++++++++++++++-----------------------
+ 1 file changed, 40 insertions(+), 39 deletions(-)
+
+diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
+index d1ac73fcd8529..d3c55f2e9b185 100644
+--- a/drivers/md/raid0.c
++++ b/drivers/md/raid0.c
+@@ -557,54 +557,21 @@ static void raid0_handle_discard(struct mddev *mddev, struct bio *bio)
+ bio_endio(bio);
+ }
+
+-static bool raid0_make_request(struct mddev *mddev, struct bio *bio)
++static void raid0_map_submit_bio(struct mddev *mddev, struct bio *bio)
+ {
+ struct r0conf *conf = mddev->private;
+ struct strip_zone *zone;
+ struct md_rdev *tmp_dev;
+- sector_t bio_sector;
+- sector_t sector;
+- sector_t orig_sector;
+- unsigned chunk_sects;
+- unsigned sectors;
+-
+- if (unlikely(bio->bi_opf & REQ_PREFLUSH)
+- && md_flush_request(mddev, bio))
+- return true;
+-
+- if (unlikely((bio_op(bio) == REQ_OP_DISCARD))) {
+- raid0_handle_discard(mddev, bio);
+- return true;
+- }
+-
+- bio_sector = bio->bi_iter.bi_sector;
+- sector = bio_sector;
+- chunk_sects = mddev->chunk_sectors;
+-
+- sectors = chunk_sects -
+- (likely(is_power_of_2(chunk_sects))
+- ? (sector & (chunk_sects-1))
+- : sector_div(sector, chunk_sects));
+-
+- /* Restore due to sector_div */
+- sector = bio_sector;
+-
+- if (sectors < bio_sectors(bio)) {
+- struct bio *split = bio_split(bio, sectors, GFP_NOIO,
+- &mddev->bio_set);
+- bio_chain(split, bio);
+- submit_bio_noacct(bio);
+- bio = split;
+- }
++ sector_t bio_sector = bio->bi_iter.bi_sector;
++ sector_t sector = bio_sector;
+
+ if (bio->bi_pool != &mddev->bio_set)
+ md_account_bio(mddev, &bio);
+
+- orig_sector = sector;
+ zone = find_zone(mddev->private, §or);
+ switch (conf->layout) {
+ case RAID0_ORIG_LAYOUT:
+- tmp_dev = map_sector(mddev, zone, orig_sector, §or);
++ tmp_dev = map_sector(mddev, zone, bio_sector, §or);
+ break;
+ case RAID0_ALT_MULTIZONE_LAYOUT:
+ tmp_dev = map_sector(mddev, zone, sector, §or);
+@@ -612,13 +579,13 @@ static bool raid0_make_request(struct mddev *mddev, struct bio *bio)
+ default:
+ WARN(1, "md/raid0:%s: Invalid layout\n", mdname(mddev));
+ bio_io_error(bio);
+- return true;
++ return;
+ }
+
+ if (unlikely(is_rdev_broken(tmp_dev))) {
+ bio_io_error(bio);
+ md_error(mddev, tmp_dev);
+- return true;
++ return;
+ }
+
+ bio_set_dev(bio, tmp_dev->bdev);
+@@ -630,6 +597,40 @@ static bool raid0_make_request(struct mddev *mddev, struct bio *bio)
+ bio_sector);
+ mddev_check_write_zeroes(mddev, bio);
+ submit_bio_noacct(bio);
++}
++
++static bool raid0_make_request(struct mddev *mddev, struct bio *bio)
++{
++ sector_t sector;
++ unsigned chunk_sects;
++ unsigned sectors;
++
++ if (unlikely(bio->bi_opf & REQ_PREFLUSH)
++ && md_flush_request(mddev, bio))
++ return true;
++
++ if (unlikely((bio_op(bio) == REQ_OP_DISCARD))) {
++ raid0_handle_discard(mddev, bio);
++ return true;
++ }
++
++ sector = bio->bi_iter.bi_sector;
++ chunk_sects = mddev->chunk_sectors;
++
++ sectors = chunk_sects -
++ (likely(is_power_of_2(chunk_sects))
++ ? (sector & (chunk_sects-1))
++ : sector_div(sector, chunk_sects));
++
++ if (sectors < bio_sectors(bio)) {
++ struct bio *split = bio_split(bio, sectors, GFP_NOIO,
++ &mddev->bio_set);
++ bio_chain(split, bio);
++ submit_bio_noacct(bio);
++ bio = split;
++ }
++
++ raid0_map_submit_bio(mddev, bio);
+ return true;
+ }
+
+--
+2.40.1
+
--- /dev/null
+From ab94968e2961a52f60ccca4636975ed00effa4bc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Aug 2023 11:27:08 +0200
+Subject: md/raid0: Fix performance regression for large sequential writes
+
+From: Jan Kara <jack@suse.cz>
+
+[ Upstream commit 319ff40a542736d67e5bce18635de35d0e7a0bff ]
+
+Commit f00d7c85be9e ("md/raid0: fix up bio splitting.") among other
+things changed how bio that needs to be split is submitted. Before this
+commit, we have split the bio, mapped and submitted each part. After
+this commit, we map only the first part of the split bio and submit the
+second part unmapped. Due to bio sorting in __submit_bio_noacct() this
+results in the following request ordering:
+
+ 9,0 18 1181 0.525037895 15995 Q WS 1479315464 + 63392
+
+ Split off chunk-sized (1024 sectors) request:
+
+ 9,0 18 1182 0.629019647 15995 X WS 1479315464 / 1479316488
+
+ Request is unaligned to the chunk so it's split in
+ raid0_make_request(). This is the first part mapped and punted to
+ bio_list:
+
+ 8,0 18 7053 0.629020455 15995 A WS 739921928 + 1016 <- (9,0) 1479315464
+
+ Now raid0_make_request() returns, second part is postponed on
+ bio_list. __submit_bio_noacct() resorts the bio_list, mapped request
+ is submitted to the underlying device:
+
+ 8,0 18 7054 0.629022782 15995 G WS 739921928 + 1016
+
+ Now we take another request from the bio_list which is the remainder
+ of the original huge request. Split off another chunk-sized bit from
+ it and the situation repeats:
+
+ 9,0 18 1183 0.629024499 15995 X WS 1479316488 / 1479317512
+ 8,16 18 6998 0.629025110 15995 A WS 739921928 + 1016 <- (9,0) 1479316488
+ 8,16 18 6999 0.629026728 15995 G WS 739921928 + 1016
+ ...
+ 9,0 18 1184 0.629032940 15995 X WS 1479317512 / 1479318536 [libnetacq-write]
+ 8,0 18 7059 0.629033294 15995 A WS 739922952 + 1016 <- (9,0) 1479317512
+ 8,0 18 7060 0.629033902 15995 G WS 739922952 + 1016
+ ...
+
+ This repeats until we consume the whole original huge request. Now we
+ finally get to processing the second parts of the split off requests
+ (in reverse order):
+
+ 8,16 18 7181 0.629161384 15995 A WS 739952640 + 8 <- (9,0) 1479377920
+ 8,0 18 7239 0.629162140 15995 A WS 739952640 + 8 <- (9,0) 1479376896
+ 8,16 18 7186 0.629163881 15995 A WS 739951616 + 8 <- (9,0) 1479375872
+ 8,0 18 7242 0.629164421 15995 A WS 739951616 + 8 <- (9,0) 1479374848
+ ...
+
+I guess it is obvious that this IO pattern is extremely inefficient way
+to perform sequential IO. It also makes bio_list to grow to rather long
+lengths.
+
+Change raid0_make_request() to map both parts of the split bio. Since we
+know we are provided with at most chunk-sized bios, we will always need
+to split the incoming bio at most once.
+
+Fixes: f00d7c85be9e ("md/raid0: fix up bio splitting.")
+Signed-off-by: Jan Kara <jack@suse.cz>
+Reviewed-by: Yu Kuai <yukuai3@huawei.com>
+Link: https://lore.kernel.org/r/20230814092720.3931-2-jack@suse.cz
+Signed-off-by: Song Liu <song@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/raid0.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
+index d3c55f2e9b185..595856948dff8 100644
+--- a/drivers/md/raid0.c
++++ b/drivers/md/raid0.c
+@@ -626,7 +626,7 @@ static bool raid0_make_request(struct mddev *mddev, struct bio *bio)
+ struct bio *split = bio_split(bio, sectors, GFP_NOIO,
+ &mddev->bio_set);
+ bio_chain(split, bio);
+- submit_bio_noacct(bio);
++ raid0_map_submit_bio(mddev, bio);
+ bio = split;
+ }
+
+--
+2.40.1
+
--- /dev/null
+From abb2844ee95e8e3fc8de36fe9c36b4396da094a3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Aug 2023 21:53:55 +0800
+Subject: md/raid1: free the r1bio before waiting for blocked rdev
+
+From: Xueshi Hu <xueshi.hu@smartx.com>
+
+[ Upstream commit 992db13a4aee766c8bfbf046ad15c2db5fa7cab8 ]
+
+Raid1 reshape will change mempool and r1conf::raid_disks which are
+needed to free r1bio. allow_barrier() make a concurrent raid1_reshape()
+possible. So, free the in-flight r1bio before waiting blocked rdev.
+
+Fixes: 6bfe0b499082 ("md: support blocking writes to an array on device failure")
+Reviewed-by: Yu Kuai <yukuai3@huawei.com>
+Signed-off-by: Xueshi Hu <xueshi.hu@smartx.com>
+Link: https://lore.kernel.org/r/20230814135356.1113639-3-xueshi.hu@smartx.com
+Signed-off-by: Song Liu <song@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/raid1.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
+index e51b77a3a8397..ebbe41a33b821 100644
+--- a/drivers/md/raid1.c
++++ b/drivers/md/raid1.c
+@@ -1370,6 +1370,7 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
+ return;
+ }
+
++ retry_write:
+ r1_bio = alloc_r1bio(mddev, bio);
+ r1_bio->sectors = max_write_sectors;
+
+@@ -1385,7 +1386,6 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
+ */
+
+ disks = conf->raid_disks * 2;
+- retry_write:
+ blocked_rdev = NULL;
+ rcu_read_lock();
+ max_sectors = r1_bio->sectors;
+@@ -1465,7 +1465,7 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
+ for (j = 0; j < i; j++)
+ if (r1_bio->bios[j])
+ rdev_dec_pending(conf->mirrors[j].rdev, mddev);
+- r1_bio->state = 0;
++ free_r1bio(r1_bio);
+ allow_barrier(conf, bio->bi_iter.bi_sector);
+
+ if (bio->bi_opf & REQ_NOWAIT) {
+--
+2.40.1
+
--- /dev/null
+From 7836951b418bc7d42ca525f850742d054831cd6c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Aug 2023 21:53:56 +0800
+Subject: md/raid1: hold the barrier until handle_read_error() finishes
+
+From: Xueshi Hu <xueshi.hu@smartx.com>
+
+[ Upstream commit c069da449a13669ffa754fd971747e7e17e7d691 ]
+
+handle_read_error() will call allow_barrier() to match the former barrier
+raising. However, it should put the allow_barrier() at the end to avoid a
+concurrent raid reshape.
+
+Fixes: 689389a06ce7 ("md/raid1: simplify handle_read_error().")
+Reviewed-by: Yu Kuai <yukuai3@huawei.com>
+Signed-off-by: Xueshi Hu <xueshi.hu@smartx.com>
+Link: https://lore.kernel.org/r/20230814135356.1113639-4-xueshi.hu@smartx.com
+Signed-off-by: Song Liu <song@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/raid1.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
+index ebbe41a33b821..975301f2debdd 100644
+--- a/drivers/md/raid1.c
++++ b/drivers/md/raid1.c
+@@ -2495,6 +2495,7 @@ static void handle_read_error(struct r1conf *conf, struct r1bio *r1_bio)
+ struct mddev *mddev = conf->mddev;
+ struct bio *bio;
+ struct md_rdev *rdev;
++ sector_t sector;
+
+ clear_bit(R1BIO_ReadError, &r1_bio->state);
+ /* we got a read error. Maybe the drive is bad. Maybe just
+@@ -2524,12 +2525,13 @@ static void handle_read_error(struct r1conf *conf, struct r1bio *r1_bio)
+ }
+
+ rdev_dec_pending(rdev, conf->mddev);
+- allow_barrier(conf, r1_bio->sector);
++ sector = r1_bio->sector;
+ bio = r1_bio->master_bio;
+
+ /* Reuse the old r1_bio so that the IO_BLOCKED settings are preserved */
+ r1_bio->state = 0;
+ raid1_read_request(mddev, bio, r1_bio->sectors, r1_bio);
++ allow_barrier(conf, sector);
+ }
+
+ static void raid1d(struct md_thread *thread)
+--
+2.40.1
+
--- /dev/null
+From 3a4bda87668148460de642daa97e35e1b16447ae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 Jul 2023 16:05:28 +0800
+Subject: md/raid10: factor out dereference_rdev_and_rrdev()
+
+From: Li Nan <linan122@huawei.com>
+
+[ Upstream commit b99f8fd2d91eb734f13098aa1cf337edaca454b7 ]
+
+Factor out a helper to get 'rdev' and 'replacement' from config->mirrors.
+Just to make code cleaner and prepare to fix the bug of io loss while
+'replacement' replace 'rdev'.
+
+There is no functional change.
+
+Signed-off-by: Li Nan <linan122@huawei.com>
+Link: https://lore.kernel.org/r/20230701080529.2684932-3-linan666@huaweicloud.com
+Signed-off-by: Song Liu <song@kernel.org>
+Stable-dep-of: 673643490b9a ("md/raid10: use dereference_rdev_and_rrdev() to get devices")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/raid10.c | 29 ++++++++++++++++++++---------
+ 1 file changed, 20 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
+index ee75b058438f3..f47fd50651c45 100644
+--- a/drivers/md/raid10.c
++++ b/drivers/md/raid10.c
+@@ -1321,6 +1321,25 @@ static void raid10_write_one_disk(struct mddev *mddev, struct r10bio *r10_bio,
+ }
+ }
+
++static struct md_rdev *dereference_rdev_and_rrdev(struct raid10_info *mirror,
++ struct md_rdev **prrdev)
++{
++ struct md_rdev *rdev, *rrdev;
++
++ rrdev = rcu_dereference(mirror->replacement);
++ /*
++ * Read replacement first to prevent reading both rdev and
++ * replacement as NULL during replacement replace rdev.
++ */
++ smp_mb();
++ rdev = rcu_dereference(mirror->rdev);
++ if (rdev == rrdev)
++ rrdev = NULL;
++
++ *prrdev = rrdev;
++ return rdev;
++}
++
+ static void wait_blocked_dev(struct mddev *mddev, struct r10bio *r10_bio)
+ {
+ int i;
+@@ -1464,15 +1483,7 @@ static void raid10_write_request(struct mddev *mddev, struct bio *bio,
+ int d = r10_bio->devs[i].devnum;
+ struct md_rdev *rdev, *rrdev;
+
+- rrdev = rcu_dereference(conf->mirrors[d].replacement);
+- /*
+- * Read replacement first to prevent reading both rdev and
+- * replacement as NULL during replacement replace rdev.
+- */
+- smp_mb();
+- rdev = rcu_dereference(conf->mirrors[d].rdev);
+- if (rdev == rrdev)
+- rrdev = NULL;
++ rdev = dereference_rdev_and_rrdev(&conf->mirrors[d], &rrdev);
+ if (rdev && (test_bit(Faulty, &rdev->flags)))
+ rdev = NULL;
+ if (rrdev && (test_bit(Faulty, &rrdev->flags)))
+--
+2.40.1
+
--- /dev/null
+From 641825b4700ba896c5f5704e67e05cd3451e4e78 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 Jul 2023 16:05:29 +0800
+Subject: md/raid10: use dereference_rdev_and_rrdev() to get devices
+
+From: Li Nan <linan122@huawei.com>
+
+[ Upstream commit 673643490b9a0eb3b25633abe604f62b8f63dba1 ]
+
+Commit 2ae6aaf76912 ("md/raid10: fix io loss while replacement replace
+rdev") reads replacement first to prevent io loss. However, there are same
+issue in wait_blocked_dev() and raid10_handle_discard(), too. Fix it by
+using dereference_rdev_and_rrdev() to get devices.
+
+Fixes: d30588b2731f ("md/raid10: improve raid10 discard request")
+Fixes: f2e7e269a752 ("md/raid10: pull the code that wait for blocked dev into one function")
+Signed-off-by: Li Nan <linan122@huawei.com>
+Link: https://lore.kernel.org/r/20230701080529.2684932-4-linan666@huaweicloud.com
+Signed-off-by: Song Liu <song@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/raid10.c | 13 +++++--------
+ 1 file changed, 5 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
+index f47fd50651c45..925ab30c15d49 100644
+--- a/drivers/md/raid10.c
++++ b/drivers/md/raid10.c
+@@ -1350,11 +1350,9 @@ static void wait_blocked_dev(struct mddev *mddev, struct r10bio *r10_bio)
+ blocked_rdev = NULL;
+ rcu_read_lock();
+ for (i = 0; i < conf->copies; i++) {
+- struct md_rdev *rdev = rcu_dereference(conf->mirrors[i].rdev);
+- struct md_rdev *rrdev = rcu_dereference(
+- conf->mirrors[i].replacement);
+- if (rdev == rrdev)
+- rrdev = NULL;
++ struct md_rdev *rdev, *rrdev;
++
++ rdev = dereference_rdev_and_rrdev(&conf->mirrors[i], &rrdev);
+ if (rdev && unlikely(test_bit(Blocked, &rdev->flags))) {
+ atomic_inc(&rdev->nr_pending);
+ blocked_rdev = rdev;
+@@ -1790,10 +1788,9 @@ static int raid10_handle_discard(struct mddev *mddev, struct bio *bio)
+ */
+ rcu_read_lock();
+ for (disk = 0; disk < geo->raid_disks; disk++) {
+- struct md_rdev *rdev = rcu_dereference(conf->mirrors[disk].rdev);
+- struct md_rdev *rrdev = rcu_dereference(
+- conf->mirrors[disk].replacement);
++ struct md_rdev *rdev, *rrdev;
+
++ rdev = dereference_rdev_and_rrdev(&conf->mirrors[disk], &rrdev);
+ r10_bio->devs[disk].bio = NULL;
+ r10_bio->devs[disk].repl_bio = NULL;
+
+--
+2.40.1
+
--- /dev/null
+From 52ac9d4163665019c2a8c303881de3d61c6328f3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Jul 2023 17:17:27 +0800
+Subject: md/raid5-cache: fix a deadlock in r5l_exit_log()
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+[ Upstream commit a705b11b358dee677aad80630e7608b2d5f56691 ]
+
+Commit b13015af94cf ("md/raid5-cache: Clear conf->log after finishing
+work") introduce a new problem:
+
+// caller hold reconfig_mutex
+r5l_exit_log
+ flush_work(&log->disable_writeback_work)
+ r5c_disable_writeback_async
+ wait_event
+ /*
+ * conf->log is not NULL, and mddev_trylock()
+ * will fail, wait_event() can never pass.
+ */
+ conf->log = NULL
+
+Fix this problem by setting 'config->log' to NULL before wake_up() as it
+used to be, so that wait_event() from r5c_disable_writeback_async() can
+exist. In the meantime, move forward md_unregister_thread() so that
+null-ptr-deref this commit fixed can still be fixed.
+
+Fixes: b13015af94cf ("md/raid5-cache: Clear conf->log after finishing work")
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Link: https://lore.kernel.org/r/20230708091727.1417894-1-yukuai1@huaweicloud.com
+Signed-off-by: Song Liu <song@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/raid5-cache.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c
+index 46182b955aef8..5c246b2697e0b 100644
+--- a/drivers/md/raid5-cache.c
++++ b/drivers/md/raid5-cache.c
+@@ -3164,12 +3164,15 @@ void r5l_exit_log(struct r5conf *conf)
+ {
+ struct r5l_log *log = conf->log;
+
+- /* Ensure disable_writeback_work wakes up and exits */
+- wake_up(&conf->mddev->sb_wait);
+- flush_work(&log->disable_writeback_work);
+ md_unregister_thread(&log->reclaim_thread);
+
++ /*
++ * 'reconfig_mutex' is held by caller, set 'confg->log' to NULL to
++ * ensure disable_writeback_work wakes up and exits.
++ */
+ conf->log = NULL;
++ wake_up(&conf->mddev->sb_wait);
++ flush_work(&log->disable_writeback_work);
+
+ mempool_exit(&log->meta_pool);
+ bioset_exit(&log->bs);
+--
+2.40.1
+
--- /dev/null
+From d19f6d6845ef0f41c236d54e93b9aead41fde5c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Aug 2023 18:49:12 +0800
+Subject: md/raid5-cache: fix null-ptr-deref for r5l_flush_stripe_to_raid()
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+[ Upstream commit 0d0bd28c500173bfca78aa840f8f36d261ef1765 ]
+
+r5l_flush_stripe_to_raid() will check if the list 'flushing_ios' is
+empty, and then submit 'flush_bio', however, r5l_log_flush_endio()
+is clearing the list first and then clear the bio, which will cause
+null-ptr-deref:
+
+T1: submit flush io
+raid5d
+ handle_active_stripes
+ r5l_flush_stripe_to_raid
+ // list is empty
+ // add 'io_end_ios' to the list
+ bio_init
+ submit_bio
+ // io1
+
+T2: io1 is done
+r5l_log_flush_endio
+ list_splice_tail_init
+ // clear the list
+ T3: submit new flush io
+ ...
+ r5l_flush_stripe_to_raid
+ // list is empty
+ // add 'io_end_ios' to the list
+ bio_init
+ bio_uninit
+ // clear bio->bi_blkg
+ submit_bio
+ // null-ptr-deref
+
+Fix this problem by clearing bio before clearing the list in
+r5l_log_flush_endio().
+
+Fixes: 0dd00cba99c3 ("raid5-cache: fully initialize flush_bio when needed")
+Reported-and-tested-by: Corey Hickey <bugfood-ml@fatooh.org>
+Closes: https://lore.kernel.org/all/cddd7213-3dfd-4ab7-a3ac-edd54d74a626@fatooh.org/
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Song Liu <song@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/raid5-cache.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c
+index 5c246b2697e0b..21653e1ed9384 100644
+--- a/drivers/md/raid5-cache.c
++++ b/drivers/md/raid5-cache.c
+@@ -1260,14 +1260,13 @@ static void r5l_log_flush_endio(struct bio *bio)
+
+ if (bio->bi_status)
+ md_error(log->rdev->mddev, log->rdev);
++ bio_uninit(bio);
+
+ spin_lock_irqsave(&log->io_list_lock, flags);
+ list_for_each_entry(io, &log->flushing_ios, log_sibling)
+ r5l_io_run_stripes(io);
+ list_splice_tail_init(&log->flushing_ios, &log->finished_ios);
+ spin_unlock_irqrestore(&log->io_list_lock, flags);
+-
+- bio_uninit(bio);
+ }
+
+ /*
+--
+2.40.1
+
--- /dev/null
+From 6e9911e3fb7ca7d15719ac6fe7d513afb9678613 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 Jun 2023 09:29:31 +0800
+Subject: md: restore 'noio_flag' for the last mddev_resume()
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+[ Upstream commit e24ed04389f9619e0aaef615a8948633c182a8b0 ]
+
+memalloc_noio_save() is called for the first mddev_suspend(), and
+repeated mddev_suspend() only increase 'suspended'. However,
+memalloc_noio_restore() is also called for the first mddev_resume(),
+which means that memory reclaim will be enabled before the last
+mddev_resume() is called, while the array is still suspended.
+
+Fix this problem by restore 'noio_flag' for the last mddev_resume().
+
+Fixes: 78f57ef9d50a ("md: use memalloc scope APIs in mddev_suspend()/mddev_resume()")
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Link: https://lore.kernel.org/r/20230628012931.88911-3-yukuai1@huaweicloud.com
+Signed-off-by: Song Liu <song@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/md.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/md/md.c b/drivers/md/md.c
+index 32d7ba8069aef..a2904e10ae35e 100644
+--- a/drivers/md/md.c
++++ b/drivers/md/md.c
+@@ -477,11 +477,13 @@ EXPORT_SYMBOL_GPL(mddev_suspend);
+
+ void mddev_resume(struct mddev *mddev)
+ {
+- /* entred the memalloc scope from mddev_suspend() */
+- memalloc_noio_restore(mddev->noio_flag);
+ lockdep_assert_held(&mddev->reconfig_mutex);
+ if (--mddev->suspended)
+ return;
++
++ /* entred the memalloc scope from mddev_suspend() */
++ memalloc_noio_restore(mddev->noio_flag);
++
+ percpu_ref_resurrect(&mddev->active_io);
+ wake_up(&mddev->sb_wait);
+ mddev->pers->quiesce(mddev, 0);
+--
+2.40.1
+
--- /dev/null
+From 8ab49dfd8bbac1ff00c8912a7f61105e8dc8c2bc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 18 Jun 2023 20:17:40 +0200
+Subject: media: ad5820: Drop unsupported ad5823 from i2c_ and of_device_id
+ tables
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit f126ff7e4024f6704e6ec0d4137037568708a3c7 ]
+
+The supported ad5820 and ad5821 VCMs both use a single 16 bit register
+which is written by sending 2 bytes with the data directly after sending
+the i2c-client address.
+
+The ad5823 OTOH has a more typical i2c / smbus device setup with multiple
+8 bit registers where the first byte send after the i2c-client address is
+the register address and the actual data only starts from the second byte
+after the i2c-client address.
+
+The ad5823 i2c_ and of_device_id-s was added at the same time as
+the ad5821 ids with as rationale:
+
+"""
+Some camera modules also refer that AD5823 is a replacement of AD5820:
+https://download.kamami.com/p564094-OV8865_DS.pdf
+"""
+
+The AD5823 may be an electrical and functional replacement of the AD5820,
+but from a software pov it is not compatible at all and it is going to
+need its own driver, drop its id from the ad5820 driver.
+
+Fixes: b8bf73136bae ("media: ad5820: Add support for ad5821 and ad5823")
+Cc: Pavel Machek <pavel@ucw.cz>
+Cc: Ricardo Ribalda Delgado <ribalda@kernel.org>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Reviewed-by: Ricardo Ribalda <ribalda@chromium.org>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/i2c/ad5820.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/media/i2c/ad5820.c b/drivers/media/i2c/ad5820.c
+index 44c26af49071c..786f38b4cbc0e 100644
+--- a/drivers/media/i2c/ad5820.c
++++ b/drivers/media/i2c/ad5820.c
+@@ -349,7 +349,6 @@ static void ad5820_remove(struct i2c_client *client)
+ static const struct i2c_device_id ad5820_id_table[] = {
+ { "ad5820", 0 },
+ { "ad5821", 0 },
+- { "ad5823", 0 },
+ { }
+ };
+ MODULE_DEVICE_TABLE(i2c, ad5820_id_table);
+@@ -357,7 +356,6 @@ MODULE_DEVICE_TABLE(i2c, ad5820_id_table);
+ static const struct of_device_id ad5820_of_table[] = {
+ { .compatible = "adi,ad5820" },
+ { .compatible = "adi,ad5821" },
+- { .compatible = "adi,ad5823" },
+ { }
+ };
+ MODULE_DEVICE_TABLE(of, ad5820_of_table);
+--
+2.40.1
+
--- /dev/null
+From 2880616d5d5294f0a089e697ed7a1fede0ea1cc0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Jun 2023 17:14:08 +0800
+Subject: media: amphion: add helper function to get id name
+
+From: Ming Qian <ming.qian@nxp.com>
+
+[ Upstream commit 12cd8b8ac02525977b2e860a877add10e8ce7468 ]
+
+convert numbers into meaningful names,
+then it can improve the log readability
+
+Fixes: 9f599f351e86 ("media: amphion: add vpu core driver")
+Signed-off-by: Ming Qian <ming.qian@nxp.com>
+Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/amphion/vdec.c | 9 +--
+ drivers/media/platform/amphion/vpu.h | 3 +
+ drivers/media/platform/amphion/vpu_cmds.c | 11 ++--
+ drivers/media/platform/amphion/vpu_dbg.c | 6 +-
+ drivers/media/platform/amphion/vpu_helpers.c | 61 ++++++++++++++++++++
+ drivers/media/platform/amphion/vpu_msgs.c | 2 +-
+ 6 files changed, 79 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/media/platform/amphion/vdec.c b/drivers/media/platform/amphion/vdec.c
+index 56c4deea4494d..60f3a73c6a8ad 100644
+--- a/drivers/media/platform/amphion/vdec.c
++++ b/drivers/media/platform/amphion/vdec.c
+@@ -299,7 +299,8 @@ static int vdec_update_state(struct vpu_inst *inst, enum vpu_codec_state state,
+ vdec->state = VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE;
+
+ if (inst->state != pre_state)
+- vpu_trace(inst->dev, "[%d] %d -> %d\n", inst->id, pre_state, inst->state);
++ vpu_trace(inst->dev, "[%d] %s -> %s\n", inst->id,
++ vpu_codec_state_name(pre_state), vpu_codec_state_name(inst->state));
+
+ if (inst->state == VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
+ vdec_handle_resolution_change(inst);
+@@ -1037,8 +1038,8 @@ static int vdec_response_frame(struct vpu_inst *inst, struct vb2_v4l2_buffer *vb
+ return -EINVAL;
+ }
+
+- dev_dbg(inst->dev, "[%d] state = %d, alloc fs %d, tag = 0x%x\n",
+- inst->id, inst->state, vbuf->vb2_buf.index, vdec->seq_tag);
++ dev_dbg(inst->dev, "[%d] state = %s, alloc fs %d, tag = 0x%x\n",
++ inst->id, vpu_codec_state_name(inst->state), vbuf->vb2_buf.index, vdec->seq_tag);
+ vpu_buf = to_vpu_vb2_buffer(vbuf);
+
+ memset(&info, 0, sizeof(info));
+@@ -1400,7 +1401,7 @@ static void vdec_abort(struct vpu_inst *inst)
+ struct vpu_rpc_buffer_desc desc;
+ int ret;
+
+- vpu_trace(inst->dev, "[%d] state = %d\n", inst->id, inst->state);
++ vpu_trace(inst->dev, "[%d] state = %s\n", inst->id, vpu_codec_state_name(inst->state));
+
+ vdec->aborting = true;
+ vpu_iface_add_scode(inst, SCODE_PADDING_ABORT);
+diff --git a/drivers/media/platform/amphion/vpu.h b/drivers/media/platform/amphion/vpu.h
+index 3bfe193722af4..5a701f64289ef 100644
+--- a/drivers/media/platform/amphion/vpu.h
++++ b/drivers/media/platform/amphion/vpu.h
+@@ -355,6 +355,9 @@ void vpu_inst_record_flow(struct vpu_inst *inst, u32 flow);
+ int vpu_core_driver_init(void);
+ void vpu_core_driver_exit(void);
+
++const char *vpu_id_name(u32 id);
++const char *vpu_codec_state_name(enum vpu_codec_state state);
++
+ extern bool debug;
+ #define vpu_trace(dev, fmt, arg...) \
+ do { \
+diff --git a/drivers/media/platform/amphion/vpu_cmds.c b/drivers/media/platform/amphion/vpu_cmds.c
+index fa581ba6bab2d..647d94554fb5d 100644
+--- a/drivers/media/platform/amphion/vpu_cmds.c
++++ b/drivers/media/platform/amphion/vpu_cmds.c
+@@ -98,7 +98,7 @@ static struct vpu_cmd_t *vpu_alloc_cmd(struct vpu_inst *inst, u32 id, void *data
+ cmd->id = id;
+ ret = vpu_iface_pack_cmd(inst->core, cmd->pkt, inst->id, id, data);
+ if (ret) {
+- dev_err(inst->dev, "iface pack cmd(%d) fail\n", id);
++ dev_err(inst->dev, "iface pack cmd %s fail\n", vpu_id_name(id));
+ vfree(cmd->pkt);
+ vfree(cmd);
+ return NULL;
+@@ -125,14 +125,14 @@ static int vpu_session_process_cmd(struct vpu_inst *inst, struct vpu_cmd_t *cmd)
+ {
+ int ret;
+
+- dev_dbg(inst->dev, "[%d]send cmd(0x%x)\n", inst->id, cmd->id);
++ dev_dbg(inst->dev, "[%d]send cmd %s\n", inst->id, vpu_id_name(cmd->id));
+ vpu_iface_pre_send_cmd(inst);
+ ret = vpu_cmd_send(inst->core, cmd->pkt);
+ if (!ret) {
+ vpu_iface_post_send_cmd(inst);
+ vpu_inst_record_flow(inst, cmd->id);
+ } else {
+- dev_err(inst->dev, "[%d] iface send cmd(0x%x) fail\n", inst->id, cmd->id);
++ dev_err(inst->dev, "[%d] iface send cmd %s fail\n", inst->id, vpu_id_name(cmd->id));
+ }
+
+ return ret;
+@@ -149,7 +149,8 @@ static void vpu_process_cmd_request(struct vpu_inst *inst)
+ list_for_each_entry_safe(cmd, tmp, &inst->cmd_q, list) {
+ list_del_init(&cmd->list);
+ if (vpu_session_process_cmd(inst, cmd))
+- dev_err(inst->dev, "[%d] process cmd(%d) fail\n", inst->id, cmd->id);
++ dev_err(inst->dev, "[%d] process cmd %s fail\n",
++ inst->id, vpu_id_name(cmd->id));
+ if (cmd->request) {
+ inst->pending = (void *)cmd;
+ break;
+@@ -339,7 +340,7 @@ static int vpu_session_send_cmd(struct vpu_inst *inst, u32 id, void *data)
+
+ exit:
+ if (ret)
+- dev_err(inst->dev, "[%d] send cmd(0x%x) fail\n", inst->id, id);
++ dev_err(inst->dev, "[%d] send cmd %s fail\n", inst->id, vpu_id_name(id));
+
+ return ret;
+ }
+diff --git a/drivers/media/platform/amphion/vpu_dbg.c b/drivers/media/platform/amphion/vpu_dbg.c
+index 44b830ae01d8c..adc523b950618 100644
+--- a/drivers/media/platform/amphion/vpu_dbg.c
++++ b/drivers/media/platform/amphion/vpu_dbg.c
+@@ -67,7 +67,7 @@ static int vpu_dbg_instance(struct seq_file *s, void *data)
+ num = scnprintf(str, sizeof(str), "tgig = %d,pid = %d\n", inst->tgid, inst->pid);
+ if (seq_write(s, str, num))
+ return 0;
+- num = scnprintf(str, sizeof(str), "state = %d\n", inst->state);
++ num = scnprintf(str, sizeof(str), "state = %s\n", vpu_codec_state_name(inst->state));
+ if (seq_write(s, str, num))
+ return 0;
+ num = scnprintf(str, sizeof(str),
+@@ -188,9 +188,9 @@ static int vpu_dbg_instance(struct seq_file *s, void *data)
+
+ if (!inst->flows[idx])
+ continue;
+- num = scnprintf(str, sizeof(str), "\t[%s]0x%x\n",
++ num = scnprintf(str, sizeof(str), "\t[%s] %s\n",
+ inst->flows[idx] >= VPU_MSG_ID_NOOP ? "M" : "C",
+- inst->flows[idx]);
++ vpu_id_name(inst->flows[idx]));
+ if (seq_write(s, str, num)) {
+ mutex_unlock(&inst->core->cmd_lock);
+ return 0;
+diff --git a/drivers/media/platform/amphion/vpu_helpers.c b/drivers/media/platform/amphion/vpu_helpers.c
+index 019c77e84514c..af3b336e5dc32 100644
+--- a/drivers/media/platform/amphion/vpu_helpers.c
++++ b/drivers/media/platform/amphion/vpu_helpers.c
+@@ -11,6 +11,7 @@
+ #include <linux/module.h>
+ #include <linux/platform_device.h>
+ #include "vpu.h"
++#include "vpu_defs.h"
+ #include "vpu_core.h"
+ #include "vpu_rpc.h"
+ #include "vpu_helpers.h"
+@@ -447,3 +448,63 @@ int vpu_find_src_by_dst(struct vpu_pair *pairs, u32 cnt, u32 dst)
+
+ return -EINVAL;
+ }
++
++const char *vpu_id_name(u32 id)
++{
++ switch (id) {
++ case VPU_CMD_ID_NOOP: return "noop";
++ case VPU_CMD_ID_CONFIGURE_CODEC: return "configure codec";
++ case VPU_CMD_ID_START: return "start";
++ case VPU_CMD_ID_STOP: return "stop";
++ case VPU_CMD_ID_ABORT: return "abort";
++ case VPU_CMD_ID_RST_BUF: return "reset buf";
++ case VPU_CMD_ID_SNAPSHOT: return "snapshot";
++ case VPU_CMD_ID_FIRM_RESET: return "reset firmware";
++ case VPU_CMD_ID_UPDATE_PARAMETER: return "update parameter";
++ case VPU_CMD_ID_FRAME_ENCODE: return "encode frame";
++ case VPU_CMD_ID_SKIP: return "skip";
++ case VPU_CMD_ID_FS_ALLOC: return "alloc fb";
++ case VPU_CMD_ID_FS_RELEASE: return "release fb";
++ case VPU_CMD_ID_TIMESTAMP: return "timestamp";
++ case VPU_CMD_ID_DEBUG: return "debug";
++ case VPU_MSG_ID_RESET_DONE: return "reset done";
++ case VPU_MSG_ID_START_DONE: return "start done";
++ case VPU_MSG_ID_STOP_DONE: return "stop done";
++ case VPU_MSG_ID_ABORT_DONE: return "abort done";
++ case VPU_MSG_ID_BUF_RST: return "buf reset done";
++ case VPU_MSG_ID_MEM_REQUEST: return "mem request";
++ case VPU_MSG_ID_PARAM_UPD_DONE: return "param upd done";
++ case VPU_MSG_ID_FRAME_INPUT_DONE: return "frame input done";
++ case VPU_MSG_ID_ENC_DONE: return "encode done";
++ case VPU_MSG_ID_DEC_DONE: return "frame display";
++ case VPU_MSG_ID_FRAME_REQ: return "fb request";
++ case VPU_MSG_ID_FRAME_RELEASE: return "fb release";
++ case VPU_MSG_ID_SEQ_HDR_FOUND: return "seq hdr found";
++ case VPU_MSG_ID_RES_CHANGE: return "resolution change";
++ case VPU_MSG_ID_PIC_HDR_FOUND: return "pic hdr found";
++ case VPU_MSG_ID_PIC_DECODED: return "picture decoded";
++ case VPU_MSG_ID_PIC_EOS: return "eos";
++ case VPU_MSG_ID_FIFO_LOW: return "fifo low";
++ case VPU_MSG_ID_BS_ERROR: return "bs error";
++ case VPU_MSG_ID_UNSUPPORTED: return "unsupported";
++ case VPU_MSG_ID_FIRMWARE_XCPT: return "exception";
++ case VPU_MSG_ID_PIC_SKIPPED: return "skipped";
++ }
++ return "<unknown>";
++}
++
++const char *vpu_codec_state_name(enum vpu_codec_state state)
++{
++ switch (state) {
++ case VPU_CODEC_STATE_DEINIT: return "initialization";
++ case VPU_CODEC_STATE_CONFIGURED: return "configured";
++ case VPU_CODEC_STATE_START: return "start";
++ case VPU_CODEC_STATE_STARTED: return "started";
++ case VPU_CODEC_STATE_ACTIVE: return "active";
++ case VPU_CODEC_STATE_SEEK: return "seek";
++ case VPU_CODEC_STATE_STOP: return "stop";
++ case VPU_CODEC_STATE_DRAIN: return "drain";
++ case VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE: return "resolution change";
++ }
++ return "<unknown>";
++}
+diff --git a/drivers/media/platform/amphion/vpu_msgs.c b/drivers/media/platform/amphion/vpu_msgs.c
+index 92672a802b492..f9eb488d1b5e2 100644
+--- a/drivers/media/platform/amphion/vpu_msgs.c
++++ b/drivers/media/platform/amphion/vpu_msgs.c
+@@ -210,7 +210,7 @@ static int vpu_session_handle_msg(struct vpu_inst *inst, struct vpu_rpc_event *m
+ return -EINVAL;
+
+ msg_id = ret;
+- dev_dbg(inst->dev, "[%d] receive event(0x%x)\n", inst->id, msg_id);
++ dev_dbg(inst->dev, "[%d] receive event(%s)\n", inst->id, vpu_id_name(msg_id));
+
+ for (i = 0; i < ARRAY_SIZE(handlers); i++) {
+ if (handlers[i].id == msg_id) {
+--
+2.40.1
+
--- /dev/null
+From 7ea5b80a0447b2d47bf0fb78f91797e3895750fa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Jul 2023 15:44:11 +0800
+Subject: media: amphion: decoder support display delay for all formats
+
+From: Ming Qian <ming.qian@nxp.com>
+
+[ Upstream commit b69713f502027150ecc08e663fa1804d78b3ef42 ]
+
+the firmware only support low latency mode for h264,
+but firmware will notify an event to driver
+when one frame is decoded,
+if V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY_ENABLE is enabled,
+and V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY is set to 0,
+driver can display the decoded frame immediately.
+
+Fixes: ffa331d9bf94 ("media: amphion: decoder implement display delay enable")
+Signed-off-by: Ming Qian <ming.qian@nxp.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/amphion/vdec.c | 25 ++++++++++++++++++++++---
+ 1 file changed, 22 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/media/platform/amphion/vdec.c b/drivers/media/platform/amphion/vdec.c
+index 60f3a73c6a8ad..eeb2ef72df5b3 100644
+--- a/drivers/media/platform/amphion/vdec.c
++++ b/drivers/media/platform/amphion/vdec.c
+@@ -742,6 +742,21 @@ static int vdec_frame_decoded(struct vpu_inst *inst, void *arg)
+ dev_info(inst->dev, "[%d] buf[%d] has been decoded\n", inst->id, info->id);
+ vpu_set_buffer_state(vbuf, VPU_BUF_STATE_DECODED);
+ vdec->decoded_frame_count++;
++ if (vdec->params.display_delay_enable) {
++ struct vpu_format *cur_fmt;
++
++ cur_fmt = vpu_get_format(inst, inst->cap_format.type);
++ vpu_set_buffer_state(vbuf, VPU_BUF_STATE_READY);
++ for (int i = 0; i < vbuf->vb2_buf.num_planes; i++)
++ vb2_set_plane_payload(&vbuf->vb2_buf,
++ i, vpu_get_fmt_plane_size(cur_fmt, i));
++ vbuf->field = cur_fmt->field;
++ vbuf->sequence = vdec->sequence++;
++ dev_dbg(inst->dev, "[%d][OUTPUT TS]%32lld\n", inst->id, vbuf->vb2_buf.timestamp);
++
++ v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
++ vdec->display_frame_count++;
++ }
+ exit:
+ vpu_inst_unlock(inst);
+
+@@ -769,14 +784,14 @@ static void vdec_buf_done(struct vpu_inst *inst, struct vpu_frame_info *frame)
+ struct vpu_format *cur_fmt;
+ struct vpu_vb2_buffer *vpu_buf;
+ struct vb2_v4l2_buffer *vbuf;
+- u32 sequence;
+ int i;
+
+ if (!frame)
+ return;
+
+ vpu_inst_lock(inst);
+- sequence = vdec->sequence++;
++ if (!vdec->params.display_delay_enable)
++ vdec->sequence++;
+ vpu_buf = vdec_find_buffer(inst, frame->luma);
+ vpu_inst_unlock(inst);
+ if (!vpu_buf) {
+@@ -795,13 +810,17 @@ static void vdec_buf_done(struct vpu_inst *inst, struct vpu_frame_info *frame)
+ dev_err(inst->dev, "[%d] buffer id(%d, %d) dismatch\n",
+ inst->id, vbuf->vb2_buf.index, frame->id);
+
++ if (vpu_get_buffer_state(vbuf) == VPU_BUF_STATE_READY && vdec->params.display_delay_enable)
++ return;
++
+ if (vpu_get_buffer_state(vbuf) != VPU_BUF_STATE_DECODED)
+ dev_err(inst->dev, "[%d] buffer(%d) ready without decoded\n", inst->id, frame->id);
++
+ vpu_set_buffer_state(vbuf, VPU_BUF_STATE_READY);
+ for (i = 0; i < vbuf->vb2_buf.num_planes; i++)
+ vb2_set_plane_payload(&vbuf->vb2_buf, i, vpu_get_fmt_plane_size(cur_fmt, i));
+ vbuf->field = cur_fmt->field;
+- vbuf->sequence = sequence;
++ vbuf->sequence = vdec->sequence;
+ dev_dbg(inst->dev, "[%d][OUTPUT TS]%32lld\n", inst->id, vbuf->vb2_buf.timestamp);
+
+ v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
+--
+2.40.1
+
--- /dev/null
+From e5f85a602b9957906753c4408521cf93e390eea4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Jul 2023 17:50:13 +0800
+Subject: media: amphion: ensure the bitops don't cross boundaries
+
+From: Ming Qian <ming.qian@nxp.com>
+
+[ Upstream commit 5bd28eae48589694ff4e5badb03bf75dae695b3f ]
+
+the supported_instance_count determine the instance index range,
+it shouldn't exceed the bits number of instance_mask,
+otherwise the bitops of instance_mask may cross boundaries
+
+Fixes: 9f599f351e86 ("media: amphion: add vpu core driver")
+Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+Signed-off-by: Ming Qian <ming.qian@nxp.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/amphion/vpu_core.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/media/platform/amphion/vpu_core.c b/drivers/media/platform/amphion/vpu_core.c
+index 82bf8b3be66a2..bfdebf2449a5c 100644
+--- a/drivers/media/platform/amphion/vpu_core.c
++++ b/drivers/media/platform/amphion/vpu_core.c
+@@ -88,6 +88,8 @@ static int vpu_core_boot_done(struct vpu_core *core)
+
+ core->supported_instance_count = min(core->supported_instance_count, count);
+ }
++ if (core->supported_instance_count >= BITS_PER_TYPE(core->instance_mask))
++ core->supported_instance_count = BITS_PER_TYPE(core->instance_mask);
+ core->fw_version = fw_version;
+ vpu_core_set_state(core, VPU_CORE_ACTIVE);
+
+--
+2.40.1
+
--- /dev/null
+From 6cd6a3942a1d7148206fbcf86cad4a3c5831d080 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Jul 2023 17:50:09 +0800
+Subject: media: amphion: fix CHECKED_RETURN issues reported by coverity
+
+From: Ming Qian <ming.qian@nxp.com>
+
+[ Upstream commit b237b058adbc7825da9c8f358f1ff3f0467d623a ]
+
+calling "vpu_cmd_send/vpu_get_buffer_state/vpu_session_alloc_fs"
+without checking return value
+
+Fixes: 9f599f351e86 ("media: amphion: add vpu core driver")
+Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+Signed-off-by: Ming Qian <ming.qian@nxp.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/amphion/vdec.c | 5 ++++-
+ drivers/media/platform/amphion/vpu_cmds.c | 3 ++-
+ drivers/media/platform/amphion/vpu_dbg.c | 11 +++++++++--
+ 3 files changed, 15 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/media/platform/amphion/vdec.c b/drivers/media/platform/amphion/vdec.c
+index eeb2ef72df5b3..133d77d1ea0c3 100644
+--- a/drivers/media/platform/amphion/vdec.c
++++ b/drivers/media/platform/amphion/vdec.c
+@@ -1019,6 +1019,7 @@ static int vdec_response_frame_abnormal(struct vpu_inst *inst)
+ {
+ struct vdec_t *vdec = inst->priv;
+ struct vpu_fs_info info;
++ int ret;
+
+ if (!vdec->req_frame_count)
+ return 0;
+@@ -1026,7 +1027,9 @@ static int vdec_response_frame_abnormal(struct vpu_inst *inst)
+ memset(&info, 0, sizeof(info));
+ info.type = MEM_RES_FRAME;
+ info.tag = vdec->seq_tag + 0xf0;
+- vpu_session_alloc_fs(inst, &info);
++ ret = vpu_session_alloc_fs(inst, &info);
++ if (ret)
++ return ret;
+ vdec->req_frame_count--;
+
+ return 0;
+diff --git a/drivers/media/platform/amphion/vpu_cmds.c b/drivers/media/platform/amphion/vpu_cmds.c
+index 647d94554fb5d..7e137f276c3b1 100644
+--- a/drivers/media/platform/amphion/vpu_cmds.c
++++ b/drivers/media/platform/amphion/vpu_cmds.c
+@@ -306,7 +306,8 @@ static void vpu_core_keep_active(struct vpu_core *core)
+
+ dev_dbg(core->dev, "try to wake up\n");
+ mutex_lock(&core->cmd_lock);
+- vpu_cmd_send(core, &pkt);
++ if (vpu_cmd_send(core, &pkt))
++ dev_err(core->dev, "fail to keep active\n");
+ mutex_unlock(&core->cmd_lock);
+ }
+
+diff --git a/drivers/media/platform/amphion/vpu_dbg.c b/drivers/media/platform/amphion/vpu_dbg.c
+index adc523b950618..982c2c777484c 100644
+--- a/drivers/media/platform/amphion/vpu_dbg.c
++++ b/drivers/media/platform/amphion/vpu_dbg.c
+@@ -50,6 +50,13 @@ static char *vpu_stat_name[] = {
+ [VPU_BUF_STATE_ERROR] = "error",
+ };
+
++static inline const char *to_vpu_stat_name(int state)
++{
++ if (state <= VPU_BUF_STATE_ERROR)
++ return vpu_stat_name[state];
++ return "unknown";
++}
++
+ static int vpu_dbg_instance(struct seq_file *s, void *data)
+ {
+ struct vpu_inst *inst = s->private;
+@@ -141,7 +148,7 @@ static int vpu_dbg_instance(struct seq_file *s, void *data)
+ num = scnprintf(str, sizeof(str),
+ "output [%2d] state = %10s, %8s\n",
+ i, vb2_stat_name[vb->state],
+- vpu_stat_name[vpu_get_buffer_state(vbuf)]);
++ to_vpu_stat_name(vpu_get_buffer_state(vbuf)));
+ if (seq_write(s, str, num))
+ return 0;
+ }
+@@ -156,7 +163,7 @@ static int vpu_dbg_instance(struct seq_file *s, void *data)
+ num = scnprintf(str, sizeof(str),
+ "capture[%2d] state = %10s, %8s\n",
+ i, vb2_stat_name[vb->state],
+- vpu_stat_name[vpu_get_buffer_state(vbuf)]);
++ to_vpu_stat_name(vpu_get_buffer_state(vbuf)));
+ if (seq_write(s, str, num))
+ return 0;
+ }
+--
+2.40.1
+
--- /dev/null
+From 4ea4d356abc58e0cae3dab3ee7b1d6d3e47d9020 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Jul 2023 17:50:10 +0800
+Subject: media: amphion: fix REVERSE_INULL issues reported by coverity
+
+From: Ming Qian <ming.qian@nxp.com>
+
+[ Upstream commit 79d3bafaecc13bccab1ebbd28a15e669c5a4cdaf ]
+
+null-checking of a pointor is suggested before dereferencing it
+
+Fixes: 9f599f351e86 ("media: amphion: add vpu core driver")
+Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+Signed-off-by: Ming Qian <ming.qian@nxp.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/amphion/venc.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/platform/amphion/venc.c b/drivers/media/platform/amphion/venc.c
+index 58480e2755ec4..4eb57d793a9c0 100644
+--- a/drivers/media/platform/amphion/venc.c
++++ b/drivers/media/platform/amphion/venc.c
+@@ -268,7 +268,7 @@ static int venc_g_parm(struct file *file, void *fh, struct v4l2_streamparm *parm
+ {
+ struct vpu_inst *inst = to_inst(file);
+ struct venc_t *venc = inst->priv;
+- struct v4l2_fract *timeperframe = &parm->parm.capture.timeperframe;
++ struct v4l2_fract *timeperframe;
+
+ if (!parm)
+ return -EINVAL;
+@@ -279,6 +279,7 @@ static int venc_g_parm(struct file *file, void *fh, struct v4l2_streamparm *parm
+ if (!vpu_helper_check_type(inst, parm->type))
+ return -EINVAL;
+
++ timeperframe = &parm->parm.capture.timeperframe;
+ parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
+ parm->parm.capture.readbuffers = 0;
+ timeperframe->numerator = venc->params.frame_rate.numerator;
+@@ -291,7 +292,7 @@ static int venc_s_parm(struct file *file, void *fh, struct v4l2_streamparm *parm
+ {
+ struct vpu_inst *inst = to_inst(file);
+ struct venc_t *venc = inst->priv;
+- struct v4l2_fract *timeperframe = &parm->parm.capture.timeperframe;
++ struct v4l2_fract *timeperframe;
+ unsigned long n, d;
+
+ if (!parm)
+@@ -303,6 +304,7 @@ static int venc_s_parm(struct file *file, void *fh, struct v4l2_streamparm *parm
+ if (!vpu_helper_check_type(inst, parm->type))
+ return -EINVAL;
+
++ timeperframe = &parm->parm.capture.timeperframe;
+ if (!timeperframe->numerator)
+ timeperframe->numerator = venc->params.frame_rate.numerator;
+ if (!timeperframe->denominator)
+--
+2.40.1
+
--- /dev/null
+From 3a38a93a9ede4a73937f41c8f47219cd9e00b0f9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Jul 2023 17:50:11 +0800
+Subject: media: amphion: fix UNINIT issues reported by coverity
+
+From: Ming Qian <ming.qian@nxp.com>
+
+[ Upstream commit c224d0497a31ea2d173e1ea16af308945bff9037 ]
+
+using uninitialized value may introduce risk
+
+Fixes: 9f599f351e86 ("media: amphion: add vpu core driver")
+Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+Signed-off-by: Ming Qian <ming.qian@nxp.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/amphion/vpu_msgs.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/media/platform/amphion/vpu_msgs.c b/drivers/media/platform/amphion/vpu_msgs.c
+index f9eb488d1b5e2..d0ead051f7d18 100644
+--- a/drivers/media/platform/amphion/vpu_msgs.c
++++ b/drivers/media/platform/amphion/vpu_msgs.c
+@@ -32,7 +32,7 @@ static void vpu_session_handle_start_done(struct vpu_inst *inst, struct vpu_rpc_
+
+ static void vpu_session_handle_mem_request(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+ {
+- struct vpu_pkt_mem_req_data req_data;
++ struct vpu_pkt_mem_req_data req_data = { 0 };
+
+ vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&req_data);
+ vpu_trace(inst->dev, "[%d] %d:%d %d:%d %d:%d\n",
+@@ -80,7 +80,7 @@ static void vpu_session_handle_resolution_change(struct vpu_inst *inst, struct v
+
+ static void vpu_session_handle_enc_frame_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+ {
+- struct vpu_enc_pic_info info;
++ struct vpu_enc_pic_info info = { 0 };
+
+ vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&info);
+ dev_dbg(inst->dev, "[%d] frame id = %d, wptr = 0x%x, size = %d\n",
+@@ -90,7 +90,7 @@ static void vpu_session_handle_enc_frame_done(struct vpu_inst *inst, struct vpu_
+
+ static void vpu_session_handle_frame_request(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+ {
+- struct vpu_fs_info fs;
++ struct vpu_fs_info fs = { 0 };
+
+ vpu_iface_unpack_msg_data(inst->core, pkt, &fs);
+ call_void_vop(inst, event_notify, VPU_MSG_ID_FRAME_REQ, &fs);
+@@ -107,7 +107,7 @@ static void vpu_session_handle_frame_release(struct vpu_inst *inst, struct vpu_r
+ info.type = inst->out_format.type;
+ call_void_vop(inst, buf_done, &info);
+ } else if (inst->core->type == VPU_CORE_TYPE_DEC) {
+- struct vpu_fs_info fs;
++ struct vpu_fs_info fs = { 0 };
+
+ vpu_iface_unpack_msg_data(inst->core, pkt, &fs);
+ call_void_vop(inst, event_notify, VPU_MSG_ID_FRAME_RELEASE, &fs);
+@@ -122,7 +122,7 @@ static void vpu_session_handle_input_done(struct vpu_inst *inst, struct vpu_rpc_
+
+ static void vpu_session_handle_pic_decoded(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+ {
+- struct vpu_dec_pic_info info;
++ struct vpu_dec_pic_info info = { 0 };
+
+ vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&info);
+ call_void_vop(inst, get_one_frame, &info);
+@@ -130,7 +130,7 @@ static void vpu_session_handle_pic_decoded(struct vpu_inst *inst, struct vpu_rpc
+
+ static void vpu_session_handle_pic_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+ {
+- struct vpu_dec_pic_info info;
++ struct vpu_dec_pic_info info = { 0 };
+ struct vpu_frame_info frame;
+
+ memset(&frame, 0, sizeof(frame));
+--
+2.40.1
+
--- /dev/null
+From aa954713473d3a55d596e3485566563d44cfa4b0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Jul 2023 17:50:12 +0800
+Subject: media: amphion: fix UNUSED_VALUE issue reported by coverity
+
+From: Ming Qian <ming.qian@nxp.com>
+
+[ Upstream commit cf6a06354989c41b536be8e094561ee16223cf1f ]
+
+assign value '-EINVAL' to ret, but the stored value is overwritten
+before it can be used
+
+Fixes: 9f599f351e86 ("media: amphion: add vpu core driver")
+Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+Signed-off-by: Ming Qian <ming.qian@nxp.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/amphion/vpu_cmds.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/platform/amphion/vpu_cmds.c b/drivers/media/platform/amphion/vpu_cmds.c
+index 7e137f276c3b1..235b71398d403 100644
+--- a/drivers/media/platform/amphion/vpu_cmds.c
++++ b/drivers/media/platform/amphion/vpu_cmds.c
+@@ -315,7 +315,7 @@ static int vpu_session_send_cmd(struct vpu_inst *inst, u32 id, void *data)
+ {
+ unsigned long key;
+ int sync = false;
+- int ret = -EINVAL;
++ int ret;
+
+ if (inst->id < 0)
+ return -EINVAL;
+--
+2.40.1
+
--- /dev/null
+From c6bc8461e4d196a4407e95d909b663f126fc9ab3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Jun 2023 15:48:46 +0800
+Subject: media: amphion: reinit vpu if reqbufs output 0
+
+From: Ming Qian <ming.qian@nxp.com>
+
+[ Upstream commit 73e3f09292a0492a3fe0f87a8170a74f12624c5e ]
+
+according to v4l2 stateful decoder document 4.5.1.3. State Machine,
+the state should change from seek to initialization
+if call VIDIOC_REQBUFS(OUTPUT, 0).
+
+so reinit the vpu decoder if reqbufs output 0
+
+Fixes: 6de8d628df6e ("media: amphion: add v4l2 m2m vpu decoder stateful driver")
+Signed-off-by: Ming Qian <ming.qian@nxp.com>
+Tested-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/amphion/vdec.c | 2 --
+ drivers/media/platform/amphion/vpu_v4l2.c | 7 ++++++-
+ 2 files changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/media/platform/amphion/vdec.c b/drivers/media/platform/amphion/vdec.c
+index 6515f3cdb7a74..56c4deea4494d 100644
+--- a/drivers/media/platform/amphion/vdec.c
++++ b/drivers/media/platform/amphion/vdec.c
+@@ -1453,9 +1453,7 @@ static void vdec_release(struct vpu_inst *inst)
+ {
+ if (inst->id != VPU_INST_NULL_ID)
+ vpu_trace(inst->dev, "[%d]\n", inst->id);
+- vpu_inst_lock(inst);
+ vdec_stop(inst, true);
+- vpu_inst_unlock(inst);
+ }
+
+ static void vdec_cleanup(struct vpu_inst *inst)
+diff --git a/drivers/media/platform/amphion/vpu_v4l2.c b/drivers/media/platform/amphion/vpu_v4l2.c
+index 810e93d2c954a..8c9028df3bf42 100644
+--- a/drivers/media/platform/amphion/vpu_v4l2.c
++++ b/drivers/media/platform/amphion/vpu_v4l2.c
+@@ -489,6 +489,11 @@ static int vpu_vb2_queue_setup(struct vb2_queue *vq,
+ for (i = 0; i < cur_fmt->mem_planes; i++)
+ psize[i] = vpu_get_fmt_plane_size(cur_fmt, i);
+
++ if (V4L2_TYPE_IS_OUTPUT(vq->type) && inst->state == VPU_CODEC_STATE_SEEK) {
++ vpu_trace(inst->dev, "reinit when VIDIOC_REQBUFS(OUTPUT, 0)\n");
++ call_void_vop(inst, release);
++ }
++
+ return 0;
+ }
+
+@@ -773,9 +778,9 @@ int vpu_v4l2_close(struct file *file)
+ v4l2_m2m_ctx_release(inst->fh.m2m_ctx);
+ inst->fh.m2m_ctx = NULL;
+ }
++ call_void_vop(inst, release);
+ vpu_inst_unlock(inst);
+
+- call_void_vop(inst, release);
+ vpu_inst_unregister(inst);
+ vpu_inst_put(inst);
+
+--
+2.40.1
+
--- /dev/null
+From 1a06d8a3fbcd36e57946afd2c15e637785957c48 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 Jun 2023 15:58:37 +0200
+Subject: media: cec: core: add adap_nb_transmit_canceled() callback
+
+From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+
+[ Upstream commit da53c36ddd3f118a525a04faa8c47ca471e6c467 ]
+
+A potential deadlock was found by Zheng Zhang with a local syzkaller
+instance.
+
+The problem is that when a non-blocking CEC transmit is canceled by calling
+cec_data_cancel, that in turn can call the high-level received() driver
+callback, which can call cec_transmit_msg() to transmit a new message.
+
+The cec_data_cancel() function is called with the adap->lock mutex held,
+and cec_transmit_msg() tries to take that same lock.
+
+The root cause is that the received() callback can either be used to pass
+on a received message (and then adap->lock is not held), or to report a
+canceled transmit (and then adap->lock is held).
+
+This is confusing, so create a new low-level adap_nb_transmit_canceled
+callback that reports back that a non-blocking transmit was canceled.
+
+And the received() callback is only called when a message is received,
+as was the case before commit f9d0ecbf56f4 ("media: cec: correctly pass
+on reply results") complicated matters.
+
+Reported-by: Zheng Zhang <zheng.zhang@email.ucr.edu>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Fixes: f9d0ecbf56f4 ("media: cec: correctly pass on reply results")
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/cec/core/cec-adap.c | 4 ++--
+ include/media/cec.h | 6 ++++--
+ 2 files changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/media/cec/core/cec-adap.c b/drivers/media/cec/core/cec-adap.c
+index 241b1621b197c..a9b73fb33888d 100644
+--- a/drivers/media/cec/core/cec-adap.c
++++ b/drivers/media/cec/core/cec-adap.c
+@@ -385,8 +385,8 @@ static void cec_data_cancel(struct cec_data *data, u8 tx_status, u8 rx_status)
+ cec_queue_msg_monitor(adap, &data->msg, 1);
+
+ if (!data->blocking && data->msg.sequence)
+- /* Allow drivers to process the message first */
+- call_op(adap, received, &data->msg);
++ /* Allow drivers to react to a canceled transmit */
++ call_void_op(adap, adap_nb_transmit_canceled, &data->msg);
+
+ cec_data_completed(data);
+ }
+diff --git a/include/media/cec.h b/include/media/cec.h
+index abee41ae02d0e..6556cc161dc0a 100644
+--- a/include/media/cec.h
++++ b/include/media/cec.h
+@@ -121,14 +121,16 @@ struct cec_adap_ops {
+ void (*adap_configured)(struct cec_adapter *adap, bool configured);
+ int (*adap_transmit)(struct cec_adapter *adap, u8 attempts,
+ u32 signal_free_time, struct cec_msg *msg);
++ void (*adap_nb_transmit_canceled)(struct cec_adapter *adap,
++ const struct cec_msg *msg);
+ void (*adap_status)(struct cec_adapter *adap, struct seq_file *file);
+ void (*adap_free)(struct cec_adapter *adap);
+
+- /* Error injection callbacks */
++ /* Error injection callbacks, called without adap->lock held */
+ int (*error_inj_show)(struct cec_adapter *adap, struct seq_file *sf);
+ bool (*error_inj_parse_line)(struct cec_adapter *adap, char *line);
+
+- /* High-level CEC message callback */
++ /* High-level CEC message callback, called without adap->lock held */
+ int (*received)(struct cec_adapter *adap, struct cec_msg *msg);
+ };
+
+--
+2.40.1
+
--- /dev/null
+From 111753b814d3d81874c108df72609435b542c2ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 Jun 2023 15:58:38 +0200
+Subject: media: cec: core: add adap_unconfigured() callback
+
+From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+
+[ Upstream commit 948a77aaecf202f722cf2264025f9987e5bd5c26 ]
+
+The adap_configured() callback was called with the adap->lock mutex
+held if the 'configured' argument was false, and without the adap->lock
+mutex held if that argument was true.
+
+That was very confusing, and so split this up in a adap_unconfigured()
+callback and a high-level configured() callback.
+
+This also makes it easier to understand when the mutex is held: all
+low-level adap_* callbacks are called with the mutex held. All other
+callbacks are called without that mutex held.
+
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Fixes: f1b57164305d ("media: cec: add optional adap_configured callback")
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/cec/core/cec-adap.c | 4 ++--
+ include/media/cec.h | 5 +++--
+ 2 files changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/media/cec/core/cec-adap.c b/drivers/media/cec/core/cec-adap.c
+index a9b73fb33888d..09ca83c233299 100644
+--- a/drivers/media/cec/core/cec-adap.c
++++ b/drivers/media/cec/core/cec-adap.c
+@@ -1348,7 +1348,7 @@ static void cec_adap_unconfigure(struct cec_adapter *adap)
+ cec_flush(adap);
+ wake_up_interruptible(&adap->kthread_waitq);
+ cec_post_state_event(adap);
+- call_void_op(adap, adap_configured, false);
++ call_void_op(adap, adap_unconfigured);
+ }
+
+ /*
+@@ -1539,7 +1539,7 @@ static int cec_config_thread_func(void *arg)
+ adap->kthread_config = NULL;
+ complete(&adap->config_completion);
+ mutex_unlock(&adap->lock);
+- call_void_op(adap, adap_configured, true);
++ call_void_op(adap, configured);
+ return 0;
+
+ unconfigure:
+diff --git a/include/media/cec.h b/include/media/cec.h
+index 6556cc161dc0a..9c007f83569aa 100644
+--- a/include/media/cec.h
++++ b/include/media/cec.h
+@@ -113,12 +113,12 @@ struct cec_fh {
+ #define CEC_FREE_TIME_TO_USEC(ft) ((ft) * 2400)
+
+ struct cec_adap_ops {
+- /* Low-level callbacks */
++ /* Low-level callbacks, called with adap->lock held */
+ int (*adap_enable)(struct cec_adapter *adap, bool enable);
+ int (*adap_monitor_all_enable)(struct cec_adapter *adap, bool enable);
+ int (*adap_monitor_pin_enable)(struct cec_adapter *adap, bool enable);
+ int (*adap_log_addr)(struct cec_adapter *adap, u8 logical_addr);
+- void (*adap_configured)(struct cec_adapter *adap, bool configured);
++ void (*adap_unconfigured)(struct cec_adapter *adap);
+ int (*adap_transmit)(struct cec_adapter *adap, u8 attempts,
+ u32 signal_free_time, struct cec_msg *msg);
+ void (*adap_nb_transmit_canceled)(struct cec_adapter *adap,
+@@ -131,6 +131,7 @@ struct cec_adap_ops {
+ bool (*error_inj_parse_line)(struct cec_adapter *adap, char *line);
+
+ /* High-level CEC message callback, called without adap->lock held */
++ void (*configured)(struct cec_adapter *adap);
+ int (*received)(struct cec_adapter *adap, struct cec_msg *msg);
+ };
+
+--
+2.40.1
+
--- /dev/null
+From 3309759f3e16cd203228956000ae8e77a0a9ba80 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Jun 2023 01:55:01 -0700
+Subject: media: cx24120: Add retval check for cx24120_message_send()
+
+From: Daniil Dulov <d.dulov@aladdin.ru>
+
+[ Upstream commit 96002c0ac824e1773d3f706b1f92e2a9f2988047 ]
+
+If cx24120_message_send() returns error, we should keep local struct
+unchanged.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: 5afc9a25be8d ("[media] Add support for TechniSat Skystar S2")
+Signed-off-by: Daniil Dulov <d.dulov@aladdin.ru>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/dvb-frontends/cx24120.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c
+index d8acd582c7111..0f778660c72b8 100644
+--- a/drivers/media/dvb-frontends/cx24120.c
++++ b/drivers/media/dvb-frontends/cx24120.c
+@@ -973,7 +973,9 @@ static void cx24120_set_clock_ratios(struct dvb_frontend *fe)
+ cmd.arg[8] = (clock_ratios_table[idx].rate >> 8) & 0xff;
+ cmd.arg[9] = (clock_ratios_table[idx].rate >> 0) & 0xff;
+
+- cx24120_message_send(state, &cmd);
++ ret = cx24120_message_send(state, &cmd);
++ if (ret != 0)
++ return;
+
+ /* Calculate ber window rates for stat work */
+ cx24120_calculate_ber_window(state, clock_ratios_table[idx].rate);
+--
+2.40.1
+
--- /dev/null
+From 279781b41856bc755649bf3905948865d7fc3cce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Mar 2023 06:38:32 -0700
+Subject: media: dib7000p: Fix potential division by zero
+
+From: Daniil Dulov <d.dulov@aladdin.ru>
+
+[ Upstream commit a1db7b2c5533fc67e2681eb5efc921a67bc7d5b8 ]
+
+Variable loopdiv can be assigned 0, then it is used as a denominator,
+without checking it for 0.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: 713d54a8bd81 ("[media] DiB7090: add support for the dib7090 based")
+Signed-off-by: Daniil Dulov <d.dulov@aladdin.ru>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+[hverkuil: (bw != NULL) -> bw]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/dvb-frontends/dib7000p.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/dvb-frontends/dib7000p.c b/drivers/media/dvb-frontends/dib7000p.c
+index a90d2f51868ff..632534eff0ffa 100644
+--- a/drivers/media/dvb-frontends/dib7000p.c
++++ b/drivers/media/dvb-frontends/dib7000p.c
+@@ -497,7 +497,7 @@ static int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth
+ prediv = reg_1856 & 0x3f;
+ loopdiv = (reg_1856 >> 6) & 0x3f;
+
+- if ((bw != NULL) && (bw->pll_prediv != prediv || bw->pll_ratio != loopdiv)) {
++ if (loopdiv && bw && (bw->pll_prediv != prediv || bw->pll_ratio != loopdiv)) {
+ dprintk("Updating pll (prediv: old = %d new = %d ; loopdiv : old = %d new = %d)\n", prediv, bw->pll_prediv, loopdiv, bw->pll_ratio);
+ reg_1856 &= 0xf000;
+ reg_1857 = dib7000p_read_word(state, 1857);
+--
+2.40.1
+
--- /dev/null
+From f6875b20fbd52e667e5fc89a8e6bcea91f246b12 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Jul 2023 10:08:28 +0200
+Subject: media: Documentation: Fix [GS]_ROUTING documentation
+
+From: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+
+[ Upstream commit 997a6b01cd97b74684728d5af6511c333f25957d ]
+
+Add mention that successful VIDIOC_SUBDEV_G_ROUTING call will update
+'num_routes' and remove mention about non-existing streams, which is
+incorrect.
+
+Fixes: ea73eda50813 ("media: Documentation: Add GS_ROUTING documentation")
+Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../userspace-api/media/v4l/vidioc-subdev-g-routing.rst | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/Documentation/userspace-api/media/v4l/vidioc-subdev-g-routing.rst b/Documentation/userspace-api/media/v4l/vidioc-subdev-g-routing.rst
+index 2d6e3bbdd0404..72677a280cd64 100644
+--- a/Documentation/userspace-api/media/v4l/vidioc-subdev-g-routing.rst
++++ b/Documentation/userspace-api/media/v4l/vidioc-subdev-g-routing.rst
+@@ -58,6 +58,9 @@ the subdevice exposes, drivers return the ENOSPC error code and adjust the
+ value of the ``num_routes`` field. Application should then reserve enough memory
+ for all the route entries and call ``VIDIOC_SUBDEV_G_ROUTING`` again.
+
++On a successful ``VIDIOC_SUBDEV_G_ROUTING`` call the driver updates the
++``num_routes`` field to reflect the actual number of routes returned.
++
+ .. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+ .. c:type:: v4l2_subdev_routing
+@@ -138,9 +141,7 @@ ENOSPC
+
+ EINVAL
+ The sink or source pad identifiers reference a non-existing pad, or reference
+- pads of different types (ie. the sink_pad identifiers refers to a source pad)
+- or the sink or source stream identifiers reference a non-existing stream on
+- the sink or source pad.
++ pads of different types (ie. the sink_pad identifiers refers to a source pad).
+
+ E2BIG
+ The application provided ``num_routes`` for ``VIDIOC_SUBDEV_S_ROUTING`` is
+--
+2.40.1
+
--- /dev/null
+From 77db7f3789e9911d83cd7d7ee468d4115b38d923 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 May 2023 07:58:36 +0200
+Subject: media: dvb-usb: m920x: Fix a potential memory leak in
+ m920x_i2c_xfer()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit ea9ef6c2e001c5dc94bee35ebd1c8a98621cf7b8 ]
+
+'read' is freed when it is known to be NULL, but not when a read error
+occurs.
+
+Revert the logic to avoid a small leak, should a m920x_read() call fail.
+
+Fixes: a2ab06d7c4d6 ("media: m920x: don't use stack on USB reads")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/dvb-usb/m920x.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/usb/dvb-usb/m920x.c b/drivers/media/usb/dvb-usb/m920x.c
+index fea5bcf72a31a..c88a202daf5fc 100644
+--- a/drivers/media/usb/dvb-usb/m920x.c
++++ b/drivers/media/usb/dvb-usb/m920x.c
+@@ -277,7 +277,6 @@ static int m920x_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int nu
+ char *read = kmalloc(1, GFP_KERNEL);
+ if (!read) {
+ ret = -ENOMEM;
+- kfree(read);
+ goto unlock;
+ }
+
+@@ -288,8 +287,10 @@ static int m920x_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int nu
+
+ if ((ret = m920x_read(d->udev, M9206_I2C, 0x0,
+ 0x20 | stop,
+- read, 1)) != 0)
++ read, 1)) != 0) {
++ kfree(read);
+ goto unlock;
++ }
+ msg[i].buf[j] = read[0];
+ }
+
+--
+2.40.1
+
--- /dev/null
+From ad5573a7904256e4e411671bc734b35f27899fe3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Jul 2023 19:40:07 +0200
+Subject: media: go7007: Remove redundant if statement
+
+From: Colin Ian King <colin.i.king@gmail.com>
+
+[ Upstream commit f33cb49081da0ec5af0888f8ecbd566bd326eed1 ]
+
+The if statement that compares msgs[i].len != 3 is always false because
+it is in a code block where msg[i].len is equal to 3. The check is
+redundant and can be removed.
+
+As detected by cppcheck static analysis:
+drivers/media/usb/go7007/go7007-i2c.c:168:20: warning: Opposite inner
+'if' condition leads to a dead code block. [oppositeInnerCondition]
+
+Link: https://lore.kernel.org/linux-media/20230727174007.635572-1-colin.i.king@gmail.com
+
+Fixes: 866b8695d67e ("Staging: add the go7007 video driver")
+Signed-off-by: Colin Ian King <colin.i.king@gmail.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/go7007/go7007-i2c.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/media/usb/go7007/go7007-i2c.c b/drivers/media/usb/go7007/go7007-i2c.c
+index 38339dd2f83f7..2880370e45c8b 100644
+--- a/drivers/media/usb/go7007/go7007-i2c.c
++++ b/drivers/media/usb/go7007/go7007-i2c.c
+@@ -165,8 +165,6 @@ static int go7007_i2c_master_xfer(struct i2c_adapter *adapter,
+ } else if (msgs[i].len == 3) {
+ if (msgs[i].flags & I2C_M_RD)
+ return -EIO;
+- if (msgs[i].len != 3)
+- return -EIO;
+ if (go7007_i2c_xfer(go, msgs[i].addr, 0,
+ (msgs[i].buf[0] << 8) | msgs[i].buf[1],
+ 0x01, &msgs[i].buf[2]) < 0)
+--
+2.40.1
+
--- /dev/null
+From 500b46cf9a934d1a57d190e873d03597734b53b7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Jun 2023 10:07:34 +0200
+Subject: media: i2c: imx290: drop format param from imx290_ctrl_update
+
+From: Tommaso Merciai <tomm.merciai@gmail.com>
+
+[ Upstream commit 9b4e0e7a570d222be5f5e0f914d3c4528eadeeb4 ]
+
+The format param actually is not used in imx290_ctrl_update
+function, let's drop this
+
+Fixes: bc35f9a21a55 ("media: i2c: imx290: Fix the pixel rate at 148.5Mpix/s")
+Signed-off-by: Tommaso Merciai <tomm.merciai@gmail.com>
+Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/i2c/imx290.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/media/i2c/imx290.c b/drivers/media/i2c/imx290.c
+index 5ea25b7acc55f..a84b581682a21 100644
+--- a/drivers/media/i2c/imx290.c
++++ b/drivers/media/i2c/imx290.c
+@@ -902,7 +902,6 @@ static const char * const imx290_test_pattern_menu[] = {
+ };
+
+ static void imx290_ctrl_update(struct imx290 *imx290,
+- const struct v4l2_mbus_framefmt *format,
+ const struct imx290_mode *mode)
+ {
+ unsigned int hblank_min = mode->hmax_min - mode->width;
+@@ -1195,7 +1194,7 @@ static int imx290_set_fmt(struct v4l2_subdev *sd,
+ if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
+ imx290->current_mode = mode;
+
+- imx290_ctrl_update(imx290, &fmt->format, mode);
++ imx290_ctrl_update(imx290, mode);
+ imx290_exposure_update(imx290, mode);
+ }
+
+@@ -1300,7 +1299,6 @@ static const struct media_entity_operations imx290_subdev_entity_ops = {
+ static int imx290_subdev_init(struct imx290 *imx290)
+ {
+ struct i2c_client *client = to_i2c_client(imx290->dev);
+- const struct v4l2_mbus_framefmt *format;
+ struct v4l2_subdev_state *state;
+ int ret;
+
+@@ -1335,8 +1333,7 @@ static int imx290_subdev_init(struct imx290 *imx290)
+ }
+
+ state = v4l2_subdev_lock_and_get_active_state(&imx290->sd);
+- format = v4l2_subdev_get_pad_format(&imx290->sd, state, 0);
+- imx290_ctrl_update(imx290, format, imx290->current_mode);
++ imx290_ctrl_update(imx290, imx290->current_mode);
+ v4l2_subdev_unlock_state(state);
+
+ return 0;
+--
+2.40.1
+
--- /dev/null
+From 3fc7c5f0f234ba9016f7d47b3de31ab6f7e254ea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Aug 2023 15:33:37 +0200
+Subject: media: i2c: rdacm21: Fix uninitialized value
+
+From: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+
+[ Upstream commit 33c7ae8f49e3413c81e879e1fdfcea4c5516e37b ]
+
+Fix the following smatch warning:
+
+drivers/media/i2c/rdacm21.c:373 ov10640_check_id() error: uninitialized
+symbol 'val'.
+
+Initialize 'val' to 0 in the ov10640_check_id() function.
+
+Fixes: 2b821698dc73 ("media: i2c: rdacm21: Power up OV10640 before OV490")
+Reported-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/i2c/rdacm21.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/i2c/rdacm21.c b/drivers/media/i2c/rdacm21.c
+index 9ccc56c30d3b0..d269c541ebe4c 100644
+--- a/drivers/media/i2c/rdacm21.c
++++ b/drivers/media/i2c/rdacm21.c
+@@ -351,7 +351,7 @@ static void ov10640_power_up(struct rdacm21_device *dev)
+ static int ov10640_check_id(struct rdacm21_device *dev)
+ {
+ unsigned int i;
+- u8 val;
++ u8 val = 0;
+
+ /* Read OV10640 ID to test communications. */
+ for (i = 0; i < OV10640_PID_TIMEOUT; ++i) {
+--
+2.40.1
+
--- /dev/null
+From 52166e1101c8dd26232a4cdd387769f170acf48e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Jun 2023 12:30:30 +0200
+Subject: media: i2c: tvp5150: check return value of devm_kasprintf()
+
+From: Claudiu Beznea <claudiu.beznea@microchip.com>
+
+[ Upstream commit 26ce7054d804be73935b9268d6e0ecf2fbbc8aef ]
+
+devm_kasprintf() returns a pointer to dynamically allocated memory.
+Pointer could be NULL in case allocation fails. Check pointer validity.
+Identified with coccinelle (kmerr.cocci script).
+
+Fixes: 0556f1d580d4 ("media: tvp5150: add input source selection of_graph support")
+Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
+Reviewed-by: Marco Felsch <m.felsch@pengutronix.de>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/i2c/tvp5150.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c
+index 859f1cb2fa744..84f87c016f9b5 100644
+--- a/drivers/media/i2c/tvp5150.c
++++ b/drivers/media/i2c/tvp5150.c
+@@ -2068,6 +2068,10 @@ static int tvp5150_parse_dt(struct tvp5150 *decoder, struct device_node *np)
+ tvpc->ent.name = devm_kasprintf(dev, GFP_KERNEL, "%s %s",
+ v4l2c->name, v4l2c->label ?
+ v4l2c->label : "");
++ if (!tvpc->ent.name) {
++ ret = -ENOMEM;
++ goto err_free;
++ }
+ }
+
+ ep_np = of_graph_get_endpoint_by_regs(np, TVP5150_PAD_VID_OUT, 0);
+--
+2.40.1
+
--- /dev/null
+From 5719fba3aeaf8531f65de2661ac91f9fbf0ad1e9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Jul 2023 23:29:54 +0200
+Subject: media: ipu-bridge: Do not use on stack memory for software_node.name
+ field
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 11e0a7c8e04ee5f406f2baa27761746cbedcfa11 ]
+
+Commit 567f97bd381f ("media: ipu3-cio2: support multiple sensors and VCMs
+with same HID") introduced an on stack vcm_name and then uses this for
+the name field of the software_node struct used for the vcm.
+
+But the software_node struct is much longer lived then the current
+stack-frame, so this is no good.
+
+Instead extend the ipu_node_names struct with an extra field to store
+the vcm software_node name and use that.
+
+Note this also changes the length of the allocated buffer from
+ACPI_ID_LEN + 4 to 16. the name is filled with "<ipu_vcm_types[x]>-%u"
+where ipu_vcm_types[x] is not an ACPI_ID. The maximum length of
+the strings in the ipu_vcm_types[] array is 11 + 5 bytes for "-255\0"
+means 16 bytes are needed in the worst case scenario.
+
+Fixes: 567f97bd381f ("media: ipu3-cio2: support multiple sensors and VCMs with same HID")
+Cc: Bingbu Cao <bingbu.cao@intel.com>
+Reviewed-by: Andy Shevchenko <andy@kernel.org>
+Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/pci/intel/ipu-bridge.c | 7 +++----
+ drivers/media/pci/intel/ipu-bridge.h | 1 +
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/media/pci/intel/ipu-bridge.c b/drivers/media/pci/intel/ipu-bridge.c
+index 38fa756602bc0..88490ea304dee 100644
+--- a/drivers/media/pci/intel/ipu-bridge.c
++++ b/drivers/media/pci/intel/ipu-bridge.c
+@@ -220,7 +220,6 @@ static void ipu_bridge_create_connection_swnodes(struct ipu_bridge *bridge,
+ struct ipu_sensor *sensor)
+ {
+ struct software_node *nodes = sensor->swnodes;
+- char vcm_name[ACPI_ID_LEN + 4];
+
+ ipu_bridge_init_swnode_names(sensor);
+
+@@ -240,10 +239,10 @@ static void ipu_bridge_create_connection_swnodes(struct ipu_bridge *bridge,
+ sensor->ipu_properties);
+ if (sensor->ssdb.vcmtype) {
+ /* append ssdb.link to distinguish VCM nodes with same HID */
+- snprintf(vcm_name, sizeof(vcm_name), "%s-%u",
+- ipu_vcm_types[sensor->ssdb.vcmtype - 1],
++ snprintf(sensor->node_names.vcm, sizeof(sensor->node_names.vcm),
++ "%s-%u", ipu_vcm_types[sensor->ssdb.vcmtype - 1],
+ sensor->ssdb.link);
+- nodes[SWNODE_VCM] = NODE_VCM(vcm_name);
++ nodes[SWNODE_VCM] = NODE_VCM(sensor->node_names.vcm);
+ }
+
+ ipu_bridge_init_swnode_group(sensor);
+diff --git a/drivers/media/pci/intel/ipu-bridge.h b/drivers/media/pci/intel/ipu-bridge.h
+index d35b5f30ac3fc..1ff0b2d04d929 100644
+--- a/drivers/media/pci/intel/ipu-bridge.h
++++ b/drivers/media/pci/intel/ipu-bridge.h
+@@ -104,6 +104,7 @@ struct ipu_node_names {
+ char port[7];
+ char endpoint[11];
+ char remote_port[7];
++ char vcm[16];
+ };
+
+ struct ipu_sensor_config {
+--
+2.40.1
+
--- /dev/null
+From 5a51daefb49e6d45a9fec470f579dea5a493e2f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Jul 2023 23:29:53 +0200
+Subject: media: ipu-bridge: Fix null pointer deref on SSDB/PLD parsing
+ warnings
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 284be5693163343e1cf17c03917eecd1d6681bcf ]
+
+When ipu_bridge_parse_rotation() and ipu_bridge_parse_orientation() run
+sensor->adev is not set yet.
+
+So if either of the dev_warn() calls about unknown values are hit this
+will lead to a NULL pointer deref.
+
+Set sensor->adev earlier, with a borrowed ref to avoid making unrolling
+on errors harder, to fix this.
+
+Fixes: 485aa3df0dff ("media: ipu3-cio2: Parse sensor orientation and rotation")
+Cc: Fabian Wüthrich <me@fabwu.ch>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/pci/intel/ipu3/cio2-bridge.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/media/pci/intel/ipu3/cio2-bridge.c b/drivers/media/pci/intel/ipu3/cio2-bridge.c
+index 3c2accfe54551..7fba87736b6b8 100644
+--- a/drivers/media/pci/intel/ipu3/cio2-bridge.c
++++ b/drivers/media/pci/intel/ipu3/cio2-bridge.c
+@@ -308,6 +308,11 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg,
+ }
+
+ sensor = &bridge->sensors[bridge->n_sensors];
++ /*
++ * Borrow our adev ref to the sensor for now, on success
++ * acpi_dev_get(adev) is done further below.
++ */
++ sensor->adev = adev;
+
+ ret = cio2_bridge_read_acpi_buffer(adev, "SSDB",
+ &sensor->ssdb,
+--
+2.40.1
+
--- /dev/null
+From 96dd6b3bad83f1cbb25d6aa00668c13d9ff7ac3e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 May 2023 12:05:21 +0200
+Subject: media: ipu3-cio2: rename cio2 bridge to ipu bridge and move out of
+ ipu3
+
+From: Bingbu Cao <bingbu.cao@intel.com>
+
+[ Upstream commit 881ca25978c6f536a00205daa8b2452edd057ff9 ]
+
+cio2 bridge was involved along with IPU3. However, in fact all Intel IPUs
+besides IPU3 CIO2 need this bridge driver. This patch move bridge driver
+out of ipu3 directory and rename as ipu-bridge. Then it can be worked with
+IPU3 and other Intel IPUs.
+
+Signed-off-by: Bingbu Cao <bingbu.cao@intel.com>
+Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Stable-dep-of: 11e0a7c8e04e ("media: ipu-bridge: Do not use on stack memory for software_node.name field")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/pci/Kconfig | 2 +-
+ drivers/media/pci/intel/Kconfig | 21 +++
+ drivers/media/pci/intel/Makefile | 4 +-
+ .../{ipu3/cio2-bridge.c => ipu-bridge.c} | 177 +++++++++---------
+ .../{ipu3/cio2-bridge.h => ipu-bridge.h} | 56 +++---
+ drivers/media/pci/intel/ipu3/Kconfig | 19 --
+ drivers/media/pci/intel/ipu3/Makefile | 1 -
+ drivers/media/pci/intel/ipu3/ipu3-cio2-main.c | 4 +-
+ drivers/media/pci/intel/ipu3/ipu3-cio2.h | 6 -
+ 9 files changed, 147 insertions(+), 143 deletions(-)
+ create mode 100644 drivers/media/pci/intel/Kconfig
+ rename drivers/media/pci/intel/{ipu3/cio2-bridge.c => ipu-bridge.c} (69%)
+ rename drivers/media/pci/intel/{ipu3/cio2-bridge.h => ipu-bridge.h} (72%)
+
+diff --git a/drivers/media/pci/Kconfig b/drivers/media/pci/Kconfig
+index 480194543d055..ee095bde0b686 100644
+--- a/drivers/media/pci/Kconfig
++++ b/drivers/media/pci/Kconfig
+@@ -73,7 +73,7 @@ config VIDEO_PCI_SKELETON
+ Enable build of the skeleton PCI driver, used as a reference
+ when developing new drivers.
+
+-source "drivers/media/pci/intel/ipu3/Kconfig"
++source "drivers/media/pci/intel/Kconfig"
+
+ endif #MEDIA_PCI_SUPPORT
+ endif #PCI
+diff --git a/drivers/media/pci/intel/Kconfig b/drivers/media/pci/intel/Kconfig
+new file mode 100644
+index 0000000000000..64a29b0b7033b
+--- /dev/null
++++ b/drivers/media/pci/intel/Kconfig
+@@ -0,0 +1,21 @@
++# SPDX-License-Identifier: GPL-2.0-only
++config IPU_BRIDGE
++ bool "Intel IPU Sensors Bridge"
++ depends on VIDEO_IPU3_CIO2 && ACPI
++ depends on I2C
++ help
++ This extension provides an API for the Intel IPU driver to create
++ connections to cameras that are hidden in the SSDB buffer in ACPI.
++ It can be used to enable support for cameras in detachable / hybrid
++ devices that ship with Windows.
++
++ Say Y here if your device is a detachable / hybrid laptop that comes
++ with Windows installed by the OEM, for example:
++
++ - Microsoft Surface models (except Surface Pro 3)
++ - The Lenovo Miix line (for example the 510, 520, 710 and 720)
++ - Dell 7285
++
++ If in doubt, say N here.
++
++source "drivers/media/pci/intel/ipu3/Kconfig"
+diff --git a/drivers/media/pci/intel/Makefile b/drivers/media/pci/intel/Makefile
+index 0b4236c4db49a..951191a7e4011 100644
+--- a/drivers/media/pci/intel/Makefile
++++ b/drivers/media/pci/intel/Makefile
+@@ -1,6 +1,6 @@
+ # SPDX-License-Identifier: GPL-2.0-only
+ #
+-# Makefile for the IPU3 cio2 and ImGU drivers
++# Makefile for the IPU drivers
+ #
+-
++obj-$(CONFIG_IPU_BRIDGE) += ipu-bridge.o
+ obj-y += ipu3/
+diff --git a/drivers/media/pci/intel/ipu3/cio2-bridge.c b/drivers/media/pci/intel/ipu-bridge.c
+similarity index 69%
+rename from drivers/media/pci/intel/ipu3/cio2-bridge.c
+rename to drivers/media/pci/intel/ipu-bridge.c
+index 7fba87736b6b8..38fa756602bc0 100644
+--- a/drivers/media/pci/intel/ipu3/cio2-bridge.c
++++ b/drivers/media/pci/intel/ipu-bridge.c
+@@ -8,7 +8,7 @@
+ #include <linux/property.h>
+ #include <media/v4l2-fwnode.h>
+
+-#include "cio2-bridge.h"
++#include "ipu-bridge.h"
+
+ /*
+ * Extend this array with ACPI Hardware IDs of devices known to be working
+@@ -20,26 +20,26 @@
+ *
+ * Do not add an entry for a sensor that is not actually supported.
+ */
+-static const struct cio2_sensor_config cio2_supported_sensors[] = {
++static const struct ipu_sensor_config ipu_supported_sensors[] = {
+ /* Omnivision OV5693 */
+- CIO2_SENSOR_CONFIG("INT33BE", 1, 419200000),
++ IPU_SENSOR_CONFIG("INT33BE", 1, 419200000),
+ /* Omnivision OV8865 */
+- CIO2_SENSOR_CONFIG("INT347A", 1, 360000000),
++ IPU_SENSOR_CONFIG("INT347A", 1, 360000000),
+ /* Omnivision OV7251 */
+- CIO2_SENSOR_CONFIG("INT347E", 1, 319200000),
++ IPU_SENSOR_CONFIG("INT347E", 1, 319200000),
+ /* Omnivision OV2680 */
+- CIO2_SENSOR_CONFIG("OVTI2680", 0),
++ IPU_SENSOR_CONFIG("OVTI2680", 0),
+ /* Omnivision ov8856 */
+- CIO2_SENSOR_CONFIG("OVTI8856", 3, 180000000, 360000000, 720000000),
++ IPU_SENSOR_CONFIG("OVTI8856", 3, 180000000, 360000000, 720000000),
+ /* Omnivision ov2740 */
+- CIO2_SENSOR_CONFIG("INT3474", 1, 360000000),
++ IPU_SENSOR_CONFIG("INT3474", 1, 360000000),
+ /* Hynix hi556 */
+- CIO2_SENSOR_CONFIG("INT3537", 1, 437000000),
++ IPU_SENSOR_CONFIG("INT3537", 1, 437000000),
+ /* Omnivision ov13b10 */
+- CIO2_SENSOR_CONFIG("OVTIDB10", 1, 560000000),
++ IPU_SENSOR_CONFIG("OVTIDB10", 1, 560000000),
+ };
+
+-static const struct cio2_property_names prop_names = {
++static const struct ipu_property_names prop_names = {
+ .clock_frequency = "clock-frequency",
+ .rotation = "rotation",
+ .orientation = "orientation",
+@@ -49,7 +49,7 @@ static const struct cio2_property_names prop_names = {
+ .link_frequencies = "link-frequencies",
+ };
+
+-static const char * const cio2_vcm_types[] = {
++static const char * const ipu_vcm_types[] = {
+ "ad5823",
+ "dw9714",
+ "ad5816",
+@@ -61,8 +61,8 @@ static const char * const cio2_vcm_types[] = {
+ "lc898212axb",
+ };
+
+-static int cio2_bridge_read_acpi_buffer(struct acpi_device *adev, char *id,
+- void *data, u32 size)
++static int ipu_bridge_read_acpi_buffer(struct acpi_device *adev, char *id,
++ void *data, u32 size)
+ {
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ union acpi_object *obj;
+@@ -98,12 +98,12 @@ static int cio2_bridge_read_acpi_buffer(struct acpi_device *adev, char *id,
+ return ret;
+ }
+
+-static u32 cio2_bridge_parse_rotation(struct cio2_sensor *sensor)
++static u32 ipu_bridge_parse_rotation(struct ipu_sensor *sensor)
+ {
+ switch (sensor->ssdb.degree) {
+- case CIO2_SENSOR_ROTATION_NORMAL:
++ case IPU_SENSOR_ROTATION_NORMAL:
+ return 0;
+- case CIO2_SENSOR_ROTATION_INVERTED:
++ case IPU_SENSOR_ROTATION_INVERTED:
+ return 180;
+ default:
+ dev_warn(&sensor->adev->dev,
+@@ -113,7 +113,7 @@ static u32 cio2_bridge_parse_rotation(struct cio2_sensor *sensor)
+ }
+ }
+
+-static enum v4l2_fwnode_orientation cio2_bridge_parse_orientation(struct cio2_sensor *sensor)
++static enum v4l2_fwnode_orientation ipu_bridge_parse_orientation(struct ipu_sensor *sensor)
+ {
+ switch (sensor->pld->panel) {
+ case ACPI_PLD_PANEL_FRONT:
+@@ -132,20 +132,20 @@ static enum v4l2_fwnode_orientation cio2_bridge_parse_orientation(struct cio2_se
+ }
+ }
+
+-static void cio2_bridge_create_fwnode_properties(
+- struct cio2_sensor *sensor,
+- struct cio2_bridge *bridge,
+- const struct cio2_sensor_config *cfg)
++static void ipu_bridge_create_fwnode_properties(
++ struct ipu_sensor *sensor,
++ struct ipu_bridge *bridge,
++ const struct ipu_sensor_config *cfg)
+ {
+ u32 rotation;
+ enum v4l2_fwnode_orientation orientation;
+
+- rotation = cio2_bridge_parse_rotation(sensor);
+- orientation = cio2_bridge_parse_orientation(sensor);
++ rotation = ipu_bridge_parse_rotation(sensor);
++ orientation = ipu_bridge_parse_orientation(sensor);
+
+ sensor->prop_names = prop_names;
+
+- sensor->local_ref[0] = SOFTWARE_NODE_REFERENCE(&sensor->swnodes[SWNODE_CIO2_ENDPOINT]);
++ sensor->local_ref[0] = SOFTWARE_NODE_REFERENCE(&sensor->swnodes[SWNODE_IPU_ENDPOINT]);
+ sensor->remote_ref[0] = SOFTWARE_NODE_REFERENCE(&sensor->swnodes[SWNODE_SENSOR_ENDPOINT]);
+
+ sensor->dev_properties[0] = PROPERTY_ENTRY_U32(
+@@ -181,16 +181,16 @@ static void cio2_bridge_create_fwnode_properties(
+ cfg->link_freqs,
+ cfg->nr_link_freqs);
+
+- sensor->cio2_properties[0] = PROPERTY_ENTRY_U32_ARRAY_LEN(
++ sensor->ipu_properties[0] = PROPERTY_ENTRY_U32_ARRAY_LEN(
+ sensor->prop_names.data_lanes,
+ bridge->data_lanes,
+ sensor->ssdb.lanes);
+- sensor->cio2_properties[1] = PROPERTY_ENTRY_REF_ARRAY(
++ sensor->ipu_properties[1] = PROPERTY_ENTRY_REF_ARRAY(
+ sensor->prop_names.remote_endpoint,
+ sensor->remote_ref);
+ }
+
+-static void cio2_bridge_init_swnode_names(struct cio2_sensor *sensor)
++static void ipu_bridge_init_swnode_names(struct ipu_sensor *sensor)
+ {
+ snprintf(sensor->node_names.remote_port,
+ sizeof(sensor->node_names.remote_port),
+@@ -203,26 +203,26 @@ static void cio2_bridge_init_swnode_names(struct cio2_sensor *sensor)
+ SWNODE_GRAPH_ENDPOINT_NAME_FMT, 0); /* And endpoint 0 */
+ }
+
+-static void cio2_bridge_init_swnode_group(struct cio2_sensor *sensor)
++static void ipu_bridge_init_swnode_group(struct ipu_sensor *sensor)
+ {
+ struct software_node *nodes = sensor->swnodes;
+
+ sensor->group[SWNODE_SENSOR_HID] = &nodes[SWNODE_SENSOR_HID];
+ sensor->group[SWNODE_SENSOR_PORT] = &nodes[SWNODE_SENSOR_PORT];
+ sensor->group[SWNODE_SENSOR_ENDPOINT] = &nodes[SWNODE_SENSOR_ENDPOINT];
+- sensor->group[SWNODE_CIO2_PORT] = &nodes[SWNODE_CIO2_PORT];
+- sensor->group[SWNODE_CIO2_ENDPOINT] = &nodes[SWNODE_CIO2_ENDPOINT];
++ sensor->group[SWNODE_IPU_PORT] = &nodes[SWNODE_IPU_PORT];
++ sensor->group[SWNODE_IPU_ENDPOINT] = &nodes[SWNODE_IPU_ENDPOINT];
+ if (sensor->ssdb.vcmtype)
+ sensor->group[SWNODE_VCM] = &nodes[SWNODE_VCM];
+ }
+
+-static void cio2_bridge_create_connection_swnodes(struct cio2_bridge *bridge,
+- struct cio2_sensor *sensor)
++static void ipu_bridge_create_connection_swnodes(struct ipu_bridge *bridge,
++ struct ipu_sensor *sensor)
+ {
+ struct software_node *nodes = sensor->swnodes;
+ char vcm_name[ACPI_ID_LEN + 4];
+
+- cio2_bridge_init_swnode_names(sensor);
++ ipu_bridge_init_swnode_names(sensor);
+
+ nodes[SWNODE_SENSOR_HID] = NODE_SENSOR(sensor->name,
+ sensor->dev_properties);
+@@ -232,24 +232,24 @@ static void cio2_bridge_create_connection_swnodes(struct cio2_bridge *bridge,
+ sensor->node_names.endpoint,
+ &nodes[SWNODE_SENSOR_PORT],
+ sensor->ep_properties);
+- nodes[SWNODE_CIO2_PORT] = NODE_PORT(sensor->node_names.remote_port,
+- &bridge->cio2_hid_node);
+- nodes[SWNODE_CIO2_ENDPOINT] = NODE_ENDPOINT(
++ nodes[SWNODE_IPU_PORT] = NODE_PORT(sensor->node_names.remote_port,
++ &bridge->ipu_hid_node);
++ nodes[SWNODE_IPU_ENDPOINT] = NODE_ENDPOINT(
+ sensor->node_names.endpoint,
+- &nodes[SWNODE_CIO2_PORT],
+- sensor->cio2_properties);
++ &nodes[SWNODE_IPU_PORT],
++ sensor->ipu_properties);
+ if (sensor->ssdb.vcmtype) {
+ /* append ssdb.link to distinguish VCM nodes with same HID */
+ snprintf(vcm_name, sizeof(vcm_name), "%s-%u",
+- cio2_vcm_types[sensor->ssdb.vcmtype - 1],
++ ipu_vcm_types[sensor->ssdb.vcmtype - 1],
+ sensor->ssdb.link);
+ nodes[SWNODE_VCM] = NODE_VCM(vcm_name);
+ }
+
+- cio2_bridge_init_swnode_group(sensor);
++ ipu_bridge_init_swnode_group(sensor);
+ }
+
+-static void cio2_bridge_instantiate_vcm_i2c_client(struct cio2_sensor *sensor)
++static void ipu_bridge_instantiate_vcm_i2c_client(struct ipu_sensor *sensor)
+ {
+ struct i2c_board_info board_info = { };
+ char name[16];
+@@ -259,7 +259,7 @@ static void cio2_bridge_instantiate_vcm_i2c_client(struct cio2_sensor *sensor)
+
+ snprintf(name, sizeof(name), "%s-VCM", acpi_dev_name(sensor->adev));
+ board_info.dev_name = name;
+- strscpy(board_info.type, cio2_vcm_types[sensor->ssdb.vcmtype - 1],
++ strscpy(board_info.type, ipu_vcm_types[sensor->ssdb.vcmtype - 1],
+ ARRAY_SIZE(board_info.type));
+ board_info.swnode = &sensor->swnodes[SWNODE_VCM];
+
+@@ -273,9 +273,9 @@ static void cio2_bridge_instantiate_vcm_i2c_client(struct cio2_sensor *sensor)
+ }
+ }
+
+-static void cio2_bridge_unregister_sensors(struct cio2_bridge *bridge)
++static void ipu_bridge_unregister_sensors(struct ipu_bridge *bridge)
+ {
+- struct cio2_sensor *sensor;
++ struct ipu_sensor *sensor;
+ unsigned int i;
+
+ for (i = 0; i < bridge->n_sensors; i++) {
+@@ -287,12 +287,12 @@ static void cio2_bridge_unregister_sensors(struct cio2_bridge *bridge)
+ }
+ }
+
+-static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg,
+- struct cio2_bridge *bridge,
+- struct pci_dev *cio2)
++static int ipu_bridge_connect_sensor(const struct ipu_sensor_config *cfg,
++ struct ipu_bridge *bridge,
++ struct pci_dev *ipu)
+ {
+ struct fwnode_handle *fwnode, *primary;
+- struct cio2_sensor *sensor;
++ struct ipu_sensor *sensor;
+ struct acpi_device *adev;
+ acpi_status status;
+ int ret;
+@@ -303,7 +303,7 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg,
+
+ if (bridge->n_sensors >= CIO2_NUM_PORTS) {
+ acpi_dev_put(adev);
+- dev_err(&cio2->dev, "Exceeded available CIO2 ports\n");
++ dev_err(&ipu->dev, "Exceeded available IPU ports\n");
+ return -EINVAL;
+ }
+
+@@ -314,16 +314,16 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg,
+ */
+ sensor->adev = adev;
+
+- ret = cio2_bridge_read_acpi_buffer(adev, "SSDB",
+- &sensor->ssdb,
+- sizeof(sensor->ssdb));
++ ret = ipu_bridge_read_acpi_buffer(adev, "SSDB",
++ &sensor->ssdb,
++ sizeof(sensor->ssdb));
+ if (ret)
+ goto err_put_adev;
+
+ snprintf(sensor->name, sizeof(sensor->name), "%s-%u",
+ cfg->hid, sensor->ssdb.link);
+
+- if (sensor->ssdb.vcmtype > ARRAY_SIZE(cio2_vcm_types)) {
++ if (sensor->ssdb.vcmtype > ARRAY_SIZE(ipu_vcm_types)) {
+ dev_warn(&adev->dev, "Unknown VCM type %d\n",
+ sensor->ssdb.vcmtype);
+ sensor->ssdb.vcmtype = 0;
+@@ -335,15 +335,15 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg,
+ goto err_put_adev;
+ }
+
+- if (sensor->ssdb.lanes > CIO2_MAX_LANES) {
++ if (sensor->ssdb.lanes > IPU_MAX_LANES) {
+ dev_err(&adev->dev,
+ "Number of lanes in SSDB is invalid\n");
+ ret = -EINVAL;
+ goto err_free_pld;
+ }
+
+- cio2_bridge_create_fwnode_properties(sensor, bridge, cfg);
+- cio2_bridge_create_connection_swnodes(bridge, sensor);
++ ipu_bridge_create_fwnode_properties(sensor, bridge, cfg);
++ ipu_bridge_create_connection_swnodes(bridge, sensor);
+
+ ret = software_node_register_node_group(sensor->group);
+ if (ret)
+@@ -361,9 +361,9 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg,
+ primary = acpi_fwnode_handle(adev);
+ primary->secondary = fwnode;
+
+- cio2_bridge_instantiate_vcm_i2c_client(sensor);
++ ipu_bridge_instantiate_vcm_i2c_client(sensor);
+
+- dev_info(&cio2->dev, "Found supported sensor %s\n",
++ dev_info(&ipu->dev, "Found supported sensor %s\n",
+ acpi_dev_name(adev));
+
+ bridge->n_sensors++;
+@@ -380,17 +380,17 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg,
+ return ret;
+ }
+
+-static int cio2_bridge_connect_sensors(struct cio2_bridge *bridge,
+- struct pci_dev *cio2)
++static int ipu_bridge_connect_sensors(struct ipu_bridge *bridge,
++ struct pci_dev *ipu)
+ {
+ unsigned int i;
+ int ret;
+
+- for (i = 0; i < ARRAY_SIZE(cio2_supported_sensors); i++) {
+- const struct cio2_sensor_config *cfg =
+- &cio2_supported_sensors[i];
++ for (i = 0; i < ARRAY_SIZE(ipu_supported_sensors); i++) {
++ const struct ipu_sensor_config *cfg =
++ &ipu_supported_sensors[i];
+
+- ret = cio2_bridge_connect_sensor(cfg, bridge, cio2);
++ ret = ipu_bridge_connect_sensor(cfg, bridge, ipu);
+ if (ret)
+ goto err_unregister_sensors;
+ }
+@@ -398,7 +398,7 @@ static int cio2_bridge_connect_sensors(struct cio2_bridge *bridge,
+ return 0;
+
+ err_unregister_sensors:
+- cio2_bridge_unregister_sensors(bridge);
++ ipu_bridge_unregister_sensors(bridge);
+ return ret;
+ }
+
+@@ -414,15 +414,15 @@ static int cio2_bridge_connect_sensors(struct cio2_bridge *bridge,
+ * acpi_dev_ready_for_enumeration() helper, like the i2c-core-acpi code does
+ * for the sensors.
+ */
+-static int cio2_bridge_sensors_are_ready(void)
++static int ipu_bridge_sensors_are_ready(void)
+ {
+ struct acpi_device *adev;
+ bool ready = true;
+ unsigned int i;
+
+- for (i = 0; i < ARRAY_SIZE(cio2_supported_sensors); i++) {
+- const struct cio2_sensor_config *cfg =
+- &cio2_supported_sensors[i];
++ for (i = 0; i < ARRAY_SIZE(ipu_supported_sensors); i++) {
++ const struct ipu_sensor_config *cfg =
++ &ipu_supported_sensors[i];
+
+ for_each_acpi_dev_match(adev, cfg->hid, NULL, -1) {
+ if (!adev->status.enabled)
+@@ -436,50 +436,50 @@ static int cio2_bridge_sensors_are_ready(void)
+ return ready;
+ }
+
+-int cio2_bridge_init(struct pci_dev *cio2)
++int ipu_bridge_init(struct pci_dev *ipu)
+ {
+- struct device *dev = &cio2->dev;
++ struct device *dev = &ipu->dev;
+ struct fwnode_handle *fwnode;
+- struct cio2_bridge *bridge;
++ struct ipu_bridge *bridge;
+ unsigned int i;
+ int ret;
+
+- if (!cio2_bridge_sensors_are_ready())
++ if (!ipu_bridge_sensors_are_ready())
+ return -EPROBE_DEFER;
+
+ bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
+ if (!bridge)
+ return -ENOMEM;
+
+- strscpy(bridge->cio2_node_name, CIO2_HID,
+- sizeof(bridge->cio2_node_name));
+- bridge->cio2_hid_node.name = bridge->cio2_node_name;
++ strscpy(bridge->ipu_node_name, IPU_HID,
++ sizeof(bridge->ipu_node_name));
++ bridge->ipu_hid_node.name = bridge->ipu_node_name;
+
+- ret = software_node_register(&bridge->cio2_hid_node);
++ ret = software_node_register(&bridge->ipu_hid_node);
+ if (ret < 0) {
+- dev_err(dev, "Failed to register the CIO2 HID node\n");
++ dev_err(dev, "Failed to register the IPU HID node\n");
+ goto err_free_bridge;
+ }
+
+ /*
+ * Map the lane arrangement, which is fixed for the IPU3 (meaning we
+ * only need one, rather than one per sensor). We include it as a
+- * member of the struct cio2_bridge rather than a global variable so
++ * member of the struct ipu_bridge rather than a global variable so
+ * that it survives if the module is unloaded along with the rest of
+ * the struct.
+ */
+- for (i = 0; i < CIO2_MAX_LANES; i++)
++ for (i = 0; i < IPU_MAX_LANES; i++)
+ bridge->data_lanes[i] = i + 1;
+
+- ret = cio2_bridge_connect_sensors(bridge, cio2);
++ ret = ipu_bridge_connect_sensors(bridge, ipu);
+ if (ret || bridge->n_sensors == 0)
+- goto err_unregister_cio2;
++ goto err_unregister_ipu;
+
+ dev_info(dev, "Connected %d cameras\n", bridge->n_sensors);
+
+- fwnode = software_node_fwnode(&bridge->cio2_hid_node);
++ fwnode = software_node_fwnode(&bridge->ipu_hid_node);
+ if (!fwnode) {
+- dev_err(dev, "Error getting fwnode from cio2 software_node\n");
++ dev_err(dev, "Error getting fwnode from ipu software_node\n");
+ ret = -ENODEV;
+ goto err_unregister_sensors;
+ }
+@@ -489,11 +489,12 @@ int cio2_bridge_init(struct pci_dev *cio2)
+ return 0;
+
+ err_unregister_sensors:
+- cio2_bridge_unregister_sensors(bridge);
+-err_unregister_cio2:
+- software_node_unregister(&bridge->cio2_hid_node);
++ ipu_bridge_unregister_sensors(bridge);
++err_unregister_ipu:
++ software_node_unregister(&bridge->ipu_hid_node);
+ err_free_bridge:
+ kfree(bridge);
+
+ return ret;
+ }
++EXPORT_SYMBOL_NS_GPL(ipu_bridge_init, INTEL_IPU_BRIDGE);
+diff --git a/drivers/media/pci/intel/ipu3/cio2-bridge.h b/drivers/media/pci/intel/ipu-bridge.h
+similarity index 72%
+rename from drivers/media/pci/intel/ipu3/cio2-bridge.h
+rename to drivers/media/pci/intel/ipu-bridge.h
+index b76ed8a641e20..d35b5f30ac3fc 100644
+--- a/drivers/media/pci/intel/ipu3/cio2-bridge.h
++++ b/drivers/media/pci/intel/ipu-bridge.h
+@@ -1,25 +1,25 @@
+ /* SPDX-License-Identifier: GPL-2.0 */
+ /* Author: Dan Scally <djrscally@gmail.com> */
+-#ifndef __CIO2_BRIDGE_H
+-#define __CIO2_BRIDGE_H
++#ifndef __IPU_BRIDGE_H
++#define __IPU_BRIDGE_H
+
+ #include <linux/property.h>
+ #include <linux/types.h>
+
+-#include "ipu3-cio2.h"
++#include "ipu3/ipu3-cio2.h"
+
+ struct i2c_client;
+
+-#define CIO2_HID "INT343E"
+-#define CIO2_MAX_LANES 4
++#define IPU_HID "INT343E"
++#define IPU_MAX_LANES 4
+ #define MAX_NUM_LINK_FREQS 3
+
+ /* Values are educated guesses as we don't have a spec */
+-#define CIO2_SENSOR_ROTATION_NORMAL 0
+-#define CIO2_SENSOR_ROTATION_INVERTED 1
++#define IPU_SENSOR_ROTATION_NORMAL 0
++#define IPU_SENSOR_ROTATION_INVERTED 1
+
+-#define CIO2_SENSOR_CONFIG(_HID, _NR, ...) \
+- (const struct cio2_sensor_config) { \
++#define IPU_SENSOR_CONFIG(_HID, _NR, ...) \
++ (const struct ipu_sensor_config) { \
+ .hid = _HID, \
+ .nr_link_freqs = _NR, \
+ .link_freqs = { __VA_ARGS__ } \
+@@ -49,19 +49,19 @@ struct i2c_client;
+ .name = _TYPE, \
+ }
+
+-enum cio2_sensor_swnodes {
++enum ipu_sensor_swnodes {
+ SWNODE_SENSOR_HID,
+ SWNODE_SENSOR_PORT,
+ SWNODE_SENSOR_ENDPOINT,
+- SWNODE_CIO2_PORT,
+- SWNODE_CIO2_ENDPOINT,
++ SWNODE_IPU_PORT,
++ SWNODE_IPU_ENDPOINT,
+ /* Must be last because it is optional / maybe empty */
+ SWNODE_VCM,
+ SWNODE_COUNT
+ };
+
+ /* Data representation as it is in ACPI SSDB buffer */
+-struct cio2_sensor_ssdb {
++struct ipu_sensor_ssdb {
+ u8 version;
+ u8 sku;
+ u8 guid_csi2[16];
+@@ -90,7 +90,7 @@ struct cio2_sensor_ssdb {
+ u8 reserved2[13];
+ } __packed;
+
+-struct cio2_property_names {
++struct ipu_property_names {
+ char clock_frequency[16];
+ char rotation[9];
+ char orientation[12];
+@@ -100,19 +100,19 @@ struct cio2_property_names {
+ char link_frequencies[17];
+ };
+
+-struct cio2_node_names {
++struct ipu_node_names {
+ char port[7];
+ char endpoint[11];
+ char remote_port[7];
+ };
+
+-struct cio2_sensor_config {
++struct ipu_sensor_config {
+ const char *hid;
+ const u8 nr_link_freqs;
+ const u64 link_freqs[MAX_NUM_LINK_FREQS];
+ };
+
+-struct cio2_sensor {
++struct ipu_sensor {
+ /* append ssdb.link(u8) in "-%u" format as suffix of HID */
+ char name[ACPI_ID_LEN + 4];
+ struct acpi_device *adev;
+@@ -121,26 +121,32 @@ struct cio2_sensor {
+ /* SWNODE_COUNT + 1 for terminating NULL */
+ const struct software_node *group[SWNODE_COUNT + 1];
+ struct software_node swnodes[SWNODE_COUNT];
+- struct cio2_node_names node_names;
++ struct ipu_node_names node_names;
+
+- struct cio2_sensor_ssdb ssdb;
++ struct ipu_sensor_ssdb ssdb;
+ struct acpi_pld_info *pld;
+
+- struct cio2_property_names prop_names;
++ struct ipu_property_names prop_names;
+ struct property_entry ep_properties[5];
+ struct property_entry dev_properties[5];
+- struct property_entry cio2_properties[3];
++ struct property_entry ipu_properties[3];
+ struct software_node_ref_args local_ref[1];
+ struct software_node_ref_args remote_ref[1];
+ struct software_node_ref_args vcm_ref[1];
+ };
+
+-struct cio2_bridge {
+- char cio2_node_name[ACPI_ID_LEN];
+- struct software_node cio2_hid_node;
++struct ipu_bridge {
++ char ipu_node_name[ACPI_ID_LEN];
++ struct software_node ipu_hid_node;
+ u32 data_lanes[4];
+ unsigned int n_sensors;
+- struct cio2_sensor sensors[CIO2_NUM_PORTS];
++ struct ipu_sensor sensors[CIO2_NUM_PORTS];
+ };
+
++#if IS_ENABLED(CONFIG_IPU_BRIDGE)
++int ipu_bridge_init(struct pci_dev *ipu);
++#else
++static inline int ipu_bridge_init(struct pci_dev *ipu) { return 0; }
++#endif
++
+ #endif
+diff --git a/drivers/media/pci/intel/ipu3/Kconfig b/drivers/media/pci/intel/ipu3/Kconfig
+index 65b0c1598fbf1..9be06ee81ff05 100644
+--- a/drivers/media/pci/intel/ipu3/Kconfig
++++ b/drivers/media/pci/intel/ipu3/Kconfig
+@@ -17,22 +17,3 @@ config VIDEO_IPU3_CIO2
+ Say Y or M here if you have a Skylake/Kaby Lake SoC with MIPI CSI-2
+ connected camera.
+ The module will be called ipu3-cio2.
+-
+-config CIO2_BRIDGE
+- bool "IPU3 CIO2 Sensors Bridge"
+- depends on VIDEO_IPU3_CIO2 && ACPI
+- depends on I2C
+- help
+- This extension provides an API for the ipu3-cio2 driver to create
+- connections to cameras that are hidden in the SSDB buffer in ACPI.
+- It can be used to enable support for cameras in detachable / hybrid
+- devices that ship with Windows.
+-
+- Say Y here if your device is a detachable / hybrid laptop that comes
+- with Windows installed by the OEM, for example:
+-
+- - Microsoft Surface models (except Surface Pro 3)
+- - The Lenovo Miix line (for example the 510, 520, 710 and 720)
+- - Dell 7285
+-
+- If in doubt, say N here.
+diff --git a/drivers/media/pci/intel/ipu3/Makefile b/drivers/media/pci/intel/ipu3/Makefile
+index 933777e6ea8ab..429d516452e42 100644
+--- a/drivers/media/pci/intel/ipu3/Makefile
++++ b/drivers/media/pci/intel/ipu3/Makefile
+@@ -2,4 +2,3 @@
+ obj-$(CONFIG_VIDEO_IPU3_CIO2) += ipu3-cio2.o
+
+ ipu3-cio2-y += ipu3-cio2-main.o
+-ipu3-cio2-$(CONFIG_CIO2_BRIDGE) += cio2-bridge.o
+diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
+index 3c84cb1216320..03a7ab4d2e693 100644
+--- a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
++++ b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
+@@ -29,6 +29,7 @@
+ #include <media/v4l2-ioctl.h>
+ #include <media/videobuf2-dma-sg.h>
+
++#include "../ipu-bridge.h"
+ #include "ipu3-cio2.h"
+
+ struct ipu3_cio2_fmt {
+@@ -1727,7 +1728,7 @@ static int cio2_pci_probe(struct pci_dev *pci_dev,
+ return -EINVAL;
+ }
+
+- r = cio2_bridge_init(pci_dev);
++ r = ipu_bridge_init(pci_dev);
+ if (r)
+ return r;
+ }
+@@ -2060,3 +2061,4 @@ MODULE_AUTHOR("Yuning Pu <yuning.pu@intel.com>");
+ MODULE_AUTHOR("Yong Zhi <yong.zhi@intel.com>");
+ MODULE_LICENSE("GPL v2");
+ MODULE_DESCRIPTION("IPU3 CIO2 driver");
++MODULE_IMPORT_NS(INTEL_IPU_BRIDGE);
+diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2.h b/drivers/media/pci/intel/ipu3/ipu3-cio2.h
+index 3a1f394e05aa7..d731ce8adbe31 100644
+--- a/drivers/media/pci/intel/ipu3/ipu3-cio2.h
++++ b/drivers/media/pci/intel/ipu3/ipu3-cio2.h
+@@ -459,10 +459,4 @@ static inline struct cio2_queue *vb2q_to_cio2_queue(struct vb2_queue *vq)
+ return container_of(vq, struct cio2_queue, vbq);
+ }
+
+-#if IS_ENABLED(CONFIG_CIO2_BRIDGE)
+-int cio2_bridge_init(struct pci_dev *cio2);
+-#else
+-static inline int cio2_bridge_init(struct pci_dev *cio2) { return 0; }
+-#endif
+-
+ #endif
+--
+2.40.1
+
--- /dev/null
+From 74d1c6b7bf11ed07f768c77438b4751b1754d348 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Jun 2023 16:05:39 +0300
+Subject: media: mediatek: vcodec: fix potential double free
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit be40f524b6edac4fb9a98ef79620fd9b9497a998 ]
+
+The "lat_buf->private_data" needs to be set to NULL to prevent a
+double free. How this would happen is if vdec_msg_queue_init() failed
+twice in a row and on the second time it failed earlier than on the
+first time.
+
+The vdec_msg_queue_init() function has a loop which does:
+ for (i = 0; i < NUM_BUFFER_COUNT; i++) {
+
+Each iteration initializes one element in the msg_queue->lat_buf[] array
+and then the clean up function vdec_msg_queue_deinit() frees each
+element of the msg_queue->lat_buf[] array. This clean up code relies
+on the assumption that every element is either initialized or zeroed.
+Leaving a freed pointer which is non-zero breaks the assumption.
+
+Fixes: b199fe46f35c ("media: mtk-vcodec: Add msg queue feature for lat and core architecture")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c b/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c
+index 03f8d7cd8eddc..675f62814f94e 100644
+--- a/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c
++++ b/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c
+@@ -246,6 +246,7 @@ void vdec_msg_queue_deinit(struct vdec_msg_queue *msg_queue,
+ mtk_vcodec_mem_free(ctx, mem);
+
+ kfree(lat_buf->private_data);
++ lat_buf->private_data = NULL;
+ }
+ }
+
+--
+2.40.1
+
--- /dev/null
+From e10ed0daaff13e57d612167880e789c65771506b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Jun 2023 16:06:47 +0300
+Subject: media: mediatek: vcodec: fix resource leaks in vdec_msg_queue_init()
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit cf10b0bb503c974ba049d6f888b21178be20a962 ]
+
+If we encounter any error in the vdec_msg_queue_init() then we need
+to set "msg_queue->wdma_addr.size = 0;". Normally, this is done
+inside the vdec_msg_queue_deinit() function. However, if the
+first call to allocate &msg_queue->wdma_addr fails, then the
+vdec_msg_queue_deinit() function is a no-op. For that situation, just
+set the size to zero explicitly and return.
+
+There were two other error paths which did not clean up before returning.
+Change those error paths to goto mem_alloc_err.
+
+Fixes: b199fe46f35c ("media: mtk-vcodec: Add msg queue feature for lat and core architecture")
+Fixes: 2f5d0aef37c6 ("media: mediatek: vcodec: support stateless AV1 decoder")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c b/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c
+index 675f62814f94e..a81212c0ade9d 100644
+--- a/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c
++++ b/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c
+@@ -313,6 +313,7 @@ int vdec_msg_queue_init(struct vdec_msg_queue *msg_queue,
+ err = mtk_vcodec_mem_alloc(ctx, &msg_queue->wdma_addr);
+ if (err) {
+ mtk_v4l2_err("failed to allocate wdma_addr buf");
++ msg_queue->wdma_addr.size = 0;
+ return -ENOMEM;
+ }
+ msg_queue->wdma_rptr_addr = msg_queue->wdma_addr.dma_addr;
+--
+2.40.1
+
--- /dev/null
+From 94dd54ed936b9cdfce9a40ed190fdced1fee7537 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Jul 2023 17:14:41 +0800
+Subject: media: mediatek: vcodec: Return NULL if no vdec_fb is found
+
+From: Irui Wang <irui.wang@mediatek.com>
+
+[ Upstream commit dfa2d6e07432270330ae191f50a0e70636a4cd2b ]
+
+"fb_use_list" is used to store used or referenced frame buffers for
+vp9 stateful decoder. "NULL" should be returned when getting target
+frame buffer failed from "fb_use_list", not a random unexpected one.
+
+Fixes: f77e89854b3e ("[media] vcodec: mediatek: Add Mediatek VP9 Video Decoder Driver")
+Signed-off-by: Irui Wang <irui.wang@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_if.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_if.c b/drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_if.c
+index 70b8383f7c8ec..a27a109d8d144 100644
+--- a/drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_if.c
++++ b/drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_if.c
+@@ -226,10 +226,11 @@ static struct vdec_fb *vp9_rm_from_fb_use_list(struct vdec_vp9_inst
+ if (fb->base_y.va == addr) {
+ list_move_tail(&node->list,
+ &inst->available_fb_node_list);
+- break;
++ return fb;
+ }
+ }
+- return fb;
++
++ return NULL;
+ }
+
+ static void vp9_add_to_fb_free_list(struct vdec_vp9_inst *inst,
+--
+2.40.1
+
--- /dev/null
+From 5f21f63a91c923ce7c4991bb1ca805ca168afe16 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Jul 2023 17:24:14 +0800
+Subject: media: mtk-jpeg: Fix use after free bug due to uncanceled work
+
+From: Zheng Wang <zyytlz.wz@163.com>
+
+[ Upstream commit c677d7ae83141d390d1253abebafa49c962afb52 ]
+
+In mtk_jpeg_probe, &jpeg->job_timeout_work is bound with
+mtk_jpeg_job_timeout_work. Then mtk_jpeg_dec_device_run
+and mtk_jpeg_enc_device_run may be called to start the
+work.
+If we remove the module which will call mtk_jpeg_remove
+to make cleanup, there may be a unfinished work. The
+possible sequence is as follows, which will cause a
+typical UAF bug.
+
+Fix it by canceling the work before cleanup in the mtk_jpeg_remove
+
+CPU0 CPU1
+
+ |mtk_jpeg_job_timeout_work
+mtk_jpeg_remove |
+ v4l2_m2m_release |
+ kfree(m2m_dev); |
+ |
+ | v4l2_m2m_get_curr_priv
+ | m2m_dev->curr_ctx //use
+Fixes: b2f0d2724ba4 ("[media] vcodec: mediatek: Add Mediatek JPEG Decoder Driver")
+Signed-off-by: Zheng Wang <zyytlz.wz@163.com>
+Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
+Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
+index 60425c99a2b8b..7194f88edc0fb 100644
+--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
++++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
+@@ -1403,6 +1403,7 @@ static void mtk_jpeg_remove(struct platform_device *pdev)
+ {
+ struct mtk_jpeg_dev *jpeg = platform_get_drvdata(pdev);
+
++ cancel_delayed_work_sync(&jpeg->job_timeout_work);
+ pm_runtime_disable(&pdev->dev);
+ video_unregister_device(jpeg->vdev);
+ v4l2_m2m_release(jpeg->m2m_dev);
+--
+2.40.1
+
--- /dev/null
+From 5e3468f3d7b01be63e6f40751b86a388afe115ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Aug 2023 11:33:21 +0200
+Subject: media: ov2680: Add ov2680_fill_format() helper function
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 6d6849b2203f3244b575ba01d3e41ee19aa2cadf ]
+
+Add a ov2680_fill_format() helper function and use this everywhere were
+a v4l2_mbus_framefmt struct needs to be filled in so that the driver always
+fills it consistently.
+
+This is a preparation patch for fixing ov2680_set_fmt()
+which == V4L2_SUBDEV_FORMAT_TRY calls not properly filling in
+the passed in v4l2_mbus_framefmt struct.
+
+Note that for ov2680_init_cfg() this now simply always fills
+the try_fmt struct of the passed in sd_state. This is correct because
+ov2680_init_cfg() is never called with a NULL sd_state so the old
+sd_state check is not necessary.
+
+Fixes: 3ee47cad3e69 ("media: ov2680: Add Omnivision OV2680 sensor driver")
+Acked-by: Rui Miguel Silva <rmfrfs@gmail.com>
+Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/i2c/ov2680.c | 49 +++++++++++++++++++++-----------------
+ 1 file changed, 27 insertions(+), 22 deletions(-)
+
+diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c
+index 4f7ff23ef8973..6e0e8d21d189f 100644
+--- a/drivers/media/i2c/ov2680.c
++++ b/drivers/media/i2c/ov2680.c
+@@ -54,6 +54,9 @@
+ #define OV2680_WIDTH_MAX 1600
+ #define OV2680_HEIGHT_MAX 1200
+
++#define OV2680_DEFAULT_WIDTH 800
++#define OV2680_DEFAULT_HEIGHT 600
++
+ enum ov2680_mode_id {
+ OV2680_MODE_QUXGA_800_600,
+ OV2680_MODE_720P_1280_720,
+@@ -315,7 +318,8 @@ static void ov2680_power_down(struct ov2680_dev *sensor)
+ usleep_range(5000, 10000);
+ }
+
+-static void ov2680_set_bayer_order(struct ov2680_dev *sensor)
++static void ov2680_set_bayer_order(struct ov2680_dev *sensor,
++ struct v4l2_mbus_framefmt *fmt)
+ {
+ int hv_flip = 0;
+
+@@ -325,7 +329,19 @@ static void ov2680_set_bayer_order(struct ov2680_dev *sensor)
+ if (sensor->ctrls.hflip && sensor->ctrls.hflip->val)
+ hv_flip += 2;
+
+- sensor->fmt.code = ov2680_hv_flip_bayer_order[hv_flip];
++ fmt->code = ov2680_hv_flip_bayer_order[hv_flip];
++}
++
++static void ov2680_fill_format(struct ov2680_dev *sensor,
++ struct v4l2_mbus_framefmt *fmt,
++ unsigned int width, unsigned int height)
++{
++ memset(fmt, 0, sizeof(*fmt));
++ fmt->width = width;
++ fmt->height = height;
++ fmt->field = V4L2_FIELD_NONE;
++ fmt->colorspace = V4L2_COLORSPACE_SRGB;
++ ov2680_set_bayer_order(sensor, fmt);
+ }
+
+ static int ov2680_set_vflip(struct ov2680_dev *sensor, s32 val)
+@@ -340,7 +356,7 @@ static int ov2680_set_vflip(struct ov2680_dev *sensor, s32 val)
+ if (ret < 0)
+ return ret;
+
+- ov2680_set_bayer_order(sensor);
++ ov2680_set_bayer_order(sensor, &sensor->fmt);
+ return 0;
+ }
+
+@@ -356,7 +372,7 @@ static int ov2680_set_hflip(struct ov2680_dev *sensor, s32 val)
+ if (ret < 0)
+ return ret;
+
+- ov2680_set_bayer_order(sensor);
++ ov2680_set_bayer_order(sensor, &sensor->fmt);
+ return 0;
+ }
+
+@@ -614,10 +630,7 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
+ goto unlock;
+ }
+
+- fmt->width = mode->width;
+- fmt->height = mode->height;
+- fmt->code = sensor->fmt.code;
+- fmt->colorspace = sensor->fmt.colorspace;
++ ov2680_fill_format(sensor, fmt, mode->width, mode->height);
+
+ sensor->current_mode = mode;
+ sensor->fmt = format->format;
+@@ -632,16 +645,11 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
+ static int ov2680_init_cfg(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state)
+ {
+- struct v4l2_subdev_format fmt = {
+- .which = sd_state ? V4L2_SUBDEV_FORMAT_TRY
+- : V4L2_SUBDEV_FORMAT_ACTIVE,
+- .format = {
+- .width = 800,
+- .height = 600,
+- }
+- };
++ struct ov2680_dev *sensor = to_ov2680_dev(sd);
+
+- return ov2680_set_fmt(sd, sd_state, &fmt);
++ ov2680_fill_format(sensor, &sd_state->pads[0].try_fmt,
++ OV2680_DEFAULT_WIDTH, OV2680_DEFAULT_HEIGHT);
++ return 0;
+ }
+
+ static int ov2680_enum_frame_size(struct v4l2_subdev *sd,
+@@ -740,11 +748,8 @@ static int ov2680_mode_init(struct ov2680_dev *sensor)
+ const struct ov2680_mode_info *init_mode;
+
+ /* set initial mode */
+- sensor->fmt.code = MEDIA_BUS_FMT_SBGGR10_1X10;
+- sensor->fmt.width = 800;
+- sensor->fmt.height = 600;
+- sensor->fmt.field = V4L2_FIELD_NONE;
+- sensor->fmt.colorspace = V4L2_COLORSPACE_SRGB;
++ ov2680_fill_format(sensor, &sensor->fmt,
++ OV2680_DEFAULT_WIDTH, OV2680_DEFAULT_HEIGHT);
+
+ sensor->frame_interval.denominator = OV2680_FRAME_RATE;
+ sensor->frame_interval.numerator = 1;
+--
+2.40.1
+
--- /dev/null
+From 580b36b5b4944023af577904a3b0ad90526e374c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Aug 2023 11:33:20 +0200
+Subject: media: ov2680: Don't take the lock for try_fmt calls
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit e521b9cc1a49de677f4fc65909ce4877fbf7b113 ]
+
+On ov2680_set_fmt() calls with format->which == V4L2_SUBDEV_FORMAT_TRY,
+ov2680_set_fmt() does not talk to the sensor.
+
+So in this case there is no need to lock the sensor->lock mutex or
+to check that the sensor is streaming.
+
+Fixes: 3ee47cad3e69 ("media: ov2680: Add Omnivision OV2680 sensor driver")
+Acked-by: Rui Miguel Silva <rmfrfs@gmail.com>
+Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/i2c/ov2680.c | 20 +++++++++-----------
+ 1 file changed, 9 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c
+index de11a5fb03659..4f7ff23ef8973 100644
+--- a/drivers/media/i2c/ov2680.c
++++ b/drivers/media/i2c/ov2680.c
+@@ -595,24 +595,22 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
+ if (format->pad != 0)
+ return -EINVAL;
+
+- mutex_lock(&sensor->lock);
+-
+- if (sensor->is_streaming) {
+- ret = -EBUSY;
+- goto unlock;
+- }
+-
+ mode = v4l2_find_nearest_size(ov2680_mode_data,
+ ARRAY_SIZE(ov2680_mode_data), width,
+ height, fmt->width, fmt->height);
+- if (!mode) {
+- ret = -EINVAL;
+- goto unlock;
+- }
++ if (!mode)
++ return -EINVAL;
+
+ if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
+ try_fmt = v4l2_subdev_get_try_format(sd, sd_state, 0);
+ format->format = *try_fmt;
++ return 0;
++ }
++
++ mutex_lock(&sensor->lock);
++
++ if (sensor->is_streaming) {
++ ret = -EBUSY;
+ goto unlock;
+ }
+
+--
+2.40.1
+
--- /dev/null
+From 7661399ab549e1b7341e59eb0b9ddb6a84823fbd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Aug 2023 11:33:17 +0200
+Subject: media: ov2680: Fix ov2680_bayer_order()
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 50a7bad4e0a37d7018ab6fe843dd84bc6b2ecf72 ]
+
+The index into ov2680_hv_flip_bayer_order[] should be 0-3, but
+ov2680_bayer_order() was using 0 + BIT(2) + (BIT(2) << 1) as
+max index, while the intention was to use: 0 + 1 + 2 as max index.
+
+Fix the index calculation in ov2680_bayer_order(), while at it
+also just use the ctrl values rather then reading them back using
+a slow i2c-read transaction.
+
+This also allows making the function void, since there now are
+no more i2c-reads to error check.
+
+Note the check for the ctrls being NULL is there to allow
+adding an ov2680_fill_format() helper later, which will call
+ov2680_set_bayer_order() during probe() before the ctrls are created.
+
+[Sakari Ailus: Change all users of ov2680_set_bayer_order() here]
+
+Fixes: 3ee47cad3e69 ("media: ov2680: Add Omnivision OV2680 sensor driver")
+Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
+Acked-by: Rui Miguel Silva <rmfrfs@gmail.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/i2c/ov2680.c | 33 ++++++++++++++-------------------
+ 1 file changed, 14 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c
+index 42efd60c6a96b..7d072448c8530 100644
+--- a/drivers/media/i2c/ov2680.c
++++ b/drivers/media/i2c/ov2680.c
+@@ -315,26 +315,17 @@ static void ov2680_power_down(struct ov2680_dev *sensor)
+ usleep_range(5000, 10000);
+ }
+
+-static int ov2680_bayer_order(struct ov2680_dev *sensor)
++static void ov2680_set_bayer_order(struct ov2680_dev *sensor)
+ {
+- u32 format1;
+- u32 format2;
+- u32 hv_flip;
+- int ret;
+-
+- ret = ov2680_read_reg(sensor, OV2680_REG_FORMAT1, &format1);
+- if (ret < 0)
+- return ret;
++ int hv_flip = 0;
+
+- ret = ov2680_read_reg(sensor, OV2680_REG_FORMAT2, &format2);
+- if (ret < 0)
+- return ret;
++ if (sensor->ctrls.vflip && sensor->ctrls.vflip->val)
++ hv_flip += 1;
+
+- hv_flip = (format2 & BIT(2) << 1) | (format1 & BIT(2));
++ if (sensor->ctrls.hflip && sensor->ctrls.hflip->val)
++ hv_flip += 2;
+
+ sensor->fmt.code = ov2680_hv_flip_bayer_order[hv_flip];
+-
+- return 0;
+ }
+
+ static int ov2680_vflip_enable(struct ov2680_dev *sensor)
+@@ -345,7 +336,8 @@ static int ov2680_vflip_enable(struct ov2680_dev *sensor)
+ if (ret < 0)
+ return ret;
+
+- return ov2680_bayer_order(sensor);
++ ov2680_set_bayer_order(sensor);
++ return 0;
+ }
+
+ static int ov2680_vflip_disable(struct ov2680_dev *sensor)
+@@ -356,7 +348,8 @@ static int ov2680_vflip_disable(struct ov2680_dev *sensor)
+ if (ret < 0)
+ return ret;
+
+- return ov2680_bayer_order(sensor);
++ ov2680_set_bayer_order(sensor);
++ return 0;
+ }
+
+ static int ov2680_hflip_enable(struct ov2680_dev *sensor)
+@@ -367,7 +360,8 @@ static int ov2680_hflip_enable(struct ov2680_dev *sensor)
+ if (ret < 0)
+ return ret;
+
+- return ov2680_bayer_order(sensor);
++ ov2680_set_bayer_order(sensor);
++ return 0;
+ }
+
+ static int ov2680_hflip_disable(struct ov2680_dev *sensor)
+@@ -378,7 +372,8 @@ static int ov2680_hflip_disable(struct ov2680_dev *sensor)
+ if (ret < 0)
+ return ret;
+
+- return ov2680_bayer_order(sensor);
++ ov2680_set_bayer_order(sensor);
++ return 0;
+ }
+
+ static int ov2680_test_pattern_set(struct ov2680_dev *sensor, int value)
+--
+2.40.1
+
--- /dev/null
+From 3a8603ff685cf2e20609120d07a59b4e0f6e877c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Aug 2023 11:33:22 +0200
+Subject: media: ov2680: Fix ov2680_set_fmt() which == V4L2_SUBDEV_FORMAT_TRY
+ not working
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit c0e97a4b4f20639f74cd5809b42ba6cbf9736a7d ]
+
+ov2680_set_fmt() which == V4L2_SUBDEV_FORMAT_TRY was getting
+the try_fmt v4l2_mbus_framefmt struct from the passed in sd_state
+and then storing the contents of that into the return by reference
+format->format struct.
+
+While the right thing to do would be filling format->format based on
+the just looked up mode and then store the results of that in
+sd_state->pads[0].try_fmt .
+
+Before the previous change introducing ov2680_fill_format() this
+resulted in ov2680_set_fmt() which == V4L2_SUBDEV_FORMAT_TRY always
+returning the zero-ed out sd_state->pads[0].try_fmt in format->format
+breaking callers using this.
+
+After the introduction of ov2680_fill_format() which at least
+initializes sd_state->pads[0].try_fmt properly, format->format
+is now always being filled with the default 800x600 mode set by
+ov2680_init_cfg() independent of the actual requested mode.
+
+Move the filling of format->format with ov2680_fill_format() to
+before the if (which == V4L2_SUBDEV_FORMAT_TRY) and then store
+the filled in format->format in sd_state->pads[0].try_fmt to
+fix this.
+
+Note this removes the fmt local variable because IMHO having a local
+variable which points to a sub-struct of one of the function arguments
+just leads to confusion when reading the code.
+
+Fixes: 3ee47cad3e69 ("media: ov2680: Add Omnivision OV2680 sensor driver")
+Acked-by: Rui Miguel Silva <rmfrfs@gmail.com>
+Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/i2c/ov2680.c | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c
+index 6e0e8d21d189f..a24344ef9852c 100644
+--- a/drivers/media/i2c/ov2680.c
++++ b/drivers/media/i2c/ov2680.c
+@@ -603,7 +603,6 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_format *format)
+ {
+ struct ov2680_dev *sensor = to_ov2680_dev(sd);
+- struct v4l2_mbus_framefmt *fmt = &format->format;
+ struct v4l2_mbus_framefmt *try_fmt;
+ const struct ov2680_mode_info *mode;
+ int ret = 0;
+@@ -612,14 +611,18 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
+ return -EINVAL;
+
+ mode = v4l2_find_nearest_size(ov2680_mode_data,
+- ARRAY_SIZE(ov2680_mode_data), width,
+- height, fmt->width, fmt->height);
++ ARRAY_SIZE(ov2680_mode_data),
++ width, height,
++ format->format.width,
++ format->format.height);
+ if (!mode)
+ return -EINVAL;
+
++ ov2680_fill_format(sensor, &format->format, mode->width, mode->height);
++
+ if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
+ try_fmt = v4l2_subdev_get_try_format(sd, sd_state, 0);
+- format->format = *try_fmt;
++ *try_fmt = format->format;
+ return 0;
+ }
+
+@@ -630,8 +633,6 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
+ goto unlock;
+ }
+
+- ov2680_fill_format(sensor, fmt, mode->width, mode->height);
+-
+ sensor->current_mode = mode;
+ sensor->fmt = format->format;
+ sensor->mode_pending_changes = true;
+--
+2.40.1
+
--- /dev/null
+From 1b82b45ef00e4c0587430491e82ae8578cef3009 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Aug 2023 11:33:23 +0200
+Subject: media: ov2680: Fix regulators being left enabled on ov2680_power_on()
+ errors
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 84b4bd7e0d98166aa32fd470e672721190492eae ]
+
+When the ov2680_power_on() "sensor soft reset failed" path is hit during
+probe() the WARN() about putting an enabled regulator at
+drivers/regulator/core.c:2398 triggers 3 times (once for each regulator),
+filling dmesg with backtraces.
+
+Fix this by properly disabling the regulators on ov2680_power_on() errors.
+
+Fixes: 3ee47cad3e69 ("media: ov2680: Add Omnivision OV2680 sensor driver")
+Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
+Acked-by: Rui Miguel Silva <rmfrfs@gmail.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/i2c/ov2680.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c
+index a24344ef9852c..8943e4e78a0df 100644
+--- a/drivers/media/i2c/ov2680.c
++++ b/drivers/media/i2c/ov2680.c
+@@ -475,7 +475,7 @@ static int ov2680_power_on(struct ov2680_dev *sensor)
+ ret = ov2680_write_reg(sensor, OV2680_REG_SOFT_RESET, 0x01);
+ if (ret != 0) {
+ dev_err(dev, "sensor soft reset failed\n");
+- return ret;
++ goto err_disable_regulators;
+ }
+ usleep_range(1000, 2000);
+ } else {
+@@ -485,7 +485,7 @@ static int ov2680_power_on(struct ov2680_dev *sensor)
+
+ ret = clk_prepare_enable(sensor->xvclk);
+ if (ret < 0)
+- return ret;
++ goto err_disable_regulators;
+
+ sensor->is_enabled = true;
+
+@@ -495,6 +495,10 @@ static int ov2680_power_on(struct ov2680_dev *sensor)
+ ov2680_stream_disable(sensor);
+
+ return 0;
++
++err_disable_regulators:
++ regulator_bulk_disable(OV2680_NUM_SUPPLIES, sensor->supplies);
++ return ret;
+ }
+
+ static int ov2680_s_power(struct v4l2_subdev *sd, int on)
+--
+2.40.1
+
--- /dev/null
+From 0e59bb2fa14721614d59f7dda33c506b205c0ec5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Aug 2023 11:33:18 +0200
+Subject: media: ov2680: Fix vflip / hflip set functions
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit d5d08ad330c9ccebc5e066fda815423a290f48b0 ]
+
+ov2680_vflip_disable() / ov2680_hflip_disable() pass BIT(0) instead of
+0 as value to ov2680_mod_reg().
+
+While fixing this also:
+
+1. Stop having separate enable/disable functions for hflip / vflip
+2. Move the is_streaming check, which is unique to hflip / vflip
+ into the ov2680_set_?flip() functions.
+
+for a nice code cleanup.
+
+Fixes: 3ee47cad3e69 ("media: ov2680: Add Omnivision OV2680 sensor driver")
+Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
+Acked-by: Rui Miguel Silva <rmfrfs@gmail.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/i2c/ov2680.c | 50 +++++++++-----------------------------
+ 1 file changed, 12 insertions(+), 38 deletions(-)
+
+diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c
+index 7d072448c8530..c999a898dfe77 100644
+--- a/drivers/media/i2c/ov2680.c
++++ b/drivers/media/i2c/ov2680.c
+@@ -328,23 +328,15 @@ static void ov2680_set_bayer_order(struct ov2680_dev *sensor)
+ sensor->fmt.code = ov2680_hv_flip_bayer_order[hv_flip];
+ }
+
+-static int ov2680_vflip_enable(struct ov2680_dev *sensor)
++static int ov2680_set_vflip(struct ov2680_dev *sensor, s32 val)
+ {
+ int ret;
+
+- ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT1, BIT(2), BIT(2));
+- if (ret < 0)
+- return ret;
+-
+- ov2680_set_bayer_order(sensor);
+- return 0;
+-}
+-
+-static int ov2680_vflip_disable(struct ov2680_dev *sensor)
+-{
+- int ret;
++ if (sensor->is_streaming)
++ return -EBUSY;
+
+- ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT1, BIT(2), BIT(0));
++ ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT1,
++ BIT(2), val ? BIT(2) : 0);
+ if (ret < 0)
+ return ret;
+
+@@ -352,23 +344,15 @@ static int ov2680_vflip_disable(struct ov2680_dev *sensor)
+ return 0;
+ }
+
+-static int ov2680_hflip_enable(struct ov2680_dev *sensor)
++static int ov2680_set_hflip(struct ov2680_dev *sensor, s32 val)
+ {
+ int ret;
+
+- ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT2, BIT(2), BIT(2));
+- if (ret < 0)
+- return ret;
+-
+- ov2680_set_bayer_order(sensor);
+- return 0;
+-}
+-
+-static int ov2680_hflip_disable(struct ov2680_dev *sensor)
+-{
+- int ret;
++ if (sensor->is_streaming)
++ return -EBUSY;
+
+- ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT2, BIT(2), BIT(0));
++ ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT2,
++ BIT(2), val ? BIT(2) : 0);
+ if (ret < 0)
+ return ret;
+
+@@ -722,19 +706,9 @@ static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl)
+ case V4L2_CID_EXPOSURE:
+ return ov2680_exposure_set(sensor, ctrl->val);
+ case V4L2_CID_VFLIP:
+- if (sensor->is_streaming)
+- return -EBUSY;
+- if (ctrl->val)
+- return ov2680_vflip_enable(sensor);
+- else
+- return ov2680_vflip_disable(sensor);
++ return ov2680_set_vflip(sensor, ctrl->val);
+ case V4L2_CID_HFLIP:
+- if (sensor->is_streaming)
+- return -EBUSY;
+- if (ctrl->val)
+- return ov2680_hflip_enable(sensor);
+- else
+- return ov2680_hflip_disable(sensor);
++ return ov2680_set_hflip(sensor, ctrl->val);
+ case V4L2_CID_TEST_PATTERN:
+ return ov2680_test_pattern_set(sensor, ctrl->val);
+ default:
+--
+2.40.1
+
--- /dev/null
+From cdaf4b82490f3ca96eb6c8e8244b14bb714f755d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Aug 2023 11:33:16 +0200
+Subject: media: ov2680: Remove auto-gain and auto-exposure controls
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 7b5a42e6ae71927359ea67a2c22570ba97fa4059 ]
+
+Quoting the OV2680 datasheet:
+
+"3.2 exposure and gain control
+
+In the OV2680, the exposure time and gain are set manually from an external
+controller. The OV2680 supports manual gain and exposure control only for
+normal applications, no auto mode."
+
+And indeed testing with the atomisp_ov2680 fork of ov2680.c has shown that
+auto-exposure and auto-gain do not work.
+
+Note that the code setting the auto-exposure flag was broken, callers
+of ov2680_exposure_set() were directly passing !!ctrls->auto_exp->val as
+"bool auto_exp" value, but ctrls->auto_exp is a menu control with:
+
+enum v4l2_exposure_auto_type {
+ V4L2_EXPOSURE_AUTO = 0,
+ V4L2_EXPOSURE_MANUAL = 1,
+ ...
+
+So instead of passing !!ctrls->auto_exp->val they should have been passing
+ctrls->auto_exp->val == V4L2_EXPOSURE_AUTO, iow the passed value was
+inverted of what it should have been.
+
+Also remove ov2680_g_volatile_ctrl() since without auto support the gain
+and exposure controls are not volatile.
+
+This also fixes the control values not being properly applied in
+ov2680_mode_set(). The 800x600 mode register-list also sets gain,
+exposure and vflip overriding the last set ctrl values.
+
+ov2680_mode_set() does call ov2680_gain_set() and ov2680_exposure_set()
+but did this before writing the mode register-list, so these values
+would still be overridden by the mode register-list.
+
+Add a v4l2_ctrl_handler_setup() call after writing the mode register-list
+to restore all ctrl values. Also remove the ctrls->gain->is_new check from
+ov2680_gain_set() so that the gain always gets restored properly.
+
+Last since ov2680_mode_set() now calls v4l2_ctrl_handler_setup(), remove
+the v4l2_ctrl_handler_setup() call after ov2680_mode_restore() since
+ov2680_mode_restore() calls ov2680_mode_set().
+
+Fixes: 3ee47cad3e69 ("media: ov2680: Add Omnivision OV2680 sensor driver")
+Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
+Acked-by: Rui Miguel Silva <rmfrfs@gmail.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/i2c/ov2680.c | 161 ++++---------------------------------
+ 1 file changed, 17 insertions(+), 144 deletions(-)
+
+diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c
+index 54153bf66bddc..42efd60c6a96b 100644
+--- a/drivers/media/i2c/ov2680.c
++++ b/drivers/media/i2c/ov2680.c
+@@ -85,15 +85,8 @@ struct ov2680_mode_info {
+
+ struct ov2680_ctrls {
+ struct v4l2_ctrl_handler handler;
+- struct {
+- struct v4l2_ctrl *auto_exp;
+- struct v4l2_ctrl *exposure;
+- };
+- struct {
+- struct v4l2_ctrl *auto_gain;
+- struct v4l2_ctrl *gain;
+- };
+-
++ struct v4l2_ctrl *exposure;
++ struct v4l2_ctrl *gain;
+ struct v4l2_ctrl *hflip;
+ struct v4l2_ctrl *vflip;
+ struct v4l2_ctrl *test_pattern;
+@@ -143,6 +136,7 @@ static const struct reg_value ov2680_setting_30fps_QUXGA_800_600[] = {
+ {0x380e, 0x02}, {0x380f, 0x84}, {0x3811, 0x04}, {0x3813, 0x04},
+ {0x3814, 0x31}, {0x3815, 0x31}, {0x3820, 0xc0}, {0x4008, 0x00},
+ {0x4009, 0x03}, {0x4837, 0x1e}, {0x3501, 0x4e}, {0x3502, 0xe0},
++ {0x3503, 0x03},
+ };
+
+ static const struct reg_value ov2680_setting_30fps_720P_1280_720[] = {
+@@ -405,69 +399,15 @@ static int ov2680_test_pattern_set(struct ov2680_dev *sensor, int value)
+ return 0;
+ }
+
+-static int ov2680_gain_set(struct ov2680_dev *sensor, bool auto_gain)
+-{
+- struct ov2680_ctrls *ctrls = &sensor->ctrls;
+- u32 gain;
+- int ret;
+-
+- ret = ov2680_mod_reg(sensor, OV2680_REG_R_MANUAL, BIT(1),
+- auto_gain ? 0 : BIT(1));
+- if (ret < 0)
+- return ret;
+-
+- if (auto_gain || !ctrls->gain->is_new)
+- return 0;
+-
+- gain = ctrls->gain->val;
+-
+- ret = ov2680_write_reg16(sensor, OV2680_REG_GAIN_PK, gain);
+-
+- return 0;
+-}
+-
+-static int ov2680_gain_get(struct ov2680_dev *sensor)
+-{
+- u32 gain;
+- int ret;
+-
+- ret = ov2680_read_reg16(sensor, OV2680_REG_GAIN_PK, &gain);
+- if (ret)
+- return ret;
+-
+- return gain;
+-}
+-
+-static int ov2680_exposure_set(struct ov2680_dev *sensor, bool auto_exp)
++static int ov2680_gain_set(struct ov2680_dev *sensor, u32 gain)
+ {
+- struct ov2680_ctrls *ctrls = &sensor->ctrls;
+- u32 exp;
+- int ret;
+-
+- ret = ov2680_mod_reg(sensor, OV2680_REG_R_MANUAL, BIT(0),
+- auto_exp ? 0 : BIT(0));
+- if (ret < 0)
+- return ret;
+-
+- if (auto_exp || !ctrls->exposure->is_new)
+- return 0;
+-
+- exp = (u32)ctrls->exposure->val;
+- exp <<= 4;
+-
+- return ov2680_write_reg24(sensor, OV2680_REG_EXPOSURE_PK_HIGH, exp);
++ return ov2680_write_reg16(sensor, OV2680_REG_GAIN_PK, gain);
+ }
+
+-static int ov2680_exposure_get(struct ov2680_dev *sensor)
++static int ov2680_exposure_set(struct ov2680_dev *sensor, u32 exp)
+ {
+- int ret;
+- u32 exp;
+-
+- ret = ov2680_read_reg24(sensor, OV2680_REG_EXPOSURE_PK_HIGH, &exp);
+- if (ret)
+- return ret;
+-
+- return exp >> 4;
++ return ov2680_write_reg24(sensor, OV2680_REG_EXPOSURE_PK_HIGH,
++ exp << 4);
+ }
+
+ static int ov2680_stream_enable(struct ov2680_dev *sensor)
+@@ -482,33 +422,17 @@ static int ov2680_stream_disable(struct ov2680_dev *sensor)
+
+ static int ov2680_mode_set(struct ov2680_dev *sensor)
+ {
+- struct ov2680_ctrls *ctrls = &sensor->ctrls;
+ int ret;
+
+- ret = ov2680_gain_set(sensor, false);
+- if (ret < 0)
+- return ret;
+-
+- ret = ov2680_exposure_set(sensor, false);
++ ret = ov2680_load_regs(sensor, sensor->current_mode);
+ if (ret < 0)
+ return ret;
+
+- ret = ov2680_load_regs(sensor, sensor->current_mode);
++ /* Restore value of all ctrls */
++ ret = __v4l2_ctrl_handler_setup(&sensor->ctrls.handler);
+ if (ret < 0)
+ return ret;
+
+- if (ctrls->auto_gain->val) {
+- ret = ov2680_gain_set(sensor, true);
+- if (ret < 0)
+- return ret;
+- }
+-
+- if (ctrls->auto_exp->val == V4L2_EXPOSURE_AUTO) {
+- ret = ov2680_exposure_set(sensor, true);
+- if (ret < 0)
+- return ret;
+- }
+-
+ sensor->mode_pending_changes = false;
+
+ return 0;
+@@ -590,15 +514,10 @@ static int ov2680_s_power(struct v4l2_subdev *sd, int on)
+ else
+ ret = ov2680_power_off(sensor);
+
+- mutex_unlock(&sensor->lock);
+-
+- if (on && ret == 0) {
+- ret = v4l2_ctrl_handler_setup(&sensor->ctrls.handler);
+- if (ret < 0)
+- return ret;
+-
++ if (on && ret == 0)
+ ret = ov2680_mode_restore(sensor);
+- }
++
++ mutex_unlock(&sensor->lock);
+
+ return ret;
+ }
+@@ -794,52 +713,19 @@ static int ov2680_enum_frame_interval(struct v4l2_subdev *sd,
+ return 0;
+ }
+
+-static int ov2680_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
+-{
+- struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
+- struct ov2680_dev *sensor = to_ov2680_dev(sd);
+- struct ov2680_ctrls *ctrls = &sensor->ctrls;
+- int val;
+-
+- if (!sensor->is_enabled)
+- return 0;
+-
+- switch (ctrl->id) {
+- case V4L2_CID_GAIN:
+- val = ov2680_gain_get(sensor);
+- if (val < 0)
+- return val;
+- ctrls->gain->val = val;
+- break;
+- case V4L2_CID_EXPOSURE:
+- val = ov2680_exposure_get(sensor);
+- if (val < 0)
+- return val;
+- ctrls->exposure->val = val;
+- break;
+- }
+-
+- return 0;
+-}
+-
+ static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl)
+ {
+ struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
+ struct ov2680_dev *sensor = to_ov2680_dev(sd);
+- struct ov2680_ctrls *ctrls = &sensor->ctrls;
+
+ if (!sensor->is_enabled)
+ return 0;
+
+ switch (ctrl->id) {
+- case V4L2_CID_AUTOGAIN:
+- return ov2680_gain_set(sensor, !!ctrl->val);
+ case V4L2_CID_GAIN:
+- return ov2680_gain_set(sensor, !!ctrls->auto_gain->val);
+- case V4L2_CID_EXPOSURE_AUTO:
+- return ov2680_exposure_set(sensor, !!ctrl->val);
++ return ov2680_gain_set(sensor, ctrl->val);
+ case V4L2_CID_EXPOSURE:
+- return ov2680_exposure_set(sensor, !!ctrls->auto_exp->val);
++ return ov2680_exposure_set(sensor, ctrl->val);
+ case V4L2_CID_VFLIP:
+ if (sensor->is_streaming)
+ return -EBUSY;
+@@ -864,7 +750,6 @@ static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl)
+ }
+
+ static const struct v4l2_ctrl_ops ov2680_ctrl_ops = {
+- .g_volatile_ctrl = ov2680_g_volatile_ctrl,
+ .s_ctrl = ov2680_s_ctrl,
+ };
+
+@@ -936,7 +821,7 @@ static int ov2680_v4l2_register(struct ov2680_dev *sensor)
+ if (ret < 0)
+ return ret;
+
+- v4l2_ctrl_handler_init(hdl, 7);
++ v4l2_ctrl_handler_init(hdl, 5);
+
+ hdl->lock = &sensor->lock;
+
+@@ -948,16 +833,9 @@ static int ov2680_v4l2_register(struct ov2680_dev *sensor)
+ ARRAY_SIZE(test_pattern_menu) - 1,
+ 0, 0, test_pattern_menu);
+
+- ctrls->auto_exp = v4l2_ctrl_new_std_menu(hdl, ops,
+- V4L2_CID_EXPOSURE_AUTO,
+- V4L2_EXPOSURE_MANUAL, 0,
+- V4L2_EXPOSURE_AUTO);
+-
+ ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE,
+ 0, 32767, 1, 0);
+
+- ctrls->auto_gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTOGAIN,
+- 0, 1, 1, 1);
+ ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN, 0, 2047, 1, 0);
+
+ if (hdl->error) {
+@@ -965,14 +843,9 @@ static int ov2680_v4l2_register(struct ov2680_dev *sensor)
+ goto cleanup_entity;
+ }
+
+- ctrls->gain->flags |= V4L2_CTRL_FLAG_VOLATILE;
+- ctrls->exposure->flags |= V4L2_CTRL_FLAG_VOLATILE;
+ ctrls->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
+ ctrls->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
+
+- v4l2_ctrl_auto_cluster(2, &ctrls->auto_gain, 0, true);
+- v4l2_ctrl_auto_cluster(2, &ctrls->auto_exp, 1, true);
+-
+ sensor->sd.ctrl_handler = hdl;
+
+ ret = v4l2_async_register_subdev(&sensor->sd);
+--
+2.40.1
+
--- /dev/null
+From e3773f8e3787aedc067723df5ab891c3fd0984d5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Aug 2023 11:33:19 +0200
+Subject: media: ov2680: Remove VIDEO_V4L2_SUBDEV_API ifdef-s
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 49c282d5a8c5f4d1d9088622bec792294c716010 ]
+
+VIDEO_V4L2_SUBDEV_API is now automatically selected in Kconfig
+for all sensor drivers. Remove the ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+checks.
+
+This is a preparation patch for fixing ov2680_set_fmt()
+which == V4L2_SUBDEV_FORMAT_TRY calls not properly filling in
+the passed in v4l2_mbus_framefmt struct.
+
+Fixes: 3ee47cad3e69 ("media: ov2680: Add Omnivision OV2680 sensor driver")
+Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
+Acked-by: Rui Miguel Silva <rmfrfs@gmail.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/i2c/ov2680.c | 16 ++--------------
+ 1 file changed, 2 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c
+index c999a898dfe77..de11a5fb03659 100644
+--- a/drivers/media/i2c/ov2680.c
++++ b/drivers/media/i2c/ov2680.c
+@@ -562,7 +562,6 @@ static int ov2680_get_fmt(struct v4l2_subdev *sd,
+ {
+ struct ov2680_dev *sensor = to_ov2680_dev(sd);
+ struct v4l2_mbus_framefmt *fmt = NULL;
+- int ret = 0;
+
+ if (format->pad != 0)
+ return -EINVAL;
+@@ -570,22 +569,17 @@ static int ov2680_get_fmt(struct v4l2_subdev *sd,
+ mutex_lock(&sensor->lock);
+
+ if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
+-#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+ fmt = v4l2_subdev_get_try_format(&sensor->sd, sd_state,
+ format->pad);
+-#else
+- ret = -EINVAL;
+-#endif
+ } else {
+ fmt = &sensor->fmt;
+ }
+
+- if (fmt)
+- format->format = *fmt;
++ format->format = *fmt;
+
+ mutex_unlock(&sensor->lock);
+
+- return ret;
++ return 0;
+ }
+
+ static int ov2680_set_fmt(struct v4l2_subdev *sd,
+@@ -594,9 +588,7 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
+ {
+ struct ov2680_dev *sensor = to_ov2680_dev(sd);
+ struct v4l2_mbus_framefmt *fmt = &format->format;
+-#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+ struct v4l2_mbus_framefmt *try_fmt;
+-#endif
+ const struct ov2680_mode_info *mode;
+ int ret = 0;
+
+@@ -619,10 +611,8 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
+ }
+
+ if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
+-#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+ try_fmt = v4l2_subdev_get_try_format(sd, sd_state, 0);
+ format->format = *try_fmt;
+-#endif
+ goto unlock;
+ }
+
+@@ -780,9 +770,7 @@ static int ov2680_v4l2_register(struct ov2680_dev *sensor)
+ v4l2_i2c_subdev_init(&sensor->sd, sensor->i2c_client,
+ &ov2680_subdev_ops);
+
+-#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+ sensor->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
+-#endif
+ sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
+ sensor->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
+
+--
+2.40.1
+
--- /dev/null
+From 2fb8cf256ade42808d89fce8cdac0a45de5f6af9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Aug 2023 16:47:25 +0200
+Subject: media: ov5640: Enable MIPI interface in ov5640_set_power_mipi()
+
+From: Marek Vasut <marex@denx.de>
+
+[ Upstream commit 98cb72d3b9c5e03b10fa993752ecfcbd9c572d8c ]
+
+Set OV5640_REG_IO_MIPI_CTRL00 bit 2 to 1 instead of 0, since 1 means
+MIPI CSI2 interface, while 0 means CPI parallel interface.
+
+In the ov5640_set_power_mipi() the interface should obviously be set
+to MIPI CSI2 since this functions is used to power up the sensor when
+operated in MIPI CSI2 mode. The sensor should not be in CPI mode in
+that case.
+
+This fixes a corner case where capturing the first frame on i.MX8MN
+with CSI/ISI resulted in corrupted frame.
+
+Fixes: aa4bb8b8838f ("media: ov5640: Re-work MIPI startup sequence")
+Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Tested-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> # [Test on imx6q]
+Signed-off-by: Marek Vasut <marex@denx.de>
+Tested-by: Jai Luthra <j-luthra@ti.com> # [Test on bplay, sk-am62]
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/i2c/ov5640.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c
+index 1bc4d72a906e5..74cfe2d373577 100644
+--- a/drivers/media/i2c/ov5640.c
++++ b/drivers/media/i2c/ov5640.c
+@@ -2542,9 +2542,9 @@ static int ov5640_set_power_mipi(struct ov5640_dev *sensor, bool on)
+ * "ov5640_set_stream_mipi()")
+ * [4] = 0 : Power up MIPI HS Tx
+ * [3] = 0 : Power up MIPI LS Rx
+- * [2] = 0 : MIPI interface disabled
++ * [2] = 1 : MIPI interface enabled
+ */
+- ret = ov5640_write_reg(sensor, OV5640_REG_IO_MIPI_CTRL00, 0x40);
++ ret = ov5640_write_reg(sensor, OV5640_REG_IO_MIPI_CTRL00, 0x44);
+ if (ret)
+ return ret;
+
+--
+2.40.1
+
--- /dev/null
+From 4b8df56e8be4be8085299b06e68f2e8bac01a871 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Jul 2023 00:21:16 +0200
+Subject: media: ov5640: Fix initial RESETB state and annotate timings
+
+From: Marek Vasut <marex@denx.de>
+
+[ Upstream commit a210df337c5f5c2cd82f36c9dbb154ec63365c80 ]
+
+The initial state of RESETB input signal of OV5640 should be
+asserted, i.e. the sensor should be in reset. This is not the
+case, make it so.
+
+Since the subsequent assertion of RESETB signal is no longer
+necessary and the timing of the power sequencing could be
+slightly adjusted, add annotations to the delays which match
+OV5640 datasheet rev. 2.03, both:
+ figure 2-3 power up timing with internal DVDD
+ figure 2-4 power up timing with external DVDD source
+
+The 5..10ms delay between PWDN assertion and RESETB assertion
+is not even documented in the power sequencing diagram, and
+with this reset fix, it is no longer even necessary.
+
+Fixes: 19a81c1426c1 ("[media] add Omnivision OV5640 sensor driver")
+Reported-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Signed-off-by: Marek Vasut <marex@denx.de>
+Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Tested-by: Jai Luthra <j-luthra@ti.com>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/i2c/ov5640.c | 11 ++++-------
+ 1 file changed, 4 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c
+index 74cfe2d373577..bf50705ad6d36 100644
+--- a/drivers/media/i2c/ov5640.c
++++ b/drivers/media/i2c/ov5640.c
+@@ -2452,16 +2452,13 @@ static void ov5640_power(struct ov5640_dev *sensor, bool enable)
+ static void ov5640_powerup_sequence(struct ov5640_dev *sensor)
+ {
+ if (sensor->pwdn_gpio) {
+- gpiod_set_value_cansleep(sensor->reset_gpio, 0);
++ gpiod_set_value_cansleep(sensor->reset_gpio, 1);
+
+ /* camera power cycle */
+ ov5640_power(sensor, false);
+- usleep_range(5000, 10000);
++ usleep_range(5000, 10000); /* t2 */
+ ov5640_power(sensor, true);
+- usleep_range(5000, 10000);
+-
+- gpiod_set_value_cansleep(sensor->reset_gpio, 1);
+- usleep_range(1000, 2000);
++ usleep_range(1000, 2000); /* t3 */
+
+ gpiod_set_value_cansleep(sensor->reset_gpio, 0);
+ } else {
+@@ -2469,7 +2466,7 @@ static void ov5640_powerup_sequence(struct ov5640_dev *sensor)
+ ov5640_write_reg(sensor, OV5640_REG_SYS_CTRL0,
+ OV5640_REG_SYS_CTRL0_SW_RST);
+ }
+- usleep_range(20000, 25000);
++ usleep_range(20000, 25000); /* t4 */
+
+ /*
+ * software standby: allows registers programming;
+--
+2.40.1
+
--- /dev/null
+From ca61574f8ea717de8a7c4cb48470294b7c0593d2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 Jun 2023 04:43:40 +0200
+Subject: media: ov5640: fix low resolution image abnormal issue
+
+From: Guoniu.zhou <guoniu.zhou@nxp.com>
+
+[ Upstream commit a828002f38c5ee49d3f0c0e64c0f0caa1aec8dc2 ]
+
+OV5640 will output abnormal image data when work at low resolution
+(320x240, 176x144 and 160x120) after switching from high resolution,
+such as 1080P, the time interval between high and low switching must
+be less than 1000ms in order to OV5640 don't enter suspend state during
+the time.
+
+The reason is by 0x3824 value don't restore to initialize value when
+do resolution switching. In high resolution setting array, 0x3824 is
+set to 0x04, but low resolution setting array remove 0x3824 in commit
+db15c1957a2d ("media: ov5640: Remove duplicated mode settings"). So
+when do resolution switching from high to low, such as 1080P to 320x240,
+and the time interval is less than auto suspend delay time which means
+global initialize setting array will not be loaded, the output image
+data are abnormal. Hence move 0x3824 from ov5640_init_setting[] table
+to ov5640_setting_low_res[] table and also move 0x4407 0x460b, 0x460c
+to avoid same issue.
+
+Fixes: db15c1957a2d ("media: ov5640: Remove duplicated mode settings")
+Signed-off-by: Guoniu.zhou <guoniu.zhou@nxp.com>
+Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/i2c/ov5640.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c
+index 1536649b9e90f..1bc4d72a906e5 100644
+--- a/drivers/media/i2c/ov5640.c
++++ b/drivers/media/i2c/ov5640.c
+@@ -568,9 +568,7 @@ static const struct reg_value ov5640_init_setting[] = {
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x3000, 0x00, 0, 0},
+ {0x3002, 0x1c, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x302e, 0x08, 0, 0}, {0x4300, 0x3f, 0, 0},
+- {0x501f, 0x00, 0, 0}, {0x4407, 0x04, 0, 0},
+- {0x440e, 0x00, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
+- {0x4837, 0x0a, 0, 0}, {0x3824, 0x02, 0, 0},
++ {0x501f, 0x00, 0, 0}, {0x440e, 0x00, 0, 0}, {0x4837, 0x0a, 0, 0},
+ {0x5000, 0xa7, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x5180, 0xff, 0, 0},
+ {0x5181, 0xf2, 0, 0}, {0x5182, 0x00, 0, 0}, {0x5183, 0x14, 0, 0},
+ {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0}, {0x5186, 0x09, 0, 0},
+@@ -634,7 +632,8 @@ static const struct reg_value ov5640_setting_low_res[] = {
+ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0},
+- {0x4407, 0x04, 0, 0}, {0x5001, 0xa3, 0, 0},
++ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
++ {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
+ };
+
+ static const struct reg_value ov5640_setting_720P_1280_720[] = {
+--
+2.40.1
+
--- /dev/null
+From c4f670b7c454427376ef33547ede9821a5448c57 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Jul 2023 17:06:11 +0200
+Subject: media: rkvdec: increase max supported height for H.264
+
+From: Benjamin Gaignard <benjamin.gaignard@collabora.com>
+
+[ Upstream commit f000e6ca2d60fefd02a180a57df2c4162fa0c1b7 ]
+
+After testing it is possible for the hardware to decode H264
+bistream with a height up to 2560.
+
+Signed-off-by: Benjamin Gaignard <benjamin.gaignard@collabora.com>
+Fixes: cd33c830448ba ("media: rkvdec: Add the rkvdec driver")
+Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/media/rkvdec/rkvdec.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c
+index 134e2b9fa7d9a..84a41792cb4b8 100644
+--- a/drivers/staging/media/rkvdec/rkvdec.c
++++ b/drivers/staging/media/rkvdec/rkvdec.c
+@@ -120,7 +120,7 @@ static const struct rkvdec_coded_fmt_desc rkvdec_coded_fmts[] = {
+ .max_width = 4096,
+ .step_width = 16,
+ .min_height = 48,
+- .max_height = 2304,
++ .max_height = 2560,
+ .step_height = 16,
+ },
+ .ctrls = &rkvdec_h264_ctrls,
+--
+2.40.1
+
--- /dev/null
+From 827c96e7e73fd4a80821209839b9dd9b08deb389 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Jun 2023 20:31:05 +0200
+Subject: media: v4l2-core: Fix a potential resource leak in
+ v4l2_fwnode_parse_link()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit d7b13edd4cb4bfa335b6008ab867ac28582d3e5c ]
+
+If fwnode_graph_get_remote_endpoint() fails, 'fwnode' is known to be NULL,
+so fwnode_handle_put() is a no-op.
+
+Release the reference taken from a previous fwnode_graph_get_port_parent()
+call instead.
+
+Also handle fwnode_graph_get_port_parent() failures.
+
+In order to fix these issues, add an error handling path to the function
+and the needed gotos.
+
+Fixes: ca50c197bd96 ("[media] v4l: fwnode: Support generic fwnode for parsing standardised properties")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/v4l2-core/v4l2-fwnode.c | 18 ++++++++++++++----
+ 1 file changed, 14 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c
+index 049c2f2001eaa..4fa9225aa3d93 100644
+--- a/drivers/media/v4l2-core/v4l2-fwnode.c
++++ b/drivers/media/v4l2-core/v4l2-fwnode.c
+@@ -568,19 +568,29 @@ int v4l2_fwnode_parse_link(struct fwnode_handle *fwnode,
+ link->local_id = fwep.id;
+ link->local_port = fwep.port;
+ link->local_node = fwnode_graph_get_port_parent(fwnode);
++ if (!link->local_node)
++ return -ENOLINK;
+
+ fwnode = fwnode_graph_get_remote_endpoint(fwnode);
+- if (!fwnode) {
+- fwnode_handle_put(fwnode);
+- return -ENOLINK;
+- }
++ if (!fwnode)
++ goto err_put_local_node;
+
+ fwnode_graph_parse_endpoint(fwnode, &fwep);
+ link->remote_id = fwep.id;
+ link->remote_port = fwep.port;
+ link->remote_node = fwnode_graph_get_port_parent(fwnode);
++ if (!link->remote_node)
++ goto err_put_remote_endpoint;
+
+ return 0;
++
++err_put_remote_endpoint:
++ fwnode_handle_put(fwnode);
++
++err_put_local_node:
++ fwnode_handle_put(link->local_node);
++
++ return -ENOLINK;
+ }
+ EXPORT_SYMBOL_GPL(v4l2_fwnode_parse_link);
+
+--
+2.40.1
+
--- /dev/null
+From 6cd84470bdb6a5cd0df7a0f2fe1baa365d964ae6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 May 2023 14:30:35 +0200
+Subject: media: venus: hfi_venus: Only consider sys_idle_indicator on V1
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit 6283e4834c69fa93a108efa18c6aa09c7e626f49 ]
+
+As per information from Qualcomm [1], this property is not really
+supported beyond msm8916 (HFI V1) and some newer HFI versions really
+dislike receiving it, going as far as crashing the device.
+
+Only consider toggling it (via the module option) on HFIV1.
+While at it, get rid of the global static variable (which defaulted
+to zero) which was never explicitly assigned to for V1.
+
+Note: [1] is a reply to the actual message in question, as lore did not
+properly receive some of the emails..
+
+[1] https://lore.kernel.org/lkml/955cd520-3881-0c22-d818-13fe9a47e124@linaro.org/
+Fixes: 7ed9e0b3393c ("media: venus: hfi, vdec: v6 Add IS_V6() to existing IS_V4() if locations")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Stanimir Varbanov <stanimir.k.varbanov@gmail.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/qcom/venus/hfi_venus.c | 18 ++++++------------
+ 1 file changed, 6 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c b/drivers/media/platform/qcom/venus/hfi_venus.c
+index 2ad40b3945b0b..bff435abd59ba 100644
+--- a/drivers/media/platform/qcom/venus/hfi_venus.c
++++ b/drivers/media/platform/qcom/venus/hfi_venus.c
+@@ -131,7 +131,6 @@ struct venus_hfi_device {
+
+ static bool venus_pkt_debug;
+ int venus_fw_debug = HFI_DEBUG_MSG_ERROR | HFI_DEBUG_MSG_FATAL;
+-static bool venus_sys_idle_indicator;
+ static bool venus_fw_low_power_mode = true;
+ static int venus_hw_rsp_timeout = 1000;
+ static bool venus_fw_coverage;
+@@ -947,17 +946,12 @@ static int venus_sys_set_default_properties(struct venus_hfi_device *hdev)
+ if (ret)
+ dev_warn(dev, "setting fw debug msg ON failed (%d)\n", ret);
+
+- /*
+- * Idle indicator is disabled by default on some 4xx firmware versions,
+- * enable it explicitly in order to make suspend functional by checking
+- * WFI (wait-for-interrupt) bit.
+- */
+- if (IS_V4(hdev->core) || IS_V6(hdev->core))
+- venus_sys_idle_indicator = true;
+-
+- ret = venus_sys_set_idle_message(hdev, venus_sys_idle_indicator);
+- if (ret)
+- dev_warn(dev, "setting idle response ON failed (%d)\n", ret);
++ /* HFI_PROPERTY_SYS_IDLE_INDICATOR is not supported beyond 8916 (HFI V1) */
++ if (IS_V1(hdev->core)) {
++ ret = venus_sys_set_idle_message(hdev, false);
++ if (ret)
++ dev_warn(dev, "setting idle response ON failed (%d)\n", ret);
++ }
+
+ ret = venus_sys_set_power_control(hdev, venus_fw_low_power_mode);
+ if (ret)
+--
+2.40.1
+
--- /dev/null
+From 7dbf01d632925e920ed51d57a65bedb2984d3573 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Jul 2023 09:15:10 +0200
+Subject: media: verisilicon: Fix TRY_FMT on encoder OUTPUT
+
+From: Michael Tretter <m.tretter@pengutronix.de>
+
+[ Upstream commit b3b4c9d3cb3bf8725a3ded26f7042b1a37f25333 ]
+
+Commit f100ce3bbd6a ("media: verisilicon: Fix crash when probing
+encoder") removed vpu_fmt from hantro_try_fmt(), since it was
+initialized from vpu_dst_fmt, which may not be initialized, when TRY_FMT
+is called. It was replaced by fmt, which is found using the pixelformat.
+
+For the encoder, this changed the fmt to contain the raw format instead
+of the coded format. The format constraints as of fmt->frmsize are only
+valid for the coded format and are 0 for the raw formats. Therefore, the
+size of a encoder OUTPUT device is constrained to 0 and the
+v4l2-compliance tests for G_FMT, TRY_FMT, and SET_FMT fail.
+
+Bring back vpu_fmt to use the coded format on an encoder OUTPUT device,
+but initialize it using the currently set pixelformat on dst_fmt, which
+is the coded format on an encoder.
+
+Fixes: f100ce3bbd6a ("media: verisilicon: Fix crash when probing encoder")
+Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/verisilicon/hantro_v4l2.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/platform/verisilicon/hantro_v4l2.c b/drivers/media/platform/verisilicon/hantro_v4l2.c
+index 61cfaaf4e927b..e56d58fe28022 100644
+--- a/drivers/media/platform/verisilicon/hantro_v4l2.c
++++ b/drivers/media/platform/verisilicon/hantro_v4l2.c
+@@ -276,6 +276,7 @@ static int hantro_try_fmt(const struct hantro_ctx *ctx,
+ enum v4l2_buf_type type)
+ {
+ const struct hantro_fmt *fmt;
++ const struct hantro_fmt *vpu_fmt;
+ bool capture = V4L2_TYPE_IS_CAPTURE(type);
+ bool coded;
+
+@@ -295,19 +296,23 @@ static int hantro_try_fmt(const struct hantro_ctx *ctx,
+
+ if (coded) {
+ pix_mp->num_planes = 1;
+- } else if (!ctx->is_encoder) {
++ vpu_fmt = fmt;
++ } else if (ctx->is_encoder) {
++ vpu_fmt = hantro_find_format(ctx, ctx->dst_fmt.pixelformat);
++ } else {
+ /*
+ * Width/height on the CAPTURE end of a decoder are ignored and
+ * replaced by the OUTPUT ones.
+ */
+ pix_mp->width = ctx->src_fmt.width;
+ pix_mp->height = ctx->src_fmt.height;
++ vpu_fmt = fmt;
+ }
+
+ pix_mp->field = V4L2_FIELD_NONE;
+
+ v4l2_apply_frmsize_constraints(&pix_mp->width, &pix_mp->height,
+- &fmt->frmsize);
++ &vpu_fmt->frmsize);
+
+ if (!coded) {
+ /* Fill remaining fields */
+--
+2.40.1
+
--- /dev/null
+From 82627f163ab133bd9bbd5d8233a5203b90138ea3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Aug 2023 15:43:10 +0200
+Subject: mlxsw: core_hwmon: Adjust module label names based on MTCAP sensor
+ counter
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Vadim Pasternak <vadimp@nvidia.com>
+
+[ Upstream commit 3fc134a07438055fc93ce1bbacf2702ddd09500c ]
+
+Transceiver module temperature sensors are indexed after ASIC and
+platform sensors. The current label printing method does not take this
+into account and simply prints the index of the transceiver module
+sensor.
+
+On new systems that have platform sensors this results in incorrect
+(shifted) transceiver module labels being printed:
+
+$ sensors
+[...]
+front panel 002: +37.0°C (crit = +70.0°C, emerg = +75.0°C)
+front panel 003: +47.0°C (crit = +70.0°C, emerg = +75.0°C)
+[...]
+
+Fix by taking the sensor count into account. After the fix:
+
+$ sensors
+[...]
+front panel 001: +37.0°C (crit = +70.0°C, emerg = +75.0°C)
+front panel 002: +47.0°C (crit = +70.0°C, emerg = +75.0°C)
+[...]
+
+Fixes: a53779de6a0e ("mlxsw: core: Add QSFP module temperature label attribute to hwmon")
+Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
+index 70735068cf292..0fd290d776ffe 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
+@@ -405,7 +405,8 @@ mlxsw_hwmon_module_temp_label_show(struct device *dev,
+ container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
+
+ return sprintf(buf, "front panel %03u\n",
+- mlxsw_hwmon_attr->type_index);
++ mlxsw_hwmon_attr->type_index + 1 -
++ mlxsw_hwmon_attr->mlxsw_hwmon_dev->sensor_count);
+ }
+
+ static ssize_t
+--
+2.40.1
+
--- /dev/null
+From 1e94ff16a7627f5d9cc1d7f4fdcd543ccbcc2dc0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Aug 2023 15:43:08 +0200
+Subject: mlxsw: i2c: Fix chunk size setting in output mailbox buffer
+
+From: Vadim Pasternak <vadimp@nvidia.com>
+
+[ Upstream commit 146c7c330507c0384bf29d567186632bfe975927 ]
+
+The driver reads commands output from the output mailbox. If the size
+of the output mailbox is not a multiple of the transaction /
+block size, then the driver will not issue enough read transactions
+to read the entire output, which can result in driver initialization
+errors.
+
+Fix by determining the number of transactions using DIV_ROUND_UP().
+
+Fixes: 3029a693beda ("mlxsw: i2c: Allow flexible setting of I2C transactions size")
+Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlxsw/i2c.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/i2c.c b/drivers/net/ethernet/mellanox/mlxsw/i2c.c
+index 2c586c2308aef..d23734ecb416a 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/i2c.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/i2c.c
+@@ -444,7 +444,7 @@ mlxsw_i2c_cmd(struct device *dev, u16 opcode, u32 in_mod, size_t in_mbox_size,
+ } else {
+ /* No input mailbox is case of initialization query command. */
+ reg_size = MLXSW_I2C_MAX_DATA_SIZE;
+- num = reg_size / mlxsw_i2c->block_size;
++ num = DIV_ROUND_UP(reg_size, mlxsw_i2c->block_size);
+
+ if (mutex_lock_interruptible(&mlxsw_i2c->cmd.lock) < 0) {
+ dev_err(&client->dev, "Could not acquire lock");
+--
+2.40.1
+
--- /dev/null
+From 68372e3892e62c7306dc0a625aafdeadadbf8b7d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Aug 2023 15:43:09 +0200
+Subject: mlxsw: i2c: Limit single transaction buffer size
+
+From: Vadim Pasternak <vadimp@nvidia.com>
+
+[ Upstream commit d7248f1cc835bd80e936dc5b2d94b149bdd0077d ]
+
+Maximum size of buffer is obtained from underlying I2C adapter and in
+case adapter allows I2C transaction buffer size greater than 100 bytes,
+transaction will fail due to firmware limitation.
+
+As a result driver will fail initialization.
+
+Limit the maximum size of transaction buffer by 100 bytes to fit to
+firmware.
+
+Remove unnecessary calculation:
+max_t(u16, MLXSW_I2C_BLK_DEF, quirk_size).
+This condition can not happened.
+
+Fixes: 3029a693beda ("mlxsw: i2c: Allow flexible setting of I2C transactions size")
+Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
+Reviewed-by: Petr Machata <petrm@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlxsw/i2c.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/i2c.c b/drivers/net/ethernet/mellanox/mlxsw/i2c.c
+index d23734ecb416a..4fac27c36ad85 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/i2c.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/i2c.c
+@@ -48,6 +48,7 @@
+ #define MLXSW_I2C_MBOX_SIZE_BITS 12
+ #define MLXSW_I2C_ADDR_BUF_SIZE 4
+ #define MLXSW_I2C_BLK_DEF 32
++#define MLXSW_I2C_BLK_MAX 100
+ #define MLXSW_I2C_RETRY 5
+ #define MLXSW_I2C_TIMEOUT_MSECS 5000
+ #define MLXSW_I2C_MAX_DATA_SIZE 256
+@@ -653,7 +654,7 @@ static int mlxsw_i2c_probe(struct i2c_client *client)
+ return -EOPNOTSUPP;
+ }
+
+- mlxsw_i2c->block_size = max_t(u16, MLXSW_I2C_BLK_DEF,
++ mlxsw_i2c->block_size = min_t(u16, MLXSW_I2C_BLK_MAX,
+ min_t(u16, quirks->max_read_len,
+ quirks->max_write_len));
+ } else {
+--
+2.40.1
+
--- /dev/null
+From 644927b35057c1232316547ad62368bf2bfa9b94 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Jul 2023 11:29:09 -0700
+Subject: mtd: rawnand: brcmnand: Fix mtd oobsize
+
+From: William Zhang <william.zhang@broadcom.com>
+
+[ Upstream commit 60177390fa061c62d156f4a546e3efd90df3c183 ]
+
+brcmnand controller can only access the flash spare area up to certain
+bytes based on the ECC level. It can be less than the actual flash spare
+area size. For example, for many NAND chip supporting ECC BCH-8, it has
+226 bytes spare area. But controller can only uses 218 bytes. So brcmand
+driver overrides the mtd oobsize with the controller's accessible spare
+area size. When the nand base driver utilizes the nand_device object, it
+resets the oobsize back to the actual flash spare aprea size from
+nand_memory_organization structure and controller may not able to access
+all the oob area as mtd advises.
+
+This change fixes the issue by overriding the oobsize in the
+nand_memory_organization structure to the controller's accessible spare
+area size.
+
+Fixes: a7ab085d7c16 ("mtd: rawnand: Initialize the nand_device object")
+Signed-off-by: William Zhang <william.zhang@broadcom.com>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20230706182909.79151-6-william.zhang@broadcom.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/nand/raw/brcmnand/brcmnand.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+index 2e9c2e2d9c9f7..d8418d7fcc372 100644
+--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
++++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+@@ -2612,6 +2612,8 @@ static int brcmnand_setup_dev(struct brcmnand_host *host)
+ struct nand_chip *chip = &host->chip;
+ const struct nand_ecc_props *requirements =
+ nanddev_get_ecc_requirements(&chip->base);
++ struct nand_memory_organization *memorg =
++ nanddev_get_memorg(&chip->base);
+ struct brcmnand_controller *ctrl = host->ctrl;
+ struct brcmnand_cfg *cfg = &host->hwcfg;
+ char msg[128];
+@@ -2633,10 +2635,11 @@ static int brcmnand_setup_dev(struct brcmnand_host *host)
+ if (cfg->spare_area_size > ctrl->max_oob)
+ cfg->spare_area_size = ctrl->max_oob;
+ /*
+- * Set oobsize to be consistent with controller's spare_area_size, as
+- * the rest is inaccessible.
++ * Set mtd and memorg oobsize to be consistent with controller's
++ * spare_area_size, as the rest is inaccessible.
+ */
+ mtd->oobsize = cfg->spare_area_size * (mtd->writesize >> FC_SHIFT);
++ memorg->oobsize = mtd->oobsize;
+
+ cfg->device_size = mtd->size;
+ cfg->block_size = mtd->erasesize;
+--
+2.40.1
+
--- /dev/null
+From 1770e92dc7057f037f74a55b0794443f395ab5dd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Aug 2023 19:58:39 +0800
+Subject: mtd: rawnand: fsmc: handle clk prepare error in fsmc_nand_resume()
+
+From: Yi Yang <yiyang13@huawei.com>
+
+[ Upstream commit a5a88125d00612586e941ae13e7fcf36ba8f18a7 ]
+
+In fsmc_nand_resume(), the return value of clk_prepare_enable() should be
+checked since it might fail.
+
+Fixes: e25da1c07dfb ("mtd: fsmc_nand: Add clk_{un}prepare() support")
+Signed-off-by: Yi Yang <yiyang13@huawei.com>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20230817115839.10192-1-yiyang13@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/nand/raw/fsmc_nand.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mtd/nand/raw/fsmc_nand.c b/drivers/mtd/nand/raw/fsmc_nand.c
+index 7b4742420dfcb..2e33ae77502a0 100644
+--- a/drivers/mtd/nand/raw/fsmc_nand.c
++++ b/drivers/mtd/nand/raw/fsmc_nand.c
+@@ -1200,9 +1200,14 @@ static int fsmc_nand_suspend(struct device *dev)
+ static int fsmc_nand_resume(struct device *dev)
+ {
+ struct fsmc_nand_data *host = dev_get_drvdata(dev);
++ int ret;
+
+ if (host) {
+- clk_prepare_enable(host->clk);
++ ret = clk_prepare_enable(host->clk);
++ if (ret) {
++ dev_err(dev, "failed to enable clk\n");
++ return ret;
++ }
+ if (host->dev_timings)
+ fsmc_nand_setup(host, host->dev_timings);
+ nand_reset(&host->nand, 0);
+--
+2.40.1
+
--- /dev/null
+From 85c51855f79668704f65ba5658b3eb52623cc441 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Aug 2023 14:42:23 +0800
+Subject: mtd: spi-nor: Check bus width while setting QE bit
+
+From: Hsin-Yi Wang <hsinyi@chromium.org>
+
+[ Upstream commit f01d8155a92e33cdaa85d20bfbe6c441907b3c1f ]
+
+spi_nor_write_16bit_sr_and_check() should also check if bus width is
+4 before setting QE bit.
+
+Fixes: 39d1e3340c73 ("mtd: spi-nor: Fix clearing of QE bit on lock()/unlock()")
+Suggested-by: Michael Walle <michael@walle.cc>
+Suggested-by: Tudor Ambarus <tudor.ambarus@linaro.org>
+Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>
+Reviewed-by: Michael Walle <michael@walle.cc>
+Link: https://lore.kernel.org/r/20230818064524.1229100-2-hsinyi@chromium.org
+Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/spi-nor/core.c | 19 ++++++++++---------
+ 1 file changed, 10 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
+index 5f29fac8669a3..55f4a902b8be9 100644
+--- a/drivers/mtd/spi-nor/core.c
++++ b/drivers/mtd/spi-nor/core.c
+@@ -870,21 +870,22 @@ static int spi_nor_write_16bit_sr_and_check(struct spi_nor *nor, u8 sr1)
+ ret = spi_nor_read_cr(nor, &sr_cr[1]);
+ if (ret)
+ return ret;
+- } else if (nor->params->quad_enable) {
++ } else if (spi_nor_get_protocol_width(nor->read_proto) == 4 &&
++ spi_nor_get_protocol_width(nor->write_proto) == 4 &&
++ nor->params->quad_enable) {
+ /*
+ * If the Status Register 2 Read command (35h) is not
+ * supported, we should at least be sure we don't
+ * change the value of the SR2 Quad Enable bit.
+ *
+- * We can safely assume that when the Quad Enable method is
+- * set, the value of the QE bit is one, as a consequence of the
+- * nor->params->quad_enable() call.
++ * When the Quad Enable method is set and the buswidth is 4, we
++ * can safely assume that the value of the QE bit is one, as a
++ * consequence of the nor->params->quad_enable() call.
+ *
+- * We can safely assume that the Quad Enable bit is present in
+- * the Status Register 2 at BIT(1). According to the JESD216
+- * revB standard, BFPT DWORDS[15], bits 22:20, the 16-bit
+- * Write Status (01h) command is available just for the cases
+- * in which the QE bit is described in SR2 at BIT(1).
++ * According to the JESD216 revB standard, BFPT DWORDS[15],
++ * bits 22:20, the 16-bit Write Status (01h) command is
++ * available just for the cases in which the QE bit is
++ * described in SR2 at BIT(1).
+ */
+ sr_cr[1] = SR2_QUAD_EN_BIT1;
+ } else {
+--
+2.40.1
+
--- /dev/null
+From 8cd1d96b1249694ddcd20d71eb789406e0a0f502 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 19 Aug 2023 04:06:46 +0000
+Subject: net: annotate data-races around sk->sk_lingertime
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit bc1fb82ae11753c5dec53c667a055dc37796dbd2 ]
+
+sk_getsockopt() runs locklessly. This means sk->sk_lingertime
+can be read while other threads are changing its value.
+
+Other reads also happen without socket lock being held,
+and must be annotated.
+
+Remove preprocessor logic using BITS_PER_LONG, compilers
+are smart enough to figure this by themselves.
+
+v2: fixed a clang W=1 (-Wtautological-constant-out-of-range-compare) warning
+ (Jakub)
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/iso.c | 2 +-
+ net/bluetooth/sco.c | 2 +-
+ net/core/sock.c | 18 +++++++++---------
+ net/sched/em_meta.c | 2 +-
+ net/smc/af_smc.c | 2 +-
+ 5 files changed, 13 insertions(+), 13 deletions(-)
+
+diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
+index cd07836850758..00e93ae6373da 100644
+--- a/net/bluetooth/iso.c
++++ b/net/bluetooth/iso.c
+@@ -1486,7 +1486,7 @@ static int iso_sock_release(struct socket *sock)
+
+ iso_sock_close(sk);
+
+- if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime &&
++ if (sock_flag(sk, SOCK_LINGER) && READ_ONCE(sk->sk_lingertime) &&
+ !(current->flags & PF_EXITING)) {
+ lock_sock(sk);
+ err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime);
+diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
+index 7762604ddfc05..99b149261949a 100644
+--- a/net/bluetooth/sco.c
++++ b/net/bluetooth/sco.c
+@@ -1267,7 +1267,7 @@ static int sco_sock_release(struct socket *sock)
+
+ sco_sock_close(sk);
+
+- if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime &&
++ if (sock_flag(sk, SOCK_LINGER) && READ_ONCE(sk->sk_lingertime) &&
+ !(current->flags & PF_EXITING)) {
+ lock_sock(sk);
+ err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime);
+diff --git a/net/core/sock.c b/net/core/sock.c
+index ddcf0630cc3ee..b2083a359ec10 100644
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -793,7 +793,7 @@ EXPORT_SYMBOL(sock_set_reuseport);
+ void sock_no_linger(struct sock *sk)
+ {
+ lock_sock(sk);
+- sk->sk_lingertime = 0;
++ WRITE_ONCE(sk->sk_lingertime, 0);
+ sock_set_flag(sk, SOCK_LINGER);
+ release_sock(sk);
+ }
+@@ -1226,15 +1226,15 @@ int sk_setsockopt(struct sock *sk, int level, int optname,
+ ret = -EFAULT;
+ break;
+ }
+- if (!ling.l_onoff)
++ if (!ling.l_onoff) {
+ sock_reset_flag(sk, SOCK_LINGER);
+- else {
+-#if (BITS_PER_LONG == 32)
+- if ((unsigned int)ling.l_linger >= MAX_SCHEDULE_TIMEOUT/HZ)
+- sk->sk_lingertime = MAX_SCHEDULE_TIMEOUT;
++ } else {
++ unsigned long t_sec = ling.l_linger;
++
++ if (t_sec >= MAX_SCHEDULE_TIMEOUT / HZ)
++ WRITE_ONCE(sk->sk_lingertime, MAX_SCHEDULE_TIMEOUT);
+ else
+-#endif
+- sk->sk_lingertime = (unsigned int)ling.l_linger * HZ;
++ WRITE_ONCE(sk->sk_lingertime, t_sec * HZ);
+ sock_set_flag(sk, SOCK_LINGER);
+ }
+ break;
+@@ -1680,7 +1680,7 @@ int sk_getsockopt(struct sock *sk, int level, int optname,
+ case SO_LINGER:
+ lv = sizeof(v.ling);
+ v.ling.l_onoff = sock_flag(sk, SOCK_LINGER);
+- v.ling.l_linger = sk->sk_lingertime / HZ;
++ v.ling.l_linger = READ_ONCE(sk->sk_lingertime) / HZ;
+ break;
+
+ case SO_BSDCOMPAT:
+diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c
+index 6fdba069f6bfd..da34fd4c92695 100644
+--- a/net/sched/em_meta.c
++++ b/net/sched/em_meta.c
+@@ -502,7 +502,7 @@ META_COLLECTOR(int_sk_lingertime)
+ *err = -1;
+ return;
+ }
+- dst->value = sk->sk_lingertime / HZ;
++ dst->value = READ_ONCE(sk->sk_lingertime) / HZ;
+ }
+
+ META_COLLECTOR(int_sk_err_qlen)
+diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
+index f94e7a04e33d0..462ece6bb1802 100644
+--- a/net/smc/af_smc.c
++++ b/net/smc/af_smc.c
+@@ -1820,7 +1820,7 @@ void smc_close_non_accepted(struct sock *sk)
+ lock_sock(sk);
+ if (!sk->sk_lingertime)
+ /* wait for peer closing */
+- sk->sk_lingertime = SMC_MAX_STREAM_WAIT_TIMEOUT;
++ WRITE_ONCE(sk->sk_lingertime, SMC_MAX_STREAM_WAIT_TIMEOUT);
+ __smc_release(smc);
+ release_sock(sk);
+ sock_put(sk); /* sock_hold above */
+--
+2.40.1
+
--- /dev/null
+From ddadac1f41557351a477b3963b644171f84b6d89 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Aug 2023 14:43:36 +0800
+Subject: net: arcnet: Do not call kfree_skb() under local_irq_disable()
+
+From: Jinjie Ruan <ruanjinjie@huawei.com>
+
+[ Upstream commit 786c96e92fb9e854cb8b0cb7399bb2fb28e15c4b ]
+
+It is not allowed to call kfree_skb() from hardware interrupt
+context or with hardware interrupts being disabled.
+So replace kfree_skb() with dev_kfree_skb_irq() under
+local_irq_disable(). Compile tested only.
+
+Fixes: 05fcd31cc472 ("arcnet: add err_skb package for package status feedback")
+Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/arcnet/arcnet.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c
+index 1bad1866ae462..a48220f91a2df 100644
+--- a/drivers/net/arcnet/arcnet.c
++++ b/drivers/net/arcnet/arcnet.c
+@@ -468,7 +468,7 @@ static void arcnet_reply_tasklet(struct tasklet_struct *t)
+
+ ret = sock_queue_err_skb(sk, ackskb);
+ if (ret)
+- kfree_skb(ackskb);
++ dev_kfree_skb_irq(ackskb);
+
+ local_irq_enable();
+ };
+--
+2.40.1
+
--- /dev/null
+From 2e96dd1287139a03a298d686375ba0e638370ead Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Jul 2023 17:30:07 +0200
+Subject: net: export inet_lookup_reuseport and inet6_lookup_reuseport
+
+From: Lorenz Bauer <lmb@isovalent.com>
+
+[ Upstream commit ce796e60b3b196b61fcc565df195443cbb846ef0 ]
+
+Rename the existing reuseport helpers for IPv4 and IPv6 so that they
+can be invoked in the follow up commit. Export them so that building
+DCCP and IPv6 as a module works.
+
+No change in functionality.
+
+Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: Lorenz Bauer <lmb@isovalent.com>
+Link: https://lore.kernel.org/r/20230720-so-reuseport-v6-3-7021b683cdae@isovalent.com
+Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
+Stable-dep-of: 9c02bec95954 ("bpf, net: Support SO_REUSEPORT sockets with bpf_sk_assign")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/inet6_hashtables.h | 7 +++++++
+ include/net/inet_hashtables.h | 5 +++++
+ net/ipv4/inet_hashtables.c | 15 ++++++++-------
+ net/ipv6/inet6_hashtables.c | 19 ++++++++++---------
+ 4 files changed, 30 insertions(+), 16 deletions(-)
+
+diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h
+index 56f1286583d3c..032ddab48f8f8 100644
+--- a/include/net/inet6_hashtables.h
++++ b/include/net/inet6_hashtables.h
+@@ -48,6 +48,13 @@ struct sock *__inet6_lookup_established(struct net *net,
+ const u16 hnum, const int dif,
+ const int sdif);
+
++struct sock *inet6_lookup_reuseport(struct net *net, struct sock *sk,
++ struct sk_buff *skb, int doff,
++ const struct in6_addr *saddr,
++ __be16 sport,
++ const struct in6_addr *daddr,
++ unsigned short hnum);
++
+ struct sock *inet6_lookup_listener(struct net *net,
+ struct inet_hashinfo *hashinfo,
+ struct sk_buff *skb, int doff,
+diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
+index 99bd823e97f62..8734f3488f5d0 100644
+--- a/include/net/inet_hashtables.h
++++ b/include/net/inet_hashtables.h
+@@ -379,6 +379,11 @@ struct sock *__inet_lookup_established(struct net *net,
+ const __be32 daddr, const u16 hnum,
+ const int dif, const int sdif);
+
++struct sock *inet_lookup_reuseport(struct net *net, struct sock *sk,
++ struct sk_buff *skb, int doff,
++ __be32 saddr, __be16 sport,
++ __be32 daddr, unsigned short hnum);
++
+ static inline struct sock *
+ inet_lookup_established(struct net *net, struct inet_hashinfo *hashinfo,
+ const __be32 saddr, const __be16 sport,
+diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
+index 0819d6001b9ab..ecb838460629e 100644
+--- a/net/ipv4/inet_hashtables.c
++++ b/net/ipv4/inet_hashtables.c
+@@ -332,10 +332,10 @@ static inline int compute_score(struct sock *sk, struct net *net,
+ return score;
+ }
+
+-static inline struct sock *lookup_reuseport(struct net *net, struct sock *sk,
+- struct sk_buff *skb, int doff,
+- __be32 saddr, __be16 sport,
+- __be32 daddr, unsigned short hnum)
++struct sock *inet_lookup_reuseport(struct net *net, struct sock *sk,
++ struct sk_buff *skb, int doff,
++ __be32 saddr, __be16 sport,
++ __be32 daddr, unsigned short hnum)
+ {
+ struct sock *reuse_sk = NULL;
+ u32 phash;
+@@ -346,6 +346,7 @@ static inline struct sock *lookup_reuseport(struct net *net, struct sock *sk,
+ }
+ return reuse_sk;
+ }
++EXPORT_SYMBOL_GPL(inet_lookup_reuseport);
+
+ /*
+ * Here are some nice properties to exploit here. The BSD API
+@@ -369,8 +370,8 @@ static struct sock *inet_lhash2_lookup(struct net *net,
+ sk_nulls_for_each_rcu(sk, node, &ilb2->nulls_head) {
+ score = compute_score(sk, net, hnum, daddr, dif, sdif);
+ if (score > hiscore) {
+- result = lookup_reuseport(net, sk, skb, doff,
+- saddr, sport, daddr, hnum);
++ result = inet_lookup_reuseport(net, sk, skb, doff,
++ saddr, sport, daddr, hnum);
+ if (result)
+ return result;
+
+@@ -399,7 +400,7 @@ static inline struct sock *inet_lookup_run_bpf(struct net *net,
+ if (no_reuseport || IS_ERR_OR_NULL(sk))
+ return sk;
+
+- reuse_sk = lookup_reuseport(net, sk, skb, doff, saddr, sport, daddr, hnum);
++ reuse_sk = inet_lookup_reuseport(net, sk, skb, doff, saddr, sport, daddr, hnum);
+ if (reuse_sk)
+ sk = reuse_sk;
+ return sk;
+diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
+index b64b49012655e..b7c56867314ed 100644
+--- a/net/ipv6/inet6_hashtables.c
++++ b/net/ipv6/inet6_hashtables.c
+@@ -111,12 +111,12 @@ static inline int compute_score(struct sock *sk, struct net *net,
+ return score;
+ }
+
+-static inline struct sock *lookup_reuseport(struct net *net, struct sock *sk,
+- struct sk_buff *skb, int doff,
+- const struct in6_addr *saddr,
+- __be16 sport,
+- const struct in6_addr *daddr,
+- unsigned short hnum)
++struct sock *inet6_lookup_reuseport(struct net *net, struct sock *sk,
++ struct sk_buff *skb, int doff,
++ const struct in6_addr *saddr,
++ __be16 sport,
++ const struct in6_addr *daddr,
++ unsigned short hnum)
+ {
+ struct sock *reuse_sk = NULL;
+ u32 phash;
+@@ -127,6 +127,7 @@ static inline struct sock *lookup_reuseport(struct net *net, struct sock *sk,
+ }
+ return reuse_sk;
+ }
++EXPORT_SYMBOL_GPL(inet6_lookup_reuseport);
+
+ /* called with rcu_read_lock() */
+ static struct sock *inet6_lhash2_lookup(struct net *net,
+@@ -143,8 +144,8 @@ static struct sock *inet6_lhash2_lookup(struct net *net,
+ sk_nulls_for_each_rcu(sk, node, &ilb2->nulls_head) {
+ score = compute_score(sk, net, hnum, daddr, dif, sdif);
+ if (score > hiscore) {
+- result = lookup_reuseport(net, sk, skb, doff,
+- saddr, sport, daddr, hnum);
++ result = inet6_lookup_reuseport(net, sk, skb, doff,
++ saddr, sport, daddr, hnum);
+ if (result)
+ return result;
+
+@@ -175,7 +176,7 @@ static inline struct sock *inet6_lookup_run_bpf(struct net *net,
+ if (no_reuseport || IS_ERR_OR_NULL(sk))
+ return sk;
+
+- reuse_sk = lookup_reuseport(net, sk, skb, doff, saddr, sport, daddr, hnum);
++ reuse_sk = inet6_lookup_reuseport(net, sk, skb, doff, saddr, sport, daddr, hnum);
+ if (reuse_sk)
+ sk = reuse_sk;
+ return sk;
+--
+2.40.1
+
--- /dev/null
+From 14a7c473d8d22952b08334d2657356e4926a8251 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Aug 2023 09:53:41 +0100
+Subject: net: Fix slab-out-of-bounds in inet[6]_steal_sock
+
+From: Lorenz Bauer <lmb@isovalent.com>
+
+[ Upstream commit 8897562f67b3e61ad736cd5c9f307447d33280e4 ]
+
+Kumar reported a KASAN splat in tcp_v6_rcv:
+
+ bash-5.2# ./test_progs -t btf_skc_cls_ingress
+ ...
+ [ 51.810085] BUG: KASAN: slab-out-of-bounds in tcp_v6_rcv+0x2d7d/0x3440
+ [ 51.810458] Read of size 2 at addr ffff8881053f038c by task test_progs/226
+
+The problem is that inet[6]_steal_sock accesses sk->sk_protocol without
+accounting for request or timewait sockets. To fix this we can't just
+check sock_common->skc_reuseport since that flag is present on timewait
+sockets.
+
+Instead, add a fullsock check to avoid the out of bands access of sk_protocol.
+
+Fixes: 9c02bec95954 ("bpf, net: Support SO_REUSEPORT sockets with bpf_sk_assign")
+Reported-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+Signed-off-by: Lorenz Bauer <lmb@isovalent.com>
+Link: https://lore.kernel.org/r/20230815-bpf-next-v2-1-95126eaa4c1b@isovalent.com
+Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/inet6_hashtables.h | 2 +-
+ include/net/inet_hashtables.h | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h
+index 475e672b4facc..12780b8fb5630 100644
+--- a/include/net/inet6_hashtables.h
++++ b/include/net/inet6_hashtables.h
+@@ -107,7 +107,7 @@ struct sock *inet6_steal_sock(struct net *net, struct sk_buff *skb, int doff,
+ if (!sk)
+ return NULL;
+
+- if (!prefetched)
++ if (!prefetched || !sk_fullsock(sk))
+ return sk;
+
+ if (sk->sk_protocol == IPPROTO_TCP) {
+diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
+index a1b8eb147ce73..9414cb4e6e624 100644
+--- a/include/net/inet_hashtables.h
++++ b/include/net/inet_hashtables.h
+@@ -455,7 +455,7 @@ struct sock *inet_steal_sock(struct net *net, struct sk_buff *skb, int doff,
+ if (!sk)
+ return NULL;
+
+- if (!prefetched)
++ if (!prefetched || !sk_fullsock(sk))
+ return sk;
+
+ if (sk->sk_protocol == IPPROTO_TCP) {
+--
+2.40.1
+
--- /dev/null
+From 8d7c6e193922a79a987cb8c4527121bcc5859450 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Aug 2023 14:06:41 +0800
+Subject: net: hns3: fix wrong rpu tln reg issue
+
+From: Jijie Shao <shaojijie@huawei.com>
+
+[ Upstream commit 36122201eeaefd78547def9681aa5d83b5a00b6a ]
+
+In the original RPU query command, the status register values of
+multiple RPU tunnels are accumulated by default, which is unreasonable.
+This patch Fix it by querying the specified tunnel ID.
+The tunnel number of the device can be obtained from firmware
+during initialization.
+
+Fixes: ddb54554fa51 ("net: hns3: add DFX registers information for ethtool -d")
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hns3/hnae3.h | 1 +
+ .../hisilicon/hns3/hns3pf/hclge_cmd.h | 4 +-
+ .../hisilicon/hns3/hns3pf/hclge_main.c | 2 +
+ .../hisilicon/hns3/hns3pf/hclge_regs.c | 66 ++++++++++++++++++-
+ 4 files changed, 71 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+index 6df84184173d1..e9c108128bb3b 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
++++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+@@ -382,6 +382,7 @@ struct hnae3_dev_specs {
+ u16 umv_size;
+ u16 mc_mac_size;
+ u32 mac_stats_num;
++ u8 tnl_num;
+ };
+
+ struct hnae3_client_ops {
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
+index 91c173f40701a..d5cfdc4c082d8 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
+@@ -826,7 +826,9 @@ struct hclge_dev_specs_1_cmd {
+ u8 rsv0[2];
+ __le16 umv_size;
+ __le16 mc_mac_size;
+- u8 rsv1[12];
++ u8 rsv1[6];
++ u8 tnl_num;
++ u8 rsv2[5];
+ };
+
+ /* mac speed type defined in firmware command */
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+index cd41e7cb65306..0d56dc2e9960e 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+@@ -1327,6 +1327,7 @@ static void hclge_set_default_dev_specs(struct hclge_dev *hdev)
+ ae_dev->dev_specs.max_frm_size = HCLGE_MAC_MAX_FRAME;
+ ae_dev->dev_specs.max_qset_num = HCLGE_MAX_QSET_NUM;
+ ae_dev->dev_specs.umv_size = HCLGE_DEFAULT_UMV_SPACE_PER_PF;
++ ae_dev->dev_specs.tnl_num = 0;
+ }
+
+ static void hclge_parse_dev_specs(struct hclge_dev *hdev,
+@@ -1350,6 +1351,7 @@ static void hclge_parse_dev_specs(struct hclge_dev *hdev,
+ ae_dev->dev_specs.max_frm_size = le16_to_cpu(req1->max_frm_size);
+ ae_dev->dev_specs.umv_size = le16_to_cpu(req1->umv_size);
+ ae_dev->dev_specs.mc_mac_size = le16_to_cpu(req1->mc_mac_size);
++ ae_dev->dev_specs.tnl_num = req1->tnl_num;
+ }
+
+ static void hclge_check_dev_specs(struct hclge_dev *hdev)
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c
+index 734e5f757b9c5..43c1c18fa81f8 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c
+@@ -125,6 +125,7 @@ enum hclge_reg_tag {
+ HCLGE_REG_TAG_DFX_RCB,
+ HCLGE_REG_TAG_DFX_TQP,
+ HCLGE_REG_TAG_DFX_SSU_2,
++ HCLGE_REG_TAG_RPU_TNL,
+ };
+
+ #pragma pack(4)
+@@ -147,6 +148,8 @@ struct hclge_reg_header {
+ #define HCLGE_REG_HEADER_SPACE (sizeof(struct hclge_reg_header) / sizeof(u32))
+ #define HCLGE_REG_MAGIC_NUMBER 0x686e733372656773 /* meaning is hns3regs */
+
++#define HCLGE_REG_RPU_TNL_ID_0 1
++
+ static u32 hclge_reg_get_header(void *data)
+ {
+ struct hclge_reg_header *header = data;
+@@ -342,6 +345,28 @@ static int hclge_dfx_reg_cmd_send(struct hclge_dev *hdev,
+ return ret;
+ }
+
++/* tnl_id = 0 means get sum of all tnl reg's value */
++static int hclge_dfx_reg_rpu_tnl_cmd_send(struct hclge_dev *hdev, u32 tnl_id,
++ struct hclge_desc *desc, int bd_num)
++{
++ int i, ret;
++
++ for (i = 0; i < bd_num; i++) {
++ hclge_cmd_setup_basic_desc(&desc[i], HCLGE_OPC_DFX_RPU_REG_0,
++ true);
++ if (i != bd_num - 1)
++ desc[i].flag |= cpu_to_le16(HCLGE_COMM_CMD_FLAG_NEXT);
++ }
++
++ desc[0].data[0] = cpu_to_le32(tnl_id);
++ ret = hclge_cmd_send(&hdev->hw, desc, bd_num);
++ if (ret)
++ dev_err(&hdev->pdev->dev,
++ "failed to query dfx rpu tnl reg, ret = %d\n",
++ ret);
++ return ret;
++}
++
+ static int hclge_dfx_reg_fetch_data(struct hclge_desc *desc_src, int bd_num,
+ void *data)
+ {
+@@ -363,6 +388,7 @@ static int hclge_dfx_reg_fetch_data(struct hclge_desc *desc_src, int bd_num,
+ static int hclge_get_dfx_reg_len(struct hclge_dev *hdev, int *len)
+ {
+ u32 dfx_reg_type_num = ARRAY_SIZE(hclge_dfx_bd_offset_list);
++ struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev);
+ int data_len_per_desc;
+ int *bd_num_list;
+ int ret;
+@@ -384,11 +410,41 @@ static int hclge_get_dfx_reg_len(struct hclge_dev *hdev, int *len)
+ for (i = 0; i < dfx_reg_type_num; i++)
+ *len += bd_num_list[i] * data_len_per_desc + HCLGE_REG_TLV_SIZE;
+
++ /**
++ * the num of dfx_rpu_0 is reused by each dfx_rpu_tnl
++ * HCLGE_DFX_BD_OFFSET is starting at 1, but the array subscript is
++ * starting at 0, so offset need '- 1'.
++ */
++ *len += (bd_num_list[HCLGE_DFX_RPU_0_BD_OFFSET - 1] * data_len_per_desc +
++ HCLGE_REG_TLV_SIZE) * ae_dev->dev_specs.tnl_num;
++
+ out:
+ kfree(bd_num_list);
+ return ret;
+ }
+
++static int hclge_get_dfx_rpu_tnl_reg(struct hclge_dev *hdev, u32 *reg,
++ struct hclge_desc *desc_src,
++ int bd_num)
++{
++ struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev);
++ int ret = 0;
++ u8 i;
++
++ for (i = HCLGE_REG_RPU_TNL_ID_0; i <= ae_dev->dev_specs.tnl_num; i++) {
++ ret = hclge_dfx_reg_rpu_tnl_cmd_send(hdev, i, desc_src, bd_num);
++ if (ret)
++ break;
++
++ reg += hclge_reg_get_tlv(HCLGE_REG_TAG_RPU_TNL,
++ ARRAY_SIZE(desc_src->data) * bd_num,
++ reg);
++ reg += hclge_dfx_reg_fetch_data(desc_src, bd_num, reg);
++ }
++
++ return ret;
++}
++
+ static int hclge_get_dfx_reg(struct hclge_dev *hdev, void *data)
+ {
+ u32 dfx_reg_type_num = ARRAY_SIZE(hclge_dfx_bd_offset_list);
+@@ -428,7 +484,7 @@ static int hclge_get_dfx_reg(struct hclge_dev *hdev, void *data)
+ if (ret) {
+ dev_err(&hdev->pdev->dev,
+ "Get dfx reg fail, status is %d.\n", ret);
+- break;
++ goto free;
+ }
+
+ reg += hclge_reg_get_tlv(HCLGE_REG_TAG_DFX_BIOS_COMMON + i,
+@@ -437,6 +493,14 @@ static int hclge_get_dfx_reg(struct hclge_dev *hdev, void *data)
+ reg += hclge_dfx_reg_fetch_data(desc_src, bd_num, reg);
+ }
+
++ /**
++ * HCLGE_DFX_BD_OFFSET is starting at 1, but the array subscript is
++ * starting at 0, so offset need '- 1'.
++ */
++ bd_num = bd_num_list[HCLGE_DFX_RPU_0_BD_OFFSET - 1];
++ ret = hclge_get_dfx_rpu_tnl_reg(hdev, reg, desc_src, bd_num);
++
++free:
+ kfree(desc_src);
+ out:
+ kfree(bd_num_list);
+--
+2.40.1
+
--- /dev/null
+From efe1b9c50a2d137062071e8b2c7915c344e7ddc5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Aug 2023 14:06:38 +0800
+Subject: net: hns3: move dump regs function to a separate file
+
+From: Jijie Shao <shaojijie@huawei.com>
+
+[ Upstream commit 939ccd107ffcade20c9c7055a2e7ae0fd724fb72 ]
+
+The dump register function is being refactored.
+The first step in refactoring is put the dump regs function
+into a separate file.
+
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 36122201eeae ("net: hns3: fix wrong rpu tln reg issue")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hns3/Makefile | 4 +-
+ .../hisilicon/hns3/hns3pf/hclge_debugfs.c | 1 +
+ .../hisilicon/hns3/hns3pf/hclge_main.c | 558 +----------------
+ .../hisilicon/hns3/hns3pf/hclge_main.h | 2 -
+ .../hisilicon/hns3/hns3pf/hclge_regs.c | 567 ++++++++++++++++++
+ .../hisilicon/hns3/hns3pf/hclge_regs.h | 17 +
+ .../hisilicon/hns3/hns3vf/hclgevf_main.c | 121 +---
+ .../hisilicon/hns3/hns3vf/hclgevf_main.h | 1 +
+ .../hisilicon/hns3/hns3vf/hclgevf_regs.c | 127 ++++
+ .../hisilicon/hns3/hns3vf/hclgevf_regs.h | 13 +
+ 10 files changed, 731 insertions(+), 680 deletions(-)
+ create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c
+ create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.h
+ create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c
+ create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.h
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/Makefile b/drivers/net/ethernet/hisilicon/hns3/Makefile
+index 6efea46628587..e214bfaece1f3 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/Makefile
++++ b/drivers/net/ethernet/hisilicon/hns3/Makefile
+@@ -17,11 +17,11 @@ hns3-$(CONFIG_HNS3_DCB) += hns3_dcbnl.o
+
+ obj-$(CONFIG_HNS3_HCLGEVF) += hclgevf.o
+
+-hclgevf-objs = hns3vf/hclgevf_main.o hns3vf/hclgevf_mbx.o hns3vf/hclgevf_devlink.o \
++hclgevf-objs = hns3vf/hclgevf_main.o hns3vf/hclgevf_mbx.o hns3vf/hclgevf_devlink.o hns3vf/hclgevf_regs.o \
+ hns3_common/hclge_comm_cmd.o hns3_common/hclge_comm_rss.o hns3_common/hclge_comm_tqp_stats.o
+
+ obj-$(CONFIG_HNS3_HCLGE) += hclge.o
+-hclge-objs = hns3pf/hclge_main.o hns3pf/hclge_mdio.o hns3pf/hclge_tm.o \
++hclge-objs = hns3pf/hclge_main.o hns3pf/hclge_mdio.o hns3pf/hclge_tm.o hns3pf/hclge_regs.o \
+ hns3pf/hclge_mbx.o hns3pf/hclge_err.o hns3pf/hclge_debugfs.o hns3pf/hclge_ptp.o hns3pf/hclge_devlink.o \
+ hns3_common/hclge_comm_cmd.o hns3_common/hclge_comm_rss.o hns3_common/hclge_comm_tqp_stats.o
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c
+index 0fb2eaee3e8a0..f01a7a9ee02ca 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c
+@@ -7,6 +7,7 @@
+ #include "hclge_debugfs.h"
+ #include "hclge_err.h"
+ #include "hclge_main.h"
++#include "hclge_regs.h"
+ #include "hclge_tm.h"
+ #include "hnae3.h"
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+index 0876890798ba4..cd41e7cb65306 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+@@ -20,6 +20,7 @@
+ #include "hclge_main.h"
+ #include "hclge_mbx.h"
+ #include "hclge_mdio.h"
++#include "hclge_regs.h"
+ #include "hclge_tm.h"
+ #include "hclge_err.h"
+ #include "hnae3.h"
+@@ -40,20 +41,6 @@
+ #define HCLGE_PF_RESET_SYNC_TIME 20
+ #define HCLGE_PF_RESET_SYNC_CNT 1500
+
+-/* Get DFX BD number offset */
+-#define HCLGE_DFX_BIOS_BD_OFFSET 1
+-#define HCLGE_DFX_SSU_0_BD_OFFSET 2
+-#define HCLGE_DFX_SSU_1_BD_OFFSET 3
+-#define HCLGE_DFX_IGU_BD_OFFSET 4
+-#define HCLGE_DFX_RPU_0_BD_OFFSET 5
+-#define HCLGE_DFX_RPU_1_BD_OFFSET 6
+-#define HCLGE_DFX_NCSI_BD_OFFSET 7
+-#define HCLGE_DFX_RTC_BD_OFFSET 8
+-#define HCLGE_DFX_PPP_BD_OFFSET 9
+-#define HCLGE_DFX_RCB_BD_OFFSET 10
+-#define HCLGE_DFX_TQP_BD_OFFSET 11
+-#define HCLGE_DFX_SSU_2_BD_OFFSET 12
+-
+ #define HCLGE_LINK_STATUS_MS 10
+
+ static int hclge_set_mac_mtu(struct hclge_dev *hdev, int new_mps);
+@@ -94,62 +81,6 @@ static const struct pci_device_id ae_algo_pci_tbl[] = {
+
+ MODULE_DEVICE_TABLE(pci, ae_algo_pci_tbl);
+
+-static const u32 cmdq_reg_addr_list[] = {HCLGE_COMM_NIC_CSQ_BASEADDR_L_REG,
+- HCLGE_COMM_NIC_CSQ_BASEADDR_H_REG,
+- HCLGE_COMM_NIC_CSQ_DEPTH_REG,
+- HCLGE_COMM_NIC_CSQ_TAIL_REG,
+- HCLGE_COMM_NIC_CSQ_HEAD_REG,
+- HCLGE_COMM_NIC_CRQ_BASEADDR_L_REG,
+- HCLGE_COMM_NIC_CRQ_BASEADDR_H_REG,
+- HCLGE_COMM_NIC_CRQ_DEPTH_REG,
+- HCLGE_COMM_NIC_CRQ_TAIL_REG,
+- HCLGE_COMM_NIC_CRQ_HEAD_REG,
+- HCLGE_COMM_VECTOR0_CMDQ_SRC_REG,
+- HCLGE_COMM_CMDQ_INTR_STS_REG,
+- HCLGE_COMM_CMDQ_INTR_EN_REG,
+- HCLGE_COMM_CMDQ_INTR_GEN_REG};
+-
+-static const u32 common_reg_addr_list[] = {HCLGE_MISC_VECTOR_REG_BASE,
+- HCLGE_PF_OTHER_INT_REG,
+- HCLGE_MISC_RESET_STS_REG,
+- HCLGE_MISC_VECTOR_INT_STS,
+- HCLGE_GLOBAL_RESET_REG,
+- HCLGE_FUN_RST_ING,
+- HCLGE_GRO_EN_REG};
+-
+-static const u32 ring_reg_addr_list[] = {HCLGE_RING_RX_ADDR_L_REG,
+- HCLGE_RING_RX_ADDR_H_REG,
+- HCLGE_RING_RX_BD_NUM_REG,
+- HCLGE_RING_RX_BD_LENGTH_REG,
+- HCLGE_RING_RX_MERGE_EN_REG,
+- HCLGE_RING_RX_TAIL_REG,
+- HCLGE_RING_RX_HEAD_REG,
+- HCLGE_RING_RX_FBD_NUM_REG,
+- HCLGE_RING_RX_OFFSET_REG,
+- HCLGE_RING_RX_FBD_OFFSET_REG,
+- HCLGE_RING_RX_STASH_REG,
+- HCLGE_RING_RX_BD_ERR_REG,
+- HCLGE_RING_TX_ADDR_L_REG,
+- HCLGE_RING_TX_ADDR_H_REG,
+- HCLGE_RING_TX_BD_NUM_REG,
+- HCLGE_RING_TX_PRIORITY_REG,
+- HCLGE_RING_TX_TC_REG,
+- HCLGE_RING_TX_MERGE_EN_REG,
+- HCLGE_RING_TX_TAIL_REG,
+- HCLGE_RING_TX_HEAD_REG,
+- HCLGE_RING_TX_FBD_NUM_REG,
+- HCLGE_RING_TX_OFFSET_REG,
+- HCLGE_RING_TX_EBD_NUM_REG,
+- HCLGE_RING_TX_EBD_OFFSET_REG,
+- HCLGE_RING_TX_BD_ERR_REG,
+- HCLGE_RING_EN_REG};
+-
+-static const u32 tqp_intr_reg_addr_list[] = {HCLGE_TQP_INTR_CTRL_REG,
+- HCLGE_TQP_INTR_GL0_REG,
+- HCLGE_TQP_INTR_GL1_REG,
+- HCLGE_TQP_INTR_GL2_REG,
+- HCLGE_TQP_INTR_RL_REG};
+-
+ static const char hns3_nic_test_strs[][ETH_GSTRING_LEN] = {
+ "External Loopback test",
+ "App Loopback test",
+@@ -375,36 +306,6 @@ static const struct hclge_mac_mgr_tbl_entry_cmd hclge_mgr_table[] = {
+ },
+ };
+
+-static const u32 hclge_dfx_bd_offset_list[] = {
+- HCLGE_DFX_BIOS_BD_OFFSET,
+- HCLGE_DFX_SSU_0_BD_OFFSET,
+- HCLGE_DFX_SSU_1_BD_OFFSET,
+- HCLGE_DFX_IGU_BD_OFFSET,
+- HCLGE_DFX_RPU_0_BD_OFFSET,
+- HCLGE_DFX_RPU_1_BD_OFFSET,
+- HCLGE_DFX_NCSI_BD_OFFSET,
+- HCLGE_DFX_RTC_BD_OFFSET,
+- HCLGE_DFX_PPP_BD_OFFSET,
+- HCLGE_DFX_RCB_BD_OFFSET,
+- HCLGE_DFX_TQP_BD_OFFSET,
+- HCLGE_DFX_SSU_2_BD_OFFSET
+-};
+-
+-static const enum hclge_opcode_type hclge_dfx_reg_opcode_list[] = {
+- HCLGE_OPC_DFX_BIOS_COMMON_REG,
+- HCLGE_OPC_DFX_SSU_REG_0,
+- HCLGE_OPC_DFX_SSU_REG_1,
+- HCLGE_OPC_DFX_IGU_EGU_REG,
+- HCLGE_OPC_DFX_RPU_REG_0,
+- HCLGE_OPC_DFX_RPU_REG_1,
+- HCLGE_OPC_DFX_NCSI_REG,
+- HCLGE_OPC_DFX_RTC_REG,
+- HCLGE_OPC_DFX_PPP_REG,
+- HCLGE_OPC_DFX_RCB_REG,
+- HCLGE_OPC_DFX_TQP_REG,
+- HCLGE_OPC_DFX_SSU_REG_2
+-};
+-
+ static const struct key_info meta_data_key_info[] = {
+ { PACKET_TYPE_ID, 6 },
+ { IP_FRAGEMENT, 1 },
+@@ -12392,463 +12293,6 @@ static int hclge_set_channels(struct hnae3_handle *handle, u32 new_tqps_num,
+ return ret;
+ }
+
+-static int hclge_get_regs_num(struct hclge_dev *hdev, u32 *regs_num_32_bit,
+- u32 *regs_num_64_bit)
+-{
+- struct hclge_desc desc;
+- u32 total_num;
+- int ret;
+-
+- hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_QUERY_REG_NUM, true);
+- ret = hclge_cmd_send(&hdev->hw, &desc, 1);
+- if (ret) {
+- dev_err(&hdev->pdev->dev,
+- "Query register number cmd failed, ret = %d.\n", ret);
+- return ret;
+- }
+-
+- *regs_num_32_bit = le32_to_cpu(desc.data[0]);
+- *regs_num_64_bit = le32_to_cpu(desc.data[1]);
+-
+- total_num = *regs_num_32_bit + *regs_num_64_bit;
+- if (!total_num)
+- return -EINVAL;
+-
+- return 0;
+-}
+-
+-static int hclge_get_32_bit_regs(struct hclge_dev *hdev, u32 regs_num,
+- void *data)
+-{
+-#define HCLGE_32_BIT_REG_RTN_DATANUM 8
+-#define HCLGE_32_BIT_DESC_NODATA_LEN 2
+-
+- struct hclge_desc *desc;
+- u32 *reg_val = data;
+- __le32 *desc_data;
+- int nodata_num;
+- int cmd_num;
+- int i, k, n;
+- int ret;
+-
+- if (regs_num == 0)
+- return 0;
+-
+- nodata_num = HCLGE_32_BIT_DESC_NODATA_LEN;
+- cmd_num = DIV_ROUND_UP(regs_num + nodata_num,
+- HCLGE_32_BIT_REG_RTN_DATANUM);
+- desc = kcalloc(cmd_num, sizeof(struct hclge_desc), GFP_KERNEL);
+- if (!desc)
+- return -ENOMEM;
+-
+- hclge_cmd_setup_basic_desc(&desc[0], HCLGE_OPC_QUERY_32_BIT_REG, true);
+- ret = hclge_cmd_send(&hdev->hw, desc, cmd_num);
+- if (ret) {
+- dev_err(&hdev->pdev->dev,
+- "Query 32 bit register cmd failed, ret = %d.\n", ret);
+- kfree(desc);
+- return ret;
+- }
+-
+- for (i = 0; i < cmd_num; i++) {
+- if (i == 0) {
+- desc_data = (__le32 *)(&desc[i].data[0]);
+- n = HCLGE_32_BIT_REG_RTN_DATANUM - nodata_num;
+- } else {
+- desc_data = (__le32 *)(&desc[i]);
+- n = HCLGE_32_BIT_REG_RTN_DATANUM;
+- }
+- for (k = 0; k < n; k++) {
+- *reg_val++ = le32_to_cpu(*desc_data++);
+-
+- regs_num--;
+- if (!regs_num)
+- break;
+- }
+- }
+-
+- kfree(desc);
+- return 0;
+-}
+-
+-static int hclge_get_64_bit_regs(struct hclge_dev *hdev, u32 regs_num,
+- void *data)
+-{
+-#define HCLGE_64_BIT_REG_RTN_DATANUM 4
+-#define HCLGE_64_BIT_DESC_NODATA_LEN 1
+-
+- struct hclge_desc *desc;
+- u64 *reg_val = data;
+- __le64 *desc_data;
+- int nodata_len;
+- int cmd_num;
+- int i, k, n;
+- int ret;
+-
+- if (regs_num == 0)
+- return 0;
+-
+- nodata_len = HCLGE_64_BIT_DESC_NODATA_LEN;
+- cmd_num = DIV_ROUND_UP(regs_num + nodata_len,
+- HCLGE_64_BIT_REG_RTN_DATANUM);
+- desc = kcalloc(cmd_num, sizeof(struct hclge_desc), GFP_KERNEL);
+- if (!desc)
+- return -ENOMEM;
+-
+- hclge_cmd_setup_basic_desc(&desc[0], HCLGE_OPC_QUERY_64_BIT_REG, true);
+- ret = hclge_cmd_send(&hdev->hw, desc, cmd_num);
+- if (ret) {
+- dev_err(&hdev->pdev->dev,
+- "Query 64 bit register cmd failed, ret = %d.\n", ret);
+- kfree(desc);
+- return ret;
+- }
+-
+- for (i = 0; i < cmd_num; i++) {
+- if (i == 0) {
+- desc_data = (__le64 *)(&desc[i].data[0]);
+- n = HCLGE_64_BIT_REG_RTN_DATANUM - nodata_len;
+- } else {
+- desc_data = (__le64 *)(&desc[i]);
+- n = HCLGE_64_BIT_REG_RTN_DATANUM;
+- }
+- for (k = 0; k < n; k++) {
+- *reg_val++ = le64_to_cpu(*desc_data++);
+-
+- regs_num--;
+- if (!regs_num)
+- break;
+- }
+- }
+-
+- kfree(desc);
+- return 0;
+-}
+-
+-#define MAX_SEPARATE_NUM 4
+-#define SEPARATOR_VALUE 0xFDFCFBFA
+-#define REG_NUM_PER_LINE 4
+-#define REG_LEN_PER_LINE (REG_NUM_PER_LINE * sizeof(u32))
+-#define REG_SEPARATOR_LINE 1
+-#define REG_NUM_REMAIN_MASK 3
+-
+-int hclge_query_bd_num_cmd_send(struct hclge_dev *hdev, struct hclge_desc *desc)
+-{
+- int i;
+-
+- /* initialize command BD except the last one */
+- for (i = 0; i < HCLGE_GET_DFX_REG_TYPE_CNT - 1; i++) {
+- hclge_cmd_setup_basic_desc(&desc[i], HCLGE_OPC_DFX_BD_NUM,
+- true);
+- desc[i].flag |= cpu_to_le16(HCLGE_COMM_CMD_FLAG_NEXT);
+- }
+-
+- /* initialize the last command BD */
+- hclge_cmd_setup_basic_desc(&desc[i], HCLGE_OPC_DFX_BD_NUM, true);
+-
+- return hclge_cmd_send(&hdev->hw, desc, HCLGE_GET_DFX_REG_TYPE_CNT);
+-}
+-
+-static int hclge_get_dfx_reg_bd_num(struct hclge_dev *hdev,
+- int *bd_num_list,
+- u32 type_num)
+-{
+- u32 entries_per_desc, desc_index, index, offset, i;
+- struct hclge_desc desc[HCLGE_GET_DFX_REG_TYPE_CNT];
+- int ret;
+-
+- ret = hclge_query_bd_num_cmd_send(hdev, desc);
+- if (ret) {
+- dev_err(&hdev->pdev->dev,
+- "Get dfx bd num fail, status is %d.\n", ret);
+- return ret;
+- }
+-
+- entries_per_desc = ARRAY_SIZE(desc[0].data);
+- for (i = 0; i < type_num; i++) {
+- offset = hclge_dfx_bd_offset_list[i];
+- index = offset % entries_per_desc;
+- desc_index = offset / entries_per_desc;
+- bd_num_list[i] = le32_to_cpu(desc[desc_index].data[index]);
+- }
+-
+- return ret;
+-}
+-
+-static int hclge_dfx_reg_cmd_send(struct hclge_dev *hdev,
+- struct hclge_desc *desc_src, int bd_num,
+- enum hclge_opcode_type cmd)
+-{
+- struct hclge_desc *desc = desc_src;
+- int i, ret;
+-
+- hclge_cmd_setup_basic_desc(desc, cmd, true);
+- for (i = 0; i < bd_num - 1; i++) {
+- desc->flag |= cpu_to_le16(HCLGE_COMM_CMD_FLAG_NEXT);
+- desc++;
+- hclge_cmd_setup_basic_desc(desc, cmd, true);
+- }
+-
+- desc = desc_src;
+- ret = hclge_cmd_send(&hdev->hw, desc, bd_num);
+- if (ret)
+- dev_err(&hdev->pdev->dev,
+- "Query dfx reg cmd(0x%x) send fail, status is %d.\n",
+- cmd, ret);
+-
+- return ret;
+-}
+-
+-static int hclge_dfx_reg_fetch_data(struct hclge_desc *desc_src, int bd_num,
+- void *data)
+-{
+- int entries_per_desc, reg_num, separator_num, desc_index, index, i;
+- struct hclge_desc *desc = desc_src;
+- u32 *reg = data;
+-
+- entries_per_desc = ARRAY_SIZE(desc->data);
+- reg_num = entries_per_desc * bd_num;
+- separator_num = REG_NUM_PER_LINE - (reg_num & REG_NUM_REMAIN_MASK);
+- for (i = 0; i < reg_num; i++) {
+- index = i % entries_per_desc;
+- desc_index = i / entries_per_desc;
+- *reg++ = le32_to_cpu(desc[desc_index].data[index]);
+- }
+- for (i = 0; i < separator_num; i++)
+- *reg++ = SEPARATOR_VALUE;
+-
+- return reg_num + separator_num;
+-}
+-
+-static int hclge_get_dfx_reg_len(struct hclge_dev *hdev, int *len)
+-{
+- u32 dfx_reg_type_num = ARRAY_SIZE(hclge_dfx_bd_offset_list);
+- int data_len_per_desc, bd_num, i;
+- int *bd_num_list;
+- u32 data_len;
+- int ret;
+-
+- bd_num_list = kcalloc(dfx_reg_type_num, sizeof(int), GFP_KERNEL);
+- if (!bd_num_list)
+- return -ENOMEM;
+-
+- ret = hclge_get_dfx_reg_bd_num(hdev, bd_num_list, dfx_reg_type_num);
+- if (ret) {
+- dev_err(&hdev->pdev->dev,
+- "Get dfx reg bd num fail, status is %d.\n", ret);
+- goto out;
+- }
+-
+- data_len_per_desc = sizeof_field(struct hclge_desc, data);
+- *len = 0;
+- for (i = 0; i < dfx_reg_type_num; i++) {
+- bd_num = bd_num_list[i];
+- data_len = data_len_per_desc * bd_num;
+- *len += (data_len / REG_LEN_PER_LINE + 1) * REG_LEN_PER_LINE;
+- }
+-
+-out:
+- kfree(bd_num_list);
+- return ret;
+-}
+-
+-static int hclge_get_dfx_reg(struct hclge_dev *hdev, void *data)
+-{
+- u32 dfx_reg_type_num = ARRAY_SIZE(hclge_dfx_bd_offset_list);
+- int bd_num, bd_num_max, buf_len, i;
+- struct hclge_desc *desc_src;
+- int *bd_num_list;
+- u32 *reg = data;
+- int ret;
+-
+- bd_num_list = kcalloc(dfx_reg_type_num, sizeof(int), GFP_KERNEL);
+- if (!bd_num_list)
+- return -ENOMEM;
+-
+- ret = hclge_get_dfx_reg_bd_num(hdev, bd_num_list, dfx_reg_type_num);
+- if (ret) {
+- dev_err(&hdev->pdev->dev,
+- "Get dfx reg bd num fail, status is %d.\n", ret);
+- goto out;
+- }
+-
+- bd_num_max = bd_num_list[0];
+- for (i = 1; i < dfx_reg_type_num; i++)
+- bd_num_max = max_t(int, bd_num_max, bd_num_list[i]);
+-
+- buf_len = sizeof(*desc_src) * bd_num_max;
+- desc_src = kzalloc(buf_len, GFP_KERNEL);
+- if (!desc_src) {
+- ret = -ENOMEM;
+- goto out;
+- }
+-
+- for (i = 0; i < dfx_reg_type_num; i++) {
+- bd_num = bd_num_list[i];
+- ret = hclge_dfx_reg_cmd_send(hdev, desc_src, bd_num,
+- hclge_dfx_reg_opcode_list[i]);
+- if (ret) {
+- dev_err(&hdev->pdev->dev,
+- "Get dfx reg fail, status is %d.\n", ret);
+- break;
+- }
+-
+- reg += hclge_dfx_reg_fetch_data(desc_src, bd_num, reg);
+- }
+-
+- kfree(desc_src);
+-out:
+- kfree(bd_num_list);
+- return ret;
+-}
+-
+-static int hclge_fetch_pf_reg(struct hclge_dev *hdev, void *data,
+- struct hnae3_knic_private_info *kinfo)
+-{
+-#define HCLGE_RING_REG_OFFSET 0x200
+-#define HCLGE_RING_INT_REG_OFFSET 0x4
+-
+- int i, j, reg_num, separator_num;
+- int data_num_sum;
+- u32 *reg = data;
+-
+- /* fetching per-PF registers valus from PF PCIe register space */
+- reg_num = ARRAY_SIZE(cmdq_reg_addr_list);
+- separator_num = MAX_SEPARATE_NUM - (reg_num & REG_NUM_REMAIN_MASK);
+- for (i = 0; i < reg_num; i++)
+- *reg++ = hclge_read_dev(&hdev->hw, cmdq_reg_addr_list[i]);
+- for (i = 0; i < separator_num; i++)
+- *reg++ = SEPARATOR_VALUE;
+- data_num_sum = reg_num + separator_num;
+-
+- reg_num = ARRAY_SIZE(common_reg_addr_list);
+- separator_num = MAX_SEPARATE_NUM - (reg_num & REG_NUM_REMAIN_MASK);
+- for (i = 0; i < reg_num; i++)
+- *reg++ = hclge_read_dev(&hdev->hw, common_reg_addr_list[i]);
+- for (i = 0; i < separator_num; i++)
+- *reg++ = SEPARATOR_VALUE;
+- data_num_sum += reg_num + separator_num;
+-
+- reg_num = ARRAY_SIZE(ring_reg_addr_list);
+- separator_num = MAX_SEPARATE_NUM - (reg_num & REG_NUM_REMAIN_MASK);
+- for (j = 0; j < kinfo->num_tqps; j++) {
+- for (i = 0; i < reg_num; i++)
+- *reg++ = hclge_read_dev(&hdev->hw,
+- ring_reg_addr_list[i] +
+- HCLGE_RING_REG_OFFSET * j);
+- for (i = 0; i < separator_num; i++)
+- *reg++ = SEPARATOR_VALUE;
+- }
+- data_num_sum += (reg_num + separator_num) * kinfo->num_tqps;
+-
+- reg_num = ARRAY_SIZE(tqp_intr_reg_addr_list);
+- separator_num = MAX_SEPARATE_NUM - (reg_num & REG_NUM_REMAIN_MASK);
+- for (j = 0; j < hdev->num_msi_used - 1; j++) {
+- for (i = 0; i < reg_num; i++)
+- *reg++ = hclge_read_dev(&hdev->hw,
+- tqp_intr_reg_addr_list[i] +
+- HCLGE_RING_INT_REG_OFFSET * j);
+- for (i = 0; i < separator_num; i++)
+- *reg++ = SEPARATOR_VALUE;
+- }
+- data_num_sum += (reg_num + separator_num) * (hdev->num_msi_used - 1);
+-
+- return data_num_sum;
+-}
+-
+-static int hclge_get_regs_len(struct hnae3_handle *handle)
+-{
+- int cmdq_lines, common_lines, ring_lines, tqp_intr_lines;
+- struct hnae3_knic_private_info *kinfo = &handle->kinfo;
+- struct hclge_vport *vport = hclge_get_vport(handle);
+- struct hclge_dev *hdev = vport->back;
+- int regs_num_32_bit, regs_num_64_bit, dfx_regs_len;
+- int regs_lines_32_bit, regs_lines_64_bit;
+- int ret;
+-
+- ret = hclge_get_regs_num(hdev, ®s_num_32_bit, ®s_num_64_bit);
+- if (ret) {
+- dev_err(&hdev->pdev->dev,
+- "Get register number failed, ret = %d.\n", ret);
+- return ret;
+- }
+-
+- ret = hclge_get_dfx_reg_len(hdev, &dfx_regs_len);
+- if (ret) {
+- dev_err(&hdev->pdev->dev,
+- "Get dfx reg len failed, ret = %d.\n", ret);
+- return ret;
+- }
+-
+- cmdq_lines = sizeof(cmdq_reg_addr_list) / REG_LEN_PER_LINE +
+- REG_SEPARATOR_LINE;
+- common_lines = sizeof(common_reg_addr_list) / REG_LEN_PER_LINE +
+- REG_SEPARATOR_LINE;
+- ring_lines = sizeof(ring_reg_addr_list) / REG_LEN_PER_LINE +
+- REG_SEPARATOR_LINE;
+- tqp_intr_lines = sizeof(tqp_intr_reg_addr_list) / REG_LEN_PER_LINE +
+- REG_SEPARATOR_LINE;
+- regs_lines_32_bit = regs_num_32_bit * sizeof(u32) / REG_LEN_PER_LINE +
+- REG_SEPARATOR_LINE;
+- regs_lines_64_bit = regs_num_64_bit * sizeof(u64) / REG_LEN_PER_LINE +
+- REG_SEPARATOR_LINE;
+-
+- return (cmdq_lines + common_lines + ring_lines * kinfo->num_tqps +
+- tqp_intr_lines * (hdev->num_msi_used - 1) + regs_lines_32_bit +
+- regs_lines_64_bit) * REG_LEN_PER_LINE + dfx_regs_len;
+-}
+-
+-static void hclge_get_regs(struct hnae3_handle *handle, u32 *version,
+- void *data)
+-{
+- struct hnae3_knic_private_info *kinfo = &handle->kinfo;
+- struct hclge_vport *vport = hclge_get_vport(handle);
+- struct hclge_dev *hdev = vport->back;
+- u32 regs_num_32_bit, regs_num_64_bit;
+- int i, reg_num, separator_num, ret;
+- u32 *reg = data;
+-
+- *version = hdev->fw_version;
+-
+- ret = hclge_get_regs_num(hdev, ®s_num_32_bit, ®s_num_64_bit);
+- if (ret) {
+- dev_err(&hdev->pdev->dev,
+- "Get register number failed, ret = %d.\n", ret);
+- return;
+- }
+-
+- reg += hclge_fetch_pf_reg(hdev, reg, kinfo);
+-
+- ret = hclge_get_32_bit_regs(hdev, regs_num_32_bit, reg);
+- if (ret) {
+- dev_err(&hdev->pdev->dev,
+- "Get 32 bit register failed, ret = %d.\n", ret);
+- return;
+- }
+- reg_num = regs_num_32_bit;
+- reg += reg_num;
+- separator_num = MAX_SEPARATE_NUM - (reg_num & REG_NUM_REMAIN_MASK);
+- for (i = 0; i < separator_num; i++)
+- *reg++ = SEPARATOR_VALUE;
+-
+- ret = hclge_get_64_bit_regs(hdev, regs_num_64_bit, reg);
+- if (ret) {
+- dev_err(&hdev->pdev->dev,
+- "Get 64 bit register failed, ret = %d.\n", ret);
+- return;
+- }
+- reg_num = regs_num_64_bit * 2;
+- reg += reg_num;
+- separator_num = MAX_SEPARATE_NUM - (reg_num & REG_NUM_REMAIN_MASK);
+- for (i = 0; i < separator_num; i++)
+- *reg++ = SEPARATOR_VALUE;
+-
+- ret = hclge_get_dfx_reg(hdev, reg);
+- if (ret)
+- dev_err(&hdev->pdev->dev,
+- "Get dfx register failed, ret = %d.\n", ret);
+-}
+-
+ static int hclge_set_led_status(struct hclge_dev *hdev, u8 locate_led_status)
+ {
+ struct hclge_set_led_state_cmd *req;
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
+index 81aa6b0facf5a..e292a1253dd72 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
+@@ -1147,8 +1147,6 @@ int hclge_push_vf_port_base_vlan_info(struct hclge_vport *vport, u8 vfid,
+ u16 state,
+ struct hclge_vlan_info *vlan_info);
+ void hclge_task_schedule(struct hclge_dev *hdev, unsigned long delay_time);
+-int hclge_query_bd_num_cmd_send(struct hclge_dev *hdev,
+- struct hclge_desc *desc);
+ void hclge_report_hw_error(struct hclge_dev *hdev,
+ enum hnae3_hw_error_type type);
+ void hclge_inform_vf_promisc_info(struct hclge_vport *vport);
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c
+new file mode 100644
+index 0000000000000..e566443948756
+--- /dev/null
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c
+@@ -0,0 +1,567 @@
++// SPDX-License-Identifier: GPL-2.0+
++// Copyright (c) 2023 Hisilicon Limited.
++
++#include "hclge_cmd.h"
++#include "hclge_main.h"
++#include "hclge_regs.h"
++#include "hnae3.h"
++
++static const u32 cmdq_reg_addr_list[] = {HCLGE_COMM_NIC_CSQ_BASEADDR_L_REG,
++ HCLGE_COMM_NIC_CSQ_BASEADDR_H_REG,
++ HCLGE_COMM_NIC_CSQ_DEPTH_REG,
++ HCLGE_COMM_NIC_CSQ_TAIL_REG,
++ HCLGE_COMM_NIC_CSQ_HEAD_REG,
++ HCLGE_COMM_NIC_CRQ_BASEADDR_L_REG,
++ HCLGE_COMM_NIC_CRQ_BASEADDR_H_REG,
++ HCLGE_COMM_NIC_CRQ_DEPTH_REG,
++ HCLGE_COMM_NIC_CRQ_TAIL_REG,
++ HCLGE_COMM_NIC_CRQ_HEAD_REG,
++ HCLGE_COMM_VECTOR0_CMDQ_SRC_REG,
++ HCLGE_COMM_CMDQ_INTR_STS_REG,
++ HCLGE_COMM_CMDQ_INTR_EN_REG,
++ HCLGE_COMM_CMDQ_INTR_GEN_REG};
++
++static const u32 common_reg_addr_list[] = {HCLGE_MISC_VECTOR_REG_BASE,
++ HCLGE_PF_OTHER_INT_REG,
++ HCLGE_MISC_RESET_STS_REG,
++ HCLGE_MISC_VECTOR_INT_STS,
++ HCLGE_GLOBAL_RESET_REG,
++ HCLGE_FUN_RST_ING,
++ HCLGE_GRO_EN_REG};
++
++static const u32 ring_reg_addr_list[] = {HCLGE_RING_RX_ADDR_L_REG,
++ HCLGE_RING_RX_ADDR_H_REG,
++ HCLGE_RING_RX_BD_NUM_REG,
++ HCLGE_RING_RX_BD_LENGTH_REG,
++ HCLGE_RING_RX_MERGE_EN_REG,
++ HCLGE_RING_RX_TAIL_REG,
++ HCLGE_RING_RX_HEAD_REG,
++ HCLGE_RING_RX_FBD_NUM_REG,
++ HCLGE_RING_RX_OFFSET_REG,
++ HCLGE_RING_RX_FBD_OFFSET_REG,
++ HCLGE_RING_RX_STASH_REG,
++ HCLGE_RING_RX_BD_ERR_REG,
++ HCLGE_RING_TX_ADDR_L_REG,
++ HCLGE_RING_TX_ADDR_H_REG,
++ HCLGE_RING_TX_BD_NUM_REG,
++ HCLGE_RING_TX_PRIORITY_REG,
++ HCLGE_RING_TX_TC_REG,
++ HCLGE_RING_TX_MERGE_EN_REG,
++ HCLGE_RING_TX_TAIL_REG,
++ HCLGE_RING_TX_HEAD_REG,
++ HCLGE_RING_TX_FBD_NUM_REG,
++ HCLGE_RING_TX_OFFSET_REG,
++ HCLGE_RING_TX_EBD_NUM_REG,
++ HCLGE_RING_TX_EBD_OFFSET_REG,
++ HCLGE_RING_TX_BD_ERR_REG,
++ HCLGE_RING_EN_REG};
++
++static const u32 tqp_intr_reg_addr_list[] = {HCLGE_TQP_INTR_CTRL_REG,
++ HCLGE_TQP_INTR_GL0_REG,
++ HCLGE_TQP_INTR_GL1_REG,
++ HCLGE_TQP_INTR_GL2_REG,
++ HCLGE_TQP_INTR_RL_REG};
++
++/* Get DFX BD number offset */
++#define HCLGE_DFX_BIOS_BD_OFFSET 1
++#define HCLGE_DFX_SSU_0_BD_OFFSET 2
++#define HCLGE_DFX_SSU_1_BD_OFFSET 3
++#define HCLGE_DFX_IGU_BD_OFFSET 4
++#define HCLGE_DFX_RPU_0_BD_OFFSET 5
++#define HCLGE_DFX_RPU_1_BD_OFFSET 6
++#define HCLGE_DFX_NCSI_BD_OFFSET 7
++#define HCLGE_DFX_RTC_BD_OFFSET 8
++#define HCLGE_DFX_PPP_BD_OFFSET 9
++#define HCLGE_DFX_RCB_BD_OFFSET 10
++#define HCLGE_DFX_TQP_BD_OFFSET 11
++#define HCLGE_DFX_SSU_2_BD_OFFSET 12
++
++static const u32 hclge_dfx_bd_offset_list[] = {
++ HCLGE_DFX_BIOS_BD_OFFSET,
++ HCLGE_DFX_SSU_0_BD_OFFSET,
++ HCLGE_DFX_SSU_1_BD_OFFSET,
++ HCLGE_DFX_IGU_BD_OFFSET,
++ HCLGE_DFX_RPU_0_BD_OFFSET,
++ HCLGE_DFX_RPU_1_BD_OFFSET,
++ HCLGE_DFX_NCSI_BD_OFFSET,
++ HCLGE_DFX_RTC_BD_OFFSET,
++ HCLGE_DFX_PPP_BD_OFFSET,
++ HCLGE_DFX_RCB_BD_OFFSET,
++ HCLGE_DFX_TQP_BD_OFFSET,
++ HCLGE_DFX_SSU_2_BD_OFFSET
++};
++
++static const enum hclge_opcode_type hclge_dfx_reg_opcode_list[] = {
++ HCLGE_OPC_DFX_BIOS_COMMON_REG,
++ HCLGE_OPC_DFX_SSU_REG_0,
++ HCLGE_OPC_DFX_SSU_REG_1,
++ HCLGE_OPC_DFX_IGU_EGU_REG,
++ HCLGE_OPC_DFX_RPU_REG_0,
++ HCLGE_OPC_DFX_RPU_REG_1,
++ HCLGE_OPC_DFX_NCSI_REG,
++ HCLGE_OPC_DFX_RTC_REG,
++ HCLGE_OPC_DFX_PPP_REG,
++ HCLGE_OPC_DFX_RCB_REG,
++ HCLGE_OPC_DFX_TQP_REG,
++ HCLGE_OPC_DFX_SSU_REG_2
++};
++
++#define MAX_SEPARATE_NUM 4
++#define SEPARATOR_VALUE 0xFDFCFBFA
++#define REG_NUM_PER_LINE 4
++#define REG_LEN_PER_LINE (REG_NUM_PER_LINE * sizeof(u32))
++#define REG_SEPARATOR_LINE 1
++#define REG_NUM_REMAIN_MASK 3
++
++static int hclge_get_32_bit_regs(struct hclge_dev *hdev, u32 regs_num,
++ void *data)
++{
++#define HCLGE_32_BIT_REG_RTN_DATANUM 8
++#define HCLGE_32_BIT_DESC_NODATA_LEN 2
++
++ struct hclge_desc *desc;
++ u32 *reg_val = data;
++ __le32 *desc_data;
++ int nodata_num;
++ int cmd_num;
++ int i, k, n;
++ int ret;
++
++ if (regs_num == 0)
++ return 0;
++
++ nodata_num = HCLGE_32_BIT_DESC_NODATA_LEN;
++ cmd_num = DIV_ROUND_UP(regs_num + nodata_num,
++ HCLGE_32_BIT_REG_RTN_DATANUM);
++ desc = kcalloc(cmd_num, sizeof(struct hclge_desc), GFP_KERNEL);
++ if (!desc)
++ return -ENOMEM;
++
++ hclge_cmd_setup_basic_desc(&desc[0], HCLGE_OPC_QUERY_32_BIT_REG, true);
++ ret = hclge_cmd_send(&hdev->hw, desc, cmd_num);
++ if (ret) {
++ dev_err(&hdev->pdev->dev,
++ "Query 32 bit register cmd failed, ret = %d.\n", ret);
++ kfree(desc);
++ return ret;
++ }
++
++ for (i = 0; i < cmd_num; i++) {
++ if (i == 0) {
++ desc_data = (__le32 *)(&desc[i].data[0]);
++ n = HCLGE_32_BIT_REG_RTN_DATANUM - nodata_num;
++ } else {
++ desc_data = (__le32 *)(&desc[i]);
++ n = HCLGE_32_BIT_REG_RTN_DATANUM;
++ }
++ for (k = 0; k < n; k++) {
++ *reg_val++ = le32_to_cpu(*desc_data++);
++
++ regs_num--;
++ if (!regs_num)
++ break;
++ }
++ }
++
++ kfree(desc);
++ return 0;
++}
++
++static int hclge_get_64_bit_regs(struct hclge_dev *hdev, u32 regs_num,
++ void *data)
++{
++#define HCLGE_64_BIT_REG_RTN_DATANUM 4
++#define HCLGE_64_BIT_DESC_NODATA_LEN 1
++
++ struct hclge_desc *desc;
++ u64 *reg_val = data;
++ __le64 *desc_data;
++ int nodata_len;
++ int cmd_num;
++ int i, k, n;
++ int ret;
++
++ if (regs_num == 0)
++ return 0;
++
++ nodata_len = HCLGE_64_BIT_DESC_NODATA_LEN;
++ cmd_num = DIV_ROUND_UP(regs_num + nodata_len,
++ HCLGE_64_BIT_REG_RTN_DATANUM);
++ desc = kcalloc(cmd_num, sizeof(struct hclge_desc), GFP_KERNEL);
++ if (!desc)
++ return -ENOMEM;
++
++ hclge_cmd_setup_basic_desc(&desc[0], HCLGE_OPC_QUERY_64_BIT_REG, true);
++ ret = hclge_cmd_send(&hdev->hw, desc, cmd_num);
++ if (ret) {
++ dev_err(&hdev->pdev->dev,
++ "Query 64 bit register cmd failed, ret = %d.\n", ret);
++ kfree(desc);
++ return ret;
++ }
++
++ for (i = 0; i < cmd_num; i++) {
++ if (i == 0) {
++ desc_data = (__le64 *)(&desc[i].data[0]);
++ n = HCLGE_64_BIT_REG_RTN_DATANUM - nodata_len;
++ } else {
++ desc_data = (__le64 *)(&desc[i]);
++ n = HCLGE_64_BIT_REG_RTN_DATANUM;
++ }
++ for (k = 0; k < n; k++) {
++ *reg_val++ = le64_to_cpu(*desc_data++);
++
++ regs_num--;
++ if (!regs_num)
++ break;
++ }
++ }
++
++ kfree(desc);
++ return 0;
++}
++
++int hclge_query_bd_num_cmd_send(struct hclge_dev *hdev, struct hclge_desc *desc)
++{
++ int i;
++
++ /* initialize command BD except the last one */
++ for (i = 0; i < HCLGE_GET_DFX_REG_TYPE_CNT - 1; i++) {
++ hclge_cmd_setup_basic_desc(&desc[i], HCLGE_OPC_DFX_BD_NUM,
++ true);
++ desc[i].flag |= cpu_to_le16(HCLGE_COMM_CMD_FLAG_NEXT);
++ }
++
++ /* initialize the last command BD */
++ hclge_cmd_setup_basic_desc(&desc[i], HCLGE_OPC_DFX_BD_NUM, true);
++
++ return hclge_cmd_send(&hdev->hw, desc, HCLGE_GET_DFX_REG_TYPE_CNT);
++}
++
++static int hclge_get_dfx_reg_bd_num(struct hclge_dev *hdev,
++ int *bd_num_list,
++ u32 type_num)
++{
++ u32 entries_per_desc, desc_index, index, offset, i;
++ struct hclge_desc desc[HCLGE_GET_DFX_REG_TYPE_CNT];
++ int ret;
++
++ ret = hclge_query_bd_num_cmd_send(hdev, desc);
++ if (ret) {
++ dev_err(&hdev->pdev->dev,
++ "Get dfx bd num fail, status is %d.\n", ret);
++ return ret;
++ }
++
++ entries_per_desc = ARRAY_SIZE(desc[0].data);
++ for (i = 0; i < type_num; i++) {
++ offset = hclge_dfx_bd_offset_list[i];
++ index = offset % entries_per_desc;
++ desc_index = offset / entries_per_desc;
++ bd_num_list[i] = le32_to_cpu(desc[desc_index].data[index]);
++ }
++
++ return ret;
++}
++
++static int hclge_dfx_reg_cmd_send(struct hclge_dev *hdev,
++ struct hclge_desc *desc_src, int bd_num,
++ enum hclge_opcode_type cmd)
++{
++ struct hclge_desc *desc = desc_src;
++ int i, ret;
++
++ hclge_cmd_setup_basic_desc(desc, cmd, true);
++ for (i = 0; i < bd_num - 1; i++) {
++ desc->flag |= cpu_to_le16(HCLGE_COMM_CMD_FLAG_NEXT);
++ desc++;
++ hclge_cmd_setup_basic_desc(desc, cmd, true);
++ }
++
++ desc = desc_src;
++ ret = hclge_cmd_send(&hdev->hw, desc, bd_num);
++ if (ret)
++ dev_err(&hdev->pdev->dev,
++ "Query dfx reg cmd(0x%x) send fail, status is %d.\n",
++ cmd, ret);
++
++ return ret;
++}
++
++static int hclge_dfx_reg_fetch_data(struct hclge_desc *desc_src, int bd_num,
++ void *data)
++{
++ int entries_per_desc, reg_num, separator_num, desc_index, index, i;
++ struct hclge_desc *desc = desc_src;
++ u32 *reg = data;
++
++ entries_per_desc = ARRAY_SIZE(desc->data);
++ reg_num = entries_per_desc * bd_num;
++ separator_num = REG_NUM_PER_LINE - (reg_num & REG_NUM_REMAIN_MASK);
++ for (i = 0; i < reg_num; i++) {
++ index = i % entries_per_desc;
++ desc_index = i / entries_per_desc;
++ *reg++ = le32_to_cpu(desc[desc_index].data[index]);
++ }
++ for (i = 0; i < separator_num; i++)
++ *reg++ = SEPARATOR_VALUE;
++
++ return reg_num + separator_num;
++}
++
++static int hclge_get_dfx_reg_len(struct hclge_dev *hdev, int *len)
++{
++ u32 dfx_reg_type_num = ARRAY_SIZE(hclge_dfx_bd_offset_list);
++ int data_len_per_desc, bd_num;
++ int *bd_num_list;
++ u32 data_len, i;
++ int ret;
++
++ bd_num_list = kcalloc(dfx_reg_type_num, sizeof(int), GFP_KERNEL);
++ if (!bd_num_list)
++ return -ENOMEM;
++
++ ret = hclge_get_dfx_reg_bd_num(hdev, bd_num_list, dfx_reg_type_num);
++ if (ret) {
++ dev_err(&hdev->pdev->dev,
++ "Get dfx reg bd num fail, status is %d.\n", ret);
++ goto out;
++ }
++
++ data_len_per_desc = sizeof_field(struct hclge_desc, data);
++ *len = 0;
++ for (i = 0; i < dfx_reg_type_num; i++) {
++ bd_num = bd_num_list[i];
++ data_len = data_len_per_desc * bd_num;
++ *len += (data_len / REG_LEN_PER_LINE + 1) * REG_LEN_PER_LINE;
++ }
++
++out:
++ kfree(bd_num_list);
++ return ret;
++}
++
++static int hclge_get_dfx_reg(struct hclge_dev *hdev, void *data)
++{
++ u32 dfx_reg_type_num = ARRAY_SIZE(hclge_dfx_bd_offset_list);
++ int bd_num, bd_num_max, buf_len;
++ struct hclge_desc *desc_src;
++ int *bd_num_list;
++ u32 *reg = data;
++ int ret;
++ u32 i;
++
++ bd_num_list = kcalloc(dfx_reg_type_num, sizeof(int), GFP_KERNEL);
++ if (!bd_num_list)
++ return -ENOMEM;
++
++ ret = hclge_get_dfx_reg_bd_num(hdev, bd_num_list, dfx_reg_type_num);
++ if (ret) {
++ dev_err(&hdev->pdev->dev,
++ "Get dfx reg bd num fail, status is %d.\n", ret);
++ goto out;
++ }
++
++ bd_num_max = bd_num_list[0];
++ for (i = 1; i < dfx_reg_type_num; i++)
++ bd_num_max = max_t(int, bd_num_max, bd_num_list[i]);
++
++ buf_len = sizeof(*desc_src) * bd_num_max;
++ desc_src = kzalloc(buf_len, GFP_KERNEL);
++ if (!desc_src) {
++ ret = -ENOMEM;
++ goto out;
++ }
++
++ for (i = 0; i < dfx_reg_type_num; i++) {
++ bd_num = bd_num_list[i];
++ ret = hclge_dfx_reg_cmd_send(hdev, desc_src, bd_num,
++ hclge_dfx_reg_opcode_list[i]);
++ if (ret) {
++ dev_err(&hdev->pdev->dev,
++ "Get dfx reg fail, status is %d.\n", ret);
++ break;
++ }
++
++ reg += hclge_dfx_reg_fetch_data(desc_src, bd_num, reg);
++ }
++
++ kfree(desc_src);
++out:
++ kfree(bd_num_list);
++ return ret;
++}
++
++static int hclge_fetch_pf_reg(struct hclge_dev *hdev, void *data,
++ struct hnae3_knic_private_info *kinfo)
++{
++#define HCLGE_RING_REG_OFFSET 0x200
++#define HCLGE_RING_INT_REG_OFFSET 0x4
++
++ int i, j, reg_num, separator_num;
++ int data_num_sum;
++ u32 *reg = data;
++
++ /* fetching per-PF registers valus from PF PCIe register space */
++ reg_num = ARRAY_SIZE(cmdq_reg_addr_list);
++ separator_num = MAX_SEPARATE_NUM - (reg_num & REG_NUM_REMAIN_MASK);
++ for (i = 0; i < reg_num; i++)
++ *reg++ = hclge_read_dev(&hdev->hw, cmdq_reg_addr_list[i]);
++ for (i = 0; i < separator_num; i++)
++ *reg++ = SEPARATOR_VALUE;
++ data_num_sum = reg_num + separator_num;
++
++ reg_num = ARRAY_SIZE(common_reg_addr_list);
++ separator_num = MAX_SEPARATE_NUM - (reg_num & REG_NUM_REMAIN_MASK);
++ for (i = 0; i < reg_num; i++)
++ *reg++ = hclge_read_dev(&hdev->hw, common_reg_addr_list[i]);
++ for (i = 0; i < separator_num; i++)
++ *reg++ = SEPARATOR_VALUE;
++ data_num_sum += reg_num + separator_num;
++
++ reg_num = ARRAY_SIZE(ring_reg_addr_list);
++ separator_num = MAX_SEPARATE_NUM - (reg_num & REG_NUM_REMAIN_MASK);
++ for (j = 0; j < kinfo->num_tqps; j++) {
++ for (i = 0; i < reg_num; i++)
++ *reg++ = hclge_read_dev(&hdev->hw,
++ ring_reg_addr_list[i] +
++ HCLGE_RING_REG_OFFSET * j);
++ for (i = 0; i < separator_num; i++)
++ *reg++ = SEPARATOR_VALUE;
++ }
++ data_num_sum += (reg_num + separator_num) * kinfo->num_tqps;
++
++ reg_num = ARRAY_SIZE(tqp_intr_reg_addr_list);
++ separator_num = MAX_SEPARATE_NUM - (reg_num & REG_NUM_REMAIN_MASK);
++ for (j = 0; j < hdev->num_msi_used - 1; j++) {
++ for (i = 0; i < reg_num; i++)
++ *reg++ = hclge_read_dev(&hdev->hw,
++ tqp_intr_reg_addr_list[i] +
++ HCLGE_RING_INT_REG_OFFSET * j);
++ for (i = 0; i < separator_num; i++)
++ *reg++ = SEPARATOR_VALUE;
++ }
++ data_num_sum += (reg_num + separator_num) * (hdev->num_msi_used - 1);
++
++ return data_num_sum;
++}
++
++static int hclge_get_regs_num(struct hclge_dev *hdev, u32 *regs_num_32_bit,
++ u32 *regs_num_64_bit)
++{
++ struct hclge_desc desc;
++ u32 total_num;
++ int ret;
++
++ hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_QUERY_REG_NUM, true);
++ ret = hclge_cmd_send(&hdev->hw, &desc, 1);
++ if (ret) {
++ dev_err(&hdev->pdev->dev,
++ "Query register number cmd failed, ret = %d.\n", ret);
++ return ret;
++ }
++
++ *regs_num_32_bit = le32_to_cpu(desc.data[0]);
++ *regs_num_64_bit = le32_to_cpu(desc.data[1]);
++
++ total_num = *regs_num_32_bit + *regs_num_64_bit;
++ if (!total_num)
++ return -EINVAL;
++
++ return 0;
++}
++
++int hclge_get_regs_len(struct hnae3_handle *handle)
++{
++ int cmdq_lines, common_lines, ring_lines, tqp_intr_lines;
++ struct hnae3_knic_private_info *kinfo = &handle->kinfo;
++ struct hclge_vport *vport = hclge_get_vport(handle);
++ struct hclge_dev *hdev = vport->back;
++ int regs_num_32_bit, regs_num_64_bit, dfx_regs_len;
++ int regs_lines_32_bit, regs_lines_64_bit;
++ int ret;
++
++ ret = hclge_get_regs_num(hdev, ®s_num_32_bit, ®s_num_64_bit);
++ if (ret) {
++ dev_err(&hdev->pdev->dev,
++ "Get register number failed, ret = %d.\n", ret);
++ return ret;
++ }
++
++ ret = hclge_get_dfx_reg_len(hdev, &dfx_regs_len);
++ if (ret) {
++ dev_err(&hdev->pdev->dev,
++ "Get dfx reg len failed, ret = %d.\n", ret);
++ return ret;
++ }
++
++ cmdq_lines = sizeof(cmdq_reg_addr_list) / REG_LEN_PER_LINE +
++ REG_SEPARATOR_LINE;
++ common_lines = sizeof(common_reg_addr_list) / REG_LEN_PER_LINE +
++ REG_SEPARATOR_LINE;
++ ring_lines = sizeof(ring_reg_addr_list) / REG_LEN_PER_LINE +
++ REG_SEPARATOR_LINE;
++ tqp_intr_lines = sizeof(tqp_intr_reg_addr_list) / REG_LEN_PER_LINE +
++ REG_SEPARATOR_LINE;
++ regs_lines_32_bit = regs_num_32_bit * sizeof(u32) / REG_LEN_PER_LINE +
++ REG_SEPARATOR_LINE;
++ regs_lines_64_bit = regs_num_64_bit * sizeof(u64) / REG_LEN_PER_LINE +
++ REG_SEPARATOR_LINE;
++
++ return (cmdq_lines + common_lines + ring_lines * kinfo->num_tqps +
++ tqp_intr_lines * (hdev->num_msi_used - 1) + regs_lines_32_bit +
++ regs_lines_64_bit) * REG_LEN_PER_LINE + dfx_regs_len;
++}
++
++void hclge_get_regs(struct hnae3_handle *handle, u32 *version,
++ void *data)
++{
++#define HCLGE_REG_64_BIT_SPACE_MULTIPLE 2
++
++ struct hnae3_knic_private_info *kinfo = &handle->kinfo;
++ struct hclge_vport *vport = hclge_get_vport(handle);
++ struct hclge_dev *hdev = vport->back;
++ u32 regs_num_32_bit, regs_num_64_bit;
++ int i, reg_num, separator_num, ret;
++ u32 *reg = data;
++
++ *version = hdev->fw_version;
++
++ ret = hclge_get_regs_num(hdev, ®s_num_32_bit, ®s_num_64_bit);
++ if (ret) {
++ dev_err(&hdev->pdev->dev,
++ "Get register number failed, ret = %d.\n", ret);
++ return;
++ }
++
++ reg += hclge_fetch_pf_reg(hdev, reg, kinfo);
++
++ ret = hclge_get_32_bit_regs(hdev, regs_num_32_bit, reg);
++ if (ret) {
++ dev_err(&hdev->pdev->dev,
++ "Get 32 bit register failed, ret = %d.\n", ret);
++ return;
++ }
++ reg_num = regs_num_32_bit;
++ reg += reg_num;
++ separator_num = MAX_SEPARATE_NUM - (reg_num & REG_NUM_REMAIN_MASK);
++ for (i = 0; i < separator_num; i++)
++ *reg++ = SEPARATOR_VALUE;
++
++ ret = hclge_get_64_bit_regs(hdev, regs_num_64_bit, reg);
++ if (ret) {
++ dev_err(&hdev->pdev->dev,
++ "Get 64 bit register failed, ret = %d.\n", ret);
++ return;
++ }
++ reg_num = regs_num_64_bit * HCLGE_REG_64_BIT_SPACE_MULTIPLE;
++ reg += reg_num;
++ separator_num = MAX_SEPARATE_NUM - (reg_num & REG_NUM_REMAIN_MASK);
++ for (i = 0; i < separator_num; i++)
++ *reg++ = SEPARATOR_VALUE;
++
++ ret = hclge_get_dfx_reg(hdev, reg);
++ if (ret)
++ dev_err(&hdev->pdev->dev,
++ "Get dfx register failed, ret = %d.\n", ret);
++}
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.h
+new file mode 100644
+index 0000000000000..b6bc1ecb8054e
+--- /dev/null
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.h
+@@ -0,0 +1,17 @@
++/* SPDX-License-Identifier: GPL-2.0+ */
++// Copyright (c) 2023 Hisilicon Limited.
++
++#ifndef __HCLGE_REGS_H
++#define __HCLGE_REGS_H
++#include <linux/types.h>
++#include "hclge_comm_cmd.h"
++
++struct hnae3_handle;
++struct hclge_dev;
++
++int hclge_query_bd_num_cmd_send(struct hclge_dev *hdev,
++ struct hclge_desc *desc);
++int hclge_get_regs_len(struct hnae3_handle *handle);
++void hclge_get_regs(struct hnae3_handle *handle, u32 *version,
++ void *data);
++#endif
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+index dd08989a4c7c1..de42a0e1b54b8 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+@@ -6,6 +6,7 @@
+ #include <net/rtnetlink.h>
+ #include "hclgevf_cmd.h"
+ #include "hclgevf_main.h"
++#include "hclgevf_regs.h"
+ #include "hclge_mbx.h"
+ #include "hnae3.h"
+ #include "hclgevf_devlink.h"
+@@ -33,58 +34,6 @@ static const struct pci_device_id ae_algovf_pci_tbl[] = {
+
+ MODULE_DEVICE_TABLE(pci, ae_algovf_pci_tbl);
+
+-static const u32 cmdq_reg_addr_list[] = {HCLGE_COMM_NIC_CSQ_BASEADDR_L_REG,
+- HCLGE_COMM_NIC_CSQ_BASEADDR_H_REG,
+- HCLGE_COMM_NIC_CSQ_DEPTH_REG,
+- HCLGE_COMM_NIC_CSQ_TAIL_REG,
+- HCLGE_COMM_NIC_CSQ_HEAD_REG,
+- HCLGE_COMM_NIC_CRQ_BASEADDR_L_REG,
+- HCLGE_COMM_NIC_CRQ_BASEADDR_H_REG,
+- HCLGE_COMM_NIC_CRQ_DEPTH_REG,
+- HCLGE_COMM_NIC_CRQ_TAIL_REG,
+- HCLGE_COMM_NIC_CRQ_HEAD_REG,
+- HCLGE_COMM_VECTOR0_CMDQ_SRC_REG,
+- HCLGE_COMM_VECTOR0_CMDQ_STATE_REG,
+- HCLGE_COMM_CMDQ_INTR_EN_REG,
+- HCLGE_COMM_CMDQ_INTR_GEN_REG};
+-
+-static const u32 common_reg_addr_list[] = {HCLGEVF_MISC_VECTOR_REG_BASE,
+- HCLGEVF_RST_ING,
+- HCLGEVF_GRO_EN_REG};
+-
+-static const u32 ring_reg_addr_list[] = {HCLGEVF_RING_RX_ADDR_L_REG,
+- HCLGEVF_RING_RX_ADDR_H_REG,
+- HCLGEVF_RING_RX_BD_NUM_REG,
+- HCLGEVF_RING_RX_BD_LENGTH_REG,
+- HCLGEVF_RING_RX_MERGE_EN_REG,
+- HCLGEVF_RING_RX_TAIL_REG,
+- HCLGEVF_RING_RX_HEAD_REG,
+- HCLGEVF_RING_RX_FBD_NUM_REG,
+- HCLGEVF_RING_RX_OFFSET_REG,
+- HCLGEVF_RING_RX_FBD_OFFSET_REG,
+- HCLGEVF_RING_RX_STASH_REG,
+- HCLGEVF_RING_RX_BD_ERR_REG,
+- HCLGEVF_RING_TX_ADDR_L_REG,
+- HCLGEVF_RING_TX_ADDR_H_REG,
+- HCLGEVF_RING_TX_BD_NUM_REG,
+- HCLGEVF_RING_TX_PRIORITY_REG,
+- HCLGEVF_RING_TX_TC_REG,
+- HCLGEVF_RING_TX_MERGE_EN_REG,
+- HCLGEVF_RING_TX_TAIL_REG,
+- HCLGEVF_RING_TX_HEAD_REG,
+- HCLGEVF_RING_TX_FBD_NUM_REG,
+- HCLGEVF_RING_TX_OFFSET_REG,
+- HCLGEVF_RING_TX_EBD_NUM_REG,
+- HCLGEVF_RING_TX_EBD_OFFSET_REG,
+- HCLGEVF_RING_TX_BD_ERR_REG,
+- HCLGEVF_RING_EN_REG};
+-
+-static const u32 tqp_intr_reg_addr_list[] = {HCLGEVF_TQP_INTR_CTRL_REG,
+- HCLGEVF_TQP_INTR_GL0_REG,
+- HCLGEVF_TQP_INTR_GL1_REG,
+- HCLGEVF_TQP_INTR_GL2_REG,
+- HCLGEVF_TQP_INTR_RL_REG};
+-
+ /* hclgevf_cmd_send - send command to command queue
+ * @hw: pointer to the hw struct
+ * @desc: prefilled descriptor for describing the command
+@@ -111,7 +60,7 @@ void hclgevf_arq_init(struct hclgevf_dev *hdev)
+ spin_unlock(&cmdq->crq.lock);
+ }
+
+-static struct hclgevf_dev *hclgevf_ae_get_hdev(struct hnae3_handle *handle)
++struct hclgevf_dev *hclgevf_ae_get_hdev(struct hnae3_handle *handle)
+ {
+ if (!handle->client)
+ return container_of(handle, struct hclgevf_dev, nic);
+@@ -3262,72 +3211,6 @@ static void hclgevf_get_link_mode(struct hnae3_handle *handle,
+ *advertising = hdev->hw.mac.advertising;
+ }
+
+-#define MAX_SEPARATE_NUM 4
+-#define SEPARATOR_VALUE 0xFDFCFBFA
+-#define REG_NUM_PER_LINE 4
+-#define REG_LEN_PER_LINE (REG_NUM_PER_LINE * sizeof(u32))
+-
+-static int hclgevf_get_regs_len(struct hnae3_handle *handle)
+-{
+- int cmdq_lines, common_lines, ring_lines, tqp_intr_lines;
+- struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
+-
+- cmdq_lines = sizeof(cmdq_reg_addr_list) / REG_LEN_PER_LINE + 1;
+- common_lines = sizeof(common_reg_addr_list) / REG_LEN_PER_LINE + 1;
+- ring_lines = sizeof(ring_reg_addr_list) / REG_LEN_PER_LINE + 1;
+- tqp_intr_lines = sizeof(tqp_intr_reg_addr_list) / REG_LEN_PER_LINE + 1;
+-
+- return (cmdq_lines + common_lines + ring_lines * hdev->num_tqps +
+- tqp_intr_lines * (hdev->num_msi_used - 1)) * REG_LEN_PER_LINE;
+-}
+-
+-static void hclgevf_get_regs(struct hnae3_handle *handle, u32 *version,
+- void *data)
+-{
+- struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
+- int i, j, reg_um, separator_num;
+- u32 *reg = data;
+-
+- *version = hdev->fw_version;
+-
+- /* fetching per-VF registers values from VF PCIe register space */
+- reg_um = sizeof(cmdq_reg_addr_list) / sizeof(u32);
+- separator_num = MAX_SEPARATE_NUM - reg_um % REG_NUM_PER_LINE;
+- for (i = 0; i < reg_um; i++)
+- *reg++ = hclgevf_read_dev(&hdev->hw, cmdq_reg_addr_list[i]);
+- for (i = 0; i < separator_num; i++)
+- *reg++ = SEPARATOR_VALUE;
+-
+- reg_um = sizeof(common_reg_addr_list) / sizeof(u32);
+- separator_num = MAX_SEPARATE_NUM - reg_um % REG_NUM_PER_LINE;
+- for (i = 0; i < reg_um; i++)
+- *reg++ = hclgevf_read_dev(&hdev->hw, common_reg_addr_list[i]);
+- for (i = 0; i < separator_num; i++)
+- *reg++ = SEPARATOR_VALUE;
+-
+- reg_um = sizeof(ring_reg_addr_list) / sizeof(u32);
+- separator_num = MAX_SEPARATE_NUM - reg_um % REG_NUM_PER_LINE;
+- for (j = 0; j < hdev->num_tqps; j++) {
+- for (i = 0; i < reg_um; i++)
+- *reg++ = hclgevf_read_dev(&hdev->hw,
+- ring_reg_addr_list[i] +
+- HCLGEVF_TQP_REG_SIZE * j);
+- for (i = 0; i < separator_num; i++)
+- *reg++ = SEPARATOR_VALUE;
+- }
+-
+- reg_um = sizeof(tqp_intr_reg_addr_list) / sizeof(u32);
+- separator_num = MAX_SEPARATE_NUM - reg_um % REG_NUM_PER_LINE;
+- for (j = 0; j < hdev->num_msi_used - 1; j++) {
+- for (i = 0; i < reg_um; i++)
+- *reg++ = hclgevf_read_dev(&hdev->hw,
+- tqp_intr_reg_addr_list[i] +
+- 4 * j);
+- for (i = 0; i < separator_num; i++)
+- *reg++ = SEPARATOR_VALUE;
+- }
+-}
+-
+ void hclgevf_update_port_base_vlan_info(struct hclgevf_dev *hdev, u16 state,
+ struct hclge_mbx_port_base_vlan *port_base_vlan)
+ {
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h
+index 59ca6c794d6db..81c16b8c8da29 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h
+@@ -294,4 +294,5 @@ void hclgevf_reset_task_schedule(struct hclgevf_dev *hdev);
+ void hclgevf_mbx_task_schedule(struct hclgevf_dev *hdev);
+ void hclgevf_update_port_base_vlan_info(struct hclgevf_dev *hdev, u16 state,
+ struct hclge_mbx_port_base_vlan *port_base_vlan);
++struct hclgevf_dev *hclgevf_ae_get_hdev(struct hnae3_handle *handle);
+ #endif
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c
+new file mode 100644
+index 0000000000000..197ab733306b5
+--- /dev/null
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c
+@@ -0,0 +1,127 @@
++// SPDX-License-Identifier: GPL-2.0+
++// Copyright (c) 2023 Hisilicon Limited.
++
++#include "hclgevf_main.h"
++#include "hclgevf_regs.h"
++#include "hnae3.h"
++
++static const u32 cmdq_reg_addr_list[] = {HCLGE_COMM_NIC_CSQ_BASEADDR_L_REG,
++ HCLGE_COMM_NIC_CSQ_BASEADDR_H_REG,
++ HCLGE_COMM_NIC_CSQ_DEPTH_REG,
++ HCLGE_COMM_NIC_CSQ_TAIL_REG,
++ HCLGE_COMM_NIC_CSQ_HEAD_REG,
++ HCLGE_COMM_NIC_CRQ_BASEADDR_L_REG,
++ HCLGE_COMM_NIC_CRQ_BASEADDR_H_REG,
++ HCLGE_COMM_NIC_CRQ_DEPTH_REG,
++ HCLGE_COMM_NIC_CRQ_TAIL_REG,
++ HCLGE_COMM_NIC_CRQ_HEAD_REG,
++ HCLGE_COMM_VECTOR0_CMDQ_SRC_REG,
++ HCLGE_COMM_VECTOR0_CMDQ_STATE_REG,
++ HCLGE_COMM_CMDQ_INTR_EN_REG,
++ HCLGE_COMM_CMDQ_INTR_GEN_REG};
++
++static const u32 common_reg_addr_list[] = {HCLGEVF_MISC_VECTOR_REG_BASE,
++ HCLGEVF_RST_ING,
++ HCLGEVF_GRO_EN_REG};
++
++static const u32 ring_reg_addr_list[] = {HCLGEVF_RING_RX_ADDR_L_REG,
++ HCLGEVF_RING_RX_ADDR_H_REG,
++ HCLGEVF_RING_RX_BD_NUM_REG,
++ HCLGEVF_RING_RX_BD_LENGTH_REG,
++ HCLGEVF_RING_RX_MERGE_EN_REG,
++ HCLGEVF_RING_RX_TAIL_REG,
++ HCLGEVF_RING_RX_HEAD_REG,
++ HCLGEVF_RING_RX_FBD_NUM_REG,
++ HCLGEVF_RING_RX_OFFSET_REG,
++ HCLGEVF_RING_RX_FBD_OFFSET_REG,
++ HCLGEVF_RING_RX_STASH_REG,
++ HCLGEVF_RING_RX_BD_ERR_REG,
++ HCLGEVF_RING_TX_ADDR_L_REG,
++ HCLGEVF_RING_TX_ADDR_H_REG,
++ HCLGEVF_RING_TX_BD_NUM_REG,
++ HCLGEVF_RING_TX_PRIORITY_REG,
++ HCLGEVF_RING_TX_TC_REG,
++ HCLGEVF_RING_TX_MERGE_EN_REG,
++ HCLGEVF_RING_TX_TAIL_REG,
++ HCLGEVF_RING_TX_HEAD_REG,
++ HCLGEVF_RING_TX_FBD_NUM_REG,
++ HCLGEVF_RING_TX_OFFSET_REG,
++ HCLGEVF_RING_TX_EBD_NUM_REG,
++ HCLGEVF_RING_TX_EBD_OFFSET_REG,
++ HCLGEVF_RING_TX_BD_ERR_REG,
++ HCLGEVF_RING_EN_REG};
++
++static const u32 tqp_intr_reg_addr_list[] = {HCLGEVF_TQP_INTR_CTRL_REG,
++ HCLGEVF_TQP_INTR_GL0_REG,
++ HCLGEVF_TQP_INTR_GL1_REG,
++ HCLGEVF_TQP_INTR_GL2_REG,
++ HCLGEVF_TQP_INTR_RL_REG};
++
++#define MAX_SEPARATE_NUM 4
++#define SEPARATOR_VALUE 0xFDFCFBFA
++#define REG_NUM_PER_LINE 4
++#define REG_LEN_PER_LINE (REG_NUM_PER_LINE * sizeof(u32))
++
++int hclgevf_get_regs_len(struct hnae3_handle *handle)
++{
++ int cmdq_lines, common_lines, ring_lines, tqp_intr_lines;
++ struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
++
++ cmdq_lines = sizeof(cmdq_reg_addr_list) / REG_LEN_PER_LINE + 1;
++ common_lines = sizeof(common_reg_addr_list) / REG_LEN_PER_LINE + 1;
++ ring_lines = sizeof(ring_reg_addr_list) / REG_LEN_PER_LINE + 1;
++ tqp_intr_lines = sizeof(tqp_intr_reg_addr_list) / REG_LEN_PER_LINE + 1;
++
++ return (cmdq_lines + common_lines + ring_lines * hdev->num_tqps +
++ tqp_intr_lines * (hdev->num_msi_used - 1)) * REG_LEN_PER_LINE;
++}
++
++void hclgevf_get_regs(struct hnae3_handle *handle, u32 *version,
++ void *data)
++{
++#define HCLGEVF_RING_REG_OFFSET 0x200
++#define HCLGEVF_RING_INT_REG_OFFSET 0x4
++
++ struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
++ int i, j, reg_um, separator_num;
++ u32 *reg = data;
++
++ *version = hdev->fw_version;
++
++ /* fetching per-VF registers values from VF PCIe register space */
++ reg_um = sizeof(cmdq_reg_addr_list) / sizeof(u32);
++ separator_num = MAX_SEPARATE_NUM - reg_um % REG_NUM_PER_LINE;
++ for (i = 0; i < reg_um; i++)
++ *reg++ = hclgevf_read_dev(&hdev->hw, cmdq_reg_addr_list[i]);
++ for (i = 0; i < separator_num; i++)
++ *reg++ = SEPARATOR_VALUE;
++
++ reg_um = sizeof(common_reg_addr_list) / sizeof(u32);
++ separator_num = MAX_SEPARATE_NUM - reg_um % REG_NUM_PER_LINE;
++ for (i = 0; i < reg_um; i++)
++ *reg++ = hclgevf_read_dev(&hdev->hw, common_reg_addr_list[i]);
++ for (i = 0; i < separator_num; i++)
++ *reg++ = SEPARATOR_VALUE;
++
++ reg_um = sizeof(ring_reg_addr_list) / sizeof(u32);
++ separator_num = MAX_SEPARATE_NUM - reg_um % REG_NUM_PER_LINE;
++ for (j = 0; j < hdev->num_tqps; j++) {
++ for (i = 0; i < reg_um; i++)
++ *reg++ = hclgevf_read_dev(&hdev->hw,
++ ring_reg_addr_list[i] +
++ HCLGEVF_RING_REG_OFFSET * j);
++ for (i = 0; i < separator_num; i++)
++ *reg++ = SEPARATOR_VALUE;
++ }
++
++ reg_um = sizeof(tqp_intr_reg_addr_list) / sizeof(u32);
++ separator_num = MAX_SEPARATE_NUM - reg_um % REG_NUM_PER_LINE;
++ for (j = 0; j < hdev->num_msi_used - 1; j++) {
++ for (i = 0; i < reg_um; i++)
++ *reg++ = hclgevf_read_dev(&hdev->hw,
++ tqp_intr_reg_addr_list[i] +
++ HCLGEVF_RING_INT_REG_OFFSET * j);
++ for (i = 0; i < separator_num; i++)
++ *reg++ = SEPARATOR_VALUE;
++ }
++}
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.h b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.h
+new file mode 100644
+index 0000000000000..77bdcf60a1afe
+--- /dev/null
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.h
+@@ -0,0 +1,13 @@
++/* SPDX-License-Identifier: GPL-2.0+ */
++/* Copyright (c) 2023 Hisilicon Limited. */
++
++#ifndef __HCLGEVF_REGS_H
++#define __HCLGEVF_REGS_H
++#include <linux/types.h>
++
++struct hnae3_handle;
++
++int hclgevf_get_regs_len(struct hnae3_handle *handle);
++void hclgevf_get_regs(struct hnae3_handle *handle, u32 *version,
++ void *data);
++#endif
+--
+2.40.1
+
--- /dev/null
+From 37976c1493cbff52abfbcd56ced55f9f3d458a66 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Aug 2023 14:06:39 +0800
+Subject: net: hns3: Support tlv in regs data for HNS3 PF driver
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jijie Shao <shaojijie@huawei.com>
+
+[ Upstream commit d8634b7c3f62d265fc2ecf29286aa9c5b78f969f ]
+
+The dump register function is being refactored.
+The second step in refactoring is to support tlv info in regs data for
+HNS3 PF driver.
+
+Currently, if we use "ethtool -d" to dump regs value,
+the output is as follows:
+ offset1: 00 01 02 03 04 05 ...
+ offset2:10 11 12 13 14 15 ...
+ ......
+
+We can't get the value of a register directly.
+
+This patch deletes the original separator information and
+add tag_len_value information in regs data.
+ethtool can parse register data in key-value format by -d command.
+
+a patch will be added to the ethtool to parse regs data
+in the following format:
+ reg1 : value2
+ reg2 : value2
+ ......
+
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 36122201eeae ("net: hns3: fix wrong rpu tln reg issue")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../hisilicon/hns3/hns3pf/hclge_regs.c | 167 +++++++++++-------
+ 1 file changed, 102 insertions(+), 65 deletions(-)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c
+index e566443948756..734e5f757b9c5 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c
+@@ -106,12 +106,66 @@ static const enum hclge_opcode_type hclge_dfx_reg_opcode_list[] = {
+ HCLGE_OPC_DFX_SSU_REG_2
+ };
+
+-#define MAX_SEPARATE_NUM 4
+-#define SEPARATOR_VALUE 0xFDFCFBFA
+-#define REG_NUM_PER_LINE 4
+-#define REG_LEN_PER_LINE (REG_NUM_PER_LINE * sizeof(u32))
+-#define REG_SEPARATOR_LINE 1
+-#define REG_NUM_REMAIN_MASK 3
++enum hclge_reg_tag {
++ HCLGE_REG_TAG_CMDQ = 0,
++ HCLGE_REG_TAG_COMMON,
++ HCLGE_REG_TAG_RING,
++ HCLGE_REG_TAG_TQP_INTR,
++ HCLGE_REG_TAG_QUERY_32_BIT,
++ HCLGE_REG_TAG_QUERY_64_BIT,
++ HCLGE_REG_TAG_DFX_BIOS_COMMON,
++ HCLGE_REG_TAG_DFX_SSU_0,
++ HCLGE_REG_TAG_DFX_SSU_1,
++ HCLGE_REG_TAG_DFX_IGU_EGU,
++ HCLGE_REG_TAG_DFX_RPU_0,
++ HCLGE_REG_TAG_DFX_RPU_1,
++ HCLGE_REG_TAG_DFX_NCSI,
++ HCLGE_REG_TAG_DFX_RTC,
++ HCLGE_REG_TAG_DFX_PPP,
++ HCLGE_REG_TAG_DFX_RCB,
++ HCLGE_REG_TAG_DFX_TQP,
++ HCLGE_REG_TAG_DFX_SSU_2,
++};
++
++#pragma pack(4)
++struct hclge_reg_tlv {
++ u16 tag;
++ u16 len;
++};
++
++struct hclge_reg_header {
++ u64 magic_number;
++ u8 is_vf;
++ u8 rsv[7];
++};
++
++#pragma pack()
++
++#define HCLGE_REG_TLV_SIZE sizeof(struct hclge_reg_tlv)
++#define HCLGE_REG_HEADER_SIZE sizeof(struct hclge_reg_header)
++#define HCLGE_REG_TLV_SPACE (sizeof(struct hclge_reg_tlv) / sizeof(u32))
++#define HCLGE_REG_HEADER_SPACE (sizeof(struct hclge_reg_header) / sizeof(u32))
++#define HCLGE_REG_MAGIC_NUMBER 0x686e733372656773 /* meaning is hns3regs */
++
++static u32 hclge_reg_get_header(void *data)
++{
++ struct hclge_reg_header *header = data;
++
++ header->magic_number = HCLGE_REG_MAGIC_NUMBER;
++ header->is_vf = 0x0;
++
++ return HCLGE_REG_HEADER_SPACE;
++}
++
++static u32 hclge_reg_get_tlv(u32 tag, u32 regs_num, void *data)
++{
++ struct hclge_reg_tlv *tlv = data;
++
++ tlv->tag = tag;
++ tlv->len = regs_num * sizeof(u32) + HCLGE_REG_TLV_SIZE;
++
++ return HCLGE_REG_TLV_SPACE;
++}
+
+ static int hclge_get_32_bit_regs(struct hclge_dev *hdev, u32 regs_num,
+ void *data)
+@@ -291,31 +345,28 @@ static int hclge_dfx_reg_cmd_send(struct hclge_dev *hdev,
+ static int hclge_dfx_reg_fetch_data(struct hclge_desc *desc_src, int bd_num,
+ void *data)
+ {
+- int entries_per_desc, reg_num, separator_num, desc_index, index, i;
++ int entries_per_desc, reg_num, desc_index, index, i;
+ struct hclge_desc *desc = desc_src;
+ u32 *reg = data;
+
+ entries_per_desc = ARRAY_SIZE(desc->data);
+ reg_num = entries_per_desc * bd_num;
+- separator_num = REG_NUM_PER_LINE - (reg_num & REG_NUM_REMAIN_MASK);
+ for (i = 0; i < reg_num; i++) {
+ index = i % entries_per_desc;
+ desc_index = i / entries_per_desc;
+ *reg++ = le32_to_cpu(desc[desc_index].data[index]);
+ }
+- for (i = 0; i < separator_num; i++)
+- *reg++ = SEPARATOR_VALUE;
+
+- return reg_num + separator_num;
++ return reg_num;
+ }
+
+ static int hclge_get_dfx_reg_len(struct hclge_dev *hdev, int *len)
+ {
+ u32 dfx_reg_type_num = ARRAY_SIZE(hclge_dfx_bd_offset_list);
+- int data_len_per_desc, bd_num;
++ int data_len_per_desc;
+ int *bd_num_list;
+- u32 data_len, i;
+ int ret;
++ u32 i;
+
+ bd_num_list = kcalloc(dfx_reg_type_num, sizeof(int), GFP_KERNEL);
+ if (!bd_num_list)
+@@ -330,11 +381,8 @@ static int hclge_get_dfx_reg_len(struct hclge_dev *hdev, int *len)
+
+ data_len_per_desc = sizeof_field(struct hclge_desc, data);
+ *len = 0;
+- for (i = 0; i < dfx_reg_type_num; i++) {
+- bd_num = bd_num_list[i];
+- data_len = data_len_per_desc * bd_num;
+- *len += (data_len / REG_LEN_PER_LINE + 1) * REG_LEN_PER_LINE;
+- }
++ for (i = 0; i < dfx_reg_type_num; i++)
++ *len += bd_num_list[i] * data_len_per_desc + HCLGE_REG_TLV_SIZE;
+
+ out:
+ kfree(bd_num_list);
+@@ -383,6 +431,9 @@ static int hclge_get_dfx_reg(struct hclge_dev *hdev, void *data)
+ break;
+ }
+
++ reg += hclge_reg_get_tlv(HCLGE_REG_TAG_DFX_BIOS_COMMON + i,
++ ARRAY_SIZE(desc_src->data) * bd_num,
++ reg);
+ reg += hclge_dfx_reg_fetch_data(desc_src, bd_num, reg);
+ }
+
+@@ -398,50 +449,43 @@ static int hclge_fetch_pf_reg(struct hclge_dev *hdev, void *data,
+ #define HCLGE_RING_REG_OFFSET 0x200
+ #define HCLGE_RING_INT_REG_OFFSET 0x4
+
+- int i, j, reg_num, separator_num;
++ int i, j, reg_num;
+ int data_num_sum;
+ u32 *reg = data;
+
+ /* fetching per-PF registers valus from PF PCIe register space */
+ reg_num = ARRAY_SIZE(cmdq_reg_addr_list);
+- separator_num = MAX_SEPARATE_NUM - (reg_num & REG_NUM_REMAIN_MASK);
++ reg += hclge_reg_get_tlv(HCLGE_REG_TAG_CMDQ, reg_num, reg);
+ for (i = 0; i < reg_num; i++)
+ *reg++ = hclge_read_dev(&hdev->hw, cmdq_reg_addr_list[i]);
+- for (i = 0; i < separator_num; i++)
+- *reg++ = SEPARATOR_VALUE;
+- data_num_sum = reg_num + separator_num;
++ data_num_sum = reg_num + HCLGE_REG_TLV_SPACE;
+
+ reg_num = ARRAY_SIZE(common_reg_addr_list);
+- separator_num = MAX_SEPARATE_NUM - (reg_num & REG_NUM_REMAIN_MASK);
++ reg += hclge_reg_get_tlv(HCLGE_REG_TAG_COMMON, reg_num, reg);
+ for (i = 0; i < reg_num; i++)
+ *reg++ = hclge_read_dev(&hdev->hw, common_reg_addr_list[i]);
+- for (i = 0; i < separator_num; i++)
+- *reg++ = SEPARATOR_VALUE;
+- data_num_sum += reg_num + separator_num;
++ data_num_sum += reg_num + HCLGE_REG_TLV_SPACE;
+
+ reg_num = ARRAY_SIZE(ring_reg_addr_list);
+- separator_num = MAX_SEPARATE_NUM - (reg_num & REG_NUM_REMAIN_MASK);
+ for (j = 0; j < kinfo->num_tqps; j++) {
++ reg += hclge_reg_get_tlv(HCLGE_REG_TAG_RING, reg_num, reg);
+ for (i = 0; i < reg_num; i++)
+ *reg++ = hclge_read_dev(&hdev->hw,
+ ring_reg_addr_list[i] +
+ HCLGE_RING_REG_OFFSET * j);
+- for (i = 0; i < separator_num; i++)
+- *reg++ = SEPARATOR_VALUE;
+ }
+- data_num_sum += (reg_num + separator_num) * kinfo->num_tqps;
++ data_num_sum += (reg_num + HCLGE_REG_TLV_SPACE) * kinfo->num_tqps;
+
+ reg_num = ARRAY_SIZE(tqp_intr_reg_addr_list);
+- separator_num = MAX_SEPARATE_NUM - (reg_num & REG_NUM_REMAIN_MASK);
+ for (j = 0; j < hdev->num_msi_used - 1; j++) {
++ reg += hclge_reg_get_tlv(HCLGE_REG_TAG_TQP_INTR, reg_num, reg);
+ for (i = 0; i < reg_num; i++)
+ *reg++ = hclge_read_dev(&hdev->hw,
+ tqp_intr_reg_addr_list[i] +
+ HCLGE_RING_INT_REG_OFFSET * j);
+- for (i = 0; i < separator_num; i++)
+- *reg++ = SEPARATOR_VALUE;
+ }
+- data_num_sum += (reg_num + separator_num) * (hdev->num_msi_used - 1);
++ data_num_sum += (reg_num + HCLGE_REG_TLV_SPACE) *
++ (hdev->num_msi_used - 1);
+
+ return data_num_sum;
+ }
+@@ -473,12 +517,12 @@ static int hclge_get_regs_num(struct hclge_dev *hdev, u32 *regs_num_32_bit,
+
+ int hclge_get_regs_len(struct hnae3_handle *handle)
+ {
+- int cmdq_lines, common_lines, ring_lines, tqp_intr_lines;
+ struct hnae3_knic_private_info *kinfo = &handle->kinfo;
+ struct hclge_vport *vport = hclge_get_vport(handle);
+- struct hclge_dev *hdev = vport->back;
+ int regs_num_32_bit, regs_num_64_bit, dfx_regs_len;
+- int regs_lines_32_bit, regs_lines_64_bit;
++ int cmdq_len, common_len, ring_len, tqp_intr_len;
++ int regs_len_32_bit, regs_len_64_bit;
++ struct hclge_dev *hdev = vport->back;
+ int ret;
+
+ ret = hclge_get_regs_num(hdev, ®s_num_32_bit, ®s_num_64_bit);
+@@ -495,22 +539,17 @@ int hclge_get_regs_len(struct hnae3_handle *handle)
+ return ret;
+ }
+
+- cmdq_lines = sizeof(cmdq_reg_addr_list) / REG_LEN_PER_LINE +
+- REG_SEPARATOR_LINE;
+- common_lines = sizeof(common_reg_addr_list) / REG_LEN_PER_LINE +
+- REG_SEPARATOR_LINE;
+- ring_lines = sizeof(ring_reg_addr_list) / REG_LEN_PER_LINE +
+- REG_SEPARATOR_LINE;
+- tqp_intr_lines = sizeof(tqp_intr_reg_addr_list) / REG_LEN_PER_LINE +
+- REG_SEPARATOR_LINE;
+- regs_lines_32_bit = regs_num_32_bit * sizeof(u32) / REG_LEN_PER_LINE +
+- REG_SEPARATOR_LINE;
+- regs_lines_64_bit = regs_num_64_bit * sizeof(u64) / REG_LEN_PER_LINE +
+- REG_SEPARATOR_LINE;
+-
+- return (cmdq_lines + common_lines + ring_lines * kinfo->num_tqps +
+- tqp_intr_lines * (hdev->num_msi_used - 1) + regs_lines_32_bit +
+- regs_lines_64_bit) * REG_LEN_PER_LINE + dfx_regs_len;
++ cmdq_len = HCLGE_REG_TLV_SIZE + sizeof(cmdq_reg_addr_list);
++ common_len = HCLGE_REG_TLV_SIZE + sizeof(common_reg_addr_list);
++ ring_len = HCLGE_REG_TLV_SIZE + sizeof(ring_reg_addr_list);
++ tqp_intr_len = HCLGE_REG_TLV_SIZE + sizeof(tqp_intr_reg_addr_list);
++ regs_len_32_bit = HCLGE_REG_TLV_SIZE + regs_num_32_bit * sizeof(u32);
++ regs_len_64_bit = HCLGE_REG_TLV_SIZE + regs_num_64_bit * sizeof(u64);
++
++ /* return the total length of all register values */
++ return HCLGE_REG_HEADER_SIZE + cmdq_len + common_len + ring_len *
++ kinfo->num_tqps + tqp_intr_len * (hdev->num_msi_used - 1) +
++ regs_len_32_bit + regs_len_64_bit + dfx_regs_len;
+ }
+
+ void hclge_get_regs(struct hnae3_handle *handle, u32 *version,
+@@ -522,8 +561,8 @@ void hclge_get_regs(struct hnae3_handle *handle, u32 *version,
+ struct hclge_vport *vport = hclge_get_vport(handle);
+ struct hclge_dev *hdev = vport->back;
+ u32 regs_num_32_bit, regs_num_64_bit;
+- int i, reg_num, separator_num, ret;
+ u32 *reg = data;
++ int ret;
+
+ *version = hdev->fw_version;
+
+@@ -534,31 +573,29 @@ void hclge_get_regs(struct hnae3_handle *handle, u32 *version,
+ return;
+ }
+
++ reg += hclge_reg_get_header(reg);
+ reg += hclge_fetch_pf_reg(hdev, reg, kinfo);
+
++ reg += hclge_reg_get_tlv(HCLGE_REG_TAG_QUERY_32_BIT,
++ regs_num_32_bit, reg);
+ ret = hclge_get_32_bit_regs(hdev, regs_num_32_bit, reg);
+ if (ret) {
+ dev_err(&hdev->pdev->dev,
+ "Get 32 bit register failed, ret = %d.\n", ret);
+ return;
+ }
+- reg_num = regs_num_32_bit;
+- reg += reg_num;
+- separator_num = MAX_SEPARATE_NUM - (reg_num & REG_NUM_REMAIN_MASK);
+- for (i = 0; i < separator_num; i++)
+- *reg++ = SEPARATOR_VALUE;
++ reg += regs_num_32_bit;
+
++ reg += hclge_reg_get_tlv(HCLGE_REG_TAG_QUERY_64_BIT,
++ regs_num_64_bit *
++ HCLGE_REG_64_BIT_SPACE_MULTIPLE, reg);
+ ret = hclge_get_64_bit_regs(hdev, regs_num_64_bit, reg);
+ if (ret) {
+ dev_err(&hdev->pdev->dev,
+ "Get 64 bit register failed, ret = %d.\n", ret);
+ return;
+ }
+- reg_num = regs_num_64_bit * HCLGE_REG_64_BIT_SPACE_MULTIPLE;
+- reg += reg_num;
+- separator_num = MAX_SEPARATE_NUM - (reg_num & REG_NUM_REMAIN_MASK);
+- for (i = 0; i < separator_num; i++)
+- *reg++ = SEPARATOR_VALUE;
++ reg += regs_num_64_bit * HCLGE_REG_64_BIT_SPACE_MULTIPLE;
+
+ ret = hclge_get_dfx_reg(hdev, reg);
+ if (ret)
+--
+2.40.1
+
--- /dev/null
+From 684571bbd7927bae7fc1a594eec2fe86e0bdd5d5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Aug 2023 13:05:04 +0800
+Subject: net: lan966x: Fix return value check for vcap_get_rule()
+
+From: Ruan Jinjie <ruanjinjie@huawei.com>
+
+[ Upstream commit ab104318f63997113b0ce7ac288e51359925ed79 ]
+
+As Simon Horman suggests, update vcap_get_rule() to always
+return an ERR_PTR() and update the error detection conditions to
+use IS_ERR(), so use IS_ERR() to fix the return value issue.
+
+Fixes: 72df3489fb10 ("net: lan966x: Add ptp trap rules")
+Signed-off-by: Ruan Jinjie <ruanjinjie@huawei.com>
+Suggested-by: Simon Horman <horms@kernel.org>
+Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c b/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c
+index 266a21a2d1246..1da2b1f82ae93 100644
+--- a/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c
++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c
+@@ -59,7 +59,7 @@ static int lan966x_ptp_add_trap(struct lan966x_port *port,
+ int err;
+
+ vrule = vcap_get_rule(lan966x->vcap_ctrl, rule_id);
+- if (vrule) {
++ if (!IS_ERR(vrule)) {
+ u32 value, mask;
+
+ /* Just modify the ingress port mask and exit */
+@@ -106,7 +106,7 @@ static int lan966x_ptp_del_trap(struct lan966x_port *port,
+ int err;
+
+ vrule = vcap_get_rule(lan966x->vcap_ctrl, rule_id);
+- if (!vrule)
++ if (IS_ERR(vrule))
+ return -EEXIST;
+
+ vcap_rule_get_key_u32(vrule, VCAP_KF_IF_IGR_PORT_MASK, &value, &mask);
+--
+2.40.1
+
--- /dev/null
+From 253d97b46dacb0d6e759188584c1eb744e8498f2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Aug 2023 15:09:11 +0800
+Subject: net-memcg: Fix scope of sockmem pressure indicators
+
+From: Abel Wu <wuyun.abel@bytedance.com>
+
+[ Upstream commit ac8a52962164a50e693fa021d3564d7745b83a7f ]
+
+Now there are two indicators of socket memory pressure sit inside
+struct mem_cgroup, socket_pressure and tcpmem_pressure, indicating
+memory reclaim pressure in memcg->memory and ->tcpmem respectively.
+
+When in legacy mode (cgroupv1), the socket memory is charged into
+->tcpmem which is independent of ->memory, so socket_pressure has
+nothing to do with socket's pressure at all. Things could be worse
+by taking socket_pressure into consideration in legacy mode, as a
+pressure in ->memory can lead to premature reclamation/throttling
+in socket.
+
+While for the default mode (cgroupv2), the socket memory is charged
+into ->memory, and ->tcpmem/->tcpmem_pressure are simply not used.
+
+So {socket,tcpmem}_pressure are only used in default/legacy mode
+respectively for indicating socket memory pressure. This patch fixes
+the pieces of code that make mixed use of both.
+
+Fixes: 8e8ae645249b ("mm: memcontrol: hook up vmpressure to socket pressure")
+Signed-off-by: Abel Wu <wuyun.abel@bytedance.com>
+Acked-by: Shakeel Butt <shakeelb@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/memcontrol.h | 9 +++++++--
+ mm/vmpressure.c | 8 ++++++++
+ 2 files changed, 15 insertions(+), 2 deletions(-)
+
+diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
+index 222d7370134c7..7f2921217f50b 100644
+--- a/include/linux/memcontrol.h
++++ b/include/linux/memcontrol.h
+@@ -284,6 +284,11 @@ struct mem_cgroup {
+ atomic_long_t memory_events[MEMCG_NR_MEMORY_EVENTS];
+ atomic_long_t memory_events_local[MEMCG_NR_MEMORY_EVENTS];
+
++ /*
++ * Hint of reclaim pressure for socket memroy management. Note
++ * that this indicator should NOT be used in legacy cgroup mode
++ * where socket memory is accounted/charged separately.
++ */
+ unsigned long socket_pressure;
+
+ /* Legacy tcp memory accounting */
+@@ -1743,8 +1748,8 @@ void mem_cgroup_sk_alloc(struct sock *sk);
+ void mem_cgroup_sk_free(struct sock *sk);
+ static inline bool mem_cgroup_under_socket_pressure(struct mem_cgroup *memcg)
+ {
+- if (!cgroup_subsys_on_dfl(memory_cgrp_subsys) && memcg->tcpmem_pressure)
+- return true;
++ if (!cgroup_subsys_on_dfl(memory_cgrp_subsys))
++ return !!memcg->tcpmem_pressure;
+ do {
+ if (time_before(jiffies, READ_ONCE(memcg->socket_pressure)))
+ return true;
+diff --git a/mm/vmpressure.c b/mm/vmpressure.c
+index b52644771cc43..22c6689d93027 100644
+--- a/mm/vmpressure.c
++++ b/mm/vmpressure.c
+@@ -244,6 +244,14 @@ void vmpressure(gfp_t gfp, struct mem_cgroup *memcg, bool tree,
+ if (mem_cgroup_disabled())
+ return;
+
++ /*
++ * The in-kernel users only care about the reclaim efficiency
++ * for this @memcg rather than the whole subtree, and there
++ * isn't and won't be any in-kernel user in a legacy cgroup.
++ */
++ if (!cgroup_subsys_on_dfl(memory_cgrp_subsys) && !tree)
++ return;
++
+ vmpr = memcg_to_vmpressure(memcg);
+
+ /*
+--
+2.40.1
+
--- /dev/null
+From 0a9eec2c244af576196c552ea24652806b3d8c2e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Aug 2023 16:05:54 -0700
+Subject: net/mlx5: Dynamic cyclecounter shift calculation for PTP free running
+ clock
+
+From: Rahul Rameshbabu <rrameshbabu@nvidia.com>
+
+[ Upstream commit 84a58e60038fa0366006977dba85eae16b2e3d78 ]
+
+Use a dynamic calculation to determine the shift value for the internal
+timer cyclecounter that will lead to the highest precision frequency
+adjustments. Previously used a constant for the shift value assuming all
+devices supported by the driver had a nominal frequency of 1GHz. However,
+there are devices that operate at different frequencies. The previous shift
+value constant would break the PHC functionality for those devices.
+
+Reported-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Closes: https://lore.kernel.org/netdev/20230815151507.3028503-1-vadfed@meta.com/
+Fixes: 6a4010927562 ("net/mlx5: Update cyclecounter shift value to improve ptp free running mode precision")
+Signed-off-by: Rahul Rameshbabu <rrameshbabu@nvidia.com>
+Tested-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Acked-by: Saeed Mahameed <saeedm@nvidia.com>
+Link: https://lore.kernel.org/r/20230821230554.236210-1-rrameshbabu@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/mellanox/mlx5/core/lib/clock.c | 32 ++++++++++++++++---
+ 1 file changed, 27 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
+index dba4c5e2f7667..94a1635ecdd47 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
+@@ -32,16 +32,13 @@
+
+ #include <linux/clocksource.h>
+ #include <linux/highmem.h>
++#include <linux/log2.h>
+ #include <linux/ptp_clock_kernel.h>
+ #include <rdma/mlx5-abi.h>
+ #include "lib/eq.h"
+ #include "en.h"
+ #include "clock.h"
+
+-enum {
+- MLX5_CYCLES_SHIFT = 31
+-};
+-
+ enum {
+ MLX5_PIN_MODE_IN = 0x0,
+ MLX5_PIN_MODE_OUT = 0x1,
+@@ -93,6 +90,31 @@ static bool mlx5_modify_mtutc_allowed(struct mlx5_core_dev *mdev)
+ return MLX5_CAP_MCAM_FEATURE(mdev, ptpcyc2realtime_modify);
+ }
+
++static u32 mlx5_ptp_shift_constant(u32 dev_freq_khz)
++{
++ /* Optimal shift constant leads to corrections above just 1 scaled ppm.
++ *
++ * Two sets of equations are needed to derive the optimal shift
++ * constant for the cyclecounter.
++ *
++ * dev_freq_khz * 1000 / 2^shift_constant = 1 scaled_ppm
++ * ppb = scaled_ppm * 1000 / 2^16
++ *
++ * Using the two equations together
++ *
++ * dev_freq_khz * 1000 / 1 scaled_ppm = 2^shift_constant
++ * dev_freq_khz * 2^16 / 1 ppb = 2^shift_constant
++ * dev_freq_khz = 2^(shift_constant - 16)
++ *
++ * then yields
++ *
++ * shift_constant = ilog2(dev_freq_khz) + 16
++ */
++
++ return min(ilog2(dev_freq_khz) + 16,
++ ilog2((U32_MAX / NSEC_PER_MSEC) * dev_freq_khz));
++}
++
+ static bool mlx5_is_mtutc_time_adj_cap(struct mlx5_core_dev *mdev, s64 delta)
+ {
+ s64 min = MLX5_MTUTC_OPERATION_ADJUST_TIME_MIN;
+@@ -910,7 +932,7 @@ static void mlx5_timecounter_init(struct mlx5_core_dev *mdev)
+
+ dev_freq = MLX5_CAP_GEN(mdev, device_frequency_khz);
+ timer->cycles.read = read_internal_timer;
+- timer->cycles.shift = MLX5_CYCLES_SHIFT;
++ timer->cycles.shift = mlx5_ptp_shift_constant(dev_freq);
+ timer->cycles.mult = clocksource_khz2mult(dev_freq,
+ timer->cycles.shift);
+ timer->nominal_c_mult = timer->cycles.mult;
+--
+2.40.1
+
--- /dev/null
+From d6254b4af47b85987fb37bf52918dca7381773ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Jul 2023 15:04:59 +0300
+Subject: net/mlx5: Use RMW accessors for changing LNKCTL
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit 30de872537bda526664d7a20b646adfb3e7ce6e6 ]
+
+Don't assume that only the driver would be accessing LNKCTL of the upstream
+bridge. ASPM policy changes can trigger write to LNKCTL outside of driver's
+control.
+
+Use RMW capability accessors which do proper locking to avoid losing
+concurrent updates to the register value.
+
+Suggested-by: Lukas Wunner <lukas@wunner.de>
+Fixes: eabe8e5e88f5 ("net/mlx5: Handle sync reset now event")
+Link: https://lore.kernel.org/r/20230717120503.15276-8-ilpo.jarvinen@linux.intel.com
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c | 9 ++-------
+ 1 file changed, 2 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+index 50022e7565f14..f202150a5093c 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+@@ -332,16 +332,11 @@ static int mlx5_pci_link_toggle(struct mlx5_core_dev *dev)
+ pci_cfg_access_lock(sdev);
+ }
+ /* PCI link toggle */
+- err = pci_read_config_word(bridge, cap + PCI_EXP_LNKCTL, ®16);
+- if (err)
+- return err;
+- reg16 |= PCI_EXP_LNKCTL_LD;
+- err = pci_write_config_word(bridge, cap + PCI_EXP_LNKCTL, reg16);
++ err = pcie_capability_set_word(bridge, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_LD);
+ if (err)
+ return err;
+ msleep(500);
+- reg16 &= ~PCI_EXP_LNKCTL_LD;
+- err = pci_write_config_word(bridge, cap + PCI_EXP_LNKCTL, reg16);
++ err = pcie_capability_clear_word(bridge, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_LD);
+ if (err)
+ return err;
+
+--
+2.40.1
+
--- /dev/null
+From 0b1126906102cec0e95f1c6e286c23db7d68ba76 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Jul 2023 17:30:08 +0200
+Subject: net: remove duplicate reuseport_lookup functions
+
+From: Lorenz Bauer <lmb@isovalent.com>
+
+[ Upstream commit 0f495f7617229772403e683033abc473f0f0553c ]
+
+There are currently four copies of reuseport_lookup: one each for
+(TCP, UDP)x(IPv4, IPv6). This forces us to duplicate all callers of
+those functions as well. This is already the case for sk_lookup
+helpers (inet,inet6,udp4,udp6)_lookup_run_bpf.
+
+There are two differences between the reuseport_lookup helpers:
+
+1. They call different hash functions depending on protocol
+2. UDP reuseport_lookup checks that sk_state != TCP_ESTABLISHED
+
+Move the check for sk_state into the caller and use the INDIRECT_CALL
+infrastructure to cut down the helpers to one per IP version.
+
+Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: Lorenz Bauer <lmb@isovalent.com>
+Link: https://lore.kernel.org/r/20230720-so-reuseport-v6-4-7021b683cdae@isovalent.com
+Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
+Stable-dep-of: 9c02bec95954 ("bpf, net: Support SO_REUSEPORT sockets with bpf_sk_assign")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/inet6_hashtables.h | 11 ++++++++-
+ include/net/inet_hashtables.h | 15 ++++++++-----
+ net/ipv4/inet_hashtables.c | 20 +++++++++++------
+ net/ipv4/udp.c | 34 +++++++++++-----------------
+ net/ipv6/inet6_hashtables.c | 14 ++++++++----
+ net/ipv6/udp.c | 41 +++++++++++++---------------------
+ 6 files changed, 72 insertions(+), 63 deletions(-)
+
+diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h
+index 032ddab48f8f8..f89320b6fee31 100644
+--- a/include/net/inet6_hashtables.h
++++ b/include/net/inet6_hashtables.h
+@@ -48,12 +48,21 @@ struct sock *__inet6_lookup_established(struct net *net,
+ const u16 hnum, const int dif,
+ const int sdif);
+
++typedef u32 (inet6_ehashfn_t)(const struct net *net,
++ const struct in6_addr *laddr, const u16 lport,
++ const struct in6_addr *faddr, const __be16 fport);
++
++inet6_ehashfn_t inet6_ehashfn;
++
++INDIRECT_CALLABLE_DECLARE(inet6_ehashfn_t udp6_ehashfn);
++
+ struct sock *inet6_lookup_reuseport(struct net *net, struct sock *sk,
+ struct sk_buff *skb, int doff,
+ const struct in6_addr *saddr,
+ __be16 sport,
+ const struct in6_addr *daddr,
+- unsigned short hnum);
++ unsigned short hnum,
++ inet6_ehashfn_t *ehashfn);
+
+ struct sock *inet6_lookup_listener(struct net *net,
+ struct inet_hashinfo *hashinfo,
+diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
+index 8734f3488f5d0..ddfa2e67fdb51 100644
+--- a/include/net/inet_hashtables.h
++++ b/include/net/inet_hashtables.h
+@@ -379,10 +379,19 @@ struct sock *__inet_lookup_established(struct net *net,
+ const __be32 daddr, const u16 hnum,
+ const int dif, const int sdif);
+
++typedef u32 (inet_ehashfn_t)(const struct net *net,
++ const __be32 laddr, const __u16 lport,
++ const __be32 faddr, const __be16 fport);
++
++inet_ehashfn_t inet_ehashfn;
++
++INDIRECT_CALLABLE_DECLARE(inet_ehashfn_t udp_ehashfn);
++
+ struct sock *inet_lookup_reuseport(struct net *net, struct sock *sk,
+ struct sk_buff *skb, int doff,
+ __be32 saddr, __be16 sport,
+- __be32 daddr, unsigned short hnum);
++ __be32 daddr, unsigned short hnum,
++ inet_ehashfn_t *ehashfn);
+
+ static inline struct sock *
+ inet_lookup_established(struct net *net, struct inet_hashinfo *hashinfo,
+@@ -453,10 +462,6 @@ static inline struct sock *__inet_lookup_skb(struct inet_hashinfo *hashinfo,
+ refcounted);
+ }
+
+-u32 inet6_ehashfn(const struct net *net,
+- const struct in6_addr *laddr, const u16 lport,
+- const struct in6_addr *faddr, const __be16 fport);
+-
+ static inline void sk_daddr_set(struct sock *sk, __be32 addr)
+ {
+ sk->sk_daddr = addr; /* alias of inet_daddr */
+diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
+index ecb838460629e..0a7a726464d9d 100644
+--- a/net/ipv4/inet_hashtables.c
++++ b/net/ipv4/inet_hashtables.c
+@@ -28,9 +28,9 @@
+ #include <net/tcp.h>
+ #include <net/sock_reuseport.h>
+
+-static u32 inet_ehashfn(const struct net *net, const __be32 laddr,
+- const __u16 lport, const __be32 faddr,
+- const __be16 fport)
++u32 inet_ehashfn(const struct net *net, const __be32 laddr,
++ const __u16 lport, const __be32 faddr,
++ const __be16 fport)
+ {
+ static u32 inet_ehash_secret __read_mostly;
+
+@@ -39,6 +39,7 @@ static u32 inet_ehashfn(const struct net *net, const __be32 laddr,
+ return __inet_ehashfn(laddr, lport, faddr, fport,
+ inet_ehash_secret + net_hash_mix(net));
+ }
++EXPORT_SYMBOL_GPL(inet_ehashfn);
+
+ /* This function handles inet_sock, but also timewait and request sockets
+ * for IPv4/IPv6.
+@@ -332,16 +333,20 @@ static inline int compute_score(struct sock *sk, struct net *net,
+ return score;
+ }
+
++INDIRECT_CALLABLE_DECLARE(inet_ehashfn_t udp_ehashfn);
++
+ struct sock *inet_lookup_reuseport(struct net *net, struct sock *sk,
+ struct sk_buff *skb, int doff,
+ __be32 saddr, __be16 sport,
+- __be32 daddr, unsigned short hnum)
++ __be32 daddr, unsigned short hnum,
++ inet_ehashfn_t *ehashfn)
+ {
+ struct sock *reuse_sk = NULL;
+ u32 phash;
+
+ if (sk->sk_reuseport) {
+- phash = inet_ehashfn(net, daddr, hnum, saddr, sport);
++ phash = INDIRECT_CALL_2(ehashfn, udp_ehashfn, inet_ehashfn,
++ net, daddr, hnum, saddr, sport);
+ reuse_sk = reuseport_select_sock(sk, phash, skb, doff);
+ }
+ return reuse_sk;
+@@ -371,7 +376,7 @@ static struct sock *inet_lhash2_lookup(struct net *net,
+ score = compute_score(sk, net, hnum, daddr, dif, sdif);
+ if (score > hiscore) {
+ result = inet_lookup_reuseport(net, sk, skb, doff,
+- saddr, sport, daddr, hnum);
++ saddr, sport, daddr, hnum, inet_ehashfn);
+ if (result)
+ return result;
+
+@@ -400,7 +405,8 @@ static inline struct sock *inet_lookup_run_bpf(struct net *net,
+ if (no_reuseport || IS_ERR_OR_NULL(sk))
+ return sk;
+
+- reuse_sk = inet_lookup_reuseport(net, sk, skb, doff, saddr, sport, daddr, hnum);
++ reuse_sk = inet_lookup_reuseport(net, sk, skb, doff, saddr, sport, daddr, hnum,
++ inet_ehashfn);
+ if (reuse_sk)
+ sk = reuse_sk;
+ return sk;
+diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
+index a3302136ce92e..aaba742f6d103 100644
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -407,9 +407,9 @@ static int compute_score(struct sock *sk, struct net *net,
+ return score;
+ }
+
+-static u32 udp_ehashfn(const struct net *net, const __be32 laddr,
+- const __u16 lport, const __be32 faddr,
+- const __be16 fport)
++INDIRECT_CALLABLE_SCOPE
++u32 udp_ehashfn(const struct net *net, const __be32 laddr, const __u16 lport,
++ const __be32 faddr, const __be16 fport)
+ {
+ static u32 udp_ehash_secret __read_mostly;
+
+@@ -419,22 +419,6 @@ static u32 udp_ehashfn(const struct net *net, const __be32 laddr,
+ udp_ehash_secret + net_hash_mix(net));
+ }
+
+-static struct sock *lookup_reuseport(struct net *net, struct sock *sk,
+- struct sk_buff *skb,
+- __be32 saddr, __be16 sport,
+- __be32 daddr, unsigned short hnum)
+-{
+- struct sock *reuse_sk = NULL;
+- u32 hash;
+-
+- if (sk->sk_reuseport && sk->sk_state != TCP_ESTABLISHED) {
+- hash = udp_ehashfn(net, daddr, hnum, saddr, sport);
+- reuse_sk = reuseport_select_sock(sk, hash, skb,
+- sizeof(struct udphdr));
+- }
+- return reuse_sk;
+-}
+-
+ /* called with rcu_read_lock() */
+ static struct sock *udp4_lib_lookup2(struct net *net,
+ __be32 saddr, __be16 sport,
+@@ -453,7 +437,14 @@ static struct sock *udp4_lib_lookup2(struct net *net,
+ daddr, hnum, dif, sdif);
+ if (score > badness) {
+ badness = score;
+- result = lookup_reuseport(net, sk, skb, saddr, sport, daddr, hnum);
++
++ if (sk->sk_state == TCP_ESTABLISHED) {
++ result = sk;
++ continue;
++ }
++
++ result = inet_lookup_reuseport(net, sk, skb, sizeof(struct udphdr),
++ saddr, sport, daddr, hnum, udp_ehashfn);
+ if (!result) {
+ result = sk;
+ continue;
+@@ -492,7 +483,8 @@ static struct sock *udp4_lookup_run_bpf(struct net *net,
+ if (no_reuseport || IS_ERR_OR_NULL(sk))
+ return sk;
+
+- reuse_sk = lookup_reuseport(net, sk, skb, saddr, sport, daddr, hnum);
++ reuse_sk = inet_lookup_reuseport(net, sk, skb, sizeof(struct udphdr),
++ saddr, sport, daddr, hnum, udp_ehashfn);
+ if (reuse_sk)
+ sk = reuse_sk;
+ return sk;
+diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
+index b7c56867314ed..3616225c89ef6 100644
+--- a/net/ipv6/inet6_hashtables.c
++++ b/net/ipv6/inet6_hashtables.c
+@@ -39,6 +39,7 @@ u32 inet6_ehashfn(const struct net *net,
+ return __inet6_ehashfn(lhash, lport, fhash, fport,
+ inet6_ehash_secret + net_hash_mix(net));
+ }
++EXPORT_SYMBOL_GPL(inet6_ehashfn);
+
+ /*
+ * Sockets in TCP_CLOSE state are _always_ taken out of the hash, so
+@@ -111,18 +112,22 @@ static inline int compute_score(struct sock *sk, struct net *net,
+ return score;
+ }
+
++INDIRECT_CALLABLE_DECLARE(inet6_ehashfn_t udp6_ehashfn);
++
+ struct sock *inet6_lookup_reuseport(struct net *net, struct sock *sk,
+ struct sk_buff *skb, int doff,
+ const struct in6_addr *saddr,
+ __be16 sport,
+ const struct in6_addr *daddr,
+- unsigned short hnum)
++ unsigned short hnum,
++ inet6_ehashfn_t *ehashfn)
+ {
+ struct sock *reuse_sk = NULL;
+ u32 phash;
+
+ if (sk->sk_reuseport) {
+- phash = inet6_ehashfn(net, daddr, hnum, saddr, sport);
++ phash = INDIRECT_CALL_INET(ehashfn, udp6_ehashfn, inet6_ehashfn,
++ net, daddr, hnum, saddr, sport);
+ reuse_sk = reuseport_select_sock(sk, phash, skb, doff);
+ }
+ return reuse_sk;
+@@ -145,7 +150,7 @@ static struct sock *inet6_lhash2_lookup(struct net *net,
+ score = compute_score(sk, net, hnum, daddr, dif, sdif);
+ if (score > hiscore) {
+ result = inet6_lookup_reuseport(net, sk, skb, doff,
+- saddr, sport, daddr, hnum);
++ saddr, sport, daddr, hnum, inet6_ehashfn);
+ if (result)
+ return result;
+
+@@ -176,7 +181,8 @@ static inline struct sock *inet6_lookup_run_bpf(struct net *net,
+ if (no_reuseport || IS_ERR_OR_NULL(sk))
+ return sk;
+
+- reuse_sk = inet6_lookup_reuseport(net, sk, skb, doff, saddr, sport, daddr, hnum);
++ reuse_sk = inet6_lookup_reuseport(net, sk, skb, doff,
++ saddr, sport, daddr, hnum, inet6_ehashfn);
+ if (reuse_sk)
+ sk = reuse_sk;
+ return sk;
+diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
+index 9c7457823eb97..19f5a2fc8f378 100644
+--- a/net/ipv6/udp.c
++++ b/net/ipv6/udp.c
+@@ -72,11 +72,12 @@ int udpv6_init_sock(struct sock *sk)
+ return 0;
+ }
+
+-static u32 udp6_ehashfn(const struct net *net,
+- const struct in6_addr *laddr,
+- const u16 lport,
+- const struct in6_addr *faddr,
+- const __be16 fport)
++INDIRECT_CALLABLE_SCOPE
++u32 udp6_ehashfn(const struct net *net,
++ const struct in6_addr *laddr,
++ const u16 lport,
++ const struct in6_addr *faddr,
++ const __be16 fport)
+ {
+ static u32 udp6_ehash_secret __read_mostly;
+ static u32 udp_ipv6_hash_secret __read_mostly;
+@@ -161,24 +162,6 @@ static int compute_score(struct sock *sk, struct net *net,
+ return score;
+ }
+
+-static struct sock *lookup_reuseport(struct net *net, struct sock *sk,
+- struct sk_buff *skb,
+- const struct in6_addr *saddr,
+- __be16 sport,
+- const struct in6_addr *daddr,
+- unsigned int hnum)
+-{
+- struct sock *reuse_sk = NULL;
+- u32 hash;
+-
+- if (sk->sk_reuseport && sk->sk_state != TCP_ESTABLISHED) {
+- hash = udp6_ehashfn(net, daddr, hnum, saddr, sport);
+- reuse_sk = reuseport_select_sock(sk, hash, skb,
+- sizeof(struct udphdr));
+- }
+- return reuse_sk;
+-}
+-
+ /* called with rcu_read_lock() */
+ static struct sock *udp6_lib_lookup2(struct net *net,
+ const struct in6_addr *saddr, __be16 sport,
+@@ -196,7 +179,14 @@ static struct sock *udp6_lib_lookup2(struct net *net,
+ daddr, hnum, dif, sdif);
+ if (score > badness) {
+ badness = score;
+- result = lookup_reuseport(net, sk, skb, saddr, sport, daddr, hnum);
++
++ if (sk->sk_state == TCP_ESTABLISHED) {
++ result = sk;
++ continue;
++ }
++
++ result = inet6_lookup_reuseport(net, sk, skb, sizeof(struct udphdr),
++ saddr, sport, daddr, hnum, udp6_ehashfn);
+ if (!result) {
+ result = sk;
+ continue;
+@@ -236,7 +226,8 @@ static inline struct sock *udp6_lookup_run_bpf(struct net *net,
+ if (no_reuseport || IS_ERR_OR_NULL(sk))
+ return sk;
+
+- reuse_sk = lookup_reuseport(net, sk, skb, saddr, sport, daddr, hnum);
++ reuse_sk = inet6_lookup_reuseport(net, sk, skb, sizeof(struct udphdr),
++ saddr, sport, daddr, hnum, udp6_ehashfn);
+ if (reuse_sk)
+ sk = reuse_sk;
+ return sk;
+--
+2.40.1
+
--- /dev/null
+From fe1da6632cc82a1fae9706276a0fc3b524ee97f6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Aug 2023 01:49:05 -0700
+Subject: net/sched: sch_hfsc: Ensure inner classes have fsc curve
+
+From: Budimir Markovic <markovicbudimir@gmail.com>
+
+[ Upstream commit b3d26c5702c7d6c45456326e56d2ccf3f103e60f ]
+
+HFSC assumes that inner classes have an fsc curve, but it is currently
+possible for classes without an fsc curve to become parents. This leads
+to bugs including a use-after-free.
+
+Don't allow non-root classes without HFSC_FSC to become parents.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: Budimir Markovic <markovicbudimir@gmail.com>
+Signed-off-by: Budimir Markovic <markovicbudimir@gmail.com>
+Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Link: https://lore.kernel.org/r/20230824084905.422-1-markovicbudimir@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_hfsc.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
+index 70b0c5873d326..61d52594ff6d8 100644
+--- a/net/sched/sch_hfsc.c
++++ b/net/sched/sch_hfsc.c
+@@ -1012,6 +1012,10 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
+ if (parent == NULL)
+ return -ENOENT;
+ }
++ if (!(parent->cl_flags & HFSC_FSC) && parent != &q->root) {
++ NL_SET_ERR_MSG(extack, "Invalid parent - parent class must have FSC");
++ return -EINVAL;
++ }
+
+ if (classid == 0 || TC_H_MAJ(classid ^ sch->handle) != 0)
+ return -EINVAL;
+--
+2.40.1
+
--- /dev/null
+From 186695735c368f0738d7a3e5aef210b720f9577c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Aug 2023 10:55:29 +0800
+Subject: net: tcp: fix unexcepted socket die when snd_wnd is 0
+
+From: Menglong Dong <imagedong@tencent.com>
+
+[ Upstream commit e89688e3e97868451a5d05b38a9d2633d6785cd4 ]
+
+In tcp_retransmit_timer(), a window shrunk connection will be regarded
+as timeout if 'tcp_jiffies32 - tp->rcv_tstamp > TCP_RTO_MAX'. This is not
+right all the time.
+
+The retransmits will become zero-window probes in tcp_retransmit_timer()
+if the 'snd_wnd==0'. Therefore, the icsk->icsk_rto will come up to
+TCP_RTO_MAX sooner or later.
+
+However, the timer can be delayed and be triggered after 122877ms, not
+TCP_RTO_MAX, as I tested.
+
+Therefore, 'tcp_jiffies32 - tp->rcv_tstamp > TCP_RTO_MAX' is always true
+once the RTO come up to TCP_RTO_MAX, and the socket will die.
+
+Fix this by replacing the 'tcp_jiffies32' with '(u32)icsk->icsk_timeout',
+which is exact the timestamp of the timeout.
+
+However, "tp->rcv_tstamp" can restart from idle, then tp->rcv_tstamp
+could already be a long time (minutes or hours) in the past even on the
+first RTO. So we double check the timeout with the duration of the
+retransmission.
+
+Meanwhile, making "2 * TCP_RTO_MAX" as the timeout to avoid the socket
+dying too soon.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Link: https://lore.kernel.org/netdev/CADxym3YyMiO+zMD4zj03YPM3FBi-1LHi6gSD2XT8pyAMM096pg@mail.gmail.com/
+Signed-off-by: Menglong Dong <imagedong@tencent.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_timer.c | 18 +++++++++++++++++-
+ 1 file changed, 17 insertions(+), 1 deletion(-)
+
+diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
+index 366c3c25ebe20..db90bd2d4ed66 100644
+--- a/net/ipv4/tcp_timer.c
++++ b/net/ipv4/tcp_timer.c
+@@ -441,6 +441,22 @@ static void tcp_fastopen_synack_timer(struct sock *sk, struct request_sock *req)
+ req->timeout << req->num_timeout, TCP_RTO_MAX);
+ }
+
++static bool tcp_rtx_probe0_timed_out(const struct sock *sk,
++ const struct sk_buff *skb)
++{
++ const struct tcp_sock *tp = tcp_sk(sk);
++ const int timeout = TCP_RTO_MAX * 2;
++ u32 rcv_delta, rtx_delta;
++
++ rcv_delta = inet_csk(sk)->icsk_timeout - tp->rcv_tstamp;
++ if (rcv_delta <= timeout)
++ return false;
++
++ rtx_delta = (u32)msecs_to_jiffies(tcp_time_stamp(tp) -
++ (tp->retrans_stamp ?: tcp_skb_timestamp(skb)));
++
++ return rtx_delta > timeout;
++}
+
+ /**
+ * tcp_retransmit_timer() - The TCP retransmit timeout handler
+@@ -506,7 +522,7 @@ void tcp_retransmit_timer(struct sock *sk)
+ tp->snd_una, tp->snd_nxt);
+ }
+ #endif
+- if (tcp_jiffies32 - tp->rcv_tstamp > TCP_RTO_MAX) {
++ if (tcp_rtx_probe0_timed_out(sk, skb)) {
+ tcp_write_err(sk);
+ goto out;
+ }
+--
+2.40.1
+
--- /dev/null
+From f049f1947912ff4f8d4a570a35b49f5bb2724b3a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Aug 2023 09:50:59 -0700
+Subject: netrom: Deny concurrent connect().
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit c2f8fd7949603efb03908e05abbf7726748c8de3 ]
+
+syzkaller reported null-ptr-deref [0] related to AF_NETROM.
+This is another self-accept issue from the strace log. [1]
+
+syz-executor creates an AF_NETROM socket and calls connect(), which
+is blocked at that time. Then, sk->sk_state is TCP_SYN_SENT and
+sock->state is SS_CONNECTING.
+
+ [pid 5059] socket(AF_NETROM, SOCK_SEQPACKET, 0) = 4
+ [pid 5059] connect(4, {sa_family=AF_NETROM, sa_data="..." <unfinished ...>
+
+Another thread calls connect() concurrently, which finally fails
+with -EINVAL. However, the problem here is the socket state is
+reset even while the first connect() is blocked.
+
+ [pid 5060] connect(4, NULL, 0 <unfinished ...>
+ [pid 5060] <... connect resumed>) = -1 EINVAL (Invalid argument)
+
+As sk->state is TCP_CLOSE and sock->state is SS_UNCONNECTED, the
+following listen() succeeds. Then, the first connect() looks up
+itself as a listener and puts skb into the queue with skb->sk itself.
+As a result, the next accept() gets another FD of itself as 3, and
+the first connect() finishes.
+
+ [pid 5060] listen(4, 0 <unfinished ...>
+ [pid 5060] <... listen resumed>) = 0
+ [pid 5060] accept(4, NULL, NULL <unfinished ...>
+ [pid 5060] <... accept resumed>) = 3
+ [pid 5059] <... connect resumed>) = 0
+
+Then, accept4() is called but blocked, which causes the general protection
+fault later.
+
+ [pid 5059] accept4(4, NULL, 0x20000400, SOCK_NONBLOCK <unfinished ...>
+
+After that, another self-accept occurs by accept() and writev().
+
+ [pid 5060] accept(4, NULL, NULL <unfinished ...>
+ [pid 5061] writev(3, [{iov_base=...}] <unfinished ...>
+ [pid 5061] <... writev resumed>) = 99
+ [pid 5060] <... accept resumed>) = 6
+
+Finally, the leader thread close()s all FDs. Since the three FDs
+reference the same socket, nr_release() does the cleanup for it
+three times, and the remaining accept4() causes the following fault.
+
+ [pid 5058] close(3) = 0
+ [pid 5058] close(4) = 0
+ [pid 5058] close(5) = -1 EBADF (Bad file descriptor)
+ [pid 5058] close(6) = 0
+ [pid 5058] <... exit_group resumed>) = ?
+ [ 83.456055][ T5059] general protection fault, probably for non-canonical address 0xdffffc0000000003: 0000 [#1] PREEMPT SMP KASAN
+
+To avoid the issue, we need to return an error for connect() if
+another connect() is in progress, as done in __inet_stream_connect().
+
+[0]:
+general protection fault, probably for non-canonical address 0xdffffc0000000003: 0000 [#1] PREEMPT SMP KASAN
+KASAN: null-ptr-deref in range [0x0000000000000018-0x000000000000001f]
+CPU: 0 PID: 5059 Comm: syz-executor.0 Not tainted 6.5.0-rc5-syzkaller-00194-gace0ab3a4b54 #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/26/2023
+RIP: 0010:__lock_acquire+0x109/0x5de0 kernel/locking/lockdep.c:5012
+Code: 45 85 c9 0f 84 cc 0e 00 00 44 8b 05 11 6e 23 0b 45 85 c0 0f 84 be 0d 00 00 48 ba 00 00 00 00 00 fc ff df 4c 89 d1 48 c1 e9 03 <80> 3c 11 00 0f 85 e8 40 00 00 49 81 3a a0 69 48 90 0f 84 96 0d 00
+RSP: 0018:ffffc90003d6f9e0 EFLAGS: 00010006
+RAX: ffff8880244c8000 RBX: 1ffff920007adf6c RCX: 0000000000000003
+RDX: dffffc0000000000 RSI: 0000000000000000 RDI: 0000000000000018
+RBP: 0000000000000001 R08: 0000000000000001 R09: 0000000000000001
+R10: 0000000000000018 R11: 0000000000000000 R12: 0000000000000000
+R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
+FS: 00007f51d519a6c0(0000) GS:ffff8880b9800000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 00007f51d5158d58 CR3: 000000002943f000 CR4: 00000000003506f0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+Call Trace:
+ <TASK>
+ lock_acquire kernel/locking/lockdep.c:5761 [inline]
+ lock_acquire+0x1ae/0x510 kernel/locking/lockdep.c:5726
+ __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline]
+ _raw_spin_lock_irqsave+0x3a/0x50 kernel/locking/spinlock.c:162
+ prepare_to_wait+0x47/0x380 kernel/sched/wait.c:269
+ nr_accept+0x20d/0x650 net/netrom/af_netrom.c:798
+ do_accept+0x3a6/0x570 net/socket.c:1872
+ __sys_accept4_file net/socket.c:1913 [inline]
+ __sys_accept4+0x99/0x120 net/socket.c:1943
+ __do_sys_accept4 net/socket.c:1954 [inline]
+ __se_sys_accept4 net/socket.c:1951 [inline]
+ __x64_sys_accept4+0x96/0x100 net/socket.c:1951
+ do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+ do_syscall_64+0x38/0xb0 arch/x86/entry/common.c:80
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+RIP: 0033:0x7f51d447cae9
+Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 e1 20 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48
+RSP: 002b:00007f51d519a0c8 EFLAGS: 00000246 ORIG_RAX: 0000000000000120
+RAX: ffffffffffffffda RBX: 00007f51d459bf80 RCX: 00007f51d447cae9
+RDX: 0000000020000400 RSI: 0000000000000000 RDI: 0000000000000004
+RBP: 00007f51d44c847a R08: 0000000000000000 R09: 0000000000000000
+R10: 0000000000000800 R11: 0000000000000246 R12: 0000000000000000
+R13: 000000000000000b R14: 00007f51d459bf80 R15: 00007ffc25c34e48
+ </TASK>
+
+Link: https://syzkaller.appspot.com/text?tag=CrashLog&x=152cdb63a80000 [1]
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+666c97e4686410e79649@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=666c97e4686410e79649
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netrom/af_netrom.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
+index 5a4cb796150f5..ec5747969f964 100644
+--- a/net/netrom/af_netrom.c
++++ b/net/netrom/af_netrom.c
+@@ -660,6 +660,11 @@ static int nr_connect(struct socket *sock, struct sockaddr *uaddr,
+ goto out_release;
+ }
+
++ if (sock->state == SS_CONNECTING) {
++ err = -EALREADY;
++ goto out_release;
++ }
++
+ sk->sk_state = TCP_CLOSE;
+ sock->state = SS_UNCONNECTED;
+
+--
+2.40.1
+
--- /dev/null
+From 969c8baa803bea27b301faf83ae17356ea8288c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Jul 2023 11:08:46 +0300
+Subject: nfs/blocklayout: Use the passed in gfp flags
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 08b45fcb2d4675f6182fe0edc0d8b1fe604051fa ]
+
+This allocation should use the passed in GFP_ flags instead of
+GFP_KERNEL. One places where this matters is in filelayout_pg_init_write()
+which uses GFP_NOFS as the allocation flags.
+
+Fixes: 5c83746a0cf2 ("pnfs/blocklayout: in-kernel GETDEVICEINFO XDR parsing")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/blocklayout/dev.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/fs/nfs/blocklayout/dev.c b/fs/nfs/blocklayout/dev.c
+index fea5f8821da5e..ce2ea62397972 100644
+--- a/fs/nfs/blocklayout/dev.c
++++ b/fs/nfs/blocklayout/dev.c
+@@ -402,7 +402,7 @@ bl_parse_concat(struct nfs_server *server, struct pnfs_block_dev *d,
+ int ret, i;
+
+ d->children = kcalloc(v->concat.volumes_count,
+- sizeof(struct pnfs_block_dev), GFP_KERNEL);
++ sizeof(struct pnfs_block_dev), gfp_mask);
+ if (!d->children)
+ return -ENOMEM;
+
+@@ -431,7 +431,7 @@ bl_parse_stripe(struct nfs_server *server, struct pnfs_block_dev *d,
+ int ret, i;
+
+ d->children = kcalloc(v->stripe.volumes_count,
+- sizeof(struct pnfs_block_dev), GFP_KERNEL);
++ sizeof(struct pnfs_block_dev), gfp_mask);
+ if (!d->children)
+ return -ENOMEM;
+
+--
+2.40.1
+
--- /dev/null
+From 916a2e7e0e9ff0bd6ec4f41e8b715710f1bda029 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Aug 2023 14:22:38 -0400
+Subject: NFS: Guard against READDIR loop when entry names exceed MAXNAMELEN
+
+From: Benjamin Coddington <bcodding@redhat.com>
+
+[ Upstream commit f67b55b6588bcf9316a1e6e8d529100a5aa3ebe6 ]
+
+Commit 64cfca85bacd asserts the only valid return values for
+nfs2/3_decode_dirent should not include -ENAMETOOLONG, but for a server
+that sends a filename3 which exceeds MAXNAMELEN in a READDIR response the
+client's behavior will be to endlessly retry the operation.
+
+We could map -ENAMETOOLONG into -EBADCOOKIE, but that would produce
+truncated listings without any error. The client should return an error
+for this case to clearly assert that the server implementation must be
+corrected.
+
+Fixes: 64cfca85bacd ("NFS: Return valid errors from nfs2/3_decode_dirent()")
+Signed-off-by: Benjamin Coddington <bcodding@redhat.com>
+Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/nfs2xdr.c | 2 +-
+ fs/nfs/nfs3xdr.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
+index 05c3b4b2b3dd8..c190938142960 100644
+--- a/fs/nfs/nfs2xdr.c
++++ b/fs/nfs/nfs2xdr.c
+@@ -949,7 +949,7 @@ int nfs2_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
+
+ error = decode_filename_inline(xdr, &entry->name, &entry->len);
+ if (unlikely(error))
+- return -EAGAIN;
++ return error == -ENAMETOOLONG ? -ENAMETOOLONG : -EAGAIN;
+
+ /*
+ * The type (size and byte order) of nfscookie isn't defined in
+diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c
+index 3b0b650c9c5ab..60f032be805ae 100644
+--- a/fs/nfs/nfs3xdr.c
++++ b/fs/nfs/nfs3xdr.c
+@@ -1991,7 +1991,7 @@ int nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
+
+ error = decode_inline_filename3(xdr, &entry->name, &entry->len);
+ if (unlikely(error))
+- return -EAGAIN;
++ return error == -ENAMETOOLONG ? -ENAMETOOLONG : -EAGAIN;
+
+ error = decode_cookie3(xdr, &new_cookie);
+ if (unlikely(error))
+--
+2.40.1
+
--- /dev/null
+From 7cc482bca34d86f7903d01be7597c85f609c3c10 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Aug 2023 10:20:52 -0400
+Subject: NFSD: da_addr_body field missing in some GETDEVICEINFO replies
+
+From: Chuck Lever <chuck.lever@oracle.com>
+
+[ Upstream commit 6372e2ee629894433fe6107d7048536a3280a284 ]
+
+The XDR specification in RFC 8881 looks like this:
+
+struct device_addr4 {
+ layouttype4 da_layout_type;
+ opaque da_addr_body<>;
+};
+
+struct GETDEVICEINFO4resok {
+ device_addr4 gdir_device_addr;
+ bitmap4 gdir_notification;
+};
+
+union GETDEVICEINFO4res switch (nfsstat4 gdir_status) {
+case NFS4_OK:
+ GETDEVICEINFO4resok gdir_resok4;
+case NFS4ERR_TOOSMALL:
+ count4 gdir_mincount;
+default:
+ void;
+};
+
+Looking at nfsd4_encode_getdeviceinfo() ....
+
+When the client provides a zero gd_maxcount, then the Linux NFS
+server implementation encodes the da_layout_type field and then
+skips the da_addr_body field completely, proceeding directly to
+encode gdir_notification field.
+
+There does not appear to be an option in the specification to skip
+encoding da_addr_body. Moreover, Section 18.40.3 says:
+
+> If the client wants to just update or turn off notifications, it
+> MAY send a GETDEVICEINFO operation with gdia_maxcount set to zero.
+> In that event, if the device ID is valid, the reply's da_addr_body
+> field of the gdir_device_addr field will be of zero length.
+
+Since the layout drivers are responsible for encoding the
+da_addr_body field, put this fix inside the ->encode_getdeviceinfo
+methods.
+
+Fixes: 9cf514ccfacb ("nfsd: implement pNFS operations")
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Cc: Tom Haynes <loghyr@gmail.com>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfsd/blocklayoutxdr.c | 9 +++++++++
+ fs/nfsd/flexfilelayoutxdr.c | 9 +++++++++
+ fs/nfsd/nfs4xdr.c | 25 +++++++++++--------------
+ 3 files changed, 29 insertions(+), 14 deletions(-)
+
+diff --git a/fs/nfsd/blocklayoutxdr.c b/fs/nfsd/blocklayoutxdr.c
+index 8e9c1a0f8d380..1ed2f691ebb90 100644
+--- a/fs/nfsd/blocklayoutxdr.c
++++ b/fs/nfsd/blocklayoutxdr.c
+@@ -83,6 +83,15 @@ nfsd4_block_encode_getdeviceinfo(struct xdr_stream *xdr,
+ int len = sizeof(__be32), ret, i;
+ __be32 *p;
+
++ /*
++ * See paragraph 5 of RFC 8881 S18.40.3.
++ */
++ if (!gdp->gd_maxcount) {
++ if (xdr_stream_encode_u32(xdr, 0) != XDR_UNIT)
++ return nfserr_resource;
++ return nfs_ok;
++ }
++
+ p = xdr_reserve_space(xdr, len + sizeof(__be32));
+ if (!p)
+ return nfserr_resource;
+diff --git a/fs/nfsd/flexfilelayoutxdr.c b/fs/nfsd/flexfilelayoutxdr.c
+index e81d2a5cf381e..bb205328e043d 100644
+--- a/fs/nfsd/flexfilelayoutxdr.c
++++ b/fs/nfsd/flexfilelayoutxdr.c
+@@ -85,6 +85,15 @@ nfsd4_ff_encode_getdeviceinfo(struct xdr_stream *xdr,
+ int addr_len;
+ __be32 *p;
+
++ /*
++ * See paragraph 5 of RFC 8881 S18.40.3.
++ */
++ if (!gdp->gd_maxcount) {
++ if (xdr_stream_encode_u32(xdr, 0) != XDR_UNIT)
++ return nfserr_resource;
++ return nfs_ok;
++ }
++
+ /* len + padding for two strings */
+ addr_len = 16 + da->netaddr.netid_len + da->netaddr.addr_len;
+ ver_len = 20;
+diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
+index ee1a24debd60c..679d9be4abd4d 100644
+--- a/fs/nfsd/nfs4xdr.c
++++ b/fs/nfsd/nfs4xdr.c
+@@ -4681,20 +4681,17 @@ nfsd4_encode_getdeviceinfo(struct nfsd4_compoundres *resp, __be32 nfserr,
+
+ *p++ = cpu_to_be32(gdev->gd_layout_type);
+
+- /* If maxcount is 0 then just update notifications */
+- if (gdev->gd_maxcount != 0) {
+- ops = nfsd4_layout_ops[gdev->gd_layout_type];
+- nfserr = ops->encode_getdeviceinfo(xdr, gdev);
+- if (nfserr) {
+- /*
+- * We don't bother to burden the layout drivers with
+- * enforcing gd_maxcount, just tell the client to
+- * come back with a bigger buffer if it's not enough.
+- */
+- if (xdr->buf->len + 4 > gdev->gd_maxcount)
+- goto toosmall;
+- return nfserr;
+- }
++ ops = nfsd4_layout_ops[gdev->gd_layout_type];
++ nfserr = ops->encode_getdeviceinfo(xdr, gdev);
++ if (nfserr) {
++ /*
++ * We don't bother to burden the layout drivers with
++ * enforcing gd_maxcount, just tell the client to
++ * come back with a bigger buffer if it's not enough.
++ */
++ if (xdr->buf->len + 4 > gdev->gd_maxcount)
++ goto toosmall;
++ return nfserr;
+ }
+
+ if (gdev->gd_notify_types) {
+--
+2.40.1
+
--- /dev/null
+From 885ff8aab16274abc990afbb1c152e730aaaa9b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Aug 2023 16:43:53 -0400
+Subject: NFSv4.2: fix handling of COPY ERR_OFFLOAD_NO_REQ
+
+From: Olga Kornievskaia <kolga@netapp.com>
+
+[ Upstream commit 5690eed941ab7e33c3c3d6b850100cabf740f075 ]
+
+If the client sent a synchronous copy and the server replied with
+ERR_OFFLOAD_NO_REQ indicating that it wants an asynchronous
+copy instead, the client should retry with asynchronous copy.
+
+Fixes: 539f57b3e0fd ("NFS handle COPY ERR_OFFLOAD_NO_REQS")
+Signed-off-by: Olga Kornievskaia <kolga@netapp.com>
+Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/nfs42proc.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c
+index 5d7e0511f3513..d5ec3d5568da5 100644
+--- a/fs/nfs/nfs42proc.c
++++ b/fs/nfs/nfs42proc.c
+@@ -471,8 +471,9 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src,
+ continue;
+ }
+ break;
+- } else if (err == -NFS4ERR_OFFLOAD_NO_REQS && !args.sync) {
+- args.sync = true;
++ } else if (err == -NFS4ERR_OFFLOAD_NO_REQS &&
++ args.sync != res.synchronous) {
++ args.sync = res.synchronous;
+ dst_exception.retry = 1;
+ continue;
+ } else if ((err == -ESTALE ||
+--
+2.40.1
+
--- /dev/null
+From 6928a6168f25e09f01ec7ba8950c91bc38b9576c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 May 2023 17:02:54 -0400
+Subject: NFSv4.2: Fix READ_PLUS size calculations
+
+From: Anna Schumaker <Anna.Schumaker@Netapp.com>
+
+[ Upstream commit 8d18f6c5bb864d97a730f471c56cdecf313efe64 ]
+
+I bump the decode_read_plus_maxsz to account for hole segments, but I
+need to subtract out this increase when calling
+rpc_prepare_reply_pages() so the common case of single data segment
+replies can be directly placed into the xdr pages without needing to be
+shifted around.
+
+Reported-by: Chuck Lever <chuck.lever@oracle.com>
+Fixes: d3b00a802c845 ("NFS: Replace the READ_PLUS decoding code")
+Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/nfs42xdr.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/fs/nfs/nfs42xdr.c b/fs/nfs/nfs42xdr.c
+index ef3b150970ff6..75765382cc0e6 100644
+--- a/fs/nfs/nfs42xdr.c
++++ b/fs/nfs/nfs42xdr.c
+@@ -51,10 +51,16 @@
+ (1 /* data_content4 */ + \
+ 2 /* data_info4.di_offset */ + \
+ 1 /* data_info4.di_length */)
++#define NFS42_READ_PLUS_HOLE_SEGMENT_SIZE \
++ (1 /* data_content4 */ + \
++ 2 /* data_info4.di_offset */ + \
++ 2 /* data_info4.di_length */)
++#define READ_PLUS_SEGMENT_SIZE_DIFF (NFS42_READ_PLUS_HOLE_SEGMENT_SIZE - \
++ NFS42_READ_PLUS_DATA_SEGMENT_SIZE)
+ #define decode_read_plus_maxsz (op_decode_hdr_maxsz + \
+ 1 /* rpr_eof */ + \
+ 1 /* rpr_contents count */ + \
+- NFS42_READ_PLUS_DATA_SEGMENT_SIZE)
++ NFS42_READ_PLUS_HOLE_SEGMENT_SIZE)
+ #define encode_seek_maxsz (op_encode_hdr_maxsz + \
+ encode_stateid_maxsz + \
+ 2 /* offset */ + \
+@@ -781,8 +787,8 @@ static void nfs4_xdr_enc_read_plus(struct rpc_rqst *req,
+ encode_putfh(xdr, args->fh, &hdr);
+ encode_read_plus(xdr, args, &hdr);
+
+- rpc_prepare_reply_pages(req, args->pages, args->pgbase,
+- args->count, hdr.replen);
++ rpc_prepare_reply_pages(req, args->pages, args->pgbase, args->count,
++ hdr.replen - READ_PLUS_SEGMENT_SIZE_DIFF);
+ encode_nops(&hdr);
+ }
+
+--
+2.40.1
+
--- /dev/null
+From 889d59f19fb66d2a13338069fd2df847e3151512 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 May 2023 17:27:08 -0400
+Subject: NFSv4.2: Fix READ_PLUS smatch warnings
+
+From: Anna Schumaker <Anna.Schumaker@Netapp.com>
+
+[ Upstream commit bb05a617f06b7a882e19c4f475b8e37f14d9ceac ]
+
+Smatch reports:
+ fs/nfs/nfs42xdr.c:1131 decode_read_plus() warn: missing error code? 'status'
+
+Which Dan suggests to fix by doing a hardcoded "return 0" from the
+"if (segments == 0)" check.
+
+Additionally, smatch reports that the "status = -EIO" assignment is not
+used. This patch addresses both these issues.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Reported-by: Dan Carpenter <error27@gmail.com>
+Closes: https://lore.kernel.org/r/202305222209.6l5VM2lL-lkp@intel.com/
+Fixes: d3b00a802c845 ("NFS: Replace the READ_PLUS decoding code")
+Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/nfs42xdr.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/fs/nfs/nfs42xdr.c b/fs/nfs/nfs42xdr.c
+index a6df815a140c7..ef3b150970ff6 100644
+--- a/fs/nfs/nfs42xdr.c
++++ b/fs/nfs/nfs42xdr.c
+@@ -1136,13 +1136,12 @@ static int decode_read_plus(struct xdr_stream *xdr, struct nfs_pgio_res *res)
+ res->eof = be32_to_cpup(p++);
+ segments = be32_to_cpup(p++);
+ if (segments == 0)
+- return status;
++ return 0;
+
+ segs = kmalloc_array(segments, sizeof(*segs), GFP_KERNEL);
+ if (!segs)
+ return -ENOMEM;
+
+- status = -EIO;
+ for (i = 0; i < segments; i++) {
+ status = decode_read_plus_segment(xdr, &segs[i]);
+ if (status < 0)
+--
+2.40.1
+
--- /dev/null
+From 687f69ca66e914f83bea5a1fe71664ab823e73b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Jun 2023 15:26:25 -0400
+Subject: NFSv4.2: Rework scratch handling for READ_PLUS (again)
+
+From: Anna Schumaker <Anna.Schumaker@Netapp.com>
+
+[ Upstream commit 303a78052091c81e9003915c521fdca1c7e117af ]
+
+I found that the read code might send multiple requests using the same
+nfs_pgio_header, but nfs4_proc_read_setup() is only called once. This is
+how we ended up occasionally double-freeing the scratch buffer, but also
+means we set a NULL pointer but non-zero length to the xdr scratch
+buffer. This results in an oops the first time decoding needs to copy
+something to scratch, which frequently happens when decoding READ_PLUS
+hole segments.
+
+I fix this by moving scratch handling into the pageio read code. I
+provide a function to allocate scratch space for decoding read replies,
+and free the scratch buffer when the nfs_pgio_header is freed.
+
+Fixes: fbd2a05f29a9 (NFSv4.2: Rework scratch handling for READ_PLUS)
+Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/internal.h | 1 +
+ fs/nfs/nfs42.h | 1 +
+ fs/nfs/nfs42xdr.c | 2 +-
+ fs/nfs/nfs4proc.c | 13 +------------
+ fs/nfs/read.c | 10 ++++++++++
+ 5 files changed, 14 insertions(+), 13 deletions(-)
+
+diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
+index 3cc027d3bd588..1607c23f68d41 100644
+--- a/fs/nfs/internal.h
++++ b/fs/nfs/internal.h
+@@ -489,6 +489,7 @@ extern const struct nfs_pgio_completion_ops nfs_async_read_completion_ops;
+ extern void nfs_pageio_init_read(struct nfs_pageio_descriptor *pgio,
+ struct inode *inode, bool force_mds,
+ const struct nfs_pgio_completion_ops *compl_ops);
++extern bool nfs_read_alloc_scratch(struct nfs_pgio_header *hdr, size_t size);
+ extern int nfs_read_add_folio(struct nfs_pageio_descriptor *pgio,
+ struct nfs_open_context *ctx,
+ struct folio *folio);
+diff --git a/fs/nfs/nfs42.h b/fs/nfs/nfs42.h
+index 0fe5aacbcfdf1..b59876b01a1e3 100644
+--- a/fs/nfs/nfs42.h
++++ b/fs/nfs/nfs42.h
+@@ -13,6 +13,7 @@
+ * more? Need to consider not to pre-alloc too much for a compound.
+ */
+ #define PNFS_LAYOUTSTATS_MAXDEV (4)
++#define READ_PLUS_SCRATCH_SIZE (16)
+
+ /* nfs4.2proc.c */
+ #ifdef CONFIG_NFS_V4_2
+diff --git a/fs/nfs/nfs42xdr.c b/fs/nfs/nfs42xdr.c
+index 75765382cc0e6..20aa5e746497d 100644
+--- a/fs/nfs/nfs42xdr.c
++++ b/fs/nfs/nfs42xdr.c
+@@ -1351,7 +1351,7 @@ static int nfs4_xdr_dec_read_plus(struct rpc_rqst *rqstp,
+ struct compound_hdr hdr;
+ int status;
+
+- xdr_set_scratch_buffer(xdr, res->scratch, sizeof(res->scratch));
++ xdr_set_scratch_buffer(xdr, res->scratch, READ_PLUS_SCRATCH_SIZE);
+
+ status = decode_compound_hdr(xdr, &hdr);
+ if (status)
+diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
+index fd752e0c4ec24..43d458965330f 100644
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -5438,18 +5438,8 @@ static bool nfs4_read_plus_not_supported(struct rpc_task *task,
+ return false;
+ }
+
+-static inline void nfs4_read_plus_scratch_free(struct nfs_pgio_header *hdr)
+-{
+- if (hdr->res.scratch) {
+- kfree(hdr->res.scratch);
+- hdr->res.scratch = NULL;
+- }
+-}
+-
+ static int nfs4_read_done(struct rpc_task *task, struct nfs_pgio_header *hdr)
+ {
+- nfs4_read_plus_scratch_free(hdr);
+-
+ if (!nfs4_sequence_done(task, &hdr->res.seq_res))
+ return -EAGAIN;
+ if (nfs4_read_stateid_changed(task, &hdr->args))
+@@ -5469,8 +5459,7 @@ static bool nfs42_read_plus_support(struct nfs_pgio_header *hdr,
+ /* Note: We don't use READ_PLUS with pNFS yet */
+ if (nfs_server_capable(hdr->inode, NFS_CAP_READ_PLUS) && !hdr->ds_clp) {
+ msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ_PLUS];
+- hdr->res.scratch = kmalloc(32, GFP_KERNEL);
+- return hdr->res.scratch != NULL;
++ return nfs_read_alloc_scratch(hdr, READ_PLUS_SCRATCH_SIZE);
+ }
+ return false;
+ }
+diff --git a/fs/nfs/read.c b/fs/nfs/read.c
+index f71eeee67e201..7dc21a48e3e7b 100644
+--- a/fs/nfs/read.c
++++ b/fs/nfs/read.c
+@@ -47,6 +47,8 @@ static struct nfs_pgio_header *nfs_readhdr_alloc(void)
+
+ static void nfs_readhdr_free(struct nfs_pgio_header *rhdr)
+ {
++ if (rhdr->res.scratch != NULL)
++ kfree(rhdr->res.scratch);
+ kmem_cache_free(nfs_rdata_cachep, rhdr);
+ }
+
+@@ -108,6 +110,14 @@ void nfs_pageio_reset_read_mds(struct nfs_pageio_descriptor *pgio)
+ }
+ EXPORT_SYMBOL_GPL(nfs_pageio_reset_read_mds);
+
++bool nfs_read_alloc_scratch(struct nfs_pgio_header *hdr, size_t size)
++{
++ WARN_ON(hdr->res.scratch != NULL);
++ hdr->res.scratch = kmalloc(size, GFP_KERNEL);
++ return hdr->res.scratch != NULL;
++}
++EXPORT_SYMBOL_GPL(nfs_read_alloc_scratch);
++
+ static void nfs_readpage_release(struct nfs_page *req, int error)
+ {
+ struct folio *folio = nfs_page_to_folio(req);
+--
+2.40.1
+
--- /dev/null
+From dd917ddd3162f28e48d6057bbb02c91c9902b306 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Aug 2023 19:41:03 +0800
+Subject: nvdimm: Fix dereference after free in register_nvdimm_pmu()
+
+From: Konstantin Meskhidze <konstantin.meskhidze@huawei.com>
+
+[ Upstream commit 08ca6906a4b7e48f8e93b7c1f49a742a415be6d5 ]
+
+'nd_pmu->pmu.attr_groups' is dereferenced in function
+'nvdimm_pmu_free_hotplug_memory' call after it has been freed. Because in
+function 'nvdimm_pmu_free_hotplug_memory' memory pointed by the fields of
+'nd_pmu->pmu.attr_groups' is deallocated it is necessary to call 'kfree'
+after 'nvdimm_pmu_free_hotplug_memory'.
+
+Fixes: 0fab1ba6ad6b ("drivers/nvdimm: Add perf interface to expose nvdimm performance stats")
+Co-developed-by: Ivanov Mikhail <ivanov.mikhail1@huawei-partners.com>
+Signed-off-by: Konstantin Meskhidze <konstantin.meskhidze@huawei.com>
+Reviewed-by: Jeff Moyer <jmoyer@redhat.com>
+Link: https://lore.kernel.org/r/20230817114103.754977-1-konstantin.meskhidze@huawei.com
+Signed-off-by: Dave Jiang <dave.jiang@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvdimm/nd_perf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/nvdimm/nd_perf.c b/drivers/nvdimm/nd_perf.c
+index 14881c4e03e6b..2b6dc80d8fb5b 100644
+--- a/drivers/nvdimm/nd_perf.c
++++ b/drivers/nvdimm/nd_perf.c
+@@ -308,8 +308,8 @@ int register_nvdimm_pmu(struct nvdimm_pmu *nd_pmu, struct platform_device *pdev)
+
+ rc = perf_pmu_register(&nd_pmu->pmu, nd_pmu->pmu.name, -1);
+ if (rc) {
+- kfree(nd_pmu->pmu.attr_groups);
+ nvdimm_pmu_free_hotplug_memory(nd_pmu);
++ kfree(nd_pmu->pmu.attr_groups);
+ return rc;
+ }
+
+--
+2.40.1
+
--- /dev/null
+From c6c866c1619990df0017670442f53c4d346d8b0f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Aug 2023 19:59:45 +0800
+Subject: nvdimm: Fix memleak of pmu attr_groups in unregister_nvdimm_pmu()
+
+From: Konstantin Meskhidze <konstantin.meskhidze@huawei.com>
+
+[ Upstream commit 85ae42c72142346645e63c33835da947dfa008b3 ]
+
+Memory pointed by 'nd_pmu->pmu.attr_groups' is allocated in function
+'register_nvdimm_pmu' and is lost after 'kfree(nd_pmu)' call in function
+'unregister_nvdimm_pmu'.
+
+Fixes: 0fab1ba6ad6b ("drivers/nvdimm: Add perf interface to expose nvdimm performance stats")
+Co-developed-by: Ivanov Mikhail <ivanov.mikhail1@huawei-partners.com>
+Signed-off-by: Konstantin Meskhidze <konstantin.meskhidze@huawei.com>
+Reviewed-by: Jeff Moyer <jmoyer@redhat.com>
+Link: https://lore.kernel.org/r/20230817115945.771826-1-konstantin.meskhidze@huawei.com
+Signed-off-by: Dave Jiang <dave.jiang@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvdimm/nd_perf.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/nvdimm/nd_perf.c b/drivers/nvdimm/nd_perf.c
+index 433bbb68ae641..14881c4e03e6b 100644
+--- a/drivers/nvdimm/nd_perf.c
++++ b/drivers/nvdimm/nd_perf.c
+@@ -324,6 +324,7 @@ void unregister_nvdimm_pmu(struct nvdimm_pmu *nd_pmu)
+ {
+ perf_pmu_unregister(&nd_pmu->pmu);
+ nvdimm_pmu_free_hotplug_memory(nd_pmu);
++ kfree(nd_pmu->pmu.attr_groups);
+ kfree(nd_pmu);
+ }
+ EXPORT_SYMBOL_GPL(unregister_nvdimm_pmu);
+--
+2.40.1
+
--- /dev/null
+From 6149126bb9e2c4bb68254047ccee6bec52b9ffa3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Aug 2023 14:27:42 +0100
+Subject: nvmem: core: Return NULL when no nvmem layout is found
+
+From: Miquel Raynal <miquel.raynal@bootlin.com>
+
+[ Upstream commit 81e1d9a39569d315f747c2af19ce502cd08645ed ]
+
+Currently, of_nvmem_layout_get_container() returns NULL on error, or an
+error pointer if either CONFIG_NVMEM or CONFIG_OF is turned off. We
+should likely avoid this kind of mix for two reasons: to clarify the
+intend and anyway fix the !CONFIG_OF which will likely always if we use
+this helper somewhere else. Let's just return NULL when no layout is
+found, we don't need an error value here.
+
+Link: https://staticthinking.wordpress.com/2022/08/01/mixing-error-pointers-and-null/
+Fixes: 266570f496b9 ("nvmem: core: introduce NVMEM layouts")
+Reported-by: kernel test robot <lkp@intel.com>
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Closes: https://lore.kernel.org/r/202308030002.DnSFOrMB-lkp@intel.com/
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Reviewed-by: Michael Walle <michael@walle.cc>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20230823132744.350618-21-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/nvmem-consumer.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/linux/nvmem-consumer.h b/include/linux/nvmem-consumer.h
+index fa030d93b768e..27373024856dc 100644
+--- a/include/linux/nvmem-consumer.h
++++ b/include/linux/nvmem-consumer.h
+@@ -256,7 +256,7 @@ static inline struct nvmem_device *of_nvmem_device_get(struct device_node *np,
+ static inline struct device_node *
+ of_nvmem_layout_get_container(struct nvmem_device *nvmem)
+ {
+- return ERR_PTR(-EOPNOTSUPP);
++ return NULL;
+ }
+ #endif /* CONFIG_NVMEM && CONFIG_OF */
+
+--
+2.40.1
+
--- /dev/null
+From 4506187e620458bc57bc30ebccfac4efffaed696 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Aug 2023 13:40:31 +0530
+Subject: octeontx2-af: CN10KB: fix PFC configuration
+
+From: Hariprasad Kelam <hkelam@marvell.com>
+
+[ Upstream commit 47bcc9c1cf6aa60156c7532983090e86d9d171b6 ]
+
+Suppose user has enabled pfc with prio 0,1 on a PF netdev(eth0)
+ dcb pfc set dev eth0 prio-pfc o:on 1:on
+later user enabled pfc priorities 2 and 3 on the VF interface(eth1)
+ dcb pfc set dev eth1 prio-pfc 2:on 3:on
+
+Instead of enabling pfc on all priorities (0..3), the driver only
+enables on priorities 2,3. This patch corrects the issue by using
+the proper CSR address.
+
+Fixes: b9d0fedc6234 ("octeontx2-af: cn10kb: Add RPM_USX MAC support")
+Signed-off-by: Hariprasad Kelam <hkelam@marvell.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://lore.kernel.org/r/20230824081032.436432-3-sumang@marvell.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/octeontx2/af/rpm.c | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rpm.c b/drivers/net/ethernet/marvell/octeontx2/af/rpm.c
+index b4fcb20c3f4fd..af21e2030cff2 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rpm.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rpm.c
+@@ -355,8 +355,8 @@ int rpm_lmac_enadis_pause_frm(void *rpmd, int lmac_id, u8 tx_pause,
+
+ void rpm_lmac_pause_frm_config(void *rpmd, int lmac_id, bool enable)
+ {
++ u64 cfg, pfc_class_mask_cfg;
+ rpm_t *rpm = rpmd;
+- u64 cfg;
+
+ /* ALL pause frames received are completely ignored */
+ cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG);
+@@ -380,9 +380,11 @@ void rpm_lmac_pause_frm_config(void *rpmd, int lmac_id, bool enable)
+ rpm_write(rpm, 0, RPMX_CMR_CHAN_MSK_OR, ~0ULL);
+
+ /* Disable all PFC classes */
+- cfg = rpm_read(rpm, lmac_id, RPMX_CMRX_PRT_CBFC_CTL);
++ pfc_class_mask_cfg = is_dev_rpm2(rpm) ? RPM2_CMRX_PRT_CBFC_CTL :
++ RPMX_CMRX_PRT_CBFC_CTL;
++ cfg = rpm_read(rpm, lmac_id, pfc_class_mask_cfg);
+ cfg = FIELD_SET(RPM_PFC_CLASS_MASK, 0, cfg);
+- rpm_write(rpm, lmac_id, RPMX_CMRX_PRT_CBFC_CTL, cfg);
++ rpm_write(rpm, lmac_id, pfc_class_mask_cfg, cfg);
+ }
+
+ int rpm_get_rx_stats(void *rpmd, int lmac_id, int idx, u64 *rx_stat)
+@@ -605,8 +607,11 @@ int rpm_lmac_pfc_config(void *rpmd, int lmac_id, u8 tx_pause, u8 rx_pause, u16 p
+ if (!is_lmac_valid(rpm, lmac_id))
+ return -ENODEV;
+
++ pfc_class_mask_cfg = is_dev_rpm2(rpm) ? RPM2_CMRX_PRT_CBFC_CTL :
++ RPMX_CMRX_PRT_CBFC_CTL;
++
+ cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG);
+- class_en = rpm_read(rpm, lmac_id, RPMX_CMRX_PRT_CBFC_CTL);
++ class_en = rpm_read(rpm, lmac_id, pfc_class_mask_cfg);
+ pfc_en |= FIELD_GET(RPM_PFC_CLASS_MASK, class_en);
+
+ if (rx_pause) {
+@@ -635,10 +640,6 @@ int rpm_lmac_pfc_config(void *rpmd, int lmac_id, u8 tx_pause, u8 rx_pause, u16 p
+ cfg |= RPMX_MTI_MAC100X_COMMAND_CONFIG_PFC_MODE;
+
+ rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg);
+-
+- pfc_class_mask_cfg = is_dev_rpm2(rpm) ? RPM2_CMRX_PRT_CBFC_CTL :
+- RPMX_CMRX_PRT_CBFC_CTL;
+-
+ rpm_write(rpm, lmac_id, pfc_class_mask_cfg, class_en);
+
+ return 0;
+--
+2.40.1
+
--- /dev/null
+From bc789e965af22f3602cc57921627a344d5e5ca72 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Aug 2023 13:40:30 +0530
+Subject: octeontx2-pf: Fix PFC TX scheduler free
+
+From: Suman Ghosh <sumang@marvell.com>
+
+[ Upstream commit a9ac2e18779597f280d68a5b5f5bdd51a34080fa ]
+
+During PFC TX schedulers free, flag TXSCHQ_FREE_ALL was being set
+which caused free up all schedulers other than the PFC schedulers.
+This patch fixes that to free only the PFC Tx schedulers.
+
+Fixes: 99c969a83d82 ("octeontx2-pf: Add egress PFC support")
+Signed-off-by: Suman Ghosh <sumang@marvell.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://lore.kernel.org/r/20230824081032.436432-2-sumang@marvell.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/marvell/octeontx2/nic/otx2_common.c | 1 +
+ .../ethernet/marvell/octeontx2/nic/otx2_dcbnl.c | 15 ++++-----------
+ 2 files changed, 5 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
+index dd97731f81698..011355e73696e 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
+@@ -773,6 +773,7 @@ void otx2_txschq_free_one(struct otx2_nic *pfvf, u16 lvl, u16 schq)
+
+ mutex_unlock(&pfvf->mbox.lock);
+ }
++EXPORT_SYMBOL(otx2_txschq_free_one);
+
+ void otx2_txschq_stop(struct otx2_nic *pfvf)
+ {
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_dcbnl.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_dcbnl.c
+index ccaf97bb1ce03..6492749dd7c89 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_dcbnl.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_dcbnl.c
+@@ -125,19 +125,12 @@ int otx2_pfc_txschq_alloc(struct otx2_nic *pfvf)
+
+ static int otx2_pfc_txschq_stop_one(struct otx2_nic *pfvf, u8 prio)
+ {
+- struct nix_txsch_free_req *free_req;
++ int lvl;
+
+- mutex_lock(&pfvf->mbox.lock);
+ /* free PFC TLx nodes */
+- free_req = otx2_mbox_alloc_msg_nix_txsch_free(&pfvf->mbox);
+- if (!free_req) {
+- mutex_unlock(&pfvf->mbox.lock);
+- return -ENOMEM;
+- }
+-
+- free_req->flags = TXSCHQ_FREE_ALL;
+- otx2_sync_mbox_msg(&pfvf->mbox);
+- mutex_unlock(&pfvf->mbox.lock);
++ for (lvl = 0; lvl < pfvf->hw.txschq_link_cfg_lvl; lvl++)
++ otx2_txschq_free_one(pfvf, lvl,
++ pfvf->pfc_schq_list[lvl][prio]);
+
+ pfvf->pfc_alloc_status[prio] = false;
+ return 0;
+--
+2.40.1
+
--- /dev/null
+From 4274aecb31bcad5c575311a8d0afc49653a8551e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 13 May 2023 14:21:39 +0530
+Subject: octeontx2-pf: Refactor schedular queue alloc/free calls
+
+From: Hariprasad Kelam <hkelam@marvell.com>
+
+[ Upstream commit 6b4b2ded9c4282deea421eef144ab0ced954721c ]
+
+1. Upon txschq free request, the transmit schedular config in hardware
+is not getting reset. This patch adds necessary changes to do the same.
+
+2. Current implementation calls txschq alloc during interface
+initialization and in response handler updates the default txschq array.
+This creates a problem for htb offload where txsch alloc will be called
+for every tc class. This patch addresses the issue by reading txschq
+response in mbox caller function instead in the response handler.
+
+3. Current otx2_txschq_stop routine tries to free all txschq nodes
+allocated to the interface. This creates a problem for htb offload.
+This patch introduces the otx2_txschq_free_one to free txschq in a
+given level.
+
+Signed-off-by: Hariprasad Kelam <hkelam@marvell.com>
+Signed-off-by: Naveen Mamindlapalli <naveenm@marvell.com>
+Signed-off-by: Sunil Kovvuri Goutham <sgoutham@marvell.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: a9ac2e187795 ("octeontx2-pf: Fix PFC TX scheduler free")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/marvell/octeontx2/af/rvu_nix.c | 45 +++++++++++++
+ .../marvell/octeontx2/nic/otx2_common.c | 67 ++++++++++++-------
+ .../marvell/octeontx2/nic/otx2_common.h | 3 +-
+ .../ethernet/marvell/octeontx2/nic/otx2_pf.c | 13 +---
+ .../ethernet/marvell/octeontx2/nic/otx2_vf.c | 4 --
+ 5 files changed, 94 insertions(+), 38 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
+index 49c1dbe5ec788..43f6d1b50d2ad 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
+@@ -1691,6 +1691,42 @@ handle_txschq_shaper_update(struct rvu *rvu, int blkaddr, int nixlf,
+ return true;
+ }
+
++static void nix_reset_tx_schedule(struct rvu *rvu, int blkaddr,
++ int lvl, int schq)
++{
++ u64 tlx_parent = 0, tlx_schedule = 0;
++
++ switch (lvl) {
++ case NIX_TXSCH_LVL_TL2:
++ tlx_parent = NIX_AF_TL2X_PARENT(schq);
++ tlx_schedule = NIX_AF_TL2X_SCHEDULE(schq);
++ break;
++ case NIX_TXSCH_LVL_TL3:
++ tlx_parent = NIX_AF_TL3X_PARENT(schq);
++ tlx_schedule = NIX_AF_TL3X_SCHEDULE(schq);
++ break;
++ case NIX_TXSCH_LVL_TL4:
++ tlx_parent = NIX_AF_TL4X_PARENT(schq);
++ tlx_schedule = NIX_AF_TL4X_SCHEDULE(schq);
++ break;
++ case NIX_TXSCH_LVL_MDQ:
++ /* no need to reset SMQ_CFG as HW clears this CSR
++ * on SMQ flush
++ */
++ tlx_parent = NIX_AF_MDQX_PARENT(schq);
++ tlx_schedule = NIX_AF_MDQX_SCHEDULE(schq);
++ break;
++ default:
++ return;
++ }
++
++ if (tlx_parent)
++ rvu_write64(rvu, blkaddr, tlx_parent, 0x0);
++
++ if (tlx_schedule)
++ rvu_write64(rvu, blkaddr, tlx_schedule, 0x0);
++}
++
+ /* Disable shaping of pkts by a scheduler queue
+ * at a given scheduler level.
+ */
+@@ -2040,6 +2076,7 @@ int rvu_mbox_handler_nix_txsch_alloc(struct rvu *rvu,
+ pfvf_map[schq] = TXSCH_MAP(pcifunc, 0);
+ nix_reset_tx_linkcfg(rvu, blkaddr, lvl, schq);
+ nix_reset_tx_shaping(rvu, blkaddr, nixlf, lvl, schq);
++ nix_reset_tx_schedule(rvu, blkaddr, lvl, schq);
+ }
+
+ for (idx = 0; idx < req->schq[lvl]; idx++) {
+@@ -2049,6 +2086,7 @@ int rvu_mbox_handler_nix_txsch_alloc(struct rvu *rvu,
+ pfvf_map[schq] = TXSCH_MAP(pcifunc, 0);
+ nix_reset_tx_linkcfg(rvu, blkaddr, lvl, schq);
+ nix_reset_tx_shaping(rvu, blkaddr, nixlf, lvl, schq);
++ nix_reset_tx_schedule(rvu, blkaddr, lvl, schq);
+ }
+ }
+
+@@ -2144,6 +2182,7 @@ static int nix_txschq_free(struct rvu *rvu, u16 pcifunc)
+ continue;
+ nix_reset_tx_linkcfg(rvu, blkaddr, lvl, schq);
+ nix_clear_tx_xoff(rvu, blkaddr, lvl, schq);
++ nix_reset_tx_shaping(rvu, blkaddr, nixlf, lvl, schq);
+ }
+ }
+ nix_clear_tx_xoff(rvu, blkaddr, NIX_TXSCH_LVL_TL1,
+@@ -2182,6 +2221,7 @@ static int nix_txschq_free(struct rvu *rvu, u16 pcifunc)
+ for (schq = 0; schq < txsch->schq.max; schq++) {
+ if (TXSCH_MAP_FUNC(txsch->pfvf_map[schq]) != pcifunc)
+ continue;
++ nix_reset_tx_schedule(rvu, blkaddr, lvl, schq);
+ rvu_free_rsrc(&txsch->schq, schq);
+ txsch->pfvf_map[schq] = TXSCH_MAP(0, NIX_TXSCHQ_FREE);
+ }
+@@ -2241,6 +2281,9 @@ static int nix_txschq_free_one(struct rvu *rvu,
+ */
+ nix_clear_tx_xoff(rvu, blkaddr, lvl, schq);
+
++ nix_reset_tx_linkcfg(rvu, blkaddr, lvl, schq);
++ nix_reset_tx_shaping(rvu, blkaddr, nixlf, lvl, schq);
++
+ /* Flush if it is a SMQ. Onus of disabling
+ * TL2/3 queue links before SMQ flush is on user
+ */
+@@ -2250,6 +2293,8 @@ static int nix_txschq_free_one(struct rvu *rvu,
+ goto err;
+ }
+
++ nix_reset_tx_schedule(rvu, blkaddr, lvl, schq);
++
+ /* Free the resource */
+ rvu_free_rsrc(&txsch->schq, schq);
+ txsch->pfvf_map[schq] = TXSCH_MAP(0, NIX_TXSCHQ_FREE);
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
+index 8a41ad8ca04f1..dd97731f81698 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
+@@ -716,7 +716,8 @@ EXPORT_SYMBOL(otx2_smq_flush);
+ int otx2_txsch_alloc(struct otx2_nic *pfvf)
+ {
+ struct nix_txsch_alloc_req *req;
+- int lvl;
++ struct nix_txsch_alloc_rsp *rsp;
++ int lvl, schq, rc;
+
+ /* Get memory to put this msg */
+ req = otx2_mbox_alloc_msg_nix_txsch_alloc(&pfvf->mbox);
+@@ -726,33 +727,68 @@ int otx2_txsch_alloc(struct otx2_nic *pfvf)
+ /* Request one schq per level */
+ for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++)
+ req->schq[lvl] = 1;
++ rc = otx2_sync_mbox_msg(&pfvf->mbox);
++ if (rc)
++ return rc;
+
+- return otx2_sync_mbox_msg(&pfvf->mbox);
++ rsp = (struct nix_txsch_alloc_rsp *)
++ otx2_mbox_get_rsp(&pfvf->mbox.mbox, 0, &req->hdr);
++ if (IS_ERR(rsp))
++ return PTR_ERR(rsp);
++
++ /* Setup transmit scheduler list */
++ for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++)
++ for (schq = 0; schq < rsp->schq[lvl]; schq++)
++ pfvf->hw.txschq_list[lvl][schq] =
++ rsp->schq_list[lvl][schq];
++
++ pfvf->hw.txschq_link_cfg_lvl = rsp->link_cfg_lvl;
++
++ return 0;
+ }
+
+-int otx2_txschq_stop(struct otx2_nic *pfvf)
++void otx2_txschq_free_one(struct otx2_nic *pfvf, u16 lvl, u16 schq)
+ {
+ struct nix_txsch_free_req *free_req;
+- int lvl, schq, err;
++ int err;
+
+ mutex_lock(&pfvf->mbox.lock);
+- /* Free the transmit schedulers */
++
+ free_req = otx2_mbox_alloc_msg_nix_txsch_free(&pfvf->mbox);
+ if (!free_req) {
+ mutex_unlock(&pfvf->mbox.lock);
+- return -ENOMEM;
++ netdev_err(pfvf->netdev,
++ "Failed alloc txschq free req\n");
++ return;
+ }
+
+- free_req->flags = TXSCHQ_FREE_ALL;
++ free_req->schq_lvl = lvl;
++ free_req->schq = schq;
++
+ err = otx2_sync_mbox_msg(&pfvf->mbox);
++ if (err) {
++ netdev_err(pfvf->netdev,
++ "Failed stop txschq %d at level %d\n", schq, lvl);
++ }
++
+ mutex_unlock(&pfvf->mbox.lock);
++}
++
++void otx2_txschq_stop(struct otx2_nic *pfvf)
++{
++ int lvl, schq;
++
++ /* free non QOS TLx nodes */
++ for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++)
++ otx2_txschq_free_one(pfvf, lvl,
++ pfvf->hw.txschq_list[lvl][0]);
+
+ /* Clear the txschq list */
+ for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) {
+ for (schq = 0; schq < MAX_TXSCHQ_PER_FUNC; schq++)
+ pfvf->hw.txschq_list[lvl][schq] = 0;
+ }
+- return err;
++
+ }
+
+ void otx2_sqb_flush(struct otx2_nic *pfvf)
+@@ -1629,21 +1665,6 @@ void mbox_handler_cgx_fec_stats(struct otx2_nic *pfvf,
+ pfvf->hw.cgx_fec_uncorr_blks += rsp->fec_uncorr_blks;
+ }
+
+-void mbox_handler_nix_txsch_alloc(struct otx2_nic *pf,
+- struct nix_txsch_alloc_rsp *rsp)
+-{
+- int lvl, schq;
+-
+- /* Setup transmit scheduler list */
+- for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++)
+- for (schq = 0; schq < rsp->schq[lvl]; schq++)
+- pf->hw.txschq_list[lvl][schq] =
+- rsp->schq_list[lvl][schq];
+-
+- pf->hw.txschq_link_cfg_lvl = rsp->link_cfg_lvl;
+-}
+-EXPORT_SYMBOL(mbox_handler_nix_txsch_alloc);
+-
+ void mbox_handler_npa_lf_alloc(struct otx2_nic *pfvf,
+ struct npa_lf_alloc_rsp *rsp)
+ {
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
+index 0c8fc66ade82d..53cf964fc3e14 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
+@@ -920,7 +920,8 @@ int otx2_config_nix(struct otx2_nic *pfvf);
+ int otx2_config_nix_queues(struct otx2_nic *pfvf);
+ int otx2_txschq_config(struct otx2_nic *pfvf, int lvl, int prio, bool pfc_en);
+ int otx2_txsch_alloc(struct otx2_nic *pfvf);
+-int otx2_txschq_stop(struct otx2_nic *pfvf);
++void otx2_txschq_stop(struct otx2_nic *pfvf);
++void otx2_txschq_free_one(struct otx2_nic *pfvf, u16 lvl, u16 schq);
+ void otx2_sqb_flush(struct otx2_nic *pfvf);
+ int __otx2_alloc_rbuf(struct otx2_nic *pfvf, struct otx2_pool *pool,
+ dma_addr_t *dma);
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
+index 384d26bee9b23..fb951e953df34 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
+@@ -791,10 +791,6 @@ static void otx2_process_pfaf_mbox_msg(struct otx2_nic *pf,
+ case MBOX_MSG_NIX_LF_ALLOC:
+ mbox_handler_nix_lf_alloc(pf, (struct nix_lf_alloc_rsp *)msg);
+ break;
+- case MBOX_MSG_NIX_TXSCH_ALLOC:
+- mbox_handler_nix_txsch_alloc(pf,
+- (struct nix_txsch_alloc_rsp *)msg);
+- break;
+ case MBOX_MSG_NIX_BP_ENABLE:
+ mbox_handler_nix_bp_enable(pf, (struct nix_bp_cfg_rsp *)msg);
+ break;
+@@ -1517,8 +1513,7 @@ static int otx2_init_hw_resources(struct otx2_nic *pf)
+ otx2_free_cq_res(pf);
+ otx2_ctx_disable(mbox, NIX_AQ_CTYPE_RQ, false);
+ err_free_txsch:
+- if (otx2_txschq_stop(pf))
+- dev_err(pf->dev, "%s failed to stop TX schedulers\n", __func__);
++ otx2_txschq_stop(pf);
+ err_free_sq_ptrs:
+ otx2_sq_free_sqbs(pf);
+ err_free_rq_ptrs:
+@@ -1553,15 +1548,13 @@ static void otx2_free_hw_resources(struct otx2_nic *pf)
+ struct mbox *mbox = &pf->mbox;
+ struct otx2_cq_queue *cq;
+ struct msg_req *req;
+- int qidx, err;
++ int qidx;
+
+ /* Ensure all SQE are processed */
+ otx2_sqb_flush(pf);
+
+ /* Stop transmission */
+- err = otx2_txschq_stop(pf);
+- if (err)
+- dev_err(pf->dev, "RVUPF: Failed to stop/free TX schedulers\n");
++ otx2_txschq_stop(pf);
+
+ #ifdef CONFIG_DCB
+ if (pf->pfc_en)
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c
+index 53366dbfbf27c..f8f0c01f62a14 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c
+@@ -70,10 +70,6 @@ static void otx2vf_process_vfaf_mbox_msg(struct otx2_nic *vf,
+ case MBOX_MSG_NIX_LF_ALLOC:
+ mbox_handler_nix_lf_alloc(vf, (struct nix_lf_alloc_rsp *)msg);
+ break;
+- case MBOX_MSG_NIX_TXSCH_ALLOC:
+- mbox_handler_nix_txsch_alloc(vf,
+- (struct nix_txsch_alloc_rsp *)msg);
+- break;
+ case MBOX_MSG_NIX_BP_ENABLE:
+ mbox_handler_nix_bp_enable(vf, (struct nix_bp_cfg_rsp *)msg);
+ break;
+--
+2.40.1
+
--- /dev/null
+From e9c08a5860ec097cf99b54648207a5df1fa0b805 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Jul 2023 10:50:28 +0200
+Subject: of: overlay: Call of_changeset_init() early
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit a9515ff4fb142b690a0d2b58782b15903b990dba ]
+
+When of_overlay_fdt_apply() fails, the changeset may be partially
+applied, and the caller is still expected to call of_overlay_remove() to
+clean up this partial state.
+
+However, of_overlay_apply() calls of_resolve_phandles() before
+init_overlay_changeset(). Hence if the overlay fails to apply due to an
+unresolved symbol, the overlay_changeset.cset.entries list is still
+uninitialized, and cleanup will crash with a NULL-pointer dereference in
+overlay_removal_is_ok().
+
+Fix this by moving the call to of_changeset_init() from
+init_overlay_changeset() to of_overlay_fdt_apply(), where all other
+early initialization is done.
+
+Fixes: f948d6d8b792bb90 ("of: overlay: avoid race condition between applying multiple overlays")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/4f1d6d74b61cba2599026adb6d1948ae559ce91f.1690533838.git.geert+renesas@glider.be
+Signed-off-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/of/overlay.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
+index 7feb643f13707..28b479afd506f 100644
+--- a/drivers/of/overlay.c
++++ b/drivers/of/overlay.c
+@@ -752,8 +752,6 @@ static int init_overlay_changeset(struct overlay_changeset *ovcs)
+ if (!of_node_is_root(ovcs->overlay_root))
+ pr_debug("%s() ovcs->overlay_root is not root\n", __func__);
+
+- of_changeset_init(&ovcs->cset);
+-
+ cnt = 0;
+
+ /* fragment nodes */
+@@ -1013,6 +1011,7 @@ int of_overlay_fdt_apply(const void *overlay_fdt, u32 overlay_fdt_size,
+
+ INIT_LIST_HEAD(&ovcs->ovcs_list);
+ list_add_tail(&ovcs->ovcs_list, &ovcs_list);
++ of_changeset_init(&ovcs->cset);
+
+ /*
+ * Must create permanent copy of FDT because of_fdt_unflatten_tree()
+--
+2.40.1
+
--- /dev/null
+From 65676056e35b3de28153a578f525496ce12ed0d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Jul 2023 16:02:46 +0800
+Subject: of: unittest: fix null pointer dereferencing in
+ of_unittest_find_node_by_name()
+
+From: Ruan Jinjie <ruanjinjie@huawei.com>
+
+[ Upstream commit d6ce4f0ea19c32f10867ed93d8386924326ab474 ]
+
+when kmalloc() fail to allocate memory in kasprintf(), name
+or full_name will be NULL, strcmp() will cause
+null pointer dereference.
+
+Fixes: 0d638a07d3a1 ("of: Convert to using %pOF instead of full_name")
+Signed-off-by: Ruan Jinjie <ruanjinjie@huawei.com>
+Link: https://lore.kernel.org/r/20230727080246.519539-1-ruanjinjie@huawei.com
+Signed-off-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/of/unittest.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c
+index 4fe02e9f7dcdd..be41eb246b6b2 100644
+--- a/drivers/of/unittest.c
++++ b/drivers/of/unittest.c
+@@ -77,7 +77,7 @@ static void __init of_unittest_find_node_by_name(void)
+
+ np = of_find_node_by_path("/testcase-data");
+ name = kasprintf(GFP_KERNEL, "%pOF", np);
+- unittest(np && !strcmp("/testcase-data", name),
++ unittest(np && name && !strcmp("/testcase-data", name),
+ "find /testcase-data failed\n");
+ of_node_put(np);
+ kfree(name);
+@@ -88,14 +88,14 @@ static void __init of_unittest_find_node_by_name(void)
+
+ np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a");
+ name = kasprintf(GFP_KERNEL, "%pOF", np);
+- unittest(np && !strcmp("/testcase-data/phandle-tests/consumer-a", name),
++ unittest(np && name && !strcmp("/testcase-data/phandle-tests/consumer-a", name),
+ "find /testcase-data/phandle-tests/consumer-a failed\n");
+ of_node_put(np);
+ kfree(name);
+
+ np = of_find_node_by_path("testcase-alias");
+ name = kasprintf(GFP_KERNEL, "%pOF", np);
+- unittest(np && !strcmp("/testcase-data", name),
++ unittest(np && name && !strcmp("/testcase-data", name),
+ "find testcase-alias failed\n");
+ of_node_put(np);
+ kfree(name);
+@@ -106,7 +106,7 @@ static void __init of_unittest_find_node_by_name(void)
+
+ np = of_find_node_by_path("testcase-alias/phandle-tests/consumer-a");
+ name = kasprintf(GFP_KERNEL, "%pOF", np);
+- unittest(np && !strcmp("/testcase-data/phandle-tests/consumer-a", name),
++ unittest(np && name && !strcmp("/testcase-data/phandle-tests/consumer-a", name),
+ "find testcase-alias/phandle-tests/consumer-a failed\n");
+ of_node_put(np);
+ kfree(name);
+@@ -1533,6 +1533,8 @@ static void attach_node_and_children(struct device_node *np)
+ const char *full_name;
+
+ full_name = kasprintf(GFP_KERNEL, "%pOF", np);
++ if (!full_name)
++ return;
+
+ if (!strcmp(full_name, "/__local_fixups__") ||
+ !strcmp(full_name, "/__fixups__")) {
+--
+2.40.1
+
--- /dev/null
+From bcfb7226b758b75827f4f939004011e0f0479769 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Jul 2023 10:50:29 +0200
+Subject: of: unittest: Fix overlay type in apply/revert check
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit 6becf8f845ae1f0b1cfed395bbeccbd23654162d ]
+
+The removal check in of_unittest_apply_revert_overlay_check()
+always uses the platform device overlay type, while it should use the
+actual overlay type, as passed as a parameter to the function.
+
+This has no impact on any current test, as all tests calling
+of_unittest_apply_revert_overlay_check() use the platform device overlay
+type.
+
+Fixes: d5e75500ca401d31 ("of: unitest: Add I2C overlay unit tests.")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/ba0234c41ba808f10112094f88792beeb6dbaedf.1690533838.git.geert+renesas@glider.be
+Signed-off-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/of/unittest.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c
+index be41eb246b6b2..03a1de841d3b7 100644
+--- a/drivers/of/unittest.c
++++ b/drivers/of/unittest.c
+@@ -2210,7 +2210,7 @@ static int __init of_unittest_apply_revert_overlay_check(int overlay_nr,
+ of_unittest_untrack_overlay(save_ovcs_id);
+
+ /* unittest device must be again in before state */
+- if (of_unittest_device_exists(unittest_nr, PDEV_OVERLAY) != before) {
++ if (of_unittest_device_exists(unittest_nr, ovtype) != before) {
+ unittest(0, "%s with device @\"%s\" %s\n",
+ overlay_name_from_nr(overlay_nr),
+ unittest_path(unittest_nr, ovtype),
+--
+2.40.1
+
--- /dev/null
+From 5ce9630c85c9134b424513a8030c6c03d4e62c09 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Jul 2023 18:16:34 +0530
+Subject: OPP: Fix passing 0 to PTR_ERR in _opp_attach_genpd()
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+[ Upstream commit d920920f85a82c1c806a4143871a0e8f534732f2 ]
+
+If dev_pm_domain_attach_by_name() returns NULL, then 0 will be passed to
+PTR_ERR() as reported by the smatch warning below:
+
+drivers/opp/core.c:2456 _opp_attach_genpd() warn: passing zero to 'PTR_ERR'
+
+Fix it by checking for the non-NULL virt_dev pointer before passing it to
+PTR_ERR. Otherwise return -ENODEV.
+
+Fixes: 4ea9496cbc95 ("opp: Fix error check in dev_pm_opp_attach_genpd()")
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/opp/core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/opp/core.c b/drivers/opp/core.c
+index b5973fefdfd83..75b43c6c7031c 100644
+--- a/drivers/opp/core.c
++++ b/drivers/opp/core.c
+@@ -2382,7 +2382,7 @@ static int _opp_attach_genpd(struct opp_table *opp_table, struct device *dev,
+
+ virt_dev = dev_pm_domain_attach_by_name(dev, *name);
+ if (IS_ERR_OR_NULL(virt_dev)) {
+- ret = PTR_ERR(virt_dev) ? : -ENODEV;
++ ret = virt_dev ? PTR_ERR(virt_dev) : -ENODEV;
+ dev_err(dev, "Couldn't attach to pm_domain: %d\n", ret);
+ goto err;
+ }
+--
+2.40.1
+
--- /dev/null
+From dca73edd7e99b3d03dd8ad0ce846d2056dc9cbe7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Jul 2023 15:04:53 +0300
+Subject: PCI: Add locking to RMW PCI Express Capability Register accessors
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit 5e70d0acf0825f439079736080350371f8d6699a ]
+
+Many places in the kernel write the Link Control and Root Control PCI
+Express Capability Registers without proper concurrency control and this
+could result in losing the changes one of the writers intended to make.
+
+Add pcie_cap_lock spinlock into the struct pci_dev and use it to protect
+bit changes made in the RMW capability accessors. Protect only a selected
+set of registers by differentiating the RMW accessor internally to
+locked/unlocked variants using a wrapper which has the same signature as
+pcie_capability_clear_and_set_word(). As the Capability Register (pos)
+given to the wrapper is always a constant, the compiler should be able to
+simplify all the dead-code away.
+
+So far only the Link Control Register (ASPM, hotplug, link retraining,
+various drivers) and the Root Control Register (AER & PME) seem to
+require RMW locking.
+
+Suggested-by: Lukas Wunner <lukas@wunner.de>
+Fixes: c7f486567c1d ("PCI PM: PCIe PME root port service driver")
+Fixes: f12eb72a268b ("PCI/ASPM: Use PCI Express Capability accessors")
+Fixes: 7d715a6c1ae5 ("PCI: add PCI Express ASPM support")
+Fixes: affa48de8417 ("staging/rdma/hfi1: Add support for enabling/disabling PCIe ASPM")
+Fixes: 849a9366cba9 ("misc: rtsx: Add support new chip rts5228 mmc: rtsx: Add support MMC_CAP2_NO_MMC")
+Fixes: 3d1e7aa80d1c ("misc: rtsx: Use pcie_capability_clear_and_set_word() for PCI_EXP_LNKCTL")
+Fixes: c0e5f4e73a71 ("misc: rtsx: Add support for RTS5261")
+Fixes: 3df4fce739e2 ("misc: rtsx: separate aspm mode into MODE_REG and MODE_CFG")
+Fixes: 121e9c6b5c4c ("misc: rtsx: modify and fix init_hw function")
+Fixes: 19f3bd548f27 ("mfd: rtsx: Remove LCTLR defination")
+Fixes: 773ccdfd9cc6 ("mfd: rtsx: Read vendor setting from config space")
+Fixes: 8275b77a1513 ("mfd: rts5249: Add support for RTS5250S power saving")
+Fixes: 5da4e04ae480 ("misc: rtsx: Add support for RTS5260")
+Fixes: 0f49bfbd0f2e ("tg3: Use PCI Express Capability accessors")
+Fixes: 5e7dfd0fb94a ("tg3: Prevent corruption at 10 / 100Mbps w CLKREQ")
+Fixes: b726e493e8dc ("r8169: sync existing 8168 device hardware start sequences with vendor driver")
+Fixes: e6de30d63eb1 ("r8169: more 8168dp support.")
+Fixes: 8a06127602de ("Bluetooth: hci_bcm4377: Add new driver for BCM4377 PCIe boards")
+Fixes: 6f461f6c7c96 ("e1000e: enable/disable ASPM L0s and L1 and ERT according to hardware errata")
+Fixes: 1eae4eb2a1c7 ("e1000e: Disable L1 ASPM power savings for 82573 mobile variants")
+Fixes: 8060e169e02f ("ath9k: Enable extended synch for AR9485 to fix L0s recovery issue")
+Fixes: 69ce674bfa69 ("ath9k: do btcoex ASPM disabling at initialization time")
+Fixes: f37f05503575 ("mt76: mt76x2e: disable pcie_aspm by default")
+Link: https://lore.kernel.org/r/20230717120503.15276-2-ilpo.jarvinen@linux.intel.com
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: "Rafael J. Wysocki" <rafael@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/access.c | 20 +++++++++++++++++---
+ drivers/pci/probe.c | 1 +
+ include/linux/pci.h | 34 ++++++++++++++++++++++++++++++++--
+ 3 files changed, 50 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/pci/access.c b/drivers/pci/access.c
+index 3c230ca3de584..0b2e90d2f04f2 100644
+--- a/drivers/pci/access.c
++++ b/drivers/pci/access.c
+@@ -497,8 +497,8 @@ int pcie_capability_write_dword(struct pci_dev *dev, int pos, u32 val)
+ }
+ EXPORT_SYMBOL(pcie_capability_write_dword);
+
+-int pcie_capability_clear_and_set_word(struct pci_dev *dev, int pos,
+- u16 clear, u16 set)
++int pcie_capability_clear_and_set_word_unlocked(struct pci_dev *dev, int pos,
++ u16 clear, u16 set)
+ {
+ int ret;
+ u16 val;
+@@ -512,7 +512,21 @@ int pcie_capability_clear_and_set_word(struct pci_dev *dev, int pos,
+
+ return ret;
+ }
+-EXPORT_SYMBOL(pcie_capability_clear_and_set_word);
++EXPORT_SYMBOL(pcie_capability_clear_and_set_word_unlocked);
++
++int pcie_capability_clear_and_set_word_locked(struct pci_dev *dev, int pos,
++ u16 clear, u16 set)
++{
++ unsigned long flags;
++ int ret;
++
++ spin_lock_irqsave(&dev->pcie_cap_lock, flags);
++ ret = pcie_capability_clear_and_set_word_unlocked(dev, pos, clear, set);
++ spin_unlock_irqrestore(&dev->pcie_cap_lock, flags);
++
++ return ret;
++}
++EXPORT_SYMBOL(pcie_capability_clear_and_set_word_locked);
+
+ int pcie_capability_clear_and_set_dword(struct pci_dev *dev, int pos,
+ u32 clear, u32 set)
+diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
+index 00ed20ac0dd61..2b36dbf74af51 100644
+--- a/drivers/pci/probe.c
++++ b/drivers/pci/probe.c
+@@ -2320,6 +2320,7 @@ struct pci_dev *pci_alloc_dev(struct pci_bus *bus)
+ .end = -1,
+ };
+
++ spin_lock_init(&dev->pcie_cap_lock);
+ #ifdef CONFIG_PCI_MSI
+ raw_spin_lock_init(&dev->msi_lock);
+ #endif
+diff --git a/include/linux/pci.h b/include/linux/pci.h
+index c69a2cc1f4123..7ee498cd1f374 100644
+--- a/include/linux/pci.h
++++ b/include/linux/pci.h
+@@ -467,6 +467,7 @@ struct pci_dev {
+ pci_dev_flags_t dev_flags;
+ atomic_t enable_cnt; /* pci_enable_device has been called */
+
++ spinlock_t pcie_cap_lock; /* Protects RMW ops in capability accessors */
+ u32 saved_config_space[16]; /* Config space saved at suspend time */
+ struct hlist_head saved_cap_space;
+ int rom_attr_enabled; /* Display of ROM attribute enabled? */
+@@ -1217,11 +1218,40 @@ int pcie_capability_read_word(struct pci_dev *dev, int pos, u16 *val);
+ int pcie_capability_read_dword(struct pci_dev *dev, int pos, u32 *val);
+ int pcie_capability_write_word(struct pci_dev *dev, int pos, u16 val);
+ int pcie_capability_write_dword(struct pci_dev *dev, int pos, u32 val);
+-int pcie_capability_clear_and_set_word(struct pci_dev *dev, int pos,
+- u16 clear, u16 set);
++int pcie_capability_clear_and_set_word_unlocked(struct pci_dev *dev, int pos,
++ u16 clear, u16 set);
++int pcie_capability_clear_and_set_word_locked(struct pci_dev *dev, int pos,
++ u16 clear, u16 set);
+ int pcie_capability_clear_and_set_dword(struct pci_dev *dev, int pos,
+ u32 clear, u32 set);
+
++/**
++ * pcie_capability_clear_and_set_word - RMW accessor for PCI Express Capability Registers
++ * @dev: PCI device structure of the PCI Express device
++ * @pos: PCI Express Capability Register
++ * @clear: Clear bitmask
++ * @set: Set bitmask
++ *
++ * Perform a Read-Modify-Write (RMW) operation using @clear and @set
++ * bitmasks on PCI Express Capability Register at @pos. Certain PCI Express
++ * Capability Registers are accessed concurrently in RMW fashion, hence
++ * require locking which is handled transparently to the caller.
++ */
++static inline int pcie_capability_clear_and_set_word(struct pci_dev *dev,
++ int pos,
++ u16 clear, u16 set)
++{
++ switch (pos) {
++ case PCI_EXP_LNKCTL:
++ case PCI_EXP_RTCTL:
++ return pcie_capability_clear_and_set_word_locked(dev, pos,
++ clear, set);
++ default:
++ return pcie_capability_clear_and_set_word_unlocked(dev, pos,
++ clear, set);
++ }
++}
++
+ static inline int pcie_capability_set_word(struct pci_dev *dev, int pos,
+ u16 set)
+ {
+--
+2.40.1
+
--- /dev/null
+From de7d4d97a6cb910b0f4b589217535888db4e9c1d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Mar 2023 14:34:53 +0100
+Subject: PCI: apple: Initialize pcie->nvecs before use
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Sven Peter <sven@svenpeter.dev>
+
+[ Upstream commit d8650c0c2aa2e413594e4cb0faafa9958c1d7782 ]
+
+The apple_pcie_setup_port() function computes ilog2(pcie->nvecs) to set
+up the number of MSIs available for each port. However, it's called
+before apple_msi_init(), which initializes pcie->nvecs.
+
+Luckily, pcie->nvecs is part of kzalloc()-ed structure and, as such,
+initialized as zero. ilog2(0) happens to be 0xffffffff which then simply
+configures more MSIs in hardware than we have. This doesn't break
+anything because we never hand out those vectors.
+
+Thus, swap the order of the two calls so that the correctly initialized
+value is then used.
+
+[kwilczynski: commit log]
+Link: https://lore.kernel.org/linux-pci/20230311133453.63246-1-sven@svenpeter.dev
+Fixes: 476c41ed4597 ("PCI: apple: Implement MSI support")
+Signed-off-by: Sven Peter <sven@svenpeter.dev>
+Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
+Reviewed-by: Marc Zyngier <maz@kernel.org>
+Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
+Reviewed-by: Eric Curtin <ecurtin@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/pcie-apple.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/pci/controller/pcie-apple.c b/drivers/pci/controller/pcie-apple.c
+index 66f37e403a09c..2340dab6cd5bd 100644
+--- a/drivers/pci/controller/pcie-apple.c
++++ b/drivers/pci/controller/pcie-apple.c
+@@ -783,6 +783,10 @@ static int apple_pcie_init(struct pci_config_window *cfg)
+ cfg->priv = pcie;
+ INIT_LIST_HEAD(&pcie->ports);
+
++ ret = apple_msi_init(pcie);
++ if (ret)
++ return ret;
++
+ for_each_child_of_node(dev->of_node, of_port) {
+ ret = apple_pcie_setup_port(pcie, of_port);
+ if (ret) {
+@@ -792,7 +796,7 @@ static int apple_pcie_init(struct pci_config_window *cfg)
+ }
+ }
+
+- return apple_msi_init(pcie);
++ return 0;
+ }
+
+ static int apple_pcie_probe(struct platform_device *pdev)
+--
+2.40.1
+
--- /dev/null
+From 343e0b98b6db3687396bbd4e2e8c7caeb8298804 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Jul 2023 15:04:56 +0300
+Subject: PCI/ASPM: Use RMW accessors for changing LNKCTL
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit e09060b3b6b4661278ff8e1b7b81a37d5ea86eae ]
+
+Don't assume that the device is fully under the control of ASPM and use RMW
+capability accessors which do proper locking to avoid losing concurrent
+updates to the register values.
+
+If configuration fails in pcie_aspm_configure_common_clock(), the
+function attempts to restore the old PCI_EXP_LNKCTL_CCC settings. Store
+only the old PCI_EXP_LNKCTL_CCC bit for the relevant devices rather
+than the content of the whole LNKCTL registers. It aligns better with
+how pcie_lnkctl_clear_and_set() expects its parameter and makes the
+code more obvious to understand.
+
+Suggested-by: Lukas Wunner <lukas@wunner.de>
+Fixes: 2a42d9dba784 ("PCIe: ASPM: Break out of endless loop waiting for PCI config bits to switch")
+Fixes: 7d715a6c1ae5 ("PCI: add PCI Express ASPM support")
+Link: https://lore.kernel.org/r/20230717120503.15276-5-ilpo.jarvinen@linux.intel.com
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Acked-by: "Rafael J. Wysocki" <rafael@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pcie/aspm.c | 30 +++++++++++++-----------------
+ 1 file changed, 13 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
+index 998e26de2ad76..75e51b965c0b7 100644
+--- a/drivers/pci/pcie/aspm.c
++++ b/drivers/pci/pcie/aspm.c
+@@ -250,7 +250,7 @@ static int pcie_retrain_link(struct pcie_link_state *link)
+ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link)
+ {
+ int same_clock = 1;
+- u16 reg16, parent_reg, child_reg[8];
++ u16 reg16, ccc, parent_old_ccc, child_old_ccc[8];
+ struct pci_dev *child, *parent = link->pdev;
+ struct pci_bus *linkbus = parent->subordinate;
+ /*
+@@ -272,6 +272,7 @@ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link)
+
+ /* Port might be already in common clock mode */
+ pcie_capability_read_word(parent, PCI_EXP_LNKCTL, ®16);
++ parent_old_ccc = reg16 & PCI_EXP_LNKCTL_CCC;
+ if (same_clock && (reg16 & PCI_EXP_LNKCTL_CCC)) {
+ bool consistent = true;
+
+@@ -288,34 +289,29 @@ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link)
+ pci_info(parent, "ASPM: current common clock configuration is inconsistent, reconfiguring\n");
+ }
+
++ ccc = same_clock ? PCI_EXP_LNKCTL_CCC : 0;
+ /* Configure downstream component, all functions */
+ list_for_each_entry(child, &linkbus->devices, bus_list) {
+ pcie_capability_read_word(child, PCI_EXP_LNKCTL, ®16);
+- child_reg[PCI_FUNC(child->devfn)] = reg16;
+- if (same_clock)
+- reg16 |= PCI_EXP_LNKCTL_CCC;
+- else
+- reg16 &= ~PCI_EXP_LNKCTL_CCC;
+- pcie_capability_write_word(child, PCI_EXP_LNKCTL, reg16);
++ child_old_ccc[PCI_FUNC(child->devfn)] = reg16 & PCI_EXP_LNKCTL_CCC;
++ pcie_capability_clear_and_set_word(child, PCI_EXP_LNKCTL,
++ PCI_EXP_LNKCTL_CCC, ccc);
+ }
+
+ /* Configure upstream component */
+- pcie_capability_read_word(parent, PCI_EXP_LNKCTL, ®16);
+- parent_reg = reg16;
+- if (same_clock)
+- reg16 |= PCI_EXP_LNKCTL_CCC;
+- else
+- reg16 &= ~PCI_EXP_LNKCTL_CCC;
+- pcie_capability_write_word(parent, PCI_EXP_LNKCTL, reg16);
++ pcie_capability_clear_and_set_word(parent, PCI_EXP_LNKCTL,
++ PCI_EXP_LNKCTL_CCC, ccc);
+
+ if (pcie_retrain_link(link)) {
+
+ /* Training failed. Restore common clock configurations */
+ pci_err(parent, "ASPM: Could not configure common clock\n");
+ list_for_each_entry(child, &linkbus->devices, bus_list)
+- pcie_capability_write_word(child, PCI_EXP_LNKCTL,
+- child_reg[PCI_FUNC(child->devfn)]);
+- pcie_capability_write_word(parent, PCI_EXP_LNKCTL, parent_reg);
++ pcie_capability_clear_and_set_word(child, PCI_EXP_LNKCTL,
++ PCI_EXP_LNKCTL_CCC,
++ child_old_ccc[PCI_FUNC(child->devfn)]);
++ pcie_capability_clear_and_set_word(parent, PCI_EXP_LNKCTL,
++ PCI_EXP_LNKCTL_CCC, parent_old_ccc);
+ }
+ }
+
+--
+2.40.1
+
--- /dev/null
+From 1d9729e89e2fa95c11106ff4de699be0a71893e9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Jul 2023 11:29:42 -0700
+Subject: PCI/DOE: Fix destroy_work_on_stack() race
+
+From: Ira Weiny <ira.weiny@intel.com>
+
+[ Upstream commit e3a3a097eaebaf234a482b4d2f9f18fe989208c1 ]
+
+The following debug object splat was observed in testing:
+
+ ODEBUG: free active (active state 0) object: 0000000097d23782 object type: work_struct hint: doe_statemachine_work+0x0/0x510
+ WARNING: CPU: 1 PID: 71 at lib/debugobjects.c:514 debug_print_object+0x7d/0xb0
+ ...
+ Workqueue: pci 0000:36:00.0 DOE [1 doe_statemachine_work
+ RIP: 0010:debug_print_object+0x7d/0xb0
+ ...
+ Call Trace:
+ ? debug_print_object+0x7d/0xb0
+ ? __pfx_doe_statemachine_work+0x10/0x10
+ debug_object_free.part.0+0x11b/0x150
+ doe_statemachine_work+0x45e/0x510
+ process_one_work+0x1d4/0x3c0
+
+This occurs because destroy_work_on_stack() was called after signaling
+the completion in the calling thread. This creates a race between
+destroy_work_on_stack() and the task->work struct going out of scope in
+pci_doe().
+
+Signal the work complete after destroying the work struct. This is safe
+because signal_task_complete() is the final thing the work item does and
+the workqueue code is careful not to access the work struct after.
+
+Fixes: abf04be0e707 ("PCI/DOE: Fix memory leak with CONFIG_DEBUG_OBJECTS=y")
+Link: https://lore.kernel.org/r/20230726-doe-fix-v1-1-af07e614d4dd@intel.com
+Signed-off-by: Ira Weiny <ira.weiny@intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Lukas Wunner <lukas@wunner.de>
+Acked-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/doe.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/pci/doe.c b/drivers/pci/doe.c
+index 1b97a5ab71a96..e3aab5edaf706 100644
+--- a/drivers/pci/doe.c
++++ b/drivers/pci/doe.c
+@@ -293,8 +293,8 @@ static int pci_doe_recv_resp(struct pci_doe_mb *doe_mb, struct pci_doe_task *tas
+ static void signal_task_complete(struct pci_doe_task *task, int rv)
+ {
+ task->rv = rv;
+- task->complete(task);
+ destroy_work_on_stack(&task->work);
++ task->complete(task);
+ }
+
+ static void signal_task_abort(struct pci_doe_task *task, int rv)
+--
+2.40.1
+
--- /dev/null
+From a0847472d8419cb6e9d95f95967267bb630e2e2d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Apr 2023 20:34:11 +0800
+Subject: PCI: Mark NVIDIA T4 GPUs to avoid bus reset
+
+From: Wu Zongyong <wuzongyong@linux.alibaba.com>
+
+[ Upstream commit d5af729dc2071273f14cbb94abbc60608142fd83 ]
+
+NVIDIA T4 GPUs do not work with SBR. This problem is found when the T4 card
+is direct attached to a Root Port only. Avoid bus reset by marking T4 GPUs
+PCI_DEV_FLAGS_NO_BUS_RESET.
+
+Fixes: 4c207e7121fa ("PCI: Mark some NVIDIA GPUs to avoid bus reset")
+Link: https://lore.kernel.org/r/2dcebea53a6eb9bd212ec6d8974af2e5e0333ef6.1681129861.git.wuzongyong@linux.alibaba.com
+Signed-off-by: Wu Zongyong <wuzongyong@linux.alibaba.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/quirks.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
+index b7c65193e786a..c05ed6e60748d 100644
+--- a/drivers/pci/quirks.c
++++ b/drivers/pci/quirks.c
+@@ -3631,7 +3631,7 @@ static void quirk_no_bus_reset(struct pci_dev *dev)
+ */
+ static void quirk_nvidia_no_bus_reset(struct pci_dev *dev)
+ {
+- if ((dev->device & 0xffc0) == 0x2340)
++ if ((dev->device & 0xffc0) == 0x2340 || dev->device == 0x1eb8)
+ quirk_no_bus_reset(dev);
+ }
+ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
+--
+2.40.1
+
--- /dev/null
+From df8495e038b9ba1ba97e2057d8db01fc953b67df Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Jul 2023 14:13:55 +0100
+Subject: PCI: microchip: Correct the DED and SEC interrupt bit offsets
+
+From: Daire McNamara <daire.mcnamara@microchip.com>
+
+[ Upstream commit 6d473a5a26136edf55c435a1c433e52910e03926 ]
+
+The SEC and DED interrupt bits are laid out the wrong way round so the SEC
+interrupt handler attempts to mask, unmask, and clear the DED interrupt
+and vice versa. Correct the bit offsets so that each interrupt handler
+operates properly.
+
+Link: https://lore.kernel.org/r/20230728131401.1615724-2-daire.mcnamara@microchip.com
+Fixes: 6f15a9c9f941 ("PCI: microchip: Add Microchip PolarFire PCIe controller driver")
+Signed-off-by: Daire McNamara <daire.mcnamara@microchip.com>
+Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/pcie-microchip-host.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/pci/controller/pcie-microchip-host.c b/drivers/pci/controller/pcie-microchip-host.c
+index 5e710e4854646..dd5245904c874 100644
+--- a/drivers/pci/controller/pcie-microchip-host.c
++++ b/drivers/pci/controller/pcie-microchip-host.c
+@@ -167,12 +167,12 @@
+ #define EVENT_PCIE_DLUP_EXIT 2
+ #define EVENT_SEC_TX_RAM_SEC_ERR 3
+ #define EVENT_SEC_RX_RAM_SEC_ERR 4
+-#define EVENT_SEC_AXI2PCIE_RAM_SEC_ERR 5
+-#define EVENT_SEC_PCIE2AXI_RAM_SEC_ERR 6
++#define EVENT_SEC_PCIE2AXI_RAM_SEC_ERR 5
++#define EVENT_SEC_AXI2PCIE_RAM_SEC_ERR 6
+ #define EVENT_DED_TX_RAM_DED_ERR 7
+ #define EVENT_DED_RX_RAM_DED_ERR 8
+-#define EVENT_DED_AXI2PCIE_RAM_DED_ERR 9
+-#define EVENT_DED_PCIE2AXI_RAM_DED_ERR 10
++#define EVENT_DED_PCIE2AXI_RAM_DED_ERR 9
++#define EVENT_DED_AXI2PCIE_RAM_DED_ERR 10
+ #define EVENT_LOCAL_DMA_END_ENGINE_0 11
+ #define EVENT_LOCAL_DMA_END_ENGINE_1 12
+ #define EVENT_LOCAL_DMA_ERROR_ENGINE_0 13
+--
+2.40.1
+
--- /dev/null
+From faf831693fbf5effbd080e2f9f7006f9c4113b3d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Jul 2023 15:04:55 +0300
+Subject: PCI: pciehp: Use RMW accessors for changing LNKCTL
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit 5f75f96c61039151c193775d776fde42477eace1 ]
+
+As hotplug is not the only driver touching LNKCTL, use the RMW capability
+accessor which handles concurrent changes correctly.
+
+Suggested-by: Lukas Wunner <lukas@wunner.de>
+Fixes: 7f822999e12a ("PCI: pciehp: Add Disable/enable link functions")
+Link: https://lore.kernel.org/r/20230717120503.15276-4-ilpo.jarvinen@linux.intel.com
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Acked-by: "Rafael J. Wysocki" <rafael@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/hotplug/pciehp_hpc.c | 12 +++---------
+ 1 file changed, 3 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
+index f8c70115b6917..5deb45d79f9de 100644
+--- a/drivers/pci/hotplug/pciehp_hpc.c
++++ b/drivers/pci/hotplug/pciehp_hpc.c
+@@ -332,17 +332,11 @@ int pciehp_check_link_status(struct controller *ctrl)
+ static int __pciehp_link_set(struct controller *ctrl, bool enable)
+ {
+ struct pci_dev *pdev = ctrl_dev(ctrl);
+- u16 lnk_ctrl;
+
+- pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &lnk_ctrl);
++ pcie_capability_clear_and_set_word(pdev, PCI_EXP_LNKCTL,
++ PCI_EXP_LNKCTL_LD,
++ enable ? 0 : PCI_EXP_LNKCTL_LD);
+
+- if (enable)
+- lnk_ctrl &= ~PCI_EXP_LNKCTL_LD;
+- else
+- lnk_ctrl |= PCI_EXP_LNKCTL_LD;
+-
+- pcie_capability_write_word(pdev, PCI_EXP_LNKCTL, lnk_ctrl);
+- ctrl_dbg(ctrl, "%s: lnk_ctrl = %x\n", __func__, lnk_ctrl);
+ return 0;
+ }
+
+--
+2.40.1
+
--- /dev/null
+From facd24254a780a16455e714389e83fad5e305ed9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Jun 2023 19:40:36 +0530
+Subject: PCI: qcom-ep: Switch MHI bus master clock off during L1SS
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+[ Upstream commit b9cbc06049cb6b7a322d708c2098195fb9fdcc4c ]
+
+Currently, as part of the qcom_pcie_perst_deassert() function, instead
+of writing the updated value to clear PARF_MSTR_AXI_CLK_EN, the variable
+"val" is re-read.
+
+This must be fixed to ensure that the master clock supplied to the MHI
+bus is correctly gated during L1.1/L1.2 to save power.
+
+Thus, replace the line that re-reads "val" with a line that writes the
+updated value to the register to clear PARF_MSTR_AXI_CLK_EN.
+
+[kwilczynski: commit log]
+Fixes: c457ac029e44 ("PCI: qcom-ep: Gate Master AXI clock to MHI bus during L1SS")
+Link: https://lore.kernel.org/linux-pci/20230627141036.11600-1-manivannan.sadhasivam@linaro.org
+Reported-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pcie-qcom-ep.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c
+index 19b32839ea261..043b356d7d72d 100644
+--- a/drivers/pci/controller/dwc/pcie-qcom-ep.c
++++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c
+@@ -415,7 +415,7 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci)
+ /* Gate Master AXI clock to MHI bus during L1SS */
+ val = readl_relaxed(pcie_ep->parf + PARF_MHI_CLOCK_RESET_CTRL);
+ val &= ~PARF_MSTR_AXI_CLK_EN;
+- val = readl_relaxed(pcie_ep->parf + PARF_MHI_CLOCK_RESET_CTRL);
++ writel_relaxed(val, pcie_ep->parf + PARF_MHI_CLOCK_RESET_CTRL);
+
+ dw_pcie_ep_init_notify(&pcie_ep->pci.ep);
+
+--
+2.40.1
+
--- /dev/null
+From a8152ed5fee162e413cdf7ceae1069fb3e27f76d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Aug 2023 09:17:53 -0700
+Subject: pds_core: check for work queue before use
+
+From: Shannon Nelson <shannon.nelson@amd.com>
+
+[ Upstream commit 969cfd4c8ca50c32901342cdd3d677c3ffe61371 ]
+
+Add a check that the wq exists before queuing up work for a
+failed devcmd, as the PF is responsible for health and the VF
+doesn't have a wq.
+
+Fixes: c2dbb0904310 ("pds_core: health timer and workqueue")
+Signed-off-by: Shannon Nelson <shannon.nelson@amd.com>
+Reviewed-by: Brett Creeley <brett.creeley@amd.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://lore.kernel.org/r/20230824161754.34264-5-shannon.nelson@amd.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/amd/pds_core/dev.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/amd/pds_core/dev.c b/drivers/net/ethernet/amd/pds_core/dev.c
+index debe5216fe29e..524f422ee7ace 100644
+--- a/drivers/net/ethernet/amd/pds_core/dev.c
++++ b/drivers/net/ethernet/amd/pds_core/dev.c
+@@ -183,7 +183,7 @@ int pdsc_devcmd_locked(struct pdsc *pdsc, union pds_core_dev_cmd *cmd,
+ err = pdsc_devcmd_wait(pdsc, max_seconds);
+ memcpy_fromio(comp, &pdsc->cmd_regs->comp, sizeof(*comp));
+
+- if (err == -ENXIO || err == -ETIMEDOUT)
++ if ((err == -ENXIO || err == -ETIMEDOUT) && pdsc->wq)
+ queue_work(pdsc->wq, &pdsc->health_work);
+
+ return err;
+--
+2.40.1
+
--- /dev/null
+From f4c83be69a5ea7dd75a9b09b2131e56be91e4628 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Aug 2023 09:17:51 -0700
+Subject: pds_core: no health reporter in VF
+
+From: Shannon Nelson <shannon.nelson@amd.com>
+
+[ Upstream commit e48b894a1db7f6ce66bff0402ab21ff9f0e56034 ]
+
+Make sure the health reporter is set up before we use it in
+our devlink health updates, especially since the VF doesn't
+set up the health reporter.
+
+Fixes: 25b450c05a49 ("pds_core: add devlink health facilities")
+Signed-off-by: Shannon Nelson <shannon.nelson@amd.com>
+Reviewed-by: Brett Creeley <brett.creeley@amd.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://lore.kernel.org/r/20230824161754.34264-3-shannon.nelson@amd.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/amd/pds_core/core.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/amd/pds_core/core.c b/drivers/net/ethernet/amd/pds_core/core.c
+index 483a070d96fa9..2a315f2da37d7 100644
+--- a/drivers/net/ethernet/amd/pds_core/core.c
++++ b/drivers/net/ethernet/amd/pds_core/core.c
+@@ -524,7 +524,8 @@ static void pdsc_fw_down(struct pdsc *pdsc)
+ }
+
+ /* Notify clients of fw_down */
+- devlink_health_report(pdsc->fw_reporter, "FW down reported", pdsc);
++ if (pdsc->fw_reporter)
++ devlink_health_report(pdsc->fw_reporter, "FW down reported", pdsc);
+ pdsc_notify(PDS_EVENT_RESET, &reset_event);
+
+ pdsc_stop(pdsc);
+@@ -554,8 +555,9 @@ static void pdsc_fw_up(struct pdsc *pdsc)
+
+ /* Notify clients of fw_up */
+ pdsc->fw_recoveries++;
+- devlink_health_reporter_state_update(pdsc->fw_reporter,
+- DEVLINK_HEALTH_REPORTER_STATE_HEALTHY);
++ if (pdsc->fw_reporter)
++ devlink_health_reporter_state_update(pdsc->fw_reporter,
++ DEVLINK_HEALTH_REPORTER_STATE_HEALTHY);
+ pdsc_notify(PDS_EVENT_RESET, &reset_event);
+
+ return;
+--
+2.40.1
+
--- /dev/null
+From 33d5b4f237af59e813c3250b3c3d7d51bb141d5c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Aug 2023 09:17:52 -0700
+Subject: pds_core: no reset command for VF
+
+From: Shannon Nelson <shannon.nelson@amd.com>
+
+[ Upstream commit 95e383226d6fcda6c217912f11edf8d74de9cc85 ]
+
+The VF doesn't need to send a reset command, and in a PCI reset
+scenario it might not have a valid IO space to write to anyway.
+
+Fixes: 523847df1b37 ("pds_core: add devcmd device interfaces")
+Signed-off-by: Shannon Nelson <shannon.nelson@amd.com>
+Reviewed-by: Brett Creeley <brett.creeley@amd.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://lore.kernel.org/r/20230824161754.34264-4-shannon.nelson@amd.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/amd/pds_core/core.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/amd/pds_core/core.c b/drivers/net/ethernet/amd/pds_core/core.c
+index 2a315f2da37d7..d06934edc265e 100644
+--- a/drivers/net/ethernet/amd/pds_core/core.c
++++ b/drivers/net/ethernet/amd/pds_core/core.c
+@@ -464,7 +464,8 @@ void pdsc_teardown(struct pdsc *pdsc, bool removing)
+ {
+ int i;
+
+- pdsc_devcmd_reset(pdsc);
++ if (!pdsc->pdev->is_virtfn)
++ pdsc_devcmd_reset(pdsc);
+ pdsc_qcq_free(pdsc, &pdsc->notifyqcq);
+ pdsc_qcq_free(pdsc, &pdsc->adminqcq);
+
+--
+2.40.1
+
--- /dev/null
+From fcfa612db21d34a31e8bacb3a05eb3cf8d4cd156 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Aug 2023 09:17:54 -0700
+Subject: pds_core: pass opcode to devcmd_wait
+
+From: Shannon Nelson <shannon.nelson@amd.com>
+
+[ Upstream commit 0ea064e74bc8f915aba3f2d0fb3418247a09b73d ]
+
+Don't rely on the PCI memory for the devcmd opcode because we
+read a 0xff value if the PCI bus is broken, which can cause us
+to report a bogus dev_cmd opcode later.
+
+Fixes: 523847df1b37 ("pds_core: add devcmd device interfaces")
+Signed-off-by: Shannon Nelson <shannon.nelson@amd.com>
+Reviewed-by: Brett Creeley <brett.creeley@amd.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://lore.kernel.org/r/20230824161754.34264-6-shannon.nelson@amd.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/amd/pds_core/dev.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/amd/pds_core/dev.c b/drivers/net/ethernet/amd/pds_core/dev.c
+index 524f422ee7ace..f77cd9f5a2fda 100644
+--- a/drivers/net/ethernet/amd/pds_core/dev.c
++++ b/drivers/net/ethernet/amd/pds_core/dev.c
+@@ -121,7 +121,7 @@ static const char *pdsc_devcmd_str(int opcode)
+ }
+ }
+
+-static int pdsc_devcmd_wait(struct pdsc *pdsc, int max_seconds)
++static int pdsc_devcmd_wait(struct pdsc *pdsc, u8 opcode, int max_seconds)
+ {
+ struct device *dev = pdsc->dev;
+ unsigned long start_time;
+@@ -131,9 +131,6 @@ static int pdsc_devcmd_wait(struct pdsc *pdsc, int max_seconds)
+ int done = 0;
+ int err = 0;
+ int status;
+- int opcode;
+-
+- opcode = ioread8(&pdsc->cmd_regs->cmd.opcode);
+
+ start_time = jiffies;
+ max_wait = start_time + (max_seconds * HZ);
+@@ -180,7 +177,7 @@ int pdsc_devcmd_locked(struct pdsc *pdsc, union pds_core_dev_cmd *cmd,
+
+ memcpy_toio(&pdsc->cmd_regs->cmd, cmd, sizeof(*cmd));
+ pdsc_devcmd_dbell(pdsc);
+- err = pdsc_devcmd_wait(pdsc, max_seconds);
++ 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)
+--
+2.40.1
+
--- /dev/null
+From e7e7c0ccaf07a157c55dd08f40f5e7af4f652a60 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Aug 2023 09:17:50 -0700
+Subject: pds_core: protect devlink callbacks from fw_down state
+
+From: Shannon Nelson <shannon.nelson@amd.com>
+
+[ Upstream commit 91202ce78fcd070982a115f0bf6f328af619aa00 ]
+
+Don't access structs that have been cleared when in the fw_down
+state and the various structs have been cleaned and are waiting
+to recover. This caused a panic on rmmod when already in fw_down
+and devlink_param_unregister() tried to check the parameters.
+
+Fixes: 40ced8944536 ("pds_core: devlink params for enabling VIF support")
+Signed-off-by: Shannon Nelson <shannon.nelson@amd.com>
+Reviewed-by: Brett Creeley <brett.creeley@amd.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://lore.kernel.org/r/20230824161754.34264-2-shannon.nelson@amd.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/amd/pds_core/devlink.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ethernet/amd/pds_core/devlink.c b/drivers/net/ethernet/amd/pds_core/devlink.c
+index 9c6b3653c1c7c..d9607033bbf21 100644
+--- a/drivers/net/ethernet/amd/pds_core/devlink.c
++++ b/drivers/net/ethernet/amd/pds_core/devlink.c
+@@ -10,6 +10,9 @@ pdsc_viftype *pdsc_dl_find_viftype_by_id(struct pdsc *pdsc,
+ {
+ int vt;
+
++ if (!pdsc->viftype_status)
++ return NULL;
++
+ for (vt = 0; vt < PDS_DEV_TYPE_MAX; vt++) {
+ if (pdsc->viftype_status[vt].dl_id == dl_id)
+ return &pdsc->viftype_status[vt];
+--
+2.40.1
+
--- /dev/null
+From 60383c630c99464f8d26998c9a8fd114e674c332 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Aug 2023 09:54:38 +0800
+Subject: perf/imx_ddr: don't enable counter0 if none of 4 counters are used
+
+From: Xu Yang <xu.yang_2@nxp.com>
+
+[ Upstream commit f4e2bd91ddf5e8543cbe7ad80b3fba3d2dc63fa3 ]
+
+In current driver, counter0 will be enabled after ddr_perf_pmu_enable()
+is called even though none of the 4 counters are used. This will cause
+counter0 continue to count until ddr_perf_pmu_disabled() is called. If
+pmu is not disabled all the time, the pmu interrupt will be asserted
+from time to time due to counter0 will overflow and irq handler will
+clear it. It's not an expected behavior. This patch will not enable
+counter0 if none of 4 counters are used.
+
+Fixes: 9a66d36cc7ac ("drivers/perf: imx_ddr: Add DDR performance counter support to perf")
+Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Link: https://lore.kernel.org/r/20230811015438.1999307-2-xu.yang_2@nxp.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/perf/fsl_imx8_ddr_perf.c | 24 +++++++++---------------
+ 1 file changed, 9 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/perf/fsl_imx8_ddr_perf.c b/drivers/perf/fsl_imx8_ddr_perf.c
+index 5222ba1e79d0e..c684aab407f86 100644
+--- a/drivers/perf/fsl_imx8_ddr_perf.c
++++ b/drivers/perf/fsl_imx8_ddr_perf.c
+@@ -101,6 +101,7 @@ struct ddr_pmu {
+ const struct fsl_ddr_devtype_data *devtype_data;
+ int irq;
+ int id;
++ int active_counter;
+ };
+
+ static ssize_t ddr_perf_identifier_show(struct device *dev,
+@@ -495,6 +496,10 @@ static void ddr_perf_event_start(struct perf_event *event, int flags)
+
+ ddr_perf_counter_enable(pmu, event->attr.config, counter, true);
+
++ if (!pmu->active_counter++)
++ ddr_perf_counter_enable(pmu, EVENT_CYCLES_ID,
++ EVENT_CYCLES_COUNTER, true);
++
+ hwc->state = 0;
+ }
+
+@@ -548,6 +553,10 @@ static void ddr_perf_event_stop(struct perf_event *event, int flags)
+ ddr_perf_counter_enable(pmu, event->attr.config, counter, false);
+ ddr_perf_event_update(event);
+
++ if (!--pmu->active_counter)
++ ddr_perf_counter_enable(pmu, EVENT_CYCLES_ID,
++ EVENT_CYCLES_COUNTER, false);
++
+ hwc->state |= PERF_HES_STOPPED;
+ }
+
+@@ -565,25 +574,10 @@ static void ddr_perf_event_del(struct perf_event *event, int flags)
+
+ static void ddr_perf_pmu_enable(struct pmu *pmu)
+ {
+- struct ddr_pmu *ddr_pmu = to_ddr_pmu(pmu);
+-
+- /* enable cycle counter if cycle is not active event list */
+- if (ddr_pmu->events[EVENT_CYCLES_COUNTER] == NULL)
+- ddr_perf_counter_enable(ddr_pmu,
+- EVENT_CYCLES_ID,
+- EVENT_CYCLES_COUNTER,
+- true);
+ }
+
+ static void ddr_perf_pmu_disable(struct pmu *pmu)
+ {
+- struct ddr_pmu *ddr_pmu = to_ddr_pmu(pmu);
+-
+- if (ddr_pmu->events[EVENT_CYCLES_COUNTER] == NULL)
+- ddr_perf_counter_enable(ddr_pmu,
+- EVENT_CYCLES_ID,
+- EVENT_CYCLES_COUNTER,
+- false);
+ }
+
+ static int ddr_perf_init(struct ddr_pmu *pmu, void __iomem *base,
+--
+2.40.1
+
--- /dev/null
+From aad8c27381a116319fea5ad318d4143e2c8dd07c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Jun 2023 17:10:21 +0000
+Subject: phy/rockchip: inno-hdmi: do not power on rk3328 post pll on reg write
+
+From: Jonas Karlman <jonas@kwiboo.se>
+
+[ Upstream commit 19a1d46bd699940a496d3b0d4e142ef99834988c ]
+
+inno_write is used to configure 0xaa reg, that also hold the
+POST_PLL_POWER_DOWN bit.
+When POST_PLL_REFCLK_SEL_TMDS is configured the power down bit is not
+taken into consideration.
+
+Fix this by keeping the power down bit until configuration is complete.
+Also reorder the reg write order for consistency.
+
+Fixes: 53706a116863 ("phy: add Rockchip Innosilicon hdmi phy")
+Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
+Link: https://lore.kernel.org/r/20230615171005.2251032-5-jonas@kwiboo.se
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
+index 7d412f771f6c3..fbdc23953b52e 100644
+--- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
++++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
+@@ -1023,9 +1023,10 @@ inno_hdmi_phy_rk3328_power_on(struct inno_hdmi_phy *inno,
+
+ inno_write(inno, 0xac, RK3328_POST_PLL_FB_DIV_7_0(cfg->fbdiv));
+ if (cfg->postdiv == 1) {
+- inno_write(inno, 0xaa, RK3328_POST_PLL_REFCLK_SEL_TMDS);
+ inno_write(inno, 0xab, RK3328_POST_PLL_FB_DIV_8(cfg->fbdiv) |
+ RK3328_POST_PLL_PRE_DIV(cfg->prediv));
++ inno_write(inno, 0xaa, RK3328_POST_PLL_REFCLK_SEL_TMDS |
++ RK3328_POST_PLL_POWER_DOWN);
+ } else {
+ v = (cfg->postdiv / 2) - 1;
+ v &= RK3328_POST_PLL_POST_DIV_MASK;
+@@ -1033,7 +1034,8 @@ inno_hdmi_phy_rk3328_power_on(struct inno_hdmi_phy *inno,
+ inno_write(inno, 0xab, RK3328_POST_PLL_FB_DIV_8(cfg->fbdiv) |
+ RK3328_POST_PLL_PRE_DIV(cfg->prediv));
+ inno_write(inno, 0xaa, RK3328_POST_PLL_POST_DIV_ENABLE |
+- RK3328_POST_PLL_REFCLK_SEL_TMDS);
++ RK3328_POST_PLL_REFCLK_SEL_TMDS |
++ RK3328_POST_PLL_POWER_DOWN);
+ }
+
+ for (v = 0; v < 14; v++)
+--
+2.40.1
+
--- /dev/null
+From b9c0cc765559bd1c95b76665b2af336d9b9e86db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Jun 2023 17:10:19 +0000
+Subject: phy/rockchip: inno-hdmi: round fractal pixclock in rk3328 recalc_rate
+
+From: Zheng Yang <zhengyang@rock-chips.com>
+
+[ Upstream commit d5ef343c1d62bc4c4c2c393af654a41cb34b449f ]
+
+inno_hdmi_phy_rk3328_clk_recalc_rate() is returning a rate not found
+in the pre pll config table when the fractal divider is used.
+This can prevent proper power_on because a tmdsclock for the new rate
+is not found in the pre pll config table.
+
+Fix this by saving and returning a rounded pixel rate that exist
+in the pre pll config table.
+
+Fixes: 53706a116863 ("phy: add Rockchip Innosilicon hdmi phy")
+Signed-off-by: Zheng Yang <zhengyang@rock-chips.com>
+Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
+Link: https://lore.kernel.org/r/20230615171005.2251032-3-jonas@kwiboo.se
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
+index f348e5347d817..7d412f771f6c3 100644
+--- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
++++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
+@@ -745,10 +745,12 @@ unsigned long inno_hdmi_phy_rk3328_clk_recalc_rate(struct clk_hw *hw,
+ do_div(vco, (nd * (no_a == 1 ? no_b : no_a) * no_d * 2));
+ }
+
+- inno->pixclock = vco;
+- dev_dbg(inno->dev, "%s rate %lu\n", __func__, inno->pixclock);
++ inno->pixclock = DIV_ROUND_CLOSEST((unsigned long)vco, 1000) * 1000;
+
+- return vco;
++ dev_dbg(inno->dev, "%s rate %lu vco %llu\n",
++ __func__, inno->pixclock, vco);
++
++ return inno->pixclock;
+ }
+
+ static long inno_hdmi_phy_rk3328_clk_round_rate(struct clk_hw *hw,
+--
+2.40.1
+
--- /dev/null
+From b27633cc34fa3f10f2e29a8407179216d6f29e58 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Jun 2023 17:10:17 +0000
+Subject: phy/rockchip: inno-hdmi: use correct vco_div_5 macro on rk3328
+
+From: Jonas Karlman <jonas@kwiboo.se>
+
+[ Upstream commit 644c06dfbd0da713f772abf0a8f8581ac78e6264 ]
+
+inno_hdmi_phy_rk3328_clk_set_rate() is using the RK3228 macro
+when configuring vco_div_5 on RK3328.
+
+Fix this by using correct vco_div_5 macro for RK3328.
+
+Fixes: 53706a116863 ("phy: add Rockchip Innosilicon hdmi phy")
+Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
+Link: https://lore.kernel.org/r/20230615171005.2251032-2-jonas@kwiboo.se
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
+index 1e1563f5fffc4..f348e5347d817 100644
+--- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
++++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
+@@ -790,8 +790,8 @@ static int inno_hdmi_phy_rk3328_clk_set_rate(struct clk_hw *hw,
+ RK3328_PRE_PLL_POWER_DOWN);
+
+ /* Configure pre-pll */
+- inno_update_bits(inno, 0xa0, RK3228_PCLK_VCO_DIV_5_MASK,
+- RK3228_PCLK_VCO_DIV_5(cfg->vco_div_5_en));
++ inno_update_bits(inno, 0xa0, RK3328_PCLK_VCO_DIV_5_MASK,
++ RK3328_PCLK_VCO_DIV_5(cfg->vco_div_5_en));
+ inno_write(inno, 0xa1, RK3328_PRE_PLL_PRE_DIV(cfg->prediv));
+
+ val = RK3328_SPREAD_SPECTRUM_MOD_DISABLE;
+--
+2.40.1
+
--- /dev/null
+From a171f25a9f6aacd72f76ff57e9dbdfa38d0c323e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Jun 2023 13:04:09 +0300
+Subject: pinctrl: mcp23s08: check return value of devm_kasprintf()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Claudiu Beznea <claudiu.beznea@microchip.com>
+
+[ Upstream commit f941714a7c7698eadb59bc27d34d6d6f38982705 ]
+
+devm_kasprintf() returns a pointer to dynamically allocated memory.
+Pointer could be NULL in case allocation fails. Check pointer validity.
+Identified with coccinelle (kmerr.cocci script).
+
+Fixes: 0f04a81784fe ("pinctrl: mcp23s08: Split to three parts: core, I²C, SPI")
+Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://lore.kernel.org/r/20230621100409.1608395-1-claudiu.beznea@microchip.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/pinctrl-mcp23s08_spi.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/pinctrl/pinctrl-mcp23s08_spi.c b/drivers/pinctrl/pinctrl-mcp23s08_spi.c
+index 9ae10318f6f35..ea059b9c5542e 100644
+--- a/drivers/pinctrl/pinctrl-mcp23s08_spi.c
++++ b/drivers/pinctrl/pinctrl-mcp23s08_spi.c
+@@ -91,18 +91,28 @@ static int mcp23s08_spi_regmap_init(struct mcp23s08 *mcp, struct device *dev,
+ mcp->reg_shift = 0;
+ mcp->chip.ngpio = 8;
+ mcp->chip.label = devm_kasprintf(dev, GFP_KERNEL, "mcp23s08.%d", addr);
++ if (!mcp->chip.label)
++ return -ENOMEM;
+
+ config = &mcp23x08_regmap;
+ name = devm_kasprintf(dev, GFP_KERNEL, "%d", addr);
++ if (!name)
++ return -ENOMEM;
++
+ break;
+
+ case MCP_TYPE_S17:
+ mcp->reg_shift = 1;
+ mcp->chip.ngpio = 16;
+ mcp->chip.label = devm_kasprintf(dev, GFP_KERNEL, "mcp23s17.%d", addr);
++ if (!mcp->chip.label)
++ return -ENOMEM;
+
+ config = &mcp23x17_regmap;
+ name = devm_kasprintf(dev, GFP_KERNEL, "%d", addr);
++ if (!name)
++ return -ENOMEM;
++
+ break;
+
+ case MCP_TYPE_S18:
+--
+2.40.1
+
--- /dev/null
+From 8ecc249358e0b263a3f90608f8267e44019e6936 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Aug 2023 04:03:26 +0100
+Subject: pinctrl: mediatek: assign functions to configure pin bias on MT7986
+
+From: Daniel Golle <daniel@makrotopia.org>
+
+[ Upstream commit 0d8387fba9f151220e48dc3dcdc2335539708f13 ]
+
+Assign bias_disable_get/set and bias_get/set functions to allow
+configuring pin bias on MT7986.
+
+Fixes: 2c58d8dc9cd0 ("pinctrl: mediatek: add pull_type attribute for mediatek MT7986 SoC")
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://lore.kernel.org/r/47f72372354312a839b9337e09476aadcc206e8b.1692327317.git.daniel@makrotopia.org
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/mediatek/pinctrl-mt7986.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7986.c b/drivers/pinctrl/mediatek/pinctrl-mt7986.c
+index aa0ccd67f4f4e..acaac9b38aa8a 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-mt7986.c
++++ b/drivers/pinctrl/mediatek/pinctrl-mt7986.c
+@@ -922,6 +922,10 @@ static struct mtk_pin_soc mt7986a_data = {
+ .ies_present = false,
+ .base_names = mt7986_pinctrl_register_base_names,
+ .nbase_names = ARRAY_SIZE(mt7986_pinctrl_register_base_names),
++ .bias_disable_set = mtk_pinconf_bias_disable_set,
++ .bias_disable_get = mtk_pinconf_bias_disable_get,
++ .bias_set = mtk_pinconf_bias_set,
++ .bias_get = mtk_pinconf_bias_get,
+ .pull_type = mt7986_pull_type,
+ .bias_set_combo = mtk_pinconf_bias_set_combo,
+ .bias_get_combo = mtk_pinconf_bias_get_combo,
+@@ -944,6 +948,10 @@ static struct mtk_pin_soc mt7986b_data = {
+ .ies_present = false,
+ .base_names = mt7986_pinctrl_register_base_names,
+ .nbase_names = ARRAY_SIZE(mt7986_pinctrl_register_base_names),
++ .bias_disable_set = mtk_pinconf_bias_disable_set,
++ .bias_disable_get = mtk_pinconf_bias_disable_get,
++ .bias_set = mtk_pinconf_bias_set,
++ .bias_get = mtk_pinconf_bias_get,
+ .pull_type = mt7986_pull_type,
+ .bias_set_combo = mtk_pinconf_bias_set_combo,
+ .bias_get_combo = mtk_pinconf_bias_get_combo,
+--
+2.40.1
+
--- /dev/null
+From 94f85694268acaa3d478a5c5b4be4ce6c2b8eacf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Aug 2023 04:02:35 +0100
+Subject: pinctrl: mediatek: fix pull_type data for MT7981
+
+From: Daniel Golle <daniel@makrotopia.org>
+
+[ Upstream commit 8f6f16fe1553ce63edfb98a39ef9d4754a0c39bf ]
+
+MediaTek has released pull_type data for MT7981 in their SDK.
+Use it and set functions to configure pin bias.
+
+Fixes: 6c83b2d94fcc ("pinctrl: add mt7981 pinctrl driver")
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://lore.kernel.org/r/7bcc8ead25dbfabc7f5a85d066224a926fbb4941.1692327317.git.daniel@makrotopia.org
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/mediatek/pinctrl-mt7981.c | 44 +++++++----------------
+ 1 file changed, 13 insertions(+), 31 deletions(-)
+
+diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7981.c b/drivers/pinctrl/mediatek/pinctrl-mt7981.c
+index 18abc57800111..0fd2c0c451f95 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-mt7981.c
++++ b/drivers/pinctrl/mediatek/pinctrl-mt7981.c
+@@ -457,37 +457,15 @@ static const unsigned int mt7981_pull_type[] = {
+ MTK_PULL_PUPD_R1R0_TYPE,/*34*/ MTK_PULL_PUPD_R1R0_TYPE,/*35*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*36*/ MTK_PULL_PUPD_R1R0_TYPE,/*37*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*38*/ MTK_PULL_PUPD_R1R0_TYPE,/*39*/
+- MTK_PULL_PUPD_R1R0_TYPE,/*40*/ MTK_PULL_PUPD_R1R0_TYPE,/*41*/
+- MTK_PULL_PUPD_R1R0_TYPE,/*42*/ MTK_PULL_PUPD_R1R0_TYPE,/*43*/
+- MTK_PULL_PUPD_R1R0_TYPE,/*44*/ MTK_PULL_PUPD_R1R0_TYPE,/*45*/
+- MTK_PULL_PUPD_R1R0_TYPE,/*46*/ MTK_PULL_PUPD_R1R0_TYPE,/*47*/
+- MTK_PULL_PUPD_R1R0_TYPE,/*48*/ MTK_PULL_PUPD_R1R0_TYPE,/*49*/
+- MTK_PULL_PUPD_R1R0_TYPE,/*50*/ MTK_PULL_PUPD_R1R0_TYPE,/*51*/
+- MTK_PULL_PUPD_R1R0_TYPE,/*52*/ MTK_PULL_PUPD_R1R0_TYPE,/*53*/
+- MTK_PULL_PUPD_R1R0_TYPE,/*54*/ MTK_PULL_PUPD_R1R0_TYPE,/*55*/
+- MTK_PULL_PUPD_R1R0_TYPE,/*56*/ MTK_PULL_PUPD_R1R0_TYPE,/*57*/
+- MTK_PULL_PUPD_R1R0_TYPE,/*58*/ MTK_PULL_PUPD_R1R0_TYPE,/*59*/
+- MTK_PULL_PUPD_R1R0_TYPE,/*60*/ MTK_PULL_PUPD_R1R0_TYPE,/*61*/
+- MTK_PULL_PUPD_R1R0_TYPE,/*62*/ MTK_PULL_PUPD_R1R0_TYPE,/*63*/
+- MTK_PULL_PUPD_R1R0_TYPE,/*64*/ MTK_PULL_PUPD_R1R0_TYPE,/*65*/
+- MTK_PULL_PUPD_R1R0_TYPE,/*66*/ MTK_PULL_PUPD_R1R0_TYPE,/*67*/
+- MTK_PULL_PUPD_R1R0_TYPE,/*68*/ MTK_PULL_PU_PD_TYPE,/*69*/
+- MTK_PULL_PU_PD_TYPE,/*70*/ MTK_PULL_PU_PD_TYPE,/*71*/
+- MTK_PULL_PU_PD_TYPE,/*72*/ MTK_PULL_PU_PD_TYPE,/*73*/
+- MTK_PULL_PU_PD_TYPE,/*74*/ MTK_PULL_PU_PD_TYPE,/*75*/
+- MTK_PULL_PU_PD_TYPE,/*76*/ MTK_PULL_PU_PD_TYPE,/*77*/
+- MTK_PULL_PU_PD_TYPE,/*78*/ MTK_PULL_PU_PD_TYPE,/*79*/
+- MTK_PULL_PU_PD_TYPE,/*80*/ MTK_PULL_PU_PD_TYPE,/*81*/
+- MTK_PULL_PU_PD_TYPE,/*82*/ MTK_PULL_PU_PD_TYPE,/*83*/
+- MTK_PULL_PU_PD_TYPE,/*84*/ MTK_PULL_PU_PD_TYPE,/*85*/
+- MTK_PULL_PU_PD_TYPE,/*86*/ MTK_PULL_PU_PD_TYPE,/*87*/
+- MTK_PULL_PU_PD_TYPE,/*88*/ MTK_PULL_PU_PD_TYPE,/*89*/
+- MTK_PULL_PU_PD_TYPE,/*90*/ MTK_PULL_PU_PD_TYPE,/*91*/
+- MTK_PULL_PU_PD_TYPE,/*92*/ MTK_PULL_PU_PD_TYPE,/*93*/
+- MTK_PULL_PU_PD_TYPE,/*94*/ MTK_PULL_PU_PD_TYPE,/*95*/
+- MTK_PULL_PU_PD_TYPE,/*96*/ MTK_PULL_PU_PD_TYPE,/*97*/
+- MTK_PULL_PU_PD_TYPE,/*98*/ MTK_PULL_PU_PD_TYPE,/*99*/
+- MTK_PULL_PU_PD_TYPE,/*100*/
++ MTK_PULL_PU_PD_TYPE,/*40*/ MTK_PULL_PU_PD_TYPE,/*41*/
++ MTK_PULL_PU_PD_TYPE,/*42*/ MTK_PULL_PU_PD_TYPE,/*43*/
++ MTK_PULL_PU_PD_TYPE,/*44*/ MTK_PULL_PU_PD_TYPE,/*45*/
++ MTK_PULL_PU_PD_TYPE,/*46*/ MTK_PULL_PU_PD_TYPE,/*47*/
++ MTK_PULL_PU_PD_TYPE,/*48*/ MTK_PULL_PU_PD_TYPE,/*49*/
++ MTK_PULL_PU_PD_TYPE,/*50*/ MTK_PULL_PU_PD_TYPE,/*51*/
++ MTK_PULL_PU_PD_TYPE,/*52*/ MTK_PULL_PU_PD_TYPE,/*53*/
++ MTK_PULL_PU_PD_TYPE,/*54*/ MTK_PULL_PU_PD_TYPE,/*55*/
++ MTK_PULL_PU_PD_TYPE,/*56*/
+ };
+
+ static const struct mtk_pin_reg_calc mt7981_reg_cals[] = {
+@@ -1014,6 +992,10 @@ static struct mtk_pin_soc mt7981_data = {
+ .ies_present = false,
+ .base_names = mt7981_pinctrl_register_base_names,
+ .nbase_names = ARRAY_SIZE(mt7981_pinctrl_register_base_names),
++ .bias_disable_set = mtk_pinconf_bias_disable_set,
++ .bias_disable_get = mtk_pinconf_bias_disable_get,
++ .bias_set = mtk_pinconf_bias_set,
++ .bias_get = mtk_pinconf_bias_get,
+ .pull_type = mt7981_pull_type,
+ .bias_set_combo = mtk_pinconf_bias_set_combo,
+ .bias_get_combo = mtk_pinconf_bias_get_combo,
+--
+2.40.1
+
--- /dev/null
+From 2e8973a32528b5fee28fe557e4f9685171c20671 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Aug 2023 13:54:21 -0500
+Subject: platform/x86/amd/pmf: Fix a missing cleanup path
+
+From: Mario Limonciello <mario.limonciello@amd.com>
+
+[ Upstream commit 4dbd6e61adc7e52dd1c9165f0ccaa90806611e40 ]
+
+On systems that support slider notifications but don't otherwise support
+granular slider the SPS cleanup path doesn't run.
+
+This means that loading/unloading/loading leads to failures because
+the sysfs files don't get setup properly when reloaded.
+
+Add the missing cleanup path.
+
+Fixes: 33c9ab5b493a ("platform/x86/amd/pmf: Notify OS power slider update")
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Link: https://lore.kernel.org/r/20230823185421.23959-1-mario.limonciello@amd.com
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/amd/pmf/core.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/platform/x86/amd/pmf/core.c b/drivers/platform/x86/amd/pmf/core.c
+index a022325161273..6fa33a05c5a75 100644
+--- a/drivers/platform/x86/amd/pmf/core.c
++++ b/drivers/platform/x86/amd/pmf/core.c
+@@ -322,7 +322,8 @@ static void amd_pmf_init_features(struct amd_pmf_dev *dev)
+
+ static void amd_pmf_deinit_features(struct amd_pmf_dev *dev)
+ {
+- if (is_apmf_func_supported(dev, APMF_FUNC_STATIC_SLIDER_GRANULAR)) {
++ if (is_apmf_func_supported(dev, APMF_FUNC_STATIC_SLIDER_GRANULAR) ||
++ is_apmf_func_supported(dev, APMF_FUNC_OS_POWER_SLIDER_UPDATE)) {
+ power_supply_unreg_notifier(&dev->pwr_src_notifier);
+ amd_pmf_deinit_sps(dev);
+ }
+--
+2.40.1
+
--- /dev/null
+From f628aa55a5b6b46e0f829126d358c9eab1e2f13e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 5 Aug 2023 07:36:10 +0200
+Subject: platform/x86: dell-sysman: Fix reference leak
+
+From: Armin Wolf <W_Armin@gmx.de>
+
+[ Upstream commit 7295a996fdab7bf83dc3d4078fa8b139b8e0a1bf ]
+
+If a duplicate attribute is found using kset_find_obj(),
+a reference to that attribute is returned. This means
+that we need to dispose it accordingly. Use kobject_put()
+to dispose the duplicate attribute in such a case.
+
+Compile-tested only.
+
+Fixes: e8a60aa7404b ("platform/x86: Introduce support for Systems Management Driver over WMI for Dell Systems")
+Signed-off-by: Armin Wolf <W_Armin@gmx.de>
+Link: https://lore.kernel.org/r/20230805053610.7106-1-W_Armin@gmx.de
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/dell/dell-wmi-sysman/sysman.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c b/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c
+index 0285b47d99d13..1dd5aa37ecc8b 100644
+--- a/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c
++++ b/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c
+@@ -396,6 +396,7 @@ static int init_bios_attributes(int attr_type, const char *guid)
+ struct kobject *attr_name_kobj; //individual attribute names
+ union acpi_object *obj = NULL;
+ union acpi_object *elements;
++ struct kobject *duplicate;
+ struct kset *tmp_set;
+ int min_elements;
+
+@@ -454,9 +455,11 @@ static int init_bios_attributes(int attr_type, const char *guid)
+ else
+ tmp_set = wmi_priv.main_dir_kset;
+
+- if (kset_find_obj(tmp_set, elements[ATTR_NAME].string.pointer)) {
+- pr_debug("duplicate attribute name found - %s\n",
+- elements[ATTR_NAME].string.pointer);
++ duplicate = kset_find_obj(tmp_set, elements[ATTR_NAME].string.pointer);
++ if (duplicate) {
++ pr_debug("Duplicate attribute name found - %s\n",
++ elements[ATTR_NAME].string.pointer);
++ kobject_put(duplicate);
+ goto nextobj;
+ }
+
+--
+2.40.1
+
--- /dev/null
+From b7a33864bd32e0022ab59cccd886f98745c87ae9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Aug 2023 14:31:31 -0400
+Subject: pNFS: Fix assignment of xprtdata.cred
+
+From: Anna Schumaker <Anna.Schumaker@Netapp.com>
+
+[ Upstream commit c4a123d2e8c4dc91d581ee7d05c0cd51a0273fab ]
+
+The comma at the end of the line was leftover from an earlier refactor
+of the _nfs4_pnfs_v3_ds_connect() function. This is technically valid C,
+so the compilers didn't catch it, but if I'm understanding how it works
+correctly it assigns the return value of rpc_clnt_add_xprtr() to
+xprtdata.cred.
+
+Reported-by: Olga Kornievskaia <kolga@netapp.com>
+Fixes: a12f996d3413 ("NFSv4/pNFS: Use connections to a DS that are all of the same protocol family")
+Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/pnfs_nfs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/nfs/pnfs_nfs.c b/fs/nfs/pnfs_nfs.c
+index a0112ad4937aa..2e14ce2f82191 100644
+--- a/fs/nfs/pnfs_nfs.c
++++ b/fs/nfs/pnfs_nfs.c
+@@ -943,7 +943,7 @@ static int _nfs4_pnfs_v4_ds_connect(struct nfs_server *mds_srv,
+ * Test this address for session trunking and
+ * add as an alias
+ */
+- xprtdata.cred = nfs4_get_clid_cred(clp),
++ xprtdata.cred = nfs4_get_clid_cred(clp);
+ rpc_clnt_add_xprt(clp->cl_rpcclient, &xprt_args,
+ rpc_clnt_setup_test_and_add_xprt,
+ &rpcdata);
+--
+2.40.1
+
--- /dev/null
+From e539e74c8dc2be415938f483d70a06e6c29e75d3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Jul 2023 11:17:26 +0100
+Subject: powercap: arm_scmi: Remove recursion while parsing zones
+
+From: Cristian Marussi <cristian.marussi@arm.com>
+
+[ Upstream commit 3e767d6850f867cc33ac16ca097350a1d2417982 ]
+
+Powercap zones can be defined as arranged in a hierarchy of trees and when
+registering a zone with powercap_register_zone(), the kernel powercap
+subsystem expects this to happen starting from the root zones down to the
+leaves; on the other side, de-registration by powercap_deregister_zone()
+must begin from the leaf zones.
+
+Available SCMI powercap zones are retrieved dynamically from the platform
+at probe time and, while any defined hierarchy between the zones is
+described properly in the zones descriptor, the platform returns the
+availables zones with no particular well-defined order: as a consequence,
+the trees possibly composing the hierarchy of zones have to be somehow
+walked properly to register the retrieved zones from the root.
+
+Currently the ARM SCMI Powercap driver walks the zones using a recursive
+algorithm; this approach, even though correct and tested can lead to kernel
+stack overflow when processing a returned hierarchy of zones composed by
+particularly high trees.
+
+Avoid possible kernel stack overflow by substituting the recursive approach
+with an iterative one supported by a dynamically allocated stack-like data
+structure.
+
+Fixes: b55eef5226b7 ("powercap: arm_scmi: Add SCMI Powercap based driver")
+Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
+Acked-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/powercap/arm_scmi_powercap.c | 159 ++++++++++++++++-----------
+ 1 file changed, 92 insertions(+), 67 deletions(-)
+
+diff --git a/drivers/powercap/arm_scmi_powercap.c b/drivers/powercap/arm_scmi_powercap.c
+index 05d0e516176a5..5d7330280bd83 100644
+--- a/drivers/powercap/arm_scmi_powercap.c
++++ b/drivers/powercap/arm_scmi_powercap.c
+@@ -12,6 +12,7 @@
+ #include <linux/module.h>
+ #include <linux/powercap.h>
+ #include <linux/scmi_protocol.h>
++#include <linux/slab.h>
+
+ #define to_scmi_powercap_zone(z) \
+ container_of(z, struct scmi_powercap_zone, zone)
+@@ -19,6 +20,8 @@
+ static const struct scmi_powercap_proto_ops *powercap_ops;
+
+ struct scmi_powercap_zone {
++ bool registered;
++ bool invalid;
+ unsigned int height;
+ struct device *dev;
+ struct scmi_protocol_handle *ph;
+@@ -32,6 +35,7 @@ struct scmi_powercap_root {
+ unsigned int num_zones;
+ struct scmi_powercap_zone *spzones;
+ struct list_head *registered_zones;
++ struct list_head scmi_zones;
+ };
+
+ static struct powercap_control_type *scmi_top_pcntrl;
+@@ -255,12 +259,6 @@ static void scmi_powercap_unregister_all_zones(struct scmi_powercap_root *pr)
+ }
+ }
+
+-static inline bool
+-scmi_powercap_is_zone_registered(struct scmi_powercap_zone *spz)
+-{
+- return !list_empty(&spz->node);
+-}
+-
+ static inline unsigned int
+ scmi_powercap_get_zone_height(struct scmi_powercap_zone *spz)
+ {
+@@ -279,11 +277,46 @@ scmi_powercap_get_parent_zone(struct scmi_powercap_zone *spz)
+ return &spz->spzones[spz->info->parent_id];
+ }
+
++static int scmi_powercap_register_zone(struct scmi_powercap_root *pr,
++ struct scmi_powercap_zone *spz,
++ struct scmi_powercap_zone *parent)
++{
++ int ret = 0;
++ struct powercap_zone *z;
++
++ if (spz->invalid) {
++ list_del(&spz->node);
++ return -EINVAL;
++ }
++
++ z = powercap_register_zone(&spz->zone, scmi_top_pcntrl, spz->info->name,
++ parent ? &parent->zone : NULL,
++ &zone_ops, 1, &constraint_ops);
++ if (!IS_ERR(z)) {
++ spz->height = scmi_powercap_get_zone_height(spz);
++ spz->registered = true;
++ list_move(&spz->node, &pr->registered_zones[spz->height]);
++ dev_dbg(spz->dev, "Registered node %s - parent %s - height:%d\n",
++ spz->info->name, parent ? parent->info->name : "ROOT",
++ spz->height);
++ } else {
++ list_del(&spz->node);
++ ret = PTR_ERR(z);
++ dev_err(spz->dev,
++ "Error registering node:%s - parent:%s - h:%d - ret:%d\n",
++ spz->info->name,
++ parent ? parent->info->name : "ROOT",
++ spz->height, ret);
++ }
++
++ return ret;
++}
++
+ /**
+- * scmi_powercap_register_zone - Register an SCMI powercap zone recursively
++ * scmi_zones_register- Register SCMI powercap zones starting from parent zones
+ *
++ * @dev: A reference to the SCMI device
+ * @pr: A reference to the root powercap zones descriptors
+- * @spz: A reference to the SCMI powercap zone to register
+ *
+ * When registering SCMI powercap zones with the powercap framework we should
+ * take care to always register zones starting from the root ones and to
+@@ -293,10 +326,10 @@ scmi_powercap_get_parent_zone(struct scmi_powercap_zone *spz)
+ * zones provided by the SCMI platform firmware is built to comply with such
+ * requirement.
+ *
+- * This function, given an SCMI powercap zone to register, takes care to walk
+- * the SCMI powercap zones tree up to the root looking recursively for
+- * unregistered parent zones before registering the provided zone; at the same
+- * time each registered zone height in such a tree is accounted for and each
++ * This function, given the set of SCMI powercap zones to register, takes care
++ * to walk the SCMI powercap zones trees up to the root registering any
++ * unregistered parent zone before registering the child zones; at the same
++ * time each registered-zone height in such a tree is accounted for and each
+ * zone, once registered, is stored in the @registered_zones array that is
+ * indexed by zone height: this way will be trivial, at unregister time, to walk
+ * the @registered_zones array backward and unregister all the zones starting
+@@ -314,57 +347,55 @@ scmi_powercap_get_parent_zone(struct scmi_powercap_zone *spz)
+ *
+ * Return: 0 on Success
+ */
+-static int scmi_powercap_register_zone(struct scmi_powercap_root *pr,
+- struct scmi_powercap_zone *spz)
++static int scmi_zones_register(struct device *dev,
++ struct scmi_powercap_root *pr)
+ {
+ int ret = 0;
+- struct scmi_powercap_zone *parent;
+-
+- if (!spz->info)
+- return ret;
++ unsigned int sp = 0, reg_zones = 0;
++ struct scmi_powercap_zone *spz, **zones_stack;
+
+- parent = scmi_powercap_get_parent_zone(spz);
+- if (parent && !scmi_powercap_is_zone_registered(parent)) {
+- /*
+- * Bail out if a parent domain was marked as unsupported:
+- * only domains participating as leaves can be skipped.
+- */
+- if (!parent->info)
+- return -ENODEV;
++ zones_stack = kcalloc(pr->num_zones, sizeof(spz), GFP_KERNEL);
++ if (!zones_stack)
++ return -ENOMEM;
+
+- ret = scmi_powercap_register_zone(pr, parent);
+- if (ret)
+- return ret;
+- }
++ spz = list_first_entry_or_null(&pr->scmi_zones,
++ struct scmi_powercap_zone, node);
++ while (spz) {
++ struct scmi_powercap_zone *parent;
+
+- if (!scmi_powercap_is_zone_registered(spz)) {
+- struct powercap_zone *z;
+-
+- z = powercap_register_zone(&spz->zone,
+- scmi_top_pcntrl,
+- spz->info->name,
+- parent ? &parent->zone : NULL,
+- &zone_ops, 1, &constraint_ops);
+- if (!IS_ERR(z)) {
+- spz->height = scmi_powercap_get_zone_height(spz);
+- list_add(&spz->node,
+- &pr->registered_zones[spz->height]);
+- dev_dbg(spz->dev,
+- "Registered node %s - parent %s - height:%d\n",
+- spz->info->name,
+- parent ? parent->info->name : "ROOT",
+- spz->height);
+- ret = 0;
++ parent = scmi_powercap_get_parent_zone(spz);
++ if (parent && !parent->registered) {
++ zones_stack[sp++] = spz;
++ spz = parent;
+ } else {
+- ret = PTR_ERR(z);
+- dev_err(spz->dev,
+- "Error registering node:%s - parent:%s - h:%d - ret:%d\n",
+- spz->info->name,
+- parent ? parent->info->name : "ROOT",
+- spz->height, ret);
++ ret = scmi_powercap_register_zone(pr, spz, parent);
++ if (!ret) {
++ reg_zones++;
++ } else if (sp) {
++ /* Failed to register a non-leaf zone.
++ * Bail-out.
++ */
++ dev_err(dev,
++ "Failed to register non-leaf zone - ret:%d\n",
++ ret);
++ scmi_powercap_unregister_all_zones(pr);
++ reg_zones = 0;
++ goto out;
++ }
++ /* Pick next zone to process */
++ if (sp)
++ spz = zones_stack[--sp];
++ else
++ spz = list_first_entry_or_null(&pr->scmi_zones,
++ struct scmi_powercap_zone,
++ node);
+ }
+ }
+
++out:
++ kfree(zones_stack);
++ dev_info(dev, "Registered %d SCMI Powercap domains !\n", reg_zones);
++
+ return ret;
+ }
+
+@@ -408,6 +439,8 @@ static int scmi_powercap_probe(struct scmi_device *sdev)
+ if (!pr->registered_zones)
+ return -ENOMEM;
+
++ INIT_LIST_HEAD(&pr->scmi_zones);
++
+ for (i = 0, spz = pr->spzones; i < pr->num_zones; i++, spz++) {
+ /*
+ * Powercap domains are validate by the protocol layer, i.e.
+@@ -422,6 +455,7 @@ static int scmi_powercap_probe(struct scmi_device *sdev)
+ INIT_LIST_HEAD(&spz->node);
+ INIT_LIST_HEAD(&pr->registered_zones[i]);
+
++ list_add_tail(&spz->node, &pr->scmi_zones);
+ /*
+ * Forcibly skip powercap domains using an abstract scale.
+ * Note that only leaves domains can be skipped, so this could
+@@ -432,7 +466,7 @@ static int scmi_powercap_probe(struct scmi_device *sdev)
+ dev_warn(dev,
+ "Abstract power scale not supported. Skip %s.\n",
+ spz->info->name);
+- spz->info = NULL;
++ spz->invalid = true;
+ continue;
+ }
+ }
+@@ -441,21 +475,12 @@ static int scmi_powercap_probe(struct scmi_device *sdev)
+ * Scan array of retrieved SCMI powercap domains and register them
+ * recursively starting from the root domains.
+ */
+- for (i = 0, spz = pr->spzones; i < pr->num_zones; i++, spz++) {
+- ret = scmi_powercap_register_zone(pr, spz);
+- if (ret) {
+- dev_err(dev,
+- "Failed to register powercap zone %s - ret:%d\n",
+- spz->info->name, ret);
+- scmi_powercap_unregister_all_zones(pr);
+- return ret;
+- }
+- }
++ ret = scmi_zones_register(dev, pr);
++ if (ret)
++ return ret;
+
+ dev_set_drvdata(dev, pr);
+
+- dev_info(dev, "Registered %d SCMI Powercap domains !\n", pr->num_zones);
+-
+ return ret;
+ }
+
+--
+2.40.1
+
--- /dev/null
+From b8cd5ebedc37bfc9b320d673d02276441642b9c7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Aug 2023 15:53:16 +1000
+Subject: powerpc: Don't include lppaca.h in paca.h
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+[ Upstream commit 1aa000667669fa855853decbb1c69e974d8ff716 ]
+
+By adding a forward declaration for struct lppaca we can untangle paca.h
+and lppaca.h. Also move get_lppaca() into lppaca.h for consistency.
+
+Add includes of lppaca.h to some files that need it.
+
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/20230823055317.751786-3-mpe@ellerman.id.au
+Stable-dep-of: eac030b22ea1 ("powerpc/pseries: Rework lppaca_shared_proc() to avoid DEBUG_PREEMPT")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/include/asm/lppaca.h | 4 ++++
+ arch/powerpc/include/asm/paca.h | 6 +-----
+ arch/powerpc/include/asm/paravirt.h | 1 +
+ arch/powerpc/include/asm/plpar_wrappers.h | 1 +
+ arch/powerpc/kvm/book3s_hv_ras.c | 1 +
+ arch/powerpc/mm/book3s64/slb.c | 1 +
+ arch/powerpc/xmon/xmon.c | 1 +
+ 7 files changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/arch/powerpc/include/asm/lppaca.h b/arch/powerpc/include/asm/lppaca.h
+index 34d44cb17c874..fe278172e9d42 100644
+--- a/arch/powerpc/include/asm/lppaca.h
++++ b/arch/powerpc/include/asm/lppaca.h
+@@ -134,6 +134,10 @@ static inline bool lppaca_shared_proc(struct lppaca *l)
+ return !!(l->__old_status & LPPACA_OLD_SHARED_PROC);
+ }
+
++#ifdef CONFIG_PPC_PSERIES
++#define get_lppaca() (get_paca()->lppaca_ptr)
++#endif
++
+ /*
+ * SLB shadow buffer structure as defined in the PAPR. The save_area
+ * contains adjacent ESID and VSID pairs for each shadowed SLB. The
+diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h
+index da0377f465973..46ac4647b5fb9 100644
+--- a/arch/powerpc/include/asm/paca.h
++++ b/arch/powerpc/include/asm/paca.h
+@@ -15,7 +15,6 @@
+ #include <linux/cache.h>
+ #include <linux/string.h>
+ #include <asm/types.h>
+-#include <asm/lppaca.h>
+ #include <asm/mmu.h>
+ #include <asm/page.h>
+ #ifdef CONFIG_PPC_BOOK3E_64
+@@ -47,14 +46,11 @@ extern unsigned int debug_smp_processor_id(void); /* from linux/smp.h */
+ #define get_paca() local_paca
+ #endif
+
+-#ifdef CONFIG_PPC_PSERIES
+-#define get_lppaca() (get_paca()->lppaca_ptr)
+-#endif
+-
+ #define get_slb_shadow() (get_paca()->slb_shadow_ptr)
+
+ struct task_struct;
+ struct rtas_args;
++struct lppaca;
+
+ /*
+ * Defines the layout of the paca.
+diff --git a/arch/powerpc/include/asm/paravirt.h b/arch/powerpc/include/asm/paravirt.h
+index f5ba1a3c41f8e..e08513d731193 100644
+--- a/arch/powerpc/include/asm/paravirt.h
++++ b/arch/powerpc/include/asm/paravirt.h
+@@ -6,6 +6,7 @@
+ #include <asm/smp.h>
+ #ifdef CONFIG_PPC64
+ #include <asm/paca.h>
++#include <asm/lppaca.h>
+ #include <asm/hvcall.h>
+ #endif
+
+diff --git a/arch/powerpc/include/asm/plpar_wrappers.h b/arch/powerpc/include/asm/plpar_wrappers.h
+index 8239c0af5eb2b..fe3d0ea0058ac 100644
+--- a/arch/powerpc/include/asm/plpar_wrappers.h
++++ b/arch/powerpc/include/asm/plpar_wrappers.h
+@@ -9,6 +9,7 @@
+
+ #include <asm/hvcall.h>
+ #include <asm/paca.h>
++#include <asm/lppaca.h>
+ #include <asm/page.h>
+
+ static inline long poll_pending(void)
+diff --git a/arch/powerpc/kvm/book3s_hv_ras.c b/arch/powerpc/kvm/book3s_hv_ras.c
+index ccfd969656306..82be6d87514b7 100644
+--- a/arch/powerpc/kvm/book3s_hv_ras.c
++++ b/arch/powerpc/kvm/book3s_hv_ras.c
+@@ -9,6 +9,7 @@
+ #include <linux/kvm.h>
+ #include <linux/kvm_host.h>
+ #include <linux/kernel.h>
++#include <asm/lppaca.h>
+ #include <asm/opal.h>
+ #include <asm/mce.h>
+ #include <asm/machdep.h>
+diff --git a/arch/powerpc/mm/book3s64/slb.c b/arch/powerpc/mm/book3s64/slb.c
+index 6956f637a38c1..f2708c8629a52 100644
+--- a/arch/powerpc/mm/book3s64/slb.c
++++ b/arch/powerpc/mm/book3s64/slb.c
+@@ -13,6 +13,7 @@
+ #include <asm/mmu.h>
+ #include <asm/mmu_context.h>
+ #include <asm/paca.h>
++#include <asm/lppaca.h>
+ #include <asm/ppc-opcode.h>
+ #include <asm/cputable.h>
+ #include <asm/cacheflush.h>
+diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
+index 70c4c59a1a8f4..70ce51b8a9291 100644
+--- a/arch/powerpc/xmon/xmon.c
++++ b/arch/powerpc/xmon/xmon.c
+@@ -58,6 +58,7 @@
+ #ifdef CONFIG_PPC64
+ #include <asm/hvcall.h>
+ #include <asm/paca.h>
++#include <asm/lppaca.h>
+ #endif
+
+ #include "nonstdio.h"
+--
+2.40.1
+
--- /dev/null
+From 45441bb39b19a7b4f765ec4416d02bb64c20fdf6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Jul 2023 10:37:15 +0530
+Subject: powerpc/fadump: reset dump area size if fadump memory reserve fails
+
+From: Sourabh Jain <sourabhjain@linux.ibm.com>
+
+[ Upstream commit d1eb75e0dfed80d2d85b664e28a39f65b290ab55 ]
+
+In case fadump_reserve_mem() fails to reserve memory, the
+reserve_dump_area_size variable will retain the reserve area size. This
+will lead to /sys/kernel/fadump/mem_reserved node displaying an incorrect
+memory reserved by fadump.
+
+To fix this problem, reserve dump area size variable is set to 0 if fadump
+failed to reserve memory.
+
+Fixes: 8255da95e545 ("powerpc/fadump: release all the memory above boot memory size")
+Signed-off-by: Sourabh Jain <sourabhjain@linux.ibm.com>
+Acked-by: Mahesh Salgaonkar <mahesh@linux.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/20230704050715.203581-1-sourabhjain@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/fadump.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c
+index ea0a073abd969..3ff2da7b120b5 100644
+--- a/arch/powerpc/kernel/fadump.c
++++ b/arch/powerpc/kernel/fadump.c
+@@ -654,6 +654,7 @@ int __init fadump_reserve_mem(void)
+ return ret;
+ error_out:
+ fw_dump.fadump_enabled = 0;
++ fw_dump.reserve_dump_area_size = 0;
+ return 0;
+ }
+
+--
+2.40.1
+
--- /dev/null
+From dff9420151e9d5c6d1f42bc607ad2e33c140d794 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Mar 2023 14:53:22 +1100
+Subject: powerpc/iommu: Fix notifiers being shared by PCI and VIO buses
+
+From: Russell Currey <ruscur@russell.cc>
+
+[ Upstream commit c37b6908f7b2bd24dcaaf14a180e28c9132b9c58 ]
+
+fail_iommu_setup() registers the fail_iommu_bus_notifier struct to both
+PCI and VIO buses. struct notifier_block is a linked list node, so this
+causes any notifiers later registered to either bus type to also be
+registered to the other since they share the same node.
+
+This causes issues in (at least) the vgaarb code, which registers a
+notifier for PCI buses. pci_notify() ends up being called on a vio
+device, converted with to_pci_dev() even though it's not a PCI device,
+and finally makes a bad access in vga_arbiter_add_pci_device() as
+discovered with KASAN:
+
+ BUG: KASAN: slab-out-of-bounds in vga_arbiter_add_pci_device+0x60/0xe00
+ Read of size 4 at addr c000000264c26fdc by task swapper/0/1
+
+ Call Trace:
+ dump_stack_lvl+0x1bc/0x2b8 (unreliable)
+ print_report+0x3f4/0xc60
+ kasan_report+0x244/0x698
+ __asan_load4+0xe8/0x250
+ vga_arbiter_add_pci_device+0x60/0xe00
+ pci_notify+0x88/0x444
+ notifier_call_chain+0x104/0x320
+ blocking_notifier_call_chain+0xa0/0x140
+ device_add+0xac8/0x1d30
+ device_register+0x58/0x80
+ vio_register_device_node+0x9ac/0xce0
+ vio_bus_scan_register_devices+0xc4/0x13c
+ __machine_initcall_pseries_vio_device_init+0x94/0xf0
+ do_one_initcall+0x12c/0xaa8
+ kernel_init_freeable+0xa48/0xba8
+ kernel_init+0x64/0x400
+ ret_from_kernel_thread+0x5c/0x64
+
+Fix this by creating separate notifier_block structs for each bus type.
+
+Fixes: d6b9a81b2a45 ("powerpc: IOMMU fault injection")
+Reported-by: Nageswara R Sastry <rnsastry@linux.ibm.com>
+Signed-off-by: Russell Currey <ruscur@russell.cc>
+Tested-by: Nageswara R Sastry <rnsastry@linux.ibm.com>
+Reviewed-by: Andrew Donnellan <ajd@linux.ibm.com>
+[mpe: Add #ifdef to fix CONFIG_IBMVIO=n build]
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/20230322035322.328709-1-ruscur@russell.cc
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/iommu.c | 17 ++++++++++++++---
+ 1 file changed, 14 insertions(+), 3 deletions(-)
+
+diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
+index 67f0b01e6ff57..400831307cd7b 100644
+--- a/arch/powerpc/kernel/iommu.c
++++ b/arch/powerpc/kernel/iommu.c
+@@ -172,17 +172,28 @@ static int fail_iommu_bus_notify(struct notifier_block *nb,
+ return 0;
+ }
+
+-static struct notifier_block fail_iommu_bus_notifier = {
++/*
++ * PCI and VIO buses need separate notifier_block structs, since they're linked
++ * list nodes. Sharing a notifier_block would mean that any notifiers later
++ * registered for PCI buses would also get called by VIO buses and vice versa.
++ */
++static struct notifier_block fail_iommu_pci_bus_notifier = {
+ .notifier_call = fail_iommu_bus_notify
+ };
+
++#ifdef CONFIG_IBMVIO
++static struct notifier_block fail_iommu_vio_bus_notifier = {
++ .notifier_call = fail_iommu_bus_notify
++};
++#endif
++
+ static int __init fail_iommu_setup(void)
+ {
+ #ifdef CONFIG_PCI
+- bus_register_notifier(&pci_bus_type, &fail_iommu_bus_notifier);
++ bus_register_notifier(&pci_bus_type, &fail_iommu_pci_bus_notifier);
+ #endif
+ #ifdef CONFIG_IBMVIO
+- bus_register_notifier(&vio_bus_type, &fail_iommu_bus_notifier);
++ bus_register_notifier(&vio_bus_type, &fail_iommu_vio_bus_notifier);
+ #endif
+
+ return 0;
+--
+2.40.1
+
--- /dev/null
+From 5e0ac9cc7634c7097edc64c1c3f5227228d1d901 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Mar 2023 11:04:23 +0800
+Subject: powerpc/mpc5xxx: Add missing fwnode_handle_put()
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit b9bbbf4979073d5536b7650decd37fcb901e6556 ]
+
+In mpc5xxx_fwnode_get_bus_frequency(), we should add
+fwnode_handle_put() when break out of the iteration
+fwnode_for_each_parent_node() as it will automatically
+increase and decrease the refcounter.
+
+Fixes: de06fba62af6 ("powerpc/mpc5xxx: Switch mpc5xxx_get_bus_frequency() to use fwnode")
+Signed-off-by: Liang He <windhl@126.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/20230322030423.1855440-1-windhl@126.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/sysdev/mpc5xxx_clocks.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/arch/powerpc/sysdev/mpc5xxx_clocks.c b/arch/powerpc/sysdev/mpc5xxx_clocks.c
+index c5bf7e1b37804..58cee28e23992 100644
+--- a/arch/powerpc/sysdev/mpc5xxx_clocks.c
++++ b/arch/powerpc/sysdev/mpc5xxx_clocks.c
+@@ -25,8 +25,10 @@ unsigned long mpc5xxx_fwnode_get_bus_frequency(struct fwnode_handle *fwnode)
+
+ fwnode_for_each_parent_node(fwnode, parent) {
+ ret = fwnode_property_read_u32(parent, "bus-frequency", &bus_freq);
+- if (!ret)
++ if (!ret) {
++ fwnode_handle_put(parent);
+ return bus_freq;
++ }
+ }
+
+ return 0;
+--
+2.40.1
+
--- /dev/null
+From 31ce69cd57c23b065a7aa3e3a599fbbf334d7632 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Aug 2023 10:59:44 +0200
+Subject: powerpc/perf: Convert fsl_emb notifier to state machine callbacks
+
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+
+[ Upstream commit 34daf445f82bd3a4df852bb5f1dffd792ac830a0 ]
+
+ CC arch/powerpc/perf/core-fsl-emb.o
+arch/powerpc/perf/core-fsl-emb.c:675:6: error: no previous prototype for 'hw_perf_event_setup' [-Werror=missing-prototypes]
+ 675 | void hw_perf_event_setup(int cpu)
+ | ^~~~~~~~~~~~~~~~~~~
+
+Looks like fsl_emb was completely missed by commit 3f6da3905398 ("perf:
+Rework and fix the arch CPU-hotplug hooks")
+
+So, apply same changes as commit 3f6da3905398 ("perf: Rework and fix
+the arch CPU-hotplug hooks") then commit 57ecde42cc74 ("powerpc/perf:
+Convert book3s notifier to state machine callbacks")
+
+While at it, also fix following error:
+
+arch/powerpc/perf/core-fsl-emb.c: In function 'perf_event_interrupt':
+arch/powerpc/perf/core-fsl-emb.c:648:13: error: variable 'found' set but not used [-Werror=unused-but-set-variable]
+ 648 | int found = 0;
+ | ^~~~~
+
+Fixes: 3f6da3905398 ("perf: Rework and fix the arch CPU-hotplug hooks")
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/603e1facb32608f88f40b7d7b9094adc50e7b2dc.1692349125.git.christophe.leroy@csgroup.eu
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/perf/core-fsl-emb.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/arch/powerpc/perf/core-fsl-emb.c b/arch/powerpc/perf/core-fsl-emb.c
+index ee721f420a7ba..1a53ab08447cb 100644
+--- a/arch/powerpc/perf/core-fsl-emb.c
++++ b/arch/powerpc/perf/core-fsl-emb.c
+@@ -645,7 +645,6 @@ static void perf_event_interrupt(struct pt_regs *regs)
+ struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
+ struct perf_event *event;
+ unsigned long val;
+- int found = 0;
+
+ for (i = 0; i < ppmu->n_counter; ++i) {
+ event = cpuhw->event[i];
+@@ -654,7 +653,6 @@ static void perf_event_interrupt(struct pt_regs *regs)
+ if ((int)val < 0) {
+ if (event) {
+ /* event has overflowed */
+- found = 1;
+ record_and_restart(event, val, regs);
+ } else {
+ /*
+@@ -672,11 +670,13 @@ static void perf_event_interrupt(struct pt_regs *regs)
+ isync();
+ }
+
+-void hw_perf_event_setup(int cpu)
++static int fsl_emb_pmu_prepare_cpu(unsigned int cpu)
+ {
+ struct cpu_hw_events *cpuhw = &per_cpu(cpu_hw_events, cpu);
+
+ memset(cpuhw, 0, sizeof(*cpuhw));
++
++ return 0;
+ }
+
+ int register_fsl_emb_pmu(struct fsl_emb_pmu *pmu)
+@@ -689,6 +689,8 @@ int register_fsl_emb_pmu(struct fsl_emb_pmu *pmu)
+ pmu->name);
+
+ perf_pmu_register(&fsl_emb_pmu, "cpu", PERF_TYPE_RAW);
++ cpuhp_setup_state(CPUHP_PERF_POWER, "perf/powerpc:prepare",
++ fsl_emb_pmu_prepare_cpu, NULL);
+
+ return 0;
+ }
+--
+2.40.1
+
--- /dev/null
+From e01aee75cc6fd37bcd73efe18cf84735b66d145c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 May 2023 19:15:59 +1000
+Subject: powerpc/pseries: Fix hcall tracepoints with JUMP_LABEL=n
+
+From: Nicholas Piggin <npiggin@gmail.com>
+
+[ Upstream commit 750bd41aeaeb1f0e0128aa4f8fcd6dd759713641 ]
+
+With JUMP_LABEL=n, hcall_tracepoint_refcount's address is being tested
+instead of its value. This results in the tracing slowpath always being
+taken unnecessarily.
+
+Fixes: 9a10ccb29c0a2 ("powerpc/pseries: move hcall_tracepoint_refcount out of .toc")
+Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/20230509091600.70994-1-npiggin@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/platforms/pseries/hvCall.S | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/powerpc/platforms/pseries/hvCall.S b/arch/powerpc/platforms/pseries/hvCall.S
+index 35254ac7af5ee..ca0674b0b683e 100644
+--- a/arch/powerpc/platforms/pseries/hvCall.S
++++ b/arch/powerpc/platforms/pseries/hvCall.S
+@@ -91,6 +91,7 @@ BEGIN_FTR_SECTION; \
+ b 1f; \
+ END_FTR_SECTION(0, 1); \
+ LOAD_REG_ADDR(r12, hcall_tracepoint_refcount) ; \
++ ld r12,0(r12); \
+ std r12,32(r1); \
+ cmpdi r12,0; \
+ bne- LABEL; \
+--
+2.40.1
+
--- /dev/null
+From 2ec7066b16fc935a0868bcd4a7d529ef3de4e27a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Aug 2023 15:53:17 +1000
+Subject: powerpc/pseries: Rework lppaca_shared_proc() to avoid DEBUG_PREEMPT
+
+From: Russell Currey <ruscur@russell.cc>
+
+[ Upstream commit eac030b22ea12cdfcbb2e941c21c03964403c63f ]
+
+lppaca_shared_proc() takes a pointer to the lppaca which is typically
+accessed through get_lppaca(). With DEBUG_PREEMPT enabled, this leads
+to checking if preemption is enabled, for example:
+
+ BUG: using smp_processor_id() in preemptible [00000000] code: grep/10693
+ caller is lparcfg_data+0x408/0x19a0
+ CPU: 4 PID: 10693 Comm: grep Not tainted 6.5.0-rc3 #2
+ Call Trace:
+ dump_stack_lvl+0x154/0x200 (unreliable)
+ check_preemption_disabled+0x214/0x220
+ lparcfg_data+0x408/0x19a0
+ ...
+
+This isn't actually a problem however, as it does not matter which
+lppaca is accessed, the shared proc state will be the same.
+vcpudispatch_stats_procfs_init() already works around this by disabling
+preemption, but the lparcfg code does not, erroring any time
+/proc/powerpc/lparcfg is accessed with DEBUG_PREEMPT enabled.
+
+Instead of disabling preemption on the caller side, rework
+lppaca_shared_proc() to not take a pointer and instead directly access
+the lppaca, bypassing any potential preemption checks.
+
+Fixes: f13c13a00512 ("powerpc: Stop using non-architected shared_proc field in lppaca")
+Signed-off-by: Russell Currey <ruscur@russell.cc>
+[mpe: Rework to avoid needing a definition in paca.h and lppaca.h]
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/20230823055317.751786-4-mpe@ellerman.id.au
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/include/asm/lppaca.h | 11 +++++++++--
+ arch/powerpc/platforms/pseries/lpar.c | 10 +---------
+ arch/powerpc/platforms/pseries/lparcfg.c | 4 ++--
+ arch/powerpc/platforms/pseries/setup.c | 2 +-
+ drivers/cpuidle/cpuidle-pseries.c | 8 +-------
+ 5 files changed, 14 insertions(+), 21 deletions(-)
+
+diff --git a/arch/powerpc/include/asm/lppaca.h b/arch/powerpc/include/asm/lppaca.h
+index fe278172e9d42..ee1488d38fdc1 100644
+--- a/arch/powerpc/include/asm/lppaca.h
++++ b/arch/powerpc/include/asm/lppaca.h
+@@ -45,6 +45,7 @@
+ #include <asm/types.h>
+ #include <asm/mmu.h>
+ #include <asm/firmware.h>
++#include <asm/paca.h>
+
+ /*
+ * The lppaca is the "virtual processor area" registered with the hypervisor,
+@@ -127,14 +128,20 @@ struct lppaca {
+ */
+ #define LPPACA_OLD_SHARED_PROC 2
+
+-static inline bool lppaca_shared_proc(struct lppaca *l)
++#ifdef CONFIG_PPC_PSERIES
++/*
++ * All CPUs should have the same shared proc value, so directly access the PACA
++ * to avoid false positives from DEBUG_PREEMPT.
++ */
++static inline bool lppaca_shared_proc(void)
+ {
++ struct lppaca *l = local_paca->lppaca_ptr;
++
+ if (!firmware_has_feature(FW_FEATURE_SPLPAR))
+ return false;
+ return !!(l->__old_status & LPPACA_OLD_SHARED_PROC);
+ }
+
+-#ifdef CONFIG_PPC_PSERIES
+ #define get_lppaca() (get_paca()->lppaca_ptr)
+ #endif
+
+diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
+index 2eab323f69706..cb2f1211f7ebf 100644
+--- a/arch/powerpc/platforms/pseries/lpar.c
++++ b/arch/powerpc/platforms/pseries/lpar.c
+@@ -639,16 +639,8 @@ static const struct proc_ops vcpudispatch_stats_freq_proc_ops = {
+
+ static int __init vcpudispatch_stats_procfs_init(void)
+ {
+- /*
+- * Avoid smp_processor_id while preemptible. All CPUs should have
+- * the same value for lppaca_shared_proc.
+- */
+- preempt_disable();
+- if (!lppaca_shared_proc(get_lppaca())) {
+- preempt_enable();
++ if (!lppaca_shared_proc())
+ return 0;
+- }
+- preempt_enable();
+
+ if (!proc_create("powerpc/vcpudispatch_stats", 0600, NULL,
+ &vcpudispatch_stats_proc_ops))
+diff --git a/arch/powerpc/platforms/pseries/lparcfg.c b/arch/powerpc/platforms/pseries/lparcfg.c
+index 8acc705095209..1c151d77e74b3 100644
+--- a/arch/powerpc/platforms/pseries/lparcfg.c
++++ b/arch/powerpc/platforms/pseries/lparcfg.c
+@@ -206,7 +206,7 @@ static void parse_ppp_data(struct seq_file *m)
+ ppp_data.active_system_procs);
+
+ /* pool related entries are appropriate for shared configs */
+- if (lppaca_shared_proc(get_lppaca())) {
++ if (lppaca_shared_proc()) {
+ unsigned long pool_idle_time, pool_procs;
+
+ seq_printf(m, "pool=%d\n", ppp_data.pool_num);
+@@ -560,7 +560,7 @@ static int pseries_lparcfg_data(struct seq_file *m, void *v)
+ partition_potential_processors);
+
+ seq_printf(m, "shared_processor_mode=%d\n",
+- lppaca_shared_proc(get_lppaca()));
++ lppaca_shared_proc());
+
+ #ifdef CONFIG_PPC_64S_HASH_MMU
+ if (!radix_enabled())
+diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
+index e2a57cfa6c837..0ef2a7e014aa1 100644
+--- a/arch/powerpc/platforms/pseries/setup.c
++++ b/arch/powerpc/platforms/pseries/setup.c
+@@ -847,7 +847,7 @@ static void __init pSeries_setup_arch(void)
+ if (firmware_has_feature(FW_FEATURE_LPAR)) {
+ vpa_init(boot_cpuid);
+
+- if (lppaca_shared_proc(get_lppaca())) {
++ if (lppaca_shared_proc()) {
+ static_branch_enable(&shared_processor);
+ pv_spinlocks_init();
+ #ifdef CONFIG_PARAVIRT_TIME_ACCOUNTING
+diff --git a/drivers/cpuidle/cpuidle-pseries.c b/drivers/cpuidle/cpuidle-pseries.c
+index a7d33f3ee01e7..14db9b7d985d1 100644
+--- a/drivers/cpuidle/cpuidle-pseries.c
++++ b/drivers/cpuidle/cpuidle-pseries.c
+@@ -414,13 +414,7 @@ static int __init pseries_idle_probe(void)
+ return -ENODEV;
+
+ if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
+- /*
+- * Use local_paca instead of get_lppaca() since
+- * preemption is not disabled, and it is not required in
+- * fact, since lppaca_ptr does not need to be the value
+- * associated to the current CPU, it can be from any CPU.
+- */
+- if (lppaca_shared_proc(local_paca->lppaca_ptr)) {
++ if (lppaca_shared_proc()) {
+ cpuidle_state_table = shared_states;
+ max_idle_state = ARRAY_SIZE(shared_states);
+ } else {
+--
+2.40.1
+
--- /dev/null
+From 40a1a0f56eb74970a74be046f94cf03c8f39ac09 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Aug 2023 10:01:43 +0200
+Subject: powerpc/radix: Move some functions into #ifdef
+ CONFIG_KVM_BOOK3S_HV_POSSIBLE
+
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+
+[ Upstream commit 4a9dd8f292efd614f0a18452e6474fe19ae17b47 ]
+
+With skiboot_defconfig, Clang reports:
+
+ CC arch/powerpc/mm/book3s64/radix_tlb.o
+arch/powerpc/mm/book3s64/radix_tlb.c:419:20: error: unused function '_tlbie_pid_lpid' [-Werror,-Wunused-function]
+static inline void _tlbie_pid_lpid(unsigned long pid, unsigned long lpid,
+ ^
+arch/powerpc/mm/book3s64/radix_tlb.c:663:20: error: unused function '_tlbie_va_range_lpid' [-Werror,-Wunused-function]
+static inline void _tlbie_va_range_lpid(unsigned long start, unsigned long end,
+ ^
+
+This is because those functions are only called from functions
+enclosed in a #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
+
+Move below functions inside that #ifdef
+* __tlbie_pid_lpid(unsigned long pid,
+* __tlbie_va_lpid(unsigned long va, unsigned long pid,
+* fixup_tlbie_pid_lpid(unsigned long pid, unsigned long lpid)
+* _tlbie_pid_lpid(unsigned long pid, unsigned long lpid,
+* fixup_tlbie_va_range_lpid(unsigned long va,
+* __tlbie_va_range_lpid(unsigned long start, unsigned long end,
+* _tlbie_va_range_lpid(unsigned long start, unsigned long end,
+
+Fixes: f0c6fbbb9050 ("KVM: PPC: Book3S HV: Add support for H_RPT_INVALIDATE")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202307260802.Mjr99P5O-lkp@intel.com/
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/3d72efd39f986ee939d068af69fdce28bd600766.1691568093.git.christophe.leroy@csgroup.eu
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/mm/book3s64/radix_tlb.c | 240 ++++++++++++++-------------
+ 1 file changed, 121 insertions(+), 119 deletions(-)
+
+diff --git a/arch/powerpc/mm/book3s64/radix_tlb.c b/arch/powerpc/mm/book3s64/radix_tlb.c
+index 0bd4866d98241..9383606c5e6e0 100644
+--- a/arch/powerpc/mm/book3s64/radix_tlb.c
++++ b/arch/powerpc/mm/book3s64/radix_tlb.c
+@@ -127,21 +127,6 @@ static __always_inline void __tlbie_pid(unsigned long pid, unsigned long ric)
+ trace_tlbie(0, 0, rb, rs, ric, prs, r);
+ }
+
+-static __always_inline void __tlbie_pid_lpid(unsigned long pid,
+- unsigned long lpid,
+- unsigned long ric)
+-{
+- unsigned long rb, rs, prs, r;
+-
+- rb = PPC_BIT(53); /* IS = 1 */
+- rs = (pid << PPC_BITLSHIFT(31)) | (lpid & ~(PPC_BITMASK(0, 31)));
+- prs = 1; /* process scoped */
+- r = 1; /* radix format */
+-
+- asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1)
+- : : "r"(rb), "i"(r), "i"(prs), "i"(ric), "r"(rs) : "memory");
+- trace_tlbie(0, 0, rb, rs, ric, prs, r);
+-}
+ static __always_inline void __tlbie_lpid(unsigned long lpid, unsigned long ric)
+ {
+ unsigned long rb,rs,prs,r;
+@@ -202,23 +187,6 @@ static __always_inline void __tlbie_va(unsigned long va, unsigned long pid,
+ trace_tlbie(0, 0, rb, rs, ric, prs, r);
+ }
+
+-static __always_inline void __tlbie_va_lpid(unsigned long va, unsigned long pid,
+- unsigned long lpid,
+- unsigned long ap, unsigned long ric)
+-{
+- unsigned long rb, rs, prs, r;
+-
+- rb = va & ~(PPC_BITMASK(52, 63));
+- rb |= ap << PPC_BITLSHIFT(58);
+- rs = (pid << PPC_BITLSHIFT(31)) | (lpid & ~(PPC_BITMASK(0, 31)));
+- prs = 1; /* process scoped */
+- r = 1; /* radix format */
+-
+- asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1)
+- : : "r"(rb), "i"(r), "i"(prs), "i"(ric), "r"(rs) : "memory");
+- trace_tlbie(0, 0, rb, rs, ric, prs, r);
+-}
+-
+ static __always_inline void __tlbie_lpid_va(unsigned long va, unsigned long lpid,
+ unsigned long ap, unsigned long ric)
+ {
+@@ -264,22 +232,6 @@ static inline void fixup_tlbie_va_range(unsigned long va, unsigned long pid,
+ }
+ }
+
+-static inline void fixup_tlbie_va_range_lpid(unsigned long va,
+- unsigned long pid,
+- unsigned long lpid,
+- unsigned long ap)
+-{
+- if (cpu_has_feature(CPU_FTR_P9_TLBIE_ERAT_BUG)) {
+- asm volatile("ptesync" : : : "memory");
+- __tlbie_pid_lpid(0, lpid, RIC_FLUSH_TLB);
+- }
+-
+- if (cpu_has_feature(CPU_FTR_P9_TLBIE_STQ_BUG)) {
+- asm volatile("ptesync" : : : "memory");
+- __tlbie_va_lpid(va, pid, lpid, ap, RIC_FLUSH_TLB);
+- }
+-}
+-
+ static inline void fixup_tlbie_pid(unsigned long pid)
+ {
+ /*
+@@ -299,26 +251,6 @@ static inline void fixup_tlbie_pid(unsigned long pid)
+ }
+ }
+
+-static inline void fixup_tlbie_pid_lpid(unsigned long pid, unsigned long lpid)
+-{
+- /*
+- * We can use any address for the invalidation, pick one which is
+- * probably unused as an optimisation.
+- */
+- unsigned long va = ((1UL << 52) - 1);
+-
+- if (cpu_has_feature(CPU_FTR_P9_TLBIE_ERAT_BUG)) {
+- asm volatile("ptesync" : : : "memory");
+- __tlbie_pid_lpid(0, lpid, RIC_FLUSH_TLB);
+- }
+-
+- if (cpu_has_feature(CPU_FTR_P9_TLBIE_STQ_BUG)) {
+- asm volatile("ptesync" : : : "memory");
+- __tlbie_va_lpid(va, pid, lpid, mmu_get_ap(MMU_PAGE_64K),
+- RIC_FLUSH_TLB);
+- }
+-}
+-
+ static inline void fixup_tlbie_lpid_va(unsigned long va, unsigned long lpid,
+ unsigned long ap)
+ {
+@@ -416,31 +348,6 @@ static inline void _tlbie_pid(unsigned long pid, unsigned long ric)
+ asm volatile("eieio; tlbsync; ptesync": : :"memory");
+ }
+
+-static inline void _tlbie_pid_lpid(unsigned long pid, unsigned long lpid,
+- unsigned long ric)
+-{
+- asm volatile("ptesync" : : : "memory");
+-
+- /*
+- * Workaround the fact that the "ric" argument to __tlbie_pid
+- * must be a compile-time contraint to match the "i" constraint
+- * in the asm statement.
+- */
+- switch (ric) {
+- case RIC_FLUSH_TLB:
+- __tlbie_pid_lpid(pid, lpid, RIC_FLUSH_TLB);
+- fixup_tlbie_pid_lpid(pid, lpid);
+- break;
+- case RIC_FLUSH_PWC:
+- __tlbie_pid_lpid(pid, lpid, RIC_FLUSH_PWC);
+- break;
+- case RIC_FLUSH_ALL:
+- default:
+- __tlbie_pid_lpid(pid, lpid, RIC_FLUSH_ALL);
+- fixup_tlbie_pid_lpid(pid, lpid);
+- }
+- asm volatile("eieio; tlbsync; ptesync" : : : "memory");
+-}
+ struct tlbiel_pid {
+ unsigned long pid;
+ unsigned long ric;
+@@ -566,20 +473,6 @@ static inline void __tlbie_va_range(unsigned long start, unsigned long end,
+ fixup_tlbie_va_range(addr - page_size, pid, ap);
+ }
+
+-static inline void __tlbie_va_range_lpid(unsigned long start, unsigned long end,
+- unsigned long pid, unsigned long lpid,
+- unsigned long page_size,
+- unsigned long psize)
+-{
+- unsigned long addr;
+- unsigned long ap = mmu_get_ap(psize);
+-
+- for (addr = start; addr < end; addr += page_size)
+- __tlbie_va_lpid(addr, pid, lpid, ap, RIC_FLUSH_TLB);
+-
+- fixup_tlbie_va_range_lpid(addr - page_size, pid, lpid, ap);
+-}
+-
+ static __always_inline void _tlbie_va(unsigned long va, unsigned long pid,
+ unsigned long psize, unsigned long ric)
+ {
+@@ -660,18 +553,6 @@ static inline void _tlbie_va_range(unsigned long start, unsigned long end,
+ asm volatile("eieio; tlbsync; ptesync": : :"memory");
+ }
+
+-static inline void _tlbie_va_range_lpid(unsigned long start, unsigned long end,
+- unsigned long pid, unsigned long lpid,
+- unsigned long page_size,
+- unsigned long psize, bool also_pwc)
+-{
+- asm volatile("ptesync" : : : "memory");
+- if (also_pwc)
+- __tlbie_pid_lpid(pid, lpid, RIC_FLUSH_PWC);
+- __tlbie_va_range_lpid(start, end, pid, lpid, page_size, psize);
+- asm volatile("eieio; tlbsync; ptesync" : : : "memory");
+-}
+-
+ static inline void _tlbiel_va_range_multicast(struct mm_struct *mm,
+ unsigned long start, unsigned long end,
+ unsigned long pid, unsigned long page_size,
+@@ -1486,6 +1367,127 @@ void radix__flush_tlb_all(void)
+ }
+
+ #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
++static __always_inline void __tlbie_pid_lpid(unsigned long pid,
++ unsigned long lpid,
++ unsigned long ric)
++{
++ unsigned long rb, rs, prs, r;
++
++ rb = PPC_BIT(53); /* IS = 1 */
++ rs = (pid << PPC_BITLSHIFT(31)) | (lpid & ~(PPC_BITMASK(0, 31)));
++ prs = 1; /* process scoped */
++ r = 1; /* radix format */
++
++ asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1)
++ : : "r"(rb), "i"(r), "i"(prs), "i"(ric), "r"(rs) : "memory");
++ trace_tlbie(0, 0, rb, rs, ric, prs, r);
++}
++
++static __always_inline void __tlbie_va_lpid(unsigned long va, unsigned long pid,
++ unsigned long lpid,
++ unsigned long ap, unsigned long ric)
++{
++ unsigned long rb, rs, prs, r;
++
++ rb = va & ~(PPC_BITMASK(52, 63));
++ rb |= ap << PPC_BITLSHIFT(58);
++ rs = (pid << PPC_BITLSHIFT(31)) | (lpid & ~(PPC_BITMASK(0, 31)));
++ prs = 1; /* process scoped */
++ r = 1; /* radix format */
++
++ asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1)
++ : : "r"(rb), "i"(r), "i"(prs), "i"(ric), "r"(rs) : "memory");
++ trace_tlbie(0, 0, rb, rs, ric, prs, r);
++}
++
++static inline void fixup_tlbie_pid_lpid(unsigned long pid, unsigned long lpid)
++{
++ /*
++ * We can use any address for the invalidation, pick one which is
++ * probably unused as an optimisation.
++ */
++ unsigned long va = ((1UL << 52) - 1);
++
++ if (cpu_has_feature(CPU_FTR_P9_TLBIE_ERAT_BUG)) {
++ asm volatile("ptesync" : : : "memory");
++ __tlbie_pid_lpid(0, lpid, RIC_FLUSH_TLB);
++ }
++
++ if (cpu_has_feature(CPU_FTR_P9_TLBIE_STQ_BUG)) {
++ asm volatile("ptesync" : : : "memory");
++ __tlbie_va_lpid(va, pid, lpid, mmu_get_ap(MMU_PAGE_64K),
++ RIC_FLUSH_TLB);
++ }
++}
++
++static inline void _tlbie_pid_lpid(unsigned long pid, unsigned long lpid,
++ unsigned long ric)
++{
++ asm volatile("ptesync" : : : "memory");
++
++ /*
++ * Workaround the fact that the "ric" argument to __tlbie_pid
++ * must be a compile-time contraint to match the "i" constraint
++ * in the asm statement.
++ */
++ switch (ric) {
++ case RIC_FLUSH_TLB:
++ __tlbie_pid_lpid(pid, lpid, RIC_FLUSH_TLB);
++ fixup_tlbie_pid_lpid(pid, lpid);
++ break;
++ case RIC_FLUSH_PWC:
++ __tlbie_pid_lpid(pid, lpid, RIC_FLUSH_PWC);
++ break;
++ case RIC_FLUSH_ALL:
++ default:
++ __tlbie_pid_lpid(pid, lpid, RIC_FLUSH_ALL);
++ fixup_tlbie_pid_lpid(pid, lpid);
++ }
++ asm volatile("eieio; tlbsync; ptesync" : : : "memory");
++}
++
++static inline void fixup_tlbie_va_range_lpid(unsigned long va,
++ unsigned long pid,
++ unsigned long lpid,
++ unsigned long ap)
++{
++ if (cpu_has_feature(CPU_FTR_P9_TLBIE_ERAT_BUG)) {
++ asm volatile("ptesync" : : : "memory");
++ __tlbie_pid_lpid(0, lpid, RIC_FLUSH_TLB);
++ }
++
++ if (cpu_has_feature(CPU_FTR_P9_TLBIE_STQ_BUG)) {
++ asm volatile("ptesync" : : : "memory");
++ __tlbie_va_lpid(va, pid, lpid, ap, RIC_FLUSH_TLB);
++ }
++}
++
++static inline void __tlbie_va_range_lpid(unsigned long start, unsigned long end,
++ unsigned long pid, unsigned long lpid,
++ unsigned long page_size,
++ unsigned long psize)
++{
++ unsigned long addr;
++ unsigned long ap = mmu_get_ap(psize);
++
++ for (addr = start; addr < end; addr += page_size)
++ __tlbie_va_lpid(addr, pid, lpid, ap, RIC_FLUSH_TLB);
++
++ fixup_tlbie_va_range_lpid(addr - page_size, pid, lpid, ap);
++}
++
++static inline void _tlbie_va_range_lpid(unsigned long start, unsigned long end,
++ unsigned long pid, unsigned long lpid,
++ unsigned long page_size,
++ unsigned long psize, bool also_pwc)
++{
++ asm volatile("ptesync" : : : "memory");
++ if (also_pwc)
++ __tlbie_pid_lpid(pid, lpid, RIC_FLUSH_PWC);
++ __tlbie_va_range_lpid(start, end, pid, lpid, page_size, psize);
++ asm volatile("eieio; tlbsync; ptesync" : : : "memory");
++}
++
+ /*
+ * Performs process-scoped invalidations for a given LPID
+ * as part of H_RPT_INVALIDATE hcall.
+--
+2.40.1
+
--- /dev/null
+From e7f8b696757ce9b9d7ec614a8942a8ad7ff4279e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Jun 2023 19:08:20 +0800
+Subject: quota: add new helper dquot_active()
+
+From: Baokun Li <libaokun1@huawei.com>
+
+[ Upstream commit 33bcfafc48cb186bc4bbcea247feaa396594229e ]
+
+Add new helper function dquot_active() to make the code more concise.
+
+Signed-off-by: Baokun Li <libaokun1@huawei.com>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Message-Id: <20230630110822.3881712-4-libaokun1@huawei.com>
+Stable-dep-of: dabc8b207566 ("quota: fix dqput() to follow the guarantees dquot_srcu should provide")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/quota/dquot.c | 23 ++++++++++++++---------
+ 1 file changed, 14 insertions(+), 9 deletions(-)
+
+diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
+index a08698d9859a8..88aa747f48008 100644
+--- a/fs/quota/dquot.c
++++ b/fs/quota/dquot.c
+@@ -336,6 +336,11 @@ static void wait_on_dquot(struct dquot *dquot)
+ mutex_unlock(&dquot->dq_lock);
+ }
+
++static inline int dquot_active(struct dquot *dquot)
++{
++ return test_bit(DQ_ACTIVE_B, &dquot->dq_flags);
++}
++
+ static inline int dquot_dirty(struct dquot *dquot)
+ {
+ return test_bit(DQ_MOD_B, &dquot->dq_flags);
+@@ -351,14 +356,14 @@ int dquot_mark_dquot_dirty(struct dquot *dquot)
+ {
+ int ret = 1;
+
+- if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags))
++ if (!dquot_active(dquot))
+ return 0;
+
+ if (sb_dqopt(dquot->dq_sb)->flags & DQUOT_NOLIST_DIRTY)
+ return test_and_set_bit(DQ_MOD_B, &dquot->dq_flags);
+
+ /* If quota is dirty already, we don't have to acquire dq_list_lock */
+- if (test_bit(DQ_MOD_B, &dquot->dq_flags))
++ if (dquot_dirty(dquot))
+ return 1;
+
+ spin_lock(&dq_list_lock);
+@@ -440,7 +445,7 @@ int dquot_acquire(struct dquot *dquot)
+ smp_mb__before_atomic();
+ set_bit(DQ_READ_B, &dquot->dq_flags);
+ /* Instantiate dquot if needed */
+- if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && !dquot->dq_off) {
++ if (!dquot_active(dquot) && !dquot->dq_off) {
+ ret = dqopt->ops[dquot->dq_id.type]->commit_dqblk(dquot);
+ /* Write the info if needed */
+ if (info_dirty(&dqopt->info[dquot->dq_id.type])) {
+@@ -482,7 +487,7 @@ int dquot_commit(struct dquot *dquot)
+ goto out_lock;
+ /* Inactive dquot can be only if there was error during read/init
+ * => we have better not writing it */
+- if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags))
++ if (dquot_active(dquot))
+ ret = dqopt->ops[dquot->dq_id.type]->commit_dqblk(dquot);
+ else
+ ret = -EIO;
+@@ -597,7 +602,7 @@ int dquot_scan_active(struct super_block *sb,
+
+ spin_lock(&dq_list_lock);
+ list_for_each_entry(dquot, &inuse_list, dq_inuse) {
+- if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags))
++ if (!dquot_active(dquot))
+ continue;
+ if (dquot->dq_sb != sb)
+ continue;
+@@ -612,7 +617,7 @@ int dquot_scan_active(struct super_block *sb,
+ * outstanding call and recheck the DQ_ACTIVE_B after that.
+ */
+ wait_on_dquot(dquot);
+- if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) {
++ if (dquot_active(dquot)) {
+ ret = fn(dquot, priv);
+ if (ret < 0)
+ goto out;
+@@ -663,7 +668,7 @@ int dquot_writeback_dquots(struct super_block *sb, int type)
+ dquot = list_first_entry(&dirty, struct dquot,
+ dq_dirty);
+
+- WARN_ON(!test_bit(DQ_ACTIVE_B, &dquot->dq_flags));
++ WARN_ON(!dquot_active(dquot));
+
+ /* Now we have active dquot from which someone is
+ * holding reference so we can safely just increase
+@@ -800,7 +805,7 @@ void dqput(struct dquot *dquot)
+ dquot_write_dquot(dquot);
+ goto we_slept;
+ }
+- if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) {
++ if (dquot_active(dquot)) {
+ spin_unlock(&dq_list_lock);
+ dquot->dq_sb->dq_op->release_dquot(dquot);
+ goto we_slept;
+@@ -901,7 +906,7 @@ struct dquot *dqget(struct super_block *sb, struct kqid qid)
+ * already finished or it will be canceled due to dq_count > 1 test */
+ wait_on_dquot(dquot);
+ /* Read the dquot / allocate space in quota file */
+- if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) {
++ if (!dquot_active(dquot)) {
+ int err;
+
+ err = sb->dq_op->acquire_dquot(dquot);
+--
+2.40.1
+
--- /dev/null
+From 50af61738bca288a8cfe0b8813601ad8c739a6d7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Jun 2023 19:08:18 +0800
+Subject: quota: factor out dquot_write_dquot()
+
+From: Baokun Li <libaokun1@huawei.com>
+
+[ Upstream commit 024128477809f8073d870307c8157b8826ebfd08 ]
+
+Refactor out dquot_write_dquot() to reduce duplicate code.
+
+Signed-off-by: Baokun Li <libaokun1@huawei.com>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Message-Id: <20230630110822.3881712-2-libaokun1@huawei.com>
+Stable-dep-of: dabc8b207566 ("quota: fix dqput() to follow the guarantees dquot_srcu should provide")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/quota/dquot.c | 39 ++++++++++++++++-----------------------
+ 1 file changed, 16 insertions(+), 23 deletions(-)
+
+diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
+index e3e4f40476579..108ba9f1e4208 100644
+--- a/fs/quota/dquot.c
++++ b/fs/quota/dquot.c
+@@ -628,6 +628,18 @@ int dquot_scan_active(struct super_block *sb,
+ }
+ EXPORT_SYMBOL(dquot_scan_active);
+
++static inline int dquot_write_dquot(struct dquot *dquot)
++{
++ int ret = dquot->dq_sb->dq_op->write_dquot(dquot);
++ if (ret < 0) {
++ quota_error(dquot->dq_sb, "Can't write quota structure "
++ "(error %d). Quota may get out of sync!", ret);
++ /* Clear dirty bit anyway to avoid infinite loop. */
++ clear_dquot_dirty(dquot);
++ }
++ return ret;
++}
++
+ /* Write all dquot structures to quota files */
+ int dquot_writeback_dquots(struct super_block *sb, int type)
+ {
+@@ -658,16 +670,9 @@ int dquot_writeback_dquots(struct super_block *sb, int type)
+ * use count */
+ dqgrab(dquot);
+ spin_unlock(&dq_list_lock);
+- err = sb->dq_op->write_dquot(dquot);
+- if (err) {
+- /*
+- * Clear dirty bit anyway to avoid infinite
+- * loop here.
+- */
+- clear_dquot_dirty(dquot);
+- if (!ret)
+- ret = err;
+- }
++ err = dquot_write_dquot(dquot);
++ if (err && !ret)
++ ret = err;
+ dqput(dquot);
+ spin_lock(&dq_list_lock);
+ }
+@@ -765,8 +770,6 @@ static struct shrinker dqcache_shrinker = {
+ */
+ void dqput(struct dquot *dquot)
+ {
+- int ret;
+-
+ if (!dquot)
+ return;
+ #ifdef CONFIG_QUOTA_DEBUG
+@@ -794,17 +797,7 @@ void dqput(struct dquot *dquot)
+ if (dquot_dirty(dquot)) {
+ spin_unlock(&dq_list_lock);
+ /* Commit dquot before releasing */
+- ret = dquot->dq_sb->dq_op->write_dquot(dquot);
+- if (ret < 0) {
+- quota_error(dquot->dq_sb, "Can't write quota structure"
+- " (error %d). Quota may get out of sync!",
+- ret);
+- /*
+- * We clear dirty bit anyway, so that we avoid
+- * infinite loop here
+- */
+- clear_dquot_dirty(dquot);
+- }
++ dquot_write_dquot(dquot);
+ goto we_slept;
+ }
+ if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) {
+--
+2.40.1
+
--- /dev/null
+From b6c60df22cb2e114bfbbd14c9588cb735ce6888c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Jun 2023 19:08:21 +0800
+Subject: quota: fix dqput() to follow the guarantees dquot_srcu should provide
+
+From: Baokun Li <libaokun1@huawei.com>
+
+[ Upstream commit dabc8b20756601b9e1cc85a81d47d3f98ed4d13a ]
+
+The dquot_mark_dquot_dirty() using dquot references from the inode
+should be protected by dquot_srcu. quota_off code takes care to call
+synchronize_srcu(&dquot_srcu) to not drop dquot references while they
+are used by other users. But dquot_transfer() breaks this assumption.
+We call dquot_transfer() to drop the last reference of dquot and add
+it to free_dquots, but there may still be other users using the dquot
+at this time, as shown in the function graph below:
+
+ cpu1 cpu2
+_________________|_________________
+wb_do_writeback CHOWN(1)
+ ...
+ ext4_da_update_reserve_space
+ dquot_claim_block
+ ...
+ dquot_mark_dquot_dirty // try to dirty old quota
+ test_bit(DQ_ACTIVE_B, &dquot->dq_flags) // still ACTIVE
+ if (test_bit(DQ_MOD_B, &dquot->dq_flags))
+ // test no dirty, wait dq_list_lock
+ ...
+ dquot_transfer
+ __dquot_transfer
+ dqput_all(transfer_from) // rls old dquot
+ dqput // last dqput
+ dquot_release
+ clear_bit(DQ_ACTIVE_B, &dquot->dq_flags)
+ atomic_dec(&dquot->dq_count)
+ put_dquot_last(dquot)
+ list_add_tail(&dquot->dq_free, &free_dquots)
+ // add the dquot to free_dquots
+ if (!test_and_set_bit(DQ_MOD_B, &dquot->dq_flags))
+ add dqi_dirty_list // add released dquot to dirty_list
+
+This can cause various issues, such as dquot being destroyed by
+dqcache_shrink_scan() after being added to free_dquots, which can trigger
+a UAF in dquot_mark_dquot_dirty(); or after dquot is added to free_dquots
+and then to dirty_list, it is added to free_dquots again after
+dquot_writeback_dquots() is executed, which causes the free_dquots list to
+be corrupted and triggers a UAF when dqcache_shrink_scan() is called for
+freeing dquot twice.
+
+As Honza said, we need to fix dquot_transfer() to follow the guarantees
+dquot_srcu should provide. But calling synchronize_srcu() directly from
+dquot_transfer() is too expensive (and mostly unnecessary). So we add
+dquot whose last reference should be dropped to the new global dquot
+list releasing_dquots, and then queue work item which would call
+synchronize_srcu() and after that perform the final cleanup of all the
+dquots on releasing_dquots.
+
+Fixes: 4580b30ea887 ("quota: Do not dirty bad dquots")
+Suggested-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Baokun Li <libaokun1@huawei.com>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Message-Id: <20230630110822.3881712-5-libaokun1@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/quota/dquot.c | 96 +++++++++++++++++++++++++++++++++++++++---------
+ 1 file changed, 78 insertions(+), 18 deletions(-)
+
+diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
+index 88aa747f48008..c7afe433d991a 100644
+--- a/fs/quota/dquot.c
++++ b/fs/quota/dquot.c
+@@ -225,13 +225,22 @@ static void put_quota_format(struct quota_format_type *fmt)
+
+ /*
+ * Dquot List Management:
+- * The quota code uses four lists for dquot management: the inuse_list,
+- * free_dquots, dqi_dirty_list, and dquot_hash[] array. A single dquot
+- * structure may be on some of those lists, depending on its current state.
++ * The quota code uses five lists for dquot management: the inuse_list,
++ * releasing_dquots, free_dquots, dqi_dirty_list, and dquot_hash[] array.
++ * A single dquot structure may be on some of those lists, depending on
++ * its current state.
+ *
+ * All dquots are placed to the end of inuse_list when first created, and this
+ * list is used for invalidate operation, which must look at every dquot.
+ *
++ * When the last reference of a dquot will be dropped, the dquot will be
++ * added to releasing_dquots. We'd then queue work item which would call
++ * synchronize_srcu() and after that perform the final cleanup of all the
++ * dquots on the list. Both releasing_dquots and free_dquots use the
++ * dq_free list_head in the dquot struct. When a dquot is removed from
++ * releasing_dquots, a reference count is always subtracted, and if
++ * dq_count == 0 at that point, the dquot will be added to the free_dquots.
++ *
+ * Unused dquots (dq_count == 0) are added to the free_dquots list when freed,
+ * and this list is searched whenever we need an available dquot. Dquots are
+ * removed from the list as soon as they are used again, and
+@@ -250,6 +259,7 @@ static void put_quota_format(struct quota_format_type *fmt)
+
+ static LIST_HEAD(inuse_list);
+ static LIST_HEAD(free_dquots);
++static LIST_HEAD(releasing_dquots);
+ static unsigned int dq_hash_bits, dq_hash_mask;
+ static struct hlist_head *dquot_hash;
+
+@@ -260,6 +270,9 @@ static qsize_t inode_get_rsv_space(struct inode *inode);
+ static qsize_t __inode_get_rsv_space(struct inode *inode);
+ static int __dquot_initialize(struct inode *inode, int type);
+
++static void quota_release_workfn(struct work_struct *work);
++static DECLARE_DELAYED_WORK(quota_release_work, quota_release_workfn);
++
+ static inline unsigned int
+ hashfn(const struct super_block *sb, struct kqid qid)
+ {
+@@ -305,12 +318,18 @@ static inline void put_dquot_last(struct dquot *dquot)
+ dqstats_inc(DQST_FREE_DQUOTS);
+ }
+
++static inline void put_releasing_dquots(struct dquot *dquot)
++{
++ list_add_tail(&dquot->dq_free, &releasing_dquots);
++}
++
+ static inline void remove_free_dquot(struct dquot *dquot)
+ {
+ if (list_empty(&dquot->dq_free))
+ return;
+ list_del_init(&dquot->dq_free);
+- dqstats_dec(DQST_FREE_DQUOTS);
++ if (!atomic_read(&dquot->dq_count))
++ dqstats_dec(DQST_FREE_DQUOTS);
+ }
+
+ static inline void put_inuse(struct dquot *dquot)
+@@ -552,6 +571,8 @@ static void invalidate_dquots(struct super_block *sb, int type)
+ struct dquot *dquot, *tmp;
+
+ restart:
++ flush_delayed_work("a_release_work);
++
+ spin_lock(&dq_list_lock);
+ list_for_each_entry_safe(dquot, tmp, &inuse_list, dq_inuse) {
+ if (dquot->dq_sb != sb)
+@@ -560,6 +581,12 @@ static void invalidate_dquots(struct super_block *sb, int type)
+ continue;
+ /* Wait for dquot users */
+ if (atomic_read(&dquot->dq_count)) {
++ /* dquot in releasing_dquots, flush and retry */
++ if (!list_empty(&dquot->dq_free)) {
++ spin_unlock(&dq_list_lock);
++ goto restart;
++ }
++
+ atomic_inc(&dquot->dq_count);
+ spin_unlock(&dq_list_lock);
+ /*
+@@ -770,6 +797,49 @@ static struct shrinker dqcache_shrinker = {
+ .seeks = DEFAULT_SEEKS,
+ };
+
++/*
++ * Safely release dquot and put reference to dquot.
++ */
++static void quota_release_workfn(struct work_struct *work)
++{
++ struct dquot *dquot;
++ struct list_head rls_head;
++
++ spin_lock(&dq_list_lock);
++ /* Exchange the list head to avoid livelock. */
++ list_replace_init(&releasing_dquots, &rls_head);
++ spin_unlock(&dq_list_lock);
++
++restart:
++ synchronize_srcu(&dquot_srcu);
++ spin_lock(&dq_list_lock);
++ while (!list_empty(&rls_head)) {
++ dquot = list_first_entry(&rls_head, struct dquot, dq_free);
++ /* Dquot got used again? */
++ if (atomic_read(&dquot->dq_count) > 1) {
++ remove_free_dquot(dquot);
++ atomic_dec(&dquot->dq_count);
++ continue;
++ }
++ if (dquot_dirty(dquot)) {
++ spin_unlock(&dq_list_lock);
++ /* Commit dquot before releasing */
++ dquot_write_dquot(dquot);
++ goto restart;
++ }
++ if (dquot_active(dquot)) {
++ spin_unlock(&dq_list_lock);
++ dquot->dq_sb->dq_op->release_dquot(dquot);
++ goto restart;
++ }
++ /* Dquot is inactive and clean, now move it to free list */
++ remove_free_dquot(dquot);
++ atomic_dec(&dquot->dq_count);
++ put_dquot_last(dquot);
++ }
++ spin_unlock(&dq_list_lock);
++}
++
+ /*
+ * Put reference to dquot
+ */
+@@ -786,7 +856,7 @@ void dqput(struct dquot *dquot)
+ }
+ #endif
+ dqstats_inc(DQST_DROPS);
+-we_slept:
++
+ spin_lock(&dq_list_lock);
+ if (atomic_read(&dquot->dq_count) > 1) {
+ /* We have more than one user... nothing to do */
+@@ -798,25 +868,15 @@ void dqput(struct dquot *dquot)
+ spin_unlock(&dq_list_lock);
+ return;
+ }
++
+ /* Need to release dquot? */
+- if (dquot_dirty(dquot)) {
+- spin_unlock(&dq_list_lock);
+- /* Commit dquot before releasing */
+- dquot_write_dquot(dquot);
+- goto we_slept;
+- }
+- if (dquot_active(dquot)) {
+- spin_unlock(&dq_list_lock);
+- dquot->dq_sb->dq_op->release_dquot(dquot);
+- goto we_slept;
+- }
+- atomic_dec(&dquot->dq_count);
+ #ifdef CONFIG_QUOTA_DEBUG
+ /* sanity check */
+ BUG_ON(!list_empty(&dquot->dq_free));
+ #endif
+- put_dquot_last(dquot);
++ put_releasing_dquots(dquot);
+ spin_unlock(&dq_list_lock);
++ queue_delayed_work(system_unbound_wq, "a_release_work, 1);
+ }
+ EXPORT_SYMBOL(dqput);
+
+--
+2.40.1
+
--- /dev/null
+From 54d515b60dec5f36b9eddd256140be26a3a2906e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Jun 2023 19:08:19 +0800
+Subject: quota: rename dquot_active() to inode_quota_active()
+
+From: Baokun Li <libaokun1@huawei.com>
+
+[ Upstream commit 4b9bdfa16535de8f49bf954aeed0f525ee2fc322 ]
+
+Now we have a helper function dquot_dirty() to determine if dquot has
+DQ_MOD_B bit. dquot_active() can easily be misunderstood as a helper
+function to determine if dquot has DQ_ACTIVE_B bit. So we avoid this by
+renaming it to inode_quota_active() and later on we will add the helper
+function dquot_active() to determine if dquot has DQ_ACTIVE_B bit.
+
+Signed-off-by: Baokun Li <libaokun1@huawei.com>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Message-Id: <20230630110822.3881712-3-libaokun1@huawei.com>
+Stable-dep-of: dabc8b207566 ("quota: fix dqput() to follow the guarantees dquot_srcu should provide")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/quota/dquot.c | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
+index 108ba9f1e4208..a08698d9859a8 100644
+--- a/fs/quota/dquot.c
++++ b/fs/quota/dquot.c
+@@ -1418,7 +1418,7 @@ static int info_bdq_free(struct dquot *dquot, qsize_t space)
+ return QUOTA_NL_NOWARN;
+ }
+
+-static int dquot_active(const struct inode *inode)
++static int inode_quota_active(const struct inode *inode)
+ {
+ struct super_block *sb = inode->i_sb;
+
+@@ -1441,7 +1441,7 @@ static int __dquot_initialize(struct inode *inode, int type)
+ qsize_t rsv;
+ int ret = 0;
+
+- if (!dquot_active(inode))
++ if (!inode_quota_active(inode))
+ return 0;
+
+ dquots = i_dquot(inode);
+@@ -1549,7 +1549,7 @@ bool dquot_initialize_needed(struct inode *inode)
+ struct dquot **dquots;
+ int i;
+
+- if (!dquot_active(inode))
++ if (!inode_quota_active(inode))
+ return false;
+
+ dquots = i_dquot(inode);
+@@ -1660,7 +1660,7 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags)
+ int reserve = flags & DQUOT_SPACE_RESERVE;
+ struct dquot **dquots;
+
+- if (!dquot_active(inode)) {
++ if (!inode_quota_active(inode)) {
+ if (reserve) {
+ spin_lock(&inode->i_lock);
+ *inode_reserved_space(inode) += number;
+@@ -1730,7 +1730,7 @@ int dquot_alloc_inode(struct inode *inode)
+ struct dquot_warn warn[MAXQUOTAS];
+ struct dquot * const *dquots;
+
+- if (!dquot_active(inode))
++ if (!inode_quota_active(inode))
+ return 0;
+ for (cnt = 0; cnt < MAXQUOTAS; cnt++)
+ warn[cnt].w_type = QUOTA_NL_NOWARN;
+@@ -1773,7 +1773,7 @@ int dquot_claim_space_nodirty(struct inode *inode, qsize_t number)
+ struct dquot **dquots;
+ int cnt, index;
+
+- if (!dquot_active(inode)) {
++ if (!inode_quota_active(inode)) {
+ spin_lock(&inode->i_lock);
+ *inode_reserved_space(inode) -= number;
+ __inode_add_bytes(inode, number);
+@@ -1815,7 +1815,7 @@ void dquot_reclaim_space_nodirty(struct inode *inode, qsize_t number)
+ struct dquot **dquots;
+ int cnt, index;
+
+- if (!dquot_active(inode)) {
++ if (!inode_quota_active(inode)) {
+ spin_lock(&inode->i_lock);
+ *inode_reserved_space(inode) += number;
+ __inode_sub_bytes(inode, number);
+@@ -1859,7 +1859,7 @@ void __dquot_free_space(struct inode *inode, qsize_t number, int flags)
+ struct dquot **dquots;
+ int reserve = flags & DQUOT_SPACE_RESERVE, index;
+
+- if (!dquot_active(inode)) {
++ if (!inode_quota_active(inode)) {
+ if (reserve) {
+ spin_lock(&inode->i_lock);
+ *inode_reserved_space(inode) -= number;
+@@ -1914,7 +1914,7 @@ void dquot_free_inode(struct inode *inode)
+ struct dquot * const *dquots;
+ int index;
+
+- if (!dquot_active(inode))
++ if (!inode_quota_active(inode))
+ return;
+
+ dquots = i_dquot(inode);
+@@ -2086,7 +2086,7 @@ int dquot_transfer(struct mnt_idmap *idmap, struct inode *inode,
+ struct super_block *sb = inode->i_sb;
+ int ret;
+
+- if (!dquot_active(inode))
++ if (!inode_quota_active(inode))
+ return 0;
+
+ if (i_uid_needs_update(idmap, iattr, inode)) {
+--
+2.40.1
+
--- /dev/null
+From ae243709bb2c2c979b2ead0b70da1399a55564ab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Aug 2023 01:45:22 -0700
+Subject: RDMA/bnxt_re: Remove a redundant flag
+
+From: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+
+[ Upstream commit fd28c8a8c7a10e7b53851129c6d8dc5945108fe9 ]
+
+After the cited commit, BNXT_RE_FLAG_GOT_MSIX is redundant.
+Remove it.
+
+Fixes: 303432211324 ("bnxt_en: Remove runtime interrupt vector allocation")
+Signed-off-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
+Link: https://lore.kernel.org/r/1691052326-32143-3-git-send-email-selvin.xavier@broadcom.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/bnxt_re/bnxt_re.h | 1 -
+ drivers/infiniband/hw/bnxt_re/main.c | 5 ++---
+ 2 files changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/infiniband/hw/bnxt_re/bnxt_re.h b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
+index eef3ef3fabb42..bacb1b6723ef8 100644
+--- a/drivers/infiniband/hw/bnxt_re/bnxt_re.h
++++ b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
+@@ -116,7 +116,6 @@ struct bnxt_re_dev {
+ struct list_head list;
+ unsigned long flags;
+ #define BNXT_RE_FLAG_NETDEV_REGISTERED 0
+-#define BNXT_RE_FLAG_GOT_MSIX 2
+ #define BNXT_RE_FLAG_HAVE_L2_REF 3
+ #define BNXT_RE_FLAG_RCFW_CHANNEL_EN 4
+ #define BNXT_RE_FLAG_QOS_WORK_REG 5
+diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c
+index 4f00fb7869f8e..bfab2c83faf92 100644
+--- a/drivers/infiniband/hw/bnxt_re/main.c
++++ b/drivers/infiniband/hw/bnxt_re/main.c
+@@ -1113,8 +1113,8 @@ static void bnxt_re_dev_uninit(struct bnxt_re_dev *rdev)
+ bnxt_re_net_ring_free(rdev, rdev->rcfw.creq.ring_id, type);
+ bnxt_qplib_free_rcfw_channel(&rdev->rcfw);
+ }
+- if (test_and_clear_bit(BNXT_RE_FLAG_GOT_MSIX, &rdev->flags))
+- rdev->num_msix = 0;
++
++ rdev->num_msix = 0;
+
+ bnxt_re_destroy_chip_ctx(rdev);
+ if (test_and_clear_bit(BNXT_RE_FLAG_NETDEV_REGISTERED, &rdev->flags))
+@@ -1170,7 +1170,6 @@ static int bnxt_re_dev_init(struct bnxt_re_dev *rdev, u8 wqe_mode)
+ ibdev_dbg(&rdev->ibdev, "Got %d MSI-X vectors\n",
+ rdev->en_dev->ulp_tbl->msix_requested);
+ rdev->num_msix = rdev->en_dev->ulp_tbl->msix_requested;
+- set_bit(BNXT_RE_FLAG_GOT_MSIX, &rdev->flags);
+
+ bnxt_re_query_hwrm_intf_version(rdev);
+
+--
+2.40.1
+
--- /dev/null
+From 89ba5d2ef718c71f3799291b5f0805b230a8a121 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Aug 2023 08:27:25 +0000
+Subject: RDMA/efa: Fix wrong resources deallocation order
+
+From: Yonatan Nachum <ynachum@amazon.com>
+
+[ Upstream commit dc202c57e9a1423aed528e4b8dc949509cd32191 ]
+
+When trying to destroy QP or CQ, we first decrease the refcount and
+potentially free memory regions allocated for the object and then
+request the device to destroy the object. If the device fails, the
+object isn't fully destroyed so the user/IB core can try to destroy the
+object again which will lead to underflow when trying to decrease an
+already zeroed refcount.
+
+Deallocate resources in reverse order of allocating them to safely free
+them.
+
+Fixes: ff6629f88c52 ("RDMA/efa: Do not delay freeing of DMA pages")
+Reviewed-by: Michael Margolin <mrgolin@amazon.com>
+Reviewed-by: Yossi Leybovich <sleybo@amazon.com>
+Signed-off-by: Yonatan Nachum <ynachum@amazon.com>
+Link: https://lore.kernel.org/r/20230822082725.31719-1-ynachum@amazon.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/efa/efa_verbs.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/infiniband/hw/efa/efa_verbs.c b/drivers/infiniband/hw/efa/efa_verbs.c
+index 2a195c4b0f17d..3538d59521e41 100644
+--- a/drivers/infiniband/hw/efa/efa_verbs.c
++++ b/drivers/infiniband/hw/efa/efa_verbs.c
+@@ -449,12 +449,12 @@ int efa_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata)
+
+ ibdev_dbg(&dev->ibdev, "Destroy qp[%u]\n", ibqp->qp_num);
+
+- efa_qp_user_mmap_entries_remove(qp);
+-
+ err = efa_destroy_qp_handle(dev, qp->qp_handle);
+ if (err)
+ return err;
+
++ efa_qp_user_mmap_entries_remove(qp);
++
+ if (qp->rq_cpu_addr) {
+ ibdev_dbg(&dev->ibdev,
+ "qp->cpu_addr[0x%p] freed: size[%lu], dma[%pad]\n",
+@@ -1013,8 +1013,8 @@ int efa_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
+ "Destroy cq[%d] virt[0x%p] freed: size[%lu], dma[%pad]\n",
+ cq->cq_idx, cq->cpu_addr, cq->size, &cq->dma_addr);
+
+- efa_cq_user_mmap_entries_remove(cq);
+ efa_destroy_cq_idx(dev, cq->cq_idx);
++ efa_cq_user_mmap_entries_remove(cq);
+ if (cq->eq) {
+ xa_erase(&dev->cqs_xa, cq->cq_idx);
+ synchronize_irq(cq->eq->irq.irqn);
+--
+2.40.1
+
--- /dev/null
+From b7a71d20d2f2589cf3ccf144a85de27e7c1a2d33 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Aug 2023 09:27:11 +0800
+Subject: RDMA/hns: Fix CQ and QP cache affinity
+
+From: Chengchang Tang <tangchengchang@huawei.com>
+
+[ Upstream commit 9e03dbea2b0634b21a45946b4f8097e0dc86ebe1 ]
+
+Currently, the affinity between QP cache and CQ cache is not
+considered when assigning QPN, it will affect the message rate of HW.
+
+Allocate QPN from QP cache with better CQ affinity to get better
+performance.
+
+Fixes: 71586dd20010 ("RDMA/hns: Create QP with selected QPN for bank load balance")
+Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
+Signed-off-by: Junxian Huang <huangjunxian6@hisilicon.com>
+Link: https://lore.kernel.org/r/20230804012711.808069-5-huangjunxian6@hisilicon.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_device.h | 1 +
+ drivers/infiniband/hw/hns/hns_roce_qp.c | 28 ++++++++++++++++-----
+ 2 files changed, 23 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h
+index 84239b907de2a..bb94eb076858c 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_device.h
++++ b/drivers/infiniband/hw/hns/hns_roce_device.h
+@@ -97,6 +97,7 @@
+ #define HNS_ROCE_CQ_BANK_NUM 4
+
+ #define CQ_BANKID_SHIFT 2
++#define CQ_BANKID_MASK GENMASK(1, 0)
+
+ enum {
+ SERV_TYPE_RC,
+diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c
+index d855a917f4cfa..cdc1c6de43a17 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_qp.c
++++ b/drivers/infiniband/hw/hns/hns_roce_qp.c
+@@ -170,14 +170,29 @@ static void hns_roce_ib_qp_event(struct hns_roce_qp *hr_qp,
+ }
+ }
+
+-static u8 get_least_load_bankid_for_qp(struct hns_roce_bank *bank)
++static u8 get_affinity_cq_bank(u8 qp_bank)
+ {
+- u32 least_load = bank[0].inuse;
++ return (qp_bank >> 1) & CQ_BANKID_MASK;
++}
++
++static u8 get_least_load_bankid_for_qp(struct ib_qp_init_attr *init_attr,
++ struct hns_roce_bank *bank)
++{
++#define INVALID_LOAD_QPNUM 0xFFFFFFFF
++ struct ib_cq *scq = init_attr->send_cq;
++ u32 least_load = INVALID_LOAD_QPNUM;
++ unsigned long cqn = 0;
+ u8 bankid = 0;
+ u32 bankcnt;
+ u8 i;
+
+- for (i = 1; i < HNS_ROCE_QP_BANK_NUM; i++) {
++ if (scq)
++ cqn = to_hr_cq(scq)->cqn;
++
++ for (i = 0; i < HNS_ROCE_QP_BANK_NUM; i++) {
++ if (scq && (get_affinity_cq_bank(i) != (cqn & CQ_BANKID_MASK)))
++ continue;
++
+ bankcnt = bank[i].inuse;
+ if (bankcnt < least_load) {
+ least_load = bankcnt;
+@@ -209,7 +224,8 @@ static int alloc_qpn_with_bankid(struct hns_roce_bank *bank, u8 bankid,
+
+ return 0;
+ }
+-static int alloc_qpn(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp)
++static int alloc_qpn(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp,
++ struct ib_qp_init_attr *init_attr)
+ {
+ struct hns_roce_qp_table *qp_table = &hr_dev->qp_table;
+ unsigned long num = 0;
+@@ -220,7 +236,7 @@ static int alloc_qpn(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp)
+ num = 1;
+ } else {
+ mutex_lock(&qp_table->bank_mutex);
+- bankid = get_least_load_bankid_for_qp(qp_table->bank);
++ bankid = get_least_load_bankid_for_qp(init_attr, qp_table->bank);
+
+ ret = alloc_qpn_with_bankid(&qp_table->bank[bankid], bankid,
+ &num);
+@@ -1082,7 +1098,7 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev,
+ goto err_buf;
+ }
+
+- ret = alloc_qpn(hr_dev, hr_qp);
++ ret = alloc_qpn(hr_dev, hr_qp, init_attr);
+ if (ret) {
+ ibdev_err(ibdev, "failed to alloc QPN, ret = %d.\n", ret);
+ goto err_qpn;
+--
+2.40.1
+
--- /dev/null
+From bafb4bd512784e0f4093dee9d2b86ff4764687e8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Aug 2023 09:27:10 +0800
+Subject: RDMA/hns: Fix inaccurate error label name in init instance
+
+From: Junxian Huang <huangjunxian6@hisilicon.com>
+
+[ Upstream commit c9c0bd3c177d93d80968f720304087ba83fe8f74 ]
+
+This patch fixes inaccurate error label name in init instance.
+
+Fixes: 70f92521584f ("RDMA/hns: Use the reserved loopback QPs to free MR before destroying MPT")
+Signed-off-by: Junxian Huang <huangjunxian6@hisilicon.com>
+Link: https://lore.kernel.org/r/20230804012711.808069-4-huangjunxian6@hisilicon.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+index fe7908ed39022..ec1b82ddc23dd 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+@@ -6741,14 +6741,14 @@ static int __hns_roce_hw_v2_init_instance(struct hnae3_handle *handle)
+ ret = hns_roce_init(hr_dev);
+ if (ret) {
+ dev_err(hr_dev->dev, "RoCE Engine init failed!\n");
+- goto error_failed_cfg;
++ goto error_failed_roce_init;
+ }
+
+ if (hr_dev->pci_dev->revision == PCI_REVISION_ID_HIP08) {
+ ret = free_mr_init(hr_dev);
+ if (ret) {
+ dev_err(hr_dev->dev, "failed to init free mr!\n");
+- goto error_failed_roce_init;
++ goto error_failed_free_mr_init;
+ }
+ }
+
+@@ -6756,10 +6756,10 @@ static int __hns_roce_hw_v2_init_instance(struct hnae3_handle *handle)
+
+ return 0;
+
+-error_failed_roce_init:
++error_failed_free_mr_init:
+ hns_roce_exit(hr_dev);
+
+-error_failed_cfg:
++error_failed_roce_init:
+ kfree(hr_dev->priv);
+
+ error_failed_kzalloc:
+--
+2.40.1
+
--- /dev/null
+From ee16a66135c939ea955f6d51fc2acd808077bf80 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Aug 2023 09:27:09 +0800
+Subject: RDMA/hns: Fix incorrect post-send with direct wqe of wr-list
+
+From: Junxian Huang <huangjunxian6@hisilicon.com>
+
+[ Upstream commit 706efac4477cdb8be857f6322457de524acc02ff ]
+
+Currently, direct wqe is not supported for wr-list. RoCE driver excludes
+direct wqe for wr-list by judging whether the number of wr is 1.
+
+For a wr-list where the second wr is a length-error atomic wr, the
+post-send driver handles the first wr and adds 1 to the wr number counter
+firstly. While handling the second wr, the driver finds out a length error
+and terminates the wr handle process, remaining the counter at 1. This
+causes the driver mistakenly judges there is only 1 wr and thus enters
+the direct wqe process, carrying the current length-error atomic wqe.
+
+This patch fixes the error by adding a judgement whether the current wr
+is a bad wr. If so, use the normal doorbell process but not direct wqe
+despite the wr number is 1.
+
+Fixes: 01584a5edcc4 ("RDMA/hns: Add support of direct wqe")
+Signed-off-by: Junxian Huang <huangjunxian6@hisilicon.com>
+Link: https://lore.kernel.org/r/20230804012711.808069-3-huangjunxian6@hisilicon.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+index d4c6b9bc0a4ea..fe7908ed39022 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+@@ -757,7 +757,8 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp,
+ qp->sq.head += nreq;
+ qp->next_sge = sge_idx;
+
+- if (nreq == 1 && (qp->en_flags & HNS_ROCE_QP_CAP_DIRECT_WQE))
++ if (nreq == 1 && !ret &&
++ (qp->en_flags & HNS_ROCE_QP_CAP_DIRECT_WQE))
+ write_dwqe(hr_dev, qp, wqe);
+ else
+ update_sq_db(hr_dev, qp);
+--
+2.40.1
+
--- /dev/null
+From 393719090c0d2521207d5e5ac9c979d61831e53c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Aug 2023 09:27:08 +0800
+Subject: RDMA/hns: Fix port active speed
+
+From: Chengchang Tang <tangchengchang@huawei.com>
+
+[ Upstream commit df1bcf90a66a10967a3a43510b42cb3566208011 ]
+
+HW supports a variety of different speed, but the current speed
+is fixed.
+
+The real speed should be querried from ethernet.
+
+Fixes: 9a4435375cd1 ("IB/hns: Add driver files for hns RoCE driver")
+Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
+Signed-off-by: Junxian Huang <huangjunxian6@hisilicon.com>
+Link: https://lore.kernel.org/r/20230804012711.808069-2-huangjunxian6@hisilicon.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_main.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c
+index 485e110ca4333..9141eadf33d2a 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_main.c
++++ b/drivers/infiniband/hw/hns/hns_roce_main.c
+@@ -219,6 +219,7 @@ static int hns_roce_query_port(struct ib_device *ib_dev, u32 port_num,
+ unsigned long flags;
+ enum ib_mtu mtu;
+ u32 port;
++ int ret;
+
+ port = port_num - 1;
+
+@@ -231,8 +232,10 @@ static int hns_roce_query_port(struct ib_device *ib_dev, u32 port_num,
+ IB_PORT_BOOT_MGMT_SUP;
+ props->max_msg_sz = HNS_ROCE_MAX_MSG_LEN;
+ props->pkey_tbl_len = 1;
+- props->active_width = IB_WIDTH_4X;
+- props->active_speed = 1;
++ ret = ib_get_eth_speed(ib_dev, port_num, &props->active_speed,
++ &props->active_width);
++ if (ret)
++ ibdev_warn(ib_dev, "failed to get speed, ret = %d.\n", ret);
+
+ spin_lock_irqsave(&hr_dev->iboe.lock, flags);
+
+--
+2.40.1
+
--- /dev/null
+From a61659707790945b801539288dc32eb370b3ca14 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Aug 2023 09:48:38 -0500
+Subject: RDMA/irdma: Prevent zero-length STAG registration
+
+From: Christopher Bednarz <christopher.n.bednarz@intel.com>
+
+[ Upstream commit bb6d73d9add68ad270888db327514384dfa44958 ]
+
+Currently irdma allows zero-length STAGs to be programmed in HW during
+the kernel mode fast register flow. Zero-length MR or STAG registration
+disable HW memory length checks.
+
+Improve gaps in bounds checking in irdma by preventing zero-length STAG or
+MR registrations except if the IB_PD_UNSAFE_GLOBAL_RKEY is set.
+
+This addresses the disclosure CVE-2023-25775.
+
+Fixes: b48c24c2d710 ("RDMA/irdma: Implement device supported verb APIs")
+Signed-off-by: Christopher Bednarz <christopher.n.bednarz@intel.com>
+Signed-off-by: Shiraz Saleem <shiraz.saleem@intel.com>
+Link: https://lore.kernel.org/r/20230818144838.1758-1-shiraz.saleem@intel.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/irdma/ctrl.c | 6 ++++++
+ drivers/infiniband/hw/irdma/type.h | 2 ++
+ drivers/infiniband/hw/irdma/verbs.c | 10 ++++++++--
+ 3 files changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/hw/irdma/ctrl.c b/drivers/infiniband/hw/irdma/ctrl.c
+index 45e3344daa048..ef47ec271e19e 100644
+--- a/drivers/infiniband/hw/irdma/ctrl.c
++++ b/drivers/infiniband/hw/irdma/ctrl.c
+@@ -1061,6 +1061,9 @@ static int irdma_sc_alloc_stag(struct irdma_sc_dev *dev,
+ u64 hdr;
+ enum irdma_page_size page_size;
+
++ if (!info->total_len && !info->all_memory)
++ return -EINVAL;
++
+ if (info->page_size == 0x40000000)
+ page_size = IRDMA_PAGE_SIZE_1G;
+ else if (info->page_size == 0x200000)
+@@ -1126,6 +1129,9 @@ static int irdma_sc_mr_reg_non_shared(struct irdma_sc_dev *dev,
+ u8 addr_type;
+ enum irdma_page_size page_size;
+
++ if (!info->total_len && !info->all_memory)
++ return -EINVAL;
++
+ if (info->page_size == 0x40000000)
+ page_size = IRDMA_PAGE_SIZE_1G;
+ else if (info->page_size == 0x200000)
+diff --git a/drivers/infiniband/hw/irdma/type.h b/drivers/infiniband/hw/irdma/type.h
+index a20709577ab0a..3b1fa5bc0a585 100644
+--- a/drivers/infiniband/hw/irdma/type.h
++++ b/drivers/infiniband/hw/irdma/type.h
+@@ -971,6 +971,7 @@ struct irdma_allocate_stag_info {
+ bool remote_access:1;
+ bool use_hmc_fcn_index:1;
+ bool use_pf_rid:1;
++ bool all_memory:1;
+ u8 hmc_fcn_index;
+ };
+
+@@ -998,6 +999,7 @@ struct irdma_reg_ns_stag_info {
+ bool use_hmc_fcn_index:1;
+ u8 hmc_fcn_index;
+ bool use_pf_rid:1;
++ bool all_memory:1;
+ };
+
+ struct irdma_fast_reg_stag_info {
+diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c
+index 8f9378767f307..20d70f0d21e0f 100644
+--- a/drivers/infiniband/hw/irdma/verbs.c
++++ b/drivers/infiniband/hw/irdma/verbs.c
+@@ -2552,7 +2552,8 @@ static int irdma_hw_alloc_stag(struct irdma_device *iwdev,
+ struct irdma_mr *iwmr)
+ {
+ struct irdma_allocate_stag_info *info;
+- struct irdma_pd *iwpd = to_iwpd(iwmr->ibmr.pd);
++ struct ib_pd *pd = iwmr->ibmr.pd;
++ struct irdma_pd *iwpd = to_iwpd(pd);
+ int status;
+ struct irdma_cqp_request *cqp_request;
+ struct cqp_cmds_info *cqp_info;
+@@ -2568,6 +2569,7 @@ static int irdma_hw_alloc_stag(struct irdma_device *iwdev,
+ info->stag_idx = iwmr->stag >> IRDMA_CQPSQ_STAG_IDX_S;
+ info->pd_id = iwpd->sc_pd.pd_id;
+ info->total_len = iwmr->len;
++ info->all_memory = pd->flags & IB_PD_UNSAFE_GLOBAL_RKEY;
+ info->remote_access = true;
+ cqp_info->cqp_cmd = IRDMA_OP_ALLOC_STAG;
+ cqp_info->post_sq = 1;
+@@ -2615,6 +2617,8 @@ static struct ib_mr *irdma_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
+ iwmr->type = IRDMA_MEMREG_TYPE_MEM;
+ palloc = &iwpbl->pble_alloc;
+ iwmr->page_cnt = max_num_sg;
++ /* Use system PAGE_SIZE as the sg page sizes are unknown at this point */
++ iwmr->len = max_num_sg * PAGE_SIZE;
+ err_code = irdma_get_pble(iwdev->rf->pble_rsrc, palloc, iwmr->page_cnt,
+ false);
+ if (err_code)
+@@ -2694,7 +2698,8 @@ static int irdma_hwreg_mr(struct irdma_device *iwdev, struct irdma_mr *iwmr,
+ {
+ struct irdma_pbl *iwpbl = &iwmr->iwpbl;
+ struct irdma_reg_ns_stag_info *stag_info;
+- struct irdma_pd *iwpd = to_iwpd(iwmr->ibmr.pd);
++ struct ib_pd *pd = iwmr->ibmr.pd;
++ struct irdma_pd *iwpd = to_iwpd(pd);
+ struct irdma_pble_alloc *palloc = &iwpbl->pble_alloc;
+ struct irdma_cqp_request *cqp_request;
+ struct cqp_cmds_info *cqp_info;
+@@ -2713,6 +2718,7 @@ static int irdma_hwreg_mr(struct irdma_device *iwdev, struct irdma_mr *iwmr,
+ stag_info->total_len = iwmr->len;
+ stag_info->access_rights = irdma_get_mr_access(access);
+ stag_info->pd_id = iwpd->sc_pd.pd_id;
++ stag_info->all_memory = pd->flags & IB_PD_UNSAFE_GLOBAL_RKEY;
+ if (stag_info->access_rights & IRDMA_ACCESS_FLAGS_ZERO_BASED)
+ stag_info->addr_type = IRDMA_ADDR_TYPE_ZERO_BASED;
+ else
+--
+2.40.1
+
--- /dev/null
+From d779f521926865fda24df76fe1ff14a465fe4a55 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Aug 2023 08:46:26 -0600
+Subject: RDMA/irdma: Replace one-element array with flexible-array member
+
+From: Gustavo A. R. Silva <gustavoars@kernel.org>
+
+[ Upstream commit 38313c6d2a02c28162e06753b01bd885caf9386d ]
+
+One-element and zero-length arrays are deprecated. So, replace
+one-element array in struct irdma_qvlist_info with flexible-array
+member.
+
+A patch for this was sent a while ago[1]. However, it seems that, at
+the time, the changes were partially folded[2][3], and the actual
+flexible-array transformation was omitted. This patch fixes that.
+
+The only binary difference seen before/after changes is shown below:
+
+| drivers/infiniband/hw/irdma/hw.o
+| @@ -868,7 +868,7 @@
+| drivers/infiniband/hw/irdma/hw.c:484 (discriminator 2)
+| size += struct_size(iw_qvlist, qv_info, rf->msix_count);
+| 55b: imul $0x45c,%rdi,%rdi
+|- 562: add $0x10,%rdi
+|+ 562: add $0x4,%rdi
+
+which is, of course, expected as it reflects the mistake made
+while folding the patch I've mentioned above.
+
+Worth mentioning is the fact that with this change we save 12 bytes
+of memory, as can be inferred from the diff snapshot above. Notice
+that:
+
+$ pahole -C rdma_qv_info idrivers/infiniband/hw/irdma/hw.o
+struct irdma_qv_info {
+ u32 v_idx; /* 0 4 */
+ u16 ceq_idx; /* 4 2 */
+ u16 aeq_idx; /* 6 2 */
+ u8 itr_idx; /* 8 1 */
+
+ /* size: 12, cachelines: 1, members: 4 */
+ /* padding: 3 */
+ /* last cacheline: 12 bytes */
+};
+
+Link: https://lore.kernel.org/linux-hardening/20210525230038.GA175516@embeddedor/ [1]
+Link: https://lore.kernel.org/linux-hardening/bf46b428deef4e9e89b0ea1704b1f0e5@intel.com/ [2]
+Link: https://lore.kernel.org/linux-rdma/20210520143809.819-1-shiraz.saleem@intel.com/T/#u [3]
+Fixes: 44d9e52977a1 ("RDMA/irdma: Implement device initialization definitions")
+Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
+Link: https://lore.kernel.org/r/ZMpsQrZadBaJGkt4@work
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/irdma/main.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/irdma/main.h b/drivers/infiniband/hw/irdma/main.h
+index 2323962cdeacb..de2f4c0514118 100644
+--- a/drivers/infiniband/hw/irdma/main.h
++++ b/drivers/infiniband/hw/irdma/main.h
+@@ -239,7 +239,7 @@ struct irdma_qv_info {
+
+ struct irdma_qvlist_info {
+ u32 num_vectors;
+- struct irdma_qv_info qv_info[1];
++ struct irdma_qv_info qv_info[];
+ };
+
+ struct irdma_gen_ops {
+--
+2.40.1
+
--- /dev/null
+From 63cf46a05ea39cd4425916c8a2d89f880cee3a98 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Jul 2023 10:27:03 +0800
+Subject: RDMA/qedr: Remove a duplicate assignment in irdma_query_ah()
+
+From: Minjie Du <duminjie@vivo.com>
+
+[ Upstream commit 65e02e840847158c7ee48ca8e6e91062b0f78662 ]
+
+Delete a duplicate statement from this function implementation.
+
+Fixes: b48c24c2d710 ("RDMA/irdma: Implement device supported verb APIs")
+Signed-off-by: Minjie Du <duminjie@vivo.com>
+Acked-by: Alok Prasad <palok@marvell.com>
+Link: https://lore.kernel.org/r/20230706022704.1260-1-duminjie@vivo.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/irdma/verbs.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c
+index eaa12c1245982..8f9378767f307 100644
+--- a/drivers/infiniband/hw/irdma/verbs.c
++++ b/drivers/infiniband/hw/irdma/verbs.c
+@@ -4424,7 +4424,6 @@ static int irdma_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr)
+ ah_attr->grh.traffic_class = ah->sc_ah.ah_info.tc_tos;
+ ah_attr->grh.hop_limit = ah->sc_ah.ah_info.hop_ttl;
+ ah_attr->grh.sgid_index = ah->sgid_index;
+- ah_attr->grh.sgid_index = ah->sgid_index;
+ memcpy(&ah_attr->grh.dgid, &ah->dgid,
+ sizeof(ah_attr->grh.dgid));
+ }
+--
+2.40.1
+
--- /dev/null
+From 2606f5e0fa5e1f767efb8cf4b8935781cd191523 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Jul 2023 15:07:49 -0500
+Subject: RDMA/rxe: Fix incomplete state save in rxe_requester
+
+From: Bob Pearson <rpearsonhpe@gmail.com>
+
+[ Upstream commit 5d122db2ff80cd2aed4dcd630befb56b51ddf947 ]
+
+If a send packet is dropped by the IP layer in rxe_requester()
+the call to rxe_xmit_packet() can fail with err == -EAGAIN.
+To recover, the state of the wqe is restored to the state before
+the packet was sent so it can be resent. However, the routines
+that save and restore the state miss a significnt part of the
+variable state in the wqe, the dma struct which is used to process
+through the sge table. And, the state is not saved before the packet
+is built which modifies the dma struct.
+
+Under heavy stress testing with many QPs on a fast node sending
+large messages to a slow node dropped packets are observed and
+the resent packets are corrupted because the dma struct was not
+restored. This patch fixes this behavior and allows the test cases
+to succeed.
+
+Fixes: 3050b9985024 ("IB/rxe: Fix race condition between requester and completer")
+Link: https://lore.kernel.org/r/20230721200748.4604-1-rpearsonhpe@gmail.com
+Signed-off-by: Bob Pearson <rpearsonhpe@gmail.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/sw/rxe/rxe_req.c | 45 ++++++++++++++++-------------
+ 1 file changed, 25 insertions(+), 20 deletions(-)
+
+diff --git a/drivers/infiniband/sw/rxe/rxe_req.c b/drivers/infiniband/sw/rxe/rxe_req.c
+index 5fe7cbae30313..1104255b7be9a 100644
+--- a/drivers/infiniband/sw/rxe/rxe_req.c
++++ b/drivers/infiniband/sw/rxe/rxe_req.c
+@@ -578,10 +578,11 @@ static void save_state(struct rxe_send_wqe *wqe,
+ struct rxe_send_wqe *rollback_wqe,
+ u32 *rollback_psn)
+ {
+- rollback_wqe->state = wqe->state;
++ rollback_wqe->state = wqe->state;
+ rollback_wqe->first_psn = wqe->first_psn;
+- rollback_wqe->last_psn = wqe->last_psn;
+- *rollback_psn = qp->req.psn;
++ rollback_wqe->last_psn = wqe->last_psn;
++ rollback_wqe->dma = wqe->dma;
++ *rollback_psn = qp->req.psn;
+ }
+
+ static void rollback_state(struct rxe_send_wqe *wqe,
+@@ -589,10 +590,11 @@ static void rollback_state(struct rxe_send_wqe *wqe,
+ struct rxe_send_wqe *rollback_wqe,
+ u32 rollback_psn)
+ {
+- wqe->state = rollback_wqe->state;
++ wqe->state = rollback_wqe->state;
+ wqe->first_psn = rollback_wqe->first_psn;
+- wqe->last_psn = rollback_wqe->last_psn;
+- qp->req.psn = rollback_psn;
++ wqe->last_psn = rollback_wqe->last_psn;
++ wqe->dma = rollback_wqe->dma;
++ qp->req.psn = rollback_psn;
+ }
+
+ static void update_state(struct rxe_qp *qp, struct rxe_pkt_info *pkt)
+@@ -797,6 +799,9 @@ int rxe_requester(struct rxe_qp *qp)
+ pkt.mask = rxe_opcode[opcode].mask;
+ pkt.wqe = wqe;
+
++ /* save wqe state before we build and send packet */
++ save_state(wqe, qp, &rollback_wqe, &rollback_psn);
++
+ av = rxe_get_av(&pkt, &ah);
+ if (unlikely(!av)) {
+ rxe_dbg_qp(qp, "Failed no address vector\n");
+@@ -829,29 +834,29 @@ int rxe_requester(struct rxe_qp *qp)
+ if (ah)
+ rxe_put(ah);
+
+- /*
+- * To prevent a race on wqe access between requester and completer,
+- * wqe members state and psn need to be set before calling
+- * rxe_xmit_packet().
+- * Otherwise, completer might initiate an unjustified retry flow.
+- */
+- save_state(wqe, qp, &rollback_wqe, &rollback_psn);
++ /* update wqe state as though we had sent it */
+ update_wqe_state(qp, wqe, &pkt);
+ update_wqe_psn(qp, wqe, &pkt, payload);
+
+ err = rxe_xmit_packet(qp, &pkt, skb);
+ if (err) {
+- qp->need_req_skb = 1;
++ if (err != -EAGAIN) {
++ wqe->status = IB_WC_LOC_QP_OP_ERR;
++ goto err;
++ }
+
++ /* the packet was dropped so reset wqe to the state
++ * before we sent it so we can try to resend
++ */
+ rollback_state(wqe, qp, &rollback_wqe, rollback_psn);
+
+- if (err == -EAGAIN) {
+- rxe_sched_task(&qp->req.task);
+- goto exit;
+- }
++ /* force a delay until the dropped packet is freed and
++ * the send queue is drained below the low water mark
++ */
++ qp->need_req_skb = 1;
+
+- wqe->status = IB_WC_LOC_QP_OP_ERR;
+- goto err;
++ rxe_sched_task(&qp->req.task);
++ goto exit;
+ }
+
+ update_state(qp, &pkt);
+--
+2.40.1
+
--- /dev/null
+From ebb1135477bf904a4ebcbd0a4d505a65ea330ff2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Jun 2023 09:01:43 -0500
+Subject: RDMA/rxe: Fix rxe_modify_srq
+
+From: Bob Pearson <rpearsonhpe@gmail.com>
+
+[ Upstream commit cc28f351155def8db209647f2e20a59a7080825b ]
+
+This patch corrects an error in rxe_modify_srq where if the
+caller changes the srq size the actual new value is not returned
+to the caller since it may be larger than what is requested.
+Additionally it open codes the subroutine rcv_wqe_size() which
+adds very little value, and makes some whitespace changes.
+
+Fixes: 8700e3e7c485 ("Soft RoCE driver")
+Link: https://lore.kernel.org/r/20230620140142.9452-1-rpearsonhpe@gmail.com
+Signed-off-by: Bob Pearson <rpearsonhpe@gmail.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/sw/rxe/rxe_loc.h | 6 ---
+ drivers/infiniband/sw/rxe/rxe_srq.c | 60 +++++++++++++++++------------
+ 2 files changed, 36 insertions(+), 30 deletions(-)
+
+diff --git a/drivers/infiniband/sw/rxe/rxe_loc.h b/drivers/infiniband/sw/rxe/rxe_loc.h
+index 804b15e929dd9..5b32724a95c8d 100644
+--- a/drivers/infiniband/sw/rxe/rxe_loc.h
++++ b/drivers/infiniband/sw/rxe/rxe_loc.h
+@@ -138,12 +138,6 @@ static inline int qp_mtu(struct rxe_qp *qp)
+ return IB_MTU_4096;
+ }
+
+-static inline int rcv_wqe_size(int max_sge)
+-{
+- return sizeof(struct rxe_recv_wqe) +
+- max_sge * sizeof(struct ib_sge);
+-}
+-
+ void free_rd_atomic_resource(struct resp_res *res);
+
+ static inline void rxe_advance_resp_resource(struct rxe_qp *qp)
+diff --git a/drivers/infiniband/sw/rxe/rxe_srq.c b/drivers/infiniband/sw/rxe/rxe_srq.c
+index 27ca82ec0826b..3661cb627d28a 100644
+--- a/drivers/infiniband/sw/rxe/rxe_srq.c
++++ b/drivers/infiniband/sw/rxe/rxe_srq.c
+@@ -45,40 +45,41 @@ int rxe_srq_from_init(struct rxe_dev *rxe, struct rxe_srq *srq,
+ struct ib_srq_init_attr *init, struct ib_udata *udata,
+ struct rxe_create_srq_resp __user *uresp)
+ {
+- int err;
+- int srq_wqe_size;
+ struct rxe_queue *q;
+- enum queue_type type;
++ int wqe_size;
++ int err;
+
+- srq->ibsrq.event_handler = init->event_handler;
+- srq->ibsrq.srq_context = init->srq_context;
+- srq->limit = init->attr.srq_limit;
+- srq->srq_num = srq->elem.index;
+- srq->rq.max_wr = init->attr.max_wr;
+- srq->rq.max_sge = init->attr.max_sge;
++ srq->ibsrq.event_handler = init->event_handler;
++ srq->ibsrq.srq_context = init->srq_context;
++ srq->limit = init->attr.srq_limit;
++ srq->srq_num = srq->elem.index;
++ srq->rq.max_wr = init->attr.max_wr;
++ srq->rq.max_sge = init->attr.max_sge;
+
+- srq_wqe_size = rcv_wqe_size(srq->rq.max_sge);
++ wqe_size = sizeof(struct rxe_recv_wqe) +
++ srq->rq.max_sge*sizeof(struct ib_sge);
+
+ spin_lock_init(&srq->rq.producer_lock);
+ spin_lock_init(&srq->rq.consumer_lock);
+
+- type = QUEUE_TYPE_FROM_CLIENT;
+- q = rxe_queue_init(rxe, &srq->rq.max_wr, srq_wqe_size, type);
++ q = rxe_queue_init(rxe, &srq->rq.max_wr, wqe_size,
++ QUEUE_TYPE_FROM_CLIENT);
+ if (!q) {
+ rxe_dbg_srq(srq, "Unable to allocate queue\n");
+- return -ENOMEM;
++ err = -ENOMEM;
++ goto err_out;
+ }
+
+- srq->rq.queue = q;
+-
+ err = do_mmap_info(rxe, uresp ? &uresp->mi : NULL, udata, q->buf,
+ q->buf_size, &q->ip);
+ if (err) {
+- vfree(q->buf);
+- kfree(q);
+- return err;
++ rxe_dbg_srq(srq, "Unable to init mmap info for caller\n");
++ goto err_free;
+ }
+
++ srq->rq.queue = q;
++ init->attr.max_wr = srq->rq.max_wr;
++
+ if (uresp) {
+ if (copy_to_user(&uresp->srq_num, &srq->srq_num,
+ sizeof(uresp->srq_num))) {
+@@ -88,6 +89,12 @@ int rxe_srq_from_init(struct rxe_dev *rxe, struct rxe_srq *srq,
+ }
+
+ return 0;
++
++err_free:
++ vfree(q->buf);
++ kfree(q);
++err_out:
++ return err;
+ }
+
+ int rxe_srq_chk_attr(struct rxe_dev *rxe, struct rxe_srq *srq,
+@@ -145,9 +152,10 @@ int rxe_srq_from_attr(struct rxe_dev *rxe, struct rxe_srq *srq,
+ struct ib_srq_attr *attr, enum ib_srq_attr_mask mask,
+ struct rxe_modify_srq_cmd *ucmd, struct ib_udata *udata)
+ {
+- int err;
+ struct rxe_queue *q = srq->rq.queue;
+ struct mminfo __user *mi = NULL;
++ int wqe_size;
++ int err;
+
+ if (mask & IB_SRQ_MAX_WR) {
+ /*
+@@ -156,12 +164,16 @@ int rxe_srq_from_attr(struct rxe_dev *rxe, struct rxe_srq *srq,
+ */
+ mi = u64_to_user_ptr(ucmd->mmap_info_addr);
+
+- err = rxe_queue_resize(q, &attr->max_wr,
+- rcv_wqe_size(srq->rq.max_sge), udata, mi,
+- &srq->rq.producer_lock,
++ wqe_size = sizeof(struct rxe_recv_wqe) +
++ srq->rq.max_sge*sizeof(struct ib_sge);
++
++ err = rxe_queue_resize(q, &attr->max_wr, wqe_size,
++ udata, mi, &srq->rq.producer_lock,
+ &srq->rq.consumer_lock);
+ if (err)
+- goto err2;
++ goto err_free;
++
++ srq->rq.max_wr = attr->max_wr;
+ }
+
+ if (mask & IB_SRQ_LIMIT)
+@@ -169,7 +181,7 @@ int rxe_srq_from_attr(struct rxe_dev *rxe, struct rxe_srq *srq,
+
+ return 0;
+
+-err2:
++err_free:
+ rxe_queue_cleanup(q);
+ srq->rq.queue = NULL;
+ return err;
+--
+2.40.1
+
--- /dev/null
+From 31ae0995a40a513008d8853b5a2a63794db62f46 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Jun 2023 08:55:21 -0500
+Subject: RDMA/rxe: Fix unsafe drain work queue code
+
+From: Bob Pearson <rpearsonhpe@gmail.com>
+
+[ Upstream commit 5993b75d0bc71cd2b441d174b028fc36180f032c ]
+
+If create_qp does not fully succeed it is possible for qp cleanup
+code to attempt to drain the send or recv work queues before the
+queues have been created causing a seg fault. This patch checks
+to see if the queues exist before attempting to drain them.
+
+Link: https://lore.kernel.org/r/20230620135519.9365-3-rpearsonhpe@gmail.com
+Reported-by: syzbot+2da1965168e7dbcba136@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/linux-rdma/00000000000012d89205fe7cfe00@google.com/raw
+Fixes: 49dc9c1f0c7e ("RDMA/rxe: Cleanup reset state handling in rxe_resp.c")
+Fixes: fbdeb828a21f ("RDMA/rxe: Cleanup error state handling in rxe_comp.c")
+Signed-off-by: Bob Pearson <rpearsonhpe@gmail.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/sw/rxe/rxe_comp.c | 4 ++++
+ drivers/infiniband/sw/rxe/rxe_resp.c | 4 ++++
+ 2 files changed, 8 insertions(+)
+
+diff --git a/drivers/infiniband/sw/rxe/rxe_comp.c b/drivers/infiniband/sw/rxe/rxe_comp.c
+index f46c5a5fd0aea..44fece204abdd 100644
+--- a/drivers/infiniband/sw/rxe/rxe_comp.c
++++ b/drivers/infiniband/sw/rxe/rxe_comp.c
+@@ -597,6 +597,10 @@ static void flush_send_queue(struct rxe_qp *qp, bool notify)
+ struct rxe_queue *q = qp->sq.queue;
+ int err;
+
++ /* send queue never got created. nothing to do. */
++ if (!qp->sq.queue)
++ return;
++
+ while ((wqe = queue_head(q, q->type))) {
+ if (notify) {
+ err = flush_send_wqe(qp, wqe);
+diff --git a/drivers/infiniband/sw/rxe/rxe_resp.c b/drivers/infiniband/sw/rxe/rxe_resp.c
+index ee68306555b99..ed5af55237d9f 100644
+--- a/drivers/infiniband/sw/rxe/rxe_resp.c
++++ b/drivers/infiniband/sw/rxe/rxe_resp.c
+@@ -1452,6 +1452,10 @@ static void flush_recv_queue(struct rxe_qp *qp, bool notify)
+ if (qp->srq)
+ return;
+
++ /* recv queue not created. nothing to do. */
++ if (!qp->rq.queue)
++ return;
++
+ while ((wqe = queue_head(q, q->type))) {
+ if (notify) {
+ err = flush_recv_wqe(qp, wqe);
+--
+2.40.1
+
--- /dev/null
+From befc7a97c81b2cf74b65ebd88f5132d1ebe2478e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Jun 2023 08:55:19 -0500
+Subject: RDMA/rxe: Move work queue code to subroutines
+
+From: Bob Pearson <rpearsonhpe@gmail.com>
+
+[ Upstream commit e0ba8ff46704fc924e2ef0451ba196cbdc0d68f2 ]
+
+This patch:
+ - Moves code to initialize a qp send work queue to a
+ subroutine named rxe_init_sq.
+ - Moves code to initialize a qp recv work queue to a
+ subroutine named rxe_init_rq.
+ - Moves initialization of qp request and response packet
+ queues ahead of work queue initialization so that cleanup
+ of a qp if it is not fully completed can successfully
+ attempt to drain the packet queues without a seg fault.
+ - Makes minor whitespace cleanups.
+
+Fixes: 8700e3e7c485 ("Soft RoCE driver")
+Link: https://lore.kernel.org/r/20230620135519.9365-2-rpearsonhpe@gmail.com
+Signed-off-by: Bob Pearson <rpearsonhpe@gmail.com>
+Acked-by: Zhu Yanjun <zyjzyj2000@gmail.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/sw/rxe/rxe_qp.c | 159 ++++++++++++++++++++---------
+ 1 file changed, 108 insertions(+), 51 deletions(-)
+
+diff --git a/drivers/infiniband/sw/rxe/rxe_qp.c b/drivers/infiniband/sw/rxe/rxe_qp.c
+index a0f206431cf8e..b66afadbd7c40 100644
+--- a/drivers/infiniband/sw/rxe/rxe_qp.c
++++ b/drivers/infiniband/sw/rxe/rxe_qp.c
+@@ -183,13 +183,63 @@ static void rxe_qp_init_misc(struct rxe_dev *rxe, struct rxe_qp *qp,
+ atomic_set(&qp->skb_out, 0);
+ }
+
++static int rxe_init_sq(struct rxe_qp *qp, struct ib_qp_init_attr *init,
++ struct ib_udata *udata,
++ struct rxe_create_qp_resp __user *uresp)
++{
++ struct rxe_dev *rxe = to_rdev(qp->ibqp.device);
++ int wqe_size;
++ int err;
++
++ qp->sq.max_wr = init->cap.max_send_wr;
++ wqe_size = max_t(int, init->cap.max_send_sge * sizeof(struct ib_sge),
++ init->cap.max_inline_data);
++ qp->sq.max_sge = wqe_size / sizeof(struct ib_sge);
++ qp->sq.max_inline = wqe_size;
++ wqe_size += sizeof(struct rxe_send_wqe);
++
++ qp->sq.queue = rxe_queue_init(rxe, &qp->sq.max_wr, wqe_size,
++ QUEUE_TYPE_FROM_CLIENT);
++ if (!qp->sq.queue) {
++ rxe_err_qp(qp, "Unable to allocate send queue");
++ err = -ENOMEM;
++ goto err_out;
++ }
++
++ /* prepare info for caller to mmap send queue if user space qp */
++ err = do_mmap_info(rxe, uresp ? &uresp->sq_mi : NULL, udata,
++ qp->sq.queue->buf, qp->sq.queue->buf_size,
++ &qp->sq.queue->ip);
++ if (err) {
++ rxe_err_qp(qp, "do_mmap_info failed, err = %d", err);
++ goto err_free;
++ }
++
++ /* return actual capabilities to caller which may be larger
++ * than requested
++ */
++ init->cap.max_send_wr = qp->sq.max_wr;
++ init->cap.max_send_sge = qp->sq.max_sge;
++ init->cap.max_inline_data = qp->sq.max_inline;
++
++ return 0;
++
++err_free:
++ vfree(qp->sq.queue->buf);
++ kfree(qp->sq.queue);
++ qp->sq.queue = NULL;
++err_out:
++ return err;
++}
++
+ static int rxe_qp_init_req(struct rxe_dev *rxe, struct rxe_qp *qp,
+ struct ib_qp_init_attr *init, struct ib_udata *udata,
+ struct rxe_create_qp_resp __user *uresp)
+ {
+ int err;
+- int wqe_size;
+- enum queue_type type;
++
++ /* if we don't finish qp create make sure queue is valid */
++ skb_queue_head_init(&qp->req_pkts);
+
+ err = sock_create_kern(&init_net, AF_INET, SOCK_DGRAM, 0, &qp->sk);
+ if (err < 0)
+@@ -204,32 +254,10 @@ static int rxe_qp_init_req(struct rxe_dev *rxe, struct rxe_qp *qp,
+ * (0xc000 - 0xffff).
+ */
+ qp->src_port = RXE_ROCE_V2_SPORT + (hash_32(qp_num(qp), 14) & 0x3fff);
+- qp->sq.max_wr = init->cap.max_send_wr;
+-
+- /* These caps are limited by rxe_qp_chk_cap() done by the caller */
+- wqe_size = max_t(int, init->cap.max_send_sge * sizeof(struct ib_sge),
+- init->cap.max_inline_data);
+- qp->sq.max_sge = init->cap.max_send_sge =
+- wqe_size / sizeof(struct ib_sge);
+- qp->sq.max_inline = init->cap.max_inline_data = wqe_size;
+- wqe_size += sizeof(struct rxe_send_wqe);
+
+- type = QUEUE_TYPE_FROM_CLIENT;
+- qp->sq.queue = rxe_queue_init(rxe, &qp->sq.max_wr,
+- wqe_size, type);
+- if (!qp->sq.queue)
+- return -ENOMEM;
+-
+- err = do_mmap_info(rxe, uresp ? &uresp->sq_mi : NULL, udata,
+- qp->sq.queue->buf, qp->sq.queue->buf_size,
+- &qp->sq.queue->ip);
+-
+- if (err) {
+- vfree(qp->sq.queue->buf);
+- kfree(qp->sq.queue);
+- qp->sq.queue = NULL;
++ err = rxe_init_sq(qp, init, udata, uresp);
++ if (err)
+ return err;
+- }
+
+ qp->req.wqe_index = queue_get_producer(qp->sq.queue,
+ QUEUE_TYPE_FROM_CLIENT);
+@@ -248,36 +276,65 @@ static int rxe_qp_init_req(struct rxe_dev *rxe, struct rxe_qp *qp,
+ return 0;
+ }
+
++static int rxe_init_rq(struct rxe_qp *qp, struct ib_qp_init_attr *init,
++ struct ib_udata *udata,
++ struct rxe_create_qp_resp __user *uresp)
++{
++ struct rxe_dev *rxe = to_rdev(qp->ibqp.device);
++ int wqe_size;
++ int err;
++
++ qp->rq.max_wr = init->cap.max_recv_wr;
++ qp->rq.max_sge = init->cap.max_recv_sge;
++ wqe_size = sizeof(struct rxe_recv_wqe) +
++ qp->rq.max_sge*sizeof(struct ib_sge);
++
++ qp->rq.queue = rxe_queue_init(rxe, &qp->rq.max_wr, wqe_size,
++ QUEUE_TYPE_FROM_CLIENT);
++ if (!qp->rq.queue) {
++ rxe_err_qp(qp, "Unable to allocate recv queue");
++ err = -ENOMEM;
++ goto err_out;
++ }
++
++ /* prepare info for caller to mmap recv queue if user space qp */
++ err = do_mmap_info(rxe, uresp ? &uresp->rq_mi : NULL, udata,
++ qp->rq.queue->buf, qp->rq.queue->buf_size,
++ &qp->rq.queue->ip);
++ if (err) {
++ rxe_err_qp(qp, "do_mmap_info failed, err = %d", err);
++ goto err_free;
++ }
++
++ /* return actual capabilities to caller which may be larger
++ * than requested
++ */
++ init->cap.max_recv_wr = qp->rq.max_wr;
++
++ return 0;
++
++err_free:
++ vfree(qp->rq.queue->buf);
++ kfree(qp->rq.queue);
++ qp->rq.queue = NULL;
++err_out:
++ return err;
++}
++
+ static int rxe_qp_init_resp(struct rxe_dev *rxe, struct rxe_qp *qp,
+ struct ib_qp_init_attr *init,
+ struct ib_udata *udata,
+ struct rxe_create_qp_resp __user *uresp)
+ {
+ int err;
+- int wqe_size;
+- enum queue_type type;
++
++ /* if we don't finish qp create make sure queue is valid */
++ skb_queue_head_init(&qp->resp_pkts);
+
+ if (!qp->srq) {
+- qp->rq.max_wr = init->cap.max_recv_wr;
+- qp->rq.max_sge = init->cap.max_recv_sge;
+-
+- wqe_size = rcv_wqe_size(qp->rq.max_sge);
+-
+- type = QUEUE_TYPE_FROM_CLIENT;
+- qp->rq.queue = rxe_queue_init(rxe, &qp->rq.max_wr,
+- wqe_size, type);
+- if (!qp->rq.queue)
+- return -ENOMEM;
+-
+- err = do_mmap_info(rxe, uresp ? &uresp->rq_mi : NULL, udata,
+- qp->rq.queue->buf, qp->rq.queue->buf_size,
+- &qp->rq.queue->ip);
+- if (err) {
+- vfree(qp->rq.queue->buf);
+- kfree(qp->rq.queue);
+- qp->rq.queue = NULL;
++ err = rxe_init_rq(qp, init, udata, uresp);
++ if (err)
+ return err;
+- }
+ }
+
+ rxe_init_task(&qp->resp.task, qp, rxe_responder);
+@@ -307,10 +364,10 @@ int rxe_qp_from_init(struct rxe_dev *rxe, struct rxe_qp *qp, struct rxe_pd *pd,
+ if (srq)
+ rxe_get(srq);
+
+- qp->pd = pd;
+- qp->rcq = rcq;
+- qp->scq = scq;
+- qp->srq = srq;
++ qp->pd = pd;
++ qp->rcq = rcq;
++ qp->scq = scq;
++ qp->srq = srq;
+
+ atomic_inc(&rcq->num_wq);
+ atomic_inc(&scq->num_wq);
+--
+2.40.1
+
--- /dev/null
+From 1ce77a7d1a12c99a99e0a4323bc05865d2b288d9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Aug 2023 21:32:53 +0800
+Subject: RDMA/siw: Balance the reference of cep->kref in the error path
+
+From: Guoqing Jiang <guoqing.jiang@linux.dev>
+
+[ Upstream commit b056327bee09e6b86683d3f709a438ccd6031d72 ]
+
+The siw_connect can go to err in below after cep is allocated successfully:
+
+1. If siw_cm_alloc_work returns failure. In this case socket is not
+assoicated with cep so siw_cep_put can't be called by siw_socket_disassoc.
+We need to call siw_cep_put twice since cep->kref is increased once after
+it was initialized.
+
+2. If siw_cm_queue_work can't find a work, which means siw_cep_get is not
+called in siw_cm_queue_work, so cep->kref is increased twice by siw_cep_get
+and when associate socket with cep after it was initialized. So we need to
+call siw_cep_put three times (one in siw_socket_disassoc).
+
+3. siw_send_mpareqrep returns error, this scenario is similar as 2.
+
+So we need to remove one siw_cep_put in the error path.
+
+Fixes: 6c52fdc244b5 ("rdma/siw: connection management")
+Signed-off-by: Guoqing Jiang <guoqing.jiang@linux.dev>
+Link: https://lore.kernel.org/r/20230821133255.31111-2-guoqing.jiang@linux.dev
+Acked-by: Bernard Metzler <bmt@zurich.ibm.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/sw/siw/siw_cm.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/infiniband/sw/siw/siw_cm.c b/drivers/infiniband/sw/siw/siw_cm.c
+index da530c0404da4..a2605178f4eda 100644
+--- a/drivers/infiniband/sw/siw/siw_cm.c
++++ b/drivers/infiniband/sw/siw/siw_cm.c
+@@ -1501,7 +1501,6 @@ int siw_connect(struct iw_cm_id *id, struct iw_cm_conn_param *params)
+
+ cep->cm_id = NULL;
+ id->rem_ref(id);
+- siw_cep_put(cep);
+
+ qp->cep = NULL;
+ siw_cep_put(cep);
+--
+2.40.1
+
--- /dev/null
+From 79b66f9ac7cd012a02c5007565eb194d432753e8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Aug 2023 21:32:54 +0800
+Subject: RDMA/siw: Correct wrong debug message
+
+From: Guoqing Jiang <guoqing.jiang@linux.dev>
+
+[ Upstream commit bee024d20451e4ce04ea30099cad09f7f75d288b ]
+
+We need to print num_sle first then pbl->max_buf per the condition.
+Also replace mem->pbl with pbl while at it.
+
+Fixes: 303ae1cdfdf7 ("rdma/siw: application interface")
+Signed-off-by: Guoqing Jiang <guoqing.jiang@linux.dev>
+Link: https://lore.kernel.org/r/20230821133255.31111-3-guoqing.jiang@linux.dev
+Acked-by: Bernard Metzler <bmt@zurich.ibm.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/sw/siw/siw_verbs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/sw/siw/siw_verbs.c b/drivers/infiniband/sw/siw/siw_verbs.c
+index 32b0befd25e27..10cabc792c68e 100644
+--- a/drivers/infiniband/sw/siw/siw_verbs.c
++++ b/drivers/infiniband/sw/siw/siw_verbs.c
+@@ -1494,7 +1494,7 @@ int siw_map_mr_sg(struct ib_mr *base_mr, struct scatterlist *sl, int num_sle,
+
+ if (pbl->max_buf < num_sle) {
+ siw_dbg_mem(mem, "too many SGE's: %d > %d\n",
+- mem->pbl->max_buf, num_sle);
++ num_sle, pbl->max_buf);
+ return -ENOMEM;
+ }
+ for_each_sg(sl, slp, num_sle, i) {
+--
+2.40.1
+
--- /dev/null
+From 374fb30e49e7c37f792698fc3818946ab7a9d98c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Jul 2023 11:12:12 -0400
+Subject: RDMA/siw: Fabricate a GID on tun and loopback devices
+
+From: Chuck Lever <chuck.lever@oracle.com>
+
+[ Upstream commit bad5b6e34ffbaacc77ad28a0f482e33b3929e635 ]
+
+LOOPBACK and NONE (tunnel) devices have all-zero MAC addresses.
+Currently, siw_device_create() falls back to copying the IB device's
+name in those cases, because an all-zero MAC address breaks the RDMA
+core address resolution mechanism.
+
+However, at the point when siw_device_create() constructs a GID, the
+ib_device::name field is uninitialized, leaving the MAC address to
+remain in an all-zero state.
+
+Fabricate a random artificial GID for such devices, and ensure this
+artificial GID is returned for all device query operations.
+
+Link: https://lore.kernel.org/r/168960673260.3007.12378736853793339110.stgit@manet.1015granger.net
+Reported-by: Tom Talpey <tom@talpey.com>
+Fixes: a2d36b02c15d ("RDMA/siw: Enable siw on tunnel devices")
+Reviewed-by: Bernard Metzler <bmt@zurich.ibm.com>
+Reviewed-by: Tom Talpey <tom@talpey.com>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/sw/siw/siw.h | 1 +
+ drivers/infiniband/sw/siw/siw_main.c | 22 ++++++++--------------
+ drivers/infiniband/sw/siw/siw_verbs.c | 4 ++--
+ 3 files changed, 11 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/infiniband/sw/siw/siw.h b/drivers/infiniband/sw/siw/siw.h
+index 2f3a9cda3850f..8b4a710b82bc1 100644
+--- a/drivers/infiniband/sw/siw/siw.h
++++ b/drivers/infiniband/sw/siw/siw.h
+@@ -74,6 +74,7 @@ struct siw_device {
+
+ u32 vendor_part_id;
+ int numa_node;
++ char raw_gid[ETH_ALEN];
+
+ /* physical port state (only one port per device) */
+ enum ib_port_state state;
+diff --git a/drivers/infiniband/sw/siw/siw_main.c b/drivers/infiniband/sw/siw/siw_main.c
+index 65b5cda5457ba..f45600d169ae7 100644
+--- a/drivers/infiniband/sw/siw/siw_main.c
++++ b/drivers/infiniband/sw/siw/siw_main.c
+@@ -75,8 +75,7 @@ static int siw_device_register(struct siw_device *sdev, const char *name)
+ return rv;
+ }
+
+- siw_dbg(base_dev, "HWaddr=%pM\n", sdev->netdev->dev_addr);
+-
++ siw_dbg(base_dev, "HWaddr=%pM\n", sdev->raw_gid);
+ return 0;
+ }
+
+@@ -313,24 +312,19 @@ static struct siw_device *siw_device_create(struct net_device *netdev)
+ return NULL;
+
+ base_dev = &sdev->base_dev;
+-
+ sdev->netdev = netdev;
+
+- if (netdev->type != ARPHRD_LOOPBACK && netdev->type != ARPHRD_NONE) {
+- addrconf_addr_eui48((unsigned char *)&base_dev->node_guid,
+- netdev->dev_addr);
++ if (netdev->addr_len) {
++ memcpy(sdev->raw_gid, netdev->dev_addr,
++ min_t(unsigned int, netdev->addr_len, ETH_ALEN));
+ } else {
+ /*
+- * This device does not have a HW address,
+- * but connection mangagement lib expects gid != 0
++ * This device does not have a HW address, but
++ * connection mangagement requires a unique gid.
+ */
+- size_t len = min_t(size_t, strlen(base_dev->name), 6);
+- char addr[6] = { };
+-
+- memcpy(addr, base_dev->name, len);
+- addrconf_addr_eui48((unsigned char *)&base_dev->node_guid,
+- addr);
++ eth_random_addr(sdev->raw_gid);
+ }
++ addrconf_addr_eui48((u8 *)&base_dev->node_guid, sdev->raw_gid);
+
+ base_dev->uverbs_cmd_mask |= BIT_ULL(IB_USER_VERBS_CMD_POST_SEND);
+
+diff --git a/drivers/infiniband/sw/siw/siw_verbs.c b/drivers/infiniband/sw/siw/siw_verbs.c
+index 398ec13db6248..32b0befd25e27 100644
+--- a/drivers/infiniband/sw/siw/siw_verbs.c
++++ b/drivers/infiniband/sw/siw/siw_verbs.c
+@@ -157,7 +157,7 @@ int siw_query_device(struct ib_device *base_dev, struct ib_device_attr *attr,
+ attr->vendor_part_id = sdev->vendor_part_id;
+
+ addrconf_addr_eui48((u8 *)&attr->sys_image_guid,
+- sdev->netdev->dev_addr);
++ sdev->raw_gid);
+
+ return 0;
+ }
+@@ -218,7 +218,7 @@ int siw_query_gid(struct ib_device *base_dev, u32 port, int idx,
+
+ /* subnet_prefix == interface_id == 0; */
+ memset(gid, 0, sizeof(*gid));
+- memcpy(&gid->raw[0], sdev->netdev->dev_addr, 6);
++ memcpy(gid->raw, sdev->raw_gid, ETH_ALEN);
+
+ return 0;
+ }
+--
+2.40.1
+
--- /dev/null
+From 05552b1def90d8b664d69c0c18486ba3025c11b3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Jul 2023 13:53:55 -0400
+Subject: refscale: Fix uninitalized use of wait_queue_head_t
+
+From: Waiman Long <longman@redhat.com>
+
+[ Upstream commit f5063e8948dad7f31adb007284a5d5038ae31bb8 ]
+
+Running the refscale test occasionally crashes the kernel with the
+following error:
+
+[ 8569.952896] BUG: unable to handle page fault for address: ffffffffffffffe8
+[ 8569.952900] #PF: supervisor read access in kernel mode
+[ 8569.952902] #PF: error_code(0x0000) - not-present page
+[ 8569.952904] PGD c4b048067 P4D c4b049067 PUD c4b04b067 PMD 0
+[ 8569.952910] Oops: 0000 [#1] PREEMPT_RT SMP NOPTI
+[ 8569.952916] Hardware name: Dell Inc. PowerEdge R750/0WMWCR, BIOS 1.2.4 05/28/2021
+[ 8569.952917] RIP: 0010:prepare_to_wait_event+0x101/0x190
+ :
+[ 8569.952940] Call Trace:
+[ 8569.952941] <TASK>
+[ 8569.952944] ref_scale_reader+0x380/0x4a0 [refscale]
+[ 8569.952959] kthread+0x10e/0x130
+[ 8569.952966] ret_from_fork+0x1f/0x30
+[ 8569.952973] </TASK>
+
+The likely cause is that init_waitqueue_head() is called after the call to
+the torture_create_kthread() function that creates the ref_scale_reader
+kthread. Although this init_waitqueue_head() call will very likely
+complete before this kthread is created and starts running, it is
+possible that the calling kthread will be delayed between the calls to
+torture_create_kthread() and init_waitqueue_head(). In this case, the
+new kthread will use the waitqueue head before it is properly initialized,
+which is not good for the kernel's health and well-being.
+
+The above crash happened here:
+
+ static inline void __add_wait_queue(...)
+ {
+ :
+ if (!(wq->flags & WQ_FLAG_PRIORITY)) <=== Crash here
+
+The offset of flags from list_head entry in wait_queue_entry is
+-0x18. If reader_tasks[i].wq.head.next is NULL as allocated reader_task
+structure is zero initialized, the instruction will try to access address
+0xffffffffffffffe8, which is exactly the fault address listed above.
+
+This commit therefore invokes init_waitqueue_head() before creating
+the kthread.
+
+Fixes: 653ed64b01dc ("refperf: Add a test to measure performance of read-side synchronization")
+Signed-off-by: Waiman Long <longman@redhat.com>
+Reviewed-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
+Reviewed-by: Davidlohr Bueso <dave@stgolabs.net>
+Acked-by: Joel Fernandes (Google) <joel@joelfernandes.org>
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/rcu/refscale.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/kernel/rcu/refscale.c b/kernel/rcu/refscale.c
+index 1970ce5f22d40..71d138573856f 100644
+--- a/kernel/rcu/refscale.c
++++ b/kernel/rcu/refscale.c
+@@ -1107,12 +1107,11 @@ ref_scale_init(void)
+ VERBOSE_SCALEOUT("Starting %d reader threads", nreaders);
+
+ for (i = 0; i < nreaders; i++) {
++ init_waitqueue_head(&reader_tasks[i].wq);
+ firsterr = torture_create_kthread(ref_scale_reader, (void *)i,
+ reader_tasks[i].task);
+ if (torture_init_error(firsterr))
+ goto unwind;
+-
+- init_waitqueue_head(&(reader_tasks[i].wq));
+ }
+
+ // Main Task
+--
+2.40.1
+
--- /dev/null
+From ba560e4d4c541c5fbad849b2fc6206d4616b2b57 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 May 2023 22:22:27 +0100
+Subject: regmap: Load register defaults in blocks rather than register by
+ register
+
+From: Mark Brown <broonie@kernel.org>
+
+[ Upstream commit 3a48d2127f4dbd767d43bf8280b67d585e701f75 ]
+
+Currently we use the normal single register write function to load the
+default values into the cache, resulting in a large number of reallocations
+when there are blocks of registers as we extend the memory region we are
+using to store the values. Instead scan through the list of defaults for
+blocks of adjacent registers and do a single allocation and insert for each
+such block. No functional change.
+
+We do not take advantage of the maple tree preallocation, this is purely at
+the regcache level. It is not clear to me yet if the maple tree level would
+help much here or if we'd have more overhead from overallocating and then
+freeing maple tree data.
+
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Link: https://lore.kernel.org/r/20230523-regcache-maple-load-defaults-v1-1-0c04336f005d@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: b0393e1fe40e ("regmap: maple: Use alloc_flags for memory allocations")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/regmap/regcache-maple.c | 58 +++++++++++++++++++++++++---
+ 1 file changed, 52 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/base/regmap/regcache-maple.c b/drivers/base/regmap/regcache-maple.c
+index c2e3a0f6c2183..14f6f49af097c 100644
+--- a/drivers/base/regmap/regcache-maple.c
++++ b/drivers/base/regmap/regcache-maple.c
+@@ -242,11 +242,41 @@ static int regcache_maple_exit(struct regmap *map)
+ return 0;
+ }
+
++static int regcache_maple_insert_block(struct regmap *map, int first,
++ int last)
++{
++ struct maple_tree *mt = map->cache;
++ MA_STATE(mas, mt, first, last);
++ unsigned long *entry;
++ int i, ret;
++
++ entry = kcalloc(last - first + 1, sizeof(unsigned long), GFP_KERNEL);
++ if (!entry)
++ return -ENOMEM;
++
++ for (i = 0; i < last - first + 1; i++)
++ entry[i] = map->reg_defaults[first + i].def;
++
++ mas_lock(&mas);
++
++ mas_set_range(&mas, map->reg_defaults[first].reg,
++ map->reg_defaults[last].reg);
++ ret = mas_store_gfp(&mas, entry, GFP_KERNEL);
++
++ mas_unlock(&mas);
++
++ if (ret)
++ kfree(entry);
++
++ return ret;
++}
++
+ static int regcache_maple_init(struct regmap *map)
+ {
+ struct maple_tree *mt;
+ int i;
+ int ret;
++ int range_start;
+
+ mt = kmalloc(sizeof(*mt), GFP_KERNEL);
+ if (!mt)
+@@ -255,14 +285,30 @@ static int regcache_maple_init(struct regmap *map)
+
+ mt_init(mt);
+
+- for (i = 0; i < map->num_reg_defaults; i++) {
+- ret = regcache_maple_write(map,
+- map->reg_defaults[i].reg,
+- map->reg_defaults[i].def);
+- if (ret)
+- goto err;
++ if (!map->num_reg_defaults)
++ return 0;
++
++ range_start = 0;
++
++ /* Scan for ranges of contiguous registers */
++ for (i = 1; i < map->num_reg_defaults; i++) {
++ if (map->reg_defaults[i].reg !=
++ map->reg_defaults[i - 1].reg + 1) {
++ ret = regcache_maple_insert_block(map, range_start,
++ i - 1);
++ if (ret != 0)
++ goto err;
++
++ range_start = i;
++ }
+ }
+
++ /* Add the last block */
++ ret = regcache_maple_insert_block(map, range_start,
++ map->num_reg_defaults - 1);
++ if (ret != 0)
++ goto err;
++
+ return 0;
+
+ err:
+--
+2.40.1
+
--- /dev/null
+From d908d538c8544452e4b3627669d7b63cd5918318 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Jul 2023 10:20:21 -0700
+Subject: regmap: maple: Use alloc_flags for memory allocations
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+[ Upstream commit b0393e1fe40e962574613a5cdc4a470d6c1de023 ]
+
+REGCACHE_MAPLE needs to allocate memory for regmap operations.
+This results in lockdep splats if used with fast_io since fast_io uses
+spinlocks for locking.
+
+BUG: sleeping function called from invalid context at include/linux/sched/mm.h:306
+in_atomic(): 1, irqs_disabled(): 128, non_block: 0, pid: 167, name: kunit_try_catch
+preempt_count: 1, expected: 0
+1 lock held by kunit_try_catch/167:
+ #0: 838e9c10 (regmap_kunit:86:(config)->lock){....}-{2:2}, at: regmap_lock_spinlock+0x14/0x1c
+irq event stamp: 146
+hardirqs last enabled at (145): [<8078bfa8>] crng_make_state+0x1a0/0x294
+hardirqs last disabled at (146): [<80c5f62c>] _raw_spin_lock_irqsave+0x7c/0x80
+softirqs last enabled at (0): [<80110cc4>] copy_process+0x810/0x216c
+softirqs last disabled at (0): [<00000000>] 0x0
+CPU: 0 PID: 167 Comm: kunit_try_catch Tainted: G N 6.5.0-rc1-00028-gc4be22597a36-dirty #6
+Hardware name: Generic DT based system
+ unwind_backtrace from show_stack+0x18/0x1c
+ show_stack from dump_stack_lvl+0x38/0x5c
+ dump_stack_lvl from __might_resched+0x188/0x2d0
+ __might_resched from __kmem_cache_alloc_node+0x1f4/0x258
+ __kmem_cache_alloc_node from __kmalloc+0x48/0x170
+ __kmalloc from regcache_maple_write+0x194/0x248
+ regcache_maple_write from _regmap_write+0x88/0x140
+ _regmap_write from regmap_write+0x44/0x68
+ regmap_write from basic_read_write+0x8c/0x27c
+ basic_read_write from kunit_generic_run_threadfn_adapter+0x1c/0x28
+ kunit_generic_run_threadfn_adapter from kthread+0xf8/0x120
+ kthread from ret_from_fork+0x14/0x3c
+Exception stack(0x881a5fb0 to 0x881a5ff8)
+5fa0: 00000000 00000000 00000000 00000000
+5fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
+5fe0: 00000000 00000000 00000000 00000000 00000013 00000000
+
+Use map->alloc_flags instead of GFP_KERNEL for memory allocations to fix
+the problem.
+
+Fixes: f033c26de5a5 ("regmap: Add maple tree based register cache")
+Cc: Dan Carpenter <dan.carpenter@linaro.org>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://lore.kernel.org/r/20230720172021.2617326-1-linux@roeck-us.net
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/regmap/regcache-maple.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/base/regmap/regcache-maple.c b/drivers/base/regmap/regcache-maple.c
+index 14f6f49af097c..08316d578be23 100644
+--- a/drivers/base/regmap/regcache-maple.c
++++ b/drivers/base/regmap/regcache-maple.c
+@@ -74,7 +74,7 @@ static int regcache_maple_write(struct regmap *map, unsigned int reg,
+ rcu_read_unlock();
+
+ entry = kmalloc((last - index + 1) * sizeof(unsigned long),
+- GFP_KERNEL);
++ map->alloc_flags);
+ if (!entry)
+ return -ENOMEM;
+
+@@ -92,7 +92,7 @@ static int regcache_maple_write(struct regmap *map, unsigned int reg,
+ mas_lock(&mas);
+
+ mas_set_range(&mas, index, last);
+- ret = mas_store_gfp(&mas, entry, GFP_KERNEL);
++ ret = mas_store_gfp(&mas, entry, map->alloc_flags);
+
+ mas_unlock(&mas);
+
+@@ -134,7 +134,7 @@ static int regcache_maple_drop(struct regmap *map, unsigned int min,
+
+ lower = kmemdup(entry, ((min - mas.index) *
+ sizeof(unsigned long)),
+- GFP_KERNEL);
++ map->alloc_flags);
+ if (!lower) {
+ ret = -ENOMEM;
+ goto out_unlocked;
+@@ -148,7 +148,7 @@ static int regcache_maple_drop(struct regmap *map, unsigned int min,
+ upper = kmemdup(&entry[max + 1],
+ ((mas.last - max) *
+ sizeof(unsigned long)),
+- GFP_KERNEL);
++ map->alloc_flags);
+ if (!upper) {
+ ret = -ENOMEM;
+ goto out_unlocked;
+@@ -162,7 +162,7 @@ static int regcache_maple_drop(struct regmap *map, unsigned int min,
+ /* Insert new nodes with the saved data */
+ if (lower) {
+ mas_set_range(&mas, lower_index, lower_last);
+- ret = mas_store_gfp(&mas, lower, GFP_KERNEL);
++ ret = mas_store_gfp(&mas, lower, map->alloc_flags);
+ if (ret != 0)
+ goto out;
+ lower = NULL;
+@@ -170,7 +170,7 @@ static int regcache_maple_drop(struct regmap *map, unsigned int min,
+
+ if (upper) {
+ mas_set_range(&mas, upper_index, upper_last);
+- ret = mas_store_gfp(&mas, upper, GFP_KERNEL);
++ ret = mas_store_gfp(&mas, upper, map->alloc_flags);
+ if (ret != 0)
+ goto out;
+ upper = NULL;
+@@ -250,7 +250,7 @@ static int regcache_maple_insert_block(struct regmap *map, int first,
+ unsigned long *entry;
+ int i, ret;
+
+- entry = kcalloc(last - first + 1, sizeof(unsigned long), GFP_KERNEL);
++ entry = kcalloc(last - first + 1, sizeof(unsigned long), map->alloc_flags);
+ if (!entry)
+ return -ENOMEM;
+
+@@ -261,7 +261,7 @@ static int regcache_maple_insert_block(struct regmap *map, int first,
+
+ mas_set_range(&mas, map->reg_defaults[first].reg,
+ map->reg_defaults[last].reg);
+- ret = mas_store_gfp(&mas, entry, GFP_KERNEL);
++ ret = mas_store_gfp(&mas, entry, map->alloc_flags);
+
+ mas_unlock(&mas);
+
+--
+2.40.1
+
--- /dev/null
+From d81afea6817fdd2d186e14e7498f8e706703ed9d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Jul 2023 17:55:33 +0300
+Subject: regmap: rbtree: Use alloc_flags for memory allocations
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 0c8b0bf42c8cef56f7cd9cd876fbb7ece9217064 ]
+
+The kunit tests discovered a sleeping in atomic bug. The allocations
+in the regcache-rbtree code should use the map->alloc_flags instead of
+GFP_KERNEL.
+
+[ 5.005510] BUG: sleeping function called from invalid context at include/linux/sched/mm.h:306
+[ 5.005960] in_atomic(): 1, irqs_disabled(): 128, non_block: 0, pid: 117, name: kunit_try_catch
+[ 5.006219] preempt_count: 1, expected: 0
+[ 5.006414] 1 lock held by kunit_try_catch/117:
+[ 5.006590] #0: 833b9010 (regmap_kunit:86:(config)->lock){....}-{2:2}, at: regmap_lock_spinlock+0x14/0x1c
+[ 5.007493] irq event stamp: 162
+[ 5.007627] hardirqs last enabled at (161): [<80786738>] crng_make_state+0x1a0/0x294
+[ 5.007871] hardirqs last disabled at (162): [<80c531ec>] _raw_spin_lock_irqsave+0x7c/0x80
+[ 5.008119] softirqs last enabled at (0): [<801110ac>] copy_process+0x810/0x2138
+[ 5.008356] softirqs last disabled at (0): [<00000000>] 0x0
+[ 5.008688] CPU: 0 PID: 117 Comm: kunit_try_catch Tainted: G N 6.4.4-rc3-g0e8d2fdfb188 #1
+[ 5.009011] Hardware name: Generic DT based system
+[ 5.009277] unwind_backtrace from show_stack+0x18/0x1c
+[ 5.009497] show_stack from dump_stack_lvl+0x38/0x5c
+[ 5.009676] dump_stack_lvl from __might_resched+0x188/0x2d0
+[ 5.009860] __might_resched from __kmem_cache_alloc_node+0x1dc/0x25c
+[ 5.010061] __kmem_cache_alloc_node from kmalloc_trace+0x30/0xc8
+[ 5.010254] kmalloc_trace from regcache_rbtree_write+0x26c/0x468
+[ 5.010446] regcache_rbtree_write from _regmap_write+0x88/0x140
+[ 5.010634] _regmap_write from regmap_write+0x44/0x68
+[ 5.010803] regmap_write from basic_read_write+0x8c/0x270
+[ 5.010980] basic_read_write from kunit_try_run_case+0x48/0xa0
+
+Fixes: 28644c809f44 ("regmap: Add the rbtree cache support")
+Reported-by: Guenter Roeck <linux@roeck-us.net>
+Closes: https://lore.kernel.org/all/ee59d128-413c-48ad-a3aa-d9d350c80042@roeck-us.net/
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Tested-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://lore.kernel.org/r/58f12a07-5f4b-4a8f-ab84-0a42d1908cb9@moroto.mountain
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/regmap/regcache-rbtree.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c
+index fabf87058d80b..ae6b8788d5f3f 100644
+--- a/drivers/base/regmap/regcache-rbtree.c
++++ b/drivers/base/regmap/regcache-rbtree.c
+@@ -277,7 +277,7 @@ static int regcache_rbtree_insert_to_block(struct regmap *map,
+
+ blk = krealloc(rbnode->block,
+ blklen * map->cache_word_size,
+- GFP_KERNEL);
++ map->alloc_flags);
+ if (!blk)
+ return -ENOMEM;
+
+@@ -286,7 +286,7 @@ static int regcache_rbtree_insert_to_block(struct regmap *map,
+ if (BITS_TO_LONGS(blklen) > BITS_TO_LONGS(rbnode->blklen)) {
+ present = krealloc(rbnode->cache_present,
+ BITS_TO_LONGS(blklen) * sizeof(*present),
+- GFP_KERNEL);
++ map->alloc_flags);
+ if (!present)
+ return -ENOMEM;
+
+@@ -320,7 +320,7 @@ regcache_rbtree_node_alloc(struct regmap *map, unsigned int reg)
+ const struct regmap_range *range;
+ int i;
+
+- rbnode = kzalloc(sizeof(*rbnode), GFP_KERNEL);
++ rbnode = kzalloc(sizeof(*rbnode), map->alloc_flags);
+ if (!rbnode)
+ return NULL;
+
+@@ -346,13 +346,13 @@ regcache_rbtree_node_alloc(struct regmap *map, unsigned int reg)
+ }
+
+ rbnode->block = kmalloc_array(rbnode->blklen, map->cache_word_size,
+- GFP_KERNEL);
++ map->alloc_flags);
+ if (!rbnode->block)
+ goto err_free;
+
+ rbnode->cache_present = kcalloc(BITS_TO_LONGS(rbnode->blklen),
+ sizeof(*rbnode->cache_present),
+- GFP_KERNEL);
++ map->alloc_flags);
+ if (!rbnode->cache_present)
+ goto err_free_block;
+
+--
+2.40.1
+
--- /dev/null
+From f0dd9e4e1f464f6bea7e1e46338298c269b1f099 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 4 Jun 2023 12:16:06 +0100
+Subject: reiserfs: Check the return value from __getblk()
+
+From: Matthew Wilcox <willy@infradead.org>
+
+[ Upstream commit ba38980add7ffc9e674ada5b4ded4e7d14e76581 ]
+
+__getblk() can return a NULL pointer if we run out of memory or if we
+try to access beyond the end of the device; check it and handle it
+appropriately.
+
+Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
+Link: https://lore.kernel.org/lkml/CAFcO6XOacq3hscbXevPQP7sXRoYFz34ZdKPYjmd6k5sZuhGFDw@mail.gmail.com/
+Tested-by: butt3rflyh4ck <butterflyhuangxx@gmail.com>
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") # probably introduced in 2002
+Acked-by: Edward Shishkin <edward.shishkin@gmail.com>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/reiserfs/journal.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
+index 4d11d60f493c1..dd58e0dca5e5a 100644
+--- a/fs/reiserfs/journal.c
++++ b/fs/reiserfs/journal.c
+@@ -2326,7 +2326,7 @@ static struct buffer_head *reiserfs_breada(struct block_device *dev,
+ int i, j;
+
+ bh = __getblk(dev, block, bufsize);
+- if (buffer_uptodate(bh))
++ if (!bh || buffer_uptodate(bh))
+ return (bh);
+
+ if (block + BUFNR > max_block) {
+@@ -2336,6 +2336,8 @@ static struct buffer_head *reiserfs_breada(struct block_device *dev,
+ j = 1;
+ for (i = 1; i < blocks; i++) {
+ bh = __getblk(dev, block + i, bufsize);
++ if (!bh)
++ break;
+ if (buffer_uptodate(bh)) {
+ brelse(bh);
+ break;
+--
+2.40.1
+
--- /dev/null
+From 892b6436bddfe686241908dfc62aab426857b9bf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Jul 2023 19:29:53 +0800
+Subject: Revert "f2fs: fix to do sanity check on extent cache correctly"
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 958ccbbf1ce716d77c7cfa79ace50a421c1eed73 ]
+
+syzbot reports a f2fs bug as below:
+
+UBSAN: array-index-out-of-bounds in fs/f2fs/f2fs.h:3275:19
+index 1409 is out of range for type '__le32[923]' (aka 'unsigned int[923]')
+Call Trace:
+ __dump_stack lib/dump_stack.c:88 [inline]
+ dump_stack_lvl+0x1e7/0x2d0 lib/dump_stack.c:106
+ ubsan_epilogue lib/ubsan.c:217 [inline]
+ __ubsan_handle_out_of_bounds+0x11c/0x150 lib/ubsan.c:348
+ inline_data_addr fs/f2fs/f2fs.h:3275 [inline]
+ __recover_inline_status fs/f2fs/inode.c:113 [inline]
+ do_read_inode fs/f2fs/inode.c:480 [inline]
+ f2fs_iget+0x4730/0x48b0 fs/f2fs/inode.c:604
+ f2fs_fill_super+0x640e/0x80c0 fs/f2fs/super.c:4601
+ mount_bdev+0x276/0x3b0 fs/super.c:1391
+ legacy_get_tree+0xef/0x190 fs/fs_context.c:611
+ vfs_get_tree+0x8c/0x270 fs/super.c:1519
+ do_new_mount+0x28f/0xae0 fs/namespace.c:3335
+ do_mount fs/namespace.c:3675 [inline]
+ __do_sys_mount fs/namespace.c:3884 [inline]
+ __se_sys_mount+0x2d9/0x3c0 fs/namespace.c:3861
+ do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+ do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+The issue was bisected to:
+
+commit d48a7b3a72f121655d95b5157c32c7d555e44c05
+Author: Chao Yu <chao@kernel.org>
+Date: Mon Jan 9 03:49:20 2023 +0000
+
+ f2fs: fix to do sanity check on extent cache correctly
+
+The root cause is we applied both v1 and v2 of the patch, v2 is the right
+fix, so it needs to revert v1 in order to fix reported issue.
+
+v1:
+commit d48a7b3a72f1 ("f2fs: fix to do sanity check on extent cache correctly")
+https://lore.kernel.org/lkml/20230109034920.492914-1-chao@kernel.org/
+
+v2:
+commit 269d11948100 ("f2fs: fix to do sanity check on extent cache correctly")
+https://lore.kernel.org/lkml/20230207134808.1827869-1-chao@kernel.org/
+
+Reported-by: syzbot+601018296973a481f302@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/linux-f2fs-devel/000000000000fcf0690600e4d04d@google.com/
+Fixes: d48a7b3a72f1 ("f2fs: fix to do sanity check on extent cache correctly")
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/inode.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
+index cf4327ad106c0..a99c151e3bdcf 100644
+--- a/fs/f2fs/inode.c
++++ b/fs/f2fs/inode.c
+@@ -396,6 +396,12 @@ static int do_read_inode(struct inode *inode)
+ fi->i_inline_xattr_size = 0;
+ }
+
++ if (!sanity_check_inode(inode, node_page)) {
++ f2fs_put_page(node_page, 1);
++ f2fs_handle_error(sbi, ERROR_CORRUPTED_INODE);
++ return -EFSCORRUPTED;
++ }
++
+ /* check data exist */
+ if (f2fs_has_inline_data(inode) && !f2fs_exist_data(inode))
+ __recover_inline_status(inode, node_page);
+@@ -465,12 +471,6 @@ static int do_read_inode(struct inode *inode)
+ f2fs_init_read_extent_tree(inode, node_page);
+ f2fs_init_age_extent_tree(inode);
+
+- if (!sanity_check_inode(inode, node_page)) {
+- f2fs_put_page(node_page, 1);
+- f2fs_handle_error(sbi, ERROR_CORRUPTED_INODE);
+- return -EFSCORRUPTED;
+- }
+-
+ if (!sanity_check_extent_cache(inode)) {
+ f2fs_put_page(node_page, 1);
+ f2fs_handle_error(sbi, ERROR_CORRUPTED_INODE);
+--
+2.40.1
+
--- /dev/null
+From 55a41d23e22fe979997b022307679773105b9e5d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Aug 2023 10:57:14 +0300
+Subject: Revert "IB/isert: Fix incorrect release of isert connection"
+
+From: Leon Romanovsky <leonro@nvidia.com>
+
+[ Upstream commit dfe261107c080709459c32695847eec96238852b ]
+
+Commit: 699826f4e30a ("IB/isert: Fix incorrect release of isert connection") is
+causing problems on OPA when DEVICE_REMOVAL is happening.
+
+ ------------[ cut here ]------------
+ WARNING: CPU: 52 PID: 2117247 at drivers/infiniband/core/cq.c:359
+ib_cq_pool_cleanup+0xac/0xb0 [ib_core]
+ Modules linked in: nfsd nfs_acl target_core_user uio tcm_fc libfc
+scsi_transport_fc tcm_loop target_core_pscsi target_core_iblock target_core_file
+rpcsec_gss_krb5 auth_rpcgss nfsv4 dns_resolver nfs lockd grace fscache netfs
+rfkill rpcrdma rdma_ucm ib_srpt sunrpc ib_isert iscsi_target_mod target_core_mod
+opa_vnic ib_iser libiscsi ib_umad scsi_transport_iscsi rdma_cm ib_ipoib iw_cm
+ib_cm hfi1(-) rdmavt ib_uverbs intel_rapl_msr intel_rapl_common sb_edac ib_core
+x86_pkg_temp_thermal intel_powerclamp coretemp i2c_i801 mxm_wmi rapl iTCO_wdt
+ipmi_si iTCO_vendor_support mei_me ipmi_devintf mei intel_cstate ioatdma
+intel_uncore i2c_smbus joydev pcspkr lpc_ich ipmi_msghandler acpi_power_meter
+acpi_pad xfs libcrc32c sr_mod sd_mod cdrom t10_pi sg crct10dif_pclmul
+crc32_pclmul crc32c_intel drm_kms_helper drm_shmem_helper ahci libahci
+ghash_clmulni_intel igb drm libata dca i2c_algo_bit wmi fuse
+ CPU: 52 PID: 2117247 Comm: modprobe Not tainted 6.5.0-rc1+ #1
+ Hardware name: Intel Corporation S2600CWR/S2600CW, BIOS
+SE5C610.86B.01.01.0014.121820151719 12/18/2015
+ RIP: 0010:ib_cq_pool_cleanup+0xac/0xb0 [ib_core]
+ Code: ff 48 8b 43 40 48 8d 7b 40 48 83 e8 40 4c 39 e7 75 b3 49 83
+c4 10 4d 39 fc 75 94 5b 5d 41 5c 41 5d 41 5e 41 5f c3 cc cc cc cc <0f> 0b eb a1
+90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 0f 1f
+ RSP: 0018:ffffc10bea13fc80 EFLAGS: 00010206
+ RAX: 000000000000010c RBX: ffff9bf5c7e66c00 RCX: 000000008020001d
+ RDX: 000000008020001e RSI: fffff175221f9900 RDI: ffff9bf5c7e67640
+ RBP: ffff9bf5c7e67600 R08: ffff9bf5c7e64400 R09: 000000008020001d
+ R10: 0000000040000000 R11: 0000000000000000 R12: ffff9bee4b1e8a18
+ R13: dead000000000122 R14: dead000000000100 R15: ffff9bee4b1e8a38
+ FS: 00007ff1e6d38740(0000) GS:ffff9bfd9fb00000(0000) knlGS:0000000000000000
+ CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ CR2: 00005652044ecc68 CR3: 0000000889b5c005 CR4: 00000000001706e0
+ Call Trace:
+ <TASK>
+ ? __warn+0x80/0x130
+ ? ib_cq_pool_cleanup+0xac/0xb0 [ib_core]
+ ? report_bug+0x195/0x1a0
+ ? handle_bug+0x3c/0x70
+ ? exc_invalid_op+0x14/0x70
+ ? asm_exc_invalid_op+0x16/0x20
+ ? ib_cq_pool_cleanup+0xac/0xb0 [ib_core]
+ disable_device+0x9d/0x160 [ib_core]
+ __ib_unregister_device+0x42/0xb0 [ib_core]
+ ib_unregister_device+0x22/0x30 [ib_core]
+ rvt_unregister_device+0x20/0x90 [rdmavt]
+ hfi1_unregister_ib_device+0x16/0xf0 [hfi1]
+ remove_one+0x55/0x1a0 [hfi1]
+ pci_device_remove+0x36/0xa0
+ device_release_driver_internal+0x193/0x200
+ driver_detach+0x44/0x90
+ bus_remove_driver+0x69/0xf0
+ pci_unregister_driver+0x2a/0xb0
+ hfi1_mod_cleanup+0xc/0x3c [hfi1]
+ __do_sys_delete_module.constprop.0+0x17a/0x2f0
+ ? exit_to_user_mode_prepare+0xc4/0xd0
+ ? syscall_trace_enter.constprop.0+0x126/0x1a0
+ do_syscall_64+0x5c/0x90
+ ? syscall_exit_to_user_mode+0x12/0x30
+ ? do_syscall_64+0x69/0x90
+ ? syscall_exit_work+0x103/0x130
+ ? syscall_exit_to_user_mode+0x12/0x30
+ ? do_syscall_64+0x69/0x90
+ ? exc_page_fault+0x65/0x150
+ entry_SYSCALL_64_after_hwframe+0x6e/0xd8
+ RIP: 0033:0x7ff1e643f5ab
+ Code: 73 01 c3 48 8b 0d 75 a8 1b 00 f7 d8 64 89 01 48 83 c8 ff c3
+66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa b8 b0 00 00 00 0f 05 <48> 3d 01 f0
+ff ff 73 01 c3 48 8b 0d 45 a8 1b 00 f7 d8 64 89 01 48
+ RSP: 002b:00007ffec9103cc8 EFLAGS: 00000206 ORIG_RAX: 00000000000000b0
+ RAX: ffffffffffffffda RBX: 00005615267fdc50 RCX: 00007ff1e643f5ab
+ RDX: 0000000000000000 RSI: 0000000000000800 RDI: 00005615267fdcb8
+ RBP: 00005615267fdc50 R08: 0000000000000000 R09: 0000000000000000
+ R10: 00007ff1e659eac0 R11: 0000000000000206 R12: 00005615267fdcb8
+ R13: 0000000000000000 R14: 00005615267fdcb8 R15: 00007ffec9105ff8
+ </TASK>
+ ---[ end trace 0000000000000000 ]---
+
+And...
+
+ restrack: ------------[ cut here ]------------
+ infiniband hfi1_0: BUG: RESTRACK detected leak of resources
+ restrack: Kernel PD object allocated by ib_isert is not freed
+ restrack: Kernel CQ object allocated by ib_core is not freed
+ restrack: Kernel QP object allocated by rdma_cm is not freed
+ restrack: ------------[ cut here ]------------
+
+Fixes: 699826f4e30a ("IB/isert: Fix incorrect release of isert connection")
+Reported-by: Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com>
+Closes: https://lore.kernel.org/all/921cd1d9-2879-f455-1f50-0053fe6a6655@cornelisnetworks.com
+Link: https://lore.kernel.org/r/a27982d3235005c58f6d321f3fad5eb6e1beaf9e.1692604607.git.leonro@nvidia.com
+Tested-by: Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com>
+Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/isert/ib_isert.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c
+index 92e1e7587af8b..00a7303c8cc60 100644
+--- a/drivers/infiniband/ulp/isert/ib_isert.c
++++ b/drivers/infiniband/ulp/isert/ib_isert.c
+@@ -2570,6 +2570,8 @@ static void isert_wait_conn(struct iscsit_conn *conn)
+ isert_put_unsol_pending_cmds(conn);
+ isert_wait4cmds(conn);
+ isert_wait4logout(isert_conn);
++
++ queue_work(isert_release_wq, &isert_conn->release_work);
+ }
+
+ static void isert_free_conn(struct iscsit_conn *conn)
+--
+2.40.1
+
--- /dev/null
+From 7220160a0cb280e0a2f41e293506c0b575af924c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Jun 2023 11:06:31 +0800
+Subject: rpmsg: glink: Add check for kstrdup
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit b5c9ee8296a3760760c7b5d2e305f91412adc795 ]
+
+Add check for the return value of kstrdup() and return the error
+if it fails in order to avoid NULL pointer dereference.
+
+Fixes: b4f8e52b89f6 ("rpmsg: Introduce Qualcomm RPM glink driver")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Link: https://lore.kernel.org/r/20230619030631.12361-1-jiasheng@iscas.ac.cn
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rpmsg/qcom_glink_native.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c
+index 1beb40a1d3df2..e4015db99899d 100644
+--- a/drivers/rpmsg/qcom_glink_native.c
++++ b/drivers/rpmsg/qcom_glink_native.c
+@@ -221,6 +221,10 @@ static struct glink_channel *qcom_glink_alloc_channel(struct qcom_glink *glink,
+
+ channel->glink = glink;
+ channel->name = kstrdup(name, GFP_KERNEL);
++ if (!channel->name) {
++ kfree(channel);
++ return ERR_PTR(-ENOMEM);
++ }
+
+ init_completion(&channel->open_req);
+ init_completion(&channel->open_ack);
+--
+2.40.1
+
--- /dev/null
+From 1778915ce40c7b3336def06ccd515cc760a7864f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Aug 2023 14:23:45 +0200
+Subject: s390/paes: fix PKEY_TYPE_EP11_AES handling for secure keyblobs
+
+From: Holger Dengler <dengler@linux.ibm.com>
+
+[ Upstream commit cba33db3fc4dbf2e54294b0e499d2335a3a00d78 ]
+
+Commit 'fa6999e326fe ("s390/pkey: support CCA and EP11 secure ECC
+private keys")' introduced PKEY_TYPE_EP11_AES securekey blobs as a
+supplement to the PKEY_TYPE_EP11 (which won't work in environments
+with session-bound keys). This new keyblobs has a different maximum
+size, so fix paes crypto module to accept also these larger keyblobs.
+
+Fixes: fa6999e326fe ("s390/pkey: support CCA and EP11 secure ECC private keys")
+Signed-off-by: Holger Dengler <dengler@linux.ibm.com>
+Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com>
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/crypto/paes_s390.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/s390/crypto/paes_s390.c b/arch/s390/crypto/paes_s390.c
+index 29dc827e0fe81..143ae4d4284db 100644
+--- a/arch/s390/crypto/paes_s390.c
++++ b/arch/s390/crypto/paes_s390.c
+@@ -35,7 +35,7 @@
+ * and padding is also possible, the limits need to be generous.
+ */
+ #define PAES_MIN_KEYSIZE 16
+-#define PAES_MAX_KEYSIZE 320
++#define PAES_MAX_KEYSIZE MAXEP11AESKEYBLOBSIZE
+
+ static u8 *ctrblk;
+ static DEFINE_MUTEX(ctrblk_lock);
+--
+2.40.1
+
--- /dev/null
+From 75a0bd64333d581fa31bd1e26c9cf25554ea1472 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Jul 2023 11:33:45 +0200
+Subject: s390/pkey: fix/harmonize internal keyblob headers
+
+From: Holger Dengler <dengler@linux.ibm.com>
+
+[ Upstream commit 37a08f010b7c423b5e4c9ed3b187d21166553007 ]
+
+Commit 'fa6999e326fe ("s390/pkey: support CCA and EP11 secure ECC
+private keys")' introduced PKEY_TYPE_EP11_AES as a supplement to
+PKEY_TYPE_EP11. All pkeys have an internal header/payload structure,
+which is opaque to the userspace. The header structures for
+PKEY_TYPE_EP11 and PKEY_TYPE_EP11_AES are nearly identical and there
+is no reason, why different structures are used. In preparation to fix
+the keyversion handling in the broken PKEY IOCTLs, the same header
+structure is used for PKEY_TYPE_EP11 and PKEY_TYPE_EP11_AES. This
+reduces the number of different code paths and increases the
+readability.
+
+Fixes: fa6999e326fe ("s390/pkey: support CCA and EP11 secure ECC private keys")
+Signed-off-by: Holger Dengler <dengler@linux.ibm.com>
+Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com>
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/s390/crypto/pkey_api.c | 2 +-
+ drivers/s390/crypto/zcrypt_ep11misc.c | 4 ++--
+ drivers/s390/crypto/zcrypt_ep11misc.h | 9 +--------
+ 3 files changed, 4 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/s390/crypto/pkey_api.c b/drivers/s390/crypto/pkey_api.c
+index a8def50c149bd..e650df3fe7ccb 100644
+--- a/drivers/s390/crypto/pkey_api.c
++++ b/drivers/s390/crypto/pkey_api.c
+@@ -747,7 +747,7 @@ static int pkey_verifykey2(const u8 *key, size_t keylen,
+ if (ktype)
+ *ktype = PKEY_TYPE_EP11;
+ if (ksize)
+- *ksize = kb->head.keybitlen;
++ *ksize = kb->head.bitlen;
+
+ rc = ep11_findcard2(&_apqns, &_nr_apqns, *cardnr, *domain,
+ ZCRYPT_CEX7, EP11_API_V, kb->wkvp);
+diff --git a/drivers/s390/crypto/zcrypt_ep11misc.c b/drivers/s390/crypto/zcrypt_ep11misc.c
+index f67d19d08571b..79dc57e720ff1 100644
+--- a/drivers/s390/crypto/zcrypt_ep11misc.c
++++ b/drivers/s390/crypto/zcrypt_ep11misc.c
+@@ -787,7 +787,7 @@ int ep11_genaeskey(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,
+ kb->head.type = TOKTYPE_NON_CCA;
+ kb->head.len = rep_pl->data_len;
+ kb->head.version = TOKVER_EP11_AES;
+- kb->head.keybitlen = keybitsize;
++ kb->head.bitlen = keybitsize;
+
+ out:
+ kfree(req);
+@@ -1055,7 +1055,7 @@ static int ep11_unwrapkey(u16 card, u16 domain,
+ kb->head.type = TOKTYPE_NON_CCA;
+ kb->head.len = rep_pl->data_len;
+ kb->head.version = TOKVER_EP11_AES;
+- kb->head.keybitlen = keybitsize;
++ kb->head.bitlen = keybitsize;
+
+ out:
+ kfree(req);
+diff --git a/drivers/s390/crypto/zcrypt_ep11misc.h b/drivers/s390/crypto/zcrypt_ep11misc.h
+index 07445041869fe..912b3918c10a1 100644
+--- a/drivers/s390/crypto/zcrypt_ep11misc.h
++++ b/drivers/s390/crypto/zcrypt_ep11misc.h
+@@ -29,14 +29,7 @@ struct ep11keyblob {
+ union {
+ u8 session[32];
+ /* only used for PKEY_TYPE_EP11: */
+- struct {
+- u8 type; /* 0x00 (TOKTYPE_NON_CCA) */
+- u8 res0; /* unused */
+- u16 len; /* total length in bytes of this blob */
+- u8 version; /* 0x03 (TOKVER_EP11_AES) */
+- u8 res1; /* unused */
+- u16 keybitlen; /* clear key bit len, 0 for unknown */
+- } head;
++ struct ep11kblob_header head;
+ };
+ u8 wkvp[16]; /* wrapping key verification pattern */
+ u64 attr; /* boolean key attributes */
+--
+2.40.1
+
--- /dev/null
+From 44b5696edde394bf903ace0d7cf35f171e9527a4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Aug 2023 16:02:58 +0200
+Subject: s390/pkey: fix PKEY_TYPE_EP11_AES handling for sysfs attributes
+
+From: Holger Dengler <dengler@linux.ibm.com>
+
+[ Upstream commit b9352e4b9b9eff949bcc6907b8569b3a1d992f1e ]
+
+Commit 'fa6999e326fe ("s390/pkey: support CCA and EP11 secure ECC
+private keys")' introduced a new PKEY_TYPE_EP11_AES securekey type as
+a supplement to the existing PKEY_TYPE_EP11 (which won't work in
+environments with session-bound keys). The pkey EP11 securekey
+attributes use PKEY_TYPE_EP11_AES (instead of PKEY_TYPE_EP11)
+keyblobs, to make the generated keyblobs usable also in environments,
+where session-bound keys are required.
+
+There should be no negative impacts to userspace because the internal
+structure of the keyblobs is opaque. The increased size of the
+generated keyblobs is reflected by the changed size of the attributes.
+
+Fixes: fa6999e326fe ("s390/pkey: support CCA and EP11 secure ECC private keys")
+Signed-off-by: Holger Dengler <dengler@linux.ibm.com>
+Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com>
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/include/uapi/asm/pkey.h | 2 +-
+ drivers/s390/crypto/pkey_api.c | 6 +++---
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/s390/include/uapi/asm/pkey.h b/arch/s390/include/uapi/asm/pkey.h
+index 924b876f992c1..29c6fd369761e 100644
+--- a/arch/s390/include/uapi/asm/pkey.h
++++ b/arch/s390/include/uapi/asm/pkey.h
+@@ -26,7 +26,7 @@
+ #define MAXCLRKEYSIZE 32 /* a clear key value may be up to 32 bytes */
+ #define MAXAESCIPHERKEYSIZE 136 /* our aes cipher keys have always 136 bytes */
+ #define MINEP11AESKEYBLOBSIZE 256 /* min EP11 AES key blob size */
+-#define MAXEP11AESKEYBLOBSIZE 320 /* max EP11 AES key blob size */
++#define MAXEP11AESKEYBLOBSIZE 336 /* max EP11 AES key blob size */
+
+ /* Minimum size of a key blob */
+ #define MINKEYBLOBSIZE SECKEYBLOBSIZE
+diff --git a/drivers/s390/crypto/pkey_api.c b/drivers/s390/crypto/pkey_api.c
+index 79568da580c67..2b92ec20ed68e 100644
+--- a/drivers/s390/crypto/pkey_api.c
++++ b/drivers/s390/crypto/pkey_api.c
+@@ -1947,7 +1947,7 @@ static struct attribute_group ccacipher_attr_group = {
+ * (i.e. off != 0 or count < key blob size) -EINVAL is returned.
+ * This function and the sysfs attributes using it provide EP11 key blobs
+ * padded to the upper limit of MAXEP11AESKEYBLOBSIZE which is currently
+- * 320 bytes.
++ * 336 bytes.
+ */
+ static ssize_t pkey_ep11_aes_attr_read(enum pkey_key_size keybits,
+ bool is_xts, char *buf, loff_t off,
+@@ -1976,7 +1976,7 @@ static ssize_t pkey_ep11_aes_attr_read(enum pkey_key_size keybits,
+ card = apqns[i] >> 16;
+ dom = apqns[i] & 0xFFFF;
+ rc = ep11_genaeskey(card, dom, keybits, 0, buf, &keysize,
+- PKEY_TYPE_EP11);
++ PKEY_TYPE_EP11_AES);
+ if (rc == 0)
+ break;
+ }
+@@ -1987,7 +1987,7 @@ static ssize_t pkey_ep11_aes_attr_read(enum pkey_key_size keybits,
+ keysize = MAXEP11AESKEYBLOBSIZE;
+ buf += MAXEP11AESKEYBLOBSIZE;
+ rc = ep11_genaeskey(card, dom, keybits, 0, buf, &keysize,
+- PKEY_TYPE_EP11);
++ PKEY_TYPE_EP11_AES);
+ if (rc == 0)
+ return 2 * MAXEP11AESKEYBLOBSIZE;
+ }
+--
+2.40.1
+
--- /dev/null
+From 7a932d20b9f311fd1272dd8e7582ed55b38ed6d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Jul 2023 09:49:55 +0200
+Subject: s390/pkey: fix PKEY_TYPE_EP11_AES handling in PKEY_GENSECK2 IOCTL
+
+From: Holger Dengler <dengler@linux.ibm.com>
+
+[ Upstream commit fb249ce7f7bfd8621a38e4ad401ba74b680786d4 ]
+
+Commit 'fa6999e326fe ("s390/pkey: support CCA and EP11 secure ECC
+private keys")' introduced PKEY_TYPE_EP11_AES for the PKEY_GENSECK2
+IOCTL, to enable userspace to generate securekey blobs of this
+type. Unfortunately, all PKEY_GENSECK2 IOCTL requests for
+PKEY_TYPE_EP11_AES return with an error (-EINVAL). Fix the handling
+for PKEY_TYPE_EP11_AES in PKEY_GENSECK2 IOCTL, so that userspace can
+generate securekey blobs of this type.
+
+The start of the header and the keyblob, as well as the length need
+special handling, depending on the internal keyversion. Add a helper
+function that splits an uninitialized buffer into start and size of
+the header as well as start and size of the payload, depending on the
+requested keyversion.
+
+Do the header-related calculations and the raw genkey request handling
+in separate functions. Use the raw genkey request function for
+internal purposes.
+
+Fixes: fa6999e326fe ("s390/pkey: support CCA and EP11 secure ECC private keys")
+Signed-off-by: Holger Dengler <dengler@linux.ibm.com>
+Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com>
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/s390/crypto/pkey_api.c | 18 +++--
+ drivers/s390/crypto/zcrypt_ep11misc.c | 103 ++++++++++++++++++++++----
+ drivers/s390/crypto/zcrypt_ep11misc.h | 2 +-
+ 3 files changed, 102 insertions(+), 21 deletions(-)
+
+diff --git a/drivers/s390/crypto/pkey_api.c b/drivers/s390/crypto/pkey_api.c
+index e650df3fe7ccb..79568da580c67 100644
+--- a/drivers/s390/crypto/pkey_api.c
++++ b/drivers/s390/crypto/pkey_api.c
+@@ -565,6 +565,11 @@ static int pkey_genseckey2(const struct pkey_apqn *apqns, size_t nr_apqns,
+ if (*keybufsize < MINEP11AESKEYBLOBSIZE)
+ return -EINVAL;
+ break;
++ case PKEY_TYPE_EP11_AES:
++ if (*keybufsize < (sizeof(struct ep11kblob_header) +
++ MINEP11AESKEYBLOBSIZE))
++ return -EINVAL;
++ break;
+ default:
+ return -EINVAL;
+ }
+@@ -581,9 +586,10 @@ static int pkey_genseckey2(const struct pkey_apqn *apqns, size_t nr_apqns,
+ for (i = 0, rc = -ENODEV; i < nr_apqns; i++) {
+ card = apqns[i].card;
+ dom = apqns[i].domain;
+- if (ktype == PKEY_TYPE_EP11) {
++ if (ktype == PKEY_TYPE_EP11 ||
++ ktype == PKEY_TYPE_EP11_AES) {
+ rc = ep11_genaeskey(card, dom, ksize, kflags,
+- keybuf, keybufsize);
++ keybuf, keybufsize, ktype);
+ } else if (ktype == PKEY_TYPE_CCA_DATA) {
+ rc = cca_genseckey(card, dom, ksize, keybuf);
+ *keybufsize = (rc ? 0 : SECKEYBLOBSIZE);
+@@ -1313,7 +1319,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
+ apqns = _copy_apqns_from_user(kgs.apqns, kgs.apqn_entries);
+ if (IS_ERR(apqns))
+ return PTR_ERR(apqns);
+- kkey = kmalloc(klen, GFP_KERNEL);
++ kkey = kzalloc(klen, GFP_KERNEL);
+ if (!kkey) {
+ kfree(apqns);
+ return -ENOMEM;
+@@ -1969,7 +1975,8 @@ static ssize_t pkey_ep11_aes_attr_read(enum pkey_key_size keybits,
+ for (i = 0, rc = -ENODEV; i < nr_apqns; i++) {
+ card = apqns[i] >> 16;
+ dom = apqns[i] & 0xFFFF;
+- rc = ep11_genaeskey(card, dom, keybits, 0, buf, &keysize);
++ rc = ep11_genaeskey(card, dom, keybits, 0, buf, &keysize,
++ PKEY_TYPE_EP11);
+ if (rc == 0)
+ break;
+ }
+@@ -1979,7 +1986,8 @@ static ssize_t pkey_ep11_aes_attr_read(enum pkey_key_size keybits,
+ if (is_xts) {
+ keysize = MAXEP11AESKEYBLOBSIZE;
+ buf += MAXEP11AESKEYBLOBSIZE;
+- rc = ep11_genaeskey(card, dom, keybits, 0, buf, &keysize);
++ rc = ep11_genaeskey(card, dom, keybits, 0, buf, &keysize,
++ PKEY_TYPE_EP11);
+ if (rc == 0)
+ return 2 * MAXEP11AESKEYBLOBSIZE;
+ }
+diff --git a/drivers/s390/crypto/zcrypt_ep11misc.c b/drivers/s390/crypto/zcrypt_ep11misc.c
+index 79dc57e720ff1..0cd0395fa17fc 100644
+--- a/drivers/s390/crypto/zcrypt_ep11misc.c
++++ b/drivers/s390/crypto/zcrypt_ep11misc.c
+@@ -113,6 +113,50 @@ static void __exit card_cache_free(void)
+ spin_unlock_bh(&card_list_lock);
+ }
+
++static int ep11_kb_split(const u8 *kb, size_t kblen, u32 kbver,
++ struct ep11kblob_header **kbhdr, size_t *kbhdrsize,
++ u8 **kbpl, size_t *kbplsize)
++{
++ struct ep11kblob_header *hdr = NULL;
++ size_t hdrsize, plsize = 0;
++ int rc = -EINVAL;
++ u8 *pl = NULL;
++
++ if (kblen < sizeof(struct ep11kblob_header))
++ goto out;
++ hdr = (struct ep11kblob_header *)kb;
++
++ switch (kbver) {
++ case TOKVER_EP11_AES:
++ /* header overlays the payload */
++ hdrsize = 0;
++ break;
++ case TOKVER_EP11_ECC_WITH_HEADER:
++ case TOKVER_EP11_AES_WITH_HEADER:
++ /* payload starts after the header */
++ hdrsize = sizeof(struct ep11kblob_header);
++ break;
++ default:
++ goto out;
++ }
++
++ plsize = kblen - hdrsize;
++ pl = (u8 *)kb + hdrsize;
++
++ if (kbhdr)
++ *kbhdr = hdr;
++ if (kbhdrsize)
++ *kbhdrsize = hdrsize;
++ if (kbpl)
++ *kbpl = pl;
++ if (kbplsize)
++ *kbplsize = plsize;
++
++ rc = 0;
++out:
++ return rc;
++}
++
+ /*
+ * Simple check if the key blob is a valid EP11 AES key blob with header.
+ */
+@@ -664,8 +708,9 @@ EXPORT_SYMBOL(ep11_get_domain_info);
+ */
+ #define KEY_ATTR_DEFAULTS 0x00200c00
+
+-int ep11_genaeskey(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,
+- u8 *keybuf, size_t *keybufsize)
++static int _ep11_genaeskey(u16 card, u16 domain,
++ u32 keybitsize, u32 keygenflags,
++ u8 *keybuf, size_t *keybufsize)
+ {
+ struct keygen_req_pl {
+ struct pl_head head;
+@@ -701,7 +746,6 @@ int ep11_genaeskey(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,
+ struct ep11_cprb *req = NULL, *rep = NULL;
+ struct ep11_target_dev target;
+ struct ep11_urb *urb = NULL;
+- struct ep11keyblob *kb;
+ int api, rc = -ENOMEM;
+
+ switch (keybitsize) {
+@@ -780,14 +824,9 @@ int ep11_genaeskey(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,
+ goto out;
+ }
+
+- /* copy key blob and set header values */
++ /* copy key blob */
+ memcpy(keybuf, rep_pl->data, rep_pl->data_len);
+ *keybufsize = rep_pl->data_len;
+- kb = (struct ep11keyblob *)keybuf;
+- kb->head.type = TOKTYPE_NON_CCA;
+- kb->head.len = rep_pl->data_len;
+- kb->head.version = TOKVER_EP11_AES;
+- kb->head.bitlen = keybitsize;
+
+ out:
+ kfree(req);
+@@ -795,6 +834,43 @@ int ep11_genaeskey(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,
+ kfree(urb);
+ return rc;
+ }
++
++int ep11_genaeskey(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,
++ u8 *keybuf, size_t *keybufsize, u32 keybufver)
++{
++ struct ep11kblob_header *hdr;
++ size_t hdr_size, pl_size;
++ u8 *pl;
++ int rc;
++
++ switch (keybufver) {
++ case TOKVER_EP11_AES:
++ case TOKVER_EP11_AES_WITH_HEADER:
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ rc = ep11_kb_split(keybuf, *keybufsize, keybufver,
++ &hdr, &hdr_size, &pl, &pl_size);
++ if (rc)
++ return rc;
++
++ rc = _ep11_genaeskey(card, domain, keybitsize, keygenflags,
++ pl, &pl_size);
++ if (rc)
++ return rc;
++
++ *keybufsize = hdr_size + pl_size;
++
++ /* update header information */
++ hdr->type = TOKTYPE_NON_CCA;
++ hdr->len = *keybufsize;
++ hdr->version = keybufver;
++ hdr->bitlen = keybitsize;
++
++ return 0;
++}
+ EXPORT_SYMBOL(ep11_genaeskey);
+
+ static int ep11_cryptsingle(u16 card, u16 domain,
+@@ -1201,7 +1277,6 @@ int ep11_clr2keyblob(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,
+ const u8 *clrkey, u8 *keybuf, size_t *keybufsize)
+ {
+ int rc;
+- struct ep11keyblob *kb;
+ u8 encbuf[64], *kek = NULL;
+ size_t clrkeylen, keklen, encbuflen = sizeof(encbuf);
+
+@@ -1223,17 +1298,15 @@ int ep11_clr2keyblob(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,
+ }
+
+ /* Step 1: generate AES 256 bit random kek key */
+- rc = ep11_genaeskey(card, domain, 256,
+- 0x00006c00, /* EN/DECRYPT, WRAP/UNWRAP */
+- kek, &keklen);
++ rc = _ep11_genaeskey(card, domain, 256,
++ 0x00006c00, /* EN/DECRYPT, WRAP/UNWRAP */
++ kek, &keklen);
+ if (rc) {
+ DEBUG_ERR(
+ "%s generate kek key failed, rc=%d\n",
+ __func__, rc);
+ goto out;
+ }
+- kb = (struct ep11keyblob *)kek;
+- memset(&kb->head, 0, sizeof(kb->head));
+
+ /* Step 2: encrypt clear key value with the kek key */
+ rc = ep11_cryptsingle(card, domain, 0, 0, def_iv, kek, keklen,
+diff --git a/drivers/s390/crypto/zcrypt_ep11misc.h b/drivers/s390/crypto/zcrypt_ep11misc.h
+index 912b3918c10a1..ed328c354bade 100644
+--- a/drivers/s390/crypto/zcrypt_ep11misc.h
++++ b/drivers/s390/crypto/zcrypt_ep11misc.h
+@@ -107,7 +107,7 @@ int ep11_get_domain_info(u16 card, u16 domain, struct ep11_domain_info *info);
+ * Generate (random) EP11 AES secure key.
+ */
+ int ep11_genaeskey(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,
+- u8 *keybuf, size_t *keybufsize);
++ u8 *keybuf, size_t *keybufsize, u32 keybufver);
+
+ /*
+ * Generate EP11 AES secure key with given clear key value.
+--
+2.40.1
+
--- /dev/null
+From 0392408811fd53ee22cdbc33137addb5c5a43595 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Aug 2023 18:01:16 +0900
+Subject: samples/bpf: fix bio latency check with tracepoint
+
+From: Daniel T. Lee <danieltimlee@gmail.com>
+
+[ Upstream commit 92632115fb57ff9e368f256913e96d6fd5abf5ab ]
+
+Recently, a new tracepoint for the block layer, specifically the
+block_io_start/done tracepoints, was introduced in commit 5a80bd075f3b
+("block: introduce block_io_start/block_io_done tracepoints").
+
+Previously, the kprobe entry used for this purpose was quite unstable
+and inherently broke relevant probes [1]. Now that a stable tracepoint
+is available, this commit replaces the bio latency check with it.
+
+One of the changes made during this replacement is the key used for the
+hash table. Since 'struct request' cannot be used as a hash key, the
+approach taken follows that which was implemented in bcc/biolatency [2].
+(uses dev:sector for the key)
+
+[1]: https://github.com/iovisor/bcc/issues/4261
+[2]: https://github.com/iovisor/bcc/pull/4691
+
+Fixes: 450b7879e345 ("block: move blk_account_io_{start,done} to blk-mq.c")
+Signed-off-by: Daniel T. Lee <danieltimlee@gmail.com>
+Link: https://lore.kernel.org/r/20230818090119.477441-7-danieltimlee@gmail.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ samples/bpf/tracex3_kern.c | 36 ++++++++++++++++++++++++------------
+ 1 file changed, 24 insertions(+), 12 deletions(-)
+
+diff --git a/samples/bpf/tracex3_kern.c b/samples/bpf/tracex3_kern.c
+index bde6591cb20c5..af235bd6615b1 100644
+--- a/samples/bpf/tracex3_kern.c
++++ b/samples/bpf/tracex3_kern.c
+@@ -11,6 +11,12 @@
+ #include <bpf/bpf_helpers.h>
+ #include <bpf/bpf_tracing.h>
+
++struct start_key {
++ dev_t dev;
++ u32 _pad;
++ sector_t sector;
++};
++
+ struct {
+ __uint(type, BPF_MAP_TYPE_HASH);
+ __type(key, long);
+@@ -18,16 +24,17 @@ struct {
+ __uint(max_entries, 4096);
+ } my_map SEC(".maps");
+
+-/* kprobe is NOT a stable ABI. If kernel internals change this bpf+kprobe
+- * example will no longer be meaningful
+- */
+-SEC("kprobe/blk_mq_start_request")
+-int bpf_prog1(struct pt_regs *ctx)
++/* from /sys/kernel/tracing/events/block/block_io_start/format */
++SEC("tracepoint/block/block_io_start")
++int bpf_prog1(struct trace_event_raw_block_rq *ctx)
+ {
+- long rq = PT_REGS_PARM1(ctx);
+ u64 val = bpf_ktime_get_ns();
++ struct start_key key = {
++ .dev = ctx->dev,
++ .sector = ctx->sector
++ };
+
+- bpf_map_update_elem(&my_map, &rq, &val, BPF_ANY);
++ bpf_map_update_elem(&my_map, &key, &val, BPF_ANY);
+ return 0;
+ }
+
+@@ -49,21 +56,26 @@ struct {
+ __uint(max_entries, SLOTS);
+ } lat_map SEC(".maps");
+
+-SEC("kprobe/__blk_account_io_done")
+-int bpf_prog2(struct pt_regs *ctx)
++/* from /sys/kernel/tracing/events/block/block_io_done/format */
++SEC("tracepoint/block/block_io_done")
++int bpf_prog2(struct trace_event_raw_block_rq *ctx)
+ {
+- long rq = PT_REGS_PARM1(ctx);
++ struct start_key key = {
++ .dev = ctx->dev,
++ .sector = ctx->sector
++ };
++
+ u64 *value, l, base;
+ u32 index;
+
+- value = bpf_map_lookup_elem(&my_map, &rq);
++ value = bpf_map_lookup_elem(&my_map, &key);
+ if (!value)
+ return 0;
+
+ u64 cur_time = bpf_ktime_get_ns();
+ u64 delta = cur_time - *value;
+
+- bpf_map_delete_elem(&my_map, &rq);
++ bpf_map_delete_elem(&my_map, &key);
+
+ /* the lines below are computing index = log10(delta)*10
+ * using integer arithmetic
+--
+2.40.1
+
--- /dev/null
+From b45ea0b543a917439f4b70d0c6f0e1341f866931 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Aug 2023 18:01:17 +0900
+Subject: samples/bpf: fix broken map lookup probe
+
+From: Daniel T. Lee <danieltimlee@gmail.com>
+
+[ Upstream commit d93a7cf6ca2cfcd7de5d06f753ce8d5e863316ac ]
+
+In the commit 7c4cd051add3 ("bpf: Fix syscall's stackmap lookup
+potential deadlock"), a potential deadlock issue was addressed, which
+resulted in *_map_lookup_elem not triggering BPF programs.
+(prior to lookup, bpf_disable_instrumentation() is used)
+
+To resolve the broken map lookup probe using "htab_map_lookup_elem",
+this commit introduces an alternative approach. Instead, it utilize
+"bpf_map_copy_value" and apply a filter specifically for the hash table
+with map_type.
+
+Signed-off-by: Daniel T. Lee <danieltimlee@gmail.com>
+Fixes: 7c4cd051add3 ("bpf: Fix syscall's stackmap lookup potential deadlock")
+Link: https://lore.kernel.org/r/20230818090119.477441-8-danieltimlee@gmail.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ samples/bpf/tracex6_kern.c | 17 +++++++++++++++--
+ 1 file changed, 15 insertions(+), 2 deletions(-)
+
+diff --git a/samples/bpf/tracex6_kern.c b/samples/bpf/tracex6_kern.c
+index acad5712d8b4f..fd602c2774b8b 100644
+--- a/samples/bpf/tracex6_kern.c
++++ b/samples/bpf/tracex6_kern.c
+@@ -2,6 +2,8 @@
+ #include <linux/version.h>
+ #include <uapi/linux/bpf.h>
+ #include <bpf/bpf_helpers.h>
++#include <bpf/bpf_tracing.h>
++#include <bpf/bpf_core_read.h>
+
+ struct {
+ __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
+@@ -45,13 +47,24 @@ int bpf_prog1(struct pt_regs *ctx)
+ return 0;
+ }
+
+-SEC("kprobe/htab_map_lookup_elem")
+-int bpf_prog2(struct pt_regs *ctx)
++/*
++ * Since *_map_lookup_elem can't be expected to trigger bpf programs
++ * due to potential deadlocks (bpf_disable_instrumentation), this bpf
++ * program will be attached to bpf_map_copy_value (which is called
++ * from map_lookup_elem) and will only filter the hashtable type.
++ */
++SEC("kprobe/bpf_map_copy_value")
++int BPF_KPROBE(bpf_prog2, struct bpf_map *map)
+ {
+ u32 key = bpf_get_smp_processor_id();
+ struct bpf_perf_event_value *val, buf;
++ enum bpf_map_type type;
+ int error;
+
++ type = BPF_CORE_READ(map, map_type);
++ if (type != BPF_MAP_TYPE_HASH)
++ return 0;
++
+ error = bpf_perf_event_read_value(&counters, key, &buf, sizeof(buf));
+ if (error)
+ return 0;
+--
+2.40.1
+
--- /dev/null
+From 6aaf3ffe975bb7f4c44f5283975c8229b598fce8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 30 Jul 2023 20:07:40 -0700
+Subject: sched/psi: Select KERNFS as needed
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit 98dfdd9ee93995a408192dbbf3dd219ba23e3738 ]
+
+Users of KERNFS should select it to enforce its being built, so
+do this to prevent a build error.
+
+In file included from ../kernel/sched/build_utility.c:97:
+../kernel/sched/psi.c: In function 'psi_trigger_poll':
+../kernel/sched/psi.c:1479:17: error: implicit declaration of function 'kernfs_generic_poll' [-Werror=implicit-function-declaration]
+ 1479 | kernfs_generic_poll(t->of, wait);
+
+Fixes: aff037078eca ("sched/psi: use kernfs polling functions for PSI trigger polling")
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Acked-by: Suren Baghdasaryan <surenb@google.com>
+Link: lore.kernel.org/r/202307310732.r65EQFY0-lkp@intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ init/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/init/Kconfig b/init/Kconfig
+index 32c24950c4ced..c70617066a4c8 100644
+--- a/init/Kconfig
++++ b/init/Kconfig
+@@ -629,6 +629,7 @@ config TASK_IO_ACCOUNTING
+
+ config PSI
+ bool "Pressure stall information tracking"
++ select KERNFS
+ help
+ Collect metrics that indicate how overcommitted the CPU, memory,
+ and IO capacity are in the system.
+--
+2.40.1
+
--- /dev/null
+From 70330a5708a2358db31df49cbad56c01d70f2f56 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Aug 2023 17:19:05 +0200
+Subject: sched/rt: Fix sysctl_sched_rr_timeslice intial value
+
+From: Cyril Hrubis <chrubis@suse.cz>
+
+[ Upstream commit c7fcb99877f9f542c918509b2801065adcaf46fa ]
+
+There is a 10% rounding error in the intial value of the
+sysctl_sched_rr_timeslice with CONFIG_HZ_300=y.
+
+This was found with LTP test sched_rr_get_interval01:
+
+sched_rr_get_interval01.c:57: TPASS: sched_rr_get_interval() passed
+sched_rr_get_interval01.c:64: TPASS: Time quantum 0s 99999990ns
+sched_rr_get_interval01.c:72: TFAIL: /proc/sys/kernel/sched_rr_timeslice_ms != 100 got 90
+sched_rr_get_interval01.c:57: TPASS: sched_rr_get_interval() passed
+sched_rr_get_interval01.c:64: TPASS: Time quantum 0s 99999990ns
+sched_rr_get_interval01.c:72: TFAIL: /proc/sys/kernel/sched_rr_timeslice_ms != 100 got 90
+
+What this test does is to compare the return value from the
+sched_rr_get_interval() and the sched_rr_timeslice_ms sysctl file and
+fails if they do not match.
+
+The problem it found is the intial sysctl file value which was computed as:
+
+static int sysctl_sched_rr_timeslice = (MSEC_PER_SEC / HZ) * RR_TIMESLICE;
+
+which works fine as long as MSEC_PER_SEC is multiple of HZ, however it
+introduces 10% rounding error for CONFIG_HZ_300:
+
+(MSEC_PER_SEC / HZ) * (100 * HZ / 1000)
+
+(1000 / 300) * (100 * 300 / 1000)
+
+3 * 30 = 90
+
+This can be easily fixed by reversing the order of the multiplication
+and division. After this fix we get:
+
+(MSEC_PER_SEC * (100 * HZ / 1000)) / HZ
+
+(1000 * (100 * 300 / 1000)) / 300
+
+(1000 * 30) / 300 = 100
+
+Fixes: 975e155ed873 ("sched/rt: Show the 'sched_rr_timeslice' SCHED_RR timeslice tuning knob in milliseconds")
+Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Petr Vorel <pvorel@suse.cz>
+Acked-by: Mel Gorman <mgorman@suse.de>
+Tested-by: Petr Vorel <pvorel@suse.cz>
+Link: https://lore.kernel.org/r/20230802151906.25258-2-chrubis@suse.cz
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/rt.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
+index 00e0e50741153..185d3d749f6b6 100644
+--- a/kernel/sched/rt.c
++++ b/kernel/sched/rt.c
+@@ -25,7 +25,7 @@ unsigned int sysctl_sched_rt_period = 1000000;
+ int sysctl_sched_rt_runtime = 950000;
+
+ #ifdef CONFIG_SYSCTL
+-static int sysctl_sched_rr_timeslice = (MSEC_PER_SEC / HZ) * RR_TIMESLICE;
++static int sysctl_sched_rr_timeslice = (MSEC_PER_SEC * RR_TIMESLICE) / HZ;
+ static int sched_rt_handler(struct ctl_table *table, int write, void *buffer,
+ size_t *lenp, loff_t *ppos);
+ static int sched_rr_handler(struct ctl_table *table, int write, void *buffer,
+--
+2.40.1
+
--- /dev/null
+From fb6225a13d561a17d9b6059671456ae64aff8221 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Jul 2023 17:28:46 +0800
+Subject: scripts/gdb: fix 'lx-lsmod' show the wrong size
+
+From: Kuan-Ying Lee <Kuan-Ying.Lee@mediatek.com>
+
+[ Upstream commit fb40b0537342e1acd5c2daf2ff6780c1d0d2883c ]
+
+'lsmod' shows total core layout size, so we need to sum up all the
+sections in core layout in gdb scripts.
+
+/ # lsmod
+kasan_test 200704 0 - Live 0xffff80007f640000
+
+Before patch:
+(gdb) lx-lsmod
+Address Module Size Used by
+0xffff80007f640000 kasan_test 36864 0
+
+After patch:
+(gdb) lx-lsmod
+Address Module Size Used by
+0xffff80007f640000 kasan_test 200704 0
+
+Link: https://lkml.kernel.org/r/20230710092852.31049-1-Kuan-Ying.Lee@mediatek.com
+Fixes: b4aff7513df3 ("scripts/gdb: use mem instead of core_layout to get the module address")
+Signed-off-by: Kuan-Ying Lee <Kuan-Ying.Lee@mediatek.com>
+Reviewed-by: Pankaj Raghav <p.raghav@samsung.com>
+Cc: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Cc: Chinwen Chang <chinwen.chang@mediatek.com>
+Cc: Jan Kiszka <jan.kiszka@siemens.com>
+Cc: Kieran Bingham <kbingham@kernel.org>
+Cc: Luis Chamberlain <mcgrof@kernel.org>
+Cc: Matthias Brugger <matthias.bgg@gmail.com>
+Cc: Qun-Wei Lin <qun-wei.lin@mediatek.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/gdb/linux/constants.py.in | 3 +++
+ scripts/gdb/linux/modules.py | 12 +++++++++---
+ 2 files changed, 12 insertions(+), 3 deletions(-)
+
+diff --git a/scripts/gdb/linux/constants.py.in b/scripts/gdb/linux/constants.py.in
+index 50a92c4e9984e..fab74ca9df6fc 100644
+--- a/scripts/gdb/linux/constants.py.in
++++ b/scripts/gdb/linux/constants.py.in
+@@ -64,6 +64,9 @@ LX_GDBPARSED(IRQ_HIDDEN)
+
+ /* linux/module.h */
+ LX_GDBPARSED(MOD_TEXT)
++LX_GDBPARSED(MOD_DATA)
++LX_GDBPARSED(MOD_RODATA)
++LX_GDBPARSED(MOD_RO_AFTER_INIT)
+
+ /* linux/mount.h */
+ LX_VALUE(MNT_NOSUID)
+diff --git a/scripts/gdb/linux/modules.py b/scripts/gdb/linux/modules.py
+index 261f28640f4cd..f76a43bfa15fc 100644
+--- a/scripts/gdb/linux/modules.py
++++ b/scripts/gdb/linux/modules.py
+@@ -73,11 +73,17 @@ class LxLsmod(gdb.Command):
+ " " if utils.get_long_type().sizeof == 8 else ""))
+
+ for module in module_list():
+- layout = module['mem'][constants.LX_MOD_TEXT]
++ text = module['mem'][constants.LX_MOD_TEXT]
++ text_addr = str(text['base']).split()[0]
++ total_size = 0
++
++ for i in range(constants.LX_MOD_TEXT, constants.LX_MOD_RO_AFTER_INIT + 1):
++ total_size += module['mem'][i]['size']
++
+ gdb.write("{address} {name:<19} {size:>8} {ref}".format(
+- address=str(layout['base']).split()[0],
++ address=text_addr,
+ name=module['name'].string(),
+- size=str(layout['size']),
++ size=str(total_size),
+ ref=str(module['refcnt']['counter'] - 1)))
+
+ t = self._module_use_type.get_type().pointer()
+--
+2.40.1
+
--- /dev/null
+From 73c8c240fd14161addc6688db15feffb3aaaedf1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 23 Jul 2023 15:59:38 +0800
+Subject: scsi: be2iscsi: Add length check when parsing nlattrs
+
+From: Lin Ma <linma@zju.edu.cn>
+
+[ Upstream commit ee0268f230f66cb472df3424f380ea668da2749a ]
+
+beiscsi_iface_set_param() parses nlattr with nla_for_each_attr and assumes
+every attributes can be viewed as struct iscsi_iface_param_info.
+
+This is not true because there is no any nla_policy to validate the
+attributes passed from the upper function iscsi_set_iface_params().
+
+Add the nla_len check before accessing the nlattr data and return EINVAL if
+the length check fails.
+
+Fixes: 0e43895ec1f4 ("[SCSI] be2iscsi: adding functionality to change network settings using iscsiadm")
+Signed-off-by: Lin Ma <linma@zju.edu.cn>
+Link: https://lore.kernel.org/r/20230723075938.3713864-1-linma@zju.edu.cn
+Reviewed-by: Chris Leech <cleech@redhat.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/be2iscsi/be_iscsi.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c
+index 8aeaddc93b167..8d374ae863ba2 100644
+--- a/drivers/scsi/be2iscsi/be_iscsi.c
++++ b/drivers/scsi/be2iscsi/be_iscsi.c
+@@ -450,6 +450,10 @@ int beiscsi_iface_set_param(struct Scsi_Host *shost,
+ }
+
+ nla_for_each_attr(attrib, data, dt_len, rm_len) {
++ /* ignore nla_type as it is never used */
++ if (nla_len(attrib) < sizeof(*iface_param))
++ return -EINVAL;
++
+ iface_param = nla_data(attrib);
+
+ if (iface_param->param_type != ISCSI_NET_PARAM)
+--
+2.40.1
+
--- /dev/null
+From 18218e7cbd268d774ba7b6416cf45a92f5181317 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Aug 2023 10:03:25 -0400
+Subject: scsi: core: Use 32-bit hostnum in scsi_host_lookup()
+
+From: Tony Battersby <tonyb@cybernetics.com>
+
+[ Upstream commit 62ec2092095b678ff89ce4ba51c2938cd1e8e630 ]
+
+Change scsi_host_lookup() hostnum argument type from unsigned short to
+unsigned int to match the type used everywhere else.
+
+Fixes: 6d49f63b415c ("[SCSI] Make host_no an unsigned int")
+Signed-off-by: Tony Battersby <tonyb@cybernetics.com>
+Link: https://lore.kernel.org/r/a02497e7-c12b-ef15-47fc-3f0a0b00ffce@cybernetics.com
+Reviewed-by: Bart Van Assche <bvanassche@acm.org>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/hosts.c | 4 ++--
+ include/scsi/scsi_host.h | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
+index f0bc8bbb39381..13ee3453e56a1 100644
+--- a/drivers/scsi/hosts.c
++++ b/drivers/scsi/hosts.c
+@@ -536,7 +536,7 @@ EXPORT_SYMBOL(scsi_host_alloc);
+ static int __scsi_host_match(struct device *dev, const void *data)
+ {
+ struct Scsi_Host *p;
+- const unsigned short *hostnum = data;
++ const unsigned int *hostnum = data;
+
+ p = class_to_shost(dev);
+ return p->host_no == *hostnum;
+@@ -553,7 +553,7 @@ static int __scsi_host_match(struct device *dev, const void *data)
+ * that scsi_host_get() took. The put_device() below dropped
+ * the reference from class_find_device().
+ **/
+-struct Scsi_Host *scsi_host_lookup(unsigned short hostnum)
++struct Scsi_Host *scsi_host_lookup(unsigned int hostnum)
+ {
+ struct device *cdev;
+ struct Scsi_Host *shost = NULL;
+diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
+index 0f29799efa021..6b90b476a03cb 100644
+--- a/include/scsi/scsi_host.h
++++ b/include/scsi/scsi_host.h
+@@ -763,7 +763,7 @@ extern void scsi_remove_host(struct Scsi_Host *);
+ extern struct Scsi_Host *scsi_host_get(struct Scsi_Host *);
+ extern int scsi_host_busy(struct Scsi_Host *shost);
+ extern void scsi_host_put(struct Scsi_Host *t);
+-extern struct Scsi_Host *scsi_host_lookup(unsigned short);
++extern struct Scsi_Host *scsi_host_lookup(unsigned int hostnum);
+ extern const char *scsi_host_state_name(enum scsi_host_state);
+ extern void scsi_host_complete_all_commands(struct Scsi_Host *shost,
+ enum scsi_host_status status);
+--
+2.40.1
+
--- /dev/null
+From 5fe0d36a8343a75bdf1699ea6b4de673b301271f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Aug 2023 07:47:08 +0000
+Subject: scsi: fcoe: Fix potential deadlock on &fip->ctlr_lock
+
+From: Chengfeng Ye <dg573847474@gmail.com>
+
+[ Upstream commit 1a1975551943f681772720f639ff42fbaa746212 ]
+
+There is a long call chain that &fip->ctlr_lock is acquired by isr
+fnic_isr_msix_wq_copy() under hard IRQ context. Thus other process context
+code acquiring the lock should disable IRQ, otherwise deadlock could happen
+if the IRQ preempts the execution while the lock is held in process context
+on the same CPU.
+
+[ISR]
+fnic_isr_msix_wq_copy()
+ -> fnic_wq_copy_cmpl_handler()
+ -> fnic_fcpio_cmpl_handler()
+ -> fnic_fcpio_flogi_reg_cmpl_handler()
+ -> fnic_flush_tx()
+ -> fnic_send_frame()
+ -> fcoe_ctlr_els_send()
+ -> spin_lock_bh(&fip->ctlr_lock)
+
+[Process Context]
+1. fcoe_ctlr_timer_work()
+ -> fcoe_ctlr_flogi_send()
+ -> spin_lock_bh(&fip->ctlr_lock)
+
+2. fcoe_ctlr_recv_work()
+ -> fcoe_ctlr_recv_handler()
+ -> fcoe_ctlr_recv_els()
+ -> fcoe_ctlr_announce()
+ -> spin_lock_bh(&fip->ctlr_lock)
+
+3. fcoe_ctlr_recv_work()
+ -> fcoe_ctlr_recv_handler()
+ -> fcoe_ctlr_recv_els()
+ -> fcoe_ctlr_flogi_retry()
+ -> spin_lock_bh(&fip->ctlr_lock)
+
+4. -> fcoe_xmit()
+ -> fcoe_ctlr_els_send()
+ -> spin_lock_bh(&fip->ctlr_lock)
+
+spin_lock_bh() is not enough since fnic_isr_msix_wq_copy() is a
+hardirq.
+
+These flaws were found by an experimental static analysis tool I am
+developing for irq-related deadlock.
+
+The patch fix the potential deadlocks by spin_lock_irqsave() to disable
+hard irq.
+
+Fixes: 794d98e77f59 ("[SCSI] libfcoe: retry rejected FLOGI to another FCF if possible")
+Signed-off-by: Chengfeng Ye <dg573847474@gmail.com>
+Link: https://lore.kernel.org/r/20230817074708.7509-1-dg573847474@gmail.com
+Reviewed-by: Davidlohr Bueso <dave@stgolabs.net>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/fcoe/fcoe_ctlr.c | 20 ++++++++++++--------
+ 1 file changed, 12 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c
+index 5c8d1ba3f8f3c..19eee108db021 100644
+--- a/drivers/scsi/fcoe/fcoe_ctlr.c
++++ b/drivers/scsi/fcoe/fcoe_ctlr.c
+@@ -319,16 +319,17 @@ static void fcoe_ctlr_announce(struct fcoe_ctlr *fip)
+ {
+ struct fcoe_fcf *sel;
+ struct fcoe_fcf *fcf;
++ unsigned long flags;
+
+ mutex_lock(&fip->ctlr_mutex);
+- spin_lock_bh(&fip->ctlr_lock);
++ spin_lock_irqsave(&fip->ctlr_lock, flags);
+
+ kfree_skb(fip->flogi_req);
+ fip->flogi_req = NULL;
+ list_for_each_entry(fcf, &fip->fcfs, list)
+ fcf->flogi_sent = 0;
+
+- spin_unlock_bh(&fip->ctlr_lock);
++ spin_unlock_irqrestore(&fip->ctlr_lock, flags);
+ sel = fip->sel_fcf;
+
+ if (sel && ether_addr_equal(sel->fcf_mac, fip->dest_addr))
+@@ -699,6 +700,7 @@ int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct fc_lport *lport,
+ {
+ struct fc_frame *fp;
+ struct fc_frame_header *fh;
++ unsigned long flags;
+ u16 old_xid;
+ u8 op;
+ u8 mac[ETH_ALEN];
+@@ -732,11 +734,11 @@ int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct fc_lport *lport,
+ op = FIP_DT_FLOGI;
+ if (fip->mode == FIP_MODE_VN2VN)
+ break;
+- spin_lock_bh(&fip->ctlr_lock);
++ spin_lock_irqsave(&fip->ctlr_lock, flags);
+ kfree_skb(fip->flogi_req);
+ fip->flogi_req = skb;
+ fip->flogi_req_send = 1;
+- spin_unlock_bh(&fip->ctlr_lock);
++ spin_unlock_irqrestore(&fip->ctlr_lock, flags);
+ schedule_work(&fip->timer_work);
+ return -EINPROGRESS;
+ case ELS_FDISC:
+@@ -1705,10 +1707,11 @@ static int fcoe_ctlr_flogi_send_locked(struct fcoe_ctlr *fip)
+ static int fcoe_ctlr_flogi_retry(struct fcoe_ctlr *fip)
+ {
+ struct fcoe_fcf *fcf;
++ unsigned long flags;
+ int error;
+
+ mutex_lock(&fip->ctlr_mutex);
+- spin_lock_bh(&fip->ctlr_lock);
++ spin_lock_irqsave(&fip->ctlr_lock, flags);
+ LIBFCOE_FIP_DBG(fip, "re-sending FLOGI - reselect\n");
+ fcf = fcoe_ctlr_select(fip);
+ if (!fcf || fcf->flogi_sent) {
+@@ -1719,7 +1722,7 @@ static int fcoe_ctlr_flogi_retry(struct fcoe_ctlr *fip)
+ fcoe_ctlr_solicit(fip, NULL);
+ error = fcoe_ctlr_flogi_send_locked(fip);
+ }
+- spin_unlock_bh(&fip->ctlr_lock);
++ spin_unlock_irqrestore(&fip->ctlr_lock, flags);
+ mutex_unlock(&fip->ctlr_mutex);
+ return error;
+ }
+@@ -1736,8 +1739,9 @@ static int fcoe_ctlr_flogi_retry(struct fcoe_ctlr *fip)
+ static void fcoe_ctlr_flogi_send(struct fcoe_ctlr *fip)
+ {
+ struct fcoe_fcf *fcf;
++ unsigned long flags;
+
+- spin_lock_bh(&fip->ctlr_lock);
++ spin_lock_irqsave(&fip->ctlr_lock, flags);
+ fcf = fip->sel_fcf;
+ if (!fcf || !fip->flogi_req_send)
+ goto unlock;
+@@ -1764,7 +1768,7 @@ static void fcoe_ctlr_flogi_send(struct fcoe_ctlr *fip)
+ } else /* XXX */
+ LIBFCOE_FIP_DBG(fip, "No FCF selected - defer send\n");
+ unlock:
+- spin_unlock_bh(&fip->ctlr_lock);
++ spin_unlock_irqrestore(&fip->ctlr_lock, flags);
+ }
+
+ /**
+--
+2.40.1
+
--- /dev/null
+From fab36f33a6c16fb48d686e0b1f75103b76820586 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Jul 2023 11:14:58 +0800
+Subject: scsi: hisi_sas: Fix normally completed I/O analysed as failed
+
+From: Xingui Yang <yangxingui@huawei.com>
+
+[ Upstream commit f5393a5602cacfda2014e0ff8220e5a7564e7cd1 ]
+
+The PIO read command has no response frame and the struct iu[1024] won't be
+filled. I/Os which are normally completed will be treated as failed in
+sas_ata_task_done() when iu contains abnormal dirty data.
+
+Consequently ending_fis should not be filled by iu when the response frame
+hasn't been written to memory.
+
+Fixes: d380f55503ed ("scsi: hisi_sas: Don't bother clearing status buffer IU in task prep")
+Signed-off-by: Xingui Yang <yangxingui@huawei.com>
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Link: https://lore.kernel.org/r/1689045300-44318-2-git-send-email-chenxiang66@hisilicon.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 11 +++++++++--
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 6 ++++--
+ 2 files changed, 13 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+index cd78e4c983aa8..38a91e227842c 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -2026,6 +2026,11 @@ static void slot_err_v2_hw(struct hisi_hba *hisi_hba,
+ u16 dma_tx_err_type = le16_to_cpu(err_record->dma_tx_err_type);
+ u16 sipc_rx_err_type = le16_to_cpu(err_record->sipc_rx_err_type);
+ u32 dma_rx_err_type = le32_to_cpu(err_record->dma_rx_err_type);
++ struct hisi_sas_complete_v2_hdr *complete_queue =
++ hisi_hba->complete_hdr[slot->cmplt_queue];
++ struct hisi_sas_complete_v2_hdr *complete_hdr =
++ &complete_queue[slot->cmplt_queue_slot];
++ u32 dw0 = le32_to_cpu(complete_hdr->dw0);
+ int error = -1;
+
+ if (err_phase == 1) {
+@@ -2310,7 +2315,8 @@ static void slot_err_v2_hw(struct hisi_hba *hisi_hba,
+ break;
+ }
+ }
+- hisi_sas_sata_done(task, slot);
++ if (dw0 & CMPLT_HDR_RSPNS_XFRD_MSK)
++ hisi_sas_sata_done(task, slot);
+ }
+ break;
+ default:
+@@ -2443,7 +2449,8 @@ static void slot_complete_v2_hw(struct hisi_hba *hisi_hba,
+ case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP:
+ {
+ ts->stat = SAS_SAM_STAT_GOOD;
+- hisi_sas_sata_done(task, slot);
++ if (dw0 & CMPLT_HDR_RSPNS_XFRD_MSK)
++ hisi_sas_sata_done(task, slot);
+ break;
+ }
+ default:
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index 81a2a0437c95a..1794ad709183e 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -2247,7 +2247,8 @@ slot_err_v3_hw(struct hisi_hba *hisi_hba, struct sas_task *task,
+ ts->stat = SAS_OPEN_REJECT;
+ ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
+ }
+- hisi_sas_sata_done(task, slot);
++ if (dw0 & CMPLT_HDR_RSPNS_XFRD_MSK)
++ hisi_sas_sata_done(task, slot);
+ break;
+ case SAS_PROTOCOL_SMP:
+ ts->stat = SAS_SAM_STAT_CHECK_CONDITION;
+@@ -2374,7 +2375,8 @@ static void slot_complete_v3_hw(struct hisi_hba *hisi_hba,
+ case SAS_PROTOCOL_STP:
+ case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP:
+ ts->stat = SAS_SAM_STAT_GOOD;
+- hisi_sas_sata_done(task, slot);
++ if (dw0 & CMPLT_HDR_RSPNS_XFRD_MSK)
++ hisi_sas_sata_done(task, slot);
+ break;
+ default:
+ ts->stat = SAS_SAM_STAT_CHECK_CONDITION;
+--
+2.40.1
+
--- /dev/null
+From 4674959942c2bf7ffafe17a5db940caa63f6156a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 May 2023 10:41:21 +0800
+Subject: scsi: hisi_sas: Fix warnings detected by sparse
+
+From: Xingui Yang <yangxingui@huawei.com>
+
+[ Upstream commit c0328cc595124579328462fc45d7a29a084cf357 ]
+
+This patch fixes the following warning:
+
+drivers/scsi/hisi_sas/hisi_sas_v3_hw.c:2168:43: sparse: sparse: restricted __le32 degrades to integer
+
+Reported-by: kernel test robot <lkp@intel.com>
+Link: https://lore.kernel.org/oe-kbuild-all/202304161254.NztCVZIO-lkp@intel.com/
+Signed-off-by: Xingui Yang <yangxingui@huawei.com>
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Link: https://lore.kernel.org/r/1684118481-95908-4-git-send-email-chenxiang66@hisilicon.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Stable-dep-of: f5393a5602ca ("scsi: hisi_sas: Fix normally completed I/O analysed as failed")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index 12d588454f5de..81a2a0437c95a 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -2206,6 +2206,7 @@ slot_err_v3_hw(struct hisi_hba *hisi_hba, struct sas_task *task,
+ u32 trans_tx_fail_type = le32_to_cpu(record->trans_tx_fail_type);
+ u16 sipc_rx_err_type = le16_to_cpu(record->sipc_rx_err_type);
+ u32 dw3 = le32_to_cpu(complete_hdr->dw3);
++ u32 dw0 = le32_to_cpu(complete_hdr->dw0);
+
+ switch (task->task_proto) {
+ case SAS_PROTOCOL_SSP:
+@@ -2215,8 +2216,8 @@ slot_err_v3_hw(struct hisi_hba *hisi_hba, struct sas_task *task,
+ * but I/O information has been written to the host memory, we examine
+ * response IU.
+ */
+- if (!(complete_hdr->dw0 & CMPLT_HDR_RSPNS_GOOD_MSK) &&
+- (complete_hdr->dw0 & CMPLT_HDR_RSPNS_XFRD_MSK))
++ if (!(dw0 & CMPLT_HDR_RSPNS_GOOD_MSK) &&
++ (dw0 & CMPLT_HDR_RSPNS_XFRD_MSK))
+ return false;
+
+ ts->residual = trans_tx_fail_type;
+@@ -2232,7 +2233,7 @@ slot_err_v3_hw(struct hisi_hba *hisi_hba, struct sas_task *task,
+ case SAS_PROTOCOL_SATA:
+ case SAS_PROTOCOL_STP:
+ case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP:
+- if ((complete_hdr->dw0 & CMPLT_HDR_RSPNS_XFRD_MSK) &&
++ if ((dw0 & CMPLT_HDR_RSPNS_XFRD_MSK) &&
+ (sipc_rx_err_type & RX_FIS_STATUS_ERR_MSK)) {
+ ts->stat = SAS_PROTO_RESPONSE;
+ } else if (dma_rx_err_type & RX_DATA_LEN_UNDERFLOW_MSK) {
+--
+2.40.1
+
--- /dev/null
+From 8f360d26a3196c6a4e9890cc80d675f4729d9772 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Jul 2023 10:45:29 +0800
+Subject: scsi: iscsi: Add length check for nlattr payload
+
+From: Lin Ma <linma@zju.edu.cn>
+
+[ Upstream commit 971dfcb74a800047952f5288512b9c7ddedb050a ]
+
+The current NETLINK_ISCSI netlink parsing loop checks every nlmsg to make
+sure the length is bigger than sizeof(struct iscsi_uevent) and then calls
+iscsi_if_recv_msg().
+
+ nlh = nlmsg_hdr(skb);
+ if (nlh->nlmsg_len < sizeof(*nlh) + sizeof(*ev) ||
+ skb->len < nlh->nlmsg_len) {
+ break;
+ }
+ ...
+ err = iscsi_if_recv_msg(skb, nlh, &group);
+
+Hence, in iscsi_if_recv_msg() the nlmsg_data can be safely converted to
+iscsi_uevent as the length is already checked.
+
+However, in other cases the length of nlattr payload is not checked before
+the payload is converted to other data structures. One example is
+iscsi_set_path() which converts the payload to type iscsi_path without any
+checks:
+
+ params = (struct iscsi_path *)((char *)ev + sizeof(*ev));
+
+Whereas iscsi_if_transport_conn() correctly checks the pdu_len:
+
+ pdu_len = nlh->nlmsg_len - sizeof(*nlh) - sizeof(*ev);
+ if ((ev->u.send_pdu.hdr_size > pdu_len) ..
+ err = -EINVAL;
+
+To sum up, some code paths called in iscsi_if_recv_msg() do not check the
+length of the data (see below picture) and directly convert the data to
+another data structure. This could result in an out-of-bound reads and heap
+dirty data leakage.
+
+ _________ nlmsg_len(nlh) _______________
+ / \
++----------+--------------+---------------------------+
+| nlmsghdr | iscsi_uevent | data |
++----------+--------------+---------------------------+
+ \ /
+ iscsi_uevent->u.set_param.len
+
+Fix the issue by adding the length check before accessing it. To clean up
+the code, an additional parameter named rlen is added. The rlen is
+calculated at the beginning of iscsi_if_recv_msg() which avoids duplicated
+calculation.
+
+Fixes: ac20c7bf070d ("[SCSI] iscsi_transport: Added Ping support")
+Fixes: 43514774ff40 ("[SCSI] iscsi class: Add new NETLINK_ISCSI messages for cnic/bnx2i driver.")
+Fixes: 1d9bf13a9cf9 ("[SCSI] iscsi class: add iscsi host set param event")
+Fixes: 01cb225dad8d ("[SCSI] iscsi: add target discvery event to transport class")
+Fixes: 264faaaa1254 ("[SCSI] iscsi: add transport end point callbacks")
+Fixes: fd7255f51a13 ("[SCSI] iscsi: add sysfs attrs for uspace sync up")
+Signed-off-by: Lin Ma <linma@zju.edu.cn>
+Link: https://lore.kernel.org/r/20230725024529.428311-1-linma@zju.edu.cn
+Reviewed-by: Chris Leech <cleech@redhat.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/scsi_transport_iscsi.c | 72 +++++++++++++++++------------
+ 1 file changed, 43 insertions(+), 29 deletions(-)
+
+diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
+index b9b97300e3b3c..2680de88f5bbc 100644
+--- a/drivers/scsi/scsi_transport_iscsi.c
++++ b/drivers/scsi/scsi_transport_iscsi.c
+@@ -3013,14 +3013,15 @@ iscsi_if_destroy_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev
+ }
+
+ static int
+-iscsi_if_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev)
++iscsi_if_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev, u32 rlen)
+ {
+ char *data = (char*)ev + sizeof(*ev);
+ struct iscsi_cls_conn *conn;
+ struct iscsi_cls_session *session;
+ int err = 0, value = 0, state;
+
+- if (ev->u.set_param.len > PAGE_SIZE)
++ if (ev->u.set_param.len > rlen ||
++ ev->u.set_param.len > PAGE_SIZE)
+ return -EINVAL;
+
+ session = iscsi_session_lookup(ev->u.set_param.sid);
+@@ -3117,7 +3118,7 @@ static int iscsi_if_ep_disconnect(struct iscsi_transport *transport,
+
+ static int
+ iscsi_if_transport_ep(struct iscsi_transport *transport,
+- struct iscsi_uevent *ev, int msg_type)
++ struct iscsi_uevent *ev, int msg_type, u32 rlen)
+ {
+ struct iscsi_endpoint *ep;
+ int rc = 0;
+@@ -3125,7 +3126,10 @@ iscsi_if_transport_ep(struct iscsi_transport *transport,
+ switch (msg_type) {
+ case ISCSI_UEVENT_TRANSPORT_EP_CONNECT_THROUGH_HOST:
+ case ISCSI_UEVENT_TRANSPORT_EP_CONNECT:
+- rc = iscsi_if_ep_connect(transport, ev, msg_type);
++ if (rlen < sizeof(struct sockaddr))
++ rc = -EINVAL;
++ else
++ rc = iscsi_if_ep_connect(transport, ev, msg_type);
+ break;
+ case ISCSI_UEVENT_TRANSPORT_EP_POLL:
+ if (!transport->ep_poll)
+@@ -3149,12 +3153,15 @@ iscsi_if_transport_ep(struct iscsi_transport *transport,
+
+ static int
+ iscsi_tgt_dscvr(struct iscsi_transport *transport,
+- struct iscsi_uevent *ev)
++ struct iscsi_uevent *ev, u32 rlen)
+ {
+ struct Scsi_Host *shost;
+ struct sockaddr *dst_addr;
+ int err;
+
++ if (rlen < sizeof(*dst_addr))
++ return -EINVAL;
++
+ if (!transport->tgt_dscvr)
+ return -EINVAL;
+
+@@ -3175,7 +3182,7 @@ iscsi_tgt_dscvr(struct iscsi_transport *transport,
+
+ static int
+ iscsi_set_host_param(struct iscsi_transport *transport,
+- struct iscsi_uevent *ev)
++ struct iscsi_uevent *ev, u32 rlen)
+ {
+ char *data = (char*)ev + sizeof(*ev);
+ struct Scsi_Host *shost;
+@@ -3184,7 +3191,8 @@ iscsi_set_host_param(struct iscsi_transport *transport,
+ if (!transport->set_host_param)
+ return -ENOSYS;
+
+- if (ev->u.set_host_param.len > PAGE_SIZE)
++ if (ev->u.set_host_param.len > rlen ||
++ ev->u.set_host_param.len > PAGE_SIZE)
+ return -EINVAL;
+
+ shost = scsi_host_lookup(ev->u.set_host_param.host_no);
+@@ -3201,12 +3209,15 @@ iscsi_set_host_param(struct iscsi_transport *transport,
+ }
+
+ static int
+-iscsi_set_path(struct iscsi_transport *transport, struct iscsi_uevent *ev)
++iscsi_set_path(struct iscsi_transport *transport, struct iscsi_uevent *ev, u32 rlen)
+ {
+ struct Scsi_Host *shost;
+ struct iscsi_path *params;
+ int err;
+
++ if (rlen < sizeof(*params))
++ return -EINVAL;
++
+ if (!transport->set_path)
+ return -ENOSYS;
+
+@@ -3266,12 +3277,15 @@ iscsi_set_iface_params(struct iscsi_transport *transport,
+ }
+
+ static int
+-iscsi_send_ping(struct iscsi_transport *transport, struct iscsi_uevent *ev)
++iscsi_send_ping(struct iscsi_transport *transport, struct iscsi_uevent *ev, u32 rlen)
+ {
+ struct Scsi_Host *shost;
+ struct sockaddr *dst_addr;
+ int err;
+
++ if (rlen < sizeof(*dst_addr))
++ return -EINVAL;
++
+ if (!transport->send_ping)
+ return -ENOSYS;
+
+@@ -3769,13 +3783,12 @@ iscsi_get_host_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh)
+ }
+
+ static int iscsi_if_transport_conn(struct iscsi_transport *transport,
+- struct nlmsghdr *nlh)
++ struct nlmsghdr *nlh, u32 pdu_len)
+ {
+ struct iscsi_uevent *ev = nlmsg_data(nlh);
+ struct iscsi_cls_session *session;
+ struct iscsi_cls_conn *conn = NULL;
+ struct iscsi_endpoint *ep;
+- uint32_t pdu_len;
+ int err = 0;
+
+ switch (nlh->nlmsg_type) {
+@@ -3860,8 +3873,6 @@ static int iscsi_if_transport_conn(struct iscsi_transport *transport,
+
+ break;
+ case ISCSI_UEVENT_SEND_PDU:
+- pdu_len = nlh->nlmsg_len - sizeof(*nlh) - sizeof(*ev);
+-
+ if ((ev->u.send_pdu.hdr_size > pdu_len) ||
+ (ev->u.send_pdu.data_size > (pdu_len - ev->u.send_pdu.hdr_size))) {
+ err = -EINVAL;
+@@ -3891,6 +3902,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
+ struct iscsi_internal *priv;
+ struct iscsi_cls_session *session;
+ struct iscsi_endpoint *ep = NULL;
++ u32 rlen;
+
+ if (!netlink_capable(skb, CAP_SYS_ADMIN))
+ return -EPERM;
+@@ -3910,6 +3922,13 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
+
+ portid = NETLINK_CB(skb).portid;
+
++ /*
++ * Even though the remaining payload may not be regarded as nlattr,
++ * (like address or something else), calculate the remaining length
++ * here to ease following length checks.
++ */
++ rlen = nlmsg_attrlen(nlh, sizeof(*ev));
++
+ switch (nlh->nlmsg_type) {
+ case ISCSI_UEVENT_CREATE_SESSION:
+ err = iscsi_if_create_session(priv, ep, ev,
+@@ -3966,7 +3985,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
+ err = -EINVAL;
+ break;
+ case ISCSI_UEVENT_SET_PARAM:
+- err = iscsi_if_set_param(transport, ev);
++ err = iscsi_if_set_param(transport, ev, rlen);
+ break;
+ case ISCSI_UEVENT_CREATE_CONN:
+ case ISCSI_UEVENT_DESTROY_CONN:
+@@ -3974,7 +3993,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
+ case ISCSI_UEVENT_START_CONN:
+ case ISCSI_UEVENT_BIND_CONN:
+ case ISCSI_UEVENT_SEND_PDU:
+- err = iscsi_if_transport_conn(transport, nlh);
++ err = iscsi_if_transport_conn(transport, nlh, rlen);
+ break;
+ case ISCSI_UEVENT_GET_STATS:
+ err = iscsi_if_get_stats(transport, nlh);
+@@ -3983,23 +4002,22 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
+ case ISCSI_UEVENT_TRANSPORT_EP_POLL:
+ case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT:
+ case ISCSI_UEVENT_TRANSPORT_EP_CONNECT_THROUGH_HOST:
+- err = iscsi_if_transport_ep(transport, ev, nlh->nlmsg_type);
++ err = iscsi_if_transport_ep(transport, ev, nlh->nlmsg_type, rlen);
+ break;
+ case ISCSI_UEVENT_TGT_DSCVR:
+- err = iscsi_tgt_dscvr(transport, ev);
++ err = iscsi_tgt_dscvr(transport, ev, rlen);
+ break;
+ case ISCSI_UEVENT_SET_HOST_PARAM:
+- err = iscsi_set_host_param(transport, ev);
++ err = iscsi_set_host_param(transport, ev, rlen);
+ break;
+ case ISCSI_UEVENT_PATH_UPDATE:
+- err = iscsi_set_path(transport, ev);
++ err = iscsi_set_path(transport, ev, rlen);
+ break;
+ case ISCSI_UEVENT_SET_IFACE_PARAMS:
+- err = iscsi_set_iface_params(transport, ev,
+- nlmsg_attrlen(nlh, sizeof(*ev)));
++ err = iscsi_set_iface_params(transport, ev, rlen);
+ break;
+ case ISCSI_UEVENT_PING:
+- err = iscsi_send_ping(transport, ev);
++ err = iscsi_send_ping(transport, ev, rlen);
+ break;
+ case ISCSI_UEVENT_GET_CHAP:
+ err = iscsi_get_chap(transport, nlh);
+@@ -4008,13 +4026,10 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
+ err = iscsi_delete_chap(transport, ev);
+ break;
+ case ISCSI_UEVENT_SET_FLASHNODE_PARAMS:
+- err = iscsi_set_flashnode_param(transport, ev,
+- nlmsg_attrlen(nlh,
+- sizeof(*ev)));
++ err = iscsi_set_flashnode_param(transport, ev, rlen);
+ break;
+ case ISCSI_UEVENT_NEW_FLASHNODE:
+- err = iscsi_new_flashnode(transport, ev,
+- nlmsg_attrlen(nlh, sizeof(*ev)));
++ err = iscsi_new_flashnode(transport, ev, rlen);
+ break;
+ case ISCSI_UEVENT_DEL_FLASHNODE:
+ err = iscsi_del_flashnode(transport, ev);
+@@ -4029,8 +4044,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
+ err = iscsi_logout_flashnode_sid(transport, ev);
+ break;
+ case ISCSI_UEVENT_SET_CHAP:
+- err = iscsi_set_chap(transport, ev,
+- nlmsg_attrlen(nlh, sizeof(*ev)));
++ err = iscsi_set_chap(transport, ev, rlen);
+ break;
+ case ISCSI_UEVENT_GET_HOST_STATS:
+ err = iscsi_get_host_stats(transport, nlh);
+--
+2.40.1
+
--- /dev/null
+From 91e34da43e6a9676fbcdc941a5eb4ba93188953d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 23 Jul 2023 15:58:20 +0800
+Subject: scsi: iscsi: Add strlen() check in iscsi_if_set{_host}_param()
+
+From: Lin Ma <linma@zju.edu.cn>
+
+[ Upstream commit ce51c817008450ef4188471db31639d42d37a5e1 ]
+
+The functions iscsi_if_set_param() and iscsi_if_set_host_param() convert an
+nlattr payload to type char* and then call C string handling functions like
+sscanf and kstrdup:
+
+ char *data = (char*)ev + sizeof(*ev);
+ ...
+ sscanf(data, "%d", &value);
+
+However, since the nlattr is provided by the user-space program and the
+nlmsg skb is allocated with GFP_KERNEL instead of GFP_ZERO flag (see
+netlink_alloc_large_skb() in netlink_sendmsg()), dirty data on the heap can
+lead to an OOB access for those string handling functions.
+
+By investigating how the bug is introduced, we find it is really
+interesting as the old version parsing code starting from commit
+fd7255f51a13 ("[SCSI] iscsi: add sysfs attrs for uspace sync up") treated
+the nlattr as integer bytes instead of string and had length check in
+iscsi_copy_param():
+
+ if (ev->u.set_param.len != sizeof(uint32_t))
+ BUG();
+
+But, since the commit a54a52caad4b ("[SCSI] iscsi: fixup set/get param
+functions"), the code treated the nlattr as C string while forgetting to
+add any strlen checks(), opening the possibility of an OOB access.
+
+Fix the potential OOB by adding the strlen() check before accessing the
+buf. If the data passes this check, all low-level set_param handlers can
+safely treat this buf as legal C string.
+
+Fixes: fd7255f51a13 ("[SCSI] iscsi: add sysfs attrs for uspace sync up")
+Fixes: 1d9bf13a9cf9 ("[SCSI] iscsi class: add iscsi host set param event")
+Signed-off-by: Lin Ma <linma@zju.edu.cn>
+Link: https://lore.kernel.org/r/20230723075820.3713119-1-linma@zju.edu.cn
+Reviewed-by: Chris Leech <cleech@redhat.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/scsi_transport_iscsi.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
+index 2680de88f5bbc..49dbcd67579aa 100644
+--- a/drivers/scsi/scsi_transport_iscsi.c
++++ b/drivers/scsi/scsi_transport_iscsi.c
+@@ -3029,6 +3029,10 @@ iscsi_if_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev, u
+ if (!conn || !session)
+ return -EINVAL;
+
++ /* data will be regarded as NULL-ended string, do length check */
++ if (strlen(data) > ev->u.set_param.len)
++ return -EINVAL;
++
+ switch (ev->u.set_param.param) {
+ case ISCSI_PARAM_SESS_RECOVERY_TMO:
+ sscanf(data, "%d", &value);
+@@ -3202,6 +3206,10 @@ iscsi_set_host_param(struct iscsi_transport *transport,
+ return -ENODEV;
+ }
+
++ /* see similar check in iscsi_if_set_param() */
++ if (strlen(data) > ev->u.set_host_param.len)
++ return -EINVAL;
++
+ err = transport->set_host_param(shost, ev->u.set_host_param.param,
+ data, ev->u.set_host_param.len);
+ scsi_host_put(shost);
+--
+2.40.1
+
--- /dev/null
+From 5a5364999e02121ca7efbe71022fa27ef7794d97 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Jul 2023 10:40:33 +0200
+Subject: scsi: qedf: Do not touch __user pointer in qedf_dbg_debug_cmd_read()
+ directly
+
+From: Oleksandr Natalenko <oleksandr@redhat.com>
+
+[ Upstream commit 31b5991a9a91ba97237ac9da509d78eec453ff72 ]
+
+The qedf_dbg_debug_cmd_read() function invokes sprintf() directly on a
+__user pointer, which may crash the kernel.
+
+Avoid doing that by using a small on-stack buffer for scnprintf() and then
+calling simple_read_from_buffer() which does a proper copy_to_user() call.
+
+Fixes: 61d8658b4a43 ("scsi: qedf: Add QLogic FastLinQ offload FCoE driver framework.")
+Link: https://lore.kernel.org/lkml/20230724120241.40495-1-oleksandr@redhat.com/
+Link: https://lore.kernel.org/linux-scsi/20230726101236.11922-1-skashyap@marvell.com/
+Cc: Saurav Kashyap <skashyap@marvell.com>
+Cc: Rob Evers <revers@redhat.com>
+Cc: Johannes Thumshirn <Johannes.Thumshirn@wdc.com>
+Cc: David Laight <David.Laight@ACULAB.COM>
+Cc: Jozef Bacik <jobacik@redhat.com>
+Cc: Laurence Oberman <loberman@redhat.com>
+Cc: "James E.J. Bottomley" <jejb@linux.ibm.com>
+Cc: "Martin K. Petersen" <martin.petersen@oracle.com>
+Cc: GR-QLogic-Storage-Upstream@marvell.com
+Cc: linux-scsi@vger.kernel.org
+Reviewed-by: Laurence Oberman <loberman@redhat.com>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Tested-by: Laurence Oberman <loberman@redhat.com>
+Acked-by: Saurav Kashyap <skashyap@marvell.com>
+Signed-off-by: Oleksandr Natalenko <oleksandr@redhat.com>
+Link: https://lore.kernel.org/r/20230731084034.37021-3-oleksandr@redhat.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qedf/qedf_debugfs.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/scsi/qedf/qedf_debugfs.c b/drivers/scsi/qedf/qedf_debugfs.c
+index 3eb4334ac6a32..1c5716540e465 100644
+--- a/drivers/scsi/qedf/qedf_debugfs.c
++++ b/drivers/scsi/qedf/qedf_debugfs.c
+@@ -138,15 +138,14 @@ qedf_dbg_debug_cmd_read(struct file *filp, char __user *buffer, size_t count,
+ loff_t *ppos)
+ {
+ int cnt;
++ char cbuf[32];
+ struct qedf_dbg_ctx *qedf_dbg =
+ (struct qedf_dbg_ctx *)filp->private_data;
+
+ QEDF_INFO(qedf_dbg, QEDF_LOG_DEBUGFS, "debug mask=0x%x\n", qedf_debug);
+- cnt = sprintf(buffer, "debug mask = 0x%x\n", qedf_debug);
++ cnt = scnprintf(cbuf, sizeof(cbuf), "debug mask = 0x%x\n", qedf_debug);
+
+- cnt = min_t(int, count, cnt - *ppos);
+- *ppos += cnt;
+- return cnt;
++ return simple_read_from_buffer(buffer, count, ppos, cbuf, cnt);
+ }
+
+ static ssize_t
+--
+2.40.1
+
--- /dev/null
+From 9cab475adb11061ab17844dd50b8d65884bdf109 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Jul 2023 10:40:34 +0200
+Subject: scsi: qedf: Do not touch __user pointer in qedf_dbg_fp_int_cmd_read()
+ directly
+
+From: Oleksandr Natalenko <oleksandr@redhat.com>
+
+[ Upstream commit 25dbc20deab5165f847b4eb42f376f725a986ee8 ]
+
+The qedf_dbg_fp_int_cmd_read() function invokes sprintf() directly on a
+__user pointer, which may crash the kernel.
+
+Avoid doing that by vmalloc()'ating a buffer for scnprintf() and then
+calling simple_read_from_buffer() which does a proper copy_to_user() call.
+
+Fixes: 61d8658b4a43 ("scsi: qedf: Add QLogic FastLinQ offload FCoE driver framework.")
+Link: https://lore.kernel.org/lkml/20230724120241.40495-1-oleksandr@redhat.com/
+Link: https://lore.kernel.org/linux-scsi/20230726101236.11922-1-skashyap@marvell.com/
+Cc: Saurav Kashyap <skashyap@marvell.com>
+Cc: Rob Evers <revers@redhat.com>
+Cc: Johannes Thumshirn <Johannes.Thumshirn@wdc.com>
+Cc: David Laight <David.Laight@ACULAB.COM>
+Cc: Jozef Bacik <jobacik@redhat.com>
+Cc: Laurence Oberman <loberman@redhat.com>
+Cc: "James E.J. Bottomley" <jejb@linux.ibm.com>
+Cc: "Martin K. Petersen" <martin.petersen@oracle.com>
+Cc: GR-QLogic-Storage-Upstream@marvell.com
+Cc: linux-scsi@vger.kernel.org
+Reviewed-by: Laurence Oberman <loberman@redhat.com>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Tested-by: Laurence Oberman <loberman@redhat.com>
+Acked-by: Saurav Kashyap <skashyap@marvell.com>
+Signed-off-by: Oleksandr Natalenko <oleksandr@redhat.com>
+Link: https://lore.kernel.org/r/20230731084034.37021-4-oleksandr@redhat.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qedf/qedf_dbg.h | 2 ++
+ drivers/scsi/qedf/qedf_debugfs.c | 21 +++++++++++++++------
+ 2 files changed, 17 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/scsi/qedf/qedf_dbg.h b/drivers/scsi/qedf/qedf_dbg.h
+index f4d81127239eb..5ec2b817c694a 100644
+--- a/drivers/scsi/qedf/qedf_dbg.h
++++ b/drivers/scsi/qedf/qedf_dbg.h
+@@ -59,6 +59,8 @@ extern uint qedf_debug;
+ #define QEDF_LOG_NOTICE 0x40000000 /* Notice logs */
+ #define QEDF_LOG_WARN 0x80000000 /* Warning logs */
+
++#define QEDF_DEBUGFS_LOG_LEN (2 * PAGE_SIZE)
++
+ /* Debug context structure */
+ struct qedf_dbg_ctx {
+ unsigned int host_no;
+diff --git a/drivers/scsi/qedf/qedf_debugfs.c b/drivers/scsi/qedf/qedf_debugfs.c
+index 1c5716540e465..451fd236bfd05 100644
+--- a/drivers/scsi/qedf/qedf_debugfs.c
++++ b/drivers/scsi/qedf/qedf_debugfs.c
+@@ -8,6 +8,7 @@
+ #include <linux/uaccess.h>
+ #include <linux/debugfs.h>
+ #include <linux/module.h>
++#include <linux/vmalloc.h>
+
+ #include "qedf.h"
+ #include "qedf_dbg.h"
+@@ -98,7 +99,9 @@ static ssize_t
+ qedf_dbg_fp_int_cmd_read(struct file *filp, char __user *buffer, size_t count,
+ loff_t *ppos)
+ {
++ ssize_t ret;
+ size_t cnt = 0;
++ char *cbuf;
+ int id;
+ struct qedf_fastpath *fp = NULL;
+ struct qedf_dbg_ctx *qedf_dbg =
+@@ -108,19 +111,25 @@ qedf_dbg_fp_int_cmd_read(struct file *filp, char __user *buffer, size_t count,
+
+ QEDF_INFO(qedf_dbg, QEDF_LOG_DEBUGFS, "entered\n");
+
+- cnt = sprintf(buffer, "\nFastpath I/O completions\n\n");
++ cbuf = vmalloc(QEDF_DEBUGFS_LOG_LEN);
++ if (!cbuf)
++ return 0;
++
++ cnt += scnprintf(cbuf + cnt, QEDF_DEBUGFS_LOG_LEN - cnt, "\nFastpath I/O completions\n\n");
+
+ for (id = 0; id < qedf->num_queues; id++) {
+ fp = &(qedf->fp_array[id]);
+ if (fp->sb_id == QEDF_SB_ID_NULL)
+ continue;
+- cnt += sprintf((buffer + cnt), "#%d: %lu\n", id,
+- fp->completions);
++ cnt += scnprintf(cbuf + cnt, QEDF_DEBUGFS_LOG_LEN - cnt,
++ "#%d: %lu\n", id, fp->completions);
+ }
+
+- cnt = min_t(int, count, cnt - *ppos);
+- *ppos += cnt;
+- return cnt;
++ ret = simple_read_from_buffer(buffer, count, ppos, cbuf, cnt);
++
++ vfree(cbuf);
++
++ return ret;
+ }
+
+ static ssize_t
+--
+2.40.1
+
--- /dev/null
+From 50613ec82887efee45e9a721f5b9e9a17487ffae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Jul 2023 10:40:32 +0200
+Subject: scsi: qedf: Do not touch __user pointer in
+ qedf_dbg_stop_io_on_error_cmd_read() directly
+
+From: Oleksandr Natalenko <oleksandr@redhat.com>
+
+[ Upstream commit 7d3d20dee4f648ec44e9717d5f647d594d184433 ]
+
+The qedf_dbg_stop_io_on_error_cmd_read() function invokes sprintf()
+directly on a __user pointer, which may crash the kernel.
+
+Avoid doing that by using a small on-stack buffer for scnprintf() and then
+calling simple_read_from_buffer() which does a proper copy_to_user() call.
+
+Fixes: 61d8658b4a43 ("scsi: qedf: Add QLogic FastLinQ offload FCoE driver framework.")
+Link: https://lore.kernel.org/lkml/20230724120241.40495-1-oleksandr@redhat.com/
+Link: https://lore.kernel.org/linux-scsi/20230726101236.11922-1-skashyap@marvell.com/
+Cc: Saurav Kashyap <skashyap@marvell.com>
+Cc: Rob Evers <revers@redhat.com>
+Cc: Johannes Thumshirn <Johannes.Thumshirn@wdc.com>
+Cc: David Laight <David.Laight@ACULAB.COM>
+Cc: Jozef Bacik <jobacik@redhat.com>
+Cc: Laurence Oberman <loberman@redhat.com>
+Cc: "James E.J. Bottomley" <jejb@linux.ibm.com>
+Cc: "Martin K. Petersen" <martin.petersen@oracle.com>
+Cc: GR-QLogic-Storage-Upstream@marvell.com
+Cc: linux-scsi@vger.kernel.org
+Reviewed-by: Laurence Oberman <loberman@redhat.com>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Tested-by: Laurence Oberman <loberman@redhat.com>
+Acked-by: Saurav Kashyap <skashyap@marvell.com>
+Signed-off-by: Oleksandr Natalenko <oleksandr@redhat.com>
+Link: https://lore.kernel.org/r/20230731084034.37021-2-oleksandr@redhat.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qedf/qedf_debugfs.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/scsi/qedf/qedf_debugfs.c b/drivers/scsi/qedf/qedf_debugfs.c
+index a3ed681c8ce3f..3eb4334ac6a32 100644
+--- a/drivers/scsi/qedf/qedf_debugfs.c
++++ b/drivers/scsi/qedf/qedf_debugfs.c
+@@ -185,18 +185,17 @@ qedf_dbg_stop_io_on_error_cmd_read(struct file *filp, char __user *buffer,
+ size_t count, loff_t *ppos)
+ {
+ int cnt;
++ char cbuf[7];
+ struct qedf_dbg_ctx *qedf_dbg =
+ (struct qedf_dbg_ctx *)filp->private_data;
+ struct qedf_ctx *qedf = container_of(qedf_dbg,
+ struct qedf_ctx, dbg_ctx);
+
+ QEDF_INFO(qedf_dbg, QEDF_LOG_DEBUGFS, "entered\n");
+- cnt = sprintf(buffer, "%s\n",
++ cnt = scnprintf(cbuf, sizeof(cbuf), "%s\n",
+ qedf->stop_io_on_error ? "true" : "false");
+
+- cnt = min_t(int, count, cnt - *ppos);
+- *ppos += cnt;
+- return cnt;
++ return simple_read_from_buffer(buffer, count, ppos, cbuf, cnt);
+ }
+
+ static ssize_t
+--
+2.40.1
+
--- /dev/null
+From afb1c9f77502d13b708b2e3f325c9df95b3cb6de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 23 Jul 2023 16:00:53 +0800
+Subject: scsi: qla4xxx: Add length check when parsing nlattrs
+
+From: Lin Ma <linma@zju.edu.cn>
+
+[ Upstream commit 47cd3770e31df942e2bb925a9a855c79ed0662eb ]
+
+There are three places that qla4xxx parses nlattrs:
+
+ - qla4xxx_set_chap_entry()
+
+ - qla4xxx_iface_set_param()
+
+ - qla4xxx_sysfs_ddb_set_param()
+
+and each of them directly converts the nlattr to specific pointer of
+structure without length checking. This could be dangerous as those
+attributes are not validated and a malformed nlattr (e.g., length 0) could
+result in an OOB read that leaks heap dirty data.
+
+Add the nla_len check before accessing the nlattr data and return EINVAL if
+the length check fails.
+
+Fixes: 26ffd7b45fe9 ("[SCSI] qla4xxx: Add support to set CHAP entries")
+Fixes: 1e9e2be3ee03 ("[SCSI] qla4xxx: Add flash node mgmt support")
+Fixes: 00c31889f751 ("[SCSI] qla4xxx: fix data alignment and use nl helpers")
+Signed-off-by: Lin Ma <linma@zju.edu.cn>
+Link: https://lore.kernel.org/r/20230723080053.3714534-1-linma@zju.edu.cn
+Reviewed-by: Chris Leech <cleech@redhat.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla4xxx/ql4_os.c | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
+index ee6d784c095c9..b6959470ddc04 100644
+--- a/drivers/scsi/qla4xxx/ql4_os.c
++++ b/drivers/scsi/qla4xxx/ql4_os.c
+@@ -968,6 +968,11 @@ static int qla4xxx_set_chap_entry(struct Scsi_Host *shost, void *data, int len)
+ memset(&chap_rec, 0, sizeof(chap_rec));
+
+ nla_for_each_attr(attr, data, len, rem) {
++ if (nla_len(attr) < sizeof(*param_info)) {
++ rc = -EINVAL;
++ goto exit_set_chap;
++ }
++
+ param_info = nla_data(attr);
+
+ switch (param_info->param) {
+@@ -2750,6 +2755,11 @@ qla4xxx_iface_set_param(struct Scsi_Host *shost, void *data, uint32_t len)
+ }
+
+ nla_for_each_attr(attr, data, len, rem) {
++ if (nla_len(attr) < sizeof(*iface_param)) {
++ rval = -EINVAL;
++ goto exit_init_fw_cb;
++ }
++
+ iface_param = nla_data(attr);
+
+ if (iface_param->param_type == ISCSI_NET_PARAM) {
+@@ -8104,6 +8114,11 @@ qla4xxx_sysfs_ddb_set_param(struct iscsi_bus_flash_session *fnode_sess,
+
+ memset((void *)&chap_tbl, 0, sizeof(chap_tbl));
+ nla_for_each_attr(attr, data, len, rem) {
++ if (nla_len(attr) < sizeof(*fnode_param)) {
++ rc = -EINVAL;
++ goto exit_set_param;
++ }
++
+ fnode_param = nla_data(attr);
+
+ switch (fnode_param->param) {
+--
+2.40.1
+
--- /dev/null
+From a38b2d629ef22f91eac06192fb8db00626f52ae3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Jul 2023 13:08:30 -0700
+Subject: scsi: RDMA/srp: Fix residual handling
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit 89e637c19b2441aabc8dbf22a8745b932fd6996e ]
+
+Although the code for residual handling in the SRP initiator follows the
+SCSI documentation, that documentation has never been correct. Because
+scsi_finish_command() starts from the data buffer length and subtracts the
+residual, scsi_set_resid() must not be called if a residual overflow
+occurs. Hence remove the scsi_set_resid() calls from the SRP initiator if a
+residual overflow occurrs.
+
+Cc: Leon Romanovsky <leon@kernel.org>
+Cc: Jason Gunthorpe <jgg@nvidia.com>
+Fixes: 9237f04e12cc ("scsi: core: Fix scsi_get/set_resid() interface")
+Fixes: e714531a349f ("IB/srp: Fix residual handling")
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Link: https://lore.kernel.org/r/20230724200843.3376570-3-bvanassche@acm.org
+Acked-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/srp/ib_srp.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
+index 0e513a7e5ac80..1574218764e0a 100644
+--- a/drivers/infiniband/ulp/srp/ib_srp.c
++++ b/drivers/infiniband/ulp/srp/ib_srp.c
+@@ -1979,12 +1979,8 @@ static void srp_process_rsp(struct srp_rdma_ch *ch, struct srp_rsp *rsp)
+
+ if (unlikely(rsp->flags & SRP_RSP_FLAG_DIUNDER))
+ scsi_set_resid(scmnd, be32_to_cpu(rsp->data_in_res_cnt));
+- else if (unlikely(rsp->flags & SRP_RSP_FLAG_DIOVER))
+- scsi_set_resid(scmnd, -be32_to_cpu(rsp->data_in_res_cnt));
+ else if (unlikely(rsp->flags & SRP_RSP_FLAG_DOUNDER))
+ scsi_set_resid(scmnd, be32_to_cpu(rsp->data_out_res_cnt));
+- else if (unlikely(rsp->flags & SRP_RSP_FLAG_DOOVER))
+- scsi_set_resid(scmnd, -be32_to_cpu(rsp->data_out_res_cnt));
+
+ srp_free_req(ch, req, scmnd,
+ be32_to_cpu(rsp->req_lim_delta));
+--
+2.40.1
+
--- /dev/null
+From 7c3f9ee2ee6e40d27bcfd684a975f1b133699e49 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Jul 2023 13:08:29 -0700
+Subject: scsi: ufs: Fix residual handling
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit 2903265e27bfc6dea915dd9e17a1b2587f621f73 ]
+
+Only call scsi_set_resid() in case of an underflow. Do not call
+scsi_set_resid() in case of an overflow.
+
+Cc: Avri Altman <avri.altman@wdc.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Fixes: cb38845d90fc ("scsi: ufs: core: Set the residual byte count")
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Link: https://lore.kernel.org/r/20230724200843.3376570-2-bvanassche@acm.org
+Reviewed-by: Avri Altman <avri.altman@wdc.com>
+Reviewed-by: Adrian Hunter <adrian.hunter@intel.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ufs/core/ufshcd.c | 12 ++++++++++--
+ include/ufs/ufs.h | 6 ++++++
+ 2 files changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
+index 6d8ef80d9cbc4..b9177182e5a7b 100644
+--- a/drivers/ufs/core/ufshcd.c
++++ b/drivers/ufs/core/ufshcd.c
+@@ -5255,9 +5255,17 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp,
+ int result = 0;
+ int scsi_status;
+ enum utp_ocs ocs;
++ u8 upiu_flags;
++ u32 resid;
+
+- scsi_set_resid(lrbp->cmd,
+- be32_to_cpu(lrbp->ucd_rsp_ptr->sr.residual_transfer_count));
++ upiu_flags = be32_to_cpu(lrbp->ucd_rsp_ptr->header.dword_0) >> 16;
++ resid = be32_to_cpu(lrbp->ucd_rsp_ptr->sr.residual_transfer_count);
++ /*
++ * Test !overflow instead of underflow to support UFS devices that do
++ * not set either flag.
++ */
++ if (resid && !(upiu_flags & UPIU_RSP_FLAG_OVERFLOW))
++ scsi_set_resid(lrbp->cmd, resid);
+
+ /* overall command status of utrd */
+ ocs = ufshcd_get_tr_ocs(lrbp, cqe);
+diff --git a/include/ufs/ufs.h b/include/ufs/ufs.h
+index 4e8d6240e589b..af5f5e588d5f4 100644
+--- a/include/ufs/ufs.h
++++ b/include/ufs/ufs.h
+@@ -102,6 +102,12 @@ enum {
+ UPIU_CMD_FLAGS_READ = 0x40,
+ };
+
++/* UPIU response flags */
++enum {
++ UPIU_RSP_FLAG_UNDERFLOW = 0x20,
++ UPIU_RSP_FLAG_OVERFLOW = 0x40,
++};
++
+ /* UPIU Task Attributes */
+ enum {
+ UPIU_TASK_ATTR_SIMPLE = 0x00,
+--
+2.40.1
+
--- /dev/null
+From 30dfe298fb6759f831413b53732d085b4a4d3c0c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Aug 2023 11:07:27 +0800
+Subject: selftests/bpf: Clean up fmod_ret in bench_rename test script
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Yipeng Zou <zouyipeng@huawei.com>
+
+[ Upstream commit 83a89c4b6ae93481d3f618aba6a29d89208d26ed ]
+
+Running the bench_rename test script, the following error occurs:
+
+ # ./benchs/run_bench_rename.sh
+ base : 0.819 ± 0.012M/s
+ kprobe : 0.538 ± 0.009M/s
+ kretprobe : 0.503 ± 0.004M/s
+ rawtp : 0.779 ± 0.020M/s
+ fentry : 0.726 ± 0.007M/s
+ fexit : 0.691 ± 0.007M/s
+ benchmark 'rename-fmodret' not found
+
+The bench_rename_fmodret has been removed in commit b000def2e052
+("selftests: Remove fmod_ret from test_overhead"), thus remove it
+from the runners in the test script.
+
+Fixes: b000def2e052 ("selftests: Remove fmod_ret from test_overhead")
+Signed-off-by: Yipeng Zou <zouyipeng@huawei.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Link: https://lore.kernel.org/bpf/20230814030727.3010390-1-zouyipeng@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/benchs/run_bench_rename.sh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/bpf/benchs/run_bench_rename.sh b/tools/testing/selftests/bpf/benchs/run_bench_rename.sh
+index 16f774b1cdbed..7b281dbe41656 100755
+--- a/tools/testing/selftests/bpf/benchs/run_bench_rename.sh
++++ b/tools/testing/selftests/bpf/benchs/run_bench_rename.sh
+@@ -2,7 +2,7 @@
+
+ set -eufo pipefail
+
+-for i in base kprobe kretprobe rawtp fentry fexit fmodret
++for i in base kprobe kretprobe rawtp fentry fexit
+ do
+ summary=$(sudo ./bench -w2 -d5 -a rename-$i | tail -n1 | cut -d'(' -f1 | cut -d' ' -f3-)
+ printf "%-10s: %s\n" $i "$summary"
+--
+2.40.1
+
--- /dev/null
+From 2822b5a2cad03415b7a61ba498e39f63bb6eef9e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Jun 2023 15:19:42 +0200
+Subject: selftests/bpf: Fix bpf_nf failure upon test rerun
+
+From: Daniel Borkmann <daniel@iogearbox.net>
+
+[ Upstream commit 17e8e5d6e09adb4b4f4fb5c89b3ec3fcae2c64a6 ]
+
+Alexei reported:
+
+ After fast forwarding bpf-next today bpf_nf test started to fail when
+ run twice:
+
+ $ ./test_progs -t bpf_nf
+ #17 bpf_nf:OK
+ Summary: 1/10 PASSED, 0 SKIPPED, 0 FAILED
+
+ $ ./test_progs -t bpf_nf
+ All error logs:
+ test_bpf_nf_ct:PASS:test_bpf_nf__open_and_load 0 nsec
+ test_bpf_nf_ct:PASS:iptables-legacy -t raw -A PREROUTING -j CONNMARK
+ --set-mark 42/0 0 nsec
+ (network_helpers.c:102: errno: Address already in use) Failed to bind socket
+ test_bpf_nf_ct:FAIL:start_server unexpected start_server: actual -1 < expected 0
+ #17/1 bpf_nf/xdp-ct:FAIL
+ test_bpf_nf_ct:PASS:test_bpf_nf__open_and_load 0 nsec
+ test_bpf_nf_ct:PASS:iptables-legacy -t raw -A PREROUTING -j CONNMARK
+ --set-mark 42/0 0 nsec
+ (network_helpers.c:102: errno: Address already in use) Failed to bind socket
+ test_bpf_nf_ct:FAIL:start_server unexpected start_server: actual -1 < expected 0
+ #17/2 bpf_nf/tc-bpf-ct:FAIL
+ #17 bpf_nf:FAIL
+ Summary: 0/8 PASSED, 0 SKIPPED, 1 FAILED
+
+I was able to locally reproduce as well. Rearrange the connection teardown
+so that the client closes its connection first so that we don't need to
+linger in TCP time-wait.
+
+Fixes: e81fbd4c1ba7 ("selftests/bpf: Add existing connection bpf_*_ct_lookup() test")
+Reported-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Link: https://lore.kernel.org/bpf/CAADnVQ+0dnDq_v_vH1EfkacbfGnHANaon7zsw10pMb-D9FS0Pw@mail.gmail.com
+Link: https://lore.kernel.org/bpf/20230626131942.5100-1-daniel@iogearbox.net
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/prog_tests/bpf_nf.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_nf.c b/tools/testing/selftests/bpf/prog_tests/bpf_nf.c
+index c8ba4009e4ab9..b30ff6b3b81ae 100644
+--- a/tools/testing/selftests/bpf/prog_tests/bpf_nf.c
++++ b/tools/testing/selftests/bpf/prog_tests/bpf_nf.c
+@@ -123,12 +123,13 @@ static void test_bpf_nf_ct(int mode)
+ ASSERT_EQ(skel->data->test_snat_addr, 0, "Test for source natting");
+ ASSERT_EQ(skel->data->test_dnat_addr, 0, "Test for destination natting");
+ end:
+- if (srv_client_fd != -1)
+- close(srv_client_fd);
+ if (client_fd != -1)
+ close(client_fd);
++ if (srv_client_fd != -1)
++ close(srv_client_fd);
+ if (srv_fd != -1)
+ close(srv_fd);
++
+ snprintf(cmd, sizeof(cmd), iptables, "-D");
+ system(cmd);
+ test_bpf_nf__destroy(skel);
+--
+2.40.1
+
--- /dev/null
+From 856e578d1783e529b60244fe8c8eb0c0ed11543e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Aug 2023 11:14:34 +0800
+Subject: selftests/bpf: Fix repeat option when kfunc_call verification fails
+
+From: Yipeng Zou <zouyipeng@huawei.com>
+
+[ Upstream commit 811915db674f8daf19bb4fcb67da9017235ce26d ]
+
+There is no way where topts.repeat can be set to 1 when tc_test fails.
+Fix the typo where the break statement slipped by one line.
+
+Fixes: fb66223a244f ("selftests/bpf: add test for accessing ctx from syscall program type")
+Signed-off-by: Yipeng Zou <zouyipeng@huawei.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Reviewed-by: Li Zetao <lizetao1@huawei.com>
+Link: https://lore.kernel.org/bpf/20230814031434.3077944-1-zouyipeng@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/prog_tests/kfunc_call.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/bpf/prog_tests/kfunc_call.c b/tools/testing/selftests/bpf/prog_tests/kfunc_call.c
+index a543742cd7bd1..2eb71559713c9 100644
+--- a/tools/testing/selftests/bpf/prog_tests/kfunc_call.c
++++ b/tools/testing/selftests/bpf/prog_tests/kfunc_call.c
+@@ -173,8 +173,8 @@ static void verify_fail(struct kfunc_test_params *param)
+ case tc_test:
+ topts.data_in = &pkt_v4;
+ topts.data_size_in = sizeof(pkt_v4);
+- break;
+ topts.repeat = 1;
++ break;
+ }
+
+ skel = kfunc_call_fail__open_opts(&opts);
+--
+2.40.1
+
--- /dev/null
+From cd3d1b6a65c6a18496f2c15f45e5b1f3ec7ed4b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Aug 2023 08:39:06 +0100
+Subject: selftests/bpf: fix static assert compilation issue for test_cls_*.c
+
+From: Alan Maguire <alan.maguire@oracle.com>
+
+[ Upstream commit 416c6d01244ecbf0abfdb898fd091b50ef951b48 ]
+
+commit bdeeed3498c7 ("libbpf: fix offsetof() and container_of() to work with CO-RE")
+
+...was backported to stable trees such as 5.15. The problem is that with older
+LLVM/clang (14/15) - which is often used for older kernels - we see compilation
+failures in BPF selftests now:
+
+In file included from progs/test_cls_redirect_subprogs.c:2:
+progs/test_cls_redirect.c:90:2: error: static assertion expression is not an integral constant expression
+ sizeof(flow_ports_t) !=
+ ^~~~~~~~~~~~~~~~~~~~~~~
+progs/test_cls_redirect.c:91:3: note: cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression
+ offsetofend(struct bpf_sock_tuple, ipv4.dport) -
+ ^
+progs/test_cls_redirect.c:32:3: note: expanded from macro 'offsetofend'
+ (offsetof(TYPE, MEMBER) + sizeof((((TYPE *)0)->MEMBER)))
+ ^
+tools/testing/selftests/bpf/tools/include/bpf/bpf_helpers.h:86:33: note: expanded from macro 'offsetof'
+ ^
+In file included from progs/test_cls_redirect_subprogs.c:2:
+progs/test_cls_redirect.c:95:2: error: static assertion expression is not an integral constant expression
+ sizeof(flow_ports_t) !=
+ ^~~~~~~~~~~~~~~~~~~~~~~
+progs/test_cls_redirect.c:96:3: note: cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression
+ offsetofend(struct bpf_sock_tuple, ipv6.dport) -
+ ^
+progs/test_cls_redirect.c:32:3: note: expanded from macro 'offsetofend'
+ (offsetof(TYPE, MEMBER) + sizeof((((TYPE *)0)->MEMBER)))
+ ^
+tools/testing/selftests/bpf/tools/include/bpf/bpf_helpers.h:86:33: note: expanded from macro 'offsetof'
+ ^
+2 errors generated.
+make: *** [Makefile:594: tools/testing/selftests/bpf/test_cls_redirect_subprogs.bpf.o] Error 1
+
+The problem is the new offsetof() does not play nice with static asserts.
+Given that the context is a static assert (and CO-RE relocation is not
+needed at compile time), offsetof() usage can be replaced by restoring
+the original offsetof() definition as __builtin_offsetof().
+
+Fixes: bdeeed3498c7 ("libbpf: fix offsetof() and container_of() to work with CO-RE")
+Reported-by: Colm Harrington <colm.harrington@oracle.com>
+Signed-off-by: Alan Maguire <alan.maguire@oracle.com>
+Tested-by: Yipeng Zou <zouyipeng@huawei.com>
+Acked-by: Yonghong Song <yonghong.song@linux.dev>
+Link: https://lore.kernel.org/r/20230802073906.3197480-1-alan.maguire@oracle.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/progs/test_cls_redirect.h | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/tools/testing/selftests/bpf/progs/test_cls_redirect.h b/tools/testing/selftests/bpf/progs/test_cls_redirect.h
+index 76eab0aacba0c..233b089d1fbac 100644
+--- a/tools/testing/selftests/bpf/progs/test_cls_redirect.h
++++ b/tools/testing/selftests/bpf/progs/test_cls_redirect.h
+@@ -12,6 +12,15 @@
+ #include <linux/ipv6.h>
+ #include <linux/udp.h>
+
++/* offsetof() is used in static asserts, and the libbpf-redefined CO-RE
++ * friendly version breaks compilation for older clang versions <= 15
++ * when invoked in a static assert. Restore original here.
++ */
++#ifdef offsetof
++#undef offsetof
++#define offsetof(type, member) __builtin_offsetof(type, member)
++#endif
++
+ struct gre_base_hdr {
+ uint16_t flags;
+ uint16_t protocol;
+--
+2.40.1
+
--- /dev/null
+From 47a4b2be1dca331a92820b10e6c424eb65821eec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Aug 2023 13:39:27 +0530
+Subject: selftests/futex: Order calls to futex_lock_pi
+
+From: Nysal Jan K.A <nysal@linux.ibm.com>
+
+[ Upstream commit fbf4dec702774286db409815ffb077711a96b824 ]
+
+Observed occassional failures in the futex_wait_timeout test:
+
+ok 1 futex_wait relative succeeds
+ok 2 futex_wait_bitset realtime succeeds
+ok 3 futex_wait_bitset monotonic succeeds
+ok 4 futex_wait_requeue_pi realtime succeeds
+ok 5 futex_wait_requeue_pi monotonic succeeds
+not ok 6 futex_lock_pi realtime returned 0
+......
+
+The test expects the child thread to complete some steps before
+the parent thread gets to run. There is an implicit expectation
+of the order of invocation of futex_lock_pi between the child thread
+and the parent thread. Make this order explicit. If the order is
+not met, the futex_lock_pi call in the parent thread succeeds and
+will not timeout.
+
+Fixes: f4addd54b161 ("selftests: futex: Expand timeout test")
+Signed-off-by: Nysal Jan K.A <nysal@linux.ibm.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../selftests/futex/functional/futex_wait_timeout.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/tools/testing/selftests/futex/functional/futex_wait_timeout.c b/tools/testing/selftests/futex/functional/futex_wait_timeout.c
+index 3651ce17beeb9..d183f878360bc 100644
+--- a/tools/testing/selftests/futex/functional/futex_wait_timeout.c
++++ b/tools/testing/selftests/futex/functional/futex_wait_timeout.c
+@@ -24,6 +24,7 @@
+
+ static long timeout_ns = 100000; /* 100us default timeout */
+ static futex_t futex_pi;
++static pthread_barrier_t barrier;
+
+ void usage(char *prog)
+ {
+@@ -48,6 +49,8 @@ void *get_pi_lock(void *arg)
+ if (ret != 0)
+ error("futex_lock_pi failed\n", ret);
+
++ pthread_barrier_wait(&barrier);
++
+ /* Blocks forever */
+ ret = futex_wait(&lock, 0, NULL, 0);
+ error("futex_wait failed\n", ret);
+@@ -130,6 +133,7 @@ int main(int argc, char *argv[])
+ basename(argv[0]));
+ ksft_print_msg("\tArguments: timeout=%ldns\n", timeout_ns);
+
++ pthread_barrier_init(&barrier, NULL, 2);
+ pthread_create(&thread, NULL, get_pi_lock, NULL);
+
+ /* initialize relative timeout */
+@@ -163,6 +167,9 @@ int main(int argc, char *argv[])
+ res = futex_wait_requeue_pi(&f1, f1, &futex_pi, &to, 0);
+ test_timeout(res, &ret, "futex_wait_requeue_pi monotonic", ETIMEDOUT);
+
++ /* Wait until the other thread calls futex_lock_pi() */
++ pthread_barrier_wait(&barrier);
++ pthread_barrier_destroy(&barrier);
+ /*
+ * FUTEX_LOCK_PI with CLOCK_REALTIME
+ * Due to historical reasons, FUTEX_LOCK_PI supports only realtime
+--
+2.40.1
+
--- /dev/null
+From 38f034a90460bb4bc3ab496b5b8ea28e2e52fb98 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Aug 2023 10:43:58 -0700
+Subject: selftests/harness: Actually report SKIP for signal tests
+
+From: Kees Cook <keescook@chromium.org>
+
+[ Upstream commit b3d46e11fec0c5a8972e5061bb1462119ae5736d ]
+
+Tests that were expecting a signal were not correctly checking for a
+SKIP condition. Move the check before the signal checking when
+processing test result.
+
+Cc: Shuah Khan <shuah@kernel.org>
+Cc: Andy Lutomirski <luto@amacapital.net>
+Cc: Will Drewry <wad@chromium.org>
+Cc: linux-kselftest@vger.kernel.org
+Fixes: 9847d24af95c ("selftests/harness: Refactor XFAIL into SKIP")
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/kselftest_harness.h | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h
+index 5fd49ad0c696f..e05ac82610467 100644
+--- a/tools/testing/selftests/kselftest_harness.h
++++ b/tools/testing/selftests/kselftest_harness.h
+@@ -938,7 +938,11 @@ void __wait_for_test(struct __test_metadata *t)
+ fprintf(TH_LOG_STREAM,
+ "# %s: Test terminated by timeout\n", t->name);
+ } else if (WIFEXITED(status)) {
+- if (t->termsig != -1) {
++ if (WEXITSTATUS(status) == 255) {
++ /* SKIP */
++ t->passed = 1;
++ t->skip = 1;
++ } else if (t->termsig != -1) {
+ t->passed = 0;
+ fprintf(TH_LOG_STREAM,
+ "# %s: Test exited normally instead of by signal (code: %d)\n",
+@@ -950,11 +954,6 @@ void __wait_for_test(struct __test_metadata *t)
+ case 0:
+ t->passed = 1;
+ break;
+- /* SKIP */
+- case 255:
+- t->passed = 1;
+- t->skip = 1;
+- break;
+ /* Other failure, assume step report. */
+ default:
+ t->passed = 0;
+--
+2.40.1
+
--- /dev/null
+From 72bd734c80e90b27a080f8f3315ced3a31fc9565 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Aug 2023 18:40:57 +1000
+Subject: selftests: memfd: error out test process when child test fails
+
+From: Aleksa Sarai <cyphar@cyphar.com>
+
+[ Upstream commit 99f34659e78b9b781a3248e0b080b4dfca4957e2 ]
+
+Patch series "memfd: cleanups for vm.memfd_noexec", v2.
+
+The most critical issue with vm.memfd_noexec=2 (the fact that passing
+MFD_EXEC would bypass it entirely[1]) has been fixed in Andrew's
+tree[2], but there are still some outstanding issues that need to be
+addressed:
+
+ * vm.memfd_noexec=2 shouldn't reject old-style memfd_create(2) syscalls
+ because it will make it far to difficult to ever migrate. Instead it
+ should imply MFD_EXEC.
+
+ * The dmesg warnings are pr_warn_once(), which on most systems means
+ that they will be used up by systemd or some other boot process and
+ userspace developers will never see it.
+
+ - For the !(flags & (MFD_EXEC | MFD_NOEXEC_SEAL)) case, outputting a
+ rate-limited message to the kernel log is necessary to tell
+ userspace that they should add the new flags.
+
+ Arguably the most ideal way to deal with the spam concern[3,4]
+ while still prompting userspace to switch to the new flags would be
+ to only log the warning once per task or something similar.
+ However, adding something to task_struct for tracking this would be
+ needless bloat for a single pr_warn_ratelimited().
+
+ So just switch to pr_info_ratelimited() to avoid spamming the log
+ with something that isn't a real warning. There's lots of
+ info-level stuff in dmesg, it seems really unlikely that this
+ should be an actual problem. Most programs are already switching to
+ the new flags anyway.
+
+ - For the vm.memfd_noexec=2 case, we need to log a warning for every
+ failure because otherwise userspace will have no idea why their
+ previously working program started returning -EACCES (previously
+ -EINVAL) from memfd_create(2). pr_warn_once() is simply wrong here.
+
+ * The racheting mechanism for vm.memfd_noexec makes it incredibly
+ unappealing for most users to enable the sysctl because enabling it
+ on &init_pid_ns means you need a system reboot to unset it. Given the
+ actual security threat being protected against, CAP_SYS_ADMIN users
+ being restricted in this way makes little sense.
+
+ The argument for this ratcheting by the original author was that it
+ allows you to have a hierarchical setting that cannot be unset by
+ child pidnses, but this is not accurate -- changing the parent
+ pidns's vm.memfd_noexec setting to be more restrictive didn't affect
+ children.
+
+ Instead, switch the vm.memfd_noexec sysctl to be properly
+ hierarchical and allow CAP_SYS_ADMIN users (in the pidns's owning
+ userns) to lower the setting as long as it is not lower than the
+ parent's effective setting. This change also makes it so that
+ changing a parent pidns's vm.memfd_noexec will affect all
+ descendants, providing a properly hierarchical setting. The
+ performance impact of this is incredibly minimal since the maximum
+ depth of pidns is 32 and it is only checked during memfd_create(2)
+ and unshare(CLONE_NEWPID).
+
+ * The memfd selftests would not exit with a non-zero error code when
+ certain tests that ran in a forked process (specifically the ones
+ related to MFD_EXEC and MFD_NOEXEC_SEAL) failed.
+
+[1]: https://lore.kernel.org/all/ZJwcsU0vI-nzgOB_@codewreck.org/
+[2]: https://lore.kernel.org/all/20230705063315.3680666-1-jeffxu@google.com/
+[3]: https://lore.kernel.org/Y5yS8wCnuYGLHMj4@x1n/
+[4]: https://lore.kernel.org/f185bb42-b29c-977e-312e-3349eea15383@linuxfoundation.org/
+
+This patch (of 5):
+
+Before this change, a test runner using this self test would see a return
+code of 0 when the tests using a child process (namely the MFD_NOEXEC_SEAL
+and MFD_EXEC tests) failed, masking test failures.
+
+Link: https://lkml.kernel.org/r/20230814-memfd-vm-noexec-uapi-fixes-v2-0-7ff9e3e10ba6@cyphar.com
+Link: https://lkml.kernel.org/r/20230814-memfd-vm-noexec-uapi-fixes-v2-1-7ff9e3e10ba6@cyphar.com
+Fixes: 11f75a01448f ("selftests/memfd: add tests for MFD_NOEXEC_SEAL MFD_EXEC")
+Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
+Reviewed-by: Jeff Xu <jeffxu@google.com>
+Cc: "Christian Brauner (Microsoft)" <brauner@kernel.org>
+Cc: Daniel Verkamp <dverkamp@chromium.org>
+Cc: Dominique Martinet <asmadeus@codewreck.org>
+Cc: Kees Cook <keescook@chromium.org>
+Cc: Shuah Khan <shuah@kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/memfd/memfd_test.c | 19 ++++++++++++++++++-
+ 1 file changed, 18 insertions(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/memfd/memfd_test.c b/tools/testing/selftests/memfd/memfd_test.c
+index dba0e8ba002f8..7fc5d7c3bd65b 100644
+--- a/tools/testing/selftests/memfd/memfd_test.c
++++ b/tools/testing/selftests/memfd/memfd_test.c
+@@ -1202,7 +1202,24 @@ static pid_t spawn_newpid_thread(unsigned int flags, int (*fn)(void *))
+
+ static void join_newpid_thread(pid_t pid)
+ {
+- waitpid(pid, NULL, 0);
++ int wstatus;
++
++ if (waitpid(pid, &wstatus, 0) < 0) {
++ printf("newpid thread: waitpid() failed: %m\n");
++ abort();
++ }
++
++ if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus) != 0) {
++ printf("newpid thread: exited with non-zero error code %d\n",
++ WEXITSTATUS(wstatus));
++ abort();
++ }
++
++ if (WIFSIGNALED(wstatus)) {
++ printf("newpid thread: killed by signal %d\n",
++ WTERMSIG(wstatus));
++ abort();
++ }
+ }
+
+ /*
+--
+2.40.1
+
--- /dev/null
+From 253831a8a6a7fd8e3d95abb76de42ad3081fdc7a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Jul 2023 16:14:49 +0300
+Subject: selftests/resctrl: Add resctrl.h into build deps
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit 8e289f4542890168705219e54f0231dccfabddbe ]
+
+Makefile only lists *.c as build dependencies for the resctrl_tests
+executable which excludes resctrl.h.
+
+Add *.h to wildcard() to include resctrl.h.
+
+Fixes: 591a6e8588fc ("selftests/resctrl: Add basic resctrl file system operations and data")
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Reviewed-by: Reinette Chatre <reinette.chatre@intel.com>
+Tested-by: Babu Moger <babu.moger@amd.com>
+Tested-by: Shaopeng Tan (Fujitsu) <tan.shaopeng@fujitsu.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/resctrl/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/resctrl/Makefile b/tools/testing/selftests/resctrl/Makefile
+index 73d53257df42f..5073dbc961258 100644
+--- a/tools/testing/selftests/resctrl/Makefile
++++ b/tools/testing/selftests/resctrl/Makefile
+@@ -7,4 +7,4 @@ TEST_GEN_PROGS := resctrl_tests
+
+ include ../lib.mk
+
+-$(OUTPUT)/resctrl_tests: $(wildcard *.c)
++$(OUTPUT)/resctrl_tests: $(wildcard *.[ch])
+--
+2.40.1
+
--- /dev/null
+From 296b2da2ec44440c479a1ed2cceaeec0626582bf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Jul 2023 16:14:52 +0300
+Subject: selftests/resctrl: Close perf value read fd on errors
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit 51a0c3b7f028169e40db930575dd01fe81c3e765 ]
+
+Perf event fd (fd_lm) is not closed when run_fill_buf() returns error.
+
+Close fd_lm only in cat_val() to make it easier to track it is always
+closed.
+
+Fixes: 790bf585b0ee ("selftests/resctrl: Add Cache Allocation Technology (CAT) selftest")
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Tested-by: Babu Moger <babu.moger@amd.com>
+Tested-by: Shaopeng Tan (Fujitsu) <tan.shaopeng@fujitsu.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/resctrl/cache.c | 18 +++++++++++-------
+ 1 file changed, 11 insertions(+), 7 deletions(-)
+
+diff --git a/tools/testing/selftests/resctrl/cache.c b/tools/testing/selftests/resctrl/cache.c
+index 8a4fe8693be63..289b619116fec 100644
+--- a/tools/testing/selftests/resctrl/cache.c
++++ b/tools/testing/selftests/resctrl/cache.c
+@@ -87,21 +87,19 @@ static int reset_enable_llc_perf(pid_t pid, int cpu_no)
+ static int get_llc_perf(unsigned long *llc_perf_miss)
+ {
+ __u64 total_misses;
++ int ret;
+
+ /* Stop counters after one span to get miss rate */
+
+ ioctl(fd_lm, PERF_EVENT_IOC_DISABLE, 0);
+
+- if (read(fd_lm, &rf_cqm, sizeof(struct read_format)) == -1) {
++ ret = read(fd_lm, &rf_cqm, sizeof(struct read_format));
++ if (ret == -1) {
+ perror("Could not get llc misses through perf");
+-
+ return -1;
+ }
+
+ total_misses = rf_cqm.values[0].value;
+-
+- close(fd_lm);
+-
+ *llc_perf_miss = total_misses;
+
+ return 0;
+@@ -253,19 +251,25 @@ int cat_val(struct resctrl_val_param *param)
+ memflush, operation, resctrl_val)) {
+ fprintf(stderr, "Error-running fill buffer\n");
+ ret = -1;
+- break;
++ goto pe_close;
+ }
+
+ sleep(1);
+ ret = measure_cache_vals(param, bm_pid);
+ if (ret)
+- break;
++ goto pe_close;
++
++ close(fd_lm);
+ } else {
+ break;
+ }
+ }
+
+ return ret;
++
++pe_close:
++ close(fd_lm);
++ return ret;
+ }
+
+ /*
+--
+2.40.1
+
--- /dev/null
+From f46c5bcbed2342aba10de74a1b6b06354c2eb200 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Jul 2023 16:14:50 +0300
+Subject: selftests/resctrl: Don't leak buffer in fill_cache()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit 2d320b1029ee7329ee0638181be967789775b962 ]
+
+The error path in fill_cache() does return before the allocated buffer
+is freed leaking the buffer.
+
+The leak was introduced when fill_cache_read() started to return errors
+in commit c7b607fa9325 ("selftests/resctrl: Fix null pointer
+dereference on open failed"), before that both fill functions always
+returned 0.
+
+Move free() earlier to prevent the mem leak.
+
+Fixes: c7b607fa9325 ("selftests/resctrl: Fix null pointer dereference on open failed")
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Reviewed-by: Reinette Chatre <reinette.chatre@intel.com>
+Tested-by: Babu Moger <babu.moger@amd.com>
+Tested-by: Shaopeng Tan (Fujitsu) <tan.shaopeng@fujitsu.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/resctrl/fill_buf.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/resctrl/fill_buf.c b/tools/testing/selftests/resctrl/fill_buf.c
+index 341cc93ca84c4..3b328c8448964 100644
+--- a/tools/testing/selftests/resctrl/fill_buf.c
++++ b/tools/testing/selftests/resctrl/fill_buf.c
+@@ -177,12 +177,13 @@ fill_cache(unsigned long long buf_size, int malloc_and_init, int memflush,
+ else
+ ret = fill_cache_write(start_ptr, end_ptr, resctrl_val);
+
++ free(startptr);
++
+ if (ret) {
+ printf("\n Error in fill cache read/write...\n");
+ return -1;
+ }
+
+- free(startptr);
+
+ return 0;
+ }
+--
+2.40.1
+
--- /dev/null
+From bfa4e77436499b569b2c2452642f7e30c3f2e922 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Jul 2023 16:14:51 +0300
+Subject: selftests/resctrl: Unmount resctrl FS if child fails to run benchmark
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit f99e413eb54652e2436cc56d081176bc9a34cd8d ]
+
+A child calls PARENT_EXIT() when it fails to run a benchmark to kill
+the parent process. PARENT_EXIT() lacks unmount for the resctrl FS and
+the parent won't be there to unmount it either after it gets killed.
+
+Add the resctrl FS unmount also to PARENT_EXIT().
+
+Fixes: 591a6e8588fc ("selftests/resctrl: Add basic resctrl file system operations and data")
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Reviewed-by: Reinette Chatre <reinette.chatre@intel.com>
+Tested-by: Babu Moger <babu.moger@amd.com>
+Tested-by: Shaopeng Tan (Fujitsu) <tan.shaopeng@fujitsu.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/resctrl/resctrl.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/tools/testing/selftests/resctrl/resctrl.h b/tools/testing/selftests/resctrl/resctrl.h
+index 87e39456dee08..f455f0b7e314b 100644
+--- a/tools/testing/selftests/resctrl/resctrl.h
++++ b/tools/testing/selftests/resctrl/resctrl.h
+@@ -43,6 +43,7 @@
+ do { \
+ perror(err_msg); \
+ kill(ppid, SIGKILL); \
++ umount_resctrlfs(); \
+ exit(EXIT_FAILURE); \
+ } while (0)
+
+--
+2.40.1
+
--- /dev/null
+From e01a1012684cf104da5efca61722ef79fd4b39e0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Jul 2023 14:40:52 +0800
+Subject: serial: sprd: Assign sprd_port after initialized to avoid wrong
+ access
+
+From: Chunyan Zhang <chunyan.zhang@unisoc.com>
+
+[ Upstream commit f9608f1887568b728839d006024585ab02ef29e5 ]
+
+The global pointer 'sprd_port' may not zero when sprd_probe returns
+failure, that is a risk for sprd_port to be accessed afterward, and
+may lead to unexpected errors.
+
+For example:
+
+There are two UART ports, UART1 is used for console and configured in
+kernel command line, i.e. "console=";
+
+The UART1 probe failed and the memory allocated to sprd_port[1] was
+released, but sprd_port[1] was not set to NULL;
+
+In UART2 probe, the same virtual address was allocated to sprd_port[2],
+and UART2 probe process finally will go into sprd_console_setup() to
+register UART1 as console since it is configured as preferred console
+(filled to console_cmdline[]), but the console parameters (sprd_port[1])
+belong to UART2.
+
+So move the sprd_port[] assignment to where the port already initialized
+can avoid the above issue.
+
+Fixes: b7396a38fb28 ("tty/serial: Add Spreadtrum sc9836-uart driver support")
+Signed-off-by: Chunyan Zhang <chunyan.zhang@unisoc.com>
+Link: https://lore.kernel.org/r/20230725064053.235448-1-chunyan.zhang@unisoc.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/sprd_serial.c | 25 +++++++++++++++++--------
+ 1 file changed, 17 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_serial.c
+index b58f51296ace2..fc1377029021b 100644
+--- a/drivers/tty/serial/sprd_serial.c
++++ b/drivers/tty/serial/sprd_serial.c
+@@ -1106,7 +1106,7 @@ static bool sprd_uart_is_console(struct uart_port *uport)
+ static int sprd_clk_init(struct uart_port *uport)
+ {
+ struct clk *clk_uart, *clk_parent;
+- struct sprd_uart_port *u = sprd_port[uport->line];
++ struct sprd_uart_port *u = container_of(uport, struct sprd_uart_port, port);
+
+ clk_uart = devm_clk_get(uport->dev, "uart");
+ if (IS_ERR(clk_uart)) {
+@@ -1149,22 +1149,22 @@ static int sprd_probe(struct platform_device *pdev)
+ {
+ struct resource *res;
+ struct uart_port *up;
++ struct sprd_uart_port *sport;
+ int irq;
+ int index;
+ int ret;
+
+ index = of_alias_get_id(pdev->dev.of_node, "serial");
+- if (index < 0 || index >= ARRAY_SIZE(sprd_port)) {
++ if (index < 0 || index >= UART_NR_MAX) {
+ dev_err(&pdev->dev, "got a wrong serial alias id %d\n", index);
+ return -EINVAL;
+ }
+
+- sprd_port[index] = devm_kzalloc(&pdev->dev, sizeof(*sprd_port[index]),
+- GFP_KERNEL);
+- if (!sprd_port[index])
++ sport = devm_kzalloc(&pdev->dev, sizeof(*sport), GFP_KERNEL);
++ if (!sport)
+ return -ENOMEM;
+
+- up = &sprd_port[index]->port;
++ up = &sport->port;
+ up->dev = &pdev->dev;
+ up->line = index;
+ up->type = PORT_SPRD;
+@@ -1195,7 +1195,7 @@ static int sprd_probe(struct platform_device *pdev)
+ * Allocate one dma buffer to prepare for receive transfer, in case
+ * memory allocation failure at runtime.
+ */
+- ret = sprd_rx_alloc_buf(sprd_port[index]);
++ ret = sprd_rx_alloc_buf(sport);
+ if (ret)
+ return ret;
+
+@@ -1206,14 +1206,23 @@ static int sprd_probe(struct platform_device *pdev)
+ return ret;
+ }
+ }
++
+ sprd_ports_num++;
++ sprd_port[index] = sport;
+
+ ret = uart_add_one_port(&sprd_uart_driver, up);
+ if (ret)
+- sprd_remove(pdev);
++ goto clean_port;
+
+ platform_set_drvdata(pdev, up);
+
++ return 0;
++
++clean_port:
++ sprd_port[index] = NULL;
++ if (--sprd_ports_num == 0)
++ uart_unregister_driver(&sprd_uart_driver);
++ sprd_rx_free_buf(sport);
+ return ret;
+ }
+
+--
+2.40.1
+
--- /dev/null
+From 1a5013848deb1fc7fc22daa7bd8c62432ea06852 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Jul 2023 14:40:53 +0800
+Subject: serial: sprd: Fix DMA buffer leak issue
+
+From: Chunyan Zhang <chunyan.zhang@unisoc.com>
+
+[ Upstream commit cd119fdc3ee1450fbf7f78862b5de44c42b6e47f ]
+
+Release DMA buffer when _probe() returns failure to avoid memory leak.
+
+Fixes: f4487db58eb7 ("serial: sprd: Add DMA mode support")
+Signed-off-by: Chunyan Zhang <chunyan.zhang@unisoc.com>
+Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
+Link: https://lore.kernel.org/r/20230725064053.235448-2-chunyan.zhang@unisoc.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/sprd_serial.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_serial.c
+index fc1377029021b..99da964e8bd44 100644
+--- a/drivers/tty/serial/sprd_serial.c
++++ b/drivers/tty/serial/sprd_serial.c
+@@ -364,7 +364,7 @@ static void sprd_rx_free_buf(struct sprd_uart_port *sp)
+ if (sp->rx_dma.virt)
+ dma_free_coherent(sp->port.dev, SPRD_UART_RX_SIZE,
+ sp->rx_dma.virt, sp->rx_dma.phys_addr);
+-
++ sp->rx_dma.virt = NULL;
+ }
+
+ static int sprd_rx_dma_config(struct uart_port *port, u32 burst)
+@@ -1203,7 +1203,7 @@ static int sprd_probe(struct platform_device *pdev)
+ ret = uart_register_driver(&sprd_uart_driver);
+ if (ret < 0) {
+ pr_err("Failed to register SPRD-UART driver\n");
+- return ret;
++ goto free_rx_buf;
+ }
+ }
+
+@@ -1222,6 +1222,7 @@ static int sprd_probe(struct platform_device *pdev)
+ sprd_port[index] = NULL;
+ if (--sprd_ports_num == 0)
+ uart_unregister_driver(&sprd_uart_driver);
++free_rx_buf:
+ sprd_rx_free_buf(sport);
+ return ret;
+ }
+--
+2.40.1
+
--- /dev/null
+From 243579211eebab68b1d6c1f12e8b08599ee67e1e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Aug 2023 18:54:06 +0800
+Subject: serial: tegra: handle clk prepare error in tegra_uart_hw_init()
+
+From: Yi Yang <yiyang13@huawei.com>
+
+[ Upstream commit 5abd01145d0cc6cd1b7c2fe6ee0b9ea0fa13671e ]
+
+In tegra_uart_hw_init(), the return value of clk_prepare_enable() should
+be checked since it might fail.
+
+Fixes: e9ea096dd225 ("serial: tegra: add serial driver")
+Signed-off-by: Yi Yang <yiyang13@huawei.com>
+Link: https://lore.kernel.org/r/20230817105406.228674-1-yiyang13@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/serial-tegra.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c
+index 1cf08b33456c9..37e1e05bc87e6 100644
+--- a/drivers/tty/serial/serial-tegra.c
++++ b/drivers/tty/serial/serial-tegra.c
+@@ -998,7 +998,11 @@ static int tegra_uart_hw_init(struct tegra_uart_port *tup)
+ tup->ier_shadow = 0;
+ tup->current_baud = 0;
+
+- clk_prepare_enable(tup->uart_clk);
++ ret = clk_prepare_enable(tup->uart_clk);
++ if (ret) {
++ dev_err(tup->uport.dev, "could not enable clk\n");
++ return ret;
++ }
+
+ /* Reset the UART controller to clear all previous status.*/
+ reset_control_assert(tup->rst);
+--
+2.40.1
+
revert-fuse-in-fuse_flush-only-wait-if-someone-wants-the-return-code.patch
revert-pci-tegra194-enable-support-for-256-byte-payload.patch
revert-net-macsec-preserve-ingress-frame-ordering.patch
+reiserfs-check-the-return-value-from-__getblk.patch
+splice-always-fsnotify_access-in-fsnotify_modify-out.patch
+splice-fsnotify_access-fd-fsnotify_modify-fd-in-vmsp.patch
+splice-fsnotify_access-in-fsnotify_modify-out-on-suc.patch
+eventfd-prevent-underflow-for-eventfd-semaphores.patch
+fs-fix-error-checking-for-d_hash_and_lookup.patch
+iomap-remove-large-folio-handling-in-iomap_invalidat.patch
+tmpfs-verify-g-u-id-mount-options-correctly.patch
+selftests-harness-actually-report-skip-for-signal-te.patch
+vfs-security-fix-automount-superblock-lsm-init-probl.patch
+arm-ptrace-restore-syscall-restart-tracing.patch
+arm-ptrace-restore-syscall-skipping-for-tracers.patch
+locking-arch-avoid-variable-shadowing-in-local_try_c.patch
+refscale-fix-uninitalized-use-of-wait_queue_head_t.patch
+clocksource-handle-negative-skews-in-skew-is-too-lar.patch
+powercap-arm_scmi-remove-recursion-while-parsing-zon.patch
+opp-fix-passing-0-to-ptr_err-in-_opp_attach_genpd.patch
+selftests-resctrl-add-resctrl.h-into-build-deps.patch
+selftests-resctrl-don-t-leak-buffer-in-fill_cache.patch
+selftests-resctrl-unmount-resctrl-fs-if-child-fails-.patch
+selftests-resctrl-close-perf-value-read-fd-on-errors.patch
+arm64-ptrace-clean-up-error-handling-path-in-sve_set.patch
+sched-psi-select-kernfs-as-needed.patch
+cpuidle-teo-update-idle-duration-estimate-when-choos.patch
+x86-decompressor-don-t-rely-on-upper-32-bits-of-gprs.patch
+arm64-fpsimd-only-provide-the-length-to-cpufeature-f.patch
+sched-rt-fix-sysctl_sched_rr_timeslice-intial-value.patch
+perf-imx_ddr-don-t-enable-counter0-if-none-of-4-coun.patch
+selftests-futex-order-calls-to-futex_lock_pi.patch
+s390-pkey-fix-harmonize-internal-keyblob-headers.patch
+s390-pkey-fix-pkey_type_ep11_aes-handling-in-pkey_ge.patch
+s390-pkey-fix-pkey_type_ep11_aes-handling-for-sysfs-.patch
+s390-paes-fix-pkey_type_ep11_aes-handling-for-secure.patch
+irqchip-loongson-eiointc-fix-return-value-checking-o.patch
+acpi-x86-s2idle-post-increment-variables-when-gettin.patch
+acpi-x86-s2idle-fix-a-logic-error-parsing-amd-constr.patch
+thermal-of-fix-potential-uninitialized-value-access.patch
+cpufreq-amd-pstate-ut-remove-module-parameter-access.patch
+cpufreq-amd-pstate-ut-fix-kernel-panic-when-loading-.patch
+x86-efistub-fix-pci-rom-preservation-in-mixed-mode.patch
+cpufreq-powernow-k8-use-related_cpus-instead-of-cpus.patch
+cpufreq-tegra194-add-online-offline-hooks.patch
+cpufreq-tegra194-remove-opp-table-in-exit-hook.patch
+selftests-bpf-fix-bpf_nf-failure-upon-test-rerun.patch
+libbpf-only-reset-sec_def-handler-when-necessary.patch
+bpftool-use-a-local-copy-of-perf_event-to-fix-access.patch
+bpftool-define-a-local-bpf_perf_link-to-fix-accessin.patch
+bpftool-use-a-local-copy-of-bpf_link_type_perf_event.patch
+bpftool-use-a-local-bpf_perf_event_value-to-fix-acce.patch
+libbpf-fix-realloc-api-handling-in-zero-sized-edge-c.patch
+bpf-clear-the-probe_addr-for-uprobe.patch
+bpf-fix-an-error-around-ptr_untrusted.patch
+bpf-fix-an-error-in-verifying-a-field-in-a-union.patch
+crypto-qat-change-value-of-default-idle-filter.patch
+tcp-tcp_enter_quickack_mode-should-be-static.patch
+hwrng-nomadik-keep-clock-enabled-while-hwrng-is-regi.patch
+hwrng-pic32-use-devm_clk_get_enabled.patch
+regmap-load-register-defaults-in-blocks-rather-than-.patch
+regmap-maple-use-alloc_flags-for-memory-allocations.patch
+regmap-rbtree-use-alloc_flags-for-memory-allocations.patch
+wifi-rtw89-debug-fix-error-handling-in-rtw89_debug_p.patch
+wifi-mt76-mt7996-fix-header-translation-logic.patch
+wifi-mt76-mt7915-fix-background-radar-event-being-bl.patch
+wifi-mt76-mt7915-rework-tx-packets-counting-when-wed.patch
+wifi-mt76-mt7915-rework-tx-bytes-counting-when-wed-i.patch
+wifi-mt76-mt7921-fix-non-psc-channel-scan-fail.patch
+wifi-mt76-mt7996-fix-bss-wlan_idx-when-sending-bss_i.patch
+wifi-mt76-mt7996-use-correct-phy-for-background-rada.patch
+wifi-mt76-mt7996-fix-wa-event-ring-size.patch
+udp-re-score-reuseport-groups-when-connected-sockets.patch
+bpf-reject-unhashed-sockets-in-bpf_sk_assign.patch
+net-export-inet_lookup_reuseport-and-inet6_lookup_re.patch
+net-remove-duplicate-reuseport_lookup-functions.patch
+bpf-net-support-so_reuseport-sockets-with-bpf_sk_ass.patch
+wifi-mt76-mt7915-fix-command-timeout-in-ap-stop-peri.patch
+wifi-mt76-mt7915-fix-capabilities-in-non-ap-mode.patch
+wifi-mt76-mt7915-remove-vht160-capability-on-mt7915.patch
+wifi-mt76-testmode-add-nla_policy-for-mt76_tm_attr_t.patch
+spi-tegra20-sflash-fix-to-check-return-value-of-plat.patch
+can-gs_usb-gs_usb_receive_bulk_callback-count-rx-ove.patch
+can-tcan4x5x-remove-reserved-register-0x814-from-wri.patch
+wifi-mt76-mt7915-fix-tlv-length-of-mt7915_mcu_get_ch.patch
+wifi-mt76-mt7915-fix-power-limits-while-chan_switch.patch
+wifi-rtw89-fix-loading-of-compressed-firmware.patch
+wifi-mwifiex-fix-oob-and-integer-underflow-when-rx-p.patch
+wifi-mwifiex-fix-error-recovery-in-pcie-buffer-descr.patch
+wifi-ath11k-fix-band-selection-for-ppdu-received-in-.patch
+wifi-ath12k-fix-memcpy-array-overflow-in-ath12k_peer.patch
+selftests-bpf-fix-static-assert-compilation-issue-fo.patch
+spi-mpc5xxx-psc-fix-unsigned-expression-compared-wit.patch
+bpf-fix-bpf_dynptr_slice-to-stop-return-an-err_ptr.patch
+kbuild-rust_is_available-remove-v-option.patch
+kbuild-rust_is_available-fix-version-check-when-cc-h.patch
+kbuild-rust_is_available-add-check-for-bindgen-invoc.patch
+kbuild-rust_is_available-fix-confusion-when-a-versio.patch
+crypto-stm32-properly-handle-pm_runtime_get-failing.patch
+crypto-api-use-work-queue-in-crypto_destroy_instance.patch
+bluetooth-hci_event-fix-parsing-of-cis-established-e.patch
+bluetooth-iso-add-support-for-connecting-multiple-bi.patch
+bluetooth-iso-do-not-emit-new-le-create-cis-if-previ.patch
+bluetooth-nokia-fix-value-check-in-nokia_bluetooth_s.patch
+bluetooth-iso-fix-not-checking-for-valid-cig-cis-ids.patch
+bluetooth-hci_conn-fix-not-allowing-valid-cis-id.patch
+bluetooth-hci_conn-use-kmemdup-to-replace-kzalloc-me.patch
+bluetooth-hci_conn-fix-hci_le_set_cig_params.patch
+bluetooth-fix-potential-use-after-free-when-clear-ke.patch
+bluetooth-hci_sync-don-t-double-print-name-in-add-re.patch
+bluetooth-hci_sync-avoid-use-after-free-in-dbg-for-h.patch
+bluetooth-hci_conn-always-allocate-unique-handles.patch
+bluetooth-hci_event-drop-only-unbound-cis-if-set-cig.patch
+net-tcp-fix-unexcepted-socket-die-when-snd_wnd-is-0.patch
+selftests-bpf-fix-repeat-option-when-kfunc_call-veri.patch
+selftests-bpf-clean-up-fmod_ret-in-bench_rename-test.patch
+spi-tegra114-remove-unnecessary-null-pointer-checks.patch
+net-fix-slab-out-of-bounds-in-inet-6-_steal_sock.patch
+net-hns3-move-dump-regs-function-to-a-separate-file.patch
+net-hns3-support-tlv-in-regs-data-for-hns3-pf-driver.patch
+net-hns3-fix-wrong-rpu-tln-reg-issue.patch
+net-memcg-fix-scope-of-sockmem-pressure-indicators.patch
+ice-ice_aq_check_events-fix-off-by-one-check-when-fi.patch
+crypto-caam-fix-unchecked-return-value-error.patch
+hwrng-iproc-rng200-implement-suspend-and-resume-call.patch
+lwt-fix-return-values-of-bpf-xmit-ops.patch
+lwt-check-lwtunnel_xmit_continue-strictly.patch
+scripts-gdb-fix-lx-lsmod-show-the-wrong-size.patch
+fs-ocfs2-namei-check-return-value-of-ocfs2_add_entry.patch
+net-lan966x-fix-return-value-check-for-vcap_get_rule.patch
+net-annotate-data-races-around-sk-sk_lingertime.patch
+wifi-mwifiex-fix-memory-leak-in-mwifiex_histogram_re.patch
+wifi-mwifiex-fix-missed-return-in-oob-checks-failed-.patch
+wifi-rtw89-8852b-rfk-fine-tune-iqk-parameters-to-imp.patch
+selftests-memfd-error-out-test-process-when-child-te.patch
+arm-dts-add-.dts-files-missing-from-the-build.patch
+samples-bpf-fix-bio-latency-check-with-tracepoint.patch
+samples-bpf-fix-broken-map-lookup-probe.patch
+wifi-ath9k-fix-races-between-ath9k_wmi_cmd-and-ath9k.patch
+wifi-ath9k-protect-wmi-command-response-buffer-repla.patch
+bpf-fix-a-bpf_kptr_xchg-issue-with-local-kptr.patch
+wifi-mac80211-fix-puncturing-bitmap-handling-in-csa.patch
+wifi-nl80211-cfg80211-add-forgotten-nla_policy-for-b.patch
+mac80211-make-ieee80211_tx_info-padding-explicit.patch
+bpf-fix-check_func_arg_reg_off-bug-for-graph-root-no.patch
+wifi-mwifiex-avoid-possible-null-skb-pointer-derefer.patch
+bluetooth-hci_conn-consolidate-code-for-aborting-con.patch
+bluetooth-iso-notify-user-space-about-failed-bis-con.patch
+bluetooth-hci_sync-fix-uaf-on-hci_abort_conn_sync.patch
+bluetooth-hci_sync-fix-uaf-in-hci_disconnect_all_syn.patch
+bluetooth-hci_conn-fail-sco-iso-via-hci_conn_failed-.patch
+bluetooth-btusb-do-not-call-kfree_skb-under-spin_loc.patch
+arm64-mm-use-ptep_clear-instead-of-pte_clear-in-clea.patch
+net-mlx5-dynamic-cyclecounter-shift-calculation-for-.patch
+wifi-ath9k-use-is_err-with-debugfs_create_dir.patch
+ice-avoid-executing-commands-on-other-ports-when-dri.patch
+net-arcnet-do-not-call-kfree_skb-under-local_irq_dis.patch
+mlxsw-i2c-fix-chunk-size-setting-in-output-mailbox-b.patch
+mlxsw-i2c-limit-single-transaction-buffer-size.patch
+mlxsw-core_hwmon-adjust-module-label-names-based-on-.patch
+hwmon-tmp513-fix-the-channel-number-in-tmp51x_is_vis.patch
+octeontx2-pf-refactor-schedular-queue-alloc-free-cal.patch
+octeontx2-pf-fix-pfc-tx-scheduler-free.patch
+octeontx2-af-cn10kb-fix-pfc-configuration.patch
+cteonxt2-pf-fix-backpressure-config-for-multiple-pfc.patch
+sfc-check-firmware-supports-ethernet-ptp-filter.patch
+net-sched-sch_hfsc-ensure-inner-classes-have-fsc-cur.patch
+pds_core-protect-devlink-callbacks-from-fw_down-stat.patch
+pds_core-no-health-reporter-in-vf.patch
+pds_core-no-reset-command-for-vf.patch
+pds_core-check-for-work-queue-before-use.patch
+pds_core-pass-opcode-to-devcmd_wait.patch
+netrom-deny-concurrent-connect.patch
+drm-bridge-tc358764-fix-debug-print-parameter-order.patch
+asoc-soc-compress-fix-deadlock-in-soc_compr_open_fe.patch
+asoc-cs43130-fix-numerator-denominator-mixup.patch
+drm-bridge-dw-mipi-dsi-fix-enable-disable-of-dsi-con.patch
+quota-factor-out-dquot_write_dquot.patch
+quota-rename-dquot_active-to-inode_quota_active.patch
+quota-add-new-helper-dquot_active.patch
+quota-fix-dqput-to-follow-the-guarantees-dquot_srcu-.patch
+drm-amd-display-do-not-set-drr-on-pipe-commit.patch
+drm-hyperv-fix-a-compilation-issue-because-of-not-in.patch
+asoc-stac9766-fix-build-errors-with-regmap_ac97.patch
+soc-qcom-ocmem-add-ocmem-hardware-version-print.patch
+soc-qcom-ocmem-fix-num_ports-num_macros-macros.patch
+arm64-defconfig-enable-qualcomm-msm8996-global-clock.patch
+arm64-dts-qcom-sm8150-use-proper-dsi-phy-compatible.patch
+arm64-dts-qcom-sm6350-fix-zap-region.patch
+arm64-dts-qcom-sm8250-correct-dynamic-power-coeffici.patch
+arm64-dts-qcom-msm8916-l8150-correct-light-sensor-vd.patch
+arm64-dts-qcom-sm8250-edo-add-gpio-line-names-for-tl.patch
+arm64-dts-qcom-sm8250-edo-add-gpio-line-names-for-pm.patch
+arm64-dts-qcom-sm8250-edo-rectify-gpio-keys.patch
+arm64-dts-qcom-sc8280xp-crd-correct-vreg_misc_3p3-gp.patch
+arm64-dts-qcom-sc8280xp-add-missing-scm-interconnect.patch
+arm64-dts-qcom-msm8996-add-missing-interrupt-to-the-.patch
+arm64-dts-qcom-sdm845-tama-set-serial-indices-and-st.patch
+arm64-dts-qcom-sm8350-fix-cpu-idle-state-residency-t.patch
+arm64-dts-qcom-sm8350-add-missing-lmh-interrupts-to-.patch
+arm64-dts-qcom-sm8350-use-proper-cpu-compatibles.patch
+arm64-dts-qcom-pm8350-fix-thermal-zone-name.patch
+arm64-dts-qcom-pm8350b-fix-thermal-zone-name.patch
+arm64-dts-qcom-pmr735b-fix-thermal-zone-name.patch
+arm64-dts-qcom-pmk8350-fix-adc-tm-compatible-string.patch
+arm64-dts-qcom-sm8450-hdk-remove-pmr735b-pmic-inclus.patch
+arm64-dts-qcom-sm8250-mark-pcie-hosts-as-dma-coheren.patch
+arm-dts-stm32-adopt-generic-iio-bindings-for-adc-cha.patch
+arm-dts-stm32-add-missing-detach-mailbox-for-emtrion.patch
+arm-dts-stm32-add-missing-detach-mailbox-for-odyssey.patch
+arm-dts-stm32-update-to-generic-adc-channel-binding-.patch
+arm-dts-stm32-add-missing-detach-mailbox-for-dhcom-s.patch
+arm-dts-stm32-add-missing-detach-mailbox-for-dhcor-s.patch
+firmware-ti_sci-use-system_state-to-determine-pollin.patch
+drm-amdgpu-avoid-integer-overflow-warning-in-amdgpu_.patch
+arm-dts-bcm53573-drop-nonexistent-default-off-led-tr.patch
+arm-dts-bcm53573-drop-nonexistent-usb-cells.patch
+arm-dts-bcm53573-add-cells-sizes-to-pcie-node.patch
+arm-dts-bcm53573-use-updated-spi-gpio-binding-proper.patch
+arm64-tegra-fix-hsuart-for-jetson-agx-orin.patch
+arm64-dts-qcom-sm8250-sony-xperia-correct-gpio-keys-.patch
+arm64-dts-qcom-pm6150l-add-missing-short-interrupt.patch
+arm64-dts-qcom-pm660l-add-missing-short-interrupt.patch
+arm64-dts-qcom-pmi8950-add-missing-ovp-interrupt.patch
+arm64-dts-qcom-pmi8994-add-missing-ovp-interrupt.patch
+arm64-tegra-fix-hsuart-for-smaug.patch
+drm-etnaviv-fix-dumping-of-active-mmu-context.patch
+block-cleanup-queue_wc_store.patch
+block-don-t-allow-enabling-a-cache-on-devices-that-d.patch
+x86-mm-fix-pat-bit-missing-from-page-protection-modi.patch
+drm-bridge-anx7625-use-common-macros-for-dp-power-se.patch
+drm-bridge-anx7625-use-common-macros-for-hdcp-capabi.patch
+arm-dts-samsung-s3c6410-mini6410-correct-ethernet-re.patch
+arm-dts-s5pv210-add-dummy-5v-regulator-for-backlight.patch
+arm-dts-samsung-s5pv210-smdkv210-correct-ethernet-re.patch
+drm-adv7511-fix-low-refresh-rate-register-for-adv753.patch
+arm-dts-bcm53573-fix-ethernet-info-for-luxul-devices.patch
+arm64-dts-qcom-sdm845-add-missing-rpmh-power-domain-.patch
+arm64-dts-qcom-sdm845-fix-the-min-frequency-of-ice_c.patch
+arm64-dts-qcom-msm8996-gemini-fix-touchscreen-vio-su.patch
+drm-amdgpu-update-min-to-min_t-in-amdgpu_info_ioctl.patch
+arm64-dts-rockchip-fix-pcie-regulators-on-radxa-e25.patch
+arm64-dts-rockchip-enable-sata-on-radxa-e25.patch
+asoc-fsl-fsl_qmc_audio-fix-snd_pcm_format_t-values-h.patch
+md-restore-noio_flag-for-the-last-mddev_resume.patch
+md-raid10-factor-out-dereference_rdev_and_rrdev.patch
+md-raid10-use-dereference_rdev_and_rrdev-to-get-devi.patch
+md-md-bitmap-remove-unnecessary-local-variable-in-ba.patch
+md-md-bitmap-hold-reconfig_mutex-in-backlog_store.patch
+drm-msm-update-dev-core-dump-to-not-print-backwards.patch
+drm-tegra-dpaux-fix-incorrect-return-value-of-platfo.patch
+of-unittest-fix-null-pointer-dereferencing-in-of_uni.patch
+arm64-dts-qcom-sm8150-fix-the-i2c7-interrupt.patch
+drm-ast-report-connection-status-on-display-port.patch
+arm-dts-bcm53573-fix-tenda-ac9-switch-cpu-port.patch
+drm-armada-fix-off-by-one-error-in-armada_overlay_ge.patch
+drm-repaper-reduce-temporary-buffer-size-in-repaper_.patch
+drm-panel-simple-add-missing-connector-type-and-pixe.patch
+ima-remove-deprecated-ima_trusted_keyring-kconfig.patch
+drm-xlnx-zynqmp_dpsub-add-missing-check-for-dma_set_.patch
+drm-msm-dpu-drop-the-regdma-configuration.patch
+drm-msm-dpu-increase-memtype-count-to-16-for-sm8550.patch
+arm64-dts-qcom-sm8550-mtp-add-missing-supply-for-l1b.patch
+soc-qcom-smem-fix-incompatible-types-in-comparison.patch
+drm-msm-mdp5-don-t-leak-some-plane-state.patch
+firmware-meson_sm-fix-to-avoid-potential-null-pointe.patch
+drm-msm-dpu-fix-the-irq-index-in-dpu_encoder_phys_wb.patch
+smackfs-prevent-underflow-in-smk_set_cipso.patch
+drm-amd-pm-fix-variable-dereferenced-issue-in-amdgpu.patch
+drm-msm-a2xx-call-adreno_gpu_init-earlier.patch
+drm-msm-a6xx-fix-gmu-lockdep-splat.patch
+asoc-sof-intel-hda-mlink-fix-off-by-one-error.patch
+asoc-sof-intel-fix-u16-32-confusion-in-lsdiid.patch
+drm-mediatek-fix-uninitialized-symbol.patch
+audit-fix-possible-soft-lockup-in-__audit_inode_chil.patch
+block-mq-deadline-use-correct-way-to-throttling-writ.patch
+io_uring-fix-drain-stalls-by-invalid-sqe.patch
+drm-mediatek-dp-add-missing-error-checks-in-mtk_dp_p.patch
+arm64-dts-ti-k3-j784s4-fix-interrupt-ranges-for-wkup.patch
+bus-ti-sysc-fix-build-warning-for-64-bit-build.patch
+drm-mediatek-remove-freeing-not-dynamic-allocated-me.patch
+drm-mediatek-add-cnt-checking-for-coverity-issue.patch
+arm64-dts-imx8mp-debix-remove-unused-fec-pinctrl-nod.patch
+arm-dts-qcom-ipq4019-correct-sdhci-xo-clock.patch
+arm64-dts-ti-k3-am62x-sk-common-update-main-i2c1-fre.patch
+drm-mediatek-fix-potential-memory-leak-if-vmap-fail.patch
+drm-mediatek-fix-void-pointer-to-enum-cast-warning.patch
+arm64-dts-qcom-apq8016-sbc-fix-ov5640-regulator-supp.patch
+arm64-dts-qcom-msm8916-longcheer-l8910-add-front-fla.patch
+arm64-dts-qcom-msm8916-fix-regulator-constraints.patch
+arm64-dts-qcom-msm8916-disable-audio-codecs-by-defau.patch
+arm64-dts-qcom-msm8916-define-regulator-constraints-.patch
+arm64-dts-qcom-msm8916-rename-msmgpio-tlmm.patch
+arm64-dts-qcom-apq8016-sbc-rename-ov5640-enable-gpio.patch
+arm64-dts-qcom-msm8998-drop-bus-clock-reference-from.patch
+arm64-dts-qcom-msm8998-add-missing-power-domain-to-m.patch
+arm-dts-qcom-sdx65-mtp-update-the-pmic-used-in-sdx65.patch
+arm64-dts-qcom-msm8996-fix-dsi1-interrupts.patch
+arm64-dts-qcom-sc8280xp-x13s-unreserve-nc-pins.patch
+bus-ti-sysc-fix-cast-to-enum-warning.patch
+md-raid5-cache-fix-a-deadlock-in-r5l_exit_log.patch
+md-raid5-cache-fix-null-ptr-deref-for-r5l_flush_stri.patch
+firmware-cs_dsp-fix-new-control-name-check.patch
+blk-cgroup-fix-null-deref-caused-by-blkg_policy_data.patch
+md-raid1-free-the-r1bio-before-waiting-for-blocked-r.patch
+md-raid1-hold-the-barrier-until-handle_read_error-fi.patch
+md-raid0-factor-out-helper-for-mapping-and-submittin.patch
+md-raid0-fix-performance-regression-for-large-sequen.patch
+md-raid0-account-for-split-bio-in-iostat-accounting.patch
+asoc-sof-amd-clear-dsp-to-host-interrupt-status.patch
+of-overlay-call-of_changeset_init-early.patch
+of-unittest-fix-overlay-type-in-apply-revert-check.patch
+alsa-ac97-fix-possible-error-value-of-rac97.patch
+ipmi-ssif-add-check-for-kstrdup.patch
+ipmi-ssif-fix-a-memory-leak-when-scanning-for-an-ada.patch
+clk-qcom-gpucc-sm6350-introduce-index-based-clk-look.patch
+clk-qcom-gpucc-sm6350-fix-clock-source-names.patch
+clk-qcom-gcc-sc8280xp-add-missing-gdsc-flags.patch
+dt-bindings-clock-qcom-gcc-sc8280xp-add-missing-gdsc.patch
+clk-qcom-gcc-sc8280xp-add-missing-gdscs.patch
+clk-qcom-gcc-sm7150-add-clk_ops_parent_enable-to-sdc.patch
+clk-rockchip-rk3568-fix-pll-rate-setting-for-78.75mh.patch
+pci-apple-initialize-pcie-nvecs-before-use.patch
+pci-qcom-ep-switch-mhi-bus-master-clock-off-during-l.patch
+drivers-clk-keystone-fix-parameter-judgment-in-_of_p.patch
+edac-i10nm-skip-the-absent-memory-controllers.patch
+iommufd-fix-locking-around-hwpt-allocation.patch
+pci-doe-fix-destroy_work_on_stack-race.patch
+clk-qcom-dispcc-sc8280xp-use-ret-registers-on-gdscs.patch
+clk-sunxi-ng-modify-mismatched-function-name.patch
+clk-qcom-gcc-sc7180-fix-up-gcc_sdcc2_apps_clk_src.patch
+edac-igen6-fix-the-issue-of-no-error-events.patch
+ext4-correct-grp-validation-in-ext4_mb_good_group.patch
+ext4-avoid-potential-data-overflow-in-next_linear_gr.patch
+clk-qcom-gcc-sm8250-fix-gcc_sdcc2_apps_clk_src.patch
+kvm-vfio-prepare-for-accepting-vfio-device-fd.patch
+kvm-vfio-ensure-kvg-instance-stays-around-in-kvm_vfi.patch
+clk-qcom-reset-use-the-correct-type-of-sleep-delay-b.patch
+clk-qcom-gcc-sm6350-fix-gcc_sdcc2_apps_clk_src.patch
+pci-microchip-correct-the-ded-and-sec-interrupt-bit-.patch
+pci-mark-nvidia-t4-gpus-to-avoid-bus-reset.patch
+pinctrl-mcp23s08-check-return-value-of-devm_kasprint.patch
+pci-add-locking-to-rmw-pci-express-capability-regist.patch
+pci-pciehp-use-rmw-accessors-for-changing-lnkctl.patch
+pci-aspm-use-rmw-accessors-for-changing-lnkctl.patch
+clk-qcom-gcc-sm8450-use-floor-ops-for-sdcc-rcgs.patch
+clk-qcom-gcc-qdu1000-fix-gcc_pcie_0_pipe_clk_src-clo.patch
+clk-qcom-gcc-qdu1000-fix-clkref-clocks-handling.patch
+dt-bindings-clock-update-gcc-clocks-for-qdu1000-and-.patch
+clk-qcom-gcc-qdu1000-register-gcc_gpll1_out_even-clo.patch
+clk-imx-pllv4-fix-spll2-mult-range.patch
+clk-imx-imx8ulp-update-spll2-type.patch
+clk-imx8mp-fix-sai4-clock.patch
+clk-imx-composite-8m-fix-clock-pauses-when-set_rate-.patch
+powerpc-radix-move-some-functions-into-ifdef-config_.patch
+vfio-type1-fix-cap_migration-information-leak.patch
+nvdimm-fix-memleak-of-pmu-attr_groups-in-unregister_.patch
+nvdimm-fix-dereference-after-free-in-register_nvdimm.patch
+powerpc-fadump-reset-dump-area-size-if-fadump-memory.patch
+powerpc-perf-convert-fsl_emb-notifier-to-state-machi.patch
+pinctrl-mediatek-fix-pull_type-data-for-mt7981.patch
+pinctrl-mediatek-assign-functions-to-configure-pin-b.patch
+drm-amdgpu-use-rmw-accessors-for-changing-lnkctl.patch
+drm-radeon-use-rmw-accessors-for-changing-lnkctl.patch
+net-mlx5-use-rmw-accessors-for-changing-lnkctl.patch
+wifi-ath11k-use-rmw-accessors-for-changing-lnkctl.patch
+wifi-ath12k-use-rmw-accessors-for-changing-lnkctl.patch
+wifi-ath10k-use-rmw-accessors-for-changing-lnkctl.patch
+nfsv4.2-fix-read_plus-smatch-warnings.patch
+nfsv4.2-fix-read_plus-size-calculations.patch
+nfsv4.2-rework-scratch-handling-for-read_plus-again.patch
+powerpc-don-t-include-lppaca.h-in-paca.h.patch
+powerpc-pseries-rework-lppaca_shared_proc-to-avoid-d.patch
+nfs-blocklayout-use-the-passed-in-gfp-flags.patch
+powerpc-pseries-fix-hcall-tracepoints-with-jump_labe.patch
+powerpc-mpc5xxx-add-missing-fwnode_handle_put.patch
+powerpc-iommu-fix-notifiers-being-shared-by-pci-and-.patch
+ext4-fix-unttached-inode-after-power-cut-with-orphan.patch
+jfs-validate-max-amount-of-blocks-before-allocation.patch
+fs-lockd-avoid-possible-wrong-null-parameter.patch
+nfsd-da_addr_body-field-missing-in-some-getdeviceinf.patch
+nfs-guard-against-readdir-loop-when-entry-names-exce.patch
+nfsv4.2-fix-handling-of-copy-err_offload_no_req.patch
+pnfs-fix-assignment-of-xprtdata.cred.patch
+cgroup-cpuset-inherit-parent-s-load-balance-state-in.patch
+rdma-qedr-remove-a-duplicate-assignment-in-irdma_que.patch
+media-ov5640-fix-low-resolution-image-abnormal-issue.patch
+media-i2c-imx290-drop-format-param-from-imx290_ctrl_.patch
+media-ad5820-drop-unsupported-ad5823-from-i2c_-and-o.patch
+media-i2c-tvp5150-check-return-value-of-devm_kasprin.patch
+media-v4l2-core-fix-a-potential-resource-leak-in-v4l.patch
+iommu-amd-iommu_v2-fix-pasid_state-refcount-dec-hit-.patch
+iommu-rockchip-fix-directory-table-address-encoding.patch
+drivers-usb-smsusb-fix-error-handling-code-in-smsusb.patch
+media-dib7000p-fix-potential-division-by-zero.patch
+media-dvb-usb-m920x-fix-a-potential-memory-leak-in-m.patch
+media-cx24120-add-retval-check-for-cx24120_message_s.patch
+rdma-siw-fabricate-a-gid-on-tun-and-loopback-devices.patch
+scsi-hisi_sas-fix-warnings-detected-by-sparse.patch
+scsi-hisi_sas-fix-normally-completed-i-o-analysed-as.patch
+dt-bindings-extcon-maxim-max77843-restrict-connector.patch
+media-amphion-reinit-vpu-if-reqbufs-output-0.patch
+media-amphion-add-helper-function-to-get-id-name.patch
+media-verisilicon-fix-try_fmt-on-encoder-output.patch
+media-mtk-jpeg-fix-use-after-free-bug-due-to-uncance.patch
+media-amphion-decoder-support-display-delay-for-all-.patch
+media-rkvdec-increase-max-supported-height-for-h.264.patch
+media-amphion-fix-checked_return-issues-reported-by-.patch
+media-amphion-fix-reverse_inull-issues-reported-by-c.patch
+media-amphion-fix-uninit-issues-reported-by-coverity.patch
+media-amphion-fix-unused_value-issue-reported-by-cov.patch
+media-amphion-ensure-the-bitops-don-t-cross-boundari.patch
+media-mediatek-vcodec-return-null-if-no-vdec_fb-is-f.patch
+media-mediatek-vcodec-fix-potential-double-free.patch
+media-mediatek-vcodec-fix-resource-leaks-in-vdec_msg.patch
+usb-phy-mxs-fix-getting-wrong-state-with-mxs_phy_is_.patch
+scsi-rdma-srp-fix-residual-handling.patch
+scsi-ufs-fix-residual-handling.patch
+scsi-iscsi-add-length-check-for-nlattr-payload.patch
+scsi-iscsi-add-strlen-check-in-iscsi_if_set-_host-_p.patch
+scsi-be2iscsi-add-length-check-when-parsing-nlattrs.patch
+scsi-qla4xxx-add-length-check-when-parsing-nlattrs.patch
+iio-accel-adxl313-fix-adxl313_i2c_id-table.patch
+serial-sprd-assign-sprd_port-after-initialized-to-av.patch
+serial-sprd-fix-dma-buffer-leak-issue.patch
+x86-apm-drop-the-duplicate-apm_minor_dev-macro.patch
+rdma-rxe-move-work-queue-code-to-subroutines.patch
+rdma-rxe-fix-unsafe-drain-work-queue-code.patch
+rdma-rxe-fix-rxe_modify_srq.patch
+rdma-rxe-fix-incomplete-state-save-in-rxe_requester.patch
+scsi-qedf-do-not-touch-__user-pointer-in-qedf_dbg_st.patch
+scsi-qedf-do-not-touch-__user-pointer-in-qedf_dbg_de.patch
+scsi-qedf-do-not-touch-__user-pointer-in-qedf_dbg_fp.patch
+rdma-irdma-replace-one-element-array-with-flexible-a.patch
+coresight-tmc-explicit-type-conversions-to-prevent-i.patch
+interconnect-qcom-qcm2290-enable-sync-state.patch
+dma-buf-sync_file-fix-docs-syntax.patch
+driver-core-test_async-fix-an-error-code.patch
+driver-core-call-dma_cleanup-on-the-test_remove-path.patch
+kernfs-add-stub-helper-for-kernfs_generic_poll.patch
+extcon-cht_wc-add-power_supply-dependency.patch
+iommu-mediatek-fix-two-iommu-share-pagetable-issue.patch
+iommu-sprd-add-missing-force_aperture.patch
+iommu-remove-kernel-doc-warnings.patch
+rdma-bnxt_re-remove-a-redundant-flag.patch
+rdma-hns-fix-port-active-speed.patch
+rdma-hns-fix-incorrect-post-send-with-direct-wqe-of-.patch
+rdma-hns-fix-inaccurate-error-label-name-in-init-ins.patch
+rdma-hns-fix-cq-and-qp-cache-affinity.patch
+ib-uverbs-fix-an-potential-error-pointer-dereference.patch
+fsi-aspeed-reset-master-errors-after-cfam-reset.patch
+iommu-qcom-disable-and-reset-context-bank-before-pro.patch
+tty-serial-qcom-geni-serial-poll-primary-sequencer-i.patch
+iommu-vt-d-fix-to-flush-cache-of-pasid-directory-tab.patch
+platform-x86-dell-sysman-fix-reference-leak.patch
+media-cec-core-add-adap_nb_transmit_canceled-callbac.patch
+media-cec-core-add-adap_unconfigured-callback.patch
+media-go7007-remove-redundant-if-statement.patch
+media-venus-hfi_venus-only-consider-sys_idle_indicat.patch
+arm64-defconfig-drop-config_video_imx_media.patch
+media-ipu-bridge-fix-null-pointer-deref-on-ssdb-pld-.patch
+media-ipu3-cio2-rename-cio2-bridge-to-ipu-bridge-and.patch
+media-ipu-bridge-do-not-use-on-stack-memory-for-soft.patch
+docs-abi-fix-spelling-grammar-in-sbefifo-timeout-int.patch
+usb-gadget-core-add-missing-kerneldoc-for-vbus_work.patch
+usb-gadget-f_mass_storage-fix-unused-variable-warnin.patch
+drivers-base-free-devm-resources-when-unregistering-.patch
+hid-input-support-devices-sending-eraser-without-inv.patch
+media-ov5640-enable-mipi-interface-in-ov5640_set_pow.patch
+media-ov5640-fix-initial-resetb-state-and-annotate-t.patch
+media-documentation-fix-gs-_routing-documentation.patch
+media-ov2680-remove-auto-gain-and-auto-exposure-cont.patch
+media-ov2680-fix-ov2680_bayer_order.patch
+media-ov2680-fix-vflip-hflip-set-functions.patch
+media-ov2680-remove-video_v4l2_subdev_api-ifdef-s.patch
+media-ov2680-don-t-take-the-lock-for-try_fmt-calls.patch
+media-ov2680-add-ov2680_fill_format-helper-function.patch
+media-ov2680-fix-ov2680_set_fmt-which-v4l2_subdev_fo.patch
+media-ov2680-fix-regulators-being-left-enabled-on-ov.patch
+media-i2c-rdacm21-fix-uninitialized-value.patch
+f2fs-fix-spelling-in-abi-documentation.patch
+f2fs-fix-to-avoid-mmap-vs-set_compress_option-case.patch
+f2fs-only-lfs-mode-is-allowed-with-zoned-block-devic.patch
+revert-f2fs-fix-to-do-sanity-check-on-extent-cache-c.patch
+f2fs-refactor-struct-f2fs_attr-macro.patch
+f2fs-fix-to-account-gc-stats-correctly.patch
+f2fs-fix-to-drop-all-dirty-meta-node-pages-during-um.patch
+f2fs-fix-to-account-cp-stats-correctly.patch
+coresight-trbe-fix-trbe-potential-sleep-in-atomic-co.patch
+rdma-irdma-prevent-zero-length-stag-registration.patch
+scsi-core-use-32-bit-hostnum-in-scsi_host_lookup.patch
+scsi-fcoe-fix-potential-deadlock-on-fip-ctlr_lock.patch
+interconnect-qcom-sm8450-enable-sync_state.patch
+interconnect-qcom-bcm-voter-improve-enable_mask-hand.patch
+interconnect-qcom-bcm-voter-use-enable_maks-for-keep.patch
+serial-tegra-handle-clk-prepare-error-in-tegra_uart_.patch
+amba-bus-fix-refcount-leak.patch
+revert-ib-isert-fix-incorrect-release-of-isert-conne.patch
+rdma-siw-balance-the-reference-of-cep-kref-in-the-er.patch
+rdma-siw-correct-wrong-debug-message.patch
+rdma-efa-fix-wrong-resources-deallocation-order.patch
+hid-logitech-dj-fix-error-handling-in-logi_dj_recv_s.patch
+nvmem-core-return-null-when-no-nvmem-layout-is-found.patch
+hid-uclogic-correct-devm-device-reference-for-hidinp.patch
+hid-multitouch-correct-devm-device-reference-for-hid.patch
+platform-x86-amd-pmf-fix-a-missing-cleanup-path.patch
+tick-rcu-fix-false-positive-softirq-work-is-pending-.patch
+x86-speculation-mark-all-skylake-cpus-as-vulnerable-.patch
+tracing-remove-extra-space-at-the-end-of-hwlat_detec.patch
+tracing-fix-race-issue-between-cpu-buffer-write-and-.patch
+mtd-rawnand-brcmnand-fix-mtd-oobsize.patch
+dmaengine-idxd-modify-the-dependence-of-attribute-pa.patch
+phy-rockchip-inno-hdmi-use-correct-vco_div_5-macro-o.patch
+phy-rockchip-inno-hdmi-round-fractal-pixclock-in-rk3.patch
+phy-rockchip-inno-hdmi-do-not-power-on-rk3328-post-p.patch
+rpmsg-glink-add-check-for-kstrdup.patch
+leds-pwm-fix-error-code-in-led_pwm_create_fwnode.patch
+thermal-drivers-mediatek-lvts_thermal-handle-irq-on-.patch
+thermal-drivers-mediatek-lvts_thermal-honor-sensors-.patch
+thermal-drivers-mediatek-lvts_thermal-use-offset-thr.patch
+thermal-drivers-mediatek-lvts_thermal-disable-undesi.patch
+thermal-drivers-mediatek-lvts_thermal-don-t-leave-th.patch
+thermal-drivers-mediatek-lvts_thermal-manage-thresho.patch
+thermal-drivers-imx8mm-suppress-log-message-on-probe.patch
+leds-multicolor-use-rounded-division-when-calculatin.patch
+leds-fix-bug_on-check-for-led_color_id_multi-that-is.patch
+leds-trigger-tty-do-not-use-led_on-off-constants-use.patch
+mtd-spi-nor-check-bus-width-while-setting-qe-bit.patch
+mtd-rawnand-fsmc-handle-clk-prepare-error-in-fsmc_na.patch
+um-fix-hostaudio-build-errors.patch
+dmaengine-ste_dma40-add-missing-irq-check-in-d40_pro.patch
+dmaengine-idxd-simplify-wq-attribute-visibility-chec.patch
+dmaengine-idxd-expose-ats-disable-knob-only-when-wq-.patch
+dmaengine-idxd-allow-ats-disable-update-only-for-con.patch
+dmaengine-idxd-fix-issues-with-prs-disable-sysfs-kno.patch
+drivers-hv-vmbus-don-t-dereference-acpi-root-object-.patch
+um-virt-pci-fix-missing-declaration-warning.patch
+cpufreq-fix-the-race-condition-while-updating-the-tr.patch
+virtio_vdpa-build-affinity-masks-conditionally.patch
+virtio_ring-fix-avail_wrap_counter-in-virtqueue_add_.patch
--- /dev/null
+From dd8b9719e9e765281262a49fd70a69bac95fa26e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Aug 2023 17:46:57 +0100
+Subject: sfc: Check firmware supports Ethernet PTP filter
+
+From: Alex Austin <alex.austin@amd.com>
+
+[ Upstream commit c4413a20fa6d7c4888009fb7dd391685f196cd36 ]
+
+Not all firmware variants support RSS filters. Do not fail all PTP
+functionality when raw ethernet PTP filters fail to insert.
+
+Fixes: e4616f64726b ("sfc: support PTP over Ethernet")
+Signed-off-by: Alex Austin <alex.austin@amd.com>
+Acked-by: Edward Cree <ecree.xilinx@gmail.com>
+Reviewed-by: Pieter Jansen van Vuuren <pieter.jansen-van-vuuren@amd.com>
+Link: https://lore.kernel.org/r/20230824164657.42379-1-alex.austin@amd.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/sfc/ptp.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c
+index 0c40571133cb9..00cf6de3bb2be 100644
+--- a/drivers/net/ethernet/sfc/ptp.c
++++ b/drivers/net/ethernet/sfc/ptp.c
+@@ -1485,7 +1485,9 @@ static int efx_ptp_insert_multicast_filters(struct efx_nic *efx)
+ goto fail;
+
+ rc = efx_ptp_insert_eth_multicast_filter(efx);
+- if (rc < 0)
++
++ /* Not all firmware variants support this filter */
++ if (rc < 0 && rc != -EPROTONOSUPPORT)
+ goto fail;
+ }
+
+--
+2.40.1
+
--- /dev/null
+From 61500d475c8e6e00a15a289356365510bc713f60 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Jul 2023 08:52:39 +0300
+Subject: smackfs: Prevent underflow in smk_set_cipso()
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 3ad49d37cf5759c3b8b68d02e3563f633d9c1aee ]
+
+There is a upper bound to "catlen" but no lower bound to prevent
+negatives. I don't see that this necessarily causes a problem but we
+may as well be safe.
+
+Fixes: e114e473771c ("Smack: Simplified Mandatory Access Control Kernel")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/smack/smackfs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
+index 5590eaad241bb..25f67d1b5c73e 100644
+--- a/security/smack/smackfs.c
++++ b/security/smack/smackfs.c
+@@ -896,7 +896,7 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf,
+ }
+
+ ret = sscanf(rule, "%d", &catlen);
+- if (ret != 1 || catlen > SMACK_CIPSO_MAXCATNUM)
++ if (ret != 1 || catlen < 0 || catlen > SMACK_CIPSO_MAXCATNUM)
+ goto out;
+
+ if (format == SMK_FIXED24_FMT &&
+--
+2.40.1
+
--- /dev/null
+From 4d5f253d3e02a8bd8799bd69d14e3e52cf1c8c66 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 May 2023 10:41:15 +0200
+Subject: soc: qcom: ocmem: Add OCMEM hardware version print
+
+From: Luca Weiss <luca@z3ntu.xyz>
+
+[ Upstream commit e81a16e77259294cd4ff0a9c1fbe5aa0e311a47d ]
+
+It might be useful to know what hardware version of the OCMEM block the
+SoC contains. Add a debug print for that.
+
+Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230509-ocmem-hwver-v3-1-e51f3488e0f4@z3ntu.xyz
+Stable-dep-of: a7b484b1c933 ("soc: qcom: ocmem: Fix NUM_PORTS & NUM_MACROS macros")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/qcom/ocmem.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/soc/qcom/ocmem.c b/drivers/soc/qcom/ocmem.c
+index 199fe98720350..aaddc3cc53b7f 100644
+--- a/drivers/soc/qcom/ocmem.c
++++ b/drivers/soc/qcom/ocmem.c
+@@ -76,6 +76,10 @@ struct ocmem {
+ #define OCMEM_REG_GFX_MPU_START 0x00001004
+ #define OCMEM_REG_GFX_MPU_END 0x00001008
+
++#define OCMEM_HW_VERSION_MAJOR(val) FIELD_GET(GENMASK(31, 28), val)
++#define OCMEM_HW_VERSION_MINOR(val) FIELD_GET(GENMASK(27, 16), val)
++#define OCMEM_HW_VERSION_STEP(val) FIELD_GET(GENMASK(15, 0), val)
++
+ #define OCMEM_HW_PROFILE_NUM_PORTS(val) FIELD_PREP(0x0000000f, (val))
+ #define OCMEM_HW_PROFILE_NUM_MACROS(val) FIELD_PREP(0x00003f00, (val))
+
+@@ -355,6 +359,12 @@ static int ocmem_dev_probe(struct platform_device *pdev)
+ }
+ }
+
++ reg = ocmem_read(ocmem, OCMEM_REG_HW_VERSION);
++ dev_dbg(dev, "OCMEM hardware version: %lu.%lu.%lu\n",
++ OCMEM_HW_VERSION_MAJOR(reg),
++ OCMEM_HW_VERSION_MINOR(reg),
++ OCMEM_HW_VERSION_STEP(reg));
++
+ reg = ocmem_read(ocmem, OCMEM_REG_HW_PROFILE);
+ ocmem->num_ports = OCMEM_HW_PROFILE_NUM_PORTS(reg);
+ ocmem->num_macros = OCMEM_HW_PROFILE_NUM_MACROS(reg);
+--
+2.40.1
+
--- /dev/null
+From c2d7c3704fa9bab8fdaa545dc2e3e44bb60583f7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Jun 2023 18:35:47 +0200
+Subject: soc: qcom: ocmem: Fix NUM_PORTS & NUM_MACROS macros
+
+From: Luca Weiss <luca@z3ntu.xyz>
+
+[ Upstream commit a7b484b1c9332a1ee12e8799d62a11ee3f8e0801 ]
+
+Since we're using these two macros to read a value from a register, we
+need to use the FIELD_GET instead of the FIELD_PREP macro, otherwise
+we're getting wrong values.
+
+So instead of:
+
+ [ 3.111779] ocmem fdd00000.sram: 2 ports, 1 regions, 512 macros, not interleaved
+
+we now get the correct value of:
+
+ [ 3.129672] ocmem fdd00000.sram: 2 ports, 1 regions, 2 macros, not interleaved
+
+Fixes: 88c1e9404f1d ("soc: qcom: add OCMEM driver")
+Reviewed-by: Caleb Connolly <caleb.connolly@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
+Link: https://lore.kernel.org/r/20230506-msm8226-ocmem-v3-1-79da95a2581f@z3ntu.xyz
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/qcom/ocmem.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/soc/qcom/ocmem.c b/drivers/soc/qcom/ocmem.c
+index aaddc3cc53b7f..ef7c1748242ac 100644
+--- a/drivers/soc/qcom/ocmem.c
++++ b/drivers/soc/qcom/ocmem.c
+@@ -80,8 +80,8 @@ struct ocmem {
+ #define OCMEM_HW_VERSION_MINOR(val) FIELD_GET(GENMASK(27, 16), val)
+ #define OCMEM_HW_VERSION_STEP(val) FIELD_GET(GENMASK(15, 0), val)
+
+-#define OCMEM_HW_PROFILE_NUM_PORTS(val) FIELD_PREP(0x0000000f, (val))
+-#define OCMEM_HW_PROFILE_NUM_MACROS(val) FIELD_PREP(0x00003f00, (val))
++#define OCMEM_HW_PROFILE_NUM_PORTS(val) FIELD_GET(0x0000000f, (val))
++#define OCMEM_HW_PROFILE_NUM_MACROS(val) FIELD_GET(0x00003f00, (val))
+
+ #define OCMEM_HW_PROFILE_LAST_REGN_HALFSIZE 0x00010000
+ #define OCMEM_HW_PROFILE_INTERLEAVING 0x00020000
+--
+2.40.1
+
--- /dev/null
+From 7ddb53648756cc65266b44274deebe0f281a5c68 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Aug 2023 17:48:07 +0800
+Subject: soc: qcom: smem: Fix incompatible types in comparison
+
+From: Chen Jiahao <chenjiahao16@huawei.com>
+
+[ Upstream commit 5f908786cf44fcb397cfe0f322ef2f41b0909e2a ]
+
+This patch fixes the following sparse error:
+
+drivers/soc/qcom/smem.c:738:30: error: incompatible types in comparison expression (different add ress spaces):
+drivers/soc/qcom/smem.c:738:30: void *
+drivers/soc/qcom/smem.c:738:30: void [noderef] __iomem *
+
+In addr_in_range(), "base" is of type void __iomem *, converting
+void *addr to the same type to fix above sparse error.
+
+Fixes: 20bb6c9de1b7 ("soc: qcom: smem: map only partitions used by local HOST")
+Signed-off-by: Chen Jiahao <chenjiahao16@huawei.com>
+Link: https://lore.kernel.org/r/20230801094807.4146779-1-chenjiahao16@huawei.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/qcom/smem.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c
+index 6be7ea93c78cf..1e08bb3b1679a 100644
+--- a/drivers/soc/qcom/smem.c
++++ b/drivers/soc/qcom/smem.c
+@@ -723,7 +723,7 @@ EXPORT_SYMBOL(qcom_smem_get_free_space);
+
+ static bool addr_in_range(void __iomem *base, size_t size, void *addr)
+ {
+- return base && (addr >= base && addr < base + size);
++ return base && ((void __iomem *)addr >= base && (void __iomem *)addr < base + size);
+ }
+
+ /**
+--
+2.40.1
+
--- /dev/null
+From 6e7f4b13f381bde63bbf0c1f063037a159367c7a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Aug 2023 21:48:05 +0800
+Subject: spi: mpc5xxx-psc: Fix unsigned expression compared with zero
+
+From: Li Zetao <lizetao1@huawei.com>
+
+[ Upstream commit de5e92cb5cefd2968b96075995a36e28298edf71 ]
+
+There is two warnings reported by coccinelle:
+
+./drivers/spi/spi-mpc512x-psc.c:493:5-13: WARNING:
+ Unsigned expression compared with zero: mps -> irq < 0
+./drivers/spi/spi-mpc52xx-psc.c:332:5-13: WARNING:
+ Unsigned expression compared with zero: mps -> irq < 0
+
+The commit "208ee586f862"
+("spi: mpc5xxx-psc: Return immediately if IRQ resource is unavailable")
+was to check whether the IRQ resource is unavailable. When the IRQ
+resource is unavailable, an error code is returned, however, the type
+of "mps->irq" is "unsigned int", causing the error code to flip. Modify
+the type of "mps->irq" to solve this problem.
+
+Fixes: 208ee586f862 ("spi: mpc5xxx-psc: Return immediately if IRQ resource is unavailable")
+Signed-off-by: Li Zetao <lizetao1@huawei.com>
+Link: https://lore.kernel.org/r/20230803134805.1037251-1-lizetao1@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-mpc512x-psc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-mpc512x-psc.c b/drivers/spi/spi-mpc512x-psc.c
+index 99aeef28a4774..5cecca1bef026 100644
+--- a/drivers/spi/spi-mpc512x-psc.c
++++ b/drivers/spi/spi-mpc512x-psc.c
+@@ -53,7 +53,7 @@ struct mpc512x_psc_spi {
+ int type;
+ void __iomem *psc;
+ struct mpc512x_psc_fifo __iomem *fifo;
+- unsigned int irq;
++ int irq;
+ u8 bits_per_word;
+ u32 mclk_rate;
+
+--
+2.40.1
+
--- /dev/null
+From 4e8f4e956559f1f0ca249d76ba5cd61e1bacbeea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Aug 2023 12:20:58 +0300
+Subject: spi: tegra114: Remove unnecessary NULL-pointer checks
+
+From: Alexander Danilenko <al.b.danilenko@gmail.com>
+
+[ Upstream commit 373c36bf7914e3198ac2654dede499f340c52950 ]
+
+cs_setup, cs_hold and cs_inactive points to fields of spi_device struct,
+so there is no sense in checking them for NULL.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: 04e6bb0d6bb1 ("spi: modify set_cs_timing parameter")
+Signed-off-by: Alexander Danilenko <al.b.danilenko@gmail.com>
+Link: https://lore.kernel.org/r/20230815092058.4083-1-al.b.danilenko@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-tegra114.c | 18 +++++++-----------
+ 1 file changed, 7 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c
+index 488df681eaefc..2226d77a5d20a 100644
+--- a/drivers/spi/spi-tegra114.c
++++ b/drivers/spi/spi-tegra114.c
+@@ -723,27 +723,23 @@ static int tegra_spi_set_hw_cs_timing(struct spi_device *spi)
+ struct spi_delay *setup = &spi->cs_setup;
+ struct spi_delay *hold = &spi->cs_hold;
+ struct spi_delay *inactive = &spi->cs_inactive;
+- u8 setup_dly, hold_dly, inactive_dly;
++ u8 setup_dly, hold_dly;
+ u32 setup_hold;
+ u32 spi_cs_timing;
+ u32 inactive_cycles;
+ u8 cs_state;
+
+- if ((setup && setup->unit != SPI_DELAY_UNIT_SCK) ||
+- (hold && hold->unit != SPI_DELAY_UNIT_SCK) ||
+- (inactive && inactive->unit != SPI_DELAY_UNIT_SCK)) {
++ if (setup->unit != SPI_DELAY_UNIT_SCK ||
++ hold->unit != SPI_DELAY_UNIT_SCK ||
++ inactive->unit != SPI_DELAY_UNIT_SCK) {
+ dev_err(&spi->dev,
+ "Invalid delay unit %d, should be SPI_DELAY_UNIT_SCK\n",
+ SPI_DELAY_UNIT_SCK);
+ return -EINVAL;
+ }
+
+- setup_dly = setup ? setup->value : 0;
+- hold_dly = hold ? hold->value : 0;
+- inactive_dly = inactive ? inactive->value : 0;
+-
+- setup_dly = min_t(u8, setup_dly, MAX_SETUP_HOLD_CYCLES);
+- hold_dly = min_t(u8, hold_dly, MAX_SETUP_HOLD_CYCLES);
++ setup_dly = min_t(u8, setup->value, MAX_SETUP_HOLD_CYCLES);
++ hold_dly = min_t(u8, hold->value, MAX_SETUP_HOLD_CYCLES);
+ if (setup_dly && hold_dly) {
+ setup_hold = SPI_SETUP_HOLD(setup_dly - 1, hold_dly - 1);
+ spi_cs_timing = SPI_CS_SETUP_HOLD(tspi->spi_cs_timing1,
+@@ -755,7 +751,7 @@ static int tegra_spi_set_hw_cs_timing(struct spi_device *spi)
+ }
+ }
+
+- inactive_cycles = min_t(u8, inactive_dly, MAX_INACTIVE_CYCLES);
++ inactive_cycles = min_t(u8, inactive->value, MAX_INACTIVE_CYCLES);
+ if (inactive_cycles)
+ inactive_cycles--;
+ cs_state = inactive_cycles ? 0 : 1;
+--
+2.40.1
+
--- /dev/null
+From 6514e50f929890bf8b3c7f66720a1c795d63cbf9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 22 Jul 2023 23:49:09 +0800
+Subject: spi: tegra20-sflash: fix to check return value of platform_get_irq()
+ in tegra_sflash_probe()
+
+From: Zhang Shurong <zhang_shurong@foxmail.com>
+
+[ Upstream commit 29a449e765ff70a5bd533be94babb6d36985d096 ]
+
+The platform_get_irq might be failed and return a negative result. So
+there should have an error handling code.
+
+Fixed this by adding an error handling code.
+
+Fixes: 8528547bcc33 ("spi: tegra: add spi driver for sflash controller")
+Signed-off-by: Zhang Shurong <zhang_shurong@foxmail.com>
+Link: https://lore.kernel.org/r/tencent_71FC162D589E4788C2152AAC84CD8D5C6D06@qq.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-tegra20-sflash.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-tegra20-sflash.c b/drivers/spi/spi-tegra20-sflash.c
+index 4286310628a2b..0c5507473f972 100644
+--- a/drivers/spi/spi-tegra20-sflash.c
++++ b/drivers/spi/spi-tegra20-sflash.c
+@@ -455,7 +455,11 @@ static int tegra_sflash_probe(struct platform_device *pdev)
+ goto exit_free_master;
+ }
+
+- tsd->irq = platform_get_irq(pdev, 0);
++ ret = platform_get_irq(pdev, 0);
++ if (ret < 0)
++ goto exit_free_master;
++ tsd->irq = ret;
++
+ ret = request_irq(tsd->irq, tegra_sflash_isr, 0,
+ dev_name(&pdev->dev), tsd);
+ if (ret < 0) {
+--
+2.40.1
+
--- /dev/null
+From 508c3b59af6131691354f35cf33df57a2e60ca4d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Jul 2023 16:42:13 +0200
+Subject: splice: always fsnotify_access(in), fsnotify_modify(out) on success
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
+
+[ Upstream commit 12ee4b66af34f8e72f3b2fd93a946a955efe7c86 ]
+
+The current behaviour caused an asymmetry where some write APIs
+(write, sendfile) would notify the written-to/read-from objects,
+but splice wouldn't.
+
+This affected userspace which uses inotify, most notably coreutils
+tail -f, to monitor pipes.
+If the pipe buffer had been filled by a splice-family function:
+ * tail wouldn't know and thus wouldn't service the pipe, and
+ * all writes to the pipe would block because it's full,
+thus service was denied.
+(For the particular case of tail -f this could be worked around
+ with ---disable-inotify.)
+
+Fixes: 983652c69199 ("splice: report related fsnotify events")
+Link: https://lore.kernel.org/linux-fsdevel/jbyihkyk5dtaohdwjyivambb2gffyjs3dodpofafnkkunxq7bu@jngkdxx65pux/t/#u
+Link: https://bugs.debian.org/1039488
+Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
+Acked-by: Jan Kara <jack@suse.cz>
+Reviewed-by: Amir Goldstein <amir73il@gmail.com>
+Message-Id: <604ec704d933e0e0121d9e107ce914512e045fad.1688393619.git.nabijaczleweli@nabijaczleweli.xyz>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/splice.c | 32 +++++++++++++++-----------------
+ 1 file changed, 15 insertions(+), 17 deletions(-)
+
+diff --git a/fs/splice.c b/fs/splice.c
+index 030e162985b5d..90abe551acb78 100644
+--- a/fs/splice.c
++++ b/fs/splice.c
+@@ -1153,10 +1153,8 @@ long do_splice(struct file *in, loff_t *off_in, struct file *out,
+ if ((in->f_flags | out->f_flags) & O_NONBLOCK)
+ flags |= SPLICE_F_NONBLOCK;
+
+- return splice_pipe_to_pipe(ipipe, opipe, len, flags);
+- }
+-
+- if (ipipe) {
++ ret = splice_pipe_to_pipe(ipipe, opipe, len, flags);
++ } else if (ipipe) {
+ if (off_in)
+ return -ESPIPE;
+ if (off_out) {
+@@ -1181,18 +1179,11 @@ long do_splice(struct file *in, loff_t *off_in, struct file *out,
+ ret = do_splice_from(ipipe, out, &offset, len, flags);
+ file_end_write(out);
+
+- if (ret > 0)
+- fsnotify_modify(out);
+-
+ if (!off_out)
+ out->f_pos = offset;
+ else
+ *off_out = offset;
+-
+- return ret;
+- }
+-
+- if (opipe) {
++ } else if (opipe) {
+ if (off_out)
+ return -ESPIPE;
+ if (off_in) {
+@@ -1208,18 +1199,25 @@ long do_splice(struct file *in, loff_t *off_in, struct file *out,
+
+ ret = splice_file_to_pipe(in, opipe, &offset, len, flags);
+
+- if (ret > 0)
+- fsnotify_access(in);
+-
+ if (!off_in)
+ in->f_pos = offset;
+ else
+ *off_in = offset;
++ } else {
++ ret = -EINVAL;
++ }
+
+- return ret;
++ if (ret > 0) {
++ /*
++ * Generate modify out before access in:
++ * do_splice_from() may've already sent modify out,
++ * and this ensures the events get merged.
++ */
++ fsnotify_modify(out);
++ fsnotify_access(in);
+ }
+
+- return -EINVAL;
++ return ret;
+ }
+
+ static long __do_splice(struct file *in, loff_t __user *off_in,
+--
+2.40.1
+
--- /dev/null
+From e984efbd218772d59dd6d5c92620697709763084 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Jul 2023 16:42:17 +0200
+Subject: splice: fsnotify_access(fd)/fsnotify_modify(fd) in vmsplice
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
+
+[ Upstream commit 7f0f1ea069e52d5a16921abd59377a7da6c25149 ]
+
+Same logic applies here: this can fill up the pipe and pollers that rely
+on getting IN_MODIFY notifications never wake up.
+
+Fixes: 983652c69199 ("splice: report related fsnotify events")
+Link: https://lore.kernel.org/linux-fsdevel/jbyihkyk5dtaohdwjyivambb2gffyjs3dodpofafnkkunxq7bu@jngkdxx65pux/t/#u
+Link: https://bugs.debian.org/1039488
+Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
+Acked-by: Jan Kara <jack@suse.cz>
+Reviewed-by: Amir Goldstein <amir73il@gmail.com>
+Message-Id: <8d9ad5acb9c5c1dd2376a2ff5da6ac3183115389.1688393619.git.nabijaczleweli@nabijaczleweli.xyz>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/splice.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/fs/splice.c b/fs/splice.c
+index 90abe551acb78..c08eb445a1d20 100644
+--- a/fs/splice.c
++++ b/fs/splice.c
+@@ -1346,6 +1346,9 @@ static long vmsplice_to_user(struct file *file, struct iov_iter *iter,
+ pipe_unlock(pipe);
+ }
+
++ if (ret > 0)
++ fsnotify_access(file);
++
+ return ret;
+ }
+
+@@ -1375,8 +1378,10 @@ static long vmsplice_to_pipe(struct file *file, struct iov_iter *iter,
+ if (!ret)
+ ret = iter_to_pipe(iter, pipe, buf_flag);
+ pipe_unlock(pipe);
+- if (ret > 0)
++ if (ret > 0) {
+ wakeup_pipe_readers(pipe);
++ fsnotify_modify(file);
++ }
+ return ret;
+ }
+
+--
+2.40.1
+
--- /dev/null
+From 1845ba7da505f983ee19ff0ae77f76cc1d3b35ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Jul 2023 16:42:21 +0200
+Subject: splice: fsnotify_access(in), fsnotify_modify(out) on success in tee
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
+
+[ Upstream commit 576d498e0ac5caff2d9f6312573ab54d98f12d32 ]
+
+Same logic applies here: this can fill up the pipe, and pollers that rely
+on getting IN_MODIFY notifications never wake up.
+
+Fixes: 983652c69199 ("splice: report related fsnotify events")
+Link: https://lore.kernel.org/linux-fsdevel/jbyihkyk5dtaohdwjyivambb2gffyjs3dodpofafnkkunxq7bu@jngkdxx65pux/t/#u
+Link: https://bugs.debian.org/1039488
+Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
+Acked-by: Jan Kara <jack@suse.cz>
+Reviewed-by: Amir Goldstein <amir73il@gmail.com>
+Message-Id: <10d76dd8c85017ae3cd047c9b9a32e26daefdaa2.1688393619.git.nabijaczleweli@nabijaczleweli.xyz>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/splice.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/fs/splice.c b/fs/splice.c
+index c08eb445a1d20..3ae2de263e806 100644
+--- a/fs/splice.c
++++ b/fs/splice.c
+@@ -1815,6 +1815,11 @@ long do_tee(struct file *in, struct file *out, size_t len, unsigned int flags)
+ }
+ }
+
++ if (ret > 0) {
++ fsnotify_access(in);
++ fsnotify_modify(out);
++ }
++
+ return ret;
+ }
+
+--
+2.40.1
+
--- /dev/null
+From 85af1dd67a20de919c9757adc32d2d2038e3941b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Jul 2023 16:20:49 +0000
+Subject: tcp: tcp_enter_quickack_mode() should be static
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 03b123debcbc8db987bda17ed8412cc011064c22 ]
+
+After commit d2ccd7bc8acd ("tcp: avoid resetting ACK timer in DCTCP"),
+tcp_enter_quickack_mode() is only used from net/ipv4/tcp_input.c.
+
+Fixes: d2ccd7bc8acd ("tcp: avoid resetting ACK timer in DCTCP")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Yuchung Cheng <ycheng@google.com>
+Cc: Neal Cardwell <ncardwell@google.com>
+Link: https://lore.kernel.org/r/20230718162049.1444938-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/tcp.h | 1 -
+ net/ipv4/tcp_input.c | 3 +--
+ 2 files changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/include/net/tcp.h b/include/net/tcp.h
+index 182337a8cf94a..ca6435f5d821e 100644
+--- a/include/net/tcp.h
++++ b/include/net/tcp.h
+@@ -355,7 +355,6 @@ ssize_t tcp_splice_read(struct socket *sk, loff_t *ppos,
+ struct sk_buff *tcp_stream_alloc_skb(struct sock *sk, int size, gfp_t gfp,
+ bool force_schedule);
+
+-void tcp_enter_quickack_mode(struct sock *sk, unsigned int max_quickacks);
+ static inline void tcp_dec_quickack_mode(struct sock *sk,
+ const unsigned int pkts)
+ {
+diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
+index 57f1e4883b761..094b3e266bbea 100644
+--- a/net/ipv4/tcp_input.c
++++ b/net/ipv4/tcp_input.c
+@@ -287,7 +287,7 @@ static void tcp_incr_quickack(struct sock *sk, unsigned int max_quickacks)
+ icsk->icsk_ack.quick = quickacks;
+ }
+
+-void tcp_enter_quickack_mode(struct sock *sk, unsigned int max_quickacks)
++static void tcp_enter_quickack_mode(struct sock *sk, unsigned int max_quickacks)
+ {
+ struct inet_connection_sock *icsk = inet_csk(sk);
+
+@@ -295,7 +295,6 @@ void tcp_enter_quickack_mode(struct sock *sk, unsigned int max_quickacks)
+ inet_csk_exit_pingpong_mode(sk);
+ icsk->icsk_ack.ato = TCP_ATO_MIN;
+ }
+-EXPORT_SYMBOL(tcp_enter_quickack_mode);
+
+ /* Send ACKs quickly, if "quick" count is not exhausted
+ * and the session is not interactive.
+--
+2.40.1
+
--- /dev/null
+From ab1add2b3d4970d3cd02cd119d8af9c5fdc43d18 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Jul 2023 13:26:46 +0200
+Subject: thermal/drivers/imx8mm: Suppress log message on probe deferral
+
+From: Ahmad Fatoum <a.fatoum@pengutronix.de>
+
+[ Upstream commit 4afcb58ea47e66c025d2b0a5f091dce5aaf95b0f ]
+
+nvmem_cell_read_u32() may return -EPROBE_DEFER if NVMEM supplier has not
+yet been probed. Future reprobe may succeed, so printing:
+
+ i.mx8mm_thermal 30260000.tmu: Failed to read OCOTP nvmem cell (-517).
+
+to the log is confusing. Fix this by using dev_err_probe. This also
+elevates the message from warning to error, which is more correct: The
+log message is only ever printed in probe error path and probe aborts
+afterwards, so it really warrants an error-level message.
+
+Fixes: 403291648823 ("thermal/drivers/imx: Add support for loading calibration data from OCOTP")
+Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
+Reviewed-by: Marek Vasut <marex@denx.de>
+Reviewed-by: Peng Fan <peng.fan@nxp.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20230708112647.2897294-1-a.fatoum@pengutronix.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/imx8mm_thermal.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/thermal/imx8mm_thermal.c b/drivers/thermal/imx8mm_thermal.c
+index d8005e9ec992b..1f780c4a1c890 100644
+--- a/drivers/thermal/imx8mm_thermal.c
++++ b/drivers/thermal/imx8mm_thermal.c
+@@ -179,10 +179,8 @@ static int imx8mm_tmu_probe_set_calib_v1(struct platform_device *pdev,
+ int ret;
+
+ ret = nvmem_cell_read_u32(&pdev->dev, "calib", &ana0);
+- if (ret) {
+- dev_warn(dev, "Failed to read OCOTP nvmem cell (%d).\n", ret);
+- return ret;
+- }
++ if (ret)
++ return dev_err_probe(dev, ret, "Failed to read OCOTP nvmem cell\n");
+
+ writel(FIELD_PREP(TASR_BUF_VREF_MASK,
+ FIELD_GET(ANA0_BUF_VREF_MASK, ana0)) |
+--
+2.40.1
+
--- /dev/null
+From adadc93db6181caa768a648caf7b42857705763f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Jul 2023 11:37:35 -0400
+Subject: thermal/drivers/mediatek/lvts_thermal: Disable undesired interrupts
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+
+[ Upstream commit 487bf099e85b724c824f5fafaf93c6749c4d2120 ]
+
+Out of the many interrupts supported by the hardware, the only ones of
+interest to the driver currently are:
+* The temperature went over the high offset threshold, for any of the
+ sensors
+* The temperature went below the low offset threshold, for any of the
+ sensors
+* The temperature went over the stage3 threshold
+
+These are the only thresholds configured by the driver through the
+OFFSETH, OFFSETL, and PROTTC registers, respectively.
+
+The current interrupt mask in LVTS_MONINT_CONF, enables many more
+interrupts, including data ready on sensors for both filtered and
+immediate mode. These are not only not handled by the driver, but they
+are also triggered too often, causing unneeded overhead. Disable these
+unnecessary interrupts.
+
+The meaning of each bit can be seen in the comment describing
+LVTS_MONINTST in the IRQ handler.
+
+Fixes: f5f633b18234 ("thermal/drivers/mediatek: Add the Low Voltage Thermal Sensor driver")
+Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20230706153823.201943-5-nfraprado@collabora.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/mediatek/lvts_thermal.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/thermal/mediatek/lvts_thermal.c b/drivers/thermal/mediatek/lvts_thermal.c
+index 80abd10596d85..0fa90ac6ed41f 100644
+--- a/drivers/thermal/mediatek/lvts_thermal.c
++++ b/drivers/thermal/mediatek/lvts_thermal.c
+@@ -63,7 +63,7 @@
+ #define LVTS_HW_FILTER 0x2
+ #define LVTS_TSSEL_CONF 0x13121110
+ #define LVTS_CALSCALE_CONF 0x300
+-#define LVTS_MONINT_CONF 0x9FBF7BDE
++#define LVTS_MONINT_CONF 0x8300318C
+
+ #define LVTS_INT_SENSOR0 0x0009001F
+ #define LVTS_INT_SENSOR1 0x001203E0
+--
+2.40.1
+
--- /dev/null
+From b2b1aea84b57f07f1f8732cfb5108759b0cd1065 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Jul 2023 11:37:36 -0400
+Subject: thermal/drivers/mediatek/lvts_thermal: Don't leave threshold zeroed
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+
+[ Upstream commit 77354eaef8218bc40d6b37e783b0b8dcca22a7d9 ]
+
+The thermal framework might leave the low threshold unset if there
+aren't any lower trip points. This leaves the register zeroed, which
+translates to a very high temperature for the low threshold. The
+interrupt for this threshold is then immediately triggered, and the
+state machine gets stuck, preventing any other temperature monitoring
+interrupts to ever trigger.
+
+(The same happens by not setting the Cold or Hot to Normal thresholds
+when using those)
+
+Set the unused threshold to a valid low value. This value was chosen so
+that for any valid golden temperature read from the efuse, when the
+value is converted to raw and back again to milliCelsius, the result
+doesn't underflow.
+
+Fixes: f5f633b18234 ("thermal/drivers/mediatek: Add the Low Voltage Thermal Sensor driver")
+Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20230706153823.201943-6-nfraprado@collabora.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/mediatek/lvts_thermal.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/thermal/mediatek/lvts_thermal.c b/drivers/thermal/mediatek/lvts_thermal.c
+index 0fa90ac6ed41f..a6bdcdfffa333 100644
+--- a/drivers/thermal/mediatek/lvts_thermal.c
++++ b/drivers/thermal/mediatek/lvts_thermal.c
+@@ -81,6 +81,8 @@
+
+ #define LVTS_HW_SHUTDOWN_MT8195 105000
+
++#define LVTS_MINIMUM_THRESHOLD 20000
++
+ static int golden_temp = LVTS_GOLDEN_TEMP_DEFAULT;
+ static int coeff_b = LVTS_COEFF_B;
+
+@@ -292,7 +294,7 @@ static int lvts_set_trips(struct thermal_zone_device *tz, int low, int high)
+ {
+ struct lvts_sensor *lvts_sensor = thermal_zone_device_priv(tz);
+ void __iomem *base = lvts_sensor->base;
+- u32 raw_low = lvts_temp_to_raw(low);
++ u32 raw_low = lvts_temp_to_raw(low != -INT_MAX ? low : LVTS_MINIMUM_THRESHOLD);
+ u32 raw_high = lvts_temp_to_raw(high);
+
+ /*
+@@ -304,11 +306,9 @@ static int lvts_set_trips(struct thermal_zone_device *tz, int low, int high)
+ *
+ * 14-0 : Raw temperature for threshold
+ */
+- if (low != -INT_MAX) {
+- pr_debug("%s: Setting low limit temperature interrupt: %d\n",
+- thermal_zone_device_type(tz), low);
+- writel(raw_low, LVTS_OFFSETL(base));
+- }
++ pr_debug("%s: Setting low limit temperature interrupt: %d\n",
++ thermal_zone_device_type(tz), low);
++ writel(raw_low, LVTS_OFFSETL(base));
+
+ /*
+ * High offset temperature threshold
+--
+2.40.1
+
--- /dev/null
+From 87e738752d1ae9c4fed28839478294c3dcc2e536 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Jul 2023 11:37:32 -0400
+Subject: thermal/drivers/mediatek/lvts_thermal: Handle IRQ on all controllers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+
+[ Upstream commit cbd8c5aae2a988bafd4586bea710eeddc30a82ce ]
+
+There is a single IRQ handler for each LVTS thermal domain, and it is
+supposed to check each of its underlying controllers for the origin of
+the interrupt and clear its status. However due to a typo, only the
+first controller was ever being handled, which resulted in the interrupt
+never being cleared when it happened on the other controllers. Add the
+missing index so interrupts are handled for all controllers.
+
+Fixes: f5f633b18234 ("thermal/drivers/mediatek: Add the Low Voltage Thermal Sensor driver")
+Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Tested-by: Chen-Yu Tsai <wenst@chromium.org>
+Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20230706153823.201943-2-nfraprado@collabora.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/mediatek/lvts_thermal.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/thermal/mediatek/lvts_thermal.c b/drivers/thermal/mediatek/lvts_thermal.c
+index d0a3f95b7884b..56b24c5b645f3 100644
+--- a/drivers/thermal/mediatek/lvts_thermal.c
++++ b/drivers/thermal/mediatek/lvts_thermal.c
+@@ -449,7 +449,7 @@ static irqreturn_t lvts_irq_handler(int irq, void *data)
+
+ for (i = 0; i < lvts_td->num_lvts_ctrl; i++) {
+
+- aux = lvts_ctrl_irq_handler(lvts_td->lvts_ctrl);
++ aux = lvts_ctrl_irq_handler(&lvts_td->lvts_ctrl[i]);
+ if (aux != IRQ_HANDLED)
+ continue;
+
+--
+2.40.1
+
--- /dev/null
+From f0b05aef3262fc04acb101d4d1a3983633422ae3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Jul 2023 11:37:33 -0400
+Subject: thermal/drivers/mediatek/lvts_thermal: Honor sensors in immediate
+ mode
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+
+[ Upstream commit 64de162e34e4cb2982a1d96e492f018026a61c1d ]
+
+Each controller can be configured to operate on immediate or filtered
+mode. On filtered mode, the sensors are enabled by setting the
+corresponding bits in MONCTL0, while on immediate mode, by setting
+MSRCTL1.
+
+Previously, the code would set MSRCTL1 for all four sensors when
+configured to immediate mode, but given that the controller might not
+have all four sensors connected, this would cause interrupts to trigger
+for non-existent sensors. Fix this by handling the MSRCTL1 register
+analogously to the MONCTL0: only enable the sensors that were declared.
+
+Fixes: f5f633b18234 ("thermal/drivers/mediatek: Add the Low Voltage Thermal Sensor driver")
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Tested-by: Chen-Yu Tsai <wenst@chromium.org>
+Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20230706153823.201943-3-nfraprado@collabora.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/mediatek/lvts_thermal.c | 57 ++++++++++++++-----------
+ 1 file changed, 33 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/thermal/mediatek/lvts_thermal.c b/drivers/thermal/mediatek/lvts_thermal.c
+index 56b24c5b645f3..64748153d181e 100644
+--- a/drivers/thermal/mediatek/lvts_thermal.c
++++ b/drivers/thermal/mediatek/lvts_thermal.c
+@@ -894,24 +894,6 @@ static int lvts_ctrl_configure(struct device *dev, struct lvts_ctrl *lvts_ctrl)
+ LVTS_HW_FILTER << 3 | LVTS_HW_FILTER;
+ writel(value, LVTS_MSRCTL0(lvts_ctrl->base));
+
+- /*
+- * LVTS_MSRCTL1 : Measurement control
+- *
+- * Bits:
+- *
+- * 9: Ignore MSRCTL0 config and do immediate measurement on sensor3
+- * 6: Ignore MSRCTL0 config and do immediate measurement on sensor2
+- * 5: Ignore MSRCTL0 config and do immediate measurement on sensor1
+- * 4: Ignore MSRCTL0 config and do immediate measurement on sensor0
+- *
+- * That configuration will ignore the filtering and the delays
+- * introduced below in MONCTL1 and MONCTL2
+- */
+- if (lvts_ctrl->mode == LVTS_MSR_IMMEDIATE_MODE) {
+- value = BIT(9) | BIT(6) | BIT(5) | BIT(4);
+- writel(value, LVTS_MSRCTL1(lvts_ctrl->base));
+- }
+-
+ /*
+ * LVTS_MONCTL1 : Period unit and group interval configuration
+ *
+@@ -977,6 +959,15 @@ static int lvts_ctrl_start(struct device *dev, struct lvts_ctrl *lvts_ctrl)
+ struct thermal_zone_device *tz;
+ u32 sensor_map = 0;
+ int i;
++ /*
++ * Bitmaps to enable each sensor on immediate and filtered modes, as
++ * described in MSRCTL1 and MONCTL0 registers below, respectively.
++ */
++ u32 sensor_imm_bitmap[] = { BIT(4), BIT(5), BIT(6), BIT(9) };
++ u32 sensor_filt_bitmap[] = { BIT(0), BIT(1), BIT(2), BIT(3) };
++
++ u32 *sensor_bitmap = lvts_ctrl->mode == LVTS_MSR_IMMEDIATE_MODE ?
++ sensor_imm_bitmap : sensor_filt_bitmap;
+
+ for (i = 0; i < lvts_ctrl->num_lvts_sensor; i++) {
+
+@@ -1012,20 +1003,38 @@ static int lvts_ctrl_start(struct device *dev, struct lvts_ctrl *lvts_ctrl)
+ * map, so we can enable the temperature monitoring in
+ * the hardware thermal controller.
+ */
+- sensor_map |= BIT(i);
++ sensor_map |= sensor_bitmap[i];
+ }
+
+ /*
+- * Bits:
+- * 9: Single point access flow
+- * 0-3: Enable sensing point 0-3
+- *
+ * The initialization of the thermal zones give us
+ * which sensor point to enable. If any thermal zone
+ * was not described in the device tree, it won't be
+ * enabled here in the sensor map.
+ */
+- writel(sensor_map | BIT(9), LVTS_MONCTL0(lvts_ctrl->base));
++ if (lvts_ctrl->mode == LVTS_MSR_IMMEDIATE_MODE) {
++ /*
++ * LVTS_MSRCTL1 : Measurement control
++ *
++ * Bits:
++ *
++ * 9: Ignore MSRCTL0 config and do immediate measurement on sensor3
++ * 6: Ignore MSRCTL0 config and do immediate measurement on sensor2
++ * 5: Ignore MSRCTL0 config and do immediate measurement on sensor1
++ * 4: Ignore MSRCTL0 config and do immediate measurement on sensor0
++ *
++ * That configuration will ignore the filtering and the delays
++ * introduced in MONCTL1 and MONCTL2
++ */
++ writel(sensor_map, LVTS_MSRCTL1(lvts_ctrl->base));
++ } else {
++ /*
++ * Bits:
++ * 9: Single point access flow
++ * 0-3: Enable sensing point 0-3
++ */
++ writel(sensor_map | BIT(9), LVTS_MONCTL0(lvts_ctrl->base));
++ }
+
+ return 0;
+ }
+--
+2.40.1
+
--- /dev/null
+From 189659b837560590fd4c14a971a712be4a802fd4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Jul 2023 11:37:37 -0400
+Subject: thermal/drivers/mediatek/lvts_thermal: Manage threshold between
+ sensors
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+
+[ Upstream commit 2bba1acf7a4cbe62abbb4c686e0414209ec5943b ]
+
+Each LVTS thermal controller can have up to four sensors, each capable
+of triggering its own interrupt when its measured temperature crosses
+the configured threshold. The threshold for each sensor is handled
+separately by the thermal framework, since each one is registered with
+its own thermal zone and trips. However, the temperature thresholds are
+configured on the controller, and therefore are shared between all
+sensors on that controller.
+
+When the temperature measured by the sensors is different enough to
+cause the thermal framework to configure different thresholds for each
+one, interrupts start triggering on sensors outside the last threshold
+configured.
+
+To address the issue, track the thresholds required by each sensor and
+only actually set the highest one in the hardware, and disable
+interrupts for all sensors outside the current configured range.
+
+Fixes: f5f633b18234 ("thermal/drivers/mediatek: Add the Low Voltage Thermal Sensor driver")
+Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20230706153823.201943-7-nfraprado@collabora.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/mediatek/lvts_thermal.c | 69 +++++++++++++++++++++++++
+ 1 file changed, 69 insertions(+)
+
+diff --git a/drivers/thermal/mediatek/lvts_thermal.c b/drivers/thermal/mediatek/lvts_thermal.c
+index a6bdcdfffa333..d4f160e8c7dbc 100644
+--- a/drivers/thermal/mediatek/lvts_thermal.c
++++ b/drivers/thermal/mediatek/lvts_thermal.c
+@@ -65,6 +65,11 @@
+ #define LVTS_CALSCALE_CONF 0x300
+ #define LVTS_MONINT_CONF 0x8300318C
+
++#define LVTS_MONINT_OFFSET_SENSOR0 0xC
++#define LVTS_MONINT_OFFSET_SENSOR1 0x180
++#define LVTS_MONINT_OFFSET_SENSOR2 0x3000
++#define LVTS_MONINT_OFFSET_SENSOR3 0x3000000
++
+ #define LVTS_INT_SENSOR0 0x0009001F
+ #define LVTS_INT_SENSOR1 0x001203E0
+ #define LVTS_INT_SENSOR2 0x00247C00
+@@ -110,6 +115,8 @@ struct lvts_sensor {
+ void __iomem *base;
+ int id;
+ int dt_id;
++ int low_thresh;
++ int high_thresh;
+ };
+
+ struct lvts_ctrl {
+@@ -119,6 +126,8 @@ struct lvts_ctrl {
+ int num_lvts_sensor;
+ int mode;
+ void __iomem *base;
++ int low_thresh;
++ int high_thresh;
+ };
+
+ struct lvts_domain {
+@@ -290,12 +299,66 @@ static int lvts_get_temp(struct thermal_zone_device *tz, int *temp)
+ return 0;
+ }
+
++static void lvts_update_irq_mask(struct lvts_ctrl *lvts_ctrl)
++{
++ u32 masks[] = {
++ LVTS_MONINT_OFFSET_SENSOR0,
++ LVTS_MONINT_OFFSET_SENSOR1,
++ LVTS_MONINT_OFFSET_SENSOR2,
++ LVTS_MONINT_OFFSET_SENSOR3,
++ };
++ u32 value = 0;
++ int i;
++
++ value = readl(LVTS_MONINT(lvts_ctrl->base));
++
++ for (i = 0; i < ARRAY_SIZE(masks); i++) {
++ if (lvts_ctrl->sensors[i].high_thresh == lvts_ctrl->high_thresh
++ && lvts_ctrl->sensors[i].low_thresh == lvts_ctrl->low_thresh)
++ value |= masks[i];
++ else
++ value &= ~masks[i];
++ }
++
++ writel(value, LVTS_MONINT(lvts_ctrl->base));
++}
++
++static bool lvts_should_update_thresh(struct lvts_ctrl *lvts_ctrl, int high)
++{
++ int i;
++
++ if (high > lvts_ctrl->high_thresh)
++ return true;
++
++ for (i = 0; i < lvts_ctrl->num_lvts_sensor; i++)
++ if (lvts_ctrl->sensors[i].high_thresh == lvts_ctrl->high_thresh
++ && lvts_ctrl->sensors[i].low_thresh == lvts_ctrl->low_thresh)
++ return false;
++
++ return true;
++}
++
+ static int lvts_set_trips(struct thermal_zone_device *tz, int low, int high)
+ {
+ struct lvts_sensor *lvts_sensor = thermal_zone_device_priv(tz);
++ struct lvts_ctrl *lvts_ctrl = container_of(lvts_sensor, struct lvts_ctrl, sensors[lvts_sensor->id]);
+ void __iomem *base = lvts_sensor->base;
+ u32 raw_low = lvts_temp_to_raw(low != -INT_MAX ? low : LVTS_MINIMUM_THRESHOLD);
+ u32 raw_high = lvts_temp_to_raw(high);
++ bool should_update_thresh;
++
++ lvts_sensor->low_thresh = low;
++ lvts_sensor->high_thresh = high;
++
++ should_update_thresh = lvts_should_update_thresh(lvts_ctrl, high);
++ if (should_update_thresh) {
++ lvts_ctrl->high_thresh = high;
++ lvts_ctrl->low_thresh = low;
++ }
++ lvts_update_irq_mask(lvts_ctrl);
++
++ if (!should_update_thresh)
++ return 0;
+
+ /*
+ * Low offset temperature threshold
+@@ -519,6 +582,9 @@ static int lvts_sensor_init(struct device *dev, struct lvts_ctrl *lvts_ctrl,
+ */
+ lvts_sensor[i].msr = lvts_ctrl_data->mode == LVTS_MSR_IMMEDIATE_MODE ?
+ imm_regs[i] : msr_regs[i];
++
++ lvts_sensor[i].low_thresh = INT_MIN;
++ lvts_sensor[i].high_thresh = INT_MIN;
+ };
+
+ lvts_ctrl->num_lvts_sensor = lvts_ctrl_data->num_lvts_sensor;
+@@ -686,6 +752,9 @@ static int lvts_ctrl_init(struct device *dev, struct lvts_domain *lvts_td,
+ */
+ lvts_ctrl[i].hw_tshut_raw_temp =
+ lvts_temp_to_raw(lvts_data->lvts_ctrl[i].hw_tshut_temp);
++
++ lvts_ctrl[i].low_thresh = INT_MIN;
++ lvts_ctrl[i].high_thresh = INT_MIN;
+ }
+
+ /*
+--
+2.40.1
+
--- /dev/null
+From 3e9c49981f84380adda47ae25762ee0039906203 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Jul 2023 11:37:34 -0400
+Subject: thermal/drivers/mediatek/lvts_thermal: Use offset threshold for IRQ
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+
+[ Upstream commit f79e996c7ed27bb196facbcd1c69ee33631d7051 ]
+
+There are two kinds of temperature monitoring interrupts available:
+* High Offset, Low Offset
+* Hot, Hot to normal, Cold
+
+The code currently uses the hot/h2n/cold interrupts, however in a way
+that doesn't work: the cold threshold is left uninitialized, which
+prevents the other thresholds from ever triggering, and the h2n
+interrupt is used as the lower threshold, which prevents the hot
+interrupt from triggering again after the thresholds are updated by the
+thermal framework, since a hot interrupt can only trigger again after
+the hot to normal interrupt has been triggered.
+
+But better yet than addressing those issues, is to use the high/low
+offset interrupts instead. This way only two thresholds need to be
+managed, which have a simpler state machine, making them a better match
+to the thermal framework's high and low thresholds.
+
+Fixes: f5f633b18234 ("thermal/drivers/mediatek: Add the Low Voltage Thermal Sensor driver")
+Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20230706153823.201943-4-nfraprado@collabora.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/mediatek/lvts_thermal.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/thermal/mediatek/lvts_thermal.c b/drivers/thermal/mediatek/lvts_thermal.c
+index 64748153d181e..80abd10596d85 100644
+--- a/drivers/thermal/mediatek/lvts_thermal.c
++++ b/drivers/thermal/mediatek/lvts_thermal.c
+@@ -296,9 +296,9 @@ static int lvts_set_trips(struct thermal_zone_device *tz, int low, int high)
+ u32 raw_high = lvts_temp_to_raw(high);
+
+ /*
+- * Hot to normal temperature threshold
++ * Low offset temperature threshold
+ *
+- * LVTS_H2NTHRE
++ * LVTS_OFFSETL
+ *
+ * Bits:
+ *
+@@ -307,13 +307,13 @@ static int lvts_set_trips(struct thermal_zone_device *tz, int low, int high)
+ if (low != -INT_MAX) {
+ pr_debug("%s: Setting low limit temperature interrupt: %d\n",
+ thermal_zone_device_type(tz), low);
+- writel(raw_low, LVTS_H2NTHRE(base));
++ writel(raw_low, LVTS_OFFSETL(base));
+ }
+
+ /*
+- * Hot temperature threshold
++ * High offset temperature threshold
+ *
+- * LVTS_HTHRE
++ * LVTS_OFFSETH
+ *
+ * Bits:
+ *
+@@ -321,7 +321,7 @@ static int lvts_set_trips(struct thermal_zone_device *tz, int low, int high)
+ */
+ pr_debug("%s: Setting high limit temperature interrupt: %d\n",
+ thermal_zone_device_type(tz), high);
+- writel(raw_high, LVTS_HTHRE(base));
++ writel(raw_high, LVTS_OFFSETH(base));
+
+ return 0;
+ }
+--
+2.40.1
+
--- /dev/null
+From 77abd63355be2bb4057c55f8f2d3fcb39f630dd8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Jul 2023 09:16:36 +0800
+Subject: thermal/of: Fix potential uninitialized value access
+
+From: Peng Fan <peng.fan@nxp.com>
+
+[ Upstream commit f96801f0cfcefc0a16b146596577c53c75ee9773 ]
+
+If of_parse_phandle_with_args() called from __thermal_of_bind() or
+__thermal_of_unbind() fails, cooling_spec.np will not be initialized,
+so move the of_node_put() calls below the respective return value checks
+to avoid dereferencing an uninitialized pointer.
+
+Fixes: 3fd6d6e2b4e8 ("thermal/of: Rework the thermal device tree initialization")
+Signed-off-by: Peng Fan <peng.fan@nxp.com>
+[ rjw: Subject and changelog edits ]
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/thermal_of.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c
+index bc07ae1c284cf..22272f9c5934a 100644
+--- a/drivers/thermal/thermal_of.c
++++ b/drivers/thermal/thermal_of.c
+@@ -292,13 +292,13 @@ static int __thermal_of_unbind(struct device_node *map_np, int index, int trip_i
+ ret = of_parse_phandle_with_args(map_np, "cooling-device", "#cooling-cells",
+ index, &cooling_spec);
+
+- of_node_put(cooling_spec.np);
+-
+ if (ret < 0) {
+ pr_err("Invalid cooling-device entry\n");
+ return ret;
+ }
+
++ of_node_put(cooling_spec.np);
++
+ if (cooling_spec.args_count < 2) {
+ pr_err("wrong reference to cooling device, missing limits\n");
+ return -EINVAL;
+@@ -325,13 +325,13 @@ static int __thermal_of_bind(struct device_node *map_np, int index, int trip_id,
+ ret = of_parse_phandle_with_args(map_np, "cooling-device", "#cooling-cells",
+ index, &cooling_spec);
+
+- of_node_put(cooling_spec.np);
+-
+ if (ret < 0) {
+ pr_err("Invalid cooling-device entry\n");
+ return ret;
+ }
+
++ of_node_put(cooling_spec.np);
++
+ if (cooling_spec.args_count < 2) {
+ pr_err("wrong reference to cooling device, missing limits\n");
+ return -EINVAL;
+--
+2.40.1
+
--- /dev/null
+From 55384ea86b38739f24befa15ca48fb465f7d2bb0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Aug 2023 16:07:57 -0400
+Subject: tick/rcu: Fix false positive "softirq work is pending" messages
+
+From: Paul Gortmaker <paul.gortmaker@windriver.com>
+
+[ Upstream commit 96c1fa04f089a7e977a44e4e8fdc92e81be20bef ]
+
+In commit 0345691b24c0 ("tick/rcu: Stop allowing RCU_SOFTIRQ in idle") the
+new function report_idle_softirq() was created by breaking code out of the
+existing can_stop_idle_tick() for kernels v5.18 and newer.
+
+In doing so, the code essentially went from a one conditional:
+
+ if (a && b && c)
+ warn();
+
+to a three conditional:
+
+ if (!a)
+ return;
+ if (!b)
+ return;
+ if (!c)
+ return;
+ warn();
+
+But that conversion got the condition for the RT specific
+local_bh_blocked() wrong. The original condition was:
+
+ !local_bh_blocked()
+
+but the conversion failed to negate it so it ended up as:
+
+ if (!local_bh_blocked())
+ return false;
+
+This issue lay dormant until another fixup for the same commit was added
+in commit a7e282c77785 ("tick/rcu: Fix bogus ratelimit condition").
+This commit realized the ratelimit was essentially set to zero instead
+of ten, and hence *no* softirq pending messages would ever be issued.
+
+Once this commit was backported via linux-stable, both the v6.1 and v6.4
+preempt-rt kernels started printing out 10 instances of this at boot:
+
+ NOHZ tick-stop error: local softirq work is pending, handler #80!!!
+
+Remove the negation and return when local_bh_blocked() evaluates to true to
+bring the correct behaviour back.
+
+Fixes: 0345691b24c0 ("tick/rcu: Stop allowing RCU_SOFTIRQ in idle")
+Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Tested-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
+Reviewed-by: Wen Yang <wenyang.linux@foxmail.com>
+Acked-by: Frederic Weisbecker <frederic@kernel.org>
+Link: https://lore.kernel.org/r/20230818200757.1808398-1-paul.gortmaker@windriver.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/time/tick-sched.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
+index 4df14db4da490..87015e9deacc9 100644
+--- a/kernel/time/tick-sched.c
++++ b/kernel/time/tick-sched.c
+@@ -1045,7 +1045,7 @@ static bool report_idle_softirq(void)
+ return false;
+
+ /* On RT, softirqs handling may be waiting on some lock */
+- if (!local_bh_blocked())
++ if (local_bh_blocked())
+ return false;
+
+ pr_warn("NOHZ tick-stop error: local softirq work is pending, handler #%02x!!!\n",
+--
+2.40.1
+
--- /dev/null
+From 26f21540bd294bb17e77e746da60bb7ef4d73527 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Aug 2023 18:17:04 +0200
+Subject: tmpfs: verify {g,u}id mount options correctly
+
+From: Christian Brauner <brauner@kernel.org>
+
+[ Upstream commit 0200679fc7953177941e41c2a4241d0b6c2c5de8 ]
+
+A while ago we received the following report:
+
+"The other outstanding issue I noticed comes from the fact that
+fsconfig syscalls may occur in a different userns than that which
+called fsopen. That means that resolving the uid/gid via
+current_user_ns() can save a kuid that isn't mapped in the associated
+namespace when the filesystem is finally mounted. This means that it
+is possible for an unprivileged user to create files owned by any
+group in a tmpfs mount (since we can set the SUID bit on the tmpfs
+directory), or a tmpfs that is owned by any user, including the root
+group/user."
+
+The contract for {g,u}id mount options and {g,u}id values in general set
+from userspace has always been that they are translated according to the
+caller's idmapping. In so far, tmpfs has been doing the correct thing.
+But since tmpfs is mountable in unprivileged contexts it is also
+necessary to verify that the resulting {k,g}uid is representable in the
+namespace of the superblock to avoid such bugs as above.
+
+The new mount api's cross-namespace delegation abilities are already
+widely used. After having talked to a bunch of userspace this is the
+most faithful solution with minimal regression risks. I know of one
+users - systemd - that makes use of the new mount api in this way and
+they don't set unresolable {g,u}ids. So the regression risk is minimal.
+
+Link: https://lore.kernel.org/lkml/CALxfFW4BXhEwxR0Q5LSkg-8Vb4r2MONKCcUCVioehXQKr35eHg@mail.gmail.com
+Fixes: f32356261d44 ("vfs: Convert ramfs, shmem, tmpfs, devtmpfs, rootfs to use the new mount API")
+Reviewed-by: "Seth Forshee (DigitalOcean)" <sforshee@kernel.org>
+Reported-by: Seth Jenkins <sethjenkins@google.com>
+Message-Id: <20230801-vfs-fs_context-uidgid-v1-1-daf46a050bbf@kernel.org>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/shmem.c | 28 ++++++++++++++++++++++++----
+ 1 file changed, 24 insertions(+), 4 deletions(-)
+
+diff --git a/mm/shmem.c b/mm/shmem.c
+index fe208a072e594..87cc98a9a014a 100644
+--- a/mm/shmem.c
++++ b/mm/shmem.c
+@@ -3506,6 +3506,8 @@ static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param)
+ unsigned long long size;
+ char *rest;
+ int opt;
++ kuid_t kuid;
++ kgid_t kgid;
+
+ opt = fs_parse(fc, shmem_fs_parameters, param, &result);
+ if (opt < 0)
+@@ -3541,14 +3543,32 @@ static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param)
+ ctx->mode = result.uint_32 & 07777;
+ break;
+ case Opt_uid:
+- ctx->uid = make_kuid(current_user_ns(), result.uint_32);
+- if (!uid_valid(ctx->uid))
++ kuid = make_kuid(current_user_ns(), result.uint_32);
++ if (!uid_valid(kuid))
+ goto bad_value;
++
++ /*
++ * The requested uid must be representable in the
++ * filesystem's idmapping.
++ */
++ if (!kuid_has_mapping(fc->user_ns, kuid))
++ goto bad_value;
++
++ ctx->uid = kuid;
+ break;
+ case Opt_gid:
+- ctx->gid = make_kgid(current_user_ns(), result.uint_32);
+- if (!gid_valid(ctx->gid))
++ kgid = make_kgid(current_user_ns(), result.uint_32);
++ if (!gid_valid(kgid))
+ goto bad_value;
++
++ /*
++ * The requested gid must be representable in the
++ * filesystem's idmapping.
++ */
++ if (!kgid_has_mapping(fc->user_ns, kgid))
++ goto bad_value;
++
++ ctx->gid = kgid;
+ break;
+ case Opt_huge:
+ ctx->huge = result.uint_32;
+--
+2.40.1
+
--- /dev/null
+From a08ee46d2ceb29adc525a4da098e2e48e2be0443 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 31 Aug 2023 21:27:39 +0800
+Subject: tracing: Fix race issue between cpu buffer write and swap
+
+From: Zheng Yejian <zhengyejian1@huawei.com>
+
+[ Upstream commit 3163f635b20e9e1fb4659e74f47918c9dddfe64e ]
+
+Warning happened in rb_end_commit() at code:
+ if (RB_WARN_ON(cpu_buffer, !local_read(&cpu_buffer->committing)))
+
+ WARNING: CPU: 0 PID: 139 at kernel/trace/ring_buffer.c:3142
+ rb_commit+0x402/0x4a0
+ Call Trace:
+ ring_buffer_unlock_commit+0x42/0x250
+ trace_buffer_unlock_commit_regs+0x3b/0x250
+ trace_event_buffer_commit+0xe5/0x440
+ trace_event_buffer_reserve+0x11c/0x150
+ trace_event_raw_event_sched_switch+0x23c/0x2c0
+ __traceiter_sched_switch+0x59/0x80
+ __schedule+0x72b/0x1580
+ schedule+0x92/0x120
+ worker_thread+0xa0/0x6f0
+
+It is because the race between writing event into cpu buffer and swapping
+cpu buffer through file per_cpu/cpu0/snapshot:
+
+ Write on CPU 0 Swap buffer by per_cpu/cpu0/snapshot on CPU 1
+ -------- --------
+ tracing_snapshot_write()
+ [...]
+
+ ring_buffer_lock_reserve()
+ cpu_buffer = buffer->buffers[cpu]; // 1. Suppose find 'cpu_buffer_a';
+ [...]
+ rb_reserve_next_event()
+ [...]
+
+ ring_buffer_swap_cpu()
+ if (local_read(&cpu_buffer_a->committing))
+ goto out_dec;
+ if (local_read(&cpu_buffer_b->committing))
+ goto out_dec;
+ buffer_a->buffers[cpu] = cpu_buffer_b;
+ buffer_b->buffers[cpu] = cpu_buffer_a;
+ // 2. cpu_buffer has swapped here.
+
+ rb_start_commit(cpu_buffer);
+ if (unlikely(READ_ONCE(cpu_buffer->buffer)
+ != buffer)) { // 3. This check passed due to 'cpu_buffer->buffer'
+ [...] // has not changed here.
+ return NULL;
+ }
+ cpu_buffer_b->buffer = buffer_a;
+ cpu_buffer_a->buffer = buffer_b;
+ [...]
+
+ // 4. Reserve event from 'cpu_buffer_a'.
+
+ ring_buffer_unlock_commit()
+ [...]
+ cpu_buffer = buffer->buffers[cpu]; // 5. Now find 'cpu_buffer_b' !!!
+ rb_commit(cpu_buffer)
+ rb_end_commit() // 6. WARN for the wrong 'committing' state !!!
+
+Based on above analysis, we can easily reproduce by following testcase:
+ ``` bash
+ #!/bin/bash
+
+ dmesg -n 7
+ sysctl -w kernel.panic_on_warn=1
+ TR=/sys/kernel/tracing
+ echo 7 > ${TR}/buffer_size_kb
+ echo "sched:sched_switch" > ${TR}/set_event
+ while [ true ]; do
+ echo 1 > ${TR}/per_cpu/cpu0/snapshot
+ done &
+ while [ true ]; do
+ echo 1 > ${TR}/per_cpu/cpu0/snapshot
+ done &
+ while [ true ]; do
+ echo 1 > ${TR}/per_cpu/cpu0/snapshot
+ done &
+ ```
+
+To fix it, IIUC, we can use smp_call_function_single() to do the swap on
+the target cpu where the buffer is located, so that above race would be
+avoided.
+
+Link: https://lore.kernel.org/linux-trace-kernel/20230831132739.4070878-1-zhengyejian1@huawei.com
+
+Cc: <mhiramat@kernel.org>
+Fixes: f1affcaaa861 ("tracing: Add snapshot in the per_cpu trace directories")
+Signed-off-by: Zheng Yejian <zhengyejian1@huawei.com>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/trace.c | 17 ++++++++++++-----
+ 1 file changed, 12 insertions(+), 5 deletions(-)
+
+diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
+index 9614248b98f1a..133be5a19b920 100644
+--- a/kernel/trace/trace.c
++++ b/kernel/trace/trace.c
+@@ -7590,6 +7590,11 @@ static int tracing_snapshot_open(struct inode *inode, struct file *file)
+ return ret;
+ }
+
++static void tracing_swap_cpu_buffer(void *tr)
++{
++ update_max_tr_single((struct trace_array *)tr, current, smp_processor_id());
++}
++
+ static ssize_t
+ tracing_snapshot_write(struct file *filp, const char __user *ubuf, size_t cnt,
+ loff_t *ppos)
+@@ -7648,13 +7653,15 @@ tracing_snapshot_write(struct file *filp, const char __user *ubuf, size_t cnt,
+ ret = tracing_alloc_snapshot_instance(tr);
+ if (ret < 0)
+ break;
+- local_irq_disable();
+ /* Now, we're going to swap */
+- if (iter->cpu_file == RING_BUFFER_ALL_CPUS)
++ if (iter->cpu_file == RING_BUFFER_ALL_CPUS) {
++ local_irq_disable();
+ update_max_tr(tr, current, smp_processor_id(), NULL);
+- else
+- update_max_tr_single(tr, current, iter->cpu_file);
+- local_irq_enable();
++ local_irq_enable();
++ } else {
++ smp_call_function_single(iter->cpu_file, tracing_swap_cpu_buffer,
++ (void *)tr, 1);
++ }
+ break;
+ default:
+ if (tr->allocated_snapshot) {
+--
+2.40.1
+
--- /dev/null
+From 48e98fcda3e7346a0ba10e840e3e8bb809730c4e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Aug 2023 13:34:30 +0300
+Subject: tracing: Remove extra space at the end of hwlat_detector/mode
+
+From: Mikhail Kobuk <m.kobuk@ispras.ru>
+
+[ Upstream commit 2cf0dee989a8b2501929eaab29473b6b1fa11057 ]
+
+Space is printed after each mode value including the last one:
+$ echo \"$(sudo cat /sys/kernel/tracing/hwlat_detector/mode)\"
+"none [round-robin] per-cpu "
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Link: https://lore.kernel.org/linux-trace-kernel/20230825103432.7750-1-m.kobuk@ispras.ru
+
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Fixes: 8fa826b7344d ("trace/hwlat: Implement the mode config option")
+Signed-off-by: Mikhail Kobuk <m.kobuk@ispras.ru>
+Reviewed-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
+Acked-by: Daniel Bristot de Oliveira <bristot@kernel.org>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/trace_hwlat.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/trace/trace_hwlat.c b/kernel/trace/trace_hwlat.c
+index 2f37a6e68aa9f..b791524a6536a 100644
+--- a/kernel/trace/trace_hwlat.c
++++ b/kernel/trace/trace_hwlat.c
+@@ -635,7 +635,7 @@ static int s_mode_show(struct seq_file *s, void *v)
+ else
+ seq_printf(s, "%s", thread_mode_str[mode]);
+
+- if (mode != MODE_MAX)
++ if (mode < MODE_MAX - 1) /* if mode is any but last */
+ seq_puts(s, " ");
+
+ return 0;
+--
+2.40.1
+
--- /dev/null
+From de1f8ee448f6b21a6db30a0a256f6c019fbaa305 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Aug 2023 16:23:13 +0530
+Subject: tty: serial: qcom-geni-serial: Poll primary sequencer irq status
+ after cancel_tx
+
+From: Vijaya Krishna Nivarthi <quic_vnivarth@quicinc.com>
+
+[ Upstream commit 9c8441330bb399cba6177acce9b0e68c0dbaa597 ]
+
+TX is handled by primary sequencer. After cancelling primary command, poll
+primary sequencer's irq status instead of that of secondary.
+While at it, also remove a couple of redundant lines that read from IRQ_EN
+register and write back same.
+
+Fixes: 2aaa43c70778 ("tty: serial: qcom-geni-serial: add support for serial engine DMA")
+Signed-off-by: Vijaya Krishna Nivarthi <quic_vnivarth@quicinc.com>
+Link: https://lore.kernel.org/r/1691578393-9891-1-git-send-email-quic_vnivarth@quicinc.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/qcom_geni_serial.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
+index 24ebdb0b63a8e..ae632a9d4f3ae 100644
+--- a/drivers/tty/serial/qcom_geni_serial.c
++++ b/drivers/tty/serial/qcom_geni_serial.c
+@@ -592,7 +592,6 @@ static void qcom_geni_serial_stop_tx_dma(struct uart_port *uport)
+ {
+ struct qcom_geni_serial_port *port = to_dev_port(uport);
+ bool done;
+- u32 m_irq_en;
+
+ if (!qcom_geni_serial_main_active(uport))
+ return;
+@@ -604,12 +603,10 @@ static void qcom_geni_serial_stop_tx_dma(struct uart_port *uport)
+ port->tx_remaining = 0;
+ }
+
+- m_irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
+- writel(m_irq_en, uport->membase + SE_GENI_M_IRQ_EN);
+ geni_se_cancel_m_cmd(&port->se);
+
+- done = qcom_geni_serial_poll_bit(uport, SE_GENI_S_IRQ_STATUS,
+- S_CMD_CANCEL_EN, true);
++ done = qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS,
++ M_CMD_CANCEL_EN, true);
+ if (!done) {
+ geni_se_abort_m_cmd(&port->se);
+ done = qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS,
+--
+2.40.1
+
--- /dev/null
+From 7728f34b0c82e51fe737b1b8990444c343414ddc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Jul 2023 17:30:05 +0200
+Subject: udp: re-score reuseport groups when connected sockets are present
+
+From: Lorenz Bauer <lmb@isovalent.com>
+
+[ Upstream commit f0ea27e7bfe1c34e1f451a63eb68faa1d4c3a86d ]
+
+Contrary to TCP, UDP reuseport groups can contain TCP_ESTABLISHED
+sockets. To support these properly we remember whether a group has
+a connected socket and skip the fast reuseport early-return. In
+effect we continue scoring all reuseport sockets and then choose the
+one with the highest score.
+
+The current code fails to re-calculate the score for the result of
+lookup_reuseport. According to Kuniyuki Iwashima:
+
+ 1) SO_INCOMING_CPU is set
+ -> selected sk might have +1 score
+
+ 2) BPF prog returns ESTABLISHED and/or SO_INCOMING_CPU sk
+ -> selected sk will have more than 8
+
+ Using the old score could trigger more lookups depending on the
+ order that sockets are created.
+
+ sk -> sk (SO_INCOMING_CPU) -> sk (ESTABLISHED)
+ | |
+ `-> select the next SO_INCOMING_CPU sk
+ |
+ `-> select itself (We should save this lookup)
+
+Fixes: efc6b6f6c311 ("udp: Improve load balancing for SO_REUSEPORT.")
+Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: Lorenz Bauer <lmb@isovalent.com>
+Link: https://lore.kernel.org/r/20230720-so-reuseport-v6-1-7021b683cdae@isovalent.com
+Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/udp.c | 20 +++++++++++++++-----
+ net/ipv6/udp.c | 19 ++++++++++++++-----
+ 2 files changed, 29 insertions(+), 10 deletions(-)
+
+diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
+index 6d327d6d978c5..a3302136ce92e 100644
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -452,14 +452,24 @@ static struct sock *udp4_lib_lookup2(struct net *net,
+ score = compute_score(sk, net, saddr, sport,
+ daddr, hnum, dif, sdif);
+ if (score > badness) {
+- result = lookup_reuseport(net, sk, skb,
+- saddr, sport, daddr, hnum);
++ badness = score;
++ result = lookup_reuseport(net, sk, skb, saddr, sport, daddr, hnum);
++ if (!result) {
++ result = sk;
++ continue;
++ }
++
+ /* Fall back to scoring if group has connections */
+- if (result && !reuseport_has_conns(sk))
++ if (!reuseport_has_conns(sk))
+ return result;
+
+- result = result ? : sk;
+- badness = score;
++ /* Reuseport logic returned an error, keep original score. */
++ if (IS_ERR(result))
++ continue;
++
++ badness = compute_score(result, net, saddr, sport,
++ daddr, hnum, dif, sdif);
++
+ }
+ }
+ return result;
+diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
+index 8521729fb2375..9c7457823eb97 100644
+--- a/net/ipv6/udp.c
++++ b/net/ipv6/udp.c
+@@ -195,14 +195,23 @@ static struct sock *udp6_lib_lookup2(struct net *net,
+ score = compute_score(sk, net, saddr, sport,
+ daddr, hnum, dif, sdif);
+ if (score > badness) {
+- result = lookup_reuseport(net, sk, skb,
+- saddr, sport, daddr, hnum);
++ badness = score;
++ result = lookup_reuseport(net, sk, skb, saddr, sport, daddr, hnum);
++ if (!result) {
++ result = sk;
++ continue;
++ }
++
+ /* Fall back to scoring if group has connections */
+- if (result && !reuseport_has_conns(sk))
++ if (!reuseport_has_conns(sk))
+ return result;
+
+- result = result ? : sk;
+- badness = score;
++ /* Reuseport logic returned an error, keep original score. */
++ if (IS_ERR(result))
++ continue;
++
++ badness = compute_score(sk, net, saddr, sport,
++ daddr, hnum, dif, sdif);
+ }
+ }
+ return result;
+--
+2.40.1
+
--- /dev/null
+From 66a52841baad80d5fa0f3c87eb5f355b8eb4948c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Aug 2023 22:15:00 -0700
+Subject: um: Fix hostaudio build errors
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit db4bfcba7bb8d10f00bba2a3da6b9a9c2a1d7b71 ]
+
+Use "select" to ensure that the required kconfig symbols are set
+as expected.
+Drop HOSTAUDIO since it is now equivalent to UML_SOUND.
+
+Set CONFIG_SOUND=m in ARCH=um defconfig files to maintain the
+status quo of the default configs.
+
+Allow SOUND with UML regardless of HAS_IOMEM. Otherwise there is a
+kconfig warning for unmet dependencies. (This was not an issue when
+SOUND was defined in arch/um/drivers/Kconfig. I have done 50 randconfig
+builds and didn't find any issues.)
+
+This fixes build errors when CONFIG_SOUND is not set:
+
+ld: arch/um/drivers/hostaudio_kern.o: in function `hostaudio_cleanup_module':
+hostaudio_kern.c:(.exit.text+0xa): undefined reference to `unregister_sound_mixer'
+ld: hostaudio_kern.c:(.exit.text+0x15): undefined reference to `unregister_sound_dsp'
+ld: arch/um/drivers/hostaudio_kern.o: in function `hostaudio_init_module':
+hostaudio_kern.c:(.init.text+0x19): undefined reference to `register_sound_dsp'
+ld: hostaudio_kern.c:(.init.text+0x31): undefined reference to `register_sound_mixer'
+ld: hostaudio_kern.c:(.init.text+0x49): undefined reference to `unregister_sound_dsp'
+
+and this kconfig warning:
+WARNING: unmet direct dependencies detected for SOUND
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Fixes: d886e87cb82b ("sound: make OSS sound core optional")
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: lore.kernel.org/r/202307141416.vxuRVpFv-lkp@intel.com
+Cc: Richard Weinberger <richard@nod.at>
+Cc: Anton Ivanov <anton.ivanov@cambridgegreys.com>
+Cc: Johannes Berg <johannes@sipsolutions.net>
+Cc: linux-um@lists.infradead.org
+Cc: Tejun Heo <tj@kernel.org>
+Cc: Takashi Iwai <tiwai@suse.de>
+Cc: Jaroslav Kysela <perex@perex.cz>
+Cc: Masahiro Yamada <masahiroy@kernel.org>
+Cc: Nathan Chancellor <nathan@kernel.org>
+Cc: Nick Desaulniers <ndesaulniers@google.com>
+Cc: Nicolas Schier <nicolas@fjasle.eu>
+Cc: linux-kbuild@vger.kernel.org
+Cc: alsa-devel@alsa-project.org
+Reviewed-by: Masahiro Yamada <masahiroy@kernel.org>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/um/configs/i386_defconfig | 1 +
+ arch/um/configs/x86_64_defconfig | 1 +
+ arch/um/drivers/Kconfig | 16 +++-------------
+ arch/um/drivers/Makefile | 2 +-
+ sound/Kconfig | 2 +-
+ 5 files changed, 7 insertions(+), 15 deletions(-)
+
+diff --git a/arch/um/configs/i386_defconfig b/arch/um/configs/i386_defconfig
+index c0162286d68b7..c33a6880a437a 100644
+--- a/arch/um/configs/i386_defconfig
++++ b/arch/um/configs/i386_defconfig
+@@ -35,6 +35,7 @@ CONFIG_TTY_CHAN=y
+ CONFIG_XTERM_CHAN=y
+ CONFIG_CON_CHAN="pts"
+ CONFIG_SSL_CHAN="pts"
++CONFIG_SOUND=m
+ CONFIG_UML_SOUND=m
+ CONFIG_DEVTMPFS=y
+ CONFIG_DEVTMPFS_MOUNT=y
+diff --git a/arch/um/configs/x86_64_defconfig b/arch/um/configs/x86_64_defconfig
+index bec6e5d956873..df29f282b6ac2 100644
+--- a/arch/um/configs/x86_64_defconfig
++++ b/arch/um/configs/x86_64_defconfig
+@@ -33,6 +33,7 @@ CONFIG_TTY_CHAN=y
+ CONFIG_XTERM_CHAN=y
+ CONFIG_CON_CHAN="pts"
+ CONFIG_SSL_CHAN="pts"
++CONFIG_SOUND=m
+ CONFIG_UML_SOUND=m
+ CONFIG_DEVTMPFS=y
+ CONFIG_DEVTMPFS_MOUNT=y
+diff --git a/arch/um/drivers/Kconfig b/arch/um/drivers/Kconfig
+index 36911b1fddcf0..b94b2618e7d84 100644
+--- a/arch/um/drivers/Kconfig
++++ b/arch/um/drivers/Kconfig
+@@ -111,24 +111,14 @@ config SSL_CHAN
+
+ config UML_SOUND
+ tristate "Sound support"
++ depends on SOUND
++ select SOUND_OSS_CORE
+ help
+ This option enables UML sound support. If enabled, it will pull in
+- soundcore and the UML hostaudio relay, which acts as a intermediary
++ the UML hostaudio relay, which acts as a intermediary
+ between the host's dsp and mixer devices and the UML sound system.
+ It is safe to say 'Y' here.
+
+-config SOUND
+- tristate
+- default UML_SOUND
+-
+-config SOUND_OSS_CORE
+- bool
+- default UML_SOUND
+-
+-config HOSTAUDIO
+- tristate
+- default UML_SOUND
+-
+ endmenu
+
+ menu "UML Network Devices"
+diff --git a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile
+index a461a950f0518..0e6af81096fd5 100644
+--- a/arch/um/drivers/Makefile
++++ b/arch/um/drivers/Makefile
+@@ -54,7 +54,7 @@ obj-$(CONFIG_UML_NET) += net.o
+ obj-$(CONFIG_MCONSOLE) += mconsole.o
+ obj-$(CONFIG_MMAPPER) += mmapper_kern.o
+ obj-$(CONFIG_BLK_DEV_UBD) += ubd.o
+-obj-$(CONFIG_HOSTAUDIO) += hostaudio.o
++obj-$(CONFIG_UML_SOUND) += hostaudio.o
+ obj-$(CONFIG_NULL_CHAN) += null.o
+ obj-$(CONFIG_PORT_CHAN) += port.o
+ obj-$(CONFIG_PTY_CHAN) += pty.o
+diff --git a/sound/Kconfig b/sound/Kconfig
+index 0ddfb717b81dc..466e848689bd1 100644
+--- a/sound/Kconfig
++++ b/sound/Kconfig
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0-only
+ menuconfig SOUND
+ tristate "Sound card support"
+- depends on HAS_IOMEM
++ depends on HAS_IOMEM || UML
+ help
+ If you have a sound card in your computer, i.e. if it can say more
+ than an occasional beep, say Y.
+--
+2.40.1
+
--- /dev/null
+From 4a86bae21a4320aa334bec045de22ca09e9ec78b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Aug 2023 12:40:44 +0200
+Subject: um: virt-pci: fix missing declaration warning
+
+From: Vincent Whitchurch <vincent.whitchurch@axis.com>
+
+[ Upstream commit 974b808d85abbc03c3914af63d60d5816aabf2ca ]
+
+Fix this warning which appears with W=1 and without CONFIG_OF:
+
+ warning: no previous declaration for 'pcibios_get_phb_of_node'
+
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202308230949.PphIIlhq-lkp@intel.com/
+Fixes: 314a1408b79a ("um: virt-pci: implement pcibios_get_phb_of_node()")
+Signed-off-by: Vincent Whitchurch <vincent.whitchurch@axis.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/um/drivers/virt-pci.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/um/drivers/virt-pci.c b/arch/um/drivers/virt-pci.c
+index 7699ca5f35d48..ffe2ee8a02465 100644
+--- a/arch/um/drivers/virt-pci.c
++++ b/arch/um/drivers/virt-pci.c
+@@ -544,6 +544,7 @@ static void um_pci_irq_vq_cb(struct virtqueue *vq)
+ }
+ }
+
++#ifdef CONFIG_OF
+ /* Copied from arch/x86/kernel/devicetree.c */
+ struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus)
+ {
+@@ -562,6 +563,7 @@ struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus)
+ }
+ return NULL;
+ }
++#endif
+
+ static int um_pci_init_vqs(struct um_pci_device *dev)
+ {
+--
+2.40.1
+
--- /dev/null
+From e780f7c77666f4c136a75ee33c4c265167e63762 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Aug 2023 13:44:38 -0400
+Subject: USB: gadget: core: Add missing kerneldoc for vbus_work
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+[ Upstream commit 159a98afc88e88f588077afe818081d67f50a5e0 ]
+
+Add a missing kerneldoc description of the vbus_work field in struct usb_udc.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Fixes: 50966da807c8 ("usb: gadget: udc: core: Offload usb_udc_vbus_handler processing")
+Link: https://lore.kernel.org/r/1e5e7cda-b2c8-4917-9952-4354f365ede0@rowland.harvard.edu
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/udc/core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c
+index d5bc2892184ca..5ec47757167e8 100644
+--- a/drivers/usb/gadget/udc/core.c
++++ b/drivers/usb/gadget/udc/core.c
+@@ -40,6 +40,7 @@ static const struct bus_type gadget_bus_type;
+ * @allow_connect: Indicates whether UDC is allowed to be pulled up.
+ * Set/cleared by gadget_(un)bind_driver() after gadget driver is bound or
+ * unbound.
++ * @vbus_work: work routine to handle VBUS status change notifications.
+ * @connect_lock: protects udc->started, gadget->connect,
+ * gadget->allow_connect and gadget->deactivate. The routines
+ * usb_gadget_connect_locked(), usb_gadget_disconnect_locked(),
+--
+2.40.1
+
--- /dev/null
+From 1dfe8675904f4108ea016b3f6d6aee8125f74d93 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Aug 2023 13:47:04 -0400
+Subject: USB: gadget: f_mass_storage: Fix unused variable warning
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+[ Upstream commit 55c3e571d2a0aabef4f1354604443f1c415d2e85 ]
+
+Fix a "variable set but not used" warning in f_mass_storage.c. rc is
+used if verbose debugging is enabled but not otherwise.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Fixes: d5e2b67aae79 ("USB: g_mass_storage: template f_mass_storage.c file created")
+Link: https://lore.kernel.org/r/cfed16c7-aa46-494b-ba84-b0e0dc99be3a@rowland.harvard.edu
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/function/f_mass_storage.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c
+index 3a30feb47073f..e927d82f0890d 100644
+--- a/drivers/usb/gadget/function/f_mass_storage.c
++++ b/drivers/usb/gadget/function/f_mass_storage.c
+@@ -927,7 +927,7 @@ static void invalidate_sub(struct fsg_lun *curlun)
+ {
+ struct file *filp = curlun->filp;
+ struct inode *inode = file_inode(filp);
+- unsigned long rc;
++ unsigned long __maybe_unused rc;
+
+ rc = invalidate_mapping_pages(inode->i_mapping, 0, -1);
+ VLDBG(curlun, "invalidate_mapping_pages -> %ld\n", rc);
+--
+2.40.1
+
--- /dev/null
+From 654bdc29ce9c4708398986fdfeb799617ca0f5c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Jun 2023 19:03:52 +0800
+Subject: usb: phy: mxs: fix getting wrong state with mxs_phy_is_otg_host()
+
+From: Xu Yang <xu.yang_2@nxp.com>
+
+[ Upstream commit 5eda42aebb7668b4dcff025cd3ccb0d3d7c53da6 ]
+
+The function mxs_phy_is_otg_host() will return true if OTG_ID_VALUE is
+0 at USBPHY_CTRL register. However, OTG_ID_VALUE will not reflect the real
+state if the ID pin is float, such as Host-only or Type-C cases. The value
+of OTG_ID_VALUE is always 1 which means device mode.
+This patch will fix the issue by judging the current mode based on
+last_event. The controller will update last_event in time.
+
+Fixes: 7b09e67639d6 ("usb: phy: mxs: refine mxs_phy_disconnect_line")
+Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
+Acked-by: Peter Chen <peter.chen@kernel.org>
+Link: https://lore.kernel.org/r/20230627110353.1879477-2-xu.yang_2@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/phy/phy-mxs-usb.c | 10 ++--------
+ 1 file changed, 2 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c
+index e1a2b2ea098b5..cceabb9d37e98 100644
+--- a/drivers/usb/phy/phy-mxs-usb.c
++++ b/drivers/usb/phy/phy-mxs-usb.c
+@@ -388,14 +388,8 @@ static void __mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool disconnect)
+
+ static bool mxs_phy_is_otg_host(struct mxs_phy *mxs_phy)
+ {
+- void __iomem *base = mxs_phy->phy.io_priv;
+- u32 phyctrl = readl(base + HW_USBPHY_CTRL);
+-
+- if (IS_ENABLED(CONFIG_USB_OTG) &&
+- !(phyctrl & BM_USBPHY_CTRL_OTG_ID_VALUE))
+- return true;
+-
+- return false;
++ return IS_ENABLED(CONFIG_USB_OTG) &&
++ mxs_phy->phy.last_event == USB_EVENT_ID;
+ }
+
+ static void mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool on)
+--
+2.40.1
+
--- /dev/null
+From 8865891c962aaa1d2a83656d7f570c49acce9e5a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Aug 2023 11:53:52 -0400
+Subject: vfio/type1: fix cap_migration information leak
+
+From: Stefan Hajnoczi <stefanha@redhat.com>
+
+[ Upstream commit cd24e2a60af633f157d7e59c0a6dba64f131c0b1 ]
+
+Fix an information leak where an uninitialized hole in struct
+vfio_iommu_type1_info_cap_migration on the stack is exposed to userspace.
+
+The definition of struct vfio_iommu_type1_info_cap_migration contains a hole as
+shown in this pahole(1) output:
+
+ struct vfio_iommu_type1_info_cap_migration {
+ struct vfio_info_cap_header header; /* 0 8 */
+ __u32 flags; /* 8 4 */
+
+ /* XXX 4 bytes hole, try to pack */
+
+ __u64 pgsize_bitmap; /* 16 8 */
+ __u64 max_dirty_bitmap_size; /* 24 8 */
+
+ /* size: 32, cachelines: 1, members: 4 */
+ /* sum members: 28, holes: 1, sum holes: 4 */
+ /* last cacheline: 32 bytes */
+ };
+
+The cap_mig variable is filled in without initializing the hole:
+
+ static int vfio_iommu_migration_build_caps(struct vfio_iommu *iommu,
+ struct vfio_info_cap *caps)
+ {
+ struct vfio_iommu_type1_info_cap_migration cap_mig;
+
+ cap_mig.header.id = VFIO_IOMMU_TYPE1_INFO_CAP_MIGRATION;
+ cap_mig.header.version = 1;
+
+ cap_mig.flags = 0;
+ /* support minimum pgsize */
+ cap_mig.pgsize_bitmap = (size_t)1 << __ffs(iommu->pgsize_bitmap);
+ cap_mig.max_dirty_bitmap_size = DIRTY_BITMAP_SIZE_MAX;
+
+ return vfio_info_add_capability(caps, &cap_mig.header, sizeof(cap_mig));
+ }
+
+The structure is then copied to a temporary location on the heap. At this point
+it's already too late and ioctl(VFIO_IOMMU_GET_INFO) copies it to userspace
+later:
+
+ int vfio_info_add_capability(struct vfio_info_cap *caps,
+ struct vfio_info_cap_header *cap, size_t size)
+ {
+ struct vfio_info_cap_header *header;
+
+ header = vfio_info_cap_add(caps, size, cap->id, cap->version);
+ if (IS_ERR(header))
+ return PTR_ERR(header);
+
+ memcpy(header + 1, cap + 1, size - sizeof(*header));
+
+ return 0;
+ }
+
+This issue was found by code inspection.
+
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Reviewed-by: Kevin Tian <kevin.tian@intel.com>
+Fixes: ad721705d09c ("vfio iommu: Add migration capability to report supported features")
+Link: https://lore.kernel.org/r/20230801155352.1391945-1-stefanha@redhat.com
+Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/vfio/vfio_iommu_type1.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
+index 0d2f805468e19..cd2113be632b9 100644
+--- a/drivers/vfio/vfio_iommu_type1.c
++++ b/drivers/vfio/vfio_iommu_type1.c
+@@ -2729,7 +2729,7 @@ static int vfio_iommu_iova_build_caps(struct vfio_iommu *iommu,
+ static int vfio_iommu_migration_build_caps(struct vfio_iommu *iommu,
+ struct vfio_info_cap *caps)
+ {
+- struct vfio_iommu_type1_info_cap_migration cap_mig;
++ struct vfio_iommu_type1_info_cap_migration cap_mig = {};
+
+ cap_mig.header.id = VFIO_IOMMU_TYPE1_INFO_CAP_MIGRATION;
+ cap_mig.header.version = 1;
+--
+2.40.1
+
--- /dev/null
+From a397b4f68f196240c70db419cbdfbddee90e5e9b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Aug 2023 07:34:20 -0400
+Subject: vfs, security: Fix automount superblock LSM init problem, preventing
+ NFS sb sharing
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit d80a8f1b58c2bc8d7c6bfb65401ea4f7ec8cddc2 ]
+
+When NFS superblocks are created by automounting, their LSM parameters
+aren't set in the fs_context struct prior to sget_fc() being called,
+leading to failure to match existing superblocks.
+
+This bug leads to messages like the following appearing in dmesg when
+fscache is enabled:
+
+ NFS: Cache volume key already in use (nfs,4.2,2,108,106a8c0,1,,,,100000,100000,2ee,3a98,1d4c,3a98,1)
+
+Fix this by adding a new LSM hook to load fc->security for submount
+creation.
+
+Signed-off-by: David Howells <dhowells@redhat.com>
+Signed-off-by: Jeff Layton <jlayton@kernel.org>
+Link: https://lore.kernel.org/r/165962680944.3334508.6610023900349142034.stgit@warthog.procyon.org.uk/ # v1
+Link: https://lore.kernel.org/r/165962729225.3357250.14350728846471527137.stgit@warthog.procyon.org.uk/ # v2
+Link: https://lore.kernel.org/r/165970659095.2812394.6868894171102318796.stgit@warthog.procyon.org.uk/ # v3
+Link: https://lore.kernel.org/r/166133579016.3678898.6283195019480567275.stgit@warthog.procyon.org.uk/ # v4
+Link: https://lore.kernel.org/r/217595.1662033775@warthog.procyon.org.uk/ # v5
+Fixes: 9bc61ab18b1d ("vfs: Introduce fs_context, switch vfs_kern_mount() to it.")
+Fixes: 779df6a5480f ("NFS: Ensure security label is set for root inode")
+Tested-by: Jeff Layton <jlayton@kernel.org>
+Acked-by: Casey Schaufler <casey@schaufler-ca.com>
+Acked-by: "Christian Brauner (Microsoft)" <brauner@kernel.org>
+Acked-by: Paul Moore <paul@paul-moore.com>
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Message-Id: <20230808-master-v9-1-e0ecde888221@kernel.org>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/fs_context.c | 23 +++++++++++++++-
+ include/linux/lsm_hook_defs.h | 1 +
+ include/linux/security.h | 6 +++++
+ security/security.c | 14 ++++++++++
+ security/selinux/hooks.c | 22 +++++++++++++++
+ security/smack/smack_lsm.c | 51 +++++++++++++++++++++++++++++++++++
+ 6 files changed, 116 insertions(+), 1 deletion(-)
+
+diff --git a/fs/fs_context.c b/fs/fs_context.c
+index 851214d1d013d..375023e40161d 100644
+--- a/fs/fs_context.c
++++ b/fs/fs_context.c
+@@ -315,10 +315,31 @@ struct fs_context *fs_context_for_reconfigure(struct dentry *dentry,
+ }
+ EXPORT_SYMBOL(fs_context_for_reconfigure);
+
++/**
++ * fs_context_for_submount: allocate a new fs_context for a submount
++ * @type: file_system_type of the new context
++ * @reference: reference dentry from which to copy relevant info
++ *
++ * Allocate a new fs_context suitable for a submount. This also ensures that
++ * the fc->security object is inherited from @reference (if needed).
++ */
+ struct fs_context *fs_context_for_submount(struct file_system_type *type,
+ struct dentry *reference)
+ {
+- return alloc_fs_context(type, reference, 0, 0, FS_CONTEXT_FOR_SUBMOUNT);
++ struct fs_context *fc;
++ int ret;
++
++ fc = alloc_fs_context(type, reference, 0, 0, FS_CONTEXT_FOR_SUBMOUNT);
++ if (IS_ERR(fc))
++ return fc;
++
++ ret = security_fs_context_submount(fc, reference->d_sb);
++ if (ret) {
++ put_fs_context(fc);
++ return ERR_PTR(ret);
++ }
++
++ return fc;
+ }
+ EXPORT_SYMBOL(fs_context_for_submount);
+
+diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
+index 6bb55e61e8e87..fb9f5f00a7789 100644
+--- a/include/linux/lsm_hook_defs.h
++++ b/include/linux/lsm_hook_defs.h
+@@ -54,6 +54,7 @@ LSM_HOOK(int, 0, bprm_creds_from_file, struct linux_binprm *bprm, struct file *f
+ LSM_HOOK(int, 0, bprm_check_security, struct linux_binprm *bprm)
+ LSM_HOOK(void, LSM_RET_VOID, bprm_committing_creds, struct linux_binprm *bprm)
+ LSM_HOOK(void, LSM_RET_VOID, bprm_committed_creds, struct linux_binprm *bprm)
++LSM_HOOK(int, 0, fs_context_submount, struct fs_context *fc, struct super_block *reference)
+ LSM_HOOK(int, 0, fs_context_dup, struct fs_context *fc,
+ struct fs_context *src_sc)
+ LSM_HOOK(int, -ENOPARAM, fs_context_parse_param, struct fs_context *fc,
+diff --git a/include/linux/security.h b/include/linux/security.h
+index e2734e9e44d5c..274c75fa2e272 100644
+--- a/include/linux/security.h
++++ b/include/linux/security.h
+@@ -293,6 +293,7 @@ int security_bprm_creds_from_file(struct linux_binprm *bprm, struct file *file);
+ int security_bprm_check(struct linux_binprm *bprm);
+ void security_bprm_committing_creds(struct linux_binprm *bprm);
+ void security_bprm_committed_creds(struct linux_binprm *bprm);
++int security_fs_context_submount(struct fs_context *fc, struct super_block *reference);
+ int security_fs_context_dup(struct fs_context *fc, struct fs_context *src_fc);
+ int security_fs_context_parse_param(struct fs_context *fc, struct fs_parameter *param);
+ int security_sb_alloc(struct super_block *sb);
+@@ -629,6 +630,11 @@ static inline void security_bprm_committed_creds(struct linux_binprm *bprm)
+ {
+ }
+
++static inline int security_fs_context_submount(struct fs_context *fc,
++ struct super_block *reference)
++{
++ return 0;
++}
+ static inline int security_fs_context_dup(struct fs_context *fc,
+ struct fs_context *src_fc)
+ {
+diff --git a/security/security.c b/security/security.c
+index d5ff7ff45b776..521f74e77dd15 100644
+--- a/security/security.c
++++ b/security/security.c
+@@ -1138,6 +1138,20 @@ void security_bprm_committed_creds(struct linux_binprm *bprm)
+ call_void_hook(bprm_committed_creds, bprm);
+ }
+
++/**
++ * security_fs_context_submount() - Initialise fc->security
++ * @fc: new filesystem context
++ * @reference: dentry reference for submount/remount
++ *
++ * Fill out the ->security field for a new fs_context.
++ *
++ * Return: Returns 0 on success or negative error code on failure.
++ */
++int security_fs_context_submount(struct fs_context *fc, struct super_block *reference)
++{
++ return call_int_hook(fs_context_submount, 0, fc, reference);
++}
++
+ /**
+ * security_fs_context_dup() - Duplicate a fs_context LSM blob
+ * @fc: destination filesystem context
+diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
+index 79b4890e9936d..674f43372f490 100644
+--- a/security/selinux/hooks.c
++++ b/security/selinux/hooks.c
+@@ -2721,6 +2721,27 @@ static int selinux_umount(struct vfsmount *mnt, int flags)
+ FILESYSTEM__UNMOUNT, NULL);
+ }
+
++static int selinux_fs_context_submount(struct fs_context *fc,
++ struct super_block *reference)
++{
++ const struct superblock_security_struct *sbsec;
++ struct selinux_mnt_opts *opts;
++
++ opts = kzalloc(sizeof(*opts), GFP_KERNEL);
++ if (!opts)
++ return -ENOMEM;
++
++ sbsec = selinux_superblock(reference);
++ if (sbsec->flags & FSCONTEXT_MNT)
++ opts->fscontext_sid = sbsec->sid;
++ if (sbsec->flags & CONTEXT_MNT)
++ opts->context_sid = sbsec->mntpoint_sid;
++ if (sbsec->flags & DEFCONTEXT_MNT)
++ opts->defcontext_sid = sbsec->def_sid;
++ fc->security = opts;
++ return 0;
++}
++
+ static int selinux_fs_context_dup(struct fs_context *fc,
+ struct fs_context *src_fc)
+ {
+@@ -7142,6 +7163,7 @@ static struct security_hook_list selinux_hooks[] __ro_after_init = {
+ /*
+ * PUT "CLONING" (ACCESSING + ALLOCATING) HOOKS HERE
+ */
++ LSM_HOOK_INIT(fs_context_submount, selinux_fs_context_submount),
+ LSM_HOOK_INIT(fs_context_dup, selinux_fs_context_dup),
+ LSM_HOOK_INIT(fs_context_parse_param, selinux_fs_context_parse_param),
+ LSM_HOOK_INIT(sb_eat_lsm_opts, selinux_sb_eat_lsm_opts),
+diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
+index 7a3e9ab137d85..6bdc01600aa74 100644
+--- a/security/smack/smack_lsm.c
++++ b/security/smack/smack_lsm.c
+@@ -614,6 +614,56 @@ static int smack_add_opt(int token, const char *s, void **mnt_opts)
+ return -EINVAL;
+ }
+
++/**
++ * smack_fs_context_submount - Initialise security data for a filesystem context
++ * @fc: The filesystem context.
++ * @reference: reference superblock
++ *
++ * Returns 0 on success or -ENOMEM on error.
++ */
++static int smack_fs_context_submount(struct fs_context *fc,
++ struct super_block *reference)
++{
++ struct superblock_smack *sbsp;
++ struct smack_mnt_opts *ctx;
++ struct inode_smack *isp;
++
++ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
++ if (!ctx)
++ return -ENOMEM;
++ fc->security = ctx;
++
++ sbsp = smack_superblock(reference);
++ isp = smack_inode(reference->s_root->d_inode);
++
++ if (sbsp->smk_default) {
++ ctx->fsdefault = kstrdup(sbsp->smk_default->smk_known, GFP_KERNEL);
++ if (!ctx->fsdefault)
++ return -ENOMEM;
++ }
++
++ if (sbsp->smk_floor) {
++ ctx->fsfloor = kstrdup(sbsp->smk_floor->smk_known, GFP_KERNEL);
++ if (!ctx->fsfloor)
++ return -ENOMEM;
++ }
++
++ if (sbsp->smk_hat) {
++ ctx->fshat = kstrdup(sbsp->smk_hat->smk_known, GFP_KERNEL);
++ if (!ctx->fshat)
++ return -ENOMEM;
++ }
++
++ if (isp->smk_flags & SMK_INODE_TRANSMUTE) {
++ if (sbsp->smk_root) {
++ ctx->fstransmute = kstrdup(sbsp->smk_root->smk_known, GFP_KERNEL);
++ if (!ctx->fstransmute)
++ return -ENOMEM;
++ }
++ }
++ return 0;
++}
++
+ /**
+ * smack_fs_context_dup - Duplicate the security data on fs_context duplication
+ * @fc: The new filesystem context.
+@@ -4845,6 +4895,7 @@ static struct security_hook_list smack_hooks[] __ro_after_init = {
+ LSM_HOOK_INIT(ptrace_traceme, smack_ptrace_traceme),
+ LSM_HOOK_INIT(syslog, smack_syslog),
+
++ LSM_HOOK_INIT(fs_context_submount, smack_fs_context_submount),
+ LSM_HOOK_INIT(fs_context_dup, smack_fs_context_dup),
+ LSM_HOOK_INIT(fs_context_parse_param, smack_fs_context_parse_param),
+
+--
+2.40.1
+
--- /dev/null
+From 0f5db70fc50f53ffe85809148fc9b11da02bde3a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Aug 2023 05:10:59 +0000
+Subject: virtio_ring: fix avail_wrap_counter in virtqueue_add_packed
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Yuan Yao <yuanyaogoog@chromium.org>
+
+[ Upstream commit 1acfe2c1225899eab5ab724c91b7e1eb2881b9ab ]
+
+In current packed virtqueue implementation, the avail_wrap_counter won't
+flip, in the case when the driver supplies a descriptor chain with a
+length equals to the queue size; total_sg == vq->packed.vring.num.
+
+Let’s assume the following situation:
+vq->packed.vring.num=4
+vq->packed.next_avail_idx: 1
+vq->packed.avail_wrap_counter: 0
+
+Then the driver adds a descriptor chain containing 4 descriptors.
+
+We expect the following result with avail_wrap_counter flipped:
+vq->packed.next_avail_idx: 1
+vq->packed.avail_wrap_counter: 1
+
+But, the current implementation gives the following result:
+vq->packed.next_avail_idx: 1
+vq->packed.avail_wrap_counter: 0
+
+To reproduce the bug, you can set a packed queue size as small as
+possible, so that the driver is more likely to provide a descriptor
+chain with a length equal to the packed queue size. For example, in
+qemu run following commands:
+sudo qemu-system-x86_64 \
+-enable-kvm \
+-nographic \
+-kernel "path/to/kernel_image" \
+-m 1G \
+-drive file="path/to/rootfs",if=none,id=disk \
+-device virtio-blk,drive=disk \
+-drive file="path/to/disk_image",if=none,id=rwdisk \
+-device virtio-blk,drive=rwdisk,packed=on,queue-size=4,\
+indirect_desc=off \
+-append "console=ttyS0 root=/dev/vda rw init=/bin/bash"
+
+Inside the VM, create a directory and mount the rwdisk device on it. The
+rwdisk will hang and mount operation will not complete.
+
+This commit fixes the wrap counter error by flipping the
+packed.avail_wrap_counter, when start of descriptor chain equals to the
+end of descriptor chain (head == i).
+
+Fixes: 1ce9e6055fa0 ("virtio_ring: introduce packed ring support")
+Signed-off-by: Yuan Yao <yuanyaogoog@chromium.org>
+Message-Id: <20230808051110.3492693-1-yuanyaogoog@chromium.org>
+Acked-by: Jason Wang <jasowang@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/virtio/virtio_ring.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
+index c5310eaf8b468..da1150d127c24 100644
+--- a/drivers/virtio/virtio_ring.c
++++ b/drivers/virtio/virtio_ring.c
+@@ -1461,7 +1461,7 @@ static inline int virtqueue_add_packed(struct virtqueue *_vq,
+ }
+ }
+
+- if (i < head)
++ if (i <= head)
+ vq->packed.avail_wrap_counter ^= 1;
+
+ /* We're using some buffers from the free list. */
+--
+2.40.1
+
--- /dev/null
+From 6dec2e3c27a2f7d84f6980ec6f52b74147f3835b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Aug 2023 05:15:39 -0400
+Subject: virtio_vdpa: build affinity masks conditionally
+
+From: Jason Wang <jasowang@redhat.com>
+
+[ Upstream commit ae15aceaa98ad9499763923f7890e345d9f46b60 ]
+
+We try to build affinity mask via create_affinity_masks()
+unconditionally which may lead several issues:
+
+- the affinity mask is not used for parent without affinity support
+ (only VDUSE support the affinity now)
+- the logic of create_affinity_masks() might not work for devices
+ other than block. For example it's not rare in the networking device
+ where the number of queues could exceed the number of CPUs. Such
+ case breaks the current affinity logic which is based on
+ group_cpus_evenly() who assumes the number of CPUs are not less than
+ the number of groups. This can trigger a warning[1]:
+
+ if (ret >= 0)
+ WARN_ON(nr_present + nr_others < numgrps);
+
+Fixing this by only build the affinity masks only when
+
+- Driver passes affinity descriptor, driver like virtio-blk can make
+ sure to limit the number of queues when it exceeds the number of CPUs
+- Parent support affinity setting config ops
+
+This help to avoid the warning. More optimizations could be done on
+top.
+
+[1]
+[ 682.146655] WARNING: CPU: 6 PID: 1550 at lib/group_cpus.c:400 group_cpus_evenly+0x1aa/0x1c0
+[ 682.146668] CPU: 6 PID: 1550 Comm: vdpa Not tainted 6.5.0-rc5jason+ #79
+[ 682.146671] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.2-0-gea1b7a073390-prebuilt.qemu.org 04/01/2014
+[ 682.146673] RIP: 0010:group_cpus_evenly+0x1aa/0x1c0
+[ 682.146676] Code: 4c 89 e0 5b 5d 41 5c 41 5d 41 5e c3 cc cc cc cc e8 1b c4 74 ff 48 89 ef e8 13 ac 98 ff 4c 89 e7 45 31 e4 e8 08 ac 98 ff eb c2 <0f> 0b eb b6 e8 fd 05 c3 00 45 31 e4 eb e5 cc cc cc cc cc cc cc cc
+[ 682.146679] RSP: 0018:ffffc9000215f498 EFLAGS: 00010293
+[ 682.146682] RAX: 000000000001f1e0 RBX: 0000000000000041 RCX: 0000000000000000
+[ 682.146684] RDX: ffff888109922058 RSI: 0000000000000041 RDI: 0000000000000030
+[ 682.146686] RBP: ffff888109922058 R08: ffffc9000215f498 R09: ffffc9000215f4a0
+[ 682.146687] R10: 00000000000198d0 R11: 0000000000000030 R12: ffff888107e02800
+[ 682.146689] R13: 0000000000000030 R14: 0000000000000030 R15: 0000000000000041
+[ 682.146692] FS: 00007fef52315740(0000) GS:ffff888237380000(0000) knlGS:0000000000000000
+[ 682.146695] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 682.146696] CR2: 00007fef52509000 CR3: 0000000110dbc004 CR4: 0000000000370ee0
+[ 682.146698] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+[ 682.146700] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+[ 682.146701] Call Trace:
+[ 682.146703] <TASK>
+[ 682.146705] ? __warn+0x7b/0x130
+[ 682.146709] ? group_cpus_evenly+0x1aa/0x1c0
+[ 682.146712] ? report_bug+0x1c8/0x1e0
+[ 682.146717] ? handle_bug+0x3c/0x70
+[ 682.146721] ? exc_invalid_op+0x14/0x70
+[ 682.146723] ? asm_exc_invalid_op+0x16/0x20
+[ 682.146727] ? group_cpus_evenly+0x1aa/0x1c0
+[ 682.146729] ? group_cpus_evenly+0x15c/0x1c0
+[ 682.146731] create_affinity_masks+0xaf/0x1a0
+[ 682.146735] virtio_vdpa_find_vqs+0x83/0x1d0
+[ 682.146738] ? __pfx_default_calc_sets+0x10/0x10
+[ 682.146742] virtnet_find_vqs+0x1f0/0x370
+[ 682.146747] virtnet_probe+0x501/0xcd0
+[ 682.146749] ? vp_modern_get_status+0x12/0x20
+[ 682.146751] ? get_cap_addr.isra.0+0x10/0xc0
+[ 682.146754] virtio_dev_probe+0x1af/0x260
+[ 682.146759] really_probe+0x1a5/0x410
+
+Fixes: 3dad56823b53 ("virtio-vdpa: Support interrupt affinity spreading mechanism")
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+Message-Id: <20230811091539.1359865-1-jasowang@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/virtio/virtio_vdpa.c | 17 +++++++++++------
+ 1 file changed, 11 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/virtio/virtio_vdpa.c b/drivers/virtio/virtio_vdpa.c
+index 961161da59000..06ce6d8c2e004 100644
+--- a/drivers/virtio/virtio_vdpa.c
++++ b/drivers/virtio/virtio_vdpa.c
+@@ -366,11 +366,14 @@ static int virtio_vdpa_find_vqs(struct virtio_device *vdev, unsigned int nvqs,
+ struct irq_affinity default_affd = { 0 };
+ struct cpumask *masks;
+ struct vdpa_callback cb;
++ bool has_affinity = desc && ops->set_vq_affinity;
+ int i, err, queue_idx = 0;
+
+- masks = create_affinity_masks(nvqs, desc ? desc : &default_affd);
+- if (!masks)
+- return -ENOMEM;
++ if (has_affinity) {
++ masks = create_affinity_masks(nvqs, desc ? desc : &default_affd);
++ if (!masks)
++ return -ENOMEM;
++ }
+
+ for (i = 0; i < nvqs; ++i) {
+ if (!names[i]) {
+@@ -386,20 +389,22 @@ static int virtio_vdpa_find_vqs(struct virtio_device *vdev, unsigned int nvqs,
+ goto err_setup_vq;
+ }
+
+- if (ops->set_vq_affinity)
++ if (has_affinity)
+ ops->set_vq_affinity(vdpa, i, &masks[i]);
+ }
+
+ cb.callback = virtio_vdpa_config_cb;
+ cb.private = vd_dev;
+ ops->set_config_cb(vdpa, &cb);
+- kfree(masks);
++ if (has_affinity)
++ kfree(masks);
+
+ return 0;
+
+ err_setup_vq:
+ virtio_vdpa_del_vqs(vdev);
+- kfree(masks);
++ if (has_affinity)
++ kfree(masks);
+ return err;
+ }
+
+--
+2.40.1
+
--- /dev/null
+From 28b2e36d998c4d42a5d07f7e5ea98f300820fcdb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Jul 2023 15:05:02 +0300
+Subject: wifi: ath10k: Use RMW accessors for changing LNKCTL
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit f139492a09f15254fa261245cdbd65555cdf39e3 ]
+
+Don't assume that only the driver would be accessing LNKCTL. ASPM policy
+changes can trigger write to LNKCTL outside of driver's control.
+
+Use RMW capability accessors which does proper locking to avoid losing
+concurrent updates to the register value. On restore, clear the ASPMC field
+properly.
+
+Suggested-by: Lukas Wunner <lukas@wunner.de>
+Fixes: 76d870ed09ab ("ath10k: enable ASPM")
+Link: https://lore.kernel.org/r/20230717120503.15276-11-ilpo.jarvinen@linux.intel.com
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Acked-by: Kalle Valo <kvalo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath10k/pci.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
+index a7f44f6335fb8..9275a672f90cb 100644
+--- a/drivers/net/wireless/ath/ath10k/pci.c
++++ b/drivers/net/wireless/ath/ath10k/pci.c
+@@ -1963,8 +1963,9 @@ static int ath10k_pci_hif_start(struct ath10k *ar)
+ ath10k_pci_irq_enable(ar);
+ ath10k_pci_rx_post(ar);
+
+- pcie_capability_write_word(ar_pci->pdev, PCI_EXP_LNKCTL,
+- ar_pci->link_ctl);
++ pcie_capability_clear_and_set_word(ar_pci->pdev, PCI_EXP_LNKCTL,
++ PCI_EXP_LNKCTL_ASPMC,
++ ar_pci->link_ctl & PCI_EXP_LNKCTL_ASPMC);
+
+ return 0;
+ }
+@@ -2821,8 +2822,8 @@ static int ath10k_pci_hif_power_up(struct ath10k *ar,
+
+ pcie_capability_read_word(ar_pci->pdev, PCI_EXP_LNKCTL,
+ &ar_pci->link_ctl);
+- pcie_capability_write_word(ar_pci->pdev, PCI_EXP_LNKCTL,
+- ar_pci->link_ctl & ~PCI_EXP_LNKCTL_ASPMC);
++ pcie_capability_clear_word(ar_pci->pdev, PCI_EXP_LNKCTL,
++ PCI_EXP_LNKCTL_ASPMC);
+
+ /*
+ * Bring the target up cleanly.
+--
+2.40.1
+
--- /dev/null
+From 18e762cecfc18a386d56b42ce9f8f705d791f14f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Jul 2023 10:16:24 +0530
+Subject: wifi: ath11k: fix band selection for ppdu received in channel 177 of
+ 5 GHz
+
+From: Aditya Kumar Singh <quic_adisi@quicinc.com>
+
+[ Upstream commit 72c8caf904aed2caed5d6e75233294b6159ddb5d ]
+
+5 GHz band channel 177 support was added with the commit e5e94d10c856 ("wifi:
+ath11k: add channel 177 into 5 GHz channel list"). However, during processing
+for the received ppdu in ath11k_dp_rx_h_ppdu(), channel number is checked only
+till 173. This leads to driver code checking for channel and then fetching the
+band from it which is extra effort since firmware has already given the channel
+number in the metadata.
+
+Fix this issue by checking the channel number till 177 since we support
+it now.
+
+Found via code review. Compile tested only.
+
+Fixes: e5e94d10c856 ("wifi: ath11k: add channel 177 into 5 GHz channel list")
+Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20230726044624.20507-1-quic_adisi@quicinc.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath11k/dp_rx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c
+index f67ce62b2b48d..c5ff1bc02999e 100644
+--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
+@@ -2408,7 +2408,7 @@ static void ath11k_dp_rx_h_ppdu(struct ath11k *ar, struct hal_rx_desc *rx_desc,
+ rx_status->freq = center_freq;
+ } else if (channel_num >= 1 && channel_num <= 14) {
+ rx_status->band = NL80211_BAND_2GHZ;
+- } else if (channel_num >= 36 && channel_num <= 173) {
++ } else if (channel_num >= 36 && channel_num <= 177) {
+ rx_status->band = NL80211_BAND_5GHZ;
+ } else {
+ spin_lock_bh(&ar->data_lock);
+--
+2.40.1
+
--- /dev/null
+From 66e45be82ef96181bec1a781713b0f6d0eaee157 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Jul 2023 15:05:00 +0300
+Subject: wifi: ath11k: Use RMW accessors for changing LNKCTL
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit 6c1b6bdb34aaf8f94f65a9cae1d63490320c11bc ]
+
+Don't assume that only the driver would be accessing LNKCTL. ASPM policy
+changes can trigger write to LNKCTL outside of driver's control.
+
+Use RMW capability accessors which do proper locking to avoid losing
+concurrent updates to the register value. On restore, clear the ASPMC field
+properly.
+
+Suggested-by: Lukas Wunner <lukas@wunner.de>
+Fixes: e9603f4bdcc0 ("ath11k: pci: disable ASPM L0sLs before downloading firmware")
+Link: https://lore.kernel.org/r/20230717120503.15276-9-ilpo.jarvinen@linux.intel.com
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Acked-by: Kalle Valo <kvalo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath11k/pci.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c
+index 7b33731a50ee7..6ba4cef6b1c7d 100644
+--- a/drivers/net/wireless/ath/ath11k/pci.c
++++ b/drivers/net/wireless/ath/ath11k/pci.c
+@@ -581,8 +581,8 @@ static void ath11k_pci_aspm_disable(struct ath11k_pci *ab_pci)
+ u16_get_bits(ab_pci->link_ctl, PCI_EXP_LNKCTL_ASPM_L1));
+
+ /* disable L0s and L1 */
+- pcie_capability_write_word(ab_pci->pdev, PCI_EXP_LNKCTL,
+- ab_pci->link_ctl & ~PCI_EXP_LNKCTL_ASPMC);
++ pcie_capability_clear_word(ab_pci->pdev, PCI_EXP_LNKCTL,
++ PCI_EXP_LNKCTL_ASPMC);
+
+ set_bit(ATH11K_PCI_ASPM_RESTORE, &ab_pci->flags);
+ }
+@@ -590,8 +590,10 @@ static void ath11k_pci_aspm_disable(struct ath11k_pci *ab_pci)
+ static void ath11k_pci_aspm_restore(struct ath11k_pci *ab_pci)
+ {
+ if (test_and_clear_bit(ATH11K_PCI_ASPM_RESTORE, &ab_pci->flags))
+- pcie_capability_write_word(ab_pci->pdev, PCI_EXP_LNKCTL,
+- ab_pci->link_ctl);
++ pcie_capability_clear_and_set_word(ab_pci->pdev, PCI_EXP_LNKCTL,
++ PCI_EXP_LNKCTL_ASPMC,
++ ab_pci->link_ctl &
++ PCI_EXP_LNKCTL_ASPMC);
+ }
+
+ static int ath11k_pci_power_up(struct ath11k_base *ab)
+--
+2.40.1
+
--- /dev/null
+From 588835131172543daba8b8c313f3084a64c3ade2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Jul 2023 14:37:29 +0200
+Subject: wifi: ath12k: fix memcpy array overflow in ath12k_peer_assoc_h_he()
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 603cf6c2fcdcbc38f1daa316794e7268852677a7 ]
+
+Two memory copies in this function copy from a short array into a longer one,
+using the wrong size, which leads to an out-of-bounds access:
+
+include/linux/fortify-string.h:592:4: error: call to '__read_overflow2_field' declared with 'warning' attribute: detected read beyond size of field (2nd parameter); maybe use struct_group()? [-Werror,-Wattribute-warning]
+ __read_overflow2_field(q_size_field, size);
+ ^
+include/linux/fortify-string.h:592:4: error: call to '__read_overflow2_field' declared with 'warning' attribute: detected read beyond size of field (2nd parameter); maybe use struct_group()? [-Werror,-Wattribute-warning]
+2 errors generated.
+
+Fixes: d889913205cf7 ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20230703123737.3420464-1-arnd@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath12k/mac.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
+index 58acfe8fdf8c0..faccea2d8148c 100644
+--- a/drivers/net/wireless/ath/ath12k/mac.c
++++ b/drivers/net/wireless/ath/ath12k/mac.c
+@@ -1634,9 +1634,9 @@ static void ath12k_peer_assoc_h_he(struct ath12k *ar,
+ arg->peer_nss = min(sta->deflink.rx_nss, max_nss);
+
+ memcpy(&arg->peer_he_cap_macinfo, he_cap->he_cap_elem.mac_cap_info,
+- sizeof(arg->peer_he_cap_macinfo));
++ sizeof(he_cap->he_cap_elem.mac_cap_info));
+ memcpy(&arg->peer_he_cap_phyinfo, he_cap->he_cap_elem.phy_cap_info,
+- sizeof(arg->peer_he_cap_phyinfo));
++ sizeof(he_cap->he_cap_elem.phy_cap_info));
+ arg->peer_he_ops = vif->bss_conf.he_oper.params;
+
+ /* the top most byte is used to indicate BSS color info */
+--
+2.40.1
+
--- /dev/null
+From 71cc3657aacf9b46c8171336ff4130cb53c1426e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Jul 2023 15:05:01 +0300
+Subject: wifi: ath12k: Use RMW accessors for changing LNKCTL
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit f5a7ac118faf6d4f794975947b3300717eae8fc5 ]
+
+Don't assume that only the driver would be accessing LNKCTL. ASPM policy
+changes can trigger write to LNKCTL outside of driver's control.
+
+Use RMW capability accessors which do proper locking to avoid losing
+concurrent updates to the register value. On restore, clear the ASPMC field
+properly.
+
+Suggested-by: Lukas Wunner <lukas@wunner.de>
+Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices")
+Link: https://lore.kernel.org/r/20230717120503.15276-10-ilpo.jarvinen@linux.intel.com
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Acked-by: Kalle Valo <kvalo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath12k/pci.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c
+index 9f174daf324c9..e1e45eb50f3e3 100644
+--- a/drivers/net/wireless/ath/ath12k/pci.c
++++ b/drivers/net/wireless/ath/ath12k/pci.c
+@@ -794,8 +794,8 @@ static void ath12k_pci_aspm_disable(struct ath12k_pci *ab_pci)
+ u16_get_bits(ab_pci->link_ctl, PCI_EXP_LNKCTL_ASPM_L1));
+
+ /* disable L0s and L1 */
+- pcie_capability_write_word(ab_pci->pdev, PCI_EXP_LNKCTL,
+- ab_pci->link_ctl & ~PCI_EXP_LNKCTL_ASPMC);
++ pcie_capability_clear_word(ab_pci->pdev, PCI_EXP_LNKCTL,
++ PCI_EXP_LNKCTL_ASPMC);
+
+ set_bit(ATH12K_PCI_ASPM_RESTORE, &ab_pci->flags);
+ }
+@@ -803,8 +803,10 @@ static void ath12k_pci_aspm_disable(struct ath12k_pci *ab_pci)
+ static void ath12k_pci_aspm_restore(struct ath12k_pci *ab_pci)
+ {
+ if (test_and_clear_bit(ATH12K_PCI_ASPM_RESTORE, &ab_pci->flags))
+- pcie_capability_write_word(ab_pci->pdev, PCI_EXP_LNKCTL,
+- ab_pci->link_ctl);
++ pcie_capability_clear_and_set_word(ab_pci->pdev, PCI_EXP_LNKCTL,
++ PCI_EXP_LNKCTL_ASPMC,
++ ab_pci->link_ctl &
++ PCI_EXP_LNKCTL_ASPMC);
+ }
+
+ static void ath12k_pci_kill_tasklets(struct ath12k_base *ab)
+--
+2.40.1
+
--- /dev/null
+From b4333b4a5fe742cb651bd444c3a8fbf573b05502 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Apr 2023 22:26:06 +0300
+Subject: wifi: ath9k: fix races between ath9k_wmi_cmd and ath9k_wmi_ctrl_rx
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Fedor Pchelkin <pchelkin@ispras.ru>
+
+[ Upstream commit b674fb513e2e7a514fcde287c0f73915d393fdb6 ]
+
+Currently, the synchronization between ath9k_wmi_cmd() and
+ath9k_wmi_ctrl_rx() is exposed to a race condition which, although being
+rather unlikely, can lead to invalid behaviour of ath9k_wmi_cmd().
+
+Consider the following scenario:
+
+CPU0 CPU1
+
+ath9k_wmi_cmd(...)
+ mutex_lock(&wmi->op_mutex)
+ ath9k_wmi_cmd_issue(...)
+ wait_for_completion_timeout(...)
+ ---
+ timeout
+ ---
+ /* the callback is being processed
+ * before last_seq_id became zero
+ */
+ ath9k_wmi_ctrl_rx(...)
+ spin_lock_irqsave(...)
+ /* wmi->last_seq_id check here
+ * doesn't detect timeout yet
+ */
+ spin_unlock_irqrestore(...)
+ /* last_seq_id is zeroed to
+ * indicate there was a timeout
+ */
+ wmi->last_seq_id = 0
+ mutex_unlock(&wmi->op_mutex)
+ return -ETIMEDOUT
+
+ath9k_wmi_cmd(...)
+ mutex_lock(&wmi->op_mutex)
+ /* the buffer is replaced with
+ * another one
+ */
+ wmi->cmd_rsp_buf = rsp_buf
+ wmi->cmd_rsp_len = rsp_len
+ ath9k_wmi_cmd_issue(...)
+ spin_lock_irqsave(...)
+ spin_unlock_irqrestore(...)
+ wait_for_completion_timeout(...)
+ /* the continuation of the
+ * callback left after the first
+ * ath9k_wmi_cmd call
+ */
+ ath9k_wmi_rsp_callback(...)
+ /* copying data designated
+ * to already timeouted
+ * WMI command into an
+ * inappropriate wmi_cmd_buf
+ */
+ memcpy(...)
+ complete(&wmi->cmd_wait)
+ /* awakened by the bogus callback
+ * => invalid return result
+ */
+ mutex_unlock(&wmi->op_mutex)
+ return 0
+
+To fix this, update last_seq_id on timeout path inside ath9k_wmi_cmd()
+under the wmi_lock. Move ath9k_wmi_rsp_callback() under wmi_lock inside
+ath9k_wmi_ctrl_rx() so that the wmi->cmd_wait can be completed only for
+initially designated wmi_cmd call, otherwise the path would be rejected
+with last_seq_id check.
+
+Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
+
+Fixes: fb9987d0f748 ("ath9k_htc: Support for AR9271 chipset.")
+Signed-off-by: Fedor Pchelkin <pchelkin@ispras.ru>
+Acked-by: Toke Høiland-Jørgensen <toke@toke.dk>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20230425192607.18015-1-pchelkin@ispras.ru
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath9k/wmi.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c
+index d652c647d56b5..04f363cb90fe5 100644
+--- a/drivers/net/wireless/ath/ath9k/wmi.c
++++ b/drivers/net/wireless/ath/ath9k/wmi.c
+@@ -242,10 +242,10 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb,
+ spin_unlock_irqrestore(&wmi->wmi_lock, flags);
+ goto free_skb;
+ }
+- spin_unlock_irqrestore(&wmi->wmi_lock, flags);
+
+ /* WMI command response */
+ ath9k_wmi_rsp_callback(wmi, skb);
++ spin_unlock_irqrestore(&wmi->wmi_lock, flags);
+
+ free_skb:
+ kfree_skb(skb);
+@@ -308,8 +308,8 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
+ struct ath_common *common = ath9k_hw_common(ah);
+ u16 headroom = sizeof(struct htc_frame_hdr) +
+ sizeof(struct wmi_cmd_hdr);
++ unsigned long time_left, flags;
+ struct sk_buff *skb;
+- unsigned long time_left;
+ int ret = 0;
+
+ if (ah->ah_flags & AH_UNPLUGGED)
+@@ -345,7 +345,9 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
+ if (!time_left) {
+ ath_dbg(common, WMI, "Timeout waiting for WMI command: %s\n",
+ wmi_cmd_to_name(cmd_id));
++ spin_lock_irqsave(&wmi->wmi_lock, flags);
+ wmi->last_seq_id = 0;
++ spin_unlock_irqrestore(&wmi->wmi_lock, flags);
+ mutex_unlock(&wmi->op_mutex);
+ return -ETIMEDOUT;
+ }
+--
+2.40.1
+
--- /dev/null
+From ec589697f691f58c6eb2c6097f301bc616ed6f78 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Apr 2023 22:26:07 +0300
+Subject: wifi: ath9k: protect WMI command response buffer replacement with a
+ lock
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Fedor Pchelkin <pchelkin@ispras.ru>
+
+[ Upstream commit 454994cfa9e4c18b6df9f78b60db8eadc20a6c25 ]
+
+If ath9k_wmi_cmd() has exited with a timeout, it is possible that during
+next ath9k_wmi_cmd() call the wmi_rsp callback for previous wmi command
+writes to new wmi->cmd_rsp_buf and makes a completion. This results in an
+invalid ath9k_wmi_cmd() return value.
+
+Move the replacement of WMI command response buffer and length under
+wmi_lock. Note that last_seq_id value is updated there, too.
+
+Thus, the buffer cannot be written to by a belated wmi_rsp callback
+because that path is properly rejected by the last_seq_id check.
+
+Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
+
+Fixes: fb9987d0f748 ("ath9k_htc: Support for AR9271 chipset.")
+Signed-off-by: Fedor Pchelkin <pchelkin@ispras.ru>
+Acked-by: Toke Høiland-Jørgensen <toke@toke.dk>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20230425192607.18015-2-pchelkin@ispras.ru
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath9k/wmi.c | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c
+index 04f363cb90fe5..1476b42b52a91 100644
+--- a/drivers/net/wireless/ath/ath9k/wmi.c
++++ b/drivers/net/wireless/ath/ath9k/wmi.c
+@@ -283,7 +283,8 @@ int ath9k_wmi_connect(struct htc_target *htc, struct wmi *wmi,
+
+ static int ath9k_wmi_cmd_issue(struct wmi *wmi,
+ struct sk_buff *skb,
+- enum wmi_cmd_id cmd, u16 len)
++ enum wmi_cmd_id cmd, u16 len,
++ u8 *rsp_buf, u32 rsp_len)
+ {
+ struct wmi_cmd_hdr *hdr;
+ unsigned long flags;
+@@ -293,6 +294,11 @@ static int ath9k_wmi_cmd_issue(struct wmi *wmi,
+ hdr->seq_no = cpu_to_be16(++wmi->tx_seq_id);
+
+ spin_lock_irqsave(&wmi->wmi_lock, flags);
++
++ /* record the rsp buffer and length */
++ wmi->cmd_rsp_buf = rsp_buf;
++ wmi->cmd_rsp_len = rsp_len;
++
+ wmi->last_seq_id = wmi->tx_seq_id;
+ spin_unlock_irqrestore(&wmi->wmi_lock, flags);
+
+@@ -333,11 +339,7 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
+ goto out;
+ }
+
+- /* record the rsp buffer and length */
+- wmi->cmd_rsp_buf = rsp_buf;
+- wmi->cmd_rsp_len = rsp_len;
+-
+- ret = ath9k_wmi_cmd_issue(wmi, skb, cmd_id, cmd_len);
++ ret = ath9k_wmi_cmd_issue(wmi, skb, cmd_id, cmd_len, rsp_buf, rsp_len);
+ if (ret)
+ goto out;
+
+--
+2.40.1
+
--- /dev/null
+From 31ac9335177ac98cbd3123f3bb8b24fc95b62d34 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Jul 2023 11:03:44 +0800
+Subject: wifi: ath9k: use IS_ERR() with debugfs_create_dir()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Wang Ming <machel@vivo.com>
+
+[ Upstream commit 1e4134610d93271535ecf900a676e1f094e9944c ]
+
+The debugfs_create_dir() function returns error pointers,
+it never returns NULL. Most incorrect error checks were fixed,
+but the one in ath9k_htc_init_debug() was forgotten.
+
+Fix the remaining error check.
+
+Fixes: e5facc75fa91 ("ath9k_htc: Cleanup HTC debugfs")
+Signed-off-by: Wang Ming <machel@vivo.com>
+Acked-by: Toke Høiland-Jørgensen <toke@toke.dk>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20230713030358.12379-1-machel@vivo.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath9k/htc_drv_debug.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
+index b3ed65e5c4da8..c55aab01fff5d 100644
+--- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
++++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
+@@ -491,7 +491,7 @@ int ath9k_htc_init_debug(struct ath_hw *ah)
+
+ priv->debug.debugfs_phy = debugfs_create_dir(KBUILD_MODNAME,
+ priv->hw->wiphy->debugfsdir);
+- if (!priv->debug.debugfs_phy)
++ if (IS_ERR(priv->debug.debugfs_phy))
+ return -ENOMEM;
+
+ ath9k_cmn_spectral_init_debug(&priv->spec_priv, priv->debug.debugfs_phy);
+--
+2.40.1
+
--- /dev/null
+From 18d84322aaf53af7e6aac30f8c433fdc4007a0bb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Aug 2023 12:13:36 +0200
+Subject: wifi: mac80211: fix puncturing bitmap handling in CSA
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit 927521170c4a18c620f97865f7bad48f17c48967 ]
+
+Code inspection reveals that we switch the puncturing bitmap
+before the real channel switch, since that happens only in
+the second round of the worker after the channel context is
+switched by ieee80211_link_use_reserved_context().
+
+Fixes: 2cc25e4b2a04 ("wifi: mac80211: configure puncturing bitmap")
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/cfg.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index f2d08dbccfb7d..30d69091064fe 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -3640,12 +3640,6 @@ static int __ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata)
+ lockdep_assert_held(&local->mtx);
+ lockdep_assert_held(&local->chanctx_mtx);
+
+- if (sdata->vif.bss_conf.eht_puncturing != sdata->vif.bss_conf.csa_punct_bitmap) {
+- sdata->vif.bss_conf.eht_puncturing =
+- sdata->vif.bss_conf.csa_punct_bitmap;
+- changed |= BSS_CHANGED_EHT_PUNCTURING;
+- }
+-
+ /*
+ * using reservation isn't immediate as it may be deferred until later
+ * with multi-vif. once reservation is complete it will re-schedule the
+@@ -3675,6 +3669,12 @@ static int __ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata)
+ if (err)
+ return err;
+
++ if (sdata->vif.bss_conf.eht_puncturing != sdata->vif.bss_conf.csa_punct_bitmap) {
++ sdata->vif.bss_conf.eht_puncturing =
++ sdata->vif.bss_conf.csa_punct_bitmap;
++ changed |= BSS_CHANGED_EHT_PUNCTURING;
++ }
++
+ ieee80211_link_info_change_notify(sdata, &sdata->deflink, changed);
+
+ if (sdata->deflink.csa_block_tx) {
+--
+2.40.1
+
--- /dev/null
+From d257359b76d0cdb006333f021340248beb56ee20 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 May 2023 11:11:57 +0800
+Subject: wifi: mt76: mt7915: fix background radar event being blocked
+
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+
+[ Upstream commit 9a3994077d170ec9ac75e800932b5671d9940cd2 ]
+
+The background radar uses MT_RX_SEL2 as its band indication, so fix it.
+
+Fixes: 7a53eecd5c87 (wifi: mt76: mt7915: check the correctness of event data)
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7915/mcu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+index 9fcb22fa1f97e..088a065e37d5d 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+@@ -274,7 +274,7 @@ mt7915_mcu_rx_radar_detected(struct mt7915_dev *dev, struct sk_buff *skb)
+
+ r = (struct mt7915_mcu_rdd_report *)skb->data;
+
+- if (r->band_idx > MT_BAND1)
++ if (r->band_idx > MT_RX_SEL2)
+ return;
+
+ if ((r->band_idx && !dev->phy.mt76->band_idx) &&
+--
+2.40.1
+
--- /dev/null
+From ea7036dd91ef7df41b039bb77592163e3eb751a3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Jun 2023 22:39:30 +0200
+Subject: wifi: mt76: mt7915: fix capabilities in non-AP mode
+
+From: Felix Fietkau <nbd@nbd.name>
+
+[ Upstream commit 02a894046d5ab7d0010f39ea54fde7e167919d04 ]
+
+Capabilities in vif->bss_conf are only initialized in AP mode.
+For other modes, they should be enabled by default, in order to avoid a
+mismatch.
+
+Fixes: 885f7af7e544 ("wifi: mt76: mt7915: remove mt7915_mcu_beacon_check_caps()")
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/wireless/mediatek/mt76/mt7915/main.c | 21 +++++++++++++++
+ .../net/wireless/mediatek/mt76/mt7915/mcu.c | 27 ++++++++++---------
+ .../wireless/mediatek/mt76/mt7915/mt7915.h | 14 ++++++++++
+ 3 files changed, 50 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+index 13d429bd44e28..ed345a0b931e0 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+@@ -269,6 +269,7 @@ static int mt7915_add_interface(struct ieee80211_hw *hw,
+ vif->offload_flags |= IEEE80211_OFFLOAD_ENCAP_4ADDR;
+
+ mt7915_init_bitrate_mask(vif);
++ memset(&mvif->cap, -1, sizeof(mvif->cap));
+
+ mt7915_mcu_add_bss_info(phy, vif, true);
+ mt7915_mcu_add_sta(dev, vif, NULL, true);
+@@ -657,6 +658,24 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
+ mutex_unlock(&dev->mt76.mutex);
+ }
+
++static void
++mt7915_vif_check_caps(struct mt7915_phy *phy, struct ieee80211_vif *vif)
++{
++ struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
++ struct mt7915_vif_cap *vc = &mvif->cap;
++
++ vc->ht_ldpc = vif->bss_conf.ht_ldpc;
++ vc->vht_ldpc = vif->bss_conf.vht_ldpc;
++ vc->vht_su_ebfer = vif->bss_conf.vht_su_beamformer;
++ vc->vht_su_ebfee = vif->bss_conf.vht_su_beamformee;
++ vc->vht_mu_ebfer = vif->bss_conf.vht_mu_beamformer;
++ vc->vht_mu_ebfee = vif->bss_conf.vht_mu_beamformee;
++ vc->he_ldpc = vif->bss_conf.he_ldpc;
++ vc->he_su_ebfer = vif->bss_conf.he_su_beamformer;
++ vc->he_su_ebfee = vif->bss_conf.he_su_beamformee;
++ vc->he_mu_ebfer = vif->bss_conf.he_mu_beamformer;
++}
++
+ static int
+ mt7915_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *link_conf)
+@@ -667,6 +686,8 @@ mt7915_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+
+ mutex_lock(&dev->mt76.mutex);
+
++ mt7915_vif_check_caps(phy, vif);
++
+ err = mt7915_mcu_add_bss_info(phy, vif, true);
+ if (err)
+ goto out;
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+index 8da9c87e98042..a325066bf57e9 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+@@ -710,6 +710,7 @@ static void
+ mt7915_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
+ struct ieee80211_vif *vif)
+ {
++ struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
+ struct ieee80211_he_cap_elem *elem = &sta->deflink.he_cap.he_cap_elem;
+ struct ieee80211_he_mcs_nss_supp mcs_map;
+ struct sta_rec_he *he;
+@@ -743,7 +744,7 @@ mt7915_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_5G))
+ cap |= STA_REC_HE_CAP_BW20_RU242_SUPPORT;
+
+- if (vif->bss_conf.he_ldpc &&
++ if (mvif->cap.he_ldpc &&
+ (elem->phy_cap_info[1] &
+ IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD))
+ cap |= STA_REC_HE_CAP_LDPC;
+@@ -852,6 +853,7 @@ static void
+ mt7915_mcu_sta_muru_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
+ struct ieee80211_sta *sta, struct ieee80211_vif *vif)
+ {
++ struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
+ struct ieee80211_he_cap_elem *elem = &sta->deflink.he_cap.he_cap_elem;
+ struct sta_rec_muru *muru;
+ struct tlv *tlv;
+@@ -864,9 +866,9 @@ mt7915_mcu_sta_muru_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
+
+ muru = (struct sta_rec_muru *)tlv;
+
+- muru->cfg.mimo_dl_en = vif->bss_conf.he_mu_beamformer ||
+- vif->bss_conf.vht_mu_beamformer ||
+- vif->bss_conf.vht_mu_beamformee;
++ muru->cfg.mimo_dl_en = mvif->cap.he_mu_ebfer ||
++ mvif->cap.vht_mu_ebfer ||
++ mvif->cap.vht_mu_ebfee;
+ if (!is_mt7915(&dev->mt76))
+ muru->cfg.mimo_ul_en = true;
+ muru->cfg.ofdma_dl_en = true;
+@@ -999,8 +1001,8 @@ mt7915_mcu_sta_wtbl_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
+ mt76_connac_mcu_wtbl_hdr_trans_tlv(skb, vif, wcid, tlv, wtbl_hdr);
+ if (sta)
+ mt76_connac_mcu_wtbl_ht_tlv(&dev->mt76, skb, sta, tlv,
+- wtbl_hdr, vif->bss_conf.ht_ldpc,
+- vif->bss_conf.vht_ldpc);
++ wtbl_hdr, mvif->cap.ht_ldpc,
++ mvif->cap.vht_ldpc);
+
+ return 0;
+ }
+@@ -1009,6 +1011,7 @@ static inline bool
+ mt7915_is_ebf_supported(struct mt7915_phy *phy, struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta, bool bfee)
+ {
++ struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
+ int tx_ant = hweight8(phy->mt76->chainmask) - 1;
+
+ if (vif->type != NL80211_IFTYPE_STATION &&
+@@ -1022,10 +1025,10 @@ mt7915_is_ebf_supported(struct mt7915_phy *phy, struct ieee80211_vif *vif,
+ struct ieee80211_he_cap_elem *pe = &sta->deflink.he_cap.he_cap_elem;
+
+ if (bfee)
+- return vif->bss_conf.he_su_beamformee &&
++ return mvif->cap.he_su_ebfee &&
+ HE_PHY(CAP3_SU_BEAMFORMER, pe->phy_cap_info[3]);
+ else
+- return vif->bss_conf.he_su_beamformer &&
++ return mvif->cap.he_su_ebfer &&
+ HE_PHY(CAP4_SU_BEAMFORMEE, pe->phy_cap_info[4]);
+ }
+
+@@ -1033,10 +1036,10 @@ mt7915_is_ebf_supported(struct mt7915_phy *phy, struct ieee80211_vif *vif,
+ u32 cap = sta->deflink.vht_cap.cap;
+
+ if (bfee)
+- return vif->bss_conf.vht_su_beamformee &&
++ return mvif->cap.vht_su_ebfee &&
+ (cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE);
+ else
+- return vif->bss_conf.vht_su_beamformer &&
++ return mvif->cap.vht_su_ebfer &&
+ (cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE);
+ }
+
+@@ -1531,7 +1534,7 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev,
+ cap |= STA_CAP_TX_STBC;
+ if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_RX_STBC)
+ cap |= STA_CAP_RX_STBC;
+- if (vif->bss_conf.ht_ldpc &&
++ if (mvif->cap.ht_ldpc &&
+ (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING))
+ cap |= STA_CAP_LDPC;
+
+@@ -1557,7 +1560,7 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev,
+ cap |= STA_CAP_VHT_TX_STBC;
+ if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_1)
+ cap |= STA_CAP_VHT_RX_STBC;
+- if (vif->bss_conf.vht_ldpc &&
++ if (mvif->cap.vht_ldpc &&
+ (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC))
+ cap |= STA_CAP_VHT_LDPC;
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+index 3053f4abf7dbe..0f76733c9c1ac 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+@@ -147,9 +147,23 @@ struct mt7915_sta {
+ } twt;
+ };
+
++struct mt7915_vif_cap {
++ bool ht_ldpc:1;
++ bool vht_ldpc:1;
++ bool he_ldpc:1;
++ bool vht_su_ebfer:1;
++ bool vht_su_ebfee:1;
++ bool vht_mu_ebfer:1;
++ bool vht_mu_ebfee:1;
++ bool he_su_ebfer:1;
++ bool he_su_ebfee:1;
++ bool he_mu_ebfer:1;
++};
++
+ struct mt7915_vif {
+ struct mt76_vif mt76; /* must be first */
+
++ struct mt7915_vif_cap cap;
+ struct mt7915_sta sta;
+ struct mt7915_phy *phy;
+
+--
+2.40.1
+
--- /dev/null
+From fb98ec27949875733b88f02dd8c5a5879c4f18d3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 28 May 2023 21:04:28 +0300
+Subject: wifi: mt76: mt7915: fix command timeout in AP stop period
+
+From: Rany Hany <rany_hany@riseup.net>
+
+[ Upstream commit c4f0755823045b66484fb53d686f85d3151400f4 ]
+
+Due to AP stop improperly, mt7915 driver would face random command timeout
+by chip fw problem. Migrate AP start/stop process to .start_ap/.stop_ap and
+congiure BSS network settings in both hooks.
+
+The new flow is shown below.
+* AP start
+ .start_ap()
+ configure BSS network resource
+ set BSS to connected state
+ .bss_info_changed()
+ enable fw beacon offload
+
+* AP stop
+ .bss_info_changed()
+ disable fw beacon offload (skip this command)
+ .stop_ap()
+ set BSS to disconnected state (beacon offload disabled automatically)
+ destroy BSS network resource
+
+Based on "mt76: mt7921: fix command timeout in AP stop period"
+
+Signed-off-by: Rany Hany <rany_hany@riseup.net>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Stable-dep-of: 02a894046d5a ("wifi: mt76: mt7915: fix capabilities in non-AP mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/wireless/mediatek/mt76/mt7915/main.c | 63 +++++++++++++++----
+ 1 file changed, 50 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+index 2da57357c4174..13d429bd44e28 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+@@ -599,6 +599,7 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
+ {
+ struct mt7915_phy *phy = mt7915_hw_phy(hw);
+ struct mt7915_dev *dev = mt7915_hw_dev(hw);
++ int set_bss_info = -1, set_sta = -1;
+
+ mutex_lock(&dev->mt76.mutex);
+
+@@ -607,15 +608,18 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
+ * and then peer references bss_info_rfch to set bandwidth cap.
+ */
+ if (changed & BSS_CHANGED_BSSID &&
+- vif->type == NL80211_IFTYPE_STATION) {
+- bool join = !is_zero_ether_addr(info->bssid);
+-
+- mt7915_mcu_add_bss_info(phy, vif, join);
+- mt7915_mcu_add_sta(dev, vif, NULL, join);
+- }
+-
++ vif->type == NL80211_IFTYPE_STATION)
++ set_bss_info = set_sta = !is_zero_ether_addr(info->bssid);
+ if (changed & BSS_CHANGED_ASSOC)
+- mt7915_mcu_add_bss_info(phy, vif, vif->cfg.assoc);
++ set_bss_info = vif->cfg.assoc;
++ if (changed & BSS_CHANGED_BEACON_ENABLED &&
++ vif->type != NL80211_IFTYPE_AP)
++ set_bss_info = set_sta = info->enable_beacon;
++
++ if (set_bss_info == 1)
++ mt7915_mcu_add_bss_info(phy, vif, true);
++ if (set_sta == 1)
++ mt7915_mcu_add_sta(dev, vif, NULL, true);
+
+ if (changed & BSS_CHANGED_ERP_CTS_PROT)
+ mt7915_mac_enable_rtscts(dev, vif, info->use_cts_prot);
+@@ -629,11 +633,6 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
+ }
+ }
+
+- if (changed & BSS_CHANGED_BEACON_ENABLED && info->enable_beacon) {
+- mt7915_mcu_add_bss_info(phy, vif, true);
+- mt7915_mcu_add_sta(dev, vif, NULL, true);
+- }
+-
+ /* ensure that enable txcmd_mode after bss_info */
+ if (changed & (BSS_CHANGED_QOS | BSS_CHANGED_BEACON_ENABLED))
+ mt7915_mcu_set_tx(dev, vif);
+@@ -650,6 +649,42 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
+ BSS_CHANGED_FILS_DISCOVERY))
+ mt7915_mcu_add_beacon(hw, vif, info->enable_beacon, changed);
+
++ if (set_bss_info == 0)
++ mt7915_mcu_add_bss_info(phy, vif, false);
++ if (set_sta == 0)
++ mt7915_mcu_add_sta(dev, vif, NULL, false);
++
++ mutex_unlock(&dev->mt76.mutex);
++}
++
++static int
++mt7915_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
++ struct ieee80211_bss_conf *link_conf)
++{
++ struct mt7915_phy *phy = mt7915_hw_phy(hw);
++ struct mt7915_dev *dev = mt7915_hw_dev(hw);
++ int err;
++
++ mutex_lock(&dev->mt76.mutex);
++
++ err = mt7915_mcu_add_bss_info(phy, vif, true);
++ if (err)
++ goto out;
++ err = mt7915_mcu_add_sta(dev, vif, NULL, true);
++out:
++ mutex_unlock(&dev->mt76.mutex);
++
++ return err;
++}
++
++static void
++mt7915_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
++ struct ieee80211_bss_conf *link_conf)
++{
++ struct mt7915_dev *dev = mt7915_hw_dev(hw);
++
++ mutex_lock(&dev->mt76.mutex);
++ mt7915_mcu_add_sta(dev, vif, NULL, false);
+ mutex_unlock(&dev->mt76.mutex);
+ }
+
+@@ -1528,6 +1563,8 @@ const struct ieee80211_ops mt7915_ops = {
+ .conf_tx = mt7915_conf_tx,
+ .configure_filter = mt7915_configure_filter,
+ .bss_info_changed = mt7915_bss_info_changed,
++ .start_ap = mt7915_start_ap,
++ .stop_ap = mt7915_stop_ap,
+ .sta_add = mt7915_sta_add,
+ .sta_remove = mt7915_sta_remove,
+ .sta_pre_rcu_remove = mt76_sta_pre_rcu_remove,
+--
+2.40.1
+
--- /dev/null
+From 368bda4228de09cd76f4babc43771d9717740b26 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Jul 2023 02:35:06 +0800
+Subject: wifi: mt76: mt7915: fix power-limits while chan_switch
+
+From: Ryder Lee <ryder.lee@mediatek.com>
+
+[ Upstream commit 6c0570bc21ec2073890aa252c8420ca7bec402e4 ]
+
+If user changes the channel without completely disabling the interface the
+txpower_sku values reported track the old channel the device was operating on.
+If user bounces the interface the correct power tables are applied.
+
+mt7915_sku_group_len array gets updated before the channel switch happens so it
+uses data from the old channel.
+
+Fixes: ecb187a74e18 ("mt76: mt7915: rework the flow of txpower setting")
+Fixes: f1d962369d56 ("mt76: mt7915: implement HE per-rate tx power support")
+Reported-By: Chad Monroe <chad.monroe@smartrg.com>
+Tested-by: Chad Monroe <chad.monroe@smartrg.com>
+Signed-off-by: Allen Ye <allen.ye@mediatek.com>
+Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7915/main.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+index ed345a0b931e0..42a983e40ade9 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+@@ -471,7 +471,8 @@ static int mt7915_config(struct ieee80211_hw *hw, u32 changed)
+ ieee80211_wake_queues(hw);
+ }
+
+- if (changed & IEEE80211_CONF_CHANGE_POWER) {
++ if (changed & (IEEE80211_CONF_CHANGE_POWER |
++ IEEE80211_CONF_CHANGE_CHANNEL)) {
+ ret = mt7915_mcu_set_txpower_sku(phy);
+ if (ret)
+ return ret;
+--
+2.40.1
+
--- /dev/null
+From 39480a8e49d7312aeecbad353e6c47d9d7b6a427 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Jul 2023 02:35:05 +0800
+Subject: wifi: mt76: mt7915: fix tlv length of mt7915_mcu_get_chan_mib_info
+
+From: Ryder Lee <ryder.lee@mediatek.com>
+
+[ Upstream commit 4f1875c288dfc1ccea81fc17fef1d30c9d8498b2 ]
+
+Correct per-device TLV lengths to avoid invalid operation in firmware.
+( 64.040375:28:STATS-E)statsGetSingleHWCounter: MIB counter index = 65472 not supported.
+This happens on mt7916/mt7986.
+
+Fixes: b0bfa00595be ("wifi: mt76: mt7915: improve accuracy of time_busy calculation")
+Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7915/mcu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+index a325066bf57e9..1a8611c6b684d 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+@@ -3000,7 +3000,7 @@ int mt7915_mcu_get_chan_mib_info(struct mt7915_phy *phy, bool chan_switch)
+ }
+
+ ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_CMD(GET_MIB_INFO),
+- req, sizeof(req), true, &skb);
++ req, len * sizeof(req[0]), true, &skb);
+ if (ret)
+ return ret;
+
+--
+2.40.1
+
--- /dev/null
+From a342c5000892386a140cb14f90311b94165c3bdb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Jul 2023 10:57:15 +0200
+Subject: wifi: mt76: mt7915: remove VHT160 capability on MT7915
+
+From: Felix Fietkau <nbd@nbd.name>
+
+[ Upstream commit 3ec5ac12ac8a4e6b1e085374325a5fbd1b650fd5 ]
+
+The IEEE80211_VHT_CAP_EXT_NSS_BW value already indicates support for half-NSS
+160 MHz support, so it is wrong to also advertise full 160 MHz support.
+
+Fixes: c2f73eacee3b ("wifi: mt76: mt7915: add back 160MHz channel width support for MT7915")
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7915/init.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
+index 927a98a315ae8..9defd2b3c2f8d 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
+@@ -414,7 +414,6 @@ mt7915_init_wiphy(struct mt7915_phy *phy)
+ if (!dev->dbdc_support)
+ vht_cap->cap |=
+ IEEE80211_VHT_CAP_SHORT_GI_160 |
+- IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ |
+ FIELD_PREP(IEEE80211_VHT_CAP_EXT_NSS_BW_MASK, 1);
+ } else {
+ vht_cap->cap |=
+--
+2.40.1
+
--- /dev/null
+From 52cb1046c8b4b1016e493d3a27858ed89e19cce4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 May 2023 12:53:18 +0800
+Subject: wifi: mt76: mt7915: rework tx bytes counting when WED is active
+
+From: Peter Chiu <chui-hao.chiu@mediatek.com>
+
+[ Upstream commit f39d499345dddb8382986fd5a2a0e84a63b1a6d5 ]
+
+Concurrent binding/non-binding skbs could be handled anywhere which leads
+to mixed byte counting, so switch to use PPDU TxS reporting regardless Tx
+paths when WED is active.
+
+Fixes: 43eaa3689507 ("wifi: mt76: add PPDU based TxS support for WED device")
+Co-developed-by: Ryder Lee <ryder.lee@mediatek.com>
+Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
+Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../wireless/mediatek/mt76/mt76_connac_mac.c | 2 --
+ .../net/wireless/mediatek/mt76/mt7915/init.c | 6 ++++
+ .../net/wireless/mediatek/mt76/mt7915/mmio.c | 30 ++-----------------
+ drivers/net/wireless/mediatek/mt76/tx.c | 9 +++++-
+ 4 files changed, 16 insertions(+), 31 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
+index 49b2b1f3ffa87..e415ac5e321f1 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
+@@ -522,8 +522,6 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi,
+ q_idx = wmm_idx * MT76_CONNAC_MAX_WMM_SETS +
+ mt76_connac_lmac_mapping(skb_get_queue_mapping(skb));
+
+- /* counting non-offloading skbs */
+- wcid->stats.tx_bytes += skb->len;
+ /* mt7915 WA only counts WED path */
+ if (is_mt7915(dev) && mtk_wed_device_active(&dev->mmio.wed))
+ wcid->stats.tx_packets++;
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
+index ac2049f49bb38..927a98a315ae8 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
+@@ -499,6 +499,12 @@ mt7915_mac_init_band(struct mt7915_dev *dev, u8 band)
+ set = FIELD_PREP(MT_WTBLOFF_TOP_RSCR_RCPI_MODE, 0) |
+ FIELD_PREP(MT_WTBLOFF_TOP_RSCR_RCPI_PARAM, 0x3);
+ mt76_rmw(dev, MT_WTBLOFF_TOP_RSCR(band), mask, set);
++
++ /* MT_TXD5_TX_STATUS_HOST (MPDU format) has higher priority than
++ * MT_AGG_ACR_PPDU_TXS2H (PPDU format) even though ACR bit is set.
++ */
++ if (mtk_wed_device_active(&dev->mt76.mmio.wed))
++ mt76_set(dev, MT_AGG_ACR4(band), MT_AGG_ACR_PPDU_TXS2H);
+ }
+
+ static void
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c b/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c
+index 45f3558bf31c1..2fa059af23ded 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c
+@@ -545,8 +545,6 @@ static u32 mt7915_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val)
+ static int mt7915_mmio_wed_offload_enable(struct mtk_wed_device *wed)
+ {
+ struct mt7915_dev *dev;
+- struct mt7915_phy *phy;
+- int ret;
+
+ dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
+
+@@ -554,43 +552,19 @@ static int mt7915_mmio_wed_offload_enable(struct mtk_wed_device *wed)
+ dev->mt76.token_size = wed->wlan.token_start;
+ spin_unlock_bh(&dev->mt76.token_lock);
+
+- ret = wait_event_timeout(dev->mt76.tx_wait,
+- !dev->mt76.wed_token_count, HZ);
+- if (!ret)
+- return -EAGAIN;
+-
+- phy = &dev->phy;
+- mt76_set(dev, MT_AGG_ACR4(phy->mt76->band_idx), MT_AGG_ACR_PPDU_TXS2H);
+-
+- phy = dev->mt76.phys[MT_BAND1] ? dev->mt76.phys[MT_BAND1]->priv : NULL;
+- if (phy)
+- mt76_set(dev, MT_AGG_ACR4(phy->mt76->band_idx),
+- MT_AGG_ACR_PPDU_TXS2H);
+-
+- return 0;
++ return !wait_event_timeout(dev->mt76.tx_wait,
++ !dev->mt76.wed_token_count, HZ);
+ }
+
+ static void mt7915_mmio_wed_offload_disable(struct mtk_wed_device *wed)
+ {
+ struct mt7915_dev *dev;
+- struct mt7915_phy *phy;
+
+ dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
+
+ spin_lock_bh(&dev->mt76.token_lock);
+ dev->mt76.token_size = MT7915_TOKEN_SIZE;
+ spin_unlock_bh(&dev->mt76.token_lock);
+-
+- /* MT_TXD5_TX_STATUS_HOST (MPDU format) has higher priority than
+- * MT_AGG_ACR_PPDU_TXS2H (PPDU format) even though ACR bit is set.
+- */
+- phy = &dev->phy;
+- mt76_clear(dev, MT_AGG_ACR4(phy->mt76->band_idx), MT_AGG_ACR_PPDU_TXS2H);
+-
+- phy = dev->mt76.phys[MT_BAND1] ? dev->mt76.phys[MT_BAND1]->priv : NULL;
+- if (phy)
+- mt76_clear(dev, MT_AGG_ACR4(phy->mt76->band_idx),
+- MT_AGG_ACR_PPDU_TXS2H);
+ }
+
+ static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
+diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c
+index 72b3ec715e47a..e9b9728458a9b 100644
+--- a/drivers/net/wireless/mediatek/mt76/tx.c
++++ b/drivers/net/wireless/mediatek/mt76/tx.c
+@@ -121,6 +121,7 @@ int
+ mt76_tx_status_skb_add(struct mt76_dev *dev, struct mt76_wcid *wcid,
+ struct sk_buff *skb)
+ {
++ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct mt76_tx_cb *cb = mt76_tx_skb_cb(skb);
+ int pid;
+@@ -134,8 +135,14 @@ mt76_tx_status_skb_add(struct mt76_dev *dev, struct mt76_wcid *wcid,
+ return MT_PACKET_ID_NO_ACK;
+
+ if (!(info->flags & (IEEE80211_TX_CTL_REQ_TX_STATUS |
+- IEEE80211_TX_CTL_RATE_CTRL_PROBE)))
++ IEEE80211_TX_CTL_RATE_CTRL_PROBE))) {
++ if (mtk_wed_device_active(&dev->mmio.wed) &&
++ ((info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) ||
++ ieee80211_is_data(hdr->frame_control)))
++ return MT_PACKET_ID_WED;
++
+ return MT_PACKET_ID_NO_SKB;
++ }
+
+ spin_lock_bh(&dev->status_lock);
+
+--
+2.40.1
+
--- /dev/null
+From 9f98117d2a4448d15db314cdf933461b902bfdc9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 May 2023 12:53:17 +0800
+Subject: wifi: mt76: mt7915: rework tx packets counting when WED is active
+
+From: Peter Chiu <chui-hao.chiu@mediatek.com>
+
+[ Upstream commit 161a7528e4074d104305fc109c16134b4990070e ]
+
+PPDU TxS can only report MPDU count whereas mac80211 requires MSDU scale
+(NL80211_STA_INFO_TX_PACKETS), so switch to get MSDU counts from WA
+statistic.
+
+Note that mt7915 WA firmware only counts tx_packet for WED path, so driver
+needs to take care of host path additionally.
+
+Fixes: 43eaa3689507 ("wifi: mt76: add PPDU based TxS support for WED device")
+Co-developed-by: Ryder Lee <ryder.lee@mediatek.com>
+Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
+Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt76.h | 2 +-
+ .../wireless/mediatek/mt76/mt76_connac_mac.c | 9 ++-
+ .../wireless/mediatek/mt76/mt76_connac_mcu.h | 1 +
+ .../net/wireless/mediatek/mt76/mt7915/main.c | 6 +-
+ .../net/wireless/mediatek/mt76/mt7915/mcu.c | 74 +++++++++++++++++--
+ .../wireless/mediatek/mt76/mt7915/mt7915.h | 1 +
+ 6 files changed, 79 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
+index 6b07b8fafec2f..0e9f4197213a3 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76.h
++++ b/drivers/net/wireless/mediatek/mt76/mt76.h
+@@ -277,7 +277,7 @@ struct mt76_sta_stats {
+ u64 tx_mcs[16]; /* mcs idx */
+ u64 tx_bytes;
+ /* WED TX */
+- u32 tx_packets;
++ u32 tx_packets; /* unit: MSDU */
+ u32 tx_retries;
+ u32 tx_failed;
+ /* WED RX */
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
+index be4d63db5f64a..49b2b1f3ffa87 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
+@@ -524,7 +524,9 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi,
+
+ /* counting non-offloading skbs */
+ wcid->stats.tx_bytes += skb->len;
+- wcid->stats.tx_packets++;
++ /* mt7915 WA only counts WED path */
++ if (is_mt7915(dev) && mtk_wed_device_active(&dev->mmio.wed))
++ wcid->stats.tx_packets++;
+ }
+
+ val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len + sz_txd) |
+@@ -609,12 +611,11 @@ bool mt76_connac2_mac_fill_txs(struct mt76_dev *dev, struct mt76_wcid *wcid,
+ txs = le32_to_cpu(txs_data[0]);
+
+ /* PPDU based reporting */
+- if (FIELD_GET(MT_TXS0_TXS_FORMAT, txs) > 1) {
++ if (mtk_wed_device_active(&dev->mmio.wed) &&
++ FIELD_GET(MT_TXS0_TXS_FORMAT, txs) > 1) {
+ stats->tx_bytes +=
+ le32_get_bits(txs_data[5], MT_TXS5_MPDU_TX_BYTE) -
+ le32_get_bits(txs_data[7], MT_TXS7_MPDU_RETRY_BYTE);
+- stats->tx_packets +=
+- le32_get_bits(txs_data[5], MT_TXS5_MPDU_TX_CNT);
+ stats->tx_failed +=
+ le32_get_bits(txs_data[6], MT_TXS6_MPDU_FAIL_CNT);
+ stats->tx_retries +=
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
+index ca1ce97a6d2fd..7a52b68491b6e 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
++++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
+@@ -998,6 +998,7 @@ enum {
+ MCU_EXT_EVENT_ASSERT_DUMP = 0x23,
+ MCU_EXT_EVENT_RDD_REPORT = 0x3a,
+ MCU_EXT_EVENT_CSA_NOTIFY = 0x4f,
++ MCU_EXT_EVENT_WA_TX_STAT = 0x74,
+ MCU_EXT_EVENT_BCC_NOTIFY = 0x75,
+ MCU_EXT_EVENT_MURU_CTRL = 0x9f,
+ };
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+index 1b361199c0616..2da57357c4174 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+@@ -1042,8 +1042,10 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw,
+ sinfo->tx_bytes = msta->wcid.stats.tx_bytes;
+ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES64);
+
+- sinfo->tx_packets = msta->wcid.stats.tx_packets;
+- sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS);
++ if (!mt7915_mcu_wed_wa_tx_stats(phy->dev, msta->wcid.idx)) {
++ sinfo->tx_packets = msta->wcid.stats.tx_packets;
++ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS);
++ }
+
+ sinfo->tx_failed = msta->wcid.stats.tx_failed;
+ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED);
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+index 088a065e37d5d..8da9c87e98042 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+@@ -164,7 +164,9 @@ mt7915_mcu_parse_response(struct mt76_dev *mdev, int cmd,
+ }
+
+ rxd = (struct mt76_connac2_mcu_rxd *)skb->data;
+- if (seq != rxd->seq)
++ if (seq != rxd->seq &&
++ !(rxd->eid == MCU_CMD_EXT_CID &&
++ rxd->ext_eid == MCU_EXT_EVENT_WA_TX_STAT))
+ return -EAGAIN;
+
+ if (cmd == MCU_CMD(PATCH_SEM_CONTROL)) {
+@@ -395,12 +397,14 @@ void mt7915_mcu_rx_event(struct mt7915_dev *dev, struct sk_buff *skb)
+ struct mt76_connac2_mcu_rxd *rxd;
+
+ rxd = (struct mt76_connac2_mcu_rxd *)skb->data;
+- if (rxd->ext_eid == MCU_EXT_EVENT_THERMAL_PROTECT ||
+- rxd->ext_eid == MCU_EXT_EVENT_FW_LOG_2_HOST ||
+- rxd->ext_eid == MCU_EXT_EVENT_ASSERT_DUMP ||
+- rxd->ext_eid == MCU_EXT_EVENT_PS_SYNC ||
+- rxd->ext_eid == MCU_EXT_EVENT_BCC_NOTIFY ||
+- !rxd->seq)
++ if ((rxd->ext_eid == MCU_EXT_EVENT_THERMAL_PROTECT ||
++ rxd->ext_eid == MCU_EXT_EVENT_FW_LOG_2_HOST ||
++ rxd->ext_eid == MCU_EXT_EVENT_ASSERT_DUMP ||
++ rxd->ext_eid == MCU_EXT_EVENT_PS_SYNC ||
++ rxd->ext_eid == MCU_EXT_EVENT_BCC_NOTIFY ||
++ !rxd->seq) &&
++ !(rxd->eid == MCU_CMD_EXT_CID &&
++ rxd->ext_eid == MCU_EXT_EVENT_WA_TX_STAT))
+ mt7915_mcu_rx_unsolicited_event(dev, skb);
+ else
+ mt76_mcu_rx_event(&dev->mt76, skb);
+@@ -3733,6 +3737,62 @@ int mt7915_mcu_twt_agrt_update(struct mt7915_dev *dev,
+ &req, sizeof(req), true);
+ }
+
++int mt7915_mcu_wed_wa_tx_stats(struct mt7915_dev *dev, u16 wlan_idx)
++{
++ struct {
++ __le32 cmd;
++ __le32 num;
++ __le32 __rsv;
++ __le16 wlan_idx;
++ } req = {
++ .cmd = cpu_to_le32(0x15),
++ .num = cpu_to_le32(1),
++ .wlan_idx = cpu_to_le16(wlan_idx),
++ };
++ struct mt7915_mcu_wa_tx_stat {
++ __le16 wlan_idx;
++ u8 __rsv[2];
++
++ /* tx_bytes is deprecated since WA byte counter uses u32,
++ * which easily leads to overflow.
++ */
++ __le32 tx_bytes;
++ __le32 tx_packets;
++ } *res;
++ struct mt76_wcid *wcid;
++ struct sk_buff *skb;
++ int ret;
++
++ ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_WA_PARAM_CMD(QUERY),
++ &req, sizeof(req), true, &skb);
++ if (ret)
++ return ret;
++
++ if (!is_mt7915(&dev->mt76))
++ skb_pull(skb, 4);
++
++ res = (struct mt7915_mcu_wa_tx_stat *)skb->data;
++
++ if (le16_to_cpu(res->wlan_idx) != wlan_idx) {
++ ret = -EINVAL;
++ goto out;
++ }
++
++ rcu_read_lock();
++
++ wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]);
++ if (wcid)
++ wcid->stats.tx_packets += le32_to_cpu(res->tx_packets);
++ else
++ ret = -EINVAL;
++
++ rcu_read_unlock();
++out:
++ dev_kfree_skb(skb);
++
++ return ret;
++}
++
+ int mt7915_mcu_rf_regval(struct mt7915_dev *dev, u32 regidx, u32 *val, bool set)
+ {
+ struct {
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+index b3ead35307406..3053f4abf7dbe 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+@@ -539,6 +539,7 @@ int mt7915_mcu_get_rx_rate(struct mt7915_phy *phy, struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta, struct rate_info *rate);
+ int mt7915_mcu_rdd_background_enable(struct mt7915_phy *phy,
+ struct cfg80211_chan_def *chandef);
++int mt7915_mcu_wed_wa_tx_stats(struct mt7915_dev *dev, u16 wcid);
+ int mt7915_mcu_rf_regval(struct mt7915_dev *dev, u32 regidx, u32 *val, bool set);
+ int mt7915_mcu_wa_cmd(struct mt7915_dev *dev, int cmd, u32 a1, u32 a2, u32 a3);
+ int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 type, u8 ctrl);
+--
+2.40.1
+
--- /dev/null
+From 7a480bfd9286c66c027ea108dd4ad2ead682fb2a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 May 2023 22:08:14 +0800
+Subject: wifi: mt76: mt7921: fix non-PSC channel scan fail
+
+From: Ming Yen Hsieh <mingyen.hsieh@mediatek.com>
+
+[ Upstream commit 0e5911bb7cc92c00dda9b4d635c1266b7ca915c6 ]
+
+Due to the scan command may only request legacy bands and PSC channel
+in 6GHz band, we are unable to scan the APs on non-PSC channel in this
+case. Enable WIPHY_FLAG_SPLIT_SCAN_6GHZ to support non-PSC channel
+(obtained during scan on legacy bands) in 6GHz scan request.
+
+Fixes: 50ac15a511e3 ("mt76: mt7921: add 6GHz support")
+Signed-off-by: Ming Yen Hsieh <mingyen.hsieh@mediatek.com>
+Signed-off-by: Deren Wu <deren.wu@mediatek.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7921/init.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/init.c b/drivers/net/wireless/mediatek/mt76/mt7921/init.c
+index bf1da9fddfaba..f41975e37d06a 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/init.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/init.c
+@@ -113,7 +113,8 @@ mt7921_init_wiphy(struct ieee80211_hw *hw)
+ wiphy->max_sched_scan_ssids = MT76_CONNAC_MAX_SCHED_SCAN_SSID;
+ wiphy->max_match_sets = MT76_CONNAC_MAX_SCAN_MATCH;
+ wiphy->max_sched_scan_reqs = 1;
+- wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
++ wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH |
++ WIPHY_FLAG_SPLIT_SCAN_6GHZ;
+ wiphy->reg_notifier = mt7921_regd_notifier;
+
+ wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR |
+--
+2.40.1
+
--- /dev/null
+From be4ed0a196edc2afa84e669c58e632b33358eb6a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Jun 2023 23:21:34 +0800
+Subject: wifi: mt76: mt7996: fix bss wlan_idx when sending bss_info command
+
+From: Peter Chiu <chui-hao.chiu@mediatek.com>
+
+[ Upstream commit cc945b546227423488fe4be0ab92fd126b703246 ]
+
+The bmc_tx_wlan_idx should be the wlan_idx of the current bss rather
+than peer AP's wlan_idx, otherwise there will appear some frame
+decryption problems on station mode.
+
+Fixes: 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
+Reviewed-by: Shayne Chen <shayne.chen@mediatek.com>
+Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
+Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
+index 88e2f9d0e5130..cd54e81d73044 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
+@@ -712,6 +712,7 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb,
+ struct cfg80211_chan_def *chandef = &phy->chandef;
+ struct mt76_connac_bss_basic_tlv *bss;
+ u32 type = CONNECTION_INFRA_AP;
++ u16 sta_wlan_idx = wlan_idx;
+ struct tlv *tlv;
+ int idx;
+
+@@ -731,7 +732,7 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb,
+ struct mt76_wcid *wcid;
+
+ wcid = (struct mt76_wcid *)sta->drv_priv;
+- wlan_idx = wcid->idx;
++ sta_wlan_idx = wcid->idx;
+ }
+ rcu_read_unlock();
+ }
+@@ -751,7 +752,7 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb,
+ bss->bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int);
+ bss->dtim_period = vif->bss_conf.dtim_period;
+ bss->bmc_tx_wlan_idx = cpu_to_le16(wlan_idx);
+- bss->sta_idx = cpu_to_le16(wlan_idx);
++ bss->sta_idx = cpu_to_le16(sta_wlan_idx);
+ bss->conn_type = cpu_to_le32(type);
+ bss->omac_idx = mvif->omac_idx;
+ bss->band_idx = mvif->band_idx;
+--
+2.40.1
+
--- /dev/null
+From c7803de24415d5ba34643f04496595033885a35b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Apr 2023 07:05:15 +0800
+Subject: wifi: mt76: mt7996: fix header translation logic
+
+From: Ryder Lee <ryder.lee@mediatek.com>
+
+[ Upstream commit c55b4e788f1dd6ca89cc97cf291d2a03b0b96de1 ]
+
+When header translation failure is indicated, the hardware will insert
+an extra 2-byte field containing the data length after the protocol
+type field. This happens either when the LLC-SNAP pattern did not match,
+or if a VLAN header was detected.
+
+The previous commit accidentally breaks the logic, so reverts back.
+
+Fixes: 27db47ab1f47 (wifi: mt76: mt7996: enable mesh HW amsdu/de-amsdu support)
+Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7996/mac.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
+index 9b0f6053e0fa6..25c5deb15d213 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
+@@ -836,14 +836,19 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb)
+ skb_pull(skb, hdr_gap);
+ if (!hdr_trans && status->amsdu && !(ieee80211_has_a4(fc) && is_mesh)) {
+ pad_start = ieee80211_get_hdrlen_from_skb(skb);
+- } else if (hdr_trans && (rxd2 & MT_RXD2_NORMAL_HDR_TRANS_ERROR) &&
+- get_unaligned_be16(skb->data + pad_start) == ETH_P_8021Q) {
++ } else if (hdr_trans && (rxd2 & MT_RXD2_NORMAL_HDR_TRANS_ERROR)) {
+ /* When header translation failure is indicated,
+ * the hardware will insert an extra 2-byte field
+ * containing the data length after the protocol
+- * type field.
++ * type field. This happens either when the LLC-SNAP
++ * pattern did not match, or if a VLAN header was
++ * detected.
+ */
+- pad_start = 16;
++ pad_start = 12;
++ if (get_unaligned_be16(skb->data + pad_start) == ETH_P_8021Q)
++ pad_start += 4;
++ else
++ pad_start = 0;
+ }
+
+ if (pad_start) {
+--
+2.40.1
+
--- /dev/null
+From c9f694858b9528f801c92c38af3874efd15db606 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Jun 2023 23:21:39 +0800
+Subject: wifi: mt76: mt7996: fix WA event ring size
+
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+
+[ Upstream commit 1634de418b3048c5f435b6ffd37f75943c554c04 ]
+
+Fix rx ring size of WA event to get rid of event loss and queue overflow
+problems.
+
+Fixes: 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7996/dma.c | 2 +-
+ drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h | 1 +
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/dma.c b/drivers/net/wireless/mediatek/mt76/mt7996/dma.c
+index 534143465d9b3..fbedaacffbba5 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7996/dma.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7996/dma.c
+@@ -293,7 +293,7 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+ /* event from WA */
+ ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU_WA],
+ MT_RXQ_ID(MT_RXQ_MCU_WA),
+- MT7996_RX_MCU_RING_SIZE,
++ MT7996_RX_MCU_RING_SIZE_WA,
+ MT_RX_BUF_SIZE,
+ MT_RXQ_RING_BASE(MT_RXQ_MCU_WA));
+ if (ret)
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
+index 4d7dcb95a620a..b8bcad717d89f 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
+@@ -26,6 +26,7 @@
+
+ #define MT7996_RX_RING_SIZE 1536
+ #define MT7996_RX_MCU_RING_SIZE 512
++#define MT7996_RX_MCU_RING_SIZE_WA 1024
+
+ #define MT7996_FIRMWARE_WA "mediatek/mt7996/mt7996_wa.bin"
+ #define MT7996_FIRMWARE_WM "mediatek/mt7996/mt7996_wm.bin"
+--
+2.40.1
+
--- /dev/null
+From 52cef43e6a8371e7cc4d057d68dbcb8efec79325 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Jun 2023 23:21:38 +0800
+Subject: wifi: mt76: mt7996: use correct phy for background radar event
+
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+
+[ Upstream commit 9ffe0d5690ed916e09baad2cc9ee7ec65b110038 ]
+
+If driver directly uses the band_idx reported from the radar event to
+access mt76_phy array, it will get the wrong phy for background radar.
+Fix this by adjusting the statement.
+
+Fixes: 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
+index cd54e81d73044..62a02b03d83ba 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
+@@ -339,7 +339,11 @@ mt7996_mcu_rx_radar_detected(struct mt7996_dev *dev, struct sk_buff *skb)
+ if (r->band_idx >= ARRAY_SIZE(dev->mt76.phys))
+ return;
+
+- mphy = dev->mt76.phys[r->band_idx];
++ if (dev->rdd2_phy && r->band_idx == MT_RX_SEL2)
++ mphy = dev->rdd2_phy->mt76;
++ else
++ mphy = dev->mt76.phys[r->band_idx];
++
+ if (!mphy)
+ return;
+
+--
+2.40.1
+
--- /dev/null
+From 1e5fb061969eff5253815a7646eeb59d7a3fd234 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 23 Jul 2023 16:03:50 +0800
+Subject: wifi: mt76: testmode: add nla_policy for MT76_TM_ATTR_TX_LENGTH
+
+From: Lin Ma <linma@zju.edu.cn>
+
+[ Upstream commit 74f12d511625e603fac8c0c2b6872e687e56dd61 ]
+
+It seems that the nla_policy in mt76_tm_policy is missed for attribute
+MT76_TM_ATTR_TX_LENGTH. This patch adds the correct description to make
+sure the
+
+ u32 val = nla_get_u32(tb[MT76_TM_ATTR_TX_LENGTH]);
+
+in function mt76_testmode_cmd() is safe and will not result in
+out-of-attribute read.
+
+Fixes: f0efa8621550 ("mt76: add API for testmode support")
+Signed-off-by: Lin Ma <linma@zju.edu.cn>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/testmode.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/testmode.c b/drivers/net/wireless/mediatek/mt76/testmode.c
+index 0accc71a91c9a..4644dace9bb34 100644
+--- a/drivers/net/wireless/mediatek/mt76/testmode.c
++++ b/drivers/net/wireless/mediatek/mt76/testmode.c
+@@ -8,6 +8,7 @@ const struct nla_policy mt76_tm_policy[NUM_MT76_TM_ATTRS] = {
+ [MT76_TM_ATTR_RESET] = { .type = NLA_FLAG },
+ [MT76_TM_ATTR_STATE] = { .type = NLA_U8 },
+ [MT76_TM_ATTR_TX_COUNT] = { .type = NLA_U32 },
++ [MT76_TM_ATTR_TX_LENGTH] = { .type = NLA_U32 },
+ [MT76_TM_ATTR_TX_RATE_MODE] = { .type = NLA_U8 },
+ [MT76_TM_ATTR_TX_RATE_NSS] = { .type = NLA_U8 },
+ [MT76_TM_ATTR_TX_RATE_IDX] = { .type = NLA_U8 },
+--
+2.40.1
+
--- /dev/null
+From 0b62b3d6011478da214e46325f8f4e6e87fe6849 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Aug 2023 12:49:57 +0300
+Subject: wifi: mwifiex: avoid possible NULL skb pointer dereference
+
+From: Dmitry Antipov <dmantipov@yandex.ru>
+
+[ Upstream commit 35a7a1ce7c7d61664ee54f5239a1f120ab95a87e ]
+
+In 'mwifiex_handle_uap_rx_forward()', always check the value
+returned by 'skb_copy()' to avoid potential NULL pointer
+dereference in 'mwifiex_uap_queue_bridged_pkt()', and drop
+original skb in case of copying failure.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: 838e4f449297 ("mwifiex: improve uAP RX handling")
+Acked-by: Brian Norris <briannorris@chromium.org>
+Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20230814095041.16416-1-dmantipov@yandex.ru
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/marvell/mwifiex/uap_txrx.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/marvell/mwifiex/uap_txrx.c b/drivers/net/wireless/marvell/mwifiex/uap_txrx.c
+index c1b8d41dd7536..b8b9a0fcb19cd 100644
+--- a/drivers/net/wireless/marvell/mwifiex/uap_txrx.c
++++ b/drivers/net/wireless/marvell/mwifiex/uap_txrx.c
+@@ -253,7 +253,15 @@ int mwifiex_handle_uap_rx_forward(struct mwifiex_private *priv,
+
+ if (is_multicast_ether_addr(ra)) {
+ skb_uap = skb_copy(skb, GFP_ATOMIC);
+- mwifiex_uap_queue_bridged_pkt(priv, skb_uap);
++ if (likely(skb_uap)) {
++ mwifiex_uap_queue_bridged_pkt(priv, skb_uap);
++ } else {
++ mwifiex_dbg(adapter, ERROR,
++ "failed to copy skb for uAP\n");
++ priv->stats.rx_dropped++;
++ dev_kfree_skb_any(skb);
++ return -1;
++ }
+ } else {
+ if (mwifiex_get_sta_entry(priv, ra)) {
+ /* Requeue Intra-BSS packet */
+--
+2.40.1
+
--- /dev/null
+From 973003e006d27082f5f0ae5182bb59f5324c507e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Jul 2023 10:43:07 +0300
+Subject: wifi: mwifiex: fix error recovery in PCIE buffer descriptor
+ management
+
+From: Dmitry Antipov <dmantipov@yandex.ru>
+
+[ Upstream commit 288c63d5cb4667a51a04668b3e2bb0ea499bc5f4 ]
+
+Add missing 'kfree_skb()' in 'mwifiex_init_rxq_ring()' and never do
+'kfree(card->rxbd_ring_vbase)' because this area is DMAed and should
+be released with 'dma_free_coherent()'. The latter is performed in
+'mwifiex_pcie_delete_rxbd_ring()', which is now called to recover
+from possible errors in 'mwifiex_pcie_create_rxbd_ring()'. Likewise
+for 'mwifiex_pcie_init_evt_ring()', 'kfree(card->evtbd_ring_vbase)'
+'mwifiex_pcie_delete_evtbd_ring()' and 'mwifiex_pcie_create_rxbd_ring()'.
+
+Fixes: d930faee141b ("mwifiex: add support for Marvell pcie8766 chipset")
+Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
+Acked-by: Brian Norris <briannorris@chromium.org>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20230731074334.56463-1-dmantipov@yandex.ru
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/marvell/mwifiex/pcie.c | 25 ++++++++++++++-------
+ 1 file changed, 17 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
+index 9a698a16a8f38..6697132ecc977 100644
+--- a/drivers/net/wireless/marvell/mwifiex/pcie.c
++++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
+@@ -189,6 +189,8 @@ static int mwifiex_pcie_probe_of(struct device *dev)
+ }
+
+ static void mwifiex_pcie_work(struct work_struct *work);
++static int mwifiex_pcie_delete_rxbd_ring(struct mwifiex_adapter *adapter);
++static int mwifiex_pcie_delete_evtbd_ring(struct mwifiex_adapter *adapter);
+
+ static int
+ mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb,
+@@ -792,14 +794,15 @@ static int mwifiex_init_rxq_ring(struct mwifiex_adapter *adapter)
+ if (!skb) {
+ mwifiex_dbg(adapter, ERROR,
+ "Unable to allocate skb for RX ring.\n");
+- kfree(card->rxbd_ring_vbase);
+ return -ENOMEM;
+ }
+
+ if (mwifiex_map_pci_memory(adapter, skb,
+ MWIFIEX_RX_DATA_BUF_SIZE,
+- DMA_FROM_DEVICE))
+- return -1;
++ DMA_FROM_DEVICE)) {
++ kfree_skb(skb);
++ return -ENOMEM;
++ }
+
+ buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
+
+@@ -849,7 +852,6 @@ static int mwifiex_pcie_init_evt_ring(struct mwifiex_adapter *adapter)
+ if (!skb) {
+ mwifiex_dbg(adapter, ERROR,
+ "Unable to allocate skb for EVENT buf.\n");
+- kfree(card->evtbd_ring_vbase);
+ return -ENOMEM;
+ }
+ skb_put(skb, MAX_EVENT_SIZE);
+@@ -857,8 +859,7 @@ static int mwifiex_pcie_init_evt_ring(struct mwifiex_adapter *adapter)
+ if (mwifiex_map_pci_memory(adapter, skb, MAX_EVENT_SIZE,
+ DMA_FROM_DEVICE)) {
+ kfree_skb(skb);
+- kfree(card->evtbd_ring_vbase);
+- return -1;
++ return -ENOMEM;
+ }
+
+ buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
+@@ -1058,6 +1059,7 @@ static int mwifiex_pcie_delete_txbd_ring(struct mwifiex_adapter *adapter)
+ */
+ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter)
+ {
++ int ret;
+ struct pcie_service_card *card = adapter->card;
+ const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
+
+@@ -1096,7 +1098,10 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter)
+ (u32)((u64)card->rxbd_ring_pbase >> 32),
+ card->rxbd_ring_size);
+
+- return mwifiex_init_rxq_ring(adapter);
++ ret = mwifiex_init_rxq_ring(adapter);
++ if (ret)
++ mwifiex_pcie_delete_rxbd_ring(adapter);
++ return ret;
+ }
+
+ /*
+@@ -1127,6 +1132,7 @@ static int mwifiex_pcie_delete_rxbd_ring(struct mwifiex_adapter *adapter)
+ */
+ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter)
+ {
++ int ret;
+ struct pcie_service_card *card = adapter->card;
+ const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
+
+@@ -1161,7 +1167,10 @@ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter)
+ (u32)((u64)card->evtbd_ring_pbase >> 32),
+ card->evtbd_ring_size);
+
+- return mwifiex_pcie_init_evt_ring(adapter);
++ ret = mwifiex_pcie_init_evt_ring(adapter);
++ if (ret)
++ mwifiex_pcie_delete_evtbd_ring(adapter);
++ return ret;
+ }
+
+ /*
+--
+2.40.1
+
--- /dev/null
+From d4d6a831c366ee6a2d800bfe3a88e820da148605 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Aug 2023 19:07:15 +0300
+Subject: wifi: mwifiex: fix memory leak in mwifiex_histogram_read()
+
+From: Dmitry Antipov <dmantipov@yandex.ru>
+
+[ Upstream commit 9c8fd72a5c2a031cbc680a2990107ecd958ffcdb ]
+
+Always free the zeroed page on return from 'mwifiex_histogram_read()'.
+
+Fixes: cbf6e05527a7 ("mwifiex: add rx histogram statistics support")
+
+Acked-by: Brian Norris <briannorris@chromium.org>
+Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20230802160726.85545-1-dmantipov@yandex.ru
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/marvell/mwifiex/debugfs.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/marvell/mwifiex/debugfs.c b/drivers/net/wireless/marvell/mwifiex/debugfs.c
+index 52b18f4a774b7..0cdd6c50c1c08 100644
+--- a/drivers/net/wireless/marvell/mwifiex/debugfs.c
++++ b/drivers/net/wireless/marvell/mwifiex/debugfs.c
+@@ -253,8 +253,11 @@ mwifiex_histogram_read(struct file *file, char __user *ubuf,
+ if (!p)
+ return -ENOMEM;
+
+- if (!priv || !priv->hist_data)
+- return -EFAULT;
++ if (!priv || !priv->hist_data) {
++ ret = -EFAULT;
++ goto free_and_exit;
++ }
++
+ phist_data = priv->hist_data;
+
+ p += sprintf(p, "\n"
+@@ -309,6 +312,8 @@ mwifiex_histogram_read(struct file *file, char __user *ubuf,
+ ret = simple_read_from_buffer(ubuf, count, ppos, (char *)page,
+ (unsigned long)p - page);
+
++free_and_exit:
++ free_page(page);
+ return ret;
+ }
+
+--
+2.40.1
+
--- /dev/null
+From e2b6609ea1032a7ab824a2761b56df662f016b58 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Aug 2023 08:39:11 +0000
+Subject: wifi: mwifiex: Fix missed return in oob checks failed path
+
+From: Polaris Pi <pinkperfect2021@gmail.com>
+
+[ Upstream commit 2785851c627f2db05f9271f7f63661b5dbd95c4c ]
+
+Add missed return in mwifiex_uap_queue_bridged_pkt() and
+mwifiex_process_rx_packet().
+
+Fixes: 119585281617 ("wifi: mwifiex: Fix OOB and integer underflow when rx packets")
+Signed-off-by: Polaris Pi <pinkperfect2021@gmail.com>
+Reported-by: Dmitry Antipov <dmantipov@yandex.ru>
+Acked-by: Brian Norris <briannorris@chromium.org>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20230810083911.3725248-1-pinkperfect2021@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/marvell/mwifiex/sta_rx.c | 1 +
+ drivers/net/wireless/marvell/mwifiex/uap_txrx.c | 1 +
+ 2 files changed, 2 insertions(+)
+
+diff --git a/drivers/net/wireless/marvell/mwifiex/sta_rx.c b/drivers/net/wireless/marvell/mwifiex/sta_rx.c
+index f2899d53a43f9..65420ad674167 100644
+--- a/drivers/net/wireless/marvell/mwifiex/sta_rx.c
++++ b/drivers/net/wireless/marvell/mwifiex/sta_rx.c
+@@ -92,6 +92,7 @@ int mwifiex_process_rx_packet(struct mwifiex_private *priv,
+ skb->len, rx_pkt_off);
+ priv->stats.rx_dropped++;
+ dev_kfree_skb_any(skb);
++ return -1;
+ }
+
+ if ((!memcmp(&rx_pkt_hdr->rfc1042_hdr, bridge_tunnel_header,
+diff --git a/drivers/net/wireless/marvell/mwifiex/uap_txrx.c b/drivers/net/wireless/marvell/mwifiex/uap_txrx.c
+index 04ff051f5d186..c1b8d41dd7536 100644
+--- a/drivers/net/wireless/marvell/mwifiex/uap_txrx.c
++++ b/drivers/net/wireless/marvell/mwifiex/uap_txrx.c
+@@ -110,6 +110,7 @@ static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv,
+ skb->len, le16_to_cpu(uap_rx_pd->rx_pkt_offset));
+ priv->stats.rx_dropped++;
+ dev_kfree_skb_any(skb);
++ return;
+ }
+
+ if ((!memcmp(&rx_pkt_hdr->rfc1042_hdr, bridge_tunnel_header,
+--
+2.40.1
+
--- /dev/null
+From 168e325ee1a0e225ab53c466175e7151515714d7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 23 Jul 2023 07:07:41 +0000
+Subject: wifi: mwifiex: Fix OOB and integer underflow when rx packets
+
+From: Polaris Pi <pinkperfect2021@gmail.com>
+
+[ Upstream commit 11958528161731c58e105b501ed60b83a91ea941 ]
+
+Make sure mwifiex_process_mgmt_packet,
+mwifiex_process_sta_rx_packet and mwifiex_process_uap_rx_packet,
+mwifiex_uap_queue_bridged_pkt and mwifiex_process_rx_packet
+not out-of-bounds access the skb->data buffer.
+
+Fixes: 2dbaf751b1de ("mwifiex: report received management frames to cfg80211")
+Signed-off-by: Polaris Pi <pinkperfect2021@gmail.com>
+Reviewed-by: Matthew Wang <matthewmwang@chromium.org>
+Reviewed-by: Brian Norris <briannorris@chromium.org>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20230723070741.1544662-1-pinkperfect2021@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/marvell/mwifiex/sta_rx.c | 11 ++++++++++-
+ .../net/wireless/marvell/mwifiex/uap_txrx.c | 19 +++++++++++++++++++
+ drivers/net/wireless/marvell/mwifiex/util.c | 10 +++++++---
+ 3 files changed, 36 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/wireless/marvell/mwifiex/sta_rx.c b/drivers/net/wireless/marvell/mwifiex/sta_rx.c
+index 13659b02ba882..f2899d53a43f9 100644
+--- a/drivers/net/wireless/marvell/mwifiex/sta_rx.c
++++ b/drivers/net/wireless/marvell/mwifiex/sta_rx.c
+@@ -86,6 +86,14 @@ int mwifiex_process_rx_packet(struct mwifiex_private *priv,
+ rx_pkt_len = le16_to_cpu(local_rx_pd->rx_pkt_length);
+ rx_pkt_hdr = (void *)local_rx_pd + rx_pkt_off;
+
++ if (sizeof(*rx_pkt_hdr) + rx_pkt_off > skb->len) {
++ mwifiex_dbg(priv->adapter, ERROR,
++ "wrong rx packet offset: len=%d, rx_pkt_off=%d\n",
++ skb->len, rx_pkt_off);
++ priv->stats.rx_dropped++;
++ dev_kfree_skb_any(skb);
++ }
++
+ if ((!memcmp(&rx_pkt_hdr->rfc1042_hdr, bridge_tunnel_header,
+ sizeof(bridge_tunnel_header))) ||
+ (!memcmp(&rx_pkt_hdr->rfc1042_hdr, rfc1042_header,
+@@ -194,7 +202,8 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_private *priv,
+
+ rx_pkt_hdr = (void *)local_rx_pd + rx_pkt_offset;
+
+- if ((rx_pkt_offset + rx_pkt_length) > (u16) skb->len) {
++ if ((rx_pkt_offset + rx_pkt_length) > skb->len ||
++ sizeof(rx_pkt_hdr->eth803_hdr) + rx_pkt_offset > skb->len) {
+ mwifiex_dbg(adapter, ERROR,
+ "wrong rx packet: len=%d, rx_pkt_offset=%d, rx_pkt_length=%d\n",
+ skb->len, rx_pkt_offset, rx_pkt_length);
+diff --git a/drivers/net/wireless/marvell/mwifiex/uap_txrx.c b/drivers/net/wireless/marvell/mwifiex/uap_txrx.c
+index e495f7eaea033..04ff051f5d186 100644
+--- a/drivers/net/wireless/marvell/mwifiex/uap_txrx.c
++++ b/drivers/net/wireless/marvell/mwifiex/uap_txrx.c
+@@ -103,6 +103,15 @@ static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv,
+ return;
+ }
+
++ if (sizeof(*rx_pkt_hdr) +
++ le16_to_cpu(uap_rx_pd->rx_pkt_offset) > skb->len) {
++ mwifiex_dbg(adapter, ERROR,
++ "wrong rx packet offset: len=%d,rx_pkt_offset=%d\n",
++ skb->len, le16_to_cpu(uap_rx_pd->rx_pkt_offset));
++ priv->stats.rx_dropped++;
++ dev_kfree_skb_any(skb);
++ }
++
+ if ((!memcmp(&rx_pkt_hdr->rfc1042_hdr, bridge_tunnel_header,
+ sizeof(bridge_tunnel_header))) ||
+ (!memcmp(&rx_pkt_hdr->rfc1042_hdr, rfc1042_header,
+@@ -367,6 +376,16 @@ int mwifiex_process_uap_rx_packet(struct mwifiex_private *priv,
+ rx_pkt_type = le16_to_cpu(uap_rx_pd->rx_pkt_type);
+ rx_pkt_hdr = (void *)uap_rx_pd + le16_to_cpu(uap_rx_pd->rx_pkt_offset);
+
++ if (le16_to_cpu(uap_rx_pd->rx_pkt_offset) +
++ sizeof(rx_pkt_hdr->eth803_hdr) > skb->len) {
++ mwifiex_dbg(adapter, ERROR,
++ "wrong rx packet for struct ethhdr: len=%d, offset=%d\n",
++ skb->len, le16_to_cpu(uap_rx_pd->rx_pkt_offset));
++ priv->stats.rx_dropped++;
++ dev_kfree_skb_any(skb);
++ return 0;
++ }
++
+ ether_addr_copy(ta, rx_pkt_hdr->eth803_hdr.h_source);
+
+ if ((le16_to_cpu(uap_rx_pd->rx_pkt_offset) +
+diff --git a/drivers/net/wireless/marvell/mwifiex/util.c b/drivers/net/wireless/marvell/mwifiex/util.c
+index 94c2d219835da..745b1d925b217 100644
+--- a/drivers/net/wireless/marvell/mwifiex/util.c
++++ b/drivers/net/wireless/marvell/mwifiex/util.c
+@@ -393,11 +393,15 @@ mwifiex_process_mgmt_packet(struct mwifiex_private *priv,
+ }
+
+ rx_pd = (struct rxpd *)skb->data;
++ pkt_len = le16_to_cpu(rx_pd->rx_pkt_length);
++ if (pkt_len < sizeof(struct ieee80211_hdr) + sizeof(pkt_len)) {
++ mwifiex_dbg(priv->adapter, ERROR, "invalid rx_pkt_length");
++ return -1;
++ }
+
+ skb_pull(skb, le16_to_cpu(rx_pd->rx_pkt_offset));
+ skb_pull(skb, sizeof(pkt_len));
+-
+- pkt_len = le16_to_cpu(rx_pd->rx_pkt_length);
++ pkt_len -= sizeof(pkt_len);
+
+ ieee_hdr = (void *)skb->data;
+ if (ieee80211_is_mgmt(ieee_hdr->frame_control)) {
+@@ -410,7 +414,7 @@ mwifiex_process_mgmt_packet(struct mwifiex_private *priv,
+ skb->data + sizeof(struct ieee80211_hdr),
+ pkt_len - sizeof(struct ieee80211_hdr));
+
+- pkt_len -= ETH_ALEN + sizeof(pkt_len);
++ pkt_len -= ETH_ALEN;
+ rx_pd->rx_pkt_length = cpu_to_le16(pkt_len);
+
+ cfg80211_rx_mgmt(&priv->wdev, priv->roc_cfg.chan.center_freq,
+--
+2.40.1
+
--- /dev/null
+From 4ab4a7ff85ab243be55e65dd11e02a70c0103b31 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Aug 2023 11:31:51 +0800
+Subject: wifi: nl80211/cfg80211: add forgotten nla_policy for BSS color
+ attribute
+
+From: Lin Ma <linma@zju.edu.cn>
+
+[ Upstream commit 218d690c49b7e9c94ad0d317adbdd4af846ea0dc ]
+
+The previous commit dd3e4fc75b4a ("nl80211/cfg80211: add BSS color to
+NDP ranging parameters") adds a parameter for NDP ranging by introducing
+a new attribute type named NL80211_PMSR_FTM_REQ_ATTR_BSS_COLOR.
+
+However, the author forgot to also describe the nla_policy at
+nl80211_pmsr_ftm_req_attr_policy (net/wireless/nl80211.c). Just
+complement it to avoid malformed attribute that causes out-of-attribute
+access.
+
+Fixes: dd3e4fc75b4a ("nl80211/cfg80211: add BSS color to NDP ranging parameters")
+Signed-off-by: Lin Ma <linma@zju.edu.cn>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://lore.kernel.org/r/20230809033151.768910-1-linma@zju.edu.cn
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/nl80211.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index 1b688745ce0a1..be798ce8a20ff 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -323,6 +323,7 @@ nl80211_pmsr_ftm_req_attr_policy[NL80211_PMSR_FTM_REQ_ATTR_MAX + 1] = {
+ [NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED] = { .type = NLA_FLAG },
+ [NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED] = { .type = NLA_FLAG },
+ [NL80211_PMSR_FTM_REQ_ATTR_LMR_FEEDBACK] = { .type = NLA_FLAG },
++ [NL80211_PMSR_FTM_REQ_ATTR_BSS_COLOR] = { .type = NLA_U8 },
+ };
+
+ static const struct nla_policy
+--
+2.40.1
+
--- /dev/null
+From f95e1824624217cf82d348617acf522cb3ecc2a2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Aug 2023 19:01:50 +0800
+Subject: wifi: rtw89: 8852b: rfk: fine tune IQK parameters to improve
+ performance on 2GHz band
+
+From: Ping-Ke Shih <pkshih@realtek.com>
+
+[ Upstream commit b3bfc4fb1edc8136396ece2d7204c2ee5cae188d ]
+
+A few samples get bad performance on 2GHz band, so use proper IQK command
+code and select another group to have wider range of calibration value.
+
+Fixes: f2abe804e823 ("wifi: rtw89: 8852b: rfk: add IQK")
+Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20230803110150.8457-1-pkshih@realtek.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c
+index 722ae34b09c1f..b6fccb1cb7a5c 100644
+--- a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c
++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c
+@@ -846,7 +846,7 @@ static bool _iqk_one_shot(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+ case ID_NBTXK:
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x011);
+- iqk_cmd = 0x308 | (1 << (4 + path));
++ iqk_cmd = 0x408 | (1 << (4 + path));
+ break;
+ case ID_NBRXK:
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1);
+@@ -1078,7 +1078,7 @@ static bool _iqk_nbtxk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8
+ {
+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
+ bool kfail;
+- u8 gp = 0x3;
++ u8 gp = 0x2;
+
+ switch (iqk_info->iqk_band[path]) {
+ case RTW89_BAND_2G:
+--
+2.40.1
+
--- /dev/null
+From 100f61910127a76dda32c1125f0aa7871ffb7113 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 15 Jul 2023 21:42:57 +0800
+Subject: wifi: rtw89: debug: Fix error handling in
+ rtw89_debug_priv_btc_manual_set()
+
+From: Zhang Shurong <zhang_shurong@foxmail.com>
+
+[ Upstream commit 59b4cc439f184c5eaa34161ec67af1e16ffabed4 ]
+
+If there is a failure during kstrtobool_from_user()
+rtw89_debug_priv_btc_manual_set should return a negative error code
+instead of returning the count directly.
+
+Fix this bug by returning an error code instead of a count after
+a failed call of the function "kstrtobool_from_user". Moreover
+I omitted the label "out" with this source code correction.
+
+Fixes: e3ec7017f6a2 ("rtw89: add Realtek 802.11ax driver")
+Signed-off-by: Zhang Shurong <zhang_shurong@foxmail.com>
+Acked-by: Ping-Ke Shih <pkshih@realtek.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/tencent_1C09B99BD7DA9CAD18B00C8F0F050F540607@qq.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtw89/debug.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c
+index 858494ddfb12e..9bb09fdf931ab 100644
+--- a/drivers/net/wireless/realtek/rtw89/debug.c
++++ b/drivers/net/wireless/realtek/rtw89/debug.c
+@@ -3165,12 +3165,14 @@ static ssize_t rtw89_debug_priv_btc_manual_set(struct file *filp,
+ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
+ struct rtw89_btc *btc = &rtwdev->btc;
+ bool btc_manual;
++ int ret;
+
+- if (kstrtobool_from_user(user_buf, count, &btc_manual))
+- goto out;
++ ret = kstrtobool_from_user(user_buf, count, &btc_manual);
++ if (ret)
++ return ret;
+
+ btc->ctrl.manual = btc_manual;
+-out:
++
+ return count;
+ }
+
+--
+2.40.1
+
--- /dev/null
+From 5b180a30ba8223e1342461e719dd478045245494 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Jul 2023 13:39:27 -0500
+Subject: wifi: rtw89: Fix loading of compressed firmware
+
+From: Larry Finger <Larry.Finger@lwfinger.net>
+
+[ Upstream commit 942999c48cb382feb53c6da7679a994c97963836 ]
+
+When using compressed firmware, the early firmware load feature will fail.
+In most cases, the only downside is that if a device has more than one
+firmware version available, only the last one listed will be loaded.
+In at least two cases, there is no firmware loaded, and the device fails
+initialization. See https://github.com/lwfinger/rtw89/issues/259 and
+https://bugzilla.opensuse.org/show_bug.cgi?id=1212808 for examples of
+the failure.
+
+When firmware_class.dyndbg=+p" added to the kernel boot parameters, the
+following is found:
+
+finger@localhost:~/rtw89>sudo dmesg -t | grep rtw89
+firmware_class: __allocate_fw_priv: fw-rtw89/rtw8852b_fw-1.bin fw_priv=00000000638862fb
+rtw89_8852be 0000:02:00.0: loading /lib/firmware/updates/5.14.21-150500.53-default/rtw89/rtw8852b_fw-1.bin failed for no such file or directory.
+rtw89_8852be 0000:02:00.0: loading /lib/firmware/updates/rtw89/rtw8852b_fw-1.bin failed for no such file or directory.
+rtw89_8852be 0000:02:00.0: loading /lib/firmware/5.14.21-150500.53-default/rtw89/rtw8852b_fw-1.bin failed for no such file or directory.
+rtw89_8852be 0000:02:00.0: loading /lib/firmware/rtw89/rtw8852b_fw-1.bin failed for no such file or directory.
+rtw89_8852be 0000:02:00.0: Direct firmware load for rtw89/rtw8852b_fw-1.bin failed with error -2
+firmware_class: __free_fw_priv: fw-rtw89/rtw8852b_fw-1.bin fw_priv=00000000638862fb data=00000000307c30c7 size=0
+firmware_class: __allocate_fw_priv: fw-rtw89/rtw8852b_fw.bin fw_priv=00000000638862fb
+rtw89_8852be 0000:02:00.0: loading /lib/firmware/updates/5.14.21-150500.53-default/rtw89/rtw8852b_fw.bin failed for no such file or directory.
+rtw89_8852be 0000:02:00.0: loading /lib/firmware/updates/rtw89/rtw8852b_fw.bin failed for no such file or directory.
+rtw89_8852be 0000:02:00.0: loading /lib/firmware/5.14.21-150500.53-default/rtw89/rtw8852b_fw.bin failed for no such file or directory.
+rtw89_8852be 0000:02:00.0: loading /lib/firmware/rtw89/rtw8852b_fw.bin failed for no such file or directory.
+rtw89_8852be 0000:02:00.0: Direct firmware load for rtw89/rtw8852b_fw.bin failed with error -2
+firmware_class: __free_fw_priv: fw-rtw89/rtw8852b_fw.bin fw_priv=00000000638862fb data=00000000307c30c7 size=0
+rtw89_8852be 0000:02:00.0: failed to early request firmware: -2
+firmware_class: __allocate_fw_priv: fw-rtw89/rtw8852b_fw.bin fw_priv=00000000638862fb
+rtw89_8852be 0000:02:00.0: loading /lib/firmware/updates/5.14.21-150500.53-default/rtw89/rtw8852b_fw.bin failed for no such file or directory.
+rtw89_8852be 0000:02:00.0: loading /lib/firmware/updates/rtw89/rtw8852b_fw.bin failed for no such file or directory.
+rtw89_8852be 0000:02:00.0: loading /lib/firmware/5.14.21-150500.53-default/rtw89/rtw8852b_fw.bin failed for no such file or directory.
+rtw89_8852be 0000:02:00.0: loading /lib/firmware/rtw89/rtw8852b_fw.bin failed for no such file or directory.
+rtw89_8852be 0000:02:00.0: loading /lib/firmware/updates/5.14.21-150500.53-default/rtw89/rtw8852b_fw.bin.xz failed for no such file or directory.
+rtw89_8852be 0000:02:00.0: loading /lib/firmware/updates/rtw89/rtw8852b_fw.bin.xz failed for no such file or directory.
+rtw89_8852be 0000:02:00.0: loading /lib/firmware/5.14.21-150500.53-default/rtw89/rtw8852b_fw.bin.xz failed for no such file or directory.
+rtw89_8852be 0000:02:00.0: Loading firmware from /lib/firmware/rtw89/rtw8852b_fw.bin.xz
+rtw89_8852be 0000:02:00.0: f/w decompressing rtw89/rtw8852b_fw.bin
+firmware_class: fw_set_page_data: fw-rtw89/rtw8852b_fw.bin fw_priv=00000000638862fb data=000000004ed6c2f7 size=1035232
+rtw89_8852be 0000:02:00.0: Firmware version 0.27.32.1, cmd version 0, type 1
+rtw89_8852be 0000:02:00.0: Firmware version 0.27.32.1, cmd version 0, type 3
+
+The key is that firmware version 0.27.32.1 is loaded.
+
+With this patch, the following is obtained:
+
+firmware_class: __free_fw_priv: fw-rtw89/rtw8852b_fw.bin fw_priv=000000000849addc data=00000000fd3cabe2 size=1035232
+firmware_class: fw_name_devm_release: fw_name-rtw89/rtw8852b_fw.bin devm-000000002d8c3343 released
+firmware_class: __allocate_fw_priv: fw-rtw89/rtw8852b_fw-1.bin fw_priv=000000009e1a6364
+rtw89_8852be 0000:02:00.0: loading /lib/firmware/updates/6.4.3-1-default/rtw89/rtw8852b_fw-1.bin failed for no such file or directory.
+rtw89_8852be 0000:02:00.0: loading /lib/firmware/updates/rtw89/rtw8852b_fw-1.bin failed for no such file or directory.
+rtw89_8852be 0000:02:00.0: loading /lib/firmware/6.4.3-1-default/rtw89/rtw8852b_fw-1.bin failed for no such file or directory.
+rtw89_8852be 0000:02:00.0: loading /lib/firmware/rtw89/rtw8852b_fw-1.bin failed for no such file or directory.
+rtw89_8852be 0000:02:00.0: loading /lib/firmware/updates/6.4.3-1-default/rtw89/rtw8852b_fw-1.bin.zst failed for no such file or directory.
+rtw89_8852be 0000:02:00.0: loading /lib/firmware/updates/rtw89/rtw8852b_fw-1.bin.zst failed for no such file or directory.
+rtw89_8852be 0000:02:00.0: loading /lib/firmware/6.4.3-1-default/rtw89/rtw8852b_fw-1.bin.zst failed for no such file or directory.
+rtw89_8852be 0000:02:00.0: loading /lib/firmware/rtw89/rtw8852b_fw-1.bin.zst failed for no such file or directory.
+rtw89_8852be 0000:02:00.0: loading /lib/firmware/updates/6.4.3-1-default/rtw89/rtw8852b_fw-1.bin.xz failed for no such file or directory.
+rtw89_8852be 0000:02:00.0: loading /lib/firmware/updates/rtw89/rtw8852b_fw-1.bin.xz failed for no such file or directory.
+rtw89_8852be 0000:02:00.0: loading /lib/firmware/6.4.3-1-default/rtw89/rtw8852b_fw-1.bin.xz failed for no such file or directory.
+rtw89_8852be 0000:02:00.0: Loading firmware from /lib/firmware/rtw89/rtw8852b_fw-1.bin.xz
+rtw89_8852be 0000:02:00.0: f/w decompressing rtw89/rtw8852b_fw-1.bin
+firmware_class: fw_set_page_data: fw-rtw89/rtw8852b_fw-1.bin fw_priv=000000009e1a6364 data=00000000fd3cabe2 size=1184992
+rtw89_8852be 0000:02:00.0: Loaded FW: rtw89/rtw8852b_fw-1.bin, sha256: 8539efc75f513f4585cf0cd6e79e6507da47fce87225f2d0de391a03aefe9ac8
+rtw89_8852be 0000:02:00.0: loaded firmware rtw89/rtw8852b_fw-1.bin
+rtw89_8852be 0000:02:00.0: Firmware version 0.29.29.1, cmd version 0, type 5
+rtw89_8852be 0000:02:00.0: Firmware version 0.29.29.1, cmd version 0, type 3
+
+Now, version 0.29.29.1 is loaded.
+
+Fixes: ffde7f3476a6 ("wifi: rtw89: add firmware format version to backward compatible with older drivers")
+Cc: Ping-Ke Shih <pkshih@realtek.com>
+Cc: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20230724183927.28553-1-Larry.Finger@lwfinger.net
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtw89/fw.c | 27 +++----------------------
+ 1 file changed, 3 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
+index b9b675bf9d050..60b201b24332f 100644
+--- a/drivers/net/wireless/realtek/rtw89/fw.c
++++ b/drivers/net/wireless/realtek/rtw89/fw.c
+@@ -305,31 +305,17 @@ rtw89_early_fw_feature_recognize(struct device *device,
+ struct rtw89_fw_info *early_fw,
+ int *used_fw_format)
+ {
+- union rtw89_compat_fw_hdr buf = {};
+ const struct firmware *firmware;
+- bool full_req = false;
+ char fw_name[64];
+ int fw_format;
+ u32 ver_code;
+ int ret;
+
+- /* If SECURITY_LOADPIN_ENFORCE is enabled, reading partial files will
+- * be denied (-EPERM). Then, we don't get right firmware things as
+- * expected. So, in this case, we have to request full firmware here.
+- */
+- if (IS_ENABLED(CONFIG_SECURITY_LOADPIN_ENFORCE))
+- full_req = true;
+-
+ for (fw_format = chip->fw_format_max; fw_format >= 0; fw_format--) {
+ rtw89_fw_get_filename(fw_name, sizeof(fw_name),
+ chip->fw_basename, fw_format);
+
+- if (full_req)
+- ret = request_firmware(&firmware, fw_name, device);
+- else
+- ret = request_partial_firmware_into_buf(&firmware, fw_name,
+- device, &buf, sizeof(buf),
+- 0);
++ ret = request_firmware(&firmware, fw_name, device);
+ if (!ret) {
+ dev_info(device, "loaded firmware %s\n", fw_name);
+ *used_fw_format = fw_format;
+@@ -342,10 +328,7 @@ rtw89_early_fw_feature_recognize(struct device *device,
+ return NULL;
+ }
+
+- if (full_req)
+- ver_code = rtw89_compat_fw_hdr_ver_code(firmware->data);
+- else
+- ver_code = rtw89_compat_fw_hdr_ver_code(&buf);
++ ver_code = rtw89_compat_fw_hdr_ver_code(firmware->data);
+
+ if (!ver_code)
+ goto out;
+@@ -353,11 +336,7 @@ rtw89_early_fw_feature_recognize(struct device *device,
+ rtw89_fw_iterate_feature_cfg(early_fw, chip, ver_code);
+
+ out:
+- if (full_req)
+- return firmware;
+-
+- release_firmware(firmware);
+- return NULL;
++ return firmware;
+ }
+
+ int rtw89_fw_recognize(struct rtw89_dev *rtwdev)
+--
+2.40.1
+
--- /dev/null
+From d25f2b91e8eefe99401d5a039b1f064d318587bb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Jul 2023 18:11:20 -0700
+Subject: x86/APM: drop the duplicate APM_MINOR_DEV macro
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit 4ba2909638a29630a346d6c4907a3105409bee7d ]
+
+This source file already includes <linux/miscdevice.h>, which contains
+the same macro. It doesn't need to be defined here again.
+
+Fixes: 874bcd00f520 ("apm-emulation: move APM_MINOR_DEV to include/linux/miscdevice.h")
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Cc: Jiri Kosina <jikos@kernel.org>
+Cc: x86@kernel.org
+Cc: Sohil Mehta <sohil.mehta@intel.com>
+Cc: Corentin Labbe <clabbe.montjoie@gmail.com>
+Reviewed-by: Sohil Mehta <sohil.mehta@intel.com>
+Link: https://lore.kernel.org/r/20230728011120.759-1-rdunlap@infradead.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/apm_32.c | 6 ------
+ 1 file changed, 6 deletions(-)
+
+diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c
+index c6c15ce1952fb..5934ee5bc087e 100644
+--- a/arch/x86/kernel/apm_32.c
++++ b/arch/x86/kernel/apm_32.c
+@@ -238,12 +238,6 @@
+ extern int (*console_blank_hook)(int);
+ #endif
+
+-/*
+- * The apm_bios device is one of the misc char devices.
+- * This is its minor number.
+- */
+-#define APM_MINOR_DEV 134
+-
+ /*
+ * Various options can be changed at boot time as follows:
+ * (We allow underscores for compatibility with the modules code)
+--
+2.40.1
+
--- /dev/null
+From 8426527f49d3c34d2d7958ccc9ea7f5a21daeca3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Aug 2023 18:26:58 +0200
+Subject: x86/decompressor: Don't rely on upper 32 bits of GPRs being preserved
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ard Biesheuvel <ardb@kernel.org>
+
+[ Upstream commit 264b82fdb4989cf6a44a2bcd0c6ea05e8026b2ac ]
+
+The 4-to-5 level mode switch trampoline disables long mode and paging in
+order to be able to flick the LA57 bit. According to section 3.4.1.1 of
+the x86 architecture manual [0], 64-bit GPRs might not retain the upper
+32 bits of their contents across such a mode switch.
+
+Given that RBP, RBX and RSI are live at this point, preserve them on the
+stack, along with the return address that might be above 4G as well.
+
+[0] Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1: Basic Architecture
+
+ "Because the upper 32 bits of 64-bit general-purpose registers are
+ undefined in 32-bit modes, the upper 32 bits of any general-purpose
+ register are not preserved when switching from 64-bit mode to a 32-bit
+ mode (to protected mode or compatibility mode). Software must not
+ depend on these bits to maintain a value after a 64-bit to 32-bit
+ mode switch."
+
+Fixes: 194a9749c73d650c ("x86/boot/compressed/64: Handle 5-level paging boot if kernel is above 4G")
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Link: https://lore.kernel.org/r/20230807162720.545787-2-ardb@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/boot/compressed/head_64.S | 30 +++++++++++++++++++++++-------
+ 1 file changed, 23 insertions(+), 7 deletions(-)
+
+diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S
+index 03c4328a88cbd..f732426d3b483 100644
+--- a/arch/x86/boot/compressed/head_64.S
++++ b/arch/x86/boot/compressed/head_64.S
+@@ -459,11 +459,25 @@ SYM_CODE_START(startup_64)
+ /* Save the trampoline address in RCX */
+ movq %rax, %rcx
+
++ /* Set up 32-bit addressable stack */
++ leaq TRAMPOLINE_32BIT_STACK_END(%rcx), %rsp
++
++ /*
++ * Preserve live 64-bit registers on the stack: this is necessary
++ * because the architecture does not guarantee that GPRs will retain
++ * their full 64-bit values across a 32-bit mode switch.
++ */
++ pushq %rbp
++ pushq %rbx
++ pushq %rsi
++
+ /*
+- * Load the address of trampoline_return() into RDI.
+- * It will be used by the trampoline to return to the main code.
++ * Push the 64-bit address of trampoline_return() onto the new stack.
++ * It will be used by the trampoline to return to the main code. Due to
++ * the 32-bit mode switch, it cannot be kept it in a register either.
+ */
+ leaq trampoline_return(%rip), %rdi
++ pushq %rdi
+
+ /* Switch to compatibility mode (CS.L = 0 CS.D = 1) via far return */
+ pushq $__KERNEL32_CS
+@@ -471,6 +485,11 @@ SYM_CODE_START(startup_64)
+ pushq %rax
+ lretq
+ trampoline_return:
++ /* Restore live 64-bit registers */
++ popq %rsi
++ popq %rbx
++ popq %rbp
++
+ /* Restore the stack, the 32-bit trampoline uses its own stack */
+ leaq rva(boot_stack_end)(%rbx), %rsp
+
+@@ -582,7 +601,7 @@ SYM_FUNC_END(.Lrelocated)
+ /*
+ * This is the 32-bit trampoline that will be copied over to low memory.
+ *
+- * RDI contains the return address (might be above 4G).
++ * Return address is at the top of the stack (might be above 4G).
+ * ECX contains the base address of the trampoline memory.
+ * Non zero RDX means trampoline needs to enable 5-level paging.
+ */
+@@ -592,9 +611,6 @@ SYM_CODE_START(trampoline_32bit_src)
+ movl %eax, %ds
+ movl %eax, %ss
+
+- /* Set up new stack */
+- leal TRAMPOLINE_32BIT_STACK_END(%ecx), %esp
+-
+ /* Disable paging */
+ movl %cr0, %eax
+ btrl $X86_CR0_PG_BIT, %eax
+@@ -671,7 +687,7 @@ SYM_CODE_END(trampoline_32bit_src)
+ .code64
+ SYM_FUNC_START_LOCAL_NOALIGN(.Lpaging_enabled)
+ /* Return from the trampoline */
+- jmp *%rdi
++ retq
+ SYM_FUNC_END(.Lpaging_enabled)
+
+ /*
+--
+2.40.1
+
--- /dev/null
+From 8accdb77529a68614000ccbb056ffb287e6bc3d5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Aug 2023 17:51:58 -0400
+Subject: x86/efistub: Fix PCI ROM preservation in mixed mode
+
+From: Mikel Rychliski <mikel@mikelr.com>
+
+[ Upstream commit 8b94da92559f7e403dc7ab81937cc50f949ee2fd ]
+
+preserve_pci_rom_image() was accessing the romsize field in
+efi_pci_io_protocol_t directly instead of using the efi_table_attr()
+helper. This prevents the ROM image from being saved correctly during a
+mixed mode boot.
+
+Fixes: 2c3625cb9fa2 ("efi/x86: Fold __setup_efi_pci32() and __setup_efi_pci64() into one function")
+Signed-off-by: Mikel Rychliski <mikel@mikelr.com>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/efi/libstub/x86-stub.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/firmware/efi/libstub/x86-stub.c b/drivers/firmware/efi/libstub/x86-stub.c
+index a0bfd31358ba9..9ae0d6d0c285f 100644
+--- a/drivers/firmware/efi/libstub/x86-stub.c
++++ b/drivers/firmware/efi/libstub/x86-stub.c
+@@ -61,7 +61,7 @@ preserve_pci_rom_image(efi_pci_io_protocol_t *pci, struct pci_setup_rom **__rom)
+ rom->data.type = SETUP_PCI;
+ rom->data.len = size - sizeof(struct setup_data);
+ rom->data.next = 0;
+- rom->pcilen = pci->romsize;
++ rom->pcilen = romsize;
+ *__rom = rom;
+
+ status = efi_call_proto(pci, pci.read, EfiPciIoWidthUint16,
+--
+2.40.1
+
--- /dev/null
+From 53a7fcb76d668493ac6a378d5129059eb2b406e6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Jul 2023 09:36:14 +0200
+Subject: x86/mm: Fix PAT bit missing from page protection modify mask
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Janusz Krzysztofik <janusz.krzysztofik@linux.intel.com>
+
+[ Upstream commit 548cb932051fb6232ac983ed6673dae7bdf3cf4c ]
+
+Visible glitches have been observed when running graphics applications on
+Linux under Xen hypervisor. Those observations have been confirmed with
+failures from kms_pwrite_crc Intel GPU test that verifies data coherency
+of DRM frame buffer objects using hardware CRC checksums calculated by
+display controllers, exposed to userspace via debugfs. Affected
+processing paths have then been identified with new IGT test variants that
+mmap the objects using different methods and caching modes [1].
+
+When running as a Xen PV guest, Linux uses Xen provided PAT configuration
+which is different from its native one. In particular, Xen specific PTE
+encoding of write-combining caching, likely used by graphics applications,
+differs from the Linux default one found among statically defined minimal
+set of supported modes. Since Xen defines PTE encoding of the WC mode as
+_PAGE_PAT, it no longer belongs to the minimal set, depends on correct
+handling of _PAGE_PAT bit, and can be mismatched with write-back caching.
+
+When a user calls mmap() for a DRM buffer object, DRM device specific
+.mmap file operation, called from mmap_region(), takes care of setting PTE
+encoding bits in a vm_page_prot field of an associated virtual memory area
+structure. Unfortunately, _PAGE_PAT bit is not preserved when the vma's
+.vm_flags are then applied to .vm_page_prot via vm_set_page_prot(). Bits
+to be preserved are determined with _PAGE_CHG_MASK symbol that doesn't
+cover _PAGE_PAT. As a consequence, WB caching is requested instead of WC
+when running under Xen (also, WP is silently changed to WT, and UC
+downgraded to UC_MINUS). When running on bare metal, WC is not affected,
+but WP and WT extra modes are unintentionally replaced with WC and UC,
+respectively.
+
+WP and WT modes, encoded with _PAGE_PAT bit set, were introduced by commit
+281d4078bec3 ("x86: Make page cache mode a real type"). Care was taken
+to extend _PAGE_CACHE_MASK symbol with that additional bit, but that
+symbol has never been used for identification of bits preserved when
+applying page protection flags. Support for all cache modes under Xen,
+including the problematic WC mode, was then introduced by commit
+47591df50512 ("xen: Support Xen pv-domains using PAT").
+
+The issue needs to be fixed by including _PAGE_PAT bit into a bitmask used
+by pgprot_modify() for selecting bits to be preserved. We can do that
+either internally to pgprot_modify() (as initially proposed), or by making
+_PAGE_PAT a part of _PAGE_CHG_MASK. If we go for the latter then, since
+_PAGE_PAT is the same as _PAGE_PSE, we need to note that _HPAGE_CHG_MASK
+-- a huge pmds' counterpart of _PAGE_CHG_MASK, introduced by commit
+c489f1257b8c ("thp: add pmd_modify"), defined as (_PAGE_CHG_MASK |
+_PAGE_PSE) -- will no longer differ from _PAGE_CHG_MASK. If such
+modification of _PAGE_CHG_MASK was irrelevant to its users then one might
+wonder why that new _HPAGE_CHG_MASK symbol was introduced instead of
+reusing the existing one with that otherwise irrelevant bit (_PAGE_PSE in
+that case) added.
+
+Add _PAGE_PAT to _PAGE_CHG_MASK and _PAGE_PAT_LARGE to _HPAGE_CHG_MASK for
+symmetry. Split out common bits from both symbols to a common symbol for
+clarity.
+
+[ dhansen: tweak the solution changelog description ]
+
+[1] https://gitlab.freedesktop.org/drm/igt-gpu-tools/-/commit/0f0754413f14
+
+Fixes: 281d4078bec3 ("x86: Make page cache mode a real type")
+Signed-off-by: Janusz Krzysztofik <janusz.krzysztofik@linux.intel.com>
+Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
+Reviewed-by: Andi Shyti <andi.shyti@linux.intel.com>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Tested-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
+Link: https://gitlab.freedesktop.org/drm/intel/-/issues/7648
+Link: https://lore.kernel.org/all/20230710073613.8006-2-janusz.krzysztofik%40linux.intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/include/asm/pgtable_types.h | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h
+index 447d4bee25c48..97533e6b1c61b 100644
+--- a/arch/x86/include/asm/pgtable_types.h
++++ b/arch/x86/include/asm/pgtable_types.h
+@@ -125,11 +125,12 @@
+ * instance, and is *not* included in this mask since
+ * pte_modify() does modify it.
+ */
+-#define _PAGE_CHG_MASK (PTE_PFN_MASK | _PAGE_PCD | _PAGE_PWT | \
+- _PAGE_SPECIAL | _PAGE_ACCESSED | _PAGE_DIRTY | \
+- _PAGE_SOFT_DIRTY | _PAGE_DEVMAP | _PAGE_ENC | \
+- _PAGE_UFFD_WP)
+-#define _HPAGE_CHG_MASK (_PAGE_CHG_MASK | _PAGE_PSE)
++#define _COMMON_PAGE_CHG_MASK (PTE_PFN_MASK | _PAGE_PCD | _PAGE_PWT | \
++ _PAGE_SPECIAL | _PAGE_ACCESSED | _PAGE_DIRTY |\
++ _PAGE_SOFT_DIRTY | _PAGE_DEVMAP | _PAGE_ENC | \
++ _PAGE_UFFD_WP)
++#define _PAGE_CHG_MASK (_COMMON_PAGE_CHG_MASK | _PAGE_PAT)
++#define _HPAGE_CHG_MASK (_COMMON_PAGE_CHG_MASK | _PAGE_PSE | _PAGE_PAT_LARGE)
+
+ /*
+ * The cache modes defined here are used to translate between pure SW usage
+--
+2.40.1
+
--- /dev/null
+From 55a105104ed36a6b65190dd1dbcd94ca9cca8e4e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Aug 2023 08:07:25 -0700
+Subject: x86/speculation: Mark all Skylake CPUs as vulnerable to GDS
+
+From: Dave Hansen <dave.hansen@linux.intel.com>
+
+[ Upstream commit c9f4c45c8ec3f07f4f083f9750032a1ec3eab6b2 ]
+
+The Gather Data Sampling (GDS) vulnerability is common to all Skylake
+processors. However, the "client" Skylakes* are now in this list:
+
+ https://www.intel.com/content/www/us/en/support/articles/000022396/processors.html
+
+which means they are no longer included for new vulnerabilities here:
+
+ https://www.intel.com/content/www/us/en/developer/topic-technology/software-security-guidance/processors-affected-consolidated-product-cpu-model.html
+
+or in other GDS documentation. Thus, they were not included in the
+original GDS mitigation patches.
+
+Mark SKYLAKE and SKYLAKE_L as vulnerable to GDS to match all the
+other Skylake CPUs (which include Kaby Lake). Also group the CPUs
+so that the ones that share the exact same vulnerabilities are next
+to each other.
+
+Last, move SRBDS to the end of each line. This makes it clear at a
+glance that SKYLAKE_X is unique. Of the five Skylakes, it is the
+only "server" CPU and has a different implementation from the
+clients of the "special register" hardware, making it immune to SRBDS.
+
+This makes the diff much harder to read, but the resulting table is
+worth it.
+
+I very much appreciate the report from Michael Zhivich about this
+issue. Despite what level of support a hardware vendor is providing,
+the kernel very much needs an accurate and up-to-date list of
+vulnerable CPUs. More reports like this are very welcome.
+
+* Client Skylakes are CPUID 406E3/506E3 which is family 6, models
+ 0x4E and 0x5E, aka INTEL_FAM6_SKYLAKE and INTEL_FAM6_SKYLAKE_L.
+
+Reported-by: Michael Zhivich <mzhivich@akamai.com>
+Fixes: 8974eb588283 ("x86/speculation: Add Gather Data Sampling mitigation")
+Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Reviewed-by: Daniel Sneddon <daniel.sneddon@linux.intel.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/cpu/common.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
+index 19c74e68c0a21..aa26c2bb70259 100644
+--- a/arch/x86/kernel/cpu/common.c
++++ b/arch/x86/kernel/cpu/common.c
+@@ -1282,11 +1282,11 @@ static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = {
+ VULNBL_INTEL_STEPPINGS(BROADWELL_G, X86_STEPPING_ANY, SRBDS),
+ VULNBL_INTEL_STEPPINGS(BROADWELL_X, X86_STEPPING_ANY, MMIO),
+ VULNBL_INTEL_STEPPINGS(BROADWELL, X86_STEPPING_ANY, SRBDS),
+- VULNBL_INTEL_STEPPINGS(SKYLAKE_L, X86_STEPPING_ANY, SRBDS | MMIO | RETBLEED),
+ VULNBL_INTEL_STEPPINGS(SKYLAKE_X, X86_STEPPING_ANY, MMIO | RETBLEED | GDS),
+- VULNBL_INTEL_STEPPINGS(SKYLAKE, X86_STEPPING_ANY, SRBDS | MMIO | RETBLEED),
+- VULNBL_INTEL_STEPPINGS(KABYLAKE_L, X86_STEPPING_ANY, SRBDS | MMIO | RETBLEED | GDS),
+- VULNBL_INTEL_STEPPINGS(KABYLAKE, X86_STEPPING_ANY, SRBDS | MMIO | RETBLEED | GDS),
++ VULNBL_INTEL_STEPPINGS(SKYLAKE_L, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | SRBDS),
++ VULNBL_INTEL_STEPPINGS(SKYLAKE, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | SRBDS),
++ VULNBL_INTEL_STEPPINGS(KABYLAKE_L, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | SRBDS),
++ VULNBL_INTEL_STEPPINGS(KABYLAKE, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | SRBDS),
+ VULNBL_INTEL_STEPPINGS(CANNONLAKE_L, X86_STEPPING_ANY, RETBLEED),
+ VULNBL_INTEL_STEPPINGS(ICELAKE_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED | GDS),
+ VULNBL_INTEL_STEPPINGS(ICELAKE_D, X86_STEPPING_ANY, MMIO | GDS),
+--
+2.40.1
+