linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/4] mtd: phram improvements
@ 2022-04-05 13:03 Vincent Whitchurch
  2022-04-05 13:03 ` [PATCH v2 1/4] mtd: core: Check devicetree alias for index Vincent Whitchurch
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Vincent Whitchurch @ 2022-04-05 13:03 UTC (permalink / raw)
  To: vigneshr, richard, miquel.raynal, joern
  Cc: kernel, Vincent Whitchurch, linux-mtd, devicetree, robh+dt,
	krzk+dt, frowand.list, linux-kernel

v2:
- Add note on what "phram" means in binding.
- Use /schemas/mtd/mtd.yaml instead of relative pathUse /schemas/mtd/mtd.yaml
  instead of relative path in binding.

The phram driver in the MTD subsystem can be used to allow the kernel to use an
MTD or (via mtdblock) a block device in RAM (with the contents loaded by a
bootloader for example).  This series has some improvements to make it more
usable by adding device tree support and to significantly improve its
performance by using cached mappings when possible.

I use this feature to pass the rootfs to the kernel when booting from RAM.  The
boot is much faster and requires less memory than initrd (which is on top of
that being deprecated), and it allows the same disk images to be used when
booting from RAM, unlike initramfs.

Cc: linux-mtd@lists.infradead.org

Cc: devicetree@vger.kernel.org
Cc: robh+dt@kernel.org
Cc: krzk+dt@kernel.org
Cc: frowand.list@gmail.com

Cc: linux-kernel@vger.kernel.org

Vincent Whitchurch (4):
  mtd: core: Check devicetree alias for index
  dt-bindings: reserved-memory: Add phram
  mtd: phram: Allow probing via reserved-memory
  mtd: phram: Allow cached mappings

 .../bindings/reserved-memory/phram.yaml       | 47 +++++++++++
 drivers/mtd/devices/phram.c                   | 78 +++++++++++++++++--
 drivers/mtd/mtdcore.c                         | 11 ++-
 drivers/of/platform.c                         |  1 +
 4 files changed, 129 insertions(+), 8 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/reserved-memory/phram.yaml

-- 
2.34.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v2 1/4] mtd: core: Check devicetree alias for index
  2022-04-05 13:03 [PATCH v2 0/4] mtd: phram improvements Vincent Whitchurch
@ 2022-04-05 13:03 ` Vincent Whitchurch
  2022-04-05 13:03 ` [PATCH v2 2/4] dt-bindings: reserved-memory: Add phram Vincent Whitchurch
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Vincent Whitchurch @ 2022-04-05 13:03 UTC (permalink / raw)
  To: vigneshr, richard, miquel.raynal, joern
  Cc: kernel, Vincent Whitchurch, linux-mtd, devicetree, robh+dt,
	krzk+dt, frowand.list, linux-kernel

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 <vincent.whitchurch@axis.com>
---
 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)
 
 int add_mtd_device(struct mtd_info *mtd)
 {
+	struct device_node *np = mtd_get_of_node(mtd);
 	struct mtd_info *master = mtd_get_master(mtd);
 	struct mtd_notifier *not;
-	int i, error;
+	int i, error, ofidx;
 
 	/*
 	 * May occur, for instance, on buggy drivers which call
@@ -598,7 +599,13 @@ int add_mtd_device(struct mtd_info *mtd)
 
 	mutex_lock(&mtd_table_mutex);
 
-	i = idr_alloc(&mtd_idr, mtd, 0, 0, GFP_KERNEL);
+	ofidx = -1;
+	if (np)
+		ofidx = of_alias_get_id(np, "mtd");
+	if (ofidx >= 0)
+		i = idr_alloc(&mtd_idr, mtd, ofidx, ofidx + 1, GFP_KERNEL);
+	else
+		i = idr_alloc(&mtd_idr, mtd, 0, 0, GFP_KERNEL);
 	if (i < 0) {
 		error = i;
 		goto fail_locked;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 2/4] dt-bindings: reserved-memory: Add phram
  2022-04-05 13:03 [PATCH v2 0/4] mtd: phram improvements Vincent Whitchurch
  2022-04-05 13:03 ` [PATCH v2 1/4] mtd: core: Check devicetree alias for index Vincent Whitchurch
@ 2022-04-05 13:03 ` Vincent Whitchurch
  2022-04-05 13:03 ` [PATCH v2 3/4] mtd: phram: Allow probing via reserved-memory Vincent Whitchurch
  2022-04-05 13:03 ` [PATCH v2 4/4] mtd: phram: Allow cached mappings Vincent Whitchurch
  3 siblings, 0 replies; 6+ messages in thread
From: Vincent Whitchurch @ 2022-04-05 13:03 UTC (permalink / raw)
  To: vigneshr, richard, miquel.raynal, joern
  Cc: kernel, Vincent Whitchurch, linux-mtd, devicetree, robh+dt,
	krzk+dt, frowand.list, linux-kernel

Add bindings to allow MTD/block devices to be created in reserved-memory
regions using the "phram" driver.

This allows things like partitioning to be specified via the existing
devicetree bindings.

Signed-off-by: Vincent Whitchurch <vincent.whitchurch@axis.com>
---

Notes:
    v2:
    - Add note on what "phram" means.
    - Use /schemas/mtd/mtd.yaml instead of relative pathUse /schemas/mtd/mtd.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..318415b56afe
--- /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: |
+  Use the reserved memory region 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.
+
+  If no-map is not set, cached mappings will be used for the memory region.
+
+maintainers:
+  - Vincent Whitchurch <vincent.whitchurch@axis.com>
+
+allOf:
+  - $ref: "reserved-memory.yaml"
+  - $ref: "/schemas/mtd/mtd.yaml"
+
+properties:
+  compatible:
+    const: phram
+
+  reg:
+    description: region of memory that contains the MTD/block device
+
+required:
+  - compatible
+  - reg
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    reserved-memory {
+        #address-cells = <1>;
+        #size-cells = <1>;
+
+        phram: flash@12340000 {
+            compatible = "phram";
+            label = "rootfs";
+            reg = <0x12340000 0x00800000>;
+        };
+    };
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 3/4] mtd: phram: Allow probing via reserved-memory
  2022-04-05 13:03 [PATCH v2 0/4] mtd: phram improvements Vincent Whitchurch
  2022-04-05 13:03 ` [PATCH v2 1/4] mtd: core: Check devicetree alias for index Vincent Whitchurch
  2022-04-05 13:03 ` [PATCH v2 2/4] dt-bindings: reserved-memory: Add phram Vincent Whitchurch
@ 2022-04-05 13:03 ` Vincent Whitchurch
  2022-04-06  5:25   ` kernel test robot
  2022-04-05 13:03 ` [PATCH v2 4/4] mtd: phram: Allow cached mappings Vincent Whitchurch
  3 siblings, 1 reply; 6+ messages in thread
From: Vincent Whitchurch @ 2022-04-05 13:03 UTC (permalink / raw)
  To: vigneshr, richard, miquel.raynal, joern
  Cc: kernel, Vincent Whitchurch, linux-mtd, devicetree, robh+dt,
	krzk+dt, frowand.list, linux-kernel

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 <vincent.whitchurch@axis.com>
---
 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..6dfe9401a3c5 100644
--- a/drivers/mtd/devices/phram.c
+++ b/drivers/mtd/devices/phram.c
@@ -27,6 +27,9 @@
 #include <linux/slab.h>
 #include <linux/mtd/mtd.h>
 #include <asm/div64.h>
+#include <linux/platform_device.h>
+#include <linux/of_address.h>
+#include <linux/of.h>
 
 struct phram_mtd_list {
 	struct mtd_info mtd;
@@ -89,8 +92,10 @@ static void unregister_devices(void)
 	}
 }
 
-static int register_device(char *name, phys_addr_t start, size_t len, uint32_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 = pdev ? pdev->dev.of_node : NULL;
 	struct phram_mtd_list *new;
 	int ret = -ENOMEM;
 
@@ -119,13 +124,19 @@ static int register_device(char *name, phys_addr_t start, size_t len, uint32_t e
 	new->mtd.erasesize = erasesize;
 	new->mtd.writesize = 1;
 
+	mtd_set_of_node(&new->mtd, np);
+
 	ret = -EAGAIN;
 	if (mtd_device_register(&new->mtd, NULL, 0)) {
 		pr_err("Failed to register new device\n");
 		goto out2;
 	}
 
-	list_add_tail(&new->list, &phram_list);
+	if (pdev)
+		platform_set_drvdata(pdev, new);
+	else
+		list_add_tail(&new->list, &phram_list);
+
 	return 0;
 
 out2:
@@ -278,7 +289,7 @@ static int phram_setup(const char *val)
 		goto error;
 	}
 
-	ret = register_device(name, start, len, (uint32_t)erasesize);
+	ret = register_device(NULL, name, start, len, (uint32_t)erasesize);
 	if (ret)
 		goto error;
 
@@ -325,10 +336,54 @@ static int phram_param_call(const char *val, const struct kernel_param *kp)
 module_param_call(phram, phram_param_call, NULL, NULL, 0200);
 MODULE_PARM_DESC(phram, "Memory region to map. \"phram=<name>,<start>,<length>[,<erasesize>]\"");
 
+#ifdef CONFIG_OF
+static const struct of_device_id phram_of_match[] = {
+	{ .compatible = "phram" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, phram_of_match)
+#endif
+
+static int phram_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+
+	res = 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 = platform_get_drvdata(pdev);
+
+	mtd_device_unregister(&phram->mtd);
+	iounmap(phram->mtd.priv);
+	kfree(phram);
+
+	return 0;
+}
+
+static struct platform_driver phram_driver = {
+	.probe		= phram_probe,
+	.remove		= phram_remove,
+	.driver		= {
+		.name		= "phram",
+		.of_match_table	= of_match_ptr(phram_of_match),
+	},
+};
 
 static int __init init_phram(void)
 {
-	int ret = 0;
+	int ret;
+
+	ret = platform_driver_register(&phram_driver);
+	if (ret)
+		return ret;
 
 #ifndef MODULE
 	if (phram_paramline[0])
@@ -336,12 +391,16 @@ static int __init init_phram(void)
 	phram_init_called = 1;
 #endif
 
+	if (ret)
+		platform_driver_unregister(&phram_driver);
+
 	return ret;
 }
 
 static void __exit cleanup_phram(void)
 {
 	unregister_devices();
+	platform_driver_unregister(&phram_driver);
 }
 
 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);
 
 #ifndef CONFIG_PPC
 static const struct of_device_id reserved_mem_matches[] = {
+	{ .compatible = "phram" },
 	{ .compatible = "qcom,rmtfs-mem" },
 	{ .compatible = "qcom,cmd-db" },
 	{ .compatible = "qcom,smem" },
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 4/4] mtd: phram: Allow cached mappings
  2022-04-05 13:03 [PATCH v2 0/4] mtd: phram improvements Vincent Whitchurch
                   ` (2 preceding siblings ...)
  2022-04-05 13:03 ` [PATCH v2 3/4] mtd: phram: Allow probing via reserved-memory Vincent Whitchurch
@ 2022-04-05 13:03 ` Vincent Whitchurch
  3 siblings, 0 replies; 6+ messages in thread
From: Vincent Whitchurch @ 2022-04-05 13:03 UTC (permalink / raw)
  To: vigneshr, richard, miquel.raynal, joern
  Cc: kernel, Vincent Whitchurch, linux-mtd, devicetree, robh+dt,
	krzk+dt, frowand.list, linux-kernel

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 <vincent.whitchurch@axis.com>
---
 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 6dfe9401a3c5..ac2679f9031a 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;
 };
 
 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 = pdev ? pdev->dev.of_node : NULL;
+	bool cached = np ? !of_property_read_bool(np, "no-map") : false;
 	struct phram_mtd_list *new;
 	int ret = -ENOMEM;
 
@@ -103,8 +105,13 @@ static int register_device(struct platform_device *pdev, const char *name,
 	if (!new)
 		goto out0;
 
+	new->cached = cached;
+
 	ret = -EIO;
-	new->mtd.priv = ioremap(start, len);
+	if (cached)
+		new->mtd.priv = memremap(start, len, MEMREMAP_WB);
+	else
+		new->mtd.priv = 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;
 
 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 = platform_get_drvdata(pdev);
 
 	mtd_device_unregister(&phram->mtd);
-	iounmap(phram->mtd.priv);
+	phram->cached ? memunmap(phram->mtd.priv) : iounmap(phram->mtd.priv);
 	kfree(phram);
 
 	return 0;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 3/4] mtd: phram: Allow probing via reserved-memory
  2022-04-05 13:03 ` [PATCH v2 3/4] mtd: phram: Allow probing via reserved-memory Vincent Whitchurch
@ 2022-04-06  5:25   ` kernel test robot
  0 siblings, 0 replies; 6+ messages in thread
From: kernel test robot @ 2022-04-06  5:25 UTC (permalink / raw)
  To: Vincent Whitchurch, vigneshr, richard, miquel.raynal, joern
  Cc: kbuild-all, kernel, Vincent Whitchurch, linux-mtd, devicetree,
	robh+dt, krzk+dt, frowand.list, linux-kernel

Hi Vincent,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on mtd/mtd/next]
[also build test ERROR on mtd/mtd/fixes robh/for-next v5.18-rc1 next-20220405]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/intel-lab-lkp/linux/commits/Vincent-Whitchurch/mtd-phram-improvements/20220406-070357
base:   https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git mtd/next
config: i386-randconfig-a005 (https://download.01.org/0day-ci/archive/20220406/202204061349.puriUTMO-lkp@intel.com/config)
compiler: gcc-11 (Debian 11.2.0-19) 11.2.0
reproduce (this is a W=1 build):
        # https://github.com/intel-lab-lkp/linux/commit/5f942c36259bf6194f9cc8ed7cbacdca28200e20
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Vincent-Whitchurch/mtd-phram-improvements/20220406-070357
        git checkout 5f942c36259bf6194f9cc8ed7cbacdca28200e20
        # save the config file to linux build tree
        mkdir build_dir
        make W=1 O=build_dir ARCH=i386 SHELL=/bin/bash drivers/mtd/devices/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

>> drivers/mtd/devices/phram.c:347:1: error: expected ',' or ';' before 'static'
     347 | static int phram_probe(struct platform_device *pdev)
         | ^~~~~~
>> drivers/mtd/devices/phram.c:372:27: error: 'phram_probe' undeclared here (not in a function); did you mean 'phram_write'?
     372 |         .probe          = phram_probe,
         |                           ^~~~~~~~~~~
         |                           phram_write


vim +347 drivers/mtd/devices/phram.c

   346	
 > 347	static int phram_probe(struct platform_device *pdev)
   348	{
   349		struct resource *res;
   350	
   351		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
   352		if (!res)
   353			return -ENOMEM;
   354	
   355		/* mtd_set_of_node() reads name from "label" */
   356		return register_device(pdev, NULL, res->start, resource_size(res),
   357				       PAGE_SIZE);
   358	}
   359	
   360	static int phram_remove(struct platform_device *pdev)
   361	{
   362		struct phram_mtd_list *phram = platform_get_drvdata(pdev);
   363	
   364		mtd_device_unregister(&phram->mtd);
   365		iounmap(phram->mtd.priv);
   366		kfree(phram);
   367	
   368		return 0;
   369	}
   370	
   371	static struct platform_driver phram_driver = {
 > 372		.probe		= phram_probe,
   373		.remove		= phram_remove,
   374		.driver		= {
   375			.name		= "phram",
   376			.of_match_table	= of_match_ptr(phram_of_match),
   377		},
   378	};
   379	

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-04-06  7:10 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-05 13:03 [PATCH v2 0/4] mtd: phram improvements Vincent Whitchurch
2022-04-05 13:03 ` [PATCH v2 1/4] mtd: core: Check devicetree alias for index Vincent Whitchurch
2022-04-05 13:03 ` [PATCH v2 2/4] dt-bindings: reserved-memory: Add phram Vincent Whitchurch
2022-04-05 13:03 ` [PATCH v2 3/4] mtd: phram: Allow probing via reserved-memory Vincent Whitchurch
2022-04-06  5:25   ` kernel test robot
2022-04-05 13:03 ` [PATCH v2 4/4] mtd: phram: Allow cached mappings Vincent Whitchurch

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).