--- /dev/null
+From 93ed5cf563a402e786e8eeedc6f4ad5a7c4ef7af Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Mar 2022 13:38:40 -0700
+Subject: RISC-V: Correctly print supported extensions
+
+From: Tsukasa OI <research_trasio@irq.a4lg.com>
+
+[ Upstream commit 58004f266918912771ee71f46bfb92bf64ab9108 ]
+
+This commit replaces BITS_PER_LONG with number of alphabet letters.
+
+Current ISA pretty-printing code expects extension 'a' (bit 0) through
+'z' (bit 25). Although bit 26 and higher is not currently used (thus never
+cause an issue in practice), it will be an annoying problem if we start to
+use those in the future.
+
+This commit disables printing high bits for now.
+
+Reviewed-by: Anup Patel <anup@brainfault.org>
+Tested-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Tsukasa OI <research_trasio@irq.a4lg.com>
+Signed-off-by: Atish Patra <atishp@rivosinc.com>
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Stable-dep-of: d2721bb165b3 ("RISC-V: Don't print details of CPUs disabled in DT")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/cpufeature.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
+index ac202f44a6702..ece126dad3547 100644
+--- a/arch/riscv/kernel/cpufeature.c
++++ b/arch/riscv/kernel/cpufeature.c
+@@ -13,6 +13,8 @@
+ #include <asm/smp.h>
+ #include <asm/switch_to.h>
+
++#define NUM_ALPHA_EXTS ('z' - 'a' + 1)
++
+ unsigned long elf_hwcap __read_mostly;
+
+ /* Host ISA bitmap */
+@@ -63,7 +65,7 @@ void riscv_fill_hwcap(void)
+ {
+ struct device_node *node;
+ const char *isa;
+- char print_str[BITS_PER_LONG + 1];
++ char print_str[NUM_ALPHA_EXTS + 1];
+ size_t i, j, isa_len;
+ static unsigned long isa2hwcap[256] = {0};
+
+@@ -133,13 +135,13 @@ void riscv_fill_hwcap(void)
+ }
+
+ memset(print_str, 0, sizeof(print_str));
+- for (i = 0, j = 0; i < BITS_PER_LONG; i++)
++ for (i = 0, j = 0; i < NUM_ALPHA_EXTS; i++)
+ if (riscv_isa[0] & BIT_MASK(i))
+ print_str[j++] = (char)('a' + i);
+ pr_info("riscv: ISA extensions %s\n", print_str);
+
+ memset(print_str, 0, sizeof(print_str));
+- for (i = 0, j = 0; i < BITS_PER_LONG; i++)
++ for (i = 0, j = 0; i < NUM_ALPHA_EXTS; i++)
+ if (elf_hwcap & BIT_MASK(i))
+ print_str[j++] = (char)('a' + i);
+ pr_info("riscv: ELF capabilities %s\n", print_str);
+--
+2.51.0
+
--- /dev/null
+From b18c59a5af52f5e6fec761e22d9f630db10a7786 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Oct 2025 22:00:09 +0530
+Subject: RISC-V: Don't print details of CPUs disabled in DT
+
+From: Anup Patel <apatel@ventanamicro.com>
+
+[ Upstream commit d2721bb165b3ee00dd23525885381af07fec852a ]
+
+Early boot stages may disable CPU DT nodes for unavailable
+CPUs based on SKU, pinstraps, eFuse, etc. Currently, the
+riscv_early_of_processor_hartid() prints details of a CPU
+if it is disabled in DT which has no value and gives a
+false impression to the users that there some issue with
+the CPU.
+
+Fixes: e3d794d555cd ("riscv: treat cpu devicetree nodes without status as enabled")
+Signed-off-by: Anup Patel <apatel@ventanamicro.com>
+Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Link: https://lore.kernel.org/r/20251014163009.182381-1-apatel@ventanamicro.com
+Signed-off-by: Paul Walmsley <pjw@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/cpu.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c
+index 11d6d6cc61d51..39013aedbe0ab 100644
+--- a/arch/riscv/kernel/cpu.c
++++ b/arch/riscv/kernel/cpu.c
+@@ -27,10 +27,8 @@ int riscv_of_processor_hartid(struct device_node *node, unsigned long *hart)
+ return -ENODEV;
+ }
+
+- if (!of_device_is_available(node)) {
+- pr_info("CPU with hartid=%lu is not available\n", *hart);
++ if (!of_device_is_available(node))
+ return -ENODEV;
+- }
+
+ if (of_property_read_string(node, "riscv,isa", &isa)) {
+ pr_warn("CPU with hartid=%lu has no \"riscv,isa\" property\n", *hart);
+--
+2.51.0
+
--- /dev/null
+From 37334339e71c5a10f92eacdeead0a897538672ec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Mar 2022 13:38:41 -0700
+Subject: RISC-V: Minimal parser for "riscv, isa" strings
+
+From: Tsukasa OI <research_trasio@irq.a4lg.com>
+
+[ Upstream commit 2a31c54be097c74344b4fab20ea6104012d2cb8b ]
+
+Current hart ISA ("riscv,isa") parser don't correctly parse:
+
+1. Multi-letter extensions
+2. Version numbers
+
+All ISA extensions ratified recently has multi-letter extensions
+(except 'H'). The current "riscv,isa" parser that is easily confused
+by multi-letter extensions and "p" in version numbers can be a huge
+problem for adding new extensions through the device tree.
+
+Leaving it would create incompatible hacks and would make "riscv,isa"
+value unreliable.
+
+This commit implements minimal parser for "riscv,isa" strings. With this,
+we can safely ignore multi-letter extensions and version numbers.
+
+[Improved commit text and fixed a bug around 's' in base extension]
+Signed-off-by: Atish Patra <atishp@rivosinc.com>
+[Fixed workaround for QEMU]
+Signed-off-by: Tsukasa OI <research_trasio@irq.a4lg.com>
+Tested-by: Heiko Stuebner <heiko@sntech.de>
+Reviewed-by: Anup Patel <anup@brainfault.org>
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Stable-dep-of: d2721bb165b3 ("RISC-V: Don't print details of CPUs disabled in DT")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/cpufeature.c | 72 ++++++++++++++++++++++++++++------
+ 1 file changed, 61 insertions(+), 11 deletions(-)
+
+diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
+index ece126dad3547..54d230bdaf976 100644
+--- a/arch/riscv/kernel/cpufeature.c
++++ b/arch/riscv/kernel/cpufeature.c
+@@ -7,6 +7,7 @@
+ */
+
+ #include <linux/bitmap.h>
++#include <linux/ctype.h>
+ #include <linux/of.h>
+ #include <asm/processor.h>
+ #include <asm/hwcap.h>
+@@ -66,7 +67,7 @@ void riscv_fill_hwcap(void)
+ struct device_node *node;
+ const char *isa;
+ char print_str[NUM_ALPHA_EXTS + 1];
+- size_t i, j, isa_len;
++ int i, j;
+ static unsigned long isa2hwcap[256] = {0};
+
+ isa2hwcap['i'] = isa2hwcap['I'] = COMPAT_HWCAP_ISA_I;
+@@ -92,23 +93,72 @@ void riscv_fill_hwcap(void)
+ continue;
+ }
+
+- i = 0;
+- isa_len = strlen(isa);
+ #if IS_ENABLED(CONFIG_32BIT)
+ if (!strncmp(isa, "rv32", 4))
+- i += 4;
++ isa += 4;
+ #elif IS_ENABLED(CONFIG_64BIT)
+ if (!strncmp(isa, "rv64", 4))
+- i += 4;
++ isa += 4;
+ #endif
+- for (; i < isa_len; ++i) {
+- this_hwcap |= isa2hwcap[(unsigned char)(isa[i])];
++ for (; *isa; ++isa) {
++ const char *ext = isa++;
++ const char *ext_end = isa;
++ bool ext_long = false, ext_err = false;
++
++ switch (*ext) {
++ case 's':
++ /**
++ * Workaround for invalid single-letter 's' & 'u'(QEMU).
++ * No need to set the bit in riscv_isa as 's' & 'u' are
++ * not valid ISA extensions. It works until multi-letter
++ * extension starting with "Su" appears.
++ */
++ if (ext[-1] != '_' && ext[1] == 'u') {
++ ++isa;
++ ext_err = true;
++ break;
++ }
++ fallthrough;
++ case 'x':
++ case 'z':
++ ext_long = true;
++ /* Multi-letter extension must be delimited */
++ for (; *isa && *isa != '_'; ++isa)
++ if (!islower(*isa) && !isdigit(*isa))
++ ext_err = true;
++ break;
++ default:
++ if (unlikely(!islower(*ext))) {
++ ext_err = true;
++ break;
++ }
++ /* Find next extension */
++ if (!isdigit(*isa))
++ break;
++ /* Skip the minor version */
++ while (isdigit(*++isa))
++ ;
++ if (*isa != 'p')
++ break;
++ if (!isdigit(*++isa)) {
++ --isa;
++ break;
++ }
++ /* Skip the major version */
++ while (isdigit(*++isa))
++ ;
++ break;
++ }
++ if (*isa != '_')
++ --isa;
+ /*
+- * TODO: X, Y and Z extension parsing for Host ISA
+- * bitmap will be added in-future.
++ * TODO: Full version-aware handling including
++ * multi-letter extensions will be added in-future.
+ */
+- if ('a' <= isa[i] && isa[i] < 'x')
+- this_isa |= (1UL << (isa[i] - 'a'));
++ if (ext_err || ext_long)
++ continue;
++ this_hwcap |= isa2hwcap[(unsigned char)(*ext)];
++ this_isa |= (1UL << (*ext - 'a'));
+ }
+
+ /*
+--
+2.51.0
+
--- /dev/null
+From 76b3881905903f8e8a1af4fb33bfab80b1998b8e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 27 May 2022 10:47:42 +0530
+Subject: riscv: cpu: Add 64bit hartid support on RV64
+
+From: Sunil V L <sunilvl@ventanamicro.com>
+
+[ Upstream commit ad635e723e17379b192a5ba9c182e3eedfc24d16 ]
+
+The hartid can be a 64bit value on RV64 platforms.
+
+Add support for 64bit hartid in riscv_of_processor_hartid() and
+update its callers.
+
+Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
+Reviewed-by: Atish Patra <atishp@rivosinc.com>
+Link: https://lore.kernel.org/r/20220527051743.2829940-5-sunilvl@ventanamicro.com
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Stable-dep-of: d2721bb165b3 ("RISC-V: Don't print details of CPUs disabled in DT")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/include/asm/processor.h | 4 ++--
+ arch/riscv/kernel/cpu.c | 26 +++++++++++++++-----------
+ arch/riscv/kernel/cpufeature.c | 6 ++++--
+ arch/riscv/kernel/smpboot.c | 9 +++++----
+ drivers/clocksource/timer-riscv.c | 15 ++++++++-------
+ drivers/irqchip/irq-riscv-intc.c | 7 ++++---
+ drivers/irqchip/irq-sifive-plic.c | 7 ++++---
+ 7 files changed, 42 insertions(+), 32 deletions(-)
+
+diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h
+index bdddcd5c1b71d..b5295806643b1 100644
+--- a/arch/riscv/include/asm/processor.h
++++ b/arch/riscv/include/asm/processor.h
+@@ -66,8 +66,8 @@ static inline void wait_for_interrupt(void)
+ }
+
+ struct device_node;
+-int riscv_of_processor_hartid(struct device_node *node);
+-int riscv_of_parent_hartid(struct device_node *node);
++int riscv_of_processor_hartid(struct device_node *node, unsigned long *hartid);
++int riscv_of_parent_hartid(struct device_node *node, unsigned long *hartid);
+
+ extern void riscv_fill_hwcap(void);
+
+diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c
+index f13b2c9ea912d..11d6d6cc61d51 100644
+--- a/arch/riscv/kernel/cpu.c
++++ b/arch/riscv/kernel/cpu.c
+@@ -12,37 +12,36 @@
+ * Returns the hart ID of the given device tree node, or -ENODEV if the node
+ * isn't an enabled and valid RISC-V hart node.
+ */
+-int riscv_of_processor_hartid(struct device_node *node)
++int riscv_of_processor_hartid(struct device_node *node, unsigned long *hart)
+ {
+ const char *isa;
+- u32 hart;
+
+ if (!of_device_is_compatible(node, "riscv")) {
+ pr_warn("Found incompatible CPU\n");
+ return -ENODEV;
+ }
+
+- hart = of_get_cpu_hwid(node, 0);
+- if (hart == ~0U) {
++ *hart = (unsigned long) of_get_cpu_hwid(node, 0);
++ if (*hart == ~0UL) {
+ pr_warn("Found CPU without hart ID\n");
+ return -ENODEV;
+ }
+
+ if (!of_device_is_available(node)) {
+- pr_info("CPU with hartid=%d is not available\n", hart);
++ pr_info("CPU with hartid=%lu is not available\n", *hart);
+ return -ENODEV;
+ }
+
+ if (of_property_read_string(node, "riscv,isa", &isa)) {
+- pr_warn("CPU with hartid=%d has no \"riscv,isa\" property\n", hart);
++ pr_warn("CPU with hartid=%lu has no \"riscv,isa\" property\n", *hart);
+ return -ENODEV;
+ }
+ if (isa[0] != 'r' || isa[1] != 'v') {
+- pr_warn("CPU with hartid=%d has an invalid ISA of \"%s\"\n", hart, isa);
++ pr_warn("CPU with hartid=%lu has an invalid ISA of \"%s\"\n", *hart, isa);
+ return -ENODEV;
+ }
+
+- return hart;
++ return 0;
+ }
+
+ /*
+@@ -51,11 +50,16 @@ int riscv_of_processor_hartid(struct device_node *node)
+ * To achieve this, we walk up the DT tree until we find an active
+ * RISC-V core (HART) node and extract the cpuid from it.
+ */
+-int riscv_of_parent_hartid(struct device_node *node)
++int riscv_of_parent_hartid(struct device_node *node, unsigned long *hartid)
+ {
++ int rc;
++
+ for (; node; node = node->parent) {
+- if (of_device_is_compatible(node, "riscv"))
+- return riscv_of_processor_hartid(node);
++ if (of_device_is_compatible(node, "riscv")) {
++ rc = riscv_of_processor_hartid(node, hartid);
++ if (!rc)
++ return 0;
++ }
+ }
+
+ return -1;
+diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
+index 54d230bdaf976..f46efff26e3dc 100644
+--- a/arch/riscv/kernel/cpufeature.c
++++ b/arch/riscv/kernel/cpufeature.c
+@@ -67,8 +67,9 @@ void riscv_fill_hwcap(void)
+ struct device_node *node;
+ const char *isa;
+ char print_str[NUM_ALPHA_EXTS + 1];
+- int i, j;
++ int i, j, rc;
+ static unsigned long isa2hwcap[256] = {0};
++ unsigned long hartid;
+
+ isa2hwcap['i'] = isa2hwcap['I'] = COMPAT_HWCAP_ISA_I;
+ isa2hwcap['m'] = isa2hwcap['M'] = COMPAT_HWCAP_ISA_M;
+@@ -85,7 +86,8 @@ void riscv_fill_hwcap(void)
+ unsigned long this_hwcap = 0;
+ unsigned long this_isa = 0;
+
+- if (riscv_of_processor_hartid(node) < 0)
++ rc = riscv_of_processor_hartid(node, &hartid);
++ if (rc < 0)
+ continue;
+
+ if (of_property_read_string(node, "riscv,isa", &isa)) {
+diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c
+index 0e0aed380e281..9df6413771923 100644
+--- a/arch/riscv/kernel/smpboot.c
++++ b/arch/riscv/kernel/smpboot.c
+@@ -67,15 +67,16 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
+ void __init setup_smp(void)
+ {
+ struct device_node *dn;
+- int hart;
++ unsigned long hart;
+ bool found_boot_cpu = false;
+ int cpuid = 1;
++ int rc;
+
+ cpu_set_ops(0);
+
+ for_each_of_cpu_node(dn) {
+- hart = riscv_of_processor_hartid(dn);
+- if (hart < 0)
++ rc = riscv_of_processor_hartid(dn, &hart);
++ if (rc < 0)
+ continue;
+
+ if (hart == cpuid_to_hartid_map(0)) {
+@@ -84,7 +85,7 @@ void __init setup_smp(void)
+ continue;
+ }
+ if (cpuid >= NR_CPUS) {
+- pr_warn("Invalid cpuid [%d] for hartid [%d]\n",
++ pr_warn("Invalid cpuid [%d] for hartid [%lu]\n",
+ cpuid, hart);
+ break;
+ }
+diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c
+index c51c5ed15aa75..4930d08c9374a 100644
+--- a/drivers/clocksource/timer-riscv.c
++++ b/drivers/clocksource/timer-riscv.c
+@@ -92,20 +92,21 @@ static irqreturn_t riscv_timer_interrupt(int irq, void *dev_id)
+
+ static int __init riscv_timer_init_dt(struct device_node *n)
+ {
+- int cpuid, hartid, error;
++ int cpuid, error;
++ unsigned long hartid;
+ struct device_node *child;
+ struct irq_domain *domain;
+
+- hartid = riscv_of_processor_hartid(n);
+- if (hartid < 0) {
+- pr_warn("Not valid hartid for node [%pOF] error = [%d]\n",
++ error = riscv_of_processor_hartid(n, &hartid);
++ if (error < 0) {
++ pr_warn("Not valid hartid for node [%pOF] error = [%lu]\n",
+ n, hartid);
+- return hartid;
++ return error;
+ }
+
+ cpuid = riscv_hartid_to_cpuid(hartid);
+ if (cpuid < 0) {
+- pr_warn("Invalid cpuid for hartid [%d]\n", hartid);
++ pr_warn("Invalid cpuid for hartid [%lu]\n", hartid);
+ return cpuid;
+ }
+
+@@ -131,7 +132,7 @@ static int __init riscv_timer_init_dt(struct device_node *n)
+ return -ENODEV;
+ }
+
+- pr_info("%s: Registering clocksource cpuid [%d] hartid [%d]\n",
++ pr_info("%s: Registering clocksource cpuid [%d] hartid [%lu]\n",
+ __func__, cpuid, hartid);
+ error = clocksource_register_hz(&riscv_clocksource, riscv_timebase);
+ if (error) {
+diff --git a/drivers/irqchip/irq-riscv-intc.c b/drivers/irqchip/irq-riscv-intc.c
+index 8017f6d32d52b..edbf90a7565f6 100644
+--- a/drivers/irqchip/irq-riscv-intc.c
++++ b/drivers/irqchip/irq-riscv-intc.c
+@@ -95,10 +95,11 @@ static const struct irq_domain_ops riscv_intc_domain_ops = {
+ static int __init riscv_intc_init(struct device_node *node,
+ struct device_node *parent)
+ {
+- int rc, hartid;
++ int rc;
++ unsigned long hartid;
+
+- hartid = riscv_of_parent_hartid(node);
+- if (hartid < 0) {
++ rc = riscv_of_parent_hartid(node, &hartid);
++ if (rc < 0) {
+ pr_warn("unable to find hart id for %pOF\n", node);
+ return 0;
+ }
+diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c
+index bd99ee0ae433d..5fdf0eae48f7d 100644
+--- a/drivers/irqchip/irq-sifive-plic.c
++++ b/drivers/irqchip/irq-sifive-plic.c
+@@ -315,7 +315,8 @@ static int __init plic_init(struct device_node *node,
+ for (i = 0; i < nr_contexts; i++) {
+ struct of_phandle_args parent;
+ irq_hw_number_t hwirq;
+- int cpu, hartid;
++ int cpu;
++ unsigned long hartid;
+
+ if (of_irq_parse_one(node, i, &parent)) {
+ pr_err("failed to parse parent for context %d.\n", i);
+@@ -329,8 +330,8 @@ static int __init plic_init(struct device_node *node,
+ if (parent.args[0] != RV_IRQ_EXT)
+ continue;
+
+- hartid = riscv_of_parent_hartid(parent.np);
+- if (hartid < 0) {
++ error = riscv_of_parent_hartid(parent.np, &hartid);
++ if (error < 0) {
+ pr_warn("failed to parse hart ID for context %d.\n", i);
+ continue;
+ }
+--
+2.51.0
+
--- /dev/null
+From b49cf4ec68dc8e5e449aa8e460f26ad74c390c6b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Oct 2021 11:43:28 -0500
+Subject: riscv: Use of_get_cpu_hwid()
+
+From: Rob Herring <robh@kernel.org>
+
+[ Upstream commit bd2259ee458e299ec14061da7faddcfb0d54d154 ]
+
+Replace open coded parsing of CPU nodes' 'reg' property with
+of_get_cpu_hwid().
+
+Cc: Paul Walmsley <paul.walmsley@sifive.com>
+Cc: Palmer Dabbelt <palmer@dabbelt.com>
+Cc: Albert Ou <aou@eecs.berkeley.edu>
+Cc: linux-riscv@lists.infradead.org
+Signed-off-by: Rob Herring <robh@kernel.org>
+Link: https://lore.kernel.org/r/20211006164332.1981454-9-robh@kernel.org
+Stable-dep-of: d2721bb165b3 ("RISC-V: Don't print details of CPUs disabled in DT")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/cpu.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c
+index 6d59e6906fddf..f13b2c9ea912d 100644
+--- a/arch/riscv/kernel/cpu.c
++++ b/arch/riscv/kernel/cpu.c
+@@ -22,7 +22,8 @@ int riscv_of_processor_hartid(struct device_node *node)
+ return -ENODEV;
+ }
+
+- if (of_property_read_u32(node, "reg", &hart)) {
++ hart = of_get_cpu_hwid(node, 0);
++ if (hart == ~0U) {
+ pr_warn("Found CPU without hart ID\n");
+ return -ENODEV;
+ }
+--
+2.51.0
+
dpaa2-eth-fix-the-pointer-passed-to-ptr_align-on-tx-.patch
arm64-mm-avoid-always-making-pte-dirty-in-pte_mkwrit.patch
sctp-avoid-null-dereference-when-chunk-data-buffer-i.patch
+riscv-use-of_get_cpu_hwid.patch
+risc-v-correctly-print-supported-extensions.patch
+risc-v-minimal-parser-for-riscv-isa-strings.patch
+riscv-cpu-add-64bit-hartid-support-on-rv64.patch
+risc-v-don-t-print-details-of-cpus-disabled-in-dt.patch
--- /dev/null
+From ddcb73be11eb65f25d9bffed15064862f48c79e0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Mar 2022 13:38:40 -0700
+Subject: RISC-V: Correctly print supported extensions
+
+From: Tsukasa OI <research_trasio@irq.a4lg.com>
+
+[ Upstream commit 58004f266918912771ee71f46bfb92bf64ab9108 ]
+
+This commit replaces BITS_PER_LONG with number of alphabet letters.
+
+Current ISA pretty-printing code expects extension 'a' (bit 0) through
+'z' (bit 25). Although bit 26 and higher is not currently used (thus never
+cause an issue in practice), it will be an annoying problem if we start to
+use those in the future.
+
+This commit disables printing high bits for now.
+
+Reviewed-by: Anup Patel <anup@brainfault.org>
+Tested-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Tsukasa OI <research_trasio@irq.a4lg.com>
+Signed-off-by: Atish Patra <atishp@rivosinc.com>
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Stable-dep-of: d2721bb165b3 ("RISC-V: Don't print details of CPUs disabled in DT")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/cpufeature.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
+index d959d207a40d6..dd3d57eb4eead 100644
+--- a/arch/riscv/kernel/cpufeature.c
++++ b/arch/riscv/kernel/cpufeature.c
+@@ -13,6 +13,8 @@
+ #include <asm/smp.h>
+ #include <asm/switch_to.h>
+
++#define NUM_ALPHA_EXTS ('z' - 'a' + 1)
++
+ unsigned long elf_hwcap __read_mostly;
+
+ /* Host ISA bitmap */
+@@ -63,7 +65,7 @@ void __init riscv_fill_hwcap(void)
+ {
+ struct device_node *node;
+ const char *isa;
+- char print_str[BITS_PER_LONG + 1];
++ char print_str[NUM_ALPHA_EXTS + 1];
+ size_t i, j, isa_len;
+ static unsigned long isa2hwcap[256] = {0};
+
+@@ -133,13 +135,13 @@ void __init riscv_fill_hwcap(void)
+ }
+
+ memset(print_str, 0, sizeof(print_str));
+- for (i = 0, j = 0; i < BITS_PER_LONG; i++)
++ for (i = 0, j = 0; i < NUM_ALPHA_EXTS; i++)
+ if (riscv_isa[0] & BIT_MASK(i))
+ print_str[j++] = (char)('a' + i);
+ pr_info("riscv: ISA extensions %s\n", print_str);
+
+ memset(print_str, 0, sizeof(print_str));
+- for (i = 0, j = 0; i < BITS_PER_LONG; i++)
++ for (i = 0, j = 0; i < NUM_ALPHA_EXTS; i++)
+ if (elf_hwcap & BIT_MASK(i))
+ print_str[j++] = (char)('a' + i);
+ pr_info("riscv: ELF capabilities %s\n", print_str);
+--
+2.51.0
+
--- /dev/null
+From 9618dd476d86fea6ef9c76c7106555e01910677d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Oct 2025 22:00:09 +0530
+Subject: RISC-V: Don't print details of CPUs disabled in DT
+
+From: Anup Patel <apatel@ventanamicro.com>
+
+[ Upstream commit d2721bb165b3ee00dd23525885381af07fec852a ]
+
+Early boot stages may disable CPU DT nodes for unavailable
+CPUs based on SKU, pinstraps, eFuse, etc. Currently, the
+riscv_early_of_processor_hartid() prints details of a CPU
+if it is disabled in DT which has no value and gives a
+false impression to the users that there some issue with
+the CPU.
+
+Fixes: e3d794d555cd ("riscv: treat cpu devicetree nodes without status as enabled")
+Signed-off-by: Anup Patel <apatel@ventanamicro.com>
+Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Link: https://lore.kernel.org/r/20251014163009.182381-1-apatel@ventanamicro.com
+Signed-off-by: Paul Walmsley <pjw@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/cpu.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c
+index 11d6d6cc61d51..39013aedbe0ab 100644
+--- a/arch/riscv/kernel/cpu.c
++++ b/arch/riscv/kernel/cpu.c
+@@ -27,10 +27,8 @@ int riscv_of_processor_hartid(struct device_node *node, unsigned long *hart)
+ return -ENODEV;
+ }
+
+- if (!of_device_is_available(node)) {
+- pr_info("CPU with hartid=%lu is not available\n", *hart);
++ if (!of_device_is_available(node))
+ return -ENODEV;
+- }
+
+ if (of_property_read_string(node, "riscv,isa", &isa)) {
+ pr_warn("CPU with hartid=%lu has no \"riscv,isa\" property\n", *hart);
+--
+2.51.0
+
--- /dev/null
+From 2908b9be2d473ce179ad478adc64fa0e1ee11007 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Mar 2022 13:38:41 -0700
+Subject: RISC-V: Minimal parser for "riscv, isa" strings
+
+From: Tsukasa OI <research_trasio@irq.a4lg.com>
+
+[ Upstream commit 2a31c54be097c74344b4fab20ea6104012d2cb8b ]
+
+Current hart ISA ("riscv,isa") parser don't correctly parse:
+
+1. Multi-letter extensions
+2. Version numbers
+
+All ISA extensions ratified recently has multi-letter extensions
+(except 'H'). The current "riscv,isa" parser that is easily confused
+by multi-letter extensions and "p" in version numbers can be a huge
+problem for adding new extensions through the device tree.
+
+Leaving it would create incompatible hacks and would make "riscv,isa"
+value unreliable.
+
+This commit implements minimal parser for "riscv,isa" strings. With this,
+we can safely ignore multi-letter extensions and version numbers.
+
+[Improved commit text and fixed a bug around 's' in base extension]
+Signed-off-by: Atish Patra <atishp@rivosinc.com>
+[Fixed workaround for QEMU]
+Signed-off-by: Tsukasa OI <research_trasio@irq.a4lg.com>
+Tested-by: Heiko Stuebner <heiko@sntech.de>
+Reviewed-by: Anup Patel <anup@brainfault.org>
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Stable-dep-of: d2721bb165b3 ("RISC-V: Don't print details of CPUs disabled in DT")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/cpufeature.c | 72 ++++++++++++++++++++++++++++------
+ 1 file changed, 61 insertions(+), 11 deletions(-)
+
+diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
+index dd3d57eb4eead..72c5f6ef56b5a 100644
+--- a/arch/riscv/kernel/cpufeature.c
++++ b/arch/riscv/kernel/cpufeature.c
+@@ -7,6 +7,7 @@
+ */
+
+ #include <linux/bitmap.h>
++#include <linux/ctype.h>
+ #include <linux/of.h>
+ #include <asm/processor.h>
+ #include <asm/hwcap.h>
+@@ -66,7 +67,7 @@ void __init riscv_fill_hwcap(void)
+ struct device_node *node;
+ const char *isa;
+ char print_str[NUM_ALPHA_EXTS + 1];
+- size_t i, j, isa_len;
++ int i, j;
+ static unsigned long isa2hwcap[256] = {0};
+
+ isa2hwcap['i'] = isa2hwcap['I'] = COMPAT_HWCAP_ISA_I;
+@@ -92,23 +93,72 @@ void __init riscv_fill_hwcap(void)
+ continue;
+ }
+
+- i = 0;
+- isa_len = strlen(isa);
+ #if IS_ENABLED(CONFIG_32BIT)
+ if (!strncmp(isa, "rv32", 4))
+- i += 4;
++ isa += 4;
+ #elif IS_ENABLED(CONFIG_64BIT)
+ if (!strncmp(isa, "rv64", 4))
+- i += 4;
++ isa += 4;
+ #endif
+- for (; i < isa_len; ++i) {
+- this_hwcap |= isa2hwcap[(unsigned char)(isa[i])];
++ for (; *isa; ++isa) {
++ const char *ext = isa++;
++ const char *ext_end = isa;
++ bool ext_long = false, ext_err = false;
++
++ switch (*ext) {
++ case 's':
++ /**
++ * Workaround for invalid single-letter 's' & 'u'(QEMU).
++ * No need to set the bit in riscv_isa as 's' & 'u' are
++ * not valid ISA extensions. It works until multi-letter
++ * extension starting with "Su" appears.
++ */
++ if (ext[-1] != '_' && ext[1] == 'u') {
++ ++isa;
++ ext_err = true;
++ break;
++ }
++ fallthrough;
++ case 'x':
++ case 'z':
++ ext_long = true;
++ /* Multi-letter extension must be delimited */
++ for (; *isa && *isa != '_'; ++isa)
++ if (!islower(*isa) && !isdigit(*isa))
++ ext_err = true;
++ break;
++ default:
++ if (unlikely(!islower(*ext))) {
++ ext_err = true;
++ break;
++ }
++ /* Find next extension */
++ if (!isdigit(*isa))
++ break;
++ /* Skip the minor version */
++ while (isdigit(*++isa))
++ ;
++ if (*isa != 'p')
++ break;
++ if (!isdigit(*++isa)) {
++ --isa;
++ break;
++ }
++ /* Skip the major version */
++ while (isdigit(*++isa))
++ ;
++ break;
++ }
++ if (*isa != '_')
++ --isa;
+ /*
+- * TODO: X, Y and Z extension parsing for Host ISA
+- * bitmap will be added in-future.
++ * TODO: Full version-aware handling including
++ * multi-letter extensions will be added in-future.
+ */
+- if ('a' <= isa[i] && isa[i] < 'x')
+- this_isa |= (1UL << (isa[i] - 'a'));
++ if (ext_err || ext_long)
++ continue;
++ this_hwcap |= isa2hwcap[(unsigned char)(*ext)];
++ this_isa |= (1UL << (*ext - 'a'));
+ }
+
+ /*
+--
+2.51.0
+
--- /dev/null
+From 5d6448e7ba77a1095d44c6dddc519f41301ff78a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 27 May 2022 10:47:42 +0530
+Subject: riscv: cpu: Add 64bit hartid support on RV64
+
+From: Sunil V L <sunilvl@ventanamicro.com>
+
+[ Upstream commit ad635e723e17379b192a5ba9c182e3eedfc24d16 ]
+
+The hartid can be a 64bit value on RV64 platforms.
+
+Add support for 64bit hartid in riscv_of_processor_hartid() and
+update its callers.
+
+Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
+Reviewed-by: Atish Patra <atishp@rivosinc.com>
+Link: https://lore.kernel.org/r/20220527051743.2829940-5-sunilvl@ventanamicro.com
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Stable-dep-of: d2721bb165b3 ("RISC-V: Don't print details of CPUs disabled in DT")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/include/asm/processor.h | 4 ++--
+ arch/riscv/kernel/cpu.c | 26 +++++++++++++++-----------
+ arch/riscv/kernel/cpufeature.c | 6 ++++--
+ arch/riscv/kernel/smpboot.c | 9 +++++----
+ drivers/clocksource/timer-riscv.c | 15 ++++++++-------
+ drivers/irqchip/irq-riscv-intc.c | 7 ++++---
+ drivers/irqchip/irq-sifive-plic.c | 7 ++++---
+ 7 files changed, 42 insertions(+), 32 deletions(-)
+
+diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h
+index 0749924d9e552..99fae93985062 100644
+--- a/arch/riscv/include/asm/processor.h
++++ b/arch/riscv/include/asm/processor.h
+@@ -75,8 +75,8 @@ static inline void wait_for_interrupt(void)
+ }
+
+ struct device_node;
+-int riscv_of_processor_hartid(struct device_node *node);
+-int riscv_of_parent_hartid(struct device_node *node);
++int riscv_of_processor_hartid(struct device_node *node, unsigned long *hartid);
++int riscv_of_parent_hartid(struct device_node *node, unsigned long *hartid);
+
+ extern void riscv_fill_hwcap(void);
+ extern int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src);
+diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c
+index f13b2c9ea912d..11d6d6cc61d51 100644
+--- a/arch/riscv/kernel/cpu.c
++++ b/arch/riscv/kernel/cpu.c
+@@ -12,37 +12,36 @@
+ * Returns the hart ID of the given device tree node, or -ENODEV if the node
+ * isn't an enabled and valid RISC-V hart node.
+ */
+-int riscv_of_processor_hartid(struct device_node *node)
++int riscv_of_processor_hartid(struct device_node *node, unsigned long *hart)
+ {
+ const char *isa;
+- u32 hart;
+
+ if (!of_device_is_compatible(node, "riscv")) {
+ pr_warn("Found incompatible CPU\n");
+ return -ENODEV;
+ }
+
+- hart = of_get_cpu_hwid(node, 0);
+- if (hart == ~0U) {
++ *hart = (unsigned long) of_get_cpu_hwid(node, 0);
++ if (*hart == ~0UL) {
+ pr_warn("Found CPU without hart ID\n");
+ return -ENODEV;
+ }
+
+ if (!of_device_is_available(node)) {
+- pr_info("CPU with hartid=%d is not available\n", hart);
++ pr_info("CPU with hartid=%lu is not available\n", *hart);
+ return -ENODEV;
+ }
+
+ if (of_property_read_string(node, "riscv,isa", &isa)) {
+- pr_warn("CPU with hartid=%d has no \"riscv,isa\" property\n", hart);
++ pr_warn("CPU with hartid=%lu has no \"riscv,isa\" property\n", *hart);
+ return -ENODEV;
+ }
+ if (isa[0] != 'r' || isa[1] != 'v') {
+- pr_warn("CPU with hartid=%d has an invalid ISA of \"%s\"\n", hart, isa);
++ pr_warn("CPU with hartid=%lu has an invalid ISA of \"%s\"\n", *hart, isa);
+ return -ENODEV;
+ }
+
+- return hart;
++ return 0;
+ }
+
+ /*
+@@ -51,11 +50,16 @@ int riscv_of_processor_hartid(struct device_node *node)
+ * To achieve this, we walk up the DT tree until we find an active
+ * RISC-V core (HART) node and extract the cpuid from it.
+ */
+-int riscv_of_parent_hartid(struct device_node *node)
++int riscv_of_parent_hartid(struct device_node *node, unsigned long *hartid)
+ {
++ int rc;
++
+ for (; node; node = node->parent) {
+- if (of_device_is_compatible(node, "riscv"))
+- return riscv_of_processor_hartid(node);
++ if (of_device_is_compatible(node, "riscv")) {
++ rc = riscv_of_processor_hartid(node, hartid);
++ if (!rc)
++ return 0;
++ }
+ }
+
+ return -1;
+diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
+index 72c5f6ef56b5a..5d1af366116b0 100644
+--- a/arch/riscv/kernel/cpufeature.c
++++ b/arch/riscv/kernel/cpufeature.c
+@@ -67,8 +67,9 @@ void __init riscv_fill_hwcap(void)
+ struct device_node *node;
+ const char *isa;
+ char print_str[NUM_ALPHA_EXTS + 1];
+- int i, j;
++ int i, j, rc;
+ static unsigned long isa2hwcap[256] = {0};
++ unsigned long hartid;
+
+ isa2hwcap['i'] = isa2hwcap['I'] = COMPAT_HWCAP_ISA_I;
+ isa2hwcap['m'] = isa2hwcap['M'] = COMPAT_HWCAP_ISA_M;
+@@ -85,7 +86,8 @@ void __init riscv_fill_hwcap(void)
+ unsigned long this_hwcap = 0;
+ unsigned long this_isa = 0;
+
+- if (riscv_of_processor_hartid(node) < 0)
++ rc = riscv_of_processor_hartid(node, &hartid);
++ if (rc < 0)
+ continue;
+
+ if (of_property_read_string(node, "riscv,isa", &isa)) {
+diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c
+index 0f323e935dd89..3d3def84f81c1 100644
+--- a/arch/riscv/kernel/smpboot.c
++++ b/arch/riscv/kernel/smpboot.c
+@@ -77,15 +77,16 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
+ void __init setup_smp(void)
+ {
+ struct device_node *dn;
+- int hart;
++ unsigned long hart;
+ bool found_boot_cpu = false;
+ int cpuid = 1;
++ int rc;
+
+ cpu_set_ops(0);
+
+ for_each_of_cpu_node(dn) {
+- hart = riscv_of_processor_hartid(dn);
+- if (hart < 0)
++ rc = riscv_of_processor_hartid(dn, &hart);
++ if (rc < 0)
+ continue;
+
+ if (hart == cpuid_to_hartid_map(0)) {
+@@ -95,7 +96,7 @@ void __init setup_smp(void)
+ continue;
+ }
+ if (cpuid >= NR_CPUS) {
+- pr_warn("Invalid cpuid [%d] for hartid [%d]\n",
++ pr_warn("Invalid cpuid [%d] for hartid [%lu]\n",
+ cpuid, hart);
+ break;
+ }
+diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c
+index c51c5ed15aa75..4930d08c9374a 100644
+--- a/drivers/clocksource/timer-riscv.c
++++ b/drivers/clocksource/timer-riscv.c
+@@ -92,20 +92,21 @@ static irqreturn_t riscv_timer_interrupt(int irq, void *dev_id)
+
+ static int __init riscv_timer_init_dt(struct device_node *n)
+ {
+- int cpuid, hartid, error;
++ int cpuid, error;
++ unsigned long hartid;
+ struct device_node *child;
+ struct irq_domain *domain;
+
+- hartid = riscv_of_processor_hartid(n);
+- if (hartid < 0) {
+- pr_warn("Not valid hartid for node [%pOF] error = [%d]\n",
++ error = riscv_of_processor_hartid(n, &hartid);
++ if (error < 0) {
++ pr_warn("Not valid hartid for node [%pOF] error = [%lu]\n",
+ n, hartid);
+- return hartid;
++ return error;
+ }
+
+ cpuid = riscv_hartid_to_cpuid(hartid);
+ if (cpuid < 0) {
+- pr_warn("Invalid cpuid for hartid [%d]\n", hartid);
++ pr_warn("Invalid cpuid for hartid [%lu]\n", hartid);
+ return cpuid;
+ }
+
+@@ -131,7 +132,7 @@ static int __init riscv_timer_init_dt(struct device_node *n)
+ return -ENODEV;
+ }
+
+- pr_info("%s: Registering clocksource cpuid [%d] hartid [%d]\n",
++ pr_info("%s: Registering clocksource cpuid [%d] hartid [%lu]\n",
+ __func__, cpuid, hartid);
+ error = clocksource_register_hz(&riscv_clocksource, riscv_timebase);
+ if (error) {
+diff --git a/drivers/irqchip/irq-riscv-intc.c b/drivers/irqchip/irq-riscv-intc.c
+index 54c99441c1b54..ff4a69d276ca6 100644
+--- a/drivers/irqchip/irq-riscv-intc.c
++++ b/drivers/irqchip/irq-riscv-intc.c
+@@ -95,10 +95,11 @@ static const struct irq_domain_ops riscv_intc_domain_ops = {
+ static int __init riscv_intc_init(struct device_node *node,
+ struct device_node *parent)
+ {
+- int rc, hartid;
++ int rc;
++ unsigned long hartid;
+
+- hartid = riscv_of_parent_hartid(node);
+- if (hartid < 0) {
++ rc = riscv_of_parent_hartid(node, &hartid);
++ if (rc < 0) {
+ pr_warn("unable to find hart id for %pOF\n", node);
+ return 0;
+ }
+diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c
+index 09cc98266d30f..00b64fb882b18 100644
+--- a/drivers/irqchip/irq-sifive-plic.c
++++ b/drivers/irqchip/irq-sifive-plic.c
+@@ -313,7 +313,8 @@ static int __init plic_init(struct device_node *node,
+ for (i = 0; i < nr_contexts; i++) {
+ struct of_phandle_args parent;
+ irq_hw_number_t hwirq;
+- int cpu, hartid;
++ int cpu;
++ unsigned long hartid;
+
+ if (of_irq_parse_one(node, i, &parent)) {
+ pr_err("failed to parse parent for context %d.\n", i);
+@@ -327,8 +328,8 @@ static int __init plic_init(struct device_node *node,
+ if (parent.args[0] != RV_IRQ_EXT)
+ continue;
+
+- hartid = riscv_of_parent_hartid(parent.np);
+- if (hartid < 0) {
++ error = riscv_of_parent_hartid(parent.np, &hartid);
++ if (error < 0) {
+ pr_warn("failed to parse hart ID for context %d.\n", i);
+ continue;
+ }
+--
+2.51.0
+
--- /dev/null
+From 39a229d1aca075a66b8f8e81cf91fea61a85f1ac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Oct 2021 11:43:28 -0500
+Subject: riscv: Use of_get_cpu_hwid()
+
+From: Rob Herring <robh@kernel.org>
+
+[ Upstream commit bd2259ee458e299ec14061da7faddcfb0d54d154 ]
+
+Replace open coded parsing of CPU nodes' 'reg' property with
+of_get_cpu_hwid().
+
+Cc: Paul Walmsley <paul.walmsley@sifive.com>
+Cc: Palmer Dabbelt <palmer@dabbelt.com>
+Cc: Albert Ou <aou@eecs.berkeley.edu>
+Cc: linux-riscv@lists.infradead.org
+Signed-off-by: Rob Herring <robh@kernel.org>
+Link: https://lore.kernel.org/r/20211006164332.1981454-9-robh@kernel.org
+Stable-dep-of: d2721bb165b3 ("RISC-V: Don't print details of CPUs disabled in DT")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/cpu.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c
+index 6d59e6906fddf..f13b2c9ea912d 100644
+--- a/arch/riscv/kernel/cpu.c
++++ b/arch/riscv/kernel/cpu.c
+@@ -22,7 +22,8 @@ int riscv_of_processor_hartid(struct device_node *node)
+ return -ENODEV;
+ }
+
+- if (of_property_read_u32(node, "reg", &hart)) {
++ hart = of_get_cpu_hwid(node, 0);
++ if (hart == ~0U) {
+ pr_warn("Found CPU without hart ID\n");
+ return -ENODEV;
+ }
+--
+2.51.0
+
dpaa2-eth-fix-the-pointer-passed-to-ptr_align-on-tx-.patch
arm64-mm-avoid-always-making-pte-dirty-in-pte_mkwrit.patch
sctp-avoid-null-dereference-when-chunk-data-buffer-i.patch
+riscv-use-of_get_cpu_hwid.patch
+risc-v-correctly-print-supported-extensions.patch
+risc-v-minimal-parser-for-riscv-isa-strings.patch
+riscv-cpu-add-64bit-hartid-support-on-rv64.patch
+risc-v-don-t-print-details-of-cpus-disabled-in-dt.patch
--- /dev/null
+From 2c9794e62a3ad26785d292703ecefd96f2d488fe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Oct 2025 04:55:24 -0700
+Subject: io_uring: correct __must_hold annotation in io_install_fixed_file
+
+From: Alok Tiwari <alok.a.tiwari@oracle.com>
+
+[ Upstream commit c5efc6a0b3940381d67887302ddb87a5cf623685 ]
+
+The __must_hold annotation references &req->ctx->uring_lock, but req
+is not in scope in io_install_fixed_file. This change updates the
+annotation to reference the correct ctx->uring_lock.
+improving code clarity.
+
+Fixes: f110ed8498af ("io_uring: split out fixed file installation and removal")
+Signed-off-by: Alok Tiwari <alok.a.tiwari@oracle.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ io_uring/filetable.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/io_uring/filetable.c b/io_uring/filetable.c
+index a64b4df0ac9c2..f9e59c650e893 100644
+--- a/io_uring/filetable.c
++++ b/io_uring/filetable.c
+@@ -62,7 +62,7 @@ void io_free_file_tables(struct io_file_table *table)
+
+ static int io_install_fixed_file(struct io_ring_ctx *ctx, struct file *file,
+ u32 slot_index)
+- __must_hold(&req->ctx->uring_lock)
++ __must_hold(&ctx->uring_lock)
+ {
+ bool needs_switch = false;
+ struct io_fixed_file *file_slot;
+--
+2.51.0
+
--- /dev/null
+From d647ec5b8f5d2bbd0cb3da8ec3cff6609db867bc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Oct 2025 21:30:05 -0600
+Subject: RISC-V: Define pgprot_dmacoherent() for non-coherent devices
+
+From: Anup Patel <apatel@ventanamicro.com>
+
+[ Upstream commit ca525d53f994d45c8140968b571372c45f555ac1 ]
+
+The pgprot_dmacoherent() is used when allocating memory for
+non-coherent devices and by default pgprot_dmacoherent() is
+same as pgprot_noncached() unless architecture overrides it.
+
+Currently, there is no pgprot_dmacoherent() definition for
+RISC-V hence non-coherent device memory is being mapped as
+IO thereby making CPU access to such memory slow.
+
+Define pgprot_dmacoherent() to be same as pgprot_writecombine()
+for RISC-V so that CPU access non-coherent device memory as
+NOCACHE which is better than accessing it as IO.
+
+Fixes: ff689fd21cb1 ("riscv: add RISC-V Svpbmt extension support")
+Signed-off-by: Anup Patel <apatel@ventanamicro.com>
+Tested-by: Han Gao <rabenda.cn@gmail.com>
+Tested-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
+Link: https://lore.kernel.org/r/20250820152316.1012757-1-apatel@ventanamicro.com
+Signed-off-by: Paul Walmsley <pjw@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/include/asm/pgtable.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
+index bb19a643c5c2a..1a94e633c1445 100644
+--- a/arch/riscv/include/asm/pgtable.h
++++ b/arch/riscv/include/asm/pgtable.h
+@@ -555,6 +555,8 @@ static inline pgprot_t pgprot_writecombine(pgprot_t _prot)
+ return __pgprot(prot);
+ }
+
++#define pgprot_dmacoherent pgprot_writecombine
++
+ /*
+ * THP functions
+ */
+--
+2.51.0
+
--- /dev/null
+From 395dc9886374a94e38cc82dbabced49c1fe6b836 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Oct 2025 22:00:09 +0530
+Subject: RISC-V: Don't print details of CPUs disabled in DT
+
+From: Anup Patel <apatel@ventanamicro.com>
+
+[ Upstream commit d2721bb165b3ee00dd23525885381af07fec852a ]
+
+Early boot stages may disable CPU DT nodes for unavailable
+CPUs based on SKU, pinstraps, eFuse, etc. Currently, the
+riscv_early_of_processor_hartid() prints details of a CPU
+if it is disabled in DT which has no value and gives a
+false impression to the users that there some issue with
+the CPU.
+
+Fixes: e3d794d555cd ("riscv: treat cpu devicetree nodes without status as enabled")
+Signed-off-by: Anup Patel <apatel@ventanamicro.com>
+Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Link: https://lore.kernel.org/r/20251014163009.182381-1-apatel@ventanamicro.com
+Signed-off-by: Paul Walmsley <pjw@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/cpu.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c
+index 0f76181dc634d..e642b3dc42d27 100644
+--- a/arch/riscv/kernel/cpu.c
++++ b/arch/riscv/kernel/cpu.c
+@@ -32,10 +32,8 @@ int riscv_of_processor_hartid(struct device_node *node, unsigned long *hart)
+ return -ENODEV;
+ }
+
+- if (!of_device_is_available(node)) {
+- pr_info("CPU with hartid=%lu is not available\n", *hart);
++ if (!of_device_is_available(node))
+ return -ENODEV;
+- }
+
+ if (of_property_read_string(node, "riscv,isa", &isa)) {
+ pr_warn("CPU with hartid=%lu has no \"riscv,isa\" property\n", *hart);
+--
+2.51.0
+
dpaa2-eth-fix-the-pointer-passed-to-ptr_align-on-tx-.patch
arm64-mm-avoid-always-making-pte-dirty-in-pte_mkwrit.patch
sctp-avoid-null-dereference-when-chunk-data-buffer-i.patch
+risc-v-define-pgprot_dmacoherent-for-non-coherent-de.patch
+risc-v-don-t-print-details-of-cpus-disabled-in-dt.patch
+io_uring-correct-__must_hold-annotation-in-io_instal.patch
--- /dev/null
+From 348b53c3692ec06320fedc9a0a95acda76be653a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Aug 2025 15:34:08 +0200
+Subject: arm64: dts: broadcom: bcm2712: Add default GIC address cells
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 278b6cabf18bd804f956b98a2f1068717acdbfe3 ]
+
+Add missing address-cells 0 to GIC interrupt node to silence W=1
+warning:
+
+ bcm2712.dtsi:494.4-497.31: Warning (interrupt_map): /axi/pcie@1000110000:interrupt-map:
+ Missing property '#address-cells' in node /soc@107c000000/interrupt-controller@7fff9000, using 0 as fallback
+
+Value '0' is correct because:
+1. GIC interrupt controller does not have children,
+2. interrupt-map property (in PCI node) consists of five components and
+ the fourth component "parent unit address", which size is defined by
+ '#address-cells' of the node pointed to by the interrupt-parent
+ component, is not used (=0)
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20250822133407.312505-2-krzysztof.kozlowski@linaro.org
+Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Stable-dep-of: aa960b597600 ("arm64: dts: broadcom: bcm2712: Define VGIC interrupt")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/broadcom/bcm2712.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
+index 447bfa060918c..0f38236501743 100644
+--- a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
++++ b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
+@@ -263,6 +263,7 @@
+ <0x7fffc000 0x2000>,
+ <0x7fffe000 0x2000>;
+ interrupt-controller;
++ #address-cells = <0>;
+ #interrupt-cells = <3>;
+ };
+ };
+--
+2.51.0
+
--- /dev/null
+From add60c155326d968f7bc9399006c5a80d497ff4d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Sep 2025 09:56:05 +0100
+Subject: arm64: dts: broadcom: bcm2712: Define VGIC interrupt
+
+From: Peter Robinson <pbrobinson@gmail.com>
+
+[ Upstream commit aa960b597600bed80fe171729057dd6aa188b5b5 ]
+
+Define the interrupt in the GICv2 for vGIC so KVM
+can be used, it was missed from the original upstream
+DTB for some reason.
+
+Signed-off-by: Peter Robinson <pbrobinson@gmail.com>
+Cc: Andrea della Porta <andrea.porta@suse.com>
+Cc: Phil Elwell <phil@raspberrypi.com>
+Fixes: faa3381267d0 ("arm64: dts: broadcom: Add minimal support for Raspberry Pi 5")
+Link: https://lore.kernel.org/r/20250924085612.1039247-1-pbrobinson@gmail.com
+Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/broadcom/bcm2712.dtsi | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
+index 0f38236501743..209f99b1ceae7 100644
+--- a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
++++ b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
+@@ -264,6 +264,8 @@
+ <0x7fffe000 0x2000>;
+ interrupt-controller;
+ #address-cells = <0>;
++ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) |
++ IRQ_TYPE_LEVEL_HIGH)>;
+ #interrupt-cells = <3>;
+ };
+ };
+--
+2.51.0
+
--- /dev/null
+From eab9f21c9db4bad6283a565679683c466b44075f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Oct 2025 14:24:48 +0200
+Subject: drm/panic: Fix drawing the logo on a small narrow screen
+
+From: Jocelyn Falempe <jfalempe@redhat.com>
+
+[ Upstream commit 179753aa5b7890b311968c033d08f558f0a7be21 ]
+
+If the logo width is bigger than the framebuffer width, and the
+height is big enough to hold the logo and the message, it will draw
+at x coordinate that are higher than the width, and ends up in a
+corrupted image.
+
+Fixes: 4b570ac2eb54 ("drm/rect: Add drm_rect_overlap()")
+Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
+Link: https://lore.kernel.org/r/20251009122955.562888-2-jfalempe@redhat.com
+Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_panic.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c
+index f128d345b16df..932a54b674794 100644
+--- a/drivers/gpu/drm/drm_panic.c
++++ b/drivers/gpu/drm/drm_panic.c
+@@ -306,6 +306,9 @@ static void drm_panic_logo_rect(struct drm_rect *rect, const struct font_desc *f
+ static void drm_panic_logo_draw(struct drm_scanout_buffer *sb, struct drm_rect *rect,
+ const struct font_desc *font, u32 fg_color)
+ {
++ if (rect->x2 > sb->width || rect->y2 > sb->height)
++ return;
++
+ if (logo_mono)
+ drm_panic_blit(sb, rect, logo_mono->data,
+ DIV_ROUND_UP(drm_rect_width(rect), 8), 1, fg_color);
+--
+2.51.0
+
--- /dev/null
+From c79d36988f9ba7f9a53cb6c9e17a92d6ae418e1d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Oct 2025 14:24:50 +0200
+Subject: drm/panic: Fix qr_code, ensure vmargin is positive
+
+From: Jocelyn Falempe <jfalempe@redhat.com>
+
+[ Upstream commit 4fcffb5e5c8c0c8e2ad9c99a22305a0afbecc294 ]
+
+Depending on qr_code size and screen size, the vertical margin can
+be negative, that means there is not enough room to draw the qr_code.
+
+So abort early, to avoid a segfault by trying to draw at negative
+coordinates.
+
+Fixes: cb5164ac43d0f ("drm/panic: Add a QR code panic screen")
+Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
+Link: https://lore.kernel.org/r/20251009122955.562888-4-jfalempe@redhat.com
+Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_panic.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c
+index 932a54b674794..0aa87eafdacd5 100644
+--- a/drivers/gpu/drm/drm_panic.c
++++ b/drivers/gpu/drm/drm_panic.c
+@@ -618,7 +618,10 @@ static int _draw_panic_static_qr_code(struct drm_scanout_buffer *sb)
+ pr_debug("QR width %d and scale %d\n", qr_width, scale);
+ r_qr_canvas = DRM_RECT_INIT(0, 0, qr_canvas_width * scale, qr_canvas_width * scale);
+
+- v_margin = (sb->height - drm_rect_height(&r_qr_canvas) - drm_rect_height(&r_msg)) / 5;
++ v_margin = sb->height - drm_rect_height(&r_qr_canvas) - drm_rect_height(&r_msg);
++ if (v_margin < 0)
++ return -ENOSPC;
++ v_margin /= 5;
+
+ drm_rect_translate(&r_qr_canvas, (sb->width - r_qr_canvas.x2) / 2, 2 * v_margin);
+ r_qr = DRM_RECT_INIT(r_qr_canvas.x1 + QR_MARGIN * scale, r_qr_canvas.y1 + QR_MARGIN * scale,
+--
+2.51.0
+
--- /dev/null
+From 6538e24b1ce706f42675005e84e1195a0c2c8069 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Oct 2025 11:29:22 +0100
+Subject: drm/panthor: Fix kernel panic on partial unmap of a GPU VA region
+
+From: Akash Goel <akash.goel@arm.com>
+
+[ Upstream commit 4eabd0d8791eaf9a7b114ccbf56eb488aefe7b1f ]
+
+This commit address a kernel panic issue that can happen if Userspace
+tries to partially unmap a GPU virtual region (aka drm_gpuva).
+The VM_BIND interface allows partial unmapping of a BO.
+
+Panthor driver pre-allocates memory for the new drm_gpuva structures
+that would be needed for the map/unmap operation, done using drm_gpuvm
+layer. It expected that only one new drm_gpuva would be needed on umap
+but a partial unmap can require 2 new drm_gpuva and that's why it
+ended up doing a NULL pointer dereference causing a kernel panic.
+
+Following dump was seen when partial unmap was exercised.
+ Unable to handle kernel NULL pointer dereference at virtual address 0000000000000078
+ Mem abort info:
+ ESR = 0x0000000096000046
+ EC = 0x25: DABT (current EL), IL = 32 bits
+ SET = 0, FnV = 0
+ EA = 0, S1PTW = 0
+ FSC = 0x06: level 2 translation fault
+ Data abort info:
+ ISV = 0, ISS = 0x00000046, ISS2 = 0x00000000
+ CM = 0, WnR = 1, TnD = 0, TagAccess = 0
+ GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
+ user pgtable: 4k pages, 48-bit VAs, pgdp=000000088a863000
+ [000000000000078] pgd=080000088a842003, p4d=080000088a842003, pud=0800000884bf5003, pmd=0000000000000000
+ Internal error: Oops: 0000000096000046 [#1] PREEMPT SMP
+ <snip>
+ pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+ pc : panthor_gpuva_sm_step_remap+0xe4/0x330 [panthor]
+ lr : panthor_gpuva_sm_step_remap+0x6c/0x330 [panthor]
+ sp : ffff800085d43970
+ x29: ffff800085d43970 x28: ffff00080363e440 x27: ffff0008090c6000
+ x26: 0000000000000030 x25: ffff800085d439f8 x24: ffff00080d402000
+ x23: ffff800085d43b60 x22: ffff800085d439e0 x21: ffff00080abdb180
+ x20: 0000000000000000 x19: 0000000000000000 x18: 0000000000000010
+ x17: 6e656c202c303030 x16: 3666666666646466 x15: 393d61766f69202c
+ x14: 312d3d7361203a70 x13: 303030323d6e656c x12: ffff80008324bf58
+ x11: 0000000000000003 x10: 0000000000000002 x9 : ffff8000801a6a9c
+ x8 : ffff00080360b300 x7 : 0000000000000000 x6 : 000000088aa35fc7
+ x5 : fff1000080000000 x4 : ffff8000842ddd30 x3 : 0000000000000001
+ x2 : 0000000100000000 x1 : 0000000000000001 x0 : 0000000000000078
+ Call trace:
+ panthor_gpuva_sm_step_remap+0xe4/0x330 [panthor]
+ op_remap_cb.isra.22+0x50/0x80
+ __drm_gpuvm_sm_unmap+0x10c/0x1c8
+ drm_gpuvm_sm_unmap+0x40/0x60
+ panthor_vm_exec_op+0xb4/0x3d0 [panthor]
+ panthor_vm_bind_exec_sync_op+0x154/0x278 [panthor]
+ panthor_ioctl_vm_bind+0x160/0x4a0 [panthor]
+ drm_ioctl_kernel+0xbc/0x138
+ drm_ioctl+0x240/0x500
+ __arm64_sys_ioctl+0xb0/0xf8
+ invoke_syscall+0x4c/0x110
+ el0_svc_common.constprop.1+0x98/0xf8
+ do_el0_svc+0x24/0x38
+ el0_svc+0x40/0xf8
+ el0t_64_sync_handler+0xa0/0xc8
+ el0t_64_sync+0x174/0x178
+
+Signed-off-by: Akash Goel <akash.goel@arm.com>
+Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
+Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
+Fixes: 647810ec2476 ("drm/panthor: Add the MMU/VM logical block")
+Reviewed-by: Steven Price <steven.price@arm.com>
+Signed-off-by: Steven Price <steven.price@arm.com>
+Link: https://lore.kernel.org/r/20251017102922.670084-1-akash.goel@arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/panthor/panthor_mmu.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/panthor/panthor_mmu.c
+index b57824abeb9ee..2214dbf472fa4 100644
+--- a/drivers/gpu/drm/panthor/panthor_mmu.c
++++ b/drivers/gpu/drm/panthor/panthor_mmu.c
+@@ -1168,10 +1168,14 @@ panthor_vm_op_ctx_prealloc_vmas(struct panthor_vm_op_ctx *op_ctx)
+ break;
+
+ case DRM_PANTHOR_VM_BIND_OP_TYPE_UNMAP:
+- /* Partial unmaps might trigger a remap with either a prev or a next VA,
+- * but not both.
++ /* Two VMAs can be needed for an unmap, as an unmap can happen
++ * in the middle of a drm_gpuva, requiring a remap with both
++ * prev & next VA. Or an unmap can span more than one drm_gpuva
++ * where the first and last ones are covered partially, requring
++ * a remap for the first with a prev VA and remap for the last
++ * with a next VA.
+ */
+- vma_count = 1;
++ vma_count = 2;
+ break;
+
+ default:
+--
+2.51.0
+
--- /dev/null
+From 58d3e2680bea98d172b1ea48f59082160eee1871 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Oct 2025 12:53:44 +0100
+Subject: firmware: arm_scmi: Account for failed debug initialization
+
+From: Cristian Marussi <cristian.marussi@arm.com>
+
+[ Upstream commit 2290ab43b9d8eafb8046387f10a8dfa2b030ba46 ]
+
+When the SCMI debug subsystem fails to initialize, the related debug root
+will be missing, and the underlying descriptor will be NULL.
+
+Handle this fault condition in the SCMI debug helpers that maintain
+metrics counters.
+
+Fixes: 0b3d48c4726e ("firmware: arm_scmi: Track basic SCMI communication debug metrics")
+Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
+Message-Id: <20251014115346.2391418-1-cristian.marussi@arm.com>
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_scmi/common.h | 24 ++++++++++++++--
+ drivers/firmware/arm_scmi/driver.c | 44 ++++++++++--------------------
+ 2 files changed, 35 insertions(+), 33 deletions(-)
+
+diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
+index cdec50a698a10..87acc795f7436 100644
+--- a/drivers/firmware/arm_scmi/common.h
++++ b/drivers/firmware/arm_scmi/common.h
+@@ -297,10 +297,28 @@ enum debug_counters {
+ SCMI_DEBUG_COUNTERS_LAST
+ };
+
+-static inline void scmi_inc_count(atomic_t *arr, int stat)
++/**
++ * struct scmi_debug_info - Debug common info
++ * @top_dentry: A reference to the top debugfs dentry
++ * @name: Name of this SCMI instance
++ * @type: Type of this SCMI instance
++ * @is_atomic: Flag to state if the transport of this instance is atomic
++ * @counters: An array of atomic_c's used for tracking statistics (if enabled)
++ */
++struct scmi_debug_info {
++ struct dentry *top_dentry;
++ const char *name;
++ const char *type;
++ bool is_atomic;
++ atomic_t counters[SCMI_DEBUG_COUNTERS_LAST];
++};
++
++static inline void scmi_inc_count(struct scmi_debug_info *dbg, int stat)
+ {
+- if (IS_ENABLED(CONFIG_ARM_SCMI_DEBUG_COUNTERS))
+- atomic_inc(&arr[stat]);
++ if (IS_ENABLED(CONFIG_ARM_SCMI_DEBUG_COUNTERS)) {
++ if (dbg)
++ atomic_inc(&dbg->counters[stat]);
++ }
+ }
+
+ enum scmi_bad_msg {
+diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
+index f1abe605865ad..5b4df0a27e22f 100644
+--- a/drivers/firmware/arm_scmi/driver.c
++++ b/drivers/firmware/arm_scmi/driver.c
+@@ -111,22 +111,6 @@ struct scmi_protocol_instance {
+
+ #define ph_to_pi(h) container_of(h, struct scmi_protocol_instance, ph)
+
+-/**
+- * struct scmi_debug_info - Debug common info
+- * @top_dentry: A reference to the top debugfs dentry
+- * @name: Name of this SCMI instance
+- * @type: Type of this SCMI instance
+- * @is_atomic: Flag to state if the transport of this instance is atomic
+- * @counters: An array of atomic_c's used for tracking statistics (if enabled)
+- */
+-struct scmi_debug_info {
+- struct dentry *top_dentry;
+- const char *name;
+- const char *type;
+- bool is_atomic;
+- atomic_t counters[SCMI_DEBUG_COUNTERS_LAST];
+-};
+-
+ /**
+ * struct scmi_info - Structure representing a SCMI instance
+ *
+@@ -1000,7 +984,7 @@ scmi_xfer_command_acquire(struct scmi_chan_info *cinfo, u32 msg_hdr)
+ spin_unlock_irqrestore(&minfo->xfer_lock, flags);
+
+ scmi_bad_message_trace(cinfo, msg_hdr, MSG_UNEXPECTED);
+- scmi_inc_count(info->dbg->counters, ERR_MSG_UNEXPECTED);
++ scmi_inc_count(info->dbg, ERR_MSG_UNEXPECTED);
+
+ return xfer;
+ }
+@@ -1028,7 +1012,7 @@ scmi_xfer_command_acquire(struct scmi_chan_info *cinfo, u32 msg_hdr)
+ msg_type, xfer_id, msg_hdr, xfer->state);
+
+ scmi_bad_message_trace(cinfo, msg_hdr, MSG_INVALID);
+- scmi_inc_count(info->dbg->counters, ERR_MSG_INVALID);
++ scmi_inc_count(info->dbg, ERR_MSG_INVALID);
+
+ /* On error the refcount incremented above has to be dropped */
+ __scmi_xfer_put(minfo, xfer);
+@@ -1073,7 +1057,7 @@ static void scmi_handle_notification(struct scmi_chan_info *cinfo,
+ PTR_ERR(xfer));
+
+ scmi_bad_message_trace(cinfo, msg_hdr, MSG_NOMEM);
+- scmi_inc_count(info->dbg->counters, ERR_MSG_NOMEM);
++ scmi_inc_count(info->dbg, ERR_MSG_NOMEM);
+
+ scmi_clear_channel(info, cinfo);
+ return;
+@@ -1089,7 +1073,7 @@ static void scmi_handle_notification(struct scmi_chan_info *cinfo,
+ trace_scmi_msg_dump(info->id, cinfo->id, xfer->hdr.protocol_id,
+ xfer->hdr.id, "NOTI", xfer->hdr.seq,
+ xfer->hdr.status, xfer->rx.buf, xfer->rx.len);
+- scmi_inc_count(info->dbg->counters, NOTIFICATION_OK);
++ scmi_inc_count(info->dbg, NOTIFICATION_OK);
+
+ scmi_notify(cinfo->handle, xfer->hdr.protocol_id,
+ xfer->hdr.id, xfer->rx.buf, xfer->rx.len, ts);
+@@ -1149,10 +1133,10 @@ static void scmi_handle_response(struct scmi_chan_info *cinfo,
+ if (xfer->hdr.type == MSG_TYPE_DELAYED_RESP) {
+ scmi_clear_channel(info, cinfo);
+ complete(xfer->async_done);
+- scmi_inc_count(info->dbg->counters, DELAYED_RESPONSE_OK);
++ scmi_inc_count(info->dbg, DELAYED_RESPONSE_OK);
+ } else {
+ complete(&xfer->done);
+- scmi_inc_count(info->dbg->counters, RESPONSE_OK);
++ scmi_inc_count(info->dbg, RESPONSE_OK);
+ }
+
+ if (IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT)) {
+@@ -1261,7 +1245,7 @@ static int scmi_wait_for_reply(struct device *dev, const struct scmi_desc *desc,
+ "timed out in resp(caller: %pS) - polling\n",
+ (void *)_RET_IP_);
+ ret = -ETIMEDOUT;
+- scmi_inc_count(info->dbg->counters, XFERS_RESPONSE_POLLED_TIMEOUT);
++ scmi_inc_count(info->dbg, XFERS_RESPONSE_POLLED_TIMEOUT);
+ }
+ }
+
+@@ -1286,7 +1270,7 @@ static int scmi_wait_for_reply(struct device *dev, const struct scmi_desc *desc,
+ "RESP" : "resp",
+ xfer->hdr.seq, xfer->hdr.status,
+ xfer->rx.buf, xfer->rx.len);
+- scmi_inc_count(info->dbg->counters, RESPONSE_POLLED_OK);
++ scmi_inc_count(info->dbg, RESPONSE_POLLED_OK);
+
+ if (IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT)) {
+ scmi_raw_message_report(info->raw, xfer,
+@@ -1301,7 +1285,7 @@ static int scmi_wait_for_reply(struct device *dev, const struct scmi_desc *desc,
+ dev_err(dev, "timed out in resp(caller: %pS)\n",
+ (void *)_RET_IP_);
+ ret = -ETIMEDOUT;
+- scmi_inc_count(info->dbg->counters, XFERS_RESPONSE_TIMEOUT);
++ scmi_inc_count(info->dbg, XFERS_RESPONSE_TIMEOUT);
+ }
+ }
+
+@@ -1385,13 +1369,13 @@ static int do_xfer(const struct scmi_protocol_handle *ph,
+ !is_transport_polling_capable(info->desc)) {
+ dev_warn_once(dev,
+ "Polling mode is not supported by transport.\n");
+- scmi_inc_count(info->dbg->counters, SENT_FAIL_POLLING_UNSUPPORTED);
++ scmi_inc_count(info->dbg, SENT_FAIL_POLLING_UNSUPPORTED);
+ return -EINVAL;
+ }
+
+ cinfo = idr_find(&info->tx_idr, pi->proto->id);
+ if (unlikely(!cinfo)) {
+- scmi_inc_count(info->dbg->counters, SENT_FAIL_CHANNEL_NOT_FOUND);
++ scmi_inc_count(info->dbg, SENT_FAIL_CHANNEL_NOT_FOUND);
+ return -EINVAL;
+ }
+ /* True ONLY if also supported by transport. */
+@@ -1425,19 +1409,19 @@ static int do_xfer(const struct scmi_protocol_handle *ph,
+ ret = info->desc->ops->send_message(cinfo, xfer);
+ if (ret < 0) {
+ dev_dbg(dev, "Failed to send message %d\n", ret);
+- scmi_inc_count(info->dbg->counters, SENT_FAIL);
++ scmi_inc_count(info->dbg, SENT_FAIL);
+ return ret;
+ }
+
+ trace_scmi_msg_dump(info->id, cinfo->id, xfer->hdr.protocol_id,
+ xfer->hdr.id, "CMND", xfer->hdr.seq,
+ xfer->hdr.status, xfer->tx.buf, xfer->tx.len);
+- scmi_inc_count(info->dbg->counters, SENT_OK);
++ scmi_inc_count(info->dbg, SENT_OK);
+
+ ret = scmi_wait_for_message_response(cinfo, xfer);
+ if (!ret && xfer->hdr.status) {
+ ret = scmi_to_linux_errno(xfer->hdr.status);
+- scmi_inc_count(info->dbg->counters, ERR_PROTOCOL);
++ scmi_inc_count(info->dbg, ERR_PROTOCOL);
+ }
+
+ if (info->desc->ops->mark_txdone)
+--
+2.51.0
+
--- /dev/null
+From c45957431bb8abe5b3a77bebb592634c5cb97a3c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Oct 2025 12:10:57 +0300
+Subject: firmware: arm_scmi: Fix premature SCMI_XFER_FLAG_IS_RAW clearing in
+ raw mode
+
+From: Artem Shimko <a.shimko.dev@gmail.com>
+
+[ Upstream commit 20b93a0088a595bceed4a026d527cbbac4e876c5 ]
+
+The SCMI_XFER_FLAG_IS_RAW flag was being cleared prematurely in
+scmi_xfer_raw_put() before the transfer completion was properly
+acknowledged by the raw message handlers.
+
+Move the clearing of SCMI_XFER_FLAG_IS_RAW and SCMI_XFER_FLAG_CHAN_SET
+from scmi_xfer_raw_put() to __scmi_xfer_put() to ensure the flags remain
+set throughout the entire raw message processing pipeline until the
+transfer is returned to the free pool.
+
+Fixes: 3095a3e25d8f ("firmware: arm_scmi: Add xfer helpers to provide raw access")
+Suggested-by: Cristian Marussi <cristian.marussi@arm.com>
+Signed-off-by: Artem Shimko <a.shimko.dev@gmail.com>
+Reviewed-by: Cristian Marussi <cristian.marussi@arm.com>
+Message-Id: <20251008091057.1969260-1-a.shimko.dev@gmail.com>
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_scmi/driver.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
+index 5b4df0a27e22f..79866f3b6b3e7 100644
+--- a/drivers/firmware/arm_scmi/driver.c
++++ b/drivers/firmware/arm_scmi/driver.c
+@@ -771,6 +771,7 @@ __scmi_xfer_put(struct scmi_xfers_info *minfo, struct scmi_xfer *xfer)
+ hash_del(&xfer->node);
+ xfer->pending = false;
+ }
++ xfer->flags = 0;
+ hlist_add_head(&xfer->node, &minfo->free_xfers);
+ }
+ spin_unlock_irqrestore(&minfo->xfer_lock, flags);
+@@ -789,8 +790,6 @@ void scmi_xfer_raw_put(const struct scmi_handle *handle, struct scmi_xfer *xfer)
+ {
+ struct scmi_info *info = handle_to_scmi_info(handle);
+
+- xfer->flags &= ~SCMI_XFER_FLAG_IS_RAW;
+- xfer->flags &= ~SCMI_XFER_FLAG_CHAN_SET;
+ return __scmi_xfer_put(&info->tx_minfo, xfer);
+ }
+
+--
+2.51.0
+
--- /dev/null
+From f391be2a2d66c6c85face5a57a09a526c26a7018 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Oct 2025 15:02:30 +0800
+Subject: gpio: ljca: Fix duplicated IRQ mapping
+
+From: Haotian Zhang <vulab@iscas.ac.cn>
+
+[ Upstream commit 4c4e6ea4a120cc5ab58e437c6ba123cbfc357d45 ]
+
+The generic_handle_domain_irq() function resolves the hardware IRQ
+internally. The driver performed a duplicative mapping by calling
+irq_find_mapping() first, which could lead to an RCU stall.
+
+Delete the redundant irq_find_mapping() call and pass the hardware IRQ
+directly to generic_handle_domain_irq().
+
+Fixes: c5a4b6fd31e8 ("gpio: Add support for Intel LJCA USB GPIO driver")
+Signed-off-by: Haotian Zhang <vulab@iscas.ac.cn>
+Link: https://lore.kernel.org/r/20251023070231.1305-1-vulab@iscas.ac.cn
+[Bartosz: remove unused variable]
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-ljca.c | 14 +++-----------
+ 1 file changed, 3 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/gpio/gpio-ljca.c b/drivers/gpio/gpio-ljca.c
+index c2a9b42539744..c3a595c6f6c72 100644
+--- a/drivers/gpio/gpio-ljca.c
++++ b/drivers/gpio/gpio-ljca.c
+@@ -281,22 +281,14 @@ static void ljca_gpio_event_cb(void *context, u8 cmd, const void *evt_data,
+ {
+ const struct ljca_gpio_packet *packet = evt_data;
+ struct ljca_gpio_dev *ljca_gpio = context;
+- int i, irq;
++ int i;
+
+ if (cmd != LJCA_GPIO_INT_EVENT)
+ return;
+
+ for (i = 0; i < packet->num; i++) {
+- irq = irq_find_mapping(ljca_gpio->gc.irq.domain,
+- packet->item[i].index);
+- if (!irq) {
+- dev_err(ljca_gpio->gc.parent,
+- "gpio_id %u does not mapped to IRQ yet\n",
+- packet->item[i].index);
+- return;
+- }
+-
+- generic_handle_domain_irq(ljca_gpio->gc.irq.domain, irq);
++ generic_handle_domain_irq(ljca_gpio->gc.irq.domain,
++ packet->item[i].index);
+ set_bit(packet->item[i].index, ljca_gpio->reenable_irqs);
+ }
+
+--
+2.51.0
+
--- /dev/null
+From df8d802592388c5a47f5bc8156c266f2a89ab868 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 18 Oct 2025 06:04:57 -0700
+Subject: hwmon: (sht3x) Fix error handling
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+[ Upstream commit 8dcc66ad379ec0642fb281c45ccfd7d2d366e53f ]
+
+Handling of errors when reading status, temperature, and humidity returns
+the error number as negative attribute value. Fix it up by returning
+the error as return value.
+
+Fixes: a0ac418c6007c ("hwmon: (sht3x) convert some of sysfs interface to hwmon")
+Cc: JuenKit Yip <JuenKit_Yip@hotmail.com>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/sht3x.c | 27 +++++++++++++++++----------
+ 1 file changed, 17 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/hwmon/sht3x.c b/drivers/hwmon/sht3x.c
+index 650b0bcc2359e..94466e28dc56f 100644
+--- a/drivers/hwmon/sht3x.c
++++ b/drivers/hwmon/sht3x.c
+@@ -294,24 +294,26 @@ static struct sht3x_data *sht3x_update_client(struct device *dev)
+ return data;
+ }
+
+-static int temp1_input_read(struct device *dev)
++static int temp1_input_read(struct device *dev, long *temp)
+ {
+ struct sht3x_data *data = sht3x_update_client(dev);
+
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+
+- return data->temperature;
++ *temp = data->temperature;
++ return 0;
+ }
+
+-static int humidity1_input_read(struct device *dev)
++static int humidity1_input_read(struct device *dev, long *humidity)
+ {
+ struct sht3x_data *data = sht3x_update_client(dev);
+
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+
+- return data->humidity;
++ *humidity = data->humidity;
++ return 0;
+ }
+
+ /*
+@@ -709,6 +711,7 @@ static int sht3x_read(struct device *dev, enum hwmon_sensor_types type,
+ u32 attr, int channel, long *val)
+ {
+ enum sht3x_limits index;
++ int ret;
+
+ switch (type) {
+ case hwmon_chip:
+@@ -723,10 +726,12 @@ static int sht3x_read(struct device *dev, enum hwmon_sensor_types type,
+ case hwmon_temp:
+ switch (attr) {
+ case hwmon_temp_input:
+- *val = temp1_input_read(dev);
+- break;
++ return temp1_input_read(dev, val);
+ case hwmon_temp_alarm:
+- *val = temp1_alarm_read(dev);
++ ret = temp1_alarm_read(dev);
++ if (ret < 0)
++ return ret;
++ *val = ret;
+ break;
+ case hwmon_temp_max:
+ index = limit_max;
+@@ -751,10 +756,12 @@ static int sht3x_read(struct device *dev, enum hwmon_sensor_types type,
+ case hwmon_humidity:
+ switch (attr) {
+ case hwmon_humidity_input:
+- *val = humidity1_input_read(dev);
+- break;
++ return humidity1_input_read(dev, val);
+ case hwmon_humidity_alarm:
+- *val = humidity1_alarm_read(dev);
++ ret = humidity1_alarm_read(dev);
++ if (ret < 0)
++ return ret;
++ *val = ret;
+ break;
+ case hwmon_humidity_max:
+ index = limit_max;
+--
+2.51.0
+
--- /dev/null
+From aae15cb30dd1831a7cda17910e9291edffe4fc9e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Oct 2025 04:55:24 -0700
+Subject: io_uring: correct __must_hold annotation in io_install_fixed_file
+
+From: Alok Tiwari <alok.a.tiwari@oracle.com>
+
+[ Upstream commit c5efc6a0b3940381d67887302ddb87a5cf623685 ]
+
+The __must_hold annotation references &req->ctx->uring_lock, but req
+is not in scope in io_install_fixed_file. This change updates the
+annotation to reference the correct ctx->uring_lock.
+improving code clarity.
+
+Fixes: f110ed8498af ("io_uring: split out fixed file installation and removal")
+Signed-off-by: Alok Tiwari <alok.a.tiwari@oracle.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ io_uring/filetable.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/io_uring/filetable.c b/io_uring/filetable.c
+index 997c56d32ee6c..6183d61c7222d 100644
+--- a/io_uring/filetable.c
++++ b/io_uring/filetable.c
+@@ -62,7 +62,7 @@ void io_free_file_tables(struct io_file_table *table)
+
+ static int io_install_fixed_file(struct io_ring_ctx *ctx, struct file *file,
+ u32 slot_index)
+- __must_hold(&req->ctx->uring_lock)
++ __must_hold(&ctx->uring_lock)
+ {
+ struct io_fixed_file *file_slot;
+ int ret;
+--
+2.51.0
+
--- /dev/null
+From a65b06a146745e96d52c8ac6b125aa124da3b48b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Oct 2025 10:09:00 +0200
+Subject: nbd: override creds to kernel when calling sock_{send,recv}msg()
+
+From: Ondrej Mosnacek <omosnace@redhat.com>
+
+[ Upstream commit 81ccca31214e11ea2b537fd35d4f66d7cf46268e ]
+
+sock_{send,recv}msg() internally calls security_socket_{send,recv}msg(),
+which does security checks (e.g. SELinux) for socket access against the
+current task. However, _sock_xmit() in drivers/block/nbd.c may be called
+indirectly from a userspace syscall, where the NBD socket access would
+be incorrectly checked against the calling userspace task (which simply
+tries to read/write a file that happens to reside on an NBD device).
+
+To fix this, temporarily override creds to kernel ones before calling
+the sock_*() functions. This allows the security modules to recognize
+this as internal access by the kernel, which will normally be allowed.
+
+A way to trigger the issue is to do the following (on a system with
+SELinux set to enforcing):
+
+ ### Create nbd device:
+ truncate -s 256M /tmp/testfile
+ nbd-server localhost:10809 /tmp/testfile
+
+ ### Connect to the nbd server:
+ nbd-client localhost
+
+ ### Create mdraid array
+ mdadm --create -l 1 -n 2 /dev/md/testarray /dev/nbd0 missing
+
+After these steps, assuming the SELinux policy doesn't allow the
+unexpected access pattern, errors will be visible on the kernel console:
+
+[ 142.204243] nbd0: detected capacity change from 0 to 524288
+[ 165.189967] md: async del_gendisk mode will be removed in future, please upgrade to mdadm-4.5+
+[ 165.252299] md/raid1:md127: active with 1 out of 2 mirrors
+[ 165.252725] md127: detected capacity change from 0 to 522240
+[ 165.255434] block nbd0: Send control failed (result -13)
+[ 165.255718] block nbd0: Request send failed, requeueing
+[ 165.256006] block nbd0: Dead connection, failed to find a fallback
+[ 165.256041] block nbd0: Receive control failed (result -32)
+[ 165.256423] block nbd0: shutting down sockets
+[ 165.257196] I/O error, dev nbd0, sector 2048 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2
+[ 165.257736] Buffer I/O error on dev md127, logical block 0, async page read
+[ 165.258263] I/O error, dev nbd0, sector 2048 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2
+[ 165.259376] Buffer I/O error on dev md127, logical block 0, async page read
+[ 165.259920] I/O error, dev nbd0, sector 2048 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2
+[ 165.260628] Buffer I/O error on dev md127, logical block 0, async page read
+[ 165.261661] ldm_validate_partition_table(): Disk read failed.
+[ 165.262108] I/O error, dev nbd0, sector 2048 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2
+[ 165.262769] Buffer I/O error on dev md127, logical block 0, async page read
+[ 165.263697] I/O error, dev nbd0, sector 2048 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2
+[ 165.264412] Buffer I/O error on dev md127, logical block 0, async page read
+[ 165.265412] I/O error, dev nbd0, sector 2048 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2
+[ 165.265872] Buffer I/O error on dev md127, logical block 0, async page read
+[ 165.266378] I/O error, dev nbd0, sector 2048 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2
+[ 165.267168] Buffer I/O error on dev md127, logical block 0, async page read
+[ 165.267564] md127: unable to read partition table
+[ 165.269581] I/O error, dev nbd0, sector 0 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2
+[ 165.269960] Buffer I/O error on dev nbd0, logical block 0, async page read
+[ 165.270316] I/O error, dev nbd0, sector 0 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2
+[ 165.270913] Buffer I/O error on dev nbd0, logical block 0, async page read
+[ 165.271253] I/O error, dev nbd0, sector 0 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2
+[ 165.271809] Buffer I/O error on dev nbd0, logical block 0, async page read
+[ 165.272074] ldm_validate_partition_table(): Disk read failed.
+[ 165.272360] nbd0: unable to read partition table
+[ 165.289004] ldm_validate_partition_table(): Disk read failed.
+[ 165.289614] nbd0: unable to read partition table
+
+The corresponding SELinux denial on Fedora/RHEL will look like this
+(assuming it's not silenced):
+type=AVC msg=audit(1758104872.510:116): avc: denied { write } for pid=1908 comm="mdadm" laddr=::1 lport=32772 faddr=::1 fport=10809 scontext=system_u:system_r:mdadm_t:s0-s0:c0.c1023 tcontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tclass=tcp_socket permissive=0
+
+The respective backtrace looks like this:
+@security[mdadm, -13,
+ handshake_exit+221615650
+ handshake_exit+221615650
+ handshake_exit+221616465
+ security_socket_sendmsg+5
+ sock_sendmsg+106
+ handshake_exit+221616150
+ sock_sendmsg+5
+ __sock_xmit+162
+ nbd_send_cmd+597
+ nbd_handle_cmd+377
+ nbd_queue_rq+63
+ blk_mq_dispatch_rq_list+653
+ __blk_mq_do_dispatch_sched+184
+ __blk_mq_sched_dispatch_requests+333
+ blk_mq_sched_dispatch_requests+38
+ blk_mq_run_hw_queue+239
+ blk_mq_dispatch_plug_list+382
+ blk_mq_flush_plug_list.part.0+55
+ __blk_flush_plug+241
+ __submit_bio+353
+ submit_bio_noacct_nocheck+364
+ submit_bio_wait+84
+ __blkdev_direct_IO_simple+232
+ blkdev_read_iter+162
+ vfs_read+591
+ ksys_read+95
+ do_syscall_64+92
+ entry_SYSCALL_64_after_hwframe+120
+]: 1
+
+The issue has started to appear since commit 060406c61c7c ("block: add
+plug while submitting IO").
+
+Cc: Ming Lei <ming.lei@redhat.com>
+Link: https://bugzilla.redhat.com/show_bug.cgi?id=2348878
+Fixes: 060406c61c7c ("block: add plug while submitting IO")
+Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
+Acked-by: Paul Moore <paul@paul-moore.com>
+Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
+Reviewed-by: Ming Lei <ming.lei@redhat.com>
+Tested-by: Ming Lei <ming.lei@redhat.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/nbd.c | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
+index de692eed98740..deb298371a6a3 100644
+--- a/drivers/block/nbd.c
++++ b/drivers/block/nbd.c
+@@ -52,6 +52,7 @@
+ static DEFINE_IDR(nbd_index_idr);
+ static DEFINE_MUTEX(nbd_index_mutex);
+ static struct workqueue_struct *nbd_del_wq;
++static struct cred *nbd_cred;
+ static int nbd_total_devices = 0;
+
+ struct nbd_sock {
+@@ -557,6 +558,7 @@ static int __sock_xmit(struct nbd_device *nbd, struct socket *sock, int send,
+ int result;
+ struct msghdr msg = {} ;
+ unsigned int noreclaim_flag;
++ const struct cred *old_cred;
+
+ if (unlikely(!sock)) {
+ dev_err_ratelimited(disk_to_dev(nbd->disk),
+@@ -565,6 +567,8 @@ static int __sock_xmit(struct nbd_device *nbd, struct socket *sock, int send,
+ return -EINVAL;
+ }
+
++ old_cred = override_creds(nbd_cred);
++
+ msg.msg_iter = *iter;
+
+ noreclaim_flag = memalloc_noreclaim_save();
+@@ -589,6 +593,8 @@ static int __sock_xmit(struct nbd_device *nbd, struct socket *sock, int send,
+
+ memalloc_noreclaim_restore(noreclaim_flag);
+
++ revert_creds(old_cred);
++
+ return result;
+ }
+
+@@ -2605,7 +2611,15 @@ static int __init nbd_init(void)
+ return -ENOMEM;
+ }
+
++ nbd_cred = prepare_kernel_cred(&init_task);
++ if (!nbd_cred) {
++ destroy_workqueue(nbd_del_wq);
++ unregister_blkdev(NBD_MAJOR, "nbd");
++ return -ENOMEM;
++ }
++
+ if (genl_register_family(&nbd_genl_family)) {
++ put_cred(nbd_cred);
+ destroy_workqueue(nbd_del_wq);
+ unregister_blkdev(NBD_MAJOR, "nbd");
+ return -EINVAL;
+@@ -2660,6 +2674,7 @@ static void __exit nbd_cleanup(void)
+ /* Also wait for nbd_dev_remove_work() completes */
+ destroy_workqueue(nbd_del_wq);
+
++ put_cred(nbd_cred);
+ idr_destroy(&nbd_index_idr);
+ unregister_blkdev(NBD_MAJOR, "nbd");
+ }
+--
+2.51.0
+
--- /dev/null
+From c475f368a902235612a7a2441bd3395ea7eeabd1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Oct 2025 21:30:05 -0600
+Subject: RISC-V: Define pgprot_dmacoherent() for non-coherent devices
+
+From: Anup Patel <apatel@ventanamicro.com>
+
+[ Upstream commit ca525d53f994d45c8140968b571372c45f555ac1 ]
+
+The pgprot_dmacoherent() is used when allocating memory for
+non-coherent devices and by default pgprot_dmacoherent() is
+same as pgprot_noncached() unless architecture overrides it.
+
+Currently, there is no pgprot_dmacoherent() definition for
+RISC-V hence non-coherent device memory is being mapped as
+IO thereby making CPU access to such memory slow.
+
+Define pgprot_dmacoherent() to be same as pgprot_writecombine()
+for RISC-V so that CPU access non-coherent device memory as
+NOCACHE which is better than accessing it as IO.
+
+Fixes: ff689fd21cb1 ("riscv: add RISC-V Svpbmt extension support")
+Signed-off-by: Anup Patel <apatel@ventanamicro.com>
+Tested-by: Han Gao <rabenda.cn@gmail.com>
+Tested-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
+Link: https://lore.kernel.org/r/20250820152316.1012757-1-apatel@ventanamicro.com
+Signed-off-by: Paul Walmsley <pjw@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/include/asm/pgtable.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
+index 03881122506a7..87c7d94c71f13 100644
+--- a/arch/riscv/include/asm/pgtable.h
++++ b/arch/riscv/include/asm/pgtable.h
+@@ -655,6 +655,8 @@ static inline pgprot_t pgprot_writecombine(pgprot_t _prot)
+ return __pgprot(prot);
+ }
+
++#define pgprot_dmacoherent pgprot_writecombine
++
+ /*
+ * THP functions
+ */
+--
+2.51.0
+
--- /dev/null
+From c818603649f85f7b45854af3fed7790e2337655b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Oct 2025 22:00:09 +0530
+Subject: RISC-V: Don't print details of CPUs disabled in DT
+
+From: Anup Patel <apatel@ventanamicro.com>
+
+[ Upstream commit d2721bb165b3ee00dd23525885381af07fec852a ]
+
+Early boot stages may disable CPU DT nodes for unavailable
+CPUs based on SKU, pinstraps, eFuse, etc. Currently, the
+riscv_early_of_processor_hartid() prints details of a CPU
+if it is disabled in DT which has no value and gives a
+false impression to the users that there some issue with
+the CPU.
+
+Fixes: e3d794d555cd ("riscv: treat cpu devicetree nodes without status as enabled")
+Signed-off-by: Anup Patel <apatel@ventanamicro.com>
+Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Link: https://lore.kernel.org/r/20251014163009.182381-1-apatel@ventanamicro.com
+Signed-off-by: Paul Walmsley <pjw@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/cpu.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c
+index f6b13e9f5e6cb..3dbc8cc557dd1 100644
+--- a/arch/riscv/kernel/cpu.c
++++ b/arch/riscv/kernel/cpu.c
+@@ -62,10 +62,8 @@ int __init riscv_early_of_processor_hartid(struct device_node *node, unsigned lo
+ return -ENODEV;
+ }
+
+- if (!of_device_is_available(node)) {
+- pr_info("CPU with hartid=%lu is not available\n", *hart);
++ if (!of_device_is_available(node))
+ return -ENODEV;
+- }
+
+ if (of_property_read_string(node, "riscv,isa-base", &isa))
+ goto old_interface;
+--
+2.51.0
+
--- /dev/null
+From d6409eeb9696d633c25955f4efbc944a3cd294da Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 18 Oct 2025 09:32:12 -0600
+Subject: riscv: hwprobe: avoid uninitialized variable use in hwprobe_arch_id()
+
+From: Paul Walmsley <pjw@kernel.org>
+
+[ Upstream commit b7776a802f2f80139f96530a489dd00fd7089eda ]
+
+Resolve this smatch warning:
+
+ arch/riscv/kernel/sys_hwprobe.c:50 hwprobe_arch_id() error: uninitialized symbol 'cpu_id'.
+
+This could happen if hwprobe_arch_id() was called with a key ID of
+something other than MVENDORID, MIMPID, and MARCHID. This does not
+happen in the current codebase. The only caller of hwprobe_arch_id()
+is a function that only passes one of those three key IDs.
+
+For the sake of reducing static analyzer warning noise, and in the
+unlikely event that hwprobe_arch_id() is someday called with some
+other key ID, validate hwprobe_arch_id()'s input to ensure that
+'cpu_id' is always initialized before use.
+
+Fixes: ea3de9ce8aa280 ("RISC-V: Add a syscall for HW probing")
+Cc: Evan Green <evan@rivosinc.com>
+Signed-off-by: Paul Walmsley <pjw@kernel.org>
+Link: https://lore.kernel.org/r/cf5a13ec-19d0-9862-059b-943f36107bf3@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/sys_hwprobe.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/arch/riscv/kernel/sys_hwprobe.c b/arch/riscv/kernel/sys_hwprobe.c
+index cea0ca2bf2a25..fc62548888c58 100644
+--- a/arch/riscv/kernel/sys_hwprobe.c
++++ b/arch/riscv/kernel/sys_hwprobe.c
+@@ -25,6 +25,11 @@ static void hwprobe_arch_id(struct riscv_hwprobe *pair,
+ bool first = true;
+ int cpu;
+
++ if (pair->key != RISCV_HWPROBE_KEY_MVENDORID &&
++ pair->key != RISCV_HWPROBE_KEY_MIMPID &&
++ pair->key != RISCV_HWPROBE_KEY_MARCHID)
++ goto out;
++
+ for_each_cpu(cpu, cpus) {
+ u64 cpu_id;
+
+@@ -55,6 +60,7 @@ static void hwprobe_arch_id(struct riscv_hwprobe *pair,
+ }
+ }
+
++out:
+ pair->value = id;
+ }
+
+--
+2.51.0
+
--- /dev/null
+From 87d6b3954328eabb1b80712a6a80d1abbdd6c6c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Oct 2025 11:19:34 +0200
+Subject: sched: Remove never used code in mm_cid_get()
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 53abe3e1c154628cc74e33a1bfcd865656e433a5 ]
+
+Clang is not happy with set but unused variable (this is visible
+with `make W=1` build:
+
+ kernel/sched/sched.h:3744:18: error: variable 'cpumask' set but not used [-Werror,-Wunused-but-set-variable]
+
+It seems like the variable was never used along with the assignment
+that does not have side effects as far as I can see. Remove those
+altogether.
+
+Fixes: 223baf9d17f2 ("sched: Fix performance regression introduced by mm_cid")
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Tested-by: Eric Biggers <ebiggers@kernel.org>
+Reviewed-by: Breno Leitao <leitao@debian.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/sched.h | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
+index a441990fe808d..cf541c4502d92 100644
+--- a/kernel/sched/sched.h
++++ b/kernel/sched/sched.h
+@@ -3731,11 +3731,9 @@ static inline int __mm_cid_get(struct rq *rq, struct mm_struct *mm)
+ static inline int mm_cid_get(struct rq *rq, struct mm_struct *mm)
+ {
+ struct mm_cid __percpu *pcpu_cid = mm->pcpu_cid;
+- struct cpumask *cpumask;
+ int cid;
+
+ lockdep_assert_rq_held(rq);
+- cpumask = mm_cidmask(mm);
+ cid = __this_cpu_read(pcpu_cid->cid);
+ if (mm_cid_is_valid(cid)) {
+ mm_cid_snapshot_time(rq, mm);
+--
+2.51.0
+
sctp-avoid-null-dereference-when-chunk-data-buffer-i.patch
net-phy-micrel-always-set-shared-phydev-for-lan8814.patch
net-mlx5-fix-ipsec-cleanup-over-mpv-device.patch
+spi-spi-nxp-fspi-add-extra-delay-after-dll-locked.patch
+arm64-dts-broadcom-bcm2712-add-default-gic-address-c.patch
+arm64-dts-broadcom-bcm2712-define-vgic-interrupt.patch
+firmware-arm_scmi-account-for-failed-debug-initializ.patch
+firmware-arm_scmi-fix-premature-scmi_xfer_flag_is_ra.patch
+spi-airoha-return-an-error-for-continuous-mode-dirma.patch
+spi-airoha-add-support-of-dual-quad-wires-spi-modes-.patch
+spi-airoha-do-not-keep-tx-rx-dma-buffer-always-mappe.patch
+spi-airoha-switch-back-to-non-dma-mode-in-the-case-o.patch
+spi-airoha-fix-reading-writing-of-flashes-with-more-.patch
+drm-panthor-fix-kernel-panic-on-partial-unmap-of-a-g.patch
+risc-v-define-pgprot_dmacoherent-for-non-coherent-de.patch
+risc-v-don-t-print-details-of-cpus-disabled-in-dt.patch
+riscv-hwprobe-avoid-uninitialized-variable-use-in-hw.patch
+hwmon-sht3x-fix-error-handling.patch
+nbd-override-creds-to-kernel-when-calling-sock_-send.patch
+drm-panic-fix-drawing-the-logo-on-a-small-narrow-scr.patch
+drm-panic-fix-qr_code-ensure-vmargin-is-positive.patch
+gpio-ljca-fix-duplicated-irq-mapping.patch
+io_uring-correct-__must_hold-annotation-in-io_instal.patch
+sched-remove-never-used-code-in-mm_cid_get.patch
--- /dev/null
+From c093c23806292cbc9d3e1daa4b4c9b2c0a8df434 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Oct 2025 15:16:54 +0300
+Subject: spi: airoha: add support of dual/quad wires spi modes to exec_op()
+ handler
+
+From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+
+[ Upstream commit edd2e261b1babb92213089b5feadca12e3459322 ]
+
+Booting without this patch and disabled dirmap support results in
+
+[ 2.980719] spi-nand spi0.0: Micron SPI NAND was found.
+[ 2.986040] spi-nand spi0.0: 256 MiB, block size: 128 KiB, page size: 2048, OOB size: 128
+[ 2.994709] 2 fixed-partitions partitions found on MTD device spi0.0
+[ 3.001075] Creating 2 MTD partitions on "spi0.0":
+[ 3.005862] 0x000000000000-0x000000020000 : "bl2"
+[ 3.011272] 0x000000020000-0x000010000000 : "ubi"
+...
+[ 6.195594] ubi0: attaching mtd1
+[ 13.338398] ubi0: scanning is finished
+[ 13.342188] ubi0 error: ubi_read_volume_table: the layout volume was not found
+[ 13.349784] ubi0 error: ubi_attach_mtd_dev: failed to attach mtd1, error -22
+[ 13.356897] UBI error: cannot attach mtd1
+
+If dirmap is disabled or not supported in the spi driver, the dirmap requests
+will be executed via exec_op() handler. Thus, if the hardware supports
+dual/quad spi modes, then corresponding requests will be sent to exec_op()
+handler. Current driver does not support such requests, so error is arrised.
+As result the flash can't be read/write.
+
+This patch adds support of dual and quad wires spi modes to exec_op() handler.
+
+Fixes: a403997c12019 ("spi: airoha: add SPI-NAND Flash controller driver")
+Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://patch.msgid.link/20251012121707.2296160-4-mikhail.kshevetskiy@iopsys.eu
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-airoha-snfi.c | 108 ++++++++++++++++++++++++++--------
+ 1 file changed, 82 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/spi/spi-airoha-snfi.c b/drivers/spi/spi-airoha-snfi.c
+index 6930dea48f330..a3f766e04202f 100644
+--- a/drivers/spi/spi-airoha-snfi.c
++++ b/drivers/spi/spi-airoha-snfi.c
+@@ -192,6 +192,14 @@
+ #define SPI_NAND_OP_RESET 0xff
+ #define SPI_NAND_OP_DIE_SELECT 0xc2
+
++/* SNAND FIFO commands */
++#define SNAND_FIFO_TX_BUSWIDTH_SINGLE 0x08
++#define SNAND_FIFO_TX_BUSWIDTH_DUAL 0x09
++#define SNAND_FIFO_TX_BUSWIDTH_QUAD 0x0a
++#define SNAND_FIFO_RX_BUSWIDTH_SINGLE 0x0c
++#define SNAND_FIFO_RX_BUSWIDTH_DUAL 0x0e
++#define SNAND_FIFO_RX_BUSWIDTH_QUAD 0x0f
++
+ #define SPI_NAND_CACHE_SIZE (SZ_4K + SZ_256)
+ #define SPI_MAX_TRANSFER_SIZE 511
+
+@@ -394,10 +402,26 @@ static int airoha_snand_set_mode(struct airoha_snand_ctrl *as_ctrl,
+ return regmap_write(as_ctrl->regmap_ctrl, REG_SPI_CTRL_DUMMY, 0);
+ }
+
+-static int airoha_snand_write_data(struct airoha_snand_ctrl *as_ctrl, u8 cmd,
+- const u8 *data, int len)
++static int airoha_snand_write_data(struct airoha_snand_ctrl *as_ctrl,
++ const u8 *data, int len, int buswidth)
+ {
+ int i, data_len;
++ u8 cmd;
++
++ switch (buswidth) {
++ case 0:
++ case 1:
++ cmd = SNAND_FIFO_TX_BUSWIDTH_SINGLE;
++ break;
++ case 2:
++ cmd = SNAND_FIFO_TX_BUSWIDTH_DUAL;
++ break;
++ case 4:
++ cmd = SNAND_FIFO_TX_BUSWIDTH_QUAD;
++ break;
++ default:
++ return -EINVAL;
++ }
+
+ for (i = 0; i < len; i += data_len) {
+ int err;
+@@ -416,16 +440,32 @@ static int airoha_snand_write_data(struct airoha_snand_ctrl *as_ctrl, u8 cmd,
+ return 0;
+ }
+
+-static int airoha_snand_read_data(struct airoha_snand_ctrl *as_ctrl, u8 *data,
+- int len)
++static int airoha_snand_read_data(struct airoha_snand_ctrl *as_ctrl,
++ u8 *data, int len, int buswidth)
+ {
+ int i, data_len;
++ u8 cmd;
++
++ switch (buswidth) {
++ case 0:
++ case 1:
++ cmd = SNAND_FIFO_RX_BUSWIDTH_SINGLE;
++ break;
++ case 2:
++ cmd = SNAND_FIFO_RX_BUSWIDTH_DUAL;
++ break;
++ case 4:
++ cmd = SNAND_FIFO_RX_BUSWIDTH_QUAD;
++ break;
++ default:
++ return -EINVAL;
++ }
+
+ for (i = 0; i < len; i += data_len) {
+ int err;
+
+ data_len = min(len - i, SPI_MAX_TRANSFER_SIZE);
+- err = airoha_snand_set_fifo_op(as_ctrl, 0xc, data_len);
++ err = airoha_snand_set_fifo_op(as_ctrl, cmd, data_len);
+ if (err)
+ return err;
+
+@@ -891,12 +931,28 @@ static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc,
+ static int airoha_snand_exec_op(struct spi_mem *mem,
+ const struct spi_mem_op *op)
+ {
+- u8 data[8], cmd, opcode = op->cmd.opcode;
+ struct airoha_snand_ctrl *as_ctrl;
++ int op_len, addr_len, dummy_len;
++ u8 buf[20], *data;
+ int i, err;
+
+ as_ctrl = spi_controller_get_devdata(mem->spi->controller);
+
++ op_len = op->cmd.nbytes;
++ addr_len = op->addr.nbytes;
++ dummy_len = op->dummy.nbytes;
++
++ if (op_len + dummy_len + addr_len > sizeof(buf))
++ return -EIO;
++
++ data = buf;
++ for (i = 0; i < op_len; i++)
++ *data++ = op->cmd.opcode >> (8 * (op_len - i - 1));
++ for (i = 0; i < addr_len; i++)
++ *data++ = op->addr.val >> (8 * (addr_len - i - 1));
++ for (i = 0; i < dummy_len; i++)
++ *data++ = 0xff;
++
+ /* switch to manual mode */
+ err = airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL);
+ if (err < 0)
+@@ -907,40 +963,40 @@ static int airoha_snand_exec_op(struct spi_mem *mem,
+ return err;
+
+ /* opcode */
+- err = airoha_snand_write_data(as_ctrl, 0x8, &opcode, sizeof(opcode));
++ data = buf;
++ err = airoha_snand_write_data(as_ctrl, data, op_len,
++ op->cmd.buswidth);
+ if (err)
+ return err;
+
+ /* addr part */
+- cmd = opcode == SPI_NAND_OP_GET_FEATURE ? 0x11 : 0x8;
+- put_unaligned_be64(op->addr.val, data);
+-
+- for (i = ARRAY_SIZE(data) - op->addr.nbytes;
+- i < ARRAY_SIZE(data); i++) {
+- err = airoha_snand_write_data(as_ctrl, cmd, &data[i],
+- sizeof(data[0]));
++ data += op_len;
++ if (addr_len) {
++ err = airoha_snand_write_data(as_ctrl, data, addr_len,
++ op->addr.buswidth);
+ if (err)
+ return err;
+ }
+
+ /* dummy */
+- data[0] = 0xff;
+- for (i = 0; i < op->dummy.nbytes; i++) {
+- err = airoha_snand_write_data(as_ctrl, 0x8, &data[0],
+- sizeof(data[0]));
++ data += addr_len;
++ if (dummy_len) {
++ err = airoha_snand_write_data(as_ctrl, data, dummy_len,
++ op->dummy.buswidth);
+ if (err)
+ return err;
+ }
+
+ /* data */
+- if (op->data.dir == SPI_MEM_DATA_IN) {
+- err = airoha_snand_read_data(as_ctrl, op->data.buf.in,
+- op->data.nbytes);
+- if (err)
+- return err;
+- } else {
+- err = airoha_snand_write_data(as_ctrl, 0x8, op->data.buf.out,
+- op->data.nbytes);
++ if (op->data.nbytes) {
++ if (op->data.dir == SPI_MEM_DATA_IN)
++ err = airoha_snand_read_data(as_ctrl, op->data.buf.in,
++ op->data.nbytes,
++ op->data.buswidth);
++ else
++ err = airoha_snand_write_data(as_ctrl, op->data.buf.out,
++ op->data.nbytes,
++ op->data.buswidth);
+ if (err)
+ return err;
+ }
+--
+2.51.0
+
--- /dev/null
+From d42b8b20c22dd8bd7efed3dc6fff3c1c7b2e87c8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 22 Sep 2024 19:38:30 +0200
+Subject: spi: airoha: do not keep {tx,rx} dma buffer always mapped
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ Upstream commit 7a4b3ebf1d60349587fee21872536e7bd6a4cf39 ]
+
+DMA map txrx_buf on demand in airoha_snand_dirmap_read and
+airoha_snand_dirmap_write routines and do not keep it always mapped.
+This patch is not fixing any bug or introducing any functional change
+to the driver, it just simplifies the code and improve code readability
+without introducing any performance degradation according to the results
+obtained from the mtd_speedtest kernel module test.
+
+root@OpenWrt:# insmod mtd_test.ko
+root@OpenWrt:# insmod mtd_speedtest.ko dev=5
+[ 49.849869] =================================================
+[ 49.855659] mtd_speedtest: MTD device: 5
+[ 49.859583] mtd_speedtest: MTD device size 8388608, eraseblock size 131072, page size 2048, count of eraseblocks 64, pages per eraseblock 64, OOB size 128
+[ 49.874622] mtd_test: scanning for bad eraseblocks
+[ 49.879433] mtd_test: scanned 64 eraseblocks, 0 are bad
+[ 50.106372] mtd_speedtest: testing eraseblock write speed
+[ 53.083380] mtd_speedtest: eraseblock write speed is 2756 KiB/s
+[ 53.089322] mtd_speedtest: testing eraseblock read speed
+[ 54.143360] mtd_speedtest: eraseblock read speed is 7811 KiB/s
+[ 54.370365] mtd_speedtest: testing page write speed
+[ 57.349480] mtd_speedtest: page write speed is 2754 KiB/s
+[ 57.354895] mtd_speedtest: testing page read speed
+[ 58.410431] mtd_speedtest: page read speed is 7796 KiB/s
+[ 58.636805] mtd_speedtest: testing 2 page write speed
+[ 61.612427] mtd_speedtest: 2 page write speed is 2757 KiB/s
+[ 61.618021] mtd_speedtest: testing 2 page read speed
+[ 62.672653] mtd_speedtest: 2 page read speed is 7804 KiB/s
+[ 62.678159] mtd_speedtest: Testing erase speed
+[ 62.903617] mtd_speedtest: erase speed is 37063 KiB/s
+[ 62.908678] mtd_speedtest: Testing 2x multi-block erase speed
+[ 63.134083] mtd_speedtest: 2x multi-block erase speed is 37292 KiB/s
+[ 63.140442] mtd_speedtest: Testing 4x multi-block erase speed
+[ 63.364262] mtd_speedtest: 4x multi-block erase speed is 37566 KiB/s
+[ 63.370632] mtd_speedtest: Testing 8x multi-block erase speed
+[ 63.595740] mtd_speedtest: 8x multi-block erase speed is 37344 KiB/s
+[ 63.602089] mtd_speedtest: Testing 16x multi-block erase speed
+[ 63.827426] mtd_speedtest: 16x multi-block erase speed is 37320 KiB/s
+[ 63.833860] mtd_speedtest: Testing 32x multi-block erase speed
+[ 64.059389] mtd_speedtest: 32x multi-block erase speed is 37288 KiB/s
+[ 64.065833] mtd_speedtest: Testing 64x multi-block erase speed
+[ 64.290609] mtd_speedtest: 64x multi-block erase speed is 37415 KiB/s
+[ 64.297063] mtd_speedtest: finished
+[ 64.300555] =================================================
+
+Tested-by: Christian Marangi <ansuelsmth@gmail.com>
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://patch.msgid.link/20240922-airoha-spi-fixes-v3-1-f958802b3d68@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 20d7b236b78c ("spi: airoha: switch back to non-dma mode in the case of error")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-airoha-snfi.c | 154 ++++++++++++++++------------------
+ 1 file changed, 71 insertions(+), 83 deletions(-)
+
+diff --git a/drivers/spi/spi-airoha-snfi.c b/drivers/spi/spi-airoha-snfi.c
+index a3f766e04202f..0b89dc42545b1 100644
+--- a/drivers/spi/spi-airoha-snfi.c
++++ b/drivers/spi/spi-airoha-snfi.c
+@@ -214,13 +214,6 @@ enum airoha_snand_cs {
+ SPI_CHIP_SEL_LOW,
+ };
+
+-struct airoha_snand_dev {
+- size_t buf_len;
+-
+- u8 *txrx_buf;
+- dma_addr_t dma_addr;
+-};
+-
+ struct airoha_snand_ctrl {
+ struct device *dev;
+ struct regmap *regmap_ctrl;
+@@ -657,9 +650,9 @@ static bool airoha_snand_supports_op(struct spi_mem *mem,
+
+ static int airoha_snand_dirmap_create(struct spi_mem_dirmap_desc *desc)
+ {
+- struct airoha_snand_dev *as_dev = spi_get_ctldata(desc->mem->spi);
++ u8 *txrx_buf = spi_get_ctldata(desc->mem->spi);
+
+- if (!as_dev->txrx_buf)
++ if (!txrx_buf)
+ return -EINVAL;
+
+ if (desc->info.offset + desc->info.length > U32_MAX)
+@@ -678,10 +671,11 @@ static int airoha_snand_dirmap_create(struct spi_mem_dirmap_desc *desc)
+ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc,
+ u64 offs, size_t len, void *buf)
+ {
+- struct spi_device *spi = desc->mem->spi;
+- struct airoha_snand_dev *as_dev = spi_get_ctldata(spi);
+ struct spi_mem_op *op = &desc->info.op_tmpl;
++ struct spi_device *spi = desc->mem->spi;
+ struct airoha_snand_ctrl *as_ctrl;
++ u8 *txrx_buf = spi_get_ctldata(spi);
++ dma_addr_t dma_addr;
+ u32 val, rd_mode;
+ int err;
+
+@@ -706,14 +700,17 @@ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc,
+ if (err)
+ return err;
+
+- dma_sync_single_for_device(as_ctrl->dev, as_dev->dma_addr,
+- as_dev->buf_len, DMA_BIDIRECTIONAL);
++ dma_addr = dma_map_single(as_ctrl->dev, txrx_buf, SPI_NAND_CACHE_SIZE,
++ DMA_FROM_DEVICE);
++ err = dma_mapping_error(as_ctrl->dev, dma_addr);
++ if (err)
++ return err;
+
+ /* set dma addr */
+ err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_STRADDR,
+- as_dev->dma_addr);
++ dma_addr);
+ if (err)
+- return err;
++ goto error_dma_unmap;
+
+ /* set cust sec size */
+ val = as_ctrl->nfi_cfg.sec_size * as_ctrl->nfi_cfg.sec_num;
+@@ -722,58 +719,58 @@ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc,
+ REG_SPI_NFI_SNF_MISC_CTL2,
+ SPI_NFI_READ_DATA_BYTE_NUM, val);
+ if (err)
+- return err;
++ goto error_dma_unmap;
+
+ /* set read command */
+ err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_RD_CTL2,
+ op->cmd.opcode);
+ if (err)
+- return err;
++ goto error_dma_unmap;
+
+ /* set read mode */
+ err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_SNF_MISC_CTL,
+ FIELD_PREP(SPI_NFI_DATA_READ_WR_MODE, rd_mode));
+ if (err)
+- return err;
++ goto error_dma_unmap;
+
+ /* set read addr */
+ err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_RD_CTL3, 0x0);
+ if (err)
+- return err;
++ goto error_dma_unmap;
+
+ /* set nfi read */
+ err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG,
+ SPI_NFI_OPMODE,
+ FIELD_PREP(SPI_NFI_OPMODE, 6));
+ if (err)
+- return err;
++ goto error_dma_unmap;
+
+ err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG,
+ SPI_NFI_READ_MODE | SPI_NFI_DMA_MODE);
+ if (err)
+- return err;
++ goto error_dma_unmap;
+
+ err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_CMD, 0x0);
+ if (err)
+- return err;
++ goto error_dma_unmap;
+
+ /* trigger dma start read */
+ err = regmap_clear_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON,
+ SPI_NFI_RD_TRIG);
+ if (err)
+- return err;
++ goto error_dma_unmap;
+
+ err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON,
+ SPI_NFI_RD_TRIG);
+ if (err)
+- return err;
++ goto error_dma_unmap;
+
+ err = regmap_read_poll_timeout(as_ctrl->regmap_nfi,
+ REG_SPI_NFI_SNF_STA_CTL1, val,
+ (val & SPI_NFI_READ_FROM_CACHE_DONE),
+ 0, 1 * USEC_PER_SEC);
+ if (err)
+- return err;
++ goto error_dma_unmap;
+
+ /*
+ * SPI_NFI_READ_FROM_CACHE_DONE bit must be written at the end
+@@ -783,35 +780,41 @@ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc,
+ SPI_NFI_READ_FROM_CACHE_DONE,
+ SPI_NFI_READ_FROM_CACHE_DONE);
+ if (err)
+- return err;
++ goto error_dma_unmap;
+
+ err = regmap_read_poll_timeout(as_ctrl->regmap_nfi, REG_SPI_NFI_INTR,
+ val, (val & SPI_NFI_AHB_DONE), 0,
+ 1 * USEC_PER_SEC);
+ if (err)
+- return err;
++ goto error_dma_unmap;
+
+ /* DMA read need delay for data ready from controller to DRAM */
+ udelay(1);
+
+- dma_sync_single_for_cpu(as_ctrl->dev, as_dev->dma_addr,
+- as_dev->buf_len, DMA_BIDIRECTIONAL);
++ dma_unmap_single(as_ctrl->dev, dma_addr, SPI_NAND_CACHE_SIZE,
++ DMA_FROM_DEVICE);
+ err = airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL);
+ if (err < 0)
+ return err;
+
+- memcpy(buf, as_dev->txrx_buf + offs, len);
++ memcpy(buf, txrx_buf + offs, len);
+
+ return len;
++
++error_dma_unmap:
++ dma_unmap_single(as_ctrl->dev, dma_addr, SPI_NAND_CACHE_SIZE,
++ DMA_FROM_DEVICE);
++ return err;
+ }
+
+ static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc,
+ u64 offs, size_t len, const void *buf)
+ {
+- struct spi_device *spi = desc->mem->spi;
+- struct airoha_snand_dev *as_dev = spi_get_ctldata(spi);
+ struct spi_mem_op *op = &desc->info.op_tmpl;
++ struct spi_device *spi = desc->mem->spi;
++ u8 *txrx_buf = spi_get_ctldata(spi);
+ struct airoha_snand_ctrl *as_ctrl;
++ dma_addr_t dma_addr;
+ u32 wr_mode, val;
+ int err;
+
+@@ -820,19 +823,20 @@ static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc,
+ if (err < 0)
+ return err;
+
+- dma_sync_single_for_cpu(as_ctrl->dev, as_dev->dma_addr,
+- as_dev->buf_len, DMA_BIDIRECTIONAL);
+- memcpy(as_dev->txrx_buf + offs, buf, len);
+- dma_sync_single_for_device(as_ctrl->dev, as_dev->dma_addr,
+- as_dev->buf_len, DMA_BIDIRECTIONAL);
++ memcpy(txrx_buf + offs, buf, len);
++ dma_addr = dma_map_single(as_ctrl->dev, txrx_buf, SPI_NAND_CACHE_SIZE,
++ DMA_TO_DEVICE);
++ err = dma_mapping_error(as_ctrl->dev, dma_addr);
++ if (err)
++ return err;
+
+ err = airoha_snand_set_mode(as_ctrl, SPI_MODE_DMA);
+ if (err < 0)
+- return err;
++ goto error_dma_unmap;
+
+ err = airoha_snand_nfi_config(as_ctrl);
+ if (err)
+- return err;
++ goto error_dma_unmap;
+
+ if (op->cmd.opcode == SPI_NAND_OP_PROGRAM_LOAD_QUAD ||
+ op->cmd.opcode == SPI_NAND_OP_PROGRAM_LOAD_RAMDON_QUAD)
+@@ -841,9 +845,9 @@ static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc,
+ wr_mode = 0;
+
+ err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_STRADDR,
+- as_dev->dma_addr);
++ dma_addr);
+ if (err)
+- return err;
++ goto error_dma_unmap;
+
+ val = FIELD_PREP(SPI_NFI_PROG_LOAD_BYTE_NUM,
+ as_ctrl->nfi_cfg.sec_size * as_ctrl->nfi_cfg.sec_num);
+@@ -851,65 +855,65 @@ static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc,
+ REG_SPI_NFI_SNF_MISC_CTL2,
+ SPI_NFI_PROG_LOAD_BYTE_NUM, val);
+ if (err)
+- return err;
++ goto error_dma_unmap;
+
+ err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_PG_CTL1,
+ FIELD_PREP(SPI_NFI_PG_LOAD_CMD,
+ op->cmd.opcode));
+ if (err)
+- return err;
++ goto error_dma_unmap;
+
+ err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_SNF_MISC_CTL,
+ FIELD_PREP(SPI_NFI_DATA_READ_WR_MODE, wr_mode));
+ if (err)
+- return err;
++ goto error_dma_unmap;
+
+ err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_PG_CTL2, 0x0);
+ if (err)
+- return err;
++ goto error_dma_unmap;
+
+ err = regmap_clear_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG,
+ SPI_NFI_READ_MODE);
+ if (err)
+- return err;
++ goto error_dma_unmap;
+
+ err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG,
+ SPI_NFI_OPMODE,
+ FIELD_PREP(SPI_NFI_OPMODE, 3));
+ if (err)
+- return err;
++ goto error_dma_unmap;
+
+ err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG,
+ SPI_NFI_DMA_MODE);
+ if (err)
+- return err;
++ goto error_dma_unmap;
+
+ err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_CMD, 0x80);
+ if (err)
+- return err;
++ goto error_dma_unmap;
+
+ err = regmap_clear_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON,
+ SPI_NFI_WR_TRIG);
+ if (err)
+- return err;
++ goto error_dma_unmap;
+
+ err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON,
+ SPI_NFI_WR_TRIG);
+ if (err)
+- return err;
++ goto error_dma_unmap;
+
+ err = regmap_read_poll_timeout(as_ctrl->regmap_nfi, REG_SPI_NFI_INTR,
+ val, (val & SPI_NFI_AHB_DONE), 0,
+ 1 * USEC_PER_SEC);
+ if (err)
+- return err;
++ goto error_dma_unmap;
+
+ err = regmap_read_poll_timeout(as_ctrl->regmap_nfi,
+ REG_SPI_NFI_SNF_STA_CTL1, val,
+ (val & SPI_NFI_LOAD_TO_CACHE_DONE),
+ 0, 1 * USEC_PER_SEC);
+ if (err)
+- return err;
++ goto error_dma_unmap;
+
+ /*
+ * SPI_NFI_LOAD_TO_CACHE_DONE bit must be written at the end
+@@ -919,13 +923,20 @@ static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc,
+ SPI_NFI_LOAD_TO_CACHE_DONE,
+ SPI_NFI_LOAD_TO_CACHE_DONE);
+ if (err)
+- return err;
++ goto error_dma_unmap;
+
++ dma_unmap_single(as_ctrl->dev, dma_addr, SPI_NAND_CACHE_SIZE,
++ DMA_TO_DEVICE);
+ err = airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL);
+ if (err < 0)
+ return err;
+
+ return len;
++
++error_dma_unmap:
++ dma_unmap_single(as_ctrl->dev, dma_addr, SPI_NAND_CACHE_SIZE,
++ DMA_TO_DEVICE);
++ return err;
+ }
+
+ static int airoha_snand_exec_op(struct spi_mem *mem,
+@@ -1016,42 +1027,20 @@ static const struct spi_controller_mem_ops airoha_snand_mem_ops = {
+ static int airoha_snand_setup(struct spi_device *spi)
+ {
+ struct airoha_snand_ctrl *as_ctrl;
+- struct airoha_snand_dev *as_dev;
+-
+- as_ctrl = spi_controller_get_devdata(spi->controller);
+-
+- as_dev = devm_kzalloc(as_ctrl->dev, sizeof(*as_dev), GFP_KERNEL);
+- if (!as_dev)
+- return -ENOMEM;
++ u8 *txrx_buf;
+
+ /* prepare device buffer */
+- as_dev->buf_len = SPI_NAND_CACHE_SIZE;
+- as_dev->txrx_buf = devm_kzalloc(as_ctrl->dev, as_dev->buf_len,
+- GFP_KERNEL);
+- if (!as_dev->txrx_buf)
+- return -ENOMEM;
+-
+- as_dev->dma_addr = dma_map_single(as_ctrl->dev, as_dev->txrx_buf,
+- as_dev->buf_len, DMA_BIDIRECTIONAL);
+- if (dma_mapping_error(as_ctrl->dev, as_dev->dma_addr))
++ as_ctrl = spi_controller_get_devdata(spi->controller);
++ txrx_buf = devm_kzalloc(as_ctrl->dev, SPI_NAND_CACHE_SIZE,
++ GFP_KERNEL);
++ if (!txrx_buf)
+ return -ENOMEM;
+
+- spi_set_ctldata(spi, as_dev);
++ spi_set_ctldata(spi, txrx_buf);
+
+ return 0;
+ }
+
+-static void airoha_snand_cleanup(struct spi_device *spi)
+-{
+- struct airoha_snand_dev *as_dev = spi_get_ctldata(spi);
+- struct airoha_snand_ctrl *as_ctrl;
+-
+- as_ctrl = spi_controller_get_devdata(spi->controller);
+- dma_unmap_single(as_ctrl->dev, as_dev->dma_addr,
+- as_dev->buf_len, DMA_BIDIRECTIONAL);
+- spi_set_ctldata(spi, NULL);
+-}
+-
+ static int airoha_snand_nfi_setup(struct airoha_snand_ctrl *as_ctrl)
+ {
+ u32 val, sec_size, sec_num;
+@@ -1153,7 +1142,6 @@ static int airoha_snand_probe(struct platform_device *pdev)
+ ctrl->bits_per_word_mask = SPI_BPW_MASK(8);
+ ctrl->mode_bits = SPI_RX_DUAL;
+ ctrl->setup = airoha_snand_setup;
+- ctrl->cleanup = airoha_snand_cleanup;
+ device_set_node(&ctrl->dev, dev_fwnode(dev));
+
+ err = airoha_snand_nfi_setup(as_ctrl);
+--
+2.51.0
+
--- /dev/null
+From 5f8322edaff8a8d755f9d518d02539ec34f4cae5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Oct 2025 15:16:57 +0300
+Subject: spi: airoha: fix reading/writing of flashes with more than one plane
+ per lun
+
+From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+
+[ Upstream commit 0b7d9b25e4bc2e478c9d06281a65f930769fca09 ]
+
+Attaching UBI on the flash with more than one plane per lun will lead to
+the following error:
+
+[ 2.980989] spi-nand spi0.0: Micron SPI NAND was found.
+[ 2.986309] spi-nand spi0.0: 256 MiB, block size: 128 KiB, page size: 2048, OOB size: 128
+[ 2.994978] 2 fixed-partitions partitions found on MTD device spi0.0
+[ 3.001350] Creating 2 MTD partitions on "spi0.0":
+[ 3.006159] 0x000000000000-0x000000020000 : "bl2"
+[ 3.011663] 0x000000020000-0x000010000000 : "ubi"
+...
+[ 6.391748] ubi0: attaching mtd1
+[ 6.412545] ubi0 error: ubi_attach: PEB 0 contains corrupted VID header, and the data does not contain all 0xFF
+[ 6.422677] ubi0 error: ubi_attach: this may be a non-UBI PEB or a severe VID header corruption which requires manual inspection
+[ 6.434249] Volume identifier header dump:
+[ 6.438349] magic 55424923
+[ 6.441482] version 1
+[ 6.444007] vol_type 0
+[ 6.446539] copy_flag 0
+[ 6.449068] compat 0
+[ 6.451594] vol_id 0
+[ 6.454120] lnum 1
+[ 6.456651] data_size 4096
+[ 6.459442] used_ebs 1061644134
+[ 6.462748] data_pad 0
+[ 6.465274] sqnum 0
+[ 6.467805] hdr_crc 61169820
+[ 6.470943] Volume identifier header hexdump:
+[ 6.475308] hexdump of PEB 0 offset 4096, length 126976
+[ 6.507391] ubi0 warning: ubi_attach: valid VID header but corrupted EC header at PEB 4
+[ 6.515415] ubi0 error: ubi_compare_lebs: unsupported on-flash UBI format
+[ 6.522222] ubi0 error: ubi_attach_mtd_dev: failed to attach mtd1, error -22
+[ 6.529294] UBI error: cannot attach mtd1
+
+Non dirmap reading works good. Looking to spi_mem_no_dirmap_read() code we'll see:
+
+ static ssize_t spi_mem_no_dirmap_read(struct spi_mem_dirmap_desc *desc,
+ u64 offs, size_t len, void *buf)
+ {
+ struct spi_mem_op op = desc->info.op_tmpl;
+ int ret;
+
+// --- see here ---
+ op.addr.val = desc->info.offset + offs;
+//-----------------
+ op.data.buf.in = buf;
+ op.data.nbytes = len;
+ ret = spi_mem_adjust_op_size(desc->mem, &op);
+ if (ret)
+ return ret;
+
+ ret = spi_mem_exec_op(desc->mem, &op);
+ if (ret)
+ return ret;
+
+ return op.data.nbytes;
+ }
+
+The similar happens for spi_mem_no_dirmap_write(). Thus the address
+passed to the flash should take in the account the value of
+desc->info.offset.
+
+This patch fix dirmap reading/writing of flashes with more than one
+plane per lun.
+
+Fixes: a403997c12019 ("spi: airoha: add SPI-NAND Flash controller driver")
+Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://patch.msgid.link/20251012121707.2296160-7-mikhail.kshevetskiy@iopsys.eu
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-airoha-snfi.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/spi/spi-airoha-snfi.c b/drivers/spi/spi-airoha-snfi.c
+index 8143fbb0cf4e6..b78163eaed61d 100644
+--- a/drivers/spi/spi-airoha-snfi.c
++++ b/drivers/spi/spi-airoha-snfi.c
+@@ -733,8 +733,9 @@ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc,
+ if (err)
+ goto error_dma_unmap;
+
+- /* set read addr */
+- err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_RD_CTL3, 0x0);
++ /* set read addr: zero page offset + descriptor read offset */
++ err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_RD_CTL3,
++ desc->info.offset);
+ if (err)
+ goto error_dma_unmap;
+
+@@ -870,7 +871,9 @@ static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc,
+ if (err)
+ goto error_dma_unmap;
+
+- err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_PG_CTL2, 0x0);
++ /* set write addr: zero page offset + descriptor write offset */
++ err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_PG_CTL2,
++ desc->info.offset);
+ if (err)
+ goto error_dma_unmap;
+
+--
+2.51.0
+
--- /dev/null
+From b18a2fc00d55b5a306b14045a64d58d0d65edab3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Oct 2025 15:16:52 +0300
+Subject: spi: airoha: return an error for continuous mode dirmap creation
+ cases
+
+From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+
+[ Upstream commit 4314ffce4eb81a6c18700af1b6e29b6e0c6b9e37 ]
+
+This driver can accelerate single page operations only, thus
+continuous reading mode should not be used.
+
+Continuous reading will use sizes up to the size of one erase block.
+This size is much larger than the size of single flash page. Use this
+difference to identify continuous reading and return an error.
+
+Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+Reviewed-by: Frieder Schrempf <frieder.schrempf@kontron.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Fixes: a403997c12019 ("spi: airoha: add SPI-NAND Flash controller driver")
+Link: https://patch.msgid.link/20251012121707.2296160-2-mikhail.kshevetskiy@iopsys.eu
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-airoha-snfi.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/spi/spi-airoha-snfi.c b/drivers/spi/spi-airoha-snfi.c
+index 1369691a997bf..6930dea48f330 100644
+--- a/drivers/spi/spi-airoha-snfi.c
++++ b/drivers/spi/spi-airoha-snfi.c
+@@ -625,6 +625,10 @@ static int airoha_snand_dirmap_create(struct spi_mem_dirmap_desc *desc)
+ if (desc->info.offset + desc->info.length > U32_MAX)
+ return -EINVAL;
+
++ /* continuous reading is not supported */
++ if (desc->info.length > SPI_NAND_CACHE_SIZE)
++ return -E2BIG;
++
+ if (!airoha_snand_supports_op(desc->mem, &desc->info.op_tmpl))
+ return -EOPNOTSUPP;
+
+--
+2.51.0
+
--- /dev/null
+From ef4772f5f146ef683b66df81d15ca3953d5797de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Oct 2025 15:16:56 +0300
+Subject: spi: airoha: switch back to non-dma mode in the case of error
+
+From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+
+[ Upstream commit 20d7b236b78c7ec685a22db5689b9c829975e0c3 ]
+
+Current dirmap code does not switch back to non-dma mode in the case of
+error. This is wrong.
+
+This patch fixes dirmap read/write error path.
+
+Fixes: a403997c12019 ("spi: airoha: add SPI-NAND Flash controller driver")
+Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://patch.msgid.link/20251012121707.2296160-6-mikhail.kshevetskiy@iopsys.eu
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-airoha-snfi.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/spi/spi-airoha-snfi.c b/drivers/spi/spi-airoha-snfi.c
+index 0b89dc42545b1..8143fbb0cf4e6 100644
+--- a/drivers/spi/spi-airoha-snfi.c
++++ b/drivers/spi/spi-airoha-snfi.c
+@@ -698,13 +698,13 @@ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc,
+
+ err = airoha_snand_nfi_config(as_ctrl);
+ if (err)
+- return err;
++ goto error_dma_mode_off;
+
+ dma_addr = dma_map_single(as_ctrl->dev, txrx_buf, SPI_NAND_CACHE_SIZE,
+ DMA_FROM_DEVICE);
+ err = dma_mapping_error(as_ctrl->dev, dma_addr);
+ if (err)
+- return err;
++ goto error_dma_mode_off;
+
+ /* set dma addr */
+ err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_STRADDR,
+@@ -804,6 +804,8 @@ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc,
+ error_dma_unmap:
+ dma_unmap_single(as_ctrl->dev, dma_addr, SPI_NAND_CACHE_SIZE,
+ DMA_FROM_DEVICE);
++error_dma_mode_off:
++ airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL);
+ return err;
+ }
+
+@@ -936,6 +938,7 @@ static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc,
+ error_dma_unmap:
+ dma_unmap_single(as_ctrl->dev, dma_addr, SPI_NAND_CACHE_SIZE,
+ DMA_TO_DEVICE);
++ airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL);
+ return err;
+ }
+
+--
+2.51.0
+
--- /dev/null
+From f4746f6757588c40f278918e2054c0a0e693e3ea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Sep 2025 16:47:14 +0800
+Subject: spi: spi-nxp-fspi: add extra delay after dll locked
+
+From: Han Xu <han.xu@nxp.com>
+
+[ Upstream commit b93b4269791fdebbac2a9ad26f324dc2abb9e60f ]
+
+Due to the erratum ERR050272, the DLL lock status register STS2
+[xREFLOCK, xSLVLOCK] bit may indicate DLL is locked before DLL is
+actually locked. Add an extra 4us delay as a workaround.
+
+refer to ERR050272, on Page 20.
+https://www.nxp.com/docs/en/errata/IMX8_1N94W.pdf
+
+Fixes: 99d822b3adc4 ("spi: spi-nxp-fspi: use DLL calibration when clock rate > 100MHz")
+Signed-off-by: Han Xu <han.xu@nxp.com>
+Signed-off-by: Haibo Chen <haibo.chen@nxp.com>
+Link: https://patch.msgid.link/20250922-fspi-fix-v1-2-ff4315359d31@nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-nxp-fspi.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c
+index 5a1e55a01c521..b569302f22e61 100644
+--- a/drivers/spi/spi-nxp-fspi.c
++++ b/drivers/spi/spi-nxp-fspi.c
+@@ -665,6 +665,12 @@ static void nxp_fspi_dll_calibration(struct nxp_fspi *f)
+ 0, POLL_TOUT, true);
+ if (ret)
+ dev_warn(f->dev, "DLL lock failed, please fix it!\n");
++
++ /*
++ * For ERR050272, DLL lock status bit is not accurate,
++ * wait for 4us more as a workaround.
++ */
++ udelay(4);
+ }
+
+ /*
+--
+2.51.0
+
--- /dev/null
+From 80e7bd57652bd1bfa4a4ca912fdb34786914f878 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Aug 2025 15:34:08 +0200
+Subject: arm64: dts: broadcom: bcm2712: Add default GIC address cells
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 278b6cabf18bd804f956b98a2f1068717acdbfe3 ]
+
+Add missing address-cells 0 to GIC interrupt node to silence W=1
+warning:
+
+ bcm2712.dtsi:494.4-497.31: Warning (interrupt_map): /axi/pcie@1000110000:interrupt-map:
+ Missing property '#address-cells' in node /soc@107c000000/interrupt-controller@7fff9000, using 0 as fallback
+
+Value '0' is correct because:
+1. GIC interrupt controller does not have children,
+2. interrupt-map property (in PCI node) consists of five components and
+ the fourth component "parent unit address", which size is defined by
+ '#address-cells' of the node pointed to by the interrupt-parent
+ component, is not used (=0)
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20250822133407.312505-2-krzysztof.kozlowski@linaro.org
+Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Stable-dep-of: aa960b597600 ("arm64: dts: broadcom: bcm2712: Define VGIC interrupt")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/broadcom/bcm2712.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
+index 0a9212d3106f1..940f1c4831988 100644
+--- a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
++++ b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
+@@ -270,6 +270,7 @@
+ <0x7fffc000 0x2000>,
+ <0x7fffe000 0x2000>;
+ interrupt-controller;
++ #address-cells = <0>;
+ #interrupt-cells = <3>;
+ };
+
+--
+2.51.0
+
--- /dev/null
+From 081d616975fe49bc0dae220b5a3d2b3024155609 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Sep 2025 09:56:05 +0100
+Subject: arm64: dts: broadcom: bcm2712: Define VGIC interrupt
+
+From: Peter Robinson <pbrobinson@gmail.com>
+
+[ Upstream commit aa960b597600bed80fe171729057dd6aa188b5b5 ]
+
+Define the interrupt in the GICv2 for vGIC so KVM
+can be used, it was missed from the original upstream
+DTB for some reason.
+
+Signed-off-by: Peter Robinson <pbrobinson@gmail.com>
+Cc: Andrea della Porta <andrea.porta@suse.com>
+Cc: Phil Elwell <phil@raspberrypi.com>
+Fixes: faa3381267d0 ("arm64: dts: broadcom: Add minimal support for Raspberry Pi 5")
+Link: https://lore.kernel.org/r/20250924085612.1039247-1-pbrobinson@gmail.com
+Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/broadcom/bcm2712.dtsi | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
+index 940f1c4831988..18e73580828a5 100644
+--- a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
++++ b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
+@@ -271,6 +271,8 @@
+ <0x7fffe000 0x2000>;
+ interrupt-controller;
+ #address-cells = <0>;
++ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) |
++ IRQ_TYPE_LEVEL_HIGH)>;
+ #interrupt-cells = <3>;
+ };
+
+--
+2.51.0
+
--- /dev/null
+From 101bbf37bc6050c799c21d33bf018785394d7f43 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Oct 2025 10:33:31 +0200
+Subject: block: require LBA dma_alignment when using PI
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit 4c8cf6bd28d6fea23819f082ddc8063fd6fa963a ]
+
+The block layer PI generation / verification code expects the bio_vecs
+to have at least LBA size (or more correctly integrity internal)
+granularity. With the direct I/O alignment relaxation in 2022, user
+space can now feed bios with less alignment than that, leading to
+scribbling outside the PI buffers. Apparently this wasn't noticed so far
+because none of the tests generate such buffers, but since 851c4c96db00
+("xfs: implement XFS_IOC_DIOINFO in terms of vfs_getattr"), xfstests
+generic/013 by default generates such I/O now that the relaxed alignment
+is advertised by the XFS_IOC_DIOINFO ioctl.
+
+Fix this by increasing the required alignment when using PI, although
+handling arbitrary alignment in the long run would be even nicer.
+
+Fixes: bf8d08532bc1 ("iomap: add support for dma aligned direct-io")
+Fixes: b1a000d3b8ec ("block: relax direct io memory alignment")
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
+Reviewed-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-settings.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/block/blk-settings.c b/block/blk-settings.c
+index 8fa52914e16b0..c3e131f4f9083 100644
+--- a/block/blk-settings.c
++++ b/block/blk-settings.c
+@@ -184,6 +184,16 @@ static int blk_validate_integrity_limits(struct queue_limits *lim)
+ if (!bi->interval_exp)
+ bi->interval_exp = ilog2(lim->logical_block_size);
+
++ /*
++ * The PI generation / validation helpers do not expect intervals to
++ * straddle multiple bio_vecs. Enforce alignment so that those are
++ * never generated, and that each buffer is aligned as expected.
++ */
++ if (bi->csum_type) {
++ lim->dma_alignment = max(lim->dma_alignment,
++ (1U << bi->interval_exp) - 1);
++ }
++
+ return 0;
+ }
+
+--
+2.51.0
+
--- /dev/null
+From d289c7c2aace45e9152b66936e5af99bf619fd14 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Oct 2025 14:24:53 +0200
+Subject: drm/panic: Fix 24bit pixel crossing page boundaries
+
+From: Jocelyn Falempe <jfalempe@redhat.com>
+
+[ Upstream commit 23437509a69476d4f896891032d62ac868731668 ]
+
+When using page list framebuffer, and using RGB888 format, some
+pixels can cross the page boundaries, and this case was not handled,
+leading to writing 1 or 2 bytes on the next virtual address.
+
+Add a check and a specific function to handle this case.
+
+Fixes: c9ff2808790f0 ("drm/panic: Add support to scanout buffer as array of pages")
+Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
+Link: https://lore.kernel.org/r/20251009122955.562888-7-jfalempe@redhat.com
+Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_panic.c | 46 +++++++++++++++++++++++++++++++++++--
+ 1 file changed, 44 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c
+index 1bc15c44207b4..f52752880e1c9 100644
+--- a/drivers/gpu/drm/drm_panic.c
++++ b/drivers/gpu/drm/drm_panic.c
+@@ -174,6 +174,33 @@ static void drm_panic_write_pixel24(void *vaddr, unsigned int offset, u32 color)
+ *p = color & 0xff;
+ }
+
++/*
++ * Special case if the pixel crosses page boundaries
++ */
++static void drm_panic_write_pixel24_xpage(void *vaddr, struct page *next_page,
++ unsigned int offset, u32 color)
++{
++ u8 *vaddr2;
++ u8 *p = vaddr + offset;
++
++ vaddr2 = kmap_local_page_try_from_panic(next_page);
++
++ *p++ = color & 0xff;
++ color >>= 8;
++
++ if (offset == PAGE_SIZE - 1)
++ p = vaddr2;
++
++ *p++ = color & 0xff;
++ color >>= 8;
++
++ if (offset == PAGE_SIZE - 2)
++ p = vaddr2;
++
++ *p = color & 0xff;
++ kunmap_local(vaddr2);
++}
++
+ static void drm_panic_write_pixel32(void *vaddr, unsigned int offset, u32 color)
+ {
+ u32 *p = vaddr + offset;
+@@ -231,7 +258,14 @@ static void drm_panic_blit_page(struct page **pages, unsigned int dpitch,
+ page = new_page;
+ vaddr = kmap_local_page_try_from_panic(pages[page]);
+ }
+- if (vaddr)
++ if (!vaddr)
++ continue;
++
++ // Special case for 24bit, as a pixel might cross page boundaries
++ if (cpp == 3 && offset + 3 > PAGE_SIZE)
++ drm_panic_write_pixel24_xpage(vaddr, pages[page + 1],
++ offset, fg32);
++ else
+ drm_panic_write_pixel(vaddr, offset, fg32, cpp);
+ }
+ }
+@@ -321,7 +355,15 @@ static void drm_panic_fill_page(struct page **pages, unsigned int dpitch,
+ page = new_page;
+ vaddr = kmap_local_page_try_from_panic(pages[page]);
+ }
+- drm_panic_write_pixel(vaddr, offset, color, cpp);
++ if (!vaddr)
++ continue;
++
++ // Special case for 24bit, as a pixel might cross page boundaries
++ if (cpp == 3 && offset + 3 > PAGE_SIZE)
++ drm_panic_write_pixel24_xpage(vaddr, pages[page + 1],
++ offset, color);
++ else
++ drm_panic_write_pixel(vaddr, offset, color, cpp);
+ }
+ }
+ if (vaddr)
+--
+2.51.0
+
--- /dev/null
+From 9af2a1f98a9aee8d6e016c37b2f9bec7cd38989b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Oct 2025 14:24:48 +0200
+Subject: drm/panic: Fix drawing the logo on a small narrow screen
+
+From: Jocelyn Falempe <jfalempe@redhat.com>
+
+[ Upstream commit 179753aa5b7890b311968c033d08f558f0a7be21 ]
+
+If the logo width is bigger than the framebuffer width, and the
+height is big enough to hold the logo and the message, it will draw
+at x coordinate that are higher than the width, and ends up in a
+corrupted image.
+
+Fixes: 4b570ac2eb54 ("drm/rect: Add drm_rect_overlap()")
+Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
+Link: https://lore.kernel.org/r/20251009122955.562888-2-jfalempe@redhat.com
+Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_panic.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c
+index 1d6312fa14293..23ba791c6131b 100644
+--- a/drivers/gpu/drm/drm_panic.c
++++ b/drivers/gpu/drm/drm_panic.c
+@@ -429,6 +429,9 @@ static void drm_panic_logo_rect(struct drm_rect *rect, const struct font_desc *f
+ static void drm_panic_logo_draw(struct drm_scanout_buffer *sb, struct drm_rect *rect,
+ const struct font_desc *font, u32 fg_color)
+ {
++ if (rect->x2 > sb->width || rect->y2 > sb->height)
++ return;
++
+ if (logo_mono)
+ drm_panic_blit(sb, rect, logo_mono->data,
+ DIV_ROUND_UP(drm_rect_width(rect), 8), 1, fg_color);
+--
+2.51.0
+
--- /dev/null
+From a47322c2e021cf9f2e4d2d20869f6440fb9d9804 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Oct 2025 14:24:50 +0200
+Subject: drm/panic: Fix qr_code, ensure vmargin is positive
+
+From: Jocelyn Falempe <jfalempe@redhat.com>
+
+[ Upstream commit 4fcffb5e5c8c0c8e2ad9c99a22305a0afbecc294 ]
+
+Depending on qr_code size and screen size, the vertical margin can
+be negative, that means there is not enough room to draw the qr_code.
+
+So abort early, to avoid a segfault by trying to draw at negative
+coordinates.
+
+Fixes: cb5164ac43d0f ("drm/panic: Add a QR code panic screen")
+Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
+Link: https://lore.kernel.org/r/20251009122955.562888-4-jfalempe@redhat.com
+Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_panic.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c
+index 23ba791c6131b..1bc15c44207b4 100644
+--- a/drivers/gpu/drm/drm_panic.c
++++ b/drivers/gpu/drm/drm_panic.c
+@@ -736,7 +736,10 @@ static int _draw_panic_static_qr_code(struct drm_scanout_buffer *sb)
+ pr_debug("QR width %d and scale %d\n", qr_width, scale);
+ r_qr_canvas = DRM_RECT_INIT(0, 0, qr_canvas_width * scale, qr_canvas_width * scale);
+
+- v_margin = (sb->height - drm_rect_height(&r_qr_canvas) - drm_rect_height(&r_msg)) / 5;
++ v_margin = sb->height - drm_rect_height(&r_qr_canvas) - drm_rect_height(&r_msg);
++ if (v_margin < 0)
++ return -ENOSPC;
++ v_margin /= 5;
+
+ drm_rect_translate(&r_qr_canvas, (sb->width - r_qr_canvas.x2) / 2, 2 * v_margin);
+ r_qr = DRM_RECT_INIT(r_qr_canvas.x1 + QR_MARGIN * scale, r_qr_canvas.y1 + QR_MARGIN * scale,
+--
+2.51.0
+
--- /dev/null
+From 113943fc51162cc3191efda22f9c2a02066f58a6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Oct 2025 11:29:22 +0100
+Subject: drm/panthor: Fix kernel panic on partial unmap of a GPU VA region
+
+From: Akash Goel <akash.goel@arm.com>
+
+[ Upstream commit 4eabd0d8791eaf9a7b114ccbf56eb488aefe7b1f ]
+
+This commit address a kernel panic issue that can happen if Userspace
+tries to partially unmap a GPU virtual region (aka drm_gpuva).
+The VM_BIND interface allows partial unmapping of a BO.
+
+Panthor driver pre-allocates memory for the new drm_gpuva structures
+that would be needed for the map/unmap operation, done using drm_gpuvm
+layer. It expected that only one new drm_gpuva would be needed on umap
+but a partial unmap can require 2 new drm_gpuva and that's why it
+ended up doing a NULL pointer dereference causing a kernel panic.
+
+Following dump was seen when partial unmap was exercised.
+ Unable to handle kernel NULL pointer dereference at virtual address 0000000000000078
+ Mem abort info:
+ ESR = 0x0000000096000046
+ EC = 0x25: DABT (current EL), IL = 32 bits
+ SET = 0, FnV = 0
+ EA = 0, S1PTW = 0
+ FSC = 0x06: level 2 translation fault
+ Data abort info:
+ ISV = 0, ISS = 0x00000046, ISS2 = 0x00000000
+ CM = 0, WnR = 1, TnD = 0, TagAccess = 0
+ GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
+ user pgtable: 4k pages, 48-bit VAs, pgdp=000000088a863000
+ [000000000000078] pgd=080000088a842003, p4d=080000088a842003, pud=0800000884bf5003, pmd=0000000000000000
+ Internal error: Oops: 0000000096000046 [#1] PREEMPT SMP
+ <snip>
+ pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+ pc : panthor_gpuva_sm_step_remap+0xe4/0x330 [panthor]
+ lr : panthor_gpuva_sm_step_remap+0x6c/0x330 [panthor]
+ sp : ffff800085d43970
+ x29: ffff800085d43970 x28: ffff00080363e440 x27: ffff0008090c6000
+ x26: 0000000000000030 x25: ffff800085d439f8 x24: ffff00080d402000
+ x23: ffff800085d43b60 x22: ffff800085d439e0 x21: ffff00080abdb180
+ x20: 0000000000000000 x19: 0000000000000000 x18: 0000000000000010
+ x17: 6e656c202c303030 x16: 3666666666646466 x15: 393d61766f69202c
+ x14: 312d3d7361203a70 x13: 303030323d6e656c x12: ffff80008324bf58
+ x11: 0000000000000003 x10: 0000000000000002 x9 : ffff8000801a6a9c
+ x8 : ffff00080360b300 x7 : 0000000000000000 x6 : 000000088aa35fc7
+ x5 : fff1000080000000 x4 : ffff8000842ddd30 x3 : 0000000000000001
+ x2 : 0000000100000000 x1 : 0000000000000001 x0 : 0000000000000078
+ Call trace:
+ panthor_gpuva_sm_step_remap+0xe4/0x330 [panthor]
+ op_remap_cb.isra.22+0x50/0x80
+ __drm_gpuvm_sm_unmap+0x10c/0x1c8
+ drm_gpuvm_sm_unmap+0x40/0x60
+ panthor_vm_exec_op+0xb4/0x3d0 [panthor]
+ panthor_vm_bind_exec_sync_op+0x154/0x278 [panthor]
+ panthor_ioctl_vm_bind+0x160/0x4a0 [panthor]
+ drm_ioctl_kernel+0xbc/0x138
+ drm_ioctl+0x240/0x500
+ __arm64_sys_ioctl+0xb0/0xf8
+ invoke_syscall+0x4c/0x110
+ el0_svc_common.constprop.1+0x98/0xf8
+ do_el0_svc+0x24/0x38
+ el0_svc+0x40/0xf8
+ el0t_64_sync_handler+0xa0/0xc8
+ el0t_64_sync+0x174/0x178
+
+Signed-off-by: Akash Goel <akash.goel@arm.com>
+Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
+Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
+Fixes: 647810ec2476 ("drm/panthor: Add the MMU/VM logical block")
+Reviewed-by: Steven Price <steven.price@arm.com>
+Signed-off-by: Steven Price <steven.price@arm.com>
+Link: https://lore.kernel.org/r/20251017102922.670084-1-akash.goel@arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/panthor/panthor_mmu.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/panthor/panthor_mmu.c
+index 4140f697ba5af..0402f5f734a1b 100644
+--- a/drivers/gpu/drm/panthor/panthor_mmu.c
++++ b/drivers/gpu/drm/panthor/panthor_mmu.c
+@@ -1147,10 +1147,14 @@ panthor_vm_op_ctx_prealloc_vmas(struct panthor_vm_op_ctx *op_ctx)
+ break;
+
+ case DRM_PANTHOR_VM_BIND_OP_TYPE_UNMAP:
+- /* Partial unmaps might trigger a remap with either a prev or a next VA,
+- * but not both.
++ /* Two VMAs can be needed for an unmap, as an unmap can happen
++ * in the middle of a drm_gpuva, requiring a remap with both
++ * prev & next VA. Or an unmap can span more than one drm_gpuva
++ * where the first and last ones are covered partially, requring
++ * a remap for the first with a prev VA and remap for the last
++ * with a next VA.
+ */
+- vma_count = 1;
++ vma_count = 2;
+ break;
+
+ default:
+--
+2.51.0
+
--- /dev/null
+From cc69779029b5e3fcb0ebe8fd44f077fd34078929 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Sep 2025 16:09:27 +0100
+Subject: firmware: arm_ffa: Add support for IMPDEF value in the memory access
+ descriptor
+
+From: Sudeep Holla <sudeep.holla@arm.com>
+
+[ Upstream commit 11fb1a82aefa6f7fea6ac82334edb5639b9927df ]
+
+FF-A v1.2 introduced 16 byte IMPLEMENTATION DEFINED value in the endpoint
+memory access descriptor to allow any sender could to specify an its any
+custom value for each receiver. Also this value must be specified by the
+receiver when retrieving the memory region. The sender must ensure it
+informs the receiver of this value via an IMPLEMENTATION DEFINED mechanism
+such as a partition message.
+
+So the FF-A driver can use the message interfaces to communicate the value
+and set the same in the ffa_mem_region_attributes structures when using
+the memory interfaces.
+
+The driver ensure that the size of the endpoint memory access descriptors
+is set correctly based on the FF-A version.
+
+Fixes: 9fac08d9d985 ("firmware: arm_ffa: Upgrade FF-A version to v1.2 in the driver")
+Reported-by: Lixiang Mao <liximao@qti.qualcomm.com>
+Tested-by: Lixiang Mao <liximao@qti.qualcomm.com>
+Message-Id: <20250923150927.1218364-1-sudeep.holla@arm.com>
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_ffa/driver.c | 37 ++++++++++++++++++++++---------
+ include/linux/arm_ffa.h | 21 ++++++++++++++++--
+ 2 files changed, 46 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
+index 65bf1685350a2..c72ee47565856 100644
+--- a/drivers/firmware/arm_ffa/driver.c
++++ b/drivers/firmware/arm_ffa/driver.c
+@@ -649,6 +649,26 @@ static u16 ffa_memory_attributes_get(u32 func_id)
+ return FFA_MEM_NORMAL | FFA_MEM_WRITE_BACK | FFA_MEM_INNER_SHAREABLE;
+ }
+
++static void ffa_emad_impdef_value_init(u32 version, void *dst, void *src)
++{
++ struct ffa_mem_region_attributes *ep_mem_access;
++
++ if (FFA_EMAD_HAS_IMPDEF_FIELD(version))
++ memcpy(dst, src, sizeof(ep_mem_access->impdef_val));
++}
++
++static void
++ffa_mem_region_additional_setup(u32 version, struct ffa_mem_region *mem_region)
++{
++ if (!FFA_MEM_REGION_HAS_EP_MEM_OFFSET(version)) {
++ mem_region->ep_mem_size = 0;
++ } else {
++ mem_region->ep_mem_size = ffa_emad_size_get(version);
++ mem_region->ep_mem_offset = sizeof(*mem_region);
++ memset(mem_region->reserved, 0, 12);
++ }
++}
++
+ static int
+ ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize,
+ struct ffa_mem_ops_args *args)
+@@ -667,27 +687,24 @@ ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize,
+ mem_region->flags = args->flags;
+ mem_region->sender_id = drv_info->vm_id;
+ mem_region->attributes = ffa_memory_attributes_get(func_id);
+- ep_mem_access = buffer +
+- ffa_mem_desc_offset(buffer, 0, drv_info->version);
+ composite_offset = ffa_mem_desc_offset(buffer, args->nattrs,
+ drv_info->version);
+
+- for (idx = 0; idx < args->nattrs; idx++, ep_mem_access++) {
++ for (idx = 0; idx < args->nattrs; idx++) {
++ ep_mem_access = buffer +
++ ffa_mem_desc_offset(buffer, idx, drv_info->version);
+ ep_mem_access->receiver = args->attrs[idx].receiver;
+ ep_mem_access->attrs = args->attrs[idx].attrs;
+ ep_mem_access->composite_off = composite_offset;
+ ep_mem_access->flag = 0;
+ ep_mem_access->reserved = 0;
++ ffa_emad_impdef_value_init(drv_info->version,
++ ep_mem_access->impdef_val,
++ args->attrs[idx].impdef_val);
+ }
+ mem_region->handle = 0;
+ mem_region->ep_count = args->nattrs;
+- if (drv_info->version <= FFA_VERSION_1_0) {
+- mem_region->ep_mem_size = 0;
+- } else {
+- mem_region->ep_mem_size = sizeof(*ep_mem_access);
+- mem_region->ep_mem_offset = sizeof(*mem_region);
+- memset(mem_region->reserved, 0, 12);
+- }
++ ffa_mem_region_additional_setup(drv_info->version, mem_region);
+
+ composite = buffer + composite_offset;
+ composite->total_pg_cnt = ffa_get_num_pages_sg(args->sg);
+diff --git a/include/linux/arm_ffa.h b/include/linux/arm_ffa.h
+index e1634897e159c..effa4d5e0242d 100644
+--- a/include/linux/arm_ffa.h
++++ b/include/linux/arm_ffa.h
+@@ -337,6 +337,7 @@ struct ffa_mem_region_attributes {
+ * an `struct ffa_mem_region_addr_range`.
+ */
+ u32 composite_off;
++ u8 impdef_val[16];
+ u64 reserved;
+ };
+
+@@ -416,15 +417,31 @@ struct ffa_mem_region {
+ #define CONSTITUENTS_OFFSET(x) \
+ (offsetof(struct ffa_composite_mem_region, constituents[x]))
+
++#define FFA_EMAD_HAS_IMPDEF_FIELD(version) ((version) >= FFA_VERSION_1_2)
++#define FFA_MEM_REGION_HAS_EP_MEM_OFFSET(version) ((version) > FFA_VERSION_1_0)
++
++static inline u32 ffa_emad_size_get(u32 ffa_version)
++{
++ u32 sz;
++ struct ffa_mem_region_attributes *ep_mem_access;
++
++ if (FFA_EMAD_HAS_IMPDEF_FIELD(ffa_version))
++ sz = sizeof(*ep_mem_access);
++ else
++ sz = sizeof(*ep_mem_access) - sizeof(ep_mem_access->impdef_val);
++
++ return sz;
++}
++
+ static inline u32
+ ffa_mem_desc_offset(struct ffa_mem_region *buf, int count, u32 ffa_version)
+ {
+- u32 offset = count * sizeof(struct ffa_mem_region_attributes);
++ u32 offset = count * ffa_emad_size_get(ffa_version);
+ /*
+ * Earlier to v1.1, the endpoint memory descriptor array started at
+ * offset 32(i.e. offset of ep_mem_offset in the current structure)
+ */
+- if (ffa_version <= FFA_VERSION_1_0)
++ if (!FFA_MEM_REGION_HAS_EP_MEM_OFFSET(ffa_version))
+ offset += offsetof(struct ffa_mem_region, ep_mem_offset);
+ else
+ offset += sizeof(struct ffa_mem_region);
+--
+2.51.0
+
--- /dev/null
+From 75446183128d20614e35e3a3828dce15a8b10ba2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Oct 2025 12:53:44 +0100
+Subject: firmware: arm_scmi: Account for failed debug initialization
+
+From: Cristian Marussi <cristian.marussi@arm.com>
+
+[ Upstream commit 2290ab43b9d8eafb8046387f10a8dfa2b030ba46 ]
+
+When the SCMI debug subsystem fails to initialize, the related debug root
+will be missing, and the underlying descriptor will be NULL.
+
+Handle this fault condition in the SCMI debug helpers that maintain
+metrics counters.
+
+Fixes: 0b3d48c4726e ("firmware: arm_scmi: Track basic SCMI communication debug metrics")
+Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
+Message-Id: <20251014115346.2391418-1-cristian.marussi@arm.com>
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_scmi/common.h | 24 ++++++++++++++--
+ drivers/firmware/arm_scmi/driver.c | 44 ++++++++++--------------------
+ 2 files changed, 35 insertions(+), 33 deletions(-)
+
+diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
+index 07b9e629276d2..21c0b95027c64 100644
+--- a/drivers/firmware/arm_scmi/common.h
++++ b/drivers/firmware/arm_scmi/common.h
+@@ -309,10 +309,28 @@ enum debug_counters {
+ SCMI_DEBUG_COUNTERS_LAST
+ };
+
+-static inline void scmi_inc_count(atomic_t *arr, int stat)
++/**
++ * struct scmi_debug_info - Debug common info
++ * @top_dentry: A reference to the top debugfs dentry
++ * @name: Name of this SCMI instance
++ * @type: Type of this SCMI instance
++ * @is_atomic: Flag to state if the transport of this instance is atomic
++ * @counters: An array of atomic_c's used for tracking statistics (if enabled)
++ */
++struct scmi_debug_info {
++ struct dentry *top_dentry;
++ const char *name;
++ const char *type;
++ bool is_atomic;
++ atomic_t counters[SCMI_DEBUG_COUNTERS_LAST];
++};
++
++static inline void scmi_inc_count(struct scmi_debug_info *dbg, int stat)
+ {
+- if (IS_ENABLED(CONFIG_ARM_SCMI_DEBUG_COUNTERS))
+- atomic_inc(&arr[stat]);
++ if (IS_ENABLED(CONFIG_ARM_SCMI_DEBUG_COUNTERS)) {
++ if (dbg)
++ atomic_inc(&dbg->counters[stat]);
++ }
+ }
+
+ static inline void scmi_dec_count(atomic_t *arr, int stat)
+diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
+index bd56a877fdfc8..56419285c0bfd 100644
+--- a/drivers/firmware/arm_scmi/driver.c
++++ b/drivers/firmware/arm_scmi/driver.c
+@@ -115,22 +115,6 @@ struct scmi_protocol_instance {
+
+ #define ph_to_pi(h) container_of(h, struct scmi_protocol_instance, ph)
+
+-/**
+- * struct scmi_debug_info - Debug common info
+- * @top_dentry: A reference to the top debugfs dentry
+- * @name: Name of this SCMI instance
+- * @type: Type of this SCMI instance
+- * @is_atomic: Flag to state if the transport of this instance is atomic
+- * @counters: An array of atomic_c's used for tracking statistics (if enabled)
+- */
+-struct scmi_debug_info {
+- struct dentry *top_dentry;
+- const char *name;
+- const char *type;
+- bool is_atomic;
+- atomic_t counters[SCMI_DEBUG_COUNTERS_LAST];
+-};
+-
+ /**
+ * struct scmi_info - Structure representing a SCMI instance
+ *
+@@ -1034,7 +1018,7 @@ scmi_xfer_command_acquire(struct scmi_chan_info *cinfo, u32 msg_hdr)
+ spin_unlock_irqrestore(&minfo->xfer_lock, flags);
+
+ scmi_bad_message_trace(cinfo, msg_hdr, MSG_UNEXPECTED);
+- scmi_inc_count(info->dbg->counters, ERR_MSG_UNEXPECTED);
++ scmi_inc_count(info->dbg, ERR_MSG_UNEXPECTED);
+
+ return xfer;
+ }
+@@ -1062,7 +1046,7 @@ scmi_xfer_command_acquire(struct scmi_chan_info *cinfo, u32 msg_hdr)
+ msg_type, xfer_id, msg_hdr, xfer->state);
+
+ scmi_bad_message_trace(cinfo, msg_hdr, MSG_INVALID);
+- scmi_inc_count(info->dbg->counters, ERR_MSG_INVALID);
++ scmi_inc_count(info->dbg, ERR_MSG_INVALID);
+
+ /* On error the refcount incremented above has to be dropped */
+ __scmi_xfer_put(minfo, xfer);
+@@ -1107,7 +1091,7 @@ static void scmi_handle_notification(struct scmi_chan_info *cinfo,
+ PTR_ERR(xfer));
+
+ scmi_bad_message_trace(cinfo, msg_hdr, MSG_NOMEM);
+- scmi_inc_count(info->dbg->counters, ERR_MSG_NOMEM);
++ scmi_inc_count(info->dbg, ERR_MSG_NOMEM);
+
+ scmi_clear_channel(info, cinfo);
+ return;
+@@ -1123,7 +1107,7 @@ static void scmi_handle_notification(struct scmi_chan_info *cinfo,
+ trace_scmi_msg_dump(info->id, cinfo->id, xfer->hdr.protocol_id,
+ xfer->hdr.id, "NOTI", xfer->hdr.seq,
+ xfer->hdr.status, xfer->rx.buf, xfer->rx.len);
+- scmi_inc_count(info->dbg->counters, NOTIFICATION_OK);
++ scmi_inc_count(info->dbg, NOTIFICATION_OK);
+
+ scmi_notify(cinfo->handle, xfer->hdr.protocol_id,
+ xfer->hdr.id, xfer->rx.buf, xfer->rx.len, ts);
+@@ -1183,10 +1167,10 @@ static void scmi_handle_response(struct scmi_chan_info *cinfo,
+ if (xfer->hdr.type == MSG_TYPE_DELAYED_RESP) {
+ scmi_clear_channel(info, cinfo);
+ complete(xfer->async_done);
+- scmi_inc_count(info->dbg->counters, DELAYED_RESPONSE_OK);
++ scmi_inc_count(info->dbg, DELAYED_RESPONSE_OK);
+ } else {
+ complete(&xfer->done);
+- scmi_inc_count(info->dbg->counters, RESPONSE_OK);
++ scmi_inc_count(info->dbg, RESPONSE_OK);
+ }
+
+ if (IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT)) {
+@@ -1296,7 +1280,7 @@ static int scmi_wait_for_reply(struct device *dev, const struct scmi_desc *desc,
+ "timed out in resp(caller: %pS) - polling\n",
+ (void *)_RET_IP_);
+ ret = -ETIMEDOUT;
+- scmi_inc_count(info->dbg->counters, XFERS_RESPONSE_POLLED_TIMEOUT);
++ scmi_inc_count(info->dbg, XFERS_RESPONSE_POLLED_TIMEOUT);
+ }
+ }
+
+@@ -1321,7 +1305,7 @@ static int scmi_wait_for_reply(struct device *dev, const struct scmi_desc *desc,
+ "RESP" : "resp",
+ xfer->hdr.seq, xfer->hdr.status,
+ xfer->rx.buf, xfer->rx.len);
+- scmi_inc_count(info->dbg->counters, RESPONSE_POLLED_OK);
++ scmi_inc_count(info->dbg, RESPONSE_POLLED_OK);
+
+ if (IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT)) {
+ scmi_raw_message_report(info->raw, xfer,
+@@ -1336,7 +1320,7 @@ static int scmi_wait_for_reply(struct device *dev, const struct scmi_desc *desc,
+ dev_err(dev, "timed out in resp(caller: %pS)\n",
+ (void *)_RET_IP_);
+ ret = -ETIMEDOUT;
+- scmi_inc_count(info->dbg->counters, XFERS_RESPONSE_TIMEOUT);
++ scmi_inc_count(info->dbg, XFERS_RESPONSE_TIMEOUT);
+ }
+ }
+
+@@ -1420,13 +1404,13 @@ static int do_xfer(const struct scmi_protocol_handle *ph,
+ !is_transport_polling_capable(info->desc)) {
+ dev_warn_once(dev,
+ "Polling mode is not supported by transport.\n");
+- scmi_inc_count(info->dbg->counters, SENT_FAIL_POLLING_UNSUPPORTED);
++ scmi_inc_count(info->dbg, SENT_FAIL_POLLING_UNSUPPORTED);
+ return -EINVAL;
+ }
+
+ cinfo = idr_find(&info->tx_idr, pi->proto->id);
+ if (unlikely(!cinfo)) {
+- scmi_inc_count(info->dbg->counters, SENT_FAIL_CHANNEL_NOT_FOUND);
++ scmi_inc_count(info->dbg, SENT_FAIL_CHANNEL_NOT_FOUND);
+ return -EINVAL;
+ }
+ /* True ONLY if also supported by transport. */
+@@ -1461,19 +1445,19 @@ static int do_xfer(const struct scmi_protocol_handle *ph,
+ ret = info->desc->ops->send_message(cinfo, xfer);
+ if (ret < 0) {
+ dev_dbg(dev, "Failed to send message %d\n", ret);
+- scmi_inc_count(info->dbg->counters, SENT_FAIL);
++ scmi_inc_count(info->dbg, SENT_FAIL);
+ return ret;
+ }
+
+ trace_scmi_msg_dump(info->id, cinfo->id, xfer->hdr.protocol_id,
+ xfer->hdr.id, "CMND", xfer->hdr.seq,
+ xfer->hdr.status, xfer->tx.buf, xfer->tx.len);
+- scmi_inc_count(info->dbg->counters, SENT_OK);
++ scmi_inc_count(info->dbg, SENT_OK);
+
+ ret = scmi_wait_for_message_response(cinfo, xfer);
+ if (!ret && xfer->hdr.status) {
+ ret = scmi_to_linux_errno(xfer->hdr.status);
+- scmi_inc_count(info->dbg->counters, ERR_PROTOCOL);
++ scmi_inc_count(info->dbg, ERR_PROTOCOL);
+ }
+
+ if (info->desc->ops->mark_txdone)
+--
+2.51.0
+
--- /dev/null
+From 472a6cb37a19c5f5724bf744bbeba79fa6f3e456 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Oct 2025 12:10:57 +0300
+Subject: firmware: arm_scmi: Fix premature SCMI_XFER_FLAG_IS_RAW clearing in
+ raw mode
+
+From: Artem Shimko <a.shimko.dev@gmail.com>
+
+[ Upstream commit 20b93a0088a595bceed4a026d527cbbac4e876c5 ]
+
+The SCMI_XFER_FLAG_IS_RAW flag was being cleared prematurely in
+scmi_xfer_raw_put() before the transfer completion was properly
+acknowledged by the raw message handlers.
+
+Move the clearing of SCMI_XFER_FLAG_IS_RAW and SCMI_XFER_FLAG_CHAN_SET
+from scmi_xfer_raw_put() to __scmi_xfer_put() to ensure the flags remain
+set throughout the entire raw message processing pipeline until the
+transfer is returned to the free pool.
+
+Fixes: 3095a3e25d8f ("firmware: arm_scmi: Add xfer helpers to provide raw access")
+Suggested-by: Cristian Marussi <cristian.marussi@arm.com>
+Signed-off-by: Artem Shimko <a.shimko.dev@gmail.com>
+Reviewed-by: Cristian Marussi <cristian.marussi@arm.com>
+Message-Id: <20251008091057.1969260-1-a.shimko.dev@gmail.com>
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_scmi/driver.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
+index 1cd15412024cd..a8f2247feab9d 100644
+--- a/drivers/firmware/arm_scmi/driver.c
++++ b/drivers/firmware/arm_scmi/driver.c
+@@ -805,6 +805,7 @@ __scmi_xfer_put(struct scmi_xfers_info *minfo, struct scmi_xfer *xfer)
+
+ scmi_dec_count(info->dbg, XFERS_INFLIGHT);
+ }
++ xfer->flags = 0;
+ hlist_add_head(&xfer->node, &minfo->free_xfers);
+ }
+ spin_unlock_irqrestore(&minfo->xfer_lock, flags);
+@@ -823,8 +824,6 @@ void scmi_xfer_raw_put(const struct scmi_handle *handle, struct scmi_xfer *xfer)
+ {
+ struct scmi_info *info = handle_to_scmi_info(handle);
+
+- xfer->flags &= ~SCMI_XFER_FLAG_IS_RAW;
+- xfer->flags &= ~SCMI_XFER_FLAG_CHAN_SET;
+ return __scmi_xfer_put(&info->tx_minfo, xfer);
+ }
+
+--
+2.51.0
+
--- /dev/null
+From 71b7d8b1c08d73116dccc67ec1f8dc6da4cf32b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Oct 2025 15:02:30 +0800
+Subject: gpio: ljca: Fix duplicated IRQ mapping
+
+From: Haotian Zhang <vulab@iscas.ac.cn>
+
+[ Upstream commit 4c4e6ea4a120cc5ab58e437c6ba123cbfc357d45 ]
+
+The generic_handle_domain_irq() function resolves the hardware IRQ
+internally. The driver performed a duplicative mapping by calling
+irq_find_mapping() first, which could lead to an RCU stall.
+
+Delete the redundant irq_find_mapping() call and pass the hardware IRQ
+directly to generic_handle_domain_irq().
+
+Fixes: c5a4b6fd31e8 ("gpio: Add support for Intel LJCA USB GPIO driver")
+Signed-off-by: Haotian Zhang <vulab@iscas.ac.cn>
+Link: https://lore.kernel.org/r/20251023070231.1305-1-vulab@iscas.ac.cn
+[Bartosz: remove unused variable]
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-ljca.c | 14 +++-----------
+ 1 file changed, 3 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/gpio/gpio-ljca.c b/drivers/gpio/gpio-ljca.c
+index 3b4f8830c7411..f32d1d237795b 100644
+--- a/drivers/gpio/gpio-ljca.c
++++ b/drivers/gpio/gpio-ljca.c
+@@ -286,22 +286,14 @@ static void ljca_gpio_event_cb(void *context, u8 cmd, const void *evt_data,
+ {
+ const struct ljca_gpio_packet *packet = evt_data;
+ struct ljca_gpio_dev *ljca_gpio = context;
+- int i, irq;
++ int i;
+
+ if (cmd != LJCA_GPIO_INT_EVENT)
+ return;
+
+ for (i = 0; i < packet->num; i++) {
+- irq = irq_find_mapping(ljca_gpio->gc.irq.domain,
+- packet->item[i].index);
+- if (!irq) {
+- dev_err(ljca_gpio->gc.parent,
+- "gpio_id %u does not mapped to IRQ yet\n",
+- packet->item[i].index);
+- return;
+- }
+-
+- generic_handle_domain_irq(ljca_gpio->gc.irq.domain, irq);
++ generic_handle_domain_irq(ljca_gpio->gc.irq.domain,
++ packet->item[i].index);
+ set_bit(packet->item[i].index, ljca_gpio->reenable_irqs);
+ }
+
+--
+2.51.0
+
--- /dev/null
+From e41ede00d7d6cd4f2059d9096aabebd73fca0c75 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Oct 2025 14:34:14 +0800
+Subject: hwmon: (cgbc-hwmon) Add missing NULL check after devm_kzalloc()
+
+From: Li Qiang <liqiang01@kylinos.cn>
+
+[ Upstream commit a09a5aa8bf258ddc99a22c30f17fe304b96b5350 ]
+
+The driver allocates memory for sensor data using devm_kzalloc(), but
+did not check if the allocation succeeded. In case of memory allocation
+failure, dereferencing the NULL pointer would lead to a kernel crash.
+
+Add a NULL pointer check and return -ENOMEM to handle allocation failure
+properly.
+
+Signed-off-by: Li Qiang <liqiang01@kylinos.cn>
+Fixes: 08ebc9def79fc ("hwmon: Add Congatec Board Controller monitoring driver")
+Reviewed-by: Thomas Richard <thomas.richard@bootlin.com>
+Link: https://lore.kernel.org/r/20251017063414.1557447-1-liqiang01@kylinos.cn
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/cgbc-hwmon.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/hwmon/cgbc-hwmon.c b/drivers/hwmon/cgbc-hwmon.c
+index 772f44d56ccff..3aff4e092132f 100644
+--- a/drivers/hwmon/cgbc-hwmon.c
++++ b/drivers/hwmon/cgbc-hwmon.c
+@@ -107,6 +107,9 @@ static int cgbc_hwmon_probe_sensors(struct device *dev, struct cgbc_hwmon_data *
+ nb_sensors = data[0];
+
+ hwmon->sensors = devm_kzalloc(dev, sizeof(*hwmon->sensors) * nb_sensors, GFP_KERNEL);
++ if (!hwmon->sensors)
++ return -ENOMEM;
++
+ sensor = hwmon->sensors;
+
+ for (i = 0; i < nb_sensors; i++) {
+--
+2.51.0
+
--- /dev/null
+From aaddcd50f2ecc53c7c418ac4723ef5e9e5dd72b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Oct 2025 21:12:49 +0300
+Subject: hwmon: (pmbus/isl68137) Fix child node reference leak on early return
+
+From: Erick Karanja <karanja99erick@gmail.com>
+
+[ Upstream commit 57f6f47920ef2f598c46d0a04bd9c8984c98e6df ]
+
+In the case of an early return, the reference to the child node needs
+to be released.
+
+Use for_each_child_of_node_scoped to fix the issue.
+
+Fixes: 3996187f80a0e ("hwmon: (pmbus/isl68137) add support for voltage divider on Vout")
+Signed-off-by: Erick Karanja <karanja99erick@gmail.com>
+Link: https://lore.kernel.org/r/20251012181249.359401-1-karanja99erick@gmail.com
+[groeck: Updated subject/description]
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/pmbus/isl68137.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/hwmon/pmbus/isl68137.c b/drivers/hwmon/pmbus/isl68137.c
+index c52c55d2e7f48..0c6b31ee755b9 100644
+--- a/drivers/hwmon/pmbus/isl68137.c
++++ b/drivers/hwmon/pmbus/isl68137.c
+@@ -334,10 +334,9 @@ static int isl68137_probe_from_dt(struct device *dev,
+ struct isl68137_data *data)
+ {
+ const struct device_node *np = dev->of_node;
+- struct device_node *child;
+ int err;
+
+- for_each_child_of_node(np, child) {
++ for_each_child_of_node_scoped(np, child) {
+ if (strcmp(child->name, "channel"))
+ continue;
+
+--
+2.51.0
+
--- /dev/null
+From 4664fd5dad57138b6af5331959a24e1ff33c78eb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 18 Oct 2025 06:04:57 -0700
+Subject: hwmon: (sht3x) Fix error handling
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+[ Upstream commit 8dcc66ad379ec0642fb281c45ccfd7d2d366e53f ]
+
+Handling of errors when reading status, temperature, and humidity returns
+the error number as negative attribute value. Fix it up by returning
+the error as return value.
+
+Fixes: a0ac418c6007c ("hwmon: (sht3x) convert some of sysfs interface to hwmon")
+Cc: JuenKit Yip <JuenKit_Yip@hotmail.com>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/sht3x.c | 27 +++++++++++++++++----------
+ 1 file changed, 17 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/hwmon/sht3x.c b/drivers/hwmon/sht3x.c
+index 557ad3e7752a9..f36c0229328fa 100644
+--- a/drivers/hwmon/sht3x.c
++++ b/drivers/hwmon/sht3x.c
+@@ -291,24 +291,26 @@ static struct sht3x_data *sht3x_update_client(struct device *dev)
+ return data;
+ }
+
+-static int temp1_input_read(struct device *dev)
++static int temp1_input_read(struct device *dev, long *temp)
+ {
+ struct sht3x_data *data = sht3x_update_client(dev);
+
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+
+- return data->temperature;
++ *temp = data->temperature;
++ return 0;
+ }
+
+-static int humidity1_input_read(struct device *dev)
++static int humidity1_input_read(struct device *dev, long *humidity)
+ {
+ struct sht3x_data *data = sht3x_update_client(dev);
+
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+
+- return data->humidity;
++ *humidity = data->humidity;
++ return 0;
+ }
+
+ /*
+@@ -706,6 +708,7 @@ static int sht3x_read(struct device *dev, enum hwmon_sensor_types type,
+ u32 attr, int channel, long *val)
+ {
+ enum sht3x_limits index;
++ int ret;
+
+ switch (type) {
+ case hwmon_chip:
+@@ -720,10 +723,12 @@ static int sht3x_read(struct device *dev, enum hwmon_sensor_types type,
+ case hwmon_temp:
+ switch (attr) {
+ case hwmon_temp_input:
+- *val = temp1_input_read(dev);
+- break;
++ return temp1_input_read(dev, val);
+ case hwmon_temp_alarm:
+- *val = temp1_alarm_read(dev);
++ ret = temp1_alarm_read(dev);
++ if (ret < 0)
++ return ret;
++ *val = ret;
+ break;
+ case hwmon_temp_max:
+ index = limit_max;
+@@ -748,10 +753,12 @@ static int sht3x_read(struct device *dev, enum hwmon_sensor_types type,
+ case hwmon_humidity:
+ switch (attr) {
+ case hwmon_humidity_input:
+- *val = humidity1_input_read(dev);
+- break;
++ return humidity1_input_read(dev, val);
+ case hwmon_humidity_alarm:
+- *val = humidity1_alarm_read(dev);
++ ret = humidity1_alarm_read(dev);
++ if (ret < 0)
++ return ret;
++ *val = ret;
+ break;
+ case hwmon_humidity_max:
+ index = limit_max;
+--
+2.51.0
+
--- /dev/null
+From 652c291577ea9c5244c871e2fb3c6ef7ba3403c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Oct 2025 12:53:45 +0100
+Subject: include: trace: Fix inflight count helper on failed initialization
+
+From: Cristian Marussi <cristian.marussi@arm.com>
+
+[ Upstream commit 289ce7e9a5e1a52ac7e522a3e389dc16be08d7a4 ]
+
+Add a check to the scmi_inflight_count() helper to handle the case
+when the SCMI debug subsystem fails to initialize.
+
+Fixes: f8e656382b4a ("include: trace: Add tracepoint support for inflight xfer count")
+Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
+Message-Id: <20251014115346.2391418-2-cristian.marussi@arm.com>
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_scmi/common.h | 8 +++++---
+ drivers/firmware/arm_scmi/driver.c | 7 +++++--
+ 2 files changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
+index 21c0b95027c64..7c35c95fddbaf 100644
+--- a/drivers/firmware/arm_scmi/common.h
++++ b/drivers/firmware/arm_scmi/common.h
+@@ -333,10 +333,12 @@ static inline void scmi_inc_count(struct scmi_debug_info *dbg, int stat)
+ }
+ }
+
+-static inline void scmi_dec_count(atomic_t *arr, int stat)
++static inline void scmi_dec_count(struct scmi_debug_info *dbg, int stat)
+ {
+- if (IS_ENABLED(CONFIG_ARM_SCMI_DEBUG_COUNTERS))
+- atomic_dec(&arr[stat]);
++ if (IS_ENABLED(CONFIG_ARM_SCMI_DEBUG_COUNTERS)) {
++ if (dbg)
++ atomic_dec(&dbg->counters[stat]);
++ }
+ }
+
+ enum scmi_bad_msg {
+diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
+index 56419285c0bfd..1cd15412024cd 100644
+--- a/drivers/firmware/arm_scmi/driver.c
++++ b/drivers/firmware/arm_scmi/driver.c
+@@ -594,7 +594,7 @@ scmi_xfer_inflight_register_unlocked(struct scmi_xfer *xfer,
+ /* Set in-flight */
+ set_bit(xfer->hdr.seq, minfo->xfer_alloc_table);
+ hash_add(minfo->pending_xfers, &xfer->node, xfer->hdr.seq);
+- scmi_inc_count(info->dbg->counters, XFERS_INFLIGHT);
++ scmi_inc_count(info->dbg, XFERS_INFLIGHT);
+
+ xfer->pending = true;
+ }
+@@ -803,7 +803,7 @@ __scmi_xfer_put(struct scmi_xfers_info *minfo, struct scmi_xfer *xfer)
+ hash_del(&xfer->node);
+ xfer->pending = false;
+
+- scmi_dec_count(info->dbg->counters, XFERS_INFLIGHT);
++ scmi_dec_count(info->dbg, XFERS_INFLIGHT);
+ }
+ hlist_add_head(&xfer->node, &minfo->free_xfers);
+ }
+@@ -3407,6 +3407,9 @@ int scmi_inflight_count(const struct scmi_handle *handle)
+ if (IS_ENABLED(CONFIG_ARM_SCMI_DEBUG_COUNTERS)) {
+ struct scmi_info *info = handle_to_scmi_info(handle);
+
++ if (!info->dbg)
++ return 0;
++
+ return atomic_read(&info->dbg->counters[XFERS_INFLIGHT]);
+ } else {
+ return 0;
+--
+2.51.0
+
--- /dev/null
+From e30e4ba072bc623e0e72cefbbd74fc8cf98b0c09 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Oct 2025 04:55:24 -0700
+Subject: io_uring: correct __must_hold annotation in io_install_fixed_file
+
+From: Alok Tiwari <alok.a.tiwari@oracle.com>
+
+[ Upstream commit c5efc6a0b3940381d67887302ddb87a5cf623685 ]
+
+The __must_hold annotation references &req->ctx->uring_lock, but req
+is not in scope in io_install_fixed_file. This change updates the
+annotation to reference the correct ctx->uring_lock.
+improving code clarity.
+
+Fixes: f110ed8498af ("io_uring: split out fixed file installation and removal")
+Signed-off-by: Alok Tiwari <alok.a.tiwari@oracle.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ io_uring/filetable.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/io_uring/filetable.c b/io_uring/filetable.c
+index a21660e3145ab..794ef95df293c 100644
+--- a/io_uring/filetable.c
++++ b/io_uring/filetable.c
+@@ -57,7 +57,7 @@ void io_free_file_tables(struct io_ring_ctx *ctx, struct io_file_table *table)
+
+ static int io_install_fixed_file(struct io_ring_ctx *ctx, struct file *file,
+ u32 slot_index)
+- __must_hold(&req->ctx->uring_lock)
++ __must_hold(&ctx->uring_lock)
+ {
+ struct io_rsrc_node *node;
+
+--
+2.51.0
+
--- /dev/null
+From efb180409e1a1fcdcd1f8c9e49ea3ad67b22973d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 18 Oct 2025 12:32:54 -0700
+Subject: io_uring: fix incorrect unlikely() usage in io_waitid_prep()
+
+From: Alok Tiwari <alok.a.tiwari@oracle.com>
+
+[ Upstream commit 4ec703ec0c384a2199808c4eb2e9037236285a8d ]
+
+The negation operator is incorrectly placed outside the unlikely()
+macro:
+
+ if (!unlikely(iwa))
+
+This inverts the compiler branch prediction hint, marking the NULL case
+as likely instead of unlikely. The intent is to indicate that allocation
+failures are rare, consistent with common kernel patterns.
+
+ Moving the negation inside unlikely():
+
+ if (unlikely(!iwa))
+
+Fixes: 2b4fc4cd43f2 ("io_uring/waitid: setup async data in the prep handler")
+Signed-off-by: Alok Tiwari <alok.a.tiwari@oracle.com>
+Reviewed-by: Gabriel Krisman Bertazi <krisman@suse.de>
+Reviewed-by: Caleb Sander Mateos <csander@purestorage.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ io_uring/waitid.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/io_uring/waitid.c b/io_uring/waitid.c
+index 3101ad8ec0cf6..c8ca00e681f77 100644
+--- a/io_uring/waitid.c
++++ b/io_uring/waitid.c
+@@ -252,7 +252,7 @@ int io_waitid_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
+ return -EINVAL;
+
+ iwa = io_uring_alloc_async_data(NULL, req);
+- if (!unlikely(iwa))
++ if (unlikely(!iwa))
+ return -ENOMEM;
+ iwa->req = req;
+
+--
+2.51.0
+
--- /dev/null
+From d1e09c6841cfa8b03e0fc7c4cc691e9e97367771 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Oct 2025 10:09:00 +0200
+Subject: nbd: override creds to kernel when calling sock_{send,recv}msg()
+
+From: Ondrej Mosnacek <omosnace@redhat.com>
+
+[ Upstream commit 81ccca31214e11ea2b537fd35d4f66d7cf46268e ]
+
+sock_{send,recv}msg() internally calls security_socket_{send,recv}msg(),
+which does security checks (e.g. SELinux) for socket access against the
+current task. However, _sock_xmit() in drivers/block/nbd.c may be called
+indirectly from a userspace syscall, where the NBD socket access would
+be incorrectly checked against the calling userspace task (which simply
+tries to read/write a file that happens to reside on an NBD device).
+
+To fix this, temporarily override creds to kernel ones before calling
+the sock_*() functions. This allows the security modules to recognize
+this as internal access by the kernel, which will normally be allowed.
+
+A way to trigger the issue is to do the following (on a system with
+SELinux set to enforcing):
+
+ ### Create nbd device:
+ truncate -s 256M /tmp/testfile
+ nbd-server localhost:10809 /tmp/testfile
+
+ ### Connect to the nbd server:
+ nbd-client localhost
+
+ ### Create mdraid array
+ mdadm --create -l 1 -n 2 /dev/md/testarray /dev/nbd0 missing
+
+After these steps, assuming the SELinux policy doesn't allow the
+unexpected access pattern, errors will be visible on the kernel console:
+
+[ 142.204243] nbd0: detected capacity change from 0 to 524288
+[ 165.189967] md: async del_gendisk mode will be removed in future, please upgrade to mdadm-4.5+
+[ 165.252299] md/raid1:md127: active with 1 out of 2 mirrors
+[ 165.252725] md127: detected capacity change from 0 to 522240
+[ 165.255434] block nbd0: Send control failed (result -13)
+[ 165.255718] block nbd0: Request send failed, requeueing
+[ 165.256006] block nbd0: Dead connection, failed to find a fallback
+[ 165.256041] block nbd0: Receive control failed (result -32)
+[ 165.256423] block nbd0: shutting down sockets
+[ 165.257196] I/O error, dev nbd0, sector 2048 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2
+[ 165.257736] Buffer I/O error on dev md127, logical block 0, async page read
+[ 165.258263] I/O error, dev nbd0, sector 2048 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2
+[ 165.259376] Buffer I/O error on dev md127, logical block 0, async page read
+[ 165.259920] I/O error, dev nbd0, sector 2048 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2
+[ 165.260628] Buffer I/O error on dev md127, logical block 0, async page read
+[ 165.261661] ldm_validate_partition_table(): Disk read failed.
+[ 165.262108] I/O error, dev nbd0, sector 2048 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2
+[ 165.262769] Buffer I/O error on dev md127, logical block 0, async page read
+[ 165.263697] I/O error, dev nbd0, sector 2048 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2
+[ 165.264412] Buffer I/O error on dev md127, logical block 0, async page read
+[ 165.265412] I/O error, dev nbd0, sector 2048 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2
+[ 165.265872] Buffer I/O error on dev md127, logical block 0, async page read
+[ 165.266378] I/O error, dev nbd0, sector 2048 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2
+[ 165.267168] Buffer I/O error on dev md127, logical block 0, async page read
+[ 165.267564] md127: unable to read partition table
+[ 165.269581] I/O error, dev nbd0, sector 0 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2
+[ 165.269960] Buffer I/O error on dev nbd0, logical block 0, async page read
+[ 165.270316] I/O error, dev nbd0, sector 0 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2
+[ 165.270913] Buffer I/O error on dev nbd0, logical block 0, async page read
+[ 165.271253] I/O error, dev nbd0, sector 0 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2
+[ 165.271809] Buffer I/O error on dev nbd0, logical block 0, async page read
+[ 165.272074] ldm_validate_partition_table(): Disk read failed.
+[ 165.272360] nbd0: unable to read partition table
+[ 165.289004] ldm_validate_partition_table(): Disk read failed.
+[ 165.289614] nbd0: unable to read partition table
+
+The corresponding SELinux denial on Fedora/RHEL will look like this
+(assuming it's not silenced):
+type=AVC msg=audit(1758104872.510:116): avc: denied { write } for pid=1908 comm="mdadm" laddr=::1 lport=32772 faddr=::1 fport=10809 scontext=system_u:system_r:mdadm_t:s0-s0:c0.c1023 tcontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tclass=tcp_socket permissive=0
+
+The respective backtrace looks like this:
+@security[mdadm, -13,
+ handshake_exit+221615650
+ handshake_exit+221615650
+ handshake_exit+221616465
+ security_socket_sendmsg+5
+ sock_sendmsg+106
+ handshake_exit+221616150
+ sock_sendmsg+5
+ __sock_xmit+162
+ nbd_send_cmd+597
+ nbd_handle_cmd+377
+ nbd_queue_rq+63
+ blk_mq_dispatch_rq_list+653
+ __blk_mq_do_dispatch_sched+184
+ __blk_mq_sched_dispatch_requests+333
+ blk_mq_sched_dispatch_requests+38
+ blk_mq_run_hw_queue+239
+ blk_mq_dispatch_plug_list+382
+ blk_mq_flush_plug_list.part.0+55
+ __blk_flush_plug+241
+ __submit_bio+353
+ submit_bio_noacct_nocheck+364
+ submit_bio_wait+84
+ __blkdev_direct_IO_simple+232
+ blkdev_read_iter+162
+ vfs_read+591
+ ksys_read+95
+ do_syscall_64+92
+ entry_SYSCALL_64_after_hwframe+120
+]: 1
+
+The issue has started to appear since commit 060406c61c7c ("block: add
+plug while submitting IO").
+
+Cc: Ming Lei <ming.lei@redhat.com>
+Link: https://bugzilla.redhat.com/show_bug.cgi?id=2348878
+Fixes: 060406c61c7c ("block: add plug while submitting IO")
+Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
+Acked-by: Paul Moore <paul@paul-moore.com>
+Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
+Reviewed-by: Ming Lei <ming.lei@redhat.com>
+Tested-by: Ming Lei <ming.lei@redhat.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/nbd.c | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
+index 87b0b78249da3..ad39ab95ea665 100644
+--- a/drivers/block/nbd.c
++++ b/drivers/block/nbd.c
+@@ -52,6 +52,7 @@
+ static DEFINE_IDR(nbd_index_idr);
+ static DEFINE_MUTEX(nbd_index_mutex);
+ static struct workqueue_struct *nbd_del_wq;
++static struct cred *nbd_cred;
+ static int nbd_total_devices = 0;
+
+ struct nbd_sock {
+@@ -554,6 +555,7 @@ static int __sock_xmit(struct nbd_device *nbd, struct socket *sock, int send,
+ int result;
+ struct msghdr msg = {} ;
+ unsigned int noreclaim_flag;
++ const struct cred *old_cred;
+
+ if (unlikely(!sock)) {
+ dev_err_ratelimited(disk_to_dev(nbd->disk),
+@@ -562,6 +564,8 @@ static int __sock_xmit(struct nbd_device *nbd, struct socket *sock, int send,
+ return -EINVAL;
+ }
+
++ old_cred = override_creds(nbd_cred);
++
+ msg.msg_iter = *iter;
+
+ noreclaim_flag = memalloc_noreclaim_save();
+@@ -586,6 +590,8 @@ static int __sock_xmit(struct nbd_device *nbd, struct socket *sock, int send,
+
+ memalloc_noreclaim_restore(noreclaim_flag);
+
++ revert_creds(old_cred);
++
+ return result;
+ }
+
+@@ -2677,7 +2683,15 @@ static int __init nbd_init(void)
+ return -ENOMEM;
+ }
+
++ nbd_cred = prepare_kernel_cred(&init_task);
++ if (!nbd_cred) {
++ destroy_workqueue(nbd_del_wq);
++ unregister_blkdev(NBD_MAJOR, "nbd");
++ return -ENOMEM;
++ }
++
+ if (genl_register_family(&nbd_genl_family)) {
++ put_cred(nbd_cred);
+ destroy_workqueue(nbd_del_wq);
+ unregister_blkdev(NBD_MAJOR, "nbd");
+ return -EINVAL;
+@@ -2732,6 +2746,7 @@ static void __exit nbd_cleanup(void)
+ /* Also wait for nbd_dev_remove_work() completes */
+ destroy_workqueue(nbd_del_wq);
+
++ put_cred(nbd_cred);
+ idr_destroy(&nbd_index_idr);
+ unregister_blkdev(NBD_MAJOR, "nbd");
+ }
+--
+2.51.0
+
--- /dev/null
+From dc4ba65d1501a08fa32c61cb472de9b4d5365c7f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Oct 2025 14:40:59 +0200
+Subject: of/irq: Add msi-parent check to of_msi_xlate()
+
+From: Lorenzo Pieralisi <lpieralisi@kernel.org>
+
+[ Upstream commit 119aaeed0b6729293f41ea33be05ecd27a947d48 ]
+
+In some legacy platforms the MSI controller for a PCI host bridge is
+identified by an msi-parent property whose phandle points at an MSI
+controller node with no #msi-cells property, that implicitly
+means #msi-cells == 0.
+
+For such platforms, mapping a device ID and retrieving the MSI controller
+node becomes simply a matter of checking whether in the device hierarchy
+there is an msi-parent property pointing at an MSI controller node with
+such characteristics.
+
+Add a helper function to of_msi_xlate() to check the msi-parent property in
+addition to msi-map and retrieve the MSI controller node (with a 1:1 ID
+deviceID-IN<->deviceID-OUT mapping) to provide support for deviceID
+mapping and MSI controller node retrieval for such platforms.
+
+Fixes: 57d72196dfc8 ("irqchip/gic-v5: Add GICv5 ITS support")
+Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Cc: Sascha Bischoff <sascha.bischoff@arm.com>
+Cc: Rob Herring <robh@kernel.org>
+Cc: Marc Zyngier <maz@kernel.org>
+Link: https://patch.msgid.link/20251021124103.198419-2-lpieralisi@kernel.org
+Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/of/irq.c | 39 ++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 36 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/of/irq.c b/drivers/of/irq.c
+index e7c12abd10ab7..3d4afeeb30ed7 100644
+--- a/drivers/of/irq.c
++++ b/drivers/of/irq.c
+@@ -670,6 +670,36 @@ void __init of_irq_init(const struct of_device_id *matches)
+ }
+ }
+
++static int of_check_msi_parent(struct device_node *dev_node, struct device_node **msi_node)
++{
++ struct of_phandle_args msi_spec;
++ int ret;
++
++ /*
++ * An msi-parent phandle with a missing or == 0 #msi-cells
++ * property identifies a 1:1 ID translation mapping.
++ *
++ * Set the msi controller node if the firmware matches this
++ * condition.
++ */
++ ret = of_parse_phandle_with_optional_args(dev_node, "msi-parent", "#msi-cells",
++ 0, &msi_spec);
++ if (ret)
++ return ret;
++
++ if ((*msi_node && *msi_node != msi_spec.np) || msi_spec.args_count != 0)
++ ret = -EINVAL;
++
++ if (!ret) {
++ /* Return with a node reference held */
++ *msi_node = msi_spec.np;
++ return 0;
++ }
++ of_node_put(msi_spec.np);
++
++ return ret;
++}
++
+ /**
+ * of_msi_xlate - map a MSI ID and find relevant MSI controller node
+ * @dev: device for which the mapping is to be done.
+@@ -677,7 +707,7 @@ void __init of_irq_init(const struct of_device_id *matches)
+ * @id_in: Device ID.
+ *
+ * Walk up the device hierarchy looking for devices with a "msi-map"
+- * property. If found, apply the mapping to @id_in.
++ * or "msi-parent" property. If found, apply the mapping to @id_in.
+ * If @msi_np points to a non-NULL device node pointer, only entries targeting
+ * that node will be matched; if it points to a NULL value, it will receive the
+ * device node of the first matching target phandle, with a reference held.
+@@ -691,12 +721,15 @@ u32 of_msi_xlate(struct device *dev, struct device_node **msi_np, u32 id_in)
+
+ /*
+ * Walk up the device parent links looking for one with a
+- * "msi-map" property.
++ * "msi-map" or an "msi-parent" property.
+ */
+- for (parent_dev = dev; parent_dev; parent_dev = parent_dev->parent)
++ for (parent_dev = dev; parent_dev; parent_dev = parent_dev->parent) {
+ if (!of_map_id(parent_dev->of_node, id_in, "msi-map",
+ "msi-map-mask", msi_np, &id_out))
+ break;
++ if (!of_check_msi_parent(parent_dev->of_node, msi_np))
++ break;
++ }
+ return id_out;
+ }
+
+--
+2.51.0
+
--- /dev/null
+From 966ee70e2ab6cba93a898fafce9139718a290d9a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Aug 2025 15:34:43 +0200
+Subject: of/irq: Convert of_msi_map_id() callers to of_msi_xlate()
+
+From: Lorenzo Pieralisi <lpieralisi@kernel.org>
+
+[ Upstream commit a576a849d5f33356e0d8fd3eae4fbaf8869417e5 ]
+
+With the introduction of the of_msi_xlate() function, the OF layer
+provides an API to map a device ID and retrieve the MSI controller
+node the ID is mapped to with a single call.
+
+of_msi_map_id() is currently used to map a deviceID to a specific
+MSI controller node; of_msi_xlate() can be used for that purpose
+too, there is no need to keep the two functions.
+
+Convert of_msi_map_id() to of_msi_xlate() calls and update the
+of_msi_xlate() documentation to describe how the struct device_node
+pointer passed in should be set-up to either provide the MSI controller
+node target or receive its pointer upon mapping completion.
+
+Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Rob Herring <robh@kernel.org>
+Cc: Marc Zyngier <maz@kernel.org>
+Acked-by: Thomas Gleixner <tglx@linutronix.de>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Link: https://lore.kernel.org/r/20250805133443.936955-1-lpieralisi@kernel.org
+Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
+Stable-dep-of: 119aaeed0b67 ("of/irq: Add msi-parent check to of_msi_xlate()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c | 2 +-
+ drivers/of/irq.c | 25 +++++----------------
+ drivers/pci/msi/irqdomain.c | 2 +-
+ include/linux/of_irq.h | 6 -----
+ 4 files changed, 7 insertions(+), 28 deletions(-)
+
+diff --git a/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c b/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c
+index 11549d85f23b8..b5785472765a3 100644
+--- a/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c
++++ b/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c
+@@ -30,7 +30,7 @@ static u32 fsl_mc_msi_domain_get_msi_id(struct irq_domain *domain,
+ u32 out_id;
+
+ of_node = irq_domain_get_of_node(domain);
+- out_id = of_node ? of_msi_map_id(&mc_dev->dev, of_node, mc_dev->icid) :
++ out_id = of_node ? of_msi_xlate(&mc_dev->dev, &of_node, mc_dev->icid) :
+ iort_msi_map_id(&mc_dev->dev, mc_dev->icid);
+
+ return out_id;
+diff --git a/drivers/of/irq.c b/drivers/of/irq.c
+index 74aaea61de13c..e7c12abd10ab7 100644
+--- a/drivers/of/irq.c
++++ b/drivers/of/irq.c
+@@ -673,13 +673,14 @@ void __init of_irq_init(const struct of_device_id *matches)
+ /**
+ * of_msi_xlate - map a MSI ID and find relevant MSI controller node
+ * @dev: device for which the mapping is to be done.
+- * @msi_np: Pointer to store the MSI controller node
++ * @msi_np: Pointer to target MSI controller node
+ * @id_in: Device ID.
+ *
+ * Walk up the device hierarchy looking for devices with a "msi-map"
+- * property. If found, apply the mapping to @id_in. @msi_np pointed
+- * value must be NULL on entry, if an MSI controller is found @msi_np is
+- * initialized to the MSI controller node with a reference held.
++ * property. If found, apply the mapping to @id_in.
++ * If @msi_np points to a non-NULL device node pointer, only entries targeting
++ * that node will be matched; if it points to a NULL value, it will receive the
++ * device node of the first matching target phandle, with a reference held.
+ *
+ * Returns: The mapped MSI id.
+ */
+@@ -699,22 +700,6 @@ u32 of_msi_xlate(struct device *dev, struct device_node **msi_np, u32 id_in)
+ return id_out;
+ }
+
+-/**
+- * of_msi_map_id - Map a MSI ID for a device.
+- * @dev: device for which the mapping is to be done.
+- * @msi_np: device node of the expected msi controller.
+- * @id_in: unmapped MSI ID for the device.
+- *
+- * Walk up the device hierarchy looking for devices with a "msi-map"
+- * property. If found, apply the mapping to @id_in.
+- *
+- * Return: The mapped MSI ID.
+- */
+-u32 of_msi_map_id(struct device *dev, struct device_node *msi_np, u32 id_in)
+-{
+- return of_msi_xlate(dev, &msi_np, id_in);
+-}
+-
+ /**
+ * of_msi_map_get_device_domain - Use msi-map to find the relevant MSI domain
+ * @dev: device for which the mapping is to be done.
+diff --git a/drivers/pci/msi/irqdomain.c b/drivers/pci/msi/irqdomain.c
+index b11b7f63f0d6f..cbdc83c064d42 100644
+--- a/drivers/pci/msi/irqdomain.c
++++ b/drivers/pci/msi/irqdomain.c
+@@ -479,7 +479,7 @@ u32 pci_msi_domain_get_msi_rid(struct irq_domain *domain, struct pci_dev *pdev)
+ pci_for_each_dma_alias(pdev, get_msi_id_cb, &rid);
+
+ of_node = irq_domain_get_of_node(domain);
+- rid = of_node ? of_msi_map_id(&pdev->dev, of_node, rid) :
++ rid = of_node ? of_msi_xlate(&pdev->dev, &of_node, rid) :
+ iort_msi_map_id(&pdev->dev, rid);
+
+ return rid;
+diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h
+index a480063c9cb19..1db8543dfc8a6 100644
+--- a/include/linux/of_irq.h
++++ b/include/linux/of_irq.h
+@@ -55,7 +55,6 @@ extern struct irq_domain *of_msi_map_get_device_domain(struct device *dev,
+ u32 bus_token);
+ extern void of_msi_configure(struct device *dev, const struct device_node *np);
+ extern u32 of_msi_xlate(struct device *dev, struct device_node **msi_np, u32 id_in);
+-u32 of_msi_map_id(struct device *dev, struct device_node *msi_np, u32 id_in);
+ #else
+ static inline void of_irq_init(const struct of_device_id *matches)
+ {
+@@ -105,11 +104,6 @@ static inline u32 of_msi_xlate(struct device *dev, struct device_node **msi_np,
+ {
+ return id_in;
+ }
+-static inline u32 of_msi_map_id(struct device *dev,
+- struct device_node *msi_np, u32 id_in)
+-{
+- return id_in;
+-}
+ #endif
+
+ #if defined(CONFIG_OF_IRQ) || defined(CONFIG_SPARC)
+--
+2.51.0
+
--- /dev/null
+From 953ba98525e314e46320c4d964f007cb85983816 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Oct 2025 21:30:05 -0600
+Subject: RISC-V: Define pgprot_dmacoherent() for non-coherent devices
+
+From: Anup Patel <apatel@ventanamicro.com>
+
+[ Upstream commit ca525d53f994d45c8140968b571372c45f555ac1 ]
+
+The pgprot_dmacoherent() is used when allocating memory for
+non-coherent devices and by default pgprot_dmacoherent() is
+same as pgprot_noncached() unless architecture overrides it.
+
+Currently, there is no pgprot_dmacoherent() definition for
+RISC-V hence non-coherent device memory is being mapped as
+IO thereby making CPU access to such memory slow.
+
+Define pgprot_dmacoherent() to be same as pgprot_writecombine()
+for RISC-V so that CPU access non-coherent device memory as
+NOCACHE which is better than accessing it as IO.
+
+Fixes: ff689fd21cb1 ("riscv: add RISC-V Svpbmt extension support")
+Signed-off-by: Anup Patel <apatel@ventanamicro.com>
+Tested-by: Han Gao <rabenda.cn@gmail.com>
+Tested-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
+Link: https://lore.kernel.org/r/20250820152316.1012757-1-apatel@ventanamicro.com
+Signed-off-by: Paul Walmsley <pjw@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/include/asm/pgtable.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
+index 8150677429398..4355e8f3670bb 100644
+--- a/arch/riscv/include/asm/pgtable.h
++++ b/arch/riscv/include/asm/pgtable.h
+@@ -653,6 +653,8 @@ static inline pgprot_t pgprot_writecombine(pgprot_t _prot)
+ return __pgprot(prot);
+ }
+
++#define pgprot_dmacoherent pgprot_writecombine
++
+ /*
+ * Both Svade and Svadu control the hardware behavior when the PTE A/D bits need to be set. By
+ * default the M-mode firmware enables the hardware updating scheme when only Svadu is present in
+--
+2.51.0
+
--- /dev/null
+From 5a15954d4ad64f14d23c4371e3fd83984723299f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Oct 2025 22:00:09 +0530
+Subject: RISC-V: Don't print details of CPUs disabled in DT
+
+From: Anup Patel <apatel@ventanamicro.com>
+
+[ Upstream commit d2721bb165b3ee00dd23525885381af07fec852a ]
+
+Early boot stages may disable CPU DT nodes for unavailable
+CPUs based on SKU, pinstraps, eFuse, etc. Currently, the
+riscv_early_of_processor_hartid() prints details of a CPU
+if it is disabled in DT which has no value and gives a
+false impression to the users that there some issue with
+the CPU.
+
+Fixes: e3d794d555cd ("riscv: treat cpu devicetree nodes without status as enabled")
+Signed-off-by: Anup Patel <apatel@ventanamicro.com>
+Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Link: https://lore.kernel.org/r/20251014163009.182381-1-apatel@ventanamicro.com
+Signed-off-by: Paul Walmsley <pjw@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/cpu.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c
+index f6b13e9f5e6cb..3dbc8cc557dd1 100644
+--- a/arch/riscv/kernel/cpu.c
++++ b/arch/riscv/kernel/cpu.c
+@@ -62,10 +62,8 @@ int __init riscv_early_of_processor_hartid(struct device_node *node, unsigned lo
+ return -ENODEV;
+ }
+
+- if (!of_device_is_available(node)) {
+- pr_info("CPU with hartid=%lu is not available\n", *hart);
++ if (!of_device_is_available(node))
+ return -ENODEV;
+- }
+
+ if (of_property_read_string(node, "riscv,isa-base", &isa))
+ goto old_interface;
+--
+2.51.0
+
--- /dev/null
+From 9b5c932446c4b9828b61aa3ef5e45c769fcdf9f5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 18 Oct 2025 09:32:12 -0600
+Subject: riscv: hwprobe: avoid uninitialized variable use in hwprobe_arch_id()
+
+From: Paul Walmsley <pjw@kernel.org>
+
+[ Upstream commit b7776a802f2f80139f96530a489dd00fd7089eda ]
+
+Resolve this smatch warning:
+
+ arch/riscv/kernel/sys_hwprobe.c:50 hwprobe_arch_id() error: uninitialized symbol 'cpu_id'.
+
+This could happen if hwprobe_arch_id() was called with a key ID of
+something other than MVENDORID, MIMPID, and MARCHID. This does not
+happen in the current codebase. The only caller of hwprobe_arch_id()
+is a function that only passes one of those three key IDs.
+
+For the sake of reducing static analyzer warning noise, and in the
+unlikely event that hwprobe_arch_id() is someday called with some
+other key ID, validate hwprobe_arch_id()'s input to ensure that
+'cpu_id' is always initialized before use.
+
+Fixes: ea3de9ce8aa280 ("RISC-V: Add a syscall for HW probing")
+Cc: Evan Green <evan@rivosinc.com>
+Signed-off-by: Paul Walmsley <pjw@kernel.org>
+Link: https://lore.kernel.org/r/cf5a13ec-19d0-9862-059b-943f36107bf3@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/sys_hwprobe.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/arch/riscv/kernel/sys_hwprobe.c b/arch/riscv/kernel/sys_hwprobe.c
+index 3e9259790816e..5436b9d022e00 100644
+--- a/arch/riscv/kernel/sys_hwprobe.c
++++ b/arch/riscv/kernel/sys_hwprobe.c
+@@ -27,6 +27,11 @@ static void hwprobe_arch_id(struct riscv_hwprobe *pair,
+ bool first = true;
+ int cpu;
+
++ if (pair->key != RISCV_HWPROBE_KEY_MVENDORID &&
++ pair->key != RISCV_HWPROBE_KEY_MIMPID &&
++ pair->key != RISCV_HWPROBE_KEY_MARCHID)
++ goto out;
++
+ for_each_cpu(cpu, cpus) {
+ u64 cpu_id;
+
+@@ -57,6 +62,7 @@ static void hwprobe_arch_id(struct riscv_hwprobe *pair,
+ }
+ }
+
++out:
+ pair->value = id;
+ }
+
+--
+2.51.0
+
--- /dev/null
+From 7a91d8ee52f9c049710e7458f338c4ecf182d7ce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Oct 2025 11:19:34 +0200
+Subject: sched: Remove never used code in mm_cid_get()
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 53abe3e1c154628cc74e33a1bfcd865656e433a5 ]
+
+Clang is not happy with set but unused variable (this is visible
+with `make W=1` build:
+
+ kernel/sched/sched.h:3744:18: error: variable 'cpumask' set but not used [-Werror,-Wunused-but-set-variable]
+
+It seems like the variable was never used along with the assignment
+that does not have side effects as far as I can see. Remove those
+altogether.
+
+Fixes: 223baf9d17f2 ("sched: Fix performance regression introduced by mm_cid")
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Tested-by: Eric Biggers <ebiggers@kernel.org>
+Reviewed-by: Breno Leitao <leitao@debian.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/sched.h | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
+index cf2109b67f9a3..72fb9129afb6a 100644
+--- a/kernel/sched/sched.h
++++ b/kernel/sched/sched.h
+@@ -3735,11 +3735,9 @@ static inline int mm_cid_get(struct rq *rq, struct task_struct *t,
+ struct mm_struct *mm)
+ {
+ struct mm_cid __percpu *pcpu_cid = mm->pcpu_cid;
+- struct cpumask *cpumask;
+ int cid;
+
+ lockdep_assert_rq_held(rq);
+- cpumask = mm_cidmask(mm);
+ cid = __this_cpu_read(pcpu_cid->cid);
+ if (mm_cid_is_valid(cid)) {
+ mm_cid_snapshot_time(rq, mm);
+--
+2.51.0
+
ovpn-use-datagram_poll_queue-for-socket-readiness-in.patch
net-phy-micrel-always-set-shared-phydev-for-lan8814.patch
net-mlx5-fix-ipsec-cleanup-over-mpv-device.patch
+spi-rockchip-sfc-fix-dma-api-usage.patch
+firmware-arm_ffa-add-support-for-impdef-value-in-the.patch
+spi-spi-nxp-fspi-add-the-support-for-sample-data-fro.patch
+spi-spi-nxp-fspi-re-config-the-clock-rate-when-opera.patch
+spi-spi-nxp-fspi-add-extra-delay-after-dll-locked.patch
+spi-spi-nxp-fspi-limit-the-clock-rate-for-different-.patch
+spi-cadence-quadspi-fix-pm_runtime-unbalance-on-dma-.patch
+arm64-dts-broadcom-bcm2712-add-default-gic-address-c.patch
+arm64-dts-broadcom-bcm2712-define-vgic-interrupt.patch
+firmware-arm_scmi-account-for-failed-debug-initializ.patch
+include-trace-fix-inflight-count-helper-on-failed-in.patch
+firmware-arm_scmi-fix-premature-scmi_xfer_flag_is_ra.patch
+spi-airoha-return-an-error-for-continuous-mode-dirma.patch
+spi-airoha-add-support-of-dual-quad-wires-spi-modes-.patch
+spi-airoha-switch-back-to-non-dma-mode-in-the-case-o.patch
+spi-airoha-fix-reading-writing-of-flashes-with-more-.patch
+sysfs-check-visibility-before-changing-group-attribu.patch
+drm-panthor-fix-kernel-panic-on-partial-unmap-of-a-g.patch
+risc-v-define-pgprot_dmacoherent-for-non-coherent-de.patch
+risc-v-don-t-print-details-of-cpus-disabled-in-dt.patch
+riscv-hwprobe-avoid-uninitialized-variable-use-in-hw.patch
+hwmon-pmbus-isl68137-fix-child-node-reference-leak-o.patch
+hwmon-cgbc-hwmon-add-missing-null-check-after-devm_k.patch
+hwmon-sht3x-fix-error-handling.patch
+io_uring-fix-incorrect-unlikely-usage-in-io_waitid_p.patch
+nbd-override-creds-to-kernel-when-calling-sock_-send.patch
+drm-panic-fix-drawing-the-logo-on-a-small-narrow-scr.patch
+drm-panic-fix-qr_code-ensure-vmargin-is-positive.patch
+drm-panic-fix-24bit-pixel-crossing-page-boundaries.patch
+of-irq-convert-of_msi_map_id-callers-to-of_msi_xlate.patch
+of-irq-add-msi-parent-check-to-of_msi_xlate.patch
+block-require-lba-dma_alignment-when-using-pi.patch
+gpio-ljca-fix-duplicated-irq-mapping.patch
+io_uring-correct-__must_hold-annotation-in-io_instal.patch
+sched-remove-never-used-code-in-mm_cid_get.patch
--- /dev/null
+From faa8f2d2b8713400e15ba41ae0e3425a60614f67 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Oct 2025 15:16:54 +0300
+Subject: spi: airoha: add support of dual/quad wires spi modes to exec_op()
+ handler
+
+From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+
+[ Upstream commit edd2e261b1babb92213089b5feadca12e3459322 ]
+
+Booting without this patch and disabled dirmap support results in
+
+[ 2.980719] spi-nand spi0.0: Micron SPI NAND was found.
+[ 2.986040] spi-nand spi0.0: 256 MiB, block size: 128 KiB, page size: 2048, OOB size: 128
+[ 2.994709] 2 fixed-partitions partitions found on MTD device spi0.0
+[ 3.001075] Creating 2 MTD partitions on "spi0.0":
+[ 3.005862] 0x000000000000-0x000000020000 : "bl2"
+[ 3.011272] 0x000000020000-0x000010000000 : "ubi"
+...
+[ 6.195594] ubi0: attaching mtd1
+[ 13.338398] ubi0: scanning is finished
+[ 13.342188] ubi0 error: ubi_read_volume_table: the layout volume was not found
+[ 13.349784] ubi0 error: ubi_attach_mtd_dev: failed to attach mtd1, error -22
+[ 13.356897] UBI error: cannot attach mtd1
+
+If dirmap is disabled or not supported in the spi driver, the dirmap requests
+will be executed via exec_op() handler. Thus, if the hardware supports
+dual/quad spi modes, then corresponding requests will be sent to exec_op()
+handler. Current driver does not support such requests, so error is arrised.
+As result the flash can't be read/write.
+
+This patch adds support of dual and quad wires spi modes to exec_op() handler.
+
+Fixes: a403997c12019 ("spi: airoha: add SPI-NAND Flash controller driver")
+Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://patch.msgid.link/20251012121707.2296160-4-mikhail.kshevetskiy@iopsys.eu
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-airoha-snfi.c | 108 ++++++++++++++++++++++++++--------
+ 1 file changed, 82 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/spi/spi-airoha-snfi.c b/drivers/spi/spi-airoha-snfi.c
+index 043a03cd90a19..0b89dc42545b1 100644
+--- a/drivers/spi/spi-airoha-snfi.c
++++ b/drivers/spi/spi-airoha-snfi.c
+@@ -192,6 +192,14 @@
+ #define SPI_NAND_OP_RESET 0xff
+ #define SPI_NAND_OP_DIE_SELECT 0xc2
+
++/* SNAND FIFO commands */
++#define SNAND_FIFO_TX_BUSWIDTH_SINGLE 0x08
++#define SNAND_FIFO_TX_BUSWIDTH_DUAL 0x09
++#define SNAND_FIFO_TX_BUSWIDTH_QUAD 0x0a
++#define SNAND_FIFO_RX_BUSWIDTH_SINGLE 0x0c
++#define SNAND_FIFO_RX_BUSWIDTH_DUAL 0x0e
++#define SNAND_FIFO_RX_BUSWIDTH_QUAD 0x0f
++
+ #define SPI_NAND_CACHE_SIZE (SZ_4K + SZ_256)
+ #define SPI_MAX_TRANSFER_SIZE 511
+
+@@ -387,10 +395,26 @@ static int airoha_snand_set_mode(struct airoha_snand_ctrl *as_ctrl,
+ return regmap_write(as_ctrl->regmap_ctrl, REG_SPI_CTRL_DUMMY, 0);
+ }
+
+-static int airoha_snand_write_data(struct airoha_snand_ctrl *as_ctrl, u8 cmd,
+- const u8 *data, int len)
++static int airoha_snand_write_data(struct airoha_snand_ctrl *as_ctrl,
++ const u8 *data, int len, int buswidth)
+ {
+ int i, data_len;
++ u8 cmd;
++
++ switch (buswidth) {
++ case 0:
++ case 1:
++ cmd = SNAND_FIFO_TX_BUSWIDTH_SINGLE;
++ break;
++ case 2:
++ cmd = SNAND_FIFO_TX_BUSWIDTH_DUAL;
++ break;
++ case 4:
++ cmd = SNAND_FIFO_TX_BUSWIDTH_QUAD;
++ break;
++ default:
++ return -EINVAL;
++ }
+
+ for (i = 0; i < len; i += data_len) {
+ int err;
+@@ -409,16 +433,32 @@ static int airoha_snand_write_data(struct airoha_snand_ctrl *as_ctrl, u8 cmd,
+ return 0;
+ }
+
+-static int airoha_snand_read_data(struct airoha_snand_ctrl *as_ctrl, u8 *data,
+- int len)
++static int airoha_snand_read_data(struct airoha_snand_ctrl *as_ctrl,
++ u8 *data, int len, int buswidth)
+ {
+ int i, data_len;
++ u8 cmd;
++
++ switch (buswidth) {
++ case 0:
++ case 1:
++ cmd = SNAND_FIFO_RX_BUSWIDTH_SINGLE;
++ break;
++ case 2:
++ cmd = SNAND_FIFO_RX_BUSWIDTH_DUAL;
++ break;
++ case 4:
++ cmd = SNAND_FIFO_RX_BUSWIDTH_QUAD;
++ break;
++ default:
++ return -EINVAL;
++ }
+
+ for (i = 0; i < len; i += data_len) {
+ int err;
+
+ data_len = min(len - i, SPI_MAX_TRANSFER_SIZE);
+- err = airoha_snand_set_fifo_op(as_ctrl, 0xc, data_len);
++ err = airoha_snand_set_fifo_op(as_ctrl, cmd, data_len);
+ if (err)
+ return err;
+
+@@ -902,12 +942,28 @@ static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc,
+ static int airoha_snand_exec_op(struct spi_mem *mem,
+ const struct spi_mem_op *op)
+ {
+- u8 data[8], cmd, opcode = op->cmd.opcode;
+ struct airoha_snand_ctrl *as_ctrl;
++ int op_len, addr_len, dummy_len;
++ u8 buf[20], *data;
+ int i, err;
+
+ as_ctrl = spi_controller_get_devdata(mem->spi->controller);
+
++ op_len = op->cmd.nbytes;
++ addr_len = op->addr.nbytes;
++ dummy_len = op->dummy.nbytes;
++
++ if (op_len + dummy_len + addr_len > sizeof(buf))
++ return -EIO;
++
++ data = buf;
++ for (i = 0; i < op_len; i++)
++ *data++ = op->cmd.opcode >> (8 * (op_len - i - 1));
++ for (i = 0; i < addr_len; i++)
++ *data++ = op->addr.val >> (8 * (addr_len - i - 1));
++ for (i = 0; i < dummy_len; i++)
++ *data++ = 0xff;
++
+ /* switch to manual mode */
+ err = airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL);
+ if (err < 0)
+@@ -918,40 +974,40 @@ static int airoha_snand_exec_op(struct spi_mem *mem,
+ return err;
+
+ /* opcode */
+- err = airoha_snand_write_data(as_ctrl, 0x8, &opcode, sizeof(opcode));
++ data = buf;
++ err = airoha_snand_write_data(as_ctrl, data, op_len,
++ op->cmd.buswidth);
+ if (err)
+ return err;
+
+ /* addr part */
+- cmd = opcode == SPI_NAND_OP_GET_FEATURE ? 0x11 : 0x8;
+- put_unaligned_be64(op->addr.val, data);
+-
+- for (i = ARRAY_SIZE(data) - op->addr.nbytes;
+- i < ARRAY_SIZE(data); i++) {
+- err = airoha_snand_write_data(as_ctrl, cmd, &data[i],
+- sizeof(data[0]));
++ data += op_len;
++ if (addr_len) {
++ err = airoha_snand_write_data(as_ctrl, data, addr_len,
++ op->addr.buswidth);
+ if (err)
+ return err;
+ }
+
+ /* dummy */
+- data[0] = 0xff;
+- for (i = 0; i < op->dummy.nbytes; i++) {
+- err = airoha_snand_write_data(as_ctrl, 0x8, &data[0],
+- sizeof(data[0]));
++ data += addr_len;
++ if (dummy_len) {
++ err = airoha_snand_write_data(as_ctrl, data, dummy_len,
++ op->dummy.buswidth);
+ if (err)
+ return err;
+ }
+
+ /* data */
+- if (op->data.dir == SPI_MEM_DATA_IN) {
+- err = airoha_snand_read_data(as_ctrl, op->data.buf.in,
+- op->data.nbytes);
+- if (err)
+- return err;
+- } else {
+- err = airoha_snand_write_data(as_ctrl, 0x8, op->data.buf.out,
+- op->data.nbytes);
++ if (op->data.nbytes) {
++ if (op->data.dir == SPI_MEM_DATA_IN)
++ err = airoha_snand_read_data(as_ctrl, op->data.buf.in,
++ op->data.nbytes,
++ op->data.buswidth);
++ else
++ err = airoha_snand_write_data(as_ctrl, op->data.buf.out,
++ op->data.nbytes,
++ op->data.buswidth);
+ if (err)
+ return err;
+ }
+--
+2.51.0
+
--- /dev/null
+From a6a83c357af5f6f88ecb8963ee2d10f4721c6e20 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Oct 2025 15:16:57 +0300
+Subject: spi: airoha: fix reading/writing of flashes with more than one plane
+ per lun
+
+From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+
+[ Upstream commit 0b7d9b25e4bc2e478c9d06281a65f930769fca09 ]
+
+Attaching UBI on the flash with more than one plane per lun will lead to
+the following error:
+
+[ 2.980989] spi-nand spi0.0: Micron SPI NAND was found.
+[ 2.986309] spi-nand spi0.0: 256 MiB, block size: 128 KiB, page size: 2048, OOB size: 128
+[ 2.994978] 2 fixed-partitions partitions found on MTD device spi0.0
+[ 3.001350] Creating 2 MTD partitions on "spi0.0":
+[ 3.006159] 0x000000000000-0x000000020000 : "bl2"
+[ 3.011663] 0x000000020000-0x000010000000 : "ubi"
+...
+[ 6.391748] ubi0: attaching mtd1
+[ 6.412545] ubi0 error: ubi_attach: PEB 0 contains corrupted VID header, and the data does not contain all 0xFF
+[ 6.422677] ubi0 error: ubi_attach: this may be a non-UBI PEB or a severe VID header corruption which requires manual inspection
+[ 6.434249] Volume identifier header dump:
+[ 6.438349] magic 55424923
+[ 6.441482] version 1
+[ 6.444007] vol_type 0
+[ 6.446539] copy_flag 0
+[ 6.449068] compat 0
+[ 6.451594] vol_id 0
+[ 6.454120] lnum 1
+[ 6.456651] data_size 4096
+[ 6.459442] used_ebs 1061644134
+[ 6.462748] data_pad 0
+[ 6.465274] sqnum 0
+[ 6.467805] hdr_crc 61169820
+[ 6.470943] Volume identifier header hexdump:
+[ 6.475308] hexdump of PEB 0 offset 4096, length 126976
+[ 6.507391] ubi0 warning: ubi_attach: valid VID header but corrupted EC header at PEB 4
+[ 6.515415] ubi0 error: ubi_compare_lebs: unsupported on-flash UBI format
+[ 6.522222] ubi0 error: ubi_attach_mtd_dev: failed to attach mtd1, error -22
+[ 6.529294] UBI error: cannot attach mtd1
+
+Non dirmap reading works good. Looking to spi_mem_no_dirmap_read() code we'll see:
+
+ static ssize_t spi_mem_no_dirmap_read(struct spi_mem_dirmap_desc *desc,
+ u64 offs, size_t len, void *buf)
+ {
+ struct spi_mem_op op = desc->info.op_tmpl;
+ int ret;
+
+// --- see here ---
+ op.addr.val = desc->info.offset + offs;
+//-----------------
+ op.data.buf.in = buf;
+ op.data.nbytes = len;
+ ret = spi_mem_adjust_op_size(desc->mem, &op);
+ if (ret)
+ return ret;
+
+ ret = spi_mem_exec_op(desc->mem, &op);
+ if (ret)
+ return ret;
+
+ return op.data.nbytes;
+ }
+
+The similar happens for spi_mem_no_dirmap_write(). Thus the address
+passed to the flash should take in the account the value of
+desc->info.offset.
+
+This patch fix dirmap reading/writing of flashes with more than one
+plane per lun.
+
+Fixes: a403997c12019 ("spi: airoha: add SPI-NAND Flash controller driver")
+Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://patch.msgid.link/20251012121707.2296160-7-mikhail.kshevetskiy@iopsys.eu
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-airoha-snfi.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/spi/spi-airoha-snfi.c b/drivers/spi/spi-airoha-snfi.c
+index 8143fbb0cf4e6..b78163eaed61d 100644
+--- a/drivers/spi/spi-airoha-snfi.c
++++ b/drivers/spi/spi-airoha-snfi.c
+@@ -733,8 +733,9 @@ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc,
+ if (err)
+ goto error_dma_unmap;
+
+- /* set read addr */
+- err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_RD_CTL3, 0x0);
++ /* set read addr: zero page offset + descriptor read offset */
++ err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_RD_CTL3,
++ desc->info.offset);
+ if (err)
+ goto error_dma_unmap;
+
+@@ -870,7 +871,9 @@ static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc,
+ if (err)
+ goto error_dma_unmap;
+
+- err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_PG_CTL2, 0x0);
++ /* set write addr: zero page offset + descriptor write offset */
++ err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_PG_CTL2,
++ desc->info.offset);
+ if (err)
+ goto error_dma_unmap;
+
+--
+2.51.0
+
--- /dev/null
+From 0cc5c48f5c004e1ae9931cdf873892d5d9a223a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Oct 2025 15:16:52 +0300
+Subject: spi: airoha: return an error for continuous mode dirmap creation
+ cases
+
+From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+
+[ Upstream commit 4314ffce4eb81a6c18700af1b6e29b6e0c6b9e37 ]
+
+This driver can accelerate single page operations only, thus
+continuous reading mode should not be used.
+
+Continuous reading will use sizes up to the size of one erase block.
+This size is much larger than the size of single flash page. Use this
+difference to identify continuous reading and return an error.
+
+Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+Reviewed-by: Frieder Schrempf <frieder.schrempf@kontron.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Fixes: a403997c12019 ("spi: airoha: add SPI-NAND Flash controller driver")
+Link: https://patch.msgid.link/20251012121707.2296160-2-mikhail.kshevetskiy@iopsys.eu
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-airoha-snfi.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/spi/spi-airoha-snfi.c b/drivers/spi/spi-airoha-snfi.c
+index dbe640986825e..043a03cd90a19 100644
+--- a/drivers/spi/spi-airoha-snfi.c
++++ b/drivers/spi/spi-airoha-snfi.c
+@@ -618,6 +618,10 @@ static int airoha_snand_dirmap_create(struct spi_mem_dirmap_desc *desc)
+ if (desc->info.offset + desc->info.length > U32_MAX)
+ return -EINVAL;
+
++ /* continuous reading is not supported */
++ if (desc->info.length > SPI_NAND_CACHE_SIZE)
++ return -E2BIG;
++
+ if (!airoha_snand_supports_op(desc->mem, &desc->info.op_tmpl))
+ return -EOPNOTSUPP;
+
+--
+2.51.0
+
--- /dev/null
+From df7866ba7837d55486bfb76f478629a2fee25f9d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Oct 2025 15:16:56 +0300
+Subject: spi: airoha: switch back to non-dma mode in the case of error
+
+From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+
+[ Upstream commit 20d7b236b78c7ec685a22db5689b9c829975e0c3 ]
+
+Current dirmap code does not switch back to non-dma mode in the case of
+error. This is wrong.
+
+This patch fixes dirmap read/write error path.
+
+Fixes: a403997c12019 ("spi: airoha: add SPI-NAND Flash controller driver")
+Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://patch.msgid.link/20251012121707.2296160-6-mikhail.kshevetskiy@iopsys.eu
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-airoha-snfi.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/spi/spi-airoha-snfi.c b/drivers/spi/spi-airoha-snfi.c
+index 0b89dc42545b1..8143fbb0cf4e6 100644
+--- a/drivers/spi/spi-airoha-snfi.c
++++ b/drivers/spi/spi-airoha-snfi.c
+@@ -698,13 +698,13 @@ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc,
+
+ err = airoha_snand_nfi_config(as_ctrl);
+ if (err)
+- return err;
++ goto error_dma_mode_off;
+
+ dma_addr = dma_map_single(as_ctrl->dev, txrx_buf, SPI_NAND_CACHE_SIZE,
+ DMA_FROM_DEVICE);
+ err = dma_mapping_error(as_ctrl->dev, dma_addr);
+ if (err)
+- return err;
++ goto error_dma_mode_off;
+
+ /* set dma addr */
+ err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_STRADDR,
+@@ -804,6 +804,8 @@ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc,
+ error_dma_unmap:
+ dma_unmap_single(as_ctrl->dev, dma_addr, SPI_NAND_CACHE_SIZE,
+ DMA_FROM_DEVICE);
++error_dma_mode_off:
++ airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL);
+ return err;
+ }
+
+@@ -936,6 +938,7 @@ static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc,
+ error_dma_unmap:
+ dma_unmap_single(as_ctrl->dev, dma_addr, SPI_NAND_CACHE_SIZE,
+ DMA_TO_DEVICE);
++ airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL);
+ return err;
+ }
+
+--
+2.51.0
+
--- /dev/null
+From ef88b99d0731b232914ce0243ddd0cc04a5d52ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Oct 2025 09:10:38 +0200
+Subject: spi: cadence-quadspi: Fix pm_runtime unbalance on dma EPROBE_DEFER
+
+From: Mattijs Korpershoek <mkorpershoek@kernel.org>
+
+[ Upstream commit 8735696acea24ac1f9d4490992418c71941ca68c ]
+
+In csqspi_probe(), when cqspi_request_mmap_dma() returns -EPROBE_DEFER,
+we handle the error by jumping to probe_setup_failed.
+In that label, we call pm_runtime_disable(), even if we never called
+pm_runtime_enable() before.
+
+Because of this, the driver cannot probe:
+
+[ 2.690018] cadence-qspi 47040000.spi: No Rx DMA available
+[ 2.699735] spi-nor spi0.0: resume failed with -13
+[ 2.699741] spi-nor: probe of spi0.0 failed with error -13
+
+Only call pm_runtime_disable() if it was enabled by adding a new
+label to handle cqspi_request_mmap_dma() failures.
+
+Fixes: b07f349d1864 ("spi: spi-cadence-quadspi: Fix pm runtime unbalance")
+Signed-off-by: Mattijs Korpershoek <mkorpershoek@kernel.org>
+Reviewed-by: Dan Carpenter <dan.carpenter@linaro.org>
+Link: https://patch.msgid.link/20251009-cadence-quadspi-fix-pm-runtime-v2-1-8bdfefc43902@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-cadence-quadspi.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c
+index d1a59120d3845..ce0f605ab688b 100644
+--- a/drivers/spi/spi-cadence-quadspi.c
++++ b/drivers/spi/spi-cadence-quadspi.c
+@@ -1995,7 +1995,7 @@ static int cqspi_probe(struct platform_device *pdev)
+ if (cqspi->use_direct_mode) {
+ ret = cqspi_request_mmap_dma(cqspi);
+ if (ret == -EPROBE_DEFER)
+- goto probe_setup_failed;
++ goto probe_dma_failed;
+ }
+
+ if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM))) {
+@@ -2019,9 +2019,10 @@ static int cqspi_probe(struct platform_device *pdev)
+
+ return 0;
+ probe_setup_failed:
+- cqspi_controller_enable(cqspi, 0);
+ if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM)))
+ pm_runtime_disable(dev);
++probe_dma_failed:
++ cqspi_controller_enable(cqspi, 0);
+ probe_reset_failed:
+ if (cqspi->is_jh7110)
+ cqspi_jh7110_disable_clk(pdev, cqspi);
+--
+2.51.0
+
--- /dev/null
+From 4926c4660250380f56198d7ca85d92db982198f4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Oct 2025 13:42:39 +0200
+Subject: spi: rockchip-sfc: Fix DMA-API usage
+
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+
+[ Upstream commit ee795e82e10197c070efd380dc9615c73dffad6c ]
+
+Use DMA-API dma_map_single() call for getting the DMA address of the
+transfer buffer instead of hacking with virt_to_phys().
+
+This fixes the following DMA-API debug warning:
+------------[ cut here ]------------
+DMA-API: rockchip-sfc fe300000.spi: device driver tries to sync DMA memory it has not allocated [device address=0x000000000cf70000] [size=288 bytes]
+WARNING: kernel/dma/debug.c:1106 at check_sync+0x1d8/0x690, CPU#2: systemd-udevd/151
+Modules linked in: ...
+Hardware name: Hardkernel ODROID-M1 (DT)
+pstate: 604000c9 (nZCv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+pc : check_sync+0x1d8/0x690
+lr : check_sync+0x1d8/0x690
+..
+Call trace:
+ check_sync+0x1d8/0x690 (P)
+ debug_dma_sync_single_for_cpu+0x84/0x8c
+ __dma_sync_single_for_cpu+0x88/0x234
+ rockchip_sfc_exec_mem_op+0x4a0/0x798 [spi_rockchip_sfc]
+ spi_mem_exec_op+0x408/0x498
+ spi_nor_read_data+0x170/0x184
+ spi_nor_read_sfdp+0x74/0xe4
+ spi_nor_parse_sfdp+0x120/0x11f0
+ spi_nor_sfdp_init_params_deprecated+0x3c/0x8c
+ spi_nor_scan+0x690/0xf88
+ spi_nor_probe+0xe4/0x304
+ spi_mem_probe+0x6c/0xa8
+ spi_probe+0x94/0xd4
+ really_probe+0xbc/0x298
+ ...
+
+Fixes: b69386fcbc60 ("spi: rockchip-sfc: Using normal memory for dma")
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Link: https://patch.msgid.link/20251003114239.431114-1-m.szyprowski@samsung.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-rockchip-sfc.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-rockchip-sfc.c b/drivers/spi/spi-rockchip-sfc.c
+index 9eba5c0a60f23..b3c2b03b11535 100644
+--- a/drivers/spi/spi-rockchip-sfc.c
++++ b/drivers/spi/spi-rockchip-sfc.c
+@@ -704,7 +704,12 @@ static int rockchip_sfc_probe(struct platform_device *pdev)
+ ret = -ENOMEM;
+ goto err_dma;
+ }
+- sfc->dma_buffer = virt_to_phys(sfc->buffer);
++ sfc->dma_buffer = dma_map_single(dev, sfc->buffer,
++ sfc->max_iosize, DMA_BIDIRECTIONAL);
++ if (dma_mapping_error(dev, sfc->dma_buffer)) {
++ ret = -ENOMEM;
++ goto err_dma_map;
++ }
+ }
+
+ ret = devm_spi_register_controller(dev, host);
+@@ -715,6 +720,9 @@ static int rockchip_sfc_probe(struct platform_device *pdev)
+
+ return 0;
+ err_register:
++ dma_unmap_single(dev, sfc->dma_buffer, sfc->max_iosize,
++ DMA_BIDIRECTIONAL);
++err_dma_map:
+ free_pages((unsigned long)sfc->buffer, get_order(sfc->max_iosize));
+ err_dma:
+ pm_runtime_get_sync(dev);
+@@ -736,6 +744,8 @@ static void rockchip_sfc_remove(struct platform_device *pdev)
+ struct spi_controller *host = sfc->host;
+
+ spi_unregister_controller(host);
++ dma_unmap_single(&pdev->dev, sfc->dma_buffer, sfc->max_iosize,
++ DMA_BIDIRECTIONAL);
+ free_pages((unsigned long)sfc->buffer, get_order(sfc->max_iosize));
+
+ clk_disable_unprepare(sfc->clk);
+--
+2.51.0
+
--- /dev/null
+From ef364cd7867e3e5ed5261ea0bef440bb9e08945e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Sep 2025 16:47:14 +0800
+Subject: spi: spi-nxp-fspi: add extra delay after dll locked
+
+From: Han Xu <han.xu@nxp.com>
+
+[ Upstream commit b93b4269791fdebbac2a9ad26f324dc2abb9e60f ]
+
+Due to the erratum ERR050272, the DLL lock status register STS2
+[xREFLOCK, xSLVLOCK] bit may indicate DLL is locked before DLL is
+actually locked. Add an extra 4us delay as a workaround.
+
+refer to ERR050272, on Page 20.
+https://www.nxp.com/docs/en/errata/IMX8_1N94W.pdf
+
+Fixes: 99d822b3adc4 ("spi: spi-nxp-fspi: use DLL calibration when clock rate > 100MHz")
+Signed-off-by: Han Xu <han.xu@nxp.com>
+Signed-off-by: Haibo Chen <haibo.chen@nxp.com>
+Link: https://patch.msgid.link/20250922-fspi-fix-v1-2-ff4315359d31@nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-nxp-fspi.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c
+index 542d6f57c1aef..bde6d131ab8b7 100644
+--- a/drivers/spi/spi-nxp-fspi.c
++++ b/drivers/spi/spi-nxp-fspi.c
+@@ -709,6 +709,12 @@ static void nxp_fspi_dll_calibration(struct nxp_fspi *f)
+ 0, POLL_TOUT, true);
+ if (ret)
+ dev_warn(f->dev, "DLL lock failed, please fix it!\n");
++
++ /*
++ * For ERR050272, DLL lock status bit is not accurate,
++ * wait for 4us more as a workaround.
++ */
++ udelay(4);
+ }
+
+ /*
+--
+2.51.0
+
--- /dev/null
+From 6ea69e010ee2dfb405b0e2bcbcef0631e1c16c6d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Sep 2025 15:27:09 +0800
+Subject: spi: spi-nxp-fspi: add the support for sample data from DQS pad
+
+From: Haibo Chen <haibo.chen@nxp.com>
+
+[ Upstream commit c07f270323175b83779c2c2b80b360ed476baec5 ]
+
+flexspi define four mode for sample clock source selection.
+Here is the list of modes:
+mode 0: Dummy Read strobe generated by FlexSPI Controller and loopback
+ internally
+mode 1: Dummy Read strobe generated by FlexSPI Controller and loopback
+ from DQS pad
+mode 2: Reserved
+mode 3: Flash provided Read strobe and input from DQS pad
+
+In default, flexspi use mode 0 after reset. And for DTR mode, flexspi
+only support 8D-8D-8D mode. For 8D-8D-8D mode, IC suggest to use mode 3,
+otherwise read always get incorrect data.
+
+For DTR mode, flexspi will automatically div 2 of the root clock
+and output to device. the formula is:
+ device_clock = root_clock / (is_dtr ? 2 : 1)
+So correct the clock rate setting for DTR mode to get the max
+performance.
+
+Signed-off-by: Haibo Chen <haibo.chen@nxp.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Link: https://patch.msgid.link/20250917-flexspi-ddr-v2-4-bb9fe2a01889@nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: a89103f67112 ("spi: spi-nxp-fspi: re-config the clock rate when operation require new clock rate")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-nxp-fspi.c | 56 ++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 53 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c
+index b92bfef47371f..7cbe774f1f39b 100644
+--- a/drivers/spi/spi-nxp-fspi.c
++++ b/drivers/spi/spi-nxp-fspi.c
+@@ -399,7 +399,8 @@ struct nxp_fspi {
+ struct mutex lock;
+ struct pm_qos_request pm_qos_req;
+ int selected;
+-#define FSPI_NEED_INIT (1 << 0)
++#define FSPI_NEED_INIT BIT(0)
++#define FSPI_DTR_MODE BIT(1)
+ int flags;
+ };
+
+@@ -645,6 +646,40 @@ static void nxp_fspi_clk_disable_unprep(struct nxp_fspi *f)
+ return;
+ }
+
++/*
++ * Sample Clock source selection for Flash Reading
++ * Four modes defined by fspi:
++ * mode 0: Dummy Read strobe generated by FlexSPI Controller
++ * and loopback internally
++ * mode 1: Dummy Read strobe generated by FlexSPI Controller
++ * and loopback from DQS pad
++ * mode 2: Reserved
++ * mode 3: Flash provided Read strobe and input from DQS pad
++ *
++ * fspi default use mode 0 after reset
++ */
++static void nxp_fspi_select_rx_sample_clk_source(struct nxp_fspi *f,
++ bool op_is_dtr)
++{
++ u32 reg;
++
++ /*
++ * For 8D-8D-8D mode, need to use mode 3 (Flash provided Read
++ * strobe and input from DQS pad), otherwise read operaton may
++ * meet issue.
++ * This mode require flash device connect the DQS pad on board.
++ * For other modes, still use mode 0, keep align with before.
++ * spi_nor_suspend will disable 8D-8D-8D mode, also need to
++ * change the mode back to mode 0.
++ */
++ reg = fspi_readl(f, f->iobase + FSPI_MCR0);
++ if (op_is_dtr)
++ reg |= FSPI_MCR0_RXCLKSRC(3);
++ else /*select mode 0 */
++ reg &= ~FSPI_MCR0_RXCLKSRC(3);
++ fspi_writel(f, reg, f->iobase + FSPI_MCR0);
++}
++
+ static void nxp_fspi_dll_calibration(struct nxp_fspi *f)
+ {
+ int ret;
+@@ -715,15 +750,18 @@ static void nxp_fspi_dll_calibration(struct nxp_fspi *f)
+ static void nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi,
+ const struct spi_mem_op *op)
+ {
++ /* flexspi only support one DTR mode: 8D-8D-8D */
++ bool op_is_dtr = op->cmd.dtr && op->addr.dtr && op->dummy.dtr && op->data.dtr;
+ unsigned long rate = op->max_freq;
+ int ret;
+ uint64_t size_kb;
+
+ /*
+ * Return, if previously selected target device is same as current
+- * requested target device.
++ * requested target device. Also the DTR or STR mode do not change.
+ */
+- if (f->selected == spi_get_chipselect(spi, 0))
++ if ((f->selected == spi_get_chipselect(spi, 0)) &&
++ (!!(f->flags & FSPI_DTR_MODE) == op_is_dtr))
+ return;
+
+ /* Reset FLSHxxCR0 registers */
+@@ -740,6 +778,18 @@ static void nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi,
+
+ dev_dbg(f->dev, "Target device [CS:%x] selected\n", spi_get_chipselect(spi, 0));
+
++ nxp_fspi_select_rx_sample_clk_source(f, op_is_dtr);
++
++ if (op_is_dtr) {
++ f->flags |= FSPI_DTR_MODE;
++ /* For DTR mode, flexspi will default div 2 and output to device.
++ * so here to config the root clock to 2 * device rate.
++ */
++ rate = rate * 2;
++ } else {
++ f->flags &= ~FSPI_DTR_MODE;
++ }
++
+ nxp_fspi_clk_disable_unprep(f);
+
+ ret = clk_set_rate(f->clk, rate);
+--
+2.51.0
+
--- /dev/null
+From 75d2b5386a554394500ea2f690ad347b8dd1f2e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Sep 2025 16:47:15 +0800
+Subject: spi: spi-nxp-fspi: limit the clock rate for different sample clock
+ source selection
+
+From: Haibo Chen <haibo.chen@nxp.com>
+
+[ Upstream commit f43579ef3500527649b1c233be7cf633806353aa ]
+
+For different sample clock source selection, the max frequency
+flexspi supported are different. For mode 0, max frequency is 66MHz.
+For mode 3, the max frequency is 166MHz.
+
+Refer to 3.9.9 FlexSPI timing parameters on page 65.
+https://www.nxp.com/docs/en/data-sheet/IMX8MNCEC.pdf
+
+Though flexspi maybe still work under higher frequency, but can't
+guarantee the stability. IC suggest to add this limitation on all
+SoCs which contain flexspi.
+
+Fixes: c07f27032317 ("spi: spi-nxp-fspi: add the support for sample data from DQS pad")
+Signed-off-by: Haibo Chen <haibo.chen@nxp.com>
+Link: https://patch.msgid.link/20250922-fspi-fix-v1-3-ff4315359d31@nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-nxp-fspi.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c
+index bde6d131ab8b7..ab13f11242c3c 100644
+--- a/drivers/spi/spi-nxp-fspi.c
++++ b/drivers/spi/spi-nxp-fspi.c
+@@ -404,6 +404,8 @@ struct nxp_fspi {
+ int flags;
+ /* save the previous operation clock rate */
+ unsigned long pre_op_rate;
++ /* the max clock rate fspi output to device */
++ unsigned long max_rate;
+ };
+
+ static inline int needs_ip_only(struct nxp_fspi *f)
+@@ -675,10 +677,13 @@ static void nxp_fspi_select_rx_sample_clk_source(struct nxp_fspi *f,
+ * change the mode back to mode 0.
+ */
+ reg = fspi_readl(f, f->iobase + FSPI_MCR0);
+- if (op_is_dtr)
++ if (op_is_dtr) {
+ reg |= FSPI_MCR0_RXCLKSRC(3);
+- else /*select mode 0 */
++ f->max_rate = 166000000;
++ } else { /*select mode 0 */
+ reg &= ~FSPI_MCR0_RXCLKSRC(3);
++ f->max_rate = 66000000;
++ }
+ fspi_writel(f, reg, f->iobase + FSPI_MCR0);
+ }
+
+@@ -793,6 +798,7 @@ static void nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi,
+ dev_dbg(f->dev, "Target device [CS:%x] selected\n", spi_get_chipselect(spi, 0));
+
+ nxp_fspi_select_rx_sample_clk_source(f, op_is_dtr);
++ rate = min(f->max_rate, op->max_freq);
+
+ if (op_is_dtr) {
+ f->flags |= FSPI_DTR_MODE;
+--
+2.51.0
+
--- /dev/null
+From 2413585fd3efaf09fa87c0836d0365e619314b39 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Sep 2025 16:47:13 +0800
+Subject: spi: spi-nxp-fspi: re-config the clock rate when operation require
+ new clock rate
+
+From: Haibo Chen <haibo.chen@nxp.com>
+
+[ Upstream commit a89103f67112453fa36c9513e951c19eed9d2d92 ]
+
+Current operation contain the max_freq, so new coming operation may use
+new clock rate, need to re-config the clock rate to match the requirement.
+
+Fixes: 26851cf65ffc ("spi: nxp-fspi: Support per spi-mem operation frequency switches")
+Signed-off-by: Haibo Chen <haibo.chen@nxp.com>
+Link: https://patch.msgid.link/20250922-fspi-fix-v1-1-ff4315359d31@nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-nxp-fspi.c | 16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c
+index 7cbe774f1f39b..542d6f57c1aef 100644
+--- a/drivers/spi/spi-nxp-fspi.c
++++ b/drivers/spi/spi-nxp-fspi.c
+@@ -402,6 +402,8 @@ struct nxp_fspi {
+ #define FSPI_NEED_INIT BIT(0)
+ #define FSPI_DTR_MODE BIT(1)
+ int flags;
++ /* save the previous operation clock rate */
++ unsigned long pre_op_rate;
+ };
+
+ static inline int needs_ip_only(struct nxp_fspi *f)
+@@ -757,11 +759,17 @@ static void nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi,
+ uint64_t size_kb;
+
+ /*
+- * Return, if previously selected target device is same as current
+- * requested target device. Also the DTR or STR mode do not change.
++ * Return when following condition all meet,
++ * 1, if previously selected target device is same as current
++ * requested target device.
++ * 2, the DTR or STR mode do not change.
++ * 3, previous operation max rate equals current one.
++ *
++ * For other case, need to re-config.
+ */
+ if ((f->selected == spi_get_chipselect(spi, 0)) &&
+- (!!(f->flags & FSPI_DTR_MODE) == op_is_dtr))
++ (!!(f->flags & FSPI_DTR_MODE) == op_is_dtr) &&
++ (f->pre_op_rate == op->max_freq))
+ return;
+
+ /* Reset FLSHxxCR0 registers */
+@@ -807,6 +815,8 @@ static void nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi,
+ if (rate > 100000000)
+ nxp_fspi_dll_calibration(f);
+
++ f->pre_op_rate = op->max_freq;
++
+ f->selected = spi_get_chipselect(spi, 0);
+ }
+
+--
+2.51.0
+
--- /dev/null
+From 019831271dae4bb829597661ef0214273e05aba3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Oct 2025 12:14:56 +0200
+Subject: sysfs: check visibility before changing group attribute ownership
+
+From: Fernando Fernandez Mancera <fmancera@suse.de>
+
+[ Upstream commit c7fbb8218b4ad35fec0bd2256d2b9c8d60331f33 ]
+
+Since commit 0c17270f9b92 ("net: sysfs: Implement is_visible for
+phys_(port_id, port_name, switch_id)"), __dev_change_net_namespace() can
+hit WARN_ON() when trying to change owner of a file that isn't visible.
+See the trace below:
+
+ WARNING: CPU: 6 PID: 2938 at net/core/dev.c:12410 __dev_change_net_namespace+0xb89/0xc30
+ CPU: 6 UID: 0 PID: 2938 Comm: incusd Not tainted 6.17.1-1-mainline #1 PREEMPT(full) 4b783b4a638669fb644857f484487d17cb45ed1f
+ Hardware name: Framework Laptop 13 (AMD Ryzen 7040Series)/FRANMDCP07, BIOS 03.07 02/19/2025
+ RIP: 0010:__dev_change_net_namespace+0xb89/0xc30
+ [...]
+ Call Trace:
+ <TASK>
+ ? if6_seq_show+0x30/0x50
+ do_setlink.isra.0+0xc7/0x1270
+ ? __nla_validate_parse+0x5c/0xcc0
+ ? security_capable+0x94/0x1a0
+ rtnl_newlink+0x858/0xc20
+ ? update_curr+0x8e/0x1c0
+ ? update_entity_lag+0x71/0x80
+ ? sched_balance_newidle+0x358/0x450
+ ? psi_task_switch+0x113/0x2a0
+ ? __pfx_rtnl_newlink+0x10/0x10
+ rtnetlink_rcv_msg+0x346/0x3e0
+ ? sched_clock+0x10/0x30
+ ? __pfx_rtnetlink_rcv_msg+0x10/0x10
+ netlink_rcv_skb+0x59/0x110
+ netlink_unicast+0x285/0x3c0
+ ? __alloc_skb+0xdb/0x1a0
+ netlink_sendmsg+0x20d/0x430
+ ____sys_sendmsg+0x39f/0x3d0
+ ? import_iovec+0x2f/0x40
+ ___sys_sendmsg+0x99/0xe0
+ __sys_sendmsg+0x8a/0xf0
+ do_syscall_64+0x81/0x970
+ ? __sys_bind+0xe3/0x110
+ ? syscall_exit_work+0x143/0x1b0
+ ? do_syscall_64+0x244/0x970
+ ? sock_alloc_file+0x63/0xc0
+ ? syscall_exit_work+0x143/0x1b0
+ ? do_syscall_64+0x244/0x970
+ ? alloc_fd+0x12e/0x190
+ ? put_unused_fd+0x2a/0x70
+ ? do_sys_openat2+0xa2/0xe0
+ ? syscall_exit_work+0x143/0x1b0
+ ? do_syscall_64+0x244/0x970
+ ? exc_page_fault+0x7e/0x1a0
+ entry_SYSCALL_64_after_hwframe+0x76/0x7e
+ [...]
+ </TASK>
+
+Fix this by checking is_visible() before trying to touch the attribute.
+
+Fixes: 303a42769c4c ("sysfs: add sysfs_group{s}_change_owner()")
+Fixes: 0c17270f9b92 ("net: sysfs: Implement is_visible for phys_(port_id, port_name, switch_id)")
+Reported-by: Cynthia <cynthia@kosmx.dev>
+Closes: https://lore.kernel.org/netdev/01070199e22de7f8-28f711ab-d3f1-46d9-b9a0-048ab05eb09b-000000@eu-central-1.amazonses.com/
+Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
+Reviewed-by: Jakub Kicinski <kuba@kernel.org>
+Link: https://lore.kernel.org/r/20251016101456.4087-1-fmancera@suse.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/sysfs/group.c | 26 +++++++++++++++++++++-----
+ 1 file changed, 21 insertions(+), 5 deletions(-)
+
+diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c
+index 2d78e94072a0d..e142bac4f9f80 100644
+--- a/fs/sysfs/group.c
++++ b/fs/sysfs/group.c
+@@ -498,17 +498,26 @@ int compat_only_sysfs_link_entry_to_kobj(struct kobject *kobj,
+ }
+ EXPORT_SYMBOL_GPL(compat_only_sysfs_link_entry_to_kobj);
+
+-static int sysfs_group_attrs_change_owner(struct kernfs_node *grp_kn,
++static int sysfs_group_attrs_change_owner(struct kobject *kobj,
++ struct kernfs_node *grp_kn,
+ const struct attribute_group *grp,
+ struct iattr *newattrs)
+ {
+ struct kernfs_node *kn;
+- int error;
++ int error, i;
++ umode_t mode;
+
+ if (grp->attrs) {
+ struct attribute *const *attr;
+
+- for (attr = grp->attrs; *attr; attr++) {
++ for (i = 0, attr = grp->attrs; *attr; i++, attr++) {
++ if (grp->is_visible) {
++ mode = grp->is_visible(kobj, *attr, i);
++ if (mode & SYSFS_GROUP_INVISIBLE)
++ break;
++ if (!mode)
++ continue;
++ }
+ kn = kernfs_find_and_get(grp_kn, (*attr)->name);
+ if (!kn)
+ return -ENOENT;
+@@ -523,7 +532,14 @@ static int sysfs_group_attrs_change_owner(struct kernfs_node *grp_kn,
+ if (grp->bin_attrs) {
+ const struct bin_attribute *const *bin_attr;
+
+- for (bin_attr = grp->bin_attrs; *bin_attr; bin_attr++) {
++ for (i = 0, bin_attr = grp->bin_attrs; *bin_attr; i++, bin_attr++) {
++ if (grp->is_bin_visible) {
++ mode = grp->is_bin_visible(kobj, *bin_attr, i);
++ if (mode & SYSFS_GROUP_INVISIBLE)
++ break;
++ if (!mode)
++ continue;
++ }
+ kn = kernfs_find_and_get(grp_kn, (*bin_attr)->attr.name);
+ if (!kn)
+ return -ENOENT;
+@@ -573,7 +589,7 @@ int sysfs_group_change_owner(struct kobject *kobj,
+
+ error = kernfs_setattr(grp_kn, &newattrs);
+ if (!error)
+- error = sysfs_group_attrs_change_owner(grp_kn, grp, &newattrs);
++ error = sysfs_group_attrs_change_owner(kobj, grp_kn, grp, &newattrs);
+
+ kernfs_put(grp_kn);
+
+--
+2.51.0
+
--- /dev/null
+From 30c89140a4ddce8425bab82946256f5feea17e9e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Oct 2025 12:53:44 +0100
+Subject: firmware: arm_scmi: Account for failed debug initialization
+
+From: Cristian Marussi <cristian.marussi@arm.com>
+
+[ Upstream commit 2290ab43b9d8eafb8046387f10a8dfa2b030ba46 ]
+
+When the SCMI debug subsystem fails to initialize, the related debug root
+will be missing, and the underlying descriptor will be NULL.
+
+Handle this fault condition in the SCMI debug helpers that maintain
+metrics counters.
+
+Fixes: 0b3d48c4726e ("firmware: arm_scmi: Track basic SCMI communication debug metrics")
+Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
+Message-Id: <20251014115346.2391418-1-cristian.marussi@arm.com>
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_scmi/common.h | 24 ++++++++++++++--
+ drivers/firmware/arm_scmi/driver.c | 44 ++++++++++--------------------
+ 2 files changed, 35 insertions(+), 33 deletions(-)
+
+diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
+index 6c22348712154..dc95652fff400 100644
+--- a/drivers/firmware/arm_scmi/common.h
++++ b/drivers/firmware/arm_scmi/common.h
+@@ -321,10 +321,28 @@ enum debug_counters {
+ SCMI_DEBUG_COUNTERS_LAST
+ };
+
+-static inline void scmi_inc_count(atomic_t *arr, int stat)
++/**
++ * struct scmi_debug_info - Debug common info
++ * @top_dentry: A reference to the top debugfs dentry
++ * @name: Name of this SCMI instance
++ * @type: Type of this SCMI instance
++ * @is_atomic: Flag to state if the transport of this instance is atomic
++ * @counters: An array of atomic_c's used for tracking statistics (if enabled)
++ */
++struct scmi_debug_info {
++ struct dentry *top_dentry;
++ const char *name;
++ const char *type;
++ bool is_atomic;
++ atomic_t counters[SCMI_DEBUG_COUNTERS_LAST];
++};
++
++static inline void scmi_inc_count(struct scmi_debug_info *dbg, int stat)
+ {
+- if (IS_ENABLED(CONFIG_ARM_SCMI_DEBUG_COUNTERS))
+- atomic_inc(&arr[stat]);
++ if (IS_ENABLED(CONFIG_ARM_SCMI_DEBUG_COUNTERS)) {
++ if (dbg)
++ atomic_inc(&dbg->counters[stat]);
++ }
+ }
+
+ enum scmi_bad_msg {
+diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
+index d1fd2e492909e..9d4c983a27547 100644
+--- a/drivers/firmware/arm_scmi/driver.c
++++ b/drivers/firmware/arm_scmi/driver.c
+@@ -102,22 +102,6 @@ struct scmi_protocol_instance {
+
+ #define ph_to_pi(h) container_of(h, struct scmi_protocol_instance, ph)
+
+-/**
+- * struct scmi_debug_info - Debug common info
+- * @top_dentry: A reference to the top debugfs dentry
+- * @name: Name of this SCMI instance
+- * @type: Type of this SCMI instance
+- * @is_atomic: Flag to state if the transport of this instance is atomic
+- * @counters: An array of atomic_c's used for tracking statistics (if enabled)
+- */
+-struct scmi_debug_info {
+- struct dentry *top_dentry;
+- const char *name;
+- const char *type;
+- bool is_atomic;
+- atomic_t counters[SCMI_DEBUG_COUNTERS_LAST];
+-};
+-
+ /**
+ * struct scmi_info - Structure representing a SCMI instance
+ *
+@@ -856,7 +840,7 @@ scmi_xfer_command_acquire(struct scmi_chan_info *cinfo, u32 msg_hdr)
+ spin_unlock_irqrestore(&minfo->xfer_lock, flags);
+
+ scmi_bad_message_trace(cinfo, msg_hdr, MSG_UNEXPECTED);
+- scmi_inc_count(info->dbg->counters, ERR_MSG_UNEXPECTED);
++ scmi_inc_count(info->dbg, ERR_MSG_UNEXPECTED);
+
+ return xfer;
+ }
+@@ -884,7 +868,7 @@ scmi_xfer_command_acquire(struct scmi_chan_info *cinfo, u32 msg_hdr)
+ msg_type, xfer_id, msg_hdr, xfer->state);
+
+ scmi_bad_message_trace(cinfo, msg_hdr, MSG_INVALID);
+- scmi_inc_count(info->dbg->counters, ERR_MSG_INVALID);
++ scmi_inc_count(info->dbg, ERR_MSG_INVALID);
+
+
+ /* On error the refcount incremented above has to be dropped */
+@@ -930,7 +914,7 @@ static void scmi_handle_notification(struct scmi_chan_info *cinfo,
+ PTR_ERR(xfer));
+
+ scmi_bad_message_trace(cinfo, msg_hdr, MSG_NOMEM);
+- scmi_inc_count(info->dbg->counters, ERR_MSG_NOMEM);
++ scmi_inc_count(info->dbg, ERR_MSG_NOMEM);
+
+ scmi_clear_channel(info, cinfo);
+ return;
+@@ -946,7 +930,7 @@ static void scmi_handle_notification(struct scmi_chan_info *cinfo,
+ trace_scmi_msg_dump(info->id, cinfo->id, xfer->hdr.protocol_id,
+ xfer->hdr.id, "NOTI", xfer->hdr.seq,
+ xfer->hdr.status, xfer->rx.buf, xfer->rx.len);
+- scmi_inc_count(info->dbg->counters, NOTIFICATION_OK);
++ scmi_inc_count(info->dbg, NOTIFICATION_OK);
+
+ scmi_notify(cinfo->handle, xfer->hdr.protocol_id,
+ xfer->hdr.id, xfer->rx.buf, xfer->rx.len, ts);
+@@ -1006,10 +990,10 @@ static void scmi_handle_response(struct scmi_chan_info *cinfo,
+ if (xfer->hdr.type == MSG_TYPE_DELAYED_RESP) {
+ scmi_clear_channel(info, cinfo);
+ complete(xfer->async_done);
+- scmi_inc_count(info->dbg->counters, DELAYED_RESPONSE_OK);
++ scmi_inc_count(info->dbg, DELAYED_RESPONSE_OK);
+ } else {
+ complete(&xfer->done);
+- scmi_inc_count(info->dbg->counters, RESPONSE_OK);
++ scmi_inc_count(info->dbg, RESPONSE_OK);
+ }
+
+ if (IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT)) {
+@@ -1117,7 +1101,7 @@ static int scmi_wait_for_reply(struct device *dev, const struct scmi_desc *desc,
+ "timed out in resp(caller: %pS) - polling\n",
+ (void *)_RET_IP_);
+ ret = -ETIMEDOUT;
+- scmi_inc_count(info->dbg->counters, XFERS_RESPONSE_POLLED_TIMEOUT);
++ scmi_inc_count(info->dbg, XFERS_RESPONSE_POLLED_TIMEOUT);
+ }
+ }
+
+@@ -1142,7 +1126,7 @@ static int scmi_wait_for_reply(struct device *dev, const struct scmi_desc *desc,
+ "RESP" : "resp",
+ xfer->hdr.seq, xfer->hdr.status,
+ xfer->rx.buf, xfer->rx.len);
+- scmi_inc_count(info->dbg->counters, RESPONSE_POLLED_OK);
++ scmi_inc_count(info->dbg, RESPONSE_POLLED_OK);
+
+ if (IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT)) {
+ struct scmi_info *info =
+@@ -1160,7 +1144,7 @@ static int scmi_wait_for_reply(struct device *dev, const struct scmi_desc *desc,
+ dev_err(dev, "timed out in resp(caller: %pS)\n",
+ (void *)_RET_IP_);
+ ret = -ETIMEDOUT;
+- scmi_inc_count(info->dbg->counters, XFERS_RESPONSE_TIMEOUT);
++ scmi_inc_count(info->dbg, XFERS_RESPONSE_TIMEOUT);
+ }
+ }
+
+@@ -1244,13 +1228,13 @@ static int do_xfer(const struct scmi_protocol_handle *ph,
+ !is_transport_polling_capable(info->desc)) {
+ dev_warn_once(dev,
+ "Polling mode is not supported by transport.\n");
+- scmi_inc_count(info->dbg->counters, SENT_FAIL_POLLING_UNSUPPORTED);
++ scmi_inc_count(info->dbg, SENT_FAIL_POLLING_UNSUPPORTED);
+ return -EINVAL;
+ }
+
+ cinfo = idr_find(&info->tx_idr, pi->proto->id);
+ if (unlikely(!cinfo)) {
+- scmi_inc_count(info->dbg->counters, SENT_FAIL_CHANNEL_NOT_FOUND);
++ scmi_inc_count(info->dbg, SENT_FAIL_CHANNEL_NOT_FOUND);
+ return -EINVAL;
+ }
+ /* True ONLY if also supported by transport. */
+@@ -1284,19 +1268,19 @@ static int do_xfer(const struct scmi_protocol_handle *ph,
+ ret = info->desc->ops->send_message(cinfo, xfer);
+ if (ret < 0) {
+ dev_dbg(dev, "Failed to send message %d\n", ret);
+- scmi_inc_count(info->dbg->counters, SENT_FAIL);
++ scmi_inc_count(info->dbg, SENT_FAIL);
+ return ret;
+ }
+
+ trace_scmi_msg_dump(info->id, cinfo->id, xfer->hdr.protocol_id,
+ xfer->hdr.id, "CMND", xfer->hdr.seq,
+ xfer->hdr.status, xfer->tx.buf, xfer->tx.len);
+- scmi_inc_count(info->dbg->counters, SENT_OK);
++ scmi_inc_count(info->dbg, SENT_OK);
+
+ ret = scmi_wait_for_message_response(cinfo, xfer);
+ if (!ret && xfer->hdr.status) {
+ ret = scmi_to_linux_errno(xfer->hdr.status);
+- scmi_inc_count(info->dbg->counters, ERR_PROTOCOL);
++ scmi_inc_count(info->dbg, ERR_PROTOCOL);
+ }
+
+ if (info->desc->ops->mark_txdone)
+--
+2.51.0
+
--- /dev/null
+From c097920d87933213e3449868e8d5215eea749346 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Oct 2025 12:10:57 +0300
+Subject: firmware: arm_scmi: Fix premature SCMI_XFER_FLAG_IS_RAW clearing in
+ raw mode
+
+From: Artem Shimko <a.shimko.dev@gmail.com>
+
+[ Upstream commit 20b93a0088a595bceed4a026d527cbbac4e876c5 ]
+
+The SCMI_XFER_FLAG_IS_RAW flag was being cleared prematurely in
+scmi_xfer_raw_put() before the transfer completion was properly
+acknowledged by the raw message handlers.
+
+Move the clearing of SCMI_XFER_FLAG_IS_RAW and SCMI_XFER_FLAG_CHAN_SET
+from scmi_xfer_raw_put() to __scmi_xfer_put() to ensure the flags remain
+set throughout the entire raw message processing pipeline until the
+transfer is returned to the free pool.
+
+Fixes: 3095a3e25d8f ("firmware: arm_scmi: Add xfer helpers to provide raw access")
+Suggested-by: Cristian Marussi <cristian.marussi@arm.com>
+Signed-off-by: Artem Shimko <a.shimko.dev@gmail.com>
+Reviewed-by: Cristian Marussi <cristian.marussi@arm.com>
+Message-Id: <20251008091057.1969260-1-a.shimko.dev@gmail.com>
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_scmi/driver.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
+index 9d4c983a27547..fbe893734411c 100644
+--- a/drivers/firmware/arm_scmi/driver.c
++++ b/drivers/firmware/arm_scmi/driver.c
+@@ -627,6 +627,7 @@ __scmi_xfer_put(struct scmi_xfers_info *minfo, struct scmi_xfer *xfer)
+ hash_del(&xfer->node);
+ xfer->pending = false;
+ }
++ xfer->flags = 0;
+ hlist_add_head(&xfer->node, &minfo->free_xfers);
+ }
+ spin_unlock_irqrestore(&minfo->xfer_lock, flags);
+@@ -645,8 +646,6 @@ void scmi_xfer_raw_put(const struct scmi_handle *handle, struct scmi_xfer *xfer)
+ {
+ struct scmi_info *info = handle_to_scmi_info(handle);
+
+- xfer->flags &= ~SCMI_XFER_FLAG_IS_RAW;
+- xfer->flags &= ~SCMI_XFER_FLAG_CHAN_SET;
+ return __scmi_xfer_put(&info->tx_minfo, xfer);
+ }
+
+--
+2.51.0
+
--- /dev/null
+From 6e8798cc9a84c115dcccf1fc0ddc9994699916c7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Oct 2025 15:02:30 +0800
+Subject: gpio: ljca: Fix duplicated IRQ mapping
+
+From: Haotian Zhang <vulab@iscas.ac.cn>
+
+[ Upstream commit 4c4e6ea4a120cc5ab58e437c6ba123cbfc357d45 ]
+
+The generic_handle_domain_irq() function resolves the hardware IRQ
+internally. The driver performed a duplicative mapping by calling
+irq_find_mapping() first, which could lead to an RCU stall.
+
+Delete the redundant irq_find_mapping() call and pass the hardware IRQ
+directly to generic_handle_domain_irq().
+
+Fixes: c5a4b6fd31e8 ("gpio: Add support for Intel LJCA USB GPIO driver")
+Signed-off-by: Haotian Zhang <vulab@iscas.ac.cn>
+Link: https://lore.kernel.org/r/20251023070231.1305-1-vulab@iscas.ac.cn
+[Bartosz: remove unused variable]
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-ljca.c | 14 +++-----------
+ 1 file changed, 3 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/gpio/gpio-ljca.c b/drivers/gpio/gpio-ljca.c
+index dfec9fbfc7a9b..ddd73b8b790e7 100644
+--- a/drivers/gpio/gpio-ljca.c
++++ b/drivers/gpio/gpio-ljca.c
+@@ -281,22 +281,14 @@ static void ljca_gpio_event_cb(void *context, u8 cmd, const void *evt_data,
+ {
+ const struct ljca_gpio_packet *packet = evt_data;
+ struct ljca_gpio_dev *ljca_gpio = context;
+- int i, irq;
++ int i;
+
+ if (cmd != LJCA_GPIO_INT_EVENT)
+ return;
+
+ for (i = 0; i < packet->num; i++) {
+- irq = irq_find_mapping(ljca_gpio->gc.irq.domain,
+- packet->item[i].index);
+- if (!irq) {
+- dev_err(ljca_gpio->gc.parent,
+- "gpio_id %u does not mapped to IRQ yet\n",
+- packet->item[i].index);
+- return;
+- }
+-
+- generic_handle_domain_irq(ljca_gpio->gc.irq.domain, irq);
++ generic_handle_domain_irq(ljca_gpio->gc.irq.domain,
++ packet->item[i].index);
+ set_bit(packet->item[i].index, ljca_gpio->reenable_irqs);
+ }
+
+--
+2.51.0
+
--- /dev/null
+From 2420f273b4a8a094d39c632d8a988ecd17989941 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Oct 2023 14:33:25 +0800
+Subject: gpio: update Intel LJCA USB GPIO driver
+
+From: Wentong Wu <wentong.wu@intel.com>
+
+[ Upstream commit 1034cc423f1b4a7a9a56d310ca980fcd2753e11d ]
+
+This driver communicate with LJCA GPIO module with specific
+protocol through interfaces exported by LJCA USB driver.
+Update the driver according to LJCA USB driver's changes.
+
+Signed-off-by: Wentong Wu <wentong.wu@intel.com>
+Reviewed-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Acked-by: Linus Walleij <linus.walleij@linaro.org>
+Acked-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Tested-by: Hans de Goede <hdegoede@redhat.com>
+Link: https://lore.kernel.org/r/1696833205-16716-5-git-send-email-wentong.wu@intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 4c4e6ea4a120 ("gpio: ljca: Fix duplicated IRQ mapping")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/Kconfig | 4 +-
+ drivers/gpio/gpio-ljca.c | 246 +++++++++++++++++++++++----------------
+ 2 files changed, 145 insertions(+), 105 deletions(-)
+
+diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
+index ebd4e113dc265..de051a085e63f 100644
+--- a/drivers/gpio/Kconfig
++++ b/drivers/gpio/Kconfig
+@@ -1313,9 +1313,9 @@ config GPIO_KEMPLD
+
+ config GPIO_LJCA
+ tristate "INTEL La Jolla Cove Adapter GPIO support"
+- depends on MFD_LJCA
++ depends on USB_LJCA
+ select GPIOLIB_IRQCHIP
+- default MFD_LJCA
++ default USB_LJCA
+ help
+ Select this option to enable GPIO driver for the INTEL
+ La Jolla Cove Adapter (LJCA) board.
+diff --git a/drivers/gpio/gpio-ljca.c b/drivers/gpio/gpio-ljca.c
+index 87863f0230f5c..dfec9fbfc7a9b 100644
+--- a/drivers/gpio/gpio-ljca.c
++++ b/drivers/gpio/gpio-ljca.c
+@@ -6,6 +6,7 @@
+ */
+
+ #include <linux/acpi.h>
++#include <linux/auxiliary_bus.h>
+ #include <linux/bitfield.h>
+ #include <linux/bitops.h>
+ #include <linux/dev_printk.h>
+@@ -13,19 +14,18 @@
+ #include <linux/irq.h>
+ #include <linux/kernel.h>
+ #include <linux/kref.h>
+-#include <linux/mfd/ljca.h>
+ #include <linux/module.h>
+-#include <linux/platform_device.h>
+ #include <linux/slab.h>
+ #include <linux/types.h>
++#include <linux/usb/ljca.h>
+
+ /* GPIO commands */
+-#define LJCA_GPIO_CONFIG 1
+-#define LJCA_GPIO_READ 2
+-#define LJCA_GPIO_WRITE 3
+-#define LJCA_GPIO_INT_EVENT 4
+-#define LJCA_GPIO_INT_MASK 5
+-#define LJCA_GPIO_INT_UNMASK 6
++#define LJCA_GPIO_CONFIG 1
++#define LJCA_GPIO_READ 2
++#define LJCA_GPIO_WRITE 3
++#define LJCA_GPIO_INT_EVENT 4
++#define LJCA_GPIO_INT_MASK 5
++#define LJCA_GPIO_INT_UNMASK 6
+
+ #define LJCA_GPIO_CONF_DISABLE BIT(0)
+ #define LJCA_GPIO_CONF_INPUT BIT(1)
+@@ -36,45 +36,49 @@
+ #define LJCA_GPIO_CONF_INTERRUPT BIT(6)
+ #define LJCA_GPIO_INT_TYPE BIT(7)
+
+-#define LJCA_GPIO_CONF_EDGE FIELD_PREP(LJCA_GPIO_INT_TYPE, 1)
+-#define LJCA_GPIO_CONF_LEVEL FIELD_PREP(LJCA_GPIO_INT_TYPE, 0)
++#define LJCA_GPIO_CONF_EDGE FIELD_PREP(LJCA_GPIO_INT_TYPE, 1)
++#define LJCA_GPIO_CONF_LEVEL FIELD_PREP(LJCA_GPIO_INT_TYPE, 0)
+
+ /* Intentional overlap with PULLUP / PULLDOWN */
+-#define LJCA_GPIO_CONF_SET BIT(3)
+-#define LJCA_GPIO_CONF_CLR BIT(4)
++#define LJCA_GPIO_CONF_SET BIT(3)
++#define LJCA_GPIO_CONF_CLR BIT(4)
+
+-struct gpio_op {
++#define LJCA_GPIO_BUF_SIZE 60u
++
++struct ljca_gpio_op {
+ u8 index;
+ u8 value;
+ } __packed;
+
+-struct gpio_packet {
++struct ljca_gpio_packet {
+ u8 num;
+- struct gpio_op item[];
++ struct ljca_gpio_op item[] __counted_by(num);
+ } __packed;
+
+-#define LJCA_GPIO_BUF_SIZE 60
+ struct ljca_gpio_dev {
+- struct platform_device *pdev;
++ struct ljca_client *ljca;
+ struct gpio_chip gc;
+ struct ljca_gpio_info *gpio_info;
+ DECLARE_BITMAP(unmasked_irqs, LJCA_MAX_GPIO_NUM);
+ DECLARE_BITMAP(enabled_irqs, LJCA_MAX_GPIO_NUM);
+ DECLARE_BITMAP(reenable_irqs, LJCA_MAX_GPIO_NUM);
++ DECLARE_BITMAP(output_enabled, LJCA_MAX_GPIO_NUM);
+ u8 *connect_mode;
+- /* mutex to protect irq bus */
++ /* protect irq bus */
+ struct mutex irq_lock;
+ struct work_struct work;
+- /* lock to protect package transfer to Hardware */
++ /* protect package transfer to hardware */
+ struct mutex trans_lock;
+
+ u8 obuf[LJCA_GPIO_BUF_SIZE];
+ u8 ibuf[LJCA_GPIO_BUF_SIZE];
+ };
+
+-static int gpio_config(struct ljca_gpio_dev *ljca_gpio, u8 gpio_id, u8 config)
++static int ljca_gpio_config(struct ljca_gpio_dev *ljca_gpio, u8 gpio_id,
++ u8 config)
+ {
+- struct gpio_packet *packet = (struct gpio_packet *)ljca_gpio->obuf;
++ struct ljca_gpio_packet *packet =
++ (struct ljca_gpio_packet *)ljca_gpio->obuf;
+ int ret;
+
+ mutex_lock(&ljca_gpio->trans_lock);
+@@ -82,43 +86,43 @@ static int gpio_config(struct ljca_gpio_dev *ljca_gpio, u8 gpio_id, u8 config)
+ packet->item[0].value = config | ljca_gpio->connect_mode[gpio_id];
+ packet->num = 1;
+
+- ret = ljca_transfer(ljca_gpio->gpio_info->ljca, LJCA_GPIO_CONFIG, packet,
+- struct_size(packet, item, packet->num), NULL, NULL);
++ ret = ljca_transfer(ljca_gpio->ljca, LJCA_GPIO_CONFIG, (u8 *)packet,
++ struct_size(packet, item, packet->num), NULL, 0);
+ mutex_unlock(&ljca_gpio->trans_lock);
+- return ret;
++
++ return ret < 0 ? ret : 0;
+ }
+
+ static int ljca_gpio_read(struct ljca_gpio_dev *ljca_gpio, u8 gpio_id)
+ {
+- struct gpio_packet *packet = (struct gpio_packet *)ljca_gpio->obuf;
+- struct gpio_packet *ack_packet = (struct gpio_packet *)ljca_gpio->ibuf;
+- unsigned int ibuf_len = LJCA_GPIO_BUF_SIZE;
++ struct ljca_gpio_packet *ack_packet =
++ (struct ljca_gpio_packet *)ljca_gpio->ibuf;
++ struct ljca_gpio_packet *packet =
++ (struct ljca_gpio_packet *)ljca_gpio->obuf;
+ int ret;
+
+ mutex_lock(&ljca_gpio->trans_lock);
+ packet->num = 1;
+ packet->item[0].index = gpio_id;
+- ret = ljca_transfer(ljca_gpio->gpio_info->ljca, LJCA_GPIO_READ, packet,
+- struct_size(packet, item, packet->num), ljca_gpio->ibuf, &ibuf_len);
+- if (ret)
+- goto out_unlock;
+-
+- if (!ibuf_len || ack_packet->num != packet->num) {
+- dev_err(&ljca_gpio->pdev->dev, "failed gpio_id:%u %u", gpio_id, ack_packet->num);
+- ret = -EIO;
++ ret = ljca_transfer(ljca_gpio->ljca, LJCA_GPIO_READ, (u8 *)packet,
++ struct_size(packet, item, packet->num),
++ ljca_gpio->ibuf, LJCA_GPIO_BUF_SIZE);
++
++ if (ret <= 0 || ack_packet->num != packet->num) {
++ dev_err(&ljca_gpio->ljca->auxdev.dev,
++ "read package error, gpio_id: %u num: %u ret: %d\n",
++ gpio_id, ack_packet->num, ret);
++ ret = ret < 0 ? ret : -EIO;
+ }
+-
+-out_unlock:
+ mutex_unlock(&ljca_gpio->trans_lock);
+- if (ret)
+- return ret;
+- return ack_packet->item[0].value > 0;
++
++ return ret < 0 ? ret : ack_packet->item[0].value > 0;
+ }
+
+-static int ljca_gpio_write(struct ljca_gpio_dev *ljca_gpio, u8 gpio_id,
+- int value)
++static int ljca_gpio_write(struct ljca_gpio_dev *ljca_gpio, u8 gpio_id, int value)
+ {
+- struct gpio_packet *packet = (struct gpio_packet *)ljca_gpio->obuf;
++ struct ljca_gpio_packet *packet =
++ (struct ljca_gpio_packet *)ljca_gpio->obuf;
+ int ret;
+
+ mutex_lock(&ljca_gpio->trans_lock);
+@@ -126,10 +130,11 @@ static int ljca_gpio_write(struct ljca_gpio_dev *ljca_gpio, u8 gpio_id,
+ packet->item[0].index = gpio_id;
+ packet->item[0].value = value & 1;
+
+- ret = ljca_transfer(ljca_gpio->gpio_info->ljca, LJCA_GPIO_WRITE, packet,
+- struct_size(packet, item, packet->num), NULL, NULL);
++ ret = ljca_transfer(ljca_gpio->ljca, LJCA_GPIO_WRITE, (u8 *)packet,
++ struct_size(packet, item, packet->num), NULL, 0);
+ mutex_unlock(&ljca_gpio->trans_lock);
+- return ret;
++
++ return ret < 0 ? ret : 0;
+ }
+
+ static int ljca_gpio_get_value(struct gpio_chip *chip, unsigned int offset)
+@@ -147,16 +152,24 @@ static void ljca_gpio_set_value(struct gpio_chip *chip, unsigned int offset,
+
+ ret = ljca_gpio_write(ljca_gpio, offset, val);
+ if (ret)
+- dev_err(chip->parent, "offset:%u val:%d set value failed %d\n", offset, val, ret);
++ dev_err(chip->parent,
++ "set value failed offset: %u val: %d ret: %d\n",
++ offset, val, ret);
+ }
+
+-static int ljca_gpio_direction_input(struct gpio_chip *chip,
+- unsigned int offset)
++static int ljca_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
+ {
+ struct ljca_gpio_dev *ljca_gpio = gpiochip_get_data(chip);
+ u8 config = LJCA_GPIO_CONF_INPUT | LJCA_GPIO_CONF_CLR;
++ int ret;
+
+- return gpio_config(ljca_gpio, offset, config);
++ ret = ljca_gpio_config(ljca_gpio, offset, config);
++ if (ret)
++ return ret;
++
++ clear_bit(offset, ljca_gpio->output_enabled);
++
++ return 0;
+ }
+
+ static int ljca_gpio_direction_output(struct gpio_chip *chip,
+@@ -166,14 +179,26 @@ static int ljca_gpio_direction_output(struct gpio_chip *chip,
+ u8 config = LJCA_GPIO_CONF_OUTPUT | LJCA_GPIO_CONF_CLR;
+ int ret;
+
+- ret = gpio_config(ljca_gpio, offset, config);
++ ret = ljca_gpio_config(ljca_gpio, offset, config);
+ if (ret)
+ return ret;
+
+ ljca_gpio_set_value(chip, offset, val);
++ set_bit(offset, ljca_gpio->output_enabled);
++
+ return 0;
+ }
+
++static int ljca_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
++{
++ struct ljca_gpio_dev *ljca_gpio = gpiochip_get_data(chip);
++
++ if (test_bit(offset, ljca_gpio->output_enabled))
++ return GPIO_LINE_DIRECTION_OUT;
++
++ return GPIO_LINE_DIRECTION_IN;
++}
++
+ static int ljca_gpio_set_config(struct gpio_chip *chip, unsigned int offset,
+ unsigned long config)
+ {
+@@ -197,7 +222,8 @@ static int ljca_gpio_set_config(struct gpio_chip *chip, unsigned int offset,
+ return 0;
+ }
+
+-static int ljca_gpio_init_valid_mask(struct gpio_chip *chip, unsigned long *valid_mask,
++static int ljca_gpio_init_valid_mask(struct gpio_chip *chip,
++ unsigned long *valid_mask,
+ unsigned int ngpios)
+ {
+ struct ljca_gpio_dev *ljca_gpio = gpiochip_get_data(chip);
+@@ -208,15 +234,18 @@ static int ljca_gpio_init_valid_mask(struct gpio_chip *chip, unsigned long *vali
+ return 0;
+ }
+
+-static void ljca_gpio_irq_init_valid_mask(struct gpio_chip *chip, unsigned long *valid_mask,
++static void ljca_gpio_irq_init_valid_mask(struct gpio_chip *chip,
++ unsigned long *valid_mask,
+ unsigned int ngpios)
+ {
+ ljca_gpio_init_valid_mask(chip, valid_mask, ngpios);
+ }
+
+-static int ljca_enable_irq(struct ljca_gpio_dev *ljca_gpio, int gpio_id, bool enable)
++static int ljca_enable_irq(struct ljca_gpio_dev *ljca_gpio, int gpio_id,
++ bool enable)
+ {
+- struct gpio_packet *packet = (struct gpio_packet *)ljca_gpio->obuf;
++ struct ljca_gpio_packet *packet =
++ (struct ljca_gpio_packet *)ljca_gpio->obuf;
+ int ret;
+
+ mutex_lock(&ljca_gpio->trans_lock);
+@@ -224,18 +253,20 @@ static int ljca_enable_irq(struct ljca_gpio_dev *ljca_gpio, int gpio_id, bool en
+ packet->item[0].index = gpio_id;
+ packet->item[0].value = 0;
+
+- ret = ljca_transfer(ljca_gpio->gpio_info->ljca,
+- enable ? LJCA_GPIO_INT_UNMASK : LJCA_GPIO_INT_MASK, packet,
+- struct_size(packet, item, packet->num), NULL, NULL);
++ ret = ljca_transfer(ljca_gpio->ljca,
++ enable ? LJCA_GPIO_INT_UNMASK : LJCA_GPIO_INT_MASK,
++ (u8 *)packet, struct_size(packet, item, packet->num),
++ NULL, 0);
+ mutex_unlock(&ljca_gpio->trans_lock);
+- return ret;
++
++ return ret < 0 ? ret : 0;
+ }
+
+ static void ljca_gpio_async(struct work_struct *work)
+ {
+- struct ljca_gpio_dev *ljca_gpio = container_of(work, struct ljca_gpio_dev, work);
+- int gpio_id;
+- int unmasked;
++ struct ljca_gpio_dev *ljca_gpio =
++ container_of(work, struct ljca_gpio_dev, work);
++ int gpio_id, unmasked;
+
+ for_each_set_bit(gpio_id, ljca_gpio->reenable_irqs, ljca_gpio->gc.ngpio) {
+ clear_bit(gpio_id, ljca_gpio->reenable_irqs);
+@@ -245,20 +276,22 @@ static void ljca_gpio_async(struct work_struct *work)
+ }
+ }
+
+-static void ljca_gpio_event_cb(void *context, u8 cmd, const void *evt_data, int len)
++static void ljca_gpio_event_cb(void *context, u8 cmd, const void *evt_data,
++ int len)
+ {
+- const struct gpio_packet *packet = evt_data;
++ const struct ljca_gpio_packet *packet = evt_data;
+ struct ljca_gpio_dev *ljca_gpio = context;
+- int i;
+- int irq;
++ int i, irq;
+
+ if (cmd != LJCA_GPIO_INT_EVENT)
+ return;
+
+ for (i = 0; i < packet->num; i++) {
+- irq = irq_find_mapping(ljca_gpio->gc.irq.domain, packet->item[i].index);
++ irq = irq_find_mapping(ljca_gpio->gc.irq.domain,
++ packet->item[i].index);
+ if (!irq) {
+- dev_err(ljca_gpio->gc.parent, "gpio_id %u does not mapped to IRQ yet\n",
++ dev_err(ljca_gpio->gc.parent,
++ "gpio_id %u does not mapped to IRQ yet\n",
+ packet->item[i].index);
+ return;
+ }
+@@ -299,18 +332,22 @@ static int ljca_irq_set_type(struct irq_data *irqd, unsigned int type)
+ ljca_gpio->connect_mode[gpio_id] = LJCA_GPIO_CONF_INTERRUPT;
+ switch (type) {
+ case IRQ_TYPE_LEVEL_HIGH:
+- ljca_gpio->connect_mode[gpio_id] |= (LJCA_GPIO_CONF_LEVEL | LJCA_GPIO_CONF_PULLUP);
++ ljca_gpio->connect_mode[gpio_id] |=
++ (LJCA_GPIO_CONF_LEVEL | LJCA_GPIO_CONF_PULLUP);
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+- ljca_gpio->connect_mode[gpio_id] |= (LJCA_GPIO_CONF_LEVEL | LJCA_GPIO_CONF_PULLDOWN);
++ ljca_gpio->connect_mode[gpio_id] |=
++ (LJCA_GPIO_CONF_LEVEL | LJCA_GPIO_CONF_PULLDOWN);
+ break;
+ case IRQ_TYPE_EDGE_BOTH:
+ break;
+ case IRQ_TYPE_EDGE_RISING:
+- ljca_gpio->connect_mode[gpio_id] |= (LJCA_GPIO_CONF_EDGE | LJCA_GPIO_CONF_PULLUP);
++ ljca_gpio->connect_mode[gpio_id] |=
++ (LJCA_GPIO_CONF_EDGE | LJCA_GPIO_CONF_PULLUP);
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+- ljca_gpio->connect_mode[gpio_id] |= (LJCA_GPIO_CONF_EDGE | LJCA_GPIO_CONF_PULLDOWN);
++ ljca_gpio->connect_mode[gpio_id] |=
++ (LJCA_GPIO_CONF_EDGE | LJCA_GPIO_CONF_PULLDOWN);
+ break;
+ default:
+ return -EINVAL;
+@@ -332,15 +369,14 @@ static void ljca_irq_bus_unlock(struct irq_data *irqd)
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
+ struct ljca_gpio_dev *ljca_gpio = gpiochip_get_data(gc);
+ int gpio_id = irqd_to_hwirq(irqd);
+- int enabled;
+- int unmasked;
++ int enabled, unmasked;
+
+ enabled = test_bit(gpio_id, ljca_gpio->enabled_irqs);
+ unmasked = test_bit(gpio_id, ljca_gpio->unmasked_irqs);
+
+ if (enabled != unmasked) {
+ if (unmasked) {
+- gpio_config(ljca_gpio, gpio_id, 0);
++ ljca_gpio_config(ljca_gpio, gpio_id, 0);
+ ljca_enable_irq(ljca_gpio, gpio_id, true);
+ set_bit(gpio_id, ljca_gpio->enabled_irqs);
+ } else {
+@@ -363,43 +399,48 @@ static const struct irq_chip ljca_gpio_irqchip = {
+ GPIOCHIP_IRQ_RESOURCE_HELPERS,
+ };
+
+-static int ljca_gpio_probe(struct platform_device *pdev)
++static int ljca_gpio_probe(struct auxiliary_device *auxdev,
++ const struct auxiliary_device_id *aux_dev_id)
+ {
++ struct ljca_client *ljca = auxiliary_dev_to_ljca_client(auxdev);
+ struct ljca_gpio_dev *ljca_gpio;
+ struct gpio_irq_chip *girq;
+ int ret;
+
+- ljca_gpio = devm_kzalloc(&pdev->dev, sizeof(*ljca_gpio), GFP_KERNEL);
++ ljca_gpio = devm_kzalloc(&auxdev->dev, sizeof(*ljca_gpio), GFP_KERNEL);
+ if (!ljca_gpio)
+ return -ENOMEM;
+
+- ljca_gpio->gpio_info = dev_get_platdata(&pdev->dev);
+- ljca_gpio->connect_mode = devm_kcalloc(&pdev->dev, ljca_gpio->gpio_info->num,
+- sizeof(*ljca_gpio->connect_mode), GFP_KERNEL);
++ ljca_gpio->ljca = ljca;
++ ljca_gpio->gpio_info = dev_get_platdata(&auxdev->dev);
++ ljca_gpio->connect_mode = devm_kcalloc(&auxdev->dev,
++ ljca_gpio->gpio_info->num,
++ sizeof(*ljca_gpio->connect_mode),
++ GFP_KERNEL);
+ if (!ljca_gpio->connect_mode)
+ return -ENOMEM;
+
+ mutex_init(&ljca_gpio->irq_lock);
+ mutex_init(&ljca_gpio->trans_lock);
+- ljca_gpio->pdev = pdev;
+ ljca_gpio->gc.direction_input = ljca_gpio_direction_input;
+ ljca_gpio->gc.direction_output = ljca_gpio_direction_output;
++ ljca_gpio->gc.get_direction = ljca_gpio_get_direction;
+ ljca_gpio->gc.get = ljca_gpio_get_value;
+ ljca_gpio->gc.set = ljca_gpio_set_value;
+ ljca_gpio->gc.set_config = ljca_gpio_set_config;
+ ljca_gpio->gc.init_valid_mask = ljca_gpio_init_valid_mask;
+ ljca_gpio->gc.can_sleep = true;
+- ljca_gpio->gc.parent = &pdev->dev;
++ ljca_gpio->gc.parent = &auxdev->dev;
+
+ ljca_gpio->gc.base = -1;
+ ljca_gpio->gc.ngpio = ljca_gpio->gpio_info->num;
+- ljca_gpio->gc.label = ACPI_COMPANION(&pdev->dev) ?
+- acpi_dev_name(ACPI_COMPANION(&pdev->dev)) :
+- dev_name(&pdev->dev);
++ ljca_gpio->gc.label = ACPI_COMPANION(&auxdev->dev) ?
++ acpi_dev_name(ACPI_COMPANION(&auxdev->dev)) :
++ dev_name(&auxdev->dev);
+ ljca_gpio->gc.owner = THIS_MODULE;
+
+- platform_set_drvdata(pdev, ljca_gpio);
+- ljca_register_event_cb(ljca_gpio->gpio_info->ljca, ljca_gpio_event_cb, ljca_gpio);
++ auxiliary_set_drvdata(auxdev, ljca_gpio);
++ ljca_register_event_cb(ljca, ljca_gpio_event_cb, ljca_gpio);
+
+ girq = &ljca_gpio->gc.irq;
+ gpio_irq_chip_set_chip(girq, &ljca_gpio_irqchip);
+@@ -413,7 +454,7 @@ static int ljca_gpio_probe(struct platform_device *pdev)
+ INIT_WORK(&ljca_gpio->work, ljca_gpio_async);
+ ret = gpiochip_add_data(&ljca_gpio->gc, ljca_gpio);
+ if (ret) {
+- ljca_unregister_event_cb(ljca_gpio->gpio_info->ljca);
++ ljca_unregister_event_cb(ljca);
+ mutex_destroy(&ljca_gpio->irq_lock);
+ mutex_destroy(&ljca_gpio->trans_lock);
+ }
+@@ -421,34 +462,33 @@ static int ljca_gpio_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+-static int ljca_gpio_remove(struct platform_device *pdev)
++static void ljca_gpio_remove(struct auxiliary_device *auxdev)
+ {
+- struct ljca_gpio_dev *ljca_gpio = platform_get_drvdata(pdev);
++ struct ljca_gpio_dev *ljca_gpio = auxiliary_get_drvdata(auxdev);
+
+ gpiochip_remove(&ljca_gpio->gc);
+- ljca_unregister_event_cb(ljca_gpio->gpio_info->ljca);
++ ljca_unregister_event_cb(ljca_gpio->ljca);
++ cancel_work_sync(&ljca_gpio->work);
+ mutex_destroy(&ljca_gpio->irq_lock);
+ mutex_destroy(&ljca_gpio->trans_lock);
+- return 0;
+ }
+
+-#define LJCA_GPIO_DRV_NAME "ljca-gpio"
+-static const struct platform_device_id ljca_gpio_id[] = {
+- { LJCA_GPIO_DRV_NAME, 0 },
+- { /* sentinel */ }
++static const struct auxiliary_device_id ljca_gpio_id_table[] = {
++ { "usb_ljca.ljca-gpio", 0 },
++ { /* sentinel */ },
+ };
+-MODULE_DEVICE_TABLE(platform, ljca_gpio_id);
++MODULE_DEVICE_TABLE(auxiliary, ljca_gpio_id_table);
+
+-static struct platform_driver ljca_gpio_driver = {
+- .driver.name = LJCA_GPIO_DRV_NAME,
++static struct auxiliary_driver ljca_gpio_driver = {
+ .probe = ljca_gpio_probe,
+ .remove = ljca_gpio_remove,
++ .id_table = ljca_gpio_id_table,
+ };
+-module_platform_driver(ljca_gpio_driver);
++module_auxiliary_driver(ljca_gpio_driver);
+
+-MODULE_AUTHOR("Ye Xiang <xiang.ye@intel.com>");
+-MODULE_AUTHOR("Wang Zhifeng <zhifeng.wang@intel.com>");
+-MODULE_AUTHOR("Zhang Lixu <lixu.zhang@intel.com>");
++MODULE_AUTHOR("Wentong Wu <wentong.wu@intel.com>");
++MODULE_AUTHOR("Zhifeng Wang <zhifeng.wang@intel.com>");
++MODULE_AUTHOR("Lixu Zhang <lixu.zhang@intel.com>");
+ MODULE_DESCRIPTION("Intel La Jolla Cove Adapter USB-GPIO driver");
+ MODULE_LICENSE("GPL");
+ MODULE_IMPORT_NS(LJCA);
+--
+2.51.0
+
--- /dev/null
+From f03437f936c061e2594f520eff9058342a6e387f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 18 Oct 2025 06:04:57 -0700
+Subject: hwmon: (sht3x) Fix error handling
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+[ Upstream commit 8dcc66ad379ec0642fb281c45ccfd7d2d366e53f ]
+
+Handling of errors when reading status, temperature, and humidity returns
+the error number as negative attribute value. Fix it up by returning
+the error as return value.
+
+Fixes: a0ac418c6007c ("hwmon: (sht3x) convert some of sysfs interface to hwmon")
+Cc: JuenKit Yip <JuenKit_Yip@hotmail.com>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/sht3x.c | 27 +++++++++++++++++----------
+ 1 file changed, 17 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/hwmon/sht3x.c b/drivers/hwmon/sht3x.c
+index 79657910b79e6..d8a86e60cf8c1 100644
+--- a/drivers/hwmon/sht3x.c
++++ b/drivers/hwmon/sht3x.c
+@@ -288,24 +288,26 @@ static struct sht3x_data *sht3x_update_client(struct device *dev)
+ return data;
+ }
+
+-static int temp1_input_read(struct device *dev)
++static int temp1_input_read(struct device *dev, long *temp)
+ {
+ struct sht3x_data *data = sht3x_update_client(dev);
+
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+
+- return data->temperature;
++ *temp = data->temperature;
++ return 0;
+ }
+
+-static int humidity1_input_read(struct device *dev)
++static int humidity1_input_read(struct device *dev, long *humidity)
+ {
+ struct sht3x_data *data = sht3x_update_client(dev);
+
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+
+- return data->humidity;
++ *humidity = data->humidity;
++ return 0;
+ }
+
+ /*
+@@ -703,6 +705,7 @@ static int sht3x_read(struct device *dev, enum hwmon_sensor_types type,
+ u32 attr, int channel, long *val)
+ {
+ enum sht3x_limits index;
++ int ret;
+
+ switch (type) {
+ case hwmon_chip:
+@@ -717,10 +720,12 @@ static int sht3x_read(struct device *dev, enum hwmon_sensor_types type,
+ case hwmon_temp:
+ switch (attr) {
+ case hwmon_temp_input:
+- *val = temp1_input_read(dev);
+- break;
++ return temp1_input_read(dev, val);
+ case hwmon_temp_alarm:
+- *val = temp1_alarm_read(dev);
++ ret = temp1_alarm_read(dev);
++ if (ret < 0)
++ return ret;
++ *val = ret;
+ break;
+ case hwmon_temp_max:
+ index = limit_max;
+@@ -745,10 +750,12 @@ static int sht3x_read(struct device *dev, enum hwmon_sensor_types type,
+ case hwmon_humidity:
+ switch (attr) {
+ case hwmon_humidity_input:
+- *val = humidity1_input_read(dev);
+- break;
++ return humidity1_input_read(dev, val);
+ case hwmon_humidity_alarm:
+- *val = humidity1_alarm_read(dev);
++ ret = humidity1_alarm_read(dev);
++ if (ret < 0)
++ return ret;
++ *val = ret;
+ break;
+ case hwmon_humidity_max:
+ index = limit_max;
+--
+2.51.0
+
--- /dev/null
+From a5fdbed4f3e985f3ee6b9bb1a4534a01f7e8de92 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Oct 2025 04:55:24 -0700
+Subject: io_uring: correct __must_hold annotation in io_install_fixed_file
+
+From: Alok Tiwari <alok.a.tiwari@oracle.com>
+
+[ Upstream commit c5efc6a0b3940381d67887302ddb87a5cf623685 ]
+
+The __must_hold annotation references &req->ctx->uring_lock, but req
+is not in scope in io_install_fixed_file. This change updates the
+annotation to reference the correct ctx->uring_lock.
+improving code clarity.
+
+Fixes: f110ed8498af ("io_uring: split out fixed file installation and removal")
+Signed-off-by: Alok Tiwari <alok.a.tiwari@oracle.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ io_uring/filetable.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/io_uring/filetable.c b/io_uring/filetable.c
+index 6e86e6188dbee..ff74d41d9e53c 100644
+--- a/io_uring/filetable.c
++++ b/io_uring/filetable.c
+@@ -62,7 +62,7 @@ void io_free_file_tables(struct io_file_table *table)
+
+ static int io_install_fixed_file(struct io_ring_ctx *ctx, struct file *file,
+ u32 slot_index)
+- __must_hold(&req->ctx->uring_lock)
++ __must_hold(&ctx->uring_lock)
+ {
+ struct io_fixed_file *file_slot;
+ int ret;
+--
+2.51.0
+
--- /dev/null
+From 4e3a4ee3fefa3e784ac9df40b934c34b0280c12e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Oct 2025 21:30:05 -0600
+Subject: RISC-V: Define pgprot_dmacoherent() for non-coherent devices
+
+From: Anup Patel <apatel@ventanamicro.com>
+
+[ Upstream commit ca525d53f994d45c8140968b571372c45f555ac1 ]
+
+The pgprot_dmacoherent() is used when allocating memory for
+non-coherent devices and by default pgprot_dmacoherent() is
+same as pgprot_noncached() unless architecture overrides it.
+
+Currently, there is no pgprot_dmacoherent() definition for
+RISC-V hence non-coherent device memory is being mapped as
+IO thereby making CPU access to such memory slow.
+
+Define pgprot_dmacoherent() to be same as pgprot_writecombine()
+for RISC-V so that CPU access non-coherent device memory as
+NOCACHE which is better than accessing it as IO.
+
+Fixes: ff689fd21cb1 ("riscv: add RISC-V Svpbmt extension support")
+Signed-off-by: Anup Patel <apatel@ventanamicro.com>
+Tested-by: Han Gao <rabenda.cn@gmail.com>
+Tested-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
+Link: https://lore.kernel.org/r/20250820152316.1012757-1-apatel@ventanamicro.com
+Signed-off-by: Paul Walmsley <pjw@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/include/asm/pgtable.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
+index 332a6bf72b1d5..987cfe87e7825 100644
+--- a/arch/riscv/include/asm/pgtable.h
++++ b/arch/riscv/include/asm/pgtable.h
+@@ -618,6 +618,8 @@ static inline pgprot_t pgprot_writecombine(pgprot_t _prot)
+ return __pgprot(prot);
+ }
+
++#define pgprot_dmacoherent pgprot_writecombine
++
+ /*
+ * THP functions
+ */
+--
+2.51.0
+
--- /dev/null
+From eacd6c5ff807674b54d0d099830a60b9907ed633 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Oct 2025 22:00:09 +0530
+Subject: RISC-V: Don't print details of CPUs disabled in DT
+
+From: Anup Patel <apatel@ventanamicro.com>
+
+[ Upstream commit d2721bb165b3ee00dd23525885381af07fec852a ]
+
+Early boot stages may disable CPU DT nodes for unavailable
+CPUs based on SKU, pinstraps, eFuse, etc. Currently, the
+riscv_early_of_processor_hartid() prints details of a CPU
+if it is disabled in DT which has no value and gives a
+false impression to the users that there some issue with
+the CPU.
+
+Fixes: e3d794d555cd ("riscv: treat cpu devicetree nodes without status as enabled")
+Signed-off-by: Anup Patel <apatel@ventanamicro.com>
+Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Link: https://lore.kernel.org/r/20251014163009.182381-1-apatel@ventanamicro.com
+Signed-off-by: Paul Walmsley <pjw@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/cpu.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c
+index 88732abecd023..93e794d0e5231 100644
+--- a/arch/riscv/kernel/cpu.c
++++ b/arch/riscv/kernel/cpu.c
+@@ -61,10 +61,8 @@ int __init riscv_early_of_processor_hartid(struct device_node *node, unsigned lo
+ return -ENODEV;
+ }
+
+- if (!of_device_is_available(node)) {
+- pr_info("CPU with hartid=%lu is not available\n", *hart);
++ if (!of_device_is_available(node))
+ return -ENODEV;
+- }
+
+ if (of_property_read_string(node, "riscv,isa-base", &isa))
+ goto old_interface;
+--
+2.51.0
+
--- /dev/null
+From 825df7217d429b597f05953cedf8bc377b4de17c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Oct 2025 11:19:34 +0200
+Subject: sched: Remove never used code in mm_cid_get()
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 53abe3e1c154628cc74e33a1bfcd865656e433a5 ]
+
+Clang is not happy with set but unused variable (this is visible
+with `make W=1` build:
+
+ kernel/sched/sched.h:3744:18: error: variable 'cpumask' set but not used [-Werror,-Wunused-but-set-variable]
+
+It seems like the variable was never used along with the assignment
+that does not have side effects as far as I can see. Remove those
+altogether.
+
+Fixes: 223baf9d17f2 ("sched: Fix performance regression introduced by mm_cid")
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Tested-by: Eric Biggers <ebiggers@kernel.org>
+Reviewed-by: Breno Leitao <leitao@debian.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/sched.h | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
+index f7cb505ab337a..64634314a89ce 100644
+--- a/kernel/sched/sched.h
++++ b/kernel/sched/sched.h
+@@ -3435,11 +3435,9 @@ static inline int __mm_cid_get(struct rq *rq, struct mm_struct *mm)
+ static inline int mm_cid_get(struct rq *rq, struct mm_struct *mm)
+ {
+ struct mm_cid __percpu *pcpu_cid = mm->pcpu_cid;
+- struct cpumask *cpumask;
+ int cid;
+
+ lockdep_assert_rq_held(rq);
+- cpumask = mm_cidmask(mm);
+ cid = __this_cpu_read(pcpu_cid->cid);
+ if (mm_cid_is_valid(cid)) {
+ mm_cid_snapshot_time(rq, mm);
+--
+2.51.0
+
net-mlx5e-rx-fix-generating-skb-from-non-linear-xdp_.patch-5039
arm64-mm-avoid-always-making-pte-dirty-in-pte_mkwrit.patch
sctp-avoid-null-dereference-when-chunk-data-buffer-i.patch
+spi-spi-nxp-fspi-add-extra-delay-after-dll-locked.patch
+firmware-arm_scmi-account-for-failed-debug-initializ.patch
+firmware-arm_scmi-fix-premature-scmi_xfer_flag_is_ra.patch
+risc-v-define-pgprot_dmacoherent-for-non-coherent-de.patch
+risc-v-don-t-print-details-of-cpus-disabled-in-dt.patch
+hwmon-sht3x-fix-error-handling.patch
+gpio-update-intel-ljca-usb-gpio-driver.patch
+gpio-ljca-fix-duplicated-irq-mapping.patch
+io_uring-correct-__must_hold-annotation-in-io_instal.patch
+sched-remove-never-used-code-in-mm_cid_get.patch
--- /dev/null
+From c79cc7ac845ae1c78727be08ad2f3607769ee3bc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Sep 2025 16:47:14 +0800
+Subject: spi: spi-nxp-fspi: add extra delay after dll locked
+
+From: Han Xu <han.xu@nxp.com>
+
+[ Upstream commit b93b4269791fdebbac2a9ad26f324dc2abb9e60f ]
+
+Due to the erratum ERR050272, the DLL lock status register STS2
+[xREFLOCK, xSLVLOCK] bit may indicate DLL is locked before DLL is
+actually locked. Add an extra 4us delay as a workaround.
+
+refer to ERR050272, on Page 20.
+https://www.nxp.com/docs/en/errata/IMX8_1N94W.pdf
+
+Fixes: 99d822b3adc4 ("spi: spi-nxp-fspi: use DLL calibration when clock rate > 100MHz")
+Signed-off-by: Han Xu <han.xu@nxp.com>
+Signed-off-by: Haibo Chen <haibo.chen@nxp.com>
+Link: https://patch.msgid.link/20250922-fspi-fix-v1-2-ff4315359d31@nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-nxp-fspi.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c
+index bc6c086ddd43f..731504ec7ef8b 100644
+--- a/drivers/spi/spi-nxp-fspi.c
++++ b/drivers/spi/spi-nxp-fspi.c
+@@ -665,6 +665,12 @@ static void nxp_fspi_dll_calibration(struct nxp_fspi *f)
+ 0, POLL_TOUT, true);
+ if (ret)
+ dev_warn(f->dev, "DLL lock failed, please fix it!\n");
++
++ /*
++ * For ERR050272, DLL lock status bit is not accurate,
++ * wait for 4us more as a workaround.
++ */
++ udelay(4);
+ }
+
+ /*
+--
+2.51.0
+