From nobody Mon May 11 07:06:12 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1EB6EC433FE for ; Tue, 12 Apr 2022 13:53:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1356425AbiDLNzw (ORCPT ); Tue, 12 Apr 2022 09:55:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51372 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1356372AbiDLNz3 (ORCPT ); Tue, 12 Apr 2022 09:55:29 -0400 Received: from smtp2.axis.com (smtp2.axis.com [195.60.68.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2944E5716E; Tue, 12 Apr 2022 06:53:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=axis.com; q=dns/txt; s=axis-central1; t=1649771589; x=1681307589; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=7cRqrzsYNIRfiAOotHa409y/Hl5ia/NeruEwkXktTvU=; b=a0Q4bD4xe9Vgk7lswM/brL3FPWhU9ZFmXjJ7Ve2idfSJzVx+4jK1YGNV VPXcD7srccXyED6vDy9W3LOJQbcTZ+w7V/xjfY3vmvMC/y5hhtiwEGCGj GkqCM77pTGJm0aMNIeCfjKg/z6XDssmuZBLEpYZDdkbOH/NImbuUbYeG3 QaCcMO9a2k4Oq1RnlIqyy9kxo+LP+UaKtLqCARPhTIkQUpJmevN1CUt2h fjrNIemSGWrvlR7eweH22s8UQKO6zt46bf3LfGp9JmMnCfGYpWB4ahQEK BXb8kw+OGX2Mz5nkBKAF27HjU2MyAYk5ZTLOxefV7VhPbY24nfwhrDgLF g==; From: Vincent Whitchurch To: , , , CC: , Vincent Whitchurch , , , , , , Subject: [PATCH v3 1/4] mtd: core: Check devicetree alias for index Date: Tue, 12 Apr 2022 15:52:59 +0200 Message-ID: <20220412135302.1682890-2-vincent.whitchurch@axis.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220412135302.1682890-1-vincent.whitchurch@axis.com> References: <20220412135302.1682890-1-vincent.whitchurch@axis.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Allow the MTD index to be specified via a devicetree alias, so that the number does not just depend on probe order. This is useful to allow pseudo-devices like phram to be optionally used on systems, without having this affect the numbering of the real hardware MTD devices. Signed-off-by: Vincent Whitchurch --- drivers/mtd/mtdcore.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index 7731796024e0..9eb0680db312 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -557,9 +557,10 @@ static int mtd_nvmem_add(struct mtd_info *mtd) =20 int add_mtd_device(struct mtd_info *mtd) { + struct device_node *np =3D mtd_get_of_node(mtd); struct mtd_info *master =3D mtd_get_master(mtd); struct mtd_notifier *not; - int i, error; + int i, error, ofidx; =20 /* * May occur, for instance, on buggy drivers which call @@ -598,7 +599,13 @@ int add_mtd_device(struct mtd_info *mtd) =20 mutex_lock(&mtd_table_mutex); =20 - i =3D idr_alloc(&mtd_idr, mtd, 0, 0, GFP_KERNEL); + ofidx =3D -1; + if (np) + ofidx =3D of_alias_get_id(np, "mtd"); + if (ofidx >=3D 0) + i =3D idr_alloc(&mtd_idr, mtd, ofidx, ofidx + 1, GFP_KERNEL); + else + i =3D idr_alloc(&mtd_idr, mtd, 0, 0, GFP_KERNEL); if (i < 0) { error =3D i; goto fail_locked; --=20 2.34.1 From nobody Mon May 11 07:06:12 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C049EC433F5 for ; Tue, 12 Apr 2022 13:53:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1356395AbiDLNzb (ORCPT ); Tue, 12 Apr 2022 09:55:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51300 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1356352AbiDLNzZ (ORCPT ); Tue, 12 Apr 2022 09:55:25 -0400 Received: from smtp2.axis.com (smtp2.axis.com [195.60.68.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7955757488; Tue, 12 Apr 2022 06:53:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=axis.com; q=dns/txt; s=axis-central1; t=1649771588; x=1681307588; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=jupemliQ8dJWnscgwhDk1djkO0V1yNDM+5JWRzk83NE=; b=AsPkKyqRtkZeyL7JAWRqNjITpIQwd2aRv3sIsgEO3000zpSp1w7RwlHG 9iaNT6vCNeCQdXD+dAmx3OKQbEGaag9JLgIMG3QITu4CDDSo8t+4MiUrt sv1UOvMIO7W+b+/BaG9G9Ji/uyncRR7ExGGmXLYCZkem/zHYpWLqyYdqF cMLDu36juukh721NzCbP/+J7U0AFr1oLzI8UUjoNqQ9ZVAJ/9Qe93ovld VVDqHlyZKvS/E7+NvXwJHB7NnUO9UGCn4WNiCect5HZmBrb4orkf3sWRq v/Wi1Ik27HultEwH27w2Sq7i68Jq11RFgt1Z0XWO8QGn8bM5Ea63DG5r7 A==; From: Vincent Whitchurch To: , , , CC: , Vincent Whitchurch , , , , , , Subject: [PATCH v3 2/4] dt-bindings: reserved-memory: Support MTD/block device Date: Tue, 12 Apr 2022 15:53:00 +0200 Message-ID: <20220412135302.1682890-3-vincent.whitchurch@axis.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220412135302.1682890-1-vincent.whitchurch@axis.com> References: <20220412135302.1682890-1-vincent.whitchurch@axis.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add bindings to allow MTD/block devices to be used in reserved-memory regions using the "phram" (MTD in PHysical RAM) driver. This allows things like partitioning to be specified via the existing devicetree bindings. Signed-off-by: Vincent Whitchurch Reviewed-by: Rob Herring --- Notes: v3: - Reword description. =20 v2: - Add note on what "phram" means. - Use /schemas/mtd/mtd.yaml instead of relative pathUse /schemas/mtd/mt= d.yaml instead of relative path. .../bindings/reserved-memory/phram.yaml | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 Documentation/devicetree/bindings/reserved-memory/phram= .yaml diff --git a/Documentation/devicetree/bindings/reserved-memory/phram.yaml b= /Documentation/devicetree/bindings/reserved-memory/phram.yaml new file mode 100644 index 000000000000..6c4db28015f1 --- /dev/null +++ b/Documentation/devicetree/bindings/reserved-memory/phram.yaml @@ -0,0 +1,47 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/reserved-memory/phram.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MTD/block device in RAM + +description: | + Specifies that the reserved memory region can be used as an MTD or block + device. + + The "phram" node is named after the "MTD in PHysical RAM" driver which + provides an implementation of this functionality in Linux. + +maintainers: + - Vincent Whitchurch + +allOf: + - $ref: "reserved-memory.yaml" + - $ref: "/schemas/mtd/mtd.yaml" + +properties: + compatible: + const: phram + + reg: + description: region of memory that can be used as an MTD/block device + +required: + - compatible + - reg + +unevaluatedProperties: false + +examples: + - | + reserved-memory { + #address-cells =3D <1>; + #size-cells =3D <1>; + + phram: flash@12340000 { + compatible =3D "phram"; + label =3D "rootfs"; + reg =3D <0x12340000 0x00800000>; + }; + }; --=20 2.34.1 From nobody Mon May 11 07:06:12 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4F32EC433EF for ; Tue, 12 Apr 2022 13:53:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1356401AbiDLNzi (ORCPT ); Tue, 12 Apr 2022 09:55:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51378 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1356379AbiDLNz3 (ORCPT ); Tue, 12 Apr 2022 09:55:29 -0400 Received: from smtp2.axis.com (smtp2.axis.com [195.60.68.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AE210583AD; Tue, 12 Apr 2022 06:53:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=axis.com; q=dns/txt; s=axis-central1; t=1649771591; x=1681307591; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=1WivjijgLp2UzgX8W5CgQakX5pH8VwBd0BfhWfMFW+Q=; b=Jtmyrn3WpYYHaCmHkiJKBw95g3pm7SMH9cnuTCdT7W+z6FKJx1gvYQK/ 7KGe3IAR6sXrKWPQgt9GRfiJeU3DyMQiG2UZz8J8Gp50F3s8Pu88/I94G vU3z8b+4I8/1BAX+iWln6mVrvVm1880jV8FO3uE/R5AOMmUUz/GC776xc i3+cRQtpjFN9iGIKgXZmByiG4ylMUXwjfffXmFpkRJrnfqF8yvU1UHNH3 N6VNLoBYXqYYq67hyqB0DK2P3CLubWlEtvTE8UHcczQKZdAOgLQM+Ya3W Ht8ySXY4xB/MwYzgU98/bXdkxQ9eJ1M5upaeSn4EPVHS8V5o7KDrHZq56 A==; From: Vincent Whitchurch To: , , , CC: , Vincent Whitchurch , , , , , , Subject: [PATCH v3 3/4] mtd: phram: Allow probing via reserved-memory Date: Tue, 12 Apr 2022 15:53:01 +0200 Message-ID: <20220412135302.1682890-4-vincent.whitchurch@axis.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220412135302.1682890-1-vincent.whitchurch@axis.com> References: <20220412135302.1682890-1-vincent.whitchurch@axis.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Allow phram to be probed from the devicetree. It expects to be in a reserved-memory node as documented by the bindings. This allows things like partitioning to be specified via the devicetree. Signed-off-by: Vincent Whitchurch Acked-by: Rob Herring --- Notes: v3: - Add missing semicolon after MODULE_DEVICE_TABLE causing build errors = on some configs. drivers/mtd/devices/phram.c | 67 ++++++++++++++++++++++++++++++++++--- drivers/of/platform.c | 1 + 2 files changed, 64 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c index d503821a3e60..506e9edf5c85 100644 --- a/drivers/mtd/devices/phram.c +++ b/drivers/mtd/devices/phram.c @@ -27,6 +27,9 @@ #include #include #include +#include +#include +#include =20 struct phram_mtd_list { struct mtd_info mtd; @@ -89,8 +92,10 @@ static void unregister_devices(void) } } =20 -static int register_device(char *name, phys_addr_t start, size_t len, uint= 32_t erasesize) +static int register_device(struct platform_device *pdev, const char *name, + phys_addr_t start, size_t len, uint32_t erasesize) { + struct device_node *np =3D pdev ? pdev->dev.of_node : NULL; struct phram_mtd_list *new; int ret =3D -ENOMEM; =20 @@ -119,13 +124,19 @@ static int register_device(char *name, phys_addr_t st= art, size_t len, uint32_t e new->mtd.erasesize =3D erasesize; new->mtd.writesize =3D 1; =20 + mtd_set_of_node(&new->mtd, np); + ret =3D -EAGAIN; if (mtd_device_register(&new->mtd, NULL, 0)) { pr_err("Failed to register new device\n"); goto out2; } =20 - list_add_tail(&new->list, &phram_list); + if (pdev) + platform_set_drvdata(pdev, new); + else + list_add_tail(&new->list, &phram_list); + return 0; =20 out2: @@ -278,7 +289,7 @@ static int phram_setup(const char *val) goto error; } =20 - ret =3D register_device(name, start, len, (uint32_t)erasesize); + ret =3D register_device(NULL, name, start, len, (uint32_t)erasesize); if (ret) goto error; =20 @@ -325,10 +336,54 @@ static int phram_param_call(const char *val, const st= ruct kernel_param *kp) module_param_call(phram, phram_param_call, NULL, NULL, 0200); MODULE_PARM_DESC(phram, "Memory region to map. \"phram=3D,,[,]\""); =20 +#ifdef CONFIG_OF +static const struct of_device_id phram_of_match[] =3D { + { .compatible =3D "phram" }, + {} +}; +MODULE_DEVICE_TABLE(of, phram_of_match); +#endif + +static int phram_probe(struct platform_device *pdev) +{ + struct resource *res; + + res =3D platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENOMEM; + + /* mtd_set_of_node() reads name from "label" */ + return register_device(pdev, NULL, res->start, resource_size(res), + PAGE_SIZE); +} + +static int phram_remove(struct platform_device *pdev) +{ + struct phram_mtd_list *phram =3D platform_get_drvdata(pdev); + + mtd_device_unregister(&phram->mtd); + iounmap(phram->mtd.priv); + kfree(phram); + + return 0; +} + +static struct platform_driver phram_driver =3D { + .probe =3D phram_probe, + .remove =3D phram_remove, + .driver =3D { + .name =3D "phram", + .of_match_table =3D of_match_ptr(phram_of_match), + }, +}; =20 static int __init init_phram(void) { - int ret =3D 0; + int ret; + + ret =3D platform_driver_register(&phram_driver); + if (ret) + return ret; =20 #ifndef MODULE if (phram_paramline[0]) @@ -336,12 +391,16 @@ static int __init init_phram(void) phram_init_called =3D 1; #endif =20 + if (ret) + platform_driver_unregister(&phram_driver); + return ret; } =20 static void __exit cleanup_phram(void) { unregister_devices(); + platform_driver_unregister(&phram_driver); } =20 module_init(init_phram); diff --git a/drivers/of/platform.c b/drivers/of/platform.c index a16b74f32aa9..55d62b82c650 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -509,6 +509,7 @@ EXPORT_SYMBOL_GPL(of_platform_default_populate); =20 #ifndef CONFIG_PPC static const struct of_device_id reserved_mem_matches[] =3D { + { .compatible =3D "phram" }, { .compatible =3D "qcom,rmtfs-mem" }, { .compatible =3D "qcom,cmd-db" }, { .compatible =3D "qcom,smem" }, --=20 2.34.1 From nobody Mon May 11 07:06:12 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AE639C433F5 for ; Tue, 12 Apr 2022 13:53:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1356416AbiDLNzq (ORCPT ); Tue, 12 Apr 2022 09:55:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51376 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1356355AbiDLNz3 (ORCPT ); Tue, 12 Apr 2022 09:55:29 -0400 Received: from smtp2.axis.com (smtp2.axis.com [195.60.68.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7FB4D580EF; Tue, 12 Apr 2022 06:53:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=axis.com; q=dns/txt; s=axis-central1; t=1649771591; x=1681307591; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=LejCdvhc0hzLl8lZPhOSbxuyu0T2rEaAYkiZnsIK59M=; b=Qh9Q62iITEJ0oyxHCbwzj2tA6BKXeadDpXrmVpYf51OAvZ11Uh8Dz5jx 1anzzKIQMFq/kCJGrFWB0wiV8bbh1WbI0EPI7vA5ZxjUOP1X+sNqkqHWJ 4eEg4Uur17tPlKkUj7OopD3fzVb402DJ5/yqgbWMW2g7ltoyzFsqdUZd9 0wQWlXHjNVXdnRGd74SsLtSMP2UrzxWW3Nl+mki+jZx4V8wBPLp9iAr86 4U+mMp4avCoPQlftbh3Iml3dsyhZkplGXkXRsZrZQppGcZSS8MX58nTKS yBWSh9DhuIhTgxbqnqQZn7sPCODCWthAFyKUYjQzLliJkrrGoSjLIJKkG g==; From: Vincent Whitchurch To: , , , CC: , Vincent Whitchurch , , , , , , Subject: [PATCH v3 4/4] mtd: phram: Allow cached mappings Date: Tue, 12 Apr 2022 15:53:02 +0200 Message-ID: <20220412135302.1682890-5-vincent.whitchurch@axis.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220412135302.1682890-1-vincent.whitchurch@axis.com> References: <20220412135302.1682890-1-vincent.whitchurch@axis.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Currently phram always uses ioremap(), but this is unnecessary when normal memory is used. If the reserved-memory node does not specify the no-map property, indicating it should be mapped as system RAM and ioremap() cannot be used on it, use a cached mapping using memremap(MEMREMAP_WB) instead. On one of my systems this improves read performance by ~70%. Signed-off-by: Vincent Whitchurch Reported-by: kernel test robot --- drivers/mtd/devices/phram.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c index 506e9edf5c85..89d74a1eff4f 100644 --- a/drivers/mtd/devices/phram.c +++ b/drivers/mtd/devices/phram.c @@ -34,6 +34,7 @@ struct phram_mtd_list { struct mtd_info mtd; struct list_head list; + bool cached; }; =20 static LIST_HEAD(phram_list); @@ -96,6 +97,7 @@ static int register_device(struct platform_device *pdev, = const char *name, phys_addr_t start, size_t len, uint32_t erasesize) { struct device_node *np =3D pdev ? pdev->dev.of_node : NULL; + bool cached =3D np ? !of_property_read_bool(np, "no-map") : false; struct phram_mtd_list *new; int ret =3D -ENOMEM; =20 @@ -103,8 +105,13 @@ static int register_device(struct platform_device *pde= v, const char *name, if (!new) goto out0; =20 + new->cached =3D cached; + ret =3D -EIO; - new->mtd.priv =3D ioremap(start, len); + if (cached) + new->mtd.priv =3D memremap(start, len, MEMREMAP_WB); + else + new->mtd.priv =3D ioremap(start, len); if (!new->mtd.priv) { pr_err("ioremap failed\n"); goto out1; @@ -140,7 +147,7 @@ static int register_device(struct platform_device *pdev= , const char *name, return 0; =20 out2: - iounmap(new->mtd.priv); + cached ? memunmap(new->mtd.priv) : iounmap(new->mtd.priv); out1: kfree(new); out0: @@ -362,7 +369,7 @@ static int phram_remove(struct platform_device *pdev) struct phram_mtd_list *phram =3D platform_get_drvdata(pdev); =20 mtd_device_unregister(&phram->mtd); - iounmap(phram->mtd.priv); + phram->cached ? memunmap(phram->mtd.priv) : iounmap(phram->mtd.priv); kfree(phram); =20 return 0; --=20 2.34.1