--- /dev/null
+From 63b22fe4f3d54cfd4f127da128872280cc418f32 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 14 Jan 2023 09:50:50 +0100
+Subject: ACPI: battery: Fix missing NUL-termination with large strings
+
+From: Armin Wolf <W_Armin@gmx.de>
+
+[ Upstream commit f2ac14b5f197e4a2dec51e5ceaa56682ff1592bc ]
+
+When encountering a string bigger than the destination buffer (32 bytes),
+the string is not properly NUL-terminated, causing buffer overreads later.
+
+This for example happens on the Inspiron 3505, where the battery
+model name is larger than 32 bytes, which leads to sysfs showing
+the model name together with the serial number string (which is
+NUL-terminated and thus prevents worse).
+
+Fix this by using strscpy() which ensures that the result is
+always NUL-terminated.
+
+Fixes: 106449e870b3 ("ACPI: Battery: Allow extract string from integer")
+Signed-off-by: Armin Wolf <W_Armin@gmx.de>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/battery.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
+index be743d177bcbf..8b43efe97da5d 100644
+--- a/drivers/acpi/battery.c
++++ b/drivers/acpi/battery.c
+@@ -454,7 +454,7 @@ static int extract_package(struct acpi_battery *battery,
+ u8 *ptr = (u8 *)battery + offsets[i].offset;
+ if (element->type == ACPI_TYPE_STRING ||
+ element->type == ACPI_TYPE_BUFFER)
+- strncpy(ptr, element->string.pointer, 32);
++ strscpy(ptr, element->string.pointer, 32);
+ else if (element->type == ACPI_TYPE_INTEGER) {
+ strncpy(ptr, (u8 *)&element->integer.value,
+ sizeof(u64));
+--
+2.39.2
+
--- /dev/null
+From b915eba18fa120aa7a10f140a949a4d6ac0709a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 23 Jan 2023 13:45:58 +0000
+Subject: ACPI: Don't build ACPICA with '-Os'
+
+From: Mark Rutland <mark.rutland@arm.com>
+
+[ Upstream commit 8f9e0a52810dd83406c768972d022c37e7a18f1f ]
+
+The ACPICA code has been built with '-Os' since the beginning of git
+history, though there's no explanatory comment as to why.
+
+This is unfortunate as GCC drops the alignment specificed by
+'-falign-functions=N' when '-Os' is used, as reported in GCC bug 88345:
+
+ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88345
+
+This prevents CONFIG_FUNCTION_ALIGNMENT and
+CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B from having their expected effect
+on the ACPICA code. This is doubly unfortunate as in subsequent patches
+arm64 will depend upon CONFIG_FUNCTION_ALIGNMENT for its ftrace
+implementation.
+
+Drop the '-Os' flag when building the ACPICA code. With this removed,
+the code builds cleanly and works correctly in testing so far.
+
+I've tested this by selecting CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B=y,
+building and booting a kernel using ACPI, and looking for misaligned
+text symbols:
+
+* arm64:
+
+ Before, v6.2-rc3:
+ # uname -rm
+ 6.2.0-rc3 aarch64
+ # grep ' [Tt] ' /proc/kallsyms | grep -iv '[048c]0 [Tt] ' | wc -l
+ 5009
+
+ Before, v6.2-rc3 + fixed __cold:
+ # uname -rm
+ 6.2.0-rc3-00001-g2a2bedf8bfa9 aarch64
+ # grep ' [Tt] ' /proc/kallsyms | grep -iv '[048c]0 [Tt] ' | wc -l
+ 919
+
+ After:
+ # uname -rm
+ 6.2.0-rc3-00002-g267bddc38572 aarch64
+ # grep ' [Tt] ' /proc/kallsyms | grep -iv '[048c]0 [Tt] ' | wc -l
+ 323
+ # grep ' [Tt] ' /proc/kallsyms | grep -iv '[048c]0 [Tt] ' | grep acpi | wc -l
+ 0
+
+* x86_64:
+
+ Before, v6.2-rc3:
+ # uname -rm
+ 6.2.0-rc3 x86_64
+ # grep ' [Tt] ' /proc/kallsyms | grep -iv '[048c]0 [Tt] ' | wc -l
+ 11537
+
+ Before, v6.2-rc3 + fixed __cold:
+ # uname -rm
+ 6.2.0-rc3-00001-g2a2bedf8bfa9 x86_64
+ # grep ' [Tt] ' /proc/kallsyms | grep -iv '[048c]0 [Tt] ' | wc -l
+ 2805
+
+ After:
+ # uname -rm
+ 6.2.0-rc3-00002-g267bddc38572 x86_64
+ # grep ' [Tt] ' /proc/kallsyms | grep -iv '[048c]0 [Tt] ' | wc -l
+ 1357
+ # grep ' [Tt] ' /proc/kallsyms | grep -iv '[048c]0 [Tt] ' | grep acpi | wc -l
+ 0
+
+With the patch applied, the remaining unaligned text labels are a
+combination of static call trampolines and labels in assembly, which can
+be dealt with in subsequent patches.
+
+Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Cc: Florent Revest <revest@chromium.org>
+Cc: Len Brown <lenb@kernel.org>
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Robert Moore <robert.moore@intel.com>
+Cc: Steven Rostedt <rostedt@goodmis.org>
+Cc: Will Deacon <will@kernel.org>
+Cc: linux-acpi@vger.kernel.org
+Link: https://lore.kernel.org/r/20230123134603.1064407-4-mark.rutland@arm.com
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/acpica/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile
+index 59700433a96e5..f919811156b1f 100644
+--- a/drivers/acpi/acpica/Makefile
++++ b/drivers/acpi/acpica/Makefile
+@@ -3,7 +3,7 @@
+ # Makefile for ACPICA Core interpreter
+ #
+
+-ccflags-y := -Os -D_LINUX -DBUILDING_ACPICA
++ccflags-y := -D_LINUX -DBUILDING_ACPICA
+ ccflags-$(CONFIG_ACPI_DEBUG) += -DACPI_DEBUG_OUTPUT
+
+ # use acpi.o to put all files here into acpi.o modparam namespace
+--
+2.39.2
+
--- /dev/null
+From d8ae3dec5fe3d4ebec6904cfff8d80b31234d09a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Feb 2023 13:44:49 +0100
+Subject: ACPI: video: Fix Lenovo Ideapad Z570 DMI match
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 2d11eae42d52a131f06061015e49dc0f085c5bfc ]
+
+Multiple Ideapad Z570 variants need acpi_backlight=native to force native
+use on these pre Windows 8 machines since acpi_video backlight control
+does not work here.
+
+The original DMI quirk matches on a product_name of "102434U" but other
+variants may have different product_name-s such as e.g. "1024D9U".
+
+Move to checking product_version instead as is more or less standard for
+Lenovo DMI quirks for similar reasons.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/video_detect.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
+index b13713199ad94..038542b3a80a7 100644
+--- a/drivers/acpi/video_detect.c
++++ b/drivers/acpi/video_detect.c
+@@ -313,7 +313,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
+ .ident = "Lenovo Ideapad Z570",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+- DMI_MATCH(DMI_PRODUCT_NAME, "102434U"),
++ DMI_MATCH(DMI_PRODUCT_VERSION, "Ideapad Z570"),
+ },
+ },
+ {
+--
+2.39.2
+
--- /dev/null
+From 9a890380bcf1e7578ed54597af66fcb58223d033 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Dec 2022 09:51:20 -0600
+Subject: ACPICA: Drop port I/O validation for some regions
+
+From: Mario Limonciello <mario.limonciello@amd.com>
+
+[ Upstream commit e1d9148582ab2c3dada5c5cf8ca7531ca269fee5 ]
+
+Microsoft introduced support in Windows XP for blocking port I/O
+to various regions. For Windows compatibility ACPICA has adopted
+the same protections and will disallow writes to those
+(presumably) the same regions.
+
+On some systems the AML included with the firmware will issue 4 byte
+long writes to 0x80. These writes aren't making it over because of this
+blockage. The first 4 byte write attempt is rejected, and then
+subsequently 1 byte at a time each offset is tried. The first at 0x80
+works, but then the next 3 bytes are rejected.
+
+This manifests in bizarre failures for devices that expected the AML to
+write all 4 bytes. Trying the same AML on Windows 10 or 11 doesn't hit
+this failure and all 4 bytes are written.
+
+Either some of these regions were wrong or some point after Windows XP
+some of these regions blocks have been lifted.
+
+In the last 15 years there doesn't seem to be any reports popping up of
+this error in the Windows event viewer anymore. There is no documentation
+at Microsoft's developer site indicating that Windows ACPI interpreter
+blocks these regions. Between the lack of documentation and the fact that
+the writes actually do work in Windows 10 and 11, it's quite likely
+Windows doesn't actually enforce this anymore.
+
+So to help the issue, only enforce Windows XP specific entries if the
+latest _OSI supported is Windows XP. Continue to enforce the
+ALWAYS_ILLEGAL entries.
+
+Link: https://github.com/acpica/acpica/pull/817
+Fixes: 7f0719039085 ("ACPICA: New: I/O port protection")
+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/acpica/hwvalid.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/acpi/acpica/hwvalid.c b/drivers/acpi/acpica/hwvalid.c
+index b2ca7dfd3fc92..0cc4de3f71d51 100644
+--- a/drivers/acpi/acpica/hwvalid.c
++++ b/drivers/acpi/acpica/hwvalid.c
+@@ -23,8 +23,8 @@ acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width);
+ *
+ * The table is used to implement the Microsoft port access rules that
+ * first appeared in Windows XP. Some ports are always illegal, and some
+- * ports are only illegal if the BIOS calls _OSI with a win_XP string or
+- * later (meaning that the BIOS itelf is post-XP.)
++ * ports are only illegal if the BIOS calls _OSI with nothing newer than
++ * the specific _OSI strings.
+ *
+ * This provides ACPICA with the desired port protections and
+ * Microsoft compatibility.
+@@ -145,7 +145,8 @@ acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width)
+
+ /* Port illegality may depend on the _OSI calls made by the BIOS */
+
+- if (acpi_gbl_osi_data >= port_info->osi_dependency) {
++ if (port_info->osi_dependency == ACPI_ALWAYS_ILLEGAL ||
++ acpi_gbl_osi_data == port_info->osi_dependency) {
+ ACPI_DEBUG_PRINT((ACPI_DB_VALUES,
+ "Denied AML access to port 0x%8.8X%8.8X/%X (%s 0x%.4X-0x%.4X)\n",
+ ACPI_FORMAT_UINT64(address),
+--
+2.39.2
+
--- /dev/null
+From d4e32765a9b503c3513c7fd84998ffdc6dfdd6ae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 7 Jan 2023 02:53:08 +0300
+Subject: ACPICA: nsrepair: handle cases without a return value correctly
+
+From: Daniil Tatianin <d-tatianin@yandex-team.ru>
+
+[ Upstream commit ca843a4c79486e99a19b859ef0b9887854afe146 ]
+
+Previously acpi_ns_simple_repair() would crash if expected_btypes
+contained any combination of ACPI_RTYPE_NONE with a different type,
+e.g | ACPI_RTYPE_INTEGER because of slightly incorrect logic in the
+!return_object branch, which wouldn't return AE_AML_NO_RETURN_VALUE
+for such cases.
+
+Found by Linux Verification Center (linuxtesting.org) with the SVACE
+static analysis tool.
+
+Link: https://github.com/acpica/acpica/pull/811
+Fixes: 61db45ca2163 ("ACPICA: Restore code that repairs NULL package elements in return values.")
+Signed-off-by: Daniil Tatianin <d-tatianin@yandex-team.ru>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/acpica/nsrepair.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/acpi/acpica/nsrepair.c b/drivers/acpi/acpica/nsrepair.c
+index 90db2d85e7f5c..f28d811a3724d 100644
+--- a/drivers/acpi/acpica/nsrepair.c
++++ b/drivers/acpi/acpica/nsrepair.c
+@@ -181,8 +181,9 @@ acpi_ns_simple_repair(struct acpi_evaluate_info *info,
+ * Try to fix if there was no return object. Warning if failed to fix.
+ */
+ if (!return_object) {
+- if (expected_btypes && (!(expected_btypes & ACPI_RTYPE_NONE))) {
+- if (package_index != ACPI_NOT_PACKAGE_ELEMENT) {
++ if (expected_btypes) {
++ if (!(expected_btypes & ACPI_RTYPE_NONE) &&
++ package_index != ACPI_NOT_PACKAGE_ELEMENT) {
+ ACPI_WARN_PREDEFINED((AE_INFO,
+ info->full_pathname,
+ ACPI_WARN_ALWAYS,
+@@ -196,14 +197,15 @@ acpi_ns_simple_repair(struct acpi_evaluate_info *info,
+ if (ACPI_SUCCESS(status)) {
+ return (AE_OK); /* Repair was successful */
+ }
+- } else {
++ }
++
++ if (expected_btypes != ACPI_RTYPE_NONE) {
+ ACPI_WARN_PREDEFINED((AE_INFO,
+ info->full_pathname,
+ ACPI_WARN_ALWAYS,
+ "Missing expected return value"));
++ return (AE_AML_NO_RETURN_VALUE);
+ }
+-
+- return (AE_AML_NO_RETURN_VALUE);
+ }
+ }
+
+--
+2.39.2
+
--- /dev/null
+From a213fa18fefca5556d54f871a056affdf4bc5ec1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Jan 2023 00:14:02 -0500
+Subject: alpha/boot/tools/objstrip: fix the check for ELF header
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+[ Upstream commit 1878787797cbb019eeefe6f905514dcd557302b6 ]
+
+Just memcmp() with ELFMAG - that's the normal way to do it in userland
+code, which that thing is. Besides, that has the benefit of actually
+building - str_has_prefix() is *NOT* present in <string.h>.
+
+Fixes: 5f14596e55de "alpha: Replace strncmp with str_has_prefix"
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/alpha/boot/tools/objstrip.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/alpha/boot/tools/objstrip.c b/arch/alpha/boot/tools/objstrip.c
+index 08b430d25a315..7cf92d172dce9 100644
+--- a/arch/alpha/boot/tools/objstrip.c
++++ b/arch/alpha/boot/tools/objstrip.c
+@@ -148,7 +148,7 @@ main (int argc, char *argv[])
+ #ifdef __ELF__
+ elf = (struct elfhdr *) buf;
+
+- if (elf->e_ident[0] == 0x7f && str_has_prefix((char *)elf->e_ident + 1, "ELF")) {
++ if (memcmp(&elf->e_ident[EI_MAG0], ELFMAG, SELFMAG) == 0) {
+ if (elf->e_type != ET_EXEC) {
+ fprintf(stderr, "%s: %s is not an ELF executable\n",
+ prog_name, inname);
+--
+2.39.2
+
--- /dev/null
+From b2727051f19372dbfadf78b46847f971ebae9c2e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Jan 2023 14:15:23 +0300
+Subject: ALSA: hda/ca0132: minor fix for allocation size
+
+From: Alexey V. Vissarionov <gremlin@altlinux.org>
+
+[ Upstream commit 3ee0fe7fa39b14d1cea455b7041f2df933bd97d2 ]
+
+Although the "dma_chan" pointer occupies more or equal space compared
+to "*dma_chan", the allocation size should use the size of variable
+itself.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: 01ef7dbffb41 ("ALSA: hda - Update CA0132 codec to load DSP firmware binary")
+Signed-off-by: Alexey V. Vissarionov <gremlin@altlinux.org>
+Link: https://lore.kernel.org/r/20230117111522.GA15213@altlinux.org
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_ca0132.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
+index 82f14c3f642bd..24c2638cde376 100644
+--- a/sound/pci/hda/patch_ca0132.c
++++ b/sound/pci/hda/patch_ca0132.c
+@@ -2331,7 +2331,7 @@ static int dspio_set_uint_param_no_source(struct hda_codec *codec, int mod_id,
+ static int dspio_alloc_dma_chan(struct hda_codec *codec, unsigned int *dma_chan)
+ {
+ int status = 0;
+- unsigned int size = sizeof(dma_chan);
++ unsigned int size = sizeof(*dma_chan);
+
+ codec_dbg(codec, " dspio_alloc_dma_chan() -- begin\n");
+ status = dspio_scp(codec, MASTERCONTROL, 0x20,
+--
+2.39.2
+
--- /dev/null
+From d426e579e4ed586af0a21dd858c6261e8821c14c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Jan 2023 16:53:54 +0100
+Subject: ARM: dts: exynos: correct wr-active property in Exynos3250 Rinato
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit d15d2a617499882971ddb773a583015bf36fa492 ]
+
+The property is wr-active:
+
+ exynos3250-rinato.dtb: fimd@11c00000: i80-if-timings: 'wr-act' does not match any of the regexes: 'pinctrl-[0-9]+'
+
+Fixes: b59b3afb94d4 ("ARM: dts: add fimd device support for exynos3250-rinato")
+Link: https://lore.kernel.org/r/20230120155404.323386-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/exynos3250-rinato.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/exynos3250-rinato.dts b/arch/arm/boot/dts/exynos3250-rinato.dts
+index f9e3b13d3aac2..bbf01f76ce3b1 100644
+--- a/arch/arm/boot/dts/exynos3250-rinato.dts
++++ b/arch/arm/boot/dts/exynos3250-rinato.dts
+@@ -249,7 +249,7 @@ &fimd {
+ i80-if-timings {
+ cs-setup = <0>;
+ wr-setup = <0>;
+- wr-act = <1>;
++ wr-active = <1>;
+ wr-hold = <0>;
+ };
+ };
+--
+2.39.2
+
--- /dev/null
+From cd674eba668ced7ad379d081bca460c24c23a5d1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 21 Jan 2023 22:18:42 +0200
+Subject: ARM: dts: exynos: Use Exynos5420 compatible for the MIPI video phy
+
+From: Markuss Broks <markuss.broks@gmail.com>
+
+[ Upstream commit 5d5aa219a790d61cad2c38e1aa32058f16ad2f0b ]
+
+For some reason, the driver adding support for Exynos5420 MIPI phy
+back in 2016 wasn't used on Exynos5420, which caused a kernel panic.
+Add the proper compatible for it.
+
+Signed-off-by: Markuss Broks <markuss.broks@gmail.com>
+Link: https://lore.kernel.org/r/20230121201844.46872-2-markuss.broks@gmail.com
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/exynos5420.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi
+index 83580f076a587..34886535f8477 100644
+--- a/arch/arm/boot/dts/exynos5420.dtsi
++++ b/arch/arm/boot/dts/exynos5420.dtsi
+@@ -605,7 +605,7 @@ dp_phy: dp-video-phy {
+ };
+
+ mipi_phy: mipi-video-phy {
+- compatible = "samsung,s5pv210-mipi-video-phy";
++ compatible = "samsung,exynos5420-mipi-video-phy";
+ syscon = <&pmu_system_controller>;
+ #phy-cells = <1>;
+ };
+--
+2.39.2
+
--- /dev/null
+From 37851e2e47455b5a6655f8cdcde6fc3310f1e934 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Dec 2022 11:04:33 +0800
+Subject: ARM: dts: imx7s: correct iomuxc gpr mux controller cells
+
+From: Peng Fan <peng.fan@nxp.com>
+
+[ Upstream commit 0e3e1946606a2919b1dda9967ab2e1c5af2fedd6 ]
+
+Per binding doc reg-mux.yaml, the #mux-control-cells should be 1
+
+Signed-off-by: Peng Fan <peng.fan@nxp.com>
+Reviewed-by: Marco Felsch <m.felsch@pengutronix.de>
+Fixes: 94a905a79f2c ("ARM: dts: imx7s: add multiplexer controls")
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/imx7s.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi
+index 9e1b0af0aa43f..43b39ad9ddcee 100644
+--- a/arch/arm/boot/dts/imx7s.dtsi
++++ b/arch/arm/boot/dts/imx7s.dtsi
+@@ -494,7 +494,7 @@ gpr: iomuxc-gpr@30340000 {
+
+ mux: mux-controller {
+ compatible = "mmio-mux";
+- #mux-control-cells = <0>;
++ #mux-control-cells = <1>;
+ mux-reg-masks = <0x14 0x00000010>;
+ };
+
+--
+2.39.2
+
--- /dev/null
+From e7f54c4cc8b66e6072df3a79c2efb63c37919737 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 31 Dec 2022 16:58:54 -0600
+Subject: ARM: dts: sun8i: nanopi-duo2: Fix regulator GPIO reference
+
+From: Samuel Holland <samuel@sholland.org>
+
+[ Upstream commit 2177d4ae971f79b4a9a3c411f2fb8ae6113d1430 ]
+
+The property named in the schema is 'enable-gpios', not 'enable-gpio'.
+This makes no difference at runtime, because the regulator is marked as
+always-on, but it breaks validation.
+
+Fixes: 4701fc6e5dd9 ("ARM: dts: sun8i: add FriendlyARM NanoPi Duo2")
+Reviewed-by: Andre Przywara <andre.przywara@arm.com>
+Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Signed-off-by: Samuel Holland <samuel@sholland.org>
+Link: https://lore.kernel.org/r/20221231225854.16320-2-samuel@sholland.org
+Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/sun8i-h3-nanopi-duo2.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/sun8i-h3-nanopi-duo2.dts b/arch/arm/boot/dts/sun8i-h3-nanopi-duo2.dts
+index 6b149271ef13f..8722fdf77ebc2 100644
+--- a/arch/arm/boot/dts/sun8i-h3-nanopi-duo2.dts
++++ b/arch/arm/boot/dts/sun8i-h3-nanopi-duo2.dts
+@@ -57,7 +57,7 @@ reg_vdd_cpux: vdd-cpux-regulator {
+ regulator-ramp-delay = <50>; /* 4ms */
+
+ enable-active-high;
+- enable-gpio = <&r_pio 0 8 GPIO_ACTIVE_HIGH>; /* PL8 */
++ enable-gpios = <&r_pio 0 8 GPIO_ACTIVE_HIGH>; /* PL8 */
+ gpios = <&r_pio 0 6 GPIO_ACTIVE_HIGH>; /* PL6 */
+ gpios-states = <0x1>;
+ states = <1100000 0>, <1300000 1>;
+--
+2.39.2
+
--- /dev/null
+From c3bbead1f0474364a482381acf904a2f43f3d7ff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Jan 2023 14:11:23 +0800
+Subject: ARM: imx: Call ida_simple_remove() for ida_simple_get
+
+From: Angus Chen <angus.chen@jaguarmicro.com>
+
+[ Upstream commit ebeb49f43c8952f12aa20f03f00d7009edc2d1c5 ]
+
+The function call ida_simple_get maybe fail,we should deal with it.
+And if ida_simple_get success ,it need to call ida_simple_remove also.
+BTW,devm_kasprintf can handle id is zero for consistency.
+
+Fixes: e76bdfd7403a ("ARM: imx: Added perf functionality to mmdc driver")
+Signed-off-by: Angus Chen <angus.chen@jaguarmicro.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-imx/mmdc.c | 24 ++++++++++++------------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+diff --git a/arch/arm/mach-imx/mmdc.c b/arch/arm/mach-imx/mmdc.c
+index af12668d0bf51..b9efe9da06e0b 100644
+--- a/arch/arm/mach-imx/mmdc.c
++++ b/arch/arm/mach-imx/mmdc.c
+@@ -99,6 +99,7 @@ struct mmdc_pmu {
+ cpumask_t cpu;
+ struct hrtimer hrtimer;
+ unsigned int active_events;
++ int id;
+ struct device *dev;
+ struct perf_event *mmdc_events[MMDC_NUM_COUNTERS];
+ struct hlist_node node;
+@@ -433,8 +434,6 @@ static enum hrtimer_restart mmdc_pmu_timer_handler(struct hrtimer *hrtimer)
+ static int mmdc_pmu_init(struct mmdc_pmu *pmu_mmdc,
+ void __iomem *mmdc_base, struct device *dev)
+ {
+- int mmdc_num;
+-
+ *pmu_mmdc = (struct mmdc_pmu) {
+ .pmu = (struct pmu) {
+ .task_ctx_nr = perf_invalid_context,
+@@ -452,15 +451,16 @@ static int mmdc_pmu_init(struct mmdc_pmu *pmu_mmdc,
+ .active_events = 0,
+ };
+
+- mmdc_num = ida_simple_get(&mmdc_ida, 0, 0, GFP_KERNEL);
++ pmu_mmdc->id = ida_simple_get(&mmdc_ida, 0, 0, GFP_KERNEL);
+
+- return mmdc_num;
++ return pmu_mmdc->id;
+ }
+
+ static int imx_mmdc_remove(struct platform_device *pdev)
+ {
+ struct mmdc_pmu *pmu_mmdc = platform_get_drvdata(pdev);
+
++ ida_simple_remove(&mmdc_ida, pmu_mmdc->id);
+ cpuhp_state_remove_instance_nocalls(cpuhp_mmdc_state, &pmu_mmdc->node);
+ perf_pmu_unregister(&pmu_mmdc->pmu);
+ iounmap(pmu_mmdc->mmdc_base);
+@@ -474,7 +474,6 @@ static int imx_mmdc_perf_init(struct platform_device *pdev, void __iomem *mmdc_b
+ {
+ struct mmdc_pmu *pmu_mmdc;
+ char *name;
+- int mmdc_num;
+ int ret;
+ const struct of_device_id *of_id =
+ of_match_device(imx_mmdc_dt_ids, &pdev->dev);
+@@ -497,14 +496,14 @@ static int imx_mmdc_perf_init(struct platform_device *pdev, void __iomem *mmdc_b
+ cpuhp_mmdc_state = ret;
+ }
+
+- mmdc_num = mmdc_pmu_init(pmu_mmdc, mmdc_base, &pdev->dev);
+- pmu_mmdc->mmdc_ipg_clk = mmdc_ipg_clk;
+- if (mmdc_num == 0)
+- name = "mmdc";
+- else
+- name = devm_kasprintf(&pdev->dev,
+- GFP_KERNEL, "mmdc%d", mmdc_num);
++ ret = mmdc_pmu_init(pmu_mmdc, mmdc_base, &pdev->dev);
++ if (ret < 0)
++ goto pmu_free;
+
++ name = devm_kasprintf(&pdev->dev,
++ GFP_KERNEL, "mmdc%d", ret);
++
++ pmu_mmdc->mmdc_ipg_clk = mmdc_ipg_clk;
+ pmu_mmdc->devtype_data = (struct fsl_mmdc_devtype_data *)of_id->data;
+
+ hrtimer_init(&pmu_mmdc->hrtimer, CLOCK_MONOTONIC,
+@@ -525,6 +524,7 @@ static int imx_mmdc_perf_init(struct platform_device *pdev, void __iomem *mmdc_b
+
+ pmu_register_err:
+ pr_warn("MMDC Perf PMU failed (%d), disabled\n", ret);
++ ida_simple_remove(&mmdc_ida, pmu_mmdc->id);
+ cpuhp_state_remove_instance_nocalls(cpuhp_mmdc_state, &pmu_mmdc->node);
+ hrtimer_cancel(&pmu_mmdc->hrtimer);
+ pmu_free:
+--
+2.39.2
+
--- /dev/null
+From 960c5abeacee4f6796917978bb7638b4a735a493 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 19 Jan 2023 11:57:54 +0200
+Subject: ARM: OMAP1: call platform_device_put() in error case in
+ omap1_dm_timer_init()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 0414a100d6ab32721efa70ab55524540fdfe0ede ]
+
+If platform_device_add() is not called or failed, it should call
+platform_device_put() in error case.
+
+Fixes: 97933d6ced60 ("ARM: OMAP1: dmtimer: conversion to platform devices")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Message-Id: <20220701094602.2365099-1-yangyingliang@huawei.com>
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-omap1/timer.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-omap1/timer.c b/arch/arm/mach-omap1/timer.c
+index 97fc2096b9709..05f016d5e9f67 100644
+--- a/arch/arm/mach-omap1/timer.c
++++ b/arch/arm/mach-omap1/timer.c
+@@ -165,7 +165,7 @@ static int __init omap1_dm_timer_init(void)
+ kfree(pdata);
+
+ err_free_pdev:
+- platform_device_unregister(pdev);
++ platform_device_put(pdev);
+
+ return ret;
+ }
+--
+2.39.2
+
--- /dev/null
+From 0c736b9dd353a6f5289e97f3d8270b45cb90959a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Nov 2022 22:19:17 +0800
+Subject: ARM: OMAP2+: Fix memory leak in realtime_counter_init()
+
+From: Chen Hui <judy.chenhui@huawei.com>
+
+[ Upstream commit ed8167cbf65c2b6ff6faeb0f96ded4d6d581e1ac ]
+
+The "sys_clk" resource is malloced by clk_get(),
+it is not released when the function return.
+
+Fixes: fa6d79d27614 ("ARM: OMAP: Add initialisation for the real-time counter.")
+Signed-off-by: Chen Hui <judy.chenhui@huawei.com>
+Message-Id: <20221108141917.46796-1-judy.chenhui@huawei.com>
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-omap2/timer.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
+index 620ba69c8f114..5677c4a08f376 100644
+--- a/arch/arm/mach-omap2/timer.c
++++ b/arch/arm/mach-omap2/timer.c
+@@ -76,6 +76,7 @@ static void __init realtime_counter_init(void)
+ }
+
+ rate = clk_get_rate(sys_clk);
++ clk_put(sys_clk);
+
+ if (soc_is_dra7xx()) {
+ /*
+--
+2.39.2
+
--- /dev/null
+From f6861608e2546bf1c5b39ba92fad908685230681 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Jan 2023 10:02:12 +0100
+Subject: ARM: s3c: fix s3c64xx_set_timer_source prototype
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 5bf52f5e4d12b8109f348cab60cb7d51092c4270 ]
+
+The prototype does not match the definition, as gcc-13 points
+out:
+
+arch/arm/mach-s3c/s3c64xx.c:169:13: error: conflicting types for 's3c64xx_set_timer_source' due to enum/integer mismatch; have 'void(unsigned int, unsigned int)' [-Werror=enum-int-mismatch]
+ 169 | void __init s3c64xx_set_timer_source(unsigned int event, unsigned int source)
+ | ^~~~~~~~~~~~~~~~~~~~~~~~
+In file included from arch/arm/mach-s3c/s3c64xx.c:50:
+arch/arm/mach-s3c/s3c64xx.h:62:20: note: previous declaration of 's3c64xx_set_timer_source' with type 'void(enum s3c64xx_timer_mode, enum s3c64xx_timer_mode)'
+ 62 | extern void __init s3c64xx_set_timer_source(enum s3c64xx_timer_mode event,
+ | ^~~~~~~~~~~~~~~~~~~~~~~~
+
+Fixes: 4280506ac9bb ("ARM: SAMSUNG: Move all platforms to new clocksource driver")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Link: https://lore.kernel.org/r/20230118090224.2162863-1-arnd@kernel.org
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-s3c/s3c64xx.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-s3c/s3c64xx.c b/arch/arm/mach-s3c/s3c64xx.c
+index 4dfb648142f2a..17f0065031490 100644
+--- a/arch/arm/mach-s3c/s3c64xx.c
++++ b/arch/arm/mach-s3c/s3c64xx.c
+@@ -173,7 +173,8 @@ static struct samsung_pwm_variant s3c64xx_pwm_variant = {
+ .tclk_mask = (1 << 7) | (1 << 6) | (1 << 5),
+ };
+
+-void __init s3c64xx_set_timer_source(unsigned int event, unsigned int source)
++void __init s3c64xx_set_timer_source(enum s3c64xx_timer_mode event,
++ enum s3c64xx_timer_mode source)
+ {
+ s3c64xx_pwm_variant.output_mask = BIT(SAMSUNG_PWM_NUM) - 1;
+ s3c64xx_pwm_variant.output_mask &= ~(BIT(event) | BIT(source));
+--
+2.39.2
+
--- /dev/null
+From e3031cb8e9ceb83bdaadd00cd8512c3c78e5c17d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Nov 2022 22:05:44 +0800
+Subject: ARM: zynq: Fix refcount leak in zynq_early_slcr_init
+
+From: Qiheng Lin <linqiheng@huawei.com>
+
+[ Upstream commit 9eedb910a3be0005b88c696a8552c0d4c9937cd4 ]
+
+of_find_compatible_node() returns a node pointer with refcount incremented,
+we should use of_node_put() on error path.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: 3329659df030 ("ARM: zynq: Simplify SLCR initialization")
+Signed-off-by: Qiheng Lin <linqiheng@huawei.com>
+Link: https://lore.kernel.org/r/20221129140544.41293-1-linqiheng@huawei.com
+Signed-off-by: Michal Simek <michal.simek@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-zynq/slcr.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/mach-zynq/slcr.c b/arch/arm/mach-zynq/slcr.c
+index 37707614885a5..9765b3f4c2fc5 100644
+--- a/arch/arm/mach-zynq/slcr.c
++++ b/arch/arm/mach-zynq/slcr.c
+@@ -213,6 +213,7 @@ int __init zynq_early_slcr_init(void)
+ zynq_slcr_regmap = syscon_regmap_lookup_by_compatible("xlnx,zynq-slcr");
+ if (IS_ERR(zynq_slcr_regmap)) {
+ pr_err("%s: failed to find zynq-slcr\n", __func__);
++ of_node_put(np);
+ return -ENODEV;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From a3c11cf0d5095e61002cac2d1572709591eada9c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Jan 2023 11:34:23 +0100
+Subject: arm64: dts: amlogic: meson-axg: fix SCPI clock dvfs node name
+
+From: Neil Armstrong <neil.armstrong@linaro.org>
+
+[ Upstream commit 5b7069d72f03c92a0ab919725017394ebce03a81 ]
+
+Fixes:
+scpi: clocks: 'clock-controller' does not match any of the regexes: '^clocks-[0-9a-f]+$', 'pinctrl-[0-9]+'
+
+Link: https://lore.kernel.org/r/20230124-b4-amlogic-bindings-fixups-v1-2-44351528957e@linaro.org
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/amlogic/meson-axg.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
+index 5c75fbf0d4709..ddf9eb79e4930 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
++++ b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
+@@ -151,7 +151,7 @@ scpi {
+ scpi_clocks: clocks {
+ compatible = "arm,scpi-clocks";
+
+- scpi_dvfs: clock-controller {
++ scpi_dvfs: clocks-0 {
+ compatible = "arm,scpi-dvfs-clocks";
+ #clock-cells = <1>;
+ clock-indices = <0>;
+--
+2.39.2
+
--- /dev/null
+From 148e195e383f8e2b5d5566aeb02d097358dd27c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Jan 2023 11:34:24 +0100
+Subject: arm64: dts: amlogic: meson-gx: add missing SCPI sensors compatible
+
+From: Neil Armstrong <neil.armstrong@linaro.org>
+
+[ Upstream commit 2ff650051493d5bdb6dd09d4c2850bb37db6be31 ]
+
+Fixes:
+scpi: sensors:compatible: 'oneOf' conditional failed, one must be fixed:
+ ['amlogic,meson-gxbb-scpi-sensors'] is too short
+ 'arm,scpi-sensors' was expected
+
+Link: https://lore.kernel.org/r/20230124-b4-amlogic-bindings-fixups-v1-3-44351528957e@linaro.org
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/amlogic/meson-axg.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
+index ddf9eb79e4930..c892b252e5b0c 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
++++ b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
+@@ -160,7 +160,7 @@ scpi_dvfs: clocks-0 {
+ };
+
+ scpi_sensors: sensors {
+- compatible = "amlogic,meson-gxbb-scpi-sensors";
++ compatible = "amlogic,meson-gxbb-scpi-sensors", "arm,scpi-sensors";
+ #thermal-sensor-cells = <1>;
+ };
+ };
+--
+2.39.2
+
--- /dev/null
+From 6eef9fddf68bd3a44b63e890838a67f851c9b8e5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Jan 2023 11:34:27 +0100
+Subject: arm64: dts: amlogic: meson-gx: add missing unit address to rng node
+ name
+
+From: Neil Armstrong <neil.armstrong@linaro.org>
+
+[ Upstream commit 61ff70708b98a85516eccb3755084ac97b42cf48 ]
+
+Fixes:
+bus@c8834000: rng: {...} should not be valid under {'type': 'object'}
+
+Link: https://lore.kernel.org/r/20230124-b4-amlogic-bindings-fixups-v1-6-44351528957e@linaro.org
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
+index 39293450135a6..4c7131526c4d3 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
++++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
+@@ -524,7 +524,7 @@ periphs: bus@c8834000 {
+ #size-cells = <2>;
+ ranges = <0x0 0x0 0x0 0xc8834000 0x0 0x2000>;
+
+- hwrng: rng {
++ hwrng: rng@0 {
+ compatible = "amlogic,meson-rng";
+ reg = <0x0 0x0 0x0 0x4>;
+ };
+--
+2.39.2
+
--- /dev/null
+From 5425c02344b7ac7f72ab7b91f53153b6b09a0b1e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Jan 2023 11:34:22 +0100
+Subject: arm64: dts: amlogic: meson-gx: fix SCPI clock dvfs node name
+
+From: Neil Armstrong <neil.armstrong@linaro.org>
+
+[ Upstream commit 127f79212b07c5d9a6657a87e3eafdd889335814 ]
+
+Fixes:
+scpi: clocks: 'clock-controller' does not match any of the regexes: '^clocks-[0-9a-f]+$', 'pinctrl-[0-9]+'
+
+Link: https://lore.kernel.org/r/20230124-b4-amlogic-bindings-fixups-v1-1-44351528957e@linaro.org
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
+index 85f4876c509ae..39293450135a6 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
++++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
+@@ -243,7 +243,7 @@ scpi {
+ scpi_clocks: clocks {
+ compatible = "arm,scpi-clocks";
+
+- scpi_dvfs: clock-controller {
++ scpi_dvfs: clocks-0 {
+ compatible = "arm,scpi-dvfs-clocks";
+ #clock-cells = <1>;
+ clock-indices = <0>;
+--
+2.39.2
+
--- /dev/null
+From f9adb4ccdb2a90de3b87b2aba2c0ebfeaa8602a5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Jan 2023 11:34:31 +0100
+Subject: arm64: dts: amlogic: meson-gx-libretech-pc: fix update button name
+
+From: Neil Armstrong <neil.armstrong@linaro.org>
+
+[ Upstream commit 6bb506ed36968207a8832f0143ebc127f0770eef ]
+
+Fixes:
+ adc-keys: 'update-button' does not match any of the regexes: '^button-', 'pinctrl-[0-9]+'
+
+Link: https://lore.kernel.org/r/20230124-b4-amlogic-bindings-fixups-v1-10-44351528957e@linaro.org
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/amlogic/meson-gx-libretech-pc.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gx-libretech-pc.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx-libretech-pc.dtsi
+index c2480bab8d337..27e964bfa947a 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-gx-libretech-pc.dtsi
++++ b/arch/arm64/boot/dts/amlogic/meson-gx-libretech-pc.dtsi
+@@ -17,7 +17,7 @@ adc-keys {
+ io-channel-names = "buttons";
+ keyup-threshold-microvolt = <1800000>;
+
+- update-button {
++ button-update {
+ label = "update";
+ linux,code = <KEY_VENDOR>;
+ press-threshold-microvolt = <1300000>;
+--
+2.39.2
+
--- /dev/null
+From a623a78667cc8e0953b270b2c24decc9bd9da9a3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Jan 2023 11:34:34 +0100
+Subject: arm64: dts: amlogic: meson-gxbb-kii-pro: fix led node name
+
+From: Neil Armstrong <neil.armstrong@linaro.org>
+
+[ Upstream commit afdef3b188c934f79ad4b0a7bd8c692742f9b5af ]
+
+Fixes:
+leds: status: {...} is not of type 'array'
+
+Link: https://lore.kernel.org/r/20230124-b4-amlogic-bindings-fixups-v1-13-44351528957e@linaro.org
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/amlogic/meson-gxbb-kii-pro.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-kii-pro.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-kii-pro.dts
+index e8394a8269ee1..802faf7e4e3cb 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-kii-pro.dts
++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-kii-pro.dts
+@@ -16,7 +16,7 @@ / {
+
+ leds {
+ compatible = "gpio-leds";
+- status {
++ led {
+ gpios = <&gpio_ao GPIOAO_13 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ color = <LED_COLOR_ID_RED>;
+--
+2.39.2
+
--- /dev/null
+From 7fca052f7affe17dc3ade69cf530a63f8f78f670 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Jan 2023 11:34:30 +0100
+Subject: arm64: dts: amlogic: meson-gxl: add missing unit address to
+ eth-phy-mux node name
+
+From: Neil Armstrong <neil.armstrong@linaro.org>
+
+[ Upstream commit d19189f70ba596798ea49166d2d1ef36a8df5289 ]
+
+Fixes:
+bus@c8834000: eth-phy-mux: {...} should not be valid under {'type': 'object'}
+
+Link: https://lore.kernel.org/r/20230124-b4-amlogic-bindings-fixups-v1-9-44351528957e@linaro.org
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
+index c3ac531c4f84a..3500229350522 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
++++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
+@@ -759,7 +759,7 @@ mux {
+ };
+ };
+
+- eth-phy-mux {
++ eth-phy-mux@55c {
+ compatible = "mdio-mux-mmioreg", "mdio-mux";
+ #address-cells = <1>;
+ #size-cells = <0>;
+--
+2.39.2
+
--- /dev/null
+From 240c345f39790cb052d13b33fb9f0c83f00ad7eb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Jan 2023 11:34:33 +0100
+Subject: arm64: dts: amlogic: meson-gxl-s905d-phicomm-n1: fix led node name
+
+From: Neil Armstrong <neil.armstrong@linaro.org>
+
+[ Upstream commit eee64d8fbbdaab72bbab3e462f3a7b742d20c8c2 ]
+
+Fixes:
+leds: status: {...} is not of type 'array'
+
+Link: https://lore.kernel.org/r/20230124-b4-amlogic-bindings-fixups-v1-12-44351528957e@linaro.org
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/amlogic/meson-gxl-s905d-phicomm-n1.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-phicomm-n1.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-phicomm-n1.dts
+index 9ef210f17b4aa..393d3cb33b9ee 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-phicomm-n1.dts
++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-phicomm-n1.dts
+@@ -18,7 +18,7 @@ cvbs-connector {
+ leds {
+ compatible = "gpio-leds";
+
+- status {
++ led {
+ label = "n1:white:status";
+ gpios = <&gpio_ao GPIOAO_9 GPIO_ACTIVE_HIGH>;
+ default-state = "on";
+--
+2.39.2
+
--- /dev/null
+From 626e40fb24d79267a2d2e432fa9c853f5fe8f500 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Jan 2023 11:34:26 +0100
+Subject: arm64: dts: amlogic: meson-gxl-s905d-sml5442tw: drop invalid
+ clock-names property
+
+From: Neil Armstrong <neil.armstrong@linaro.org>
+
+[ Upstream commit e3bd275ccbacf5eb18eaa311cea39f8bf8655feb ]
+
+Fixes:
+bluetooth: 'clock-names' does not match any of the regexes: 'pinctrl-[0-9]+'
+
+Link: https://lore.kernel.org/r/20230124-b4-amlogic-bindings-fixups-v1-5-44351528957e@linaro.org
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/amlogic/meson-gxl-s905d-sml5442tw.dts | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-sml5442tw.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-sml5442tw.dts
+index 0b95e9ecbef0a..ca3fd6b67b940 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-sml5442tw.dts
++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-sml5442tw.dts
+@@ -75,6 +75,5 @@ bluetooth {
+ enable-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>;
+ max-speed = <2000000>;
+ clocks = <&wifi32k>;
+- clock-names = "lpo";
+ };
+ };
+--
+2.39.2
+
--- /dev/null
+From 01233d93a903992f636dad657f3b8905fdf56060 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Nov 2022 12:20:27 +0100
+Subject: arm64: dts: mediatek: mt7622: Add missing pwm-cells to pwm node
+
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+
+[ Upstream commit 22925af785fa3470efdf566339616d801119d348 ]
+
+Specify #pwm-cells on pwm@11006000 to make it actually usable.
+
+Fixes: ae457b7679c4 ("arm64: dts: mt7622: add SoC and peripheral related device nodes")
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20221128112028.58021-2-angelogioacchino.delregno@collabora.com
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/mediatek/mt7622.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+index 7c6d871538a63..884930a5849a2 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+@@ -428,6 +428,7 @@ uart3: serial@11005000 {
+ pwm: pwm@11006000 {
+ compatible = "mediatek,mt7622-pwm";
+ reg = <0 0x11006000 0 0x1000>;
++ #pwm-cells = <2>;
+ interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&topckgen CLK_TOP_PWM_SEL>,
+ <&pericfg CLK_PERI_PWM_PD>,
+--
+2.39.2
+
--- /dev/null
+From 6f459d25d1120b4197c85e98c4332d9c623bb02b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Dec 2022 16:42:26 +0800
+Subject: arm64: dts: mediatek: mt8183: Fix systimer 13 MHz clock description
+
+From: Chen-Yu Tsai <wenst@chromium.org>
+
+[ Upstream commit ce8a06b5bac75ccce99c0cf91b96b767d64f28a7 ]
+
+The systimer block derives its 13 MHz clock by dividing the main 26 MHz
+oscillator clock by 2 internally, not through the TOPCKGEN clock
+controller.
+
+On the MT8183 this divider is set either by power-on-reset or by the
+bootloader. The bootloader may then make the divider unconfigurable to,
+but can be read out by, the operating system.
+
+Making the systimer block take the 26 MHz clock directly requires
+changing the implementations. As an ABI compatible fix, change the
+input clock of the systimer block a fixed factor divide-by-2 clock
+that takes the 26 MHz oscillator as its input.
+
+Fixes: 5bc8e2875ffb ("arm64: dts: mt8183: add systimer0 device node")
+Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20221201084229.3464449-2-wenst@chromium.org
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/mediatek/mt8183.dtsi | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+index 08a914d3a6435..31bc8bae8cff8 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+@@ -205,6 +205,15 @@ psci {
+ method = "smc";
+ };
+
++ clk13m: fixed-factor-clock-13m {
++ compatible = "fixed-factor-clock";
++ #clock-cells = <0>;
++ clocks = <&clk26m>;
++ clock-div = <2>;
++ clock-mult = <1>;
++ clock-output-names = "clk13m";
++ };
++
+ clk26m: oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+@@ -355,8 +364,7 @@ systimer: timer@10017000 {
+ "mediatek,mt6765-timer";
+ reg = <0 0x10017000 0 0x1000>;
+ interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&topckgen CLK_TOP_CLK13M>;
+- clock-names = "clk13m";
++ clocks = <&clk13m>;
+ };
+
+ gce: mailbox@10238000 {
+--
+2.39.2
+
--- /dev/null
+From a9faae9b101efafb7445ca8cfd0942dc0069540a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Jan 2023 22:13:49 +0100
+Subject: arm64: dts: meson-g12a: Fix internal Ethernet PHY unit name
+
+From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+
+[ Upstream commit e7303651bbc76c848007f1cfac1fbeaa65f600d1 ]
+
+Documentation/devicetree/bindings/net/ethernet-phy.yaml defines that the
+node name for Ethernet PHYs should match the following pattern:
+ ^ethernet-phy(@[a-f0-9]+)?$
+
+Replace the underscore with a hyphen to adhere to this binding.
+
+Fixes: 280c17df8fbf ("arm64: dts: meson: g12a: add mdio multiplexer")
+Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://lore.kernel.org/r/20230111211350.1461860-6-martin.blumenstingl@googlemail.com
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
+index 2091db7c9b8af..c0defb36592d0 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
++++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
+@@ -1727,7 +1727,7 @@ int_mdio: mdio@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+- internal_ephy: ethernet_phy@8 {
++ internal_ephy: ethernet-phy@8 {
+ compatible = "ethernet-phy-id0180.3301",
+ "ethernet-phy-ieee802.3-c22";
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+--
+2.39.2
+
--- /dev/null
+From a5c99334e608983eb74a81addfc0488ae8a7da37 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Jan 2023 22:13:48 +0100
+Subject: arm64: dts: meson-gx: Fix Ethernet MAC address unit name
+
+From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+
+[ Upstream commit 8ed5310356bfa47cc6bb4221ae6b21258c52e3d1 ]
+
+Unit names should use hyphens instead of underscores to not cause
+warnings.
+
+Fixes: bfe59f92d306 ("ARM64: dts: amlogic: gxbb: Enable NVMEM")
+Suggested-by: Vyacheslav Bocharov <adeep@lexina.in>
+Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://lore.kernel.org/r/20230111211350.1461860-5-martin.blumenstingl@googlemail.com
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
+index 88a7db5c55a07..46018df13cc24 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
++++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
+@@ -226,7 +226,7 @@ sn: sn@14 {
+ reg = <0x14 0x10>;
+ };
+
+- eth_mac: eth_mac@34 {
++ eth_mac: eth-mac@34 {
+ reg = <0x34 0x10>;
+ };
+
+--
+2.39.2
+
--- /dev/null
+From d7f883c0b3773bb977af5a56769cb7bc509ee73b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Jan 2023 22:13:50 +0100
+Subject: arm64: dts: meson-gx: Fix the SCPI DVFS node name and unit address
+
+From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+
+[ Upstream commit f189c869ad92787ddd753558bcbae89d75825bb6 ]
+
+Node names should be generic and use hyphens instead of underscores to
+not cause warnings. Also nodes without a reg property should not have a
+unit-address. Change the scpi_dvfs node to use clock-controller as node
+name without a unit address (since it does not have a reg property).
+
+Fixes: 70db166a2baa ("ARM64: dts: meson-gxbb: Add SCPI with cpufreq & sensors Nodes")
+Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://lore.kernel.org/r/20230111211350.1461860-7-martin.blumenstingl@googlemail.com
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
+index 46018df13cc24..85f4876c509ae 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
++++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
+@@ -243,7 +243,7 @@ scpi {
+ scpi_clocks: clocks {
+ compatible = "arm,scpi-clocks";
+
+- scpi_dvfs: scpi_clocks@0 {
++ scpi_dvfs: clock-controller {
+ compatible = "arm,scpi-dvfs-clocks";
+ #clock-cells = <1>;
+ clock-indices = <0>;
+--
+2.39.2
+
--- /dev/null
+From cfee16e715046cd962578375a2a91acad457784f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 19 Jan 2023 05:30:31 +0000
+Subject: arm64: dts: meson: remove CPU opps below 1GHz for G12A boards
+
+From: Christian Hewitt <christianshewitt@gmail.com>
+
+[ Upstream commit 3cbd431c2b34d84605d358c8c57654193fd661fb ]
+
+Amlogic G12A devices experience CPU stalls and random board wedges when
+the system idles and CPU cores clock down to lower opp points. Recent
+vendor kernels include a change to remove 100-250MHz and other distro
+sources also remove the 500/667MHz points. Unless all 100-667Mhz opps
+are removed or the CPU governor forced to performance stalls are still
+observed, so let's remove them to improve stability and uptime.
+
+Fixes: b190056fa9ee ("arm64: dts: meson-g12a: add cpus OPP table")
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+Link: https://lore.kernel.org/r/20230119053031.21400-1-christianshewitt@gmail.com
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/amlogic/meson-g12a.dtsi | 20 --------------------
+ 1 file changed, 20 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi
+index fb0ab27d1f642..6eaceb717d617 100644
+--- a/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi
++++ b/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi
+@@ -57,26 +57,6 @@ cpu_opp_table: opp-table {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+- opp-100000000 {
+- opp-hz = /bits/ 64 <100000000>;
+- opp-microvolt = <731000>;
+- };
+-
+- opp-250000000 {
+- opp-hz = /bits/ 64 <250000000>;
+- opp-microvolt = <731000>;
+- };
+-
+- opp-500000000 {
+- opp-hz = /bits/ 64 <500000000>;
+- opp-microvolt = <731000>;
+- };
+-
+- opp-667000000 {
+- opp-hz = /bits/ 64 <666666666>;
+- opp-microvolt = <731000>;
+- };
+-
+ opp-1000000000 {
+ opp-hz = /bits/ 64 <1000000000>;
+ opp-microvolt = <731000>;
+--
+2.39.2
+
--- /dev/null
+From 38992ffda70ae56152406f35bcf8389fd5f6006a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Sep 2021 11:42:51 +0800
+Subject: arm64: dts: qcom: Fix IPQ8074 PCIe PHY nodes
+
+From: Shawn Guo <shawn.guo@linaro.org>
+
+[ Upstream commit 942bcd33ed455ad40b71a59901bd926bbf4a500e ]
+
+IPQ8074 PCIe PHY nodes are broken in the many ways:
+
+- '#address-cells', '#size-cells' and 'ranges' are missing.
+- Child phy/lane node is missing, and the child properties like
+ '#phy-cells' and 'clocks' are mistakenly put into parent node.
+- The clocks properties for parent node are missing.
+
+Fix them to get the nodes comply with the bindings schema.
+
+Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20210929034253.24570-9-shawn.guo@linaro.org
+Stable-dep-of: 7ba33591b45f ("arm64: dts: qcom: ipq8074: fix Gen3 PCIe QMP PHY")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/ipq8074.dtsi | 46 +++++++++++++++++++++------
+ 1 file changed, 36 insertions(+), 10 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+index 9114402c044b3..5b17dbefe5cfd 100644
+--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
++++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+@@ -167,34 +167,60 @@ qusb_phy_0: phy@79000 {
+ resets = <&gcc GCC_QUSB2_0_PHY_BCR>;
+ };
+
+- pcie_phy0: phy@86000 {
++ pcie_qmp0: phy@86000 {
+ compatible = "qcom,ipq8074-qmp-pcie-phy";
+ reg = <0x00086000 0x1000>;
+- #phy-cells = <0>;
+- clocks = <&gcc GCC_PCIE0_PIPE_CLK>;
+- clock-names = "pipe_clk";
+- clock-output-names = "pcie20_phy0_pipe_clk";
++ #address-cells = <1>;
++ #size-cells = <1>;
++ ranges;
+
++ clocks = <&gcc GCC_PCIE0_AUX_CLK>,
++ <&gcc GCC_PCIE0_AHB_CLK>;
++ clock-names = "aux", "cfg_ahb";
+ resets = <&gcc GCC_PCIE0_PHY_BCR>,
+ <&gcc GCC_PCIE0PHY_PHY_BCR>;
+ reset-names = "phy",
+ "common";
+ status = "disabled";
++
++ pcie_phy0: phy@86200 {
++ reg = <0x86200 0x16c>,
++ <0x86400 0x200>,
++ <0x86800 0x4f4>;
++ #phy-cells = <0>;
++ #clock-cells = <0>;
++ clocks = <&gcc GCC_PCIE0_PIPE_CLK>;
++ clock-names = "pipe0";
++ clock-output-names = "pcie_0_pipe_clk";
++ };
+ };
+
+- pcie_phy1: phy@8e000 {
++ pcie_qmp1: phy@8e000 {
+ compatible = "qcom,ipq8074-qmp-pcie-phy";
+ reg = <0x0008e000 0x1000>;
+- #phy-cells = <0>;
+- clocks = <&gcc GCC_PCIE1_PIPE_CLK>;
+- clock-names = "pipe_clk";
+- clock-output-names = "pcie20_phy1_pipe_clk";
++ #address-cells = <1>;
++ #size-cells = <1>;
++ ranges;
+
++ clocks = <&gcc GCC_PCIE1_AUX_CLK>,
++ <&gcc GCC_PCIE1_AHB_CLK>;
++ clock-names = "aux", "cfg_ahb";
+ resets = <&gcc GCC_PCIE1_PHY_BCR>,
+ <&gcc GCC_PCIE1PHY_PHY_BCR>;
+ reset-names = "phy",
+ "common";
+ status = "disabled";
++
++ pcie_phy1: phy@8e200 {
++ reg = <0x8e200 0x16c>,
++ <0x8e400 0x200>,
++ <0x8e800 0x4f4>;
++ #phy-cells = <0>;
++ #clock-cells = <0>;
++ clocks = <&gcc GCC_PCIE1_PIPE_CLK>;
++ clock-names = "pipe0";
++ clock-output-names = "pcie_1_pipe_clk";
++ };
+ };
+
+ tlmm: pinctrl@1000000 {
+--
+2.39.2
+
--- /dev/null
+From b26c092edbb3863acd2c2e5924e2fc6594c25383 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Jan 2023 17:44:43 +0100
+Subject: arm64: dts: qcom: ipq8074: correct Gen2 PCIe ranges
+
+From: Robert Marko <robimarko@gmail.com>
+
+[ Upstream commit 2055cb7dccea16bafa3adf9c5e3216949512c34a ]
+
+Current ranges property set in Gen2 PCIe node is incorrect, replace it
+with the downstream 5.4 QCA kernel value.
+
+Fixes: 33057e1672fe ("ARM: dts: ipq8074: Add pcie nodes")
+Signed-off-by: Robert Marko <robimarko@gmail.com>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230113164449.906002-3-robimarko@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/ipq8074.dtsi | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+index 98f0001fc7092..1dbae9c73c590 100644
+--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
++++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+@@ -610,9 +610,9 @@ pcie1: pci@10000000 {
+ phy-names = "pciephy";
+
+ ranges = <0x81000000 0 0x10200000 0x10200000
+- 0 0x100000 /* downstream I/O */
+- 0x82000000 0 0x10300000 0x10300000
+- 0 0xd00000>; /* non-prefetchable memory */
++ 0 0x10000>, /* downstream I/O */
++ <0x82000000 0 0x10220000 0x10220000
++ 0 0xfde0000>; /* non-prefetchable memory */
+
+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi";
+--
+2.39.2
+
--- /dev/null
+From f62e49c178272e2efdf4c5a3ed84c6bd708801bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Jan 2023 17:44:49 +0100
+Subject: arm64: dts: qcom: ipq8074: correct PCIe QMP PHY output clock names
+
+From: Robert Marko <robimarko@gmail.com>
+
+[ Upstream commit 0e8b90c0256cf9c9589e2cee517dedc987a34355 ]
+
+Current PCIe QMP PHY output name were changed in ("arm64: dts: qcom: Fix
+IPQ8074 PCIe PHY nodes") however it did not account for the fact that GCC
+driver is relying on the old names to match them as they are being used as
+the parent for the gcc_pcie0_pipe_clk and gcc_pcie1_pipe_clk.
+
+This broke parenting as GCC could not find the parent clock, so fix it by
+changing to the names that driver is expecting.
+
+Fixes: 942bcd33ed45 ("arm64: dts: qcom: Fix IPQ8074 PCIe PHY nodes")
+Signed-off-by: Robert Marko <robimarko@gmail.com>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230113164449.906002-9-robimarko@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/ipq8074.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+index 4ef364c010125..25f78c71e0105 100644
+--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
++++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+@@ -192,7 +192,7 @@ pcie_phy0: phy@84200 {
+ #clock-cells = <0>;
+ clocks = <&gcc GCC_PCIE0_PIPE_CLK>;
+ clock-names = "pipe0";
+- clock-output-names = "pcie_0_pipe_clk";
++ clock-output-names = "pcie20_phy0_pipe_clk";
+ };
+ };
+
+@@ -220,7 +220,7 @@ pcie_phy1: phy@8e200 {
+ #clock-cells = <0>;
+ clocks = <&gcc GCC_PCIE1_PIPE_CLK>;
+ clock-names = "pipe0";
+- clock-output-names = "pcie_1_pipe_clk";
++ clock-output-names = "pcie20_phy1_pipe_clk";
+ };
+ };
+
+--
+2.39.2
+
--- /dev/null
+From e1f13fe2e4d3d1d0f26dc4addbc0a5ce65cac54b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 Jan 2023 14:04:40 +0100
+Subject: arm64: dts: qcom: ipq8074: correct USB3 QMP PHY-s clock output names
+
+From: Robert Marko <robimarko@gmail.com>
+
+[ Upstream commit 877cff3568c0f54511d77918ae16b2d6e9a0dfce ]
+
+It seems that clock-output-names for the USB3 QMP PHY-s where set without
+actually checking what is the GCC clock driver expecting, so clock core
+could never actually find the parents for usb0_pipe_clk_src and
+usb1_pipe_clk_src clocks in the GCC driver.
+
+So, correct the names to be what the driver expects so that parenting
+works.
+
+Before:
+gcc_usb0_pipe_clk_src 0 0 0 125000000 0 0 50000 Y
+gcc_usb1_pipe_clk_src 0 0 0 125000000 0 0 50000 Y
+
+After:
+ usb3phy_0_cc_pipe_clk 1 1 0 125000000 0 0 50000 Y
+ usb0_pipe_clk_src 1 1 0 125000000 0 0 50000 Y
+ gcc_usb0_pipe_clk 1 1 0 125000000 0 0 50000 Y
+ usb3phy_1_cc_pipe_clk 1 1 0 125000000 0 0 50000 Y
+ usb1_pipe_clk_src 1 1 0 125000000 0 0 50000 Y
+ gcc_usb1_pipe_clk 1 1 0 125000000 0 0 50000 Y
+
+Fixes: 5e09bc51d07b ("arm64: dts: ipq8074: enable USB support")
+Signed-off-by: Robert Marko <robimarko@gmail.com>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230108130440.670181-2-robimarko@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/ipq8074.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+index 99e2488b92dc3..9114402c044b3 100644
+--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
++++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+@@ -108,7 +108,7 @@ usb1_ssphy: lane@58200 {
+ #phy-cells = <0>;
+ clocks = <&gcc GCC_USB1_PIPE_CLK>;
+ clock-names = "pipe0";
+- clock-output-names = "gcc_usb1_pipe_clk_src";
++ clock-output-names = "usb3phy_1_cc_pipe_clk";
+ };
+ };
+
+@@ -151,7 +151,7 @@ usb0_ssphy: lane@78200 {
+ #phy-cells = <0>;
+ clocks = <&gcc GCC_USB0_PIPE_CLK>;
+ clock-names = "pipe0";
+- clock-output-names = "gcc_usb0_pipe_clk_src";
++ clock-output-names = "usb3phy_0_cc_pipe_clk";
+ };
+ };
+
+--
+2.39.2
+
--- /dev/null
+From dc7f1dd99ac0ef14b2483dc1d66da7495d672dd6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Jan 2023 17:44:48 +0100
+Subject: arm64: dts: qcom: ipq8074: fix Gen3 PCIe node
+
+From: Robert Marko <robimarko@gmail.com>
+
+[ Upstream commit 3e83a9c41ab0244a45a4a2800b9adb8de0d15f82 ]
+
+IPQ8074 comes in 2 silicon versions:
+* v1 with 2x Gen2 PCIe ports and QMP PHY-s
+* v2 with 1x Gen3 and 1x Gen2 PCIe ports and QMP PHY-s
+
+v2 is the final and production version that is actually supported by the
+kernel, however it looks like PCIe related nodes were added for the v1 SoC.
+
+Finish the PCIe fixup by using the correct compatible, adding missing ATU
+register space, declaring max-link-speed, use correct ranges, add missing
+clocks and resets.
+
+Fixes: 33057e1672fe ("ARM: dts: ipq8074: Add pcie nodes")
+Signed-off-by: Robert Marko <robimarko@gmail.com>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230113164449.906002-8-robimarko@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/ipq8074.dtsi | 30 +++++++++++++++------------
+ 1 file changed, 17 insertions(+), 13 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+index 1dbae9c73c590..4ef364c010125 100644
+--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
++++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+@@ -655,16 +655,18 @@ IRQ_TYPE_LEVEL_HIGH>, /* int_c */
+ };
+
+ pcie0: pci@20000000 {
+- compatible = "qcom,pcie-ipq8074";
++ compatible = "qcom,pcie-ipq8074-gen3";
+ reg = <0x20000000 0xf1d>,
+ <0x20000f20 0xa8>,
+- <0x00080000 0x2000>,
++ <0x20001000 0x1000>,
++ <0x00080000 0x4000>,
+ <0x20100000 0x1000>;
+- reg-names = "dbi", "elbi", "parf", "config";
++ reg-names = "dbi", "elbi", "atu", "parf", "config";
+ device_type = "pci";
+ linux,pci-domain = <0>;
+ bus-range = <0x00 0xff>;
+ num-lanes = <1>;
++ max-link-speed = <3>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+@@ -672,9 +674,9 @@ pcie0: pci@20000000 {
+ phy-names = "pciephy";
+
+ ranges = <0x81000000 0 0x20200000 0x20200000
+- 0 0x100000 /* downstream I/O */
+- 0x82000000 0 0x20300000 0x20300000
+- 0 0xd00000>; /* non-prefetchable memory */
++ 0 0x10000>, /* downstream I/O */
++ <0x82000000 0 0x20220000 0x20220000
++ 0 0xfde0000>; /* non-prefetchable memory */
+
+ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi";
+@@ -692,28 +694,30 @@ IRQ_TYPE_LEVEL_HIGH>, /* int_c */
+ clocks = <&gcc GCC_SYS_NOC_PCIE0_AXI_CLK>,
+ <&gcc GCC_PCIE0_AXI_M_CLK>,
+ <&gcc GCC_PCIE0_AXI_S_CLK>,
+- <&gcc GCC_PCIE0_AHB_CLK>,
+- <&gcc GCC_PCIE0_AUX_CLK>;
+-
++ <&gcc GCC_PCIE0_AXI_S_BRIDGE_CLK>,
++ <&gcc GCC_PCIE0_RCHNG_CLK>;
+ clock-names = "iface",
+ "axi_m",
+ "axi_s",
+- "ahb",
+- "aux";
++ "axi_bridge",
++ "rchng";
++
+ resets = <&gcc GCC_PCIE0_PIPE_ARES>,
+ <&gcc GCC_PCIE0_SLEEP_ARES>,
+ <&gcc GCC_PCIE0_CORE_STICKY_ARES>,
+ <&gcc GCC_PCIE0_AXI_MASTER_ARES>,
+ <&gcc GCC_PCIE0_AXI_SLAVE_ARES>,
+ <&gcc GCC_PCIE0_AHB_ARES>,
+- <&gcc GCC_PCIE0_AXI_MASTER_STICKY_ARES>;
++ <&gcc GCC_PCIE0_AXI_MASTER_STICKY_ARES>,
++ <&gcc GCC_PCIE0_AXI_SLAVE_STICKY_ARES>;
+ reset-names = "pipe",
+ "sleep",
+ "sticky",
+ "axi_m",
+ "axi_s",
+ "ahb",
+- "axi_m_sticky";
++ "axi_m_sticky",
++ "axi_s_sticky";
+ status = "disabled";
+ };
+ };
+--
+2.39.2
+
--- /dev/null
+From 2440d0ce904d9235310d3bd6b29a888d6ec1de19 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Jan 2023 17:44:42 +0100
+Subject: arm64: dts: qcom: ipq8074: fix Gen3 PCIe QMP PHY
+
+From: Robert Marko <robimarko@gmail.com>
+
+[ Upstream commit 7ba33591b45f9d547a317e42f1c2acd19c925eb6 ]
+
+IPQ8074 comes in 2 silicon versions:
+* v1 with 2x Gen2 PCIe ports and QMP PHY-s
+* v2 with 1x Gen3 and 1x Gen2 PCIe ports and QMP PHY-s
+
+v2 is the final and production version that is actually supported by the
+kernel, however it looks like PCIe related nodes were added for the v1 SoC.
+
+Now that we have Gen3 QMP PHY support, we can start fixing the PCIe support
+by fixing the Gen3 QMP PHY node first.
+
+Change the compatible to the Gen3 QMP PHY, correct the register space start
+and size, add the missing misc PCS register space.
+
+Fixes: 33057e1672fe ("ARM: dts: ipq8074: Add pcie nodes")
+Signed-off-by: Robert Marko <robimarko@gmail.com>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230113164449.906002-2-robimarko@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/ipq8074.dtsi | 15 ++++++++-------
+ 1 file changed, 8 insertions(+), 7 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+index 555f633ef20e0..98f0001fc7092 100644
+--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
++++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+@@ -167,9 +167,9 @@ qusb_phy_0: phy@79000 {
+ resets = <&gcc GCC_QUSB2_0_PHY_BCR>;
+ };
+
+- pcie_qmp0: phy@86000 {
+- compatible = "qcom,ipq8074-qmp-pcie-phy";
+- reg = <0x00086000 0x1c4>;
++ pcie_qmp0: phy@84000 {
++ compatible = "qcom,ipq8074-qmp-gen3-pcie-phy";
++ reg = <0x00084000 0x1bc>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+@@ -183,10 +183,11 @@ pcie_qmp0: phy@86000 {
+ "common";
+ status = "disabled";
+
+- pcie_phy0: phy@86200 {
+- reg = <0x86200 0x16c>,
+- <0x86400 0x200>,
+- <0x86800 0x4f4>;
++ pcie_phy0: phy@84200 {
++ reg = <0x84200 0x16c>,
++ <0x84400 0x200>,
++ <0x84800 0x1f0>,
++ <0x84c00 0xf4>;
+ #phy-cells = <0>;
+ #clock-cells = <0>;
+ clocks = <&gcc GCC_PCIE0_PIPE_CLK>;
+--
+2.39.2
+
--- /dev/null
+From 7ea18d551ca2541752a1644010f739391c524d82 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Sep 2022 16:34:30 +0200
+Subject: arm64: dts: qcom: ipq8074: fix PCIe PHY serdes size
+
+From: Johan Hovold <johan+linaro@kernel.org>
+
+[ Upstream commit ed22cc93abae68f9d3fc4957c20a1d902cf28882 ]
+
+The size of the PCIe PHY serdes register region is 0x1c4 and the
+corresponding 'reg' property should specifically not include the
+adjacent regions that are defined in the child node (e.g. tx and rx).
+
+Fixes: 33057e1672fe ("ARM: dts: ipq8074: Add pcie nodes")
+Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20220915143431.19842-1-johan+linaro@kernel.org
+Stable-dep-of: 7ba33591b45f ("arm64: dts: qcom: ipq8074: fix Gen3 PCIe QMP PHY")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/ipq8074.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+index 5b17dbefe5cfd..555f633ef20e0 100644
+--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
++++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+@@ -169,7 +169,7 @@ qusb_phy_0: phy@79000 {
+
+ pcie_qmp0: phy@86000 {
+ compatible = "qcom,ipq8074-qmp-pcie-phy";
+- reg = <0x00086000 0x1000>;
++ reg = <0x00086000 0x1c4>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+@@ -197,7 +197,7 @@ pcie_phy0: phy@86200 {
+
+ pcie_qmp1: phy@8e000 {
+ compatible = "qcom,ipq8074-qmp-pcie-phy";
+- reg = <0x0008e000 0x1000>;
++ reg = <0x0008e000 0x1c4>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+--
+2.39.2
+
--- /dev/null
+From d4f6e38324f58813e6fc46a101f1605b45e1b641 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Dec 2022 06:21:51 +0200
+Subject: arm64: dts: qcom: qcs404: use symbol names for PCIe resets
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 41a37d157a613444c97e8f71a5fb2a21116b70d7 ]
+
+The commit e5bbbff5b7d7 ("clk: gcc-qcs404: Add PCIe resets") added names
+for PCIe resets, but it did not change the existing qcs404.dtsi to use
+these names. Do it now and use symbol names to make it easier to check
+and modify the dtsi in future.
+
+Fixes: e5bbbff5b7d7 ("clk: gcc-qcs404: Add PCIe resets")
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20221226042154.2666748-14-dmitry.baryshkov@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/qcs404.dtsi | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/qcs404.dtsi b/arch/arm64/boot/dts/qcom/qcs404.dtsi
+index 7bddc5ebc6aa2..d41f068dde167 100644
+--- a/arch/arm64/boot/dts/qcom/qcs404.dtsi
++++ b/arch/arm64/boot/dts/qcom/qcs404.dtsi
+@@ -775,7 +775,7 @@ pcie_phy: phy@7786000 {
+
+ clocks = <&gcc GCC_PCIE_0_PIPE_CLK>;
+ resets = <&gcc GCC_PCIEPHY_0_PHY_BCR>,
+- <&gcc 21>;
++ <&gcc GCC_PCIE_0_PIPE_ARES>;
+ reset-names = "phy", "pipe";
+
+ clock-output-names = "pcie_0_pipe_clk";
+@@ -1305,12 +1305,12 @@ pcie: pci@10000000 {
+ <&gcc GCC_PCIE_0_SLV_AXI_CLK>;
+ clock-names = "iface", "aux", "master_bus", "slave_bus";
+
+- resets = <&gcc 18>,
+- <&gcc 17>,
+- <&gcc 15>,
+- <&gcc 19>,
++ resets = <&gcc GCC_PCIE_0_AXI_MASTER_ARES>,
++ <&gcc GCC_PCIE_0_AXI_SLAVE_ARES>,
++ <&gcc GCC_PCIE_0_AXI_MASTER_STICKY_ARES>,
++ <&gcc GCC_PCIE_0_CORE_STICKY_ARES>,
+ <&gcc GCC_PCIE_0_BCR>,
+- <&gcc 16>;
++ <&gcc GCC_PCIE_0_AHB_ARES>;
+ reset-names = "axi_m",
+ "axi_s",
+ "axi_m_sticky",
+--
+2.39.2
+
--- /dev/null
+From 6d7d4f7402a18f5214ef06e0683966d4a6a715fe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Dec 2022 11:19:17 +0100
+Subject: arm64: dts: qcom: sc7180: correct SPMI bus address cells
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 1f75745537222172f84783d369bbd1fb2d4b6414 ]
+
+The SPMI bus uses two address cells and zero size cells (second reg
+entry - SPMI_USID - is not the size):
+
+ spmi@c440000: #address-cells:0:0: 2 was expected
+
+Fixes: 0f9dc5f09fbd ("arm64: dts: qcom: sc7180: Add SPMI PMIC arbiter device")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Reviewed-by: Stephen Boyd <swboyd@chromium.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20221213101921.47924-1-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sc7180.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi
+index c71f3afc1cc9f..eb07a882d43b3 100644
+--- a/arch/arm64/boot/dts/qcom/sc7180.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi
+@@ -3066,8 +3066,8 @@ spmi_bus: spmi@c440000 {
+ interrupts-extended = <&pdc 1 IRQ_TYPE_LEVEL_HIGH>;
+ qcom,ee = <0>;
+ qcom,channel = <0>;
+- #address-cells = <1>;
+- #size-cells = <1>;
++ #address-cells = <2>;
++ #size-cells = <0>;
+ interrupt-controller;
+ #interrupt-cells = <4>;
+ cell-index = <0>;
+--
+2.39.2
+
--- /dev/null
+From 979850ca0aaf0e0d81b0b276d1c4e7b9148467c7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Dec 2022 16:13:16 +0100
+Subject: arm64: dts: qcom: sdm845-db845c: fix audio codec interrupt pin name
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 740862bb5f59b93efb390a417995f88a64bdc323 ]
+
+The pin config entry should have a string, not number, for the GPIO used
+as WCD9340 audio codec interrupt.
+
+Fixes: 89a32a4e769c ("arm64: dts: qcom: db845c: add analog audio support")
+Reported-by: Doug Anderson <dianders@chromium.org>
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20221222151319.122398-1-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sdm845-db845c.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
+index c6691bdc81002..1e889ca932e41 100644
+--- a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
++++ b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
+@@ -896,7 +896,7 @@ sdc2_card_det_n: sd-card-det-n {
+ };
+
+ wcd_intr_default: wcd_intr_default {
+- pins = <54>;
++ pins = "gpio54";
+ function = "gpio";
+
+ input-enable;
+--
+2.39.2
+
--- /dev/null
+From b12fb63af3e3afac880f2e7cf2f0ddecde354a4f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 14 Jan 2023 16:56:45 -0600
+Subject: arm64: dts: renesas: beacon-renesom: Fix gpio expander reference
+
+From: Adam Ford <aford173@gmail.com>
+
+[ Upstream commit d7f9492dfc03153ac56ab59066a196558748f575 ]
+
+The board used to originally introduce the Beacon Embedded RZ/G2[M/N/H]
+boards had a GPIO expander with address 20, but this was changed when
+the final board went to production.
+
+The production boards changed both the part itself and the address.
+With the incorrect address, the LCD cannot come up. If the LCD fails,
+the rcar-du driver fails to come up, and that also breaks HDMI.
+
+Pre-release board were not shipped to the general public, so it should
+be safe to push this as a fix. Anyone with a production board would
+have video fail due to this GPIO expander change.
+
+Fixes: a1d8a344f1ca ("arm64: dts: renesas: Introduce r8a774a1-beacon-rzg2m-kit")
+Signed-off-by: Adam Ford <aford173@gmail.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/20230114225647.227972-1-aford173@gmail.com
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../dts/renesas/beacon-renesom-baseboard.dtsi | 24 ++++++++-----------
+ 1 file changed, 10 insertions(+), 14 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi b/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi
+index 53e1d43cbecf8..663adf79471bc 100644
+--- a/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi
++++ b/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi
+@@ -399,20 +399,6 @@ wm8962_endpoint: endpoint {
+ };
+ };
+
+- /* 0 - lcd_reset */
+- /* 1 - lcd_pwr */
+- /* 2 - lcd_select */
+- /* 3 - backlight-enable */
+- /* 4 - Touch_shdwn */
+- /* 5 - LCD_H_pol */
+- /* 6 - lcd_V_pol */
+- gpio_exp1: gpio@20 {
+- compatible = "onnn,pca9654";
+- reg = <0x20>;
+- gpio-controller;
+- #gpio-cells = <2>;
+- };
+-
+ touchscreen@26 {
+ compatible = "ilitek,ili2117";
+ reg = <0x26>;
+@@ -445,6 +431,16 @@ hd3ss3220_ep: endpoint {
+ };
+ };
+ };
++
++ gpio_exp1: gpio@70 {
++ compatible = "nxp,pca9538";
++ reg = <0x70>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ gpio-line-names = "lcd_reset", "lcd_pwr", "lcd_select",
++ "backlight-enable", "Touch_shdwn",
++ "LCD_H_pol", "lcd_V_pol";
++ };
+ };
+
+ &lvds0 {
+--
+2.39.2
+
--- /dev/null
+From 65bd849e7eb43bb8fd319faf4cc4441a66bd7b9e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 19 Jan 2023 09:56:22 +0530
+Subject: arm64: dts: ti: k3-j7200: Fix wakeup pinmux range
+
+From: Vaishnav Achath <vaishnav.a@ti.com>
+
+[ Upstream commit 9ae21ac445e911e3541985c20052fc05d60f6879 ]
+
+The WKUP_PADCONFIG register region in J7200 has multiple non-addressable
+regions, split the existing wkup_pmx region as follows to avoid the
+non-addressable regions and include all valid WKUP_PADCONFIG registers.
+Also update references to old nodes with new ones.
+
+wkup_pmx0 -> 13 pins (WKUP_PADCONFIG 0 - 12)
+wkup_pmx1 -> 2 pins (WKUP_PADCONFIG 14 - 15)
+wkup_pmx2 -> 59 pins (WKUP_PADCONFIG 26 - 84)
+wkup_pmx3 -> 8 pins (WKUP_PADCONFIG 93 - 100)
+
+J7200 Datasheet (Table 6-106, Section 6.4 Pin Multiplexing) :
+ https://www.ti.com/lit/ds/symlink/dra821u.pdf
+
+Fixes: d361ed88455f ("arm64: dts: ti: Add support for J7200 SoC")
+
+Signed-off-by: Vaishnav Achath <vaishnav.a@ti.com>
+Reviewed-by: Jayesh Choudhary <j-choudhary@ti.com>
+Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
+Link: https://lore.kernel.org/r/20230119042622.22310-1-vaishnav.a@ti.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../dts/ti/k3-j7200-common-proc-board.dts | 2 +-
+ .../boot/dts/ti/k3-j7200-mcu-wakeup.dtsi | 29 ++++++++++++++++++-
+ 2 files changed, 29 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
+index e8a4143e1c241..909ab6661aef5 100644
+--- a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
++++ b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
+@@ -16,7 +16,7 @@ chosen {
+ };
+ };
+
+-&wkup_pmx0 {
++&wkup_pmx2 {
+ mcu_cpsw_pins_default: mcu-cpsw-pins-default {
+ pinctrl-single,pins = <
+ J721E_WKUP_IOPAD(0x0068, PIN_OUTPUT, 0) /* MCU_RGMII1_TX_CTL */
+diff --git a/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi
+index eb2a78a53512c..7f252cc6eb379 100644
+--- a/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi
++++ b/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi
+@@ -56,7 +56,34 @@ chipid@43000014 {
+ wkup_pmx0: pinctrl@4301c000 {
+ compatible = "pinctrl-single";
+ /* Proxy 0 addressing */
+- reg = <0x00 0x4301c000 0x00 0x178>;
++ reg = <0x00 0x4301c000 0x00 0x34>;
++ #pinctrl-cells = <1>;
++ pinctrl-single,register-width = <32>;
++ pinctrl-single,function-mask = <0xffffffff>;
++ };
++
++ wkup_pmx1: pinctrl@0x4301c038 {
++ compatible = "pinctrl-single";
++ /* Proxy 0 addressing */
++ reg = <0x00 0x4301c038 0x00 0x8>;
++ #pinctrl-cells = <1>;
++ pinctrl-single,register-width = <32>;
++ pinctrl-single,function-mask = <0xffffffff>;
++ };
++
++ wkup_pmx2: pinctrl@0x4301c068 {
++ compatible = "pinctrl-single";
++ /* Proxy 0 addressing */
++ reg = <0x00 0x4301c068 0x00 0xec>;
++ #pinctrl-cells = <1>;
++ pinctrl-single,register-width = <32>;
++ pinctrl-single,function-mask = <0xffffffff>;
++ };
++
++ wkup_pmx3: pinctrl@0x4301c174 {
++ compatible = "pinctrl-single";
++ /* Proxy 0 addressing */
++ reg = <0x00 0x4301c174 0x00 0x20>;
+ #pinctrl-cells = <1>;
+ pinctrl-single,register-width = <32>;
+ pinctrl-single,function-mask = <0xffffffff>;
+--
+2.39.2
+
--- /dev/null
+From cc6e8b77b713ab2b5641840cfe68d522118e707a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Jul 2021 18:02:30 +0800
+Subject: ASoC: atmel: fix spelling mistakes
+
+From: Gu Shengxian <gushengxian@yulong.com>
+
+[ Upstream commit 55233b22502151e0b2d9cc599e1ddf1f5584c87a ]
+
+Fix some spelling mistakes as follows:
+regaedles ==> regardless
+prezent ==> present
+underrrun ==> underrun
+controlls ==> controls
+
+Signed-off-by: Gu Shengxian <gushengxian@yulong.com>
+Link: https://lore.kernel.org/r/20210706100230.32633-1-gushengxian507419@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: a4c4161d6eae ("ASoC: mchp-spdifrx: fix return value in case completion times out")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/atmel/mchp-spdifrx.c | 6 +++---
+ sound/soc/atmel/mchp-spdiftx.c | 2 +-
+ sound/soc/atmel/tse850-pcm5142.c | 2 +-
+ 3 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/sound/soc/atmel/mchp-spdifrx.c b/sound/soc/atmel/mchp-spdifrx.c
+index c83f32a462f63..3962ce00ad34a 100644
+--- a/sound/soc/atmel/mchp-spdifrx.c
++++ b/sound/soc/atmel/mchp-spdifrx.c
+@@ -56,7 +56,7 @@
+ /* Validity Bit Mode */
+ #define SPDIFRX_MR_VBMODE_MASK GENAMSK(1, 1)
+ #define SPDIFRX_MR_VBMODE_ALWAYS_LOAD \
+- (0 << 1) /* Load sample regardles of validity bit value */
++ (0 << 1) /* Load sample regardless of validity bit value */
+ #define SPDIFRX_MR_VBMODE_DISCARD_IF_VB1 \
+ (1 << 1) /* Load sample only if validity bit is 0 */
+
+@@ -523,7 +523,7 @@ static int mchp_spdifrx_cs_get(struct mchp_spdifrx_dev *dev,
+ /* check for new data available */
+ ret = wait_for_completion_interruptible_timeout(&ch_stat->done,
+ msecs_to_jiffies(100));
+- /* IP might not be started or valid stream might not be prezent */
++ /* IP might not be started or valid stream might not be present */
+ if (ret < 0) {
+ dev_dbg(dev->dev, "channel status for channel %d timeout\n",
+ channel);
+@@ -575,7 +575,7 @@ static int mchp_spdifrx_subcode_ch_get(struct mchp_spdifrx_dev *dev,
+ mchp_spdifrx_isr_blockend_en(dev);
+ ret = wait_for_completion_interruptible_timeout(&user_data->done,
+ msecs_to_jiffies(100));
+- /* IP might not be started or valid stream might not be prezent */
++ /* IP might not be started or valid stream might not be present */
+ if (ret <= 0) {
+ dev_dbg(dev->dev, "user data for channel %d timeout\n",
+ channel);
+diff --git a/sound/soc/atmel/mchp-spdiftx.c b/sound/soc/atmel/mchp-spdiftx.c
+index 0d2e3fa21519c..bcca1cf3cd7b6 100644
+--- a/sound/soc/atmel/mchp-spdiftx.c
++++ b/sound/soc/atmel/mchp-spdiftx.c
+@@ -80,7 +80,7 @@
+ #define SPDIFTX_MR_VALID1 BIT(24)
+ #define SPDIFTX_MR_VALID2 BIT(25)
+
+-/* Disable Null Frame on underrrun */
++/* Disable Null Frame on underrun */
+ #define SPDIFTX_MR_DNFR_MASK GENMASK(27, 27)
+ #define SPDIFTX_MR_DNFR_INVALID (0 << 27)
+ #define SPDIFTX_MR_DNFR_VALID (1 << 27)
+diff --git a/sound/soc/atmel/tse850-pcm5142.c b/sound/soc/atmel/tse850-pcm5142.c
+index 59e2edb22b3ad..50c3dc6936f90 100644
+--- a/sound/soc/atmel/tse850-pcm5142.c
++++ b/sound/soc/atmel/tse850-pcm5142.c
+@@ -23,7 +23,7 @@
+ // IN2 +---o--+------------+--o---+ OUT2
+ // loop2 relays
+ //
+-// The 'loop1' gpio pin controlls two relays, which are either in loop
++// The 'loop1' gpio pin controls two relays, which are either in loop
+ // position, meaning that input and output are directly connected, or
+ // they are in mixer position, meaning that the signal is passed through
+ // the 'Sum' mixer. Similarly for 'loop2'.
+--
+2.39.2
+
--- /dev/null
+From ac96eabd0c81d5ee2a96057101cdae6927a7ca18 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Feb 2023 19:36:46 +0100
+Subject: ASoC: dt-bindings: meson: fix gx-card codec node regex
+
+From: Jerome Brunet <jbrunet@baylibre.com>
+
+[ Upstream commit 480b26226873c88e482575ceb0d0a38d76e1be57 ]
+
+'codec' is a valid node name when there is a single codec
+in the link. Fix the node regular expression to apply this.
+
+Fixes: fd00366b8e41 ("ASoC: meson: gx: add sound card dt-binding documentation")
+Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20230202183653.486216-3-jbrunet@baylibre.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../devicetree/bindings/sound/amlogic,gx-sound-card.yaml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml b/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml
+index 2e35aeaa8781d..89e3819c6127a 100644
+--- a/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml
++++ b/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml
+@@ -61,7 +61,7 @@ patternProperties:
+ description: phandle of the CPU DAI
+
+ patternProperties:
+- "^codec-[0-9]+$":
++ "^codec(-[0-9]+)?$":
+ type: object
+ description: |-
+ Codecs:
+--
+2.39.2
+
--- /dev/null
+From 217693601d30d6ad6f3c323b01b82ea8b18d8f66 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Jan 2023 15:07:54 +0800
+Subject: ASoC: fsl_sai: initialize is_dsp_mode flag
+
+From: Shengjiu Wang <shengjiu.wang@nxp.com>
+
+[ Upstream commit a23924b7dd7b748fff8e305e1daf590fed2af21b ]
+
+Initialize is_dsp_mode flag in the beginning of function
+fsl_sai_set_dai_fmt_tr().
+
+When the DAIFMT is DAIFMT_DSP_B the first time, is_dsp_mode is
+true, then the second time DAIFMT is DAIFMT_I2S, is_dsp_mode
+still true, which is a wrong state. So need to initialize
+is_dsp_mode flag every time.
+
+Fixes: a3f7dcc9cc03 ("ASoC: fsl-sai: Add SND_SOC_DAIFMT_DSP_A/B support.")
+Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
+Reviewed-by: Iuliana Prodan <iuliana.prodan@nxp.com>
+Link: https://lore.kernel.org/r/1673852874-32200-1-git-send-email-shengjiu.wang@nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/fsl/fsl_sai.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
+index 3e5c1eaccd5e7..6a5d2b08e2713 100644
+--- a/sound/soc/fsl/fsl_sai.c
++++ b/sound/soc/fsl/fsl_sai.c
+@@ -230,6 +230,7 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai,
+ if (!sai->is_lsb_first)
+ val_cr4 |= FSL_SAI_CR4_MF;
+
++ sai->is_dsp_mode = false;
+ /* DAI mode */
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+--
+2.39.2
+
--- /dev/null
+From 00041fc4b45810462ff66baaee8b9a268da9aedf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 27 Jan 2023 14:41:29 -0800
+Subject: ASoC: kirkwood: Iterate over array indexes instead of using pointer
+ math
+
+From: Kees Cook <keescook@chromium.org>
+
+[ Upstream commit b3bcedc0402fcdc5c8624c433562d9d1882749d8 ]
+
+Walking the dram->cs array was seen as accesses beyond the first array
+item by the compiler. Instead, use the array index directly. This allows
+for run-time bounds checking under CONFIG_UBSAN_BOUNDS as well. Seen
+with GCC 13 with -fstrict-flex-arrays:
+
+../sound/soc/kirkwood/kirkwood-dma.c: In function
+'kirkwood_dma_conf_mbus_windows.constprop':
+../sound/soc/kirkwood/kirkwood-dma.c:90:24: warning: array subscript 0 is outside array bounds of 'const struct mbus_dram_window[0]' [-Warray-bounds=]
+ 90 | if ((cs->base & 0xffff0000) < (dma & 0xffff0000)) {
+ | ~~^~~~~~
+
+Cc: Liam Girdwood <lgirdwood@gmail.com>
+Cc: Mark Brown <broonie@kernel.org>
+Cc: Jaroslav Kysela <perex@perex.cz>
+Cc: Takashi Iwai <tiwai@suse.com>
+Cc: alsa-devel@alsa-project.org
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Link: https://lore.kernel.org/r/20230127224128.never.410-kees@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/kirkwood/kirkwood-dma.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/kirkwood/kirkwood-dma.c b/sound/soc/kirkwood/kirkwood-dma.c
+index e037826b24517..2d41e6ab2ce4e 100644
+--- a/sound/soc/kirkwood/kirkwood-dma.c
++++ b/sound/soc/kirkwood/kirkwood-dma.c
+@@ -86,7 +86,7 @@ kirkwood_dma_conf_mbus_windows(void __iomem *base, int win,
+
+ /* try to find matching cs for current dma address */
+ for (i = 0; i < dram->num_cs; i++) {
+- const struct mbus_dram_window *cs = dram->cs + i;
++ const struct mbus_dram_window *cs = &dram->cs[i];
+ if ((cs->base & 0xffff0000) < (dma & 0xffff0000)) {
+ writel(cs->base & 0xffff0000,
+ base + KIRKWOOD_AUDIO_WIN_BASE_REG(win));
+--
+2.39.2
+
--- /dev/null
+From e8e6aacb567baacddd7d76c2f94595883fdbfdd9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 Jan 2023 14:06:43 +0200
+Subject: ASoC: mchp-spdifrx: disable all interrupts in
+ mchp_spdifrx_dai_remove()
+
+From: Claudiu Beznea <claudiu.beznea@microchip.com>
+
+[ Upstream commit aaecdc32b7e35b4f9b457fb3509414aa9a932589 ]
+
+CSC interrupts which might be used in controls are on bits 8 and 9 of
+SPDIFRX_IDR register. Thus disable all the interrupts that are exported
+by driver.
+
+Fixes: ef265c55c1ac ("ASoC: mchp-spdifrx: add driver for SPDIF RX")
+Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
+Link: https://lore.kernel.org/r/20230130120647.638049-5-claudiu.beznea@microchip.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/atmel/mchp-spdifrx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/atmel/mchp-spdifrx.c b/sound/soc/atmel/mchp-spdifrx.c
+index eb1b8724e11f4..03b7037239b85 100644
+--- a/sound/soc/atmel/mchp-spdifrx.c
++++ b/sound/soc/atmel/mchp-spdifrx.c
+@@ -921,7 +921,7 @@ static int mchp_spdifrx_dai_remove(struct snd_soc_dai *dai)
+ struct mchp_spdifrx_dev *dev = snd_soc_dai_get_drvdata(dai);
+
+ /* Disable interrupts */
+- regmap_write(dev->regmap, SPDIFRX_IDR, 0xFF);
++ regmap_write(dev->regmap, SPDIFRX_IDR, GENMASK(14, 0));
+
+ clk_disable_unprepare(dev->pclk);
+
+--
+2.39.2
+
--- /dev/null
+From 166d143ab8ddfe9c7e21b0ff3b7b406e26635b7a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 Jan 2023 14:06:42 +0200
+Subject: ASoC: mchp-spdifrx: fix controls that works with completion mechanism
+
+From: Claudiu Beznea <claudiu.beznea@microchip.com>
+
+[ Upstream commit d3681df44e856aab523a6eb7ba15b5e41efcbb1c ]
+
+Channel status get and channel subcode get controls relies on data
+returned by controls when certain IRQs are raised. To achieve that
+completions are used b/w controls and interrupt service routine. The
+concurrent accesses to these controls are protected by
+struct snd_card::controls_rwsem.
+
+Issues identified:
+- reinit_completion() may be called while waiting for completion
+ which should be avoided
+- in case of multiple threads waiting, the complete() call in interrupt
+ will signal only one waiting thread per interrupt which may lead to
+ timeout for the others
+- in case of channel status get as the CSC interrupt is not refcounted
+ ISR may disable interrupt for threads that were just enabled it.
+
+To solve these the access to controls were protected by a mutex. Along
+with this there is no need for spinlock to protect the software cache
+reads/updates b/w controls and ISR as the update is happening only when
+requested from control, and only one reader can reach the control.
+
+Fixes: ef265c55c1ac ("ASoC: mchp-spdifrx: add driver for SPDIF RX")
+Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
+Link: https://lore.kernel.org/r/20230130120647.638049-4-claudiu.beznea@microchip.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/atmel/mchp-spdifrx.c | 143 ++++++++++++++++++---------------
+ 1 file changed, 77 insertions(+), 66 deletions(-)
+
+diff --git a/sound/soc/atmel/mchp-spdifrx.c b/sound/soc/atmel/mchp-spdifrx.c
+index 076a78fd0b125..eb1b8724e11f4 100644
+--- a/sound/soc/atmel/mchp-spdifrx.c
++++ b/sound/soc/atmel/mchp-spdifrx.c
+@@ -217,7 +217,6 @@ struct mchp_spdifrx_ch_stat {
+ struct mchp_spdifrx_user_data {
+ unsigned char data[SPDIFRX_UD_BITS / 8];
+ struct completion done;
+- spinlock_t lock; /* protect access to user data */
+ };
+
+ struct mchp_spdifrx_mixer_control {
+@@ -231,8 +230,6 @@ struct mchp_spdifrx_mixer_control {
+ struct mchp_spdifrx_dev {
+ struct snd_dmaengine_dai_dma_data capture;
+ struct mchp_spdifrx_mixer_control control;
+- spinlock_t blockend_lock; /* protect access to blockend_refcount */
+- int blockend_refcount;
+ struct mutex mlock;
+ struct device *dev;
+ struct regmap *regmap;
+@@ -277,37 +274,11 @@ static void mchp_spdifrx_channel_user_data_read(struct mchp_spdifrx_dev *dev,
+ }
+ }
+
+-/* called from non-atomic context only */
+-static void mchp_spdifrx_isr_blockend_en(struct mchp_spdifrx_dev *dev)
+-{
+- unsigned long flags;
+-
+- spin_lock_irqsave(&dev->blockend_lock, flags);
+- dev->blockend_refcount++;
+- /* don't enable BLOCKEND interrupt if it's already enabled */
+- if (dev->blockend_refcount == 1)
+- regmap_write(dev->regmap, SPDIFRX_IER, SPDIFRX_IR_BLOCKEND);
+- spin_unlock_irqrestore(&dev->blockend_lock, flags);
+-}
+-
+-/* called from atomic/non-atomic context */
+-static void mchp_spdifrx_isr_blockend_dis(struct mchp_spdifrx_dev *dev)
+-{
+- unsigned long flags;
+-
+- spin_lock_irqsave(&dev->blockend_lock, flags);
+- dev->blockend_refcount--;
+- /* don't enable BLOCKEND interrupt if it's already enabled */
+- if (dev->blockend_refcount == 0)
+- regmap_write(dev->regmap, SPDIFRX_IDR, SPDIFRX_IR_BLOCKEND);
+- spin_unlock_irqrestore(&dev->blockend_lock, flags);
+-}
+-
+ static irqreturn_t mchp_spdif_interrupt(int irq, void *dev_id)
+ {
+ struct mchp_spdifrx_dev *dev = dev_id;
+ struct mchp_spdifrx_mixer_control *ctrl = &dev->control;
+- u32 sr, imr, pending, idr = 0;
++ u32 sr, imr, pending;
+ irqreturn_t ret = IRQ_NONE;
+ int ch;
+
+@@ -322,13 +293,10 @@ static irqreturn_t mchp_spdif_interrupt(int irq, void *dev_id)
+
+ if (pending & SPDIFRX_IR_BLOCKEND) {
+ for (ch = 0; ch < SPDIFRX_CHANNELS; ch++) {
+- spin_lock(&ctrl->user_data[ch].lock);
+ mchp_spdifrx_channel_user_data_read(dev, ch);
+- spin_unlock(&ctrl->user_data[ch].lock);
+-
+ complete(&ctrl->user_data[ch].done);
+ }
+- mchp_spdifrx_isr_blockend_dis(dev);
++ regmap_write(dev->regmap, SPDIFRX_IDR, SPDIFRX_IR_BLOCKEND);
+ ret = IRQ_HANDLED;
+ }
+
+@@ -336,7 +304,7 @@ static irqreturn_t mchp_spdif_interrupt(int irq, void *dev_id)
+ if (pending & SPDIFRX_IR_CSC(ch)) {
+ mchp_spdifrx_channel_status_read(dev, ch);
+ complete(&ctrl->ch_stat[ch].done);
+- idr |= SPDIFRX_IR_CSC(ch);
++ regmap_write(dev->regmap, SPDIFRX_IDR, SPDIFRX_IR_CSC(ch));
+ ret = IRQ_HANDLED;
+ }
+ }
+@@ -346,8 +314,6 @@ static irqreturn_t mchp_spdif_interrupt(int irq, void *dev_id)
+ ret = IRQ_HANDLED;
+ }
+
+- regmap_write(dev->regmap, SPDIFRX_IDR, idr);
+-
+ return ret;
+ }
+
+@@ -517,23 +483,51 @@ static int mchp_spdifrx_cs_get(struct mchp_spdifrx_dev *dev,
+ {
+ struct mchp_spdifrx_mixer_control *ctrl = &dev->control;
+ struct mchp_spdifrx_ch_stat *ch_stat = &ctrl->ch_stat[channel];
+- int ret;
++ int ret = 0;
++
++ mutex_lock(&dev->mlock);
+
+- regmap_write(dev->regmap, SPDIFRX_IER, SPDIFRX_IR_CSC(channel));
+- /* check for new data available */
+- ret = wait_for_completion_interruptible_timeout(&ch_stat->done,
+- msecs_to_jiffies(100));
+- /* IP might not be started or valid stream might not be present */
+- if (ret <= 0) {
+- dev_dbg(dev->dev, "channel status for channel %d timeout\n",
+- channel);
+- return ret ? : -ETIMEDOUT;
++ /*
++ * We may reach this point with both clocks enabled but the receiver
++ * still disabled. To void waiting for completion and return with
++ * timeout check the dev->trigger_enabled.
++ *
++ * To retrieve data:
++ * - if the receiver is enabled CSC IRQ will update the data in software
++ * caches (ch_stat->data)
++ * - otherwise we just update it here the software caches with latest
++ * available information and return it; in this case we don't need
++ * spin locking as the IRQ is disabled and will not be raised from
++ * anywhere else.
++ */
++
++ if (dev->trigger_enabled) {
++ reinit_completion(&ch_stat->done);
++ regmap_write(dev->regmap, SPDIFRX_IER, SPDIFRX_IR_CSC(channel));
++ /* Check for new data available */
++ ret = wait_for_completion_interruptible_timeout(&ch_stat->done,
++ msecs_to_jiffies(100));
++ /* Valid stream might not be present */
++ if (ret <= 0) {
++ dev_dbg(dev->dev, "channel status for channel %d timeout\n",
++ channel);
++ regmap_write(dev->regmap, SPDIFRX_IDR, SPDIFRX_IR_CSC(channel));
++ ret = ret ? : -ETIMEDOUT;
++ goto unlock;
++ } else {
++ ret = 0;
++ }
++ } else {
++ /* Update software cache with latest channel status. */
++ mchp_spdifrx_channel_status_read(dev, channel);
+ }
+
+ memcpy(uvalue->value.iec958.status, ch_stat->data,
+ sizeof(ch_stat->data));
+
+- return 0;
++unlock:
++ mutex_unlock(&dev->mlock);
++ return ret;
+ }
+
+ static int mchp_spdifrx_cs1_get(struct snd_kcontrol *kcontrol,
+@@ -567,29 +561,49 @@ static int mchp_spdifrx_subcode_ch_get(struct mchp_spdifrx_dev *dev,
+ int channel,
+ struct snd_ctl_elem_value *uvalue)
+ {
+- unsigned long flags;
+ struct mchp_spdifrx_mixer_control *ctrl = &dev->control;
+ struct mchp_spdifrx_user_data *user_data = &ctrl->user_data[channel];
+- int ret;
++ int ret = 0;
++
++ mutex_lock(&dev->mlock);
++
++ /*
++ * We may reach this point with both clocks enabled but the receiver
++ * still disabled. To void waiting for completion to just timeout we
++ * check here the dev->trigger_enabled flag.
++ *
++ * To retrieve data:
++ * - if the receiver is enabled we need to wait for blockend IRQ to read
++ * data to and update it for us in software caches
++ * - otherwise reading the SPDIFRX_CHUD() registers is enough.
++ */
+
+- reinit_completion(&user_data->done);
+- mchp_spdifrx_isr_blockend_en(dev);
+- ret = wait_for_completion_interruptible_timeout(&user_data->done,
+- msecs_to_jiffies(100));
+- /* IP might not be started or valid stream might not be present */
+- if (ret <= 0) {
+- dev_dbg(dev->dev, "user data for channel %d timeout\n",
+- channel);
+- mchp_spdifrx_isr_blockend_dis(dev);
+- return ret ? : -ETIMEDOUT;
++ if (dev->trigger_enabled) {
++ reinit_completion(&user_data->done);
++ regmap_write(dev->regmap, SPDIFRX_IER, SPDIFRX_IR_BLOCKEND);
++ ret = wait_for_completion_interruptible_timeout(&user_data->done,
++ msecs_to_jiffies(100));
++ /* Valid stream might not be present. */
++ if (ret <= 0) {
++ dev_dbg(dev->dev, "user data for channel %d timeout\n",
++ channel);
++ regmap_write(dev->regmap, SPDIFRX_IDR, SPDIFRX_IR_BLOCKEND);
++ ret = ret ? : -ETIMEDOUT;
++ goto unlock;
++ } else {
++ ret = 0;
++ }
++ } else {
++ /* Update software cache with last available data. */
++ mchp_spdifrx_channel_user_data_read(dev, channel);
+ }
+
+- spin_lock_irqsave(&user_data->lock, flags);
+ memcpy(uvalue->value.iec958.subcode, user_data->data,
+ sizeof(user_data->data));
+- spin_unlock_irqrestore(&user_data->lock, flags);
+
+- return 0;
++unlock:
++ mutex_unlock(&dev->mlock);
++ return ret;
+ }
+
+ static int mchp_spdifrx_subcode_ch1_get(struct snd_kcontrol *kcontrol,
+@@ -890,11 +904,9 @@ static int mchp_spdifrx_dai_probe(struct snd_soc_dai *dai)
+ SPDIFRX_MR_AUTORST_NOACTION |
+ SPDIFRX_MR_PACK_DISABLED);
+
+- dev->blockend_refcount = 0;
+ for (ch = 0; ch < SPDIFRX_CHANNELS; ch++) {
+ init_completion(&ctrl->ch_stat[ch].done);
+ init_completion(&ctrl->user_data[ch].done);
+- spin_lock_init(&ctrl->user_data[ch].lock);
+ }
+
+ /* Add controls */
+@@ -1004,7 +1016,6 @@ static int mchp_spdifrx_probe(struct platform_device *pdev)
+ */
+ clk_set_min_rate(dev->gclk, 48000 * SPDIFRX_GCLK_RATIO_MIN + 1);
+
+- spin_lock_init(&dev->blockend_lock);
+ mutex_init(&dev->mlock);
+
+ dev->dev = &pdev->dev;
+--
+2.39.2
+
--- /dev/null
+From b9ae7dfc1db1fed4c987d398aee3d835d9a6c464 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 Jan 2023 14:06:40 +0200
+Subject: ASoC: mchp-spdifrx: fix controls which rely on rsr register
+
+From: Claudiu Beznea <claudiu.beznea@microchip.com>
+
+[ Upstream commit fa09fa60385abbf99342494b280da8b4aebbc0e9 ]
+
+The SPDIFRX block is clocked by 2 clocks: peripheral and generic clocks.
+Peripheral clock feeds user interface (registers) and generic clock feeds
+the receiver.
+
+To enable the receiver the generic clock needs to be enabled and also the
+ENABLE bit of MCHP_SPDIFRX_MR register need to be set.
+
+The signal control exported by mchp-spdifrx driver reports wrong status
+when the receiver is disabled. This can happen when requesting the signal
+and the capture was not previously started. To solve this the receiver
+needs to be enabled (by enabling generic clock and setting ENABLE bit of
+MR register) before reading the signal status.
+
+As with this fix there are 2 paths now that need to control the generic
+clock and ENABLE bit of SPDIFRX_MR register (one path though controls, one
+path though configuration) a mutex has been introduced. We can't rely on
+subsystem locking as the controls are protected by
+struct snd_card::controls_rwsem semaphore and configuration is protected
+by a different lock (embedded in snd_pcm_stream_lock_irq()).
+
+The introduction of mutex is also extended to other controls which rely on
+SPDIFRX_RSR.ULOCK bit as it has been discovered experimentally that having
+both clocks enabled but not the receiver (through ENABLE bit of SPDIFRX.MR)
+leads to inconsistent values of SPDIFRX_RSR.ULOCK. Thus on some controls we
+rely on software state (dev->trigger_enabled protected by mutex) to
+retrieve proper values.
+
+Fixes: ef265c55c1ac ("ASoC: mchp-spdifrx: add driver for SPDIF RX")
+Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
+Link: https://lore.kernel.org/r/20230130120647.638049-2-claudiu.beznea@microchip.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/atmel/mchp-spdifrx.c | 192 ++++++++++++++++++++++++---------
+ 1 file changed, 142 insertions(+), 50 deletions(-)
+
+diff --git a/sound/soc/atmel/mchp-spdifrx.c b/sound/soc/atmel/mchp-spdifrx.c
+index 46f3407ed0e81..c83f32a462f63 100644
+--- a/sound/soc/atmel/mchp-spdifrx.c
++++ b/sound/soc/atmel/mchp-spdifrx.c
+@@ -233,11 +233,13 @@ struct mchp_spdifrx_dev {
+ struct mchp_spdifrx_mixer_control control;
+ spinlock_t blockend_lock; /* protect access to blockend_refcount */
+ int blockend_refcount;
++ struct mutex mlock;
+ struct device *dev;
+ struct regmap *regmap;
+ struct clk *pclk;
+ struct clk *gclk;
+ unsigned int fmt;
++ unsigned int trigger_enabled;
+ unsigned int gclk_enabled:1;
+ };
+
+@@ -353,47 +355,40 @@ static int mchp_spdifrx_trigger(struct snd_pcm_substream *substream, int cmd,
+ struct snd_soc_dai *dai)
+ {
+ struct mchp_spdifrx_dev *dev = snd_soc_dai_get_drvdata(dai);
+- u32 mr;
+- int running;
+- int ret;
+-
+- regmap_read(dev->regmap, SPDIFRX_MR, &mr);
+- running = !!(mr & SPDIFRX_MR_RXEN_ENABLE);
++ int ret = 0;
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+- if (!running) {
+- mr &= ~SPDIFRX_MR_RXEN_MASK;
+- mr |= SPDIFRX_MR_RXEN_ENABLE;
+- /* enable overrun interrupts */
+- regmap_write(dev->regmap, SPDIFRX_IER,
+- SPDIFRX_IR_OVERRUN);
+- }
++ mutex_lock(&dev->mlock);
++ /* Enable overrun interrupts */
++ regmap_write(dev->regmap, SPDIFRX_IER, SPDIFRX_IR_OVERRUN);
++
++ /* Enable receiver. */
++ regmap_update_bits(dev->regmap, SPDIFRX_MR, SPDIFRX_MR_RXEN_MASK,
++ SPDIFRX_MR_RXEN_ENABLE);
++ dev->trigger_enabled = true;
++ mutex_unlock(&dev->mlock);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+- if (running) {
+- mr &= ~SPDIFRX_MR_RXEN_MASK;
+- mr |= SPDIFRX_MR_RXEN_DISABLE;
+- /* disable overrun interrupts */
+- regmap_write(dev->regmap, SPDIFRX_IDR,
+- SPDIFRX_IR_OVERRUN);
+- }
++ mutex_lock(&dev->mlock);
++ /* Disable overrun interrupts */
++ regmap_write(dev->regmap, SPDIFRX_IDR, SPDIFRX_IR_OVERRUN);
++
++ /* Disable receiver. */
++ regmap_update_bits(dev->regmap, SPDIFRX_MR, SPDIFRX_MR_RXEN_MASK,
++ SPDIFRX_MR_RXEN_DISABLE);
++ dev->trigger_enabled = false;
++ mutex_unlock(&dev->mlock);
+ break;
+ default:
+- return -EINVAL;
++ ret = -EINVAL;
+ }
+
+- ret = regmap_write(dev->regmap, SPDIFRX_MR, mr);
+- if (ret) {
+- dev_err(dev->dev, "unable to enable/disable RX: %d\n", ret);
+- return ret;
+- }
+-
+- return 0;
++ return ret;
+ }
+
+ static int mchp_spdifrx_hw_params(struct snd_pcm_substream *substream,
+@@ -413,13 +408,6 @@ static int mchp_spdifrx_hw_params(struct snd_pcm_substream *substream,
+ return -EINVAL;
+ }
+
+- regmap_read(dev->regmap, SPDIFRX_MR, &mr);
+-
+- if (mr & SPDIFRX_MR_RXEN_ENABLE) {
+- dev_err(dev->dev, "PCM already running\n");
+- return -EBUSY;
+- }
+-
+ if (params_channels(params) != SPDIFRX_CHANNELS) {
+ dev_err(dev->dev, "unsupported number of channels: %d\n",
+ params_channels(params));
+@@ -445,6 +433,13 @@ static int mchp_spdifrx_hw_params(struct snd_pcm_substream *substream,
+ return -EINVAL;
+ }
+
++ mutex_lock(&dev->mlock);
++ if (dev->trigger_enabled) {
++ dev_err(dev->dev, "PCM already running\n");
++ ret = -EBUSY;
++ goto unlock;
++ }
++
+ if (dev->gclk_enabled) {
+ clk_disable_unprepare(dev->gclk);
+ dev->gclk_enabled = 0;
+@@ -455,19 +450,24 @@ static int mchp_spdifrx_hw_params(struct snd_pcm_substream *substream,
+ dev_err(dev->dev,
+ "unable to set gclk min rate: rate %u * ratio %u + 1\n",
+ params_rate(params), SPDIFRX_GCLK_RATIO_MIN);
+- return ret;
++ goto unlock;
+ }
+ ret = clk_prepare_enable(dev->gclk);
+ if (ret) {
+ dev_err(dev->dev, "unable to enable gclk: %d\n", ret);
+- return ret;
++ goto unlock;
+ }
+ dev->gclk_enabled = 1;
+
+ dev_dbg(dev->dev, "GCLK range min set to %d\n",
+ params_rate(params) * SPDIFRX_GCLK_RATIO_MIN + 1);
+
+- return regmap_write(dev->regmap, SPDIFRX_MR, mr);
++ ret = regmap_write(dev->regmap, SPDIFRX_MR, mr);
++
++unlock:
++ mutex_unlock(&dev->mlock);
++
++ return ret;
+ }
+
+ static int mchp_spdifrx_hw_free(struct snd_pcm_substream *substream,
+@@ -475,10 +475,12 @@ static int mchp_spdifrx_hw_free(struct snd_pcm_substream *substream,
+ {
+ struct mchp_spdifrx_dev *dev = snd_soc_dai_get_drvdata(dai);
+
++ mutex_lock(&dev->mlock);
+ if (dev->gclk_enabled) {
+ clk_disable_unprepare(dev->gclk);
+ dev->gclk_enabled = 0;
+ }
++ mutex_unlock(&dev->mlock);
+ return 0;
+ }
+
+@@ -627,10 +629,24 @@ static int mchp_spdifrx_ulock_get(struct snd_kcontrol *kcontrol,
+ u32 val;
+ bool ulock_old = ctrl->ulock;
+
+- regmap_read(dev->regmap, SPDIFRX_RSR, &val);
+- ctrl->ulock = !(val & SPDIFRX_RSR_ULOCK);
++ mutex_lock(&dev->mlock);
++
++ /*
++ * The RSR.ULOCK has wrong value if both pclk and gclk are enabled
++ * and the receiver is disabled. Thus we take into account the
++ * dev->trigger_enabled here to return a real status.
++ */
++ if (dev->trigger_enabled) {
++ regmap_read(dev->regmap, SPDIFRX_RSR, &val);
++ ctrl->ulock = !(val & SPDIFRX_RSR_ULOCK);
++ } else {
++ ctrl->ulock = 0;
++ }
++
+ uvalue->value.integer.value[0] = ctrl->ulock;
+
++ mutex_unlock(&dev->mlock);
++
+ return ulock_old != ctrl->ulock;
+ }
+
+@@ -643,8 +659,22 @@ static int mchp_spdifrx_badf_get(struct snd_kcontrol *kcontrol,
+ u32 val;
+ bool badf_old = ctrl->badf;
+
+- regmap_read(dev->regmap, SPDIFRX_RSR, &val);
+- ctrl->badf = !!(val & SPDIFRX_RSR_BADF);
++ mutex_lock(&dev->mlock);
++
++ /*
++ * The RSR.ULOCK has wrong value if both pclk and gclk are enabled
++ * and the receiver is disabled. Thus we take into account the
++ * dev->trigger_enabled here to return a real status.
++ */
++ if (dev->trigger_enabled) {
++ regmap_read(dev->regmap, SPDIFRX_RSR, &val);
++ ctrl->badf = !!(val & SPDIFRX_RSR_BADF);
++ } else {
++ ctrl->badf = 0;
++ }
++
++ mutex_unlock(&dev->mlock);
++
+ uvalue->value.integer.value[0] = ctrl->badf;
+
+ return badf_old != ctrl->badf;
+@@ -656,11 +686,48 @@ static int mchp_spdifrx_signal_get(struct snd_kcontrol *kcontrol,
+ struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
+ struct mchp_spdifrx_dev *dev = snd_soc_dai_get_drvdata(dai);
+ struct mchp_spdifrx_mixer_control *ctrl = &dev->control;
+- u32 val;
++ u32 val = ~0U, loops = 10;
++ int ret;
+ bool signal_old = ctrl->signal;
+
+- regmap_read(dev->regmap, SPDIFRX_RSR, &val);
+- ctrl->signal = !(val & SPDIFRX_RSR_NOSIGNAL);
++ mutex_lock(&dev->mlock);
++
++ /*
++ * To get the signal we need to have receiver enabled. This
++ * could be enabled also from trigger() function thus we need to
++ * take care of not disabling the receiver when it runs.
++ */
++ if (!dev->trigger_enabled) {
++ ret = clk_prepare_enable(dev->gclk);
++ if (ret)
++ goto unlock;
++
++ regmap_update_bits(dev->regmap, SPDIFRX_MR, SPDIFRX_MR_RXEN_MASK,
++ SPDIFRX_MR_RXEN_ENABLE);
++
++ /* Wait for RSR.ULOCK bit. */
++ while (--loops) {
++ regmap_read(dev->regmap, SPDIFRX_RSR, &val);
++ if (!(val & SPDIFRX_RSR_ULOCK))
++ break;
++ usleep_range(100, 150);
++ }
++
++ regmap_update_bits(dev->regmap, SPDIFRX_MR, SPDIFRX_MR_RXEN_MASK,
++ SPDIFRX_MR_RXEN_DISABLE);
++
++ clk_disable_unprepare(dev->gclk);
++ } else {
++ regmap_read(dev->regmap, SPDIFRX_RSR, &val);
++ }
++
++unlock:
++ mutex_unlock(&dev->mlock);
++
++ if (!(val & SPDIFRX_RSR_ULOCK))
++ ctrl->signal = !(val & SPDIFRX_RSR_NOSIGNAL);
++ else
++ ctrl->signal = 0;
+ uvalue->value.integer.value[0] = ctrl->signal;
+
+ return signal_old != ctrl->signal;
+@@ -685,18 +752,32 @@ static int mchp_spdifrx_rate_get(struct snd_kcontrol *kcontrol,
+ u32 val;
+ int rate;
+
+- regmap_read(dev->regmap, SPDIFRX_RSR, &val);
+-
+- /* if the receiver is not locked, ISF data is invalid */
+- if (val & SPDIFRX_RSR_ULOCK || !(val & SPDIFRX_RSR_IFS_MASK)) {
++ mutex_lock(&dev->mlock);
++
++ /*
++ * The RSR.ULOCK has wrong value if both pclk and gclk are enabled
++ * and the receiver is disabled. Thus we take into account the
++ * dev->trigger_enabled here to return a real status.
++ */
++ if (dev->trigger_enabled) {
++ regmap_read(dev->regmap, SPDIFRX_RSR, &val);
++ /* If the receiver is not locked, ISF data is invalid. */
++ if (val & SPDIFRX_RSR_ULOCK || !(val & SPDIFRX_RSR_IFS_MASK)) {
++ ucontrol->value.integer.value[0] = 0;
++ goto unlock;
++ }
++ } else {
++ /* Reveicer is not locked, IFS data is invalid. */
+ ucontrol->value.integer.value[0] = 0;
+- return 0;
++ goto unlock;
+ }
+
+ rate = clk_get_rate(dev->gclk);
+
+ ucontrol->value.integer.value[0] = rate / (32 * SPDIFRX_RSR_IFS(val));
+
++unlock:
++ mutex_unlock(&dev->mlock);
+ return 0;
+ }
+
+@@ -912,7 +993,18 @@ static int mchp_spdifrx_probe(struct platform_device *pdev)
+ "failed to get the PMC generated clock: %d\n", err);
+ return err;
+ }
++
++ /*
++ * Signal control need a valid rate on gclk. hw_params() configures
++ * it propertly but requesting signal before any hw_params() has been
++ * called lead to invalid value returned for signal. Thus, configure
++ * gclk at a valid rate, here, in initialization, to simplify the
++ * control path.
++ */
++ clk_set_min_rate(dev->gclk, 48000 * SPDIFRX_GCLK_RATIO_MIN + 1);
++
+ spin_lock_init(&dev->blockend_lock);
++ mutex_init(&dev->mlock);
+
+ dev->dev = &pdev->dev;
+ dev->regmap = regmap;
+--
+2.39.2
+
--- /dev/null
+From 23cf556d2cb751d54e896b2ac5c1720d33370b6e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 Jan 2023 14:06:41 +0200
+Subject: ASoC: mchp-spdifrx: fix return value in case completion times out
+
+From: Claudiu Beznea <claudiu.beznea@microchip.com>
+
+[ Upstream commit a4c4161d6eae3ef5f486d1638ef452d9bc1376b0 ]
+
+wait_for_completion_interruptible_timeout() returns 0 in case of
+timeout. Check this into account when returning from function.
+
+Fixes: ef265c55c1ac ("ASoC: mchp-spdifrx: add driver for SPDIF RX")
+Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
+Link: https://lore.kernel.org/r/20230130120647.638049-3-claudiu.beznea@microchip.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/atmel/mchp-spdifrx.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/atmel/mchp-spdifrx.c b/sound/soc/atmel/mchp-spdifrx.c
+index 3962ce00ad34a..076a78fd0b125 100644
+--- a/sound/soc/atmel/mchp-spdifrx.c
++++ b/sound/soc/atmel/mchp-spdifrx.c
+@@ -524,9 +524,10 @@ static int mchp_spdifrx_cs_get(struct mchp_spdifrx_dev *dev,
+ ret = wait_for_completion_interruptible_timeout(&ch_stat->done,
+ msecs_to_jiffies(100));
+ /* IP might not be started or valid stream might not be present */
+- if (ret < 0) {
++ if (ret <= 0) {
+ dev_dbg(dev->dev, "channel status for channel %d timeout\n",
+ channel);
++ return ret ? : -ETIMEDOUT;
+ }
+
+ memcpy(uvalue->value.iec958.status, ch_stat->data,
+@@ -580,7 +581,7 @@ static int mchp_spdifrx_subcode_ch_get(struct mchp_spdifrx_dev *dev,
+ dev_dbg(dev->dev, "user data for channel %d timeout\n",
+ channel);
+ mchp_spdifrx_isr_blockend_dis(dev);
+- return ret;
++ return ret ? : -ETIMEDOUT;
+ }
+
+ spin_lock_irqsave(&user_data->lock, flags);
+--
+2.39.2
+
--- /dev/null
+From be299a6824ef07814901cf7b0c34b930ad4f5139 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Feb 2023 09:34:19 -0700
+Subject: ASoC: mchp-spdifrx: Fix uninitialized use of mr in
+ mchp_spdifrx_hw_params()
+
+From: Nathan Chancellor <nathan@kernel.org>
+
+[ Upstream commit 218674a45930c700486d27b765bf2f1b43f8cbf7 ]
+
+Clang warns:
+
+ ../sound/soc/atmel/mchp-spdifrx.c:455:3: error: variable 'mr' is uninitialized when used here [-Werror,-Wuninitialized]
+ mr |= SPDIFRX_MR_ENDIAN_BIG;
+ ^~
+ ../sound/soc/atmel/mchp-spdifrx.c:432:8: note: initialize the variable 'mr' to silence this warning
+ u32 mr;
+ ^
+ = 0
+ 1 error generated.
+
+Zero initialize mr so that these bitwise OR and assignment operation
+works unconditionally.
+
+Fixes: fa09fa60385a ("ASoC: mchp-spdifrx: fix controls which rely on rsr register")
+Link: https://github.com/ClangBuiltLinux/linux/issues/1797
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Reviewed-by: Claudiu Beznea <claudiu.beznea@microchip.com>
+Link: https://lore.kernel.org/r/20230202-mchp-spdifrx-fix-uninit-mr-v1-1-629a045d7a2f@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/atmel/mchp-spdifrx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/atmel/mchp-spdifrx.c b/sound/soc/atmel/mchp-spdifrx.c
+index 03b7037239b85..39a3c2a33bdbb 100644
+--- a/sound/soc/atmel/mchp-spdifrx.c
++++ b/sound/soc/atmel/mchp-spdifrx.c
+@@ -362,7 +362,7 @@ static int mchp_spdifrx_hw_params(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+ {
+ struct mchp_spdifrx_dev *dev = snd_soc_dai_get_drvdata(dai);
+- u32 mr;
++ u32 mr = 0;
+ int ret;
+
+ dev_dbg(dev->dev, "%s() rate=%u format=%#x width=%u channels=%u\n",
+--
+2.39.2
+
--- /dev/null
+From 53bfaf551876f6abf8a97bb4ece0107f0983007b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 23 Jan 2023 23:17:20 +0000
+Subject: ASoC: soc-compress.c: fixup private_data on snd_soc_new_compress()
+
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+
+[ Upstream commit ffe4c0f0bfaa571a676a0e946d4a6a0607f94294 ]
+
+commit d3268a40d4b19f ("ASoC: soc-compress.c: fix NULL dereference")
+enables DPCM capture, but it should independent from playback.
+This patch fixup it.
+
+Fixes: d3268a40d4b1 ("ASoC: soc-compress.c: fix NULL dereference")
+Link: https://lore.kernel.org/r/87tu0i6j7j.wl-kuninori.morimoto.gx@renesas.com
+Acked-by: Charles Keepax <ckeepax@opensource.cirrus.com>
+Acked-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Link: https://lore.kernel.org/r/871qnkvo1s.wl-kuninori.morimoto.gx@renesas.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/soc-compress.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
+index d0f3ff8edd904..8f4ebb189e019 100644
+--- a/sound/soc/soc-compress.c
++++ b/sound/soc/soc-compress.c
+@@ -822,7 +822,7 @@ int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
+ rtd->fe_compr = 1;
+ if (rtd->dai_link->dpcm_playback)
+ be_pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->private_data = rtd;
+- else if (rtd->dai_link->dpcm_capture)
++ if (rtd->dai_link->dpcm_capture)
+ be_pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->private_data = rtd;
+ memcpy(compr->ops, &soc_compr_dyn_ops, sizeof(soc_compr_dyn_ops));
+ } else {
+--
+2.39.2
+
--- /dev/null
+From 843728a61a848e1d6b94d478cc9fb2b4c8aff4ac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Feb 2023 13:28:51 +0000
+Subject: ASoC: soc-dapm.h: fixup warning struct snd_pcm_substream not declared
+
+From: Lucas Tanure <lucas.tanure@collabora.com>
+
+[ Upstream commit fdff966bfde7cf0c85562d2bfb1ff1ba83da5f7b ]
+
+Add struct snd_pcm_substream forward declaration
+
+Fixes: 078a85f2806f ("ASoC: dapm: Only power up active channels from a DAI")
+Signed-off-by: Lucas Tanure <lucas.tanure@collabora.com>
+Reviewed-by: Charles Keepax <ckeepax@opensource.cirrus.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20230215132851.1626881-1-lucas.tanure@collabora.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/sound/soc-dapm.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
+index c3039e97929a5..32e93d55acf73 100644
+--- a/include/sound/soc-dapm.h
++++ b/include/sound/soc-dapm.h
+@@ -16,6 +16,7 @@
+ #include <sound/asoc.h>
+
+ struct device;
++struct snd_pcm_substream;
+ struct snd_soc_pcm_runtime;
+ struct soc_enum;
+
+--
+2.39.2
+
--- /dev/null
+From f9b7349efd037822493a060a44a1d96ad43203b9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Feb 2023 09:38:05 +0200
+Subject: ASoC: tlv320adcx140: fix 'ti,gpio-config' DT property init
+
+From: Steffen Aschbacher <steffen.aschbacher@stihl.de>
+
+[ Upstream commit 771725efe5e2e5396dd9d1220437e5f9d6b9ca9d ]
+
+When the 'ti,gpio-config' property is not defined, the
+device_property_count_u32() will return an error, rather than zero.
+
+The current check, only handles a return value of zero, which assumes that
+the property is defined and has nothing defined.
+
+This change extends the check to also check for an error case (most likely
+to be hit by the case that the 'ti,gpio-config' is not defined).
+
+In case that the 'ti,gpio-config' and the returned 'gpio_count' is not
+correct, there is a 'if (gpio_count != ADCX140_NUM_GPIO_CFGS)' check, a few
+lines lower that will return -EINVAL.
+This means that someone tried to define 'ti,gpio-config', but with the
+wrong number of GPIOs.
+
+Fixes: d5214321498a ("ASoC: tlv320adcx140: Add support for configuring GPIO pin")
+Signed-off-by: Steffen Aschbacher <steffen.aschbacher@stihl.de>
+Signed-off-by: Alexandru Ardelean <alex@shruggie.ro>
+Link: https://lore.kernel.org/r/20230213073805.14640-1-alex@shruggie.ro
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/tlv320adcx140.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/codecs/tlv320adcx140.c b/sound/soc/codecs/tlv320adcx140.c
+index 53a80246aee19..a6241a0453694 100644
+--- a/sound/soc/codecs/tlv320adcx140.c
++++ b/sound/soc/codecs/tlv320adcx140.c
+@@ -870,7 +870,7 @@ static int adcx140_configure_gpio(struct adcx140_priv *adcx140)
+
+ gpio_count = device_property_count_u32(adcx140->dev,
+ "ti,gpio-config");
+- if (gpio_count == 0)
++ if (gpio_count <= 0)
+ return 0;
+
+ if (gpio_count != ADCX140_NUM_GPIO_CFGS)
+--
+2.39.2
+
--- /dev/null
+From 4288ce325fa05f70d7b664edf255c3938f9a9432 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Apr 2022 10:37:32 +0300
+Subject: ath9k: hif_usb: simplify if-if to if-else
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Wan Jiabing <wanjiabing@vivo.com>
+
+[ Upstream commit 2950833f10cfa601813262e1d9c8473f9415681b ]
+
+Use if and else instead of if(A) and if (!A).
+
+Signed-off-by: Wan Jiabing <wanjiabing@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/20220424094441.104937-1-wanjiabing@vivo.com
+Stable-dep-of: 0af54343a762 ("wifi: ath9k: hif_usb: clean up skbs if ath9k_hif_usb_rx_stream() fails")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath9k/hif_usb.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
+index f938ac1a4abd4..f54380fb6c9e5 100644
+--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
++++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
+@@ -368,10 +368,9 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev)
+ __skb_queue_head_init(&tx_buf->skb_queue);
+ list_move_tail(&tx_buf->list, &hif_dev->tx.tx_buf);
+ hif_dev->tx.tx_buf_cnt++;
+- }
+-
+- if (!ret)
++ } else {
+ TX_STAT_INC(buf_queued);
++ }
+
+ return ret;
+ }
+--
+2.39.2
+
--- /dev/null
+From 928f76fe03f3a50a1e7df204a25b1ea135c32147 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 21:44:07 +0300
+Subject: ath9k: htc: clean up statistics macros
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pavel Skripkin <paskripkin@gmail.com>
+
+[ Upstream commit d7fc76039b74ad37b7056d5607b05d7cb31a5404 ]
+
+I've changed *STAT_* macros a bit in previous patch and I seems like
+they become really unreadable. Align these macros definitions to make
+code cleaner and fix folllowing checkpatch warning
+
+ERROR: Macros with complex values should be enclosed in parentheses
+
+Also, statistics macros now accept an hif_dev as argument, since
+macros that depend on having a local variable with a magic name
+don't abide by the coding style.
+
+No functional change
+
+Suggested-by: Jeff Johnson <quic_jjohnson@quicinc.com>
+Signed-off-by: Pavel Skripkin <paskripkin@gmail.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/ebb2306d06a496cd1b032155ae52fdc5fa8cc2c5.1655145743.git.paskripkin@gmail.com
+Stable-dep-of: 0af54343a762 ("wifi: ath9k: hif_usb: clean up skbs if ath9k_hif_usb_rx_stream() fails")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath9k/hif_usb.c | 26 +++++++--------
+ drivers/net/wireless/ath/ath9k/htc.h | 32 +++++++++++--------
+ drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 10 +++---
+ 3 files changed, 36 insertions(+), 32 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
+index f54380fb6c9e5..1a2e0c7eeb023 100644
+--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
++++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
+@@ -244,11 +244,11 @@ static inline void ath9k_skb_queue_complete(struct hif_device_usb *hif_dev,
+ ath9k_htc_txcompletion_cb(hif_dev->htc_handle,
+ skb, txok);
+ if (txok) {
+- TX_STAT_INC(skb_success);
+- TX_STAT_ADD(skb_success_bytes, ln);
++ TX_STAT_INC(hif_dev, skb_success);
++ TX_STAT_ADD(hif_dev, skb_success_bytes, ln);
+ }
+ else
+- TX_STAT_INC(skb_failed);
++ TX_STAT_INC(hif_dev, skb_failed);
+ }
+ }
+
+@@ -302,7 +302,7 @@ static void hif_usb_tx_cb(struct urb *urb)
+ hif_dev->tx.tx_buf_cnt++;
+ if (!(hif_dev->tx.flags & HIF_USB_TX_STOP))
+ __hif_usb_tx(hif_dev); /* Check for pending SKBs */
+- TX_STAT_INC(buf_completed);
++ TX_STAT_INC(hif_dev, buf_completed);
+ spin_unlock(&hif_dev->tx.tx_lock);
+ }
+
+@@ -353,7 +353,7 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev)
+ tx_buf->len += tx_buf->offset;
+
+ __skb_queue_tail(&tx_buf->skb_queue, nskb);
+- TX_STAT_INC(skb_queued);
++ TX_STAT_INC(hif_dev, skb_queued);
+ }
+
+ usb_fill_bulk_urb(tx_buf->urb, hif_dev->udev,
+@@ -369,7 +369,7 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev)
+ list_move_tail(&tx_buf->list, &hif_dev->tx.tx_buf);
+ hif_dev->tx.tx_buf_cnt++;
+ } else {
+- TX_STAT_INC(buf_queued);
++ TX_STAT_INC(hif_dev, buf_queued);
+ }
+
+ return ret;
+@@ -514,7 +514,7 @@ static void hif_usb_sta_drain(void *hif_handle, u8 idx)
+ ath9k_htc_txcompletion_cb(hif_dev->htc_handle,
+ skb, false);
+ hif_dev->tx.tx_skb_cnt--;
+- TX_STAT_INC(skb_failed);
++ TX_STAT_INC(hif_dev, skb_failed);
+ }
+ }
+
+@@ -585,14 +585,14 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
+ pkt_tag = get_unaligned_le16(ptr + index + 2);
+
+ if (pkt_tag != ATH_USB_RX_STREAM_MODE_TAG) {
+- RX_STAT_INC(skb_dropped);
++ RX_STAT_INC(hif_dev, skb_dropped);
+ return;
+ }
+
+ if (pkt_len > 2 * MAX_RX_BUF_SIZE) {
+ dev_err(&hif_dev->udev->dev,
+ "ath9k_htc: invalid pkt_len (%x)\n", pkt_len);
+- RX_STAT_INC(skb_dropped);
++ RX_STAT_INC(hif_dev, skb_dropped);
+ return;
+ }
+
+@@ -618,7 +618,7 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
+ goto err;
+ }
+ skb_reserve(nskb, 32);
+- RX_STAT_INC(skb_allocated);
++ RX_STAT_INC(hif_dev, skb_allocated);
+
+ memcpy(nskb->data, &(skb->data[chk_idx+4]),
+ hif_dev->rx_transfer_len);
+@@ -639,7 +639,7 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
+ goto err;
+ }
+ skb_reserve(nskb, 32);
+- RX_STAT_INC(skb_allocated);
++ RX_STAT_INC(hif_dev, skb_allocated);
+
+ memcpy(nskb->data, &(skb->data[chk_idx+4]), pkt_len);
+ skb_put(nskb, pkt_len);
+@@ -649,10 +649,10 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
+
+ err:
+ for (i = 0; i < pool_index; i++) {
+- RX_STAT_ADD(skb_completed_bytes, skb_pool[i]->len);
++ RX_STAT_ADD(hif_dev, skb_completed_bytes, skb_pool[i]->len);
+ ath9k_htc_rx_msg(hif_dev->htc_handle, skb_pool[i],
+ skb_pool[i]->len, USB_WLAN_RX_PIPE);
+- RX_STAT_INC(skb_completed);
++ RX_STAT_INC(hif_dev, skb_completed);
+ }
+ }
+
+diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
+index e3d546ef71ddc..30f0765fb9fd8 100644
+--- a/drivers/net/wireless/ath/ath9k/htc.h
++++ b/drivers/net/wireless/ath/ath9k/htc.h
+@@ -327,14 +327,18 @@ static inline struct ath9k_htc_tx_ctl *HTC_SKB_CB(struct sk_buff *skb)
+ }
+
+ #ifdef CONFIG_ATH9K_HTC_DEBUGFS
+-#define __STAT_SAFE(expr) (hif_dev->htc_handle->drv_priv ? (expr) : 0)
+-#define TX_STAT_INC(c) __STAT_SAFE(hif_dev->htc_handle->drv_priv->debug.tx_stats.c++)
+-#define TX_STAT_ADD(c, a) __STAT_SAFE(hif_dev->htc_handle->drv_priv->debug.tx_stats.c += a)
+-#define RX_STAT_INC(c) __STAT_SAFE(hif_dev->htc_handle->drv_priv->debug.skbrx_stats.c++)
+-#define RX_STAT_ADD(c, a) __STAT_SAFE(hif_dev->htc_handle->drv_priv->debug.skbrx_stats.c += a)
+-#define CAB_STAT_INC priv->debug.tx_stats.cab_queued++
+-
+-#define TX_QSTAT_INC(q) (priv->debug.tx_stats.queue_stats[q]++)
++#define __STAT_SAFE(hif_dev, expr) ((hif_dev)->htc_handle->drv_priv ? (expr) : 0)
++#define CAB_STAT_INC(priv) ((priv)->debug.tx_stats.cab_queued++)
++#define TX_QSTAT_INC(priv, q) ((priv)->debug.tx_stats.queue_stats[q]++)
++
++#define TX_STAT_INC(hif_dev, c) \
++ __STAT_SAFE((hif_dev), (hif_dev)->htc_handle->drv_priv->debug.tx_stats.c++)
++#define TX_STAT_ADD(hif_dev, c, a) \
++ __STAT_SAFE((hif_dev), (hif_dev)->htc_handle->drv_priv->debug.tx_stats.c += a)
++#define RX_STAT_INC(hif_dev, c) \
++ __STAT_SAFE((hif_dev), (hif_dev)->htc_handle->drv_priv->debug.skbrx_stats.c++)
++#define RX_STAT_ADD(hif_dev, c, a) \
++ __STAT_SAFE((hif_dev), (hif_dev)->htc_handle->drv_priv->debug.skbrx_stats.c += a)
+
+ void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv,
+ struct ath_rx_status *rs);
+@@ -374,13 +378,13 @@ void ath9k_htc_get_et_stats(struct ieee80211_hw *hw,
+ struct ethtool_stats *stats, u64 *data);
+ #else
+
+-#define TX_STAT_INC(c) do { } while (0)
+-#define TX_STAT_ADD(c, a) do { } while (0)
+-#define RX_STAT_INC(c) do { } while (0)
+-#define RX_STAT_ADD(c, a) do { } while (0)
+-#define CAB_STAT_INC do { } while (0)
++#define TX_STAT_INC(hif_dev, c)
++#define TX_STAT_ADD(hif_dev, c, a)
++#define RX_STAT_INC(hif_dev, c)
++#define RX_STAT_ADD(hif_dev, c, a)
+
+-#define TX_QSTAT_INC(c) do { } while (0)
++#define CAB_STAT_INC(priv)
++#define TX_QSTAT_INC(priv, c)
+
+ static inline void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv,
+ struct ath_rx_status *rs)
+diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+index 43a743ec9d9e0..622fc7f170402 100644
+--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
++++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+@@ -106,20 +106,20 @@ static inline enum htc_endpoint_id get_htc_epid(struct ath9k_htc_priv *priv,
+
+ switch (qnum) {
+ case 0:
+- TX_QSTAT_INC(IEEE80211_AC_VO);
++ TX_QSTAT_INC(priv, IEEE80211_AC_VO);
+ epid = priv->data_vo_ep;
+ break;
+ case 1:
+- TX_QSTAT_INC(IEEE80211_AC_VI);
++ TX_QSTAT_INC(priv, IEEE80211_AC_VI);
+ epid = priv->data_vi_ep;
+ break;
+ case 2:
+- TX_QSTAT_INC(IEEE80211_AC_BE);
++ TX_QSTAT_INC(priv, IEEE80211_AC_BE);
+ epid = priv->data_be_ep;
+ break;
+ case 3:
+ default:
+- TX_QSTAT_INC(IEEE80211_AC_BK);
++ TX_QSTAT_INC(priv, IEEE80211_AC_BK);
+ epid = priv->data_bk_ep;
+ break;
+ }
+@@ -323,7 +323,7 @@ static void ath9k_htc_tx_data(struct ath9k_htc_priv *priv,
+ memcpy(tx_fhdr, (u8 *) &tx_hdr, sizeof(tx_hdr));
+
+ if (is_cab) {
+- CAB_STAT_INC;
++ CAB_STAT_INC(priv);
+ tx_ctl->epid = priv->cab_ep;
+ return;
+ }
+--
+2.39.2
+
--- /dev/null
+From 8c5af05825486f6cbe23a45245125f0f8ec28b25 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Jan 2023 15:08:05 +0800
+Subject: blk-iocost: fix divide by 0 error in calc_lcoefs()
+
+From: Li Nan <linan122@huawei.com>
+
+[ Upstream commit 984af1e66b4126cf145153661cc24c213e2ec231 ]
+
+echo max of u64 to cost.model can cause divide by 0 error.
+
+ # echo 8:0 rbps=18446744073709551615 > /sys/fs/cgroup/io.cost.model
+
+ divide error: 0000 [#1] PREEMPT SMP
+ RIP: 0010:calc_lcoefs+0x4c/0xc0
+ Call Trace:
+ <TASK>
+ ioc_refresh_params+0x2b3/0x4f0
+ ioc_cost_model_write+0x3cb/0x4c0
+ ? _copy_from_iter+0x6d/0x6c0
+ ? kernfs_fop_write_iter+0xfc/0x270
+ cgroup_file_write+0xa0/0x200
+ kernfs_fop_write_iter+0x17d/0x270
+ vfs_write+0x414/0x620
+ ksys_write+0x73/0x160
+ __x64_sys_write+0x1e/0x30
+ do_syscall_64+0x35/0x80
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+calc_lcoefs() uses the input value of cost.model in DIV_ROUND_UP_ULL,
+overflow would happen if bps plus IOC_PAGE_SIZE is greater than
+ULLONG_MAX, it can cause divide by 0 error.
+
+Fix the problem by setting basecost
+
+Signed-off-by: Li Nan <linan122@huawei.com>
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Acked-by: Tejun Heo <tj@kernel.org>
+Link: https://lore.kernel.org/r/20230117070806.3857142-5-yukuai1@huaweicloud.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-iocost.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/block/blk-iocost.c b/block/blk-iocost.c
+index fb8f959a7f327..9255b642d6adb 100644
+--- a/block/blk-iocost.c
++++ b/block/blk-iocost.c
+@@ -872,9 +872,14 @@ static void calc_lcoefs(u64 bps, u64 seqiops, u64 randiops,
+
+ *page = *seqio = *randio = 0;
+
+- if (bps)
+- *page = DIV64_U64_ROUND_UP(VTIME_PER_SEC,
+- DIV_ROUND_UP_ULL(bps, IOC_PAGE_SIZE));
++ if (bps) {
++ u64 bps_pages = DIV_ROUND_UP_ULL(bps, IOC_PAGE_SIZE);
++
++ if (bps_pages)
++ *page = DIV64_U64_ROUND_UP(VTIME_PER_SEC, bps_pages);
++ else
++ *page = 1;
++ }
+
+ if (seqiops) {
+ v = DIV64_U64_ROUND_UP(VTIME_PER_SEC, seqiops);
+--
+2.39.2
+
--- /dev/null
+From 4a9d0256a8cfe84b6a9a2d1e6be4e88e434a504a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Jan 2023 17:37:13 +0800
+Subject: blk-mq: avoid sleep in blk_mq_alloc_request_hctx
+
+From: Kemeng Shi <shikemeng@huaweicloud.com>
+
+[ Upstream commit 6ee858a3d3270a68902d66bb47c151a83622535c ]
+
+Commit 1f5bd336b9150 ("blk-mq: add blk_mq_alloc_request_hctx") add
+blk_mq_alloc_request_hctx to send commands to a specific queue. If
+BLK_MQ_REQ_NOWAIT is not set in tag allocation, we may change to different
+hctx after sleep and get tag from unexpected hctx. So BLK_MQ_REQ_NOWAIT
+must be set in flags for blk_mq_alloc_request_hctx.
+After commit 600c3b0cea784 ("blk-mq: open code __blk_mq_alloc_request in
+blk_mq_alloc_request_hctx"), blk_mq_alloc_request_hctx return -EINVAL
+if both BLK_MQ_REQ_NOWAIT and BLK_MQ_REQ_RESERVED are not set instead of
+if BLK_MQ_REQ_NOWAIT is not set. So if BLK_MQ_REQ_NOWAIT is not set and
+BLK_MQ_REQ_RESERVED is set, blk_mq_alloc_request_hctx could alloc tag
+from unexpected hctx. I guess what we need here is that return -EINVAL
+if either BLK_MQ_REQ_NOWAIT or BLK_MQ_REQ_RESERVED is not set.
+
+Currently both BLK_MQ_REQ_NOWAIT and BLK_MQ_REQ_RESERVED will be set if
+specific hctx is needed in nvme_auth_submit, nvmf_connect_io_queue
+and nvmf_connect_admin_queue. Fix the potential BLK_MQ_REQ_NOWAIT missed
+case in future.
+
+Fixes: 600c3b0cea78 ("blk-mq: open code __blk_mq_alloc_request in blk_mq_alloc_request_hctx")
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Kemeng Shi <shikemeng@huaweicloud.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-mq.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/block/blk-mq.c b/block/blk-mq.c
+index e37ba792902af..cf66de0f00fd3 100644
+--- a/block/blk-mq.c
++++ b/block/blk-mq.c
+@@ -448,7 +448,8 @@ struct request *blk_mq_alloc_request_hctx(struct request_queue *q,
+ * allocator for this for the rare use case of a command tied to
+ * a specific queue.
+ */
+- if (WARN_ON_ONCE(!(flags & (BLK_MQ_REQ_NOWAIT | BLK_MQ_REQ_RESERVED))))
++ if (WARN_ON_ONCE(!(flags & BLK_MQ_REQ_NOWAIT)) ||
++ WARN_ON_ONCE(!(flags & BLK_MQ_REQ_RESERVED)))
+ return ERR_PTR(-EINVAL);
+
+ if (hctx_idx >= q->nr_hw_queues)
+--
+2.39.2
+
--- /dev/null
+From 0e77226ac5326a98dee8d2309418354bfebc2121 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Jan 2023 17:37:26 +0800
+Subject: blk-mq: correct stale comment of .get_budget
+
+From: Kemeng Shi <shikemeng@huaweicloud.com>
+
+[ Upstream commit 01542f651a9f58a9b176c3d3dc3eefbacee53b78 ]
+
+Commit 88022d7201e96 ("blk-mq: don't handle failure in .get_budget")
+remove BLK_STS_RESOURCE return value and we only check if we can get
+the budget from .get_budget() now.
+Correct stale comment that ".get_budget() returns BLK_STS_NO_RESOURCE"
+to ".get_budget() fails to get the budget".
+
+Fixes: 88022d7201e9 ("blk-mq: don't handle failure in .get_budget")
+Signed-off-by: Kemeng Shi <shikemeng@huaweicloud.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-mq-sched.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/block/blk-mq-sched.c b/block/blk-mq-sched.c
+index 862acb5a84523..7858c5a3535e9 100644
+--- a/block/blk-mq-sched.c
++++ b/block/blk-mq-sched.c
+@@ -109,7 +109,7 @@ static bool blk_mq_dispatch_hctx_list(struct list_head *rq_list)
+ /*
+ * Only SCSI implements .get_budget and .put_budget, and SCSI restarts
+ * its queue by itself in its completion handler, so we don't need to
+- * restart queue if .get_budget() returns BLK_STS_NO_RESOURCE.
++ * restart queue if .get_budget() fails to get the budget.
+ *
+ * Returns -EAGAIN if hctx->dispatch was found non-empty and run_work has to
+ * be run again. This is necessary to avoid starving flushes.
+@@ -223,7 +223,7 @@ static struct blk_mq_ctx *blk_mq_next_ctx(struct blk_mq_hw_ctx *hctx,
+ /*
+ * Only SCSI implements .get_budget and .put_budget, and SCSI restarts
+ * its queue by itself in its completion handler, so we don't need to
+- * restart queue if .get_budget() returns BLK_STS_NO_RESOURCE.
++ * restart queue if .get_budget() fails to get the budget.
+ *
+ * Returns -EAGAIN if hctx->dispatch was found non-empty and run_work has to
+ * be run again. This is necessary to avoid starving flushes.
+--
+2.39.2
+
--- /dev/null
+From f2dec1e9545b8d75ecdad555b1cd6f9549f84874 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Jan 2023 17:37:14 +0800
+Subject: blk-mq: remove stale comment for blk_mq_sched_mark_restart_hctx
+
+From: Kemeng Shi <shikemeng@huaweicloud.com>
+
+[ Upstream commit c31e76bcc379182fe67a82c618493b7b8868c672 ]
+
+Commit 97889f9ac24f8 ("blk-mq: remove synchronize_rcu() from
+blk_mq_del_queue_tag_set()") remove handle of TAG_SHARED in restart,
+then shared_hctx_restart counted for how many hardware queues are marked
+for restart is removed too.
+Remove the stale comment that we still count hardware queues need restart.
+
+Fixes: 97889f9ac24f ("blk-mq: remove synchronize_rcu() from blk_mq_del_queue_tag_set()")
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Kemeng Shi <shikemeng@huaweicloud.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-mq-sched.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/block/blk-mq-sched.c b/block/blk-mq-sched.c
+index 72e64ba661fc7..862acb5a84523 100644
+--- a/block/blk-mq-sched.c
++++ b/block/blk-mq-sched.c
+@@ -45,8 +45,7 @@ void blk_mq_sched_assign_ioc(struct request *rq)
+ }
+
+ /*
+- * Mark a hardware queue as needing a restart. For shared queues, maintain
+- * a count of how many hardware queues are marked for restart.
++ * Mark a hardware queue as needing a restart.
+ */
+ void blk_mq_sched_mark_restart_hctx(struct blk_mq_hw_ctx *hctx)
+ {
+--
+2.39.2
+
--- /dev/null
+From 6ccc68d7c6970ab4fdfb00253f8b95b46c8a6c86 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Feb 2023 12:18:01 -0500
+Subject: block: bio-integrity: Copy flags when bio_integrity_payload is cloned
+
+From: Martin K. Petersen <martin.petersen@oracle.com>
+
+[ Upstream commit b6a4bdcda430e3ca43bbb9cb1d4d4d34ebe15c40 ]
+
+Make sure to copy the flags when a bio_integrity_payload is cloned.
+Otherwise per-I/O properties such as IP checksum flag will not be
+passed down to the HBA driver. Since the integrity buffer is owned by
+the original bio, the BIP_BLOCK_INTEGRITY flag needs to be masked off
+to avoid a double free in the completion path.
+
+Fixes: aae7df50190a ("block: Integrity checksum flag")
+Fixes: b1f01388574c ("block: Relocate bio integrity flags")
+Reported-by: Saurav Kashyap <skashyap@marvell.com>
+Tested-by: Saurav Kashyap <skashyap@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
+Link: https://lore.kernel.org/r/20230215171801.21062-1-martin.petersen@oracle.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/bio-integrity.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/block/bio-integrity.c b/block/bio-integrity.c
+index 4f6f140a44e06..a4cfc97275df6 100644
+--- a/block/bio-integrity.c
++++ b/block/bio-integrity.c
+@@ -428,6 +428,7 @@ int bio_integrity_clone(struct bio *bio, struct bio *bio_src,
+
+ bip->bip_vcnt = bip_src->bip_vcnt;
+ bip->bip_iter = bip_src->bip_iter;
++ bip->bip_flags = bip_src->bip_flags & ~BIP_BLOCK_INTEGRITY;
+
+ return 0;
+ }
+--
+2.39.2
+
--- /dev/null
+From fee9d5ad9a8af72dffddae9b86d781a7cb5210f2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 25 Dec 2022 14:07:13 -0500
+Subject: Bluetooth: btusb: Add VID:PID 13d3:3529 for Realtek RTL8821CE
+
+From: Moises Cardona <moisesmcardona@gmail.com>
+
+[ Upstream commit 1eec3b95b5ce7fb2cdd273ac4f8b24b1ed6776a1 ]
+
+This patch adds VID:PID 13d3:3529 to the btusb.c file.
+
+This VID:PID is found in the Realtek RTL8821CE module
+(M.2 module AW-CB304NF on an ASUS E210MA laptop)
+
+Output of /sys/kernel/debug/usb/devices:
+
+T: Bus=01 Lev=01 Prnt=01 Port=07 Cnt=02 Dev#= 3 Spd=12 MxCh= 0
+D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
+P: Vendor=13d3 ProdID=3529 Rev= 1.10
+S: Manufacturer=Realtek
+S: Product=Bluetooth Radio
+C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=500mA
+I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms
+E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms
+I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms
+I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms
+I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms
+I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms
+I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
+
+Signed-off-by: Moises Cardona <moisesmcardona@gmail.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 | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 3d905fda9b29a..2695ece47eb0e 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -393,6 +393,10 @@ static const struct usb_device_id blacklist_table[] = {
+ { USB_VENDOR_AND_INTERFACE_INFO(0x8087, 0xe0, 0x01, 0x01),
+ .driver_info = BTUSB_IGNORE },
+
++ /* Realtek 8821CE Bluetooth devices */
++ { USB_DEVICE(0x13d3, 0x3529), .driver_info = BTUSB_REALTEK |
++ BTUSB_WIDEBAND_SPEECH },
++
+ /* Realtek 8822CE Bluetooth devices */
+ { USB_DEVICE(0x0bda, 0xb00c), .driver_info = BTUSB_REALTEK |
+ BTUSB_WIDEBAND_SPEECH },
+--
+2.39.2
+
--- /dev/null
+From 3d5ebe24cb9e1d637abdb223de1a1433a8b7796b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Feb 2023 14:01:11 -0800
+Subject: Bluetooth: L2CAP: Fix potential user-after-free
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit df5703348813235874d851934e957c3723d71644 ]
+
+This fixes all instances of which requires to allocate a buffer calling
+alloc_skb which may release the chan lock and reacquire later which
+makes it possible that the chan is disconnected in the meantime.
+
+Fixes: a6a5568c03c4 ("Bluetooth: Lock the L2CAP channel when sending")
+Reported-by: Alexander Coffin <alex.coffin@matician.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/l2cap_core.c | 24 ------------------------
+ net/bluetooth/l2cap_sock.c | 8 ++++++++
+ 2 files changed, 8 insertions(+), 24 deletions(-)
+
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index cf56582d298ad..bde90df6b4976 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -2679,14 +2679,6 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len)
+ if (IS_ERR(skb))
+ return PTR_ERR(skb);
+
+- /* Channel lock is released before requesting new skb and then
+- * reacquired thus we need to recheck channel state.
+- */
+- if (chan->state != BT_CONNECTED) {
+- kfree_skb(skb);
+- return -ENOTCONN;
+- }
+-
+ l2cap_do_send(chan, skb);
+ return len;
+ }
+@@ -2731,14 +2723,6 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len)
+ if (IS_ERR(skb))
+ return PTR_ERR(skb);
+
+- /* Channel lock is released before requesting new skb and then
+- * reacquired thus we need to recheck channel state.
+- */
+- if (chan->state != BT_CONNECTED) {
+- kfree_skb(skb);
+- return -ENOTCONN;
+- }
+-
+ l2cap_do_send(chan, skb);
+ err = len;
+ break;
+@@ -2759,14 +2743,6 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len)
+ */
+ err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
+
+- /* The channel could have been closed while segmenting,
+- * check that it is still connected.
+- */
+- if (chan->state != BT_CONNECTED) {
+- __skb_queue_purge(&seg_queue);
+- err = -ENOTCONN;
+- }
+-
+ if (err)
+ break;
+
+diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
+index d2c6785205992..a267c9b6bcef4 100644
+--- a/net/bluetooth/l2cap_sock.c
++++ b/net/bluetooth/l2cap_sock.c
+@@ -1623,6 +1623,14 @@ static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan,
+ if (!skb)
+ return ERR_PTR(err);
+
++ /* Channel lock is released before requesting new skb and then
++ * reacquired thus we need to recheck channel state.
++ */
++ if (chan->state != BT_CONNECTED) {
++ kfree_skb(skb);
++ return ERR_PTR(-ENOTCONN);
++ }
++
+ skb->priority = sk->sk_priority;
+
+ bt_cb(skb)->l2cap.chan = chan;
+--
+2.39.2
+
--- /dev/null
+From c9ed413e34be547719e0548a472b6ec10f8a881b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Feb 2023 20:59:52 -0800
+Subject: bpf: Fix global subprog context argument resolution logic
+
+From: Andrii Nakryiko <andrii@kernel.org>
+
+[ Upstream commit d384dce281ed1b504fae2e279507827638d56fa3 ]
+
+KPROBE program's user-facing context type is defined as typedef
+bpf_user_pt_regs_t. This leads to a problem when trying to passing
+kprobe/uprobe/usdt context argument into global subprog, as kernel
+always strip away mods and typedefs of user-supplied type, but takes
+expected type from bpf_ctx_convert as is, which causes mismatch.
+
+Current way to work around this is to define a fake struct with the same
+name as expected typedef:
+
+ struct bpf_user_pt_regs_t {};
+
+ __noinline my_global_subprog(struct bpf_user_pt_regs_t *ctx) { ... }
+
+This patch fixes the issue by resolving expected type, if it's not
+a struct. It still leaves the above work-around working for backwards
+compatibility.
+
+Fixes: 91cc1a99740e ("bpf: Annotate context types")
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Stanislav Fomichev <sdf@google.com>
+Link: https://lore.kernel.org/bpf/20230216045954.3002473-2-andrii@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/btf.c | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
+index 52e7048607399..11b612e94e4e1 100644
+--- a/kernel/bpf/btf.c
++++ b/kernel/bpf/btf.c
+@@ -4273,6 +4273,7 @@ btf_get_prog_ctx_type(struct bpf_verifier_log *log, struct btf *btf,
+ if (!ctx_struct)
+ /* should not happen */
+ return NULL;
++again:
+ ctx_tname = btf_name_by_offset(btf_vmlinux, ctx_struct->name_off);
+ if (!ctx_tname) {
+ /* should not happen */
+@@ -4286,8 +4287,16 @@ btf_get_prog_ctx_type(struct bpf_verifier_log *log, struct btf *btf,
+ * int socket_filter_bpf_prog(struct __sk_buff *skb)
+ * { // no fields of skb are ever used }
+ */
+- if (strcmp(ctx_tname, tname))
+- return NULL;
++ if (strcmp(ctx_tname, tname)) {
++ /* bpf_user_pt_regs_t is a typedef, so resolve it to
++ * underlying struct and check name again
++ */
++ if (!btf_type_is_modifier(ctx_struct))
++ return NULL;
++ while (btf_type_is_modifier(ctx_struct))
++ ctx_struct = btf_type_by_id(btf_vmlinux, ctx_struct->type);
++ goto again;
++ }
+ return ctx_type;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 4df2bc21aa26d0d1ac0d8aed89b9488491ae5ae8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Feb 2023 21:17:01 +0800
+Subject: bpftool: profile online CPUs instead of possible
+
+From: Tonghao Zhang <tong@infragraf.org>
+
+[ Upstream commit 377c16fa3f3c60d21e4b05314c8be034ce37f2eb ]
+
+The number of online cpu may be not equal to possible cpu.
+"bpftool prog profile" can not create pmu event on possible
+but on online cpu.
+
+$ dmidecode -s system-product-name
+PowerEdge R620
+$ cat /sys/devices/system/cpu/possible
+0-47
+$ cat /sys/devices/system/cpu/online
+0-31
+
+Disable cpu dynamically:
+$ echo 0 > /sys/devices/system/cpu/cpuX/online
+
+If one cpu is offline, perf_event_open will return ENODEV.
+To fix this issue:
+* check value returned and skip offline cpu.
+* close pmu_fd immediately on error path, avoid fd leaking.
+
+Fixes: 47c09d6a9f67 ("bpftool: Introduce "prog profile" command")
+Signed-off-by: Tonghao Zhang <tong@infragraf.org>
+Cc: Quentin Monnet <quentin@isovalent.com>
+Cc: Alexei Starovoitov <ast@kernel.org>
+Cc: Daniel Borkmann <daniel@iogearbox.net>
+Cc: Andrii Nakryiko <andrii@kernel.org>
+Cc: Martin KaFai Lau <martin.lau@linux.dev>
+Cc: Song Liu <song@kernel.org>
+Cc: Yonghong Song <yhs@fb.com>
+Cc: John Fastabend <john.fastabend@gmail.com>
+Cc: KP Singh <kpsingh@kernel.org>
+Cc: Stanislav Fomichev <sdf@google.com>
+Cc: Hao Luo <haoluo@google.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Acked-by: John Fastabend <john.fastabend@gmail.com>
+Link: https://lore.kernel.org/r/20230202131701.29519-1-tong@infragraf.org
+Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/bpf/bpftool/prog.c | 38 ++++++++++++++++++++++++++++++--------
+ 1 file changed, 30 insertions(+), 8 deletions(-)
+
+diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c
+index 592536904dde2..d2bcce627b320 100644
+--- a/tools/bpf/bpftool/prog.c
++++ b/tools/bpf/bpftool/prog.c
+@@ -1912,10 +1912,38 @@ static void profile_close_perf_events(struct profiler_bpf *obj)
+ profile_perf_event_cnt = 0;
+ }
+
++static int profile_open_perf_event(int mid, int cpu, int map_fd)
++{
++ int pmu_fd;
++
++ pmu_fd = syscall(__NR_perf_event_open, &metrics[mid].attr,
++ -1 /*pid*/, cpu, -1 /*group_fd*/, 0);
++ if (pmu_fd < 0) {
++ if (errno == ENODEV) {
++ p_info("cpu %d may be offline, skip %s profiling.",
++ cpu, metrics[mid].name);
++ profile_perf_event_cnt++;
++ return 0;
++ }
++ return -1;
++ }
++
++ if (bpf_map_update_elem(map_fd,
++ &profile_perf_event_cnt,
++ &pmu_fd, BPF_ANY) ||
++ ioctl(pmu_fd, PERF_EVENT_IOC_ENABLE, 0)) {
++ close(pmu_fd);
++ return -1;
++ }
++
++ profile_perf_events[profile_perf_event_cnt++] = pmu_fd;
++ return 0;
++}
++
+ static int profile_open_perf_events(struct profiler_bpf *obj)
+ {
+ unsigned int cpu, m;
+- int map_fd, pmu_fd;
++ int map_fd;
+
+ profile_perf_events = calloc(
+ sizeof(int), obj->rodata->num_cpu * obj->rodata->num_metric);
+@@ -1934,17 +1962,11 @@ static int profile_open_perf_events(struct profiler_bpf *obj)
+ if (!metrics[m].selected)
+ continue;
+ for (cpu = 0; cpu < obj->rodata->num_cpu; cpu++) {
+- pmu_fd = syscall(__NR_perf_event_open, &metrics[m].attr,
+- -1/*pid*/, cpu, -1/*group_fd*/, 0);
+- if (pmu_fd < 0 ||
+- bpf_map_update_elem(map_fd, &profile_perf_event_cnt,
+- &pmu_fd, BPF_ANY) ||
+- ioctl(pmu_fd, PERF_EVENT_IOC_ENABLE, 0)) {
++ if (profile_open_perf_event(m, cpu, map_fd)) {
+ p_err("failed to create event %s on cpu %d",
+ metrics[m].name, cpu);
+ return -1;
+ }
+- profile_perf_events[profile_perf_event_cnt++] = pmu_fd;
+ }
+ }
+ return 0;
+--
+2.39.2
+
--- /dev/null
+From e34bfa52c73de2a0f8deee47cab2a17c1e0d5fc9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 May 2021 01:01:37 +0200
+Subject: builddeb: clean generated package content
+
+From: Bastian Germann <bage@linutronix.de>
+
+[ Upstream commit c9f9cf2560e40b62015c6c4a04be60f55ce5240e ]
+
+For each binary Debian package, a directory with the package name is
+created in the debian directory. Correct the generated file matches in the
+package's clean target, which were renamed without adjusting the target.
+
+Fixes: 1694e94e4f46 ("builddeb: match temporary directory name to the package name")
+Signed-off-by: Bastian Germann <bage@linutronix.de>
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/package/mkdebian | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/scripts/package/mkdebian b/scripts/package/mkdebian
+index 60a2a63a5e900..32d528a367868 100755
+--- a/scripts/package/mkdebian
++++ b/scripts/package/mkdebian
+@@ -236,7 +236,7 @@ binary-arch: build-arch
+ KBUILD_BUILD_VERSION=${revision} -f \$(srctree)/Makefile intdeb-pkg
+
+ clean:
+- rm -rf debian/*tmp debian/files
++ rm -rf debian/files debian/linux-*
+ \$(MAKE) clean
+
+ binary: binary-arch
+--
+2.39.2
+
--- /dev/null
+From 6a6a90874928bb6a56083af817c22c112f341d15 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Feb 2023 20:04:48 +0100
+Subject: can: esd_usb: Move mislocated storage of SJA1000_ECC_SEG bits in case
+ of a bus error
+
+From: Frank Jungclaus <frank.jungclaus@esd.eu>
+
+[ Upstream commit 118469f88180438ef43dee93d71f77c00e7b425d ]
+
+Move the supply for cf->data[3] (bit stream position of CAN error), in
+case of a bus- or protocol-error, outside of the "switch (ecc &
+SJA1000_ECC_MASK){}"-statement, because this bit stream position is
+independent of the error type.
+
+Fixes: 96d8e90382dc ("can: Add driver for esd CAN-USB/2 device")
+Signed-off-by: Frank Jungclaus <frank.jungclaus@esd.eu>
+Link: https://lore.kernel.org/all/20230216190450.3901254-2-frank.jungclaus@esd.eu
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/usb/esd_usb2.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/can/usb/esd_usb2.c b/drivers/net/can/usb/esd_usb2.c
+index 73c5343e609bc..c9ccce6c60b46 100644
+--- a/drivers/net/can/usb/esd_usb2.c
++++ b/drivers/net/can/usb/esd_usb2.c
+@@ -278,7 +278,6 @@ static void esd_usb2_rx_event(struct esd_usb2_net_priv *priv,
+ cf->data[2] |= CAN_ERR_PROT_STUFF;
+ break;
+ default:
+- cf->data[3] = ecc & SJA1000_ECC_SEG;
+ break;
+ }
+
+@@ -286,6 +285,9 @@ static void esd_usb2_rx_event(struct esd_usb2_net_priv *priv,
+ if (!(ecc & SJA1000_ECC_DIR))
+ cf->data[2] |= CAN_ERR_PROT_TX;
+
++ /* Bit stream position in CAN frame as the error was detected */
++ cf->data[3] = ecc & SJA1000_ECC_SEG;
++
+ if (priv->can.state == CAN_STATE_ERROR_WARNING ||
+ priv->can.state == CAN_STATE_ERROR_PASSIVE) {
+ cf->data[1] = (txerr > rxerr) ?
+--
+2.39.2
+
--- /dev/null
+From fdcb5229607a1347e514ff286b193a88813ac19d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Nov 2022 16:42:07 +0800
+Subject: cifs: Fix lost destroy smbd connection when MR allocate failed
+
+From: Zhang Xiaoxu <zhangxiaoxu5@huawei.com>
+
+[ Upstream commit e9d3401d95d62a9531082cd2453ed42f2740e3fd ]
+
+If the MR allocate failed, the smb direct connection info is NULL,
+then smbd_destroy() will directly return, then the connection info
+will be leaked.
+
+Let's set the smb direct connection info to the server before call
+smbd_destroy().
+
+Fixes: c7398583340a ("CIFS: SMBD: Implement RDMA memory registration")
+Signed-off-by: Zhang Xiaoxu <zhangxiaoxu5@huawei.com>
+Acked-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
+Reviewed-by: David Howells <dhowells@redhat.com>
+Reviewed-by: Tom Talpey <tom@talpey.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/cifs/smbdirect.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/fs/cifs/smbdirect.c b/fs/cifs/smbdirect.c
+index f73f9b0625251..c93d4ec843beb 100644
+--- a/fs/cifs/smbdirect.c
++++ b/fs/cifs/smbdirect.c
+@@ -1691,6 +1691,7 @@ static struct smbd_connection *_smbd_get_connection(
+
+ allocate_mr_failed:
+ /* At this point, need to a full transport shutdown */
++ server->smbd_conn = info;
+ smbd_destroy(server);
+ return NULL;
+
+--
+2.39.2
+
--- /dev/null
+From 05f53a7f7ba09bb87a55e0f39f29220e7c39defc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Nov 2022 16:42:08 +0800
+Subject: cifs: Fix warning and UAF when destroy the MR list
+
+From: Zhang Xiaoxu <zhangxiaoxu5@huawei.com>
+
+[ Upstream commit 3e161c2791f8e661eed24a2c624087084d910215 ]
+
+If the MR allocate failed, the MR recovery work not initialized
+and list not cleared. Then will be warning and UAF when release
+the MR:
+
+ WARNING: CPU: 4 PID: 824 at kernel/workqueue.c:3066 __flush_work.isra.0+0xf7/0x110
+ CPU: 4 PID: 824 Comm: mount.cifs Not tainted 6.1.0-rc5+ #82
+ RIP: 0010:__flush_work.isra.0+0xf7/0x110
+ Call Trace:
+ <TASK>
+ __cancel_work_timer+0x2ba/0x2e0
+ smbd_destroy+0x4e1/0x990
+ _smbd_get_connection+0x1cbd/0x2110
+ smbd_get_connection+0x21/0x40
+ cifs_get_tcp_session+0x8ef/0xda0
+ mount_get_conns+0x60/0x750
+ cifs_mount+0x103/0xd00
+ cifs_smb3_do_mount+0x1dd/0xcb0
+ smb3_get_tree+0x1d5/0x300
+ vfs_get_tree+0x41/0xf0
+ path_mount+0x9b3/0xdd0
+ __x64_sys_mount+0x190/0x1d0
+ do_syscall_64+0x35/0x80
+ entry_SYSCALL_64_after_hwframe+0x46/0xb0
+
+ BUG: KASAN: use-after-free in smbd_destroy+0x4fc/0x990
+ Read of size 8 at addr ffff88810b156a08 by task mount.cifs/824
+ CPU: 4 PID: 824 Comm: mount.cifs Tainted: G W 6.1.0-rc5+ #82
+ Call Trace:
+ dump_stack_lvl+0x34/0x44
+ print_report+0x171/0x472
+ kasan_report+0xad/0x130
+ smbd_destroy+0x4fc/0x990
+ _smbd_get_connection+0x1cbd/0x2110
+ smbd_get_connection+0x21/0x40
+ cifs_get_tcp_session+0x8ef/0xda0
+ mount_get_conns+0x60/0x750
+ cifs_mount+0x103/0xd00
+ cifs_smb3_do_mount+0x1dd/0xcb0
+ smb3_get_tree+0x1d5/0x300
+ vfs_get_tree+0x41/0xf0
+ path_mount+0x9b3/0xdd0
+ __x64_sys_mount+0x190/0x1d0
+ do_syscall_64+0x35/0x80
+ entry_SYSCALL_64_after_hwframe+0x46/0xb0
+
+ Allocated by task 824:
+ kasan_save_stack+0x1e/0x40
+ kasan_set_track+0x21/0x30
+ __kasan_kmalloc+0x7a/0x90
+ _smbd_get_connection+0x1b6f/0x2110
+ smbd_get_connection+0x21/0x40
+ cifs_get_tcp_session+0x8ef/0xda0
+ mount_get_conns+0x60/0x750
+ cifs_mount+0x103/0xd00
+ cifs_smb3_do_mount+0x1dd/0xcb0
+ smb3_get_tree+0x1d5/0x300
+ vfs_get_tree+0x41/0xf0
+ path_mount+0x9b3/0xdd0
+ __x64_sys_mount+0x190/0x1d0
+ do_syscall_64+0x35/0x80
+ entry_SYSCALL_64_after_hwframe+0x46/0xb0
+
+ Freed by task 824:
+ kasan_save_stack+0x1e/0x40
+ kasan_set_track+0x21/0x30
+ kasan_save_free_info+0x2a/0x40
+ ____kasan_slab_free+0x143/0x1b0
+ __kmem_cache_free+0xc8/0x330
+ _smbd_get_connection+0x1c6a/0x2110
+ smbd_get_connection+0x21/0x40
+ cifs_get_tcp_session+0x8ef/0xda0
+ mount_get_conns+0x60/0x750
+ cifs_mount+0x103/0xd00
+ cifs_smb3_do_mount+0x1dd/0xcb0
+ smb3_get_tree+0x1d5/0x300
+ vfs_get_tree+0x41/0xf0
+ path_mount+0x9b3/0xdd0
+ __x64_sys_mount+0x190/0x1d0
+ do_syscall_64+0x35/0x80
+ entry_SYSCALL_64_after_hwframe+0x46/0xb0
+
+Let's initialize the MR recovery work before MR allocate to prevent
+the warning, remove the MRs from the list to prevent the UAF.
+
+Fixes: c7398583340a ("CIFS: SMBD: Implement RDMA memory registration")
+Acked-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
+Reviewed-by: Tom Talpey <tom@talpey.com>
+Signed-off-by: Zhang Xiaoxu <zhangxiaoxu5@huawei.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/cifs/smbdirect.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/fs/cifs/smbdirect.c b/fs/cifs/smbdirect.c
+index c93d4ec843beb..bcc611069308a 100644
+--- a/fs/cifs/smbdirect.c
++++ b/fs/cifs/smbdirect.c
+@@ -2240,6 +2240,7 @@ static int allocate_mr_list(struct smbd_connection *info)
+ atomic_set(&info->mr_ready_count, 0);
+ atomic_set(&info->mr_used_count, 0);
+ init_waitqueue_head(&info->wait_for_mr_cleanup);
++ INIT_WORK(&info->mr_recovery_work, smbd_mr_recovery_work);
+ /* Allocate more MRs (2x) than hardware responder_resources */
+ for (i = 0; i < info->responder_resources * 2; i++) {
+ smbdirect_mr = kzalloc(sizeof(*smbdirect_mr), GFP_KERNEL);
+@@ -2267,13 +2268,13 @@ static int allocate_mr_list(struct smbd_connection *info)
+ list_add_tail(&smbdirect_mr->list, &info->mr_list);
+ atomic_inc(&info->mr_ready_count);
+ }
+- INIT_WORK(&info->mr_recovery_work, smbd_mr_recovery_work);
+ return 0;
+
+ out:
+ kfree(smbdirect_mr);
+
+ list_for_each_entry_safe(smbdirect_mr, tmp, &info->mr_list, list) {
++ list_del(&smbdirect_mr->list);
+ ib_dereg_mr(smbdirect_mr->mr);
+ kfree(smbdirect_mr->sgl);
+ kfree(smbdirect_mr);
+--
+2.39.2
+
--- /dev/null
+From 170022c0d9340dde922745dc3759d66fb57521b6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Jan 2023 17:23:30 +0800
+Subject: clk: Honor CLK_OPS_PARENT_ENABLE in clk_core_is_enabled()
+
+From: Chen-Yu Tsai <wenst@chromium.org>
+
+[ Upstream commit 79200d5851c8e7179f68a4a6f162d8f1bde4986f ]
+
+In the previous commits that added CLK_OPS_PARENT_ENABLE, support for
+this flag was only added to rate change operations (rate setting and
+reparent) and disabling unused subtree. It was not added to the
+clock gate related operations. Any hardware driver that needs it for
+these operations will either see bogus results, or worse, hang.
+
+This has been seen on MT8192 and MT8195, where the imp_ii2_* clk
+drivers set this, but dumping debugfs clk_summary would cause it
+to hang.
+
+Prepare parent on prepare and enable parent on enable dependencies are
+already handled automatically by the core as part of its sequencing.
+Whether the case for "enable parent on prepare" should be supported by
+this flag or not is not clear, and thus ignored for now.
+
+This change solely fixes the handling of clk_core_is_enabled, i.e.
+enabling the parent clock when reading the hardware state. Unfortunately
+clk_core_is_enabled is called in a variety of places, sometimes with
+the enable clock already held. To avoid deadlocking, the core will
+ignore readouts and just return false if CLK_OPS_PARENT_ENABLE is set
+but the parent isn't currently enabled.
+
+Fixes: fc8726a2c021 ("clk: core: support clocks which requires parents enable (part 2)")
+Fixes: a4b3518d146f ("clk: core: support clocks which requires parents enable (part 1)")
+Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
+Link: https://lore.kernel.org/r/20230103092330.494102-1-wenst@chromium.org
+Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/clk.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
+index b355d3d40f63a..3575afe16a574 100644
+--- a/drivers/clk/clk.c
++++ b/drivers/clk/clk.c
+@@ -251,6 +251,17 @@ static bool clk_core_is_enabled(struct clk_core *core)
+ }
+ }
+
++ /*
++ * This could be called with the enable lock held, or from atomic
++ * context. If the parent isn't enabled already, we can't do
++ * anything here. We can also assume this clock isn't enabled.
++ */
++ if ((core->flags & CLK_OPS_PARENT_ENABLE) && core->parent)
++ if (!clk_core_is_enabled(core->parent)) {
++ ret = false;
++ goto done;
++ }
++
+ ret = core->ops->is_enabled(core->hw);
+ done:
+ if (core->rpm_enabled)
+--
+2.39.2
+
--- /dev/null
+From 7cd232dd00d3e764e0b476484ca1e08871737888 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Jan 2023 19:00:29 +0800
+Subject: clk: imx: avoid memory leak
+
+From: Peng Fan <peng.fan@nxp.com>
+
+[ Upstream commit f4419db4086e8c31821da14140e81498516a3c75 ]
+
+In case imx_register_uart_clocks return early, the imx_uart_clocks
+memory will be no freed. So execute kfree always to avoid memory leak.
+
+Fixes: 379c9a24cc23 ("clk: imx: Fix reparenting of UARTs not associated with stdout")
+Signed-off-by: Peng Fan <peng.fan@nxp.com>
+Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
+Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
+Link: https://lore.kernel.org/r/20230104110032.1220721-2-peng.fan@oss.nxp.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/imx/clk.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/clk/imx/clk.c b/drivers/clk/imx/clk.c
+index 7cc669934253a..d4cf0c7045ab2 100644
+--- a/drivers/clk/imx/clk.c
++++ b/drivers/clk/imx/clk.c
+@@ -201,9 +201,10 @@ static int __init imx_clk_disable_uart(void)
+ clk_disable_unprepare(imx_uart_clocks[i]);
+ clk_put(imx_uart_clocks[i]);
+ }
+- kfree(imx_uart_clocks);
+ }
+
++ kfree(imx_uart_clocks);
++
+ return 0;
+ }
+ late_initcall_sync(imx_clk_disable_uart);
+--
+2.39.2
+
--- /dev/null
+From 86456224b2f15b3fe3e35c95407f0a91074fb654 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Dec 2022 06:21:43 +0200
+Subject: clk: qcom: gcc-qcs404: disable gpll[04]_out_aux parents
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 712c64caf31374de57aa193a9dff57172b2f6f82 ]
+
+On the QCS404 platform the driver for the Global Clock Controller
+doens't define gpll0_out_aux and gpll4_out_aux clocks, so it's not
+possible to use them as parents. Remove entries for these clocks.
+
+Note: backporting this patch to earlier kernels would also require a
+previous patch which switches the gcc driver to use ARRAY_SIZE for
+parent data arrays.
+
+Fixes: 652f1813c113 ("clk: qcom: gcc: Add global clock controller driver for QCS404")
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20221226042154.2666748-6-dmitry.baryshkov@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-qcs404.c | 16 ----------------
+ 1 file changed, 16 deletions(-)
+
+diff --git a/drivers/clk/qcom/gcc-qcs404.c b/drivers/clk/qcom/gcc-qcs404.c
+index 46d314d692505..4299fe8f19274 100644
+--- a/drivers/clk/qcom/gcc-qcs404.c
++++ b/drivers/clk/qcom/gcc-qcs404.c
+@@ -25,11 +25,9 @@ enum {
+ P_CORE_BI_PLL_TEST_SE,
+ P_DSI0_PHY_PLL_OUT_BYTECLK,
+ P_DSI0_PHY_PLL_OUT_DSICLK,
+- P_GPLL0_OUT_AUX,
+ P_GPLL0_OUT_MAIN,
+ P_GPLL1_OUT_MAIN,
+ P_GPLL3_OUT_MAIN,
+- P_GPLL4_OUT_AUX,
+ P_GPLL4_OUT_MAIN,
+ P_GPLL6_OUT_AUX,
+ P_HDMI_PHY_PLL_CLK,
+@@ -109,28 +107,24 @@ static const char * const gcc_parent_names_4[] = {
+ static const struct parent_map gcc_parent_map_5[] = {
+ { P_XO, 0 },
+ { P_DSI0_PHY_PLL_OUT_BYTECLK, 1 },
+- { P_GPLL0_OUT_AUX, 2 },
+ { P_CORE_BI_PLL_TEST_SE, 7 },
+ };
+
+ static const char * const gcc_parent_names_5[] = {
+ "cxo",
+ "dsi0pll_byteclk_src",
+- "gpll0_out_aux",
+ "core_bi_pll_test_se",
+ };
+
+ static const struct parent_map gcc_parent_map_6[] = {
+ { P_XO, 0 },
+ { P_DSI0_PHY_PLL_OUT_BYTECLK, 2 },
+- { P_GPLL0_OUT_AUX, 3 },
+ { P_CORE_BI_PLL_TEST_SE, 7 },
+ };
+
+ static const char * const gcc_parent_names_6[] = {
+ "cxo",
+ "dsi0_phy_pll_out_byteclk",
+- "gpll0_out_aux",
+ "core_bi_pll_test_se",
+ };
+
+@@ -139,7 +133,6 @@ static const struct parent_map gcc_parent_map_7[] = {
+ { P_GPLL0_OUT_MAIN, 1 },
+ { P_GPLL3_OUT_MAIN, 2 },
+ { P_GPLL6_OUT_AUX, 3 },
+- { P_GPLL4_OUT_AUX, 4 },
+ { P_CORE_BI_PLL_TEST_SE, 7 },
+ };
+
+@@ -148,7 +141,6 @@ static const char * const gcc_parent_names_7[] = {
+ "gpll0_out_main",
+ "gpll3_out_main",
+ "gpll6_out_aux",
+- "gpll4_out_aux",
+ "core_bi_pll_test_se",
+ };
+
+@@ -207,14 +199,12 @@ static const char * const gcc_parent_names_11[] = {
+ static const struct parent_map gcc_parent_map_12[] = {
+ { P_XO, 0 },
+ { P_DSI0_PHY_PLL_OUT_DSICLK, 1 },
+- { P_GPLL0_OUT_AUX, 2 },
+ { P_CORE_BI_PLL_TEST_SE, 7 },
+ };
+
+ static const char * const gcc_parent_names_12[] = {
+ "cxo",
+ "dsi0pll_pclk_src",
+- "gpll0_out_aux",
+ "core_bi_pll_test_se",
+ };
+
+@@ -237,40 +227,34 @@ static const char * const gcc_parent_names_13[] = {
+ static const struct parent_map gcc_parent_map_14[] = {
+ { P_XO, 0 },
+ { P_GPLL0_OUT_MAIN, 1 },
+- { P_GPLL4_OUT_AUX, 2 },
+ { P_CORE_BI_PLL_TEST_SE, 7 },
+ };
+
+ static const char * const gcc_parent_names_14[] = {
+ "cxo",
+ "gpll0_out_main",
+- "gpll4_out_aux",
+ "core_bi_pll_test_se",
+ };
+
+ static const struct parent_map gcc_parent_map_15[] = {
+ { P_XO, 0 },
+- { P_GPLL0_OUT_AUX, 2 },
+ { P_CORE_BI_PLL_TEST_SE, 7 },
+ };
+
+ static const char * const gcc_parent_names_15[] = {
+ "cxo",
+- "gpll0_out_aux",
+ "core_bi_pll_test_se",
+ };
+
+ static const struct parent_map gcc_parent_map_16[] = {
+ { P_XO, 0 },
+ { P_GPLL0_OUT_MAIN, 1 },
+- { P_GPLL0_OUT_AUX, 2 },
+ { P_CORE_BI_PLL_TEST_SE, 7 },
+ };
+
+ static const char * const gcc_parent_names_16[] = {
+ "cxo",
+ "gpll0_out_main",
+- "gpll0_out_aux",
+ "core_bi_pll_test_se",
+ };
+
+--
+2.39.2
+
--- /dev/null
+From 7cde42064fa20db85846357bd2bf291818f09443 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Dec 2022 06:21:44 +0200
+Subject: clk: qcom: gcc-qcs404: fix names of the DSI clocks used as parents
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 47d94d30cd3dcc743241b4208b1eec7247610c84 ]
+
+The QCS404 uses 28nm LPM DSI PHY, which registers dsi0pll and
+dsi0pllbyte clocks. Fix all DSI PHY clock names used as parents inside
+the GCC driver.
+
+Fixes: 652f1813c113 ("clk: qcom: gcc: Add global clock controller driver for QCS404")
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20221226042154.2666748-7-dmitry.baryshkov@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-qcs404.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/clk/qcom/gcc-qcs404.c b/drivers/clk/qcom/gcc-qcs404.c
+index 4299fe8f19274..a7a9884799cd3 100644
+--- a/drivers/clk/qcom/gcc-qcs404.c
++++ b/drivers/clk/qcom/gcc-qcs404.c
+@@ -112,7 +112,7 @@ static const struct parent_map gcc_parent_map_5[] = {
+
+ static const char * const gcc_parent_names_5[] = {
+ "cxo",
+- "dsi0pll_byteclk_src",
++ "dsi0pllbyte",
+ "core_bi_pll_test_se",
+ };
+
+@@ -124,7 +124,7 @@ static const struct parent_map gcc_parent_map_6[] = {
+
+ static const char * const gcc_parent_names_6[] = {
+ "cxo",
+- "dsi0_phy_pll_out_byteclk",
++ "dsi0pllbyte",
+ "core_bi_pll_test_se",
+ };
+
+@@ -167,7 +167,7 @@ static const struct parent_map gcc_parent_map_9[] = {
+ static const char * const gcc_parent_names_9[] = {
+ "cxo",
+ "gpll0_out_main",
+- "dsi0_phy_pll_out_dsiclk",
++ "dsi0pll",
+ "gpll6_out_aux",
+ "core_bi_pll_test_se",
+ };
+@@ -204,7 +204,7 @@ static const struct parent_map gcc_parent_map_12[] = {
+
+ static const char * const gcc_parent_names_12[] = {
+ "cxo",
+- "dsi0pll_pclk_src",
++ "dsi0pll",
+ "core_bi_pll_test_se",
+ };
+
+--
+2.39.2
+
--- /dev/null
+From c88260c3eb0c604fa064fba8cc74a773832f828a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Feb 2023 19:23:04 +0200
+Subject: clk: qcom: gpucc-sc7180: fix clk_dis_wait being programmed for CX
+ GDSC
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 658c82caffa042b351f5a1b6325819297a951a04 ]
+
+The gdsc_init() function will rewrite the CLK_DIS_WAIT field while
+registering the GDSC (writing the value 0x2 by default). This will
+override the setting done in the driver's probe function.
+
+Set cx_gdsc.clk_dis_wait_val to 8 to follow the intention of the probe
+function.
+
+Fixes: 745ff069a49c ("clk: qcom: Add graphics clock controller driver for SC7180")
+Reviewed-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230201172305.993146-1-dmitry.baryshkov@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gpucc-sc7180.c | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+diff --git a/drivers/clk/qcom/gpucc-sc7180.c b/drivers/clk/qcom/gpucc-sc7180.c
+index 88a739b6fec39..c51114e7e1e66 100644
+--- a/drivers/clk/qcom/gpucc-sc7180.c
++++ b/drivers/clk/qcom/gpucc-sc7180.c
+@@ -21,8 +21,6 @@
+ #define CX_GMU_CBCR_SLEEP_SHIFT 4
+ #define CX_GMU_CBCR_WAKE_MASK 0xF
+ #define CX_GMU_CBCR_WAKE_SHIFT 8
+-#define CLK_DIS_WAIT_SHIFT 12
+-#define CLK_DIS_WAIT_MASK (0xf << CLK_DIS_WAIT_SHIFT)
+
+ enum {
+ P_BI_TCXO,
+@@ -163,6 +161,7 @@ static struct clk_branch gpu_cc_cxo_clk = {
+ static struct gdsc cx_gdsc = {
+ .gdscr = 0x106c,
+ .gds_hw_ctrl = 0x1540,
++ .clk_dis_wait_val = 8,
+ .pd = {
+ .name = "cx_gdsc",
+ },
+@@ -245,10 +244,6 @@ static int gpu_cc_sc7180_probe(struct platform_device *pdev)
+ value = 0xF << CX_GMU_CBCR_WAKE_SHIFT | 0xF << CX_GMU_CBCR_SLEEP_SHIFT;
+ regmap_update_bits(regmap, 0x1098, mask, value);
+
+- /* Configure clk_dis_wait for gpu_cx_gdsc */
+- regmap_update_bits(regmap, 0x106c, CLK_DIS_WAIT_MASK,
+- 8 << CLK_DIS_WAIT_SHIFT);
+-
+ return qcom_cc_really_probe(pdev, &gpu_cc_sc7180_desc, regmap);
+ }
+
+--
+2.39.2
+
--- /dev/null
+From ad6c675fd80378451506325eb8da3c5e95af2e66 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Feb 2023 19:23:05 +0200
+Subject: clk: qcom: gpucc-sdm845: fix clk_dis_wait being programmed for CX
+ GDSC
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit cb81719e3c1165ef1bc33137dc628f750eed8ea4 ]
+
+The gdsc_init() function will rewrite the CLK_DIS_WAIT field while
+registering the GDSC (writing the value 0x2 by default). This will
+override the setting done in the driver's probe function.
+
+Set cx_gdsc.clk_dis_wait_val to 8 to follow the intention of the probe
+function.
+
+Fixes: 453361cdd757 ("clk: qcom: Add graphics clock controller driver for SDM845")
+Reviewed-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230201172305.993146-2-dmitry.baryshkov@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gpucc-sdm845.c | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+diff --git a/drivers/clk/qcom/gpucc-sdm845.c b/drivers/clk/qcom/gpucc-sdm845.c
+index 5663698b306b9..658c6ac700e1e 100644
+--- a/drivers/clk/qcom/gpucc-sdm845.c
++++ b/drivers/clk/qcom/gpucc-sdm845.c
+@@ -22,8 +22,6 @@
+ #define CX_GMU_CBCR_SLEEP_SHIFT 4
+ #define CX_GMU_CBCR_WAKE_MASK 0xf
+ #define CX_GMU_CBCR_WAKE_SHIFT 8
+-#define CLK_DIS_WAIT_SHIFT 12
+-#define CLK_DIS_WAIT_MASK (0xf << CLK_DIS_WAIT_SHIFT)
+
+ enum {
+ P_BI_TCXO,
+@@ -124,6 +122,7 @@ static struct clk_branch gpu_cc_cxo_clk = {
+ static struct gdsc gpu_cx_gdsc = {
+ .gdscr = 0x106c,
+ .gds_hw_ctrl = 0x1540,
++ .clk_dis_wait_val = 0x8,
+ .pd = {
+ .name = "gpu_cx_gdsc",
+ },
+@@ -196,10 +195,6 @@ static int gpu_cc_sdm845_probe(struct platform_device *pdev)
+ value = 0xf << CX_GMU_CBCR_WAKE_SHIFT | 0xf << CX_GMU_CBCR_SLEEP_SHIFT;
+ regmap_update_bits(regmap, 0x1098, mask, value);
+
+- /* Configure clk_dis_wait for gpu_cx_gdsc */
+- regmap_update_bits(regmap, 0x106c, CLK_DIS_WAIT_MASK,
+- 8 << CLK_DIS_WAIT_SHIFT);
+-
+ return qcom_cc_really_probe(pdev, &gpu_cc_sdm845_desc, regmap);
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 9c87007cfd8d476b59c821b00a5d6afceaa29b2f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Dec 2022 17:40:17 +0300
+Subject: clk: renesas: cpg-mssr: Fix use after free if cpg_mssr_common_init()
+ failed
+
+From: Alexey Khoroshilov <khoroshilov@ispras.ru>
+
+[ Upstream commit fbfd614aeaa2853c2c575299dfe2458db8eff67e ]
+
+If cpg_mssr_common_init() fails after assigning priv to global variable
+cpg_mssr_priv, it deallocates priv, but cpg_mssr_priv keeps dangling
+pointer that potentially can be used later.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: 1f7db7bbf031 ("clk: renesas: cpg-mssr: Add early clock support")
+Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/1671806417-32623-1-git-send-email-khoroshilov@ispras.ru
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/renesas/renesas-cpg-mssr.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c
+index 94db883703377..12e5a78819773 100644
+--- a/drivers/clk/renesas/renesas-cpg-mssr.c
++++ b/drivers/clk/renesas/renesas-cpg-mssr.c
+@@ -960,7 +960,6 @@ static int __init cpg_mssr_common_init(struct device *dev,
+ goto out_err;
+ }
+
+- cpg_mssr_priv = priv;
+ priv->num_core_clks = info->num_total_core_clks;
+ priv->num_mod_clks = info->num_hw_mod_clks;
+ priv->last_dt_core_clk = info->last_dt_core_clk;
+@@ -990,6 +989,8 @@ static int __init cpg_mssr_common_init(struct device *dev,
+ if (error)
+ goto out_err;
+
++ cpg_mssr_priv = priv;
++
+ return 0;
+
+ out_err:
+--
+2.39.2
+
--- /dev/null
+From 0c21e2ab3cdefcc6e777f498310d552f110f71a7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Jan 2023 09:23:34 +0100
+Subject: clk: renesas: cpg-mssr: Remove superfluous check in resume code
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit 1c052043c79af5f70e80e2acd4dd70904ae08666 ]
+
+When the code flow arrives at printing the error message in
+cpg_mssr_resume_noirq(), we know for sure that we are not running on an
+RZ/A Soc, as the code checked for that before.
+
+Fixes: ace342097768e35f ("clk: renesas: cpg-mssr: Fix STBCR suspend/resume handling")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/144a3e66d748c0c17f3524ac8fa6ece5bf5b6f1e.1673425314.git.geert+renesas@glider.be
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/renesas/renesas-cpg-mssr.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c
+index 12e5a78819773..a5a68e1e75490 100644
+--- a/drivers/clk/renesas/renesas-cpg-mssr.c
++++ b/drivers/clk/renesas/renesas-cpg-mssr.c
+@@ -914,9 +914,8 @@ static int cpg_mssr_resume_noirq(struct device *dev)
+ }
+
+ if (!i)
+- dev_warn(dev, "Failed to enable %s%u[0x%x]\n",
+- priv->reg_layout == CLK_REG_LAYOUT_RZ_A ?
+- "STB" : "SMSTP", reg, oldval & mask);
++ dev_warn(dev, "Failed to enable SMSTP%u[0x%x]\n", reg,
++ oldval & mask);
+ }
+
+ return 0;
+--
+2.39.2
+
--- /dev/null
+From 99c4d14adcf726801f997a540a0210dfb7fd6453 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Dec 2022 16:25:12 +0800
+Subject: clocksource: Suspend the watchdog temporarily when high read latency
+ detected
+
+From: Feng Tang <feng.tang@intel.com>
+
+[ Upstream commit b7082cdfc464bf9231300605d03eebf943dda307 ]
+
+Bugs have been reported on 8 sockets x86 machines in which the TSC was
+wrongly disabled when the system is under heavy workload.
+
+ [ 818.380354] clocksource: timekeeping watchdog on CPU336: hpet wd-wd read-back delay of 1203520ns
+ [ 818.436160] clocksource: wd-tsc-wd read-back delay of 181880ns, clock-skew test skipped!
+ [ 819.402962] clocksource: timekeeping watchdog on CPU338: hpet wd-wd read-back delay of 324000ns
+ [ 819.448036] clocksource: wd-tsc-wd read-back delay of 337240ns, clock-skew test skipped!
+ [ 819.880863] clocksource: timekeeping watchdog on CPU339: hpet read-back delay of 150280ns, attempt 3, marking unstable
+ [ 819.936243] tsc: Marking TSC unstable due to clocksource watchdog
+ [ 820.068173] TSC found unstable after boot, most likely due to broken BIOS. Use 'tsc=unstable'.
+ [ 820.092382] sched_clock: Marking unstable (818769414384, 1195404998)
+ [ 820.643627] clocksource: Checking clocksource tsc synchronization from CPU 267 to CPUs 0,4,25,70,126,430,557,564.
+ [ 821.067990] clocksource: Switched to clocksource hpet
+
+This can be reproduced by running memory intensive 'stream' tests,
+or some of the stress-ng subcases such as 'ioport'.
+
+The reason for these issues is the when system is under heavy load, the
+read latency of the clocksources can be very high. Even lightweight TSC
+reads can show high latencies, and latencies are much worse for external
+clocksources such as HPET or the APIC PM timer. These latencies can
+result in false-positive clocksource-unstable determinations.
+
+These issues were initially reported by a customer running on a production
+system, and this problem was reproduced on several generations of Xeon
+servers, especially when running the stress-ng test. These Xeon servers
+were not production systems, but they did have the latest steppings
+and firmware.
+
+Given that the clocksource watchdog is a continual diagnostic check with
+frequency of twice a second, there is no need to rush it when the system
+is under heavy load. Therefore, when high clocksource read latencies
+are detected, suspend the watchdog timer for 5 minutes.
+
+Signed-off-by: Feng Tang <feng.tang@intel.com>
+Acked-by: Waiman Long <longman@redhat.com>
+Cc: John Stultz <jstultz@google.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Stephen Boyd <sboyd@kernel.org>
+Cc: Feng Tang <feng.tang@intel.com>
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/time/clocksource.c | 45 ++++++++++++++++++++++++++++-----------
+ 1 file changed, 32 insertions(+), 13 deletions(-)
+
+diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
+index e34ceb91f4c5a..86e0fbe583f2b 100644
+--- a/kernel/time/clocksource.c
++++ b/kernel/time/clocksource.c
+@@ -312,6 +312,15 @@ static void clocksource_verify_percpu(struct clocksource *cs)
+ testcpu, cs_nsec_min, cs_nsec_max, cs->name);
+ }
+
++static inline void clocksource_reset_watchdog(void)
++{
++ struct clocksource *cs;
++
++ list_for_each_entry(cs, &watchdog_list, wd_list)
++ cs->flags &= ~CLOCK_SOURCE_WATCHDOG;
++}
++
++
+ static void clocksource_watchdog(struct timer_list *unused)
+ {
+ u64 csnow, wdnow, cslast, wdlast, delta;
+@@ -319,6 +328,7 @@ static void clocksource_watchdog(struct timer_list *unused)
+ int64_t wd_nsec, cs_nsec;
+ struct clocksource *cs;
+ enum wd_read_status read_ret;
++ unsigned long extra_wait = 0;
+ u32 md;
+
+ spin_lock(&watchdog_lock);
+@@ -338,13 +348,30 @@ static void clocksource_watchdog(struct timer_list *unused)
+
+ read_ret = cs_watchdog_read(cs, &csnow, &wdnow);
+
+- if (read_ret != WD_READ_SUCCESS) {
+- if (read_ret == WD_READ_UNSTABLE)
+- /* Clock readout unreliable, so give it up. */
+- __clocksource_unstable(cs);
++ if (read_ret == WD_READ_UNSTABLE) {
++ /* Clock readout unreliable, so give it up. */
++ __clocksource_unstable(cs);
+ continue;
+ }
+
++ /*
++ * When WD_READ_SKIP is returned, it means the system is likely
++ * under very heavy load, where the latency of reading
++ * watchdog/clocksource is very big, and affect the accuracy of
++ * watchdog check. So give system some space and suspend the
++ * watchdog check for 5 minutes.
++ */
++ if (read_ret == WD_READ_SKIP) {
++ /*
++ * As the watchdog timer will be suspended, and
++ * cs->last could keep unchanged for 5 minutes, reset
++ * the counters.
++ */
++ clocksource_reset_watchdog();
++ extra_wait = HZ * 300;
++ break;
++ }
++
+ /* Clocksource initialized ? */
+ if (!(cs->flags & CLOCK_SOURCE_WATCHDOG) ||
+ atomic_read(&watchdog_reset_pending)) {
+@@ -434,7 +461,7 @@ static void clocksource_watchdog(struct timer_list *unused)
+ * pair clocksource_stop_watchdog() clocksource_start_watchdog().
+ */
+ if (!timer_pending(&watchdog_timer)) {
+- watchdog_timer.expires += WATCHDOG_INTERVAL;
++ watchdog_timer.expires += WATCHDOG_INTERVAL + extra_wait;
+ add_timer_on(&watchdog_timer, next_cpu);
+ }
+ out:
+@@ -459,14 +486,6 @@ static inline void clocksource_stop_watchdog(void)
+ watchdog_running = 0;
+ }
+
+-static inline void clocksource_reset_watchdog(void)
+-{
+- struct clocksource *cs;
+-
+- list_for_each_entry(cs, &watchdog_list, wd_list)
+- cs->flags &= ~CLOCK_SOURCE_WATCHDOG;
+-}
+-
+ static void clocksource_resume_watchdog(void)
+ {
+ atomic_inc(&watchdog_reset_pending);
+--
+2.39.2
+
--- /dev/null
+From 28cf33678a21609837addcaeb06a81280fac352e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 27 Jan 2023 14:39:21 -0800
+Subject: coda: Avoid partial allocation of sig_inputArgs
+
+From: Kees Cook <keescook@chromium.org>
+
+[ Upstream commit 48df133578c70185a95a49390d42df1996ddba2a ]
+
+GCC does not like having a partially allocated object, since it cannot
+reason about it for bounds checking when it is passed to other code.
+Instead, fully allocate sig_inputArgs. (Alternatively, sig_inputArgs
+should be defined as a struct coda_in_hdr, if it is actually not using
+any other part of the union.) Seen under GCC 13:
+
+../fs/coda/upcall.c: In function 'coda_upcall':
+../fs/coda/upcall.c:801:22: warning: array subscript 'union inputArgs[0]' is partly outside array bounds of 'unsigned char[20]' [-Warray-bounds=]
+ 801 | sig_inputArgs->ih.opcode = CODA_SIGNAL;
+ | ^~
+
+Cc: Jan Harkes <jaharkes@cs.cmu.edu>
+Cc: coda@cs.cmu.edu
+Cc: codalist@coda.cs.cmu.edu
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Link: https://lore.kernel.org/r/20230127223921.never.882-kees@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/coda/upcall.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/coda/upcall.c b/fs/coda/upcall.c
+index eb3b1898da462..610484c90260b 100644
+--- a/fs/coda/upcall.c
++++ b/fs/coda/upcall.c
+@@ -790,7 +790,7 @@ static int coda_upcall(struct venus_comm *vcp,
+ sig_req = kmalloc(sizeof(struct upc_req), GFP_KERNEL);
+ if (!sig_req) goto exit;
+
+- sig_inputArgs = kvzalloc(sizeof(struct coda_in_hdr), GFP_KERNEL);
++ sig_inputArgs = kvzalloc(sizeof(*sig_inputArgs), GFP_KERNEL);
+ if (!sig_inputArgs) {
+ kfree(sig_req);
+ goto exit;
+--
+2.39.2
+
--- /dev/null
+From ce947a7ba44d2625f840f1169cefe671b255288e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Dec 2022 14:18:46 -0800
+Subject: crypto: ccp - Avoid page allocation failure warning for SEV_GET_ID2
+
+From: David Rientjes <rientjes@google.com>
+
+[ Upstream commit 91dfd98216d817ec5f1c55890bacb7b4fe9b068a ]
+
+For SEV_GET_ID2, the user provided length does not have a specified
+limitation because the length of the ID may change in the future. The
+kernel memory allocation, however, is implicitly limited to 4MB on x86 by
+the page allocator, otherwise the kzalloc() will fail.
+
+When this happens, it is best not to spam the kernel log with the warning.
+Simply fail the allocation and return ENOMEM to the user.
+
+Fixes: d6112ea0cb34 ("crypto: ccp - introduce SEV_GET_ID2 command")
+Reported-by: Andy Nguyen <theflow@google.com>
+Reported-by: Peter Gonda <pgonda@google.com>
+Suggested-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: David Rientjes <rientjes@google.com>
+Acked-by: Tom Lendacky <thomas.lendacky@amd.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/ccp/sev-dev.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c
+index 6edd938ce6acc..e70ae98de1189 100644
+--- a/drivers/crypto/ccp/sev-dev.c
++++ b/drivers/crypto/ccp/sev-dev.c
+@@ -631,7 +631,14 @@ static int sev_ioctl_do_get_id2(struct sev_issue_cmd *argp)
+ input_address = (void __user *)input.address;
+
+ if (input.address && input.length) {
+- id_blob = kzalloc(input.length, GFP_KERNEL);
++ /*
++ * The length of the ID shouldn't be assumed by software since
++ * it may change in the future. The allocation size is limited
++ * to 1 << (PAGE_SHIFT + MAX_ORDER - 1) by the page allocator.
++ * If the allocation fails, simply return ENOMEM rather than
++ * warning in the kernel log.
++ */
++ id_blob = kzalloc(input.length, GFP_KERNEL | __GFP_NOWARN);
+ if (!id_blob)
+ return -ENOMEM;
+
+--
+2.39.2
+
--- /dev/null
+From 2063a19206867bfec3eb8e316fcb0d8e8eee56aa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Jan 2023 10:15:02 +0800
+Subject: crypto: ccp - Failure on re-initialization due to duplicate sysfs
+ filename
+
+From: Koba Ko <koba.taiwan@gmail.com>
+
+[ Upstream commit 299bf602b3f92f1456aef59c6413591fb02e762a ]
+
+The following warning appears during the CCP module re-initialization:
+
+[ 140.965403] sysfs: cannot create duplicate filename
+'/devices/pci0000:00/0000:00:07.1/0000:03:00.2/dma/dma0chan0'
+[ 140.975736] CPU: 0 PID: 388 Comm: kworker/0:2 Kdump: loaded Not
+tainted 6.2.0-0.rc2.18.eln124.x86_64 #1
+[ 140.985185] Hardware name: HPE ProLiant DL325 Gen10/ProLiant DL325
+Gen10, BIOS A41 07/17/2020
+[ 140.993761] Workqueue: events work_for_cpu_fn
+[ 140.998151] Call Trace:
+[ 141.000613] <TASK>
+[ 141.002726] dump_stack_lvl+0x33/0x46
+[ 141.006415] sysfs_warn_dup.cold+0x17/0x23
+[ 141.010542] sysfs_create_dir_ns+0xba/0xd0
+[ 141.014670] kobject_add_internal+0xba/0x260
+[ 141.018970] kobject_add+0x81/0xb0
+[ 141.022395] device_add+0xdc/0x7e0
+[ 141.025822] ? complete_all+0x20/0x90
+[ 141.029510] __dma_async_device_channel_register+0xc9/0x130
+[ 141.035119] dma_async_device_register+0x19e/0x3b0
+[ 141.039943] ccp_dmaengine_register+0x334/0x3f0 [ccp]
+[ 141.045042] ccp5_init+0x662/0x6a0 [ccp]
+[ 141.049000] ? devm_kmalloc+0x40/0xd0
+[ 141.052688] ccp_dev_init+0xbb/0xf0 [ccp]
+[ 141.056732] ? __pci_set_master+0x56/0xd0
+[ 141.060768] sp_init+0x70/0x90 [ccp]
+[ 141.064377] sp_pci_probe+0x186/0x1b0 [ccp]
+[ 141.068596] local_pci_probe+0x41/0x80
+[ 141.072374] work_for_cpu_fn+0x16/0x20
+[ 141.076145] process_one_work+0x1c8/0x380
+[ 141.080181] worker_thread+0x1ab/0x380
+[ 141.083953] ? __pfx_worker_thread+0x10/0x10
+[ 141.088250] kthread+0xda/0x100
+[ 141.091413] ? __pfx_kthread+0x10/0x10
+[ 141.095185] ret_from_fork+0x2c/0x50
+[ 141.098788] </TASK>
+[ 141.100996] kobject_add_internal failed for dma0chan0 with -EEXIST,
+don't try to register things with the same name in the same directory.
+[ 141.113703] ccp 0000:03:00.2: ccp initialization failed
+
+The /dma/dma0chan0 sysfs file is not removed since dma_chan object
+has been released in ccp_dma_release() before releasing dma device.
+A correct procedure would be: release dma channels first => unregister
+dma device => release ccp dma object.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=216888
+Fixes: 68dbe80f5b51 ("crypto: ccp - Release dma channels before dmaengine unrgister")
+Tested-by: Vladis Dronov <vdronov@redhat.com>
+Signed-off-by: Koba Ko <koba.ko@canonical.com>
+Reviewed-by: Vladis Dronov <vdronov@redhat.com>
+Acked-by: Tom Lendacky <thomas.lendacky@amd.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/ccp/ccp-dmaengine.c | 21 +++++++++++++++++----
+ 1 file changed, 17 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/crypto/ccp/ccp-dmaengine.c b/drivers/crypto/ccp/ccp-dmaengine.c
+index b9299defb431d..e416456b2b8aa 100644
+--- a/drivers/crypto/ccp/ccp-dmaengine.c
++++ b/drivers/crypto/ccp/ccp-dmaengine.c
+@@ -643,14 +643,26 @@ static void ccp_dma_release(struct ccp_device *ccp)
+ chan = ccp->ccp_dma_chan + i;
+ dma_chan = &chan->dma_chan;
+
+- if (dma_chan->client_count)
+- dma_release_channel(dma_chan);
+-
+ tasklet_kill(&chan->cleanup_tasklet);
+ list_del_rcu(&dma_chan->device_node);
+ }
+ }
+
++static void ccp_dma_release_channels(struct ccp_device *ccp)
++{
++ struct ccp_dma_chan *chan;
++ struct dma_chan *dma_chan;
++ unsigned int i;
++
++ for (i = 0; i < ccp->cmd_q_count; i++) {
++ chan = ccp->ccp_dma_chan + i;
++ dma_chan = &chan->dma_chan;
++
++ if (dma_chan->client_count)
++ dma_release_channel(dma_chan);
++ }
++}
++
+ int ccp_dmaengine_register(struct ccp_device *ccp)
+ {
+ struct ccp_dma_chan *chan;
+@@ -771,8 +783,9 @@ void ccp_dmaengine_unregister(struct ccp_device *ccp)
+ if (!dmaengine)
+ return;
+
+- ccp_dma_release(ccp);
++ ccp_dma_release_channels(ccp);
+ dma_async_device_unregister(dma_dev);
++ ccp_dma_release(ccp);
+
+ kmem_cache_destroy(ccp->dma_desc_cache);
+ kmem_cache_destroy(ccp->dma_cmd_cache);
+--
+2.39.2
+
--- /dev/null
+From 513f6612427e524f5eaa50a5fd6260e8a21c9f7b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 23 Jan 2023 16:53:08 -0600
+Subject: crypto: ccp - Flush the SEV-ES TMR memory before giving it to
+ firmware
+
+From: Tom Lendacky <thomas.lendacky@amd.com>
+
+[ Upstream commit 46a334a98f585ef78d51d8f5736596887bdd7f54 ]
+
+Perform a cache flush on the SEV-ES TMR memory after allocation to prevent
+any possibility of the firmware encountering an error should dirty cache
+lines be present. Use clflush_cache_range() to flush the SEV-ES TMR memory.
+
+Fixes: 97f9ac3db661 ("crypto: ccp - Add support for SEV-ES to the PSP driver")
+Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/ccp/sev-dev.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c
+index 8a900226d73a3..856d867f46ebb 100644
+--- a/drivers/crypto/ccp/sev-dev.c
++++ b/drivers/crypto/ccp/sev-dev.c
+@@ -23,6 +23,7 @@
+ #include <linux/gfp.h>
+
+ #include <asm/smp.h>
++#include <asm/cacheflush.h>
+
+ #include "psp-dev.h"
+ #include "sev-dev.h"
+@@ -1067,7 +1068,10 @@ void sev_pci_init(void)
+
+ /* Obtain the TMR memory area for SEV-ES use */
+ sev_es_tmr = sev_fw_alloc(SEV_ES_TMR_SIZE);
+- if (!sev_es_tmr)
++ if (sev_es_tmr)
++ /* Must flush the cache before giving it to the firmware */
++ clflush_cache_range(sev_es_tmr, SEV_ES_TMR_SIZE);
++ else
+ dev_warn(sev->dev,
+ "SEV: TMR allocation failed, SEV-ES support unavailable\n");
+
+--
+2.39.2
+
--- /dev/null
+From f52c519e0e08c770a48de84d38cd55b296ad9caf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Dec 2021 15:33:04 -0800
+Subject: crypto: ccp - Refactor out sev_fw_alloc()
+
+From: Peter Gonda <pgonda@google.com>
+
+[ Upstream commit cc17982d58d1e67eab831e7023ede999dda56173 ]
+
+Create a helper function sev_fw_alloc() which can be used to allocate
+aligned memory regions for use by the PSP firmware. Currently only used
+for the SEV-ES TMR region but will be used for the SEV_INIT_EX NV memory
+region.
+
+Signed-off-by: Peter Gonda <pgonda@google.com>
+Reviewed-by: Marc Orr <marcorr@google.com>
+Acked-by: David Rientjes <rientjes@google.com>
+Acked-by: Brijesh Singh <brijesh.singh@amd.com>
+Cc: Tom Lendacky <thomas.lendacky@amd.com>
+Cc: Brijesh Singh <brijesh.singh@amd.com>
+Cc: Marc Orr <marcorr@google.com>
+Cc: Joerg Roedel <jroedel@suse.de>
+Cc: Herbert Xu <herbert@gondor.apana.org.au>
+Cc: David Rientjes <rientjes@google.com>
+Cc: John Allen <john.allen@amd.com>
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: Paolo Bonzini <pbonzini@redhat.com>
+Cc: linux-crypto@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Stable-dep-of: 46a334a98f58 ("crypto: ccp - Flush the SEV-ES TMR memory before giving it to firmware")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/ccp/sev-dev.c | 20 +++++++++++++-------
+ 1 file changed, 13 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c
+index e70ae98de1189..8a900226d73a3 100644
+--- a/drivers/crypto/ccp/sev-dev.c
++++ b/drivers/crypto/ccp/sev-dev.c
+@@ -138,6 +138,17 @@ static int sev_cmd_buffer_len(int cmd)
+ return 0;
+ }
+
++static void *sev_fw_alloc(unsigned long len)
++{
++ struct page *page;
++
++ page = alloc_pages(GFP_KERNEL, get_order(len));
++ if (!page)
++ return NULL;
++
++ return page_address(page);
++}
++
+ static int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret)
+ {
+ struct psp_device *psp = psp_master;
+@@ -1040,7 +1051,6 @@ EXPORT_SYMBOL_GPL(sev_issue_cmd_external_user);
+ void sev_pci_init(void)
+ {
+ struct sev_device *sev = psp_master->sev_data;
+- struct page *tmr_page;
+ int error, rc;
+
+ if (!sev)
+@@ -1056,14 +1066,10 @@ void sev_pci_init(void)
+ sev_get_api_version();
+
+ /* Obtain the TMR memory area for SEV-ES use */
+- tmr_page = alloc_pages(GFP_KERNEL, get_order(SEV_ES_TMR_SIZE));
+- if (tmr_page) {
+- sev_es_tmr = page_address(tmr_page);
+- } else {
+- sev_es_tmr = NULL;
++ sev_es_tmr = sev_fw_alloc(SEV_ES_TMR_SIZE);
++ if (!sev_es_tmr)
+ dev_warn(sev->dev,
+ "SEV: TMR allocation failed, SEV-ES support unavailable\n");
+- }
+
+ /* Initialize the platform */
+ rc = sev_platform_init(&error);
+--
+2.39.2
+
--- /dev/null
+From 70da80ef89c211367f7f6d9f9e6f046b8230db43 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 May 2022 15:31:26 +0000
+Subject: crypto: ccp - Use kzalloc for sev ioctl interfaces to prevent kernel
+ memory leak
+
+From: John Allen <john.allen@amd.com>
+
+[ Upstream commit 13dc15a3f5fd7f884e4bfa8c011a0ae868df12ae ]
+
+For some sev ioctl interfaces, input may be passed that is less than or
+equal to SEV_FW_BLOB_MAX_SIZE, but larger than the data that PSP
+firmware returns. In this case, kmalloc will allocate memory that is the
+size of the input rather than the size of the data. Since PSP firmware
+doesn't fully overwrite the buffer, the sev ioctl interfaces with the
+issue may return uninitialized slab memory.
+
+Currently, all of the ioctl interfaces in the ccp driver are safe, but
+to prevent future problems, change all ioctl interfaces that allocate
+memory with kmalloc to use kzalloc and memset the data buffer to zero
+in sev_ioctl_do_platform_status.
+
+Fixes: 38103671aad3 ("crypto: ccp: Use the stack and common buffer for status commands")
+Fixes: e799035609e15 ("crypto: ccp: Implement SEV_PEK_CSR ioctl command")
+Fixes: 76a2b524a4b1d ("crypto: ccp: Implement SEV_PDH_CERT_EXPORT ioctl command")
+Fixes: d6112ea0cb344 ("crypto: ccp - introduce SEV_GET_ID2 command")
+Cc: stable@vger.kernel.org
+Reported-by: Andy Nguyen <theflow@google.com>
+Suggested-by: David Rientjes <rientjes@google.com>
+Suggested-by: Peter Gonda <pgonda@google.com>
+Signed-off-by: John Allen <john.allen@amd.com>
+Reviewed-by: Peter Gonda <pgonda@google.com>
+Acked-by: David Rientjes <rientjes@google.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Stable-dep-of: 91dfd98216d8 ("crypto: ccp - Avoid page allocation failure warning for SEV_GET_ID2")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/ccp/sev-dev.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c
+index 1aac3a12a6c7c..6edd938ce6acc 100644
+--- a/drivers/crypto/ccp/sev-dev.c
++++ b/drivers/crypto/ccp/sev-dev.c
+@@ -352,6 +352,8 @@ static int sev_ioctl_do_platform_status(struct sev_issue_cmd *argp)
+ struct sev_user_data_status data;
+ int ret;
+
++ memset(&data, 0, sizeof(data));
++
+ ret = __sev_do_cmd_locked(SEV_CMD_PLATFORM_STATUS, &data, &argp->error);
+ if (ret)
+ return ret;
+@@ -405,7 +407,7 @@ static int sev_ioctl_do_pek_csr(struct sev_issue_cmd *argp, bool writable)
+ if (input.length > SEV_FW_BLOB_MAX_SIZE)
+ return -EFAULT;
+
+- blob = kmalloc(input.length, GFP_KERNEL);
++ blob = kzalloc(input.length, GFP_KERNEL);
+ if (!blob)
+ return -ENOMEM;
+
+@@ -629,7 +631,7 @@ static int sev_ioctl_do_get_id2(struct sev_issue_cmd *argp)
+ input_address = (void __user *)input.address;
+
+ if (input.address && input.length) {
+- id_blob = kmalloc(input.length, GFP_KERNEL);
++ id_blob = kzalloc(input.length, GFP_KERNEL);
+ if (!id_blob)
+ return -ENOMEM;
+
+@@ -748,14 +750,14 @@ static int sev_ioctl_do_pdh_export(struct sev_issue_cmd *argp, bool writable)
+ if (input.cert_chain_len > SEV_FW_BLOB_MAX_SIZE)
+ return -EFAULT;
+
+- pdh_blob = kmalloc(input.pdh_cert_len, GFP_KERNEL);
++ pdh_blob = kzalloc(input.pdh_cert_len, GFP_KERNEL);
+ if (!pdh_blob)
+ return -ENOMEM;
+
+ data.pdh_cert_address = __psp_pa(pdh_blob);
+ data.pdh_cert_len = input.pdh_cert_len;
+
+- cert_blob = kmalloc(input.cert_chain_len, GFP_KERNEL);
++ cert_blob = kzalloc(input.cert_chain_len, GFP_KERNEL);
+ if (!cert_blob) {
+ ret = -ENOMEM;
+ goto e_free_pdh;
+--
+2.39.2
+
--- /dev/null
+From 7127a1ef88e7ea3baa2cc56d15610c16002c53e0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Apr 2021 15:49:50 -0700
+Subject: crypto: ccp: Use the stack and common buffer for status commands
+
+From: Sean Christopherson <seanjc@google.com>
+
+[ Upstream commit 38103671aad38e888743dd26c767869cfc15adca ]
+
+Drop the dedicated status_cmd_buf and instead use a local variable for
+PLATFORM_STATUS. Now that the low level helper uses an internal buffer
+for all commands, using the stack for the upper layers is safe even when
+running with CONFIG_VMAP_STACK=y.
+
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Message-Id: <20210406224952.4177376-7-seanjc@google.com>
+Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
+Acked-by: Tom Lendacky <thomas.lendacky@amd.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Stable-dep-of: 91dfd98216d8 ("crypto: ccp - Avoid page allocation failure warning for SEV_GET_ID2")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/ccp/sev-dev.c | 27 ++++++++++++---------------
+ drivers/crypto/ccp/sev-dev.h | 1 -
+ 2 files changed, 12 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c
+index 75341ad2fdd8a..1aac3a12a6c7c 100644
+--- a/drivers/crypto/ccp/sev-dev.c
++++ b/drivers/crypto/ccp/sev-dev.c
+@@ -304,15 +304,14 @@ static int sev_platform_shutdown(int *error)
+
+ static int sev_get_platform_state(int *state, int *error)
+ {
+- struct sev_device *sev = psp_master->sev_data;
++ struct sev_user_data_status data;
+ int rc;
+
+- rc = __sev_do_cmd_locked(SEV_CMD_PLATFORM_STATUS,
+- &sev->status_cmd_buf, error);
++ rc = __sev_do_cmd_locked(SEV_CMD_PLATFORM_STATUS, &data, error);
+ if (rc)
+ return rc;
+
+- *state = sev->status_cmd_buf.state;
++ *state = data.state;
+ return rc;
+ }
+
+@@ -350,15 +349,14 @@ static int sev_ioctl_do_reset(struct sev_issue_cmd *argp, bool writable)
+
+ static int sev_ioctl_do_platform_status(struct sev_issue_cmd *argp)
+ {
+- struct sev_device *sev = psp_master->sev_data;
+- struct sev_user_data_status *data = &sev->status_cmd_buf;
++ struct sev_user_data_status data;
+ int ret;
+
+- ret = __sev_do_cmd_locked(SEV_CMD_PLATFORM_STATUS, data, &argp->error);
++ ret = __sev_do_cmd_locked(SEV_CMD_PLATFORM_STATUS, &data, &argp->error);
+ if (ret)
+ return ret;
+
+- if (copy_to_user((void __user *)argp->data, data, sizeof(*data)))
++ if (copy_to_user((void __user *)argp->data, &data, sizeof(data)))
+ ret = -EFAULT;
+
+ return ret;
+@@ -457,21 +455,20 @@ EXPORT_SYMBOL_GPL(psp_copy_user_blob);
+ static int sev_get_api_version(void)
+ {
+ struct sev_device *sev = psp_master->sev_data;
+- struct sev_user_data_status *status;
++ struct sev_user_data_status status;
+ int error = 0, ret;
+
+- status = &sev->status_cmd_buf;
+- ret = sev_platform_status(status, &error);
++ ret = sev_platform_status(&status, &error);
+ if (ret) {
+ dev_err(sev->dev,
+ "SEV: failed to get status. Error: %#x\n", error);
+ return 1;
+ }
+
+- sev->api_major = status->api_major;
+- sev->api_minor = status->api_minor;
+- sev->build = status->build;
+- sev->state = status->state;
++ sev->api_major = status.api_major;
++ sev->api_minor = status.api_minor;
++ sev->build = status.build;
++ sev->state = status.state;
+
+ return 0;
+ }
+diff --git a/drivers/crypto/ccp/sev-dev.h b/drivers/crypto/ccp/sev-dev.h
+index dd5c4fe82914c..3b0cd0f854df9 100644
+--- a/drivers/crypto/ccp/sev-dev.h
++++ b/drivers/crypto/ccp/sev-dev.h
+@@ -46,7 +46,6 @@ struct sev_device {
+ unsigned int int_rcvd;
+ wait_queue_head_t int_queue;
+ struct sev_misc_dev *misc;
+- struct sev_user_data_status status_cmd_buf;
+ struct sev_data_init init_cmd_buf;
+
+ u8 api_major;
+--
+2.39.2
+
--- /dev/null
+From e50aba86b1f8e2824fb966688fb0bc1c9c2f8479 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Apr 2021 15:49:49 -0700
+Subject: crypto: ccp: Use the stack for small SEV command buffers
+
+From: Sean Christopherson <seanjc@google.com>
+
+[ Upstream commit e4a9af799e5539b0feb99571f0aaed5a3c81dc5a ]
+
+For commands with small input/output buffers, use the local stack to
+"allocate" the structures used to communicate with the PSP. Now that
+__sev_do_cmd_locked() gracefully handles vmalloc'd buffers, there's no
+reason to avoid using the stack, e.g. CONFIG_VMAP_STACK=y will just work.
+
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Message-Id: <20210406224952.4177376-6-seanjc@google.com>
+Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
+Acked-by: Tom Lendacky <thomas.lendacky@amd.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Stable-dep-of: 91dfd98216d8 ("crypto: ccp - Avoid page allocation failure warning for SEV_GET_ID2")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/ccp/sev-dev.c | 117 +++++++++++++----------------------
+ 1 file changed, 44 insertions(+), 73 deletions(-)
+
+diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c
+index ed39a22e1b2b9..75341ad2fdd8a 100644
+--- a/drivers/crypto/ccp/sev-dev.c
++++ b/drivers/crypto/ccp/sev-dev.c
+@@ -385,7 +385,7 @@ static int sev_ioctl_do_pek_csr(struct sev_issue_cmd *argp, bool writable)
+ {
+ struct sev_device *sev = psp_master->sev_data;
+ struct sev_user_data_pek_csr input;
+- struct sev_data_pek_csr *data;
++ struct sev_data_pek_csr data;
+ void __user *input_address;
+ void *blob = NULL;
+ int ret;
+@@ -396,9 +396,7 @@ static int sev_ioctl_do_pek_csr(struct sev_issue_cmd *argp, bool writable)
+ if (copy_from_user(&input, (void __user *)argp->data, sizeof(input)))
+ return -EFAULT;
+
+- data = kzalloc(sizeof(*data), GFP_KERNEL);
+- if (!data)
+- return -ENOMEM;
++ memset(&data, 0, sizeof(data));
+
+ /* userspace wants to query CSR length */
+ if (!input.address || !input.length)
+@@ -406,19 +404,15 @@ static int sev_ioctl_do_pek_csr(struct sev_issue_cmd *argp, bool writable)
+
+ /* allocate a physically contiguous buffer to store the CSR blob */
+ input_address = (void __user *)input.address;
+- if (input.length > SEV_FW_BLOB_MAX_SIZE) {
+- ret = -EFAULT;
+- goto e_free;
+- }
++ if (input.length > SEV_FW_BLOB_MAX_SIZE)
++ return -EFAULT;
+
+ blob = kmalloc(input.length, GFP_KERNEL);
+- if (!blob) {
+- ret = -ENOMEM;
+- goto e_free;
+- }
++ if (!blob)
++ return -ENOMEM;
+
+- data->address = __psp_pa(blob);
+- data->len = input.length;
++ data.address = __psp_pa(blob);
++ data.len = input.length;
+
+ cmd:
+ if (sev->state == SEV_STATE_UNINIT) {
+@@ -427,10 +421,10 @@ static int sev_ioctl_do_pek_csr(struct sev_issue_cmd *argp, bool writable)
+ goto e_free_blob;
+ }
+
+- ret = __sev_do_cmd_locked(SEV_CMD_PEK_CSR, data, &argp->error);
++ ret = __sev_do_cmd_locked(SEV_CMD_PEK_CSR, &data, &argp->error);
+
+ /* If we query the CSR length, FW responded with expected data. */
+- input.length = data->len;
++ input.length = data.len;
+
+ if (copy_to_user((void __user *)argp->data, &input, sizeof(input))) {
+ ret = -EFAULT;
+@@ -444,8 +438,6 @@ static int sev_ioctl_do_pek_csr(struct sev_issue_cmd *argp, bool writable)
+
+ e_free_blob:
+ kfree(blob);
+-e_free:
+- kfree(data);
+ return ret;
+ }
+
+@@ -577,7 +569,7 @@ static int sev_ioctl_do_pek_import(struct sev_issue_cmd *argp, bool writable)
+ {
+ struct sev_device *sev = psp_master->sev_data;
+ struct sev_user_data_pek_cert_import input;
+- struct sev_data_pek_cert_import *data;
++ struct sev_data_pek_cert_import data;
+ void *pek_blob, *oca_blob;
+ int ret;
+
+@@ -587,19 +579,14 @@ static int sev_ioctl_do_pek_import(struct sev_issue_cmd *argp, bool writable)
+ if (copy_from_user(&input, (void __user *)argp->data, sizeof(input)))
+ return -EFAULT;
+
+- data = kzalloc(sizeof(*data), GFP_KERNEL);
+- if (!data)
+- return -ENOMEM;
+-
+ /* copy PEK certificate blobs from userspace */
+ pek_blob = psp_copy_user_blob(input.pek_cert_address, input.pek_cert_len);
+- if (IS_ERR(pek_blob)) {
+- ret = PTR_ERR(pek_blob);
+- goto e_free;
+- }
++ if (IS_ERR(pek_blob))
++ return PTR_ERR(pek_blob);
+
+- data->pek_cert_address = __psp_pa(pek_blob);
+- data->pek_cert_len = input.pek_cert_len;
++ data.reserved = 0;
++ data.pek_cert_address = __psp_pa(pek_blob);
++ data.pek_cert_len = input.pek_cert_len;
+
+ /* copy PEK certificate blobs from userspace */
+ oca_blob = psp_copy_user_blob(input.oca_cert_address, input.oca_cert_len);
+@@ -608,8 +595,8 @@ static int sev_ioctl_do_pek_import(struct sev_issue_cmd *argp, bool writable)
+ goto e_free_pek;
+ }
+
+- data->oca_cert_address = __psp_pa(oca_blob);
+- data->oca_cert_len = input.oca_cert_len;
++ data.oca_cert_address = __psp_pa(oca_blob);
++ data.oca_cert_len = input.oca_cert_len;
+
+ /* If platform is not in INIT state then transition it to INIT */
+ if (sev->state != SEV_STATE_INIT) {
+@@ -618,21 +605,19 @@ static int sev_ioctl_do_pek_import(struct sev_issue_cmd *argp, bool writable)
+ goto e_free_oca;
+ }
+
+- ret = __sev_do_cmd_locked(SEV_CMD_PEK_CERT_IMPORT, data, &argp->error);
++ ret = __sev_do_cmd_locked(SEV_CMD_PEK_CERT_IMPORT, &data, &argp->error);
+
+ e_free_oca:
+ kfree(oca_blob);
+ e_free_pek:
+ kfree(pek_blob);
+-e_free:
+- kfree(data);
+ return ret;
+ }
+
+ static int sev_ioctl_do_get_id2(struct sev_issue_cmd *argp)
+ {
+ struct sev_user_data_get_id2 input;
+- struct sev_data_get_id *data;
++ struct sev_data_get_id data;
+ void __user *input_address;
+ void *id_blob = NULL;
+ int ret;
+@@ -646,28 +631,25 @@ static int sev_ioctl_do_get_id2(struct sev_issue_cmd *argp)
+
+ input_address = (void __user *)input.address;
+
+- data = kzalloc(sizeof(*data), GFP_KERNEL);
+- if (!data)
+- return -ENOMEM;
+-
+ if (input.address && input.length) {
+ id_blob = kmalloc(input.length, GFP_KERNEL);
+- if (!id_blob) {
+- kfree(data);
++ if (!id_blob)
+ return -ENOMEM;
+- }
+
+- data->address = __psp_pa(id_blob);
+- data->len = input.length;
++ data.address = __psp_pa(id_blob);
++ data.len = input.length;
++ } else {
++ data.address = 0;
++ data.len = 0;
+ }
+
+- ret = __sev_do_cmd_locked(SEV_CMD_GET_ID, data, &argp->error);
++ ret = __sev_do_cmd_locked(SEV_CMD_GET_ID, &data, &argp->error);
+
+ /*
+ * Firmware will return the length of the ID value (either the minimum
+ * required length or the actual length written), return it to the user.
+ */
+- input.length = data->len;
++ input.length = data.len;
+
+ if (copy_to_user((void __user *)argp->data, &input, sizeof(input))) {
+ ret = -EFAULT;
+@@ -675,7 +657,7 @@ static int sev_ioctl_do_get_id2(struct sev_issue_cmd *argp)
+ }
+
+ if (id_blob) {
+- if (copy_to_user(input_address, id_blob, data->len)) {
++ if (copy_to_user(input_address, id_blob, data.len)) {
+ ret = -EFAULT;
+ goto e_free;
+ }
+@@ -683,7 +665,6 @@ static int sev_ioctl_do_get_id2(struct sev_issue_cmd *argp)
+
+ e_free:
+ kfree(id_blob);
+- kfree(data);
+
+ return ret;
+ }
+@@ -733,7 +714,7 @@ static int sev_ioctl_do_pdh_export(struct sev_issue_cmd *argp, bool writable)
+ struct sev_device *sev = psp_master->sev_data;
+ struct sev_user_data_pdh_cert_export input;
+ void *pdh_blob = NULL, *cert_blob = NULL;
+- struct sev_data_pdh_cert_export *data;
++ struct sev_data_pdh_cert_export data;
+ void __user *input_cert_chain_address;
+ void __user *input_pdh_cert_address;
+ int ret;
+@@ -751,9 +732,7 @@ static int sev_ioctl_do_pdh_export(struct sev_issue_cmd *argp, bool writable)
+ if (copy_from_user(&input, (void __user *)argp->data, sizeof(input)))
+ return -EFAULT;
+
+- data = kzalloc(sizeof(*data), GFP_KERNEL);
+- if (!data)
+- return -ENOMEM;
++ memset(&data, 0, sizeof(data));
+
+ /* Userspace wants to query the certificate length. */
+ if (!input.pdh_cert_address ||
+@@ -765,25 +744,19 @@ static int sev_ioctl_do_pdh_export(struct sev_issue_cmd *argp, bool writable)
+ input_cert_chain_address = (void __user *)input.cert_chain_address;
+
+ /* Allocate a physically contiguous buffer to store the PDH blob. */
+- if (input.pdh_cert_len > SEV_FW_BLOB_MAX_SIZE) {
+- ret = -EFAULT;
+- goto e_free;
+- }
++ if (input.pdh_cert_len > SEV_FW_BLOB_MAX_SIZE)
++ return -EFAULT;
+
+ /* Allocate a physically contiguous buffer to store the cert chain blob. */
+- if (input.cert_chain_len > SEV_FW_BLOB_MAX_SIZE) {
+- ret = -EFAULT;
+- goto e_free;
+- }
++ if (input.cert_chain_len > SEV_FW_BLOB_MAX_SIZE)
++ return -EFAULT;
+
+ pdh_blob = kmalloc(input.pdh_cert_len, GFP_KERNEL);
+- if (!pdh_blob) {
+- ret = -ENOMEM;
+- goto e_free;
+- }
++ if (!pdh_blob)
++ return -ENOMEM;
+
+- data->pdh_cert_address = __psp_pa(pdh_blob);
+- data->pdh_cert_len = input.pdh_cert_len;
++ data.pdh_cert_address = __psp_pa(pdh_blob);
++ data.pdh_cert_len = input.pdh_cert_len;
+
+ cert_blob = kmalloc(input.cert_chain_len, GFP_KERNEL);
+ if (!cert_blob) {
+@@ -791,15 +764,15 @@ static int sev_ioctl_do_pdh_export(struct sev_issue_cmd *argp, bool writable)
+ goto e_free_pdh;
+ }
+
+- data->cert_chain_address = __psp_pa(cert_blob);
+- data->cert_chain_len = input.cert_chain_len;
++ data.cert_chain_address = __psp_pa(cert_blob);
++ data.cert_chain_len = input.cert_chain_len;
+
+ cmd:
+- ret = __sev_do_cmd_locked(SEV_CMD_PDH_CERT_EXPORT, data, &argp->error);
++ ret = __sev_do_cmd_locked(SEV_CMD_PDH_CERT_EXPORT, &data, &argp->error);
+
+ /* If we query the length, FW responded with expected data. */
+- input.cert_chain_len = data->cert_chain_len;
+- input.pdh_cert_len = data->pdh_cert_len;
++ input.cert_chain_len = data.cert_chain_len;
++ input.pdh_cert_len = data.pdh_cert_len;
+
+ if (copy_to_user((void __user *)argp->data, &input, sizeof(input))) {
+ ret = -EFAULT;
+@@ -824,8 +797,6 @@ static int sev_ioctl_do_pdh_export(struct sev_issue_cmd *argp, bool writable)
+ kfree(cert_blob);
+ e_free_pdh:
+ kfree(pdh_blob);
+-e_free:
+- kfree(data);
+ return ret;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 72425eb30b89afa6573515ae0f4c8b96f9990c7a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Feb 2023 14:01:53 +0800
+Subject: crypto: crypto4xx - Call dma_unmap_page when done
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+[ Upstream commit bcdda4301bdc4955d45f7e1ffefb6207967b067e ]
+
+In crypto4xx_cipher_done, we should be unmapping the dst page, not
+mapping it.
+
+This was flagged by a sparse warning about the unused addr variable.
+While we're at it, also fix a sparse warning regarding the unused
+ctx variable in crypto4xx_ahash_done (by actually using it).
+
+Fixes: 049359d65527 ("crypto: amcc - Add crypt4xx driver")
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Tested-by: Christian Lamparter <chunkeey@gmail.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/amcc/crypto4xx_core.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/crypto/amcc/crypto4xx_core.c b/drivers/crypto/amcc/crypto4xx_core.c
+index 2e3690f65786d..6d05ac0c05134 100644
+--- a/drivers/crypto/amcc/crypto4xx_core.c
++++ b/drivers/crypto/amcc/crypto4xx_core.c
+@@ -522,7 +522,6 @@ static void crypto4xx_cipher_done(struct crypto4xx_device *dev,
+ {
+ struct skcipher_request *req;
+ struct scatterlist *dst;
+- dma_addr_t addr;
+
+ req = skcipher_request_cast(pd_uinfo->async_req);
+
+@@ -531,8 +530,8 @@ static void crypto4xx_cipher_done(struct crypto4xx_device *dev,
+ req->cryptlen, req->dst);
+ } else {
+ dst = pd_uinfo->dest_va;
+- addr = dma_map_page(dev->core_dev->device, sg_page(dst),
+- dst->offset, dst->length, DMA_FROM_DEVICE);
++ dma_unmap_page(dev->core_dev->device, pd->dest, dst->length,
++ DMA_FROM_DEVICE);
+ }
+
+ if (pd_uinfo->sa_va->sa_command_0.bf.save_iv == SA_SAVE_IV) {
+@@ -557,10 +556,9 @@ static void crypto4xx_ahash_done(struct crypto4xx_device *dev,
+ struct ahash_request *ahash_req;
+
+ ahash_req = ahash_request_cast(pd_uinfo->async_req);
+- ctx = crypto_tfm_ctx(ahash_req->base.tfm);
++ ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(ahash_req));
+
+- crypto4xx_copy_digest_to_dst(ahash_req->result, pd_uinfo,
+- crypto_tfm_ctx(ahash_req->base.tfm));
++ crypto4xx_copy_digest_to_dst(ahash_req->result, pd_uinfo, ctx);
+ crypto4xx_ret_sg_desc(dev, pd_uinfo);
+
+ if (pd_uinfo->state & PD_ENTRY_BUSY)
+--
+2.39.2
+
--- /dev/null
+From c799dc2c910e0fb3fdc2796a545116ac3a4dbc0e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Jan 2023 18:24:09 +0800
+Subject: crypto: essiv - Handle EBUSY correctly
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+[ Upstream commit b5a772adf45a32c68bef28e60621f12617161556 ]
+
+As it is essiv only handles the special return value of EINPROGERSS,
+which means that in all other cases it will free data related to the
+request.
+
+However, as the caller of essiv may specify MAY_BACKLOG, we also need
+to expect EBUSY and treat it in the same way. Otherwise backlogged
+requests will trigger a use-after-free.
+
+Fixes: be1eb7f78aa8 ("crypto: essiv - create wrapper template...")
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Acked-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ crypto/essiv.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/crypto/essiv.c b/crypto/essiv.c
+index d012be23d496d..85bb624e32b9b 100644
+--- a/crypto/essiv.c
++++ b/crypto/essiv.c
+@@ -170,7 +170,12 @@ static void essiv_aead_done(struct crypto_async_request *areq, int err)
+ struct aead_request *req = areq->data;
+ struct essiv_aead_request_ctx *rctx = aead_request_ctx(req);
+
++ if (err == -EINPROGRESS)
++ goto out;
++
+ kfree(rctx->assoc);
++
++out:
+ aead_request_complete(req, err);
+ }
+
+@@ -246,7 +251,7 @@ static int essiv_aead_crypt(struct aead_request *req, bool enc)
+ err = enc ? crypto_aead_encrypt(subreq) :
+ crypto_aead_decrypt(subreq);
+
+- if (rctx->assoc && err != -EINPROGRESS)
++ if (rctx->assoc && err != -EINPROGRESS && err != -EBUSY)
+ kfree(rctx->assoc);
+ return err;
+ }
+--
+2.39.2
+
--- /dev/null
+From 404867695a72ed4f6978604fa8cb1bf9529f3520 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Jan 2023 20:19:48 -0800
+Subject: crypto: hisilicon: Wipe entire pool on error
+
+From: Kees Cook <keescook@chromium.org>
+
+[ Upstream commit aa85923a954e7704bc9d3847dabeb8540aa98d13 ]
+
+To work around a Clang __builtin_object_size bug that shows up under
+CONFIG_FORTIFY_SOURCE and UBSAN_BOUNDS, move the per-loop-iteration
+mem_block wipe into a single wipe of the entire pool structure after
+the loop.
+
+Reported-by: Nathan Chancellor <nathan@kernel.org>
+Link: https://github.com/ClangBuiltLinux/linux/issues/1780
+Cc: Weili Qian <qianweili@huawei.com>
+Cc: Zhou Wang <wangzhou1@hisilicon.com>
+Cc: Herbert Xu <herbert@gondor.apana.org.au>
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: linux-crypto@vger.kernel.org
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Tested-by: Nathan Chancellor <nathan@kernel.org> # build
+Link: https://lore.kernel.org/r/20230106041945.never.831-kees@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/hisilicon/sgl.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/crypto/hisilicon/sgl.c b/drivers/crypto/hisilicon/sgl.c
+index 725a739800b0a..ce77826c7fb05 100644
+--- a/drivers/crypto/hisilicon/sgl.c
++++ b/drivers/crypto/hisilicon/sgl.c
+@@ -113,9 +113,8 @@ struct hisi_acc_sgl_pool *hisi_acc_create_sgl_pool(struct device *dev,
+ for (j = 0; j < i; j++) {
+ dma_free_coherent(dev, block_size, block[j].sgl,
+ block[j].sgl_dma);
+- memset(block + j, 0, sizeof(*block));
+ }
+- kfree(pool);
++ kfree_sensitive(pool);
+ return ERR_PTR(-ENOMEM);
+ }
+ EXPORT_SYMBOL_GPL(hisi_acc_create_sgl_pool);
+--
+2.39.2
+
--- /dev/null
+From bccd0b929fb80742ce25db366f3b0695917c78f7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 31 Jan 2023 16:02:04 +0800
+Subject: crypto: rsa-pkcs1pad - Use akcipher_request_complete
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+[ Upstream commit 564cabc0ca0bdfa8f0fc1ae74b24d0a7554522c5 ]
+
+Use the akcipher_request_complete helper instead of calling the
+completion function directly. In fact the previous code was buggy
+in that EINPROGRESS was never passed back to the original caller.
+
+Fixes: 3d5b1ecdea6f ("crypto: rsa - RSA padding algorithm")
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ crypto/rsa-pkcs1pad.c | 34 +++++++++++++++-------------------
+ 1 file changed, 15 insertions(+), 19 deletions(-)
+
+diff --git a/crypto/rsa-pkcs1pad.c b/crypto/rsa-pkcs1pad.c
+index 9d804831c8b3f..a4ebbb889274e 100644
+--- a/crypto/rsa-pkcs1pad.c
++++ b/crypto/rsa-pkcs1pad.c
+@@ -214,16 +214,14 @@ static void pkcs1pad_encrypt_sign_complete_cb(
+ struct crypto_async_request *child_async_req, int err)
+ {
+ struct akcipher_request *req = child_async_req->data;
+- struct crypto_async_request async_req;
+
+ if (err == -EINPROGRESS)
+- return;
++ goto out;
++
++ err = pkcs1pad_encrypt_sign_complete(req, err);
+
+- async_req.data = req->base.data;
+- async_req.tfm = crypto_akcipher_tfm(crypto_akcipher_reqtfm(req));
+- async_req.flags = child_async_req->flags;
+- req->base.complete(&async_req,
+- pkcs1pad_encrypt_sign_complete(req, err));
++out:
++ akcipher_request_complete(req, err);
+ }
+
+ static int pkcs1pad_encrypt(struct akcipher_request *req)
+@@ -332,15 +330,14 @@ static void pkcs1pad_decrypt_complete_cb(
+ struct crypto_async_request *child_async_req, int err)
+ {
+ struct akcipher_request *req = child_async_req->data;
+- struct crypto_async_request async_req;
+
+ if (err == -EINPROGRESS)
+- return;
++ goto out;
++
++ err = pkcs1pad_decrypt_complete(req, err);
+
+- async_req.data = req->base.data;
+- async_req.tfm = crypto_akcipher_tfm(crypto_akcipher_reqtfm(req));
+- async_req.flags = child_async_req->flags;
+- req->base.complete(&async_req, pkcs1pad_decrypt_complete(req, err));
++out:
++ akcipher_request_complete(req, err);
+ }
+
+ static int pkcs1pad_decrypt(struct akcipher_request *req)
+@@ -512,15 +509,14 @@ static void pkcs1pad_verify_complete_cb(
+ struct crypto_async_request *child_async_req, int err)
+ {
+ struct akcipher_request *req = child_async_req->data;
+- struct crypto_async_request async_req;
+
+ if (err == -EINPROGRESS)
+- return;
++ goto out;
+
+- async_req.data = req->base.data;
+- async_req.tfm = crypto_akcipher_tfm(crypto_akcipher_reqtfm(req));
+- async_req.flags = child_async_req->flags;
+- req->base.complete(&async_req, pkcs1pad_verify_complete(req, err));
++ err = pkcs1pad_verify_complete(req, err);
++
++out:
++ akcipher_request_complete(req, err);
+ }
+
+ /*
+--
+2.39.2
+
--- /dev/null
+From 65fb982e69cbc771fdf16e4d9a4c22b3437629a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Jan 2023 18:27:51 +0800
+Subject: crypto: seqiv - Handle EBUSY correctly
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+[ Upstream commit 32e62025e5e52fbe4812ef044759de7010b15dbc ]
+
+As it is seqiv only handles the special return value of EINPROGERSS,
+which means that in all other cases it will free data related to the
+request.
+
+However, as the caller of seqiv may specify MAY_BACKLOG, we also need
+to expect EBUSY and treat it in the same way. Otherwise backlogged
+requests will trigger a use-after-free.
+
+Fixes: 0a270321dbf9 ("[CRYPTO] seqiv: Add Sequence Number IV Generator")
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ crypto/seqiv.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/crypto/seqiv.c b/crypto/seqiv.c
+index 0899d527c2845..b1bcfe537daf1 100644
+--- a/crypto/seqiv.c
++++ b/crypto/seqiv.c
+@@ -23,7 +23,7 @@ static void seqiv_aead_encrypt_complete2(struct aead_request *req, int err)
+ struct aead_request *subreq = aead_request_ctx(req);
+ struct crypto_aead *geniv;
+
+- if (err == -EINPROGRESS)
++ if (err == -EINPROGRESS || err == -EBUSY)
+ return;
+
+ if (err)
+--
+2.39.2
+
--- /dev/null
+From fb97e9411a3e84ff49bcda0b413382b9d4da8cb8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Dec 2022 21:40:40 -0800
+Subject: crypto: x86/ghash - fix unaligned access in ghash_setkey()
+
+From: Eric Biggers <ebiggers@google.com>
+
+[ Upstream commit 116db2704c193fff6d73ea6c2219625f0c9bdfc8 ]
+
+The key can be unaligned, so use the unaligned memory access helpers.
+
+Fixes: 8ceee72808d1 ("crypto: ghash-clmulni-intel - use C implementation for setkey()")
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/crypto/ghash-clmulni-intel_glue.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/x86/crypto/ghash-clmulni-intel_glue.c b/arch/x86/crypto/ghash-clmulni-intel_glue.c
+index 1f1a95f3dd0ca..c0ab0ff4af655 100644
+--- a/arch/x86/crypto/ghash-clmulni-intel_glue.c
++++ b/arch/x86/crypto/ghash-clmulni-intel_glue.c
+@@ -19,6 +19,7 @@
+ #include <crypto/internal/simd.h>
+ #include <asm/cpu_device_id.h>
+ #include <asm/simd.h>
++#include <asm/unaligned.h>
+
+ #define GHASH_BLOCK_SIZE 16
+ #define GHASH_DIGEST_SIZE 16
+@@ -54,15 +55,14 @@ static int ghash_setkey(struct crypto_shash *tfm,
+ const u8 *key, unsigned int keylen)
+ {
+ struct ghash_ctx *ctx = crypto_shash_ctx(tfm);
+- be128 *x = (be128 *)key;
+ u64 a, b;
+
+ if (keylen != GHASH_BLOCK_SIZE)
+ return -EINVAL;
+
+ /* perform multiplication by 'x' in GF(2^128) */
+- a = be64_to_cpu(x->a);
+- b = be64_to_cpu(x->b);
++ a = get_unaligned_be64(key);
++ b = get_unaligned_be64(key + 8);
+
+ ctx->shash.a = (b << 1) | (a >> 63);
+ ctx->shash.b = (a << 1) | (b >> 63);
+--
+2.39.2
+
--- /dev/null
+From f854977cc6d64a72a367826962374bb9c9378358 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 22 Jan 2023 16:07:37 +0800
+Subject: crypto: xts - Handle EBUSY correctly
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+[ Upstream commit 51c082514c2dedf2711c99d93c196cc4eedceb40 ]
+
+As it is xts only handles the special return value of EINPROGRESS,
+which means that in all other cases it will free data related to the
+request.
+
+However, as the caller of xts may specify MAY_BACKLOG, we also need
+to expect EBUSY and treat it in the same way. Otherwise backlogged
+requests will trigger a use-after-free.
+
+Fixes: 8083b1bf8163 ("crypto: xts - add support for ciphertext stealing")
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Acked-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ crypto/xts.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/crypto/xts.c b/crypto/xts.c
+index ad45b009774b1..c6a105dba38b9 100644
+--- a/crypto/xts.c
++++ b/crypto/xts.c
+@@ -202,12 +202,12 @@ static void xts_encrypt_done(struct crypto_async_request *areq, int err)
+ if (!err) {
+ struct xts_request_ctx *rctx = skcipher_request_ctx(req);
+
+- rctx->subreq.base.flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
++ rctx->subreq.base.flags &= CRYPTO_TFM_REQ_MAY_BACKLOG;
+ err = xts_xor_tweak_post(req, true);
+
+ if (!err && unlikely(req->cryptlen % XTS_BLOCK_SIZE)) {
+ err = xts_cts_final(req, crypto_skcipher_encrypt);
+- if (err == -EINPROGRESS)
++ if (err == -EINPROGRESS || err == -EBUSY)
+ return;
+ }
+ }
+@@ -222,12 +222,12 @@ static void xts_decrypt_done(struct crypto_async_request *areq, int err)
+ if (!err) {
+ struct xts_request_ctx *rctx = skcipher_request_ctx(req);
+
+- rctx->subreq.base.flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
++ rctx->subreq.base.flags &= CRYPTO_TFM_REQ_MAY_BACKLOG;
+ err = xts_xor_tweak_post(req, false);
+
+ if (!err && unlikely(req->cryptlen % XTS_BLOCK_SIZE)) {
+ err = xts_cts_final(req, crypto_skcipher_decrypt);
+- if (err == -EINPROGRESS)
++ if (err == -EINPROGRESS || err == -EBUSY)
+ return;
+ }
+ }
+--
+2.39.2
+
--- /dev/null
+From cd55a4bd42e035b75b39b4c43ad1747e9218621d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Feb 2023 15:31:08 -0500
+Subject: dm cache: add cond_resched() to various workqueue loops
+
+From: Mike Snitzer <snitzer@kernel.org>
+
+[ Upstream commit 76227f6dc805e9e960128bcc6276647361e0827c ]
+
+Otherwise on resource constrained systems these workqueues may be too
+greedy.
+
+Signed-off-by: Mike Snitzer <snitzer@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/dm-cache-target.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c
+index 9b2aec3098010..f98ad4366301b 100644
+--- a/drivers/md/dm-cache-target.c
++++ b/drivers/md/dm-cache-target.c
+@@ -1883,6 +1883,7 @@ static void process_deferred_bios(struct work_struct *ws)
+
+ else
+ commit_needed = process_bio(cache, bio) || commit_needed;
++ cond_resched();
+ }
+
+ if (commit_needed)
+@@ -1905,6 +1906,7 @@ static void requeue_deferred_bios(struct cache *cache)
+ while ((bio = bio_list_pop(&bios))) {
+ bio->bi_status = BLK_STS_DM_REQUEUE;
+ bio_endio(bio);
++ cond_resched();
+ }
+ }
+
+@@ -1945,6 +1947,8 @@ static void check_migrations(struct work_struct *ws)
+ r = mg_start(cache, op, NULL);
+ if (r)
+ break;
++
++ cond_resched();
+ }
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 1db59f1bff5387206580fd6f9c1d4aa61ab15db2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Feb 2023 13:06:05 -0500
+Subject: dm: remove flush_scheduled_work() during local_exit()
+
+From: Mike Snitzer <snitzer@kernel.org>
+
+[ Upstream commit 0b22ff5360f5c4e11050b89206370fdf7dc0a226 ]
+
+Commit acfe0ad74d2e1 ("dm: allocate a special workqueue for deferred
+device removal") switched from using system workqueue to a single
+workqueue local to DM. But it didn't eliminate the call to
+flush_scheduled_work() that was introduced purely for the benefit of
+deferred device removal with commit 2c140a246dc ("dm: allow remove to
+be deferred").
+
+Since DM core uses its own workqueue (and queue_work) there is no need
+to call flush_scheduled_work() from local_exit(). local_exit()'s
+destroy_workqueue(deferred_remove_workqueue) handles flushing work
+started with queue_work().
+
+Fixes: acfe0ad74d2e1 ("dm: allocate a special workqueue for deferred device removal")
+Signed-off-by: Mike Snitzer <snitzer@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/dm.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/md/dm.c b/drivers/md/dm.c
+index 1005abf768609..7163ecc4d53fa 100644
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -265,7 +265,6 @@ static int __init local_init(void)
+
+ static void local_exit(void)
+ {
+- flush_scheduled_work();
+ destroy_workqueue(deferred_remove_workqueue);
+
+ unregister_blkdev(_major, _name);
+--
+2.39.2
+
--- /dev/null
+From 6696ae0ee1c7adef9f589753f45db0a504300e81 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Feb 2023 15:29:44 -0500
+Subject: dm thin: add cond_resched() to various workqueue loops
+
+From: Mike Snitzer <snitzer@kernel.org>
+
+[ Upstream commit e4f80303c2353952e6e980b23914e4214487f2a6 ]
+
+Otherwise on resource constrained systems these workqueues may be too
+greedy.
+
+Signed-off-by: Mike Snitzer <snitzer@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/dm-thin.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c
+index f3c519e18a12f..c890bb3e51852 100644
+--- a/drivers/md/dm-thin.c
++++ b/drivers/md/dm-thin.c
+@@ -2217,6 +2217,7 @@ static void process_thin_deferred_bios(struct thin_c *tc)
+ throttle_work_update(&pool->throttle);
+ dm_pool_issue_prefetches(pool->pmd);
+ }
++ cond_resched();
+ }
+ blk_finish_plug(&plug);
+ }
+@@ -2299,6 +2300,7 @@ static void process_thin_deferred_cells(struct thin_c *tc)
+ else
+ pool->process_cell(tc, cell);
+ }
++ cond_resched();
+ } while (!list_empty(&cells));
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 8e37304adbc208579961db35ead38ae977e96941 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Jan 2023 00:23:20 +0100
+Subject: docs/scripts/gdb: add necessary make scripts_gdb step
+
+From: Jakob Koschel <jkl820.git@gmail.com>
+
+[ Upstream commit 6b219431037bf98c9efd49716aea9b68440477a3 ]
+
+In order to debug the kernel successfully with gdb you need to run
+'make scripts_gdb' nowadays.
+
+This was changed with the following commit:
+
+Commit 67274c083438340ad16c ("scripts/gdb: delay generation of gdb
+constants.py")
+
+In order to have a complete guide for beginners this remark
+should be added to the offial documentation.
+
+Signed-off-by: Jakob Koschel <jkl820.git@gmail.com>
+Link: https://lore.kernel.org/r/20230112-documentation-gdb-v2-1-292785c43dc9@gmail.com
+Signed-off-by: Jonathan Corbet <corbet@lwn.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/dev-tools/gdb-kernel-debugging.rst | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/Documentation/dev-tools/gdb-kernel-debugging.rst b/Documentation/dev-tools/gdb-kernel-debugging.rst
+index 4756f6b3a04e5..10cdd990b63d0 100644
+--- a/Documentation/dev-tools/gdb-kernel-debugging.rst
++++ b/Documentation/dev-tools/gdb-kernel-debugging.rst
+@@ -39,6 +39,10 @@ Setup
+ this mode. In this case, you should build the kernel with
+ CONFIG_RANDOMIZE_BASE disabled if the architecture supports KASLR.
+
++- Build the gdb scripts (required on kernels v5.1 and above)::
++
++ make scripts_gdb
++
+ - Enable the gdb stub of QEMU/KVM, either
+
+ - at VM startup time by appending "-s" to the QEMU command line
+--
+2.39.2
+
--- /dev/null
+From 0fe0b02278e51251c87991a311e5d24f4dc6cb9f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Nov 2022 10:50:46 +0800
+Subject: drm: amd: display: Fix memory leakage
+
+From: Konstantin Meskhidze <konstantin.meskhidze@huawei.com>
+
+[ Upstream commit 6b8701be1f66064ca72733c5f6e13748cdbf8397 ]
+
+This commit fixes memory leakage in dc_construct_ctx() function.
+
+Signed-off-by: Konstantin Meskhidze <konstantin.meskhidze@huawei.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/core/dc.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
+index 99887bcfada04..7e0a55aa2b180 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
+@@ -616,6 +616,7 @@ static bool dc_construct_ctx(struct dc *dc,
+
+ dc_ctx->perf_trace = dc_perf_trace_create();
+ if (!dc_ctx->perf_trace) {
++ kfree(dc_ctx);
+ ASSERT_CRITICAL(false);
+ return false;
+ }
+--
+2.39.2
+
--- /dev/null
+From cd5ba4929aabbd4099e37ff9e54bc5cc5e4b4af3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Dec 2022 09:06:42 -0500
+Subject: drm/amd/display: Fix potential null-deref in dm_resume
+
+From: Roman Li <roman.li@amd.com>
+
+[ Upstream commit 7a7175a2cd84b7874bebbf8e59f134557a34161b ]
+
+[Why]
+Fixing smatch error:
+dm_resume() error: we previously assumed 'aconnector->dc_link' could be null
+
+[How]
+Check if dc_link null at the beginning of the loop,
+so further checks can be dropped.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+
+Reviewed-by: Wayne Lin <Wayne.Lin@amd.com>
+Acked-by: Jasdeep Dhillon <jdhillon@amd.com>
+Signed-off-by: Roman Li <roman.li@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index fbe15f4b75fd5..dbdf0e210522c 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -2051,12 +2051,14 @@ static int dm_resume(void *handle)
+ drm_for_each_connector_iter(connector, &iter) {
+ aconnector = to_amdgpu_dm_connector(connector);
+
++ if (!aconnector->dc_link)
++ continue;
++
+ /*
+ * this is the case when traversing through already created
+ * MST connectors, should be skipped
+ */
+- if (aconnector->dc_link &&
+- aconnector->dc_link->type == dc_connection_mst_branch)
++ if (aconnector->dc_link->type == dc_connection_mst_branch)
+ continue;
+
+ mutex_lock(&aconnector->hpd_lock);
+--
+2.39.2
+
--- /dev/null
+From abd79a7cc9158f9d1716df309cd2f7c418195228 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Feb 2023 20:36:02 +0100
+Subject: drm/amdgpu: fix enum odm_combine_mode mismatch
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 087bad7eb1f6945f8232f132953ecc2bda8bd38d ]
+
+A conversion from 'bool' to 'enum odm_combine_mode' was incomplete,
+and gcc warns about this with many instances of
+
+display/dc/dml/dcn20/display_mode_vba_20.c:3899:44: warning: implicit conversion from 'enum <anonymous>' to 'enum
+odm_combine_mode' [-Wenum-conversion]
+ 3899 | locals->ODMCombineEnablePerState[i][k] = false;
+
+Change the ones that we get a warning for, using the same numerical
+values to leave the behavior unchanged.
+
+Fixes: 5fc11598166d ("drm/amd/display: expand dml structs")
+Link: https://lore.kernel.org/all/20201026210039.3884312-3-arnd@kernel.org/
+Link: https://lore.kernel.org/all/20210927100659.1431744-1-arnd@kernel.org/
+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>
+---
+ .../amd/display/dc/dml/dcn20/display_mode_vba_20.c | 8 ++++----
+ .../amd/display/dc/dml/dcn20/display_mode_vba_20v2.c | 10 +++++-----
+ .../amd/display/dc/dml/dcn21/display_mode_vba_21.c | 12 ++++++------
+ 3 files changed, 15 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c
+index b3f0476899d32..14e7a59a9cd13 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c
+@@ -3897,14 +3897,14 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
+ mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine = mode_lib->vba.PixelClock[k] / 2
+ * (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
+
+- locals->ODMCombineEnablePerState[i][k] = false;
++ locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled;
+ mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine;
+ if (mode_lib->vba.ODMCapability) {
+ if (locals->PlaneRequiredDISPCLKWithoutODMCombine > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity) {
+- locals->ODMCombineEnablePerState[i][k] = true;
++ locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
+ mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
+ } else if (locals->HActive[k] > DCN20_MAX_420_IMAGE_WIDTH && locals->OutputFormat[k] == dm_420) {
+- locals->ODMCombineEnablePerState[i][k] = true;
++ locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
+ mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
+ }
+ }
+@@ -3957,7 +3957,7 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
+ locals->RequiredDISPCLK[i][j] = 0.0;
+ locals->DISPCLK_DPPCLK_Support[i][j] = true;
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+- locals->ODMCombineEnablePerState[i][k] = false;
++ locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled;
+ if (locals->SwathWidthYSingleDPP[k] <= locals->MaximumSwathWidth[k]) {
+ locals->NoOfDPP[i][j][k] = 1;
+ locals->RequiredDPPCLK[i][j][k] = locals->MinDPPCLKUsingSingleDPP[k]
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c
+index 1bcda7eba4a6f..ee1c80366bd65 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c
+@@ -3974,17 +3974,17 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
+ mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine = mode_lib->vba.PixelClock[k] / 2
+ * (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
+
+- locals->ODMCombineEnablePerState[i][k] = false;
++ locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled;
+ mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine;
+ if (mode_lib->vba.ODMCapability) {
+ if (locals->PlaneRequiredDISPCLKWithoutODMCombine > MaxMaxDispclkRoundedDown) {
+- locals->ODMCombineEnablePerState[i][k] = true;
++ locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
+ mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
+ } else if (locals->DSCEnabled[k] && (locals->HActive[k] > DCN20_MAX_DSC_IMAGE_WIDTH)) {
+- locals->ODMCombineEnablePerState[i][k] = true;
++ locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
+ mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
+ } else if (locals->HActive[k] > DCN20_MAX_420_IMAGE_WIDTH && locals->OutputFormat[k] == dm_420) {
+- locals->ODMCombineEnablePerState[i][k] = true;
++ locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
+ mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
+ }
+ }
+@@ -4037,7 +4037,7 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
+ locals->RequiredDISPCLK[i][j] = 0.0;
+ locals->DISPCLK_DPPCLK_Support[i][j] = true;
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+- locals->ODMCombineEnablePerState[i][k] = false;
++ locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled;
+ if (locals->SwathWidthYSingleDPP[k] <= locals->MaximumSwathWidth[k]) {
+ locals->NoOfDPP[i][j][k] = 1;
+ locals->RequiredDPPCLK[i][j][k] = locals->MinDPPCLKUsingSingleDPP[k]
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c
+index c09bca3350687..25693e62db805 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c
+@@ -3975,17 +3975,17 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
+ mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine = mode_lib->vba.PixelClock[k] / 2
+ * (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
+
+- locals->ODMCombineEnablePerState[i][k] = false;
++ locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled;
+ mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine;
+ if (mode_lib->vba.ODMCapability) {
+ if (locals->PlaneRequiredDISPCLKWithoutODMCombine > MaxMaxDispclkRoundedDown) {
+- locals->ODMCombineEnablePerState[i][k] = true;
++ locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
+ mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
+ } else if (locals->DSCEnabled[k] && (locals->HActive[k] > DCN21_MAX_DSC_IMAGE_WIDTH)) {
+- locals->ODMCombineEnablePerState[i][k] = true;
++ locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
+ mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
+ } else if (locals->HActive[k] > DCN21_MAX_420_IMAGE_WIDTH && locals->OutputFormat[k] == dm_420) {
+- locals->ODMCombineEnablePerState[i][k] = true;
++ locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
+ mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
+ }
+ }
+@@ -4038,7 +4038,7 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
+ locals->RequiredDISPCLK[i][j] = 0.0;
+ locals->DISPCLK_DPPCLK_Support[i][j] = true;
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+- locals->ODMCombineEnablePerState[i][k] = false;
++ locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled;
+ if (locals->SwathWidthYSingleDPP[k] <= locals->MaximumSwathWidth[k]) {
+ locals->NoOfDPP[i][j][k] = 1;
+ locals->RequiredDPPCLK[i][j][k] = locals->MinDPPCLKUsingSingleDPP[k]
+@@ -5213,7 +5213,7 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
+ mode_lib->vba.ODMCombineEnabled[k] =
+ locals->ODMCombineEnablePerState[mode_lib->vba.VoltageLevel][k];
+ } else {
+- mode_lib->vba.ODMCombineEnabled[k] = false;
++ mode_lib->vba.ODMCombineEnabled[k] = dm_odm_combine_mode_disabled;
+ }
+ mode_lib->vba.DSCEnabled[k] =
+ locals->RequiresDSC[mode_lib->vba.VoltageLevel][k];
+--
+2.39.2
+
--- /dev/null
+From c0c7d928008abfc4b3e0227f73029f275c3668dd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Jan 2023 10:16:50 +0200
+Subject: drm/bridge: lt9611: fix clock calculation
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 2576eb26494eb0509dd9ceb0cd27771a7a5e3674 ]
+
+Instead of having several fixed values for the pcr register, calculate
+it before programming. This allows the bridge to support most of the
+display modes.
+
+Fixes: 23278bf54afe ("drm/bridge: Introduce LT9611 DSI to HDMI bridge")
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230118081658.2198520-6-dmitry.baryshkov@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/lontium-lt9611.c | 32 +++++++++++--------------
+ 1 file changed, 14 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c
+index 4925566dfc54f..bb13511dd4263 100644
+--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
++++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
+@@ -190,8 +190,9 @@ static void lt9611_mipi_video_setup(struct lt9611 *lt9611,
+ regmap_write(lt9611->regmap, 0x831b, (u8)(hsync_porch % 256));
+ }
+
+-static void lt9611_pcr_setup(struct lt9611 *lt9611, const struct drm_display_mode *mode)
++static void lt9611_pcr_setup(struct lt9611 *lt9611, const struct drm_display_mode *mode, unsigned int postdiv)
+ {
++ unsigned int pcr_m = mode->clock * 5 * postdiv / 27000;
+ const struct reg_sequence reg_cfg[] = {
+ { 0x830b, 0x01 },
+ { 0x830c, 0x10 },
+@@ -234,24 +235,14 @@ static void lt9611_pcr_setup(struct lt9611 *lt9611, const struct drm_display_mod
+ else
+ regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg));
+
+- switch (mode->hdisplay) {
+- case 640:
+- regmap_write(lt9611->regmap, 0x8326, 0x14);
+- break;
+- case 1920:
+- regmap_write(lt9611->regmap, 0x8326, 0x37);
+- break;
+- case 3840:
+- regmap_write(lt9611->regmap, 0x8326, 0x37);
+- break;
+- }
++ regmap_write(lt9611->regmap, 0x8326, pcr_m);
+
+ /* pcr rst */
+ regmap_write(lt9611->regmap, 0x8011, 0x5a);
+ regmap_write(lt9611->regmap, 0x8011, 0xfa);
+ }
+
+-static int lt9611_pll_setup(struct lt9611 *lt9611, const struct drm_display_mode *mode)
++static int lt9611_pll_setup(struct lt9611 *lt9611, const struct drm_display_mode *mode, unsigned int *postdiv)
+ {
+ unsigned int pclk = mode->clock;
+ const struct reg_sequence reg_cfg[] = {
+@@ -269,12 +260,16 @@ static int lt9611_pll_setup(struct lt9611 *lt9611, const struct drm_display_mode
+
+ regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg));
+
+- if (pclk > 150000)
++ if (pclk > 150000) {
+ regmap_write(lt9611->regmap, 0x812d, 0x88);
+- else if (pclk > 70000)
++ *postdiv = 1;
++ } else if (pclk > 70000) {
+ regmap_write(lt9611->regmap, 0x812d, 0x99);
+- else
++ *postdiv = 2;
++ } else {
+ regmap_write(lt9611->regmap, 0x812d, 0xaa);
++ *postdiv = 4;
++ }
+
+ /*
+ * first divide pclk by 2 first
+@@ -917,14 +912,15 @@ static void lt9611_bridge_mode_set(struct drm_bridge *bridge,
+ {
+ struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
+ struct hdmi_avi_infoframe avi_frame;
++ unsigned int postdiv;
+ int ret;
+
+ lt9611_bridge_pre_enable(bridge);
+
+ lt9611_mipi_input_digital(lt9611, mode);
+- lt9611_pll_setup(lt9611, mode);
++ lt9611_pll_setup(lt9611, mode, &postdiv);
+ lt9611_mipi_video_setup(lt9611, mode);
+- lt9611_pcr_setup(lt9611, mode);
++ lt9611_pcr_setup(lt9611, mode, postdiv);
+
+ ret = drm_hdmi_avi_infoframe_from_display_mode(&avi_frame,
+ <9611->connector,
+--
+2.39.2
+
--- /dev/null
+From 07f0113bb7dabc6bec922c704b8308d45cc1f267 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Jan 2023 10:16:47 +0200
+Subject: drm/bridge: lt9611: fix HPD reenablement
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit a7790f6bd38f3642b60ae3504a2c749135b89451 ]
+
+The driver will reset the bridge in the atomic_pre_enable(). However
+this will also drop the HPD interrupt state. Instead of resetting the
+bridge, properly wake it up. This fixes the HPD interrupt delivery after
+the disable/enable cycle.
+
+Fixes: 23278bf54afe ("drm/bridge: Introduce LT9611 DSI to HDMI bridge")
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230118081658.2198520-3-dmitry.baryshkov@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/lontium-lt9611.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c
+index 5e5641ac5ea3d..fe660d667daf6 100644
+--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
++++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
+@@ -880,12 +880,18 @@ static enum drm_mode_status lt9611_bridge_mode_valid(struct drm_bridge *bridge,
+ static void lt9611_bridge_pre_enable(struct drm_bridge *bridge)
+ {
+ struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
++ static const struct reg_sequence reg_cfg[] = {
++ { 0x8102, 0x12 },
++ { 0x8123, 0x40 },
++ { 0x8130, 0xea },
++ { 0x8011, 0xfa },
++ };
+
+ if (!lt9611->sleep)
+ return;
+
+- lt9611_reset(lt9611);
+- regmap_write(lt9611->regmap, 0x80ee, 0x01);
++ regmap_multi_reg_write(lt9611->regmap,
++ reg_cfg, ARRAY_SIZE(reg_cfg));
+
+ lt9611->sleep = false;
+ }
+--
+2.39.2
+
--- /dev/null
+From 642aeae4fbea02ed294c434c0339d5470aa6dc12 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Jan 2023 10:16:48 +0200
+Subject: drm/bridge: lt9611: fix polarity programming
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 0b157efa384ea417304b1da284ee2f603c607fc3 ]
+
+Fix programming of hsync and vsync polarities
+
+Fixes: 23278bf54afe ("drm/bridge: Introduce LT9611 DSI to HDMI bridge")
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230118081658.2198520-4-dmitry.baryshkov@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/lontium-lt9611.c | 17 ++++++++++++-----
+ 1 file changed, 12 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c
+index fe660d667daf6..4c56407c4cf04 100644
+--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
++++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
+@@ -205,7 +205,6 @@ static void lt9611_pcr_setup(struct lt9611 *lt9611, const struct drm_display_mod
+
+ /* stage 2 */
+ { 0x834a, 0x40 },
+- { 0x831d, 0x10 },
+
+ /* MK limit */
+ { 0x832d, 0x38 },
+@@ -220,11 +219,19 @@ static void lt9611_pcr_setup(struct lt9611 *lt9611, const struct drm_display_mod
+ { 0x8325, 0x00 },
+ { 0x832a, 0x01 },
+ { 0x834a, 0x10 },
+- { 0x831d, 0x10 },
+- { 0x8326, 0x37 },
+ };
++ u8 pol = 0x10;
+
+- regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg));
++ if (mode->flags & DRM_MODE_FLAG_NHSYNC)
++ pol |= 0x2;
++ if (mode->flags & DRM_MODE_FLAG_NVSYNC)
++ pol |= 0x1;
++ regmap_write(lt9611->regmap, 0x831d, pol);
++
++ if (mode->hdisplay == 3840)
++ regmap_multi_reg_write(lt9611->regmap, reg_cfg2, ARRAY_SIZE(reg_cfg2));
++ else
++ regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg));
+
+ switch (mode->hdisplay) {
+ case 640:
+@@ -234,7 +241,7 @@ static void lt9611_pcr_setup(struct lt9611 *lt9611, const struct drm_display_mod
+ regmap_write(lt9611->regmap, 0x8326, 0x37);
+ break;
+ case 3840:
+- regmap_multi_reg_write(lt9611->regmap, reg_cfg2, ARRAY_SIZE(reg_cfg2));
++ regmap_write(lt9611->regmap, 0x8326, 0x37);
+ break;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 8c1902df2e9c7d6120f37148c12d44ee74641306 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Jan 2023 10:16:49 +0200
+Subject: drm/bridge: lt9611: fix programming of video modes
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit ad188aa47edaa033a270e1a3efae43836ff47569 ]
+
+Program the upper part of the hfront_porch into the proper register.
+
+Fixes: 23278bf54afe ("drm/bridge: Introduce LT9611 DSI to HDMI bridge")
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230118081658.2198520-5-dmitry.baryshkov@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/lontium-lt9611.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c
+index 4c56407c4cf04..4925566dfc54f 100644
+--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
++++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
+@@ -185,7 +185,8 @@ static void lt9611_mipi_video_setup(struct lt9611 *lt9611,
+
+ regmap_write(lt9611->regmap, 0x8319, (u8)(hfront_porch % 256));
+
+- regmap_write(lt9611->regmap, 0x831a, (u8)(hsync_porch / 256));
++ regmap_write(lt9611->regmap, 0x831a, (u8)(hsync_porch / 256) |
++ ((hfront_porch / 256) << 4));
+ regmap_write(lt9611->regmap, 0x831b, (u8)(hsync_porch % 256));
+ }
+
+--
+2.39.2
+
--- /dev/null
+From b0c4944ad39db17b6309ca59fa6cf4fa5b22c854 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Jan 2023 10:16:46 +0200
+Subject: drm/bridge: lt9611: fix sleep mode setup
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit ae2d329f104b75a0a78dcaded29fe6283289cdf9 ]
+
+On atomic_post_disable the bridge goes to the low power state. However
+the code disables too much of the chip, so the HPD event is not being
+detected and delivered to the host. Reduce the power saving in order to
+get the HPD event.
+
+Fixes: 23278bf54afe ("drm/bridge: Introduce LT9611 DSI to HDMI bridge")
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230118081658.2198520-2-dmitry.baryshkov@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/lontium-lt9611.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c
+index 1dcc28a4d8537..5e5641ac5ea3d 100644
+--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
++++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
+@@ -446,12 +446,11 @@ static void lt9611_sleep_setup(struct lt9611 *lt9611)
+ { 0x8023, 0x01 },
+ { 0x8157, 0x03 }, /* set addr pin as output */
+ { 0x8149, 0x0b },
+- { 0x8151, 0x30 }, /* disable IRQ */
++
+ { 0x8102, 0x48 }, /* MIPI Rx power down */
+ { 0x8123, 0x80 },
+ { 0x8130, 0x00 },
+- { 0x8100, 0x01 }, /* bandgap power down */
+- { 0x8101, 0x00 }, /* system clk power down */
++ { 0x8011, 0x0a },
+ };
+
+ regmap_multi_reg_write(lt9611->regmap,
+--
+2.39.2
+
--- /dev/null
+From 5361aa239d2ebf9c9e419b5e1dea659df49ba091 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Jan 2023 10:16:51 +0200
+Subject: drm/bridge: lt9611: pass a pointer to the of node
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit b0a7f8736789935f62d6df32d441cdf05a5c05d2 ]
+
+Pass a pointer to the OF node while registering lt9611 MIPI device.
+
+Fixes: 23278bf54afe ("drm/bridge: Introduce LT9611 DSI to HDMI bridge")
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230118081658.2198520-7-dmitry.baryshkov@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/lontium-lt9611.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c
+index bb13511dd4263..0c6dea9ccb728 100644
+--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
++++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
+@@ -759,7 +759,7 @@ static const struct drm_connector_funcs lt9611_bridge_connector_funcs = {
+ static struct mipi_dsi_device *lt9611_attach_dsi(struct lt9611 *lt9611,
+ struct device_node *dsi_node)
+ {
+- const struct mipi_dsi_device_info info = { "lt9611", 0, NULL };
++ const struct mipi_dsi_device_info info = { "lt9611", 0, lt9611->dev->of_node};
+ struct mipi_dsi_device *dsi;
+ struct mipi_dsi_host *host;
+ int ret;
+--
+2.39.2
+
--- /dev/null
+From aee6631aedf1b4e37252a2cb9a0b71986655257e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Nov 2022 09:12:26 +0000
+Subject: drm/bridge: megachips: Fix error handling in i2c_register_driver()
+
+From: Yuan Can <yuancan@huawei.com>
+
+[ Upstream commit 4ecff954c370b82bce45bdca2846c5c5563e8a8a ]
+
+A problem about insmod megachips-stdpxxxx-ge-b850v3-fw.ko failed is
+triggered with the following log given:
+
+[ 4497.981497] Error: Driver 'stdp4028-ge-b850v3-fw' is already registered, aborting...
+insmod: ERROR: could not insert module megachips-stdpxxxx-ge-b850v3-fw.ko: Device or resource busy
+
+The reason is that stdpxxxx_ge_b850v3_init() returns i2c_add_driver()
+directly without checking its return value, if i2c_add_driver() failed,
+it returns without calling i2c_del_driver() on the previous i2c driver,
+resulting the megachips-stdpxxxx-ge-b850v3-fw can never be installed
+later.
+A simple call graph is shown as below:
+
+ stdpxxxx_ge_b850v3_init()
+ i2c_add_driver(&stdp4028_ge_b850v3_fw_driver)
+ i2c_add_driver(&stdp2690_ge_b850v3_fw_driver)
+ i2c_register_driver()
+ driver_register()
+ bus_add_driver()
+ priv = kzalloc(...) # OOM happened
+ # return without delete stdp4028_ge_b850v3_fw_driver
+
+Fix by calling i2c_del_driver() on stdp4028_ge_b850v3_fw_driver when
+i2c_add_driver() returns error.
+
+Fixes: fcfa0ddc18ed ("drm/bridge: Drivers for megachips-stdpxxxx-ge-b850v3-fw (LVDS-DP++)")
+Signed-off-by: Yuan Can <yuancan@huawei.com>
+Reviewed-by: Andrzej Hajda <andrzej.hajda@intel.com>
+Tested-by: Ian Ray <ian.ray@ge.com>
+Signed-off-by: Robert Foss <robert.foss@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20221108091226.114524-1-yuancan@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
+index 72248a565579e..e41afcc5326b1 100644
+--- a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
++++ b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
+@@ -444,7 +444,11 @@ static int __init stdpxxxx_ge_b850v3_init(void)
+ if (ret)
+ return ret;
+
+- return i2c_add_driver(&stdp2690_ge_b850v3_fw_driver);
++ ret = i2c_add_driver(&stdp2690_ge_b850v3_fw_driver);
++ if (ret)
++ i2c_del_driver(&stdp4028_ge_b850v3_fw_driver);
++
++ return ret;
+ }
+ module_init(stdpxxxx_ge_b850v3_init);
+
+--
+2.39.2
+
--- /dev/null
+From c10394ffb0cd1426eba6dd9af2230d01f7bd97da Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Nov 2022 10:16:51 +0800
+Subject: drm: Fix potential null-ptr-deref due to drmm_mode_config_init()
+
+From: Shang XiaoJing <shangxiaojing@huawei.com>
+
+[ Upstream commit 834c23e4f798dcdc8af251b3c428ceef94741991 ]
+
+drmm_mode_config_init() will call drm_mode_create_standard_properties()
+and won't check the ret value. When drm_mode_create_standard_properties()
+failed due to alloc, property will be a NULL pointer and may causes the
+null-ptr-deref. Fix the null-ptr-deref by adding the ret value check.
+
+Found null-ptr-deref while testing insert module bochs:
+general protection fault, probably for non-canonical address
+ 0xdffffc000000000c: 0000 [#1] SMP KASAN PTI
+KASAN: null-ptr-deref in range [0x0000000000000060-0x0000000000000067]
+CPU: 3 PID: 249 Comm: modprobe Not tainted 6.1.0-rc1+ #364
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
+rel-1.15.0-0-g2dd4b9b3f840-prebuilt.qemu.org 04/01/2014
+RIP: 0010:drm_object_attach_property+0x73/0x3c0 [drm]
+Call Trace:
+ <TASK>
+ __drm_connector_init+0xb6c/0x1100 [drm]
+ bochs_pci_probe.cold.11+0x4cb/0x7fe [bochs]
+ pci_device_probe+0x17d/0x340
+ really_probe+0x1db/0x5d0
+ __driver_probe_device+0x1e7/0x250
+ driver_probe_device+0x4a/0x120
+ __driver_attach+0xcd/0x2c0
+ bus_for_each_dev+0x11a/0x1b0
+ bus_add_driver+0x3d7/0x500
+ driver_register+0x18e/0x320
+ do_one_initcall+0xc4/0x3e0
+ do_init_module+0x1b4/0x630
+ load_module+0x5dca/0x7230
+ __do_sys_finit_module+0x100/0x170
+ do_syscall_64+0x3f/0x90
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+RIP: 0033:0x7ff65af9f839
+
+Fixes: 6b4959f43a04 ("drm/atomic: atomic plane properties")
+Signed-off-by: Shang XiaoJing <shangxiaojing@huawei.com>
+Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/20221118021651.2460-1-shangxiaojing@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_mode_config.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
+index f1affc1bb6799..fad2c11811270 100644
+--- a/drivers/gpu/drm/drm_mode_config.c
++++ b/drivers/gpu/drm/drm_mode_config.c
+@@ -398,6 +398,8 @@ static void drm_mode_config_init_release(struct drm_device *dev, void *ptr)
+ */
+ int drmm_mode_config_init(struct drm_device *dev)
+ {
++ int ret;
++
+ mutex_init(&dev->mode_config.mutex);
+ drm_modeset_lock_init(&dev->mode_config.connection_mutex);
+ mutex_init(&dev->mode_config.idr_mutex);
+@@ -419,7 +421,11 @@ int drmm_mode_config_init(struct drm_device *dev)
+ init_llist_head(&dev->mode_config.connector_free_list);
+ INIT_WORK(&dev->mode_config.connector_free_work, drm_connector_free_work_fn);
+
+- drm_mode_create_standard_properties(dev);
++ ret = drm_mode_create_standard_properties(dev);
++ if (ret) {
++ drm_mode_config_cleanup(dev);
++ return ret;
++ }
+
+ /* Just to be sure */
+ dev->mode_config.num_fb = 0;
+--
+2.39.2
+
--- /dev/null
+From f2e09f65c00923fd6543d12d37e24cf15f4f5236 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Nov 2022 17:43:10 +0100
+Subject: drm/fourcc: Add missing big-endian XRGB1555 and RGB565 formats
+
+From: Geert Uytterhoeven <geert@linux-m68k.org>
+
+[ Upstream commit 6fb6c979ca628583d4d0c59a0f8ff977e581ecc0 ]
+
+As of commit eae06120f1974e1a ("drm: refuse ADDFB2 ioctl for broken
+bigendian drivers"), drivers must set the
+quirk_addfb_prefer_host_byte_order quirk to make the drm_mode_addfb()
+compat code work correctly on big-endian machines.
+
+While that works fine for big-endian XRGB8888 and ARGB8888, which are
+mapped to the existing little-endian BGRX8888 and BGRA8888 formats, it
+does not work for big-endian XRGB1555 and RGB565, as the latter are not
+listed in the format database.
+
+Fix this by adding the missing formats. Limit this to big-endian
+platforms, as there is currently no need to support these formats on
+little-endian platforms.
+
+Fixes: 6960e6da9cec3f66 ("drm: fix drm_mode_addfb() on big endian machines.")
+Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Link: https://patchwork.freedesktop.org/patch/msgid/3ee1f8144feb96c28742b22384189f1f83bcfc1a.1669221671.git.geert@linux-m68k.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_fourcc.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
+index 92152c06b75b7..8d1064061e836 100644
+--- a/drivers/gpu/drm/drm_fourcc.c
++++ b/drivers/gpu/drm/drm_fourcc.c
+@@ -178,6 +178,10 @@ const struct drm_format_info *__drm_format_info(u32 format)
+ { .format = DRM_FORMAT_BGRA5551, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
+ { .format = DRM_FORMAT_RGB565, .depth = 16, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
+ { .format = DRM_FORMAT_BGR565, .depth = 16, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
++#ifdef __BIG_ENDIAN
++ { .format = DRM_FORMAT_XRGB1555 | DRM_FORMAT_BIG_ENDIAN, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
++ { .format = DRM_FORMAT_RGB565 | DRM_FORMAT_BIG_ENDIAN, .depth = 16, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
++#endif
+ { .format = DRM_FORMAT_RGB888, .depth = 24, .num_planes = 1, .cpp = { 3, 0, 0 }, .hsub = 1, .vsub = 1 },
+ { .format = DRM_FORMAT_BGR888, .depth = 24, .num_planes = 1, .cpp = { 3, 0, 0 }, .hsub = 1, .vsub = 1 },
+ { .format = DRM_FORMAT_XRGB8888, .depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
+--
+2.39.2
+
--- /dev/null
+From 6828913fc1242f835c17f1ed339395cd3bd0f66f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Nov 2022 09:39:49 -0500
+Subject: drm/mediatek: Clean dangling pointer on bind error path
+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 36aa8c61af55675ed967900fbe5deb32d776f051 ]
+
+mtk_drm_bind() can fail, in which case drm_dev_put() is called,
+destroying the drm_device object. However a pointer to it was still
+being held in the private object, and that pointer would be passed along
+to DRM in mtk_drm_sys_prepare() if a suspend were triggered at that
+point, resulting in a panic. Clean the pointer when destroying the
+object in the error path to prevent this from happening.
+
+Fixes: 119f5173628a ("drm/mediatek: Add DRM Driver for Mediatek SoC MT8173.")
+Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20221122143949.3493104-1-nfraprado@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_drm_drv.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+index 59c85c63b7cc9..719c46d245dd2 100644
+--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
++++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+@@ -378,6 +378,7 @@ static int mtk_drm_bind(struct device *dev)
+ err_deinit:
+ mtk_drm_kms_deinit(drm);
+ err_free:
++ private->drm = NULL;
+ drm_dev_put(drm);
+ return ret;
+ }
+--
+2.39.2
+
--- /dev/null
+From 6a681f7c08b17ad643af8407aecb46d696b311e0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 19 Jan 2023 15:12:55 -0800
+Subject: drm/mediatek: Drop unbalanced obj unref
+
+From: Rob Clark <robdclark@chromium.org>
+
+[ Upstream commit 4deef811828e87e26a978d5d6433b261d4713849 ]
+
+In the error path, mtk_drm_gem_object_mmap() is dropping an obj
+reference that it doesn't own.
+
+Fixes: 119f5173628a ("drm/mediatek: Add DRM Driver for Mediatek SoC MT8173.")
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20230119231255.2883365-1-robdclark@gmail.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_gem.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.c b/drivers/gpu/drm/mediatek/mtk_drm_gem.c
+index 43c54dde2f3fc..29702dd8631d4 100644
+--- a/drivers/gpu/drm/mediatek/mtk_drm_gem.c
++++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.c
+@@ -142,8 +142,6 @@ static int mtk_drm_gem_object_mmap(struct drm_gem_object *obj,
+
+ ret = dma_mmap_attrs(priv->dma_dev, vma, mtk_gem->cookie,
+ mtk_gem->dma_addr, obj->size, mtk_gem->dma_attrs);
+- if (ret)
+- drm_gem_vm_close(vma);
+
+ return ret;
+ }
+--
+2.39.2
+
--- /dev/null
+From 53e0fe145923916bec209b2a3ed57d10d07a1d1d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Jan 2023 13:54:51 +0800
+Subject: drm/mediatek: dsi: Reduce the time of dsi from LP11 to sending cmd
+
+From: Xinlei Lee <xinlei.lee@mediatek.com>
+
+[ Upstream commit 91aeaed2c1147e3b1157dc084d23f190856a6c23 ]
+
+According to Figure 16 Turnaround Procedure on page 36 in [1], you
+can see the status of LP-00 -> LP10 -> LP11. This state can correspond
+to the state of DSI from LP00 -> LP11 in mtk_dsi_lane_ready function
+in mtk_dsi.c.
+
+LP-00 -> LP10 -> LP11 takes about 2*TLPX time (refer to [1] page 51
+to see that TLPX is 50ns)
+
+The delay at the end of the mtk_dsi_lane_ready function should be
+greater than the 2*TLPX specified by the DSI spec, and less than
+the time specified by the DSI_RX (generally 6ms to 40ms), to avoid
+problems caused by the RX specification
+
+[1]:mipi_D-PHY_specification_v1-1
+
+Fixes: 39e8d062b03c ("drm/mediatek: Keep dsi as LP00 before dcs cmds transfer")
+Signed-off-by: Xinlei Lee <xinlei.lee@mediatek.com>
+Acked-by: Sam Ravnborg <sam@ravnborg.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://patchwork.kernel.org/project/linux-mediatek/patch/1673330093-6771-2-git-send-email-xinlei.lee@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_dsi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
+index 146c4d04f572d..a6e71b7b69b83 100644
+--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
++++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
+@@ -704,7 +704,7 @@ static void mtk_dsi_lane_ready(struct mtk_dsi *dsi)
+ mtk_dsi_clk_ulp_mode_leave(dsi);
+ mtk_dsi_lane0_ulp_mode_leave(dsi);
+ mtk_dsi_clk_hs_mode(dsi, 0);
+- msleep(20);
++ usleep_range(1000, 3000);
+ /* The reaction time after pulling up the mipi signal for dsi_rx */
+ }
+ }
+--
+2.39.2
+
--- /dev/null
+From 229b18828f7429c44b88bcb3cd8014223d4e1f8f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Dec 2022 17:51:15 +0800
+Subject: drm/mediatek: mtk_drm_crtc: Add checks for devm_kcalloc
+
+From: ruanjinjie <ruanjinjie@huawei.com>
+
+[ Upstream commit 5bf1e3bd7da625ccf9a22c8cb7d65271e6e47f4c ]
+
+As the devm_kcalloc may return NULL, the return value needs to be checked
+to avoid NULL poineter dereference.
+
+Fixes: 31c5558dae05 ("drm/mediatek: Refactor plane init")
+Signed-off-by: ruanjinjie <ruanjinjie@huawei.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20221205095115.2905090-1-ruanjinjie@huawei.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 | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+index dfd5ed15a7f4a..e83b1c406b96a 100644
+--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
++++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+@@ -803,6 +803,8 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
+
+ mtk_crtc->planes = devm_kcalloc(dev, num_comp_planes,
+ sizeof(struct drm_plane), GFP_KERNEL);
++ if (!mtk_crtc->planes)
++ return -ENOMEM;
+
+ for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
+ ret = mtk_drm_crtc_init_comp_planes(drm_dev, mtk_crtc, i,
+--
+2.39.2
+
--- /dev/null
+From 2ce0b504f9812a1104948b95d651dda80946b4d5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Jan 2023 10:44:41 +0800
+Subject: drm/mediatek: Use NULL instead of 0 for NULL pointer
+
+From: Miles Chen <miles.chen@mediatek.com>
+
+[ Upstream commit 4744cde06f57dd6fbaac468663b1fe2f653eaa16 ]
+
+Use NULL for NULL pointer to fix the following sparse warning:
+drivers/gpu/drm/mediatek/mtk_drm_gem.c:265:27: sparse: warning: Using plain integer as NULL pointer
+
+Fixes: 3df64d7b0a4f ("drm/mediatek: Implement gem prime vmap/vunmap function")
+Signed-off-by: Miles Chen <miles.chen@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20230111024443.24559-1-miles.chen@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_gem.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.c b/drivers/gpu/drm/mediatek/mtk_drm_gem.c
+index 0583e557ad372..43c54dde2f3fc 100644
+--- a/drivers/gpu/drm/mediatek/mtk_drm_gem.c
++++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.c
+@@ -266,6 +266,6 @@ void mtk_drm_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr)
+ return;
+
+ vunmap(vaddr);
+- mtk_gem->kvaddr = 0;
++ mtk_gem->kvaddr = NULL;
+ kfree(mtk_gem->pages);
+ }
+--
+2.39.2
+
--- /dev/null
+From 77caa8a31f9b91281001e36361c264a3b8687292 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Jan 2023 17:49:07 -0500
+Subject: drm/mipi-dsi: Fix byte order of 16-bit DCS set/get brightness
+
+From: Daniel Mentz <danielmentz@google.com>
+
+[ Upstream commit c9d27c6be518b4ef2966d9564654ef99292ea1b3 ]
+
+The MIPI DCS specification demands that brightness values are sent in
+big endian byte order. It also states that one parameter (i.e. one byte)
+shall be sent/received for 8 bit wide values, and two parameters shall
+be used for values that are between 9 and 16 bits wide.
+
+Add new functions to properly handle 16-bit brightness in big endian,
+since the two 8- and 16-bit cases are distinct from each other.
+
+[richard: use separate functions instead of switch/case]
+[richard: split into 16-bit component]
+
+Fixes: 1a9d759331b8 ("drm/dsi: Implement DCS set/get display brightness")
+Signed-off-by: Daniel Mentz <danielmentz@google.com>
+Link: https://android.googlesource.com/kernel/msm/+/754affd62d0ee268c686c53169b1dbb7deac8550
+[richard: fix 16-bit brightness_get]
+Signed-off-by: Richard Acayan <mailingradian@gmail.com>
+Tested-by: Caleb Connolly <caleb@connolly.tech>
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230116224909.23884-2-mailingradian@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_mipi_dsi.c | 52 ++++++++++++++++++++++++++++++++++
+ include/drm/drm_mipi_dsi.h | 4 +++
+ 2 files changed, 56 insertions(+)
+
+diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
+index 2c43d54766f34..19fb1d93a4f07 100644
+--- a/drivers/gpu/drm/drm_mipi_dsi.c
++++ b/drivers/gpu/drm/drm_mipi_dsi.c
+@@ -1143,6 +1143,58 @@ int mipi_dsi_dcs_get_display_brightness(struct mipi_dsi_device *dsi,
+ }
+ EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness);
+
++/**
++ * mipi_dsi_dcs_set_display_brightness_large() - sets the 16-bit brightness value
++ * of the display
++ * @dsi: DSI peripheral device
++ * @brightness: brightness value
++ *
++ * Return: 0 on success or a negative error code on failure.
++ */
++int mipi_dsi_dcs_set_display_brightness_large(struct mipi_dsi_device *dsi,
++ u16 brightness)
++{
++ u8 payload[2] = { brightness >> 8, brightness & 0xff };
++ ssize_t err;
++
++ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS,
++ payload, sizeof(payload));
++ if (err < 0)
++ return err;
++
++ return 0;
++}
++EXPORT_SYMBOL(mipi_dsi_dcs_set_display_brightness_large);
++
++/**
++ * mipi_dsi_dcs_get_display_brightness_large() - gets the current 16-bit
++ * brightness value of the display
++ * @dsi: DSI peripheral device
++ * @brightness: brightness value
++ *
++ * Return: 0 on success or a negative error code on failure.
++ */
++int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi,
++ u16 *brightness)
++{
++ u8 brightness_be[2];
++ ssize_t err;
++
++ err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_DISPLAY_BRIGHTNESS,
++ brightness_be, sizeof(brightness_be));
++ if (err <= 0) {
++ if (err == 0)
++ err = -ENODATA;
++
++ return err;
++ }
++
++ *brightness = (brightness_be[0] << 8) | brightness_be[1];
++
++ return 0;
++}
++EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness_large);
++
+ static int mipi_dsi_drv_probe(struct device *dev)
+ {
+ struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver);
+diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
+index 360e6377e84ba..31ba85a4110a8 100644
+--- a/include/drm/drm_mipi_dsi.h
++++ b/include/drm/drm_mipi_dsi.h
+@@ -283,6 +283,10 @@ int mipi_dsi_dcs_set_display_brightness(struct mipi_dsi_device *dsi,
+ u16 brightness);
+ int mipi_dsi_dcs_get_display_brightness(struct mipi_dsi_device *dsi,
+ u16 *brightness);
++int mipi_dsi_dcs_set_display_brightness_large(struct mipi_dsi_device *dsi,
++ u16 brightness);
++int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi,
++ u16 *brightness);
+
+ /**
+ * struct mipi_dsi_driver - DSI driver
+--
+2.39.2
+
--- /dev/null
+From 0a860f61899f6bd1b457dfbd9992a170c004a583 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Dec 2022 20:39:56 +0530
+Subject: drm/msm/adreno: Fix null ptr access in adreno_gpu_cleanup()
+
+From: Akhil P Oommen <quic_akhilpo@quicinc.com>
+
+[ Upstream commit dbeedbcb268d055d8895aceca427f897e12c2b50 ]
+
+Fix the below kernel panic due to null pointer access:
+[ 18.504431] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000048
+[ 18.513464] Mem abort info:
+[ 18.516346] ESR = 0x0000000096000005
+[ 18.520204] EC = 0x25: DABT (current EL), IL = 32 bits
+[ 18.525706] SET = 0, FnV = 0
+[ 18.528878] EA = 0, S1PTW = 0
+[ 18.532117] FSC = 0x05: level 1 translation fault
+[ 18.537138] Data abort info:
+[ 18.540110] ISV = 0, ISS = 0x00000005
+[ 18.544060] CM = 0, WnR = 0
+[ 18.547109] user pgtable: 4k pages, 39-bit VAs, pgdp=0000000112826000
+[ 18.553738] [0000000000000048] pgd=0000000000000000, p4d=0000000000000000, pud=0000000000000000
+[ 18.562690] Internal error: Oops: 0000000096000005 [#1] PREEMPT SMP
+**Snip**
+[ 18.696758] Call trace:
+[ 18.699278] adreno_gpu_cleanup+0x30/0x88
+[ 18.703396] a6xx_destroy+0xc0/0x130
+[ 18.707066] a6xx_gpu_init+0x308/0x424
+[ 18.710921] adreno_bind+0x178/0x288
+[ 18.714590] component_bind_all+0xe0/0x214
+[ 18.718797] msm_drm_bind+0x1d4/0x614
+[ 18.722566] try_to_bring_up_aggregate_device+0x16c/0x1b8
+[ 18.728105] __component_add+0xa0/0x158
+[ 18.732048] component_add+0x20/0x2c
+[ 18.735719] adreno_probe+0x40/0xc0
+[ 18.739300] platform_probe+0xb4/0xd4
+[ 18.743068] really_probe+0xfc/0x284
+[ 18.746738] __driver_probe_device+0xc0/0xec
+[ 18.751129] driver_probe_device+0x48/0x110
+[ 18.755421] __device_attach_driver+0xa8/0xd0
+[ 18.759900] bus_for_each_drv+0x90/0xdc
+[ 18.763843] __device_attach+0xfc/0x174
+[ 18.767786] device_initial_probe+0x20/0x2c
+[ 18.772090] bus_probe_device+0x40/0xa0
+[ 18.776032] deferred_probe_work_func+0x94/0xd0
+[ 18.780686] process_one_work+0x190/0x3d0
+[ 18.784805] worker_thread+0x280/0x3d4
+[ 18.788659] kthread+0x104/0x1c0
+[ 18.791981] ret_from_fork+0x10/0x20
+[ 18.795654] Code: f9400408 aa0003f3 aa1f03f4 91142015 (f9402516)
+[ 18.801913] ---[ end trace 0000000000000000 ]---
+[ 18.809039] Kernel panic - not syncing: Oops: Fatal exception
+
+Fixes: 17e822f7591f ("drm/msm: fix unbalanced pm_runtime_enable in adreno_gpu_{init, cleanup}")
+Signed-off-by: Akhil P Oommen <quic_akhilpo@quicinc.com>
+Patchwork: https://patchwork.freedesktop.org/patch/515605/
+Link: https://lore.kernel.org/r/20221221203925.v2.1.Ib978de92c4bd000b515486aad72e96c2481f84d0@changeid
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/adreno/adreno_gpu.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+index de8cc25506d61..78181e2d78a97 100644
+--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
++++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+@@ -954,13 +954,13 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
+ void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu)
+ {
+ struct msm_gpu *gpu = &adreno_gpu->base;
+- struct msm_drm_private *priv = gpu->dev->dev_private;
++ struct msm_drm_private *priv = gpu->dev ? gpu->dev->dev_private : NULL;
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(adreno_gpu->info->fw); i++)
+ release_firmware(adreno_gpu->fw[i]);
+
+- if (pm_runtime_enabled(&priv->gpu_pdev->dev))
++ if (priv && pm_runtime_enabled(&priv->gpu_pdev->dev))
+ pm_runtime_disable(&priv->gpu_pdev->dev);
+
+ msm_gpu_cleanup(&adreno_gpu->base);
+--
+2.39.2
+
--- /dev/null
+From 7d40cc2c4ad115c49c06e8649d984e5b9beeb0bc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Dec 2022 16:05:17 +0800
+Subject: drm/msm/dpu: Add check for cstate
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit c96988b7d99327bb08bd9efd29a203b22cd88ace ]
+
+As kzalloc may fail and return NULL pointer,
+it should be better to check cstate
+in order to avoid the NULL pointer dereference
+in __drm_atomic_helper_crtc_reset.
+
+Fixes: 1cff7440a86e ("drm/msm: Convert to using __drm_atomic_helper_crtc_reset() for reset.")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Patchwork: https://patchwork.freedesktop.org/patch/514163/
+Link: https://lore.kernel.org/r/20221206080517.43786-1-jiasheng@iscas.ac.cn
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+index f56414a06ec41..d6e9efed8b6a3 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+@@ -682,7 +682,10 @@ static void dpu_crtc_reset(struct drm_crtc *crtc)
+ if (crtc->state)
+ dpu_crtc_destroy_state(crtc, crtc->state);
+
+- __drm_atomic_helper_crtc_reset(crtc, &cstate->base);
++ if (cstate)
++ __drm_atomic_helper_crtc_reset(crtc, &cstate->base);
++ else
++ __drm_atomic_helper_crtc_reset(crtc, NULL);
+ }
+
+ /**
+--
+2.39.2
+
--- /dev/null
+From 80479cfb050c5108e5e678386d1037f645707ce7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Dec 2022 16:02:36 +0800
+Subject: drm/msm/dpu: Add check for pstates
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit 93340e10b9c5fc86730d149636e0aa8b47bb5a34 ]
+
+As kzalloc may fail and return NULL pointer,
+it should be better to check pstates
+in order to avoid the NULL pointer dereference.
+
+Fixes: 25fdd5933e4c ("drm/msm: Add SDM845 DPU support")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Patchwork: https://patchwork.freedesktop.org/patch/514160/
+Link: https://lore.kernel.org/r/20221206080236.43687-1-jiasheng@iscas.ac.cn
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+index d6e9efed8b6a3..5afb3c544653c 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+@@ -834,6 +834,8 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
+ struct drm_rect crtc_rect = { 0 };
+
+ pstates = kzalloc(sizeof(*pstates) * DPU_STAGE_MAX * 4, GFP_KERNEL);
++ if (!pstates)
++ return -ENOMEM;
+
+ if (!state->enable || !state->active) {
+ DPU_DEBUG("crtc%d -> enable %d, active %d, skip atomic_check\n",
+--
+2.39.2
+
--- /dev/null
+From d36290aee1528a76ad82825d73ebab8217f95616 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Jan 2023 00:15:55 +0100
+Subject: drm/msm/dpu: Disallow unallocated resources to be returned
+
+From: Marijn Suijten <marijn.suijten@somainline.org>
+
+[ Upstream commit abc40122d9a69f56c04efb5a7485795f5ac799d1 ]
+
+In the event that the topology requests resources that have not been
+created by the system (because they are typically not represented in
+dpu_mdss_cfg ^1), the resource(s) in global_state (in this case DSC
+blocks, until their allocation/assignment is being sanity-checked in
+"drm/msm/dpu: Reject topologies for which no DSC blocks are available")
+remain NULL but will still be returned out of
+dpu_rm_get_assigned_resources, where the caller expects to get an array
+containing num_blks valid pointers (but instead gets these NULLs).
+
+To prevent this from happening, where null-pointer dereferences
+typically result in a hard-to-debug platform lockup, num_blks shouldn't
+increase past NULL blocks and will print an error and break instead.
+After all, max_blks represents the static size of the maximum number of
+blocks whereas the actual amount varies per platform.
+
+^1: which can happen after a git rebase ended up moving additions to
+_dpu_cfg to a different struct which has the same patch context.
+
+Fixes: bb00a452d6f7 ("drm/msm/dpu: Refactor resource manager")
+Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Patchwork: https://patchwork.freedesktop.org/patch/517636/
+Link: https://lore.kernel.org/r/20230109231556.344977-1-marijn.suijten@somainline.org
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+index 74a13ccad34c0..9483005297438 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+@@ -633,6 +633,11 @@ int dpu_rm_get_assigned_resources(struct dpu_rm *rm,
+ blks_size, enc_id);
+ break;
+ }
++ if (!hw_blks[i]) {
++ DPU_ERROR("Allocated resource %d unavailable to assign to enc %d\n",
++ type, enc_id);
++ break;
++ }
+ blks[num_blks++] = hw_blks[i];
+ }
+
+--
+2.39.2
+
--- /dev/null
+From be7e5b8a0a9563c49208450eb0e633f06ead9ec7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Jan 2023 10:16:51 +0800
+Subject: drm/msm/dsi: Add missing check for alloc_ordered_workqueue
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit 115906ca7b535afb1fe7b5406c566ccd3873f82b ]
+
+Add check for the return value of alloc_ordered_workqueue as it may return
+NULL pointer and cause NULL pointer dereference.
+
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Patchwork: https://patchwork.freedesktop.org/patch/517646/
+Link: https://lore.kernel.org/r/20230110021651.12770-1-jiasheng@iscas.ac.cn
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/dsi/dsi_host.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
+index 51e8318cc8ff4..5a76aa1389173 100644
+--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
++++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
+@@ -1913,6 +1913,9 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
+
+ /* setup workqueue */
+ msm_host->workqueue = alloc_ordered_workqueue("dsi_drm_work", 0);
++ if (!msm_host->workqueue)
++ return -ENOMEM;
++
+ INIT_WORK(&msm_host->err_work, dsi_err_worker);
+ INIT_WORK(&msm_host->hpd_work, dsi_hpd_worker);
+
+--
+2.39.2
+
--- /dev/null
+From 6f5c635a80d598a0da1a1e3fe4481f9b2e0c1138 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Jan 2023 10:30:11 +0800
+Subject: drm/msm/hdmi: Add missing check for alloc_ordered_workqueue
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit afe4cb96153a0d8003e4e4ebd91b5c543e10df84 ]
+
+Add check for the return value of alloc_ordered_workqueue as it may return
+NULL pointer and cause NULL pointer dereference in `hdmi_hdcp.c` and
+`hdmi_hpd.c`.
+
+Fixes: c6a57a50ad56 ("drm/msm/hdmi: add hdmi hdcp support (V3)")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Patchwork: https://patchwork.freedesktop.org/patch/517211/
+Link: https://lore.kernel.org/r/20230106023011.3985-1-jiasheng@iscas.ac.cn
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/hdmi/hdmi.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
+index efb14043a6ec4..bee208773beec 100644
+--- a/drivers/gpu/drm/msm/hdmi/hdmi.c
++++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
+@@ -264,6 +264,10 @@ static struct hdmi *msm_hdmi_init(struct platform_device *pdev)
+ pm_runtime_enable(&pdev->dev);
+
+ hdmi->workq = alloc_ordered_workqueue("msm_hdmi", 0);
++ if (!hdmi->workq) {
++ ret = -ENOMEM;
++ goto fail;
++ }
+
+ hdmi->i2c = msm_hdmi_i2c_init(hdmi);
+ if (IS_ERR(hdmi->i2c)) {
+--
+2.39.2
+
--- /dev/null
+From c77876395272a71227f6e8ab9171dc619968f5ec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Dec 2022 15:48:19 +0800
+Subject: drm/msm/mdp5: Add check for kzalloc
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit 13fcfcb2a9a4787fe4e49841d728f6f2e9fa6911 ]
+
+As kzalloc may fail and return NULL pointer,
+it should be better to check the return value
+in order to avoid the NULL pointer dereference.
+
+Fixes: 1cff7440a86e ("drm/msm: Convert to using __drm_atomic_helper_crtc_reset() for reset.")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Patchwork: https://patchwork.freedesktop.org/patch/514154/
+Link: https://lore.kernel.org/r/20221206074819.18134-1-jiasheng@iscas.ac.cn
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
+index ff4f207cbdeaf..60e7371cd0e0d 100644
+--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
++++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
+@@ -1124,7 +1124,10 @@ static void mdp5_crtc_reset(struct drm_crtc *crtc)
+ if (crtc->state)
+ mdp5_crtc_destroy_state(crtc, crtc->state);
+
+- __drm_atomic_helper_crtc_reset(crtc, &mdp5_cstate->base);
++ if (mdp5_cstate)
++ __drm_atomic_helper_crtc_reset(crtc, &mdp5_cstate->base);
++ else
++ __drm_atomic_helper_crtc_reset(crtc, NULL);
+ }
+
+ static const struct drm_crtc_funcs mdp5_crtc_no_lm_cursor_funcs = {
+--
+2.39.2
+
--- /dev/null
+From f6c80aaa0b0e9b039fcbaefb57553c8324e94474 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Jan 2023 04:01:52 +0200
+Subject: drm/msm: use strscpy instead of strncpy
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit d7fd8634f48d76aa799ed57beb7d87dab91bde80 ]
+
+Using strncpy can result in non-NULL-terminated destination string. Use
+strscpy instead. This fixes following warning:
+
+drivers/gpu/drm/msm/msm_fence.c: In function ‘msm_fence_context_alloc’:
+drivers/gpu/drm/msm/msm_fence.c:25:9: warning: ‘strncpy’ specified bound 32 equals destination size [-Wstringop-truncation]
+ 25 | strncpy(fctx->name, name, sizeof(fctx->name));
+ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Fixes: f97decac5f4c ("drm/msm: Support multiple ringbuffers")
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Patchwork: https://patchwork.freedesktop.org/patch/518787/
+Link: https://lore.kernel.org/r/20230118020152.1689213-1-dmitry.baryshkov@linaro.org
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/msm_fence.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/msm/msm_fence.c b/drivers/gpu/drm/msm/msm_fence.c
+index cd59a59180385..50a25c119f4d9 100644
+--- a/drivers/gpu/drm/msm/msm_fence.c
++++ b/drivers/gpu/drm/msm/msm_fence.c
+@@ -20,7 +20,7 @@ msm_fence_context_alloc(struct drm_device *dev, const char *name)
+ return ERR_PTR(-ENOMEM);
+
+ fctx->dev = dev;
+- strncpy(fctx->name, name, sizeof(fctx->name));
++ strscpy(fctx->name, name, sizeof(fctx->name));
+ fctx->context = dma_fence_context_alloc(1);
+ init_waitqueue_head(&fctx->event);
+ spin_lock_init(&fctx->spinlock);
+--
+2.39.2
+
--- /dev/null
+From 062c300a63725b59e82a29454f2773d3d32fd81f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Nov 2022 16:59:55 +0100
+Subject: drm: mxsfb: DRM_MXSFB should depend on ARCH_MXS || ARCH_MXC
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit 7783cc67862f9166c901bfa0f80b717aa8d354dd ]
+
+Freescale/NXP i.MX LCDIF and eLCDIF LCD controllers are only present on
+Freescale/NXP i.MX SoCs. Hence add a dependency on ARCH_MXS ||
+ARCH_MXC, to prevent asking the user about this driver when configuring
+a kernel without Freescale/NXP i.MX support.
+
+Fixes: 45d59d704080cc0c ("drm: Add new driver for MXSFB controller")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Marek Vasut <marex@denx.de>
+Signed-off-by: Marek Vasut <marex@denx.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/98e74779ca2bc575d91afff03369e86b080c01ac.1669046358.git.geert+renesas@glider.be
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/mxsfb/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/mxsfb/Kconfig b/drivers/gpu/drm/mxsfb/Kconfig
+index ee22cd25d3e3d..e7201e16119a4 100644
+--- a/drivers/gpu/drm/mxsfb/Kconfig
++++ b/drivers/gpu/drm/mxsfb/Kconfig
+@@ -8,6 +8,7 @@ config DRM_MXSFB
+ tristate "i.MX (e)LCDIF LCD controller"
+ depends on DRM && OF
+ depends on COMMON_CLK
++ depends on ARCH_MXS || ARCH_MXC || COMPILE_TEST
+ select DRM_MXS
+ select DRM_KMS_HELPER
+ select DRM_KMS_CMA_HELPER
+--
+2.39.2
+
--- /dev/null
+From 33d89731ba8c2bf4a346468775645ca614c9085d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Sep 2022 11:22:05 +0300
+Subject: drm/omap: dsi: Fix excessive stack usage
+
+From: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+
+[ Upstream commit cfca78971b9233aef0891507a98fba62046d4542 ]
+
+dsi_dump_dsi_irqs(), a function used for debugfs prints, has a large
+struct in its frame, which can result in:
+
+drivers/gpu/drm/omapdrm/dss/dsi.c:1126:1: warning: the frame size of 1060 bytes is larger than 1024 bytes [-Wframe-larger-than=]
+
+As the performance of the function is of no concern, let's allocate the
+struct with kmalloc instead.
+
+Compile-tested only.
+
+Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+Reported-by: kernel test robot <lkp@intel.com>
+Reviewed-by: Arnd Bergmann <arnd@arndb.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220916082206.167427-1-tomi.valkeinen@ideasonboard.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/omapdrm/dss/dsi.c | 26 ++++++++++++++++----------
+ 1 file changed, 16 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
+index eeccf40bae416..1b1ddc5fe6dcc 100644
+--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
++++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
+@@ -1444,22 +1444,26 @@ static int dsi_dump_dsi_irqs(struct seq_file *s, void *p)
+ {
+ struct dsi_data *dsi = s->private;
+ unsigned long flags;
+- struct dsi_irq_stats stats;
++ struct dsi_irq_stats *stats;
++
++ stats = kmalloc(sizeof(*stats), GFP_KERNEL);
++ if (!stats)
++ return -ENOMEM;
+
+ spin_lock_irqsave(&dsi->irq_stats_lock, flags);
+
+- stats = dsi->irq_stats;
++ *stats = dsi->irq_stats;
+ memset(&dsi->irq_stats, 0, sizeof(dsi->irq_stats));
+ dsi->irq_stats.last_reset = jiffies;
+
+ spin_unlock_irqrestore(&dsi->irq_stats_lock, flags);
+
+ seq_printf(s, "period %u ms\n",
+- jiffies_to_msecs(jiffies - stats.last_reset));
++ jiffies_to_msecs(jiffies - stats->last_reset));
+
+- seq_printf(s, "irqs %d\n", stats.irq_count);
++ seq_printf(s, "irqs %d\n", stats->irq_count);
+ #define PIS(x) \
+- seq_printf(s, "%-20s %10d\n", #x, stats.dsi_irqs[ffs(DSI_IRQ_##x)-1]);
++ seq_printf(s, "%-20s %10d\n", #x, stats->dsi_irqs[ffs(DSI_IRQ_##x)-1]);
+
+ seq_printf(s, "-- DSI%d interrupts --\n", dsi->module_id + 1);
+ PIS(VC0);
+@@ -1483,10 +1487,10 @@ static int dsi_dump_dsi_irqs(struct seq_file *s, void *p)
+
+ #define PIS(x) \
+ seq_printf(s, "%-20s %10d %10d %10d %10d\n", #x, \
+- stats.vc_irqs[0][ffs(DSI_VC_IRQ_##x)-1], \
+- stats.vc_irqs[1][ffs(DSI_VC_IRQ_##x)-1], \
+- stats.vc_irqs[2][ffs(DSI_VC_IRQ_##x)-1], \
+- stats.vc_irqs[3][ffs(DSI_VC_IRQ_##x)-1]);
++ stats->vc_irqs[0][ffs(DSI_VC_IRQ_##x)-1], \
++ stats->vc_irqs[1][ffs(DSI_VC_IRQ_##x)-1], \
++ stats->vc_irqs[2][ffs(DSI_VC_IRQ_##x)-1], \
++ stats->vc_irqs[3][ffs(DSI_VC_IRQ_##x)-1]);
+
+ seq_printf(s, "-- VC interrupts --\n");
+ PIS(CS);
+@@ -1502,7 +1506,7 @@ static int dsi_dump_dsi_irqs(struct seq_file *s, void *p)
+
+ #define PIS(x) \
+ seq_printf(s, "%-20s %10d\n", #x, \
+- stats.cio_irqs[ffs(DSI_CIO_IRQ_##x)-1]);
++ stats->cio_irqs[ffs(DSI_CIO_IRQ_##x)-1]);
+
+ seq_printf(s, "-- CIO interrupts --\n");
+ PIS(ERRSYNCESC1);
+@@ -1527,6 +1531,8 @@ static int dsi_dump_dsi_irqs(struct seq_file *s, void *p)
+ PIS(ULPSACTIVENOT_ALL1);
+ #undef PIS
+
++ kfree(stats);
++
+ return 0;
+ }
+ #endif
+--
+2.39.2
+
--- /dev/null
+From ab775d54ef9699b9c174ce782071216abcc40c4c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Feb 2023 16:46:59 +0000
+Subject: drm: panel-orientation-quirks: Add quirk for Lenovo IdeaPad Duet 3
+ 10IGL5
+
+From: Darrell Kavanagh <darrell.kavanagh@gmail.com>
+
+[ Upstream commit 38b2d8efd03d2e56431b611e3523f0158306451d ]
+
+Another Lenovo convertable where the panel is installed landscape but is
+reported to the kernel as portrait.
+
+Signed-off-by: Darrell Kavanagh <darrell.kavanagh@gmail.com>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230214164659.3583-1-darrell.kavanagh@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_panel_orientation_quirks.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c
+index ce739ba45c551..8768073794fbf 100644
+--- a/drivers/gpu/drm/drm_panel_orientation_quirks.c
++++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c
+@@ -278,6 +278,12 @@ static const struct dmi_system_id orientation_data[] = {
+ DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad D330-10IGL"),
+ },
+ .driver_data = (void *)&lcd800x1280_rightside_up,
++ }, { /* Lenovo IdeaPad Duet 3 10IGL5 */
++ .matches = {
++ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++ DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "IdeaPad Duet 3 10IGL5"),
++ },
++ .driver_data = (void *)&lcd1200x1920_rightside_up,
+ }, { /* Lenovo Yoga Book X90F / X91F / X91L */
+ .matches = {
+ /* Non exact match to match all versions */
+--
+2.39.2
+
--- /dev/null
+From b5996cc95524a9cef2451445b90b4f5d9e4d74f4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Jan 2023 17:47:29 +0800
+Subject: drm/radeon: free iio for atombios when driver shutdown
+
+From: Liwei Song <liwei.song@windriver.com>
+
+[ Upstream commit 4773fadedca918faec443daaca5e4ea1c0ced144 ]
+
+Fix below kmemleak when unload radeon driver:
+
+unreferenced object 0xffff9f8608ede200 (size 512):
+ comm "systemd-udevd", pid 326, jiffies 4294682822 (age 716.338s)
+ hex dump (first 32 bytes):
+ 00 00 00 00 c4 aa ec aa 14 ab 00 00 00 00 00 00 ................
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ backtrace:
+ [<0000000062fadebe>] kmem_cache_alloc_trace+0x2f1/0x500
+ [<00000000b6883cea>] atom_parse+0x117/0x230 [radeon]
+ [<00000000158c23fd>] radeon_atombios_init+0xab/0x170 [radeon]
+ [<00000000683f672e>] si_init+0x57/0x750 [radeon]
+ [<00000000566cc31f>] radeon_device_init+0x559/0x9c0 [radeon]
+ [<0000000046efabb3>] radeon_driver_load_kms+0xc1/0x1a0 [radeon]
+ [<00000000b5155064>] drm_dev_register+0xdd/0x1d0
+ [<0000000045fec835>] radeon_pci_probe+0xbd/0x100 [radeon]
+ [<00000000e69ecca3>] pci_device_probe+0xe1/0x160
+ [<0000000019484b76>] really_probe.part.0+0xc1/0x2c0
+ [<000000003f2649da>] __driver_probe_device+0x96/0x130
+ [<00000000231c5bb1>] driver_probe_device+0x24/0xf0
+ [<0000000000a42377>] __driver_attach+0x77/0x190
+ [<00000000d7574da6>] bus_for_each_dev+0x7f/0xd0
+ [<00000000633166d2>] driver_attach+0x1e/0x30
+ [<00000000313b05b8>] bus_add_driver+0x12c/0x1e0
+
+iio was allocated in atom_index_iio() called by atom_parse(),
+but it doesn't got released when the dirver is shutdown.
+Fix this kmemleak by free it in radeon_atombios_fini().
+
+Signed-off-by: Liwei Song <liwei.song@windriver.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/radeon/radeon_device.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
+index 8287410f471fb..131f425c363a5 100644
+--- a/drivers/gpu/drm/radeon/radeon_device.c
++++ b/drivers/gpu/drm/radeon/radeon_device.c
+@@ -1022,6 +1022,7 @@ void radeon_atombios_fini(struct radeon_device *rdev)
+ {
+ if (rdev->mode_info.atom_context) {
+ kfree(rdev->mode_info.atom_context->scratch);
++ kfree(rdev->mode_info.atom_context->iio);
+ }
+ kfree(rdev->mode_info.atom_context);
+ rdev->mode_info.atom_context = NULL;
+--
+2.39.2
+
--- /dev/null
+From 488fdc3909563b2759296213a7bc2017ca0b9955 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Dec 2022 18:18:03 -0600
+Subject: drm: tidss: Fix pixel format definition
+
+From: Randolph Sapp <rs@ti.com>
+
+[ Upstream commit 2df0433b18f2735a49d2c3a968b40fa2881137c0 ]
+
+There was a long-standing bug from a typo that created 2 ARGB1555 and
+ABGR1555 pixel format entries. Weston 10 has a sanity check that alerted
+me to this issue.
+
+According to the Supported Pixel Data formats table we have the later
+entries should have been for Alpha-X instead.
+
+Signed-off-by: Randolph Sapp <rs@ti.com>
+Fixes: 32a1795f57eecc ("drm/tidss: New driver for TI Keystone platform Display SubSystem")
+Reviewed-by: Aradhya Bhatia <a-bhatia1@ti.com>
+Acked-by: Andrew Davis <afd@ti.com>
+Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20221202001803.1765805-1-rs@ti.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/tidss/tidss_dispc.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/tidss_dispc.c
+index b669168ae7cb2..33716213a8210 100644
+--- a/drivers/gpu/drm/tidss/tidss_dispc.c
++++ b/drivers/gpu/drm/tidss/tidss_dispc.c
+@@ -1855,8 +1855,8 @@ static const struct {
+ { DRM_FORMAT_XBGR4444, 0x21, },
+ { DRM_FORMAT_RGBX4444, 0x22, },
+
+- { DRM_FORMAT_ARGB1555, 0x25, },
+- { DRM_FORMAT_ABGR1555, 0x26, },
++ { DRM_FORMAT_XRGB1555, 0x25, },
++ { DRM_FORMAT_XBGR1555, 0x26, },
+
+ { DRM_FORMAT_XRGB8888, 0x27, },
+ { DRM_FORMAT_XBGR8888, 0x28, },
+--
+2.39.2
+
--- /dev/null
+From 3abdc5688113eb7e14f2a8c37c1fb2294161f6cf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Dec 2022 10:02:38 +0100
+Subject: drm/tiny: ili9486: Do not assume 8-bit only SPI controllers
+
+From: Carlo Caione <ccaione@baylibre.com>
+
+[ Upstream commit 77772e607522daa61f3af74df018559db75c43d6 ]
+
+The pixel data for the ILI9486 is always 16-bits wide and it must be
+sent over the SPI bus. When the controller is only able to deal with
+8-bit transfers, this 16-bits data needs to be swapped before the
+sending to account for the big endian bus, this is on the contrary not
+needed when the SPI controller already supports 16-bits transfers.
+
+The decision about swapping the pixel data or not is taken in the MIPI
+DBI code by probing the controller capabilities: if the controller only
+suppors 8-bit transfers the data is swapped, otherwise it is not.
+
+This swapping/non-swapping is relying on the assumption that when the
+controller does support 16-bit transactions then the data is sent
+unswapped in 16-bits-per-word over SPI.
+
+The problem with the ILI9486 driver is that it is forcing 8-bit
+transactions also for controllers supporting 16-bits, violating the
+assumption and corrupting the pixel data.
+
+Align the driver to what is done in the MIPI DBI code by adjusting the
+transfer size to the maximum allowed by the SPI controller.
+
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Carlo Caione <ccaione@baylibre.com>
+Reviewed-by: Kamlesh Gurudasani <kamlesh.gurudasani@gmail.com>
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20221116-s905x_spi_ili9486-v4-2-f86b4463b9e4@baylibre.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/tiny/ili9486.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/tiny/ili9486.c b/drivers/gpu/drm/tiny/ili9486.c
+index 403af68fa4400..7ea26e5fbcb28 100644
+--- a/drivers/gpu/drm/tiny/ili9486.c
++++ b/drivers/gpu/drm/tiny/ili9486.c
+@@ -43,6 +43,7 @@ static int waveshare_command(struct mipi_dbi *mipi, u8 *cmd, u8 *par,
+ size_t num)
+ {
+ struct spi_device *spi = mipi->spi;
++ unsigned int bpw = 8;
+ void *data = par;
+ u32 speed_hz;
+ int i, ret;
+@@ -56,8 +57,6 @@ static int waveshare_command(struct mipi_dbi *mipi, u8 *cmd, u8 *par,
+ * The displays are Raspberry Pi HATs and connected to the 8-bit only
+ * SPI controller, so 16-bit command and parameters need byte swapping
+ * before being transferred as 8-bit on the big endian SPI bus.
+- * Pixel data bytes have already been swapped before this function is
+- * called.
+ */
+ buf[0] = cpu_to_be16(*cmd);
+ gpiod_set_value_cansleep(mipi->dc, 0);
+@@ -71,12 +70,18 @@ static int waveshare_command(struct mipi_dbi *mipi, u8 *cmd, u8 *par,
+ for (i = 0; i < num; i++)
+ buf[i] = cpu_to_be16(par[i]);
+ num *= 2;
+- speed_hz = mipi_dbi_spi_cmd_max_speed(spi, num);
+ data = buf;
+ }
+
++ /*
++ * Check whether pixel data bytes needs to be swapped or not
++ */
++ if (*cmd == MIPI_DCS_WRITE_MEMORY_START && !mipi->swap_bytes)
++ bpw = 16;
++
+ gpiod_set_value_cansleep(mipi->dc, 1);
+- ret = mipi_dbi_spi_transfer(spi, speed_hz, 8, data, num);
++ speed_hz = mipi_dbi_spi_cmd_max_speed(spi, num);
++ ret = mipi_dbi_spi_transfer(spi, speed_hz, bpw, data, num);
+ free:
+ kfree(buf);
+
+--
+2.39.2
+
--- /dev/null
+From 196a519c698c84a219a5eff36e629aae759f5ef8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 16:47:36 +0200
+Subject: drm/vc4: dpi: Add option for inverting pixel clock and output enable
+
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+
+[ Upstream commit 3c2707632146b22e97b0fbf6778bab8add2eaa1d ]
+
+DRM provides flags for inverting pixel clock and output enable
+signals, but these were not mapped to the relevant registers.
+
+Add those mappings.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Link: https://lore.kernel.org/r/20220613144800.326124-10-maxime@cerno.tech
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Stable-dep-of: 0870d86eac8a ("drm/vc4: dpi: Fix format mapping for RGB565")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_dpi.c | 66 ++++++++++++++++++++---------------
+ 1 file changed, 38 insertions(+), 28 deletions(-)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_dpi.c b/drivers/gpu/drm/vc4/vc4_dpi.c
+index a90f2545baee0..0e25add2df071 100644
+--- a/drivers/gpu/drm/vc4/vc4_dpi.c
++++ b/drivers/gpu/drm/vc4/vc4_dpi.c
+@@ -148,35 +148,45 @@ static void vc4_dpi_encoder_enable(struct drm_encoder *encoder)
+ }
+ drm_connector_list_iter_end(&conn_iter);
+
+- if (connector && connector->display_info.num_bus_formats) {
+- u32 bus_format = connector->display_info.bus_formats[0];
+-
+- switch (bus_format) {
+- case MEDIA_BUS_FMT_RGB888_1X24:
+- dpi_c |= VC4_SET_FIELD(DPI_FORMAT_24BIT_888_RGB,
+- DPI_FORMAT);
+- break;
+- case MEDIA_BUS_FMT_BGR888_1X24:
+- dpi_c |= VC4_SET_FIELD(DPI_FORMAT_24BIT_888_RGB,
+- DPI_FORMAT);
+- dpi_c |= VC4_SET_FIELD(DPI_ORDER_BGR, DPI_ORDER);
+- break;
+- case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
+- dpi_c |= VC4_SET_FIELD(DPI_FORMAT_18BIT_666_RGB_2,
+- DPI_FORMAT);
+- break;
+- case MEDIA_BUS_FMT_RGB666_1X18:
+- dpi_c |= VC4_SET_FIELD(DPI_FORMAT_18BIT_666_RGB_1,
+- DPI_FORMAT);
+- break;
+- case MEDIA_BUS_FMT_RGB565_1X16:
+- dpi_c |= VC4_SET_FIELD(DPI_FORMAT_16BIT_565_RGB_3,
+- DPI_FORMAT);
+- break;
+- default:
+- DRM_ERROR("Unknown media bus format %d\n", bus_format);
+- break;
++ if (connector) {
++ if (connector->display_info.num_bus_formats) {
++ u32 bus_format = connector->display_info.bus_formats[0];
++
++ switch (bus_format) {
++ case MEDIA_BUS_FMT_RGB888_1X24:
++ dpi_c |= VC4_SET_FIELD(DPI_FORMAT_24BIT_888_RGB,
++ DPI_FORMAT);
++ break;
++ case MEDIA_BUS_FMT_BGR888_1X24:
++ dpi_c |= VC4_SET_FIELD(DPI_FORMAT_24BIT_888_RGB,
++ DPI_FORMAT);
++ dpi_c |= VC4_SET_FIELD(DPI_ORDER_BGR,
++ DPI_ORDER);
++ break;
++ case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
++ dpi_c |= VC4_SET_FIELD(DPI_FORMAT_18BIT_666_RGB_2,
++ DPI_FORMAT);
++ break;
++ case MEDIA_BUS_FMT_RGB666_1X18:
++ dpi_c |= VC4_SET_FIELD(DPI_FORMAT_18BIT_666_RGB_1,
++ DPI_FORMAT);
++ break;
++ case MEDIA_BUS_FMT_RGB565_1X16:
++ dpi_c |= VC4_SET_FIELD(DPI_FORMAT_16BIT_565_RGB_3,
++ DPI_FORMAT);
++ break;
++ default:
++ DRM_ERROR("Unknown media bus format %d\n",
++ bus_format);
++ break;
++ }
+ }
++
++ if (connector->display_info.bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE)
++ dpi_c |= DPI_PIXEL_CLK_INVERT;
++
++ if (connector->display_info.bus_flags & DRM_BUS_FLAG_DE_LOW)
++ dpi_c |= DPI_OUTPUT_ENABLE_INVERT;
+ } else {
+ /* Default to 24bit if no connector found. */
+ dpi_c |= VC4_SET_FIELD(DPI_FORMAT_24BIT_888_RGB, DPI_FORMAT);
+--
+2.39.2
+
--- /dev/null
+From e991ed89dcf4305c609c21c1de09240241408f86 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Dec 2022 09:42:52 +0100
+Subject: drm/vc4: dpi: Fix format mapping for RGB565
+
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+
+[ Upstream commit 0870d86eac8a9abd89a0be1b719d5dc5bac936f0 ]
+
+The mapping is incorrect for RGB565_1X16 as it should be
+DPI_FORMAT_18BIT_666_RGB_1 instead of DPI_FORMAT_18BIT_666_RGB_3.
+
+Fixes: 08302c35b59d ("drm/vc4: Add DPI driver")
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Link: https://lore.kernel.org/r/20221013-rpi-dpi-improvements-v3-7-eb76e26a772d@cerno.tech
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_dpi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_dpi.c b/drivers/gpu/drm/vc4/vc4_dpi.c
+index 0e25add2df071..9c8a71d7426a0 100644
+--- a/drivers/gpu/drm/vc4/vc4_dpi.c
++++ b/drivers/gpu/drm/vc4/vc4_dpi.c
+@@ -172,7 +172,7 @@ static void vc4_dpi_encoder_enable(struct drm_encoder *encoder)
+ DPI_FORMAT);
+ break;
+ case MEDIA_BUS_FMT_RGB565_1X16:
+- dpi_c |= VC4_SET_FIELD(DPI_FORMAT_16BIT_565_RGB_3,
++ dpi_c |= VC4_SET_FIELD(DPI_FORMAT_16BIT_565_RGB_1,
+ DPI_FORMAT);
+ break;
+ default:
+--
+2.39.2
+
--- /dev/null
+From 41f65aac08b3409d002d564e187b78b4eb8752ed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Dec 2022 12:53:25 +0100
+Subject: drm/vc4: hdmi: Correct interlaced timings again
+
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+
+[ Upstream commit 771d6539f27bd55f43d8a95d53a7eeaaffa2681c ]
+
+The back porch timings were correct, only the sync offset was wrong.
+Correct timing is now reported for 1080i and 576i, but the h offset is
+incorrect for 480i for non-obvious reasons.
+
+Fixes: fb10dc451c0f ("drm/vc4: hdmi: Correct HDMI timing registers for interlaced modes")
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Link: https://lore.kernel.org/r/20221207-rpi-hvs-crtc-misc-v1-14-1f8e0770798b@cerno.tech
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_hdmi.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
+index 539ebf85fd7c0..7e8620838de9c 100644
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -567,11 +567,12 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
+ VC4_SET_FIELD(mode->crtc_vdisplay, VC5_HDMI_VERTA_VAL));
+ u32 vertb = (VC4_SET_FIELD(mode->htotal >> (2 - pixel_rep),
+ VC5_HDMI_VERTB_VSPO) |
+- VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end,
++ VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end +
++ interlaced,
+ VC4_HDMI_VERTB_VBP));
+ u32 vertb_even = (VC4_SET_FIELD(0, VC5_HDMI_VERTB_VSPO) |
+ VC4_SET_FIELD(mode->crtc_vtotal -
+- mode->crtc_vsync_end - interlaced,
++ mode->crtc_vsync_end,
+ VC4_HDMI_VERTB_VBP));
+
+ HDMI_WRITE(HDMI_VEC_INTERFACE_XBAR, 0x354021);
+--
+2.39.2
+
--- /dev/null
+From 63f009356dfdf8442d76eac06964e8e3d6ab098e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Dec 2022 12:53:17 +0100
+Subject: drm/vc4: hvs: Fix colour order for xRGB1555 on HVS5
+
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+
+[ Upstream commit 902973dc1a049c0d7bf0c222b8f2b3876f01b4a2 ]
+
+Same as the xRGB8888 formats, HVS5 has managed to swap the colour
+channels for the xRGB1555 formats as well. Add the relevant
+config for pixel_order_hvs5.
+
+Fixes: c54619b0bfb3 ("drm/vc4: Add support for the BCM2711 HVS5")
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Link: https://lore.kernel.org/r/20221207-rpi-hvs-crtc-misc-v1-6-1f8e0770798b@cerno.tech
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_plane.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
+index 4df222a830493..2e03c16c60bb1 100644
+--- a/drivers/gpu/drm/vc4/vc4_plane.c
++++ b/drivers/gpu/drm/vc4/vc4_plane.c
+@@ -72,11 +72,13 @@ static const struct hvs_format {
+ .drm = DRM_FORMAT_ARGB1555,
+ .hvs = HVS_PIXEL_FORMAT_RGBA5551,
+ .pixel_order = HVS_PIXEL_ORDER_ABGR,
++ .pixel_order_hvs5 = HVS_PIXEL_ORDER_ARGB,
+ },
+ {
+ .drm = DRM_FORMAT_XRGB1555,
+ .hvs = HVS_PIXEL_FORMAT_RGBA5551,
+ .pixel_order = HVS_PIXEL_ORDER_ABGR,
++ .pixel_order_hvs5 = HVS_PIXEL_ORDER_ARGB,
+ },
+ {
+ .drm = DRM_FORMAT_RGB888,
+--
+2.39.2
+
--- /dev/null
+From c8c7971b03d7fb4fba690c703efdb8317058334c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Dec 2022 12:53:13 +0100
+Subject: drm/vc4: hvs: Set AXI panic modes
+
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+
+[ Upstream commit df993fced230daa8452892406f3180c93ebf7e7b ]
+
+The HVS can change AXI request mode based on how full the COB
+FIFOs are.
+Until now the vc4 driver has been relying on the firmware to
+have set these to sensible values.
+
+With HVS channel 2 now being used for live video, change the
+panic mode for all channels to be explicitly set by the driver,
+and the same for all channels.
+
+Fixes: c54619b0bfb3 ("drm/vc4: Add support for the BCM2711 HVS5")
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Link: https://lore.kernel.org/r/20221207-rpi-hvs-crtc-misc-v1-2-1f8e0770798b@cerno.tech
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_hvs.c | 11 +++++++++++
+ drivers/gpu/drm/vc4/vc4_regs.h | 6 ++++++
+ 2 files changed, 17 insertions(+)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
+index 95fa6fc052a72..f8f2fc3d15f73 100644
+--- a/drivers/gpu/drm/vc4/vc4_hvs.c
++++ b/drivers/gpu/drm/vc4/vc4_hvs.c
+@@ -677,6 +677,17 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data)
+ SCALER_DISPCTRL_DSPEISLUR(2) |
+ SCALER_DISPCTRL_SCLEIRQ);
+
++ /* Set AXI panic mode.
++ * VC4 panics when < 2 lines in FIFO.
++ * VC5 panics when less than 1 line in the FIFO.
++ */
++ dispctrl &= ~(SCALER_DISPCTRL_PANIC0_MASK |
++ SCALER_DISPCTRL_PANIC1_MASK |
++ SCALER_DISPCTRL_PANIC2_MASK);
++ dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC0);
++ dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC1);
++ dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC2);
++
+ HVS_WRITE(SCALER_DISPCTRL, dispctrl);
+
+ ret = devm_request_irq(dev, platform_get_irq(pdev, 0),
+diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h
+index be2c32a519b31..a324ef88ceafb 100644
+--- a/drivers/gpu/drm/vc4/vc4_regs.h
++++ b/drivers/gpu/drm/vc4/vc4_regs.h
+@@ -220,6 +220,12 @@
+ #define SCALER_DISPCTRL 0x00000000
+ /* Global register for clock gating the HVS */
+ # define SCALER_DISPCTRL_ENABLE BIT(31)
++# define SCALER_DISPCTRL_PANIC0_MASK VC4_MASK(25, 24)
++# define SCALER_DISPCTRL_PANIC0_SHIFT 24
++# define SCALER_DISPCTRL_PANIC1_MASK VC4_MASK(27, 26)
++# define SCALER_DISPCTRL_PANIC1_SHIFT 26
++# define SCALER_DISPCTRL_PANIC2_MASK VC4_MASK(29, 28)
++# define SCALER_DISPCTRL_PANIC2_SHIFT 28
+ # define SCALER_DISPCTRL_DSP3_MUX_MASK VC4_MASK(19, 18)
+ # define SCALER_DISPCTRL_DSP3_MUX_SHIFT 18
+
+--
+2.39.2
+
--- /dev/null
+From fa3dbd91e4f7749fc14a264a5f880471e4306c65 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Nov 2022 06:51:56 +0000
+Subject: drm/vkms: Fix null-ptr-deref in vkms_release()
+
+From: Yuan Can <yuancan@huawei.com>
+
+[ Upstream commit 2fe2a8f40c21161ffe7653cc234e7934db5b7cc5 ]
+
+A null-ptr-deref is triggered when it tries to destroy the workqueue in
+vkms->output.composer_workq in vkms_release().
+
+ KASAN: null-ptr-deref in range [0x0000000000000118-0x000000000000011f]
+ CPU: 5 PID: 17193 Comm: modprobe Not tainted 6.0.0-11331-gd465bff130bf #24
+ RIP: 0010:destroy_workqueue+0x2f/0x710
+ ...
+ Call Trace:
+ <TASK>
+ ? vkms_config_debugfs_init+0x50/0x50 [vkms]
+ __devm_drm_dev_alloc+0x15a/0x1c0 [drm]
+ vkms_init+0x245/0x1000 [vkms]
+ do_one_initcall+0xd0/0x4f0
+ do_init_module+0x1a4/0x680
+ load_module+0x6249/0x7110
+ __do_sys_finit_module+0x140/0x200
+ do_syscall_64+0x35/0x80
+ entry_SYSCALL_64_after_hwframe+0x46/0xb0
+
+The reason is that an OOM happened which triggers the destroy of the
+workqueue, however, the workqueue is alloced in the later process,
+thus a null-ptr-deref happened. A simple call graph is shown as below:
+
+ vkms_init()
+ vkms_create()
+ devm_drm_dev_alloc()
+ __devm_drm_dev_alloc()
+ devm_drm_dev_init()
+ devm_add_action_or_reset()
+ devm_add_action() # an error happened
+ devm_drm_dev_init_release()
+ drm_dev_put()
+ kref_put()
+ drm_dev_release()
+ vkms_release()
+ destroy_workqueue() # null-ptr-deref happened
+ vkms_modeset_init()
+ vkms_output_init()
+ vkms_crtc_init() # where the workqueue get allocated
+
+Fix this by checking if composer_workq is NULL before passing it to
+the destroy_workqueue() in vkms_release().
+
+Fixes: 6c234fe37c57 ("drm/vkms: Implement CRC debugfs API")
+Signed-off-by: Yuan Can <yuancan@huawei.com>
+Reviewed-by: Melissa Wen <mwen@igalia.com>
+Signed-off-by: Melissa Wen <melissa.srw@gmail.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20221101065156.41584-3-yuancan@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vkms/vkms_drv.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c
+index cb0b6230c22ce..838428988f79d 100644
+--- a/drivers/gpu/drm/vkms/vkms_drv.c
++++ b/drivers/gpu/drm/vkms/vkms_drv.c
+@@ -61,7 +61,8 @@ static void vkms_release(struct drm_device *dev)
+ {
+ struct vkms_device *vkms = container_of(dev, struct vkms_device, drm);
+
+- destroy_workqueue(vkms->output.composer_workq);
++ if (vkms->output.composer_workq)
++ destroy_workqueue(vkms->output.composer_workq);
+ }
+
+ static void vkms_atomic_commit_tail(struct drm_atomic_state *old_state)
+--
+2.39.2
+
--- /dev/null
+From 5e98394d2ec696b5053828b2fe3ae3c8197e8063 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 19 Nov 2022 17:25:03 +0800
+Subject: genirq: Fix the return type of kstat_cpu_irqs_sum()
+
+From: Zhen Lei <thunder.leizhen@huawei.com>
+
+[ Upstream commit 47904aed898a08f028572b9b5a5cc101ddfb2d82 ]
+
+The type of member ->irqs_sum is unsigned long, but kstat_cpu_irqs_sum()
+returns int, which can result in truncation. Therefore, change the
+kstat_cpu_irqs_sum() function's return value to unsigned long to avoid
+truncation.
+
+Fixes: f2c66cd8eedd ("/proc/stat: scalability of irq num per cpu")
+Reported-by: Elliott, Robert (Servers) <elliott@hpe.com>
+Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
+Cc: Tejun Heo <tj@kernel.org>
+Cc: "Peter Zijlstra (Intel)" <peterz@infradead.org>
+Cc: Josh Don <joshdon@google.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Reviewed-by: Frederic Weisbecker <frederic@kernel.org>
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/kernel_stat.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h
+index 8fff3500d50ee..1160e20995a02 100644
+--- a/include/linux/kernel_stat.h
++++ b/include/linux/kernel_stat.h
+@@ -73,7 +73,7 @@ extern unsigned int kstat_irqs_usr(unsigned int irq);
+ /*
+ * Number of interrupts per cpu, since bootup
+ */
+-static inline unsigned int kstat_cpu_irqs_sum(unsigned int cpu)
++static inline unsigned long kstat_cpu_irqs_sum(unsigned int cpu)
+ {
+ return kstat_cpu(cpu).irqs_sum;
+ }
+--
+2.39.2
+
--- /dev/null
+From a44007ffed3e76c6629d206b17920017accb1a9a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 31 Jan 2023 15:06:53 +0100
+Subject: gfs2: Improve gfs2_make_fs_rw error handling
+
+From: Andreas Gruenbacher <agruenba@redhat.com>
+
+[ Upstream commit b66f723bb552ad59c2acb5d45ea45c890f84498b ]
+
+In gfs2_make_fs_rw(), make sure to call gfs2_consist() to report an
+inconsistency and mark the filesystem as withdrawn when
+gfs2_find_jhead() fails.
+
+At the end of gfs2_make_fs_rw(), when we discover that the filesystem
+has been withdrawn, make sure we report an error. This also replaces
+the gfs2_withdrawn() check after gfs2_find_jhead().
+
+Reported-by: Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>
+Cc: syzbot+f51cb4b9afbd87ec06f2@syzkaller.appspotmail.com
+Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/gfs2/super.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
+index d14b98aa1c3eb..5cb7e771b57ab 100644
+--- a/fs/gfs2/super.c
++++ b/fs/gfs2/super.c
+@@ -145,8 +145,10 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp)
+ return -EIO;
+
+ error = gfs2_find_jhead(sdp->sd_jdesc, &head, false);
+- if (error || gfs2_withdrawn(sdp))
++ if (error) {
++ gfs2_consist(sdp);
+ return error;
++ }
+
+ if (!(head.lh_flags & GFS2_LOG_HEAD_UNMOUNT)) {
+ gfs2_consist(sdp);
+@@ -158,7 +160,9 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp)
+ gfs2_log_pointers_init(sdp, head.lh_blkno);
+
+ error = gfs2_quota_init(sdp);
+- if (!error && !gfs2_withdrawn(sdp))
++ if (!error && gfs2_withdrawn(sdp))
++ error = -EIO;
++ if (!error)
+ set_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags);
+ return error;
+ }
+--
+2.39.2
+
--- /dev/null
+From d30766dbf3ba6ddfe655983449550452692223f2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Feb 2023 15:08:50 +0100
+Subject: gfs2: jdata writepage fix
+
+From: Andreas Gruenbacher <agruenba@redhat.com>
+
+[ Upstream commit cbb60951ce18c9b6e91d2eb97deb41d8ff616622 ]
+
+The ->writepage() and ->writepages() operations are supposed to write
+entire pages. However, on filesystems with a block size smaller than
+PAGE_SIZE, __gfs2_jdata_writepage() only adds the first block to the
+current transaction instead of adding the entire page. Fix that.
+
+Fixes: 18ec7d5c3f43 ("[GFS2] Make journaled data files identical to normal files on disk")
+Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/gfs2/aops.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c
+index cc4f987687f3c..5306595548703 100644
+--- a/fs/gfs2/aops.c
++++ b/fs/gfs2/aops.c
+@@ -152,7 +152,6 @@ static int __gfs2_jdata_writepage(struct page *page, struct writeback_control *w
+ {
+ struct inode *inode = page->mapping->host;
+ struct gfs2_inode *ip = GFS2_I(inode);
+- struct gfs2_sbd *sdp = GFS2_SB(inode);
+
+ if (PageChecked(page)) {
+ ClearPageChecked(page);
+@@ -160,7 +159,7 @@ static int __gfs2_jdata_writepage(struct page *page, struct writeback_control *w
+ create_empty_buffers(page, inode->i_sb->s_blocksize,
+ BIT(BH_Dirty)|BIT(BH_Uptodate));
+ }
+- gfs2_page_add_databufs(ip, page, 0, sdp->sd_vfs->s_blocksize);
++ gfs2_page_add_databufs(ip, page, 0, PAGE_SIZE);
+ }
+ return gfs2_write_jdata_page(page, wbc);
+ }
+--
+2.39.2
+
--- /dev/null
+From 3d362b896bf25949c1a445ddce50f0d8810f3d13 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Dec 2022 17:02:47 +0800
+Subject: gpio: vf610: connect GPIO label to dev name
+
+From: Haibo Chen <haibo.chen@nxp.com>
+
+[ Upstream commit 6f8ecb7f85f441eb7d78ba2a4df45ee8a821934e ]
+
+Current GPIO label is fixed, so can't distinguish different GPIO
+controllers through labels. Use dev name instead.
+
+Fixes: 7f2691a19627 ("gpio: vf610: add gpiolib/IRQ chip driver for Vybrid")
+Signed-off-by: Clark Wang <xiaoning.wang@nxp.com>
+Signed-off-by: Haibo Chen <haibo.chen@nxp.com>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-vf610.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpio/gpio-vf610.c b/drivers/gpio/gpio-vf610.c
+index 1ae612c796eef..396a687e020f5 100644
+--- a/drivers/gpio/gpio-vf610.c
++++ b/drivers/gpio/gpio-vf610.c
+@@ -304,7 +304,7 @@ static int vf610_gpio_probe(struct platform_device *pdev)
+ gc = &port->gc;
+ gc->of_node = np;
+ gc->parent = dev;
+- gc->label = "vf610-gpio";
++ gc->label = dev_name(dev);
+ gc->ngpio = VF610_GPIO_PER_PORT;
+ gc->base = of_alias_get_id(np, "gpio") * VF610_GPIO_PER_PORT;
+
+--
+2.39.2
+
--- /dev/null
+From 36be176925724e04bb537cf2c59232d06c26aabe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 19 Jan 2023 15:39:00 +0200
+Subject: gpu: host1x: Don't skip assigning syncpoints to channels
+
+From: Mikko Perttunen <mperttunen@nvidia.com>
+
+[ Upstream commit eb258cc1fd458e584082be987dbc6ec42668c05e ]
+
+The code to write the syncpoint channel assignment register
+incorrectly skips the write if hypervisor registers are not available.
+
+The register, however, is within the guest aperture so remove the
+check and assign syncpoints properly even on virtualized systems.
+
+Fixes: c3f52220f276 ("gpu: host1x: Enable Tegra186 syncpoint protection")
+Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/host1x/hw/syncpt_hw.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/drivers/gpu/host1x/hw/syncpt_hw.c b/drivers/gpu/host1x/hw/syncpt_hw.c
+index dd39d67ccec36..8cf35b2eff3db 100644
+--- a/drivers/gpu/host1x/hw/syncpt_hw.c
++++ b/drivers/gpu/host1x/hw/syncpt_hw.c
+@@ -106,9 +106,6 @@ static void syncpt_assign_to_channel(struct host1x_syncpt *sp,
+ #if HOST1X_HW >= 6
+ struct host1x *host = sp->host;
+
+- if (!host->hv_regs)
+- return;
+-
+ host1x_sync_writel(host,
+ HOST1X_SYNC_SYNCPT_CH_APP_CH(ch ? ch->id : 0xff),
+ HOST1X_SYNC_SYNCPT_CH_APP(sp->id));
+--
+2.39.2
+
--- /dev/null
+From d6690560b750c1048b2c6f2ad9c2e45402be3516 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Jul 2022 23:22:27 +0800
+Subject: gpu: ipu-v3: common: Add of_node_put() for reference returned by
+ of_graph_get_port_by_id()
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit 9afdf98cfdfa2ba8ec068cf08c5fcdc1ed8daf3f ]
+
+In ipu_add_client_devices(), we need to call of_node_put() for
+reference returned by of_graph_get_port_by_id() in fail path.
+
+Fixes: 17e052175039 ("gpu: ipu-v3: Do not bail out on missing optional port nodes")
+Signed-off-by: Liang He <windhl@126.com>
+Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
+Link: https://lore.kernel.org/r/20220720152227.1288413-1-windhl@126.com
+Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220720152227.1288413-1-windhl@126.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/ipu-v3/ipu-common.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c
+index d166ee262ce43..22dae3f510517 100644
+--- a/drivers/gpu/ipu-v3/ipu-common.c
++++ b/drivers/gpu/ipu-v3/ipu-common.c
+@@ -1168,6 +1168,7 @@ static int ipu_add_client_devices(struct ipu_soc *ipu, unsigned long ipu_base)
+ pdev = platform_device_alloc(reg->name, id++);
+ if (!pdev) {
+ ret = -ENOMEM;
++ of_node_put(of_node);
+ goto err_register;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 9ad8e13251bbad689137eb41a267120e84c7b52f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Dec 2022 22:53:30 +0000
+Subject: HID: Add Mapping for System Microphone Mute
+
+From: Jingyuan Liang <jingyliang@chromium.org>
+
+[ Upstream commit 2d60f9f4f26785a00273cb81fe60eff129ebd449 ]
+
+HUTRR110 added a new usage code for a key that is supposed to
+mute/unmute microphone system-wide.
+
+Map the new usage code(0x01 0xa9) to keycode KEY_MICMUTE.
+Additionally hid-debug is adjusted to recognize this keycode as well.
+
+Signed-off-by: Jingyuan Liang <jingyliang@chromium.org>
+Reviewed-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-debug.c | 1 +
+ drivers/hid/hid-input.c | 8 ++++++++
+ 2 files changed, 9 insertions(+)
+
+diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c
+index f4e2e69377589..1f60a381ae63e 100644
+--- a/drivers/hid/hid-debug.c
++++ b/drivers/hid/hid-debug.c
+@@ -933,6 +933,7 @@ static const char *keys[KEY_MAX + 1] = {
+ [KEY_VOICECOMMAND] = "VoiceCommand",
+ [KEY_EMOJI_PICKER] = "EmojiPicker",
+ [KEY_DICTATE] = "Dictate",
++ [KEY_MICMUTE] = "MicrophoneMute",
+ [KEY_BRIGHTNESS_MIN] = "BrightnessMin",
+ [KEY_BRIGHTNESS_MAX] = "BrightnessMax",
+ [KEY_BRIGHTNESS_AUTO] = "BrightnessAuto",
+diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
+index 75a4d8d6bb0fd..3399953256d85 100644
+--- a/drivers/hid/hid-input.c
++++ b/drivers/hid/hid-input.c
+@@ -675,6 +675,14 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
+ break;
+ }
+
++ if ((usage->hid & 0xf0) == 0xa0) { /* SystemControl */
++ switch (usage->hid & 0xf) {
++ case 0x9: map_key_clear(KEY_MICMUTE); break;
++ default: goto ignore;
++ }
++ break;
++ }
++
+ if ((usage->hid & 0xf0) == 0xb0) { /* SC - Display */
+ switch (usage->hid & 0xf) {
+ case 0x05: map_key_clear(KEY_SWITCHVIDEOMODE); break;
+--
+2.39.2
+
--- /dev/null
+From 1fbc9a692ded3044bdbe91a1328d6be64d313b5b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Feb 2023 18:59:59 +0000
+Subject: HID: bigben: use spinlock to protect concurrent accesses
+
+From: Pietro Borrello <borrello@diag.uniroma1.it>
+
+[ Upstream commit 9fefb6201c4f8dd9f58c581b2a66e5cde2895ea2 ]
+
+bigben driver has a worker that may access data concurrently.
+Proct the accesses using a spinlock.
+
+Fixes: 256a90ed9e46 ("HID: hid-bigbenff: driver for BigBen Interactive PS3OFMINIPAD gamepad")
+Signed-off-by: Pietro Borrello <borrello@diag.uniroma1.it>
+Link: https://lore.kernel.org/r/20230125-hid-unregister-leds-v4-1-7860c5763c38@diag.uniroma1.it
+Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-bigbenff.c | 52 ++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 50 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/hid/hid-bigbenff.c b/drivers/hid/hid-bigbenff.c
+index e8b16665860d6..ed3d2d7bc1dd4 100644
+--- a/drivers/hid/hid-bigbenff.c
++++ b/drivers/hid/hid-bigbenff.c
+@@ -174,6 +174,7 @@ static __u8 pid0902_rdesc_fixed[] = {
+ struct bigben_device {
+ struct hid_device *hid;
+ struct hid_report *report;
++ spinlock_t lock;
+ bool removed;
+ u8 led_state; /* LED1 = 1 .. LED4 = 8 */
+ u8 right_motor_on; /* right motor off/on 0/1 */
+@@ -190,12 +191,27 @@ static void bigben_worker(struct work_struct *work)
+ struct bigben_device *bigben = container_of(work,
+ struct bigben_device, worker);
+ struct hid_field *report_field = bigben->report->field[0];
++ bool do_work_led = false;
++ bool do_work_ff = false;
++ u8 *buf;
++ u32 len;
++ unsigned long flags;
+
+ if (bigben->removed || !report_field)
+ return;
+
++ buf = hid_alloc_report_buf(bigben->report, GFP_KERNEL);
++ if (!buf)
++ return;
++
++ len = hid_report_len(bigben->report);
++
++ /* LED work */
++ spin_lock_irqsave(&bigben->lock, flags);
++
+ if (bigben->work_led) {
+ bigben->work_led = false;
++ do_work_led = true;
+ report_field->value[0] = 0x01; /* 1 = led message */
+ report_field->value[1] = 0x08; /* reserved value, always 8 */
+ report_field->value[2] = bigben->led_state;
+@@ -204,11 +220,22 @@ static void bigben_worker(struct work_struct *work)
+ report_field->value[5] = 0x00; /* padding */
+ report_field->value[6] = 0x00; /* padding */
+ report_field->value[7] = 0x00; /* padding */
+- hid_hw_request(bigben->hid, bigben->report, HID_REQ_SET_REPORT);
++ hid_output_report(bigben->report, buf);
++ }
++
++ spin_unlock_irqrestore(&bigben->lock, flags);
++
++ if (do_work_led) {
++ hid_hw_raw_request(bigben->hid, bigben->report->id, buf, len,
++ bigben->report->type, HID_REQ_SET_REPORT);
+ }
+
++ /* FF work */
++ spin_lock_irqsave(&bigben->lock, flags);
++
+ if (bigben->work_ff) {
+ bigben->work_ff = false;
++ do_work_ff = true;
+ report_field->value[0] = 0x02; /* 2 = rumble effect message */
+ report_field->value[1] = 0x08; /* reserved value, always 8 */
+ report_field->value[2] = bigben->right_motor_on;
+@@ -217,8 +244,17 @@ static void bigben_worker(struct work_struct *work)
+ report_field->value[5] = 0x00; /* padding */
+ report_field->value[6] = 0x00; /* padding */
+ report_field->value[7] = 0x00; /* padding */
+- hid_hw_request(bigben->hid, bigben->report, HID_REQ_SET_REPORT);
++ hid_output_report(bigben->report, buf);
++ }
++
++ spin_unlock_irqrestore(&bigben->lock, flags);
++
++ if (do_work_ff) {
++ hid_hw_raw_request(bigben->hid, bigben->report->id, buf, len,
++ bigben->report->type, HID_REQ_SET_REPORT);
+ }
++
++ kfree(buf);
+ }
+
+ static int hid_bigben_play_effect(struct input_dev *dev, void *data,
+@@ -228,6 +264,7 @@ static int hid_bigben_play_effect(struct input_dev *dev, void *data,
+ struct bigben_device *bigben = hid_get_drvdata(hid);
+ u8 right_motor_on;
+ u8 left_motor_force;
++ unsigned long flags;
+
+ if (!bigben) {
+ hid_err(hid, "no device data\n");
+@@ -242,9 +279,12 @@ static int hid_bigben_play_effect(struct input_dev *dev, void *data,
+
+ if (right_motor_on != bigben->right_motor_on ||
+ left_motor_force != bigben->left_motor_force) {
++ spin_lock_irqsave(&bigben->lock, flags);
+ bigben->right_motor_on = right_motor_on;
+ bigben->left_motor_force = left_motor_force;
+ bigben->work_ff = true;
++ spin_unlock_irqrestore(&bigben->lock, flags);
++
+ schedule_work(&bigben->worker);
+ }
+
+@@ -259,6 +299,7 @@ static void bigben_set_led(struct led_classdev *led,
+ struct bigben_device *bigben = hid_get_drvdata(hid);
+ int n;
+ bool work;
++ unsigned long flags;
+
+ if (!bigben) {
+ hid_err(hid, "no device data\n");
+@@ -267,6 +308,7 @@ static void bigben_set_led(struct led_classdev *led,
+
+ for (n = 0; n < NUM_LEDS; n++) {
+ if (led == bigben->leds[n]) {
++ spin_lock_irqsave(&bigben->lock, flags);
+ if (value == LED_OFF) {
+ work = (bigben->led_state & BIT(n));
+ bigben->led_state &= ~BIT(n);
+@@ -274,6 +316,7 @@ static void bigben_set_led(struct led_classdev *led,
+ work = !(bigben->led_state & BIT(n));
+ bigben->led_state |= BIT(n);
+ }
++ spin_unlock_irqrestore(&bigben->lock, flags);
+
+ if (work) {
+ bigben->work_led = true;
+@@ -307,8 +350,12 @@ static enum led_brightness bigben_get_led(struct led_classdev *led)
+ static void bigben_remove(struct hid_device *hid)
+ {
+ struct bigben_device *bigben = hid_get_drvdata(hid);
++ unsigned long flags;
+
++ spin_lock_irqsave(&bigben->lock, flags);
+ bigben->removed = true;
++ spin_unlock_irqrestore(&bigben->lock, flags);
++
+ cancel_work_sync(&bigben->worker);
+ hid_hw_stop(hid);
+ }
+@@ -362,6 +409,7 @@ static int bigben_probe(struct hid_device *hid,
+ set_bit(FF_RUMBLE, hidinput->input->ffbit);
+
+ INIT_WORK(&bigben->worker, bigben_worker);
++ spin_lock_init(&bigben->lock);
+
+ error = input_ff_create_memless(hidinput->input, NULL,
+ hid_bigben_play_effect);
+--
+2.39.2
+
--- /dev/null
+From be89d90c97abf38376c7b1b8bbce462aedd866c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Feb 2023 19:00:01 +0000
+Subject: HID: bigben: use spinlock to safely schedule workers
+
+From: Pietro Borrello <borrello@diag.uniroma1.it>
+
+[ Upstream commit 76ca8da989c7d97a7f76c75d475fe95a584439d7 ]
+
+Use spinlocks to deal with workers introducing a wrapper
+bigben_schedule_work(), and several spinlock checks.
+Otherwise, bigben_set_led() may schedule bigben->worker after the
+structure has been freed, causing a use-after-free.
+
+Fixes: 4eb1b01de5b9 ("HID: hid-bigbenff: fix race condition for scheduled work during removal")
+Signed-off-by: Pietro Borrello <borrello@diag.uniroma1.it>
+Link: https://lore.kernel.org/r/20230125-hid-unregister-leds-v4-3-7860c5763c38@diag.uniroma1.it
+Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-bigbenff.c | 18 ++++++++++++------
+ 1 file changed, 12 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/hid/hid-bigbenff.c b/drivers/hid/hid-bigbenff.c
+index b98c5f31c184b..9d6560db762b1 100644
+--- a/drivers/hid/hid-bigbenff.c
++++ b/drivers/hid/hid-bigbenff.c
+@@ -185,6 +185,15 @@ struct bigben_device {
+ struct work_struct worker;
+ };
+
++static inline void bigben_schedule_work(struct bigben_device *bigben)
++{
++ unsigned long flags;
++
++ spin_lock_irqsave(&bigben->lock, flags);
++ if (!bigben->removed)
++ schedule_work(&bigben->worker);
++ spin_unlock_irqrestore(&bigben->lock, flags);
++}
+
+ static void bigben_worker(struct work_struct *work)
+ {
+@@ -197,9 +206,6 @@ static void bigben_worker(struct work_struct *work)
+ u32 len;
+ unsigned long flags;
+
+- if (bigben->removed)
+- return;
+-
+ buf = hid_alloc_report_buf(bigben->report, GFP_KERNEL);
+ if (!buf)
+ return;
+@@ -285,7 +291,7 @@ static int hid_bigben_play_effect(struct input_dev *dev, void *data,
+ bigben->work_ff = true;
+ spin_unlock_irqrestore(&bigben->lock, flags);
+
+- schedule_work(&bigben->worker);
++ bigben_schedule_work(bigben);
+ }
+
+ return 0;
+@@ -320,7 +326,7 @@ static void bigben_set_led(struct led_classdev *led,
+
+ if (work) {
+ bigben->work_led = true;
+- schedule_work(&bigben->worker);
++ bigben_schedule_work(bigben);
+ }
+ return;
+ }
+@@ -450,7 +456,7 @@ static int bigben_probe(struct hid_device *hid,
+ bigben->left_motor_force = 0;
+ bigben->work_led = true;
+ bigben->work_ff = true;
+- schedule_work(&bigben->worker);
++ bigben_schedule_work(bigben);
+
+ hid_info(hid, "LED and force feedback support for BigBen gamepad\n");
+
+--
+2.39.2
+
--- /dev/null
+From b1685bb861fac086afda53a5031fd2a14300e8c6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Feb 2023 00:01:44 +0000
+Subject: hid: bigben_probe(): validate report count
+
+From: Pietro Borrello <borrello@diag.uniroma1.it>
+
+[ Upstream commit b94335f899542a0da5fafc38af8edcaf90195843 ]
+
+bigben_probe() does not validate that the output report has the
+needed report values in the first field.
+A malicious device registering a report with one field and a single
+value causes an head OOB write in bigben_worker() when
+accessing report_field->value[1] to report_field->value[7].
+Use hid_validate_values() which takes care of all the needed checks.
+
+Fixes: 256a90ed9e46 ("HID: hid-bigbenff: driver for BigBen Interactive PS3OFMINIPAD gamepad")
+Signed-off-by: Pietro Borrello <borrello@diag.uniroma1.it>
+Link: https://lore.kernel.org/r/20230211-bigben-oob-v1-1-d2849688594c@diag.uniroma1.it
+Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-bigbenff.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/hid/hid-bigbenff.c b/drivers/hid/hid-bigbenff.c
+index 9d6560db762b1..a02cb517b4c47 100644
+--- a/drivers/hid/hid-bigbenff.c
++++ b/drivers/hid/hid-bigbenff.c
+@@ -371,7 +371,6 @@ static int bigben_probe(struct hid_device *hid,
+ {
+ struct bigben_device *bigben;
+ struct hid_input *hidinput;
+- struct list_head *report_list;
+ struct led_classdev *led;
+ char *name;
+ size_t name_sz;
+@@ -396,14 +395,12 @@ static int bigben_probe(struct hid_device *hid,
+ return error;
+ }
+
+- report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
+- if (list_empty(report_list)) {
++ bigben->report = hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 8);
++ if (!bigben->report) {
+ hid_err(hid, "no output report found\n");
+ error = -ENODEV;
+ goto error_hw_stop;
+ }
+- bigben->report = list_entry(report_list->next,
+- struct hid_report, list);
+
+ if (list_empty(&hid->inputs)) {
+ hid_err(hid, "no inputs found\n");
+--
+2.39.2
+
--- /dev/null
+From a5654b408b5a0b510ca910c6d4dfe865108da339 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Feb 2023 19:00:00 +0000
+Subject: HID: bigben_worker() remove unneeded check on report_field
+
+From: Pietro Borrello <borrello@diag.uniroma1.it>
+
+[ Upstream commit 27d2a2fd844ec7da70d19fabb482304fd1e0595b ]
+
+bigben_worker() checks report_field to be non-NULL.
+The check has been added in commit
+918aa1ef104d ("HID: bigbenff: prevent null pointer dereference")
+to prevent a NULL pointer crash.
+However, the true root cause was a missing check for output
+reports, patched in commit
+c7bf714f8755 ("HID: check empty report_list in bigben_probe()"),
+where the type-confused report list_entry was overlapping with
+a NULL pointer, which was then causing the crash.
+
+Fixes: 918aa1ef104d ("HID: bigbenff: prevent null pointer dereference")
+Signed-off-by: Pietro Borrello <borrello@diag.uniroma1.it>
+Link: https://lore.kernel.org/r/20230125-hid-unregister-leds-v4-2-7860c5763c38@diag.uniroma1.it
+Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-bigbenff.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/hid/hid-bigbenff.c b/drivers/hid/hid-bigbenff.c
+index ed3d2d7bc1dd4..b98c5f31c184b 100644
+--- a/drivers/hid/hid-bigbenff.c
++++ b/drivers/hid/hid-bigbenff.c
+@@ -197,7 +197,7 @@ static void bigben_worker(struct work_struct *work)
+ u32 len;
+ unsigned long flags;
+
+- if (bigben->removed || !report_field)
++ if (bigben->removed)
+ return;
+
+ buf = hid_alloc_report_buf(bigben->report, GFP_KERNEL);
+--
+2.39.2
+
--- /dev/null
+From 5da5a1ea408fd12ae7bddbf2de9b24d4b00aa651 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 Jan 2023 13:17:22 +0100
+Subject: HID: logitech-hidpp: Don't restart communication if not necessary
+
+From: Bastien Nocera <hadess@hadess.net>
+
+[ Upstream commit 498ba20690357691103de0f766960355247c78be ]
+
+Don't stop and restart communication with the device unless we need to
+modify the connect flags used because of a device quirk.
+
+Signed-off-by: Bastien Nocera <hadess@hadess.net>
+Link: https://lore.kernel.org/r/20230125121723.3122-1-hadess@hadess.net
+Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-logitech-hidpp.c | 32 ++++++++++++++++++++------------
+ 1 file changed, 20 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
+index 66b1051620390..f5ea8e1d84452 100644
+--- a/drivers/hid/hid-logitech-hidpp.c
++++ b/drivers/hid/hid-logitech-hidpp.c
+@@ -3763,6 +3763,7 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
+ bool connected;
+ unsigned int connect_mask = HID_CONNECT_DEFAULT;
+ struct hidpp_ff_private_data data;
++ bool will_restart = false;
+
+ /* report_fixup needs drvdata to be set before we call hid_parse */
+ hidpp = devm_kzalloc(&hdev->dev, sizeof(*hidpp), GFP_KERNEL);
+@@ -3818,6 +3819,10 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
+ return ret;
+ }
+
++ if (hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT ||
++ hidpp->quirks & HIDPP_QUIRK_UNIFYING)
++ will_restart = true;
++
+ INIT_WORK(&hidpp->work, delayed_work_cb);
+ mutex_init(&hidpp->send_mutex);
+ init_waitqueue_head(&hidpp->wait);
+@@ -3832,7 +3837,7 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
+ * Plain USB connections need to actually call start and open
+ * on the transport driver to allow incoming data.
+ */
+- ret = hid_hw_start(hdev, 0);
++ ret = hid_hw_start(hdev, will_restart ? 0 : connect_mask);
+ if (ret) {
+ hid_err(hdev, "hw start failed\n");
+ goto hid_hw_start_fail;
+@@ -3869,6 +3874,7 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
+ hidpp->wireless_feature_index = 0;
+ else if (ret)
+ goto hid_hw_init_fail;
++ ret = 0;
+ }
+
+ if (connected && (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)) {
+@@ -3883,19 +3889,21 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
+
+ hidpp_connect_event(hidpp);
+
+- /* Reset the HID node state */
+- hid_device_io_stop(hdev);
+- hid_hw_close(hdev);
+- hid_hw_stop(hdev);
++ if (will_restart) {
++ /* Reset the HID node state */
++ hid_device_io_stop(hdev);
++ hid_hw_close(hdev);
++ hid_hw_stop(hdev);
+
+- if (hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT)
+- connect_mask &= ~HID_CONNECT_HIDINPUT;
++ if (hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT)
++ connect_mask &= ~HID_CONNECT_HIDINPUT;
+
+- /* Now export the actual inputs and hidraw nodes to the world */
+- ret = hid_hw_start(hdev, connect_mask);
+- if (ret) {
+- hid_err(hdev, "%s:hid_hw_start returned error\n", __func__);
+- goto hid_hw_start_fail;
++ /* Now export the actual inputs and hidraw nodes to the world */
++ ret = hid_hw_start(hdev, connect_mask);
++ if (ret) {
++ hid_err(hdev, "%s:hid_hw_start returned error\n", __func__);
++ goto hid_hw_start_fail;
++ }
+ }
+
+ if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) {
+--
+2.39.2
+
--- /dev/null
+From 860df3ae099adfafd8a5c5ebc4f3242aaa705e00 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Jan 2023 12:46:20 +0100
+Subject: hwmon: (coretemp) Simplify platform device handling
+
+From: Robin Murphy <robin.murphy@arm.com>
+
+[ Upstream commit 6d03bbff456befeccdd4d663177c4d6c75d0c4ff ]
+
+Coretemp's platform driver is unconventional. All the real work is done
+globally by the initcall and CPU hotplug notifiers, while the "driver"
+effectively just wraps an allocation and the registration of the hwmon
+interface in a long-winded round-trip through the driver core. The whole
+logic of dynamically creating and destroying platform devices to bring
+the interfaces up and down is error prone, since it assumes
+platform_device_add() will synchronously bind the driver and set drvdata
+before it returns, thus results in a NULL dereference if drivers_autoprobe
+is turned off for the platform bus. Furthermore, the unusual approach of
+doing that from within a CPU hotplug notifier, already commented in the
+code that it deadlocks suspend, also causes lockdep issues for other
+drivers or subsystems which may want to legitimately register a CPU
+hotplug notifier from a platform bus notifier.
+
+All of these issues can be solved by ripping this unusual behaviour out
+completely, simply tying the platform devices to the lifetime of the
+module itself, and directly managing the hwmon interfaces from the
+hotplug notifiers. There is a slight user-visible change in that
+/sys/bus/platform/drivers/coretemp will no longer appear, and
+/sys/devices/platform/coretemp.n will remain present if package n is
+hotplugged off, but hwmon users should really only be looking for the
+presence of the hwmon interfaces, whose behaviour remains unchanged.
+
+Link: https://lore.kernel.org/lkml/20220922101036.87457-1-janusz.krzysztofik@linux.intel.com/
+Link: https://gitlab.freedesktop.org/drm/intel/issues/6641
+Signed-off-by: Robin Murphy <robin.murphy@arm.com>
+Signed-off-by: Janusz Krzysztofik <janusz.krzysztofik@linux.intel.com>
+Link: https://lore.kernel.org/r/20230103114620.15319-1-janusz.krzysztofik@linux.intel.com
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/coretemp.c | 128 ++++++++++++++++++---------------------
+ 1 file changed, 58 insertions(+), 70 deletions(-)
+
+diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
+index 42b84ebff0579..eaae5de2ab616 100644
+--- a/drivers/hwmon/coretemp.c
++++ b/drivers/hwmon/coretemp.c
+@@ -550,66 +550,49 @@ static void coretemp_remove_core(struct platform_data *pdata, int indx)
+ ida_free(&pdata->ida, indx - BASE_SYSFS_ATTR_NO);
+ }
+
+-static int coretemp_probe(struct platform_device *pdev)
++static int coretemp_device_add(int zoneid)
+ {
+- struct device *dev = &pdev->dev;
++ struct platform_device *pdev;
+ struct platform_data *pdata;
++ int err;
+
+ /* Initialize the per-zone data structures */
+- pdata = devm_kzalloc(dev, sizeof(struct platform_data), GFP_KERNEL);
++ pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+
+- pdata->pkg_id = pdev->id;
++ pdata->pkg_id = zoneid;
+ ida_init(&pdata->ida);
+- platform_set_drvdata(pdev, pdata);
+
+- pdata->hwmon_dev = devm_hwmon_device_register_with_groups(dev, DRVNAME,
+- pdata, NULL);
+- return PTR_ERR_OR_ZERO(pdata->hwmon_dev);
+-}
+-
+-static int coretemp_remove(struct platform_device *pdev)
+-{
+- struct platform_data *pdata = platform_get_drvdata(pdev);
+- int i;
++ pdev = platform_device_alloc(DRVNAME, zoneid);
++ if (!pdev) {
++ err = -ENOMEM;
++ goto err_free_pdata;
++ }
+
+- for (i = MAX_CORE_DATA - 1; i >= 0; --i)
+- if (pdata->core_data[i])
+- coretemp_remove_core(pdata, i);
++ err = platform_device_add(pdev);
++ if (err)
++ goto err_put_dev;
+
+- ida_destroy(&pdata->ida);
++ platform_set_drvdata(pdev, pdata);
++ zone_devices[zoneid] = pdev;
+ return 0;
+-}
+
+-static struct platform_driver coretemp_driver = {
+- .driver = {
+- .name = DRVNAME,
+- },
+- .probe = coretemp_probe,
+- .remove = coretemp_remove,
+-};
++err_put_dev:
++ platform_device_put(pdev);
++err_free_pdata:
++ kfree(pdata);
++ return err;
++}
+
+-static struct platform_device *coretemp_device_add(unsigned int cpu)
++static void coretemp_device_remove(int zoneid)
+ {
+- int err, zoneid = topology_logical_die_id(cpu);
+- struct platform_device *pdev;
+-
+- if (zoneid < 0)
+- return ERR_PTR(-ENOMEM);
+-
+- pdev = platform_device_alloc(DRVNAME, zoneid);
+- if (!pdev)
+- return ERR_PTR(-ENOMEM);
+-
+- err = platform_device_add(pdev);
+- if (err) {
+- platform_device_put(pdev);
+- return ERR_PTR(err);
+- }
++ struct platform_device *pdev = zone_devices[zoneid];
++ struct platform_data *pdata = platform_get_drvdata(pdev);
+
+- zone_devices[zoneid] = pdev;
+- return pdev;
++ ida_destroy(&pdata->ida);
++ kfree(pdata);
++ platform_device_unregister(pdev);
+ }
+
+ static int coretemp_cpu_online(unsigned int cpu)
+@@ -633,7 +616,10 @@ static int coretemp_cpu_online(unsigned int cpu)
+ if (!cpu_has(c, X86_FEATURE_DTHERM))
+ return -ENODEV;
+
+- if (!pdev) {
++ pdata = platform_get_drvdata(pdev);
++ if (!pdata->hwmon_dev) {
++ struct device *hwmon;
++
+ /* Check the microcode version of the CPU */
+ if (chk_ucode_version(cpu))
+ return -EINVAL;
+@@ -644,9 +630,11 @@ static int coretemp_cpu_online(unsigned int cpu)
+ * online. So, initialize per-pkg data structures and
+ * then bring this core online.
+ */
+- pdev = coretemp_device_add(cpu);
+- if (IS_ERR(pdev))
+- return PTR_ERR(pdev);
++ hwmon = hwmon_device_register_with_groups(&pdev->dev, DRVNAME,
++ pdata, NULL);
++ if (IS_ERR(hwmon))
++ return PTR_ERR(hwmon);
++ pdata->hwmon_dev = hwmon;
+
+ /*
+ * Check whether pkgtemp support is available.
+@@ -656,7 +644,6 @@ static int coretemp_cpu_online(unsigned int cpu)
+ coretemp_add_core(pdev, cpu, 1);
+ }
+
+- pdata = platform_get_drvdata(pdev);
+ /*
+ * Check whether a thread sibling is already online. If not add the
+ * interface for this CPU core.
+@@ -675,18 +662,14 @@ static int coretemp_cpu_offline(unsigned int cpu)
+ struct temp_data *tdata;
+ int i, indx = -1, target;
+
+- /*
+- * Don't execute this on suspend as the device remove locks
+- * up the machine.
+- */
++ /* No need to tear down any interfaces for suspend */
+ if (cpuhp_tasks_frozen)
+ return 0;
+
+ /* If the physical CPU device does not exist, just return */
+- if (!pdev)
+- return 0;
+-
+ pd = platform_get_drvdata(pdev);
++ if (!pd->hwmon_dev)
++ return 0;
+
+ for (i = 0; i < NUM_REAL_CORES; i++) {
+ if (pd->cpu_map[i] == topology_core_id(cpu)) {
+@@ -718,13 +701,14 @@ static int coretemp_cpu_offline(unsigned int cpu)
+ }
+
+ /*
+- * If all cores in this pkg are offline, remove the device. This
+- * will invoke the platform driver remove function, which cleans up
+- * the rest.
++ * If all cores in this pkg are offline, remove the interface.
+ */
++ tdata = pd->core_data[PKG_SYSFS_ATTR_NO];
+ if (cpumask_empty(&pd->cpumask)) {
+- zone_devices[topology_logical_die_id(cpu)] = NULL;
+- platform_device_unregister(pdev);
++ if (tdata)
++ coretemp_remove_core(pd, PKG_SYSFS_ATTR_NO);
++ hwmon_device_unregister(pd->hwmon_dev);
++ pd->hwmon_dev = NULL;
+ return 0;
+ }
+
+@@ -732,7 +716,6 @@ static int coretemp_cpu_offline(unsigned int cpu)
+ * Check whether this core is the target for the package
+ * interface. We need to assign it to some other cpu.
+ */
+- tdata = pd->core_data[PKG_SYSFS_ATTR_NO];
+ if (tdata && tdata->cpu == cpu) {
+ target = cpumask_first(&pd->cpumask);
+ mutex_lock(&tdata->update_lock);
+@@ -751,7 +734,7 @@ static enum cpuhp_state coretemp_hp_online;
+
+ static int __init coretemp_init(void)
+ {
+- int err;
++ int i, err;
+
+ /*
+ * CPUID.06H.EAX[0] indicates whether the CPU has thermal
+@@ -767,20 +750,22 @@ static int __init coretemp_init(void)
+ if (!zone_devices)
+ return -ENOMEM;
+
+- err = platform_driver_register(&coretemp_driver);
+- if (err)
+- goto outzone;
++ for (i = 0; i < max_zones; i++) {
++ err = coretemp_device_add(i);
++ if (err)
++ goto outzone;
++ }
+
+ err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "hwmon/coretemp:online",
+ coretemp_cpu_online, coretemp_cpu_offline);
+ if (err < 0)
+- goto outdrv;
++ goto outzone;
+ coretemp_hp_online = err;
+ return 0;
+
+-outdrv:
+- platform_driver_unregister(&coretemp_driver);
+ outzone:
++ while (i--)
++ coretemp_device_remove(i);
+ kfree(zone_devices);
+ return err;
+ }
+@@ -788,8 +773,11 @@ module_init(coretemp_init)
+
+ static void __exit coretemp_exit(void)
+ {
++ int i;
++
+ cpuhp_remove_state(coretemp_hp_online);
+- platform_driver_unregister(&coretemp_driver);
++ for (i = 0; i < max_zones; i++)
++ coretemp_device_remove(i);
+ kfree(zone_devices);
+ }
+ module_exit(coretemp_exit)
+--
+2.39.2
+
--- /dev/null
+From 231c32df77c59682cdf420e482454a3cb4be95c1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 Jan 2023 17:32:25 -0500
+Subject: hwmon: (ltc2945) Handle error case in ltc2945_value_store
+
+From: Jonathan Cormier <jcormier@criticallink.com>
+
+[ Upstream commit 178b01eccfb0b8149682f61388400bd3d903dddc ]
+
+ltc2945_val_to_reg errors were not being handled
+which would have resulted in register being set to
+0 (clamped) instead of being left alone.
+
+Fixes: 6700ce035f83 ("hwmon: Driver for Linear Technologies LTC2945")
+
+Signed-off-by: Jonathan Cormier <jcormier@criticallink.com>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/ltc2945.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/hwmon/ltc2945.c b/drivers/hwmon/ltc2945.c
+index ba9c868a8641e..65d792f184255 100644
+--- a/drivers/hwmon/ltc2945.c
++++ b/drivers/hwmon/ltc2945.c
+@@ -248,6 +248,8 @@ static ssize_t ltc2945_value_store(struct device *dev,
+
+ /* convert to register value, then clamp and write result */
+ regval = ltc2945_val_to_reg(dev, reg, val);
++ if (regval < 0)
++ return regval;
+ if (is_power_reg(reg)) {
+ regval = clamp_val(regval, 0, 0xffffff);
+ regbuf[0] = regval >> 16;
+--
+2.39.2
+
--- /dev/null
+From e78e1f1df60705e60ee48e435f4fd6721032d8c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Feb 2023 16:57:30 +0200
+Subject: hwmon: (mlxreg-fan) Return zero speed for broken fan
+
+From: Vadim Pasternak <vadimp@nvidia.com>
+
+[ Upstream commit a1ffd3c46267ee5c807acd780e15df9bb692223f ]
+
+Currently for broken fan driver returns value calculated based on error
+code (0xFF) in related fan speed register.
+Thus, for such fan user gets fan{n}_fault to 1 and fan{n}_input with
+misleading value.
+
+Add check for fan fault prior return speed value and return zero if
+fault is detected.
+
+Fixes: 65afb4c8e7e4 ("hwmon: (mlxreg-fan) Add support for Mellanox FAN driver")
+Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
+Link: https://lore.kernel.org/r/20230212145730.24247-1-vadimp@nvidia.com
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/mlxreg-fan.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/hwmon/mlxreg-fan.c b/drivers/hwmon/mlxreg-fan.c
+index bd8f5a3aaad9c..052c897a635d5 100644
+--- a/drivers/hwmon/mlxreg-fan.c
++++ b/drivers/hwmon/mlxreg-fan.c
+@@ -127,6 +127,12 @@ mlxreg_fan_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
+ if (err)
+ return err;
+
++ if (MLXREG_FAN_GET_FAULT(regval, tacho->mask)) {
++ /* FAN is broken - return zero for FAN speed. */
++ *val = 0;
++ return 0;
++ }
++
+ *val = MLXREG_FAN_GET_RPM(regval, fan->divider,
+ fan->samples);
+ break;
+--
+2.39.2
+
--- /dev/null
+From e8b74743f0f70dc8f6a28b90fb9d1e6903877bfb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Dec 2022 16:01:31 -0800
+Subject: ice: add missing checks for PF vsi type
+
+From: Jesse Brandeburg <jesse.brandeburg@intel.com>
+
+[ Upstream commit 6a8d013e904ad9a66706fcc926ec9993bed7d190 ]
+
+There were a few places we had missed checking the VSI type to make sure
+it was definitely a PF VSI, before calling setup functions intended only
+for the PF VSI.
+
+This doesn't fix any explicit bugs but cleans up the code in a few
+places and removes one explicit != vsi->type check that can be
+superseded by this code (it's a super set)
+
+Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
+Tested-by: Gurucharan G <gurucharanx.g@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 | 17 ++++++++---------
+ 1 file changed, 8 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
+index c1465096239b6..4f0d63fa5709b 100644
+--- a/drivers/net/ethernet/intel/ice/ice_main.c
++++ b/drivers/net/ethernet/intel/ice/ice_main.c
+@@ -5200,15 +5200,12 @@ int ice_vsi_cfg(struct ice_vsi *vsi)
+ {
+ int err;
+
+- if (vsi->netdev) {
++ if (vsi->netdev && vsi->type == ICE_VSI_PF) {
+ ice_set_rx_mode(vsi->netdev);
+
+- if (vsi->type != ICE_VSI_LB) {
+- err = ice_vsi_vlan_setup(vsi);
+-
+- if (err)
+- return err;
+- }
++ err = ice_vsi_vlan_setup(vsi);
++ if (err)
++ return err;
+ }
+ ice_vsi_cfg_dcb_rings(vsi);
+
+@@ -5267,7 +5264,7 @@ static int ice_up_complete(struct ice_vsi *vsi)
+
+ if (vsi->port_info &&
+ (vsi->port_info->phy.link_info.link_info & ICE_AQ_LINK_UP) &&
+- vsi->netdev) {
++ vsi->netdev && vsi->type == ICE_VSI_PF) {
+ ice_print_link_msg(vsi, true);
+ netif_tx_start_all_queues(vsi->netdev);
+ netif_carrier_on(vsi->netdev);
+@@ -5277,7 +5274,9 @@ static int ice_up_complete(struct ice_vsi *vsi)
+ * set the baseline so counters are ready when interface is up
+ */
+ ice_update_eth_stats(vsi);
+- ice_service_task_schedule(pf);
++
++ if (vsi->type == ICE_VSI_PF)
++ ice_service_task_schedule(pf);
+
+ return 0;
+ }
+--
+2.39.2
+
--- /dev/null
+From 854bc76adc7c545dff4fdbb9021ed1f080c7c866 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 14 Jan 2023 13:11:41 +0000
+Subject: inet: fix fast path in __inet_hash_connect()
+
+From: Pietro Borrello <borrello@diag.uniroma1.it>
+
+[ Upstream commit 21cbd90a6fab7123905386985e3e4a80236b8714 ]
+
+__inet_hash_connect() has a fast path taken if sk_head(&tb->owners) is
+equal to the sk parameter.
+sk_head() returns the hlist_entry() with respect to the sk_node field.
+However entries in the tb->owners list are inserted with respect to the
+sk_bind_node field with sk_add_bind_node().
+Thus the check would never pass and the fast path never execute.
+
+This fast path has never been executed or tested as this bug seems
+to be present since commit 1da177e4c3f4 ("Linux-2.6.12-rc2"), thus
+remove it to reduce code complexity.
+
+Signed-off-by: Pietro Borrello <borrello@diag.uniroma1.it>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://lore.kernel.org/r/20230112-inet_hash_connect_bind_head-v3-1-b591fd212b93@diag.uniroma1.it
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/inet_hashtables.c | 12 +-----------
+ 1 file changed, 1 insertion(+), 11 deletions(-)
+
+diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
+index 2615b72118d1f..79bf550c9dfc5 100644
+--- a/net/ipv4/inet_hashtables.c
++++ b/net/ipv4/inet_hashtables.c
+@@ -760,17 +760,7 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
+ u32 index;
+
+ if (port) {
+- head = &hinfo->bhash[inet_bhashfn(net, port,
+- hinfo->bhash_size)];
+- tb = inet_csk(sk)->icsk_bind_hash;
+- spin_lock_bh(&head->lock);
+- if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) {
+- inet_ehash_nolisten(sk, NULL, NULL);
+- spin_unlock_bh(&head->lock);
+- return 0;
+- }
+- spin_unlock(&head->lock);
+- /* No definite answer... Walk to established hash table */
++ local_bh_disable();
+ ret = check_established(death_row, sk, port, NULL);
+ local_bh_enable();
+ return ret;
+--
+2.39.2
+
--- /dev/null
+From a80e20b5a70f5f94d3747f62848817b29a4b164a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 Jan 2023 11:52:26 +0100
+Subject: Input: ads7846 - always set last command to PWRDOWN
+
+From: Luca Ellero <l.ellero@asem.it>
+
+[ Upstream commit 13f82ca3878db8284a70ef9711d7f710a31eb562 ]
+
+Controllers that report pressure (e.g. ADS7846) use 5 commands and the
+correct sequence is READ_X, READ_Y, READ_Z1, READ_Z2, PWRDOWN.
+
+Controllers that don't report pressure (e.g. ADS7845/ADS7843) use only 3
+commands and the correct sequence should be READ_X, READ_Y, PWRDOWN. But
+the sequence sent was incorrect: READ_X, READ_Y, READ_Z1.
+
+Fix this by setting the third (and last) command to PWRDOWN.
+
+Fixes: ffa458c1bd9b ("spi: ads7846 driver")
+Signed-off-by: Luca Ellero <l.ellero@asem.it>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://lore.kernel.org/r/20230126105227.47648-3-l.ellero@asem.it
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/input/touchscreen/ads7846.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
+index 0610fab5ed93b..9f5cc42a567a5 100644
+--- a/drivers/input/touchscreen/ads7846.c
++++ b/drivers/input/touchscreen/ads7846.c
+@@ -1075,6 +1075,9 @@ static int ads7846_setup_spi_msg(struct ads7846 *ts,
+ struct ads7846_buf_layout *l = &packet->l[cmd_idx];
+ unsigned int max_count;
+
++ if (cmd_idx == packet->cmds - 1)
++ cmd_idx = ADS7846_PWDOWN;
++
+ if (ads7846_cmd_need_settle(cmd_idx))
+ max_count = packet->count + packet->count_skip;
+ else
+@@ -1111,7 +1114,12 @@ static int ads7846_setup_spi_msg(struct ads7846 *ts,
+
+ for (cmd_idx = 0; cmd_idx < packet->cmds; cmd_idx++) {
+ struct ads7846_buf_layout *l = &packet->l[cmd_idx];
+- u8 cmd = ads7846_get_cmd(cmd_idx, vref);
++ u8 cmd;
++
++ if (cmd_idx == packet->cmds - 1)
++ cmd_idx = ADS7846_PWDOWN;
++
++ cmd = ads7846_get_cmd(cmd_idx, vref);
+
+ for (b = 0; b < l->count; b++)
+ packet->tx[l->offset + b].cmd = cmd;
+--
+2.39.2
+
--- /dev/null
+From c169cab794f1676be06036a309c62a9dc4cffa65 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Nov 2020 16:39:05 -0800
+Subject: Input: ads7846 - convert to full duplex
+
+From: Oleksij Rempel <o.rempel@pengutronix.de>
+
+[ Upstream commit 9c9509717b53e701469493a8d87ed42c7d782502 ]
+
+Starting with 3eac5c7e44f3 ("Input: ads7846 - extend the driver for ads7845
+controller support"), the ads7845 was partially converted to full duplex
+mode.
+
+Since it is not touchscreen controller specific, it is better to extend
+this conversion to cover entire driver. This will reduce CPU load and make
+driver more readable.
+
+Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Link: https://lore.kernel.org/r/20201110085041.16303-2-o.rempel@pengutronix.de
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Stable-dep-of: 13f82ca3878d ("Input: ads7846 - always set last command to PWRDOWN")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/input/touchscreen/ads7846.c | 192 +++++++++-------------------
+ 1 file changed, 62 insertions(+), 130 deletions(-)
+
+diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
+index 370e0dbc02dea..04ca0e13acd39 100644
+--- a/drivers/input/touchscreen/ads7846.c
++++ b/drivers/input/touchscreen/ads7846.c
+@@ -63,19 +63,26 @@
+ /* this driver doesn't aim at the peak continuous sample rate */
+ #define SAMPLE_BITS (8 /*cmd*/ + 16 /*sample*/ + 2 /* before, after */)
+
+-struct ts_event {
++struct ads7846_buf {
++ u8 cmd;
+ /*
+- * For portability, we can't read 12 bit values using SPI (which
+- * would make the controller deliver them as native byte order u16
+- * with msbs zeroed). Instead, we read them as two 8-bit values,
+- * *** WHICH NEED BYTESWAPPING *** and range adjustment.
++ * This union is a temporary hack. The driver does an in-place
++ * endianness conversion. This will be cleaned up in the next
++ * patch.
+ */
+- u16 x;
+- u16 y;
+- u16 z1, z2;
+- bool ignore;
+- u8 x_buf[3];
+- u8 y_buf[3];
++ union {
++ __be16 data_be16;
++ u16 data;
++ };
++} __packed;
++
++
++struct ts_event {
++ bool ignore;
++ struct ads7846_buf x;
++ struct ads7846_buf y;
++ struct ads7846_buf z1;
++ struct ads7846_buf z2;
+ };
+
+ /*
+@@ -84,11 +91,12 @@ struct ts_event {
+ * systems where main memory is not DMA-coherent (most non-x86 boards).
+ */
+ struct ads7846_packet {
+- u8 read_x, read_y, read_z1, read_z2, pwrdown;
+- u16 dummy; /* for the pwrdown read */
+- struct ts_event tc;
+- /* for ads7845 with mpc5121 psc spi we use 3-byte buffers */
+- u8 read_x_cmd[3], read_y_cmd[3], pwrdown_cmd[3];
++ struct ts_event tc;
++ struct ads7846_buf read_x_cmd;
++ struct ads7846_buf read_y_cmd;
++ struct ads7846_buf read_z1_cmd;
++ struct ads7846_buf read_z2_cmd;
++ struct ads7846_buf pwrdown_cmd;
+ };
+
+ struct ads7846 {
+@@ -687,16 +695,9 @@ static int ads7846_get_value(struct ads7846 *ts, struct spi_message *m)
+ int value;
+ struct spi_transfer *t =
+ list_entry(m->transfers.prev, struct spi_transfer, transfer_list);
++ struct ads7846_buf *buf = t->rx_buf;
+
+- if (ts->model == 7845) {
+- value = be16_to_cpup((__be16 *)&(((char *)t->rx_buf)[1]));
+- } else {
+- /*
+- * adjust: on-wire is a must-ignore bit, a BE12 value, then
+- * padding; built from two 8 bit values written msb-first.
+- */
+- value = be16_to_cpup((__be16 *)t->rx_buf);
+- }
++ value = be16_to_cpup(&buf->data_be16);
+
+ /* enforce ADC output is 12 bits width */
+ return (value >> 3) & 0xfff;
+@@ -706,8 +707,9 @@ static void ads7846_update_value(struct spi_message *m, int val)
+ {
+ struct spi_transfer *t =
+ list_entry(m->transfers.prev, struct spi_transfer, transfer_list);
++ struct ads7846_buf *buf = t->rx_buf;
+
+- *(u16 *)t->rx_buf = val;
++ buf->data = val;
+ }
+
+ static void ads7846_read_state(struct ads7846 *ts)
+@@ -775,16 +777,14 @@ static void ads7846_report_state(struct ads7846 *ts)
+ * from on-the-wire format as part of debouncing to get stable
+ * readings.
+ */
++ x = packet->tc.x.data;
++ y = packet->tc.y.data;
+ if (ts->model == 7845) {
+- x = *(u16 *)packet->tc.x_buf;
+- y = *(u16 *)packet->tc.y_buf;
+ z1 = 0;
+ z2 = 0;
+ } else {
+- x = packet->tc.x;
+- y = packet->tc.y;
+- z1 = packet->tc.z1;
+- z2 = packet->tc.z2;
++ z1 = packet->tc.z1.data;
++ z2 = packet->tc.z2.data;
+ }
+
+ /* range filtering */
+@@ -1002,26 +1002,11 @@ static void ads7846_setup_spi_msg(struct ads7846 *ts,
+ spi_message_init(m);
+ m->context = ts;
+
+- if (ts->model == 7845) {
+- packet->read_y_cmd[0] = READ_Y(vref);
+- packet->read_y_cmd[1] = 0;
+- packet->read_y_cmd[2] = 0;
+- x->tx_buf = &packet->read_y_cmd[0];
+- x->rx_buf = &packet->tc.y_buf[0];
+- x->len = 3;
+- spi_message_add_tail(x, m);
+- } else {
+- /* y- still on; turn on only y+ (and ADC) */
+- packet->read_y = READ_Y(vref);
+- x->tx_buf = &packet->read_y;
+- x->len = 1;
+- spi_message_add_tail(x, m);
+-
+- x++;
+- x->rx_buf = &packet->tc.y;
+- x->len = 2;
+- spi_message_add_tail(x, m);
+- }
++ packet->read_y_cmd.cmd = READ_Y(vref);
++ x->tx_buf = &packet->read_y_cmd;
++ x->rx_buf = &packet->tc.y;
++ x->len = 3;
++ spi_message_add_tail(x, m);
+
+ /*
+ * The first sample after switching drivers can be low quality;
+@@ -1031,15 +1016,11 @@ static void ads7846_setup_spi_msg(struct ads7846 *ts,
+ if (pdata->settle_delay_usecs) {
+ x->delay.value = pdata->settle_delay_usecs;
+ x->delay.unit = SPI_DELAY_UNIT_USECS;
+-
+ x++;
+- x->tx_buf = &packet->read_y;
+- x->len = 1;
+- spi_message_add_tail(x, m);
+
+- x++;
++ x->tx_buf = &packet->read_y_cmd;
+ x->rx_buf = &packet->tc.y;
+- x->len = 2;
++ x->len = 3;
+ spi_message_add_tail(x, m);
+ }
+
+@@ -1048,28 +1029,13 @@ static void ads7846_setup_spi_msg(struct ads7846 *ts,
+ spi_message_init(m);
+ m->context = ts;
+
+- if (ts->model == 7845) {
+- x++;
+- packet->read_x_cmd[0] = READ_X(vref);
+- packet->read_x_cmd[1] = 0;
+- packet->read_x_cmd[2] = 0;
+- x->tx_buf = &packet->read_x_cmd[0];
+- x->rx_buf = &packet->tc.x_buf[0];
+- x->len = 3;
+- spi_message_add_tail(x, m);
+- } else {
+- /* turn y- off, x+ on, then leave in lowpower */
+- x++;
+- packet->read_x = READ_X(vref);
+- x->tx_buf = &packet->read_x;
+- x->len = 1;
+- spi_message_add_tail(x, m);
+-
+- x++;
+- x->rx_buf = &packet->tc.x;
+- x->len = 2;
+- spi_message_add_tail(x, m);
+- }
++ /* turn y- off, x+ on, then leave in lowpower */
++ x++;
++ packet->read_x_cmd.cmd = READ_X(vref);
++ x->tx_buf = &packet->read_x_cmd;
++ x->rx_buf = &packet->tc.x;
++ x->len = 3;
++ spi_message_add_tail(x, m);
+
+ /* ... maybe discard first sample ... */
+ if (pdata->settle_delay_usecs) {
+@@ -1077,13 +1043,9 @@ static void ads7846_setup_spi_msg(struct ads7846 *ts,
+ x->delay.unit = SPI_DELAY_UNIT_USECS;
+
+ x++;
+- x->tx_buf = &packet->read_x;
+- x->len = 1;
+- spi_message_add_tail(x, m);
+-
+- x++;
++ x->tx_buf = &packet->read_x_cmd;
+ x->rx_buf = &packet->tc.x;
+- x->len = 2;
++ x->len = 3;
+ spi_message_add_tail(x, m);
+ }
+
+@@ -1095,14 +1057,10 @@ static void ads7846_setup_spi_msg(struct ads7846 *ts,
+ m->context = ts;
+
+ x++;
+- packet->read_z1 = READ_Z1(vref);
+- x->tx_buf = &packet->read_z1;
+- x->len = 1;
+- spi_message_add_tail(x, m);
+-
+- x++;
++ packet->read_z1_cmd.cmd = READ_Z1(vref);
++ x->tx_buf = &packet->read_z1_cmd;
+ x->rx_buf = &packet->tc.z1;
+- x->len = 2;
++ x->len = 3;
+ spi_message_add_tail(x, m);
+
+ /* ... maybe discard first sample ... */
+@@ -1111,13 +1069,9 @@ static void ads7846_setup_spi_msg(struct ads7846 *ts,
+ x->delay.unit = SPI_DELAY_UNIT_USECS;
+
+ x++;
+- x->tx_buf = &packet->read_z1;
+- x->len = 1;
+- spi_message_add_tail(x, m);
+-
+- x++;
++ x->tx_buf = &packet->read_z1_cmd;
+ x->rx_buf = &packet->tc.z1;
+- x->len = 2;
++ x->len = 3;
+ spi_message_add_tail(x, m);
+ }
+
+@@ -1127,14 +1081,10 @@ static void ads7846_setup_spi_msg(struct ads7846 *ts,
+ m->context = ts;
+
+ x++;
+- packet->read_z2 = READ_Z2(vref);
+- x->tx_buf = &packet->read_z2;
+- x->len = 1;
+- spi_message_add_tail(x, m);
+-
+- x++;
++ packet->read_z2_cmd.cmd = READ_Z2(vref);
++ x->tx_buf = &packet->read_z2_cmd;
+ x->rx_buf = &packet->tc.z2;
+- x->len = 2;
++ x->len = 3;
+ spi_message_add_tail(x, m);
+
+ /* ... maybe discard first sample ... */
+@@ -1143,13 +1093,9 @@ static void ads7846_setup_spi_msg(struct ads7846 *ts,
+ x->delay.unit = SPI_DELAY_UNIT_USECS;
+
+ x++;
+- x->tx_buf = &packet->read_z2;
+- x->len = 1;
+- spi_message_add_tail(x, m);
+-
+- x++;
++ x->tx_buf = &packet->read_z2_cmd;
+ x->rx_buf = &packet->tc.z2;
+- x->len = 2;
++ x->len = 3;
+ spi_message_add_tail(x, m);
+ }
+ }
+@@ -1160,24 +1106,10 @@ static void ads7846_setup_spi_msg(struct ads7846 *ts,
+ spi_message_init(m);
+ m->context = ts;
+
+- if (ts->model == 7845) {
+- x++;
+- packet->pwrdown_cmd[0] = PWRDOWN;
+- packet->pwrdown_cmd[1] = 0;
+- packet->pwrdown_cmd[2] = 0;
+- x->tx_buf = &packet->pwrdown_cmd[0];
+- x->len = 3;
+- } else {
+- x++;
+- packet->pwrdown = PWRDOWN;
+- x->tx_buf = &packet->pwrdown;
+- x->len = 1;
+- spi_message_add_tail(x, m);
+-
+- x++;
+- x->rx_buf = &packet->dummy;
+- x->len = 2;
+- }
++ x++;
++ packet->pwrdown_cmd.cmd = PWRDOWN;
++ x->tx_buf = &packet->pwrdown_cmd;
++ x->len = 3;
+
+ CS_CHANGE(*x);
+ spi_message_add_tail(x, m);
+--
+2.39.2
+
--- /dev/null
+From 55cd8dfa270f884461c9a0bbae840be68793eaab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Jan 2021 23:18:28 -0800
+Subject: Input: ads7846 - convert to one message
+
+From: Oleksij Rempel <o.rempel@pengutronix.de>
+
+[ Upstream commit 6965eece2a89c3f1d00881c6052ee1e987870c08 ]
+
+Convert multiple full duplex transfers in to a single transfer to reduce
+CPU load.
+
+Current driver version support following filtering modes:
+- ads7846_no_filter() - not filtered
+- ads7846_debounce_filter() - driver specific debounce filter
+- pdata->filter - platform specific debounce filter (do any platform
+ provides such filter?)
+
+Without filter this HW is not really usable, since the physic of
+resistive touchscreen can provide some bounce effects. With driver internal
+filter, we have constant amount of retries + debounce retries if some anomaly
+was detected.
+
+High amount of tiny SPI transfers is the primer reason of high CPU load
+and interrupt frequency.
+
+This patch create one SPI transfer with all fields and not optional retires. If
+bounce anomaly was detected, we will make more transfer if needed.
+
+Without this patch, we will get about 10% CPU load on iMX6S on pen-down event.
+For example by holding stylus on the screen.
+
+With this patch, depending in the amount of retries, the CPU load will
+be 1% with "ti,debounce-rep = <3>".
+
+One buffer transfer allows us to use PIO FIFO or DMA engine, depending
+on the platform.
+
+Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Link: https://lore.kernel.org/r/20201110085041.16303-3-o.rempel@pengutronix.de
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Stable-dep-of: 13f82ca3878d ("Input: ads7846 - always set last command to PWRDOWN")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/input/touchscreen/ads7846.c | 376 ++++++++++++++--------------
+ 1 file changed, 193 insertions(+), 183 deletions(-)
+
+diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
+index 04ca0e13acd39..0610fab5ed93b 100644
+--- a/drivers/input/touchscreen/ads7846.c
++++ b/drivers/input/touchscreen/ads7846.c
+@@ -65,24 +65,13 @@
+
+ struct ads7846_buf {
+ u8 cmd;
+- /*
+- * This union is a temporary hack. The driver does an in-place
+- * endianness conversion. This will be cleaned up in the next
+- * patch.
+- */
+- union {
+- __be16 data_be16;
+- u16 data;
+- };
++ __be16 data;
+ } __packed;
+
+-
+-struct ts_event {
+- bool ignore;
+- struct ads7846_buf x;
+- struct ads7846_buf y;
+- struct ads7846_buf z1;
+- struct ads7846_buf z2;
++struct ads7846_buf_layout {
++ unsigned int offset;
++ unsigned int count;
++ unsigned int skip;
+ };
+
+ /*
+@@ -91,12 +80,18 @@ struct ts_event {
+ * systems where main memory is not DMA-coherent (most non-x86 boards).
+ */
+ struct ads7846_packet {
+- struct ts_event tc;
+- struct ads7846_buf read_x_cmd;
+- struct ads7846_buf read_y_cmd;
+- struct ads7846_buf read_z1_cmd;
+- struct ads7846_buf read_z2_cmd;
++ unsigned int count;
++ unsigned int count_skip;
++ unsigned int cmds;
++ unsigned int last_cmd_idx;
++ struct ads7846_buf_layout l[5];
++ struct ads7846_buf *rx;
++ struct ads7846_buf *tx;
++
+ struct ads7846_buf pwrdown_cmd;
++
++ bool ignore;
++ u16 x, y, z1, z2;
+ };
+
+ struct ads7846 {
+@@ -195,7 +190,6 @@ struct ads7846 {
+ #define READ_Y(vref) (READ_12BIT_DFR(y, 1, vref))
+ #define READ_Z1(vref) (READ_12BIT_DFR(z1, 1, vref))
+ #define READ_Z2(vref) (READ_12BIT_DFR(z2, 1, vref))
+-
+ #define READ_X(vref) (READ_12BIT_DFR(x, 1, vref))
+ #define PWRDOWN (READ_12BIT_DFR(y, 0, 0)) /* LAST */
+
+@@ -208,6 +202,21 @@ struct ads7846 {
+ #define REF_ON (READ_12BIT_DFR(x, 1, 1))
+ #define REF_OFF (READ_12BIT_DFR(y, 0, 0))
+
++/* Order commands in the most optimal way to reduce Vref switching and
++ * settling time:
++ * Measure: X; Vref: X+, X-; IN: Y+
++ * Measure: Y; Vref: Y+, Y-; IN: X+
++ * Measure: Z1; Vref: Y+, X-; IN: X+
++ * Measure: Z2; Vref: Y+, X-; IN: Y-
++ */
++enum ads7846_cmds {
++ ADS7846_X,
++ ADS7846_Y,
++ ADS7846_Z1,
++ ADS7846_Z2,
++ ADS7846_PWDOWN,
++};
++
+ static int get_pendown_state(struct ads7846 *ts)
+ {
+ if (ts->get_pendown_state)
+@@ -690,26 +699,109 @@ static int ads7846_no_filter(void *ads, int data_idx, int *val)
+ return ADS7846_FILTER_OK;
+ }
+
+-static int ads7846_get_value(struct ads7846 *ts, struct spi_message *m)
++static int ads7846_get_value(struct ads7846_buf *buf)
+ {
+ int value;
+- struct spi_transfer *t =
+- list_entry(m->transfers.prev, struct spi_transfer, transfer_list);
+- struct ads7846_buf *buf = t->rx_buf;
+
+- value = be16_to_cpup(&buf->data_be16);
++ value = be16_to_cpup(&buf->data);
+
+ /* enforce ADC output is 12 bits width */
+ return (value >> 3) & 0xfff;
+ }
+
+-static void ads7846_update_value(struct spi_message *m, int val)
++static void ads7846_set_cmd_val(struct ads7846 *ts, enum ads7846_cmds cmd_idx,
++ u16 val)
++{
++ struct ads7846_packet *packet = ts->packet;
++
++ switch (cmd_idx) {
++ case ADS7846_Y:
++ packet->y = val;
++ break;
++ case ADS7846_X:
++ packet->x = val;
++ break;
++ case ADS7846_Z1:
++ packet->z1 = val;
++ break;
++ case ADS7846_Z2:
++ packet->z2 = val;
++ break;
++ default:
++ WARN_ON_ONCE(1);
++ }
++}
++
++static u8 ads7846_get_cmd(enum ads7846_cmds cmd_idx, int vref)
++{
++ switch (cmd_idx) {
++ case ADS7846_Y:
++ return READ_Y(vref);
++ case ADS7846_X:
++ return READ_X(vref);
++
++ /* 7846 specific commands */
++ case ADS7846_Z1:
++ return READ_Z1(vref);
++ case ADS7846_Z2:
++ return READ_Z2(vref);
++ case ADS7846_PWDOWN:
++ return PWRDOWN;
++ default:
++ WARN_ON_ONCE(1);
++ }
++
++ return 0;
++}
++
++static bool ads7846_cmd_need_settle(enum ads7846_cmds cmd_idx)
++{
++ switch (cmd_idx) {
++ case ADS7846_X:
++ case ADS7846_Y:
++ case ADS7846_Z1:
++ case ADS7846_Z2:
++ return true;
++ case ADS7846_PWDOWN:
++ return false;
++ default:
++ WARN_ON_ONCE(1);
++ }
++
++ return false;
++}
++
++static int ads7846_filter(struct ads7846 *ts)
+ {
+- struct spi_transfer *t =
+- list_entry(m->transfers.prev, struct spi_transfer, transfer_list);
+- struct ads7846_buf *buf = t->rx_buf;
++ struct ads7846_packet *packet = ts->packet;
++ int action;
++ int val;
++ unsigned int cmd_idx, b;
+
+- buf->data = val;
++ packet->ignore = false;
++ for (cmd_idx = packet->last_cmd_idx; cmd_idx < packet->cmds - 1; cmd_idx++) {
++ struct ads7846_buf_layout *l = &packet->l[cmd_idx];
++
++ packet->last_cmd_idx = cmd_idx;
++
++ for (b = l->skip; b < l->count; b++) {
++ val = ads7846_get_value(&packet->rx[l->offset + b]);
++
++ action = ts->filter(ts->filter_data, cmd_idx, &val);
++ if (action == ADS7846_FILTER_REPEAT) {
++ if (b == l->count - 1)
++ return -EAGAIN;
++ } else if (action == ADS7846_FILTER_OK) {
++ ads7846_set_cmd_val(ts, cmd_idx, val);
++ break;
++ } else {
++ packet->ignore = true;
++ return 0;
++ }
++ }
++ }
++
++ return 0;
+ }
+
+ static void ads7846_read_state(struct ads7846 *ts)
+@@ -717,52 +809,26 @@ static void ads7846_read_state(struct ads7846 *ts)
+ struct ads7846_packet *packet = ts->packet;
+ struct spi_message *m;
+ int msg_idx = 0;
+- int val;
+- int action;
+ int error;
+
+- while (msg_idx < ts->msg_count) {
++ packet->last_cmd_idx = 0;
+
++ while (true) {
+ ts->wait_for_sync();
+
+ m = &ts->msg[msg_idx];
+ error = spi_sync(ts->spi, m);
+ if (error) {
+ dev_err(&ts->spi->dev, "spi_sync --> %d\n", error);
+- packet->tc.ignore = true;
++ packet->ignore = true;
+ return;
+ }
+
+- /*
+- * Last message is power down request, no need to convert
+- * or filter the value.
+- */
+- if (msg_idx < ts->msg_count - 1) {
+-
+- val = ads7846_get_value(ts, m);
+-
+- action = ts->filter(ts->filter_data, msg_idx, &val);
+- switch (action) {
+- case ADS7846_FILTER_REPEAT:
+- continue;
+-
+- case ADS7846_FILTER_IGNORE:
+- packet->tc.ignore = true;
+- msg_idx = ts->msg_count - 1;
+- continue;
+-
+- case ADS7846_FILTER_OK:
+- ads7846_update_value(m, val);
+- packet->tc.ignore = false;
+- msg_idx++;
+- break;
++ error = ads7846_filter(ts);
++ if (error)
++ continue;
+
+- default:
+- BUG();
+- }
+- } else {
+- msg_idx++;
+- }
++ return;
+ }
+ }
+
+@@ -772,19 +838,14 @@ static void ads7846_report_state(struct ads7846 *ts)
+ unsigned int Rt;
+ u16 x, y, z1, z2;
+
+- /*
+- * ads7846_get_value() does in-place conversion (including byte swap)
+- * from on-the-wire format as part of debouncing to get stable
+- * readings.
+- */
+- x = packet->tc.x.data;
+- y = packet->tc.y.data;
++ x = packet->x;
++ y = packet->y;
+ if (ts->model == 7845) {
+ z1 = 0;
+ z2 = 0;
+ } else {
+- z1 = packet->tc.z1.data;
+- z2 = packet->tc.z2.data;
++ z1 = packet->z1;
++ z2 = packet->z2;
+ }
+
+ /* range filtering */
+@@ -817,9 +878,9 @@ static void ads7846_report_state(struct ads7846 *ts)
+ * the maximum. Don't report it to user space, repeat at least
+ * once more the measurement
+ */
+- if (packet->tc.ignore || Rt > ts->pressure_max) {
++ if (packet->ignore || Rt > ts->pressure_max) {
+ dev_vdbg(&ts->spi->dev, "ignored %d pressure %d\n",
+- packet->tc.ignore, Rt);
++ packet->ignore, Rt);
+ return;
+ }
+
+@@ -980,13 +1041,59 @@ static int ads7846_setup_pendown(struct spi_device *spi,
+ * Set up the transfers to read touchscreen state; this assumes we
+ * use formula #2 for pressure, not #3.
+ */
+-static void ads7846_setup_spi_msg(struct ads7846 *ts,
++static int ads7846_setup_spi_msg(struct ads7846 *ts,
+ const struct ads7846_platform_data *pdata)
+ {
+ struct spi_message *m = &ts->msg[0];
+ struct spi_transfer *x = ts->xfer;
+ struct ads7846_packet *packet = ts->packet;
+ int vref = pdata->keep_vref_on;
++ unsigned int count, offset = 0;
++ unsigned int cmd_idx, b;
++ unsigned long time;
++ size_t size = 0;
++
++ /* time per bit */
++ time = NSEC_PER_SEC / ts->spi->max_speed_hz;
++
++ count = pdata->settle_delay_usecs * NSEC_PER_USEC / time;
++ packet->count_skip = DIV_ROUND_UP(count, 24);
++
++ if (ts->debounce_max && ts->debounce_rep)
++ /* ads7846_debounce_filter() is making ts->debounce_rep + 2
++ * reads. So we need to get all samples for normal case. */
++ packet->count = ts->debounce_rep + 2;
++ else
++ packet->count = 1;
++
++ if (ts->model == 7846)
++ packet->cmds = 5; /* x, y, z1, z2, pwdown */
++ else
++ packet->cmds = 3; /* x, y, pwdown */
++
++ for (cmd_idx = 0; cmd_idx < packet->cmds; cmd_idx++) {
++ struct ads7846_buf_layout *l = &packet->l[cmd_idx];
++ unsigned int max_count;
++
++ if (ads7846_cmd_need_settle(cmd_idx))
++ max_count = packet->count + packet->count_skip;
++ else
++ max_count = packet->count;
++
++ l->offset = offset;
++ offset += max_count;
++ l->count = max_count;
++ l->skip = packet->count_skip;
++ size += sizeof(*packet->tx) * max_count;
++ }
++
++ packet->tx = devm_kzalloc(&ts->spi->dev, size, GFP_KERNEL);
++ if (!packet->tx)
++ return -ENOMEM;
++
++ packet->rx = devm_kzalloc(&ts->spi->dev, size, GFP_KERNEL);
++ if (!packet->rx)
++ return -ENOMEM;
+
+ if (ts->model == 7873) {
+ /*
+@@ -1002,117 +1109,20 @@ static void ads7846_setup_spi_msg(struct ads7846 *ts,
+ spi_message_init(m);
+ m->context = ts;
+
+- packet->read_y_cmd.cmd = READ_Y(vref);
+- x->tx_buf = &packet->read_y_cmd;
+- x->rx_buf = &packet->tc.y;
+- x->len = 3;
+- spi_message_add_tail(x, m);
++ for (cmd_idx = 0; cmd_idx < packet->cmds; cmd_idx++) {
++ struct ads7846_buf_layout *l = &packet->l[cmd_idx];
++ u8 cmd = ads7846_get_cmd(cmd_idx, vref);
+
+- /*
+- * The first sample after switching drivers can be low quality;
+- * optionally discard it, using a second one after the signals
+- * have had enough time to stabilize.
+- */
+- if (pdata->settle_delay_usecs) {
+- x->delay.value = pdata->settle_delay_usecs;
+- x->delay.unit = SPI_DELAY_UNIT_USECS;
+- x++;
+-
+- x->tx_buf = &packet->read_y_cmd;
+- x->rx_buf = &packet->tc.y;
+- x->len = 3;
+- spi_message_add_tail(x, m);
++ for (b = 0; b < l->count; b++)
++ packet->tx[l->offset + b].cmd = cmd;
+ }
+
+- ts->msg_count++;
+- m++;
+- spi_message_init(m);
+- m->context = ts;
+-
+- /* turn y- off, x+ on, then leave in lowpower */
+- x++;
+- packet->read_x_cmd.cmd = READ_X(vref);
+- x->tx_buf = &packet->read_x_cmd;
+- x->rx_buf = &packet->tc.x;
+- x->len = 3;
++ x->tx_buf = packet->tx;
++ x->rx_buf = packet->rx;
++ x->len = size;
+ spi_message_add_tail(x, m);
+
+- /* ... maybe discard first sample ... */
+- if (pdata->settle_delay_usecs) {
+- x->delay.value = pdata->settle_delay_usecs;
+- x->delay.unit = SPI_DELAY_UNIT_USECS;
+-
+- x++;
+- x->tx_buf = &packet->read_x_cmd;
+- x->rx_buf = &packet->tc.x;
+- x->len = 3;
+- spi_message_add_tail(x, m);
+- }
+-
+- /* turn y+ off, x- on; we'll use formula #2 */
+- if (ts->model == 7846) {
+- ts->msg_count++;
+- m++;
+- spi_message_init(m);
+- m->context = ts;
+-
+- x++;
+- packet->read_z1_cmd.cmd = READ_Z1(vref);
+- x->tx_buf = &packet->read_z1_cmd;
+- x->rx_buf = &packet->tc.z1;
+- x->len = 3;
+- spi_message_add_tail(x, m);
+-
+- /* ... maybe discard first sample ... */
+- if (pdata->settle_delay_usecs) {
+- x->delay.value = pdata->settle_delay_usecs;
+- x->delay.unit = SPI_DELAY_UNIT_USECS;
+-
+- x++;
+- x->tx_buf = &packet->read_z1_cmd;
+- x->rx_buf = &packet->tc.z1;
+- x->len = 3;
+- spi_message_add_tail(x, m);
+- }
+-
+- ts->msg_count++;
+- m++;
+- spi_message_init(m);
+- m->context = ts;
+-
+- x++;
+- packet->read_z2_cmd.cmd = READ_Z2(vref);
+- x->tx_buf = &packet->read_z2_cmd;
+- x->rx_buf = &packet->tc.z2;
+- x->len = 3;
+- spi_message_add_tail(x, m);
+-
+- /* ... maybe discard first sample ... */
+- if (pdata->settle_delay_usecs) {
+- x->delay.value = pdata->settle_delay_usecs;
+- x->delay.unit = SPI_DELAY_UNIT_USECS;
+-
+- x++;
+- x->tx_buf = &packet->read_z2_cmd;
+- x->rx_buf = &packet->tc.z2;
+- x->len = 3;
+- spi_message_add_tail(x, m);
+- }
+- }
+-
+- /* power down */
+- ts->msg_count++;
+- m++;
+- spi_message_init(m);
+- m->context = ts;
+-
+- x++;
+- packet->pwrdown_cmd.cmd = PWRDOWN;
+- x->tx_buf = &packet->pwrdown_cmd;
+- x->len = 3;
+-
+- CS_CHANGE(*x);
+- spi_message_add_tail(x, m);
++ return 0;
+ }
+
+ #ifdef CONFIG_OF
+--
+2.39.2
+
--- /dev/null
+From b24309b2386c561151986b80540beed659c077c2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 Jan 2023 11:52:27 +0100
+Subject: Input: ads7846 - don't check penirq immediately for 7845
+
+From: Luca Ellero <l.ellero@asem.it>
+
+[ Upstream commit fa9f4275b20ec7b2a8fb05c66362d10b36f9efec ]
+
+To discard false readings, one should use "ti,penirq-recheck-delay-usecs".
+Checking get_pendown_state() at the beginning, most of the time fails
+causing malfunctioning.
+
+Fixes: ffa458c1bd9b ("spi: ads7846 driver")
+Signed-off-by: Luca Ellero <l.ellero@asem.it>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://lore.kernel.org/r/20230126105227.47648-4-l.ellero@asem.it
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/input/touchscreen/ads7846.c | 8 +-------
+ 1 file changed, 1 insertion(+), 7 deletions(-)
+
+diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
+index 9f5cc42a567a5..1753288cedde7 100644
+--- a/drivers/input/touchscreen/ads7846.c
++++ b/drivers/input/touchscreen/ads7846.c
+@@ -852,14 +852,8 @@ static void ads7846_report_state(struct ads7846 *ts)
+ if (x == MAX_12BIT)
+ x = 0;
+
+- if (ts->model == 7843) {
++ if (ts->model == 7843 || ts->model == 7845) {
+ Rt = ts->pressure_max / 2;
+- } else if (ts->model == 7845) {
+- if (get_pendown_state(ts))
+- Rt = ts->pressure_max / 2;
+- else
+- Rt = 0;
+- dev_vdbg(&ts->spi->dev, "x/y: %d/%d, PD %d\n", x, y, Rt);
+ } else if (likely(x && z1)) {
+ /* compute touch pressure resistance using equation #2 */
+ Rt = z2;
+--
+2.39.2
+
--- /dev/null
+From 7a83a182da78b0540c99af2fc2578d7cdaf18a05 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 Jan 2023 11:52:25 +0100
+Subject: Input: ads7846 - don't report pressure for ads7845
+
+From: Luca Ellero <l.ellero@asem.it>
+
+[ Upstream commit d50584d783313c8b05b84d0b07a2142f1bde46dd ]
+
+ADS7845 doesn't support pressure.
+Avoid the following error reported by libinput-list-devices:
+"ADS7845 Touchscreen: kernel bug: device has min == max on ABS_PRESSURE".
+
+Fixes: ffa458c1bd9b ("spi: ads7846 driver")
+Signed-off-by: Luca Ellero <l.ellero@asem.it>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://lore.kernel.org/r/20230126105227.47648-2-l.ellero@asem.it
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/input/touchscreen/ads7846.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
+index ff97897feaf2a..370e0dbc02dea 100644
+--- a/drivers/input/touchscreen/ads7846.c
++++ b/drivers/input/touchscreen/ads7846.c
+@@ -1381,8 +1381,9 @@ static int ads7846_probe(struct spi_device *spi)
+ pdata->y_min ? : 0,
+ pdata->y_max ? : MAX_12BIT,
+ 0, 0);
+- input_set_abs_params(input_dev, ABS_PRESSURE,
+- pdata->pressure_min, pdata->pressure_max, 0, 0);
++ if (ts->model != 7845)
++ input_set_abs_params(input_dev, ABS_PRESSURE,
++ pdata->pressure_min, pdata->pressure_max, 0, 0);
+
+ /*
+ * Parse common framework properties. Must be done here to ensure the
+--
+2.39.2
+
--- /dev/null
+From 213e3c68be2aab91ddd7656befd37a3cf7d107fd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Jan 2023 11:59:12 -0600
+Subject: Input: iqs269a - configure device with a single block write
+
+From: Jeff LaBundy <jeff@labundy.com>
+
+[ Upstream commit 3689abfc4e369a643d758a02fb9ad0b2403d6d6d ]
+
+Unless it is being done as part of servicing a soft reset interrupt,
+configuring channels on-the-fly (as is the case when writing to the
+ati_trigger attribute) may cause GPIO3 (which reflects the state of
+touch for a selected channel) to be inadvertently asserted.
+
+To solve this problem, follow the vendor's recommendation and write
+all channel configuration as well as the REDO_ATI register field as
+part of a single block write. This ensures the device has been told
+to re-calibrate itself following an I2C stop condition, after which
+sensing resumes and GPIO3 may be asserted.
+
+Fixes: 04e49867fad1 ("Input: add support for Azoteq IQS269A")
+Signed-off-by: Jeff LaBundy <jeff@labundy.com>
+Reviewed-by: Mattijs Korpershoek <mkorpershoek@baylibre.com>
+Link: https://lore.kernel.org/r/Y7Rs8GyV7g0nF5Yy@nixie71
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/input/misc/iqs269a.c | 98 ++++++++++++++----------------------
+ 1 file changed, 39 insertions(+), 59 deletions(-)
+
+diff --git a/drivers/input/misc/iqs269a.c b/drivers/input/misc/iqs269a.c
+index ea3401a1000f0..1530efd301c24 100644
+--- a/drivers/input/misc/iqs269a.c
++++ b/drivers/input/misc/iqs269a.c
+@@ -96,8 +96,6 @@
+ #define IQS269_MISC_B_TRACKING_UI_ENABLE BIT(4)
+ #define IQS269_MISC_B_FILT_STR_SLIDER GENMASK(1, 0)
+
+-#define IQS269_CHx_SETTINGS 0x8C
+-
+ #define IQS269_CHx_ENG_A_MEAS_CAP_SIZE BIT(15)
+ #define IQS269_CHx_ENG_A_RX_GND_INACTIVE BIT(13)
+ #define IQS269_CHx_ENG_A_LOCAL_CAP_SIZE BIT(12)
+@@ -245,6 +243,18 @@ struct iqs269_ver_info {
+ u8 padding;
+ } __packed;
+
++struct iqs269_ch_reg {
++ u8 rx_enable;
++ u8 tx_enable;
++ __be16 engine_a;
++ __be16 engine_b;
++ __be16 ati_comp;
++ u8 thresh[3];
++ u8 hyst;
++ u8 assoc_select;
++ u8 assoc_weight;
++} __packed;
++
+ struct iqs269_sys_reg {
+ __be16 general;
+ u8 active;
+@@ -266,18 +276,7 @@ struct iqs269_sys_reg {
+ u8 timeout_swipe;
+ u8 thresh_swipe;
+ u8 redo_ati;
+-} __packed;
+-
+-struct iqs269_ch_reg {
+- u8 rx_enable;
+- u8 tx_enable;
+- __be16 engine_a;
+- __be16 engine_b;
+- __be16 ati_comp;
+- u8 thresh[3];
+- u8 hyst;
+- u8 assoc_select;
+- u8 assoc_weight;
++ struct iqs269_ch_reg ch_reg[IQS269_NUM_CH];
+ } __packed;
+
+ struct iqs269_flags {
+@@ -292,7 +291,6 @@ struct iqs269_private {
+ struct regmap *regmap;
+ struct mutex lock;
+ struct iqs269_switch_desc switches[ARRAY_SIZE(iqs269_events)];
+- struct iqs269_ch_reg ch_reg[IQS269_NUM_CH];
+ struct iqs269_sys_reg sys_reg;
+ struct input_dev *keypad;
+ struct input_dev *slider[IQS269_NUM_SL];
+@@ -307,6 +305,7 @@ struct iqs269_private {
+ static int iqs269_ati_mode_set(struct iqs269_private *iqs269,
+ unsigned int ch_num, unsigned int mode)
+ {
++ struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg;
+ u16 engine_a;
+
+ if (ch_num >= IQS269_NUM_CH)
+@@ -317,12 +316,12 @@ static int iqs269_ati_mode_set(struct iqs269_private *iqs269,
+
+ mutex_lock(&iqs269->lock);
+
+- engine_a = be16_to_cpu(iqs269->ch_reg[ch_num].engine_a);
++ engine_a = be16_to_cpu(ch_reg[ch_num].engine_a);
+
+ engine_a &= ~IQS269_CHx_ENG_A_ATI_MODE_MASK;
+ engine_a |= (mode << IQS269_CHx_ENG_A_ATI_MODE_SHIFT);
+
+- iqs269->ch_reg[ch_num].engine_a = cpu_to_be16(engine_a);
++ ch_reg[ch_num].engine_a = cpu_to_be16(engine_a);
+ iqs269->ati_current = false;
+
+ mutex_unlock(&iqs269->lock);
+@@ -333,13 +332,14 @@ static int iqs269_ati_mode_set(struct iqs269_private *iqs269,
+ static int iqs269_ati_mode_get(struct iqs269_private *iqs269,
+ unsigned int ch_num, unsigned int *mode)
+ {
++ struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg;
+ u16 engine_a;
+
+ if (ch_num >= IQS269_NUM_CH)
+ return -EINVAL;
+
+ mutex_lock(&iqs269->lock);
+- engine_a = be16_to_cpu(iqs269->ch_reg[ch_num].engine_a);
++ engine_a = be16_to_cpu(ch_reg[ch_num].engine_a);
+ mutex_unlock(&iqs269->lock);
+
+ engine_a &= IQS269_CHx_ENG_A_ATI_MODE_MASK;
+@@ -351,6 +351,7 @@ static int iqs269_ati_mode_get(struct iqs269_private *iqs269,
+ static int iqs269_ati_base_set(struct iqs269_private *iqs269,
+ unsigned int ch_num, unsigned int base)
+ {
++ struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg;
+ u16 engine_b;
+
+ if (ch_num >= IQS269_NUM_CH)
+@@ -379,12 +380,12 @@ static int iqs269_ati_base_set(struct iqs269_private *iqs269,
+
+ mutex_lock(&iqs269->lock);
+
+- engine_b = be16_to_cpu(iqs269->ch_reg[ch_num].engine_b);
++ engine_b = be16_to_cpu(ch_reg[ch_num].engine_b);
+
+ engine_b &= ~IQS269_CHx_ENG_B_ATI_BASE_MASK;
+ engine_b |= base;
+
+- iqs269->ch_reg[ch_num].engine_b = cpu_to_be16(engine_b);
++ ch_reg[ch_num].engine_b = cpu_to_be16(engine_b);
+ iqs269->ati_current = false;
+
+ mutex_unlock(&iqs269->lock);
+@@ -395,13 +396,14 @@ static int iqs269_ati_base_set(struct iqs269_private *iqs269,
+ static int iqs269_ati_base_get(struct iqs269_private *iqs269,
+ unsigned int ch_num, unsigned int *base)
+ {
++ struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg;
+ u16 engine_b;
+
+ if (ch_num >= IQS269_NUM_CH)
+ return -EINVAL;
+
+ mutex_lock(&iqs269->lock);
+- engine_b = be16_to_cpu(iqs269->ch_reg[ch_num].engine_b);
++ engine_b = be16_to_cpu(ch_reg[ch_num].engine_b);
+ mutex_unlock(&iqs269->lock);
+
+ switch (engine_b & IQS269_CHx_ENG_B_ATI_BASE_MASK) {
+@@ -429,6 +431,7 @@ static int iqs269_ati_base_get(struct iqs269_private *iqs269,
+ static int iqs269_ati_target_set(struct iqs269_private *iqs269,
+ unsigned int ch_num, unsigned int target)
+ {
++ struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg;
+ u16 engine_b;
+
+ if (ch_num >= IQS269_NUM_CH)
+@@ -439,12 +442,12 @@ static int iqs269_ati_target_set(struct iqs269_private *iqs269,
+
+ mutex_lock(&iqs269->lock);
+
+- engine_b = be16_to_cpu(iqs269->ch_reg[ch_num].engine_b);
++ engine_b = be16_to_cpu(ch_reg[ch_num].engine_b);
+
+ engine_b &= ~IQS269_CHx_ENG_B_ATI_TARGET_MASK;
+ engine_b |= target / 32;
+
+- iqs269->ch_reg[ch_num].engine_b = cpu_to_be16(engine_b);
++ ch_reg[ch_num].engine_b = cpu_to_be16(engine_b);
+ iqs269->ati_current = false;
+
+ mutex_unlock(&iqs269->lock);
+@@ -455,13 +458,14 @@ static int iqs269_ati_target_set(struct iqs269_private *iqs269,
+ static int iqs269_ati_target_get(struct iqs269_private *iqs269,
+ unsigned int ch_num, unsigned int *target)
+ {
++ struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg;
+ u16 engine_b;
+
+ if (ch_num >= IQS269_NUM_CH)
+ return -EINVAL;
+
+ mutex_lock(&iqs269->lock);
+- engine_b = be16_to_cpu(iqs269->ch_reg[ch_num].engine_b);
++ engine_b = be16_to_cpu(ch_reg[ch_num].engine_b);
+ mutex_unlock(&iqs269->lock);
+
+ *target = (engine_b & IQS269_CHx_ENG_B_ATI_TARGET_MASK) * 32;
+@@ -531,13 +535,7 @@ static int iqs269_parse_chan(struct iqs269_private *iqs269,
+ if (fwnode_property_present(ch_node, "azoteq,slider1-select"))
+ iqs269->sys_reg.slider_select[1] |= BIT(reg);
+
+- ch_reg = &iqs269->ch_reg[reg];
+-
+- error = regmap_raw_read(iqs269->regmap,
+- IQS269_CHx_SETTINGS + reg * sizeof(*ch_reg) / 2,
+- ch_reg, sizeof(*ch_reg));
+- if (error)
+- return error;
++ ch_reg = &iqs269->sys_reg.ch_reg[reg];
+
+ error = iqs269_parse_mask(ch_node, "azoteq,rx-enable",
+ &ch_reg->rx_enable);
+@@ -1042,10 +1040,8 @@ static int iqs269_parse_prop(struct iqs269_private *iqs269)
+
+ static int iqs269_dev_init(struct iqs269_private *iqs269)
+ {
+- struct iqs269_sys_reg *sys_reg = &iqs269->sys_reg;
+- struct iqs269_ch_reg *ch_reg;
+ unsigned int val;
+- int error, i;
++ int error;
+
+ mutex_lock(&iqs269->lock);
+
+@@ -1055,27 +1051,8 @@ static int iqs269_dev_init(struct iqs269_private *iqs269)
+ if (error)
+ goto err_mutex;
+
+- for (i = 0; i < IQS269_NUM_CH; i++) {
+- if (!(sys_reg->active & BIT(i)))
+- continue;
+-
+- ch_reg = &iqs269->ch_reg[i];
+-
+- error = regmap_raw_write(iqs269->regmap,
+- IQS269_CHx_SETTINGS + i *
+- sizeof(*ch_reg) / 2, ch_reg,
+- sizeof(*ch_reg));
+- if (error)
+- goto err_mutex;
+- }
+-
+- /*
+- * The REDO-ATI and ATI channel selection fields must be written in the
+- * same block write, so every field between registers 0x80 through 0x8B
+- * (inclusive) must be written as well.
+- */
+- error = regmap_raw_write(iqs269->regmap, IQS269_SYS_SETTINGS, sys_reg,
+- sizeof(*sys_reg));
++ error = regmap_raw_write(iqs269->regmap, IQS269_SYS_SETTINGS,
++ &iqs269->sys_reg, sizeof(iqs269->sys_reg));
+ if (error)
+ goto err_mutex;
+
+@@ -1349,6 +1326,7 @@ static ssize_t hall_bin_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+ {
+ struct iqs269_private *iqs269 = dev_get_drvdata(dev);
++ struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg;
+ struct i2c_client *client = iqs269->client;
+ unsigned int val;
+ int error;
+@@ -1363,8 +1341,8 @@ static ssize_t hall_bin_show(struct device *dev,
+ if (error)
+ return error;
+
+- switch (iqs269->ch_reg[IQS269_CHx_HALL_ACTIVE].rx_enable &
+- iqs269->ch_reg[IQS269_CHx_HALL_INACTIVE].rx_enable) {
++ switch (ch_reg[IQS269_CHx_HALL_ACTIVE].rx_enable &
++ ch_reg[IQS269_CHx_HALL_INACTIVE].rx_enable) {
+ case IQS269_HALL_PAD_R:
+ val &= IQS269_CAL_DATA_A_HALL_BIN_R_MASK;
+ val >>= IQS269_CAL_DATA_A_HALL_BIN_R_SHIFT;
+@@ -1444,9 +1422,10 @@ static ssize_t rx_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+ {
+ struct iqs269_private *iqs269 = dev_get_drvdata(dev);
++ struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg;
+
+ return scnprintf(buf, PAGE_SIZE, "%u\n",
+- iqs269->ch_reg[iqs269->ch_num].rx_enable);
++ ch_reg[iqs269->ch_num].rx_enable);
+ }
+
+ static ssize_t rx_enable_store(struct device *dev,
+@@ -1454,6 +1433,7 @@ static ssize_t rx_enable_store(struct device *dev,
+ size_t count)
+ {
+ struct iqs269_private *iqs269 = dev_get_drvdata(dev);
++ struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg;
+ unsigned int val;
+ int error;
+
+@@ -1466,7 +1446,7 @@ static ssize_t rx_enable_store(struct device *dev,
+
+ mutex_lock(&iqs269->lock);
+
+- iqs269->ch_reg[iqs269->ch_num].rx_enable = val;
++ ch_reg[iqs269->ch_num].rx_enable = val;
+ iqs269->ati_current = false;
+
+ mutex_unlock(&iqs269->lock);
+--
+2.39.2
+
--- /dev/null
+From 5c4f12843a6188c177e9eeb4f1821a460855dfdc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Jan 2023 11:59:35 -0600
+Subject: Input: iqs269a - do not poll during ATI
+
+From: Jeff LaBundy <jeff@labundy.com>
+
+[ Upstream commit b08134eb254db56e9ce8170d9b82f0d7a616b6f8 ]
+
+After initial start-up, the driver triggers ATI (calibration) with
+the newly loaded register configuration in place. Next, the driver
+polls a register field to ensure ATI completed in a timely fashion
+and that the device is ready to sense.
+
+However, communicating with the device over I2C while ATI is under-
+way may induce noise in the device and cause ATI to fail. As such,
+the vendor recommends not to poll the device during ATI.
+
+To solve this problem, let the device naturally signal to the host
+that ATI is complete by way of an interrupt. A completion prevents
+the device from successfully probing until this happens.
+
+As an added benefit, initial switch states are now reported in the
+interrupt handler at the same time ATI status is checked. As such,
+duplicate code that reports initial switch states has been removed
+from iqs269_input_init().
+
+The former logic that scaled ATI timeout and filter settling delay
+is not carried forward with the new implementation, as it produces
+overly conservative delays at the lower clock rate.
+
+Rather, a single timeout that covers both clock rates is used. The
+filter settling delay does not happen to be necessary and has been
+removed as well.
+
+Fixes: 04e49867fad1 ("Input: add support for Azoteq IQS269A")
+Signed-off-by: Jeff LaBundy <jeff@labundy.com>
+Reviewed-by: Mattijs Korpershoek <mkorpershoek@baylibre.com>
+Link: https://lore.kernel.org/r/Y7RtB2T7AF9rYMjK@nixie71
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/input/misc/iqs269a.c | 97 +++++++++++++++++-------------------
+ 1 file changed, 46 insertions(+), 51 deletions(-)
+
+diff --git a/drivers/input/misc/iqs269a.c b/drivers/input/misc/iqs269a.c
+index 814d1a898e7ff..8b30c911f7899 100644
+--- a/drivers/input/misc/iqs269a.c
++++ b/drivers/input/misc/iqs269a.c
+@@ -9,6 +9,7 @@
+ * axial sliders presented by the device.
+ */
+
++#include <linux/completion.h>
+ #include <linux/delay.h>
+ #include <linux/device.h>
+ #include <linux/err.h>
+@@ -144,10 +145,6 @@
+ #define IQS269_NUM_CH 8
+ #define IQS269_NUM_SL 2
+
+-#define IQS269_ATI_POLL_SLEEP_US (iqs269->delay_mult * 10000)
+-#define IQS269_ATI_POLL_TIMEOUT_US (iqs269->delay_mult * 500000)
+-#define IQS269_ATI_STABLE_DELAY_MS (iqs269->delay_mult * 150)
+-
+ #define iqs269_irq_wait() usleep_range(200, 250)
+
+ enum iqs269_local_cap_size {
+@@ -289,10 +286,10 @@ struct iqs269_private {
+ struct mutex lock;
+ struct iqs269_switch_desc switches[ARRAY_SIZE(iqs269_events)];
+ struct iqs269_sys_reg sys_reg;
++ struct completion ati_done;
+ struct input_dev *keypad;
+ struct input_dev *slider[IQS269_NUM_SL];
+ unsigned int keycode[ARRAY_SIZE(iqs269_events) * IQS269_NUM_CH];
+- unsigned int delay_mult;
+ unsigned int ch_num;
+ bool hall_enable;
+ bool ati_current;
+@@ -973,13 +970,8 @@ static int iqs269_parse_prop(struct iqs269_private *iqs269)
+
+ general = be16_to_cpu(sys_reg->general);
+
+- if (device_property_present(&client->dev, "azoteq,clk-div")) {
++ if (device_property_present(&client->dev, "azoteq,clk-div"))
+ general |= IQS269_SYS_SETTINGS_CLK_DIV;
+- iqs269->delay_mult = 4;
+- } else {
+- general &= ~IQS269_SYS_SETTINGS_CLK_DIV;
+- iqs269->delay_mult = 1;
+- }
+
+ /*
+ * Configure the device to automatically switch between normal and low-
+@@ -1036,7 +1028,6 @@ static int iqs269_parse_prop(struct iqs269_private *iqs269)
+
+ static int iqs269_dev_init(struct iqs269_private *iqs269)
+ {
+- unsigned int val;
+ int error;
+
+ mutex_lock(&iqs269->lock);
+@@ -1052,14 +1043,12 @@ static int iqs269_dev_init(struct iqs269_private *iqs269)
+ if (error)
+ goto err_mutex;
+
+- error = regmap_read_poll_timeout(iqs269->regmap, IQS269_SYS_FLAGS, val,
+- !(val & IQS269_SYS_FLAGS_IN_ATI),
+- IQS269_ATI_POLL_SLEEP_US,
+- IQS269_ATI_POLL_TIMEOUT_US);
+- if (error)
+- goto err_mutex;
++ /*
++ * The following delay gives the device time to deassert its RDY output
++ * so as to prevent an interrupt from being serviced prematurely.
++ */
++ usleep_range(2000, 2100);
+
+- msleep(IQS269_ATI_STABLE_DELAY_MS);
+ iqs269->ati_current = true;
+
+ err_mutex:
+@@ -1071,10 +1060,8 @@ static int iqs269_dev_init(struct iqs269_private *iqs269)
+ static int iqs269_input_init(struct iqs269_private *iqs269)
+ {
+ struct i2c_client *client = iqs269->client;
+- struct iqs269_flags flags;
+ unsigned int sw_code, keycode;
+ int error, i, j;
+- u8 dir_mask, state;
+
+ iqs269->keypad = devm_input_allocate_device(&client->dev);
+ if (!iqs269->keypad)
+@@ -1087,23 +1074,7 @@ static int iqs269_input_init(struct iqs269_private *iqs269)
+ iqs269->keypad->name = "iqs269a_keypad";
+ iqs269->keypad->id.bustype = BUS_I2C;
+
+- if (iqs269->hall_enable) {
+- error = regmap_raw_read(iqs269->regmap, IQS269_SYS_FLAGS,
+- &flags, sizeof(flags));
+- if (error) {
+- dev_err(&client->dev,
+- "Failed to read initial status: %d\n", error);
+- return error;
+- }
+- }
+-
+ for (i = 0; i < ARRAY_SIZE(iqs269_events); i++) {
+- dir_mask = flags.states[IQS269_ST_OFFS_DIR];
+- if (!iqs269_events[i].dir_up)
+- dir_mask = ~dir_mask;
+-
+- state = flags.states[iqs269_events[i].st_offs] & dir_mask;
+-
+ sw_code = iqs269->switches[i].code;
+
+ for (j = 0; j < IQS269_NUM_CH; j++) {
+@@ -1116,13 +1087,9 @@ static int iqs269_input_init(struct iqs269_private *iqs269)
+ switch (j) {
+ case IQS269_CHx_HALL_ACTIVE:
+ if (iqs269->hall_enable &&
+- iqs269->switches[i].enabled) {
++ iqs269->switches[i].enabled)
+ input_set_capability(iqs269->keypad,
+ EV_SW, sw_code);
+- input_report_switch(iqs269->keypad,
+- sw_code,
+- state & BIT(j));
+- }
+ fallthrough;
+
+ case IQS269_CHx_HALL_INACTIVE:
+@@ -1138,14 +1105,6 @@ static int iqs269_input_init(struct iqs269_private *iqs269)
+ }
+ }
+
+- input_sync(iqs269->keypad);
+-
+- error = input_register_device(iqs269->keypad);
+- if (error) {
+- dev_err(&client->dev, "Failed to register keypad: %d\n", error);
+- return error;
+- }
+-
+ for (i = 0; i < IQS269_NUM_SL; i++) {
+ if (!iqs269->sys_reg.slider_select[i])
+ continue;
+@@ -1205,6 +1164,9 @@ static int iqs269_report(struct iqs269_private *iqs269)
+ return error;
+ }
+
++ if (be16_to_cpu(flags.system) & IQS269_SYS_FLAGS_IN_ATI)
++ return 0;
++
+ error = regmap_raw_read(iqs269->regmap, IQS269_SLIDER_X, slider_x,
+ sizeof(slider_x));
+ if (error) {
+@@ -1267,6 +1229,12 @@ static int iqs269_report(struct iqs269_private *iqs269)
+
+ input_sync(iqs269->keypad);
+
++ /*
++ * The following completion signals that ATI has finished, any initial
++ * switch states have been reported and the keypad can be registered.
++ */
++ complete_all(&iqs269->ati_done);
++
+ return 0;
+ }
+
+@@ -1298,6 +1266,9 @@ static ssize_t counts_show(struct device *dev,
+ if (!iqs269->ati_current || iqs269->hall_enable)
+ return -EPERM;
+
++ if (!completion_done(&iqs269->ati_done))
++ return -EBUSY;
++
+ /*
+ * Unsolicited I2C communication prompts the device to assert its RDY
+ * pin, so disable the interrupt line until the operation is finished
+@@ -1554,7 +1525,9 @@ static ssize_t ati_trigger_show(struct device *dev,
+ {
+ struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+
+- return scnprintf(buf, PAGE_SIZE, "%u\n", iqs269->ati_current);
++ return scnprintf(buf, PAGE_SIZE, "%u\n",
++ iqs269->ati_current &&
++ completion_done(&iqs269->ati_done));
+ }
+
+ static ssize_t ati_trigger_store(struct device *dev,
+@@ -1574,6 +1547,7 @@ static ssize_t ati_trigger_store(struct device *dev,
+ return count;
+
+ disable_irq(client->irq);
++ reinit_completion(&iqs269->ati_done);
+
+ error = iqs269_dev_init(iqs269);
+
+@@ -1583,6 +1557,10 @@ static ssize_t ati_trigger_store(struct device *dev,
+ if (error)
+ return error;
+
++ if (!wait_for_completion_timeout(&iqs269->ati_done,
++ msecs_to_jiffies(2000)))
++ return -ETIMEDOUT;
++
+ return count;
+ }
+
+@@ -1641,6 +1619,7 @@ static int iqs269_probe(struct i2c_client *client)
+ }
+
+ mutex_init(&iqs269->lock);
++ init_completion(&iqs269->ati_done);
+
+ error = regmap_raw_read(iqs269->regmap, IQS269_VER_INFO, &ver_info,
+ sizeof(ver_info));
+@@ -1676,6 +1655,22 @@ static int iqs269_probe(struct i2c_client *client)
+ return error;
+ }
+
++ if (!wait_for_completion_timeout(&iqs269->ati_done,
++ msecs_to_jiffies(2000))) {
++ dev_err(&client->dev, "Failed to complete ATI\n");
++ return -ETIMEDOUT;
++ }
++
++ /*
++ * The keypad may include one or more switches and is not registered
++ * until ATI is complete and the initial switch states are read.
++ */
++ error = input_register_device(iqs269->keypad);
++ if (error) {
++ dev_err(&client->dev, "Failed to register keypad: %d\n", error);
++ return error;
++ }
++
+ error = devm_device_add_group(&client->dev, &iqs269_attr_group);
+ if (error)
+ dev_err(&client->dev, "Failed to add attributes: %d\n", error);
+--
+2.39.2
+
--- /dev/null
+From 7d4eb0c66680251ba352a39016e4ae7cd2783db7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Jan 2023 11:59:21 -0600
+Subject: Input: iqs269a - do not poll during suspend or resume
+
+From: Jeff LaBundy <jeff@labundy.com>
+
+[ Upstream commit 18ab69c8ca5678324efbeed874b707ce7b2feae1 ]
+
+Polling the device while it transitions from automatic to manual
+power mode switching may keep the device from actually finishing
+the transition. The process appears to time out depending on the
+polling rate and the device's core clock frequency.
+
+This is ultimately unnecessary in the first place; instead it is
+sufficient to write the desired mode during initialization, then
+disable automatic switching at suspend. This eliminates the need
+to ensure the device is prepared for a manual change and removes
+the 'suspend_mode' variable.
+
+Similarly, polling the device while it transitions from one mode
+to another under manual control may time out as well. This added
+step does not appear to be necessary either, so drop it.
+
+Fixes: 04e49867fad1 ("Input: add support for Azoteq IQS269A")
+Signed-off-by: Jeff LaBundy <jeff@labundy.com>
+Reviewed-by: Mattijs Korpershoek <mkorpershoek@baylibre.com>
+Link: https://lore.kernel.org/r/Y7Rs+eEXlRw4Vq57@nixie71
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/input/misc/iqs269a.c | 118 +++++++++--------------------------
+ 1 file changed, 31 insertions(+), 87 deletions(-)
+
+diff --git a/drivers/input/misc/iqs269a.c b/drivers/input/misc/iqs269a.c
+index 1530efd301c24..814d1a898e7ff 100644
+--- a/drivers/input/misc/iqs269a.c
++++ b/drivers/input/misc/iqs269a.c
+@@ -148,9 +148,6 @@
+ #define IQS269_ATI_POLL_TIMEOUT_US (iqs269->delay_mult * 500000)
+ #define IQS269_ATI_STABLE_DELAY_MS (iqs269->delay_mult * 150)
+
+-#define IQS269_PWR_MODE_POLL_SLEEP_US IQS269_ATI_POLL_SLEEP_US
+-#define IQS269_PWR_MODE_POLL_TIMEOUT_US IQS269_ATI_POLL_TIMEOUT_US
+-
+ #define iqs269_irq_wait() usleep_range(200, 250)
+
+ enum iqs269_local_cap_size {
+@@ -295,7 +292,6 @@ struct iqs269_private {
+ struct input_dev *keypad;
+ struct input_dev *slider[IQS269_NUM_SL];
+ unsigned int keycode[ARRAY_SIZE(iqs269_events) * IQS269_NUM_CH];
+- unsigned int suspend_mode;
+ unsigned int delay_mult;
+ unsigned int ch_num;
+ bool hall_enable;
+@@ -767,17 +763,6 @@ static int iqs269_parse_prop(struct iqs269_private *iqs269)
+ iqs269->hall_enable = device_property_present(&client->dev,
+ "azoteq,hall-enable");
+
+- if (!device_property_read_u32(&client->dev, "azoteq,suspend-mode",
+- &val)) {
+- if (val > IQS269_SYS_SETTINGS_PWR_MODE_MAX) {
+- dev_err(&client->dev, "Invalid suspend mode: %u\n",
+- val);
+- return -EINVAL;
+- }
+-
+- iqs269->suspend_mode = val;
+- }
+-
+ error = regmap_raw_read(iqs269->regmap, IQS269_SYS_SETTINGS, sys_reg,
+ sizeof(*sys_reg));
+ if (error)
+@@ -1005,6 +990,17 @@ static int iqs269_parse_prop(struct iqs269_private *iqs269)
+ general &= ~IQS269_SYS_SETTINGS_DIS_AUTO;
+ general &= ~IQS269_SYS_SETTINGS_PWR_MODE_MASK;
+
++ if (!device_property_read_u32(&client->dev, "azoteq,suspend-mode",
++ &val)) {
++ if (val > IQS269_SYS_SETTINGS_PWR_MODE_MAX) {
++ dev_err(&client->dev, "Invalid suspend mode: %u\n",
++ val);
++ return -EINVAL;
++ }
++
++ general |= (val << IQS269_SYS_SETTINGS_PWR_MODE_SHIFT);
++ }
++
+ if (!device_property_read_u32(&client->dev, "azoteq,ulp-update",
+ &val)) {
+ if (val > IQS269_SYS_SETTINGS_ULP_UPDATE_MAX) {
+@@ -1687,59 +1683,30 @@ static int iqs269_probe(struct i2c_client *client)
+ return error;
+ }
+
++static u16 iqs269_general_get(struct iqs269_private *iqs269)
++{
++ u16 general = be16_to_cpu(iqs269->sys_reg.general);
++
++ general &= ~IQS269_SYS_SETTINGS_REDO_ATI;
++ general &= ~IQS269_SYS_SETTINGS_ACK_RESET;
++
++ return general | IQS269_SYS_SETTINGS_DIS_AUTO;
++}
++
+ static int __maybe_unused iqs269_suspend(struct device *dev)
+ {
+ struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+ struct i2c_client *client = iqs269->client;
+- unsigned int val;
+ int error;
++ u16 general = iqs269_general_get(iqs269);
+
+- if (!iqs269->suspend_mode)
++ if (!(general & IQS269_SYS_SETTINGS_PWR_MODE_MASK))
+ return 0;
+
+ disable_irq(client->irq);
+
+- /*
+- * Automatic power mode switching must be disabled before the device is
+- * forced into any particular power mode. In this case, the device will
+- * transition into normal-power mode.
+- */
+- error = regmap_update_bits(iqs269->regmap, IQS269_SYS_SETTINGS,
+- IQS269_SYS_SETTINGS_DIS_AUTO, ~0);
+- if (error)
+- goto err_irq;
+-
+- /*
+- * The following check ensures the device has completed its transition
+- * into normal-power mode before a manual mode switch is performed.
+- */
+- error = regmap_read_poll_timeout(iqs269->regmap, IQS269_SYS_FLAGS, val,
+- !(val & IQS269_SYS_FLAGS_PWR_MODE_MASK),
+- IQS269_PWR_MODE_POLL_SLEEP_US,
+- IQS269_PWR_MODE_POLL_TIMEOUT_US);
+- if (error)
+- goto err_irq;
+-
+- error = regmap_update_bits(iqs269->regmap, IQS269_SYS_SETTINGS,
+- IQS269_SYS_SETTINGS_PWR_MODE_MASK,
+- iqs269->suspend_mode <<
+- IQS269_SYS_SETTINGS_PWR_MODE_SHIFT);
+- if (error)
+- goto err_irq;
+-
+- /*
+- * This last check ensures the device has completed its transition into
+- * the desired power mode to prevent any spurious interrupts from being
+- * triggered after iqs269_suspend has already returned.
+- */
+- error = regmap_read_poll_timeout(iqs269->regmap, IQS269_SYS_FLAGS, val,
+- (val & IQS269_SYS_FLAGS_PWR_MODE_MASK)
+- == (iqs269->suspend_mode <<
+- IQS269_SYS_FLAGS_PWR_MODE_SHIFT),
+- IQS269_PWR_MODE_POLL_SLEEP_US,
+- IQS269_PWR_MODE_POLL_TIMEOUT_US);
++ error = regmap_write(iqs269->regmap, IQS269_SYS_SETTINGS, general);
+
+-err_irq:
+ iqs269_irq_wait();
+ enable_irq(client->irq);
+
+@@ -1750,43 +1717,20 @@ static int __maybe_unused iqs269_resume(struct device *dev)
+ {
+ struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+ struct i2c_client *client = iqs269->client;
+- unsigned int val;
+ int error;
++ u16 general = iqs269_general_get(iqs269);
+
+- if (!iqs269->suspend_mode)
++ if (!(general & IQS269_SYS_SETTINGS_PWR_MODE_MASK))
+ return 0;
+
+ disable_irq(client->irq);
+
+- error = regmap_update_bits(iqs269->regmap, IQS269_SYS_SETTINGS,
+- IQS269_SYS_SETTINGS_PWR_MODE_MASK, 0);
+- if (error)
+- goto err_irq;
+-
+- /*
+- * This check ensures the device has returned to normal-power mode
+- * before automatic power mode switching is re-enabled.
+- */
+- error = regmap_read_poll_timeout(iqs269->regmap, IQS269_SYS_FLAGS, val,
+- !(val & IQS269_SYS_FLAGS_PWR_MODE_MASK),
+- IQS269_PWR_MODE_POLL_SLEEP_US,
+- IQS269_PWR_MODE_POLL_TIMEOUT_US);
+- if (error)
+- goto err_irq;
+-
+- error = regmap_update_bits(iqs269->regmap, IQS269_SYS_SETTINGS,
+- IQS269_SYS_SETTINGS_DIS_AUTO, 0);
+- if (error)
+- goto err_irq;
+-
+- /*
+- * This step reports any events that may have been "swallowed" as a
+- * result of polling PWR_MODE (which automatically acknowledges any
+- * pending interrupts).
+- */
+- error = iqs269_report(iqs269);
++ error = regmap_write(iqs269->regmap, IQS269_SYS_SETTINGS,
++ general & ~IQS269_SYS_SETTINGS_PWR_MODE_MASK);
++ if (!error)
++ error = regmap_write(iqs269->regmap, IQS269_SYS_SETTINGS,
++ general & ~IQS269_SYS_SETTINGS_DIS_AUTO);
+
+-err_irq:
+ iqs269_irq_wait();
+ enable_irq(client->irq);
+
+--
+2.39.2
+
--- /dev/null
+From fd4a57f123e79ea9f511aab17d47b39d94963eab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Jan 2023 11:58:31 -0600
+Subject: Input: iqs269a - drop unused device node references
+
+From: Jeff LaBundy <jeff@labundy.com>
+
+[ Upstream commit 59bc9cb3b80abaa42643abede0d5db8477901d9c ]
+
+Each call to device/fwnode_get_named_child_node() must be matched
+with a call to fwnode_handle_put() once the corresponding node is
+no longer in use. This ensures a reference count remains balanced
+in the case of dynamic device tree support.
+
+Currently, the driver does not call fwnode_handle_put() on nested
+event nodes. This patch solves this problem by adding the missing
+instances of fwnode_handle_put().
+
+As part of this change, the logic which parses each channel's key
+code is gently refactored in order to reduce the number of places
+from which fwnode_handle_put() is called.
+
+Fixes: 04e49867fad1 ("Input: add support for Azoteq IQS269A")
+Signed-off-by: Jeff LaBundy <jeff@labundy.com>
+Link: https://lore.kernel.org/r/Y7Rsx68k/gvDVXAt@nixie71
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/input/misc/iqs269a.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/input/misc/iqs269a.c b/drivers/input/misc/iqs269a.c
+index a348247d3d38f..ea3c97c5f764f 100644
+--- a/drivers/input/misc/iqs269a.c
++++ b/drivers/input/misc/iqs269a.c
+@@ -694,6 +694,7 @@ static int iqs269_parse_chan(struct iqs269_private *iqs269,
+ dev_err(&client->dev,
+ "Invalid channel %u threshold: %u\n",
+ reg, val);
++ fwnode_handle_put(ev_node);
+ return -EINVAL;
+ }
+
+@@ -707,6 +708,7 @@ static int iqs269_parse_chan(struct iqs269_private *iqs269,
+ dev_err(&client->dev,
+ "Invalid channel %u hysteresis: %u\n",
+ reg, val);
++ fwnode_handle_put(ev_node);
+ return -EINVAL;
+ }
+
+@@ -721,8 +723,16 @@ static int iqs269_parse_chan(struct iqs269_private *iqs269,
+ }
+ }
+
+- if (fwnode_property_read_u32(ev_node, "linux,code", &val))
++ error = fwnode_property_read_u32(ev_node, "linux,code", &val);
++ fwnode_handle_put(ev_node);
++ if (error == -EINVAL) {
+ continue;
++ } else if (error) {
++ dev_err(&client->dev,
++ "Failed to read channel %u code: %d\n", reg,
++ error);
++ return error;
++ }
+
+ switch (reg) {
+ case IQS269_CHx_HALL_ACTIVE:
+--
+2.39.2
+
--- /dev/null
+From 20f687d958723ae9b25a476d2e9ca9bee1e6a472 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Jan 2023 11:58:59 -0600
+Subject: Input: iqs269a - increase interrupt handler return delay
+
+From: Jeff LaBundy <jeff@labundy.com>
+
+[ Upstream commit e023cc4abde3c01b895660b0e5a8488deb36b8c1 ]
+
+The time the device takes to deassert its RDY output following an
+I2C stop condition scales with the core clock frequency.
+
+To prevent level-triggered interrupts from being reasserted after
+the interrupt handler returns, increase the time before returning
+to account for the worst-case delay (~140 us) plus margin.
+
+Fixes: 04e49867fad1 ("Input: add support for Azoteq IQS269A")
+Signed-off-by: Jeff LaBundy <jeff@labundy.com>
+Reviewed-by: Mattijs Korpershoek <mkorpershoek@baylibre.com>
+Link: https://lore.kernel.org/r/Y7Rs484ypy4dab5G@nixie71
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/input/misc/iqs269a.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/input/misc/iqs269a.c b/drivers/input/misc/iqs269a.c
+index ea3c97c5f764f..ea3401a1000f0 100644
+--- a/drivers/input/misc/iqs269a.c
++++ b/drivers/input/misc/iqs269a.c
+@@ -153,7 +153,7 @@
+ #define IQS269_PWR_MODE_POLL_SLEEP_US IQS269_ATI_POLL_SLEEP_US
+ #define IQS269_PWR_MODE_POLL_TIMEOUT_US IQS269_ATI_POLL_TIMEOUT_US
+
+-#define iqs269_irq_wait() usleep_range(100, 150)
++#define iqs269_irq_wait() usleep_range(200, 250)
+
+ enum iqs269_local_cap_size {
+ IQS269_LOCAL_CAP_SIZE_0,
+--
+2.39.2
+
--- /dev/null
+From 834fde82fa8d31818fb621c00040f2c07917c21c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Jan 2023 12:28:10 +0400
+Subject: irqchip/alpine-msi: Fix refcount leak in alpine_msix_init_domains
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 071d068b89e95d1b078aa6bbcb9d0961b77d6aa1 ]
+
+of_irq_find_parent() returns a node pointer with refcount incremented,
+We should use of_node_put() on it when not needed anymore.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: e6b78f2c3e14 ("irqchip: Add the Alpine MSIX interrupt controller")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20230102082811.3947760-1-linmq006@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/irqchip/irq-alpine-msi.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/irqchip/irq-alpine-msi.c b/drivers/irqchip/irq-alpine-msi.c
+index ede02dc2bcd0b..1819bb1d27230 100644
+--- a/drivers/irqchip/irq-alpine-msi.c
++++ b/drivers/irqchip/irq-alpine-msi.c
+@@ -199,6 +199,7 @@ static int alpine_msix_init_domains(struct alpine_msix_data *priv,
+ }
+
+ gic_domain = irq_find_host(gic_node);
++ of_node_put(gic_node);
+ if (!gic_domain) {
+ pr_err("Failed to find the GIC domain\n");
+ return -ENXIO;
+--
+2.39.2
+
--- /dev/null
+From b15e8574b09a6cfbd3b23c951a7ce557c40a3b57 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Jan 2023 16:13:18 +0400
+Subject: irqchip: Fix refcount leak in platform_irqchip_probe
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 6caa5a2b78f5f53c433d3a3781e53325da22f0ac ]
+
+of_irq_find_parent() returns a node pointer with refcount incremented,
+We should use of_node_put() on it when not needed anymore.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: f8410e626569 ("irqchip: Add IRQCHIP_PLATFORM_DRIVER_BEGIN/END and IRQCHIP_MATCH helper macros")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20230102121318.3990586-1-linmq006@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/irqchip/irqchip.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/irqchip/irqchip.c b/drivers/irqchip/irqchip.c
+index 3570f0a588c4b..7899607fbee8d 100644
+--- a/drivers/irqchip/irqchip.c
++++ b/drivers/irqchip/irqchip.c
+@@ -38,8 +38,10 @@ int platform_irqchip_probe(struct platform_device *pdev)
+ struct device_node *par_np = of_irq_find_parent(np);
+ of_irq_init_cb_t irq_init_cb = of_device_get_match_data(&pdev->dev);
+
+- if (!irq_init_cb)
++ if (!irq_init_cb) {
++ of_node_put(par_np);
+ return -EINVAL;
++ }
+
+ if (par_np == np)
+ par_np = NULL;
+@@ -52,8 +54,10 @@ int platform_irqchip_probe(struct platform_device *pdev)
+ * interrupt controller. The actual initialization callback of this
+ * interrupt controller can check for specific domains as necessary.
+ */
+- if (par_np && !irq_find_matching_host(par_np, DOMAIN_BUS_ANY))
++ if (par_np && !irq_find_matching_host(par_np, DOMAIN_BUS_ANY)) {
++ of_node_put(par_np);
+ return -EPROBE_DEFER;
++ }
+
+ return irq_init_cb(np, par_np);
+ }
+--
+2.39.2
+
--- /dev/null
+From d6007c2ce34ac14682f245e9283603fae5614629 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Dec 2022 15:09:34 -0800
+Subject: irqchip/irq-bcm7120-l2: Set IRQ_LEVEL for level triggered interrupts
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Florian Fainelli <f.fainelli@gmail.com>
+
+[ Upstream commit 13a157b38ca5b4f9eed81442b8821db293755961 ]
+
+When support for the interrupt controller was added with a5042de2688d,
+we forgot to update the flags to be set to contain IRQ_LEVEL. While the
+flow handler is correct, the output from /proc/interrupts does not show
+such interrupts as being level triggered when they are, correct that.
+
+Fixes: a5042de2688d ("irqchip: bcm7120-l2: Add Broadcom BCM7120-style Level 2 interrupt controller")
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20221216230934.2478345-3-f.fainelli@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/irqchip/irq-bcm7120-l2.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/irqchip/irq-bcm7120-l2.c b/drivers/irqchip/irq-bcm7120-l2.c
+index c7c9e976acbb9..7d776c905b7d2 100644
+--- a/drivers/irqchip/irq-bcm7120-l2.c
++++ b/drivers/irqchip/irq-bcm7120-l2.c
+@@ -273,7 +273,8 @@ static int __init bcm7120_l2_intc_probe(struct device_node *dn,
+ flags |= IRQ_GC_BE_IO;
+
+ ret = irq_alloc_domain_generic_chips(data->domain, IRQS_PER_WORD, 1,
+- dn->full_name, handle_level_irq, clr, 0, flags);
++ dn->full_name, handle_level_irq, clr,
++ IRQ_LEVEL, flags);
+ if (ret) {
+ pr_err("failed to allocate generic irq chip\n");
+ goto out_free_domain;
+--
+2.39.2
+
--- /dev/null
+From 6efd3ffbc31cb40a6398c54b203a1e3633b742ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Dec 2022 15:09:33 -0800
+Subject: irqchip/irq-brcmstb-l2: Set IRQ_LEVEL for level triggered interrupts
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Florian Fainelli <f.fainelli@gmail.com>
+
+[ Upstream commit 94debe03e8afa1267f95a9001786a6aa506b9ff3 ]
+
+When support for the level triggered interrupt controller flavor was
+added with c0ca7262088e, we forgot to update the flags to be set to
+contain IRQ_LEVEL. While the flow handler is correct, the output from
+/proc/interrupts does not show such interrupts as being level triggered
+when they are, correct that.
+
+Fixes: c0ca7262088e ("irqchip/brcmstb-l2: Add support for the BCM7271 L2 controller")
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20221216230934.2478345-2-f.fainelli@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/irqchip/irq-brcmstb-l2.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/irqchip/irq-brcmstb-l2.c b/drivers/irqchip/irq-brcmstb-l2.c
+index cdd6a42d4efa4..a4aee16db5314 100644
+--- a/drivers/irqchip/irq-brcmstb-l2.c
++++ b/drivers/irqchip/irq-brcmstb-l2.c
+@@ -161,6 +161,7 @@ static int __init brcmstb_l2_intc_of_init(struct device_node *np,
+ *init_params)
+ {
+ unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
++ unsigned int set = 0;
+ struct brcmstb_l2_intc_data *data;
+ struct irq_chip_type *ct;
+ int ret;
+@@ -208,9 +209,12 @@ static int __init brcmstb_l2_intc_of_init(struct device_node *np,
+ if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
+ flags |= IRQ_GC_BE_IO;
+
++ if (init_params->handler == handle_level_irq)
++ set |= IRQ_LEVEL;
++
+ /* Allocate a single Generic IRQ chip for this node */
+ ret = irq_alloc_domain_generic_chips(data->domain, 32, 1,
+- np->full_name, init_params->handler, clr, 0, flags);
++ np->full_name, init_params->handler, clr, set, flags);
+ if (ret) {
+ pr_err("failed to allocate generic irq chip\n");
+ goto out_free_domain;
+--
+2.39.2
+
--- /dev/null
+From e22455db15ff197c620ee0f67208d4da281ba395 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Jan 2023 12:42:08 +0400
+Subject: irqchip/irq-mvebu-gicp: Fix refcount leak in mvebu_gicp_probe
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 9419e700021a393f67be36abd0c4f3acc6139041 ]
+
+of_irq_find_parent() returns a node pointer with refcount incremented,
+We should use of_node_put() on it when not needed anymore.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: a68a63cb4dfc ("irqchip/irq-mvebu-gicp: Add new driver for Marvell GICP")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20230102084208.3951758-1-linmq006@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/irqchip/irq-mvebu-gicp.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/irqchip/irq-mvebu-gicp.c b/drivers/irqchip/irq-mvebu-gicp.c
+index 3be5c5dba1dab..5caec411059f5 100644
+--- a/drivers/irqchip/irq-mvebu-gicp.c
++++ b/drivers/irqchip/irq-mvebu-gicp.c
+@@ -223,6 +223,7 @@ static int mvebu_gicp_probe(struct platform_device *pdev)
+ }
+
+ parent_domain = irq_find_host(irq_parent_dn);
++ of_node_put(irq_parent_dn);
+ if (!parent_domain) {
+ dev_err(&pdev->dev, "failed to find parent IRQ domain\n");
+ return -ENODEV;
+--
+2.39.2
+
--- /dev/null
+From 3169cdbd98650eef0b8709cade9ed4513e317ed5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Jan 2023 12:56:10 +0400
+Subject: irqchip/ti-sci: Fix refcount leak in ti_sci_intr_irq_domain_probe
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 02298b7bae12936ca313975b02e7f98b06670d37 ]
+
+of_irq_find_parent() returns a node pointer with refcount incremented,
+We should use of_node_put() on it when not needed anymore.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: cd844b0715ce ("irqchip/ti-sci-intr: Add support for Interrupt Router driver")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20230102085611.3955984-1-linmq006@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/irqchip/irq-ti-sci-intr.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/irqchip/irq-ti-sci-intr.c b/drivers/irqchip/irq-ti-sci-intr.c
+index fe8fad22bcf96..020ddf29efb80 100644
+--- a/drivers/irqchip/irq-ti-sci-intr.c
++++ b/drivers/irqchip/irq-ti-sci-intr.c
+@@ -236,6 +236,7 @@ static int ti_sci_intr_irq_domain_probe(struct platform_device *pdev)
+ }
+
+ parent_domain = irq_find_host(parent_node);
++ of_node_put(parent_node);
+ if (!parent_domain) {
+ dev_err(dev, "Failed to find IRQ parent domain\n");
+ return -ENODEV;
+--
+2.39.2
+
--- /dev/null
+From 6eb8547aa792e065491a2de21ead08e7313572c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Feb 2023 01:37:10 +0900
+Subject: l2tp: Avoid possible recursive deadlock in l2tp_tunnel_register()
+
+From: Shigeru Yoshida <syoshida@redhat.com>
+
+[ Upstream commit 9ca5e7ecab064f1f47da07f7c1ddf40e4bc0e5ac ]
+
+When a file descriptor of pppol2tp socket is passed as file descriptor
+of UDP socket, a recursive deadlock occurs in l2tp_tunnel_register().
+This situation is reproduced by the following program:
+
+int main(void)
+{
+ int sock;
+ struct sockaddr_pppol2tp addr;
+
+ sock = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OL2TP);
+ if (sock < 0) {
+ perror("socket");
+ return 1;
+ }
+
+ addr.sa_family = AF_PPPOX;
+ addr.sa_protocol = PX_PROTO_OL2TP;
+ addr.pppol2tp.pid = 0;
+ addr.pppol2tp.fd = sock;
+ addr.pppol2tp.addr.sin_family = PF_INET;
+ addr.pppol2tp.addr.sin_port = htons(0);
+ addr.pppol2tp.addr.sin_addr.s_addr = inet_addr("192.168.0.1");
+ addr.pppol2tp.s_tunnel = 1;
+ addr.pppol2tp.s_session = 0;
+ addr.pppol2tp.d_tunnel = 0;
+ addr.pppol2tp.d_session = 0;
+
+ if (connect(sock, (const struct sockaddr *)&addr, sizeof(addr)) < 0) {
+ perror("connect");
+ return 1;
+ }
+
+ return 0;
+}
+
+This program causes the following lockdep warning:
+
+ ============================================
+ WARNING: possible recursive locking detected
+ 6.2.0-rc5-00205-gc96618275234 #56 Not tainted
+ --------------------------------------------
+ repro/8607 is trying to acquire lock:
+ ffff8880213c8130 (sk_lock-AF_PPPOX){+.+.}-{0:0}, at: l2tp_tunnel_register+0x2b7/0x11c0
+
+ but task is already holding lock:
+ ffff8880213c8130 (sk_lock-AF_PPPOX){+.+.}-{0:0}, at: pppol2tp_connect+0xa82/0x1a30
+
+ other info that might help us debug this:
+ Possible unsafe locking scenario:
+
+ CPU0
+ ----
+ lock(sk_lock-AF_PPPOX);
+ lock(sk_lock-AF_PPPOX);
+
+ *** DEADLOCK ***
+
+ May be due to missing lock nesting notation
+
+ 1 lock held by repro/8607:
+ #0: ffff8880213c8130 (sk_lock-AF_PPPOX){+.+.}-{0:0}, at: pppol2tp_connect+0xa82/0x1a30
+
+ stack backtrace:
+ CPU: 0 PID: 8607 Comm: repro Not tainted 6.2.0-rc5-00205-gc96618275234 #56
+ Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.1-2.fc37 04/01/2014
+ Call Trace:
+ <TASK>
+ dump_stack_lvl+0x100/0x178
+ __lock_acquire.cold+0x119/0x3b9
+ ? lockdep_hardirqs_on_prepare+0x410/0x410
+ lock_acquire+0x1e0/0x610
+ ? l2tp_tunnel_register+0x2b7/0x11c0
+ ? lock_downgrade+0x710/0x710
+ ? __fget_files+0x283/0x3e0
+ lock_sock_nested+0x3a/0xf0
+ ? l2tp_tunnel_register+0x2b7/0x11c0
+ l2tp_tunnel_register+0x2b7/0x11c0
+ ? sprintf+0xc4/0x100
+ ? l2tp_tunnel_del_work+0x6b0/0x6b0
+ ? debug_object_deactivate+0x320/0x320
+ ? lockdep_init_map_type+0x16d/0x7a0
+ ? lockdep_init_map_type+0x16d/0x7a0
+ ? l2tp_tunnel_create+0x2bf/0x4b0
+ ? l2tp_tunnel_create+0x3c6/0x4b0
+ pppol2tp_connect+0x14e1/0x1a30
+ ? pppol2tp_put_sk+0xd0/0xd0
+ ? aa_sk_perm+0x2b7/0xa80
+ ? aa_af_perm+0x260/0x260
+ ? bpf_lsm_socket_connect+0x9/0x10
+ ? pppol2tp_put_sk+0xd0/0xd0
+ __sys_connect_file+0x14f/0x190
+ __sys_connect+0x133/0x160
+ ? __sys_connect_file+0x190/0x190
+ ? lockdep_hardirqs_on+0x7d/0x100
+ ? ktime_get_coarse_real_ts64+0x1b7/0x200
+ ? ktime_get_coarse_real_ts64+0x147/0x200
+ ? __audit_syscall_entry+0x396/0x500
+ __x64_sys_connect+0x72/0xb0
+ do_syscall_64+0x38/0xb0
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+This patch fixes the issue by getting/creating the tunnel before
+locking the pppol2tp socket.
+
+Fixes: 0b2c59720e65 ("l2tp: close all race conditions in l2tp_tunnel_register()")
+Cc: Cong Wang <cong.wang@bytedance.com>
+Signed-off-by: Shigeru Yoshida <syoshida@redhat.com>
+Reviewed-by: Guillaume Nault <gnault@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/l2tp/l2tp_ppp.c | 125 ++++++++++++++++++++++++--------------------
+ 1 file changed, 67 insertions(+), 58 deletions(-)
+
+diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
+index aea85f91f0599..5ecc0f2009444 100644
+--- a/net/l2tp/l2tp_ppp.c
++++ b/net/l2tp/l2tp_ppp.c
+@@ -651,54 +651,22 @@ static int pppol2tp_tunnel_mtu(const struct l2tp_tunnel *tunnel)
+ return mtu - PPPOL2TP_HEADER_OVERHEAD;
+ }
+
+-/* connect() handler. Attach a PPPoX socket to a tunnel UDP socket
+- */
+-static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
+- int sockaddr_len, int flags)
++static struct l2tp_tunnel *pppol2tp_tunnel_get(struct net *net,
++ const struct l2tp_connect_info *info,
++ bool *new_tunnel)
+ {
+- struct sock *sk = sock->sk;
+- struct pppox_sock *po = pppox_sk(sk);
+- struct l2tp_session *session = NULL;
+- struct l2tp_connect_info info;
+ struct l2tp_tunnel *tunnel;
+- struct pppol2tp_session *ps;
+- struct l2tp_session_cfg cfg = { 0, };
+- bool drop_refcnt = false;
+- bool drop_tunnel = false;
+- bool new_session = false;
+- bool new_tunnel = false;
+ int error;
+
+- error = pppol2tp_sockaddr_get_info(uservaddr, sockaddr_len, &info);
+- if (error < 0)
+- return error;
++ *new_tunnel = false;
+
+- lock_sock(sk);
+-
+- /* Check for already bound sockets */
+- error = -EBUSY;
+- if (sk->sk_state & PPPOX_CONNECTED)
+- goto end;
+-
+- /* We don't supporting rebinding anyway */
+- error = -EALREADY;
+- if (sk->sk_user_data)
+- goto end; /* socket is already attached */
+-
+- /* Don't bind if tunnel_id is 0 */
+- error = -EINVAL;
+- if (!info.tunnel_id)
+- goto end;
+-
+- tunnel = l2tp_tunnel_get(sock_net(sk), info.tunnel_id);
+- if (tunnel)
+- drop_tunnel = true;
++ tunnel = l2tp_tunnel_get(net, info->tunnel_id);
+
+ /* Special case: create tunnel context if session_id and
+ * peer_session_id is 0. Otherwise look up tunnel using supplied
+ * tunnel id.
+ */
+- if (!info.session_id && !info.peer_session_id) {
++ if (!info->session_id && !info->peer_session_id) {
+ if (!tunnel) {
+ struct l2tp_tunnel_cfg tcfg = {
+ .encap = L2TP_ENCAPTYPE_UDP,
+@@ -707,40 +675,82 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
+ /* Prevent l2tp_tunnel_register() from trying to set up
+ * a kernel socket.
+ */
+- if (info.fd < 0) {
+- error = -EBADF;
+- goto end;
+- }
++ if (info->fd < 0)
++ return ERR_PTR(-EBADF);
+
+- error = l2tp_tunnel_create(info.fd,
+- info.version,
+- info.tunnel_id,
+- info.peer_tunnel_id, &tcfg,
++ error = l2tp_tunnel_create(info->fd,
++ info->version,
++ info->tunnel_id,
++ info->peer_tunnel_id, &tcfg,
+ &tunnel);
+ if (error < 0)
+- goto end;
++ return ERR_PTR(error);
+
+ l2tp_tunnel_inc_refcount(tunnel);
+- error = l2tp_tunnel_register(tunnel, sock_net(sk),
+- &tcfg);
++ error = l2tp_tunnel_register(tunnel, net, &tcfg);
+ if (error < 0) {
+ kfree(tunnel);
+- goto end;
++ return ERR_PTR(error);
+ }
+- drop_tunnel = true;
+- new_tunnel = true;
++
++ *new_tunnel = true;
+ }
+ } else {
+ /* Error if we can't find the tunnel */
+- error = -ENOENT;
+ if (!tunnel)
+- goto end;
++ return ERR_PTR(-ENOENT);
+
+ /* Error if socket is not prepped */
+- if (!tunnel->sock)
+- goto end;
++ if (!tunnel->sock) {
++ l2tp_tunnel_dec_refcount(tunnel);
++ return ERR_PTR(-ENOENT);
++ }
+ }
+
++ return tunnel;
++}
++
++/* connect() handler. Attach a PPPoX socket to a tunnel UDP socket
++ */
++static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
++ int sockaddr_len, int flags)
++{
++ struct sock *sk = sock->sk;
++ struct pppox_sock *po = pppox_sk(sk);
++ struct l2tp_session *session = NULL;
++ struct l2tp_connect_info info;
++ struct l2tp_tunnel *tunnel;
++ struct pppol2tp_session *ps;
++ struct l2tp_session_cfg cfg = { 0, };
++ bool drop_refcnt = false;
++ bool new_session = false;
++ bool new_tunnel = false;
++ int error;
++
++ error = pppol2tp_sockaddr_get_info(uservaddr, sockaddr_len, &info);
++ if (error < 0)
++ return error;
++
++ /* Don't bind if tunnel_id is 0 */
++ if (!info.tunnel_id)
++ return -EINVAL;
++
++ tunnel = pppol2tp_tunnel_get(sock_net(sk), &info, &new_tunnel);
++ if (IS_ERR(tunnel))
++ return PTR_ERR(tunnel);
++
++ lock_sock(sk);
++
++ /* Check for already bound sockets */
++ error = -EBUSY;
++ if (sk->sk_state & PPPOX_CONNECTED)
++ goto end;
++
++ /* We don't supporting rebinding anyway */
++ error = -EALREADY;
++ if (sk->sk_user_data)
++ goto end; /* socket is already attached */
++
+ if (tunnel->peer_tunnel_id == 0)
+ tunnel->peer_tunnel_id = info.peer_tunnel_id;
+
+@@ -841,8 +851,7 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
+ }
+ if (drop_refcnt)
+ l2tp_session_dec_refcount(session);
+- if (drop_tunnel)
+- l2tp_tunnel_dec_refcount(tunnel);
++ l2tp_tunnel_dec_refcount(tunnel);
+ release_sock(sk);
+
+ return error;
+--
+2.39.2
+
--- /dev/null
+From 383ea7ba8c9904402d226d7868a63a17e9f35ccf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Jan 2023 12:45:14 +0100
+Subject: leds: led-class: Add missing put_device() to led_put()
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 445110941eb94709216363f9d807d2508e64abd7 ]
+
+led_put() is used to "undo" a successful of_led_get() call,
+of_led_get() uses class_find_device_by_of_node() which returns
+a reference to the device which must be free-ed with put_device()
+when the caller is done with it.
+
+Add a put_device() call to led_put() to free the reference returned
+by class_find_device_by_of_node().
+
+And also add a put_device() in the error-exit case of try_module_get()
+failing.
+
+Fixes: 699a8c7c4bd3 ("leds: Add of_led_get() and led_put()")
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Lee Jones <lee@kernel.org>
+Link: https://lore.kernel.org/r/20230120114524.408368-2-hdegoede@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/leds/led-class.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c
+index 4365c1cc4505f..e28a4bb716032 100644
+--- a/drivers/leds/led-class.c
++++ b/drivers/leds/led-class.c
+@@ -242,8 +242,10 @@ struct led_classdev *of_led_get(struct device_node *np, int index)
+
+ led_cdev = dev_get_drvdata(led_dev);
+
+- if (!try_module_get(led_cdev->dev->parent->driver->owner))
++ if (!try_module_get(led_cdev->dev->parent->driver->owner)) {
++ put_device(led_cdev->dev);
+ return ERR_PTR(-ENODEV);
++ }
+
+ return led_cdev;
+ }
+@@ -256,6 +258,7 @@ EXPORT_SYMBOL_GPL(of_led_get);
+ void led_put(struct led_classdev *led_cdev)
+ {
+ module_put(led_cdev->dev->parent->driver->owner);
++ put_device(led_cdev->dev);
+ }
+ EXPORT_SYMBOL_GPL(led_put);
+
+--
+2.39.2
+
--- /dev/null
+From 8fde334c9a530b575647439465ce4e8894365440 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Dec 2022 16:18:07 +0400
+Subject: leds: led-core: Fix refcount leak in of_led_get()
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit da1afe8e6099980fe1e2fd7436dca284af9d3f29 ]
+
+class_find_device_by_of_node() calls class_find_device(), it will take
+the reference, use the put_device() to drop the reference when not need
+anymore.
+
+Fixes: 699a8c7c4bd3 ("leds: Add of_led_get() and led_put()")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Signed-off-by: Lee Jones <lee@kernel.org>
+Link: https://lore.kernel.org/r/20221220121807.1543790-1-linmq006@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/leds/led-class.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c
+index e28a4bb716032..fcb9eee3b6097 100644
+--- a/drivers/leds/led-class.c
++++ b/drivers/leds/led-class.c
+@@ -236,6 +236,7 @@ struct led_classdev *of_led_get(struct device_node *np, int index)
+
+ led_dev = class_find_device_by_of_node(leds_class, led_node);
+ of_node_put(led_node);
++ put_device(led_dev);
+
+ if (!led_dev)
+ return ERR_PTR(-EPROBE_DEFER);
+--
+2.39.2
+
--- /dev/null
+From 4fb9b977015c39ed1d7c4d2a60811bc6eba1617c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Dec 2022 15:27:39 +0100
+Subject: lib/mpi: Fix buffer overrun when SG is too long
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+[ Upstream commit 7361d1bc307b926cbca214ab67b641123c2d6357 ]
+
+The helper mpi_read_raw_from_sgl sets the number of entries in
+the SG list according to nbytes. However, if the last entry
+in the SG list contains more data than nbytes, then it may overrun
+the buffer because it only allocates enough memory for nbytes.
+
+Fixes: 2d4d1eea540b ("lib/mpi: Add mpi sgl helpers")
+Reported-by: Roberto Sassu <roberto.sassu@huaweicloud.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Reviewed-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/mpi/mpicoder.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/lib/mpi/mpicoder.c b/lib/mpi/mpicoder.c
+index 7ea225b2204fa..7054311d78792 100644
+--- a/lib/mpi/mpicoder.c
++++ b/lib/mpi/mpicoder.c
+@@ -504,7 +504,8 @@ MPI mpi_read_raw_from_sgl(struct scatterlist *sgl, unsigned int nbytes)
+
+ while (sg_miter_next(&miter)) {
+ buff = miter.addr;
+- len = miter.length;
++ len = min_t(unsigned, miter.length, nbytes);
++ nbytes -= len;
+
+ for (x = 0; x < len; x++) {
+ a <<= 8;
+--
+2.39.2
+
--- /dev/null
+From b5c54ae85852ffbba5a3d9808f8f2e0c67bb7b29 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Feb 2023 01:12:01 +0100
+Subject: libbpf: Fix alen calculation in libbpf_nla_dump_errormsg()
+
+From: Ilya Leoshkevich <iii@linux.ibm.com>
+
+[ Upstream commit 17bcd27a08a21397698edf143084d7c87ce17946 ]
+
+The code assumes that everything that comes after nlmsgerr are nlattrs.
+When calculating their size, it does not account for the initial
+nlmsghdr. This may lead to accessing uninitialized memory.
+
+Fixes: bbf48c18ee0c ("libbpf: add error reporting in XDP")
+Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/20230210001210.395194-8-iii@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/nlattr.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/lib/bpf/nlattr.c b/tools/lib/bpf/nlattr.c
+index b607fa9852b1c..1a04299a2a604 100644
+--- a/tools/lib/bpf/nlattr.c
++++ b/tools/lib/bpf/nlattr.c
+@@ -178,7 +178,7 @@ int libbpf_nla_dump_errormsg(struct nlmsghdr *nlh)
+ hlen += nlmsg_len(&err->msg);
+
+ attr = (struct nlattr *) ((void *) err + hlen);
+- alen = nlh->nlmsg_len - hlen;
++ alen = (void *)nlh + nlh->nlmsg_len - (void *)attr;
+
+ if (libbpf_nla_parse(tb, NLMSGERR_ATTR_MAX, attr, alen,
+ extack_policy) != 0) {
+--
+2.39.2
+
--- /dev/null
+From 42b245a6404acfe4b4e32a67fffcb1e93af88305 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 Dec 2022 13:15:03 -0800
+Subject: libbpf: Fix btf__align_of() by taking into account field offsets
+
+From: Andrii Nakryiko <andrii@kernel.org>
+
+[ Upstream commit 25a4481b4136af7794e1df2d6c90ed2f354d60ce ]
+
+btf__align_of() is supposed to be return alignment requirement of
+a requested BTF type. For STRUCT/UNION it doesn't always return correct
+value, because it calculates alignment only based on field types. But
+for packed structs this is not enough, we need to also check field
+offsets and struct size. If field offset isn't aligned according to
+field type's natural alignment, then struct must be packed. Similarly,
+if struct size is not a multiple of struct's natural alignment, then
+struct must be packed as well.
+
+This patch fixes this issue precisely by additionally checking these
+conditions.
+
+Fixes: 3d208f4ca111 ("libbpf: Expose btf__align_of() API")
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Link: https://lore.kernel.org/bpf/20221212211505.558851-5-andrii@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/btf.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c
+index e6f644cdc9f15..f7c48b1fb3a05 100644
+--- a/tools/lib/bpf/btf.c
++++ b/tools/lib/bpf/btf.c
+@@ -614,8 +614,21 @@ int btf__align_of(const struct btf *btf, __u32 id)
+ if (align <= 0)
+ return align;
+ max_align = max(max_align, align);
++
++ /* if field offset isn't aligned according to field
++ * type's alignment, then struct must be packed
++ */
++ if (btf_member_bitfield_size(t, i) == 0 &&
++ (m->offset % (8 * align)) != 0)
++ return 1;
+ }
+
++ /* if struct/union size isn't a multiple of its alignment,
++ * then struct must be packed
++ */
++ if ((t->size % max_align) != 0)
++ return 1;
++
+ return max_align;
+ }
+ default:
+--
+2.39.2
+
--- /dev/null
+From 6a7364ec871e567433a4402c29b2070598742226 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 May 2021 02:45:15 +0900
+Subject: linux/kconfig.h: replace IF_ENABLED() with PTR_IF() in
+ <linux/kernel.h>
+
+From: Masahiro Yamada <masahiroy@kernel.org>
+
+[ Upstream commit 0ab1438bad43d95877f848b7df551bd431680270 ]
+
+<linux/kconfig.h> is included from all the kernel-space source files,
+including C, assembly, linker scripts. It is intended to contain a
+minimal set of macros to evaluate CONFIG options.
+
+IF_ENABLED() is an intruder here because (x ? y : z) is C code, which
+should not be included from assembly files or linker scripts.
+
+Also, <linux/kconfig.h> is no longer self-contained because NULL is
+defined in <linux/stddef.h>.
+
+Move IF_ENABLED() out to <linux/kernel.h> as PTR_IF(). PTF_IF()
+takes the general boolean expression instead of a CONFIG option
+so that it fits better in <linux/kernel.h>.
+
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Stable-dep-of: 18ab69c8ca56 ("Input: iqs269a - do not poll during suspend or resume")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/pinctrl-ingenic.c | 3 +++
+ include/linux/kernel.h | 2 ++
+ 2 files changed, 5 insertions(+)
+
+diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c
+index e0df5ad6741dc..4d07c531371cd 100644
+--- a/drivers/pinctrl/pinctrl-ingenic.c
++++ b/drivers/pinctrl/pinctrl-ingenic.c
+@@ -11,6 +11,7 @@
+ #include <linux/gpio/driver.h>
+ #include <linux/interrupt.h>
+ #include <linux/io.h>
++#include <linux/kernel.h>
+ #include <linux/of_device.h>
+ #include <linux/of_irq.h>
+ #include <linux/of_platform.h>
+@@ -2826,6 +2827,8 @@ static int __init ingenic_pinctrl_probe(struct platform_device *pdev)
+ return 0;
+ }
+
++#define IF_ENABLED(cfg, ptr) PTR_IF(IS_ENABLED(cfg), (ptr))
++
+ static const struct of_device_id ingenic_pinctrl_of_match[] = {
+ { .compatible = "ingenic,jz4740-pinctrl", .data = &jz4740_chip_info },
+ { .compatible = "ingenic,jz4725b-pinctrl", .data = &jz4725b_chip_info },
+diff --git a/include/linux/kernel.h b/include/linux/kernel.h
+index 394f10fc29aad..66948e1bf4fa6 100644
+--- a/include/linux/kernel.h
++++ b/include/linux/kernel.h
+@@ -47,6 +47,8 @@
+ */
+ #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
+
++#define PTR_IF(cond, ptr) ((cond) ? (ptr) : NULL)
++
+ #define u64_to_user_ptr(x) ( \
+ { \
+ typecheck(u64, (x)); \
+--
+2.39.2
+
--- /dev/null
+From 898966ed54b9d1cea8b8e1ebf65c825f133d12bb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Jan 2023 16:55:27 +1300
+Subject: m68k: Check syscall_trace_enter() return code
+
+From: Michael Schmitz <schmitzmic@gmail.com>
+
+[ Upstream commit 2ca8a1de4437f21562e57f9ac123914747a8e7a1 ]
+
+Check return code of syscall_trace_enter(), and skip syscall
+if -1. Return code will be left at what had been set by
+ptrace or seccomp (in regs->d0).
+
+No regression seen in testing with strace on ARAnyM.
+
+Signed-off-by: Michael Schmitz <schmitzmic@gmail.com>
+Reviewed-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Link: https://lore.kernel.org/r/20230112035529.13521-2-schmitzmic@gmail.com
+Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/m68k/68000/entry.S | 2 ++
+ arch/m68k/coldfire/entry.S | 2 ++
+ arch/m68k/kernel/entry.S | 3 +++
+ 3 files changed, 7 insertions(+)
+
+diff --git a/arch/m68k/68000/entry.S b/arch/m68k/68000/entry.S
+index 259b3661b6141..94abf3d8afc52 100644
+--- a/arch/m68k/68000/entry.S
++++ b/arch/m68k/68000/entry.S
+@@ -47,6 +47,8 @@ do_trace:
+ jbsr syscall_trace_enter
+ RESTORE_SWITCH_STACK
+ addql #4,%sp
++ addql #1,%d0
++ jeq ret_from_exception
+ movel %sp@(PT_OFF_ORIG_D0),%d1
+ movel #-ENOSYS,%d0
+ cmpl #NR_syscalls,%d1
+diff --git a/arch/m68k/coldfire/entry.S b/arch/m68k/coldfire/entry.S
+index d43a02795a4a4..f1d41a9328a27 100644
+--- a/arch/m68k/coldfire/entry.S
++++ b/arch/m68k/coldfire/entry.S
+@@ -92,6 +92,8 @@ ENTRY(system_call)
+ jbsr syscall_trace_enter
+ RESTORE_SWITCH_STACK
+ addql #4,%sp
++ addql #1,%d0
++ jeq ret_from_exception
+ movel %d3,%a0
+ jbsr %a0@
+ movel %d0,%sp@(PT_OFF_D0) /* save the return value */
+diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S
+index 9dd76fbb7c6b2..546bab6bfc273 100644
+--- a/arch/m68k/kernel/entry.S
++++ b/arch/m68k/kernel/entry.S
+@@ -167,9 +167,12 @@ do_trace_entry:
+ jbsr syscall_trace
+ RESTORE_SWITCH_STACK
+ addql #4,%sp
++ addql #1,%d0 | optimization for cmpil #-1,%d0
++ jeq ret_from_syscall
+ movel %sp@(PT_OFF_ORIG_D0),%d0
+ cmpl #NR_syscalls,%d0
+ jcs syscall
++ jra ret_from_syscall
+ badsys:
+ movel #-ENOSYS,%sp@(PT_OFF_D0)
+ jra ret_from_syscall
+--
+2.39.2
+
--- /dev/null
+From 0fbd946cb86652c6646354939e4381270d1ebae1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Feb 2023 17:08:25 -0800
+Subject: m68k: /proc/hardware should depend on PROC_FS
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit 1e5b5df65af99013b4d31607ddb3ca5731dbe44d ]
+
+When CONFIG_PROC_FS is not set, there is a build error for an unused
+function. Make PROC_HARDWARE depend on PROC_FS to prevent this error.
+
+In file included from ../arch/m68k/kernel/setup.c:3:
+../arch/m68k/kernel/setup_mm.c:477:12: error: 'hardware_proc_show' defined but not used [-Werror=unused-function]
+ 477 | static int hardware_proc_show(struct seq_file *m, void *v)
+ | ^~~~~~~~~~~~~~~~~~
+
+Fixes: 66d857b08b8c ("m68k: merge m68k and m68knommu arch directories") # v3.0
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Reviewed-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Link: https://lore.kernel.org/r/20230209010825.24136-1-rdunlap@infradead.org
+Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/m68k/Kconfig.devices | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/m68k/Kconfig.devices b/arch/m68k/Kconfig.devices
+index 6a87b4a5fcac2..e6e3efac18407 100644
+--- a/arch/m68k/Kconfig.devices
++++ b/arch/m68k/Kconfig.devices
+@@ -19,6 +19,7 @@ config HEARTBEAT
+ # We have a dedicated heartbeat LED. :-)
+ config PROC_HARDWARE
+ bool "/proc/hardware support"
++ depends on PROC_FS
+ help
+ Say Y here to support the /proc/hardware file, which gives you
+ access to information about the machine you're running on,
+--
+2.39.2
+
--- /dev/null
+From 98ee56bbc4b333cd5bbcee2c496772c33a572651 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Jan 2023 09:16:23 +0100
+Subject: media: i2c: imx219: Fix binning for RAW8 capture
+
+From: Jai Luthra <j-luthra@ti.com>
+
+[ Upstream commit ef86447e775fb1f2ced00d4c7fff2c0a1c63f165 ]
+
+2x2 binning works fine for RAW10 capture, but for RAW8 1232p mode it
+leads to corrupted frames [1][2].
+
+Using the special 2x2 analog binning mode fixes the issue, but causes
+artefacts for RAW10 1232p capture. So here we choose the binning mode
+depending upon the frame format selected.
+
+As both binning modes work fine for 480p RAW8 and RAW10 capture, it can
+share the same code path as 1232p for selecting binning mode.
+
+[1] https://forums.raspberrypi.com/viewtopic.php?t=332103
+[2] https://github.com/raspberrypi/libcamera-apps/issues/281
+
+Fixes: 22da1d56e982 ("media: i2c: imx219: Add support for RAW8 bit bayer format")
+Signed-off-by: Jai Luthra <j-luthra@ti.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/imx219.c | 57 ++++++++++++++++++++++++++++++++------
+ 1 file changed, 49 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c
+index a28926069b82b..b975636d94401 100644
+--- a/drivers/media/i2c/imx219.c
++++ b/drivers/media/i2c/imx219.c
+@@ -89,6 +89,12 @@
+
+ #define IMX219_REG_ORIENTATION 0x0172
+
++/* Binning Mode */
++#define IMX219_REG_BINNING_MODE 0x0174
++#define IMX219_BINNING_NONE 0x0000
++#define IMX219_BINNING_2X2 0x0101
++#define IMX219_BINNING_2X2_ANALOG 0x0303
++
+ /* Test Pattern Control */
+ #define IMX219_REG_TEST_PATTERN 0x0600
+ #define IMX219_TEST_PATTERN_DISABLE 0
+@@ -143,6 +149,9 @@ struct imx219_mode {
+
+ /* Default register values */
+ struct imx219_reg_list reg_list;
++
++ /* 2x2 binning is used */
++ bool binning;
+ };
+
+ static const struct imx219_reg imx219_common_regs[] = {
+@@ -212,8 +221,6 @@ static const struct imx219_reg mode_3280x2464_regs[] = {
+ {0x016d, 0xd0},
+ {0x016e, 0x09},
+ {0x016f, 0xa0},
+- {0x0174, 0x00}, /* No-Binning */
+- {0x0175, 0x00},
+ {0x0624, 0x0c},
+ {0x0625, 0xd0},
+ {0x0626, 0x09},
+@@ -233,8 +240,6 @@ static const struct imx219_reg mode_1920_1080_regs[] = {
+ {0x016d, 0x80},
+ {0x016e, 0x04},
+ {0x016f, 0x38},
+- {0x0174, 0x00}, /* No-Binning */
+- {0x0175, 0x00},
+ {0x0624, 0x07},
+ {0x0625, 0x80},
+ {0x0626, 0x04},
+@@ -254,8 +259,6 @@ static const struct imx219_reg mode_1640_1232_regs[] = {
+ {0x016d, 0x68},
+ {0x016e, 0x04},
+ {0x016f, 0xd0},
+- {0x0174, 0x01}, /* x2-Binning */
+- {0x0175, 0x01},
+ {0x0624, 0x06},
+ {0x0625, 0x68},
+ {0x0626, 0x04},
+@@ -275,8 +278,6 @@ static const struct imx219_reg mode_640_480_regs[] = {
+ {0x016d, 0x80},
+ {0x016e, 0x01},
+ {0x016f, 0xe0},
+- {0x0174, 0x03}, /* x2-analog binning */
+- {0x0175, 0x03},
+ {0x0624, 0x06},
+ {0x0625, 0x68},
+ {0x0626, 0x04},
+@@ -386,6 +387,7 @@ static const struct imx219_mode supported_modes[] = {
+ .num_of_regs = ARRAY_SIZE(mode_3280x2464_regs),
+ .regs = mode_3280x2464_regs,
+ },
++ .binning = false,
+ },
+ {
+ /* 1080P 30fps cropped */
+@@ -402,6 +404,7 @@ static const struct imx219_mode supported_modes[] = {
+ .num_of_regs = ARRAY_SIZE(mode_1920_1080_regs),
+ .regs = mode_1920_1080_regs,
+ },
++ .binning = false,
+ },
+ {
+ /* 2x2 binned 30fps mode */
+@@ -418,6 +421,7 @@ static const struct imx219_mode supported_modes[] = {
+ .num_of_regs = ARRAY_SIZE(mode_1640_1232_regs),
+ .regs = mode_1640_1232_regs,
+ },
++ .binning = true,
+ },
+ {
+ /* 640x480 30fps mode */
+@@ -434,6 +438,7 @@ static const struct imx219_mode supported_modes[] = {
+ .num_of_regs = ARRAY_SIZE(mode_640_480_regs),
+ .regs = mode_640_480_regs,
+ },
++ .binning = true,
+ },
+ };
+
+@@ -872,6 +877,35 @@ static int imx219_set_framefmt(struct imx219 *imx219)
+ return -EINVAL;
+ }
+
++static int imx219_set_binning(struct imx219 *imx219)
++{
++ if (!imx219->mode->binning) {
++ return imx219_write_reg(imx219, IMX219_REG_BINNING_MODE,
++ IMX219_REG_VALUE_16BIT,
++ IMX219_BINNING_NONE);
++ }
++
++ switch (imx219->fmt.code) {
++ case MEDIA_BUS_FMT_SRGGB8_1X8:
++ case MEDIA_BUS_FMT_SGRBG8_1X8:
++ case MEDIA_BUS_FMT_SGBRG8_1X8:
++ case MEDIA_BUS_FMT_SBGGR8_1X8:
++ return imx219_write_reg(imx219, IMX219_REG_BINNING_MODE,
++ IMX219_REG_VALUE_16BIT,
++ IMX219_BINNING_2X2_ANALOG);
++
++ case MEDIA_BUS_FMT_SRGGB10_1X10:
++ case MEDIA_BUS_FMT_SGRBG10_1X10:
++ case MEDIA_BUS_FMT_SGBRG10_1X10:
++ case MEDIA_BUS_FMT_SBGGR10_1X10:
++ return imx219_write_reg(imx219, IMX219_REG_BINNING_MODE,
++ IMX219_REG_VALUE_16BIT,
++ IMX219_BINNING_2X2);
++ }
++
++ return -EINVAL;
++}
++
+ static const struct v4l2_rect *
+ __imx219_get_pad_crop(struct imx219 *imx219, struct v4l2_subdev_pad_config *cfg,
+ unsigned int pad, enum v4l2_subdev_format_whence which)
+@@ -957,6 +991,13 @@ static int imx219_start_streaming(struct imx219 *imx219)
+ goto err_rpm_put;
+ }
+
++ ret = imx219_set_binning(imx219);
++ if (ret) {
++ dev_err(&client->dev, "%s failed to set binning: %d\n",
++ __func__, ret);
++ goto err_rpm_put;
++ }
++
+ /* Apply customized values from user */
+ ret = __v4l2_ctrl_handler_setup(imx219->sd.ctrl_handler);
+ if (ret)
+--
+2.39.2
+
--- /dev/null
+From 416c6537efe21fa70d7601f2a8e69c7f87ce0752 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Apr 2020 17:51:47 +0200
+Subject: media: i2c: imx219: remove redundant writes
+
+From: Sameer Puri <purisame@spuri.io>
+
+[ Upstream commit fbef89886da6d7735d20fdde16a1ee6ed6c6ab56 ]
+
+These writes to 0x162, 0x163 already appear earlier in the struct for
+the 1920x1080 mode and do not need to be repeated.
+
+Signed-off-by: Sameer Puri <purisame@spuri.io>
+Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Stable-dep-of: ef86447e775f ("media: i2c: imx219: Fix binning for RAW8 capture")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/i2c/imx219.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c
+index 4771d0ef2c46f..cad0a8df203ed 100644
+--- a/drivers/media/i2c/imx219.c
++++ b/drivers/media/i2c/imx219.c
+@@ -262,8 +262,6 @@ static const struct imx219_reg mode_1920_1080_regs[] = {
+ {0x4793, 0x10},
+ {0x4797, 0x0e},
+ {0x479b, 0x0e},
+- {0x0162, 0x0d},
+- {0x0163, 0x78},
+ };
+
+ static const struct imx219_reg mode_1640_1232_regs[] = {
+--
+2.39.2
+
--- /dev/null
+From 663c056e62da9dafe65ccf80204de864d9e65a00 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Dec 2022 13:07:53 +0100
+Subject: media: i2c: imx219: Split common registers from mode tables
+
+From: Adam Ford <aford173@gmail.com>
+
+[ Upstream commit 8508455961d5a9e8907bcfd8dcd58f19d9b6ce47 ]
+
+There are four modes, and each mode has a table of registers.
+Some of the registers are common to all modes, so create new
+tables for these common registers to reduce duplicate code.
+
+Signed-off-by: Adam Ford <aford173@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>
+Stable-dep-of: ef86447e775f ("media: i2c: imx219: Fix binning for RAW8 capture")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/i2c/imx219.c | 206 +++++++++++--------------------------
+ 1 file changed, 59 insertions(+), 147 deletions(-)
+
+diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c
+index cad0a8df203ed..a28926069b82b 100644
+--- a/drivers/media/i2c/imx219.c
++++ b/drivers/media/i2c/imx219.c
+@@ -145,23 +145,61 @@ struct imx219_mode {
+ struct imx219_reg_list reg_list;
+ };
+
+-/*
+- * Register sets lifted off the i2C interface from the Raspberry Pi firmware
+- * driver.
+- * 3280x2464 = mode 2, 1920x1080 = mode 1, 1640x1232 = mode 4, 640x480 = mode 7.
+- */
+-static const struct imx219_reg mode_3280x2464_regs[] = {
+- {0x0100, 0x00},
++static const struct imx219_reg imx219_common_regs[] = {
++ {0x0100, 0x00}, /* Mode Select */
++
++ /* To Access Addresses 3000-5fff, send the following commands */
+ {0x30eb, 0x0c},
+ {0x30eb, 0x05},
+ {0x300a, 0xff},
+ {0x300b, 0xff},
+ {0x30eb, 0x05},
+ {0x30eb, 0x09},
+- {0x0114, 0x01},
+- {0x0128, 0x00},
+- {0x012a, 0x18},
++
++ /* PLL Clock Table */
++ {0x0301, 0x05}, /* VTPXCK_DIV */
++ {0x0303, 0x01}, /* VTSYSCK_DIV */
++ {0x0304, 0x03}, /* PREPLLCK_VT_DIV 0x03 = AUTO set */
++ {0x0305, 0x03}, /* PREPLLCK_OP_DIV 0x03 = AUTO set */
++ {0x0306, 0x00}, /* PLL_VT_MPY */
++ {0x0307, 0x39},
++ {0x030b, 0x01}, /* OP_SYS_CLK_DIV */
++ {0x030c, 0x00}, /* PLL_OP_MPY */
++ {0x030d, 0x72},
++
++ /* Undocumented registers */
++ {0x455e, 0x00},
++ {0x471e, 0x4b},
++ {0x4767, 0x0f},
++ {0x4750, 0x14},
++ {0x4540, 0x00},
++ {0x47b4, 0x14},
++ {0x4713, 0x30},
++ {0x478b, 0x10},
++ {0x478f, 0x10},
++ {0x4793, 0x10},
++ {0x4797, 0x0e},
++ {0x479b, 0x0e},
++
++ /* Frame Bank Register Group "A" */
++ {0x0162, 0x0d}, /* Line_Length_A */
++ {0x0163, 0x78},
++ {0x0170, 0x01}, /* X_ODD_INC_A */
++ {0x0171, 0x01}, /* Y_ODD_INC_A */
++
++ /* Output setup registers */
++ {0x0114, 0x01}, /* CSI 2-Lane Mode */
++ {0x0128, 0x00}, /* DPHY Auto Mode */
++ {0x012a, 0x18}, /* EXCK_Freq */
+ {0x012b, 0x00},
++};
++
++/*
++ * Register sets lifted off the i2C interface from the Raspberry Pi firmware
++ * driver.
++ * 3280x2464 = mode 2, 1920x1080 = mode 1, 1640x1232 = mode 4, 640x480 = mode 7.
++ */
++static const struct imx219_reg mode_3280x2464_regs[] = {
+ {0x0164, 0x00},
+ {0x0165, 0x00},
+ {0x0166, 0x0c},
+@@ -174,53 +212,15 @@ static const struct imx219_reg mode_3280x2464_regs[] = {
+ {0x016d, 0xd0},
+ {0x016e, 0x09},
+ {0x016f, 0xa0},
+- {0x0170, 0x01},
+- {0x0171, 0x01},
+- {0x0174, 0x00},
++ {0x0174, 0x00}, /* No-Binning */
+ {0x0175, 0x00},
+- {0x0301, 0x05},
+- {0x0303, 0x01},
+- {0x0304, 0x03},
+- {0x0305, 0x03},
+- {0x0306, 0x00},
+- {0x0307, 0x39},
+- {0x030b, 0x01},
+- {0x030c, 0x00},
+- {0x030d, 0x72},
+ {0x0624, 0x0c},
+ {0x0625, 0xd0},
+ {0x0626, 0x09},
+ {0x0627, 0xa0},
+- {0x455e, 0x00},
+- {0x471e, 0x4b},
+- {0x4767, 0x0f},
+- {0x4750, 0x14},
+- {0x4540, 0x00},
+- {0x47b4, 0x14},
+- {0x4713, 0x30},
+- {0x478b, 0x10},
+- {0x478f, 0x10},
+- {0x4793, 0x10},
+- {0x4797, 0x0e},
+- {0x479b, 0x0e},
+- {0x0162, 0x0d},
+- {0x0163, 0x78},
+ };
+
+ static const struct imx219_reg mode_1920_1080_regs[] = {
+- {0x0100, 0x00},
+- {0x30eb, 0x05},
+- {0x30eb, 0x0c},
+- {0x300a, 0xff},
+- {0x300b, 0xff},
+- {0x30eb, 0x05},
+- {0x30eb, 0x09},
+- {0x0114, 0x01},
+- {0x0128, 0x00},
+- {0x012a, 0x18},
+- {0x012b, 0x00},
+- {0x0162, 0x0d},
+- {0x0163, 0x78},
+ {0x0164, 0x02},
+ {0x0165, 0xa8},
+ {0x0166, 0x0a},
+@@ -233,49 +233,15 @@ static const struct imx219_reg mode_1920_1080_regs[] = {
+ {0x016d, 0x80},
+ {0x016e, 0x04},
+ {0x016f, 0x38},
+- {0x0170, 0x01},
+- {0x0171, 0x01},
+- {0x0174, 0x00},
++ {0x0174, 0x00}, /* No-Binning */
+ {0x0175, 0x00},
+- {0x0301, 0x05},
+- {0x0303, 0x01},
+- {0x0304, 0x03},
+- {0x0305, 0x03},
+- {0x0306, 0x00},
+- {0x0307, 0x39},
+- {0x030b, 0x01},
+- {0x030c, 0x00},
+- {0x030d, 0x72},
+ {0x0624, 0x07},
+ {0x0625, 0x80},
+ {0x0626, 0x04},
+ {0x0627, 0x38},
+- {0x455e, 0x00},
+- {0x471e, 0x4b},
+- {0x4767, 0x0f},
+- {0x4750, 0x14},
+- {0x4540, 0x00},
+- {0x47b4, 0x14},
+- {0x4713, 0x30},
+- {0x478b, 0x10},
+- {0x478f, 0x10},
+- {0x4793, 0x10},
+- {0x4797, 0x0e},
+- {0x479b, 0x0e},
+ };
+
+ static const struct imx219_reg mode_1640_1232_regs[] = {
+- {0x0100, 0x00},
+- {0x30eb, 0x0c},
+- {0x30eb, 0x05},
+- {0x300a, 0xff},
+- {0x300b, 0xff},
+- {0x30eb, 0x05},
+- {0x30eb, 0x09},
+- {0x0114, 0x01},
+- {0x0128, 0x00},
+- {0x012a, 0x18},
+- {0x012b, 0x00},
+ {0x0164, 0x00},
+ {0x0165, 0x00},
+ {0x0166, 0x0c},
+@@ -288,53 +254,15 @@ static const struct imx219_reg mode_1640_1232_regs[] = {
+ {0x016d, 0x68},
+ {0x016e, 0x04},
+ {0x016f, 0xd0},
+- {0x0170, 0x01},
+- {0x0171, 0x01},
+- {0x0174, 0x01},
++ {0x0174, 0x01}, /* x2-Binning */
+ {0x0175, 0x01},
+- {0x0301, 0x05},
+- {0x0303, 0x01},
+- {0x0304, 0x03},
+- {0x0305, 0x03},
+- {0x0306, 0x00},
+- {0x0307, 0x39},
+- {0x030b, 0x01},
+- {0x030c, 0x00},
+- {0x030d, 0x72},
+ {0x0624, 0x06},
+ {0x0625, 0x68},
+ {0x0626, 0x04},
+ {0x0627, 0xd0},
+- {0x455e, 0x00},
+- {0x471e, 0x4b},
+- {0x4767, 0x0f},
+- {0x4750, 0x14},
+- {0x4540, 0x00},
+- {0x47b4, 0x14},
+- {0x4713, 0x30},
+- {0x478b, 0x10},
+- {0x478f, 0x10},
+- {0x4793, 0x10},
+- {0x4797, 0x0e},
+- {0x479b, 0x0e},
+- {0x0162, 0x0d},
+- {0x0163, 0x78},
+ };
+
+ static const struct imx219_reg mode_640_480_regs[] = {
+- {0x0100, 0x00},
+- {0x30eb, 0x05},
+- {0x30eb, 0x0c},
+- {0x300a, 0xff},
+- {0x300b, 0xff},
+- {0x30eb, 0x05},
+- {0x30eb, 0x09},
+- {0x0114, 0x01},
+- {0x0128, 0x00},
+- {0x012a, 0x18},
+- {0x012b, 0x00},
+- {0x0162, 0x0d},
+- {0x0163, 0x78},
+ {0x0164, 0x03},
+ {0x0165, 0xe8},
+ {0x0166, 0x08},
+@@ -347,35 +275,12 @@ static const struct imx219_reg mode_640_480_regs[] = {
+ {0x016d, 0x80},
+ {0x016e, 0x01},
+ {0x016f, 0xe0},
+- {0x0170, 0x01},
+- {0x0171, 0x01},
+- {0x0174, 0x03},
++ {0x0174, 0x03}, /* x2-analog binning */
+ {0x0175, 0x03},
+- {0x0301, 0x05},
+- {0x0303, 0x01},
+- {0x0304, 0x03},
+- {0x0305, 0x03},
+- {0x0306, 0x00},
+- {0x0307, 0x39},
+- {0x030b, 0x01},
+- {0x030c, 0x00},
+- {0x030d, 0x72},
+ {0x0624, 0x06},
+ {0x0625, 0x68},
+ {0x0626, 0x04},
+ {0x0627, 0xd0},
+- {0x455e, 0x00},
+- {0x471e, 0x4b},
+- {0x4767, 0x0f},
+- {0x4750, 0x14},
+- {0x4540, 0x00},
+- {0x47b4, 0x14},
+- {0x4713, 0x30},
+- {0x478b, 0x10},
+- {0x478f, 0x10},
+- {0x4793, 0x10},
+- {0x4797, 0x0e},
+- {0x479b, 0x0e},
+ };
+
+ static const struct imx219_reg raw8_framefmt_regs[] = {
+@@ -1030,6 +935,13 @@ static int imx219_start_streaming(struct imx219 *imx219)
+ return ret;
+ }
+
++ /* Send all registers that are common to all modes */
++ ret = imx219_write_regs(imx219, imx219_common_regs, ARRAY_SIZE(imx219_common_regs));
++ if (ret) {
++ dev_err(&client->dev, "%s failed to send mfg header\n", __func__);
++ goto err_rpm_put;
++ }
++
+ /* Apply default values of current mode */
+ reg_list = &imx219->mode->reg_list;
+ ret = imx219_write_regs(imx219, reg_list->regs, reg_list->num_of_regs);
+--
+2.39.2
+
--- /dev/null
+From 123fa112ac6071ac51c0feeb7dc8a4a5666bd4a2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 Jan 2023 14:03:51 +0100
+Subject: media: i2c: ov7670: 0 instead of -EINVAL was returned
+
+From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+
+[ Upstream commit 6a4c664539e6de9b32b65ddcf767ec1bcc1d7f8a ]
+
+If the media bus is unsupported, then return -EINVAL. Instead it
+returned 'ret' which happened to be 0.
+
+This fixes a smatch warning:
+
+ov7670.c:1843 ov7670_parse_dt() warn: missing error code? 'ret'
+
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Fixes: 01b8444828fc ("media: v4l2: i2c: ov7670: Implement OF mbus configuration")
+Acked-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/ov7670.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c
+index 154776d0069ea..e47800cb6c0f7 100644
+--- a/drivers/media/i2c/ov7670.c
++++ b/drivers/media/i2c/ov7670.c
+@@ -1824,7 +1824,7 @@ static int ov7670_parse_dt(struct device *dev,
+
+ if (bus_cfg.bus_type != V4L2_MBUS_PARALLEL) {
+ dev_err(dev, "Unsupported media bus type\n");
+- return ret;
++ return -EINVAL;
+ }
+ info->mbus_config = bus_cfg.bus.parallel.flags;
+
+--
+2.39.2
+
--- /dev/null
+From bdc27da68ac1f0f4239415cccdcd7f66becf99fd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Dec 2022 09:06:25 +0100
+Subject: media: i2c: ov772x: Fix memleak in ov772x_probe()
+
+From: Yuan Can <yuancan@huawei.com>
+
+[ Upstream commit 7485edb2b6ca5960205c0a49bedfd09bba30e521 ]
+
+A memory leak was reported when testing ov772x with bpf mock device:
+
+AssertionError: unreferenced object 0xffff888109afa7a8 (size 8):
+ comm "python3", pid 279, jiffies 4294805921 (age 20.681s)
+ hex dump (first 8 bytes):
+ 80 22 88 15 81 88 ff ff ."......
+ backtrace:
+ [<000000009990b438>] __kmalloc_node+0x44/0x1b0
+ [<000000009e32f7d7>] kvmalloc_node+0x34/0x180
+ [<00000000faf48134>] v4l2_ctrl_handler_init_class+0x11d/0x180 [videodev]
+ [<00000000da376937>] ov772x_probe+0x1c3/0x68c [ov772x]
+ [<000000003f0d225e>] i2c_device_probe+0x28d/0x680
+ [<00000000e0b6db89>] really_probe+0x17c/0x3f0
+ [<000000001b19fcee>] __driver_probe_device+0xe3/0x170
+ [<0000000048370519>] driver_probe_device+0x49/0x120
+ [<000000005ead07a0>] __device_attach_driver+0xf7/0x150
+ [<0000000043f452b8>] bus_for_each_drv+0x114/0x180
+ [<00000000358e5596>] __device_attach+0x1e5/0x2d0
+ [<0000000043f83c5d>] bus_probe_device+0x126/0x140
+ [<00000000ee0f3046>] device_add+0x810/0x1130
+ [<00000000e0278184>] i2c_new_client_device+0x359/0x4f0
+ [<0000000070baf34f>] of_i2c_register_device+0xf1/0x110
+ [<00000000a9f2159d>] of_i2c_notify+0x100/0x160
+unreferenced object 0xffff888119825c00 (size 256):
+ comm "python3", pid 279, jiffies 4294805921 (age 20.681s)
+ hex dump (first 32 bytes):
+ 00 b4 a5 17 81 88 ff ff 00 5e 82 19 81 88 ff ff .........^......
+ 10 5c 82 19 81 88 ff ff 10 5c 82 19 81 88 ff ff .\.......\......
+ backtrace:
+ [<000000009990b438>] __kmalloc_node+0x44/0x1b0
+ [<000000009e32f7d7>] kvmalloc_node+0x34/0x180
+ [<0000000073d88e0b>] v4l2_ctrl_new.cold+0x19b/0x86f [videodev]
+ [<00000000b1f576fb>] v4l2_ctrl_new_std+0x16f/0x210 [videodev]
+ [<00000000caf7ac99>] ov772x_probe+0x1fa/0x68c [ov772x]
+ [<000000003f0d225e>] i2c_device_probe+0x28d/0x680
+ [<00000000e0b6db89>] really_probe+0x17c/0x3f0
+ [<000000001b19fcee>] __driver_probe_device+0xe3/0x170
+ [<0000000048370519>] driver_probe_device+0x49/0x120
+ [<000000005ead07a0>] __device_attach_driver+0xf7/0x150
+ [<0000000043f452b8>] bus_for_each_drv+0x114/0x180
+ [<00000000358e5596>] __device_attach+0x1e5/0x2d0
+ [<0000000043f83c5d>] bus_probe_device+0x126/0x140
+ [<00000000ee0f3046>] device_add+0x810/0x1130
+ [<00000000e0278184>] i2c_new_client_device+0x359/0x4f0
+ [<0000000070baf34f>] of_i2c_register_device+0xf1/0x110
+
+The reason is that if priv->hdl.error is set, ov772x_probe() jumps to the
+error_mutex_destroy without doing v4l2_ctrl_handler_free(), and all
+resources allocated in v4l2_ctrl_handler_init() and v4l2_ctrl_new_std()
+are leaked.
+
+Fixes: 1112babde214 ("media: i2c: Copy ov772x soc_camera sensor driver")
+Signed-off-by: Yuan Can <yuancan@huawei.com>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@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/ov772x.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/media/i2c/ov772x.c b/drivers/media/i2c/ov772x.c
+index 2cc6a678069a2..5033950a48ab6 100644
+--- a/drivers/media/i2c/ov772x.c
++++ b/drivers/media/i2c/ov772x.c
+@@ -1397,7 +1397,7 @@ static int ov772x_probe(struct i2c_client *client)
+ priv->subdev.ctrl_handler = &priv->hdl;
+ if (priv->hdl.error) {
+ ret = priv->hdl.error;
+- goto error_mutex_destroy;
++ goto error_ctrl_free;
+ }
+
+ priv->clk = clk_get(&client->dev, NULL);
+@@ -1446,7 +1446,6 @@ static int ov772x_probe(struct i2c_client *client)
+ clk_put(priv->clk);
+ error_ctrl_free:
+ v4l2_ctrl_handler_free(&priv->hdl);
+-error_mutex_destroy:
+ mutex_destroy(&priv->lock);
+
+ return ret;
+--
+2.39.2
+
--- /dev/null
+From b74e1905b8041b4b699e0b86b8f7110b03247e24 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Dec 2022 14:05:55 +0100
+Subject: media: max9286: Fix memleak in max9286_v4l2_register()
+
+From: Shang XiaoJing <shangxiaojing@huawei.com>
+
+[ Upstream commit 8636c5fc7658c7c6299fb8b352d24ea4b9ba99e2 ]
+
+There is a kmemleak when testing the media/i2c/max9286.c with bpf mock
+device:
+
+kmemleak: 5 new suspected memory leaks (see /sys/kernel/debug/kmemleak)
+
+unreferenced object 0xffff88810defc400 (size 256):
+ comm "python3", pid 278, jiffies 4294737563 (age 31.978s)
+ hex dump (first 32 bytes):
+ 28 06 a7 0a 81 88 ff ff 00 fe 22 12 81 88 ff ff (.........".....
+ 10 c4 ef 0d 81 88 ff ff 10 c4 ef 0d 81 88 ff ff ................
+ backtrace:
+ [<00000000191de6a7>] __kmalloc_node+0x44/0x1b0
+ [<000000002f4912b7>] kvmalloc_node+0x34/0x180
+ [<0000000057dc4cae>] v4l2_ctrl_new+0x325/0x10f0 [videodev]
+ [<0000000026030272>] v4l2_ctrl_new_std+0x16f/0x210 [videodev]
+ [<00000000f0d9ea2f>] max9286_probe+0x76e/0xbff [max9286]
+ [<00000000ea8f6455>] i2c_device_probe+0x28d/0x680
+ [<0000000087529af3>] really_probe+0x17c/0x3f0
+ [<00000000b08be526>] __driver_probe_device+0xe3/0x170
+ [<000000004382edea>] driver_probe_device+0x49/0x120
+ [<000000007bde528a>] __device_attach_driver+0xf7/0x150
+ [<000000009f9c6ab4>] bus_for_each_drv+0x114/0x180
+ [<00000000c8aaf588>] __device_attach+0x1e5/0x2d0
+ [<0000000041cc06b9>] bus_probe_device+0x126/0x140
+ [<000000002309860d>] device_add+0x810/0x1130
+ [<000000002827bf98>] i2c_new_client_device+0x359/0x4f0
+ [<00000000593bdc85>] of_i2c_register_device+0xf1/0x110
+
+max9286_v4l2_register() calls v4l2_ctrl_new_std(), but won't free the
+created v412_ctrl when fwnode_graph_get_endpoint_by_id() failed, which
+causes the memleak. Call v4l2_ctrl_handler_free() to free the v412_ctrl.
+
+Fixes: 66d8c9d2422d ("media: i2c: Add MAX9286 driver")
+Signed-off-by: Shang XiaoJing <shangxiaojing@huawei.com>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@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/max9286.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
+index b1e2476d3c9e6..79a11c0184c65 100644
+--- a/drivers/media/i2c/max9286.c
++++ b/drivers/media/i2c/max9286.c
+@@ -890,6 +890,7 @@ static int max9286_v4l2_register(struct max9286_priv *priv)
+ err_put_node:
+ fwnode_handle_put(ep);
+ err_async:
++ v4l2_ctrl_handler_free(&priv->ctrls);
+ max9286_v4l2_notifier_unregister(priv);
+
+ return ret;
+--
+2.39.2
+
--- /dev/null
+From 96b4f2b9279ae215e3e391151195fa0422f43c3f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Dec 2022 08:59:37 +0100
+Subject: media: ov2740: Fix memleak in ov2740_init_controls()
+
+From: Shang XiaoJing <shangxiaojing@huawei.com>
+
+[ Upstream commit 2d899592ed7829d0d5140853bac4d58742a6b8af ]
+
+There is a kmemleak when testing the media/i2c/ov2740.c with bpf mock
+device:
+
+unreferenced object 0xffff8881090e19e0 (size 16):
+ comm "51-i2c-ov2740", pid 278, jiffies 4294781584 (age 23.613s)
+ hex dump (first 16 bytes):
+ 00 f3 7c 0b 81 88 ff ff 80 75 6a 09 81 88 ff ff ..|......uj.....
+ backtrace:
+ [<000000004e9fad8f>] __kmalloc_node+0x44/0x1b0
+ [<0000000039c802f4>] kvmalloc_node+0x34/0x180
+ [<000000009b8b5c63>] v4l2_ctrl_handler_init_class+0x11d/0x180
+[videodev]
+ [<0000000038644056>] ov2740_probe+0x37d/0x84f [ov2740]
+ [<0000000092489f59>] i2c_device_probe+0x28d/0x680
+ [<000000001038babe>] really_probe+0x17c/0x3f0
+ [<0000000098c7af1c>] __driver_probe_device+0xe3/0x170
+ [<00000000e1b3dc24>] device_driver_attach+0x34/0x80
+ [<000000005a04a34d>] bind_store+0x10b/0x1a0
+ [<00000000ce25d4f2>] drv_attr_store+0x49/0x70
+ [<000000007d9f4e9a>] sysfs_kf_write+0x8c/0xb0
+ [<00000000be6cff0f>] kernfs_fop_write_iter+0x216/0x2e0
+ [<0000000031ddb40a>] vfs_write+0x658/0x810
+ [<0000000041beecdd>] ksys_write+0xd6/0x1b0
+ [<0000000023755840>] do_syscall_64+0x38/0x90
+ [<00000000b2cc2da2>] entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+ov2740_init_controls() won't clean all the allocated resources in fail
+path, which may causes the memleaks. Add v4l2_ctrl_handler_free() to
+prevent memleak.
+
+Fixes: 866edc895171 ("media: i2c: Add ov2740 image sensor driver")
+Signed-off-by: Shang XiaoJing <shangxiaojing@huawei.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/ov2740.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/i2c/ov2740.c b/drivers/media/i2c/ov2740.c
+index bd0d45b0d43f5..34d74e575a431 100644
+--- a/drivers/media/i2c/ov2740.c
++++ b/drivers/media/i2c/ov2740.c
+@@ -577,8 +577,10 @@ static int ov2740_init_controls(struct ov2740 *ov2740)
+ V4L2_CID_TEST_PATTERN,
+ ARRAY_SIZE(ov2740_test_pattern_menu) - 1,
+ 0, 0, ov2740_test_pattern_menu);
+- if (ctrl_hdlr->error)
++ if (ctrl_hdlr->error) {
++ v4l2_ctrl_handler_free(ctrl_hdlr);
+ return ctrl_hdlr->error;
++ }
+
+ ov2740->sd.ctrl_handler = ctrl_hdlr;
+
+--
+2.39.2
+
--- /dev/null
+From 991fdfead9231cd1f25df940302b6d21083f7a14 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Dec 2022 08:59:38 +0100
+Subject: media: ov5675: Fix memleak in ov5675_init_controls()
+
+From: Shang XiaoJing <shangxiaojing@huawei.com>
+
+[ Upstream commit dd74ed6c213003533e3abf4c204374ef01d86978 ]
+
+There is a kmemleak when testing the media/i2c/ov5675.c with bpf mock
+device:
+
+AssertionError: unreferenced object 0xffff888107362160 (size 16):
+ comm "python3", pid 277, jiffies 4294832798 (age 20.722s)
+ hex dump (first 16 bytes):
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ backtrace:
+ [<00000000abe7d67c>] __kmalloc_node+0x44/0x1b0
+ [<000000008a725aac>] kvmalloc_node+0x34/0x180
+ [<000000009a53cd11>] v4l2_ctrl_handler_init_class+0x11d/0x180
+[videodev]
+ [<0000000055b46db0>] ov5675_probe+0x38b/0x897 [ov5675]
+ [<00000000153d886c>] i2c_device_probe+0x28d/0x680
+ [<000000004afb7e8f>] really_probe+0x17c/0x3f0
+ [<00000000ff2f18e4>] __driver_probe_device+0xe3/0x170
+ [<000000000a001029>] driver_probe_device+0x49/0x120
+ [<00000000e39743c7>] __device_attach_driver+0xf7/0x150
+ [<00000000d32fd070>] bus_for_each_drv+0x114/0x180
+ [<000000009083ac41>] __device_attach+0x1e5/0x2d0
+ [<0000000015b4a830>] bus_probe_device+0x126/0x140
+ [<000000007813deaf>] device_add+0x810/0x1130
+ [<000000007becb867>] i2c_new_client_device+0x386/0x540
+ [<000000007f9cf4b4>] of_i2c_register_device+0xf1/0x110
+ [<00000000ebfdd032>] of_i2c_notify+0xfc/0x1f0
+
+ov5675_init_controls() won't clean all the allocated resources in fail
+path, which may causes the memleaks. Add v4l2_ctrl_handler_free() to
+prevent memleak.
+
+Fixes: bf27502b1f3b ("media: ov5675: Add support for OV5675 sensor")
+Signed-off-by: Shang XiaoJing <shangxiaojing@huawei.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/ov5675.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/i2c/ov5675.c b/drivers/media/i2c/ov5675.c
+index 9540ce8918f0c..aa35a9546177a 100644
+--- a/drivers/media/i2c/ov5675.c
++++ b/drivers/media/i2c/ov5675.c
+@@ -791,8 +791,10 @@ static int ov5675_init_controls(struct ov5675 *ov5675)
+ v4l2_ctrl_new_std(ctrl_hdlr, &ov5675_ctrl_ops,
+ V4L2_CID_VFLIP, 0, 1, 1, 0);
+
+- if (ctrl_hdlr->error)
++ if (ctrl_hdlr->error) {
++ v4l2_ctrl_handler_free(ctrl_hdlr);
+ return ctrl_hdlr->error;
++ }
+
+ ov5675->sd.ctrl_handler = ctrl_hdlr;
+
+--
+2.39.2
+
--- /dev/null
+From 991dae177b57a7798d5828d04cf219108b514df8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Jan 2023 09:55:37 +0100
+Subject: media: platform: ti: Add missing check for devm_regulator_get
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit da8e05f84a11c3cc3b0ba0a3c62d20e358002d99 ]
+
+Add check for the return value of devm_regulator_get since it may return
+error pointer.
+
+Fixes: 448de7e7850b ("[media] omap3isp: OMAP3 ISP core")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/omap3isp/isp.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
+index 1311b4996eceb..21c16698cc2db 100644
+--- a/drivers/media/platform/omap3isp/isp.c
++++ b/drivers/media/platform/omap3isp/isp.c
+@@ -2297,7 +2297,16 @@ static int isp_probe(struct platform_device *pdev)
+
+ /* Regulators */
+ isp->isp_csiphy1.vdd = devm_regulator_get(&pdev->dev, "vdd-csiphy1");
++ if (IS_ERR(isp->isp_csiphy1.vdd)) {
++ ret = PTR_ERR(isp->isp_csiphy1.vdd);
++ goto error;
++ }
++
+ isp->isp_csiphy2.vdd = devm_regulator_get(&pdev->dev, "vdd-csiphy2");
++ if (IS_ERR(isp->isp_csiphy2.vdd)) {
++ ret = PTR_ERR(isp->isp_csiphy2.vdd);
++ goto error;
++ }
+
+ /* Clocks
+ *
+--
+2.39.2
+
--- /dev/null
+From d7e9b091e574332b3f1f01fd33a66b9dc0fb0a4a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Jan 2023 08:55:33 +0100
+Subject: media: rc: Fix use-after-free bugs caused by ene_tx_irqsim()
+
+From: Duoming Zhou <duoming@zju.edu.cn>
+
+[ Upstream commit 29b0589a865b6f66d141d79b2dd1373e4e50fe17 ]
+
+When the ene device is detaching, function ene_remove() will
+be called. But there is no function to cancel tx_sim_timer
+in ene_remove(), the timer handler ene_tx_irqsim() could race
+with ene_remove(). As a result, the UAF bugs could happen,
+the process is shown below.
+
+ (cleanup routine) | (timer routine)
+ | mod_timer(&dev->tx_sim_timer, ..)
+ene_remove() | (wait a time)
+ | ene_tx_irqsim()
+ | dev->hw_lock //USE
+ | ene_tx_sample(dev) //USE
+
+Fix by adding del_timer_sync(&dev->tx_sim_timer) in ene_remove(),
+The tx_sim_timer could stop before ene device is deallocated.
+
+What's more, The rc_unregister_device() and del_timer_sync()
+should be called first in ene_remove() and the deallocated
+functions such as free_irq(), release_region() and so on
+should be called behind them. Because the rc_unregister_device()
+is well synchronized. Otherwise, race conditions may happen. The
+situations that may lead to race conditions are shown below.
+
+Firstly, the rx receiver is disabled with ene_rx_disable()
+before rc_unregister_device() in ene_remove(), which means it
+can be enabled again if a process opens /dev/lirc0 between
+ene_rx_disable() and rc_unregister_device().
+
+Secondly, the irqaction descriptor is freed by free_irq()
+before the rc device is unregistered, which means irqaction
+descriptor may be accessed again after it is deallocated.
+
+Thirdly, the timer can call ene_tx_sample() that can write
+to the io ports, which means the io ports could be accessed
+again after they are deallocated by release_region().
+
+Therefore, the rc_unregister_device() and del_timer_sync()
+should be called first in ene_remove().
+
+Suggested by: Sean Young <sean@mess.org>
+
+Fixes: 9ea53b74df9c ("V4L/DVB: STAGING: remove lirc_ene0100 driver")
+Signed-off-by: Duoming Zhou <duoming@zju.edu.cn>
+Signed-off-by: Sean Young <sean@mess.org>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/rc/ene_ir.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/rc/ene_ir.c b/drivers/media/rc/ene_ir.c
+index 6049e5c95394f..5aa3953cab82c 100644
+--- a/drivers/media/rc/ene_ir.c
++++ b/drivers/media/rc/ene_ir.c
+@@ -1106,6 +1106,8 @@ static void ene_remove(struct pnp_dev *pnp_dev)
+ struct ene_device *dev = pnp_get_drvdata(pnp_dev);
+ unsigned long flags;
+
++ rc_unregister_device(dev->rdev);
++ del_timer_sync(&dev->tx_sim_timer);
+ spin_lock_irqsave(&dev->hw_lock, flags);
+ ene_rx_disable(dev);
+ ene_rx_restore_hw_buffer(dev);
+@@ -1113,7 +1115,6 @@ static void ene_remove(struct pnp_dev *pnp_dev)
+
+ free_irq(dev->irq, dev);
+ release_region(dev->hw_io, ENE_IO_SIZE);
+- rc_unregister_device(dev->rdev);
+ kfree(dev);
+ }
+
+--
+2.39.2
+
--- /dev/null
+From cd4c37abb8be25990159084ffa9e6612e60fde9b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 Jan 2023 12:00:59 +0100
+Subject: media: saa7134: Use video_unregister_device for radio_dev
+
+From: Tasos Sahanidis <tasos@tasossah.com>
+
+[ Upstream commit bc7635c6435c77a0c168e2cc6535740adfaff4e4 ]
+
+The radio device doesn't use vb2, thus calling vb2_video_unregister_device()
+which results in the following warning being printed on module unload.
+
+WARNING: CPU: 1 PID: 215963 at drivers/media/common/videobuf2/videobuf2-v4l2.c:1236 vb2_video_unregister_device+0xc6/0xe0 [videobuf2_v4l2]
+
+Fixes: 11788d9b7e91 ("media: media/pci: use vb2_video_unregister_device()")
+Signed-off-by: Tasos Sahanidis <tasos@tasossah.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/pci/saa7134/saa7134-core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/pci/saa7134/saa7134-core.c b/drivers/media/pci/saa7134/saa7134-core.c
+index efb757d5168a6..e97c30070fc64 100644
+--- a/drivers/media/pci/saa7134/saa7134-core.c
++++ b/drivers/media/pci/saa7134/saa7134-core.c
+@@ -977,7 +977,7 @@ static void saa7134_unregister_video(struct saa7134_dev *dev)
+ }
+ if (dev->radio_dev) {
+ if (video_is_registered(dev->radio_dev))
+- vb2_video_unregister_device(dev->radio_dev);
++ video_unregister_device(dev->radio_dev);
+ else
+ video_device_release(dev->radio_dev);
+ dev->radio_dev = NULL;
+--
+2.39.2
+
--- /dev/null
+From 6bba50c4a4de1a26763a5b52473a00aaacbd0d72 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Nov 2022 12:01:59 +0100
+Subject: media: ti: cal: fix possible memory leak in cal_ctx_create()
+
+From: Gaosheng Cui <cuigaosheng1@huawei.com>
+
+[ Upstream commit 7acd650a0484d92985a0d6d867d980c6dd019885 ]
+
+The memory of ctx is allocated in cal_ctx_create(), but it will
+not be freed when cal_ctx_v4l2_init() fails, so add kfree() when
+cal_ctx_v4l2_init() fails to fix it.
+
+Fixes: d68a94e98a89 ("media: ti-vpe: cal: Split video device initialization and registration")
+Signed-off-by: Gaosheng Cui <cuigaosheng1@huawei.com>
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/ti-vpe/cal.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/platform/ti-vpe/cal.c b/drivers/media/platform/ti-vpe/cal.c
+index 2eef245c31a17..93121c90d76ae 100644
+--- a/drivers/media/platform/ti-vpe/cal.c
++++ b/drivers/media/platform/ti-vpe/cal.c
+@@ -624,8 +624,10 @@ static struct cal_ctx *cal_ctx_create(struct cal_dev *cal, int inst)
+ ctx->cport = inst;
+
+ ret = cal_ctx_v4l2_init(ctx);
+- if (ret)
++ if (ret) {
++ kfree(ctx);
+ return NULL;
++ }
+
+ return ctx;
+ }
+--
+2.39.2
+
--- /dev/null
+From 95b409ae4d3fdc8396b798727dbad95756abd782 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 23 Jan 2023 03:04:38 +0100
+Subject: media: usb: siano: Fix use after free bugs caused by do_submit_urb
+
+From: Duoming Zhou <duoming@zju.edu.cn>
+
+[ Upstream commit ebad8e731c1c06adf04621d6fd327b860c0861b5 ]
+
+There are UAF bugs caused by do_submit_urb(). One of the KASan reports
+is shown below:
+
+[ 36.403605] BUG: KASAN: use-after-free in worker_thread+0x4a2/0x890
+[ 36.406105] Read of size 8 at addr ffff8880059600e8 by task kworker/0:2/49
+[ 36.408316]
+[ 36.408867] CPU: 0 PID: 49 Comm: kworker/0:2 Not tainted 6.2.0-rc3-15798-g5a41237ad1d4-dir8
+[ 36.411696] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g15584
+[ 36.416157] Workqueue: 0x0 (events)
+[ 36.417654] Call Trace:
+[ 36.418546] <TASK>
+[ 36.419320] dump_stack_lvl+0x96/0xd0
+[ 36.420522] print_address_description+0x75/0x350
+[ 36.421992] print_report+0x11b/0x250
+[ 36.423174] ? _raw_spin_lock_irqsave+0x87/0xd0
+[ 36.424806] ? __virt_addr_valid+0xcf/0x170
+[ 36.426069] ? worker_thread+0x4a2/0x890
+[ 36.427355] kasan_report+0x131/0x160
+[ 36.428556] ? worker_thread+0x4a2/0x890
+[ 36.430053] worker_thread+0x4a2/0x890
+[ 36.431297] ? worker_clr_flags+0x90/0x90
+[ 36.432479] kthread+0x166/0x190
+[ 36.433493] ? kthread_blkcg+0x50/0x50
+[ 36.434669] ret_from_fork+0x22/0x30
+[ 36.435923] </TASK>
+[ 36.436684]
+[ 36.437215] Allocated by task 24:
+[ 36.438289] kasan_set_track+0x50/0x80
+[ 36.439436] __kasan_kmalloc+0x89/0xa0
+[ 36.440566] smsusb_probe+0x374/0xc90
+[ 36.441920] usb_probe_interface+0x2d1/0x4c0
+[ 36.443253] really_probe+0x1d5/0x580
+[ 36.444539] __driver_probe_device+0xe3/0x130
+[ 36.446085] driver_probe_device+0x49/0x220
+[ 36.447423] __device_attach_driver+0x19e/0x1b0
+[ 36.448931] bus_for_each_drv+0xcb/0x110
+[ 36.450217] __device_attach+0x132/0x1f0
+[ 36.451470] bus_probe_device+0x59/0xf0
+[ 36.452563] device_add+0x4ec/0x7b0
+[ 36.453830] usb_set_configuration+0xc63/0xe10
+[ 36.455230] usb_generic_driver_probe+0x3b/0x80
+[ 36.456166] printk: console [ttyGS0] disabled
+[ 36.456569] usb_probe_device+0x90/0x110
+[ 36.459523] really_probe+0x1d5/0x580
+[ 36.461027] __driver_probe_device+0xe3/0x130
+[ 36.462465] driver_probe_device+0x49/0x220
+[ 36.463847] __device_attach_driver+0x19e/0x1b0
+[ 36.465229] bus_for_each_drv+0xcb/0x110
+[ 36.466466] __device_attach+0x132/0x1f0
+[ 36.467799] bus_probe_device+0x59/0xf0
+[ 36.469010] device_add+0x4ec/0x7b0
+[ 36.470125] usb_new_device+0x863/0xa00
+[ 36.471374] hub_event+0x18c7/0x2220
+[ 36.472746] process_one_work+0x34c/0x5b0
+[ 36.474041] worker_thread+0x4b7/0x890
+[ 36.475216] kthread+0x166/0x190
+[ 36.476267] ret_from_fork+0x22/0x30
+[ 36.477447]
+[ 36.478160] Freed by task 24:
+[ 36.479239] kasan_set_track+0x50/0x80
+[ 36.480512] kasan_save_free_info+0x2b/0x40
+[ 36.481808] ____kasan_slab_free+0x122/0x1a0
+[ 36.483173] __kmem_cache_free+0xc4/0x200
+[ 36.484563] smsusb_term_device+0xcd/0xf0
+[ 36.485896] smsusb_probe+0xc85/0xc90
+[ 36.486976] usb_probe_interface+0x2d1/0x4c0
+[ 36.488303] really_probe+0x1d5/0x580
+[ 36.489498] __driver_probe_device+0xe3/0x130
+[ 36.491140] driver_probe_device+0x49/0x220
+[ 36.492475] __device_attach_driver+0x19e/0x1b0
+[ 36.493988] bus_for_each_drv+0xcb/0x110
+[ 36.495171] __device_attach+0x132/0x1f0
+[ 36.496617] bus_probe_device+0x59/0xf0
+[ 36.497875] device_add+0x4ec/0x7b0
+[ 36.498972] usb_set_configuration+0xc63/0xe10
+[ 36.500264] usb_generic_driver_probe+0x3b/0x80
+[ 36.501740] usb_probe_device+0x90/0x110
+[ 36.503084] really_probe+0x1d5/0x580
+[ 36.504241] __driver_probe_device+0xe3/0x130
+[ 36.505548] driver_probe_device+0x49/0x220
+[ 36.506766] __device_attach_driver+0x19e/0x1b0
+[ 36.508368] bus_for_each_drv+0xcb/0x110
+[ 36.509646] __device_attach+0x132/0x1f0
+[ 36.510911] bus_probe_device+0x59/0xf0
+[ 36.512103] device_add+0x4ec/0x7b0
+[ 36.513215] usb_new_device+0x863/0xa00
+[ 36.514736] hub_event+0x18c7/0x2220
+[ 36.516130] process_one_work+0x34c/0x5b0
+[ 36.517396] worker_thread+0x4b7/0x890
+[ 36.518591] kthread+0x166/0x190
+[ 36.519599] ret_from_fork+0x22/0x30
+[ 36.520851]
+[ 36.521405] Last potentially related work creation:
+[ 36.523143] kasan_save_stack+0x3f/0x60
+[ 36.524275] kasan_record_aux_stack_noalloc+0x9d/0xb0
+[ 36.525831] insert_work+0x25/0x130
+[ 36.527039] __queue_work+0x4d4/0x620
+[ 36.528236] queue_work_on+0x72/0xb0
+[ 36.529344] __usb_hcd_giveback_urb+0x13f/0x1b0
+[ 36.530819] dummy_timer+0x350/0x1a40
+[ 36.532149] call_timer_fn+0x2c/0x190
+[ 36.533567] expire_timers+0x69/0x1f0
+[ 36.534736] __run_timers+0x289/0x2d0
+[ 36.535841] run_timer_softirq+0x2d/0x60
+[ 36.537110] __do_softirq+0x116/0x380
+[ 36.538377]
+[ 36.538950] Second to last potentially related work creation:
+[ 36.540855] kasan_save_stack+0x3f/0x60
+[ 36.542084] kasan_record_aux_stack_noalloc+0x9d/0xb0
+[ 36.543592] insert_work+0x25/0x130
+[ 36.544891] __queue_work+0x4d4/0x620
+[ 36.546168] queue_work_on+0x72/0xb0
+[ 36.547328] __usb_hcd_giveback_urb+0x13f/0x1b0
+[ 36.548805] dummy_timer+0x350/0x1a40
+[ 36.550116] call_timer_fn+0x2c/0x190
+[ 36.551570] expire_timers+0x69/0x1f0
+[ 36.552762] __run_timers+0x289/0x2d0
+[ 36.553916] run_timer_softirq+0x2d/0x60
+[ 36.555118] __do_softirq+0x116/0x380
+[ 36.556239]
+[ 36.556807] The buggy address belongs to the object at ffff888005960000
+[ 36.556807] which belongs to the cache kmalloc-4k of size 4096
+[ 36.560652] The buggy address is located 232 bytes inside of
+[ 36.560652] 4096-byte region [ffff888005960000, ffff888005961000)
+[ 36.564791]
+[ 36.565355] The buggy address belongs to the physical page:
+[ 36.567212] page:000000004f0a0731 refcount:1 mapcount:0 mapping:0000000000000000 index:0x00
+[ 36.570534] head:000000004f0a0731 order:3 compound_mapcount:0 subpages_mapcount:0 compound0
+[ 36.573717] flags: 0x100000000010200(slab|head|node=0|zone=1)
+[ 36.575481] raw: 0100000000010200 ffff888001042140 dead000000000122 0000000000000000
+[ 36.577842] raw: 0000000000000000 0000000000040004 00000001ffffffff 0000000000000000
+[ 36.580175] page dumped because: kasan: bad access detected
+[ 36.581994]
+[ 36.582548] Memory state around the buggy address:
+[ 36.583983] ffff88800595ff80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
+[ 36.586240] ffff888005960000: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+[ 36.588884] >ffff888005960080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+[ 36.591071] ^
+[ 36.593295] ffff888005960100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+[ 36.595705] ffff888005960180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+[ 36.598026] ==================================================================
+[ 36.600224] Disabling lock debugging due to kernel taint
+[ 36.602681] general protection fault, probably for non-canonical address 0x43600a000000060I
+[ 36.607129] CPU: 0 PID: 49 Comm: kworker/0:2 Tainted: G B 6.2.0-rc3-15798-8
+[ 36.611115] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g15584
+[ 36.615026] Workqueue: events do_submit_urb
+[ 36.616290] RIP: 0010:_raw_spin_lock_irqsave+0x8a/0xd0
+[ 36.618107] Code: 24 00 00 00 00 48 89 df be 04 00 00 00 e8 9e b5 c6 fe 48 89 ef be 04 00 5
+[ 36.623522] RSP: 0018:ffff888004b6fcf0 EFLAGS: 00010046
+[ 36.625072] RAX: 0000000000000000 RBX: 043600a000000060 RCX: ffffffff9fc0e0d7
+[ 36.627206] RDX: 0000000000000000 RSI: dffffc0000000000 RDI: ffff888004b6fcf0
+[ 36.629813] RBP: ffff888004b6fcf0 R08: dffffc0000000000 R09: ffffed100096df9f
+[ 36.631974] R10: dfffe9100096dfa0 R11: 1ffff1100096df9e R12: ffff888005960020
+[ 36.634285] R13: ffff8880059600f0 R14: 0000000000000246 R15: 0000000000000001
+[ 36.636438] FS: 0000000000000000(0000) GS:ffff88806d600000(0000) knlGS:0000000000000000
+[ 36.639092] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 36.640951] CR2: 00007f07476819a3 CR3: 0000000004a34000 CR4: 00000000000006f0
+[ 36.643411] Call Trace:
+[ 36.644215] <TASK>
+[ 36.644902] smscore_getbuffer+0x3e/0x1e0
+[ 36.646147] do_submit_urb+0x4f/0x190
+[ 36.647449] process_one_work+0x34c/0x5b0
+[ 36.648777] worker_thread+0x4b7/0x890
+[ 36.649984] ? worker_clr_flags+0x90/0x90
+[ 36.651166] kthread+0x166/0x190
+[ 36.652151] ? kthread_blkcg+0x50/0x50
+[ 36.653547] ret_from_fork+0x22/0x30
+[ 36.655051] </TASK>
+[ 36.655733] Modules linked in:
+[ 36.656787] ---[ end trace 0000000000000000 ]---
+[ 36.658328] RIP: 0010:_raw_spin_lock_irqsave+0x8a/0xd0
+[ 36.660045] Code: 24 00 00 00 00 48 89 df be 04 00 00 00 e8 9e b5 c6 fe 48 89 ef be 04 00 5
+[ 36.665730] RSP: 0018:ffff888004b6fcf0 EFLAGS: 00010046
+[ 36.667448] RAX: 0000000000000000 RBX: 043600a000000060 RCX: ffffffff9fc0e0d7
+[ 36.669675] RDX: 0000000000000000 RSI: dffffc0000000000 RDI: ffff888004b6fcf0
+[ 36.672645] RBP: ffff888004b6fcf0 R08: dffffc0000000000 R09: ffffed100096df9f
+[ 36.674921] R10: dfffe9100096dfa0 R11: 1ffff1100096df9e R12: ffff888005960020
+[ 36.677034] R13: ffff8880059600f0 R14: 0000000000000246 R15: 0000000000000001
+[ 36.679184] FS: 0000000000000000(0000) GS:ffff88806d600000(0000) knlGS:0000000000000000
+[ 36.681655] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 36.683383] CR2: 00007f07476819a3 CR3: 0000000004a34000 CR4: 00000000000006f0
+[ 36.685733] Kernel panic - not syncing: Fatal exception
+[ 36.688585] Kernel Offset: 0x1d400000 from 0xffffffff81000000 (relocation range: 0xfffffff)
+[ 36.692199] ---[ end Kernel panic - not syncing: Fatal exception ]---
+
+When the siano device is plugged in, it may call the following functions
+to initialize the device.
+
+smsusb_probe()-->smsusb_init_device()-->smscore_start_device().
+
+When smscore_start_device() gets failed, the function smsusb_term_device()
+will be called and smsusb_device_t will be deallocated. Although we use
+usb_kill_urb() in smsusb_stop_streaming() to cancel transfer requests
+and wait for them to finish, the worker threads that are scheduled by
+smsusb_onresponse() may be still running. As a result, the UAF bugs
+could happen.
+
+We add cancel_work_sync() in smsusb_stop_streaming() in order that the
+worker threads could finish before the smsusb_device_t is deallocated.
+
+Fixes: dd47fbd40e6e ("[media] smsusb: don't sleep while atomic")
+Signed-off-by: Duoming Zhou <duoming@zju.edu.cn>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/siano/smsusb.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/media/usb/siano/smsusb.c b/drivers/media/usb/siano/smsusb.c
+index df4c5dcba39cd..1babfe6e2c361 100644
+--- a/drivers/media/usb/siano/smsusb.c
++++ b/drivers/media/usb/siano/smsusb.c
+@@ -179,6 +179,7 @@ static void smsusb_stop_streaming(struct smsusb_device_t *dev)
+
+ for (i = 0; i < MAX_URBS; i++) {
+ usb_kill_urb(&dev->surbs[i].urb);
++ cancel_work_sync(&dev->surbs[i].wq);
+
+ if (dev->surbs[i].cb) {
+ smscore_putbuffer(dev->coredev, dev->surbs[i].cb);
+--
+2.39.2
+
--- /dev/null
+From bc70309394cd5655ff5a00488199dfbd2862f7bc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Dec 2022 14:15:55 +0800
+Subject: mfd: pcf50633-adc: Fix potential memleak in pcf50633_adc_async_read()
+
+From: Qiheng Lin <linqiheng@huawei.com>
+
+[ Upstream commit 8b450dcff23aa254844492831a8e2b508a9d522d ]
+
+`req` is allocated in pcf50633_adc_async_read(), but
+adc_enqueue_request() could fail to insert the `req` into queue.
+We need to check the return value and free it in the case of failure.
+
+Fixes: 08c3e06a5eb2 ("mfd: PCF50633 adc driver")
+Signed-off-by: Qiheng Lin <linqiheng@huawei.com>
+Signed-off-by: Lee Jones <lee@kernel.org>
+Link: https://lore.kernel.org/r/20221208061555.8776-1-linqiheng@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/pcf50633-adc.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mfd/pcf50633-adc.c b/drivers/mfd/pcf50633-adc.c
+index 5cd653e615125..191b1bc6141c2 100644
+--- a/drivers/mfd/pcf50633-adc.c
++++ b/drivers/mfd/pcf50633-adc.c
+@@ -136,6 +136,7 @@ int pcf50633_adc_async_read(struct pcf50633 *pcf, int mux, int avg,
+ void *callback_param)
+ {
+ struct pcf50633_adc_request *req;
++ int ret;
+
+ /* req is freed when the result is ready, in interrupt handler */
+ req = kmalloc(sizeof(*req), GFP_KERNEL);
+@@ -147,7 +148,11 @@ int pcf50633_adc_async_read(struct pcf50633 *pcf, int mux, int avg,
+ req->callback = callback;
+ req->callback_param = callback_param;
+
+- return adc_enqueue_request(pcf, req);
++ ret = adc_enqueue_request(pcf, req);
++ if (ret)
++ kfree(req);
++
++ return ret;
+ }
+ EXPORT_SYMBOL_GPL(pcf50633_adc_async_read);
+
+--
+2.39.2
+
--- /dev/null
+From 22c32e0d738c46f7e510a864eac195f0b5bf58b7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Feb 2023 12:07:49 -0800
+Subject: MIPS: SMP-CPS: fix build error when HOTPLUG_CPU not set
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit 6f02e39fa40f16c24e7a5c599a854c0d1682788d ]
+
+When MIPS_CPS=y, MIPS_CPS_PM is not set, HOTPLUG_CPU is not set, and
+KEXEC=y, cps_shutdown_this_cpu() attempts to call cps_pm_enter_state(),
+which is not built when MIPS_CPS_PM is not set.
+Conditionally execute the else branch based on CONFIG_HOTPLUG_CPU
+to remove the build error.
+This build failure is from a randconfig file.
+
+mips-linux-ld: arch/mips/kernel/smp-cps.o: in function `$L162':
+smp-cps.c:(.text.cps_kexec_nonboot_cpu+0x31c): undefined reference to `cps_pm_enter_state'
+
+Fixes: 1447864bee4c ("MIPS: kexec: CPS systems to halt nonboot CPUs")
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Cc: Dengcheng Zhu <dzhu@wavecomp.com>
+Cc: Paul Burton <paulburton@kernel.org>
+Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Cc: linux-mips@vger.kernel.org
+Cc: Sergei Shtylyov <sergei.shtylyov@gmail.com>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/mips/kernel/smp-cps.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
+index dbb3f1fc71ab6..f659adb681bc3 100644
+--- a/arch/mips/kernel/smp-cps.c
++++ b/arch/mips/kernel/smp-cps.c
+@@ -423,9 +423,11 @@ static void cps_shutdown_this_cpu(enum cpu_death death)
+ wmb();
+ }
+ } else {
+- pr_debug("Gating power to core %d\n", core);
+- /* Power down the core */
+- cps_pm_enter_state(CPS_PM_POWER_GATED);
++ if (IS_ENABLED(CONFIG_HOTPLUG_CPU)) {
++ pr_debug("Gating power to core %d\n", core);
++ /* Power down the core */
++ cps_pm_enter_state(CPS_PM_POWER_GATED);
++ }
+ }
+ }
+
+--
+2.39.2
+
--- /dev/null
+From a9fa43601258410ff763b1e77892bfca6912e172 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 19 Feb 2023 15:15:25 -0800
+Subject: MIPS: vpe-mt: drop physical_memsize
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit 91dc288f4edf0d768e46c2c6d33e0ab703403459 ]
+
+When neither LANTIQ nor MIPS_MALTA is set, 'physical_memsize' is not
+declared. This causes the build to fail with:
+
+mips-linux-ld: arch/mips/kernel/vpe-mt.o: in function `vpe_run':
+arch/mips/kernel/vpe-mt.c:(.text.vpe_run+0x280): undefined reference to `physical_memsize'
+
+LANTIQ is not using 'physical_memsize' and MIPS_MALTA's use of it is
+self-contained in mti-malta/malta-dtshim.c.
+Use of physical_memsize in vpe-mt.c appears to be unused, so eliminate
+this loader mode completely and require VPE programs to be compiled with
+DFLT_STACK_SIZE and DFLT_HEAP_SIZE defined.
+
+Fixes: 9050d50e2244 ("MIPS: lantiq: Set physical_memsize")
+Fixes: 1a2a6d7e8816 ("MIPS: APRP: Split VPE loader into separate files.")
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Reported-by: kernel test robot <lkp@intel.com>
+Link: https://lore.kernel.org/all/202302030625.2g3E98sY-lkp@intel.com/
+Cc: Dengcheng Zhu <dzhu@wavecomp.com>
+Cc: John Crispin <john@phrozen.org>
+Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Cc: Philippe Mathieu-Daudé <philmd@linaro.org>
+Cc: "Steven J. Hill" <Steven.Hill@imgtec.com>
+Cc: Qais Yousef <Qais.Yousef@imgtec.com>
+Cc: Yang Yingliang <yangyingliang@huawei.com>
+Cc: Hauke Mehrtens <hauke@hauke-m.de>
+Cc: James Hogan <jhogan@kernel.org>
+Cc: linux-mips@vger.kernel.org
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/mips/include/asm/vpe.h | 1 -
+ arch/mips/kernel/vpe-mt.c | 7 +++----
+ arch/mips/lantiq/prom.c | 6 ------
+ 3 files changed, 3 insertions(+), 11 deletions(-)
+
+diff --git a/arch/mips/include/asm/vpe.h b/arch/mips/include/asm/vpe.h
+index 80e70dbd1f641..012731546cf60 100644
+--- a/arch/mips/include/asm/vpe.h
++++ b/arch/mips/include/asm/vpe.h
+@@ -104,7 +104,6 @@ struct vpe_control {
+ struct list_head tc_list; /* Thread contexts */
+ };
+
+-extern unsigned long physical_memsize;
+ extern struct vpe_control vpecontrol;
+ extern const struct file_operations vpe_fops;
+
+diff --git a/arch/mips/kernel/vpe-mt.c b/arch/mips/kernel/vpe-mt.c
+index 9fd7cd48ea1d2..496ed8f362f62 100644
+--- a/arch/mips/kernel/vpe-mt.c
++++ b/arch/mips/kernel/vpe-mt.c
+@@ -92,12 +92,11 @@ int vpe_run(struct vpe *v)
+ write_tc_c0_tchalt(read_tc_c0_tchalt() & ~TCHALT_H);
+
+ /*
+- * The sde-kit passes 'memsize' to __start in $a3, so set something
+- * here... Or set $a3 to zero and define DFLT_STACK_SIZE and
+- * DFLT_HEAP_SIZE when you compile your program
++ * We don't pass the memsize here, so VPE programs need to be
++ * compiled with DFLT_STACK_SIZE and DFLT_HEAP_SIZE defined.
+ */
++ mttgpr(7, 0);
+ mttgpr(6, v->ntcs);
+- mttgpr(7, physical_memsize);
+
+ /* set up VPE1 */
+ /*
+diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c
+index 3f568f5aae2d1..2729a4b63e187 100644
+--- a/arch/mips/lantiq/prom.c
++++ b/arch/mips/lantiq/prom.c
+@@ -22,12 +22,6 @@
+ DEFINE_SPINLOCK(ebu_lock);
+ EXPORT_SYMBOL_GPL(ebu_lock);
+
+-/*
+- * This is needed by the VPE loader code, just set it to 0 and assume
+- * that the firmware hardcodes this value to something useful.
+- */
+-unsigned long physical_memsize = 0L;
+-
+ /*
+ * this struct is filled by the soc specific detection code and holds
+ * information about the specific soc type, revision and name
+--
+2.39.2
+
--- /dev/null
+From a59c0b490c3923e0c00dc591654709641cf9e4a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 28 Jan 2023 14:41:11 +0100
+Subject: mtd: rawnand: fsl_elbc: Propagate HW ECC settings to HW
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pali Rohár <pali@kernel.org>
+
+[ Upstream commit b56265257d38af5abf43bd5461ca166b401c35a5 ]
+
+It is possible that current chip->ecc.engine_type value does not match to
+configured HW value (if HW ECC checking and generating is enabled or not).
+
+This can happen with old U-Boot bootloader version which either does not
+initialize NAND (and let it in some default unusable state) or initialize
+NAND with different parameters than what is specified in kernel DTS file.
+
+So if kernel chose to use some chip->ecc.engine_type settings (e.g. from
+DTS file) then do not depend on bootloader HW configuration and configures
+HW ECC settings according to chip->ecc.engine_type value.
+
+BR_DECC must be set to BR_DECC_CHK_GEN when HW is doing ECC (both
+generating and checking), or to BR_DECC_OFF when HW is not doing ECC.
+
+This change fixes usage of SW ECC support in case bootloader explicitly
+enabled HW ECC support and kernel DTS file has specified to use SW ECC.
+(Of course this works only in case when NAND is not a boot device and both
+bootloader and kernel are loaded from different location, e.g. FLASH NOR.)
+
+Fixes: f6424c22aa36 ("mtd: rawnand: fsl_elbc: Make SW ECC work")
+Signed-off-by: Pali Rohár <pali@kernel.org>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20230128134111.32559-1-pali@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/nand/raw/fsl_elbc_nand.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/mtd/nand/raw/fsl_elbc_nand.c b/drivers/mtd/nand/raw/fsl_elbc_nand.c
+index c174b6dc3c6ba..093019455f5b0 100644
+--- a/drivers/mtd/nand/raw/fsl_elbc_nand.c
++++ b/drivers/mtd/nand/raw/fsl_elbc_nand.c
+@@ -726,6 +726,7 @@ static int fsl_elbc_attach_chip(struct nand_chip *chip)
+ struct fsl_lbc_ctrl *ctrl = priv->ctrl;
+ struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
+ unsigned int al;
++ u32 br;
+
+ /*
+ * if ECC was not chosen in DT, decide whether to use HW or SW ECC from
+@@ -765,6 +766,13 @@ static int fsl_elbc_attach_chip(struct nand_chip *chip)
+ return -EINVAL;
+ }
+
++ /* enable/disable HW ECC checking and generating based on if HW ECC was chosen */
++ br = in_be32(&lbc->bank[priv->bank].br) & ~BR_DECC;
++ if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_ON_HOST)
++ out_be32(&lbc->bank[priv->bank].br, br | BR_DECC_CHK_GEN);
++ else
++ out_be32(&lbc->bank[priv->bank].br, br | BR_DECC_OFF);
++
+ /* calculate FMR Address Length field */
+ al = 0;
+ if (chip->pagemask & 0xffff0000)
+--
+2.39.2
+
--- /dev/null
+From a6decfb038327abeb835a945782417991a789ed2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Dec 2022 12:15:24 -0600
+Subject: mtd: rawnand: sunxi: Fix the size of the last OOB region
+
+From: Samuel Holland <samuel@sholland.org>
+
+[ Upstream commit 34569d869532b54d6e360d224a0254dcdd6a1785 ]
+
+The previous code assigned to the wrong structure member.
+
+Fixes: c66811e6d350 ("mtd: nand: sunxi: switch to mtd_ooblayout_ops")
+Signed-off-by: Samuel Holland <samuel@sholland.org>
+Acked-By: Dhruva Gole <d-gole@ti.com>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20221229181526.53766-6-samuel@sholland.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/nand/raw/sunxi_nand.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c
+index 2a7ca3072f357..52eb28f3277cd 100644
+--- a/drivers/mtd/nand/raw/sunxi_nand.c
++++ b/drivers/mtd/nand/raw/sunxi_nand.c
+@@ -1587,7 +1587,7 @@ static int sunxi_nand_ooblayout_free(struct mtd_info *mtd, int section,
+ if (section < ecc->steps)
+ oobregion->length = 4;
+ else
+- oobregion->offset = mtd->oobsize - oobregion->offset;
++ oobregion->length = mtd->oobsize - oobregion->offset;
+
+ return 0;
+ }
+--
+2.39.2
+
--- /dev/null
+From 75ac4d61dba0bb092c5f5f7e6cfcd1424e7e847f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 4 Feb 2023 17:39:20 +0000
+Subject: net: add sock_init_data_uid()
+
+From: Pietro Borrello <borrello@diag.uniroma1.it>
+
+[ Upstream commit 584f3742890e966d2f0a1f3c418c9ead70b2d99e ]
+
+Add sock_init_data_uid() to explicitly initialize the socket uid.
+To initialise the socket uid, sock_init_data() assumes a the struct
+socket* sock is always embedded in a struct socket_alloc, used to
+access the corresponding inode uid. This may not be true.
+Examples are sockets created in tun_chr_open() and tap_open().
+
+Fixes: 86741ec25462 ("net: core: Add a UID field to struct sock.")
+Signed-off-by: Pietro Borrello <borrello@diag.uniroma1.it>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/sock.h | 7 ++++++-
+ net/core/sock.c | 15 ++++++++++++---
+ 2 files changed, 18 insertions(+), 4 deletions(-)
+
+diff --git a/include/net/sock.h b/include/net/sock.h
+index 0f48d50a6dde7..1d8529311d6f9 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -1775,7 +1775,12 @@ void sk_common_release(struct sock *sk);
+ * Default socket callbacks and setup code
+ */
+
+-/* Initialise core socket variables */
++/* Initialise core socket variables using an explicit uid. */
++void sock_init_data_uid(struct socket *sock, struct sock *sk, kuid_t uid);
++
++/* Initialise core socket variables.
++ * Assumes struct socket *sock is embedded in a struct socket_alloc.
++ */
+ void sock_init_data(struct socket *sock, struct sock *sk);
+
+ /*
+diff --git a/net/core/sock.c b/net/core/sock.c
+index 1bb6a003323b3..c5ae520d4a69c 100644
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -2968,7 +2968,7 @@ void sk_stop_timer_sync(struct sock *sk, struct timer_list *timer)
+ }
+ EXPORT_SYMBOL(sk_stop_timer_sync);
+
+-void sock_init_data(struct socket *sock, struct sock *sk)
++void sock_init_data_uid(struct socket *sock, struct sock *sk, kuid_t uid)
+ {
+ sk_init_common(sk);
+ sk->sk_send_head = NULL;
+@@ -2987,11 +2987,10 @@ void sock_init_data(struct socket *sock, struct sock *sk)
+ sk->sk_type = sock->type;
+ RCU_INIT_POINTER(sk->sk_wq, &sock->wq);
+ sock->sk = sk;
+- sk->sk_uid = SOCK_INODE(sock)->i_uid;
+ } else {
+ RCU_INIT_POINTER(sk->sk_wq, NULL);
+- sk->sk_uid = make_kuid(sock_net(sk)->user_ns, 0);
+ }
++ sk->sk_uid = uid;
+
+ rwlock_init(&sk->sk_callback_lock);
+ if (sk->sk_kern_sock)
+@@ -3049,6 +3048,16 @@ void sock_init_data(struct socket *sock, struct sock *sk)
+ refcount_set(&sk->sk_refcnt, 1);
+ atomic_set(&sk->sk_drops, 0);
+ }
++EXPORT_SYMBOL(sock_init_data_uid);
++
++void sock_init_data(struct socket *sock, struct sock *sk)
++{
++ kuid_t uid = sock ?
++ SOCK_INODE(sock)->i_uid :
++ make_kuid(sock_net(sk)->user_ns, 0);
++
++ sock_init_data_uid(sock, sk, uid);
++}
+ EXPORT_SYMBOL(sock_init_data);
+
+ void lock_sock_nested(struct sock *sk, int subclass)
+--
+2.39.2
+
--- /dev/null
+From 0da72130e860fd9a0ab2226762c0ce55e93fea4d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 Jan 2023 16:08:19 -0800
+Subject: net: bcmgenet: Add a check for oversized packets
+
+From: Florian Fainelli <f.fainelli@gmail.com>
+
+[ Upstream commit 5c0862c2c962052ed5055220a00ac1cefb92fbcd ]
+
+Occasionnaly we may get oversized packets from the hardware which
+exceed the nomimal 2KiB buffer size we allocate SKBs with. Add an early
+check which drops the packet to avoid invoking skb_over_panic() and move
+on to processing the next packet.
+
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/genet/bcmgenet.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+index e0a6a2e62d23b..7667cbb5adfd6 100644
+--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+@@ -2263,6 +2263,14 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring,
+ __func__, p_index, ring->c_index,
+ ring->read_ptr, dma_length_status);
+
++ if (unlikely(len > RX_BUF_LENGTH)) {
++ netif_err(priv, rx_status, dev, "oversized packet\n");
++ dev->stats.rx_length_errors++;
++ dev->stats.rx_errors++;
++ dev_kfree_skb_any(skb);
++ goto next;
++ }
++
+ if (unlikely(!(dma_flag & DMA_EOP) || !(dma_flag & DMA_SOP))) {
+ netif_err(priv, rx_status, dev,
+ "dropping fragmented packet!\n");
+--
+2.39.2
+
--- /dev/null
+From 2a97a1b5fe95b78fd8891ff492869b9288a18556 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Feb 2023 11:41:28 -0800
+Subject: net: bcmgenet: fix MoCA LED control
+
+From: Doug Berger <opendmb@gmail.com>
+
+[ Upstream commit a7515af9fb8f0890fe540b108def4a86b9e8330a ]
+
+When the bcmgenet_mii_config() code was refactored it was missed
+that the LED control for the MoCA interface got overwritten by
+the port_ctrl value. Its previous programming is restored here.
+
+Fixes: 4f8d81b77e66 ("net: bcmgenet: Refactor register access in bcmgenet_mii_config")
+Signed-off-by: Doug Berger <opendmb@gmail.com>
+Acked-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/genet/bcmmii.c | 11 ++---------
+ 1 file changed, 2 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c
+index f9e91304d2327..4b875838a6467 100644
+--- a/drivers/net/ethernet/broadcom/genet/bcmmii.c
++++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c
+@@ -165,15 +165,6 @@ void bcmgenet_phy_power_set(struct net_device *dev, bool enable)
+
+ static void bcmgenet_moca_phy_setup(struct bcmgenet_priv *priv)
+ {
+- u32 reg;
+-
+- if (!GENET_IS_V5(priv)) {
+- /* Speed settings are set in bcmgenet_mii_setup() */
+- reg = bcmgenet_sys_readl(priv, SYS_PORT_CTRL);
+- reg |= LED_ACT_SOURCE_MAC;
+- bcmgenet_sys_writel(priv, reg, SYS_PORT_CTRL);
+- }
+-
+ if (priv->hw_params->flags & GENET_HAS_MOCA_LINK_DET)
+ fixed_phy_set_link_update(priv->dev->phydev,
+ bcmgenet_fixed_phy_link_update);
+@@ -206,6 +197,8 @@ int bcmgenet_mii_config(struct net_device *dev, bool init)
+
+ if (!phy_name) {
+ phy_name = "MoCA";
++ if (!GENET_IS_V5(priv))
++ port_ctrl |= LED_ACT_SOURCE_MAC;
+ bcmgenet_moca_phy_setup(priv);
+ }
+ break;
+--
+2.39.2
+
--- /dev/null
+From a85a13582a82d2d8500b8fcb6706459d888451a2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Dec 2021 01:44:36 -0800
+Subject: net: ethernet: ti: add missing of_node_put before return
+
+From: Wang Qing <wangqing@vivo.com>
+
+[ Upstream commit be565ec71d1d59438bed0c7ed0a252a327e0b0ef ]
+
+Fix following coccicheck warning:
+WARNING: Function "for_each_child_of_node"
+should have of_node_put() before return.
+
+Early exits from for_each_child_of_node should decrement the
+node reference counter.
+
+Signed-off-by: Wang Qing <wangqing@vivo.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ti/am65-cpsw-nuss.c | 29 ++++++++++++++++--------
+ 1 file changed, 20 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+index 5300e1439e1e5..4074310abcff4 100644
+--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c
++++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+@@ -1724,13 +1724,14 @@ static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common)
+ if (ret < 0) {
+ dev_err(dev, "%pOF error reading port_id %d\n",
+ port_np, ret);
+- return ret;
++ goto of_node_put;
+ }
+
+ if (!port_id || port_id > common->port_num) {
+ dev_err(dev, "%pOF has invalid port_id %u %s\n",
+ port_np, port_id, port_np->name);
+- return -EINVAL;
++ ret = -EINVAL;
++ goto of_node_put;
+ }
+
+ port = am65_common_get_port(common, port_id);
+@@ -1746,8 +1747,10 @@ static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common)
+ (AM65_CPSW_NU_FRAM_PORT_OFFSET * (port_id - 1));
+
+ port->slave.mac_sl = cpsw_sl_get("am65", dev, port->port_base);
+- if (IS_ERR(port->slave.mac_sl))
+- return PTR_ERR(port->slave.mac_sl);
++ if (IS_ERR(port->slave.mac_sl)) {
++ ret = PTR_ERR(port->slave.mac_sl);
++ goto of_node_put;
++ }
+
+ port->disabled = !of_device_is_available(port_np);
+ if (port->disabled)
+@@ -1758,7 +1761,7 @@ static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common)
+ ret = PTR_ERR(port->slave.ifphy);
+ dev_err(dev, "%pOF error retrieving port phy: %d\n",
+ port_np, ret);
+- return ret;
++ goto of_node_put;
+ }
+
+ port->slave.mac_only =
+@@ -1767,10 +1770,12 @@ static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common)
+ /* get phy/link info */
+ if (of_phy_is_fixed_link(port_np)) {
+ ret = of_phy_register_fixed_link(port_np);
+- if (ret)
+- return dev_err_probe(dev, ret,
++ if (ret) {
++ ret = dev_err_probe(dev, ret,
+ "failed to register fixed-link phy %pOF\n",
+ port_np);
++ goto of_node_put;
++ }
+ port->slave.phy_node = of_node_get(port_np);
+ } else {
+ port->slave.phy_node =
+@@ -1780,14 +1785,15 @@ static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common)
+ if (!port->slave.phy_node) {
+ dev_err(dev,
+ "slave[%d] no phy found\n", port_id);
+- return -ENODEV;
++ ret = -ENODEV;
++ goto of_node_put;
+ }
+
+ ret = of_get_phy_mode(port_np, &port->slave.phy_if);
+ if (ret) {
+ dev_err(dev, "%pOF read phy-mode err %d\n",
+ port_np, ret);
+- return ret;
++ goto of_node_put;
+ }
+
+ mac_addr = of_get_mac_address(port_np);
+@@ -1804,6 +1810,11 @@ static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common)
+ of_node_put(node);
+
+ return 0;
++
++of_node_put:
++ of_node_put(port_np);
++ of_node_put(node);
++ return ret;
+ }
+
+ static void am65_cpsw_pcpu_stats_free(void *data)
+--
+2.39.2
+
--- /dev/null
+From 404c6a1bf6e1aa1e590f39345c1dd1aa7e016285 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Oct 2020 22:07:04 +0200
+Subject: net: ethernet: ti: am65-cpsw: fix tx csum offload for multi mac mode
+
+From: Grygorii Strashko <grygorii.strashko@ti.com>
+
+[ Upstream commit 97067aaf127487788a297267dede0008cd75bb7b ]
+
+The current implementation uses .ndo_set_features() callback to track
+NETIF_F_HW_CSUM feature changes and update generic
+CPSW_P0_CONTROL_REG.RX_CHECKSUM_EN option accordingly. It's not going to
+work in case of multi-port devices as TX csum offload can be changed per
+netdev.
+
+On K3 CPSWxG devices TX csum offload enabled in the following way:
+
+ - the CPSW_P0_CONTROL_REG.RX_CHECKSUM_EN option enables TX csum offload in
+generic and affects all TX DMA channels and packets;
+
+ - corresponding fields in TX DMA descriptor have to be filed properly when
+upper layer wants to offload TX csum (skb->ip_summed == CHECKSUM_PARTIAL)
+and it's per-packet option.
+
+The Linux Network core is expected to never request TX csum offload if
+netdev NETIF_F_HW_CSUM feature is disabled, and, as result, TX DMA
+descriptors should not be modified, and per-packet TX csum offload will be
+disabled (or enabled) on per-netdev basis. Which, in turn, makes it safe to
+enable the CPSW_P0_CONTROL_REG.RX_CHECKSUM_EN option unconditionally.
+
+Hence, fix TX csum offload for multi-port devices by:
+ - enabling the CPSW_P0_CONTROL_REG.RX_CHECKSUM_EN option in
+am65_cpsw_nuss_common_open() unconditionally
+ - and removing .ndo_set_features() callback implementation, which was used
+only NETIF_F_HW_CSUM feature update purposes
+
+Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
+Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ti/am65-cpsw-nuss.c | 30 +-----------------------
+ 1 file changed, 1 insertion(+), 29 deletions(-)
+
+diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+index 059d68d48f1e9..487c1570dd420 100644
+--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c
++++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+@@ -426,9 +426,7 @@ static int am65_cpsw_nuss_common_open(struct am65_cpsw_common *common,
+ writel(common->rx_flow_id_base,
+ host_p->port_base + AM65_CPSW_PORT0_REG_FLOW_ID_OFFSET);
+ /* en tx crc offload */
+- if (features & NETIF_F_HW_CSUM)
+- writel(AM65_CPSW_P0_REG_CTL_RX_CHECKSUM_EN,
+- host_p->port_base + AM65_CPSW_P0_REG_CTL);
++ writel(AM65_CPSW_P0_REG_CTL_RX_CHECKSUM_EN, host_p->port_base + AM65_CPSW_P0_REG_CTL);
+
+ am65_cpsw_nuss_set_p0_ptype(common);
+
+@@ -1369,31 +1367,6 @@ static void am65_cpsw_nuss_ndo_get_stats(struct net_device *dev,
+ stats->tx_dropped = dev->stats.tx_dropped;
+ }
+
+-static int am65_cpsw_nuss_ndo_slave_set_features(struct net_device *ndev,
+- netdev_features_t features)
+-{
+- struct am65_cpsw_common *common = am65_ndev_to_common(ndev);
+- netdev_features_t changes = features ^ ndev->features;
+- struct am65_cpsw_host *host_p;
+-
+- host_p = am65_common_get_host(common);
+-
+- if (changes & NETIF_F_HW_CSUM) {
+- bool enable = !!(features & NETIF_F_HW_CSUM);
+-
+- dev_info(common->dev, "Turn %s tx-checksum-ip-generic\n",
+- enable ? "ON" : "OFF");
+- if (enable)
+- writel(AM65_CPSW_P0_REG_CTL_RX_CHECKSUM_EN,
+- host_p->port_base + AM65_CPSW_P0_REG_CTL);
+- else
+- writel(0,
+- host_p->port_base + AM65_CPSW_P0_REG_CTL);
+- }
+-
+- return 0;
+-}
+-
+ static const struct net_device_ops am65_cpsw_nuss_netdev_ops_2g = {
+ .ndo_open = am65_cpsw_nuss_ndo_slave_open,
+ .ndo_stop = am65_cpsw_nuss_ndo_slave_stop,
+@@ -1406,7 +1379,6 @@ static const struct net_device_ops am65_cpsw_nuss_netdev_ops_2g = {
+ .ndo_vlan_rx_add_vid = am65_cpsw_nuss_ndo_slave_add_vid,
+ .ndo_vlan_rx_kill_vid = am65_cpsw_nuss_ndo_slave_kill_vid,
+ .ndo_do_ioctl = am65_cpsw_nuss_ndo_slave_ioctl,
+- .ndo_set_features = am65_cpsw_nuss_ndo_slave_set_features,
+ .ndo_setup_tc = am65_cpsw_qos_ndo_setup_tc,
+ };
+
+--
+2.39.2
+
--- /dev/null
+From 5b57f81ecba5868c6979fc785e70e923a7f7eabe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Oct 2020 22:07:07 +0200
+Subject: net: ethernet: ti: am65-cpsw: handle deferred probe with
+ dev_err_probe()
+
+From: Grygorii Strashko <grygorii.strashko@ti.com>
+
+[ Upstream commit 8fbc2f9edce23d19fc09ef5bf8d4eb38be2db0f8 ]
+
+Use new dev_err_probe() API to handle deferred probe properly and simplify
+the code.
+
+Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ti/am65-cpsw-nuss.c | 28 +++++++++---------------
+ 1 file changed, 10 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+index 487c1570dd420..5300e1439e1e5 100644
+--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c
++++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+@@ -1487,9 +1487,8 @@ static int am65_cpsw_nuss_init_tx_chns(struct am65_cpsw_common *common)
+ tx_chn->tx_chn_name,
+ &tx_cfg);
+ if (IS_ERR(tx_chn->tx_chn)) {
+- ret = PTR_ERR(tx_chn->tx_chn);
+- dev_err(dev, "Failed to request tx dma channel %d\n",
+- ret);
++ ret = dev_err_probe(dev, PTR_ERR(tx_chn->tx_chn),
++ "Failed to request tx dma channel\n");
+ goto err;
+ }
+
+@@ -1560,8 +1559,8 @@ static int am65_cpsw_nuss_init_rx_chns(struct am65_cpsw_common *common)
+
+ rx_chn->rx_chn = k3_udma_glue_request_rx_chn(dev, "rx", &rx_cfg);
+ if (IS_ERR(rx_chn->rx_chn)) {
+- ret = PTR_ERR(rx_chn->rx_chn);
+- dev_err(dev, "Failed to request rx dma channel %d\n", ret);
++ ret = dev_err_probe(dev, PTR_ERR(rx_chn->rx_chn),
++ "Failed to request rx dma channel\n");
+ goto err;
+ }
+
+@@ -1768,12 +1767,10 @@ static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common)
+ /* get phy/link info */
+ if (of_phy_is_fixed_link(port_np)) {
+ ret = of_phy_register_fixed_link(port_np);
+- if (ret) {
+- if (ret != -EPROBE_DEFER)
+- dev_err(dev, "%pOF failed to register fixed-link phy: %d\n",
+- port_np, ret);
+- return ret;
+- }
++ if (ret)
++ return dev_err_probe(dev, ret,
++ "failed to register fixed-link phy %pOF\n",
++ port_np);
+ port->slave.phy_node = of_node_get(port_np);
+ } else {
+ port->slave.phy_node =
+@@ -2062,13 +2059,8 @@ static int am65_cpsw_nuss_probe(struct platform_device *pdev)
+ return -ENOMEM;
+
+ clk = devm_clk_get(dev, "fck");
+- if (IS_ERR(clk)) {
+- ret = PTR_ERR(clk);
+-
+- if (ret != -EPROBE_DEFER)
+- dev_err(dev, "error getting fck clock %d\n", ret);
+- return ret;
+- }
++ if (IS_ERR(clk))
++ return dev_err_probe(dev, PTR_ERR(clk), "getting fck clock\n");
+ common->bus_freq = clk_get_rate(clk);
+
+ pm_runtime_enable(dev);
+--
+2.39.2
+
--- /dev/null
+From 64e2c3e188e5c549230e0047807dfc24b67cba6f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Jan 2023 19:57:04 +0200
+Subject: net/mlx5: Enhance debug print in page allocation failure
+
+From: Jack Morgenstein <jackm@nvidia.com>
+
+[ Upstream commit 7eef93003e5d20e1a6a6e59e12d914b5431cbda2 ]
+
+Provide more details to aid debugging.
+
+Fixes: bf0bf77f6519 ("mlx5: Support communicating arbitrary host page size to firmware")
+Signed-off-by: Eran Ben Elisha <eranbe@nvidia.com>
+Signed-off-by: Majd Dibbiny <majd@nvidia.com>
+Signed-off-by: Jack Morgenstein <jackm@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
+index a44a2bad5bbb5..1ea71f06fdb1c 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
+@@ -216,7 +216,8 @@ static int alloc_4k(struct mlx5_core_dev *dev, u64 *addr, u32 function)
+
+ n = find_first_bit(&fp->bitmask, 8 * sizeof(fp->bitmask));
+ if (n >= MLX5_NUM_4K_IN_PAGE) {
+- mlx5_core_warn(dev, "alloc 4k bug\n");
++ mlx5_core_warn(dev, "alloc 4k bug: fw page = 0x%llx, n = %u, bitmask: %lu, max num of 4K pages: %d\n",
++ fp->addr, n, fp->bitmask, MLX5_NUM_4K_IN_PAGE);
+ return -ENOENT;
+ }
+ clear_bit(n, &fp->bitmask);
+--
+2.39.2
+
--- /dev/null
+From e96c7605864e80b5732946bd0a28ac159e473ef3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Jan 2023 13:34:02 +0200
+Subject: net/mlx5: fw_tracer: Fix debug print
+
+From: Shay Drory <shayd@nvidia.com>
+
+[ Upstream commit 988c2352273997a242f15c4fc3711773515006a2 ]
+
+The debug message specify tdsn, but takes as an argument the
+tmsn. The correct argument is tmsn, hence, fix the print.
+
+Signed-off-by: Shay Drory <shayd@nvidia.com>
+Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+index 40d7bfca37499..0a011a41c039e 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+@@ -603,7 +603,7 @@ static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer,
+ } else {
+ cur_string = mlx5_tracer_message_get(tracer, tracer_event);
+ if (!cur_string) {
+- pr_debug("%s Got string event for unknown string tdsm: %d\n",
++ pr_debug("%s Got string event for unknown string tmsn: %d\n",
+ __func__, tracer_event->string_event.tmsn);
+ return -1;
+ }
+--
+2.39.2
+
--- /dev/null
+From 714b5509ff4570d6fc43f61c78204c2047872580 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Feb 2023 15:45:38 +1100
+Subject: NFS: fix disabling of swap
+
+From: NeilBrown <neilb@suse.de>
+
+[ Upstream commit 5bab56fff53ce161ed859d9559a10361d4f79578 ]
+
+When swap is activated to a file on an NFSv4 mount we arrange that the
+state manager thread is always present as starting a new thread requires
+memory allocations that might block waiting for swap.
+
+Unfortunately the code for allowing the state manager thread to exit when
+swap is disabled was not tested properly and does not work.
+This can be seen by examining /proc/fs/nfsfs/servers after disabling swap
+and unmounting the filesystem. The servers file will still list one
+entry. Also a "ps" listing will show the state manager thread is still
+present.
+
+There are two problems.
+ 1/ rpc_clnt_swap_deactivate() doesn't walk up the ->cl_parent list to
+ find the primary client on which the state manager runs.
+
+ 2/ The thread is not woken up properly and it immediately goes back to
+ sleep without checking whether it is really needed. Using
+ nfs4_schedule_state_manager() ensures a proper wake-up.
+
+Reported-by: Olga Kornievskaia <aglo@umich.edu>
+Fixes: 4dc73c679114 ("NFSv4: keep state manager thread active if swap is enabled")
+Signed-off-by: NeilBrown <neilb@suse.de>
+Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/nfs4proc.c | 4 +++-
+ net/sunrpc/clnt.c | 2 ++
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
+index 8f502e2ac34fd..8653335c17b67 100644
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -10400,7 +10400,9 @@ static void nfs4_disable_swap(struct inode *inode)
+ /* The state manager thread will now exit once it is
+ * woken.
+ */
+- wake_up_var(&NFS_SERVER(inode)->nfs_client->cl_state);
++ struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
++
++ nfs4_schedule_state_manager(clp);
+ }
+
+ static const struct inode_operations nfs4_dir_inode_operations = {
+diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
+index e190d38c4c827..c6e8bd78e35d6 100644
+--- a/net/sunrpc/clnt.c
++++ b/net/sunrpc/clnt.c
+@@ -3047,6 +3047,8 @@ rpc_clnt_swap_deactivate_callback(struct rpc_clnt *clnt,
+ void
+ rpc_clnt_swap_deactivate(struct rpc_clnt *clnt)
+ {
++ while (clnt != clnt->cl_parent)
++ clnt = clnt->cl_parent;
+ if (atomic_dec_if_positive(&clnt->cl_swapper) == 0)
+ rpc_clnt_iterate_for_each_xprt(clnt,
+ rpc_clnt_swap_deactivate_callback, NULL);
+--
+2.39.2
+
--- /dev/null
+From b7729876bb4bba452d3aada9abae01cec1fc68ed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Mar 2021 14:51:36 -0400
+Subject: NFS: Fix up handling of outstanding layoutcommit in
+ nfs_update_inode()
+
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+
+[ Upstream commit 709fa5769914b377af87962bbe4ff81ffb019b2d ]
+
+If there is an outstanding layoutcommit, then the list of attributes
+whose values are expected to change is not the full set. So let's
+be explicit about the full list.
+
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Stable-dep-of: b46d80bd2d6e ("nfs4trace: fix state manager flag printing")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/inode.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
+index 1adece1cff3ed..36f415278c042 100644
+--- a/fs/nfs/inode.c
++++ b/fs/nfs/inode.c
+@@ -1906,7 +1906,11 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
+ nfs_wcc_update_inode(inode, fattr);
+
+ if (pnfs_layoutcommit_outstanding(inode)) {
+- nfsi->cache_validity |= save_cache_validity & NFS_INO_INVALID_ATTR;
++ nfsi->cache_validity |=
++ save_cache_validity &
++ (NFS_INO_INVALID_CHANGE | NFS_INO_INVALID_CTIME |
++ NFS_INO_INVALID_MTIME | NFS_INO_INVALID_SIZE |
++ NFS_INO_REVAL_FORCED);
+ cache_revalidated = false;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 07f2bf2d010231ff9b1a00195e297dd124796755 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Feb 2023 08:18:23 -0500
+Subject: nfs4trace: fix state manager flag printing
+
+From: Benjamin Coddington <bcodding@redhat.com>
+
+[ Upstream commit b46d80bd2d6e7e063c625a20de54248afe8d4889 ]
+
+__print_flags wants a mask, not the enum value. Add two more flags.
+
+Fixes: 511ba52e4c01 ("NFS4: Trace state recovery operation")
+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/nfs4trace.h | 42 ++++++++++++++++++++++--------------------
+ 1 file changed, 22 insertions(+), 20 deletions(-)
+
+diff --git a/fs/nfs/nfs4trace.h b/fs/nfs/nfs4trace.h
+index 484c1da96dea2..d862df9761e77 100644
+--- a/fs/nfs/nfs4trace.h
++++ b/fs/nfs/nfs4trace.h
+@@ -584,32 +584,34 @@ TRACE_DEFINE_ENUM(NFS4CLNT_MOVED);
+ TRACE_DEFINE_ENUM(NFS4CLNT_LEASE_MOVED);
+ TRACE_DEFINE_ENUM(NFS4CLNT_DELEGATION_EXPIRED);
+ TRACE_DEFINE_ENUM(NFS4CLNT_RUN_MANAGER);
++TRACE_DEFINE_ENUM(NFS4CLNT_MANAGER_AVAILABLE);
+ TRACE_DEFINE_ENUM(NFS4CLNT_RECALL_RUNNING);
+ TRACE_DEFINE_ENUM(NFS4CLNT_RECALL_ANY_LAYOUT_READ);
+ TRACE_DEFINE_ENUM(NFS4CLNT_RECALL_ANY_LAYOUT_RW);
++TRACE_DEFINE_ENUM(NFS4CLNT_DELEGRETURN_DELAYED);
+
+ #define show_nfs4_clp_state(state) \
+ __print_flags(state, "|", \
+- { NFS4CLNT_MANAGER_RUNNING, "MANAGER_RUNNING" }, \
+- { NFS4CLNT_CHECK_LEASE, "CHECK_LEASE" }, \
+- { NFS4CLNT_LEASE_EXPIRED, "LEASE_EXPIRED" }, \
+- { NFS4CLNT_RECLAIM_REBOOT, "RECLAIM_REBOOT" }, \
+- { NFS4CLNT_RECLAIM_NOGRACE, "RECLAIM_NOGRACE" }, \
+- { NFS4CLNT_DELEGRETURN, "DELEGRETURN" }, \
+- { NFS4CLNT_SESSION_RESET, "SESSION_RESET" }, \
+- { NFS4CLNT_LEASE_CONFIRM, "LEASE_CONFIRM" }, \
+- { NFS4CLNT_SERVER_SCOPE_MISMATCH, \
+- "SERVER_SCOPE_MISMATCH" }, \
+- { NFS4CLNT_PURGE_STATE, "PURGE_STATE" }, \
+- { NFS4CLNT_BIND_CONN_TO_SESSION, \
+- "BIND_CONN_TO_SESSION" }, \
+- { NFS4CLNT_MOVED, "MOVED" }, \
+- { NFS4CLNT_LEASE_MOVED, "LEASE_MOVED" }, \
+- { NFS4CLNT_DELEGATION_EXPIRED, "DELEGATION_EXPIRED" }, \
+- { NFS4CLNT_RUN_MANAGER, "RUN_MANAGER" }, \
+- { NFS4CLNT_RECALL_RUNNING, "RECALL_RUNNING" }, \
+- { NFS4CLNT_RECALL_ANY_LAYOUT_READ, "RECALL_ANY_LAYOUT_READ" }, \
+- { NFS4CLNT_RECALL_ANY_LAYOUT_RW, "RECALL_ANY_LAYOUT_RW" })
++ { BIT(NFS4CLNT_MANAGER_RUNNING), "MANAGER_RUNNING" }, \
++ { BIT(NFS4CLNT_CHECK_LEASE), "CHECK_LEASE" }, \
++ { BIT(NFS4CLNT_LEASE_EXPIRED), "LEASE_EXPIRED" }, \
++ { BIT(NFS4CLNT_RECLAIM_REBOOT), "RECLAIM_REBOOT" }, \
++ { BIT(NFS4CLNT_RECLAIM_NOGRACE), "RECLAIM_NOGRACE" }, \
++ { BIT(NFS4CLNT_DELEGRETURN), "DELEGRETURN" }, \
++ { BIT(NFS4CLNT_SESSION_RESET), "SESSION_RESET" }, \
++ { BIT(NFS4CLNT_LEASE_CONFIRM), "LEASE_CONFIRM" }, \
++ { BIT(NFS4CLNT_SERVER_SCOPE_MISMATCH), "SERVER_SCOPE_MISMATCH" }, \
++ { BIT(NFS4CLNT_PURGE_STATE), "PURGE_STATE" }, \
++ { BIT(NFS4CLNT_BIND_CONN_TO_SESSION), "BIND_CONN_TO_SESSION" }, \
++ { BIT(NFS4CLNT_MOVED), "MOVED" }, \
++ { BIT(NFS4CLNT_LEASE_MOVED), "LEASE_MOVED" }, \
++ { BIT(NFS4CLNT_DELEGATION_EXPIRED), "DELEGATION_EXPIRED" }, \
++ { BIT(NFS4CLNT_RUN_MANAGER), "RUN_MANAGER" }, \
++ { BIT(NFS4CLNT_MANAGER_AVAILABLE), "MANAGER_AVAILABLE" }, \
++ { BIT(NFS4CLNT_RECALL_RUNNING), "RECALL_RUNNING" }, \
++ { BIT(NFS4CLNT_RECALL_ANY_LAYOUT_READ), "RECALL_ANY_LAYOUT_READ" }, \
++ { BIT(NFS4CLNT_RECALL_ANY_LAYOUT_RW), "RECALL_ANY_LAYOUT_RW" }, \
++ { BIT(NFS4CLNT_DELEGRETURN_DELAYED), "DELERETURN_DELAYED" })
+
+ TRACE_EVENT(nfs4_state_mgr,
+ TP_PROTO(
+--
+2.39.2
+
--- /dev/null
+From dbc0c5bedd450f372b6e8d8de7ec17fa9d263db3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 27 Jan 2023 11:18:56 -0500
+Subject: nfsd: fix race to check ls_layouts
+
+From: Benjamin Coddington <bcodding@redhat.com>
+
+[ Upstream commit fb610c4dbc996415d57d7090957ecddd4fd64fb6 ]
+
+Its possible for __break_lease to find the layout's lease before we've
+added the layout to the owner's ls_layouts list. In that case, setting
+ls_recalled = true without actually recalling the layout will cause the
+server to never send a recall callback.
+
+Move the check for ls_layouts before setting ls_recalled.
+
+Fixes: c5c707f96fc9 ("nfsd: implement pNFS layout recalls")
+Signed-off-by: Benjamin Coddington <bcodding@redhat.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/nfsd/nfs4layouts.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/fs/nfsd/nfs4layouts.c b/fs/nfsd/nfs4layouts.c
+index a97873f2d22b0..2673019d30ecd 100644
+--- a/fs/nfsd/nfs4layouts.c
++++ b/fs/nfsd/nfs4layouts.c
+@@ -322,11 +322,11 @@ nfsd4_recall_file_layout(struct nfs4_layout_stateid *ls)
+ if (ls->ls_recalled)
+ goto out_unlock;
+
+- ls->ls_recalled = true;
+- atomic_inc(&ls->ls_stid.sc_file->fi_lo_recalls);
+ if (list_empty(&ls->ls_layouts))
+ goto out_unlock;
+
++ ls->ls_recalled = true;
++ atomic_inc(&ls->ls_stid.sc_file->fi_lo_recalls);
+ trace_nfsd_layout_recall(&ls->ls_stid.sc_stateid);
+
+ refcount_inc(&ls->ls_stid.sc_count);
+--
+2.39.2
+
--- /dev/null
+From fe667af1f86b8938843ee3ecb434d844709bfe64 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Jan 2023 14:38:30 -0500
+Subject: nfsd: zero out pointers after putting nfsd_files on COPY setup error
+
+From: Jeff Layton <jlayton@kernel.org>
+
+[ Upstream commit 1f0001d43d0c0ac2a19a34a914f6595ad97cbc1d ]
+
+At first, I thought this might be a source of nfsd_file overputs, but
+the current callers seem to avoid an extra put when nfsd4_verify_copy
+returns an error.
+
+Still, it's "bad form" to leave the pointers filled out when we don't
+have a reference to them anymore, and that might lead to bugs later.
+Zero them out as a defensive coding measure.
+
+Signed-off-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfsd/nfs4proc.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
+index 735ee8a798705..f82cfe843b99b 100644
+--- a/fs/nfsd/nfs4proc.c
++++ b/fs/nfsd/nfs4proc.c
+@@ -1075,8 +1075,10 @@ nfsd4_verify_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ return status;
+ out_put_dst:
+ nfsd_file_put(*dst);
++ *dst = NULL;
+ out_put_src:
+ nfsd_file_put(*src);
++ *src = NULL;
+ goto out;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 91545029437e4e31e92547d233271bf040d48cfc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Mar 2022 10:41:44 +1100
+Subject: NFSv4: keep state manager thread active if swap is enabled
+
+From: NeilBrown <neilb@suse.de>
+
+[ Upstream commit 4dc73c679114a2f408567e2e44770ed934190db2 ]
+
+If we are swapping over NFSv4, we may not be able to allocate memory to
+start the state-manager thread at the time when we need it.
+So keep it always running when swap is enabled, and just signal it to
+start.
+
+This requires updating and testing the cl_swapper count on the root
+rpc_clnt after following all ->cl_parent links.
+
+Signed-off-by: NeilBrown <neilb@suse.de>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Stable-dep-of: b46d80bd2d6e ("nfs4trace: fix state manager flag printing")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/file.c | 15 ++++++++++++---
+ fs/nfs/nfs4_fs.h | 1 +
+ fs/nfs/nfs4proc.c | 20 ++++++++++++++++++++
+ fs/nfs/nfs4state.c | 40 +++++++++++++++++++++++++++++++++-------
+ include/linux/nfs_xdr.h | 2 ++
+ net/sunrpc/clnt.c | 2 ++
+ 6 files changed, 70 insertions(+), 10 deletions(-)
+
+diff --git a/fs/nfs/file.c b/fs/nfs/file.c
+index ad856b7b9a46c..7be1a7f7fcb2a 100644
+--- a/fs/nfs/file.c
++++ b/fs/nfs/file.c
+@@ -487,8 +487,9 @@ static int nfs_swap_activate(struct swap_info_struct *sis, struct file *file,
+ {
+ unsigned long blocks;
+ long long isize;
+- struct rpc_clnt *clnt = NFS_CLIENT(file->f_mapping->host);
+- struct inode *inode = file->f_mapping->host;
++ struct inode *inode = file_inode(file);
++ struct rpc_clnt *clnt = NFS_CLIENT(inode);
++ struct nfs_client *cl = NFS_SERVER(inode)->nfs_client;
+
+ spin_lock(&inode->i_lock);
+ blocks = inode->i_blocks;
+@@ -501,14 +502,22 @@ static int nfs_swap_activate(struct swap_info_struct *sis, struct file *file,
+
+ *span = sis->pages;
+
++
++ if (cl->rpc_ops->enable_swap)
++ cl->rpc_ops->enable_swap(inode);
++
+ return rpc_clnt_swap_activate(clnt);
+ }
+
+ static void nfs_swap_deactivate(struct file *file)
+ {
+- struct rpc_clnt *clnt = NFS_CLIENT(file->f_mapping->host);
++ struct inode *inode = file_inode(file);
++ struct rpc_clnt *clnt = NFS_CLIENT(inode);
++ struct nfs_client *cl = NFS_SERVER(inode)->nfs_client;
+
+ rpc_clnt_swap_deactivate(clnt);
++ if (cl->rpc_ops->disable_swap)
++ cl->rpc_ops->disable_swap(file_inode(file));
+ }
+
+ const struct address_space_operations nfs_file_aops = {
+diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
+index 6d916563356ef..8b41c0b8624e3 100644
+--- a/fs/nfs/nfs4_fs.h
++++ b/fs/nfs/nfs4_fs.h
+@@ -42,6 +42,7 @@ enum nfs4_client_state {
+ NFS4CLNT_LEASE_MOVED,
+ NFS4CLNT_DELEGATION_EXPIRED,
+ NFS4CLNT_RUN_MANAGER,
++ NFS4CLNT_MANAGER_AVAILABLE,
+ NFS4CLNT_RECALL_RUNNING,
+ NFS4CLNT_RECALL_ANY_LAYOUT_READ,
+ NFS4CLNT_RECALL_ANY_LAYOUT_RW,
+diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
+index ee46ab09e3306..8f502e2ac34fd 100644
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -10385,6 +10385,24 @@ static ssize_t nfs4_listxattr(struct dentry *dentry, char *list, size_t size)
+ return error + error2 + error3;
+ }
+
++static void nfs4_enable_swap(struct inode *inode)
++{
++ /* The state manager thread must always be running.
++ * It will notice the client is a swapper, and stay put.
++ */
++ struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
++
++ nfs4_schedule_state_manager(clp);
++}
++
++static void nfs4_disable_swap(struct inode *inode)
++{
++ /* The state manager thread will now exit once it is
++ * woken.
++ */
++ wake_up_var(&NFS_SERVER(inode)->nfs_client->cl_state);
++}
++
+ static const struct inode_operations nfs4_dir_inode_operations = {
+ .create = nfs_create,
+ .lookup = nfs_lookup,
+@@ -10461,6 +10479,8 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
+ .free_client = nfs4_free_client,
+ .create_server = nfs4_create_server,
+ .clone_server = nfs_clone_server,
++ .enable_swap = nfs4_enable_swap,
++ .disable_swap = nfs4_disable_swap,
+ };
+
+ static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = {
+diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
+index 175b2e064003e..628e030f8e3ba 100644
+--- a/fs/nfs/nfs4state.c
++++ b/fs/nfs/nfs4state.c
+@@ -1208,10 +1208,17 @@ void nfs4_schedule_state_manager(struct nfs_client *clp)
+ {
+ struct task_struct *task;
+ char buf[INET6_ADDRSTRLEN + sizeof("-manager") + 1];
++ struct rpc_clnt *cl = clp->cl_rpcclient;
++
++ while (cl != cl->cl_parent)
++ cl = cl->cl_parent;
+
+ set_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state);
+- if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0)
++ if (test_and_set_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state) != 0) {
++ wake_up_var(&clp->cl_state);
+ return;
++ }
++ set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state);
+ __module_get(THIS_MODULE);
+ refcount_inc(&clp->cl_count);
+
+@@ -1229,6 +1236,7 @@ void nfs4_schedule_state_manager(struct nfs_client *clp)
+ if (!nfs_client_init_is_complete(clp))
+ nfs_mark_client_ready(clp, PTR_ERR(task));
+ nfs4_clear_state_manager_bit(clp);
++ clear_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state);
+ nfs_put_client(clp);
+ module_put(THIS_MODULE);
+ }
+@@ -2680,12 +2688,8 @@ static void nfs4_state_manager(struct nfs_client *clp)
+ clear_bit(NFS4CLNT_RECALL_RUNNING, &clp->cl_state);
+ }
+
+- /* Did we race with an attempt to give us more work? */
+- if (!test_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state))
+- return;
+- if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0)
+- return;
+- memflags = memalloc_nofs_save();
++ return;
++
+ } while (refcount_read(&clp->cl_count) > 1 && !signalled());
+ goto out_drain;
+
+@@ -2706,9 +2710,31 @@ static void nfs4_state_manager(struct nfs_client *clp)
+ static int nfs4_run_state_manager(void *ptr)
+ {
+ struct nfs_client *clp = ptr;
++ struct rpc_clnt *cl = clp->cl_rpcclient;
++
++ while (cl != cl->cl_parent)
++ cl = cl->cl_parent;
+
+ allow_signal(SIGKILL);
++again:
++ set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state);
+ nfs4_state_manager(clp);
++ if (atomic_read(&cl->cl_swapper)) {
++ wait_var_event_interruptible(&clp->cl_state,
++ test_bit(NFS4CLNT_RUN_MANAGER,
++ &clp->cl_state));
++ if (atomic_read(&cl->cl_swapper) &&
++ test_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state))
++ goto again;
++ /* Either no longer a swapper, or were signalled */
++ }
++ clear_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state);
++
++ if (refcount_read(&clp->cl_count) > 1 && !signalled() &&
++ test_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state) &&
++ !test_and_set_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state))
++ goto again;
++
+ nfs_put_client(clp);
+ module_put_and_exit(0);
+ return 0;
+diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
+index 5491ad5f48a94..33442fd018a06 100644
+--- a/include/linux/nfs_xdr.h
++++ b/include/linux/nfs_xdr.h
+@@ -1789,6 +1789,8 @@ struct nfs_rpc_ops {
+ struct nfs_server *(*create_server)(struct fs_context *);
+ struct nfs_server *(*clone_server)(struct nfs_server *, struct nfs_fh *,
+ struct nfs_fattr *, rpc_authflavor_t);
++ void (*enable_swap)(struct inode *inode);
++ void (*disable_swap)(struct inode *inode);
+ };
+
+ /*
+diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
+index c478108ca6a65..e190d38c4c827 100644
+--- a/net/sunrpc/clnt.c
++++ b/net/sunrpc/clnt.c
+@@ -3026,6 +3026,8 @@ rpc_clnt_swap_activate_callback(struct rpc_clnt *clnt,
+ int
+ rpc_clnt_swap_activate(struct rpc_clnt *clnt)
+ {
++ while (clnt != clnt->cl_parent)
++ clnt = clnt->cl_parent;
+ if (atomic_inc_return(&clnt->cl_swapper) == 1)
+ return rpc_clnt_iterate_for_each_xprt(clnt,
+ rpc_clnt_swap_activate_callback, NULL);
+--
+2.39.2
+
--- /dev/null
+From 0e2a4b26e1cd88fa9b192752f7395fe6ece33670 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Feb 2023 14:00:58 +0100
+Subject: objtool: add UACCESS exceptions for __tsan_volatile_read/write
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit d5d469247264e56960705dc5ae7e1d014861fe40 ]
+
+A lot of the tsan helpers are already excempt from the UACCESS warnings,
+but some more functions were added that need the same thing:
+
+kernel/kcsan/core.o: warning: objtool: __tsan_volatile_read16+0x0: call to __tsan_unaligned_read16() with UACCESS enabled
+kernel/kcsan/core.o: warning: objtool: __tsan_volatile_write16+0x0: call to __tsan_unaligned_write16() with UACCESS enabled
+vmlinux.o: warning: objtool: __tsan_unaligned_volatile_read16+0x4: call to __tsan_unaligned_read16() with UACCESS enabled
+vmlinux.o: warning: objtool: __tsan_unaligned_volatile_write16+0x4: call to __tsan_unaligned_write16() with UACCESS enabled
+
+As Marco points out, these functions don't even call each other
+explicitly but instead gcc (but not clang) notices the functions
+being identical and turns one symbol into a direct branch to the
+other.
+
+Link: https://lkml.kernel.org/r/20230215130058.3836177-4-arnd@kernel.org
+Fixes: 75d75b7a4d54 ("kcsan: Support distinguishing volatile accesses")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Acked-by: Marco Elver <elver@google.com>
+Cc: Alexander Potapenko <glider@google.com>
+Cc: Andrey Konovalov <andreyknvl@gmail.com>
+Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
+Cc: Dmitry Vyukov <dvyukov@google.com>
+Cc: Josh Poimboeuf <jpoimboe@kernel.org>
+Cc: Kuan-Ying Lee <Kuan-Ying.Lee@mediatek.com>
+Cc: Peter Zijlstra (Intel) <peterz@infradead.org>
+Cc: Vincenzo Frascino <vincenzo.frascino@arm.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/objtool/check.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/tools/objtool/check.c b/tools/objtool/check.c
+index ff47aed7ef6fe..5c4190382a51a 100644
+--- a/tools/objtool/check.c
++++ b/tools/objtool/check.c
+@@ -864,6 +864,8 @@ static const char *uaccess_safe_builtin[] = {
+ "__tsan_atomic64_compare_exchange_val",
+ "__tsan_atomic_thread_fence",
+ "__tsan_atomic_signal_fence",
++ "__tsan_unaligned_read16",
++ "__tsan_unaligned_write16",
+ /* KCOV */
+ "write_comp_data",
+ "check_kcov_mode",
+--
+2.39.2
+
--- /dev/null
+From ac5ac5784ee3ccce460c513746b77975cc00dd6e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Feb 2023 12:00:37 +0800
+Subject: OPP: fix error checking in opp_migrate_dentry()
+
+From: Qi Zheng <zhengqi.arch@bytedance.com>
+
+[ Upstream commit eca4c0eea53432ec4b711b2a8ad282cbad231b4f ]
+
+Since commit ff9fb72bc077 ("debugfs: return error values,
+not NULL") changed return value of debugfs_rename() in
+error cases from %NULL to %ERR_PTR(-ERROR), we should
+also check error values instead of NULL.
+
+Fixes: ff9fb72bc077 ("debugfs: return error values, not NULL")
+Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/opp/debugfs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/opp/debugfs.c b/drivers/opp/debugfs.c
+index 596c185b5dda4..60f4ff8e044d1 100644
+--- a/drivers/opp/debugfs.c
++++ b/drivers/opp/debugfs.c
+@@ -204,7 +204,7 @@ static void opp_migrate_dentry(struct opp_device *opp_dev,
+
+ dentry = debugfs_rename(rootdir, opp_dev->dentry, rootdir,
+ opp_table->dentry_name);
+- if (!dentry) {
++ if (IS_ERR(dentry)) {
+ dev_err(dev, "%s: Failed to rename link from: %s to %s\n",
+ __func__, dev_name(opp_dev->dev), dev_name(dev));
+ return;
+--
+2.39.2
+
--- /dev/null
+From c0608f9972c22979111349a7b40e1334dbb1d458 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Jan 2023 00:26:09 -0800
+Subject: perf llvm: Fix inadvertent file creation
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit 9f19aab47ced012eddef1e2bc96007efc7713b61 ]
+
+The LLVM template is first echo-ed into command_out and then
+command_out executed. The echo surrounds the template with double
+quotes, however, the template itself may contain quotes. This is
+generally innocuous but in tools/perf/tests/bpf-script-test-prologue.c
+we see:
+...
+SEC("func=null_lseek file->f_mode offset orig")
+...
+where the first double quote ends the double quote of the echo, then
+the > redirects output into a file called f_mode.
+
+To avoid this inadvertent behavior substitute redirects and similar
+characters to be ASCII control codes, then substitute the output in
+the echo back again.
+
+Fixes: 5eab5a7ee032acaa ("perf llvm: Display eBPF compiling command in debug output")
+Signed-off-by: Ian Rogers <irogers@google.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Andrii Nakryiko <andrii@kernel.org>
+Cc: bpf@vger.kernel.org
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: llvm@lists.linux.dev
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Nathan Chancellor <nathan@kernel.org>
+Cc: Nick Desaulniers <ndesaulniers@google.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Tom Rix <trix@redhat.com>
+Link: https://lore.kernel.org/r/20230105082609.344538-1-irogers@google.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/llvm-utils.c | 25 ++++++++++++++++++++++++-
+ 1 file changed, 24 insertions(+), 1 deletion(-)
+
+diff --git a/tools/perf/util/llvm-utils.c b/tools/perf/util/llvm-utils.c
+index 0bf6b4d4c90a7..570cde4640d05 100644
+--- a/tools/perf/util/llvm-utils.c
++++ b/tools/perf/util/llvm-utils.c
+@@ -525,14 +525,37 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf,
+
+ pr_debug("llvm compiling command template: %s\n", template);
+
++ /*
++ * Below, substitute control characters for values that can cause the
++ * echo to misbehave, then substitute the values back.
++ */
+ err = -ENOMEM;
+- if (asprintf(&command_echo, "echo -n \"%s\"", template) < 0)
++ if (asprintf(&command_echo, "echo -n \a%s\a", template) < 0)
+ goto errout;
+
++#define SWAP_CHAR(a, b) do { if (*p == a) *p = b; } while (0)
++ for (char *p = command_echo; *p; p++) {
++ SWAP_CHAR('<', '\001');
++ SWAP_CHAR('>', '\002');
++ SWAP_CHAR('"', '\003');
++ SWAP_CHAR('\'', '\004');
++ SWAP_CHAR('|', '\005');
++ SWAP_CHAR('&', '\006');
++ SWAP_CHAR('\a', '"');
++ }
+ err = read_from_pipe(command_echo, (void **) &command_out, NULL);
+ if (err)
+ goto errout;
+
++ for (char *p = command_out; *p; p++) {
++ SWAP_CHAR('\001', '<');
++ SWAP_CHAR('\002', '>');
++ SWAP_CHAR('\003', '"');
++ SWAP_CHAR('\004', '\'');
++ SWAP_CHAR('\005', '|');
++ SWAP_CHAR('\006', '&');
++ }
++#undef SWAP_CHAR
+ pr_debug("llvm compiling command : %s\n", command_out);
+
+ err = read_from_pipe(template, &obj_buf, &obj_buf_sz);
+--
+2.39.2
+
--- /dev/null
+From ae497db1949bd7d09ef837ef5a6725fd4731b1c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Feb 2023 11:50:57 +0800
+Subject: perf tools: Fix auto-complete on aarch64
+
+From: Yicong Yang <yangyicong@hisilicon.com>
+
+[ Upstream commit ffd1240e8f0814262ceb957dbe961f6e0aef1e7a ]
+
+On aarch64 CPU related events are not under event_source/devices/cpu/events,
+they're under event_source/devices/armv8_pmuv3_0/events on my machine.
+Using current auto-complete script will generate below error:
+
+ [root@localhost bin]# perf stat -e
+ ls: cannot access '/sys/bus/event_source/devices/cpu/events': No such file or directory
+
+Fix this by not testing /sys/bus/event_source/devices/cpu/events on
+aarch64 machine.
+
+Fixes: 74cd5815d9af6e6c ("perf tool: Improve bash command line auto-complete for multiple events with comma")
+Reviewed-by: James Clark <james.clark@arm.com>
+Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Jin Yao <yao.jin@linux.intel.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: linux-arm-kernel@lists.infradead.org
+Cc: linuxarm@huawei.com
+Cc: prime.zeng@hisilicon.com
+Link: https://lore.kernel.org/r/20230207035057.43394-1-yangyicong@huawei.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/perf-completion.sh | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/tools/perf/perf-completion.sh b/tools/perf/perf-completion.sh
+index fdf75d45efff7..978249d7868c2 100644
+--- a/tools/perf/perf-completion.sh
++++ b/tools/perf/perf-completion.sh
+@@ -165,7 +165,12 @@ __perf_main ()
+
+ local cur1=${COMP_WORDS[COMP_CWORD]}
+ local raw_evts=$($cmd list --raw-dump)
+- local arr s tmp result
++ local arr s tmp result cpu_evts
++
++ # aarch64 doesn't have /sys/bus/event_source/devices/cpu/events
++ if [[ `uname -m` != aarch64 ]]; then
++ cpu_evts=$(ls /sys/bus/event_source/devices/cpu/events)
++ fi
+
+ if [[ "$cur1" == */* && ${cur1#*/} =~ ^[A-Z] ]]; then
+ OLD_IFS="$IFS"
+@@ -183,9 +188,9 @@ __perf_main ()
+ fi
+ done
+
+- evts=${result}" "$(ls /sys/bus/event_source/devices/cpu/events)
++ evts=${result}" "${cpu_evts}
+ else
+- evts=${raw_evts}" "$(ls /sys/bus/event_source/devices/cpu/events)
++ evts=${raw_evts}" "${cpu_evts}
+ fi
+
+ if [[ "$cur1" == , ]]; then
+--
+2.39.2
+
--- /dev/null
+From 545b17c0296b0ca9cecb4874a88bb9a694798bc2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Feb 2023 15:27:14 +0200
+Subject: pinctrl: at91: use devm_kasprintf() to avoid potential leaks
+
+From: Claudiu Beznea <claudiu.beznea@microchip.com>
+
+[ Upstream commit 1c4e5c470a56f7f7c649c0c70e603abc1eab15c4 ]
+
+Use devm_kasprintf() instead of kasprintf() to avoid any potential
+leaks. At the moment drivers have no remove functionality thus
+there is no need for fixes tag.
+
+Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
+Link: https://lore.kernel.org/r/20230203132714.1931596-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-at91-pio4.c | 4 ++--
+ drivers/pinctrl/pinctrl-at91.c | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/pinctrl/pinctrl-at91-pio4.c b/drivers/pinctrl/pinctrl-at91-pio4.c
+index 578b387100d9b..d2e2b101978f8 100644
+--- a/drivers/pinctrl/pinctrl-at91-pio4.c
++++ b/drivers/pinctrl/pinctrl-at91-pio4.c
+@@ -1081,8 +1081,8 @@ static int atmel_pinctrl_probe(struct platform_device *pdev)
+
+ pin_desc[i].number = i;
+ /* Pin naming convention: P(bank_name)(bank_pin_number). */
+- pin_desc[i].name = kasprintf(GFP_KERNEL, "P%c%d",
+- bank + 'A', line);
++ pin_desc[i].name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "P%c%d",
++ bank + 'A', line);
+
+ group->name = group_names[i] = pin_desc[i].name;
+ group->pin = pin_desc[i].number;
+diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c
+index 9015486e38c18..52ecd47c18e2d 100644
+--- a/drivers/pinctrl/pinctrl-at91.c
++++ b/drivers/pinctrl/pinctrl-at91.c
+@@ -1891,7 +1891,7 @@ static int at91_gpio_probe(struct platform_device *pdev)
+ }
+
+ for (i = 0; i < chip->ngpio; i++)
+- names[i] = kasprintf(GFP_KERNEL, "pio%c%d", alias_idx + 'A', i);
++ names[i] = devm_kasprintf(&pdev->dev, GFP_KERNEL, "pio%c%d", alias_idx + 'A', i);
+
+ chip->names = (const char *const *)names;
+
+--
+2.39.2
+
--- /dev/null
+From d7365bea76884c0bb78fbc39e9494d7e940f098c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Jan 2023 23:53:50 +0200
+Subject: pinctrl: bcm2835: Remove of_node_put() in
+ bcm2835_of_gpio_ranges_fallback()
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 2d578dd27871372f7159dd3206149ec616700d87 ]
+
+Remove wrong of_node_put() in bcm2835_of_gpio_ranges_fallback(),
+there is no counterpart of_node_get() for it.
+
+Fixes: d2b67744fd99 ("pinctrl: bcm2835: implement hook for missing gpio-ranges")
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reviewed-by: Stefan Wahren <stefan.wahren@i2se.com>
+Tested-by: Stefan Wahren <stefan.wahren@i2se.com>
+Tested-by: Florian Fainelli <f.fainelli@gmail.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Acked-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Link: https://lore.kernel.org/r/20230113215352.44272-3-andriy.shevchenko@linux.intel.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/bcm/pinctrl-bcm2835.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
+index 39d2024dc2ee5..c7ae9f900b532 100644
+--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c
++++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
+@@ -356,8 +356,6 @@ static int bcm2835_of_gpio_ranges_fallback(struct gpio_chip *gc,
+ {
+ struct pinctrl_dev *pctldev = of_pinctrl_get(np);
+
+- of_node_put(np);
+-
+ if (!pctldev)
+ return 0;
+
+--
+2.39.2
+
--- /dev/null
+From f647de23f7d58d1328b9471e51863a0d57fe561b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Jan 2023 14:20:36 +0800
+Subject: pinctrl: mediatek: Initialize variable *buf to zero
+
+From: Guodong Liu <Guodong.Liu@mediatek.com>
+
+[ Upstream commit 2e34f82ba214134ecf590fbe0cdbd87401645a8a ]
+
+Coverity spotted that *buf is not initialized to zero in
+mtk_pctrl_dbg_show. Using uninitialized variable *buf as argument to %s
+when calling seq_printf. Fix this coverity by initializing *buf as zero.
+
+Fixes: 184d8e13f9b1 ("pinctrl: mediatek: Add support for pin configuration dump via debugfs.")
+Signed-off-by: Guodong Liu <Guodong.Liu@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20230118062036.26258-3-Guodong.Liu@mediatek.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/mediatek/pinctrl-paris.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
+index 2a9d2801388d7..e486d66e220b0 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
++++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
+@@ -637,7 +637,7 @@ static void mtk_pctrl_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
+ unsigned int gpio)
+ {
+ struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
+- char buf[PIN_DBG_BUF_SZ];
++ char buf[PIN_DBG_BUF_SZ] = { 0 };
+
+ (void)mtk_pctrl_show_one_pin(hw, gpio, buf, PIN_DBG_BUF_SZ);
+
+--
+2.39.2
+
--- /dev/null
+From 6ebfbe78489b16003995d7941ca91915eab13509 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Jan 2023 14:20:35 +0800
+Subject: pinctrl: mediatek: Initialize variable pullen and pullup to zero
+
+From: Guodong Liu <Guodong.Liu@mediatek.com>
+
+[ Upstream commit a298c70a10c604a6b3df5a0aa56597b705ba0f6b ]
+
+Coverity spotted that pullen and pullup is not initialized to zero in
+mtk_pctrl_show_one_pin. The uninitialized variable pullen is used in
+assignment statement "rsel = pullen;" in mtk_pctrl_show_one_pin, and
+Uninitialized variable pullup is used when calling scnprintf. Fix this
+coverity by initializing pullen and pullup as zero.
+
+Fixes: 184d8e13f9b1 ("pinctrl: mediatek: Add support for pin configuration dump via debugfs.")
+Signed-off-by: Guodong Liu <Guodong.Liu@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20230118062036.26258-2-Guodong.Liu@mediatek.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/mediatek/pinctrl-paris.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
+index d0a4ebbe1e7e6..2a9d2801388d7 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
++++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
+@@ -574,7 +574,7 @@ static int mtk_hw_get_value_wrap(struct mtk_pinctrl *hw, unsigned int gpio, int
+ ssize_t mtk_pctrl_show_one_pin(struct mtk_pinctrl *hw,
+ unsigned int gpio, char *buf, unsigned int bufLen)
+ {
+- int pinmux, pullup, pullen, len = 0, r1 = -1, r0 = -1;
++ int pinmux, pullup = 0, pullen = 0, len = 0, r1 = -1, r0 = -1;
+ const struct mtk_pin_desc *desc;
+
+ if (gpio >= hw->soc->npins)
+--
+2.39.2
+
--- /dev/null
+From a021ead6f61dea68bf656a5c268416f5227440d0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 31 Dec 2022 17:42:50 +0100
+Subject: pinctrl: qcom: pinctrl-msm8976: Correct function names for wcss pins
+
+From: Adam Skladowski <a39.skl@gmail.com>
+
+[ Upstream commit a7cc0e2685082a0d79baec02df184dfa83cbfac3 ]
+
+Adjust names of function for wcss pins, also fix third gpio in bt group.
+
+Fixes: bcd11493f0ab ("pinctrl: qcom: Add a pinctrl driver for MSM8976 and 8956")
+Signed-off-by: Adam Skladowski <a39.skl@gmail.com>
+Reviewed-by: Marijn Suijten <marijn.suijten@somainline.org>
+Link: https://lore.kernel.org/r/20221231164250.74550-1-a39.skl@gmail.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/qcom/pinctrl-msm8976.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/pinctrl/qcom/pinctrl-msm8976.c b/drivers/pinctrl/qcom/pinctrl-msm8976.c
+index ec43edf9b660a..e11d845847190 100644
+--- a/drivers/pinctrl/qcom/pinctrl-msm8976.c
++++ b/drivers/pinctrl/qcom/pinctrl-msm8976.c
+@@ -733,7 +733,7 @@ static const char * const codec_int2_groups[] = {
+ "gpio74",
+ };
+ static const char * const wcss_bt_groups[] = {
+- "gpio39", "gpio47", "gpio88",
++ "gpio39", "gpio47", "gpio48",
+ };
+ static const char * const sdc3_groups[] = {
+ "gpio39", "gpio40", "gpio41",
+@@ -958,9 +958,9 @@ static const struct msm_pingroup msm8976_groups[] = {
+ PINGROUP(37, NA, NA, NA, qdss_tracedata_b, NA, NA, NA, NA, NA),
+ PINGROUP(38, NA, NA, NA, NA, NA, NA, NA, qdss_tracedata_b, NA),
+ PINGROUP(39, wcss_bt, sdc3, NA, qdss_tracedata_a, NA, NA, NA, NA, NA),
+- PINGROUP(40, wcss_wlan, sdc3, NA, qdss_tracedata_a, NA, NA, NA, NA, NA),
+- PINGROUP(41, wcss_wlan, sdc3, NA, qdss_tracedata_a, NA, NA, NA, NA, NA),
+- PINGROUP(42, wcss_wlan, sdc3, NA, qdss_tracedata_a, NA, NA, NA, NA, NA),
++ PINGROUP(40, wcss_wlan2, sdc3, NA, qdss_tracedata_a, NA, NA, NA, NA, NA),
++ PINGROUP(41, wcss_wlan1, sdc3, NA, qdss_tracedata_a, NA, NA, NA, NA, NA),
++ PINGROUP(42, wcss_wlan0, sdc3, NA, qdss_tracedata_a, NA, NA, NA, NA, NA),
+ PINGROUP(43, wcss_wlan, sdc3, NA, NA, qdss_tracedata_a, NA, NA, NA, NA),
+ PINGROUP(44, wcss_wlan, sdc3, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(45, wcss_fm, NA, qdss_tracectl_a, NA, NA, NA, NA, NA, NA),
+--
+2.39.2
+
--- /dev/null
+From f84516d850833cd942f9f61f19c9a613b70ee4be Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Mar 2021 16:14:41 +0800
+Subject: pinctrl: rockchip: add support for rk3568
+
+From: Jianqun Xu <jay.xu@rock-chips.com>
+
+[ Upstream commit c0dadc0e47a895e95c17a4df1fa12737e1d57d6f ]
+
+RK3568 SoCs have 5 gpio controllers, each gpio has 32 pins. GPIO supports
+set iomux, pull, drive strength and schmitt.
+
+Signed-off-by: Jianqun Xu <jay.xu@rock-chips.com>
+Link: https://lore.kernel.org/r/20210319081441.368358-1-jay.xu@rock-chips.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Stable-dep-of: c818ae563bf9 ("pinctrl: rockchip: Fix refcount leak in rockchip_pinctrl_parse_groups")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/pinctrl-rockchip.c | 292 ++++++++++++++++++++++++++++-
+ 1 file changed, 290 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
+index 07b1204174bf1..38ea70f49cb07 100644
+--- a/drivers/pinctrl/pinctrl-rockchip.c
++++ b/drivers/pinctrl/pinctrl-rockchip.c
+@@ -61,8 +61,17 @@ enum rockchip_pinctrl_type {
+ RK3308,
+ RK3368,
+ RK3399,
++ RK3568,
+ };
+
++
++/**
++ * Generate a bitmask for setting a value (v) with a write mask bit in hiword
++ * register 31:16 area.
++ */
++#define WRITE_MASK_VAL(h, l, v) \
++ (GENMASK(((h) + 16), ((l) + 16)) | (((v) << (l)) & GENMASK((h), (l))))
++
+ /*
+ * Encode variants of iomux registers into a type variable
+ */
+@@ -290,6 +299,25 @@ struct rockchip_pin_bank {
+ .pull_type[3] = pull3, \
+ }
+
++#define PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, FLAG) \
++ { \
++ .bank_num = ID, \
++ .pin = PIN, \
++ .func = FUNC, \
++ .route_offset = REG, \
++ .route_val = VAL, \
++ .route_location = FLAG, \
++ }
++
++#define RK_MUXROUTE_SAME(ID, PIN, FUNC, REG, VAL) \
++ PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROCKCHIP_ROUTE_SAME)
++
++#define RK_MUXROUTE_GRF(ID, PIN, FUNC, REG, VAL) \
++ PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROCKCHIP_ROUTE_GRF)
++
++#define RK_MUXROUTE_PMU(ID, PIN, FUNC, REG, VAL) \
++ PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROCKCHIP_ROUTE_PMU)
++
+ /**
+ * struct rockchip_mux_recalced_data: represent a pin iomux data.
+ * @num: bank number.
+@@ -1409,6 +1437,102 @@ static struct rockchip_mux_route_data rk3399_mux_route_data[] = {
+ },
+ };
+
++static struct rockchip_mux_route_data rk3568_mux_route_data[] = {
++ RK_MUXROUTE_PMU(0, RK_PB7, 1, 0x0110, WRITE_MASK_VAL(1, 0, 0)), /* PWM0 IO mux M0 */
++ RK_MUXROUTE_PMU(0, RK_PC7, 2, 0x0110, WRITE_MASK_VAL(1, 0, 1)), /* PWM0 IO mux M1 */
++ RK_MUXROUTE_PMU(0, RK_PC0, 1, 0x0110, WRITE_MASK_VAL(3, 2, 0)), /* PWM1 IO mux M0 */
++ RK_MUXROUTE_PMU(0, RK_PB5, 4, 0x0110, WRITE_MASK_VAL(3, 2, 1)), /* PWM1 IO mux M1 */
++ RK_MUXROUTE_PMU(0, RK_PC1, 1, 0x0110, WRITE_MASK_VAL(5, 4, 0)), /* PWM2 IO mux M0 */
++ RK_MUXROUTE_PMU(0, RK_PB6, 4, 0x0110, WRITE_MASK_VAL(5, 4, 1)), /* PWM2 IO mux M1 */
++ RK_MUXROUTE_PMU(0, RK_PB3, 2, 0x0300, WRITE_MASK_VAL(0, 0, 0)), /* CAN0 IO mux M0 */
++ RK_MUXROUTE_GRF(2, RK_PA1, 4, 0x0300, WRITE_MASK_VAL(0, 0, 1)), /* CAN0 IO mux M1 */
++ RK_MUXROUTE_GRF(1, RK_PA1, 3, 0x0300, WRITE_MASK_VAL(2, 2, 0)), /* CAN1 IO mux M0 */
++ RK_MUXROUTE_GRF(4, RK_PC3, 3, 0x0300, WRITE_MASK_VAL(2, 2, 1)), /* CAN1 IO mux M1 */
++ RK_MUXROUTE_GRF(4, RK_PB5, 3, 0x0300, WRITE_MASK_VAL(4, 4, 0)), /* CAN2 IO mux M0 */
++ RK_MUXROUTE_GRF(2, RK_PB2, 4, 0x0300, WRITE_MASK_VAL(4, 4, 1)), /* CAN2 IO mux M1 */
++ RK_MUXROUTE_GRF(4, RK_PC4, 1, 0x0300, WRITE_MASK_VAL(6, 6, 0)), /* HPDIN IO mux M0 */
++ RK_MUXROUTE_PMU(0, RK_PC2, 2, 0x0300, WRITE_MASK_VAL(6, 6, 1)), /* HPDIN IO mux M1 */
++ RK_MUXROUTE_GRF(3, RK_PB1, 3, 0x0300, WRITE_MASK_VAL(8, 8, 0)), /* GMAC1 IO mux M0 */
++ RK_MUXROUTE_GRF(4, RK_PA7, 3, 0x0300, WRITE_MASK_VAL(8, 8, 1)), /* GMAC1 IO mux M1 */
++ RK_MUXROUTE_GRF(4, RK_PD1, 1, 0x0300, WRITE_MASK_VAL(10, 10, 0)), /* HDMITX IO mux M0 */
++ RK_MUXROUTE_PMU(0, RK_PC7, 1, 0x0300, WRITE_MASK_VAL(10, 10, 1)), /* HDMITX IO mux M1 */
++ RK_MUXROUTE_PMU(0, RK_PB6, 1, 0x0300, WRITE_MASK_VAL(14, 14, 0)), /* I2C2 IO mux M0 */
++ RK_MUXROUTE_GRF(4, RK_PB4, 1, 0x0300, WRITE_MASK_VAL(14, 14, 1)), /* I2C2 IO mux M1 */
++ RK_MUXROUTE_GRF(1, RK_PA0, 1, 0x0304, WRITE_MASK_VAL(0, 0, 0)), /* I2C3 IO mux M0 */
++ RK_MUXROUTE_GRF(3, RK_PB6, 4, 0x0304, WRITE_MASK_VAL(0, 0, 1)), /* I2C3 IO mux M1 */
++ RK_MUXROUTE_GRF(4, RK_PB2, 1, 0x0304, WRITE_MASK_VAL(2, 2, 0)), /* I2C4 IO mux M0 */
++ RK_MUXROUTE_GRF(2, RK_PB1, 2, 0x0304, WRITE_MASK_VAL(2, 2, 1)), /* I2C4 IO mux M1 */
++ RK_MUXROUTE_GRF(3, RK_PB4, 4, 0x0304, WRITE_MASK_VAL(4, 4, 0)), /* I2C5 IO mux M0 */
++ RK_MUXROUTE_GRF(4, RK_PD0, 2, 0x0304, WRITE_MASK_VAL(4, 4, 1)), /* I2C5 IO mux M1 */
++ RK_MUXROUTE_GRF(3, RK_PB1, 5, 0x0304, WRITE_MASK_VAL(14, 14, 0)), /* PWM8 IO mux M0 */
++ RK_MUXROUTE_GRF(1, RK_PD5, 4, 0x0304, WRITE_MASK_VAL(14, 14, 1)), /* PWM8 IO mux M1 */
++ RK_MUXROUTE_GRF(3, RK_PB2, 5, 0x0308, WRITE_MASK_VAL(0, 0, 0)), /* PWM9 IO mux M0 */
++ RK_MUXROUTE_GRF(1, RK_PD6, 4, 0x0308, WRITE_MASK_VAL(0, 0, 1)), /* PWM9 IO mux M1 */
++ RK_MUXROUTE_GRF(3, RK_PB5, 5, 0x0308, WRITE_MASK_VAL(2, 2, 0)), /* PWM10 IO mux M0 */
++ RK_MUXROUTE_GRF(2, RK_PA1, 2, 0x0308, WRITE_MASK_VAL(2, 2, 1)), /* PWM10 IO mux M1 */
++ RK_MUXROUTE_GRF(3, RK_PB6, 5, 0x0308, WRITE_MASK_VAL(4, 4, 0)), /* PWM11 IO mux M0 */
++ RK_MUXROUTE_GRF(4, RK_PC0, 3, 0x0308, WRITE_MASK_VAL(4, 4, 1)), /* PWM11 IO mux M1 */
++ RK_MUXROUTE_GRF(3, RK_PB7, 2, 0x0308, WRITE_MASK_VAL(6, 6, 0)), /* PWM12 IO mux M0 */
++ RK_MUXROUTE_GRF(4, RK_PC5, 1, 0x0308, WRITE_MASK_VAL(6, 6, 1)), /* PWM12 IO mux M1 */
++ RK_MUXROUTE_GRF(3, RK_PC0, 2, 0x0308, WRITE_MASK_VAL(8, 8, 0)), /* PWM13 IO mux M0 */
++ RK_MUXROUTE_GRF(4, RK_PC6, 1, 0x0308, WRITE_MASK_VAL(8, 8, 1)), /* PWM13 IO mux M1 */
++ RK_MUXROUTE_GRF(3, RK_PC4, 1, 0x0308, WRITE_MASK_VAL(10, 10, 0)), /* PWM14 IO mux M0 */
++ RK_MUXROUTE_GRF(4, RK_PC2, 1, 0x0308, WRITE_MASK_VAL(10, 10, 1)), /* PWM14 IO mux M1 */
++ RK_MUXROUTE_GRF(3, RK_PC5, 1, 0x0308, WRITE_MASK_VAL(12, 12, 0)), /* PWM15 IO mux M0 */
++ RK_MUXROUTE_GRF(4, RK_PC3, 1, 0x0308, WRITE_MASK_VAL(12, 12, 1)), /* PWM15 IO mux M1 */
++ RK_MUXROUTE_GRF(3, RK_PD2, 3, 0x0308, WRITE_MASK_VAL(14, 14, 0)), /* SDMMC2 IO mux M0 */
++ RK_MUXROUTE_GRF(3, RK_PA5, 5, 0x0308, WRITE_MASK_VAL(14, 14, 1)), /* SDMMC2 IO mux M1 */
++ RK_MUXROUTE_PMU(0, RK_PB5, 2, 0x030c, WRITE_MASK_VAL(0, 0, 0)), /* SPI0 IO mux M0 */
++ RK_MUXROUTE_GRF(2, RK_PD3, 3, 0x030c, WRITE_MASK_VAL(0, 0, 1)), /* SPI0 IO mux M1 */
++ RK_MUXROUTE_GRF(2, RK_PB5, 3, 0x030c, WRITE_MASK_VAL(2, 2, 0)), /* SPI1 IO mux M0 */
++ RK_MUXROUTE_GRF(3, RK_PC3, 3, 0x030c, WRITE_MASK_VAL(2, 2, 1)), /* SPI1 IO mux M1 */
++ RK_MUXROUTE_GRF(2, RK_PC1, 4, 0x030c, WRITE_MASK_VAL(4, 4, 0)), /* SPI2 IO mux M0 */
++ RK_MUXROUTE_GRF(3, RK_PA0, 3, 0x030c, WRITE_MASK_VAL(4, 4, 1)), /* SPI2 IO mux M1 */
++ RK_MUXROUTE_GRF(4, RK_PB3, 4, 0x030c, WRITE_MASK_VAL(6, 6, 0)), /* SPI3 IO mux M0 */
++ RK_MUXROUTE_GRF(4, RK_PC2, 2, 0x030c, WRITE_MASK_VAL(6, 6, 1)), /* SPI3 IO mux M1 */
++ RK_MUXROUTE_GRF(2, RK_PB4, 2, 0x030c, WRITE_MASK_VAL(8, 8, 0)), /* UART1 IO mux M0 */
++ RK_MUXROUTE_PMU(0, RK_PD1, 1, 0x030c, WRITE_MASK_VAL(8, 8, 1)), /* UART1 IO mux M1 */
++ RK_MUXROUTE_PMU(0, RK_PD1, 1, 0x030c, WRITE_MASK_VAL(10, 10, 0)), /* UART2 IO mux M0 */
++ RK_MUXROUTE_GRF(1, RK_PD5, 2, 0x030c, WRITE_MASK_VAL(10, 10, 1)), /* UART2 IO mux M1 */
++ RK_MUXROUTE_GRF(1, RK_PA1, 2, 0x030c, WRITE_MASK_VAL(12, 12, 0)), /* UART3 IO mux M0 */
++ RK_MUXROUTE_GRF(3, RK_PB7, 4, 0x030c, WRITE_MASK_VAL(12, 12, 1)), /* UART3 IO mux M1 */
++ RK_MUXROUTE_GRF(1, RK_PA6, 2, 0x030c, WRITE_MASK_VAL(14, 14, 0)), /* UART4 IO mux M0 */
++ RK_MUXROUTE_GRF(3, RK_PB2, 4, 0x030c, WRITE_MASK_VAL(14, 14, 1)), /* UART4 IO mux M1 */
++ RK_MUXROUTE_GRF(2, RK_PA2, 3, 0x0310, WRITE_MASK_VAL(0, 0, 0)), /* UART5 IO mux M0 */
++ RK_MUXROUTE_GRF(3, RK_PC2, 4, 0x0310, WRITE_MASK_VAL(0, 0, 1)), /* UART5 IO mux M1 */
++ RK_MUXROUTE_GRF(2, RK_PA4, 3, 0x0310, WRITE_MASK_VAL(2, 2, 0)), /* UART6 IO mux M0 */
++ RK_MUXROUTE_GRF(1, RK_PD5, 3, 0x0310, WRITE_MASK_VAL(2, 2, 1)), /* UART6 IO mux M1 */
++ RK_MUXROUTE_GRF(2, RK_PA6, 3, 0x0310, WRITE_MASK_VAL(5, 4, 0)), /* UART7 IO mux M0 */
++ RK_MUXROUTE_GRF(3, RK_PC4, 4, 0x0310, WRITE_MASK_VAL(5, 4, 1)), /* UART7 IO mux M1 */
++ RK_MUXROUTE_GRF(4, RK_PA2, 4, 0x0310, WRITE_MASK_VAL(5, 4, 2)), /* UART7 IO mux M2 */
++ RK_MUXROUTE_GRF(2, RK_PC5, 3, 0x0310, WRITE_MASK_VAL(6, 6, 0)), /* UART8 IO mux M0 */
++ RK_MUXROUTE_GRF(2, RK_PD7, 4, 0x0310, WRITE_MASK_VAL(6, 6, 1)), /* UART8 IO mux M1 */
++ RK_MUXROUTE_GRF(2, RK_PB0, 3, 0x0310, WRITE_MASK_VAL(9, 8, 0)), /* UART9 IO mux M0 */
++ RK_MUXROUTE_GRF(4, RK_PC5, 4, 0x0310, WRITE_MASK_VAL(9, 8, 1)), /* UART9 IO mux M1 */
++ RK_MUXROUTE_GRF(4, RK_PA4, 4, 0x0310, WRITE_MASK_VAL(9, 8, 2)), /* UART9 IO mux M2 */
++ RK_MUXROUTE_GRF(1, RK_PA2, 1, 0x0310, WRITE_MASK_VAL(11, 10, 0)), /* I2S1 IO mux M0 */
++ RK_MUXROUTE_GRF(3, RK_PC6, 4, 0x0310, WRITE_MASK_VAL(11, 10, 1)), /* I2S1 IO mux M1 */
++ RK_MUXROUTE_GRF(2, RK_PD0, 5, 0x0310, WRITE_MASK_VAL(11, 10, 2)), /* I2S1 IO mux M2 */
++ RK_MUXROUTE_GRF(2, RK_PC1, 1, 0x0310, WRITE_MASK_VAL(12, 12, 0)), /* I2S2 IO mux M0 */
++ RK_MUXROUTE_GRF(4, RK_PB6, 5, 0x0310, WRITE_MASK_VAL(12, 12, 1)), /* I2S2 IO mux M1 */
++ RK_MUXROUTE_GRF(3, RK_PA2, 4, 0x0310, WRITE_MASK_VAL(14, 14, 0)), /* I2S3 IO mux M0 */
++ RK_MUXROUTE_GRF(4, RK_PC2, 5, 0x0310, WRITE_MASK_VAL(14, 14, 1)), /* I2S3 IO mux M1 */
++ RK_MUXROUTE_GRF(1, RK_PA4, 3, 0x0314, WRITE_MASK_VAL(1, 0, 0)), /* PDM IO mux M0 */
++ RK_MUXROUTE_GRF(1, RK_PA6, 3, 0x0314, WRITE_MASK_VAL(1, 0, 0)), /* PDM IO mux M0 */
++ RK_MUXROUTE_GRF(3, RK_PD6, 5, 0x0314, WRITE_MASK_VAL(1, 0, 1)), /* PDM IO mux M1 */
++ RK_MUXROUTE_GRF(4, RK_PA0, 4, 0x0314, WRITE_MASK_VAL(1, 0, 1)), /* PDM IO mux M1 */
++ RK_MUXROUTE_GRF(3, RK_PC4, 5, 0x0314, WRITE_MASK_VAL(1, 0, 2)), /* PDM IO mux M2 */
++ RK_MUXROUTE_PMU(0, RK_PA5, 3, 0x0314, WRITE_MASK_VAL(3, 2, 0)), /* PCIE20 IO mux M0 */
++ RK_MUXROUTE_GRF(2, RK_PD0, 4, 0x0314, WRITE_MASK_VAL(3, 2, 1)), /* PCIE20 IO mux M1 */
++ RK_MUXROUTE_GRF(1, RK_PB0, 4, 0x0314, WRITE_MASK_VAL(3, 2, 2)), /* PCIE20 IO mux M2 */
++ RK_MUXROUTE_PMU(0, RK_PA4, 3, 0x0314, WRITE_MASK_VAL(5, 4, 0)), /* PCIE30X1 IO mux M0 */
++ RK_MUXROUTE_GRF(2, RK_PD2, 4, 0x0314, WRITE_MASK_VAL(5, 4, 1)), /* PCIE30X1 IO mux M1 */
++ RK_MUXROUTE_GRF(1, RK_PA5, 4, 0x0314, WRITE_MASK_VAL(5, 4, 2)), /* PCIE30X1 IO mux M2 */
++ RK_MUXROUTE_PMU(0, RK_PA6, 2, 0x0314, WRITE_MASK_VAL(7, 6, 0)), /* PCIE30X2 IO mux M0 */
++ RK_MUXROUTE_GRF(2, RK_PD4, 4, 0x0314, WRITE_MASK_VAL(7, 6, 1)), /* PCIE30X2 IO mux M1 */
++ RK_MUXROUTE_GRF(4, RK_PC2, 4, 0x0314, WRITE_MASK_VAL(7, 6, 2)), /* PCIE30X2 IO mux M2 */
++};
++
+ static bool rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin,
+ int mux, u32 *loc, u32 *reg, u32 *value)
+ {
+@@ -2117,6 +2241,68 @@ static void rk3399_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
+ *bit = (pin_num % 8) * 2;
+ }
+
++#define RK3568_PULL_PMU_OFFSET 0x20
++#define RK3568_PULL_GRF_OFFSET 0x80
++#define RK3568_PULL_BITS_PER_PIN 2
++#define RK3568_PULL_PINS_PER_REG 8
++#define RK3568_PULL_BANK_STRIDE 0x10
++
++static void rk3568_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
++ int pin_num, struct regmap **regmap,
++ int *reg, u8 *bit)
++{
++ struct rockchip_pinctrl *info = bank->drvdata;
++
++ if (bank->bank_num == 0) {
++ *regmap = info->regmap_pmu;
++ *reg = RK3568_PULL_PMU_OFFSET;
++ *reg += bank->bank_num * RK3568_PULL_BANK_STRIDE;
++ *reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4);
++
++ *bit = pin_num % RK3568_PULL_PINS_PER_REG;
++ *bit *= RK3568_PULL_BITS_PER_PIN;
++ } else {
++ *regmap = info->regmap_base;
++ *reg = RK3568_PULL_GRF_OFFSET;
++ *reg += (bank->bank_num - 1) * RK3568_PULL_BANK_STRIDE;
++ *reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4);
++
++ *bit = (pin_num % RK3568_PULL_PINS_PER_REG);
++ *bit *= RK3568_PULL_BITS_PER_PIN;
++ }
++}
++
++#define RK3568_DRV_PMU_OFFSET 0x70
++#define RK3568_DRV_GRF_OFFSET 0x200
++#define RK3568_DRV_BITS_PER_PIN 8
++#define RK3568_DRV_PINS_PER_REG 2
++#define RK3568_DRV_BANK_STRIDE 0x40
++
++static void rk3568_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
++ int pin_num, struct regmap **regmap,
++ int *reg, u8 *bit)
++{
++ struct rockchip_pinctrl *info = bank->drvdata;
++
++ /* The first 32 pins of the first bank are located in PMU */
++ if (bank->bank_num == 0) {
++ *regmap = info->regmap_pmu;
++ *reg = RK3568_DRV_PMU_OFFSET;
++ *reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4);
++
++ *bit = pin_num % RK3568_DRV_PINS_PER_REG;
++ *bit *= RK3568_DRV_BITS_PER_PIN;
++ } else {
++ *regmap = info->regmap_base;
++ *reg = RK3568_DRV_GRF_OFFSET;
++ *reg += (bank->bank_num - 1) * RK3568_DRV_BANK_STRIDE;
++ *reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4);
++
++ *bit = (pin_num % RK3568_DRV_PINS_PER_REG);
++ *bit *= RK3568_DRV_BITS_PER_PIN;
++ }
++}
++
+ static int rockchip_perpin_drv_list[DRV_TYPE_MAX][8] = {
+ { 2, 4, 8, 12, -1, -1, -1, -1 },
+ { 3, 6, 9, 12, -1, -1, -1, -1 },
+@@ -2217,6 +2403,11 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
+ bank->bank_num, pin_num, strength);
+
+ ctrl->drv_calc_reg(bank, pin_num, ®map, ®, &bit);
++ if (ctrl->type == RK3568) {
++ rmask_bits = RK3568_DRV_BITS_PER_PIN;
++ ret = (1 << (strength + 1)) - 1;
++ goto config;
++ }
+
+ ret = -EINVAL;
+ for (i = 0; i < ARRAY_SIZE(rockchip_perpin_drv_list[drv_type]); i++) {
+@@ -2286,6 +2477,7 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
+ return -EINVAL;
+ }
+
++config:
+ /* enable the write to the equivalent lower bits */
+ data = ((1 << rmask_bits) - 1) << (bit + 16);
+ rmask = data | (data >> 16);
+@@ -2388,6 +2580,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
+ case RK3308:
+ case RK3368:
+ case RK3399:
++ case RK3568:
+ pull_type = bank->pull_type[pin_num / 8];
+ ret = -EINVAL;
+ for (i = 0; i < ARRAY_SIZE(rockchip_pull_list[pull_type]);
+@@ -2397,6 +2590,14 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
+ break;
+ }
+ }
++ /*
++ * In the TRM, pull-up being 1 for everything except the GPIO0_D0-D6,
++ * where that pull up value becomes 3.
++ */
++ if (ctrl->type == RK3568 && bank->bank_num == 0 && pin_num >= 27 && pin_num <= 30) {
++ if (ret == 1)
++ ret = 3;
++ }
+
+ if (ret < 0) {
+ dev_err(info->dev, "unsupported pull setting %d\n",
+@@ -2441,6 +2642,35 @@ static int rk3328_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
+ return 0;
+ }
+
++#define RK3568_SCHMITT_BITS_PER_PIN 2
++#define RK3568_SCHMITT_PINS_PER_REG 8
++#define RK3568_SCHMITT_BANK_STRIDE 0x10
++#define RK3568_SCHMITT_GRF_OFFSET 0xc0
++#define RK3568_SCHMITT_PMUGRF_OFFSET 0x30
++
++static int rk3568_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
++ int pin_num,
++ struct regmap **regmap,
++ int *reg, u8 *bit)
++{
++ struct rockchip_pinctrl *info = bank->drvdata;
++
++ if (bank->bank_num == 0) {
++ *regmap = info->regmap_pmu;
++ *reg = RK3568_SCHMITT_PMUGRF_OFFSET;
++ } else {
++ *regmap = info->regmap_base;
++ *reg = RK3568_SCHMITT_GRF_OFFSET;
++ *reg += (bank->bank_num - 1) * RK3568_SCHMITT_BANK_STRIDE;
++ }
++
++ *reg += ((pin_num / RK3568_SCHMITT_PINS_PER_REG) * 4);
++ *bit = pin_num % RK3568_SCHMITT_PINS_PER_REG;
++ *bit *= RK3568_SCHMITT_BITS_PER_PIN;
++
++ return 0;
++}
++
+ static int rockchip_get_schmitt(struct rockchip_pin_bank *bank, int pin_num)
+ {
+ struct rockchip_pinctrl *info = bank->drvdata;
+@@ -2459,6 +2689,13 @@ static int rockchip_get_schmitt(struct rockchip_pin_bank *bank, int pin_num)
+ return ret;
+
+ data >>= bit;
++ switch (ctrl->type) {
++ case RK3568:
++ return data & ((1 << RK3568_SCHMITT_BITS_PER_PIN) - 1);
++ default:
++ break;
++ }
++
+ return data & 0x1;
+ }
+
+@@ -2480,8 +2717,17 @@ static int rockchip_set_schmitt(struct rockchip_pin_bank *bank,
+ return ret;
+
+ /* enable the write to the equivalent lower bits */
+- data = BIT(bit + 16) | (enable << bit);
+- rmask = BIT(bit + 16) | BIT(bit);
++ switch (ctrl->type) {
++ case RK3568:
++ data = ((1 << RK3568_SCHMITT_BITS_PER_PIN) - 1) << (bit + 16);
++ rmask = data | (data >> 16);
++ data |= ((enable ? 0x2 : 0x1) << bit);
++ break;
++ default:
++ data = BIT(bit + 16) | (enable << bit);
++ rmask = BIT(bit + 16) | BIT(bit);
++ break;
++ }
+
+ return regmap_update_bits(regmap, reg, rmask, data);
+ }
+@@ -2655,6 +2901,7 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl,
+ case RK3308:
+ case RK3368:
+ case RK3399:
++ case RK3568:
+ return (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT);
+ }
+
+@@ -4230,6 +4477,45 @@ static struct rockchip_pin_ctrl rk3399_pin_ctrl = {
+ .drv_calc_reg = rk3399_calc_drv_reg_and_bit,
+ };
+
++static struct rockchip_pin_bank rk3568_pin_banks[] = {
++ PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT,
++ IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT,
++ IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT,
++ IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT),
++ PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT,
++ IOMUX_WIDTH_4BIT,
++ IOMUX_WIDTH_4BIT,
++ IOMUX_WIDTH_4BIT),
++ PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT,
++ IOMUX_WIDTH_4BIT,
++ IOMUX_WIDTH_4BIT,
++ IOMUX_WIDTH_4BIT),
++ PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT,
++ IOMUX_WIDTH_4BIT,
++ IOMUX_WIDTH_4BIT,
++ IOMUX_WIDTH_4BIT),
++ PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT,
++ IOMUX_WIDTH_4BIT,
++ IOMUX_WIDTH_4BIT,
++ IOMUX_WIDTH_4BIT),
++};
++
++static struct rockchip_pin_ctrl rk3568_pin_ctrl = {
++ .pin_banks = rk3568_pin_banks,
++ .nr_banks = ARRAY_SIZE(rk3568_pin_banks),
++ .label = "RK3568-GPIO",
++ .type = RK3568,
++ .grf_mux_offset = 0x0,
++ .pmu_mux_offset = 0x0,
++ .grf_drv_offset = 0x0200,
++ .pmu_drv_offset = 0x0070,
++ .iomux_routes = rk3568_mux_route_data,
++ .niomux_routes = ARRAY_SIZE(rk3568_mux_route_data),
++ .pull_calc_reg = rk3568_calc_pull_reg_and_bit,
++ .drv_calc_reg = rk3568_calc_drv_reg_and_bit,
++ .schmitt_calc_reg = rk3568_calc_schmitt_reg_and_bit,
++};
++
+ static const struct of_device_id rockchip_pinctrl_dt_match[] = {
+ { .compatible = "rockchip,px30-pinctrl",
+ .data = &px30_pin_ctrl },
+@@ -4259,6 +4545,8 @@ static const struct of_device_id rockchip_pinctrl_dt_match[] = {
+ .data = &rk3368_pin_ctrl },
+ { .compatible = "rockchip,rk3399-pinctrl",
+ .data = &rk3399_pin_ctrl },
++ { .compatible = "rockchip,rk3568-pinctrl",
++ .data = &rk3568_pin_ctrl },
+ {},
+ };
+
+--
+2.39.2
+
--- /dev/null
+From 09b580ff616df42637ef5101bf8a511520936671 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Apr 2021 17:12:40 +0800
+Subject: pinctrl: rockchip: do coding style for mux route struct
+
+From: Jianqun Xu <jay.xu@rock-chips.com>
+
+[ Upstream commit fe202ea8e5b170ef7b3741da885e8cb7bae1106e ]
+
+The mux route tables take many lines for each SoC, and it will be more
+instances for newly SoC, that makes the file size increase larger.
+
+This patch only do coding style for mux route struct, by adding a new
+definition and replace the structs by script which supplied by
+huangtao@rock-chips.com
+
+sed -i -e "
+/static struct rockchip_mux_route_data /bcheck
+b
+:append-next-line
+N
+:check
+/^[^;]*$/bappend-next-line
+s/[[:blank:]]*.bank_num = \([[:digit:]]*,\)\n/\tRK_MUXROUTE_SAME(\1/g
+s/[[:blank:]]*.pin =[[:blank:]]*0,\n/ RK_PA0,/g
+s/[[:blank:]]*.pin =[[:blank:]]*1,\n/ RK_PA1,/g
+s/[[:blank:]]*.pin =[[:blank:]]*2,\n/ RK_PA2,/g
+s/[[:blank:]]*.pin =[[:blank:]]*3,\n/ RK_PA3,/g
+s/[[:blank:]]*.pin =[[:blank:]]*4,\n/ RK_PA4,/g
+s/[[:blank:]]*.pin =[[:blank:]]*5,\n/ RK_PA5,/g
+s/[[:blank:]]*.pin =[[:blank:]]*6,\n/ RK_PA6,/g
+s/[[:blank:]]*.pin =[[:blank:]]*7,\n/ RK_PA7,/g
+s/[[:blank:]]*.pin =[[:blank:]]*8,\n/ RK_PB0,/g
+s/[[:blank:]]*.pin =[[:blank:]]*9,\n/ RK_PB1,/g
+s/[[:blank:]]*.pin =[[:blank:]]*10,\n/ RK_PB2,/g
+s/[[:blank:]]*.pin =[[:blank:]]*11,\n/ RK_PB3,/g
+s/[[:blank:]]*.pin =[[:blank:]]*12,\n/ RK_PB4,/g
+s/[[:blank:]]*.pin =[[:blank:]]*13,\n/ RK_PB5,/g
+s/[[:blank:]]*.pin =[[:blank:]]*14,\n/ RK_PB6,/g
+s/[[:blank:]]*.pin =[[:blank:]]*15,\n/ RK_PB7,/g
+s/[[:blank:]]*.pin =[[:blank:]]*16,\n/ RK_PC0,/g
+s/[[:blank:]]*.pin =[[:blank:]]*17,\n/ RK_PC1,/g
+s/[[:blank:]]*.pin =[[:blank:]]*18,\n/ RK_PC2,/g
+s/[[:blank:]]*.pin =[[:blank:]]*19,\n/ RK_PC3,/g
+s/[[:blank:]]*.pin =[[:blank:]]*20,\n/ RK_PC4,/g
+s/[[:blank:]]*.pin =[[:blank:]]*21,\n/ RK_PC5,/g
+s/[[:blank:]]*.pin =[[:blank:]]*22,\n/ RK_PC6,/g
+s/[[:blank:]]*.pin =[[:blank:]]*23,\n/ RK_PC7,/g
+s/[[:blank:]]*.pin =[[:blank:]]*24,\n/ RK_PD0,/g
+s/[[:blank:]]*.pin =[[:blank:]]*25,\n/ RK_PD1,/g
+s/[[:blank:]]*.pin =[[:blank:]]*26,\n/ RK_PD2,/g
+s/[[:blank:]]*.pin =[[:blank:]]*27,\n/ RK_PD3,/g
+s/[[:blank:]]*.pin =[[:blank:]]*28,\n/ RK_PD4,/g
+s/[[:blank:]]*.pin =[[:blank:]]*29,\n/ RK_PD5,/g
+s/[[:blank:]]*.pin =[[:blank:]]*30,\n/ RK_PD6,/g
+s/[[:blank:]]*.pin =[[:blank:]]*31,\n/ RK_PD7,/g
+s/[[:blank:]]*.func = \([[:digit:]]*,\)\n/ \1/g
+s/[[:blank:]]*.route_location =[[:blank:]]*\([[:print:]]*,\)\n//g
+s/[[:blank:]]*.route_offset = \(0x[[:xdigit:]]*,\)\n/ \1/g
+s/[[:blank:]]*.route_val =[[:blank:]]*\([[:print:]]*\),\n/ \1),/g
+s/\t{\n//g
+s/\t}, {\n//g
+s/\t},//g
+s/[[:blank:]]*\(\/\*[[:print:]]*\*\/\)\n[[:blank:]]*RK_MUXROUTE_SAME(\([[:print:]]*\)),\n/\tRK_MUXROUTE_SAME(\2), \1\n/g
+s/[[:blank:]]*\(\/\*[[:print:]]*\*\/\)\n[[:blank:]]*RK_MUXROUTE_SAME(\([[:print:]]*\)),/\tRK_MUXROUTE_SAME(\2), \1\n/g
+" drivers/pinctrl/pinctrl-rockchip.c
+
+Reviewed-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Jianqun Xu <jay.xu@rock-chips.com>
+Link: https://lore.kernel.org/r/20210420091240.1246429-1-jay.xu@rock-chips.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Stable-dep-of: c818ae563bf9 ("pinctrl: rockchip: Fix refcount leak in rockchip_pinctrl_parse_groups")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/pinctrl-rockchip.c | 650 ++++-------------------------
+ 1 file changed, 80 insertions(+), 570 deletions(-)
+
+diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
+index 38ea70f49cb07..944c7254f672b 100644
+--- a/drivers/pinctrl/pinctrl-rockchip.c
++++ b/drivers/pinctrl/pinctrl-rockchip.c
+@@ -844,597 +844,107 @@ static void rockchip_get_recalced_mux(struct rockchip_pin_bank *bank, int pin,
+ }
+
+ static struct rockchip_mux_route_data px30_mux_route_data[] = {
+- {
+- /* cif-d2m0 */
+- .bank_num = 2,
+- .pin = 0,
+- .func = 1,
+- .route_offset = 0x184,
+- .route_val = BIT(16 + 7),
+- }, {
+- /* cif-d2m1 */
+- .bank_num = 3,
+- .pin = 3,
+- .func = 3,
+- .route_offset = 0x184,
+- .route_val = BIT(16 + 7) | BIT(7),
+- }, {
+- /* pdm-m0 */
+- .bank_num = 3,
+- .pin = 22,
+- .func = 2,
+- .route_offset = 0x184,
+- .route_val = BIT(16 + 8),
+- }, {
+- /* pdm-m1 */
+- .bank_num = 2,
+- .pin = 22,
+- .func = 1,
+- .route_offset = 0x184,
+- .route_val = BIT(16 + 8) | BIT(8),
+- }, {
+- /* uart2-rxm0 */
+- .bank_num = 1,
+- .pin = 27,
+- .func = 2,
+- .route_offset = 0x184,
+- .route_val = BIT(16 + 10),
+- }, {
+- /* uart2-rxm1 */
+- .bank_num = 2,
+- .pin = 14,
+- .func = 2,
+- .route_offset = 0x184,
+- .route_val = BIT(16 + 10) | BIT(10),
+- }, {
+- /* uart3-rxm0 */
+- .bank_num = 0,
+- .pin = 17,
+- .func = 2,
+- .route_offset = 0x184,
+- .route_val = BIT(16 + 9),
+- }, {
+- /* uart3-rxm1 */
+- .bank_num = 1,
+- .pin = 15,
+- .func = 2,
+- .route_offset = 0x184,
+- .route_val = BIT(16 + 9) | BIT(9),
+- },
++ RK_MUXROUTE_SAME(2, RK_PA0, 1, 0x184, BIT(16 + 7)), /* cif-d2m0 */
++ RK_MUXROUTE_SAME(3, RK_PA3, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d2m1 */
++ RK_MUXROUTE_SAME(3, RK_PC6, 2, 0x184, BIT(16 + 8)), /* pdm-m0 */
++ RK_MUXROUTE_SAME(2, RK_PC6, 1, 0x184, BIT(16 + 8) | BIT(8)), /* pdm-m1 */
++ RK_MUXROUTE_SAME(1, RK_PD3, 2, 0x184, BIT(16 + 10)), /* uart2-rxm0 */
++ RK_MUXROUTE_SAME(2, RK_PB6, 2, 0x184, BIT(16 + 10) | BIT(10)), /* uart2-rxm1 */
++ RK_MUXROUTE_SAME(0, RK_PC1, 2, 0x184, BIT(16 + 9)), /* uart3-rxm0 */
++ RK_MUXROUTE_SAME(1, RK_PB7, 2, 0x184, BIT(16 + 9) | BIT(9)), /* uart3-rxm1 */
+ };
+
+ static struct rockchip_mux_route_data rk3128_mux_route_data[] = {
+- {
+- /* spi-0 */
+- .bank_num = 1,
+- .pin = 10,
+- .func = 1,
+- .route_offset = 0x144,
+- .route_val = BIT(16 + 3) | BIT(16 + 4),
+- }, {
+- /* spi-1 */
+- .bank_num = 1,
+- .pin = 27,
+- .func = 3,
+- .route_offset = 0x144,
+- .route_val = BIT(16 + 3) | BIT(16 + 4) | BIT(3),
+- }, {
+- /* spi-2 */
+- .bank_num = 0,
+- .pin = 13,
+- .func = 2,
+- .route_offset = 0x144,
+- .route_val = BIT(16 + 3) | BIT(16 + 4) | BIT(4),
+- }, {
+- /* i2s-0 */
+- .bank_num = 1,
+- .pin = 5,
+- .func = 1,
+- .route_offset = 0x144,
+- .route_val = BIT(16 + 5),
+- }, {
+- /* i2s-1 */
+- .bank_num = 0,
+- .pin = 14,
+- .func = 1,
+- .route_offset = 0x144,
+- .route_val = BIT(16 + 5) | BIT(5),
+- }, {
+- /* emmc-0 */
+- .bank_num = 1,
+- .pin = 22,
+- .func = 2,
+- .route_offset = 0x144,
+- .route_val = BIT(16 + 6),
+- }, {
+- /* emmc-1 */
+- .bank_num = 2,
+- .pin = 4,
+- .func = 2,
+- .route_offset = 0x144,
+- .route_val = BIT(16 + 6) | BIT(6),
+- },
++ RK_MUXROUTE_SAME(1, RK_PB2, 1, 0x144, BIT(16 + 3) | BIT(16 + 4)), /* spi-0 */
++ RK_MUXROUTE_SAME(1, RK_PD3, 3, 0x144, BIT(16 + 3) | BIT(16 + 4) | BIT(3)), /* spi-1 */
++ RK_MUXROUTE_SAME(0, RK_PB5, 2, 0x144, BIT(16 + 3) | BIT(16 + 4) | BIT(4)), /* spi-2 */
++ RK_MUXROUTE_SAME(1, RK_PA5, 1, 0x144, BIT(16 + 5)), /* i2s-0 */
++ RK_MUXROUTE_SAME(0, RK_PB6, 1, 0x144, BIT(16 + 5) | BIT(5)), /* i2s-1 */
++ RK_MUXROUTE_SAME(1, RK_PC6, 2, 0x144, BIT(16 + 6)), /* emmc-0 */
++ RK_MUXROUTE_SAME(2, RK_PA4, 2, 0x144, BIT(16 + 6) | BIT(6)), /* emmc-1 */
+ };
+
+ static struct rockchip_mux_route_data rk3188_mux_route_data[] = {
+- {
+- /* non-iomuxed emmc/flash pins on flash-dqs */
+- .bank_num = 0,
+- .pin = 24,
+- .func = 1,
+- .route_location = ROCKCHIP_ROUTE_GRF,
+- .route_offset = 0xa0,
+- .route_val = BIT(16 + 11),
+- }, {
+- /* non-iomuxed emmc/flash pins on emmc-clk */
+- .bank_num = 0,
+- .pin = 24,
+- .func = 2,
+- .route_location = ROCKCHIP_ROUTE_GRF,
+- .route_offset = 0xa0,
+- .route_val = BIT(16 + 11) | BIT(11),
+- },
++ RK_MUXROUTE_SAME(0, RK_PD0, 1, 0xa0, BIT(16 + 11)), /* non-iomuxed emmc/flash pins on flash-dqs */
++ RK_MUXROUTE_SAME(0, RK_PD0, 2, 0xa0, BIT(16 + 11) | BIT(11)), /* non-iomuxed emmc/flash pins on emmc-clk */
+ };
+
+ static struct rockchip_mux_route_data rk3228_mux_route_data[] = {
+- {
+- /* pwm0-0 */
+- .bank_num = 0,
+- .pin = 26,
+- .func = 1,
+- .route_offset = 0x50,
+- .route_val = BIT(16),
+- }, {
+- /* pwm0-1 */
+- .bank_num = 3,
+- .pin = 21,
+- .func = 1,
+- .route_offset = 0x50,
+- .route_val = BIT(16) | BIT(0),
+- }, {
+- /* pwm1-0 */
+- .bank_num = 0,
+- .pin = 27,
+- .func = 1,
+- .route_offset = 0x50,
+- .route_val = BIT(16 + 1),
+- }, {
+- /* pwm1-1 */
+- .bank_num = 0,
+- .pin = 30,
+- .func = 2,
+- .route_offset = 0x50,
+- .route_val = BIT(16 + 1) | BIT(1),
+- }, {
+- /* pwm2-0 */
+- .bank_num = 0,
+- .pin = 28,
+- .func = 1,
+- .route_offset = 0x50,
+- .route_val = BIT(16 + 2),
+- }, {
+- /* pwm2-1 */
+- .bank_num = 1,
+- .pin = 12,
+- .func = 2,
+- .route_offset = 0x50,
+- .route_val = BIT(16 + 2) | BIT(2),
+- }, {
+- /* pwm3-0 */
+- .bank_num = 3,
+- .pin = 26,
+- .func = 1,
+- .route_offset = 0x50,
+- .route_val = BIT(16 + 3),
+- }, {
+- /* pwm3-1 */
+- .bank_num = 1,
+- .pin = 11,
+- .func = 2,
+- .route_offset = 0x50,
+- .route_val = BIT(16 + 3) | BIT(3),
+- }, {
+- /* sdio-0_d0 */
+- .bank_num = 1,
+- .pin = 1,
+- .func = 1,
+- .route_offset = 0x50,
+- .route_val = BIT(16 + 4),
+- }, {
+- /* sdio-1_d0 */
+- .bank_num = 3,
+- .pin = 2,
+- .func = 1,
+- .route_offset = 0x50,
+- .route_val = BIT(16 + 4) | BIT(4),
+- }, {
+- /* spi-0_rx */
+- .bank_num = 0,
+- .pin = 13,
+- .func = 2,
+- .route_offset = 0x50,
+- .route_val = BIT(16 + 5),
+- }, {
+- /* spi-1_rx */
+- .bank_num = 2,
+- .pin = 0,
+- .func = 2,
+- .route_offset = 0x50,
+- .route_val = BIT(16 + 5) | BIT(5),
+- }, {
+- /* emmc-0_cmd */
+- .bank_num = 1,
+- .pin = 22,
+- .func = 2,
+- .route_offset = 0x50,
+- .route_val = BIT(16 + 7),
+- }, {
+- /* emmc-1_cmd */
+- .bank_num = 2,
+- .pin = 4,
+- .func = 2,
+- .route_offset = 0x50,
+- .route_val = BIT(16 + 7) | BIT(7),
+- }, {
+- /* uart2-0_rx */
+- .bank_num = 1,
+- .pin = 19,
+- .func = 2,
+- .route_offset = 0x50,
+- .route_val = BIT(16 + 8),
+- }, {
+- /* uart2-1_rx */
+- .bank_num = 1,
+- .pin = 10,
+- .func = 2,
+- .route_offset = 0x50,
+- .route_val = BIT(16 + 8) | BIT(8),
+- }, {
+- /* uart1-0_rx */
+- .bank_num = 1,
+- .pin = 10,
+- .func = 1,
+- .route_offset = 0x50,
+- .route_val = BIT(16 + 11),
+- }, {
+- /* uart1-1_rx */
+- .bank_num = 3,
+- .pin = 13,
+- .func = 1,
+- .route_offset = 0x50,
+- .route_val = BIT(16 + 11) | BIT(11),
+- },
++ RK_MUXROUTE_SAME(0, RK_PD2, 1, 0x50, BIT(16)), /* pwm0-0 */
++ RK_MUXROUTE_SAME(3, RK_PC5, 1, 0x50, BIT(16) | BIT(0)), /* pwm0-1 */
++ RK_MUXROUTE_SAME(0, RK_PD3, 1, 0x50, BIT(16 + 1)), /* pwm1-0 */
++ RK_MUXROUTE_SAME(0, RK_PD6, 2, 0x50, BIT(16 + 1) | BIT(1)), /* pwm1-1 */
++ RK_MUXROUTE_SAME(0, RK_PD4, 1, 0x50, BIT(16 + 2)), /* pwm2-0 */
++ RK_MUXROUTE_SAME(1, RK_PB4, 2, 0x50, BIT(16 + 2) | BIT(2)), /* pwm2-1 */
++ RK_MUXROUTE_SAME(3, RK_PD2, 1, 0x50, BIT(16 + 3)), /* pwm3-0 */
++ RK_MUXROUTE_SAME(1, RK_PB3, 2, 0x50, BIT(16 + 3) | BIT(3)), /* pwm3-1 */
++ RK_MUXROUTE_SAME(1, RK_PA1, 1, 0x50, BIT(16 + 4)), /* sdio-0_d0 */
++ RK_MUXROUTE_SAME(3, RK_PA2, 1, 0x50, BIT(16 + 4) | BIT(4)), /* sdio-1_d0 */
++ RK_MUXROUTE_SAME(0, RK_PB5, 2, 0x50, BIT(16 + 5)), /* spi-0_rx */
++ RK_MUXROUTE_SAME(2, RK_PA0, 2, 0x50, BIT(16 + 5) | BIT(5)), /* spi-1_rx */
++ RK_MUXROUTE_SAME(1, RK_PC6, 2, 0x50, BIT(16 + 7)), /* emmc-0_cmd */
++ RK_MUXROUTE_SAME(2, RK_PA4, 2, 0x50, BIT(16 + 7) | BIT(7)), /* emmc-1_cmd */
++ RK_MUXROUTE_SAME(1, RK_PC3, 2, 0x50, BIT(16 + 8)), /* uart2-0_rx */
++ RK_MUXROUTE_SAME(1, RK_PB2, 2, 0x50, BIT(16 + 8) | BIT(8)), /* uart2-1_rx */
++ RK_MUXROUTE_SAME(1, RK_PB2, 1, 0x50, BIT(16 + 11)), /* uart1-0_rx */
++ RK_MUXROUTE_SAME(3, RK_PB5, 1, 0x50, BIT(16 + 11) | BIT(11)), /* uart1-1_rx */
+ };
+
+ static struct rockchip_mux_route_data rk3288_mux_route_data[] = {
+- {
+- /* edphdmi_cecinoutt1 */
+- .bank_num = 7,
+- .pin = 16,
+- .func = 2,
+- .route_offset = 0x264,
+- .route_val = BIT(16 + 12) | BIT(12),
+- }, {
+- /* edphdmi_cecinout */
+- .bank_num = 7,
+- .pin = 23,
+- .func = 4,
+- .route_offset = 0x264,
+- .route_val = BIT(16 + 12),
+- },
++ RK_MUXROUTE_SAME(7, RK_PC0, 2, 0x264, BIT(16 + 12) | BIT(12)), /* edphdmi_cecinoutt1 */
++ RK_MUXROUTE_SAME(7, RK_PC7, 4, 0x264, BIT(16 + 12)), /* edphdmi_cecinout */
+ };
+
+ static struct rockchip_mux_route_data rk3308_mux_route_data[] = {
+- {
+- /* rtc_clk */
+- .bank_num = 0,
+- .pin = 19,
+- .func = 1,
+- .route_offset = 0x314,
+- .route_val = BIT(16 + 0) | BIT(0),
+- }, {
+- /* uart2_rxm0 */
+- .bank_num = 1,
+- .pin = 22,
+- .func = 2,
+- .route_offset = 0x314,
+- .route_val = BIT(16 + 2) | BIT(16 + 3),
+- }, {
+- /* uart2_rxm1 */
+- .bank_num = 4,
+- .pin = 26,
+- .func = 2,
+- .route_offset = 0x314,
+- .route_val = BIT(16 + 2) | BIT(16 + 3) | BIT(2),
+- }, {
+- /* i2c3_sdam0 */
+- .bank_num = 0,
+- .pin = 15,
+- .func = 2,
+- .route_offset = 0x608,
+- .route_val = BIT(16 + 8) | BIT(16 + 9),
+- }, {
+- /* i2c3_sdam1 */
+- .bank_num = 3,
+- .pin = 12,
+- .func = 2,
+- .route_offset = 0x608,
+- .route_val = BIT(16 + 8) | BIT(16 + 9) | BIT(8),
+- }, {
+- /* i2c3_sdam2 */
+- .bank_num = 2,
+- .pin = 0,
+- .func = 3,
+- .route_offset = 0x608,
+- .route_val = BIT(16 + 8) | BIT(16 + 9) | BIT(9),
+- }, {
+- /* i2s-8ch-1-sclktxm0 */
+- .bank_num = 1,
+- .pin = 3,
+- .func = 2,
+- .route_offset = 0x308,
+- .route_val = BIT(16 + 3),
+- }, {
+- /* i2s-8ch-1-sclkrxm0 */
+- .bank_num = 1,
+- .pin = 4,
+- .func = 2,
+- .route_offset = 0x308,
+- .route_val = BIT(16 + 3),
+- }, {
+- /* i2s-8ch-1-sclktxm1 */
+- .bank_num = 1,
+- .pin = 13,
+- .func = 2,
+- .route_offset = 0x308,
+- .route_val = BIT(16 + 3) | BIT(3),
+- }, {
+- /* i2s-8ch-1-sclkrxm1 */
+- .bank_num = 1,
+- .pin = 14,
+- .func = 2,
+- .route_offset = 0x308,
+- .route_val = BIT(16 + 3) | BIT(3),
+- }, {
+- /* pdm-clkm0 */
+- .bank_num = 1,
+- .pin = 4,
+- .func = 3,
+- .route_offset = 0x308,
+- .route_val = BIT(16 + 12) | BIT(16 + 13),
+- }, {
+- /* pdm-clkm1 */
+- .bank_num = 1,
+- .pin = 14,
+- .func = 4,
+- .route_offset = 0x308,
+- .route_val = BIT(16 + 12) | BIT(16 + 13) | BIT(12),
+- }, {
+- /* pdm-clkm2 */
+- .bank_num = 2,
+- .pin = 6,
+- .func = 2,
+- .route_offset = 0x308,
+- .route_val = BIT(16 + 12) | BIT(16 + 13) | BIT(13),
+- }, {
+- /* pdm-clkm-m2 */
+- .bank_num = 2,
+- .pin = 4,
+- .func = 3,
+- .route_offset = 0x600,
+- .route_val = BIT(16 + 2) | BIT(2),
+- }, {
+- /* spi1_miso */
+- .bank_num = 3,
+- .pin = 10,
+- .func = 3,
+- .route_offset = 0x314,
+- .route_val = BIT(16 + 9),
+- }, {
+- /* spi1_miso_m1 */
+- .bank_num = 2,
+- .pin = 4,
+- .func = 2,
+- .route_offset = 0x314,
+- .route_val = BIT(16 + 9) | BIT(9),
+- }, {
+- /* owire_m0 */
+- .bank_num = 0,
+- .pin = 11,
+- .func = 3,
+- .route_offset = 0x314,
+- .route_val = BIT(16 + 10) | BIT(16 + 11),
+- }, {
+- /* owire_m1 */
+- .bank_num = 1,
+- .pin = 22,
+- .func = 7,
+- .route_offset = 0x314,
+- .route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(10),
+- }, {
+- /* owire_m2 */
+- .bank_num = 2,
+- .pin = 2,
+- .func = 5,
+- .route_offset = 0x314,
+- .route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(11),
+- }, {
+- /* can_rxd_m0 */
+- .bank_num = 0,
+- .pin = 11,
+- .func = 2,
+- .route_offset = 0x314,
+- .route_val = BIT(16 + 12) | BIT(16 + 13),
+- }, {
+- /* can_rxd_m1 */
+- .bank_num = 1,
+- .pin = 22,
+- .func = 5,
+- .route_offset = 0x314,
+- .route_val = BIT(16 + 12) | BIT(16 + 13) | BIT(12),
+- }, {
+- /* can_rxd_m2 */
+- .bank_num = 2,
+- .pin = 2,
+- .func = 4,
+- .route_offset = 0x314,
+- .route_val = BIT(16 + 12) | BIT(16 + 13) | BIT(13),
+- }, {
+- /* mac_rxd0_m0 */
+- .bank_num = 1,
+- .pin = 20,
+- .func = 3,
+- .route_offset = 0x314,
+- .route_val = BIT(16 + 14),
+- }, {
+- /* mac_rxd0_m1 */
+- .bank_num = 4,
+- .pin = 2,
+- .func = 2,
+- .route_offset = 0x314,
+- .route_val = BIT(16 + 14) | BIT(14),
+- }, {
+- /* uart3_rx */
+- .bank_num = 3,
+- .pin = 12,
+- .func = 4,
+- .route_offset = 0x314,
+- .route_val = BIT(16 + 15),
+- }, {
+- /* uart3_rx_m1 */
+- .bank_num = 0,
+- .pin = 17,
+- .func = 3,
+- .route_offset = 0x314,
+- .route_val = BIT(16 + 15) | BIT(15),
+- },
++ RK_MUXROUTE_SAME(0, RK_PC3, 1, 0x314, BIT(16 + 0) | BIT(0)), /* rtc_clk */
++ RK_MUXROUTE_SAME(1, RK_PC6, 2, 0x314, BIT(16 + 2) | BIT(16 + 3)), /* uart2_rxm0 */
++ RK_MUXROUTE_SAME(4, RK_PD2, 2, 0x314, BIT(16 + 2) | BIT(16 + 3) | BIT(2)), /* uart2_rxm1 */
++ RK_MUXROUTE_SAME(0, RK_PB7, 2, 0x608, BIT(16 + 8) | BIT(16 + 9)), /* i2c3_sdam0 */
++ RK_MUXROUTE_SAME(3, RK_PB4, 2, 0x608, BIT(16 + 8) | BIT(16 + 9) | BIT(8)), /* i2c3_sdam1 */
++ RK_MUXROUTE_SAME(2, RK_PA0, 3, 0x608, BIT(16 + 8) | BIT(16 + 9) | BIT(9)), /* i2c3_sdam2 */
++ RK_MUXROUTE_SAME(1, RK_PA3, 2, 0x308, BIT(16 + 3)), /* i2s-8ch-1-sclktxm0 */
++ RK_MUXROUTE_SAME(1, RK_PA4, 2, 0x308, BIT(16 + 3)), /* i2s-8ch-1-sclkrxm0 */
++ RK_MUXROUTE_SAME(1, RK_PB5, 2, 0x308, BIT(16 + 3) | BIT(3)), /* i2s-8ch-1-sclktxm1 */
++ RK_MUXROUTE_SAME(1, RK_PB6, 2, 0x308, BIT(16 + 3) | BIT(3)), /* i2s-8ch-1-sclkrxm1 */
++ RK_MUXROUTE_SAME(1, RK_PA4, 3, 0x308, BIT(16 + 12) | BIT(16 + 13)), /* pdm-clkm0 */
++ RK_MUXROUTE_SAME(1, RK_PB6, 4, 0x308, BIT(16 + 12) | BIT(16 + 13) | BIT(12)), /* pdm-clkm1 */
++ RK_MUXROUTE_SAME(2, RK_PA6, 2, 0x308, BIT(16 + 12) | BIT(16 + 13) | BIT(13)), /* pdm-clkm2 */
++ RK_MUXROUTE_SAME(2, RK_PA4, 3, 0x600, BIT(16 + 2) | BIT(2)), /* pdm-clkm-m2 */
++ RK_MUXROUTE_SAME(3, RK_PB2, 3, 0x314, BIT(16 + 9)), /* spi1_miso */
++ RK_MUXROUTE_SAME(2, RK_PA4, 2, 0x314, BIT(16 + 9) | BIT(9)), /* spi1_miso_m1 */
++ RK_MUXROUTE_SAME(0, RK_PB3, 3, 0x314, BIT(16 + 10) | BIT(16 + 11)), /* owire_m0 */
++ RK_MUXROUTE_SAME(1, RK_PC6, 7, 0x314, BIT(16 + 10) | BIT(16 + 11) | BIT(10)), /* owire_m1 */
++ RK_MUXROUTE_SAME(2, RK_PA2, 5, 0x314, BIT(16 + 10) | BIT(16 + 11) | BIT(11)), /* owire_m2 */
++ RK_MUXROUTE_SAME(0, RK_PB3, 2, 0x314, BIT(16 + 12) | BIT(16 + 13)), /* can_rxd_m0 */
++ RK_MUXROUTE_SAME(1, RK_PC6, 5, 0x314, BIT(16 + 12) | BIT(16 + 13) | BIT(12)), /* can_rxd_m1 */
++ RK_MUXROUTE_SAME(2, RK_PA2, 4, 0x314, BIT(16 + 12) | BIT(16 + 13) | BIT(13)), /* can_rxd_m2 */
++ RK_MUXROUTE_SAME(1, RK_PC4, 3, 0x314, BIT(16 + 14)), /* mac_rxd0_m0 */
++ RK_MUXROUTE_SAME(4, RK_PA2, 2, 0x314, BIT(16 + 14) | BIT(14)), /* mac_rxd0_m1 */
++ RK_MUXROUTE_SAME(3, RK_PB4, 4, 0x314, BIT(16 + 15)), /* uart3_rx */
++ RK_MUXROUTE_SAME(0, RK_PC1, 3, 0x314, BIT(16 + 15) | BIT(15)), /* uart3_rx_m1 */
+ };
+
+ static struct rockchip_mux_route_data rk3328_mux_route_data[] = {
+- {
+- /* uart2dbg_rxm0 */
+- .bank_num = 1,
+- .pin = 1,
+- .func = 2,
+- .route_offset = 0x50,
+- .route_val = BIT(16) | BIT(16 + 1),
+- }, {
+- /* uart2dbg_rxm1 */
+- .bank_num = 2,
+- .pin = 1,
+- .func = 1,
+- .route_offset = 0x50,
+- .route_val = BIT(16) | BIT(16 + 1) | BIT(0),
+- }, {
+- /* gmac-m1_rxd0 */
+- .bank_num = 1,
+- .pin = 11,
+- .func = 2,
+- .route_offset = 0x50,
+- .route_val = BIT(16 + 2) | BIT(2),
+- }, {
+- /* gmac-m1-optimized_rxd3 */
+- .bank_num = 1,
+- .pin = 14,
+- .func = 2,
+- .route_offset = 0x50,
+- .route_val = BIT(16 + 10) | BIT(10),
+- }, {
+- /* pdm_sdi0m0 */
+- .bank_num = 2,
+- .pin = 19,
+- .func = 2,
+- .route_offset = 0x50,
+- .route_val = BIT(16 + 3),
+- }, {
+- /* pdm_sdi0m1 */
+- .bank_num = 1,
+- .pin = 23,
+- .func = 3,
+- .route_offset = 0x50,
+- .route_val = BIT(16 + 3) | BIT(3),
+- }, {
+- /* spi_rxdm2 */
+- .bank_num = 3,
+- .pin = 2,
+- .func = 4,
+- .route_offset = 0x50,
+- .route_val = BIT(16 + 4) | BIT(16 + 5) | BIT(5),
+- }, {
+- /* i2s2_sdim0 */
+- .bank_num = 1,
+- .pin = 24,
+- .func = 1,
+- .route_offset = 0x50,
+- .route_val = BIT(16 + 6),
+- }, {
+- /* i2s2_sdim1 */
+- .bank_num = 3,
+- .pin = 2,
+- .func = 6,
+- .route_offset = 0x50,
+- .route_val = BIT(16 + 6) | BIT(6),
+- }, {
+- /* card_iom1 */
+- .bank_num = 2,
+- .pin = 22,
+- .func = 3,
+- .route_offset = 0x50,
+- .route_val = BIT(16 + 7) | BIT(7),
+- }, {
+- /* tsp_d5m1 */
+- .bank_num = 2,
+- .pin = 16,
+- .func = 3,
+- .route_offset = 0x50,
+- .route_val = BIT(16 + 8) | BIT(8),
+- }, {
+- /* cif_data5m1 */
+- .bank_num = 2,
+- .pin = 16,
+- .func = 4,
+- .route_offset = 0x50,
+- .route_val = BIT(16 + 9) | BIT(9),
+- },
++ RK_MUXROUTE_SAME(1, RK_PA1, 2, 0x50, BIT(16) | BIT(16 + 1)), /* uart2dbg_rxm0 */
++ RK_MUXROUTE_SAME(2, RK_PA1, 1, 0x50, BIT(16) | BIT(16 + 1) | BIT(0)), /* uart2dbg_rxm1 */
++ RK_MUXROUTE_SAME(1, RK_PB3, 2, 0x50, BIT(16 + 2) | BIT(2)), /* gmac-m1_rxd0 */
++ RK_MUXROUTE_SAME(1, RK_PB6, 2, 0x50, BIT(16 + 10) | BIT(10)), /* gmac-m1-optimized_rxd3 */
++ RK_MUXROUTE_SAME(2, RK_PC3, 2, 0x50, BIT(16 + 3)), /* pdm_sdi0m0 */
++ RK_MUXROUTE_SAME(1, RK_PC7, 3, 0x50, BIT(16 + 3) | BIT(3)), /* pdm_sdi0m1 */
++ RK_MUXROUTE_SAME(3, RK_PA2, 4, 0x50, BIT(16 + 4) | BIT(16 + 5) | BIT(5)), /* spi_rxdm2 */
++ RK_MUXROUTE_SAME(1, RK_PD0, 1, 0x50, BIT(16 + 6)), /* i2s2_sdim0 */
++ RK_MUXROUTE_SAME(3, RK_PA2, 6, 0x50, BIT(16 + 6) | BIT(6)), /* i2s2_sdim1 */
++ RK_MUXROUTE_SAME(2, RK_PC6, 3, 0x50, BIT(16 + 7) | BIT(7)), /* card_iom1 */
++ RK_MUXROUTE_SAME(2, RK_PC0, 3, 0x50, BIT(16 + 8) | BIT(8)), /* tsp_d5m1 */
++ RK_MUXROUTE_SAME(2, RK_PC0, 4, 0x50, BIT(16 + 9) | BIT(9)), /* cif_data5m1 */
+ };
+
+ static struct rockchip_mux_route_data rk3399_mux_route_data[] = {
+- {
+- /* uart2dbga_rx */
+- .bank_num = 4,
+- .pin = 8,
+- .func = 2,
+- .route_offset = 0xe21c,
+- .route_val = BIT(16 + 10) | BIT(16 + 11),
+- }, {
+- /* uart2dbgb_rx */
+- .bank_num = 4,
+- .pin = 16,
+- .func = 2,
+- .route_offset = 0xe21c,
+- .route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(10),
+- }, {
+- /* uart2dbgc_rx */
+- .bank_num = 4,
+- .pin = 19,
+- .func = 1,
+- .route_offset = 0xe21c,
+- .route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(11),
+- }, {
+- /* pcie_clkreqn */
+- .bank_num = 2,
+- .pin = 26,
+- .func = 2,
+- .route_offset = 0xe21c,
+- .route_val = BIT(16 + 14),
+- }, {
+- /* pcie_clkreqnb */
+- .bank_num = 4,
+- .pin = 24,
+- .func = 1,
+- .route_offset = 0xe21c,
+- .route_val = BIT(16 + 14) | BIT(14),
+- },
++ RK_MUXROUTE_SAME(4, RK_PB0, 2, 0xe21c, BIT(16 + 10) | BIT(16 + 11)), /* uart2dbga_rx */
++ RK_MUXROUTE_SAME(4, RK_PC0, 2, 0xe21c, BIT(16 + 10) | BIT(16 + 11) | BIT(10)), /* uart2dbgb_rx */
++ RK_MUXROUTE_SAME(4, RK_PC3, 1, 0xe21c, BIT(16 + 10) | BIT(16 + 11) | BIT(11)), /* uart2dbgc_rx */
++ RK_MUXROUTE_SAME(2, RK_PD2, 2, 0xe21c, BIT(16 + 14)), /* pcie_clkreqn */
++ RK_MUXROUTE_SAME(4, RK_PD0, 1, 0xe21c, BIT(16 + 14) | BIT(14)), /* pcie_clkreqnb */
+ };
+
+ static struct rockchip_mux_route_data rk3568_mux_route_data[] = {
+--
+2.39.2
+
--- /dev/null
+From 900970915588dce7af8542f03ba2701de6dca66f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Jan 2023 15:28:45 +0400
+Subject: pinctrl: rockchip: Fix refcount leak in rockchip_pinctrl_parse_groups
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit c818ae563bf99457f02e8170aabd6b174f629f65 ]
+
+of_find_node_by_phandle() returns a node pointer with refcount incremented,
+We should use of_node_put() on it when not needed anymore.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: d3e5116119bd ("pinctrl: add pinctrl driver for Rockchip SoCs")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Link: https://lore.kernel.org/r/20230102112845.3982407-1-linmq006@gmail.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/pinctrl-rockchip.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
+index 944c7254f672b..764c96ddfc768 100644
+--- a/drivers/pinctrl/pinctrl-rockchip.c
++++ b/drivers/pinctrl/pinctrl-rockchip.c
+@@ -2650,6 +2650,7 @@ static int rockchip_pinctrl_parse_groups(struct device_node *np,
+ np_config = of_find_node_by_phandle(be32_to_cpup(phandle));
+ ret = pinconf_generic_parse_dt_config(np_config, NULL,
+ &grp->data[j].configs, &grp->data[j].nconfigs);
++ of_node_put(np_config);
+ if (ret)
+ return ret;
+ }
+--
+2.39.2
+
--- /dev/null
+From 24d4ea7d74db21e7e934c409ae37535948c4c4a6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Jan 2023 12:24:56 +0400
+Subject: pinctrl: stm32: Fix refcount leak in stm32_pctrl_get_irq_domain
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit dcef18c8ac40aa85bb339f64c1dd31dd458b06fb ]
+
+of_irq_find_parent() returns a node pointer with refcount incremented,
+We should use of_node_put() on it when not needed anymore.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: d86f4d71e42a ("pinctrl: stm32: check irq controller availability at probe")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Link: https://lore.kernel.org/r/20230102082503.3944927-1-linmq006@gmail.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/stm32/pinctrl-stm32.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c
+index 60406f1f8337e..2d852f15cc501 100644
+--- a/drivers/pinctrl/stm32/pinctrl-stm32.c
++++ b/drivers/pinctrl/stm32/pinctrl-stm32.c
+@@ -1338,6 +1338,7 @@ static struct irq_domain *stm32_pctrl_get_irq_domain(struct device_node *np)
+ return ERR_PTR(-ENXIO);
+
+ domain = irq_find_host(parent);
++ of_node_put(parent);
+ if (!domain)
+ /* domain not registered yet */
+ return ERR_PTR(-EPROBE_DEFER);
+--
+2.39.2
+
--- /dev/null
+From 56bc56e997ec49451b4793df5e533a717e142f52 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Feb 2023 16:15:15 +0100
+Subject: PM: EM: fix memory leak with using debugfs_lookup()
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+[ Upstream commit a0e8c13ccd6a9a636d27353da62c2410c4eca337 ]
+
+When calling debugfs_lookup() the result must have dput() called on it,
+otherwise the memory will leak over time. To make things simpler, just
+call debugfs_lookup_and_remove() instead which handles all of the logic
+at once.
+
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/power/energy_model.c | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+diff --git a/kernel/power/energy_model.c b/kernel/power/energy_model.c
+index 119b929dcff0f..334173fe6940e 100644
+--- a/kernel/power/energy_model.c
++++ b/kernel/power/energy_model.c
+@@ -72,10 +72,7 @@ static void em_debug_create_pd(struct device *dev)
+
+ static void em_debug_remove_pd(struct device *dev)
+ {
+- struct dentry *debug_dir;
+-
+- debug_dir = debugfs_lookup(dev_name(dev), rootdir);
+- debugfs_remove_recursive(debug_dir);
++ debugfs_lookup_and_remove(dev_name(dev), rootdir);
+ }
+
+ static int __init em_debug_init(void)
+--
+2.39.2
+
--- /dev/null
+From 8bb64027cedc8a3c050716e134eeb843454c59db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Jan 2023 20:57:26 +0800
+Subject: powercap: fix possible name leak in powercap_register_zone()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 1b6599f741a4525ca761ecde46e5885ff1e6ba58 ]
+
+In the error path after calling dev_set_name(), the device
+name is leaked. To fix this, calling dev_set_name() before
+device_register(), and call put_device() if it returns error.
+
+All the resources is released in powercap_release(), so it
+can return from powercap_register_zone() directly.
+
+Fixes: 75d2364ea0ca ("PowerCap: Add class driver")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/powercap/powercap_sys.c | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/powercap/powercap_sys.c b/drivers/powercap/powercap_sys.c
+index 3f0b8e2ef3d46..7a3109a538813 100644
+--- a/drivers/powercap/powercap_sys.c
++++ b/drivers/powercap/powercap_sys.c
+@@ -530,9 +530,6 @@ struct powercap_zone *powercap_register_zone(
+ power_zone->name = kstrdup(name, GFP_KERNEL);
+ if (!power_zone->name)
+ goto err_name_alloc;
+- dev_set_name(&power_zone->dev, "%s:%x",
+- dev_name(power_zone->dev.parent),
+- power_zone->id);
+ power_zone->constraints = kcalloc(nr_constraints,
+ sizeof(*power_zone->constraints),
+ GFP_KERNEL);
+@@ -555,9 +552,16 @@ struct powercap_zone *powercap_register_zone(
+ power_zone->dev_attr_groups[0] = &power_zone->dev_zone_attr_group;
+ power_zone->dev_attr_groups[1] = NULL;
+ power_zone->dev.groups = power_zone->dev_attr_groups;
++ dev_set_name(&power_zone->dev, "%s:%x",
++ dev_name(power_zone->dev.parent),
++ power_zone->id);
+ result = device_register(&power_zone->dev);
+- if (result)
+- goto err_dev_ret;
++ if (result) {
++ put_device(&power_zone->dev);
++ mutex_unlock(&control_type->lock);
++
++ return ERR_PTR(result);
++ }
+
+ control_type->nr_zones++;
+ mutex_unlock(&control_type->lock);
+--
+2.39.2
+
--- /dev/null
+From 7965dc89865b46002db945aa59d5ea4c30750a2c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Feb 2023 16:26:49 +0530
+Subject: powerpc/eeh: Set channel state after notifying the drivers
+
+From: Ganesh Goudar <ganeshgr@linux.ibm.com>
+
+[ Upstream commit 9efcdaac36e1643a1b7f5337e6143ce142d381b1 ]
+
+When a PCI error is encountered 6th time in an hour we
+set the channel state to perm_failure and notify the
+driver about the permanent failure.
+
+However, after upstream commit 38ddc011478e ("powerpc/eeh:
+Make permanently failed devices non-actionable"), EEH handler
+stops calling any routine once the device is marked as
+permanent failure. This issue can lead to fatal consequences
+like kernel hang with certain PCI devices.
+
+Following log is observed with lpfc driver, with and without
+this change, Without this change kernel hangs, If PCI error
+is encountered 6 times for a device in an hour.
+
+Without the change
+
+ EEH: Beginning: 'error_detected(permanent failure)'
+ PCI 0132:60:00.0#600000: EEH: not actionable (1,1,1)
+ PCI 0132:60:00.1#600000: EEH: not actionable (1,1,1)
+ EEH: Finished:'error_detected(permanent failure)'
+
+With the change
+
+ EEH: Beginning: 'error_detected(permanent failure)'
+ EEH: Invoking lpfc->error_detected(permanent failure)
+ EEH: lpfc driver reports: 'disconnect'
+ EEH: Invoking lpfc->error_detected(permanent failure)
+ EEH: lpfc driver reports: 'disconnect'
+ EEH: Finished:'error_detected(permanent failure)'
+
+To fix the issue, set channel state to permanent failure after
+notifying the drivers.
+
+Fixes: 38ddc011478e ("powerpc/eeh: Make permanently failed devices non-actionable")
+Suggested-by: Mahesh Salgaonkar <mahesh@linux.ibm.com>
+Signed-off-by: Ganesh Goudar <ganeshgr@linux.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20230209105649.127707-1-ganeshgr@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/eeh_driver.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c
+index cb3ac555c9446..665d847ef9b5a 100644
+--- a/arch/powerpc/kernel/eeh_driver.c
++++ b/arch/powerpc/kernel/eeh_driver.c
+@@ -1069,10 +1069,10 @@ void eeh_handle_normal_event(struct eeh_pe *pe)
+ eeh_slot_error_detail(pe, EEH_LOG_PERM);
+
+ /* Notify all devices that they're about to go down. */
+- eeh_set_channel_state(pe, pci_channel_io_perm_failure);
+ eeh_set_irq_state(pe, false);
+ eeh_pe_report("error_detected(permanent failure)", pe,
+ eeh_report_failure, NULL);
++ eeh_set_channel_state(pe, pci_channel_io_perm_failure);
+
+ /* Mark the PE to be removed permanently */
+ eeh_pe_state_mark(pe, EEH_PE_REMOVED);
+@@ -1189,10 +1189,10 @@ void eeh_handle_special_event(void)
+
+ /* Notify all devices to be down */
+ eeh_pe_state_clear(pe, EEH_PE_PRI_BUS, true);
+- eeh_set_channel_state(pe, pci_channel_io_perm_failure);
+ eeh_pe_report(
+ "error_detected(permanent failure)", pe,
+ eeh_report_failure, NULL);
++ eeh_set_channel_state(pe, pci_channel_io_perm_failure);
+
+ pci_lock_rescan_remove();
+ list_for_each_entry(hose, &hose_list, list_node) {
+--
+2.39.2
+
--- /dev/null
+From f2fc37ae5c5a3779d6792350f8a7dfcb7fdb5317 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Oct 2021 18:06:27 +1100
+Subject: powerpc/eeh: Small refactor of eeh_handle_normal_event()
+
+From: Daniel Axtens <dja@axtens.net>
+
+[ Upstream commit 10b34ece132ee46dc4e6459c765d180c422a09fa ]
+
+The control flow of eeh_handle_normal_event() is a bit tricky.
+
+Break out one of the error handling paths - rather than be in an else
+block, we'll make it part of the regular body of the function and put a
+'goto out;' in the true limb of the if.
+
+Signed-off-by: Daniel Axtens <dja@axtens.net>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20211015070628.1331635-1-dja@axtens.net
+Stable-dep-of: 9efcdaac36e1 ("powerpc/eeh: Set channel state after notifying the drivers")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/eeh_driver.c | 69 ++++++++++++++++----------------
+ 1 file changed, 35 insertions(+), 34 deletions(-)
+
+diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c
+index 3eff6a4888e79..cb3ac555c9446 100644
+--- a/arch/powerpc/kernel/eeh_driver.c
++++ b/arch/powerpc/kernel/eeh_driver.c
+@@ -1054,45 +1054,46 @@ void eeh_handle_normal_event(struct eeh_pe *pe)
+ }
+
+ pr_info("EEH: Recovery successful.\n");
+- } else {
+- /*
+- * About 90% of all real-life EEH failures in the field
+- * are due to poorly seated PCI cards. Only 10% or so are
+- * due to actual, failed cards.
+- */
+- pr_err("EEH: Unable to recover from failure from PHB#%x-PE#%x.\n"
+- "Please try reseating or replacing it\n",
+- pe->phb->global_number, pe->addr);
++ goto out;
++ }
+
+- eeh_slot_error_detail(pe, EEH_LOG_PERM);
++ /*
++ * About 90% of all real-life EEH failures in the field
++ * are due to poorly seated PCI cards. Only 10% or so are
++ * due to actual, failed cards.
++ */
++ pr_err("EEH: Unable to recover from failure from PHB#%x-PE#%x.\n"
++ "Please try reseating or replacing it\n",
++ pe->phb->global_number, pe->addr);
+
+- /* Notify all devices that they're about to go down. */
+- eeh_set_channel_state(pe, pci_channel_io_perm_failure);
+- eeh_set_irq_state(pe, false);
+- eeh_pe_report("error_detected(permanent failure)", pe,
+- eeh_report_failure, NULL);
++ eeh_slot_error_detail(pe, EEH_LOG_PERM);
+
+- /* Mark the PE to be removed permanently */
+- eeh_pe_state_mark(pe, EEH_PE_REMOVED);
++ /* Notify all devices that they're about to go down. */
++ eeh_set_channel_state(pe, pci_channel_io_perm_failure);
++ eeh_set_irq_state(pe, false);
++ eeh_pe_report("error_detected(permanent failure)", pe,
++ eeh_report_failure, NULL);
+
+- /*
+- * Shut down the device drivers for good. We mark
+- * all removed devices correctly to avoid access
+- * the their PCI config any more.
+- */
+- if (pe->type & EEH_PE_VF) {
+- eeh_pe_dev_traverse(pe, eeh_rmv_device, NULL);
+- eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED);
+- } else {
+- eeh_pe_state_clear(pe, EEH_PE_PRI_BUS, true);
+- eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED);
++ /* Mark the PE to be removed permanently */
++ eeh_pe_state_mark(pe, EEH_PE_REMOVED);
+
+- pci_lock_rescan_remove();
+- pci_hp_remove_devices(bus);
+- pci_unlock_rescan_remove();
+- /* The passed PE should no longer be used */
+- return;
+- }
++ /*
++ * Shut down the device drivers for good. We mark
++ * all removed devices correctly to avoid access
++ * the their PCI config any more.
++ */
++ if (pe->type & EEH_PE_VF) {
++ eeh_pe_dev_traverse(pe, eeh_rmv_device, NULL);
++ eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED);
++ } else {
++ eeh_pe_state_clear(pe, EEH_PE_PRI_BUS, true);
++ eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED);
++
++ pci_lock_rescan_remove();
++ pci_hp_remove_devices(bus);
++ pci_unlock_rescan_remove();
++ /* The passed PE should no longer be used */
++ return;
+ }
+
+ out:
+--
+2.39.2
+
--- /dev/null
+From a72f9c204014cb6ccab13652be468da836c1b8fe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Feb 2023 12:41:50 -0600
+Subject: powerpc/perf/hv-24x7: add missing RTAS retry status handling
+
+From: Nathan Lynch <nathanl@linux.ibm.com>
+
+[ Upstream commit cc4b26eab1859fa1a70711872caaf6414809973f ]
+
+The ibm,get-system-parameter RTAS function may return -2 or 990x,
+which indicate that the caller should try again. read_24x7_sys_info()
+ignores this, allowing transient failures in reporting processor
+module information.
+
+Move the RTAS call into a coventional rtas_busy_delay()-based loop,
+along with the parsing of results on success.
+
+Signed-off-by: Nathan Lynch <nathanl@linux.ibm.com>
+Fixes: 8ba214267382 ("powerpc/hv-24x7: Add rtas call in hv-24x7 driver to get processor details")
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20230125-b4-powerpc-rtas-queue-v3-2-26929c8cce78@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/perf/hv-24x7.c | 42 ++++++++++++++++---------------------
+ 1 file changed, 18 insertions(+), 24 deletions(-)
+
+diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c
+index 6e7e820508df7..1cd2351d241e8 100644
+--- a/arch/powerpc/perf/hv-24x7.c
++++ b/arch/powerpc/perf/hv-24x7.c
+@@ -79,9 +79,8 @@ static u32 phys_coresperchip; /* Physical cores per chip */
+ */
+ void read_24x7_sys_info(void)
+ {
+- int call_status, len, ntypes;
+-
+- spin_lock(&rtas_data_buf_lock);
++ const s32 token = rtas_token("ibm,get-system-parameter");
++ int call_status;
+
+ /*
+ * Making system parameter: chips and sockets and cores per chip
+@@ -91,32 +90,27 @@ void read_24x7_sys_info(void)
+ phys_chipspersocket = 1;
+ phys_coresperchip = 1;
+
+- call_status = rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1,
+- NULL,
+- PROCESSOR_MODULE_INFO,
+- __pa(rtas_data_buf),
+- RTAS_DATA_BUF_SIZE);
++ do {
++ spin_lock(&rtas_data_buf_lock);
++ call_status = rtas_call(token, 3, 1, NULL, PROCESSOR_MODULE_INFO,
++ __pa(rtas_data_buf), RTAS_DATA_BUF_SIZE);
++ if (call_status == 0) {
++ int ntypes = be16_to_cpup((__be16 *)&rtas_data_buf[2]);
++ int len = be16_to_cpup((__be16 *)&rtas_data_buf[0]);
++
++ if (len >= 8 && ntypes != 0) {
++ phys_sockets = be16_to_cpup((__be16 *)&rtas_data_buf[4]);
++ phys_chipspersocket = be16_to_cpup((__be16 *)&rtas_data_buf[6]);
++ phys_coresperchip = be16_to_cpup((__be16 *)&rtas_data_buf[8]);
++ }
++ }
++ spin_unlock(&rtas_data_buf_lock);
++ } while (rtas_busy_delay(call_status));
+
+ if (call_status != 0) {
+ pr_err("Error calling get-system-parameter %d\n",
+ call_status);
+- } else {
+- len = be16_to_cpup((__be16 *)&rtas_data_buf[0]);
+- if (len < 8)
+- goto out;
+-
+- ntypes = be16_to_cpup((__be16 *)&rtas_data_buf[2]);
+-
+- if (!ntypes)
+- goto out;
+-
+- phys_sockets = be16_to_cpup((__be16 *)&rtas_data_buf[4]);
+- phys_chipspersocket = be16_to_cpup((__be16 *)&rtas_data_buf[6]);
+- phys_coresperchip = be16_to_cpup((__be16 *)&rtas_data_buf[8]);
+ }
+-
+-out:
+- spin_unlock(&rtas_data_buf_lock);
+ }
+
+ /* Domains for which more than one result element are returned for each event. */
+--
+2.39.2
+
--- /dev/null
+From 65997cf6fdb0dafc662078420d684b50c747eb4c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Jan 2023 10:32:15 +0100
+Subject: powerpc/powernv/ioda: Skip unallocated resources when mapping to PE
+
+From: Frederic Barrat <fbarrat@linux.ibm.com>
+
+[ Upstream commit e64e71056f323a1e178dccf04d4c0f032d84436c ]
+
+pnv_ioda_setup_pe_res() calls opal to map a resource with a PE. However,
+the code assumes the resource is allocated and it uses the resource
+address to find out the segment(s) which need to be mapped to the
+PE. In the unlikely case where the resource hasn't been allocated, the
+computation for the segment number is garbage, which can lead to
+invalid memory access and potentially a kernel crash, such as:
+
+[ ] pci_bus 0002:02: Configuring PE for bus
+[ ] pci 0002:02 : [PE# fc] Secondary bus 0x0000000000000002..0x0000000000000002 associated with PE#fc
+[ ] BUG: Kernel NULL pointer dereference on write at 0x00000000
+[ ] Faulting instruction address: 0xc00000000005eac4
+[ ] Oops: Kernel access of bad area, sig: 7 [#1]
+[ ] LE PAGE_SIZE=64K MMU=Radix SMP NR_CPUS=2048 NUMA PowerNV
+[ ] Modules linked in:
+[ ] CPU: 12 PID: 1 Comm: swapper/20 Not tainted 5.10.50-openpower1 #2
+[ ] NIP: c00000000005eac4 LR: c00000000005ea44 CTR: 0000000030061b9c
+[ ] REGS: c000200007383650 TRAP: 0300 Not tainted (5.10.50-openpower1)
+[ ] MSR: 9000000000009033 <SF,HV,EE,ME,IR,DR,RI,LE> CR: 44000224 XER: 20040000
+[ ] CFAR: c00000000005eaa0 DAR: 0000000000000000 DSISR: 02080000 IRQMASK: 0
+[ ] GPR00: c00000000005dd98 c0002000073838e0 c00000000185de00 c000200fff018960
+[ ] GPR04: 00000000000000fc 0000000000000003 0000000000000000 0000000000000000
+[ ] GPR08: 0000000000000000 0000000000000000 0000000000000000 9000000000001033
+[ ] GPR12: 0000000031cb0000 c000000ffffe6a80 c000000000010a58 0000000000000000
+[ ] GPR16: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
+[ ] GPR20: 0000000000000000 0000000000000000 0000000000000000 c00000000711e200
+[ ] GPR24: 0000000000000100 c000200009501120 c00020000cee2800 00000000000003ff
+[ ] GPR28: c000200fff018960 0000000000000000 c000200ffcb7fd00 0000000000000000
+[ ] NIP [c00000000005eac4] pnv_ioda_setup_pe_res+0x94/0x1a0
+[ ] LR [c00000000005ea44] pnv_ioda_setup_pe_res+0x14/0x1a0
+[ ] Call Trace:
+[ ] [c0002000073838e0] [c00000000005eb98] pnv_ioda_setup_pe_res+0x168/0x1a0 (unreliable)
+[ ] [c000200007383970] [c00000000005dd98] pnv_pci_ioda_dma_dev_setup+0x43c/0x970
+[ ] [c000200007383a60] [c000000000032cdc] pcibios_bus_add_device+0x78/0x18c
+[ ] [c000200007383aa0] [c00000000028f2bc] pci_bus_add_device+0x28/0xbc
+[ ] [c000200007383b10] [c00000000028f3a0] pci_bus_add_devices+0x50/0x7c
+[ ] [c000200007383b50] [c00000000028f3c4] pci_bus_add_devices+0x74/0x7c
+[ ] [c000200007383b90] [c00000000028f3c4] pci_bus_add_devices+0x74/0x7c
+[ ] [c000200007383bd0] [c00000000069ad0c] pcibios_init+0xf0/0x104
+[ ] [c000200007383c50] [c0000000000106d8] do_one_initcall+0x84/0x1c4
+[ ] [c000200007383d20] [c0000000006910b8] kernel_init_freeable+0x264/0x268
+[ ] [c000200007383dc0] [c000000000010a68] kernel_init+0x18/0x138
+[ ] [c000200007383e20] [c00000000000cbfc] ret_from_kernel_thread+0x5c/0x80
+[ ] Instruction dump:
+[ ] 7f89e840 409d000c 7fbbf840 409c000c 38210090 4848f448 809c002c e95e0120
+[ ] 7ba91764 38a00003 57a7043e 38c00000 <7c8a492e> 5484043e e87e0018 4bff23bd
+
+Hitting the problem is not that easy. It was seen with a (semi-bogus)
+PCI device with a class code of 0. The generic PCI framework doesn't
+allocate resources in such a case.
+
+The patch is simply skipping resources which are still flagged with
+IORESOURCE_UNSET.
+
+We don't have the problem with 64-bit mem resources, as the address of
+the resource is checked to be within the range of the 64-bit mmio
+window. See pnv_ioda_reserve_dev_m64_pe() and pnv_pci_is_m64().
+
+Reported-by: Andrew Jeffery <andrew@aj.id.au>
+Fixes: 23e79425fe7c ("powerpc/powernv: Simplify pnv_ioda_setup_pe_seg()")
+Signed-off-by: Frederic Barrat <fbarrat@linux.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20230120093215.19496-1-fbarrat@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/platforms/powernv/pci-ioda.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
+index 2b4ceb5e6ce4c..a1e6dd47743f1 100644
+--- a/arch/powerpc/platforms/powernv/pci-ioda.c
++++ b/arch/powerpc/platforms/powernv/pci-ioda.c
+@@ -2260,7 +2260,8 @@ static void pnv_ioda_setup_pe_res(struct pnv_ioda_pe *pe,
+ int index;
+ int64_t rc;
+
+- if (!res || !res->flags || res->start > res->end)
++ if (!res || !res->flags || res->start > res->end ||
++ res->flags & IORESOURCE_UNSET)
+ return;
+
+ if (res->flags & IORESOURCE_IO) {
+--
+2.39.2
+
--- /dev/null
+From 4021ae05b49106f285e40e77858c1f056f3d09d1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Feb 2023 12:41:51 -0600
+Subject: powerpc/pseries/lpar: add missing RTAS retry status handling
+
+From: Nathan Lynch <nathanl@linux.ibm.com>
+
+[ Upstream commit daa8ab59044610aa8ef2ee45a6c157b5e11635e9 ]
+
+The ibm,get-system-parameter RTAS function may return -2 or 990x,
+which indicate that the caller should try again.
+
+pseries_lpar_read_hblkrm_characteristics() ignores this, making it
+possible to incorrectly detect TLB block invalidation characteristics
+at boot.
+
+Move the RTAS call into a coventional rtas_busy_delay()-based loop.
+
+Signed-off-by: Nathan Lynch <nathanl@linux.ibm.com>
+Fixes: 1211ee61b4a8 ("powerpc/pseries: Read TLB Block Invalidate Characteristics")
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20230125-b4-powerpc-rtas-queue-v3-3-26929c8cce78@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/platforms/pseries/lpar.c | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
+index 1c3ac0f663369..115d196560b8b 100644
+--- a/arch/powerpc/platforms/pseries/lpar.c
++++ b/arch/powerpc/platforms/pseries/lpar.c
+@@ -1433,22 +1433,22 @@ static inline void __init check_lp_set_hblkrm(unsigned int lp,
+
+ void __init pseries_lpar_read_hblkrm_characteristics(void)
+ {
++ const s32 token = rtas_token("ibm,get-system-parameter");
+ unsigned char local_buffer[SPLPAR_TLB_BIC_MAXLENGTH];
+ int call_status, len, idx, bpsize;
+
+ if (!firmware_has_feature(FW_FEATURE_BLOCK_REMOVE))
+ return;
+
+- spin_lock(&rtas_data_buf_lock);
+- memset(rtas_data_buf, 0, RTAS_DATA_BUF_SIZE);
+- call_status = rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1,
+- NULL,
+- SPLPAR_TLB_BIC_TOKEN,
+- __pa(rtas_data_buf),
+- RTAS_DATA_BUF_SIZE);
+- memcpy(local_buffer, rtas_data_buf, SPLPAR_TLB_BIC_MAXLENGTH);
+- local_buffer[SPLPAR_TLB_BIC_MAXLENGTH - 1] = '\0';
+- spin_unlock(&rtas_data_buf_lock);
++ do {
++ spin_lock(&rtas_data_buf_lock);
++ memset(rtas_data_buf, 0, RTAS_DATA_BUF_SIZE);
++ call_status = rtas_call(token, 3, 1, NULL, SPLPAR_TLB_BIC_TOKEN,
++ __pa(rtas_data_buf), RTAS_DATA_BUF_SIZE);
++ memcpy(local_buffer, rtas_data_buf, SPLPAR_TLB_BIC_MAXLENGTH);
++ local_buffer[SPLPAR_TLB_BIC_MAXLENGTH - 1] = '\0';
++ spin_unlock(&rtas_data_buf_lock);
++ } while (rtas_busy_delay(call_status));
+
+ if (call_status != 0) {
+ pr_warn("%s %s Error calling get-system-parameter (0x%x)\n",
+--
+2.39.2
+
--- /dev/null
+From 7cab60857ab706a64543713816238049fba1b2be Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Feb 2023 12:41:52 -0600
+Subject: powerpc/pseries/lparcfg: add missing RTAS retry status handling
+
+From: Nathan Lynch <nathanl@linux.ibm.com>
+
+[ Upstream commit 5d08633e5f6564b60f1cbe09af3af40a74d66431 ]
+
+The ibm,get-system-parameter RTAS function may return -2 or 990x,
+which indicate that the caller should try again.
+
+lparcfg's parse_system_parameter_string() ignores this, making it
+possible to intermittently report incorrect SPLPAR characteristics.
+
+Move the RTAS call into a coventional rtas_busy_delay()-based loop.
+
+Signed-off-by: Nathan Lynch <nathanl@linux.ibm.com>
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20230125-b4-powerpc-rtas-queue-v3-4-26929c8cce78@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/platforms/pseries/lparcfg.c | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/arch/powerpc/platforms/pseries/lparcfg.c b/arch/powerpc/platforms/pseries/lparcfg.c
+index e278390ab28d1..d3517e498512f 100644
+--- a/arch/powerpc/platforms/pseries/lparcfg.c
++++ b/arch/powerpc/platforms/pseries/lparcfg.c
+@@ -322,6 +322,7 @@ static void parse_mpp_x_data(struct seq_file *m)
+ */
+ static void parse_system_parameter_string(struct seq_file *m)
+ {
++ const s32 token = rtas_token("ibm,get-system-parameter");
+ int call_status;
+
+ unsigned char *local_buffer = kmalloc(SPLPAR_MAXLENGTH, GFP_KERNEL);
+@@ -331,16 +332,15 @@ static void parse_system_parameter_string(struct seq_file *m)
+ return;
+ }
+
+- spin_lock(&rtas_data_buf_lock);
+- memset(rtas_data_buf, 0, SPLPAR_MAXLENGTH);
+- call_status = rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1,
+- NULL,
+- SPLPAR_CHARACTERISTICS_TOKEN,
+- __pa(rtas_data_buf),
+- RTAS_DATA_BUF_SIZE);
+- memcpy(local_buffer, rtas_data_buf, SPLPAR_MAXLENGTH);
+- local_buffer[SPLPAR_MAXLENGTH - 1] = '\0';
+- spin_unlock(&rtas_data_buf_lock);
++ do {
++ spin_lock(&rtas_data_buf_lock);
++ memset(rtas_data_buf, 0, SPLPAR_MAXLENGTH);
++ call_status = rtas_call(token, 3, 1, NULL, SPLPAR_CHARACTERISTICS_TOKEN,
++ __pa(rtas_data_buf), RTAS_DATA_BUF_SIZE);
++ memcpy(local_buffer, rtas_data_buf, SPLPAR_MAXLENGTH);
++ local_buffer[SPLPAR_MAXLENGTH - 1] = '\0';
++ spin_unlock(&rtas_data_buf_lock);
++ } while (rtas_busy_delay(call_status));
+
+ if (call_status != 0) {
+ printk(KERN_INFO
+--
+2.39.2
+
--- /dev/null
+From 506913adc111174f2bf3ab16a48daa7a7586550d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Jan 2023 20:05:02 -0700
+Subject: powerpc: Remove linker flag from KBUILD_AFLAGS
+
+From: Nathan Chancellor <nathan@kernel.org>
+
+[ Upstream commit 31f48f16264bc70962fb3e7ec62da64d0a2ba04a ]
+
+When clang's -Qunused-arguments is dropped from KBUILD_CPPFLAGS, it
+points out that KBUILD_AFLAGS contains a linker flag, which will be
+unused:
+
+ clang: error: -Wl,-a32: 'linker' input unused [-Werror,-Wunused-command-line-argument]
+
+This was likely supposed to be '-Wa,-a$(BITS)'. However, this change is
+unnecessary, as all supported versions of clang and gcc will pass '-a64'
+or '-a32' to GNU as based on the value of '-m'; the behavior of the
+latest stable release of the oldest supported major version of each
+compiler is shown below and each compiler's latest release exhibits the
+same behavior (GCC 12.2.0 and Clang 15.0.6).
+
+ $ powerpc64-linux-gcc --version | head -1
+ powerpc64-linux-gcc (GCC) 5.5.0
+
+ $ powerpc64-linux-gcc -m64 -### -x assembler-with-cpp -c -o /dev/null /dev/null &| grep 'as '
+ .../as -a64 -mppc64 -many -mbig -o /dev/null /tmp/cctwuBzZ.s
+
+ $ powerpc64-linux-gcc -m32 -### -x assembler-with-cpp -c -o /dev/null /dev/null &| grep 'as '
+ .../as -a32 -mppc -many -mbig -o /dev/null /tmp/ccaZP4mF.sg
+
+ $ clang --version | head -1
+ Ubuntu clang version 11.1.0-++20211011094159+1fdec59bffc1-1~exp1~20211011214622.5
+
+ $ clang --target=powerpc64-linux-gnu -fno-integrated-as -m64 -### \
+ -x assembler-with-cpp -c -o /dev/null /dev/null &| grep gnu-as
+ "/usr/bin/powerpc64-linux-gnu-as" "-a64" "-mppc64" "-many" "-o" "/dev/null" "/tmp/null-80267c.s"
+
+ $ clang --target=powerpc64-linux-gnu -fno-integrated-as -m64 -### \
+ -x assembler-with-cpp -c -o /dev/null /dev/null &| grep gnu-as
+ "/usr/bin/powerpc64-linux-gnu-as" "-a32" "-mppc" "-many" "-o" "/dev/null" "/tmp/null-ab8f8d.s"
+
+Remove this flag altogether to avoid future issues.
+
+Fixes: 1421dc6d4829 ("powerpc/kbuild: Use flags variables rather than overriding LD/CC/AS")
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
+Tested-by: Linux Kernel Functional Testing <lkft@linaro.org>
+Tested-by: Anders Roxell <anders.roxell@linaro.org>
+Acked-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
+index 6122541412961..a3f66ade09b32 100644
+--- a/arch/powerpc/Makefile
++++ b/arch/powerpc/Makefile
+@@ -92,7 +92,7 @@ aflags-$(CONFIG_CPU_LITTLE_ENDIAN) += -mlittle-endian
+
+ ifeq ($(HAS_BIARCH),y)
+ KBUILD_CFLAGS += -m$(BITS)
+-KBUILD_AFLAGS += -m$(BITS) -Wl,-a$(BITS)
++KBUILD_AFLAGS += -m$(BITS)
+ KBUILD_LDFLAGS += -m elf$(BITS)$(LDEMULATION)
+ endif
+
+--
+2.39.2
+
--- /dev/null
+From e42632a60ea04f9c65ac66f1e3dbb25786add1cd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Feb 2023 12:41:54 -0600
+Subject: powerpc/rtas: ensure 4KB alignment for rtas_data_buf
+
+From: Nathan Lynch <nathanl@linux.ibm.com>
+
+[ Upstream commit 836b5b9fcc8e09cea7e8a59a070349a00e818308 ]
+
+Some RTAS functions that have work area parameters impose alignment
+requirements on the work area passed to them by the OS. Examples
+include:
+
+- ibm,configure-connector
+- ibm,update-nodes
+- ibm,update-properties
+
+4KB is the greatest alignment required by PAPR for such
+buffers. rtas_data_buf used to have a __page_aligned attribute in the
+arch/ppc64 days, but that was changed to __cacheline_aligned for
+unknown reasons by commit 033ef338b6e0 ("powerpc: Merge rtas.c into
+arch/powerpc/kernel"). That works out to 128-byte alignment
+on ppc64, which isn't right.
+
+This was found by inspection and I'm not aware of any real problems
+caused by this. Either current RTAS implementations don't enforce the
+alignment constraints, or rtas_data_buf is always being placed at a
+4KB boundary by accident (or both, perhaps).
+
+Use __aligned(SZ_4K) to ensure the rtas_data_buf has alignment
+appropriate for all users.
+
+Signed-off-by: Nathan Lynch <nathanl@linux.ibm.com>
+Fixes: 033ef338b6e0 ("powerpc: Merge rtas.c into arch/powerpc/kernel")
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20230125-b4-powerpc-rtas-queue-v3-6-26929c8cce78@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/rtas.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
+index 7d0bcc515a058..c2e407a112a28 100644
+--- a/arch/powerpc/kernel/rtas.c
++++ b/arch/powerpc/kernel/rtas.c
+@@ -54,7 +54,7 @@ EXPORT_SYMBOL(rtas);
+ DEFINE_SPINLOCK(rtas_data_buf_lock);
+ EXPORT_SYMBOL_GPL(rtas_data_buf_lock);
+
+-char rtas_data_buf[RTAS_DATA_BUF_SIZE] __cacheline_aligned;
++char rtas_data_buf[RTAS_DATA_BUF_SIZE] __aligned(SZ_4K);
+ EXPORT_SYMBOL_GPL(rtas_data_buf);
+
+ unsigned long rtas_rmo_buf;
+--
+2.39.2
+
--- /dev/null
+From 78165227cef47f899c63618efa9a7705433c3e63 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Jan 2023 08:04:46 -0600
+Subject: powerpc/rtas: make all exports GPL
+
+From: Nathan Lynch <nathanl@linux.ibm.com>
+
+[ Upstream commit 9bce6243848dfd0ff7c2be6e8d82ab9b1e6c7858 ]
+
+The first symbol exports of RTAS functions and data came with the (now
+removed) scanlog driver in 2003:
+
+https://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git/commit/?id=f92e361842d5251e50562b09664082dcbd0548bb
+
+At the time this was applied, EXPORT_SYMBOL_GPL() was very new, and
+the exports of rtas_call() etc have remained non-GPL. As new APIs have
+been added to the RTAS subsystem, their symbol exports have followed
+the convention set by existing code.
+
+However, the historical evidence is that RTAS function exports have been
+added over time only to satisfy the needs of in-kernel users, and these
+clients must have fairly intimate knowledge of how the APIs work to use
+them safely. No out of tree users are known, and future ones seem
+unlikely.
+
+Arguably the default for RTAS symbols should have become
+EXPORT_SYMBOL_GPL once it was available. Let's make it so now, and
+exceptions can be evaluated as needed.
+
+Signed-off-by: Nathan Lynch <nathanl@linux.ibm.com>
+Reviewed-by: Laurent Dufour <laurent.dufour@fr.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20230124140448.45938-3-nathanl@linux.ibm.com
+Stable-dep-of: 836b5b9fcc8e ("powerpc/rtas: ensure 4KB alignment for rtas_data_buf")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/rtas.c | 22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
+index 014229c40435a..7d0bcc515a058 100644
+--- a/arch/powerpc/kernel/rtas.c
++++ b/arch/powerpc/kernel/rtas.c
+@@ -52,10 +52,10 @@ struct rtas_t rtas = {
+ EXPORT_SYMBOL(rtas);
+
+ DEFINE_SPINLOCK(rtas_data_buf_lock);
+-EXPORT_SYMBOL(rtas_data_buf_lock);
++EXPORT_SYMBOL_GPL(rtas_data_buf_lock);
+
+ char rtas_data_buf[RTAS_DATA_BUF_SIZE] __cacheline_aligned;
+-EXPORT_SYMBOL(rtas_data_buf);
++EXPORT_SYMBOL_GPL(rtas_data_buf);
+
+ unsigned long rtas_rmo_buf;
+
+@@ -64,7 +64,7 @@ unsigned long rtas_rmo_buf;
+ * This is done like this so rtas_flash can be a module.
+ */
+ void (*rtas_flash_term_hook)(int);
+-EXPORT_SYMBOL(rtas_flash_term_hook);
++EXPORT_SYMBOL_GPL(rtas_flash_term_hook);
+
+ /* RTAS use home made raw locking instead of spin_lock_irqsave
+ * because those can be called from within really nasty contexts
+@@ -312,7 +312,7 @@ void rtas_progress(char *s, unsigned short hex)
+
+ spin_unlock(&progress_lock);
+ }
+-EXPORT_SYMBOL(rtas_progress); /* needed by rtas_flash module */
++EXPORT_SYMBOL_GPL(rtas_progress); /* needed by rtas_flash module */
+
+ int rtas_token(const char *service)
+ {
+@@ -322,7 +322,7 @@ int rtas_token(const char *service)
+ tokp = of_get_property(rtas.dev, service, NULL);
+ return tokp ? be32_to_cpu(*tokp) : RTAS_UNKNOWN_SERVICE;
+ }
+-EXPORT_SYMBOL(rtas_token);
++EXPORT_SYMBOL_GPL(rtas_token);
+
+ int rtas_service_present(const char *service)
+ {
+@@ -482,7 +482,7 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...)
+ }
+ return ret;
+ }
+-EXPORT_SYMBOL(rtas_call);
++EXPORT_SYMBOL_GPL(rtas_call);
+
+ /* For RTAS_BUSY (-2), delay for 1 millisecond. For an extended busy status
+ * code of 990n, perform the hinted delay of 10^n (last digit) milliseconds.
+@@ -517,7 +517,7 @@ unsigned int rtas_busy_delay(int status)
+
+ return ms;
+ }
+-EXPORT_SYMBOL(rtas_busy_delay);
++EXPORT_SYMBOL_GPL(rtas_busy_delay);
+
+ static int rtas_error_rc(int rtas_rc)
+ {
+@@ -563,7 +563,7 @@ int rtas_get_power_level(int powerdomain, int *level)
+ return rtas_error_rc(rc);
+ return rc;
+ }
+-EXPORT_SYMBOL(rtas_get_power_level);
++EXPORT_SYMBOL_GPL(rtas_get_power_level);
+
+ int rtas_set_power_level(int powerdomain, int level, int *setlevel)
+ {
+@@ -581,7 +581,7 @@ int rtas_set_power_level(int powerdomain, int level, int *setlevel)
+ return rtas_error_rc(rc);
+ return rc;
+ }
+-EXPORT_SYMBOL(rtas_set_power_level);
++EXPORT_SYMBOL_GPL(rtas_set_power_level);
+
+ int rtas_get_sensor(int sensor, int index, int *state)
+ {
+@@ -599,7 +599,7 @@ int rtas_get_sensor(int sensor, int index, int *state)
+ return rtas_error_rc(rc);
+ return rc;
+ }
+-EXPORT_SYMBOL(rtas_get_sensor);
++EXPORT_SYMBOL_GPL(rtas_get_sensor);
+
+ int rtas_get_sensor_fast(int sensor, int index, int *state)
+ {
+@@ -660,7 +660,7 @@ int rtas_set_indicator(int indicator, int index, int new_value)
+ return rtas_error_rc(rc);
+ return rc;
+ }
+-EXPORT_SYMBOL(rtas_set_indicator);
++EXPORT_SYMBOL_GPL(rtas_set_indicator);
+
+ /*
+ * Ignoring RTAS extended delay
+--
+2.39.2
+
--- /dev/null
+From c4bb5d3b9c5b2dc16841407e18fc47ae01687b0f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Feb 2023 20:40:57 +0100
+Subject: printf: fix errname.c list
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 0c2baf6509af1d11310ae4c1c839481a6e9a4bc4 ]
+
+On most architectures, gcc -Wextra warns about the list of error
+numbers containing both EDEADLK and EDEADLOCK:
+
+lib/errname.c:15:67: warning: initialized field overwritten [-Woverride-init]
+ 15 | #define E(err) [err + BUILD_BUG_ON_ZERO(err <= 0 || err > 300)] = "-" #err
+ | ^~~
+lib/errname.c:172:2: note: in expansion of macro 'E'
+ 172 | E(EDEADLK), /* EDEADLOCK */
+ | ^
+
+On parisc, a similar error happens with -ECANCELLED, which is an
+alias for ECANCELED.
+
+Make the EDEADLK printing conditional on the number being distinct
+from EDEADLOCK, and remove the -ECANCELLED bit completely as it
+can never be hit.
+
+To ensure these are correct, add static_assert lines that verify
+all the remaining aliases are in fact identical to the canonical
+name.
+
+Fixes: 57f5677e535b ("printf: add support for printing symbolic error names")
+Cc: Petr Mladek <pmladek@suse.com>
+Suggested-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
+Acked-by: Uwe Kleine-König <uwe@kleine-koenig.org>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/all/20210514213456.745039-1-arnd@kernel.org/
+Link: https://lore.kernel.org/all/20210927123409.1109737-1-arnd@kernel.org/
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Sergey Senozhatsky <senozhatsky@chromium.org>
+Acked-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
+Reviewed-by: Petr Mladek <pmladek@suse.com>
+Signed-off-by: Petr Mladek <pmladek@suse.com>
+Link: https://lore.kernel.org/r/20230206194126.380350-1-arnd@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/errname.c | 22 ++++++++++++++--------
+ 1 file changed, 14 insertions(+), 8 deletions(-)
+
+diff --git a/lib/errname.c b/lib/errname.c
+index 0c4d3e66170e9..a5799a8c9cab9 100644
+--- a/lib/errname.c
++++ b/lib/errname.c
+@@ -20,6 +20,7 @@ static const char *names_0[] = {
+ E(EADDRNOTAVAIL),
+ E(EADV),
+ E(EAFNOSUPPORT),
++ E(EAGAIN), /* EWOULDBLOCK */
+ E(EALREADY),
+ E(EBADE),
+ E(EBADF),
+@@ -30,15 +31,17 @@ static const char *names_0[] = {
+ E(EBADSLT),
+ E(EBFONT),
+ E(EBUSY),
+-#ifdef ECANCELLED
+- E(ECANCELLED),
+-#endif
++ E(ECANCELED), /* ECANCELLED */
+ E(ECHILD),
+ E(ECHRNG),
+ E(ECOMM),
+ E(ECONNABORTED),
++ E(ECONNREFUSED), /* EREFUSED */
+ E(ECONNRESET),
++ E(EDEADLK), /* EDEADLOCK */
++#if EDEADLK != EDEADLOCK /* mips, sparc, powerpc */
+ E(EDEADLOCK),
++#endif
+ E(EDESTADDRREQ),
+ E(EDOM),
+ E(EDOTDOT),
+@@ -165,14 +168,17 @@ static const char *names_0[] = {
+ E(EUSERS),
+ E(EXDEV),
+ E(EXFULL),
+-
+- E(ECANCELED), /* ECANCELLED */
+- E(EAGAIN), /* EWOULDBLOCK */
+- E(ECONNREFUSED), /* EREFUSED */
+- E(EDEADLK), /* EDEADLOCK */
+ };
+ #undef E
+
++#ifdef EREFUSED /* parisc */
++static_assert(EREFUSED == ECONNREFUSED);
++#endif
++#ifdef ECANCELLED /* parisc */
++static_assert(ECANCELLED == ECANCELED);
++#endif
++static_assert(EAGAIN == EWOULDBLOCK); /* everywhere */
++
+ #define E(err) [err - 512 + BUILD_BUG_ON_ZERO(err < 512 || err > 550)] = "-" #err
+ static const char *names_512[] = {
+ E(ERESTARTSYS),
+--
+2.39.2
+
--- /dev/null
+From 05f0ec39fcfbbff84d5adf498c64de45da8c680b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Dec 2022 11:41:44 -0800
+Subject: rcu: Make RCU_LOCKDEP_WARN() avoid early lockdep checks
+
+From: Paul E. McKenney <paulmck@kernel.org>
+
+[ Upstream commit 0cae5ded535c3a80aed94f119bbd4ee3ae284a65 ]
+
+Currently, RCU_LOCKDEP_WARN() checks the condition before checking
+to see if lockdep is still enabled. This is necessary to avoid the
+false-positive splats fixed by commit 3066820034b5dd ("rcu: Reject
+RCU_LOCKDEP_WARN() false positives"). However, the current state can
+result in false-positive splats during early boot before lockdep is fully
+initialized. This commit therefore checks debug_lockdep_rcu_enabled()
+both before and after checking the condition, thus avoiding both sets
+of false-positive error reports.
+
+Reported-by: Steven Rostedt <rostedt@goodmis.org>
+Reported-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Reported-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Reviewed-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Boqun Feng <boqun.feng@gmail.com>
+Cc: Matthew Wilcox <willy@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/rcupdate.h | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
+index 1f46db38d6ec6..ef8d56b18da6b 100644
+--- a/include/linux/rcupdate.h
++++ b/include/linux/rcupdate.h
+@@ -308,11 +308,18 @@ static inline int rcu_read_lock_any_held(void)
+ * RCU_LOCKDEP_WARN - emit lockdep splat if specified condition is met
+ * @c: condition to check
+ * @s: informative message
++ *
++ * This checks debug_lockdep_rcu_enabled() before checking (c) to
++ * prevent early boot splats due to lockdep not yet being initialized,
++ * and rechecks it after checking (c) to prevent false-positive splats
++ * due to races with lockdep being disabled. See commit 3066820034b5dd
++ * ("rcu: Reject RCU_LOCKDEP_WARN() false positives") for more detail.
+ */
+ #define RCU_LOCKDEP_WARN(c, s) \
+ do { \
+ static bool __section(".data.unlikely") __warned; \
+- if ((c) && debug_lockdep_rcu_enabled() && !__warned) { \
++ if (debug_lockdep_rcu_enabled() && (c) && \
++ debug_lockdep_rcu_enabled() && !__warned) { \
+ __warned = true; \
+ lockdep_rcu_suspicious(__FILE__, __LINE__, s); \
+ } \
+--
+2.39.2
+
--- /dev/null
+From 901c34f6c0ec75c4e9c03f5cf31042313b69dd42 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Dec 2022 15:55:48 -0800
+Subject: rcu: Suppress smp_processor_id() complaint in
+ synchronize_rcu_expedited_wait()
+
+From: Paul E. McKenney <paulmck@kernel.org>
+
+[ Upstream commit 2d7f00b2f01301d6e41fd4a28030dab0442265be ]
+
+The normal grace period's RCU CPU stall warnings are invoked from the
+scheduling-clock interrupt handler, and can thus invoke smp_processor_id()
+with impunity, which allows them to directly invoke dump_cpu_task().
+In contrast, the expedited grace period's RCU CPU stall warnings are
+invoked from process context, which causes the dump_cpu_task() function's
+calls to smp_processor_id() to complain bitterly in debug kernels.
+
+This commit therefore causes synchronize_rcu_expedited_wait() to disable
+preemption around its call to dump_cpu_task().
+
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/rcu/tree_exp.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/kernel/rcu/tree_exp.h b/kernel/rcu/tree_exp.h
+index 0dc16345e668c..ef6570137dcd5 100644
+--- a/kernel/rcu/tree_exp.h
++++ b/kernel/rcu/tree_exp.h
+@@ -564,7 +564,9 @@ static void synchronize_rcu_expedited_wait(void)
+ mask = leaf_node_cpu_bit(rnp, cpu);
+ if (!(READ_ONCE(rnp->expmask) & mask))
+ continue;
++ preempt_disable(); // For smp_processor_id() in dump_cpu_task().
+ dump_cpu_task(cpu);
++ preempt_enable();
+ }
+ }
+ jiffies_stall = 3 * rcu_jiffies_till_stall_check() + 3;
+--
+2.39.2
+
--- /dev/null
+From 1a60c7a7f889b79bcb0001e5267828e96aaa3bea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Nov 2022 14:55:00 +0100
+Subject: rcu-tasks: Fix synchronize_rcu_tasks() VS zap_pid_ns_processes()
+
+From: Frederic Weisbecker <frederic@kernel.org>
+
+[ Upstream commit 28319d6dc5e2ffefa452c2377dd0f71621b5bff0 ]
+
+RCU Tasks and PID-namespace unshare can interact in do_exit() in a
+complicated circular dependency:
+
+1) TASK A calls unshare(CLONE_NEWPID), this creates a new PID namespace
+ that every subsequent child of TASK A will belong to. But TASK A
+ doesn't itself belong to that new PID namespace.
+
+2) TASK A forks() and creates TASK B. TASK A stays attached to its PID
+ namespace (let's say PID_NS1) and TASK B is the first task belonging
+ to the new PID namespace created by unshare() (let's call it PID_NS2).
+
+3) Since TASK B is the first task attached to PID_NS2, it becomes the
+ PID_NS2 child reaper.
+
+4) TASK A forks() again and creates TASK C which get attached to PID_NS2.
+ Note how TASK C has TASK A as a parent (belonging to PID_NS1) but has
+ TASK B (belonging to PID_NS2) as a pid_namespace child_reaper.
+
+5) TASK B exits and since it is the child reaper for PID_NS2, it has to
+ kill all other tasks attached to PID_NS2, and wait for all of them to
+ die before getting reaped itself (zap_pid_ns_process()).
+
+6) TASK A calls synchronize_rcu_tasks() which leads to
+ synchronize_srcu(&tasks_rcu_exit_srcu).
+
+7) TASK B is waiting for TASK C to get reaped. But TASK B is under a
+ tasks_rcu_exit_srcu SRCU critical section (exit_notify() is between
+ exit_tasks_rcu_start() and exit_tasks_rcu_finish()), blocking TASK A.
+
+8) TASK C exits and since TASK A is its parent, it waits for it to reap
+ TASK C, but it can't because TASK A waits for TASK B that waits for
+ TASK C.
+
+Pid_namespace semantics can hardly be changed at this point. But the
+coverage of tasks_rcu_exit_srcu can be reduced instead.
+
+The current task is assumed not to be concurrently reapable at this
+stage of exit_notify() and therefore tasks_rcu_exit_srcu can be
+temporarily relaxed without breaking its constraints, providing a way
+out of the deadlock scenario.
+
+[ paulmck: Fix build failure by adding additional declaration. ]
+
+Fixes: 3f95aa81d265 ("rcu: Make TASKS_RCU handle tasks that are almost done exiting")
+Reported-by: Pengfei Xu <pengfei.xu@intel.com>
+Suggested-by: Boqun Feng <boqun.feng@gmail.com>
+Suggested-by: Neeraj Upadhyay <quic_neeraju@quicinc.com>
+Suggested-by: Paul E. McKenney <paulmck@kernel.org>
+Cc: Oleg Nesterov <oleg@redhat.com>
+Cc: Lai Jiangshan <jiangshanlai@gmail.com>
+Cc: Eric W . Biederman <ebiederm@xmission.com>
+Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/rcupdate.h | 2 ++
+ kernel/pid_namespace.c | 17 +++++++++++++++++
+ kernel/rcu/tasks.h | 15 +++++++++++++--
+ 3 files changed, 32 insertions(+), 2 deletions(-)
+
+diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
+index 095b3b39bd032..1f46db38d6ec6 100644
+--- a/include/linux/rcupdate.h
++++ b/include/linux/rcupdate.h
+@@ -189,6 +189,7 @@ void synchronize_rcu_tasks_rude(void);
+
+ #define rcu_note_voluntary_context_switch(t) rcu_tasks_qs(t, false)
+ void exit_tasks_rcu_start(void);
++void exit_tasks_rcu_stop(void);
+ void exit_tasks_rcu_finish(void);
+ #else /* #ifdef CONFIG_TASKS_RCU_GENERIC */
+ #define rcu_tasks_qs(t, preempt) do { } while (0)
+@@ -196,6 +197,7 @@ void exit_tasks_rcu_finish(void);
+ #define call_rcu_tasks call_rcu
+ #define synchronize_rcu_tasks synchronize_rcu
+ static inline void exit_tasks_rcu_start(void) { }
++static inline void exit_tasks_rcu_stop(void) { }
+ static inline void exit_tasks_rcu_finish(void) { }
+ #endif /* #else #ifdef CONFIG_TASKS_RCU_GENERIC */
+
+diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c
+index ef8733e2a476e..20243682e6056 100644
+--- a/kernel/pid_namespace.c
++++ b/kernel/pid_namespace.c
+@@ -251,7 +251,24 @@ void zap_pid_ns_processes(struct pid_namespace *pid_ns)
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (pid_ns->pid_allocated == init_pids)
+ break;
++ /*
++ * Release tasks_rcu_exit_srcu to avoid following deadlock:
++ *
++ * 1) TASK A unshare(CLONE_NEWPID)
++ * 2) TASK A fork() twice -> TASK B (child reaper for new ns)
++ * and TASK C
++ * 3) TASK B exits, kills TASK C, waits for TASK A to reap it
++ * 4) TASK A calls synchronize_rcu_tasks()
++ * -> synchronize_srcu(tasks_rcu_exit_srcu)
++ * 5) *DEADLOCK*
++ *
++ * It is considered safe to release tasks_rcu_exit_srcu here
++ * because we assume the current task can not be concurrently
++ * reaped at this point.
++ */
++ exit_tasks_rcu_stop();
+ schedule();
++ exit_tasks_rcu_start();
+ }
+ __set_current_state(TASK_RUNNING);
+
+diff --git a/kernel/rcu/tasks.h b/kernel/rcu/tasks.h
+index c4af3c05663f4..df8143c8a6a8e 100644
+--- a/kernel/rcu/tasks.h
++++ b/kernel/rcu/tasks.h
+@@ -604,17 +604,28 @@ void exit_tasks_rcu_start(void) __acquires(&tasks_rcu_exit_srcu)
+ * task is exiting and may be removed from the tasklist. See
+ * corresponding synchronize_srcu() for further details.
+ */
+-void exit_tasks_rcu_finish(void) __releases(&tasks_rcu_exit_srcu)
++void exit_tasks_rcu_stop(void) __releases(&tasks_rcu_exit_srcu)
+ {
+ struct task_struct *t = current;
+
+ __srcu_read_unlock(&tasks_rcu_exit_srcu, t->rcu_tasks_idx);
+- exit_tasks_rcu_finish_trace(t);
++}
++
++/*
++ * Contribute to protect against tasklist scan blind spot while the
++ * task is exiting and may be removed from the tasklist. See
++ * corresponding synchronize_srcu() for further details.
++ */
++void exit_tasks_rcu_finish(void)
++{
++ exit_tasks_rcu_stop();
++ exit_tasks_rcu_finish_trace(current);
+ }
+
+ #else /* #ifdef CONFIG_TASKS_RCU */
+ static inline void show_rcu_tasks_classic_gp_kthread(void) { }
+ void exit_tasks_rcu_start(void) { }
++void exit_tasks_rcu_stop(void) { }
+ void exit_tasks_rcu_finish(void) { exit_tasks_rcu_finish_trace(current); }
+ #endif /* #else #ifdef CONFIG_TASKS_RCU */
+
+--
+2.39.2
+
--- /dev/null
+From 6418ba553fc55739c9e9f8f744f9ab30d8a2c781 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Nov 2022 14:54:58 +0100
+Subject: rcu-tasks: Improve comments explaining tasks_rcu_exit_srcu purpose
+
+From: Frederic Weisbecker <frederic@kernel.org>
+
+[ Upstream commit e4e1e8089c5fd948da12cb9f4adc93821036945f ]
+
+Make sure we don't need to look again into the depths of git blame in
+order not to miss a subtle part about how rcu-tasks is dealing with
+exiting tasks.
+
+Suggested-by: Boqun Feng <boqun.feng@gmail.com>
+Suggested-by: Neeraj Upadhyay <quic_neeraju@quicinc.com>
+Suggested-by: Paul E. McKenney <paulmck@kernel.org>
+Cc: Oleg Nesterov <oleg@redhat.com>
+Cc: Lai Jiangshan <jiangshanlai@gmail.com>
+Cc: Eric W. Biederman <ebiederm@xmission.com>
+Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Stable-dep-of: 28319d6dc5e2 ("rcu-tasks: Fix synchronize_rcu_tasks() VS zap_pid_ns_processes()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/rcu/tasks.h | 37 +++++++++++++++++++++++++++++--------
+ 1 file changed, 29 insertions(+), 8 deletions(-)
+
+diff --git a/kernel/rcu/tasks.h b/kernel/rcu/tasks.h
+index 8b51e6a5b3869..372644126b0de 100644
+--- a/kernel/rcu/tasks.h
++++ b/kernel/rcu/tasks.h
+@@ -416,11 +416,21 @@ static void rcu_tasks_pertask(struct task_struct *t, struct list_head *hop)
+ static void rcu_tasks_postscan(struct list_head *hop)
+ {
+ /*
+- * Wait for tasks that are in the process of exiting. This
+- * does only part of the job, ensuring that all tasks that were
+- * previously exiting reach the point where they have disabled
+- * preemption, allowing the later synchronize_rcu() to finish
+- * the job.
++ * Exiting tasks may escape the tasklist scan. Those are vulnerable
++ * until their final schedule() with TASK_DEAD state. To cope with
++ * this, divide the fragile exit path part in two intersecting
++ * read side critical sections:
++ *
++ * 1) An _SRCU_ read side starting before calling exit_notify(),
++ * which may remove the task from the tasklist, and ending after
++ * the final preempt_disable() call in do_exit().
++ *
++ * 2) An _RCU_ read side starting with the final preempt_disable()
++ * call in do_exit() and ending with the final call to schedule()
++ * with TASK_DEAD state.
++ *
++ * This handles the part 1). And postgp will handle part 2) with a
++ * call to synchronize_rcu().
+ */
+ synchronize_srcu(&tasks_rcu_exit_srcu);
+ }
+@@ -487,7 +497,10 @@ static void rcu_tasks_postgp(struct rcu_tasks *rtp)
+ *
+ * In addition, this synchronize_rcu() waits for exiting tasks
+ * to complete their final preempt_disable() region of execution,
+- * cleaning up after the synchronize_srcu() above.
++ * cleaning up after synchronize_srcu(&tasks_rcu_exit_srcu),
++ * enforcing the whole region before tasklist removal until
++ * the final schedule() with TASK_DEAD state to be an RCU TASKS
++ * read side critical section.
+ */
+ synchronize_rcu();
+ }
+@@ -576,7 +589,11 @@ static void show_rcu_tasks_classic_gp_kthread(void)
+ }
+ #endif /* #ifndef CONFIG_TINY_RCU */
+
+-/* Do the srcu_read_lock() for the above synchronize_srcu(). */
++/*
++ * Contribute to protect against tasklist scan blind spot while the
++ * task is exiting and may be removed from the tasklist. See
++ * corresponding synchronize_srcu() for further details.
++ */
+ void exit_tasks_rcu_start(void) __acquires(&tasks_rcu_exit_srcu)
+ {
+ preempt_disable();
+@@ -584,7 +601,11 @@ void exit_tasks_rcu_start(void) __acquires(&tasks_rcu_exit_srcu)
+ preempt_enable();
+ }
+
+-/* Do the srcu_read_unlock() for the above synchronize_srcu(). */
++/*
++ * Contribute to protect against tasklist scan blind spot while the
++ * task is exiting and may be removed from the tasklist. See
++ * corresponding synchronize_srcu() for further details.
++ */
+ void exit_tasks_rcu_finish(void) __releases(&tasks_rcu_exit_srcu)
+ {
+ struct task_struct *t = current;
+--
+2.39.2
+
--- /dev/null
+From 9c9be8e4a143b45ee1427ab826f277472c49d965 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Dec 2022 07:45:33 +0800
+Subject: rcu-tasks: Make rude RCU-Tasks work well with CPU hotplug
+
+From: Zqiang <qiang1.zhang@intel.com>
+
+[ Upstream commit ea5c8987fef20a8cca07e428aa28bc64649c5104 ]
+
+The synchronize_rcu_tasks_rude() function invokes rcu_tasks_rude_wait_gp()
+to wait one rude RCU-tasks grace period. The rcu_tasks_rude_wait_gp()
+function in turn checks if there is only a single online CPU. If so, it
+will immediately return, because a call to synchronize_rcu_tasks_rude()
+is by definition a grace period on a single-CPU system. (We could
+have blocked!)
+
+Unfortunately, this check uses num_online_cpus() without synchronization,
+which can result in too-short grace periods. To see this, consider the
+following scenario:
+
+ CPU0 CPU1 (going offline)
+ migration/1 task:
+ cpu_stopper_thread
+ -> take_cpu_down
+ -> _cpu_disable
+ (dec __num_online_cpus)
+ ->cpuhp_invoke_callback
+ preempt_disable
+ access old_data0
+ task1
+ del old_data0 .....
+ synchronize_rcu_tasks_rude()
+ task1 schedule out
+ ....
+ task2 schedule in
+ rcu_tasks_rude_wait_gp()
+ ->__num_online_cpus == 1
+ ->return
+ ....
+ task1 schedule in
+ ->free old_data0
+ preempt_enable
+
+When CPU1 decrements __num_online_cpus, its value becomes 1. However,
+CPU1 has not finished going offline, and will take one last trip through
+the scheduler and the idle loop before it actually stops executing
+instructions. Because synchronize_rcu_tasks_rude() is mostly used for
+tracing, and because both the scheduler and the idle loop can be traced,
+this means that CPU0's prematurely ended grace period might disrupt the
+tracing on CPU1. Given that this disruption might include CPU1 executing
+instructions in memory that was just now freed (and maybe reallocated),
+this is a matter of some concern.
+
+This commit therefore removes that problematic single-CPU check from the
+rcu_tasks_rude_wait_gp() function. This dispenses with the single-CPU
+optimization, but there is no evidence indicating that this optimization
+is important. In addition, synchronize_rcu_tasks_generic() contains a
+similar optimization (albeit only for early boot), which also splats.
+(As in exactly why are you invoking synchronize_rcu_tasks_rude() so
+early in boot, anyway???)
+
+It is OK for the synchronize_rcu_tasks_rude() function's check to be
+unsynchronized because the only times that this check can evaluate to
+true is when there is only a single CPU running with preemption
+disabled.
+
+While in the area, this commit also fixes a minor bug in which a
+call to synchronize_rcu_tasks_rude() would instead be attributed to
+synchronize_rcu_tasks().
+
+[ paulmck: Add "synchronize_" prefix and "()" suffix. ]
+
+Signed-off-by: Zqiang <qiang1.zhang@intel.com>
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/rcu/tasks.h | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+diff --git a/kernel/rcu/tasks.h b/kernel/rcu/tasks.h
+index df8143c8a6a8e..c66d47685b28e 100644
+--- a/kernel/rcu/tasks.h
++++ b/kernel/rcu/tasks.h
+@@ -171,8 +171,9 @@ static void call_rcu_tasks_generic(struct rcu_head *rhp, rcu_callback_t func,
+ static void synchronize_rcu_tasks_generic(struct rcu_tasks *rtp)
+ {
+ /* Complain if the scheduler has not started. */
+- WARN_ONCE(rcu_scheduler_active == RCU_SCHEDULER_INACTIVE,
+- "synchronize_rcu_tasks called too soon");
++ if (WARN_ONCE(rcu_scheduler_active == RCU_SCHEDULER_INACTIVE,
++ "synchronize_%s() called too soon", rtp->name))
++ return;
+
+ /* Wait for the grace period. */
+ wait_rcu_gp(rtp->call_func);
+@@ -648,9 +649,6 @@ static void rcu_tasks_be_rude(struct work_struct *work)
+ // Wait for one rude RCU-tasks grace period.
+ static void rcu_tasks_rude_wait_gp(struct rcu_tasks *rtp)
+ {
+- if (num_online_cpus() <= 1)
+- return; // Fastpath for only one CPU.
+-
+ rtp->n_ipis += cpumask_weight(cpu_online_mask);
+ schedule_on_each_cpu(rcu_tasks_be_rude);
+ }
+--
+2.39.2
+
--- /dev/null
+From 360d42ba033e7dee289e40fc6380495c0a06198f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Nov 2022 14:54:59 +0100
+Subject: rcu-tasks: Remove preemption disablement around srcu_read_[un]lock()
+ calls
+
+From: Frederic Weisbecker <frederic@kernel.org>
+
+[ Upstream commit 44757092958bdd749775022f915b7ac974384c2a ]
+
+Ever since the following commit:
+
+ 5a41344a3d83 ("srcu: Simplify __srcu_read_unlock() via this_cpu_dec()")
+
+SRCU doesn't rely anymore on preemption to be disabled in order to
+modify the per-CPU counter. And even then it used to be done from the API
+itself.
+
+Therefore and after checking further, it appears to be safe to remove
+the preemption disablement around __srcu_read_[un]lock() in
+exit_tasks_rcu_start() and exit_tasks_rcu_finish()
+
+Suggested-by: Boqun Feng <boqun.feng@gmail.com>
+Suggested-by: Paul E. McKenney <paulmck@kernel.org>
+Suggested-by: Neeraj Upadhyay <quic_neeraju@quicinc.com>
+Cc: Lai Jiangshan <jiangshanlai@gmail.com>
+Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Stable-dep-of: 28319d6dc5e2 ("rcu-tasks: Fix synchronize_rcu_tasks() VS zap_pid_ns_processes()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/rcu/tasks.h | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/kernel/rcu/tasks.h b/kernel/rcu/tasks.h
+index 372644126b0de..c4af3c05663f4 100644
+--- a/kernel/rcu/tasks.h
++++ b/kernel/rcu/tasks.h
+@@ -596,9 +596,7 @@ static void show_rcu_tasks_classic_gp_kthread(void)
+ */
+ void exit_tasks_rcu_start(void) __acquires(&tasks_rcu_exit_srcu)
+ {
+- preempt_disable();
+ current->rcu_tasks_idx = __srcu_read_lock(&tasks_rcu_exit_srcu);
+- preempt_enable();
+ }
+
+ /*
+@@ -610,9 +608,7 @@ void exit_tasks_rcu_finish(void) __releases(&tasks_rcu_exit_srcu)
+ {
+ struct task_struct *t = current;
+
+- preempt_disable();
+ __srcu_read_unlock(&tasks_rcu_exit_srcu, t->rcu_tasks_idx);
+- preempt_enable();
+ exit_tasks_rcu_finish_trace(t);
+ }
+
+--
+2.39.2
+
--- /dev/null
+From a2a95588af524e81db4f053eb7ae83bca3c74e03 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Feb 2023 12:26:23 +0000
+Subject: rds: rds_rm_zerocopy_callback() correct order for list_add_tail()
+
+From: Pietro Borrello <borrello@diag.uniroma1.it>
+
+[ Upstream commit 68762148d1b011d47bc2ceed7321739b5aea1e63 ]
+
+rds_rm_zerocopy_callback() uses list_add_tail() with swapped
+arguments. This links the list head with the new entry, losing
+the references to the remaining part of the list.
+
+Fixes: 9426bbc6de99 ("rds: use list structure to track information for zerocopy completion notification")
+Suggested-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Pietro Borrello <borrello@diag.uniroma1.it>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rds/message.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/rds/message.c b/net/rds/message.c
+index b363ef13c75ef..8fa3d19c2e667 100644
+--- a/net/rds/message.c
++++ b/net/rds/message.c
+@@ -118,7 +118,7 @@ static void rds_rm_zerocopy_callback(struct rds_sock *rs,
+ ck = &info->zcookies;
+ memset(ck, 0, sizeof(*ck));
+ WARN_ON(!rds_zcookie_add(info, cookie));
+- list_add_tail(&q->zcookie_head, &info->rs_zcookie_next);
++ list_add_tail(&info->rs_zcookie_next, &q->zcookie_head);
+
+ spin_unlock_irqrestore(&q->lock, flags);
+ /* caller invokes rds_wake_sk_sleep() */
+--
+2.39.2
+
--- /dev/null
+From 8919ade7cdd2369cb9cfcb02515f3ceceb41dd8f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 27 Jan 2023 14:52:07 -0800
+Subject: regulator: max77802: Bounds check regulator id against opmode
+
+From: Kees Cook <keescook@chromium.org>
+
+[ Upstream commit 4fd8bcec5fd7c0d586206fa2f42bd67b06cdaa7e ]
+
+Explicitly bounds-check the id before accessing the opmode array. Seen
+with GCC 13:
+
+../drivers/regulator/max77802-regulator.c: In function 'max77802_enable':
+../drivers/regulator/max77802-regulator.c:217:29: warning: array subscript [0, 41] is outside array bounds of 'unsigned int[42]' [-Warray-bounds=]
+ 217 | if (max77802->opmode[id] == MAX77802_OFF_PWRREQ)
+ | ~~~~~~~~~~~~~~~~^~~~
+../drivers/regulator/max77802-regulator.c:62:22: note: while referencing 'opmode'
+ 62 | unsigned int opmode[MAX77802_REG_MAX];
+ | ^~~~~~
+
+Cc: Javier Martinez Canillas <javier@dowhile0.org>
+Cc: Liam Girdwood <lgirdwood@gmail.com>
+Cc: Mark Brown <broonie@kernel.org>
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Acked-by: Javier Martinez Canillas <javierm@redhat.com>
+Link: https://lore.kernel.org/r/20230127225203.never.864-kees@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/max77802-regulator.c | 34 ++++++++++++++++++--------
+ 1 file changed, 24 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/regulator/max77802-regulator.c b/drivers/regulator/max77802-regulator.c
+index 7b8ec8c0bd151..660e179a82a2c 100644
+--- a/drivers/regulator/max77802-regulator.c
++++ b/drivers/regulator/max77802-regulator.c
+@@ -95,9 +95,11 @@ static int max77802_set_suspend_disable(struct regulator_dev *rdev)
+ {
+ unsigned int val = MAX77802_OFF_PWRREQ;
+ struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev);
+- int id = rdev_get_id(rdev);
++ unsigned int id = rdev_get_id(rdev);
+ int shift = max77802_get_opmode_shift(id);
+
++ if (WARN_ON_ONCE(id >= ARRAY_SIZE(max77802->opmode)))
++ return -EINVAL;
+ max77802->opmode[id] = val;
+ return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
+ rdev->desc->enable_mask, val << shift);
+@@ -111,7 +113,7 @@ static int max77802_set_suspend_disable(struct regulator_dev *rdev)
+ static int max77802_set_mode(struct regulator_dev *rdev, unsigned int mode)
+ {
+ struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev);
+- int id = rdev_get_id(rdev);
++ unsigned int id = rdev_get_id(rdev);
+ unsigned int val;
+ int shift = max77802_get_opmode_shift(id);
+
+@@ -128,6 +130,9 @@ static int max77802_set_mode(struct regulator_dev *rdev, unsigned int mode)
+ return -EINVAL;
+ }
+
++ if (WARN_ON_ONCE(id >= ARRAY_SIZE(max77802->opmode)))
++ return -EINVAL;
++
+ max77802->opmode[id] = val;
+ return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
+ rdev->desc->enable_mask, val << shift);
+@@ -136,8 +141,10 @@ static int max77802_set_mode(struct regulator_dev *rdev, unsigned int mode)
+ static unsigned max77802_get_mode(struct regulator_dev *rdev)
+ {
+ struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev);
+- int id = rdev_get_id(rdev);
++ unsigned int id = rdev_get_id(rdev);
+
++ if (WARN_ON_ONCE(id >= ARRAY_SIZE(max77802->opmode)))
++ return -EINVAL;
+ return max77802_map_mode(max77802->opmode[id]);
+ }
+
+@@ -161,10 +168,13 @@ static int max77802_set_suspend_mode(struct regulator_dev *rdev,
+ unsigned int mode)
+ {
+ struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev);
+- int id = rdev_get_id(rdev);
++ unsigned int id = rdev_get_id(rdev);
+ unsigned int val;
+ int shift = max77802_get_opmode_shift(id);
+
++ if (WARN_ON_ONCE(id >= ARRAY_SIZE(max77802->opmode)))
++ return -EINVAL;
++
+ /*
+ * If the regulator has been disabled for suspend
+ * then is invalid to try setting a suspend mode.
+@@ -210,9 +220,11 @@ static int max77802_set_suspend_mode(struct regulator_dev *rdev,
+ static int max77802_enable(struct regulator_dev *rdev)
+ {
+ struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev);
+- int id = rdev_get_id(rdev);
++ unsigned int id = rdev_get_id(rdev);
+ int shift = max77802_get_opmode_shift(id);
+
++ if (WARN_ON_ONCE(id >= ARRAY_SIZE(max77802->opmode)))
++ return -EINVAL;
+ if (max77802->opmode[id] == MAX77802_OFF_PWRREQ)
+ max77802->opmode[id] = MAX77802_OPMODE_NORMAL;
+
+@@ -541,7 +553,7 @@ static int max77802_pmic_probe(struct platform_device *pdev)
+
+ for (i = 0; i < MAX77802_REG_MAX; i++) {
+ struct regulator_dev *rdev;
+- int id = regulators[i].id;
++ unsigned int id = regulators[i].id;
+ int shift = max77802_get_opmode_shift(id);
+ int ret;
+
+@@ -559,10 +571,12 @@ static int max77802_pmic_probe(struct platform_device *pdev)
+ * the hardware reports OFF as the regulator operating mode.
+ * Default to operating mode NORMAL in that case.
+ */
+- if (val == MAX77802_STATUS_OFF)
+- max77802->opmode[id] = MAX77802_OPMODE_NORMAL;
+- else
+- max77802->opmode[id] = val;
++ if (id < ARRAY_SIZE(max77802->opmode)) {
++ if (val == MAX77802_STATUS_OFF)
++ max77802->opmode[id] = MAX77802_OPMODE_NORMAL;
++ else
++ max77802->opmode[id] = val;
++ }
+
+ rdev = devm_regulator_register(&pdev->dev,
+ ®ulators[i], &config);
+--
+2.39.2
+
--- /dev/null
+From 55c2c1b4b0f4ff03d8f206344b2f2e418ce6827b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 27 Jan 2023 16:53:58 -0800
+Subject: regulator: s5m8767: Bounds check id indexing into arrays
+
+From: Kees Cook <keescook@chromium.org>
+
+[ Upstream commit e314e15a0b58f9d051c00b25951073bcdae61953 ]
+
+The compiler has no way to know if "id" is within the array bounds of
+the regulators array. Add a check for this and a build-time check that
+the regulators and reg_voltage_map arrays are sized the same. Seen with
+GCC 13:
+
+../drivers/regulator/s5m8767.c: In function 's5m8767_pmic_probe':
+../drivers/regulator/s5m8767.c:936:35: warning: array subscript [0, 36] is outside array bounds of 'struct regulator_desc[37]' [-Warray-bounds=]
+ 936 | regulators[id].vsel_reg =
+ | ~~~~~~~~~~^~~~
+
+Cc: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Cc: Liam Girdwood <lgirdwood@gmail.com>
+Cc: Mark Brown <broonie@kernel.org>
+Cc: linux-samsung-soc@vger.kernel.org
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20230128005358.never.313-kees@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/s5m8767.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c
+index 35269f9982105..754c6fcc6e642 100644
+--- a/drivers/regulator/s5m8767.c
++++ b/drivers/regulator/s5m8767.c
+@@ -923,10 +923,14 @@ static int s5m8767_pmic_probe(struct platform_device *pdev)
+
+ for (i = 0; i < pdata->num_regulators; i++) {
+ const struct sec_voltage_desc *desc;
+- int id = pdata->regulators[i].id;
++ unsigned int id = pdata->regulators[i].id;
+ int enable_reg, enable_val;
+ struct regulator_dev *rdev;
+
++ BUILD_BUG_ON(ARRAY_SIZE(regulators) != ARRAY_SIZE(reg_voltage_map));
++ if (WARN_ON_ONCE(id >= ARRAY_SIZE(regulators)))
++ continue;
++
+ desc = reg_voltage_map[id];
+ if (desc) {
+ regulators[id].n_voltages =
+--
+2.39.2
+
--- /dev/null
+From 65455c2562450bcba9d7422fd2efd1ea0c688084 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Jan 2023 14:28:35 +0530
+Subject: remoteproc: qcom_q6v5_mss: Use a carveout to authenticate modem
+ headers
+
+From: Sibi Sankar <quic_sibis@quicinc.com>
+
+[ Upstream commit 57f72170a2b2a362c35bb9407fc844eac5afdec1 ]
+
+Any access to the dynamically allocated metadata region by the application
+processor after assigning it to the remote Q6 will result in a XPU
+violation. Fix this by replacing the dynamically allocated memory region
+with a no-map carveout and unmap the modem metadata memory region before
+passing control to the remote Q6.
+
+Reported-and-tested-by: Amit Pundir <amit.pundir@linaro.org>
+Fixes: 6c5a9dc2481b ("remoteproc: qcom: Make secure world call for mem ownership switch")
+Signed-off-by: Sibi Sankar <quic_sibis@quicinc.com>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230117085840.32356-7-quic_sibis@quicinc.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/remoteproc/qcom_q6v5_mss.c | 59 +++++++++++++++++++++++++++---
+ 1 file changed, 53 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/remoteproc/qcom_q6v5_mss.c b/drivers/remoteproc/qcom_q6v5_mss.c
+index 1b3aa84e36e7a..3d975ecd93360 100644
+--- a/drivers/remoteproc/qcom_q6v5_mss.c
++++ b/drivers/remoteproc/qcom_q6v5_mss.c
+@@ -17,6 +17,7 @@
+ #include <linux/module.h>
+ #include <linux/of_address.h>
+ #include <linux/of_device.h>
++#include <linux/of_reserved_mem.h>
+ #include <linux/platform_device.h>
+ #include <linux/pm_domain.h>
+ #include <linux/pm_runtime.h>
+@@ -190,6 +191,9 @@ struct q6v5 {
+ size_t mba_size;
+ size_t dp_size;
+
++ phys_addr_t mdata_phys;
++ size_t mdata_size;
++
+ phys_addr_t mpss_phys;
+ phys_addr_t mpss_reloc;
+ size_t mpss_size;
+@@ -816,15 +820,35 @@ static int q6v5_mpss_init_image(struct q6v5 *qproc, const struct firmware *fw)
+ if (IS_ERR(metadata))
+ return PTR_ERR(metadata);
+
+- ptr = dma_alloc_attrs(qproc->dev, size, &phys, GFP_KERNEL, dma_attrs);
+- if (!ptr) {
+- kfree(metadata);
+- dev_err(qproc->dev, "failed to allocate mdt buffer\n");
+- return -ENOMEM;
++ if (qproc->mdata_phys) {
++ if (size > qproc->mdata_size) {
++ ret = -EINVAL;
++ dev_err(qproc->dev, "metadata size outside memory range\n");
++ goto free_metadata;
++ }
++
++ phys = qproc->mdata_phys;
++ ptr = memremap(qproc->mdata_phys, size, MEMREMAP_WC);
++ if (!ptr) {
++ ret = -EBUSY;
++ dev_err(qproc->dev, "unable to map memory region: %pa+%zx\n",
++ &qproc->mdata_phys, size);
++ goto free_metadata;
++ }
++ } else {
++ ptr = dma_alloc_attrs(qproc->dev, size, &phys, GFP_KERNEL, dma_attrs);
++ if (!ptr) {
++ ret = -ENOMEM;
++ dev_err(qproc->dev, "failed to allocate mdt buffer\n");
++ goto free_metadata;
++ }
+ }
+
+ memcpy(ptr, metadata, size);
+
++ if (qproc->mdata_phys)
++ memunmap(ptr);
++
+ /* Hypervisor mapping to access metadata by modem */
+ mdata_perm = BIT(QCOM_SCM_VMID_HLOS);
+ ret = q6v5_xfer_mem_ownership(qproc, &mdata_perm, false, true,
+@@ -853,7 +877,9 @@ static int q6v5_mpss_init_image(struct q6v5 *qproc, const struct firmware *fw)
+ "mdt buffer not reclaimed system may become unstable\n");
+
+ free_dma_attrs:
+- dma_free_attrs(qproc->dev, size, ptr, phys, dma_attrs);
++ if (!qproc->mdata_phys)
++ dma_free_attrs(qproc->dev, size, ptr, phys, dma_attrs);
++free_metadata:
+ kfree(metadata);
+
+ return ret < 0 ? ret : 0;
+@@ -1585,6 +1611,7 @@ static int q6v5_init_reset(struct q6v5 *qproc)
+ static int q6v5_alloc_memory_region(struct q6v5 *qproc)
+ {
+ struct device_node *child;
++ struct reserved_mem *rmem;
+ struct device_node *node;
+ struct resource r;
+ int ret;
+@@ -1637,6 +1664,26 @@ static int q6v5_alloc_memory_region(struct q6v5 *qproc)
+ qproc->mpss_phys = qproc->mpss_reloc = r.start;
+ qproc->mpss_size = resource_size(&r);
+
++ if (!child) {
++ node = of_parse_phandle(qproc->dev->of_node, "memory-region", 2);
++ } else {
++ child = of_get_child_by_name(qproc->dev->of_node, "metadata");
++ node = of_parse_phandle(child, "memory-region", 0);
++ of_node_put(child);
++ }
++
++ if (!node)
++ return 0;
++
++ rmem = of_reserved_mem_lookup(node);
++ if (!rmem) {
++ dev_err(qproc->dev, "unable to resolve metadata region\n");
++ return -EINVAL;
++ }
++
++ qproc->mdata_phys = rmem->base;
++ qproc->mdata_size = rmem->size;
++
+ return 0;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From c5ffe270e253e6cf09fa3b8f7393a1cd22f21f37 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Dec 2022 23:13:21 +0100
+Subject: RISC-V: fix funct4 definition for c.jalr in parse_asm.h
+
+From: Heiko Stuebner <heiko.stuebner@vrull.eu>
+
+[ Upstream commit a3775634f6da23f5511d0282d7e792cf606e5f3b ]
+
+The opcode definition for c.jalr is
+ c.jalr c_rs1_n0 1..0=2 15..13=4 12=1 6..2=0
+
+This means funct4 consisting of bit [15:12] is 1001b, so the value is 0x9.
+
+Fixes: edde5584c7ab ("riscv: Add SW single-step support for KDB")
+Reported-by: Andrew Jones <ajones@ventanamicro.com>
+Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
+Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+Signed-off-by: Heiko Stuebner <heiko.stuebner@vrull.eu>
+Link: https://lore.kernel.org/r/20221223221332.4127602-2-heiko@sntech.de
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/include/asm/parse_asm.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/riscv/include/asm/parse_asm.h b/arch/riscv/include/asm/parse_asm.h
+index f36368de839f5..7fee806805c1b 100644
+--- a/arch/riscv/include/asm/parse_asm.h
++++ b/arch/riscv/include/asm/parse_asm.h
+@@ -125,7 +125,7 @@
+ #define FUNCT3_C_J 0xa000
+ #define FUNCT3_C_JAL 0x2000
+ #define FUNCT4_C_JR 0x8000
+-#define FUNCT4_C_JALR 0xf000
++#define FUNCT4_C_JALR 0x9000
+
+ #define FUNCT12_SRET 0x10200000
+
+--
+2.39.2
+
--- /dev/null
+From 6a8182a0dad8c794adccd1c2984a22a1432f5b2a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Jan 2023 19:41:00 +0530
+Subject: RISC-V: time: initialize hrtimer based broadcast clock event device
+
+From: Conor Dooley <conor.dooley@microchip.com>
+
+[ Upstream commit 8b3b8fbb4896984b5564789a42240e4b3caddb61 ]
+
+Similarly to commit 022eb8ae8b5e ("ARM: 8938/1: kernel: initialize
+broadcast hrtimer based clock event device"), RISC-V needs to initiate
+hrtimer based broadcast clock event device before C3STOP can be used.
+Otherwise, the introduction of C3STOP for the RISC-V arch timer in
+commit 232ccac1bd9b ("clocksource/drivers/riscv: Events are stopped
+during CPU suspend") leaves us without any broadcast timer registered.
+This prevents the kernel from entering oneshot mode, which breaks timer
+behaviour, for example clock_nanosleep().
+
+A test app that sleeps each cpu for 6, 5, 4, 3 ms respectively, HZ=250
+& C3STOP enabled, the sleep times are rounded up to the next jiffy:
+== CPU: 1 == == CPU: 2 == == CPU: 3 == == CPU: 4 ==
+Mean: 7.974992 Mean: 7.976534 Mean: 7.962591 Mean: 3.952179
+Std Dev: 0.154374 Std Dev: 0.156082 Std Dev: 0.171018 Std Dev: 0.076193
+Hi: 9.472000 Hi: 10.495000 Hi: 8.864000 Hi: 4.736000
+Lo: 6.087000 Lo: 6.380000 Lo: 4.872000 Lo: 3.403000
+Samples: 521 Samples: 521 Samples: 521 Samples: 521
+
+Link: https://lore.kernel.org/linux-riscv/YzYTNQRxLr7Q9JR0@spud/
+Fixes: 232ccac1bd9b ("clocksource/drivers/riscv: Events are stopped during CPU suspend")
+Suggested-by: Samuel Holland <samuel@sholland.org>
+Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
+Signed-off-by: Anup Patel <apatel@ventanamicro.com>
+Reviewed-by: Samuel Holland <samuel@sholland.org>
+Acked-by: Palmer Dabbelt <palmer@rivosinc.com>
+Link: https://lore.kernel.org/r/20230103141102.772228-2-apatel@ventanamicro.com
+Signed-off-by: Daniel Lezcano <daniel.lezcano@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/time.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/arch/riscv/kernel/time.c b/arch/riscv/kernel/time.c
+index 8a5cf99c07762..303ae47dfb4d6 100644
+--- a/arch/riscv/kernel/time.c
++++ b/arch/riscv/kernel/time.c
+@@ -5,6 +5,7 @@
+ */
+
+ #include <linux/of_clk.h>
++#include <linux/clockchips.h>
+ #include <linux/clocksource.h>
+ #include <linux/delay.h>
+ #include <asm/sbi.h>
+@@ -28,6 +29,8 @@ void __init time_init(void)
+
+ of_clk_init(NULL);
+ timer_probe();
++
++ tick_setup_hrtimer_broadcast();
+ }
+
+ void clocksource_arch_init(struct clocksource *cs)
+--
+2.39.2
+
--- /dev/null
+From 5e698fc1179e28c7f8deef6ff3bc9b5999d6b114 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Feb 2023 15:42:31 -0800
+Subject: rpmsg: glink: Avoid infinite loop on intent for missing channel
+
+From: Bjorn Andersson <quic_bjorande@quicinc.com>
+
+[ Upstream commit 3e74ec2f39362bffbd42854acbb67c7f4cb808f9 ]
+
+In the event that an intent advertisement arrives on an unknown channel
+the fifo is not advanced, resulting in the same message being handled
+over and over.
+
+Fixes: dacbb35e930f ("rpmsg: glink: Receive and store the remote intent buffers")
+Signed-off-by: Bjorn Andersson <quic_bjorande@quicinc.com>
+Reviewed-by: Chris Lew <quic_clew@quicinc.com>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230214234231.2069751-1-quic_bjorande@quicinc.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rpmsg/qcom_glink_native.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c
+index 7cbed0310c09f..98b6d4c09c82c 100644
+--- a/drivers/rpmsg/qcom_glink_native.c
++++ b/drivers/rpmsg/qcom_glink_native.c
+@@ -929,6 +929,7 @@ static void qcom_glink_handle_intent(struct qcom_glink *glink,
+ spin_unlock_irqrestore(&glink->idr_lock, flags);
+ if (!channel) {
+ dev_err(glink->dev, "intents for non-existing channel\n");
++ qcom_glink_rx_advance(glink, ALIGN(msglen, 8));
+ return;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 2600f186ddcbe341d9cdaf60e3e9ad67a7e93878 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Oct 2020 22:29:53 +0100
+Subject: rtlwifi: fix -Wpointer-sign warning
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit ef41937631bfee855e2b406e1d536efdaa9ce512 ]
+
+There are thousands of warnings in a W=2 build from just one file:
+
+drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.c:3788:15: warning: pointer targets in initialization of 'u8 *' {aka 'unsigned char *'} from 'char *' differ in signedness [-Wpointer-sign]
+
+Change the types to consistently use 'const char *' for the
+strings.
+
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Acked-by: Ping-Ke Shih <pkshih@realtek.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/20201026213040.3889546-6-arnd@kernel.org
+Stable-dep-of: 117dbeda22ec ("wifi: rtlwifi: Fix global-out-of-bounds bug in _rtl8812ae_phy_set_txpower_limit()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../wireless/realtek/rtlwifi/rtl8821ae/phy.c | 81 ++++++++++---------
+ .../realtek/rtlwifi/rtl8821ae/table.c | 4 +-
+ .../realtek/rtlwifi/rtl8821ae/table.h | 4 +-
+ 3 files changed, 45 insertions(+), 44 deletions(-)
+
+diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c
+index f41a7643b9c42..119e0f799826f 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c
++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c
+@@ -1581,7 +1581,7 @@ static void _rtl8821ae_phy_txpower_by_rate_configuration(struct ieee80211_hw *hw
+ }
+
+ /* string is in decimal */
+-static bool _rtl8812ae_get_integer_from_string(char *str, u8 *pint)
++static bool _rtl8812ae_get_integer_from_string(const char *str, u8 *pint)
+ {
+ u16 i = 0;
+ *pint = 0;
+@@ -1599,7 +1599,7 @@ static bool _rtl8812ae_get_integer_from_string(char *str, u8 *pint)
+ return true;
+ }
+
+-static bool _rtl8812ae_eq_n_byte(u8 *str1, u8 *str2, u32 num)
++static bool _rtl8812ae_eq_n_byte(const char *str1, const char *str2, u32 num)
+ {
+ if (num == 0)
+ return false;
+@@ -1637,10 +1637,11 @@ static s8 _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(struct ieee80211_hw *hw,
+ return channel_index;
+ }
+
+-static void _rtl8812ae_phy_set_txpower_limit(struct ieee80211_hw *hw, u8 *pregulation,
+- u8 *pband, u8 *pbandwidth,
+- u8 *prate_section, u8 *prf_path,
+- u8 *pchannel, u8 *ppower_limit)
++static void _rtl8812ae_phy_set_txpower_limit(struct ieee80211_hw *hw,
++ const char *pregulation,
++ const char *pband, const char *pbandwidth,
++ const char *prate_section, const char *prf_path,
++ const char *pchannel, const char *ppower_limit)
+ {
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &rtlpriv->phy;
+@@ -1648,8 +1649,8 @@ static void _rtl8812ae_phy_set_txpower_limit(struct ieee80211_hw *hw, u8 *pregul
+ u8 channel_index;
+ s8 power_limit = 0, prev_power_limit, ret;
+
+- if (!_rtl8812ae_get_integer_from_string((char *)pchannel, &channel) ||
+- !_rtl8812ae_get_integer_from_string((char *)ppower_limit,
++ if (!_rtl8812ae_get_integer_from_string(pchannel, &channel) ||
++ !_rtl8812ae_get_integer_from_string(ppower_limit,
+ &power_limit)) {
+ rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
+ "Illegal index of pwr_lmt table [chnl %d][val %d]\n",
+@@ -1659,42 +1660,42 @@ static void _rtl8812ae_phy_set_txpower_limit(struct ieee80211_hw *hw, u8 *pregul
+ power_limit = power_limit > MAX_POWER_INDEX ?
+ MAX_POWER_INDEX : power_limit;
+
+- if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("FCC"), 3))
++ if (_rtl8812ae_eq_n_byte(pregulation, "FCC", 3))
+ regulation = 0;
+- else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("MKK"), 3))
++ else if (_rtl8812ae_eq_n_byte(pregulation, "MKK", 3))
+ regulation = 1;
+- else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("ETSI"), 4))
++ else if (_rtl8812ae_eq_n_byte(pregulation, "ETSI", 4))
+ regulation = 2;
+- else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("WW13"), 4))
++ else if (_rtl8812ae_eq_n_byte(pregulation, "WW13", 4))
+ regulation = 3;
+
+- if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("CCK"), 3))
++ if (_rtl8812ae_eq_n_byte(prate_section, "CCK", 3))
+ rate_section = 0;
+- else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("OFDM"), 4))
++ else if (_rtl8812ae_eq_n_byte(prate_section, "OFDM", 4))
+ rate_section = 1;
+- else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("HT"), 2) &&
+- _rtl8812ae_eq_n_byte(prf_path, (u8 *)("1T"), 2))
++ else if (_rtl8812ae_eq_n_byte(prate_section, "HT", 2) &&
++ _rtl8812ae_eq_n_byte(prf_path, "1T", 2))
+ rate_section = 2;
+- else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("HT"), 2) &&
+- _rtl8812ae_eq_n_byte(prf_path, (u8 *)("2T"), 2))
++ else if (_rtl8812ae_eq_n_byte(prate_section, "HT", 2) &&
++ _rtl8812ae_eq_n_byte(prf_path, "2T", 2))
+ rate_section = 3;
+- else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("VHT"), 3) &&
+- _rtl8812ae_eq_n_byte(prf_path, (u8 *)("1T"), 2))
++ else if (_rtl8812ae_eq_n_byte(prate_section, "VHT", 3) &&
++ _rtl8812ae_eq_n_byte(prf_path, "1T", 2))
+ rate_section = 4;
+- else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("VHT"), 3) &&
+- _rtl8812ae_eq_n_byte(prf_path, (u8 *)("2T"), 2))
++ else if (_rtl8812ae_eq_n_byte(prate_section, "VHT", 3) &&
++ _rtl8812ae_eq_n_byte(prf_path, "2T", 2))
+ rate_section = 5;
+
+- if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("20M"), 3))
++ if (_rtl8812ae_eq_n_byte(pbandwidth, "20M", 3))
+ bandwidth = 0;
+- else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("40M"), 3))
++ else if (_rtl8812ae_eq_n_byte(pbandwidth, "40M", 3))
+ bandwidth = 1;
+- else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("80M"), 3))
++ else if (_rtl8812ae_eq_n_byte(pbandwidth, "80M", 3))
+ bandwidth = 2;
+- else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("160M"), 4))
++ else if (_rtl8812ae_eq_n_byte(pbandwidth, "160M", 4))
+ bandwidth = 3;
+
+- if (_rtl8812ae_eq_n_byte(pband, (u8 *)("2.4G"), 4)) {
++ if (_rtl8812ae_eq_n_byte(pband, "2.4G", 4)) {
+ ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
+ BAND_ON_2_4G,
+ channel);
+@@ -1718,7 +1719,7 @@ static void _rtl8812ae_phy_set_txpower_limit(struct ieee80211_hw *hw, u8 *pregul
+ regulation, bandwidth, rate_section, channel_index,
+ rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
+ [rate_section][channel_index][RF90_PATH_A]);
+- } else if (_rtl8812ae_eq_n_byte(pband, (u8 *)("5G"), 2)) {
++ } else if (_rtl8812ae_eq_n_byte(pband, "5G", 2)) {
+ ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
+ BAND_ON_5G,
+ channel);
+@@ -1749,10 +1750,10 @@ static void _rtl8812ae_phy_set_txpower_limit(struct ieee80211_hw *hw, u8 *pregul
+ }
+
+ static void _rtl8812ae_phy_config_bb_txpwr_lmt(struct ieee80211_hw *hw,
+- u8 *regulation, u8 *band,
+- u8 *bandwidth, u8 *rate_section,
+- u8 *rf_path, u8 *channel,
+- u8 *power_limit)
++ const char *regulation, const char *band,
++ const char *bandwidth, const char *rate_section,
++ const char *rf_path, const char *channel,
++ const char *power_limit)
+ {
+ _rtl8812ae_phy_set_txpower_limit(hw, regulation, band, bandwidth,
+ rate_section, rf_path, channel,
+@@ -1765,7 +1766,7 @@ static void _rtl8821ae_phy_read_and_config_txpwr_lmt(struct ieee80211_hw *hw)
+ struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+ u32 i = 0;
+ u32 array_len;
+- u8 **array;
++ const char **array;
+
+ if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
+ array_len = RTL8812AE_TXPWR_LMT_ARRAY_LEN;
+@@ -1778,13 +1779,13 @@ static void _rtl8821ae_phy_read_and_config_txpwr_lmt(struct ieee80211_hw *hw)
+ rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "\n");
+
+ for (i = 0; i < array_len; i += 7) {
+- u8 *regulation = array[i];
+- u8 *band = array[i+1];
+- u8 *bandwidth = array[i+2];
+- u8 *rate = array[i+3];
+- u8 *rf_path = array[i+4];
+- u8 *chnl = array[i+5];
+- u8 *val = array[i+6];
++ const char *regulation = array[i];
++ const char *band = array[i+1];
++ const char *bandwidth = array[i+2];
++ const char *rate = array[i+3];
++ const char *rf_path = array[i+4];
++ const char *chnl = array[i+5];
++ const char *val = array[i+6];
+
+ _rtl8812ae_phy_config_bb_txpwr_lmt(hw, regulation, band,
+ bandwidth, rate, rf_path,
+diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.c
+index ed72a2aeb6c8e..fcaaf664cbec5 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.c
++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.c
+@@ -2894,7 +2894,7 @@ u32 RTL8821AE_AGC_TAB_1TARRAYLEN = ARRAY_SIZE(RTL8821AE_AGC_TAB_ARRAY);
+ * TXPWR_LMT.TXT
+ ******************************************************************************/
+
+-u8 *RTL8812AE_TXPWR_LMT[] = {
++const char *RTL8812AE_TXPWR_LMT[] = {
+ "FCC", "2.4G", "20M", "CCK", "1T", "01", "36",
+ "ETSI", "2.4G", "20M", "CCK", "1T", "01", "32",
+ "MKK", "2.4G", "20M", "CCK", "1T", "01", "32",
+@@ -3463,7 +3463,7 @@ u8 *RTL8812AE_TXPWR_LMT[] = {
+
+ u32 RTL8812AE_TXPWR_LMT_ARRAY_LEN = ARRAY_SIZE(RTL8812AE_TXPWR_LMT);
+
+-u8 *RTL8821AE_TXPWR_LMT[] = {
++const char *RTL8821AE_TXPWR_LMT[] = {
+ "FCC", "2.4G", "20M", "CCK", "1T", "01", "32",
+ "ETSI", "2.4G", "20M", "CCK", "1T", "01", "32",
+ "MKK", "2.4G", "20M", "CCK", "1T", "01", "32",
+diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.h b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.h
+index 540159c25078a..76c62b7c0fb24 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.h
++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.h
+@@ -28,7 +28,7 @@ extern u32 RTL8821AE_AGC_TAB_ARRAY[];
+ extern u32 RTL8812AE_AGC_TAB_1TARRAYLEN;
+ extern u32 RTL8812AE_AGC_TAB_ARRAY[];
+ extern u32 RTL8812AE_TXPWR_LMT_ARRAY_LEN;
+-extern u8 *RTL8812AE_TXPWR_LMT[];
++extern const char *RTL8812AE_TXPWR_LMT[];
+ extern u32 RTL8821AE_TXPWR_LMT_ARRAY_LEN;
+-extern u8 *RTL8821AE_TXPWR_LMT[];
++extern const char *RTL8821AE_TXPWR_LMT[];
+ #endif
+--
+2.39.2
+
--- /dev/null
+From b37578f92e27e439e623cde658ebd75863b7b4df Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Feb 2023 01:02:53 +0100
+Subject: s390/dasd: Fix potential memleak in dasd_eckd_init()
+
+From: Qiheng Lin <linqiheng@huawei.com>
+
+[ Upstream commit 460e9bed82e49db1b823dcb4e421783854d86c40 ]
+
+`dasd_reserve_req` is allocated before `dasd_vol_info_req`, and it
+also needs to be freed before the error returns, just like the other
+cases in this function.
+
+Fixes: 9e12e54c7a8f ("s390/dasd: Handle out-of-space constraint")
+Signed-off-by: Qiheng Lin <linqiheng@huawei.com>
+Link: https://lore.kernel.org/r/20221208133809.16796-1-linqiheng@huawei.com
+Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
+Link: https://lore.kernel.org/r/20230210000253.1644903-3-sth@linux.ibm.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/s390/block/dasd_eckd.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
+index d1429936f38c6..c6930c159d2a6 100644
+--- a/drivers/s390/block/dasd_eckd.c
++++ b/drivers/s390/block/dasd_eckd.c
+@@ -6763,8 +6763,10 @@ dasd_eckd_init(void)
+ return -ENOMEM;
+ dasd_vol_info_req = kmalloc(sizeof(*dasd_vol_info_req),
+ GFP_KERNEL | GFP_DMA);
+- if (!dasd_vol_info_req)
++ if (!dasd_vol_info_req) {
++ kfree(dasd_reserve_req);
+ return -ENOMEM;
++ }
+ pe_handler_worker = kmalloc(sizeof(*pe_handler_worker),
+ GFP_KERNEL | GFP_DMA);
+ if (!pe_handler_worker) {
+--
+2.39.2
+
--- /dev/null
+From 66fac2a303e946c5b5b005e850b91c78b04d2f4b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Oct 2020 15:13:35 +0200
+Subject: s390/dasd: Prepare for additional path event handling
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jan Höppner <hoeppner@linux.ibm.com>
+
+[ Upstream commit b72949328869dfd45f6452c2410647afd7db5f1a ]
+
+As more path events need to be handled for ECKD the current path
+verification infrastructure can be reused. Rename all path verifcation
+code to fit the more broadly based task of path event handling and put
+the path verification in a new separate function.
+
+Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
+Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
+Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Stable-dep-of: 460e9bed82e4 ("s390/dasd: Fix potential memleak in dasd_eckd_init()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/s390/block/dasd.c | 4 +-
+ drivers/s390/block/dasd_eckd.c | 78 +++++++++++++++++++---------------
+ drivers/s390/block/dasd_int.h | 1 +
+ 3 files changed, 47 insertions(+), 36 deletions(-)
+
+diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
+index f4edfe383e9d9..9f26f55e4988a 100644
+--- a/drivers/s390/block/dasd.c
++++ b/drivers/s390/block/dasd.c
+@@ -2128,8 +2128,8 @@ static void __dasd_device_check_path_events(struct dasd_device *device)
+ if (device->stopped &
+ ~(DASD_STOPPED_DC_WAIT | DASD_UNRESUMED_PM))
+ return;
+- rc = device->discipline->verify_path(device,
+- dasd_path_get_tbvpm(device));
++ rc = device->discipline->pe_handler(device,
++ dasd_path_get_tbvpm(device));
+ if (rc)
+ dasd_device_set_timer(device, 50);
+ else
+diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
+index 53d22975a32fd..d1429936f38c6 100644
+--- a/drivers/s390/block/dasd_eckd.c
++++ b/drivers/s390/block/dasd_eckd.c
+@@ -103,7 +103,7 @@ struct ext_pool_exhaust_work_data {
+ };
+
+ /* definitions for the path verification worker */
+-struct path_verification_work_data {
++struct pe_handler_work_data {
+ struct work_struct worker;
+ struct dasd_device *device;
+ struct dasd_ccw_req cqr;
+@@ -112,8 +112,8 @@ struct path_verification_work_data {
+ int isglobal;
+ __u8 tbvpm;
+ };
+-static struct path_verification_work_data *path_verification_worker;
+-static DEFINE_MUTEX(dasd_path_verification_mutex);
++static struct pe_handler_work_data *pe_handler_worker;
++static DEFINE_MUTEX(dasd_pe_handler_mutex);
+
+ struct check_attention_work_data {
+ struct work_struct worker;
+@@ -1219,7 +1219,7 @@ static int verify_fcx_max_data(struct dasd_device *device, __u8 lpm)
+ }
+
+ static int rebuild_device_uid(struct dasd_device *device,
+- struct path_verification_work_data *data)
++ struct pe_handler_work_data *data)
+ {
+ struct dasd_eckd_private *private = device->private;
+ __u8 lpm, opm = dasd_path_get_opm(device);
+@@ -1257,10 +1257,9 @@ static int rebuild_device_uid(struct dasd_device *device,
+ return rc;
+ }
+
+-static void do_path_verification_work(struct work_struct *work)
++static void dasd_eckd_path_available_action(struct dasd_device *device,
++ struct pe_handler_work_data *data)
+ {
+- struct path_verification_work_data *data;
+- struct dasd_device *device;
+ struct dasd_eckd_private path_private;
+ struct dasd_uid *uid;
+ __u8 path_rcd_buf[DASD_ECKD_RCD_DATA_SIZE];
+@@ -1269,19 +1268,6 @@ static void do_path_verification_work(struct work_struct *work)
+ char print_uid[60];
+ int rc;
+
+- data = container_of(work, struct path_verification_work_data, worker);
+- device = data->device;
+-
+- /* delay path verification until device was resumed */
+- if (test_bit(DASD_FLAG_SUSPENDED, &device->flags)) {
+- schedule_work(work);
+- return;
+- }
+- /* check if path verification already running and delay if so */
+- if (test_and_set_bit(DASD_FLAG_PATH_VERIFY, &device->flags)) {
+- schedule_work(work);
+- return;
+- }
+ opm = 0;
+ npm = 0;
+ ppm = 0;
+@@ -1418,30 +1404,54 @@ static void do_path_verification_work(struct work_struct *work)
+ dasd_path_add_nohpfpm(device, hpfpm);
+ spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
+ }
++}
++
++static void do_pe_handler_work(struct work_struct *work)
++{
++ struct pe_handler_work_data *data;
++ struct dasd_device *device;
++
++ data = container_of(work, struct pe_handler_work_data, worker);
++ device = data->device;
++
++ /* delay path verification until device was resumed */
++ if (test_bit(DASD_FLAG_SUSPENDED, &device->flags)) {
++ schedule_work(work);
++ return;
++ }
++ /* check if path verification already running and delay if so */
++ if (test_and_set_bit(DASD_FLAG_PATH_VERIFY, &device->flags)) {
++ schedule_work(work);
++ return;
++ }
++
++ dasd_eckd_path_available_action(device, data);
++
+ clear_bit(DASD_FLAG_PATH_VERIFY, &device->flags);
+ dasd_put_device(device);
+ if (data->isglobal)
+- mutex_unlock(&dasd_path_verification_mutex);
++ mutex_unlock(&dasd_pe_handler_mutex);
+ else
+ kfree(data);
+ }
+
+-static int dasd_eckd_verify_path(struct dasd_device *device, __u8 lpm)
++static int dasd_eckd_pe_handler(struct dasd_device *device, __u8 lpm)
+ {
+- struct path_verification_work_data *data;
++ struct pe_handler_work_data *data;
+
+ data = kmalloc(sizeof(*data), GFP_ATOMIC | GFP_DMA);
+ if (!data) {
+- if (mutex_trylock(&dasd_path_verification_mutex)) {
+- data = path_verification_worker;
++ if (mutex_trylock(&dasd_pe_handler_mutex)) {
++ data = pe_handler_worker;
+ data->isglobal = 1;
+- } else
++ } else {
+ return -ENOMEM;
++ }
+ } else {
+ memset(data, 0, sizeof(*data));
+ data->isglobal = 0;
+ }
+- INIT_WORK(&data->worker, do_path_verification_work);
++ INIT_WORK(&data->worker, do_pe_handler_work);
+ dasd_get_device(device);
+ data->device = device;
+ data->tbvpm = lpm;
+@@ -6694,7 +6704,7 @@ static struct dasd_discipline dasd_eckd_discipline = {
+ .check_device = dasd_eckd_check_characteristics,
+ .uncheck_device = dasd_eckd_uncheck_device,
+ .do_analysis = dasd_eckd_do_analysis,
+- .verify_path = dasd_eckd_verify_path,
++ .pe_handler = dasd_eckd_pe_handler,
+ .basic_to_ready = dasd_eckd_basic_to_ready,
+ .online_to_ready = dasd_eckd_online_to_ready,
+ .basic_to_known = dasd_eckd_basic_to_known,
+@@ -6755,16 +6765,16 @@ dasd_eckd_init(void)
+ GFP_KERNEL | GFP_DMA);
+ if (!dasd_vol_info_req)
+ return -ENOMEM;
+- path_verification_worker = kmalloc(sizeof(*path_verification_worker),
+- GFP_KERNEL | GFP_DMA);
+- if (!path_verification_worker) {
++ pe_handler_worker = kmalloc(sizeof(*pe_handler_worker),
++ GFP_KERNEL | GFP_DMA);
++ if (!pe_handler_worker) {
+ kfree(dasd_reserve_req);
+ kfree(dasd_vol_info_req);
+ return -ENOMEM;
+ }
+ rawpadpage = (void *)__get_free_page(GFP_KERNEL);
+ if (!rawpadpage) {
+- kfree(path_verification_worker);
++ kfree(pe_handler_worker);
+ kfree(dasd_reserve_req);
+ kfree(dasd_vol_info_req);
+ return -ENOMEM;
+@@ -6773,7 +6783,7 @@ dasd_eckd_init(void)
+ if (!ret)
+ wait_for_device_probe();
+ else {
+- kfree(path_verification_worker);
++ kfree(pe_handler_worker);
+ kfree(dasd_reserve_req);
+ kfree(dasd_vol_info_req);
+ free_page((unsigned long)rawpadpage);
+@@ -6785,7 +6795,7 @@ static void __exit
+ dasd_eckd_cleanup(void)
+ {
+ ccw_driver_unregister(&dasd_eckd_driver);
+- kfree(path_verification_worker);
++ kfree(pe_handler_worker);
+ kfree(dasd_reserve_req);
+ free_page((unsigned long)rawpadpage);
+ }
+diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
+index 9d9685c25253d..e8a06d85d6f72 100644
+--- a/drivers/s390/block/dasd_int.h
++++ b/drivers/s390/block/dasd_int.h
+@@ -299,6 +299,7 @@ struct dasd_discipline {
+ * configuration.
+ */
+ int (*verify_path)(struct dasd_device *, __u8);
++ int (*pe_handler)(struct dasd_device *, __u8);
+
+ /*
+ * Last things to do when a device is set online, and first things
+--
+2.39.2
+
--- /dev/null
+From efe60cbaf5d94be941cbd0c392210c8fb4cf3504 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 28 Jan 2023 17:35:12 +0100
+Subject: s390/vmem: fix empty page tables cleanup under KASAN
+
+From: Vasily Gorbik <gor@linux.ibm.com>
+
+[ Upstream commit 108303b0a2d27cb14eed565e33e64ad9eefe5d7e ]
+
+Commit b9ff81003cf1 ("s390/vmem: cleanup empty page tables") introduced
+empty page tables cleanup in vmem code, but when the kernel is built
+with KASAN enabled the code has no effect due to wrong KASAN shadow
+memory intersection condition, which effectively ignores any memory
+range below KASAN shadow. Fix intersection condition to make code
+work as anticipated.
+
+Fixes: b9ff81003cf1 ("s390/vmem: cleanup empty page tables")
+Reviewed-by: Alexander Gordeev <agordeev@linux.ibm.com>
+Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/mm/vmem.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c
+index b239f2ba93b09..cbfff2460e58d 100644
+--- a/arch/s390/mm/vmem.c
++++ b/arch/s390/mm/vmem.c
+@@ -296,7 +296,7 @@ static void try_free_pmd_table(pud_t *pud, unsigned long start)
+ if (end > VMALLOC_START)
+ return;
+ #ifdef CONFIG_KASAN
+- if (start < KASAN_SHADOW_END && KASAN_SHADOW_START > end)
++ if (start < KASAN_SHADOW_END && end > KASAN_SHADOW_START)
+ return;
+ #endif
+ pmd = pmd_offset(pud, start);
+@@ -371,7 +371,7 @@ static void try_free_pud_table(p4d_t *p4d, unsigned long start)
+ if (end > VMALLOC_START)
+ return;
+ #ifdef CONFIG_KASAN
+- if (start < KASAN_SHADOW_END && KASAN_SHADOW_START > end)
++ if (start < KASAN_SHADOW_END && end > KASAN_SHADOW_START)
+ return;
+ #endif
+
+@@ -425,7 +425,7 @@ static void try_free_p4d_table(pgd_t *pgd, unsigned long start)
+ if (end > VMALLOC_START)
+ return;
+ #ifdef CONFIG_KASAN
+- if (start < KASAN_SHADOW_END && KASAN_SHADOW_START > end)
++ if (start < KASAN_SHADOW_END && end > KASAN_SHADOW_START)
+ return;
+ #endif
+
+--
+2.39.2
+
--- /dev/null
+From 379e1f1c19472c5507d37b0109112444a74130a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Mar 2022 19:34:33 +0100
+Subject: sched/deadline,rt: Remove unused parameter from
+ pick_next_[rt|dl]_entity()
+
+From: Dietmar Eggemann <dietmar.eggemann@arm.com>
+
+[ Upstream commit 821aecd09e5ad2f8d4c3d8195333d272b392f7d3 ]
+
+The `struct rq *rq` parameter isn't used. Remove it.
+
+Signed-off-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Acked-by: Juri Lelli <juri.lelli@redhat.com>
+Link: https://lore.kernel.org/r/20220302183433.333029-7-dietmar.eggemann@arm.com
+Stable-dep-of: 7c4a5b89a0b5 ("sched/rt: pick_next_rt_entity(): check list_entry")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/deadline.c | 5 ++---
+ kernel/sched/rt.c | 5 ++---
+ 2 files changed, 4 insertions(+), 6 deletions(-)
+
+diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
+index aaf98771f9357..f59cb3e8a6130 100644
+--- a/kernel/sched/deadline.c
++++ b/kernel/sched/deadline.c
+@@ -1847,8 +1847,7 @@ static void set_next_task_dl(struct rq *rq, struct task_struct *p, bool first)
+ deadline_queue_push_tasks(rq);
+ }
+
+-static struct sched_dl_entity *pick_next_dl_entity(struct rq *rq,
+- struct dl_rq *dl_rq)
++static struct sched_dl_entity *pick_next_dl_entity(struct dl_rq *dl_rq)
+ {
+ struct rb_node *left = rb_first_cached(&dl_rq->root);
+
+@@ -1867,7 +1866,7 @@ static struct task_struct *pick_next_task_dl(struct rq *rq)
+ if (!sched_dl_runnable(rq))
+ return NULL;
+
+- dl_se = pick_next_dl_entity(rq, dl_rq);
++ dl_se = pick_next_dl_entity(dl_rq);
+ BUG_ON(!dl_se);
+ p = dl_task_of(dl_se);
+ set_next_task_dl(rq, p, true);
+diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
+index e6f22836c600b..e1ce5d1868b50 100644
+--- a/kernel/sched/rt.c
++++ b/kernel/sched/rt.c
+@@ -1605,8 +1605,7 @@ static inline void set_next_task_rt(struct rq *rq, struct task_struct *p, bool f
+ rt_queue_push_tasks(rq);
+ }
+
+-static struct sched_rt_entity *pick_next_rt_entity(struct rq *rq,
+- struct rt_rq *rt_rq)
++static struct sched_rt_entity *pick_next_rt_entity(struct rt_rq *rt_rq)
+ {
+ struct rt_prio_array *array = &rt_rq->active;
+ struct sched_rt_entity *next = NULL;
+@@ -1628,7 +1627,7 @@ static struct task_struct *_pick_next_task_rt(struct rq *rq)
+ struct rt_rq *rt_rq = &rq->rt;
+
+ do {
+- rt_se = pick_next_rt_entity(rq, rt_rq);
++ rt_se = pick_next_rt_entity(rt_rq);
+ BUG_ON(!rt_se);
+ rt_rq = group_rt_rq(rt_se);
+ } while (rt_rq);
+--
+2.39.2
+
--- /dev/null
+From d80d945eea4fa7165e1a410111e0c4947075bd02 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 Jan 2023 13:22:16 +0100
+Subject: sched/fair: sanitize vruntime of entity being placed
+
+From: Zhang Qiao <zhangqiao22@huawei.com>
+
+[ Upstream commit 829c1651e9c4a6f78398d3e67651cef9bb6b42cc ]
+
+When a scheduling entity is placed onto cfs_rq, its vruntime is pulled
+to the base level (around cfs_rq->min_vruntime), so that the entity
+doesn't gain extra boost when placed backwards.
+
+However, if the entity being placed wasn't executed for a long time, its
+vruntime may get too far behind (e.g. while cfs_rq was executing a
+low-weight hog), which can inverse the vruntime comparison due to s64
+overflow. This results in the entity being placed with its original
+vruntime way forwards, so that it will effectively never get to the cpu.
+
+To prevent that, ignore the vruntime of the entity being placed if it
+didn't execute for much longer than the characteristic sheduler time
+scale.
+
+[rkagan: formatted, adjusted commit log, comments, cutoff value]
+Signed-off-by: Zhang Qiao <zhangqiao22@huawei.com>
+Co-developed-by: Roman Kagan <rkagan@amazon.de>
+Signed-off-by: Roman Kagan <rkagan@amazon.de>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lkml.kernel.org/r/20230130122216.3555094-1-rkagan@amazon.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/fair.c | 15 +++++++++++++--
+ 1 file changed, 13 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
+index c39d2fc3f9945..68166c599a355 100644
+--- a/kernel/sched/fair.c
++++ b/kernel/sched/fair.c
+@@ -4278,6 +4278,7 @@ static void
+ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial)
+ {
+ u64 vruntime = cfs_rq->min_vruntime;
++ u64 sleep_time;
+
+ /*
+ * The 'current' period is already promised to the current tasks,
+@@ -4302,8 +4303,18 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial)
+ vruntime -= thresh;
+ }
+
+- /* ensure we never gain time by being placed backwards. */
+- se->vruntime = max_vruntime(se->vruntime, vruntime);
++ /*
++ * Pull vruntime of the entity being placed to the base level of
++ * cfs_rq, to prevent boosting it if placed backwards. If the entity
++ * slept for a long time, don't even try to compare its vruntime with
++ * the base as it may be too far off and the comparison may get
++ * inversed due to s64 overflow.
++ */
++ sleep_time = rq_clock_task(rq_of(cfs_rq)) - se->exec_start;
++ if ((s64)sleep_time > 60LL * NSEC_PER_SEC)
++ se->vruntime = vruntime;
++ else
++ se->vruntime = max_vruntime(se->vruntime, vruntime);
+ }
+
+ static void check_enqueue_throttle(struct cfs_rq *cfs_rq);
+--
+2.39.2
+
--- /dev/null
+From ce14ced7d45457640d994ecfd98ff54fa9768fa3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Feb 2023 22:33:54 +0000
+Subject: sched/rt: pick_next_rt_entity(): check list_entry
+
+From: Pietro Borrello <borrello@diag.uniroma1.it>
+
+[ Upstream commit 7c4a5b89a0b5a57a64b601775b296abf77a9fe97 ]
+
+Commit 326587b84078 ("sched: fix goto retry in pick_next_task_rt()")
+removed any path which could make pick_next_rt_entity() return NULL.
+However, BUG_ON(!rt_se) in _pick_next_task_rt() (the only caller of
+pick_next_rt_entity()) still checks the error condition, which can
+never happen, since list_entry() never returns NULL.
+Remove the BUG_ON check, and instead emit a warning in the only
+possible error condition here: the queue being empty which should
+never happen.
+
+Fixes: 326587b84078 ("sched: fix goto retry in pick_next_task_rt()")
+Signed-off-by: Pietro Borrello <borrello@diag.uniroma1.it>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Phil Auld <pauld@redhat.com>
+Reviewed-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Link: https://lore.kernel.org/r/20230128-list-entry-null-check-sched-v3-1-b1a71bd1ac6b@diag.uniroma1.it
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/rt.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
+index e1ce5d1868b50..f690f901b6cc7 100644
+--- a/kernel/sched/rt.c
++++ b/kernel/sched/rt.c
+@@ -1616,6 +1616,8 @@ static struct sched_rt_entity *pick_next_rt_entity(struct rt_rq *rt_rq)
+ BUG_ON(idx >= MAX_RT_PRIO);
+
+ queue = array->queue + idx;
++ if (SCHED_WARN_ON(list_empty(queue)))
++ return NULL;
+ next = list_entry(queue->next, struct sched_rt_entity, run_list);
+
+ return next;
+@@ -1628,7 +1630,8 @@ static struct task_struct *_pick_next_task_rt(struct rq *rq)
+
+ do {
+ rt_se = pick_next_rt_entity(rt_rq);
+- BUG_ON(!rt_se);
++ if (unlikely(!rt_se))
++ return NULL;
+ rt_rq = group_rt_rq(rt_se);
+ } while (rt_rq);
+
+--
+2.39.2
+
--- /dev/null
+From 69e908b3c4b92e66630516044f127f07380127a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 28 Jan 2023 19:08:32 +0800
+Subject: scsi: aic94xx: Add missing check for dma_map_single()
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit 32fe45274edb5926abc0fac7263d9f889d02d9cf ]
+
+Add check for dma_map_single() and return error if it fails in order to
+avoid invalid DMA address.
+
+Fixes: 2908d778ab3e ("[SCSI] aic94xx: new driver")
+Link: https://lore.kernel.org/r/20230128110832.6792-1-jiasheng@iscas.ac.cn
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Reviewed-by: Jason Yan <yanaijie@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/aic94xx/aic94xx_task.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/scsi/aic94xx/aic94xx_task.c b/drivers/scsi/aic94xx/aic94xx_task.c
+index f923ed019d4a1..593b167ceefee 100644
+--- a/drivers/scsi/aic94xx/aic94xx_task.c
++++ b/drivers/scsi/aic94xx/aic94xx_task.c
+@@ -50,6 +50,9 @@ static int asd_map_scatterlist(struct sas_task *task,
+ dma_addr_t dma = dma_map_single(&asd_ha->pcidev->dev, p,
+ task->total_xfer_len,
+ task->data_dir);
++ if (dma_mapping_error(&asd_ha->pcidev->dev, dma))
++ return -ENOMEM;
++
+ sg_arr[0].bus_addr = cpu_to_le64((u64)dma);
+ sg_arr[0].size = cpu_to_le32(task->total_xfer_len);
+ sg_arr[0].flags |= ASD_SG_EL_LIST_EOL;
+--
+2.39.2
+
--- /dev/null
+From 02a77b501b9b5b798eb24c2abfe80ad1aa159eef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Feb 2023 16:21:59 +0100
+Subject: scsi: mpt3sas: Fix a memory leak
+
+From: Tomas Henzl <thenzl@redhat.com>
+
+[ Upstream commit 54dd96015e8d7a2a07359e2dfebf05b529d1780c ]
+
+Add a forgotten kfree().
+
+Fixes: dbec4c9040ed ("scsi: mpt3sas: lockless command submission")
+Link: https://lore.kernel.org/r/20230207152159.18627-1-thenzl@redhat.com
+Signed-off-by: Tomas Henzl <thenzl@redhat.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/mpt3sas/mpt3sas_base.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c
+index c1b76cda60dbc..2ad75c9a9088a 100644
+--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
++++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
+@@ -4905,6 +4905,9 @@ _base_release_memory_pools(struct MPT3SAS_ADAPTER *ioc)
+ }
+ dma_pool_destroy(ioc->pcie_sgl_dma_pool);
+ }
++ kfree(ioc->pcie_sg_lookup);
++ ioc->pcie_sg_lookup = NULL;
++
+ if (ioc->config_page) {
+ dexitprintk(ioc,
+ ioc_info(ioc, "config_page(0x%p): free\n",
+--
+2.39.2
+
--- /dev/null
+From 5218935670e8f4b4a5004cd14680ed41d0aa486a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Feb 2023 14:23:36 +0100
+Subject: sefltests: netdevsim: wait for devlink instance after netns removal
+
+From: Jiri Pirko <jiri@nvidia.com>
+
+[ Upstream commit f922c7b1c1c45740d329bf248936fdb78c0cff6e ]
+
+When devlink instance is put into network namespace and that network
+namespace gets deleted, devlink instance is moved back into init_ns.
+This is done as a part of cleanup_net() routine. Since cleanup_net()
+is called asynchronously from workqueue, there is no guarantee that
+the devlink instance move is done after "ip netns del" returns.
+
+So fix this race by making sure that the devlink instance is present
+before any other operation.
+
+Reported-by: Amir Tzin <amirtz@nvidia.com>
+Fixes: b74c37fd35a2 ("selftests: netdevsim: add tests for devlink reload with resources")
+Signed-off-by: Jiri Pirko <jiri@nvidia.com>
+Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
+Link: https://lore.kernel.org/r/20230220132336.198597-1-jiri@resnulli.us
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../selftests/drivers/net/netdevsim/devlink.sh | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+diff --git a/tools/testing/selftests/drivers/net/netdevsim/devlink.sh b/tools/testing/selftests/drivers/net/netdevsim/devlink.sh
+index 16d2de18591d3..2c81e01c30b31 100755
+--- a/tools/testing/selftests/drivers/net/netdevsim/devlink.sh
++++ b/tools/testing/selftests/drivers/net/netdevsim/devlink.sh
+@@ -16,6 +16,18 @@ SYSFS_NET_DIR=/sys/bus/netdevsim/devices/$DEV_NAME/net/
+ DEBUGFS_DIR=/sys/kernel/debug/netdevsim/$DEV_NAME/
+ DL_HANDLE=netdevsim/$DEV_NAME
+
++wait_for_devlink()
++{
++ "$@" | grep -q $DL_HANDLE
++}
++
++devlink_wait()
++{
++ local timeout=$1
++
++ busywait "$timeout" wait_for_devlink devlink dev
++}
++
+ fw_flash_test()
+ {
+ RET=0
+@@ -255,6 +267,9 @@ netns_reload_test()
+ ip netns del testns2
+ ip netns del testns1
+
++ # Wait until netns async cleanup is done.
++ devlink_wait 2000
++
+ log_test "netns reload test"
+ }
+
+@@ -347,6 +362,9 @@ resource_test()
+ ip netns del testns2
+ ip netns del testns1
+
++ # Wait until netns async cleanup is done.
++ devlink_wait 2000
++
+ log_test "resource test"
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 4adc1d26ab75a7f1438fed340c3d70d5b3e3ec9b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Feb 2023 12:04:00 +0100
+Subject: selftest: fib_tests: Always cleanup before exit
+
+From: Roxana Nicolescu <roxana.nicolescu@canonical.com>
+
+[ Upstream commit b60417a9f2b890a8094477b2204d4f73c535725e ]
+
+Usage of `set -e` before executing a command causes immediate exit
+on failure, without cleanup up the resources allocated at setup.
+This can affect the next tests that use the same resources,
+leading to a chain of failures.
+
+A simple fix is to always call cleanup function when the script exists.
+This approach is already used by other existing tests.
+
+Fixes: 1056691b2680 ("selftests: fib_tests: Make test results more verbose")
+Signed-off-by: Roxana Nicolescu <roxana.nicolescu@canonical.com>
+Link: https://lore.kernel.org/r/20230220110400.26737-2-roxana.nicolescu@canonical.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/fib_tests.sh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/tools/testing/selftests/net/fib_tests.sh b/tools/testing/selftests/net/fib_tests.sh
+index 0f3bf90e04d36..8f42e17db5d09 100755
+--- a/tools/testing/selftests/net/fib_tests.sh
++++ b/tools/testing/selftests/net/fib_tests.sh
+@@ -1773,6 +1773,8 @@ EOF
+ ################################################################################
+ # main
+
++trap cleanup EXIT
++
+ while getopts :t:pPhv o
+ do
+ case $o in
+--
+2.39.2
+
--- /dev/null
+From dc8447bbd773e647b5b2528e0032bbbeb3d85a8c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Feb 2023 00:12:11 +0100
+Subject: selftests/bpf: Fix out-of-srctree build
+
+From: Ilya Leoshkevich <iii@linux.ibm.com>
+
+[ Upstream commit 0b0757244754ea1d0721195c824770f5576e119e ]
+
+Building BPF selftests out of srctree fails with:
+
+ make: *** No rule to make target '/linux-build//ima_setup.sh', needed by 'ima_setup.sh'. Stop.
+
+The culprit is the rule that defines convenient shorthands like
+"make test_progs", which builds $(OUTPUT)/test_progs. These shorthands
+make sense only for binaries that are built though; scripts that live
+in the source tree do not end up in $(OUTPUT).
+
+Therefore drop $(TEST_PROGS) and $(TEST_PROGS_EXTENDED) from the rule.
+
+The issue exists for a while, but it became a problem only after commit
+d68ae4982cb7 ("selftests/bpf: Install all required files to run selftests"),
+which added dependencies on these scripts.
+
+Fixes: 03dcb78460c2 ("selftests/bpf: Add simple per-test targets to Makefile")
+Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Link: https://lore.kernel.org/bpf/20230208231211.283606-1-iii@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/Makefile | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
+index 1d91555333608..a845724e0906a 100644
+--- a/tools/testing/selftests/bpf/Makefile
++++ b/tools/testing/selftests/bpf/Makefile
+@@ -119,8 +119,6 @@ RESOLVE_BTFIDS := $(BUILD_DIR)/resolve_btfids/resolve_btfids
+ # NOTE: Semicolon at the end is critical to override lib.mk's default static
+ # rule for binaries.
+ $(notdir $(TEST_GEN_PROGS) \
+- $(TEST_PROGS) \
+- $(TEST_PROGS_EXTENDED) \
+ $(TEST_GEN_PROGS_EXTENDED) \
+ $(TEST_CUSTOM_PROGS)): %: $(OUTPUT)/% ;
+
+--
+2.39.2
+
--- /dev/null
+From 62b5efa1f0988c32193573901520782755dc3acf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 22 Jan 2023 08:32:50 +0900
+Subject: selftests/ftrace: Fix bash specific "==" operator
+
+From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+
+[ Upstream commit 1e6b485c922fbedf41d5a9f4e6449c5aeb923a32 ]
+
+Since commit a1d6cd88c897 ("selftests/ftrace: event_triggers: wait
+longer for test_event_enable") introduced bash specific "=="
+comparation operator, that test will fail when we run it on a
+posix-shell. `checkbashisms` warned it as below.
+
+possible bashism in ftrace/func_event_triggers.tc line 45 (should be 'b = a'):
+ if [ "$e" == $val ]; then
+
+This replaces it with "=".
+
+Fixes: a1d6cd88c897 ("selftests/ftrace: event_triggers: wait longer for test_event_enable")
+Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Reviewed-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../selftests/ftrace/test.d/ftrace/func_event_triggers.tc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc b/tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc
+index 27a68bbe778be..d9b8127950771 100644
+--- a/tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc
++++ b/tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc
+@@ -42,7 +42,7 @@ test_event_enabled() {
+
+ while [ $check_times -ne 0 ]; do
+ e=`cat $EVENT_ENABLE`
+- if [ "$e" == $val ]; then
++ if [ "$e" = $val ]; then
+ return 0
+ fi
+ sleep $SLEEP_TIME
+--
+2.39.2
+
--- /dev/null
+From 50659698a2e668c787af6c2e9eef408280add1f9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Feb 2023 13:43:40 +0100
+Subject: selftests/net: Interpret UDP_GRO cmsg data as an int value
+
+From: Jakub Sitnicki <jakub@cloudflare.com>
+
+[ Upstream commit 436864095a95fcc611c20c44a111985fa9848730 ]
+
+Data passed to user-space with a (SOL_UDP, UDP_GRO) cmsg carries an
+int (see udp_cmsg_recv), not a u16 value, as strace confirms:
+
+ recvmsg(8, {msg_name=...,
+ msg_iov=[{iov_base="\0\0..."..., iov_len=96000}],
+ msg_iovlen=1,
+ msg_control=[{cmsg_len=20, <-- sizeof(cmsghdr) + 4
+ cmsg_level=SOL_UDP,
+ cmsg_type=0x68}], <-- UDP_GRO
+ msg_controllen=24,
+ msg_flags=0}, 0) = 11200
+
+Interpreting the data as an u16 value won't work on big-endian platforms.
+Since it is too late to back out of this API decision [1], fix the test.
+
+[1]: https://lore.kernel.org/netdev/20230131174601.203127-1-jakub@cloudflare.com/
+
+Fixes: 3327a9c46352 ("selftests: add functionals test for UDP GRO")
+Suggested-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: Jakub Sitnicki <jakub@cloudflare.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>
+---
+ tools/testing/selftests/net/udpgso_bench_rx.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/tools/testing/selftests/net/udpgso_bench_rx.c b/tools/testing/selftests/net/udpgso_bench_rx.c
+index 4058c7451e70d..f35a924d4a303 100644
+--- a/tools/testing/selftests/net/udpgso_bench_rx.c
++++ b/tools/testing/selftests/net/udpgso_bench_rx.c
+@@ -214,11 +214,10 @@ static void do_verify_udp(const char *data, int len)
+
+ static int recv_msg(int fd, char *buf, int len, int *gso_size)
+ {
+- char control[CMSG_SPACE(sizeof(uint16_t))] = {0};
++ char control[CMSG_SPACE(sizeof(int))] = {0};
+ struct msghdr msg = {0};
+ struct iovec iov = {0};
+ struct cmsghdr *cmsg;
+- uint16_t *gsosizeptr;
+ int ret;
+
+ iov.iov_base = buf;
+@@ -237,8 +236,7 @@ static int recv_msg(int fd, char *buf, int len, int *gso_size)
+ cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+ if (cmsg->cmsg_level == SOL_UDP
+ && cmsg->cmsg_type == UDP_GRO) {
+- gsosizeptr = (uint16_t *) CMSG_DATA(cmsg);
+- *gso_size = *gsosizeptr;
++ *gso_size = *(int *)CMSG_DATA(cmsg);
+ break;
+ }
+ }
+--
+2.39.2
+
hid-asus-use-spinlock-to-protect-concurrent-accesses.patch
hid-asus-use-spinlock-to-safely-schedule-workers.patch
powerpc-mm-rearrange-if-else-block-to-avoid-clang-warning.patch
+arm-omap2-fix-memory-leak-in-realtime_counter_init.patch
+arm64-dts-qcom-qcs404-use-symbol-names-for-pcie-rese.patch
+arm-zynq-fix-refcount-leak-in-zynq_early_slcr_init.patch
+arm64-dts-mediatek-mt8183-fix-systimer-13-mhz-clock-.patch
+arm64-dts-qcom-sdm845-db845c-fix-audio-codec-interru.patch
+arm64-dts-qcom-sc7180-correct-spmi-bus-address-cells.patch
+arm64-dts-meson-gx-fix-ethernet-mac-address-unit-nam.patch
+arm64-dts-meson-g12a-fix-internal-ethernet-phy-unit-.patch
+arm64-dts-meson-gx-fix-the-scpi-dvfs-node-name-and-u.patch
+arm64-dts-qcom-ipq8074-correct-usb3-qmp-phy-s-clock-.patch
+arm64-dts-qcom-fix-ipq8074-pcie-phy-nodes.patch
+arm64-dts-qcom-ipq8074-fix-pcie-phy-serdes-size.patch
+arm64-dts-qcom-ipq8074-fix-gen3-pcie-qmp-phy.patch
+arm64-dts-qcom-ipq8074-correct-gen2-pcie-ranges.patch
+arm64-dts-qcom-ipq8074-fix-gen3-pcie-node.patch
+arm64-dts-qcom-ipq8074-correct-pcie-qmp-phy-output-c.patch
+arm64-dts-meson-remove-cpu-opps-below-1ghz-for-g12a-.patch
+arm-omap1-call-platform_device_put-in-error-case-in-.patch
+arm-s3c-fix-s3c64xx_set_timer_source-prototype.patch
+arm64-dts-ti-k3-j7200-fix-wakeup-pinmux-range.patch
+arm-dts-exynos-correct-wr-active-property-in-exynos3.patch
+arm-imx-call-ida_simple_remove-for-ida_simple_get.patch
+arm64-dts-amlogic-meson-gx-fix-scpi-clock-dvfs-node-.patch
+arm64-dts-amlogic-meson-axg-fix-scpi-clock-dvfs-node.patch
+arm64-dts-amlogic-meson-gx-add-missing-scpi-sensors-.patch
+arm64-dts-amlogic-meson-gxl-s905d-sml5442tw-drop-inv.patch
+arm64-dts-amlogic-meson-gx-add-missing-unit-address-.patch
+arm64-dts-amlogic-meson-gxl-add-missing-unit-address.patch
+arm64-dts-amlogic-meson-gx-libretech-pc-fix-update-b.patch
+arm64-dts-amlogic-meson-gxl-s905d-phicomm-n1-fix-led.patch
+arm64-dts-amlogic-meson-gxbb-kii-pro-fix-led-node-na.patch
+arm64-dts-renesas-beacon-renesom-fix-gpio-expander-r.patch
+arm-dts-sun8i-nanopi-duo2-fix-regulator-gpio-referen.patch
+arm-dts-imx7s-correct-iomuxc-gpr-mux-controller-cell.patch
+arm64-dts-mediatek-mt7622-add-missing-pwm-cells-to-p.patch
+blk-mq-avoid-sleep-in-blk_mq_alloc_request_hctx.patch
+blk-mq-remove-stale-comment-for-blk_mq_sched_mark_re.patch
+blk-mq-correct-stale-comment-of-.get_budget.patch
+s390-dasd-prepare-for-additional-path-event-handling.patch
+s390-dasd-fix-potential-memleak-in-dasd_eckd_init.patch
+sched-deadline-rt-remove-unused-parameter-from-pick_.patch
+sched-rt-pick_next_rt_entity-check-list_entry.patch
+x86-perf-zhaoxin-add-stepping-check-for-zxc.patch
+block-bio-integrity-copy-flags-when-bio_integrity_pa.patch
+wifi-rsi-fix-memory-leak-in-rsi_coex_attach.patch
+wifi-rtlwifi-rtl8821ae-don-t-call-kfree_skb-under-sp.patch
+wifi-rtlwifi-rtl8188ee-don-t-call-kfree_skb-under-sp.patch
+wifi-rtlwifi-rtl8723be-don-t-call-kfree_skb-under-sp.patch
+wifi-iwlegacy-common-don-t-call-dev_kfree_skb-under-.patch
+wifi-libertas-fix-memory-leak-in-lbs_init_adapter.patch
+wifi-rtl8xxxu-don-t-call-dev_kfree_skb-under-spin_lo.patch
+rtlwifi-fix-wpointer-sign-warning.patch
+wifi-rtlwifi-fix-global-out-of-bounds-bug-in-_rtl881.patch
+libbpf-fix-btf__align_of-by-taking-into-account-fiel.patch
+wifi-ipw2x00-don-t-call-dev_kfree_skb-under-spin_loc.patch
+wifi-ipw2200-fix-memory-leak-in-ipw_wdev_init.patch
+wifi-wilc1000-fix-potential-memory-leak-in-wilc_mac_.patch
+wifi-brcmfmac-fix-potential-memory-leak-in-brcmf_net.patch
+wifi-brcmfmac-unmap-dma-buffer-in-brcmf_msgbuf_alloc.patch
+wifi-libertas_tf-don-t-call-kfree_skb-under-spin_loc.patch
+wifi-libertas-if_usb-don-t-call-kfree_skb-under-spin.patch
+wifi-libertas-main-don-t-call-kfree_skb-under-spin_l.patch
+wifi-libertas-cmdresp-don-t-call-kfree_skb-under-spi.patch
+wifi-wl3501_cs-don-t-call-kfree_skb-under-spin_lock_.patch
+crypto-x86-ghash-fix-unaligned-access-in-ghash_setke.patch
+acpica-drop-port-i-o-validation-for-some-regions.patch
+genirq-fix-the-return-type-of-kstat_cpu_irqs_sum.patch
+rcu-tasks-improve-comments-explaining-tasks_rcu_exit.patch
+rcu-tasks-remove-preemption-disablement-around-srcu_.patch
+rcu-tasks-fix-synchronize_rcu_tasks-vs-zap_pid_ns_pr.patch
+lib-mpi-fix-buffer-overrun-when-sg-is-too-long.patch
+crypto-ccp-use-the-stack-for-small-sev-command-buffe.patch
+crypto-ccp-use-the-stack-and-common-buffer-for-statu.patch
+crypto-ccp-use-kzalloc-for-sev-ioctl-interfaces-to-p.patch
+crypto-ccp-avoid-page-allocation-failure-warning-for.patch
+acpica-nsrepair-handle-cases-without-a-return-value-.patch
+thermal-drivers-tsens-drop-msm8976-specific-defines.patch
+thermal-drivers-qcom-tsens_v1-enable-sensor-3-on-msm.patch
+thermal-drivers-tsens-add-compat-string-for-the-qcom.patch
+thermal-drivers-tsens-sort-out-msm8976-vs-msm8956-da.patch
+wifi-rtl8xxxu-fix-memory-leaks-with-rtl8723bu-rtl819.patch
+wifi-orinoco-check-return-value-of-hermes_write_word.patch
+wifi-ath9k-htc_hst-free-skb-in-ath9k_htc_rx_msg-if-t.patch
+ath9k-hif_usb-simplify-if-if-to-if-else.patch
+ath9k-htc-clean-up-statistics-macros.patch
+wifi-ath9k-hif_usb-clean-up-skbs-if-ath9k_hif_usb_rx.patch
+wifi-ath9k-fix-potential-stack-out-of-bounds-write-i.patch
+wifi-ath11k-fix-memory-leak-in-ath11k_peer_rx_frag_s.patch
+wifi-cfg80211-fix-extended-kck-key-length-check-in-n.patch
+acpi-battery-fix-missing-nul-termination-with-large-.patch
+crypto-ccp-failure-on-re-initialization-due-to-dupli.patch
+crypto-essiv-handle-ebusy-correctly.patch
+crypto-seqiv-handle-ebusy-correctly.patch
+powercap-fix-possible-name-leak-in-powercap_register.patch
+x86-cpu-init-ap-exception-handling-from-cpu_init_sec.patch
+x86-microcode-replace-deprecated-cpu-hotplug-functio.patch
+x86-mark-stop_this_cpu-__noreturn.patch
+x86-microcode-rip-out-the-old_interface.patch
+x86-microcode-default-disable-late-loading.patch
+x86-microcode-print-previous-version-of-microcode-af.patch
+x86-microcode-add-a-parameter-to-microcode_check-to-.patch
+x86-microcode-check-cpu-capabilities-after-late-micr.patch
+x86-microcode-adjust-late-loading-result-reporting-m.patch
+net-ethernet-ti-am65-cpsw-fix-tx-csum-offload-for-mu.patch
+net-ethernet-ti-am65-cpsw-handle-deferred-probe-with.patch
+net-ethernet-ti-add-missing-of_node_put-before-retur.patch
+crypto-xts-handle-ebusy-correctly.patch
+leds-led-class-add-missing-put_device-to-led_put.patch
+crypto-ccp-refactor-out-sev_fw_alloc.patch
+crypto-ccp-flush-the-sev-es-tmr-memory-before-giving.patch
+bpftool-profile-online-cpus-instead-of-possible.patch
+net-mlx5-enhance-debug-print-in-page-allocation-fail.patch
+irqchip-fix-refcount-leak-in-platform_irqchip_probe.patch
+irqchip-alpine-msi-fix-refcount-leak-in-alpine_msix_.patch
+irqchip-irq-mvebu-gicp-fix-refcount-leak-in-mvebu_gi.patch
+irqchip-ti-sci-fix-refcount-leak-in-ti_sci_intr_irq_.patch
+s390-vmem-fix-empty-page-tables-cleanup-under-kasan.patch
+net-add-sock_init_data_uid.patch
+tun-tun_chr_open-correctly-initialize-socket-uid.patch
+tap-tap_open-correctly-initialize-socket-uid.patch
+opp-fix-error-checking-in-opp_migrate_dentry.patch
+bluetooth-l2cap-fix-potential-user-after-free.patch
+libbpf-fix-alen-calculation-in-libbpf_nla_dump_error.patch
+rds-rds_rm_zerocopy_callback-correct-order-for-list_.patch
+crypto-rsa-pkcs1pad-use-akcipher_request_complete.patch
+m68k-proc-hardware-should-depend-on-proc_fs.patch
+risc-v-time-initialize-hrtimer-based-broadcast-clock.patch
+wifi-iwl3945-add-missing-check-for-create_singlethre.patch
+wifi-iwl4965-add-missing-check-for-create_singlethre.patch
+wifi-mwifiex-fix-loop-iterator-in-mwifiex_update_amp.patch
+selftests-bpf-fix-out-of-srctree-build.patch
+crypto-crypto4xx-call-dma_unmap_page-when-done.patch
+wifi-mac80211-make-rate-u32-in-sta_set_rate_info_rx.patch
+thermal-drivers-hisi-drop-second-sensor-hi3660.patch
+can-esd_usb-move-mislocated-storage-of-sja1000_ecc_s.patch
+bpf-fix-global-subprog-context-argument-resolution-l.patch
+irqchip-irq-brcmstb-l2-set-irq_level-for-level-trigg.patch
+irqchip-irq-bcm7120-l2-set-irq_level-for-level-trigg.patch
+selftests-net-interpret-udp_gro-cmsg-data-as-an-int-.patch
+l2tp-avoid-possible-recursive-deadlock-in-l2tp_tunne.patch
+net-bcmgenet-fix-moca-led-control.patch
+selftest-fib_tests-always-cleanup-before-exit.patch
+sefltests-netdevsim-wait-for-devlink-instance-after-.patch
+drm-fix-potential-null-ptr-deref-due-to-drmm_mode_co.patch
+drm-fourcc-add-missing-big-endian-xrgb1555-and-rgb56.patch
+drm-mxsfb-drm_mxsfb-should-depend-on-arch_mxs-arch_m.patch
+drm-bridge-megachips-fix-error-handling-in-i2c_regis.patch
+drm-vkms-fix-null-ptr-deref-in-vkms_release.patch
+drm-vc4-dpi-add-option-for-inverting-pixel-clock-and.patch
+drm-vc4-dpi-fix-format-mapping-for-rgb565.patch
+drm-tidss-fix-pixel-format-definition.patch
+gpu-ipu-v3-common-add-of_node_put-for-reference-retu.patch
+drm-msm-hdmi-add-missing-check-for-alloc_ordered_wor.patch
+pinctrl-qcom-pinctrl-msm8976-correct-function-names-.patch
+pinctrl-stm32-fix-refcount-leak-in-stm32_pctrl_get_i.patch
+pinctrl-rockchip-add-support-for-rk3568.patch
+pinctrl-rockchip-do-coding-style-for-mux-route-struc.patch
+pinctrl-rockchip-fix-refcount-leak-in-rockchip_pinct.patch
+drm-vc4-hvs-set-axi-panic-modes.patch
+drm-vc4-hvs-fix-colour-order-for-xrgb1555-on-hvs5.patch
+drm-vc4-hdmi-correct-interlaced-timings-again.patch
+asoc-fsl_sai-initialize-is_dsp_mode-flag.patch
+drm-msm-adreno-fix-null-ptr-access-in-adreno_gpu_cle.patch
+alsa-hda-ca0132-minor-fix-for-allocation-size.patch
+drm-msm-dpu-disallow-unallocated-resources-to-be-ret.patch
+drm-bridge-lt9611-fix-sleep-mode-setup.patch
+drm-bridge-lt9611-fix-hpd-reenablement.patch
+drm-bridge-lt9611-fix-polarity-programming.patch
+drm-bridge-lt9611-fix-programming-of-video-modes.patch
+drm-bridge-lt9611-fix-clock-calculation.patch
+drm-bridge-lt9611-pass-a-pointer-to-the-of-node.patch
+drm-mipi-dsi-fix-byte-order-of-16-bit-dcs-set-get-br.patch
+drm-msm-use-strscpy-instead-of-strncpy.patch
+drm-msm-dpu-add-check-for-cstate.patch
+drm-msm-dpu-add-check-for-pstates.patch
+drm-msm-mdp5-add-check-for-kzalloc.patch
+pinctrl-bcm2835-remove-of_node_put-in-bcm2835_of_gpi.patch
+pinctrl-mediatek-initialize-variable-pullen-and-pull.patch
+pinctrl-mediatek-initialize-variable-buf-to-zero.patch
+gpu-host1x-don-t-skip-assigning-syncpoints-to-channe.patch
+drm-mediatek-dsi-reduce-the-time-of-dsi-from-lp11-to.patch
+drm-mediatek-use-null-instead-of-0-for-null-pointer.patch
+drm-mediatek-drop-unbalanced-obj-unref.patch
+drm-mediatek-mtk_drm_crtc-add-checks-for-devm_kcallo.patch
+drm-mediatek-clean-dangling-pointer-on-bind-error-pa.patch
+asoc-soc-compress.c-fixup-private_data-on-snd_soc_ne.patch
+gpio-vf610-connect-gpio-label-to-dev-name.patch
+spi-dw_bt1-fix-mux_mmio-dependencies.patch
+asoc-mchp-spdifrx-fix-controls-which-rely-on-rsr-reg.patch
+asoc-atmel-fix-spelling-mistakes.patch
+asoc-mchp-spdifrx-fix-return-value-in-case-completio.patch
+asoc-mchp-spdifrx-fix-controls-that-works-with-compl.patch
+asoc-mchp-spdifrx-disable-all-interrupts-in-mchp_spd.patch
+asoc-mchp-spdifrx-fix-uninitialized-use-of-mr-in-mch.patch
+asoc-dt-bindings-meson-fix-gx-card-codec-node-regex.patch
+hwmon-ltc2945-handle-error-case-in-ltc2945_value_sto.patch
+drm-amdgpu-fix-enum-odm_combine_mode-mismatch.patch
+scsi-mpt3sas-fix-a-memory-leak.patch
+scsi-aic94xx-add-missing-check-for-dma_map_single.patch
+spi-bcm63xx-hsspi-endianness-fix-for-arm-based-soc.patch
+spi-bcm63xx-hsspi-fix-pm_runtime.patch
+spi-bcm63xx-hsspi-fix-multi-bit-mode-setting.patch
+hwmon-mlxreg-fan-return-zero-speed-for-broken-fan.patch
+asoc-tlv320adcx140-fix-ti-gpio-config-dt-property-in.patch
+dm-remove-flush_scheduled_work-during-local_exit.patch
+nfs-fix-up-handling-of-outstanding-layoutcommit-in-n.patch
+nfsv4-keep-state-manager-thread-active-if-swap-is-en.patch
+nfs4trace-fix-state-manager-flag-printing.patch
+nfs-fix-disabling-of-swap.patch
+spi-synquacer-fix-timeout-handling-in-synquacer_spi_.patch
+asoc-soc-dapm.h-fixup-warning-struct-snd_pcm_substre.patch
+hid-bigben-use-spinlock-to-protect-concurrent-access.patch
+hid-bigben_worker-remove-unneeded-check-on-report_fi.patch
+hid-bigben-use-spinlock-to-safely-schedule-workers.patch
+hid-bigben_probe-validate-report-count.patch
+nfsd-fix-race-to-check-ls_layouts.patch
+cifs-fix-lost-destroy-smbd-connection-when-mr-alloca.patch
+cifs-fix-warning-and-uaf-when-destroy-the-mr-list.patch
+gfs2-jdata-writepage-fix.patch
+perf-llvm-fix-inadvertent-file-creation.patch
+leds-led-core-fix-refcount-leak-in-of_led_get.patch
+perf-tools-fix-auto-complete-on-aarch64.patch
+sparc-allow-pm-configs-for-sparc32-compile_test.patch
+selftests-ftrace-fix-bash-specific-operator.patch
+printf-fix-errname.c-list.patch
+objtool-add-uaccess-exceptions-for-__tsan_volatile_r.patch
+mfd-pcf50633-adc-fix-potential-memleak-in-pcf50633_a.patch
+clk-qcom-gcc-qcs404-disable-gpll-04-_out_aux-parents.patch
+clk-qcom-gcc-qcs404-fix-names-of-the-dsi-clocks-used.patch
+risc-v-fix-funct4-definition-for-c.jalr-in-parse_asm.patch
+mtd-rawnand-sunxi-fix-the-size-of-the-last-oob-regio.patch
+input-iqs269a-drop-unused-device-node-references.patch
+input-iqs269a-increase-interrupt-handler-return-dela.patch
+input-iqs269a-configure-device-with-a-single-block-w.patch
+linux-kconfig.h-replace-if_enabled-with-ptr_if-in-li.patch
+clk-renesas-cpg-mssr-fix-use-after-free-if-cpg_mssr_.patch
+clk-renesas-cpg-mssr-remove-superfluous-check-in-res.patch
+clk-imx-avoid-memory-leak.patch
+input-ads7846-don-t-report-pressure-for-ads7845.patch
+input-ads7846-convert-to-full-duplex.patch
+input-ads7846-convert-to-one-message.patch
+input-ads7846-always-set-last-command-to-pwrdown.patch
+input-ads7846-don-t-check-penirq-immediately-for-784.patch
+mtd-rawnand-fsl_elbc-propagate-hw-ecc-settings-to-hw.patch
+clk-qcom-gpucc-sc7180-fix-clk_dis_wait-being-program.patch
+clk-qcom-gpucc-sdm845-fix-clk_dis_wait-being-program.patch
+powerpc-powernv-ioda-skip-unallocated-resources-when.patch
+clk-honor-clk_ops_parent_enable-in-clk_core_is_enabl.patch
+powerpc-perf-hv-24x7-add-missing-rtas-retry-status-h.patch
+powerpc-pseries-lpar-add-missing-rtas-retry-status-h.patch
+powerpc-pseries-lparcfg-add-missing-rtas-retry-statu.patch
+powerpc-rtas-make-all-exports-gpl.patch
+powerpc-rtas-ensure-4kb-alignment-for-rtas_data_buf.patch
+powerpc-eeh-small-refactor-of-eeh_handle_normal_even.patch
+powerpc-eeh-set-channel-state-after-notifying-the-dr.patch
+mips-smp-cps-fix-build-error-when-hotplug_cpu-not-se.patch
+mips-vpe-mt-drop-physical_memsize.patch
+vdpa-mlx5-don-t-clear-mr-struct-on-destroy-mr.patch
+alpha-boot-tools-objstrip-fix-the-check-for-elf-head.patch
+input-iqs269a-do-not-poll-during-suspend-or-resume.patch
+input-iqs269a-do-not-poll-during-ati.patch
+remoteproc-qcom_q6v5_mss-use-a-carveout-to-authentic.patch
+media-ti-cal-fix-possible-memory-leak-in-cal_ctx_cre.patch
+media-platform-ti-add-missing-check-for-devm_regulat.patch
+powerpc-remove-linker-flag-from-kbuild_aflags.patch
+builddeb-clean-generated-package-content.patch
+media-max9286-fix-memleak-in-max9286_v4l2_register.patch
+media-ov2740-fix-memleak-in-ov2740_init_controls.patch
+media-ov5675-fix-memleak-in-ov5675_init_controls.patch
+media-i2c-ov772x-fix-memleak-in-ov772x_probe.patch
+media-i2c-imx219-remove-redundant-writes.patch
+media-i2c-imx219-split-common-registers-from-mode-ta.patch
+media-i2c-imx219-fix-binning-for-raw8-capture.patch
+media-rc-fix-use-after-free-bugs-caused-by-ene_tx_ir.patch
+media-i2c-ov7670-0-instead-of-einval-was-returned.patch
+media-usb-siano-fix-use-after-free-bugs-caused-by-do.patch
+media-saa7134-use-video_unregister_device-for-radio_.patch
+rpmsg-glink-avoid-infinite-loop-on-intent-for-missin.patch
+udf-define-efscorrupted-error-code.patch
+arm-dts-exynos-use-exynos5420-compatible-for-the-mip.patch
+blk-iocost-fix-divide-by-0-error-in-calc_lcoefs.patch
+sched-fair-sanitize-vruntime-of-entity-being-placed.patch
+wifi-ath9k-fix-use-after-free-in-ath9k_hif_usb_disco.patch
+wifi-brcmfmac-fix-potential-stack-out-of-bounds-in-b.patch
+rcu-make-rcu_lockdep_warn-avoid-early-lockdep-checks.patch
+rcu-suppress-smp_processor_id-complaint-in-synchroni.patch
+rcu-tasks-make-rude-rcu-tasks-work-well-with-cpu-hot.patch
+wifi-ath11k-debugfs-fix-to-work-with-multiple-pci-de.patch
+thermal-intel-fix-unsigned-comparison-with-less-than.patch
+timers-prevent-union-confusion-from-unexpected-resta.patch
+x86-bugs-reset-speculation-control-settings-on-init.patch
+wifi-brcmfmac-ensure-clm-version-is-null-terminated-.patch
+wifi-mt7601u-fix-an-integer-underflow.patch
+inet-fix-fast-path-in-__inet_hash_connect.patch
+ice-add-missing-checks-for-pf-vsi-type.patch
+acpi-don-t-build-acpica-with-os.patch
+clocksource-suspend-the-watchdog-temporarily-when-hi.patch
+crypto-hisilicon-wipe-entire-pool-on-error.patch
+net-bcmgenet-add-a-check-for-oversized-packets.patch
+m68k-check-syscall_trace_enter-return-code.patch
+wifi-mt76-dma-free-rx_head-in-mt76_dma_rx_cleanup.patch
+acpi-video-fix-lenovo-ideapad-z570-dmi-match.patch
+net-mlx5-fw_tracer-fix-debug-print.patch
+coda-avoid-partial-allocation-of-sig_inputargs.patch
+uaccess-add-minimum-bounds-check-on-kernel-buffer-si.patch
+pm-em-fix-memory-leak-with-using-debugfs_lookup.patch
+bluetooth-btusb-add-vid-pid-13d3-3529-for-realtek-rt.patch
+drm-amd-display-fix-potential-null-deref-in-dm_resum.patch
+drm-omap-dsi-fix-excessive-stack-usage.patch
+hid-add-mapping-for-system-microphone-mute.patch
+drm-tiny-ili9486-do-not-assume-8-bit-only-spi-contro.patch
+drm-radeon-free-iio-for-atombios-when-driver-shutdow.patch
+drm-amd-display-fix-memory-leakage.patch
+drm-msm-dsi-add-missing-check-for-alloc_ordered_work.patch
+docs-scripts-gdb-add-necessary-make-scripts_gdb-step.patch
+asoc-kirkwood-iterate-over-array-indexes-instead-of-.patch
+regulator-max77802-bounds-check-regulator-id-against.patch
+regulator-s5m8767-bounds-check-id-indexing-into-arra.patch
+gfs2-improve-gfs2_make_fs_rw-error-handling.patch
+hwmon-coretemp-simplify-platform-device-handling.patch
+pinctrl-at91-use-devm_kasprintf-to-avoid-potential-l.patch
+hid-logitech-hidpp-don-t-restart-communication-if-no.patch
+drm-panel-orientation-quirks-add-quirk-for-lenovo-id.patch
+dm-thin-add-cond_resched-to-various-workqueue-loops.patch
+dm-cache-add-cond_resched-to-various-workqueue-loops.patch
+nfsd-zero-out-pointers-after-putting-nfsd_files-on-c.patch
--- /dev/null
+From 8532e89c1c8d339b1fa75c63366d2d485d614795 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 4 Feb 2023 16:43:57 -0800
+Subject: sparc: allow PM configs for sparc32 COMPILE_TEST
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit 7be6a87c2473957090995b7eb541e31d57a2c801 ]
+
+When doing randconfig builds for sparc32 with COMPILE_TEST, some
+(non-Sparc) drivers cause kconfig warnings with the Kconfig symbols PM,
+PM_GENERIC_DOMAINS, or PM_GENERIC_DOMAINS_OF.
+
+This is due to arch/sparc/Kconfig not using the PM Kconfig for
+Sparc32:
+
+ if SPARC64
+ source "kernel/power/Kconfig"
+ endif
+
+Arnd suggested adding "|| COMPILE_TEST" to the conditional,
+instead of trying to track down every driver that selects
+any of these PM symbols.
+
+Fixes the following kconfig warnings:
+
+WARNING: unmet direct dependencies detected for PM
+ Depends on [n]: SPARC64 [=n]
+ Selected by [y]:
+ - SUN20I_PPU [=y] && (ARCH_SUNXI || COMPILE_TEST [=y])
+
+WARNING: unmet direct dependencies detected for PM
+ Depends on [n]: SPARC64 [=n]
+ Selected by [y]:
+ - SUN20I_PPU [=y] && (ARCH_SUNXI || COMPILE_TEST [=y])
+
+WARNING: unmet direct dependencies detected for PM_GENERIC_DOMAINS
+ Depends on [n]: SPARC64 [=n] && PM [=y]
+ Selected by [y]:
+ - QCOM_GDSC [=y] && COMMON_CLK [=y] && PM [=y]
+ - SUN20I_PPU [=y] && (ARCH_SUNXI || COMPILE_TEST [=y])
+ - MESON_GX_PM_DOMAINS [=y] && (ARCH_MESON || COMPILE_TEST [=y]) && PM [=y] && OF [=y]
+ - BCM2835_POWER [=y] && (ARCH_BCM2835 || COMPILE_TEST [=y] && OF [=y]) && PM [=y]
+ - BCM_PMB [=y] && (ARCH_BCMBCA || COMPILE_TEST [=y] && OF [=y]) && PM [=y]
+ - ROCKCHIP_PM_DOMAINS [=y] && (ARCH_ROCKCHIP || COMPILE_TEST [=y]) && PM [=y]
+ Selected by [m]:
+ - ARM_SCPI_POWER_DOMAIN [=m] && (ARM_SCPI_PROTOCOL [=m] || COMPILE_TEST [=y] && OF [=y]) && PM [=y]
+ - MESON_EE_PM_DOMAINS [=m] && (ARCH_MESON || COMPILE_TEST [=y]) && PM [=y] && OF [=y]
+ - QCOM_AOSS_QMP [=m] && (ARCH_QCOM || COMPILE_TEST [=y]) && MAILBOX [=y] && COMMON_CLK [=y] && PM [=y]
+
+WARNING: unmet direct dependencies detected for PM_GENERIC_DOMAINS_OF
+ Depends on [n]: SPARC64 [=n] && PM_GENERIC_DOMAINS [=y] && OF [=y]
+ Selected by [y]:
+ - MESON_GX_PM_DOMAINS [=y] && (ARCH_MESON || COMPILE_TEST [=y]) && PM [=y] && OF [=y]
+ Selected by [m]:
+ - MESON_EE_PM_DOMAINS [=m] && (ARCH_MESON || COMPILE_TEST [=y]) && PM [=y] && OF [=y]
+
+Link: https://lkml.kernel.org/r/20230205004357.29459-1-rdunlap@infradead.org
+Fixes: bdde6b3c8ba4 ("sparc64: Hibernation support")
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Suggested-by: Arnd Bergmann <arnd@arndb.de>
+Acked-by: Sam Ravnborg <sam@ravnborg.org>
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: Kirill Tkhai <tkhai@yandex.ru>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/sparc/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
+index 530b7ec5d3ca9..b5ed893420591 100644
+--- a/arch/sparc/Kconfig
++++ b/arch/sparc/Kconfig
+@@ -293,7 +293,7 @@ config FORCE_MAX_ZONEORDER
+ This config option is actually maximum order plus one. For example,
+ a value of 13 means that the largest free memory block is 2^12 pages.
+
+-if SPARC64
++if SPARC64 || COMPILE_TEST
+ source "kernel/power/Kconfig"
+ endif
+
+--
+2.39.2
+
--- /dev/null
+From fc3dd7aee110274dc3d76f77714fea9dadf77d5e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Feb 2023 22:58:17 -0800
+Subject: spi: bcm63xx-hsspi: Endianness fix for ARM based SoC
+
+From: William Zhang <william.zhang@broadcom.com>
+
+[ Upstream commit 85a84a61699990db6a025b5073f337f49933a875 ]
+
+HSSPI controller uses big endian for the opcode in the message to the
+controller ping pong buffer. Use cpu_to_be16 to properly handle the
+endianness for both big and little endian host.
+
+Fixes: 142168eba9dc ("spi: bcm63xx-hsspi: add bcm63xx HSSPI driver")
+Signed-off-by: Kursad Oney <kursad.oney@broadcom.com>
+Signed-off-by: William Zhang <william.zhang@broadcom.com>
+Acked-by: Florian Fainelli <f.fainelli@gmail.com>
+
+Link: https://lore.kernel.org/r/20230207065826.285013-7-william.zhang@broadcom.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-bcm63xx-hsspi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-bcm63xx-hsspi.c b/drivers/spi/spi-bcm63xx-hsspi.c
+index 1f08d7553f079..f591a543b1d07 100644
+--- a/drivers/spi/spi-bcm63xx-hsspi.c
++++ b/drivers/spi/spi-bcm63xx-hsspi.c
+@@ -193,7 +193,7 @@ static int bcm63xx_hsspi_do_txrx(struct spi_device *spi, struct spi_transfer *t)
+ tx += curr_step;
+ }
+
+- __raw_writew(opcode | curr_step, bs->fifo);
++ __raw_writew((u16)cpu_to_be16(opcode | curr_step), bs->fifo);
+
+ /* enable interrupt */
+ __raw_writel(HSSPI_PINGx_CMD_DONE(0),
+--
+2.39.2
+
--- /dev/null
+From ff337383f57ad3b6dcf911e933b2a0f85219575e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Feb 2023 12:02:41 -0800
+Subject: spi: bcm63xx-hsspi: Fix multi-bit mode setting
+
+From: William Zhang <william.zhang@broadcom.com>
+
+[ Upstream commit 811ff802aaf878ebbbaeac0307a0164fa21e7d40 ]
+
+Currently the driver always sets the controller to dual data bit mode
+for both tx and rx data in the profile mode control register even for
+single data bit transfer. Luckily the opcode is set correctly according
+to SPI transfer data bit width so it does not actually cause issues.
+
+This change fixes the problem by setting tx and rx data bit mode field
+correctly according to the actual SPI transfer tx and rx data bit width.
+
+Fixes: 142168eba9dc ("spi: bcm63xx-hsspi: add bcm63xx HSSPI driver")
+Signed-off-by: William Zhang <william.zhang@broadcom.com>
+Link: https://lore.kernel.org/r/20230209200246.141520-11-william.zhang@broadcom.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-bcm63xx-hsspi.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/spi/spi-bcm63xx-hsspi.c b/drivers/spi/spi-bcm63xx-hsspi.c
+index a74345ed0e2ff..9ec33745c1472 100644
+--- a/drivers/spi/spi-bcm63xx-hsspi.c
++++ b/drivers/spi/spi-bcm63xx-hsspi.c
+@@ -163,6 +163,7 @@ static int bcm63xx_hsspi_do_txrx(struct spi_device *spi, struct spi_transfer *t)
+ int step_size = HSSPI_BUFFER_LEN;
+ const u8 *tx = t->tx_buf;
+ u8 *rx = t->rx_buf;
++ u32 val = 0;
+
+ bcm63xx_hsspi_set_clk(bs, spi, t->speed_hz);
+ bcm63xx_hsspi_set_cs(bs, spi->chip_select, true);
+@@ -178,11 +179,16 @@ static int bcm63xx_hsspi_do_txrx(struct spi_device *spi, struct spi_transfer *t)
+ step_size -= HSSPI_OPCODE_LEN;
+
+ if ((opcode == HSSPI_OP_READ && t->rx_nbits == SPI_NBITS_DUAL) ||
+- (opcode == HSSPI_OP_WRITE && t->tx_nbits == SPI_NBITS_DUAL))
++ (opcode == HSSPI_OP_WRITE && t->tx_nbits == SPI_NBITS_DUAL)) {
+ opcode |= HSSPI_OP_MULTIBIT;
+
+- __raw_writel(1 << MODE_CTRL_MULTIDATA_WR_SIZE_SHIFT |
+- 1 << MODE_CTRL_MULTIDATA_RD_SIZE_SHIFT | 0xff,
++ if (t->rx_nbits == SPI_NBITS_DUAL)
++ val |= 1 << MODE_CTRL_MULTIDATA_RD_SIZE_SHIFT;
++ if (t->tx_nbits == SPI_NBITS_DUAL)
++ val |= 1 << MODE_CTRL_MULTIDATA_WR_SIZE_SHIFT;
++ }
++
++ __raw_writel(val | 0xff,
+ bs->regs + HSSPI_PROFILE_MODE_CTRL_REG(chip_select));
+
+ while (pending > 0) {
+--
+2.39.2
+
--- /dev/null
+From 6dffc5e73a3f9e1cd31bc123ad75fa03bdb3a8fb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Feb 2021 16:18:51 +0100
+Subject: spi: bcm63xx-hsspi: fix pm_runtime
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Álvaro Fernández Rojas <noltari@gmail.com>
+
+[ Upstream commit 216e8e80057a9f0b6366327881acf88eaf9f1fd4 ]
+
+The driver sets auto_runtime_pm to true, but it doesn't call
+pm_runtime_enable(), which results in "Failed to power device" when PM support
+is enabled.
+
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Link: https://lore.kernel.org/r/20210223151851.4110-3-noltari@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 811ff802aaf8 ("spi: bcm63xx-hsspi: Fix multi-bit mode setting")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-bcm63xx-hsspi.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-bcm63xx-hsspi.c b/drivers/spi/spi-bcm63xx-hsspi.c
+index f591a543b1d07..a74345ed0e2ff 100644
+--- a/drivers/spi/spi-bcm63xx-hsspi.c
++++ b/drivers/spi/spi-bcm63xx-hsspi.c
+@@ -21,6 +21,7 @@
+ #include <linux/mutex.h>
+ #include <linux/of.h>
+ #include <linux/reset.h>
++#include <linux/pm_runtime.h>
+
+ #define HSSPI_GLOBAL_CTRL_REG 0x0
+ #define GLOBAL_CTRL_CS_POLARITY_SHIFT 0
+@@ -439,13 +440,17 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev)
+ if (ret)
+ goto out_put_master;
+
++ pm_runtime_enable(&pdev->dev);
++
+ /* register and we are done */
+ ret = devm_spi_register_master(dev, master);
+ if (ret)
+- goto out_put_master;
++ goto out_pm_disable;
+
+ return 0;
+
++out_pm_disable:
++ pm_runtime_disable(&pdev->dev);
+ out_put_master:
+ spi_master_put(master);
+ out_disable_pll_clk:
+--
+2.39.2
+
--- /dev/null
+From e824d96472a1b4c33c44d9da355d1c46b3415ef8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 Jan 2023 15:01:40 +0100
+Subject: spi: dw_bt1: fix MUX_MMIO dependencies
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit d4bde04318c0d33705e9a77d4c7df72f262011e0 ]
+
+Selecting a symbol with additional dependencies requires
+adding the same dependency here:
+
+WARNING: unmet direct dependencies detected for MUX_MMIO
+ Depends on [n]: MULTIPLEXER [=y] && OF [=n]
+ Selected by [y]:
+ - SPI_DW_BT1 [=y] && SPI [=y] && SPI_MASTER [=y] && SPI_DESIGNWARE [=y] && (MIPS_BAIKAL_T1 || COMPILE_TEST [=y])
+
+Drop the 'select' here to avoid the problem. Anyone using
+the dw-bt1 SPI driver should make sure they include the
+mux driver as well now.
+
+Fixes: 7218838109fe ("spi: dw-bt1: Fix undefined devm_mux_control_get symbol")
+Fixes: abf00907538e ("spi: dw: Add Baikal-T1 SPI Controller glue driver")
+Link: https://lore.kernel.org/all/20221218192523.c6vnfo26ua6xqf26@mobilestation/
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Serge Semin <fancer.lancer@gmail.com>
+Link: https://lore.kernel.org/r/20230130140156.3620863-1-arnd@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/Kconfig | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
+index aadaea052f51d..4d98ce7571df0 100644
+--- a/drivers/spi/Kconfig
++++ b/drivers/spi/Kconfig
+@@ -256,7 +256,6 @@ config SPI_DW_BT1
+ tristate "Baikal-T1 SPI driver for DW SPI core"
+ depends on MIPS_BAIKAL_T1 || COMPILE_TEST
+ select MULTIPLEXER
+- select MUX_MMIO
+ help
+ Baikal-T1 SoC is equipped with three DW APB SSI-based MMIO SPI
+ controllers. Two of them are pretty much normal: with IRQ, DMA,
+--
+2.39.2
+
--- /dev/null
+From b0bdad0371e2969c48cb3f164c305b7afb4da4d5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Feb 2023 14:01:28 +0100
+Subject: spi: synquacer: Fix timeout handling in synquacer_spi_transfer_one()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit e6a0b671880207566e1ece983bf989dde60bc1d7 ]
+
+wait_for_completion_timeout() never returns a <0 value. It returns either
+on timeout or a positive value (at least 1, or number of jiffies left
+till timeout)
+
+So, fix the error handling path and return -ETIMEDOUT should a timeout
+occur.
+
+Fixes: b0823ee35cf9 ("spi: Add spi driver for Socionext SynQuacer platform")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Acked-by: Jassi Brar <jaswinder.singh@linaro.org>
+Link: https://lore.kernel.org/r/c2040bf3cfa201fd8890cfab14fa5a701ffeca14.1676466072.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-synquacer.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/spi/spi-synquacer.c b/drivers/spi/spi-synquacer.c
+index 47cbe73137c23..dc188f9202c97 100644
+--- a/drivers/spi/spi-synquacer.c
++++ b/drivers/spi/spi-synquacer.c
+@@ -472,10 +472,9 @@ static int synquacer_spi_transfer_one(struct spi_master *master,
+ read_fifo(sspi);
+ }
+
+- if (status < 0) {
+- dev_err(sspi->dev, "failed to transfer. status: 0x%x\n",
+- status);
+- return status;
++ if (status == 0) {
++ dev_err(sspi->dev, "failed to transfer. Timeout.\n");
++ return -ETIMEDOUT;
+ }
+
+ return 0;
+--
+2.39.2
+
--- /dev/null
+From beca4633be20dce6d31e5fad5014f3833a866b1e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 4 Feb 2023 17:39:22 +0000
+Subject: tap: tap_open(): correctly initialize socket uid
+
+From: Pietro Borrello <borrello@diag.uniroma1.it>
+
+[ Upstream commit 66b2c338adce580dfce2199591e65e2bab889cff ]
+
+sock_init_data() assumes that the `struct socket` passed in input is
+contained in a `struct socket_alloc` allocated with sock_alloc().
+However, tap_open() passes a `struct socket` embedded in a `struct
+tap_queue` allocated with sk_alloc().
+This causes a type confusion when issuing a container_of() with
+SOCK_INODE() in sock_init_data() which results in assigning a wrong
+sk_uid to the `struct sock` in input.
+On default configuration, the type confused field overlaps with
+padding bytes between `int vnet_hdr_sz` and `struct tap_dev __rcu
+*tap` in `struct tap_queue`, which makes the uid of all tap sockets 0,
+i.e., the root one.
+Fix the assignment by using sock_init_data_uid().
+
+Fixes: 86741ec25462 ("net: core: Add a UID field to struct sock.")
+Signed-off-by: Pietro Borrello <borrello@diag.uniroma1.it>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/tap.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/tap.c b/drivers/net/tap.c
+index 8f7bb15206e9f..d9018d9fe3106 100644
+--- a/drivers/net/tap.c
++++ b/drivers/net/tap.c
+@@ -523,7 +523,7 @@ static int tap_open(struct inode *inode, struct file *file)
+ q->sock.state = SS_CONNECTED;
+ q->sock.file = file;
+ q->sock.ops = &tap_socket_ops;
+- sock_init_data(&q->sock, &q->sk);
++ sock_init_data_uid(&q->sock, &q->sk, inode->i_uid);
+ q->sk.sk_write_space = tap_sock_write_space;
+ q->sk.sk_destruct = tap_sock_destruct;
+ q->flags = IFF_VNET_HDR | IFF_NO_PI | IFF_TAP;
+--
+2.39.2
+
--- /dev/null
+From 368422f8e19ad45933cb3dc002014f03e5e28c26 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Feb 2023 22:15:07 +0800
+Subject: thermal/drivers/hisi: Drop second sensor hi3660
+
+From: Yongqin Liu <yongqin.liu@linaro.org>
+
+[ Upstream commit 15cc25829a97c3957e520e971868aacc84341317 ]
+
+The commit 74c8e6bffbe1 ("driver core: Add __alloc_size hint to devm
+allocators") exposes a panic "BRK handler: Fatal exception" on the
+hi3660_thermal_probe funciton.
+This is because the function allocates memory for only one
+sensors array entry, but tries to fill up a second one.
+
+Fix this by removing the unneeded second access.
+
+Fixes: 7d3a2a2bbadb ("thermal/drivers/hisi: Fix number of sensors on hi3660")
+Signed-off-by: Yongqin Liu <yongqin.liu@linaro.org>
+Link: https://lore.kernel.org/linux-mm/20221101223321.1326815-5-keescook@chromium.org/
+Link: https://lore.kernel.org/r/20230210141507.71014-1-yongqin.liu@linaro.org
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/hisi_thermal.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/drivers/thermal/hisi_thermal.c b/drivers/thermal/hisi_thermal.c
+index ee05950afd2f9..7b1e81912ccf7 100644
+--- a/drivers/thermal/hisi_thermal.c
++++ b/drivers/thermal/hisi_thermal.c
+@@ -435,10 +435,6 @@ static int hi3660_thermal_probe(struct hisi_thermal_data *data)
+ data->sensor[0].irq_name = "tsensor_a73";
+ data->sensor[0].data = data;
+
+- data->sensor[1].id = HI3660_LITTLE_SENSOR;
+- data->sensor[1].irq_name = "tsensor_a53";
+- data->sensor[1].data = data;
+-
+ return 0;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 1788b80659fea372ce7ede53ac0cef5e34c79471 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Feb 2021 22:31:19 +0100
+Subject: thermal/drivers/qcom/tsens_v1: Enable sensor 3 on MSM8976
+
+From: Konrad Dybcio <konrad.dybcio@somainline.org>
+
+[ Upstream commit 007d81a4519f04fa5ced5e9e28bf70cd753c398d ]
+
+The sensor *is* in fact used and does report temperature.
+
+Signed-off-by: Konrad Dybcio <konrad.dybcio@somainline.org>
+Acked-by: Thara Gopinath <thara.gopinath@linaro.org>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20210225213119.116550-1-konrad.dybcio@somainline.org
+Stable-dep-of: a7d3006be5ca ("thermal/drivers/tsens: Sort out msm8976 vs msm8956 data")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/qcom/tsens-v1.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/thermal/qcom/tsens-v1.c b/drivers/thermal/qcom/tsens-v1.c
+index bff50f3b9d0b6..13624263f1dfe 100644
+--- a/drivers/thermal/qcom/tsens-v1.c
++++ b/drivers/thermal/qcom/tsens-v1.c
+@@ -375,11 +375,11 @@ static const struct tsens_ops ops_8976 = {
+ .get_temp = get_temp_tsens_valid,
+ };
+
+-/* Valid for both MSM8956 and MSM8976. Sensor ID 3 is unused. */
++/* Valid for both MSM8956 and MSM8976. */
+ struct tsens_plat_data data_8976 = {
+ .num_sensors = 11,
+ .ops = &ops_8976,
+- .hw_ids = (unsigned int[]){0, 1, 2, 4, 5, 6, 7, 8, 9, 10},
++ .hw_ids = (unsigned int[]){0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
+ .feat = &tsens_v1_feat,
+ .fields = tsens_v1_regfields,
+ };
+--
+2.39.2
+
--- /dev/null
+From a65d1e9e1e110184f8c0f57f5027c9ed7cd7bebb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Apr 2022 03:26:46 +0300
+Subject: thermal/drivers/tsens: Add compat string for the qcom,msm8960
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 2caf73969de6675318a711d0622406c8c66afc03 ]
+
+On apq8064 (msm8960) platforms the tsens device is created manually by
+the gcc driver. Prepare the tsens driver for the qcom,msm8960-tsens
+device instantiated from the device tree.
+
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://lore.kernel.org/r/20220406002648.393486-3-dmitry.baryshkov@linaro.org
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Stable-dep-of: a7d3006be5ca ("thermal/drivers/tsens: Sort out msm8976 vs msm8956 data")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/qcom/tsens.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
+index cb4f4b5224460..9e4a60db6e23b 100644
+--- a/drivers/thermal/qcom/tsens.c
++++ b/drivers/thermal/qcom/tsens.c
+@@ -902,6 +902,9 @@ static const struct of_device_id tsens_table[] = {
+ }, {
+ .compatible = "qcom,msm8939-tsens",
+ .data = &data_8939,
++ }, {
++ .compatible = "qcom,msm8960-tsens",
++ .data = &data_8960,
+ }, {
+ .compatible = "qcom,msm8974-tsens",
+ .data = &data_8974,
+--
+2.39.2
+
--- /dev/null
+From 7811b5bc2ded71578a17ed5c8043b431d0e095dd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 1 Jan 2023 21:40:19 +0200
+Subject: thermal/drivers/tsens: Drop msm8976-specific defines
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 3bf0ea99e2e32b0335106b86d84404cc85bcd113 ]
+
+Drop msm8976-specific defines, which duplicate generic ones.
+
+Fixes: 0e580290170d ("thermal: qcom: tsens-v1: Add support for MSM8956 and MSM8976")
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://lore.kernel.org/r/20230101194034.831222-6-dmitry.baryshkov@linaro.org
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/qcom/tsens-v1.c | 9 ++-------
+ 1 file changed, 2 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/thermal/qcom/tsens-v1.c b/drivers/thermal/qcom/tsens-v1.c
+index 3c19a3800c6d6..bff50f3b9d0b6 100644
+--- a/drivers/thermal/qcom/tsens-v1.c
++++ b/drivers/thermal/qcom/tsens-v1.c
+@@ -78,11 +78,6 @@
+
+ #define MSM8976_CAL_SEL_MASK 0x3
+
+-#define MSM8976_CAL_DEGC_PT1 30
+-#define MSM8976_CAL_DEGC_PT2 120
+-#define MSM8976_SLOPE_FACTOR 1000
+-#define MSM8976_SLOPE_DEFAULT 3200
+-
+ /* eeprom layout data for qcs404/405 (v1) */
+ #define BASE0_MASK 0x000007f8
+ #define BASE1_MASK 0x0007f800
+@@ -160,8 +155,8 @@ static void compute_intercept_slope_8976(struct tsens_priv *priv,
+ priv->sensor[10].slope = 3286;
+
+ for (i = 0; i < priv->num_sensors; i++) {
+- priv->sensor[i].offset = (p1[i] * MSM8976_SLOPE_FACTOR) -
+- (MSM8976_CAL_DEGC_PT1 *
++ priv->sensor[i].offset = (p1[i] * SLOPE_FACTOR) -
++ (CAL_DEGC_PT1 *
+ priv->sensor[i].slope);
+ }
+ }
+--
+2.39.2
+
--- /dev/null
+From e522ba5990bfc80c29573f1e94b242fc7f54db01 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 1 Jan 2023 21:40:20 +0200
+Subject: thermal/drivers/tsens: Sort out msm8976 vs msm8956 data
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit a7d3006be5ca7b04e4b84b5ceaae55a700e511bd ]
+
+Tsens driver mentions that msm8976 data should be used for both msm8976
+and msm8956 SoCs. This is not quite correct, as according to the
+vendor kernels, msm8976 should use standard slope values (3200), while
+msm8956 really uses the slope values found in the driver.
+
+Add separate compatibility string for msm8956, move slope value
+overrides to the corresponding init function and use the standard
+compute_intercept_slope() function for both platforms.
+
+Fixes: 0e580290170d ("thermal: qcom: tsens-v1: Add support for MSM8956 and MSM8976")
+Cc: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://lore.kernel.org/r/20230101194034.831222-7-dmitry.baryshkov@linaro.org
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/qcom/tsens-v1.c | 56 ++++++++++++++++++---------------
+ drivers/thermal/qcom/tsens.c | 3 ++
+ drivers/thermal/qcom/tsens.h | 2 +-
+ 3 files changed, 34 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/thermal/qcom/tsens-v1.c b/drivers/thermal/qcom/tsens-v1.c
+index 13624263f1dfe..faa4576fa028f 100644
+--- a/drivers/thermal/qcom/tsens-v1.c
++++ b/drivers/thermal/qcom/tsens-v1.c
+@@ -137,30 +137,6 @@
+ #define CAL_SEL_MASK 7
+ #define CAL_SEL_SHIFT 0
+
+-static void compute_intercept_slope_8976(struct tsens_priv *priv,
+- u32 *p1, u32 *p2, u32 mode)
+-{
+- int i;
+-
+- priv->sensor[0].slope = 3313;
+- priv->sensor[1].slope = 3275;
+- priv->sensor[2].slope = 3320;
+- priv->sensor[3].slope = 3246;
+- priv->sensor[4].slope = 3279;
+- priv->sensor[5].slope = 3257;
+- priv->sensor[6].slope = 3234;
+- priv->sensor[7].slope = 3269;
+- priv->sensor[8].slope = 3255;
+- priv->sensor[9].slope = 3239;
+- priv->sensor[10].slope = 3286;
+-
+- for (i = 0; i < priv->num_sensors; i++) {
+- priv->sensor[i].offset = (p1[i] * SLOPE_FACTOR) -
+- (CAL_DEGC_PT1 *
+- priv->sensor[i].slope);
+- }
+-}
+-
+ static int calibrate_v1(struct tsens_priv *priv)
+ {
+ u32 base0 = 0, base1 = 0;
+@@ -286,7 +262,7 @@ static int calibrate_8976(struct tsens_priv *priv)
+ break;
+ }
+
+- compute_intercept_slope_8976(priv, p1, p2, mode);
++ compute_intercept_slope(priv, p1, p2, mode);
+ kfree(qfprom_cdata);
+
+ return 0;
+@@ -357,6 +333,22 @@ static const struct reg_field tsens_v1_regfields[MAX_REGFIELDS] = {
+ [TRDY] = REG_FIELD(TM_TRDY_OFF, 0, 0),
+ };
+
++static int __init init_8956(struct tsens_priv *priv) {
++ priv->sensor[0].slope = 3313;
++ priv->sensor[1].slope = 3275;
++ priv->sensor[2].slope = 3320;
++ priv->sensor[3].slope = 3246;
++ priv->sensor[4].slope = 3279;
++ priv->sensor[5].slope = 3257;
++ priv->sensor[6].slope = 3234;
++ priv->sensor[7].slope = 3269;
++ priv->sensor[8].slope = 3255;
++ priv->sensor[9].slope = 3239;
++ priv->sensor[10].slope = 3286;
++
++ return init_common(priv);
++}
++
+ static const struct tsens_ops ops_generic_v1 = {
+ .init = init_common,
+ .calibrate = calibrate_v1,
+@@ -369,13 +361,25 @@ struct tsens_plat_data data_tsens_v1 = {
+ .fields = tsens_v1_regfields,
+ };
+
++static const struct tsens_ops ops_8956 = {
++ .init = init_8956,
++ .calibrate = calibrate_8976,
++ .get_temp = get_temp_tsens_valid,
++};
++
++struct tsens_plat_data data_8956 = {
++ .num_sensors = 11,
++ .ops = &ops_8956,
++ .feat = &tsens_v1_feat,
++ .fields = tsens_v1_regfields,
++};
++
+ static const struct tsens_ops ops_8976 = {
+ .init = init_common,
+ .calibrate = calibrate_8976,
+ .get_temp = get_temp_tsens_valid,
+ };
+
+-/* Valid for both MSM8956 and MSM8976. */
+ struct tsens_plat_data data_8976 = {
+ .num_sensors = 11,
+ .ops = &ops_8976,
+diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
+index 9e4a60db6e23b..c73792ca727a1 100644
+--- a/drivers/thermal/qcom/tsens.c
++++ b/drivers/thermal/qcom/tsens.c
+@@ -902,6 +902,9 @@ static const struct of_device_id tsens_table[] = {
+ }, {
+ .compatible = "qcom,msm8939-tsens",
+ .data = &data_8939,
++ }, {
++ .compatible = "qcom,msm8956-tsens",
++ .data = &data_8956,
+ }, {
+ .compatible = "qcom,msm8960-tsens",
+ .data = &data_8960,
+diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h
+index f40b625f897e8..bbb1e8332821c 100644
+--- a/drivers/thermal/qcom/tsens.h
++++ b/drivers/thermal/qcom/tsens.h
+@@ -588,7 +588,7 @@ extern struct tsens_plat_data data_8960;
+ extern struct tsens_plat_data data_8916, data_8939, data_8974;
+
+ /* TSENS v1 targets */
+-extern struct tsens_plat_data data_tsens_v1, data_8976;
++extern struct tsens_plat_data data_tsens_v1, data_8976, data_8956;
+
+ /* TSENS v2 targets */
+ extern struct tsens_plat_data data_8996, data_tsens_v2;
+--
+2.39.2
+
--- /dev/null
+From 6b5fc347ca1ce2d3672f0df9e0fbae3daba3110f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Jan 2023 08:59:51 +0800
+Subject: thermal: intel: Fix unsigned comparison with less than zero
+
+From: Yang Li <yang.lee@linux.alibaba.com>
+
+[ Upstream commit e7fcfe67f9f410736b758969477b17ea285e8e6c ]
+
+The return value from the call to intel_tcc_get_tjmax() is int, which can
+be a negative error code. However, the return value is being assigned to
+an u32 variable 'tj_max', so making 'tj_max' an int.
+
+Eliminate the following warning:
+./drivers/thermal/intel/intel_soc_dts_iosf.c:394:5-11: WARNING: Unsigned expression compared with zero: tj_max < 0
+
+Link: https://bugzilla.openanolis.cn/show_bug.cgi?id=3637
+Reported-by: Abaci Robot <abaci@linux.alibaba.com>
+Signed-off-by: Yang Li <yang.lee@linux.alibaba.com>
+Acked-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/intel/intel_soc_dts_iosf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/thermal/intel/intel_soc_dts_iosf.c b/drivers/thermal/intel/intel_soc_dts_iosf.c
+index 4f1a2f7c016cc..8d6707e48d023 100644
+--- a/drivers/thermal/intel/intel_soc_dts_iosf.c
++++ b/drivers/thermal/intel/intel_soc_dts_iosf.c
+@@ -404,7 +404,7 @@ struct intel_soc_dts_sensors *intel_soc_dts_iosf_init(
+ {
+ struct intel_soc_dts_sensors *sensors;
+ bool notification;
+- u32 tj_max;
++ int tj_max;
+ int ret;
+ int i;
+
+--
+2.39.2
+
--- /dev/null
+From c4302c3f0d67951d8e466040a31770d1984b60d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Jan 2023 14:44:03 +0100
+Subject: timers: Prevent union confusion from unexpected restart_syscall()
+
+From: Jann Horn <jannh@google.com>
+
+[ Upstream commit 9f76d59173d9d146e96c66886b671c1915a5c5e5 ]
+
+The nanosleep syscalls use the restart_block mechanism, with a quirk:
+The `type` and `rmtp`/`compat_rmtp` fields are set up unconditionally on
+syscall entry, while the rest of the restart_block is only set up in the
+unlikely case that the syscall is actually interrupted by a signal (or
+pseudo-signal) that doesn't have a signal handler.
+
+If the restart_block was set up by a previous syscall (futex(...,
+FUTEX_WAIT, ...) or poll()) and hasn't been invalidated somehow since then,
+this will clobber some of the union fields used by futex_wait_restart() and
+do_restart_poll().
+
+If userspace afterwards wrongly calls the restart_syscall syscall,
+futex_wait_restart()/do_restart_poll() will read struct fields that have
+been clobbered.
+
+This doesn't actually lead to anything particularly interesting because
+none of the union fields contain trusted kernel data, and
+futex(..., FUTEX_WAIT, ...) and poll() aren't syscalls where it makes much
+sense to apply seccomp filters to their arguments.
+
+So the current consequences are just of the "if userspace does bad stuff,
+it can damage itself, and that's not a problem" flavor.
+
+But still, it seems like a hazard for future developers, so invalidate the
+restart_block when partly setting it up in the nanosleep syscalls.
+
+Signed-off-by: Jann Horn <jannh@google.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Link: https://lore.kernel.org/r/20230105134403.754986-1-jannh@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/time/hrtimer.c | 2 ++
+ kernel/time/posix-stubs.c | 2 ++
+ kernel/time/posix-timers.c | 2 ++
+ 3 files changed, 6 insertions(+)
+
+diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
+index 544ce87ba38a7..70deb2f01e97a 100644
+--- a/kernel/time/hrtimer.c
++++ b/kernel/time/hrtimer.c
+@@ -2024,6 +2024,7 @@ SYSCALL_DEFINE2(nanosleep, struct __kernel_timespec __user *, rqtp,
+ if (!timespec64_valid(&tu))
+ return -EINVAL;
+
++ current->restart_block.fn = do_no_restart_syscall;
+ current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE;
+ current->restart_block.nanosleep.rmtp = rmtp;
+ return hrtimer_nanosleep(timespec64_to_ktime(tu), HRTIMER_MODE_REL,
+@@ -2045,6 +2046,7 @@ SYSCALL_DEFINE2(nanosleep_time32, struct old_timespec32 __user *, rqtp,
+ if (!timespec64_valid(&tu))
+ return -EINVAL;
+
++ current->restart_block.fn = do_no_restart_syscall;
+ current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE;
+ current->restart_block.nanosleep.compat_rmtp = rmtp;
+ return hrtimer_nanosleep(timespec64_to_ktime(tu), HRTIMER_MODE_REL,
+diff --git a/kernel/time/posix-stubs.c b/kernel/time/posix-stubs.c
+index fcb3b21d8bdcd..3783d07d60ba0 100644
+--- a/kernel/time/posix-stubs.c
++++ b/kernel/time/posix-stubs.c
+@@ -146,6 +146,7 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,
+ return -EINVAL;
+ if (flags & TIMER_ABSTIME)
+ rmtp = NULL;
++ current->restart_block.fn = do_no_restart_syscall;
+ current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE;
+ current->restart_block.nanosleep.rmtp = rmtp;
+ texp = timespec64_to_ktime(t);
+@@ -239,6 +240,7 @@ SYSCALL_DEFINE4(clock_nanosleep_time32, clockid_t, which_clock, int, flags,
+ return -EINVAL;
+ if (flags & TIMER_ABSTIME)
+ rmtp = NULL;
++ current->restart_block.fn = do_no_restart_syscall;
+ current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE;
+ current->restart_block.nanosleep.compat_rmtp = rmtp;
+ texp = timespec64_to_ktime(t);
+diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
+index b624788023d8f..724ca7eb1a6e8 100644
+--- a/kernel/time/posix-timers.c
++++ b/kernel/time/posix-timers.c
+@@ -1270,6 +1270,7 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,
+ return -EINVAL;
+ if (flags & TIMER_ABSTIME)
+ rmtp = NULL;
++ current->restart_block.fn = do_no_restart_syscall;
+ current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE;
+ current->restart_block.nanosleep.rmtp = rmtp;
+
+@@ -1297,6 +1298,7 @@ SYSCALL_DEFINE4(clock_nanosleep_time32, clockid_t, which_clock, int, flags,
+ return -EINVAL;
+ if (flags & TIMER_ABSTIME)
+ rmtp = NULL;
++ current->restart_block.fn = do_no_restart_syscall;
+ current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE;
+ current->restart_block.nanosleep.compat_rmtp = rmtp;
+
+--
+2.39.2
+
--- /dev/null
+From e343a83c2270932f686c35a32a230d4cd6795165 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 4 Feb 2023 17:39:21 +0000
+Subject: tun: tun_chr_open(): correctly initialize socket uid
+
+From: Pietro Borrello <borrello@diag.uniroma1.it>
+
+[ Upstream commit a096ccca6e503a5c575717ff8a36ace27510ab0a ]
+
+sock_init_data() assumes that the `struct socket` passed in input is
+contained in a `struct socket_alloc` allocated with sock_alloc().
+However, tun_chr_open() passes a `struct socket` embedded in a `struct
+tun_file` allocated with sk_alloc().
+This causes a type confusion when issuing a container_of() with
+SOCK_INODE() in sock_init_data() which results in assigning a wrong
+sk_uid to the `struct sock` in input.
+On default configuration, the type confused field overlaps with the
+high 4 bytes of `struct tun_struct __rcu *tun` of `struct tun_file`,
+NULL at the time of call, which makes the uid of all tun sockets 0,
+i.e., the root one.
+Fix the assignment by using sock_init_data_uid().
+
+Fixes: 86741ec25462 ("net: core: Add a UID field to struct sock.")
+Signed-off-by: Pietro Borrello <borrello@diag.uniroma1.it>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/tun.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/tun.c b/drivers/net/tun.c
+index 67ce7b779af61..f1d46aea8a2ba 100644
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -3457,7 +3457,7 @@ static int tun_chr_open(struct inode *inode, struct file * file)
+ tfile->socket.file = file;
+ tfile->socket.ops = &tun_socket_ops;
+
+- sock_init_data(&tfile->socket, &tfile->sk);
++ sock_init_data_uid(&tfile->socket, &tfile->sk, inode->i_uid);
+
+ tfile->sk.sk_write_space = tun_sock_write_space;
+ tfile->sk.sk_sndbuf = INT_MAX;
+--
+2.39.2
+
--- /dev/null
+From 09636258685c66aea010161082a1116c9dc23235 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 31 Jan 2023 17:37:59 -0800
+Subject: uaccess: Add minimum bounds check on kernel buffer size
+
+From: Kees Cook <keescook@chromium.org>
+
+[ Upstream commit 04ffde1319a715bd0550ded3580d4ea3bc003776 ]
+
+While there is logic about the difference between ksize and usize,
+copy_struct_from_user() didn't check the size of the destination buffer
+(when it was known) against ksize. Add this check so there is an upper
+bounds check on the possible memset() call, otherwise lower bounds
+checks made by callers will trigger bounds warnings under -Warray-bounds.
+Seen under GCC 13:
+
+In function 'copy_struct_from_user',
+ inlined from 'iommufd_fops_ioctl' at
+../drivers/iommu/iommufd/main.c:333:8:
+../include/linux/fortify-string.h:59:33: warning: '__builtin_memset' offset [57, 4294967294] is out of the bounds [0, 56] of object 'buf' with type 'union ucmd_buffer' [-Warray-bounds=]
+ 59 | #define __underlying_memset __builtin_memset
+ | ^
+../include/linux/fortify-string.h:453:9: note: in expansion of macro '__underlying_memset'
+ 453 | __underlying_memset(p, c, __fortify_size); \
+ | ^~~~~~~~~~~~~~~~~~~
+../include/linux/fortify-string.h:461:25: note: in expansion of macro '__fortify_memset_chk'
+ 461 | #define memset(p, c, s) __fortify_memset_chk(p, c, s, \
+ | ^~~~~~~~~~~~~~~~~~~~
+../include/linux/uaccess.h:334:17: note: in expansion of macro 'memset'
+ 334 | memset(dst + size, 0, rest);
+ | ^~~~~~
+../drivers/iommu/iommufd/main.c: In function 'iommufd_fops_ioctl':
+../drivers/iommu/iommufd/main.c:311:27: note: 'buf' declared here
+ 311 | union ucmd_buffer buf;
+ | ^~~
+
+Cc: Christian Brauner <brauner@kernel.org>
+Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk>
+Cc: Arnd Bergmann <arnd@arndb.de>
+Cc: Dinh Nguyen <dinguyen@kernel.org>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Geert Uytterhoeven <geert@linux-m68k.org>
+Cc: Alexander Potapenko <glider@google.com>
+Acked-by: Aleksa Sarai <cyphar@cyphar.com>
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Link: https://lore.kernel.org/lkml/20230203193523.never.667-kees@kernel.org/
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/uaccess.h | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h
+index c7c6e8b8344d4..20668760daa02 100644
+--- a/include/linux/uaccess.h
++++ b/include/linux/uaccess.h
+@@ -348,6 +348,10 @@ copy_struct_from_user(void *dst, size_t ksize, const void __user *src,
+ size_t size = min(ksize, usize);
+ size_t rest = max(ksize, usize) - size;
+
++ /* Double check if ksize is larger than a known object size. */
++ if (WARN_ON_ONCE(ksize > __builtin_object_size(dst, 1)))
++ return -E2BIG;
++
+ /* Deal with trailing bytes. */
+ if (usize < ksize) {
+ memset(dst + size, 0, rest);
+--
+2.39.2
+
--- /dev/null
+From 60e6fc024ca5219187fe20f38747e8bc0d7ee7c6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Sep 2022 16:34:45 +0200
+Subject: udf: Define EFSCORRUPTED error code
+
+From: Jan Kara <jack@suse.cz>
+
+[ Upstream commit 3d2d7e61553dbcc8ba45201d8ae4f383742c8202 ]
+
+Similarly to other filesystems define EFSCORRUPTED error code for
+reporting internal filesystem corruption.
+
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/udf/udf_sb.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/fs/udf/udf_sb.h b/fs/udf/udf_sb.h
+index 4fa620543d302..2205859731dc2 100644
+--- a/fs/udf/udf_sb.h
++++ b/fs/udf/udf_sb.h
+@@ -51,6 +51,8 @@
+ #define MF_DUPLICATE_MD 0x01
+ #define MF_MIRROR_FE_LOADED 0x02
+
++#define EFSCORRUPTED EUCLEAN
++
+ struct udf_meta_data {
+ __u32 s_meta_file_loc;
+ __u32 s_mirror_file_loc;
+--
+2.39.2
+
--- /dev/null
+From adf01f9e3492069cff72cbe030f8d82ef2fe68a9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Feb 2023 14:19:56 +0200
+Subject: vdpa/mlx5: Don't clear mr struct on destroy MR
+
+From: Eli Cohen <elic@nvidia.com>
+
+[ Upstream commit aef24311bd2d8a6d39a80c34f278b0fd1692aed3 ]
+
+Clearing the mr struct erases the lock owner and causes warnings to be
+emitted. It is not required to clear the mr so remove the memset call.
+
+Fixes: 94abbccdf291 ("vdpa/mlx5: Add shared memory registration code")
+Signed-off-by: Eli Cohen <elic@nvidia.com>
+Message-Id: <20230206121956.1149356-1-elic@nvidia.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/vdpa/mlx5/core/mr.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
+index 32c9925de4736..1f94ea46c01a5 100644
+--- a/drivers/vdpa/mlx5/core/mr.c
++++ b/drivers/vdpa/mlx5/core/mr.c
+@@ -448,7 +448,6 @@ void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev)
+ unmap_direct_mr(mvdev, dmr);
+ kfree(dmr);
+ }
+- memset(mr, 0, sizeof(*mr));
+ mr->initialized = false;
+ out:
+ mutex_unlock(&mr->mkey_mtx);
+--
+2.39.2
+
--- /dev/null
+From 5ca6f914763a45a9c43e546b7994a6aa19ed6783 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Dec 2022 19:15:59 +0200
+Subject: wifi: ath11k: debugfs: fix to work with multiple PCI devices
+
+From: Kalle Valo <quic_kvalo@quicinc.com>
+
+[ Upstream commit 323d91d4684d238f6bc3693fed93caf795378fe0 ]
+
+ath11k fails to load if there are multiple ath11k PCI devices with same name:
+
+ ath11k_pci 0000:01:00.0: Hardware name qcn9074 hw1.0
+ debugfs: Directory 'ath11k' with parent '/' already present!
+ ath11k_pci 0000:01:00.0: failed to create ath11k debugfs
+ ath11k_pci 0000:01:00.0: failed to create soc core: -17
+ ath11k_pci 0000:01:00.0: failed to init core: -17
+ ath11k_pci: probe of 0000:01:00.0 failed with error -17
+
+Fix this by creating a directory for each ath11k device using schema
+<bus>-<devname>, for example "pci-0000:06:00.0". This directory created under
+the top-level ath11k directory, for example /sys/kernel/debug/ath11k.
+
+The reference to the toplevel ath11k directory is not stored anymore within ath11k, instead
+it's retrieved using debugfs_lookup(). If the directory does not exist it will
+be created. After the last directory from the ath11k directory is removed, for
+example when doing rmmod ath11k, the empty ath11k directory is left in place,
+it's a minor cosmetic issue anyway.
+
+Here's an example hierarchy with one WCN6855:
+
+ath11k
+`-- pci-0000:06:00.0
+ |-- mac0
+ | |-- dfs_block_radar_events
+ | |-- dfs_simulate_radar
+ | |-- ext_rx_stats
+ | |-- ext_tx_stats
+ | |-- fw_dbglog_config
+ | |-- fw_stats
+ | | |-- beacon_stats
+ | | |-- pdev_stats
+ | | `-- vdev_stats
+ | |-- htt_stats
+ | |-- htt_stats_reset
+ | |-- htt_stats_type
+ | `-- pktlog_filter
+ |-- simulate_fw_crash
+ `-- soc_dp_stats
+
+I didn't have a test setup where I could connect multiple ath11k devices to the
+same the host, so I have only tested this with one device.
+
+Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.9
+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1
+Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1
+
+Tested-by: Robert Marko <robert.marko@sartura.hr>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20221220121231.20120-1-kvalo@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath11k/core.h | 1 -
+ drivers/net/wireless/ath/ath11k/debugfs.c | 48 +++++++++++++++++++----
+ 2 files changed, 40 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h
+index d2f2898d17b49..a66e275af1eb4 100644
+--- a/drivers/net/wireless/ath/ath11k/core.h
++++ b/drivers/net/wireless/ath/ath11k/core.h
+@@ -712,7 +712,6 @@ struct ath11k_base {
+ enum ath11k_dfs_region dfs_region;
+ #ifdef CONFIG_ATH11K_DEBUGFS
+ struct dentry *debugfs_soc;
+- struct dentry *debugfs_ath11k;
+ #endif
+ struct ath11k_soc_dp_stats soc_stats;
+
+diff --git a/drivers/net/wireless/ath/ath11k/debugfs.c b/drivers/net/wireless/ath/ath11k/debugfs.c
+index 1b914e67d314d..196314ab4ff0b 100644
+--- a/drivers/net/wireless/ath/ath11k/debugfs.c
++++ b/drivers/net/wireless/ath/ath11k/debugfs.c
+@@ -836,10 +836,6 @@ int ath11k_debugfs_pdev_create(struct ath11k_base *ab)
+ if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags))
+ return 0;
+
+- ab->debugfs_soc = debugfs_create_dir(ab->hw_params.name, ab->debugfs_ath11k);
+- if (IS_ERR(ab->debugfs_soc))
+- return PTR_ERR(ab->debugfs_soc);
+-
+ debugfs_create_file("simulate_fw_crash", 0600, ab->debugfs_soc, ab,
+ &fops_simulate_fw_crash);
+
+@@ -857,15 +853,51 @@ void ath11k_debugfs_pdev_destroy(struct ath11k_base *ab)
+
+ int ath11k_debugfs_soc_create(struct ath11k_base *ab)
+ {
+- ab->debugfs_ath11k = debugfs_create_dir("ath11k", NULL);
++ struct dentry *root;
++ bool dput_needed;
++ char name[64];
++ int ret;
++
++ root = debugfs_lookup("ath11k", NULL);
++ if (!root) {
++ root = debugfs_create_dir("ath11k", NULL);
++ if (IS_ERR_OR_NULL(root))
++ return PTR_ERR(root);
++
++ dput_needed = false;
++ } else {
++ /* a dentry from lookup() needs dput() after we don't use it */
++ dput_needed = true;
++ }
++
++ scnprintf(name, sizeof(name), "%s-%s", ath11k_bus_str(ab->hif.bus),
++ dev_name(ab->dev));
++
++ ab->debugfs_soc = debugfs_create_dir(name, root);
++ if (IS_ERR_OR_NULL(ab->debugfs_soc)) {
++ ret = PTR_ERR(ab->debugfs_soc);
++ goto out;
++ }
++
++ ret = 0;
+
+- return PTR_ERR_OR_ZERO(ab->debugfs_ath11k);
++out:
++ if (dput_needed)
++ dput(root);
++
++ return ret;
+ }
+
+ void ath11k_debugfs_soc_destroy(struct ath11k_base *ab)
+ {
+- debugfs_remove_recursive(ab->debugfs_ath11k);
+- ab->debugfs_ath11k = NULL;
++ debugfs_remove_recursive(ab->debugfs_soc);
++ ab->debugfs_soc = NULL;
++
++ /* We are not removing ath11k directory on purpose, even if it
++ * would be empty. This simplifies the directory handling and it's
++ * a minor cosmetic issue to leave an empty ath11k directory to
++ * debugfs.
++ */
+ }
+
+ void ath11k_debugfs_fw_stats_init(struct ath11k *ar)
+--
+2.39.2
+
--- /dev/null
+From eb9b6fb6c388684a919f472166a69dd8b4e4de24 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Jan 2023 12:11:42 +0400
+Subject: wifi: ath11k: Fix memory leak in ath11k_peer_rx_frag_setup
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit ed3f83b3459a67a3ab9d806490ac304b567b1c2d ]
+
+crypto_alloc_shash() allocates resources, which should be released by
+crypto_free_shash(). When ath11k_peer_find() fails, there has memory
+leak. Add missing crypto_free_shash() to fix this.
+
+Fixes: 243874c64c81 ("ath11k: handle RX fragments")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20230102081142.3937570-1-linmq006@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath11k/dp_rx.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c
+index 2e77dca6b1ad6..578fdc446bc03 100644
+--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
+@@ -3022,6 +3022,7 @@ int ath11k_peer_rx_frag_setup(struct ath11k *ar, const u8 *peer_mac, int vdev_id
+ if (!peer) {
+ ath11k_warn(ab, "failed to find the peer to set up fragment info\n");
+ spin_unlock_bh(&ab->base_lock);
++ crypto_free_shash(tfm);
+ return -ENOENT;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From b743b260f67e3b36a8934a149174a45a1c858b84 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Jan 2023 21:41:30 +0900
+Subject: wifi: ath9k: Fix potential stack-out-of-bounds write in
+ ath9k_wmi_rsp_callback()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Minsuk Kang <linuxlovemin@yonsei.ac.kr>
+
+[ Upstream commit 8a2f35b9830692f7a616f2f627f943bc748af13a ]
+
+Fix a stack-out-of-bounds write that occurs in a WMI response callback
+function that is called after a timeout occurs in ath9k_wmi_cmd().
+The callback writes to wmi->cmd_rsp_buf, a stack-allocated buffer that
+could no longer be valid when a timeout occurs. Set wmi->last_seq_id to
+0 when a timeout occurred.
+
+Found by a modified version of syzkaller.
+
+BUG: KASAN: stack-out-of-bounds in ath9k_wmi_ctrl_rx
+Write of size 4
+Call Trace:
+ memcpy
+ ath9k_wmi_ctrl_rx
+ ath9k_htc_rx_msg
+ ath9k_hif_usb_reg_in_cb
+ __usb_hcd_giveback_urb
+ usb_hcd_giveback_urb
+ dummy_timer
+ call_timer_fn
+ run_timer_softirq
+ __do_softirq
+ irq_exit_rcu
+ sysvec_apic_timer_interrupt
+
+Fixes: fb9987d0f748 ("ath9k_htc: Support for AR9271 chipset.")
+Signed-off-by: Minsuk Kang <linuxlovemin@yonsei.ac.kr>
+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/20230104124130.10996-1-linuxlovemin@yonsei.ac.kr
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath9k/wmi.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c
+index f315c54bd3ac0..19345b8f7bfd5 100644
+--- a/drivers/net/wireless/ath/ath9k/wmi.c
++++ b/drivers/net/wireless/ath/ath9k/wmi.c
+@@ -341,6 +341,7 @@ 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));
++ wmi->last_seq_id = 0;
+ mutex_unlock(&wmi->op_mutex);
+ return -ETIMEDOUT;
+ }
+--
+2.39.2
+
--- /dev/null
+From c0be021cd379becabfcf603fd6b1c872f504c6a3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Dec 2022 10:43:08 +0900
+Subject: wifi: ath9k: Fix use-after-free in ath9k_hif_usb_disconnect()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Minsuk Kang <linuxlovemin@yonsei.ac.kr>
+
+[ Upstream commit f099c5c9e2ba08a379bd354a82e05ef839ae29ac ]
+
+This patch fixes a use-after-free in ath9k that occurs in
+ath9k_hif_usb_disconnect() when ath9k_destroy_wmi() is trying to access
+'drv_priv' that has already been freed by ieee80211_free_hw(), called by
+ath9k_htc_hw_deinit(). The patch moves ath9k_destroy_wmi() before
+ieee80211_free_hw(). Note that urbs from the driver should be killed
+before freeing 'wmi' with ath9k_destroy_wmi() as their callbacks will
+access 'wmi'.
+
+Found by a modified version of syzkaller.
+
+==================================================================
+BUG: KASAN: use-after-free in ath9k_destroy_wmi+0x38/0x40
+Read of size 8 at addr ffff8881069132a0 by task kworker/0:1/7
+
+CPU: 0 PID: 7 Comm: kworker/0:1 Tainted: G O 5.14.0+ #131
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014
+Workqueue: usb_hub_wq hub_event
+Call Trace:
+ dump_stack_lvl+0x8e/0xd1
+ print_address_description.constprop.0.cold+0x93/0x334
+ ? ath9k_destroy_wmi+0x38/0x40
+ ? ath9k_destroy_wmi+0x38/0x40
+ kasan_report.cold+0x83/0xdf
+ ? ath9k_destroy_wmi+0x38/0x40
+ ath9k_destroy_wmi+0x38/0x40
+ ath9k_hif_usb_disconnect+0x329/0x3f0
+ ? ath9k_hif_usb_suspend+0x120/0x120
+ ? usb_disable_interface+0xfc/0x180
+ usb_unbind_interface+0x19b/0x7e0
+ ? usb_autoresume_device+0x50/0x50
+ device_release_driver_internal+0x44d/0x520
+ bus_remove_device+0x2e5/0x5a0
+ device_del+0x5b2/0xe30
+ ? __device_link_del+0x370/0x370
+ ? usb_remove_ep_devs+0x43/0x80
+ ? remove_intf_ep_devs+0x112/0x1a0
+ usb_disable_device+0x1e3/0x5a0
+ usb_disconnect+0x267/0x870
+ hub_event+0x168d/0x3950
+ ? rcu_read_lock_sched_held+0xa1/0xd0
+ ? hub_port_debounce+0x2e0/0x2e0
+ ? check_irq_usage+0x860/0xf20
+ ? drain_workqueue+0x281/0x360
+ ? lock_release+0x640/0x640
+ ? rcu_read_lock_sched_held+0xa1/0xd0
+ ? rcu_read_lock_bh_held+0xb0/0xb0
+ ? lockdep_hardirqs_on_prepare+0x273/0x3e0
+ process_one_work+0x92b/0x1460
+ ? pwq_dec_nr_in_flight+0x330/0x330
+ ? rwlock_bug.part.0+0x90/0x90
+ worker_thread+0x95/0xe00
+ ? __kthread_parkme+0x115/0x1e0
+ ? process_one_work+0x1460/0x1460
+ kthread+0x3a1/0x480
+ ? set_kthread_struct+0x120/0x120
+ ret_from_fork+0x1f/0x30
+
+The buggy address belongs to the page:
+page:ffffea00041a44c0 refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x106913
+flags: 0x200000000000000(node=0|zone=2)
+raw: 0200000000000000 0000000000000000 dead000000000122 0000000000000000
+raw: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000
+page dumped because: kasan: bad access detected
+page_owner tracks the page as freed
+page last allocated via order 3, migratetype Unmovable, gfp_mask 0x40dc0(GFP_KERNEL|__GFP_COMP|__GFP_ZERO), pid 7, ts 38347963444, free_ts 41399957635
+ prep_new_page+0x1aa/0x240
+ get_page_from_freelist+0x159a/0x27c0
+ __alloc_pages+0x2da/0x6a0
+ alloc_pages+0xec/0x1e0
+ kmalloc_order+0x39/0xf0
+ kmalloc_order_trace+0x19/0x120
+ __kmalloc+0x308/0x390
+ wiphy_new_nm+0x6f5/0x1dd0
+ ieee80211_alloc_hw_nm+0x36d/0x2230
+ ath9k_htc_probe_device+0x9d/0x1e10
+ ath9k_htc_hw_init+0x34/0x50
+ ath9k_hif_usb_firmware_cb+0x25f/0x4e0
+ request_firmware_work_func+0x131/0x240
+ process_one_work+0x92b/0x1460
+ worker_thread+0x95/0xe00
+ kthread+0x3a1/0x480
+page last free stack trace:
+ free_pcp_prepare+0x3d3/0x7f0
+ free_unref_page+0x1e/0x3d0
+ device_release+0xa4/0x240
+ kobject_put+0x186/0x4c0
+ put_device+0x20/0x30
+ ath9k_htc_disconnect_device+0x1cf/0x2c0
+ ath9k_htc_hw_deinit+0x26/0x30
+ ath9k_hif_usb_disconnect+0x2d9/0x3f0
+ usb_unbind_interface+0x19b/0x7e0
+ device_release_driver_internal+0x44d/0x520
+ bus_remove_device+0x2e5/0x5a0
+ device_del+0x5b2/0xe30
+ usb_disable_device+0x1e3/0x5a0
+ usb_disconnect+0x267/0x870
+ hub_event+0x168d/0x3950
+ process_one_work+0x92b/0x1460
+
+Memory state around the buggy address:
+ ffff888106913180: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
+ ffff888106913200: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
+>ffff888106913280: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
+ ^
+ ffff888106913300: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
+ ffff888106913380: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
+==================================================================
+
+Reported-by: Dokyung Song <dokyungs@yonsei.ac.kr>
+Reported-by: Jisoo Jang <jisoo.jang@yonsei.ac.kr>
+Reported-by: Minsuk Kang <linuxlovemin@yonsei.ac.kr>
+Signed-off-by: Minsuk Kang <linuxlovemin@yonsei.ac.kr>
+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/20221205014308.1617597-1-linuxlovemin@yonsei.ac.kr
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath9k/hif_usb.c | 2 --
+ drivers/net/wireless/ath/ath9k/htc_drv_init.c | 2 ++
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
+index de6c0824c9cab..f521dfa2f1945 100644
+--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
++++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
+@@ -1424,8 +1424,6 @@ static void ath9k_hif_usb_disconnect(struct usb_interface *interface)
+
+ if (hif_dev->flags & HIF_USB_READY) {
+ ath9k_htc_hw_deinit(hif_dev->htc_handle, unplugged);
+- ath9k_hif_usb_dev_deinit(hif_dev);
+- ath9k_destroy_wmi(hif_dev->htc_handle->drv_priv);
+ ath9k_htc_hw_free(hif_dev->htc_handle);
+ }
+
+diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+index 07ac88fb1c577..96a3185a96d75 100644
+--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
++++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+@@ -988,6 +988,8 @@ void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug)
+
+ ath9k_deinit_device(htc_handle->drv_priv);
+ ath9k_stop_wmi(htc_handle->drv_priv);
++ ath9k_hif_usb_dealloc_urbs((struct hif_device_usb *)htc_handle->hif_dev);
++ ath9k_destroy_wmi(htc_handle->drv_priv);
+ ieee80211_free_hw(htc_handle->drv_priv->hw);
+ }
+ }
+--
+2.39.2
+
--- /dev/null
+From 4965c89948216b77894bab88df27719d4be241e4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Jan 2023 15:36:15 +0300
+Subject: wifi: ath9k: hif_usb: clean up skbs if ath9k_hif_usb_rx_stream()
+ fails
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Fedor Pchelkin <pchelkin@ispras.ru>
+
+[ Upstream commit 0af54343a76263a12dbae7fafb64eb47c4a6ad38 ]
+
+Syzkaller detected a memory leak of skbs in ath9k_hif_usb_rx_stream().
+While processing skbs in ath9k_hif_usb_rx_stream(), the already allocated
+skbs in skb_pool are not freed if ath9k_hif_usb_rx_stream() fails. If we
+have an incorrect pkt_len or pkt_tag, the input skb is considered invalid
+and dropped. All the associated packets already in skb_pool should be
+dropped and freed. Added a comment describing this issue.
+
+The patch also makes remain_skb NULL after being processed so that it
+cannot be referenced after potential free. The initialization of hif_dev
+fields which are associated with remain_skb (rx_remain_len,
+rx_transfer_len and rx_pad_len) is moved after a new remain_skb is
+allocated.
+
+Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
+
+Fixes: 6ce708f54cc8 ("ath9k: Fix out-of-bound memcpy in ath9k_hif_usb_rx_stream")
+Fixes: 44b23b488d44 ("ath9k: hif_usb: Reduce indent 1 column")
+Reported-by: syzbot+e9632e3eb038d93d6bc6@syzkaller.appspotmail.com
+Signed-off-by: Fedor Pchelkin <pchelkin@ispras.ru>
+Signed-off-by: Alexey Khoroshilov <khoroshilov@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/20230104123615.51511-1-pchelkin@ispras.ru
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath9k/hif_usb.c | 31 +++++++++++++++++-------
+ 1 file changed, 22 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
+index 1a2e0c7eeb023..de6c0824c9cab 100644
+--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
++++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
+@@ -561,11 +561,11 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
+ memcpy(ptr, skb->data, rx_remain_len);
+
+ rx_pkt_len += rx_remain_len;
+- hif_dev->rx_remain_len = 0;
+ skb_put(remain_skb, rx_pkt_len);
+
+ skb_pool[pool_index++] = remain_skb;
+-
++ hif_dev->remain_skb = NULL;
++ hif_dev->rx_remain_len = 0;
+ } else {
+ index = rx_remain_len;
+ }
+@@ -584,16 +584,21 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
+ pkt_len = get_unaligned_le16(ptr + index);
+ pkt_tag = get_unaligned_le16(ptr + index + 2);
+
++ /* It is supposed that if we have an invalid pkt_tag or
++ * pkt_len then the whole input SKB is considered invalid
++ * and dropped; the associated packets already in skb_pool
++ * are dropped, too.
++ */
+ if (pkt_tag != ATH_USB_RX_STREAM_MODE_TAG) {
+ RX_STAT_INC(hif_dev, skb_dropped);
+- return;
++ goto invalid_pkt;
+ }
+
+ if (pkt_len > 2 * MAX_RX_BUF_SIZE) {
+ dev_err(&hif_dev->udev->dev,
+ "ath9k_htc: invalid pkt_len (%x)\n", pkt_len);
+ RX_STAT_INC(hif_dev, skb_dropped);
+- return;
++ goto invalid_pkt;
+ }
+
+ pad_len = 4 - (pkt_len & 0x3);
+@@ -605,11 +610,6 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
+
+ if (index > MAX_RX_BUF_SIZE) {
+ spin_lock(&hif_dev->rx_lock);
+- hif_dev->rx_remain_len = index - MAX_RX_BUF_SIZE;
+- hif_dev->rx_transfer_len =
+- MAX_RX_BUF_SIZE - chk_idx - 4;
+- hif_dev->rx_pad_len = pad_len;
+-
+ nskb = __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC);
+ if (!nskb) {
+ dev_err(&hif_dev->udev->dev,
+@@ -617,6 +617,12 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
+ spin_unlock(&hif_dev->rx_lock);
+ goto err;
+ }
++
++ hif_dev->rx_remain_len = index - MAX_RX_BUF_SIZE;
++ hif_dev->rx_transfer_len =
++ MAX_RX_BUF_SIZE - chk_idx - 4;
++ hif_dev->rx_pad_len = pad_len;
++
+ skb_reserve(nskb, 32);
+ RX_STAT_INC(hif_dev, skb_allocated);
+
+@@ -654,6 +660,13 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
+ skb_pool[i]->len, USB_WLAN_RX_PIPE);
+ RX_STAT_INC(hif_dev, skb_completed);
+ }
++ return;
++invalid_pkt:
++ for (i = 0; i < pool_index; i++) {
++ dev_kfree_skb_any(skb_pool[i]);
++ RX_STAT_INC(hif_dev, skb_dropped);
++ }
++ return;
+ }
+
+ static void ath9k_hif_usb_rx_cb(struct urb *urb)
+--
+2.39.2
+
--- /dev/null
+From c4de15beb762fe5154211fdf673b054f9a9b99b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Jan 2023 15:35:46 +0300
+Subject: wifi: ath9k: htc_hst: free skb in ath9k_htc_rx_msg() if there is no
+ callback function
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Fedor Pchelkin <pchelkin@ispras.ru>
+
+[ Upstream commit 9b25e3985477ac3f02eca5fc1e0cc6850a3f7e69 ]
+
+It is stated that ath9k_htc_rx_msg() either frees the provided skb or
+passes its management to another callback function. However, the skb is
+not freed in case there is no another callback function, and Syzkaller was
+able to cause a memory leak. Also minor comment fix.
+
+Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
+
+Fixes: fb9987d0f748 ("ath9k_htc: Support for AR9271 chipset.")
+Reported-by: syzbot+e008dccab31bd3647609@syzkaller.appspotmail.com
+Reported-by: syzbot+6692c72009680f7c4eb2@syzkaller.appspotmail.com
+Signed-off-by: Fedor Pchelkin <pchelkin@ispras.ru>
+Signed-off-by: Alexey Khoroshilov <khoroshilov@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/20230104123546.51427-1-pchelkin@ispras.ru
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath9k/htc_hst.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c
+index ca05b07a45e67..fe62ff668f757 100644
+--- a/drivers/net/wireless/ath/ath9k/htc_hst.c
++++ b/drivers/net/wireless/ath/ath9k/htc_hst.c
+@@ -391,7 +391,7 @@ static void ath9k_htc_fw_panic_report(struct htc_target *htc_handle,
+ * HTC Messages are handled directly here and the obtained SKB
+ * is freed.
+ *
+- * Service messages (Data, WMI) passed to the corresponding
++ * Service messages (Data, WMI) are passed to the corresponding
+ * endpoint RX handlers, which have to free the SKB.
+ */
+ void ath9k_htc_rx_msg(struct htc_target *htc_handle,
+@@ -478,6 +478,8 @@ void ath9k_htc_rx_msg(struct htc_target *htc_handle,
+ if (endpoint->ep_callbacks.rx)
+ endpoint->ep_callbacks.rx(endpoint->ep_callbacks.priv,
+ skb, epid);
++ else
++ goto invalid;
+ }
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 94d3d0b9ead6faa7b7aa89d71aef4a2d7590baa4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Dec 2022 16:51:39 +0900
+Subject: wifi: brcmfmac: ensure CLM version is null-terminated to prevent
+ stack-out-of-bounds
+
+From: Jisoo Jang <jisoo.jang@yonsei.ac.kr>
+
+[ Upstream commit 660145d708be52f946a82e5b633c020f58f996de ]
+
+Fix a stack-out-of-bounds read in brcmfmac that occurs
+when 'buf' that is not null-terminated is passed as an argument of
+strreplace() in brcmf_c_preinit_dcmds(). This buffer is filled with
+a CLM version string by memcpy() in brcmf_fil_iovar_data_get().
+Ensure buf is null-terminated.
+
+Found by a modified version of syzkaller.
+
+[ 33.004414][ T1896] brcmfmac: brcmf_c_process_clm_blob: no clm_blob available (err=-2), device may have limited channels available
+[ 33.013486][ T1896] brcmfmac: brcmf_c_preinit_dcmds: Firmware: BCM43236/3 wl0: Nov 30 2011 17:33:42 version 5.90.188.22
+[ 33.021554][ T1896] ==================================================================
+[ 33.022379][ T1896] BUG: KASAN: stack-out-of-bounds in strreplace+0xf2/0x110
+[ 33.023122][ T1896] Read of size 1 at addr ffffc90001d6efc8 by task kworker/0:2/1896
+[ 33.023852][ T1896]
+[ 33.024096][ T1896] CPU: 0 PID: 1896 Comm: kworker/0:2 Tainted: G O 5.14.0+ #132
+[ 33.024927][ T1896] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014
+[ 33.026065][ T1896] Workqueue: usb_hub_wq hub_event
+[ 33.026581][ T1896] Call Trace:
+[ 33.026896][ T1896] dump_stack_lvl+0x57/0x7d
+[ 33.027372][ T1896] print_address_description.constprop.0.cold+0xf/0x334
+[ 33.028037][ T1896] ? strreplace+0xf2/0x110
+[ 33.028403][ T1896] ? strreplace+0xf2/0x110
+[ 33.028807][ T1896] kasan_report.cold+0x83/0xdf
+[ 33.029283][ T1896] ? strreplace+0xf2/0x110
+[ 33.029666][ T1896] strreplace+0xf2/0x110
+[ 33.029966][ T1896] brcmf_c_preinit_dcmds+0xab1/0xc40
+[ 33.030351][ T1896] ? brcmf_c_set_joinpref_default+0x100/0x100
+[ 33.030787][ T1896] ? rcu_read_lock_sched_held+0xa1/0xd0
+[ 33.031223][ T1896] ? rcu_read_lock_bh_held+0xb0/0xb0
+[ 33.031661][ T1896] ? lock_acquire+0x19d/0x4e0
+[ 33.032091][ T1896] ? find_held_lock+0x2d/0x110
+[ 33.032605][ T1896] ? brcmf_usb_deq+0x1a7/0x260
+[ 33.033087][ T1896] ? brcmf_usb_rx_fill_all+0x5a/0xf0
+[ 33.033582][ T1896] brcmf_attach+0x246/0xd40
+[ 33.034022][ T1896] ? wiphy_new_nm+0x1476/0x1d50
+[ 33.034383][ T1896] ? kmemdup+0x30/0x40
+[ 33.034722][ T1896] brcmf_usb_probe+0x12de/0x1690
+[ 33.035223][ T1896] ? brcmf_usbdev_qinit.constprop.0+0x470/0x470
+[ 33.035833][ T1896] usb_probe_interface+0x25f/0x710
+[ 33.036315][ T1896] really_probe+0x1be/0xa90
+[ 33.036656][ T1896] __driver_probe_device+0x2ab/0x460
+[ 33.037026][ T1896] ? usb_match_id.part.0+0x88/0xc0
+[ 33.037383][ T1896] driver_probe_device+0x49/0x120
+[ 33.037790][ T1896] __device_attach_driver+0x18a/0x250
+[ 33.038300][ T1896] ? driver_allows_async_probing+0x120/0x120
+[ 33.038986][ T1896] bus_for_each_drv+0x123/0x1a0
+[ 33.039906][ T1896] ? bus_rescan_devices+0x20/0x20
+[ 33.041412][ T1896] ? lockdep_hardirqs_on_prepare+0x273/0x3e0
+[ 33.041861][ T1896] ? trace_hardirqs_on+0x1c/0x120
+[ 33.042330][ T1896] __device_attach+0x207/0x330
+[ 33.042664][ T1896] ? device_bind_driver+0xb0/0xb0
+[ 33.043026][ T1896] ? kobject_uevent_env+0x230/0x12c0
+[ 33.043515][ T1896] bus_probe_device+0x1a2/0x260
+[ 33.043914][ T1896] device_add+0xa61/0x1ce0
+[ 33.044227][ T1896] ? __mutex_unlock_slowpath+0xe7/0x660
+[ 33.044891][ T1896] ? __fw_devlink_link_to_suppliers+0x550/0x550
+[ 33.045531][ T1896] usb_set_configuration+0x984/0x1770
+[ 33.046051][ T1896] ? kernfs_create_link+0x175/0x230
+[ 33.046548][ T1896] usb_generic_driver_probe+0x69/0x90
+[ 33.046931][ T1896] usb_probe_device+0x9c/0x220
+[ 33.047434][ T1896] really_probe+0x1be/0xa90
+[ 33.047760][ T1896] __driver_probe_device+0x2ab/0x460
+[ 33.048134][ T1896] driver_probe_device+0x49/0x120
+[ 33.048516][ T1896] __device_attach_driver+0x18a/0x250
+[ 33.048910][ T1896] ? driver_allows_async_probing+0x120/0x120
+[ 33.049437][ T1896] bus_for_each_drv+0x123/0x1a0
+[ 33.049814][ T1896] ? bus_rescan_devices+0x20/0x20
+[ 33.050164][ T1896] ? lockdep_hardirqs_on_prepare+0x273/0x3e0
+[ 33.050579][ T1896] ? trace_hardirqs_on+0x1c/0x120
+[ 33.050936][ T1896] __device_attach+0x207/0x330
+[ 33.051399][ T1896] ? device_bind_driver+0xb0/0xb0
+[ 33.051888][ T1896] ? kobject_uevent_env+0x230/0x12c0
+[ 33.052314][ T1896] bus_probe_device+0x1a2/0x260
+[ 33.052688][ T1896] device_add+0xa61/0x1ce0
+[ 33.053121][ T1896] ? __fw_devlink_link_to_suppliers+0x550/0x550
+[ 33.053568][ T1896] usb_new_device.cold+0x463/0xf66
+[ 33.053953][ T1896] ? hub_disconnect+0x400/0x400
+[ 33.054313][ T1896] ? rwlock_bug.part.0+0x90/0x90
+[ 33.054661][ T1896] ? lockdep_hardirqs_on_prepare+0x273/0x3e0
+[ 33.055094][ T1896] hub_event+0x10d5/0x3330
+[ 33.055530][ T1896] ? hub_port_debounce+0x280/0x280
+[ 33.055934][ T1896] ? __lock_acquire+0x1671/0x5790
+[ 33.056387][ T1896] ? wq_calc_node_cpumask+0x170/0x2a0
+[ 33.056924][ T1896] ? lock_release+0x640/0x640
+[ 33.057383][ T1896] ? rcu_read_lock_sched_held+0xa1/0xd0
+[ 33.057916][ T1896] ? rcu_read_lock_bh_held+0xb0/0xb0
+[ 33.058402][ T1896] ? lockdep_hardirqs_on_prepare+0x273/0x3e0
+[ 33.059019][ T1896] process_one_work+0x873/0x13e0
+[ 33.059488][ T1896] ? lock_release+0x640/0x640
+[ 33.059932][ T1896] ? pwq_dec_nr_in_flight+0x320/0x320
+[ 33.060446][ T1896] ? rwlock_bug.part.0+0x90/0x90
+[ 33.060898][ T1896] worker_thread+0x8b/0xd10
+[ 33.061348][ T1896] ? __kthread_parkme+0xd9/0x1d0
+[ 33.061810][ T1896] ? process_one_work+0x13e0/0x13e0
+[ 33.062288][ T1896] kthread+0x379/0x450
+[ 33.062660][ T1896] ? _raw_spin_unlock_irq+0x24/0x30
+[ 33.063148][ T1896] ? set_kthread_struct+0x100/0x100
+[ 33.063606][ T1896] ret_from_fork+0x1f/0x30
+[ 33.064070][ T1896]
+[ 33.064313][ T1896]
+[ 33.064545][ T1896] addr ffffc90001d6efc8 is located in stack of task kworker/0:2/1896 at offset 512 in frame:
+[ 33.065478][ T1896] brcmf_c_preinit_dcmds+0x0/0xc40
+[ 33.065973][ T1896]
+[ 33.066191][ T1896] this frame has 4 objects:
+[ 33.066614][ T1896] [48, 56) 'ptr'
+[ 33.066618][ T1896] [80, 148) 'revinfo'
+[ 33.066957][ T1896] [192, 210) 'eventmask'
+[ 33.067338][ T1896] [256, 512) 'buf'
+[ 33.067742][ T1896]
+[ 33.068304][ T1896] Memory state around the buggy address:
+[ 33.068838][ T1896] ffffc90001d6ee80: f2 00 00 02 f2 f2 f2 f2 f2 00 00 00 00 00 00 00
+[ 33.069545][ T1896] ffffc90001d6ef00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+[ 33.070626][ T1896] >ffffc90001d6ef80: 00 00 00 00 00 00 00 00 00 f3 f3 f3 f3 f3 f3 f3
+[ 33.072052][ T1896] ^
+[ 33.073043][ T1896] ffffc90001d6f000: f3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+[ 33.074230][ T1896] ffffc90001d6f080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+[ 33.074914][ T1896] ==================================================================
+[ 33.075713][ T1896] Disabling lock debugging due to kernel taint
+
+Reviewed-by: Arend van Spriel<arend.vanspriel@broadcom.com>
+Signed-off-by: Jisoo Jang <jisoo.jang@yonsei.ac.kr>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20221230075139.56591-1-jisoo.jang@yonsei.ac.kr
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+index 57bb1fbedaa87..f29de630908d7 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+@@ -281,15 +281,17 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
+ if (err) {
+ brcmf_dbg(TRACE, "retrieving clmver failed, %d\n", err);
+ } else {
++ buf[sizeof(buf) - 1] = '\0';
+ clmver = (char *)buf;
+- /* store CLM version for adding it to revinfo debugfs file */
+- memcpy(ifp->drvr->clmver, clmver, sizeof(ifp->drvr->clmver));
+
+ /* Replace all newline/linefeed characters with space
+ * character
+ */
+ strreplace(clmver, '\n', ' ');
+
++ /* store CLM version for adding it to revinfo debugfs file */
++ memcpy(ifp->drvr->clmver, clmver, sizeof(ifp->drvr->clmver));
++
+ brcmf_dbg(INFO, "CLM version = %s\n", clmver);
+ }
+
+--
+2.39.2
+
--- /dev/null
+From bfe5565e41f0d335303f46eb180de18d449f6db2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 19:33:01 +0800
+Subject: wifi: brcmfmac: fix potential memory leak in
+ brcmf_netdev_start_xmit()
+
+From: Zhang Changzhong <zhangchangzhong@huawei.com>
+
+[ Upstream commit 212fde3fe76e962598ce1d47b97cc78afdfc71b3 ]
+
+The brcmf_netdev_start_xmit() returns NETDEV_TX_OK without freeing skb
+in case of pskb_expand_head() fails, add dev_kfree_skb() to fix it.
+Compile tested only.
+
+Fixes: 270a6c1f65fe ("brcmfmac: rework headroom check in .start_xmit()")
+Signed-off-by: Zhang Changzhong <zhangchangzhong@huawei.com>
+Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/1668684782-47422-1-git-send-email-zhangchangzhong@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+index c8e1d505f7b5d..3d544eedc1a39 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+@@ -333,6 +333,7 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
+ bphy_err(drvr, "%s: failed to expand headroom\n",
+ brcmf_ifname(ifp));
+ atomic_inc(&drvr->bus_if->stats.pktcow_failed);
++ dev_kfree_skb(skb);
+ goto done;
+ }
+ }
+--
+2.39.2
+
--- /dev/null
+From aa383dbce23b9c9e65763fd6f86fb767503d0abe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Nov 2022 13:34:58 +0900
+Subject: wifi: brcmfmac: Fix potential stack-out-of-bounds in
+ brcmf_c_preinit_dcmds()
+
+From: Jisoo Jang <jisoo.jang@yonsei.ac.kr>
+
+[ Upstream commit 0a06cadcc2a0044e4a117cc0e61436fc3a0dad69 ]
+
+This patch fixes a stack-out-of-bounds read in brcmfmac that occurs
+when 'buf' that is not null-terminated is passed as an argument of
+strsep() in brcmf_c_preinit_dcmds(). This buffer is filled with a firmware
+version string by memcpy() in brcmf_fil_iovar_data_get().
+The patch ensures buf is null-terminated.
+
+Found by a modified version of syzkaller.
+
+[ 47.569679][ T1897] brcmfmac: brcmf_fw_alloc_request: using brcm/brcmfmac43236b for chip BCM43236/3
+[ 47.582839][ T1897] brcmfmac: brcmf_c_process_clm_blob: no clm_blob available (err=-2), device may have limited channels available
+[ 47.601565][ T1897] ==================================================================
+[ 47.602574][ T1897] BUG: KASAN: stack-out-of-bounds in strsep+0x1b2/0x1f0
+[ 47.603447][ T1897] Read of size 1 at addr ffffc90001f6f000 by task kworker/0:2/1897
+[ 47.604336][ T1897]
+[ 47.604621][ T1897] CPU: 0 PID: 1897 Comm: kworker/0:2 Tainted: G O 5.14.0+ #131
+[ 47.605617][ T1897] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014
+[ 47.606907][ T1897] Workqueue: usb_hub_wq hub_event
+[ 47.607453][ T1897] Call Trace:
+[ 47.607801][ T1897] dump_stack_lvl+0x8e/0xd1
+[ 47.608295][ T1897] print_address_description.constprop.0.cold+0xf/0x334
+[ 47.609009][ T1897] ? strsep+0x1b2/0x1f0
+[ 47.609434][ T1897] ? strsep+0x1b2/0x1f0
+[ 47.609863][ T1897] kasan_report.cold+0x83/0xdf
+[ 47.610366][ T1897] ? strsep+0x1b2/0x1f0
+[ 47.610882][ T1897] strsep+0x1b2/0x1f0
+[ 47.611300][ T1897] ? brcmf_fil_iovar_data_get+0x3a/0xf0
+[ 47.611883][ T1897] brcmf_c_preinit_dcmds+0x995/0xc40
+[ 47.612434][ T1897] ? brcmf_c_set_joinpref_default+0x100/0x100
+[ 47.613078][ T1897] ? rcu_read_lock_sched_held+0xa1/0xd0
+[ 47.613662][ T1897] ? rcu_read_lock_bh_held+0xb0/0xb0
+[ 47.614208][ T1897] ? lock_acquire+0x19d/0x4e0
+[ 47.614704][ T1897] ? find_held_lock+0x2d/0x110
+[ 47.615236][ T1897] ? brcmf_usb_deq+0x1a7/0x260
+[ 47.615741][ T1897] ? brcmf_usb_rx_fill_all+0x5a/0xf0
+[ 47.616288][ T1897] brcmf_attach+0x246/0xd40
+[ 47.616758][ T1897] ? wiphy_new_nm+0x1703/0x1dd0
+[ 47.617280][ T1897] ? kmemdup+0x43/0x50
+[ 47.617720][ T1897] brcmf_usb_probe+0x12de/0x1690
+[ 47.618244][ T1897] ? brcmf_usbdev_qinit.constprop.0+0x470/0x470
+[ 47.618901][ T1897] usb_probe_interface+0x2aa/0x760
+[ 47.619429][ T1897] ? usb_probe_device+0x250/0x250
+[ 47.619950][ T1897] really_probe+0x205/0xb70
+[ 47.620435][ T1897] ? driver_allows_async_probing+0x130/0x130
+[ 47.621048][ T1897] __driver_probe_device+0x311/0x4b0
+[ 47.621595][ T1897] ? driver_allows_async_probing+0x130/0x130
+[ 47.622209][ T1897] driver_probe_device+0x4e/0x150
+[ 47.622739][ T1897] __device_attach_driver+0x1cc/0x2a0
+[ 47.623287][ T1897] bus_for_each_drv+0x156/0x1d0
+[ 47.623796][ T1897] ? bus_rescan_devices+0x30/0x30
+[ 47.624309][ T1897] ? lockdep_hardirqs_on_prepare+0x273/0x3e0
+[ 47.624907][ T1897] ? trace_hardirqs_on+0x46/0x160
+[ 47.625437][ T1897] __device_attach+0x23f/0x3a0
+[ 47.625924][ T1897] ? device_bind_driver+0xd0/0xd0
+[ 47.626433][ T1897] ? kobject_uevent_env+0x287/0x14b0
+[ 47.627057][ T1897] bus_probe_device+0x1da/0x290
+[ 47.627557][ T1897] device_add+0xb7b/0x1eb0
+[ 47.628027][ T1897] ? wait_for_completion+0x290/0x290
+[ 47.628593][ T1897] ? __fw_devlink_link_to_suppliers+0x5a0/0x5a0
+[ 47.629249][ T1897] usb_set_configuration+0xf59/0x16f0
+[ 47.629829][ T1897] usb_generic_driver_probe+0x82/0xa0
+[ 47.630385][ T1897] usb_probe_device+0xbb/0x250
+[ 47.630927][ T1897] ? usb_suspend+0x590/0x590
+[ 47.631397][ T1897] really_probe+0x205/0xb70
+[ 47.631855][ T1897] ? driver_allows_async_probing+0x130/0x130
+[ 47.632469][ T1897] __driver_probe_device+0x311/0x4b0
+[ 47.633002][ T1897] ? usb_generic_driver_match+0x75/0x90
+[ 47.633573][ T1897] ? driver_allows_async_probing+0x130/0x130
+[ 47.634170][ T1897] driver_probe_device+0x4e/0x150
+[ 47.634703][ T1897] __device_attach_driver+0x1cc/0x2a0
+[ 47.635248][ T1897] bus_for_each_drv+0x156/0x1d0
+[ 47.635748][ T1897] ? bus_rescan_devices+0x30/0x30
+[ 47.636271][ T1897] ? lockdep_hardirqs_on_prepare+0x273/0x3e0
+[ 47.636881][ T1897] ? trace_hardirqs_on+0x46/0x160
+[ 47.637396][ T1897] __device_attach+0x23f/0x3a0
+[ 47.637904][ T1897] ? device_bind_driver+0xd0/0xd0
+[ 47.638426][ T1897] ? kobject_uevent_env+0x287/0x14b0
+[ 47.638985][ T1897] bus_probe_device+0x1da/0x290
+[ 47.639512][ T1897] device_add+0xb7b/0x1eb0
+[ 47.639977][ T1897] ? __fw_devlink_link_to_suppliers+0x5a0/0x5a0
+[ 47.640612][ T1897] ? kfree+0x14a/0x6b0
+[ 47.641055][ T1897] ? __usb_get_extra_descriptor+0x116/0x160
+[ 47.641679][ T1897] usb_new_device.cold+0x49c/0x1029
+[ 47.642245][ T1897] ? hub_disconnect+0x450/0x450
+[ 47.642756][ T1897] ? rwlock_bug.part.0+0x90/0x90
+[ 47.643273][ T1897] ? _raw_spin_unlock_irq+0x24/0x30
+[ 47.643822][ T1897] ? lockdep_hardirqs_on_prepare+0x273/0x3e0
+[ 47.644445][ T1897] hub_event+0x1c98/0x3950
+[ 47.644939][ T1897] ? hub_port_debounce+0x2e0/0x2e0
+[ 47.645467][ T1897] ? check_irq_usage+0x861/0xf20
+[ 47.645975][ T1897] ? drain_workqueue+0x280/0x360
+[ 47.646506][ T1897] ? lock_release+0x640/0x640
+[ 47.646994][ T1897] ? rcu_read_lock_sched_held+0xa1/0xd0
+[ 47.647572][ T1897] ? rcu_read_lock_bh_held+0xb0/0xb0
+[ 47.648111][ T1897] ? lockdep_hardirqs_on_prepare+0x273/0x3e0
+[ 47.648735][ T1897] process_one_work+0x92b/0x1460
+[ 47.649262][ T1897] ? pwq_dec_nr_in_flight+0x330/0x330
+[ 47.649816][ T1897] ? rwlock_bug.part.0+0x90/0x90
+[ 47.650336][ T1897] worker_thread+0x95/0xe00
+[ 47.650830][ T1897] ? __kthread_parkme+0x115/0x1e0
+[ 47.651361][ T1897] ? process_one_work+0x1460/0x1460
+[ 47.651904][ T1897] kthread+0x3a1/0x480
+[ 47.652329][ T1897] ? set_kthread_struct+0x120/0x120
+[ 47.652878][ T1897] ret_from_fork+0x1f/0x30
+[ 47.653370][ T1897]
+[ 47.653608][ T1897]
+[ 47.653848][ T1897] addr ffffc90001f6f000 is located in stack of task kworker/0:2/1897 at offset 512 in frame:
+[ 47.654891][ T1897] brcmf_c_preinit_dcmds+0x0/0xc40
+[ 47.655442][ T1897]
+[ 47.655690][ T1897] this frame has 4 objects:
+[ 47.656151][ T1897] [48, 56) 'ptr'
+[ 47.656159][ T1897] [80, 148) 'revinfo'
+[ 47.656534][ T1897] [192, 210) 'eventmask'
+[ 47.656953][ T1897] [256, 512) 'buf'
+[ 47.657410][ T1897]
+[ 47.658035][ T1897] Memory state around the buggy address:
+[ 47.658743][ T1897] ffffc90001f6ef00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+[ 47.659577][ T1897] ffffc90001f6ef80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+[ 47.660394][ T1897] >ffffc90001f6f000: f3 f3 f3 f3 f3 f3 f3 f3 00 00 00 00 00 00 00 00
+[ 47.661199][ T1897] ^
+[ 47.661625][ T1897] ffffc90001f6f080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+[ 47.662455][ T1897] ffffc90001f6f100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1
+[ 47.663318][ T1897] ==================================================================
+[ 47.664147][ T1897] Disabling lock debugging due to kernel taint
+
+Reported-by: Dokyung Song <dokyungs@yonsei.ac.kr>
+Reported-by: Jisoo Jang <jisoo.jang@yonsei.ac.kr>
+Reported-by: Minsuk Kang <linuxlovemin@yonsei.ac.kr>
+Signed-off-by: Jisoo Jang <jisoo.jang@yonsei.ac.kr>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20221115043458.37562-1-jisoo.jang@yonsei.ac.kr
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+index e3758bd86acf0..57bb1fbedaa87 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+@@ -264,6 +264,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
+ err);
+ goto done;
+ }
++ buf[sizeof(buf) - 1] = '\0';
+ ptr = (char *)buf;
+ strsep(&ptr, "\n");
+
+--
+2.39.2
+
--- /dev/null
+From 7d16d24fbbfe7667c0fa49e43906d8c10707cfa5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Dec 2022 09:31:14 +0800
+Subject: wifi: brcmfmac: unmap dma buffer in brcmf_msgbuf_alloc_pktid()
+
+From: Zhengchao Shao <shaozhengchao@huawei.com>
+
+[ Upstream commit b9f420032f2ba1e634b22ca7b433e5c40ea663af ]
+
+After the DMA buffer is mapped to a physical address, address is stored
+in pktids in brcmf_msgbuf_alloc_pktid(). Then, pktids is parsed in
+brcmf_msgbuf_get_pktid()/brcmf_msgbuf_release_array() to obtain physaddr
+and later unmap the DMA buffer. But when count is always equal to
+pktids->array_size, physaddr isn't stored in pktids and the DMA buffer
+will not be unmapped anyway.
+
+Fixes: 9a1bb60250d2 ("brcmfmac: Adding msgbuf protocol.")
+Signed-off-by: Zhengchao Shao <shaozhengchao@huawei.com>
+Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20221207013114.1748936-1-shaozhengchao@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
+index 7c8e08ee8f0ff..bd3b234b78038 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
+@@ -346,8 +346,11 @@ brcmf_msgbuf_alloc_pktid(struct device *dev,
+ count++;
+ } while (count < pktids->array_size);
+
+- if (count == pktids->array_size)
++ if (count == pktids->array_size) {
++ dma_unmap_single(dev, *physaddr, skb->len - data_offset,
++ pktids->direction);
+ return -ENOMEM;
++ }
+
+ array[*idx].data_offset = data_offset;
+ array[*idx].physaddr = *physaddr;
+--
+2.39.2
+
--- /dev/null
+From 9074c7804336b8b4306af5fca4340119d39c8bac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Dec 2022 20:07:14 +0530
+Subject: wifi: cfg80211: Fix extended KCK key length check in
+ nl80211_set_rekey_data()
+
+From: Shivani Baranwal <quic_shivbara@quicinc.com>
+
+[ Upstream commit df4969ca135b9b3b2c38c07514aaa775112ac835 ]
+
+The extended KCK key length check wrongly using the KEK key attribute
+for validation. Due to this GTK rekey offload is failing when the KCK
+key length is 24 bytes even though the driver advertising
+WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK flag. Use correct attribute to fix the
+same.
+
+Fixes: 093a48d2aa4b ("cfg80211: support bigger kek/kck key length")
+Signed-off-by: Shivani Baranwal <quic_shivbara@quicinc.com>
+Signed-off-by: Veerendranath Jakkam <quic_vjakkam@quicinc.com>
+Link: https://lore.kernel.org/r/20221206143715.1802987-2-quic_vjakkam@quicinc.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/nl80211.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index 8a7f0c8fba5e9..ea36d8c47b31a 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -12675,7 +12675,7 @@ static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info)
+ return -ERANGE;
+ if (nla_len(tb[NL80211_REKEY_DATA_KCK]) != NL80211_KCK_LEN &&
+ !(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK &&
+- nla_len(tb[NL80211_REKEY_DATA_KEK]) == NL80211_KCK_EXT_LEN))
++ nla_len(tb[NL80211_REKEY_DATA_KCK]) == NL80211_KCK_EXT_LEN))
+ return -ERANGE;
+
+ rekey_data.kek = nla_data(tb[NL80211_REKEY_DATA_KEK]);
+--
+2.39.2
+
--- /dev/null
+From ab513d6e90d848079ceddf1a559f36f3d0a04e84 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Dec 2022 09:24:22 +0800
+Subject: wifi: ipw2200: fix memory leak in ipw_wdev_init()
+
+From: Zhengchao Shao <shaozhengchao@huawei.com>
+
+[ Upstream commit 9fe21dc626117fb44a8eb393713a86a620128ce3 ]
+
+In the error path of ipw_wdev_init(), exception value is returned, and
+the memory applied for in the function is not released. Also the memory
+is not released in ipw_pci_probe(). As a result, memory leakage occurs.
+So memory release needs to be added to the error path of ipw_wdev_init().
+
+Fixes: a3caa99e6c68 ("libipw: initiate cfg80211 API conversion (v2)")
+Signed-off-by: Zhengchao Shao <shaozhengchao@huawei.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20221209012422.182669-1-shaozhengchao@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/ipw2x00/ipw2200.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2200.c b/drivers/net/wireless/intel/ipw2x00/ipw2200.c
+index df28e4a05e140..bb728fb24b8a4 100644
+--- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c
++++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c
+@@ -11400,9 +11400,14 @@ static int ipw_wdev_init(struct net_device *dev)
+ set_wiphy_dev(wdev->wiphy, &priv->pci_dev->dev);
+
+ /* With that information in place, we can now register the wiphy... */
+- if (wiphy_register(wdev->wiphy))
+- rc = -EIO;
++ rc = wiphy_register(wdev->wiphy);
++ if (rc)
++ goto out;
++
++ return 0;
+ out:
++ kfree(priv->ieee->a_band.channels);
++ kfree(priv->ieee->bg_band.channels);
+ return rc;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 02a49ad9b2e01e43e2b61009de1533e10af3347a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Dec 2022 22:38:26 +0800
+Subject: wifi: ipw2x00: don't call dev_kfree_skb() under spin_lock_irqsave()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 45fc6d7461f18df2f238caf0cbc5acc4163203d1 ]
+
+It is not allowed to call kfree_skb() or consume_skb() from hardware
+interrupt context or with hardware interrupts being disabled.
+
+It should use dev_kfree_skb_irq() or dev_consume_skb_irq() instead.
+The difference between them is free reason, dev_kfree_skb_irq() means
+the SKB is dropped in error and dev_consume_skb_irq() means the SKB
+is consumed in normal.
+
+In this case, dev_kfree_skb() is called to free and drop the SKB when
+it's reset, so replace it with dev_kfree_skb_irq(). Compile tested
+only.
+
+Fixes: 43f66a6ce8da ("Add ipw2200 wireless driver.")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20221208143826.2385218-1-yangyingliang@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/ipw2x00/ipw2200.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2200.c b/drivers/net/wireless/intel/ipw2x00/ipw2200.c
+index ada6ce32c1f19..df28e4a05e140 100644
+--- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c
++++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c
+@@ -3444,7 +3444,7 @@ static void ipw_rx_queue_reset(struct ipw_priv *priv,
+ dma_unmap_single(&priv->pci_dev->dev,
+ rxq->pool[i].dma_addr,
+ IPW_RX_BUF_SIZE, DMA_FROM_DEVICE);
+- dev_kfree_skb(rxq->pool[i].skb);
++ dev_kfree_skb_irq(rxq->pool[i].skb);
+ rxq->pool[i].skb = NULL;
+ }
+ list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
+--
+2.39.2
+
--- /dev/null
+From cad31ec121d150b9c1c10210628362f588b2e99f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Feb 2023 14:30:32 +0800
+Subject: wifi: iwl3945: Add missing check for create_singlethread_workqueue
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit 1fdeb8b9f29dfd64805bb49475ac7566a3cb06cb ]
+
+Add the check for the return value of the create_singlethread_workqueue
+in order to avoid NULL pointer dereference.
+
+Fixes: b481de9ca074 ("[IWLWIFI]: add iwlwifi wireless drivers")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20230208063032.42763-2-jiasheng@iscas.ac.cn
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlegacy/3945-mac.c | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/wireless/intel/iwlegacy/3945-mac.c b/drivers/net/wireless/intel/iwlegacy/3945-mac.c
+index 4ca8212d4fa4b..ef0ac42a55a2a 100644
+--- a/drivers/net/wireless/intel/iwlegacy/3945-mac.c
++++ b/drivers/net/wireless/intel/iwlegacy/3945-mac.c
+@@ -3380,10 +3380,12 @@ static DEVICE_ATTR(dump_errors, 0200, NULL, il3945_dump_error_log);
+ *
+ *****************************************************************************/
+
+-static void
++static int
+ il3945_setup_deferred_work(struct il_priv *il)
+ {
+ il->workqueue = create_singlethread_workqueue(DRV_NAME);
++ if (!il->workqueue)
++ return -ENOMEM;
+
+ init_waitqueue_head(&il->wait_command_queue);
+
+@@ -3400,6 +3402,8 @@ il3945_setup_deferred_work(struct il_priv *il)
+ timer_setup(&il->watchdog, il_bg_watchdog, 0);
+
+ tasklet_setup(&il->irq_tasklet, il3945_irq_tasklet);
++
++ return 0;
+ }
+
+ static void
+@@ -3721,7 +3725,10 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ }
+
+ il_set_rxon_channel(il, &il->bands[NL80211_BAND_2GHZ].channels[5]);
+- il3945_setup_deferred_work(il);
++ err = il3945_setup_deferred_work(il);
++ if (err)
++ goto out_remove_sysfs;
++
+ il3945_setup_handlers(il);
+ il_power_initialize(il);
+
+@@ -3733,7 +3740,7 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+
+ err = il3945_setup_mac(il);
+ if (err)
+- goto out_remove_sysfs;
++ goto out_destroy_workqueue;
+
+ il_dbgfs_register(il, DRV_NAME);
+
+@@ -3742,9 +3749,10 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+
+ return 0;
+
+-out_remove_sysfs:
++out_destroy_workqueue:
+ destroy_workqueue(il->workqueue);
+ il->workqueue = NULL;
++out_remove_sysfs:
+ sysfs_remove_group(&pdev->dev.kobj, &il3945_attribute_group);
+ out_release_irq:
+ free_irq(il->pci_dev->irq, il);
+--
+2.39.2
+
--- /dev/null
+From e0d5a3722a88796a5afebbeadcfe4630220782a9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Feb 2023 09:07:48 +0800
+Subject: wifi: iwl4965: Add missing check for create_singlethread_workqueue()
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit 26e6775f75517ad6844fe5b79bc5f3fa8c22ee61 ]
+
+Add the check for the return value of the create_singlethread_workqueue()
+in order to avoid NULL pointer dereference.
+
+Fixes: b481de9ca074 ("[IWLWIFI]: add iwlwifi wireless drivers")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20230209010748.45454-1-jiasheng@iscas.ac.cn
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlegacy/4965-mac.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/intel/iwlegacy/4965-mac.c b/drivers/net/wireless/intel/iwlegacy/4965-mac.c
+index 28675a4ad8612..12cf22d0e9949 100644
+--- a/drivers/net/wireless/intel/iwlegacy/4965-mac.c
++++ b/drivers/net/wireless/intel/iwlegacy/4965-mac.c
+@@ -6212,10 +6212,12 @@ il4965_bg_txpower_work(struct work_struct *work)
+ mutex_unlock(&il->mutex);
+ }
+
+-static void
++static int
+ il4965_setup_deferred_work(struct il_priv *il)
+ {
+ il->workqueue = create_singlethread_workqueue(DRV_NAME);
++ if (!il->workqueue)
++ return -ENOMEM;
+
+ init_waitqueue_head(&il->wait_command_queue);
+
+@@ -6234,6 +6236,8 @@ il4965_setup_deferred_work(struct il_priv *il)
+ timer_setup(&il->watchdog, il_bg_watchdog, 0);
+
+ tasklet_setup(&il->irq_tasklet, il4965_irq_tasklet);
++
++ return 0;
+ }
+
+ static void
+@@ -6623,7 +6627,10 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ goto out_disable_msi;
+ }
+
+- il4965_setup_deferred_work(il);
++ err = il4965_setup_deferred_work(il);
++ if (err)
++ goto out_free_irq;
++
+ il4965_setup_handlers(il);
+
+ /*********************************************
+@@ -6661,6 +6668,7 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ out_destroy_workqueue:
+ destroy_workqueue(il->workqueue);
+ il->workqueue = NULL;
++out_free_irq:
+ free_irq(il->pci_dev->irq, il);
+ out_disable_msi:
+ pci_disable_msi(il->pci_dev);
+--
+2.39.2
+
--- /dev/null
+From b30eeae6e7ad8bcad97da8e60f117ee8d1dd0788 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Dec 2022 22:40:13 +0800
+Subject: wifi: iwlegacy: common: don't call dev_kfree_skb() under
+ spin_lock_irqsave()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 0c1528675d7a9787cb516b64d8f6c0f6f8efcb48 ]
+
+It is not allowed to call consume_skb() from hardware interrupt context
+or with interrupts being disabled. So replace dev_kfree_skb() with
+dev_consume_skb_irq() under spin_lock_irqsave(). Compile tested only.
+
+Fixes: 4bc85c1324aa ("Revert "iwlwifi: split the drivers for agn and legacy devices 3945/4965"")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20221207144013.70210-1-yangyingliang@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlegacy/common.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/intel/iwlegacy/common.c b/drivers/net/wireless/intel/iwlegacy/common.c
+index 0651a6a416d1d..4b55779de00a9 100644
+--- a/drivers/net/wireless/intel/iwlegacy/common.c
++++ b/drivers/net/wireless/intel/iwlegacy/common.c
+@@ -5176,7 +5176,7 @@ il_mac_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+ memset(&il->current_ht_config, 0, sizeof(struct il_ht_config));
+
+ /* new association get rid of ibss beacon skb */
+- dev_kfree_skb(il->beacon_skb);
++ dev_consume_skb_irq(il->beacon_skb);
+ il->beacon_skb = NULL;
+ il->timestamp = 0;
+
+@@ -5295,7 +5295,7 @@ il_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+ }
+
+ spin_lock_irqsave(&il->lock, flags);
+- dev_kfree_skb(il->beacon_skb);
++ dev_consume_skb_irq(il->beacon_skb);
+ il->beacon_skb = skb;
+
+ timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
+--
+2.39.2
+
--- /dev/null
+From 925be14589500d4ccd43b011073f8b7d60913d53 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Dec 2022 23:00:08 +0800
+Subject: wifi: libertas: cmdresp: don't call kfree_skb() under
+ spin_lock_irqsave()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 708a49a64237f19bd404852f297aaadbc9e7fee0 ]
+
+It is not allowed to call kfree_skb() from hardware interrupt
+context or with interrupts being disabled. So replace kfree_skb()
+with dev_kfree_skb_irq() under spin_lock_irqsave(). Compile
+tested only.
+
+Fixes: f52b041aed77 ("libertas: Add spinlock to avoid race condition")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20221207150008.111743-5-yangyingliang@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/marvell/libertas/cmdresp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/marvell/libertas/cmdresp.c b/drivers/net/wireless/marvell/libertas/cmdresp.c
+index cb515c5584c1f..74cb7551f4275 100644
+--- a/drivers/net/wireless/marvell/libertas/cmdresp.c
++++ b/drivers/net/wireless/marvell/libertas/cmdresp.c
+@@ -48,7 +48,7 @@ void lbs_mac_event_disconnected(struct lbs_private *priv,
+
+ /* Free Tx and Rx packets */
+ spin_lock_irqsave(&priv->driver_lock, flags);
+- kfree_skb(priv->currenttxskb);
++ dev_kfree_skb_irq(priv->currenttxskb);
+ priv->currenttxskb = NULL;
+ priv->tx_pending_len = 0;
+ spin_unlock_irqrestore(&priv->driver_lock, flags);
+--
+2.39.2
+
--- /dev/null
+From 693f9e8973b2492bc3cf80f82c4593af7fd0913b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Dec 2022 20:14:48 +0800
+Subject: wifi: libertas: fix memory leak in lbs_init_adapter()
+
+From: Zhengchao Shao <shaozhengchao@huawei.com>
+
+[ Upstream commit 16a03958618fb91bb1bc7077cf3211055162cc2f ]
+
+When kfifo_alloc() failed in lbs_init_adapter(), cmd buffer is not
+released. Add free memory to processing error path.
+
+Fixes: 7919b89c8276 ("libertas: convert libertas driver to use an event/cmdresp queue")
+Signed-off-by: Zhengchao Shao <shaozhengchao@huawei.com>
+Reviewed-by: Jiri Pirko <jiri@nvidia.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20221208121448.2845986-1-shaozhengchao@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/marvell/libertas/main.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/marvell/libertas/main.c b/drivers/net/wireless/marvell/libertas/main.c
+index ee4cf3437e28a..36237457d1363 100644
+--- a/drivers/net/wireless/marvell/libertas/main.c
++++ b/drivers/net/wireless/marvell/libertas/main.c
+@@ -870,6 +870,7 @@ static int lbs_init_adapter(struct lbs_private *priv)
+ ret = kfifo_alloc(&priv->event_fifo, sizeof(u32) * 16, GFP_KERNEL);
+ if (ret) {
+ pr_err("Out of memory allocating event FIFO buffer\n");
++ lbs_free_cmd_buffer(priv);
+ goto out;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From f1d00c648f465bf974b60eb9ec959e6849e625f7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Dec 2022 23:00:06 +0800
+Subject: wifi: libertas: if_usb: don't call kfree_skb() under
+ spin_lock_irqsave()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 3968e81ba644f10a7d45bae2539560db9edac501 ]
+
+It is not allowed to call kfree_skb() from hardware interrupt
+context or with interrupts being disabled. So replace kfree_skb()
+with dev_kfree_skb_irq() under spin_lock_irqsave(). Compile
+tested only.
+
+Fixes: a3128feef6d5 ("libertas: use irqsave() in USB's complete callback")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20221207150008.111743-3-yangyingliang@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/marvell/libertas/if_usb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/marvell/libertas/if_usb.c b/drivers/net/wireless/marvell/libertas/if_usb.c
+index 32fdc4150b605..2240b4db8c036 100644
+--- a/drivers/net/wireless/marvell/libertas/if_usb.c
++++ b/drivers/net/wireless/marvell/libertas/if_usb.c
+@@ -637,7 +637,7 @@ static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff,
+ priv->resp_len[i] = (recvlength - MESSAGE_HEADER_LEN);
+ memcpy(priv->resp_buf[i], recvbuff + MESSAGE_HEADER_LEN,
+ priv->resp_len[i]);
+- kfree_skb(skb);
++ dev_kfree_skb_irq(skb);
+ lbs_notify_command_response(priv, i);
+
+ spin_unlock_irqrestore(&priv->driver_lock, flags);
+--
+2.39.2
+
--- /dev/null
+From 6cf1867c2995cae2c21093c05f6dbb458c817f70 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Dec 2022 23:00:07 +0800
+Subject: wifi: libertas: main: don't call kfree_skb() under
+ spin_lock_irqsave()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit f393df151540bf858effbd29ff572ab94e76a4c4 ]
+
+It is not allowed to call kfree_skb() from hardware interrupt
+context or with interrupts being disabled. So replace kfree_skb()
+with dev_kfree_skb_irq() under spin_lock_irqsave(). Compile
+tested only.
+
+Fixes: d2e7b3425c47 ("libertas: disable functionality when interface is down")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20221207150008.111743-4-yangyingliang@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/marvell/libertas/main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/marvell/libertas/main.c b/drivers/net/wireless/marvell/libertas/main.c
+index 36237457d1363..1c56cc2742b07 100644
+--- a/drivers/net/wireless/marvell/libertas/main.c
++++ b/drivers/net/wireless/marvell/libertas/main.c
+@@ -217,7 +217,7 @@ int lbs_stop_iface(struct lbs_private *priv)
+
+ spin_lock_irqsave(&priv->driver_lock, flags);
+ priv->iface_running = false;
+- kfree_skb(priv->currenttxskb);
++ dev_kfree_skb_irq(priv->currenttxskb);
+ priv->currenttxskb = NULL;
+ priv->tx_pending_len = 0;
+ spin_unlock_irqrestore(&priv->driver_lock, flags);
+--
+2.39.2
+
--- /dev/null
+From c05dff2ea3e642be397db7a03a90d39be7927889 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Dec 2022 23:00:05 +0800
+Subject: wifi: libertas_tf: don't call kfree_skb() under spin_lock_irqsave()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 9388ce97b98216833c969191ee6df61a7201d797 ]
+
+It is not allowed to call kfree_skb() from hardware interrupt
+context or with interrupts being disabled. So replace kfree_skb()
+with dev_kfree_skb_irq() under spin_lock_irqsave(). Compile
+tested only.
+
+Fixes: fc75122fabb5 ("libertas_tf: use irqsave() in USB's complete callback")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20221207150008.111743-2-yangyingliang@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/marvell/libertas_tf/if_usb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/marvell/libertas_tf/if_usb.c b/drivers/net/wireless/marvell/libertas_tf/if_usb.c
+index ecce8b56f8a28..2c45ef6e04077 100644
+--- a/drivers/net/wireless/marvell/libertas_tf/if_usb.c
++++ b/drivers/net/wireless/marvell/libertas_tf/if_usb.c
+@@ -613,7 +613,7 @@ static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff,
+ spin_lock_irqsave(&priv->driver_lock, flags);
+ memcpy(priv->cmd_resp_buff, recvbuff + MESSAGE_HEADER_LEN,
+ recvlength - MESSAGE_HEADER_LEN);
+- kfree_skb(skb);
++ dev_kfree_skb_irq(skb);
+ lbtf_cmd_response_rx(priv);
+ spin_unlock_irqrestore(&priv->driver_lock, flags);
+ }
+--
+2.39.2
+
--- /dev/null
+From 7e20a9270f4dade928d996ec1d894e712bc99442 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Feb 2023 19:06:59 +0800
+Subject: wifi: mac80211: make rate u32 in sta_set_rate_info_rx()
+
+From: Shayne Chen <shayne.chen@mediatek.com>
+
+[ Upstream commit 59336e07b287d91dc4ec265e07724e8f7e3d0209 ]
+
+The value of last_rate in ieee80211_sta_rx_stats is degraded from u32 to
+u16 after being assigned to rate variable, which causes information loss
+in STA_STATS_FIELD_TYPE and later bitfields.
+
+Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
+Link: https://lore.kernel.org/r/20230209110659.25447-1-shayne.chen@mediatek.com
+Fixes: 41cbb0f5a295 ("mac80211: add support for HE")
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/sta_info.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
+index cee39ae52245c..d572478c4d68e 100644
+--- a/net/mac80211/sta_info.c
++++ b/net/mac80211/sta_info.c
+@@ -2159,7 +2159,7 @@ static void sta_stats_decode_rate(struct ieee80211_local *local, u32 rate,
+
+ static int sta_set_rate_info_rx(struct sta_info *sta, struct rate_info *rinfo)
+ {
+- u16 rate = READ_ONCE(sta_get_last_rx_stats(sta)->last_rate);
++ u32 rate = READ_ONCE(sta_get_last_rx_stats(sta)->last_rate);
+
+ if (rate == STA_STATS_RATE_INVALID)
+ return -EINVAL;
+--
+2.39.2
+
--- /dev/null
+From 9723498900d87895499ebe4af0e38bbc3eb3e7a5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 1 Jan 2023 12:47:57 +0100
+Subject: wifi: mt76: dma: free rx_head in mt76_dma_rx_cleanup
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ Upstream commit 1b88b47e898edef0e56e3a2f4e49f052a136153d ]
+
+Free rx_head skb in mt76_dma_rx_cleanup routine in order to avoid
+possible memory leak at module unload.
+
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/dma.c | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c
+index f01b455783b23..7991705e9d134 100644
+--- a/drivers/net/wireless/mediatek/mt76/dma.c
++++ b/drivers/net/wireless/mediatek/mt76/dma.c
+@@ -476,6 +476,7 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
+ bool more;
+
+ spin_lock_bh(&q->lock);
++
+ do {
+ buf = mt76_dma_dequeue(dev, q, true, NULL, NULL, &more);
+ if (!buf)
+@@ -483,6 +484,12 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
+
+ skb_free_frag(buf);
+ } while (1);
++
++ if (q->rx_head) {
++ dev_kfree_skb(q->rx_head);
++ q->rx_head = NULL;
++ }
++
+ spin_unlock_bh(&q->lock);
+
+ if (!q->rx_page.va)
+@@ -505,12 +512,6 @@ mt76_dma_rx_reset(struct mt76_dev *dev, enum mt76_rxq_id qid)
+ mt76_dma_rx_cleanup(dev, q);
+ mt76_dma_sync_idx(dev, q);
+ mt76_dma_rx_fill(dev, q);
+-
+- if (!q->rx_head)
+- return;
+-
+- dev_kfree_skb(q->rx_head);
+- q->rx_head = NULL;
+ }
+
+ static void
+--
+2.39.2
+
--- /dev/null
+From bb1523198ac048ae28eb7e82bd5f6c33931d499f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Dec 2022 18:29:06 +0900
+Subject: wifi: mt7601u: fix an integer underflow
+
+From: Jisoo Jang <jisoo.jang@yonsei.ac.kr>
+
+[ Upstream commit 803f3176c5df3b5582c27ea690f204abb60b19b9 ]
+
+Fix an integer underflow that leads to a null pointer dereference in
+'mt7601u_rx_skb_from_seg()'. The variable 'dma_len' in the URB packet
+could be manipulated, which could trigger an integer underflow of
+'seg_len' in 'mt7601u_rx_process_seg()'. This underflow subsequently
+causes the 'bad_frame' checks in 'mt7601u_rx_skb_from_seg()' to be
+bypassed, eventually leading to a dereference of the pointer 'p', which
+is a null pointer.
+
+Ensure that 'dma_len' is greater than 'min_seg_len'.
+
+Found by a modified version of syzkaller.
+
+KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f]
+CPU: 0 PID: 12 Comm: ksoftirqd/0 Tainted: G W O 5.14.0+
+#139
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
+rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014
+RIP: 0010:skb_add_rx_frag+0x143/0x370
+Code: e2 07 83 c2 03 38 ca 7c 08 84 c9 0f 85 86 01 00 00 4c 8d 7d 08 44
+89 68 08 48 b8 00 00 00 00 00 fc ff df 4c 89 fa 48 c1 ea 03 <80> 3c 02
+00 0f 85 cd 01 00 00 48 8b 45 08 a8 01 0f 85 3d 01 00 00
+RSP: 0018:ffffc900000cfc90 EFLAGS: 00010202
+RAX: dffffc0000000000 RBX: ffff888115520dc0 RCX: 0000000000000000
+RDX: 0000000000000001 RSI: ffff8881118430c0 RDI: ffff8881118430f8
+RBP: 0000000000000000 R08: 0000000000000e09 R09: 0000000000000010
+R10: ffff888111843017 R11: ffffed1022308602 R12: 0000000000000000
+R13: 0000000000000e09 R14: 0000000000000010 R15: 0000000000000008
+FS: 0000000000000000(0000) GS:ffff88811a800000(0000)
+knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 000000004035af40 CR3: 00000001157f2000 CR4: 0000000000750ef0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+PKRU: 55555554
+Call Trace:
+ mt7601u_rx_tasklet+0xc73/0x1270
+ ? mt7601u_submit_rx_buf.isra.0+0x510/0x510
+ ? tasklet_action_common.isra.0+0x79/0x2f0
+ tasklet_action_common.isra.0+0x206/0x2f0
+ __do_softirq+0x1b5/0x880
+ ? tasklet_unlock+0x30/0x30
+ run_ksoftirqd+0x26/0x50
+ smpboot_thread_fn+0x34f/0x7d0
+ ? smpboot_register_percpu_thread+0x370/0x370
+ kthread+0x3a1/0x480
+ ? set_kthread_struct+0x120/0x120
+ ret_from_fork+0x1f/0x30
+Modules linked in: 88XXau(O) 88x2bu(O)
+---[ end trace 57f34f93b4da0f9b ]---
+RIP: 0010:skb_add_rx_frag+0x143/0x370
+Code: e2 07 83 c2 03 38 ca 7c 08 84 c9 0f 85 86 01 00 00 4c 8d 7d 08 44
+89 68 08 48 b8 00 00 00 00 00 fc ff df 4c 89 fa 48 c1 ea 03 <80> 3c 02
+00 0f 85 cd 01 00 00 48 8b 45 08 a8 01 0f 85 3d 01 00 00
+RSP: 0018:ffffc900000cfc90 EFLAGS: 00010202
+RAX: dffffc0000000000 RBX: ffff888115520dc0 RCX: 0000000000000000
+RDX: 0000000000000001 RSI: ffff8881118430c0 RDI: ffff8881118430f8
+RBP: 0000000000000000 R08: 0000000000000e09 R09: 0000000000000010
+R10: ffff888111843017 R11: ffffed1022308602 R12: 0000000000000000
+R13: 0000000000000e09 R14: 0000000000000010 R15: 0000000000000008
+FS: 0000000000000000(0000) GS:ffff88811a800000(0000)
+knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 000000004035af40 CR3: 00000001157f2000 CR4: 0000000000750ef0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+PKRU: 55555554
+
+Signed-off-by: Jisoo Jang <jisoo.jang@yonsei.ac.kr>
+Acked-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20221229092906.2328282-1-jisoo.jang@yonsei.ac.kr
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt7601u/dma.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt7601u/dma.c b/drivers/net/wireless/mediatek/mt7601u/dma.c
+index 11071519fce81..8ba291abecff8 100644
+--- a/drivers/net/wireless/mediatek/mt7601u/dma.c
++++ b/drivers/net/wireless/mediatek/mt7601u/dma.c
+@@ -118,7 +118,8 @@ static u16 mt7601u_rx_next_seg_len(u8 *data, u32 data_len)
+ if (data_len < min_seg_len ||
+ WARN_ON_ONCE(!dma_len) ||
+ WARN_ON_ONCE(dma_len + MT_DMA_HDRS > data_len) ||
+- WARN_ON_ONCE(dma_len & 0x3))
++ WARN_ON_ONCE(dma_len & 0x3) ||
++ WARN_ON_ONCE(dma_len < min_seg_len))
+ return 0;
+
+ return MT_DMA_HDRS + dma_len;
+--
+2.39.2
+
--- /dev/null
+From a9200f3a1036d07c264b93b642a08528fe99081e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Feb 2023 17:41:33 +0300
+Subject: wifi: mwifiex: fix loop iterator in mwifiex_update_ampdu_txwinsize()
+
+From: Dan Carpenter <error27@gmail.com>
+
+[ Upstream commit 3cfb7df24cee0f5fdc4cc5d3176cab9aadfcb430 ]
+
+This code re-uses "i" to be the iterator for both the inside and outside
+loops. It means the outside loop will exit earlier than intended.
+
+Fixes: d219b7eb3792 ("mwifiex: handle BT coex event to adjust Rx BA window size")
+Signed-off-by: Dan Carpenter <error27@gmail.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/Y+ERnaDaZD7RtLvX@kili
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/marvell/mwifiex/11n.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/wireless/marvell/mwifiex/11n.c b/drivers/net/wireless/marvell/mwifiex/11n.c
+index cf08a4af84d6d..b99381ebb82a1 100644
+--- a/drivers/net/wireless/marvell/mwifiex/11n.c
++++ b/drivers/net/wireless/marvell/mwifiex/11n.c
+@@ -890,7 +890,7 @@ mwifiex_send_delba_txbastream_tbl(struct mwifiex_private *priv, u8 tid)
+ */
+ void mwifiex_update_ampdu_txwinsize(struct mwifiex_adapter *adapter)
+ {
+- u8 i;
++ u8 i, j;
+ u32 tx_win_size;
+ struct mwifiex_private *priv;
+
+@@ -921,8 +921,8 @@ void mwifiex_update_ampdu_txwinsize(struct mwifiex_adapter *adapter)
+ if (tx_win_size != priv->add_ba_param.tx_win_size) {
+ if (!priv->media_connected)
+ continue;
+- for (i = 0; i < MAX_NUM_TID; i++)
+- mwifiex_send_delba_txbastream_tbl(priv, i);
++ for (j = 0; j < MAX_NUM_TID; j++)
++ mwifiex_send_delba_txbastream_tbl(priv, j);
+ }
+ }
+ }
+--
+2.39.2
+
--- /dev/null
+From f3064e5ad4cd0be57b928662e3f181d026c1cf31 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Dec 2022 16:33:06 +0300
+Subject: wifi: orinoco: check return value of hermes_write_wordrec()
+
+From: Alexey Kodanev <aleksei.kodanev@bell-sw.com>
+
+[ Upstream commit 1e346cbb096a5351a637ec1992beffbf330547f0 ]
+
+There is currently no return check for writing an authentication
+type (HERMES_AUTH_SHARED_KEY or HERMES_AUTH_OPEN). It looks like
+it was accidentally skipped.
+
+This patch adds a return check similar to the other checks in
+__orinoco_hw_setup_enc() for hermes_write_wordrec().
+
+Detected using the static analysis tool - Svace.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Alexey Kodanev <aleksei.kodanev@bell-sw.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20221227133306.201356-1-aleksei.kodanev@bell-sw.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intersil/orinoco/hw.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/wireless/intersil/orinoco/hw.c b/drivers/net/wireless/intersil/orinoco/hw.c
+index 61af5a28f269f..af49aa421e47f 100644
+--- a/drivers/net/wireless/intersil/orinoco/hw.c
++++ b/drivers/net/wireless/intersil/orinoco/hw.c
+@@ -931,6 +931,8 @@ int __orinoco_hw_setup_enc(struct orinoco_private *priv)
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFAUTHENTICATION_AGERE,
+ auth_flag);
++ if (err)
++ return err;
+ }
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFWEPENABLED_AGERE,
+--
+2.39.2
+
--- /dev/null
+From 08cdba02ee888359ede79f08b008cc3d62394ad1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Dec 2022 06:14:41 +0000
+Subject: wifi: rsi: Fix memory leak in rsi_coex_attach()
+
+From: Yuan Can <yuancan@huawei.com>
+
+[ Upstream commit 956fb851a6e19da5ab491e19c1bc323bb2c2cf6f ]
+
+The coex_cb needs to be freed when rsi_create_kthread() failed in
+rsi_coex_attach().
+
+Fixes: 2108df3c4b18 ("rsi: add coex support")
+Signed-off-by: Yuan Can <yuancan@huawei.com>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20221205061441.114632-1-yuancan@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/rsi/rsi_91x_coex.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/rsi/rsi_91x_coex.c b/drivers/net/wireless/rsi/rsi_91x_coex.c
+index a0c5d02ae88cf..7395359b43b77 100644
+--- a/drivers/net/wireless/rsi/rsi_91x_coex.c
++++ b/drivers/net/wireless/rsi/rsi_91x_coex.c
+@@ -160,6 +160,7 @@ int rsi_coex_attach(struct rsi_common *common)
+ rsi_coex_scheduler_thread,
+ "Coex-Tx-Thread")) {
+ rsi_dbg(ERR_ZONE, "%s: Unable to init tx thrd\n", __func__);
++ kfree(coex_cb);
+ return -EINVAL;
+ }
+ return 0;
+--
+2.39.2
+
--- /dev/null
+From 8e98d14bf2e9ecb598a2a26675abbafa57ffb194 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Dec 2022 22:35:17 +0800
+Subject: wifi: rtl8xxxu: don't call dev_kfree_skb() under spin_lock_irqsave()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 4c2005ac87685907b3719b4f40215b578efd27c4 ]
+
+It is not allowed to call kfree_skb() or consume_skb() from hardware
+interrupt context or with hardware interrupts being disabled.
+
+It should use dev_kfree_skb_irq() or dev_consume_skb_irq() instead.
+The difference between them is free reason, dev_kfree_skb_irq() means
+the SKB is dropped in error and dev_consume_skb_irq() means the SKB
+is consumed in normal.
+
+In this case, dev_kfree_skb() is called to free and drop the SKB when
+it's shutdown, so replace it with dev_kfree_skb_irq(). Compile tested
+only.
+
+Fixes: 26f1fad29ad9 ("New driver: rtl8xxxu (mac80211)")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20221208143517.2383424-1-yangyingliang@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
+index 2cb86c28d11fe..f8b1871fe290a 100644
+--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
+@@ -5184,7 +5184,7 @@ static void rtl8xxxu_queue_rx_urb(struct rtl8xxxu_priv *priv,
+ pending = priv->rx_urb_pending_count;
+ } else {
+ skb = (struct sk_buff *)rx_urb->urb.context;
+- dev_kfree_skb(skb);
++ dev_kfree_skb_irq(skb);
+ usb_free_urb(&rx_urb->urb);
+ }
+
+--
+2.39.2
+
--- /dev/null
+From ef352171a0ec01b270581329055ab288afd48d7c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Dec 2022 13:48:04 +0200
+Subject: wifi: rtl8xxxu: Fix memory leaks with RTL8723BU, RTL8192EU
+
+From: Bitterblue Smith <rtl8821cerfe2@gmail.com>
+
+[ Upstream commit b39f662ce1648db0b9de32e6a849b098480793cb ]
+
+The wifi + bluetooth combo chip RTL8723BU can leak memory (especially?)
+when it's connected to a bluetooth audio device. The busy bluetooth
+traffic generates lots of C2H (card to host) messages, which are not
+freed correctly.
+
+To fix this, move the dev_kfree_skb() call in rtl8xxxu_c2hcmd_callback()
+inside the loop where skb_dequeue() is called.
+
+The RTL8192EU leaks memory because the C2H messages are added to the
+queue and left there forever. (This was fine in the past because it
+probably wasn't sending any C2H messages until commit e542e66b7c2e
+("wifi: rtl8xxxu: gen2: Turn on the rate control"). Since that commit
+it sends a C2H message when the TX rate changes.)
+
+To fix this, delete the check for rf_paths > 1 and the goto. Let the
+function process the C2H messages from RTL8192EU like the ones from
+the other chips.
+
+Theoretically the RTL8188FU could also leak like RTL8723BU, but it
+most likely doesn't send C2H messages frequently enough.
+
+This change was tested with RTL8723BU by Erhard F. I tested it with
+RTL8188FU and RTL8192EU.
+
+Reported-by: Erhard F. <erhard_f@mailbox.org>
+Tested-by: Erhard F. <erhard_f@mailbox.org>
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=215197
+Fixes: e542e66b7c2e ("rtl8xxxu: add bluetooth co-existence support for single antenna")
+Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
+Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/03b099c1-c671-d252-36f4-57b70d721f9d@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
+index f8b1871fe290a..376782b7aba81 100644
+--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
+@@ -5491,9 +5491,6 @@ static void rtl8xxxu_c2hcmd_callback(struct work_struct *work)
+ btcoex = &priv->bt_coex;
+ rarpt = &priv->ra_report;
+
+- if (priv->rf_paths > 1)
+- goto out;
+-
+ while (!skb_queue_empty(&priv->c2hcmd_queue)) {
+ spin_lock_irqsave(&priv->c2hcmd_lock, flags);
+ skb = __skb_dequeue(&priv->c2hcmd_queue);
+@@ -5547,10 +5544,9 @@ static void rtl8xxxu_c2hcmd_callback(struct work_struct *work)
+ default:
+ break;
+ }
+- }
+
+-out:
+- dev_kfree_skb(skb);
++ dev_kfree_skb(skb);
++ }
+ }
+
+ static void rtl8723bu_handle_c2h(struct rtl8xxxu_priv *priv,
+--
+2.39.2
+
--- /dev/null
+From bd90884fe597706a925ba5aadb61682a7e15b3e5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 Dec 2022 10:58:12 +0800
+Subject: wifi: rtlwifi: Fix global-out-of-bounds bug in
+ _rtl8812ae_phy_set_txpower_limit()
+
+From: Li Zetao <lizetao1@huawei.com>
+
+[ Upstream commit 117dbeda22ec5ea0918254d03b540ef8b8a64d53 ]
+
+There is a global-out-of-bounds reported by KASAN:
+
+ BUG: KASAN: global-out-of-bounds in
+ _rtl8812ae_eq_n_byte.part.0+0x3d/0x84 [rtl8821ae]
+ Read of size 1 at addr ffffffffa0773c43 by task NetworkManager/411
+
+ CPU: 6 PID: 411 Comm: NetworkManager Tainted: G D
+ 6.1.0-rc8+ #144 e15588508517267d37
+ Hardware name: QEMU Standard PC (Q35 + ICH9, 2009),
+ Call Trace:
+ <TASK>
+ ...
+ kasan_report+0xbb/0x1c0
+ _rtl8812ae_eq_n_byte.part.0+0x3d/0x84 [rtl8821ae]
+ rtl8821ae_phy_bb_config.cold+0x346/0x641 [rtl8821ae]
+ rtl8821ae_hw_init+0x1f5e/0x79b0 [rtl8821ae]
+ ...
+ </TASK>
+
+The root cause of the problem is that the comparison order of
+"prate_section" in _rtl8812ae_phy_set_txpower_limit() is wrong. The
+_rtl8812ae_eq_n_byte() is used to compare the first n bytes of the two
+strings from tail to head, which causes the problem. In the
+_rtl8812ae_phy_set_txpower_limit(), it was originally intended to meet
+this requirement by carefully designing the comparison order.
+For example, "pregulation" and "pbandwidth" are compared in order of
+length from small to large, first is 3 and last is 4. However, the
+comparison order of "prate_section" dose not obey such order requirement,
+therefore when "prate_section" is "HT", when comparing from tail to head,
+it will lead to access out of bounds in _rtl8812ae_eq_n_byte(). As
+mentioned above, the _rtl8812ae_eq_n_byte() has the same function as
+strcmp(), so just strcmp() is enough.
+
+Fix it by removing _rtl8812ae_eq_n_byte() and use strcmp() barely.
+Although it can be fixed by adjusting the comparison order of
+"prate_section", this may cause the value of "rate_section" to not be
+from 0 to 5. In addition, commit "21e4b0726dc6" not only moved driver
+from staging to regular tree, but also added setting txpower limit
+function during the driver config phase, so the problem was introduced
+by this commit.
+
+Fixes: 21e4b0726dc6 ("rtlwifi: rtl8821ae: Move driver from staging to regular tree")
+Signed-off-by: Li Zetao <lizetao1@huawei.com>
+Acked-by: Ping-Ke Shih <pkshih@realtek.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20221212025812.1541311-1-lizetao1@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../wireless/realtek/rtlwifi/rtl8821ae/phy.c | 52 +++++++------------
+ 1 file changed, 20 insertions(+), 32 deletions(-)
+
+diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c
+index 119e0f799826f..c0c06ab6d3e76 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c
++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c
+@@ -1599,18 +1599,6 @@ static bool _rtl8812ae_get_integer_from_string(const char *str, u8 *pint)
+ return true;
+ }
+
+-static bool _rtl8812ae_eq_n_byte(const char *str1, const char *str2, u32 num)
+-{
+- if (num == 0)
+- return false;
+- while (num > 0) {
+- num--;
+- if (str1[num] != str2[num])
+- return false;
+- }
+- return true;
+-}
+-
+ static s8 _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(struct ieee80211_hw *hw,
+ u8 band, u8 channel)
+ {
+@@ -1660,42 +1648,42 @@ static void _rtl8812ae_phy_set_txpower_limit(struct ieee80211_hw *hw,
+ power_limit = power_limit > MAX_POWER_INDEX ?
+ MAX_POWER_INDEX : power_limit;
+
+- if (_rtl8812ae_eq_n_byte(pregulation, "FCC", 3))
++ if (strcmp(pregulation, "FCC") == 0)
+ regulation = 0;
+- else if (_rtl8812ae_eq_n_byte(pregulation, "MKK", 3))
++ else if (strcmp(pregulation, "MKK") == 0)
+ regulation = 1;
+- else if (_rtl8812ae_eq_n_byte(pregulation, "ETSI", 4))
++ else if (strcmp(pregulation, "ETSI") == 0)
+ regulation = 2;
+- else if (_rtl8812ae_eq_n_byte(pregulation, "WW13", 4))
++ else if (strcmp(pregulation, "WW13") == 0)
+ regulation = 3;
+
+- if (_rtl8812ae_eq_n_byte(prate_section, "CCK", 3))
++ if (strcmp(prate_section, "CCK") == 0)
+ rate_section = 0;
+- else if (_rtl8812ae_eq_n_byte(prate_section, "OFDM", 4))
++ else if (strcmp(prate_section, "OFDM") == 0)
+ rate_section = 1;
+- else if (_rtl8812ae_eq_n_byte(prate_section, "HT", 2) &&
+- _rtl8812ae_eq_n_byte(prf_path, "1T", 2))
++ else if (strcmp(prate_section, "HT") == 0 &&
++ strcmp(prf_path, "1T") == 0)
+ rate_section = 2;
+- else if (_rtl8812ae_eq_n_byte(prate_section, "HT", 2) &&
+- _rtl8812ae_eq_n_byte(prf_path, "2T", 2))
++ else if (strcmp(prate_section, "HT") == 0 &&
++ strcmp(prf_path, "2T") == 0)
+ rate_section = 3;
+- else if (_rtl8812ae_eq_n_byte(prate_section, "VHT", 3) &&
+- _rtl8812ae_eq_n_byte(prf_path, "1T", 2))
++ else if (strcmp(prate_section, "VHT") == 0 &&
++ strcmp(prf_path, "1T") == 0)
+ rate_section = 4;
+- else if (_rtl8812ae_eq_n_byte(prate_section, "VHT", 3) &&
+- _rtl8812ae_eq_n_byte(prf_path, "2T", 2))
++ else if (strcmp(prate_section, "VHT") == 0 &&
++ strcmp(prf_path, "2T") == 0)
+ rate_section = 5;
+
+- if (_rtl8812ae_eq_n_byte(pbandwidth, "20M", 3))
++ if (strcmp(pbandwidth, "20M") == 0)
+ bandwidth = 0;
+- else if (_rtl8812ae_eq_n_byte(pbandwidth, "40M", 3))
++ else if (strcmp(pbandwidth, "40M") == 0)
+ bandwidth = 1;
+- else if (_rtl8812ae_eq_n_byte(pbandwidth, "80M", 3))
++ else if (strcmp(pbandwidth, "80M") == 0)
+ bandwidth = 2;
+- else if (_rtl8812ae_eq_n_byte(pbandwidth, "160M", 4))
++ else if (strcmp(pbandwidth, "160M") == 0)
+ bandwidth = 3;
+
+- if (_rtl8812ae_eq_n_byte(pband, "2.4G", 4)) {
++ if (strcmp(pband, "2.4G") == 0) {
+ ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
+ BAND_ON_2_4G,
+ channel);
+@@ -1719,7 +1707,7 @@ static void _rtl8812ae_phy_set_txpower_limit(struct ieee80211_hw *hw,
+ regulation, bandwidth, rate_section, channel_index,
+ rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
+ [rate_section][channel_index][RF90_PATH_A]);
+- } else if (_rtl8812ae_eq_n_byte(pband, "5G", 2)) {
++ } else if (strcmp(pband, "5G") == 0) {
+ ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
+ BAND_ON_5G,
+ channel);
+--
+2.39.2
+
--- /dev/null
+From 495ef48a4b006618c83eb67921ac776e4fe9f10e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Dec 2022 22:14:10 +0800
+Subject: wifi: rtlwifi: rtl8188ee: don't call kfree_skb() under
+ spin_lock_irqsave()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 2611687fa7ffc84190f92292de0b80468de17220 ]
+
+It is not allowed to call kfree_skb() from hardware interrupt
+context or with interrupts being disabled. All the SKBs have
+been dequeued from the old queue, so it's safe to enqueue these
+SKBs to a free queue, then free them after spin_unlock_irqrestore()
+at once. Compile tested only.
+
+Fixes: 7fe3b3abb5da ("rtlwifi: rtl8188ee: rtl8821ae: Fix a queue locking problem")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Acked-by: Ping-Ke Shih <pkshih@realtek.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20221207141411.46098-3-yangyingliang@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c
+index 63f9ea21962f2..335a3c9cdbab6 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c
++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c
+@@ -68,8 +68,10 @@ static void _rtl88ee_return_beacon_queue_skb(struct ieee80211_hw *hw)
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[BEACON_QUEUE];
++ struct sk_buff_head free_list;
+ unsigned long flags;
+
++ skb_queue_head_init(&free_list);
+ spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
+ while (skb_queue_len(&ring->queue)) {
+ struct rtl_tx_desc *entry = &ring->desc[ring->idx];
+@@ -79,10 +81,12 @@ static void _rtl88ee_return_beacon_queue_skb(struct ieee80211_hw *hw)
+ rtlpriv->cfg->ops->get_desc(hw, (u8 *)entry,
+ true, HW_DESC_TXBUFF_ADDR),
+ skb->len, DMA_TO_DEVICE);
+- kfree_skb(skb);
++ __skb_queue_tail(&free_list, skb);
+ ring->idx = (ring->idx + 1) % ring->entries;
+ }
+ spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
++
++ __skb_queue_purge(&free_list);
+ }
+
+ static void _rtl88ee_disable_bcn_sub_func(struct ieee80211_hw *hw)
+--
+2.39.2
+
--- /dev/null
+From 268464cde04fe4d9a8c102a53d574becb1b2fce9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Dec 2022 22:14:11 +0800
+Subject: wifi: rtlwifi: rtl8723be: don't call kfree_skb() under
+ spin_lock_irqsave()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 313950c2114e7051c4e3020fd82495fa1fb526a8 ]
+
+It is not allowed to call kfree_skb() from hardware interrupt
+context or with interrupts being disabled. All the SKBs have
+been dequeued from the old queue, so it's safe to enqueue these
+SKBs to a free queue, then free them after spin_unlock_irqrestore()
+at once. Compile tested only.
+
+Fixes: 5c99f04fec93 ("rtlwifi: rtl8723be: Update driver to match Realtek release of 06/28/14")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Acked-by: Ping-Ke Shih <pkshih@realtek.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20221207141411.46098-4-yangyingliang@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c
+index 0748aedce2adb..ccbb082d5e928 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c
++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c
+@@ -30,8 +30,10 @@ static void _rtl8723be_return_beacon_queue_skb(struct ieee80211_hw *hw)
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[BEACON_QUEUE];
++ struct sk_buff_head free_list;
+ unsigned long flags;
+
++ skb_queue_head_init(&free_list);
+ spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
+ while (skb_queue_len(&ring->queue)) {
+ struct rtl_tx_desc *entry = &ring->desc[ring->idx];
+@@ -41,10 +43,12 @@ static void _rtl8723be_return_beacon_queue_skb(struct ieee80211_hw *hw)
+ rtlpriv->cfg->ops->get_desc(hw, (u8 *)entry,
+ true, HW_DESC_TXBUFF_ADDR),
+ skb->len, DMA_TO_DEVICE);
+- kfree_skb(skb);
++ __skb_queue_tail(&free_list, skb);
+ ring->idx = (ring->idx + 1) % ring->entries;
+ }
+ spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
++
++ __skb_queue_purge(&free_list);
+ }
+
+ static void _rtl8723be_set_bcn_ctrl_reg(struct ieee80211_hw *hw,
+--
+2.39.2
+
--- /dev/null
+From 2790a6a52d90b928cdbe3bec676e505833ecd684 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Dec 2022 22:14:09 +0800
+Subject: wifi: rtlwifi: rtl8821ae: don't call kfree_skb() under
+ spin_lock_irqsave()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 106031c1f4a850915190d7ec1026696282f9359b ]
+
+It is not allowed to call kfree_skb() from hardware interrupt
+context or with interrupts being disabled. All the SKBs have
+been dequeued from the old queue, so it's safe to enqueue these
+SKBs to a free queue, then free them after spin_unlock_irqrestore()
+at once. Compile tested only.
+
+Fixes: 5c99f04fec93 ("rtlwifi: rtl8723be: Update driver to match Realtek release of 06/28/14")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Acked-by: Ping-Ke Shih <pkshih@realtek.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20221207141411.46098-2-yangyingliang@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c
+index 33ffc24d36759..c4ee65cc2d5e6 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c
++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c
+@@ -26,8 +26,10 @@ static void _rtl8821ae_return_beacon_queue_skb(struct ieee80211_hw *hw)
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[BEACON_QUEUE];
++ struct sk_buff_head free_list;
+ unsigned long flags;
+
++ skb_queue_head_init(&free_list);
+ spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
+ while (skb_queue_len(&ring->queue)) {
+ struct rtl_tx_desc *entry = &ring->desc[ring->idx];
+@@ -37,10 +39,12 @@ static void _rtl8821ae_return_beacon_queue_skb(struct ieee80211_hw *hw)
+ rtlpriv->cfg->ops->get_desc(hw, (u8 *)entry,
+ true, HW_DESC_TXBUFF_ADDR),
+ skb->len, DMA_TO_DEVICE);
+- kfree_skb(skb);
++ __skb_queue_tail(&free_list, skb);
+ ring->idx = (ring->idx + 1) % ring->entries;
+ }
+ spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
++
++ __skb_queue_purge(&free_list);
+ }
+
+ static void _rtl8821ae_set_bcn_ctrl_reg(struct ieee80211_hw *hw,
+--
+2.39.2
+
--- /dev/null
+From cd24f118a3beb61509820f95d006fc1515a11c80 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 19:36:03 +0800
+Subject: wifi: wilc1000: fix potential memory leak in wilc_mac_xmit()
+
+From: Zhang Changzhong <zhangchangzhong@huawei.com>
+
+[ Upstream commit deb962ec9e1c9a81babd3d37542ad4bd6ac3396e ]
+
+The wilc_mac_xmit() returns NETDEV_TX_OK without freeing skb, add
+dev_kfree_skb() to fix it. Compile tested only.
+
+Fixes: c5c77ba18ea6 ("staging: wilc1000: Add SDIO/SPI 802.11 driver")
+Signed-off-by: Zhang Changzhong <zhangchangzhong@huawei.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/1668684964-48622-1-git-send-email-zhangchangzhong@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/microchip/wilc1000/netdev.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/microchip/wilc1000/netdev.c b/drivers/net/wireless/microchip/wilc1000/netdev.c
+index 20615c7ec1683..c508f429984ab 100644
+--- a/drivers/net/wireless/microchip/wilc1000/netdev.c
++++ b/drivers/net/wireless/microchip/wilc1000/netdev.c
+@@ -684,6 +684,7 @@ netdev_tx_t wilc_mac_xmit(struct sk_buff *skb, struct net_device *ndev)
+
+ if (skb->dev != ndev) {
+ netdev_err(ndev, "Packet not destined to this device\n");
++ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 58f4f2d8ae4a2e712ee40ade01eaf11e5d81f667 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Dec 2022 23:04:53 +0800
+Subject: wifi: wl3501_cs: don't call kfree_skb() under spin_lock_irqsave()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 44bacbdf9066c590423259dbd6d520baac99c1a8 ]
+
+It is not allowed to call kfree_skb() from hardware interrupt
+context or with interrupts being disabled. So replace kfree_skb()
+with dev_kfree_skb_irq() under spin_lock_irqsave(). Compile
+tested only.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20221207150453.114742-1-yangyingliang@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/wl3501_cs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
+index ff1701adbb179..ccf6344ed6fd2 100644
+--- a/drivers/net/wireless/wl3501_cs.c
++++ b/drivers/net/wireless/wl3501_cs.c
+@@ -1330,7 +1330,7 @@ static netdev_tx_t wl3501_hard_start_xmit(struct sk_buff *skb,
+ } else {
+ ++dev->stats.tx_packets;
+ dev->stats.tx_bytes += skb->len;
+- kfree_skb(skb);
++ dev_kfree_skb_irq(skb);
+
+ if (this->tx_buffer_cnt < 2)
+ netif_stop_queue(dev);
+--
+2.39.2
+
--- /dev/null
+From ff9760006999ab25365b96690bcd7875df9d2345 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Nov 2022 07:31:48 -0800
+Subject: x86/bugs: Reset speculation control settings on init
+
+From: Breno Leitao <leitao@debian.org>
+
+[ Upstream commit 0125acda7d76b943ca55811df40ed6ec0ecf670f ]
+
+Currently, x86_spec_ctrl_base is read at boot time and speculative bits
+are set if Kconfig items are enabled. For example, IBRS is enabled if
+CONFIG_CPU_IBRS_ENTRY is configured, etc. These MSR bits are not cleared
+if the mitigations are disabled.
+
+This is a problem when kexec-ing a kernel that has the mitigation
+disabled from a kernel that has the mitigation enabled. In this case,
+the MSR bits are not cleared during the new kernel boot. As a result,
+this might have some performance degradation that is hard to pinpoint.
+
+This problem does not happen if the machine is (hard) rebooted because
+the bit will be cleared by default.
+
+ [ bp: Massage. ]
+
+Suggested-by: Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
+Signed-off-by: Breno Leitao <leitao@debian.org>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Link: https://lore.kernel.org/r/20221128153148.1129350-1-leitao@debian.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/include/asm/msr-index.h | 4 ++++
+ arch/x86/kernel/cpu/bugs.c | 10 +++++++++-
+ 2 files changed, 13 insertions(+), 1 deletion(-)
+
+diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
+index 5a8ee3b83af2a..f71a177b6b185 100644
+--- a/arch/x86/include/asm/msr-index.h
++++ b/arch/x86/include/asm/msr-index.h
+@@ -54,6 +54,10 @@
+ #define SPEC_CTRL_RRSBA_DIS_S_SHIFT 6 /* Disable RRSBA behavior */
+ #define SPEC_CTRL_RRSBA_DIS_S BIT(SPEC_CTRL_RRSBA_DIS_S_SHIFT)
+
++/* A mask for bits which the kernel toggles when controlling mitigations */
++#define SPEC_CTRL_MITIGATIONS_MASK (SPEC_CTRL_IBRS | SPEC_CTRL_STIBP | SPEC_CTRL_SSBD \
++ | SPEC_CTRL_RRSBA_DIS_S)
++
+ #define MSR_IA32_PRED_CMD 0x00000049 /* Prediction Command */
+ #define PRED_CMD_IBPB BIT(0) /* Indirect Branch Prediction Barrier */
+
+diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
+index a2a087a797ae5..c5034986ea444 100644
+--- a/arch/x86/kernel/cpu/bugs.c
++++ b/arch/x86/kernel/cpu/bugs.c
+@@ -136,9 +136,17 @@ void __init check_bugs(void)
+ * have unknown values. AMD64_LS_CFG MSR is cached in the early AMD
+ * init code as it is not enumerated and depends on the family.
+ */
+- if (boot_cpu_has(X86_FEATURE_MSR_SPEC_CTRL))
++ if (cpu_feature_enabled(X86_FEATURE_MSR_SPEC_CTRL)) {
+ rdmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base);
+
++ /*
++ * Previously running kernel (kexec), may have some controls
++ * turned ON. Clear them and let the mitigations setup below
++ * rediscover them based on configuration.
++ */
++ x86_spec_ctrl_base &= ~SPEC_CTRL_MITIGATIONS_MASK;
++ }
++
+ /* Select the proper CPU mitigations before patching alternatives: */
+ spectre_v1_select_mitigation();
+ spectre_v2_select_mitigation();
+--
+2.39.2
+
--- /dev/null
+From 9fb8013e59e337b3b3e0ce32c6875fc8835a6e2d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 May 2021 23:29:25 +0200
+Subject: x86/cpu: Init AP exception handling from cpu_init_secondary()
+
+From: Borislav Petkov <bp@suse.de>
+
+[ Upstream commit b1efd0ff4bd16e8bb8607ba566b03f2024a830bb ]
+
+SEV-ES guests require properly setup task register with which the TSS
+descriptor in the GDT can be located so that the IST-type #VC exception
+handler which they need to function properly, can be executed.
+
+This setup needs to happen before attempting to load microcode in
+ucode_cpu_init() on secondary CPUs which can cause such #VC exceptions.
+
+Simplify the machinery by running that exception setup from a new function
+cpu_init_secondary() and explicitly call cpu_init_exception_handling() for
+the boot CPU before cpu_init(). The latter prepares for fixing and
+simplifying the exception/IST setup on the boot CPU.
+
+There should be no functional changes resulting from this patch.
+
+[ tglx: Reworked it so cpu_init_exception_handling() stays seperate ]
+
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Reviewed-by: Lai Jiangshan <laijs@linux.alibaba.com>
+Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lore.kernel.org/r/87k0o6gtvu.ffs@nanos.tec.linutronix.de
+Stable-dep-of: c0dd9245aa9e ("x86/microcode: Check CPU capabilities after late microcode update correctly")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/include/asm/processor.h | 1 +
+ arch/x86/kernel/cpu/common.c | 28 +++++++++++++++-------------
+ arch/x86/kernel/smpboot.c | 3 +--
+ arch/x86/kernel/traps.c | 4 +---
+ 4 files changed, 18 insertions(+), 18 deletions(-)
+
+diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
+index d428d611a43a9..388541ec77aad 100644
+--- a/arch/x86/include/asm/processor.h
++++ b/arch/x86/include/asm/processor.h
+@@ -682,6 +682,7 @@ extern void load_direct_gdt(int);
+ extern void load_fixmap_gdt(int);
+ extern void load_percpu_segment(int);
+ extern void cpu_init(void);
++extern void cpu_init_secondary(void);
+ extern void cpu_init_exception_handling(void);
+ extern void cr4_init(void);
+
+diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
+index 56573241d0293..4402589a1ee19 100644
+--- a/arch/x86/kernel/cpu/common.c
++++ b/arch/x86/kernel/cpu/common.c
+@@ -2048,13 +2048,12 @@ void cpu_init_exception_handling(void)
+
+ /*
+ * cpu_init() initializes state that is per-CPU. Some data is already
+- * initialized (naturally) in the bootstrap process, such as the GDT
+- * and IDT. We reload them nevertheless, this function acts as a
+- * 'CPU state barrier', nothing should get across.
++ * initialized (naturally) in the bootstrap process, such as the GDT. We
++ * reload it nevertheless, this function acts as a 'CPU state barrier',
++ * nothing should get across.
+ */
+ void cpu_init(void)
+ {
+- struct tss_struct *tss = this_cpu_ptr(&cpu_tss_rw);
+ struct task_struct *cur = current;
+ int cpu = raw_smp_processor_id();
+
+@@ -2067,8 +2066,6 @@ void cpu_init(void)
+ early_cpu_to_node(cpu) != NUMA_NO_NODE)
+ set_numa_node(early_cpu_to_node(cpu));
+ #endif
+- setup_getcpu(cpu);
+-
+ pr_debug("Initializing CPU#%d\n", cpu);
+
+ if (IS_ENABLED(CONFIG_X86_64) || cpu_feature_enabled(X86_FEATURE_VME) ||
+@@ -2080,7 +2077,6 @@ void cpu_init(void)
+ * and set up the GDT descriptor:
+ */
+ switch_to_new_gdt(cpu);
+- load_current_idt();
+
+ if (IS_ENABLED(CONFIG_X86_64)) {
+ loadsegment(fs, 0);
+@@ -2100,12 +2096,6 @@ void cpu_init(void)
+ initialize_tlbstate_and_flush();
+ enter_lazy_tlb(&init_mm, cur);
+
+- /* Initialize the TSS. */
+- tss_setup_ist(tss);
+- tss_setup_io_bitmap(tss);
+- set_tss_desc(cpu, &get_cpu_entry_area(cpu)->tss.x86_tss);
+-
+- load_TR_desc();
+ /*
+ * sp0 points to the entry trampoline stack regardless of what task
+ * is running.
+@@ -2127,6 +2117,18 @@ void cpu_init(void)
+ load_fixmap_gdt(cpu);
+ }
+
++#ifdef CONFIG_SMP
++void cpu_init_secondary(void)
++{
++ /*
++ * Relies on the BP having set-up the IDT tables, which are loaded
++ * on this CPU in cpu_init_exception_handling().
++ */
++ cpu_init_exception_handling();
++ cpu_init();
++}
++#endif
++
+ /*
+ * The microcode loader calls this upon late microcode load to recheck features,
+ * only when microcode has been updated. Caller holds microcode_mutex and CPU
+diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
+index e8e5515fb7e9c..bda89ecc7799f 100644
+--- a/arch/x86/kernel/smpboot.c
++++ b/arch/x86/kernel/smpboot.c
+@@ -227,8 +227,7 @@ static void notrace start_secondary(void *unused)
+ load_cr3(swapper_pg_dir);
+ __flush_tlb_all();
+ #endif
+- cpu_init_exception_handling();
+- cpu_init();
++ cpu_init_secondary();
+ rcu_cpu_starting(raw_smp_processor_id());
+ x86_cpuinit.early_percpu_clock_init();
+ smp_callin();
+diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
+index 2a39a2df6f43e..3780c728345c3 100644
+--- a/arch/x86/kernel/traps.c
++++ b/arch/x86/kernel/traps.c
+@@ -1185,9 +1185,7 @@ void __init trap_init(void)
+
+ idt_setup_traps();
+
+- /*
+- * Should be a barrier for any external CPU state:
+- */
++ cpu_init_exception_handling();
+ cpu_init();
+
+ idt_setup_ist_traps();
+--
+2.39.2
+
--- /dev/null
+From 47462fc45be3c25f4948ec12e619d2201ba18d00 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Mar 2022 16:30:47 +0100
+Subject: x86: Mark stop_this_cpu() __noreturn
+
+From: Peter Zijlstra <peterz@infradead.org>
+
+[ Upstream commit f9cdf7ca57cada055f61ef6d0eb4db21c3f200db ]
+
+vmlinux.o: warning: objtool: smp_stop_nmi_callback()+0x2b: unreachable instruction
+
+0000 0000000000047cf0 <smp_stop_nmi_callback>:
+...
+0026 47d16: e8 00 00 00 00 call 47d1b <smp_stop_nmi_callback+0x2b> 47d17: R_X86_64_PLT32 stop_this_cpu-0x4
+002b 47d1b: b8 01 00 00 00 mov $0x1,%eax
+
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Acked-by: Josh Poimboeuf <jpoimboe@redhat.com>
+Link: https://lore.kernel.org/r/20220308154319.290905453@infradead.org
+Stable-dep-of: c0dd9245aa9e ("x86/microcode: Check CPU capabilities after late microcode update correctly")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/include/asm/processor.h | 2 +-
+ arch/x86/kernel/process.c | 2 +-
+ tools/objtool/check.c | 1 +
+ 3 files changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
+index 388541ec77aad..01bcbf8a25b29 100644
+--- a/arch/x86/include/asm/processor.h
++++ b/arch/x86/include/asm/processor.h
+@@ -839,7 +839,7 @@ bool xen_set_default_idle(void);
+ #define xen_set_default_idle 0
+ #endif
+
+-void stop_this_cpu(void *dummy);
++void __noreturn stop_this_cpu(void *dummy);
+ void microcode_check(void);
+
+ enum l1tf_mitigations {
+diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
+index 5e17c3939dd1c..1cba09a9f1c13 100644
+--- a/arch/x86/kernel/process.c
++++ b/arch/x86/kernel/process.c
+@@ -720,7 +720,7 @@ bool xen_set_default_idle(void)
+ }
+ #endif
+
+-void stop_this_cpu(void *dummy)
++void __noreturn stop_this_cpu(void *dummy)
+ {
+ local_irq_disable();
+ /*
+diff --git a/tools/objtool/check.c b/tools/objtool/check.c
+index 985bcc5cea8a4..ff47aed7ef6fe 100644
+--- a/tools/objtool/check.c
++++ b/tools/objtool/check.c
+@@ -180,6 +180,7 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,
+ "kunit_try_catch_throw",
+ "xen_start_kernel",
+ "cpu_bringup_and_idle",
++ "stop_this_cpu",
+ };
+
+ if (!func)
+--
+2.39.2
+
--- /dev/null
+From 619a2fe99a192cca4928022fd8cb3a6855b4ab02 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Jan 2023 07:35:50 -0800
+Subject: x86/microcode: Add a parameter to microcode_check() to store CPU
+ capabilities
+
+From: Ashok Raj <ashok.raj@intel.com>
+
+[ Upstream commit ab31c74455c64e69342ddab21fd9426fcbfefde7 ]
+
+Add a parameter to store CPU capabilities before performing a microcode
+update so that CPU capabilities can be compared before and after update.
+
+ [ bp: Massage. ]
+
+Signed-off-by: Ashok Raj <ashok.raj@intel.com>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Link: https://lore.kernel.org/r/20230109153555.4986-2-ashok.raj@intel.com
+Stable-dep-of: c0dd9245aa9e ("x86/microcode: Check CPU capabilities after late microcode update correctly")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/include/asm/processor.h | 2 +-
+ arch/x86/kernel/cpu/common.c | 21 +++++++++++++--------
+ arch/x86/kernel/cpu/microcode/core.c | 3 ++-
+ 3 files changed, 16 insertions(+), 10 deletions(-)
+
+diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
+index 01bcbf8a25b29..6d40c409ebc16 100644
+--- a/arch/x86/include/asm/processor.h
++++ b/arch/x86/include/asm/processor.h
+@@ -840,7 +840,7 @@ bool xen_set_default_idle(void);
+ #endif
+
+ void __noreturn stop_this_cpu(void *dummy);
+-void microcode_check(void);
++void microcode_check(struct cpuinfo_x86 *prev_info);
+
+ enum l1tf_mitigations {
+ L1TF_MITIGATION_OFF,
+diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
+index 95f52540db378..f724002adbfc3 100644
+--- a/arch/x86/kernel/cpu/common.c
++++ b/arch/x86/kernel/cpu/common.c
+@@ -2130,30 +2130,35 @@ void cpu_init_secondary(void)
+ #endif
+
+ #ifdef CONFIG_MICROCODE_LATE_LOADING
+-/*
++/**
++ * microcode_check() - Check if any CPU capabilities changed after an update.
++ * @prev_info: CPU capabilities stored before an update.
++ *
+ * The microcode loader calls this upon late microcode load to recheck features,
+ * only when microcode has been updated. Caller holds microcode_mutex and CPU
+ * hotplug lock.
++ *
++ * Return: None
+ */
+-void microcode_check(void)
++void microcode_check(struct cpuinfo_x86 *prev_info)
+ {
+- struct cpuinfo_x86 info;
+-
+ perf_check_microcode();
+
+ /* Reload CPUID max function as it might've changed. */
+- info.cpuid_level = cpuid_eax(0);
++ prev_info->cpuid_level = cpuid_eax(0);
+
+ /*
+ * Copy all capability leafs to pick up the synthetic ones so that
+ * memcmp() below doesn't fail on that. The ones coming from CPUID will
+ * get overwritten in get_cpu_cap().
+ */
+- memcpy(&info.x86_capability, &boot_cpu_data.x86_capability, sizeof(info.x86_capability));
++ memcpy(&prev_info->x86_capability, &boot_cpu_data.x86_capability,
++ sizeof(prev_info->x86_capability));
+
+- get_cpu_cap(&info);
++ get_cpu_cap(prev_info);
+
+- if (!memcmp(&info.x86_capability, &boot_cpu_data.x86_capability, sizeof(info.x86_capability)))
++ if (!memcmp(&prev_info->x86_capability, &boot_cpu_data.x86_capability,
++ sizeof(prev_info->x86_capability)))
+ return;
+
+ pr_warn("x86/CPU: CPU features have changed after loading microcode, but might not take effect.\n");
+diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
+index 707a385943b41..2c70f3cfae68e 100644
+--- a/arch/x86/kernel/cpu/microcode/core.c
++++ b/arch/x86/kernel/cpu/microcode/core.c
+@@ -509,13 +509,14 @@ static int __reload_late(void *info)
+ static int microcode_reload_late(void)
+ {
+ int old = boot_cpu_data.microcode, ret;
++ struct cpuinfo_x86 prev_info;
+
+ atomic_set(&late_cpus_in, 0);
+ atomic_set(&late_cpus_out, 0);
+
+ ret = stop_machine_cpuslocked(__reload_late, NULL, cpu_online_mask);
+ if (ret == 0)
+- microcode_check();
++ microcode_check(&prev_info);
+
+ pr_info("Reload completed, microcode revision: 0x%x -> 0x%x\n",
+ old, boot_cpu_data.microcode);
+--
+2.39.2
+
--- /dev/null
+From e1e7132b8dfad21362eb68a4077183530d6ab75f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Jan 2023 07:35:52 -0800
+Subject: x86/microcode: Adjust late loading result reporting message
+
+From: Ashok Raj <ashok.raj@intel.com>
+
+[ Upstream commit 6eab3abac7043226e5375e9ead0c7607ced6767b ]
+
+During late microcode loading, the "Reload completed" message is issued
+unconditionally, regardless of success or failure.
+
+Adjust the message to report the result of the update.
+
+ [ bp: Massage. ]
+
+Fixes: 9bd681251b7c ("x86/microcode: Announce reload operation's completion")
+Suggested-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Ashok Raj <ashok.raj@intel.com>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Reviewed-by: Tony Luck <tony.luck@intel.com>
+Link: https://lore.kernel.org/lkml/874judpqqd.ffs@tglx/
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/cpu/microcode/core.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
+index 122da99bac4e4..36583bc4b88c3 100644
+--- a/arch/x86/kernel/cpu/microcode/core.c
++++ b/arch/x86/kernel/cpu/microcode/core.c
+@@ -521,11 +521,14 @@ static int microcode_reload_late(void)
+ store_cpu_caps(&prev_info);
+
+ ret = stop_machine_cpuslocked(__reload_late, NULL, cpu_online_mask);
+- if (ret == 0)
++ if (!ret) {
++ pr_info("Reload succeeded, microcode revision: 0x%x -> 0x%x\n",
++ old, boot_cpu_data.microcode);
+ microcode_check(&prev_info);
+-
+- pr_info("Reload completed, microcode revision: 0x%x -> 0x%x\n",
+- old, boot_cpu_data.microcode);
++ } else {
++ pr_info("Reload failed, current microcode revision: 0x%x\n",
++ boot_cpu_data.microcode);
++ }
+
+ return ret;
+ }
+--
+2.39.2
+
--- /dev/null
+From ae91fb90e0b9558407ec5ba02208b1c2a00aa205 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Jan 2023 07:35:51 -0800
+Subject: x86/microcode: Check CPU capabilities after late microcode update
+ correctly
+
+From: Ashok Raj <ashok.raj@intel.com>
+
+[ Upstream commit c0dd9245aa9e25a697181f6085692272c9ec61bc ]
+
+The kernel caches each CPU's feature bits at boot in an x86_capability[]
+structure. However, the capabilities in the BSP's copy can be turned off
+as a result of certain command line parameters or configuration
+restrictions, for example the SGX bit. This can cause a mismatch when
+comparing the values before and after the microcode update.
+
+Another example is X86_FEATURE_SRBDS_CTRL which gets added only after
+microcode update:
+
+ --- cpuid.before 2023-01-21 14:54:15.652000747 +0100
+ +++ cpuid.after 2023-01-21 14:54:26.632001024 +0100
+ @@ -10,7 +10,7 @@ CPU:
+ 0x00000004 0x04: eax=0x00000000 ebx=0x00000000 ecx=0x00000000 edx=0x00000000
+ 0x00000005 0x00: eax=0x00000040 ebx=0x00000040 ecx=0x00000003 edx=0x11142120
+ 0x00000006 0x00: eax=0x000027f7 ebx=0x00000002 ecx=0x00000001 edx=0x00000000
+ - 0x00000007 0x00: eax=0x00000000 ebx=0x029c6fbf ecx=0x40000000 edx=0xbc002400
+ + 0x00000007 0x00: eax=0x00000000 ebx=0x029c6fbf ecx=0x40000000 edx=0xbc002e00
+ ^^^
+
+and which proves for a gazillionth time that late loading is a bad bad
+idea.
+
+microcode_check() is called after an update to report any previously
+cached CPUID bits which might have changed due to the update.
+
+Therefore, store the cached CPU caps before the update and compare them
+with the CPU caps after the microcode update has succeeded.
+
+Thus, the comparison is done between the CPUID *hardware* bits before
+and after the upgrade instead of using the cached, possibly runtime
+modified values in BSP's boot_cpu_data copy.
+
+As a result, false warnings about CPUID bits changes are avoided.
+
+ [ bp:
+ - Massage.
+ - Add SRBDS_CTRL example.
+ - Add kernel-doc.
+ - Incorporate forgotten review feedback from dhansen.
+ ]
+
+Fixes: 1008c52c09dc ("x86/CPU: Add a microcode loader callback")
+Signed-off-by: Ashok Raj <ashok.raj@intel.com>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Link: https://lore.kernel.org/r/20230109153555.4986-3-ashok.raj@intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/include/asm/processor.h | 1 +
+ arch/x86/kernel/cpu/common.c | 36 ++++++++++++++++++----------
+ arch/x86/kernel/cpu/microcode/core.c | 6 +++++
+ 3 files changed, 30 insertions(+), 13 deletions(-)
+
+diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
+index 6d40c409ebc16..60514502ead67 100644
+--- a/arch/x86/include/asm/processor.h
++++ b/arch/x86/include/asm/processor.h
+@@ -841,6 +841,7 @@ bool xen_set_default_idle(void);
+
+ void __noreturn stop_this_cpu(void *dummy);
+ void microcode_check(struct cpuinfo_x86 *prev_info);
++void store_cpu_caps(struct cpuinfo_x86 *info);
+
+ enum l1tf_mitigations {
+ L1TF_MITIGATION_OFF,
+diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
+index f724002adbfc3..e2dee60108460 100644
+--- a/arch/x86/kernel/cpu/common.c
++++ b/arch/x86/kernel/cpu/common.c
+@@ -2130,6 +2130,25 @@ void cpu_init_secondary(void)
+ #endif
+
+ #ifdef CONFIG_MICROCODE_LATE_LOADING
++/**
++ * store_cpu_caps() - Store a snapshot of CPU capabilities
++ * @curr_info: Pointer where to store it
++ *
++ * Returns: None
++ */
++void store_cpu_caps(struct cpuinfo_x86 *curr_info)
++{
++ /* Reload CPUID max function as it might've changed. */
++ curr_info->cpuid_level = cpuid_eax(0);
++
++ /* Copy all capability leafs and pick up the synthetic ones. */
++ memcpy(&curr_info->x86_capability, &boot_cpu_data.x86_capability,
++ sizeof(curr_info->x86_capability));
++
++ /* Get the hardware CPUID leafs */
++ get_cpu_cap(curr_info);
++}
++
+ /**
+ * microcode_check() - Check if any CPU capabilities changed after an update.
+ * @prev_info: CPU capabilities stored before an update.
+@@ -2142,22 +2161,13 @@ void cpu_init_secondary(void)
+ */
+ void microcode_check(struct cpuinfo_x86 *prev_info)
+ {
+- perf_check_microcode();
+-
+- /* Reload CPUID max function as it might've changed. */
+- prev_info->cpuid_level = cpuid_eax(0);
++ struct cpuinfo_x86 curr_info;
+
+- /*
+- * Copy all capability leafs to pick up the synthetic ones so that
+- * memcmp() below doesn't fail on that. The ones coming from CPUID will
+- * get overwritten in get_cpu_cap().
+- */
+- memcpy(&prev_info->x86_capability, &boot_cpu_data.x86_capability,
+- sizeof(prev_info->x86_capability));
++ perf_check_microcode();
+
+- get_cpu_cap(prev_info);
++ store_cpu_caps(&curr_info);
+
+- if (!memcmp(&prev_info->x86_capability, &boot_cpu_data.x86_capability,
++ if (!memcmp(&prev_info->x86_capability, &curr_info.x86_capability,
+ sizeof(prev_info->x86_capability)))
+ return;
+
+diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
+index 2c70f3cfae68e..122da99bac4e4 100644
+--- a/arch/x86/kernel/cpu/microcode/core.c
++++ b/arch/x86/kernel/cpu/microcode/core.c
+@@ -514,6 +514,12 @@ static int microcode_reload_late(void)
+ atomic_set(&late_cpus_in, 0);
+ atomic_set(&late_cpus_out, 0);
+
++ /*
++ * Take a snapshot before the microcode update in order to compare and
++ * check whether any bits changed after an update.
++ */
++ store_cpu_caps(&prev_info);
++
+ ret = stop_machine_cpuslocked(__reload_late, NULL, cpu_online_mask);
+ if (ret == 0)
+ microcode_check(&prev_info);
+--
+2.39.2
+
--- /dev/null
+From 415d4af5c1b04639d123cf324937ad909128af95 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 May 2022 18:12:30 +0200
+Subject: x86/microcode: Default-disable late loading
+
+From: Borislav Petkov <bp@suse.de>
+
+[ Upstream commit a77a94f86273ce42a39cb479217dd8d68acfe0ff ]
+
+It is dangerous and it should not be used anyway - there's a nice early
+loading already.
+
+Requested-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Link: https://lore.kernel.org/r/20220525161232.14924-3-bp@alien8.de
+Stable-dep-of: c0dd9245aa9e ("x86/microcode: Check CPU capabilities after late microcode update correctly")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/Kconfig | 11 +++++++++++
+ arch/x86/kernel/cpu/common.c | 2 ++
+ arch/x86/kernel/cpu/microcode/core.c | 7 ++++++-
+ 3 files changed, 19 insertions(+), 1 deletion(-)
+
+diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
+index 1f55fc6470371..2284666e8c90c 100644
+--- a/arch/x86/Kconfig
++++ b/arch/x86/Kconfig
+@@ -1329,6 +1329,17 @@ config MICROCODE_AMD
+ If you select this option, microcode patch loading support for AMD
+ processors will be enabled.
+
++config MICROCODE_LATE_LOADING
++ bool "Late microcode loading (DANGEROUS)"
++ default n
++ depends on MICROCODE
++ help
++ Loading microcode late, when the system is up and executing instructions
++ is a tricky business and should be avoided if possible. Just the sequence
++ of synchronizing all cores and SMT threads is one fragile dance which does
++ not guarantee that cores might not softlock after the loading. Therefore,
++ use this at your own risk. Late loading taints the kernel too.
++
+ config X86_MSR
+ tristate "/dev/cpu/*/msr - Model-specific register support"
+ help
+diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
+index 4402589a1ee19..95f52540db378 100644
+--- a/arch/x86/kernel/cpu/common.c
++++ b/arch/x86/kernel/cpu/common.c
+@@ -2129,6 +2129,7 @@ void cpu_init_secondary(void)
+ }
+ #endif
+
++#ifdef CONFIG_MICROCODE_LATE_LOADING
+ /*
+ * The microcode loader calls this upon late microcode load to recheck features,
+ * only when microcode has been updated. Caller holds microcode_mutex and CPU
+@@ -2158,6 +2159,7 @@ void microcode_check(void)
+ pr_warn("x86/CPU: CPU features have changed after loading microcode, but might not take effect.\n");
+ pr_warn("x86/CPU: Please consider either early loading through initrd/built-in or a potential BIOS update.\n");
+ }
++#endif
+
+ /*
+ * Invoked from core CPU hotplug code after hotplug operations
+diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
+index 8d8d7ee47e1ce..5b27030714e43 100644
+--- a/arch/x86/kernel/cpu/microcode/core.c
++++ b/arch/x86/kernel/cpu/microcode/core.c
+@@ -393,6 +393,7 @@ static int apply_microcode_on_target(int cpu)
+ /* fake device for request_firmware */
+ static struct platform_device *microcode_pdev;
+
++#ifdef CONFIG_MICROCODE_LATE_LOADING
+ /*
+ * Late loading dance. Why the heavy-handed stomp_machine effort?
+ *
+@@ -560,6 +561,9 @@ static ssize_t reload_store(struct device *dev,
+ return ret;
+ }
+
++static DEVICE_ATTR_WO(reload);
++#endif
++
+ static ssize_t version_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+ {
+@@ -576,7 +580,6 @@ static ssize_t pf_show(struct device *dev,
+ return sprintf(buf, "0x%x\n", uci->cpu_sig.pf);
+ }
+
+-static DEVICE_ATTR_WO(reload);
+ static DEVICE_ATTR(version, 0444, version_show, NULL);
+ static DEVICE_ATTR(processor_flags, 0444, pf_show, NULL);
+
+@@ -729,7 +732,9 @@ static int mc_cpu_down_prep(unsigned int cpu)
+ }
+
+ static struct attribute *cpu_root_microcode_attrs[] = {
++#ifdef CONFIG_MICROCODE_LATE_LOADING
+ &dev_attr_reload.attr,
++#endif
+ NULL
+ };
+
+--
+2.39.2
+
--- /dev/null
+From 7aa787ce80108c9b84bae14213a35b62eed8242b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Aug 2022 18:10:30 +0000
+Subject: x86/microcode: Print previous version of microcode after reload
+
+From: Ashok Raj <ashok.raj@intel.com>
+
+[ Upstream commit 7fce8d6eccbc31a561d07c79f359ad09f0424347 ]
+
+Print both old and new versions of microcode after a reload is complete
+because knowing the previous microcode version is sometimes important
+from a debugging perspective.
+
+ [ bp: Massage commit message. ]
+
+Signed-off-by: Ashok Raj <ashok.raj@intel.com>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Acked-by: Tony Luck <tony.luck@intel.com>
+Link: https://lore.kernel.org/r/20220829181030.722891-1-ashok.raj@intel.com
+Stable-dep-of: c0dd9245aa9e ("x86/microcode: Check CPU capabilities after late microcode update correctly")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/cpu/microcode/core.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
+index 5b27030714e43..707a385943b41 100644
+--- a/arch/x86/kernel/cpu/microcode/core.c
++++ b/arch/x86/kernel/cpu/microcode/core.c
+@@ -508,7 +508,7 @@ static int __reload_late(void *info)
+ */
+ static int microcode_reload_late(void)
+ {
+- int ret;
++ int old = boot_cpu_data.microcode, ret;
+
+ atomic_set(&late_cpus_in, 0);
+ atomic_set(&late_cpus_out, 0);
+@@ -517,7 +517,8 @@ static int microcode_reload_late(void)
+ if (ret == 0)
+ microcode_check();
+
+- pr_info("Reload completed, microcode revision: 0x%x\n", boot_cpu_data.microcode);
++ pr_info("Reload completed, microcode revision: 0x%x -> 0x%x\n",
++ old, boot_cpu_data.microcode);
+
+ return ret;
+ }
+--
+2.39.2
+
--- /dev/null
+From dd90ba0dd2c2c01c6b00dc415b9c5987f95b330e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Aug 2021 16:15:51 +0200
+Subject: x86/microcode: Replace deprecated CPU-hotplug functions.
+
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+
+[ Upstream commit 2089f34f8c5b91f7235023ec72e71e3247261ecc ]
+
+The functions get_online_cpus() and put_online_cpus() have been
+deprecated during the CPU hotplug rework. They map directly to
+cpus_read_lock() and cpus_read_unlock().
+
+Replace deprecated CPU-hotplug functions with the official version.
+The behavior remains unchanged.
+
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Link: https://lore.kernel.org/r/20210803141621.780504-9-bigeasy@linutronix.de
+Stable-dep-of: c0dd9245aa9e ("x86/microcode: Check CPU capabilities after late microcode update correctly")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/cpu/microcode/core.c | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
+index 0b1732b98e719..38a58819c1b9b 100644
+--- a/arch/x86/kernel/cpu/microcode/core.c
++++ b/arch/x86/kernel/cpu/microcode/core.c
+@@ -55,7 +55,7 @@ LIST_HEAD(microcode_cache);
+ * All non cpu-hotplug-callback call sites use:
+ *
+ * - microcode_mutex to synchronize with each other;
+- * - get/put_online_cpus() to synchronize with
++ * - cpus_read_lock/unlock() to synchronize with
+ * the cpu-hotplug-callback call sites.
+ *
+ * We guarantee that only a single cpu is being
+@@ -431,7 +431,7 @@ static ssize_t microcode_write(struct file *file, const char __user *buf,
+ return ret;
+ }
+
+- get_online_cpus();
++ cpus_read_lock();
+ mutex_lock(µcode_mutex);
+
+ if (do_microcode_update(buf, len) == 0)
+@@ -441,7 +441,7 @@ static ssize_t microcode_write(struct file *file, const char __user *buf,
+ perf_check_microcode();
+
+ mutex_unlock(µcode_mutex);
+- put_online_cpus();
++ cpus_read_unlock();
+
+ return ret;
+ }
+@@ -629,7 +629,7 @@ static ssize_t reload_store(struct device *dev,
+ if (val != 1)
+ return size;
+
+- get_online_cpus();
++ cpus_read_lock();
+
+ ret = check_online_cpus();
+ if (ret)
+@@ -644,7 +644,7 @@ static ssize_t reload_store(struct device *dev,
+ mutex_unlock(µcode_mutex);
+
+ put:
+- put_online_cpus();
++ cpus_read_unlock();
+
+ if (ret == 0)
+ ret = size;
+@@ -853,14 +853,14 @@ int __init microcode_init(void)
+ if (IS_ERR(microcode_pdev))
+ return PTR_ERR(microcode_pdev);
+
+- get_online_cpus();
++ cpus_read_lock();
+ mutex_lock(µcode_mutex);
+
+ error = subsys_interface_register(&mc_cpu_interface);
+ if (!error)
+ perf_check_microcode();
+ mutex_unlock(µcode_mutex);
+- put_online_cpus();
++ cpus_read_unlock();
+
+ if (error)
+ goto out_pdev;
+@@ -892,13 +892,13 @@ int __init microcode_init(void)
+ &cpu_root_microcode_group);
+
+ out_driver:
+- get_online_cpus();
++ cpus_read_lock();
+ mutex_lock(µcode_mutex);
+
+ subsys_interface_unregister(&mc_cpu_interface);
+
+ mutex_unlock(µcode_mutex);
+- put_online_cpus();
++ cpus_read_unlock();
+
+ out_pdev:
+ platform_device_unregister(microcode_pdev);
+--
+2.39.2
+
--- /dev/null
+From b369afccaac66189ef4a4f3ac5a2ec7d19eea42b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 May 2022 18:12:29 +0200
+Subject: x86/microcode: Rip out the OLD_INTERFACE
+
+From: Borislav Petkov <bp@suse.de>
+
+[ Upstream commit 181b6f40e9ea80c76756d4d0cdeed396016c487e ]
+
+Everything should be using the early initrd loading by now.
+
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Link: https://lore.kernel.org/r/20220525161232.14924-2-bp@alien8.de
+Stable-dep-of: c0dd9245aa9e ("x86/microcode: Check CPU capabilities after late microcode update correctly")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/Kconfig | 12 ----
+ arch/x86/kernel/cpu/microcode/core.c | 100 ---------------------------
+ 2 files changed, 112 deletions(-)
+
+diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
+index d64e690139950..1f55fc6470371 100644
+--- a/arch/x86/Kconfig
++++ b/arch/x86/Kconfig
+@@ -1329,18 +1329,6 @@ config MICROCODE_AMD
+ If you select this option, microcode patch loading support for AMD
+ processors will be enabled.
+
+-config MICROCODE_OLD_INTERFACE
+- bool "Ancient loading interface (DEPRECATED)"
+- default n
+- depends on MICROCODE
+- help
+- DO NOT USE THIS! This is the ancient /dev/cpu/microcode interface
+- which was used by userspace tools like iucode_tool and microcode.ctl.
+- It is inadequate because it runs too late to be able to properly
+- load microcode on a machine and it needs special tools. Instead, you
+- should've switched to the early loading method with the initrd or
+- builtin microcode by now: Documentation/x86/microcode.rst
+-
+ config X86_MSR
+ tristate "/dev/cpu/*/msr - Model-specific register support"
+ help
+diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
+index 38a58819c1b9b..8d8d7ee47e1ce 100644
+--- a/arch/x86/kernel/cpu/microcode/core.c
++++ b/arch/x86/kernel/cpu/microcode/core.c
+@@ -390,98 +390,6 @@ static int apply_microcode_on_target(int cpu)
+ return ret;
+ }
+
+-#ifdef CONFIG_MICROCODE_OLD_INTERFACE
+-static int do_microcode_update(const void __user *buf, size_t size)
+-{
+- int error = 0;
+- int cpu;
+-
+- for_each_online_cpu(cpu) {
+- struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
+- enum ucode_state ustate;
+-
+- if (!uci->valid)
+- continue;
+-
+- ustate = microcode_ops->request_microcode_user(cpu, buf, size);
+- if (ustate == UCODE_ERROR) {
+- error = -1;
+- break;
+- } else if (ustate == UCODE_NEW) {
+- apply_microcode_on_target(cpu);
+- }
+- }
+-
+- return error;
+-}
+-
+-static int microcode_open(struct inode *inode, struct file *file)
+-{
+- return capable(CAP_SYS_RAWIO) ? stream_open(inode, file) : -EPERM;
+-}
+-
+-static ssize_t microcode_write(struct file *file, const char __user *buf,
+- size_t len, loff_t *ppos)
+-{
+- ssize_t ret = -EINVAL;
+- unsigned long nr_pages = totalram_pages();
+-
+- if ((len >> PAGE_SHIFT) > nr_pages) {
+- pr_err("too much data (max %ld pages)\n", nr_pages);
+- return ret;
+- }
+-
+- cpus_read_lock();
+- mutex_lock(µcode_mutex);
+-
+- if (do_microcode_update(buf, len) == 0)
+- ret = (ssize_t)len;
+-
+- if (ret > 0)
+- perf_check_microcode();
+-
+- mutex_unlock(µcode_mutex);
+- cpus_read_unlock();
+-
+- return ret;
+-}
+-
+-static const struct file_operations microcode_fops = {
+- .owner = THIS_MODULE,
+- .write = microcode_write,
+- .open = microcode_open,
+- .llseek = no_llseek,
+-};
+-
+-static struct miscdevice microcode_dev = {
+- .minor = MICROCODE_MINOR,
+- .name = "microcode",
+- .nodename = "cpu/microcode",
+- .fops = µcode_fops,
+-};
+-
+-static int __init microcode_dev_init(void)
+-{
+- int error;
+-
+- error = misc_register(µcode_dev);
+- if (error) {
+- pr_err("can't misc_register on minor=%d\n", MICROCODE_MINOR);
+- return error;
+- }
+-
+- return 0;
+-}
+-
+-static void __exit microcode_dev_exit(void)
+-{
+- misc_deregister(µcode_dev);
+-}
+-#else
+-#define microcode_dev_init() 0
+-#define microcode_dev_exit() do { } while (0)
+-#endif
+-
+ /* fake device for request_firmware */
+ static struct platform_device *microcode_pdev;
+
+@@ -873,10 +781,6 @@ int __init microcode_init(void)
+ goto out_driver;
+ }
+
+- error = microcode_dev_init();
+- if (error)
+- goto out_ucode_group;
+-
+ register_syscore_ops(&mc_syscore_ops);
+ cpuhp_setup_state_nocalls(CPUHP_AP_MICROCODE_LOADER, "x86/microcode:starting",
+ mc_cpu_starting, NULL);
+@@ -887,10 +791,6 @@ int __init microcode_init(void)
+
+ return 0;
+
+- out_ucode_group:
+- sysfs_remove_group(&cpu_subsys.dev_root->kobj,
+- &cpu_root_microcode_group);
+-
+ out_driver:
+ cpus_read_lock();
+ mutex_lock(µcode_mutex);
+--
+2.39.2
+
--- /dev/null
+From 38ef7093601af0fc9fec3eb2210b299878498445 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Feb 2023 16:27:22 +0800
+Subject: x86/perf/zhaoxin: Add stepping check for ZXC
+
+From: silviazhao <silviazhao-oc@zhaoxin.com>
+
+[ Upstream commit fd636b6a9bc6034f2e5bb869658898a2b472c037 ]
+
+Some of Nano series processors will lead GP when accessing
+PMC fixed counter. Meanwhile, their hardware support for PMC
+has not announced externally. So exclude Nano CPUs from ZXC
+by checking stepping information. This is an unambiguous way
+to differentiate between ZXC and Nano CPUs.
+
+Following are Nano and ZXC FMS information:
+Nano FMS: Family=6, Model=F, Stepping=[0-A][C-D]
+ZXC FMS: Family=6, Model=F, Stepping=E-F OR
+ Family=6, Model=0x19, Stepping=0-3
+
+Fixes: 3a4ac121c2ca ("x86/perf: Add hardware performance events support for Zhaoxin CPU.")
+
+Reported-by: Arjan <8vvbbqzo567a@nospam.xutrox.com>
+Reported-by: Kevin Brace <kevinbrace@gmx.com>
+Signed-off-by: silviazhao <silviazhao-oc@zhaoxin.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=212389
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/events/zhaoxin/core.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/arch/x86/events/zhaoxin/core.c b/arch/x86/events/zhaoxin/core.c
+index e68827e604ad1..e927346960303 100644
+--- a/arch/x86/events/zhaoxin/core.c
++++ b/arch/x86/events/zhaoxin/core.c
+@@ -541,7 +541,13 @@ __init int zhaoxin_pmu_init(void)
+
+ switch (boot_cpu_data.x86) {
+ case 0x06:
+- if (boot_cpu_data.x86_model == 0x0f || boot_cpu_data.x86_model == 0x19) {
++ /*
++ * Support Zhaoxin CPU from ZXC series, exclude Nano series through FMS.
++ * Nano FMS: Family=6, Model=F, Stepping=[0-A][C-D]
++ * ZXC FMS: Family=6, Model=F, Stepping=E-F OR Family=6, Model=0x19, Stepping=0-3
++ */
++ if ((boot_cpu_data.x86_model == 0x0f && boot_cpu_data.x86_stepping >= 0x0e) ||
++ boot_cpu_data.x86_model == 0x19) {
+
+ x86_pmu.max_period = x86_pmu.cntval_mask >> 1;
+
+--
+2.39.2
+