From nobody Tue Dec 2 01:06:34 2025 Received: from smtpout-04.galae.net (smtpout-04.galae.net [185.171.202.116]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4C4BA290D81 for ; Fri, 21 Nov 2025 15:42:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.171.202.116 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763739777; cv=none; b=rQ1kUKIW6mPK+kPgtoO/UxUaL5TLhoPgVUx4wncFjI/Ttzj0FmAghK995cw+mjta2QBxe/1g2kUBqGWFY9O/KwioW56aCSzAgv1RWOh//us0SdRwutiIhy6l+Nx7SPqIyL7iRebhxDN3LyFFSkBn2+RDfl8qbr8VpIEsTqqGLHM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763739777; c=relaxed/simple; bh=v8Ay6EqTkhbZBFkjZA8PgCzQZBclbCRf0P+1UkubZZM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=TkjMh9CkHlU28XgTB826s+HcWED7OXmxnG7yZO7bUXhUVZjEHF2Dvv2KfTndGKfn6Y1qpdeYBGmhZlkTpA+RtrZVhVfjVlfYUlF7WZqVN0JcAop5Fx03E3gI6eyyHmlPw6QhGW4G2vo2krib4SQ5cz2yzn//oNP1OqWEi6j/GmQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=Yyy9clkS; arc=none smtp.client-ip=185.171.202.116 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="Yyy9clkS" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id C2B52C101A0; Fri, 21 Nov 2025 15:42:20 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 24B9660719; Fri, 21 Nov 2025 15:42:43 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id D153F103721D1; Fri, 21 Nov 2025 16:42:40 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1763739762; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=v3k4BM6DHfFUns+7M05p2i5ryrAGLPtZpRAsjWs1HE8=; b=Yyy9clkS5cA4HNP14XF8n2mC2J/avKHUerjK23wreJRbhdl861iyuBAA84fC/rVnoSREQd jAknIWgIVGXH4Jvl5xhAaq1Z3p9fgkG4MGWO37avggxKl9Fjq4WciSJQw4ieQDSxlNJQio RUOPTGw9t1lzLSLYIvTMdzkDbcbC9CQ6adFDE/MAFRtPGzeWtXqdPmrJkx5behzsc63YvU ka5v08Lr22y72fXU0Db0+W+JE64HaaTWEUFUNvViWa6ubv9KP3x/FwupUMnzv8shlb9Nkj 3rejCxVeTcctwFPFY4b//bfSaP1ykyWeyl2IVr7k038kqeNjCPUZyxIxXJK3ZA== From: Gregory CLEMENT Date: Fri, 21 Nov 2025 16:42:35 +0100 Subject: [PATCH v2 1/3] of: reserved_mem: Support multiple 'reg' entries for memory-region Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251121-mtd-memregion-v2-1-c5535fdcebe4@bootlin.com> References: <20251121-mtd-memregion-v2-0-c5535fdcebe4@bootlin.com> In-Reply-To: <20251121-mtd-memregion-v2-0-c5535fdcebe4@bootlin.com> To: Rob Herring , Linus Walleij , Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Krzysztof Kozlowski , Conor Dooley Cc: Thomas Petazzoni , Vladimir Kondratiev , =?utf-8?q?Beno=C3=AEt_Monin?= , =?utf-8?q?Th=C3=A9o_Lebrun?= , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mtd@lists.infradead.org, Gregory CLEMENT X-Mailer: b4 0.14.3 X-Last-TLS-Session-Version: TLSv1.3 X-Rspamd-Fuzzy: 4424144f4218900c354d6490f15d7fd89bd74a90c2a7348481eaef86083880102d8c77ac236285b683c0bd37638dc6a3f0301a0bc431696a6ae2fe169c719249 The Device Tree specification allows a "memory-region" node to have multiple 'reg' entries, but the current kernel implementation only processes the first entry. This can lead to drivers not being able to access all the reserved memory regions specified in the Device Tree. This patch extends the reserved memory handling to support multiple 'reg' entries for a single "memory-region" node. The existing exported functions remain unchanged for backward compatibility, but new APIs are introduced to allow drivers to access all reserved memory regions. Signed-off-by: Gregory CLEMENT --- drivers/of/of_reserved_mem.c | 139 ++++++++++++++++++++++++++++++++++++= ---- include/linux/of_reserved_mem.h | 4 ++ 2 files changed, 131 insertions(+), 12 deletions(-) diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c index 2e9ea751ed2df..ecb3ffe74113f 100644 --- a/drivers/of/of_reserved_mem.c +++ b/drivers/of/of_reserved_mem.c @@ -159,6 +159,7 @@ static int __init __reserved_mem_reserve_reg(unsigned l= ong node, int len; const __be32 *prop; bool nomap; + int count =3D 0; =20 prop =3D of_get_flat_dt_prop(node, "reg", &len); if (!prop) @@ -183,6 +184,7 @@ static int __init __reserved_mem_reserve_reg(unsigned l= ong node, dma_contiguous_early_fixup(base, size); pr_debug("Reserved memory: reserved region for node '%s': base %pa, siz= e %lu MiB\n", uname, &base, (unsigned long)(size / SZ_1M)); + count++; } else { pr_err("Reserved memory: failed to reserve memory for node '%s': base %= pa, size %lu MiB\n", uname, &base, (unsigned long)(size / SZ_1M)); @@ -190,7 +192,7 @@ static int __init __reserved_mem_reserve_reg(unsigned l= ong node, =20 len -=3D t_len; } - return 0; + return count; } =20 /* @@ -235,7 +237,7 @@ void __init fdt_scan_reserved_mem_reg_nodes(void) phys_addr_t base, size; const __be32 *prop; int node, child; - int len; + int len, i; =20 if (!fdt) return; @@ -273,12 +275,12 @@ void __init fdt_scan_reserved_mem_reg_nodes(void) if (len > t_len) pr_warn("%s() ignores %d regions in node '%s'\n", __func__, len / t_len - 1, uname); - - base =3D dt_mem_next_cell(dt_root_addr_cells, &prop); - size =3D dt_mem_next_cell(dt_root_size_cells, &prop); - - if (size) - fdt_reserved_mem_save_node(child, uname, base, size); + for (i =3D 0; i < len; i +=3D t_len) { + base =3D dt_mem_next_cell(dt_root_addr_cells, &prop); + size =3D dt_mem_next_cell(dt_root_size_cells, &prop); + if (size) + fdt_reserved_mem_save_node(child, uname, base, size); + } } =20 /* check for overlapping reserved regions */ @@ -308,16 +310,16 @@ int __init fdt_scan_reserved_mem(void) =20 fdt_for_each_subnode(child, fdt, node) { const char *uname; - int err; + int err, ret; =20 if (!of_fdt_device_is_available(fdt, child)) continue; =20 uname =3D fdt_get_name(fdt, child, NULL); =20 - err =3D __reserved_mem_reserve_reg(child, uname); - if (!err) - count++; + ret =3D __reserved_mem_reserve_reg(child, uname); + if (ret > 0) + count +=3D ret; /* * Save the nodes for the dynamically-placed regions * into an array which will be used for allocation right @@ -750,6 +752,35 @@ struct reserved_mem *of_reserved_mem_lookup(struct dev= ice_node *np) } EXPORT_SYMBOL_GPL(of_reserved_mem_lookup); =20 +/** + * of_reserved_mem_array_lookup() - acquire reserved_mem array from a devi= ce node + * @np: node pointer of the desired reserved-memory region + * @rmrm: pointer to the first elemennt of the reserved_mem struct of the = memory region + * + * This function allows drivers to acquire a reference to the array of the + * reserved_mem struct based on a device node handle. + * + * Returns the number reserved_mem elements + */ +int of_reserved_mem_array_lookup(struct device_node *np, + struct reserved_mem **rmem) +{ + const char *name; + int i, count =3D 0; + + if (!np->full_name) + return 0; + + name =3D kbasename(np->full_name); + + for (i =3D 0; i < reserved_mem_count; i++) + if (!strcmp(reserved_mem[i].name, name)) + rmem[count++] =3D &reserved_mem[i]; + + return count; +} +EXPORT_SYMBOL_GPL(of_reserved_mem_array_lookup); + /** * of_reserved_mem_region_to_resource() - Get a reserved memory region as = a resource * @np: node containing 'memory-region' property @@ -785,6 +816,49 @@ int of_reserved_mem_region_to_resource(const struct de= vice_node *np, } EXPORT_SYMBOL_GPL(of_reserved_mem_region_to_resource); =20 +/** + * of_reserved_mem_region_to_resource_array() - Get a reserved memory regi= on as a resources + * @dev: device associated to the node + * @np: node containing 'memory-region' property + * @idx: index of 'memory-region' property to lookup + * @res: Pointer to an array of struct resource pointers to fill in with r= eserved regions + * + * This function allows drivers to lookup a node's 'memory-region' property + * entries by index and fill an array of struct resource pointers for the = entries. + * + * Returns the number of resources filled in @res on success. + * Returns -ENODEV if 'memory-region' is missing or unavailable, + * -EINVAL for any other error. + */ +int of_reserved_mem_region_to_resource_array(struct device *dev, const str= uct device_node *np, + unsigned int idx, struct resource **res) +{ + struct reserved_mem *rmem[MAX_RESERVED_REGIONS]; + int count, i; + struct resource *r; + + if (!np) + return -EINVAL; + + struct device_node __free(device_node) *target =3D of_parse_phandle(np, "= memory-region", idx); + if (!target || !of_device_is_available(target)) + return -ENODEV; + + count =3D of_reserved_mem_array_lookup(target, rmem); + if (count <=3D 0) + return -EINVAL; + + *res =3D devm_kzalloc(dev, count * sizeof(struct resource), GFP_KERNEL); + r =3D res[0]; + for (i =3D 0; i < count; i++) { + resource_set_range(&r[i], rmem[i]->base, rmem[i]->size); + r[i].flags =3D IORESOURCE_MEM; + r[i].name =3D rmem[i]->name; + } + return count; +} +EXPORT_SYMBOL_GPL(of_reserved_mem_region_to_resource_array); + /** * of_reserved_mem_region_to_resource_byname() - Get a reserved memory reg= ion as a resource * @np: node containing 'memory-region' property @@ -829,3 +903,44 @@ int of_reserved_mem_region_count(const struct device_n= ode *np) return of_count_phandle_with_args(np, "memory-region", NULL); } EXPORT_SYMBOL_GPL(of_reserved_mem_region_count); + +/** + * of_reserved_mem_region_count() - Return the total number of reserved me= mory regions + * @np: node containing 'memory-region' property + * + * This function counts the total number of reserved memory regions refere= nced + * by a node's 'memory-region' property. It iterates over each phandle and= sums + * the number of regions found in each referenced reserved memory node. + * + * Returns the total number of reserved memory regions on success. + * This function allows drivers to retrieve the number of entries for a no= de's + * 'memory-region' property. + * + * Returns total number of reserved memory regions on success, or negative= error + * code on a malformed property. + */ +int of_reserved_mem_region_total_count(const struct device_node *np) +{ + int nregion =3D of_count_phandle_with_args(np, "memory-region", NULL); + struct device_node *target; + int i, nregs =3D 0; + + for (i =3D 0; i < nregion; i++) { + struct reserved_mem *rmem; + + target =3D of_parse_phandle(np, "memory-region", i); + if (!target) + return -ENODEV; + + if (!of_device_is_available(target)) { + of_node_put(target); + return 0; + } + + nregs +=3D of_reserved_mem_array_lookup(target, &rmem); + + of_node_put(target); + }; + return nregs; +} +EXPORT_SYMBOL_GPL(of_reserved_mem_region_total_count); diff --git a/include/linux/of_reserved_mem.h b/include/linux/of_reserved_me= m.h index f573423359f48..1e0c6afddd812 100644 --- a/include/linux/of_reserved_mem.h +++ b/include/linux/of_reserved_mem.h @@ -40,11 +40,15 @@ int of_reserved_mem_device_init_by_name(struct device *= dev, void of_reserved_mem_device_release(struct device *dev); =20 struct reserved_mem *of_reserved_mem_lookup(struct device_node *np); +int of_reserved_mem_array_lookup(struct device_node *np, struct reserved_m= em **rmem); int of_reserved_mem_region_to_resource(const struct device_node *np, unsigned int idx, struct resource *res); +int of_reserved_mem_region_to_resource_array(struct device *dev, const str= uct device_node *np, + unsigned int idx, struct resource **res); int of_reserved_mem_region_to_resource_byname(const struct device_node *np, const char *name, struct resource *res); int of_reserved_mem_region_count(const struct device_node *np); +int of_reserved_mem_region_total_count(const struct device_node *np); =20 #else =20 --=20 2.51.0 From nobody Tue Dec 2 01:06:34 2025 Received: from smtpout-04.galae.net (smtpout-04.galae.net [185.171.202.116]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 28DC02EC0BD; Fri, 21 Nov 2025 15:42:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.171.202.116 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763739776; cv=none; b=jBQcUCTl/CL12VuQIjlaVLaYxiSYoWudZJk1rJcnwE2A2VJLtCNz8VhBaif0JK1qZ1h4xW/D8WI+q5YQ8yFEvjyqckXleFtwcmcayhMTKupzKwxgFVd9rXoZSm5BL86envDfqunotsQUJEQATZXfhXpCFRaA1N+y4kX/29GF60Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763739776; c=relaxed/simple; bh=gZqvFmuQgpTYT5A6ihr6YFdLxThPhtzNyCmkRuU0ndo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ar8DXlpAhwbBWkdKY46kcasKwQdouj7Lds+OQ4vGkLJ7Z0XpuIJoW9ACm61YvvofaI3pYV5d6V/xSm+2gY+VacDIbG74VjibKr8jbLOYdveHHcqxxZcNRb/10VLo4yK222TQdduQlcDf4TIcGAyQpPe9YwjMOviLjrVMgqc83oc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=gvolDSzw; arc=none smtp.client-ip=185.171.202.116 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="gvolDSzw" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id 9C1C6C101A1; Fri, 21 Nov 2025 15:42:22 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 0707960719; Fri, 21 Nov 2025 15:42:45 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 038AD103721D4; Fri, 21 Nov 2025 16:42:42 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1763739764; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=vd05fhfs2qIh00fsYfg5TZpdIMO9uBjqduJxogccVqo=; b=gvolDSzwc4oz9CtQ9n9Ne+bvhUP9cWcSiXZQMTWfdlpF8D92vHrXO8g5UmdoKhbHoLiOzZ MUeEtzXz5+v7rMX9/zpl37C6JnoqmXL7LF2aBc6aux7vr3aabgLSqFT++fCEQiuqhwJSYF 4L5sxyPcn0IGQVmP2C7SMNaPSD9VHmWlqbQWi2hp+E+hWKhNBpIgV3wRRUN0ECCC9BlE/D iOSNmc+iPYm16ZHpSVIWWV02HOSS7JgKeTOjwCzR35nqXf5/RcvcBJHTtOBFJc42cgEME1 9UZWLLu+VKi6eK/hecmr5+rFspaYoaZDpKorHR+e5eCDjk5kyQXgRc7D3F6G8g== From: Gregory CLEMENT Date: Fri, 21 Nov 2025 16:42:36 +0100 Subject: [PATCH v2 2/3] dt-bindings: mtd: physmap: Allow using memory-region to access memory resources Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251121-mtd-memregion-v2-2-c5535fdcebe4@bootlin.com> References: <20251121-mtd-memregion-v2-0-c5535fdcebe4@bootlin.com> In-Reply-To: <20251121-mtd-memregion-v2-0-c5535fdcebe4@bootlin.com> To: Rob Herring , Linus Walleij , Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Krzysztof Kozlowski , Conor Dooley Cc: Thomas Petazzoni , Vladimir Kondratiev , =?utf-8?q?Beno=C3=AEt_Monin?= , =?utf-8?q?Th=C3=A9o_Lebrun?= , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mtd@lists.infradead.org, Gregory CLEMENT X-Mailer: b4 0.14.3 X-Last-TLS-Session-Version: TLSv1.3 Enable access to memory resources not only via I/O address using reg, but also through a portion of main memory using memory-region. To achieve this, new compatible strings have been introduced: mtd-mem and mtd-memro. Signed-off-by: Gregory CLEMENT --- .../devicetree/bindings/mtd/mtd-physmap.yaml | 59 +++++++++++++++---= ---- 1 file changed, 40 insertions(+), 19 deletions(-) diff --git a/Documentation/devicetree/bindings/mtd/mtd-physmap.yaml b/Docum= entation/devicetree/bindings/mtd/mtd-physmap.yaml index 1b375dee83b0c..323e89aacaacd 100644 --- a/Documentation/devicetree/bindings/mtd/mtd-physmap.yaml +++ b/Documentation/devicetree/bindings/mtd/mtd-physmap.yaml @@ -13,10 +13,6 @@ description: | Flash chips (Memory Technology Devices) are often used for solid state file systems on embedded devices. =20 -allOf: - - $ref: mtd.yaml# - - $ref: /schemas/memory-controllers/mc-peripheral-props.yaml# - properties: compatible: oneOf: @@ -61,6 +57,8 @@ properties: - jedec-flash - mtd-ram - mtd-rom + - mtd-mem + - mtd-memro =20 reg: description: | @@ -116,6 +114,10 @@ properties: minItems: 1 maxItems: 8 =20 + memory-region: + items: + - description: Memory regions to map into mtd + '#address-cells': const: 1 =20 @@ -129,21 +131,25 @@ properties: =20 required: - compatible - - reg - -if: - properties: - compatible: - contains: - const: cortina,gemini-flash -then: - properties: - syscon: - $ref: /schemas/types.yaml#/definitions/phandle - description: - Phandle to the syscon controller - required: - - syscon + +allOf: + - $ref: mtd.yaml# + - if: + properties: + compatible: + contains: + enum: + - mtd-mem + - mtd-memro + then: + required: + - memory-region + properties: + addr-gpios: false + else: + $ref: /schemas/memory-controllers/mc-peripheral-props.yaml# + required: + - reg =20 unevaluatedProperties: false =20 @@ -223,4 +229,19 @@ examples: reg =3D <0 0x04000000>; }; }; + + - | + /* An example using mtd-mem */ + mem_logs: mem_logs@10000800 { + reg =3D <0x1 0x0000800 0x0 0x000f800>; + no-map; + }; + + memlog { + compatible =3D "mtd-mem"; + memory-region =3D <&mem_log>; + bank-width =3D <4>; + device-width =3D <1>; + }; + ... --=20 2.51.0 From nobody Tue Dec 2 01:06:34 2025 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BC27E2D8764 for ; Fri, 21 Nov 2025 15:42:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763739775; cv=none; b=kyHaClgDUWFBXuWslZefc/GfRVpcT+bEtZ6o6xScBYaT3Wgd0jbIHlPp+Skx9FWo7yNPoX+aCa9fRW0DVkLCQjQGpIBEbq2cQSPUiveAYjCXeMwm7juopO1yTU9VoabT33QfXzwTr5plPdpKLdHDU02ec7bjqStM+adRH0SMdKY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763739775; c=relaxed/simple; bh=R4Di4HnIicbPPtLbB8fde2op/ku0MJYw+GNztvpfabw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=QrHlPvq6wlClfWRjGRc3nz9g3gF+bpqDUh1c8MTUTAfpJYsLsrfTleibpC2I3/y8f0CCGeFlp/xvOd0wrMyQwHBoeD7df9c8Bg2TdWcN6qaFRp++zVC65moVNkX8KgT7NIfLnxPobX8+P98cu5Y8lUQ6r6rcNtCtGWd7ESCGcdc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=cvmVBhT6; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="cvmVBhT6" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id CBB0B1A1C97; Fri, 21 Nov 2025 15:42:46 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 9E51D60719; Fri, 21 Nov 2025 15:42:46 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id A793210372188; Fri, 21 Nov 2025 16:42:44 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1763739765; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=BTriyQZYYbnJqpQ9NHQXwg7JbzvLw55voRo8bIRkgF0=; b=cvmVBhT6OnVhWqrq/NM5dwpFkuXvXiRy+NzWEqJJOy1dNawbXqrlhyFSOExl1av7RgTWXV pWRRuJ25YYOIquXNd9ssNDDExXKSelGjameE8FGYnF45biWFSmLXHqd7NiRdfEUBkIq76I RuddAFVlYFKhIGyPdGXHVZ4A/S6uL7Gj7R3KqfpoSxfh9UJTQG8TXuYNEyh1rYYdm1Yo7X /i1Io1C8oJUV0ljSZZbRYVVbRlmdvAlQTYKATPKK0XFHTSO/MLb16BIY1vO5E5j4auqknt URLxal3XwSQOoUZ3rsexAtskjDkthSvpHJSr0R/ehNAJiNfrdJ8LF1yl8SL3vw== From: Gregory CLEMENT Date: Fri, 21 Nov 2025 16:42:37 +0100 Subject: [PATCH v2 3/3] mtd: physmap: Add support for RAM reserved memory regions Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251121-mtd-memregion-v2-3-c5535fdcebe4@bootlin.com> References: <20251121-mtd-memregion-v2-0-c5535fdcebe4@bootlin.com> In-Reply-To: <20251121-mtd-memregion-v2-0-c5535fdcebe4@bootlin.com> To: Rob Herring , Linus Walleij , Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Krzysztof Kozlowski , Conor Dooley Cc: Thomas Petazzoni , Vladimir Kondratiev , =?utf-8?q?Beno=C3=AEt_Monin?= , =?utf-8?q?Th=C3=A9o_Lebrun?= , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mtd@lists.infradead.org, Gregory CLEMENT X-Mailer: b4 0.14.3 X-Last-TLS-Session-Version: TLSv1.3 MTD fixed-partitions can now be exposed for reserved RAM regions, not just ROM reg regions. This is achieved by using a memory-region phandle to reference the reserved RAM region instead of the reg property. Based on the work of Muhammad Musa Signed-off-by: Gregory CLEMENT --- drivers/mtd/maps/physmap-core.c | 56 ++++++++++++++++++++++++++++++++++---= ---- 1 file changed, 47 insertions(+), 9 deletions(-) diff --git a/drivers/mtd/maps/physmap-core.c b/drivers/mtd/maps/physmap-cor= e.c index 2bd7a1af898c9..f084f6f34d611 100644 --- a/drivers/mtd/maps/physmap-core.c +++ b/drivers/mtd/maps/physmap-core.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include =20 @@ -263,6 +264,14 @@ static const struct of_device_id of_flash_match[] =3D { .type =3D "rom", .compatible =3D "direct-mapped" }, + { + .compatible =3D "mtd-mem", + .data =3D "map_ram", + }, + { + .compatible =3D "mtd-memro", + .data =3D "map_rom", + }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, of_flash_match); @@ -446,8 +455,9 @@ static int physmap_flash_pdata_init(struct platform_dev= ice *dev) static int physmap_flash_probe(struct platform_device *dev) { struct physmap_flash_info *info; - int err =3D 0; - int i; + struct resource *res_array; + int err =3D 0, is_rsvd_mem =3D 0, nreg =3D 0; + int i, curr_reg; =20 if (!dev->dev.of_node && !dev_get_platdata(&dev->dev)) return -EINVAL; @@ -459,9 +469,13 @@ static int physmap_flash_probe(struct platform_device = *dev) while (platform_get_resource(dev, IORESOURCE_MEM, info->nmaps)) info->nmaps++; =20 - if (!info->nmaps) - return -ENODEV; - + if (!info->nmaps) { + info->nmaps =3D of_reserved_mem_region_total_count(dev->dev.of_node); + if (info->nmaps > 0) + is_rsvd_mem =3D 1; + else + return -ENODEV; + } info->maps =3D devm_kzalloc(&dev->dev, sizeof(*info->maps) * info->nmaps, GFP_KERNEL); @@ -503,7 +517,23 @@ static int physmap_flash_probe(struct platform_device = *dev) for (i =3D 0; i < info->nmaps; i++) { struct resource *res; =20 - info->maps[i].virt =3D devm_platform_get_and_ioremap_resource(dev, i, &r= es); + if (is_rsvd_mem) { + if (nreg <=3D i) { + int cnt =3D of_reserved_mem_region_to_resource_array(&dev->dev, + dev->dev.of_node, i, &res_array); + if (cnt < 0) { + err =3D cnt; + goto err_out; + } + nreg +=3D cnt; + curr_reg =3D 0; + } + res =3D &res_array[curr_reg++]; + info->maps[i].virt =3D devm_ioremap_resource(&dev->dev, res); + } else { + info->maps[i].virt =3D devm_platform_get_and_ioremap_resource(dev, i, &= res); + } + if (IS_ERR(info->maps[i].virt)) { err =3D PTR_ERR(info->maps[i].virt); goto err_out; @@ -519,9 +549,17 @@ static int physmap_flash_probe(struct platform_device = *dev) info->maps[i].phys =3D res->start; =20 info->win_order =3D fls64(resource_size(res)) - 1; - info->maps[i].size =3D BIT(info->win_order + - (info->gpios ? - info->gpios->ndescs : 0)); + /* When using a memory region, the size is not necessarily a + * power of 2, so win_order is not applicable. Since GPIOs are + * unavailable in this context, directly using the region's size + * is safe. + */ + if (is_rsvd_mem) + info->maps[i].size =3D resource_size(res); + else + info->maps[i].size =3D BIT(info->win_order + + (info->gpios ? + info->gpios->ndescs : 0)); =20 info->maps[i].map_priv_1 =3D (unsigned long)dev; =20 --=20 2.51.0