--- /dev/null
+From 7405f55a9291ad119c259d6ce974cfdfecc55b6f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Oct 2024 23:28:34 +0200
+Subject: ACPI: battery: Fix possible crash when unregistering a battery hook
+
+From: Armin Wolf <W_Armin@gmx.de>
+
+[ Upstream commit 76959aff14a0012ad6b984ec7686d163deccdc16 ]
+
+When a battery hook returns an error when adding a new battery, then
+the battery hook is automatically unregistered.
+However the battery hook provider cannot know that, so it will later
+call battery_hook_unregister() on the already unregistered battery
+hook, resulting in a crash.
+
+Fix this by using the list head to mark already unregistered battery
+hooks as already being unregistered so that they can be ignored by
+battery_hook_unregister().
+
+Fixes: fa93854f7a7e ("battery: Add the battery hooking API")
+Signed-off-by: Armin Wolf <W_Armin@gmx.de>
+Link: https://patch.msgid.link/20241001212835.341788-3-W_Armin@gmx.de
+Cc: All applicable <stable@vger.kernel.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/battery.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
+index 6a8580427e1a9..8bb0f4d06adc0 100644
+--- a/drivers/acpi/battery.c
++++ b/drivers/acpi/battery.c
+@@ -712,7 +712,7 @@ static void battery_hook_unregister_unlocked(struct acpi_battery_hook *hook)
+ list_for_each_entry(battery, &acpi_battery_list, list) {
+ hook->remove_battery(battery->bat);
+ }
+- list_del(&hook->list);
++ list_del_init(&hook->list);
+
+ pr_info("extension unregistered: %s\n", hook->name);
+ }
+@@ -720,7 +720,14 @@ static void battery_hook_unregister_unlocked(struct acpi_battery_hook *hook)
+ void battery_hook_unregister(struct acpi_battery_hook *hook)
+ {
+ mutex_lock(&hook_mutex);
+- battery_hook_unregister_unlocked(hook);
++ /*
++ * Ignore already unregistered battery hooks. This might happen
++ * if a battery hook was previously unloaded due to an error when
++ * adding a new battery.
++ */
++ if (!list_empty(&hook->list))
++ battery_hook_unregister_unlocked(hook);
++
+ mutex_unlock(&hook_mutex);
+ }
+ EXPORT_SYMBOL_GPL(battery_hook_unregister);
+@@ -730,7 +737,6 @@ void battery_hook_register(struct acpi_battery_hook *hook)
+ struct acpi_battery *battery;
+
+ mutex_lock(&hook_mutex);
+- INIT_LIST_HEAD(&hook->list);
+ list_add(&hook->list, &battery_hook_list);
+ /*
+ * Now that the driver is registered, we need
+--
+2.43.0
+
--- /dev/null
+From 9a7c13cafb4f74fd603f17119ee50e07faad39dc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Oct 2024 23:28:33 +0200
+Subject: ACPI: battery: Simplify battery hook locking
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Armin Wolf <W_Armin@gmx.de>
+
+[ Upstream commit 86309cbed26139e1caae7629dcca1027d9a28e75 ]
+
+Move the conditional locking from __battery_hook_unregister()
+into battery_hook_unregister() and rename the low-level function
+to simplify the locking during battery hook removal.
+
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Reviewed-by: Pali Rohár <pali@kernel.org>
+Signed-off-by: Armin Wolf <W_Armin@gmx.de>
+Link: https://patch.msgid.link/20241001212835.341788-2-W_Armin@gmx.de
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Stable-dep-of: 76959aff14a0 ("ACPI: battery: Fix possible crash when unregistering a battery hook")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/battery.c | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
+index aed4132985a96..6a8580427e1a9 100644
+--- a/drivers/acpi/battery.c
++++ b/drivers/acpi/battery.c
+@@ -701,27 +701,27 @@ static LIST_HEAD(acpi_battery_list);
+ static LIST_HEAD(battery_hook_list);
+ static DEFINE_MUTEX(hook_mutex);
+
+-static void __battery_hook_unregister(struct acpi_battery_hook *hook, int lock)
++static void battery_hook_unregister_unlocked(struct acpi_battery_hook *hook)
+ {
+ struct acpi_battery *battery;
++
+ /*
+ * In order to remove a hook, we first need to
+ * de-register all the batteries that are registered.
+ */
+- if (lock)
+- mutex_lock(&hook_mutex);
+ list_for_each_entry(battery, &acpi_battery_list, list) {
+ hook->remove_battery(battery->bat);
+ }
+ list_del(&hook->list);
+- if (lock)
+- mutex_unlock(&hook_mutex);
++
+ pr_info("extension unregistered: %s\n", hook->name);
+ }
+
+ void battery_hook_unregister(struct acpi_battery_hook *hook)
+ {
+- __battery_hook_unregister(hook, 1);
++ mutex_lock(&hook_mutex);
++ battery_hook_unregister_unlocked(hook);
++ mutex_unlock(&hook_mutex);
+ }
+ EXPORT_SYMBOL_GPL(battery_hook_unregister);
+
+@@ -747,7 +747,7 @@ void battery_hook_register(struct acpi_battery_hook *hook)
+ * hooks.
+ */
+ pr_err("extension failed to load: %s", hook->name);
+- __battery_hook_unregister(hook, 0);
++ battery_hook_unregister_unlocked(hook);
+ goto end;
+ }
+ }
+@@ -784,7 +784,7 @@ static void battery_hook_add_battery(struct acpi_battery *battery)
+ */
+ pr_err("error in extension, unloading: %s",
+ hook_node->name);
+- __battery_hook_unregister(hook_node, 0);
++ battery_hook_unregister_unlocked(hook_node);
+ }
+ }
+ mutex_unlock(&hook_mutex);
+@@ -817,7 +817,7 @@ static void __exit battery_hook_exit(void)
+ * need to remove the hooks.
+ */
+ list_for_each_entry_safe(hook, ptr, &battery_hook_list, list) {
+- __battery_hook_unregister(hook, 1);
++ battery_hook_unregister(hook);
+ }
+ mutex_destroy(&hook_mutex);
+ }
+--
+2.43.0
+
--- /dev/null
+From 6c4e453be4702db84ebad7b8f251fd76daf94467 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Oct 2024 13:15:16 +0100
+Subject: arm64: Add Cortex-715 CPU part definition
+
+From: Anshuman Khandual <anshuman.khandual@arm.com>
+
+[ Upstream commit 07e39e60bbf0ccd5f895568e1afca032193705c0 ]
+
+Add the CPU Partnumbers for the new Arm designs.
+
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Will Deacon <will@kernel.org>
+Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
+Cc: James Morse <james.morse@arm.com>
+Cc: linux-arm-kernel@lists.infradead.org
+Cc: linux-kernel@vger.kernel.org
+Acked-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
+Link: https://lore.kernel.org/r/20221116140915.356601-2-anshuman.khandual@arm.com
+Signed-off-by: Will Deacon <will@kernel.org>
+[ Mark: Trivial backport ]
+Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/include/asm/cputype.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
+index 59f135b280a8a..75cbd3880b5c7 100644
+--- a/arch/arm64/include/asm/cputype.h
++++ b/arch/arm64/include/asm/cputype.h
+@@ -82,6 +82,7 @@
+ #define ARM_CPU_PART_CORTEX_A510 0xD46
+ #define ARM_CPU_PART_CORTEX_A520 0xD80
+ #define ARM_CPU_PART_CORTEX_A710 0xD47
++#define ARM_CPU_PART_CORTEX_A715 0xD4D
+ #define ARM_CPU_PART_CORTEX_X2 0xD48
+ #define ARM_CPU_PART_NEOVERSE_N2 0xD49
+ #define ARM_CPU_PART_CORTEX_A78C 0xD4B
+@@ -144,6 +145,7 @@
+ #define MIDR_CORTEX_A510 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A510)
+ #define MIDR_CORTEX_A520 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A520)
+ #define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710)
++#define MIDR_CORTEX_A715 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A715)
+ #define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2)
+ #define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2)
+ #define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C)
+--
+2.43.0
+
--- /dev/null
+From d44579566677de3e3a14e9c530c5dfd5208fe4f0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Oct 2024 13:15:17 +0100
+Subject: arm64: cputype: Add Neoverse-N3 definitions
+
+From: Mark Rutland <mark.rutland@arm.com>
+
+[ Upstream commit 924725707d80bc2588cefafef76ff3f164d299bc ]
+
+Add cputype definitions for Neoverse-N3. These will be used for errata
+detection in subsequent patches.
+
+These values can be found in Table A-261 ("MIDR_EL1 bit descriptions")
+in issue 02 of the Neoverse-N3 TRM, which can be found at:
+
+ https://developer.arm.com/documentation/107997/0000/?lang=en
+
+Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+Cc: James Morse <james.morse@arm.com>
+Cc: Will Deacon <will@kernel.org>
+Link: https://lore.kernel.org/r/20240930111705.3352047-2-mark.rutland@arm.com
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+[ Mark: trivial backport ]
+Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/include/asm/cputype.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
+index 75cbd3880b5c7..7dfaad0fa17b7 100644
+--- a/arch/arm64/include/asm/cputype.h
++++ b/arch/arm64/include/asm/cputype.h
+@@ -94,6 +94,7 @@
+ #define ARM_CPU_PART_NEOVERSE_V3 0xD84
+ #define ARM_CPU_PART_CORTEX_X925 0xD85
+ #define ARM_CPU_PART_CORTEX_A725 0xD87
++#define ARM_CPU_PART_NEOVERSE_N3 0xD8E
+
+ #define APM_CPU_PART_POTENZA 0x000
+
+@@ -157,6 +158,7 @@
+ #define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3)
+ #define MIDR_CORTEX_X925 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X925)
+ #define MIDR_CORTEX_A725 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A725)
++#define MIDR_NEOVERSE_N3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N3)
+ #define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
+ #define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)
+ #define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX)
+--
+2.43.0
+
--- /dev/null
+From e884ca0c9aff0aa40b20398dac85cdcbbffd24c8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Oct 2024 13:15:18 +0100
+Subject: arm64: errata: Expand speculative SSBS workaround once more
+
+From: Mark Rutland <mark.rutland@arm.com>
+
+[ Upstream commit 081eb7932c2b244f63317a982c5e3990e2c7fbdd ]
+
+A number of Arm Ltd CPUs suffer from errata whereby an MSR to the SSBS
+special-purpose register does not affect subsequent speculative
+instructions, permitting speculative store bypassing for a window of
+time.
+
+We worked around this for a number of CPUs in commits:
+
+* 7187bb7d0b5c7dfa ("arm64: errata: Add workaround for Arm errata 3194386 and 3312417")
+* 75b3c43eab594bfb ("arm64: errata: Expand speculative SSBS workaround")
+* 145502cac7ea70b5 ("arm64: errata: Expand speculative SSBS workaround (again)")
+
+Since then, a (hopefully final) batch of updates have been published,
+with two more affected CPUs. For the affected CPUs the existing
+mitigation is sufficient, as described in their respective Software
+Developer Errata Notice (SDEN) documents:
+
+* Cortex-A715 (MP148) SDEN v15.0, erratum 3456084
+ https://developer.arm.com/documentation/SDEN-2148827/1500/
+
+* Neoverse-N3 (MP195) SDEN v5.0, erratum 3456111
+ https://developer.arm.com/documentation/SDEN-3050973/0500/
+
+Enable the existing mitigation by adding the relevant MIDRs to
+erratum_spec_ssbs_list, and update silicon-errata.rst and the
+Kconfig text accordingly.
+
+Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+Cc: James Morse <james.morse@arm.com>
+Cc: Will Deacon <will@kernel.org>
+Link: https://lore.kernel.org/r/20240930111705.3352047-3-mark.rutland@arm.com
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+[ Mark: fix conflict in silicon-errata.rst, handle move ]
+Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/arm64/silicon-errata.rst | 4 ++++
+ arch/arm64/Kconfig | 2 ++
+ arch/arm64/kernel/cpu_errata.c | 2 ++
+ 3 files changed, 8 insertions(+)
+
+diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
+index 9868eb45c56a0..a2cd4022415a6 100644
+--- a/Documentation/arm64/silicon-errata.rst
++++ b/Documentation/arm64/silicon-errata.rst
+@@ -118,6 +118,8 @@ stable kernels.
+ +----------------+-----------------+-----------------+-----------------------------+
+ | ARM | Cortex-A710 | #3324338 | ARM64_ERRATUM_3194386 |
+ +----------------+-----------------+-----------------+-----------------------------+
++| ARM | Cortex-A715 | #3456084 | ARM64_ERRATUM_3194386 |
+++----------------+-----------------+-----------------+-----------------------------+
+ | ARM | Cortex-A720 | #3456091 | ARM64_ERRATUM_3194386 |
+ +----------------+-----------------+-----------------+-----------------------------+
+ | ARM | Cortex-A725 | #3456106 | ARM64_ERRATUM_3194386 |
+@@ -150,6 +152,8 @@ stable kernels.
+ +----------------+-----------------+-----------------+-----------------------------+
+ | ARM | Neoverse-N2 | #3324339 | ARM64_ERRATUM_3194386 |
+ +----------------+-----------------+-----------------+-----------------------------+
++| ARM | Neoverse-N3 | #3456111 | ARM64_ERRATUM_3194386 |
+++----------------+-----------------+-----------------+-----------------------------+
+ | ARM | Neoverse-V1 | #3324341 | ARM64_ERRATUM_3194386 |
+ +----------------+-----------------+-----------------+-----------------------------+
+ | ARM | Neoverse-V2 | #3324336 | ARM64_ERRATUM_3194386 |
+diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
+index 2d77e9269eb50..a1c9f96455b11 100644
+--- a/arch/arm64/Kconfig
++++ b/arch/arm64/Kconfig
+@@ -860,6 +860,7 @@ config ARM64_ERRATUM_3194386
+ * ARM Cortex-A78C erratum 3324346
+ * ARM Cortex-A78C erratum 3324347
+ * ARM Cortex-A710 erratam 3324338
++ * ARM Cortex-A715 errartum 3456084
+ * ARM Cortex-A720 erratum 3456091
+ * ARM Cortex-A725 erratum 3456106
+ * ARM Cortex-X1 erratum 3324344
+@@ -870,6 +871,7 @@ config ARM64_ERRATUM_3194386
+ * ARM Cortex-X925 erratum 3324334
+ * ARM Neoverse-N1 erratum 3324349
+ * ARM Neoverse N2 erratum 3324339
++ * ARM Neoverse-N3 erratum 3456111
+ * ARM Neoverse-V1 erratum 3324341
+ * ARM Neoverse V2 erratum 3324336
+ * ARM Neoverse-V3 erratum 3312417
+diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
+index c358bc1c2954e..f8b6f9df951ec 100644
+--- a/arch/arm64/kernel/cpu_errata.c
++++ b/arch/arm64/kernel/cpu_errata.c
+@@ -409,6 +409,7 @@ static const struct midr_range erratum_spec_ssbs_list[] = {
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A78),
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C),
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
++ MIDR_ALL_VERSIONS(MIDR_CORTEX_A715),
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A720),
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A725),
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_X1),
+@@ -419,6 +420,7 @@ static const struct midr_range erratum_spec_ssbs_list[] = {
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_X925),
+ MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
+ MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
++ MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N3),
+ MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1),
+ MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2),
+ MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V3),
+--
+2.43.0
+
--- /dev/null
+From addfa88a98a87ad451163f800f13124712f02b0c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Jun 2024 21:39:33 +0300
+Subject: build-id: require program headers to be right after ELF header
+
+From: Alexey Dobriyan <adobriyan@gmail.com>
+
+[ Upstream commit 961a2851324561caed579764ffbee3db82b32829 ]
+
+Neither ELF spec not ELF loader require program header to be placed right
+after ELF header, but build-id code very much assumes such placement:
+
+See
+
+ find_get_page(vma->vm_file->f_mapping, 0);
+
+line and checks against PAGE_SIZE.
+
+Returns errors for now until someone rewrites build-id parser
+to be more inline with load_elf_binary().
+
+Link: https://lkml.kernel.org/r/d58bc281-6ca7-467a-9a64-40fa214bd63e@p183
+Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
+Reviewed-by: Jiri Olsa <jolsa@kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Stable-dep-of: 905415ff3ffb ("lib/buildid: harden build ID parsing logic")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/buildid.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/lib/buildid.c b/lib/buildid.c
+index dfc62625cae4e..493537344fc81 100644
+--- a/lib/buildid.c
++++ b/lib/buildid.c
+@@ -73,6 +73,13 @@ static int get_build_id_32(const void *page_addr, unsigned char *build_id,
+ Elf32_Phdr *phdr;
+ int i;
+
++ /*
++ * FIXME
++ * Neither ELF spec nor ELF loader require that program headers
++ * start immediately after ELF header.
++ */
++ if (ehdr->e_phoff != sizeof(Elf32_Ehdr))
++ return -EINVAL;
+ /* only supports phdr that fits in one page */
+ if (ehdr->e_phnum >
+ (PAGE_SIZE - sizeof(Elf32_Ehdr)) / sizeof(Elf32_Phdr))
+@@ -98,6 +105,13 @@ static int get_build_id_64(const void *page_addr, unsigned char *build_id,
+ Elf64_Phdr *phdr;
+ int i;
+
++ /*
++ * FIXME
++ * Neither ELF spec nor ELF loader require that program headers
++ * start immediately after ELF header.
++ */
++ if (ehdr->e_phoff != sizeof(Elf64_Ehdr))
++ return -EINVAL;
+ /* only supports phdr that fits in one page */
+ if (ehdr->e_phnum >
+ (PAGE_SIZE - sizeof(Elf64_Ehdr)) / sizeof(Elf64_Phdr))
+--
+2.43.0
+
--- /dev/null
+From 35af8da03ae285e8e65144e22ff7e19639aa31b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 31 Jan 2023 09:46:39 +0100
+Subject: clk: imx6ul: add ethernet refclock mux support
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Oleksij Rempel <o.rempel@pengutronix.de>
+
+[ Upstream commit 4e197ee880c24ecb63f7fe17449b3653bc64b03c ]
+
+Add ethernet refclock mux support and set it to internal clock by
+default. This configuration will not affect existing boards.
+
+clock tree before this patch:
+fec1 <- enet1_ref_125m (gate) <- enet1_ref (divider) <-,
+ |- pll6_enet
+fec2 <- enet2_ref_125m (gate) <- enet2_ref (divider) <-´
+
+after this patch:
+fec1 <- enet1_ref_sel(mux) <- enet1_ref_125m (gate) <- ...
+ `--<> enet1_ref_pad |- pll6_enet
+fec2 <- enet2_ref_sel(mux) <- enet2_ref_125m (gate) <- ...
+ `--<> enet2_ref_pad
+
+Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Acked-by: Lee Jones <lee@kernel.org>
+Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
+Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
+Link: https://lore.kernel.org/r/20230131084642.709385-17-o.rempel@pengutronix.de
+Stable-dep-of: 32c055ef563c ("clk: imx6ul: fix clock parent for IMX6UL_CLK_ENETx_REF_SEL")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/imx/clk-imx6ul.c | 26 +++++++++++++++++++++
+ include/dt-bindings/clock/imx6ul-clock.h | 6 ++++-
+ include/linux/mfd/syscon/imx6q-iomuxc-gpr.h | 6 +++--
+ 3 files changed, 35 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c
+index 1205a1ee339dd..da9f2ca825644 100644
+--- a/drivers/clk/imx/clk-imx6ul.c
++++ b/drivers/clk/imx/clk-imx6ul.c
+@@ -10,6 +10,7 @@
+ #include <linux/err.h>
+ #include <linux/init.h>
+ #include <linux/io.h>
++#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
+ #include <linux/of.h>
+ #include <linux/of_address.h>
+ #include <linux/of_irq.h>
+@@ -94,6 +95,17 @@ static const struct clk_div_table video_div_table[] = {
+ { }
+ };
+
++static const char * enet1_ref_sels[] = { "enet1_ref_125m", "enet1_ref_pad", };
++static const u32 enet1_ref_sels_table[] = { IMX6UL_GPR1_ENET1_TX_CLK_DIR,
++ IMX6UL_GPR1_ENET1_CLK_SEL };
++static const u32 enet1_ref_sels_table_mask = IMX6UL_GPR1_ENET1_TX_CLK_DIR |
++ IMX6UL_GPR1_ENET1_CLK_SEL;
++static const char * enet2_ref_sels[] = { "enet2_ref_125m", "enet2_ref_pad", };
++static const u32 enet2_ref_sels_table[] = { IMX6UL_GPR1_ENET2_TX_CLK_DIR,
++ IMX6UL_GPR1_ENET2_CLK_SEL };
++static const u32 enet2_ref_sels_table_mask = IMX6UL_GPR1_ENET2_TX_CLK_DIR |
++ IMX6UL_GPR1_ENET2_CLK_SEL;
++
+ static u32 share_count_asrc;
+ static u32 share_count_audio;
+ static u32 share_count_sai1;
+@@ -467,6 +479,17 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
+ /* mask handshake of mmdc */
+ imx_mmdc_mask_handshake(base, 0);
+
++ hws[IMX6UL_CLK_ENET1_REF_PAD] = imx_obtain_fixed_of_clock(ccm_node, "enet1_ref_pad", 0);
++
++ hws[IMX6UL_CLK_ENET1_REF_SEL] = imx_clk_gpr_mux("enet1_ref_sel", "fsl,imx6ul-iomuxc-gpr",
++ IOMUXC_GPR1, enet1_ref_sels, ARRAY_SIZE(enet1_ref_sels),
++ enet1_ref_sels_table, enet1_ref_sels_table_mask);
++ hws[IMX6UL_CLK_ENET2_REF_PAD] = imx_obtain_fixed_of_clock(ccm_node, "enet2_ref_pad", 0);
++
++ hws[IMX6UL_CLK_ENET2_REF_SEL] = imx_clk_gpr_mux("enet2_ref_sel", "fsl,imx6ul-iomuxc-gpr",
++ IOMUXC_GPR1, enet2_ref_sels, ARRAY_SIZE(enet2_ref_sels),
++ enet2_ref_sels_table, enet2_ref_sels_table_mask);
++
+ imx_check_clk_hws(hws, IMX6UL_CLK_END);
+
+ of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
+@@ -511,6 +534,9 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
+ clk_set_parent(hws[IMX6ULL_CLK_EPDC_PRE_SEL]->clk, hws[IMX6UL_CLK_PLL3_PFD2]->clk);
+
+ clk_set_parent(hws[IMX6UL_CLK_ENFC_SEL]->clk, hws[IMX6UL_CLK_PLL2_PFD2]->clk);
++
++ clk_set_parent(hws[IMX6UL_CLK_ENET1_REF_SEL]->clk, hws[IMX6UL_CLK_ENET_REF]->clk);
++ clk_set_parent(hws[IMX6UL_CLK_ENET2_REF_SEL]->clk, hws[IMX6UL_CLK_ENET2_REF]->clk);
+ }
+
+ CLK_OF_DECLARE(imx6ul, "fsl,imx6ul-ccm", imx6ul_clocks_init);
+diff --git a/include/dt-bindings/clock/imx6ul-clock.h b/include/dt-bindings/clock/imx6ul-clock.h
+index b44920f1edb0d..66239ebc0e233 100644
+--- a/include/dt-bindings/clock/imx6ul-clock.h
++++ b/include/dt-bindings/clock/imx6ul-clock.h
+@@ -257,7 +257,11 @@
+ #define IMX6UL_CLK_GPIO5 248
+ #define IMX6UL_CLK_MMDC_P1_IPG 249
+ #define IMX6UL_CLK_ENET1_REF_125M 250
++#define IMX6UL_CLK_ENET1_REF_SEL 251
++#define IMX6UL_CLK_ENET1_REF_PAD 252
++#define IMX6UL_CLK_ENET2_REF_SEL 253
++#define IMX6UL_CLK_ENET2_REF_PAD 254
+
+-#define IMX6UL_CLK_END 251
++#define IMX6UL_CLK_END 255
+
+ #endif /* __DT_BINDINGS_CLOCK_IMX6UL_H */
+diff --git a/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h b/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
+index d4b5e527a7a3b..09c6b3184bb04 100644
+--- a/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
++++ b/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
+@@ -451,8 +451,10 @@
+ #define IMX6SX_GPR12_PCIE_RX_EQ_2 (0x2 << 0)
+
+ /* For imx6ul iomux gpr register field define */
+-#define IMX6UL_GPR1_ENET1_CLK_DIR (0x1 << 17)
+-#define IMX6UL_GPR1_ENET2_CLK_DIR (0x1 << 18)
++#define IMX6UL_GPR1_ENET2_TX_CLK_DIR BIT(18)
++#define IMX6UL_GPR1_ENET1_TX_CLK_DIR BIT(17)
++#define IMX6UL_GPR1_ENET2_CLK_SEL BIT(14)
++#define IMX6UL_GPR1_ENET1_CLK_SEL BIT(13)
+ #define IMX6UL_GPR1_ENET1_CLK_OUTPUT (0x1 << 17)
+ #define IMX6UL_GPR1_ENET2_CLK_OUTPUT (0x1 << 18)
+ #define IMX6UL_GPR1_ENET_CLK_DIR (0x3 << 17)
+--
+2.43.0
+
--- /dev/null
+From 7ca1a28556796205fcdcb1e2f340090358a0a963 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Sep 2024 09:05:53 +0000
+Subject: clk: imx6ul: fix clock parent for IMX6UL_CLK_ENETx_REF_SEL
+
+From: Michel Alex <Alex.Michel@wiedemann-group.com>
+
+[ Upstream commit 32c055ef563c3a4a73a477839f591b1b170bde8e ]
+
+Commit 4e197ee880c24ecb63f7fe17449b3653bc64b03c ("clk: imx6ul: add
+ethernet refclock mux support") sets the internal clock as default
+ethernet clock.
+
+Since IMX6UL_CLK_ENET_REF cannot be parent for IMX6UL_CLK_ENET1_REF_SEL,
+the call to clk_set_parent() fails. IMX6UL_CLK_ENET1_REF_125M is the correct
+parent and shall be used instead.
+Same applies for IMX6UL_CLK_ENET2_REF_SEL, for which IMX6UL_CLK_ENET2_REF_125M
+is the correct parent.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Alex Michel <alex.michel@wiedemann-group.com>
+Reviewed-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Link: https://lore.kernel.org/r/AS1P250MB0608F9CE4009DCE65C61EEDEA9922@AS1P250MB0608.EURP250.PROD.OUTLOOK.COM
+Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/imx/clk-imx6ul.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c
+index bdf98ef60ba0f..7beda28ed2f09 100644
+--- a/drivers/clk/imx/clk-imx6ul.c
++++ b/drivers/clk/imx/clk-imx6ul.c
+@@ -535,8 +535,8 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
+
+ clk_set_parent(hws[IMX6UL_CLK_ENFC_SEL]->clk, hws[IMX6UL_CLK_PLL2_PFD2]->clk);
+
+- clk_set_parent(hws[IMX6UL_CLK_ENET1_REF_SEL]->clk, hws[IMX6UL_CLK_ENET_REF]->clk);
+- clk_set_parent(hws[IMX6UL_CLK_ENET2_REF_SEL]->clk, hws[IMX6UL_CLK_ENET2_REF]->clk);
++ clk_set_parent(hws[IMX6UL_CLK_ENET1_REF_SEL]->clk, hws[IMX6UL_CLK_ENET1_REF_125M]->clk);
++ clk_set_parent(hws[IMX6UL_CLK_ENET2_REF_SEL]->clk, hws[IMX6UL_CLK_ENET2_REF_125M]->clk);
+
+ imx_register_uart_clocks();
+ }
+--
+2.43.0
+
--- /dev/null
+From cee8d48e428abb41b5e7efa8c5ed9af5788e5031 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 31 Jan 2023 09:46:38 +0100
+Subject: clk: imx6ul: fix enet1 gate configuration
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Oleksij Rempel <o.rempel@pengutronix.de>
+
+[ Upstream commit 5f82bfced6118450cb9ea3f12316568f6fac10ab ]
+
+According to the "i.MX 6UltraLite Applications Processor Reference Manual,
+Rev. 2, 03/2017", BIT(13) is ENET1_125M_EN which is not controlling root
+of PLL6. It is controlling ENET1 separately.
+
+So, instead of this picture (implementation before this patch):
+fec1 <- enet_ref (divider) <---------------------------,
+ |- pll6_enet (gate)
+fec2 <- enet2_ref_125m (gate) <- enet2_ref (divider) <-´
+
+we should have this one (after this patch):
+fec1 <- enet1_ref_125m (gate) <- enet1_ref (divider) <-,
+ |- pll6_enet
+fec2 <- enet2_ref_125m (gate) <- enet2_ref (divider) <-´
+
+With this fix, the RMII reference clock will be turned off, after
+setting network interface down on each separate interface
+(ip l s dev eth0 down). Which was not working before, on system with both
+FECs enabled.
+
+Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
+Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
+Link: https://lore.kernel.org/r/20230131084642.709385-16-o.rempel@pengutronix.de
+Stable-dep-of: 32c055ef563c ("clk: imx6ul: fix clock parent for IMX6UL_CLK_ENETx_REF_SEL")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/imx/clk-imx6ul.c | 7 ++++---
+ include/dt-bindings/clock/imx6ul-clock.h | 3 ++-
+ 2 files changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c
+index 206e4c43f68f8..1205a1ee339dd 100644
+--- a/drivers/clk/imx/clk-imx6ul.c
++++ b/drivers/clk/imx/clk-imx6ul.c
+@@ -176,7 +176,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
+ hws[IMX6UL_CLK_PLL3_USB_OTG] = imx_clk_hw_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13);
+ hws[IMX6UL_CLK_PLL4_AUDIO] = imx_clk_hw_gate("pll4_audio", "pll4_bypass", base + 0x70, 13);
+ hws[IMX6UL_CLK_PLL5_VIDEO] = imx_clk_hw_gate("pll5_video", "pll5_bypass", base + 0xa0, 13);
+- hws[IMX6UL_CLK_PLL6_ENET] = imx_clk_hw_gate("pll6_enet", "pll6_bypass", base + 0xe0, 13);
++ hws[IMX6UL_CLK_PLL6_ENET] = imx_clk_hw_fixed_factor("pll6_enet", "pll6_bypass", 1, 1);
+ hws[IMX6UL_CLK_PLL7_USB_HOST] = imx_clk_hw_gate("pll7_usb_host", "pll7_bypass", base + 0x20, 13);
+
+ /*
+@@ -205,12 +205,13 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
+ hws[IMX6UL_CLK_PLL3_PFD2] = imx_clk_hw_pfd("pll3_pfd2_508m", "pll3_usb_otg", base + 0xf0, 2);
+ hws[IMX6UL_CLK_PLL3_PFD3] = imx_clk_hw_pfd("pll3_pfd3_454m", "pll3_usb_otg", base + 0xf0, 3);
+
+- hws[IMX6UL_CLK_ENET_REF] = clk_hw_register_divider_table(NULL, "enet_ref", "pll6_enet", 0,
++ hws[IMX6UL_CLK_ENET_REF] = clk_hw_register_divider_table(NULL, "enet1_ref", "pll6_enet", 0,
+ base + 0xe0, 0, 2, 0, clk_enet_ref_table, &imx_ccm_lock);
+ hws[IMX6UL_CLK_ENET2_REF] = clk_hw_register_divider_table(NULL, "enet2_ref", "pll6_enet", 0,
+ base + 0xe0, 2, 2, 0, clk_enet_ref_table, &imx_ccm_lock);
+
+- hws[IMX6UL_CLK_ENET2_REF_125M] = imx_clk_hw_gate("enet_ref_125m", "enet2_ref", base + 0xe0, 20);
++ hws[IMX6UL_CLK_ENET1_REF_125M] = imx_clk_hw_gate("enet1_ref_125m", "enet1_ref", base + 0xe0, 13);
++ hws[IMX6UL_CLK_ENET2_REF_125M] = imx_clk_hw_gate("enet2_ref_125m", "enet2_ref", base + 0xe0, 20);
+ hws[IMX6UL_CLK_ENET_PTP_REF] = imx_clk_hw_fixed_factor("enet_ptp_ref", "pll6_enet", 1, 20);
+ hws[IMX6UL_CLK_ENET_PTP] = imx_clk_hw_gate("enet_ptp", "enet_ptp_ref", base + 0xe0, 21);
+
+diff --git a/include/dt-bindings/clock/imx6ul-clock.h b/include/dt-bindings/clock/imx6ul-clock.h
+index 79094338e6f1e..b44920f1edb0d 100644
+--- a/include/dt-bindings/clock/imx6ul-clock.h
++++ b/include/dt-bindings/clock/imx6ul-clock.h
+@@ -256,7 +256,8 @@
+ #define IMX6UL_CLK_GPIO4 247
+ #define IMX6UL_CLK_GPIO5 248
+ #define IMX6UL_CLK_MMDC_P1_IPG 249
++#define IMX6UL_CLK_ENET1_REF_125M 250
+
+-#define IMX6UL_CLK_END 250
++#define IMX6UL_CLK_END 251
+
+ #endif /* __DT_BINDINGS_CLOCK_IMX6UL_H */
+--
+2.43.0
+
--- /dev/null
+From 483f17cbf43e3465b2426fc9364a5d99327aaa01 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Apr 2023 13:55:17 +0200
+Subject: clk: imx6ul: retain early UART clocks during kernel init
+
+From: Alexander Stein <alexander.stein@ew.tq-group.com>
+
+[ Upstream commit 912d7af473f163ccdeb02aaabc3534177936b86c ]
+
+Make sure to keep UART clocks enabled during kernel init if
+earlyprintk or earlycon are active.
+
+Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Reviewed-by: Peng Fan <peng.fan@nxp.com>
+Link: https://lore.kernel.org/r/20230421115517.1940990-1-alexander.stein@ew.tq-group.com
+Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
+Stable-dep-of: 32c055ef563c ("clk: imx6ul: fix clock parent for IMX6UL_CLK_ENETx_REF_SEL")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/imx/clk-imx6ul.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c
+index da9f2ca825644..bdf98ef60ba0f 100644
+--- a/drivers/clk/imx/clk-imx6ul.c
++++ b/drivers/clk/imx/clk-imx6ul.c
+@@ -537,6 +537,8 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
+
+ clk_set_parent(hws[IMX6UL_CLK_ENET1_REF_SEL]->clk, hws[IMX6UL_CLK_ENET_REF]->clk);
+ clk_set_parent(hws[IMX6UL_CLK_ENET2_REF_SEL]->clk, hws[IMX6UL_CLK_ENET2_REF]->clk);
++
++ imx_register_uart_clocks();
+ }
+
+ CLK_OF_DECLARE(imx6ul, "fsl,imx6ul-ccm", imx6ul_clocks_init);
+--
+2.43.0
+
--- /dev/null
+From 5b40972c1044475dfff29bf8ffb74b90dba12a4e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 Aug 2024 10:43:03 +0530
+Subject: clk: qcom: gcc-sc8180x: Add GPLL9 support
+
+From: Satya Priya Kakitapalli <quic_skakitap@quicinc.com>
+
+[ Upstream commit 818a2f8d5e4ad2c1e39a4290158fe8e39a744c70 ]
+
+Add the missing GPLL9 pll and fix the gcc_parents_7 data to use
+the correct pll hw.
+
+Fixes: 4433594bbe5d ("clk: qcom: gcc: Add global clock controller driver for SC8180x")
+Cc: stable@vger.kernel.org
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Satya Priya Kakitapalli <quic_skakitap@quicinc.com>
+Link: https://lore.kernel.org/r/20240812-gcc-sc8180x-fixes-v2-3-8b3eaa5fb856@quicinc.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-sc8180x.c | 20 +++++++++++++++++++-
+ 1 file changed, 19 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/clk/qcom/gcc-sc8180x.c b/drivers/clk/qcom/gcc-sc8180x.c
+index 8c986a60e62c7..ba004281f2944 100644
+--- a/drivers/clk/qcom/gcc-sc8180x.c
++++ b/drivers/clk/qcom/gcc-sc8180x.c
+@@ -143,6 +143,23 @@ static struct clk_alpha_pll gpll7 = {
+ },
+ };
+
++static struct clk_alpha_pll gpll9 = {
++ .offset = 0x1c000,
++ .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TRION],
++ .clkr = {
++ .enable_reg = 0x52000,
++ .enable_mask = BIT(9),
++ .hw.init = &(const struct clk_init_data) {
++ .name = "gpll9",
++ .parent_data = &(const struct clk_parent_data) {
++ .fw_name = "bi_tcxo",
++ },
++ .num_parents = 1,
++ .ops = &clk_alpha_pll_fixed_trion_ops,
++ },
++ },
++};
++
+ static const struct parent_map gcc_parent_map_0[] = {
+ { P_BI_TCXO, 0 },
+ { P_GPLL0_OUT_MAIN, 1 },
+@@ -242,7 +259,7 @@ static const struct parent_map gcc_parent_map_7[] = {
+ static const struct clk_parent_data gcc_parents_7[] = {
+ { .fw_name = "bi_tcxo", },
+ { .hw = &gpll0.clkr.hw },
+- { .name = "gppl9" },
++ { .hw = &gpll9.clkr.hw },
+ { .hw = &gpll4.clkr.hw },
+ { .hw = &gpll0_out_even.clkr.hw },
+ };
+@@ -4420,6 +4437,7 @@ static struct clk_regmap *gcc_sc8180x_clocks[] = {
+ [GPLL1] = &gpll1.clkr,
+ [GPLL4] = &gpll4.clkr,
+ [GPLL7] = &gpll7.clkr,
++ [GPLL9] = &gpll9.clkr,
+ };
+
+ static const struct qcom_reset_map gcc_sc8180x_resets[] = {
+--
+2.43.0
+
--- /dev/null
+From 8d7b3f37c7d32d09084a1426f9b244f7831d3c7a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Dec 2021 21:23:54 +0000
+Subject: device property: Add fwnode_iomap()
+
+From: Anand Ashok Dumbre <anand.ashok.dumbre@xilinx.com>
+
+[ Upstream commit eca6e2d4a4a4b824f055eeaaa24f1c2327fb91a2 ]
+
+This patch introduces a new helper routine - fwnode_iomap(), which
+allows to map the memory mapped IO for a given device node.
+
+This implementation does not cover the ACPI case and may be expanded
+in the future. The main purpose here is to be able to develop resource
+provider agnostic drivers.
+
+Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Anand Ashok Dumbre <anand.ashok.dumbre@xilinx.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Link: https://lore.kernel.org/r/20211203212358.31444-2-anand.ashok.dumbre@xilinx.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: 8d3cefaf6592 ("i2c: core: Lock address during client device instantiation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/property.c | 16 ++++++++++++++++
+ include/linux/property.h | 2 ++
+ 2 files changed, 18 insertions(+)
+
+diff --git a/drivers/base/property.c b/drivers/base/property.c
+index 21f4184db42fc..87bb97e12749e 100644
+--- a/drivers/base/property.c
++++ b/drivers/base/property.c
+@@ -1050,6 +1050,22 @@ int fwnode_irq_get(const struct fwnode_handle *fwnode, unsigned int index)
+ }
+ EXPORT_SYMBOL(fwnode_irq_get);
+
++/**
++ * fwnode_iomap - Maps the memory mapped IO for a given fwnode
++ * @fwnode: Pointer to the firmware node
++ * @index: Index of the IO range
++ *
++ * Returns a pointer to the mapped memory.
++ */
++void __iomem *fwnode_iomap(struct fwnode_handle *fwnode, int index)
++{
++ if (IS_ENABLED(CONFIG_OF_ADDRESS) && is_of_node(fwnode))
++ return of_iomap(to_of_node(fwnode), index);
++
++ return NULL;
++}
++EXPORT_SYMBOL(fwnode_iomap);
++
+ /**
+ * fwnode_graph_get_next_endpoint - Get next endpoint firmware node
+ * @fwnode: Pointer to the parent firmware node
+diff --git a/include/linux/property.h b/include/linux/property.h
+index fe2092e39aedb..032262e3d9991 100644
+--- a/include/linux/property.h
++++ b/include/linux/property.h
+@@ -126,6 +126,8 @@ void fwnode_handle_put(struct fwnode_handle *fwnode);
+
+ int fwnode_irq_get(const struct fwnode_handle *fwnode, unsigned int index);
+
++void __iomem *fwnode_iomap(struct fwnode_handle *fwnode, int index);
++
+ unsigned int device_get_child_node_count(struct device *dev);
+
+ static inline bool device_property_read_bool(struct device *dev,
+--
+2.43.0
+
--- /dev/null
+From 1fe7f272c6f163620087ea7a5e49eb43b729ef7e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Jan 2022 17:14:25 +0530
+Subject: device property: Add fwnode_irq_get_byname
+
+From: Akhil R <akhilrajeev@nvidia.com>
+
+[ Upstream commit ca0acb511c21738b32386ce0f85c284b351d919e ]
+
+Add fwnode_irq_get_byname() to get an interrupt by name from either
+ACPI table or Device Tree, whichever is used for enumeration.
+
+In the ACPI case, this allow us to use 'interrupt-names' in
+_DSD which can be mapped to Interrupt() resource by index.
+The implementation is similar to 'interrupt-names' in the
+Device Tree.
+
+Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Stable-dep-of: 8d3cefaf6592 ("i2c: core: Lock address during client device instantiation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/property.c | 29 +++++++++++++++++++++++++++++
+ include/linux/property.h | 1 +
+ 2 files changed, 30 insertions(+)
+
+diff --git a/drivers/base/property.c b/drivers/base/property.c
+index 87bb97e12749e..ff1be3e311eeb 100644
+--- a/drivers/base/property.c
++++ b/drivers/base/property.c
+@@ -1066,6 +1066,35 @@ void __iomem *fwnode_iomap(struct fwnode_handle *fwnode, int index)
+ }
+ EXPORT_SYMBOL(fwnode_iomap);
+
++/**
++ * fwnode_irq_get_byname - Get IRQ from a fwnode using its name
++ * @fwnode: Pointer to the firmware node
++ * @name: IRQ name
++ *
++ * Description:
++ * Find a match to the string @name in the 'interrupt-names' string array
++ * in _DSD for ACPI, or of_node for Device Tree. Then get the Linux IRQ
++ * number of the IRQ resource corresponding to the index of the matched
++ * string.
++ *
++ * Return:
++ * Linux IRQ number on success, or negative errno otherwise.
++ */
++int fwnode_irq_get_byname(const struct fwnode_handle *fwnode, const char *name)
++{
++ int index;
++
++ if (!name)
++ return -EINVAL;
++
++ index = fwnode_property_match_string(fwnode, "interrupt-names", name);
++ if (index < 0)
++ return index;
++
++ return fwnode_irq_get(fwnode, index);
++}
++EXPORT_SYMBOL(fwnode_irq_get_byname);
++
+ /**
+ * fwnode_graph_get_next_endpoint - Get next endpoint firmware node
+ * @fwnode: Pointer to the parent firmware node
+diff --git a/include/linux/property.h b/include/linux/property.h
+index 032262e3d9991..840f0545d4f9d 100644
+--- a/include/linux/property.h
++++ b/include/linux/property.h
+@@ -125,6 +125,7 @@ struct fwnode_handle *fwnode_handle_get(struct fwnode_handle *fwnode);
+ void fwnode_handle_put(struct fwnode_handle *fwnode);
+
+ int fwnode_irq_get(const struct fwnode_handle *fwnode, unsigned int index);
++int fwnode_irq_get_byname(const struct fwnode_handle *fwnode, const char *name);
+
+ void __iomem *fwnode_iomap(struct fwnode_handle *fwnode, int index);
+
+--
+2.43.0
+
--- /dev/null
+From e938c49a75c60973d6bb55f231e1763b75c6db19 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 15 Sep 2024 14:28:37 -0500
+Subject: drm/amd/display: Allow backlight to go below
+ `AMDGPU_DM_DEFAULT_MIN_BACKLIGHT`
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Mario Limonciello <mario.limonciello@amd.com>
+
+[ Upstream commit 87d749a6aab73d8069d0345afaa98297816cb220 ]
+
+The issue with panel power savings compatibility below
+`AMDGPU_DM_DEFAULT_MIN_BACKLIGHT` happens at
+`AMDGPU_DM_DEFAULT_MIN_BACKLIGHT` as well.
+
+That issue will be fixed separately, so don't prevent the backlight
+brightness from going that low.
+
+Cc: Harry Wentland <harry.wentland@amd.com>
+Cc: Thomas Weißschuh <linux@weissschuh.net>
+Link: https://lore.kernel.org/amd-gfx/be04226a-a9e3-4a45-a83b-6d263c6557d8@t-8ch.de/T/#m400dee4e2fc61fe9470334d20a7c8c89c9aef44f
+Reviewed-by: Harry Wentland <harry.wentland@amd.com>
+Signed-off-by: Mario Limonciello <mario.limonciello@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 | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+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 f964e79babdb5..bfa15d8959553 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -3936,7 +3936,7 @@ static void amdgpu_dm_update_backlight_caps(struct amdgpu_display_manager *dm,
+ int spread = caps.max_input_signal - caps.min_input_signal;
+
+ if (caps.max_input_signal > AMDGPU_DM_DEFAULT_MAX_BACKLIGHT ||
+- caps.min_input_signal < AMDGPU_DM_DEFAULT_MIN_BACKLIGHT ||
++ caps.min_input_signal < 0 ||
+ spread > AMDGPU_DM_DEFAULT_MAX_BACKLIGHT ||
+ spread < AMDGPU_DM_MIN_SPREAD) {
+ DRM_DEBUG_KMS("DM: Invalid backlight caps: min=%d, max=%d\n",
+--
+2.43.0
+
--- /dev/null
+From afb54fc0cc80507d670922d192fe03e7cfbc332d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Oct 2021 22:58:41 +0100
+Subject: drm/rockchip: define gamma registers for RK3399
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Hugh Cole-Baker <sigmaris@gmail.com>
+
+[ Upstream commit 3ba000d6ae999b99f29afd64814877a5c4406786 ]
+
+The VOP on RK3399 has a different approach from previous versions for
+setting a gamma lookup table, using an update_gamma_lut register. As
+this differs from RK3288, give RK3399 its own set of "common" register
+definitions.
+
+Signed-off-by: Hugh Cole-Baker <sigmaris@gmail.com>
+Tested-by: "Milan P. Stanić" <mps@arvanta.net>
+Tested-by: Linus Heckemann <git@sphalerite.org>
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/20211019215843.42718-2-sigmaris@gmail.com
+Stable-dep-of: 6b44aa559d6c ("drm/rockchip: vop: clear DMA stop bit on RK3066")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 2 ++
+ drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 24 +++++++++++++++++++--
+ drivers/gpu/drm/rockchip/rockchip_vop_reg.h | 1 +
+ 3 files changed, 25 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+index 857d97cdc67c6..14179e89bd215 100644
+--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+@@ -99,6 +99,8 @@ struct vop_common {
+ struct vop_reg dither_down_en;
+ struct vop_reg dither_up;
+ struct vop_reg dsp_lut_en;
++ struct vop_reg update_gamma_lut;
++ struct vop_reg lut_buffer_index;
+ struct vop_reg gate_en;
+ struct vop_reg mmu_en;
+ struct vop_reg out_mode;
+diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+index 8c873fcd0e99f..de7eb2fda4833 100644
+--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
++++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+@@ -865,6 +865,24 @@ static const struct vop_output rk3399_output = {
+ .mipi_dual_channel_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 3),
+ };
+
++static const struct vop_common rk3399_common = {
++ .standby = VOP_REG_SYNC(RK3399_SYS_CTRL, 0x1, 22),
++ .gate_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 23),
++ .mmu_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 20),
++ .dither_down_sel = VOP_REG(RK3399_DSP_CTRL1, 0x1, 4),
++ .dither_down_mode = VOP_REG(RK3399_DSP_CTRL1, 0x1, 3),
++ .dither_down_en = VOP_REG(RK3399_DSP_CTRL1, 0x1, 2),
++ .pre_dither_down = VOP_REG(RK3399_DSP_CTRL1, 0x1, 1),
++ .dither_up = VOP_REG(RK3399_DSP_CTRL1, 0x1, 6),
++ .dsp_lut_en = VOP_REG(RK3399_DSP_CTRL1, 0x1, 0),
++ .update_gamma_lut = VOP_REG(RK3399_DSP_CTRL1, 0x1, 7),
++ .lut_buffer_index = VOP_REG(RK3399_DBG_POST_REG1, 0x1, 1),
++ .data_blank = VOP_REG(RK3399_DSP_CTRL0, 0x1, 19),
++ .dsp_blank = VOP_REG(RK3399_DSP_CTRL0, 0x3, 18),
++ .out_mode = VOP_REG(RK3399_DSP_CTRL0, 0xf, 0),
++ .cfg_done = VOP_REG_SYNC(RK3399_REG_CFG_DONE, 0x1, 0),
++};
++
+ static const struct vop_yuv2yuv_phy rk3399_yuv2yuv_win01_data = {
+ .y2r_coefficients = {
+ VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 0, 0xffff, 0),
+@@ -946,7 +964,7 @@ static const struct vop_data rk3399_vop_big = {
+ .version = VOP_VERSION(3, 5),
+ .feature = VOP_FEATURE_OUTPUT_RGB10,
+ .intr = &rk3366_vop_intr,
+- .common = &rk3288_common,
++ .common = &rk3399_common,
+ .modeset = &rk3288_modeset,
+ .output = &rk3399_output,
+ .afbc = &rk3399_vop_afbc,
+@@ -954,6 +972,7 @@ static const struct vop_data rk3399_vop_big = {
+ .win = rk3399_vop_win_data,
+ .win_size = ARRAY_SIZE(rk3399_vop_win_data),
+ .win_yuv2yuv = rk3399_vop_big_win_yuv2yuv_data,
++ .lut_size = 1024,
+ };
+
+ static const struct vop_win_data rk3399_vop_lit_win_data[] = {
+@@ -972,13 +991,14 @@ static const struct vop_win_yuv2yuv_data rk3399_vop_lit_win_yuv2yuv_data[] = {
+ static const struct vop_data rk3399_vop_lit = {
+ .version = VOP_VERSION(3, 6),
+ .intr = &rk3366_vop_intr,
+- .common = &rk3288_common,
++ .common = &rk3399_common,
+ .modeset = &rk3288_modeset,
+ .output = &rk3399_output,
+ .misc = &rk3368_misc,
+ .win = rk3399_vop_lit_win_data,
+ .win_size = ARRAY_SIZE(rk3399_vop_lit_win_data),
+ .win_yuv2yuv = rk3399_vop_lit_win_yuv2yuv_data,
++ .lut_size = 256,
+ };
+
+ static const struct vop_win_data rk3228_vop_win_data[] = {
+diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.h b/drivers/gpu/drm/rockchip/rockchip_vop_reg.h
+index 0b3cd65ba5c1b..406e981c75bd7 100644
+--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.h
++++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.h
+@@ -628,6 +628,7 @@
+ #define RK3399_YUV2YUV_WIN 0x02c0
+ #define RK3399_YUV2YUV_POST 0x02c4
+ #define RK3399_AUTO_GATING_EN 0x02cc
++#define RK3399_DBG_POST_REG1 0x036c
+ #define RK3399_WIN0_CSC_COE 0x03a0
+ #define RK3399_WIN1_CSC_COE 0x03c0
+ #define RK3399_WIN2_CSC_COE 0x03e0
+--
+2.43.0
+
--- /dev/null
+From f3c0b8de514925846638205a48be534c981e2e14 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Oct 2021 22:58:42 +0100
+Subject: drm/rockchip: support gamma control on RK3399
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Hugh Cole-Baker <sigmaris@gmail.com>
+
+[ Upstream commit 7ae7a6211fe7251543796d5af971acb8c9e2da9e ]
+
+The RK3399 has a 1024-entry gamma LUT with 10 bits per component on its
+"big" VOP and a 256-entry, 8 bit per component LUT on the "little" VOP.
+Compared to the RK3288, it no longer requires disabling gamma while
+updating the LUT. On the RK3399, the LUT can be updated at any time as
+the hardware has two LUT buffers, one can be written while the other is
+in use. A swap of the buffers is triggered by writing 1 to the
+update_gamma_lut register.
+
+Signed-off-by: Hugh Cole-Baker <sigmaris@gmail.com>
+Tested-by: "Milan P. Stanić" <mps@arvanta.net>
+Tested-by: Linus Heckemann <git@sphalerite.org>
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/20211019215843.42718-3-sigmaris@gmail.com
+Stable-dep-of: 6b44aa559d6c ("drm/rockchip: vop: clear DMA stop bit on RK3066")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 105 +++++++++++++-------
+ 1 file changed, 71 insertions(+), 34 deletions(-)
+
+diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+index c9056bf8659ad..3d5e463757f55 100644
+--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+@@ -9,6 +9,7 @@
+ #include <linux/delay.h>
+ #include <linux/iopoll.h>
+ #include <linux/kernel.h>
++#include <linux/log2.h>
+ #include <linux/module.h>
+ #include <linux/of.h>
+ #include <linux/of_device.h>
+@@ -66,6 +67,9 @@
+ #define VOP_REG_SET(vop, group, name, v) \
+ vop_reg_set(vop, &vop->data->group->name, 0, ~0, v, #name)
+
++#define VOP_HAS_REG(vop, group, name) \
++ (!!(vop->data->group->name.mask))
++
+ #define VOP_INTR_SET_TYPE(vop, name, type, v) \
+ do { \
+ int i, reg = 0, mask = 0; \
+@@ -1211,17 +1215,22 @@ static bool vop_dsp_lut_is_enabled(struct vop *vop)
+ return vop_read_reg(vop, 0, &vop->data->common->dsp_lut_en);
+ }
+
++static u32 vop_lut_buffer_index(struct vop *vop)
++{
++ return vop_read_reg(vop, 0, &vop->data->common->lut_buffer_index);
++}
++
+ static void vop_crtc_write_gamma_lut(struct vop *vop, struct drm_crtc *crtc)
+ {
+ struct drm_color_lut *lut = crtc->state->gamma_lut->data;
+- unsigned int i;
++ unsigned int i, bpc = ilog2(vop->data->lut_size);
+
+ for (i = 0; i < crtc->gamma_size; i++) {
+ u32 word;
+
+- word = (drm_color_lut_extract(lut[i].red, 10) << 20) |
+- (drm_color_lut_extract(lut[i].green, 10) << 10) |
+- drm_color_lut_extract(lut[i].blue, 10);
++ word = (drm_color_lut_extract(lut[i].red, bpc) << (2 * bpc)) |
++ (drm_color_lut_extract(lut[i].green, bpc) << bpc) |
++ drm_color_lut_extract(lut[i].blue, bpc);
+ writel(word, vop->lut_regs + i * 4);
+ }
+ }
+@@ -1231,38 +1240,66 @@ static void vop_crtc_gamma_set(struct vop *vop, struct drm_crtc *crtc,
+ {
+ struct drm_crtc_state *state = crtc->state;
+ unsigned int idle;
++ u32 lut_idx, old_idx;
+ int ret;
+
+ if (!vop->lut_regs)
+ return;
+- /*
+- * To disable gamma (gamma_lut is null) or to write
+- * an update to the LUT, clear dsp_lut_en.
+- */
+- spin_lock(&vop->reg_lock);
+- VOP_REG_SET(vop, common, dsp_lut_en, 0);
+- vop_cfg_done(vop);
+- spin_unlock(&vop->reg_lock);
+
+- /*
+- * In order to write the LUT to the internal memory,
+- * we need to first make sure the dsp_lut_en bit is cleared.
+- */
+- ret = readx_poll_timeout(vop_dsp_lut_is_enabled, vop,
+- idle, !idle, 5, 30 * 1000);
+- if (ret) {
+- DRM_DEV_ERROR(vop->dev, "display LUT RAM enable timeout!\n");
+- return;
+- }
++ if (!state->gamma_lut || !VOP_HAS_REG(vop, common, update_gamma_lut)) {
++ /*
++ * To disable gamma (gamma_lut is null) or to write
++ * an update to the LUT, clear dsp_lut_en.
++ */
++ spin_lock(&vop->reg_lock);
++ VOP_REG_SET(vop, common, dsp_lut_en, 0);
++ vop_cfg_done(vop);
++ spin_unlock(&vop->reg_lock);
+
+- if (!state->gamma_lut)
+- return;
++ /*
++ * In order to write the LUT to the internal memory,
++ * we need to first make sure the dsp_lut_en bit is cleared.
++ */
++ ret = readx_poll_timeout(vop_dsp_lut_is_enabled, vop,
++ idle, !idle, 5, 30 * 1000);
++ if (ret) {
++ DRM_DEV_ERROR(vop->dev, "display LUT RAM enable timeout!\n");
++ return;
++ }
++
++ if (!state->gamma_lut)
++ return;
++ } else {
++ /*
++ * On RK3399 the gamma LUT can updated without clearing dsp_lut_en,
++ * by setting update_gamma_lut then waiting for lut_buffer_index change
++ */
++ old_idx = vop_lut_buffer_index(vop);
++ }
+
+ spin_lock(&vop->reg_lock);
+ vop_crtc_write_gamma_lut(vop, crtc);
+ VOP_REG_SET(vop, common, dsp_lut_en, 1);
++ VOP_REG_SET(vop, common, update_gamma_lut, 1);
+ vop_cfg_done(vop);
+ spin_unlock(&vop->reg_lock);
++
++ if (VOP_HAS_REG(vop, common, update_gamma_lut)) {
++ ret = readx_poll_timeout(vop_lut_buffer_index, vop,
++ lut_idx, lut_idx != old_idx, 5, 30 * 1000);
++ if (ret) {
++ DRM_DEV_ERROR(vop->dev, "gamma LUT update timeout!\n");
++ return;
++ }
++
++ /*
++ * update_gamma_lut is auto cleared by HW, but write 0 to clear the bit
++ * in our backup of the regs.
++ */
++ spin_lock(&vop->reg_lock);
++ VOP_REG_SET(vop, common, update_gamma_lut, 0);
++ spin_unlock(&vop->reg_lock);
++ }
+ }
+
+ static void vop_crtc_atomic_begin(struct drm_crtc *crtc,
+@@ -1312,14 +1349,6 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc,
+ return;
+ }
+
+- /*
+- * If we have a GAMMA LUT in the state, then let's make sure
+- * it's updated. We might be coming out of suspend,
+- * which means the LUT internal memory needs to be re-written.
+- */
+- if (crtc->state->gamma_lut)
+- vop_crtc_gamma_set(vop, crtc, old_state);
+-
+ mutex_lock(&vop->vop_lock);
+
+ WARN_ON(vop->event);
+@@ -1410,6 +1439,14 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc,
+
+ VOP_REG_SET(vop, common, standby, 0);
+ mutex_unlock(&vop->vop_lock);
++
++ /*
++ * If we have a GAMMA LUT in the state, then let's make sure
++ * it's updated. We might be coming out of suspend,
++ * which means the LUT internal memory needs to be re-written.
++ */
++ if (crtc->state->gamma_lut)
++ vop_crtc_gamma_set(vop, crtc, old_state);
+ }
+
+ static bool vop_fs_irq_is_pending(struct vop *vop)
+@@ -2139,8 +2176,8 @@ static int vop_bind(struct device *dev, struct device *master, void *data)
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (res) {
+- if (!vop_data->lut_size) {
+- DRM_DEV_ERROR(dev, "no gamma LUT size defined\n");
++ if (vop_data->lut_size != 1024 && vop_data->lut_size != 256) {
++ DRM_DEV_ERROR(dev, "unsupported gamma LUT size %d\n", vop_data->lut_size);
+ return -EINVAL;
+ }
+ vop->lut_regs = devm_ioremap_resource(dev, res);
+--
+2.43.0
+
--- /dev/null
+From 324ce568ab1f5c1bb99642167faa30c8e6ea98b5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Jun 2024 17:40:48 -0300
+Subject: drm/rockchip: vop: clear DMA stop bit on RK3066
+
+From: Val Packett <val@packett.cool>
+
+[ Upstream commit 6b44aa559d6c7f4ea591ef9d2352a7250138d62a ]
+
+The RK3066 VOP sets a dma_stop bit when it's done scanning out a frame
+and needs the driver to acknowledge that by clearing the bit.
+
+Unless we clear it "between" frames, the RGB output only shows noise
+instead of the picture. atomic_flush is the place for it that least
+affects other code (doing it on vblank would require converting all
+other usages of the reg_lock to spin_(un)lock_irq, which would affect
+performance for everyone).
+
+This seems to be a redundant synchronization mechanism that was removed
+in later iterations of the VOP hardware block.
+
+Fixes: f4a6de855eae ("drm: rockchip: vop: add rk3066 vop definitions")
+Cc: stable@vger.kernel.org
+Signed-off-by: Val Packett <val@packett.cool>
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/20240624204054.5524-2-val@packett.cool
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 4 ++++
+ drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 1 +
+ drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 1 +
+ 3 files changed, 6 insertions(+)
+
+diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+index 3d5e463757f55..40e733fd8862a 100644
+--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+@@ -1544,6 +1544,10 @@ static void vop_crtc_atomic_flush(struct drm_crtc *crtc,
+ VOP_AFBC_SET(vop, enable, s->enable_afbc);
+ vop_cfg_done(vop);
+
++ /* Ack the DMA transfer of the previous frame (RK3066). */
++ if (VOP_HAS_REG(vop, common, dma_stop))
++ VOP_REG_SET(vop, common, dma_stop, 0);
++
+ spin_unlock(&vop->reg_lock);
+
+ /*
+diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+index 14179e89bd215..32d1783be01d3 100644
+--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+@@ -103,6 +103,7 @@ struct vop_common {
+ struct vop_reg lut_buffer_index;
+ struct vop_reg gate_en;
+ struct vop_reg mmu_en;
++ struct vop_reg dma_stop;
+ struct vop_reg out_mode;
+ struct vop_reg standby;
+ };
+diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+index de7eb2fda4833..3bcc3d614ee1d 100644
+--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
++++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+@@ -424,6 +424,7 @@ static const struct vop_output rk3066_output = {
+ };
+
+ static const struct vop_common rk3066_common = {
++ .dma_stop = VOP_REG(RK3066_SYS_CTRL0, 0x1, 0),
+ .standby = VOP_REG(RK3066_SYS_CTRL0, 0x1, 1),
+ .out_mode = VOP_REG(RK3066_DSP_CTRL0, 0xf, 0),
+ .cfg_done = VOP_REG(RK3066_REG_CFG_DONE, 0x1, 0),
+--
+2.43.0
+
--- /dev/null
+From 281ec23c3aaf2acdf3c2637cdf51326c9b390e60 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 Aug 2024 10:43:02 +0530
+Subject: dt-bindings: clock: qcom: Add GPLL9 support on gcc-sc8180x
+
+From: Satya Priya Kakitapalli <quic_skakitap@quicinc.com>
+
+[ Upstream commit 648b4bde0aca2980ebc0b90cdfbb80d222370c3d ]
+
+Add the missing GPLL9 which is required for the gcc sdcc2 clock.
+
+Fixes: 0fadcdfdcf57 ("dt-bindings: clock: Add SC8180x GCC binding")
+Cc: stable@vger.kernel.org
+Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Satya Priya Kakitapalli <quic_skakitap@quicinc.com>
+Link: https://lore.kernel.org/r/20240812-gcc-sc8180x-fixes-v2-2-8b3eaa5fb856@quicinc.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/dt-bindings/clock/qcom,gcc-sc8180x.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/include/dt-bindings/clock/qcom,gcc-sc8180x.h b/include/dt-bindings/clock/qcom,gcc-sc8180x.h
+index 90c6e021a0356..2569f874fe13c 100644
+--- a/include/dt-bindings/clock/qcom,gcc-sc8180x.h
++++ b/include/dt-bindings/clock/qcom,gcc-sc8180x.h
+@@ -248,6 +248,7 @@
+ #define GCC_USB3_SEC_CLKREF_CLK 238
+ #define GCC_UFS_MEM_CLKREF_EN 239
+ #define GCC_UFS_CARD_CLKREF_EN 240
++#define GPLL9 241
+
+ #define GCC_EMAC_BCR 0
+ #define GCC_GPU_BCR 1
+--
+2.43.0
+
--- /dev/null
+From 0609bdb98f5d40ffd255809a2f145787ff1e70ec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Jan 2024 12:37:26 +0530
+Subject: dt-bindings: clock: qcom: Add missing UFS QREF clocks
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+[ Upstream commit 26447dad8119fd084d7c6f167c3026700b701666 ]
+
+Add missing QREF clocks for UFS MEM and UFS CARD controllers.
+
+Fixes: 0fadcdfdcf57 ("dt-bindings: clock: Add SC8180x GCC binding")
+Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/r/20240131-ufs-phy-clock-v3-3-58a49d2f4605@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Stable-dep-of: 648b4bde0aca ("dt-bindings: clock: qcom: Add GPLL9 support on gcc-sc8180x")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/dt-bindings/clock/qcom,gcc-sc8180x.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/include/dt-bindings/clock/qcom,gcc-sc8180x.h b/include/dt-bindings/clock/qcom,gcc-sc8180x.h
+index e893415ae13d0..90c6e021a0356 100644
+--- a/include/dt-bindings/clock/qcom,gcc-sc8180x.h
++++ b/include/dt-bindings/clock/qcom,gcc-sc8180x.h
+@@ -246,6 +246,8 @@
+ #define GCC_PCIE_3_CLKREF_CLK 236
+ #define GCC_USB3_PRIM_CLKREF_CLK 237
+ #define GCC_USB3_SEC_CLKREF_CLK 238
++#define GCC_UFS_MEM_CLKREF_EN 239
++#define GCC_UFS_CARD_CLKREF_EN 240
+
+ #define GCC_EMAC_BCR 0
+ #define GCC_GPU_BCR 1
+--
+2.43.0
+
--- /dev/null
+From e0e6b44287ed4cc1765d19f8f4845a669e302192 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Aug 2024 20:15:32 +0800
+Subject: ext4: dax: fix overflowing extents beyond inode size when partially
+ writing
+
+From: Zhihao Cheng <chengzhihao1@huawei.com>
+
+[ Upstream commit dda898d7ffe85931f9cca6d702a51f33717c501e ]
+
+The dax_iomap_rw() does two things in each iteration: map written blocks
+and copy user data to blocks. If the process is killed by user(See signal
+handling in dax_iomap_iter()), the copied data will be returned and added
+on inode size, which means that the length of written extents may exceed
+the inode size, then fsck will fail. An example is given as:
+
+dd if=/dev/urandom of=file bs=4M count=1
+ dax_iomap_rw
+ iomap_iter // round 1
+ ext4_iomap_begin
+ ext4_iomap_alloc // allocate 0~2M extents(written flag)
+ dax_iomap_iter // copy 2M data
+ iomap_iter // round 2
+ iomap_iter_advance
+ iter->pos += iter->processed // iter->pos = 2M
+ ext4_iomap_begin
+ ext4_iomap_alloc // allocate 2~4M extents(written flag)
+ dax_iomap_iter
+ fatal_signal_pending
+ done = iter->pos - iocb->ki_pos // done = 2M
+ ext4_handle_inode_extension
+ ext4_update_inode_size // inode size = 2M
+
+fsck reports: Inode 13, i_size is 2097152, should be 4194304. Fix?
+
+Fix the problem by truncating extents if the written length is smaller
+than expected.
+
+Fixes: 776722e85d3b ("ext4: DAX iomap write support")
+CC: stable@vger.kernel.org
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=219136
+Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Link: https://patch.msgid.link/20240809121532.2105494-1-chengzhihao@huaweicloud.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/file.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/fs/ext4/file.c b/fs/ext4/file.c
+index 94ce73fadcba6..4791ba35ca193 100644
+--- a/fs/ext4/file.c
++++ b/fs/ext4/file.c
+@@ -307,10 +307,10 @@ static ssize_t ext4_handle_inode_extension(struct inode *inode, loff_t offset,
+ * Clean up the inode after DIO or DAX extending write has completed and the
+ * inode size has been updated using ext4_handle_inode_extension().
+ */
+-static void ext4_inode_extension_cleanup(struct inode *inode, ssize_t count)
++static void ext4_inode_extension_cleanup(struct inode *inode, bool need_trunc)
+ {
+ lockdep_assert_held_write(&inode->i_rwsem);
+- if (count < 0) {
++ if (need_trunc) {
+ ext4_truncate_failed_write(inode);
+ /*
+ * If the truncate operation failed early, then the inode may
+@@ -548,7 +548,7 @@ static ssize_t ext4_dio_write_iter(struct kiocb *iocb, struct iov_iter *from)
+ * writeback of delalloc blocks.
+ */
+ WARN_ON_ONCE(ret == -EIOCBQUEUED);
+- ext4_inode_extension_cleanup(inode, ret);
++ ext4_inode_extension_cleanup(inode, ret < 0);
+ }
+
+ out:
+@@ -632,7 +632,7 @@ ext4_dax_write_iter(struct kiocb *iocb, struct iov_iter *from)
+
+ if (extend) {
+ ret = ext4_handle_inode_extension(inode, offset, ret);
+- ext4_inode_extension_cleanup(inode, ret);
++ ext4_inode_extension_cleanup(inode, ret < (ssize_t)count);
+ }
+ out:
+ inode_unlock(inode);
+--
+2.43.0
+
--- /dev/null
+From bab6d50fad4a371152a6b778bbd82a5f2c25c18c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Oct 2023 14:13:50 +0200
+Subject: ext4: properly sync file size update after O_SYNC direct IO
+
+From: Jan Kara <jack@suse.cz>
+
+[ Upstream commit 91562895f8030cb9a0470b1db49de79346a69f91 ]
+
+Gao Xiang has reported that on ext4 O_SYNC direct IO does not properly
+sync file size update and thus if we crash at unfortunate moment, the
+file can have smaller size although O_SYNC IO has reported successful
+completion. The problem happens because update of on-disk inode size is
+handled in ext4_dio_write_iter() *after* iomap_dio_rw() (and thus
+dio_complete() in particular) has returned and generic_file_sync() gets
+called by dio_complete(). Fix the problem by handling on-disk inode size
+update directly in our ->end_io completion handler.
+
+References: https://lore.kernel.org/all/02d18236-26ef-09b0-90ad-030c4fe3ee20@linux.alibaba.com
+Reported-by: Gao Xiang <hsiangkao@linux.alibaba.com>
+CC: stable@vger.kernel.org
+Fixes: 378f32bab371 ("ext4: introduce direct I/O write using iomap infrastructure")
+Signed-off-by: Jan Kara <jack@suse.cz>
+Tested-by: Joseph Qi <joseph.qi@linux.alibaba.com>
+Reviewed-by: "Ritesh Harjani (IBM)" <ritesh.list@gmail.com>
+Link: https://lore.kernel.org/r/20231013121350.26872-1-jack@suse.cz
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Stable-dep-of: dda898d7ffe8 ("ext4: dax: fix overflowing extents beyond inode size when partially writing")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/file.c | 153 +++++++++++++++++++++----------------------------
+ 1 file changed, 65 insertions(+), 88 deletions(-)
+
+diff --git a/fs/ext4/file.c b/fs/ext4/file.c
+index 4704fe627c4e2..94ce73fadcba6 100644
+--- a/fs/ext4/file.c
++++ b/fs/ext4/file.c
+@@ -279,80 +279,38 @@ static ssize_t ext4_buffered_write_iter(struct kiocb *iocb,
+ }
+
+ static ssize_t ext4_handle_inode_extension(struct inode *inode, loff_t offset,
+- ssize_t written, size_t count)
++ ssize_t count)
+ {
+ handle_t *handle;
+- bool truncate = false;
+- u8 blkbits = inode->i_blkbits;
+- ext4_lblk_t written_blk, end_blk;
+- int ret;
+-
+- /*
+- * Note that EXT4_I(inode)->i_disksize can get extended up to
+- * inode->i_size while the I/O was running due to writeback of delalloc
+- * blocks. But, the code in ext4_iomap_alloc() is careful to use
+- * zeroed/unwritten extents if this is possible; thus we won't leave
+- * uninitialized blocks in a file even if we didn't succeed in writing
+- * as much as we intended.
+- */
+- WARN_ON_ONCE(i_size_read(inode) < EXT4_I(inode)->i_disksize);
+- if (offset + count <= EXT4_I(inode)->i_disksize) {
+- /*
+- * We need to ensure that the inode is removed from the orphan
+- * list if it has been added prematurely, due to writeback of
+- * delalloc blocks.
+- */
+- if (!list_empty(&EXT4_I(inode)->i_orphan) && inode->i_nlink) {
+- handle = ext4_journal_start(inode, EXT4_HT_INODE, 2);
+-
+- if (IS_ERR(handle)) {
+- ext4_orphan_del(NULL, inode);
+- return PTR_ERR(handle);
+- }
+-
+- ext4_orphan_del(handle, inode);
+- ext4_journal_stop(handle);
+- }
+-
+- return written;
+- }
+-
+- if (written < 0)
+- goto truncate;
+
++ lockdep_assert_held_write(&inode->i_rwsem);
+ handle = ext4_journal_start(inode, EXT4_HT_INODE, 2);
+- if (IS_ERR(handle)) {
+- written = PTR_ERR(handle);
+- goto truncate;
+- }
++ if (IS_ERR(handle))
++ return PTR_ERR(handle);
+
+- if (ext4_update_inode_size(inode, offset + written)) {
+- ret = ext4_mark_inode_dirty(handle, inode);
++ if (ext4_update_inode_size(inode, offset + count)) {
++ int ret = ext4_mark_inode_dirty(handle, inode);
+ if (unlikely(ret)) {
+- written = ret;
+ ext4_journal_stop(handle);
+- goto truncate;
++ return ret;
+ }
+ }
+
+- /*
+- * We may need to truncate allocated but not written blocks beyond EOF.
+- */
+- written_blk = ALIGN(offset + written, 1 << blkbits);
+- end_blk = ALIGN(offset + count, 1 << blkbits);
+- if (written_blk < end_blk && ext4_can_truncate(inode))
+- truncate = true;
+-
+- /*
+- * Remove the inode from the orphan list if it has been extended and
+- * everything went OK.
+- */
+- if (!truncate && inode->i_nlink)
++ if (inode->i_nlink)
+ ext4_orphan_del(handle, inode);
+ ext4_journal_stop(handle);
+
+- if (truncate) {
+-truncate:
++ return count;
++}
++
++/*
++ * Clean up the inode after DIO or DAX extending write has completed and the
++ * inode size has been updated using ext4_handle_inode_extension().
++ */
++static void ext4_inode_extension_cleanup(struct inode *inode, ssize_t count)
++{
++ lockdep_assert_held_write(&inode->i_rwsem);
++ if (count < 0) {
+ ext4_truncate_failed_write(inode);
+ /*
+ * If the truncate operation failed early, then the inode may
+@@ -361,9 +319,28 @@ static ssize_t ext4_handle_inode_extension(struct inode *inode, loff_t offset,
+ */
+ if (inode->i_nlink)
+ ext4_orphan_del(NULL, inode);
++ return;
+ }
++ /*
++ * If i_disksize got extended due to writeback of delalloc blocks while
++ * the DIO was running we could fail to cleanup the orphan list in
++ * ext4_handle_inode_extension(). Do it now.
++ */
++ if (!list_empty(&EXT4_I(inode)->i_orphan) && inode->i_nlink) {
++ handle_t *handle = ext4_journal_start(inode, EXT4_HT_INODE, 2);
+
+- return written;
++ if (IS_ERR(handle)) {
++ /*
++ * The write has successfully completed. Not much to
++ * do with the error here so just cleanup the orphan
++ * list and hope for the best.
++ */
++ ext4_orphan_del(NULL, inode);
++ return;
++ }
++ ext4_orphan_del(handle, inode);
++ ext4_journal_stop(handle);
++ }
+ }
+
+ static int ext4_dio_write_end_io(struct kiocb *iocb, ssize_t size,
+@@ -372,31 +349,22 @@ static int ext4_dio_write_end_io(struct kiocb *iocb, ssize_t size,
+ loff_t pos = iocb->ki_pos;
+ struct inode *inode = file_inode(iocb->ki_filp);
+
++ if (!error && size && flags & IOMAP_DIO_UNWRITTEN)
++ error = ext4_convert_unwritten_extents(NULL, inode, pos, size);
+ if (error)
+ return error;
+-
+- if (size && flags & IOMAP_DIO_UNWRITTEN) {
+- error = ext4_convert_unwritten_extents(NULL, inode, pos, size);
+- if (error < 0)
+- return error;
+- }
+ /*
+- * If we are extending the file, we have to update i_size here before
+- * page cache gets invalidated in iomap_dio_rw(). Otherwise racing
+- * buffered reads could zero out too much from page cache pages. Update
+- * of on-disk size will happen later in ext4_dio_write_iter() where
+- * we have enough information to also perform orphan list handling etc.
+- * Note that we perform all extending writes synchronously under
+- * i_rwsem held exclusively so i_size update is safe here in that case.
+- * If the write was not extending, we cannot see pos > i_size here
+- * because operations reducing i_size like truncate wait for all
+- * outstanding DIO before updating i_size.
++ * Note that EXT4_I(inode)->i_disksize can get extended up to
++ * inode->i_size while the I/O was running due to writeback of delalloc
++ * blocks. But the code in ext4_iomap_alloc() is careful to use
++ * zeroed/unwritten extents if this is possible; thus we won't leave
++ * uninitialized blocks in a file even if we didn't succeed in writing
++ * as much as we intended.
+ */
+- pos += size;
+- if (pos > i_size_read(inode))
+- i_size_write(inode, pos);
+-
+- return 0;
++ WARN_ON_ONCE(i_size_read(inode) < READ_ONCE(EXT4_I(inode)->i_disksize));
++ if (pos + size <= READ_ONCE(EXT4_I(inode)->i_disksize))
++ return size;
++ return ext4_handle_inode_extension(inode, pos, size);
+ }
+
+ static const struct iomap_dio_ops ext4_dio_write_ops = {
+@@ -572,9 +540,16 @@ static ssize_t ext4_dio_write_iter(struct kiocb *iocb, struct iov_iter *from)
+ 0);
+ if (ret == -ENOTBLK)
+ ret = 0;
+-
+- if (extend)
+- ret = ext4_handle_inode_extension(inode, offset, ret, count);
++ if (extend) {
++ /*
++ * We always perform extending DIO write synchronously so by
++ * now the IO is completed and ext4_handle_inode_extension()
++ * was called. Cleanup the inode in case of error or race with
++ * writeback of delalloc blocks.
++ */
++ WARN_ON_ONCE(ret == -EIOCBQUEUED);
++ ext4_inode_extension_cleanup(inode, ret);
++ }
+
+ out:
+ if (ilock_shared)
+@@ -655,8 +630,10 @@ ext4_dax_write_iter(struct kiocb *iocb, struct iov_iter *from)
+
+ ret = dax_iomap_rw(iocb, from, &ext4_iomap_ops);
+
+- if (extend)
+- ret = ext4_handle_inode_extension(inode, offset, ret, count);
++ if (extend) {
++ ret = ext4_handle_inode_extension(inode, offset, ret);
++ ext4_inode_extension_cleanup(inode, ret);
++ }
+ out:
+ inode_unlock(inode);
+ if (ret > 0)
+--
+2.43.0
+
--- /dev/null
+From 2f5c61b3abc9b1f850f5ad9c1abad77cfc374f1b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Aug 2024 21:44:50 +0200
+Subject: i2c: core: Lock address during client device instantiation
+
+From: Heiner Kallweit <hkallweit1@gmail.com>
+
+[ Upstream commit 8d3cefaf659265aa82b0373a563fdb9d16a2b947 ]
+
+Krzysztof reported an issue [0] which is caused by parallel attempts to
+instantiate the same I2C client device. This can happen if driver
+supports auto-detection, but certain devices are also instantiated
+explicitly.
+The original change isn't actually wrong, it just revealed that I2C core
+isn't prepared yet to handle this scenario.
+Calls to i2c_new_client_device() can be nested, therefore we can't use a
+simple mutex here. Parallel instantiation of devices at different addresses
+is ok, so we just have to prevent parallel instantiation at the same address.
+We can use a bitmap with one bit per 7-bit I2C client address, and atomic
+bit operations to set/check/clear bits.
+Now a parallel attempt to instantiate a device at the same address will
+result in -EBUSY being returned, avoiding the "sysfs: cannot create duplicate
+filename" splash.
+
+Note: This patch version includes small cosmetic changes to the Tested-by
+ version, only functional change is that address locking is supported
+ for slave addresses too.
+
+[0] https://lore.kernel.org/linux-i2c/9479fe4e-eb0c-407e-84c0-bd60c15baf74@ans.pl/T/#m12706546e8e2414d8f1a0dc61c53393f731685cc
+
+Fixes: caba40ec3531 ("eeprom: at24: Probe for DDR3 thermal sensor in the SPD case")
+Cc: stable@vger.kernel.org
+Tested-by: Krzysztof Piotr Oledzki <ole@ans.pl>
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/i2c-core-base.c | 28 ++++++++++++++++++++++++++++
+ include/linux/i2c.h | 3 +++
+ 2 files changed, 31 insertions(+)
+
+diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
+index 76d70de2d317d..265b7f7f38c6e 100644
+--- a/drivers/i2c/i2c-core-base.c
++++ b/drivers/i2c/i2c-core-base.c
+@@ -917,6 +917,27 @@ int i2c_dev_irq_from_resources(const struct resource *resources,
+ return 0;
+ }
+
++/*
++ * Serialize device instantiation in case it can be instantiated explicitly
++ * and by auto-detection
++ */
++static int i2c_lock_addr(struct i2c_adapter *adap, unsigned short addr,
++ unsigned short flags)
++{
++ if (!(flags & I2C_CLIENT_TEN) &&
++ test_and_set_bit(addr, adap->addrs_in_instantiation))
++ return -EBUSY;
++
++ return 0;
++}
++
++static void i2c_unlock_addr(struct i2c_adapter *adap, unsigned short addr,
++ unsigned short flags)
++{
++ if (!(flags & I2C_CLIENT_TEN))
++ clear_bit(addr, adap->addrs_in_instantiation);
++}
++
+ /**
+ * i2c_new_client_device - instantiate an i2c device
+ * @adap: the adapter managing the device
+@@ -963,6 +984,10 @@ i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *inf
+ goto out_err_silent;
+ }
+
++ status = i2c_lock_addr(adap, client->addr, client->flags);
++ if (status)
++ goto out_err_silent;
++
+ /* Check for address business */
+ status = i2c_check_addr_busy(adap, i2c_encode_flags_to_addr(client));
+ if (status)
+@@ -993,6 +1018,8 @@ i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *inf
+ dev_dbg(&adap->dev, "client [%s] registered with bus id %s\n",
+ client->name, dev_name(&client->dev));
+
++ i2c_unlock_addr(adap, client->addr, client->flags);
++
+ return client;
+
+ out_remove_swnode:
+@@ -1003,6 +1030,7 @@ i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *inf
+ dev_err(&adap->dev,
+ "Failed to register i2c client %s at 0x%02x (%d)\n",
+ client->name, client->addr, status);
++ i2c_unlock_addr(adap, client->addr, client->flags);
+ out_err_silent:
+ kfree(client);
+ return ERR_PTR(status);
+diff --git a/include/linux/i2c.h b/include/linux/i2c.h
+index 7c2ff4d7c360a..996886f187a1e 100644
+--- a/include/linux/i2c.h
++++ b/include/linux/i2c.h
+@@ -742,6 +742,9 @@ struct i2c_adapter {
+ struct regulator *bus_regulator;
+
+ struct dentry *debugfs;
++
++ /* 7bit address space */
++ DECLARE_BITMAP(addrs_in_instantiation, 1 << 7);
+ };
+ #define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev)
+
+--
+2.43.0
+
--- /dev/null
+From 1eaefbfd99cb209eb3c18634438129766323b8f2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Nov 2023 17:54:41 -0500
+Subject: i2c: create debugfs entry per adapter
+
+From: Wolfram Sang <wsa+renesas@sang-engineering.com>
+
+[ Upstream commit 73febd775bdbdb98c81255ff85773ac410ded5c4 ]
+
+Two drivers already implement custom debugfs handling for their
+i2c_adapter and more will come. So, let the core create a debugfs
+directory per adapter and pass that to drivers for their debugfs files.
+
+Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Stable-dep-of: 8d3cefaf6592 ("i2c: core: Lock address during client device instantiation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/i2c-core-base.c | 11 +++++++++++
+ include/linux/i2c.h | 2 ++
+ 2 files changed, 13 insertions(+)
+
+diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
+index c8cb6f44a0f88..76d70de2d317d 100644
+--- a/drivers/i2c/i2c-core-base.c
++++ b/drivers/i2c/i2c-core-base.c
+@@ -16,6 +16,7 @@
+ #include <linux/acpi.h>
+ #include <linux/clk/clk-conf.h>
+ #include <linux/completion.h>
++#include <linux/debugfs.h>
+ #include <linux/delay.h>
+ #include <linux/err.h>
+ #include <linux/errno.h>
+@@ -66,6 +67,8 @@ static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver);
+ static DEFINE_STATIC_KEY_FALSE(i2c_trace_msg_key);
+ static bool is_registered;
+
++static struct dentry *i2c_debugfs_root;
++
+ int i2c_transfer_trace_reg(void)
+ {
+ static_branch_inc(&i2c_trace_msg_key);
+@@ -1526,6 +1529,8 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
+ goto out_list;
+ }
+
++ adap->debugfs = debugfs_create_dir(dev_name(&adap->dev), i2c_debugfs_root);
++
+ res = i2c_setup_smbus_alert(adap);
+ if (res)
+ goto out_reg;
+@@ -1564,6 +1569,7 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
+ return 0;
+
+ out_reg:
++ debugfs_remove_recursive(adap->debugfs);
+ init_completion(&adap->dev_released);
+ device_unregister(&adap->dev);
+ wait_for_completion(&adap->dev_released);
+@@ -1765,6 +1771,8 @@ void i2c_del_adapter(struct i2c_adapter *adap)
+
+ i2c_host_notify_irq_teardown(adap);
+
++ debugfs_remove_recursive(adap->debugfs);
++
+ /* wait until all references to the device are gone
+ *
+ * FIXME: This is old code and should ideally be replaced by an
+@@ -2062,6 +2070,8 @@ static int __init i2c_init(void)
+
+ is_registered = true;
+
++ i2c_debugfs_root = debugfs_create_dir("i2c", NULL);
++
+ #ifdef CONFIG_I2C_COMPAT
+ i2c_adapter_compat_class = class_compat_register("i2c-adapter");
+ if (!i2c_adapter_compat_class) {
+@@ -2100,6 +2110,7 @@ static void __exit i2c_exit(void)
+ #ifdef CONFIG_I2C_COMPAT
+ class_compat_unregister(i2c_adapter_compat_class);
+ #endif
++ debugfs_remove_recursive(i2c_debugfs_root);
+ bus_unregister(&i2c_bus_type);
+ tracepoint_synchronize_unregister();
+ }
+diff --git a/include/linux/i2c.h b/include/linux/i2c.h
+index 8bcc0142c32c2..7c2ff4d7c360a 100644
+--- a/include/linux/i2c.h
++++ b/include/linux/i2c.h
+@@ -740,6 +740,8 @@ struct i2c_adapter {
+
+ struct irq_domain *host_notify_domain;
+ struct regulator *bus_regulator;
++
++ struct dentry *debugfs;
+ };
+ #define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev)
+
+--
+2.43.0
+
--- /dev/null
+From 81963f9161466f3b5b494ea7a78eeb6c6a1e6ba1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Jan 2022 17:14:27 +0530
+Subject: i2c: smbus: Use device_*() functions instead of of_*()
+
+From: Akhil R <akhilrajeev@nvidia.com>
+
+[ Upstream commit a263a84088f689bf0c1552a510b25d0bcc45fcae ]
+
+Change of_*() functions to device_*() for firmware agnostic usage.
+This allows to have the smbus_alert interrupt without any changes
+in the controller drivers using the ACPI table.
+
+Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Stable-dep-of: 8d3cefaf6592 ("i2c: core: Lock address during client device instantiation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/i2c-core-base.c | 2 +-
+ drivers/i2c/i2c-core-smbus.c | 11 ++++++-----
+ drivers/i2c/i2c-smbus.c | 5 +++--
+ include/linux/i2c-smbus.h | 6 +++---
+ 4 files changed, 13 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
+index b163ef91aabab..c8cb6f44a0f88 100644
+--- a/drivers/i2c/i2c-core-base.c
++++ b/drivers/i2c/i2c-core-base.c
+@@ -1526,7 +1526,7 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
+ goto out_list;
+ }
+
+- res = of_i2c_setup_smbus_alert(adap);
++ res = i2c_setup_smbus_alert(adap);
+ if (res)
+ goto out_reg;
+
+diff --git a/drivers/i2c/i2c-core-smbus.c b/drivers/i2c/i2c-core-smbus.c
+index e5b2d1465e7ed..304c2c8fee68e 100644
+--- a/drivers/i2c/i2c-core-smbus.c
++++ b/drivers/i2c/i2c-core-smbus.c
+@@ -14,6 +14,7 @@
+ #include <linux/err.h>
+ #include <linux/i2c.h>
+ #include <linux/i2c-smbus.h>
++#include <linux/property.h>
+ #include <linux/slab.h>
+
+ #include "i2c-core.h"
+@@ -701,13 +702,13 @@ struct i2c_client *i2c_new_smbus_alert_device(struct i2c_adapter *adapter,
+ }
+ EXPORT_SYMBOL_GPL(i2c_new_smbus_alert_device);
+
+-#if IS_ENABLED(CONFIG_I2C_SMBUS) && IS_ENABLED(CONFIG_OF)
+-int of_i2c_setup_smbus_alert(struct i2c_adapter *adapter)
++#if IS_ENABLED(CONFIG_I2C_SMBUS)
++int i2c_setup_smbus_alert(struct i2c_adapter *adapter)
+ {
+ int irq;
+
+- irq = of_property_match_string(adapter->dev.of_node, "interrupt-names",
+- "smbus_alert");
++ irq = device_property_match_string(adapter->dev.parent, "interrupt-names",
++ "smbus_alert");
+ if (irq == -EINVAL || irq == -ENODATA)
+ return 0;
+ else if (irq < 0)
+@@ -715,5 +716,5 @@ int of_i2c_setup_smbus_alert(struct i2c_adapter *adapter)
+
+ return PTR_ERR_OR_ZERO(i2c_new_smbus_alert_device(adapter, NULL));
+ }
+-EXPORT_SYMBOL_GPL(of_i2c_setup_smbus_alert);
++EXPORT_SYMBOL_GPL(i2c_setup_smbus_alert);
+ #endif
+diff --git a/drivers/i2c/i2c-smbus.c b/drivers/i2c/i2c-smbus.c
+index 44582cf29e162..cacdadb9415c5 100644
+--- a/drivers/i2c/i2c-smbus.c
++++ b/drivers/i2c/i2c-smbus.c
+@@ -13,7 +13,7 @@
+ #include <linux/interrupt.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+-#include <linux/of_irq.h>
++#include <linux/property.h>
+ #include <linux/slab.h>
+ #include <linux/workqueue.h>
+
+@@ -178,7 +178,8 @@ static int smbalert_probe(struct i2c_client *ara,
+ if (setup) {
+ irq = setup->irq;
+ } else {
+- irq = of_irq_get_byname(adapter->dev.of_node, "smbus_alert");
++ irq = fwnode_irq_get_byname(dev_fwnode(adapter->dev.parent),
++ "smbus_alert");
+ if (irq <= 0)
+ return irq;
+ }
+diff --git a/include/linux/i2c-smbus.h b/include/linux/i2c-smbus.h
+index 1ef421818d3a8..95cf902e0bdae 100644
+--- a/include/linux/i2c-smbus.h
++++ b/include/linux/i2c-smbus.h
+@@ -30,10 +30,10 @@ struct i2c_client *i2c_new_smbus_alert_device(struct i2c_adapter *adapter,
+ struct i2c_smbus_alert_setup *setup);
+ int i2c_handle_smbus_alert(struct i2c_client *ara);
+
+-#if IS_ENABLED(CONFIG_I2C_SMBUS) && IS_ENABLED(CONFIG_OF)
+-int of_i2c_setup_smbus_alert(struct i2c_adapter *adap);
++#if IS_ENABLED(CONFIG_I2C_SMBUS)
++int i2c_setup_smbus_alert(struct i2c_adapter *adap);
+ #else
+-static inline int of_i2c_setup_smbus_alert(struct i2c_adapter *adap)
++static inline int i2c_setup_smbus_alert(struct i2c_adapter *adap)
+ {
+ return 0;
+ }
+--
+2.43.0
+
--- /dev/null
+From 76da75ff31954756b8ca6cff496be04e88264390 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 23 Sep 2024 11:42:50 +0800
+Subject: i2c: xiic: Fix pm_runtime_set_suspended() with runtime pm enabled
+
+From: Jinjie Ruan <ruanjinjie@huawei.com>
+
+[ Upstream commit 0c8d604dea437b69a861479b413d629bc9b3da70 ]
+
+It is not valid to call pm_runtime_set_suspended() for devices
+with runtime PM enabled because it returns -EAGAIN if it is enabled
+already and working. So, call pm_runtime_disable() before to fix it.
+
+Fixes: 36ecbcab84d0 ("i2c: xiic: Implement power management")
+Cc: <stable@vger.kernel.org> # v4.6+
+Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
+Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/busses/i2c-xiic.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c
+index 678ec68f66d60..caa27411cf6fe 100644
+--- a/drivers/i2c/busses/i2c-xiic.c
++++ b/drivers/i2c/busses/i2c-xiic.c
+@@ -893,8 +893,8 @@ static int xiic_i2c_probe(struct platform_device *pdev)
+ return 0;
+
+ err_pm_disable:
+- pm_runtime_set_suspended(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
++ pm_runtime_set_suspended(&pdev->dev);
+
+ return ret;
+ }
+--
+2.43.0
+
--- /dev/null
+From f9fa3a3757186abac2dc597bf785592cbd30a86d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 Jun 2023 00:56:49 +0200
+Subject: i2c: xiic: Use devm_clk_get_enabled()
+
+From: Andi Shyti <andi.shyti@kernel.org>
+
+[ Upstream commit 8390dc7477e49e4acc9e553f385f4ff59d186efe ]
+
+Replace the pair of functions, devm_clk_get() and clk_prepare_enable(),
+with a single function devm_clk_get_enabled().
+
+Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
+Acked-by: Michal Simek <michal.simek@amd.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Stable-dep-of: 0c8d604dea43 ("i2c: xiic: Fix pm_runtime_set_suspended() with runtime pm enabled")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/busses/i2c-xiic.c | 20 +++++++-------------
+ 1 file changed, 7 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c
+index 2642062ce5b32..678ec68f66d60 100644
+--- a/drivers/i2c/busses/i2c-xiic.c
++++ b/drivers/i2c/busses/i2c-xiic.c
+@@ -837,16 +837,11 @@ static int xiic_i2c_probe(struct platform_device *pdev)
+
+ mutex_init(&i2c->lock);
+
+- i2c->clk = devm_clk_get(&pdev->dev, NULL);
++ i2c->clk = devm_clk_get_enabled(&pdev->dev, NULL);
+ if (IS_ERR(i2c->clk))
+ return dev_err_probe(&pdev->dev, PTR_ERR(i2c->clk),
+- "input clock not found.\n");
++ "failed to enable input clock.\n");
+
+- ret = clk_prepare_enable(i2c->clk);
+- if (ret) {
+- dev_err(&pdev->dev, "Unable to enable clock.\n");
+- return ret;
+- }
+ i2c->dev = &pdev->dev;
+ pm_runtime_set_autosuspend_delay(i2c->dev, XIIC_PM_TIMEOUT);
+ pm_runtime_use_autosuspend(i2c->dev);
+@@ -858,7 +853,7 @@ static int xiic_i2c_probe(struct platform_device *pdev)
+
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Cannot claim IRQ\n");
+- goto err_clk_dis;
++ goto err_pm_disable;
+ }
+
+ i2c->singlemaster =
+@@ -879,14 +874,14 @@ static int xiic_i2c_probe(struct platform_device *pdev)
+ ret = xiic_reinit(i2c);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Cannot xiic_reinit\n");
+- goto err_clk_dis;
++ goto err_pm_disable;
+ }
+
+ /* add i2c adapter to i2c tree */
+ ret = i2c_add_adapter(&i2c->adap);
+ if (ret) {
+ xiic_deinit(i2c);
+- goto err_clk_dis;
++ goto err_pm_disable;
+ }
+
+ if (pdata) {
+@@ -897,10 +892,10 @@ static int xiic_i2c_probe(struct platform_device *pdev)
+
+ return 0;
+
+-err_clk_dis:
++err_pm_disable:
+ pm_runtime_set_suspended(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+- clk_disable_unprepare(i2c->clk);
++
+ return ret;
+ }
+
+@@ -918,7 +913,6 @@ static int xiic_i2c_remove(struct platform_device *pdev)
+
+ xiic_deinit(i2c);
+ pm_runtime_put_sync(i2c->dev);
+- clk_disable_unprepare(i2c->clk);
+ pm_runtime_disable(&pdev->dev);
+ pm_runtime_set_suspended(&pdev->dev);
+ pm_runtime_dont_use_autosuspend(&pdev->dev);
+--
+2.43.0
+
--- /dev/null
+From 47f79bd805f3d6d6f624446100e883ae2d8717a9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Oct 2024 18:02:22 +0900
+Subject: kconfig: qconf: fix buffer overflow in debug links
+
+From: Masahiro Yamada <masahiroy@kernel.org>
+
+[ Upstream commit 984ed20ece1c6c20789ece040cbff3eb1a388fa9 ]
+
+If you enable "Option -> Show Debug Info" and click a link, the program
+terminates with the following error:
+
+ *** buffer overflow detected ***: terminated
+
+The buffer overflow is caused by the following line:
+
+ strcat(data, "$");
+
+The buffer needs one more byte to accommodate the additional character.
+
+Fixes: c4f7398bee9c ("kconfig: qconf: make debug links work again")
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/kconfig/qconf.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc
+index 78087b2d9ac67..61b679f6c2f2a 100644
+--- a/scripts/kconfig/qconf.cc
++++ b/scripts/kconfig/qconf.cc
+@@ -1172,7 +1172,7 @@ void ConfigInfoView::clicked(const QUrl &url)
+ {
+ QByteArray str = url.toEncoded();
+ const std::size_t count = str.size();
+- char *data = new char[count + 1];
++ char *data = new char[count + 2]; // '$' + '\0'
+ struct symbol **result;
+ struct menu *m = NULL;
+
+--
+2.43.0
+
--- /dev/null
+From 298be92a6c701bb5f1e88ebdce751f166d4f3239 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Aug 2024 10:42:23 -0700
+Subject: lib/buildid: harden build ID parsing logic
+
+From: Andrii Nakryiko <andrii@kernel.org>
+
+[ Upstream commit 905415ff3ffb1d7e5afa62bacabd79776bd24606 ]
+
+Harden build ID parsing logic, adding explicit READ_ONCE() where it's
+important to have a consistent value read and validated just once.
+
+Also, as pointed out by Andi Kleen, we need to make sure that entire ELF
+note is within a page bounds, so move the overflow check up and add an
+extra note_size boundaries validation.
+
+Fixes tag below points to the code that moved this code into
+lib/buildid.c, and then subsequently was used in perf subsystem, making
+this code exposed to perf_event_open() users in v5.12+.
+
+Cc: stable@vger.kernel.org
+Reviewed-by: Eduard Zingerman <eddyz87@gmail.com>
+Reviewed-by: Jann Horn <jannh@google.com>
+Suggested-by: Andi Kleen <ak@linux.intel.com>
+Fixes: bd7525dacd7e ("bpf: Move stack_map_get_build_id into lib")
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/r/20240829174232.3133883-2-andrii@kernel.org
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/buildid.c | 76 +++++++++++++++++++++++++++++----------------------
+ 1 file changed, 44 insertions(+), 32 deletions(-)
+
+diff --git a/lib/buildid.c b/lib/buildid.c
+index 493537344fc81..e41fb0ee405f6 100644
+--- a/lib/buildid.c
++++ b/lib/buildid.c
+@@ -18,31 +18,37 @@ static int parse_build_id_buf(unsigned char *build_id,
+ const void *note_start,
+ Elf32_Word note_size)
+ {
+- Elf32_Word note_offs = 0, new_offs;
+-
+- while (note_offs + sizeof(Elf32_Nhdr) < note_size) {
+- Elf32_Nhdr *nhdr = (Elf32_Nhdr *)(note_start + note_offs);
++ const char note_name[] = "GNU";
++ const size_t note_name_sz = sizeof(note_name);
++ u64 note_off = 0, new_off, name_sz, desc_sz;
++ const char *data;
++
++ while (note_off + sizeof(Elf32_Nhdr) < note_size &&
++ note_off + sizeof(Elf32_Nhdr) > note_off /* overflow */) {
++ Elf32_Nhdr *nhdr = (Elf32_Nhdr *)(note_start + note_off);
++
++ name_sz = READ_ONCE(nhdr->n_namesz);
++ desc_sz = READ_ONCE(nhdr->n_descsz);
++
++ new_off = note_off + sizeof(Elf32_Nhdr);
++ if (check_add_overflow(new_off, ALIGN(name_sz, 4), &new_off) ||
++ check_add_overflow(new_off, ALIGN(desc_sz, 4), &new_off) ||
++ new_off > note_size)
++ break;
+
+ if (nhdr->n_type == BUILD_ID &&
+- nhdr->n_namesz == sizeof("GNU") &&
+- !strcmp((char *)(nhdr + 1), "GNU") &&
+- nhdr->n_descsz > 0 &&
+- nhdr->n_descsz <= BUILD_ID_SIZE_MAX) {
+- memcpy(build_id,
+- note_start + note_offs +
+- ALIGN(sizeof("GNU"), 4) + sizeof(Elf32_Nhdr),
+- nhdr->n_descsz);
+- memset(build_id + nhdr->n_descsz, 0,
+- BUILD_ID_SIZE_MAX - nhdr->n_descsz);
++ name_sz == note_name_sz &&
++ memcmp(nhdr + 1, note_name, note_name_sz) == 0 &&
++ desc_sz > 0 && desc_sz <= BUILD_ID_SIZE_MAX) {
++ data = note_start + note_off + ALIGN(note_name_sz, 4);
++ memcpy(build_id, data, desc_sz);
++ memset(build_id + desc_sz, 0, BUILD_ID_SIZE_MAX - desc_sz);
+ if (size)
+- *size = nhdr->n_descsz;
++ *size = desc_sz;
+ return 0;
+ }
+- new_offs = note_offs + sizeof(Elf32_Nhdr) +
+- ALIGN(nhdr->n_namesz, 4) + ALIGN(nhdr->n_descsz, 4);
+- if (new_offs <= note_offs) /* overflow */
+- break;
+- note_offs = new_offs;
++
++ note_off = new_off;
+ }
+
+ return -EINVAL;
+@@ -71,7 +77,7 @@ static int get_build_id_32(const void *page_addr, unsigned char *build_id,
+ {
+ Elf32_Ehdr *ehdr = (Elf32_Ehdr *)page_addr;
+ Elf32_Phdr *phdr;
+- int i;
++ __u32 i, phnum;
+
+ /*
+ * FIXME
+@@ -80,18 +86,19 @@ static int get_build_id_32(const void *page_addr, unsigned char *build_id,
+ */
+ if (ehdr->e_phoff != sizeof(Elf32_Ehdr))
+ return -EINVAL;
++
++ phnum = READ_ONCE(ehdr->e_phnum);
+ /* only supports phdr that fits in one page */
+- if (ehdr->e_phnum >
+- (PAGE_SIZE - sizeof(Elf32_Ehdr)) / sizeof(Elf32_Phdr))
++ if (phnum > (PAGE_SIZE - sizeof(Elf32_Ehdr)) / sizeof(Elf32_Phdr))
+ return -EINVAL;
+
+ phdr = (Elf32_Phdr *)(page_addr + sizeof(Elf32_Ehdr));
+
+- for (i = 0; i < ehdr->e_phnum; ++i) {
++ for (i = 0; i < phnum; ++i) {
+ if (phdr[i].p_type == PT_NOTE &&
+ !parse_build_id(page_addr, build_id, size,
+- page_addr + phdr[i].p_offset,
+- phdr[i].p_filesz))
++ page_addr + READ_ONCE(phdr[i].p_offset),
++ READ_ONCE(phdr[i].p_filesz)))
+ return 0;
+ }
+ return -EINVAL;
+@@ -103,7 +110,7 @@ static int get_build_id_64(const void *page_addr, unsigned char *build_id,
+ {
+ Elf64_Ehdr *ehdr = (Elf64_Ehdr *)page_addr;
+ Elf64_Phdr *phdr;
+- int i;
++ __u32 i, phnum;
+
+ /*
+ * FIXME
+@@ -112,18 +119,19 @@ static int get_build_id_64(const void *page_addr, unsigned char *build_id,
+ */
+ if (ehdr->e_phoff != sizeof(Elf64_Ehdr))
+ return -EINVAL;
++
++ phnum = READ_ONCE(ehdr->e_phnum);
+ /* only supports phdr that fits in one page */
+- if (ehdr->e_phnum >
+- (PAGE_SIZE - sizeof(Elf64_Ehdr)) / sizeof(Elf64_Phdr))
++ if (phnum > (PAGE_SIZE - sizeof(Elf64_Ehdr)) / sizeof(Elf64_Phdr))
+ return -EINVAL;
+
+ phdr = (Elf64_Phdr *)(page_addr + sizeof(Elf64_Ehdr));
+
+- for (i = 0; i < ehdr->e_phnum; ++i) {
++ for (i = 0; i < phnum; ++i) {
+ if (phdr[i].p_type == PT_NOTE &&
+ !parse_build_id(page_addr, build_id, size,
+- page_addr + phdr[i].p_offset,
+- phdr[i].p_filesz))
++ page_addr + READ_ONCE(phdr[i].p_offset),
++ READ_ONCE(phdr[i].p_filesz)))
+ return 0;
+ }
+ return -EINVAL;
+@@ -152,6 +160,10 @@ int build_id_parse(struct vm_area_struct *vma, unsigned char *build_id,
+ page = find_get_page(vma->vm_file->f_mapping, 0);
+ if (!page)
+ return -EFAULT; /* page not mapped */
++ if (!PageUptodate(page)) {
++ put_page(page);
++ return -EFAULT;
++ }
+
+ ret = -EINVAL;
+ page_addr = kmap_atomic(page);
+--
+2.43.0
+
--- /dev/null
+From c80266cab93c6cdb05bb497fa87aac66010312e4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Dec 2023 18:29:46 +0530
+Subject: media: i2c: imx335: Enable regulator supplies
+
+From: Kieran Bingham <kieran.bingham@ideasonboard.com>
+
+[ Upstream commit fea91ee73b7cd19f08017221923d789f984abc54 ]
+
+Provide support for enabling and disabling regulator supplies to control
+power to the camera sensor.
+
+While updating the power on function, document that a sleep is
+represented as 'T4' in the datasheet power on sequence.
+
+Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Stable-dep-of: 99d30e2fdea4 ("media: imx335: Fix reset-gpio handling")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/i2c/imx335.c | 36 ++++++++++++++++++++++++++++++++++--
+ 1 file changed, 34 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/i2c/imx335.c b/drivers/media/i2c/imx335.c
+index 780eb68b1894c..b5f912e0ee08e 100644
+--- a/drivers/media/i2c/imx335.c
++++ b/drivers/media/i2c/imx335.c
+@@ -75,6 +75,12 @@ struct imx335_reg_list {
+ const struct imx335_reg *regs;
+ };
+
++static const char * const imx335_supply_name[] = {
++ "avdd", /* Analog (2.9V) supply */
++ "ovdd", /* Digital I/O (1.8V) supply */
++ "dvdd", /* Digital Core (1.2V) supply */
++};
++
+ /**
+ * struct imx335_mode - imx335 sensor mode structure
+ * @width: Frame width
+@@ -108,6 +114,7 @@ struct imx335_mode {
+ * @sd: V4L2 sub-device
+ * @pad: Media pad. Only one pad supported
+ * @reset_gpio: Sensor reset gpio
++ * @supplies: Regulator supplies to handle power control
+ * @inclk: Sensor input clock
+ * @ctrl_handler: V4L2 control handler
+ * @link_freq_ctrl: Pointer to link frequency control
+@@ -127,6 +134,8 @@ struct imx335 {
+ struct v4l2_subdev sd;
+ struct media_pad pad;
+ struct gpio_desc *reset_gpio;
++ struct regulator_bulk_data supplies[ARRAY_SIZE(imx335_supply_name)];
++
+ struct clk *inclk;
+ struct v4l2_ctrl_handler ctrl_handler;
+ struct v4l2_ctrl *link_freq_ctrl;
+@@ -790,6 +799,17 @@ static int imx335_parse_hw_config(struct imx335 *imx335)
+ return PTR_ERR(imx335->reset_gpio);
+ }
+
++ for (i = 0; i < ARRAY_SIZE(imx335_supply_name); i++)
++ imx335->supplies[i].supply = imx335_supply_name[i];
++
++ ret = devm_regulator_bulk_get(imx335->dev,
++ ARRAY_SIZE(imx335_supply_name),
++ imx335->supplies);
++ if (ret) {
++ dev_err(imx335->dev, "Failed to get regulators\n");
++ return ret;
++ }
++
+ /* Get sensor input clock */
+ imx335->inclk = devm_clk_get(imx335->dev, NULL);
+ if (IS_ERR(imx335->inclk)) {
+@@ -868,6 +888,17 @@ static int imx335_power_on(struct device *dev)
+ struct imx335 *imx335 = to_imx335(sd);
+ int ret;
+
++ ret = regulator_bulk_enable(ARRAY_SIZE(imx335_supply_name),
++ imx335->supplies);
++ if (ret) {
++ dev_err(dev, "%s: failed to enable regulators\n",
++ __func__);
++ return ret;
++ }
++
++ usleep_range(500, 550); /* Tlow */
++
++ /* Set XCLR */
+ gpiod_set_value_cansleep(imx335->reset_gpio, 1);
+
+ ret = clk_prepare_enable(imx335->inclk);
+@@ -876,12 +907,13 @@ static int imx335_power_on(struct device *dev)
+ goto error_reset;
+ }
+
+- usleep_range(20, 22);
++ usleep_range(20, 22); /* T4 */
+
+ return 0;
+
+ error_reset:
+ gpiod_set_value_cansleep(imx335->reset_gpio, 0);
++ regulator_bulk_disable(ARRAY_SIZE(imx335_supply_name), imx335->supplies);
+
+ return ret;
+ }
+@@ -898,8 +930,8 @@ static int imx335_power_off(struct device *dev)
+ struct imx335 *imx335 = to_imx335(sd);
+
+ gpiod_set_value_cansleep(imx335->reset_gpio, 0);
+-
+ clk_disable_unprepare(imx335->inclk);
++ regulator_bulk_disable(ARRAY_SIZE(imx335_supply_name), imx335->supplies);
+
+ return 0;
+ }
+--
+2.43.0
+
--- /dev/null
+From bd9ebc3720728f9d12ccfb0de899786c1113e62c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Aug 2024 11:41:52 +0530
+Subject: media: imx335: Fix reset-gpio handling
+
+From: Umang Jain <umang.jain@ideasonboard.com>
+
+[ Upstream commit 99d30e2fdea4086be4e66e2deb10de854b547ab8 ]
+
+Rectify the logical value of reset-gpio so that it is set to
+0 (disabled) during power-on and to 1 (enabled) during power-off.
+
+Set the reset-gpio to GPIO_OUT_HIGH at initialization time to make
+sure it starts off in reset. Also drop the "Set XCLR" comment which
+is not-so-informative.
+
+The existing usage of imx335 had reset-gpios polarity inverted
+(GPIO_ACTIVE_HIGH) in their device-tree sources. With this patch
+included, those DTS will not be able to stream imx335 anymore. The
+reset-gpio polarity will need to be rectified in the device-tree
+sources as shown in [1] example, in order to get imx335 functional
+again (as it remains in reset prior to this fix).
+
+Cc: stable@vger.kernel.org
+Fixes: 45d19b5fb9ae ("media: i2c: Add imx335 camera sensor driver")
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Link: https://lore.kernel.org/linux-media/20240729110437.199428-1-umang.jain@ideasonboard.com/
+Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/i2c/imx335.c | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/media/i2c/imx335.c b/drivers/media/i2c/imx335.c
+index b5f912e0ee08e..2692547791f91 100644
+--- a/drivers/media/i2c/imx335.c
++++ b/drivers/media/i2c/imx335.c
+@@ -792,7 +792,7 @@ static int imx335_parse_hw_config(struct imx335 *imx335)
+
+ /* Request optional reset pin */
+ imx335->reset_gpio = devm_gpiod_get_optional(imx335->dev, "reset",
+- GPIOD_OUT_LOW);
++ GPIOD_OUT_HIGH);
+ if (IS_ERR(imx335->reset_gpio)) {
+ dev_err(imx335->dev, "failed to get reset gpio %ld",
+ PTR_ERR(imx335->reset_gpio));
+@@ -898,8 +898,7 @@ static int imx335_power_on(struct device *dev)
+
+ usleep_range(500, 550); /* Tlow */
+
+- /* Set XCLR */
+- gpiod_set_value_cansleep(imx335->reset_gpio, 1);
++ gpiod_set_value_cansleep(imx335->reset_gpio, 0);
+
+ ret = clk_prepare_enable(imx335->inclk);
+ if (ret) {
+@@ -912,7 +911,7 @@ static int imx335_power_on(struct device *dev)
+ return 0;
+
+ error_reset:
+- gpiod_set_value_cansleep(imx335->reset_gpio, 0);
++ gpiod_set_value_cansleep(imx335->reset_gpio, 1);
+ regulator_bulk_disable(ARRAY_SIZE(imx335_supply_name), imx335->supplies);
+
+ return ret;
+@@ -929,7 +928,7 @@ static int imx335_power_off(struct device *dev)
+ struct v4l2_subdev *sd = dev_get_drvdata(dev);
+ struct imx335 *imx335 = to_imx335(sd);
+
+- gpiod_set_value_cansleep(imx335->reset_gpio, 0);
++ gpiod_set_value_cansleep(imx335->reset_gpio, 1);
+ clk_disable_unprepare(imx335->inclk);
+ regulator_bulk_disable(ARRAY_SIZE(imx335_supply_name), imx335->supplies);
+
+--
+2.43.0
+
--- /dev/null
+From ecf55423c34d66a8c7ce4d35bded5157aaecb0ec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Sep 2024 23:04:46 +0200
+Subject: r8169: add tally counter fields added with RTL8125
+
+From: Heiner Kallweit <hkallweit1@gmail.com>
+
+[ Upstream commit ced8e8b8f40accfcce4a2bbd8b150aa76d5eff9a ]
+
+RTL8125 added fields to the tally counter, what may result in the chip
+dma'ing these new fields to unallocated memory. Therefore make sure
+that the allocated memory area is big enough to hold all of the
+tally counter values, even if we use only parts of it.
+
+Fixes: f1bce4ad2f1c ("r8169: add support for RTL8125")
+Cc: stable@vger.kernel.org
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/741d26a9-2b2b-485d-91d9-ecb302e345b5@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 27 +++++++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c
+index f6e0424bf83d5..7ce11c9529c58 100644
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -576,6 +576,33 @@ struct rtl8169_counters {
+ __le32 rx_multicast;
+ __le16 tx_aborted;
+ __le16 tx_underrun;
++ /* new since RTL8125 */
++ __le64 tx_octets;
++ __le64 rx_octets;
++ __le64 rx_multicast64;
++ __le64 tx_unicast64;
++ __le64 tx_broadcast64;
++ __le64 tx_multicast64;
++ __le32 tx_pause_on;
++ __le32 tx_pause_off;
++ __le32 tx_pause_all;
++ __le32 tx_deferred;
++ __le32 tx_late_collision;
++ __le32 tx_all_collision;
++ __le32 tx_aborted32;
++ __le32 align_errors32;
++ __le32 rx_frame_too_long;
++ __le32 rx_runt;
++ __le32 rx_pause_on;
++ __le32 rx_pause_off;
++ __le32 rx_pause_all;
++ __le32 rx_unknown_opcode;
++ __le32 rx_mac_error;
++ __le32 tx_underrun32;
++ __le32 rx_mac_missed;
++ __le32 rx_tcam_dropped;
++ __le32 tdu;
++ __le32 rdu;
+ };
+
+ struct rtl8169_tc_offsets {
+--
+2.43.0
+
--- /dev/null
+From 963353a331591e7cafd59879c0b692edbf7c24bc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Sep 2024 15:00:21 +0100
+Subject: r8169: Fix spelling mistake: "tx_underun" -> "tx_underrun"
+
+From: Colin Ian King <colin.i.king@gmail.com>
+
+[ Upstream commit 8df9439389a44fb2cc4ef695e08d6a8870b1616c ]
+
+There is a spelling mistake in the struct field tx_underun, rename
+it to tx_underrun.
+
+Signed-off-by: Colin Ian King <colin.i.king@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Reviewed-by: Heiner Kallweit <hkallweit1@gmail.com>
+Link: https://patch.msgid.link/20240909140021.64884-1-colin.i.king@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: ced8e8b8f40a ("r8169: add tally counter fields added with RTL8125")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c
+index 49a3cd4ce89c2..f6e0424bf83d5 100644
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -575,7 +575,7 @@ struct rtl8169_counters {
+ __le64 rx_broadcast;
+ __le32 rx_multicast;
+ __le16 tx_aborted;
+- __le16 tx_underun;
++ __le16 tx_underrun;
+ };
+
+ struct rtl8169_tc_offsets {
+@@ -1666,7 +1666,7 @@ static void rtl8169_get_ethtool_stats(struct net_device *dev,
+ data[9] = le64_to_cpu(counters->rx_broadcast);
+ data[10] = le32_to_cpu(counters->rx_multicast);
+ data[11] = le16_to_cpu(counters->tx_aborted);
+- data[12] = le16_to_cpu(counters->tx_underun);
++ data[12] = le16_to_cpu(counters->tx_underrun);
+ }
+
+ static void rtl8169_get_strings(struct net_device *dev, u32 stringset, u8 *data)
+--
+2.43.0
+
close_range-fix-the-logics-in-descriptor-table-trimming.patch
drm-sched-add-locking-to-drm_sched_entity_modify_sched.patch
drm-amd-display-fix-system-hang-while-resume-with-tbt-monitor.patch
+kconfig-qconf-fix-buffer-overflow-in-debug-links.patch
+device-property-add-fwnode_iomap.patch
+device-property-add-fwnode_irq_get_byname.patch
+i2c-smbus-use-device_-functions-instead-of-of_.patch
+i2c-create-debugfs-entry-per-adapter.patch
+i2c-core-lock-address-during-client-device-instantia.patch
+i2c-xiic-use-devm_clk_get_enabled.patch
+i2c-xiic-fix-pm_runtime_set_suspended-with-runtime-p.patch
+spi-bcm63xx-fix-missing-pm_runtime_disable.patch
+ext4-properly-sync-file-size-update-after-o_sync-dir.patch
+ext4-dax-fix-overflowing-extents-beyond-inode-size-w.patch
+arm64-add-cortex-715-cpu-part-definition.patch
+arm64-cputype-add-neoverse-n3-definitions.patch
+arm64-errata-expand-speculative-ssbs-workaround-once.patch
+uprobes-fix-kernel-info-leak-via-uprobes-vma.patch
+drm-amd-display-allow-backlight-to-go-below-amdgpu_d.patch
+build-id-require-program-headers-to-be-right-after-e.patch
+lib-buildid-harden-build-id-parsing-logic.patch
+drm-rockchip-define-gamma-registers-for-rk3399.patch
+drm-rockchip-support-gamma-control-on-rk3399.patch
+drm-rockchip-vop-clear-dma-stop-bit-on-rk3066.patch
+clk-imx6ul-fix-enet1-gate-configuration.patch
+clk-imx6ul-add-ethernet-refclock-mux-support.patch
+clk-imx6ul-retain-early-uart-clocks-during-kernel-in.patch
+clk-imx6ul-fix-clock-parent-for-imx6ul_clk_enetx_ref.patch
+media-i2c-imx335-enable-regulator-supplies.patch
+media-imx335-fix-reset-gpio-handling.patch
+dt-bindings-clock-qcom-add-missing-ufs-qref-clocks.patch
+dt-bindings-clock-qcom-add-gpll9-support-on-gcc-sc81.patch
+r8169-fix-spelling-mistake-tx_underun-tx_underrun.patch
+r8169-add-tally-counter-fields-added-with-rtl8125.patch
+clk-qcom-gcc-sc8180x-add-gpll9-support.patch
+acpi-battery-simplify-battery-hook-locking.patch
+acpi-battery-fix-possible-crash-when-unregistering-a.patch
--- /dev/null
+From 8c2a559621c7850f994caba4e96876057cda96d8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Aug 2024 20:33:49 +0800
+Subject: spi: bcm63xx: Fix missing pm_runtime_disable()
+
+From: Jinjie Ruan <ruanjinjie@huawei.com>
+
+[ Upstream commit 265697288ec2160ca84707565d6641d46f69b0ff ]
+
+The pm_runtime_disable() is missing in the remove function, fix it
+by using devm_pm_runtime_enable(), so the pm_runtime_disable() in
+the probe error path can also be removed.
+
+Fixes: 2d13f2ff6073 ("spi: bcm63xx-spi: fix pm_runtime")
+Cc: stable@vger.kernel.org # v5.13+
+Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
+Suggested-by: Jonas Gorski <jonas.gorski@gmail.com>
+Link: https://patch.msgid.link/20240819123349.4020472-3-ruanjinjie@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-bcm63xx.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c
+index 51296615536a9..695ac74571286 100644
+--- a/drivers/spi/spi-bcm63xx.c
++++ b/drivers/spi/spi-bcm63xx.c
+@@ -595,13 +595,15 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)
+
+ bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS);
+
+- pm_runtime_enable(&pdev->dev);
++ ret = devm_pm_runtime_enable(&pdev->dev);
++ if (ret)
++ goto out_clk_disable;
+
+ /* register and we are done */
+ ret = devm_spi_register_master(dev, master);
+ if (ret) {
+ dev_err(dev, "spi register failed\n");
+- goto out_pm_disable;
++ goto out_clk_disable;
+ }
+
+ dev_info(dev, "at %pr (irq %d, FIFOs size %d)\n",
+@@ -609,8 +611,6 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)
+
+ return 0;
+
+-out_pm_disable:
+- pm_runtime_disable(&pdev->dev);
+ out_clk_disable:
+ clk_disable_unprepare(clk);
+ out_err:
+--
+2.43.0
+
--- /dev/null
+From f6ee51c21cf350691229716553fa9d26be19e0d8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Oct 2024 19:46:01 +0200
+Subject: uprobes: fix kernel info leak via "[uprobes]" vma
+
+From: Oleg Nesterov <oleg@redhat.com>
+
+commit 34820304cc2cd1804ee1f8f3504ec77813d29c8e upstream.
+
+xol_add_vma() maps the uninitialized page allocated by __create_xol_area()
+into userspace. On some architectures (x86) this memory is readable even
+without VM_READ, VM_EXEC results in the same pgprot_t as VM_EXEC|VM_READ,
+although this doesn't really matter, debugger can read this memory anyway.
+
+Link: https://lore.kernel.org/all/20240929162047.GA12611@redhat.com/
+
+Reported-by: Will Deacon <will@kernel.org>
+Fixes: d4b3b6384f98 ("uprobes/core: Allocate XOL slots for uprobes use")
+Cc: stable@vger.kernel.org
+Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Signed-off-by: Oleg Nesterov <oleg@redhat.com>
+Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/events/uprobes.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
+index aa9134cd5d00c..b37a6bde8a915 100644
+--- a/kernel/events/uprobes.c
++++ b/kernel/events/uprobes.c
+@@ -1495,7 +1495,7 @@ static struct xol_area *__create_xol_area(unsigned long vaddr)
+
+ area->xol_mapping.name = "[uprobes]";
+ area->xol_mapping.pages = area->pages;
+- area->pages[0] = alloc_page(GFP_HIGHUSER);
++ area->pages[0] = alloc_page(GFP_HIGHUSER | __GFP_ZERO);
+ if (!area->pages[0])
+ goto free_bitmap;
+ area->pages[1] = NULL;
+--
+2.43.0
+