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

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.

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       | 45 +++++++++++
 drivers/mtd/devices/phram.c                   | 78 +++++++++++++++++--
 drivers/mtd/mtdcore.c                         | 11 ++-
 drivers/of/platform.c                         |  1 +
 4 files changed, 127 insertions(+), 8 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/reserved-memory/phram.yaml

-- 
2.34.1


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

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

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 bd4b31023c82..37c8b1b5db26 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -590,9 +590,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
@@ -631,7 +632,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] 7+ messages in thread

* [PATCH 2/4] dt-bindings: reserved-memory: Add phram
  2022-03-07 14:15 [PATCH 0/4] mtd: phram improvements Vincent Whitchurch
  2022-03-07 14:15 ` [PATCH 1/4] mtd: core: Check devicetree alias for index Vincent Whitchurch
@ 2022-03-07 14:15 ` Vincent Whitchurch
  2022-03-10 20:58   ` Rob Herring
  2022-03-07 14:15 ` [PATCH 3/4] mtd: phram: Allow probing via reserved-memory Vincent Whitchurch
  2022-03-07 14:15 ` [PATCH 4/4] mtd: phram: Allow cached mappings Vincent Whitchurch
  3 siblings, 1 reply; 7+ messages in thread
From: Vincent Whitchurch @ 2022-03-07 14:15 UTC (permalink / raw)
  To: vigneshr, richard, miquel.raynal, joern
  Cc: kernel, linux-kernel, linux-mtd, devicetree, frowand.list,
	krzysztof.kozlowski, robh+dt, Vincent Whitchurch

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>
---
 .../bindings/reserved-memory/phram.yaml       | 45 +++++++++++++++++++
 1 file changed, 45 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..92e7a80ee87a
--- /dev/null
+++ b/Documentation/devicetree/bindings/reserved-memory/phram.yaml
@@ -0,0 +1,45 @@
+# 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.
+
+  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: "../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] 7+ messages in thread

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

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] 7+ messages in thread

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

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] 7+ messages in thread

* Re: [PATCH 2/4] dt-bindings: reserved-memory: Add phram
  2022-03-07 14:15 ` [PATCH 2/4] dt-bindings: reserved-memory: Add phram Vincent Whitchurch
@ 2022-03-10 20:58   ` Rob Herring
  2022-03-11 10:13     ` Vincent Whitchurch
  0 siblings, 1 reply; 7+ messages in thread
From: Rob Herring @ 2022-03-10 20:58 UTC (permalink / raw)
  To: Vincent Whitchurch
  Cc: vigneshr, richard, miquel.raynal, joern, kernel, linux-kernel,
	linux-mtd, devicetree, frowand.list, krzysztof.kozlowski

On Mon, Mar 07, 2022 at 03:15:47PM +0100, Vincent Whitchurch wrote:
> Add bindings to allow MTD/block devices to be created in reserved-memory
> regions using the "phram" driver.

What does 'ph' mean? Please define somewhere for the binding.

> 
> This allows things like partitioning to be specified via the existing
> devicetree bindings.
> 
> Signed-off-by: Vincent Whitchurch <vincent.whitchurch@axis.com>
> ---
>  .../bindings/reserved-memory/phram.yaml       | 45 +++++++++++++++++++
>  1 file changed, 45 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..92e7a80ee87a
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/reserved-memory/phram.yaml
> @@ -0,0 +1,45 @@
> +# 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.
> +
> +  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: "../mtd/mtd.yaml"

/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";

That's an odd example...

> +            reg = <0x12340000 0x00800000>;
> +        };
> +    };
> -- 
> 2.34.1
> 
> 

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

* Re: [PATCH 2/4] dt-bindings: reserved-memory: Add phram
  2022-03-10 20:58   ` Rob Herring
@ 2022-03-11 10:13     ` Vincent Whitchurch
  0 siblings, 0 replies; 7+ messages in thread
From: Vincent Whitchurch @ 2022-03-11 10:13 UTC (permalink / raw)
  To: Rob Herring
  Cc: vigneshr, richard, miquel.raynal, joern, kernel, linux-kernel,
	linux-mtd, devicetree, frowand.list, krzysztof.kozlowski

On Thu, Mar 10, 2022 at 09:58:58PM +0100, Rob Herring wrote:
> On Mon, Mar 07, 2022 at 03:15:47PM +0100, Vincent Whitchurch wrote:
> > Add bindings to allow MTD/block devices to be created in reserved-memory
> > regions using the "phram" driver.
> 
> What does 'ph' mean? Please define somewhere for the binding.

Judging from the Kconfig description it means "physical", as in
"physical memory" (as opposed to virtual memory I guess).  I will added
a note in the next version. 

[...]
> > +examples:
> > +  - |
> > +    reserved-memory {
> > +        #address-cells = <1>;
> > +        #size-cells = <1>;
> > +
> > +        phram: flash@12340000 {
> > +            compatible = "phram";
> > +            label = "rootfs";
> 
> That's an odd example...

If it's the "flash" name which is odd for RAM, that's mandated by the
mtd schema.

If it's the "rootfs" label which is odd, I'm not sure I understand why.
I use this feature to pass the rootfs to the kernel when booting from
RAM.  It 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.

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

end of thread, other threads:[~2022-03-11 10:13 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-07 14:15 [PATCH 0/4] mtd: phram improvements Vincent Whitchurch
2022-03-07 14:15 ` [PATCH 1/4] mtd: core: Check devicetree alias for index Vincent Whitchurch
2022-03-07 14:15 ` [PATCH 2/4] dt-bindings: reserved-memory: Add phram Vincent Whitchurch
2022-03-10 20:58   ` Rob Herring
2022-03-11 10:13     ` Vincent Whitchurch
2022-03-07 14:15 ` [PATCH 3/4] mtd: phram: Allow probing via reserved-memory Vincent Whitchurch
2022-03-07 14:15 ` [PATCH 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).